shithub: vim

Download patch

ref: dd360bcd3bf1fbbb1009d4b49c847facb929030b
author: phil9 <telephil9@gmail.com>
date: Thu Sep 2 13:02:16 EDT 2021

initial import

--- /dev/null
+++ b/README
@@ -1,0 +1,7 @@
+vim
+====
+This is a plan9 port of the vim editor.
+The port was initially done by stefanha (see https://vmsplice.net/9vim.html).
+
+Objective here is to add a couple of things (plumbing, mouse support) and fix some issues (shell commands and :make most notably).
+
--- /dev/null
+++ b/README.txt
@@ -1,0 +1,143 @@
+README for the Vim source code
+
+Here are a few hints for finding your way around the source code.  This
+doesn't make it less complex than it is, but it gets you started.
+
+You might also want to read ":help development".
+
+
+JUMPING AROUND
+
+First of all, use ":make tags" to generate a tags file, so that you can use
+the ":tag" command to jump around the source code.
+
+To jump to a function or variable definition, move the cursor on the name and
+use the CTRL-] command.  Use CTRL-T or CTRL-O to jump back.
+
+To jump to a file, move the cursor on its name and use the "gf" command.
+
+Most code can be found in a file with an obvious name (incomplete list):
+	buffer.c	manipulating buffers (loaded files)
+	diff.c		diff mode (vimdiff)
+	eval.c		expression evaluation
+	fileio.c	reading and writing files
+	fold.c		folding
+	getchar.c	getting characters and key mapping
+	mark.c		marks
+	mbyte.c		multy-byte character handling
+	memfile.c	storing lines for buffers in a swapfile
+	memline.c	storing lines for buffers in memory
+	menu.c		menus
+	message.c	(error) messages
+	ops.c		handling operators ("d", "y", "p")
+	option.c	options
+	quickfix.c	quickfix commands (":make", ":cn")
+	regexp.c	pattern matching
+	screen.c	updating the windows
+	search.c	pattern searching
+	spell.c		spell checking
+	syntax.c	syntax and other highlighting
+	tag.c		tags
+	term.c		terminal handling, termcap codes
+	undo.c		undo and redo
+	window.c	handling split windows
+
+
+IMPORTANT VARIABLES
+
+The current mode is stored in "State".  The values it can have are NORMAL,
+INSERT, CMDLINE, and a few others.
+
+The current window is "curwin".  The current buffer is "curbuf".  These point
+to structures with the cursor position in the window, option values, the file
+name, etc.  These are defined in structs.h.
+
+All the global variables are declared in globals.h.
+
+
+THE MAIN LOOP
+
+This is conveniently called main_loop().  It updates a few things and then
+calls normal_cmd() to process a command.  This returns when the command is
+finished.
+
+The basic idea is that Vim waits for the user to type a character and
+processes it until another character is needed.  Thus there are several places
+where Vim waits for a character to be typed.  The vgetc() function is used for
+this.  It also handles mapping.
+
+Updating the screen is mostly postponed until a command or a sequence of
+commands has finished.  The work is done by update_screen(), which calls
+win_update() for every window, which calls win_line() for every line.
+See the start of screen.c for more explanations.
+
+
+COMMAND-LINE MODE
+
+When typing a ":", normal_cmd() will call getcmdline() to obtain a line with
+an Ex command.  getcmdline() contains a loop that will handle each typed
+character.  It returns when hitting <CR> or <Esc> or some other character that
+ends the command line mode.
+
+
+EX COMMANDS
+
+Ex commands are handled by the function do_cmdline().  It does the generic
+parsing of the ":" command line and calls do_one_cmd() for each separate
+command.  It also takes care of while loops.
+
+do_one_cmd() parses the range and generic arguments and puts them in the
+exarg_t and passes it to the function that handles the command.
+
+The ":" commands are listed in ex_cmds.h.  The third entry of each item is the
+name of the function that handles the command.  The last entry are the flags
+that are used for the command.
+
+
+NORMAL MODE COMMANDS
+
+The Normal mode commands are handled by the normal_cmd() function.  It also
+handles the optional count and an extra character for some commands.  These
+are passed in a cmdarg_t to the function that handles the command.
+
+There is a table nv_cmds in normal.c which lists the first character of every
+command.  The second entry of each item is the name of the function that
+handles the command.
+
+
+INSERT MODE COMMANDS
+
+When doing an "i" or "a" command, normal_cmd() will call the edit() function.
+It contains a loop that waits for the next character and handles it.  It
+returns when leaving Insert mode.
+
+
+OPTIONS
+
+There is a list with all option names in option.c, called options[].
+
+
+THE GUI
+
+Most of the GUI code is implemented like it was a clever terminal.  Typing a
+character, moving a scrollbar, clicking the mouse, etc. are all translated
+into events which are written in the input buffer.  These are read by the
+main code, just like reading from a terminal.  The code for this is scattered
+through gui.c.  For example: gui_send_mouse_event() for a mouse click and
+gui_menu_cb() for a menu action.  Key hits are handled by the system-specific
+GUI code, which calls add_to_input_buf() to send the key code.
+
+Updating the GUI window is done by writing codes in the output buffer, just
+like writing to a terminal.  When the buffer gets full or is flushed,
+gui_write() will parse the codes and draw the appropriate items.  Finally the
+system-specific GUI code will be called to do the work.
+
+
+DEBUGGING THE GUI
+
+Remember to prevent that gvim forks and the debugger thinks Vim has exited,
+add the "-f" argument.  In gdb: "run -f -g".
+
+When stepping through display updating code, the focus event is triggered
+when going from the debugger to Vim and back.  To avoid this, recompile with
+some code in gui_focus_change() disabled.
--- /dev/null
+++ b/arabic.c
@@ -1,0 +1,1168 @@
+/* vi:set ts=8 sts=4 sw=4:
+ *
+ * VIM - Vi IMproved    by Bram Moolenaar
+ *
+ * Do ":help uganda"  in Vim to read copying and usage conditions.
+ * Do ":help credits" in Vim to see a list of people who contributed.
+ * See README.txt for an overview of the Vim source code.
+ */
+
+/*
+ * arabic.c: functions for Arabic language
+ *
+ * Included by main.c, when FEAT_ARABIC & FEAT_GUI is defined.
+ *
+ * --
+ *
+ * Author: Nadim Shaikli & Isam Bayazidi
+ *
+ */
+
+static int  A_is_a __ARGS((int cur_c));
+static int  A_is_s __ARGS((int cur_c));
+static int  A_is_f __ARGS((int cur_c));
+static int  chg_c_a2s __ARGS((int cur_c));
+static int  chg_c_a2i __ARGS((int cur_c));
+static int  chg_c_a2m __ARGS((int cur_c));
+static int  chg_c_a2f __ARGS((int cur_c));
+static int  chg_c_i2m __ARGS((int cur_c));
+static int  chg_c_f2m __ARGS((int cur_c));
+static int  chg_c_laa2i __ARGS((int hid_c));
+static int  chg_c_laa2f __ARGS((int hid_c));
+static int  half_shape __ARGS((int c));
+static int  A_firstc_laa __ARGS((int c1, int c));
+static int  A_is_harakat __ARGS((int c));
+static int  A_is_iso __ARGS((int c));
+static int  A_is_formb __ARGS((int c));
+static int  A_is_ok __ARGS((int c));
+static int  A_is_valid __ARGS((int c));
+static int  A_is_special __ARGS((int c));
+
+
+/*
+ * Returns True if c is an ISO-8859-6 shaped ARABIC letter (user entered)
+ */
+    static int
+A_is_a(cur_c)
+    int cur_c;
+{
+    switch (cur_c)
+    {
+	case a_HAMZA:
+	case a_ALEF_MADDA:
+	case a_ALEF_HAMZA_ABOVE:
+	case a_WAW_HAMZA:
+	case a_ALEF_HAMZA_BELOW:
+	case a_YEH_HAMZA:
+	case a_ALEF:
+	case a_BEH:
+	case a_TEH_MARBUTA:
+	case a_TEH:
+	case a_THEH:
+	case a_JEEM:
+	case a_HAH:
+	case a_KHAH:
+	case a_DAL:
+	case a_THAL:
+	case a_REH:
+	case a_ZAIN:
+	case a_SEEN:
+	case a_SHEEN:
+	case a_SAD:
+	case a_DAD:
+	case a_TAH:
+	case a_ZAH:
+	case a_AIN:
+	case a_GHAIN:
+	case a_TATWEEL:
+	case a_FEH:
+	case a_QAF:
+	case a_KAF:
+	case a_LAM:
+	case a_MEEM:
+	case a_NOON:
+	case a_HEH:
+	case a_WAW:
+	case a_ALEF_MAKSURA:
+	case a_YEH:
+	    return TRUE;
+    }
+
+    return FALSE;
+}
+
+
+/*
+ * Returns True if c is an Isolated Form-B ARABIC letter
+ */
+    static int
+A_is_s(cur_c)
+    int cur_c;
+{
+    switch (cur_c)
+    {
+	case a_s_HAMZA:
+	case a_s_ALEF_MADDA:
+	case a_s_ALEF_HAMZA_ABOVE:
+	case a_s_WAW_HAMZA:
+	case a_s_ALEF_HAMZA_BELOW:
+	case a_s_YEH_HAMZA:
+	case a_s_ALEF:
+	case a_s_BEH:
+	case a_s_TEH_MARBUTA:
+	case a_s_TEH:
+	case a_s_THEH:
+	case a_s_JEEM:
+	case a_s_HAH:
+	case a_s_KHAH:
+	case a_s_DAL:
+	case a_s_THAL:
+	case a_s_REH:
+	case a_s_ZAIN:
+	case a_s_SEEN:
+	case a_s_SHEEN:
+	case a_s_SAD:
+	case a_s_DAD:
+	case a_s_TAH:
+	case a_s_ZAH:
+	case a_s_AIN:
+	case a_s_GHAIN:
+	case a_s_FEH:
+	case a_s_QAF:
+	case a_s_KAF:
+	case a_s_LAM:
+	case a_s_MEEM:
+	case a_s_NOON:
+	case a_s_HEH:
+	case a_s_WAW:
+	case a_s_ALEF_MAKSURA:
+	case a_s_YEH:
+	    return TRUE;
+    }
+
+    return FALSE;
+}
+
+
+/*
+ * Returns True if c is a Final shape of an ARABIC letter
+ */
+    static int
+A_is_f(cur_c)
+    int cur_c;
+{
+    switch (cur_c)
+    {
+	case a_f_ALEF_MADDA:
+	case a_f_ALEF_HAMZA_ABOVE:
+	case a_f_WAW_HAMZA:
+	case a_f_ALEF_HAMZA_BELOW:
+	case a_f_YEH_HAMZA:
+	case a_f_ALEF:
+	case a_f_BEH:
+	case a_f_TEH_MARBUTA:
+	case a_f_TEH:
+	case a_f_THEH:
+	case a_f_JEEM:
+	case a_f_HAH:
+	case a_f_KHAH:
+	case a_f_DAL:
+	case a_f_THAL:
+	case a_f_REH:
+	case a_f_ZAIN:
+	case a_f_SEEN:
+	case a_f_SHEEN:
+	case a_f_SAD:
+	case a_f_DAD:
+	case a_f_TAH:
+	case a_f_ZAH:
+	case a_f_AIN:
+	case a_f_GHAIN:
+	case a_f_FEH:
+	case a_f_QAF:
+	case a_f_KAF:
+	case a_f_LAM:
+	case a_f_MEEM:
+	case a_f_NOON:
+	case a_f_HEH:
+	case a_f_WAW:
+	case a_f_ALEF_MAKSURA:
+	case a_f_YEH:
+	case a_f_LAM_ALEF_MADDA_ABOVE:
+	case a_f_LAM_ALEF_HAMZA_ABOVE:
+	case a_f_LAM_ALEF_HAMZA_BELOW:
+	case a_f_LAM_ALEF:
+	    return TRUE;
+    }
+    return FALSE;
+}
+
+
+/*
+ * Change shape - from ISO-8859-6/Isolated to Form-B Isolated
+ */
+    static int
+chg_c_a2s(cur_c)
+    int cur_c;
+{
+    int tempc;
+
+    switch (cur_c)
+    {
+	case a_HAMZA:
+	    tempc = a_s_HAMZA;
+	    break;
+	case a_ALEF_MADDA:
+	    tempc = a_s_ALEF_MADDA;
+	    break;
+	case a_ALEF_HAMZA_ABOVE:
+	    tempc = a_s_ALEF_HAMZA_ABOVE;
+	    break;
+	case a_WAW_HAMZA:
+	    tempc = a_s_WAW_HAMZA;
+	    break;
+	case a_ALEF_HAMZA_BELOW:
+	    tempc = a_s_ALEF_HAMZA_BELOW;
+	    break;
+	case a_YEH_HAMZA:
+	    tempc = a_s_YEH_HAMZA;
+	    break;
+	case a_ALEF:
+	    tempc = a_s_ALEF;
+	    break;
+	case a_TEH_MARBUTA:
+	    tempc = a_s_TEH_MARBUTA;
+	    break;
+	case a_DAL:
+	    tempc = a_s_DAL;
+	    break;
+	case a_THAL:
+	    tempc = a_s_THAL;
+	    break;
+	case a_REH:
+	    tempc = a_s_REH;
+	    break;
+	case a_ZAIN:
+	    tempc = a_s_ZAIN;
+	    break;
+	case a_TATWEEL:			/* exceptions */
+	    tempc = cur_c;
+	    break;
+	case a_WAW:
+	    tempc = a_s_WAW;
+	    break;
+	case a_ALEF_MAKSURA:
+	    tempc = a_s_ALEF_MAKSURA;
+	    break;
+	case a_BEH:
+	    tempc = a_s_BEH;
+	    break;
+	case a_TEH:
+	    tempc = a_s_TEH;
+	    break;
+	case a_THEH:
+	    tempc = a_s_THEH;
+	    break;
+	case a_JEEM:
+	    tempc = a_s_JEEM;
+	    break;
+	case a_HAH:
+	    tempc = a_s_HAH;
+	    break;
+	case a_KHAH:
+	    tempc = a_s_KHAH;
+	    break;
+	case a_SEEN:
+	    tempc = a_s_SEEN;
+	    break;
+	case a_SHEEN:
+	    tempc = a_s_SHEEN;
+	    break;
+	case a_SAD:
+	    tempc = a_s_SAD;
+	    break;
+	case a_DAD:
+	    tempc = a_s_DAD;
+	    break;
+	case a_TAH:
+	    tempc = a_s_TAH;
+	    break;
+	case a_ZAH:
+	    tempc = a_s_ZAH;
+	    break;
+	case a_AIN:
+	    tempc = a_s_AIN;
+	    break;
+	case a_GHAIN:
+	    tempc = a_s_GHAIN;
+	    break;
+	case a_FEH:
+	    tempc = a_s_FEH;
+	    break;
+	case a_QAF:
+	    tempc = a_s_QAF;
+	    break;
+	case a_KAF:
+	    tempc = a_s_KAF;
+	    break;
+	case a_LAM:
+	    tempc = a_s_LAM;
+	    break;
+	case a_MEEM:
+	    tempc = a_s_MEEM;
+	    break;
+	case a_NOON:
+	    tempc = a_s_NOON;
+	    break;
+	case a_HEH:
+	    tempc = a_s_HEH;
+	    break;
+	case a_YEH:
+	    tempc = a_s_YEH;
+	    break;
+	default:
+	    tempc = 0;
+    }
+
+    return tempc;
+}
+
+
+/*
+ * Change shape - from ISO-8859-6/Isolated to Initial
+ */
+    static int
+chg_c_a2i(cur_c)
+    int cur_c;
+{
+    int tempc;
+
+    switch (cur_c)
+    {
+	case a_YEH_HAMZA:
+	    tempc = a_i_YEH_HAMZA;
+	    break;
+	case a_HAMZA:			/* exceptions */
+	    tempc = a_s_HAMZA;
+	    break;
+	case a_ALEF_MADDA:		/* exceptions */
+	    tempc = a_s_ALEF_MADDA;
+	    break;
+	case a_ALEF_HAMZA_ABOVE:	/* exceptions */
+	    tempc = a_s_ALEF_HAMZA_ABOVE;
+	    break;
+	case a_WAW_HAMZA:		/* exceptions */
+	    tempc = a_s_WAW_HAMZA;
+	    break;
+	case a_ALEF_HAMZA_BELOW:	/* exceptions */
+	    tempc = a_s_ALEF_HAMZA_BELOW;
+	    break;
+	case a_ALEF:			/* exceptions */
+	    tempc = a_s_ALEF;
+	    break;
+	case a_TEH_MARBUTA:		/* exceptions */
+	    tempc = a_s_TEH_MARBUTA;
+	    break;
+	case a_DAL:			/* exceptions */
+	    tempc = a_s_DAL;
+	    break;
+	case a_THAL:			/* exceptions */
+	    tempc = a_s_THAL;
+	    break;
+	case a_REH:			/* exceptions */
+	    tempc = a_s_REH;
+	    break;
+	case a_ZAIN:			/* exceptions */
+	    tempc = a_s_ZAIN;
+	    break;
+	case a_TATWEEL:			/* exceptions */
+	    tempc = cur_c;
+	    break;
+	case a_WAW:			/* exceptions */
+	    tempc = a_s_WAW;
+	    break;
+	case a_ALEF_MAKSURA:		/* exceptions */
+	    tempc = a_s_ALEF_MAKSURA;
+	    break;
+	case a_BEH:
+	    tempc = a_i_BEH;
+	    break;
+	case a_TEH:
+	    tempc = a_i_TEH;
+	    break;
+	case a_THEH:
+	    tempc = a_i_THEH;
+	    break;
+	case a_JEEM:
+	    tempc = a_i_JEEM;
+	    break;
+	case a_HAH:
+	    tempc = a_i_HAH;
+	    break;
+	case a_KHAH:
+	    tempc = a_i_KHAH;
+	    break;
+	case a_SEEN:
+	    tempc = a_i_SEEN;
+	    break;
+	case a_SHEEN:
+	    tempc = a_i_SHEEN;
+	    break;
+	case a_SAD:
+	    tempc = a_i_SAD;
+	    break;
+	case a_DAD:
+	    tempc = a_i_DAD;
+	    break;
+	case a_TAH:
+	    tempc = a_i_TAH;
+	    break;
+	case a_ZAH:
+	    tempc = a_i_ZAH;
+	    break;
+	case a_AIN:
+	    tempc = a_i_AIN;
+	    break;
+	case a_GHAIN:
+	    tempc = a_i_GHAIN;
+	    break;
+	case a_FEH:
+	    tempc = a_i_FEH;
+	    break;
+	case a_QAF:
+	    tempc = a_i_QAF;
+	    break;
+	case a_KAF:
+	    tempc = a_i_KAF;
+	    break;
+	case a_LAM:
+	    tempc = a_i_LAM;
+	    break;
+	case a_MEEM:
+	    tempc = a_i_MEEM;
+	    break;
+	case a_NOON:
+	    tempc = a_i_NOON;
+	    break;
+	case a_HEH:
+	    tempc = a_i_HEH;
+	    break;
+	case a_YEH:
+	    tempc = a_i_YEH;
+	    break;
+	default:
+	    tempc = 0;
+    }
+
+    return tempc;
+}
+
+
+/*
+ * Change shape - from ISO-8859-6/Isolated to Medial
+ */
+    static int
+chg_c_a2m(cur_c)
+    int cur_c;
+{
+    int tempc;
+
+    switch (cur_c)
+    {
+	case a_HAMZA:			/* exception */
+	    tempc = a_s_HAMZA;
+	    break;
+	case a_ALEF_MADDA:		/* exception */
+	    tempc = a_f_ALEF_MADDA;
+	    break;
+	case a_ALEF_HAMZA_ABOVE:	/* exception */
+	    tempc = a_f_ALEF_HAMZA_ABOVE;
+	    break;
+	case a_WAW_HAMZA:		/* exception */
+	    tempc = a_f_WAW_HAMZA;
+	    break;
+	case a_ALEF_HAMZA_BELOW:	/* exception */
+	    tempc = a_f_ALEF_HAMZA_BELOW;
+	    break;
+	case a_YEH_HAMZA:
+	    tempc = a_m_YEH_HAMZA;
+	    break;
+	case a_ALEF:			/* exception */
+	    tempc = a_f_ALEF;
+	    break;
+	case a_BEH:
+	    tempc = a_m_BEH;
+	    break;
+	case a_TEH_MARBUTA:		/* exception */
+	    tempc = a_f_TEH_MARBUTA;
+	    break;
+	case a_TEH:
+	    tempc = a_m_TEH;
+	    break;
+	case a_THEH:
+	    tempc = a_m_THEH;
+	    break;
+	case a_JEEM:
+	    tempc = a_m_JEEM;
+	    break;
+	case a_HAH:
+	    tempc = a_m_HAH;
+	    break;
+	case a_KHAH:
+	    tempc = a_m_KHAH;
+	    break;
+	case a_DAL:			/* exception */
+	    tempc = a_f_DAL;
+	    break;
+	case a_THAL:			/* exception */
+	    tempc = a_f_THAL;
+	    break;
+	case a_REH:			/* exception */
+	    tempc = a_f_REH;
+	    break;
+	case a_ZAIN:			/* exception */
+	    tempc = a_f_ZAIN;
+	    break;
+	case a_SEEN:
+	    tempc = a_m_SEEN;
+	    break;
+	case a_SHEEN:
+	    tempc = a_m_SHEEN;
+	    break;
+	case a_SAD:
+	    tempc = a_m_SAD;
+	    break;
+	case a_DAD:
+	    tempc = a_m_DAD;
+	    break;
+	case a_TAH:
+	    tempc = a_m_TAH;
+	    break;
+	case a_ZAH:
+	    tempc = a_m_ZAH;
+	    break;
+	case a_AIN:
+	    tempc = a_m_AIN;
+	    break;
+	case a_GHAIN:
+	    tempc = a_m_GHAIN;
+	    break;
+	case a_TATWEEL:			/* exception */
+	    tempc = cur_c;
+	    break;
+	case a_FEH:
+	    tempc = a_m_FEH;
+	    break;
+	case a_QAF:
+	    tempc = a_m_QAF;
+	    break;
+	case a_KAF:
+	    tempc = a_m_KAF;
+	    break;
+	case a_LAM:
+	    tempc = a_m_LAM;
+	    break;
+	case a_MEEM:
+	    tempc = a_m_MEEM;
+	    break;
+	case a_NOON:
+	    tempc = a_m_NOON;
+	    break;
+	case a_HEH:
+	    tempc = a_m_HEH;
+	    break;
+	case a_WAW:			/* exception */
+	    tempc = a_f_WAW;
+	    break;
+	case a_ALEF_MAKSURA:		/* exception */
+	    tempc = a_f_ALEF_MAKSURA;
+	    break;
+	case a_YEH:
+	    tempc = a_m_YEH;
+	    break;
+	default:
+	    tempc = 0;
+    }
+
+    return tempc;
+}
+
+
+/*
+ * Change shape - from ISO-8859-6/Isolated to final
+ */
+    static int
+chg_c_a2f(cur_c)
+    int cur_c;
+{
+    int tempc;
+
+    /* NOTE: these encodings need to be accounted for
+
+	a_f_ALEF_MADDA;
+	a_f_ALEF_HAMZA_ABOVE;
+	a_f_ALEF_HAMZA_BELOW;
+	a_f_LAM_ALEF_MADDA_ABOVE;
+	a_f_LAM_ALEF_HAMZA_ABOVE;
+	a_f_LAM_ALEF_HAMZA_BELOW;
+	*/
+
+    switch (cur_c)
+    {
+	case a_HAMZA:			/* exception */
+	    tempc = a_s_HAMZA;
+	    break;
+	case a_ALEF_MADDA:
+	    tempc = a_f_ALEF_MADDA;
+	    break;
+	case a_ALEF_HAMZA_ABOVE:
+	    tempc = a_f_ALEF_HAMZA_ABOVE;
+	    break;
+	case a_WAW_HAMZA:
+	    tempc = a_f_WAW_HAMZA;
+	    break;
+	case a_ALEF_HAMZA_BELOW:
+	    tempc = a_f_ALEF_HAMZA_BELOW;
+	    break;
+	case a_YEH_HAMZA:
+	    tempc = a_f_YEH_HAMZA;
+	    break;
+	case a_ALEF:
+	    tempc = a_f_ALEF;
+	    break;
+	case a_BEH:
+	    tempc = a_f_BEH;
+	    break;
+	case a_TEH_MARBUTA:
+	    tempc = a_f_TEH_MARBUTA;
+	    break;
+	case a_TEH:
+	    tempc = a_f_TEH;
+	    break;
+	case a_THEH:
+	    tempc = a_f_THEH;
+	    break;
+	case a_JEEM:
+	    tempc = a_f_JEEM;
+	    break;
+	case a_HAH:
+	    tempc = a_f_HAH;
+	    break;
+	case a_KHAH:
+	    tempc = a_f_KHAH;
+	    break;
+	case a_DAL:
+	    tempc = a_f_DAL;
+	    break;
+	case a_THAL:
+	    tempc = a_f_THAL;
+	    break;
+	case a_REH:
+	    tempc = a_f_REH;
+	    break;
+	case a_ZAIN:
+	    tempc = a_f_ZAIN;
+	    break;
+	case a_SEEN:
+	    tempc = a_f_SEEN;
+	    break;
+	case a_SHEEN:
+	    tempc = a_f_SHEEN;
+	    break;
+	case a_SAD:
+	    tempc = a_f_SAD;
+	    break;
+	case a_DAD:
+	    tempc = a_f_DAD;
+	    break;
+	case a_TAH:
+	    tempc = a_f_TAH;
+	    break;
+	case a_ZAH:
+	    tempc = a_f_ZAH;
+	    break;
+	case a_AIN:
+	    tempc = a_f_AIN;
+	    break;
+	case a_GHAIN:
+	    tempc = a_f_GHAIN;
+	    break;
+	case a_TATWEEL:			/* exception */
+	    tempc = cur_c;
+	    break;
+	case a_FEH:
+	    tempc = a_f_FEH;
+	    break;
+	case a_QAF:
+	    tempc = a_f_QAF;
+	    break;
+	case a_KAF:
+	    tempc = a_f_KAF;
+	    break;
+	case a_LAM:
+	    tempc = a_f_LAM;
+	    break;
+	case a_MEEM:
+	    tempc = a_f_MEEM;
+	    break;
+	case a_NOON:
+	    tempc = a_f_NOON;
+	    break;
+	case a_HEH:
+	    tempc = a_f_HEH;
+	    break;
+	case a_WAW:
+	    tempc = a_f_WAW;
+	    break;
+	case a_ALEF_MAKSURA:
+	    tempc = a_f_ALEF_MAKSURA;
+	    break;
+	case a_YEH:
+	    tempc = a_f_YEH;
+	    break;
+	default:
+	    tempc = 0;
+    }
+
+    return tempc;
+}
+
+
+/*
+ * Change shape - from Initial to Medial
+ */
+    static int
+chg_c_i2m(cur_c)
+    int cur_c;
+{
+    int tempc;
+
+    switch (cur_c)
+    {
+	case a_i_YEH_HAMZA:
+	    tempc = a_m_YEH_HAMZA;
+	    break;
+	case a_i_BEH:
+	    tempc = a_m_BEH;
+	    break;
+	case a_i_TEH:
+	    tempc = a_m_TEH;
+	    break;
+	case a_i_THEH:
+	    tempc = a_m_THEH;
+	    break;
+	case a_i_JEEM:
+	    tempc = a_m_JEEM;
+	    break;
+	case a_i_HAH:
+	    tempc = a_m_HAH;
+	    break;
+	case a_i_KHAH:
+	    tempc = a_m_KHAH;
+	    break;
+	case a_i_SEEN:
+	    tempc = a_m_SEEN;
+	    break;
+	case a_i_SHEEN:
+	    tempc = a_m_SHEEN;
+	    break;
+	case a_i_SAD:
+	    tempc = a_m_SAD;
+	    break;
+	case a_i_DAD:
+	    tempc = a_m_DAD;
+	    break;
+	case a_i_TAH:
+	    tempc = a_m_TAH;
+	    break;
+	case a_i_ZAH:
+	    tempc = a_m_ZAH;
+	    break;
+	case a_i_AIN:
+	    tempc = a_m_AIN;
+	    break;
+	case a_i_GHAIN:
+	    tempc = a_m_GHAIN;
+	    break;
+	case a_i_FEH:
+	    tempc = a_m_FEH;
+	    break;
+	case a_i_QAF:
+	    tempc = a_m_QAF;
+	    break;
+	case a_i_KAF:
+	    tempc = a_m_KAF;
+	    break;
+	case a_i_LAM:
+	    tempc = a_m_LAM;
+	    break;
+	case a_i_MEEM:
+	    tempc = a_m_MEEM;
+	    break;
+	case a_i_NOON:
+	    tempc = a_m_NOON;
+	    break;
+	case a_i_HEH:
+	    tempc = a_m_HEH;
+	    break;
+	case a_i_YEH:
+	    tempc = a_m_YEH;
+	    break;
+	default:
+	    tempc = 0;
+    }
+
+    return tempc;
+}
+
+
+/*
+ * Change shape - from Final to Medial
+ */
+    static int
+chg_c_f2m(cur_c)
+    int cur_c;
+{
+    int tempc;
+
+    switch (cur_c)
+    {
+	/* NOTE: these encodings are multi-positional, no ?
+	   case a_f_ALEF_MADDA:
+	   case a_f_ALEF_HAMZA_ABOVE:
+	   case a_f_ALEF_HAMZA_BELOW:
+	   */
+	case a_f_YEH_HAMZA:
+	    tempc = a_m_YEH_HAMZA;
+	    break;
+	case a_f_WAW_HAMZA:		/* exceptions */
+	case a_f_ALEF:
+	case a_f_TEH_MARBUTA:
+	case a_f_DAL:
+	case a_f_THAL:
+	case a_f_REH:
+	case a_f_ZAIN:
+	case a_f_WAW:
+	case a_f_ALEF_MAKSURA:
+	    tempc = cur_c;
+	    break;
+	case a_f_BEH:
+	    tempc = a_m_BEH;
+	    break;
+	case a_f_TEH:
+	    tempc = a_m_TEH;
+	    break;
+	case a_f_THEH:
+	    tempc = a_m_THEH;
+	    break;
+	case a_f_JEEM:
+	    tempc = a_m_JEEM;
+	    break;
+	case a_f_HAH:
+	    tempc = a_m_HAH;
+	    break;
+	case a_f_KHAH:
+	    tempc = a_m_KHAH;
+	    break;
+	case a_f_SEEN:
+	    tempc = a_m_SEEN;
+	    break;
+	case a_f_SHEEN:
+	    tempc = a_m_SHEEN;
+	    break;
+	case a_f_SAD:
+	    tempc = a_m_SAD;
+	    break;
+	case a_f_DAD:
+	    tempc = a_m_DAD;
+	    break;
+	case a_f_TAH:
+	    tempc = a_m_TAH;
+	    break;
+	case a_f_ZAH:
+	    tempc = a_m_ZAH;
+	    break;
+	case a_f_AIN:
+	    tempc = a_m_AIN;
+	    break;
+	case a_f_GHAIN:
+	    tempc = a_m_GHAIN;
+	    break;
+	case a_f_FEH:
+	    tempc = a_m_FEH;
+	    break;
+	case a_f_QAF:
+	    tempc = a_m_QAF;
+	    break;
+	case a_f_KAF:
+	    tempc = a_m_KAF;
+	    break;
+	case a_f_LAM:
+	    tempc = a_m_LAM;
+	    break;
+	case a_f_MEEM:
+	    tempc = a_m_MEEM;
+	    break;
+	case a_f_NOON:
+	    tempc = a_m_NOON;
+	    break;
+	case a_f_HEH:
+	    tempc = a_m_HEH;
+	    break;
+	case a_f_YEH:
+	    tempc = a_m_YEH;
+	    break;
+	    /* NOTE: these encodings are multi-positional, no ?
+		case a_f_LAM_ALEF_MADDA_ABOVE:
+		case a_f_LAM_ALEF_HAMZA_ABOVE:
+		case a_f_LAM_ALEF_HAMZA_BELOW:
+		case a_f_LAM_ALEF:
+		*/
+	default:
+	    tempc = 0;
+    }
+
+    return tempc;
+}
+
+
+/*
+ * Change shape - from Combination (2 char) to an Isolated
+ */
+    static int
+chg_c_laa2i(hid_c)
+    int hid_c;
+{
+    int tempc;
+
+    switch (hid_c)
+    {
+	case a_ALEF_MADDA:
+	    tempc = a_s_LAM_ALEF_MADDA_ABOVE;
+	    break;
+	case a_ALEF_HAMZA_ABOVE:
+	    tempc = a_s_LAM_ALEF_HAMZA_ABOVE;
+	    break;
+	case a_ALEF_HAMZA_BELOW:
+	    tempc = a_s_LAM_ALEF_HAMZA_BELOW;
+	    break;
+	case a_ALEF:
+	    tempc = a_s_LAM_ALEF;
+	    break;
+	default:
+	    tempc = 0;
+    }
+
+    return tempc;
+}
+
+
+/*
+ * Change shape - from Combination-Isolated to Final
+ */
+    static int
+chg_c_laa2f(hid_c)
+    int hid_c;
+{
+    int tempc;
+
+    switch (hid_c)
+    {
+	case a_ALEF_MADDA:
+	    tempc = a_f_LAM_ALEF_MADDA_ABOVE;
+	    break;
+	case a_ALEF_HAMZA_ABOVE:
+	    tempc = a_f_LAM_ALEF_HAMZA_ABOVE;
+	    break;
+	case a_ALEF_HAMZA_BELOW:
+	    tempc = a_f_LAM_ALEF_HAMZA_BELOW;
+	    break;
+	case a_ALEF:
+	    tempc = a_f_LAM_ALEF;
+	    break;
+	default:
+	    tempc = 0;
+    }
+
+    return tempc;
+}
+
+/*
+ * Do "half-shaping" on character "c".  Return zero if no shaping.
+ */
+    static int
+half_shape(c)
+    int		c;
+{
+    if (A_is_a(c))
+	return chg_c_a2i(c);
+    if (A_is_valid(c) && A_is_f(c))
+	return chg_c_f2m(c);
+    return 0;
+}
+
+/*
+ * Do Arabic shaping on character "c".  Returns the shaped character.
+ * out:    "ccp" points to the first byte of the character to be shaped.
+ * in/out: "c1p" points to the first composing char for "c".
+ * in:     "prev_c"  is the previous character (not shaped)
+ * in:     "prev_c1" is the first composing char for the previous char
+ *		     (not shaped)
+ * in:     "next_c"  is the next character (not shaped).
+ */
+    int
+arabic_shape(c, ccp, c1p, prev_c, prev_c1, next_c)
+    int		c;
+    int		*ccp;
+    int		*c1p;
+    int		prev_c;
+    int		prev_c1;
+    int		next_c;
+{
+    int		curr_c;
+    int		shape_c;
+    int		curr_laa;
+    int		prev_laa;
+
+    /* Deal only with Arabic character, pass back all others */
+    if (!A_is_ok(c))
+	return c;
+
+    /* half-shape current and previous character */
+    shape_c = half_shape(prev_c);
+
+    /* Save away current character */
+    curr_c = c;
+
+    curr_laa = A_firstc_laa(c, *c1p);
+    prev_laa = A_firstc_laa(prev_c, prev_c1);
+
+    if (curr_laa)
+    {
+	if (A_is_valid(prev_c) && !A_is_f(shape_c)
+					 && !A_is_s(shape_c) && !prev_laa)
+	    curr_c = chg_c_laa2f(curr_laa);
+	else
+	    curr_c = chg_c_laa2i(curr_laa);
+
+	/* Remove the composing character */
+	*c1p = 0;
+    }
+    else if (!A_is_valid(prev_c) && A_is_valid(next_c))
+	curr_c = chg_c_a2i(c);
+    else if (!shape_c || A_is_f(shape_c) || A_is_s(shape_c) || prev_laa)
+	curr_c = A_is_valid(next_c) ? chg_c_a2i(c) : chg_c_a2s(c);
+    else if (A_is_valid(next_c))
+	curr_c = A_is_iso(c) ? chg_c_a2m(c) : chg_c_i2m(c);
+    else if (A_is_valid(prev_c))
+	curr_c = chg_c_a2f(c);
+    else
+	curr_c = chg_c_a2s(c);
+
+    /* Sanity check -- curr_c should, in the future, never be 0.
+     * We should, in the future, insert a fatal error here. */
+    if (curr_c == NUL)
+	curr_c = c;
+
+    if (curr_c != c && ccp != NULL)
+    {
+	char_u buf[MB_MAXBYTES];
+
+	/* Update the first byte of the character. */
+	(*mb_char2bytes)(curr_c, buf);
+	*ccp = buf[0];
+    }
+
+    /* Return the shaped character */
+    return curr_c;
+}
+
+
+/*
+ * A_firstc_laa returns first character of LAA combination if it exists
+ */
+    static int
+A_firstc_laa(c, c1)
+    int c;	/* base character */
+    int c1;	/* first composing character */
+{
+    if (c1 != NUL && c == a_LAM && !A_is_harakat(c1))
+	return c1;
+    return 0;
+}
+
+
+/*
+ * A_is_harakat returns TRUE if 'c' is an Arabic Harakat character
+ *		(harakat/tanween)
+ */
+    static int
+A_is_harakat(c)
+    int c;
+{
+    return (c >= a_FATHATAN && c <= a_SUKUN);
+}
+
+
+/*
+ * A_is_iso returns TRUE if 'c' is an Arabic ISO-8859-6 character
+ *		(alphabet/number/punctuation)
+ */
+    static int
+A_is_iso(c)
+    int c;
+{
+    return ((c >= a_HAMZA && c <= a_GHAIN)
+	    || (c >= a_TATWEEL && c <= a_HAMZA_BELOW)
+	    || c == a_MINI_ALEF);
+}
+
+
+/*
+ * A_is_formb returns TRUE if 'c' is an Arabic 10646-1 FormB character
+ *		(alphabet/number/punctuation)
+ */
+    static int
+A_is_formb(c)
+    int c;
+{
+    return ((c >= a_s_FATHATAN && c <= a_s_DAMMATAN)
+	    || c == a_s_KASRATAN
+	    || (c >= a_s_FATHA && c <= a_f_LAM_ALEF)
+	    || c == a_BYTE_ORDER_MARK);
+}
+
+
+/*
+ * A_is_ok returns TRUE if 'c' is an Arabic 10646 (8859-6 or Form-B)
+ */
+    static int
+A_is_ok(c)
+    int c;
+{
+    return (A_is_iso(c) || A_is_formb(c));
+}
+
+
+/*
+ * A_is_valid returns TRUE if 'c' is an Arabic 10646 (8859-6 or Form-B)
+ *		with some exceptions/exclusions
+ */
+    static int
+A_is_valid(c)
+    int c;
+{
+    return (A_is_ok(c) && !A_is_special(c));
+}
+
+
+/*
+ * A_is_special returns TRUE if 'c' is not a special Arabic character.
+ *		Specials don't adhere to most of the rules.
+ */
+    static int
+A_is_special(c)
+    int c;
+{
+    return (c == a_HAMZA || c == a_s_HAMZA);
+}
--- /dev/null
+++ b/arabic.h
@@ -1,0 +1,258 @@
+/* vi:set ts=8 sts=4 sw=4:
+ *
+ * VIM - Vi IMproved    by Bram Moolenaar
+ *
+ * Do ":help uganda"  in Vim to read copying and usage conditions.
+ * Do ":help credits" in Vim to see a list of people who contributed.
+ */
+
+/*
+ * Arabic characters are categorized into following types:
+ *
+ * Isolated	- iso-8859-6 form	  char denoted with	a_*
+ * Initial	- unicode form-B start	  char denoted with	a_i_*
+ * Medial	- unicode form-B middle   char denoted with	a_m_*
+ * Final	- unicode form-B final	  char denoted with	a_f_*
+ * Stand-Alone	- unicode form-B isolated char denoted with	a_s_* (NOT USED)
+ *
+ * --
+ *
+ * Author: Nadim Shaikli & Isam Bayazidi
+ * - (based on Unicode)
+ *
+ */
+
+/*
+ * Arabic ISO-10646-1 character set definition
+ */
+
+/*
+ * Arabic ISO-8859-6 (subset of 10646; 0600 - 06FF)
+ */
+#define a_COMMA				0x060C
+#define a_SEMICOLON			0x061B
+#define a_QUESTION			0x061F
+#define a_HAMZA				0x0621
+#define a_ALEF_MADDA			0x0622
+#define a_ALEF_HAMZA_ABOVE		0x0623
+#define a_WAW_HAMZA			0x0624
+#define a_ALEF_HAMZA_BELOW		0x0625
+#define a_YEH_HAMZA			0x0626
+#define a_ALEF				0x0627
+#define a_BEH				0x0628
+#define a_TEH_MARBUTA			0x0629
+#define a_TEH				0x062a
+#define a_THEH				0x062b
+#define a_JEEM				0x062c
+#define a_HAH				0x062d
+#define a_KHAH				0x062e
+#define a_DAL				0x062f
+#define a_THAL				0x0630
+#define a_REH				0x0631
+#define a_ZAIN				0x0632
+#define a_SEEN				0x0633
+#define a_SHEEN				0x0634
+#define a_SAD				0x0635
+#define a_DAD				0x0636
+#define a_TAH				0x0637
+#define a_ZAH				0x0638
+#define a_AIN				0x0639
+#define a_GHAIN				0x063a
+#define a_TATWEEL			0x0640
+#define a_FEH				0x0641
+#define a_QAF				0x0642
+#define a_KAF				0x0643
+#define a_LAM				0x0644
+#define a_MEEM				0x0645
+#define a_NOON				0x0646
+#define a_HEH				0x0647
+#define a_WAW				0x0648
+#define a_ALEF_MAKSURA			0x0649
+#define a_YEH				0x064a
+
+#define a_FATHATAN			0x064b
+#define a_DAMMATAN			0x064c
+#define a_KASRATAN			0x064d
+#define a_FATHA				0x064e
+#define a_DAMMA				0x064f
+#define a_KASRA				0x0650
+#define a_SHADDA			0x0651
+#define a_SUKUN				0x0652
+
+#define a_MADDA_ABOVE			0x0653
+#define a_HAMZA_ABOVE			0x0654
+#define a_HAMZA_BELOW			0x0655
+
+#define a_ZERO				0x0660
+#define a_ONE				0x0661
+#define a_TWO				0x0662
+#define a_THREE				0x0663
+#define a_FOUR				0x0664
+#define a_FIVE				0x0665
+#define a_SIX				0x0666
+#define a_SEVEN				0x0667
+#define a_EIGHT				0x0668
+#define a_NINE				0x0669
+#define a_PERCENT			0x066a
+#define a_DECIMAL			0x066b
+#define a_THOUSANDS			0x066c
+#define a_STAR				0x066d
+#define a_MINI_ALEF			0x0670
+/* Rest of 8859-6 does not relate to Arabic */
+
+/*
+ * Arabic Presentation Form-B (subset of 10646; FE70 - FEFF)
+ *
+ *  s -> isolated
+ *  i -> initial
+ *  m -> medial
+ *  f -> final
+ *
+ */
+#define a_s_FATHATAN			0xfe70
+#define a_m_TATWEEL_FATHATAN		0xfe71
+#define a_s_DAMMATAN			0xfe72
+
+#define a_s_KASRATAN			0xfe74
+
+#define a_s_FATHA			0xfe76
+#define a_m_FATHA			0xfe77
+#define a_s_DAMMA			0xfe78
+#define a_m_DAMMA			0xfe79
+#define a_s_KASRA			0xfe7a
+#define a_m_KASRA			0xfe7b
+#define a_s_SHADDA			0xfe7c
+#define a_m_SHADDA			0xfe7d
+#define a_s_SUKUN			0xfe7e
+#define a_m_SUKUN			0xfe7f
+
+#define a_s_HAMZA			0xfe80
+#define a_s_ALEF_MADDA			0xfe81
+#define a_f_ALEF_MADDA			0xfe82
+#define a_s_ALEF_HAMZA_ABOVE		0xfe83
+#define a_f_ALEF_HAMZA_ABOVE		0xfe84
+#define a_s_WAW_HAMZA			0xfe85
+#define a_f_WAW_HAMZA			0xfe86
+#define a_s_ALEF_HAMZA_BELOW		0xfe87
+#define a_f_ALEF_HAMZA_BELOW		0xfe88
+#define a_s_YEH_HAMZA			0xfe89
+#define a_f_YEH_HAMZA			0xfe8a
+#define a_i_YEH_HAMZA			0xfe8b
+#define a_m_YEH_HAMZA			0xfe8c
+#define a_s_ALEF			0xfe8d
+#define a_f_ALEF			0xfe8e
+#define a_s_BEH				0xfe8f
+#define a_f_BEH				0xfe90
+#define a_i_BEH				0xfe91
+#define a_m_BEH				0xfe92
+#define a_s_TEH_MARBUTA			0xfe93
+#define a_f_TEH_MARBUTA			0xfe94
+#define a_s_TEH				0xfe95
+#define a_f_TEH				0xfe96
+#define a_i_TEH				0xfe97
+#define a_m_TEH				0xfe98
+#define a_s_THEH			0xfe99
+#define a_f_THEH			0xfe9a
+#define a_i_THEH			0xfe9b
+#define a_m_THEH			0xfe9c
+#define a_s_JEEM			0xfe9d
+#define a_f_JEEM			0xfe9e
+#define a_i_JEEM			0xfe9f
+#define a_m_JEEM			0xfea0
+#define a_s_HAH				0xfea1
+#define a_f_HAH				0xfea2
+#define a_i_HAH				0xfea3
+#define a_m_HAH				0xfea4
+#define a_s_KHAH			0xfea5
+#define a_f_KHAH			0xfea6
+#define a_i_KHAH			0xfea7
+#define a_m_KHAH			0xfea8
+#define a_s_DAL				0xfea9
+#define a_f_DAL				0xfeaa
+#define a_s_THAL			0xfeab
+#define a_f_THAL			0xfeac
+#define a_s_REH				0xfead
+#define a_f_REH				0xfeae
+#define a_s_ZAIN			0xfeaf
+#define a_f_ZAIN			0xfeb0
+#define a_s_SEEN			0xfeb1
+#define a_f_SEEN			0xfeb2
+#define a_i_SEEN			0xfeb3
+#define a_m_SEEN			0xfeb4
+#define a_s_SHEEN			0xfeb5
+#define a_f_SHEEN			0xfeb6
+#define a_i_SHEEN			0xfeb7
+#define a_m_SHEEN			0xfeb8
+#define a_s_SAD				0xfeb9
+#define a_f_SAD				0xfeba
+#define a_i_SAD				0xfebb
+#define a_m_SAD				0xfebc
+#define a_s_DAD				0xfebd
+#define a_f_DAD				0xfebe
+#define a_i_DAD				0xfebf
+#define a_m_DAD				0xfec0
+#define a_s_TAH				0xfec1
+#define a_f_TAH				0xfec2
+#define a_i_TAH				0xfec3
+#define a_m_TAH				0xfec4
+#define a_s_ZAH				0xfec5
+#define a_f_ZAH				0xfec6
+#define a_i_ZAH				0xfec7
+#define a_m_ZAH				0xfec8
+#define a_s_AIN				0xfec9
+#define a_f_AIN				0xfeca
+#define a_i_AIN				0xfecb
+#define a_m_AIN				0xfecc
+#define a_s_GHAIN			0xfecd
+#define a_f_GHAIN			0xfece
+#define a_i_GHAIN			0xfecf
+#define a_m_GHAIN			0xfed0
+#define a_s_FEH				0xfed1
+#define a_f_FEH				0xfed2
+#define a_i_FEH				0xfed3
+#define a_m_FEH				0xfed4
+#define a_s_QAF				0xfed5
+#define a_f_QAF				0xfed6
+#define a_i_QAF				0xfed7
+#define a_m_QAF				0xfed8
+#define a_s_KAF				0xfed9
+#define a_f_KAF				0xfeda
+#define a_i_KAF				0xfedb
+#define a_m_KAF				0xfedc
+#define a_s_LAM				0xfedd
+#define a_f_LAM				0xfede
+#define a_i_LAM				0xfedf
+#define a_m_LAM				0xfee0
+#define a_s_MEEM			0xfee1
+#define a_f_MEEM			0xfee2
+#define a_i_MEEM			0xfee3
+#define a_m_MEEM			0xfee4
+#define a_s_NOON			0xfee5
+#define a_f_NOON			0xfee6
+#define a_i_NOON			0xfee7
+#define a_m_NOON			0xfee8
+#define a_s_HEH				0xfee9
+#define a_f_HEH				0xfeea
+#define a_i_HEH				0xfeeb
+#define a_m_HEH				0xfeec
+#define a_s_WAW				0xfeed
+#define a_f_WAW				0xfeee
+#define a_s_ALEF_MAKSURA		0xfeef
+#define a_f_ALEF_MAKSURA		0xfef0
+#define a_s_YEH				0xfef1
+#define a_f_YEH				0xfef2
+#define a_i_YEH				0xfef3
+#define a_m_YEH				0xfef4
+#define a_s_LAM_ALEF_MADDA_ABOVE	0xfef5
+#define a_f_LAM_ALEF_MADDA_ABOVE	0xfef6
+#define a_s_LAM_ALEF_HAMZA_ABOVE	0xfef7
+#define a_f_LAM_ALEF_HAMZA_ABOVE	0xfef8
+#define a_s_LAM_ALEF_HAMZA_BELOW	0xfef9
+#define a_f_LAM_ALEF_HAMZA_BELOW	0xfefa
+#define a_s_LAM_ALEF			0xfefb
+#define a_f_LAM_ALEF			0xfefc
+
+#define a_BYTE_ORDER_MARK		0xfeff
+
+/* Range of Arabic characters that might be shaped. */
+#define ARABIC_CHAR(c)		((c) >= a_HAMZA && (c) <= a_MINI_ALEF)
--- /dev/null
+++ b/ascii.h
@@ -1,0 +1,193 @@
+/* vi:set ts=8 sts=4 sw=4:
+ *
+ * VIM - Vi IMproved	by Bram Moolenaar
+ *
+ * Do ":help uganda"  in Vim to read copying and usage conditions.
+ * Do ":help credits" in Vim to see a list of people who contributed.
+ */
+
+/*
+ * Definitions of various common control characters.
+ * For EBCDIC we have to use different values.
+ */
+
+#ifndef EBCDIC
+
+/* IF_EB(ASCII_constant, EBCDIC_constant) */
+#define IF_EB(a, b)	a
+
+#define CharOrd(x)	((x) < 'a' ? (x) - 'A' : (x) - 'a')
+#define CharOrdLow(x)	((x) - 'a')
+#define CharOrdUp(x)	((x) - 'A')
+#define ROT13(c, a)	(((((c) - (a)) + 13) % 26) + (a))
+
+#define NUL		'\000'
+#define BELL		'\007'
+#define BS		'\010'
+#define TAB		'\011'
+#define NL		'\012'
+#define NL_STR		(char_u *)"\012"
+#define FF		'\014'
+#define CAR		'\015'	/* CR is used by Mac OS X */
+#define ESC		'\033'
+#define ESC_STR		(char_u *)"\033"
+#define ESC_STR_nc	"\033"
+#define DEL		0x7f
+#define DEL_STR		(char_u *)"\177"
+#define CSI		0x9b	/* Control Sequence Introducer */
+#define CSI_STR		"\233"
+#define DCS		0x90	/* Device Control String */
+#define STERM		0x9c	/* String Terminator */
+
+#define POUND		0xA3
+
+#define Ctrl_chr(x)	(TOUPPER_ASC(x) ^ 0x40) /* '?' -> DEL, '@' -> ^@, etc. */
+#define Meta(x)		((x) | 0x80)
+
+#define CTRL_F_STR	"\006"
+#define CTRL_H_STR	"\010"
+#define CTRL_V_STR	"\026"
+
+#define Ctrl_AT		0   /* @ */
+#define Ctrl_A		1
+#define Ctrl_B		2
+#define Ctrl_C		3
+#define Ctrl_D		4
+#define Ctrl_E		5
+#define Ctrl_F		6
+#define Ctrl_G		7
+#define Ctrl_H		8
+#define Ctrl_I		9
+#define Ctrl_J		10
+#define Ctrl_K		11
+#define Ctrl_L		12
+#define Ctrl_M		13
+#define Ctrl_N		14
+#define Ctrl_O		15
+#define Ctrl_P		16
+#define Ctrl_Q		17
+#define Ctrl_R		18
+#define Ctrl_S		19
+#define Ctrl_T		20
+#define Ctrl_U		21
+#define Ctrl_V		22
+#define Ctrl_W		23
+#define Ctrl_X		24
+#define Ctrl_Y		25
+#define Ctrl_Z		26
+			    /* CTRL- [ Left Square Bracket == ESC*/
+#define Ctrl_BSL	28  /* \ BackSLash */
+#define Ctrl_RSB	29  /* ] Right Square Bracket */
+#define Ctrl_HAT	30  /* ^ */
+#define Ctrl__		31
+
+#else
+
+/* EBCDIC */
+
+/* IF_EB(ASCII_constant, EBCDIC_constant) */
+#define IF_EB(a, b)	b
+
+/*
+ * Finding the position in the alphabet is not straightforward in EBCDIC.
+ * There are gaps in the code table.
+ * 'a' + 1 == 'b', but: 'i' + 7 == 'j' and 'r' + 8 == 's'
+ */
+#define CharOrd__(c) ((c) < ('j' - 'a') ? (c) : ((c) < ('s' - 'a') ? (c) - 7 : (c) - 7 - 8))
+#define CharOrdLow(x) (CharOrd__((x) - 'a'))
+#define CharOrdUp(x) (CharOrd__((x) - 'A'))
+#define CharOrd(x) (isupper(x) ? CharOrdUp(x) : CharOrdLow(x))
+
+#define EBCDIC_CHAR_ADD_(x) ((x) < 0?'a':(x)>25?'z':"abcdefghijklmnopqrstuvwxyz"[x])
+#define EBCDIC_CHAR_ADD(c,s) (isupper(c) ? toupper(EBCDIC_CHAR_ADD_(CharOrdUp(c)+(s))) : EBCDIC_CHAR_ADD_(CharOrdLow(c)+(s)))
+
+#define R13_(c) ("abcdefghijklmnopqrstuvwxyz"[((c) + 13) % 26])
+#define ROT13(c, a)  (isupper(c) ? toupper(R13_(CharOrdUp(c))) : R13_(CharOrdLow(c)))
+
+#define NUL		'\000'
+#define BELL		'\x2f'
+#define BS		'\x16'
+#define TAB		'\x05'
+#define NL		'\x15'
+#define NL_STR		(char_u *)"\x15"
+#define FF		'\x0C'
+#define CAR		'\x0D'
+#define ESC		'\x27'
+#define ESC_STR		(char_u *)"\x27"
+#define ESC_STR_nc	"\x27"
+#define DEL		0x07
+#define DEL_STR		(char_u *)"\007"
+/* TODO: EBCDIC Code page dependent (here 1047) */
+#define CSI		0x9b	/* Control Sequence Introducer */
+#define CSI_STR		"\233"
+#define DCS		0x90	/* Device Control String */
+#define STERM		0x9c	/* String Terminator */
+
+#define POUND		'£'
+
+#define CTRL_F_STR	"\056"
+#define CTRL_H_STR	"\026"
+#define CTRL_V_STR	"\062"
+
+#define Ctrl_AT		0x00   /* @ */
+#define Ctrl_A		0x01
+#define Ctrl_B		0x02
+#define Ctrl_C		0x03
+#define Ctrl_D		0x37
+#define Ctrl_E		0x2D
+#define Ctrl_F		0x2E
+#define Ctrl_G		0x2F
+#define Ctrl_H		0x16
+#define Ctrl_I		0x05
+#define Ctrl_J		0x15
+#define Ctrl_K		0x0B
+#define Ctrl_L		0x0C
+#define Ctrl_M		0x0D
+#define Ctrl_N		0x0E
+#define Ctrl_O		0x0F
+#define Ctrl_P		0x10
+#define Ctrl_Q		0x11
+#define Ctrl_R		0x12
+#define Ctrl_S		0x13
+#define Ctrl_T		0x3C
+#define Ctrl_U		0x3D
+#define Ctrl_V		0x32
+#define Ctrl_W		0x26
+#define Ctrl_X		0x18
+#define Ctrl_Y		0x19
+#define Ctrl_Z		0x3F
+			    /* CTRL- [ Left Square Bracket == ESC*/
+#define Ctrl_RSB	0x1D  /* ] Right Square Bracket */
+#define Ctrl_BSL	0x1C  /* \ BackSLash */
+#define Ctrl_HAT	0x1E  /* ^ */
+#define Ctrl__		0x1F
+
+#define Ctrl_chr(x)	(CtrlTable[(x)])
+extern char CtrlTable[];
+
+#define CtrlChar(x)	((x < ' ') ? CtrlCharTable[(x)] : 0)
+extern char CtrlCharTable[];
+
+#define MetaChar(x)	((x < ' ') ? MetaCharTable[(x)] : 0)
+extern char MetaCharTable[];
+
+#endif /* defined EBCDIC */
+
+/*
+ * Character that separates dir names in a path.
+ * For MS-DOS, WIN32 and OS/2 we use a backslash.  A slash mostly works
+ * fine, but there are places where it doesn't (e.g. in a command name).
+ * For Acorn we use a dot.
+ */
+#ifdef BACKSLASH_IN_FILENAME
+# define PATHSEP	psepc
+# define PATHSEPSTR	pseps
+#else
+# ifdef RISCOS
+#  define PATHSEP	'.'
+#  define PATHSEPSTR	"."
+# else
+#  define PATHSEP	'/'
+#  define PATHSEPSTR	"/"
+# endif
+#endif
--- /dev/null
+++ b/buffer.c
@@ -1,0 +1,5517 @@
+/* vi:set ts=8 sts=4 sw=4:
+ *
+ * VIM - Vi IMproved	by Bram Moolenaar
+ *
+ * Do ":help uganda"  in Vim to read copying and usage conditions.
+ * Do ":help credits" in Vim to see a list of people who contributed.
+ * See README.txt for an overview of the Vim source code.
+ */
+
+/*
+ * buffer.c: functions for dealing with the buffer structure
+ */
+
+/*
+ * The buffer list is a double linked list of all buffers.
+ * Each buffer can be in one of these states:
+ * never loaded: BF_NEVERLOADED is set, only the file name is valid
+ *   not loaded: b_ml.ml_mfp == NULL, no memfile allocated
+ *	 hidden: b_nwindows == 0, loaded but not displayed in a window
+ *	 normal: loaded and displayed in a window
+ *
+ * Instead of storing file names all over the place, each file name is
+ * stored in the buffer list. It can be referenced by a number.
+ *
+ * The current implementation remembers all file names ever used.
+ */
+
+#include "vim.h"
+
+#if defined(FEAT_CMDL_COMPL) || defined(FEAT_LISTCMDS) || defined(FEAT_EVAL) || defined(FEAT_PERL)
+static char_u	*buflist_match __ARGS((regprog_T *prog, buf_T *buf));
+# define HAVE_BUFLIST_MATCH
+static char_u	*fname_match __ARGS((regprog_T *prog, char_u *name));
+#endif
+static void	buflist_setfpos __ARGS((buf_T *buf, win_T *win, linenr_T lnum, colnr_T col, int copy_options));
+static wininfo_T *find_wininfo __ARGS((buf_T *buf));
+#ifdef UNIX
+static buf_T	*buflist_findname_stat __ARGS((char_u *ffname, struct stat *st));
+static int	otherfile_buf __ARGS((buf_T *buf, char_u *ffname, struct stat *stp));
+static int	buf_same_ino __ARGS((buf_T *buf, struct stat *stp));
+#else
+static int	otherfile_buf __ARGS((buf_T *buf, char_u *ffname));
+#endif
+#ifdef FEAT_TITLE
+static int	ti_change __ARGS((char_u *str, char_u **last));
+#endif
+static void	free_buffer __ARGS((buf_T *));
+static void	free_buffer_stuff __ARGS((buf_T *buf, int free_options));
+static void	clear_wininfo __ARGS((buf_T *buf));
+
+#ifdef UNIX
+# define dev_T dev_t
+#else
+# define dev_T unsigned
+#endif
+
+#if defined(FEAT_SIGNS)
+static void insert_sign __ARGS((buf_T *buf, signlist_T *prev, signlist_T *next, int id, linenr_T lnum, int typenr));
+static void buf_delete_signs __ARGS((buf_T *buf));
+#endif
+
+/*
+ * Open current buffer, that is: open the memfile and read the file into memory
+ * return FAIL for failure, OK otherwise
+ */
+    int
+open_buffer(read_stdin, eap)
+    int		read_stdin;	    /* read file from stdin */
+    exarg_T	*eap;		    /* for forced 'ff' and 'fenc' or NULL */
+{
+    int		retval = OK;
+#ifdef FEAT_AUTOCMD
+    buf_T	*old_curbuf;
+#endif
+
+    /*
+     * The 'readonly' flag is only set when BF_NEVERLOADED is being reset.
+     * When re-entering the same buffer, it should not change, because the
+     * user may have reset the flag by hand.
+     */
+    if (readonlymode && curbuf->b_ffname != NULL
+					&& (curbuf->b_flags & BF_NEVERLOADED))
+	curbuf->b_p_ro = TRUE;
+
+    if (ml_open(curbuf) == FAIL)
+    {
+	/*
+	 * There MUST be a memfile, otherwise we can't do anything
+	 * If we can't create one for the current buffer, take another buffer
+	 */
+	close_buffer(NULL, curbuf, 0);
+	for (curbuf = firstbuf; curbuf != NULL; curbuf = curbuf->b_next)
+	    if (curbuf->b_ml.ml_mfp != NULL)
+		break;
+	/*
+	 * if there is no memfile at all, exit
+	 * This is OK, since there are no changes to loose.
+	 */
+	if (curbuf == NULL)
+	{
+	    EMSG(_("E82: Cannot allocate any buffer, exiting..."));
+	    getout(2);
+	}
+	EMSG(_("E83: Cannot allocate buffer, using other one..."));
+	enter_buffer(curbuf);
+	return FAIL;
+    }
+
+#ifdef FEAT_AUTOCMD
+    /* The autocommands in readfile() may change the buffer, but only AFTER
+     * reading the file. */
+    old_curbuf = curbuf;
+    modified_was_set = FALSE;
+#endif
+
+    /* mark cursor position as being invalid */
+    changed_line_abv_curs();
+
+    if (curbuf->b_ffname != NULL
+#ifdef FEAT_NETBEANS_INTG
+	    && netbeansReadFile
+#endif
+       )
+    {
+#ifdef FEAT_NETBEANS_INTG
+	int oldFire = netbeansFireChanges;
+
+	netbeansFireChanges = 0;
+#endif
+	retval = readfile(curbuf->b_ffname, curbuf->b_fname,
+		  (linenr_T)0, (linenr_T)0, (linenr_T)MAXLNUM, eap, READ_NEW);
+#ifdef FEAT_NETBEANS_INTG
+	netbeansFireChanges = oldFire;
+#endif
+	/* Help buffer is filtered. */
+	if (curbuf->b_help)
+	    fix_help_buffer();
+    }
+    else if (read_stdin)
+    {
+	int		save_bin = curbuf->b_p_bin;
+	linenr_T	line_count;
+
+	/*
+	 * First read the text in binary mode into the buffer.
+	 * Then read from that same buffer and append at the end.  This makes
+	 * it possible to retry when 'fileformat' or 'fileencoding' was
+	 * guessed wrong.
+	 */
+	curbuf->b_p_bin = TRUE;
+	retval = readfile(NULL, NULL, (linenr_T)0,
+		  (linenr_T)0, (linenr_T)MAXLNUM, NULL, READ_NEW + READ_STDIN);
+	curbuf->b_p_bin = save_bin;
+	if (retval == OK)
+	{
+	    line_count = curbuf->b_ml.ml_line_count;
+	    retval = readfile(NULL, NULL, (linenr_T)line_count,
+			    (linenr_T)0, (linenr_T)MAXLNUM, eap, READ_BUFFER);
+	    if (retval == OK)
+	    {
+		/* Delete the binary lines. */
+		while (--line_count >= 0)
+		    ml_delete((linenr_T)1, FALSE);
+	    }
+	    else
+	    {
+		/* Delete the converted lines. */
+		while (curbuf->b_ml.ml_line_count > line_count)
+		    ml_delete(line_count, FALSE);
+	    }
+	    /* Put the cursor on the first line. */
+	    curwin->w_cursor.lnum = 1;
+	    curwin->w_cursor.col = 0;
+#ifdef FEAT_AUTOCMD
+# ifdef FEAT_EVAL
+	    apply_autocmds_retval(EVENT_STDINREADPOST, NULL, NULL, FALSE,
+							curbuf, &retval);
+# else
+	    apply_autocmds(EVENT_STDINREADPOST, NULL, NULL, FALSE, curbuf);
+# endif
+#endif
+	}
+    }
+
+    /* if first time loading this buffer, init b_chartab[] */
+    if (curbuf->b_flags & BF_NEVERLOADED)
+	(void)buf_init_chartab(curbuf, FALSE);
+
+    /*
+     * Set/reset the Changed flag first, autocmds may change the buffer.
+     * Apply the automatic commands, before processing the modelines.
+     * So the modelines have priority over auto commands.
+     */
+    /* When reading stdin, the buffer contents always needs writing, so set
+     * the changed flag.  Unless in readonly mode: "ls | gview -".
+     * When interrupted and 'cpoptions' contains 'i' set changed flag. */
+    if ((read_stdin && !readonlymode && !bufempty())
+#ifdef FEAT_AUTOCMD
+		|| modified_was_set	/* ":set modified" used in autocmd */
+# ifdef FEAT_EVAL
+		|| (aborting() && vim_strchr(p_cpo, CPO_INTMOD) != NULL)
+# endif
+#endif
+		|| (got_int && vim_strchr(p_cpo, CPO_INTMOD) != NULL))
+	changed();
+    else if (retval != FAIL)
+	unchanged(curbuf, FALSE);
+    save_file_ff(curbuf);		/* keep this fileformat */
+
+    /* require "!" to overwrite the file, because it wasn't read completely */
+#ifdef FEAT_EVAL
+    if (aborting())
+#else
+    if (got_int)
+#endif
+	curbuf->b_flags |= BF_READERR;
+
+#ifdef FEAT_FOLDING
+    /* Need to update automatic folding.  Do this before the autocommands,
+     * they may use the fold info. */
+    foldUpdateAll(curwin);
+#endif
+
+#ifdef FEAT_AUTOCMD
+    /* need to set w_topline, unless some autocommand already did that. */
+    if (!(curwin->w_valid & VALID_TOPLINE))
+    {
+	curwin->w_topline = 1;
+# ifdef FEAT_DIFF
+	curwin->w_topfill = 0;
+# endif
+    }
+# ifdef FEAT_EVAL
+    apply_autocmds_retval(EVENT_BUFENTER, NULL, NULL, FALSE, curbuf, &retval);
+# else
+    apply_autocmds(EVENT_BUFENTER, NULL, NULL, FALSE, curbuf);
+# endif
+#endif
+
+    if (retval != FAIL)
+    {
+#ifdef FEAT_AUTOCMD
+	/*
+	 * The autocommands may have changed the current buffer.  Apply the
+	 * modelines to the correct buffer, if it still exists and is loaded.
+	 */
+	if (buf_valid(old_curbuf) && old_curbuf->b_ml.ml_mfp != NULL)
+	{
+	    aco_save_T	aco;
+
+	    /* Go to the buffer that was opened. */
+	    aucmd_prepbuf(&aco, old_curbuf);
+#endif
+	    do_modelines(0);
+	    curbuf->b_flags &= ~(BF_CHECK_RO | BF_NEVERLOADED);
+
+#ifdef FEAT_AUTOCMD
+# ifdef FEAT_EVAL
+	    apply_autocmds_retval(EVENT_BUFWINENTER, NULL, NULL, FALSE, curbuf,
+								    &retval);
+# else
+	    apply_autocmds(EVENT_BUFWINENTER, NULL, NULL, FALSE, curbuf);
+# endif
+
+	    /* restore curwin/curbuf and a few other things */
+	    aucmd_restbuf(&aco);
+	}
+#endif
+    }
+
+    return retval;
+}
+
+/*
+ * Return TRUE if "buf" points to a valid buffer (in the buffer list).
+ */
+    int
+buf_valid(buf)
+    buf_T	*buf;
+{
+    buf_T	*bp;
+
+    for (bp = firstbuf; bp != NULL; bp = bp->b_next)
+	if (bp == buf)
+	    return TRUE;
+    return FALSE;
+}
+
+/*
+ * Close the link to a buffer.
+ * "action" is used when there is no longer a window for the buffer.
+ * It can be:
+ * 0			buffer becomes hidden
+ * DOBUF_UNLOAD		buffer is unloaded
+ * DOBUF_DELETE		buffer is unloaded and removed from buffer list
+ * DOBUF_WIPE		buffer is unloaded and really deleted
+ * When doing all but the first one on the current buffer, the caller should
+ * get a new buffer very soon!
+ *
+ * The 'bufhidden' option can force freeing and deleting.
+ */
+    void
+close_buffer(win, buf, action)
+    win_T	*win;		/* if not NULL, set b_last_cursor */
+    buf_T	*buf;
+    int		action;
+{
+#ifdef FEAT_AUTOCMD
+    int		is_curbuf;
+    int		nwindows = buf->b_nwindows;
+#endif
+    int		unload_buf = (action != 0);
+    int		del_buf = (action == DOBUF_DEL || action == DOBUF_WIPE);
+    int		wipe_buf = (action == DOBUF_WIPE);
+
+#ifdef FEAT_QUICKFIX
+    /*
+     * Force unloading or deleting when 'bufhidden' says so.
+     * The caller must take care of NOT deleting/freeing when 'bufhidden' is
+     * "hide" (otherwise we could never free or delete a buffer).
+     */
+    if (buf->b_p_bh[0] == 'd')		/* 'bufhidden' == "delete" */
+    {
+	del_buf = TRUE;
+	unload_buf = TRUE;
+    }
+    else if (buf->b_p_bh[0] == 'w')	/* 'bufhidden' == "wipe" */
+    {
+	del_buf = TRUE;
+	unload_buf = TRUE;
+	wipe_buf = TRUE;
+    }
+    else if (buf->b_p_bh[0] == 'u')	/* 'bufhidden' == "unload" */
+	unload_buf = TRUE;
+#endif
+
+    if (win != NULL)
+    {
+	/* Set b_last_cursor when closing the last window for the buffer.
+	 * Remember the last cursor position and window options of the buffer.
+	 * This used to be only for the current window, but then options like
+	 * 'foldmethod' may be lost with a ":only" command. */
+	if (buf->b_nwindows == 1)
+	    set_last_cursor(win);
+	buflist_setfpos(buf, win,
+		    win->w_cursor.lnum == 1 ? 0 : win->w_cursor.lnum,
+		    win->w_cursor.col, TRUE);
+    }
+
+#ifdef FEAT_AUTOCMD
+    /* When the buffer is no longer in a window, trigger BufWinLeave */
+    if (buf->b_nwindows == 1)
+    {
+	apply_autocmds(EVENT_BUFWINLEAVE, buf->b_fname, buf->b_fname,
+								  FALSE, buf);
+	if (!buf_valid(buf))	    /* autocommands may delete the buffer */
+	    return;
+
+	/* When the buffer becomes hidden, but is not unloaded, trigger
+	 * BufHidden */
+	if (!unload_buf)
+	{
+	    apply_autocmds(EVENT_BUFHIDDEN, buf->b_fname, buf->b_fname,
+								  FALSE, buf);
+	    if (!buf_valid(buf))	/* autocmds may delete the buffer */
+		return;
+	}
+# ifdef FEAT_EVAL
+	if (aborting())	    /* autocmds may abort script processing */
+	    return;
+# endif
+    }
+    nwindows = buf->b_nwindows;
+#endif
+
+    /* decrease the link count from windows (unless not in any window) */
+    if (buf->b_nwindows > 0)
+	--buf->b_nwindows;
+
+    /* Return when a window is displaying the buffer or when it's not
+     * unloaded. */
+    if (buf->b_nwindows > 0 || !unload_buf)
+    {
+#if 0	    /* why was this here? */
+	if (buf == curbuf)
+	    u_sync();	    /* sync undo before going to another buffer */
+#endif
+	return;
+    }
+
+    /* Always remove the buffer when there is no file name. */
+    if (buf->b_ffname == NULL)
+	del_buf = TRUE;
+
+    /*
+     * Free all things allocated for this buffer.
+     * Also calls the "BufDelete" autocommands when del_buf is TRUE.
+     */
+#ifdef FEAT_AUTOCMD
+    /* Remember if we are closing the current buffer.  Restore the number of
+     * windows, so that autocommands in buf_freeall() don't get confused. */
+    is_curbuf = (buf == curbuf);
+    buf->b_nwindows = nwindows;
+#endif
+
+    buf_freeall(buf, del_buf, wipe_buf);
+
+#ifdef FEAT_AUTOCMD
+    /* Autocommands may have deleted the buffer. */
+    if (!buf_valid(buf))
+	return;
+# ifdef FEAT_EVAL
+    if (aborting())	    /* autocmds may abort script processing */
+	return;
+# endif
+
+    /* Autocommands may have opened or closed windows for this buffer.
+     * Decrement the count for the close we do here. */
+    if (buf->b_nwindows > 0)
+	--buf->b_nwindows;
+
+    /*
+     * It's possible that autocommands change curbuf to the one being deleted.
+     * This might cause the previous curbuf to be deleted unexpectedly.  But
+     * in some cases it's OK to delete the curbuf, because a new one is
+     * obtained anyway.  Therefore only return if curbuf changed to the
+     * deleted buffer.
+     */
+    if (buf == curbuf && !is_curbuf)
+	return;
+#endif
+
+#ifdef FEAT_NETBEANS_INTG
+    if (usingNetbeans)
+	netbeans_file_closed(buf);
+#endif
+    /* Change directories when the 'acd' option is set. */
+    DO_AUTOCHDIR
+
+    /*
+     * Remove the buffer from the list.
+     */
+    if (wipe_buf)
+    {
+#ifdef FEAT_SUN_WORKSHOP
+	if (usingSunWorkShop)
+	    workshop_file_closed_lineno((char *)buf->b_ffname,
+			(int)buf->b_last_cursor.lnum);
+#endif
+	vim_free(buf->b_ffname);
+	vim_free(buf->b_sfname);
+	if (buf->b_prev == NULL)
+	    firstbuf = buf->b_next;
+	else
+	    buf->b_prev->b_next = buf->b_next;
+	if (buf->b_next == NULL)
+	    lastbuf = buf->b_prev;
+	else
+	    buf->b_next->b_prev = buf->b_prev;
+	free_buffer(buf);
+    }
+    else
+    {
+	if (del_buf)
+	{
+	    /* Free all internal variables and reset option values, to make
+	     * ":bdel" compatible with Vim 5.7. */
+	    free_buffer_stuff(buf, TRUE);
+
+	    /* Make it look like a new buffer. */
+	    buf->b_flags = BF_CHECK_RO | BF_NEVERLOADED;
+
+	    /* Init the options when loaded again. */
+	    buf->b_p_initialized = FALSE;
+	}
+	buf_clear_file(buf);
+	if (del_buf)
+	    buf->b_p_bl = FALSE;
+    }
+}
+
+/*
+ * Make buffer not contain a file.
+ */
+    void
+buf_clear_file(buf)
+    buf_T	*buf;
+{
+    buf->b_ml.ml_line_count = 1;
+    unchanged(buf, TRUE);
+#ifndef SHORT_FNAME
+    buf->b_shortname = FALSE;
+#endif
+    buf->b_p_eol = TRUE;
+    buf->b_start_eol = TRUE;
+#ifdef FEAT_MBYTE
+    buf->b_p_bomb = FALSE;
+#endif
+    buf->b_ml.ml_mfp = NULL;
+    buf->b_ml.ml_flags = ML_EMPTY;		/* empty buffer */
+#ifdef FEAT_NETBEANS_INTG
+    netbeans_deleted_all_lines(buf);
+#endif
+}
+
+/*
+ * buf_freeall() - free all things allocated for a buffer that are related to
+ * the file.
+ */
+/*ARGSUSED*/
+    void
+buf_freeall(buf, del_buf, wipe_buf)
+    buf_T	*buf;
+    int		del_buf;	/* buffer is going to be deleted */
+    int		wipe_buf;	/* buffer is going to be wiped out */
+{
+#ifdef FEAT_AUTOCMD
+    int		is_curbuf = (buf == curbuf);
+
+    apply_autocmds(EVENT_BUFUNLOAD, buf->b_fname, buf->b_fname, FALSE, buf);
+    if (!buf_valid(buf))	    /* autocommands may delete the buffer */
+	return;
+    if (del_buf && buf->b_p_bl)
+    {
+	apply_autocmds(EVENT_BUFDELETE, buf->b_fname, buf->b_fname, FALSE, buf);
+	if (!buf_valid(buf))	    /* autocommands may delete the buffer */
+	    return;
+    }
+    if (wipe_buf)
+    {
+	apply_autocmds(EVENT_BUFWIPEOUT, buf->b_fname, buf->b_fname,
+								  FALSE, buf);
+	if (!buf_valid(buf))	    /* autocommands may delete the buffer */
+	    return;
+    }
+# ifdef FEAT_EVAL
+    if (aborting())	    /* autocmds may abort script processing */
+	return;
+# endif
+
+    /*
+     * It's possible that autocommands change curbuf to the one being deleted.
+     * This might cause curbuf to be deleted unexpectedly.  But in some cases
+     * it's OK to delete the curbuf, because a new one is obtained anyway.
+     * Therefore only return if curbuf changed to the deleted buffer.
+     */
+    if (buf == curbuf && !is_curbuf)
+	return;
+#endif
+#ifdef FEAT_DIFF
+    diff_buf_delete(buf);	    /* Can't use 'diff' for unloaded buffer. */
+#endif
+
+#ifdef FEAT_FOLDING
+    /* No folds in an empty buffer. */
+# ifdef FEAT_WINDOWS
+    {
+	win_T		*win;
+	tabpage_T	*tp;
+
+	FOR_ALL_TAB_WINDOWS(tp, win)
+	    if (win->w_buffer == buf)
+		clearFolding(win);
+    }
+# else
+    if (curwin->w_buffer == buf)
+	clearFolding(curwin);
+# endif
+#endif
+
+#ifdef FEAT_TCL
+    tcl_buffer_free(buf);
+#endif
+    u_blockfree(buf);		    /* free the memory allocated for undo */
+    ml_close(buf, TRUE);	    /* close and delete the memline/memfile */
+    buf->b_ml.ml_line_count = 0;    /* no lines in buffer */
+    u_clearall(buf);		    /* reset all undo information */
+#ifdef FEAT_SYN_HL
+    syntax_clear(buf);		    /* reset syntax info */
+#endif
+    buf->b_flags &= ~BF_READERR;    /* a read error is no longer relevant */
+}
+
+/*
+ * Free a buffer structure and the things it contains related to the buffer
+ * itself (not the file, that must have been done already).
+ */
+    static void
+free_buffer(buf)
+    buf_T	*buf;
+{
+    free_buffer_stuff(buf, TRUE);
+#ifdef FEAT_MZSCHEME
+    mzscheme_buffer_free(buf);
+#endif
+#ifdef FEAT_PERL
+    perl_buf_free(buf);
+#endif
+#ifdef FEAT_PYTHON
+    python_buffer_free(buf);
+#endif
+#ifdef FEAT_RUBY
+    ruby_buffer_free(buf);
+#endif
+#ifdef FEAT_AUTOCMD
+    aubuflocal_remove(buf);
+#endif
+    vim_free(buf);
+}
+
+/*
+ * Free stuff in the buffer for ":bdel" and when wiping out the buffer.
+ */
+    static void
+free_buffer_stuff(buf, free_options)
+    buf_T	*buf;
+    int		free_options;		/* free options as well */
+{
+    if (free_options)
+    {
+	clear_wininfo(buf);		/* including window-local options */
+	free_buf_options(buf, TRUE);
+    }
+#ifdef FEAT_EVAL
+    vars_clear(&buf->b_vars.dv_hashtab); /* free all internal variables */
+    hash_init(&buf->b_vars.dv_hashtab);
+#endif
+#ifdef FEAT_USR_CMDS
+    uc_clear(&buf->b_ucmds);		/* clear local user commands */
+#endif
+#ifdef FEAT_SIGNS
+    buf_delete_signs(buf);		/* delete any signs */
+#endif
+#ifdef FEAT_LOCALMAP
+    map_clear_int(buf, MAP_ALL_MODES, TRUE, FALSE);  /* clear local mappings */
+    map_clear_int(buf, MAP_ALL_MODES, TRUE, TRUE);   /* clear local abbrevs */
+#endif
+#ifdef FEAT_MBYTE
+    vim_free(buf->b_start_fenc);
+    buf->b_start_fenc = NULL;
+#endif
+}
+
+/*
+ * Free the b_wininfo list for buffer "buf".
+ */
+    static void
+clear_wininfo(buf)
+    buf_T	*buf;
+{
+    wininfo_T	*wip;
+
+    while (buf->b_wininfo != NULL)
+    {
+	wip = buf->b_wininfo;
+	buf->b_wininfo = wip->wi_next;
+	if (wip->wi_optset)
+	{
+	    clear_winopt(&wip->wi_opt);
+#ifdef FEAT_FOLDING
+	    deleteFoldRecurse(&wip->wi_folds);
+#endif
+	}
+	vim_free(wip);
+    }
+}
+
+#if defined(FEAT_LISTCMDS) || defined(PROTO)
+/*
+ * Go to another buffer.  Handles the result of the ATTENTION dialog.
+ */
+    void
+goto_buffer(eap, start, dir, count)
+    exarg_T	*eap;
+    int		start;
+    int		dir;
+    int		count;
+{
+# if defined(FEAT_WINDOWS) && defined(HAS_SWAP_EXISTS_ACTION)
+    buf_T	*old_curbuf = curbuf;
+
+    swap_exists_action = SEA_DIALOG;
+# endif
+    (void)do_buffer(*eap->cmd == 's' ? DOBUF_SPLIT : DOBUF_GOTO,
+					     start, dir, count, eap->forceit);
+# if defined(FEAT_WINDOWS) && defined(HAS_SWAP_EXISTS_ACTION)
+    if (swap_exists_action == SEA_QUIT && *eap->cmd == 's')
+    {
+#  if defined(FEAT_AUTOCMD) && defined(FEAT_EVAL)
+	cleanup_T   cs;
+
+	/* Reset the error/interrupt/exception state here so that
+	 * aborting() returns FALSE when closing a window. */
+	enter_cleanup(&cs);
+#  endif
+
+	/* Quitting means closing the split window, nothing else. */
+	win_close(curwin, TRUE);
+	swap_exists_action = SEA_NONE;
+	swap_exists_did_quit = TRUE;
+
+#  if defined(FEAT_AUTOCMD) && defined(FEAT_EVAL)
+	/* Restore the error/interrupt/exception state if not discarded by a
+	 * new aborting error, interrupt, or uncaught exception. */
+	leave_cleanup(&cs);
+#  endif
+    }
+    else
+	handle_swap_exists(old_curbuf);
+# endif
+}
+#endif
+
+#if defined(HAS_SWAP_EXISTS_ACTION) || defined(PROTO)
+/*
+ * Handle the situation of swap_exists_action being set.
+ * It is allowed for "old_curbuf" to be NULL or invalid.
+ */
+    void
+handle_swap_exists(old_curbuf)
+    buf_T	*old_curbuf;
+{
+# if defined(FEAT_AUTOCMD) && defined(FEAT_EVAL)
+    cleanup_T	cs;
+# endif
+
+    if (swap_exists_action == SEA_QUIT)
+    {
+# if defined(FEAT_AUTOCMD) && defined(FEAT_EVAL)
+	/* Reset the error/interrupt/exception state here so that
+	 * aborting() returns FALSE when closing a buffer. */
+	enter_cleanup(&cs);
+# endif
+
+	/* User selected Quit at ATTENTION prompt.  Go back to previous
+	 * buffer.  If that buffer is gone or the same as the current one,
+	 * open a new, empty buffer. */
+	swap_exists_action = SEA_NONE;	/* don't want it again */
+	swap_exists_did_quit = TRUE;
+	close_buffer(curwin, curbuf, DOBUF_UNLOAD);
+	if (!buf_valid(old_curbuf) || old_curbuf == curbuf)
+	    old_curbuf = buflist_new(NULL, NULL, 1L, BLN_CURBUF | BLN_LISTED);
+	if (old_curbuf != NULL)
+	    enter_buffer(old_curbuf);
+	/* If "old_curbuf" is NULL we are in big trouble here... */
+
+# if defined(FEAT_AUTOCMD) && defined(FEAT_EVAL)
+	/* Restore the error/interrupt/exception state if not discarded by a
+	 * new aborting error, interrupt, or uncaught exception. */
+	leave_cleanup(&cs);
+# endif
+    }
+    else if (swap_exists_action == SEA_RECOVER)
+    {
+# if defined(FEAT_AUTOCMD) && defined(FEAT_EVAL)
+	/* Reset the error/interrupt/exception state here so that
+	 * aborting() returns FALSE when closing a buffer. */
+	enter_cleanup(&cs);
+# endif
+
+	/* User selected Recover at ATTENTION prompt. */
+	msg_scroll = TRUE;
+	ml_recover();
+	MSG_PUTS("\n");	/* don't overwrite the last message */
+	cmdline_row = msg_row;
+	do_modelines(0);
+
+# if defined(FEAT_AUTOCMD) && defined(FEAT_EVAL)
+	/* Restore the error/interrupt/exception state if not discarded by a
+	 * new aborting error, interrupt, or uncaught exception. */
+	leave_cleanup(&cs);
+# endif
+    }
+    swap_exists_action = SEA_NONE;
+}
+#endif
+
+#if defined(FEAT_LISTCMDS) || defined(PROTO)
+/*
+ * do_bufdel() - delete or unload buffer(s)
+ *
+ * addr_count == 0: ":bdel" - delete current buffer
+ * addr_count == 1: ":N bdel" or ":bdel N [N ..]" - first delete
+ *		    buffer "end_bnr", then any other arguments.
+ * addr_count == 2: ":N,N bdel" - delete buffers in range
+ *
+ * command can be DOBUF_UNLOAD (":bunload"), DOBUF_WIPE (":bwipeout") or
+ * DOBUF_DEL (":bdel")
+ *
+ * Returns error message or NULL
+ */
+    char_u *
+do_bufdel(command, arg, addr_count, start_bnr, end_bnr, forceit)
+    int		command;
+    char_u	*arg;		/* pointer to extra arguments */
+    int		addr_count;
+    int		start_bnr;	/* first buffer number in a range */
+    int		end_bnr;	/* buffer nr or last buffer nr in a range */
+    int		forceit;
+{
+    int		do_current = 0;	/* delete current buffer? */
+    int		deleted = 0;	/* number of buffers deleted */
+    char_u	*errormsg = NULL; /* return value */
+    int		bnr;		/* buffer number */
+    char_u	*p;
+
+#ifdef FEAT_NETBEANS_INTG
+    netbeansCloseFile = 1;
+#endif
+    if (addr_count == 0)
+    {
+	(void)do_buffer(command, DOBUF_CURRENT, FORWARD, 0, forceit);
+    }
+    else
+    {
+	if (addr_count == 2)
+	{
+	    if (*arg)		/* both range and argument is not allowed */
+		return (char_u *)_(e_trailing);
+	    bnr = start_bnr;
+	}
+	else	/* addr_count == 1 */
+	    bnr = end_bnr;
+
+	for ( ;!got_int; ui_breakcheck())
+	{
+	    /*
+	     * delete the current buffer last, otherwise when the
+	     * current buffer is deleted, the next buffer becomes
+	     * the current one and will be loaded, which may then
+	     * also be deleted, etc.
+	     */
+	    if (bnr == curbuf->b_fnum)
+		do_current = bnr;
+	    else if (do_buffer(command, DOBUF_FIRST, FORWARD, (int)bnr,
+							       forceit) == OK)
+		++deleted;
+
+	    /*
+	     * find next buffer number to delete/unload
+	     */
+	    if (addr_count == 2)
+	    {
+		if (++bnr > end_bnr)
+		    break;
+	    }
+	    else    /* addr_count == 1 */
+	    {
+		arg = skipwhite(arg);
+		if (*arg == NUL)
+		    break;
+		if (!VIM_ISDIGIT(*arg))
+		{
+		    p = skiptowhite_esc(arg);
+		    bnr = buflist_findpat(arg, p, command == DOBUF_WIPE, FALSE);
+		    if (bnr < 0)	    /* failed */
+			break;
+		    arg = p;
+		}
+		else
+		    bnr = getdigits(&arg);
+	    }
+	}
+	if (!got_int && do_current && do_buffer(command, DOBUF_FIRST,
+					  FORWARD, do_current, forceit) == OK)
+	    ++deleted;
+
+	if (deleted == 0)
+	{
+	    if (command == DOBUF_UNLOAD)
+		STRCPY(IObuff, _("E515: No buffers were unloaded"));
+	    else if (command == DOBUF_DEL)
+		STRCPY(IObuff, _("E516: No buffers were deleted"));
+	    else
+		STRCPY(IObuff, _("E517: No buffers were wiped out"));
+	    errormsg = IObuff;
+	}
+	else if (deleted >= p_report)
+	{
+	    if (command == DOBUF_UNLOAD)
+	    {
+		if (deleted == 1)
+		    MSG(_("1 buffer unloaded"));
+		else
+		    smsg((char_u *)_("%d buffers unloaded"), deleted);
+	    }
+	    else if (command == DOBUF_DEL)
+	    {
+		if (deleted == 1)
+		    MSG(_("1 buffer deleted"));
+		else
+		    smsg((char_u *)_("%d buffers deleted"), deleted);
+	    }
+	    else
+	    {
+		if (deleted == 1)
+		    MSG(_("1 buffer wiped out"));
+		else
+		    smsg((char_u *)_("%d buffers wiped out"), deleted);
+	    }
+	}
+    }
+
+#ifdef FEAT_NETBEANS_INTG
+    netbeansCloseFile = 0;
+#endif
+
+    return errormsg;
+}
+
+/*
+ * Implementation of the commands for the buffer list.
+ *
+ * action == DOBUF_GOTO	    go to specified buffer
+ * action == DOBUF_SPLIT    split window and go to specified buffer
+ * action == DOBUF_UNLOAD   unload specified buffer(s)
+ * action == DOBUF_DEL	    delete specified buffer(s) from buffer list
+ * action == DOBUF_WIPE	    delete specified buffer(s) really
+ *
+ * start == DOBUF_CURRENT   go to "count" buffer from current buffer
+ * start == DOBUF_FIRST	    go to "count" buffer from first buffer
+ * start == DOBUF_LAST	    go to "count" buffer from last buffer
+ * start == DOBUF_MOD	    go to "count" modified buffer from current buffer
+ *
+ * Return FAIL or OK.
+ */
+    int
+do_buffer(action, start, dir, count, forceit)
+    int		action;
+    int		start;
+    int		dir;		/* FORWARD or BACKWARD */
+    int		count;		/* buffer number or number of buffers */
+    int		forceit;	/* TRUE for :...! */
+{
+    buf_T	*buf;
+    buf_T	*bp;
+    int		unload = (action == DOBUF_UNLOAD || action == DOBUF_DEL
+						     || action == DOBUF_WIPE);
+
+    switch (start)
+    {
+	case DOBUF_FIRST:   buf = firstbuf; break;
+	case DOBUF_LAST:    buf = lastbuf;  break;
+	default:	    buf = curbuf;   break;
+    }
+    if (start == DOBUF_MOD)	    /* find next modified buffer */
+    {
+	while (count-- > 0)
+	{
+	    do
+	    {
+		buf = buf->b_next;
+		if (buf == NULL)
+		    buf = firstbuf;
+	    }
+	    while (buf != curbuf && !bufIsChanged(buf));
+	}
+	if (!bufIsChanged(buf))
+	{
+	    EMSG(_("E84: No modified buffer found"));
+	    return FAIL;
+	}
+    }
+    else if (start == DOBUF_FIRST && count) /* find specified buffer number */
+    {
+	while (buf != NULL && buf->b_fnum != count)
+	    buf = buf->b_next;
+    }
+    else
+    {
+	bp = NULL;
+	while (count > 0 || (!unload && !buf->b_p_bl && bp != buf))
+	{
+	    /* remember the buffer where we start, we come back there when all
+	     * buffers are unlisted. */
+	    if (bp == NULL)
+		bp = buf;
+	    if (dir == FORWARD)
+	    {
+		buf = buf->b_next;
+		if (buf == NULL)
+		    buf = firstbuf;
+	    }
+	    else
+	    {
+		buf = buf->b_prev;
+		if (buf == NULL)
+		    buf = lastbuf;
+	    }
+	    /* don't count unlisted buffers */
+	    if (unload || buf->b_p_bl)
+	    {
+		 --count;
+		 bp = NULL;	/* use this buffer as new starting point */
+	    }
+	    if (bp == buf)
+	    {
+		/* back where we started, didn't find anything. */
+		EMSG(_("E85: There is no listed buffer"));
+		return FAIL;
+	    }
+	}
+    }
+
+    if (buf == NULL)	    /* could not find it */
+    {
+	if (start == DOBUF_FIRST)
+	{
+	    /* don't warn when deleting */
+	    if (!unload)
+		EMSGN(_("E86: Buffer %ld does not exist"), count);
+	}
+	else if (dir == FORWARD)
+	    EMSG(_("E87: Cannot go beyond last buffer"));
+	else
+	    EMSG(_("E88: Cannot go before first buffer"));
+	return FAIL;
+    }
+
+#ifdef FEAT_GUI
+    need_mouse_correct = TRUE;
+#endif
+
+#ifdef FEAT_LISTCMDS
+    /*
+     * delete buffer buf from memory and/or the list
+     */
+    if (unload)
+    {
+	int	forward;
+	int	retval;
+
+	/* When unloading or deleting a buffer that's already unloaded and
+	 * unlisted: fail silently. */
+	if (action != DOBUF_WIPE && buf->b_ml.ml_mfp == NULL && !buf->b_p_bl)
+	    return FAIL;
+
+	if (!forceit && bufIsChanged(buf))
+	{
+#if defined(FEAT_GUI_DIALOG) || defined(FEAT_CON_DIALOG)
+	    if ((p_confirm || cmdmod.confirm) && p_write)
+	    {
+		dialog_changed(buf, FALSE);
+# ifdef FEAT_AUTOCMD
+		if (!buf_valid(buf))
+		    /* Autocommand deleted buffer, oops!  It's not changed
+		     * now. */
+		    return FAIL;
+# endif
+		/* If it's still changed fail silently, the dialog already
+		 * mentioned why it fails. */
+		if (bufIsChanged(buf))
+		    return FAIL;
+	    }
+	    else
+#endif
+	    {
+		EMSGN(_("E89: No write since last change for buffer %ld (add ! to override)"),
+								 buf->b_fnum);
+		return FAIL;
+	    }
+	}
+
+	/*
+	 * If deleting the last (listed) buffer, make it empty.
+	 * The last (listed) buffer cannot be unloaded.
+	 */
+	for (bp = firstbuf; bp != NULL; bp = bp->b_next)
+	    if (bp->b_p_bl && bp != buf)
+		break;
+	if (bp == NULL && buf == curbuf)
+	{
+	    if (action == DOBUF_UNLOAD)
+	    {
+		EMSG(_("E90: Cannot unload last buffer"));
+		return FAIL;
+	    }
+
+	    /* Close any other windows on this buffer, then make it empty. */
+#ifdef FEAT_WINDOWS
+	    close_windows(buf, TRUE);
+#endif
+	    setpcmark();
+	    retval = do_ecmd(0, NULL, NULL, NULL, ECMD_ONE,
+						  forceit ? ECMD_FORCEIT : 0);
+
+	    /*
+	     * do_ecmd() may create a new buffer, then we have to delete
+	     * the old one.  But do_ecmd() may have done that already, check
+	     * if the buffer still exists.
+	     */
+	    if (buf != curbuf && buf_valid(buf) && buf->b_nwindows == 0)
+		close_buffer(NULL, buf, action);
+	    return retval;
+	}
+
+#ifdef FEAT_WINDOWS
+	/*
+	 * If the deleted buffer is the current one, close the current window
+	 * (unless it's the only window).  Repeat this so long as we end up in
+	 * a window with this buffer.
+	 */
+	while (buf == curbuf
+		   && (firstwin != lastwin || first_tabpage->tp_next != NULL))
+	    win_close(curwin, FALSE);
+#endif
+
+	/*
+	 * If the buffer to be deleted is not the current one, delete it here.
+	 */
+	if (buf != curbuf)
+	{
+#ifdef FEAT_WINDOWS
+	    close_windows(buf, FALSE);
+#endif
+	    if (buf != curbuf && buf_valid(buf) && buf->b_nwindows <= 0)
+		close_buffer(NULL, buf, action);
+	    return OK;
+	}
+
+	/*
+	 * Deleting the current buffer: Need to find another buffer to go to.
+	 * There must be another, otherwise it would have been handled above.
+	 * First use au_new_curbuf, if it is valid.
+	 * Then prefer the buffer we most recently visited.
+	 * Else try to find one that is loaded, after the current buffer,
+	 * then before the current buffer.
+	 * Finally use any buffer.
+	 */
+	buf = NULL;	/* selected buffer */
+	bp = NULL;	/* used when no loaded buffer found */
+#ifdef FEAT_AUTOCMD
+	if (au_new_curbuf != NULL && buf_valid(au_new_curbuf))
+	    buf = au_new_curbuf;
+# ifdef FEAT_JUMPLIST
+	else
+# endif
+#endif
+#ifdef FEAT_JUMPLIST
+	    if (curwin->w_jumplistlen > 0)
+	{
+	    int     jumpidx;
+
+	    jumpidx = curwin->w_jumplistidx - 1;
+	    if (jumpidx < 0)
+		jumpidx = curwin->w_jumplistlen - 1;
+
+	    forward = jumpidx;
+	    while (jumpidx != curwin->w_jumplistidx)
+	    {
+		buf = buflist_findnr(curwin->w_jumplist[jumpidx].fmark.fnum);
+		if (buf != NULL)
+		{
+		    if (buf == curbuf || !buf->b_p_bl)
+			buf = NULL;	/* skip current and unlisted bufs */
+		    else if (buf->b_ml.ml_mfp == NULL)
+		    {
+			/* skip unloaded buf, but may keep it for later */
+			if (bp == NULL)
+			    bp = buf;
+			buf = NULL;
+		    }
+		}
+		if (buf != NULL)   /* found a valid buffer: stop searching */
+		    break;
+		/* advance to older entry in jump list */
+		if (!jumpidx && curwin->w_jumplistidx == curwin->w_jumplistlen)
+		    break;
+		if (--jumpidx < 0)
+		    jumpidx = curwin->w_jumplistlen - 1;
+		if (jumpidx == forward)		/* List exhausted for sure */
+		    break;
+	    }
+	}
+#endif
+
+	if (buf == NULL)	/* No previous buffer, Try 2'nd approach */
+	{
+	    forward = TRUE;
+	    buf = curbuf->b_next;
+	    for (;;)
+	    {
+		if (buf == NULL)
+		{
+		    if (!forward)	/* tried both directions */
+			break;
+		    buf = curbuf->b_prev;
+		    forward = FALSE;
+		    continue;
+		}
+		/* in non-help buffer, try to skip help buffers, and vv */
+		if (buf->b_help == curbuf->b_help && buf->b_p_bl)
+		{
+		    if (buf->b_ml.ml_mfp != NULL)   /* found loaded buffer */
+			break;
+		    if (bp == NULL)	/* remember unloaded buf for later */
+			bp = buf;
+		}
+		if (forward)
+		    buf = buf->b_next;
+		else
+		    buf = buf->b_prev;
+	    }
+	}
+	if (buf == NULL)	/* No loaded buffer, use unloaded one */
+	    buf = bp;
+	if (buf == NULL)	/* No loaded buffer, find listed one */
+	{
+	    for (buf = firstbuf; buf != NULL; buf = buf->b_next)
+		if (buf->b_p_bl && buf != curbuf)
+		    break;
+	}
+	if (buf == NULL)	/* Still no buffer, just take one */
+	{
+	    if (curbuf->b_next != NULL)
+		buf = curbuf->b_next;
+	    else
+		buf = curbuf->b_prev;
+	}
+    }
+
+    /*
+     * make buf current buffer
+     */
+    if (action == DOBUF_SPLIT)	    /* split window first */
+    {
+# ifdef FEAT_WINDOWS
+	/* jump to first window containing buf if one exists ("useopen") */
+	if (vim_strchr(p_swb, 'o') != NULL && buf_jump_open_win(buf))
+	    return OK;
+	/* jump to first window in any tab page containing buf if one exists
+	 * ("usetab") */
+	if (vim_strchr(p_swb, 'a') != NULL && buf_jump_open_tab(buf))
+	    return OK;
+	if (win_split(0, 0) == FAIL)
+# endif
+	    return FAIL;
+    }
+#endif
+
+    /* go to current buffer - nothing to do */
+    if (buf == curbuf)
+	return OK;
+
+    /*
+     * Check if the current buffer may be abandoned.
+     */
+    if (action == DOBUF_GOTO && !can_abandon(curbuf, forceit))
+    {
+#if defined(FEAT_GUI_DIALOG) || defined(FEAT_CON_DIALOG)
+	if ((p_confirm || cmdmod.confirm) && p_write)
+	{
+	    dialog_changed(curbuf, FALSE);
+# ifdef FEAT_AUTOCMD
+	    if (!buf_valid(buf))
+		/* Autocommand deleted buffer, oops! */
+		return FAIL;
+# endif
+	}
+	if (bufIsChanged(curbuf))
+#endif
+	{
+	    EMSG(_(e_nowrtmsg));
+	    return FAIL;
+	}
+    }
+
+    /* Go to the other buffer. */
+    set_curbuf(buf, action);
+
+#if defined(FEAT_LISTCMDS) && defined(FEAT_SCROLLBIND)
+    if (action == DOBUF_SPLIT)
+	curwin->w_p_scb = FALSE;	/* reset 'scrollbind' */
+#endif
+
+#if defined(FEAT_AUTOCMD) && defined(FEAT_EVAL)
+    if (aborting())	    /* autocmds may abort script processing */
+	return FAIL;
+#endif
+
+    return OK;
+}
+
+#endif /* FEAT_LISTCMDS */
+
+/*
+ * Set current buffer to "buf".  Executes autocommands and closes current
+ * buffer.  "action" tells how to close the current buffer:
+ * DOBUF_GOTO	    free or hide it
+ * DOBUF_SPLIT	    nothing
+ * DOBUF_UNLOAD	    unload it
+ * DOBUF_DEL	    delete it
+ * DOBUF_WIPE	    wipe it out
+ */
+    void
+set_curbuf(buf, action)
+    buf_T	*buf;
+    int		action;
+{
+    buf_T	*prevbuf;
+    int		unload = (action == DOBUF_UNLOAD || action == DOBUF_DEL
+						     || action == DOBUF_WIPE);
+
+    setpcmark();
+    if (!cmdmod.keepalt)
+	curwin->w_alt_fnum = curbuf->b_fnum; /* remember alternate file */
+    buflist_altfpos();			 /* remember curpos */
+
+#ifdef FEAT_VISUAL
+    /* Don't restart Select mode after switching to another buffer. */
+    VIsual_reselect = FALSE;
+#endif
+
+    /* close_windows() or apply_autocmds() may change curbuf */
+    prevbuf = curbuf;
+
+#ifdef FEAT_AUTOCMD
+    apply_autocmds(EVENT_BUFLEAVE, NULL, NULL, FALSE, curbuf);
+# ifdef FEAT_EVAL
+    if (buf_valid(prevbuf) && !aborting())
+# else
+    if (buf_valid(prevbuf))
+# endif
+#endif
+    {
+#ifdef FEAT_WINDOWS
+	if (unload)
+	    close_windows(prevbuf, FALSE);
+#endif
+#if defined(FEAT_AUTOCMD) && defined(FEAT_EVAL)
+	if (buf_valid(prevbuf) && !aborting())
+#else
+	if (buf_valid(prevbuf))
+#endif
+	{
+	    if (prevbuf == curbuf)
+		u_sync(FALSE);
+	    close_buffer(prevbuf == curwin->w_buffer ? curwin : NULL, prevbuf,
+		    unload ? action : (action == DOBUF_GOTO
+			&& !P_HID(prevbuf)
+			&& !bufIsChanged(prevbuf)) ? DOBUF_UNLOAD : 0);
+	}
+    }
+#ifdef FEAT_AUTOCMD
+# ifdef FEAT_EVAL
+    /* An autocommand may have deleted buf or aborted the script processing! */
+    if (buf_valid(buf) && !aborting())
+# else
+    if (buf_valid(buf))	    /* an autocommand may have deleted buf! */
+# endif
+#endif
+	enter_buffer(buf);
+}
+
+/*
+ * Enter a new current buffer.
+ * Old curbuf must have been abandoned already!
+ */
+    void
+enter_buffer(buf)
+    buf_T	*buf;
+{
+    /* Copy buffer and window local option values.  Not for a help buffer. */
+    buf_copy_options(buf, BCO_ENTER | BCO_NOHELP);
+    if (!buf->b_help)
+	get_winopts(buf);
+#ifdef FEAT_FOLDING
+    else
+	/* Remove all folds in the window. */
+	clearFolding(curwin);
+    foldUpdateAll(curwin);	/* update folds (later). */
+#endif
+
+    /* Get the buffer in the current window. */
+    curwin->w_buffer = buf;
+    curbuf = buf;
+    ++curbuf->b_nwindows;
+
+#ifdef FEAT_DIFF
+    if (curwin->w_p_diff)
+	diff_buf_add(curbuf);
+#endif
+
+    /* Cursor on first line by default. */
+    curwin->w_cursor.lnum = 1;
+    curwin->w_cursor.col = 0;
+#ifdef FEAT_VIRTUALEDIT
+    curwin->w_cursor.coladd = 0;
+#endif
+    curwin->w_set_curswant = TRUE;
+
+    /* Make sure the buffer is loaded. */
+    if (curbuf->b_ml.ml_mfp == NULL)	/* need to load the file */
+    {
+#ifdef FEAT_AUTOCMD
+	/* If there is no filetype, allow for detecting one.  Esp. useful for
+	 * ":ball" used in a autocommand.  If there already is a filetype we
+	 * might prefer to keep it. */
+	if (*curbuf->b_p_ft == NUL)
+	    did_filetype = FALSE;
+#endif
+
+	open_buffer(FALSE, NULL);
+    }
+    else
+    {
+	if (!msg_silent)
+	    need_fileinfo = TRUE;	/* display file info after redraw */
+	(void)buf_check_timestamp(curbuf, FALSE); /* check if file changed */
+#ifdef FEAT_AUTOCMD
+	curwin->w_topline = 1;
+# ifdef FEAT_DIFF
+	curwin->w_topfill = 0;
+# endif
+	apply_autocmds(EVENT_BUFENTER, NULL, NULL, FALSE, curbuf);
+	apply_autocmds(EVENT_BUFWINENTER, NULL, NULL, FALSE, curbuf);
+#endif
+    }
+
+    /* If autocommands did not change the cursor position, restore cursor lnum
+     * and possibly cursor col. */
+    if (curwin->w_cursor.lnum == 1 && inindent(0))
+	buflist_getfpos();
+
+    check_arg_idx(curwin);		/* check for valid arg_idx */
+#ifdef FEAT_TITLE
+    maketitle();
+#endif
+#ifdef FEAT_AUTOCMD
+    if (curwin->w_topline == 1)		/* when autocmds didn't change it */
+#endif
+	scroll_cursor_halfway(FALSE);	/* redisplay at correct position */
+
+#ifdef FEAT_NETBEANS_INTG
+    /* Send fileOpened event because we've changed buffers. */
+    if (usingNetbeans && isNetbeansBuffer(curbuf))
+	netbeans_file_activated(curbuf);
+#endif
+
+    /* Change directories when the 'acd' option is set. */
+    DO_AUTOCHDIR
+
+#ifdef FEAT_KEYMAP
+    if (curbuf->b_kmap_state & KEYMAP_INIT)
+	keymap_init();
+#endif
+#ifdef FEAT_SPELL
+    /* May need to set the spell language.  Can only do this after the buffer
+     * has been properly setup. */
+    if (!curbuf->b_help && curwin->w_p_spell && *curbuf->b_p_spl != NUL)
+	did_set_spelllang(curbuf);
+#endif
+
+    redraw_later(NOT_VALID);
+}
+
+#if defined(FEAT_AUTOCHDIR) || defined(PROTO)
+/*
+ * Change to the directory of the current buffer.
+ */
+    void
+do_autochdir()
+{
+    if (curbuf->b_ffname != NULL && vim_chdirfile(curbuf->b_ffname) == OK)
+	shorten_fnames(TRUE);
+}
+#endif
+
+/*
+ * functions for dealing with the buffer list
+ */
+
+/*
+ * Add a file name to the buffer list.  Return a pointer to the buffer.
+ * If the same file name already exists return a pointer to that buffer.
+ * If it does not exist, or if fname == NULL, a new entry is created.
+ * If (flags & BLN_CURBUF) is TRUE, may use current buffer.
+ * If (flags & BLN_LISTED) is TRUE, add new buffer to buffer list.
+ * If (flags & BLN_DUMMY) is TRUE, don't count it as a real buffer.
+ * This is the ONLY way to create a new buffer.
+ */
+static int  top_file_num = 1;		/* highest file number */
+
+    buf_T *
+buflist_new(ffname, sfname, lnum, flags)
+    char_u	*ffname;	/* full path of fname or relative */
+    char_u	*sfname;	/* short fname or NULL */
+    linenr_T	lnum;		/* preferred cursor line */
+    int		flags;		/* BLN_ defines */
+{
+    buf_T	*buf;
+#ifdef UNIX
+    struct stat	st;
+#endif
+
+    fname_expand(curbuf, &ffname, &sfname);	/* will allocate ffname */
+
+    /*
+     * If file name already exists in the list, update the entry.
+     */
+#ifdef UNIX
+    /* On Unix we can use inode numbers when the file exists.  Works better
+     * for hard links. */
+    if (sfname == NULL || mch_stat((char *)sfname, &st) < 0)
+	st.st_dev = (dev_T)-1;
+#endif
+    if (ffname != NULL && !(flags & BLN_DUMMY) && (buf =
+#ifdef UNIX
+		buflist_findname_stat(ffname, &st)
+#else
+		buflist_findname(ffname)
+#endif
+		) != NULL)
+    {
+	vim_free(ffname);
+	if (lnum != 0)
+	    buflist_setfpos(buf, curwin, lnum, (colnr_T)0, FALSE);
+	/* copy the options now, if 'cpo' doesn't have 's' and not done
+	 * already */
+	buf_copy_options(buf, 0);
+	if ((flags & BLN_LISTED) && !buf->b_p_bl)
+	{
+	    buf->b_p_bl = TRUE;
+#ifdef FEAT_AUTOCMD
+	    if (!(flags & BLN_DUMMY))
+		apply_autocmds(EVENT_BUFADD, NULL, NULL, FALSE, buf);
+#endif
+	}
+	return buf;
+    }
+
+    /*
+     * If the current buffer has no name and no contents, use the current
+     * buffer.	Otherwise: Need to allocate a new buffer structure.
+     *
+     * This is the ONLY place where a new buffer structure is allocated!
+     * (A spell file buffer is allocated in spell.c, but that's not a normal
+     * buffer.)
+     */
+    buf = NULL;
+    if ((flags & BLN_CURBUF)
+	    && curbuf != NULL
+	    && curbuf->b_ffname == NULL
+	    && curbuf->b_nwindows <= 1
+	    && (curbuf->b_ml.ml_mfp == NULL || bufempty()))
+    {
+	buf = curbuf;
+#ifdef FEAT_AUTOCMD
+	/* It's like this buffer is deleted.  Watch out for autocommands that
+	 * change curbuf!  If that happens, allocate a new buffer anyway. */
+	if (curbuf->b_p_bl)
+	    apply_autocmds(EVENT_BUFDELETE, NULL, NULL, FALSE, curbuf);
+	if (buf == curbuf)
+	    apply_autocmds(EVENT_BUFWIPEOUT, NULL, NULL, FALSE, curbuf);
+# ifdef FEAT_EVAL
+	if (aborting())		/* autocmds may abort script processing */
+	    return NULL;
+# endif
+#endif
+#ifdef FEAT_QUICKFIX
+# ifdef FEAT_AUTOCMD
+	if (buf == curbuf)
+# endif
+	{
+	    /* Make sure 'bufhidden' and 'buftype' are empty */
+	    clear_string_option(&buf->b_p_bh);
+	    clear_string_option(&buf->b_p_bt);
+	}
+#endif
+    }
+    if (buf != curbuf || curbuf == NULL)
+    {
+	buf = (buf_T *)alloc_clear((unsigned)sizeof(buf_T));
+	if (buf == NULL)
+	{
+	    vim_free(ffname);
+	    return NULL;
+	}
+    }
+
+    if (ffname != NULL)
+    {
+	buf->b_ffname = ffname;
+	buf->b_sfname = vim_strsave(sfname);
+    }
+
+    clear_wininfo(buf);
+    buf->b_wininfo = (wininfo_T *)alloc_clear((unsigned)sizeof(wininfo_T));
+
+    if ((ffname != NULL && (buf->b_ffname == NULL || buf->b_sfname == NULL))
+	    || buf->b_wininfo == NULL)
+    {
+	vim_free(buf->b_ffname);
+	buf->b_ffname = NULL;
+	vim_free(buf->b_sfname);
+	buf->b_sfname = NULL;
+	if (buf != curbuf)
+	    free_buffer(buf);
+	return NULL;
+    }
+
+    if (buf == curbuf)
+    {
+	/* free all things allocated for this buffer */
+	buf_freeall(buf, FALSE, FALSE);
+	if (buf != curbuf)	 /* autocommands deleted the buffer! */
+	    return NULL;
+#if defined(FEAT_AUTOCMD) && defined(FEAT_EVAL)
+	if (aborting())		/* autocmds may abort script processing */
+	    return NULL;
+#endif
+	/* buf->b_nwindows = 0; why was this here? */
+	free_buffer_stuff(buf, FALSE);	/* delete local variables et al. */
+#ifdef FEAT_KEYMAP
+	/* need to reload lmaps and set b:keymap_name */
+	curbuf->b_kmap_state |= KEYMAP_INIT;
+#endif
+    }
+    else
+    {
+	/*
+	 * put new buffer at the end of the buffer list
+	 */
+	buf->b_next = NULL;
+	if (firstbuf == NULL)		/* buffer list is empty */
+	{
+	    buf->b_prev = NULL;
+	    firstbuf = buf;
+	}
+	else				/* append new buffer at end of list */
+	{
+	    lastbuf->b_next = buf;
+	    buf->b_prev = lastbuf;
+	}
+	lastbuf = buf;
+
+	buf->b_fnum = top_file_num++;
+	if (top_file_num < 0)		/* wrap around (may cause duplicates) */
+	{
+	    EMSG(_("W14: Warning: List of file names overflow"));
+	    if (emsg_silent == 0)
+	    {
+		out_flush();
+		ui_delay(3000L, TRUE);	/* make sure it is noticed */
+	    }
+	    top_file_num = 1;
+	}
+
+	/*
+	 * Always copy the options from the current buffer.
+	 */
+	buf_copy_options(buf, BCO_ALWAYS);
+    }
+
+    buf->b_wininfo->wi_fpos.lnum = lnum;
+    buf->b_wininfo->wi_win = curwin;
+
+#ifdef FEAT_EVAL
+    init_var_dict(&buf->b_vars, &buf->b_bufvar);    /* init b: variables */
+#endif
+#ifdef FEAT_SYN_HL
+    hash_init(&buf->b_keywtab);
+    hash_init(&buf->b_keywtab_ic);
+#endif
+
+    buf->b_fname = buf->b_sfname;
+#ifdef UNIX
+    if (st.st_dev == (dev_T)-1)
+	buf->b_dev = -1;
+    else
+    {
+	buf->b_dev = st.st_dev;
+	buf->b_ino = st.st_ino;
+    }
+#endif
+    buf->b_u_synced = TRUE;
+    buf->b_flags = BF_CHECK_RO | BF_NEVERLOADED;
+    if (flags & BLN_DUMMY)
+	buf->b_flags |= BF_DUMMY;
+    buf_clear_file(buf);
+    clrallmarks(buf);			/* clear marks */
+    fmarks_check_names(buf);		/* check file marks for this file */
+    buf->b_p_bl = (flags & BLN_LISTED) ? TRUE : FALSE;	/* init 'buflisted' */
+#ifdef FEAT_AUTOCMD
+    if (!(flags & BLN_DUMMY))
+    {
+	apply_autocmds(EVENT_BUFNEW, NULL, NULL, FALSE, buf);
+	if (flags & BLN_LISTED)
+	    apply_autocmds(EVENT_BUFADD, NULL, NULL, FALSE, buf);
+# ifdef FEAT_EVAL
+	if (aborting())		/* autocmds may abort script processing */
+	    return NULL;
+# endif
+    }
+#endif
+
+    return buf;
+}
+
+/*
+ * Free the memory for the options of a buffer.
+ * If "free_p_ff" is TRUE also free 'fileformat', 'buftype' and
+ * 'fileencoding'.
+ */
+    void
+free_buf_options(buf, free_p_ff)
+    buf_T	*buf;
+    int		free_p_ff;
+{
+    if (free_p_ff)
+    {
+#ifdef FEAT_MBYTE
+	clear_string_option(&buf->b_p_fenc);
+#endif
+	clear_string_option(&buf->b_p_ff);
+#ifdef FEAT_QUICKFIX
+	clear_string_option(&buf->b_p_bh);
+	clear_string_option(&buf->b_p_bt);
+#endif
+    }
+#ifdef FEAT_FIND_ID
+    clear_string_option(&buf->b_p_def);
+    clear_string_option(&buf->b_p_inc);
+# ifdef FEAT_EVAL
+    clear_string_option(&buf->b_p_inex);
+# endif
+#endif
+#if defined(FEAT_CINDENT) && defined(FEAT_EVAL)
+    clear_string_option(&buf->b_p_inde);
+    clear_string_option(&buf->b_p_indk);
+#endif
+#if defined(FEAT_BEVAL) && defined(FEAT_EVAL)
+    clear_string_option(&buf->b_p_bexpr);
+#endif
+#if defined(FEAT_EVAL)
+    clear_string_option(&buf->b_p_fex);
+#endif
+#ifdef FEAT_CRYPT
+    clear_string_option(&buf->b_p_key);
+#endif
+    clear_string_option(&buf->b_p_kp);
+    clear_string_option(&buf->b_p_mps);
+    clear_string_option(&buf->b_p_fo);
+    clear_string_option(&buf->b_p_flp);
+    clear_string_option(&buf->b_p_isk);
+#ifdef FEAT_KEYMAP
+    clear_string_option(&buf->b_p_keymap);
+    ga_clear(&buf->b_kmap_ga);
+#endif
+#ifdef FEAT_COMMENTS
+    clear_string_option(&buf->b_p_com);
+#endif
+#ifdef FEAT_FOLDING
+    clear_string_option(&buf->b_p_cms);
+#endif
+    clear_string_option(&buf->b_p_nf);
+#ifdef FEAT_SYN_HL
+    clear_string_option(&buf->b_p_syn);
+#endif
+#ifdef FEAT_SPELL
+    clear_string_option(&buf->b_p_spc);
+    clear_string_option(&buf->b_p_spf);
+    vim_free(buf->b_cap_prog);
+    buf->b_cap_prog = NULL;
+    clear_string_option(&buf->b_p_spl);
+#endif
+#ifdef FEAT_SEARCHPATH
+    clear_string_option(&buf->b_p_sua);
+#endif
+#ifdef FEAT_AUTOCMD
+    clear_string_option(&buf->b_p_ft);
+#endif
+#ifdef FEAT_OSFILETYPE
+    clear_string_option(&buf->b_p_oft);
+#endif
+#ifdef FEAT_CINDENT
+    clear_string_option(&buf->b_p_cink);
+    clear_string_option(&buf->b_p_cino);
+#endif
+#if defined(FEAT_CINDENT) || defined(FEAT_SMARTINDENT)
+    clear_string_option(&buf->b_p_cinw);
+#endif
+#ifdef FEAT_INS_EXPAND
+    clear_string_option(&buf->b_p_cpt);
+#endif
+#ifdef FEAT_COMPL_FUNC
+    clear_string_option(&buf->b_p_cfu);
+    clear_string_option(&buf->b_p_ofu);
+#endif
+#ifdef FEAT_QUICKFIX
+    clear_string_option(&buf->b_p_gp);
+    clear_string_option(&buf->b_p_mp);
+    clear_string_option(&buf->b_p_efm);
+#endif
+    clear_string_option(&buf->b_p_ep);
+    clear_string_option(&buf->b_p_path);
+    clear_string_option(&buf->b_p_tags);
+#ifdef FEAT_INS_EXPAND
+    clear_string_option(&buf->b_p_dict);
+    clear_string_option(&buf->b_p_tsr);
+#endif
+#ifdef FEAT_TEXTOBJ
+    clear_string_option(&buf->b_p_qe);
+#endif
+    buf->b_p_ar = -1;
+}
+
+/*
+ * get alternate file n
+ * set linenr to lnum or altfpos.lnum if lnum == 0
+ *	also set cursor column to altfpos.col if 'startofline' is not set.
+ * if (options & GETF_SETMARK) call setpcmark()
+ * if (options & GETF_ALT) we are jumping to an alternate file.
+ * if (options & GETF_SWITCH) respect 'switchbuf' settings when jumping
+ *
+ * return FAIL for failure, OK for success
+ */
+    int
+buflist_getfile(n, lnum, options, forceit)
+    int		n;
+    linenr_T	lnum;
+    int		options;
+    int		forceit;
+{
+    buf_T	*buf;
+#ifdef FEAT_WINDOWS
+    win_T	*wp = NULL;
+#endif
+    pos_T	*fpos;
+    colnr_T	col;
+
+    buf = buflist_findnr(n);
+    if (buf == NULL)
+    {
+	if ((options & GETF_ALT) && n == 0)
+	    EMSG(_(e_noalt));
+	else
+	    EMSGN(_("E92: Buffer %ld not found"), n);
+	return FAIL;
+    }
+
+    /* if alternate file is the current buffer, nothing to do */
+    if (buf == curbuf)
+	return OK;
+
+    if (text_locked())
+    {
+	text_locked_msg();
+	return FAIL;
+    }
+#ifdef FEAT_AUTOCMD
+    if (curbuf_locked())
+	return FAIL;
+#endif
+
+    /* altfpos may be changed by getfile(), get it now */
+    if (lnum == 0)
+    {
+	fpos = buflist_findfpos(buf);
+	lnum = fpos->lnum;
+	col = fpos->col;
+    }
+    else
+	col = 0;
+
+#ifdef FEAT_WINDOWS
+    if (options & GETF_SWITCH)
+    {
+	/* use existing open window for buffer if wanted */
+	if (vim_strchr(p_swb, 'o') != NULL)	/* useopen */
+	    wp = buf_jump_open_win(buf);
+	/* use existing open window in any tab page for buffer if wanted */
+	if (vim_strchr(p_swb, 'a') != NULL)	/* usetab */
+	    wp = buf_jump_open_tab(buf);
+	/* split window if wanted ("split") */
+	if (wp == NULL && vim_strchr(p_swb, 'l') != NULL && !bufempty())
+	{
+	    if (win_split(0, 0) == FAIL)
+		return FAIL;
+# ifdef FEAT_SCROLLBIND
+	    curwin->w_p_scb = FALSE;
+# endif
+	}
+    }
+#endif
+
+    ++RedrawingDisabled;
+    if (getfile(buf->b_fnum, NULL, NULL, (options & GETF_SETMARK),
+							  lnum, forceit) <= 0)
+    {
+	--RedrawingDisabled;
+
+	/* cursor is at to BOL and w_cursor.lnum is checked due to getfile() */
+	if (!p_sol && col != 0)
+	{
+	    curwin->w_cursor.col = col;
+	    check_cursor_col();
+#ifdef FEAT_VIRTUALEDIT
+	    curwin->w_cursor.coladd = 0;
+#endif
+	    curwin->w_set_curswant = TRUE;
+	}
+	return OK;
+    }
+    --RedrawingDisabled;
+    return FAIL;
+}
+
+/*
+ * go to the last know line number for the current buffer
+ */
+    void
+buflist_getfpos()
+{
+    pos_T	*fpos;
+
+    fpos = buflist_findfpos(curbuf);
+
+    curwin->w_cursor.lnum = fpos->lnum;
+    check_cursor_lnum();
+
+    if (p_sol)
+	curwin->w_cursor.col = 0;
+    else
+    {
+	curwin->w_cursor.col = fpos->col;
+	check_cursor_col();
+#ifdef FEAT_VIRTUALEDIT
+	curwin->w_cursor.coladd = 0;
+#endif
+	curwin->w_set_curswant = TRUE;
+    }
+}
+
+#if defined(FEAT_QUICKFIX) || defined(FEAT_EVAL) || defined(PROTO)
+/*
+ * Find file in buffer list by name (it has to be for the current window).
+ * Returns NULL if not found.
+ */
+    buf_T *
+buflist_findname_exp(fname)
+    char_u *fname;
+{
+    char_u	*ffname;
+    buf_T	*buf = NULL;
+
+    /* First make the name into a full path name */
+    ffname = FullName_save(fname,
+#ifdef UNIX
+	    TRUE	    /* force expansion, get rid of symbolic links */
+#else
+	    FALSE
+#endif
+	    );
+    if (ffname != NULL)
+    {
+	buf = buflist_findname(ffname);
+	vim_free(ffname);
+    }
+    return buf;
+}
+#endif
+
+/*
+ * Find file in buffer list by name (it has to be for the current window).
+ * "ffname" must have a full path.
+ * Skips dummy buffers.
+ * Returns NULL if not found.
+ */
+    buf_T *
+buflist_findname(ffname)
+    char_u	*ffname;
+{
+#ifdef UNIX
+    struct stat st;
+
+    if (mch_stat((char *)ffname, &st) < 0)
+	st.st_dev = (dev_T)-1;
+    return buflist_findname_stat(ffname, &st);
+}
+
+/*
+ * Same as buflist_findname(), but pass the stat structure to avoid getting it
+ * twice for the same file.
+ * Returns NULL if not found.
+ */
+    static buf_T *
+buflist_findname_stat(ffname, stp)
+    char_u	*ffname;
+    struct stat	*stp;
+{
+#endif
+    buf_T	*buf;
+
+    for (buf = firstbuf; buf != NULL; buf = buf->b_next)
+	if ((buf->b_flags & BF_DUMMY) == 0 && !otherfile_buf(buf, ffname
+#ifdef UNIX
+		    , stp
+#endif
+		    ))
+	    return buf;
+    return NULL;
+}
+
+#if defined(FEAT_LISTCMDS) || defined(FEAT_EVAL) || defined(FEAT_PERL) || defined(PROTO)
+/*
+ * Find file in buffer list by a regexp pattern.
+ * Return fnum of the found buffer.
+ * Return < 0 for error.
+ */
+/*ARGSUSED*/
+    int
+buflist_findpat(pattern, pattern_end, unlisted, diffmode)
+    char_u	*pattern;
+    char_u	*pattern_end;	/* pointer to first char after pattern */
+    int		unlisted;	/* find unlisted buffers */
+    int		diffmode;	/* find diff-mode buffers only */
+{
+    buf_T	*buf;
+    regprog_T	*prog;
+    int		match = -1;
+    int		find_listed;
+    char_u	*pat;
+    char_u	*patend;
+    int		attempt;
+    char_u	*p;
+    int		toggledollar;
+
+    if (pattern_end == pattern + 1 && (*pattern == '%' || *pattern == '#'))
+    {
+	if (*pattern == '%')
+	    match = curbuf->b_fnum;
+	else
+	    match = curwin->w_alt_fnum;
+#ifdef FEAT_DIFF
+	if (diffmode && !diff_mode_buf(buflist_findnr(match)))
+	    match = -1;
+#endif
+    }
+
+    /*
+     * Try four ways of matching a listed buffer:
+     * attempt == 0: without '^' or '$' (at any position)
+     * attempt == 1: with '^' at start (only at position 0)
+     * attempt == 2: with '$' at end (only match at end)
+     * attempt == 3: with '^' at start and '$' at end (only full match)
+     * Repeat this for finding an unlisted buffer if there was no matching
+     * listed buffer.
+     */
+    else
+    {
+	pat = file_pat_to_reg_pat(pattern, pattern_end, NULL, FALSE);
+	if (pat == NULL)
+	    return -1;
+	patend = pat + STRLEN(pat) - 1;
+	toggledollar = (patend > pat && *patend == '$');
+
+	/* First try finding a listed buffer.  If not found and "unlisted"
+	 * is TRUE, try finding an unlisted buffer. */
+	find_listed = TRUE;
+	for (;;)
+	{
+	    for (attempt = 0; attempt <= 3; ++attempt)
+	    {
+		/* may add '^' and '$' */
+		if (toggledollar)
+		    *patend = (attempt < 2) ? NUL : '$'; /* add/remove '$' */
+		p = pat;
+		if (*p == '^' && !(attempt & 1))	 /* add/remove '^' */
+		    ++p;
+		prog = vim_regcomp(p, p_magic ? RE_MAGIC : 0);
+		if (prog == NULL)
+		{
+		    vim_free(pat);
+		    return -1;
+		}
+
+		for (buf = firstbuf; buf != NULL; buf = buf->b_next)
+		    if (buf->b_p_bl == find_listed
+#ifdef FEAT_DIFF
+			    && (!diffmode || diff_mode_buf(buf))
+#endif
+			    && buflist_match(prog, buf) != NULL)
+		    {
+			if (match >= 0)		/* already found a match */
+			{
+			    match = -2;
+			    break;
+			}
+			match = buf->b_fnum;	/* remember first match */
+		    }
+
+		vim_free(prog);
+		if (match >= 0)			/* found one match */
+		    break;
+	    }
+
+	    /* Only search for unlisted buffers if there was no match with
+	     * a listed buffer. */
+	    if (!unlisted || !find_listed || match != -1)
+		break;
+	    find_listed = FALSE;
+	}
+
+	vim_free(pat);
+    }
+
+    if (match == -2)
+	EMSG2(_("E93: More than one match for %s"), pattern);
+    else if (match < 0)
+	EMSG2(_("E94: No matching buffer for %s"), pattern);
+    return match;
+}
+#endif
+
+#if defined(FEAT_CMDL_COMPL) || defined(PROTO)
+
+/*
+ * Find all buffer names that match.
+ * For command line expansion of ":buf" and ":sbuf".
+ * Return OK if matches found, FAIL otherwise.
+ */
+    int
+ExpandBufnames(pat, num_file, file, options)
+    char_u	*pat;
+    int		*num_file;
+    char_u	***file;
+    int		options;
+{
+    int		count = 0;
+    buf_T	*buf;
+    int		round;
+    char_u	*p;
+    int		attempt;
+    regprog_T	*prog;
+    char_u	*patc;
+
+    *num_file = 0;		    /* return values in case of FAIL */
+    *file = NULL;
+
+    /* Make a copy of "pat" and change "^" to "\(^\|[\/]\)". */
+    if (*pat == '^')
+    {
+	patc = alloc((unsigned)STRLEN(pat) + 11);
+	if (patc == NULL)
+	    return FAIL;
+	STRCPY(patc, "\\(^\\|[\\/]\\)");
+	STRCPY(patc + 11, pat + 1);
+    }
+    else
+	patc = pat;
+
+    /*
+     * attempt == 0: try match with    '\<', match at start of word
+     * attempt == 1: try match without '\<', match anywhere
+     */
+    for (attempt = 0; attempt <= 1; ++attempt)
+    {
+	if (attempt > 0 && patc == pat)
+	    break;	/* there was no anchor, no need to try again */
+	prog = vim_regcomp(patc + attempt * 11, RE_MAGIC);
+	if (prog == NULL)
+	{
+	    if (patc != pat)
+		vim_free(patc);
+	    return FAIL;
+	}
+
+	/*
+	 * round == 1: Count the matches.
+	 * round == 2: Build the array to keep the matches.
+	 */
+	for (round = 1; round <= 2; ++round)
+	{
+	    count = 0;
+	    for (buf = firstbuf; buf != NULL; buf = buf->b_next)
+	    {
+		if (!buf->b_p_bl)	/* skip unlisted buffers */
+		    continue;
+		p = buflist_match(prog, buf);
+		if (p != NULL)
+		{
+		    if (round == 1)
+			++count;
+		    else
+		    {
+			if (options & WILD_HOME_REPLACE)
+			    p = home_replace_save(buf, p);
+			else
+			    p = vim_strsave(p);
+			(*file)[count++] = p;
+		    }
+		}
+	    }
+	    if (count == 0)	/* no match found, break here */
+		break;
+	    if (round == 1)
+	    {
+		*file = (char_u **)alloc((unsigned)(count * sizeof(char_u *)));
+		if (*file == NULL)
+		{
+		    vim_free(prog);
+		    if (patc != pat)
+			vim_free(patc);
+		    return FAIL;
+		}
+	    }
+	}
+	vim_free(prog);
+	if (count)		/* match(es) found, break here */
+	    break;
+    }
+
+    if (patc != pat)
+	vim_free(patc);
+
+    *num_file = count;
+    return (count == 0 ? FAIL : OK);
+}
+
+#endif /* FEAT_CMDL_COMPL */
+
+#ifdef HAVE_BUFLIST_MATCH
+/*
+ * Check for a match on the file name for buffer "buf" with regprog "prog".
+ */
+    static char_u *
+buflist_match(prog, buf)
+    regprog_T	*prog;
+    buf_T	*buf;
+{
+    char_u	*match;
+
+    /* First try the short file name, then the long file name. */
+    match = fname_match(prog, buf->b_sfname);
+    if (match == NULL)
+	match = fname_match(prog, buf->b_ffname);
+
+    return match;
+}
+
+/*
+ * Try matching the regexp in "prog" with file name "name".
+ * Return "name" when there is a match, NULL when not.
+ */
+    static char_u *
+fname_match(prog, name)
+    regprog_T	*prog;
+    char_u	*name;
+{
+    char_u	*match = NULL;
+    char_u	*p;
+    regmatch_T	regmatch;
+
+    if (name != NULL)
+    {
+	regmatch.regprog = prog;
+#ifdef CASE_INSENSITIVE_FILENAME
+	regmatch.rm_ic = TRUE;		/* Always ignore case */
+#else
+	regmatch.rm_ic = FALSE;		/* Never ignore case */
+#endif
+
+	if (vim_regexec(&regmatch, name, (colnr_T)0))
+	    match = name;
+	else
+	{
+	    /* Replace $(HOME) with '~' and try matching again. */
+	    p = home_replace_save(NULL, name);
+	    if (p != NULL && vim_regexec(&regmatch, p, (colnr_T)0))
+		match = name;
+	    vim_free(p);
+	}
+    }
+
+    return match;
+}
+#endif
+
+/*
+ * find file in buffer list by number
+ */
+    buf_T *
+buflist_findnr(nr)
+    int		nr;
+{
+    buf_T	*buf;
+
+    if (nr == 0)
+	nr = curwin->w_alt_fnum;
+    for (buf = firstbuf; buf != NULL; buf = buf->b_next)
+	if (buf->b_fnum == nr)
+	    return (buf);
+    return NULL;
+}
+
+/*
+ * Get name of file 'n' in the buffer list.
+ * When the file has no name an empty string is returned.
+ * home_replace() is used to shorten the file name (used for marks).
+ * Returns a pointer to allocated memory, of NULL when failed.
+ */
+    char_u *
+buflist_nr2name(n, fullname, helptail)
+    int		n;
+    int		fullname;
+    int		helptail;	/* for help buffers return tail only */
+{
+    buf_T	*buf;
+
+    buf = buflist_findnr(n);
+    if (buf == NULL)
+	return NULL;
+    return home_replace_save(helptail ? buf : NULL,
+				     fullname ? buf->b_ffname : buf->b_fname);
+}
+
+/*
+ * Set the "lnum" and "col" for the buffer "buf" and the current window.
+ * When "copy_options" is TRUE save the local window option values.
+ * When "lnum" is 0 only do the options.
+ */
+    static void
+buflist_setfpos(buf, win, lnum, col, copy_options)
+    buf_T	*buf;
+    win_T	*win;
+    linenr_T	lnum;
+    colnr_T	col;
+    int		copy_options;
+{
+    wininfo_T	*wip;
+
+    for (wip = buf->b_wininfo; wip != NULL; wip = wip->wi_next)
+	if (wip->wi_win == win)
+	    break;
+    if (wip == NULL)
+    {
+	/* allocate a new entry */
+	wip = (wininfo_T *)alloc_clear((unsigned)sizeof(wininfo_T));
+	if (wip == NULL)
+	    return;
+	wip->wi_win = win;
+	if (lnum == 0)		/* set lnum even when it's 0 */
+	    lnum = 1;
+    }
+    else
+    {
+	/* remove the entry from the list */
+	if (wip->wi_prev)
+	    wip->wi_prev->wi_next = wip->wi_next;
+	else
+	    buf->b_wininfo = wip->wi_next;
+	if (wip->wi_next)
+	    wip->wi_next->wi_prev = wip->wi_prev;
+	if (copy_options && wip->wi_optset)
+	{
+	    clear_winopt(&wip->wi_opt);
+#ifdef FEAT_FOLDING
+	    deleteFoldRecurse(&wip->wi_folds);
+#endif
+	}
+    }
+    if (lnum != 0)
+    {
+	wip->wi_fpos.lnum = lnum;
+	wip->wi_fpos.col = col;
+    }
+    if (copy_options)
+    {
+	/* Save the window-specific option values. */
+	copy_winopt(&win->w_onebuf_opt, &wip->wi_opt);
+#ifdef FEAT_FOLDING
+	wip->wi_fold_manual = win->w_fold_manual;
+	cloneFoldGrowArray(&win->w_folds, &wip->wi_folds);
+#endif
+	wip->wi_optset = TRUE;
+    }
+
+    /* insert the entry in front of the list */
+    wip->wi_next = buf->b_wininfo;
+    buf->b_wininfo = wip;
+    wip->wi_prev = NULL;
+    if (wip->wi_next)
+	wip->wi_next->wi_prev = wip;
+
+    return;
+}
+
+/*
+ * Find info for the current window in buffer "buf".
+ * If not found, return the info for the most recently used window.
+ * Returns NULL when there isn't any info.
+ */
+    static wininfo_T *
+find_wininfo(buf)
+    buf_T	*buf;
+{
+    wininfo_T	*wip;
+
+    for (wip = buf->b_wininfo; wip != NULL; wip = wip->wi_next)
+	if (wip->wi_win == curwin)
+	    break;
+    if (wip == NULL)	/* if no fpos for curwin, use the first in the list */
+	wip = buf->b_wininfo;
+    return wip;
+}
+
+/*
+ * Reset the local window options to the values last used in this window.
+ * If the buffer wasn't used in this window before, use the values from
+ * the most recently used window.  If the values were never set, use the
+ * global values for the window.
+ */
+    void
+get_winopts(buf)
+    buf_T	*buf;
+{
+    wininfo_T	*wip;
+
+    clear_winopt(&curwin->w_onebuf_opt);
+#ifdef FEAT_FOLDING
+    clearFolding(curwin);
+#endif
+
+    wip = find_wininfo(buf);
+    if (wip != NULL && wip->wi_optset)
+    {
+	copy_winopt(&wip->wi_opt, &curwin->w_onebuf_opt);
+#ifdef FEAT_FOLDING
+	curwin->w_fold_manual = wip->wi_fold_manual;
+	curwin->w_foldinvalid = TRUE;
+	cloneFoldGrowArray(&wip->wi_folds, &curwin->w_folds);
+#endif
+    }
+    else
+	copy_winopt(&curwin->w_allbuf_opt, &curwin->w_onebuf_opt);
+
+#ifdef FEAT_FOLDING
+    /* Set 'foldlevel' to 'foldlevelstart' if it's not negative. */
+    if (p_fdls >= 0)
+	curwin->w_p_fdl = p_fdls;
+#endif
+}
+
+/*
+ * Find the position (lnum and col) for the buffer 'buf' for the current
+ * window.
+ * Returns a pointer to no_position if no position is found.
+ */
+    pos_T *
+buflist_findfpos(buf)
+    buf_T	*buf;
+{
+    wininfo_T	*wip;
+    static pos_T no_position = {1, 0};
+
+    wip = find_wininfo(buf);
+    if (wip != NULL)
+	return &(wip->wi_fpos);
+    else
+	return &no_position;
+}
+
+/*
+ * Find the lnum for the buffer 'buf' for the current window.
+ */
+    linenr_T
+buflist_findlnum(buf)
+    buf_T	*buf;
+{
+    return buflist_findfpos(buf)->lnum;
+}
+
+#if defined(FEAT_LISTCMDS) || defined(PROTO)
+/*
+ * List all know file names (for :files and :buffers command).
+ */
+/*ARGSUSED*/
+    void
+buflist_list(eap)
+    exarg_T	*eap;
+{
+    buf_T	*buf;
+    int		len;
+    int		i;
+
+    for (buf = firstbuf; buf != NULL && !got_int; buf = buf->b_next)
+    {
+	/* skip unlisted buffers, unless ! was used */
+	if (!buf->b_p_bl && !eap->forceit)
+	    continue;
+	msg_putchar('\n');
+	if (buf_spname(buf) != NULL)
+	    STRCPY(NameBuff, buf_spname(buf));
+	else
+	    home_replace(buf, buf->b_fname, NameBuff, MAXPATHL, TRUE);
+
+	len = vim_snprintf((char *)IObuff, IOSIZE - 20, "%3d%c%c%c%c%c \"%s\"",
+		buf->b_fnum,
+		buf->b_p_bl ? ' ' : 'u',
+		buf == curbuf ? '%' :
+			(curwin->w_alt_fnum == buf->b_fnum ? '#' : ' '),
+		buf->b_ml.ml_mfp == NULL ? ' ' :
+			(buf->b_nwindows == 0 ? 'h' : 'a'),
+		!buf->b_p_ma ? '-' : (buf->b_p_ro ? '=' : ' '),
+		(buf->b_flags & BF_READERR) ? 'x'
+					    : (bufIsChanged(buf) ? '+' : ' '),
+		NameBuff);
+
+	/* put "line 999" in column 40 or after the file name */
+	i = 40 - vim_strsize(IObuff);
+	do
+	{
+	    IObuff[len++] = ' ';
+	} while (--i > 0 && len < IOSIZE - 18);
+	vim_snprintf((char *)IObuff + len, IOSIZE - len, _("line %ld"),
+		buf == curbuf ? curwin->w_cursor.lnum
+					       : (long)buflist_findlnum(buf));
+	msg_outtrans(IObuff);
+	out_flush();	    /* output one line at a time */
+	ui_breakcheck();
+    }
+}
+#endif
+
+/*
+ * Get file name and line number for file 'fnum'.
+ * Used by DoOneCmd() for translating '%' and '#'.
+ * Used by insert_reg() and cmdline_paste() for '#' register.
+ * Return FAIL if not found, OK for success.
+ */
+    int
+buflist_name_nr(fnum, fname, lnum)
+    int		fnum;
+    char_u	**fname;
+    linenr_T	*lnum;
+{
+    buf_T	*buf;
+
+    buf = buflist_findnr(fnum);
+    if (buf == NULL || buf->b_fname == NULL)
+	return FAIL;
+
+    *fname = buf->b_fname;
+    *lnum = buflist_findlnum(buf);
+
+    return OK;
+}
+
+/*
+ * Set the file name for "buf"' to 'ffname', short file name to 'sfname'.
+ * The file name with the full path is also remembered, for when :cd is used.
+ * Returns FAIL for failure (file name already in use by other buffer)
+ *	OK otherwise.
+ */
+    int
+setfname(buf, ffname, sfname, message)
+    buf_T	*buf;
+    char_u	*ffname, *sfname;
+    int		message;	/* give message when buffer already exists */
+{
+    buf_T	*obuf = NULL;
+#ifdef UNIX
+    struct stat st;
+#endif
+
+    if (ffname == NULL || *ffname == NUL)
+    {
+	/* Removing the name. */
+	vim_free(buf->b_ffname);
+	vim_free(buf->b_sfname);
+	buf->b_ffname = NULL;
+	buf->b_sfname = NULL;
+#ifdef UNIX
+	st.st_dev = (dev_T)-1;
+#endif
+    }
+    else
+    {
+	fname_expand(buf, &ffname, &sfname); /* will allocate ffname */
+	if (ffname == NULL)		    /* out of memory */
+	    return FAIL;
+
+	/*
+	 * if the file name is already used in another buffer:
+	 * - if the buffer is loaded, fail
+	 * - if the buffer is not loaded, delete it from the list
+	 */
+#ifdef UNIX
+	if (mch_stat((char *)ffname, &st) < 0)
+	    st.st_dev = (dev_T)-1;
+#endif
+	if (!(buf->b_flags & BF_DUMMY))
+#ifdef UNIX
+	    obuf = buflist_findname_stat(ffname, &st);
+#else
+	    obuf = buflist_findname(ffname);
+#endif
+	if (obuf != NULL && obuf != buf)
+	{
+	    if (obuf->b_ml.ml_mfp != NULL)	/* it's loaded, fail */
+	    {
+		if (message)
+		    EMSG(_("E95: Buffer with this name already exists"));
+		vim_free(ffname);
+		return FAIL;
+	    }
+	    close_buffer(NULL, obuf, DOBUF_WIPE); /* delete from the list */
+	}
+	sfname = vim_strsave(sfname);
+	if (ffname == NULL || sfname == NULL)
+	{
+	    vim_free(sfname);
+	    vim_free(ffname);
+	    return FAIL;
+	}
+#ifdef USE_FNAME_CASE
+# ifdef USE_LONG_FNAME
+	if (USE_LONG_FNAME)
+# endif
+	    fname_case(sfname, 0);    /* set correct case for short file name */
+#endif
+	vim_free(buf->b_ffname);
+	vim_free(buf->b_sfname);
+	buf->b_ffname = ffname;
+	buf->b_sfname = sfname;
+    }
+    buf->b_fname = buf->b_sfname;
+#ifdef UNIX
+    if (st.st_dev == (dev_T)-1)
+	buf->b_dev = -1;
+    else
+    {
+	buf->b_dev = st.st_dev;
+	buf->b_ino = st.st_ino;
+    }
+#endif
+
+#ifndef SHORT_FNAME
+    buf->b_shortname = FALSE;
+#endif
+
+    buf_name_changed(buf);
+    return OK;
+}
+
+/*
+ * Crude way of changing the name of a buffer.  Use with care!
+ * The name should be relative to the current directory.
+ */
+    void
+buf_set_name(fnum, name)
+    int		fnum;
+    char_u	*name;
+{
+    buf_T	*buf;
+
+    buf = buflist_findnr(fnum);
+    if (buf != NULL)
+    {
+	vim_free(buf->b_sfname);
+	vim_free(buf->b_ffname);
+	buf->b_ffname = vim_strsave(name);
+	buf->b_sfname = NULL;
+	/* Allocate ffname and expand into full path.  Also resolves .lnk
+	 * files on Win32. */
+	fname_expand(buf, &buf->b_ffname, &buf->b_sfname);
+	buf->b_fname = buf->b_sfname;
+    }
+}
+
+/*
+ * Take care of what needs to be done when the name of buffer "buf" has
+ * changed.
+ */
+    void
+buf_name_changed(buf)
+    buf_T	*buf;
+{
+    /*
+     * If the file name changed, also change the name of the swapfile
+     */
+    if (buf->b_ml.ml_mfp != NULL)
+	ml_setname(buf);
+
+    if (curwin->w_buffer == buf)
+	check_arg_idx(curwin);	/* check file name for arg list */
+#ifdef FEAT_TITLE
+    maketitle();		/* set window title */
+#endif
+#ifdef FEAT_WINDOWS
+    status_redraw_all();	/* status lines need to be redrawn */
+#endif
+    fmarks_check_names(buf);	/* check named file marks */
+    ml_timestamp(buf);		/* reset timestamp */
+}
+
+/*
+ * set alternate file name for current window
+ *
+ * Used by do_one_cmd(), do_write() and do_ecmd().
+ * Return the buffer.
+ */
+    buf_T *
+setaltfname(ffname, sfname, lnum)
+    char_u	*ffname;
+    char_u	*sfname;
+    linenr_T	lnum;
+{
+    buf_T	*buf;
+
+    /* Create a buffer.  'buflisted' is not set if it's a new buffer */
+    buf = buflist_new(ffname, sfname, lnum, 0);
+    if (buf != NULL && !cmdmod.keepalt)
+	curwin->w_alt_fnum = buf->b_fnum;
+    return buf;
+}
+
+/*
+ * Get alternate file name for current window.
+ * Return NULL if there isn't any, and give error message if requested.
+ */
+    char_u  *
+getaltfname(errmsg)
+    int		errmsg;		/* give error message */
+{
+    char_u	*fname;
+    linenr_T	dummy;
+
+    if (buflist_name_nr(0, &fname, &dummy) == FAIL)
+    {
+	if (errmsg)
+	    EMSG(_(e_noalt));
+	return NULL;
+    }
+    return fname;
+}
+
+/*
+ * Add a file name to the buflist and return its number.
+ * Uses same flags as buflist_new(), except BLN_DUMMY.
+ *
+ * used by qf_init(), main() and doarglist()
+ */
+    int
+buflist_add(fname, flags)
+    char_u	*fname;
+    int		flags;
+{
+    buf_T	*buf;
+
+    buf = buflist_new(fname, NULL, (linenr_T)0, flags);
+    if (buf != NULL)
+	return buf->b_fnum;
+    return 0;
+}
+
+#if defined(BACKSLASH_IN_FILENAME) || defined(PROTO)
+/*
+ * Adjust slashes in file names.  Called after 'shellslash' was set.
+ */
+    void
+buflist_slash_adjust()
+{
+    buf_T	*bp;
+
+    for (bp = firstbuf; bp != NULL; bp = bp->b_next)
+    {
+	if (bp->b_ffname != NULL)
+	    slash_adjust(bp->b_ffname);
+	if (bp->b_sfname != NULL)
+	    slash_adjust(bp->b_sfname);
+    }
+}
+#endif
+
+/*
+ * Set alternate cursor position for current window.
+ * Also save the local window option values.
+ */
+    void
+buflist_altfpos()
+{
+    buflist_setfpos(curbuf, curwin, curwin->w_cursor.lnum,
+						  curwin->w_cursor.col, TRUE);
+}
+
+/*
+ * Return TRUE if 'ffname' is not the same file as current file.
+ * Fname must have a full path (expanded by mch_FullName()).
+ */
+    int
+otherfile(ffname)
+    char_u	*ffname;
+{
+    return otherfile_buf(curbuf, ffname
+#ifdef UNIX
+	    , NULL
+#endif
+	    );
+}
+
+    static int
+otherfile_buf(buf, ffname
+#ifdef UNIX
+	, stp
+#endif
+	)
+    buf_T	*buf;
+    char_u	*ffname;
+#ifdef UNIX
+    struct stat	*stp;
+#endif
+{
+    /* no name is different */
+    if (ffname == NULL || *ffname == NUL || buf->b_ffname == NULL)
+	return TRUE;
+    if (fnamecmp(ffname, buf->b_ffname) == 0)
+	return FALSE;
+#ifdef UNIX
+    {
+	struct stat	st;
+
+	/* If no struct stat given, get it now */
+	if (stp == NULL)
+	{
+	    if (buf->b_dev < 0 || mch_stat((char *)ffname, &st) < 0)
+		st.st_dev = (dev_T)-1;
+	    stp = &st;
+	}
+	/* Use dev/ino to check if the files are the same, even when the names
+	 * are different (possible with links).  Still need to compare the
+	 * name above, for when the file doesn't exist yet.
+	 * Problem: The dev/ino changes when a file is deleted (and created
+	 * again) and remains the same when renamed/moved.  We don't want to
+	 * mch_stat() each buffer each time, that would be too slow.  Get the
+	 * dev/ino again when they appear to match, but not when they appear
+	 * to be different: Could skip a buffer when it's actually the same
+	 * file. */
+	if (buf_same_ino(buf, stp))
+	{
+	    buf_setino(buf);
+	    if (buf_same_ino(buf, stp))
+		return FALSE;
+	}
+    }
+#endif
+    return TRUE;
+}
+
+#if defined(UNIX) || defined(PROTO)
+/*
+ * Set inode and device number for a buffer.
+ * Must always be called when b_fname is changed!.
+ */
+    void
+buf_setino(buf)
+    buf_T	*buf;
+{
+    struct stat	st;
+
+    if (buf->b_fname != NULL && mch_stat((char *)buf->b_fname, &st) >= 0)
+    {
+	buf->b_dev = st.st_dev;
+	buf->b_ino = st.st_ino;
+    }
+    else
+	buf->b_dev = -1;
+}
+
+/*
+ * Return TRUE if dev/ino in buffer "buf" matches with "stp".
+ */
+    static int
+buf_same_ino(buf, stp)
+    buf_T	*buf;
+    struct stat *stp;
+{
+    return (buf->b_dev >= 0
+	    && stp->st_dev == buf->b_dev
+	    && stp->st_ino == buf->b_ino);
+}
+#endif
+
+/*
+ * Print info about the current buffer.
+ */
+    void
+fileinfo(fullname, shorthelp, dont_truncate)
+    int fullname;	    /* when non-zero print full path */
+    int shorthelp;
+    int	dont_truncate;
+{
+    char_u	*name;
+    int		n;
+    char_u	*p;
+    char_u	*buffer;
+    size_t	len;
+
+    buffer = alloc(IOSIZE);
+    if (buffer == NULL)
+	return;
+
+    if (fullname > 1)	    /* 2 CTRL-G: include buffer number */
+    {
+	sprintf((char *)buffer, "buf %d: ", curbuf->b_fnum);
+	p = buffer + STRLEN(buffer);
+    }
+    else
+	p = buffer;
+
+    *p++ = '"';
+    if (buf_spname(curbuf) != NULL)
+	STRCPY(p, buf_spname(curbuf));
+    else
+    {
+	if (!fullname && curbuf->b_fname != NULL)
+	    name = curbuf->b_fname;
+	else
+	    name = curbuf->b_ffname;
+	home_replace(shorthelp ? curbuf : NULL, name, p,
+					  (int)(IOSIZE - (p - buffer)), TRUE);
+    }
+
+    len = STRLEN(buffer);
+    vim_snprintf((char *)buffer + len, IOSIZE - len,
+	    "\"%s%s%s%s%s%s",
+	    curbufIsChanged() ? (shortmess(SHM_MOD)
+					  ?  " [+]" : _(" [Modified]")) : " ",
+	    (curbuf->b_flags & BF_NOTEDITED)
+#ifdef FEAT_QUICKFIX
+		    && !bt_dontwrite(curbuf)
+#endif
+					? _("[Not edited]") : "",
+	    (curbuf->b_flags & BF_NEW)
+#ifdef FEAT_QUICKFIX
+		    && !bt_dontwrite(curbuf)
+#endif
+					? _("[New file]") : "",
+	    (curbuf->b_flags & BF_READERR) ? _("[Read errors]") : "",
+	    curbuf->b_p_ro ? (shortmess(SHM_RO) ? "[RO]"
+						      : _("[readonly]")) : "",
+	    (curbufIsChanged() || (curbuf->b_flags & BF_WRITE_MASK)
+							  || curbuf->b_p_ro) ?
+								    " " : "");
+    /* With 32 bit longs and more than 21,474,836 lines multiplying by 100
+     * causes an overflow, thus for large numbers divide instead. */
+    if (curwin->w_cursor.lnum > 1000000L)
+	n = (int)(((long)curwin->w_cursor.lnum) /
+				   ((long)curbuf->b_ml.ml_line_count / 100L));
+    else
+	n = (int)(((long)curwin->w_cursor.lnum * 100L) /
+					    (long)curbuf->b_ml.ml_line_count);
+    len = STRLEN(buffer);
+    if (curbuf->b_ml.ml_flags & ML_EMPTY)
+    {
+	vim_snprintf((char *)buffer + len, IOSIZE - len, "%s", _(no_lines_msg));
+    }
+#ifdef FEAT_CMDL_INFO
+    else if (p_ru)
+    {
+	/* Current line and column are already on the screen -- webb */
+	if (curbuf->b_ml.ml_line_count == 1)
+	    vim_snprintf((char *)buffer + len, IOSIZE - len,
+		    _("1 line --%d%%--"), n);
+	else
+	    vim_snprintf((char *)buffer + len, IOSIZE - len,
+		    _("%ld lines --%d%%--"),
+					 (long)curbuf->b_ml.ml_line_count, n);
+    }
+#endif
+    else
+    {
+	vim_snprintf((char *)buffer + len, IOSIZE - len,
+		_("line %ld of %ld --%d%%-- col "),
+		(long)curwin->w_cursor.lnum,
+		(long)curbuf->b_ml.ml_line_count,
+		n);
+	validate_virtcol();
+	col_print(buffer + STRLEN(buffer),
+		   (int)curwin->w_cursor.col + 1, (int)curwin->w_virtcol + 1);
+    }
+
+    (void)append_arg_number(curwin, buffer, !shortmess(SHM_FILE), IOSIZE);
+
+    if (dont_truncate)
+    {
+	/* Temporarily set msg_scroll to avoid the message being truncated.
+	 * First call msg_start() to get the message in the right place. */
+	msg_start();
+	n = msg_scroll;
+	msg_scroll = TRUE;
+	msg(buffer);
+	msg_scroll = n;
+    }
+    else
+    {
+	p = msg_trunc_attr(buffer, FALSE, 0);
+	if (restart_edit != 0 || (msg_scrolled && !need_wait_return))
+	    /* Need to repeat the message after redrawing when:
+	     * - When restart_edit is set (otherwise there will be a delay
+	     *   before redrawing).
+	     * - When the screen was scrolled but there is no wait-return
+	     *   prompt. */
+	    set_keep_msg(p, 0);
+    }
+
+    vim_free(buffer);
+}
+
+    void
+col_print(buf, col, vcol)
+    char_u  *buf;
+    int	    col;
+    int	    vcol;
+{
+    if (col == vcol)
+	sprintf((char *)buf, "%d", col);
+    else
+	sprintf((char *)buf, "%d-%d", col, vcol);
+}
+
+#if defined(FEAT_TITLE) || defined(PROTO)
+/*
+ * put file name in title bar of window and in icon title
+ */
+
+static char_u *lasttitle = NULL;
+static char_u *lasticon = NULL;
+
+    void
+maketitle()
+{
+    char_u	*p;
+    char_u	*t_str = NULL;
+    char_u	*i_name;
+    char_u	*i_str = NULL;
+    int		maxlen = 0;
+    int		len;
+    int		mustset;
+    char_u	buf[IOSIZE];
+    int		off;
+
+    if (!redrawing())
+    {
+	/* Postpone updating the title when 'lazyredraw' is set. */
+	need_maketitle = TRUE;
+	return;
+    }
+
+    need_maketitle = FALSE;
+    if (!p_title && !p_icon)
+	return;
+
+    if (p_title)
+    {
+	if (p_titlelen > 0)
+	{
+	    maxlen = p_titlelen * Columns / 100;
+	    if (maxlen < 10)
+		maxlen = 10;
+	}
+
+	t_str = buf;
+	if (*p_titlestring != NUL)
+	{
+#ifdef FEAT_STL_OPT
+	    if (stl_syntax & STL_IN_TITLE)
+	    {
+		int	use_sandbox = FALSE;
+		int	save_called_emsg = called_emsg;
+
+# ifdef FEAT_EVAL
+		use_sandbox = was_set_insecurely((char_u *)"titlestring", 0);
+# endif
+		called_emsg = FALSE;
+		build_stl_str_hl(curwin, t_str, sizeof(buf),
+					      p_titlestring, use_sandbox,
+					      0, maxlen, NULL, NULL);
+		if (called_emsg)
+		    set_string_option_direct((char_u *)"titlestring", -1,
+					   (char_u *)"", OPT_FREE, SID_ERROR);
+		called_emsg |= save_called_emsg;
+	    }
+	    else
+#endif
+		t_str = p_titlestring;
+	}
+	else
+	{
+	    /* format: "fname + (path) (1 of 2) - VIM" */
+
+	    if (curbuf->b_fname == NULL)
+		STRCPY(buf, _("[No Name]"));
+	    else
+	    {
+		p = transstr(gettail(curbuf->b_fname));
+		vim_strncpy(buf, p, IOSIZE - 100);
+		vim_free(p);
+	    }
+
+	    switch (bufIsChanged(curbuf)
+		    + (curbuf->b_p_ro * 2)
+		    + (!curbuf->b_p_ma * 4))
+	    {
+		case 1: STRCAT(buf, " +"); break;
+		case 2: STRCAT(buf, " ="); break;
+		case 3: STRCAT(buf, " =+"); break;
+		case 4:
+		case 6: STRCAT(buf, " -"); break;
+		case 5:
+		case 7: STRCAT(buf, " -+"); break;
+	    }
+
+	    if (curbuf->b_fname != NULL)
+	    {
+		/* Get path of file, replace home dir with ~ */
+		off = (int)STRLEN(buf);
+		buf[off++] = ' ';
+		buf[off++] = '(';
+		home_replace(curbuf, curbuf->b_ffname,
+					       buf + off, IOSIZE - off, TRUE);
+#ifdef BACKSLASH_IN_FILENAME
+		/* avoid "c:/name" to be reduced to "c" */
+		if (isalpha(buf[off]) && buf[off + 1] == ':')
+		    off += 2;
+#endif
+		/* remove the file name */
+		p = gettail_sep(buf + off);
+		if (p == buf + off)
+		    /* must be a help buffer */
+		    vim_strncpy(buf + off, (char_u *)_("help"),
+							    IOSIZE - off - 1);
+		else
+		    *p = NUL;
+
+		/* translate unprintable chars */
+		p = transstr(buf + off);
+		vim_strncpy(buf + off, p, IOSIZE - off - 1);
+		vim_free(p);
+		STRCAT(buf, ")");
+	    }
+
+	    append_arg_number(curwin, buf, FALSE, IOSIZE);
+
+#if defined(FEAT_CLIENTSERVER)
+	    if (serverName != NULL)
+	    {
+		STRCAT(buf, " - ");
+		STRCAT(buf, serverName);
+	    }
+	    else
+#endif
+		STRCAT(buf, " - VIM");
+
+	    if (maxlen > 0)
+	    {
+		/* make it shorter by removing a bit in the middle */
+		len = vim_strsize(buf);
+		if (len > maxlen)
+		    trunc_string(buf, buf, maxlen);
+	    }
+	}
+    }
+    mustset = ti_change(t_str, &lasttitle);
+
+    if (p_icon)
+    {
+	i_str = buf;
+	if (*p_iconstring != NUL)
+	{
+#ifdef FEAT_STL_OPT
+	    if (stl_syntax & STL_IN_ICON)
+	    {
+		int	use_sandbox = FALSE;
+		int	save_called_emsg = called_emsg;
+
+# ifdef FEAT_EVAL
+		use_sandbox = was_set_insecurely((char_u *)"iconstring", 0);
+# endif
+		called_emsg = FALSE;
+		build_stl_str_hl(curwin, i_str, sizeof(buf),
+						    p_iconstring, use_sandbox,
+						    0, 0, NULL, NULL);
+		if (called_emsg)
+		    set_string_option_direct((char_u *)"iconstring", -1,
+					   (char_u *)"", OPT_FREE, SID_ERROR);
+		called_emsg |= save_called_emsg;
+	    }
+	    else
+#endif
+		i_str = p_iconstring;
+	}
+	else
+	{
+	    if (buf_spname(curbuf) != NULL)
+		i_name = (char_u *)buf_spname(curbuf);
+	    else		    /* use file name only in icon */
+		i_name = gettail(curbuf->b_ffname);
+	    *i_str = NUL;
+	    /* Truncate name at 100 bytes. */
+	    len = (int)STRLEN(i_name);
+	    if (len > 100)
+	    {
+		len -= 100;
+#ifdef FEAT_MBYTE
+		if (has_mbyte)
+		    len += (*mb_tail_off)(i_name, i_name + len) + 1;
+#endif
+		i_name += len;
+	    }
+	    STRCPY(i_str, i_name);
+	    trans_characters(i_str, IOSIZE);
+	}
+    }
+
+    mustset |= ti_change(i_str, &lasticon);
+
+    if (mustset)
+	resettitle();
+}
+
+/*
+ * Used for title and icon: Check if "str" differs from "*last".  Set "*last"
+ * from "str" if it does.
+ * Return TRUE when "*last" changed.
+ */
+    static int
+ti_change(str, last)
+    char_u	*str;
+    char_u	**last;
+{
+    if ((str == NULL) != (*last == NULL)
+	    || (str != NULL && *last != NULL && STRCMP(str, *last) != 0))
+    {
+	vim_free(*last);
+	if (str == NULL)
+	    *last = NULL;
+	else
+	    *last = vim_strsave(str);
+	return TRUE;
+    }
+    return FALSE;
+}
+
+/*
+ * Put current window title back (used after calling a shell)
+ */
+    void
+resettitle()
+{
+    mch_settitle(lasttitle, lasticon);
+}
+
+# if defined(EXITFREE) || defined(PROTO)
+    void
+free_titles()
+{
+    vim_free(lasttitle);
+    vim_free(lasticon);
+}
+# endif
+
+#endif /* FEAT_TITLE */
+
+#if defined(FEAT_STL_OPT) || defined(FEAT_GUI_TABLINE) || defined(PROTO)
+/*
+ * Build a string from the status line items in "fmt".
+ * Return length of string in screen cells.
+ *
+ * Normally works for window "wp", except when working for 'tabline' then it
+ * is "curwin".
+ *
+ * Items are drawn interspersed with the text that surrounds it
+ * Specials: %-<wid>(xxx%) => group, %= => middle marker, %< => truncation
+ * Item: %-<minwid>.<maxwid><itemch> All but <itemch> are optional
+ *
+ * If maxwidth is not zero, the string will be filled at any middle marker
+ * or truncated if too long, fillchar is used for all whitespace.
+ */
+/*ARGSUSED*/
+    int
+build_stl_str_hl(wp, out, outlen, fmt, use_sandbox, fillchar, maxwidth, hltab, tabtab)
+    win_T	*wp;
+    char_u	*out;		/* buffer to write into != NameBuff */
+    size_t	outlen;		/* length of out[] */
+    char_u	*fmt;
+    int		use_sandbox;	/* "fmt" was set insecurely, use sandbox */
+    int		fillchar;
+    int		maxwidth;
+    struct stl_hlrec *hltab;	/* return: HL attributes (can be NULL) */
+    struct stl_hlrec *tabtab;	/* return: tab page nrs (can be NULL) */
+{
+    char_u	*p;
+    char_u	*s;
+    char_u	*t;
+    char_u	*linecont;
+#ifdef FEAT_EVAL
+    win_T	*o_curwin;
+    buf_T	*o_curbuf;
+#endif
+    int		empty_line;
+    colnr_T	virtcol;
+    long	l;
+    long	n;
+    int		prevchar_isflag;
+    int		prevchar_isitem;
+    int		itemisflag;
+    int		fillable;
+    char_u	*str;
+    long	num;
+    int		width;
+    int		itemcnt;
+    int		curitem;
+    int		groupitem[STL_MAX_ITEM];
+    int		groupdepth;
+    struct stl_item
+    {
+	char_u		*start;
+	int		minwid;
+	int		maxwid;
+	enum
+	{
+	    Normal,
+	    Empty,
+	    Group,
+	    Middle,
+	    Highlight,
+	    TabPage,
+	    Trunc
+	}		type;
+    }		item[STL_MAX_ITEM];
+    int		minwid;
+    int		maxwid;
+    int		zeropad;
+    char_u	base;
+    char_u	opt;
+#define TMPLEN 70
+    char_u	tmp[TMPLEN];
+    char_u	*usefmt = fmt;
+    struct stl_hlrec *sp;
+
+#ifdef FEAT_EVAL
+    /*
+     * When the format starts with "%!" then evaluate it as an expression and
+     * use the result as the actual format string.
+     */
+    if (fmt[0] == '%' && fmt[1] == '!')
+    {
+	usefmt = eval_to_string_safe(fmt + 2, NULL, use_sandbox);
+	if (usefmt == NULL)
+	    usefmt = fmt;
+    }
+#endif
+
+    if (fillchar == 0)
+	fillchar = ' ';
+#ifdef FEAT_MBYTE
+    /* Can't handle a multi-byte fill character yet. */
+    else if (mb_char2len(fillchar) > 1)
+	fillchar = '-';
+#endif
+
+    /*
+     * Get line & check if empty (cursorpos will show "0-1").
+     * If inversion is possible we use it. Else '=' characters are used.
+     */
+    linecont = ml_get_buf(wp->w_buffer, wp->w_cursor.lnum, FALSE);
+    empty_line = (*linecont == NUL);
+
+    groupdepth = 0;
+    p = out;
+    curitem = 0;
+    prevchar_isflag = TRUE;
+    prevchar_isitem = FALSE;
+    for (s = usefmt; *s; )
+    {
+	if (*s != NUL && *s != '%')
+	    prevchar_isflag = prevchar_isitem = FALSE;
+
+	/*
+	 * Handle up to the next '%' or the end.
+	 */
+	while (*s != NUL && *s != '%' && p + 1 < out + outlen)
+	    *p++ = *s++;
+	if (*s == NUL || p + 1 >= out + outlen)
+	    break;
+
+	/*
+	 * Handle one '%' item.
+	 */
+	s++;
+	if (*s == '%')
+	{
+	    if (p + 1 >= out + outlen)
+		break;
+	    *p++ = *s++;
+	    prevchar_isflag = prevchar_isitem = FALSE;
+	    continue;
+	}
+	if (*s == STL_MIDDLEMARK)
+	{
+	    s++;
+	    if (groupdepth > 0)
+		continue;
+	    item[curitem].type = Middle;
+	    item[curitem++].start = p;
+	    continue;
+	}
+	if (*s == STL_TRUNCMARK)
+	{
+	    s++;
+	    item[curitem].type = Trunc;
+	    item[curitem++].start = p;
+	    continue;
+	}
+	if (*s == ')')
+	{
+	    s++;
+	    if (groupdepth < 1)
+		continue;
+	    groupdepth--;
+
+	    t = item[groupitem[groupdepth]].start;
+	    *p = NUL;
+	    l = vim_strsize(t);
+	    if (curitem > groupitem[groupdepth] + 1
+		    && item[groupitem[groupdepth]].minwid == 0)
+	    {
+		/* remove group if all items are empty */
+		for (n = groupitem[groupdepth] + 1; n < curitem; n++)
+		    if (item[n].type == Normal)
+			break;
+		if (n == curitem)
+		{
+		    p = t;
+		    l = 0;
+		}
+	    }
+	    if (l > item[groupitem[groupdepth]].maxwid)
+	    {
+		/* truncate, remove n bytes of text at the start */
+#ifdef FEAT_MBYTE
+		if (has_mbyte)
+		{
+		    /* Find the first character that should be included. */
+		    n = 0;
+		    while (l >= item[groupitem[groupdepth]].maxwid)
+		    {
+			l -= ptr2cells(t + n);
+			n += (*mb_ptr2len)(t + n);
+		    }
+		}
+		else
+#endif
+		    n = (long)(p - t) - item[groupitem[groupdepth]].maxwid + 1;
+
+		*t = '<';
+		mch_memmove(t + 1, t + n, p - (t + n));
+		p = p - n + 1;
+#ifdef FEAT_MBYTE
+		/* Fill up space left over by half a double-wide char. */
+		while (++l < item[groupitem[groupdepth]].minwid)
+		    *p++ = fillchar;
+#endif
+
+		/* correct the start of the items for the truncation */
+		for (l = groupitem[groupdepth] + 1; l < curitem; l++)
+		{
+		    item[l].start -= n;
+		    if (item[l].start < t)
+			item[l].start = t;
+		}
+	    }
+	    else if (abs(item[groupitem[groupdepth]].minwid) > l)
+	    {
+		/* fill */
+		n = item[groupitem[groupdepth]].minwid;
+		if (n < 0)
+		{
+		    /* fill by appending characters */
+		    n = 0 - n;
+		    while (l++ < n && p + 1 < out + outlen)
+			*p++ = fillchar;
+		}
+		else
+		{
+		    /* fill by inserting characters */
+		    mch_memmove(t + n - l, t, p - t);
+		    l = n - l;
+		    if (p + l >= out + outlen)
+			l = (long)((out + outlen) - p - 1);
+		    p += l;
+		    for (n = groupitem[groupdepth] + 1; n < curitem; n++)
+			item[n].start += l;
+		    for ( ; l > 0; l--)
+			*t++ = fillchar;
+		}
+	    }
+	    continue;
+	}
+	minwid = 0;
+	maxwid = 9999;
+	zeropad = FALSE;
+	l = 1;
+	if (*s == '0')
+	{
+	    s++;
+	    zeropad = TRUE;
+	}
+	if (*s == '-')
+	{
+	    s++;
+	    l = -1;
+	}
+	if (VIM_ISDIGIT(*s))
+	{
+	    minwid = (int)getdigits(&s);
+	    if (minwid < 0)	/* overflow */
+		minwid = 0;
+	}
+	if (*s == STL_USER_HL)
+	{
+	    item[curitem].type = Highlight;
+	    item[curitem].start = p;
+	    item[curitem].minwid = minwid > 9 ? 1 : minwid;
+	    s++;
+	    curitem++;
+	    continue;
+	}
+	if (*s == STL_TABPAGENR || *s == STL_TABCLOSENR)
+	{
+	    if (*s == STL_TABCLOSENR)
+	    {
+		if (minwid == 0)
+		{
+		    /* %X ends the close label, go back to the previously
+		     * define tab label nr. */
+		    for (n = curitem - 1; n >= 0; --n)
+			if (item[n].type == TabPage && item[n].minwid >= 0)
+			{
+			    minwid = item[n].minwid;
+			    break;
+			}
+		}
+		else
+		    /* close nrs are stored as negative values */
+		    minwid = - minwid;
+	    }
+	    item[curitem].type = TabPage;
+	    item[curitem].start = p;
+	    item[curitem].minwid = minwid;
+	    s++;
+	    curitem++;
+	    continue;
+	}
+	if (*s == '.')
+	{
+	    s++;
+	    if (VIM_ISDIGIT(*s))
+	    {
+		maxwid = (int)getdigits(&s);
+		if (maxwid <= 0)	/* overflow */
+		    maxwid = 50;
+	    }
+	}
+	minwid = (minwid > 50 ? 50 : minwid) * l;
+	if (*s == '(')
+	{
+	    groupitem[groupdepth++] = curitem;
+	    item[curitem].type = Group;
+	    item[curitem].start = p;
+	    item[curitem].minwid = minwid;
+	    item[curitem].maxwid = maxwid;
+	    s++;
+	    curitem++;
+	    continue;
+	}
+	if (vim_strchr(STL_ALL, *s) == NULL)
+	{
+	    s++;
+	    continue;
+	}
+	opt = *s++;
+
+	/* OK - now for the real work */
+	base = 'D';
+	itemisflag = FALSE;
+	fillable = TRUE;
+	num = -1;
+	str = NULL;
+	switch (opt)
+	{
+	case STL_FILEPATH:
+	case STL_FULLPATH:
+	case STL_FILENAME:
+	    fillable = FALSE;	/* don't change ' ' to fillchar */
+	    if (buf_spname(wp->w_buffer) != NULL)
+		STRCPY(NameBuff, buf_spname(wp->w_buffer));
+	    else
+	    {
+		t = (opt == STL_FULLPATH) ? wp->w_buffer->b_ffname
+					  : wp->w_buffer->b_fname;
+		home_replace(wp->w_buffer, t, NameBuff, MAXPATHL, TRUE);
+	    }
+	    trans_characters(NameBuff, MAXPATHL);
+	    if (opt != STL_FILENAME)
+		str = NameBuff;
+	    else
+		str = gettail(NameBuff);
+	    break;
+
+	case STL_VIM_EXPR: /* '{' */
+	    itemisflag = TRUE;
+	    t = p;
+	    while (*s != '}' && *s != NUL && p + 1 < out + outlen)
+		*p++ = *s++;
+	    if (*s != '}')	/* missing '}' or out of space */
+		break;
+	    s++;
+	    *p = 0;
+	    p = t;
+
+#ifdef FEAT_EVAL
+	    sprintf((char *)tmp, "%d", curbuf->b_fnum);
+	    set_internal_string_var((char_u *)"actual_curbuf", tmp);
+
+	    o_curbuf = curbuf;
+	    o_curwin = curwin;
+	    curwin = wp;
+	    curbuf = wp->w_buffer;
+
+	    str = eval_to_string_safe(p, &t, use_sandbox);
+
+	    curwin = o_curwin;
+	    curbuf = o_curbuf;
+	    do_unlet((char_u *)"g:actual_curbuf", TRUE);
+
+	    if (str != NULL && *str != 0)
+	    {
+		if (*skipdigits(str) == NUL)
+		{
+		    num = atoi((char *)str);
+		    vim_free(str);
+		    str = NULL;
+		    itemisflag = FALSE;
+		}
+	    }
+#endif
+	    break;
+
+	case STL_LINE:
+	    num = (wp->w_buffer->b_ml.ml_flags & ML_EMPTY)
+		  ? 0L : (long)(wp->w_cursor.lnum);
+	    break;
+
+	case STL_NUMLINES:
+	    num = wp->w_buffer->b_ml.ml_line_count;
+	    break;
+
+	case STL_COLUMN:
+	    num = !(State & INSERT) && empty_line
+		  ? 0 : (int)wp->w_cursor.col + 1;
+	    break;
+
+	case STL_VIRTCOL:
+	case STL_VIRTCOL_ALT:
+	    /* In list mode virtcol needs to be recomputed */
+	    virtcol = wp->w_virtcol;
+	    if (wp->w_p_list && lcs_tab1 == NUL)
+	    {
+		wp->w_p_list = FALSE;
+		getvcol(wp, &wp->w_cursor, NULL, &virtcol, NULL);
+		wp->w_p_list = TRUE;
+	    }
+	    ++virtcol;
+	    /* Don't display %V if it's the same as %c. */
+	    if (opt == STL_VIRTCOL_ALT
+		    && (virtcol == (colnr_T)(!(State & INSERT) && empty_line
+			    ? 0 : (int)wp->w_cursor.col + 1)))
+		break;
+	    num = (long)virtcol;
+	    break;
+
+	case STL_PERCENTAGE:
+	    num = (int)(((long)wp->w_cursor.lnum * 100L) /
+			(long)wp->w_buffer->b_ml.ml_line_count);
+	    break;
+
+	case STL_ALTPERCENT:
+	    str = tmp;
+	    get_rel_pos(wp, str);
+	    break;
+
+	case STL_ARGLISTSTAT:
+	    fillable = FALSE;
+	    tmp[0] = 0;
+	    if (append_arg_number(wp, tmp, FALSE, (int)sizeof(tmp)))
+		str = tmp;
+	    break;
+
+	case STL_KEYMAP:
+	    fillable = FALSE;
+	    if (get_keymap_str(wp, tmp, TMPLEN))
+		str = tmp;
+	    break;
+	case STL_PAGENUM:
+#if defined(FEAT_PRINTER) || defined(FEAT_GUI_TABLINE)
+	    num = printer_page_num;
+#else
+	    num = 0;
+#endif
+	    break;
+
+	case STL_BUFNO:
+	    num = wp->w_buffer->b_fnum;
+	    break;
+
+	case STL_OFFSET_X:
+	    base = 'X';
+	case STL_OFFSET:
+#ifdef FEAT_BYTEOFF
+	    l = ml_find_line_or_offset(wp->w_buffer, wp->w_cursor.lnum, NULL);
+	    num = (wp->w_buffer->b_ml.ml_flags & ML_EMPTY) || l < 0 ?
+		  0L : l + 1 + (!(State & INSERT) && empty_line ?
+				0 : (int)wp->w_cursor.col);
+#endif
+	    break;
+
+	case STL_BYTEVAL_X:
+	    base = 'X';
+	case STL_BYTEVAL:
+	    if (wp->w_cursor.col > STRLEN(linecont))
+		num = 0;
+	    else
+	    {
+#ifdef FEAT_MBYTE
+		num = (*mb_ptr2char)(linecont + wp->w_cursor.col);
+#else
+		num = linecont[wp->w_cursor.col];
+#endif
+	    }
+	    if (num == NL)
+		num = 0;
+	    else if (num == CAR && get_fileformat(wp->w_buffer) == EOL_MAC)
+		num = NL;
+	    break;
+
+	case STL_ROFLAG:
+	case STL_ROFLAG_ALT:
+	    itemisflag = TRUE;
+	    if (wp->w_buffer->b_p_ro)
+		str = (char_u *)((opt == STL_ROFLAG_ALT) ? ",RO" : "[RO]");
+	    break;
+
+	case STL_HELPFLAG:
+	case STL_HELPFLAG_ALT:
+	    itemisflag = TRUE;
+	    if (wp->w_buffer->b_help)
+		str = (char_u *)((opt == STL_HELPFLAG_ALT) ? ",HLP"
+							       : _("[Help]"));
+	    break;
+
+#ifdef FEAT_AUTOCMD
+	case STL_FILETYPE:
+	    if (*wp->w_buffer->b_p_ft != NUL
+		    && STRLEN(wp->w_buffer->b_p_ft) < TMPLEN - 3)
+	    {
+		vim_snprintf((char *)tmp, sizeof(tmp), "[%s]",
+							wp->w_buffer->b_p_ft);
+		str = tmp;
+	    }
+	    break;
+
+	case STL_FILETYPE_ALT:
+	    itemisflag = TRUE;
+	    if (*wp->w_buffer->b_p_ft != NUL
+		    && STRLEN(wp->w_buffer->b_p_ft) < TMPLEN - 2)
+	    {
+		vim_snprintf((char *)tmp, sizeof(tmp), ",%s",
+							wp->w_buffer->b_p_ft);
+		for (t = tmp; *t != 0; t++)
+		    *t = TOUPPER_LOC(*t);
+		str = tmp;
+	    }
+	    break;
+#endif
+
+#if defined(FEAT_WINDOWS) && defined(FEAT_QUICKFIX)
+	case STL_PREVIEWFLAG:
+	case STL_PREVIEWFLAG_ALT:
+	    itemisflag = TRUE;
+	    if (wp->w_p_pvw)
+		str = (char_u *)((opt == STL_PREVIEWFLAG_ALT) ? ",PRV"
+							    : _("[Preview]"));
+	    break;
+#endif
+
+	case STL_MODIFIED:
+	case STL_MODIFIED_ALT:
+	    itemisflag = TRUE;
+	    switch ((opt == STL_MODIFIED_ALT)
+		    + bufIsChanged(wp->w_buffer) * 2
+		    + (!wp->w_buffer->b_p_ma) * 4)
+	    {
+		case 2: str = (char_u *)"[+]"; break;
+		case 3: str = (char_u *)",+"; break;
+		case 4: str = (char_u *)"[-]"; break;
+		case 5: str = (char_u *)",-"; break;
+		case 6: str = (char_u *)"[+-]"; break;
+		case 7: str = (char_u *)",+-"; break;
+	    }
+	    break;
+
+	case STL_HIGHLIGHT:
+	    t = s;
+	    while (*s != '#' && *s != NUL)
+		++s;
+	    if (*s == '#')
+	    {
+		item[curitem].type = Highlight;
+		item[curitem].start = p;
+		item[curitem].minwid = -syn_namen2id(t, (int)(s - t));
+		curitem++;
+	    }
+	    ++s;
+	    continue;
+	}
+
+	item[curitem].start = p;
+	item[curitem].type = Normal;
+	if (str != NULL && *str)
+	{
+	    t = str;
+	    if (itemisflag)
+	    {
+		if ((t[0] && t[1])
+			&& ((!prevchar_isitem && *t == ',')
+			      || (prevchar_isflag && *t == ' ')))
+		    t++;
+		prevchar_isflag = TRUE;
+	    }
+	    l = vim_strsize(t);
+	    if (l > 0)
+		prevchar_isitem = TRUE;
+	    if (l > maxwid)
+	    {
+		while (l >= maxwid)
+#ifdef FEAT_MBYTE
+		    if (has_mbyte)
+		    {
+			l -= ptr2cells(t);
+			t += (*mb_ptr2len)(t);
+		    }
+		    else
+#endif
+			l -= byte2cells(*t++);
+		if (p + 1 >= out + outlen)
+		    break;
+		*p++ = '<';
+	    }
+	    if (minwid > 0)
+	    {
+		for (; l < minwid && p + 1 < out + outlen; l++)
+		{
+		    /* Don't put a "-" in front of a digit. */
+		    if (l + 1 == minwid && fillchar == '-' && VIM_ISDIGIT(*t))
+			*p++ = ' ';
+		    else
+			*p++ = fillchar;
+		}
+		minwid = 0;
+	    }
+	    else
+		minwid *= -1;
+	    while (*t && p + 1 < out + outlen)
+	    {
+		*p++ = *t++;
+		/* Change a space by fillchar, unless fillchar is '-' and a
+		 * digit follows. */
+		if (fillable && p[-1] == ' '
+				     && (!VIM_ISDIGIT(*t) || fillchar != '-'))
+		    p[-1] = fillchar;
+	    }
+	    for (; l < minwid && p + 1 < out + outlen; l++)
+		*p++ = fillchar;
+	}
+	else if (num >= 0)
+	{
+	    int nbase = (base == 'D' ? 10 : (base == 'O' ? 8 : 16));
+	    char_u nstr[20];
+
+	    if (p + 20 >= out + outlen)
+		break;		/* not sufficient space */
+	    prevchar_isitem = TRUE;
+	    t = nstr;
+	    if (opt == STL_VIRTCOL_ALT)
+	    {
+		*t++ = '-';
+		minwid--;
+	    }
+	    *t++ = '%';
+	    if (zeropad)
+		*t++ = '0';
+	    *t++ = '*';
+	    *t++ = nbase == 16 ? base : (nbase == 8 ? 'o' : 'd');
+	    *t = 0;
+
+	    for (n = num, l = 1; n >= nbase; n /= nbase)
+		l++;
+	    if (opt == STL_VIRTCOL_ALT)
+		l++;
+	    if (l > maxwid)
+	    {
+		l += 2;
+		n = l - maxwid;
+		while (l-- > maxwid)
+		    num /= nbase;
+		*t++ = '>';
+		*t++ = '%';
+		*t = t[-3];
+		*++t = 0;
+		vim_snprintf((char *)p, outlen - (p - out), (char *)nstr,
+								   0, num, n);
+	    }
+	    else
+		vim_snprintf((char *)p, outlen - (p - out), (char *)nstr,
+								 minwid, num);
+	    p += STRLEN(p);
+	}
+	else
+	    item[curitem].type = Empty;
+
+	if (opt == STL_VIM_EXPR)
+	    vim_free(str);
+
+	if (num >= 0 || (!itemisflag && str && *str))
+	    prevchar_isflag = FALSE;	    /* Item not NULL, but not a flag */
+	curitem++;
+    }
+    *p = NUL;
+    itemcnt = curitem;
+
+#ifdef FEAT_EVAL
+    if (usefmt != fmt)
+	vim_free(usefmt);
+#endif
+
+    width = vim_strsize(out);
+    if (maxwidth > 0 && width > maxwidth)
+    {
+	/* Result is too long, must trunctate somewhere. */
+	l = 0;
+	if (itemcnt == 0)
+	    s = out;
+	else
+	{
+	    for ( ; l < itemcnt; l++)
+		if (item[l].type == Trunc)
+		{
+		    /* Truncate at %< item. */
+		    s = item[l].start;
+		    break;
+		}
+	    if (l == itemcnt)
+	    {
+		/* No %< item, truncate first item. */
+		s = item[0].start;
+		l = 0;
+	    }
+	}
+
+	if (width - vim_strsize(s) >= maxwidth)
+	{
+	    /* Truncation mark is beyond max length */
+#ifdef FEAT_MBYTE
+	    if (has_mbyte)
+	    {
+		s = out;
+		width = 0;
+		for (;;)
+		{
+		    width += ptr2cells(s);
+		    if (width >= maxwidth)
+			break;
+		    s += (*mb_ptr2len)(s);
+		}
+		/* Fill up for half a double-wide character. */
+		while (++width < maxwidth)
+		    *s++ = fillchar;
+	    }
+	    else
+#endif
+		s = out + maxwidth - 1;
+	    for (l = 0; l < itemcnt; l++)
+		if (item[l].start > s)
+		    break;
+	    itemcnt = l;
+	    *s++ = '>';
+	    *s = 0;
+	}
+	else
+	{
+#ifdef FEAT_MBYTE
+	    if (has_mbyte)
+	    {
+		n = 0;
+		while (width >= maxwidth)
+		{
+		    width -= ptr2cells(s + n);
+		    n += (*mb_ptr2len)(s + n);
+		}
+	    }
+	    else
+#endif
+		n = width - maxwidth + 1;
+	    p = s + n;
+	    mch_memmove(s + 1, p, STRLEN(p) + 1);
+	    *s = '<';
+
+	    /* Fill up for half a double-wide character. */
+	    while (++width < maxwidth)
+	    {
+		s = s + STRLEN(s);
+		*s++ = fillchar;
+		*s = NUL;
+	    }
+
+	    --n;	/* count the '<' */
+	    for (; l < itemcnt; l++)
+	    {
+		if (item[l].start - n >= s)
+		    item[l].start -= n;
+		else
+		    item[l].start = s;
+	    }
+	}
+	width = maxwidth;
+    }
+    else if (width < maxwidth && STRLEN(out) + maxwidth - width + 1 < outlen)
+    {
+	/* Apply STL_MIDDLE if any */
+	for (l = 0; l < itemcnt; l++)
+	    if (item[l].type == Middle)
+		break;
+	if (l < itemcnt)
+	{
+	    p = item[l].start + maxwidth - width;
+	    mch_memmove(p, item[l].start, STRLEN(item[l].start) + 1);
+	    for (s = item[l].start; s < p; s++)
+		*s = fillchar;
+	    for (l++; l < itemcnt; l++)
+		item[l].start += maxwidth - width;
+	    width = maxwidth;
+	}
+    }
+
+    /* Store the info about highlighting. */
+    if (hltab != NULL)
+    {
+	sp = hltab;
+	for (l = 0; l < itemcnt; l++)
+	{
+	    if (item[l].type == Highlight)
+	    {
+		sp->start = item[l].start;
+		sp->userhl = item[l].minwid;
+		sp++;
+	    }
+	}
+	sp->start = NULL;
+	sp->userhl = 0;
+    }
+
+    /* Store the info about tab pages labels. */
+    if (tabtab != NULL)
+    {
+	sp = tabtab;
+	for (l = 0; l < itemcnt; l++)
+	{
+	    if (item[l].type == TabPage)
+	    {
+		sp->start = item[l].start;
+		sp->userhl = item[l].minwid;
+		sp++;
+	    }
+	}
+	sp->start = NULL;
+	sp->userhl = 0;
+    }
+
+    return width;
+}
+#endif /* FEAT_STL_OPT */
+
+#if defined(FEAT_STL_OPT) || defined(FEAT_CMDL_INFO) \
+	    || defined(FEAT_GUI_TABLINE) || defined(PROTO)
+/*
+ * Get relative cursor position in window into "str[]", in the form 99%, using
+ * "Top", "Bot" or "All" when appropriate.
+ */
+    void
+get_rel_pos(wp, str)
+    win_T	*wp;
+    char_u	*str;
+{
+    long	above; /* number of lines above window */
+    long	below; /* number of lines below window */
+
+    above = wp->w_topline - 1;
+#ifdef FEAT_DIFF
+    above += diff_check_fill(wp, wp->w_topline) - wp->w_topfill;
+#endif
+    below = wp->w_buffer->b_ml.ml_line_count - wp->w_botline + 1;
+    if (below <= 0)
+	STRCPY(str, above == 0 ? _("All") : _("Bot"));
+    else if (above <= 0)
+	STRCPY(str, _("Top"));
+    else
+	sprintf((char *)str, "%2d%%", above > 1000000L
+				    ? (int)(above / ((above + below) / 100L))
+				    : (int)(above * 100L / (above + below)));
+}
+#endif
+
+/*
+ * Append (file 2 of 8) to 'buf', if editing more than one file.
+ * Return TRUE if it was appended.
+ */
+    int
+append_arg_number(wp, buf, add_file, maxlen)
+    win_T	*wp;
+    char_u	*buf;
+    int		add_file;	/* Add "file" before the arg number */
+    int		maxlen;		/* maximum nr of chars in buf or zero*/
+{
+    char_u	*p;
+
+    if (ARGCOUNT <= 1)		/* nothing to do */
+	return FALSE;
+
+    p = buf + STRLEN(buf);		/* go to the end of the buffer */
+    if (maxlen && p - buf + 35 >= maxlen) /* getting too long */
+	return FALSE;
+    *p++ = ' ';
+    *p++ = '(';
+    if (add_file)
+    {
+	STRCPY(p, "file ");
+	p += 5;
+    }
+    sprintf((char *)p, wp->w_arg_idx_invalid ? "(%d) of %d)"
+				  : "%d of %d)", wp->w_arg_idx + 1, ARGCOUNT);
+    return TRUE;
+}
+
+/*
+ * If fname is not a full path, make it a full path.
+ * Returns pointer to allocated memory (NULL for failure).
+ */
+    char_u  *
+fix_fname(fname)
+    char_u  *fname;
+{
+    /*
+     * Force expanding the path always for Unix, because symbolic links may
+     * mess up the full path name, even though it starts with a '/'.
+     * Also expand when there is ".." in the file name, try to remove it,
+     * because "c:/src/../README" is equal to "c:/README".
+     * For MS-Windows also expand names like "longna~1" to "longname".
+     */
+#ifdef UNIX
+    return FullName_save(fname, TRUE);
+#else
+    if (!vim_isAbsName(fname) || strstr((char *)fname, "..") != NULL
+#if defined(MSWIN) || defined(DJGPP)
+	    || vim_strchr(fname, '~') != NULL
+#endif
+	    )
+	return FullName_save(fname, FALSE);
+
+    fname = vim_strsave(fname);
+
+#ifdef USE_FNAME_CASE
+# ifdef USE_LONG_FNAME
+    if (USE_LONG_FNAME)
+# endif
+    {
+	if (fname != NULL)
+	    fname_case(fname, 0);	/* set correct case for file name */
+    }
+#endif
+
+    return fname;
+#endif
+}
+
+/*
+ * Make "ffname" a full file name, set "sfname" to "ffname" if not NULL.
+ * "ffname" becomes a pointer to allocated memory (or NULL).
+ */
+/*ARGSUSED*/
+    void
+fname_expand(buf, ffname, sfname)
+    buf_T	*buf;
+    char_u	**ffname;
+    char_u	**sfname;
+{
+    if (*ffname == NULL)	/* if no file name given, nothing to do */
+	return;
+    if (*sfname == NULL)	/* if no short file name given, use ffname */
+	*sfname = *ffname;
+    *ffname = fix_fname(*ffname);   /* expand to full path */
+
+#ifdef FEAT_SHORTCUT
+    if (!buf->b_p_bin)
+    {
+	char_u  *rfname;
+
+	/* If the file name is a shortcut file, use the file it links to. */
+	rfname = mch_resolve_shortcut(*ffname);
+	if (rfname != NULL)
+	{
+	    vim_free(*ffname);
+	    *ffname = rfname;
+	    *sfname = rfname;
+	}
+    }
+#endif
+}
+
+/*
+ * Get the file name for an argument list entry.
+ */
+    char_u *
+alist_name(aep)
+    aentry_T	*aep;
+{
+    buf_T	*bp;
+
+    /* Use the name from the associated buffer if it exists. */
+    bp = buflist_findnr(aep->ae_fnum);
+    if (bp == NULL || bp->b_fname == NULL)
+	return aep->ae_fname;
+    return bp->b_fname;
+}
+
+#if defined(FEAT_WINDOWS) || defined(PROTO)
+/*
+ * do_arg_all(): Open up to 'count' windows, one for each argument.
+ */
+    void
+do_arg_all(count, forceit, keep_tabs)
+    int	count;
+    int	forceit;		/* hide buffers in current windows */
+    int keep_tabs;		/* keep curren tabs, for ":tab drop file" */
+{
+    int		i;
+    win_T	*wp, *wpnext;
+    char_u	*opened;	/* array of flags for which args are open */
+    int		opened_len;	/* lenght of opened[] */
+    int		use_firstwin = FALSE;	/* use first window for arglist */
+    int		split_ret = OK;
+    int		p_ea_save;
+    alist_T	*alist;		/* argument list to be used */
+    buf_T	*buf;
+    tabpage_T	*tpnext;
+    int		had_tab = cmdmod.tab;
+    win_T	*new_curwin = NULL;
+    tabpage_T	*new_curtab = NULL;
+
+    if (ARGCOUNT <= 0)
+    {
+	/* Don't give an error message.  We don't want it when the ":all"
+	 * command is in the .vimrc. */
+	return;
+    }
+    setpcmark();
+
+    opened_len = ARGCOUNT;
+    opened = alloc_clear((unsigned)opened_len);
+    if (opened == NULL)
+	return;
+
+#ifdef FEAT_GUI
+    need_mouse_correct = TRUE;
+#endif
+
+    /*
+     * Try closing all windows that are not in the argument list.
+     * Also close windows that are not full width;
+     * When 'hidden' or "forceit" set the buffer becomes hidden.
+     * Windows that have a changed buffer and can't be hidden won't be closed.
+     * When the ":tab" modifier was used do this for all tab pages.
+     */
+    if (had_tab > 0)
+	goto_tabpage_tp(first_tabpage);
+    for (;;)
+    {
+	tpnext = curtab->tp_next;
+	for (wp = firstwin; wp != NULL; wp = wpnext)
+	{
+	    wpnext = wp->w_next;
+	    buf = wp->w_buffer;
+	    if (buf->b_ffname == NULL
+		    || buf->b_nwindows > 1
+#ifdef FEAT_VERTSPLIT
+		    || wp->w_width != Columns
+#endif
+		    )
+		i = ARGCOUNT;
+	    else
+	    {
+		/* check if the buffer in this window is in the arglist */
+		for (i = 0; i < ARGCOUNT; ++i)
+		{
+		    if (ARGLIST[i].ae_fnum == buf->b_fnum
+			    || fullpathcmp(alist_name(&ARGLIST[i]),
+					      buf->b_ffname, TRUE) & FPC_SAME)
+		    {
+			if (i < opened_len)
+			{
+			    opened[i] = TRUE;
+			    if (i == 0)
+			    {
+				new_curwin = wp;
+				new_curtab = curtab;
+			    }
+			}
+			if (wp->w_alist != curwin->w_alist)
+			{
+			    /* Use the current argument list for all windows
+			     * containing a file from it. */
+			    alist_unlink(wp->w_alist);
+			    wp->w_alist = curwin->w_alist;
+			    ++wp->w_alist->al_refcount;
+			}
+			break;
+		    }
+		}
+	    }
+	    wp->w_arg_idx = i;
+
+	    if (i == ARGCOUNT && !keep_tabs)	/* close this window */
+	    {
+		if (P_HID(buf) || forceit || buf->b_nwindows > 1
+							|| !bufIsChanged(buf))
+		{
+		    /* If the buffer was changed, and we would like to hide it,
+		     * try autowriting. */
+		    if (!P_HID(buf) && buf->b_nwindows <= 1
+							 && bufIsChanged(buf))
+		    {
+			(void)autowrite(buf, FALSE);
+#ifdef FEAT_AUTOCMD
+			/* check if autocommands removed the window */
+			if (!win_valid(wp) || !buf_valid(buf))
+			{
+			    wpnext = firstwin;	/* start all over... */
+			    continue;
+			}
+#endif
+		    }
+#ifdef FEAT_WINDOWS
+		    /* don't close last window */
+		    if (firstwin == lastwin && first_tabpage->tp_next == NULL)
+#endif
+			use_firstwin = TRUE;
+#ifdef FEAT_WINDOWS
+		    else
+		    {
+			win_close(wp, !P_HID(buf) && !bufIsChanged(buf));
+# ifdef FEAT_AUTOCMD
+			/* check if autocommands removed the next window */
+			if (!win_valid(wpnext))
+			    wpnext = firstwin;	/* start all over... */
+# endif
+		    }
+#endif
+		}
+	    }
+	}
+
+	/* Without the ":tab" modifier only do the current tab page. */
+	if (had_tab == 0 || tpnext == NULL)
+	    break;
+
+# ifdef FEAT_AUTOCMD
+	/* check if autocommands removed the next tab page */
+	if (!valid_tabpage(tpnext))
+	    tpnext = first_tabpage;	/* start all over...*/
+# endif
+	goto_tabpage_tp(tpnext);
+    }
+
+    /*
+     * Open a window for files in the argument list that don't have one.
+     * ARGCOUNT may change while doing this, because of autocommands.
+     */
+    if (count > ARGCOUNT || count <= 0)
+	count = ARGCOUNT;
+
+    /* Autocommands may do anything to the argument list.  Make sure it's not
+     * freed while we are working here by "locking" it.  We still have to
+     * watch out for its size to be changed. */
+    alist = curwin->w_alist;
+    ++alist->al_refcount;
+
+#ifdef FEAT_AUTOCMD
+    /* Don't execute Win/Buf Enter/Leave autocommands here. */
+    ++autocmd_no_enter;
+    ++autocmd_no_leave;
+#endif
+    win_enter(lastwin, FALSE);
+#ifdef FEAT_WINDOWS
+    /* ":drop all" should re-use an empty window to avoid "--remote-tab"
+     * leaving an empty tab page when executed locally. */
+    if (keep_tabs && bufempty() && curbuf->b_nwindows == 1
+			    && curbuf->b_ffname == NULL && !curbuf->b_changed)
+	use_firstwin = TRUE;
+#endif
+
+    for (i = 0; i < count && i < alist->al_ga.ga_len && !got_int; ++i)
+    {
+	if (alist == &global_alist && i == global_alist.al_ga.ga_len - 1)
+	    arg_had_last = TRUE;
+	if (i < opened_len && opened[i])
+	{
+	    /* Move the already present window to below the current window */
+	    if (curwin->w_arg_idx != i)
+	    {
+		for (wpnext = firstwin; wpnext != NULL; wpnext = wpnext->w_next)
+		{
+		    if (wpnext->w_arg_idx == i)
+		    {
+			win_move_after(wpnext, curwin);
+			break;
+		    }
+		}
+	    }
+	}
+	else if (split_ret == OK)
+	{
+	    if (!use_firstwin)		/* split current window */
+	    {
+		p_ea_save = p_ea;
+		p_ea = TRUE;		/* use space from all windows */
+		split_ret = win_split(0, WSP_ROOM | WSP_BELOW);
+		p_ea = p_ea_save;
+		if (split_ret == FAIL)
+		    continue;
+	    }
+#ifdef FEAT_AUTOCMD
+	    else    /* first window: do autocmd for leaving this buffer */
+		--autocmd_no_leave;
+#endif
+
+	    /*
+	     * edit file "i"
+	     */
+	    curwin->w_arg_idx = i;
+	    if (i == 0)
+	    {
+		new_curwin = curwin;
+		new_curtab = curtab;
+	    }
+	    (void)do_ecmd(0, alist_name(&AARGLIST(alist)[i]), NULL, NULL,
+		      ECMD_ONE,
+		      ((P_HID(curwin->w_buffer)
+			   || bufIsChanged(curwin->w_buffer)) ? ECMD_HIDE : 0)
+							       + ECMD_OLDBUF);
+#ifdef FEAT_AUTOCMD
+	    if (use_firstwin)
+		++autocmd_no_leave;
+#endif
+	    use_firstwin = FALSE;
+	}
+	ui_breakcheck();
+
+	/* When ":tab" was used open a new tab for a new window repeatedly. */
+	if (had_tab > 0 && tabpage_index(NULL) <= p_tpm)
+	    cmdmod.tab = 9999;
+    }
+
+    /* Remove the "lock" on the argument list. */
+    alist_unlink(alist);
+
+#ifdef FEAT_AUTOCMD
+    --autocmd_no_enter;
+#endif
+    /* to window with first arg */
+    if (valid_tabpage(new_curtab))
+	goto_tabpage_tp(new_curtab);
+    if (win_valid(new_curwin))
+	win_enter(new_curwin, FALSE);
+
+#ifdef FEAT_AUTOCMD
+    --autocmd_no_leave;
+#endif
+    vim_free(opened);
+}
+
+# if defined(FEAT_LISTCMDS) || defined(PROTO)
+/*
+ * Open a window for a number of buffers.
+ */
+    void
+ex_buffer_all(eap)
+    exarg_T	*eap;
+{
+    buf_T	*buf;
+    win_T	*wp, *wpnext;
+    int		split_ret = OK;
+    int		p_ea_save;
+    int		open_wins = 0;
+    int		r;
+    int		count;		/* Maximum number of windows to open. */
+    int		all;		/* When TRUE also load inactive buffers. */
+#ifdef FEAT_WINDOWS
+    int		had_tab = cmdmod.tab;
+    tabpage_T	*tpnext;
+#endif
+
+    if (eap->addr_count == 0)	/* make as many windows as possible */
+	count = 9999;
+    else
+	count = eap->line2;	/* make as many windows as specified */
+    if (eap->cmdidx == CMD_unhide || eap->cmdidx == CMD_sunhide)
+	all = FALSE;
+    else
+	all = TRUE;
+
+    setpcmark();
+
+#ifdef FEAT_GUI
+    need_mouse_correct = TRUE;
+#endif
+
+    /*
+     * Close superfluous windows (two windows for the same buffer).
+     * Also close windows that are not full-width.
+     */
+#ifdef FEAT_WINDOWS
+    if (had_tab > 0)
+	goto_tabpage_tp(first_tabpage);
+    for (;;)
+    {
+#endif
+	tpnext = curtab->tp_next;
+	for (wp = firstwin; wp != NULL; wp = wpnext)
+	{
+	    wpnext = wp->w_next;
+	    if ((wp->w_buffer->b_nwindows > 1
+#ifdef FEAT_VERTSPLIT
+		    || ((cmdmod.split & WSP_VERT)
+			? wp->w_height + wp->w_status_height < Rows - p_ch
+							    - tabline_height()
+			: wp->w_width != Columns)
+#endif
+#ifdef FEAT_WINDOWS
+		    || (had_tab > 0 && wp != firstwin)
+#endif
+		    ) && firstwin != lastwin)
+	    {
+		win_close(wp, FALSE);
+#ifdef FEAT_AUTOCMD
+		wpnext = firstwin;	/* just in case an autocommand does
+					   something strange with windows */
+		tpnext = first_tabpage;	/* start all over...*/
+		open_wins = 0;
+#endif
+	    }
+	    else
+		++open_wins;
+	}
+
+#ifdef FEAT_WINDOWS
+	/* Without the ":tab" modifier only do the current tab page. */
+	if (had_tab == 0 || tpnext == NULL)
+	    break;
+	goto_tabpage_tp(tpnext);
+    }
+#endif
+
+    /*
+     * Go through the buffer list.  When a buffer doesn't have a window yet,
+     * open one.  Otherwise move the window to the right position.
+     * Watch out for autocommands that delete buffers or windows!
+     */
+#ifdef FEAT_AUTOCMD
+    /* Don't execute Win/Buf Enter/Leave autocommands here. */
+    ++autocmd_no_enter;
+#endif
+    win_enter(lastwin, FALSE);
+#ifdef FEAT_AUTOCMD
+    ++autocmd_no_leave;
+#endif
+    for (buf = firstbuf; buf != NULL && open_wins < count; buf = buf->b_next)
+    {
+	/* Check if this buffer needs a window */
+	if ((!all && buf->b_ml.ml_mfp == NULL) || !buf->b_p_bl)
+	    continue;
+
+#ifdef FEAT_WINDOWS
+	if (had_tab != 0)
+	{
+	    /* With the ":tab" modifier don't move the window. */
+	    if (buf->b_nwindows > 0)
+		wp = lastwin;	    /* buffer has a window, skip it */
+	    else
+		wp = NULL;
+	}
+	else
+#endif
+	{
+	    /* Check if this buffer already has a window */
+	    for (wp = firstwin; wp != NULL; wp = wp->w_next)
+		if (wp->w_buffer == buf)
+		    break;
+	    /* If the buffer already has a window, move it */
+	    if (wp != NULL)
+		win_move_after(wp, curwin);
+	}
+
+	if (wp == NULL && split_ret == OK)
+	{
+	    /* Split the window and put the buffer in it */
+	    p_ea_save = p_ea;
+	    p_ea = TRUE;		/* use space from all windows */
+	    split_ret = win_split(0, WSP_ROOM | WSP_BELOW);
+	    ++open_wins;
+	    p_ea = p_ea_save;
+	    if (split_ret == FAIL)
+		continue;
+
+	    /* Open the buffer in this window. */
+#if defined(HAS_SWAP_EXISTS_ACTION)
+	    swap_exists_action = SEA_DIALOG;
+#endif
+	    set_curbuf(buf, DOBUF_GOTO);
+#ifdef FEAT_AUTOCMD
+	    if (!buf_valid(buf))	/* autocommands deleted the buffer!!! */
+	    {
+#if defined(HAS_SWAP_EXISTS_ACTION)
+		swap_exists_action = SEA_NONE;
+# endif
+		break;
+	    }
+#endif
+#if defined(HAS_SWAP_EXISTS_ACTION)
+	    if (swap_exists_action == SEA_QUIT)
+	    {
+# if defined(FEAT_AUTOCMD) && defined(FEAT_EVAL)
+		cleanup_T   cs;
+
+		/* Reset the error/interrupt/exception state here so that
+		 * aborting() returns FALSE when closing a window. */
+		enter_cleanup(&cs);
+# endif
+
+		/* User selected Quit at ATTENTION prompt; close this window. */
+		win_close(curwin, TRUE);
+		--open_wins;
+		swap_exists_action = SEA_NONE;
+		swap_exists_did_quit = TRUE;
+
+# if defined(FEAT_AUTOCMD) && defined(FEAT_EVAL)
+		/* Restore the error/interrupt/exception state if not
+		 * discarded by a new aborting error, interrupt, or uncaught
+		 * exception. */
+		leave_cleanup(&cs);
+# endif
+	    }
+	    else
+		handle_swap_exists(NULL);
+#endif
+	}
+
+	ui_breakcheck();
+	if (got_int)
+	{
+	    (void)vgetc();	/* only break the file loading, not the rest */
+	    break;
+	}
+#ifdef FEAT_EVAL
+	/* Autocommands deleted the buffer or aborted script processing!!! */
+	if (aborting())
+	    break;
+#endif
+#ifdef FEAT_WINDOWS
+	/* When ":tab" was used open a new tab for a new window repeatedly. */
+	if (had_tab > 0 && tabpage_index(NULL) <= p_tpm)
+	    cmdmod.tab = 9999;
+#endif
+    }
+#ifdef FEAT_AUTOCMD
+    --autocmd_no_enter;
+#endif
+    win_enter(firstwin, FALSE);		/* back to first window */
+#ifdef FEAT_AUTOCMD
+    --autocmd_no_leave;
+#endif
+
+    /*
+     * Close superfluous windows.
+     */
+    for (wp = lastwin; open_wins > count; )
+    {
+	r = (P_HID(wp->w_buffer) || !bufIsChanged(wp->w_buffer)
+				     || autowrite(wp->w_buffer, FALSE) == OK);
+#ifdef FEAT_AUTOCMD
+	if (!win_valid(wp))
+	{
+	    /* BufWrite Autocommands made the window invalid, start over */
+	    wp = lastwin;
+	}
+	else
+#endif
+	    if (r)
+	{
+	    win_close(wp, !P_HID(wp->w_buffer));
+	    --open_wins;
+	    wp = lastwin;
+	}
+	else
+	{
+	    wp = wp->w_prev;
+	    if (wp == NULL)
+		break;
+	}
+    }
+}
+# endif /* FEAT_LISTCMDS */
+
+#endif /* FEAT_WINDOWS */
+
+static int  chk_modeline __ARGS((linenr_T, int));
+
+/*
+ * do_modelines() - process mode lines for the current file
+ *
+ * "flags" can be:
+ * OPT_WINONLY	    only set options local to window
+ * OPT_NOWIN	    don't set options local to window
+ *
+ * Returns immediately if the "ml" option isn't set.
+ */
+    void
+do_modelines(flags)
+    int		flags;
+{
+    linenr_T	lnum;
+    int		nmlines;
+    static int	entered = 0;
+
+    if (!curbuf->b_p_ml || (nmlines = (int)p_mls) == 0)
+	return;
+
+    /* Disallow recursive entry here.  Can happen when executing a modeline
+     * triggers an autocommand, which reloads modelines with a ":do". */
+    if (entered)
+	return;
+
+    ++entered;
+    for (lnum = 1; lnum <= curbuf->b_ml.ml_line_count && lnum <= nmlines;
+								       ++lnum)
+	if (chk_modeline(lnum, flags) == FAIL)
+	    nmlines = 0;
+
+    for (lnum = curbuf->b_ml.ml_line_count; lnum > 0 && lnum > nmlines
+		       && lnum > curbuf->b_ml.ml_line_count - nmlines; --lnum)
+	if (chk_modeline(lnum, flags) == FAIL)
+	    nmlines = 0;
+    --entered;
+}
+
+#include "version.h"		/* for version number */
+
+/*
+ * chk_modeline() - check a single line for a mode string
+ * Return FAIL if an error encountered.
+ */
+    static int
+chk_modeline(lnum, flags)
+    linenr_T	lnum;
+    int		flags;		/* Same as for do_modelines(). */
+{
+    char_u	*s;
+    char_u	*e;
+    char_u	*linecopy;		/* local copy of any modeline found */
+    int		prev;
+    int		vers;
+    int		end;
+    int		retval = OK;
+    char_u	*save_sourcing_name;
+    linenr_T	save_sourcing_lnum;
+#ifdef FEAT_EVAL
+    scid_T	save_SID;
+#endif
+
+    prev = -1;
+    for (s = ml_get(lnum); *s != NUL; ++s)
+    {
+	if (prev == -1 || vim_isspace(prev))
+	{
+	    if ((prev != -1 && STRNCMP(s, "ex:", (size_t)3) == 0)
+		    || STRNCMP(s, "vi:", (size_t)3) == 0)
+		break;
+	    if (STRNCMP(s, "vim", 3) == 0)
+	    {
+		if (s[3] == '<' || s[3] == '=' || s[3] == '>')
+		    e = s + 4;
+		else
+		    e = s + 3;
+		vers = getdigits(&e);
+		if (*e == ':'
+			&& (s[3] == ':'
+			    || (VIM_VERSION_100 >= vers && isdigit(s[3]))
+			    || (VIM_VERSION_100 < vers && s[3] == '<')
+			    || (VIM_VERSION_100 > vers && s[3] == '>')
+			    || (VIM_VERSION_100 == vers && s[3] == '=')))
+		    break;
+	    }
+	}
+	prev = *s;
+    }
+
+    if (*s)
+    {
+	do				/* skip over "ex:", "vi:" or "vim:" */
+	    ++s;
+	while (s[-1] != ':');
+
+	s = linecopy = vim_strsave(s);	/* copy the line, it will change */
+	if (linecopy == NULL)
+	    return FAIL;
+
+	save_sourcing_lnum = sourcing_lnum;
+	save_sourcing_name = sourcing_name;
+	sourcing_lnum = lnum;		/* prepare for emsg() */
+	sourcing_name = (char_u *)"modelines";
+
+	end = FALSE;
+	while (end == FALSE)
+	{
+	    s = skipwhite(s);
+	    if (*s == NUL)
+		break;
+
+	    /*
+	     * Find end of set command: ':' or end of line.
+	     * Skip over "\:", replacing it with ":".
+	     */
+	    for (e = s; *e != ':' && *e != NUL; ++e)
+		if (e[0] == '\\' && e[1] == ':')
+		    STRCPY(e, e + 1);
+	    if (*e == NUL)
+		end = TRUE;
+
+	    /*
+	     * If there is a "set" command, require a terminating ':' and
+	     * ignore the stuff after the ':'.
+	     * "vi:set opt opt opt: foo" -- foo not interpreted
+	     * "vi:opt opt opt: foo" -- foo interpreted
+	     * Accept "se" for compatibility with Elvis.
+	     */
+	    if (STRNCMP(s, "set ", (size_t)4) == 0
+		    || STRNCMP(s, "se ", (size_t)3) == 0)
+	    {
+		if (*e != ':')		/* no terminating ':'? */
+		    break;
+		end = TRUE;
+		s = vim_strchr(s, ' ') + 1;
+	    }
+	    *e = NUL;			/* truncate the set command */
+
+	    if (*s != NUL)		/* skip over an empty "::" */
+	    {
+#ifdef FEAT_EVAL
+		save_SID = current_SID;
+		current_SID = SID_MODELINE;
+#endif
+		retval = do_set(s, OPT_MODELINE | OPT_LOCAL | flags);
+#ifdef FEAT_EVAL
+		current_SID = save_SID;
+#endif
+		if (retval == FAIL)		/* stop if error found */
+		    break;
+	    }
+	    s = e + 1;			/* advance to next part */
+	}
+
+	sourcing_lnum = save_sourcing_lnum;
+	sourcing_name = save_sourcing_name;
+
+	vim_free(linecopy);
+    }
+    return retval;
+}
+
+#ifdef FEAT_VIMINFO
+    int
+read_viminfo_bufferlist(virp, writing)
+    vir_T	*virp;
+    int		writing;
+{
+    char_u	*tab;
+    linenr_T	lnum;
+    colnr_T	col;
+    buf_T	*buf;
+    char_u	*sfname;
+    char_u	*xline;
+
+    /* Handle long line and escaped characters. */
+    xline = viminfo_readstring(virp, 1, FALSE);
+
+    /* don't read in if there are files on the command-line or if writing: */
+    if (xline != NULL && !writing && ARGCOUNT == 0
+				       && find_viminfo_parameter('%') != NULL)
+    {
+	/* Format is: <fname> Tab <lnum> Tab <col>.
+	 * Watch out for a Tab in the file name, work from the end. */
+	lnum = 0;
+	col = 0;
+	tab = vim_strrchr(xline, '\t');
+	if (tab != NULL)
+	{
+	    *tab++ = '\0';
+	    col = atoi((char *)tab);
+	    tab = vim_strrchr(xline, '\t');
+	    if (tab != NULL)
+	    {
+		*tab++ = '\0';
+		lnum = atol((char *)tab);
+	    }
+	}
+
+	/* Expand "~/" in the file name at "line + 1" to a full path.
+	 * Then try shortening it by comparing with the current directory */
+	expand_env(xline, NameBuff, MAXPATHL);
+	mch_dirname(IObuff, IOSIZE);
+	sfname = shorten_fname(NameBuff, IObuff);
+	if (sfname == NULL)
+	    sfname = NameBuff;
+
+	buf = buflist_new(NameBuff, sfname, (linenr_T)0, BLN_LISTED);
+	if (buf != NULL)	/* just in case... */
+	{
+	    buf->b_last_cursor.lnum = lnum;
+	    buf->b_last_cursor.col = col;
+	    buflist_setfpos(buf, curwin, lnum, col, FALSE);
+	}
+    }
+    vim_free(xline);
+
+    return viminfo_readline(virp);
+}
+
+    void
+write_viminfo_bufferlist(fp)
+    FILE    *fp;
+{
+    buf_T	*buf;
+#ifdef FEAT_WINDOWS
+    win_T	*win;
+    tabpage_T	*tp;
+#endif
+    char_u	*line;
+    int		max_buffers;
+
+    if (find_viminfo_parameter('%') == NULL)
+	return;
+
+    /* Without a number -1 is returned: do all buffers. */
+    max_buffers = get_viminfo_parameter('%');
+
+    /* Allocate room for the file name, lnum and col. */
+    line = alloc(MAXPATHL + 40);
+    if (line == NULL)
+	return;
+
+#ifdef FEAT_WINDOWS
+    FOR_ALL_TAB_WINDOWS(tp, win)
+	set_last_cursor(win);
+#else
+    set_last_cursor(curwin);
+#endif
+
+    fprintf(fp, _("\n# Buffer list:\n"));
+    for (buf = firstbuf; buf != NULL ; buf = buf->b_next)
+    {
+	if (buf->b_fname == NULL
+		|| !buf->b_p_bl
+#ifdef FEAT_QUICKFIX
+		|| bt_quickfix(buf)
+#endif
+		|| removable(buf->b_ffname))
+	    continue;
+
+	if (max_buffers-- == 0)
+	    break;
+	putc('%', fp);
+	home_replace(NULL, buf->b_ffname, line, MAXPATHL, TRUE);
+	sprintf((char *)line + STRLEN(line), "\t%ld\t%d",
+			(long)buf->b_last_cursor.lnum,
+			buf->b_last_cursor.col);
+	viminfo_writestring(fp, line);
+    }
+    vim_free(line);
+}
+#endif
+
+
+/*
+ * Return special buffer name.
+ * Returns NULL when the buffer has a normal file name.
+ */
+    char *
+buf_spname(buf)
+    buf_T	*buf;
+{
+#if defined(FEAT_QUICKFIX) && defined(FEAT_WINDOWS)
+    if (bt_quickfix(buf))
+    {
+	win_T	*win;
+
+	/*
+	 * For location list window, w_llist_ref points to the location list.
+	 * For quickfix window, w_llist_ref is NULL.
+	 */
+	FOR_ALL_WINDOWS(win)
+	    if (win->w_buffer == buf)
+		break;
+	if (win != NULL && win->w_llist_ref != NULL)
+	    return _("[Location List]");
+	else
+	    return _("[Quickfix List]");
+    }
+#endif
+#ifdef FEAT_QUICKFIX
+    /* There is no _file_ when 'buftype' is "nofile", b_sfname
+     * contains the name as specified by the user */
+    if (bt_nofile(buf))
+    {
+	if (buf->b_sfname != NULL)
+	    return (char *)buf->b_sfname;
+	return "[Scratch]";
+    }
+#endif
+    if (buf->b_fname == NULL)
+	return _("[No Name]");
+    return NULL;
+}
+
+
+#if defined(FEAT_SIGNS) || defined(PROTO)
+/*
+ * Insert the sign into the signlist.
+ */
+    static void
+insert_sign(buf, prev, next, id, lnum, typenr)
+    buf_T	*buf;		/* buffer to store sign in */
+    signlist_T	*prev;		/* previous sign entry */
+    signlist_T	*next;		/* next sign entry */
+    int		id;		/* sign ID */
+    linenr_T	lnum;		/* line number which gets the mark */
+    int		typenr;		/* typenr of sign we are adding */
+{
+    signlist_T	*newsign;
+
+    newsign = (signlist_T *)lalloc((long_u)sizeof(signlist_T), FALSE);
+    if (newsign != NULL)
+    {
+	newsign->id = id;
+	newsign->lnum = lnum;
+	newsign->typenr = typenr;
+	newsign->next = next;
+#ifdef FEAT_NETBEANS_INTG
+	newsign->prev = prev;
+	if (next != NULL)
+	    next->prev = newsign;
+#endif
+
+	if (prev == NULL)
+	{
+	    /* When adding first sign need to redraw the windows to create the
+	     * column for signs. */
+	    if (buf->b_signlist == NULL)
+	    {
+		redraw_buf_later(buf, NOT_VALID);
+		changed_cline_bef_curs();
+	    }
+
+	    /* first sign in signlist */
+	    buf->b_signlist = newsign;
+	}
+	else
+	    prev->next = newsign;
+    }
+}
+
+/*
+ * Add the sign into the signlist. Find the right spot to do it though.
+ */
+    void
+buf_addsign(buf, id, lnum, typenr)
+    buf_T	*buf;		/* buffer to store sign in */
+    int		id;		/* sign ID */
+    linenr_T	lnum;		/* line number which gets the mark */
+    int		typenr;		/* typenr of sign we are adding */
+{
+    signlist_T	*sign;		/* a sign in the signlist */
+    signlist_T	*prev;		/* the previous sign */
+
+    prev = NULL;
+    for (sign = buf->b_signlist; sign != NULL; sign = sign->next)
+    {
+	if (lnum == sign->lnum && id == sign->id)
+	{
+	    sign->typenr = typenr;
+	    return;
+	}
+	else if (
+#ifndef FEAT_NETBEANS_INTG  /* keep signs sorted by lnum */
+		   id < 0 &&
+#endif
+			     lnum < sign->lnum)
+	{
+#ifdef FEAT_NETBEANS_INTG /* insert new sign at head of list for this lnum */
+	    /* XXX - GRP: Is this because of sign slide problem? Or is it
+	     * really needed? Or is it because we allow multiple signs per
+	     * line? If so, should I add that feature to FEAT_SIGNS?
+	     */
+	    while (prev != NULL && prev->lnum == lnum)
+		prev = prev->prev;
+	    if (prev == NULL)
+		sign = buf->b_signlist;
+	    else
+		sign = prev->next;
+#endif
+	    insert_sign(buf, prev, sign, id, lnum, typenr);
+	    return;
+	}
+	prev = sign;
+    }
+#ifdef FEAT_NETBEANS_INTG /* insert new sign at head of list for this lnum */
+    /* XXX - GRP: See previous comment */
+    while (prev != NULL && prev->lnum == lnum)
+	prev = prev->prev;
+    if (prev == NULL)
+	sign = buf->b_signlist;
+    else
+	sign = prev->next;
+#endif
+    insert_sign(buf, prev, sign, id, lnum, typenr);
+
+    return;
+}
+
+    int
+buf_change_sign_type(buf, markId, typenr)
+    buf_T	*buf;		/* buffer to store sign in */
+    int		markId;		/* sign ID */
+    int		typenr;		/* typenr of sign we are adding */
+{
+    signlist_T	*sign;		/* a sign in the signlist */
+
+    for (sign = buf->b_signlist; sign != NULL; sign = sign->next)
+    {
+	if (sign->id == markId)
+	{
+	    sign->typenr = typenr;
+	    return sign->lnum;
+	}
+    }
+
+    return 0;
+}
+
+    int_u
+buf_getsigntype(buf, lnum, type)
+    buf_T	*buf;
+    linenr_T	lnum;
+    int		type;	/* SIGN_ICON, SIGN_TEXT, SIGN_ANY, SIGN_LINEHL */
+{
+    signlist_T	*sign;		/* a sign in a b_signlist */
+
+    for (sign = buf->b_signlist; sign != NULL; sign = sign->next)
+	if (sign->lnum == lnum
+		&& (type == SIGN_ANY
+# ifdef FEAT_SIGN_ICONS
+		    || (type == SIGN_ICON
+			&& sign_get_image(sign->typenr) != NULL)
+# endif
+		    || (type == SIGN_TEXT
+			&& sign_get_text(sign->typenr) != NULL)
+		    || (type == SIGN_LINEHL
+			&& sign_get_attr(sign->typenr, TRUE) != 0)))
+	    return sign->typenr;
+    return 0;
+}
+
+
+    linenr_T
+buf_delsign(buf, id)
+    buf_T	*buf;		/* buffer sign is stored in */
+    int		id;		/* sign id */
+{
+    signlist_T	**lastp;	/* pointer to pointer to current sign */
+    signlist_T	*sign;		/* a sign in a b_signlist */
+    signlist_T	*next;		/* the next sign in a b_signlist */
+    linenr_T	lnum;		/* line number whose sign was deleted */
+
+    lastp = &buf->b_signlist;
+    lnum = 0;
+    for (sign = buf->b_signlist; sign != NULL; sign = next)
+    {
+	next = sign->next;
+	if (sign->id == id)
+	{
+	    *lastp = next;
+#ifdef FEAT_NETBEANS_INTG
+	    if (next != NULL)
+		next->prev = sign->prev;
+#endif
+	    lnum = sign->lnum;
+	    vim_free(sign);
+	    break;
+	}
+	else
+	    lastp = &sign->next;
+    }
+
+    /* When deleted the last sign need to redraw the windows to remove the
+     * sign column. */
+    if (buf->b_signlist == NULL)
+    {
+	redraw_buf_later(buf, NOT_VALID);
+	changed_cline_bef_curs();
+    }
+
+    return lnum;
+}
+
+
+/*
+ * Find the line number of the sign with the requested id. If the sign does
+ * not exist, return 0 as the line number. This will still let the correct file
+ * get loaded.
+ */
+    int
+buf_findsign(buf, id)
+    buf_T	*buf;		/* buffer to store sign in */
+    int		id;		/* sign ID */
+{
+    signlist_T	*sign;		/* a sign in the signlist */
+
+    for (sign = buf->b_signlist; sign != NULL; sign = sign->next)
+	if (sign->id == id)
+	    return sign->lnum;
+
+    return 0;
+}
+
+    int
+buf_findsign_id(buf, lnum)
+    buf_T	*buf;		/* buffer whose sign we are searching for */
+    linenr_T	lnum;		/* line number of sign */
+{
+    signlist_T	*sign;		/* a sign in the signlist */
+
+    for (sign = buf->b_signlist; sign != NULL; sign = sign->next)
+	if (sign->lnum == lnum)
+	    return sign->id;
+
+    return 0;
+}
+
+
+# if defined(FEAT_NETBEANS_INTG) || defined(PROTO)
+/* see if a given type of sign exists on a specific line */
+    int
+buf_findsigntype_id(buf, lnum, typenr)
+    buf_T	*buf;		/* buffer whose sign we are searching for */
+    linenr_T	lnum;		/* line number of sign */
+    int		typenr;		/* sign type number */
+{
+    signlist_T	*sign;		/* a sign in the signlist */
+
+    for (sign = buf->b_signlist; sign != NULL; sign = sign->next)
+	if (sign->lnum == lnum && sign->typenr == typenr)
+	    return sign->id;
+
+    return 0;
+}
+
+
+#  if defined(FEAT_SIGN_ICONS) || defined(PROTO)
+/* return the number of icons on the given line */
+    int
+buf_signcount(buf, lnum)
+    buf_T	*buf;
+    linenr_T	lnum;
+{
+    signlist_T	*sign;		/* a sign in the signlist */
+    int		count = 0;
+
+    for (sign = buf->b_signlist; sign != NULL; sign = sign->next)
+	if (sign->lnum == lnum)
+	    if (sign_get_image(sign->typenr) != NULL)
+		count++;
+
+    return count;
+}
+#  endif /* FEAT_SIGN_ICONS */
+# endif /* FEAT_NETBEANS_INTG */
+
+
+/*
+ * Delete signs in buffer "buf".
+ */
+    static void
+buf_delete_signs(buf)
+    buf_T	*buf;
+{
+    signlist_T	*next;
+
+    while (buf->b_signlist != NULL)
+    {
+	next = buf->b_signlist->next;
+	vim_free(buf->b_signlist);
+	buf->b_signlist = next;
+    }
+}
+
+/*
+ * Delete all signs in all buffers.
+ */
+    void
+buf_delete_all_signs()
+{
+    buf_T	*buf;		/* buffer we are checking for signs */
+
+    for (buf = firstbuf; buf != NULL; buf = buf->b_next)
+	if (buf->b_signlist != NULL)
+	{
+	    /* Need to redraw the windows to remove the sign column. */
+	    redraw_buf_later(buf, NOT_VALID);
+	    buf_delete_signs(buf);
+	}
+}
+
+/*
+ * List placed signs for "rbuf".  If "rbuf" is NULL do it for all buffers.
+ */
+    void
+sign_list_placed(rbuf)
+    buf_T	*rbuf;
+{
+    buf_T	*buf;
+    signlist_T	*p;
+    char	lbuf[BUFSIZ];
+
+    MSG_PUTS_TITLE(_("\n--- Signs ---"));
+    msg_putchar('\n');
+    if (rbuf == NULL)
+	buf = firstbuf;
+    else
+	buf = rbuf;
+    while (buf != NULL)
+    {
+	if (buf->b_signlist != NULL)
+	{
+	    vim_snprintf(lbuf, BUFSIZ, _("Signs for %s:"), buf->b_fname);
+	    MSG_PUTS_ATTR(lbuf, hl_attr(HLF_D));
+	    msg_putchar('\n');
+	}
+	for (p = buf->b_signlist; p != NULL; p = p->next)
+	{
+	    vim_snprintf(lbuf, BUFSIZ, _("    line=%ld  id=%d  name=%s"),
+			   (long)p->lnum, p->id, sign_typenr2name(p->typenr));
+	    MSG_PUTS(lbuf);
+	    msg_putchar('\n');
+	}
+	if (rbuf != NULL)
+	    break;
+	buf = buf->b_next;
+    }
+}
+
+/*
+ * Adjust a placed sign for inserted/deleted lines.
+ */
+    void
+sign_mark_adjust(line1, line2, amount, amount_after)
+    linenr_T	line1;
+    linenr_T	line2;
+    long	amount;
+    long	amount_after;
+{
+    signlist_T	*sign;		/* a sign in a b_signlist */
+
+    for (sign = curbuf->b_signlist; sign != NULL; sign = sign->next)
+    {
+	if (sign->lnum >= line1 && sign->lnum <= line2)
+	{
+	    if (amount == MAXLNUM)
+		sign->lnum = line1;
+	    else
+		sign->lnum += amount;
+	}
+	else if (sign->lnum > line2)
+	    sign->lnum += amount_after;
+    }
+}
+#endif /* FEAT_SIGNS */
+
+/*
+ * Set 'buflisted' for curbuf to "on" and trigger autocommands if it changed.
+ */
+    void
+set_buflisted(on)
+    int		on;
+{
+    if (on != curbuf->b_p_bl)
+    {
+	curbuf->b_p_bl = on;
+#ifdef FEAT_AUTOCMD
+	if (on)
+	    apply_autocmds(EVENT_BUFADD, NULL, NULL, FALSE, curbuf);
+	else
+	    apply_autocmds(EVENT_BUFDELETE, NULL, NULL, FALSE, curbuf);
+#endif
+    }
+}
+
+/*
+ * Read the file for "buf" again and check if the contents changed.
+ * Return TRUE if it changed or this could not be checked.
+ */
+    int
+buf_contents_changed(buf)
+    buf_T	*buf;
+{
+    buf_T	*newbuf;
+    int		differ = TRUE;
+    linenr_T	lnum;
+    aco_save_T	aco;
+    exarg_T	ea;
+
+    /* Allocate a buffer without putting it in the buffer list. */
+    newbuf = buflist_new(NULL, NULL, (linenr_T)1, BLN_DUMMY);
+    if (newbuf == NULL)
+	return TRUE;
+
+    /* Force the 'fileencoding' and 'fileformat' to be equal. */
+    if (prep_exarg(&ea, buf) == FAIL)
+    {
+	wipe_buffer(newbuf, FALSE);
+	return TRUE;
+    }
+
+    /* set curwin/curbuf to buf and save a few things */
+    aucmd_prepbuf(&aco, newbuf);
+
+    if (ml_open(curbuf) == OK
+	    && readfile(buf->b_ffname, buf->b_fname,
+				  (linenr_T)0, (linenr_T)0, (linenr_T)MAXLNUM,
+					    &ea, READ_NEW | READ_DUMMY) == OK)
+    {
+	/* compare the two files line by line */
+	if (buf->b_ml.ml_line_count == curbuf->b_ml.ml_line_count)
+	{
+	    differ = FALSE;
+	    for (lnum = 1; lnum <= curbuf->b_ml.ml_line_count; ++lnum)
+		if (STRCMP(ml_get_buf(buf, lnum, FALSE), ml_get(lnum)) != 0)
+		{
+		    differ = TRUE;
+		    break;
+		}
+	}
+    }
+    vim_free(ea.cmd);
+
+    /* restore curwin/curbuf and a few other things */
+    aucmd_restbuf(&aco);
+
+    if (curbuf != newbuf)	/* safety check */
+	wipe_buffer(newbuf, FALSE);
+
+    return differ;
+}
+
+/*
+ * Wipe out a buffer and decrement the last buffer number if it was used for
+ * this buffer.  Call this to wipe out a temp buffer that does not contain any
+ * marks.
+ */
+/*ARGSUSED*/
+    void
+wipe_buffer(buf, aucmd)
+    buf_T	*buf;
+    int		aucmd;	    /* When TRUE trigger autocommands. */
+{
+    if (buf->b_fnum == top_file_num - 1)
+	--top_file_num;
+
+#ifdef FEAT_AUTOCMD
+    if (!aucmd)		    /* Don't trigger BufDelete autocommands here. */
+	++autocmd_block;
+#endif
+    close_buffer(NULL, buf, DOBUF_WIPE);
+#ifdef FEAT_AUTOCMD
+    if (!aucmd)
+	--autocmd_block;
+#endif
+}
--- /dev/null
+++ b/charset.c
@@ -1,0 +1,1975 @@
+/* vi:set ts=8 sts=4 sw=4:
+ *
+ * VIM - Vi IMproved	by Bram Moolenaar
+ *
+ * Do ":help uganda"  in Vim to read copying and usage conditions.
+ * Do ":help credits" in Vim to see a list of people who contributed.
+ * See README.txt for an overview of the Vim source code.
+ */
+
+#include "vim.h"
+
+#ifdef FEAT_LINEBREAK
+static int win_chartabsize __ARGS((win_T *wp, char_u *p, colnr_T col));
+#endif
+
+#ifdef FEAT_MBYTE
+static int win_nolbr_chartabsize __ARGS((win_T *wp, char_u *s, colnr_T col, int *headp));
+#endif
+
+static int nr2hex __ARGS((int c));
+
+static int    chartab_initialized = FALSE;
+
+/* b_chartab[] is an array of 32 bytes, each bit representing one of the
+ * characters 0-255. */
+#define SET_CHARTAB(buf, c) (buf)->b_chartab[(unsigned)(c) >> 3] |= (1 << ((c) & 0x7))
+#define RESET_CHARTAB(buf, c) (buf)->b_chartab[(unsigned)(c) >> 3] &= ~(1 << ((c) & 0x7))
+#define GET_CHARTAB(buf, c) ((buf)->b_chartab[(unsigned)(c) >> 3] & (1 << ((c) & 0x7)))
+
+/*
+ * Fill chartab[].  Also fills curbuf->b_chartab[] with flags for keyword
+ * characters for current buffer.
+ *
+ * Depends on the option settings 'iskeyword', 'isident', 'isfname',
+ * 'isprint' and 'encoding'.
+ *
+ * The index in chartab[] depends on 'encoding':
+ * - For non-multi-byte index with the byte (same as the character).
+ * - For DBCS index with the first byte.
+ * - For UTF-8 index with the character (when first byte is up to 0x80 it is
+ *   the same as the character, if the first byte is 0x80 and above it depends
+ *   on further bytes).
+ *
+ * The contents of chartab[]:
+ * - The lower two bits, masked by CT_CELL_MASK, give the number of display
+ *   cells the character occupies (1 or 2).  Not valid for UTF-8 above 0x80.
+ * - CT_PRINT_CHAR bit is set when the character is printable (no need to
+ *   translate the character before displaying it).  Note that only DBCS
+ *   characters can have 2 display cells and still be printable.
+ * - CT_FNAME_CHAR bit is set when the character can be in a file name.
+ * - CT_ID_CHAR bit is set when the character can be in an identifier.
+ *
+ * Return FAIL if 'iskeyword', 'isident', 'isfname' or 'isprint' option has an
+ * error, OK otherwise.
+ */
+    int
+init_chartab()
+{
+    return buf_init_chartab(curbuf, TRUE);
+}
+
+    int
+buf_init_chartab(buf, global)
+    buf_T	*buf;
+    int		global;		/* FALSE: only set buf->b_chartab[] */
+{
+    int		c;
+    int		c2;
+    char_u	*p;
+    int		i;
+    int		tilde;
+    int		do_isalpha;
+
+    if (global)
+    {
+	/*
+	 * Set the default size for printable characters:
+	 * From <Space> to '~' is 1 (printable), others are 2 (not printable).
+	 * This also inits all 'isident' and 'isfname' flags to FALSE.
+	 *
+	 * EBCDIC: all chars below ' ' are not printable, all others are
+	 * printable.
+	 */
+	c = 0;
+	while (c < ' ')
+	    chartab[c++] = (dy_flags & DY_UHEX) ? 4 : 2;
+#ifdef EBCDIC
+	while (c < 255)
+#else
+	while (c <= '~')
+#endif
+	    chartab[c++] = 1 + CT_PRINT_CHAR;
+#ifdef FEAT_FKMAP
+	if (p_altkeymap)
+	{
+	    while (c < YE)
+		chartab[c++] = 1 + CT_PRINT_CHAR;
+	}
+#endif
+	while (c < 256)
+	{
+#ifdef FEAT_MBYTE
+	    /* UTF-8: bytes 0xa0 - 0xff are printable (latin1) */
+	    if (enc_utf8 && c >= 0xa0)
+		chartab[c++] = CT_PRINT_CHAR + 1;
+	    /* euc-jp characters starting with 0x8e are single width */
+	    else if (enc_dbcs == DBCS_JPNU && c == 0x8e)
+		chartab[c++] = CT_PRINT_CHAR + 1;
+	    /* other double-byte chars can be printable AND double-width */
+	    else if (enc_dbcs != 0 && MB_BYTE2LEN(c) == 2)
+		chartab[c++] = CT_PRINT_CHAR + 2;
+	    else
+#endif
+		/* the rest is unprintable by default */
+		chartab[c++] = (dy_flags & DY_UHEX) ? 4 : 2;
+	}
+
+#ifdef FEAT_MBYTE
+	/* Assume that every multi-byte char is a filename character. */
+	for (c = 1; c < 256; ++c)
+	    if ((enc_dbcs != 0 && MB_BYTE2LEN(c) > 1)
+		    || (enc_dbcs == DBCS_JPNU && c == 0x8e)
+		    || (enc_utf8 && c >= 0xa0))
+		chartab[c] |= CT_FNAME_CHAR;
+#endif
+    }
+
+    /*
+     * Init word char flags all to FALSE
+     */
+    vim_memset(buf->b_chartab, 0, (size_t)32);
+#ifdef FEAT_MBYTE
+    if (enc_dbcs != 0)
+	for (c = 0; c < 256; ++c)
+	{
+	    /* double-byte characters are probably word characters */
+	    if (MB_BYTE2LEN(c) == 2)
+		SET_CHARTAB(buf, c);
+	}
+#endif
+
+#ifdef FEAT_LISP
+    /*
+     * In lisp mode the '-' character is included in keywords.
+     */
+    if (buf->b_p_lisp)
+	SET_CHARTAB(buf, '-');
+#endif
+
+    /* Walk through the 'isident', 'iskeyword', 'isfname' and 'isprint'
+     * options Each option is a list of characters, character numbers or
+     * ranges, separated by commas, e.g.: "200-210,x,#-178,-"
+     */
+    for (i = global ? 0 : 3; i <= 3; ++i)
+    {
+	if (i == 0)
+	    p = p_isi;		/* first round: 'isident' */
+	else if (i == 1)
+	    p = p_isp;		/* second round: 'isprint' */
+	else if (i == 2)
+	    p = p_isf;		/* third round: 'isfname' */
+	else	/* i == 3 */
+	    p = buf->b_p_isk;	/* fourth round: 'iskeyword' */
+
+	while (*p)
+	{
+	    tilde = FALSE;
+	    do_isalpha = FALSE;
+	    if (*p == '^' && p[1] != NUL)
+	    {
+		tilde = TRUE;
+		++p;
+	    }
+	    if (VIM_ISDIGIT(*p))
+		c = getdigits(&p);
+	    else
+		c = *p++;
+	    c2 = -1;
+	    if (*p == '-' && p[1] != NUL)
+	    {
+		++p;
+		if (VIM_ISDIGIT(*p))
+		    c2 = getdigits(&p);
+		else
+		    c2 = *p++;
+	    }
+	    if (c <= 0 || (c2 < c && c2 != -1) || c2 >= 256
+						 || !(*p == NUL || *p == ','))
+		return FAIL;
+
+	    if (c2 == -1)	/* not a range */
+	    {
+		/*
+		 * A single '@' (not "@-@"):
+		 * Decide on letters being ID/printable/keyword chars with
+		 * standard function isalpha(). This takes care of locale for
+		 * single-byte characters).
+		 */
+		if (c == '@')
+		{
+		    do_isalpha = TRUE;
+		    c = 1;
+		    c2 = 255;
+		}
+		else
+		    c2 = c;
+	    }
+	    while (c <= c2)
+	    {
+		if (!do_isalpha || isalpha(c)
+#ifdef FEAT_FKMAP
+			|| (p_altkeymap && (F_isalpha(c) || F_isdigit(c)))
+#endif
+			    )
+		{
+		    if (i == 0)			/* (re)set ID flag */
+		    {
+			if (tilde)
+			    chartab[c] &= ~CT_ID_CHAR;
+			else
+			    chartab[c] |= CT_ID_CHAR;
+		    }
+		    else if (i == 1)		/* (re)set printable */
+		    {
+			if ((c < ' '
+#ifndef EBCDIC
+				    || c > '~'
+#endif
+#ifdef FEAT_FKMAP
+				    || (p_altkeymap
+					&& (F_isalpha(c) || F_isdigit(c)))
+#endif
+			    )
+#ifdef FEAT_MBYTE
+				/* For double-byte we keep the cell width, so
+				 * that we can detect it from the first byte. */
+				&& !(enc_dbcs && MB_BYTE2LEN(c) == 2)
+#endif
+			   )
+			{
+			    if (tilde)
+			    {
+				chartab[c] = (chartab[c] & ~CT_CELL_MASK)
+					     + ((dy_flags & DY_UHEX) ? 4 : 2);
+				chartab[c] &= ~CT_PRINT_CHAR;
+			    }
+			    else
+			    {
+				chartab[c] = (chartab[c] & ~CT_CELL_MASK) + 1;
+				chartab[c] |= CT_PRINT_CHAR;
+			    }
+			}
+		    }
+		    else if (i == 2)		/* (re)set fname flag */
+		    {
+			if (tilde)
+			    chartab[c] &= ~CT_FNAME_CHAR;
+			else
+			    chartab[c] |= CT_FNAME_CHAR;
+		    }
+		    else /* i == 3 */		/* (re)set keyword flag */
+		    {
+			if (tilde)
+			    RESET_CHARTAB(buf, c);
+			else
+			    SET_CHARTAB(buf, c);
+		    }
+		}
+		++c;
+	    }
+	    p = skip_to_option_part(p);
+	}
+    }
+    chartab_initialized = TRUE;
+    return OK;
+}
+
+/*
+ * Translate any special characters in buf[bufsize] in-place.
+ * The result is a string with only printable characters, but if there is not
+ * enough room, not all characters will be translated.
+ */
+    void
+trans_characters(buf, bufsize)
+    char_u	*buf;
+    int		bufsize;
+{
+    int		len;		/* length of string needing translation */
+    int		room;		/* room in buffer after string */
+    char_u	*trs;		/* translated character */
+    int		trs_len;	/* length of trs[] */
+
+    len = (int)STRLEN(buf);
+    room = bufsize - len;
+    while (*buf != 0)
+    {
+# ifdef FEAT_MBYTE
+	/* Assume a multi-byte character doesn't need translation. */
+	if (has_mbyte && (trs_len = (*mb_ptr2len)(buf)) > 1)
+	    len -= trs_len;
+	else
+# endif
+	{
+	    trs = transchar_byte(*buf);
+	    trs_len = (int)STRLEN(trs);
+	    if (trs_len > 1)
+	    {
+		room -= trs_len - 1;
+		if (room <= 0)
+		    return;
+		mch_memmove(buf + trs_len, buf + 1, (size_t)len);
+	    }
+	    mch_memmove(buf, trs, (size_t)trs_len);
+	    --len;
+	}
+	buf += trs_len;
+    }
+}
+
+#if defined(FEAT_EVAL) || defined(FEAT_TITLE) || defined(FEAT_INS_EXPAND) \
+	|| defined(PROTO)
+/*
+ * Translate a string into allocated memory, replacing special chars with
+ * printable chars.  Returns NULL when out of memory.
+ */
+    char_u *
+transstr(s)
+    char_u	*s;
+{
+    char_u	*res;
+    char_u	*p;
+#ifdef FEAT_MBYTE
+    int		l, len, c;
+    char_u	hexbuf[11];
+#endif
+
+#ifdef FEAT_MBYTE
+    if (has_mbyte)
+    {
+	/* Compute the length of the result, taking account of unprintable
+	 * multi-byte characters. */
+	len = 0;
+	p = s;
+	while (*p != NUL)
+	{
+	    if ((l = (*mb_ptr2len)(p)) > 1)
+	    {
+		c = (*mb_ptr2char)(p);
+		p += l;
+		if (vim_isprintc(c))
+		    len += l;
+		else
+		{
+		    transchar_hex(hexbuf, c);
+		    len += (int)STRLEN(hexbuf);
+		}
+	    }
+	    else
+	    {
+		l = byte2cells(*p++);
+		if (l > 0)
+		    len += l;
+		else
+		    len += 4;	/* illegal byte sequence */
+	    }
+	}
+	res = alloc((unsigned)(len + 1));
+    }
+    else
+#endif
+	res = alloc((unsigned)(vim_strsize(s) + 1));
+    if (res != NULL)
+    {
+	*res = NUL;
+	p = s;
+	while (*p != NUL)
+	{
+#ifdef FEAT_MBYTE
+	    if (has_mbyte && (l = (*mb_ptr2len)(p)) > 1)
+	    {
+		c = (*mb_ptr2char)(p);
+		if (vim_isprintc(c))
+		    STRNCAT(res, p, l);	/* append printable multi-byte char */
+		else
+		    transchar_hex(res + STRLEN(res), c);
+		p += l;
+	    }
+	    else
+#endif
+		STRCAT(res, transchar_byte(*p++));
+	}
+    }
+    return res;
+}
+#endif
+
+#if defined(FEAT_SYN_HL) || defined(FEAT_INS_EXPAND) || defined(PROTO)
+/*
+ * Convert the string "str[orglen]" to do ignore-case comparing.  Uses the
+ * current locale.
+ * When "buf" is NULL returns an allocated string (NULL for out-of-memory).
+ * Otherwise puts the result in "buf[buflen]".
+ */
+    char_u *
+str_foldcase(str, orglen, buf, buflen)
+    char_u	*str;
+    int		orglen;
+    char_u	*buf;
+    int		buflen;
+{
+    garray_T	ga;
+    int		i;
+    int		len = orglen;
+
+#define GA_CHAR(i)  ((char_u *)ga.ga_data)[i]
+#define GA_PTR(i)   ((char_u *)ga.ga_data + i)
+#define STR_CHAR(i)  (buf == NULL ? GA_CHAR(i) : buf[i])
+#define STR_PTR(i)   (buf == NULL ? GA_PTR(i) : buf + i)
+
+    /* Copy "str" into "buf" or allocated memory, unmodified. */
+    if (buf == NULL)
+    {
+	ga_init2(&ga, 1, 10);
+	if (ga_grow(&ga, len + 1) == FAIL)
+	    return NULL;
+	mch_memmove(ga.ga_data, str, (size_t)len);
+	ga.ga_len = len;
+    }
+    else
+    {
+	if (len >= buflen)	    /* Ugly! */
+	    len = buflen - 1;
+	mch_memmove(buf, str, (size_t)len);
+    }
+    if (buf == NULL)
+	GA_CHAR(len) = NUL;
+    else
+	buf[len] = NUL;
+
+    /* Make each character lower case. */
+    i = 0;
+    while (STR_CHAR(i) != NUL)
+    {
+#ifdef FEAT_MBYTE
+	if (enc_utf8 || (has_mbyte && MB_BYTE2LEN(STR_CHAR(i)) > 1))
+	{
+	    if (enc_utf8)
+	    {
+		int	c, lc;
+
+		c = utf_ptr2char(STR_PTR(i));
+		lc = utf_tolower(c);
+		if (c != lc)
+		{
+		    int	    ol = utf_char2len(c);
+		    int	    nl = utf_char2len(lc);
+
+		    /* If the byte length changes need to shift the following
+		     * characters forward or backward. */
+		    if (ol != nl)
+		    {
+			if (nl > ol)
+			{
+			    if (buf == NULL ? ga_grow(&ga, nl - ol + 1) == FAIL
+						    : len + nl - ol >= buflen)
+			    {
+				/* out of memory, keep old char */
+				lc = c;
+				nl = ol;
+			    }
+			}
+			if (ol != nl)
+			{
+			    if (buf == NULL)
+			    {
+				mch_memmove(GA_PTR(i) + nl, GA_PTR(i) + ol,
+						  STRLEN(GA_PTR(i) + ol) + 1);
+				ga.ga_len += nl - ol;
+			    }
+			    else
+			    {
+				mch_memmove(buf + i + nl, buf + i + ol,
+						    STRLEN(buf + i + ol) + 1);
+				len += nl - ol;
+			    }
+			}
+		    }
+		    (void)utf_char2bytes(lc, STR_PTR(i));
+		}
+	    }
+	    /* skip to next multi-byte char */
+	    i += (*mb_ptr2len)(STR_PTR(i));
+	}
+	else
+#endif
+	{
+	    if (buf == NULL)
+		GA_CHAR(i) = TOLOWER_LOC(GA_CHAR(i));
+	    else
+		buf[i] = TOLOWER_LOC(buf[i]);
+	    ++i;
+	}
+    }
+
+    if (buf == NULL)
+	return (char_u *)ga.ga_data;
+    return buf;
+}
+#endif
+
+/*
+ * Catch 22: chartab[] can't be initialized before the options are
+ * initialized, and initializing options may cause transchar() to be called!
+ * When chartab_initialized == FALSE don't use chartab[].
+ * Does NOT work for multi-byte characters, c must be <= 255.
+ * Also doesn't work for the first byte of a multi-byte, "c" must be a
+ * character!
+ */
+static char_u	transchar_buf[7];
+
+    char_u *
+transchar(c)
+    int		c;
+{
+    int			i;
+
+    i = 0;
+    if (IS_SPECIAL(c))	    /* special key code, display as ~@ char */
+    {
+	transchar_buf[0] = '~';
+	transchar_buf[1] = '@';
+	i = 2;
+	c = K_SECOND(c);
+    }
+
+    if ((!chartab_initialized && (
+#ifdef EBCDIC
+		    (c >= 64 && c < 255)
+#else
+		    (c >= ' ' && c <= '~')
+#endif
+#ifdef FEAT_FKMAP
+			|| F_ischar(c)
+#endif
+		)) || (c < 256 && vim_isprintc_strict(c)))
+    {
+	/* printable character */
+	transchar_buf[i] = c;
+	transchar_buf[i + 1] = NUL;
+    }
+    else
+	transchar_nonprint(transchar_buf + i, c);
+    return transchar_buf;
+}
+
+#if defined(FEAT_MBYTE) || defined(PROTO)
+/*
+ * Like transchar(), but called with a byte instead of a character.  Checks
+ * for an illegal UTF-8 byte.
+ */
+    char_u *
+transchar_byte(c)
+    int		c;
+{
+    if (enc_utf8 && c >= 0x80)
+    {
+	transchar_nonprint(transchar_buf, c);
+	return transchar_buf;
+    }
+    return transchar(c);
+}
+#endif
+
+/*
+ * Convert non-printable character to two or more printable characters in
+ * "buf[]".  "buf" needs to be able to hold five bytes.
+ * Does NOT work for multi-byte characters, c must be <= 255.
+ */
+    void
+transchar_nonprint(buf, c)
+    char_u	*buf;
+    int		c;
+{
+    if (c == NL)
+	c = NUL;		/* we use newline in place of a NUL */
+    else if (c == CAR && get_fileformat(curbuf) == EOL_MAC)
+	c = NL;			/* we use CR in place of  NL in this case */
+
+    if (dy_flags & DY_UHEX)		/* 'display' has "uhex" */
+	transchar_hex(buf, c);
+
+#ifdef EBCDIC
+    /* For EBCDIC only the characters 0-63 and 255 are not printable */
+    else if (CtrlChar(c) != 0 || c == DEL)
+#else
+    else if (c <= 0x7f)				/* 0x00 - 0x1f and 0x7f */
+#endif
+    {
+	buf[0] = '^';
+#ifdef EBCDIC
+	if (c == DEL)
+	    buf[1] = '?';		/* DEL displayed as ^? */
+	else
+	    buf[1] = CtrlChar(c);
+#else
+	buf[1] = c ^ 0x40;		/* DEL displayed as ^? */
+#endif
+
+	buf[2] = NUL;
+    }
+#ifdef FEAT_MBYTE
+    else if (enc_utf8 && c >= 0x80)
+    {
+	transchar_hex(buf, c);
+    }
+#endif
+#ifndef EBCDIC
+    else if (c >= ' ' + 0x80 && c <= '~' + 0x80)    /* 0xa0 - 0xfe */
+    {
+	buf[0] = '|';
+	buf[1] = c - 0x80;
+	buf[2] = NUL;
+    }
+#else
+    else if (c < 64)
+    {
+	buf[0] = '~';
+	buf[1] = MetaChar(c);
+	buf[2] = NUL;
+    }
+#endif
+    else					    /* 0x80 - 0x9f and 0xff */
+    {
+	/*
+	 * TODO: EBCDIC I don't know what to do with this chars, so I display
+	 * them as '~?' for now
+	 */
+	buf[0] = '~';
+#ifdef EBCDIC
+	buf[1] = '?';			/* 0xff displayed as ~? */
+#else
+	buf[1] = (c - 0x80) ^ 0x40;	/* 0xff displayed as ~? */
+#endif
+	buf[2] = NUL;
+    }
+}
+
+    void
+transchar_hex(buf, c)
+    char_u	*buf;
+    int		c;
+{
+    int		i = 0;
+
+    buf[0] = '<';
+#ifdef FEAT_MBYTE
+    if (c > 255)
+    {
+	buf[++i] = nr2hex((unsigned)c >> 12);
+	buf[++i] = nr2hex((unsigned)c >> 8);
+    }
+#endif
+    buf[++i] = nr2hex((unsigned)c >> 4);
+    buf[++i] = nr2hex(c);
+    buf[++i] = '>';
+    buf[++i] = NUL;
+}
+
+/*
+ * Convert the lower 4 bits of byte "c" to its hex character.
+ * Lower case letters are used to avoid the confusion of <F1> being 0xf1 or
+ * function key 1.
+ */
+    static int
+nr2hex(c)
+    int		c;
+{
+    if ((c & 0xf) <= 9)
+	return (c & 0xf) + '0';
+    return (c & 0xf) - 10 + 'a';
+}
+
+/*
+ * Return number of display cells occupied by byte "b".
+ * Caller must make sure 0 <= b <= 255.
+ * For multi-byte mode "b" must be the first byte of a character.
+ * A TAB is counted as two cells: "^I".
+ * For UTF-8 mode this will return 0 for bytes >= 0x80, because the number of
+ * cells depends on further bytes.
+ */
+    int
+byte2cells(b)
+    int		b;
+{
+#ifdef FEAT_MBYTE
+    if (enc_utf8 && b >= 0x80)
+	return 0;
+#endif
+    return (chartab[b] & CT_CELL_MASK);
+}
+
+/*
+ * Return number of display cells occupied by character "c".
+ * "c" can be a special key (negative number) in which case 3 or 4 is returned.
+ * A TAB is counted as two cells: "^I" or four: "<09>".
+ */
+    int
+char2cells(c)
+    int		c;
+{
+    if (IS_SPECIAL(c))
+	return char2cells(K_SECOND(c)) + 2;
+#ifdef FEAT_MBYTE
+    if (c >= 0x80)
+    {
+	/* UTF-8: above 0x80 need to check the value */
+	if (enc_utf8)
+	    return utf_char2cells(c);
+	/* DBCS: double-byte means double-width, except for euc-jp with first
+	 * byte 0x8e */
+	if (enc_dbcs != 0 && c >= 0x100)
+	{
+	    if (enc_dbcs == DBCS_JPNU && ((unsigned)c >> 8) == 0x8e)
+		return 1;
+	    return 2;
+	}
+    }
+#endif
+    return (chartab[c & 0xff] & CT_CELL_MASK);
+}
+
+/*
+ * Return number of display cells occupied by character at "*p".
+ * A TAB is counted as two cells: "^I" or four: "<09>".
+ */
+    int
+ptr2cells(p)
+    char_u	*p;
+{
+#ifdef FEAT_MBYTE
+    /* For UTF-8 we need to look at more bytes if the first byte is >= 0x80. */
+    if (enc_utf8 && *p >= 0x80)
+	return utf_ptr2cells(p);
+    /* For DBCS we can tell the cell count from the first byte. */
+#endif
+    return (chartab[*p] & CT_CELL_MASK);
+}
+
+/*
+ * Return the number of characters string "s" will take on the screen,
+ * counting TABs as two characters: "^I".
+ */
+    int
+vim_strsize(s)
+    char_u	*s;
+{
+    return vim_strnsize(s, (int)MAXCOL);
+}
+
+/*
+ * Return the number of characters string "s[len]" will take on the screen,
+ * counting TABs as two characters: "^I".
+ */
+    int
+vim_strnsize(s, len)
+    char_u	*s;
+    int		len;
+{
+    int		size = 0;
+
+    while (*s != NUL && --len >= 0)
+    {
+#ifdef FEAT_MBYTE
+	if (has_mbyte)
+	{
+	    int	    l = (*mb_ptr2len)(s);
+
+	    size += ptr2cells(s);
+	    s += l;
+	    len -= l - 1;
+	}
+	else
+#endif
+	    size += byte2cells(*s++);
+    }
+    return size;
+}
+
+/*
+ * Return the number of characters 'c' will take on the screen, taking
+ * into account the size of a tab.
+ * Use a define to make it fast, this is used very often!!!
+ * Also see getvcol() below.
+ */
+
+#define RET_WIN_BUF_CHARTABSIZE(wp, buf, p, col) \
+    if (*(p) == TAB && (!(wp)->w_p_list || lcs_tab1)) \
+    { \
+	int ts; \
+	ts = (buf)->b_p_ts; \
+	return (int)(ts - (col % ts)); \
+    } \
+    else \
+	return ptr2cells(p);
+
+#if defined(FEAT_VREPLACE) || defined(FEAT_EX_EXTRA) || defined(FEAT_GUI) \
+	|| defined(FEAT_VIRTUALEDIT) || defined(PROTO)
+    int
+chartabsize(p, col)
+    char_u	*p;
+    colnr_T	col;
+{
+    RET_WIN_BUF_CHARTABSIZE(curwin, curbuf, p, col)
+}
+#endif
+
+#ifdef FEAT_LINEBREAK
+    static int
+win_chartabsize(wp, p, col)
+    win_T	*wp;
+    char_u	*p;
+    colnr_T	col;
+{
+    RET_WIN_BUF_CHARTABSIZE(wp, wp->w_buffer, p, col)
+}
+#endif
+
+/*
+ * return the number of characters the string 's' will take on the screen,
+ * taking into account the size of a tab
+ */
+    int
+linetabsize(s)
+    char_u	*s;
+{
+    colnr_T	col = 0;
+
+    while (*s != NUL)
+	col += lbr_chartabsize_adv(&s, col);
+    return (int)col;
+}
+
+/*
+ * Like linetabsize(), but for a given window instead of the current one.
+ */
+    int
+win_linetabsize(wp, p, len)
+    win_T	*wp;
+    char_u	*p;
+    colnr_T	len;
+{
+    colnr_T	col = 0;
+    char_u	*s;
+
+    for (s = p; *s != NUL && (len == MAXCOL || s < p + len); mb_ptr_adv(s))
+	col += win_lbr_chartabsize(wp, s, col, NULL);
+    return (int)col;
+}
+
+/*
+ * Return TRUE if 'c' is a normal identifier character:
+ * Letters and characters from the 'isident' option.
+ */
+    int
+vim_isIDc(c)
+    int c;
+{
+    return (c > 0 && c < 0x100 && (chartab[c] & CT_ID_CHAR));
+}
+
+/*
+ * return TRUE if 'c' is a keyword character: Letters and characters from
+ * 'iskeyword' option for current buffer.
+ * For multi-byte characters mb_get_class() is used (builtin rules).
+ */
+    int
+vim_iswordc(c)
+    int c;
+{
+#ifdef FEAT_MBYTE
+    if (c >= 0x100)
+    {
+	if (enc_dbcs != 0)
+	    return dbcs_class((unsigned)c >> 8, c & 0xff) >= 2;
+	if (enc_utf8)
+	    return utf_class(c) >= 2;
+    }
+#endif
+    return (c > 0 && c < 0x100 && GET_CHARTAB(curbuf, c) != 0);
+}
+
+/*
+ * Just like vim_iswordc() but uses a pointer to the (multi-byte) character.
+ */
+    int
+vim_iswordp(p)
+    char_u *p;
+{
+#ifdef FEAT_MBYTE
+    if (has_mbyte && MB_BYTE2LEN(*p) > 1)
+	return mb_get_class(p) >= 2;
+#endif
+    return GET_CHARTAB(curbuf, *p) != 0;
+}
+
+#if defined(FEAT_SYN_HL) || defined(PROTO)
+    int
+vim_iswordc_buf(p, buf)
+    char_u	*p;
+    buf_T	*buf;
+{
+# ifdef FEAT_MBYTE
+    if (has_mbyte && MB_BYTE2LEN(*p) > 1)
+	return mb_get_class(p) >= 2;
+# endif
+    return (GET_CHARTAB(buf, *p) != 0);
+}
+#endif
+
+/*
+ * return TRUE if 'c' is a valid file-name character
+ * Assume characters above 0x100 are valid (multi-byte).
+ */
+    int
+vim_isfilec(c)
+    int	c;
+{
+    return (c >= 0x100 || (c > 0 && (chartab[c] & CT_FNAME_CHAR)));
+}
+
+/*
+ * return TRUE if 'c' is a printable character
+ * Assume characters above 0x100 are printable (multi-byte), except for
+ * Unicode.
+ */
+    int
+vim_isprintc(c)
+    int c;
+{
+#ifdef FEAT_MBYTE
+    if (enc_utf8 && c >= 0x100)
+	return utf_printable(c);
+#endif
+    return (c >= 0x100 || (c > 0 && (chartab[c] & CT_PRINT_CHAR)));
+}
+
+/*
+ * Strict version of vim_isprintc(c), don't return TRUE if "c" is the head
+ * byte of a double-byte character.
+ */
+    int
+vim_isprintc_strict(c)
+    int	c;
+{
+#ifdef FEAT_MBYTE
+    if (enc_dbcs != 0 && c < 0x100 && MB_BYTE2LEN(c) > 1)
+	return FALSE;
+    if (enc_utf8 && c >= 0x100)
+	return utf_printable(c);
+#endif
+    return (c >= 0x100 || (c > 0 && (chartab[c] & CT_PRINT_CHAR)));
+}
+
+/*
+ * like chartabsize(), but also check for line breaks on the screen
+ */
+    int
+lbr_chartabsize(s, col)
+    unsigned char	*s;
+    colnr_T		col;
+{
+#ifdef FEAT_LINEBREAK
+    if (!curwin->w_p_lbr && *p_sbr == NUL)
+    {
+#endif
+#ifdef FEAT_MBYTE
+	if (curwin->w_p_wrap)
+	    return win_nolbr_chartabsize(curwin, s, col, NULL);
+#endif
+	RET_WIN_BUF_CHARTABSIZE(curwin, curbuf, s, col)
+#ifdef FEAT_LINEBREAK
+    }
+    return win_lbr_chartabsize(curwin, s, col, NULL);
+#endif
+}
+
+/*
+ * Call lbr_chartabsize() and advance the pointer.
+ */
+    int
+lbr_chartabsize_adv(s, col)
+    char_u	**s;
+    colnr_T	col;
+{
+    int		retval;
+
+    retval = lbr_chartabsize(*s, col);
+    mb_ptr_adv(*s);
+    return retval;
+}
+
+/*
+ * This function is used very often, keep it fast!!!!
+ *
+ * If "headp" not NULL, set *headp to the size of what we for 'showbreak'
+ * string at start of line.  Warning: *headp is only set if it's a non-zero
+ * value, init to 0 before calling.
+ */
+/*ARGSUSED*/
+    int
+win_lbr_chartabsize(wp, s, col, headp)
+    win_T	*wp;
+    char_u	*s;
+    colnr_T	col;
+    int		*headp;
+{
+#ifdef FEAT_LINEBREAK
+    int		c;
+    int		size;
+    colnr_T	col2;
+    colnr_T	colmax;
+    int		added;
+# ifdef FEAT_MBYTE
+    int		mb_added = 0;
+# else
+#  define mb_added 0
+# endif
+    int		numberextra;
+    char_u	*ps;
+    int		tab_corr = (*s == TAB);
+    int		n;
+
+    /*
+     * No 'linebreak' and 'showbreak': return quickly.
+     */
+    if (!wp->w_p_lbr && *p_sbr == NUL)
+#endif
+    {
+#ifdef FEAT_MBYTE
+	if (wp->w_p_wrap)
+	    return win_nolbr_chartabsize(wp, s, col, headp);
+#endif
+	RET_WIN_BUF_CHARTABSIZE(wp, wp->w_buffer, s, col)
+    }
+
+#ifdef FEAT_LINEBREAK
+    /*
+     * First get normal size, without 'linebreak'
+     */
+    size = win_chartabsize(wp, s, col);
+    c = *s;
+
+    /*
+     * If 'linebreak' set check at a blank before a non-blank if the line
+     * needs a break here
+     */
+    if (wp->w_p_lbr
+	    && vim_isbreak(c)
+	    && !vim_isbreak(s[1])
+	    && !wp->w_p_list
+	    && wp->w_p_wrap
+# ifdef FEAT_VERTSPLIT
+	    && wp->w_width != 0
+# endif
+       )
+    {
+	/*
+	 * Count all characters from first non-blank after a blank up to next
+	 * non-blank after a blank.
+	 */
+	numberextra = win_col_off(wp);
+	col2 = col;
+	colmax = W_WIDTH(wp) - numberextra;
+	if (col >= colmax)
+	{
+	    n = colmax + win_col_off2(wp);
+	    if (n > 0)
+		colmax += (((col - colmax) / n) + 1) * n;
+	}
+
+	for (;;)
+	{
+	    ps = s;
+	    mb_ptr_adv(s);
+	    c = *s;
+	    if (!(c != NUL
+		    && (vim_isbreak(c)
+			|| (!vim_isbreak(c)
+			    && (col2 == col || !vim_isbreak(*ps))))))
+		break;
+
+	    col2 += win_chartabsize(wp, s, col2);
+	    if (col2 >= colmax)		/* doesn't fit */
+	    {
+		size = colmax - col;
+		tab_corr = FALSE;
+		break;
+	    }
+	}
+    }
+# ifdef FEAT_MBYTE
+    else if (has_mbyte && size == 2 && MB_BYTE2LEN(*s) > 1
+				    && wp->w_p_wrap && in_win_border(wp, col))
+    {
+	++size;		/* Count the ">" in the last column. */
+	mb_added = 1;
+    }
+# endif
+
+    /*
+     * May have to add something for 'showbreak' string at start of line
+     * Set *headp to the size of what we add.
+     */
+    added = 0;
+    if (*p_sbr != NUL && wp->w_p_wrap && col != 0)
+    {
+	numberextra = win_col_off(wp);
+	col += numberextra + mb_added;
+	if (col >= (colnr_T)W_WIDTH(wp))
+	{
+	    col -= W_WIDTH(wp);
+	    numberextra = W_WIDTH(wp) - (numberextra - win_col_off2(wp));
+	    if (numberextra > 0)
+		col = col % numberextra;
+	}
+	if (col == 0 || col + size > (colnr_T)W_WIDTH(wp))
+	{
+	    added = vim_strsize(p_sbr);
+	    if (tab_corr)
+		size += (added / wp->w_buffer->b_p_ts) * wp->w_buffer->b_p_ts;
+	    else
+		size += added;
+	    if (col != 0)
+		added = 0;
+	}
+    }
+    if (headp != NULL)
+	*headp = added + mb_added;
+    return size;
+#endif
+}
+
+#if defined(FEAT_MBYTE) || defined(PROTO)
+/*
+ * Like win_lbr_chartabsize(), except that we know 'linebreak' is off and
+ * 'wrap' is on.  This means we need to check for a double-byte character that
+ * doesn't fit at the end of the screen line.
+ */
+    static int
+win_nolbr_chartabsize(wp, s, col, headp)
+    win_T	*wp;
+    char_u	*s;
+    colnr_T	col;
+    int		*headp;
+{
+    int		n;
+
+    if (*s == TAB && (!wp->w_p_list || lcs_tab1))
+    {
+	n = wp->w_buffer->b_p_ts;
+	return (int)(n - (col % n));
+    }
+    n = ptr2cells(s);
+    /* Add one cell for a double-width character in the last column of the
+     * window, displayed with a ">". */
+    if (n == 2 && MB_BYTE2LEN(*s) > 1 && in_win_border(wp, col))
+    {
+	if (headp != NULL)
+	    *headp = 1;
+	return 3;
+    }
+    return n;
+}
+
+/*
+ * Return TRUE if virtual column "vcol" is in the rightmost column of window
+ * "wp".
+ */
+    int
+in_win_border(wp, vcol)
+    win_T	*wp;
+    colnr_T	vcol;
+{
+    colnr_T	width1;		/* width of first line (after line number) */
+    colnr_T	width2;		/* width of further lines */
+
+#ifdef FEAT_VERTSPLIT
+    if (wp->w_width == 0)	/* there is no border */
+	return FALSE;
+#endif
+    width1 = W_WIDTH(wp) - win_col_off(wp);
+    if (vcol < width1 - 1)
+	return FALSE;
+    if (vcol == width1 - 1)
+	return TRUE;
+    width2 = width1 + win_col_off2(wp);
+    return ((vcol - width1) % width2 == width2 - 1);
+}
+#endif /* FEAT_MBYTE */
+
+/*
+ * Get virtual column number of pos.
+ *  start: on the first position of this character (TAB, ctrl)
+ * cursor: where the cursor is on this character (first char, except for TAB)
+ *    end: on the last position of this character (TAB, ctrl)
+ *
+ * This is used very often, keep it fast!
+ */
+    void
+getvcol(wp, pos, start, cursor, end)
+    win_T	*wp;
+    pos_T	*pos;
+    colnr_T	*start;
+    colnr_T	*cursor;
+    colnr_T	*end;
+{
+    colnr_T	vcol;
+    char_u	*ptr;		/* points to current char */
+    char_u	*posptr;	/* points to char at pos->col */
+    int		incr;
+    int		head;
+    int		ts = wp->w_buffer->b_p_ts;
+    int		c;
+
+    vcol = 0;
+    ptr = ml_get_buf(wp->w_buffer, pos->lnum, FALSE);
+    posptr = ptr + pos->col;
+
+    /*
+     * This function is used very often, do some speed optimizations.
+     * When 'list', 'linebreak' and 'showbreak' are not set use a simple loop.
+     * Also use this when 'list' is set but tabs take their normal size.
+     */
+    if ((!wp->w_p_list || lcs_tab1 != NUL)
+#ifdef FEAT_LINEBREAK
+	    && !wp->w_p_lbr && *p_sbr == NUL
+#endif
+       )
+    {
+#ifndef FEAT_MBYTE
+	head = 0;
+#endif
+	for (;;)
+	{
+#ifdef FEAT_MBYTE
+	    head = 0;
+#endif
+	    c = *ptr;
+	    /* make sure we don't go past the end of the line */
+	    if (c == NUL)
+	    {
+		incr = 1;	/* NUL at end of line only takes one column */
+		break;
+	    }
+	    /* A tab gets expanded, depending on the current column */
+	    if (c == TAB)
+		incr = ts - (vcol % ts);
+	    else
+	    {
+#ifdef FEAT_MBYTE
+		if (has_mbyte)
+		{
+		    /* For utf-8, if the byte is >= 0x80, need to look at
+		     * further bytes to find the cell width. */
+		    if (enc_utf8 && c >= 0x80)
+			incr = utf_ptr2cells(ptr);
+		    else
+			incr = CHARSIZE(c);
+
+		    /* If a double-cell char doesn't fit at the end of a line
+		     * it wraps to the next line, it's like this char is three
+		     * cells wide. */
+		    if (incr == 2 && wp->w_p_wrap && in_win_border(wp, vcol))
+		    {
+			++incr;
+			head = 1;
+		    }
+		}
+		else
+#endif
+		    incr = CHARSIZE(c);
+	    }
+
+	    if (ptr >= posptr)	/* character at pos->col */
+		break;
+
+	    vcol += incr;
+	    mb_ptr_adv(ptr);
+	}
+    }
+    else
+    {
+	for (;;)
+	{
+	    /* A tab gets expanded, depending on the current column */
+	    head = 0;
+	    incr = win_lbr_chartabsize(wp, ptr, vcol, &head);
+	    /* make sure we don't go past the end of the line */
+	    if (*ptr == NUL)
+	    {
+		incr = 1;	/* NUL at end of line only takes one column */
+		break;
+	    }
+
+	    if (ptr >= posptr)	/* character at pos->col */
+		break;
+
+	    vcol += incr;
+	    mb_ptr_adv(ptr);
+	}
+    }
+    if (start != NULL)
+	*start = vcol + head;
+    if (end != NULL)
+	*end = vcol + incr - 1;
+    if (cursor != NULL)
+    {
+	if (*ptr == TAB
+		&& (State & NORMAL)
+		&& !wp->w_p_list
+		&& !virtual_active()
+#ifdef FEAT_VISUAL
+		&& !(VIsual_active
+				   && (*p_sel == 'e' || ltoreq(*pos, VIsual)))
+#endif
+		)
+	    *cursor = vcol + incr - 1;	    /* cursor at end */
+	else
+	    *cursor = vcol + head;	    /* cursor at start */
+    }
+}
+
+/*
+ * Get virtual cursor column in the current window, pretending 'list' is off.
+ */
+    colnr_T
+getvcol_nolist(posp)
+    pos_T	*posp;
+{
+    int		list_save = curwin->w_p_list;
+    colnr_T	vcol;
+
+    curwin->w_p_list = FALSE;
+    getvcol(curwin, posp, NULL, &vcol, NULL);
+    curwin->w_p_list = list_save;
+    return vcol;
+}
+
+#if defined(FEAT_VIRTUALEDIT) || defined(PROTO)
+/*
+ * Get virtual column in virtual mode.
+ */
+    void
+getvvcol(wp, pos, start, cursor, end)
+    win_T	*wp;
+    pos_T	*pos;
+    colnr_T	*start;
+    colnr_T	*cursor;
+    colnr_T	*end;
+{
+    colnr_T	col;
+    colnr_T	coladd;
+    colnr_T	endadd;
+# ifdef FEAT_MBYTE
+    char_u	*ptr;
+# endif
+
+    if (virtual_active())
+    {
+	/* For virtual mode, only want one value */
+	getvcol(wp, pos, &col, NULL, NULL);
+
+	coladd = pos->coladd;
+	endadd = 0;
+# ifdef FEAT_MBYTE
+	/* Cannot put the cursor on part of a wide character. */
+	ptr = ml_get_buf(wp->w_buffer, pos->lnum, FALSE);
+	if (pos->col < STRLEN(ptr))
+	{
+	    int c = (*mb_ptr2char)(ptr + pos->col);
+
+	    if (c != TAB && vim_isprintc(c))
+	    {
+		endadd = char2cells(c) - 1;
+		if (coladd > endadd)	/* past end of line */
+		    endadd = 0;
+		else
+		    coladd = 0;
+	    }
+	}
+# endif
+	col += coladd;
+	if (start != NULL)
+	    *start = col;
+	if (cursor != NULL)
+	    *cursor = col;
+	if (end != NULL)
+	    *end = col + endadd;
+    }
+    else
+	getvcol(wp, pos, start, cursor, end);
+}
+#endif
+
+#if defined(FEAT_VISUAL) || defined(PROTO)
+/*
+ * Get the leftmost and rightmost virtual column of pos1 and pos2.
+ * Used for Visual block mode.
+ */
+    void
+getvcols(wp, pos1, pos2, left, right)
+    win_T	*wp;
+    pos_T	*pos1, *pos2;
+    colnr_T	*left, *right;
+{
+    colnr_T	from1, from2, to1, to2;
+
+    if (ltp(pos1, pos2))
+    {
+	getvvcol(wp, pos1, &from1, NULL, &to1);
+	getvvcol(wp, pos2, &from2, NULL, &to2);
+    }
+    else
+    {
+	getvvcol(wp, pos2, &from1, NULL, &to1);
+	getvvcol(wp, pos1, &from2, NULL, &to2);
+    }
+    if (from2 < from1)
+	*left = from2;
+    else
+	*left = from1;
+    if (to2 > to1)
+    {
+	if (*p_sel == 'e' && from2 - 1 >= to1)
+	    *right = from2 - 1;
+	else
+	    *right = to2;
+    }
+    else
+	*right = to1;
+}
+#endif
+
+/*
+ * skipwhite: skip over ' ' and '\t'.
+ */
+    char_u *
+skipwhite(p)
+    char_u	*p;
+{
+    while (vim_iswhite(*p)) /* skip to next non-white */
+	++p;
+    return p;
+}
+
+/*
+ * skip over digits
+ */
+    char_u *
+skipdigits(p)
+    char_u	*p;
+{
+    while (VIM_ISDIGIT(*p))	/* skip to next non-digit */
+	++p;
+    return p;
+}
+
+#if defined(FEAT_SYN_HL) || defined(FEAT_SPELL) || defined(PROTO)
+/*
+ * skip over digits and hex characters
+ */
+    char_u *
+skiphex(p)
+    char_u	*p;
+{
+    while (vim_isxdigit(*p))	/* skip to next non-digit */
+	++p;
+    return p;
+}
+#endif
+
+#if defined(FEAT_EX_EXTRA) || defined(PROTO)
+/*
+ * skip to digit (or NUL after the string)
+ */
+    char_u *
+skiptodigit(p)
+    char_u	*p;
+{
+    while (*p != NUL && !VIM_ISDIGIT(*p))	/* skip to next digit */
+	++p;
+    return p;
+}
+
+/*
+ * skip to hex character (or NUL after the string)
+ */
+    char_u *
+skiptohex(p)
+    char_u	*p;
+{
+    while (*p != NUL && !vim_isxdigit(*p))	/* skip to next digit */
+	++p;
+    return p;
+}
+#endif
+
+/*
+ * Variant of isdigit() that can handle characters > 0x100.
+ * We don't use isdigit() here, because on some systems it also considers
+ * superscript 1 to be a digit.
+ * Use the VIM_ISDIGIT() macro for simple arguments.
+ */
+    int
+vim_isdigit(c)
+    int		c;
+{
+    return (c >= '0' && c <= '9');
+}
+
+/*
+ * Variant of isxdigit() that can handle characters > 0x100.
+ * We don't use isxdigit() here, because on some systems it also considers
+ * superscript 1 to be a digit.
+ */
+    int
+vim_isxdigit(c)
+    int		c;
+{
+    return (c >= '0' && c <= '9')
+	|| (c >= 'a' && c <= 'f')
+	|| (c >= 'A' && c <= 'F');
+}
+
+#if defined(FEAT_MBYTE) || defined(PROTO)
+/*
+ * Vim's own character class functions.  These exist because many library
+ * islower()/toupper() etc. do not work properly: they crash when used with
+ * invalid values or can't handle latin1 when the locale is C.
+ * Speed is most important here.
+ */
+#define LATIN1LOWER 'l'
+#define LATIN1UPPER 'U'
+
+static char_u latin1flags[257] = "                                                                 UUUUUUUUUUUUUUUUUUUUUUUUUU      llllllllllllllllllllllllll                                                                     UUUUUUUUUUUUUUUUUUUUUUU UUUUUUUllllllllllllllllllllllll llllllll";
+static char_u latin1upper[257] = "                                 !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`ABCDEFGHIJKLMNOPQRSTUVWXYZ{|}~\x7f\x80\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8a\x8b\x8c\x8d\x8e\x8f\x90\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9a\x9b\x9c\x9d\x9e\x9f\xa0\xa1\xa2\xa3\xa4\xa5\xa6\xa7\xa8\xa9\xaa\xab\xac\xad\xae\xaf\xb0\xb1\xb2\xb3\xb4\xb5\xb6\xb7\xb8\xb9\xba\xbb\xbc\xbd\xbe\xbf\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf\xd0\xd1\xd2\xd3\xd4\xd5\xd6\xd7\xd8\xd9\xda\xdb\xdc\xdd\xde\xdf\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf\xd0\xd1\xd2\xd3\xd4\xd5\xd6\xf7\xd8\xd9\xda\xdb\xdc\xdd\xde\xff";
+static char_u latin1lower[257] = "                                 !\"#$%&'()*+,-./0123456789:;<=>?@abcdefghijklmnopqrstuvwxyz[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\x7f\x80\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8a\x8b\x8c\x8d\x8e\x8f\x90\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9a\x9b\x9c\x9d\x9e\x9f\xa0\xa1\xa2\xa3\xa4\xa5\xa6\xa7\xa8\xa9\xaa\xab\xac\xad\xae\xaf\xb0\xb1\xb2\xb3\xb4\xb5\xb6\xb7\xb8\xb9\xba\xbb\xbc\xbd\xbe\xbf\xe0\xe1\xe2\xe3\xe4\xe5\xe6\xe7\xe8\xe9\xea\xeb\xec\xed\xee\xef\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xd7\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xdf\xe0\xe1\xe2\xe3\xe4\xe5\xe6\xe7\xe8\xe9\xea\xeb\xec\xed\xee\xef\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff";
+
+    int
+vim_islower(c)
+    int	    c;
+{
+    if (c <= '@')
+	return FALSE;
+    if (c >= 0x80)
+    {
+	if (enc_utf8)
+	    return utf_islower(c);
+	if (c >= 0x100)
+	{
+#ifdef HAVE_ISWLOWER
+	    if (has_mbyte)
+		return iswlower(c);
+#endif
+	    /* islower() can't handle these chars and may crash */
+	    return FALSE;
+	}
+	if (enc_latin1like)
+	    return (latin1flags[c] & LATIN1LOWER) == LATIN1LOWER;
+    }
+    return islower(c);
+}
+
+    int
+vim_isupper(c)
+    int	    c;
+{
+    if (c <= '@')
+	return FALSE;
+    if (c >= 0x80)
+    {
+	if (enc_utf8)
+	    return utf_isupper(c);
+	if (c >= 0x100)
+	{
+#ifdef HAVE_ISWUPPER
+	    if (has_mbyte)
+		return iswupper(c);
+#endif
+	    /* islower() can't handle these chars and may crash */
+	    return FALSE;
+	}
+	if (enc_latin1like)
+	    return (latin1flags[c] & LATIN1UPPER) == LATIN1UPPER;
+    }
+    return isupper(c);
+}
+
+    int
+vim_toupper(c)
+    int	    c;
+{
+    if (c <= '@')
+	return c;
+    if (c >= 0x80)
+    {
+	if (enc_utf8)
+	    return utf_toupper(c);
+	if (c >= 0x100)
+	{
+#ifdef HAVE_TOWUPPER
+	    if (has_mbyte)
+		return towupper(c);
+#endif
+	    /* toupper() can't handle these chars and may crash */
+	    return c;
+	}
+	if (enc_latin1like)
+	    return latin1upper[c];
+    }
+    return TOUPPER_LOC(c);
+}
+
+    int
+vim_tolower(c)
+    int	    c;
+{
+    if (c <= '@')
+	return c;
+    if (c >= 0x80)
+    {
+	if (enc_utf8)
+	    return utf_tolower(c);
+	if (c >= 0x100)
+	{
+#ifdef HAVE_TOWLOWER
+	    if (has_mbyte)
+		return towlower(c);
+#endif
+	    /* tolower() can't handle these chars and may crash */
+	    return c;
+	}
+	if (enc_latin1like)
+	    return latin1lower[c];
+    }
+    return TOLOWER_LOC(c);
+}
+#endif
+
+/*
+ * skiptowhite: skip over text until ' ' or '\t' or NUL.
+ */
+    char_u *
+skiptowhite(p)
+    char_u	*p;
+{
+    while (*p != ' ' && *p != '\t' && *p != NUL)
+	++p;
+    return p;
+}
+
+#if defined(FEAT_LISTCMDS) || defined(FEAT_SIGNS) || defined(FEAT_SNIFF) \
+	|| defined(PROTO)
+/*
+ * skiptowhite_esc: Like skiptowhite(), but also skip escaped chars
+ */
+    char_u *
+skiptowhite_esc(p)
+    char_u	*p;
+{
+    while (*p != ' ' && *p != '\t' && *p != NUL)
+    {
+	if ((*p == '\\' || *p == Ctrl_V) && *(p + 1) != NUL)
+	    ++p;
+	++p;
+    }
+    return p;
+}
+#endif
+
+/*
+ * Getdigits: Get a number from a string and skip over it.
+ * Note: the argument is a pointer to a char_u pointer!
+ */
+    long
+getdigits(pp)
+    char_u **pp;
+{
+    char_u	*p;
+    long	retval;
+
+    p = *pp;
+    retval = atol((char *)p);
+    if (*p == '-')		/* skip negative sign */
+	++p;
+    p = skipdigits(p);		/* skip to next non-digit */
+    *pp = p;
+    return retval;
+}
+
+/*
+ * Return TRUE if "lbuf" is empty or only contains blanks.
+ */
+    int
+vim_isblankline(lbuf)
+    char_u	*lbuf;
+{
+    char_u	*p;
+
+    p = skipwhite(lbuf);
+    return (*p == NUL || *p == '\r' || *p == '\n');
+}
+
+/*
+ * Convert a string into a long and/or unsigned long, taking care of
+ * hexadecimal and octal numbers.  Accepts a '-' sign.
+ * If "hexp" is not NULL, returns a flag to indicate the type of the number:
+ *  0	    decimal
+ *  '0'	    octal
+ *  'X'	    hex
+ *  'x'	    hex
+ * If "len" is not NULL, the length of the number in characters is returned.
+ * If "nptr" is not NULL, the signed result is returned in it.
+ * If "unptr" is not NULL, the unsigned result is returned in it.
+ * If "unptr" is not NULL, the unsigned result is returned in it.
+ * If "dooct" is non-zero recognize octal numbers, when > 1 always assume
+ * octal number.
+ * If "dohex" is non-zero recognize hex numbers, when > 1 always assume
+ * hex number.
+ */
+    void
+vim_str2nr(start, hexp, len, dooct, dohex, nptr, unptr)
+    char_u		*start;
+    int			*hexp;	    /* return: type of number 0 = decimal, 'x'
+				       or 'X' is hex, '0' = octal */
+    int			*len;	    /* return: detected length of number */
+    int			dooct;	    /* recognize octal number */
+    int			dohex;	    /* recognize hex number */
+    long		*nptr;	    /* return: signed result */
+    unsigned long	*unptr;	    /* return: unsigned result */
+{
+    char_u	    *ptr = start;
+    int		    hex = 0;		/* default is decimal */
+    int		    negative = FALSE;
+    unsigned long   un = 0;
+    int		    n;
+
+    if (ptr[0] == '-')
+    {
+	negative = TRUE;
+	++ptr;
+    }
+
+    /* Recognize hex and octal. */
+    if (ptr[0] == '0' && ptr[1] != '8' && ptr[1] != '9')
+    {
+	hex = ptr[1];
+	if (dohex && (hex == 'X' || hex == 'x') && vim_isxdigit(ptr[2]))
+	    ptr += 2;			/* hexadecimal */
+	else
+	{
+	    hex = 0;			/* default is decimal */
+	    if (dooct)
+	    {
+		/* Don't interpret "0", "08" or "0129" as octal. */
+		for (n = 1; VIM_ISDIGIT(ptr[n]); ++n)
+		{
+		    if (ptr[n] > '7')
+		    {
+			hex = 0;	/* can't be octal */
+			break;
+		    }
+		    if (ptr[n] > '0')
+			hex = '0';	/* assume octal */
+		}
+	    }
+	}
+    }
+
+    /*
+     * Do the string-to-numeric conversion "manually" to avoid sscanf quirks.
+     */
+    if (hex == '0' || dooct > 1)
+    {
+	/* octal */
+	while ('0' <= *ptr && *ptr <= '7')
+	{
+	    un = 8 * un + (unsigned long)(*ptr - '0');
+	    ++ptr;
+	}
+    }
+    else if (hex != 0 || dohex > 1)
+    {
+	/* hex */
+	while (vim_isxdigit(*ptr))
+	{
+	    un = 16 * un + (unsigned long)hex2nr(*ptr);
+	    ++ptr;
+	}
+    }
+    else
+    {
+	/* decimal */
+	while (VIM_ISDIGIT(*ptr))
+	{
+	    un = 10 * un + (unsigned long)(*ptr - '0');
+	    ++ptr;
+	}
+    }
+
+    if (hexp != NULL)
+	*hexp = hex;
+    if (len != NULL)
+	*len = (int)(ptr - start);
+    if (nptr != NULL)
+    {
+	if (negative)   /* account for leading '-' for decimal numbers */
+	    *nptr = -(long)un;
+	else
+	    *nptr = (long)un;
+    }
+    if (unptr != NULL)
+	*unptr = un;
+}
+
+/*
+ * Return the value of a single hex character.
+ * Only valid when the argument is '0' - '9', 'A' - 'F' or 'a' - 'f'.
+ */
+    int
+hex2nr(c)
+    int		c;
+{
+    if (c >= 'a' && c <= 'f')
+	return c - 'a' + 10;
+    if (c >= 'A' && c <= 'F')
+	return c - 'A' + 10;
+    return c - '0';
+}
+
+#if defined(FEAT_TERMRESPONSE) \
+	|| (defined(FEAT_GUI_GTK) && defined(FEAT_WINDOWS)) || defined(PROTO)
+/*
+ * Convert two hex characters to a byte.
+ * Return -1 if one of the characters is not hex.
+ */
+    int
+hexhex2nr(p)
+    char_u	*p;
+{
+    if (!vim_isxdigit(p[0]) || !vim_isxdigit(p[1]))
+	return -1;
+    return (hex2nr(p[0]) << 4) + hex2nr(p[1]);
+}
+#endif
+
+/*
+ * Return TRUE if "str" starts with a backslash that should be removed.
+ * For MS-DOS, WIN32 and OS/2 this is only done when the character after the
+ * backslash is not a normal file name character.
+ * '$' is a valid file name character, we don't remove the backslash before
+ * it.  This means it is not possible to use an environment variable after a
+ * backslash.  "C:\$VIM\doc" is taken literally, only "$VIM\doc" works.
+ * Although "\ name" is valid, the backslash in "Program\ files" must be
+ * removed.  Assume a file name doesn't start with a space.
+ * For multi-byte names, never remove a backslash before a non-ascii
+ * character, assume that all multi-byte characters are valid file name
+ * characters.
+ */
+    int
+rem_backslash(str)
+    char_u  *str;
+{
+#ifdef BACKSLASH_IN_FILENAME
+    return (str[0] == '\\'
+# ifdef FEAT_MBYTE
+	    && str[1] < 0x80
+# endif
+	    && (str[1] == ' '
+		|| (str[1] != NUL
+		    && str[1] != '*'
+		    && str[1] != '?'
+		    && !vim_isfilec(str[1]))));
+#else
+    return (str[0] == '\\' && str[1] != NUL);
+#endif
+}
+
+/*
+ * Halve the number of backslashes in a file name argument.
+ * For MS-DOS we only do this if the character after the backslash
+ * is not a normal file character.
+ */
+    void
+backslash_halve(p)
+    char_u	*p;
+{
+    for ( ; *p; ++p)
+	if (rem_backslash(p))
+	    STRCPY(p, p + 1);
+}
+
+/*
+ * backslash_halve() plus save the result in allocated memory.
+ */
+    char_u *
+backslash_halve_save(p)
+    char_u	*p;
+{
+    char_u	*res;
+
+    res = vim_strsave(p);
+    if (res == NULL)
+	return p;
+    backslash_halve(res);
+    return res;
+}
+
+#if (defined(EBCDIC) && defined(FEAT_POSTSCRIPT)) || defined(PROTO)
+/*
+ * Table for EBCDIC to ASCII conversion unashamedly taken from xxd.c!
+ * The first 64 entries have been added to map control characters defined in
+ * ascii.h
+ */
+static char_u ebcdic2ascii_tab[256] =
+{
+    0000, 0001, 0002, 0003, 0004, 0011, 0006, 0177,
+    0010, 0011, 0012, 0013, 0014, 0015, 0016, 0017,
+    0020, 0021, 0022, 0023, 0024, 0012, 0010, 0027,
+    0030, 0031, 0032, 0033, 0033, 0035, 0036, 0037,
+    0040, 0041, 0042, 0043, 0044, 0045, 0046, 0047,
+    0050, 0051, 0052, 0053, 0054, 0055, 0056, 0057,
+    0060, 0061, 0062, 0063, 0064, 0065, 0066, 0067,
+    0070, 0071, 0072, 0073, 0074, 0075, 0076, 0077,
+    0040, 0240, 0241, 0242, 0243, 0244, 0245, 0246,
+    0247, 0250, 0325, 0056, 0074, 0050, 0053, 0174,
+    0046, 0251, 0252, 0253, 0254, 0255, 0256, 0257,
+    0260, 0261, 0041, 0044, 0052, 0051, 0073, 0176,
+    0055, 0057, 0262, 0263, 0264, 0265, 0266, 0267,
+    0270, 0271, 0313, 0054, 0045, 0137, 0076, 0077,
+    0272, 0273, 0274, 0275, 0276, 0277, 0300, 0301,
+    0302, 0140, 0072, 0043, 0100, 0047, 0075, 0042,
+    0303, 0141, 0142, 0143, 0144, 0145, 0146, 0147,
+    0150, 0151, 0304, 0305, 0306, 0307, 0310, 0311,
+    0312, 0152, 0153, 0154, 0155, 0156, 0157, 0160,
+    0161, 0162, 0136, 0314, 0315, 0316, 0317, 0320,
+    0321, 0345, 0163, 0164, 0165, 0166, 0167, 0170,
+    0171, 0172, 0322, 0323, 0324, 0133, 0326, 0327,
+    0330, 0331, 0332, 0333, 0334, 0335, 0336, 0337,
+    0340, 0341, 0342, 0343, 0344, 0135, 0346, 0347,
+    0173, 0101, 0102, 0103, 0104, 0105, 0106, 0107,
+    0110, 0111, 0350, 0351, 0352, 0353, 0354, 0355,
+    0175, 0112, 0113, 0114, 0115, 0116, 0117, 0120,
+    0121, 0122, 0356, 0357, 0360, 0361, 0362, 0363,
+    0134, 0237, 0123, 0124, 0125, 0126, 0127, 0130,
+    0131, 0132, 0364, 0365, 0366, 0367, 0370, 0371,
+    0060, 0061, 0062, 0063, 0064, 0065, 0066, 0067,
+    0070, 0071, 0372, 0373, 0374, 0375, 0376, 0377
+};
+
+/*
+ * Convert a buffer worth of characters from EBCDIC to ASCII.  Only useful if
+ * wanting 7-bit ASCII characters out the other end.
+ */
+    void
+ebcdic2ascii(buffer, len)
+    char_u	*buffer;
+    int		len;
+{
+    int		i;
+
+    for (i = 0; i < len; i++)
+	buffer[i] = ebcdic2ascii_tab[buffer[i]];
+}
+#endif
--- /dev/null
+++ b/diff.c
@@ -1,0 +1,2458 @@
+/* vim:set ts=8 sts=4 sw=4:
+ *
+ * VIM - Vi IMproved	by Bram Moolenaar
+ *
+ * Do ":help uganda"  in Vim to read copying and usage conditions.
+ * Do ":help credits" in Vim to see a list of people who contributed.
+ * See README.txt for an overview of the Vim source code.
+ */
+
+/*
+ * diff.c: code for diff'ing two or three buffers.
+ */
+
+#include "vim.h"
+
+#if defined(FEAT_DIFF) || defined(PROTO)
+
+static int	diff_busy = FALSE;	/* ex_diffgetput() is busy */
+
+/* flags obtained from the 'diffopt' option */
+#define DIFF_FILLER	1	/* display filler lines */
+#define DIFF_ICASE	2	/* ignore case */
+#define DIFF_IWHITE	4	/* ignore change in white space */
+#define DIFF_HORIZONTAL	8	/* horizontal splits */
+#define DIFF_VERTICAL	16	/* vertical splits */
+static int	diff_flags = DIFF_FILLER;
+
+#define LBUFLEN 50		/* length of line in diff file */
+
+static int diff_a_works = MAYBE; /* TRUE when "diff -a" works, FALSE when it
+				    doesn't work, MAYBE when not checked yet */
+#if defined(MSWIN) || defined(MSDOS)
+static int diff_bin_works = MAYBE; /* TRUE when "diff --binary" works, FALSE
+				      when it doesn't work, MAYBE when not
+				      checked yet */
+#endif
+
+static int diff_buf_idx __ARGS((buf_T *buf));
+static int diff_buf_idx_tp __ARGS((buf_T *buf, tabpage_T *tp));
+static void diff_mark_adjust_tp __ARGS((tabpage_T *tp, int idx, linenr_T line1, linenr_T line2, long amount, long amount_after));
+static void diff_check_unchanged __ARGS((tabpage_T *tp, diff_T *dp));
+static int diff_check_sanity __ARGS((tabpage_T *tp, diff_T *dp));
+static void diff_redraw __ARGS((int dofold));
+static int diff_write __ARGS((buf_T *buf, char_u *fname));
+static void diff_file __ARGS((char_u *tmp_orig, char_u *tmp_new, char_u *tmp_diff));
+static int diff_equal_entry __ARGS((diff_T *dp, int idx1, int idx2));
+static int diff_cmp __ARGS((char_u *s1, char_u *s2));
+#ifdef FEAT_FOLDING
+static void diff_fold_update __ARGS((diff_T *dp, int skip_idx));
+#endif
+static void diff_read __ARGS((int idx_orig, int idx_new, char_u *fname));
+static void diff_copy_entry __ARGS((diff_T *dprev, diff_T *dp, int idx_orig, int idx_new));
+static diff_T *diff_alloc_new __ARGS((tabpage_T *tp, diff_T *dprev, diff_T *dp));
+
+#ifndef USE_CR
+# define tag_fgets vim_fgets
+#endif
+
+/*
+ * Called when deleting or unloading a buffer: No longer make a diff with it.
+ */
+    void
+diff_buf_delete(buf)
+    buf_T	*buf;
+{
+    int		i;
+    tabpage_T	*tp;
+
+    for (tp = first_tabpage; tp != NULL; tp = tp->tp_next)
+    {
+	i = diff_buf_idx_tp(buf, tp);
+	if (i != DB_COUNT)
+	{
+	    tp->tp_diffbuf[i] = NULL;
+	    tp->tp_diff_invalid = TRUE;
+	}
+    }
+}
+
+/*
+ * Check if the current buffer should be added to or removed from the list of
+ * diff buffers.
+ */
+    void
+diff_buf_adjust(win)
+    win_T	*win;
+{
+    win_T	*wp;
+    int		i;
+
+    if (!win->w_p_diff)
+    {
+	/* When there is no window showing a diff for this buffer, remove
+	 * it from the diffs. */
+	for (wp = firstwin; wp != NULL; wp = wp->w_next)
+	    if (wp->w_buffer == win->w_buffer && wp->w_p_diff)
+		break;
+	if (wp == NULL)
+	{
+	    i = diff_buf_idx(win->w_buffer);
+	    if (i != DB_COUNT)
+	    {
+		curtab->tp_diffbuf[i] = NULL;
+		curtab->tp_diff_invalid = TRUE;
+	    }
+	}
+    }
+    else
+	diff_buf_add(win->w_buffer);
+}
+
+/*
+ * Add a buffer to make diffs for.
+ * Call this when a new buffer is being edited in the current window where
+ * 'diff' is set.
+ * Marks the current buffer as being part of the diff and requireing updating.
+ * This must be done before any autocmd, because a command may use info
+ * about the screen contents.
+ */
+    void
+diff_buf_add(buf)
+    buf_T	*buf;
+{
+    int		i;
+
+    if (diff_buf_idx(buf) != DB_COUNT)
+	return;		/* It's already there. */
+
+    for (i = 0; i < DB_COUNT; ++i)
+	if (curtab->tp_diffbuf[i] == NULL)
+	{
+	    curtab->tp_diffbuf[i] = buf;
+	    curtab->tp_diff_invalid = TRUE;
+	    return;
+	}
+
+    EMSGN(_("E96: Can not diff more than %ld buffers"), DB_COUNT);
+}
+
+/*
+ * Find buffer "buf" in the list of diff buffers for the current tab page.
+ * Return its index or DB_COUNT if not found.
+ */
+    static int
+diff_buf_idx(buf)
+    buf_T	*buf;
+{
+    int		idx;
+
+    for (idx = 0; idx < DB_COUNT; ++idx)
+	if (curtab->tp_diffbuf[idx] == buf)
+	    break;
+    return idx;
+}
+
+/*
+ * Find buffer "buf" in the list of diff buffers for tab page "tp".
+ * Return its index or DB_COUNT if not found.
+ */
+    static int
+diff_buf_idx_tp(buf, tp)
+    buf_T	*buf;
+    tabpage_T	*tp;
+{
+    int		idx;
+
+    for (idx = 0; idx < DB_COUNT; ++idx)
+	if (tp->tp_diffbuf[idx] == buf)
+	    break;
+    return idx;
+}
+
+/*
+ * Mark the diff info involving buffer "buf" as invalid, it will be updated
+ * when info is requested.
+ */
+    void
+diff_invalidate(buf)
+    buf_T	*buf;
+{
+    tabpage_T	*tp;
+    int		i;
+
+    for (tp = first_tabpage; tp != NULL; tp = tp->tp_next)
+    {
+	i = diff_buf_idx_tp(buf, tp);
+	if (i != DB_COUNT)
+	{
+	    tp->tp_diff_invalid = TRUE;
+	    if (tp == curtab)
+		diff_redraw(TRUE);
+	}
+    }
+}
+
+/*
+ * Called by mark_adjust(): update line numbers in "curbuf".
+ */
+    void
+diff_mark_adjust(line1, line2, amount, amount_after)
+    linenr_T	line1;
+    linenr_T	line2;
+    long	amount;
+    long	amount_after;
+{
+    int		idx;
+    tabpage_T	*tp;
+
+    /* Handle all tab pages that use the current buffer in a diff. */
+    for (tp = first_tabpage; tp != NULL; tp = tp->tp_next)
+    {
+	idx = diff_buf_idx_tp(curbuf, tp);
+	if (idx != DB_COUNT)
+	    diff_mark_adjust_tp(tp, idx, line1, line2, amount, amount_after);
+    }
+}
+
+/*
+ * Update line numbers in tab page "tp" for "curbuf" with index "idx".
+ * This attempts to update the changes as much as possible:
+ * When inserting/deleting lines outside of existing change blocks, create a
+ * new change block and update the line numbers in following blocks.
+ * When inserting/deleting lines in existing change blocks, update them.
+ */
+    static void
+diff_mark_adjust_tp(tp, idx, line1, line2, amount, amount_after)
+    tabpage_T	*tp;
+    int		idx;
+    linenr_T	line1;
+    linenr_T	line2;
+    long	amount;
+    long	amount_after;
+{
+    diff_T	*dp;
+    diff_T	*dprev;
+    diff_T	*dnext;
+    int		i;
+    int		inserted, deleted;
+    int		n, off;
+    linenr_T	last;
+    linenr_T	lnum_deleted = line1;	/* lnum of remaining deletion */
+    int		check_unchanged;
+
+    if (line2 == MAXLNUM)
+    {
+	/* mark_adjust(99, MAXLNUM, 9, 0): insert lines */
+	inserted = amount;
+	deleted = 0;
+    }
+    else if (amount_after > 0)
+    {
+	/* mark_adjust(99, 98, MAXLNUM, 9): a change that inserts lines*/
+	inserted = amount_after;
+	deleted = 0;
+    }
+    else
+    {
+	/* mark_adjust(98, 99, MAXLNUM, -2): delete lines */
+	inserted = 0;
+	deleted = -amount_after;
+    }
+
+    dprev = NULL;
+    dp = tp->tp_first_diff;
+    for (;;)
+    {
+	/* If the change is after the previous diff block and before the next
+	 * diff block, thus not touching an existing change, create a new diff
+	 * block.  Don't do this when ex_diffgetput() is busy. */
+	if ((dp == NULL || dp->df_lnum[idx] - 1 > line2
+		    || (line2 == MAXLNUM && dp->df_lnum[idx] > line1))
+		&& (dprev == NULL
+		    || dprev->df_lnum[idx] + dprev->df_count[idx] < line1)
+		&& !diff_busy)
+	{
+	    dnext = diff_alloc_new(tp, dprev, dp);
+	    if (dnext == NULL)
+		return;
+
+	    dnext->df_lnum[idx] = line1;
+	    dnext->df_count[idx] = inserted;
+	    for (i = 0; i < DB_COUNT; ++i)
+		if (tp->tp_diffbuf[i] != NULL && i != idx)
+		{
+		    if (dprev == NULL)
+			dnext->df_lnum[i] = line1;
+		    else
+			dnext->df_lnum[i] = line1
+			    + (dprev->df_lnum[i] + dprev->df_count[i])
+			    - (dprev->df_lnum[idx] + dprev->df_count[idx]);
+		    dnext->df_count[i] = deleted;
+		}
+	}
+
+	/* if at end of the list, quit */
+	if (dp == NULL)
+	    break;
+
+	/*
+	 * Check for these situations:
+	 *	  1  2	3
+	 *	  1  2	3
+	 * line1     2	3  4  5
+	 *	     2	3  4  5
+	 *	     2	3  4  5
+	 * line2     2	3  4  5
+	 *		3     5  6
+	 *		3     5  6
+	 */
+	/* compute last line of this change */
+	last = dp->df_lnum[idx] + dp->df_count[idx] - 1;
+
+	/* 1. change completely above line1: nothing to do */
+	if (last >= line1 - 1)
+	{
+	    /* 6. change below line2: only adjust for amount_after; also when
+	     * "deleted" became zero when deleted all lines between two diffs */
+	    if (dp->df_lnum[idx] - (deleted + inserted != 0) > line2)
+	    {
+		if (amount_after == 0)
+		    break;	/* nothing left to change */
+		dp->df_lnum[idx] += amount_after;
+	    }
+	    else
+	    {
+		check_unchanged = FALSE;
+
+		/* 2. 3. 4. 5.: inserted/deleted lines touching this diff. */
+		if (deleted > 0)
+		{
+		    if (dp->df_lnum[idx] >= line1)
+		    {
+			off = dp->df_lnum[idx] - lnum_deleted;
+			if (last <= line2)
+			{
+			    /* 4. delete all lines of diff */
+			    if (dp->df_next != NULL
+				    && dp->df_next->df_lnum[idx] - 1 <= line2)
+			    {
+				/* delete continues in next diff, only do
+				 * lines until that one */
+				n = dp->df_next->df_lnum[idx] - lnum_deleted;
+				deleted -= n;
+				n -= dp->df_count[idx];
+				lnum_deleted = dp->df_next->df_lnum[idx];
+			    }
+			    else
+				n = deleted - dp->df_count[idx];
+			    dp->df_count[idx] = 0;
+			}
+			else
+			{
+			    /* 5. delete lines at or just before top of diff */
+			    n = off;
+			    dp->df_count[idx] -= line2 - dp->df_lnum[idx] + 1;
+			    check_unchanged = TRUE;
+			}
+			dp->df_lnum[idx] = line1;
+		    }
+		    else
+		    {
+			off = 0;
+			if (last < line2)
+			{
+			    /* 2. delete at end of of diff */
+			    dp->df_count[idx] -= last - lnum_deleted + 1;
+			    if (dp->df_next != NULL
+				    && dp->df_next->df_lnum[idx] - 1 <= line2)
+			    {
+				/* delete continues in next diff, only do
+				 * lines until that one */
+				n = dp->df_next->df_lnum[idx] - 1 - last;
+				deleted -= dp->df_next->df_lnum[idx]
+							       - lnum_deleted;
+				lnum_deleted = dp->df_next->df_lnum[idx];
+			    }
+			    else
+				n = line2 - last;
+			    check_unchanged = TRUE;
+			}
+			else
+			{
+			    /* 3. delete lines inside the diff */
+			    n = 0;
+			    dp->df_count[idx] -= deleted;
+			}
+		    }
+
+		    for (i = 0; i < DB_COUNT; ++i)
+			if (tp->tp_diffbuf[i] != NULL && i != idx)
+			{
+			    dp->df_lnum[i] -= off;
+			    dp->df_count[i] += n;
+			}
+		}
+		else
+		{
+		    if (dp->df_lnum[idx] <= line1)
+		    {
+			/* inserted lines somewhere in this diff */
+			dp->df_count[idx] += inserted;
+			check_unchanged = TRUE;
+		    }
+		    else
+			/* inserted lines somewhere above this diff */
+			dp->df_lnum[idx] += inserted;
+		}
+
+		if (check_unchanged)
+		    /* Check if inserted lines are equal, may reduce the
+		     * size of the diff.  TODO: also check for equal lines
+		     * in the middle and perhaps split the block. */
+		    diff_check_unchanged(tp, dp);
+	    }
+	}
+
+	/* check if this block touches the previous one, may merge them. */
+	if (dprev != NULL && dprev->df_lnum[idx] + dprev->df_count[idx]
+							  == dp->df_lnum[idx])
+	{
+	    for (i = 0; i < DB_COUNT; ++i)
+		if (tp->tp_diffbuf[i] != NULL)
+		    dprev->df_count[i] += dp->df_count[i];
+	    dprev->df_next = dp->df_next;
+	    vim_free(dp);
+	    dp = dprev->df_next;
+	}
+	else
+	{
+	    /* Advance to next entry. */
+	    dprev = dp;
+	    dp = dp->df_next;
+	}
+    }
+
+    dprev = NULL;
+    dp = tp->tp_first_diff;
+    while (dp != NULL)
+    {
+	/* All counts are zero, remove this entry. */
+	for (i = 0; i < DB_COUNT; ++i)
+	    if (tp->tp_diffbuf[i] != NULL && dp->df_count[i] != 0)
+		break;
+	if (i == DB_COUNT)
+	{
+	    dnext = dp->df_next;
+	    vim_free(dp);
+	    dp = dnext;
+	    if (dprev == NULL)
+		tp->tp_first_diff = dnext;
+	    else
+		dprev->df_next = dnext;
+	}
+	else
+	{
+	    /* Advance to next entry. */
+	    dprev = dp;
+	    dp = dp->df_next;
+	}
+
+    }
+
+    if (tp == curtab)
+    {
+	diff_redraw(TRUE);
+
+	/* Need to recompute the scroll binding, may remove or add filler
+	 * lines (e.g., when adding lines above w_topline). But it's slow when
+	 * making many changes, postpone until redrawing. */
+	diff_need_scrollbind = TRUE;
+    }
+}
+
+/*
+ * Allocate a new diff block and link it between "dprev" and "dp".
+ */
+    static diff_T *
+diff_alloc_new(tp, dprev, dp)
+    tabpage_T	*tp;
+    diff_T	*dprev;
+    diff_T	*dp;
+{
+    diff_T	*dnew;
+
+    dnew = (diff_T *)alloc((unsigned)sizeof(diff_T));
+    if (dnew != NULL)
+    {
+	dnew->df_next = dp;
+	if (dprev == NULL)
+	    tp->tp_first_diff = dnew;
+	else
+	    dprev->df_next = dnew;
+    }
+    return dnew;
+}
+
+/*
+ * Check if the diff block "dp" can be made smaller for lines at the start and
+ * end that are equal.  Called after inserting lines.
+ * This may result in a change where all buffers have zero lines, the caller
+ * must take care of removing it.
+ */
+    static void
+diff_check_unchanged(tp, dp)
+    tabpage_T	*tp;
+    diff_T	*dp;
+{
+    int		i_org;
+    int		i_new;
+    int		off_org, off_new;
+    char_u	*line_org;
+    int		dir = FORWARD;
+
+    /* Find the first buffers, use it as the original, compare the other
+     * buffer lines against this one. */
+    for (i_org = 0; i_org < DB_COUNT; ++i_org)
+	if (tp->tp_diffbuf[i_org] != NULL)
+	    break;
+    if (i_org == DB_COUNT)	/* safety check */
+	return;
+
+    if (diff_check_sanity(tp, dp) == FAIL)
+	return;
+
+    /* First check lines at the top, then at the bottom. */
+    off_org = 0;
+    off_new = 0;
+    for (;;)
+    {
+	/* Repeat until a line is found which is different or the number of
+	 * lines has become zero. */
+	while (dp->df_count[i_org] > 0)
+	{
+	    /* Copy the line, the next ml_get() will invalidate it.  */
+	    if (dir == BACKWARD)
+		off_org = dp->df_count[i_org] - 1;
+	    line_org = vim_strsave(ml_get_buf(tp->tp_diffbuf[i_org],
+					dp->df_lnum[i_org] + off_org, FALSE));
+	    if (line_org == NULL)
+		return;
+	    for (i_new = i_org + 1; i_new < DB_COUNT; ++i_new)
+	    {
+		if (tp->tp_diffbuf[i_new] == NULL)
+		    continue;
+		if (dir == BACKWARD)
+		    off_new = dp->df_count[i_new] - 1;
+		/* if other buffer doesn't have this line, it was inserted */
+		if (off_new < 0 || off_new >= dp->df_count[i_new])
+		    break;
+		if (diff_cmp(line_org, ml_get_buf(tp->tp_diffbuf[i_new],
+				   dp->df_lnum[i_new] + off_new, FALSE)) != 0)
+		    break;
+	    }
+	    vim_free(line_org);
+
+	    /* Stop when a line isn't equal in all diff buffers. */
+	    if (i_new != DB_COUNT)
+		break;
+
+	    /* Line matched in all buffers, remove it from the diff. */
+	    for (i_new = i_org; i_new < DB_COUNT; ++i_new)
+		if (tp->tp_diffbuf[i_new] != NULL)
+		{
+		    if (dir == FORWARD)
+			++dp->df_lnum[i_new];
+		    --dp->df_count[i_new];
+		}
+	}
+	if (dir == BACKWARD)
+	    break;
+	dir = BACKWARD;
+    }
+}
+
+/*
+ * Check if a diff block doesn't contain invalid line numbers.
+ * This can happen when the diff program returns invalid results.
+ */
+    static int
+diff_check_sanity(tp, dp)
+    tabpage_T	*tp;
+    diff_T	*dp;
+{
+    int		i;
+
+    for (i = 0; i < DB_COUNT; ++i)
+	if (tp->tp_diffbuf[i] != NULL)
+	    if (dp->df_lnum[i] + dp->df_count[i] - 1
+				      > tp->tp_diffbuf[i]->b_ml.ml_line_count)
+		return FAIL;
+    return OK;
+}
+
+/*
+ * Mark all diff buffers in the current tab page for redraw.
+ */
+    static void
+diff_redraw(dofold)
+    int		dofold;	    /* also recompute the folds */
+{
+    win_T	*wp;
+    int		n;
+
+    for (wp = firstwin; wp != NULL; wp = wp->w_next)
+	if (wp->w_p_diff)
+	{
+	    redraw_win_later(wp, SOME_VALID);
+#ifdef FEAT_FOLDING
+	    if (dofold && foldmethodIsDiff(wp))
+		foldUpdateAll(wp);
+#endif
+	    /* A change may have made filler lines invalid, need to take care
+	     * of that for other windows. */
+	    if (wp != curwin && wp->w_topfill > 0)
+	    {
+		n = diff_check(wp, wp->w_topline);
+		if (wp->w_topfill > n)
+		    wp->w_topfill = (n < 0 ? 0 : n);
+	    }
+	}
+}
+
+/*
+ * Write buffer "buf" to file "name".
+ * Always use 'fileformat' set to "unix".
+ * Return FAIL for failure
+ */
+    static int
+diff_write(buf, fname)
+    buf_T	*buf;
+    char_u	*fname;
+{
+    int		r;
+    char_u	*save_ff;
+
+    save_ff = buf->b_p_ff;
+    buf->b_p_ff = vim_strsave((char_u *)FF_UNIX);
+    r = buf_write(buf, fname, NULL, (linenr_T)1, buf->b_ml.ml_line_count,
+					     NULL, FALSE, FALSE, FALSE, TRUE);
+    free_string_option(buf->b_p_ff);
+    buf->b_p_ff = save_ff;
+    return r;
+}
+
+/*
+ * Completely update the diffs for the buffers involved.
+ * This uses the ordinary "diff" command.
+ * The buffers are written to a file, also for unmodified buffers (the file
+ * could have been produced by autocommands, e.g. the netrw plugin).
+ */
+/*ARGSUSED*/
+    void
+ex_diffupdate(eap)
+    exarg_T	*eap;	    /* can be NULL, it's not used */
+{
+    buf_T	*buf;
+    int		idx_orig;
+    int		idx_new;
+    char_u	*tmp_orig;
+    char_u	*tmp_new;
+    char_u	*tmp_diff;
+    FILE	*fd;
+    int		ok;
+
+    /* Delete all diffblocks. */
+    diff_clear(curtab);
+    curtab->tp_diff_invalid = FALSE;
+
+    /* Use the first buffer as the original text. */
+    for (idx_orig = 0; idx_orig < DB_COUNT; ++idx_orig)
+	if (curtab->tp_diffbuf[idx_orig] != NULL)
+	    break;
+    if (idx_orig == DB_COUNT)
+	return;
+
+    /* Only need to do something when there is another buffer. */
+    for (idx_new = idx_orig + 1; idx_new < DB_COUNT; ++idx_new)
+	if (curtab->tp_diffbuf[idx_new] != NULL)
+	    break;
+    if (idx_new == DB_COUNT)
+	return;
+
+    /* We need three temp file names. */
+    tmp_orig = vim_tempname('o');
+    tmp_new = vim_tempname('n');
+    tmp_diff = vim_tempname('d');
+    if (tmp_orig == NULL || tmp_new == NULL || tmp_diff == NULL)
+	goto theend;
+
+    /*
+     * Do a quick test if "diff" really works.  Otherwise it looks like there
+     * are no differences.  Can't use the return value, it's non-zero when
+     * there are differences.
+     * May try twice, first with "-a" and then without.
+     */
+    for (;;)
+    {
+	ok = FALSE;
+	fd = mch_fopen((char *)tmp_orig, "w");
+	if (fd != NULL)
+	{
+	    fwrite("line1\n", (size_t)6, (size_t)1, fd);
+	    fclose(fd);
+	    fd = mch_fopen((char *)tmp_new, "w");
+	    if (fd != NULL)
+	    {
+		fwrite("line2\n", (size_t)6, (size_t)1, fd);
+		fclose(fd);
+		diff_file(tmp_orig, tmp_new, tmp_diff);
+		fd = mch_fopen((char *)tmp_diff, "r");
+		if (fd != NULL)
+		{
+		    char_u	linebuf[LBUFLEN];
+
+		    for (;;)
+		    {
+			/* There must be a line that contains "1c1". */
+			if (tag_fgets(linebuf, LBUFLEN, fd))
+			    break;
+			if (STRNCMP(linebuf, "1c1", 3) == 0)
+			    ok = TRUE;
+		    }
+		    fclose(fd);
+		}
+		mch_remove(tmp_diff);
+		mch_remove(tmp_new);
+	    }
+	    mch_remove(tmp_orig);
+	}
+
+#ifdef FEAT_EVAL
+	/* When using 'diffexpr' break here. */
+	if (*p_dex != NUL)
+	    break;
+#endif
+
+#if defined(MSWIN) || defined(MSDOS)
+	/* If the "-a" argument works, also check if "--binary" works. */
+	if (ok && diff_a_works == MAYBE && diff_bin_works == MAYBE)
+	{
+	    diff_a_works = TRUE;
+	    diff_bin_works = TRUE;
+	    continue;
+	}
+	if (!ok && diff_a_works == TRUE && diff_bin_works == TRUE)
+	{
+	    /* Tried --binary, but it failed. "-a" works though. */
+	    diff_bin_works = FALSE;
+	    ok = TRUE;
+	}
+#endif
+
+	/* If we checked if "-a" works already, break here. */
+	if (diff_a_works != MAYBE)
+	    break;
+	diff_a_works = ok;
+
+	/* If "-a" works break here, otherwise retry without "-a". */
+	if (ok)
+	    break;
+    }
+    if (!ok)
+    {
+	EMSG(_("E97: Cannot create diffs"));
+	diff_a_works = MAYBE;
+#if defined(MSWIN) || defined(MSDOS)
+	diff_bin_works = MAYBE;
+#endif
+	goto theend;
+    }
+
+    /* Write the first buffer to a tempfile. */
+    buf = curtab->tp_diffbuf[idx_orig];
+    if (diff_write(buf, tmp_orig) == FAIL)
+	goto theend;
+
+    /* Make a difference between the first buffer and every other. */
+    for (idx_new = idx_orig + 1; idx_new < DB_COUNT; ++idx_new)
+    {
+	buf = curtab->tp_diffbuf[idx_new];
+	if (buf == NULL)
+	    continue;
+	if (diff_write(buf, tmp_new) == FAIL)
+	    continue;
+	diff_file(tmp_orig, tmp_new, tmp_diff);
+
+	/* Read the diff output and add each entry to the diff list. */
+	diff_read(idx_orig, idx_new, tmp_diff);
+	mch_remove(tmp_diff);
+	mch_remove(tmp_new);
+    }
+    mch_remove(tmp_orig);
+
+    diff_redraw(TRUE);
+
+theend:
+    vim_free(tmp_orig);
+    vim_free(tmp_new);
+    vim_free(tmp_diff);
+}
+
+/*
+ * Make a diff between files "tmp_orig" and "tmp_new", results in "tmp_diff".
+ */
+    static void
+diff_file(tmp_orig, tmp_new, tmp_diff)
+    char_u	*tmp_orig;
+    char_u	*tmp_new;
+    char_u	*tmp_diff;
+{
+    char_u	*cmd;
+
+#ifdef FEAT_EVAL
+    if (*p_dex != NUL)
+	/* Use 'diffexpr' to generate the diff file. */
+	eval_diff(tmp_orig, tmp_new, tmp_diff);
+    else
+#endif
+    {
+	cmd = alloc((unsigned)(STRLEN(tmp_orig) + STRLEN(tmp_new)
+				+ STRLEN(tmp_diff) + STRLEN(p_srr) + 27));
+	if (cmd != NULL)
+	{
+	    /* We don't want $DIFF_OPTIONS to get in the way. */
+	    if (getenv("DIFF_OPTIONS"))
+		vim_setenv((char_u *)"DIFF_OPTIONS", (char_u *)"");
+
+	    /* Build the diff command and execute it.  Always use -a, binary
+	     * differences are of no use.  Ignore errors, diff returns
+	     * non-zero when differences have been found. */
+	    sprintf((char *)cmd,
+#if defined(PLAN9)
+		    "/bin/ape/"
+#endif
+		    "diff %s%s%s%s%s %s",
+		    diff_a_works == FALSE ? "" : "-a ",
+#if defined(MSWIN) || defined(MSDOS)
+		    diff_bin_works == TRUE ? "--binary " : "",
+#else
+		    "",
+#endif
+		    (diff_flags & DIFF_IWHITE) ? "-b " : "",
+		    (diff_flags & DIFF_ICASE) ? "-i " : "",
+		    tmp_orig, tmp_new);
+	    append_redir(cmd, p_srr, tmp_diff);
+#ifdef FEAT_AUTOCMD
+	    ++autocmd_block;	/* Avoid ShellCmdPost stuff */
+#endif
+	    (void)call_shell(cmd, SHELL_FILTER|SHELL_SILENT|SHELL_DOOUT);
+#ifdef FEAT_AUTOCMD
+	    --autocmd_block;
+#endif
+	    vim_free(cmd);
+	}
+    }
+}
+
+/*
+ * Create a new version of a file from the current buffer and a diff file.
+ * The buffer is written to a file, also for unmodified buffers (the file
+ * could have been produced by autocommands, e.g. the netrw plugin).
+ */
+    void
+ex_diffpatch(eap)
+    exarg_T	*eap;
+{
+    char_u	*tmp_orig;	/* name of original temp file */
+    char_u	*tmp_new;	/* name of patched temp file */
+    char_u	*buf = NULL;
+    win_T	*old_curwin = curwin;
+    char_u	*newname = NULL;	/* name of patched file buffer */
+#ifdef UNIX
+    char_u	dirbuf[MAXPATHL];
+    char_u	*fullname = NULL;
+#endif
+#ifdef FEAT_BROWSE
+    char_u	*browseFile = NULL;
+    int		browse_flag = cmdmod.browse;
+#endif
+
+#ifdef FEAT_BROWSE
+    if (cmdmod.browse)
+    {
+	browseFile = do_browse(0, (char_u *)_("Patch file"),
+			 eap->arg, NULL, NULL, BROWSE_FILTER_ALL_FILES, NULL);
+	if (browseFile == NULL)
+	    return;		/* operation cancelled */
+	eap->arg = browseFile;
+	cmdmod.browse = FALSE;	/* don't let do_ecmd() browse again */
+    }
+#endif
+
+    /* We need two temp file names. */
+    tmp_orig = vim_tempname('o');
+    tmp_new = vim_tempname('n');
+    if (tmp_orig == NULL || tmp_new == NULL)
+	goto theend;
+
+    /* Write the current buffer to "tmp_orig". */
+    if (buf_write(curbuf, tmp_orig, NULL,
+		(linenr_T)1, curbuf->b_ml.ml_line_count,
+				     NULL, FALSE, FALSE, FALSE, TRUE) == FAIL)
+	goto theend;
+
+#ifdef UNIX
+    /* Get the absolute path of the patchfile, changing directory below. */
+    fullname = FullName_save(eap->arg, FALSE);
+#endif
+    buf = alloc((unsigned)(STRLEN(tmp_orig) + (
+# ifdef UNIX
+		    fullname != NULL ? STRLEN(fullname) :
+# endif
+		    STRLEN(eap->arg)) + STRLEN(tmp_new) + 16));
+    if (buf == NULL)
+	goto theend;
+
+#ifdef UNIX
+    /* Temporaraly chdir to /tmp, to avoid patching files in the current
+     * directory when the patch file contains more than one patch.  When we
+     * have our own temp dir use that instead, it will be cleaned up when we
+     * exit (any .rej files created).  Don't change directory if we can't
+     * return to the current. */
+    if (mch_dirname(dirbuf, MAXPATHL) != OK || mch_chdir((char *)dirbuf) != 0)
+	dirbuf[0] = NUL;
+    else
+    {
+# ifdef TEMPDIRNAMES
+	if (vim_tempdir != NULL)
+	    mch_chdir((char *)vim_tempdir);
+	else
+# endif
+	    mch_chdir("/tmp");
+	shorten_fnames(TRUE);
+    }
+#endif
+
+#ifdef FEAT_EVAL
+    if (*p_pex != NUL)
+	/* Use 'patchexpr' to generate the new file. */
+	eval_patch(tmp_orig,
+# ifdef UNIX
+		fullname != NULL ? fullname :
+# endif
+		eap->arg, tmp_new);
+    else
+#endif
+    {
+	/* Build the patch command and execute it.  Ignore errors.  Switch to
+	 * cooked mode to allow the user to respond to prompts. */
+	sprintf((char *)buf,
+#if defined(PLAN9)
+		"/bin/ape/"
+#endif
+		"patch -o %s %s < \"%s\"", tmp_new, tmp_orig,
+# ifdef UNIX
+		fullname != NULL ? fullname :
+# endif
+		eap->arg);
+#ifdef FEAT_AUTOCMD
+	++autocmd_block;	/* Avoid ShellCmdPost stuff */
+#endif
+	(void)call_shell(buf, SHELL_FILTER | SHELL_COOKED);
+#ifdef FEAT_AUTOCMD
+	--autocmd_block;
+#endif
+    }
+
+#ifdef UNIX
+    if (dirbuf[0] != NUL)
+    {
+	if (mch_chdir((char *)dirbuf) != 0)
+	    EMSG(_(e_prev_dir));
+	shorten_fnames(TRUE);
+    }
+#endif
+
+    /* patch probably has written over the screen */
+    redraw_later(CLEAR);
+
+    /* Delete any .orig or .rej file created. */
+    STRCPY(buf, tmp_new);
+    STRCAT(buf, ".orig");
+    mch_remove(buf);
+    STRCPY(buf, tmp_new);
+    STRCAT(buf, ".rej");
+    mch_remove(buf);
+
+    if (curbuf->b_fname != NULL)
+    {
+	newname = vim_strnsave(curbuf->b_fname,
+					  (int)(STRLEN(curbuf->b_fname) + 4));
+	if (newname != NULL)
+	    STRCAT(newname, ".new");
+    }
+
+#ifdef FEAT_GUI
+    need_mouse_correct = TRUE;
+#endif
+    /* don't use a new tab page, each tab page has its own diffs */
+    cmdmod.tab = 0;
+
+    if (win_split(0, (diff_flags & DIFF_VERTICAL) ? WSP_VERT : 0) != FAIL)
+    {
+	/* Pretend it was a ":split fname" command */
+	eap->cmdidx = CMD_split;
+	eap->arg = tmp_new;
+	do_exedit(eap, old_curwin);
+
+	if (curwin != old_curwin)		/* split must have worked */
+	{
+	    /* Set 'diff', 'scrollbind' on and 'wrap' off. */
+	    diff_win_options(curwin, TRUE);
+	    diff_win_options(old_curwin, TRUE);
+
+	    if (newname != NULL)
+	    {
+		/* do a ":file filename.new" on the patched buffer */
+		eap->arg = newname;
+		ex_file(eap);
+
+#ifdef FEAT_AUTOCMD
+		/* Do filetype detection with the new name. */
+		if (au_has_group((char_u *)"filetypedetect"))
+		    do_cmdline_cmd((char_u *)":doau filetypedetect BufRead");
+#endif
+	    }
+	}
+    }
+
+theend:
+    if (tmp_orig != NULL)
+	mch_remove(tmp_orig);
+    vim_free(tmp_orig);
+    if (tmp_new != NULL)
+	mch_remove(tmp_new);
+    vim_free(tmp_new);
+    vim_free(newname);
+    vim_free(buf);
+#ifdef UNIX
+    vim_free(fullname);
+#endif
+#ifdef FEAT_BROWSE
+    vim_free(browseFile);
+    cmdmod.browse = browse_flag;
+#endif
+}
+
+/*
+ * Split the window and edit another file, setting options to show the diffs.
+ */
+    void
+ex_diffsplit(eap)
+    exarg_T	*eap;
+{
+    win_T	*old_curwin = curwin;
+
+#ifdef FEAT_GUI
+    need_mouse_correct = TRUE;
+#endif
+    /* don't use a new tab page, each tab page has its own diffs */
+    cmdmod.tab = 0;
+
+    if (win_split(0, (diff_flags & DIFF_VERTICAL) ? WSP_VERT : 0) != FAIL)
+    {
+	/* Pretend it was a ":split fname" command */
+	eap->cmdidx = CMD_split;
+	curwin->w_p_diff = TRUE;
+	do_exedit(eap, old_curwin);
+
+	if (curwin != old_curwin)		/* split must have worked */
+	{
+	    /* Set 'diff', 'scrollbind' on and 'wrap' off. */
+	    diff_win_options(curwin, TRUE);
+	    diff_win_options(old_curwin, TRUE);
+	}
+    }
+}
+
+/*
+ * Set options to show difs for the current window.
+ */
+/*ARGSUSED*/
+    void
+ex_diffthis(eap)
+    exarg_T	*eap;
+{
+    /* Set 'diff', 'scrollbind' on and 'wrap' off. */
+    diff_win_options(curwin, TRUE);
+}
+
+/*
+ * Set options in window "wp" for diff mode.
+ */
+    void
+diff_win_options(wp, addbuf)
+    win_T	*wp;
+    int		addbuf;		/* Add buffer to diff. */
+{
+    wp->w_p_diff = TRUE;
+    wp->w_p_scb = TRUE;
+    wp->w_p_wrap = FALSE;
+# ifdef FEAT_FOLDING
+    {
+	win_T	    *old_curwin = curwin;
+
+	curwin = wp;
+	curbuf = curwin->w_buffer;
+	set_string_option_direct((char_u *)"fdm", -1, (char_u *)"diff",
+						       OPT_LOCAL|OPT_FREE, 0);
+	curwin = old_curwin;
+	curbuf = curwin->w_buffer;
+	wp->w_p_fdc = diff_foldcolumn;
+	wp->w_p_fen = TRUE;
+	wp->w_p_fdl = 0;
+	foldUpdateAll(wp);
+	/* make sure topline is not halfway a fold */
+	changed_window_setting_win(wp);
+    }
+# endif
+#ifdef FEAT_SCROLLBIND
+    if (vim_strchr(p_sbo, 'h') == NULL)
+	do_cmdline_cmd((char_u *)"set sbo+=hor");
+#endif
+
+    if (addbuf)
+	diff_buf_add(wp->w_buffer);
+    redraw_win_later(wp, NOT_VALID);
+}
+
+/*
+ * Set options not to show diffs.  For the current window or all windows.
+ * Only in the current tab page.
+ */
+    void
+ex_diffoff(eap)
+    exarg_T	*eap;
+{
+    win_T	*wp;
+    win_T	*old_curwin = curwin;
+#ifdef FEAT_SCROLLBIND
+    int		diffwin = FALSE;
+#endif
+
+    for (wp = firstwin; wp != NULL; wp = wp->w_next)
+    {
+	if (wp == curwin || eap->forceit)
+	{
+	    /* Set 'diff', 'scrollbind' off and 'wrap' on. */
+	    wp->w_p_diff = FALSE;
+	    wp->w_p_scb = FALSE;
+	    wp->w_p_wrap = TRUE;
+#ifdef FEAT_FOLDING
+	    curwin = wp;
+	    curbuf = curwin->w_buffer;
+	    set_string_option_direct((char_u *)"fdm", -1,
+				   (char_u *)"manual", OPT_LOCAL|OPT_FREE, 0);
+	    curwin = old_curwin;
+	    curbuf = curwin->w_buffer;
+	    wp->w_p_fdc = 0;
+	    wp->w_p_fen = FALSE;
+	    wp->w_p_fdl = 0;
+	    foldUpdateAll(wp);
+	    /* make sure topline is not halfway a fold */
+	    changed_window_setting_win(wp);
+#endif
+	    diff_buf_adjust(wp);
+	}
+#ifdef FEAT_SCROLLBIND
+	diffwin |= wp->w_p_diff;
+#endif
+    }
+
+#ifdef FEAT_SCROLLBIND
+    /* Remove "hor" from from 'scrollopt' if there are no diff windows left. */
+    if (!diffwin && vim_strchr(p_sbo, 'h') != NULL)
+	do_cmdline_cmd((char_u *)"set sbo-=hor");
+#endif
+}
+
+/*
+ * Read the diff output and add each entry to the diff list.
+ */
+    static void
+diff_read(idx_orig, idx_new, fname)
+    int		idx_orig;	/* idx of original file */
+    int		idx_new;	/* idx of new file */
+    char_u	*fname;		/* name of diff output file */
+{
+    FILE	*fd;
+    diff_T	*dprev = NULL;
+    diff_T	*dp = curtab->tp_first_diff;
+    diff_T	*dn, *dpl;
+    long	f1, l1, f2, l2;
+    char_u	linebuf[LBUFLEN];   /* only need to hold the diff line */
+    int		difftype;
+    char_u	*p;
+    long	off;
+    int		i;
+    linenr_T	lnum_orig, lnum_new;
+    long	count_orig, count_new;
+    int		notset = TRUE;	    /* block "*dp" not set yet */
+
+    fd = mch_fopen((char *)fname, "r");
+    if (fd == NULL)
+    {
+	EMSG(_("E98: Cannot read diff output"));
+	return;
+    }
+
+    for (;;)
+    {
+	if (tag_fgets(linebuf, LBUFLEN, fd))
+	    break;		/* end of file */
+	if (!isdigit(*linebuf))
+	    continue;		/* not the start of a diff block */
+
+	/* This line must be one of three formats:
+	 * {first}[,{last}]c{first}[,{last}]
+	 * {first}a{first}[,{last}]
+	 * {first}[,{last}]d{first}
+	 */
+	p = linebuf;
+	f1 = getdigits(&p);
+	if (*p == ',')
+	{
+	    ++p;
+	    l1 = getdigits(&p);
+	}
+	else
+	    l1 = f1;
+	if (*p != 'a' && *p != 'c' && *p != 'd')
+	    continue;		/* invalid diff format */
+	difftype = *p++;
+	f2 = getdigits(&p);
+	if (*p == ',')
+	{
+	    ++p;
+	    l2 = getdigits(&p);
+	}
+	else
+	    l2 = f2;
+	if (l1 < f1 || l2 < f2)
+	    continue;		/* invalid line range */
+
+	if (difftype == 'a')
+	{
+	    lnum_orig = f1 + 1;
+	    count_orig = 0;
+	}
+	else
+	{
+	    lnum_orig = f1;
+	    count_orig = l1 - f1 + 1;
+	}
+	if (difftype == 'd')
+	{
+	    lnum_new = f2 + 1;
+	    count_new = 0;
+	}
+	else
+	{
+	    lnum_new = f2;
+	    count_new = l2 - f2 + 1;
+	}
+
+	/* Go over blocks before the change, for which orig and new are equal.
+	 * Copy blocks from orig to new. */
+	while (dp != NULL
+		&& lnum_orig > dp->df_lnum[idx_orig] + dp->df_count[idx_orig])
+	{
+	    if (notset)
+		diff_copy_entry(dprev, dp, idx_orig, idx_new);
+	    dprev = dp;
+	    dp = dp->df_next;
+	    notset = TRUE;
+	}
+
+	if (dp != NULL
+		&& lnum_orig <= dp->df_lnum[idx_orig] + dp->df_count[idx_orig]
+		&& lnum_orig + count_orig >= dp->df_lnum[idx_orig])
+	{
+	    /* New block overlaps with existing block(s).
+	     * First find last block that overlaps. */
+	    for (dpl = dp; dpl->df_next != NULL; dpl = dpl->df_next)
+		if (lnum_orig + count_orig < dpl->df_next->df_lnum[idx_orig])
+		    break;
+
+	    /* If the newly found block starts before the old one, set the
+	     * start back a number of lines. */
+	    off = dp->df_lnum[idx_orig] - lnum_orig;
+	    if (off > 0)
+	    {
+		for (i = idx_orig; i < idx_new; ++i)
+		    if (curtab->tp_diffbuf[i] != NULL)
+			dp->df_lnum[i] -= off;
+		dp->df_lnum[idx_new] = lnum_new;
+		dp->df_count[idx_new] = count_new;
+	    }
+	    else if (notset)
+	    {
+		/* new block inside existing one, adjust new block */
+		dp->df_lnum[idx_new] = lnum_new + off;
+		dp->df_count[idx_new] = count_new - off;
+	    }
+	    else
+		/* second overlap of new block with existing block */
+		dp->df_count[idx_new] += count_new - count_orig;
+
+	    /* Adjust the size of the block to include all the lines to the
+	     * end of the existing block or the new diff, whatever ends last. */
+	    off = (lnum_orig + count_orig)
+			 - (dpl->df_lnum[idx_orig] + dpl->df_count[idx_orig]);
+	    if (off < 0)
+	    {
+		/* new change ends in existing block, adjust the end if not
+		 * done already */
+		if (notset)
+		    dp->df_count[idx_new] += -off;
+		off = 0;
+	    }
+	    for (i = idx_orig; i < idx_new + !notset; ++i)
+		if (curtab->tp_diffbuf[i] != NULL)
+		    dp->df_count[i] = dpl->df_lnum[i] + dpl->df_count[i]
+						       - dp->df_lnum[i] + off;
+
+	    /* Delete the diff blocks that have been merged into one. */
+	    dn = dp->df_next;
+	    dp->df_next = dpl->df_next;
+	    while (dn != dp->df_next)
+	    {
+		dpl = dn->df_next;
+		vim_free(dn);
+		dn = dpl;
+	    }
+	}
+	else
+	{
+	    /* Allocate a new diffblock. */
+	    dp = diff_alloc_new(curtab, dprev, dp);
+	    if (dp == NULL)
+		goto done;
+
+	    dp->df_lnum[idx_orig] = lnum_orig;
+	    dp->df_count[idx_orig] = count_orig;
+	    dp->df_lnum[idx_new] = lnum_new;
+	    dp->df_count[idx_new] = count_new;
+
+	    /* Set values for other buffers, these must be equal to the
+	     * original buffer, otherwise there would have been a change
+	     * already. */
+	    for (i = idx_orig + 1; i < idx_new; ++i)
+		if (curtab->tp_diffbuf[i] != NULL)
+		    diff_copy_entry(dprev, dp, idx_orig, i);
+	}
+	notset = FALSE;		/* "*dp" has been set */
+    }
+
+    /* for remaining diff blocks orig and new are equal */
+    while (dp != NULL)
+    {
+	if (notset)
+	    diff_copy_entry(dprev, dp, idx_orig, idx_new);
+	dprev = dp;
+	dp = dp->df_next;
+	notset = TRUE;
+    }
+
+done:
+    fclose(fd);
+}
+
+/*
+ * Copy an entry at "dp" from "idx_orig" to "idx_new".
+ */
+    static void
+diff_copy_entry(dprev, dp, idx_orig, idx_new)
+    diff_T	*dprev;
+    diff_T	*dp;
+    int		idx_orig;
+    int		idx_new;
+{
+    long	off;
+
+    if (dprev == NULL)
+	off = 0;
+    else
+	off = (dprev->df_lnum[idx_orig] + dprev->df_count[idx_orig])
+	    - (dprev->df_lnum[idx_new] + dprev->df_count[idx_new]);
+    dp->df_lnum[idx_new] = dp->df_lnum[idx_orig] - off;
+    dp->df_count[idx_new] = dp->df_count[idx_orig];
+}
+
+/*
+ * Clear the list of diffblocks for tab page "tp".
+ */
+    void
+diff_clear(tp)
+    tabpage_T	*tp;
+{
+    diff_T	*p, *next_p;
+
+    for (p = tp->tp_first_diff; p != NULL; p = next_p)
+    {
+	next_p = p->df_next;
+	vim_free(p);
+    }
+    tp->tp_first_diff = NULL;
+}
+
+/*
+ * Check diff status for line "lnum" in buffer "buf":
+ * Returns 0 for nothing special
+ * Returns -1 for a line that should be highlighted as changed.
+ * Returns -2 for a line that should be highlighted as added/deleted.
+ * Returns > 0 for inserting that many filler lines above it (never happens
+ * when 'diffopt' doesn't contain "filler").
+ * This should only be used for windows where 'diff' is set.
+ */
+    int
+diff_check(wp, lnum)
+    win_T	*wp;
+    linenr_T	lnum;
+{
+    int		idx;		/* index in tp_diffbuf[] for this buffer */
+    diff_T	*dp;
+    int		maxcount;
+    int		i;
+    buf_T	*buf = wp->w_buffer;
+    int		cmp;
+
+    if (curtab->tp_diff_invalid)
+	ex_diffupdate(NULL);		/* update after a big change */
+
+    if (curtab->tp_first_diff == NULL || !wp->w_p_diff)	/* no diffs at all */
+	return 0;
+
+    /* safety check: "lnum" must be a buffer line */
+    if (lnum < 1 || lnum > buf->b_ml.ml_line_count + 1)
+	return 0;
+
+    idx = diff_buf_idx(buf);
+    if (idx == DB_COUNT)
+	return 0;		/* no diffs for buffer "buf" */
+
+#ifdef FEAT_FOLDING
+    /* A closed fold never has filler lines. */
+    if (hasFoldingWin(wp, lnum, NULL, NULL, TRUE, NULL))
+	return 0;
+#endif
+
+    /* search for a change that includes "lnum" in the list of diffblocks. */
+    for (dp = curtab->tp_first_diff; dp != NULL; dp = dp->df_next)
+	if (lnum <= dp->df_lnum[idx] + dp->df_count[idx])
+	    break;
+    if (dp == NULL || lnum < dp->df_lnum[idx])
+	return 0;
+
+    if (lnum < dp->df_lnum[idx] + dp->df_count[idx])
+    {
+	int	zero = FALSE;
+
+	/* Changed or inserted line.  If the other buffers have a count of
+	 * zero, the lines were inserted.  If the other buffers have the same
+	 * count, check if the lines are identical. */
+	cmp = FALSE;
+	for (i = 0; i < DB_COUNT; ++i)
+	    if (i != idx && curtab->tp_diffbuf[i] != NULL)
+	    {
+		if (dp->df_count[i] == 0)
+		    zero = TRUE;
+		else
+		{
+		    if (dp->df_count[i] != dp->df_count[idx])
+			return -1;	    /* nr of lines changed. */
+		    cmp = TRUE;
+		}
+	    }
+	if (cmp)
+	{
+	    /* Compare all lines.  If they are equal the lines were inserted
+	     * in some buffers, deleted in others, but not changed. */
+	    for (i = 0; i < DB_COUNT; ++i)
+		if (i != idx && curtab->tp_diffbuf[i] != NULL && dp->df_count[i] != 0)
+		    if (!diff_equal_entry(dp, idx, i))
+			return -1;
+	}
+	/* If there is no buffer with zero lines then there is no difference
+	 * any longer.  Happens when making a change (or undo) that removes
+	 * the difference.  Can't remove the entry here, we might be halfway
+	 * updating the window.  Just report the text as unchanged.  Other
+	 * windows might still show the change though. */
+	if (zero == FALSE)
+	    return 0;
+	return -2;
+    }
+
+    /* If 'diffopt' doesn't contain "filler", return 0. */
+    if (!(diff_flags & DIFF_FILLER))
+	return 0;
+
+    /* Insert filler lines above the line just below the change.  Will return
+     * 0 when this buf had the max count. */
+    maxcount = 0;
+    for (i = 0; i < DB_COUNT; ++i)
+	if (curtab->tp_diffbuf[i] != NULL && dp->df_count[i] > maxcount)
+	    maxcount = dp->df_count[i];
+    return maxcount - dp->df_count[idx];
+}
+
+/*
+ * Compare two entries in diff "*dp" and return TRUE if they are equal.
+ */
+    static int
+diff_equal_entry(dp, idx1, idx2)
+    diff_T	*dp;
+    int		idx1;
+    int		idx2;
+{
+    int		i;
+    char_u	*line;
+    int		cmp;
+
+    if (dp->df_count[idx1] != dp->df_count[idx2])
+	return FALSE;
+    if (diff_check_sanity(curtab, dp) == FAIL)
+	return FALSE;
+    for (i = 0; i < dp->df_count[idx1]; ++i)
+    {
+	line = vim_strsave(ml_get_buf(curtab->tp_diffbuf[idx1],
+					       dp->df_lnum[idx1] + i, FALSE));
+	if (line == NULL)
+	    return FALSE;
+	cmp = diff_cmp(line, ml_get_buf(curtab->tp_diffbuf[idx2],
+					       dp->df_lnum[idx2] + i, FALSE));
+	vim_free(line);
+	if (cmp != 0)
+	    return FALSE;
+    }
+    return TRUE;
+}
+
+/*
+ * Compare strings "s1" and "s2" according to 'diffopt'.
+ * Return non-zero when they are different.
+ */
+    static int
+diff_cmp(s1, s2)
+    char_u	*s1;
+    char_u	*s2;
+{
+    char_u	*p1, *p2;
+#ifdef FEAT_MBYTE
+    int		l;
+#endif
+
+    if ((diff_flags & (DIFF_ICASE | DIFF_IWHITE)) == 0)
+	return STRCMP(s1, s2);
+    if ((diff_flags & DIFF_ICASE) && !(diff_flags & DIFF_IWHITE))
+	return MB_STRICMP(s1, s2);
+
+    /* Ignore white space changes and possibly ignore case. */
+    p1 = s1;
+    p2 = s2;
+    while (*p1 != NUL && *p2 != NUL)
+    {
+	if (vim_iswhite(*p1) && vim_iswhite(*p2))
+	{
+	    p1 = skipwhite(p1);
+	    p2 = skipwhite(p2);
+	}
+	else
+	{
+#ifdef FEAT_MBYTE
+	    l  = (*mb_ptr2len)(p1);
+	    if (l != (*mb_ptr2len)(p2))
+		break;
+	    if (l > 1)
+	    {
+		if (STRNCMP(p1, p2, l) != 0
+			&& (!enc_utf8
+			    || !(diff_flags & DIFF_ICASE)
+			    || utf_fold(utf_ptr2char(p1))
+					       != utf_fold(utf_ptr2char(p2))))
+		    break;
+		p1 += l;
+		p2 += l;
+	    }
+	    else
+#endif
+	    {
+		if (*p1 != *p2 && (!(diff_flags & DIFF_ICASE)
+				     || TOLOWER_LOC(*p1) != TOLOWER_LOC(*p2)))
+		    break;
+		++p1;
+		++p2;
+	    }
+	}
+    }
+
+    /* Ignore trailing white space. */
+    p1 = skipwhite(p1);
+    p2 = skipwhite(p2);
+    if (*p1 != NUL || *p2 != NUL)
+	return 1;
+    return 0;
+}
+
+/*
+ * Return the number of filler lines above "lnum".
+ */
+    int
+diff_check_fill(wp, lnum)
+    win_T	*wp;
+    linenr_T	lnum;
+{
+    int		n;
+
+    /* be quick when there are no filler lines */
+    if (!(diff_flags & DIFF_FILLER))
+	return 0;
+    n = diff_check(wp, lnum);
+    if (n <= 0)
+	return 0;
+    return n;
+}
+
+/*
+ * Set the topline of "towin" to match the position in "fromwin", so that they
+ * show the same diff'ed lines.
+ */
+    void
+diff_set_topline(fromwin, towin)
+    win_T	*fromwin;
+    win_T	*towin;
+{
+    buf_T	*buf = fromwin->w_buffer;
+    linenr_T	lnum = fromwin->w_topline;
+    int		idx;
+    diff_T	*dp;
+    int		i;
+
+    idx = diff_buf_idx(buf);
+    if (idx == DB_COUNT)
+	return;		/* safety check */
+
+    if (curtab->tp_diff_invalid)
+	ex_diffupdate(NULL);		/* update after a big change */
+
+    towin->w_topfill = 0;
+
+    /* search for a change that includes "lnum" in the list of diffblocks. */
+    for (dp = curtab->tp_first_diff; dp != NULL; dp = dp->df_next)
+	if (lnum <= dp->df_lnum[idx] + dp->df_count[idx])
+	    break;
+    if (dp == NULL)
+    {
+	/* After last change, compute topline relative to end of file; no
+	 * filler lines. */
+	towin->w_topline = towin->w_buffer->b_ml.ml_line_count
+					   - (buf->b_ml.ml_line_count - lnum);
+    }
+    else
+    {
+	/* Find index for "towin". */
+	i = diff_buf_idx(towin->w_buffer);
+	if (i == DB_COUNT)
+	    return;		/* safety check */
+
+	towin->w_topline = lnum + (dp->df_lnum[i] - dp->df_lnum[idx]);
+	if (lnum >= dp->df_lnum[idx])
+	{
+	    /* Inside a change: compute filler lines. */
+	    if (dp->df_count[i] == dp->df_count[idx])
+		towin->w_topfill = fromwin->w_topfill;
+	    else if (dp->df_count[i] > dp->df_count[idx])
+	    {
+		if (lnum == dp->df_lnum[idx] + dp->df_count[idx])
+		    towin->w_topline = dp->df_lnum[i] + dp->df_count[i]
+							 - fromwin->w_topfill;
+	    }
+	    else
+	    {
+		if (towin->w_topline >= dp->df_lnum[i] + dp->df_count[i])
+		{
+		    if (diff_flags & DIFF_FILLER)
+			towin->w_topfill = dp->df_lnum[idx]
+						   + dp->df_count[idx] - lnum;
+		    towin->w_topline = dp->df_lnum[i] + dp->df_count[i];
+		}
+	    }
+	}
+    }
+
+    /* safety check (if diff info gets outdated strange things may happen) */
+    towin->w_botfill = FALSE;
+    if (towin->w_topline > towin->w_buffer->b_ml.ml_line_count)
+    {
+	towin->w_topline = towin->w_buffer->b_ml.ml_line_count;
+	towin->w_botfill = TRUE;
+    }
+    if (towin->w_topline < 1)
+    {
+	towin->w_topline = 1;
+	towin->w_topfill = 0;
+    }
+
+    /* When w_topline changes need to recompute w_botline and cursor position */
+    invalidate_botline_win(towin);
+    changed_line_abv_curs_win(towin);
+
+    check_topfill(towin, FALSE);
+#ifdef FEAT_FOLDING
+    (void)hasFoldingWin(towin, towin->w_topline, &towin->w_topline,
+							    NULL, TRUE, NULL);
+#endif
+}
+
+/*
+ * This is called when 'diffopt' is changed.
+ */
+    int
+diffopt_changed()
+{
+    char_u	*p;
+    int		diff_context_new = 6;
+    int		diff_flags_new = 0;
+    int		diff_foldcolumn_new = 2;
+    tabpage_T	*tp;
+
+    p = p_dip;
+    while (*p != NUL)
+    {
+	if (STRNCMP(p, "filler", 6) == 0)
+	{
+	    p += 6;
+	    diff_flags_new |= DIFF_FILLER;
+	}
+	else if (STRNCMP(p, "context:", 8) == 0 && VIM_ISDIGIT(p[8]))
+	{
+	    p += 8;
+	    diff_context_new = getdigits(&p);
+	}
+	else if (STRNCMP(p, "icase", 5) == 0)
+	{
+	    p += 5;
+	    diff_flags_new |= DIFF_ICASE;
+	}
+	else if (STRNCMP(p, "iwhite", 6) == 0)
+	{
+	    p += 6;
+	    diff_flags_new |= DIFF_IWHITE;
+	}
+	else if (STRNCMP(p, "horizontal", 10) == 0)
+	{
+	    p += 10;
+	    diff_flags_new |= DIFF_HORIZONTAL;
+	}
+	else if (STRNCMP(p, "vertical", 8) == 0)
+	{
+	    p += 8;
+	    diff_flags_new |= DIFF_VERTICAL;
+	}
+	else if (STRNCMP(p, "foldcolumn:", 11) == 0 && VIM_ISDIGIT(p[11]))
+	{
+	    p += 11;
+	    diff_foldcolumn_new = getdigits(&p);
+	}
+	if (*p != ',' && *p != NUL)
+	    return FAIL;
+	if (*p == ',')
+	    ++p;
+    }
+
+    /* Can't have both "horizontal" and "vertical". */
+    if ((diff_flags_new & DIFF_HORIZONTAL) && (diff_flags_new & DIFF_VERTICAL))
+	return FAIL;
+
+    /* If "icase" or "iwhite" was added or removed, need to update the diff. */
+    if (diff_flags != diff_flags_new)
+	for (tp = first_tabpage; tp != NULL; tp = tp->tp_next)
+	    tp->tp_diff_invalid = TRUE;
+
+    diff_flags = diff_flags_new;
+    diff_context = diff_context_new;
+    diff_foldcolumn = diff_foldcolumn_new;
+
+    diff_redraw(TRUE);
+
+    /* recompute the scroll binding with the new option value, may
+     * remove or add filler lines */
+    check_scrollbind((linenr_T)0, 0L);
+
+    return OK;
+}
+
+/*
+ * Return TRUE if 'diffopt' contains "horizontal".
+ */
+    int
+diffopt_horizontal()
+{
+    return (diff_flags & DIFF_HORIZONTAL) != 0;
+}
+
+/*
+ * Find the difference within a changed line.
+ * Returns TRUE if the line was added, no other buffer has it.
+ */
+    int
+diff_find_change(wp, lnum, startp, endp)
+    win_T	*wp;
+    linenr_T	lnum;
+    int		*startp;	/* first char of the change */
+    int		*endp;		/* last char of the change */
+{
+    char_u	*line_org;
+    char_u	*line_new;
+    int		i;
+    int		si_org, si_new;
+    int		ei_org, ei_new;
+    diff_T	*dp;
+    int		idx;
+    int		off;
+    int		added = TRUE;
+
+    /* Make a copy of the line, the next ml_get() will invalidate it. */
+    line_org = vim_strsave(ml_get_buf(wp->w_buffer, lnum, FALSE));
+    if (line_org == NULL)
+	return FALSE;
+
+    idx = diff_buf_idx(wp->w_buffer);
+    if (idx == DB_COUNT)	/* cannot happen */
+    {
+	vim_free(line_org);
+	return FALSE;
+    }
+
+    /* search for a change that includes "lnum" in the list of diffblocks. */
+    for (dp = curtab->tp_first_diff; dp != NULL; dp = dp->df_next)
+	if (lnum <= dp->df_lnum[idx] + dp->df_count[idx])
+	    break;
+    if (dp == NULL || diff_check_sanity(curtab, dp) == FAIL)
+    {
+	vim_free(line_org);
+	return FALSE;
+    }
+
+    off = lnum - dp->df_lnum[idx];
+
+    for (i = 0; i < DB_COUNT; ++i)
+	if (curtab->tp_diffbuf[i] != NULL && i != idx)
+	{
+	    /* Skip lines that are not in the other change (filler lines). */
+	    if (off >= dp->df_count[i])
+		continue;
+	    added = FALSE;
+	    line_new = ml_get_buf(curtab->tp_diffbuf[i],
+						 dp->df_lnum[i] + off, FALSE);
+
+	    /* Search for start of difference */
+	    si_org = si_new = 0;
+	    while (line_org[si_org] != NUL)
+	    {
+		if ((diff_flags & DIFF_IWHITE)
+			&& vim_iswhite(line_org[si_org])
+			&& vim_iswhite(line_new[si_new]))
+		{
+		    si_org = (int)(skipwhite(line_org + si_org) - line_org);
+		    si_new = (int)(skipwhite(line_new + si_new) - line_new);
+		}
+		else
+		{
+		    if (line_org[si_org] != line_new[si_new])
+			break;
+		    ++si_org;
+		    ++si_new;
+		}
+	    }
+#ifdef FEAT_MBYTE
+	    if (has_mbyte)
+	    {
+		/* Move back to first byte of character in both lines (may
+		 * have "nn^" in line_org and "n^ in line_new). */
+		si_org -= (*mb_head_off)(line_org, line_org + si_org);
+		si_new -= (*mb_head_off)(line_new, line_new + si_new);
+	    }
+#endif
+	    if (*startp > si_org)
+		*startp = si_org;
+
+	    /* Search for end of difference, if any. */
+	    if (line_org[si_org] != NUL || line_new[si_new] != NUL)
+	    {
+		ei_org = (int)STRLEN(line_org);
+		ei_new = (int)STRLEN(line_new);
+		while (ei_org >= *startp && ei_new >= si_new
+						&& ei_org >= 0 && ei_new >= 0)
+		{
+		    if ((diff_flags & DIFF_IWHITE)
+			    && vim_iswhite(line_org[ei_org])
+			    && vim_iswhite(line_new[ei_new]))
+		    {
+			while (ei_org >= *startp
+					     && vim_iswhite(line_org[ei_org]))
+			    --ei_org;
+			while (ei_new >= si_new
+					     && vim_iswhite(line_new[ei_new]))
+			    --ei_new;
+		    }
+		    else
+		    {
+			if (line_org[ei_org] != line_new[ei_new])
+			    break;
+			--ei_org;
+			--ei_new;
+		    }
+		}
+		if (*endp < ei_org)
+		    *endp = ei_org;
+	    }
+	}
+
+    vim_free(line_org);
+    return added;
+}
+
+#if defined(FEAT_FOLDING) || defined(PROTO)
+/*
+ * Return TRUE if line "lnum" is not close to a diff block, this line should
+ * be in a fold.
+ * Return FALSE if there are no diff blocks at all in this window.
+ */
+    int
+diff_infold(wp, lnum)
+    win_T	*wp;
+    linenr_T	lnum;
+{
+    int		i;
+    int		idx = -1;
+    int		other = FALSE;
+    diff_T	*dp;
+
+    /* Return if 'diff' isn't set. */
+    if (!wp->w_p_diff)
+	return FALSE;
+
+    for (i = 0; i < DB_COUNT; ++i)
+    {
+	if (curtab->tp_diffbuf[i] == wp->w_buffer)
+	    idx = i;
+	else if (curtab->tp_diffbuf[i] != NULL)
+	    other = TRUE;
+    }
+
+    /* return here if there are no diffs in the window */
+    if (idx == -1 || !other)
+	return FALSE;
+
+    if (curtab->tp_diff_invalid)
+	ex_diffupdate(NULL);		/* update after a big change */
+
+    /* Return if there are no diff blocks.  All lines will be folded. */
+    if (curtab->tp_first_diff == NULL)
+	return TRUE;
+
+    for (dp = curtab->tp_first_diff; dp != NULL; dp = dp->df_next)
+    {
+	/* If this change is below the line there can't be any further match. */
+	if (dp->df_lnum[idx] - diff_context > lnum)
+	    break;
+	/* If this change ends before the line we have a match. */
+	if (dp->df_lnum[idx] + dp->df_count[idx] + diff_context > lnum)
+	    return FALSE;
+    }
+    return TRUE;
+}
+#endif
+
+/*
+ * "dp" and "do" commands.
+ */
+    void
+nv_diffgetput(put)
+    int		put;
+{
+    exarg_T	ea;
+
+    ea.arg = (char_u *)"";
+    if (put)
+	ea.cmdidx = CMD_diffput;
+    else
+	ea.cmdidx = CMD_diffget;
+    ea.addr_count = 0;
+    ea.line1 = curwin->w_cursor.lnum;
+    ea.line2 = curwin->w_cursor.lnum;
+    ex_diffgetput(&ea);
+}
+
+/*
+ * ":diffget"
+ * ":diffput"
+ */
+    void
+ex_diffgetput(eap)
+    exarg_T	*eap;
+{
+    linenr_T	lnum;
+    int		count;
+    linenr_T	off = 0;
+    diff_T	*dp;
+    diff_T	*dprev;
+    diff_T	*dfree;
+    int		idx_cur;
+    int		idx_other;
+    int		idx_from;
+    int		idx_to;
+    int		i;
+    int		added;
+    char_u	*p;
+    aco_save_T	aco;
+    buf_T	*buf;
+    int		start_skip, end_skip;
+    int		new_count;
+    int		buf_empty;
+    int		found_not_ma = FALSE;
+
+    /* Find the current buffer in the list of diff buffers. */
+    idx_cur = diff_buf_idx(curbuf);
+    if (idx_cur == DB_COUNT)
+    {
+	EMSG(_("E99: Current buffer is not in diff mode"));
+	return;
+    }
+
+    if (*eap->arg == NUL)
+    {
+	/* No argument: Find the other buffer in the list of diff buffers. */
+	for (idx_other = 0; idx_other < DB_COUNT; ++idx_other)
+	    if (curtab->tp_diffbuf[idx_other] != curbuf
+		    && curtab->tp_diffbuf[idx_other] != NULL)
+	    {
+		if (eap->cmdidx != CMD_diffput
+				     || curtab->tp_diffbuf[idx_other]->b_p_ma)
+		    break;
+		found_not_ma = TRUE;
+	    }
+	if (idx_other == DB_COUNT)
+	{
+	    if (found_not_ma)
+		EMSG(_("E793: No other buffer in diff mode is modifiable"));
+	    else
+		EMSG(_("E100: No other buffer in diff mode"));
+	    return;
+	}
+
+	/* Check that there isn't a third buffer in the list */
+	for (i = idx_other + 1; i < DB_COUNT; ++i)
+	    if (curtab->tp_diffbuf[i] != curbuf
+		    && curtab->tp_diffbuf[i] != NULL
+		    && (eap->cmdidx != CMD_diffput || curtab->tp_diffbuf[i]->b_p_ma))
+	    {
+		EMSG(_("E101: More than two buffers in diff mode, don't know which one to use"));
+		return;
+	    }
+    }
+    else
+    {
+	/* Buffer number or pattern given.  Ignore trailing white space. */
+	p = eap->arg + STRLEN(eap->arg);
+	while (p > eap->arg && vim_iswhite(p[-1]))
+	    --p;
+	for (i = 0; vim_isdigit(eap->arg[i]) && eap->arg + i < p; ++i)
+	    ;
+	if (eap->arg + i == p)	    /* digits only */
+	    i = atol((char *)eap->arg);
+	else
+	{
+	    i = buflist_findpat(eap->arg, p, FALSE, TRUE);
+	    if (i < 0)
+		return;		/* error message already given */
+	}
+	buf = buflist_findnr(i);
+	if (buf == NULL)
+	{
+	    EMSG2(_("E102: Can't find buffer \"%s\""), eap->arg);
+	    return;
+	}
+	idx_other = diff_buf_idx(buf);
+	if (idx_other == DB_COUNT)
+	{
+	    EMSG2(_("E103: Buffer \"%s\" is not in diff mode"), eap->arg);
+	    return;
+	}
+    }
+
+    diff_busy = TRUE;
+
+    /* When no range given include the line above or below the cursor. */
+    if (eap->addr_count == 0)
+    {
+	/* Make it possible that ":diffget" on the last line gets line below
+	 * the cursor line when there is no difference above the cursor. */
+	if (eap->cmdidx == CMD_diffget
+		&& eap->line1 == curbuf->b_ml.ml_line_count
+		&& diff_check(curwin, eap->line1) == 0
+		&& (eap->line1 == 1 || diff_check(curwin, eap->line1 - 1) == 0))
+	    ++eap->line2;
+	else if (eap->line1 > 0)
+	    --eap->line1;
+    }
+
+    if (eap->cmdidx == CMD_diffget)
+    {
+	idx_from = idx_other;
+	idx_to = idx_cur;
+    }
+    else
+    {
+	idx_from = idx_cur;
+	idx_to = idx_other;
+	/* Need to make the other buffer the current buffer to be able to make
+	 * changes in it. */
+	/* set curwin/curbuf to buf and save a few things */
+	aucmd_prepbuf(&aco, curtab->tp_diffbuf[idx_other]);
+    }
+
+    /* May give the warning for a changed buffer here, which can trigger the
+     * FileChangedRO autocommand, which may do nasty things and mess
+     * everything up. */
+    if (!curbuf->b_changed)
+    {
+	change_warning(0);
+	if (diff_buf_idx(curbuf) != idx_to)
+	{
+	    EMSG(_("E787: Buffer changed unexpectedly"));
+	    return;
+	}
+    }
+
+    dprev = NULL;
+    for (dp = curtab->tp_first_diff; dp != NULL; )
+    {
+	if (dp->df_lnum[idx_cur] > eap->line2 + off)
+	    break;	/* past the range that was specified */
+
+	dfree = NULL;
+	lnum = dp->df_lnum[idx_to];
+	count = dp->df_count[idx_to];
+	if (dp->df_lnum[idx_cur] + dp->df_count[idx_cur] > eap->line1 + off
+		&& u_save(lnum - 1, lnum + count) != FAIL)
+	{
+	    /* Inside the specified range and saving for undo worked. */
+	    start_skip = 0;
+	    end_skip = 0;
+	    if (eap->addr_count > 0)
+	    {
+		/* A range was specified: check if lines need to be skipped. */
+		start_skip = eap->line1 + off - dp->df_lnum[idx_cur];
+		if (start_skip > 0)
+		{
+		    /* range starts below start of current diff block */
+		    if (start_skip > count)
+		    {
+			lnum += count;
+			count = 0;
+		    }
+		    else
+		    {
+			count -= start_skip;
+			lnum += start_skip;
+		    }
+		}
+		else
+		    start_skip = 0;
+
+		end_skip = dp->df_lnum[idx_cur] + dp->df_count[idx_cur] - 1
+							 - (eap->line2 + off);
+		if (end_skip > 0)
+		{
+		    /* range ends above end of current/from diff block */
+		    if (idx_cur == idx_from)	/* :diffput */
+		    {
+			i = dp->df_count[idx_cur] - start_skip - end_skip;
+			if (count > i)
+			    count = i;
+		    }
+		    else			/* :diffget */
+		    {
+			count -= end_skip;
+			end_skip = dp->df_count[idx_from] - start_skip - count;
+			if (end_skip < 0)
+			    end_skip = 0;
+		    }
+		}
+		else
+		    end_skip = 0;
+	    }
+
+	    buf_empty = FALSE;
+	    added = 0;
+	    for (i = 0; i < count; ++i)
+	    {
+		/* remember deleting the last line of the buffer */
+		buf_empty = curbuf->b_ml.ml_line_count == 1;
+		ml_delete(lnum, FALSE);
+		--added;
+	    }
+	    for (i = 0; i < dp->df_count[idx_from] - start_skip - end_skip; ++i)
+	    {
+		linenr_T nr;
+
+		nr = dp->df_lnum[idx_from] + start_skip + i;
+		if (nr > curtab->tp_diffbuf[idx_from]->b_ml.ml_line_count)
+		    break;
+		p = vim_strsave(ml_get_buf(curtab->tp_diffbuf[idx_from],
+								  nr, FALSE));
+		if (p != NULL)
+		{
+		    ml_append(lnum + i - 1, p, 0, FALSE);
+		    vim_free(p);
+		    ++added;
+		    if (buf_empty && curbuf->b_ml.ml_line_count == 2)
+		    {
+			/* Added the first line into an empty buffer, need to
+			 * delete the dummy empty line. */
+			buf_empty = FALSE;
+			ml_delete((linenr_T)2, FALSE);
+		    }
+		}
+	    }
+	    new_count = dp->df_count[idx_to] + added;
+	    dp->df_count[idx_to] = new_count;
+
+	    if (start_skip == 0 && end_skip == 0)
+	    {
+		/* Check if there are any other buffers and if the diff is
+		 * equal in them. */
+		for (i = 0; i < DB_COUNT; ++i)
+		    if (curtab->tp_diffbuf[i] != NULL && i != idx_from
+								&& i != idx_to
+			    && !diff_equal_entry(dp, idx_from, i))
+			break;
+		if (i == DB_COUNT)
+		{
+		    /* delete the diff entry, the buffers are now equal here */
+		    dfree = dp;
+		    dp = dp->df_next;
+		    if (dprev == NULL)
+			curtab->tp_first_diff = dp;
+		    else
+			dprev->df_next = dp;
+		}
+	    }
+
+	    /* Adjust marks.  This will change the following entries! */
+	    if (added != 0)
+	    {
+		mark_adjust(lnum, lnum + count - 1, (long)MAXLNUM, (long)added);
+		if (curwin->w_cursor.lnum >= lnum)
+		{
+		    /* Adjust the cursor position if it's in/after the changed
+		     * lines. */
+		    if (curwin->w_cursor.lnum >= lnum + count)
+			curwin->w_cursor.lnum += added;
+		    else if (added < 0)
+			curwin->w_cursor.lnum = lnum;
+		}
+	    }
+	    changed_lines(lnum, 0, lnum + count, (long)added);
+
+	    if (dfree != NULL)
+	    {
+		/* Diff is deleted, update folds in other windows. */
+#ifdef FEAT_FOLDING
+		diff_fold_update(dfree, idx_to);
+#endif
+		vim_free(dfree);
+	    }
+	    else
+		/* mark_adjust() may have changed the count in a wrong way */
+		dp->df_count[idx_to] = new_count;
+
+	    /* When changing the current buffer, keep track of line numbers */
+	    if (idx_cur == idx_to)
+		off += added;
+	}
+
+	/* If before the range or not deleted, go to next diff. */
+	if (dfree == NULL)
+	{
+	    dprev = dp;
+	    dp = dp->df_next;
+	}
+    }
+
+    /* restore curwin/curbuf and a few other things */
+    if (idx_other == idx_to)
+    {
+	/* Syncing undo only works for the current buffer, but we change
+	 * another buffer.  Sync undo if the command was typed.  This isn't
+	 * 100% right when ":diffput" is used in a function or mapping. */
+	if (KeyTyped)
+	    u_sync(FALSE);
+	aucmd_restbuf(&aco);
+    }
+
+    diff_busy = FALSE;
+
+    /* Check that the cursor is on a valid character and update it's position.
+     * When there were filler lines the topline has become invalid. */
+    check_cursor();
+    changed_line_abv_curs();
+
+    /* Also need to redraw the other buffers. */
+    diff_redraw(FALSE);
+}
+
+#ifdef FEAT_FOLDING
+/*
+ * Update folds for all diff buffers for entry "dp".
+ * Skip buffer with index "skip_idx".
+ * When there are no diffs, all folds are removed.
+ */
+    static void
+diff_fold_update(dp, skip_idx)
+    diff_T	*dp;
+    int		skip_idx;
+{
+    int		i;
+    win_T	*wp;
+
+    for (wp = firstwin; wp != NULL; wp = wp->w_next)
+	for (i = 0; i < DB_COUNT; ++i)
+	    if (curtab->tp_diffbuf[i] == wp->w_buffer && i != skip_idx)
+		foldUpdate(wp, dp->df_lnum[i],
+					    dp->df_lnum[i] + dp->df_count[i]);
+}
+#endif
+
+/*
+ * Return TRUE if buffer "buf" is in diff-mode.
+ */
+    int
+diff_mode_buf(buf)
+    buf_T	*buf;
+{
+    tabpage_T	*tp;
+
+    for (tp = first_tabpage; tp != NULL; tp = tp->tp_next)
+	if (diff_buf_idx_tp(buf, tp) != DB_COUNT)
+	    return TRUE;
+    return FALSE;
+}
+
+/*
+ * Move "count" times in direction "dir" to the next diff block.
+ * Return FAIL if there isn't such a diff block.
+ */
+    int
+diff_move_to(dir, count)
+    int		dir;
+    long	count;
+{
+    int		idx;
+    linenr_T	lnum = curwin->w_cursor.lnum;
+    diff_T	*dp;
+
+    idx = diff_buf_idx(curbuf);
+    if (idx == DB_COUNT || curtab->tp_first_diff == NULL)
+	return FAIL;
+
+    if (curtab->tp_diff_invalid)
+	ex_diffupdate(NULL);		/* update after a big change */
+
+    if (curtab->tp_first_diff == NULL)		/* no diffs today */
+	return FAIL;
+
+    while (--count >= 0)
+    {
+	/* Check if already before first diff. */
+	if (dir == BACKWARD && lnum <= curtab->tp_first_diff->df_lnum[idx])
+	    break;
+
+	for (dp = curtab->tp_first_diff; ; dp = dp->df_next)
+	{
+	    if (dp == NULL)
+		break;
+	    if ((dir == FORWARD && lnum < dp->df_lnum[idx])
+		    || (dir == BACKWARD
+			&& (dp->df_next == NULL
+			    || lnum <= dp->df_next->df_lnum[idx])))
+	    {
+		lnum = dp->df_lnum[idx];
+		break;
+	    }
+	}
+    }
+
+    /* don't end up past the end of the file */
+    if (lnum > curbuf->b_ml.ml_line_count)
+	lnum = curbuf->b_ml.ml_line_count;
+
+    /* When the cursor didn't move at all we fail. */
+    if (lnum == curwin->w_cursor.lnum)
+	return FAIL;
+
+    setpcmark();
+    curwin->w_cursor.lnum = lnum;
+    curwin->w_cursor.col = 0;
+
+    return OK;
+}
+
+#if defined(FEAT_FOLDING) || defined(PROTO)
+/*
+ * For line "lnum" in the current window find the equivalent lnum in window
+ * "wp", compensating for inserted/deleted lines.
+ */
+    linenr_T
+diff_lnum_win(lnum, wp)
+    linenr_T	lnum;
+    win_T	*wp;
+{
+    diff_T	*dp;
+    int		idx;
+    int		i;
+    linenr_T	n;
+
+    idx = diff_buf_idx(curbuf);
+    if (idx == DB_COUNT)		/* safety check */
+	return (linenr_T)0;
+
+    if (curtab->tp_diff_invalid)
+	ex_diffupdate(NULL);		/* update after a big change */
+
+    /* search for a change that includes "lnum" in the list of diffblocks. */
+    for (dp = curtab->tp_first_diff; dp != NULL; dp = dp->df_next)
+	if (lnum <= dp->df_lnum[idx] + dp->df_count[idx])
+	    break;
+
+    /* When after the last change, compute relative to the last line number. */
+    if (dp == NULL)
+	return wp->w_buffer->b_ml.ml_line_count
+					- (curbuf->b_ml.ml_line_count - lnum);
+
+    /* Find index for "wp". */
+    i = diff_buf_idx(wp->w_buffer);
+    if (i == DB_COUNT)			/* safety check */
+	return (linenr_T)0;
+
+    n = lnum + (dp->df_lnum[i] - dp->df_lnum[idx]);
+    if (n > dp->df_lnum[i] + dp->df_count[i])
+	n = dp->df_lnum[i] + dp->df_count[i];
+    return n;
+}
+#endif
+
+#endif	/* FEAT_DIFF */
--- /dev/null
+++ b/digraph.c
@@ -1,0 +1,2510 @@
+/* vi:set ts=8 sts=4 sw=4:
+ *
+ * VIM - Vi IMproved	by Bram Moolenaar
+ *
+ * Do ":help uganda"  in Vim to read copying and usage conditions.
+ * Do ":help credits" in Vim to see a list of people who contributed.
+ * See README.txt for an overview of the Vim source code.
+ */
+
+/*
+ * digraph.c: code for digraphs
+ */
+
+#include "vim.h"
+
+#if defined(FEAT_DIGRAPHS) || defined(PROTO)
+
+#ifdef FEAT_MBYTE
+typedef int result_T;
+#else
+typedef char_u result_T;
+#endif
+
+typedef struct digraph
+{
+    char_u	char1;
+    char_u	char2;
+    result_T	result;
+} digr_T;
+
+static int getexactdigraph __ARGS((int, int, int));
+static void printdigraph __ARGS((digr_T *));
+
+/* digraphs added by the user */
+static garray_T	user_digraphs = {0, 0, sizeof(digr_T), 10, NULL};
+
+/*
+ * Note: Characters marked with XX are not included literally, because some
+ * compilers cannot handle them (Amiga SAS/C is the most picky one).
+ */
+static digr_T digraphdefault[] =
+#if defined(MSDOS) || defined(OS2)
+	/*
+	 * MSDOS digraphs.
+	 */
+       {{'C', ',', 128},	/* ~@ XX */
+	{'u', '"', 129},	/*  */
+	{'e', '\'', 130},	/* ‚ */
+	{'a', '^', 131},	/* ƒ */
+	{'a', '"', 132},	/* „ */
+	{'a', '`', 133},	/* … */
+	{'a', '@', 134},	/* † */
+	{'c', ',', 135},	/* ~G XX */
+	{'e', '^', 136},	/* ~H XX */
+	{'e', '"', 137},	/* ‰ */
+	{'e', '`', 138},	/* Š */
+	{'i', '"', 139},	/* ‹ */
+	{'i', '^', 140},	/* Œ */
+	{'i', '`', 141},	/*  */
+	{'A', '"', 142},	/* ~N XX */
+	{'A', '@', 143},	/*  */
+	{'E', '\'', 144},	/*  */
+	{'a', 'e', 145},	/* ‘ */
+	{'A', 'E', 146},	/* ’ */
+	{'o', '^', 147},	/* “ */
+	{'o', '"', 148},	/* ” */
+	{'o', '`', 149},	/* • */
+	{'u', '^', 150},	/* – */
+	{'u', '`', 151},	/* — */
+	{'y', '"', 152},	/* ˜ */
+	{'O', '"', 153},	/* ™ */
+	{'U', '"', 154},	/* š */
+	{'c', '|', 155},	/* › */
+	{'$', '$', 156},	/* œ */
+	{'Y', '-', 157},	/* ~] XX */
+	{'P', 't', 158},	/* ž */
+	{'f', 'f', 159},	/* Ÿ */
+	{'a', '\'', 160},	/*   */
+	{'i', '\'', 161},	/* ¡ */
+	{'o', '\'', 162},	/* ¢ */
+	{'u', '\'', 163},	/* x XX */
+	{'n', '~', 164},	/* ¤ */
+	{'N', '~', 165},	/* ¥ */
+	{'a', 'a', 166},	/* ¦ */
+	{'o', 'o', 167},	/* § */
+	{'~', '?', 168},	/* ¨ */
+	{'-', 'a', 169},	/* © */
+	{'a', '-', 170},	/* ª */
+	{'1', '2', 171},	/* « */
+	{'1', '4', 172},	/* ¬ */
+	{'~', '!', 173},	/* ­ */
+	{'<', '<', 174},	/* ® */
+	{'>', '>', 175},	/* ¯ */
+
+	{'s', 's', 225},	/* á */
+	{'j', 'u', 230},	/* æ */
+	{'o', '/', 237},	/* í */
+	{'+', '-', 241},	/* ñ */
+	{'>', '=', 242},	/* ò */
+	{'<', '=', 243},	/* ó */
+	{':', '-', 246},	/* ö */
+	{'~', '~', 247},	/* ÷ */
+	{'~', 'o', 248},	/* ø */
+	{'2', '2', 253},	/* ý */
+	{NUL, NUL, NUL}
+	};
+
+#else	/* !MSDOS && !OS2 */
+# ifdef __MINT__
+
+	/*
+	 * ATARI digraphs
+	 */
+       {{'C', ',', 128},	/* ~@ XX */
+	{'u', '"', 129},	/*  */
+	{'e', '\'', 130},	/* ‚ */
+	{'a', '^', 131},	/* ƒ */
+	{'a', '"', 132},	/* „ */
+	{'a', '`', 133},	/* … */
+	{'a', '@', 134},	/* † */
+	{'c', ',', 135},	/* ~G XX */
+	{'e', '^', 136},	/* ~H XX */
+	{'e', '"', 137},	/* ‰ */
+	{'e', '`', 138},	/* Š */
+	{'i', '"', 139},	/* ‹ */
+	{'i', '^', 140},	/* Œ */
+	{'i', '`', 141},	/*  */
+	{'A', '"', 142},	/* Ž */
+	{'A', '@', 143},	/*  */
+	{'E', '\'', 144},	/*  */
+	{'a', 'e', 145},	/* ‘ */
+	{'A', 'E', 146},	/* ’ */
+	{'o', '^', 147},	/* “ */
+	{'o', '"', 148},	/* ” */
+	{'o', '`', 149},	/* • */
+	{'u', '^', 150},	/* – */
+	{'u', '`', 151},	/* — */
+	{'y', '"', 152},	/* ˜ */
+	{'O', '"', 153},	/* ™ */
+	{'U', '"', 154},	/* š */
+	{'c', '|', 155},	/* › */
+	{'$', '$', 156},	/* œ */
+	{'Y', '-', 157},	/* ~] XX */
+	{'s', 's', 158},	/* ž */
+	{'f', 'f', 159},	/* Ÿ */
+	{'a', '\'', 160},	/*   */
+	{'i', '\'', 161},	/* ¡ */
+	{'o', '\'', 162},	/* ¢ */
+	{'u', '\'', 163},	/* £ */
+	{'n', '~', 164},	/* ¤ */
+	{'N', '~', 165},	/* ¥ */
+	{'a', 'a', 166},	/* ¦ */
+	{'o', 'o', 167},	/* § */
+	{'~', '?', 168},	/* ¨ */
+	{'-', 'a', 169},	/* © */
+	{'a', '-', 170},	/* ª */
+	{'1', '2', 171},	/* « */
+	{'1', '4', 172},	/* ¬ */
+	{'~', '!', 173},	/* ­ */
+	{'<', '<', 174},	/* ® */
+	{'>', '>', 175},	/* ¯ */
+	{'j', 'u', 230},	/* æ */
+	{'o', '/', 237},	/* í */
+	{'+', '-', 241},	/* ñ */
+	{'>', '=', 242},	/* ò */
+	{'<', '=', 243},	/* ó */
+	{':', '-', 246},	/* ö */
+	{'~', '~', 247},	/* ÷ */
+	{'~', 'o', 248},	/* ø */
+	{'2', '2', 253},	/* ý */
+	{NUL, NUL, NUL}
+	};
+
+# else	/* !__MINT__ */
+#  ifdef HPUX_DIGRAPHS
+
+	/*
+	 * different HPUX digraphs
+	 */
+       {{'A', '`', 161},	/* ¡ */
+	{'A', '^', 162},	/* ¢ */
+	{'E', '`', 163},	/* £ */
+	{'E', '^', 164},	/* ¤ */
+	{'E', '"', 165},	/* ¥ */
+	{'I', '^', 166},	/* ¦ */
+	{'I', '"', 167},	/* § */
+	{'\'', '\'', 168},	/* ¨ */
+	{'`', '`', 169},	/* © */
+	{'^', '^', 170},	/* ª */
+	{'"', '"', 171},	/* « */
+	{'~', '~', 172},	/* ¬ */
+	{'U', '`', 173},	/* ­ */
+	{'U', '^', 174},	/* ® */
+	{'L', '=', 175},	/* ¯ */
+	{'~', '_', 176},	/* ° */
+	{'Y', '\'', 177},	/* ± */
+	{'y', '\'', 178},	/* ² */
+	{'~', 'o', 179},	/* ³ */
+	{'C', ',', 180},	/* ´ */
+	{'c', ',', 181},	/* µ */
+	{'N', '~', 182},	/* ¶ */
+	{'n', '~', 183},	/* · */
+	{'~', '!', 184},	/* ¸ */
+	{'~', '?', 185},	/* ¹ */
+	{'o', 'x', 186},	/* º */
+	{'L', '-', 187},	/* » */
+	{'Y', '=', 188},	/* ¼ */
+	{'p', 'p', 189},	/* ½ */
+	{'f', 'l', 190},	/* ¾ */
+	{'c', '|', 191},	/* ¿ */
+	{'a', '^', 192},	/* À */
+	{'e', '^', 193},	/* Á */
+	{'o', '^', 194},	/* Â */
+	{'u', '^', 195},	/* Ã */
+	{'a', '\'', 196},	/* Ä */
+	{'e', '\'', 197},	/* Å */
+	{'o', '\'', 198},	/* Æ */
+	{'u', '\'', 199},	/* Ç */
+	{'a', '`', 200},	/* È */
+	{'e', '`', 201},	/* É */
+	{'o', '`', 202},	/* Ê */
+	{'u', '`', 203},	/* Ë */
+	{'a', '"', 204},	/* Ì */
+	{'e', '"', 205},	/* Í */
+	{'o', '"', 206},	/* Î */
+	{'u', '"', 207},	/* Ï */
+	{'A', 'o', 208},	/* Ð */
+	{'i', '^', 209},	/* Ñ */
+	{'O', '/', 210},	/* Ò */
+	{'A', 'E', 211},	/* Ó */
+	{'a', 'o', 212},	/* Ô */
+	{'i', '\'', 213},	/* Õ */
+	{'o', '/', 214},	/* Ö */
+	{'a', 'e', 215},	/* × */
+	{'A', '"', 216},	/* Ø */
+	{'i', '`', 217},	/* Ù */
+	{'O', '"', 218},	/* Ú */
+	{'U', '"', 219},	/* Û */
+	{'E', '\'', 220},	/* Ü */
+	{'i', '"', 221},	/* Ý */
+	{'s', 's', 222},	/* Þ */
+	{'O', '^', 223},	/* ß */
+	{'A', '\'', 224},	/* à */
+	{'A', '~', 225},	/* á */
+	{'a', '~', 226},	/* â */
+	{'D', '-', 227},	/* ã */
+	{'d', '-', 228},	/* ä */
+	{'I', '\'', 229},	/* å */
+	{'I', '`', 230},	/* æ */
+	{'O', '\'', 231},	/* ç */
+	{'O', '`', 232},	/* è */
+	{'O', '~', 233},	/* é */
+	{'o', '~', 234},	/* ê */
+	{'S', '~', 235},	/* ë */
+	{'s', '~', 236},	/* ì */
+	{'U', '\'', 237},	/* í */
+	{'Y', '"', 238},	/* î */
+	{'y', '"', 239},	/* ï */
+	{'p', '-', 240},	/* ð */
+	{'p', '~', 241},	/* ñ */
+	{'~', '.', 242},	/* ò */
+	{'j', 'u', 243},	/* ó */
+	{'P', 'p', 244},	/* ô */
+	{'3', '4', 245},	/* õ */
+	{'-', '-', 246},	/* ö */
+	{'1', '4', 247},	/* ÷ */
+	{'1', '2', 248},	/* ø */
+	{'a', '_', 249},	/* ù */
+	{'o', '_', 250},	/* ú */
+	{'<', '<', 251},	/* û */
+	{'x', 'x', 252},	/* ü */
+	{'>', '>', 253},	/* ý */
+	{'+', '-', 254},	/* þ */
+	{'n', 'u', 255},	/* x XX */
+	{NUL, NUL, NUL}
+	};
+
+#  else	/* !HPUX_DIGRAPHS */
+
+#   ifdef EBCDIC
+
+	/*
+	 * EBCDIC - ISO digraphs
+	 * TODO: EBCDIC Table is Code-Page 1047
+	 */
+       {{'a', '^',    66},	/* â */
+	{'a', '"',    67},	/* ä */
+	{'a', '`',    68},	/* à */
+	{'a', '\'',   69},	/* á */
+	{'a', '~',    70},	/* ã */
+	{'a', '@',    71},	/* å */
+	{'a', 'a',    71},	/* å */
+	{'c', ',',    72},	/* ç */
+	{'n', '~',    73},	/* ñ */
+	{'c', '|',    74},	/* ¢ */
+	{'e', '\'',   81},	/* é */
+	{'e', '^',    82},	/* ê */
+	{'e', '"',    83},	/* ë */
+	{'e', '`',    84},	/* è */
+	{'i', '\'',   85},	/* í */
+	{'i', '^',    86},	/* î */
+	{'i', '"',    87},	/* ï */
+	{'i', '`',    88},	/* ì */
+	{'s', 's',    89},	/* ß */
+	{'A', '^',    98},	/* Â */
+	{'A', '"',    99},	/* Ä */
+	{'A', '`',   100},	/* À */
+	{'A', '\'',  101},	/* Á */
+	{'A', '~',   102},	/* Ã */
+	{'A', '@',   103},	/* Å */
+	{'A', 'A',   103},	/* Å */
+	{'C', ',',   104},	/* Ç */
+	{'N', '~',   105},	/* Ñ */
+	{'|', '|',   106},	/* ¦ */
+	{'o', '/',   112},	/* ø */
+	{'E', '\'',  113},	/* É */
+	{'E', '^',   114},	/* Ê */
+	{'E', '"',   115},	/* Ë */
+	{'E', '`',   116},	/* È */
+	{'I', '\'',  117},	/* Í */
+	{'I', '^',   118},	/* Î */
+	{'I', '"',   119},	/* Ï */
+	{'I', '`',   120},	/* Ì */
+	{'O', '/',   128},	/* 0/ XX */
+	{'<', '<',   138},	/* « */
+	{'>', '>',   139},	/* » */
+	{'d', '-',   140},	/* ð */
+	{'y', '\'',  141},	/* ý */
+	{'i', 'p',   142},	/* þ */
+	{'+', '-',   143},	/* ± */
+	{'~', 'o',   144},	/* ° */
+	{'a', '-',   154},	/* ª */
+	{'o', '-',   155},	/* º */
+	{'a', 'e',   156},	/* æ */
+	{',', ',',   157},	/* , XX */
+	{'A', 'E',   158},	/* Æ */
+	{'o', 'x',   159},	/* ¤ - currency symbol in ISO 8859-1 */
+	{'e', '=',   159},	/* ¤ - euro symbol in ISO 8859-15 */
+	{'E', 'u',   159},	/* ¤ - euro symbol in ISO 8859-15 */
+	{'j', 'u',   160},	/* µ */
+	{'y', '"',   167},	/* x XX */
+	{'~', '!',   170},	/* ¡ */
+	{'~', '?',   171},	/* ¿ */
+	{'D', '-',   172},	/* Ð */
+	{'I', 'p',   174},	/* Þ */
+	{'r', 'O',   175},	/* ® */
+	{'-', ',',   176},	/* ¬ */
+	{'$', '$',   177},	/* £ */
+	{'Y', '-',   178},	/* ¥ */
+	{'~', '.',   179},	/* · */
+	{'c', 'O',   180},	/* © */
+	{'p', 'a',   181},	/* § */
+	{'p', 'p',   182},	/* ¶ */
+	{'1', '4',   183},	/* ¼ */
+	{'1', '2',   184},	/* ½ */
+	{'3', '4',   185},	/* ¾ */
+	{'Y', '\'',  186},	/* Ý */
+	{'"', '"',   187},	/* ¨ */
+	{'-', '=',   188},	/* ¯ */
+	{'\'', '\'', 190},	/* ´ */
+	{'O', 'E',   191},	/* × - OE in ISO 8859-15 */
+	{'/', '\\',  191},	/* × - multiplication symbol in ISO 8859-1 */
+	{'-', '-',   202},	/* ­ */
+	{'o', '^',   203},	/* ô */
+	{'o', '"',   204},	/* ö */
+	{'o', '`',   205},	/* ò */
+	{'o', '\'',  206},	/* ó */
+	{'o', '~',   207},	/* õ */
+	{'1', '1',   218},	/* ¹ */
+	{'u', '^',   219},	/* û */
+	{'u', '"',   220},	/* ü */
+	{'u', '`',   221},	/* ù */
+	{'u', '\'',  222},	/* ú */
+	{':', '-',   225},	/* ÷ - division symbol in ISO 8859-1 */
+	{'o', 'e',   225},	/* ÷ - oe in ISO 8859-15 */
+	{'2', '2',   234},	/* ² */
+	{'O', '^',   235},	/* Ô */
+	{'O', '"',   236},	/* Ö */
+	{'O', '`',   237},	/* Ò */
+	{'O', '\'',  238},	/* Ó */
+	{'O', '~',   239},	/* Õ */
+	{'3', '3',   250},	/* ³ */
+	{'U', '^',   251},	/* Û */
+	{'U', '"',   252},	/* Ü */
+	{'U', '`',   253},	/* Ù */
+	{'U', '\'',  254},	/* Ú */
+	{NUL, NUL, NUL}
+	};
+
+#   else
+#    if defined(MACOS) && !defined(FEAT_MBYTE)
+
+	/*
+	 * Macintosh digraphs
+	 */
+       {{'a', 't', 64},		/* @ */
+	{'A', '"', 128},	/* ~@ XX */
+	{'A', 'o', 129},	/* Å */
+	{'C', ',', 130},	/* Ç */
+	{'E', '\'', 131},	/* É */
+	{'N', '~', 132},	/* Ñ */
+	{'O', '"', 133},	/* Ö */
+	{'U', '"', 134},	/* Ü */
+	{'a', '\'', 135},	/* ~G XX */
+	{'a', '`', 136},	/* ~H XX */
+	{'a', '^', 137},	/* â */
+	{'a', '"', 138},	/* ä */
+	{'a', '~', 139},	/* ã */
+	{'a', 'o', 140},	/* å */
+	{'c', ',', 141},	/* ç */
+	{'e', '\'', 142},	/* é */
+	{'e', '`', 143},	/* è */
+	{'e', '^', 144},	/* ê */
+	{'e', '"', 145},	/* ë */
+	{'i', '\'', 146},	/* í */
+	{'i', '`', 147},	/* ì */
+	{'i', '^', 148},	/* î */
+	{'i', '"', 149},	/* ï */
+	{'n', '~', 150},	/* ñ */
+	{'o', '\'', 151},	/* ó */
+	{'o', '`', 152},	/* ò */
+	{'o', '^', 153},	/* ô */
+	{'o', '"', 154},	/* ö */
+	{'o', '~', 155},	/* o */
+	{'u', '\'', 156},	/* ú */
+	{'u', '`', 157},	/* ~] XX */
+	{'u', '^', 158},	/* û */
+	{'u', '"', 159},	/* ü */
+	{'+', '_', 160},	/* Ý */
+	{'~', 'o', 161},	/* ° */
+	{'c', '|', 162},	/* ¢ */
+	{'$', '$', 163},	/* £ */
+	{'p', 'a', 164},	/* § */
+	{'.', '.', 165},	/* * */
+	{'P', 'P', 166},	/* ¶ */
+	{'s', 's', 167},	/* ß */
+	{'r', 'O', 168},	/* ® */
+	{'c', 'O', 169},	/* © */
+	{'T', 'M', 170},	/*  */
+	{'=', '/', 173},	/* ‚ */
+	{'A', 'E', 174},	/* Æ */
+	{'O', '/', 175},	/* Ø */
+	{'0', '0', 176},	/* ƒ */
+	{'+', '-', 177},	/* ± */
+	{'<', '=', 178},	/* ¾ */
+	{'>', '=', 179},	/* „ */
+	{'Y', '-', 180},	/* ¥ */
+	{'j', 'u', 181},	/* µ */
+	{'m', 'u', 181},	/* µ */
+	{'d', 'd', 182},	/*  */
+	{'S', 'S', 183},	/* … */
+	{'S', 'I', 183},	/* … */
+	{'P', 'I', 184},	/* ½ */
+	{'p', 'i', 185},	/* ¼ */
+	{'I', 'I', 186},	/* † */
+	{'a', '-', 187},	/* » */
+	{'o', '-', 188},	/* º */
+	{'O', 'M', 189},	/* ½ */
+	{'a', 'e', 190},	/* æ */
+	{'o', '/', 191},	/* ø */
+	{'~', '?', 192},	/* ¿ */
+	{'~', '!', 193},	/* ¡ */
+	{'-', ',', 194},	/* ¬ */
+	{'v', '-', 195},	/* ~H XX */
+	{'f', '-', 196},	/* Ÿ */
+	{'~', '~', 197},	/* ‰ */
+	{'D', 'E', 198},	/*  */
+	{'<', '<', 199},	/* « */
+	{'>', '>', 200},	/* » */
+	{'.', ':', 201},	/* Š */
+	{'A', '`', 203},	/* À */
+	{'A', '~', 204},	/* Ã */
+	{'O', '~', 205},	/* Õ */
+	{'O', 'E', 206},	/* ‘ */
+	{'o', 'e', 207},	/* ¦ */
+	{'-', '.', 208},	/* - */
+	{'-', '-', 209},	/* - */
+	{'`', '`', 210},	/* " */
+	{'\'', '\'', 211},	/* " */
+	{'`', ' ', 212},	/* ' */
+	{'\'', ' ', 213},	/* ' */
+	{'-', ':', 214},	/* ÷ */
+	{'D', 'I', 215},	/* × */
+	{'y', ':', 216},	/* ÿ */
+	{'Y', ':', 217},	/*  */
+	{'/', '/', 218},	/* Ž */
+	{'E', '=', 219},	/* ¤ Euro System >=8.5 */
+	{'o', 'x', 219},	/* ¤ Currency System <=8.1*/
+	{'<', ' ', 220},	/* Ð */
+	{'>', ' ', 221},	/* ð */
+	{'f', 'i', 222},	/* Þ */
+	{'f', 'l', 223},	/* þ */
+	{'+', '+', 224},	/* ý */
+	{'~', '.', 225},	/* · */
+	{',', ' ', 226},	/* ’ */
+	{',', ',', 227},	/* “ */
+	{'%', '.', 228},	/* ” */
+	{'%', '0', 228},	/* ” */
+	{'A', '^', 229},	/* Â */
+	{'E', '^', 230},	/* Ê */
+	{'A', '\'', 231},	/* Á */
+	{'E', '"', 232},	/* Ë */
+	{'E', '`', 233},	/* È */
+	{'I', '\'', 234},	/* Í */
+	{'I', '^', 235},	/* Î */
+	{'I', '"', 236},	/* Ï */
+	{'I', '`', 237},	/* Ì */
+	{'O', '\'', 238},	/* Ó */
+	{'O', '^', 239},	/* Ô */
+	{'A', 'P', 240},	/* • */
+	{'O', '`', 241},	/* Ò */
+	{'U', '\'', 242},	/* Ú */
+	{'U', '^', 243},	/* Û */
+	{'U', '`', 244},	/* Ù */
+	{'i', '.', 245},	/* ž */
+	{NUL, NUL, NUL}
+	};
+
+#    else	/* !MACOS */
+
+#     ifdef OLD_DIGRAPHS
+
+	/*
+	 * digraphs compatible with Vim 5.x
+	 */
+       {{'~', '!', 161},	/* ¡ */
+	{'c', '|', 162},	/* ¢ */
+	{'$', '$', 163},	/* £ */
+	{'o', 'x', 164},	/* ¤ - currency symbol in ISO 8859-1 */
+	{'e', '=', 164},	/* ¤ - euro symbol in ISO 8859-15 */
+	{'Y', '-', 165},	/* ¥ */
+	{'|', '|', 166},	/* ¦ */
+	{'p', 'a', 167},	/* § */
+	{'"', '"', 168},	/* ¨ */
+	{'c', 'O', 169},	/* © */
+	{'a', '-', 170},	/* ª */
+	{'<', '<', 171},	/* « */
+	{'-', ',', 172},	/* ¬ */
+	{'-', '-', 173},	/* ­ */
+	{'r', 'O', 174},	/* ® */
+	{'-', '=', 175},	/* ¯ */
+	{'~', 'o', 176},	/* ° */
+	{'+', '-', 177},	/* ± */
+	{'2', '2', 178},	/* ² */
+	{'3', '3', 179},	/* ³ */
+	{'\'', '\'', 180},	/* ´ */
+	{'j', 'u', 181},	/* µ */
+	{'p', 'p', 182},	/* ¶ */
+	{'~', '.', 183},	/* · */
+	{',', ',', 184},	/* ¸ */
+	{'1', '1', 185},	/* ¹ */
+	{'o', '-', 186},	/* º */
+	{'>', '>', 187},	/* » */
+	{'1', '4', 188},	/* ¼ */
+	{'1', '2', 189},	/* ½ */
+	{'3', '4', 190},	/* ¾ */
+	{'~', '?', 191},	/* ¿ */
+	{'A', '`', 192},	/* À */
+	{'A', '\'', 193},	/* Á */
+	{'A', '^', 194},	/* Â */
+	{'A', '~', 195},	/* Ã */
+	{'A', '"', 196},	/* Ä */
+	{'A', '@', 197},	/* Å */
+	{'A', 'A', 197},	/* Å */
+	{'A', 'E', 198},	/* Æ */
+	{'C', ',', 199},	/* Ç */
+	{'E', '`', 200},	/* È */
+	{'E', '\'', 201},	/* É */
+	{'E', '^', 202},	/* Ê */
+	{'E', '"', 203},	/* Ë */
+	{'I', '`', 204},	/* Ì */
+	{'I', '\'', 205},	/* Í */
+	{'I', '^', 206},	/* Î */
+	{'I', '"', 207},	/* Ï */
+	{'D', '-', 208},	/* Ð */
+	{'N', '~', 209},	/* Ñ */
+	{'O', '`', 210},	/* Ò */
+	{'O', '\'', 211},	/* Ó */
+	{'O', '^', 212},	/* Ô */
+	{'O', '~', 213},	/* Õ */
+	{'O', '"', 214},	/* Ö */
+	{'/', '\\', 215},	/* × - multiplication symbol in ISO 8859-1 */
+	{'O', 'E', 215},	/* × - OE in ISO 8859-15 */
+	{'O', '/', 216},	/* Ø */
+	{'U', '`', 217},	/* Ù */
+	{'U', '\'', 218},	/* Ú */
+	{'U', '^', 219},	/* Û */
+	{'U', '"', 220},	/* Ü */
+	{'Y', '\'', 221},	/* Ý */
+	{'I', 'p', 222},	/* Þ */
+	{'s', 's', 223},	/* ß */
+	{'a', '`', 224},	/* à */
+	{'a', '\'', 225},	/* á */
+	{'a', '^', 226},	/* â */
+	{'a', '~', 227},	/* ã */
+	{'a', '"', 228},	/* ä */
+	{'a', '@', 229},	/* å */
+	{'a', 'a', 229},	/* å */
+	{'a', 'e', 230},	/* æ */
+	{'c', ',', 231},	/* ç */
+	{'e', '`', 232},	/* è */
+	{'e', '\'', 233},	/* é */
+	{'e', '^', 234},	/* ê */
+	{'e', '"', 235},	/* ë */
+	{'i', '`', 236},	/* ì */
+	{'i', '\'', 237},	/* í */
+	{'i', '^', 238},	/* î */
+	{'i', '"', 239},	/* ï */
+	{'d', '-', 240},	/* ð */
+	{'n', '~', 241},	/* ñ */
+	{'o', '`', 242},	/* ò */
+	{'o', '\'', 243},	/* ó */
+	{'o', '^', 244},	/* ô */
+	{'o', '~', 245},	/* õ */
+	{'o', '"', 246},	/* ö */
+	{':', '-', 247},	/* ÷ - division symbol in ISO 8859-1 */
+	{'o', 'e', 247},	/* ÷ - oe in ISO 8859-15 */
+	{'o', '/', 248},	/* ø */
+	{'u', '`', 249},	/* ù */
+	{'u', '\'', 250},	/* ú */
+	{'u', '^', 251},	/* û */
+	{'u', '"', 252},	/* ü */
+	{'y', '\'', 253},	/* ý */
+	{'i', 'p', 254},	/* þ */
+	{'y', '"', 255},	/* x XX */
+	{NUL, NUL, NUL}
+	};
+#     else /* OLD_DIGRAPHS */
+
+	/*
+	 * digraphs for Unicode from RFC1345
+	 * (also work for ISO-8859-1 aka latin1)
+	 */
+       {
+	{'N', 'U', 0x0a},	/* LF for NUL */
+	{'S', 'H', 0x01},
+	{'S', 'X', 0x02},
+	{'E', 'X', 0x03},
+	{'E', 'T', 0x04},
+	{'E', 'Q', 0x05},
+	{'A', 'K', 0x06},
+	{'B', 'L', 0x07},
+	{'B', 'S', 0x08},
+	{'H', 'T', 0x09},
+	{'L', 'F', 0x0a},
+	{'V', 'T', 0x0b},
+	{'F', 'F', 0x0c},
+	{'C', 'R', 0x0d},
+	{'S', 'O', 0x0e},
+	{'S', 'I', 0x0f},
+	{'D', 'L', 0x10},
+	{'D', '1', 0x11},
+	{'D', '2', 0x12},
+	{'D', '3', 0x13},
+	{'D', '4', 0x14},
+	{'N', 'K', 0x15},
+	{'S', 'Y', 0x16},
+	{'E', 'B', 0x17},
+	{'C', 'N', 0x18},
+	{'E', 'M', 0x19},
+	{'S', 'B', 0x1a},
+	{'E', 'C', 0x1b},
+	{'F', 'S', 0x1c},
+	{'G', 'S', 0x1d},
+	{'R', 'S', 0x1e},
+	{'U', 'S', 0x1f},
+	{'S', 'P', 0x20},
+	{'N', 'b', 0x23},
+	{'D', 'O', 0x24},
+	{'A', 't', 0x40},
+	{'<', '(', 0x5b},
+	{'/', '/', 0x5c},
+	{')', '>', 0x5d},
+	{'\'', '>', 0x5e},
+	{'\'', '!', 0x60},
+	{'(', '!', 0x7b},
+	{'!', '!', 0x7c},
+	{'!', ')', 0x7d},
+	{'\'', '?', 0x7e},
+	{'D', 'T', 0x7f},
+	{'P', 'A', 0x80},
+	{'H', 'O', 0x81},
+	{'B', 'H', 0x82},
+	{'N', 'H', 0x83},
+	{'I', 'N', 0x84},
+	{'N', 'L', 0x85},
+	{'S', 'A', 0x86},
+	{'E', 'S', 0x87},
+	{'H', 'S', 0x88},
+	{'H', 'J', 0x89},
+	{'V', 'S', 0x8a},
+	{'P', 'D', 0x8b},
+	{'P', 'U', 0x8c},
+	{'R', 'I', 0x8d},
+	{'S', '2', 0x8e},
+	{'S', '3', 0x8f},
+	{'D', 'C', 0x90},
+	{'P', '1', 0x91},
+	{'P', '2', 0x92},
+	{'T', 'S', 0x93},
+	{'C', 'C', 0x94},
+	{'M', 'W', 0x95},
+	{'S', 'G', 0x96},
+	{'E', 'G', 0x97},
+	{'S', 'S', 0x98},
+	{'G', 'C', 0x99},
+	{'S', 'C', 0x9a},
+	{'C', 'I', 0x9b},
+	{'S', 'T', 0x9c},
+	{'O', 'C', 0x9d},
+	{'P', 'M', 0x9e},
+	{'A', 'C', 0x9f},
+	{'N', 'S', 0xa0},
+	{'!', 'I', 0xa1},
+	{'C', 't', 0xa2},
+	{'P', 'd', 0xa3},
+	{'C', 'u', 0xa4},
+	{'Y', 'e', 0xa5},
+	{'B', 'B', 0xa6},
+	{'S', 'E', 0xa7},
+	{'\'', ':', 0xa8},
+	{'C', 'o', 0xa9},
+	{'-', 'a', 0xaa},
+	{'<', '<', 0xab},
+	{'N', 'O', 0xac},
+	{'-', '-', 0xad},
+	{'R', 'g', 0xae},
+	{'\'', 'm', 0xaf},
+	{'D', 'G', 0xb0},
+	{'+', '-', 0xb1},
+	{'2', 'S', 0xb2},
+	{'3', 'S', 0xb3},
+	{'\'', '\'', 0xb4},
+	{'M', 'y', 0xb5},
+	{'P', 'I', 0xb6},
+	{'.', 'M', 0xb7},
+	{'\'', ',', 0xb8},
+	{'1', 'S', 0xb9},
+	{'-', 'o', 0xba},
+	{'>', '>', 0xbb},
+	{'1', '4', 0xbc},
+	{'1', '2', 0xbd},
+	{'3', '4', 0xbe},
+	{'?', 'I', 0xbf},
+	{'A', '!', 0xc0},
+	{'A', '\'', 0xc1},
+	{'A', '>', 0xc2},
+	{'A', '?', 0xc3},
+	{'A', ':', 0xc4},
+	{'A', 'A', 0xc5},
+	{'A', 'E', 0xc6},
+	{'C', ',', 0xc7},
+	{'E', '!', 0xc8},
+	{'E', '\'', 0xc9},
+	{'E', '>', 0xca},
+	{'E', ':', 0xcb},
+	{'I', '!', 0xcc},
+	{'I', '\'', 0xcd},
+	{'I', '>', 0xce},
+	{'I', ':', 0xcf},
+	{'D', '-', 0xd0},
+	{'N', '?', 0xd1},
+	{'O', '!', 0xd2},
+	{'O', '\'', 0xd3},
+	{'O', '>', 0xd4},
+	{'O', '?', 0xd5},
+	{'O', ':', 0xd6},
+	{'*', 'X', 0xd7},
+	{'O', '/', 0xd8},
+	{'U', '!', 0xd9},
+	{'U', '\'', 0xda},
+	{'U', '>', 0xdb},
+	{'U', ':', 0xdc},
+	{'Y', '\'', 0xdd},
+	{'T', 'H', 0xde},
+	{'s', 's', 0xdf},
+	{'a', '!', 0xe0},
+	{'a', '\'', 0xe1},
+	{'a', '>', 0xe2},
+	{'a', '?', 0xe3},
+	{'a', ':', 0xe4},
+	{'a', 'a', 0xe5},
+	{'a', 'e', 0xe6},
+	{'c', ',', 0xe7},
+	{'e', '!', 0xe8},
+	{'e', '\'', 0xe9},
+	{'e', '>', 0xea},
+	{'e', ':', 0xeb},
+	{'i', '!', 0xec},
+	{'i', '\'', 0xed},
+	{'i', '>', 0xee},
+	{'i', ':', 0xef},
+	{'d', '-', 0xf0},
+	{'n', '?', 0xf1},
+	{'o', '!', 0xf2},
+	{'o', '\'', 0xf3},
+	{'o', '>', 0xf4},
+	{'o', '?', 0xf5},
+	{'o', ':', 0xf6},
+	{'-', ':', 0xf7},
+	{'o', '/', 0xf8},
+	{'u', '!', 0xf9},
+	{'u', '\'', 0xfa},
+	{'u', '>', 0xfb},
+	{'u', ':', 0xfc},
+	{'y', '\'', 0xfd},
+	{'t', 'h', 0xfe},
+	{'y', ':', 0xff},
+
+#      ifdef FEAT_MBYTE
+#	define USE_UNICODE_DIGRAPHS
+
+	{'A', '-', 0x0100},
+	{'a', '-', 0x0101},
+	{'A', '(', 0x0102},
+	{'a', '(', 0x0103},
+	{'A', ';', 0x0104},
+	{'a', ';', 0x0105},
+	{'C', '\'', 0x0106},
+	{'c', '\'', 0x0107},
+	{'C', '>', 0x0108},
+	{'c', '>', 0x0109},
+	{'C', '.', 0x010a},
+	{'c', '.', 0x010b},
+	{'C', '<', 0x010c},
+	{'c', '<', 0x010d},
+	{'D', '<', 0x010e},
+	{'d', '<', 0x010f},
+	{'D', '/', 0x0110},
+	{'d', '/', 0x0111},
+	{'E', '-', 0x0112},
+	{'e', '-', 0x0113},
+	{'E', '(', 0x0114},
+	{'e', '(', 0x0115},
+	{'E', '.', 0x0116},
+	{'e', '.', 0x0117},
+	{'E', ';', 0x0118},
+	{'e', ';', 0x0119},
+	{'E', '<', 0x011a},
+	{'e', '<', 0x011b},
+	{'G', '>', 0x011c},
+	{'g', '>', 0x011d},
+	{'G', '(', 0x011e},
+	{'g', '(', 0x011f},
+	{'G', '.', 0x0120},
+	{'g', '.', 0x0121},
+	{'G', ',', 0x0122},
+	{'g', ',', 0x0123},
+	{'H', '>', 0x0124},
+	{'h', '>', 0x0125},
+	{'H', '/', 0x0126},
+	{'h', '/', 0x0127},
+	{'I', '?', 0x0128},
+	{'i', '?', 0x0129},
+	{'I', '-', 0x012a},
+	{'i', '-', 0x012b},
+	{'I', '(', 0x012c},
+	{'i', '(', 0x012d},
+	{'I', ';', 0x012e},
+	{'i', ';', 0x012f},
+	{'I', '.', 0x0130},
+	{'i', '.', 0x0131},
+	{'I', 'J', 0x0132},
+	{'i', 'j', 0x0133},
+	{'J', '>', 0x0134},
+	{'j', '>', 0x0135},
+	{'K', ',', 0x0136},
+	{'k', ',', 0x0137},
+	{'k', 'k', 0x0138},
+	{'L', '\'', 0x0139},
+	{'l', '\'', 0x013a},
+	{'L', ',', 0x013b},
+	{'l', ',', 0x013c},
+	{'L', '<', 0x013d},
+	{'l', '<', 0x013e},
+	{'L', '.', 0x013f},
+	{'l', '.', 0x0140},
+	{'L', '/', 0x0141},
+	{'l', '/', 0x0142},
+	{'N', '\'', 0x0143},
+	{'n', '\'', 0x0144},
+	{'N', ',', 0x0145},
+	{'n', ',', 0x0146},
+	{'N', '<', 0x0147},
+	{'n', '<', 0x0148},
+	{'\'', 'n', 0x0149},
+	{'N', 'G', 0x014a},
+	{'n', 'g', 0x014b},
+	{'O', '-', 0x014c},
+	{'o', '-', 0x014d},
+	{'O', '(', 0x014e},
+	{'o', '(', 0x014f},
+	{'O', '"', 0x0150},
+	{'o', '"', 0x0151},
+	{'O', 'E', 0x0152},
+	{'o', 'e', 0x0153},
+	{'R', '\'', 0x0154},
+	{'r', '\'', 0x0155},
+	{'R', ',', 0x0156},
+	{'r', ',', 0x0157},
+	{'R', '<', 0x0158},
+	{'r', '<', 0x0159},
+	{'S', '\'', 0x015a},
+	{'s', '\'', 0x015b},
+	{'S', '>', 0x015c},
+	{'s', '>', 0x015d},
+	{'S', ',', 0x015e},
+	{'s', ',', 0x015f},
+	{'S', '<', 0x0160},
+	{'s', '<', 0x0161},
+	{'T', ',', 0x0162},
+	{'t', ',', 0x0163},
+	{'T', '<', 0x0164},
+	{'t', '<', 0x0165},
+	{'T', '/', 0x0166},
+	{'t', '/', 0x0167},
+	{'U', '?', 0x0168},
+	{'u', '?', 0x0169},
+	{'U', '-', 0x016a},
+	{'u', '-', 0x016b},
+	{'U', '(', 0x016c},
+	{'u', '(', 0x016d},
+	{'U', '0', 0x016e},
+	{'u', '0', 0x016f},
+	{'U', '"', 0x0170},
+	{'u', '"', 0x0171},
+	{'U', ';', 0x0172},
+	{'u', ';', 0x0173},
+	{'W', '>', 0x0174},
+	{'w', '>', 0x0175},
+	{'Y', '>', 0x0176},
+	{'y', '>', 0x0177},
+	{'Y', ':', 0x0178},
+	{'Z', '\'', 0x0179},
+	{'z', '\'', 0x017a},
+	{'Z', '.', 0x017b},
+	{'z', '.', 0x017c},
+	{'Z', '<', 0x017d},
+	{'z', '<', 0x017e},
+	{'O', '9', 0x01a0},
+	{'o', '9', 0x01a1},
+	{'O', 'I', 0x01a2},
+	{'o', 'i', 0x01a3},
+	{'y', 'r', 0x01a6},
+	{'U', '9', 0x01af},
+	{'u', '9', 0x01b0},
+	{'Z', '/', 0x01b5},
+	{'z', '/', 0x01b6},
+	{'E', 'D', 0x01b7},
+	{'A', '<', 0x01cd},
+	{'a', '<', 0x01ce},
+	{'I', '<', 0x01cf},
+	{'i', '<', 0x01d0},
+	{'O', '<', 0x01d1},
+	{'o', '<', 0x01d2},
+	{'U', '<', 0x01d3},
+	{'u', '<', 0x01d4},
+	{'A', '1', 0x01de},
+	{'a', '1', 0x01df},
+	{'A', '7', 0x01e0},
+	{'a', '7', 0x01e1},
+	{'A', '3', 0x01e2},
+	{'a', '3', 0x01e3},
+	{'G', '/', 0x01e4},
+	{'g', '/', 0x01e5},
+	{'G', '<', 0x01e6},
+	{'g', '<', 0x01e7},
+	{'K', '<', 0x01e8},
+	{'k', '<', 0x01e9},
+	{'O', ';', 0x01ea},
+	{'o', ';', 0x01eb},
+	{'O', '1', 0x01ec},
+	{'o', '1', 0x01ed},
+	{'E', 'Z', 0x01ee},
+	{'e', 'z', 0x01ef},
+	{'j', '<', 0x01f0},
+	{'G', '\'', 0x01f4},
+	{'g', '\'', 0x01f5},
+	{';', 'S', 0x02bf},
+	{'\'', '<', 0x02c7},
+	{'\'', '(', 0x02d8},
+	{'\'', '.', 0x02d9},
+	{'\'', '0', 0x02da},
+	{'\'', ';', 0x02db},
+	{'\'', '"', 0x02dd},
+	{'A', '%', 0x0386},
+	{'E', '%', 0x0388},
+	{'Y', '%', 0x0389},
+	{'I', '%', 0x038a},
+	{'O', '%', 0x038c},
+	{'U', '%', 0x038e},
+	{'W', '%', 0x038f},
+	{'i', '3', 0x0390},
+	{'A', '*', 0x0391},
+	{'B', '*', 0x0392},
+	{'G', '*', 0x0393},
+	{'D', '*', 0x0394},
+	{'E', '*', 0x0395},
+	{'Z', '*', 0x0396},
+	{'Y', '*', 0x0397},
+	{'H', '*', 0x0398},
+	{'I', '*', 0x0399},
+	{'K', '*', 0x039a},
+	{'L', '*', 0x039b},
+	{'M', '*', 0x039c},
+	{'N', '*', 0x039d},
+	{'C', '*', 0x039e},
+	{'O', '*', 0x039f},
+	{'P', '*', 0x03a0},
+	{'R', '*', 0x03a1},
+	{'S', '*', 0x03a3},
+	{'T', '*', 0x03a4},
+	{'U', '*', 0x03a5},
+	{'F', '*', 0x03a6},
+	{'X', '*', 0x03a7},
+	{'Q', '*', 0x03a8},
+	{'W', '*', 0x03a9},
+	{'J', '*', 0x03aa},
+	{'V', '*', 0x03ab},
+	{'a', '%', 0x03ac},
+	{'e', '%', 0x03ad},
+	{'y', '%', 0x03ae},
+	{'i', '%', 0x03af},
+	{'u', '3', 0x03b0},
+	{'a', '*', 0x03b1},
+	{'b', '*', 0x03b2},
+	{'g', '*', 0x03b3},
+	{'d', '*', 0x03b4},
+	{'e', '*', 0x03b5},
+	{'z', '*', 0x03b6},
+	{'y', '*', 0x03b7},
+	{'h', '*', 0x03b8},
+	{'i', '*', 0x03b9},
+	{'k', '*', 0x03ba},
+	{'l', '*', 0x03bb},
+	{'m', '*', 0x03bc},
+	{'n', '*', 0x03bd},
+	{'c', '*', 0x03be},
+	{'o', '*', 0x03bf},
+	{'p', '*', 0x03c0},
+	{'r', '*', 0x03c1},
+	{'*', 's', 0x03c2},
+	{'s', '*', 0x03c3},
+	{'t', '*', 0x03c4},
+	{'u', '*', 0x03c5},
+	{'f', '*', 0x03c6},
+	{'x', '*', 0x03c7},
+	{'q', '*', 0x03c8},
+	{'w', '*', 0x03c9},
+	{'j', '*', 0x03ca},
+	{'v', '*', 0x03cb},
+	{'o', '%', 0x03cc},
+	{'u', '%', 0x03cd},
+	{'w', '%', 0x03ce},
+	{'\'', 'G', 0x03d8},
+	{',', 'G', 0x03d9},
+	{'T', '3', 0x03da},
+	{'t', '3', 0x03db},
+	{'M', '3', 0x03dc},
+	{'m', '3', 0x03dd},
+	{'K', '3', 0x03de},
+	{'k', '3', 0x03df},
+	{'P', '3', 0x03e0},
+	{'p', '3', 0x03e1},
+	{'\'', '%', 0x03f4},
+	{'j', '3', 0x03f5},
+	{'I', 'O', 0x0401},
+	{'D', '%', 0x0402},
+	{'G', '%', 0x0403},
+	{'I', 'E', 0x0404},
+	{'D', 'S', 0x0405},
+	{'I', 'I', 0x0406},
+	{'Y', 'I', 0x0407},
+	{'J', '%', 0x0408},
+	{'L', 'J', 0x0409},
+	{'N', 'J', 0x040a},
+	{'T', 's', 0x040b},
+	{'K', 'J', 0x040c},
+	{'V', '%', 0x040e},
+	{'D', 'Z', 0x040f},
+	{'A', '=', 0x0410},
+	{'B', '=', 0x0411},
+	{'V', '=', 0x0412},
+	{'G', '=', 0x0413},
+	{'D', '=', 0x0414},
+	{'E', '=', 0x0415},
+	{'Z', '%', 0x0416},
+	{'Z', '=', 0x0417},
+	{'I', '=', 0x0418},
+	{'J', '=', 0x0419},
+	{'K', '=', 0x041a},
+	{'L', '=', 0x041b},
+	{'M', '=', 0x041c},
+	{'N', '=', 0x041d},
+	{'O', '=', 0x041e},
+	{'P', '=', 0x041f},
+	{'R', '=', 0x0420},
+	{'S', '=', 0x0421},
+	{'T', '=', 0x0422},
+	{'U', '=', 0x0423},
+	{'F', '=', 0x0424},
+	{'H', '=', 0x0425},
+	{'C', '=', 0x0426},
+	{'C', '%', 0x0427},
+	{'S', '%', 0x0428},
+	{'S', 'c', 0x0429},
+	{'=', '"', 0x042a},
+	{'Y', '=', 0x042b},
+	{'%', '"', 0x042c},
+	{'J', 'E', 0x042d},
+	{'J', 'U', 0x042e},
+	{'J', 'A', 0x042f},
+	{'a', '=', 0x0430},
+	{'b', '=', 0x0431},
+	{'v', '=', 0x0432},
+	{'g', '=', 0x0433},
+	{'d', '=', 0x0434},
+	{'e', '=', 0x0435},
+	{'z', '%', 0x0436},
+	{'z', '=', 0x0437},
+	{'i', '=', 0x0438},
+	{'j', '=', 0x0439},
+	{'k', '=', 0x043a},
+	{'l', '=', 0x043b},
+	{'m', '=', 0x043c},
+	{'n', '=', 0x043d},
+	{'o', '=', 0x043e},
+	{'p', '=', 0x043f},
+	{'r', '=', 0x0440},
+	{'s', '=', 0x0441},
+	{'t', '=', 0x0442},
+	{'u', '=', 0x0443},
+	{'f', '=', 0x0444},
+	{'h', '=', 0x0445},
+	{'c', '=', 0x0446},
+	{'c', '%', 0x0447},
+	{'s', '%', 0x0448},
+	{'s', 'c', 0x0449},
+	{'=', '\'', 0x044a},
+	{'y', '=', 0x044b},
+	{'%', '\'', 0x044c},
+	{'j', 'e', 0x044d},
+	{'j', 'u', 0x044e},
+	{'j', 'a', 0x044f},
+	{'i', 'o', 0x0451},
+	{'d', '%', 0x0452},
+	{'g', '%', 0x0453},
+	{'i', 'e', 0x0454},
+	{'d', 's', 0x0455},
+	{'i', 'i', 0x0456},
+	{'y', 'i', 0x0457},
+	{'j', '%', 0x0458},
+	{'l', 'j', 0x0459},
+	{'n', 'j', 0x045a},
+	{'t', 's', 0x045b},
+	{'k', 'j', 0x045c},
+	{'v', '%', 0x045e},
+	{'d', 'z', 0x045f},
+	{'Y', '3', 0x0462},
+	{'y', '3', 0x0463},
+	{'O', '3', 0x046a},
+	{'o', '3', 0x046b},
+	{'F', '3', 0x0472},
+	{'f', '3', 0x0473},
+	{'V', '3', 0x0474},
+	{'v', '3', 0x0475},
+	{'C', '3', 0x0480},
+	{'c', '3', 0x0481},
+	{'G', '3', 0x0490},
+	{'g', '3', 0x0491},
+	{'A', '+', 0x05d0},
+	{'B', '+', 0x05d1},
+	{'G', '+', 0x05d2},
+	{'D', '+', 0x05d3},
+	{'H', '+', 0x05d4},
+	{'W', '+', 0x05d5},
+	{'Z', '+', 0x05d6},
+	{'X', '+', 0x05d7},
+	{'T', 'j', 0x05d8},
+	{'J', '+', 0x05d9},
+	{'K', '%', 0x05da},
+	{'K', '+', 0x05db},
+	{'L', '+', 0x05dc},
+	{'M', '%', 0x05dd},
+	{'M', '+', 0x05de},
+	{'N', '%', 0x05df},
+	{'N', '+', 0x05e0},
+	{'S', '+', 0x05e1},
+	{'E', '+', 0x05e2},
+	{'P', '%', 0x05e3},
+	{'P', '+', 0x05e4},
+	{'Z', 'j', 0x05e5},
+	{'Z', 'J', 0x05e6},
+	{'Q', '+', 0x05e7},
+	{'R', '+', 0x05e8},
+	{'S', 'h', 0x05e9},
+	{'T', '+', 0x05ea},
+	{',', '+', 0x060c},
+	{';', '+', 0x061b},
+	{'?', '+', 0x061f},
+	{'H', '\'', 0x0621},
+	{'a', 'M', 0x0622},
+	{'a', 'H', 0x0623},
+	{'w', 'H', 0x0624},
+	{'a', 'h', 0x0625},
+	{'y', 'H', 0x0626},
+	{'a', '+', 0x0627},
+	{'b', '+', 0x0628},
+	{'t', 'm', 0x0629},
+	{'t', '+', 0x062a},
+	{'t', 'k', 0x062b},
+	{'g', '+', 0x062c},
+	{'h', 'k', 0x062d},
+	{'x', '+', 0x062e},
+	{'d', '+', 0x062f},
+	{'d', 'k', 0x0630},
+	{'r', '+', 0x0631},
+	{'z', '+', 0x0632},
+	{'s', '+', 0x0633},
+	{'s', 'n', 0x0634},
+	{'c', '+', 0x0635},
+	{'d', 'd', 0x0636},
+	{'t', 'j', 0x0637},
+	{'z', 'H', 0x0638},
+	{'e', '+', 0x0639},
+	{'i', '+', 0x063a},
+	{'+', '+', 0x0640},
+	{'f', '+', 0x0641},
+	{'q', '+', 0x0642},
+	{'k', '+', 0x0643},
+	{'l', '+', 0x0644},
+	{'m', '+', 0x0645},
+	{'n', '+', 0x0646},
+	{'h', '+', 0x0647},
+	{'w', '+', 0x0648},
+	{'j', '+', 0x0649},
+	{'y', '+', 0x064a},
+	{':', '+', 0x064b},
+	{'"', '+', 0x064c},
+	{'=', '+', 0x064d},
+	{'/', '+', 0x064e},
+	{'\'', '+', 0x064f},
+	{'1', '+', 0x0650},
+	{'3', '+', 0x0651},
+	{'0', '+', 0x0652},
+	{'a', 'S', 0x0670},
+	{'p', '+', 0x067e},
+	{'v', '+', 0x06a4},
+	{'g', 'f', 0x06af},
+	{'0', 'a', 0x06f0},
+	{'1', 'a', 0x06f1},
+	{'2', 'a', 0x06f2},
+	{'3', 'a', 0x06f3},
+	{'4', 'a', 0x06f4},
+	{'5', 'a', 0x06f5},
+	{'6', 'a', 0x06f6},
+	{'7', 'a', 0x06f7},
+	{'8', 'a', 0x06f8},
+	{'9', 'a', 0x06f9},
+	{'B', '.', 0x1e02},
+	{'b', '.', 0x1e03},
+	{'B', '_', 0x1e06},
+	{'b', '_', 0x1e07},
+	{'D', '.', 0x1e0a},
+	{'d', '.', 0x1e0b},
+	{'D', '_', 0x1e0e},
+	{'d', '_', 0x1e0f},
+	{'D', ',', 0x1e10},
+	{'d', ',', 0x1e11},
+	{'F', '.', 0x1e1e},
+	{'f', '.', 0x1e1f},
+	{'G', '-', 0x1e20},
+	{'g', '-', 0x1e21},
+	{'H', '.', 0x1e22},
+	{'h', '.', 0x1e23},
+	{'H', ':', 0x1e26},
+	{'h', ':', 0x1e27},
+	{'H', ',', 0x1e28},
+	{'h', ',', 0x1e29},
+	{'K', '\'', 0x1e30},
+	{'k', '\'', 0x1e31},
+	{'K', '_', 0x1e34},
+	{'k', '_', 0x1e35},
+	{'L', '_', 0x1e3a},
+	{'l', '_', 0x1e3b},
+	{'M', '\'', 0x1e3e},
+	{'m', '\'', 0x1e3f},
+	{'M', '.', 0x1e40},
+	{'m', '.', 0x1e41},
+	{'N', '.', 0x1e44},
+	{'n', '.', 0x1e45},
+	{'N', '_', 0x1e48},
+	{'n', '_', 0x1e49},
+	{'P', '\'', 0x1e54},
+	{'p', '\'', 0x1e55},
+	{'P', '.', 0x1e56},
+	{'p', '.', 0x1e57},
+	{'R', '.', 0x1e58},
+	{'r', '.', 0x1e59},
+	{'R', '_', 0x1e5e},
+	{'r', '_', 0x1e5f},
+	{'S', '.', 0x1e60},
+	{'s', '.', 0x1e61},
+	{'T', '.', 0x1e6a},
+	{'t', '.', 0x1e6b},
+	{'T', '_', 0x1e6e},
+	{'t', '_', 0x1e6f},
+	{'V', '?', 0x1e7c},
+	{'v', '?', 0x1e7d},
+	{'W', '!', 0x1e80},
+	{'w', '!', 0x1e81},
+	{'W', '\'', 0x1e82},
+	{'w', '\'', 0x1e83},
+	{'W', ':', 0x1e84},
+	{'w', ':', 0x1e85},
+	{'W', '.', 0x1e86},
+	{'w', '.', 0x1e87},
+	{'X', '.', 0x1e8a},
+	{'x', '.', 0x1e8b},
+	{'X', ':', 0x1e8c},
+	{'x', ':', 0x1e8d},
+	{'Y', '.', 0x1e8e},
+	{'y', '.', 0x1e8f},
+	{'Z', '>', 0x1e90},
+	{'z', '>', 0x1e91},
+	{'Z', '_', 0x1e94},
+	{'z', '_', 0x1e95},
+	{'h', '_', 0x1e96},
+	{'t', ':', 0x1e97},
+	{'w', '0', 0x1e98},
+	{'y', '0', 0x1e99},
+	{'A', '2', 0x1ea2},
+	{'a', '2', 0x1ea3},
+	{'E', '2', 0x1eba},
+	{'e', '2', 0x1ebb},
+	{'E', '?', 0x1ebc},
+	{'e', '?', 0x1ebd},
+	{'I', '2', 0x1ec8},
+	{'i', '2', 0x1ec9},
+	{'O', '2', 0x1ece},
+	{'o', '2', 0x1ecf},
+	{'U', '2', 0x1ee6},
+	{'u', '2', 0x1ee7},
+	{'Y', '!', 0x1ef2},
+	{'y', '!', 0x1ef3},
+	{'Y', '2', 0x1ef6},
+	{'y', '2', 0x1ef7},
+	{'Y', '?', 0x1ef8},
+	{'y', '?', 0x1ef9},
+	{';', '\'', 0x1f00},
+	{',', '\'', 0x1f01},
+	{';', '!', 0x1f02},
+	{',', '!', 0x1f03},
+	{'?', ';', 0x1f04},
+	{'?', ',', 0x1f05},
+	{'!', ':', 0x1f06},
+	{'?', ':', 0x1f07},
+	{'1', 'N', 0x2002},
+	{'1', 'M', 0x2003},
+	{'3', 'M', 0x2004},
+	{'4', 'M', 0x2005},
+	{'6', 'M', 0x2006},
+	{'1', 'T', 0x2009},
+	{'1', 'H', 0x200a},
+	{'-', '1', 0x2010},
+	{'-', 'N', 0x2013},
+	{'-', 'M', 0x2014},
+	{'-', '3', 0x2015},
+	{'!', '2', 0x2016},
+	{'=', '2', 0x2017},
+	{'\'', '6', 0x2018},
+	{'\'', '9', 0x2019},
+	{'.', '9', 0x201a},
+	{'9', '\'', 0x201b},
+	{'"', '6', 0x201c},
+	{'"', '9', 0x201d},
+	{':', '9', 0x201e},
+	{'9', '"', 0x201f},
+	{'/', '-', 0x2020},
+	{'/', '=', 0x2021},
+	{'.', '.', 0x2025},
+	{'%', '0', 0x2030},
+	{'1', '\'', 0x2032},
+	{'2', '\'', 0x2033},
+	{'3', '\'', 0x2034},
+	{'1', '"', 0x2035},
+	{'2', '"', 0x2036},
+	{'3', '"', 0x2037},
+	{'C', 'a', 0x2038},
+	{'<', '1', 0x2039},
+	{'>', '1', 0x203a},
+	{':', 'X', 0x203b},
+	{'\'', '-', 0x203e},
+	{'/', 'f', 0x2044},
+	{'0', 'S', 0x2070},
+	{'4', 'S', 0x2074},
+	{'5', 'S', 0x2075},
+	{'6', 'S', 0x2076},
+	{'7', 'S', 0x2077},
+	{'8', 'S', 0x2078},
+	{'9', 'S', 0x2079},
+	{'+', 'S', 0x207a},
+	{'-', 'S', 0x207b},
+	{'=', 'S', 0x207c},
+	{'(', 'S', 0x207d},
+	{')', 'S', 0x207e},
+	{'n', 'S', 0x207f},
+	{'0', 's', 0x2080},
+	{'1', 's', 0x2081},
+	{'2', 's', 0x2082},
+	{'3', 's', 0x2083},
+	{'4', 's', 0x2084},
+	{'5', 's', 0x2085},
+	{'6', 's', 0x2086},
+	{'7', 's', 0x2087},
+	{'8', 's', 0x2088},
+	{'9', 's', 0x2089},
+	{'+', 's', 0x208a},
+	{'-', 's', 0x208b},
+	{'=', 's', 0x208c},
+	{'(', 's', 0x208d},
+	{')', 's', 0x208e},
+	{'L', 'i', 0x20a4},
+	{'P', 't', 0x20a7},
+	{'W', '=', 0x20a9},
+	{'=', 'e', 0x20ac}, /* euro */
+	{'E', 'u', 0x20ac}, /* euro */
+	{'o', 'C', 0x2103},
+	{'c', 'o', 0x2105},
+	{'o', 'F', 0x2109},
+	{'N', '0', 0x2116},
+	{'P', 'O', 0x2117},
+	{'R', 'x', 0x211e},
+	{'S', 'M', 0x2120},
+	{'T', 'M', 0x2122},
+	{'O', 'm', 0x2126},
+	{'A', 'O', 0x212b},
+	{'1', '3', 0x2153},
+	{'2', '3', 0x2154},
+	{'1', '5', 0x2155},
+	{'2', '5', 0x2156},
+	{'3', '5', 0x2157},
+	{'4', '5', 0x2158},
+	{'1', '6', 0x2159},
+	{'5', '6', 0x215a},
+	{'1', '8', 0x215b},
+	{'3', '8', 0x215c},
+	{'5', '8', 0x215d},
+	{'7', '8', 0x215e},
+	{'1', 'R', 0x2160},
+	{'2', 'R', 0x2161},
+	{'3', 'R', 0x2162},
+	{'4', 'R', 0x2163},
+	{'5', 'R', 0x2164},
+	{'6', 'R', 0x2165},
+	{'7', 'R', 0x2166},
+	{'8', 'R', 0x2167},
+	{'9', 'R', 0x2168},
+	{'a', 'R', 0x2169},
+	{'b', 'R', 0x216a},
+	{'c', 'R', 0x216b},
+	{'1', 'r', 0x2170},
+	{'2', 'r', 0x2171},
+	{'3', 'r', 0x2172},
+	{'4', 'r', 0x2173},
+	{'5', 'r', 0x2174},
+	{'6', 'r', 0x2175},
+	{'7', 'r', 0x2176},
+	{'8', 'r', 0x2177},
+	{'9', 'r', 0x2178},
+	{'a', 'r', 0x2179},
+	{'b', 'r', 0x217a},
+	{'c', 'r', 0x217b},
+	{'<', '-', 0x2190},
+	{'-', '!', 0x2191},
+	{'-', '>', 0x2192},
+	{'-', 'v', 0x2193},
+	{'<', '>', 0x2194},
+	{'U', 'D', 0x2195},
+	{'<', '=', 0x21d0},
+	{'=', '>', 0x21d2},
+	{'=', '=', 0x21d4},
+	{'F', 'A', 0x2200},
+	{'d', 'P', 0x2202},
+	{'T', 'E', 0x2203},
+	{'/', '0', 0x2205},
+	{'D', 'E', 0x2206},
+	{'N', 'B', 0x2207},
+	{'(', '-', 0x2208},
+	{'-', ')', 0x220b},
+	{'*', 'P', 0x220f},
+	{'+', 'Z', 0x2211},
+	{'-', '2', 0x2212},
+	{'-', '+', 0x2213},
+	{'*', '-', 0x2217},
+	{'O', 'b', 0x2218},
+	{'S', 'b', 0x2219},
+	{'R', 'T', 0x221a},
+	{'0', '(', 0x221d},
+	{'0', '0', 0x221e},
+	{'-', 'L', 0x221f},
+	{'-', 'V', 0x2220},
+	{'P', 'P', 0x2225},
+	{'A', 'N', 0x2227},
+	{'O', 'R', 0x2228},
+	{'(', 'U', 0x2229},
+	{')', 'U', 0x222a},
+	{'I', 'n', 0x222b},
+	{'D', 'I', 0x222c},
+	{'I', 'o', 0x222e},
+	{'.', ':', 0x2234},
+	{':', '.', 0x2235},
+	{':', 'R', 0x2236},
+	{':', ':', 0x2237},
+	{'?', '1', 0x223c},
+	{'C', 'G', 0x223e},
+	{'?', '-', 0x2243},
+	{'?', '=', 0x2245},
+	{'?', '2', 0x2248},
+	{'=', '?', 0x224c},
+	{'H', 'I', 0x2253},
+	{'!', '=', 0x2260},
+	{'=', '3', 0x2261},
+	{'=', '<', 0x2264},
+	{'>', '=', 0x2265},
+	{'<', '*', 0x226a},
+	{'*', '>', 0x226b},
+	{'!', '<', 0x226e},
+	{'!', '>', 0x226f},
+	{'(', 'C', 0x2282},
+	{')', 'C', 0x2283},
+	{'(', '_', 0x2286},
+	{')', '_', 0x2287},
+	{'0', '.', 0x2299},
+	{'0', '2', 0x229a},
+	{'-', 'T', 0x22a5},
+	{'.', 'P', 0x22c5},
+	{':', '3', 0x22ee},
+	{'.', '3', 0x22ef},
+	{'E', 'h', 0x2302},
+	{'<', '7', 0x2308},
+	{'>', '7', 0x2309},
+	{'7', '<', 0x230a},
+	{'7', '>', 0x230b},
+	{'N', 'I', 0x2310},
+	{'(', 'A', 0x2312},
+	{'T', 'R', 0x2315},
+	{'I', 'u', 0x2320},
+	{'I', 'l', 0x2321},
+	{'<', '/', 0x2329},
+	{'/', '>', 0x232a},
+	{'V', 's', 0x2423},
+	{'1', 'h', 0x2440},
+	{'3', 'h', 0x2441},
+	{'2', 'h', 0x2442},
+	{'4', 'h', 0x2443},
+	{'1', 'j', 0x2446},
+	{'2', 'j', 0x2447},
+	{'3', 'j', 0x2448},
+	{'4', 'j', 0x2449},
+	{'1', '.', 0x2488},
+	{'2', '.', 0x2489},
+	{'3', '.', 0x248a},
+	{'4', '.', 0x248b},
+	{'5', '.', 0x248c},
+	{'6', '.', 0x248d},
+	{'7', '.', 0x248e},
+	{'8', '.', 0x248f},
+	{'9', '.', 0x2490},
+	{'h', 'h', 0x2500},
+	{'H', 'H', 0x2501},
+	{'v', 'v', 0x2502},
+	{'V', 'V', 0x2503},
+	{'3', '-', 0x2504},
+	{'3', '_', 0x2505},
+	{'3', '!', 0x2506},
+	{'3', '/', 0x2507},
+	{'4', '-', 0x2508},
+	{'4', '_', 0x2509},
+	{'4', '!', 0x250a},
+	{'4', '/', 0x250b},
+	{'d', 'r', 0x250c},
+	{'d', 'R', 0x250d},
+	{'D', 'r', 0x250e},
+	{'D', 'R', 0x250f},
+	{'d', 'l', 0x2510},
+	{'d', 'L', 0x2511},
+	{'D', 'l', 0x2512},
+	{'L', 'D', 0x2513},
+	{'u', 'r', 0x2514},
+	{'u', 'R', 0x2515},
+	{'U', 'r', 0x2516},
+	{'U', 'R', 0x2517},
+	{'u', 'l', 0x2518},
+	{'u', 'L', 0x2519},
+	{'U', 'l', 0x251a},
+	{'U', 'L', 0x251b},
+	{'v', 'r', 0x251c},
+	{'v', 'R', 0x251d},
+	{'V', 'r', 0x2520},
+	{'V', 'R', 0x2523},
+	{'v', 'l', 0x2524},
+	{'v', 'L', 0x2525},
+	{'V', 'l', 0x2528},
+	{'V', 'L', 0x252b},
+	{'d', 'h', 0x252c},
+	{'d', 'H', 0x252f},
+	{'D', 'h', 0x2530},
+	{'D', 'H', 0x2533},
+	{'u', 'h', 0x2534},
+	{'u', 'H', 0x2537},
+	{'U', 'h', 0x2538},
+	{'U', 'H', 0x253b},
+	{'v', 'h', 0x253c},
+	{'v', 'H', 0x253f},
+	{'V', 'h', 0x2542},
+	{'V', 'H', 0x254b},
+	{'F', 'D', 0x2571},
+	{'B', 'D', 0x2572},
+	{'T', 'B', 0x2580},
+	{'L', 'B', 0x2584},
+	{'F', 'B', 0x2588},
+	{'l', 'B', 0x258c},
+	{'R', 'B', 0x2590},
+	{'.', 'S', 0x2591},
+	{':', 'S', 0x2592},
+	{'?', 'S', 0x2593},
+	{'f', 'S', 0x25a0},
+	{'O', 'S', 0x25a1},
+	{'R', 'O', 0x25a2},
+	{'R', 'r', 0x25a3},
+	{'R', 'F', 0x25a4},
+	{'R', 'Y', 0x25a5},
+	{'R', 'H', 0x25a6},
+	{'R', 'Z', 0x25a7},
+	{'R', 'K', 0x25a8},
+	{'R', 'X', 0x25a9},
+	{'s', 'B', 0x25aa},
+	{'S', 'R', 0x25ac},
+	{'O', 'r', 0x25ad},
+	{'U', 'T', 0x25b2},
+	{'u', 'T', 0x25b3},
+	{'P', 'R', 0x25b6},
+	{'T', 'r', 0x25b7},
+	{'D', 't', 0x25bc},
+	{'d', 'T', 0x25bd},
+	{'P', 'L', 0x25c0},
+	{'T', 'l', 0x25c1},
+	{'D', 'b', 0x25c6},
+	{'D', 'w', 0x25c7},
+	{'L', 'Z', 0x25ca},
+	{'0', 'm', 0x25cb},
+	{'0', 'o', 0x25ce},
+	{'0', 'M', 0x25cf},
+	{'0', 'L', 0x25d0},
+	{'0', 'R', 0x25d1},
+	{'S', 'n', 0x25d8},
+	{'I', 'c', 0x25d9},
+	{'F', 'd', 0x25e2},
+	{'B', 'd', 0x25e3},
+	{'*', '2', 0x2605},
+	{'*', '1', 0x2606},
+	{'<', 'H', 0x261c},
+	{'>', 'H', 0x261e},
+	{'0', 'u', 0x263a},
+	{'0', 'U', 0x263b},
+	{'S', 'U', 0x263c},
+	{'F', 'm', 0x2640},
+	{'M', 'l', 0x2642},
+	{'c', 'S', 0x2660},
+	{'c', 'H', 0x2661},
+	{'c', 'D', 0x2662},
+	{'c', 'C', 0x2663},
+	{'M', 'd', 0x2669},
+	{'M', '8', 0x266a},
+	{'M', '2', 0x266b},
+	{'M', 'b', 0x266d},
+	{'M', 'x', 0x266e},
+	{'M', 'X', 0x266f},
+	{'O', 'K', 0x2713},
+	{'X', 'X', 0x2717},
+	{'-', 'X', 0x2720},
+	{'I', 'S', 0x3000},
+	{',', '_', 0x3001},
+	{'.', '_', 0x3002},
+	{'+', '"', 0x3003},
+	{'+', '_', 0x3004},
+	{'*', '_', 0x3005},
+	{';', '_', 0x3006},
+	{'0', '_', 0x3007},
+	{'<', '+', 0x300a},
+	{'>', '+', 0x300b},
+	{'<', '\'', 0x300c},
+	{'>', '\'', 0x300d},
+	{'<', '"', 0x300e},
+	{'>', '"', 0x300f},
+	{'(', '"', 0x3010},
+	{')', '"', 0x3011},
+	{'=', 'T', 0x3012},
+	{'=', '_', 0x3013},
+	{'(', '\'', 0x3014},
+	{')', '\'', 0x3015},
+	{'(', 'I', 0x3016},
+	{')', 'I', 0x3017},
+	{'-', '?', 0x301c},
+	{'A', '5', 0x3041},
+	{'a', '5', 0x3042},
+	{'I', '5', 0x3043},
+	{'i', '5', 0x3044},
+	{'U', '5', 0x3045},
+	{'u', '5', 0x3046},
+	{'E', '5', 0x3047},
+	{'e', '5', 0x3048},
+	{'O', '5', 0x3049},
+	{'o', '5', 0x304a},
+	{'k', 'a', 0x304b},
+	{'g', 'a', 0x304c},
+	{'k', 'i', 0x304d},
+	{'g', 'i', 0x304e},
+	{'k', 'u', 0x304f},
+	{'g', 'u', 0x3050},
+	{'k', 'e', 0x3051},
+	{'g', 'e', 0x3052},
+	{'k', 'o', 0x3053},
+	{'g', 'o', 0x3054},
+	{'s', 'a', 0x3055},
+	{'z', 'a', 0x3056},
+	{'s', 'i', 0x3057},
+	{'z', 'i', 0x3058},
+	{'s', 'u', 0x3059},
+	{'z', 'u', 0x305a},
+	{'s', 'e', 0x305b},
+	{'z', 'e', 0x305c},
+	{'s', 'o', 0x305d},
+	{'z', 'o', 0x305e},
+	{'t', 'a', 0x305f},
+	{'d', 'a', 0x3060},
+	{'t', 'i', 0x3061},
+	{'d', 'i', 0x3062},
+	{'t', 'U', 0x3063},
+	{'t', 'u', 0x3064},
+	{'d', 'u', 0x3065},
+	{'t', 'e', 0x3066},
+	{'d', 'e', 0x3067},
+	{'t', 'o', 0x3068},
+	{'d', 'o', 0x3069},
+	{'n', 'a', 0x306a},
+	{'n', 'i', 0x306b},
+	{'n', 'u', 0x306c},
+	{'n', 'e', 0x306d},
+	{'n', 'o', 0x306e},
+	{'h', 'a', 0x306f},
+	{'b', 'a', 0x3070},
+	{'p', 'a', 0x3071},
+	{'h', 'i', 0x3072},
+	{'b', 'i', 0x3073},
+	{'p', 'i', 0x3074},
+	{'h', 'u', 0x3075},
+	{'b', 'u', 0x3076},
+	{'p', 'u', 0x3077},
+	{'h', 'e', 0x3078},
+	{'b', 'e', 0x3079},
+	{'p', 'e', 0x307a},
+	{'h', 'o', 0x307b},
+	{'b', 'o', 0x307c},
+	{'p', 'o', 0x307d},
+	{'m', 'a', 0x307e},
+	{'m', 'i', 0x307f},
+	{'m', 'u', 0x3080},
+	{'m', 'e', 0x3081},
+	{'m', 'o', 0x3082},
+	{'y', 'A', 0x3083},
+	{'y', 'a', 0x3084},
+	{'y', 'U', 0x3085},
+	{'y', 'u', 0x3086},
+	{'y', 'O', 0x3087},
+	{'y', 'o', 0x3088},
+	{'r', 'a', 0x3089},
+	{'r', 'i', 0x308a},
+	{'r', 'u', 0x308b},
+	{'r', 'e', 0x308c},
+	{'r', 'o', 0x308d},
+	{'w', 'A', 0x308e},
+	{'w', 'a', 0x308f},
+	{'w', 'i', 0x3090},
+	{'w', 'e', 0x3091},
+	{'w', 'o', 0x3092},
+	{'n', '5', 0x3093},
+	{'v', 'u', 0x3094},
+	{'"', '5', 0x309b},
+	{'0', '5', 0x309c},
+	{'*', '5', 0x309d},
+	{'+', '5', 0x309e},
+	{'a', '6', 0x30a1},
+	{'A', '6', 0x30a2},
+	{'i', '6', 0x30a3},
+	{'I', '6', 0x30a4},
+	{'u', '6', 0x30a5},
+	{'U', '6', 0x30a6},
+	{'e', '6', 0x30a7},
+	{'E', '6', 0x30a8},
+	{'o', '6', 0x30a9},
+	{'O', '6', 0x30aa},
+	{'K', 'a', 0x30ab},
+	{'G', 'a', 0x30ac},
+	{'K', 'i', 0x30ad},
+	{'G', 'i', 0x30ae},
+	{'K', 'u', 0x30af},
+	{'G', 'u', 0x30b0},
+	{'K', 'e', 0x30b1},
+	{'G', 'e', 0x30b2},
+	{'K', 'o', 0x30b3},
+	{'G', 'o', 0x30b4},
+	{'S', 'a', 0x30b5},
+	{'Z', 'a', 0x30b6},
+	{'S', 'i', 0x30b7},
+	{'Z', 'i', 0x30b8},
+	{'S', 'u', 0x30b9},
+	{'Z', 'u', 0x30ba},
+	{'S', 'e', 0x30bb},
+	{'Z', 'e', 0x30bc},
+	{'S', 'o', 0x30bd},
+	{'Z', 'o', 0x30be},
+	{'T', 'a', 0x30bf},
+	{'D', 'a', 0x30c0},
+	{'T', 'i', 0x30c1},
+	{'D', 'i', 0x30c2},
+	{'T', 'U', 0x30c3},
+	{'T', 'u', 0x30c4},
+	{'D', 'u', 0x30c5},
+	{'T', 'e', 0x30c6},
+	{'D', 'e', 0x30c7},
+	{'T', 'o', 0x30c8},
+	{'D', 'o', 0x30c9},
+	{'N', 'a', 0x30ca},
+	{'N', 'i', 0x30cb},
+	{'N', 'u', 0x30cc},
+	{'N', 'e', 0x30cd},
+	{'N', 'o', 0x30ce},
+	{'H', 'a', 0x30cf},
+	{'B', 'a', 0x30d0},
+	{'P', 'a', 0x30d1},
+	{'H', 'i', 0x30d2},
+	{'B', 'i', 0x30d3},
+	{'P', 'i', 0x30d4},
+	{'H', 'u', 0x30d5},
+	{'B', 'u', 0x30d6},
+	{'P', 'u', 0x30d7},
+	{'H', 'e', 0x30d8},
+	{'B', 'e', 0x30d9},
+	{'P', 'e', 0x30da},
+	{'H', 'o', 0x30db},
+	{'B', 'o', 0x30dc},
+	{'P', 'o', 0x30dd},
+	{'M', 'a', 0x30de},
+	{'M', 'i', 0x30df},
+	{'M', 'u', 0x30e0},
+	{'M', 'e', 0x30e1},
+	{'M', 'o', 0x30e2},
+	{'Y', 'A', 0x30e3},
+	{'Y', 'a', 0x30e4},
+	{'Y', 'U', 0x30e5},
+	{'Y', 'u', 0x30e6},
+	{'Y', 'O', 0x30e7},
+	{'Y', 'o', 0x30e8},
+	{'R', 'a', 0x30e9},
+	{'R', 'i', 0x30ea},
+	{'R', 'u', 0x30eb},
+	{'R', 'e', 0x30ec},
+	{'R', 'o', 0x30ed},
+	{'W', 'A', 0x30ee},
+	{'W', 'a', 0x30ef},
+	{'W', 'i', 0x30f0},
+	{'W', 'e', 0x30f1},
+	{'W', 'o', 0x30f2},
+	{'N', '6', 0x30f3},
+	{'V', 'u', 0x30f4},
+	{'K', 'A', 0x30f5},
+	{'K', 'E', 0x30f6},
+	{'V', 'a', 0x30f7},
+	{'V', 'i', 0x30f8},
+	{'V', 'e', 0x30f9},
+	{'V', 'o', 0x30fa},
+	{'.', '6', 0x30fb},
+	{'-', '6', 0x30fc},
+	{'*', '6', 0x30fd},
+	{'+', '6', 0x30fe},
+	{'b', '4', 0x3105},
+	{'p', '4', 0x3106},
+	{'m', '4', 0x3107},
+	{'f', '4', 0x3108},
+	{'d', '4', 0x3109},
+	{'t', '4', 0x310a},
+	{'n', '4', 0x310b},
+	{'l', '4', 0x310c},
+	{'g', '4', 0x310d},
+	{'k', '4', 0x310e},
+	{'h', '4', 0x310f},
+	{'j', '4', 0x3110},
+	{'q', '4', 0x3111},
+	{'x', '4', 0x3112},
+	{'z', 'h', 0x3113},
+	{'c', 'h', 0x3114},
+	{'s', 'h', 0x3115},
+	{'r', '4', 0x3116},
+	{'z', '4', 0x3117},
+	{'c', '4', 0x3118},
+	{'s', '4', 0x3119},
+	{'a', '4', 0x311a},
+	{'o', '4', 0x311b},
+	{'e', '4', 0x311c},
+	{'a', 'i', 0x311e},
+	{'e', 'i', 0x311f},
+	{'a', 'u', 0x3120},
+	{'o', 'u', 0x3121},
+	{'a', 'n', 0x3122},
+	{'e', 'n', 0x3123},
+	{'a', 'N', 0x3124},
+	{'e', 'N', 0x3125},
+	{'e', 'r', 0x3126},
+	{'i', '4', 0x3127},
+	{'u', '4', 0x3128},
+	{'i', 'u', 0x3129},
+	{'v', '4', 0x312a},
+	{'n', 'G', 0x312b},
+	{'g', 'n', 0x312c},
+	{'1', 'c', 0x3220},
+	{'2', 'c', 0x3221},
+	{'3', 'c', 0x3222},
+	{'4', 'c', 0x3223},
+	{'5', 'c', 0x3224},
+	{'6', 'c', 0x3225},
+	{'7', 'c', 0x3226},
+	{'8', 'c', 0x3227},
+	{'9', 'c', 0x3228},
+	{' ', ' ', 0xe000},
+	{'/', 'c', 0xe001},
+	{'U', 'A', 0xe002},
+	{'U', 'B', 0xe003},
+	{'"', '3', 0xe004},
+	{'"', '1', 0xe005},
+	{'"', '!', 0xe006},
+	{'"', '\'', 0xe007},
+	{'"', '>', 0xe008},
+	{'"', '?', 0xe009},
+	{'"', '-', 0xe00a},
+	{'"', '(', 0xe00b},
+	{'"', '.', 0xe00c},
+	{'"', ':', 0xe00d},
+	{'"', '0', 0xe00e},
+	{'"', '"', 0xe00f},
+	{'"', '<', 0xe010},
+	{'"', ',', 0xe011},
+	{'"', ';', 0xe012},
+	{'"', '_', 0xe013},
+	{'"', '=', 0xe014},
+	{'"', '/', 0xe015},
+	{'"', 'i', 0xe016},
+	{'"', 'd', 0xe017},
+	{'"', 'p', 0xe018},
+	{';', ';', 0xe019},
+	{',', ',', 0xe01a},
+	{'b', '3', 0xe01b},
+	{'C', 'i', 0xe01c},
+	{'f', '(', 0xe01d},
+	{'e', 'd', 0xe01e},
+	{'a', 'm', 0xe01f},
+	{'p', 'm', 0xe020},
+	{'F', 'l', 0xe023},
+	{'G', 'F', 0xe024},
+	{'>', 'V', 0xe025},
+	{'!', '*', 0xe026},
+	{'?', '*', 0xe027},
+	{'J', '<', 0xe028},
+	{'f', 'f', 0xfb00},
+	{'f', 'i', 0xfb01},
+	{'f', 'l', 0xfb02},
+	{'f', 't', 0xfb05},
+	{'s', 't', 0xfb06},
+#      endif /* FEAT_MBYTE */
+	{NUL, NUL, NUL}
+       };
+
+#     endif /* OLD_DIGRAPHS */
+
+#    endif /* Macintosh */
+#   endif /* EBCDIC */
+#  endif    /* !HPUX_DIGRAPHS */
+# endif	/* !__MINT__ */
+#endif	/* !MSDOS && !OS2 */
+
+/*
+ * handle digraphs after typing a character
+ */
+    int
+do_digraph(c)
+    int	    c;
+{
+    static int	backspaced;	/* character before K_BS */
+    static int	lastchar;	/* last typed character */
+
+    if (c == -1)		/* init values */
+    {
+	backspaced = -1;
+    }
+    else if (p_dg)
+    {
+	if (backspaced >= 0)
+	    c = getdigraph(backspaced, c, FALSE);
+	backspaced = -1;
+	if ((c == K_BS || c == Ctrl_H) && lastchar >= 0)
+	    backspaced = lastchar;
+    }
+    lastchar = c;
+    return c;
+}
+
+/*
+ * Get a digraph.  Used after typing CTRL-K on the command line or in normal
+ * mode.
+ * Returns composed character, or NUL when ESC was used.
+ */
+    int
+get_digraph(cmdline)
+    int		cmdline;	/* TRUE when called from the cmdline */
+{
+    int		c, cc;
+
+    ++no_mapping;
+    ++allow_keys;
+    c = safe_vgetc();
+    --no_mapping;
+    --allow_keys;
+    if (c != ESC)		/* ESC cancels CTRL-K */
+    {
+	if (IS_SPECIAL(c))	/* insert special key code */
+	    return c;
+	if (cmdline)
+	{
+	    if (char2cells(c) == 1
+#if defined(FEAT_CRYPT) || defined(FEAT_EVAL)
+		    && cmdline_star == 0
+#endif
+		    )
+		putcmdline(c, TRUE);
+	}
+#ifdef FEAT_CMDL_INFO
+	else
+	    add_to_showcmd(c);
+#endif
+	++no_mapping;
+	++allow_keys;
+	cc = safe_vgetc();
+	--no_mapping;
+	--allow_keys;
+	if (cc != ESC)	    /* ESC cancels CTRL-K */
+	    return getdigraph(c, cc, TRUE);
+    }
+    return NUL;
+}
+
+/*
+ * Lookup the pair "char1", "char2" in the digraph tables.
+ * If no match, return "char2".
+ * If "meta" is TRUE and "char1" is a space, return "char2" | 0x80.
+ */
+    static int
+getexactdigraph(char1, char2, meta)
+    int		char1;
+    int		char2;
+    int		meta;
+{
+    int		i;
+    int		retval = 0;
+    digr_T	*dp;
+
+    if (IS_SPECIAL(char1) || IS_SPECIAL(char2))
+	return char2;
+
+    /*
+     * Search user digraphs first.
+     */
+    dp = (digr_T *)user_digraphs.ga_data;
+    for (i = 0; i < user_digraphs.ga_len; ++i)
+    {
+	if ((int)dp->char1 == char1 && (int)dp->char2 == char2)
+	{
+	    retval = dp->result;
+	    break;
+	}
+	++dp;
+    }
+
+    /*
+     * Search default digraphs.
+     */
+    if (retval == 0)
+    {
+	dp = digraphdefault;
+	for (i = 0; dp->char1 != 0; ++i)
+	{
+	    if ((int)dp->char1 == char1 && (int)dp->char2 == char2)
+	    {
+		retval = dp->result;
+		break;
+	    }
+	    ++dp;
+	}
+    }
+#ifdef FEAT_MBYTE
+# ifdef USE_UNICODE_DIGRAPHS
+    if (retval != 0 && !enc_utf8)
+    {
+	char_u	    buf[6], *to;
+	vimconv_T   vc;
+
+	/*
+	 * Convert the Unicode digraph to 'encoding'.
+	 */
+	i = utf_char2bytes(retval, buf);
+	retval = 0;
+	vc.vc_type = CONV_NONE;
+	if (convert_setup(&vc, (char_u *)"utf-8", p_enc) == OK)
+	{
+	    vc.vc_fail = TRUE;
+	    to = string_convert(&vc, buf, &i);
+	    if (to != NULL)
+	    {
+		retval = (*mb_ptr2char)(to);
+		vim_free(to);
+	    }
+	    (void)convert_setup(&vc, NULL, NULL);
+	}
+    }
+# endif
+
+    /* Ignore multi-byte characters when not in multi-byte mode. */
+    if (!has_mbyte && retval > 0xff)
+	retval = 0;
+#endif
+
+    if (retval == 0)		/* digraph deleted or not found */
+    {
+	if (char1 == ' ' && meta)	/* <space> <char> --> meta-char */
+	    return (char2 | 0x80);
+	return char2;
+    }
+    return retval;
+}
+
+/*
+ * Get digraph.
+ * Allow for both char1-char2 and char2-char1
+ */
+    int
+getdigraph(char1, char2, meta)
+    int	char1;
+    int	char2;
+    int	meta;
+{
+    int	    retval;
+
+    if (((retval = getexactdigraph(char1, char2, meta)) == char2)
+	    && (char1 != char2)
+	    && ((retval = getexactdigraph(char2, char1, meta)) == char1))
+	return char2;
+    return retval;
+}
+
+/*
+ * Add the digraphs in the argument to the digraph table.
+ * format: {c1}{c2} char {c1}{c2} char ...
+ */
+    void
+putdigraph(str)
+    char_u *str;
+{
+    int		char1, char2, n;
+    int		i;
+    digr_T	*dp;
+
+    while (*str != NUL)
+    {
+	str = skipwhite(str);
+	if (*str == NUL)
+	    return;
+	char1 = *str++;
+	char2 = *str++;
+	if (char2 == 0)
+	{
+	    EMSG(_(e_invarg));
+	    return;
+	}
+	if (char1 == ESC || char2 == ESC)
+	{
+	    EMSG(_("E104: Escape not allowed in digraph"));
+	    return;
+	}
+	str = skipwhite(str);
+	if (!VIM_ISDIGIT(*str))
+	{
+	    EMSG(_(e_number_exp));
+	    return;
+	}
+	n = getdigits(&str);
+
+	/* If the digraph already exists, replace the result. */
+	dp = (digr_T *)user_digraphs.ga_data;
+	for (i = 0; i < user_digraphs.ga_len; ++i)
+	{
+	    if ((int)dp->char1 == char1 && (int)dp->char2 == char2)
+	    {
+		dp->result = n;
+		break;
+	    }
+	    ++dp;
+	}
+
+	/* Add a new digraph to the table. */
+	if (i == user_digraphs.ga_len)
+	{
+	    if (ga_grow(&user_digraphs, 1) == OK)
+	    {
+		dp = (digr_T *)user_digraphs.ga_data + user_digraphs.ga_len;
+		dp->char1 = char1;
+		dp->char2 = char2;
+		dp->result = n;
+		++user_digraphs.ga_len;
+	    }
+	}
+    }
+}
+
+    void
+listdigraphs()
+{
+    int		i;
+    digr_T	*dp;
+
+    msg_putchar('\n');
+
+    dp = digraphdefault;
+    for (i = 0; dp->char1 != NUL && !got_int; ++i)
+    {
+#if defined(USE_UNICODE_DIGRAPHS) && defined(FEAT_MBYTE)
+	digr_T tmp;
+
+	/* May need to convert the result to 'encoding'. */
+	tmp.char1 = dp->char1;
+	tmp.char2 = dp->char2;
+	tmp.result = getexactdigraph(tmp.char1, tmp.char2, FALSE);
+	if (tmp.result != 0 && tmp.result != tmp.char2
+					  && (has_mbyte || tmp.result <= 255))
+	    printdigraph(&tmp);
+#else
+
+	if (getexactdigraph(dp->char1, dp->char2, FALSE) == dp->result
+# ifdef FEAT_MBYTE
+		&& (has_mbyte || dp->result <= 255)
+# endif
+		)
+	    printdigraph(dp);
+#endif
+	++dp;
+	ui_breakcheck();
+    }
+
+    dp = (digr_T *)user_digraphs.ga_data;
+    for (i = 0; i < user_digraphs.ga_len && !got_int; ++i)
+    {
+	printdigraph(dp);
+	ui_breakcheck();
+	++dp;
+    }
+    must_redraw = CLEAR;    /* clear screen, because some digraphs may be
+			       wrong, in which case we messed up ScreenLines */
+}
+
+    static void
+printdigraph(dp)
+    digr_T	*dp;
+{
+    char_u	buf[30];
+    char_u	*p;
+
+    int		list_width;
+
+    if ((dy_flags & DY_UHEX)
+#ifdef FEAT_MBYTE
+	    || has_mbyte
+#endif
+	    )
+	list_width = 13;
+    else
+	list_width = 11;
+
+    if (dp->result != 0)
+    {
+	if (msg_col > Columns - list_width)
+	    msg_putchar('\n');
+	if (msg_col)
+	    while (msg_col % list_width != 0)
+		msg_putchar(' ');
+
+	p = buf;
+	*p++ = dp->char1;
+	*p++ = dp->char2;
+	*p++ = ' ';
+#ifdef FEAT_MBYTE
+	if (has_mbyte)
+	{
+	    /* add a space to draw a composing char on */
+	    if (enc_utf8 && utf_iscomposing(dp->result))
+		*p++ = ' ';
+	    p += (*mb_char2bytes)(dp->result, p);
+	}
+	else
+#endif
+	    *p++ = dp->result;
+	if (char2cells(dp->result) == 1)
+	    *p++ = ' ';
+	sprintf((char *)p, " %3d", dp->result);
+	msg_outtrans(buf);
+    }
+}
+
+#endif /* FEAT_DIGRAPHS */
+
+#if defined(FEAT_KEYMAP) || defined(PROTO)
+
+/* structure used for b_kmap_ga.ga_data */
+typedef struct
+{
+    char_u	*from;
+    char_u	*to;
+} kmap_T;
+
+#define KMAP_MAXLEN 20	    /* maximum length of "from" or "to" */
+
+static void keymap_unload __ARGS((void));
+
+/*
+ * Set up key mapping tables for the 'keymap' option
+ */
+    char_u *
+keymap_init()
+{
+    curbuf->b_kmap_state &= ~KEYMAP_INIT;
+
+    if (*curbuf->b_p_keymap == NUL)
+    {
+	/* Stop any active keymap and clear the table. */
+	keymap_unload();
+    }
+    else
+    {
+	char_u	*buf;
+
+	/* Source the keymap file.  It will contain a ":loadkeymap" command
+	 * which will call ex_loadkeymap() below. */
+	buf = alloc((unsigned)(STRLEN(curbuf->b_p_keymap)
+# ifdef FEAT_MBYTE
+						       + STRLEN(p_enc)
+# endif
+						       + 14));
+	if (buf == NULL)
+	    return e_outofmem;
+
+# ifdef FEAT_MBYTE
+	/* try finding "keymap/'keymap'_'encoding'.vim"  in 'runtimepath' */
+	sprintf((char *)buf, "keymap/%s_%s.vim", curbuf->b_p_keymap, p_enc);
+	if (source_runtime(buf, FALSE) == FAIL)
+# endif
+	{
+	    /* try finding "keymap/'keymap'.vim" in 'runtimepath'  */
+	    sprintf((char *)buf, "keymap/%s.vim", curbuf->b_p_keymap);
+	    if (source_runtime(buf, FALSE) == FAIL)
+	    {
+		vim_free(buf);
+		return (char_u *)N_("E544: Keymap file not found");
+	    }
+	}
+	vim_free(buf);
+    }
+
+    return NULL;
+}
+
+/*
+ * ":loadkeymap" command: load the following lines as the keymap.
+ */
+    void
+ex_loadkeymap(eap)
+    exarg_T	*eap;
+{
+    char_u	*line;
+    char_u	*p;
+    char_u	*s;
+    kmap_T	*kp;
+#define KMAP_LLEN   200	    /* max length of "to" and "from" together */
+    char_u	buf[KMAP_LLEN + 11];
+    int		i;
+    char_u	*save_cpo = p_cpo;
+
+    if (!getline_equal(eap->getline, eap->cookie, getsourceline))
+    {
+	EMSG(_("E105: Using :loadkeymap not in a sourced file"));
+	return;
+    }
+
+    /*
+     * Stop any active keymap and clear the table.
+     */
+    keymap_unload();
+
+    curbuf->b_kmap_state = 0;
+    ga_init2(&curbuf->b_kmap_ga, (int)sizeof(kmap_T), 20);
+
+    /* Set 'cpoptions' to "C" to avoid line continuation. */
+    p_cpo = (char_u *)"C";
+
+    /*
+     * Get each line of the sourced file, break at the end.
+     */
+    for (;;)
+    {
+	line = eap->getline(0, eap->cookie, 0);
+	if (line == NULL)
+	    break;
+
+	p = skipwhite(line);
+	if (*p != '"' && *p != NUL && ga_grow(&curbuf->b_kmap_ga, 1) == OK)
+	{
+	    kp = (kmap_T *)curbuf->b_kmap_ga.ga_data + curbuf->b_kmap_ga.ga_len;
+	    s = skiptowhite(p);
+	    kp->from = vim_strnsave(p, (int)(s - p));
+	    p = skipwhite(s);
+	    s = skiptowhite(p);
+	    kp->to = vim_strnsave(p, (int)(s - p));
+
+	    if (kp->from == NULL || kp->to == NULL
+		    || STRLEN(kp->from) + STRLEN(kp->to) >= KMAP_LLEN
+		    || *kp->from == NUL || *kp->to == NUL)
+	    {
+		if (kp->to != NULL && *kp->to == NUL)
+		    EMSG(_("E791: Empty keymap entry"));
+		vim_free(kp->from);
+		vim_free(kp->to);
+	    }
+	    else
+		++curbuf->b_kmap_ga.ga_len;
+	}
+	vim_free(line);
+    }
+
+    /*
+     * setup ":lnoremap" to map the keys
+     */
+    for (i = 0; i < curbuf->b_kmap_ga.ga_len; ++i)
+    {
+	vim_snprintf((char *)buf, sizeof(buf), "<buffer> %s %s",
+				((kmap_T *)curbuf->b_kmap_ga.ga_data)[i].from,
+				 ((kmap_T *)curbuf->b_kmap_ga.ga_data)[i].to);
+	(void)do_map(2, buf, LANGMAP, FALSE);
+    }
+
+    p_cpo = save_cpo;
+
+    curbuf->b_kmap_state |= KEYMAP_LOADED;
+#ifdef FEAT_WINDOWS
+    status_redraw_curbuf();
+#endif
+}
+
+/*
+ * Stop using 'keymap'.
+ */
+    static void
+keymap_unload()
+{
+    char_u	buf[KMAP_MAXLEN + 10];
+    int		i;
+    char_u	*save_cpo = p_cpo;
+
+    if (!(curbuf->b_kmap_state & KEYMAP_LOADED))
+	return;
+
+    /* Set 'cpoptions' to "C" to avoid line continuation. */
+    p_cpo = (char_u *)"C";
+
+    /* clear the ":lmap"s */
+    for (i = 0; i < curbuf->b_kmap_ga.ga_len; ++i)
+    {
+	vim_snprintf((char *)buf, sizeof(buf), "<buffer> %s",
+			       ((kmap_T *)curbuf->b_kmap_ga.ga_data)[i].from);
+	(void)do_map(1, buf, LANGMAP, FALSE);
+    }
+
+    p_cpo = save_cpo;
+
+    ga_clear(&curbuf->b_kmap_ga);
+    curbuf->b_kmap_state &= ~KEYMAP_LOADED;
+    do_cmdline_cmd((char_u *)"unlet! b:keymap_name");
+#ifdef FEAT_WINDOWS
+    status_redraw_curbuf();
+#endif
+}
+
+#endif /* FEAT_KEYMAP */
+
--- /dev/null
+++ b/edit.c
@@ -1,0 +1,9506 @@
+/* vi:set ts=8 sts=4 sw=4:
+ *
+ * VIM - Vi IMproved	by Bram Moolenaar
+ *
+ * Do ":help uganda"  in Vim to read copying and usage conditions.
+ * Do ":help credits" in Vim to see a list of people who contributed.
+ * See README.txt for an overview of the Vim source code.
+ */
+
+/*
+ * edit.c: functions for Insert mode
+ */
+
+#include "vim.h"
+
+#ifdef FEAT_INS_EXPAND
+/*
+ * definitions used for CTRL-X submode
+ */
+#define CTRL_X_WANT_IDENT	0x100
+
+#define CTRL_X_NOT_DEFINED_YET	1
+#define CTRL_X_SCROLL		2
+#define CTRL_X_WHOLE_LINE	3
+#define CTRL_X_FILES		4
+#define CTRL_X_TAGS		(5 + CTRL_X_WANT_IDENT)
+#define CTRL_X_PATH_PATTERNS	(6 + CTRL_X_WANT_IDENT)
+#define CTRL_X_PATH_DEFINES	(7 + CTRL_X_WANT_IDENT)
+#define CTRL_X_FINISHED		8
+#define CTRL_X_DICTIONARY	(9 + CTRL_X_WANT_IDENT)
+#define CTRL_X_THESAURUS	(10 + CTRL_X_WANT_IDENT)
+#define CTRL_X_CMDLINE		11
+#define CTRL_X_FUNCTION		12
+#define CTRL_X_OMNI		13
+#define CTRL_X_SPELL		14
+#define CTRL_X_LOCAL_MSG	15	/* only used in "ctrl_x_msgs" */
+
+#define CTRL_X_MSG(i) ctrl_x_msgs[(i) & ~CTRL_X_WANT_IDENT]
+
+static char *ctrl_x_msgs[] =
+{
+    N_(" Keyword completion (^N^P)"), /* ctrl_x_mode == 0, ^P/^N compl. */
+    N_(" ^X mode (^]^D^E^F^I^K^L^N^O^Ps^U^V^Y)"),
+    NULL,
+    N_(" Whole line completion (^L^N^P)"),
+    N_(" File name completion (^F^N^P)"),
+    N_(" Tag completion (^]^N^P)"),
+    N_(" Path pattern completion (^N^P)"),
+    N_(" Definition completion (^D^N^P)"),
+    NULL,
+    N_(" Dictionary completion (^K^N^P)"),
+    N_(" Thesaurus completion (^T^N^P)"),
+    N_(" Command-line completion (^V^N^P)"),
+    N_(" User defined completion (^U^N^P)"),
+    N_(" Omni completion (^O^N^P)"),
+    N_(" Spelling suggestion (s^N^P)"),
+    N_(" Keyword Local completion (^N^P)"),
+};
+
+static char_u e_hitend[] = N_("Hit end of paragraph");
+
+/*
+ * Structure used to store one match for insert completion.
+ */
+typedef struct compl_S compl_T;
+struct compl_S
+{
+    compl_T	*cp_next;
+    compl_T	*cp_prev;
+    char_u	*cp_str;	/* matched text */
+    char	cp_icase;	/* TRUE or FALSE: ignore case */
+    char_u	*(cp_text[CPT_COUNT]);	/* text for the menu */
+    char_u	*cp_fname;	/* file containing the match, allocated when
+				 * cp_flags has FREE_FNAME */
+    int		cp_flags;	/* ORIGINAL_TEXT, CONT_S_IPOS or FREE_FNAME */
+    int		cp_number;	/* sequence number */
+};
+
+#define ORIGINAL_TEXT	(1)   /* the original text when the expansion begun */
+#define FREE_FNAME	(2)
+
+/*
+ * All the current matches are stored in a list.
+ * "compl_first_match" points to the start of the list.
+ * "compl_curr_match" points to the currently selected entry.
+ * "compl_shown_match" is different from compl_curr_match during
+ * ins_compl_get_exp().
+ */
+static compl_T    *compl_first_match = NULL;
+static compl_T    *compl_curr_match = NULL;
+static compl_T    *compl_shown_match = NULL;
+
+/* After using a cursor key <Enter> selects a match in the popup menu,
+ * otherwise it inserts a line break. */
+static int	  compl_enter_selects = FALSE;
+
+/* When "compl_leader" is not NULL only matches that start with this string
+ * are used. */
+static char_u	  *compl_leader = NULL;
+
+static int	  compl_get_longest = FALSE;	/* put longest common string
+						   in compl_leader */
+
+static int	  compl_used_match;	/* Selected one of the matches.  When
+					   FALSE the match was edited or using
+					   the longest common string. */
+
+static int	  compl_was_interrupted = FALSE;  /* didn't finish finding
+						     completions. */
+
+static int	  compl_restarting = FALSE;	/* don't insert match */
+
+/* When the first completion is done "compl_started" is set.  When it's
+ * FALSE the word to be completed must be located. */
+static int	  compl_started = FALSE;
+
+static int	  compl_matches = 0;
+static char_u	  *compl_pattern = NULL;
+static int	  compl_direction = FORWARD;
+static int	  compl_shows_dir = FORWARD;
+static int	  compl_pending = 0;	    /* > 1 for postponed CTRL-N */
+static pos_T	  compl_startpos;
+static colnr_T	  compl_col = 0;	    /* column where the text starts
+					     * that is being completed */
+static char_u	  *compl_orig_text = NULL;  /* text as it was before
+					     * completion started */
+static int	  compl_cont_mode = 0;
+static expand_T	  compl_xp;
+
+static void ins_ctrl_x __ARGS((void));
+static int  has_compl_option __ARGS((int dict_opt));
+static int ins_compl_add __ARGS((char_u *str, int len, int icase, char_u *fname, char_u **cptext, int cdir, int flags, int adup));
+static int  ins_compl_equal __ARGS((compl_T *match, char_u *str, int len));
+static void ins_compl_longest_match __ARGS((compl_T *match));
+static void ins_compl_add_matches __ARGS((int num_matches, char_u **matches, int icase));
+static int  ins_compl_make_cyclic __ARGS((void));
+static void ins_compl_upd_pum __ARGS((void));
+static void ins_compl_del_pum __ARGS((void));
+static int  pum_wanted __ARGS((void));
+static int  pum_enough_matches __ARGS((void));
+static void ins_compl_dictionaries __ARGS((char_u *dict, char_u *pat, int flags, int thesaurus));
+static void ins_compl_files __ARGS((int count, char_u **files, int thesaurus, int flags, regmatch_T *regmatch, char_u *buf, int *dir));
+static char_u *find_line_end __ARGS((char_u *ptr));
+static void ins_compl_free __ARGS((void));
+static void ins_compl_clear __ARGS((void));
+static int  ins_compl_bs __ARGS((void));
+static void ins_compl_new_leader __ARGS((void));
+static void ins_compl_addleader __ARGS((int c));
+static void ins_compl_restart __ARGS((void));
+static void ins_compl_set_original_text __ARGS((char_u *str));
+static void ins_compl_addfrommatch __ARGS((void));
+static int  ins_compl_prep __ARGS((int c));
+static buf_T *ins_compl_next_buf __ARGS((buf_T *buf, int flag));
+#if defined(FEAT_COMPL_FUNC) || defined(FEAT_EVAL)
+static void ins_compl_add_list __ARGS((list_T *list));
+#endif
+static int  ins_compl_get_exp __ARGS((pos_T *ini));
+static void ins_compl_delete __ARGS((void));
+static void ins_compl_insert __ARGS((void));
+static int  ins_compl_next __ARGS((int allow_get_expansion, int count, int insert_match));
+static int  ins_compl_key2dir __ARGS((int c));
+static int  ins_compl_pum_key __ARGS((int c));
+static int  ins_compl_key2count __ARGS((int c));
+static int  ins_compl_use_match __ARGS((int c));
+static int  ins_complete __ARGS((int c));
+static int  quote_meta __ARGS((char_u *dest, char_u *str, int len));
+#endif /* FEAT_INS_EXPAND */
+
+#define BACKSPACE_CHAR		    1
+#define BACKSPACE_WORD		    2
+#define BACKSPACE_WORD_NOT_SPACE    3
+#define BACKSPACE_LINE		    4
+
+static void ins_redraw __ARGS((int ready));
+static void ins_ctrl_v __ARGS((void));
+static void undisplay_dollar __ARGS((void));
+static void insert_special __ARGS((int, int, int));
+static void internal_format __ARGS((int textwidth, int second_indent, int flags, int format_only));
+static void check_auto_format __ARGS((int));
+static void redo_literal __ARGS((int c));
+static void start_arrow __ARGS((pos_T *end_insert_pos));
+#ifdef FEAT_SPELL
+static void check_spell_redraw __ARGS((void));
+static void spell_back_to_badword __ARGS((void));
+static int  spell_bad_len = 0;	/* length of located bad word */
+#endif
+static void stop_insert __ARGS((pos_T *end_insert_pos, int esc));
+static int  echeck_abbr __ARGS((int));
+#if 0
+static void replace_push_off __ARGS((int c));
+#endif
+static int  replace_pop __ARGS((void));
+static void replace_join __ARGS((int off));
+static void replace_pop_ins __ARGS((void));
+#ifdef FEAT_MBYTE
+static void mb_replace_pop_ins __ARGS((int cc));
+#endif
+static void replace_flush __ARGS((void));
+static void replace_do_bs __ARGS((void));
+#ifdef FEAT_CINDENT
+static int cindent_on __ARGS((void));
+#endif
+static void ins_reg __ARGS((void));
+static void ins_ctrl_g __ARGS((void));
+static void ins_ctrl_hat __ARGS((void));
+static int  ins_esc __ARGS((long *count, int cmdchar, int nomove));
+#ifdef FEAT_RIGHTLEFT
+static void ins_ctrl_ __ARGS((void));
+#endif
+#ifdef FEAT_VISUAL
+static int ins_start_select __ARGS((int c));
+#endif
+static void ins_insert __ARGS((int replaceState));
+static void ins_ctrl_o __ARGS((void));
+static void ins_shift __ARGS((int c, int lastc));
+static void ins_del __ARGS((void));
+static int  ins_bs __ARGS((int c, int mode, int *inserted_space_p));
+#ifdef FEAT_MOUSE
+static void ins_mouse __ARGS((int c));
+static void ins_mousescroll __ARGS((int up));
+#endif
+#if defined(FEAT_GUI_TABLINE) || defined(PROTO)
+static void ins_tabline __ARGS((int c));
+#endif
+static void ins_left __ARGS((void));
+static void ins_home __ARGS((int c));
+static void ins_end __ARGS((int c));
+static void ins_s_left __ARGS((void));
+static void ins_right __ARGS((void));
+static void ins_s_right __ARGS((void));
+static void ins_up __ARGS((int startcol));
+static void ins_pageup __ARGS((void));
+static void ins_down __ARGS((int startcol));
+static void ins_pagedown __ARGS((void));
+#ifdef FEAT_DND
+static void ins_drop __ARGS((void));
+#endif
+static int  ins_tab __ARGS((void));
+static int  ins_eol __ARGS((int c));
+#ifdef FEAT_DIGRAPHS
+static int  ins_digraph __ARGS((void));
+#endif
+static int  ins_copychar __ARGS((linenr_T lnum));
+static int  ins_ctrl_ey __ARGS((int tc));
+#ifdef FEAT_SMARTINDENT
+static void ins_try_si __ARGS((int c));
+#endif
+static colnr_T get_nolist_virtcol __ARGS((void));
+
+static colnr_T	Insstart_textlen;	/* length of line when insert started */
+static colnr_T	Insstart_blank_vcol;	/* vcol for first inserted blank */
+
+static char_u	*last_insert = NULL;	/* the text of the previous insert,
+					   K_SPECIAL and CSI are escaped */
+static int	last_insert_skip; /* nr of chars in front of previous insert */
+static int	new_insert_skip;  /* nr of chars in front of current insert */
+static int	did_restart_edit;	/* "restart_edit" when calling edit() */
+
+#ifdef FEAT_CINDENT
+static int	can_cindent;		/* may do cindenting on this line */
+#endif
+
+static int	old_indent = 0;		/* for ^^D command in insert mode */
+
+#ifdef FEAT_RIGHTLEFT
+static int	revins_on;		/* reverse insert mode on */
+static int	revins_chars;		/* how much to skip after edit */
+static int	revins_legal;		/* was the last char 'legal'? */
+static int	revins_scol;		/* start column of revins session */
+#endif
+
+static int	ins_need_undo;		/* call u_save() before inserting a
+					   char.  Set when edit() is called.
+					   after that arrow_used is used. */
+
+static int	did_add_space = FALSE;	/* auto_format() added an extra space
+					   under the cursor */
+
+/*
+ * edit(): Start inserting text.
+ *
+ * "cmdchar" can be:
+ * 'i'	normal insert command
+ * 'a'	normal append command
+ * 'R'	replace command
+ * 'r'	"r<CR>" command: insert one <CR>.  Note: count can be > 1, for redo,
+ *	but still only one <CR> is inserted.  The <Esc> is not used for redo.
+ * 'g'	"gI" command.
+ * 'V'	"gR" command for Virtual Replace mode.
+ * 'v'	"gr" command for single character Virtual Replace mode.
+ *
+ * This function is not called recursively.  For CTRL-O commands, it returns
+ * and lets the caller handle the Normal-mode command.
+ *
+ * Return TRUE if a CTRL-O command caused the return (insert mode pending).
+ */
+    int
+edit(cmdchar, startln, count)
+    int		cmdchar;
+    int		startln;	/* if set, insert at start of line */
+    long	count;
+{
+    int		c = 0;
+    char_u	*ptr;
+    int		lastc;
+    colnr_T	mincol;
+    static linenr_T o_lnum = 0;
+    int		i;
+    int		did_backspace = TRUE;	    /* previous char was backspace */
+#ifdef FEAT_CINDENT
+    int		line_is_white = FALSE;	    /* line is empty before insert */
+#endif
+    linenr_T	old_topline = 0;	    /* topline before insertion */
+#ifdef FEAT_DIFF
+    int		old_topfill = -1;
+#endif
+    int		inserted_space = FALSE;     /* just inserted a space */
+    int		replaceState = REPLACE;
+    int		nomove = FALSE;		    /* don't move cursor on return */
+
+    /* Remember whether editing was restarted after CTRL-O. */
+    did_restart_edit = restart_edit;
+
+    /* sleep before redrawing, needed for "CTRL-O :" that results in an
+     * error message */
+    check_for_delay(TRUE);
+
+#ifdef HAVE_SANDBOX
+    /* Don't allow inserting in the sandbox. */
+    if (sandbox != 0)
+    {
+	EMSG(_(e_sandbox));
+	return FALSE;
+    }
+#endif
+    /* Don't allow changes in the buffer while editing the cmdline.  The
+     * caller of getcmdline() may get confused. */
+    if (textlock != 0)
+    {
+	EMSG(_(e_secure));
+	return FALSE;
+    }
+
+#ifdef FEAT_INS_EXPAND
+    /* Don't allow recursive insert mode when busy with completion. */
+    if (compl_started || pum_visible())
+    {
+	EMSG(_(e_secure));
+	return FALSE;
+    }
+    ins_compl_clear();	    /* clear stuff for CTRL-X mode */
+#endif
+
+#ifdef FEAT_AUTOCMD
+    /*
+     * Trigger InsertEnter autocommands.  Do not do this for "r<CR>" or "grx".
+     */
+    if (cmdchar != 'r' && cmdchar != 'v')
+    {
+# ifdef FEAT_EVAL
+	if (cmdchar == 'R')
+	    ptr = (char_u *)"r";
+	else if (cmdchar == 'V')
+	    ptr = (char_u *)"v";
+	else
+	    ptr = (char_u *)"i";
+	set_vim_var_string(VV_INSERTMODE, ptr, 1);
+# endif
+	apply_autocmds(EVENT_INSERTENTER, NULL, NULL, FALSE, curbuf);
+    }
+#endif
+
+#ifdef FEAT_MOUSE
+    /*
+     * When doing a paste with the middle mouse button, Insstart is set to
+     * where the paste started.
+     */
+    if (where_paste_started.lnum != 0)
+	Insstart = where_paste_started;
+    else
+#endif
+    {
+	Insstart = curwin->w_cursor;
+	if (startln)
+	    Insstart.col = 0;
+    }
+    Insstart_textlen = linetabsize(ml_get_curline());
+    Insstart_blank_vcol = MAXCOL;
+    if (!did_ai)
+	ai_col = 0;
+
+    if (cmdchar != NUL && restart_edit == 0)
+    {
+	ResetRedobuff();
+	AppendNumberToRedobuff(count);
+#ifdef FEAT_VREPLACE
+	if (cmdchar == 'V' || cmdchar == 'v')
+	{
+	    /* "gR" or "gr" command */
+	    AppendCharToRedobuff('g');
+	    AppendCharToRedobuff((cmdchar == 'v') ? 'r' : 'R');
+	}
+	else
+#endif
+	{
+	    AppendCharToRedobuff(cmdchar);
+	    if (cmdchar == 'g')		    /* "gI" command */
+		AppendCharToRedobuff('I');
+	    else if (cmdchar == 'r')	    /* "r<CR>" command */
+		count = 1;		    /* insert only one <CR> */
+	}
+    }
+
+    if (cmdchar == 'R')
+    {
+#ifdef FEAT_FKMAP
+	if (p_fkmap && p_ri)
+	{
+	    beep_flush();
+	    EMSG(farsi_text_3);	    /* encoded in Farsi */
+	    State = INSERT;
+	}
+	else
+#endif
+	State = REPLACE;
+    }
+#ifdef FEAT_VREPLACE
+    else if (cmdchar == 'V' || cmdchar == 'v')
+    {
+	State = VREPLACE;
+	replaceState = VREPLACE;
+	orig_line_count = curbuf->b_ml.ml_line_count;
+	vr_lines_changed = 1;
+    }
+#endif
+    else
+	State = INSERT;
+
+    stop_insert_mode = FALSE;
+
+    /*
+     * Need to recompute the cursor position, it might move when the cursor is
+     * on a TAB or special character.
+     */
+    curs_columns(TRUE);
+
+    /*
+     * Enable langmap or IME, indicated by 'iminsert'.
+     * Note that IME may enabled/disabled without us noticing here, thus the
+     * 'iminsert' value may not reflect what is actually used.  It is updated
+     * when hitting <Esc>.
+     */
+    if (curbuf->b_p_iminsert == B_IMODE_LMAP)
+	State |= LANGMAP;
+#ifdef USE_IM_CONTROL
+    im_set_active(curbuf->b_p_iminsert == B_IMODE_IM);
+#endif
+
+#ifdef FEAT_MOUSE
+    setmouse();
+#endif
+#ifdef FEAT_CMDL_INFO
+    clear_showcmd();
+#endif
+#ifdef FEAT_RIGHTLEFT
+    /* there is no reverse replace mode */
+    revins_on = (State == INSERT && p_ri);
+    if (revins_on)
+	undisplay_dollar();
+    revins_chars = 0;
+    revins_legal = 0;
+    revins_scol = -1;
+#endif
+
+    /*
+     * Handle restarting Insert mode.
+     * Don't do this for "CTRL-O ." (repeat an insert): we get here with
+     * restart_edit non-zero, and something in the stuff buffer.
+     */
+    if (restart_edit != 0 && stuff_empty())
+    {
+#ifdef FEAT_MOUSE
+	/*
+	 * After a paste we consider text typed to be part of the insert for
+	 * the pasted text. You can backspace over the pasted text too.
+	 */
+	if (where_paste_started.lnum)
+	    arrow_used = FALSE;
+	else
+#endif
+	    arrow_used = TRUE;
+	restart_edit = 0;
+
+	/*
+	 * If the cursor was after the end-of-line before the CTRL-O and it is
+	 * now at the end-of-line, put it after the end-of-line (this is not
+	 * correct in very rare cases).
+	 * Also do this if curswant is greater than the current virtual
+	 * column.  Eg after "^O$" or "^O80|".
+	 */
+	validate_virtcol();
+	update_curswant();
+	if (((ins_at_eol && curwin->w_cursor.lnum == o_lnum)
+		    || curwin->w_curswant > curwin->w_virtcol)
+		&& *(ptr = ml_get_curline() + curwin->w_cursor.col) != NUL)
+	{
+	    if (ptr[1] == NUL)
+		++curwin->w_cursor.col;
+#ifdef FEAT_MBYTE
+	    else if (has_mbyte)
+	    {
+		i = (*mb_ptr2len)(ptr);
+		if (ptr[i] == NUL)
+		    curwin->w_cursor.col += i;
+	    }
+#endif
+	}
+	ins_at_eol = FALSE;
+    }
+    else
+	arrow_used = FALSE;
+
+    /* we are in insert mode now, don't need to start it anymore */
+    need_start_insertmode = FALSE;
+
+    /* Need to save the line for undo before inserting the first char. */
+    ins_need_undo = TRUE;
+
+#ifdef FEAT_MOUSE
+    where_paste_started.lnum = 0;
+#endif
+#ifdef FEAT_CINDENT
+    can_cindent = TRUE;
+#endif
+#ifdef FEAT_FOLDING
+    /* The cursor line is not in a closed fold, unless 'insertmode' is set or
+     * restarting. */
+    if (!p_im && did_restart_edit == 0)
+	foldOpenCursor();
+#endif
+
+    /*
+     * If 'showmode' is set, show the current (insert/replace/..) mode.
+     * A warning message for changing a readonly file is given here, before
+     * actually changing anything.  It's put after the mode, if any.
+     */
+    i = 0;
+    if (p_smd && msg_silent == 0)
+	i = showmode();
+
+    if (!p_im && did_restart_edit == 0)
+	change_warning(i + 1);
+
+#ifdef CURSOR_SHAPE
+    ui_cursor_shape();		/* may show different cursor shape */
+#endif
+#ifdef FEAT_DIGRAPHS
+    do_digraph(-1);		/* clear digraphs */
+#endif
+
+    /*
+     * Get the current length of the redo buffer, those characters have to be
+     * skipped if we want to get to the inserted characters.
+     */
+    ptr = get_inserted();
+    if (ptr == NULL)
+	new_insert_skip = 0;
+    else
+    {
+	new_insert_skip = (int)STRLEN(ptr);
+	vim_free(ptr);
+    }
+
+    old_indent = 0;
+
+    /*
+     * Main loop in Insert mode: repeat until Insert mode is left.
+     */
+    for (;;)
+    {
+#ifdef FEAT_RIGHTLEFT
+	if (!revins_legal)
+	    revins_scol = -1;	    /* reset on illegal motions */
+	else
+	    revins_legal = 0;
+#endif
+	if (arrow_used)	    /* don't repeat insert when arrow key used */
+	    count = 0;
+
+	if (stop_insert_mode)
+	{
+	    /* ":stopinsert" used or 'insertmode' reset */
+	    count = 0;
+	    goto doESCkey;
+	}
+
+	/* set curwin->w_curswant for next K_DOWN or K_UP */
+	if (!arrow_used)
+	    curwin->w_set_curswant = TRUE;
+
+	/* If there is no typeahead may check for timestamps (e.g., for when a
+	 * menu invoked a shell command). */
+	if (stuff_empty())
+	{
+	    did_check_timestamps = FALSE;
+	    if (need_check_timestamps)
+		check_timestamps(FALSE);
+	}
+
+	/*
+	 * When emsg() was called msg_scroll will have been set.
+	 */
+	msg_scroll = FALSE;
+
+#ifdef FEAT_GUI
+	/* When 'mousefocus' is set a mouse movement may have taken us to
+	 * another window.  "need_mouse_correct" may then be set because of an
+	 * autocommand. */
+	if (need_mouse_correct)
+	    gui_mouse_correct();
+#endif
+
+#ifdef FEAT_FOLDING
+	/* Open fold at the cursor line, according to 'foldopen'. */
+	if (fdo_flags & FDO_INSERT)
+	    foldOpenCursor();
+	/* Close folds where the cursor isn't, according to 'foldclose' */
+	if (!char_avail())
+	    foldCheckClose();
+#endif
+
+	/*
+	 * If we inserted a character at the last position of the last line in
+	 * the window, scroll the window one line up. This avoids an extra
+	 * redraw.
+	 * This is detected when the cursor column is smaller after inserting
+	 * something.
+	 * Don't do this when the topline changed already, it has
+	 * already been adjusted (by insertchar() calling open_line())).
+	 */
+	if (curbuf->b_mod_set
+		&& curwin->w_p_wrap
+		&& !did_backspace
+		&& curwin->w_topline == old_topline
+#ifdef FEAT_DIFF
+		&& curwin->w_topfill == old_topfill
+#endif
+		)
+	{
+	    mincol = curwin->w_wcol;
+	    validate_cursor_col();
+
+	    if ((int)curwin->w_wcol < (int)mincol - curbuf->b_p_ts
+		    && curwin->w_wrow == W_WINROW(curwin)
+						 + curwin->w_height - 1 - p_so
+		    && (curwin->w_cursor.lnum != curwin->w_topline
+#ifdef FEAT_DIFF
+			|| curwin->w_topfill > 0
+#endif
+		    ))
+	    {
+#ifdef FEAT_DIFF
+		if (curwin->w_topfill > 0)
+		    --curwin->w_topfill;
+		else
+#endif
+#ifdef FEAT_FOLDING
+		if (hasFolding(curwin->w_topline, NULL, &old_topline))
+		    set_topline(curwin, old_topline + 1);
+		else
+#endif
+		    set_topline(curwin, curwin->w_topline + 1);
+	    }
+	}
+
+	/* May need to adjust w_topline to show the cursor. */
+	update_topline();
+
+	did_backspace = FALSE;
+
+	validate_cursor();		/* may set must_redraw */
+
+	/*
+	 * Redraw the display when no characters are waiting.
+	 * Also shows mode, ruler and positions cursor.
+	 */
+	ins_redraw(TRUE);
+
+#ifdef FEAT_SCROLLBIND
+	if (curwin->w_p_scb)
+	    do_check_scrollbind(TRUE);
+#endif
+
+	update_curswant();
+	old_topline = curwin->w_topline;
+#ifdef FEAT_DIFF
+	old_topfill = curwin->w_topfill;
+#endif
+
+#ifdef USE_ON_FLY_SCROLL
+	dont_scroll = FALSE;		/* allow scrolling here */
+#endif
+
+	/*
+	 * Get a character for Insert mode.
+	 */
+	lastc = c;			/* remember previous char for CTRL-D */
+	c = safe_vgetc();
+
+#ifdef FEAT_AUTOCMD
+	/* Don't want K_CURSORHOLD for the second key, e.g., after CTRL-V. */
+	did_cursorhold = TRUE;
+#endif
+
+#ifdef FEAT_RIGHTLEFT
+	if (p_hkmap && KeyTyped)
+	    c = hkmap(c);		/* Hebrew mode mapping */
+#endif
+#ifdef FEAT_FKMAP
+	if (p_fkmap && KeyTyped)
+	    c = fkmap(c);		/* Farsi mode mapping */
+#endif
+
+#ifdef FEAT_INS_EXPAND
+	/*
+	 * Special handling of keys while the popup menu is visible or wanted
+	 * and the cursor is still in the completed word.  Only when there is
+	 * a match, skip this when no matches were found.
+	 */
+	if (compl_started
+		&& pum_wanted()
+		&& curwin->w_cursor.col >= compl_col
+		&& (compl_shown_match == NULL
+		    || compl_shown_match != compl_shown_match->cp_next))
+	{
+	    /* BS: Delete one character from "compl_leader". */
+	    if ((c == K_BS || c == Ctrl_H)
+			&& curwin->w_cursor.col > compl_col
+			&& (c = ins_compl_bs()) == NUL)
+		continue;
+
+	    /* When no match was selected or it was edited. */
+	    if (!compl_used_match)
+	    {
+		/* CTRL-L: Add one character from the current match to
+		 * "compl_leader".  Except when at the original match and
+		 * there is nothing to add, CTRL-L works like CTRL-P then. */
+		if (c == Ctrl_L
+			&& (ctrl_x_mode != CTRL_X_WHOLE_LINE
+			    || STRLEN(compl_shown_match->cp_str)
+					  > curwin->w_cursor.col - compl_col))
+		{
+		    ins_compl_addfrommatch();
+		    continue;
+		}
+
+		/* A printable, non-white character: Add to "compl_leader". */
+		if (vim_isprintc(c) && !vim_iswhite(c))
+		{
+		    ins_compl_addleader(c);
+		    continue;
+		}
+
+		/* Pressing CTRL-Y selects the current match.  When
+		 * compl_enter_selects is set the Enter key does the same. */
+		if (c == Ctrl_Y || (compl_enter_selects
+				   && (c == CAR || c == K_KENTER || c == NL)))
+		{
+		    ins_compl_delete();
+		    ins_compl_insert();
+		}
+	    }
+	}
+
+	/* Prepare for or stop CTRL-X mode.  This doesn't do completion, but
+	 * it does fix up the text when finishing completion. */
+	compl_get_longest = FALSE;
+	if (c != K_IGNORE && ins_compl_prep(c))
+	    continue;
+#endif
+
+	/* CTRL-\ CTRL-N goes to Normal mode,
+	 * CTRL-\ CTRL-G goes to mode selected with 'insertmode',
+	 * CTRL-\ CTRL-O is like CTRL-O but without moving the cursor.  */
+	if (c == Ctrl_BSL)
+	{
+	    /* may need to redraw when no more chars available now */
+	    ins_redraw(FALSE);
+	    ++no_mapping;
+	    ++allow_keys;
+	    c = safe_vgetc();
+	    --no_mapping;
+	    --allow_keys;
+	    if (c != Ctrl_N && c != Ctrl_G && c != Ctrl_O)
+	    {
+		/* it's something else */
+		vungetc(c);
+		c = Ctrl_BSL;
+	    }
+	    else if (c == Ctrl_G && p_im)
+		continue;
+	    else
+	    {
+		if (c == Ctrl_O)
+		{
+		    ins_ctrl_o();
+		    ins_at_eol = FALSE;	/* cursor keeps its column */
+		    nomove = TRUE;
+		}
+		count = 0;
+		goto doESCkey;
+	    }
+	}
+
+#ifdef FEAT_DIGRAPHS
+	c = do_digraph(c);
+#endif
+
+#ifdef FEAT_INS_EXPAND
+	if ((c == Ctrl_V || c == Ctrl_Q) && ctrl_x_mode == CTRL_X_CMDLINE)
+	    goto docomplete;
+#endif
+	if (c == Ctrl_V || c == Ctrl_Q)
+	{
+	    ins_ctrl_v();
+	    c = Ctrl_V;	/* pretend CTRL-V is last typed character */
+	    continue;
+	}
+
+#ifdef FEAT_CINDENT
+	if (cindent_on()
+# ifdef FEAT_INS_EXPAND
+		&& ctrl_x_mode == 0
+# endif
+	   )
+	{
+	    /* A key name preceded by a bang means this key is not to be
+	     * inserted.  Skip ahead to the re-indenting below.
+	     * A key name preceded by a star means that indenting has to be
+	     * done before inserting the key. */
+	    line_is_white = inindent(0);
+	    if (in_cinkeys(c, '!', line_is_white))
+		goto force_cindent;
+	    if (can_cindent && in_cinkeys(c, '*', line_is_white)
+							&& stop_arrow() == OK)
+		do_c_expr_indent();
+	}
+#endif
+
+#ifdef FEAT_RIGHTLEFT
+	if (curwin->w_p_rl)
+	    switch (c)
+	    {
+		case K_LEFT:	c = K_RIGHT; break;
+		case K_S_LEFT:	c = K_S_RIGHT; break;
+		case K_C_LEFT:	c = K_C_RIGHT; break;
+		case K_RIGHT:	c = K_LEFT; break;
+		case K_S_RIGHT: c = K_S_LEFT; break;
+		case K_C_RIGHT: c = K_C_LEFT; break;
+	    }
+#endif
+
+#ifdef FEAT_VISUAL
+	/*
+	 * If 'keymodel' contains "startsel", may start selection.  If it
+	 * does, a CTRL-O and c will be stuffed, we need to get these
+	 * characters.
+	 */
+	if (ins_start_select(c))
+	    continue;
+#endif
+
+	/*
+	 * The big switch to handle a character in insert mode.
+	 */
+	switch (c)
+	{
+	case ESC:	/* End input mode */
+	    if (echeck_abbr(ESC + ABBR_OFF))
+		break;
+	    /*FALLTHROUGH*/
+
+	case Ctrl_C:	/* End input mode */
+#ifdef FEAT_CMDWIN
+	    if (c == Ctrl_C && cmdwin_type != 0)
+	    {
+		/* Close the cmdline window. */
+		cmdwin_result = K_IGNORE;
+		got_int = FALSE; /* don't stop executing autocommands et al. */
+		nomove = TRUE;
+		goto doESCkey;
+	    }
+#endif
+
+#ifdef UNIX
+do_intr:
+#endif
+	    /* when 'insertmode' set, and not halfway a mapping, don't leave
+	     * Insert mode */
+	    if (goto_im())
+	    {
+		if (got_int)
+		{
+		    (void)vgetc();		/* flush all buffers */
+		    got_int = FALSE;
+		}
+		else
+		    vim_beep();
+		break;
+	    }
+doESCkey:
+	    /*
+	     * This is the ONLY return from edit()!
+	     */
+	    /* Always update o_lnum, so that a "CTRL-O ." that adds a line
+	     * still puts the cursor back after the inserted text. */
+	    if (ins_at_eol && gchar_cursor() == NUL)
+		o_lnum = curwin->w_cursor.lnum;
+
+	    if (ins_esc(&count, cmdchar, nomove))
+	    {
+#ifdef FEAT_AUTOCMD
+		if (cmdchar != 'r' && cmdchar != 'v')
+		    apply_autocmds(EVENT_INSERTLEAVE, NULL, NULL,
+							       FALSE, curbuf);
+		did_cursorhold = FALSE;
+#endif
+		return (c == Ctrl_O);
+	    }
+	    continue;
+
+	case Ctrl_Z:	/* suspend when 'insertmode' set */
+	    if (!p_im)
+		goto normalchar;	/* insert CTRL-Z as normal char */
+	    stuffReadbuff((char_u *)":st\r");
+	    c = Ctrl_O;
+	    /*FALLTHROUGH*/
+
+	case Ctrl_O:	/* execute one command */
+#ifdef FEAT_COMPL_FUNC
+	    if (ctrl_x_mode == CTRL_X_OMNI)
+		goto docomplete;
+#endif
+	    if (echeck_abbr(Ctrl_O + ABBR_OFF))
+		break;
+	    ins_ctrl_o();
+
+#ifdef FEAT_VIRTUALEDIT
+	    /* don't move the cursor left when 'virtualedit' has "onemore". */
+	    if (ve_flags & VE_ONEMORE)
+	    {
+		ins_at_eol = FALSE;
+		nomove = TRUE;
+	    }
+#endif
+	    count = 0;
+	    goto doESCkey;
+
+	case K_INS:	/* toggle insert/replace mode */
+	case K_KINS:
+	    ins_insert(replaceState);
+	    break;
+
+	case K_SELECT:	/* end of Select mode mapping - ignore */
+	    break;
+
+#ifdef FEAT_SNIFF
+	case K_SNIFF:	/* Sniff command received */
+	    stuffcharReadbuff(K_SNIFF);
+	    goto doESCkey;
+#endif
+
+	case K_HELP:	/* Help key works like <ESC> <Help> */
+	case K_F1:
+	case K_XF1:
+	    stuffcharReadbuff(K_HELP);
+	    if (p_im)
+		need_start_insertmode = TRUE;
+	    goto doESCkey;
+
+#ifdef FEAT_NETBEANS_INTG
+	case K_F21:	/* NetBeans command */
+	    ++no_mapping;		/* don't map the next key hits */
+	    i = safe_vgetc();
+	    --no_mapping;
+	    netbeans_keycommand(i);
+	    break;
+#endif
+
+	case K_ZERO:	/* Insert the previously inserted text. */
+	case NUL:
+	case Ctrl_A:
+	    /* For ^@ the trailing ESC will end the insert, unless there is an
+	     * error.  */
+	    if (stuff_inserted(NUL, 1L, (c == Ctrl_A)) == FAIL
+						   && c != Ctrl_A && !p_im)
+		goto doESCkey;		/* quit insert mode */
+	    inserted_space = FALSE;
+	    break;
+
+	case Ctrl_R:	/* insert the contents of a register */
+	    ins_reg();
+	    auto_format(FALSE, TRUE);
+	    inserted_space = FALSE;
+	    break;
+
+	case Ctrl_G:	/* commands starting with CTRL-G */
+	    ins_ctrl_g();
+	    break;
+
+	case Ctrl_HAT:	/* switch input mode and/or langmap */
+	    ins_ctrl_hat();
+	    break;
+
+#ifdef FEAT_RIGHTLEFT
+	case Ctrl__:	/* switch between languages */
+	    if (!p_ari)
+		goto normalchar;
+	    ins_ctrl_();
+	    break;
+#endif
+
+	case Ctrl_D:	/* Make indent one shiftwidth smaller. */
+#if defined(FEAT_INS_EXPAND) && defined(FEAT_FIND_ID)
+	    if (ctrl_x_mode == CTRL_X_PATH_DEFINES)
+		goto docomplete;
+#endif
+	    /* FALLTHROUGH */
+
+	case Ctrl_T:	/* Make indent one shiftwidth greater. */
+# ifdef FEAT_INS_EXPAND
+	    if (c == Ctrl_T && ctrl_x_mode == CTRL_X_THESAURUS)
+	    {
+		if (has_compl_option(FALSE))
+		    goto docomplete;
+		break;
+	    }
+# endif
+	    ins_shift(c, lastc);
+	    auto_format(FALSE, TRUE);
+	    inserted_space = FALSE;
+	    break;
+
+	case K_DEL:	/* delete character under the cursor */
+	case K_KDEL:
+	    ins_del();
+	    auto_format(FALSE, TRUE);
+	    break;
+
+	case K_BS:	/* delete character before the cursor */
+	case Ctrl_H:
+	    did_backspace = ins_bs(c, BACKSPACE_CHAR, &inserted_space);
+	    auto_format(FALSE, TRUE);
+	    break;
+
+	case Ctrl_W:	/* delete word before the cursor */
+	    did_backspace = ins_bs(c, BACKSPACE_WORD, &inserted_space);
+	    auto_format(FALSE, TRUE);
+	    break;
+
+	case Ctrl_U:	/* delete all inserted text in current line */
+# ifdef FEAT_COMPL_FUNC
+	    /* CTRL-X CTRL-U completes with 'completefunc'. */
+	    if (ctrl_x_mode == CTRL_X_FUNCTION)
+		goto docomplete;
+# endif
+	    did_backspace = ins_bs(c, BACKSPACE_LINE, &inserted_space);
+	    auto_format(FALSE, TRUE);
+	    inserted_space = FALSE;
+	    break;
+
+#ifdef FEAT_MOUSE
+	case K_LEFTMOUSE:   /* mouse keys */
+	case K_LEFTMOUSE_NM:
+	case K_LEFTDRAG:
+	case K_LEFTRELEASE:
+	case K_LEFTRELEASE_NM:
+	case K_MIDDLEMOUSE:
+	case K_MIDDLEDRAG:
+	case K_MIDDLERELEASE:
+	case K_RIGHTMOUSE:
+	case K_RIGHTDRAG:
+	case K_RIGHTRELEASE:
+	case K_X1MOUSE:
+	case K_X1DRAG:
+	case K_X1RELEASE:
+	case K_X2MOUSE:
+	case K_X2DRAG:
+	case K_X2RELEASE:
+	    ins_mouse(c);
+	    break;
+
+	case K_MOUSEDOWN: /* Default action for scroll wheel up: scroll up */
+	    ins_mousescroll(FALSE);
+	    break;
+
+	case K_MOUSEUP:	/* Default action for scroll wheel down: scroll down */
+	    ins_mousescroll(TRUE);
+	    break;
+#endif
+#ifdef FEAT_GUI_TABLINE
+	case K_TABLINE:
+	case K_TABMENU:
+	    ins_tabline(c);
+	    break;
+#endif
+
+	case K_IGNORE:	/* Something mapped to nothing */
+	    break;
+
+#ifdef FEAT_AUTOCMD
+	case K_CURSORHOLD:	/* Didn't type something for a while. */
+	    apply_autocmds(EVENT_CURSORHOLDI, NULL, NULL, FALSE, curbuf);
+	    did_cursorhold = TRUE;
+	    break;
+#endif
+
+#ifdef FEAT_GUI_W32
+	    /* On Win32 ignore <M-F4>, we get it when closing the window was
+	     * cancelled. */
+	case K_F4:
+	    if (mod_mask != MOD_MASK_ALT)
+		goto normalchar;
+	    break;
+#endif
+
+#ifdef FEAT_GUI
+	case K_VER_SCROLLBAR:
+	    ins_scroll();
+	    break;
+
+	case K_HOR_SCROLLBAR:
+	    ins_horscroll();
+	    break;
+#endif
+
+	case K_HOME:	/* <Home> */
+	case K_KHOME:
+	case K_S_HOME:
+	case K_C_HOME:
+	    ins_home(c);
+	    break;
+
+	case K_END:	/* <End> */
+	case K_KEND:
+	case K_S_END:
+	case K_C_END:
+	    ins_end(c);
+	    break;
+
+	case K_LEFT:	/* <Left> */
+	    if (mod_mask & (MOD_MASK_SHIFT|MOD_MASK_CTRL))
+		ins_s_left();
+	    else
+		ins_left();
+	    break;
+
+	case K_S_LEFT:	/* <S-Left> */
+	case K_C_LEFT:
+	    ins_s_left();
+	    break;
+
+	case K_RIGHT:	/* <Right> */
+	    if (mod_mask & (MOD_MASK_SHIFT|MOD_MASK_CTRL))
+		ins_s_right();
+	    else
+		ins_right();
+	    break;
+
+	case K_S_RIGHT:	/* <S-Right> */
+	case K_C_RIGHT:
+	    ins_s_right();
+	    break;
+
+	case K_UP:	/* <Up> */
+#ifdef FEAT_INS_EXPAND
+	    if (pum_visible())
+		goto docomplete;
+#endif
+	    if (mod_mask & MOD_MASK_SHIFT)
+		ins_pageup();
+	    else
+		ins_up(FALSE);
+	    break;
+
+	case K_S_UP:	/* <S-Up> */
+	case K_PAGEUP:
+	case K_KPAGEUP:
+#ifdef FEAT_INS_EXPAND
+	    if (pum_visible())
+		goto docomplete;
+#endif
+	    ins_pageup();
+	    break;
+
+	case K_DOWN:	/* <Down> */
+#ifdef FEAT_INS_EXPAND
+	    if (pum_visible())
+		goto docomplete;
+#endif
+	    if (mod_mask & MOD_MASK_SHIFT)
+		ins_pagedown();
+	    else
+		ins_down(FALSE);
+	    break;
+
+	case K_S_DOWN:	/* <S-Down> */
+	case K_PAGEDOWN:
+	case K_KPAGEDOWN:
+#ifdef FEAT_INS_EXPAND
+	    if (pum_visible())
+		goto docomplete;
+#endif
+	    ins_pagedown();
+	    break;
+
+#ifdef FEAT_DND
+	case K_DROP:	/* drag-n-drop event */
+	    ins_drop();
+	    break;
+#endif
+
+	case K_S_TAB:	/* When not mapped, use like a normal TAB */
+	    c = TAB;
+	    /* FALLTHROUGH */
+
+	case TAB:	/* TAB or Complete patterns along path */
+#if defined(FEAT_INS_EXPAND) && defined(FEAT_FIND_ID)
+	    if (ctrl_x_mode == CTRL_X_PATH_PATTERNS)
+		goto docomplete;
+#endif
+	    inserted_space = FALSE;
+	    if (ins_tab())
+		goto normalchar;	/* insert TAB as a normal char */
+	    auto_format(FALSE, TRUE);
+	    break;
+
+	case K_KENTER:	/* <Enter> */
+	    c = CAR;
+	    /* FALLTHROUGH */
+	case CAR:
+	case NL:
+#if defined(FEAT_WINDOWS) && defined(FEAT_QUICKFIX)
+	    /* In a quickfix window a <CR> jumps to the error under the
+	     * cursor. */
+	    if (bt_quickfix(curbuf) && c == CAR)
+	    {
+		if (curwin->w_llist_ref == NULL)    /* quickfix window */
+		    do_cmdline_cmd((char_u *)".cc");
+		else				    /* location list window */
+		    do_cmdline_cmd((char_u *)".ll");
+		break;
+	    }
+#endif
+#ifdef FEAT_CMDWIN
+	    if (cmdwin_type != 0)
+	    {
+		/* Execute the command in the cmdline window. */
+		cmdwin_result = CAR;
+		goto doESCkey;
+	    }
+#endif
+	    if (ins_eol(c) && !p_im)
+		goto doESCkey;	    /* out of memory */
+	    auto_format(FALSE, FALSE);
+	    inserted_space = FALSE;
+	    break;
+
+#if defined(FEAT_DIGRAPHS) || defined (FEAT_INS_EXPAND)
+	case Ctrl_K:	    /* digraph or keyword completion */
+# ifdef FEAT_INS_EXPAND
+	    if (ctrl_x_mode == CTRL_X_DICTIONARY)
+	    {
+		if (has_compl_option(TRUE))
+		    goto docomplete;
+		break;
+	    }
+# endif
+# ifdef FEAT_DIGRAPHS
+	    c = ins_digraph();
+	    if (c == NUL)
+		break;
+# endif
+	    goto normalchar;
+#endif
+
+#ifdef FEAT_INS_EXPAND
+	case Ctrl_X:	/* Enter CTRL-X mode */
+	    ins_ctrl_x();
+	    break;
+
+	case Ctrl_RSB:	/* Tag name completion after ^X */
+	    if (ctrl_x_mode != CTRL_X_TAGS)
+		goto normalchar;
+	    goto docomplete;
+
+	case Ctrl_F:	/* File name completion after ^X */
+	    if (ctrl_x_mode != CTRL_X_FILES)
+		goto normalchar;
+	    goto docomplete;
+
+	case 's':	/* Spelling completion after ^X */
+	case Ctrl_S:
+	    if (ctrl_x_mode != CTRL_X_SPELL)
+		goto normalchar;
+	    goto docomplete;
+#endif
+
+	case Ctrl_L:	/* Whole line completion after ^X */
+#ifdef FEAT_INS_EXPAND
+	    if (ctrl_x_mode != CTRL_X_WHOLE_LINE)
+#endif
+	    {
+		/* CTRL-L with 'insertmode' set: Leave Insert mode */
+		if (p_im)
+		{
+		    if (echeck_abbr(Ctrl_L + ABBR_OFF))
+			break;
+		    goto doESCkey;
+		}
+		goto normalchar;
+	    }
+#ifdef FEAT_INS_EXPAND
+	    /* FALLTHROUGH */
+
+	case Ctrl_P:	/* Do previous/next pattern completion */
+	case Ctrl_N:
+	    /* if 'complete' is empty then plain ^P is no longer special,
+	     * but it is under other ^X modes */
+	    if (*curbuf->b_p_cpt == NUL
+		    && ctrl_x_mode != 0
+		    && !(compl_cont_status & CONT_LOCAL))
+		goto normalchar;
+
+docomplete:
+	    if (ins_complete(c) == FAIL)
+		compl_cont_status = 0;
+	    break;
+#endif /* FEAT_INS_EXPAND */
+
+	case Ctrl_Y:	/* copy from previous line or scroll down */
+	case Ctrl_E:	/* copy from next line	   or scroll up */
+	    c = ins_ctrl_ey(c);
+	    break;
+
+	  default:
+#ifdef UNIX
+	    if (c == intr_char)		/* special interrupt char */
+		goto do_intr;
+#endif
+
+	    /*
+	     * Insert a nomal character.
+	     */
+normalchar:
+#ifdef FEAT_SMARTINDENT
+	    /* Try to perform smart-indenting. */
+	    ins_try_si(c);
+#endif
+
+	    if (c == ' ')
+	    {
+		inserted_space = TRUE;
+#ifdef FEAT_CINDENT
+		if (inindent(0))
+		    can_cindent = FALSE;
+#endif
+		if (Insstart_blank_vcol == MAXCOL
+			&& curwin->w_cursor.lnum == Insstart.lnum)
+		    Insstart_blank_vcol = get_nolist_virtcol();
+	    }
+
+	    if (vim_iswordc(c) || !echeck_abbr(
+#ifdef FEAT_MBYTE
+			/* Add ABBR_OFF for characters above 0x100, this is
+			 * what check_abbr() expects. */
+			(has_mbyte && c >= 0x100) ? (c + ABBR_OFF) :
+#endif
+			c))
+	    {
+		insert_special(c, FALSE, FALSE);
+#ifdef FEAT_RIGHTLEFT
+		revins_legal++;
+		revins_chars++;
+#endif
+	    }
+
+	    auto_format(FALSE, TRUE);
+
+#ifdef FEAT_FOLDING
+	    /* When inserting a character the cursor line must never be in a
+	     * closed fold. */
+	    foldOpenCursor();
+#endif
+	    break;
+	}   /* end of switch (c) */
+
+#ifdef FEAT_AUTOCMD
+	/* If typed something may trigger CursorHoldI again. */
+	if (c != K_CURSORHOLD)
+	    did_cursorhold = FALSE;
+#endif
+
+	/* If the cursor was moved we didn't just insert a space */
+	if (arrow_used)
+	    inserted_space = FALSE;
+
+#ifdef FEAT_CINDENT
+	if (can_cindent && cindent_on()
+# ifdef FEAT_INS_EXPAND
+		&& ctrl_x_mode == 0
+# endif
+	   )
+	{
+force_cindent:
+	    /*
+	     * Indent now if a key was typed that is in 'cinkeys'.
+	     */
+	    if (in_cinkeys(c, ' ', line_is_white))
+	    {
+		if (stop_arrow() == OK)
+		    /* re-indent the current line */
+		    do_c_expr_indent();
+	    }
+	}
+#endif /* FEAT_CINDENT */
+
+    }	/* for (;;) */
+    /* NOTREACHED */
+}
+
+/*
+ * Redraw for Insert mode.
+ * This is postponed until getting the next character to make '$' in the 'cpo'
+ * option work correctly.
+ * Only redraw when there are no characters available.  This speeds up
+ * inserting sequences of characters (e.g., for CTRL-R).
+ */
+/*ARGSUSED*/
+    static void
+ins_redraw(ready)
+    int		ready;	    /* not busy with something */
+{
+    if (!char_avail())
+    {
+#ifdef FEAT_AUTOCMD
+	/* Trigger CursorMoved if the cursor moved.  Not when the popup menu is
+	 * visible, the command might delete it. */
+	if (ready && has_cursormovedI()
+			     && !equalpos(last_cursormoved, curwin->w_cursor)
+# ifdef FEAT_INS_EXPAND
+			     && !pum_visible()
+# endif
+			     )
+	{
+	    apply_autocmds(EVENT_CURSORMOVEDI, NULL, NULL, FALSE, curbuf);
+	    last_cursormoved = curwin->w_cursor;
+	}
+#endif
+	if (must_redraw)
+	    update_screen(0);
+	else if (clear_cmdline || redraw_cmdline)
+	    showmode();		/* clear cmdline and show mode */
+	showruler(FALSE);
+	setcursor();
+	emsg_on_display = FALSE;	/* may remove error message now */
+    }
+}
+
+/*
+ * Handle a CTRL-V or CTRL-Q typed in Insert mode.
+ */
+    static void
+ins_ctrl_v()
+{
+    int		c;
+
+    /* may need to redraw when no more chars available now */
+    ins_redraw(FALSE);
+
+    if (redrawing() && !char_avail())
+	edit_putchar('^', TRUE);
+    AppendToRedobuff((char_u *)CTRL_V_STR);	/* CTRL-V */
+
+#ifdef FEAT_CMDL_INFO
+    add_to_showcmd_c(Ctrl_V);
+#endif
+
+    c = get_literal();
+#ifdef FEAT_CMDL_INFO
+    clear_showcmd();
+#endif
+    insert_special(c, FALSE, TRUE);
+#ifdef FEAT_RIGHTLEFT
+    revins_chars++;
+    revins_legal++;
+#endif
+}
+
+/*
+ * Put a character directly onto the screen.  It's not stored in a buffer.
+ * Used while handling CTRL-K, CTRL-V, etc. in Insert mode.
+ */
+static int  pc_status;
+#define PC_STATUS_UNSET	0	/* pc_bytes was not set */
+#define PC_STATUS_RIGHT	1	/* right halve of double-wide char */
+#define PC_STATUS_LEFT	2	/* left halve of double-wide char */
+#define PC_STATUS_SET	3	/* pc_bytes was filled */
+#ifdef FEAT_MBYTE
+static char_u pc_bytes[MB_MAXBYTES + 1]; /* saved bytes */
+#else
+static char_u pc_bytes[2];		/* saved bytes */
+#endif
+static int  pc_attr;
+static int  pc_row;
+static int  pc_col;
+
+    void
+edit_putchar(c, highlight)
+    int	    c;
+    int	    highlight;
+{
+    int	    attr;
+
+    if (ScreenLines != NULL)
+    {
+	update_topline();	/* just in case w_topline isn't valid */
+	validate_cursor();
+	if (highlight)
+	    attr = hl_attr(HLF_8);
+	else
+	    attr = 0;
+	pc_row = W_WINROW(curwin) + curwin->w_wrow;
+	pc_col = W_WINCOL(curwin);
+#if defined(FEAT_RIGHTLEFT) || defined(FEAT_MBYTE)
+	pc_status = PC_STATUS_UNSET;
+#endif
+#ifdef FEAT_RIGHTLEFT
+	if (curwin->w_p_rl)
+	{
+	    pc_col += W_WIDTH(curwin) - 1 - curwin->w_wcol;
+# ifdef FEAT_MBYTE
+	    if (has_mbyte)
+	    {
+		int fix_col = mb_fix_col(pc_col, pc_row);
+
+		if (fix_col != pc_col)
+		{
+		    screen_putchar(' ', pc_row, fix_col, attr);
+		    --curwin->w_wcol;
+		    pc_status = PC_STATUS_RIGHT;
+		}
+	    }
+# endif
+	}
+	else
+#endif
+	{
+	    pc_col += curwin->w_wcol;
+#ifdef FEAT_MBYTE
+	    if (mb_lefthalve(pc_row, pc_col))
+		pc_status = PC_STATUS_LEFT;
+#endif
+	}
+
+	/* save the character to be able to put it back */
+#if defined(FEAT_RIGHTLEFT) || defined(FEAT_MBYTE)
+	if (pc_status == PC_STATUS_UNSET)
+#endif
+	{
+	    screen_getbytes(pc_row, pc_col, pc_bytes, &pc_attr);
+	    pc_status = PC_STATUS_SET;
+	}
+	screen_putchar(c, pc_row, pc_col, attr);
+    }
+}
+
+/*
+ * Undo the previous edit_putchar().
+ */
+    void
+edit_unputchar()
+{
+    if (pc_status != PC_STATUS_UNSET && pc_row >= msg_scrolled)
+    {
+#if defined(FEAT_MBYTE)
+	if (pc_status == PC_STATUS_RIGHT)
+	    ++curwin->w_wcol;
+	if (pc_status == PC_STATUS_RIGHT || pc_status == PC_STATUS_LEFT)
+	    redrawWinline(curwin->w_cursor.lnum, FALSE);
+	else
+#endif
+	    screen_puts(pc_bytes, pc_row - msg_scrolled, pc_col, pc_attr);
+    }
+}
+
+/*
+ * Called when p_dollar is set: display a '$' at the end of the changed text
+ * Only works when cursor is in the line that changes.
+ */
+    void
+display_dollar(col)
+    colnr_T	col;
+{
+    colnr_T save_col;
+
+    if (!redrawing())
+	return;
+
+    cursor_off();
+    save_col = curwin->w_cursor.col;
+    curwin->w_cursor.col = col;
+#ifdef FEAT_MBYTE
+    if (has_mbyte)
+    {
+	char_u *p;
+
+	/* If on the last byte of a multi-byte move to the first byte. */
+	p = ml_get_curline();
+	curwin->w_cursor.col -= (*mb_head_off)(p, p + col);
+    }
+#endif
+    curs_columns(FALSE);	    /* recompute w_wrow and w_wcol */
+    if (curwin->w_wcol < W_WIDTH(curwin))
+    {
+	edit_putchar('$', FALSE);
+	dollar_vcol = curwin->w_virtcol;
+    }
+    curwin->w_cursor.col = save_col;
+}
+
+/*
+ * Call this function before moving the cursor from the normal insert position
+ * in insert mode.
+ */
+    static void
+undisplay_dollar()
+{
+    if (dollar_vcol)
+    {
+	dollar_vcol = 0;
+	redrawWinline(curwin->w_cursor.lnum, FALSE);
+    }
+}
+
+/*
+ * Insert an indent (for <Tab> or CTRL-T) or delete an indent (for CTRL-D).
+ * Keep the cursor on the same character.
+ * type == INDENT_INC	increase indent (for CTRL-T or <Tab>)
+ * type == INDENT_DEC	decrease indent (for CTRL-D)
+ * type == INDENT_SET	set indent to "amount"
+ * if round is TRUE, round the indent to 'shiftwidth' (only with _INC and _Dec).
+ */
+    void
+change_indent(type, amount, round, replaced)
+    int		type;
+    int		amount;
+    int		round;
+    int		replaced;	/* replaced character, put on replace stack */
+{
+    int		vcol;
+    int		last_vcol;
+    int		insstart_less;		/* reduction for Insstart.col */
+    int		new_cursor_col;
+    int		i;
+    char_u	*ptr;
+    int		save_p_list;
+    int		start_col;
+    colnr_T	vc;
+#ifdef FEAT_VREPLACE
+    colnr_T	orig_col = 0;		/* init for GCC */
+    char_u	*new_line, *orig_line = NULL;	/* init for GCC */
+
+    /* VREPLACE mode needs to know what the line was like before changing */
+    if (State & VREPLACE_FLAG)
+    {
+	orig_line = vim_strsave(ml_get_curline());  /* Deal with NULL below */
+	orig_col = curwin->w_cursor.col;
+    }
+#endif
+
+    /* for the following tricks we don't want list mode */
+    save_p_list = curwin->w_p_list;
+    curwin->w_p_list = FALSE;
+    vc = getvcol_nolist(&curwin->w_cursor);
+    vcol = vc;
+
+    /*
+     * For Replace mode we need to fix the replace stack later, which is only
+     * possible when the cursor is in the indent.  Remember the number of
+     * characters before the cursor if it's possible.
+     */
+    start_col = curwin->w_cursor.col;
+
+    /* determine offset from first non-blank */
+    new_cursor_col = curwin->w_cursor.col;
+    beginline(BL_WHITE);
+    new_cursor_col -= curwin->w_cursor.col;
+
+    insstart_less = curwin->w_cursor.col;
+
+    /*
+     * If the cursor is in the indent, compute how many screen columns the
+     * cursor is to the left of the first non-blank.
+     */
+    if (new_cursor_col < 0)
+	vcol = get_indent() - vcol;
+
+    if (new_cursor_col > 0)	    /* can't fix replace stack */
+	start_col = -1;
+
+    /*
+     * Set the new indent.  The cursor will be put on the first non-blank.
+     */
+    if (type == INDENT_SET)
+	(void)set_indent(amount, SIN_CHANGED);
+    else
+    {
+#ifdef FEAT_VREPLACE
+	int	save_State = State;
+
+	/* Avoid being called recursively. */
+	if (State & VREPLACE_FLAG)
+	    State = INSERT;
+#endif
+	shift_line(type == INDENT_DEC, round, 1);
+#ifdef FEAT_VREPLACE
+	State = save_State;
+#endif
+    }
+    insstart_less -= curwin->w_cursor.col;
+
+    /*
+     * Try to put cursor on same character.
+     * If the cursor is at or after the first non-blank in the line,
+     * compute the cursor column relative to the column of the first
+     * non-blank character.
+     * If we are not in insert mode, leave the cursor on the first non-blank.
+     * If the cursor is before the first non-blank, position it relative
+     * to the first non-blank, counted in screen columns.
+     */
+    if (new_cursor_col >= 0)
+    {
+	/*
+	 * When changing the indent while the cursor is touching it, reset
+	 * Insstart_col to 0.
+	 */
+	if (new_cursor_col == 0)
+	    insstart_less = MAXCOL;
+	new_cursor_col += curwin->w_cursor.col;
+    }
+    else if (!(State & INSERT))
+	new_cursor_col = curwin->w_cursor.col;
+    else
+    {
+	/*
+	 * Compute the screen column where the cursor should be.
+	 */
+	vcol = get_indent() - vcol;
+	curwin->w_virtcol = (vcol < 0) ? 0 : vcol;
+
+	/*
+	 * Advance the cursor until we reach the right screen column.
+	 */
+	vcol = last_vcol = 0;
+	new_cursor_col = -1;
+	ptr = ml_get_curline();
+	while (vcol <= (int)curwin->w_virtcol)
+	{
+	    last_vcol = vcol;
+#ifdef FEAT_MBYTE
+	    if (has_mbyte && new_cursor_col >= 0)
+		new_cursor_col += (*mb_ptr2len)(ptr + new_cursor_col);
+	    else
+#endif
+		++new_cursor_col;
+	    vcol += lbr_chartabsize(ptr + new_cursor_col, (colnr_T)vcol);
+	}
+	vcol = last_vcol;
+
+	/*
+	 * May need to insert spaces to be able to position the cursor on
+	 * the right screen column.
+	 */
+	if (vcol != (int)curwin->w_virtcol)
+	{
+	    curwin->w_cursor.col = new_cursor_col;
+	    i = (int)curwin->w_virtcol - vcol;
+	    ptr = alloc(i + 1);
+	    if (ptr != NULL)
+	    {
+		new_cursor_col += i;
+		ptr[i] = NUL;
+		while (--i >= 0)
+		    ptr[i] = ' ';
+		ins_str(ptr);
+		vim_free(ptr);
+	    }
+	}
+
+	/*
+	 * When changing the indent while the cursor is in it, reset
+	 * Insstart_col to 0.
+	 */
+	insstart_less = MAXCOL;
+    }
+
+    curwin->w_p_list = save_p_list;
+
+    if (new_cursor_col <= 0)
+	curwin->w_cursor.col = 0;
+    else
+	curwin->w_cursor.col = new_cursor_col;
+    curwin->w_set_curswant = TRUE;
+    changed_cline_bef_curs();
+
+    /*
+     * May have to adjust the start of the insert.
+     */
+    if (State & INSERT)
+    {
+	if (curwin->w_cursor.lnum == Insstart.lnum && Insstart.col != 0)
+	{
+	    if ((int)Insstart.col <= insstart_less)
+		Insstart.col = 0;
+	    else
+		Insstart.col -= insstart_less;
+	}
+	if ((int)ai_col <= insstart_less)
+	    ai_col = 0;
+	else
+	    ai_col -= insstart_less;
+    }
+
+    /*
+     * For REPLACE mode, may have to fix the replace stack, if it's possible.
+     * If the number of characters before the cursor decreased, need to pop a
+     * few characters from the replace stack.
+     * If the number of characters before the cursor increased, need to push a
+     * few NULs onto the replace stack.
+     */
+    if (REPLACE_NORMAL(State) && start_col >= 0)
+    {
+	while (start_col > (int)curwin->w_cursor.col)
+	{
+	    replace_join(0);	    /* remove a NUL from the replace stack */
+	    --start_col;
+	}
+	while (start_col < (int)curwin->w_cursor.col || replaced)
+	{
+	    replace_push(NUL);
+	    if (replaced)
+	    {
+		replace_push(replaced);
+		replaced = NUL;
+	    }
+	    ++start_col;
+	}
+    }
+
+#ifdef FEAT_VREPLACE
+    /*
+     * For VREPLACE mode, we also have to fix the replace stack.  In this case
+     * it is always possible because we backspace over the whole line and then
+     * put it back again the way we wanted it.
+     */
+    if (State & VREPLACE_FLAG)
+    {
+	/* If orig_line didn't allocate, just return.  At least we did the job,
+	 * even if you can't backspace. */
+	if (orig_line == NULL)
+	    return;
+
+	/* Save new line */
+	new_line = vim_strsave(ml_get_curline());
+	if (new_line == NULL)
+	    return;
+
+	/* We only put back the new line up to the cursor */
+	new_line[curwin->w_cursor.col] = NUL;
+
+	/* Put back original line */
+	ml_replace(curwin->w_cursor.lnum, orig_line, FALSE);
+	curwin->w_cursor.col = orig_col;
+
+	/* Backspace from cursor to start of line */
+	backspace_until_column(0);
+
+	/* Insert new stuff into line again */
+	ins_bytes(new_line);
+
+	vim_free(new_line);
+    }
+#endif
+}
+
+/*
+ * Truncate the space at the end of a line.  This is to be used only in an
+ * insert mode.  It handles fixing the replace stack for REPLACE and VREPLACE
+ * modes.
+ */
+    void
+truncate_spaces(line)
+    char_u  *line;
+{
+    int	    i;
+
+    /* find start of trailing white space */
+    for (i = (int)STRLEN(line) - 1; i >= 0 && vim_iswhite(line[i]); i--)
+    {
+	if (State & REPLACE_FLAG)
+	    replace_join(0);	    /* remove a NUL from the replace stack */
+    }
+    line[i + 1] = NUL;
+}
+
+#if defined(FEAT_VREPLACE) || defined(FEAT_INS_EXPAND) \
+	|| defined(FEAT_COMMENTS) || defined(PROTO)
+/*
+ * Backspace the cursor until the given column.  Handles REPLACE and VREPLACE
+ * modes correctly.  May also be used when not in insert mode at all.
+ */
+    void
+backspace_until_column(col)
+    int	    col;
+{
+    while ((int)curwin->w_cursor.col > col)
+    {
+	curwin->w_cursor.col--;
+	if (State & REPLACE_FLAG)
+	    replace_do_bs();
+	else
+	    (void)del_char(FALSE);
+    }
+}
+#endif
+
+#if defined(FEAT_INS_EXPAND) || defined(PROTO)
+/*
+ * CTRL-X pressed in Insert mode.
+ */
+    static void
+ins_ctrl_x()
+{
+    /* CTRL-X after CTRL-X CTRL-V doesn't do anything, so that CTRL-X
+     * CTRL-V works like CTRL-N */
+    if (ctrl_x_mode != CTRL_X_CMDLINE)
+    {
+	/* if the next ^X<> won't ADD nothing, then reset
+	 * compl_cont_status */
+	if (compl_cont_status & CONT_N_ADDS)
+	    compl_cont_status |= CONT_INTRPT;
+	else
+	    compl_cont_status = 0;
+	/* We're not sure which CTRL-X mode it will be yet */
+	ctrl_x_mode = CTRL_X_NOT_DEFINED_YET;
+	edit_submode = (char_u *)_(CTRL_X_MSG(ctrl_x_mode));
+	edit_submode_pre = NULL;
+	showmode();
+    }
+}
+
+/*
+ * Return TRUE if the 'dict' or 'tsr' option can be used.
+ */
+    static int
+has_compl_option(dict_opt)
+    int	    dict_opt;
+{
+    if (dict_opt ? (*curbuf->b_p_dict == NUL && *p_dict == NUL
+# ifdef FEAT_SPELL
+							&& !curwin->w_p_spell
+# endif
+							)
+		 : (*curbuf->b_p_tsr == NUL && *p_tsr == NUL))
+    {
+	ctrl_x_mode = 0;
+	edit_submode = NULL;
+	msg_attr(dict_opt ? (char_u *)_("'dictionary' option is empty")
+			  : (char_u *)_("'thesaurus' option is empty"),
+							      hl_attr(HLF_E));
+	if (emsg_silent == 0)
+	{
+	    vim_beep();
+	    setcursor();
+	    out_flush();
+	    ui_delay(2000L, FALSE);
+	}
+	return FALSE;
+    }
+    return TRUE;
+}
+
+/*
+ * Is the character 'c' a valid key to go to or keep us in CTRL-X mode?
+ * This depends on the current mode.
+ */
+    int
+vim_is_ctrl_x_key(c)
+    int	    c;
+{
+    /* Always allow ^R - let it's results then be checked */
+    if (c == Ctrl_R)
+	return TRUE;
+
+    /* Accept <PageUp> and <PageDown> if the popup menu is visible. */
+    if (ins_compl_pum_key(c))
+	return TRUE;
+
+    switch (ctrl_x_mode)
+    {
+	case 0:		    /* Not in any CTRL-X mode */
+	    return (c == Ctrl_N || c == Ctrl_P || c == Ctrl_X);
+	case CTRL_X_NOT_DEFINED_YET:
+	    return (   c == Ctrl_X || c == Ctrl_Y || c == Ctrl_E
+		    || c == Ctrl_L || c == Ctrl_F || c == Ctrl_RSB
+		    || c == Ctrl_I || c == Ctrl_D || c == Ctrl_P
+		    || c == Ctrl_N || c == Ctrl_T || c == Ctrl_V
+		    || c == Ctrl_Q || c == Ctrl_U || c == Ctrl_O
+		    || c == Ctrl_S || c == 's');
+	case CTRL_X_SCROLL:
+	    return (c == Ctrl_Y || c == Ctrl_E);
+	case CTRL_X_WHOLE_LINE:
+	    return (c == Ctrl_L || c == Ctrl_P || c == Ctrl_N);
+	case CTRL_X_FILES:
+	    return (c == Ctrl_F || c == Ctrl_P || c == Ctrl_N);
+	case CTRL_X_DICTIONARY:
+	    return (c == Ctrl_K || c == Ctrl_P || c == Ctrl_N);
+	case CTRL_X_THESAURUS:
+	    return (c == Ctrl_T || c == Ctrl_P || c == Ctrl_N);
+	case CTRL_X_TAGS:
+	    return (c == Ctrl_RSB || c == Ctrl_P || c == Ctrl_N);
+#ifdef FEAT_FIND_ID
+	case CTRL_X_PATH_PATTERNS:
+	    return (c == Ctrl_P || c == Ctrl_N);
+	case CTRL_X_PATH_DEFINES:
+	    return (c == Ctrl_D || c == Ctrl_P || c == Ctrl_N);
+#endif
+	case CTRL_X_CMDLINE:
+	    return (c == Ctrl_V || c == Ctrl_Q || c == Ctrl_P || c == Ctrl_N
+		    || c == Ctrl_X);
+#ifdef FEAT_COMPL_FUNC
+	case CTRL_X_FUNCTION:
+	    return (c == Ctrl_U || c == Ctrl_P || c == Ctrl_N);
+	case CTRL_X_OMNI:
+	    return (c == Ctrl_O || c == Ctrl_P || c == Ctrl_N);
+#endif
+	case CTRL_X_SPELL:
+	    return (c == Ctrl_S || c == Ctrl_P || c == Ctrl_N);
+    }
+    EMSG(_(e_internal));
+    return FALSE;
+}
+
+/*
+ * This is like ins_compl_add(), but if 'ic' and 'inf' are set, then the
+ * case of the originally typed text is used, and the case of the completed
+ * text is inferred, ie this tries to work out what case you probably wanted
+ * the rest of the word to be in -- webb
+ * TODO: make this work for multi-byte characters.
+ */
+    int
+ins_compl_add_infercase(str, len, icase, fname, dir, flags)
+    char_u	*str;
+    int		len;
+    int		icase;
+    char_u	*fname;
+    int		dir;
+    int		flags;
+{
+    int		has_lower = FALSE;
+    int		was_letter = FALSE;
+    int		idx;
+
+    if (p_ic && curbuf->b_p_inf && len < IOSIZE)
+    {
+	/* Infer case of completed part -- webb */
+	/* Use IObuff, str would change text in buffer! */
+	vim_strncpy(IObuff, str, len);
+
+	/* Rule 1: Were any chars converted to lower? */
+	for (idx = 0; idx < compl_length; ++idx)
+	{
+	    if (islower(compl_orig_text[idx]))
+	    {
+		has_lower = TRUE;
+		if (isupper(IObuff[idx]))
+		{
+		    /* Rule 1 is satisfied */
+		    for (idx = compl_length; idx < len; ++idx)
+			IObuff[idx] = TOLOWER_LOC(IObuff[idx]);
+		    break;
+		}
+	    }
+	}
+
+	/*
+	 * Rule 2: No lower case, 2nd consecutive letter converted to
+	 * upper case.
+	 */
+	if (!has_lower)
+	{
+	    for (idx = 0; idx < compl_length; ++idx)
+	    {
+		if (was_letter && isupper(compl_orig_text[idx])
+						      && islower(IObuff[idx]))
+		{
+		    /* Rule 2 is satisfied */
+		    for (idx = compl_length; idx < len; ++idx)
+			IObuff[idx] = TOUPPER_LOC(IObuff[idx]);
+		    break;
+		}
+		was_letter = isalpha(compl_orig_text[idx]);
+	    }
+	}
+
+	/* Copy the original case of the part we typed */
+	STRNCPY(IObuff, compl_orig_text, compl_length);
+
+	return ins_compl_add(IObuff, len, icase, fname, NULL, dir,
+								flags, FALSE);
+    }
+    return ins_compl_add(str, len, icase, fname, NULL, dir, flags, FALSE);
+}
+
+/*
+ * Add a match to the list of matches.
+ * If the given string is already in the list of completions, then return
+ * NOTDONE, otherwise add it to the list and return OK.  If there is an error,
+ * maybe because alloc() returns NULL, then FAIL is returned.
+ */
+    static int
+ins_compl_add(str, len, icase, fname, cptext, cdir, flags, adup)
+    char_u	*str;
+    int		len;
+    int		icase;
+    char_u	*fname;
+    char_u	**cptext;   /* extra text for popup menu or NULL */
+    int		cdir;
+    int		flags;
+    int		adup;	    /* accept duplicate match */
+{
+    compl_T	*match;
+    int		dir = (cdir == 0 ? compl_direction : cdir);
+
+    ui_breakcheck();
+    if (got_int)
+	return FAIL;
+    if (len < 0)
+	len = (int)STRLEN(str);
+
+    /*
+     * If the same match is already present, don't add it.
+     */
+    if (compl_first_match != NULL && !adup)
+    {
+	match = compl_first_match;
+	do
+	{
+	    if (    !(match->cp_flags & ORIGINAL_TEXT)
+		    && STRNCMP(match->cp_str, str, len) == 0
+		    && match->cp_str[len] == NUL)
+		return NOTDONE;
+	    match = match->cp_next;
+	} while (match != NULL && match != compl_first_match);
+    }
+
+    /* Remove any popup menu before changing the list of matches. */
+    ins_compl_del_pum();
+
+    /*
+     * Allocate a new match structure.
+     * Copy the values to the new match structure.
+     */
+    match = (compl_T *)alloc_clear((unsigned)sizeof(compl_T));
+    if (match == NULL)
+	return FAIL;
+    match->cp_number = -1;
+    if (flags & ORIGINAL_TEXT)
+	match->cp_number = 0;
+    if ((match->cp_str = vim_strnsave(str, len)) == NULL)
+    {
+	vim_free(match);
+	return FAIL;
+    }
+    match->cp_icase = icase;
+
+    /* match-fname is:
+     * - compl_curr_match->cp_fname if it is a string equal to fname.
+     * - a copy of fname, FREE_FNAME is set to free later THE allocated mem.
+     * - NULL otherwise.	--Acevedo */
+    if (fname != NULL
+	    && compl_curr_match != NULL
+	    && compl_curr_match->cp_fname != NULL
+	    && STRCMP(fname, compl_curr_match->cp_fname) == 0)
+	match->cp_fname = compl_curr_match->cp_fname;
+    else if (fname != NULL)
+    {
+	match->cp_fname = vim_strsave(fname);
+	flags |= FREE_FNAME;
+    }
+    else
+	match->cp_fname = NULL;
+    match->cp_flags = flags;
+
+    if (cptext != NULL)
+    {
+	int i;
+
+	for (i = 0; i < CPT_COUNT; ++i)
+	    if (cptext[i] != NULL && *cptext[i] != NUL)
+		match->cp_text[i] = vim_strsave(cptext[i]);
+    }
+
+    /*
+     * Link the new match structure in the list of matches.
+     */
+    if (compl_first_match == NULL)
+	match->cp_next = match->cp_prev = NULL;
+    else if (dir == FORWARD)
+    {
+	match->cp_next = compl_curr_match->cp_next;
+	match->cp_prev = compl_curr_match;
+    }
+    else	/* BACKWARD */
+    {
+	match->cp_next = compl_curr_match;
+	match->cp_prev = compl_curr_match->cp_prev;
+    }
+    if (match->cp_next)
+	match->cp_next->cp_prev = match;
+    if (match->cp_prev)
+	match->cp_prev->cp_next = match;
+    else	/* if there's nothing before, it is the first match */
+	compl_first_match = match;
+    compl_curr_match = match;
+
+    /*
+     * Find the longest common string if still doing that.
+     */
+    if (compl_get_longest && (flags & ORIGINAL_TEXT) == 0)
+	ins_compl_longest_match(match);
+
+    return OK;
+}
+
+/*
+ * Return TRUE if "str[len]" matches with match->cp_str, considering
+ * match->cp_icase.
+ */
+    static int
+ins_compl_equal(match, str, len)
+    compl_T	*match;
+    char_u	*str;
+    int		len;
+{
+    if (match->cp_icase)
+	return STRNICMP(match->cp_str, str, (size_t)len) == 0;
+    return STRNCMP(match->cp_str, str, (size_t)len) == 0;
+}
+
+/*
+ * Reduce the longest common string for match "match".
+ */
+    static void
+ins_compl_longest_match(match)
+    compl_T	*match;
+{
+    char_u	*p, *s;
+    int		c1, c2;
+    int		had_match;
+
+    if (compl_leader == NULL)
+    {
+	/* First match, use it as a whole. */
+	compl_leader = vim_strsave(match->cp_str);
+	if (compl_leader != NULL)
+	{
+	    had_match = (curwin->w_cursor.col > compl_col);
+	    ins_compl_delete();
+	    ins_bytes(compl_leader + curwin->w_cursor.col - compl_col);
+	    ins_redraw(FALSE);
+
+	    /* When the match isn't there (to avoid matching itself) remove it
+	     * again after redrawing. */
+	    if (!had_match)
+		ins_compl_delete();
+	    compl_used_match = FALSE;
+	}
+    }
+    else
+    {
+	/* Reduce the text if this match differs from compl_leader. */
+	p = compl_leader;
+	s = match->cp_str;
+	while (*p != NUL)
+	{
+#ifdef FEAT_MBYTE
+	    if (has_mbyte)
+	    {
+		c1 = mb_ptr2char(p);
+		c2 = mb_ptr2char(s);
+	    }
+	    else
+#endif
+	    {
+		c1 = *p;
+		c2 = *s;
+	    }
+	    if (match->cp_icase ? (MB_TOLOWER(c1) != MB_TOLOWER(c2))
+								 : (c1 != c2))
+		break;
+#ifdef FEAT_MBYTE
+	    if (has_mbyte)
+	    {
+		mb_ptr_adv(p);
+		mb_ptr_adv(s);
+	    }
+	    else
+#endif
+	    {
+		++p;
+		++s;
+	    }
+	}
+
+	if (*p != NUL)
+	{
+	    /* Leader was shortened, need to change the inserted text. */
+	    *p = NUL;
+	    had_match = (curwin->w_cursor.col > compl_col);
+	    ins_compl_delete();
+	    ins_bytes(compl_leader + curwin->w_cursor.col - compl_col);
+	    ins_redraw(FALSE);
+
+	    /* When the match isn't there (to avoid matching itself) remove it
+	     * again after redrawing. */
+	    if (!had_match)
+		ins_compl_delete();
+	}
+
+	compl_used_match = FALSE;
+    }
+}
+
+/*
+ * Add an array of matches to the list of matches.
+ * Frees matches[].
+ */
+    static void
+ins_compl_add_matches(num_matches, matches, icase)
+    int		num_matches;
+    char_u	**matches;
+    int		icase;
+{
+    int		i;
+    int		add_r = OK;
+    int		dir = compl_direction;
+
+    for (i = 0; i < num_matches && add_r != FAIL; i++)
+	if ((add_r = ins_compl_add(matches[i], -1, icase,
+					    NULL, NULL, dir, 0, FALSE)) == OK)
+	    /* if dir was BACKWARD then honor it just once */
+	    dir = FORWARD;
+    FreeWild(num_matches, matches);
+}
+
+/* Make the completion list cyclic.
+ * Return the number of matches (excluding the original).
+ */
+    static int
+ins_compl_make_cyclic()
+{
+    compl_T *match;
+    int	    count = 0;
+
+    if (compl_first_match != NULL)
+    {
+	/*
+	 * Find the end of the list.
+	 */
+	match = compl_first_match;
+	/* there's always an entry for the compl_orig_text, it doesn't count. */
+	while (match->cp_next != NULL && match->cp_next != compl_first_match)
+	{
+	    match = match->cp_next;
+	    ++count;
+	}
+	match->cp_next = compl_first_match;
+	compl_first_match->cp_prev = match;
+    }
+    return count;
+}
+
+/*
+ * Start completion for the complete() function.
+ * "startcol" is where the matched text starts (1 is first column).
+ * "list" is the list of matches.
+ */
+    void
+set_completion(startcol, list)
+    int	    startcol;
+    list_T  *list;
+{
+    /* If already doing completions stop it. */
+    if (ctrl_x_mode != 0)
+	ins_compl_prep(' ');
+    ins_compl_clear();
+
+    if (stop_arrow() == FAIL)
+	return;
+
+    if (startcol > (int)curwin->w_cursor.col)
+	startcol = curwin->w_cursor.col;
+    compl_col = startcol;
+    compl_length = curwin->w_cursor.col - startcol;
+    /* compl_pattern doesn't need to be set */
+    compl_orig_text = vim_strnsave(ml_get_curline() + compl_col, compl_length);
+    if (compl_orig_text == NULL || ins_compl_add(compl_orig_text,
+			-1, p_ic, NULL, NULL, 0, ORIGINAL_TEXT, FALSE) != OK)
+	return;
+
+    /* Handle like dictionary completion. */
+    ctrl_x_mode = CTRL_X_WHOLE_LINE;
+
+    ins_compl_add_list(list);
+    compl_matches = ins_compl_make_cyclic();
+    compl_started = TRUE;
+    compl_used_match = TRUE;
+    compl_cont_status = 0;
+
+    compl_curr_match = compl_first_match;
+    ins_complete(Ctrl_N);
+    out_flush();
+}
+
+
+/* "compl_match_array" points the currently displayed list of entries in the
+ * popup menu.  It is NULL when there is no popup menu. */
+static pumitem_T *compl_match_array = NULL;
+static int compl_match_arraysize;
+
+/*
+ * Update the screen and when there is any scrolling remove the popup menu.
+ */
+    static void
+ins_compl_upd_pum()
+{
+    int		h;
+
+    if (compl_match_array != NULL)
+    {
+	h = curwin->w_cline_height;
+	update_screen(0);
+	if (h != curwin->w_cline_height)
+	    ins_compl_del_pum();
+    }
+}
+
+/*
+ * Remove any popup menu.
+ */
+    static void
+ins_compl_del_pum()
+{
+    if (compl_match_array != NULL)
+    {
+	pum_undisplay();
+	vim_free(compl_match_array);
+	compl_match_array = NULL;
+    }
+}
+
+/*
+ * Return TRUE if the popup menu should be displayed.
+ */
+    static int
+pum_wanted()
+{
+    /* 'completeopt' must contain "menu" or "menuone" */
+    if (vim_strchr(p_cot, 'm') == NULL)
+	return FALSE;
+
+    /* The display looks bad on a B&W display. */
+    if (t_colors < 8
+#ifdef FEAT_GUI
+	    && !gui.in_use
+#endif
+	    )
+	return FALSE;
+    return TRUE;
+}
+
+/*
+ * Return TRUE if there are two or more matches to be shown in the popup menu.
+ * One if 'completopt' contains "menuone".
+ */
+    static int
+pum_enough_matches()
+{
+    compl_T     *compl;
+    int		i;
+
+    /* Don't display the popup menu if there are no matches or there is only
+     * one (ignoring the original text). */
+    compl = compl_first_match;
+    i = 0;
+    do
+    {
+	if (compl == NULL
+		      || ((compl->cp_flags & ORIGINAL_TEXT) == 0 && ++i == 2))
+	    break;
+	compl = compl->cp_next;
+    } while (compl != compl_first_match);
+
+    if (strstr((char *)p_cot, "menuone") != NULL)
+	return (i >= 1);
+    return (i >= 2);
+}
+
+/*
+ * Show the popup menu for the list of matches.
+ * Also adjusts "compl_shown_match" to an entry that is actually displayed.
+ */
+    void
+ins_compl_show_pum()
+{
+    compl_T     *compl;
+    compl_T     *shown_compl = NULL;
+    int		did_find_shown_match = FALSE;
+    int		shown_match_ok = FALSE;
+    int		i;
+    int		cur = -1;
+    colnr_T	col;
+    int		lead_len = 0;
+
+    if (!pum_wanted() || !pum_enough_matches())
+	return;
+
+#if defined(FEAT_EVAL)
+    /* Dirty hard-coded hack: remove any matchparen highlighting. */
+    do_cmdline_cmd((char_u *)"if exists('g:loaded_matchparen')|3match none|endif");
+#endif
+
+    /* Update the screen before drawing the popup menu over it. */
+    update_screen(0);
+
+    if (compl_match_array == NULL)
+    {
+	/* Need to build the popup menu list. */
+	compl_match_arraysize = 0;
+	compl = compl_first_match;
+	if (compl_leader != NULL)
+	    lead_len = (int)STRLEN(compl_leader);
+	do
+	{
+	    if ((compl->cp_flags & ORIGINAL_TEXT) == 0
+		    && (compl_leader == NULL
+			|| ins_compl_equal(compl, compl_leader, lead_len)))
+		++compl_match_arraysize;
+	    compl = compl->cp_next;
+	} while (compl != NULL && compl != compl_first_match);
+	if (compl_match_arraysize == 0)
+	    return;
+	compl_match_array = (pumitem_T *)alloc_clear(
+				    (unsigned)(sizeof(pumitem_T)
+						    * compl_match_arraysize));
+	if (compl_match_array != NULL)
+	{
+	    /* If the current match is the original text don't find the first
+	     * match after it, don't highlight anything. */
+	    if (compl_shown_match->cp_flags & ORIGINAL_TEXT)
+		shown_match_ok = TRUE;
+
+	    i = 0;
+	    compl = compl_first_match;
+	    do
+	    {
+		if ((compl->cp_flags & ORIGINAL_TEXT) == 0
+			&& (compl_leader == NULL
+			    || ins_compl_equal(compl, compl_leader, lead_len)))
+		{
+		    if (!shown_match_ok)
+		    {
+			if (compl == compl_shown_match || did_find_shown_match)
+			{
+			    /* This item is the shown match or this is the
+			     * first displayed item after the shown match. */
+			    compl_shown_match = compl;
+			    did_find_shown_match = TRUE;
+			    shown_match_ok = TRUE;
+			}
+			else
+			    /* Remember this displayed match for when the
+			     * shown match is just below it. */
+			    shown_compl = compl;
+			cur = i;
+		    }
+
+		    if (compl->cp_text[CPT_ABBR] != NULL)
+			compl_match_array[i].pum_text =
+						     compl->cp_text[CPT_ABBR];
+		    else
+			compl_match_array[i].pum_text = compl->cp_str;
+		    compl_match_array[i].pum_kind = compl->cp_text[CPT_KIND];
+		    compl_match_array[i].pum_info = compl->cp_text[CPT_INFO];
+		    if (compl->cp_text[CPT_MENU] != NULL)
+			compl_match_array[i++].pum_extra =
+						     compl->cp_text[CPT_MENU];
+		    else
+			compl_match_array[i++].pum_extra = compl->cp_fname;
+		}
+
+		if (compl == compl_shown_match)
+		{
+		    did_find_shown_match = TRUE;
+
+		    /* When the original text is the shown match don't set
+		     * compl_shown_match. */
+		    if (compl->cp_flags & ORIGINAL_TEXT)
+			shown_match_ok = TRUE;
+
+		    if (!shown_match_ok && shown_compl != NULL)
+		    {
+			/* The shown match isn't displayed, set it to the
+			 * previously displayed match. */
+			compl_shown_match = shown_compl;
+			shown_match_ok = TRUE;
+		    }
+		}
+		compl = compl->cp_next;
+	    } while (compl != NULL && compl != compl_first_match);
+
+	    if (!shown_match_ok)    /* no displayed match at all */
+		cur = -1;
+	}
+    }
+    else
+    {
+	/* popup menu already exists, only need to find the current item.*/
+	for (i = 0; i < compl_match_arraysize; ++i)
+	    if (compl_match_array[i].pum_text == compl_shown_match->cp_str
+		    || compl_match_array[i].pum_text
+				      == compl_shown_match->cp_text[CPT_ABBR])
+	    {
+		cur = i;
+		break;
+	    }
+    }
+
+    if (compl_match_array != NULL)
+    {
+	/* Compute the screen column of the start of the completed text.
+	 * Use the cursor to get all wrapping and other settings right. */
+	col = curwin->w_cursor.col;
+	curwin->w_cursor.col = compl_col;
+	pum_display(compl_match_array, compl_match_arraysize, cur);
+	curwin->w_cursor.col = col;
+    }
+}
+
+#define DICT_FIRST	(1)	/* use just first element in "dict" */
+#define DICT_EXACT	(2)	/* "dict" is the exact name of a file */
+
+/*
+ * Add any identifiers that match the given pattern in the list of dictionary
+ * files "dict_start" to the list of completions.
+ */
+    static void
+ins_compl_dictionaries(dict_start, pat, flags, thesaurus)
+    char_u	*dict_start;
+    char_u	*pat;
+    int		flags;		/* DICT_FIRST and/or DICT_EXACT */
+    int		thesaurus;	/* Thesaurus completion */
+{
+    char_u	*dict = dict_start;
+    char_u	*ptr;
+    char_u	*buf;
+    regmatch_T	regmatch;
+    char_u	**files;
+    int		count;
+    int		i;
+    int		save_p_scs;
+    int		dir = compl_direction;
+
+    if (*dict == NUL)
+    {
+#ifdef FEAT_SPELL
+	/* When 'dictionary' is empty and spell checking is enabled use
+	 * "spell". */
+	if (!thesaurus && curwin->w_p_spell)
+	    dict = (char_u *)"spell";
+	else
+#endif
+	    return;
+    }
+
+    buf = alloc(LSIZE);
+    if (buf == NULL)
+	return;
+    regmatch.regprog = NULL;	/* so that we can goto theend */
+
+    /* If 'infercase' is set, don't use 'smartcase' here */
+    save_p_scs = p_scs;
+    if (curbuf->b_p_inf)
+	p_scs = FALSE;
+
+    /* When invoked to match whole lines for CTRL-X CTRL-L adjust the pattern
+     * to only match at the start of a line.  Otherwise just match the
+     * pattern. Also need to double backslashes. */
+    if (ctrl_x_mode == CTRL_X_WHOLE_LINE)
+    {
+	char_u *pat_esc = vim_strsave_escaped(pat, (char_u *)"\\");
+
+	if (pat_esc == NULL)
+	    goto theend;
+	i = (int)STRLEN(pat_esc) + 10;
+	ptr = alloc(i);
+	if (ptr == NULL)
+	{
+	    vim_free(pat_esc);
+	    goto theend;
+	}
+	vim_snprintf((char *)ptr, i, "^\\s*\\zs\\V%s", pat_esc);
+	regmatch.regprog = vim_regcomp(ptr, RE_MAGIC);
+	vim_free(pat_esc);
+	vim_free(ptr);
+    }
+    else
+    {
+	regmatch.regprog = vim_regcomp(pat, p_magic ? RE_MAGIC : 0);
+	if (regmatch.regprog == NULL)
+	    goto theend;
+    }
+
+    /* ignore case depends on 'ignorecase', 'smartcase' and "pat" */
+    regmatch.rm_ic = ignorecase(pat);
+    while (*dict != NUL && !got_int && !compl_interrupted)
+    {
+	/* copy one dictionary file name into buf */
+	if (flags == DICT_EXACT)
+	{
+	    count = 1;
+	    files = &dict;
+	}
+	else
+	{
+	    /* Expand wildcards in the dictionary name, but do not allow
+	     * backticks (for security, the 'dict' option may have been set in
+	     * a modeline). */
+	    copy_option_part(&dict, buf, LSIZE, ",");
+# ifdef FEAT_SPELL
+	    if (!thesaurus && STRCMP(buf, "spell") == 0)
+		count = -1;
+	    else
+# endif
+		if (vim_strchr(buf, '`') != NULL
+		    || expand_wildcards(1, &buf, &count, &files,
+						     EW_FILE|EW_SILENT) != OK)
+		count = 0;
+	}
+
+# ifdef FEAT_SPELL
+	if (count == -1)
+	{
+	    /* Complete from active spelling.  Skip "\<" in the pattern, we
+	     * don't use it as a RE. */
+	    if (pat[0] == '\\' && pat[1] == '<')
+		ptr = pat + 2;
+	    else
+		ptr = pat;
+	    spell_dump_compl(curbuf, ptr, regmatch.rm_ic, &dir, 0);
+	}
+	else
+# endif
+	    if (count > 0)	/* avoid warning for using "files" uninit */
+	{
+	    ins_compl_files(count, files, thesaurus, flags,
+							&regmatch, buf, &dir);
+	    if (flags != DICT_EXACT)
+		FreeWild(count, files);
+	}
+	if (flags != 0)
+	    break;
+    }
+
+theend:
+    p_scs = save_p_scs;
+    vim_free(regmatch.regprog);
+    vim_free(buf);
+}
+
+    static void
+ins_compl_files(count, files, thesaurus, flags, regmatch, buf, dir)
+    int		count;
+    char_u	**files;
+    int		thesaurus;
+    int		flags;
+    regmatch_T	*regmatch;
+    char_u	*buf;
+    int		*dir;
+{
+    char_u	*ptr;
+    int		i;
+    FILE	*fp;
+    int		add_r;
+
+    for (i = 0; i < count && !got_int && !compl_interrupted; i++)
+    {
+	fp = mch_fopen((char *)files[i], "r");  /* open dictionary file */
+	if (flags != DICT_EXACT)
+	{
+	    vim_snprintf((char *)IObuff, IOSIZE,
+			      _("Scanning dictionary: %s"), (char *)files[i]);
+	    msg_trunc_attr(IObuff, TRUE, hl_attr(HLF_R));
+	}
+
+	if (fp != NULL)
+	{
+	    /*
+	     * Read dictionary file line by line.
+	     * Check each line for a match.
+	     */
+	    while (!got_int && !compl_interrupted
+					    && !vim_fgets(buf, LSIZE, fp))
+	    {
+		ptr = buf;
+		while (vim_regexec(regmatch, buf, (colnr_T)(ptr - buf)))
+		{
+		    ptr = regmatch->startp[0];
+		    if (ctrl_x_mode == CTRL_X_WHOLE_LINE)
+			ptr = find_line_end(ptr);
+		    else
+			ptr = find_word_end(ptr);
+		    add_r = ins_compl_add_infercase(regmatch->startp[0],
+					  (int)(ptr - regmatch->startp[0]),
+						     p_ic, files[i], *dir, 0);
+		    if (thesaurus)
+		    {
+			char_u *wstart;
+
+			/*
+			 * Add the other matches on the line
+			 */
+			while (!got_int)
+			{
+			    /* Find start of the next word.  Skip white
+			     * space and punctuation. */
+			    ptr = find_word_start(ptr);
+			    if (*ptr == NUL || *ptr == NL)
+				break;
+			    wstart = ptr;
+
+			    /* Find end of the word and add it. */
+#ifdef FEAT_MBYTE
+			    if (has_mbyte)
+				/* Japanese words may have characters in
+				 * different classes, only separate words
+				 * with single-byte non-word characters. */
+				while (*ptr != NUL)
+				{
+				    int l = (*mb_ptr2len)(ptr);
+
+				    if (l < 2 && !vim_iswordc(*ptr))
+					break;
+				    ptr += l;
+				}
+			    else
+#endif
+				ptr = find_word_end(ptr);
+			    add_r = ins_compl_add_infercase(wstart,
+				    (int)(ptr - wstart),
+				    p_ic, files[i], *dir, 0);
+			}
+		    }
+		    if (add_r == OK)
+			/* if dir was BACKWARD then honor it just once */
+			*dir = FORWARD;
+		    else if (add_r == FAIL)
+			break;
+		    /* avoid expensive call to vim_regexec() when at end
+		     * of line */
+		    if (*ptr == '\n' || got_int)
+			break;
+		}
+		line_breakcheck();
+		ins_compl_check_keys(50);
+	    }
+	    fclose(fp);
+	}
+    }
+}
+
+/*
+ * Find the start of the next word.
+ * Returns a pointer to the first char of the word.  Also stops at a NUL.
+ */
+    char_u *
+find_word_start(ptr)
+    char_u	*ptr;
+{
+#ifdef FEAT_MBYTE
+    if (has_mbyte)
+	while (*ptr != NUL && *ptr != '\n' && mb_get_class(ptr) <= 1)
+	    ptr += (*mb_ptr2len)(ptr);
+    else
+#endif
+	while (*ptr != NUL && *ptr != '\n' && !vim_iswordc(*ptr))
+	    ++ptr;
+    return ptr;
+}
+
+/*
+ * Find the end of the word.  Assumes it starts inside a word.
+ * Returns a pointer to just after the word.
+ */
+    char_u *
+find_word_end(ptr)
+    char_u	*ptr;
+{
+#ifdef FEAT_MBYTE
+    int		start_class;
+
+    if (has_mbyte)
+    {
+	start_class = mb_get_class(ptr);
+	if (start_class > 1)
+	    while (*ptr != NUL)
+	    {
+		ptr += (*mb_ptr2len)(ptr);
+		if (mb_get_class(ptr) != start_class)
+		    break;
+	    }
+    }
+    else
+#endif
+	while (vim_iswordc(*ptr))
+	    ++ptr;
+    return ptr;
+}
+
+/*
+ * Find the end of the line, omitting CR and NL at the end.
+ * Returns a pointer to just after the line.
+ */
+    static char_u *
+find_line_end(ptr)
+    char_u	*ptr;
+{
+    char_u	*s;
+
+    s = ptr + STRLEN(ptr);
+    while (s > ptr && (s[-1] == CAR || s[-1] == NL))
+	--s;
+    return s;
+}
+
+/*
+ * Free the list of completions
+ */
+    static void
+ins_compl_free()
+{
+    compl_T *match;
+    int	    i;
+
+    vim_free(compl_pattern);
+    compl_pattern = NULL;
+    vim_free(compl_leader);
+    compl_leader = NULL;
+
+    if (compl_first_match == NULL)
+	return;
+
+    ins_compl_del_pum();
+    pum_clear();
+
+    compl_curr_match = compl_first_match;
+    do
+    {
+	match = compl_curr_match;
+	compl_curr_match = compl_curr_match->cp_next;
+	vim_free(match->cp_str);
+	/* several entries may use the same fname, free it just once. */
+	if (match->cp_flags & FREE_FNAME)
+	    vim_free(match->cp_fname);
+	for (i = 0; i < CPT_COUNT; ++i)
+	    vim_free(match->cp_text[i]);
+	vim_free(match);
+    } while (compl_curr_match != NULL && compl_curr_match != compl_first_match);
+    compl_first_match = compl_curr_match = NULL;
+}
+
+    static void
+ins_compl_clear()
+{
+    compl_cont_status = 0;
+    compl_started = FALSE;
+    compl_matches = 0;
+    vim_free(compl_pattern);
+    compl_pattern = NULL;
+    vim_free(compl_leader);
+    compl_leader = NULL;
+    edit_submode_extra = NULL;
+    vim_free(compl_orig_text);
+    compl_orig_text = NULL;
+    compl_enter_selects = FALSE;
+}
+
+/*
+ * Return TRUE when Insert completion is active.
+ */
+    int
+ins_compl_active()
+{
+    return compl_started;
+}
+
+/*
+ * Delete one character before the cursor and show the subset of the matches
+ * that match the word that is now before the cursor.
+ * Returns the character to be used, NUL if the work is done and another char
+ * to be got from the user.
+ */
+    static int
+ins_compl_bs()
+{
+    char_u	*line;
+    char_u	*p;
+
+    line = ml_get_curline();
+    p = line + curwin->w_cursor.col;
+    mb_ptr_back(line, p);
+
+    /* Stop completion when the whole word was deleted. */
+    if ((int)(p - line) - (int)compl_col <= 0)
+	return K_BS;
+
+    /* Deleted more than what was used to find matches or didn't finish
+     * finding all matches: need to look for matches all over again. */
+    if (curwin->w_cursor.col <= compl_col + compl_length
+						     || compl_was_interrupted)
+	ins_compl_restart();
+
+    vim_free(compl_leader);
+    compl_leader = vim_strnsave(line + compl_col, (int)(p - line) - compl_col);
+    if (compl_leader != NULL)
+    {
+	ins_compl_new_leader();
+	return NUL;
+    }
+    return K_BS;
+}
+
+/*
+ * Called after changing "compl_leader".
+ * Show the popup menu with a different set of matches.
+ * May also search for matches again if the previous search was interrupted.
+ */
+    static void
+ins_compl_new_leader()
+{
+    ins_compl_del_pum();
+    ins_compl_delete();
+    ins_bytes(compl_leader + curwin->w_cursor.col - compl_col);
+    compl_used_match = FALSE;
+
+    if (compl_started)
+	ins_compl_set_original_text(compl_leader);
+    else
+    {
+#ifdef FEAT_SPELL
+	spell_bad_len = 0;	/* need to redetect bad word */
+#endif
+	/*
+	 * Matches were cleared, need to search for them now.  First display
+	 * the changed text before the cursor.  Set "compl_restarting" to
+	 * avoid that the first match is inserted.
+	 */
+	update_screen(0);
+#ifdef FEAT_GUI
+	if (gui.in_use)
+	{
+	    /* Show the cursor after the match, not after the redrawn text. */
+	    setcursor();
+	    out_flush();
+	    gui_update_cursor(FALSE, FALSE);
+	}
+#endif
+	compl_restarting = TRUE;
+	if (ins_complete(Ctrl_N) == FAIL)
+	    compl_cont_status = 0;
+	compl_restarting = FALSE;
+    }
+
+#if 0   /* disabled, made CTRL-L, BS and typing char jump to original text. */
+    if (!compl_used_match)
+    {
+	/* Go to the original text, since none of the matches is inserted. */
+	if (compl_first_match->cp_prev != NULL
+		&& (compl_first_match->cp_prev->cp_flags & ORIGINAL_TEXT))
+	    compl_shown_match = compl_first_match->cp_prev;
+	else
+	    compl_shown_match = compl_first_match;
+	compl_curr_match = compl_shown_match;
+	compl_shows_dir = compl_direction;
+    }
+#endif
+    compl_enter_selects = !compl_used_match;
+
+    /* Show the popup menu with a different set of matches. */
+    ins_compl_show_pum();
+
+    /* Don't let Enter select the original text when there is no popup menu. */
+    if (compl_match_array == NULL)
+	compl_enter_selects = FALSE;
+}
+
+/*
+ * Append one character to the match leader.  May reduce the number of
+ * matches.
+ */
+    static void
+ins_compl_addleader(c)
+    int		c;
+{
+#ifdef FEAT_MBYTE
+    int		cc;
+
+    if (has_mbyte && (cc = (*mb_char2len)(c)) > 1)
+    {
+	char_u	buf[MB_MAXBYTES + 1];
+
+	(*mb_char2bytes)(c, buf);
+	buf[cc] = NUL;
+	ins_char_bytes(buf, cc);
+    }
+    else
+#endif
+	ins_char(c);
+
+    /* If we didn't complete finding matches we must search again. */
+    if (compl_was_interrupted)
+	ins_compl_restart();
+
+    vim_free(compl_leader);
+    compl_leader = vim_strnsave(ml_get_curline() + compl_col,
+					    curwin->w_cursor.col - compl_col);
+    if (compl_leader != NULL)
+	ins_compl_new_leader();
+}
+
+/*
+ * Setup for finding completions again without leaving CTRL-X mode.  Used when
+ * BS or a key was typed while still searching for matches.
+ */
+    static void
+ins_compl_restart()
+{
+    ins_compl_free();
+    compl_started = FALSE;
+    compl_matches = 0;
+    compl_cont_status = 0;
+    compl_cont_mode = 0;
+}
+
+/*
+ * Set the first match, the original text.
+ */
+    static void
+ins_compl_set_original_text(str)
+    char_u	*str;
+{
+    char_u	*p;
+
+    /* Replace the original text entry. */
+    if (compl_first_match->cp_flags & ORIGINAL_TEXT)	/* safety check */
+    {
+	p = vim_strsave(str);
+	if (p != NULL)
+	{
+	    vim_free(compl_first_match->cp_str);
+	    compl_first_match->cp_str = p;
+	}
+    }
+}
+
+/*
+ * Append one character to the match leader.  May reduce the number of
+ * matches.
+ */
+    static void
+ins_compl_addfrommatch()
+{
+    char_u	*p;
+    int		len = curwin->w_cursor.col - compl_col;
+    int		c;
+    compl_T	*cp;
+
+    p = compl_shown_match->cp_str;
+    if ((int)STRLEN(p) <= len)   /* the match is too short */
+    {
+	/* When still at the original match use the first entry that matches
+	 * the leader. */
+	if (compl_shown_match->cp_flags & ORIGINAL_TEXT)
+	{
+	    p = NULL;
+	    for (cp = compl_shown_match->cp_next; cp != NULL
+				 && cp != compl_first_match; cp = cp->cp_next)
+	    {
+		if (compl_leader == NULL
+			|| ins_compl_equal(cp, compl_leader,
+						   (int)STRLEN(compl_leader)))
+		{
+		    p = cp->cp_str;
+		    break;
+		}
+	    }
+	    if (p == NULL || (int)STRLEN(p) <= len)
+		return;
+	}
+	else
+	    return;
+    }
+    p += len;
+#ifdef FEAT_MBYTE
+    c = mb_ptr2char(p);
+#else
+    c = *p;
+#endif
+    ins_compl_addleader(c);
+}
+
+/*
+ * Prepare for Insert mode completion, or stop it.
+ * Called just after typing a character in Insert mode.
+ * Returns TRUE when the character is not to be inserted;
+ */
+    static int
+ins_compl_prep(c)
+    int	    c;
+{
+    char_u	*ptr;
+    int		want_cindent;
+    int		retval = FALSE;
+
+    /* Forget any previous 'special' messages if this is actually
+     * a ^X mode key - bar ^R, in which case we wait to see what it gives us.
+     */
+    if (c != Ctrl_R && vim_is_ctrl_x_key(c))
+	edit_submode_extra = NULL;
+
+    /* Ignore end of Select mode mapping */
+    if (c == K_SELECT)
+	return retval;
+
+    /* Set "compl_get_longest" when finding the first matches. */
+    if (ctrl_x_mode == CTRL_X_NOT_DEFINED_YET
+				      || (ctrl_x_mode == 0 && !compl_started))
+    {
+	compl_get_longest = (vim_strchr(p_cot, 'l') != NULL);
+	compl_used_match = TRUE;
+    }
+
+    if (ctrl_x_mode == CTRL_X_NOT_DEFINED_YET)
+    {
+	/*
+	 * We have just typed CTRL-X and aren't quite sure which CTRL-X mode
+	 * it will be yet.  Now we decide.
+	 */
+	switch (c)
+	{
+	    case Ctrl_E:
+	    case Ctrl_Y:
+		ctrl_x_mode = CTRL_X_SCROLL;
+		if (!(State & REPLACE_FLAG))
+		    edit_submode = (char_u *)_(" (insert) Scroll (^E/^Y)");
+		else
+		    edit_submode = (char_u *)_(" (replace) Scroll (^E/^Y)");
+		edit_submode_pre = NULL;
+		showmode();
+		break;
+	    case Ctrl_L:
+		ctrl_x_mode = CTRL_X_WHOLE_LINE;
+		break;
+	    case Ctrl_F:
+		ctrl_x_mode = CTRL_X_FILES;
+		break;
+	    case Ctrl_K:
+		ctrl_x_mode = CTRL_X_DICTIONARY;
+		break;
+	    case Ctrl_R:
+		/* Simply allow ^R to happen without affecting ^X mode */
+		break;
+	    case Ctrl_T:
+		ctrl_x_mode = CTRL_X_THESAURUS;
+		break;
+#ifdef FEAT_COMPL_FUNC
+	    case Ctrl_U:
+		ctrl_x_mode = CTRL_X_FUNCTION;
+		break;
+	    case Ctrl_O:
+		ctrl_x_mode = CTRL_X_OMNI;
+		break;
+#endif
+	    case 's':
+	    case Ctrl_S:
+		ctrl_x_mode = CTRL_X_SPELL;
+#ifdef FEAT_SPELL
+		++emsg_off;	/* Avoid getting the E756 error twice. */
+		spell_back_to_badword();
+		--emsg_off;
+#endif
+		break;
+	    case Ctrl_RSB:
+		ctrl_x_mode = CTRL_X_TAGS;
+		break;
+#ifdef FEAT_FIND_ID
+	    case Ctrl_I:
+	    case K_S_TAB:
+		ctrl_x_mode = CTRL_X_PATH_PATTERNS;
+		break;
+	    case Ctrl_D:
+		ctrl_x_mode = CTRL_X_PATH_DEFINES;
+		break;
+#endif
+	    case Ctrl_V:
+	    case Ctrl_Q:
+		ctrl_x_mode = CTRL_X_CMDLINE;
+		break;
+	    case Ctrl_P:
+	    case Ctrl_N:
+		/* ^X^P means LOCAL expansion if nothing interrupted (eg we
+		 * just started ^X mode, or there were enough ^X's to cancel
+		 * the previous mode, say ^X^F^X^X^P or ^P^X^X^X^P, see below)
+		 * do normal expansion when interrupting a different mode (say
+		 * ^X^F^X^P or ^P^X^X^P, see below)
+		 * nothing changes if interrupting mode 0, (eg, the flag
+		 * doesn't change when going to ADDING mode  -- Acevedo */
+		if (!(compl_cont_status & CONT_INTRPT))
+		    compl_cont_status |= CONT_LOCAL;
+		else if (compl_cont_mode != 0)
+		    compl_cont_status &= ~CONT_LOCAL;
+		/* FALLTHROUGH */
+	    default:
+		/* If we have typed at least 2 ^X's... for modes != 0, we set
+		 * compl_cont_status = 0 (eg, as if we had just started ^X
+		 * mode).
+		 * For mode 0, we set "compl_cont_mode" to an impossible
+		 * value, in both cases ^X^X can be used to restart the same
+		 * mode (avoiding ADDING mode).
+		 * Undocumented feature: In a mode != 0 ^X^P and ^X^X^P start
+		 * 'complete' and local ^P expansions respectively.
+		 * In mode 0 an extra ^X is needed since ^X^P goes to ADDING
+		 * mode  -- Acevedo */
+		if (c == Ctrl_X)
+		{
+		    if (compl_cont_mode != 0)
+			compl_cont_status = 0;
+		    else
+			compl_cont_mode = CTRL_X_NOT_DEFINED_YET;
+		}
+		ctrl_x_mode = 0;
+		edit_submode = NULL;
+		showmode();
+		break;
+	}
+    }
+    else if (ctrl_x_mode != 0)
+    {
+	/* We're already in CTRL-X mode, do we stay in it? */
+	if (!vim_is_ctrl_x_key(c))
+	{
+	    if (ctrl_x_mode == CTRL_X_SCROLL)
+		ctrl_x_mode = 0;
+	    else
+		ctrl_x_mode = CTRL_X_FINISHED;
+	    edit_submode = NULL;
+	}
+	showmode();
+    }
+
+    if (compl_started || ctrl_x_mode == CTRL_X_FINISHED)
+    {
+	/* Show error message from attempted keyword completion (probably
+	 * 'Pattern not found') until another key is hit, then go back to
+	 * showing what mode we are in. */
+	showmode();
+	if ((ctrl_x_mode == 0 && c != Ctrl_N && c != Ctrl_P && c != Ctrl_R
+						     && !ins_compl_pum_key(c))
+		|| ctrl_x_mode == CTRL_X_FINISHED)
+	{
+	    /* Get here when we have finished typing a sequence of ^N and
+	     * ^P or other completion characters in CTRL-X mode.  Free up
+	     * memory that was used, and make sure we can redo the insert. */
+	    if (compl_curr_match != NULL || compl_leader != NULL || c == Ctrl_E)
+	    {
+		char_u	*p;
+		int	temp = 0;
+
+		/*
+		 * If any of the original typed text has been changed, eg when
+		 * ignorecase is set, we must add back-spaces to the redo
+		 * buffer.  We add as few as necessary to delete just the part
+		 * of the original text that has changed.
+		 * When using the longest match, edited the match or used
+		 * CTRL-E then don't use the current match.
+		 */
+		if (compl_curr_match != NULL && compl_used_match && c != Ctrl_E)
+		    ptr = compl_curr_match->cp_str;
+		else if (compl_leader != NULL)
+		    ptr = compl_leader;
+		else
+		    ptr = compl_orig_text;
+		if (compl_orig_text != NULL)
+		{
+		    p = compl_orig_text;
+		    for (temp = 0; p[temp] != NUL && p[temp] == ptr[temp];
+								       ++temp)
+			;
+#ifdef FEAT_MBYTE
+		    if (temp > 0)
+			temp -= (*mb_head_off)(compl_orig_text, p + temp);
+#endif
+		    for (p += temp; *p != NUL; mb_ptr_adv(p))
+			AppendCharToRedobuff(K_BS);
+		}
+		if (ptr != NULL)
+		    AppendToRedobuffLit(ptr + temp, -1);
+	    }
+
+#ifdef FEAT_CINDENT
+	    want_cindent = (can_cindent && cindent_on());
+#endif
+	    /*
+	     * When completing whole lines: fix indent for 'cindent'.
+	     * Otherwise, break line if it's too long.
+	     */
+	    if (compl_cont_mode == CTRL_X_WHOLE_LINE)
+	    {
+#ifdef FEAT_CINDENT
+		/* re-indent the current line */
+		if (want_cindent)
+		{
+		    do_c_expr_indent();
+		    want_cindent = FALSE;	/* don't do it again */
+		}
+#endif
+	    }
+	    else
+	    {
+		int prev_col = curwin->w_cursor.col;
+
+		/* put the cursor on the last char, for 'tw' formatting */
+		if (prev_col > 0)
+		    dec_cursor();
+		if (stop_arrow() == OK)
+		    insertchar(NUL, 0, -1);
+		if (prev_col > 0
+			     && ml_get_curline()[curwin->w_cursor.col] != NUL)
+		    inc_cursor();
+	    }
+
+	    auto_format(FALSE, TRUE);
+
+	    /* If the popup menu is displayed pressing CTRL-Y means accepting
+	     * the selection without inserting anything.  When
+	     * compl_enter_selects is set the Enter key does the same. */
+	    if ((c == Ctrl_Y || (compl_enter_selects
+				   && (c == CAR || c == K_KENTER || c == NL)))
+		    && pum_visible())
+		retval = TRUE;
+
+	    /* CTRL-E means completion is Ended, go back to the typed text. */
+	    if (c == Ctrl_E)
+	    {
+		ins_compl_delete();
+		if (compl_leader != NULL)
+		    ins_bytes(compl_leader + curwin->w_cursor.col - compl_col);
+		else if (compl_first_match != NULL)
+		    ins_bytes(compl_orig_text
+					  + curwin->w_cursor.col - compl_col);
+		retval = TRUE;
+	    }
+
+	    ins_compl_free();
+	    compl_started = FALSE;
+	    compl_matches = 0;
+	    msg_clr_cmdline();		/* necessary for "noshowmode" */
+	    ctrl_x_mode = 0;
+	    compl_enter_selects = FALSE;
+	    if (edit_submode != NULL)
+	    {
+		edit_submode = NULL;
+		showmode();
+	    }
+
+#ifdef FEAT_CINDENT
+	    /*
+	     * Indent now if a key was typed that is in 'cinkeys'.
+	     */
+	    if (want_cindent && in_cinkeys(KEY_COMPLETE, ' ', inindent(0)))
+		do_c_expr_indent();
+#endif
+	}
+    }
+
+    /* reset continue_* if we left expansion-mode, if we stay they'll be
+     * (re)set properly in ins_complete() */
+    if (!vim_is_ctrl_x_key(c))
+    {
+	compl_cont_status = 0;
+	compl_cont_mode = 0;
+    }
+
+    return retval;
+}
+
+/*
+ * Loops through the list of windows, loaded-buffers or non-loaded-buffers
+ * (depending on flag) starting from buf and looking for a non-scanned
+ * buffer (other than curbuf).	curbuf is special, if it is called with
+ * buf=curbuf then it has to be the first call for a given flag/expansion.
+ *
+ * Returns the buffer to scan, if any, otherwise returns curbuf -- Acevedo
+ */
+    static buf_T *
+ins_compl_next_buf(buf, flag)
+    buf_T	*buf;
+    int		flag;
+{
+#ifdef FEAT_WINDOWS
+    static win_T *wp;
+#endif
+
+    if (flag == 'w')		/* just windows */
+    {
+#ifdef FEAT_WINDOWS
+	if (buf == curbuf)	/* first call for this flag/expansion */
+	    wp = curwin;
+	while ((wp = (wp->w_next != NULL ? wp->w_next : firstwin)) != curwin
+		&& wp->w_buffer->b_scanned)
+	    ;
+	buf = wp->w_buffer;
+#else
+	buf = curbuf;
+#endif
+    }
+    else
+	/* 'b' (just loaded buffers), 'u' (just non-loaded buffers) or 'U'
+	 * (unlisted buffers)
+	 * When completing whole lines skip unloaded buffers. */
+	while ((buf = (buf->b_next != NULL ? buf->b_next : firstbuf)) != curbuf
+		&& ((flag == 'U'
+			? buf->b_p_bl
+			: (!buf->b_p_bl
+			    || (buf->b_ml.ml_mfp == NULL) != (flag == 'u')))
+		    || buf->b_scanned))
+	    ;
+    return buf;
+}
+
+#ifdef FEAT_COMPL_FUNC
+static void expand_by_function __ARGS((int type, char_u *base));
+
+/*
+ * Execute user defined complete function 'completefunc' or 'omnifunc', and
+ * get matches in "matches".
+ */
+    static void
+expand_by_function(type, base)
+    int		type;	    /* CTRL_X_OMNI or CTRL_X_FUNCTION */
+    char_u	*base;
+{
+    list_T      *matchlist;
+    char_u	*args[2];
+    char_u	*funcname;
+    pos_T	pos;
+
+    funcname = (type == CTRL_X_FUNCTION) ? curbuf->b_p_cfu : curbuf->b_p_ofu;
+    if (*funcname == NUL)
+	return;
+
+    /* Call 'completefunc' to obtain the list of matches. */
+    args[0] = (char_u *)"0";
+    args[1] = base;
+
+    pos = curwin->w_cursor;
+    matchlist = call_func_retlist(funcname, 2, args, FALSE);
+    curwin->w_cursor = pos;	/* restore the cursor position */
+    if (matchlist == NULL)
+	return;
+
+    ins_compl_add_list(matchlist);
+    list_unref(matchlist);
+}
+#endif /* FEAT_COMPL_FUNC */
+
+#if defined(FEAT_COMPL_FUNC) || defined(FEAT_EVAL) || defined(PROTO)
+/*
+ * Add completions from a list.
+ */
+    static void
+ins_compl_add_list(list)
+    list_T	*list;
+{
+    listitem_T	*li;
+    int		dir = compl_direction;
+
+    /* Go through the List with matches and add each of them. */
+    for (li = list->lv_first; li != NULL; li = li->li_next)
+    {
+	if (ins_compl_add_tv(&li->li_tv, dir) == OK)
+	    /* if dir was BACKWARD then honor it just once */
+	    dir = FORWARD;
+	else if (did_emsg)
+	    break;
+    }
+}
+
+/*
+ * Add a match to the list of matches from a typeval_T.
+ * If the given string is already in the list of completions, then return
+ * NOTDONE, otherwise add it to the list and return OK.  If there is an error,
+ * maybe because alloc() returns NULL, then FAIL is returned.
+ */
+    int
+ins_compl_add_tv(tv, dir)
+    typval_T	*tv;
+    int		dir;
+{
+    char_u	*word;
+    int		icase = FALSE;
+    int		adup = FALSE;
+    char_u	*(cptext[CPT_COUNT]);
+
+    if (tv->v_type == VAR_DICT && tv->vval.v_dict != NULL)
+    {
+	word = get_dict_string(tv->vval.v_dict, (char_u *)"word", FALSE);
+	cptext[CPT_ABBR] = get_dict_string(tv->vval.v_dict,
+						     (char_u *)"abbr", FALSE);
+	cptext[CPT_MENU] = get_dict_string(tv->vval.v_dict,
+						     (char_u *)"menu", FALSE);
+	cptext[CPT_KIND] = get_dict_string(tv->vval.v_dict,
+						     (char_u *)"kind", FALSE);
+	cptext[CPT_INFO] = get_dict_string(tv->vval.v_dict,
+						     (char_u *)"info", FALSE);
+	if (get_dict_string(tv->vval.v_dict, (char_u *)"icase", FALSE) != NULL)
+	    icase = get_dict_number(tv->vval.v_dict, (char_u *)"icase");
+	if (get_dict_string(tv->vval.v_dict, (char_u *)"dup", FALSE) != NULL)
+	    adup = get_dict_number(tv->vval.v_dict, (char_u *)"dup");
+    }
+    else
+    {
+	word = get_tv_string_chk(tv);
+	vim_memset(cptext, 0, sizeof(cptext));
+    }
+    if (word == NULL || *word == NUL)
+	return FAIL;
+    return ins_compl_add(word, -1, icase, NULL, cptext, dir, 0, adup);
+}
+#endif
+
+/*
+ * Get the next expansion(s), using "compl_pattern".
+ * The search starts at position "ini" in curbuf and in the direction
+ * compl_direction.
+ * When "compl_started" is FALSE start at that position, otherwise continue
+ * where we stopped searching before.
+ * This may return before finding all the matches.
+ * Return the total number of matches or -1 if still unknown -- Acevedo
+ */
+    static int
+ins_compl_get_exp(ini)
+    pos_T	*ini;
+{
+    static pos_T	first_match_pos;
+    static pos_T	last_match_pos;
+    static char_u	*e_cpt = (char_u *)"";	/* curr. entry in 'complete' */
+    static int		found_all = FALSE;	/* Found all matches of a
+						   certain type. */
+    static buf_T	*ins_buf = NULL;	/* buffer being scanned */
+
+    pos_T	*pos;
+    char_u	**matches;
+    int		save_p_scs;
+    int		save_p_ws;
+    int		save_p_ic;
+    int		i;
+    int		num_matches;
+    int		len;
+    int		found_new_match;
+    int		type = ctrl_x_mode;
+    char_u	*ptr;
+    char_u	*dict = NULL;
+    int		dict_f = 0;
+    compl_T	*old_match;
+
+    if (!compl_started)
+    {
+	for (ins_buf = firstbuf; ins_buf != NULL; ins_buf = ins_buf->b_next)
+	    ins_buf->b_scanned = 0;
+	found_all = FALSE;
+	ins_buf = curbuf;
+	e_cpt = (compl_cont_status & CONT_LOCAL)
+					    ? (char_u *)"." : curbuf->b_p_cpt;
+	last_match_pos = first_match_pos = *ini;
+    }
+
+    old_match = compl_curr_match;	/* remember the last current match */
+    pos = (compl_direction == FORWARD) ? &last_match_pos : &first_match_pos;
+    /* For ^N/^P loop over all the flags/windows/buffers in 'complete' */
+    for (;;)
+    {
+	found_new_match = FAIL;
+
+	/* For ^N/^P pick a new entry from e_cpt if compl_started is off,
+	 * or if found_all says this entry is done.  For ^X^L only use the
+	 * entries from 'complete' that look in loaded buffers. */
+	if ((ctrl_x_mode == 0 || ctrl_x_mode == CTRL_X_WHOLE_LINE)
+					&& (!compl_started || found_all))
+	{
+	    found_all = FALSE;
+	    while (*e_cpt == ',' || *e_cpt == ' ')
+		e_cpt++;
+	    if (*e_cpt == '.' && !curbuf->b_scanned)
+	    {
+		ins_buf = curbuf;
+		first_match_pos = *ini;
+		/* So that ^N can match word immediately after cursor */
+		if (ctrl_x_mode == 0)
+		    dec(&first_match_pos);
+		last_match_pos = first_match_pos;
+		type = 0;
+	    }
+	    else if (vim_strchr((char_u *)"buwU", *e_cpt) != NULL
+		 && (ins_buf = ins_compl_next_buf(ins_buf, *e_cpt)) != curbuf)
+	    {
+		/* Scan a buffer, but not the current one. */
+		if (ins_buf->b_ml.ml_mfp != NULL)   /* loaded buffer */
+		{
+		    compl_started = TRUE;
+		    first_match_pos.col = last_match_pos.col = 0;
+		    first_match_pos.lnum = ins_buf->b_ml.ml_line_count + 1;
+		    last_match_pos.lnum = 0;
+		    type = 0;
+		}
+		else	/* unloaded buffer, scan like dictionary */
+		{
+		    found_all = TRUE;
+		    if (ins_buf->b_fname == NULL)
+			continue;
+		    type = CTRL_X_DICTIONARY;
+		    dict = ins_buf->b_fname;
+		    dict_f = DICT_EXACT;
+		}
+		vim_snprintf((char *)IObuff, IOSIZE, _("Scanning: %s"),
+			ins_buf->b_fname == NULL
+			    ? buf_spname(ins_buf)
+			    : ins_buf->b_sfname == NULL
+				? (char *)ins_buf->b_fname
+				: (char *)ins_buf->b_sfname);
+		msg_trunc_attr(IObuff, TRUE, hl_attr(HLF_R));
+	    }
+	    else if (*e_cpt == NUL)
+		break;
+	    else
+	    {
+		if (ctrl_x_mode == CTRL_X_WHOLE_LINE)
+		    type = -1;
+		else if (*e_cpt == 'k' || *e_cpt == 's')
+		{
+		    if (*e_cpt == 'k')
+			type = CTRL_X_DICTIONARY;
+		    else
+			type = CTRL_X_THESAURUS;
+		    if (*++e_cpt != ',' && *e_cpt != NUL)
+		    {
+			dict = e_cpt;
+			dict_f = DICT_FIRST;
+		    }
+		}
+#ifdef FEAT_FIND_ID
+		else if (*e_cpt == 'i')
+		    type = CTRL_X_PATH_PATTERNS;
+		else if (*e_cpt == 'd')
+		    type = CTRL_X_PATH_DEFINES;
+#endif
+		else if (*e_cpt == ']' || *e_cpt == 't')
+		{
+		    type = CTRL_X_TAGS;
+		    sprintf((char*)IObuff, _("Scanning tags."));
+		    msg_trunc_attr(IObuff, TRUE, hl_attr(HLF_R));
+		}
+		else
+		    type = -1;
+
+		/* in any case e_cpt is advanced to the next entry */
+		(void)copy_option_part(&e_cpt, IObuff, IOSIZE, ",");
+
+		found_all = TRUE;
+		if (type == -1)
+		    continue;
+	    }
+	}
+
+	switch (type)
+	{
+	case -1:
+	    break;
+#ifdef FEAT_FIND_ID
+	case CTRL_X_PATH_PATTERNS:
+	case CTRL_X_PATH_DEFINES:
+	    find_pattern_in_path(compl_pattern, compl_direction,
+				 (int)STRLEN(compl_pattern), FALSE, FALSE,
+				 (type == CTRL_X_PATH_DEFINES
+				  && !(compl_cont_status & CONT_SOL))
+				 ? FIND_DEFINE : FIND_ANY, 1L, ACTION_EXPAND,
+				 (linenr_T)1, (linenr_T)MAXLNUM);
+	    break;
+#endif
+
+	case CTRL_X_DICTIONARY:
+	case CTRL_X_THESAURUS:
+	    ins_compl_dictionaries(
+		    dict != NULL ? dict
+			 : (type == CTRL_X_THESAURUS
+			     ? (*curbuf->b_p_tsr == NUL
+				 ? p_tsr
+				 : curbuf->b_p_tsr)
+			     : (*curbuf->b_p_dict == NUL
+				 ? p_dict
+				 : curbuf->b_p_dict)),
+			    compl_pattern,
+				 dict != NULL ? dict_f
+					       : 0, type == CTRL_X_THESAURUS);
+	    dict = NULL;
+	    break;
+
+	case CTRL_X_TAGS:
+	    /* set p_ic according to p_ic, p_scs and pat for find_tags(). */
+	    save_p_ic = p_ic;
+	    p_ic = ignorecase(compl_pattern);
+
+	    /* Find up to TAG_MANY matches.  Avoids that an enourmous number
+	     * of matches is found when compl_pattern is empty */
+	    if (find_tags(compl_pattern, &num_matches, &matches,
+		    TAG_REGEXP | TAG_NAMES | TAG_NOIC |
+		    TAG_INS_COMP | (ctrl_x_mode ? TAG_VERBOSE : 0),
+		    TAG_MANY, curbuf->b_ffname) == OK && num_matches > 0)
+	    {
+		ins_compl_add_matches(num_matches, matches, p_ic);
+	    }
+	    p_ic = save_p_ic;
+	    break;
+
+	case CTRL_X_FILES:
+	    if (expand_wildcards(1, &compl_pattern, &num_matches, &matches,
+				  EW_FILE|EW_DIR|EW_ADDSLASH|EW_SILENT) == OK)
+	    {
+
+		/* May change home directory back to "~". */
+		tilde_replace(compl_pattern, num_matches, matches);
+		ins_compl_add_matches(num_matches, matches,
+#ifdef CASE_INSENSITIVE_FILENAME
+			TRUE
+#else
+			FALSE
+#endif
+			);
+	    }
+	    break;
+
+	case CTRL_X_CMDLINE:
+	    if (expand_cmdline(&compl_xp, compl_pattern,
+			(int)STRLEN(compl_pattern),
+					 &num_matches, &matches) == EXPAND_OK)
+		ins_compl_add_matches(num_matches, matches, FALSE);
+	    break;
+
+#ifdef FEAT_COMPL_FUNC
+	case CTRL_X_FUNCTION:
+	case CTRL_X_OMNI:
+	    expand_by_function(type, compl_pattern);
+	    break;
+#endif
+
+	case CTRL_X_SPELL:
+#ifdef FEAT_SPELL
+	    num_matches = expand_spelling(first_match_pos.lnum,
+				 first_match_pos.col, compl_pattern, &matches);
+	    if (num_matches > 0)
+		ins_compl_add_matches(num_matches, matches, p_ic);
+#endif
+	    break;
+
+	default:	/* normal ^P/^N and ^X^L */
+	    /*
+	     * If 'infercase' is set, don't use 'smartcase' here
+	     */
+	    save_p_scs = p_scs;
+	    if (ins_buf->b_p_inf)
+		p_scs = FALSE;
+
+	    /*	buffers other than curbuf are scanned from the beginning or the
+	     *	end but never from the middle, thus setting nowrapscan in this
+	     *	buffers is a good idea, on the other hand, we always set
+	     *	wrapscan for curbuf to avoid missing matches -- Acevedo,Webb */
+	    save_p_ws = p_ws;
+	    if (ins_buf != curbuf)
+		p_ws = FALSE;
+	    else if (*e_cpt == '.')
+		p_ws = TRUE;
+	    for (;;)
+	    {
+		int	flags = 0;
+
+		++msg_silent;  /* Don't want messages for wrapscan. */
+
+		/* ctrl_x_mode == CTRL_X_WHOLE_LINE || word-wise search that
+		 * has added a word that was at the beginning of the line */
+		if (	ctrl_x_mode == CTRL_X_WHOLE_LINE
+			|| (compl_cont_status & CONT_SOL))
+		    found_new_match = search_for_exact_line(ins_buf, pos,
+					      compl_direction, compl_pattern);
+		else
+		    found_new_match = searchit(NULL, ins_buf, pos,
+							      compl_direction,
+				 compl_pattern, 1L, SEARCH_KEEP + SEARCH_NFMSG,
+							RE_LAST, (linenr_T)0);
+		--msg_silent;
+		if (!compl_started)
+		{
+		    /* set "compl_started" even on fail */
+		    compl_started = TRUE;
+		    first_match_pos = *pos;
+		    last_match_pos = *pos;
+		}
+		else if (first_match_pos.lnum == last_match_pos.lnum
+				 && first_match_pos.col == last_match_pos.col)
+		    found_new_match = FAIL;
+		if (found_new_match == FAIL)
+		{
+		    if (ins_buf == curbuf)
+			found_all = TRUE;
+		    break;
+		}
+
+		/* when ADDING, the text before the cursor matches, skip it */
+		if (	(compl_cont_status & CONT_ADDING) && ins_buf == curbuf
+			&& ini->lnum == pos->lnum
+			&& ini->col  == pos->col)
+		    continue;
+		ptr = ml_get_buf(ins_buf, pos->lnum, FALSE) + pos->col;
+		if (ctrl_x_mode == CTRL_X_WHOLE_LINE)
+		{
+		    if (compl_cont_status & CONT_ADDING)
+		    {
+			if (pos->lnum >= ins_buf->b_ml.ml_line_count)
+			    continue;
+			ptr = ml_get_buf(ins_buf, pos->lnum + 1, FALSE);
+			if (!p_paste)
+			    ptr = skipwhite(ptr);
+		    }
+		    len = (int)STRLEN(ptr);
+		}
+		else
+		{
+		    char_u	*tmp_ptr = ptr;
+
+		    if (compl_cont_status & CONT_ADDING)
+		    {
+			tmp_ptr += compl_length;
+			/* Skip if already inside a word. */
+			if (vim_iswordp(tmp_ptr))
+			    continue;
+			/* Find start of next word. */
+			tmp_ptr = find_word_start(tmp_ptr);
+		    }
+		    /* Find end of this word. */
+		    tmp_ptr = find_word_end(tmp_ptr);
+		    len = (int)(tmp_ptr - ptr);
+
+		    if ((compl_cont_status & CONT_ADDING)
+						       && len == compl_length)
+		    {
+			if (pos->lnum < ins_buf->b_ml.ml_line_count)
+			{
+			    /* Try next line, if any. the new word will be
+			     * "join" as if the normal command "J" was used.
+			     * IOSIZE is always greater than
+			     * compl_length, so the next STRNCPY always
+			     * works -- Acevedo */
+			    STRNCPY(IObuff, ptr, len);
+			    ptr = ml_get_buf(ins_buf, pos->lnum + 1, FALSE);
+			    tmp_ptr = ptr = skipwhite(ptr);
+			    /* Find start of next word. */
+			    tmp_ptr = find_word_start(tmp_ptr);
+			    /* Find end of next word. */
+			    tmp_ptr = find_word_end(tmp_ptr);
+			    if (tmp_ptr > ptr)
+			    {
+				if (*ptr != ')' && IObuff[len - 1] != TAB)
+				{
+				    if (IObuff[len - 1] != ' ')
+					IObuff[len++] = ' ';
+				    /* IObuf =~ "\k.* ", thus len >= 2 */
+				    if (p_js
+					&& (IObuff[len - 2] == '.'
+					    || (vim_strchr(p_cpo, CPO_JOINSP)
+								       == NULL
+						&& (IObuff[len - 2] == '?'
+						 || IObuff[len - 2] == '!'))))
+					IObuff[len++] = ' ';
+				}
+				/* copy as much as posible of the new word */
+				if (tmp_ptr - ptr >= IOSIZE - len)
+				    tmp_ptr = ptr + IOSIZE - len - 1;
+				STRNCPY(IObuff + len, ptr, tmp_ptr - ptr);
+				len += (int)(tmp_ptr - ptr);
+				flags |= CONT_S_IPOS;
+			    }
+			    IObuff[len] = NUL;
+			    ptr = IObuff;
+			}
+			if (len == compl_length)
+			    continue;
+		    }
+		}
+		if (ins_compl_add_infercase(ptr, len, p_ic,
+				 ins_buf == curbuf ? NULL : ins_buf->b_sfname,
+					   0, flags) != NOTDONE)
+		{
+		    found_new_match = OK;
+		    break;
+		}
+	    }
+	    p_scs = save_p_scs;
+	    p_ws = save_p_ws;
+	}
+
+	/* check if compl_curr_match has changed, (e.g. other type of
+	 * expansion added somenthing) */
+	if (type != 0 && compl_curr_match != old_match)
+	    found_new_match = OK;
+
+	/* break the loop for specialized modes (use 'complete' just for the
+	 * generic ctrl_x_mode == 0) or when we've found a new match */
+	if ((ctrl_x_mode != 0 && ctrl_x_mode != CTRL_X_WHOLE_LINE)
+						   || found_new_match != FAIL)
+	{
+	    if (got_int)
+		break;
+	    /* Fill the popup menu as soon as possible. */
+	    if (type != -1)
+		ins_compl_check_keys(0);
+
+	    if ((ctrl_x_mode != 0 && ctrl_x_mode != CTRL_X_WHOLE_LINE)
+							 || compl_interrupted)
+		break;
+	    compl_started = TRUE;
+	}
+	else
+	{
+	    /* Mark a buffer scanned when it has been scanned completely */
+	    if (type == 0 || type == CTRL_X_PATH_PATTERNS)
+		ins_buf->b_scanned = TRUE;
+
+	    compl_started = FALSE;
+	}
+    }
+    compl_started = TRUE;
+
+    if ((ctrl_x_mode == 0 || ctrl_x_mode == CTRL_X_WHOLE_LINE)
+	    && *e_cpt == NUL)		/* Got to end of 'complete' */
+	found_new_match = FAIL;
+
+    i = -1;		/* total of matches, unknown */
+    if (found_new_match == FAIL
+	    || (ctrl_x_mode != 0 && ctrl_x_mode != CTRL_X_WHOLE_LINE))
+	i = ins_compl_make_cyclic();
+
+    /* If several matches were added (FORWARD) or the search failed and has
+     * just been made cyclic then we have to move compl_curr_match to the next
+     * or previous entry (if any) -- Acevedo */
+    compl_curr_match = compl_direction == FORWARD ? old_match->cp_next
+							 : old_match->cp_prev;
+    if (compl_curr_match == NULL)
+	compl_curr_match = old_match;
+    return i;
+}
+
+/* Delete the old text being completed. */
+    static void
+ins_compl_delete()
+{
+    int	    i;
+
+    /*
+     * In insert mode: Delete the typed part.
+     * In replace mode: Put the old characters back, if any.
+     */
+    i = compl_col + (compl_cont_status & CONT_ADDING ? compl_length : 0);
+    backspace_until_column(i);
+    changed_cline_bef_curs();
+}
+
+/* Insert the new text being completed. */
+    static void
+ins_compl_insert()
+{
+    ins_bytes(compl_shown_match->cp_str + curwin->w_cursor.col - compl_col);
+    if (compl_shown_match->cp_flags & ORIGINAL_TEXT)
+	compl_used_match = FALSE;
+    else
+	compl_used_match = TRUE;
+}
+
+/*
+ * Fill in the next completion in the current direction.
+ * If "allow_get_expansion" is TRUE, then we may call ins_compl_get_exp() to
+ * get more completions.  If it is FALSE, then we just do nothing when there
+ * are no more completions in a given direction.  The latter case is used when
+ * we are still in the middle of finding completions, to allow browsing
+ * through the ones found so far.
+ * Return the total number of matches, or -1 if still unknown -- webb.
+ *
+ * compl_curr_match is currently being used by ins_compl_get_exp(), so we use
+ * compl_shown_match here.
+ *
+ * Note that this function may be called recursively once only.  First with
+ * "allow_get_expansion" TRUE, which calls ins_compl_get_exp(), which in turn
+ * calls this function with "allow_get_expansion" FALSE.
+ */
+    static int
+ins_compl_next(allow_get_expansion, count, insert_match)
+    int	    allow_get_expansion;
+    int	    count;		/* repeat completion this many times; should
+				   be at least 1 */
+    int	    insert_match;	/* Insert the newly selected match */
+{
+    int	    num_matches = -1;
+    int	    i;
+    int	    todo = count;
+    compl_T *found_compl = NULL;
+    int	    found_end = FALSE;
+    int	    advance;
+
+    if (compl_leader != NULL
+			&& (compl_shown_match->cp_flags & ORIGINAL_TEXT) == 0)
+    {
+	/* Set "compl_shown_match" to the actually shown match, it may differ
+	 * when "compl_leader" is used to omit some of the matches. */
+	while (!ins_compl_equal(compl_shown_match,
+				      compl_leader, (int)STRLEN(compl_leader))
+		&& compl_shown_match->cp_next != NULL
+		&& compl_shown_match->cp_next != compl_first_match)
+	    compl_shown_match = compl_shown_match->cp_next;
+
+	/* If we didn't find it searching forward, and compl_shows_dir is
+	 * backward, find the last match. */
+	if (compl_shows_dir == BACKWARD
+		&& !ins_compl_equal(compl_shown_match,
+				      compl_leader, (int)STRLEN(compl_leader))
+		&& (compl_shown_match->cp_next == NULL
+		    || compl_shown_match->cp_next == compl_first_match))
+	{
+	    while (!ins_compl_equal(compl_shown_match,
+				      compl_leader, (int)STRLEN(compl_leader))
+		    && compl_shown_match->cp_prev != NULL
+		    && compl_shown_match->cp_prev != compl_first_match)
+		compl_shown_match = compl_shown_match->cp_prev;
+	}
+    }
+
+    if (allow_get_expansion && insert_match
+	    && (!(compl_get_longest || compl_restarting) || compl_used_match))
+	/* Delete old text to be replaced */
+	ins_compl_delete();
+
+    /* When finding the longest common text we stick at the original text,
+     * don't let CTRL-N or CTRL-P move to the first match. */
+    advance = count != 1 || !allow_get_expansion || !compl_get_longest;
+
+    /* When restarting the search don't insert the first match either. */
+    if (compl_restarting)
+    {
+	advance = FALSE;
+	compl_restarting = FALSE;
+    }
+
+    /* Repeat this for when <PageUp> or <PageDown> is typed.  But don't wrap
+     * around. */
+    while (--todo >= 0)
+    {
+	if (compl_shows_dir == FORWARD && compl_shown_match->cp_next != NULL)
+	{
+	    compl_shown_match = compl_shown_match->cp_next;
+	    found_end = (compl_first_match != NULL
+			   && (compl_shown_match->cp_next == compl_first_match
+			       || compl_shown_match == compl_first_match));
+	}
+	else if (compl_shows_dir == BACKWARD
+					&& compl_shown_match->cp_prev != NULL)
+	{
+	    found_end = (compl_shown_match == compl_first_match);
+	    compl_shown_match = compl_shown_match->cp_prev;
+	    found_end |= (compl_shown_match == compl_first_match);
+	}
+	else
+	{
+	    if (!allow_get_expansion)
+	    {
+		if (advance)
+		{
+		    if (compl_shows_dir == BACKWARD)
+			compl_pending -= todo + 1;
+		    else
+			compl_pending += todo + 1;
+		}
+		return -1;
+	    }
+
+	    if (advance)
+	    {
+		if (compl_shows_dir == BACKWARD)
+		    --compl_pending;
+		else
+		    ++compl_pending;
+	    }
+
+	    /* Find matches. */
+	    num_matches = ins_compl_get_exp(&compl_startpos);
+
+	    /* handle any pending completions */
+	    while (compl_pending != 0 && compl_direction == compl_shows_dir
+								   && advance)
+	    {
+		if (compl_pending > 0 && compl_shown_match->cp_next != NULL)
+		{
+		    compl_shown_match = compl_shown_match->cp_next;
+		    --compl_pending;
+		}
+		if (compl_pending < 0 && compl_shown_match->cp_prev != NULL)
+		{
+		    compl_shown_match = compl_shown_match->cp_prev;
+		    ++compl_pending;
+		}
+		else
+		    break;
+	    }
+	    found_end = FALSE;
+	}
+	if ((compl_shown_match->cp_flags & ORIGINAL_TEXT) == 0
+		&& compl_leader != NULL
+		&& !ins_compl_equal(compl_shown_match,
+				     compl_leader, (int)STRLEN(compl_leader)))
+	    ++todo;
+	else
+	    /* Remember a matching item. */
+	    found_compl = compl_shown_match;
+
+	/* Stop at the end of the list when we found a usable match. */
+	if (found_end)
+	{
+	    if (found_compl != NULL)
+	    {
+		compl_shown_match = found_compl;
+		break;
+	    }
+	    todo = 1;	    /* use first usable match after wrapping around */
+	}
+    }
+
+    /* Insert the text of the new completion, or the compl_leader. */
+    if (insert_match)
+    {
+	if (!compl_get_longest || compl_used_match)
+	    ins_compl_insert();
+	else
+	    ins_bytes(compl_leader + curwin->w_cursor.col - compl_col);
+    }
+    else
+	compl_used_match = FALSE;
+
+    if (!allow_get_expansion)
+    {
+	/* may undisplay the popup menu first */
+	ins_compl_upd_pum();
+
+	/* redraw to show the user what was inserted */
+	update_screen(0);
+
+	/* display the updated popup menu */
+	ins_compl_show_pum();
+#ifdef FEAT_GUI
+	if (gui.in_use)
+	{
+	    /* Show the cursor after the match, not after the redrawn text. */
+	    setcursor();
+	    out_flush();
+	    gui_update_cursor(FALSE, FALSE);
+	}
+#endif
+
+	/* Delete old text to be replaced, since we're still searching and
+	 * don't want to match ourselves!  */
+	ins_compl_delete();
+    }
+
+    /* Enter will select a match when the match wasn't inserted and the popup
+     * menu is visible. */
+    compl_enter_selects = !insert_match && compl_match_array != NULL;
+
+    /*
+     * Show the file name for the match (if any)
+     * Truncate the file name to avoid a wait for return.
+     */
+    if (compl_shown_match->cp_fname != NULL)
+    {
+	STRCPY(IObuff, "match in file ");
+	i = (vim_strsize(compl_shown_match->cp_fname) + 16) - sc_col;
+	if (i <= 0)
+	    i = 0;
+	else
+	    STRCAT(IObuff, "<");
+	STRCAT(IObuff, compl_shown_match->cp_fname + i);
+	msg(IObuff);
+	redraw_cmdline = FALSE;	    /* don't overwrite! */
+    }
+
+    return num_matches;
+}
+
+/*
+ * Call this while finding completions, to check whether the user has hit a key
+ * that should change the currently displayed completion, or exit completion
+ * mode.  Also, when compl_pending is not zero, show a completion as soon as
+ * possible. -- webb
+ * "frequency" specifies out of how many calls we actually check.
+ */
+    void
+ins_compl_check_keys(frequency)
+    int		frequency;
+{
+    static int	count = 0;
+
+    int	    c;
+
+    /* Don't check when reading keys from a script.  That would break the test
+     * scripts */
+    if (using_script())
+	return;
+
+    /* Only do this at regular intervals */
+    if (++count < frequency)
+	return;
+    count = 0;
+
+    /* Check for a typed key.  Do use mappings, otherwise vim_is_ctrl_x_key()
+     * can't do its work correctly. */
+    c = vpeekc_any();
+    if (c != NUL)
+    {
+	if (vim_is_ctrl_x_key(c) && c != Ctrl_X && c != Ctrl_R)
+	{
+	    c = safe_vgetc();	/* Eat the character */
+	    compl_shows_dir = ins_compl_key2dir(c);
+	    (void)ins_compl_next(FALSE, ins_compl_key2count(c),
+						    c != K_UP && c != K_DOWN);
+	}
+	else
+	{
+	    /* Need to get the character to have KeyTyped set.  We'll put it
+	     * back with vungetc() below. */
+	    c = safe_vgetc();
+
+	    /* Don't interrupt completion when the character wasn't typed,
+	     * e.g., when doing @q to replay keys. */
+	    if (c != Ctrl_R && KeyTyped)
+		compl_interrupted = TRUE;
+
+	    vungetc(c);
+	}
+    }
+    if (compl_pending != 0 && !got_int)
+    {
+	int todo = compl_pending > 0 ? compl_pending : -compl_pending;
+
+	compl_pending = 0;
+	(void)ins_compl_next(FALSE, todo, TRUE);
+    }
+}
+
+/*
+ * Decide the direction of Insert mode complete from the key typed.
+ * Returns BACKWARD or FORWARD.
+ */
+    static int
+ins_compl_key2dir(c)
+    int		c;
+{
+    if (c == Ctrl_P || c == Ctrl_L
+	    || (pum_visible() && (c == K_PAGEUP || c == K_KPAGEUP
+						|| c == K_S_UP || c == K_UP)))
+	return BACKWARD;
+    return FORWARD;
+}
+
+/*
+ * Return TRUE for keys that are used for completion only when the popup menu
+ * is visible.
+ */
+    static int
+ins_compl_pum_key(c)
+    int		c;
+{
+    return pum_visible() && (c == K_PAGEUP || c == K_KPAGEUP || c == K_S_UP
+		     || c == K_PAGEDOWN || c == K_KPAGEDOWN || c == K_S_DOWN
+		     || c == K_UP || c == K_DOWN);
+}
+
+/*
+ * Decide the number of completions to move forward.
+ * Returns 1 for most keys, height of the popup menu for page-up/down keys.
+ */
+    static int
+ins_compl_key2count(c)
+    int		c;
+{
+    int		h;
+
+    if (ins_compl_pum_key(c) && c != K_UP && c != K_DOWN)
+    {
+	h = pum_get_height();
+	if (h > 3)
+	    h -= 2; /* keep some context */
+	return h;
+    }
+    return 1;
+}
+
+/*
+ * Return TRUE if completion with "c" should insert the match, FALSE if only
+ * to change the currently selected completion.
+ */
+    static int
+ins_compl_use_match(c)
+    int		c;
+{
+    switch (c)
+    {
+	case K_UP:
+	case K_DOWN:
+	case K_PAGEDOWN:
+	case K_KPAGEDOWN:
+	case K_S_DOWN:
+	case K_PAGEUP:
+	case K_KPAGEUP:
+	case K_S_UP:
+	    return FALSE;
+    }
+    return TRUE;
+}
+
+/*
+ * Do Insert mode completion.
+ * Called when character "c" was typed, which has a meaning for completion.
+ * Returns OK if completion was done, FAIL if something failed (out of mem).
+ */
+    static int
+ins_complete(c)
+    int		c;
+{
+    char_u	*line;
+    int		startcol = 0;	    /* column where searched text starts */
+    colnr_T	curs_col;	    /* cursor column */
+    int		n;
+
+    compl_direction = ins_compl_key2dir(c);
+    if (!compl_started)
+    {
+	/* First time we hit ^N or ^P (in a row, I mean) */
+
+	did_ai = FALSE;
+#ifdef FEAT_SMARTINDENT
+	did_si = FALSE;
+	can_si = FALSE;
+	can_si_back = FALSE;
+#endif
+	if (stop_arrow() == FAIL)
+	    return FAIL;
+
+	line = ml_get(curwin->w_cursor.lnum);
+	curs_col = curwin->w_cursor.col;
+	compl_pending = 0;
+
+	/* if this same ctrl_x_mode has been interrupted use the text from
+	 * "compl_startpos" to the cursor as a pattern to add a new word
+	 * instead of expand the one before the cursor, in word-wise if
+	 * "compl_startpos"
+	 * is not in the same line as the cursor then fix it (the line has
+	 * been split because it was longer than 'tw').  if SOL is set then
+	 * skip the previous pattern, a word at the beginning of the line has
+	 * been inserted, we'll look for that  -- Acevedo. */
+	if ((compl_cont_status & CONT_INTRPT) == CONT_INTRPT
+					    && compl_cont_mode == ctrl_x_mode)
+	{
+	    /*
+	     * it is a continued search
+	     */
+	    compl_cont_status &= ~CONT_INTRPT;	/* remove INTRPT */
+	    if (ctrl_x_mode == 0 || ctrl_x_mode == CTRL_X_PATH_PATTERNS
+					|| ctrl_x_mode == CTRL_X_PATH_DEFINES)
+	    {
+		if (compl_startpos.lnum != curwin->w_cursor.lnum)
+		{
+		    /* line (probably) wrapped, set compl_startpos to the
+		     * first non_blank in the line, if it is not a wordchar
+		     * include it to get a better pattern, but then we don't
+		     * want the "\\<" prefix, check it bellow */
+		    compl_col = (colnr_T)(skipwhite(line) - line);
+		    compl_startpos.col = compl_col;
+		    compl_startpos.lnum = curwin->w_cursor.lnum;
+		    compl_cont_status &= ~CONT_SOL;   /* clear SOL if present */
+		}
+		else
+		{
+		    /* S_IPOS was set when we inserted a word that was at the
+		     * beginning of the line, which means that we'll go to SOL
+		     * mode but first we need to redefine compl_startpos */
+		    if (compl_cont_status & CONT_S_IPOS)
+		    {
+			compl_cont_status |= CONT_SOL;
+			compl_startpos.col = (colnr_T)(skipwhite(
+						line + compl_length
+						+ compl_startpos.col) - line);
+		    }
+		    compl_col = compl_startpos.col;
+		}
+		compl_length = curwin->w_cursor.col - (int)compl_col;
+		/* IObuff is used to add a "word from the next line" would we
+		 * have enough space?  just being paranoic */
+#define	MIN_SPACE 75
+		if (compl_length > (IOSIZE - MIN_SPACE))
+		{
+		    compl_cont_status &= ~CONT_SOL;
+		    compl_length = (IOSIZE - MIN_SPACE);
+		    compl_col = curwin->w_cursor.col - compl_length;
+		}
+		compl_cont_status |= CONT_ADDING | CONT_N_ADDS;
+		if (compl_length < 1)
+		    compl_cont_status &= CONT_LOCAL;
+	    }
+	    else if (ctrl_x_mode == CTRL_X_WHOLE_LINE)
+		compl_cont_status = CONT_ADDING | CONT_N_ADDS;
+	    else
+		compl_cont_status = 0;
+	}
+	else
+	    compl_cont_status &= CONT_LOCAL;
+
+	if (!(compl_cont_status & CONT_ADDING))	/* normal expansion */
+	{
+	    compl_cont_mode = ctrl_x_mode;
+	    if (ctrl_x_mode != 0)	/* Remove LOCAL if ctrl_x_mode != 0 */
+		compl_cont_status = 0;
+	    compl_cont_status |= CONT_N_ADDS;
+	    compl_startpos = curwin->w_cursor;
+	    startcol = (int)curs_col;
+	    compl_col = 0;
+	}
+
+	/* Work out completion pattern and original text -- webb */
+	if (ctrl_x_mode == 0 || (ctrl_x_mode & CTRL_X_WANT_IDENT))
+	{
+	    if ((compl_cont_status & CONT_SOL)
+		    || ctrl_x_mode == CTRL_X_PATH_DEFINES)
+	    {
+		if (!(compl_cont_status & CONT_ADDING))
+		{
+		    while (--startcol >= 0 && vim_isIDc(line[startcol]))
+			;
+		    compl_col += ++startcol;
+		    compl_length = curs_col - startcol;
+		}
+		if (p_ic)
+		    compl_pattern = str_foldcase(line + compl_col,
+						       compl_length, NULL, 0);
+		else
+		    compl_pattern = vim_strnsave(line + compl_col,
+								compl_length);
+		if (compl_pattern == NULL)
+		    return FAIL;
+	    }
+	    else if (compl_cont_status & CONT_ADDING)
+	    {
+		char_u	    *prefix = (char_u *)"\\<";
+
+		/* we need 3 extra chars, 1 for the NUL and
+		 * 2 >= strlen(prefix)	-- Acevedo */
+		compl_pattern = alloc(quote_meta(NULL, line + compl_col,
+							   compl_length) + 3);
+		if (compl_pattern == NULL)
+		    return FAIL;
+		if (!vim_iswordp(line + compl_col)
+			|| (compl_col > 0
+			    && (
+#ifdef FEAT_MBYTE
+				vim_iswordp(mb_prevptr(line, line + compl_col))
+#else
+				vim_iswordc(line[compl_col - 1])
+#endif
+				)))
+		    prefix = (char_u *)"";
+		STRCPY((char *)compl_pattern, prefix);
+		(void)quote_meta(compl_pattern + STRLEN(prefix),
+					      line + compl_col, compl_length);
+	    }
+	    else if (--startcol < 0 ||
+#ifdef FEAT_MBYTE
+			   !vim_iswordp(mb_prevptr(line, line + startcol + 1))
+#else
+			   !vim_iswordc(line[startcol])
+#endif
+		    )
+	    {
+		/* Match any word of at least two chars */
+		compl_pattern = vim_strsave((char_u *)"\\<\\k\\k");
+		if (compl_pattern == NULL)
+		    return FAIL;
+		compl_col += curs_col;
+		compl_length = 0;
+	    }
+	    else
+	    {
+#ifdef FEAT_MBYTE
+		/* Search the point of change class of multibyte character
+		 * or not a word single byte character backward.  */
+		if (has_mbyte)
+		{
+		    int base_class;
+		    int head_off;
+
+		    startcol -= (*mb_head_off)(line, line + startcol);
+		    base_class = mb_get_class(line + startcol);
+		    while (--startcol >= 0)
+		    {
+			head_off = (*mb_head_off)(line, line + startcol);
+			if (base_class != mb_get_class(line + startcol
+								  - head_off))
+			    break;
+			startcol -= head_off;
+		    }
+		}
+		else
+#endif
+		    while (--startcol >= 0 && vim_iswordc(line[startcol]))
+			;
+		compl_col += ++startcol;
+		compl_length = (int)curs_col - startcol;
+		if (compl_length == 1)
+		{
+		    /* Only match word with at least two chars -- webb
+		     * there's no need to call quote_meta,
+		     * alloc(7) is enough  -- Acevedo
+		     */
+		    compl_pattern = alloc(7);
+		    if (compl_pattern == NULL)
+			return FAIL;
+		    STRCPY((char *)compl_pattern, "\\<");
+		    (void)quote_meta(compl_pattern + 2, line + compl_col, 1);
+		    STRCAT((char *)compl_pattern, "\\k");
+		}
+		else
+		{
+		    compl_pattern = alloc(quote_meta(NULL, line + compl_col,
+							   compl_length) + 3);
+		    if (compl_pattern == NULL)
+			return FAIL;
+		    STRCPY((char *)compl_pattern, "\\<");
+		    (void)quote_meta(compl_pattern + 2, line + compl_col,
+								compl_length);
+		}
+	    }
+	}
+	else if (ctrl_x_mode == CTRL_X_WHOLE_LINE)
+	{
+	    compl_col = (colnr_T)(skipwhite(line) - line);
+	    compl_length = (int)curs_col - (int)compl_col;
+	    if (compl_length < 0)	/* cursor in indent: empty pattern */
+		compl_length = 0;
+	    if (p_ic)
+		compl_pattern = str_foldcase(line + compl_col, compl_length,
+								     NULL, 0);
+	    else
+		compl_pattern = vim_strnsave(line + compl_col, compl_length);
+	    if (compl_pattern == NULL)
+		return FAIL;
+	}
+	else if (ctrl_x_mode == CTRL_X_FILES)
+	{
+	    while (--startcol >= 0 && vim_isfilec(line[startcol]))
+		;
+	    compl_col += ++startcol;
+	    compl_length = (int)curs_col - startcol;
+	    compl_pattern = addstar(line + compl_col, compl_length,
+								EXPAND_FILES);
+	    if (compl_pattern == NULL)
+		return FAIL;
+	}
+	else if (ctrl_x_mode == CTRL_X_CMDLINE)
+	{
+	    compl_pattern = vim_strnsave(line, curs_col);
+	    if (compl_pattern == NULL)
+		return FAIL;
+	    set_cmd_context(&compl_xp, compl_pattern,
+				     (int)STRLEN(compl_pattern), curs_col);
+	    if (compl_xp.xp_context == EXPAND_UNSUCCESSFUL
+		    || compl_xp.xp_context == EXPAND_NOTHING)
+		/* No completion possible, use an empty pattern to get a
+		 * "pattern not found" message. */
+		compl_col = curs_col;
+	    else
+		compl_col = (int)(compl_xp.xp_pattern - compl_pattern);
+	    compl_length = curs_col - compl_col;
+	}
+	else if (ctrl_x_mode == CTRL_X_FUNCTION || ctrl_x_mode == CTRL_X_OMNI)
+	{
+#ifdef FEAT_COMPL_FUNC
+	    /*
+	     * Call user defined function 'completefunc' with "a:findstart"
+	     * set to 1 to obtain the length of text to use for completion.
+	     */
+	    char_u	*args[2];
+	    int		col;
+	    char_u	*funcname;
+	    pos_T	pos;
+
+	    /* Call 'completefunc' or 'omnifunc' and get pattern length as a
+	     * string */
+	    funcname = ctrl_x_mode == CTRL_X_FUNCTION
+					  ? curbuf->b_p_cfu : curbuf->b_p_ofu;
+	    if (*funcname == NUL)
+	    {
+		EMSG2(_(e_notset), ctrl_x_mode == CTRL_X_FUNCTION
+					     ? "completefunc" : "omnifunc");
+		return FAIL;
+	    }
+
+	    args[0] = (char_u *)"1";
+	    args[1] = NULL;
+	    pos = curwin->w_cursor;
+	    col = call_func_retnr(funcname, 2, args, FALSE);
+	    curwin->w_cursor = pos;	/* restore the cursor position */
+
+	    if (col < 0)
+		col = curs_col;
+	    compl_col = col;
+	    if ((colnr_T)compl_col > curs_col)
+		compl_col = curs_col;
+
+	    /* Setup variables for completion.  Need to obtain "line" again,
+	     * it may have become invalid. */
+	    line = ml_get(curwin->w_cursor.lnum);
+	    compl_length = curs_col - compl_col;
+	    compl_pattern = vim_strnsave(line + compl_col, compl_length);
+	    if (compl_pattern == NULL)
+#endif
+		return FAIL;
+	}
+	else if (ctrl_x_mode == CTRL_X_SPELL)
+	{
+#ifdef FEAT_SPELL
+	    if (spell_bad_len > 0)
+		compl_col = curs_col - spell_bad_len;
+	    else
+		compl_col = spell_word_start(startcol);
+	    if (compl_col >= (colnr_T)startcol)
+	    {
+		compl_length = 0;
+		compl_col = curs_col;
+	    }
+	    else
+	    {
+		spell_expand_check_cap(compl_col);
+		compl_length = (int)curs_col - compl_col;
+	    }
+	    /* Need to obtain "line" again, it may have become invalid. */
+	    line = ml_get(curwin->w_cursor.lnum);
+	    compl_pattern = vim_strnsave(line + compl_col, compl_length);
+	    if (compl_pattern == NULL)
+#endif
+		return FAIL;
+	}
+	else
+	{
+	    EMSG2(_(e_intern2), "ins_complete()");
+	    return FAIL;
+	}
+
+	if (compl_cont_status & CONT_ADDING)
+	{
+	    edit_submode_pre = (char_u *)_(" Adding");
+	    if (ctrl_x_mode == CTRL_X_WHOLE_LINE)
+	    {
+		/* Insert a new line, keep indentation but ignore 'comments' */
+#ifdef FEAT_COMMENTS
+		char_u *old = curbuf->b_p_com;
+
+		curbuf->b_p_com = (char_u *)"";
+#endif
+		compl_startpos.lnum = curwin->w_cursor.lnum;
+		compl_startpos.col = compl_col;
+		ins_eol('\r');
+#ifdef FEAT_COMMENTS
+		curbuf->b_p_com = old;
+#endif
+		compl_length = 0;
+		compl_col = curwin->w_cursor.col;
+	    }
+	}
+	else
+	{
+	    edit_submode_pre = NULL;
+	    compl_startpos.col = compl_col;
+	}
+
+	if (compl_cont_status & CONT_LOCAL)
+	    edit_submode = (char_u *)_(ctrl_x_msgs[CTRL_X_LOCAL_MSG]);
+	else
+	    edit_submode = (char_u *)_(CTRL_X_MSG(ctrl_x_mode));
+
+	/* Always add completion for the original text. */
+	vim_free(compl_orig_text);
+	compl_orig_text = vim_strnsave(line + compl_col, compl_length);
+	if (compl_orig_text == NULL || ins_compl_add(compl_orig_text,
+			-1, p_ic, NULL, NULL, 0, ORIGINAL_TEXT, FALSE) != OK)
+	{
+	    vim_free(compl_pattern);
+	    compl_pattern = NULL;
+	    vim_free(compl_orig_text);
+	    compl_orig_text = NULL;
+	    return FAIL;
+	}
+
+	/* showmode might reset the internal line pointers, so it must
+	 * be called before line = ml_get(), or when this address is no
+	 * longer needed.  -- Acevedo.
+	 */
+	edit_submode_extra = (char_u *)_("-- Searching...");
+	edit_submode_highl = HLF_COUNT;
+	showmode();
+	edit_submode_extra = NULL;
+	out_flush();
+    }
+
+    compl_shown_match = compl_curr_match;
+    compl_shows_dir = compl_direction;
+
+    /*
+     * Find next match (and following matches).
+     */
+    n = ins_compl_next(TRUE, ins_compl_key2count(c), ins_compl_use_match(c));
+
+    /* may undisplay the popup menu */
+    ins_compl_upd_pum();
+
+    if (n > 1)		/* all matches have been found */
+	compl_matches = n;
+    compl_curr_match = compl_shown_match;
+    compl_direction = compl_shows_dir;
+
+    /* Eat the ESC that vgetc() returns after a CTRL-C to avoid leaving Insert
+     * mode. */
+    if (got_int && !global_busy)
+    {
+	(void)vgetc();
+	got_int = FALSE;
+    }
+
+    /* we found no match if the list has only the "compl_orig_text"-entry */
+    if (compl_first_match == compl_first_match->cp_next)
+    {
+	edit_submode_extra = (compl_cont_status & CONT_ADDING)
+			&& compl_length > 1
+			     ? (char_u *)_(e_hitend) : (char_u *)_(e_patnotf);
+	edit_submode_highl = HLF_E;
+	/* remove N_ADDS flag, so next ^X<> won't try to go to ADDING mode,
+	 * because we couldn't expand anything at first place, but if we used
+	 * ^P, ^N, ^X^I or ^X^D we might want to add-expand a single-char-word
+	 * (such as M in M'exico) if not tried already.  -- Acevedo */
+	if (	   compl_length > 1
+		|| (compl_cont_status & CONT_ADDING)
+		|| (ctrl_x_mode != 0
+		    && ctrl_x_mode != CTRL_X_PATH_PATTERNS
+		    && ctrl_x_mode != CTRL_X_PATH_DEFINES))
+	    compl_cont_status &= ~CONT_N_ADDS;
+    }
+
+    if (compl_curr_match->cp_flags & CONT_S_IPOS)
+	compl_cont_status |= CONT_S_IPOS;
+    else
+	compl_cont_status &= ~CONT_S_IPOS;
+
+    if (edit_submode_extra == NULL)
+    {
+	if (compl_curr_match->cp_flags & ORIGINAL_TEXT)
+	{
+	    edit_submode_extra = (char_u *)_("Back at original");
+	    edit_submode_highl = HLF_W;
+	}
+	else if (compl_cont_status & CONT_S_IPOS)
+	{
+	    edit_submode_extra = (char_u *)_("Word from other line");
+	    edit_submode_highl = HLF_COUNT;
+	}
+	else if (compl_curr_match->cp_next == compl_curr_match->cp_prev)
+	{
+	    edit_submode_extra = (char_u *)_("The only match");
+	    edit_submode_highl = HLF_COUNT;
+	}
+	else
+	{
+	    /* Update completion sequence number when needed. */
+	    if (compl_curr_match->cp_number == -1)
+	    {
+		int		number = 0;
+		compl_T		*match;
+
+		if (compl_direction == FORWARD)
+		{
+		    /* search backwards for the first valid (!= -1) number.
+		     * This should normally succeed already at the first loop
+		     * cycle, so it's fast! */
+		    for (match = compl_curr_match->cp_prev; match != NULL
+			    && match != compl_first_match;
+						       match = match->cp_prev)
+			if (match->cp_number != -1)
+			{
+			    number = match->cp_number;
+			    break;
+			}
+		    if (match != NULL)
+			/* go up and assign all numbers which are not assigned
+			 * yet */
+			for (match = match->cp_next;
+				match != NULL && match->cp_number == -1;
+						       match = match->cp_next)
+			    match->cp_number = ++number;
+		}
+		else /* BACKWARD */
+		{
+		    /* search forwards (upwards) for the first valid (!= -1)
+		     * number.  This should normally succeed already at the
+		     * first loop cycle, so it's fast! */
+		    for (match = compl_curr_match->cp_next; match != NULL
+			    && match != compl_first_match;
+						       match = match->cp_next)
+			if (match->cp_number != -1)
+			{
+			    number = match->cp_number;
+			    break;
+			}
+		    if (match != NULL)
+			/* go down and assign all numbers which are not
+			 * assigned yet */
+			for (match = match->cp_prev; match
+				&& match->cp_number == -1;
+						       match = match->cp_prev)
+			    match->cp_number = ++number;
+		}
+	    }
+
+	    /* The match should always have a sequence number now, this is
+	     * just a safety check. */
+	    if (compl_curr_match->cp_number != -1)
+	    {
+		/* Space for 10 text chars. + 2x10-digit no.s = 31.
+		 * Translations may need more than twice that. */
+		static char_u match_ref[81];
+
+		if (compl_matches > 0)
+		    vim_snprintf((char *)match_ref, sizeof(match_ref),
+				_("match %d of %d"),
+				compl_curr_match->cp_number, compl_matches);
+		else
+		    vim_snprintf((char *)match_ref, sizeof(match_ref),
+				_("match %d"),
+				compl_curr_match->cp_number);
+		edit_submode_extra = match_ref;
+		edit_submode_highl = HLF_R;
+		if (dollar_vcol)
+		    curs_columns(FALSE);
+	    }
+	}
+    }
+
+    /* Show a message about what (completion) mode we're in. */
+    showmode();
+    if (edit_submode_extra != NULL)
+    {
+	if (!p_smd)
+	    msg_attr(edit_submode_extra,
+		    edit_submode_highl < HLF_COUNT
+		    ? hl_attr(edit_submode_highl) : 0);
+    }
+    else
+	msg_clr_cmdline();	/* necessary for "noshowmode" */
+
+    /* Show the popup menu, unless we got interrupted. */
+    if (!compl_interrupted)
+    {
+	/* RedrawingDisabled may be set when invoked through complete(). */
+	n = RedrawingDisabled;
+	RedrawingDisabled = 0;
+	ins_compl_show_pum();
+	setcursor();
+	RedrawingDisabled = n;
+    }
+    compl_was_interrupted = compl_interrupted;
+    compl_interrupted = FALSE;
+
+    return OK;
+}
+
+/*
+ * Looks in the first "len" chars. of "src" for search-metachars.
+ * If dest is not NULL the chars. are copied there quoting (with
+ * a backslash) the metachars, and dest would be NUL terminated.
+ * Returns the length (needed) of dest
+ */
+    static int
+quote_meta(dest, src, len)
+    char_u	*dest;
+    char_u	*src;
+    int		len;
+{
+    int	m;
+
+    for (m = len; --len >= 0; src++)
+    {
+	switch (*src)
+	{
+	    case '.':
+	    case '*':
+	    case '[':
+		if (ctrl_x_mode == CTRL_X_DICTIONARY
+					   || ctrl_x_mode == CTRL_X_THESAURUS)
+		    break;
+	    case '~':
+		if (!p_magic)	/* quote these only if magic is set */
+		    break;
+	    case '\\':
+		if (ctrl_x_mode == CTRL_X_DICTIONARY
+					   || ctrl_x_mode == CTRL_X_THESAURUS)
+		    break;
+	    case '^':		/* currently it's not needed. */
+	    case '$':
+		m++;
+		if (dest != NULL)
+		    *dest++ = '\\';
+		break;
+	}
+	if (dest != NULL)
+	    *dest++ = *src;
+# ifdef FEAT_MBYTE
+	/* Copy remaining bytes of a multibyte character. */
+	if (has_mbyte)
+	{
+	    int i, mb_len;
+
+	    mb_len = (*mb_ptr2len)(src) - 1;
+	    if (mb_len > 0 && len >= mb_len)
+		for (i = 0; i < mb_len; ++i)
+		{
+		    --len;
+		    ++src;
+		    if (dest != NULL)
+			*dest++ = *src;
+		}
+	}
+# endif
+    }
+    if (dest != NULL)
+	*dest = NUL;
+
+    return m;
+}
+#endif /* FEAT_INS_EXPAND */
+
+/*
+ * Next character is interpreted literally.
+ * A one, two or three digit decimal number is interpreted as its byte value.
+ * If one or two digits are entered, the next character is given to vungetc().
+ * For Unicode a character > 255 may be returned.
+ */
+    int
+get_literal()
+{
+    int		cc;
+    int		nc;
+    int		i;
+    int		hex = FALSE;
+    int		octal = FALSE;
+#ifdef FEAT_MBYTE
+    int		unicode = 0;
+#endif
+
+    if (got_int)
+	return Ctrl_C;
+
+#ifdef FEAT_GUI
+    /*
+     * In GUI there is no point inserting the internal code for a special key.
+     * It is more useful to insert the string "<KEY>" instead.	This would
+     * probably be useful in a text window too, but it would not be
+     * vi-compatible (maybe there should be an option for it?) -- webb
+     */
+    if (gui.in_use)
+	++allow_keys;
+#endif
+#ifdef USE_ON_FLY_SCROLL
+    dont_scroll = TRUE;		/* disallow scrolling here */
+#endif
+    ++no_mapping;		/* don't map the next key hits */
+    cc = 0;
+    i = 0;
+    for (;;)
+    {
+	do
+	    nc = safe_vgetc();
+	while (nc == K_IGNORE || nc == K_VER_SCROLLBAR
+						    || nc == K_HOR_SCROLLBAR);
+#ifdef FEAT_CMDL_INFO
+	if (!(State & CMDLINE)
+# ifdef FEAT_MBYTE
+		&& MB_BYTE2LEN_CHECK(nc) == 1
+# endif
+	   )
+	    add_to_showcmd(nc);
+#endif
+	if (nc == 'x' || nc == 'X')
+	    hex = TRUE;
+	else if (nc == 'o' || nc == 'O')
+	    octal = TRUE;
+#ifdef FEAT_MBYTE
+	else if (nc == 'u' || nc == 'U')
+	    unicode = nc;
+#endif
+	else
+	{
+	    if (hex
+#ifdef FEAT_MBYTE
+		    || unicode != 0
+#endif
+		    )
+	    {
+		if (!vim_isxdigit(nc))
+		    break;
+		cc = cc * 16 + hex2nr(nc);
+	    }
+	    else if (octal)
+	    {
+		if (nc < '0' || nc > '7')
+		    break;
+		cc = cc * 8 + nc - '0';
+	    }
+	    else
+	    {
+		if (!VIM_ISDIGIT(nc))
+		    break;
+		cc = cc * 10 + nc - '0';
+	    }
+
+	    ++i;
+	}
+
+	if (cc > 255
+#ifdef FEAT_MBYTE
+		&& unicode == 0
+#endif
+		)
+	    cc = 255;		/* limit range to 0-255 */
+	nc = 0;
+
+	if (hex)		/* hex: up to two chars */
+	{
+	    if (i >= 2)
+		break;
+	}
+#ifdef FEAT_MBYTE
+	else if (unicode)	/* Unicode: up to four or eight chars */
+	{
+	    if ((unicode == 'u' && i >= 4) || (unicode == 'U' && i >= 8))
+		break;
+	}
+#endif
+	else if (i >= 3)	/* decimal or octal: up to three chars */
+	    break;
+    }
+    if (i == 0)	    /* no number entered */
+    {
+	if (nc == K_ZERO)   /* NUL is stored as NL */
+	{
+	    cc = '\n';
+	    nc = 0;
+	}
+	else
+	{
+	    cc = nc;
+	    nc = 0;
+	}
+    }
+
+    if (cc == 0)	/* NUL is stored as NL */
+	cc = '\n';
+#ifdef FEAT_MBYTE
+    if (enc_dbcs && (cc & 0xff) == 0)
+	cc = '?';	/* don't accept an illegal DBCS char, the NUL in the
+			   second byte will cause trouble! */
+#endif
+
+    --no_mapping;
+#ifdef FEAT_GUI
+    if (gui.in_use)
+	--allow_keys;
+#endif
+    if (nc)
+	vungetc(nc);
+    got_int = FALSE;	    /* CTRL-C typed after CTRL-V is not an interrupt */
+    return cc;
+}
+
+/*
+ * Insert character, taking care of special keys and mod_mask
+ */
+    static void
+insert_special(c, allow_modmask, ctrlv)
+    int	    c;
+    int	    allow_modmask;
+    int	    ctrlv;	    /* c was typed after CTRL-V */
+{
+    char_u  *p;
+    int	    len;
+
+    /*
+     * Special function key, translate into "<Key>". Up to the last '>' is
+     * inserted with ins_str(), so as not to replace characters in replace
+     * mode.
+     * Only use mod_mask for special keys, to avoid things like <S-Space>,
+     * unless 'allow_modmask' is TRUE.
+     */
+#ifdef MACOS
+    /* Command-key never produces a normal key */
+    if (mod_mask & MOD_MASK_CMD)
+	allow_modmask = TRUE;
+#endif
+    if (IS_SPECIAL(c) || (mod_mask && allow_modmask))
+    {
+	p = get_special_key_name(c, mod_mask);
+	len = (int)STRLEN(p);
+	c = p[len - 1];
+	if (len > 2)
+	{
+	    if (stop_arrow() == FAIL)
+		return;
+	    p[len - 1] = NUL;
+	    ins_str(p);
+	    AppendToRedobuffLit(p, -1);
+	    ctrlv = FALSE;
+	}
+    }
+    if (stop_arrow() == OK)
+	insertchar(c, ctrlv ? INSCHAR_CTRLV : 0, -1);
+}
+
+/*
+ * Special characters in this context are those that need processing other
+ * than the simple insertion that can be performed here. This includes ESC
+ * which terminates the insert, and CR/NL which need special processing to
+ * open up a new line. This routine tries to optimize insertions performed by
+ * the "redo", "undo" or "put" commands, so it needs to know when it should
+ * stop and defer processing to the "normal" mechanism.
+ * '0' and '^' are special, because they can be followed by CTRL-D.
+ */
+#ifdef EBCDIC
+# define ISSPECIAL(c)	((c) < ' ' || (c) == '0' || (c) == '^')
+#else
+# define ISSPECIAL(c)	((c) < ' ' || (c) >= DEL || (c) == '0' || (c) == '^')
+#endif
+
+#ifdef FEAT_MBYTE
+# define WHITECHAR(cc) (vim_iswhite(cc) && (!enc_utf8 || !utf_iscomposing(utf_ptr2char(ml_get_cursor() + 1))))
+#else
+# define WHITECHAR(cc) vim_iswhite(cc)
+#endif
+
+    void
+insertchar(c, flags, second_indent)
+    int		c;			/* character to insert or NUL */
+    int		flags;			/* INSCHAR_FORMAT, etc. */
+    int		second_indent;		/* indent for second line if >= 0 */
+{
+    int		textwidth;
+#ifdef FEAT_COMMENTS
+    char_u	*p;
+#endif
+    int		fo_ins_blank;
+
+    textwidth = comp_textwidth(flags & INSCHAR_FORMAT);
+    fo_ins_blank = has_format_option(FO_INS_BLANK);
+
+    /*
+     * Try to break the line in two or more pieces when:
+     * - Always do this if we have been called to do formatting only.
+     * - Always do this when 'formatoptions' has the 'a' flag and the line
+     *   ends in white space.
+     * - Otherwise:
+     *	 - Don't do this if inserting a blank
+     *	 - Don't do this if an existing character is being replaced, unless
+     *	   we're in VREPLACE mode.
+     *	 - Do this if the cursor is not on the line where insert started
+     *	 or - 'formatoptions' doesn't have 'l' or the line was not too long
+     *	       before the insert.
+     *	    - 'formatoptions' doesn't have 'b' or a blank was inserted at or
+     *	      before 'textwidth'
+     */
+    if (textwidth > 0
+	    && ((flags & INSCHAR_FORMAT)
+		|| (!vim_iswhite(c)
+		    && !((State & REPLACE_FLAG)
+#ifdef FEAT_VREPLACE
+			&& !(State & VREPLACE_FLAG)
+#endif
+			&& *ml_get_cursor() != NUL)
+		    && (curwin->w_cursor.lnum != Insstart.lnum
+			|| ((!has_format_option(FO_INS_LONG)
+				|| Insstart_textlen <= (colnr_T)textwidth)
+			    && (!fo_ins_blank
+				|| Insstart_blank_vcol <= (colnr_T)textwidth
+			    ))))))
+    {
+	/* Format with 'formatexpr' when it's set.  Use internal formatting
+	 * when 'formatexpr' isn't set or it returns non-zero. */
+#if defined(FEAT_EVAL)
+	int do_internal = TRUE;
+
+	if (*curbuf->b_p_fex != NUL)
+	{
+	    do_internal = (fex_format(curwin->w_cursor.lnum, 1L, c) != 0);
+	    /* It may be required to save for undo again, e.g. when setline()
+	     * was called. */
+	    ins_need_undo = TRUE;
+	}
+	if (do_internal)
+#endif
+	    internal_format(textwidth, second_indent, flags, c == NUL);
+    }
+
+    if (c == NUL)	    /* only formatting was wanted */
+	return;
+
+#ifdef FEAT_COMMENTS
+    /* Check whether this character should end a comment. */
+    if (did_ai && (int)c == end_comment_pending)
+    {
+	char_u  *line;
+	char_u	lead_end[COM_MAX_LEN];	    /* end-comment string */
+	int	middle_len, end_len;
+	int	i;
+
+	/*
+	 * Need to remove existing (middle) comment leader and insert end
+	 * comment leader.  First, check what comment leader we can find.
+	 */
+	i = get_leader_len(line = ml_get_curline(), &p, FALSE);
+	if (i > 0 && vim_strchr(p, COM_MIDDLE) != NULL)	/* Just checking */
+	{
+	    /* Skip middle-comment string */
+	    while (*p && p[-1] != ':')	/* find end of middle flags */
+		++p;
+	    middle_len = copy_option_part(&p, lead_end, COM_MAX_LEN, ",");
+	    /* Don't count trailing white space for middle_len */
+	    while (middle_len > 0 && vim_iswhite(lead_end[middle_len - 1]))
+		--middle_len;
+
+	    /* Find the end-comment string */
+	    while (*p && p[-1] != ':')	/* find end of end flags */
+		++p;
+	    end_len = copy_option_part(&p, lead_end, COM_MAX_LEN, ",");
+
+	    /* Skip white space before the cursor */
+	    i = curwin->w_cursor.col;
+	    while (--i >= 0 && vim_iswhite(line[i]))
+		;
+	    i++;
+
+	    /* Skip to before the middle leader */
+	    i -= middle_len;
+
+	    /* Check some expected things before we go on */
+	    if (i >= 0 && lead_end[end_len - 1] == end_comment_pending)
+	    {
+		/* Backspace over all the stuff we want to replace */
+		backspace_until_column(i);
+
+		/*
+		 * Insert the end-comment string, except for the last
+		 * character, which will get inserted as normal later.
+		 */
+		ins_bytes_len(lead_end, end_len - 1);
+	    }
+	}
+    }
+    end_comment_pending = NUL;
+#endif
+
+    did_ai = FALSE;
+#ifdef FEAT_SMARTINDENT
+    did_si = FALSE;
+    can_si = FALSE;
+    can_si_back = FALSE;
+#endif
+
+    /*
+     * If there's any pending input, grab up to INPUT_BUFLEN at once.
+     * This speeds up normal text input considerably.
+     * Don't do this when 'cindent' or 'indentexpr' is set, because we might
+     * need to re-indent at a ':', or any other character (but not what
+     * 'paste' is set)..
+     */
+#ifdef USE_ON_FLY_SCROLL
+    dont_scroll = FALSE;		/* allow scrolling here */
+#endif
+
+    if (       !ISSPECIAL(c)
+#ifdef FEAT_MBYTE
+	    && (!has_mbyte || (*mb_char2len)(c) == 1)
+#endif
+	    && vpeekc() != NUL
+	    && !(State & REPLACE_FLAG)
+#ifdef FEAT_CINDENT
+	    && !cindent_on()
+#endif
+#ifdef FEAT_RIGHTLEFT
+	    && !p_ri
+#endif
+	       )
+    {
+#define INPUT_BUFLEN 100
+	char_u		buf[INPUT_BUFLEN + 1];
+	int		i;
+	colnr_T		virtcol = 0;
+
+	buf[0] = c;
+	i = 1;
+	if (textwidth > 0)
+	    virtcol = get_nolist_virtcol();
+	/*
+	 * Stop the string when:
+	 * - no more chars available
+	 * - finding a special character (command key)
+	 * - buffer is full
+	 * - running into the 'textwidth' boundary
+	 * - need to check for abbreviation: A non-word char after a word-char
+	 */
+	while (	   (c = vpeekc()) != NUL
+		&& !ISSPECIAL(c)
+#ifdef FEAT_MBYTE
+		&& (!has_mbyte || MB_BYTE2LEN_CHECK(c) == 1)
+#endif
+		&& i < INPUT_BUFLEN
+		&& (textwidth == 0
+		    || (virtcol += byte2cells(buf[i - 1])) < (colnr_T)textwidth)
+		&& !(!no_abbr && !vim_iswordc(c) && vim_iswordc(buf[i - 1])))
+	{
+#ifdef FEAT_RIGHTLEFT
+	    c = vgetc();
+	    if (p_hkmap && KeyTyped)
+		c = hkmap(c);		    /* Hebrew mode mapping */
+# ifdef FEAT_FKMAP
+	    if (p_fkmap && KeyTyped)
+		c = fkmap(c);		    /* Farsi mode mapping */
+# endif
+	    buf[i++] = c;
+#else
+	    buf[i++] = vgetc();
+#endif
+	}
+
+#ifdef FEAT_DIGRAPHS
+	do_digraph(-1);			/* clear digraphs */
+	do_digraph(buf[i-1]);		/* may be the start of a digraph */
+#endif
+	buf[i] = NUL;
+	ins_str(buf);
+	if (flags & INSCHAR_CTRLV)
+	{
+	    redo_literal(*buf);
+	    i = 1;
+	}
+	else
+	    i = 0;
+	if (buf[i] != NUL)
+	    AppendToRedobuffLit(buf + i, -1);
+    }
+    else
+    {
+#ifdef FEAT_MBYTE
+	int		cc;
+
+	if (has_mbyte && (cc = (*mb_char2len)(c)) > 1)
+	{
+	    char_u	buf[MB_MAXBYTES + 1];
+
+	    (*mb_char2bytes)(c, buf);
+	    buf[cc] = NUL;
+	    ins_char_bytes(buf, cc);
+	    AppendCharToRedobuff(c);
+	}
+	else
+#endif
+	{
+	    ins_char(c);
+	    if (flags & INSCHAR_CTRLV)
+		redo_literal(c);
+	    else
+		AppendCharToRedobuff(c);
+	}
+    }
+}
+
+/*
+ * Format text at the current insert position.
+ */
+    static void
+internal_format(textwidth, second_indent, flags, format_only)
+    int		textwidth;
+    int		second_indent;
+    int		flags;
+    int		format_only;
+{
+    int		cc;
+    int		save_char = NUL;
+    int		haveto_redraw = FALSE;
+    int		fo_ins_blank = has_format_option(FO_INS_BLANK);
+#ifdef FEAT_MBYTE
+    int		fo_multibyte = has_format_option(FO_MBYTE_BREAK);
+#endif
+    int		fo_white_par = has_format_option(FO_WHITE_PAR);
+    int		first_line = TRUE;
+#ifdef FEAT_COMMENTS
+    colnr_T	leader_len;
+    int		no_leader = FALSE;
+    int		do_comments = (flags & INSCHAR_DO_COM);
+#endif
+
+    /*
+     * When 'ai' is off we don't want a space under the cursor to be
+     * deleted.  Replace it with an 'x' temporarily.
+     */
+    if (!curbuf->b_p_ai)
+    {
+	cc = gchar_cursor();
+	if (vim_iswhite(cc))
+	{
+	    save_char = cc;
+	    pchar_cursor('x');
+	}
+    }
+
+    /*
+     * Repeat breaking lines, until the current line is not too long.
+     */
+    while (!got_int)
+    {
+	int	startcol;		/* Cursor column at entry */
+	int	wantcol;		/* column at textwidth border */
+	int	foundcol;		/* column for start of spaces */
+	int	end_foundcol = 0;	/* column for start of word */
+	colnr_T	len;
+	colnr_T	virtcol;
+#ifdef FEAT_VREPLACE
+	int	orig_col = 0;
+	char_u	*saved_text = NULL;
+#endif
+	colnr_T	col;
+
+	virtcol = get_nolist_virtcol();
+	if (virtcol < (colnr_T)textwidth)
+	    break;
+
+#ifdef FEAT_COMMENTS
+	if (no_leader)
+	    do_comments = FALSE;
+	else if (!(flags & INSCHAR_FORMAT)
+				       && has_format_option(FO_WRAP_COMS))
+	    do_comments = TRUE;
+
+	/* Don't break until after the comment leader */
+	if (do_comments)
+	    leader_len = get_leader_len(ml_get_curline(), NULL, FALSE);
+	else
+	    leader_len = 0;
+
+	/* If the line doesn't start with a comment leader, then don't
+	 * start one in a following broken line.  Avoids that a %word
+	 * moved to the start of the next line causes all following lines
+	 * to start with %. */
+	if (leader_len == 0)
+	    no_leader = TRUE;
+#endif
+	if (!(flags & INSCHAR_FORMAT)
+#ifdef FEAT_COMMENTS
+		&& leader_len == 0
+#endif
+		&& !has_format_option(FO_WRAP))
+
+	{
+	    textwidth = 0;
+	    break;
+	}
+	if ((startcol = curwin->w_cursor.col) == 0)
+	    break;
+
+	/* find column of textwidth border */
+	coladvance((colnr_T)textwidth);
+	wantcol = curwin->w_cursor.col;
+
+	curwin->w_cursor.col = startcol - 1;
+#ifdef FEAT_MBYTE
+	/* Correct cursor for multi-byte character. */
+	if (has_mbyte)
+	    mb_adjust_cursor();
+#endif
+	foundcol = 0;
+
+	/*
+	 * Find position to break at.
+	 * Stop at first entered white when 'formatoptions' has 'v'
+	 */
+	while ((!fo_ins_blank && !has_format_option(FO_INS_VI))
+		    || curwin->w_cursor.lnum != Insstart.lnum
+		    || curwin->w_cursor.col >= Insstart.col)
+	{
+	    cc = gchar_cursor();
+	    if (WHITECHAR(cc))
+	    {
+		/* remember position of blank just before text */
+		end_foundcol = curwin->w_cursor.col;
+
+		/* find start of sequence of blanks */
+		while (curwin->w_cursor.col > 0 && WHITECHAR(cc))
+		{
+		    dec_cursor();
+		    cc = gchar_cursor();
+		}
+		if (curwin->w_cursor.col == 0 && WHITECHAR(cc))
+		    break;		/* only spaces in front of text */
+#ifdef FEAT_COMMENTS
+		/* Don't break until after the comment leader */
+		if (curwin->w_cursor.col < leader_len)
+		    break;
+#endif
+		if (has_format_option(FO_ONE_LETTER))
+		{
+		    /* do not break after one-letter words */
+		    if (curwin->w_cursor.col == 0)
+			break;	/* one-letter word at begin */
+
+		    col = curwin->w_cursor.col;
+		    dec_cursor();
+		    cc = gchar_cursor();
+
+		    if (WHITECHAR(cc))
+			continue;	/* one-letter, continue */
+		    curwin->w_cursor.col = col;
+		}
+#ifdef FEAT_MBYTE
+		if (has_mbyte)
+		    foundcol = curwin->w_cursor.col
+					 + (*mb_ptr2len)(ml_get_cursor());
+		else
+#endif
+		    foundcol = curwin->w_cursor.col + 1;
+		if (curwin->w_cursor.col < (colnr_T)wantcol)
+		    break;
+	    }
+#ifdef FEAT_MBYTE
+	    else if (cc >= 0x100 && fo_multibyte
+			      && curwin->w_cursor.col <= (colnr_T)wantcol)
+	    {
+		/* Break after or before a multi-byte character. */
+		foundcol = curwin->w_cursor.col;
+		if (curwin->w_cursor.col < (colnr_T)wantcol)
+		    foundcol += (*mb_char2len)(cc);
+		end_foundcol = foundcol;
+		break;
+	    }
+#endif
+	    if (curwin->w_cursor.col == 0)
+		break;
+	    dec_cursor();
+	}
+
+	if (foundcol == 0)		/* no spaces, cannot break line */
+	{
+	    curwin->w_cursor.col = startcol;
+	    break;
+	}
+
+	/* Going to break the line, remove any "$" now. */
+	undisplay_dollar();
+
+	/*
+	 * Offset between cursor position and line break is used by replace
+	 * stack functions.  VREPLACE does not use this, and backspaces
+	 * over the text instead.
+	 */
+#ifdef FEAT_VREPLACE
+	if (State & VREPLACE_FLAG)
+	    orig_col = startcol;	/* Will start backspacing from here */
+	else
+#endif
+	    replace_offset = startcol - end_foundcol - 1;
+
+	/*
+	 * adjust startcol for spaces that will be deleted and
+	 * characters that will remain on top line
+	 */
+	curwin->w_cursor.col = foundcol;
+	while (cc = gchar_cursor(), WHITECHAR(cc))
+	    inc_cursor();
+	startcol -= curwin->w_cursor.col;
+	if (startcol < 0)
+	    startcol = 0;
+
+#ifdef FEAT_VREPLACE
+	if (State & VREPLACE_FLAG)
+	{
+	    /*
+	     * In VREPLACE mode, we will backspace over the text to be
+	     * wrapped, so save a copy now to put on the next line.
+	     */
+	    saved_text = vim_strsave(ml_get_cursor());
+	    curwin->w_cursor.col = orig_col;
+	    if (saved_text == NULL)
+		break;	/* Can't do it, out of memory */
+	    saved_text[startcol] = NUL;
+
+	    /* Backspace over characters that will move to the next line */
+	    if (!fo_white_par)
+		backspace_until_column(foundcol);
+	}
+	else
+#endif
+	{
+	    /* put cursor after pos. to break line */
+	    if (!fo_white_par)
+		curwin->w_cursor.col = foundcol;
+	}
+
+	/*
+	 * Split the line just before the margin.
+	 * Only insert/delete lines, but don't really redraw the window.
+	 */
+	open_line(FORWARD, OPENLINE_DELSPACES + OPENLINE_MARKFIX
+		+ (fo_white_par ? OPENLINE_KEEPTRAIL : 0)
+#ifdef FEAT_COMMENTS
+		+ (do_comments ? OPENLINE_DO_COM : 0)
+#endif
+		, old_indent);
+	old_indent = 0;
+
+	replace_offset = 0;
+	if (first_line)
+	{
+	    if (second_indent < 0 && has_format_option(FO_Q_NUMBER))
+		second_indent = get_number_indent(curwin->w_cursor.lnum -1);
+	    if (second_indent >= 0)
+	    {
+#ifdef FEAT_VREPLACE
+		if (State & VREPLACE_FLAG)
+		    change_indent(INDENT_SET, second_indent, FALSE, NUL);
+		else
+#endif
+		    (void)set_indent(second_indent, SIN_CHANGED);
+	    }
+	    first_line = FALSE;
+	}
+
+#ifdef FEAT_VREPLACE
+	if (State & VREPLACE_FLAG)
+	{
+	    /*
+	     * In VREPLACE mode we have backspaced over the text to be
+	     * moved, now we re-insert it into the new line.
+	     */
+	    ins_bytes(saved_text);
+	    vim_free(saved_text);
+	}
+	else
+#endif
+	{
+	    /*
+	     * Check if cursor is not past the NUL off the line, cindent
+	     * may have added or removed indent.
+	     */
+	    curwin->w_cursor.col += startcol;
+	    len = (colnr_T)STRLEN(ml_get_curline());
+	    if (curwin->w_cursor.col > len)
+		curwin->w_cursor.col = len;
+	}
+
+	haveto_redraw = TRUE;
+#ifdef FEAT_CINDENT
+	can_cindent = TRUE;
+#endif
+	/* moved the cursor, don't autoindent or cindent now */
+	did_ai = FALSE;
+#ifdef FEAT_SMARTINDENT
+	did_si = FALSE;
+	can_si = FALSE;
+	can_si_back = FALSE;
+#endif
+	line_breakcheck();
+    }
+
+    if (save_char != NUL)		/* put back space after cursor */
+	pchar_cursor(save_char);
+
+    if (!format_only && haveto_redraw)
+    {
+	update_topline();
+	redraw_curbuf_later(VALID);
+    }
+}
+
+/*
+ * Called after inserting or deleting text: When 'formatoptions' includes the
+ * 'a' flag format from the current line until the end of the paragraph.
+ * Keep the cursor at the same position relative to the text.
+ * The caller must have saved the cursor line for undo, following ones will be
+ * saved here.
+ */
+    void
+auto_format(trailblank, prev_line)
+    int		trailblank;	/* when TRUE also format with trailing blank */
+    int		prev_line;	/* may start in previous line */
+{
+    pos_T	pos;
+    colnr_T	len;
+    char_u	*old;
+    char_u	*new, *pnew;
+    int		wasatend;
+    int		cc;
+
+    if (!has_format_option(FO_AUTO))
+	return;
+
+    pos = curwin->w_cursor;
+    old = ml_get_curline();
+
+    /* may remove added space */
+    check_auto_format(FALSE);
+
+    /* Don't format in Insert mode when the cursor is on a trailing blank, the
+     * user might insert normal text next.  Also skip formatting when "1" is
+     * in 'formatoptions' and there is a single character before the cursor.
+     * Otherwise the line would be broken and when typing another non-white
+     * next they are not joined back together. */
+    wasatend = (pos.col == STRLEN(old));
+    if (*old != NUL && !trailblank && wasatend)
+    {
+	dec_cursor();
+	cc = gchar_cursor();
+	if (!WHITECHAR(cc) && curwin->w_cursor.col > 0
+					  && has_format_option(FO_ONE_LETTER))
+	    dec_cursor();
+	cc = gchar_cursor();
+	if (WHITECHAR(cc))
+	{
+	    curwin->w_cursor = pos;
+	    return;
+	}
+	curwin->w_cursor = pos;
+    }
+
+#ifdef FEAT_COMMENTS
+    /* With the 'c' flag in 'formatoptions' and 't' missing: only format
+     * comments. */
+    if (has_format_option(FO_WRAP_COMS) && !has_format_option(FO_WRAP)
+				     && get_leader_len(old, NULL, FALSE) == 0)
+	return;
+#endif
+
+    /*
+     * May start formatting in a previous line, so that after "x" a word is
+     * moved to the previous line if it fits there now.  Only when this is not
+     * the start of a paragraph.
+     */
+    if (prev_line && !paragraph_start(curwin->w_cursor.lnum))
+    {
+	--curwin->w_cursor.lnum;
+	if (u_save_cursor() == FAIL)
+	    return;
+    }
+
+    /*
+     * Do the formatting and restore the cursor position.  "saved_cursor" will
+     * be adjusted for the text formatting.
+     */
+    saved_cursor = pos;
+    format_lines((linenr_T)-1);
+    curwin->w_cursor = saved_cursor;
+    saved_cursor.lnum = 0;
+
+    if (curwin->w_cursor.lnum > curbuf->b_ml.ml_line_count)
+    {
+	/* "cannot happen" */
+	curwin->w_cursor.lnum = curbuf->b_ml.ml_line_count;
+	coladvance((colnr_T)MAXCOL);
+    }
+    else
+	check_cursor_col();
+
+    /* Insert mode: If the cursor is now after the end of the line while it
+     * previously wasn't, the line was broken.  Because of the rule above we
+     * need to add a space when 'w' is in 'formatoptions' to keep a paragraph
+     * formatted. */
+    if (!wasatend && has_format_option(FO_WHITE_PAR))
+    {
+	new = ml_get_curline();
+	len = (colnr_T)STRLEN(new);
+	if (curwin->w_cursor.col == len)
+	{
+	    pnew = vim_strnsave(new, len + 2);
+	    pnew[len] = ' ';
+	    pnew[len + 1] = NUL;
+	    ml_replace(curwin->w_cursor.lnum, pnew, FALSE);
+	    /* remove the space later */
+	    did_add_space = TRUE;
+	}
+	else
+	    /* may remove added space */
+	    check_auto_format(FALSE);
+    }
+
+    check_cursor();
+}
+
+/*
+ * When an extra space was added to continue a paragraph for auto-formatting,
+ * delete it now.  The space must be under the cursor, just after the insert
+ * position.
+ */
+    static void
+check_auto_format(end_insert)
+    int		end_insert;	    /* TRUE when ending Insert mode */
+{
+    int		c = ' ';
+    int		cc;
+
+    if (did_add_space)
+    {
+	cc = gchar_cursor();
+	if (!WHITECHAR(cc))
+	    /* Somehow the space was removed already. */
+	    did_add_space = FALSE;
+	else
+	{
+	    if (!end_insert)
+	    {
+		inc_cursor();
+		c = gchar_cursor();
+		dec_cursor();
+	    }
+	    if (c != NUL)
+	    {
+		/* The space is no longer at the end of the line, delete it. */
+		del_char(FALSE);
+		did_add_space = FALSE;
+	    }
+	}
+    }
+}
+
+/*
+ * Find out textwidth to be used for formatting:
+ *	if 'textwidth' option is set, use it
+ *	else if 'wrapmargin' option is set, use W_WIDTH(curwin) - 'wrapmargin'
+ *	if invalid value, use 0.
+ *	Set default to window width (maximum 79) for "gq" operator.
+ */
+    int
+comp_textwidth(ff)
+    int		ff;	/* force formatting (for "gq" command) */
+{
+    int		textwidth;
+
+    textwidth = curbuf->b_p_tw;
+    if (textwidth == 0 && curbuf->b_p_wm)
+    {
+	/* The width is the window width minus 'wrapmargin' minus all the
+	 * things that add to the margin. */
+	textwidth = W_WIDTH(curwin) - curbuf->b_p_wm;
+#ifdef FEAT_CMDWIN
+	if (cmdwin_type != 0)
+	    textwidth -= 1;
+#endif
+#ifdef FEAT_FOLDING
+	textwidth -= curwin->w_p_fdc;
+#endif
+#ifdef FEAT_SIGNS
+	if (curwin->w_buffer->b_signlist != NULL
+# ifdef FEAT_NETBEANS_INTG
+			    || usingNetbeans
+# endif
+		    )
+	    textwidth -= 1;
+#endif
+	if (curwin->w_p_nu)
+	    textwidth -= 8;
+    }
+    if (textwidth < 0)
+	textwidth = 0;
+    if (ff && textwidth == 0)
+    {
+	textwidth = W_WIDTH(curwin) - 1;
+	if (textwidth > 79)
+	    textwidth = 79;
+    }
+    return textwidth;
+}
+
+/*
+ * Put a character in the redo buffer, for when just after a CTRL-V.
+ */
+    static void
+redo_literal(c)
+    int	    c;
+{
+    char_u	buf[10];
+
+    /* Only digits need special treatment.  Translate them into a string of
+     * three digits. */
+    if (VIM_ISDIGIT(c))
+    {
+	sprintf((char *)buf, "%03d", c);
+	AppendToRedobuff(buf);
+    }
+    else
+	AppendCharToRedobuff(c);
+}
+
+/*
+ * start_arrow() is called when an arrow key is used in insert mode.
+ * For undo/redo it resembles hitting the <ESC> key.
+ */
+    static void
+start_arrow(end_insert_pos)
+    pos_T    *end_insert_pos;	    /* can be NULL */
+{
+    if (!arrow_used)	    /* something has been inserted */
+    {
+	AppendToRedobuff(ESC_STR);
+	stop_insert(end_insert_pos, FALSE);
+	arrow_used = TRUE;	/* this means we stopped the current insert */
+    }
+#ifdef FEAT_SPELL
+    check_spell_redraw();
+#endif
+}
+
+#ifdef FEAT_SPELL
+/*
+ * If we skipped highlighting word at cursor, do it now.
+ * It may be skipped again, thus reset spell_redraw_lnum first.
+ */
+    static void
+check_spell_redraw()
+{
+    if (spell_redraw_lnum != 0)
+    {
+	linenr_T	lnum = spell_redraw_lnum;
+
+	spell_redraw_lnum = 0;
+	redrawWinline(lnum, FALSE);
+    }
+}
+
+/*
+ * Called when starting CTRL_X_SPELL mode: Move backwards to a previous badly
+ * spelled word, if there is one.
+ */
+    static void
+spell_back_to_badword()
+{
+    pos_T	tpos = curwin->w_cursor;
+
+    spell_bad_len = spell_move_to(curwin, BACKWARD, TRUE, TRUE, NULL);
+    if (curwin->w_cursor.col != tpos.col)
+	start_arrow(&tpos);
+}
+#endif
+
+/*
+ * stop_arrow() is called before a change is made in insert mode.
+ * If an arrow key has been used, start a new insertion.
+ * Returns FAIL if undo is impossible, shouldn't insert then.
+ */
+    int
+stop_arrow()
+{
+    if (arrow_used)
+    {
+	if (u_save_cursor() == OK)
+	{
+	    arrow_used = FALSE;
+	    ins_need_undo = FALSE;
+	}
+	Insstart = curwin->w_cursor;	/* new insertion starts here */
+	Insstart_textlen = linetabsize(ml_get_curline());
+	ai_col = 0;
+#ifdef FEAT_VREPLACE
+	if (State & VREPLACE_FLAG)
+	{
+	    orig_line_count = curbuf->b_ml.ml_line_count;
+	    vr_lines_changed = 1;
+	}
+#endif
+	ResetRedobuff();
+	AppendToRedobuff((char_u *)"1i");   /* pretend we start an insertion */
+	new_insert_skip = 2;
+    }
+    else if (ins_need_undo)
+    {
+	if (u_save_cursor() == OK)
+	    ins_need_undo = FALSE;
+    }
+
+#ifdef FEAT_FOLDING
+    /* Always open fold at the cursor line when inserting something. */
+    foldOpenCursor();
+#endif
+
+    return (arrow_used || ins_need_undo ? FAIL : OK);
+}
+
+/*
+ * Do a few things to stop inserting.
+ * "end_insert_pos" is where insert ended.  It is NULL when we already jumped
+ * to another window/buffer.
+ */
+    static void
+stop_insert(end_insert_pos, esc)
+    pos_T	*end_insert_pos;
+    int		esc;			/* called by ins_esc() */
+{
+    int		cc;
+    char_u	*ptr;
+
+    stop_redo_ins();
+    replace_flush();		/* abandon replace stack */
+
+    /*
+     * Save the inserted text for later redo with ^@ and CTRL-A.
+     * Don't do it when "restart_edit" was set and nothing was inserted,
+     * otherwise CTRL-O w and then <Left> will clear "last_insert".
+     */
+    ptr = get_inserted();
+    if (did_restart_edit == 0 || (ptr != NULL
+				       && (int)STRLEN(ptr) > new_insert_skip))
+    {
+	vim_free(last_insert);
+	last_insert = ptr;
+	last_insert_skip = new_insert_skip;
+    }
+    else
+	vim_free(ptr);
+
+    if (!arrow_used && end_insert_pos != NULL)
+    {
+	/* Auto-format now.  It may seem strange to do this when stopping an
+	 * insertion (or moving the cursor), but it's required when appending
+	 * a line and having it end in a space.  But only do it when something
+	 * was actually inserted, otherwise undo won't work. */
+	if (!ins_need_undo && has_format_option(FO_AUTO))
+	{
+	    pos_T   tpos = curwin->w_cursor;
+
+	    /* When the cursor is at the end of the line after a space the
+	     * formatting will move it to the following word.  Avoid that by
+	     * moving the cursor onto the space. */
+	    cc = 'x';
+	    if (curwin->w_cursor.col > 0 && gchar_cursor() == NUL)
+	    {
+		dec_cursor();
+		cc = gchar_cursor();
+		if (!vim_iswhite(cc))
+		    curwin->w_cursor = tpos;
+	    }
+
+	    auto_format(TRUE, FALSE);
+
+	    if (vim_iswhite(cc))
+	    {
+		if (gchar_cursor() != NUL)
+		    inc_cursor();
+#ifdef FEAT_VIRTUALEDIT
+		/* If the cursor is still at the same character, also keep
+		 * the "coladd". */
+		if (gchar_cursor() == NUL
+			&& curwin->w_cursor.lnum == tpos.lnum
+			&& curwin->w_cursor.col == tpos.col)
+		    curwin->w_cursor.coladd = tpos.coladd;
+#endif
+	    }
+	}
+
+	/* If a space was inserted for auto-formatting, remove it now. */
+	check_auto_format(TRUE);
+
+	/* If we just did an auto-indent, remove the white space from the end
+	 * of the line, and put the cursor back.
+	 * Do this when ESC was used or moving the cursor up/down. */
+	if (did_ai && (esc || (vim_strchr(p_cpo, CPO_INDENT) == NULL
+			&& curwin->w_cursor.lnum != end_insert_pos->lnum)))
+	{
+	    pos_T	tpos = curwin->w_cursor;
+
+	    curwin->w_cursor = *end_insert_pos;
+	    for (;;)
+	    {
+		if (gchar_cursor() == NUL && curwin->w_cursor.col > 0)
+		    --curwin->w_cursor.col;
+		cc = gchar_cursor();
+		if (!vim_iswhite(cc))
+		    break;
+		(void)del_char(TRUE);
+	    }
+	    if (curwin->w_cursor.lnum != tpos.lnum)
+		curwin->w_cursor = tpos;
+	    else if (cc != NUL)
+		++curwin->w_cursor.col;	/* put cursor back on the NUL */
+
+#ifdef FEAT_VISUAL
+	    /* <C-S-Right> may have started Visual mode, adjust the position for
+	     * deleted characters. */
+	    if (VIsual_active && VIsual.lnum == curwin->w_cursor.lnum)
+	    {
+		cc = (int)STRLEN(ml_get_curline());
+		if (VIsual.col > (colnr_T)cc)
+		{
+		    VIsual.col = cc;
+# ifdef FEAT_VIRTUALEDIT
+		    VIsual.coladd = 0;
+# endif
+		}
+	    }
+#endif
+	}
+    }
+    did_ai = FALSE;
+#ifdef FEAT_SMARTINDENT
+    did_si = FALSE;
+    can_si = FALSE;
+    can_si_back = FALSE;
+#endif
+
+    /* Set '[ and '] to the inserted text.  When end_insert_pos is NULL we are
+     * now in a different buffer. */
+    if (end_insert_pos != NULL)
+    {
+	curbuf->b_op_start = Insstart;
+	curbuf->b_op_end = *end_insert_pos;
+    }
+}
+
+/*
+ * Set the last inserted text to a single character.
+ * Used for the replace command.
+ */
+    void
+set_last_insert(c)
+    int		c;
+{
+    char_u	*s;
+
+    vim_free(last_insert);
+#ifdef FEAT_MBYTE
+    last_insert = alloc(MB_MAXBYTES * 3 + 5);
+#else
+    last_insert = alloc(6);
+#endif
+    if (last_insert != NULL)
+    {
+	s = last_insert;
+	/* Use the CTRL-V only when entering a special char */
+	if (c < ' ' || c == DEL)
+	    *s++ = Ctrl_V;
+	s = add_char2buf(c, s);
+	*s++ = ESC;
+	*s++ = NUL;
+	last_insert_skip = 0;
+    }
+}
+
+#if defined(EXITFREE) || defined(PROTO)
+    void
+free_last_insert()
+{
+    vim_free(last_insert);
+    last_insert = NULL;
+    vim_free(compl_orig_text);
+    compl_orig_text = NULL;
+}
+#endif
+
+/*
+ * Add character "c" to buffer "s".  Escape the special meaning of K_SPECIAL
+ * and CSI.  Handle multi-byte characters.
+ * Returns a pointer to after the added bytes.
+ */
+    char_u *
+add_char2buf(c, s)
+    int		c;
+    char_u	*s;
+{
+#ifdef FEAT_MBYTE
+    char_u	temp[MB_MAXBYTES];
+    int		i;
+    int		len;
+
+    len = (*mb_char2bytes)(c, temp);
+    for (i = 0; i < len; ++i)
+    {
+	c = temp[i];
+#endif
+	/* Need to escape K_SPECIAL and CSI like in the typeahead buffer. */
+	if (c == K_SPECIAL)
+	{
+	    *s++ = K_SPECIAL;
+	    *s++ = KS_SPECIAL;
+	    *s++ = KE_FILLER;
+	}
+#ifdef FEAT_GUI
+	else if (c == CSI)
+	{
+	    *s++ = CSI;
+	    *s++ = KS_EXTRA;
+	    *s++ = (int)KE_CSI;
+	}
+#endif
+	else
+	    *s++ = c;
+#ifdef FEAT_MBYTE
+    }
+#endif
+    return s;
+}
+
+/*
+ * move cursor to start of line
+ * if flags & BL_WHITE	move to first non-white
+ * if flags & BL_SOL	move to first non-white if startofline is set,
+ *			    otherwise keep "curswant" column
+ * if flags & BL_FIX	don't leave the cursor on a NUL.
+ */
+    void
+beginline(flags)
+    int		flags;
+{
+    if ((flags & BL_SOL) && !p_sol)
+	coladvance(curwin->w_curswant);
+    else
+    {
+	curwin->w_cursor.col = 0;
+#ifdef FEAT_VIRTUALEDIT
+	curwin->w_cursor.coladd = 0;
+#endif
+
+	if (flags & (BL_WHITE | BL_SOL))
+	{
+	    char_u  *ptr;
+
+	    for (ptr = ml_get_curline(); vim_iswhite(*ptr)
+			       && !((flags & BL_FIX) && ptr[1] == NUL); ++ptr)
+		++curwin->w_cursor.col;
+	}
+	curwin->w_set_curswant = TRUE;
+    }
+}
+
+/*
+ * oneright oneleft cursor_down cursor_up
+ *
+ * Move one char {right,left,down,up}.
+ * Doesn't move onto the NUL past the end of the line, unless it is allowed.
+ * Return OK when successful, FAIL when we hit a line of file boundary.
+ */
+
+    int
+oneright()
+{
+    char_u	*ptr;
+    int		l;
+
+#ifdef FEAT_VIRTUALEDIT
+    if (virtual_active())
+    {
+	pos_T	prevpos = curwin->w_cursor;
+
+	/* Adjust for multi-wide char (excluding TAB) */
+	ptr = ml_get_cursor();
+	coladvance(getviscol() + ((*ptr != TAB && vim_isprintc(
+# ifdef FEAT_MBYTE
+			    (*mb_ptr2char)(ptr)
+# else
+			    *ptr
+# endif
+			    ))
+		    ? ptr2cells(ptr) : 1));
+	curwin->w_set_curswant = TRUE;
+	/* Return OK if the cursor moved, FAIL otherwise (at window edge). */
+	return (prevpos.col != curwin->w_cursor.col
+		    || prevpos.coladd != curwin->w_cursor.coladd) ? OK : FAIL;
+    }
+#endif
+
+    ptr = ml_get_cursor();
+    if (*ptr == NUL)
+	return FAIL;	    /* already at the very end */
+
+#ifdef FEAT_MBYTE
+    if (has_mbyte)
+	l = (*mb_ptr2len)(ptr);
+    else
+#endif
+	l = 1;
+
+    /* move "l" bytes right, but don't end up on the NUL, unless 'virtualedit'
+     * contains "onemore". */
+    if (ptr[l] == NUL
+#ifdef FEAT_VIRTUALEDIT
+	    && (ve_flags & VE_ONEMORE) == 0
+#endif
+	    )
+	return FAIL;
+    curwin->w_cursor.col += l;
+
+    curwin->w_set_curswant = TRUE;
+    return OK;
+}
+
+    int
+oneleft()
+{
+#ifdef FEAT_VIRTUALEDIT
+    if (virtual_active())
+    {
+	int width;
+	int v = getviscol();
+
+	if (v == 0)
+	    return FAIL;
+
+# ifdef FEAT_LINEBREAK
+	/* We might get stuck on 'showbreak', skip over it. */
+	width = 1;
+	for (;;)
+	{
+	    coladvance(v - width);
+	    /* getviscol() is slow, skip it when 'showbreak' is empty and
+	     * there are no multi-byte characters */
+	    if ((*p_sbr == NUL
+#  ifdef FEAT_MBYTE
+			&& !has_mbyte
+#  endif
+			) || getviscol() < v)
+		break;
+	    ++width;
+	}
+# else
+	coladvance(v - 1);
+# endif
+
+	if (curwin->w_cursor.coladd == 1)
+	{
+	    char_u *ptr;
+
+	    /* Adjust for multi-wide char (not a TAB) */
+	    ptr = ml_get_cursor();
+	    if (*ptr != TAB && vim_isprintc(
+#  ifdef FEAT_MBYTE
+			    (*mb_ptr2char)(ptr)
+#  else
+			    *ptr
+#  endif
+			    ) && ptr2cells(ptr) > 1)
+		curwin->w_cursor.coladd = 0;
+	}
+
+	curwin->w_set_curswant = TRUE;
+	return OK;
+    }
+#endif
+
+    if (curwin->w_cursor.col == 0)
+	return FAIL;
+
+    curwin->w_set_curswant = TRUE;
+    --curwin->w_cursor.col;
+
+#ifdef FEAT_MBYTE
+    /* if the character on the left of the current cursor is a multi-byte
+     * character, move to its first byte */
+    if (has_mbyte)
+	mb_adjust_cursor();
+#endif
+    return OK;
+}
+
+    int
+cursor_up(n, upd_topline)
+    long	n;
+    int		upd_topline;	    /* When TRUE: update topline */
+{
+    linenr_T	lnum;
+
+    if (n > 0)
+    {
+	lnum = curwin->w_cursor.lnum;
+	/* This fails if the cursor is already in the first line or the count
+	 * is larger than the line number and '-' is in 'cpoptions' */
+	if (lnum <= 1 || (n >= lnum && vim_strchr(p_cpo, CPO_MINUS) != NULL))
+	    return FAIL;
+	if (n >= lnum)
+	    lnum = 1;
+	else
+#ifdef FEAT_FOLDING
+	    if (hasAnyFolding(curwin))
+	{
+	    /*
+	     * Count each sequence of folded lines as one logical line.
+	     */
+	    /* go to the the start of the current fold */
+	    (void)hasFolding(lnum, &lnum, NULL);
+
+	    while (n--)
+	    {
+		/* move up one line */
+		--lnum;
+		if (lnum <= 1)
+		    break;
+		/* If we entered a fold, move to the beginning, unless in
+		 * Insert mode or when 'foldopen' contains "all": it will open
+		 * in a moment. */
+		if (n > 0 || !((State & INSERT) || (fdo_flags & FDO_ALL)))
+		    (void)hasFolding(lnum, &lnum, NULL);
+	    }
+	    if (lnum < 1)
+		lnum = 1;
+	}
+	else
+#endif
+	    lnum -= n;
+	curwin->w_cursor.lnum = lnum;
+    }
+
+    /* try to advance to the column we want to be at */
+    coladvance(curwin->w_curswant);
+
+    if (upd_topline)
+	update_topline();	/* make sure curwin->w_topline is valid */
+
+    return OK;
+}
+
+/*
+ * Cursor down a number of logical lines.
+ */
+    int
+cursor_down(n, upd_topline)
+    long	n;
+    int		upd_topline;	    /* When TRUE: update topline */
+{
+    linenr_T	lnum;
+
+    if (n > 0)
+    {
+	lnum = curwin->w_cursor.lnum;
+#ifdef FEAT_FOLDING
+	/* Move to last line of fold, will fail if it's the end-of-file. */
+	(void)hasFolding(lnum, NULL, &lnum);
+#endif
+	/* This fails if the cursor is already in the last line or would move
+	 * beyound the last line and '-' is in 'cpoptions' */
+	if (lnum >= curbuf->b_ml.ml_line_count
+		|| (lnum + n > curbuf->b_ml.ml_line_count
+		    && vim_strchr(p_cpo, CPO_MINUS) != NULL))
+	    return FAIL;
+	if (lnum + n >= curbuf->b_ml.ml_line_count)
+	    lnum = curbuf->b_ml.ml_line_count;
+	else
+#ifdef FEAT_FOLDING
+	if (hasAnyFolding(curwin))
+	{
+	    linenr_T	last;
+
+	    /* count each sequence of folded lines as one logical line */
+	    while (n--)
+	    {
+		if (hasFolding(lnum, NULL, &last))
+		    lnum = last + 1;
+		else
+		    ++lnum;
+		if (lnum >= curbuf->b_ml.ml_line_count)
+		    break;
+	    }
+	    if (lnum > curbuf->b_ml.ml_line_count)
+		lnum = curbuf->b_ml.ml_line_count;
+	}
+	else
+#endif
+	    lnum += n;
+	curwin->w_cursor.lnum = lnum;
+    }
+
+    /* try to advance to the column we want to be at */
+    coladvance(curwin->w_curswant);
+
+    if (upd_topline)
+	update_topline();	/* make sure curwin->w_topline is valid */
+
+    return OK;
+}
+
+/*
+ * Stuff the last inserted text in the read buffer.
+ * Last_insert actually is a copy of the redo buffer, so we
+ * first have to remove the command.
+ */
+    int
+stuff_inserted(c, count, no_esc)
+    int	    c;		/* Command character to be inserted */
+    long    count;	/* Repeat this many times */
+    int	    no_esc;	/* Don't add an ESC at the end */
+{
+    char_u	*esc_ptr;
+    char_u	*ptr;
+    char_u	*last_ptr;
+    char_u	last = NUL;
+
+    ptr = get_last_insert();
+    if (ptr == NULL)
+    {
+	EMSG(_(e_noinstext));
+	return FAIL;
+    }
+
+    /* may want to stuff the command character, to start Insert mode */
+    if (c != NUL)
+	stuffcharReadbuff(c);
+    if ((esc_ptr = (char_u *)vim_strrchr(ptr, ESC)) != NULL)
+	*esc_ptr = NUL;	    /* remove the ESC */
+
+    /* when the last char is either "0" or "^" it will be quoted if no ESC
+     * comes after it OR if it will inserted more than once and "ptr"
+     * starts with ^D.	-- Acevedo
+     */
+    last_ptr = (esc_ptr ? esc_ptr : ptr + STRLEN(ptr)) - 1;
+    if (last_ptr >= ptr && (*last_ptr == '0' || *last_ptr == '^')
+	    && (no_esc || (*ptr == Ctrl_D && count > 1)))
+    {
+	last = *last_ptr;
+	*last_ptr = NUL;
+    }
+
+    do
+    {
+	stuffReadbuff(ptr);
+	/* a trailing "0" is inserted as "<C-V>048", "^" as "<C-V>^" */
+	if (last)
+	    stuffReadbuff((char_u *)(last == '0'
+			? IF_EB("\026\060\064\070", CTRL_V_STR "xf0")
+			: IF_EB("\026^", CTRL_V_STR "^")));
+    }
+    while (--count > 0);
+
+    if (last)
+	*last_ptr = last;
+
+    if (esc_ptr != NULL)
+	*esc_ptr = ESC;	    /* put the ESC back */
+
+    /* may want to stuff a trailing ESC, to get out of Insert mode */
+    if (!no_esc)
+	stuffcharReadbuff(ESC);
+
+    return OK;
+}
+
+    char_u *
+get_last_insert()
+{
+    if (last_insert == NULL)
+	return NULL;
+    return last_insert + last_insert_skip;
+}
+
+/*
+ * Get last inserted string, and remove trailing <Esc>.
+ * Returns pointer to allocated memory (must be freed) or NULL.
+ */
+    char_u *
+get_last_insert_save()
+{
+    char_u	*s;
+    int		len;
+
+    if (last_insert == NULL)
+	return NULL;
+    s = vim_strsave(last_insert + last_insert_skip);
+    if (s != NULL)
+    {
+	len = (int)STRLEN(s);
+	if (len > 0 && s[len - 1] == ESC)	/* remove trailing ESC */
+	    s[len - 1] = NUL;
+    }
+    return s;
+}
+
+/*
+ * Check the word in front of the cursor for an abbreviation.
+ * Called when the non-id character "c" has been entered.
+ * When an abbreviation is recognized it is removed from the text and
+ * the replacement string is inserted in typebuf.tb_buf[], followed by "c".
+ */
+    static int
+echeck_abbr(c)
+    int c;
+{
+    /* Don't check for abbreviation in paste mode, when disabled and just
+     * after moving around with cursor keys. */
+    if (p_paste || no_abbr || arrow_used)
+	return FALSE;
+
+    return check_abbr(c, ml_get_curline(), curwin->w_cursor.col,
+		curwin->w_cursor.lnum == Insstart.lnum ? Insstart.col : 0);
+}
+
+/*
+ * replace-stack functions
+ *
+ * When replacing characters, the replaced characters are remembered for each
+ * new character.  This is used to re-insert the old text when backspacing.
+ *
+ * There is a NUL headed list of characters for each character that is
+ * currently in the file after the insertion point.  When BS is used, one NUL
+ * headed list is put back for the deleted character.
+ *
+ * For a newline, there are two NUL headed lists.  One contains the characters
+ * that the NL replaced.  The extra one stores the characters after the cursor
+ * that were deleted (always white space).
+ *
+ * Replace_offset is normally 0, in which case replace_push will add a new
+ * character at the end of the stack.  If replace_offset is not 0, that many
+ * characters will be left on the stack above the newly inserted character.
+ */
+
+static char_u	*replace_stack = NULL;
+static long	replace_stack_nr = 0;	    /* next entry in replace stack */
+static long	replace_stack_len = 0;	    /* max. number of entries */
+
+    void
+replace_push(c)
+    int	    c;	    /* character that is replaced (NUL is none) */
+{
+    char_u  *p;
+
+    if (replace_stack_nr < replace_offset)	/* nothing to do */
+	return;
+    if (replace_stack_len <= replace_stack_nr)
+    {
+	replace_stack_len += 50;
+	p = lalloc(sizeof(char_u) * replace_stack_len, TRUE);
+	if (p == NULL)	    /* out of memory */
+	{
+	    replace_stack_len -= 50;
+	    return;
+	}
+	if (replace_stack != NULL)
+	{
+	    mch_memmove(p, replace_stack,
+				 (size_t)(replace_stack_nr * sizeof(char_u)));
+	    vim_free(replace_stack);
+	}
+	replace_stack = p;
+    }
+    p = replace_stack + replace_stack_nr - replace_offset;
+    if (replace_offset)
+	mch_memmove(p + 1, p, (size_t)(replace_offset * sizeof(char_u)));
+    *p = c;
+    ++replace_stack_nr;
+}
+
+#if 0
+/*
+ * call replace_push(c) with replace_offset set to the first NUL.
+ */
+    static void
+replace_push_off(c)
+    int	    c;
+{
+    char_u	*p;
+
+    p = replace_stack + replace_stack_nr;
+    for (replace_offset = 1; replace_offset < replace_stack_nr;
+							     ++replace_offset)
+	if (*--p == NUL)
+	    break;
+    replace_push(c);
+    replace_offset = 0;
+}
+#endif
+
+/*
+ * Pop one item from the replace stack.
+ * return -1 if stack empty
+ * return replaced character or NUL otherwise
+ */
+    static int
+replace_pop()
+{
+    if (replace_stack_nr == 0)
+	return -1;
+    return (int)replace_stack[--replace_stack_nr];
+}
+
+/*
+ * Join the top two items on the replace stack.  This removes to "off"'th NUL
+ * encountered.
+ */
+    static void
+replace_join(off)
+    int	    off;	/* offset for which NUL to remove */
+{
+    int	    i;
+
+    for (i = replace_stack_nr; --i >= 0; )
+	if (replace_stack[i] == NUL && off-- <= 0)
+	{
+	    --replace_stack_nr;
+	    mch_memmove(replace_stack + i, replace_stack + i + 1,
+					      (size_t)(replace_stack_nr - i));
+	    return;
+	}
+}
+
+/*
+ * Pop bytes from the replace stack until a NUL is found, and insert them
+ * before the cursor.  Can only be used in REPLACE or VREPLACE mode.
+ */
+    static void
+replace_pop_ins()
+{
+    int	    cc;
+    int	    oldState = State;
+
+    State = NORMAL;			/* don't want REPLACE here */
+    while ((cc = replace_pop()) > 0)
+    {
+#ifdef FEAT_MBYTE
+	mb_replace_pop_ins(cc);
+#else
+	ins_char(cc);
+#endif
+	dec_cursor();
+    }
+    State = oldState;
+}
+
+#ifdef FEAT_MBYTE
+/*
+ * Insert bytes popped from the replace stack. "cc" is the first byte.  If it
+ * indicates a multi-byte char, pop the other bytes too.
+ */
+    static void
+mb_replace_pop_ins(cc)
+    int		cc;
+{
+    int		n;
+    char_u	buf[MB_MAXBYTES];
+    int		i;
+    int		c;
+
+    if (has_mbyte && (n = MB_BYTE2LEN(cc)) > 1)
+    {
+	buf[0] = cc;
+	for (i = 1; i < n; ++i)
+	    buf[i] = replace_pop();
+	ins_bytes_len(buf, n);
+    }
+    else
+	ins_char(cc);
+
+    if (enc_utf8)
+	/* Handle composing chars. */
+	for (;;)
+	{
+	    c = replace_pop();
+	    if (c == -1)	    /* stack empty */
+		break;
+	    if ((n = MB_BYTE2LEN(c)) == 1)
+	    {
+		/* Not a multi-byte char, put it back. */
+		replace_push(c);
+		break;
+	    }
+	    else
+	    {
+		buf[0] = c;
+		for (i = 1; i < n; ++i)
+		    buf[i] = replace_pop();
+		if (utf_iscomposing(utf_ptr2char(buf)))
+		    ins_bytes_len(buf, n);
+		else
+		{
+		    /* Not a composing char, put it back. */
+		    for (i = n - 1; i >= 0; --i)
+			replace_push(buf[i]);
+		    break;
+		}
+	    }
+	}
+}
+#endif
+
+/*
+ * make the replace stack empty
+ * (called when exiting replace mode)
+ */
+    static void
+replace_flush()
+{
+    vim_free(replace_stack);
+    replace_stack = NULL;
+    replace_stack_len = 0;
+    replace_stack_nr = 0;
+}
+
+/*
+ * Handle doing a BS for one character.
+ * cc < 0: replace stack empty, just move cursor
+ * cc == 0: character was inserted, delete it
+ * cc > 0: character was replaced, put cc (first byte of original char) back
+ * and check for more characters to be put back
+ */
+    static void
+replace_do_bs()
+{
+    int		cc;
+#ifdef FEAT_VREPLACE
+    int		orig_len = 0;
+    int		ins_len;
+    int		orig_vcols = 0;
+    colnr_T	start_vcol;
+    char_u	*p;
+    int		i;
+    int		vcol;
+#endif
+
+    cc = replace_pop();
+    if (cc > 0)
+    {
+#ifdef FEAT_VREPLACE
+	if (State & VREPLACE_FLAG)
+	{
+	    /* Get the number of screen cells used by the character we are
+	     * going to delete. */
+	    getvcol(curwin, &curwin->w_cursor, NULL, &start_vcol, NULL);
+	    orig_vcols = chartabsize(ml_get_cursor(), start_vcol);
+	}
+#endif
+#ifdef FEAT_MBYTE
+	if (has_mbyte)
+	{
+	    del_char(FALSE);
+# ifdef FEAT_VREPLACE
+	    if (State & VREPLACE_FLAG)
+		orig_len = (int)STRLEN(ml_get_cursor());
+# endif
+	    replace_push(cc);
+	}
+	else
+#endif
+	{
+	    pchar_cursor(cc);
+#ifdef FEAT_VREPLACE
+	    if (State & VREPLACE_FLAG)
+		orig_len = (int)STRLEN(ml_get_cursor()) - 1;
+#endif
+	}
+	replace_pop_ins();
+
+#ifdef FEAT_VREPLACE
+	if (State & VREPLACE_FLAG)
+	{
+	    /* Get the number of screen cells used by the inserted characters */
+	    p = ml_get_cursor();
+	    ins_len = (int)STRLEN(p) - orig_len;
+	    vcol = start_vcol;
+	    for (i = 0; i < ins_len; ++i)
+	    {
+		vcol += chartabsize(p + i, vcol);
+#ifdef FEAT_MBYTE
+		i += (*mb_ptr2len)(p) - 1;
+#endif
+	    }
+	    vcol -= start_vcol;
+
+	    /* Delete spaces that were inserted after the cursor to keep the
+	     * text aligned. */
+	    curwin->w_cursor.col += ins_len;
+	    while (vcol > orig_vcols && gchar_cursor() == ' ')
+	    {
+		del_char(FALSE);
+		++orig_vcols;
+	    }
+	    curwin->w_cursor.col -= ins_len;
+	}
+#endif
+
+	/* mark the buffer as changed and prepare for displaying */
+	changed_bytes(curwin->w_cursor.lnum, curwin->w_cursor.col);
+    }
+    else if (cc == 0)
+	(void)del_char(FALSE);
+}
+
+#ifdef FEAT_CINDENT
+/*
+ * Return TRUE if C-indenting is on.
+ */
+    static int
+cindent_on()
+{
+    return (!p_paste && (curbuf->b_p_cin
+# ifdef FEAT_EVAL
+		    || *curbuf->b_p_inde != NUL
+# endif
+		    ));
+}
+#endif
+
+#if defined(FEAT_LISP) || defined(FEAT_CINDENT) || defined(PROTO)
+/*
+ * Re-indent the current line, based on the current contents of it and the
+ * surrounding lines. Fixing the cursor position seems really easy -- I'm very
+ * confused what all the part that handles Control-T is doing that I'm not.
+ * "get_the_indent" should be get_c_indent, get_expr_indent or get_lisp_indent.
+ */
+
+    void
+fixthisline(get_the_indent)
+    int (*get_the_indent) __ARGS((void));
+{
+    change_indent(INDENT_SET, get_the_indent(), FALSE, 0);
+    if (linewhite(curwin->w_cursor.lnum))
+	did_ai = TRUE;	    /* delete the indent if the line stays empty */
+}
+
+    void
+fix_indent()
+{
+    if (p_paste)
+	return;
+# ifdef FEAT_LISP
+    if (curbuf->b_p_lisp && curbuf->b_p_ai)
+	fixthisline(get_lisp_indent);
+# endif
+# if defined(FEAT_LISP) && defined(FEAT_CINDENT)
+    else
+# endif
+# ifdef FEAT_CINDENT
+	if (cindent_on())
+	    do_c_expr_indent();
+# endif
+}
+
+#endif
+
+#ifdef FEAT_CINDENT
+/*
+ * return TRUE if 'cinkeys' contains the key "keytyped",
+ * when == '*':	    Only if key is preceded with '*'	(indent before insert)
+ * when == '!':	    Only if key is prededed with '!'	(don't insert)
+ * when == ' ':	    Only if key is not preceded with '*'(indent afterwards)
+ *
+ * "keytyped" can have a few special values:
+ * KEY_OPEN_FORW
+ * KEY_OPEN_BACK
+ * KEY_COMPLETE	    just finished completion.
+ *
+ * If line_is_empty is TRUE accept keys with '0' before them.
+ */
+    int
+in_cinkeys(keytyped, when, line_is_empty)
+    int		keytyped;
+    int		when;
+    int		line_is_empty;
+{
+    char_u	*look;
+    int		try_match;
+    int		try_match_word;
+    char_u	*p;
+    char_u	*line;
+    int		icase;
+    int		i;
+
+#ifdef FEAT_EVAL
+    if (*curbuf->b_p_inde != NUL)
+	look = curbuf->b_p_indk;	/* 'indentexpr' set: use 'indentkeys' */
+    else
+#endif
+	look = curbuf->b_p_cink;	/* 'indentexpr' empty: use 'cinkeys' */
+    while (*look)
+    {
+	/*
+	 * Find out if we want to try a match with this key, depending on
+	 * 'when' and a '*' or '!' before the key.
+	 */
+	switch (when)
+	{
+	    case '*': try_match = (*look == '*'); break;
+	    case '!': try_match = (*look == '!'); break;
+	     default: try_match = (*look != '*'); break;
+	}
+	if (*look == '*' || *look == '!')
+	    ++look;
+
+	/*
+	 * If there is a '0', only accept a match if the line is empty.
+	 * But may still match when typing last char of a word.
+	 */
+	if (*look == '0')
+	{
+	    try_match_word = try_match;
+	    if (!line_is_empty)
+		try_match = FALSE;
+	    ++look;
+	}
+	else
+	    try_match_word = FALSE;
+
+	/*
+	 * does it look like a control character?
+	 */
+	if (*look == '^'
+#ifdef EBCDIC
+		&& (Ctrl_chr(look[1]) != 0)
+#else
+		&& look[1] >= '?' && look[1] <= '_'
+#endif
+		)
+	{
+	    if (try_match && keytyped == Ctrl_chr(look[1]))
+		return TRUE;
+	    look += 2;
+	}
+	/*
+	 * 'o' means "o" command, open forward.
+	 * 'O' means "O" command, open backward.
+	 */
+	else if (*look == 'o')
+	{
+	    if (try_match && keytyped == KEY_OPEN_FORW)
+		return TRUE;
+	    ++look;
+	}
+	else if (*look == 'O')
+	{
+	    if (try_match && keytyped == KEY_OPEN_BACK)
+		return TRUE;
+	    ++look;
+	}
+
+	/*
+	 * 'e' means to check for "else" at start of line and just before the
+	 * cursor.
+	 */
+	else if (*look == 'e')
+	{
+	    if (try_match && keytyped == 'e' && curwin->w_cursor.col >= 4)
+	    {
+		p = ml_get_curline();
+		if (skipwhite(p) == p + curwin->w_cursor.col - 4 &&
+			STRNCMP(p + curwin->w_cursor.col - 4, "else", 4) == 0)
+		    return TRUE;
+	    }
+	    ++look;
+	}
+
+	/*
+	 * ':' only causes an indent if it is at the end of a label or case
+	 * statement, or when it was before typing the ':' (to fix
+	 * class::method for C++).
+	 */
+	else if (*look == ':')
+	{
+	    if (try_match && keytyped == ':')
+	    {
+		p = ml_get_curline();
+		if (cin_iscase(p) || cin_isscopedecl(p) || cin_islabel(30))
+		    return TRUE;
+		if (curwin->w_cursor.col > 2
+			&& p[curwin->w_cursor.col - 1] == ':'
+			&& p[curwin->w_cursor.col - 2] == ':')
+		{
+		    p[curwin->w_cursor.col - 1] = ' ';
+		    i = (cin_iscase(p) || cin_isscopedecl(p)
+							  || cin_islabel(30));
+		    p = ml_get_curline();
+		    p[curwin->w_cursor.col - 1] = ':';
+		    if (i)
+			return TRUE;
+		}
+	    }
+	    ++look;
+	}
+
+
+	/*
+	 * Is it a key in <>, maybe?
+	 */
+	else if (*look == '<')
+	{
+	    if (try_match)
+	    {
+		/*
+		 * make up some named keys <o>, <O>, <e>, <0>, <>>, <<>, <*>,
+		 * <:> and <!> so that people can re-indent on o, O, e, 0, <,
+		 * >, *, : and ! keys if they really really want to.
+		 */
+		if (vim_strchr((char_u *)"<>!*oOe0:", look[1]) != NULL
+						       && keytyped == look[1])
+		    return TRUE;
+
+		if (keytyped == get_special_key_code(look + 1))
+		    return TRUE;
+	    }
+	    while (*look && *look != '>')
+		look++;
+	    while (*look == '>')
+		look++;
+	}
+
+	/*
+	 * Is it a word: "=word"?
+	 */
+	else if (*look == '=' && look[1] != ',' && look[1] != NUL)
+	{
+	    ++look;
+	    if (*look == '~')
+	    {
+		icase = TRUE;
+		++look;
+	    }
+	    else
+		icase = FALSE;
+	    p = vim_strchr(look, ',');
+	    if (p == NULL)
+		p = look + STRLEN(look);
+	    if ((try_match || try_match_word)
+		    && curwin->w_cursor.col >= (colnr_T)(p - look))
+	    {
+		int		match = FALSE;
+
+#ifdef FEAT_INS_EXPAND
+		if (keytyped == KEY_COMPLETE)
+		{
+		    char_u	*s;
+
+		    /* Just completed a word, check if it starts with "look".
+		     * search back for the start of a word. */
+		    line = ml_get_curline();
+# ifdef FEAT_MBYTE
+		    if (has_mbyte)
+		    {
+			char_u	*n;
+
+			for (s = line + curwin->w_cursor.col; s > line; s = n)
+			{
+			    n = mb_prevptr(line, s);
+			    if (!vim_iswordp(n))
+				break;
+			}
+		    }
+		    else
+# endif
+			for (s = line + curwin->w_cursor.col; s > line; --s)
+			    if (!vim_iswordc(s[-1]))
+				break;
+		    if (s + (p - look) <= line + curwin->w_cursor.col
+			    && (icase
+				? MB_STRNICMP(s, look, p - look)
+				: STRNCMP(s, look, p - look)) == 0)
+			match = TRUE;
+		}
+		else
+#endif
+		    /* TODO: multi-byte */
+		    if (keytyped == (int)p[-1] || (icase && keytyped < 256
+			 && TOLOWER_LOC(keytyped) == TOLOWER_LOC((int)p[-1])))
+		{
+		    line = ml_get_cursor();
+		    if ((curwin->w_cursor.col == (colnr_T)(p - look)
+				|| !vim_iswordc(line[-(p - look) - 1]))
+			    && (icase
+				? MB_STRNICMP(line - (p - look), look, p - look)
+				: STRNCMP(line - (p - look), look, p - look))
+									 == 0)
+			match = TRUE;
+		}
+		if (match && try_match_word && !try_match)
+		{
+		    /* "0=word": Check if there are only blanks before the
+		     * word. */
+		    line = ml_get_curline();
+		    if ((int)(skipwhite(line) - line) !=
+				     (int)(curwin->w_cursor.col - (p - look)))
+			match = FALSE;
+		}
+		if (match)
+		    return TRUE;
+	    }
+	    look = p;
+	}
+
+	/*
+	 * ok, it's a boring generic character.
+	 */
+	else
+	{
+	    if (try_match && *look == keytyped)
+		return TRUE;
+	    ++look;
+	}
+
+	/*
+	 * Skip over ", ".
+	 */
+	look = skip_to_option_part(look);
+    }
+    return FALSE;
+}
+#endif /* FEAT_CINDENT */
+
+#if defined(FEAT_RIGHTLEFT) || defined(PROTO)
+/*
+ * Map Hebrew keyboard when in hkmap mode.
+ */
+    int
+hkmap(c)
+    int c;
+{
+    if (p_hkmapp)   /* phonetic mapping, by Ilya Dogolazky */
+    {
+	enum {hALEF=0, BET, GIMEL, DALET, HEI, VAV, ZAIN, HET, TET, IUD,
+	    KAFsofit, hKAF, LAMED, MEMsofit, MEM, NUNsofit, NUN, SAMEH, AIN,
+	    PEIsofit, PEI, ZADIsofit, ZADI, KOF, RESH, hSHIN, TAV};
+	static char_u map[26] =
+	    {(char_u)hALEF/*a*/, (char_u)BET  /*b*/, (char_u)hKAF    /*c*/,
+	     (char_u)DALET/*d*/, (char_u)-1   /*e*/, (char_u)PEIsofit/*f*/,
+	     (char_u)GIMEL/*g*/, (char_u)HEI  /*h*/, (char_u)IUD     /*i*/,
+	     (char_u)HET  /*j*/, (char_u)KOF  /*k*/, (char_u)LAMED   /*l*/,
+	     (char_u)MEM  /*m*/, (char_u)NUN  /*n*/, (char_u)SAMEH   /*o*/,
+	     (char_u)PEI  /*p*/, (char_u)-1   /*q*/, (char_u)RESH    /*r*/,
+	     (char_u)ZAIN /*s*/, (char_u)TAV  /*t*/, (char_u)TET     /*u*/,
+	     (char_u)VAV  /*v*/, (char_u)hSHIN/*w*/, (char_u)-1      /*x*/,
+	     (char_u)AIN  /*y*/, (char_u)ZADI /*z*/};
+
+	if (c == 'N' || c == 'M' || c == 'P' || c == 'C' || c == 'Z')
+	    return (int)(map[CharOrd(c)] - 1 + p_aleph);
+							    /* '-1'='sofit' */
+	else if (c == 'x')
+	    return 'X';
+	else if (c == 'q')
+	    return '\''; /* {geresh}={'} */
+	else if (c == 246)
+	    return ' ';  /* \"o --> ' ' for a german keyboard */
+	else if (c == 228)
+	    return ' ';  /* \"a --> ' '      -- / --	       */
+	else if (c == 252)
+	    return ' ';  /* \"u --> ' '      -- / --	       */
+#ifdef EBCDIC
+	else if (islower(c))
+#else
+	/* NOTE: islower() does not do the right thing for us on Linux so we
+	 * do this the same was as 5.7 and previous, so it works correctly on
+	 * all systems.  Specifically, the e.g. Delete and Arrow keys are
+	 * munged and won't work if e.g. searching for Hebrew text.
+	 */
+	else if (c >= 'a' && c <= 'z')
+#endif
+	    return (int)(map[CharOrdLow(c)] + p_aleph);
+	else
+	    return c;
+    }
+    else
+    {
+	switch (c)
+	{
+	    case '`':	return ';';
+	    case '/':	return '.';
+	    case '\'':	return ',';
+	    case 'q':	return '/';
+	    case 'w':	return '\'';
+
+			/* Hebrew letters - set offset from 'a' */
+	    case ',':	c = '{'; break;
+	    case '.':	c = 'v'; break;
+	    case ';':	c = 't'; break;
+	    default: {
+			 static char str[] = "zqbcxlsjphmkwonu ydafe rig";
+
+#ifdef EBCDIC
+			 /* see note about islower() above */
+			 if (!islower(c))
+#else
+			 if (c < 'a' || c > 'z')
+#endif
+			     return c;
+			 c = str[CharOrdLow(c)];
+			 break;
+		     }
+	}
+
+	return (int)(CharOrdLow(c) + p_aleph);
+    }
+}
+#endif
+
+    static void
+ins_reg()
+{
+    int		need_redraw = FALSE;
+    int		regname;
+    int		literally = 0;
+#ifdef FEAT_VISUAL
+    int		vis_active = VIsual_active;
+#endif
+
+    /*
+     * If we are going to wait for a character, show a '"'.
+     */
+    pc_status = PC_STATUS_UNSET;
+    if (redrawing() && !char_avail())
+    {
+	/* may need to redraw when no more chars available now */
+	ins_redraw(FALSE);
+
+	edit_putchar('"', TRUE);
+#ifdef FEAT_CMDL_INFO
+	add_to_showcmd_c(Ctrl_R);
+#endif
+    }
+
+#ifdef USE_ON_FLY_SCROLL
+    dont_scroll = TRUE;		/* disallow scrolling here */
+#endif
+
+    /*
+     * Don't map the register name. This also prevents the mode message to be
+     * deleted when ESC is hit.
+     */
+    ++no_mapping;
+    regname = safe_vgetc();
+#ifdef FEAT_LANGMAP
+    LANGMAP_ADJUST(regname, TRUE);
+#endif
+    if (regname == Ctrl_R || regname == Ctrl_O || regname == Ctrl_P)
+    {
+	/* Get a third key for literal register insertion */
+	literally = regname;
+#ifdef FEAT_CMDL_INFO
+	add_to_showcmd_c(literally);
+#endif
+	regname = safe_vgetc();
+#ifdef FEAT_LANGMAP
+	LANGMAP_ADJUST(regname, TRUE);
+#endif
+    }
+    --no_mapping;
+
+#ifdef FEAT_EVAL
+    /*
+     * Don't call u_sync() while getting the expression,
+     * evaluating it or giving an error message for it!
+     */
+    ++no_u_sync;
+    if (regname == '=')
+    {
+# ifdef USE_IM_CONTROL
+	int	im_on = im_get_status();
+# endif
+	regname = get_expr_register();
+# ifdef USE_IM_CONTROL
+	/* Restore the Input Method. */
+	if (im_on)
+	    im_set_active(TRUE);
+# endif
+    }
+    if (regname == NUL || !valid_yank_reg(regname, FALSE))
+    {
+	vim_beep();
+	need_redraw = TRUE;	/* remove the '"' */
+    }
+    else
+    {
+#endif
+	if (literally == Ctrl_O || literally == Ctrl_P)
+	{
+	    /* Append the command to the redo buffer. */
+	    AppendCharToRedobuff(Ctrl_R);
+	    AppendCharToRedobuff(literally);
+	    AppendCharToRedobuff(regname);
+
+	    do_put(regname, BACKWARD, 1L,
+		 (literally == Ctrl_P ? PUT_FIXINDENT : 0) | PUT_CURSEND);
+	}
+	else if (insert_reg(regname, literally) == FAIL)
+	{
+	    vim_beep();
+	    need_redraw = TRUE;	/* remove the '"' */
+	}
+	else if (stop_insert_mode)
+	    /* When the '=' register was used and a function was invoked that
+	     * did ":stopinsert" then stuff_empty() returns FALSE but we won't
+	     * insert anything, need to remove the '"' */
+	    need_redraw = TRUE;
+
+#ifdef FEAT_EVAL
+    }
+    --no_u_sync;
+#endif
+#ifdef FEAT_CMDL_INFO
+    clear_showcmd();
+#endif
+
+    /* If the inserted register is empty, we need to remove the '"' */
+    if (need_redraw || stuff_empty())
+	edit_unputchar();
+
+#ifdef FEAT_VISUAL
+    /* Disallow starting Visual mode here, would get a weird mode. */
+    if (!vis_active && VIsual_active)
+	end_visual_mode();
+#endif
+}
+
+/*
+ * CTRL-G commands in Insert mode.
+ */
+    static void
+ins_ctrl_g()
+{
+    int		c;
+
+#ifdef FEAT_INS_EXPAND
+    /* Right after CTRL-X the cursor will be after the ruler. */
+    setcursor();
+#endif
+
+    /*
+     * Don't map the second key. This also prevents the mode message to be
+     * deleted when ESC is hit.
+     */
+    ++no_mapping;
+    c = safe_vgetc();
+    --no_mapping;
+    switch (c)
+    {
+	/* CTRL-G k and CTRL-G <Up>: cursor up to Insstart.col */
+	case K_UP:
+	case Ctrl_K:
+	case 'k': ins_up(TRUE);
+		  break;
+
+	/* CTRL-G j and CTRL-G <Down>: cursor down to Insstart.col */
+	case K_DOWN:
+	case Ctrl_J:
+	case 'j': ins_down(TRUE);
+		  break;
+
+	/* CTRL-G u: start new undoable edit */
+	case 'u': u_sync(TRUE);
+		  ins_need_undo = TRUE;
+
+		  /* Need to reset Insstart, esp. because a BS that joins
+		   * a line to the previous one must save for undo. */
+		  Insstart = curwin->w_cursor;
+		  break;
+
+	/* Unknown CTRL-G command, reserved for future expansion. */
+	default:  vim_beep();
+    }
+}
+
+/*
+ * CTRL-^ in Insert mode.
+ */
+    static void
+ins_ctrl_hat()
+{
+    if (map_to_exists_mode((char_u *)"", LANGMAP, FALSE))
+    {
+	/* ":lmap" mappings exists, Toggle use of ":lmap" mappings. */
+	if (State & LANGMAP)
+	{
+	    curbuf->b_p_iminsert = B_IMODE_NONE;
+	    State &= ~LANGMAP;
+	}
+	else
+	{
+	    curbuf->b_p_iminsert = B_IMODE_LMAP;
+	    State |= LANGMAP;
+#ifdef USE_IM_CONTROL
+	    im_set_active(FALSE);
+#endif
+	}
+    }
+#ifdef USE_IM_CONTROL
+    else
+    {
+	/* There are no ":lmap" mappings, toggle IM */
+	if (im_get_status())
+	{
+	    curbuf->b_p_iminsert = B_IMODE_NONE;
+	    im_set_active(FALSE);
+	}
+	else
+	{
+	    curbuf->b_p_iminsert = B_IMODE_IM;
+	    State &= ~LANGMAP;
+	    im_set_active(TRUE);
+	}
+    }
+#endif
+    set_iminsert_global();
+    showmode();
+#ifdef FEAT_GUI
+    /* may show different cursor shape or color */
+    if (gui.in_use)
+	gui_update_cursor(TRUE, FALSE);
+#endif
+#if defined(FEAT_WINDOWS) && defined(FEAT_KEYMAP)
+    /* Show/unshow value of 'keymap' in status lines. */
+    status_redraw_curbuf();
+#endif
+}
+
+/*
+ * Handle ESC in insert mode.
+ * Returns TRUE when leaving insert mode, FALSE when going to repeat the
+ * insert.
+ */
+    static int
+ins_esc(count, cmdchar, nomove)
+    long	*count;
+    int		cmdchar;
+    int		nomove;	    /* don't move cursor */
+{
+    int		temp;
+    static int	disabled_redraw = FALSE;
+
+#ifdef FEAT_SPELL
+    check_spell_redraw();
+#endif
+#if defined(FEAT_HANGULIN)
+# if defined(ESC_CHG_TO_ENG_MODE)
+    hangul_input_state_set(0);
+# endif
+    if (composing_hangul)
+    {
+	push_raw_key(composing_hangul_buffer, 2);
+	composing_hangul = 0;
+    }
+#endif
+
+    temp = curwin->w_cursor.col;
+    if (disabled_redraw)
+    {
+	--RedrawingDisabled;
+	disabled_redraw = FALSE;
+    }
+    if (!arrow_used)
+    {
+	/*
+	 * Don't append the ESC for "r<CR>" and "grx".
+	 * When 'insertmode' is set only CTRL-L stops Insert mode.  Needed for
+	 * when "count" is non-zero.
+	 */
+	if (cmdchar != 'r' && cmdchar != 'v')
+	    AppendToRedobuff(p_im ? (char_u *)"\014" : ESC_STR);
+
+	/*
+	 * Repeating insert may take a long time.  Check for
+	 * interrupt now and then.
+	 */
+	if (*count > 0)
+	{
+	    line_breakcheck();
+	    if (got_int)
+		*count = 0;
+	}
+
+	if (--*count > 0)	/* repeat what was typed */
+	{
+	    /* Vi repeats the insert without replacing characters. */
+	    if (vim_strchr(p_cpo, CPO_REPLCNT) != NULL)
+		State &= ~REPLACE_FLAG;
+
+	    (void)start_redo_ins();
+	    if (cmdchar == 'r' || cmdchar == 'v')
+		stuffReadbuff(ESC_STR);	/* no ESC in redo buffer */
+	    ++RedrawingDisabled;
+	    disabled_redraw = TRUE;
+	    return FALSE;	/* repeat the insert */
+	}
+	stop_insert(&curwin->w_cursor, TRUE);
+	undisplay_dollar();
+    }
+
+    /* When an autoindent was removed, curswant stays after the
+     * indent */
+    if (restart_edit == NUL && (colnr_T)temp == curwin->w_cursor.col)
+	curwin->w_set_curswant = TRUE;
+
+    /* Remember the last Insert position in the '^ mark. */
+    if (!cmdmod.keepjumps)
+	curbuf->b_last_insert = curwin->w_cursor;
+
+    /*
+     * The cursor should end up on the last inserted character.
+     * Don't do it for CTRL-O, unless past the end of the line.
+     */
+    if (!nomove
+	    && (curwin->w_cursor.col != 0
+#ifdef FEAT_VIRTUALEDIT
+		|| curwin->w_cursor.coladd > 0
+#endif
+	       )
+	    && (restart_edit == NUL
+		   || (gchar_cursor() == NUL
+#ifdef FEAT_VISUAL
+		       && !VIsual_active
+#endif
+		      ))
+#ifdef FEAT_RIGHTLEFT
+	    && !revins_on
+#endif
+				      )
+    {
+#ifdef FEAT_VIRTUALEDIT
+	if (curwin->w_cursor.coladd > 0 || ve_flags == VE_ALL)
+	{
+	    oneleft();
+	    if (restart_edit != NUL)
+		++curwin->w_cursor.coladd;
+	}
+	else
+#endif
+	{
+	    --curwin->w_cursor.col;
+#ifdef FEAT_MBYTE
+	    /* Correct cursor for multi-byte character. */
+	    if (has_mbyte)
+		mb_adjust_cursor();
+#endif
+	}
+    }
+
+#ifdef USE_IM_CONTROL
+    /* Disable IM to allow typing English directly for Normal mode commands.
+     * When ":lmap" is enabled don't change 'iminsert' (IM can be enabled as
+     * well). */
+    if (!(State & LANGMAP))
+	im_save_status(&curbuf->b_p_iminsert);
+    im_set_active(FALSE);
+#endif
+
+    State = NORMAL;
+    /* need to position cursor again (e.g. when on a TAB ) */
+    changed_cline_bef_curs();
+
+#ifdef FEAT_MOUSE
+    setmouse();
+#endif
+#ifdef CURSOR_SHAPE
+    ui_cursor_shape();		/* may show different cursor shape */
+#endif
+
+    /*
+     * When recording or for CTRL-O, need to display the new mode.
+     * Otherwise remove the mode message.
+     */
+    if (Recording || restart_edit != NUL)
+	showmode();
+    else if (p_smd)
+	MSG("");
+
+    return TRUE;	    /* exit Insert mode */
+}
+
+#ifdef FEAT_RIGHTLEFT
+/*
+ * Toggle language: hkmap and revins_on.
+ * Move to end of reverse inserted text.
+ */
+    static void
+ins_ctrl_()
+{
+    if (revins_on && revins_chars && revins_scol >= 0)
+    {
+	while (gchar_cursor() != NUL && revins_chars--)
+	    ++curwin->w_cursor.col;
+    }
+    p_ri = !p_ri;
+    revins_on = (State == INSERT && p_ri);
+    if (revins_on)
+    {
+	revins_scol = curwin->w_cursor.col;
+	revins_legal++;
+	revins_chars = 0;
+	undisplay_dollar();
+    }
+    else
+	revins_scol = -1;
+#ifdef FEAT_FKMAP
+    if (p_altkeymap)
+    {
+	/*
+	 * to be consistent also for redo command, using '.'
+	 * set arrow_used to true and stop it - causing to redo
+	 * characters entered in one mode (normal/reverse insert).
+	 */
+	arrow_used = TRUE;
+	(void)stop_arrow();
+	p_fkmap = curwin->w_p_rl ^ p_ri;
+	if (p_fkmap && p_ri)
+	    State = INSERT;
+    }
+    else
+#endif
+	p_hkmap = curwin->w_p_rl ^ p_ri;    /* be consistent! */
+    showmode();
+}
+#endif
+
+#ifdef FEAT_VISUAL
+/*
+ * If 'keymodel' contains "startsel", may start selection.
+ * Returns TRUE when a CTRL-O and other keys stuffed.
+ */
+    static int
+ins_start_select(c)
+    int		c;
+{
+    if (km_startsel)
+	switch (c)
+	{
+	    case K_KHOME:
+	    case K_KEND:
+	    case K_PAGEUP:
+	    case K_KPAGEUP:
+	    case K_PAGEDOWN:
+	    case K_KPAGEDOWN:
+# ifdef MACOS
+	    case K_LEFT:
+	    case K_RIGHT:
+	    case K_UP:
+	    case K_DOWN:
+	    case K_END:
+	    case K_HOME:
+# endif
+		if (!(mod_mask & MOD_MASK_SHIFT))
+		    break;
+		/* FALLTHROUGH */
+	    case K_S_LEFT:
+	    case K_S_RIGHT:
+	    case K_S_UP:
+	    case K_S_DOWN:
+	    case K_S_END:
+	    case K_S_HOME:
+		/* Start selection right away, the cursor can move with
+		 * CTRL-O when beyond the end of the line. */
+		start_selection();
+
+		/* Execute the key in (insert) Select mode. */
+		stuffcharReadbuff(Ctrl_O);
+		if (mod_mask)
+		{
+		    char_u	    buf[4];
+
+		    buf[0] = K_SPECIAL;
+		    buf[1] = KS_MODIFIER;
+		    buf[2] = mod_mask;
+		    buf[3] = NUL;
+		    stuffReadbuff(buf);
+		}
+		stuffcharReadbuff(c);
+		return TRUE;
+	}
+    return FALSE;
+}
+#endif
+
+/*
+ * <Insert> key in Insert mode: toggle insert/remplace mode.
+ */
+    static void
+ins_insert(replaceState)
+    int	    replaceState;
+{
+#ifdef FEAT_FKMAP
+    if (p_fkmap && p_ri)
+    {
+	beep_flush();
+	EMSG(farsi_text_3);	/* encoded in Farsi */
+	return;
+    }
+#endif
+
+#ifdef FEAT_AUTOCMD
+# ifdef FEAT_EVAL
+    set_vim_var_string(VV_INSERTMODE,
+		   (char_u *)((State & REPLACE_FLAG) ? "i" :
+#  ifdef FEAT_VREPLACE
+			    replaceState == VREPLACE ? "v" :
+#  endif
+			    "r"), 1);
+# endif
+    apply_autocmds(EVENT_INSERTCHANGE, NULL, NULL, FALSE, curbuf);
+#endif
+    if (State & REPLACE_FLAG)
+	State = INSERT | (State & LANGMAP);
+    else
+	State = replaceState | (State & LANGMAP);
+    AppendCharToRedobuff(K_INS);
+    showmode();
+#ifdef CURSOR_SHAPE
+    ui_cursor_shape();		/* may show different cursor shape */
+#endif
+}
+
+/*
+ * Pressed CTRL-O in Insert mode.
+ */
+    static void
+ins_ctrl_o()
+{
+#ifdef FEAT_VREPLACE
+    if (State & VREPLACE_FLAG)
+	restart_edit = 'V';
+    else
+#endif
+	if (State & REPLACE_FLAG)
+	restart_edit = 'R';
+    else
+	restart_edit = 'I';
+#ifdef FEAT_VIRTUALEDIT
+    if (virtual_active())
+	ins_at_eol = FALSE;	/* cursor always keeps its column */
+    else
+#endif
+	ins_at_eol = (gchar_cursor() == NUL);
+}
+
+/*
+ * If the cursor is on an indent, ^T/^D insert/delete one
+ * shiftwidth.	Otherwise ^T/^D behave like a "<<" or ">>".
+ * Always round the indent to 'shiftwith', this is compatible
+ * with vi.  But vi only supports ^T and ^D after an
+ * autoindent, we support it everywhere.
+ */
+    static void
+ins_shift(c, lastc)
+    int	    c;
+    int	    lastc;
+{
+    if (stop_arrow() == FAIL)
+	return;
+    AppendCharToRedobuff(c);
+
+    /*
+     * 0^D and ^^D: remove all indent.
+     */
+    if ((lastc == '0' || lastc == '^') && curwin->w_cursor.col)
+    {
+	--curwin->w_cursor.col;
+	(void)del_char(FALSE);		/* delete the '^' or '0' */
+	/* In Replace mode, restore the characters that '^' or '0' replaced. */
+	if (State & REPLACE_FLAG)
+	    replace_pop_ins();
+	if (lastc == '^')
+	    old_indent = get_indent();	/* remember curr. indent */
+	change_indent(INDENT_SET, 0, TRUE, 0);
+    }
+    else
+	change_indent(c == Ctrl_D ? INDENT_DEC : INDENT_INC, 0, TRUE, 0);
+
+    if (did_ai && *skipwhite(ml_get_curline()) != NUL)
+	did_ai = FALSE;
+#ifdef FEAT_SMARTINDENT
+    did_si = FALSE;
+    can_si = FALSE;
+    can_si_back = FALSE;
+#endif
+#ifdef FEAT_CINDENT
+    can_cindent = FALSE;	/* no cindenting after ^D or ^T */
+#endif
+}
+
+    static void
+ins_del()
+{
+    int	    temp;
+
+    if (stop_arrow() == FAIL)
+	return;
+    if (gchar_cursor() == NUL)		/* delete newline */
+    {
+	temp = curwin->w_cursor.col;
+	if (!can_bs(BS_EOL)		/* only if "eol" included */
+		|| u_save((linenr_T)(curwin->w_cursor.lnum - 1),
+		    (linenr_T)(curwin->w_cursor.lnum + 2)) == FAIL
+		|| do_join(FALSE) == FAIL)
+	    vim_beep();
+	else
+	    curwin->w_cursor.col = temp;
+    }
+    else if (del_char(FALSE) == FAIL)	/* delete char under cursor */
+	vim_beep();
+    did_ai = FALSE;
+#ifdef FEAT_SMARTINDENT
+    did_si = FALSE;
+    can_si = FALSE;
+    can_si_back = FALSE;
+#endif
+    AppendCharToRedobuff(K_DEL);
+}
+
+/*
+ * Handle Backspace, delete-word and delete-line in Insert mode.
+ * Return TRUE when backspace was actually used.
+ */
+    static int
+ins_bs(c, mode, inserted_space_p)
+    int		c;
+    int		mode;
+    int		*inserted_space_p;
+{
+    linenr_T	lnum;
+    int		cc;
+    int		temp = 0;	    /* init for GCC */
+    colnr_T	mincol;
+    int		did_backspace = FALSE;
+    int		in_indent;
+    int		oldState;
+#ifdef FEAT_MBYTE
+    int		cpc[MAX_MCO];	    /* composing characters */
+#endif
+
+    /*
+     * can't delete anything in an empty file
+     * can't backup past first character in buffer
+     * can't backup past starting point unless 'backspace' > 1
+     * can backup to a previous line if 'backspace' == 0
+     */
+    if (       bufempty()
+	    || (
+#ifdef FEAT_RIGHTLEFT
+		!revins_on &&
+#endif
+		((curwin->w_cursor.lnum == 1 && curwin->w_cursor.col == 0)
+		    || (!can_bs(BS_START)
+			&& (arrow_used
+			    || (curwin->w_cursor.lnum == Insstart.lnum
+				&& curwin->w_cursor.col <= Insstart.col)))
+		    || (!can_bs(BS_INDENT) && !arrow_used && ai_col > 0
+					 && curwin->w_cursor.col <= ai_col)
+		    || (!can_bs(BS_EOL) && curwin->w_cursor.col == 0))))
+    {
+	vim_beep();
+	return FALSE;
+    }
+
+    if (stop_arrow() == FAIL)
+	return FALSE;
+    in_indent = inindent(0);
+#ifdef FEAT_CINDENT
+    if (in_indent)
+	can_cindent = FALSE;
+#endif
+#ifdef FEAT_COMMENTS
+    end_comment_pending = NUL;	/* After BS, don't auto-end comment */
+#endif
+#ifdef FEAT_RIGHTLEFT
+    if (revins_on)	    /* put cursor after last inserted char */
+	inc_cursor();
+#endif
+
+#ifdef FEAT_VIRTUALEDIT
+    /* Virtualedit:
+     *	BACKSPACE_CHAR eats a virtual space
+     *	BACKSPACE_WORD eats all coladd
+     *	BACKSPACE_LINE eats all coladd and keeps going
+     */
+    if (curwin->w_cursor.coladd > 0)
+    {
+	if (mode == BACKSPACE_CHAR)
+	{
+	    --curwin->w_cursor.coladd;
+	    return TRUE;
+	}
+	if (mode == BACKSPACE_WORD)
+	{
+	    curwin->w_cursor.coladd = 0;
+	    return TRUE;
+	}
+	curwin->w_cursor.coladd = 0;
+    }
+#endif
+
+    /*
+     * delete newline!
+     */
+    if (curwin->w_cursor.col == 0)
+    {
+	lnum = Insstart.lnum;
+	if (curwin->w_cursor.lnum == Insstart.lnum
+#ifdef FEAT_RIGHTLEFT
+			|| revins_on
+#endif
+				    )
+	{
+	    if (u_save((linenr_T)(curwin->w_cursor.lnum - 2),
+			       (linenr_T)(curwin->w_cursor.lnum + 1)) == FAIL)
+		return FALSE;
+	    --Insstart.lnum;
+	    Insstart.col = MAXCOL;
+	}
+	/*
+	 * In replace mode:
+	 * cc < 0: NL was inserted, delete it
+	 * cc >= 0: NL was replaced, put original characters back
+	 */
+	cc = -1;
+	if (State & REPLACE_FLAG)
+	    cc = replace_pop();	    /* returns -1 if NL was inserted */
+	/*
+	 * In replace mode, in the line we started replacing, we only move the
+	 * cursor.
+	 */
+	if ((State & REPLACE_FLAG) && curwin->w_cursor.lnum <= lnum)
+	{
+	    dec_cursor();
+	}
+	else
+	{
+#ifdef FEAT_VREPLACE
+	    if (!(State & VREPLACE_FLAG)
+				   || curwin->w_cursor.lnum > orig_line_count)
+#endif
+	    {
+		temp = gchar_cursor();	/* remember current char */
+		--curwin->w_cursor.lnum;
+
+		/* When "aw" is in 'formatoptions' we must delete the space at
+		 * the end of the line, otherwise the line will be broken
+		 * again when auto-formatting. */
+		if (has_format_option(FO_AUTO)
+					   && has_format_option(FO_WHITE_PAR))
+		{
+		    char_u  *ptr = ml_get_buf(curbuf, curwin->w_cursor.lnum,
+									TRUE);
+		    int	    len;
+
+		    len = (int)STRLEN(ptr);
+		    if (len > 0 && ptr[len - 1] == ' ')
+			ptr[len - 1] = NUL;
+		}
+
+		(void)do_join(FALSE);
+		if (temp == NUL && gchar_cursor() != NUL)
+		    inc_cursor();
+	    }
+#ifdef FEAT_VREPLACE
+	    else
+		dec_cursor();
+#endif
+
+	    /*
+	     * In REPLACE mode we have to put back the text that was replaced
+	     * by the NL. On the replace stack is first a NUL-terminated
+	     * sequence of characters that were deleted and then the
+	     * characters that NL replaced.
+	     */
+	    if (State & REPLACE_FLAG)
+	    {
+		/*
+		 * Do the next ins_char() in NORMAL state, to
+		 * prevent ins_char() from replacing characters and
+		 * avoiding showmatch().
+		 */
+		oldState = State;
+		State = NORMAL;
+		/*
+		 * restore characters (blanks) deleted after cursor
+		 */
+		while (cc > 0)
+		{
+		    temp = curwin->w_cursor.col;
+#ifdef FEAT_MBYTE
+		    mb_replace_pop_ins(cc);
+#else
+		    ins_char(cc);
+#endif
+		    curwin->w_cursor.col = temp;
+		    cc = replace_pop();
+		}
+		/* restore the characters that NL replaced */
+		replace_pop_ins();
+		State = oldState;
+	    }
+	}
+	did_ai = FALSE;
+    }
+    else
+    {
+	/*
+	 * Delete character(s) before the cursor.
+	 */
+#ifdef FEAT_RIGHTLEFT
+	if (revins_on)		/* put cursor on last inserted char */
+	    dec_cursor();
+#endif
+	mincol = 0;
+						/* keep indent */
+	if (mode == BACKSPACE_LINE
+		&& (curbuf->b_p_ai
+#ifdef FEAT_CINDENT
+                    || cindent_on()
+#endif
+		   )
+#ifdef FEAT_RIGHTLEFT
+		&& !revins_on
+#endif
+			    )
+	{
+	    temp = curwin->w_cursor.col;
+	    beginline(BL_WHITE);
+	    if (curwin->w_cursor.col < (colnr_T)temp)
+		mincol = curwin->w_cursor.col;
+	    curwin->w_cursor.col = temp;
+	}
+
+	/*
+	 * Handle deleting one 'shiftwidth' or 'softtabstop'.
+	 */
+	if (	   mode == BACKSPACE_CHAR
+		&& ((p_sta && in_indent)
+		    || (curbuf->b_p_sts != 0
+			&& (*(ml_get_cursor() - 1) == TAB
+			    || (*(ml_get_cursor() - 1) == ' '
+				&& (!*inserted_space_p
+				    || arrow_used))))))
+	{
+	    int		ts;
+	    colnr_T	vcol;
+	    colnr_T	want_vcol;
+#if 0
+	    int		extra = 0;
+#endif
+
+	    *inserted_space_p = FALSE;
+	    if (p_sta && in_indent)
+		ts = curbuf->b_p_sw;
+	    else
+		ts = curbuf->b_p_sts;
+	    /* Compute the virtual column where we want to be.  Since
+	     * 'showbreak' may get in the way, need to get the last column of
+	     * the previous character. */
+	    getvcol(curwin, &curwin->w_cursor, &vcol, NULL, NULL);
+	    dec_cursor();
+	    getvcol(curwin, &curwin->w_cursor, NULL, NULL, &want_vcol);
+	    inc_cursor();
+	    want_vcol = (want_vcol / ts) * ts;
+
+	    /* delete characters until we are at or before want_vcol */
+	    while (vcol > want_vcol
+		    && (cc = *(ml_get_cursor() - 1), vim_iswhite(cc)))
+	    {
+		dec_cursor();
+		getvcol(curwin, &curwin->w_cursor, &vcol, NULL, NULL);
+		if (State & REPLACE_FLAG)
+		{
+		    /* Don't delete characters before the insert point when in
+		     * Replace mode */
+		    if (curwin->w_cursor.lnum != Insstart.lnum
+			    || curwin->w_cursor.col >= Insstart.col)
+		    {
+#if 0	/* what was this for?  It causes problems when sw != ts. */
+			if (State == REPLACE && (int)vcol < want_vcol)
+			{
+			    (void)del_char(FALSE);
+			    extra = 2;	/* don't pop too much */
+			}
+			else
+#endif
+			    replace_do_bs();
+		    }
+		}
+		else
+		    (void)del_char(FALSE);
+	    }
+
+	    /* insert extra spaces until we are at want_vcol */
+	    while (vcol < want_vcol)
+	    {
+		/* Remember the first char we inserted */
+		if (curwin->w_cursor.lnum == Insstart.lnum
+				   && curwin->w_cursor.col < Insstart.col)
+		    Insstart.col = curwin->w_cursor.col;
+
+#ifdef FEAT_VREPLACE
+		if (State & VREPLACE_FLAG)
+		    ins_char(' ');
+		else
+#endif
+		{
+		    ins_str((char_u *)" ");
+		    if ((State & REPLACE_FLAG) /* && extra <= 1 */)
+		    {
+#if 0
+			if (extra)
+			    replace_push_off(NUL);
+			else
+#endif
+			    replace_push(NUL);
+		    }
+#if 0
+		    if (extra == 2)
+			extra = 1;
+#endif
+		}
+		getvcol(curwin, &curwin->w_cursor, &vcol, NULL, NULL);
+	    }
+	}
+
+	/*
+	 * Delete upto starting point, start of line or previous word.
+	 */
+	else do
+	{
+#ifdef FEAT_RIGHTLEFT
+	    if (!revins_on) /* put cursor on char to be deleted */
+#endif
+		dec_cursor();
+
+	    /* start of word? */
+	    if (mode == BACKSPACE_WORD && !vim_isspace(gchar_cursor()))
+	    {
+		mode = BACKSPACE_WORD_NOT_SPACE;
+		temp = vim_iswordc(gchar_cursor());
+	    }
+	    /* end of word? */
+	    else if (mode == BACKSPACE_WORD_NOT_SPACE
+		    && (vim_isspace(cc = gchar_cursor())
+			    || vim_iswordc(cc) != temp))
+	    {
+#ifdef FEAT_RIGHTLEFT
+		if (!revins_on)
+#endif
+		    inc_cursor();
+#ifdef FEAT_RIGHTLEFT
+		else if (State & REPLACE_FLAG)
+		    dec_cursor();
+#endif
+		break;
+	    }
+	    if (State & REPLACE_FLAG)
+		replace_do_bs();
+	    else
+	    {
+#ifdef FEAT_MBYTE
+		if (enc_utf8 && p_deco)
+		    (void)utfc_ptr2char(ml_get_cursor(), cpc);
+#endif
+		(void)del_char(FALSE);
+#ifdef FEAT_MBYTE
+		/*
+		 * If there are combining characters and 'delcombine' is set
+		 * move the cursor back.  Don't back up before the base
+		 * character.
+		 */
+		if (enc_utf8 && p_deco && cpc[0] != NUL)
+		    inc_cursor();
+#endif
+#ifdef FEAT_RIGHTLEFT
+		if (revins_chars)
+		{
+		    revins_chars--;
+		    revins_legal++;
+		}
+		if (revins_on && gchar_cursor() == NUL)
+		    break;
+#endif
+	    }
+	    /* Just a single backspace?: */
+	    if (mode == BACKSPACE_CHAR)
+		break;
+	} while (
+#ifdef FEAT_RIGHTLEFT
+		revins_on ||
+#endif
+		(curwin->w_cursor.col > mincol
+		 && (curwin->w_cursor.lnum != Insstart.lnum
+		     || curwin->w_cursor.col != Insstart.col)));
+	did_backspace = TRUE;
+    }
+#ifdef FEAT_SMARTINDENT
+    did_si = FALSE;
+    can_si = FALSE;
+    can_si_back = FALSE;
+#endif
+    if (curwin->w_cursor.col <= 1)
+	did_ai = FALSE;
+    /*
+     * It's a little strange to put backspaces into the redo
+     * buffer, but it makes auto-indent a lot easier to deal
+     * with.
+     */
+    AppendCharToRedobuff(c);
+
+    /* If deleted before the insertion point, adjust it */
+    if (curwin->w_cursor.lnum == Insstart.lnum
+				       && curwin->w_cursor.col < Insstart.col)
+	Insstart.col = curwin->w_cursor.col;
+
+    /* vi behaviour: the cursor moves backward but the character that
+     *		     was there remains visible
+     * Vim behaviour: the cursor moves backward and the character that
+     *		      was there is erased from the screen.
+     * We can emulate the vi behaviour by pretending there is a dollar
+     * displayed even when there isn't.
+     *  --pkv Sun Jan 19 01:56:40 EST 2003 */
+    if (vim_strchr(p_cpo, CPO_BACKSPACE) != NULL && dollar_vcol == 0)
+	dollar_vcol = curwin->w_virtcol;
+
+    return did_backspace;
+}
+
+#ifdef FEAT_MOUSE
+    static void
+ins_mouse(c)
+    int	    c;
+{
+    pos_T	tpos;
+    win_T	*old_curwin = curwin;
+
+# ifdef FEAT_GUI
+    /* When GUI is active, also move/paste when 'mouse' is empty */
+    if (!gui.in_use)
+# endif
+	if (!mouse_has(MOUSE_INSERT))
+	    return;
+
+    undisplay_dollar();
+    tpos = curwin->w_cursor;
+    if (do_mouse(NULL, c, BACKWARD, 1L, 0))
+    {
+#ifdef FEAT_WINDOWS
+	win_T	*new_curwin = curwin;
+
+	if (curwin != old_curwin && win_valid(old_curwin))
+	{
+	    /* Mouse took us to another window.  We need to go back to the
+	     * previous one to stop insert there properly. */
+	    curwin = old_curwin;
+	    curbuf = curwin->w_buffer;
+	}
+#endif
+	start_arrow(curwin == old_curwin ? &tpos : NULL);
+#ifdef FEAT_WINDOWS
+	if (curwin != new_curwin && win_valid(new_curwin))
+	{
+	    curwin = new_curwin;
+	    curbuf = curwin->w_buffer;
+	}
+#endif
+# ifdef FEAT_CINDENT
+	can_cindent = TRUE;
+# endif
+    }
+
+#ifdef FEAT_WINDOWS
+    /* redraw status lines (in case another window became active) */
+    redraw_statuslines();
+#endif
+}
+
+    static void
+ins_mousescroll(up)
+    int		up;
+{
+    pos_T	tpos;
+# if defined(FEAT_GUI) && defined(FEAT_WINDOWS)
+    win_T	*old_curwin;
+# endif
+
+    tpos = curwin->w_cursor;
+
+# if defined(FEAT_GUI) && defined(FEAT_WINDOWS)
+    old_curwin = curwin;
+
+    /* Currently the mouse coordinates are only known in the GUI. */
+    if (gui.in_use && mouse_row >= 0 && mouse_col >= 0)
+    {
+	int row, col;
+
+	row = mouse_row;
+	col = mouse_col;
+
+	/* find the window at the pointer coordinates */
+	curwin = mouse_find_win(&row, &col);
+	curbuf = curwin->w_buffer;
+    }
+    if (curwin == old_curwin)
+# endif
+	undisplay_dollar();
+
+    if (mod_mask & (MOD_MASK_SHIFT | MOD_MASK_CTRL))
+	scroll_redraw(up, (long)(curwin->w_botline - curwin->w_topline));
+    else
+	scroll_redraw(up, 3L);
+
+# if defined(FEAT_GUI) && defined(FEAT_WINDOWS)
+    curwin->w_redr_status = TRUE;
+
+    curwin = old_curwin;
+    curbuf = curwin->w_buffer;
+# endif
+
+    if (!equalpos(curwin->w_cursor, tpos))
+    {
+	start_arrow(&tpos);
+# ifdef FEAT_CINDENT
+	can_cindent = TRUE;
+# endif
+    }
+}
+#endif
+
+#if defined(FEAT_GUI_TABLINE) || defined(PROTO)
+    static void
+ins_tabline(c)
+    int		c;
+{
+    /* We will be leaving the current window, unless closing another tab. */
+    if (c != K_TABMENU || current_tabmenu != TABLINE_MENU_CLOSE
+		|| (current_tab != 0 && current_tab != tabpage_index(curtab)))
+    {
+	undisplay_dollar();
+	start_arrow(&curwin->w_cursor);
+# ifdef FEAT_CINDENT
+	can_cindent = TRUE;
+# endif
+    }
+
+    if (c == K_TABLINE)
+	goto_tabpage(current_tab);
+    else
+    {
+	handle_tabmenu();
+	redraw_statuslines();	/* will redraw the tabline when needed */
+    }
+}
+#endif
+
+#if defined(FEAT_GUI) || defined(PROTO)
+    void
+ins_scroll()
+{
+    pos_T	tpos;
+
+    undisplay_dollar();
+    tpos = curwin->w_cursor;
+    if (gui_do_scroll())
+    {
+	start_arrow(&tpos);
+# ifdef FEAT_CINDENT
+	can_cindent = TRUE;
+# endif
+    }
+}
+
+    void
+ins_horscroll()
+{
+    pos_T	tpos;
+
+    undisplay_dollar();
+    tpos = curwin->w_cursor;
+    if (gui_do_horiz_scroll())
+    {
+	start_arrow(&tpos);
+# ifdef FEAT_CINDENT
+	can_cindent = TRUE;
+# endif
+    }
+}
+#endif
+
+    static void
+ins_left()
+{
+    pos_T	tpos;
+
+#ifdef FEAT_FOLDING
+    if ((fdo_flags & FDO_HOR) && KeyTyped)
+	foldOpenCursor();
+#endif
+    undisplay_dollar();
+    tpos = curwin->w_cursor;
+    if (oneleft() == OK)
+    {
+#if defined(FEAT_XIM) && defined(FEAT_GUI_GTK)
+	/* Only call start_arrow() when not busy with preediting, it will
+	 * break undo.  K_LEFT is inserted in im_correct_cursor(). */
+	if (!im_is_preediting())
+#endif
+	    start_arrow(&tpos);
+#ifdef FEAT_RIGHTLEFT
+	/* If exit reversed string, position is fixed */
+	if (revins_scol != -1 && (int)curwin->w_cursor.col >= revins_scol)
+	    revins_legal++;
+	revins_chars++;
+#endif
+    }
+
+    /*
+     * if 'whichwrap' set for cursor in insert mode may go to
+     * previous line
+     */
+    else if (vim_strchr(p_ww, '[') != NULL && curwin->w_cursor.lnum > 1)
+    {
+	start_arrow(&tpos);
+	--(curwin->w_cursor.lnum);
+	coladvance((colnr_T)MAXCOL);
+	curwin->w_set_curswant = TRUE;	/* so we stay at the end */
+    }
+    else
+	vim_beep();
+}
+
+    static void
+ins_home(c)
+    int		c;
+{
+    pos_T	tpos;
+
+#ifdef FEAT_FOLDING
+    if ((fdo_flags & FDO_HOR) && KeyTyped)
+	foldOpenCursor();
+#endif
+    undisplay_dollar();
+    tpos = curwin->w_cursor;
+    if (c == K_C_HOME)
+	curwin->w_cursor.lnum = 1;
+    curwin->w_cursor.col = 0;
+#ifdef FEAT_VIRTUALEDIT
+    curwin->w_cursor.coladd = 0;
+#endif
+    curwin->w_curswant = 0;
+    start_arrow(&tpos);
+}
+
+    static void
+ins_end(c)
+    int		c;
+{
+    pos_T	tpos;
+
+#ifdef FEAT_FOLDING
+    if ((fdo_flags & FDO_HOR) && KeyTyped)
+	foldOpenCursor();
+#endif
+    undisplay_dollar();
+    tpos = curwin->w_cursor;
+    if (c == K_C_END)
+	curwin->w_cursor.lnum = curbuf->b_ml.ml_line_count;
+    coladvance((colnr_T)MAXCOL);
+    curwin->w_curswant = MAXCOL;
+
+    start_arrow(&tpos);
+}
+
+    static void
+ins_s_left()
+{
+#ifdef FEAT_FOLDING
+    if ((fdo_flags & FDO_HOR) && KeyTyped)
+	foldOpenCursor();
+#endif
+    undisplay_dollar();
+    if (curwin->w_cursor.lnum > 1 || curwin->w_cursor.col > 0)
+    {
+	start_arrow(&curwin->w_cursor);
+	(void)bck_word(1L, FALSE, FALSE);
+	curwin->w_set_curswant = TRUE;
+    }
+    else
+	vim_beep();
+}
+
+    static void
+ins_right()
+{
+#ifdef FEAT_FOLDING
+    if ((fdo_flags & FDO_HOR) && KeyTyped)
+	foldOpenCursor();
+#endif
+    undisplay_dollar();
+    if (gchar_cursor() != NUL || virtual_active()
+	    )
+    {
+	start_arrow(&curwin->w_cursor);
+	curwin->w_set_curswant = TRUE;
+#ifdef FEAT_VIRTUALEDIT
+	if (virtual_active())
+	    oneright();
+	else
+#endif
+	{
+#ifdef FEAT_MBYTE
+	    if (has_mbyte)
+		curwin->w_cursor.col += (*mb_ptr2len)(ml_get_cursor());
+	    else
+#endif
+		++curwin->w_cursor.col;
+	}
+
+#ifdef FEAT_RIGHTLEFT
+	revins_legal++;
+	if (revins_chars)
+	    revins_chars--;
+#endif
+    }
+    /* if 'whichwrap' set for cursor in insert mode, may move the
+     * cursor to the next line */
+    else if (vim_strchr(p_ww, ']') != NULL
+	    && curwin->w_cursor.lnum < curbuf->b_ml.ml_line_count)
+    {
+	start_arrow(&curwin->w_cursor);
+	curwin->w_set_curswant = TRUE;
+	++curwin->w_cursor.lnum;
+	curwin->w_cursor.col = 0;
+    }
+    else
+	vim_beep();
+}
+
+    static void
+ins_s_right()
+{
+#ifdef FEAT_FOLDING
+    if ((fdo_flags & FDO_HOR) && KeyTyped)
+	foldOpenCursor();
+#endif
+    undisplay_dollar();
+    if (curwin->w_cursor.lnum < curbuf->b_ml.ml_line_count
+	    || gchar_cursor() != NUL)
+    {
+	start_arrow(&curwin->w_cursor);
+	(void)fwd_word(1L, FALSE, 0);
+	curwin->w_set_curswant = TRUE;
+    }
+    else
+	vim_beep();
+}
+
+    static void
+ins_up(startcol)
+    int		startcol;	/* when TRUE move to Insstart.col */
+{
+    pos_T	tpos;
+    linenr_T	old_topline = curwin->w_topline;
+#ifdef FEAT_DIFF
+    int		old_topfill = curwin->w_topfill;
+#endif
+
+    undisplay_dollar();
+    tpos = curwin->w_cursor;
+    if (cursor_up(1L, TRUE) == OK)
+    {
+	if (startcol)
+	    coladvance(getvcol_nolist(&Insstart));
+	if (old_topline != curwin->w_topline
+#ifdef FEAT_DIFF
+		|| old_topfill != curwin->w_topfill
+#endif
+		)
+	    redraw_later(VALID);
+	start_arrow(&tpos);
+#ifdef FEAT_CINDENT
+	can_cindent = TRUE;
+#endif
+    }
+    else
+	vim_beep();
+}
+
+    static void
+ins_pageup()
+{
+    pos_T	tpos;
+
+    undisplay_dollar();
+
+#ifdef FEAT_WINDOWS
+    if (mod_mask & MOD_MASK_CTRL)
+    {
+	/* <C-PageUp>: tab page back */
+	if (first_tabpage->tp_next != NULL)
+	{
+	    start_arrow(&curwin->w_cursor);
+	    goto_tabpage(-1);
+	}
+	return;
+    }
+#endif
+
+    tpos = curwin->w_cursor;
+    if (onepage(BACKWARD, 1L) == OK)
+    {
+	start_arrow(&tpos);
+#ifdef FEAT_CINDENT
+	can_cindent = TRUE;
+#endif
+    }
+    else
+	vim_beep();
+}
+
+    static void
+ins_down(startcol)
+    int		startcol;	/* when TRUE move to Insstart.col */
+{
+    pos_T	tpos;
+    linenr_T	old_topline = curwin->w_topline;
+#ifdef FEAT_DIFF
+    int		old_topfill = curwin->w_topfill;
+#endif
+
+    undisplay_dollar();
+    tpos = curwin->w_cursor;
+    if (cursor_down(1L, TRUE) == OK)
+    {
+	if (startcol)
+	    coladvance(getvcol_nolist(&Insstart));
+	if (old_topline != curwin->w_topline
+#ifdef FEAT_DIFF
+		|| old_topfill != curwin->w_topfill
+#endif
+		)
+	    redraw_later(VALID);
+	start_arrow(&tpos);
+#ifdef FEAT_CINDENT
+	can_cindent = TRUE;
+#endif
+    }
+    else
+	vim_beep();
+}
+
+    static void
+ins_pagedown()
+{
+    pos_T	tpos;
+
+    undisplay_dollar();
+
+#ifdef FEAT_WINDOWS
+    if (mod_mask & MOD_MASK_CTRL)
+    {
+	/* <C-PageDown>: tab page forward */
+	if (first_tabpage->tp_next != NULL)
+	{
+	    start_arrow(&curwin->w_cursor);
+	    goto_tabpage(0);
+	}
+	return;
+    }
+#endif
+
+    tpos = curwin->w_cursor;
+    if (onepage(FORWARD, 1L) == OK)
+    {
+	start_arrow(&tpos);
+#ifdef FEAT_CINDENT
+	can_cindent = TRUE;
+#endif
+    }
+    else
+	vim_beep();
+}
+
+#ifdef FEAT_DND
+    static void
+ins_drop()
+{
+    do_put('~', BACKWARD, 1L, PUT_CURSEND);
+}
+#endif
+
+/*
+ * Handle TAB in Insert or Replace mode.
+ * Return TRUE when the TAB needs to be inserted like a normal character.
+ */
+    static int
+ins_tab()
+{
+    int		ind;
+    int		i;
+    int		temp;
+
+    if (Insstart_blank_vcol == MAXCOL && curwin->w_cursor.lnum == Insstart.lnum)
+	Insstart_blank_vcol = get_nolist_virtcol();
+    if (echeck_abbr(TAB + ABBR_OFF))
+	return FALSE;
+
+    ind = inindent(0);
+#ifdef FEAT_CINDENT
+    if (ind)
+	can_cindent = FALSE;
+#endif
+
+    /*
+     * When nothing special, insert TAB like a normal character
+     */
+    if (!curbuf->b_p_et
+	    && !(p_sta && ind && curbuf->b_p_ts != curbuf->b_p_sw)
+	    && curbuf->b_p_sts == 0)
+	return TRUE;
+
+    if (stop_arrow() == FAIL)
+	return TRUE;
+
+    did_ai = FALSE;
+#ifdef FEAT_SMARTINDENT
+    did_si = FALSE;
+    can_si = FALSE;
+    can_si_back = FALSE;
+#endif
+    AppendToRedobuff((char_u *)"\t");
+
+    if (p_sta && ind)		/* insert tab in indent, use 'shiftwidth' */
+	temp = (int)curbuf->b_p_sw;
+    else if (curbuf->b_p_sts > 0) /* use 'softtabstop' when set */
+	temp = (int)curbuf->b_p_sts;
+    else			/* otherwise use 'tabstop' */
+	temp = (int)curbuf->b_p_ts;
+    temp -= get_nolist_virtcol() % temp;
+
+    /*
+     * Insert the first space with ins_char().	It will delete one char in
+     * replace mode.  Insert the rest with ins_str(); it will not delete any
+     * chars.  For VREPLACE mode, we use ins_char() for all characters.
+     */
+    ins_char(' ');
+    while (--temp > 0)
+    {
+#ifdef FEAT_VREPLACE
+	if (State & VREPLACE_FLAG)
+	    ins_char(' ');
+	else
+#endif
+	{
+	    ins_str((char_u *)" ");
+	    if (State & REPLACE_FLAG)	    /* no char replaced */
+		replace_push(NUL);
+	}
+    }
+
+    /*
+     * When 'expandtab' not set: Replace spaces by TABs where possible.
+     */
+    if (!curbuf->b_p_et && (curbuf->b_p_sts || (p_sta && ind)))
+    {
+	char_u		*ptr;
+#ifdef FEAT_VREPLACE
+	char_u		*saved_line = NULL;	/* init for GCC */
+	pos_T		pos;
+#endif
+	pos_T		fpos;
+	pos_T		*cursor;
+	colnr_T		want_vcol, vcol;
+	int		change_col = -1;
+	int		save_list = curwin->w_p_list;
+
+	/*
+	 * Get the current line.  For VREPLACE mode, don't make real changes
+	 * yet, just work on a copy of the line.
+	 */
+#ifdef FEAT_VREPLACE
+	if (State & VREPLACE_FLAG)
+	{
+	    pos = curwin->w_cursor;
+	    cursor = &pos;
+	    saved_line = vim_strsave(ml_get_curline());
+	    if (saved_line == NULL)
+		return FALSE;
+	    ptr = saved_line + pos.col;
+	}
+	else
+#endif
+	{
+	    ptr = ml_get_cursor();
+	    cursor = &curwin->w_cursor;
+	}
+
+	/* When 'L' is not in 'cpoptions' a tab always takes up 'ts' spaces. */
+	if (vim_strchr(p_cpo, CPO_LISTWM) == NULL)
+	    curwin->w_p_list = FALSE;
+
+	/* Find first white before the cursor */
+	fpos = curwin->w_cursor;
+	while (fpos.col > 0 && vim_iswhite(ptr[-1]))
+	{
+	    --fpos.col;
+	    --ptr;
+	}
+
+	/* In Replace mode, don't change characters before the insert point. */
+	if ((State & REPLACE_FLAG)
+		&& fpos.lnum == Insstart.lnum
+		&& fpos.col < Insstart.col)
+	{
+	    ptr += Insstart.col - fpos.col;
+	    fpos.col = Insstart.col;
+	}
+
+	/* compute virtual column numbers of first white and cursor */
+	getvcol(curwin, &fpos, &vcol, NULL, NULL);
+	getvcol(curwin, cursor, &want_vcol, NULL, NULL);
+
+	/* Use as many TABs as possible.  Beware of 'showbreak' and
+	 * 'linebreak' adding extra virtual columns. */
+	while (vim_iswhite(*ptr))
+	{
+	    i = lbr_chartabsize((char_u *)"\t", vcol);
+	    if (vcol + i > want_vcol)
+		break;
+	    if (*ptr != TAB)
+	    {
+		*ptr = TAB;
+		if (change_col < 0)
+		{
+		    change_col = fpos.col;  /* Column of first change */
+		    /* May have to adjust Insstart */
+		    if (fpos.lnum == Insstart.lnum && fpos.col < Insstart.col)
+			Insstart.col = fpos.col;
+		}
+	    }
+	    ++fpos.col;
+	    ++ptr;
+	    vcol += i;
+	}
+
+	if (change_col >= 0)
+	{
+	    int repl_off = 0;
+
+	    /* Skip over the spaces we need. */
+	    while (vcol < want_vcol && *ptr == ' ')
+	    {
+		vcol += lbr_chartabsize(ptr, vcol);
+		++ptr;
+		++repl_off;
+	    }
+	    if (vcol > want_vcol)
+	    {
+		/* Must have a char with 'showbreak' just before it. */
+		--ptr;
+		--repl_off;
+	    }
+	    fpos.col += repl_off;
+
+	    /* Delete following spaces. */
+	    i = cursor->col - fpos.col;
+	    if (i > 0)
+	    {
+		mch_memmove(ptr, ptr + i, STRLEN(ptr + i) + 1);
+		/* correct replace stack. */
+		if ((State & REPLACE_FLAG)
+#ifdef FEAT_VREPLACE
+			&& !(State & VREPLACE_FLAG)
+#endif
+			)
+		    for (temp = i; --temp >= 0; )
+			replace_join(repl_off);
+	    }
+#ifdef FEAT_NETBEANS_INTG
+	    if (usingNetbeans)
+	    {
+		netbeans_removed(curbuf, fpos.lnum, cursor->col,
+							       (long)(i + 1));
+		netbeans_inserted(curbuf, fpos.lnum, cursor->col,
+							   (char_u *)"\t", 1);
+	    }
+#endif
+	    cursor->col -= i;
+
+#ifdef FEAT_VREPLACE
+	    /*
+	     * In VREPLACE mode, we haven't changed anything yet.  Do it now by
+	     * backspacing over the changed spacing and then inserting the new
+	     * spacing.
+	     */
+	    if (State & VREPLACE_FLAG)
+	    {
+		/* Backspace from real cursor to change_col */
+		backspace_until_column(change_col);
+
+		/* Insert each char in saved_line from changed_col to
+		 * ptr-cursor */
+		ins_bytes_len(saved_line + change_col,
+						    cursor->col - change_col);
+	    }
+#endif
+	}
+
+#ifdef FEAT_VREPLACE
+	if (State & VREPLACE_FLAG)
+	    vim_free(saved_line);
+#endif
+	curwin->w_p_list = save_list;
+    }
+
+    return FALSE;
+}
+
+/*
+ * Handle CR or NL in insert mode.
+ * Return TRUE when out of memory or can't undo.
+ */
+    static int
+ins_eol(c)
+    int		c;
+{
+    int	    i;
+
+    if (echeck_abbr(c + ABBR_OFF))
+	return FALSE;
+    if (stop_arrow() == FAIL)
+	return TRUE;
+    undisplay_dollar();
+
+    /*
+     * Strange Vi behaviour: In Replace mode, typing a NL will not delete the
+     * character under the cursor.  Only push a NUL on the replace stack,
+     * nothing to put back when the NL is deleted.
+     */
+    if ((State & REPLACE_FLAG)
+#ifdef FEAT_VREPLACE
+	    && !(State & VREPLACE_FLAG)
+#endif
+	    )
+	replace_push(NUL);
+
+    /*
+     * In VREPLACE mode, a NL replaces the rest of the line, and starts
+     * replacing the next line, so we push all of the characters left on the
+     * line onto the replace stack.  This is not done here though, it is done
+     * in open_line().
+     */
+
+#ifdef FEAT_VIRTUALEDIT
+    /* Put cursor on NUL if on the last char and coladd is 1 (happens after
+     * CTRL-O). */
+    if (virtual_active() && curwin->w_cursor.coladd > 0)
+	coladvance(getviscol());
+#endif
+
+#ifdef FEAT_RIGHTLEFT
+# ifdef FEAT_FKMAP
+    if (p_altkeymap && p_fkmap)
+	fkmap(NL);
+# endif
+    /* NL in reverse insert will always start in the end of
+     * current line. */
+    if (revins_on)
+	curwin->w_cursor.col += (colnr_T)STRLEN(ml_get_cursor());
+#endif
+
+    AppendToRedobuff(NL_STR);
+    i = open_line(FORWARD,
+#ifdef FEAT_COMMENTS
+	    has_format_option(FO_RET_COMS) ? OPENLINE_DO_COM :
+#endif
+	    0, old_indent);
+    old_indent = 0;
+#ifdef FEAT_CINDENT
+    can_cindent = TRUE;
+#endif
+#ifdef FEAT_FOLDING
+    /* When inserting a line the cursor line must never be in a closed fold. */
+    foldOpenCursor();
+#endif
+
+    return (!i);
+}
+
+#ifdef FEAT_DIGRAPHS
+/*
+ * Handle digraph in insert mode.
+ * Returns character still to be inserted, or NUL when nothing remaining to be
+ * done.
+ */
+    static int
+ins_digraph()
+{
+    int	    c;
+    int	    cc;
+
+    pc_status = PC_STATUS_UNSET;
+    if (redrawing() && !char_avail())
+    {
+	/* may need to redraw when no more chars available now */
+	ins_redraw(FALSE);
+
+	edit_putchar('?', TRUE);
+#ifdef FEAT_CMDL_INFO
+	add_to_showcmd_c(Ctrl_K);
+#endif
+    }
+
+#ifdef USE_ON_FLY_SCROLL
+    dont_scroll = TRUE;		/* disallow scrolling here */
+#endif
+
+    /* don't map the digraph chars. This also prevents the
+     * mode message to be deleted when ESC is hit */
+    ++no_mapping;
+    ++allow_keys;
+    c = safe_vgetc();
+    --no_mapping;
+    --allow_keys;
+    if (IS_SPECIAL(c) || mod_mask)	    /* special key */
+    {
+#ifdef FEAT_CMDL_INFO
+	clear_showcmd();
+#endif
+	insert_special(c, TRUE, FALSE);
+	return NUL;
+    }
+    if (c != ESC)
+    {
+	if (redrawing() && !char_avail())
+	{
+	    /* may need to redraw when no more chars available now */
+	    ins_redraw(FALSE);
+
+	    if (char2cells(c) == 1)
+	    {
+		/* first remove the '?', otherwise it's restored when typing
+		 * an ESC next */
+		edit_unputchar();
+		ins_redraw(FALSE);
+		edit_putchar(c, TRUE);
+	    }
+#ifdef FEAT_CMDL_INFO
+	    add_to_showcmd_c(c);
+#endif
+	}
+	++no_mapping;
+	++allow_keys;
+	cc = safe_vgetc();
+	--no_mapping;
+	--allow_keys;
+	if (cc != ESC)
+	{
+	    AppendToRedobuff((char_u *)CTRL_V_STR);
+	    c = getdigraph(c, cc, TRUE);
+#ifdef FEAT_CMDL_INFO
+	    clear_showcmd();
+#endif
+	    return c;
+	}
+    }
+    edit_unputchar();
+#ifdef FEAT_CMDL_INFO
+    clear_showcmd();
+#endif
+    return NUL;
+}
+#endif
+
+/*
+ * Handle CTRL-E and CTRL-Y in Insert mode: copy char from other line.
+ * Returns the char to be inserted, or NUL if none found.
+ */
+    static int
+ins_copychar(lnum)
+    linenr_T	lnum;
+{
+    int	    c;
+    int	    temp;
+    char_u  *ptr, *prev_ptr;
+
+    if (lnum < 1 || lnum > curbuf->b_ml.ml_line_count)
+    {
+	vim_beep();
+	return NUL;
+    }
+
+    /* try to advance to the cursor column */
+    temp = 0;
+    ptr = ml_get(lnum);
+    prev_ptr = ptr;
+    validate_virtcol();
+    while ((colnr_T)temp < curwin->w_virtcol && *ptr != NUL)
+    {
+	prev_ptr = ptr;
+	temp += lbr_chartabsize_adv(&ptr, (colnr_T)temp);
+    }
+    if ((colnr_T)temp > curwin->w_virtcol)
+	ptr = prev_ptr;
+
+#ifdef FEAT_MBYTE
+    c = (*mb_ptr2char)(ptr);
+#else
+    c = *ptr;
+#endif
+    if (c == NUL)
+	vim_beep();
+    return c;
+}
+
+/*
+ * CTRL-Y or CTRL-E typed in Insert mode.
+ */
+    static int
+ins_ctrl_ey(tc)
+    int	    tc;
+{
+    int	    c = tc;
+
+#ifdef FEAT_INS_EXPAND
+    if (ctrl_x_mode == CTRL_X_SCROLL)
+    {
+	if (c == Ctrl_Y)
+	    scrolldown_clamp();
+	else
+	    scrollup_clamp();
+	redraw_later(VALID);
+    }
+    else
+#endif
+    {
+	c = ins_copychar(curwin->w_cursor.lnum + (c == Ctrl_Y ? -1 : 1));
+	if (c != NUL)
+	{
+	    long	tw_save;
+
+	    /* The character must be taken literally, insert like it
+	     * was typed after a CTRL-V, and pretend 'textwidth'
+	     * wasn't set.  Digits, 'o' and 'x' are special after a
+	     * CTRL-V, don't use it for these. */
+	    if (c < 256 && !isalnum(c))
+		AppendToRedobuff((char_u *)CTRL_V_STR);	/* CTRL-V */
+	    tw_save = curbuf->b_p_tw;
+	    curbuf->b_p_tw = -1;
+	    insert_special(c, TRUE, FALSE);
+	    curbuf->b_p_tw = tw_save;
+#ifdef FEAT_RIGHTLEFT
+	    revins_chars++;
+	    revins_legal++;
+#endif
+	    c = Ctrl_V;	/* pretend CTRL-V is last character */
+	    auto_format(FALSE, TRUE);
+	}
+    }
+    return c;
+}
+
+#ifdef FEAT_SMARTINDENT
+/*
+ * Try to do some very smart auto-indenting.
+ * Used when inserting a "normal" character.
+ */
+    static void
+ins_try_si(c)
+    int	    c;
+{
+    pos_T	*pos, old_pos;
+    char_u	*ptr;
+    int		i;
+    int		temp;
+
+    /*
+     * do some very smart indenting when entering '{' or '}'
+     */
+    if (((did_si || can_si_back) && c == '{') || (can_si && c == '}'))
+    {
+	/*
+	 * for '}' set indent equal to indent of line containing matching '{'
+	 */
+	if (c == '}' && (pos = findmatch(NULL, '{')) != NULL)
+	{
+	    old_pos = curwin->w_cursor;
+	    /*
+	     * If the matching '{' has a ')' immediately before it (ignoring
+	     * white-space), then line up with the start of the line
+	     * containing the matching '(' if there is one.  This handles the
+	     * case where an "if (..\n..) {" statement continues over multiple
+	     * lines -- webb
+	     */
+	    ptr = ml_get(pos->lnum);
+	    i = pos->col;
+	    if (i > 0)		/* skip blanks before '{' */
+		while (--i > 0 && vim_iswhite(ptr[i]))
+		    ;
+	    curwin->w_cursor.lnum = pos->lnum;
+	    curwin->w_cursor.col = i;
+	    if (ptr[i] == ')' && (pos = findmatch(NULL, '(')) != NULL)
+		curwin->w_cursor = *pos;
+	    i = get_indent();
+	    curwin->w_cursor = old_pos;
+#ifdef FEAT_VREPLACE
+	    if (State & VREPLACE_FLAG)
+		change_indent(INDENT_SET, i, FALSE, NUL);
+	    else
+#endif
+		(void)set_indent(i, SIN_CHANGED);
+	}
+	else if (curwin->w_cursor.col > 0)
+	{
+	    /*
+	     * when inserting '{' after "O" reduce indent, but not
+	     * more than indent of previous line
+	     */
+	    temp = TRUE;
+	    if (c == '{' && can_si_back && curwin->w_cursor.lnum > 1)
+	    {
+		old_pos = curwin->w_cursor;
+		i = get_indent();
+		while (curwin->w_cursor.lnum > 1)
+		{
+		    ptr = skipwhite(ml_get(--(curwin->w_cursor.lnum)));
+
+		    /* ignore empty lines and lines starting with '#'. */
+		    if (*ptr != '#' && *ptr != NUL)
+			break;
+		}
+		if (get_indent() >= i)
+		    temp = FALSE;
+		curwin->w_cursor = old_pos;
+	    }
+	    if (temp)
+		shift_line(TRUE, FALSE, 1);
+	}
+    }
+
+    /*
+     * set indent of '#' always to 0
+     */
+    if (curwin->w_cursor.col > 0 && can_si && c == '#')
+    {
+	/* remember current indent for next line */
+	old_indent = get_indent();
+	(void)set_indent(0, SIN_CHANGED);
+    }
+
+    /* Adjust ai_col, the char at this position can be deleted. */
+    if (ai_col > curwin->w_cursor.col)
+	ai_col = curwin->w_cursor.col;
+}
+#endif
+
+/*
+ * Get the value that w_virtcol would have when 'list' is off.
+ * Unless 'cpo' contains the 'L' flag.
+ */
+    static colnr_T
+get_nolist_virtcol()
+{
+    if (curwin->w_p_list && vim_strchr(p_cpo, CPO_LISTWM) == NULL)
+	return getvcol_nolist(&curwin->w_cursor);
+    validate_virtcol();
+    return curwin->w_virtcol;
+}
--- /dev/null
+++ b/eval.c
@@ -1,0 +1,21309 @@
+/* vi:set ts=8 sts=4 sw=4:
+ *
+ * VIM - Vi IMproved	by Bram Moolenaar
+ *
+ * Do ":help uganda"  in Vim to read copying and usage conditions.
+ * Do ":help credits" in Vim to see a list of people who contributed.
+ * See README.txt for an overview of the Vim source code.
+ */
+
+/*
+ * eval.c: Expression evaluation.
+ */
+#if defined(MSDOS) || defined(MSWIN)
+# include "vimio.h"	/* for mch_open(), must be before vim.h */
+#endif
+
+#include "vim.h"
+
+#ifdef AMIGA
+# include <time.h>	/* for strftime() */
+#endif
+
+#ifdef MACOS
+# include <time.h>	/* for time_t */
+#endif
+
+#ifdef HAVE_FCNTL_H
+# include <fcntl.h>
+#endif
+
+#if defined(FEAT_EVAL) || defined(PROTO)
+
+#define DICT_MAXNEST 100	/* maximum nesting of lists and dicts */
+
+/*
+ * In a hashtab item "hi_key" points to "di_key" in a dictitem.
+ * This avoids adding a pointer to the hashtab item.
+ * DI2HIKEY() converts a dictitem pointer to a hashitem key pointer.
+ * HIKEY2DI() converts a hashitem key pointer to a dictitem pointer.
+ * HI2DI() converts a hashitem pointer to a dictitem pointer.
+ */
+static dictitem_T dumdi;
+#define DI2HIKEY(di) ((di)->di_key)
+#define HIKEY2DI(p)  ((dictitem_T *)(p - (dumdi.di_key - (char_u *)&dumdi)))
+#define HI2DI(hi)     HIKEY2DI((hi)->hi_key)
+
+/*
+ * Structure returned by get_lval() and used by set_var_lval().
+ * For a plain name:
+ *	"name"	    points to the variable name.
+ *	"exp_name"  is NULL.
+ *	"tv"	    is NULL
+ * For a magic braces name:
+ *	"name"	    points to the expanded variable name.
+ *	"exp_name"  is non-NULL, to be freed later.
+ *	"tv"	    is NULL
+ * For an index in a list:
+ *	"name"	    points to the (expanded) variable name.
+ *	"exp_name"  NULL or non-NULL, to be freed later.
+ *	"tv"	    points to the (first) list item value
+ *	"li"	    points to the (first) list item
+ *	"range", "n1", "n2" and "empty2" indicate what items are used.
+ * For an existing Dict item:
+ *	"name"	    points to the (expanded) variable name.
+ *	"exp_name"  NULL or non-NULL, to be freed later.
+ *	"tv"	    points to the dict item value
+ *	"newkey"    is NULL
+ * For a non-existing Dict item:
+ *	"name"	    points to the (expanded) variable name.
+ *	"exp_name"  NULL or non-NULL, to be freed later.
+ *	"tv"	    points to the Dictionary typval_T
+ *	"newkey"    is the key for the new item.
+ */
+typedef struct lval_S
+{
+    char_u	*ll_name;	/* start of variable name (can be NULL) */
+    char_u	*ll_exp_name;	/* NULL or expanded name in allocated memory. */
+    typval_T	*ll_tv;		/* Typeval of item being used.  If "newkey"
+				   isn't NULL it's the Dict to which to add
+				   the item. */
+    listitem_T	*ll_li;		/* The list item or NULL. */
+    list_T	*ll_list;	/* The list or NULL. */
+    int		ll_range;	/* TRUE when a [i:j] range was used */
+    long	ll_n1;		/* First index for list */
+    long	ll_n2;		/* Second index for list range */
+    int		ll_empty2;	/* Second index is empty: [i:] */
+    dict_T	*ll_dict;	/* The Dictionary or NULL */
+    dictitem_T	*ll_di;		/* The dictitem or NULL */
+    char_u	*ll_newkey;	/* New key for Dict in alloc. mem or NULL. */
+} lval_T;
+
+
+static char *e_letunexp	= N_("E18: Unexpected characters in :let");
+static char *e_listidx = N_("E684: list index out of range: %ld");
+static char *e_undefvar = N_("E121: Undefined variable: %s");
+static char *e_missbrac = N_("E111: Missing ']'");
+static char *e_listarg = N_("E686: Argument of %s must be a List");
+static char *e_listdictarg = N_("E712: Argument of %s must be a List or Dictionary");
+static char *e_emptykey = N_("E713: Cannot use empty key for Dictionary");
+static char *e_listreq = N_("E714: List required");
+static char *e_dictreq = N_("E715: Dictionary required");
+static char *e_toomanyarg = N_("E118: Too many arguments for function: %s");
+static char *e_dictkey = N_("E716: Key not present in Dictionary: %s");
+static char *e_funcexts = N_("E122: Function %s already exists, add ! to replace it");
+static char *e_funcdict = N_("E717: Dictionary entry already exists");
+static char *e_funcref = N_("E718: Funcref required");
+static char *e_dictrange = N_("E719: Cannot use [:] with a Dictionary");
+static char *e_letwrong = N_("E734: Wrong variable type for %s=");
+static char *e_nofunc = N_("E130: Unknown function: %s");
+static char *e_illvar = N_("E461: Illegal variable name: %s");
+/*
+ * All user-defined global variables are stored in dictionary "globvardict".
+ * "globvars_var" is the variable that is used for "g:".
+ */
+static dict_T		globvardict;
+static dictitem_T	globvars_var;
+#define globvarht globvardict.dv_hashtab
+
+/*
+ * Old Vim variables such as "v:version" are also available without the "v:".
+ * Also in functions.  We need a special hashtable for them.
+ */
+static hashtab_T	compat_hashtab;
+
+/*
+ * When recursively copying lists and dicts we need to remember which ones we
+ * have done to avoid endless recursiveness.  This unique ID is used for that.
+ */
+static int current_copyID = 0;
+
+/*
+ * Array to hold the hashtab with variables local to each sourced script.
+ * Each item holds a variable (nameless) that points to the dict_T.
+ */
+typedef struct
+{
+    dictitem_T	sv_var;
+    dict_T	sv_dict;
+} scriptvar_T;
+
+static garray_T	    ga_scripts = {0, 0, sizeof(scriptvar_T), 4, NULL};
+#define SCRIPT_SV(id) (((scriptvar_T *)ga_scripts.ga_data)[(id) - 1])
+#define SCRIPT_VARS(id) (SCRIPT_SV(id).sv_dict.dv_hashtab)
+
+static int echo_attr = 0;   /* attributes used for ":echo" */
+
+/* Values for trans_function_name() argument: */
+#define TFN_INT		1	/* internal function name OK */
+#define TFN_QUIET	2	/* no error messages */
+
+/*
+ * Structure to hold info for a user function.
+ */
+typedef struct ufunc ufunc_T;
+
+struct ufunc
+{
+    int		uf_varargs;	/* variable nr of arguments */
+    int		uf_flags;
+    int		uf_calls;	/* nr of active calls */
+    garray_T	uf_args;	/* arguments */
+    garray_T	uf_lines;	/* function lines */
+#ifdef FEAT_PROFILE
+    int		uf_profiling;	/* TRUE when func is being profiled */
+    /* profiling the function as a whole */
+    int		uf_tm_count;	/* nr of calls */
+    proftime_T	uf_tm_total;	/* time spend in function + children */
+    proftime_T	uf_tm_self;	/* time spend in function itself */
+    proftime_T	uf_tm_children;	/* time spent in children this call */
+    /* profiling the function per line */
+    int		*uf_tml_count;	/* nr of times line was executed */
+    proftime_T	*uf_tml_total;	/* time spend in a line + children */
+    proftime_T	*uf_tml_self;	/* time spend in a line itself */
+    proftime_T	uf_tml_start;	/* start time for current line */
+    proftime_T	uf_tml_children; /* time spent in children for this line */
+    proftime_T	uf_tml_wait;	/* start wait time for current line */
+    int		uf_tml_idx;	/* index of line being timed; -1 if none */
+    int		uf_tml_execed;	/* line being timed was executed */
+#endif
+    scid_T	uf_script_ID;	/* ID of script where function was defined,
+				   used for s: variables */
+    int		uf_refcount;	/* for numbered function: reference count */
+    char_u	uf_name[1];	/* name of function (actually longer); can
+				   start with <SNR>123_ (<SNR> is K_SPECIAL
+				   KS_EXTRA KE_SNR) */
+};
+
+/* function flags */
+#define FC_ABORT    1		/* abort function on error */
+#define FC_RANGE    2		/* function accepts range */
+#define FC_DICT	    4		/* Dict function, uses "self" */
+
+/*
+ * All user-defined functions are found in this hashtable.
+ */
+static hashtab_T	func_hashtab;
+
+/* The names of packages that once were loaded are remembered. */
+static garray_T		ga_loaded = {0, 0, sizeof(char_u *), 4, NULL};
+
+/* list heads for garbage collection */
+static dict_T		*first_dict = NULL;	/* list of all dicts */
+static list_T		*first_list = NULL;	/* list of all lists */
+
+/* From user function to hashitem and back. */
+static ufunc_T dumuf;
+#define UF2HIKEY(fp) ((fp)->uf_name)
+#define HIKEY2UF(p)  ((ufunc_T *)(p - (dumuf.uf_name - (char_u *)&dumuf)))
+#define HI2UF(hi)     HIKEY2UF((hi)->hi_key)
+
+#define FUNCARG(fp, j)	((char_u **)(fp->uf_args.ga_data))[j]
+#define FUNCLINE(fp, j)	((char_u **)(fp->uf_lines.ga_data))[j]
+
+#define MAX_FUNC_ARGS	20	/* maximum number of function arguments */
+#define VAR_SHORT_LEN	20	/* short variable name length */
+#define FIXVAR_CNT	12	/* number of fixed variables */
+
+/* structure to hold info for a function that is currently being executed. */
+typedef struct funccall_S funccall_T;
+
+struct funccall_S
+{
+    ufunc_T	*func;		/* function being called */
+    int		linenr;		/* next line to be executed */
+    int		returned;	/* ":return" used */
+    struct			/* fixed variables for arguments */
+    {
+	dictitem_T	var;		/* variable (without room for name) */
+	char_u	room[VAR_SHORT_LEN];	/* room for the name */
+    } fixvar[FIXVAR_CNT];
+    dict_T	l_vars;		/* l: local function variables */
+    dictitem_T	l_vars_var;	/* variable for l: scope */
+    dict_T	l_avars;	/* a: argument variables */
+    dictitem_T	l_avars_var;	/* variable for a: scope */
+    list_T	l_varlist;	/* list for a:000 */
+    listitem_T	l_listitems[MAX_FUNC_ARGS];	/* listitems for a:000 */
+    typval_T	*rettv;		/* return value */
+    linenr_T	breakpoint;	/* next line with breakpoint or zero */
+    int		dbg_tick;	/* debug_tick when breakpoint was set */
+    int		level;		/* top nesting level of executed function */
+#ifdef FEAT_PROFILE
+    proftime_T	prof_child;	/* time spent in a child */
+#endif
+    funccall_T	*caller;	/* calling function or NULL */
+};
+
+/*
+ * Info used by a ":for" loop.
+ */
+typedef struct
+{
+    int		fi_semicolon;	/* TRUE if ending in '; var]' */
+    int		fi_varcount;	/* nr of variables in the list */
+    listwatch_T	fi_lw;		/* keep an eye on the item used. */
+    list_T	*fi_list;	/* list being used */
+} forinfo_T;
+
+/*
+ * Struct used by trans_function_name()
+ */
+typedef struct
+{
+    dict_T	*fd_dict;	/* Dictionary used */
+    char_u	*fd_newkey;	/* new key in "dict" in allocated memory */
+    dictitem_T	*fd_di;		/* Dictionary item used */
+} funcdict_T;
+
+
+/*
+ * Array to hold the value of v: variables.
+ * The value is in a dictitem, so that it can also be used in the v: scope.
+ * The reason to use this table anyway is for very quick access to the
+ * variables with the VV_ defines.
+ */
+#include "version.h"
+
+/* values for vv_flags: */
+#define VV_COMPAT	1	/* compatible, also used without "v:" */
+#define VV_RO		2	/* read-only */
+#define VV_RO_SBX	4	/* read-only in the sandbox */
+
+#define VV_NAME(s, t)	s, {{t}}, {0}
+
+static struct vimvar
+{
+    char	*vv_name;	/* name of variable, without v: */
+    dictitem_T	vv_di;		/* value and name for key */
+    char	vv_filler[16];	/* space for LONGEST name below!!! */
+    char	vv_flags;	/* VV_COMPAT, VV_RO, VV_RO_SBX */
+} vimvars[VV_LEN] =
+{
+    /*
+     * The order here must match the VV_ defines in vim.h!
+     * Initializing a union does not work, leave tv.vval empty to get zero's.
+     */
+    {VV_NAME("count",		 VAR_NUMBER), VV_COMPAT+VV_RO},
+    {VV_NAME("count1",		 VAR_NUMBER), VV_RO},
+    {VV_NAME("prevcount",	 VAR_NUMBER), VV_RO},
+    {VV_NAME("errmsg",		 VAR_STRING), VV_COMPAT},
+    {VV_NAME("warningmsg",	 VAR_STRING), 0},
+    {VV_NAME("statusmsg",	 VAR_STRING), 0},
+    {VV_NAME("shell_error",	 VAR_NUMBER), VV_COMPAT+VV_RO},
+    {VV_NAME("this_session",	 VAR_STRING), VV_COMPAT},
+    {VV_NAME("version",		 VAR_NUMBER), VV_COMPAT+VV_RO},
+    {VV_NAME("lnum",		 VAR_NUMBER), VV_RO_SBX},
+    {VV_NAME("termresponse",	 VAR_STRING), VV_RO},
+    {VV_NAME("fname",		 VAR_STRING), VV_RO},
+    {VV_NAME("lang",		 VAR_STRING), VV_RO},
+    {VV_NAME("lc_time",		 VAR_STRING), VV_RO},
+    {VV_NAME("ctype",		 VAR_STRING), VV_RO},
+    {VV_NAME("charconvert_from", VAR_STRING), VV_RO},
+    {VV_NAME("charconvert_to",	 VAR_STRING), VV_RO},
+    {VV_NAME("fname_in",	 VAR_STRING), VV_RO},
+    {VV_NAME("fname_out",	 VAR_STRING), VV_RO},
+    {VV_NAME("fname_new",	 VAR_STRING), VV_RO},
+    {VV_NAME("fname_diff",	 VAR_STRING), VV_RO},
+    {VV_NAME("cmdarg",		 VAR_STRING), VV_RO},
+    {VV_NAME("foldstart",	 VAR_NUMBER), VV_RO_SBX},
+    {VV_NAME("foldend",		 VAR_NUMBER), VV_RO_SBX},
+    {VV_NAME("folddashes",	 VAR_STRING), VV_RO_SBX},
+    {VV_NAME("foldlevel",	 VAR_NUMBER), VV_RO_SBX},
+    {VV_NAME("progname",	 VAR_STRING), VV_RO},
+    {VV_NAME("servername",	 VAR_STRING), VV_RO},
+    {VV_NAME("dying",		 VAR_NUMBER), VV_RO},
+    {VV_NAME("exception",	 VAR_STRING), VV_RO},
+    {VV_NAME("throwpoint",	 VAR_STRING), VV_RO},
+    {VV_NAME("register",	 VAR_STRING), VV_RO},
+    {VV_NAME("cmdbang",		 VAR_NUMBER), VV_RO},
+    {VV_NAME("insertmode",	 VAR_STRING), VV_RO},
+    {VV_NAME("val",		 VAR_UNKNOWN), VV_RO},
+    {VV_NAME("key",		 VAR_UNKNOWN), VV_RO},
+    {VV_NAME("profiling",	 VAR_NUMBER), VV_RO},
+    {VV_NAME("fcs_reason",	 VAR_STRING), VV_RO},
+    {VV_NAME("fcs_choice",	 VAR_STRING), 0},
+    {VV_NAME("beval_bufnr",	 VAR_NUMBER), VV_RO},
+    {VV_NAME("beval_winnr",	 VAR_NUMBER), VV_RO},
+    {VV_NAME("beval_lnum",	 VAR_NUMBER), VV_RO},
+    {VV_NAME("beval_col",	 VAR_NUMBER), VV_RO},
+    {VV_NAME("beval_text",	 VAR_STRING), VV_RO},
+    {VV_NAME("scrollstart",	 VAR_STRING), 0},
+    {VV_NAME("swapname",	 VAR_STRING), VV_RO},
+    {VV_NAME("swapchoice",	 VAR_STRING), 0},
+    {VV_NAME("swapcommand",	 VAR_STRING), VV_RO},
+    {VV_NAME("char",		 VAR_STRING), VV_RO},
+    {VV_NAME("mouse_win",	 VAR_NUMBER), 0},
+    {VV_NAME("mouse_lnum",	 VAR_NUMBER), 0},
+    {VV_NAME("mouse_col",	 VAR_NUMBER), 0},
+};
+
+/* shorthand */
+#define vv_type	vv_di.di_tv.v_type
+#define vv_nr	vv_di.di_tv.vval.v_number
+#define vv_str	vv_di.di_tv.vval.v_string
+#define vv_tv	vv_di.di_tv
+
+/*
+ * The v: variables are stored in dictionary "vimvardict".
+ * "vimvars_var" is the variable that is used for the "l:" scope.
+ */
+static dict_T		vimvardict;
+static dictitem_T	vimvars_var;
+#define vimvarht  vimvardict.dv_hashtab
+
+static void prepare_vimvar __ARGS((int idx, typval_T *save_tv));
+static void restore_vimvar __ARGS((int idx, typval_T *save_tv));
+#if defined(FEAT_USR_CMDS) && defined(FEAT_CMDL_COMPL)
+static int call_vim_function __ARGS((char_u *func, int argc, char_u **argv, int safe, typval_T *rettv));
+#endif
+static int ex_let_vars __ARGS((char_u *arg, typval_T *tv, int copy, int semicolon, int var_count, char_u *nextchars));
+static char_u *skip_var_list __ARGS((char_u *arg, int *var_count, int *semicolon));
+static char_u *skip_var_one __ARGS((char_u *arg));
+static void list_hashtable_vars __ARGS((hashtab_T *ht, char_u *prefix, int empty));
+static void list_glob_vars __ARGS((void));
+static void list_buf_vars __ARGS((void));
+static void list_win_vars __ARGS((void));
+#ifdef FEAT_WINDOWS
+static void list_tab_vars __ARGS((void));
+#endif
+static void list_vim_vars __ARGS((void));
+static void list_script_vars __ARGS((void));
+static void list_func_vars __ARGS((void));
+static char_u *list_arg_vars __ARGS((exarg_T *eap, char_u *arg));
+static char_u *ex_let_one __ARGS((char_u *arg, typval_T *tv, int copy, char_u *endchars, char_u *op));
+static int check_changedtick __ARGS((char_u *arg));
+static char_u *get_lval __ARGS((char_u *name, typval_T *rettv, lval_T *lp, int unlet, int skip, int quiet, int fne_flags));
+static void clear_lval __ARGS((lval_T *lp));
+static void set_var_lval __ARGS((lval_T *lp, char_u *endp, typval_T *rettv, int copy, char_u *op));
+static int tv_op __ARGS((typval_T *tv1, typval_T *tv2, char_u  *op));
+static void list_add_watch __ARGS((list_T *l, listwatch_T *lw));
+static void list_rem_watch __ARGS((list_T *l, listwatch_T *lwrem));
+static void list_fix_watch __ARGS((list_T *l, listitem_T *item));
+static void ex_unletlock __ARGS((exarg_T *eap, char_u *argstart, int deep));
+static int do_unlet_var __ARGS((lval_T *lp, char_u *name_end, int forceit));
+static int do_lock_var __ARGS((lval_T *lp, char_u *name_end, int deep, int lock));
+static void item_lock __ARGS((typval_T *tv, int deep, int lock));
+static int tv_islocked __ARGS((typval_T *tv));
+
+static int eval0 __ARGS((char_u *arg,  typval_T *rettv, char_u **nextcmd, int evaluate));
+static int eval1 __ARGS((char_u **arg, typval_T *rettv, int evaluate));
+static int eval2 __ARGS((char_u **arg, typval_T *rettv, int evaluate));
+static int eval3 __ARGS((char_u **arg, typval_T *rettv, int evaluate));
+static int eval4 __ARGS((char_u **arg, typval_T *rettv, int evaluate));
+static int eval5 __ARGS((char_u **arg, typval_T *rettv, int evaluate));
+static int eval6 __ARGS((char_u **arg, typval_T *rettv, int evaluate));
+static int eval7 __ARGS((char_u **arg, typval_T *rettv, int evaluate));
+
+static int eval_index __ARGS((char_u **arg, typval_T *rettv, int evaluate, int verbose));
+static int get_option_tv __ARGS((char_u **arg, typval_T *rettv, int evaluate));
+static int get_string_tv __ARGS((char_u **arg, typval_T *rettv, int evaluate));
+static int get_lit_string_tv __ARGS((char_u **arg, typval_T *rettv, int evaluate));
+static int get_list_tv __ARGS((char_u **arg, typval_T *rettv, int evaluate));
+static int rettv_list_alloc __ARGS((typval_T *rettv));
+static listitem_T *listitem_alloc __ARGS((void));
+static void listitem_free __ARGS((listitem_T *item));
+static void listitem_remove __ARGS((list_T *l, listitem_T *item));
+static long list_len __ARGS((list_T *l));
+static int list_equal __ARGS((list_T *l1, list_T *l2, int ic));
+static int dict_equal __ARGS((dict_T *d1, dict_T *d2, int ic));
+static int tv_equal __ARGS((typval_T *tv1, typval_T *tv2, int ic));
+static listitem_T *list_find __ARGS((list_T *l, long n));
+static long list_find_nr __ARGS((list_T *l, long idx, int *errorp));
+static long list_idx_of_item __ARGS((list_T *l, listitem_T *item));
+static void list_append __ARGS((list_T *l, listitem_T *item));
+static int list_append_tv __ARGS((list_T *l, typval_T *tv));
+static int list_append_string __ARGS((list_T *l, char_u *str, int len));
+static int list_append_number __ARGS((list_T *l, varnumber_T n));
+static int list_insert_tv __ARGS((list_T *l, typval_T *tv, listitem_T *item));
+static int list_extend __ARGS((list_T	*l1, list_T *l2, listitem_T *bef));
+static int list_concat __ARGS((list_T *l1, list_T *l2, typval_T *tv));
+static list_T *list_copy __ARGS((list_T *orig, int deep, int copyID));
+static void list_remove __ARGS((list_T *l, listitem_T *item, listitem_T *item2));
+static char_u *list2string __ARGS((typval_T *tv, int copyID));
+static int list_join __ARGS((garray_T *gap, list_T *l, char_u *sep, int echo, int copyID));
+static void set_ref_in_ht __ARGS((hashtab_T *ht, int copyID));
+static void set_ref_in_list __ARGS((list_T *l, int copyID));
+static void set_ref_in_item __ARGS((typval_T *tv, int copyID));
+static void dict_unref __ARGS((dict_T *d));
+static void dict_free __ARGS((dict_T *d, int recurse));
+static dictitem_T *dictitem_alloc __ARGS((char_u *key));
+static dictitem_T *dictitem_copy __ARGS((dictitem_T *org));
+static void dictitem_remove __ARGS((dict_T *dict, dictitem_T *item));
+static void dictitem_free __ARGS((dictitem_T *item));
+static dict_T *dict_copy __ARGS((dict_T *orig, int deep, int copyID));
+static int dict_add __ARGS((dict_T *d, dictitem_T *item));
+static long dict_len __ARGS((dict_T *d));
+static dictitem_T *dict_find __ARGS((dict_T *d, char_u *key, int len));
+static char_u *dict2string __ARGS((typval_T *tv, int copyID));
+static int get_dict_tv __ARGS((char_u **arg, typval_T *rettv, int evaluate));
+static char_u *echo_string __ARGS((typval_T *tv, char_u **tofree, char_u *numbuf, int copyID));
+static char_u *tv2string __ARGS((typval_T *tv, char_u **tofree, char_u *numbuf, int copyID));
+static char_u *string_quote __ARGS((char_u *str, int function));
+static int get_env_tv __ARGS((char_u **arg, typval_T *rettv, int evaluate));
+static int find_internal_func __ARGS((char_u *name));
+static char_u *deref_func_name __ARGS((char_u *name, int *lenp));
+static int get_func_tv __ARGS((char_u *name, int len, typval_T *rettv, char_u **arg, linenr_T firstline, linenr_T lastline, int *doesrange, int evaluate, dict_T *selfdict));
+static int call_func __ARGS((char_u *name, int len, typval_T *rettv, int argcount, typval_T *argvars, linenr_T firstline, linenr_T lastline, int *doesrange, int evaluate, dict_T *selfdict));
+static void emsg_funcname __ARGS((char *ermsg, char_u *name));
+
+static void f_add __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_append __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_argc __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_argidx __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_argv __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_browse __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_browsedir __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_bufexists __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_buflisted __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_bufloaded __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_bufname __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_bufnr __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_bufwinnr __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_byte2line __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_byteidx __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_call __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_changenr __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_char2nr __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_cindent __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_col __ARGS((typval_T *argvars, typval_T *rettv));
+#if defined(FEAT_INS_EXPAND)
+static void f_complete __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_complete_add __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_complete_check __ARGS((typval_T *argvars, typval_T *rettv));
+#endif
+static void f_confirm __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_copy __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_count __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_cscope_connection __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_cursor __ARGS((typval_T *argsvars, typval_T *rettv));
+static void f_deepcopy __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_delete __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_did_filetype __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_diff_filler __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_diff_hlID __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_empty __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_escape __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_eval __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_eventhandler __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_executable __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_exists __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_expand __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_extend __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_feedkeys __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_filereadable __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_filewritable __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_filter __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_finddir __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_findfile __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_fnamemodify __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_foldclosed __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_foldclosedend __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_foldlevel __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_foldtext __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_foldtextresult __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_foreground __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_function __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_garbagecollect __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_get __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_getbufline __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_getbufvar __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_getchar __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_getcharmod __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_getcmdline __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_getcmdpos __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_getcmdtype __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_getcwd __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_getfontname __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_getfperm __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_getfsize __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_getftime __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_getftype __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_getline __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_getpos __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_getqflist __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_getreg __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_getregtype __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_gettabwinvar __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_getwinposx __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_getwinposy __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_getwinvar __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_glob __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_globpath __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_has __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_has_key __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_haslocaldir __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_hasmapto __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_histadd __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_histdel __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_histget __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_histnr __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_hlID __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_hlexists __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_hostname __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_iconv __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_indent __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_index __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_input __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_inputdialog __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_inputlist __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_inputrestore __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_inputsave __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_inputsecret __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_insert __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_isdirectory __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_islocked __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_items __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_join __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_keys __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_last_buffer_nr __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_len __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_libcall __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_libcallnr __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_line __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_line2byte __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_lispindent __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_localtime __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_map __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_maparg __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_mapcheck __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_match __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_matcharg __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_matchend __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_matchlist __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_matchstr __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_max __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_min __ARGS((typval_T *argvars, typval_T *rettv));
+#ifdef vim_mkdir
+static void f_mkdir __ARGS((typval_T *argvars, typval_T *rettv));
+#endif
+static void f_mode __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_nextnonblank __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_nr2char __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_pathshorten __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_prevnonblank __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_printf __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_pumvisible __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_range __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_readfile __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_reltime __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_reltimestr __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_remote_expr __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_remote_foreground __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_remote_peek __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_remote_read __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_remote_send __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_remove __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_rename __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_repeat __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_resolve __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_reverse __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_search __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_searchdecl __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_searchpair __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_searchpairpos __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_searchpos __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_server2client __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_serverlist __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_setbufvar __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_setcmdpos __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_setline __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_setloclist __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_setpos __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_setqflist __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_setreg __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_settabwinvar __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_setwinvar __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_shellescape __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_simplify __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_sort __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_soundfold __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_spellbadword __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_spellsuggest __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_split __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_str2nr __ARGS((typval_T *argvars, typval_T *rettv));
+#ifdef HAVE_STRFTIME
+static void f_strftime __ARGS((typval_T *argvars, typval_T *rettv));
+#endif
+static void f_stridx __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_string __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_strlen __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_strpart __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_strridx __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_strtrans __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_submatch __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_substitute __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_synID __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_synIDattr __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_synIDtrans __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_system __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_tabpagebuflist __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_tabpagenr __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_tabpagewinnr __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_taglist __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_tagfiles __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_tempname __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_test __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_tolower __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_toupper __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_tr __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_type __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_values __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_virtcol __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_visualmode __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_winbufnr __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_wincol __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_winheight __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_winline __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_winnr __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_winrestcmd __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_winrestview __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_winsaveview __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_winwidth __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_writefile __ARGS((typval_T *argvars, typval_T *rettv));
+
+static int list2fpos __ARGS((typval_T *arg, pos_T *posp, int *fnump));
+static pos_T *var2fpos __ARGS((typval_T *varp, int lnum, int *fnum));
+static int get_env_len __ARGS((char_u **arg));
+static int get_id_len __ARGS((char_u **arg));
+static int get_name_len __ARGS((char_u **arg, char_u **alias, int evaluate, int verbose));
+static char_u *find_name_end __ARGS((char_u *arg, char_u **expr_start, char_u **expr_end, int flags));
+#define FNE_INCL_BR	1	/* find_name_end(): include [] in name */
+#define FNE_CHECK_START	2	/* find_name_end(): check name starts with
+				   valid character */
+static char_u * make_expanded_name __ARGS((char_u *in_start, char_u *expr_start, char_u *expr_end, char_u *in_end));
+static int eval_isnamec __ARGS((int c));
+static int eval_isnamec1 __ARGS((int c));
+static int get_var_tv __ARGS((char_u *name, int len, typval_T *rettv, int verbose));
+static int handle_subscript __ARGS((char_u **arg, typval_T *rettv, int evaluate, int verbose));
+static typval_T *alloc_tv __ARGS((void));
+static typval_T *alloc_string_tv __ARGS((char_u *string));
+static void init_tv __ARGS((typval_T *varp));
+static long get_tv_number __ARGS((typval_T *varp));
+static linenr_T get_tv_lnum __ARGS((typval_T *argvars));
+static linenr_T get_tv_lnum_buf __ARGS((typval_T *argvars, buf_T *buf));
+static char_u *get_tv_string __ARGS((typval_T *varp));
+static char_u *get_tv_string_buf __ARGS((typval_T *varp, char_u *buf));
+static char_u *get_tv_string_buf_chk __ARGS((typval_T *varp, char_u *buf));
+static dictitem_T *find_var __ARGS((char_u *name, hashtab_T **htp));
+static dictitem_T *find_var_in_ht __ARGS((hashtab_T *ht, char_u *varname, int writing));
+static hashtab_T *find_var_ht __ARGS((char_u *name, char_u **varname));
+static void vars_clear_ext __ARGS((hashtab_T *ht, int free_val));
+static void delete_var __ARGS((hashtab_T *ht, hashitem_T *hi));
+static void list_one_var __ARGS((dictitem_T *v, char_u *prefix));
+static void list_one_var_a __ARGS((char_u *prefix, char_u *name, int type, char_u *string));
+static void set_var __ARGS((char_u *name, typval_T *varp, int copy));
+static int var_check_ro __ARGS((int flags, char_u *name));
+static int var_check_fixed __ARGS((int flags, char_u *name));
+static int tv_check_lock __ARGS((int lock, char_u *name));
+static void copy_tv __ARGS((typval_T *from, typval_T *to));
+static int item_copy __ARGS((typval_T *from, typval_T *to, int deep, int copyID));
+static char_u *find_option_end __ARGS((char_u **arg, int *opt_flags));
+static char_u *trans_function_name __ARGS((char_u **pp, int skip, int flags, funcdict_T *fd));
+static int eval_fname_script __ARGS((char_u *p));
+static int eval_fname_sid __ARGS((char_u *p));
+static void list_func_head __ARGS((ufunc_T *fp, int indent));
+static ufunc_T *find_func __ARGS((char_u *name));
+static int function_exists __ARGS((char_u *name));
+static int builtin_function __ARGS((char_u *name));
+#ifdef FEAT_PROFILE
+static void func_do_profile __ARGS((ufunc_T *fp));
+static void prof_sort_list __ARGS((FILE *fd, ufunc_T **sorttab, int st_len, char *title, int prefer_self));
+static void prof_func_line __ARGS((FILE *fd, int count, proftime_T *total, proftime_T *self, int prefer_self));
+static int
+# ifdef __BORLANDC__
+    _RTLENTRYF
+# endif
+	prof_total_cmp __ARGS((const void *s1, const void *s2));
+static int
+# ifdef __BORLANDC__
+    _RTLENTRYF
+# endif
+	prof_self_cmp __ARGS((const void *s1, const void *s2));
+#endif
+static int script_autoload __ARGS((char_u *name, int reload));
+static char_u *autoload_name __ARGS((char_u *name));
+static void cat_func_name __ARGS((char_u *buf, ufunc_T *fp));
+static void func_free __ARGS((ufunc_T *fp));
+static void func_unref __ARGS((char_u *name));
+static void func_ref __ARGS((char_u *name));
+static void call_user_func __ARGS((ufunc_T *fp, int argcount, typval_T *argvars, typval_T *rettv, linenr_T firstline, linenr_T lastline, dict_T *selfdict));
+static void add_nr_var __ARGS((dict_T *dp, dictitem_T *v, char *name, varnumber_T nr));
+static win_T *find_win_by_nr __ARGS((typval_T *vp, tabpage_T *tp));
+static void getwinvar __ARGS((typval_T *argvars, typval_T *rettv, int off));
+static int searchpair_cmn __ARGS((typval_T *argvars, pos_T *match_pos));
+static int search_cmn __ARGS((typval_T *argvars, pos_T *match_pos, int *flagsp));
+static void setwinvar __ARGS((typval_T *argvars, typval_T *rettv, int off));
+
+/* Character used as separated in autoload function/variable names. */
+#define AUTOLOAD_CHAR '#'
+
+/*
+ * Initialize the global and v: variables.
+ */
+    void
+eval_init()
+{
+    int		    i;
+    struct vimvar   *p;
+
+    init_var_dict(&globvardict, &globvars_var);
+    init_var_dict(&vimvardict, &vimvars_var);
+    hash_init(&compat_hashtab);
+    hash_init(&func_hashtab);
+
+    for (i = 0; i < VV_LEN; ++i)
+    {
+	p = &vimvars[i];
+	STRCPY(p->vv_di.di_key, p->vv_name);
+	if (p->vv_flags & VV_RO)
+	    p->vv_di.di_flags = DI_FLAGS_RO | DI_FLAGS_FIX;
+	else if (p->vv_flags & VV_RO_SBX)
+	    p->vv_di.di_flags = DI_FLAGS_RO_SBX | DI_FLAGS_FIX;
+	else
+	    p->vv_di.di_flags = DI_FLAGS_FIX;
+
+	/* add to v: scope dict, unless the value is not always available */
+	if (p->vv_type != VAR_UNKNOWN)
+	    hash_add(&vimvarht, p->vv_di.di_key);
+	if (p->vv_flags & VV_COMPAT)
+	    /* add to compat scope dict */
+	    hash_add(&compat_hashtab, p->vv_di.di_key);
+    }
+}
+
+#if defined(EXITFREE) || defined(PROTO)
+    void
+eval_clear()
+{
+    int		    i;
+    struct vimvar   *p;
+
+    for (i = 0; i < VV_LEN; ++i)
+    {
+	p = &vimvars[i];
+	if (p->vv_di.di_tv.v_type == VAR_STRING)
+	{
+	    vim_free(p->vv_di.di_tv.vval.v_string);
+	    p->vv_di.di_tv.vval.v_string = NULL;
+	}
+    }
+    hash_clear(&vimvarht);
+    hash_clear(&compat_hashtab);
+
+    /* script-local variables */
+    for (i = 1; i <= ga_scripts.ga_len; ++i)
+	vars_clear(&SCRIPT_VARS(i));
+    ga_clear(&ga_scripts);
+    free_scriptnames();
+
+    /* global variables */
+    vars_clear(&globvarht);
+
+    /* functions */
+    free_all_functions();
+    hash_clear(&func_hashtab);
+
+    /* autoloaded script names */
+    ga_clear_strings(&ga_loaded);
+
+    /* unreferenced lists and dicts */
+    (void)garbage_collect();
+}
+#endif
+
+/*
+ * Return the name of the executed function.
+ */
+    char_u *
+func_name(cookie)
+    void *cookie;
+{
+    return ((funccall_T *)cookie)->func->uf_name;
+}
+
+/*
+ * Return the address holding the next breakpoint line for a funccall cookie.
+ */
+    linenr_T *
+func_breakpoint(cookie)
+    void *cookie;
+{
+    return &((funccall_T *)cookie)->breakpoint;
+}
+
+/*
+ * Return the address holding the debug tick for a funccall cookie.
+ */
+    int *
+func_dbg_tick(cookie)
+    void *cookie;
+{
+    return &((funccall_T *)cookie)->dbg_tick;
+}
+
+/*
+ * Return the nesting level for a funccall cookie.
+ */
+    int
+func_level(cookie)
+    void *cookie;
+{
+    return ((funccall_T *)cookie)->level;
+}
+
+/* pointer to funccal for currently active function */
+funccall_T *current_funccal = NULL;
+
+/*
+ * Return TRUE when a function was ended by a ":return" command.
+ */
+    int
+current_func_returned()
+{
+    return current_funccal->returned;
+}
+
+
+/*
+ * Set an internal variable to a string value. Creates the variable if it does
+ * not already exist.
+ */
+    void
+set_internal_string_var(name, value)
+    char_u	*name;
+    char_u	*value;
+{
+    char_u	*val;
+    typval_T	*tvp;
+
+    val = vim_strsave(value);
+    if (val != NULL)
+    {
+	tvp = alloc_string_tv(val);
+	if (tvp != NULL)
+	{
+	    set_var(name, tvp, FALSE);
+	    free_tv(tvp);
+	}
+    }
+}
+
+static lval_T	*redir_lval = NULL;
+static garray_T redir_ga;	/* only valid when redir_lval is not NULL */
+static char_u	*redir_endp = NULL;
+static char_u	*redir_varname = NULL;
+
+/*
+ * Start recording command output to a variable
+ * Returns OK if successfully completed the setup.  FAIL otherwise.
+ */
+    int
+var_redir_start(name, append)
+    char_u	*name;
+    int		append;		/* append to an existing variable */
+{
+    int		save_emsg;
+    int		err;
+    typval_T	tv;
+
+    /* Make sure a valid variable name is specified */
+    if (!eval_isnamec1(*name))
+    {
+	EMSG(_(e_invarg));
+	return FAIL;
+    }
+
+    redir_varname = vim_strsave(name);
+    if (redir_varname == NULL)
+	return FAIL;
+
+    redir_lval = (lval_T *)alloc_clear((unsigned)sizeof(lval_T));
+    if (redir_lval == NULL)
+    {
+	var_redir_stop();
+	return FAIL;
+    }
+
+    /* The output is stored in growarray "redir_ga" until redirection ends. */
+    ga_init2(&redir_ga, (int)sizeof(char), 500);
+
+    /* Parse the variable name (can be a dict or list entry). */
+    redir_endp = get_lval(redir_varname, NULL, redir_lval, FALSE, FALSE, FALSE,
+							     FNE_CHECK_START);
+    if (redir_endp == NULL || redir_lval->ll_name == NULL || *redir_endp != NUL)
+    {
+	if (redir_endp != NULL && *redir_endp != NUL)
+	    /* Trailing characters are present after the variable name */
+	    EMSG(_(e_trailing));
+	else
+	    EMSG(_(e_invarg));
+	var_redir_stop();
+	return FAIL;
+    }
+
+    /* check if we can write to the variable: set it to or append an empty
+     * string */
+    save_emsg = did_emsg;
+    did_emsg = FALSE;
+    tv.v_type = VAR_STRING;
+    tv.vval.v_string = (char_u *)"";
+    if (append)
+	set_var_lval(redir_lval, redir_endp, &tv, TRUE, (char_u *)".");
+    else
+	set_var_lval(redir_lval, redir_endp, &tv, TRUE, (char_u *)"=");
+    err = did_emsg;
+    did_emsg |= save_emsg;
+    if (err)
+    {
+	var_redir_stop();
+	return FAIL;
+    }
+    if (redir_lval->ll_newkey != NULL)
+    {
+	/* Dictionary item was created, don't do it again. */
+	vim_free(redir_lval->ll_newkey);
+	redir_lval->ll_newkey = NULL;
+    }
+
+    return OK;
+}
+
+/*
+ * Append "value[value_len]" to the variable set by var_redir_start().
+ * The actual appending is postponed until redirection ends, because the value
+ * appended may in fact be the string we write to, changing it may cause freed
+ * memory to be used:
+ *   :redir => foo
+ *   :let foo
+ *   :redir END
+ */
+    void
+var_redir_str(value, value_len)
+    char_u	*value;
+    int		value_len;
+{
+    size_t	len;
+
+    if (redir_lval == NULL)
+	return;
+
+    if (value_len == -1)
+	len = STRLEN(value);	/* Append the entire string */
+    else
+	len = value_len;	/* Append only "value_len" characters */
+
+    if (ga_grow(&redir_ga, (int)len) == OK)
+    {
+	mch_memmove((char *)redir_ga.ga_data + redir_ga.ga_len, value, len);
+	redir_ga.ga_len += (int)len;
+    }
+    else
+	var_redir_stop();
+}
+
+/*
+ * Stop redirecting command output to a variable.
+ */
+    void
+var_redir_stop()
+{
+    typval_T	tv;
+
+    if (redir_lval != NULL)
+    {
+	/* Append the trailing NUL. */
+	ga_append(&redir_ga, NUL);
+
+	/* Assign the text to the variable. */
+	tv.v_type = VAR_STRING;
+	tv.vval.v_string = redir_ga.ga_data;
+	set_var_lval(redir_lval, redir_endp, &tv, FALSE, (char_u *)".");
+	vim_free(tv.vval.v_string);
+
+	clear_lval(redir_lval);
+	vim_free(redir_lval);
+	redir_lval = NULL;
+    }
+    vim_free(redir_varname);
+    redir_varname = NULL;
+}
+
+# if defined(FEAT_MBYTE) || defined(PROTO)
+    int
+eval_charconvert(enc_from, enc_to, fname_from, fname_to)
+    char_u	*enc_from;
+    char_u	*enc_to;
+    char_u	*fname_from;
+    char_u	*fname_to;
+{
+    int		err = FALSE;
+
+    set_vim_var_string(VV_CC_FROM, enc_from, -1);
+    set_vim_var_string(VV_CC_TO, enc_to, -1);
+    set_vim_var_string(VV_FNAME_IN, fname_from, -1);
+    set_vim_var_string(VV_FNAME_OUT, fname_to, -1);
+    if (eval_to_bool(p_ccv, &err, NULL, FALSE))
+	err = TRUE;
+    set_vim_var_string(VV_CC_FROM, NULL, -1);
+    set_vim_var_string(VV_CC_TO, NULL, -1);
+    set_vim_var_string(VV_FNAME_IN, NULL, -1);
+    set_vim_var_string(VV_FNAME_OUT, NULL, -1);
+
+    if (err)
+	return FAIL;
+    return OK;
+}
+# endif
+
+# if defined(FEAT_POSTSCRIPT) || defined(PROTO)
+    int
+eval_printexpr(fname, args)
+    char_u	*fname;
+    char_u	*args;
+{
+    int		err = FALSE;
+
+    set_vim_var_string(VV_FNAME_IN, fname, -1);
+    set_vim_var_string(VV_CMDARG, args, -1);
+    if (eval_to_bool(p_pexpr, &err, NULL, FALSE))
+	err = TRUE;
+    set_vim_var_string(VV_FNAME_IN, NULL, -1);
+    set_vim_var_string(VV_CMDARG, NULL, -1);
+
+    if (err)
+    {
+	mch_remove(fname);
+	return FAIL;
+    }
+    return OK;
+}
+# endif
+
+# if defined(FEAT_DIFF) || defined(PROTO)
+    void
+eval_diff(origfile, newfile, outfile)
+    char_u	*origfile;
+    char_u	*newfile;
+    char_u	*outfile;
+{
+    int		err = FALSE;
+
+    set_vim_var_string(VV_FNAME_IN, origfile, -1);
+    set_vim_var_string(VV_FNAME_NEW, newfile, -1);
+    set_vim_var_string(VV_FNAME_OUT, outfile, -1);
+    (void)eval_to_bool(p_dex, &err, NULL, FALSE);
+    set_vim_var_string(VV_FNAME_IN, NULL, -1);
+    set_vim_var_string(VV_FNAME_NEW, NULL, -1);
+    set_vim_var_string(VV_FNAME_OUT, NULL, -1);
+}
+
+    void
+eval_patch(origfile, difffile, outfile)
+    char_u	*origfile;
+    char_u	*difffile;
+    char_u	*outfile;
+{
+    int		err;
+
+    set_vim_var_string(VV_FNAME_IN, origfile, -1);
+    set_vim_var_string(VV_FNAME_DIFF, difffile, -1);
+    set_vim_var_string(VV_FNAME_OUT, outfile, -1);
+    (void)eval_to_bool(p_pex, &err, NULL, FALSE);
+    set_vim_var_string(VV_FNAME_IN, NULL, -1);
+    set_vim_var_string(VV_FNAME_DIFF, NULL, -1);
+    set_vim_var_string(VV_FNAME_OUT, NULL, -1);
+}
+# endif
+
+/*
+ * Top level evaluation function, returning a boolean.
+ * Sets "error" to TRUE if there was an error.
+ * Return TRUE or FALSE.
+ */
+    int
+eval_to_bool(arg, error, nextcmd, skip)
+    char_u	*arg;
+    int		*error;
+    char_u	**nextcmd;
+    int		skip;	    /* only parse, don't execute */
+{
+    typval_T	tv;
+    int		retval = FALSE;
+
+    if (skip)
+	++emsg_skip;
+    if (eval0(arg, &tv, nextcmd, !skip) == FAIL)
+	*error = TRUE;
+    else
+    {
+	*error = FALSE;
+	if (!skip)
+	{
+	    retval = (get_tv_number_chk(&tv, error) != 0);
+	    clear_tv(&tv);
+	}
+    }
+    if (skip)
+	--emsg_skip;
+
+    return retval;
+}
+
+/*
+ * Top level evaluation function, returning a string.  If "skip" is TRUE,
+ * only parsing to "nextcmd" is done, without reporting errors.  Return
+ * pointer to allocated memory, or NULL for failure or when "skip" is TRUE.
+ */
+    char_u *
+eval_to_string_skip(arg, nextcmd, skip)
+    char_u	*arg;
+    char_u	**nextcmd;
+    int		skip;	    /* only parse, don't execute */
+{
+    typval_T	tv;
+    char_u	*retval;
+
+    if (skip)
+	++emsg_skip;
+    if (eval0(arg, &tv, nextcmd, !skip) == FAIL || skip)
+	retval = NULL;
+    else
+    {
+	retval = vim_strsave(get_tv_string(&tv));
+	clear_tv(&tv);
+    }
+    if (skip)
+	--emsg_skip;
+
+    return retval;
+}
+
+/*
+ * Skip over an expression at "*pp".
+ * Return FAIL for an error, OK otherwise.
+ */
+    int
+skip_expr(pp)
+    char_u	**pp;
+{
+    typval_T	rettv;
+
+    *pp = skipwhite(*pp);
+    return eval1(pp, &rettv, FALSE);
+}
+
+/*
+ * Top level evaluation function, returning a string.
+ * Return pointer to allocated memory, or NULL for failure.
+ */
+    char_u *
+eval_to_string(arg, nextcmd, dolist)
+    char_u	*arg;
+    char_u	**nextcmd;
+    int		dolist;		/* turn List into sequence of lines */
+{
+    typval_T	tv;
+    char_u	*retval;
+    garray_T	ga;
+
+    if (eval0(arg, &tv, nextcmd, TRUE) == FAIL)
+	retval = NULL;
+    else
+    {
+	if (dolist && tv.v_type == VAR_LIST)
+	{
+	    ga_init2(&ga, (int)sizeof(char), 80);
+	    list_join(&ga, tv.vval.v_list, (char_u *)"\n", TRUE, 0);
+	    ga_append(&ga, NUL);
+	    retval = (char_u *)ga.ga_data;
+	}
+	else
+	    retval = vim_strsave(get_tv_string(&tv));
+	clear_tv(&tv);
+    }
+
+    return retval;
+}
+
+/*
+ * Call eval_to_string() without using current local variables and using
+ * textlock.  When "use_sandbox" is TRUE use the sandbox.
+ */
+    char_u *
+eval_to_string_safe(arg, nextcmd, use_sandbox)
+    char_u	*arg;
+    char_u	**nextcmd;
+    int		use_sandbox;
+{
+    char_u	*retval;
+    void	*save_funccalp;
+
+    save_funccalp = save_funccal();
+    if (use_sandbox)
+	++sandbox;
+    ++textlock;
+    retval = eval_to_string(arg, nextcmd, FALSE);
+    if (use_sandbox)
+	--sandbox;
+    --textlock;
+    restore_funccal(save_funccalp);
+    return retval;
+}
+
+/*
+ * Top level evaluation function, returning a number.
+ * Evaluates "expr" silently.
+ * Returns -1 for an error.
+ */
+    int
+eval_to_number(expr)
+    char_u	*expr;
+{
+    typval_T	rettv;
+    int		retval;
+    char_u	*p = skipwhite(expr);
+
+    ++emsg_off;
+
+    if (eval1(&p, &rettv, TRUE) == FAIL)
+	retval = -1;
+    else
+    {
+	retval = get_tv_number_chk(&rettv, NULL);
+	clear_tv(&rettv);
+    }
+    --emsg_off;
+
+    return retval;
+}
+
+/*
+ * Prepare v: variable "idx" to be used.
+ * Save the current typeval in "save_tv".
+ * When not used yet add the variable to the v: hashtable.
+ */
+    static void
+prepare_vimvar(idx, save_tv)
+    int		idx;
+    typval_T	*save_tv;
+{
+    *save_tv = vimvars[idx].vv_tv;
+    if (vimvars[idx].vv_type == VAR_UNKNOWN)
+	hash_add(&vimvarht, vimvars[idx].vv_di.di_key);
+}
+
+/*
+ * Restore v: variable "idx" to typeval "save_tv".
+ * When no longer defined, remove the variable from the v: hashtable.
+ */
+    static void
+restore_vimvar(idx, save_tv)
+    int		idx;
+    typval_T	*save_tv;
+{
+    hashitem_T	*hi;
+
+    clear_tv(&vimvars[idx].vv_tv);
+    vimvars[idx].vv_tv = *save_tv;
+    if (vimvars[idx].vv_type == VAR_UNKNOWN)
+    {
+	hi = hash_find(&vimvarht, vimvars[idx].vv_di.di_key);
+	if (HASHITEM_EMPTY(hi))
+	    EMSG2(_(e_intern2), "restore_vimvar()");
+	else
+	    hash_remove(&vimvarht, hi);
+    }
+}
+
+#if defined(FEAT_SPELL) || defined(PROTO)
+/*
+ * Evaluate an expression to a list with suggestions.
+ * For the "expr:" part of 'spellsuggest'.
+ */
+    list_T *
+eval_spell_expr(badword, expr)
+    char_u	*badword;
+    char_u	*expr;
+{
+    typval_T	save_val;
+    typval_T	rettv;
+    list_T	*list = NULL;
+    char_u	*p = skipwhite(expr);
+
+    /* Set "v:val" to the bad word. */
+    prepare_vimvar(VV_VAL, &save_val);
+    vimvars[VV_VAL].vv_type = VAR_STRING;
+    vimvars[VV_VAL].vv_str = badword;
+    if (p_verbose == 0)
+	++emsg_off;
+
+    if (eval1(&p, &rettv, TRUE) == OK)
+    {
+	if (rettv.v_type != VAR_LIST)
+	    clear_tv(&rettv);
+	else
+	    list = rettv.vval.v_list;
+    }
+
+    if (p_verbose == 0)
+	--emsg_off;
+    vimvars[VV_VAL].vv_str = NULL;
+    restore_vimvar(VV_VAL, &save_val);
+
+    return list;
+}
+
+/*
+ * "list" is supposed to contain two items: a word and a number.  Return the
+ * word in "pp" and the number as the return value.
+ * Return -1 if anything isn't right.
+ * Used to get the good word and score from the eval_spell_expr() result.
+ */
+    int
+get_spellword(list, pp)
+    list_T	*list;
+    char_u	**pp;
+{
+    listitem_T	*li;
+
+    li = list->lv_first;
+    if (li == NULL)
+	return -1;
+    *pp = get_tv_string(&li->li_tv);
+
+    li = li->li_next;
+    if (li == NULL)
+	return -1;
+    return get_tv_number(&li->li_tv);
+}
+#endif
+
+/*
+ * Top level evaluation function.
+ * Returns an allocated typval_T with the result.
+ * Returns NULL when there is an error.
+ */
+    typval_T *
+eval_expr(arg, nextcmd)
+    char_u	*arg;
+    char_u	**nextcmd;
+{
+    typval_T	*tv;
+
+    tv = (typval_T *)alloc(sizeof(typval_T));
+    if (tv != NULL && eval0(arg, tv, nextcmd, TRUE) == FAIL)
+    {
+	vim_free(tv);
+	tv = NULL;
+    }
+
+    return tv;
+}
+
+
+#if (defined(FEAT_USR_CMDS) && defined(FEAT_CMDL_COMPL)) || defined(PROTO)
+/*
+ * Call some vimL function and return the result in "*rettv".
+ * Uses argv[argc] for the function arguments.
+ * Returns OK or FAIL.
+ */
+    static int
+call_vim_function(func, argc, argv, safe, rettv)
+    char_u      *func;
+    int		argc;
+    char_u      **argv;
+    int		safe;		/* use the sandbox */
+    typval_T	*rettv;
+{
+    typval_T	*argvars;
+    long	n;
+    int		len;
+    int		i;
+    int		doesrange;
+    void	*save_funccalp = NULL;
+    int		ret;
+
+    argvars = (typval_T *)alloc((unsigned)((argc + 1) * sizeof(typval_T)));
+    if (argvars == NULL)
+	return FAIL;
+
+    for (i = 0; i < argc; i++)
+    {
+	/* Pass a NULL or empty argument as an empty string */
+	if (argv[i] == NULL || *argv[i] == NUL)
+	{
+	    argvars[i].v_type = VAR_STRING;
+	    argvars[i].vval.v_string = (char_u *)"";
+	    continue;
+	}
+
+	/* Recognize a number argument, the others must be strings. */
+	vim_str2nr(argv[i], NULL, &len, TRUE, TRUE, &n, NULL);
+	if (len != 0 && len == (int)STRLEN(argv[i]))
+	{
+	    argvars[i].v_type = VAR_NUMBER;
+	    argvars[i].vval.v_number = n;
+	}
+	else
+	{
+	    argvars[i].v_type = VAR_STRING;
+	    argvars[i].vval.v_string = argv[i];
+	}
+    }
+
+    if (safe)
+    {
+	save_funccalp = save_funccal();
+	++sandbox;
+    }
+
+    rettv->v_type = VAR_UNKNOWN;		/* clear_tv() uses this */
+    ret = call_func(func, (int)STRLEN(func), rettv, argc, argvars,
+		    curwin->w_cursor.lnum, curwin->w_cursor.lnum,
+		    &doesrange, TRUE, NULL);
+    if (safe)
+    {
+	--sandbox;
+	restore_funccal(save_funccalp);
+    }
+    vim_free(argvars);
+
+    if (ret == FAIL)
+	clear_tv(rettv);
+
+    return ret;
+}
+
+/*
+ * Call vimL function "func" and return the result as a string.
+ * Returns NULL when calling the function fails.
+ * Uses argv[argc] for the function arguments.
+ */
+    void *
+call_func_retstr(func, argc, argv, safe)
+    char_u      *func;
+    int		argc;
+    char_u      **argv;
+    int		safe;		/* use the sandbox */
+{
+    typval_T	rettv;
+    char_u	*retval;
+
+    if (call_vim_function(func, argc, argv, safe, &rettv) == FAIL)
+	return NULL;
+
+    retval = vim_strsave(get_tv_string(&rettv));
+    clear_tv(&rettv);
+    return retval;
+}
+
+#if defined(FEAT_COMPL_FUNC) || defined(PROTO)
+/*
+ * Call vimL function "func" and return the result as a number.
+ * Returns -1 when calling the function fails.
+ * Uses argv[argc] for the function arguments.
+ */
+    long
+call_func_retnr(func, argc, argv, safe)
+    char_u      *func;
+    int		argc;
+    char_u      **argv;
+    int		safe;		/* use the sandbox */
+{
+    typval_T	rettv;
+    long	retval;
+
+    if (call_vim_function(func, argc, argv, safe, &rettv) == FAIL)
+	return -1;
+
+    retval = get_tv_number_chk(&rettv, NULL);
+    clear_tv(&rettv);
+    return retval;
+}
+#endif
+
+/*
+ * Call vimL function "func" and return the result as a list
+ * Uses argv[argc] for the function arguments.
+ */
+    void *
+call_func_retlist(func, argc, argv, safe)
+    char_u      *func;
+    int		argc;
+    char_u      **argv;
+    int		safe;		/* use the sandbox */
+{
+    typval_T	rettv;
+
+    if (call_vim_function(func, argc, argv, safe, &rettv) == FAIL)
+	return NULL;
+
+    if (rettv.v_type != VAR_LIST)
+    {
+	clear_tv(&rettv);
+	return NULL;
+    }
+
+    return rettv.vval.v_list;
+}
+
+#endif
+
+/*
+ * Save the current function call pointer, and set it to NULL.
+ * Used when executing autocommands and for ":source".
+ */
+    void *
+save_funccal()
+{
+    funccall_T *fc = current_funccal;
+
+    current_funccal = NULL;
+    return (void *)fc;
+}
+
+    void
+restore_funccal(vfc)
+    void *vfc;
+{
+    funccall_T *fc = (funccall_T *)vfc;
+
+    current_funccal = fc;
+}
+
+#if defined(FEAT_PROFILE) || defined(PROTO)
+/*
+ * Prepare profiling for entering a child or something else that is not
+ * counted for the script/function itself.
+ * Should always be called in pair with prof_child_exit().
+ */
+    void
+prof_child_enter(tm)
+    proftime_T *tm;	/* place to store waittime */
+{
+    funccall_T *fc = current_funccal;
+
+    if (fc != NULL && fc->func->uf_profiling)
+	profile_start(&fc->prof_child);
+    script_prof_save(tm);
+}
+
+/*
+ * Take care of time spent in a child.
+ * Should always be called after prof_child_enter().
+ */
+    void
+prof_child_exit(tm)
+    proftime_T *tm;	/* where waittime was stored */
+{
+    funccall_T *fc = current_funccal;
+
+    if (fc != NULL && fc->func->uf_profiling)
+    {
+	profile_end(&fc->prof_child);
+	profile_sub_wait(tm, &fc->prof_child); /* don't count waiting time */
+	profile_add(&fc->func->uf_tm_children, &fc->prof_child);
+	profile_add(&fc->func->uf_tml_children, &fc->prof_child);
+    }
+    script_prof_restore(tm);
+}
+#endif
+
+
+#ifdef FEAT_FOLDING
+/*
+ * Evaluate 'foldexpr'.  Returns the foldlevel, and any character preceding
+ * it in "*cp".  Doesn't give error messages.
+ */
+    int
+eval_foldexpr(arg, cp)
+    char_u	*arg;
+    int		*cp;
+{
+    typval_T	tv;
+    int		retval;
+    char_u	*s;
+    int		use_sandbox = was_set_insecurely((char_u *)"foldexpr",
+								   OPT_LOCAL);
+
+    ++emsg_off;
+    if (use_sandbox)
+	++sandbox;
+    ++textlock;
+    *cp = NUL;
+    if (eval0(arg, &tv, NULL, TRUE) == FAIL)
+	retval = 0;
+    else
+    {
+	/* If the result is a number, just return the number. */
+	if (tv.v_type == VAR_NUMBER)
+	    retval = tv.vval.v_number;
+	else if (tv.v_type != VAR_STRING || tv.vval.v_string == NULL)
+	    retval = 0;
+	else
+	{
+	    /* If the result is a string, check if there is a non-digit before
+	     * the number. */
+	    s = tv.vval.v_string;
+	    if (!VIM_ISDIGIT(*s) && *s != '-')
+		*cp = *s++;
+	    retval = atol((char *)s);
+	}
+	clear_tv(&tv);
+    }
+    --emsg_off;
+    if (use_sandbox)
+	--sandbox;
+    --textlock;
+
+    return retval;
+}
+#endif
+
+/*
+ * ":let"			list all variable values
+ * ":let var1 var2"		list variable values
+ * ":let var = expr"		assignment command.
+ * ":let var += expr"		assignment command.
+ * ":let var -= expr"		assignment command.
+ * ":let var .= expr"		assignment command.
+ * ":let [var1, var2] = expr"	unpack list.
+ */
+    void
+ex_let(eap)
+    exarg_T	*eap;
+{
+    char_u	*arg = eap->arg;
+    char_u	*expr = NULL;
+    typval_T	rettv;
+    int		i;
+    int		var_count = 0;
+    int		semicolon = 0;
+    char_u	op[2];
+    char_u	*argend;
+
+    argend = skip_var_list(arg, &var_count, &semicolon);
+    if (argend == NULL)
+	return;
+    if (argend > arg && argend[-1] == '.')  /* for var.='str' */
+	--argend;
+    expr = vim_strchr(argend, '=');
+    if (expr == NULL)
+    {
+	/*
+	 * ":let" without "=": list variables
+	 */
+	if (*arg == '[')
+	    EMSG(_(e_invarg));
+	else if (!ends_excmd(*arg))
+	    /* ":let var1 var2" */
+	    arg = list_arg_vars(eap, arg);
+	else if (!eap->skip)
+	{
+	    /* ":let" */
+	    list_glob_vars();
+	    list_buf_vars();
+	    list_win_vars();
+#ifdef FEAT_WINDOWS
+	    list_tab_vars();
+#endif
+	    list_script_vars();
+	    list_func_vars();
+	    list_vim_vars();
+	}
+	eap->nextcmd = check_nextcmd(arg);
+    }
+    else
+    {
+	op[0] = '=';
+	op[1] = NUL;
+	if (expr > argend)
+	{
+	    if (vim_strchr((char_u *)"+-.", expr[-1]) != NULL)
+		op[0] = expr[-1];   /* +=, -= or .= */
+	}
+	expr = skipwhite(expr + 1);
+
+	if (eap->skip)
+	    ++emsg_skip;
+	i = eval0(expr, &rettv, &eap->nextcmd, !eap->skip);
+	if (eap->skip)
+	{
+	    if (i != FAIL)
+		clear_tv(&rettv);
+	    --emsg_skip;
+	}
+	else if (i != FAIL)
+	{
+	    (void)ex_let_vars(eap->arg, &rettv, FALSE, semicolon, var_count,
+									  op);
+	    clear_tv(&rettv);
+	}
+    }
+}
+
+/*
+ * Assign the typevalue "tv" to the variable or variables at "arg_start".
+ * Handles both "var" with any type and "[var, var; var]" with a list type.
+ * When "nextchars" is not NULL it points to a string with characters that
+ * must appear after the variable(s).  Use "+", "-" or "." for add, subtract
+ * or concatenate.
+ * Returns OK or FAIL;
+ */
+    static int
+ex_let_vars(arg_start, tv, copy, semicolon, var_count, nextchars)
+    char_u	*arg_start;
+    typval_T	*tv;
+    int		copy;		/* copy values from "tv", don't move */
+    int		semicolon;	/* from skip_var_list() */
+    int		var_count;	/* from skip_var_list() */
+    char_u	*nextchars;
+{
+    char_u	*arg = arg_start;
+    list_T	*l;
+    int		i;
+    listitem_T	*item;
+    typval_T	ltv;
+
+    if (*arg != '[')
+    {
+	/*
+	 * ":let var = expr" or ":for var in list"
+	 */
+	if (ex_let_one(arg, tv, copy, nextchars, nextchars) == NULL)
+	    return FAIL;
+	return OK;
+    }
+
+    /*
+     * ":let [v1, v2] = list" or ":for [v1, v2] in listlist"
+     */
+    if (tv->v_type != VAR_LIST || (l = tv->vval.v_list) == NULL)
+    {
+	EMSG(_(e_listreq));
+	return FAIL;
+    }
+
+    i = list_len(l);
+    if (semicolon == 0 && var_count < i)
+    {
+	EMSG(_("E687: Less targets than List items"));
+	return FAIL;
+    }
+    if (var_count - semicolon > i)
+    {
+	EMSG(_("E688: More targets than List items"));
+	return FAIL;
+    }
+
+    item = l->lv_first;
+    while (*arg != ']')
+    {
+	arg = skipwhite(arg + 1);
+	arg = ex_let_one(arg, &item->li_tv, TRUE, (char_u *)",;]", nextchars);
+	item = item->li_next;
+	if (arg == NULL)
+	    return FAIL;
+
+	arg = skipwhite(arg);
+	if (*arg == ';')
+	{
+	    /* Put the rest of the list (may be empty) in the var after ';'.
+	     * Create a new list for this. */
+	    l = list_alloc();
+	    if (l == NULL)
+		return FAIL;
+	    while (item != NULL)
+	    {
+		list_append_tv(l, &item->li_tv);
+		item = item->li_next;
+	    }
+
+	    ltv.v_type = VAR_LIST;
+	    ltv.v_lock = 0;
+	    ltv.vval.v_list = l;
+	    l->lv_refcount = 1;
+
+	    arg = ex_let_one(skipwhite(arg + 1), &ltv, FALSE,
+						    (char_u *)"]", nextchars);
+	    clear_tv(&ltv);
+	    if (arg == NULL)
+		return FAIL;
+	    break;
+	}
+	else if (*arg != ',' && *arg != ']')
+	{
+	    EMSG2(_(e_intern2), "ex_let_vars()");
+	    return FAIL;
+	}
+    }
+
+    return OK;
+}
+
+/*
+ * Skip over assignable variable "var" or list of variables "[var, var]".
+ * Used for ":let varvar = expr" and ":for varvar in expr".
+ * For "[var, var]" increment "*var_count" for each variable.
+ * for "[var, var; var]" set "semicolon".
+ * Return NULL for an error.
+ */
+    static char_u *
+skip_var_list(arg, var_count, semicolon)
+    char_u	*arg;
+    int		*var_count;
+    int		*semicolon;
+{
+    char_u	*p, *s;
+
+    if (*arg == '[')
+    {
+	/* "[var, var]": find the matching ']'. */
+	p = arg;
+	for (;;)
+	{
+	    p = skipwhite(p + 1);	/* skip whites after '[', ';' or ',' */
+	    s = skip_var_one(p);
+	    if (s == p)
+	    {
+		EMSG2(_(e_invarg2), p);
+		return NULL;
+	    }
+	    ++*var_count;
+
+	    p = skipwhite(s);
+	    if (*p == ']')
+		break;
+	    else if (*p == ';')
+	    {
+		if (*semicolon == 1)
+		{
+		    EMSG(_("Double ; in list of variables"));
+		    return NULL;
+		}
+		*semicolon = 1;
+	    }
+	    else if (*p != ',')
+	    {
+		EMSG2(_(e_invarg2), p);
+		return NULL;
+	    }
+	}
+	return p + 1;
+    }
+    else
+	return skip_var_one(arg);
+}
+
+/*
+ * Skip one (assignable) variable name, including @r, $VAR, &option, d.key,
+ * l[idx].
+ */
+    static char_u *
+skip_var_one(arg)
+    char_u	*arg;
+{
+    if (*arg == '@' && arg[1] != NUL)
+	return arg + 2;
+    return find_name_end(*arg == '$' || *arg == '&' ? arg + 1 : arg,
+				   NULL, NULL, FNE_INCL_BR | FNE_CHECK_START);
+}
+
+/*
+ * List variables for hashtab "ht" with prefix "prefix".
+ * If "empty" is TRUE also list NULL strings as empty strings.
+ */
+    static void
+list_hashtable_vars(ht, prefix, empty)
+    hashtab_T	*ht;
+    char_u	*prefix;
+    int		empty;
+{
+    hashitem_T	*hi;
+    dictitem_T	*di;
+    int		todo;
+
+    todo = (int)ht->ht_used;
+    for (hi = ht->ht_array; todo > 0 && !got_int; ++hi)
+    {
+	if (!HASHITEM_EMPTY(hi))
+	{
+	    --todo;
+	    di = HI2DI(hi);
+	    if (empty || di->di_tv.v_type != VAR_STRING
+					   || di->di_tv.vval.v_string != NULL)
+		list_one_var(di, prefix);
+	}
+    }
+}
+
+/*
+ * List global variables.
+ */
+    static void
+list_glob_vars()
+{
+    list_hashtable_vars(&globvarht, (char_u *)"", TRUE);
+}
+
+/*
+ * List buffer variables.
+ */
+    static void
+list_buf_vars()
+{
+    char_u	numbuf[NUMBUFLEN];
+
+    list_hashtable_vars(&curbuf->b_vars.dv_hashtab, (char_u *)"b:", TRUE);
+
+    sprintf((char *)numbuf, "%ld", (long)curbuf->b_changedtick);
+    list_one_var_a((char_u *)"b:", (char_u *)"changedtick", VAR_NUMBER, numbuf);
+}
+
+/*
+ * List window variables.
+ */
+    static void
+list_win_vars()
+{
+    list_hashtable_vars(&curwin->w_vars.dv_hashtab, (char_u *)"w:", TRUE);
+}
+
+#ifdef FEAT_WINDOWS
+/*
+ * List tab page variables.
+ */
+    static void
+list_tab_vars()
+{
+    list_hashtable_vars(&curtab->tp_vars.dv_hashtab, (char_u *)"t:", TRUE);
+}
+#endif
+
+/*
+ * List Vim variables.
+ */
+    static void
+list_vim_vars()
+{
+    list_hashtable_vars(&vimvarht, (char_u *)"v:", FALSE);
+}
+
+/*
+ * List script-local variables, if there is a script.
+ */
+    static void
+list_script_vars()
+{
+    if (current_SID > 0 && current_SID <= ga_scripts.ga_len)
+	list_hashtable_vars(&SCRIPT_VARS(current_SID), (char_u *)"s:", FALSE);
+}
+
+/*
+ * List function variables, if there is a function.
+ */
+    static void
+list_func_vars()
+{
+    if (current_funccal != NULL)
+	list_hashtable_vars(&current_funccal->l_vars.dv_hashtab,
+						       (char_u *)"l:", FALSE);
+}
+
+/*
+ * List variables in "arg".
+ */
+    static char_u *
+list_arg_vars(eap, arg)
+    exarg_T	*eap;
+    char_u	*arg;
+{
+    int		error = FALSE;
+    int		len;
+    char_u	*name;
+    char_u	*name_start;
+    char_u	*arg_subsc;
+    char_u	*tofree;
+    typval_T    tv;
+
+    while (!ends_excmd(*arg) && !got_int)
+    {
+	if (error || eap->skip)
+	{
+	    arg = find_name_end(arg, NULL, NULL, FNE_INCL_BR | FNE_CHECK_START);
+	    if (!vim_iswhite(*arg) && !ends_excmd(*arg))
+	    {
+		emsg_severe = TRUE;
+		EMSG(_(e_trailing));
+		break;
+	    }
+	}
+	else
+	{
+	    /* get_name_len() takes care of expanding curly braces */
+	    name_start = name = arg;
+	    len = get_name_len(&arg, &tofree, TRUE, TRUE);
+	    if (len <= 0)
+	    {
+		/* This is mainly to keep test 49 working: when expanding
+		 * curly braces fails overrule the exception error message. */
+		if (len < 0 && !aborting())
+		{
+		    emsg_severe = TRUE;
+		    EMSG2(_(e_invarg2), arg);
+		    break;
+		}
+		error = TRUE;
+	    }
+	    else
+	    {
+		if (tofree != NULL)
+		    name = tofree;
+		if (get_var_tv(name, len, &tv, TRUE) == FAIL)
+		    error = TRUE;
+		else
+		{
+		    /* handle d.key, l[idx], f(expr) */
+		    arg_subsc = arg;
+		    if (handle_subscript(&arg, &tv, TRUE, TRUE) == FAIL)
+			error = TRUE;
+		    else
+		    {
+			if (arg == arg_subsc && len == 2 && name[1] == ':')
+			{
+			    switch (*name)
+			    {
+				case 'g': list_glob_vars(); break;
+				case 'b': list_buf_vars(); break;
+				case 'w': list_win_vars(); break;
+#ifdef FEAT_WINDOWS
+				case 't': list_tab_vars(); break;
+#endif
+				case 'v': list_vim_vars(); break;
+				case 's': list_script_vars(); break;
+				case 'l': list_func_vars(); break;
+				default:
+					  EMSG2(_("E738: Can't list variables for %s"), name);
+			    }
+			}
+			else
+			{
+			    char_u	numbuf[NUMBUFLEN];
+			    char_u	*tf;
+			    int		c;
+			    char_u	*s;
+
+			    s = echo_string(&tv, &tf, numbuf, 0);
+			    c = *arg;
+			    *arg = NUL;
+			    list_one_var_a((char_u *)"",
+				    arg == arg_subsc ? name : name_start,
+				    tv.v_type, s == NULL ? (char_u *)"" : s);
+			    *arg = c;
+			    vim_free(tf);
+			}
+			clear_tv(&tv);
+		    }
+		}
+	    }
+
+	    vim_free(tofree);
+	}
+
+	arg = skipwhite(arg);
+    }
+
+    return arg;
+}
+
+/*
+ * Set one item of ":let var = expr" or ":let [v1, v2] = list" to its value.
+ * Returns a pointer to the char just after the var name.
+ * Returns NULL if there is an error.
+ */
+    static char_u *
+ex_let_one(arg, tv, copy, endchars, op)
+    char_u	*arg;		/* points to variable name */
+    typval_T	*tv;		/* value to assign to variable */
+    int		copy;		/* copy value from "tv" */
+    char_u	*endchars;	/* valid chars after variable name  or NULL */
+    char_u	*op;		/* "+", "-", "."  or NULL*/
+{
+    int		c1;
+    char_u	*name;
+    char_u	*p;
+    char_u	*arg_end = NULL;
+    int		len;
+    int		opt_flags;
+    char_u	*tofree = NULL;
+
+    /*
+     * ":let $VAR = expr": Set environment variable.
+     */
+    if (*arg == '$')
+    {
+	/* Find the end of the name. */
+	++arg;
+	name = arg;
+	len = get_env_len(&arg);
+	if (len == 0)
+	    EMSG2(_(e_invarg2), name - 1);
+	else
+	{
+	    if (op != NULL && (*op == '+' || *op == '-'))
+		EMSG2(_(e_letwrong), op);
+	    else if (endchars != NULL
+			     && vim_strchr(endchars, *skipwhite(arg)) == NULL)
+		EMSG(_(e_letunexp));
+	    else
+	    {
+		c1 = name[len];
+		name[len] = NUL;
+		p = get_tv_string_chk(tv);
+		if (p != NULL && op != NULL && *op == '.')
+		{
+		    int	    mustfree = FALSE;
+		    char_u  *s = vim_getenv(name, &mustfree);
+
+		    if (s != NULL)
+		    {
+			p = tofree = concat_str(s, p);
+			if (mustfree)
+			    vim_free(s);
+		    }
+		}
+		if (p != NULL)
+		{
+		    vim_setenv(name, p);
+		    if (STRICMP(name, "HOME") == 0)
+			init_homedir();
+		    else if (didset_vim && STRICMP(name, "VIM") == 0)
+			didset_vim = FALSE;
+		    else if (didset_vimruntime
+					&& STRICMP(name, "VIMRUNTIME") == 0)
+			didset_vimruntime = FALSE;
+		    arg_end = arg;
+		}
+		name[len] = c1;
+		vim_free(tofree);
+	    }
+	}
+    }
+
+    /*
+     * ":let &option = expr": Set option value.
+     * ":let &l:option = expr": Set local option value.
+     * ":let &g:option = expr": Set global option value.
+     */
+    else if (*arg == '&')
+    {
+	/* Find the end of the name. */
+	p = find_option_end(&arg, &opt_flags);
+	if (p == NULL || (endchars != NULL
+			      && vim_strchr(endchars, *skipwhite(p)) == NULL))
+	    EMSG(_(e_letunexp));
+	else
+	{
+	    long	n;
+	    int		opt_type;
+	    long	numval;
+	    char_u	*stringval = NULL;
+	    char_u	*s;
+
+	    c1 = *p;
+	    *p = NUL;
+
+	    n = get_tv_number(tv);
+	    s = get_tv_string_chk(tv);	    /* != NULL if number or string */
+	    if (s != NULL && op != NULL && *op != '=')
+	    {
+		opt_type = get_option_value(arg, &numval,
+						       &stringval, opt_flags);
+		if ((opt_type == 1 && *op == '.')
+			|| (opt_type == 0 && *op != '.'))
+		    EMSG2(_(e_letwrong), op);
+		else
+		{
+		    if (opt_type == 1)  /* number */
+		    {
+			if (*op == '+')
+			    n = numval + n;
+			else
+			    n = numval - n;
+		    }
+		    else if (opt_type == 0 && stringval != NULL) /* string */
+		    {
+			s = concat_str(stringval, s);
+			vim_free(stringval);
+			stringval = s;
+		    }
+		}
+	    }
+	    if (s != NULL)
+	    {
+		set_option_value(arg, n, s, opt_flags);
+		arg_end = p;
+	    }
+	    *p = c1;
+	    vim_free(stringval);
+	}
+    }
+
+    /*
+     * ":let @r = expr": Set register contents.
+     */
+    else if (*arg == '@')
+    {
+	++arg;
+	if (op != NULL && (*op == '+' || *op == '-'))
+	    EMSG2(_(e_letwrong), op);
+	else if (endchars != NULL
+			 && vim_strchr(endchars, *skipwhite(arg + 1)) == NULL)
+	    EMSG(_(e_letunexp));
+	else
+	{
+	    char_u	*ptofree = NULL;
+	    char_u	*s;
+
+	    p = get_tv_string_chk(tv);
+	    if (p != NULL && op != NULL && *op == '.')
+	    {
+		s = get_reg_contents(*arg == '@' ? '"' : *arg, TRUE, TRUE);
+		if (s != NULL)
+		{
+		    p = ptofree = concat_str(s, p);
+		    vim_free(s);
+		}
+	    }
+	    if (p != NULL)
+	    {
+		write_reg_contents(*arg == '@' ? '"' : *arg, p, -1, FALSE);
+		arg_end = arg + 1;
+	    }
+	    vim_free(ptofree);
+	}
+    }
+
+    /*
+     * ":let var = expr": Set internal variable.
+     * ":let {expr} = expr": Idem, name made with curly braces
+     */
+    else if (eval_isnamec1(*arg) || *arg == '{')
+    {
+	lval_T	lv;
+
+	p = get_lval(arg, tv, &lv, FALSE, FALSE, FALSE, FNE_CHECK_START);
+	if (p != NULL && lv.ll_name != NULL)
+	{
+	    if (endchars != NULL && vim_strchr(endchars, *skipwhite(p)) == NULL)
+		EMSG(_(e_letunexp));
+	    else
+	    {
+		set_var_lval(&lv, p, tv, copy, op);
+		arg_end = p;
+	    }
+	}
+	clear_lval(&lv);
+    }
+
+    else
+	EMSG2(_(e_invarg2), arg);
+
+    return arg_end;
+}
+
+/*
+ * If "arg" is equal to "b:changedtick" give an error and return TRUE.
+ */
+    static int
+check_changedtick(arg)
+    char_u	*arg;
+{
+    if (STRNCMP(arg, "b:changedtick", 13) == 0 && !eval_isnamec(arg[13]))
+    {
+	EMSG2(_(e_readonlyvar), arg);
+	return TRUE;
+    }
+    return FALSE;
+}
+
+/*
+ * Get an lval: variable, Dict item or List item that can be assigned a value
+ * to: "name", "na{me}", "name[expr]", "name[expr:expr]", "name[expr][expr]",
+ * "name.key", "name.key[expr]" etc.
+ * Indexing only works if "name" is an existing List or Dictionary.
+ * "name" points to the start of the name.
+ * If "rettv" is not NULL it points to the value to be assigned.
+ * "unlet" is TRUE for ":unlet": slightly different behavior when something is
+ * wrong; must end in space or cmd separator.
+ *
+ * Returns a pointer to just after the name, including indexes.
+ * When an evaluation error occurs "lp->ll_name" is NULL;
+ * Returns NULL for a parsing error.  Still need to free items in "lp"!
+ */
+    static char_u *
+get_lval(name, rettv, lp, unlet, skip, quiet, fne_flags)
+    char_u	*name;
+    typval_T	*rettv;
+    lval_T	*lp;
+    int		unlet;
+    int		skip;
+    int		quiet;	    /* don't give error messages */
+    int		fne_flags;  /* flags for find_name_end() */
+{
+    char_u	*p;
+    char_u	*expr_start, *expr_end;
+    int		cc;
+    dictitem_T	*v;
+    typval_T	var1;
+    typval_T	var2;
+    int		empty1 = FALSE;
+    listitem_T	*ni;
+    char_u	*key = NULL;
+    int		len;
+    hashtab_T	*ht;
+
+    /* Clear everything in "lp". */
+    vim_memset(lp, 0, sizeof(lval_T));
+
+    if (skip)
+    {
+	/* When skipping just find the end of the name. */
+	lp->ll_name = name;
+	return find_name_end(name, NULL, NULL, FNE_INCL_BR | fne_flags);
+    }
+
+    /* Find the end of the name. */
+    p = find_name_end(name, &expr_start, &expr_end, fne_flags);
+    if (expr_start != NULL)
+    {
+	/* Don't expand the name when we already know there is an error. */
+	if (unlet && !vim_iswhite(*p) && !ends_excmd(*p)
+						    && *p != '[' && *p != '.')
+	{
+	    EMSG(_(e_trailing));
+	    return NULL;
+	}
+
+	lp->ll_exp_name = make_expanded_name(name, expr_start, expr_end, p);
+	if (lp->ll_exp_name == NULL)
+	{
+	    /* Report an invalid expression in braces, unless the
+	     * expression evaluation has been cancelled due to an
+	     * aborting error, an interrupt, or an exception. */
+	    if (!aborting() && !quiet)
+	    {
+		emsg_severe = TRUE;
+		EMSG2(_(e_invarg2), name);
+		return NULL;
+	    }
+	}
+	lp->ll_name = lp->ll_exp_name;
+    }
+    else
+	lp->ll_name = name;
+
+    /* Without [idx] or .key we are done. */
+    if ((*p != '[' && *p != '.') || lp->ll_name == NULL)
+	return p;
+
+    cc = *p;
+    *p = NUL;
+    v = find_var(lp->ll_name, &ht);
+    if (v == NULL && !quiet)
+	EMSG2(_(e_undefvar), lp->ll_name);
+    *p = cc;
+    if (v == NULL)
+	return NULL;
+
+    /*
+     * Loop until no more [idx] or .key is following.
+     */
+    lp->ll_tv = &v->di_tv;
+    while (*p == '[' || (*p == '.' && lp->ll_tv->v_type == VAR_DICT))
+    {
+	if (!(lp->ll_tv->v_type == VAR_LIST && lp->ll_tv->vval.v_list != NULL)
+		&& !(lp->ll_tv->v_type == VAR_DICT
+					   && lp->ll_tv->vval.v_dict != NULL))
+	{
+	    if (!quiet)
+		EMSG(_("E689: Can only index a List or Dictionary"));
+	    return NULL;
+	}
+	if (lp->ll_range)
+	{
+	    if (!quiet)
+		EMSG(_("E708: [:] must come last"));
+	    return NULL;
+	}
+
+	len = -1;
+	if (*p == '.')
+	{
+	    key = p + 1;
+	    for (len = 0; ASCII_ISALNUM(key[len]) || key[len] == '_'; ++len)
+		;
+	    if (len == 0)
+	    {
+		if (!quiet)
+		    EMSG(_(e_emptykey));
+		return NULL;
+	    }
+	    p = key + len;
+	}
+	else
+	{
+	    /* Get the index [expr] or the first index [expr: ]. */
+	    p = skipwhite(p + 1);
+	    if (*p == ':')
+		empty1 = TRUE;
+	    else
+	    {
+		empty1 = FALSE;
+		if (eval1(&p, &var1, TRUE) == FAIL)	/* recursive! */
+		    return NULL;
+		if (get_tv_string_chk(&var1) == NULL)
+		{
+		    /* not a number or string */
+		    clear_tv(&var1);
+		    return NULL;
+		}
+	    }
+
+	    /* Optionally get the second index [ :expr]. */
+	    if (*p == ':')
+	    {
+		if (lp->ll_tv->v_type == VAR_DICT)
+		{
+		    if (!quiet)
+			EMSG(_(e_dictrange));
+		    if (!empty1)
+			clear_tv(&var1);
+		    return NULL;
+		}
+		if (rettv != NULL && (rettv->v_type != VAR_LIST
+					       || rettv->vval.v_list == NULL))
+		{
+		    if (!quiet)
+			EMSG(_("E709: [:] requires a List value"));
+		    if (!empty1)
+			clear_tv(&var1);
+		    return NULL;
+		}
+		p = skipwhite(p + 1);
+		if (*p == ']')
+		    lp->ll_empty2 = TRUE;
+		else
+		{
+		    lp->ll_empty2 = FALSE;
+		    if (eval1(&p, &var2, TRUE) == FAIL)	/* recursive! */
+		    {
+			if (!empty1)
+			    clear_tv(&var1);
+			return NULL;
+		    }
+		    if (get_tv_string_chk(&var2) == NULL)
+		    {
+			/* not a number or string */
+			if (!empty1)
+			    clear_tv(&var1);
+			clear_tv(&var2);
+			return NULL;
+		    }
+		}
+		lp->ll_range = TRUE;
+	    }
+	    else
+		lp->ll_range = FALSE;
+
+	    if (*p != ']')
+	    {
+		if (!quiet)
+		    EMSG(_(e_missbrac));
+		if (!empty1)
+		    clear_tv(&var1);
+		if (lp->ll_range && !lp->ll_empty2)
+		    clear_tv(&var2);
+		return NULL;
+	    }
+
+	    /* Skip to past ']'. */
+	    ++p;
+	}
+
+	if (lp->ll_tv->v_type == VAR_DICT)
+	{
+	    if (len == -1)
+	    {
+		/* "[key]": get key from "var1" */
+		key = get_tv_string(&var1);	/* is number or string */
+		if (*key == NUL)
+		{
+		    if (!quiet)
+			EMSG(_(e_emptykey));
+		    clear_tv(&var1);
+		    return NULL;
+		}
+	    }
+	    lp->ll_list = NULL;
+	    lp->ll_dict = lp->ll_tv->vval.v_dict;
+	    lp->ll_di = dict_find(lp->ll_dict, key, len);
+	    if (lp->ll_di == NULL)
+	    {
+		/* Key does not exist in dict: may need to add it. */
+		if (*p == '[' || *p == '.' || unlet)
+		{
+		    if (!quiet)
+			EMSG2(_(e_dictkey), key);
+		    if (len == -1)
+			clear_tv(&var1);
+		    return NULL;
+		}
+		if (len == -1)
+		    lp->ll_newkey = vim_strsave(key);
+		else
+		    lp->ll_newkey = vim_strnsave(key, len);
+		if (len == -1)
+		    clear_tv(&var1);
+		if (lp->ll_newkey == NULL)
+		    p = NULL;
+		break;
+	    }
+	    if (len == -1)
+		clear_tv(&var1);
+	    lp->ll_tv = &lp->ll_di->di_tv;
+	}
+	else
+	{
+	    /*
+	     * Get the number and item for the only or first index of the List.
+	     */
+	    if (empty1)
+		lp->ll_n1 = 0;
+	    else
+	    {
+		lp->ll_n1 = get_tv_number(&var1);   /* is number or string */
+		clear_tv(&var1);
+	    }
+	    lp->ll_dict = NULL;
+	    lp->ll_list = lp->ll_tv->vval.v_list;
+	    lp->ll_li = list_find(lp->ll_list, lp->ll_n1);
+	    if (lp->ll_li == NULL)
+	    {
+		if (lp->ll_n1 < 0)
+		{
+		    lp->ll_n1 = 0;
+		    lp->ll_li = list_find(lp->ll_list, lp->ll_n1);
+		}
+	    }
+	    if (lp->ll_li == NULL)
+	    {
+		if (lp->ll_range && !lp->ll_empty2)
+		    clear_tv(&var2);
+		return NULL;
+	    }
+
+	    /*
+	     * May need to find the item or absolute index for the second
+	     * index of a range.
+	     * When no index given: "lp->ll_empty2" is TRUE.
+	     * Otherwise "lp->ll_n2" is set to the second index.
+	     */
+	    if (lp->ll_range && !lp->ll_empty2)
+	    {
+		lp->ll_n2 = get_tv_number(&var2);   /* is number or string */
+		clear_tv(&var2);
+		if (lp->ll_n2 < 0)
+		{
+		    ni = list_find(lp->ll_list, lp->ll_n2);
+		    if (ni == NULL)
+			return NULL;
+		    lp->ll_n2 = list_idx_of_item(lp->ll_list, ni);
+		}
+
+		/* Check that lp->ll_n2 isn't before lp->ll_n1. */
+		if (lp->ll_n1 < 0)
+		    lp->ll_n1 = list_idx_of_item(lp->ll_list, lp->ll_li);
+		if (lp->ll_n2 < lp->ll_n1)
+		    return NULL;
+	    }
+
+	    lp->ll_tv = &lp->ll_li->li_tv;
+	}
+    }
+
+    return p;
+}
+
+/*
+ * Clear lval "lp" that was filled by get_lval().
+ */
+    static void
+clear_lval(lp)
+    lval_T	*lp;
+{
+    vim_free(lp->ll_exp_name);
+    vim_free(lp->ll_newkey);
+}
+
+/*
+ * Set a variable that was parsed by get_lval() to "rettv".
+ * "endp" points to just after the parsed name.
+ * "op" is NULL, "+" for "+=", "-" for "-=", "." for ".=" or "=" for "=".
+ */
+    static void
+set_var_lval(lp, endp, rettv, copy, op)
+    lval_T	*lp;
+    char_u	*endp;
+    typval_T	*rettv;
+    int		copy;
+    char_u	*op;
+{
+    int		cc;
+    listitem_T	*ri;
+    dictitem_T	*di;
+
+    if (lp->ll_tv == NULL)
+    {
+	if (!check_changedtick(lp->ll_name))
+	{
+	    cc = *endp;
+	    *endp = NUL;
+	    if (op != NULL && *op != '=')
+	    {
+		typval_T tv;
+
+		/* handle +=, -= and .= */
+		if (get_var_tv(lp->ll_name, (int)STRLEN(lp->ll_name),
+							     &tv, TRUE) == OK)
+		{
+		    if (tv_op(&tv, rettv, op) == OK)
+			set_var(lp->ll_name, &tv, FALSE);
+		    clear_tv(&tv);
+		}
+	    }
+	    else
+		set_var(lp->ll_name, rettv, copy);
+	    *endp = cc;
+	}
+    }
+    else if (tv_check_lock(lp->ll_newkey == NULL
+		? lp->ll_tv->v_lock
+		: lp->ll_tv->vval.v_dict->dv_lock, lp->ll_name))
+	;
+    else if (lp->ll_range)
+    {
+	/*
+	 * Assign the List values to the list items.
+	 */
+	for (ri = rettv->vval.v_list->lv_first; ri != NULL; )
+	{
+	    if (op != NULL && *op != '=')
+		tv_op(&lp->ll_li->li_tv, &ri->li_tv, op);
+	    else
+	    {
+		clear_tv(&lp->ll_li->li_tv);
+		copy_tv(&ri->li_tv, &lp->ll_li->li_tv);
+	    }
+	    ri = ri->li_next;
+	    if (ri == NULL || (!lp->ll_empty2 && lp->ll_n2 == lp->ll_n1))
+		break;
+	    if (lp->ll_li->li_next == NULL)
+	    {
+		/* Need to add an empty item. */
+		if (list_append_number(lp->ll_list, 0) == FAIL)
+		{
+		    ri = NULL;
+		    break;
+		}
+	    }
+	    lp->ll_li = lp->ll_li->li_next;
+	    ++lp->ll_n1;
+	}
+	if (ri != NULL)
+	    EMSG(_("E710: List value has more items than target"));
+	else if (lp->ll_empty2
+		? (lp->ll_li != NULL && lp->ll_li->li_next != NULL)
+		: lp->ll_n1 != lp->ll_n2)
+	    EMSG(_("E711: List value has not enough items"));
+    }
+    else
+    {
+	/*
+	 * Assign to a List or Dictionary item.
+	 */
+	if (lp->ll_newkey != NULL)
+	{
+	    if (op != NULL && *op != '=')
+	    {
+		EMSG2(_(e_letwrong), op);
+		return;
+	    }
+
+	    /* Need to add an item to the Dictionary. */
+	    di = dictitem_alloc(lp->ll_newkey);
+	    if (di == NULL)
+		return;
+	    if (dict_add(lp->ll_tv->vval.v_dict, di) == FAIL)
+	    {
+		vim_free(di);
+		return;
+	    }
+	    lp->ll_tv = &di->di_tv;
+	}
+	else if (op != NULL && *op != '=')
+	{
+	    tv_op(lp->ll_tv, rettv, op);
+	    return;
+	}
+	else
+	    clear_tv(lp->ll_tv);
+
+	/*
+	 * Assign the value to the variable or list item.
+	 */
+	if (copy)
+	    copy_tv(rettv, lp->ll_tv);
+	else
+	{
+	    *lp->ll_tv = *rettv;
+	    lp->ll_tv->v_lock = 0;
+	    init_tv(rettv);
+	}
+    }
+}
+
+/*
+ * Handle "tv1 += tv2", "tv1 -= tv2" and "tv1 .= tv2"
+ * Returns OK or FAIL.
+ */
+    static int
+tv_op(tv1, tv2, op)
+    typval_T *tv1;
+    typval_T *tv2;
+    char_u  *op;
+{
+    long	n;
+    char_u	numbuf[NUMBUFLEN];
+    char_u	*s;
+
+    /* Can't do anything with a Funcref or a Dict on the right. */
+    if (tv2->v_type != VAR_FUNC && tv2->v_type != VAR_DICT)
+    {
+	switch (tv1->v_type)
+	{
+	    case VAR_DICT:
+	    case VAR_FUNC:
+		break;
+
+	    case VAR_LIST:
+		if (*op != '+' || tv2->v_type != VAR_LIST)
+		    break;
+		/* List += List */
+		if (tv1->vval.v_list != NULL && tv2->vval.v_list != NULL)
+		    list_extend(tv1->vval.v_list, tv2->vval.v_list, NULL);
+		return OK;
+
+	    case VAR_NUMBER:
+	    case VAR_STRING:
+		if (tv2->v_type == VAR_LIST)
+		    break;
+		if (*op == '+' || *op == '-')
+		{
+		    /* nr += nr  or  nr -= nr*/
+		    n = get_tv_number(tv1);
+		    if (*op == '+')
+			n += get_tv_number(tv2);
+		    else
+			n -= get_tv_number(tv2);
+		    clear_tv(tv1);
+		    tv1->v_type = VAR_NUMBER;
+		    tv1->vval.v_number = n;
+		}
+		else
+		{
+		    /* str .= str */
+		    s = get_tv_string(tv1);
+		    s = concat_str(s, get_tv_string_buf(tv2, numbuf));
+		    clear_tv(tv1);
+		    tv1->v_type = VAR_STRING;
+		    tv1->vval.v_string = s;
+		}
+		return OK;
+	}
+    }
+
+    EMSG2(_(e_letwrong), op);
+    return FAIL;
+}
+
+/*
+ * Add a watcher to a list.
+ */
+    static void
+list_add_watch(l, lw)
+    list_T	*l;
+    listwatch_T	*lw;
+{
+    lw->lw_next = l->lv_watch;
+    l->lv_watch = lw;
+}
+
+/*
+ * Remove a watcher from a list.
+ * No warning when it isn't found...
+ */
+    static void
+list_rem_watch(l, lwrem)
+    list_T	*l;
+    listwatch_T	*lwrem;
+{
+    listwatch_T	*lw, **lwp;
+
+    lwp = &l->lv_watch;
+    for (lw = l->lv_watch; lw != NULL; lw = lw->lw_next)
+    {
+	if (lw == lwrem)
+	{
+	    *lwp = lw->lw_next;
+	    break;
+	}
+	lwp = &lw->lw_next;
+    }
+}
+
+/*
+ * Just before removing an item from a list: advance watchers to the next
+ * item.
+ */
+    static void
+list_fix_watch(l, item)
+    list_T	*l;
+    listitem_T	*item;
+{
+    listwatch_T	*lw;
+
+    for (lw = l->lv_watch; lw != NULL; lw = lw->lw_next)
+	if (lw->lw_item == item)
+	    lw->lw_item = item->li_next;
+}
+
+/*
+ * Evaluate the expression used in a ":for var in expr" command.
+ * "arg" points to "var".
+ * Set "*errp" to TRUE for an error, FALSE otherwise;
+ * Return a pointer that holds the info.  Null when there is an error.
+ */
+    void *
+eval_for_line(arg, errp, nextcmdp, skip)
+    char_u	*arg;
+    int		*errp;
+    char_u	**nextcmdp;
+    int		skip;
+{
+    forinfo_T	*fi;
+    char_u	*expr;
+    typval_T	tv;
+    list_T	*l;
+
+    *errp = TRUE;	/* default: there is an error */
+
+    fi = (forinfo_T *)alloc_clear(sizeof(forinfo_T));
+    if (fi == NULL)
+	return NULL;
+
+    expr = skip_var_list(arg, &fi->fi_varcount, &fi->fi_semicolon);
+    if (expr == NULL)
+	return fi;
+
+    expr = skipwhite(expr);
+    if (expr[0] != 'i' || expr[1] != 'n' || !vim_iswhite(expr[2]))
+    {
+	EMSG(_("E690: Missing \"in\" after :for"));
+	return fi;
+    }
+
+    if (skip)
+	++emsg_skip;
+    if (eval0(skipwhite(expr + 2), &tv, nextcmdp, !skip) == OK)
+    {
+	*errp = FALSE;
+	if (!skip)
+	{
+	    l = tv.vval.v_list;
+	    if (tv.v_type != VAR_LIST || l == NULL)
+	    {
+		EMSG(_(e_listreq));
+		clear_tv(&tv);
+	    }
+	    else
+	    {
+		/* No need to increment the refcount, it's already set for the
+		 * list being used in "tv". */
+		fi->fi_list = l;
+		list_add_watch(l, &fi->fi_lw);
+		fi->fi_lw.lw_item = l->lv_first;
+	    }
+	}
+    }
+    if (skip)
+	--emsg_skip;
+
+    return fi;
+}
+
+/*
+ * Use the first item in a ":for" list.  Advance to the next.
+ * Assign the values to the variable (list).  "arg" points to the first one.
+ * Return TRUE when a valid item was found, FALSE when at end of list or
+ * something wrong.
+ */
+    int
+next_for_item(fi_void, arg)
+    void	*fi_void;
+    char_u	*arg;
+{
+    forinfo_T    *fi = (forinfo_T *)fi_void;
+    int		result;
+    listitem_T	*item;
+
+    item = fi->fi_lw.lw_item;
+    if (item == NULL)
+	result = FALSE;
+    else
+    {
+	fi->fi_lw.lw_item = item->li_next;
+	result = (ex_let_vars(arg, &item->li_tv, TRUE,
+			      fi->fi_semicolon, fi->fi_varcount, NULL) == OK);
+    }
+    return result;
+}
+
+/*
+ * Free the structure used to store info used by ":for".
+ */
+    void
+free_for_info(fi_void)
+    void *fi_void;
+{
+    forinfo_T    *fi = (forinfo_T *)fi_void;
+
+    if (fi != NULL && fi->fi_list != NULL)
+    {
+	list_rem_watch(fi->fi_list, &fi->fi_lw);
+	list_unref(fi->fi_list);
+    }
+    vim_free(fi);
+}
+
+#if defined(FEAT_CMDL_COMPL) || defined(PROTO)
+
+    void
+set_context_for_expression(xp, arg, cmdidx)
+    expand_T	*xp;
+    char_u	*arg;
+    cmdidx_T	cmdidx;
+{
+    int		got_eq = FALSE;
+    int		c;
+    char_u	*p;
+
+    if (cmdidx == CMD_let)
+    {
+	xp->xp_context = EXPAND_USER_VARS;
+	if (vim_strpbrk(arg, (char_u *)"\"'+-*/%.=!?~|&$([<>,#") == NULL)
+	{
+	    /* ":let var1 var2 ...": find last space. */
+	    for (p = arg + STRLEN(arg); p >= arg; )
+	    {
+		xp->xp_pattern = p;
+		mb_ptr_back(arg, p);
+		if (vim_iswhite(*p))
+		    break;
+	    }
+	    return;
+	}
+    }
+    else
+	xp->xp_context = cmdidx == CMD_call ? EXPAND_FUNCTIONS
+							  : EXPAND_EXPRESSION;
+    while ((xp->xp_pattern = vim_strpbrk(arg,
+				  (char_u *)"\"'+-*/%.=!?~|&$([<>,#")) != NULL)
+    {
+	c = *xp->xp_pattern;
+	if (c == '&')
+	{
+	    c = xp->xp_pattern[1];
+	    if (c == '&')
+	    {
+		++xp->xp_pattern;
+		xp->xp_context = cmdidx != CMD_let || got_eq
+					 ? EXPAND_EXPRESSION : EXPAND_NOTHING;
+	    }
+	    else if (c != ' ')
+	    {
+		xp->xp_context = EXPAND_SETTINGS;
+		if ((c == 'l' || c == 'g') && xp->xp_pattern[2] == ':')
+		    xp->xp_pattern += 2;
+
+	    }
+	}
+	else if (c == '$')
+	{
+	    /* environment variable */
+	    xp->xp_context = EXPAND_ENV_VARS;
+	}
+	else if (c == '=')
+	{
+	    got_eq = TRUE;
+	    xp->xp_context = EXPAND_EXPRESSION;
+	}
+	else if (c == '<'
+		&& xp->xp_context == EXPAND_FUNCTIONS
+		&& vim_strchr(xp->xp_pattern, '(') == NULL)
+	{
+	    /* Function name can start with "<SNR>" */
+	    break;
+	}
+	else if (cmdidx != CMD_let || got_eq)
+	{
+	    if (c == '"')	    /* string */
+	    {
+		while ((c = *++xp->xp_pattern) != NUL && c != '"')
+		    if (c == '\\' && xp->xp_pattern[1] != NUL)
+			++xp->xp_pattern;
+		xp->xp_context = EXPAND_NOTHING;
+	    }
+	    else if (c == '\'')	    /* literal string */
+	    {
+		/* Trick: '' is like stopping and starting a literal string. */
+		while ((c = *++xp->xp_pattern) != NUL && c != '\'')
+		    /* skip */ ;
+		xp->xp_context = EXPAND_NOTHING;
+	    }
+	    else if (c == '|')
+	    {
+		if (xp->xp_pattern[1] == '|')
+		{
+		    ++xp->xp_pattern;
+		    xp->xp_context = EXPAND_EXPRESSION;
+		}
+		else
+		    xp->xp_context = EXPAND_COMMANDS;
+	    }
+	    else
+		xp->xp_context = EXPAND_EXPRESSION;
+	}
+	else
+	    /* Doesn't look like something valid, expand as an expression
+	     * anyway. */
+	    xp->xp_context = EXPAND_EXPRESSION;
+	arg = xp->xp_pattern;
+	if (*arg != NUL)
+	    while ((c = *++arg) != NUL && (c == ' ' || c == '\t'))
+		/* skip */ ;
+    }
+    xp->xp_pattern = arg;
+}
+
+#endif /* FEAT_CMDL_COMPL */
+
+/*
+ * ":1,25call func(arg1, arg2)"	function call.
+ */
+    void
+ex_call(eap)
+    exarg_T	*eap;
+{
+    char_u	*arg = eap->arg;
+    char_u	*startarg;
+    char_u	*name;
+    char_u	*tofree;
+    int		len;
+    typval_T	rettv;
+    linenr_T	lnum;
+    int		doesrange;
+    int		failed = FALSE;
+    funcdict_T	fudi;
+
+    tofree = trans_function_name(&arg, eap->skip, TFN_INT, &fudi);
+    if (fudi.fd_newkey != NULL)
+    {
+	/* Still need to give an error message for missing key. */
+	EMSG2(_(e_dictkey), fudi.fd_newkey);
+	vim_free(fudi.fd_newkey);
+    }
+    if (tofree == NULL)
+	return;
+
+    /* Increase refcount on dictionary, it could get deleted when evaluating
+     * the arguments. */
+    if (fudi.fd_dict != NULL)
+	++fudi.fd_dict->dv_refcount;
+
+    /* If it is the name of a variable of type VAR_FUNC use its contents. */
+    len = (int)STRLEN(tofree);
+    name = deref_func_name(tofree, &len);
+
+    /* Skip white space to allow ":call func ()".  Not good, but required for
+     * backward compatibility. */
+    startarg = skipwhite(arg);
+    rettv.v_type = VAR_UNKNOWN;	/* clear_tv() uses this */
+
+    if (*startarg != '(')
+    {
+	EMSG2(_("E107: Missing braces: %s"), eap->arg);
+	goto end;
+    }
+
+    /*
+     * When skipping, evaluate the function once, to find the end of the
+     * arguments.
+     * When the function takes a range, this is discovered after the first
+     * call, and the loop is broken.
+     */
+    if (eap->skip)
+    {
+	++emsg_skip;
+	lnum = eap->line2;	/* do it once, also with an invalid range */
+    }
+    else
+	lnum = eap->line1;
+    for ( ; lnum <= eap->line2; ++lnum)
+    {
+	if (!eap->skip && eap->addr_count > 0)
+	{
+	    curwin->w_cursor.lnum = lnum;
+	    curwin->w_cursor.col = 0;
+	}
+	arg = startarg;
+	if (get_func_tv(name, (int)STRLEN(name), &rettv, &arg,
+		    eap->line1, eap->line2, &doesrange,
+					    !eap->skip, fudi.fd_dict) == FAIL)
+	{
+	    failed = TRUE;
+	    break;
+	}
+
+	/* Handle a function returning a Funcref, Dictionary or List. */
+	if (handle_subscript(&arg, &rettv, !eap->skip, TRUE) == FAIL)
+	{
+	    failed = TRUE;
+	    break;
+	}
+
+	clear_tv(&rettv);
+	if (doesrange || eap->skip)
+	    break;
+
+	/* Stop when immediately aborting on error, or when an interrupt
+	 * occurred or an exception was thrown but not caught.
+	 * get_func_tv() returned OK, so that the check for trailing
+	 * characters below is executed. */
+	if (aborting())
+	    break;
+    }
+    if (eap->skip)
+	--emsg_skip;
+
+    if (!failed)
+    {
+	/* Check for trailing illegal characters and a following command. */
+	if (!ends_excmd(*arg))
+	{
+	    emsg_severe = TRUE;
+	    EMSG(_(e_trailing));
+	}
+	else
+	    eap->nextcmd = check_nextcmd(arg);
+    }
+
+end:
+    dict_unref(fudi.fd_dict);
+    vim_free(tofree);
+}
+
+/*
+ * ":unlet[!] var1 ... " command.
+ */
+    void
+ex_unlet(eap)
+    exarg_T	*eap;
+{
+    ex_unletlock(eap, eap->arg, 0);
+}
+
+/*
+ * ":lockvar" and ":unlockvar" commands
+ */
+    void
+ex_lockvar(eap)
+    exarg_T	*eap;
+{
+    char_u	*arg = eap->arg;
+    int		deep = 2;
+
+    if (eap->forceit)
+	deep = -1;
+    else if (vim_isdigit(*arg))
+    {
+	deep = getdigits(&arg);
+	arg = skipwhite(arg);
+    }
+
+    ex_unletlock(eap, arg, deep);
+}
+
+/*
+ * ":unlet", ":lockvar" and ":unlockvar" are quite similar.
+ */
+    static void
+ex_unletlock(eap, argstart, deep)
+    exarg_T	*eap;
+    char_u	*argstart;
+    int		deep;
+{
+    char_u	*arg = argstart;
+    char_u	*name_end;
+    int		error = FALSE;
+    lval_T	lv;
+
+    do
+    {
+	/* Parse the name and find the end. */
+	name_end = get_lval(arg, NULL, &lv, TRUE, eap->skip || error, FALSE,
+							     FNE_CHECK_START);
+	if (lv.ll_name == NULL)
+	    error = TRUE;	    /* error but continue parsing */
+	if (name_end == NULL || (!vim_iswhite(*name_end)
+						   && !ends_excmd(*name_end)))
+	{
+	    if (name_end != NULL)
+	    {
+		emsg_severe = TRUE;
+		EMSG(_(e_trailing));
+	    }
+	    if (!(eap->skip || error))
+		clear_lval(&lv);
+	    break;
+	}
+
+	if (!error && !eap->skip)
+	{
+	    if (eap->cmdidx == CMD_unlet)
+	    {
+		if (do_unlet_var(&lv, name_end, eap->forceit) == FAIL)
+		    error = TRUE;
+	    }
+	    else
+	    {
+		if (do_lock_var(&lv, name_end, deep,
+					  eap->cmdidx == CMD_lockvar) == FAIL)
+		    error = TRUE;
+	    }
+	}
+
+	if (!eap->skip)
+	    clear_lval(&lv);
+
+	arg = skipwhite(name_end);
+    } while (!ends_excmd(*arg));
+
+    eap->nextcmd = check_nextcmd(arg);
+}
+
+    static int
+do_unlet_var(lp, name_end, forceit)
+    lval_T	*lp;
+    char_u	*name_end;
+    int		forceit;
+{
+    int		ret = OK;
+    int		cc;
+
+    if (lp->ll_tv == NULL)
+    {
+	cc = *name_end;
+	*name_end = NUL;
+
+	/* Normal name or expanded name. */
+	if (check_changedtick(lp->ll_name))
+	    ret = FAIL;
+	else if (do_unlet(lp->ll_name, forceit) == FAIL)
+	    ret = FAIL;
+	*name_end = cc;
+    }
+    else if (tv_check_lock(lp->ll_tv->v_lock, lp->ll_name))
+	return FAIL;
+    else if (lp->ll_range)
+    {
+	listitem_T    *li;
+
+	/* Delete a range of List items. */
+	while (lp->ll_li != NULL && (lp->ll_empty2 || lp->ll_n2 >= lp->ll_n1))
+	{
+	    li = lp->ll_li->li_next;
+	    listitem_remove(lp->ll_list, lp->ll_li);
+	    lp->ll_li = li;
+	    ++lp->ll_n1;
+	}
+    }
+    else
+    {
+	if (lp->ll_list != NULL)
+	    /* unlet a List item. */
+	    listitem_remove(lp->ll_list, lp->ll_li);
+	else
+	    /* unlet a Dictionary item. */
+	    dictitem_remove(lp->ll_dict, lp->ll_di);
+    }
+
+    return ret;
+}
+
+/*
+ * "unlet" a variable.  Return OK if it existed, FAIL if not.
+ * When "forceit" is TRUE don't complain if the variable doesn't exist.
+ */
+    int
+do_unlet(name, forceit)
+    char_u	*name;
+    int		forceit;
+{
+    hashtab_T	*ht;
+    hashitem_T	*hi;
+    char_u	*varname;
+
+    ht = find_var_ht(name, &varname);
+    if (ht != NULL && *varname != NUL)
+    {
+	hi = hash_find(ht, varname);
+	if (!HASHITEM_EMPTY(hi))
+	{
+	    if (var_check_fixed(HI2DI(hi)->di_flags, name))
+		return FAIL;
+	    if (var_check_ro(HI2DI(hi)->di_flags, name))
+		return FAIL;
+	    delete_var(ht, hi);
+	    return OK;
+	}
+    }
+    if (forceit)
+	return OK;
+    EMSG2(_("E108: No such variable: \"%s\""), name);
+    return FAIL;
+}
+
+/*
+ * Lock or unlock variable indicated by "lp".
+ * "deep" is the levels to go (-1 for unlimited);
+ * "lock" is TRUE for ":lockvar", FALSE for ":unlockvar".
+ */
+    static int
+do_lock_var(lp, name_end, deep, lock)
+    lval_T	*lp;
+    char_u	*name_end;
+    int		deep;
+    int		lock;
+{
+    int		ret = OK;
+    int		cc;
+    dictitem_T	*di;
+
+    if (deep == 0)	/* nothing to do */
+	return OK;
+
+    if (lp->ll_tv == NULL)
+    {
+	cc = *name_end;
+	*name_end = NUL;
+
+	/* Normal name or expanded name. */
+	if (check_changedtick(lp->ll_name))
+	    ret = FAIL;
+	else
+	{
+	    di = find_var(lp->ll_name, NULL);
+	    if (di == NULL)
+		ret = FAIL;
+	    else
+	    {
+		if (lock)
+		    di->di_flags |= DI_FLAGS_LOCK;
+		else
+		    di->di_flags &= ~DI_FLAGS_LOCK;
+		item_lock(&di->di_tv, deep, lock);
+	    }
+	}
+	*name_end = cc;
+    }
+    else if (lp->ll_range)
+    {
+	listitem_T    *li = lp->ll_li;
+
+	/* (un)lock a range of List items. */
+	while (li != NULL && (lp->ll_empty2 || lp->ll_n2 >= lp->ll_n1))
+	{
+	    item_lock(&li->li_tv, deep, lock);
+	    li = li->li_next;
+	    ++lp->ll_n1;
+	}
+    }
+    else if (lp->ll_list != NULL)
+	/* (un)lock a List item. */
+	item_lock(&lp->ll_li->li_tv, deep, lock);
+    else
+	/* un(lock) a Dictionary item. */
+	item_lock(&lp->ll_di->di_tv, deep, lock);
+
+    return ret;
+}
+
+/*
+ * Lock or unlock an item.  "deep" is nr of levels to go.
+ */
+    static void
+item_lock(tv, deep, lock)
+    typval_T	*tv;
+    int		deep;
+    int		lock;
+{
+    static int	recurse = 0;
+    list_T	*l;
+    listitem_T	*li;
+    dict_T	*d;
+    hashitem_T	*hi;
+    int		todo;
+
+    if (recurse >= DICT_MAXNEST)
+    {
+	EMSG(_("E743: variable nested too deep for (un)lock"));
+	return;
+    }
+    if (deep == 0)
+	return;
+    ++recurse;
+
+    /* lock/unlock the item itself */
+    if (lock)
+	tv->v_lock |= VAR_LOCKED;
+    else
+	tv->v_lock &= ~VAR_LOCKED;
+
+    switch (tv->v_type)
+    {
+	case VAR_LIST:
+	    if ((l = tv->vval.v_list) != NULL)
+	    {
+		if (lock)
+		    l->lv_lock |= VAR_LOCKED;
+		else
+		    l->lv_lock &= ~VAR_LOCKED;
+		if (deep < 0 || deep > 1)
+		    /* recursive: lock/unlock the items the List contains */
+		    for (li = l->lv_first; li != NULL; li = li->li_next)
+			item_lock(&li->li_tv, deep - 1, lock);
+	    }
+	    break;
+	case VAR_DICT:
+	    if ((d = tv->vval.v_dict) != NULL)
+	    {
+		if (lock)
+		    d->dv_lock |= VAR_LOCKED;
+		else
+		    d->dv_lock &= ~VAR_LOCKED;
+		if (deep < 0 || deep > 1)
+		{
+		    /* recursive: lock/unlock the items the List contains */
+		    todo = (int)d->dv_hashtab.ht_used;
+		    for (hi = d->dv_hashtab.ht_array; todo > 0; ++hi)
+		    {
+			if (!HASHITEM_EMPTY(hi))
+			{
+			    --todo;
+			    item_lock(&HI2DI(hi)->di_tv, deep - 1, lock);
+			}
+		    }
+		}
+	    }
+    }
+    --recurse;
+}
+
+/*
+ * Return TRUE if typeval "tv" is locked: Either tha value is locked itself or
+ * it refers to a List or Dictionary that is locked.
+ */
+    static int
+tv_islocked(tv)
+    typval_T	*tv;
+{
+    return (tv->v_lock & VAR_LOCKED)
+	|| (tv->v_type == VAR_LIST
+		&& tv->vval.v_list != NULL
+		&& (tv->vval.v_list->lv_lock & VAR_LOCKED))
+	|| (tv->v_type == VAR_DICT
+		&& tv->vval.v_dict != NULL
+		&& (tv->vval.v_dict->dv_lock & VAR_LOCKED));
+}
+
+#if (defined(FEAT_MENU) && defined(FEAT_MULTI_LANG)) || defined(PROTO)
+/*
+ * Delete all "menutrans_" variables.
+ */
+    void
+del_menutrans_vars()
+{
+    hashitem_T	*hi;
+    int		todo;
+
+    hash_lock(&globvarht);
+    todo = (int)globvarht.ht_used;
+    for (hi = globvarht.ht_array; todo > 0 && !got_int; ++hi)
+    {
+	if (!HASHITEM_EMPTY(hi))
+	{
+	    --todo;
+	    if (STRNCMP(HI2DI(hi)->di_key, "menutrans_", 10) == 0)
+		delete_var(&globvarht, hi);
+	}
+    }
+    hash_unlock(&globvarht);
+}
+#endif
+
+#if defined(FEAT_CMDL_COMPL) || defined(PROTO)
+
+/*
+ * Local string buffer for the next two functions to store a variable name
+ * with its prefix. Allocated in cat_prefix_varname(), freed later in
+ * get_user_var_name().
+ */
+
+static char_u *cat_prefix_varname __ARGS((int prefix, char_u *name));
+
+static char_u	*varnamebuf = NULL;
+static int	varnamebuflen = 0;
+
+/*
+ * Function to concatenate a prefix and a variable name.
+ */
+    static char_u *
+cat_prefix_varname(prefix, name)
+    int		prefix;
+    char_u	*name;
+{
+    int		len;
+
+    len = (int)STRLEN(name) + 3;
+    if (len > varnamebuflen)
+    {
+	vim_free(varnamebuf);
+	len += 10;			/* some additional space */
+	varnamebuf = alloc(len);
+	if (varnamebuf == NULL)
+	{
+	    varnamebuflen = 0;
+	    return NULL;
+	}
+	varnamebuflen = len;
+    }
+    *varnamebuf = prefix;
+    varnamebuf[1] = ':';
+    STRCPY(varnamebuf + 2, name);
+    return varnamebuf;
+}
+
+/*
+ * Function given to ExpandGeneric() to obtain the list of user defined
+ * (global/buffer/window/built-in) variable names.
+ */
+/*ARGSUSED*/
+    char_u *
+get_user_var_name(xp, idx)
+    expand_T	*xp;
+    int		idx;
+{
+    static long_u	gdone;
+    static long_u	bdone;
+    static long_u	wdone;
+#ifdef FEAT_WINDOWS
+    static long_u	tdone;
+#endif
+    static int		vidx;
+    static hashitem_T	*hi;
+    hashtab_T		*ht;
+
+    if (idx == 0)
+    {
+	gdone = bdone = wdone = vidx = 0;
+#ifdef FEAT_WINDOWS
+	tdone = 0;
+#endif
+    }
+
+    /* Global variables */
+    if (gdone < globvarht.ht_used)
+    {
+	if (gdone++ == 0)
+	    hi = globvarht.ht_array;
+	else
+	    ++hi;
+	while (HASHITEM_EMPTY(hi))
+	    ++hi;
+	if (STRNCMP("g:", xp->xp_pattern, 2) == 0)
+	    return cat_prefix_varname('g', hi->hi_key);
+	return hi->hi_key;
+    }
+
+    /* b: variables */
+    ht = &curbuf->b_vars.dv_hashtab;
+    if (bdone < ht->ht_used)
+    {
+	if (bdone++ == 0)
+	    hi = ht->ht_array;
+	else
+	    ++hi;
+	while (HASHITEM_EMPTY(hi))
+	    ++hi;
+	return cat_prefix_varname('b', hi->hi_key);
+    }
+    if (bdone == ht->ht_used)
+    {
+	++bdone;
+	return (char_u *)"b:changedtick";
+    }
+
+    /* w: variables */
+    ht = &curwin->w_vars.dv_hashtab;
+    if (wdone < ht->ht_used)
+    {
+	if (wdone++ == 0)
+	    hi = ht->ht_array;
+	else
+	    ++hi;
+	while (HASHITEM_EMPTY(hi))
+	    ++hi;
+	return cat_prefix_varname('w', hi->hi_key);
+    }
+
+#ifdef FEAT_WINDOWS
+    /* t: variables */
+    ht = &curtab->tp_vars.dv_hashtab;
+    if (tdone < ht->ht_used)
+    {
+	if (tdone++ == 0)
+	    hi = ht->ht_array;
+	else
+	    ++hi;
+	while (HASHITEM_EMPTY(hi))
+	    ++hi;
+	return cat_prefix_varname('t', hi->hi_key);
+    }
+#endif
+
+    /* v: variables */
+    if (vidx < VV_LEN)
+	return cat_prefix_varname('v', (char_u *)vimvars[vidx++].vv_name);
+
+    vim_free(varnamebuf);
+    varnamebuf = NULL;
+    varnamebuflen = 0;
+    return NULL;
+}
+
+#endif /* FEAT_CMDL_COMPL */
+
+/*
+ * types for expressions.
+ */
+typedef enum
+{
+    TYPE_UNKNOWN = 0
+    , TYPE_EQUAL	/* == */
+    , TYPE_NEQUAL	/* != */
+    , TYPE_GREATER	/* >  */
+    , TYPE_GEQUAL	/* >= */
+    , TYPE_SMALLER	/* <  */
+    , TYPE_SEQUAL	/* <= */
+    , TYPE_MATCH	/* =~ */
+    , TYPE_NOMATCH	/* !~ */
+} exptype_T;
+
+/*
+ * The "evaluate" argument: When FALSE, the argument is only parsed but not
+ * executed.  The function may return OK, but the rettv will be of type
+ * VAR_UNKNOWN.  The function still returns FAIL for a syntax error.
+ */
+
+/*
+ * Handle zero level expression.
+ * This calls eval1() and handles error message and nextcmd.
+ * Put the result in "rettv" when returning OK and "evaluate" is TRUE.
+ * Note: "rettv.v_lock" is not set.
+ * Return OK or FAIL.
+ */
+    static int
+eval0(arg, rettv, nextcmd, evaluate)
+    char_u	*arg;
+    typval_T	*rettv;
+    char_u	**nextcmd;
+    int		evaluate;
+{
+    int		ret;
+    char_u	*p;
+
+    p = skipwhite(arg);
+    ret = eval1(&p, rettv, evaluate);
+    if (ret == FAIL || !ends_excmd(*p))
+    {
+	if (ret != FAIL)
+	    clear_tv(rettv);
+	/*
+	 * Report the invalid expression unless the expression evaluation has
+	 * been cancelled due to an aborting error, an interrupt, or an
+	 * exception.
+	 */
+	if (!aborting())
+	    EMSG2(_(e_invexpr2), arg);
+	ret = FAIL;
+    }
+    if (nextcmd != NULL)
+	*nextcmd = check_nextcmd(p);
+
+    return ret;
+}
+
+/*
+ * Handle top level expression:
+ *	expr1 ? expr0 : expr0
+ *
+ * "arg" must point to the first non-white of the expression.
+ * "arg" is advanced to the next non-white after the recognized expression.
+ *
+ * Note: "rettv.v_lock" is not set.
+ *
+ * Return OK or FAIL.
+ */
+    static int
+eval1(arg, rettv, evaluate)
+    char_u	**arg;
+    typval_T	*rettv;
+    int		evaluate;
+{
+    int		result;
+    typval_T	var2;
+
+    /*
+     * Get the first variable.
+     */
+    if (eval2(arg, rettv, evaluate) == FAIL)
+	return FAIL;
+
+    if ((*arg)[0] == '?')
+    {
+	result = FALSE;
+	if (evaluate)
+	{
+	    int		error = FALSE;
+
+	    if (get_tv_number_chk(rettv, &error) != 0)
+		result = TRUE;
+	    clear_tv(rettv);
+	    if (error)
+		return FAIL;
+	}
+
+	/*
+	 * Get the second variable.
+	 */
+	*arg = skipwhite(*arg + 1);
+	if (eval1(arg, rettv, evaluate && result) == FAIL) /* recursive! */
+	    return FAIL;
+
+	/*
+	 * Check for the ":".
+	 */
+	if ((*arg)[0] != ':')
+	{
+	    EMSG(_("E109: Missing ':' after '?'"));
+	    if (evaluate && result)
+		clear_tv(rettv);
+	    return FAIL;
+	}
+
+	/*
+	 * Get the third variable.
+	 */
+	*arg = skipwhite(*arg + 1);
+	if (eval1(arg, &var2, evaluate && !result) == FAIL) /* recursive! */
+	{
+	    if (evaluate && result)
+		clear_tv(rettv);
+	    return FAIL;
+	}
+	if (evaluate && !result)
+	    *rettv = var2;
+    }
+
+    return OK;
+}
+
+/*
+ * Handle first level expression:
+ *	expr2 || expr2 || expr2	    logical OR
+ *
+ * "arg" must point to the first non-white of the expression.
+ * "arg" is advanced to the next non-white after the recognized expression.
+ *
+ * Return OK or FAIL.
+ */
+    static int
+eval2(arg, rettv, evaluate)
+    char_u	**arg;
+    typval_T	*rettv;
+    int		evaluate;
+{
+    typval_T	var2;
+    long	result;
+    int		first;
+    int		error = FALSE;
+
+    /*
+     * Get the first variable.
+     */
+    if (eval3(arg, rettv, evaluate) == FAIL)
+	return FAIL;
+
+    /*
+     * Repeat until there is no following "||".
+     */
+    first = TRUE;
+    result = FALSE;
+    while ((*arg)[0] == '|' && (*arg)[1] == '|')
+    {
+	if (evaluate && first)
+	{
+	    if (get_tv_number_chk(rettv, &error) != 0)
+		result = TRUE;
+	    clear_tv(rettv);
+	    if (error)
+		return FAIL;
+	    first = FALSE;
+	}
+
+	/*
+	 * Get the second variable.
+	 */
+	*arg = skipwhite(*arg + 2);
+	if (eval3(arg, &var2, evaluate && !result) == FAIL)
+	    return FAIL;
+
+	/*
+	 * Compute the result.
+	 */
+	if (evaluate && !result)
+	{
+	    if (get_tv_number_chk(&var2, &error) != 0)
+		result = TRUE;
+	    clear_tv(&var2);
+	    if (error)
+		return FAIL;
+	}
+	if (evaluate)
+	{
+	    rettv->v_type = VAR_NUMBER;
+	    rettv->vval.v_number = result;
+	}
+    }
+
+    return OK;
+}
+
+/*
+ * Handle second level expression:
+ *	expr3 && expr3 && expr3	    logical AND
+ *
+ * "arg" must point to the first non-white of the expression.
+ * "arg" is advanced to the next non-white after the recognized expression.
+ *
+ * Return OK or FAIL.
+ */
+    static int
+eval3(arg, rettv, evaluate)
+    char_u	**arg;
+    typval_T	*rettv;
+    int		evaluate;
+{
+    typval_T	var2;
+    long	result;
+    int		first;
+    int		error = FALSE;
+
+    /*
+     * Get the first variable.
+     */
+    if (eval4(arg, rettv, evaluate) == FAIL)
+	return FAIL;
+
+    /*
+     * Repeat until there is no following "&&".
+     */
+    first = TRUE;
+    result = TRUE;
+    while ((*arg)[0] == '&' && (*arg)[1] == '&')
+    {
+	if (evaluate && first)
+	{
+	    if (get_tv_number_chk(rettv, &error) == 0)
+		result = FALSE;
+	    clear_tv(rettv);
+	    if (error)
+		return FAIL;
+	    first = FALSE;
+	}
+
+	/*
+	 * Get the second variable.
+	 */
+	*arg = skipwhite(*arg + 2);
+	if (eval4(arg, &var2, evaluate && result) == FAIL)
+	    return FAIL;
+
+	/*
+	 * Compute the result.
+	 */
+	if (evaluate && result)
+	{
+	    if (get_tv_number_chk(&var2, &error) == 0)
+		result = FALSE;
+	    clear_tv(&var2);
+	    if (error)
+		return FAIL;
+	}
+	if (evaluate)
+	{
+	    rettv->v_type = VAR_NUMBER;
+	    rettv->vval.v_number = result;
+	}
+    }
+
+    return OK;
+}
+
+/*
+ * Handle third level expression:
+ *	var1 == var2
+ *	var1 =~ var2
+ *	var1 != var2
+ *	var1 !~ var2
+ *	var1 > var2
+ *	var1 >= var2
+ *	var1 < var2
+ *	var1 <= var2
+ *	var1 is var2
+ *	var1 isnot var2
+ *
+ * "arg" must point to the first non-white of the expression.
+ * "arg" is advanced to the next non-white after the recognized expression.
+ *
+ * Return OK or FAIL.
+ */
+    static int
+eval4(arg, rettv, evaluate)
+    char_u	**arg;
+    typval_T	*rettv;
+    int		evaluate;
+{
+    typval_T	var2;
+    char_u	*p;
+    int		i;
+    exptype_T	type = TYPE_UNKNOWN;
+    int		type_is = FALSE;    /* TRUE for "is" and "isnot" */
+    int		len = 2;
+    long	n1, n2;
+    char_u	*s1, *s2;
+    char_u	buf1[NUMBUFLEN], buf2[NUMBUFLEN];
+    regmatch_T	regmatch;
+    int		ic;
+    char_u	*save_cpo;
+
+    /*
+     * Get the first variable.
+     */
+    if (eval5(arg, rettv, evaluate) == FAIL)
+	return FAIL;
+
+    p = *arg;
+    switch (p[0])
+    {
+	case '=':   if (p[1] == '=')
+			type = TYPE_EQUAL;
+		    else if (p[1] == '~')
+			type = TYPE_MATCH;
+		    break;
+	case '!':   if (p[1] == '=')
+			type = TYPE_NEQUAL;
+		    else if (p[1] == '~')
+			type = TYPE_NOMATCH;
+		    break;
+	case '>':   if (p[1] != '=')
+		    {
+			type = TYPE_GREATER;
+			len = 1;
+		    }
+		    else
+			type = TYPE_GEQUAL;
+		    break;
+	case '<':   if (p[1] != '=')
+		    {
+			type = TYPE_SMALLER;
+			len = 1;
+		    }
+		    else
+			type = TYPE_SEQUAL;
+		    break;
+	case 'i':   if (p[1] == 's')
+		    {
+			if (p[2] == 'n' && p[3] == 'o' && p[4] == 't')
+			    len = 5;
+			if (!vim_isIDc(p[len]))
+			{
+			    type = len == 2 ? TYPE_EQUAL : TYPE_NEQUAL;
+			    type_is = TRUE;
+			}
+		    }
+		    break;
+    }
+
+    /*
+     * If there is a comparitive operator, use it.
+     */
+    if (type != TYPE_UNKNOWN)
+    {
+	/* extra question mark appended: ignore case */
+	if (p[len] == '?')
+	{
+	    ic = TRUE;
+	    ++len;
+	}
+	/* extra '#' appended: match case */
+	else if (p[len] == '#')
+	{
+	    ic = FALSE;
+	    ++len;
+	}
+	/* nothing appened: use 'ignorecase' */
+	else
+	    ic = p_ic;
+
+	/*
+	 * Get the second variable.
+	 */
+	*arg = skipwhite(p + len);
+	if (eval5(arg, &var2, evaluate) == FAIL)
+	{
+	    clear_tv(rettv);
+	    return FAIL;
+	}
+
+	if (evaluate)
+	{
+	    if (type_is && rettv->v_type != var2.v_type)
+	    {
+		/* For "is" a different type always means FALSE, for "notis"
+		 * it means TRUE. */
+		n1 = (type == TYPE_NEQUAL);
+	    }
+	    else if (rettv->v_type == VAR_LIST || var2.v_type == VAR_LIST)
+	    {
+		if (type_is)
+		{
+		    n1 = (rettv->v_type == var2.v_type
+				   && rettv->vval.v_list == var2.vval.v_list);
+		    if (type == TYPE_NEQUAL)
+			n1 = !n1;
+		}
+		else if (rettv->v_type != var2.v_type
+			|| (type != TYPE_EQUAL && type != TYPE_NEQUAL))
+		{
+		    if (rettv->v_type != var2.v_type)
+			EMSG(_("E691: Can only compare List with List"));
+		    else
+			EMSG(_("E692: Invalid operation for Lists"));
+		    clear_tv(rettv);
+		    clear_tv(&var2);
+		    return FAIL;
+		}
+		else
+		{
+		    /* Compare two Lists for being equal or unequal. */
+		    n1 = list_equal(rettv->vval.v_list, var2.vval.v_list, ic);
+		    if (type == TYPE_NEQUAL)
+			n1 = !n1;
+		}
+	    }
+
+	    else if (rettv->v_type == VAR_DICT || var2.v_type == VAR_DICT)
+	    {
+		if (type_is)
+		{
+		    n1 = (rettv->v_type == var2.v_type
+				   && rettv->vval.v_dict == var2.vval.v_dict);
+		    if (type == TYPE_NEQUAL)
+			n1 = !n1;
+		}
+		else if (rettv->v_type != var2.v_type
+			|| (type != TYPE_EQUAL && type != TYPE_NEQUAL))
+		{
+		    if (rettv->v_type != var2.v_type)
+			EMSG(_("E735: Can only compare Dictionary with Dictionary"));
+		    else
+			EMSG(_("E736: Invalid operation for Dictionary"));
+		    clear_tv(rettv);
+		    clear_tv(&var2);
+		    return FAIL;
+		}
+		else
+		{
+		    /* Compare two Dictionaries for being equal or unequal. */
+		    n1 = dict_equal(rettv->vval.v_dict, var2.vval.v_dict, ic);
+		    if (type == TYPE_NEQUAL)
+			n1 = !n1;
+		}
+	    }
+
+	    else if (rettv->v_type == VAR_FUNC || var2.v_type == VAR_FUNC)
+	    {
+		if (rettv->v_type != var2.v_type
+			|| (type != TYPE_EQUAL && type != TYPE_NEQUAL))
+		{
+		    if (rettv->v_type != var2.v_type)
+			EMSG(_("E693: Can only compare Funcref with Funcref"));
+		    else
+			EMSG(_("E694: Invalid operation for Funcrefs"));
+		    clear_tv(rettv);
+		    clear_tv(&var2);
+		    return FAIL;
+		}
+		else
+		{
+		    /* Compare two Funcrefs for being equal or unequal. */
+		    if (rettv->vval.v_string == NULL
+						|| var2.vval.v_string == NULL)
+			n1 = FALSE;
+		    else
+			n1 = STRCMP(rettv->vval.v_string,
+						     var2.vval.v_string) == 0;
+		    if (type == TYPE_NEQUAL)
+			n1 = !n1;
+		}
+	    }
+
+	    /*
+	     * If one of the two variables is a number, compare as a number.
+	     * When using "=~" or "!~", always compare as string.
+	     */
+	    else if ((rettv->v_type == VAR_NUMBER || var2.v_type == VAR_NUMBER)
+		    && type != TYPE_MATCH && type != TYPE_NOMATCH)
+	    {
+		n1 = get_tv_number(rettv);
+		n2 = get_tv_number(&var2);
+		switch (type)
+		{
+		    case TYPE_EQUAL:    n1 = (n1 == n2); break;
+		    case TYPE_NEQUAL:   n1 = (n1 != n2); break;
+		    case TYPE_GREATER:  n1 = (n1 > n2); break;
+		    case TYPE_GEQUAL:   n1 = (n1 >= n2); break;
+		    case TYPE_SMALLER:  n1 = (n1 < n2); break;
+		    case TYPE_SEQUAL:   n1 = (n1 <= n2); break;
+		    case TYPE_UNKNOWN:
+		    case TYPE_MATCH:
+		    case TYPE_NOMATCH:  break;  /* avoid gcc warning */
+		}
+	    }
+	    else
+	    {
+		s1 = get_tv_string_buf(rettv, buf1);
+		s2 = get_tv_string_buf(&var2, buf2);
+		if (type != TYPE_MATCH && type != TYPE_NOMATCH)
+		    i = ic ? MB_STRICMP(s1, s2) : STRCMP(s1, s2);
+		else
+		    i = 0;
+		n1 = FALSE;
+		switch (type)
+		{
+		    case TYPE_EQUAL:    n1 = (i == 0); break;
+		    case TYPE_NEQUAL:   n1 = (i != 0); break;
+		    case TYPE_GREATER:  n1 = (i > 0); break;
+		    case TYPE_GEQUAL:   n1 = (i >= 0); break;
+		    case TYPE_SMALLER:  n1 = (i < 0); break;
+		    case TYPE_SEQUAL:   n1 = (i <= 0); break;
+
+		    case TYPE_MATCH:
+		    case TYPE_NOMATCH:
+			    /* avoid 'l' flag in 'cpoptions' */
+			    save_cpo = p_cpo;
+			    p_cpo = (char_u *)"";
+			    regmatch.regprog = vim_regcomp(s2,
+							RE_MAGIC + RE_STRING);
+			    regmatch.rm_ic = ic;
+			    if (regmatch.regprog != NULL)
+			    {
+				n1 = vim_regexec_nl(&regmatch, s1, (colnr_T)0);
+				vim_free(regmatch.regprog);
+				if (type == TYPE_NOMATCH)
+				    n1 = !n1;
+			    }
+			    p_cpo = save_cpo;
+			    break;
+
+		    case TYPE_UNKNOWN:  break;  /* avoid gcc warning */
+		}
+	    }
+	    clear_tv(rettv);
+	    clear_tv(&var2);
+	    rettv->v_type = VAR_NUMBER;
+	    rettv->vval.v_number = n1;
+	}
+    }
+
+    return OK;
+}
+
+/*
+ * Handle fourth level expression:
+ *	+	number addition
+ *	-	number subtraction
+ *	.	string concatenation
+ *
+ * "arg" must point to the first non-white of the expression.
+ * "arg" is advanced to the next non-white after the recognized expression.
+ *
+ * Return OK or FAIL.
+ */
+    static int
+eval5(arg, rettv, evaluate)
+    char_u	**arg;
+    typval_T	*rettv;
+    int		evaluate;
+{
+    typval_T	var2;
+    typval_T	var3;
+    int		op;
+    long	n1, n2;
+    char_u	*s1, *s2;
+    char_u	buf1[NUMBUFLEN], buf2[NUMBUFLEN];
+    char_u	*p;
+
+    /*
+     * Get the first variable.
+     */
+    if (eval6(arg, rettv, evaluate) == FAIL)
+	return FAIL;
+
+    /*
+     * Repeat computing, until no '+', '-' or '.' is following.
+     */
+    for (;;)
+    {
+	op = **arg;
+	if (op != '+' && op != '-' && op != '.')
+	    break;
+
+	if (op != '+' || rettv->v_type != VAR_LIST)
+	{
+	    /* For "list + ...", an illegal use of the first operand as
+	     * a number cannot be determined before evaluating the 2nd
+	     * operand: if this is also a list, all is ok.
+	     * For "something . ...", "something - ..." or "non-list + ...",
+	     * we know that the first operand needs to be a string or number
+	     * without evaluating the 2nd operand.  So check before to avoid
+	     * side effects after an error. */
+	    if (evaluate && get_tv_string_chk(rettv) == NULL)
+	    {
+		clear_tv(rettv);
+		return FAIL;
+	    }
+	}
+
+	/*
+	 * Get the second variable.
+	 */
+	*arg = skipwhite(*arg + 1);
+	if (eval6(arg, &var2, evaluate) == FAIL)
+	{
+	    clear_tv(rettv);
+	    return FAIL;
+	}
+
+	if (evaluate)
+	{
+	    /*
+	     * Compute the result.
+	     */
+	    if (op == '.')
+	    {
+		s1 = get_tv_string_buf(rettv, buf1);	/* already checked */
+		s2 = get_tv_string_buf_chk(&var2, buf2);
+		if (s2 == NULL)		/* type error ? */
+		{
+		    clear_tv(rettv);
+		    clear_tv(&var2);
+		    return FAIL;
+		}
+		p = concat_str(s1, s2);
+		clear_tv(rettv);
+		rettv->v_type = VAR_STRING;
+		rettv->vval.v_string = p;
+	    }
+	    else if (op == '+' && rettv->v_type == VAR_LIST
+						   && var2.v_type == VAR_LIST)
+	    {
+		/* concatenate Lists */
+		if (list_concat(rettv->vval.v_list, var2.vval.v_list,
+							       &var3) == FAIL)
+		{
+		    clear_tv(rettv);
+		    clear_tv(&var2);
+		    return FAIL;
+		}
+		clear_tv(rettv);
+		*rettv = var3;
+	    }
+	    else
+	    {
+		int	    error = FALSE;
+
+		n1 = get_tv_number_chk(rettv, &error);
+		if (error)
+		{
+		    /* This can only happen for "list + non-list".
+		     * For "non-list + ..." or "something - ...", we returned
+		     * before evaluating the 2nd operand. */
+		    clear_tv(rettv);
+		    return FAIL;
+		}
+		n2 = get_tv_number_chk(&var2, &error);
+		if (error)
+		{
+		    clear_tv(rettv);
+		    clear_tv(&var2);
+		    return FAIL;
+		}
+		clear_tv(rettv);
+		if (op == '+')
+		    n1 = n1 + n2;
+		else
+		    n1 = n1 - n2;
+		rettv->v_type = VAR_NUMBER;
+		rettv->vval.v_number = n1;
+	    }
+	    clear_tv(&var2);
+	}
+    }
+    return OK;
+}
+
+/*
+ * Handle fifth level expression:
+ *	*	number multiplication
+ *	/	number division
+ *	%	number modulo
+ *
+ * "arg" must point to the first non-white of the expression.
+ * "arg" is advanced to the next non-white after the recognized expression.
+ *
+ * Return OK or FAIL.
+ */
+    static int
+eval6(arg, rettv, evaluate)
+    char_u	**arg;
+    typval_T	*rettv;
+    int		evaluate;
+{
+    typval_T	var2;
+    int		op;
+    long	n1, n2;
+    int		error = FALSE;
+
+    /*
+     * Get the first variable.
+     */
+    if (eval7(arg, rettv, evaluate) == FAIL)
+	return FAIL;
+
+    /*
+     * Repeat computing, until no '*', '/' or '%' is following.
+     */
+    for (;;)
+    {
+	op = **arg;
+	if (op != '*' && op != '/' && op != '%')
+	    break;
+
+	if (evaluate)
+	{
+	    n1 = get_tv_number_chk(rettv, &error);
+	    clear_tv(rettv);
+	    if (error)
+		return FAIL;
+	}
+	else
+	    n1 = 0;
+
+	/*
+	 * Get the second variable.
+	 */
+	*arg = skipwhite(*arg + 1);
+	if (eval7(arg, &var2, evaluate) == FAIL)
+	    return FAIL;
+
+	if (evaluate)
+	{
+	    n2 = get_tv_number_chk(&var2, &error);
+	    clear_tv(&var2);
+	    if (error)
+		return FAIL;
+
+	    /*
+	     * Compute the result.
+	     */
+	    if (op == '*')
+		n1 = n1 * n2;
+	    else if (op == '/')
+	    {
+		if (n2 == 0)	/* give an error message? */
+		    n1 = 0x7fffffffL;
+		else
+		    n1 = n1 / n2;
+	    }
+	    else
+	    {
+		if (n2 == 0)	/* give an error message? */
+		    n1 = 0;
+		else
+		    n1 = n1 % n2;
+	    }
+	    rettv->v_type = VAR_NUMBER;
+	    rettv->vval.v_number = n1;
+	}
+    }
+
+    return OK;
+}
+
+/*
+ * Handle sixth level expression:
+ *  number		number constant
+ *  "string"		string constant
+ *  'string'		literal string constant
+ *  &option-name	option value
+ *  @r			register contents
+ *  identifier		variable value
+ *  function()		function call
+ *  $VAR		environment variable
+ *  (expression)	nested expression
+ *  [expr, expr]	List
+ *  {key: val, key: val}  Dictionary
+ *
+ *  Also handle:
+ *  ! in front		logical NOT
+ *  - in front		unary minus
+ *  + in front		unary plus (ignored)
+ *  trailing []		subscript in String or List
+ *  trailing .name	entry in Dictionary
+ *
+ * "arg" must point to the first non-white of the expression.
+ * "arg" is advanced to the next non-white after the recognized expression.
+ *
+ * Return OK or FAIL.
+ */
+    static int
+eval7(arg, rettv, evaluate)
+    char_u	**arg;
+    typval_T	*rettv;
+    int		evaluate;
+{
+    long	n;
+    int		len;
+    char_u	*s;
+    int		val;
+    char_u	*start_leader, *end_leader;
+    int		ret = OK;
+    char_u	*alias;
+
+    /*
+     * Initialise variable so that clear_tv() can't mistake this for a
+     * string and free a string that isn't there.
+     */
+    rettv->v_type = VAR_UNKNOWN;
+
+    /*
+     * Skip '!' and '-' characters.  They are handled later.
+     */
+    start_leader = *arg;
+    while (**arg == '!' || **arg == '-' || **arg == '+')
+	*arg = skipwhite(*arg + 1);
+    end_leader = *arg;
+
+    switch (**arg)
+    {
+    /*
+     * Number constant.
+     */
+    case '0':
+    case '1':
+    case '2':
+    case '3':
+    case '4':
+    case '5':
+    case '6':
+    case '7':
+    case '8':
+    case '9':
+		vim_str2nr(*arg, NULL, &len, TRUE, TRUE, &n, NULL);
+		*arg += len;
+		if (evaluate)
+		{
+		    rettv->v_type = VAR_NUMBER;
+		    rettv->vval.v_number = n;
+		}
+		break;
+
+    /*
+     * String constant: "string".
+     */
+    case '"':	ret = get_string_tv(arg, rettv, evaluate);
+		break;
+
+    /*
+     * Literal string constant: 'str''ing'.
+     */
+    case '\'':	ret = get_lit_string_tv(arg, rettv, evaluate);
+		break;
+
+    /*
+     * List: [expr, expr]
+     */
+    case '[':	ret = get_list_tv(arg, rettv, evaluate);
+		break;
+
+    /*
+     * Dictionary: {key: val, key: val}
+     */
+    case '{':	ret = get_dict_tv(arg, rettv, evaluate);
+		break;
+
+    /*
+     * Option value: &name
+     */
+    case '&':	ret = get_option_tv(arg, rettv, evaluate);
+		break;
+
+    /*
+     * Environment variable: $VAR.
+     */
+    case '$':	ret = get_env_tv(arg, rettv, evaluate);
+		break;
+
+    /*
+     * Register contents: @r.
+     */
+    case '@':	++*arg;
+		if (evaluate)
+		{
+		    rettv->v_type = VAR_STRING;
+		    rettv->vval.v_string = get_reg_contents(**arg, TRUE, TRUE);
+		}
+		if (**arg != NUL)
+		    ++*arg;
+		break;
+
+    /*
+     * nested expression: (expression).
+     */
+    case '(':	*arg = skipwhite(*arg + 1);
+		ret = eval1(arg, rettv, evaluate);	/* recursive! */
+		if (**arg == ')')
+		    ++*arg;
+		else if (ret == OK)
+		{
+		    EMSG(_("E110: Missing ')'"));
+		    clear_tv(rettv);
+		    ret = FAIL;
+		}
+		break;
+
+    default:	ret = NOTDONE;
+		break;
+    }
+
+    if (ret == NOTDONE)
+    {
+	/*
+	 * Must be a variable or function name.
+	 * Can also be a curly-braces kind of name: {expr}.
+	 */
+	s = *arg;
+	len = get_name_len(arg, &alias, evaluate, TRUE);
+	if (alias != NULL)
+	    s = alias;
+
+	if (len <= 0)
+	    ret = FAIL;
+	else
+	{
+	    if (**arg == '(')		/* recursive! */
+	    {
+		/* If "s" is the name of a variable of type VAR_FUNC
+		 * use its contents. */
+		s = deref_func_name(s, &len);
+
+		/* Invoke the function. */
+		ret = get_func_tv(s, len, rettv, arg,
+			  curwin->w_cursor.lnum, curwin->w_cursor.lnum,
+			  &len, evaluate, NULL);
+		/* Stop the expression evaluation when immediately
+		 * aborting on error, or when an interrupt occurred or
+		 * an exception was thrown but not caught. */
+		if (aborting())
+		{
+		    if (ret == OK)
+			clear_tv(rettv);
+		    ret = FAIL;
+		}
+	    }
+	    else if (evaluate)
+		ret = get_var_tv(s, len, rettv, TRUE);
+	    else
+		ret = OK;
+	}
+
+	if (alias != NULL)
+	    vim_free(alias);
+    }
+
+    *arg = skipwhite(*arg);
+
+    /* Handle following '[', '(' and '.' for expr[expr], expr.name,
+     * expr(expr). */
+    if (ret == OK)
+	ret = handle_subscript(arg, rettv, evaluate, TRUE);
+
+    /*
+     * Apply logical NOT and unary '-', from right to left, ignore '+'.
+     */
+    if (ret == OK && evaluate && end_leader > start_leader)
+    {
+	int	    error = FALSE;
+
+	val = get_tv_number_chk(rettv, &error);
+	if (error)
+	{
+	    clear_tv(rettv);
+	    ret = FAIL;
+	}
+	else
+	{
+	    while (end_leader > start_leader)
+	    {
+		--end_leader;
+		if (*end_leader == '!')
+		    val = !val;
+		else if (*end_leader == '-')
+		    val = -val;
+	    }
+	    clear_tv(rettv);
+	    rettv->v_type = VAR_NUMBER;
+	    rettv->vval.v_number = val;
+	}
+    }
+
+    return ret;
+}
+
+/*
+ * Evaluate an "[expr]" or "[expr:expr]" index.  Also "dict.key".
+ * "*arg" points to the '[' or '.'.
+ * Returns FAIL or OK. "*arg" is advanced to after the ']'.
+ */
+    static int
+eval_index(arg, rettv, evaluate, verbose)
+    char_u	**arg;
+    typval_T	*rettv;
+    int		evaluate;
+    int		verbose;	/* give error messages */
+{
+    int		empty1 = FALSE, empty2 = FALSE;
+    typval_T	var1, var2;
+    long	n1, n2 = 0;
+    long	len = -1;
+    int		range = FALSE;
+    char_u	*s;
+    char_u	*key = NULL;
+
+    if (rettv->v_type == VAR_FUNC)
+    {
+	if (verbose)
+	    EMSG(_("E695: Cannot index a Funcref"));
+	return FAIL;
+    }
+
+    if (**arg == '.')
+    {
+	/*
+	 * dict.name
+	 */
+	key = *arg + 1;
+	for (len = 0; ASCII_ISALNUM(key[len]) || key[len] == '_'; ++len)
+	    ;
+	if (len == 0)
+	    return FAIL;
+	*arg = skipwhite(key + len);
+    }
+    else
+    {
+	/*
+	 * something[idx]
+	 *
+	 * Get the (first) variable from inside the [].
+	 */
+	*arg = skipwhite(*arg + 1);
+	if (**arg == ':')
+	    empty1 = TRUE;
+	else if (eval1(arg, &var1, evaluate) == FAIL)	/* recursive! */
+	    return FAIL;
+	else if (evaluate && get_tv_string_chk(&var1) == NULL)
+	{
+	    /* not a number or string */
+	    clear_tv(&var1);
+	    return FAIL;
+	}
+
+	/*
+	 * Get the second variable from inside the [:].
+	 */
+	if (**arg == ':')
+	{
+	    range = TRUE;
+	    *arg = skipwhite(*arg + 1);
+	    if (**arg == ']')
+		empty2 = TRUE;
+	    else if (eval1(arg, &var2, evaluate) == FAIL)	/* recursive! */
+	    {
+		if (!empty1)
+		    clear_tv(&var1);
+		return FAIL;
+	    }
+	    else if (evaluate && get_tv_string_chk(&var2) == NULL)
+	    {
+		/* not a number or string */
+		if (!empty1)
+		    clear_tv(&var1);
+		clear_tv(&var2);
+		return FAIL;
+	    }
+	}
+
+	/* Check for the ']'. */
+	if (**arg != ']')
+	{
+	    if (verbose)
+		EMSG(_(e_missbrac));
+	    clear_tv(&var1);
+	    if (range)
+		clear_tv(&var2);
+	    return FAIL;
+	}
+	*arg = skipwhite(*arg + 1);	/* skip the ']' */
+    }
+
+    if (evaluate)
+    {
+	n1 = 0;
+	if (!empty1 && rettv->v_type != VAR_DICT)
+	{
+	    n1 = get_tv_number(&var1);
+	    clear_tv(&var1);
+	}
+	if (range)
+	{
+	    if (empty2)
+		n2 = -1;
+	    else
+	    {
+		n2 = get_tv_number(&var2);
+		clear_tv(&var2);
+	    }
+	}
+
+	switch (rettv->v_type)
+	{
+	    case VAR_NUMBER:
+	    case VAR_STRING:
+		s = get_tv_string(rettv);
+		len = (long)STRLEN(s);
+		if (range)
+		{
+		    /* The resulting variable is a substring.  If the indexes
+		     * are out of range the result is empty. */
+		    if (n1 < 0)
+		    {
+			n1 = len + n1;
+			if (n1 < 0)
+			    n1 = 0;
+		    }
+		    if (n2 < 0)
+			n2 = len + n2;
+		    else if (n2 >= len)
+			n2 = len;
+		    if (n1 >= len || n2 < 0 || n1 > n2)
+			s = NULL;
+		    else
+			s = vim_strnsave(s + n1, (int)(n2 - n1 + 1));
+		}
+		else
+		{
+		    /* The resulting variable is a string of a single
+		     * character.  If the index is too big or negative the
+		     * result is empty. */
+		    if (n1 >= len || n1 < 0)
+			s = NULL;
+		    else
+			s = vim_strnsave(s + n1, 1);
+		}
+		clear_tv(rettv);
+		rettv->v_type = VAR_STRING;
+		rettv->vval.v_string = s;
+		break;
+
+	    case VAR_LIST:
+		len = list_len(rettv->vval.v_list);
+		if (n1 < 0)
+		    n1 = len + n1;
+		if (!empty1 && (n1 < 0 || n1 >= len))
+		{
+		    /* For a range we allow invalid values and return an empty
+		     * list.  A list index out of range is an error. */
+		    if (!range)
+		    {
+			if (verbose)
+			    EMSGN(_(e_listidx), n1);
+			return FAIL;
+		    }
+		    n1 = len;
+		}
+		if (range)
+		{
+		    list_T	*l;
+		    listitem_T	*item;
+
+		    if (n2 < 0)
+			n2 = len + n2;
+		    else if (n2 >= len)
+			n2 = len - 1;
+		    if (!empty2 && (n2 < 0 || n2 + 1 < n1))
+			n2 = -1;
+		    l = list_alloc();
+		    if (l == NULL)
+			return FAIL;
+		    for (item = list_find(rettv->vval.v_list, n1);
+							       n1 <= n2; ++n1)
+		    {
+			if (list_append_tv(l, &item->li_tv) == FAIL)
+			{
+			    list_free(l, TRUE);
+			    return FAIL;
+			}
+			item = item->li_next;
+		    }
+		    clear_tv(rettv);
+		    rettv->v_type = VAR_LIST;
+		    rettv->vval.v_list = l;
+		    ++l->lv_refcount;
+		}
+		else
+		{
+		    copy_tv(&list_find(rettv->vval.v_list, n1)->li_tv, &var1);
+		    clear_tv(rettv);
+		    *rettv = var1;
+		}
+		break;
+
+	    case VAR_DICT:
+		if (range)
+		{
+		    if (verbose)
+			EMSG(_(e_dictrange));
+		    if (len == -1)
+			clear_tv(&var1);
+		    return FAIL;
+		}
+		{
+		    dictitem_T	*item;
+
+		    if (len == -1)
+		    {
+			key = get_tv_string(&var1);
+			if (*key == NUL)
+			{
+			    if (verbose)
+				EMSG(_(e_emptykey));
+			    clear_tv(&var1);
+			    return FAIL;
+			}
+		    }
+
+		    item = dict_find(rettv->vval.v_dict, key, (int)len);
+
+		    if (item == NULL && verbose)
+			EMSG2(_(e_dictkey), key);
+		    if (len == -1)
+			clear_tv(&var1);
+		    if (item == NULL)
+			return FAIL;
+
+		    copy_tv(&item->di_tv, &var1);
+		    clear_tv(rettv);
+		    *rettv = var1;
+		}
+		break;
+	}
+    }
+
+    return OK;
+}
+
+/*
+ * Get an option value.
+ * "arg" points to the '&' or '+' before the option name.
+ * "arg" is advanced to character after the option name.
+ * Return OK or FAIL.
+ */
+    static int
+get_option_tv(arg, rettv, evaluate)
+    char_u	**arg;
+    typval_T	*rettv;	/* when NULL, only check if option exists */
+    int		evaluate;
+{
+    char_u	*option_end;
+    long	numval;
+    char_u	*stringval;
+    int		opt_type;
+    int		c;
+    int		working = (**arg == '+');    /* has("+option") */
+    int		ret = OK;
+    int		opt_flags;
+
+    /*
+     * Isolate the option name and find its value.
+     */
+    option_end = find_option_end(arg, &opt_flags);
+    if (option_end == NULL)
+    {
+	if (rettv != NULL)
+	    EMSG2(_("E112: Option name missing: %s"), *arg);
+	return FAIL;
+    }
+
+    if (!evaluate)
+    {
+	*arg = option_end;
+	return OK;
+    }
+
+    c = *option_end;
+    *option_end = NUL;
+    opt_type = get_option_value(*arg, &numval,
+			       rettv == NULL ? NULL : &stringval, opt_flags);
+
+    if (opt_type == -3)			/* invalid name */
+    {
+	if (rettv != NULL)
+	    EMSG2(_("E113: Unknown option: %s"), *arg);
+	ret = FAIL;
+    }
+    else if (rettv != NULL)
+    {
+	if (opt_type == -2)		/* hidden string option */
+	{
+	    rettv->v_type = VAR_STRING;
+	    rettv->vval.v_string = NULL;
+	}
+	else if (opt_type == -1)	/* hidden number option */
+	{
+	    rettv->v_type = VAR_NUMBER;
+	    rettv->vval.v_number = 0;
+	}
+	else if (opt_type == 1)		/* number option */
+	{
+	    rettv->v_type = VAR_NUMBER;
+	    rettv->vval.v_number = numval;
+	}
+	else				/* string option */
+	{
+	    rettv->v_type = VAR_STRING;
+	    rettv->vval.v_string = stringval;
+	}
+    }
+    else if (working && (opt_type == -2 || opt_type == -1))
+	ret = FAIL;
+
+    *option_end = c;		    /* put back for error messages */
+    *arg = option_end;
+
+    return ret;
+}
+
+/*
+ * Allocate a variable for a string constant.
+ * Return OK or FAIL.
+ */
+    static int
+get_string_tv(arg, rettv, evaluate)
+    char_u	**arg;
+    typval_T	*rettv;
+    int		evaluate;
+{
+    char_u	*p;
+    char_u	*name;
+    int		extra = 0;
+
+    /*
+     * Find the end of the string, skipping backslashed characters.
+     */
+    for (p = *arg + 1; *p != NUL && *p != '"'; mb_ptr_adv(p))
+    {
+	if (*p == '\\' && p[1] != NUL)
+	{
+	    ++p;
+	    /* A "\<x>" form occupies at least 4 characters, and produces up
+	     * to 6 characters: reserve space for 2 extra */
+	    if (*p == '<')
+		extra += 2;
+	}
+    }
+
+    if (*p != '"')
+    {
+	EMSG2(_("E114: Missing quote: %s"), *arg);
+	return FAIL;
+    }
+
+    /* If only parsing, set *arg and return here */
+    if (!evaluate)
+    {
+	*arg = p + 1;
+	return OK;
+    }
+
+    /*
+     * Copy the string into allocated memory, handling backslashed
+     * characters.
+     */
+    name = alloc((unsigned)(p - *arg + extra));
+    if (name == NULL)
+	return FAIL;
+    rettv->v_type = VAR_STRING;
+    rettv->vval.v_string = name;
+
+    for (p = *arg + 1; *p != NUL && *p != '"'; )
+    {
+	if (*p == '\\')
+	{
+	    switch (*++p)
+	    {
+		case 'b': *name++ = BS; ++p; break;
+		case 'e': *name++ = ESC; ++p; break;
+		case 'f': *name++ = FF; ++p; break;
+		case 'n': *name++ = NL; ++p; break;
+		case 'r': *name++ = CAR; ++p; break;
+		case 't': *name++ = TAB; ++p; break;
+
+		case 'X': /* hex: "\x1", "\x12" */
+		case 'x':
+		case 'u': /* Unicode: "\u0023" */
+		case 'U':
+			  if (vim_isxdigit(p[1]))
+			  {
+			      int	n, nr;
+			      int	c = toupper(*p);
+
+			      if (c == 'X')
+				  n = 2;
+			      else
+				  n = 4;
+			      nr = 0;
+			      while (--n >= 0 && vim_isxdigit(p[1]))
+			      {
+				  ++p;
+				  nr = (nr << 4) + hex2nr(*p);
+			      }
+			      ++p;
+#ifdef FEAT_MBYTE
+			      /* For "\u" store the number according to
+			       * 'encoding'. */
+			      if (c != 'X')
+				  name += (*mb_char2bytes)(nr, name);
+			      else
+#endif
+				  *name++ = nr;
+			  }
+			  break;
+
+			  /* octal: "\1", "\12", "\123" */
+		case '0':
+		case '1':
+		case '2':
+		case '3':
+		case '4':
+		case '5':
+		case '6':
+		case '7': *name = *p++ - '0';
+			  if (*p >= '0' && *p <= '7')
+			  {
+			      *name = (*name << 3) + *p++ - '0';
+			      if (*p >= '0' && *p <= '7')
+				  *name = (*name << 3) + *p++ - '0';
+			  }
+			  ++name;
+			  break;
+
+			    /* Special key, e.g.: "\<C-W>" */
+		case '<': extra = trans_special(&p, name, TRUE);
+			  if (extra != 0)
+			  {
+			      name += extra;
+			      break;
+			  }
+			  /* FALLTHROUGH */
+
+		default:  MB_COPY_CHAR(p, name);
+			  break;
+	    }
+	}
+	else
+	    MB_COPY_CHAR(p, name);
+
+    }
+    *name = NUL;
+    *arg = p + 1;
+
+    return OK;
+}
+
+/*
+ * Allocate a variable for a 'str''ing' constant.
+ * Return OK or FAIL.
+ */
+    static int
+get_lit_string_tv(arg, rettv, evaluate)
+    char_u	**arg;
+    typval_T	*rettv;
+    int		evaluate;
+{
+    char_u	*p;
+    char_u	*str;
+    int		reduce = 0;
+
+    /*
+     * Find the end of the string, skipping ''.
+     */
+    for (p = *arg + 1; *p != NUL; mb_ptr_adv(p))
+    {
+	if (*p == '\'')
+	{
+	    if (p[1] != '\'')
+		break;
+	    ++reduce;
+	    ++p;
+	}
+    }
+
+    if (*p != '\'')
+    {
+	EMSG2(_("E115: Missing quote: %s"), *arg);
+	return FAIL;
+    }
+
+    /* If only parsing return after setting "*arg" */
+    if (!evaluate)
+    {
+	*arg = p + 1;
+	return OK;
+    }
+
+    /*
+     * Copy the string into allocated memory, handling '' to ' reduction.
+     */
+    str = alloc((unsigned)((p - *arg) - reduce));
+    if (str == NULL)
+	return FAIL;
+    rettv->v_type = VAR_STRING;
+    rettv->vval.v_string = str;
+
+    for (p = *arg + 1; *p != NUL; )
+    {
+	if (*p == '\'')
+	{
+	    if (p[1] != '\'')
+		break;
+	    ++p;
+	}
+	MB_COPY_CHAR(p, str);
+    }
+    *str = NUL;
+    *arg = p + 1;
+
+    return OK;
+}
+
+/*
+ * Allocate a variable for a List and fill it from "*arg".
+ * Return OK or FAIL.
+ */
+    static int
+get_list_tv(arg, rettv, evaluate)
+    char_u	**arg;
+    typval_T	*rettv;
+    int		evaluate;
+{
+    list_T	*l = NULL;
+    typval_T	tv;
+    listitem_T	*item;
+
+    if (evaluate)
+    {
+	l = list_alloc();
+	if (l == NULL)
+	    return FAIL;
+    }
+
+    *arg = skipwhite(*arg + 1);
+    while (**arg != ']' && **arg != NUL)
+    {
+	if (eval1(arg, &tv, evaluate) == FAIL)	/* recursive! */
+	    goto failret;
+	if (evaluate)
+	{
+	    item = listitem_alloc();
+	    if (item != NULL)
+	    {
+		item->li_tv = tv;
+		item->li_tv.v_lock = 0;
+		list_append(l, item);
+	    }
+	    else
+		clear_tv(&tv);
+	}
+
+	if (**arg == ']')
+	    break;
+	if (**arg != ',')
+	{
+	    EMSG2(_("E696: Missing comma in List: %s"), *arg);
+	    goto failret;
+	}
+	*arg = skipwhite(*arg + 1);
+    }
+
+    if (**arg != ']')
+    {
+	EMSG2(_("E697: Missing end of List ']': %s"), *arg);
+failret:
+	if (evaluate)
+	    list_free(l, TRUE);
+	return FAIL;
+    }
+
+    *arg = skipwhite(*arg + 1);
+    if (evaluate)
+    {
+	rettv->v_type = VAR_LIST;
+	rettv->vval.v_list = l;
+	++l->lv_refcount;
+    }
+
+    return OK;
+}
+
+/*
+ * Allocate an empty header for a list.
+ * Caller should take care of the reference count.
+ */
+    list_T *
+list_alloc()
+{
+    list_T  *l;
+
+    l = (list_T *)alloc_clear(sizeof(list_T));
+    if (l != NULL)
+    {
+	/* Prepend the list to the list of lists for garbage collection. */
+	if (first_list != NULL)
+	    first_list->lv_used_prev = l;
+	l->lv_used_prev = NULL;
+	l->lv_used_next = first_list;
+	first_list = l;
+    }
+    return l;
+}
+
+/*
+ * Allocate an empty list for a return value.
+ * Returns OK or FAIL.
+ */
+    static int
+rettv_list_alloc(rettv)
+    typval_T	*rettv;
+{
+    list_T	*l = list_alloc();
+
+    if (l == NULL)
+	return FAIL;
+
+    rettv->vval.v_list = l;
+    rettv->v_type = VAR_LIST;
+    ++l->lv_refcount;
+    return OK;
+}
+
+/*
+ * Unreference a list: decrement the reference count and free it when it
+ * becomes zero.
+ */
+    void
+list_unref(l)
+    list_T *l;
+{
+    if (l != NULL && --l->lv_refcount <= 0)
+	list_free(l, TRUE);
+}
+
+/*
+ * Free a list, including all items it points to.
+ * Ignores the reference count.
+ */
+    void
+list_free(l, recurse)
+    list_T  *l;
+    int	    recurse;	/* Free Lists and Dictionaries recursively. */
+{
+    listitem_T *item;
+
+    /* Remove the list from the list of lists for garbage collection. */
+    if (l->lv_used_prev == NULL)
+	first_list = l->lv_used_next;
+    else
+	l->lv_used_prev->lv_used_next = l->lv_used_next;
+    if (l->lv_used_next != NULL)
+	l->lv_used_next->lv_used_prev = l->lv_used_prev;
+
+    for (item = l->lv_first; item != NULL; item = l->lv_first)
+    {
+	/* Remove the item before deleting it. */
+	l->lv_first = item->li_next;
+	if (recurse || (item->li_tv.v_type != VAR_LIST
+					   && item->li_tv.v_type != VAR_DICT))
+	    clear_tv(&item->li_tv);
+	vim_free(item);
+    }
+    vim_free(l);
+}
+
+/*
+ * Allocate a list item.
+ */
+    static listitem_T *
+listitem_alloc()
+{
+    return (listitem_T *)alloc(sizeof(listitem_T));
+}
+
+/*
+ * Free a list item.  Also clears the value.  Does not notify watchers.
+ */
+    static void
+listitem_free(item)
+    listitem_T *item;
+{
+    clear_tv(&item->li_tv);
+    vim_free(item);
+}
+
+/*
+ * Remove a list item from a List and free it.  Also clears the value.
+ */
+    static void
+listitem_remove(l, item)
+    list_T  *l;
+    listitem_T *item;
+{
+    list_remove(l, item, item);
+    listitem_free(item);
+}
+
+/*
+ * Get the number of items in a list.
+ */
+    static long
+list_len(l)
+    list_T	*l;
+{
+    if (l == NULL)
+	return 0L;
+    return l->lv_len;
+}
+
+/*
+ * Return TRUE when two lists have exactly the same values.
+ */
+    static int
+list_equal(l1, l2, ic)
+    list_T	*l1;
+    list_T	*l2;
+    int		ic;	/* ignore case for strings */
+{
+    listitem_T	*item1, *item2;
+
+    if (l1 == l2)
+	return TRUE;
+    if (list_len(l1) != list_len(l2))
+	return FALSE;
+
+    for (item1 = l1->lv_first, item2 = l2->lv_first;
+	    item1 != NULL && item2 != NULL;
+			       item1 = item1->li_next, item2 = item2->li_next)
+	if (!tv_equal(&item1->li_tv, &item2->li_tv, ic))
+	    return FALSE;
+    return item1 == NULL && item2 == NULL;
+}
+
+#if defined(FEAT_PYTHON) || defined(PROTO)
+/*
+ * Return the dictitem that an entry in a hashtable points to.
+ */
+    dictitem_T *
+dict_lookup(hi)
+    hashitem_T *hi;
+{
+    return HI2DI(hi);
+}
+#endif
+
+/*
+ * Return TRUE when two dictionaries have exactly the same key/values.
+ */
+    static int
+dict_equal(d1, d2, ic)
+    dict_T	*d1;
+    dict_T	*d2;
+    int		ic;	/* ignore case for strings */
+{
+    hashitem_T	*hi;
+    dictitem_T	*item2;
+    int		todo;
+
+    if (d1 == d2)
+	return TRUE;
+    if (dict_len(d1) != dict_len(d2))
+	return FALSE;
+
+    todo = (int)d1->dv_hashtab.ht_used;
+    for (hi = d1->dv_hashtab.ht_array; todo > 0; ++hi)
+    {
+	if (!HASHITEM_EMPTY(hi))
+	{
+	    item2 = dict_find(d2, hi->hi_key, -1);
+	    if (item2 == NULL)
+		return FALSE;
+	    if (!tv_equal(&HI2DI(hi)->di_tv, &item2->di_tv, ic))
+		return FALSE;
+	    --todo;
+	}
+    }
+    return TRUE;
+}
+
+/*
+ * Return TRUE if "tv1" and "tv2" have the same value.
+ * Compares the items just like "==" would compare them, but strings and
+ * numbers are different.
+ */
+    static int
+tv_equal(tv1, tv2, ic)
+    typval_T *tv1;
+    typval_T *tv2;
+    int	    ic;	    /* ignore case */
+{
+    char_u	buf1[NUMBUFLEN], buf2[NUMBUFLEN];
+    char_u	*s1, *s2;
+    static int  recursive = 0;	    /* cach recursive loops */
+    int		r;
+
+    if (tv1->v_type != tv2->v_type)
+	return FALSE;
+    /* Catch lists and dicts that have an endless loop by limiting
+     * recursiveness to 1000.  We guess they are equal then. */
+    if (recursive >= 1000)
+	return TRUE;
+
+    switch (tv1->v_type)
+    {
+	case VAR_LIST:
+	    ++recursive;
+	    r = list_equal(tv1->vval.v_list, tv2->vval.v_list, ic);
+	    --recursive;
+	    return r;
+
+	case VAR_DICT:
+	    ++recursive;
+	    r = dict_equal(tv1->vval.v_dict, tv2->vval.v_dict, ic);
+	    --recursive;
+	    return r;
+
+	case VAR_FUNC:
+	    return (tv1->vval.v_string != NULL
+		    && tv2->vval.v_string != NULL
+		    && STRCMP(tv1->vval.v_string, tv2->vval.v_string) == 0);
+
+	case VAR_NUMBER:
+	    return tv1->vval.v_number == tv2->vval.v_number;
+
+	case VAR_STRING:
+	    s1 = get_tv_string_buf(tv1, buf1);
+	    s2 = get_tv_string_buf(tv2, buf2);
+	    return ((ic ? MB_STRICMP(s1, s2) : STRCMP(s1, s2)) == 0);
+    }
+
+    EMSG2(_(e_intern2), "tv_equal()");
+    return TRUE;
+}
+
+/*
+ * Locate item with index "n" in list "l" and return it.
+ * A negative index is counted from the end; -1 is the last item.
+ * Returns NULL when "n" is out of range.
+ */
+    static listitem_T *
+list_find(l, n)
+    list_T	*l;
+    long	n;
+{
+    listitem_T	*item;
+    long	idx;
+
+    if (l == NULL)
+	return NULL;
+
+    /* Negative index is relative to the end. */
+    if (n < 0)
+	n = l->lv_len + n;
+
+    /* Check for index out of range. */
+    if (n < 0 || n >= l->lv_len)
+	return NULL;
+
+    /* When there is a cached index may start search from there. */
+    if (l->lv_idx_item != NULL)
+    {
+	if (n < l->lv_idx / 2)
+	{
+	    /* closest to the start of the list */
+	    item = l->lv_first;
+	    idx = 0;
+	}
+	else if (n > (l->lv_idx + l->lv_len) / 2)
+	{
+	    /* closest to the end of the list */
+	    item = l->lv_last;
+	    idx = l->lv_len - 1;
+	}
+	else
+	{
+	    /* closest to the cached index */
+	    item = l->lv_idx_item;
+	    idx = l->lv_idx;
+	}
+    }
+    else
+    {
+	if (n < l->lv_len / 2)
+	{
+	    /* closest to the start of the list */
+	    item = l->lv_first;
+	    idx = 0;
+	}
+	else
+	{
+	    /* closest to the end of the list */
+	    item = l->lv_last;
+	    idx = l->lv_len - 1;
+	}
+    }
+
+    while (n > idx)
+    {
+	/* search forward */
+	item = item->li_next;
+	++idx;
+    }
+    while (n < idx)
+    {
+	/* search backward */
+	item = item->li_prev;
+	--idx;
+    }
+
+    /* cache the used index */
+    l->lv_idx = idx;
+    l->lv_idx_item = item;
+
+    return item;
+}
+
+/*
+ * Get list item "l[idx]" as a number.
+ */
+    static long
+list_find_nr(l, idx, errorp)
+    list_T	*l;
+    long	idx;
+    int		*errorp;	/* set to TRUE when something wrong */
+{
+    listitem_T	*li;
+
+    li = list_find(l, idx);
+    if (li == NULL)
+    {
+	if (errorp != NULL)
+	    *errorp = TRUE;
+	return -1L;
+    }
+    return get_tv_number_chk(&li->li_tv, errorp);
+}
+
+/*
+ * Locate "item" list "l" and return its index.
+ * Returns -1 when "item" is not in the list.
+ */
+    static long
+list_idx_of_item(l, item)
+    list_T	*l;
+    listitem_T	*item;
+{
+    long	idx = 0;
+    listitem_T	*li;
+
+    if (l == NULL)
+	return -1;
+    idx = 0;
+    for (li = l->lv_first; li != NULL && li != item; li = li->li_next)
+	++idx;
+    if (li == NULL)
+	return -1;
+    return idx;
+}
+
+/*
+ * Append item "item" to the end of list "l".
+ */
+    static void
+list_append(l, item)
+    list_T	*l;
+    listitem_T	*item;
+{
+    if (l->lv_last == NULL)
+    {
+	/* empty list */
+	l->lv_first = item;
+	l->lv_last = item;
+	item->li_prev = NULL;
+    }
+    else
+    {
+	l->lv_last->li_next = item;
+	item->li_prev = l->lv_last;
+	l->lv_last = item;
+    }
+    ++l->lv_len;
+    item->li_next = NULL;
+}
+
+/*
+ * Append typval_T "tv" to the end of list "l".
+ * Return FAIL when out of memory.
+ */
+    static int
+list_append_tv(l, tv)
+    list_T	*l;
+    typval_T	*tv;
+{
+    listitem_T	*li = listitem_alloc();
+
+    if (li == NULL)
+	return FAIL;
+    copy_tv(tv, &li->li_tv);
+    list_append(l, li);
+    return OK;
+}
+
+/*
+ * Add a dictionary to a list.  Used by getqflist().
+ * Return FAIL when out of memory.
+ */
+    int
+list_append_dict(list, dict)
+    list_T	*list;
+    dict_T	*dict;
+{
+    listitem_T	*li = listitem_alloc();
+
+    if (li == NULL)
+	return FAIL;
+    li->li_tv.v_type = VAR_DICT;
+    li->li_tv.v_lock = 0;
+    li->li_tv.vval.v_dict = dict;
+    list_append(list, li);
+    ++dict->dv_refcount;
+    return OK;
+}
+
+/*
+ * Make a copy of "str" and append it as an item to list "l".
+ * When "len" >= 0 use "str[len]".
+ * Returns FAIL when out of memory.
+ */
+    static int
+list_append_string(l, str, len)
+    list_T	*l;
+    char_u	*str;
+    int		len;
+{
+    listitem_T *li = listitem_alloc();
+
+    if (li == NULL)
+	return FAIL;
+    list_append(l, li);
+    li->li_tv.v_type = VAR_STRING;
+    li->li_tv.v_lock = 0;
+    if (str == NULL)
+	li->li_tv.vval.v_string = NULL;
+    else if ((li->li_tv.vval.v_string = (len >= 0 ? vim_strnsave(str, len)
+						 : vim_strsave(str))) == NULL)
+	return FAIL;
+    return OK;
+}
+
+/*
+ * Append "n" to list "l".
+ * Returns FAIL when out of memory.
+ */
+    static int
+list_append_number(l, n)
+    list_T	*l;
+    varnumber_T	n;
+{
+    listitem_T	*li;
+
+    li = listitem_alloc();
+    if (li == NULL)
+	return FAIL;
+    li->li_tv.v_type = VAR_NUMBER;
+    li->li_tv.v_lock = 0;
+    li->li_tv.vval.v_number = n;
+    list_append(l, li);
+    return OK;
+}
+
+/*
+ * Insert typval_T "tv" in list "l" before "item".
+ * If "item" is NULL append at the end.
+ * Return FAIL when out of memory.
+ */
+    static int
+list_insert_tv(l, tv, item)
+    list_T	*l;
+    typval_T	*tv;
+    listitem_T	*item;
+{
+    listitem_T	*ni = listitem_alloc();
+
+    if (ni == NULL)
+	return FAIL;
+    copy_tv(tv, &ni->li_tv);
+    if (item == NULL)
+	/* Append new item at end of list. */
+	list_append(l, ni);
+    else
+    {
+	/* Insert new item before existing item. */
+	ni->li_prev = item->li_prev;
+	ni->li_next = item;
+	if (item->li_prev == NULL)
+	{
+	    l->lv_first = ni;
+	    ++l->lv_idx;
+	}
+	else
+	{
+	    item->li_prev->li_next = ni;
+	    l->lv_idx_item = NULL;
+	}
+	item->li_prev = ni;
+	++l->lv_len;
+    }
+    return OK;
+}
+
+/*
+ * Extend "l1" with "l2".
+ * If "bef" is NULL append at the end, otherwise insert before this item.
+ * Returns FAIL when out of memory.
+ */
+    static int
+list_extend(l1, l2, bef)
+    list_T	*l1;
+    list_T	*l2;
+    listitem_T	*bef;
+{
+    listitem_T	*item;
+
+    for (item = l2->lv_first; item != NULL; item = item->li_next)
+	if (list_insert_tv(l1, &item->li_tv, bef) == FAIL)
+	    return FAIL;
+    return OK;
+}
+
+/*
+ * Concatenate lists "l1" and "l2" into a new list, stored in "tv".
+ * Return FAIL when out of memory.
+ */
+    static int
+list_concat(l1, l2, tv)
+    list_T	*l1;
+    list_T	*l2;
+    typval_T	*tv;
+{
+    list_T	*l;
+
+    /* make a copy of the first list. */
+    l = list_copy(l1, FALSE, 0);
+    if (l == NULL)
+	return FAIL;
+    tv->v_type = VAR_LIST;
+    tv->vval.v_list = l;
+
+    /* append all items from the second list */
+    return list_extend(l, l2, NULL);
+}
+
+/*
+ * Make a copy of list "orig".  Shallow if "deep" is FALSE.
+ * The refcount of the new list is set to 1.
+ * See item_copy() for "copyID".
+ * Returns NULL when out of memory.
+ */
+    static list_T *
+list_copy(orig, deep, copyID)
+    list_T	*orig;
+    int		deep;
+    int		copyID;
+{
+    list_T	*copy;
+    listitem_T	*item;
+    listitem_T	*ni;
+
+    if (orig == NULL)
+	return NULL;
+
+    copy = list_alloc();
+    if (copy != NULL)
+    {
+	if (copyID != 0)
+	{
+	    /* Do this before adding the items, because one of the items may
+	     * refer back to this list. */
+	    orig->lv_copyID = copyID;
+	    orig->lv_copylist = copy;
+	}
+	for (item = orig->lv_first; item != NULL && !got_int;
+							 item = item->li_next)
+	{
+	    ni = listitem_alloc();
+	    if (ni == NULL)
+		break;
+	    if (deep)
+	    {
+		if (item_copy(&item->li_tv, &ni->li_tv, deep, copyID) == FAIL)
+		{
+		    vim_free(ni);
+		    break;
+		}
+	    }
+	    else
+		copy_tv(&item->li_tv, &ni->li_tv);
+	    list_append(copy, ni);
+	}
+	++copy->lv_refcount;
+	if (item != NULL)
+	{
+	    list_unref(copy);
+	    copy = NULL;
+	}
+    }
+
+    return copy;
+}
+
+/*
+ * Remove items "item" to "item2" from list "l".
+ * Does not free the listitem or the value!
+ */
+    static void
+list_remove(l, item, item2)
+    list_T	*l;
+    listitem_T	*item;
+    listitem_T	*item2;
+{
+    listitem_T	*ip;
+
+    /* notify watchers */
+    for (ip = item; ip != NULL; ip = ip->li_next)
+    {
+	--l->lv_len;
+	list_fix_watch(l, ip);
+	if (ip == item2)
+	    break;
+    }
+
+    if (item2->li_next == NULL)
+	l->lv_last = item->li_prev;
+    else
+	item2->li_next->li_prev = item->li_prev;
+    if (item->li_prev == NULL)
+	l->lv_first = item2->li_next;
+    else
+	item->li_prev->li_next = item2->li_next;
+    l->lv_idx_item = NULL;
+}
+
+/*
+ * Return an allocated string with the string representation of a list.
+ * May return NULL.
+ */
+    static char_u *
+list2string(tv, copyID)
+    typval_T	*tv;
+    int		copyID;
+{
+    garray_T	ga;
+
+    if (tv->vval.v_list == NULL)
+	return NULL;
+    ga_init2(&ga, (int)sizeof(char), 80);
+    ga_append(&ga, '[');
+    if (list_join(&ga, tv->vval.v_list, (char_u *)", ", FALSE, copyID) == FAIL)
+    {
+	vim_free(ga.ga_data);
+	return NULL;
+    }
+    ga_append(&ga, ']');
+    ga_append(&ga, NUL);
+    return (char_u *)ga.ga_data;
+}
+
+/*
+ * Join list "l" into a string in "*gap", using separator "sep".
+ * When "echo" is TRUE use String as echoed, otherwise as inside a List.
+ * Return FAIL or OK.
+ */
+    static int
+list_join(gap, l, sep, echo, copyID)
+    garray_T	*gap;
+    list_T	*l;
+    char_u	*sep;
+    int		echo;
+    int		copyID;
+{
+    int		first = TRUE;
+    char_u	*tofree;
+    char_u	numbuf[NUMBUFLEN];
+    listitem_T	*item;
+    char_u	*s;
+
+    for (item = l->lv_first; item != NULL && !got_int; item = item->li_next)
+    {
+	if (first)
+	    first = FALSE;
+	else
+	    ga_concat(gap, sep);
+
+	if (echo)
+	    s = echo_string(&item->li_tv, &tofree, numbuf, copyID);
+	else
+	    s = tv2string(&item->li_tv, &tofree, numbuf, copyID);
+	if (s != NULL)
+	    ga_concat(gap, s);
+	vim_free(tofree);
+	if (s == NULL)
+	    return FAIL;
+    }
+    return OK;
+}
+
+/*
+ * Garbage collection for lists and dictionaries.
+ *
+ * We use reference counts to be able to free most items right away when they
+ * are no longer used.  But for composite items it's possible that it becomes
+ * unused while the reference count is > 0: When there is a recursive
+ * reference.  Example:
+ *	:let l = [1, 2, 3]
+ *	:let d = {9: l}
+ *	:let l[1] = d
+ *
+ * Since this is quite unusual we handle this with garbage collection: every
+ * once in a while find out which lists and dicts are not referenced from any
+ * variable.
+ *
+ * Here is a good reference text about garbage collection (refers to Python
+ * but it applies to all reference-counting mechanisms):
+ *	http://python.ca/nas/python/gc/
+ */
+
+/*
+ * Do garbage collection for lists and dicts.
+ * Return TRUE if some memory was freed.
+ */
+    int
+garbage_collect()
+{
+    dict_T	*dd;
+    list_T	*ll;
+    int		copyID = ++current_copyID;
+    buf_T	*buf;
+    win_T	*wp;
+    int		i;
+    funccall_T	*fc;
+    int		did_free = FALSE;
+#ifdef FEAT_WINDOWS
+    tabpage_T	*tp;
+#endif
+
+    /* Only do this once. */
+    want_garbage_collect = FALSE;
+    may_garbage_collect = FALSE;
+
+    /*
+     * 1. Go through all accessible variables and mark all lists and dicts
+     *    with copyID.
+     */
+    /* script-local variables */
+    for (i = 1; i <= ga_scripts.ga_len; ++i)
+	set_ref_in_ht(&SCRIPT_VARS(i), copyID);
+
+    /* buffer-local variables */
+    for (buf = firstbuf; buf != NULL; buf = buf->b_next)
+	set_ref_in_ht(&buf->b_vars.dv_hashtab, copyID);
+
+    /* window-local variables */
+    FOR_ALL_TAB_WINDOWS(tp, wp)
+	set_ref_in_ht(&wp->w_vars.dv_hashtab, copyID);
+
+#ifdef FEAT_WINDOWS
+    /* tabpage-local variables */
+    for (tp = first_tabpage; tp != NULL; tp = tp->tp_next)
+	set_ref_in_ht(&tp->tp_vars.dv_hashtab, copyID);
+#endif
+
+    /* global variables */
+    set_ref_in_ht(&globvarht, copyID);
+
+    /* function-local variables */
+    for (fc = current_funccal; fc != NULL; fc = fc->caller)
+    {
+	set_ref_in_ht(&fc->l_vars.dv_hashtab, copyID);
+	set_ref_in_ht(&fc->l_avars.dv_hashtab, copyID);
+    }
+
+    /*
+     * 2. Go through the list of dicts and free items without the copyID.
+     */
+    for (dd = first_dict; dd != NULL; )
+	if (dd->dv_copyID != copyID)
+	{
+	    /* Free the Dictionary and ordinary items it contains, but don't
+	     * recurse into Lists and Dictionaries, they will be in the list
+	     * of dicts or list of lists. */
+	    dict_free(dd, FALSE);
+	    did_free = TRUE;
+
+	    /* restart, next dict may also have been freed */
+	    dd = first_dict;
+	}
+	else
+	    dd = dd->dv_used_next;
+
+    /*
+     * 3. Go through the list of lists and free items without the copyID.
+     *    But don't free a list that has a watcher (used in a for loop), these
+     *    are not referenced anywhere.
+     */
+    for (ll = first_list; ll != NULL; )
+	if (ll->lv_copyID != copyID && ll->lv_watch == NULL)
+	{
+	    /* Free the List and ordinary items it contains, but don't recurse
+	     * into Lists and Dictionaries, they will be in the list of dicts
+	     * or list of lists. */
+	    list_free(ll, FALSE);
+	    did_free = TRUE;
+
+	    /* restart, next list may also have been freed */
+	    ll = first_list;
+	}
+	else
+	    ll = ll->lv_used_next;
+
+    return did_free;
+}
+
+/*
+ * Mark all lists and dicts referenced through hashtab "ht" with "copyID".
+ */
+    static void
+set_ref_in_ht(ht, copyID)
+    hashtab_T	*ht;
+    int		copyID;
+{
+    int		todo;
+    hashitem_T	*hi;
+
+    todo = (int)ht->ht_used;
+    for (hi = ht->ht_array; todo > 0; ++hi)
+	if (!HASHITEM_EMPTY(hi))
+	{
+	    --todo;
+	    set_ref_in_item(&HI2DI(hi)->di_tv, copyID);
+	}
+}
+
+/*
+ * Mark all lists and dicts referenced through list "l" with "copyID".
+ */
+    static void
+set_ref_in_list(l, copyID)
+    list_T	*l;
+    int		copyID;
+{
+    listitem_T *li;
+
+    for (li = l->lv_first; li != NULL; li = li->li_next)
+	set_ref_in_item(&li->li_tv, copyID);
+}
+
+/*
+ * Mark all lists and dicts referenced through typval "tv" with "copyID".
+ */
+    static void
+set_ref_in_item(tv, copyID)
+    typval_T	*tv;
+    int		copyID;
+{
+    dict_T	*dd;
+    list_T	*ll;
+
+    switch (tv->v_type)
+    {
+	case VAR_DICT:
+	    dd = tv->vval.v_dict;
+	    if (dd->dv_copyID != copyID)
+	    {
+		/* Didn't see this dict yet. */
+		dd->dv_copyID = copyID;
+		set_ref_in_ht(&dd->dv_hashtab, copyID);
+	    }
+	    break;
+
+	case VAR_LIST:
+	    ll = tv->vval.v_list;
+	    if (ll->lv_copyID != copyID)
+	    {
+		/* Didn't see this list yet. */
+		ll->lv_copyID = copyID;
+		set_ref_in_list(ll, copyID);
+	    }
+	    break;
+    }
+    return;
+}
+
+/*
+ * Allocate an empty header for a dictionary.
+ */
+    dict_T *
+dict_alloc()
+{
+    dict_T *d;
+
+    d = (dict_T *)alloc(sizeof(dict_T));
+    if (d != NULL)
+    {
+	/* Add the list to the list of dicts for garbage collection. */
+	if (first_dict != NULL)
+	    first_dict->dv_used_prev = d;
+	d->dv_used_next = first_dict;
+	d->dv_used_prev = NULL;
+	first_dict = d;
+
+	hash_init(&d->dv_hashtab);
+	d->dv_lock = 0;
+	d->dv_refcount = 0;
+	d->dv_copyID = 0;
+    }
+    return d;
+}
+
+/*
+ * Unreference a Dictionary: decrement the reference count and free it when it
+ * becomes zero.
+ */
+    static void
+dict_unref(d)
+    dict_T *d;
+{
+    if (d != NULL && --d->dv_refcount <= 0)
+	dict_free(d, TRUE);
+}
+
+/*
+ * Free a Dictionary, including all items it contains.
+ * Ignores the reference count.
+ */
+    static void
+dict_free(d, recurse)
+    dict_T  *d;
+    int	    recurse;	/* Free Lists and Dictionaries recursively. */
+{
+    int		todo;
+    hashitem_T	*hi;
+    dictitem_T	*di;
+
+    /* Remove the dict from the list of dicts for garbage collection. */
+    if (d->dv_used_prev == NULL)
+	first_dict = d->dv_used_next;
+    else
+	d->dv_used_prev->dv_used_next = d->dv_used_next;
+    if (d->dv_used_next != NULL)
+	d->dv_used_next->dv_used_prev = d->dv_used_prev;
+
+    /* Lock the hashtab, we don't want it to resize while freeing items. */
+    hash_lock(&d->dv_hashtab);
+    todo = (int)d->dv_hashtab.ht_used;
+    for (hi = d->dv_hashtab.ht_array; todo > 0; ++hi)
+    {
+	if (!HASHITEM_EMPTY(hi))
+	{
+	    /* Remove the item before deleting it, just in case there is
+	     * something recursive causing trouble. */
+	    di = HI2DI(hi);
+	    hash_remove(&d->dv_hashtab, hi);
+	    if (recurse || (di->di_tv.v_type != VAR_LIST
+					     && di->di_tv.v_type != VAR_DICT))
+		clear_tv(&di->di_tv);
+	    vim_free(di);
+	    --todo;
+	}
+    }
+    hash_clear(&d->dv_hashtab);
+    vim_free(d);
+}
+
+/*
+ * Allocate a Dictionary item.
+ * The "key" is copied to the new item.
+ * Note that the value of the item "di_tv" still needs to be initialized!
+ * Returns NULL when out of memory.
+ */
+    static dictitem_T *
+dictitem_alloc(key)
+    char_u	*key;
+{
+    dictitem_T *di;
+
+    di = (dictitem_T *)alloc((unsigned)(sizeof(dictitem_T) + STRLEN(key)));
+    if (di != NULL)
+    {
+	STRCPY(di->di_key, key);
+	di->di_flags = 0;
+    }
+    return di;
+}
+
+/*
+ * Make a copy of a Dictionary item.
+ */
+    static dictitem_T *
+dictitem_copy(org)
+    dictitem_T *org;
+{
+    dictitem_T *di;
+
+    di = (dictitem_T *)alloc((unsigned)(sizeof(dictitem_T)
+						      + STRLEN(org->di_key)));
+    if (di != NULL)
+    {
+	STRCPY(di->di_key, org->di_key);
+	di->di_flags = 0;
+	copy_tv(&org->di_tv, &di->di_tv);
+    }
+    return di;
+}
+
+/*
+ * Remove item "item" from Dictionary "dict" and free it.
+ */
+    static void
+dictitem_remove(dict, item)
+    dict_T	*dict;
+    dictitem_T	*item;
+{
+    hashitem_T	*hi;
+
+    hi = hash_find(&dict->dv_hashtab, item->di_key);
+    if (HASHITEM_EMPTY(hi))
+	EMSG2(_(e_intern2), "dictitem_remove()");
+    else
+	hash_remove(&dict->dv_hashtab, hi);
+    dictitem_free(item);
+}
+
+/*
+ * Free a dict item.  Also clears the value.
+ */
+    static void
+dictitem_free(item)
+    dictitem_T *item;
+{
+    clear_tv(&item->di_tv);
+    vim_free(item);
+}
+
+/*
+ * Make a copy of dict "d".  Shallow if "deep" is FALSE.
+ * The refcount of the new dict is set to 1.
+ * See item_copy() for "copyID".
+ * Returns NULL when out of memory.
+ */
+    static dict_T *
+dict_copy(orig, deep, copyID)
+    dict_T	*orig;
+    int		deep;
+    int		copyID;
+{
+    dict_T	*copy;
+    dictitem_T	*di;
+    int		todo;
+    hashitem_T	*hi;
+
+    if (orig == NULL)
+	return NULL;
+
+    copy = dict_alloc();
+    if (copy != NULL)
+    {
+	if (copyID != 0)
+	{
+	    orig->dv_copyID = copyID;
+	    orig->dv_copydict = copy;
+	}
+	todo = (int)orig->dv_hashtab.ht_used;
+	for (hi = orig->dv_hashtab.ht_array; todo > 0 && !got_int; ++hi)
+	{
+	    if (!HASHITEM_EMPTY(hi))
+	    {
+		--todo;
+
+		di = dictitem_alloc(hi->hi_key);
+		if (di == NULL)
+		    break;
+		if (deep)
+		{
+		    if (item_copy(&HI2DI(hi)->di_tv, &di->di_tv, deep,
+							      copyID) == FAIL)
+		    {
+			vim_free(di);
+			break;
+		    }
+		}
+		else
+		    copy_tv(&HI2DI(hi)->di_tv, &di->di_tv);
+		if (dict_add(copy, di) == FAIL)
+		{
+		    dictitem_free(di);
+		    break;
+		}
+	    }
+	}
+
+	++copy->dv_refcount;
+	if (todo > 0)
+	{
+	    dict_unref(copy);
+	    copy = NULL;
+	}
+    }
+
+    return copy;
+}
+
+/*
+ * Add item "item" to Dictionary "d".
+ * Returns FAIL when out of memory and when key already existed.
+ */
+    static int
+dict_add(d, item)
+    dict_T	*d;
+    dictitem_T	*item;
+{
+    return hash_add(&d->dv_hashtab, item->di_key);
+}
+
+/*
+ * Add a number or string entry to dictionary "d".
+ * When "str" is NULL use number "nr", otherwise use "str".
+ * Returns FAIL when out of memory and when key already exists.
+ */
+    int
+dict_add_nr_str(d, key, nr, str)
+    dict_T	*d;
+    char	*key;
+    long	nr;
+    char_u	*str;
+{
+    dictitem_T	*item;
+
+    item = dictitem_alloc((char_u *)key);
+    if (item == NULL)
+	return FAIL;
+    item->di_tv.v_lock = 0;
+    if (str == NULL)
+    {
+	item->di_tv.v_type = VAR_NUMBER;
+	item->di_tv.vval.v_number = nr;
+    }
+    else
+    {
+	item->di_tv.v_type = VAR_STRING;
+	item->di_tv.vval.v_string = vim_strsave(str);
+    }
+    if (dict_add(d, item) == FAIL)
+    {
+	dictitem_free(item);
+	return FAIL;
+    }
+    return OK;
+}
+
+/*
+ * Get the number of items in a Dictionary.
+ */
+    static long
+dict_len(d)
+    dict_T	*d;
+{
+    if (d == NULL)
+	return 0L;
+    return (long)d->dv_hashtab.ht_used;
+}
+
+/*
+ * Find item "key[len]" in Dictionary "d".
+ * If "len" is negative use strlen(key).
+ * Returns NULL when not found.
+ */
+    static dictitem_T *
+dict_find(d, key, len)
+    dict_T	*d;
+    char_u	*key;
+    int		len;
+{
+#define AKEYLEN 200
+    char_u	buf[AKEYLEN];
+    char_u	*akey;
+    char_u	*tofree = NULL;
+    hashitem_T	*hi;
+
+    if (len < 0)
+	akey = key;
+    else if (len >= AKEYLEN)
+    {
+	tofree = akey = vim_strnsave(key, len);
+	if (akey == NULL)
+	    return NULL;
+    }
+    else
+    {
+	/* Avoid a malloc/free by using buf[]. */
+	vim_strncpy(buf, key, len);
+	akey = buf;
+    }
+
+    hi = hash_find(&d->dv_hashtab, akey);
+    vim_free(tofree);
+    if (HASHITEM_EMPTY(hi))
+	return NULL;
+    return HI2DI(hi);
+}
+
+/*
+ * Get a string item from a dictionary.
+ * When "save" is TRUE allocate memory for it.
+ * Returns NULL if the entry doesn't exist or out of memory.
+ */
+    char_u *
+get_dict_string(d, key, save)
+    dict_T	*d;
+    char_u	*key;
+    int		save;
+{
+    dictitem_T	*di;
+    char_u	*s;
+
+    di = dict_find(d, key, -1);
+    if (di == NULL)
+	return NULL;
+    s = get_tv_string(&di->di_tv);
+    if (save && s != NULL)
+	s = vim_strsave(s);
+    return s;
+}
+
+/*
+ * Get a number item from a dictionary.
+ * Returns 0 if the entry doesn't exist or out of memory.
+ */
+    long
+get_dict_number(d, key)
+    dict_T	*d;
+    char_u	*key;
+{
+    dictitem_T	*di;
+
+    di = dict_find(d, key, -1);
+    if (di == NULL)
+	return 0;
+    return get_tv_number(&di->di_tv);
+}
+
+/*
+ * Return an allocated string with the string representation of a Dictionary.
+ * May return NULL.
+ */
+    static char_u *
+dict2string(tv, copyID)
+    typval_T	*tv;
+    int		copyID;
+{
+    garray_T	ga;
+    int		first = TRUE;
+    char_u	*tofree;
+    char_u	numbuf[NUMBUFLEN];
+    hashitem_T	*hi;
+    char_u	*s;
+    dict_T	*d;
+    int		todo;
+
+    if ((d = tv->vval.v_dict) == NULL)
+	return NULL;
+    ga_init2(&ga, (int)sizeof(char), 80);
+    ga_append(&ga, '{');
+
+    todo = (int)d->dv_hashtab.ht_used;
+    for (hi = d->dv_hashtab.ht_array; todo > 0 && !got_int; ++hi)
+    {
+	if (!HASHITEM_EMPTY(hi))
+	{
+	    --todo;
+
+	    if (first)
+		first = FALSE;
+	    else
+		ga_concat(&ga, (char_u *)", ");
+
+	    tofree = string_quote(hi->hi_key, FALSE);
+	    if (tofree != NULL)
+	    {
+		ga_concat(&ga, tofree);
+		vim_free(tofree);
+	    }
+	    ga_concat(&ga, (char_u *)": ");
+	    s = tv2string(&HI2DI(hi)->di_tv, &tofree, numbuf, copyID);
+	    if (s != NULL)
+		ga_concat(&ga, s);
+	    vim_free(tofree);
+	    if (s == NULL)
+		break;
+	}
+    }
+    if (todo > 0)
+    {
+	vim_free(ga.ga_data);
+	return NULL;
+    }
+
+    ga_append(&ga, '}');
+    ga_append(&ga, NUL);
+    return (char_u *)ga.ga_data;
+}
+
+/*
+ * Allocate a variable for a Dictionary and fill it from "*arg".
+ * Return OK or FAIL.  Returns NOTDONE for {expr}.
+ */
+    static int
+get_dict_tv(arg, rettv, evaluate)
+    char_u	**arg;
+    typval_T	*rettv;
+    int		evaluate;
+{
+    dict_T	*d = NULL;
+    typval_T	tvkey;
+    typval_T	tv;
+    char_u	*key;
+    dictitem_T	*item;
+    char_u	*start = skipwhite(*arg + 1);
+    char_u	buf[NUMBUFLEN];
+
+    /*
+     * First check if it's not a curly-braces thing: {expr}.
+     * Must do this without evaluating, otherwise a function may be called
+     * twice.  Unfortunately this means we need to call eval1() twice for the
+     * first item.
+     * But {} is an empty Dictionary.
+     */
+    if (*start != '}')
+    {
+	if (eval1(&start, &tv, FALSE) == FAIL)	/* recursive! */
+	    return FAIL;
+	if (*start == '}')
+	    return NOTDONE;
+    }
+
+    if (evaluate)
+    {
+	d = dict_alloc();
+	if (d == NULL)
+	    return FAIL;
+    }
+    tvkey.v_type = VAR_UNKNOWN;
+    tv.v_type = VAR_UNKNOWN;
+
+    *arg = skipwhite(*arg + 1);
+    while (**arg != '}' && **arg != NUL)
+    {
+	if (eval1(arg, &tvkey, evaluate) == FAIL)	/* recursive! */
+	    goto failret;
+	if (**arg != ':')
+	{
+	    EMSG2(_("E720: Missing colon in Dictionary: %s"), *arg);
+	    clear_tv(&tvkey);
+	    goto failret;
+	}
+	key = get_tv_string_buf_chk(&tvkey, buf);
+	if (key == NULL || *key == NUL)
+	{
+	    /* "key" is NULL when get_tv_string_buf_chk() gave an errmsg */
+	    if (key != NULL)
+		EMSG(_(e_emptykey));
+	    clear_tv(&tvkey);
+	    goto failret;
+	}
+
+	*arg = skipwhite(*arg + 1);
+	if (eval1(arg, &tv, evaluate) == FAIL)	/* recursive! */
+	{
+	    clear_tv(&tvkey);
+	    goto failret;
+	}
+	if (evaluate)
+	{
+	    item = dict_find(d, key, -1);
+	    if (item != NULL)
+	    {
+		EMSG2(_("E721: Duplicate key in Dictionary: \"%s\""), key);
+		clear_tv(&tvkey);
+		clear_tv(&tv);
+		goto failret;
+	    }
+	    item = dictitem_alloc(key);
+	    clear_tv(&tvkey);
+	    if (item != NULL)
+	    {
+		item->di_tv = tv;
+		item->di_tv.v_lock = 0;
+		if (dict_add(d, item) == FAIL)
+		    dictitem_free(item);
+	    }
+	}
+
+	if (**arg == '}')
+	    break;
+	if (**arg != ',')
+	{
+	    EMSG2(_("E722: Missing comma in Dictionary: %s"), *arg);
+	    goto failret;
+	}
+	*arg = skipwhite(*arg + 1);
+    }
+
+    if (**arg != '}')
+    {
+	EMSG2(_("E723: Missing end of Dictionary '}': %s"), *arg);
+failret:
+	if (evaluate)
+	    dict_free(d, TRUE);
+	return FAIL;
+    }
+
+    *arg = skipwhite(*arg + 1);
+    if (evaluate)
+    {
+	rettv->v_type = VAR_DICT;
+	rettv->vval.v_dict = d;
+	++d->dv_refcount;
+    }
+
+    return OK;
+}
+
+/*
+ * Return a string with the string representation of a variable.
+ * If the memory is allocated "tofree" is set to it, otherwise NULL.
+ * "numbuf" is used for a number.
+ * Does not put quotes around strings, as ":echo" displays values.
+ * When "copyID" is not NULL replace recursive lists and dicts with "...".
+ * May return NULL;
+ */
+    static char_u *
+echo_string(tv, tofree, numbuf, copyID)
+    typval_T	*tv;
+    char_u	**tofree;
+    char_u	*numbuf;
+    int		copyID;
+{
+    static int	recurse = 0;
+    char_u	*r = NULL;
+
+    if (recurse >= DICT_MAXNEST)
+    {
+	EMSG(_("E724: variable nested too deep for displaying"));
+	*tofree = NULL;
+	return NULL;
+    }
+    ++recurse;
+
+    switch (tv->v_type)
+    {
+	case VAR_FUNC:
+	    *tofree = NULL;
+	    r = tv->vval.v_string;
+	    break;
+
+	case VAR_LIST:
+	    if (tv->vval.v_list == NULL)
+	    {
+		*tofree = NULL;
+		r = NULL;
+	    }
+	    else if (copyID != 0 && tv->vval.v_list->lv_copyID == copyID)
+	    {
+		*tofree = NULL;
+		r = (char_u *)"[...]";
+	    }
+	    else
+	    {
+		tv->vval.v_list->lv_copyID = copyID;
+		*tofree = list2string(tv, copyID);
+		r = *tofree;
+	    }
+	    break;
+
+	case VAR_DICT:
+	    if (tv->vval.v_dict == NULL)
+	    {
+		*tofree = NULL;
+		r = NULL;
+	    }
+	    else if (copyID != 0 && tv->vval.v_dict->dv_copyID == copyID)
+	    {
+		*tofree = NULL;
+		r = (char_u *)"{...}";
+	    }
+	    else
+	    {
+		tv->vval.v_dict->dv_copyID = copyID;
+		*tofree = dict2string(tv, copyID);
+		r = *tofree;
+	    }
+	    break;
+
+	case VAR_STRING:
+	case VAR_NUMBER:
+	    *tofree = NULL;
+	    r = get_tv_string_buf(tv, numbuf);
+	    break;
+
+	default:
+	    EMSG2(_(e_intern2), "echo_string()");
+	    *tofree = NULL;
+    }
+
+    --recurse;
+    return r;
+}
+
+/*
+ * Return a string with the string representation of a variable.
+ * If the memory is allocated "tofree" is set to it, otherwise NULL.
+ * "numbuf" is used for a number.
+ * Puts quotes around strings, so that they can be parsed back by eval().
+ * May return NULL;
+ */
+    static char_u *
+tv2string(tv, tofree, numbuf, copyID)
+    typval_T	*tv;
+    char_u	**tofree;
+    char_u	*numbuf;
+    int		copyID;
+{
+    switch (tv->v_type)
+    {
+	case VAR_FUNC:
+	    *tofree = string_quote(tv->vval.v_string, TRUE);
+	    return *tofree;
+	case VAR_STRING:
+	    *tofree = string_quote(tv->vval.v_string, FALSE);
+	    return *tofree;
+	case VAR_NUMBER:
+	case VAR_LIST:
+	case VAR_DICT:
+	    break;
+	default:
+	    EMSG2(_(e_intern2), "tv2string()");
+    }
+    return echo_string(tv, tofree, numbuf, copyID);
+}
+
+/*
+ * Return string "str" in ' quotes, doubling ' characters.
+ * If "str" is NULL an empty string is assumed.
+ * If "function" is TRUE make it function('string').
+ */
+    static char_u *
+string_quote(str, function)
+    char_u	*str;
+    int		function;
+{
+    unsigned	len;
+    char_u	*p, *r, *s;
+
+    len = (function ? 13 : 3);
+    if (str != NULL)
+    {
+	len += (unsigned)STRLEN(str);
+	for (p = str; *p != NUL; mb_ptr_adv(p))
+	    if (*p == '\'')
+		++len;
+    }
+    s = r = alloc(len);
+    if (r != NULL)
+    {
+	if (function)
+	{
+	    STRCPY(r, "function('");
+	    r += 10;
+	}
+	else
+	    *r++ = '\'';
+	if (str != NULL)
+	    for (p = str; *p != NUL; )
+	    {
+		if (*p == '\'')
+		    *r++ = '\'';
+		MB_COPY_CHAR(p, r);
+	    }
+	*r++ = '\'';
+	if (function)
+	    *r++ = ')';
+	*r++ = NUL;
+    }
+    return s;
+}
+
+/*
+ * Get the value of an environment variable.
+ * "arg" is pointing to the '$'.  It is advanced to after the name.
+ * If the environment variable was not set, silently assume it is empty.
+ * Always return OK.
+ */
+    static int
+get_env_tv(arg, rettv, evaluate)
+    char_u	**arg;
+    typval_T	*rettv;
+    int		evaluate;
+{
+    char_u	*string = NULL;
+    int		len;
+    int		cc;
+    char_u	*name;
+    int		mustfree = FALSE;
+
+    ++*arg;
+    name = *arg;
+    len = get_env_len(arg);
+    if (evaluate)
+    {
+	if (len != 0)
+	{
+	    cc = name[len];
+	    name[len] = NUL;
+	    /* first try vim_getenv(), fast for normal environment vars */
+	    string = vim_getenv(name, &mustfree);
+	    if (string != NULL && *string != NUL)
+	    {
+		if (!mustfree)
+		    string = vim_strsave(string);
+	    }
+	    else
+	    {
+		if (mustfree)
+		    vim_free(string);
+
+		/* next try expanding things like $VIM and ${HOME} */
+		string = expand_env_save(name - 1);
+		if (string != NULL && *string == '$')
+		{
+		    vim_free(string);
+		    string = NULL;
+		}
+	    }
+	    name[len] = cc;
+	}
+	rettv->v_type = VAR_STRING;
+	rettv->vval.v_string = string;
+    }
+
+    return OK;
+}
+
+/*
+ * Array with names and number of arguments of all internal functions
+ * MUST BE KEPT SORTED IN strcmp() ORDER FOR BINARY SEARCH!
+ */
+static struct fst
+{
+    char	*f_name;	/* function name */
+    char	f_min_argc;	/* minimal number of arguments */
+    char	f_max_argc;	/* maximal number of arguments */
+    void	(*f_func) __ARGS((typval_T *args, typval_T *rvar));
+				/* implementation of function */
+} functions[] =
+{
+    {"add",		2, 2, f_add},
+    {"append",		2, 2, f_append},
+    {"argc",		0, 0, f_argc},
+    {"argidx",		0, 0, f_argidx},
+    {"argv",		0, 1, f_argv},
+    {"browse",		4, 4, f_browse},
+    {"browsedir",	2, 2, f_browsedir},
+    {"bufexists",	1, 1, f_bufexists},
+    {"buffer_exists",	1, 1, f_bufexists},	/* obsolete */
+    {"buffer_name",	1, 1, f_bufname},	/* obsolete */
+    {"buffer_number",	1, 1, f_bufnr},		/* obsolete */
+    {"buflisted",	1, 1, f_buflisted},
+    {"bufloaded",	1, 1, f_bufloaded},
+    {"bufname",		1, 1, f_bufname},
+    {"bufnr",		1, 2, f_bufnr},
+    {"bufwinnr",	1, 1, f_bufwinnr},
+    {"byte2line",	1, 1, f_byte2line},
+    {"byteidx",		2, 2, f_byteidx},
+    {"call",		2, 3, f_call},
+    {"changenr",	0, 0, f_changenr},
+    {"char2nr",		1, 1, f_char2nr},
+    {"cindent",		1, 1, f_cindent},
+    {"col",		1, 1, f_col},
+#if defined(FEAT_INS_EXPAND)
+    {"complete",	2, 2, f_complete},
+    {"complete_add",	1, 1, f_complete_add},
+    {"complete_check",	0, 0, f_complete_check},
+#endif
+    {"confirm",		1, 4, f_confirm},
+    {"copy",		1, 1, f_copy},
+    {"count",		2, 4, f_count},
+    {"cscope_connection",0,3, f_cscope_connection},
+    {"cursor",		1, 3, f_cursor},
+    {"deepcopy",	1, 2, f_deepcopy},
+    {"delete",		1, 1, f_delete},
+    {"did_filetype",	0, 0, f_did_filetype},
+    {"diff_filler",	1, 1, f_diff_filler},
+    {"diff_hlID",	2, 2, f_diff_hlID},
+    {"empty",		1, 1, f_empty},
+    {"escape",		2, 2, f_escape},
+    {"eval",		1, 1, f_eval},
+    {"eventhandler",	0, 0, f_eventhandler},
+    {"executable",	1, 1, f_executable},
+    {"exists",		1, 1, f_exists},
+    {"expand",		1, 2, f_expand},
+    {"extend",		2, 3, f_extend},
+    {"feedkeys",	1, 2, f_feedkeys},
+    {"file_readable",	1, 1, f_filereadable},	/* obsolete */
+    {"filereadable",	1, 1, f_filereadable},
+    {"filewritable",	1, 1, f_filewritable},
+    {"filter",		2, 2, f_filter},
+    {"finddir",		1, 3, f_finddir},
+    {"findfile",	1, 3, f_findfile},
+    {"fnamemodify",	2, 2, f_fnamemodify},
+    {"foldclosed",	1, 1, f_foldclosed},
+    {"foldclosedend",	1, 1, f_foldclosedend},
+    {"foldlevel",	1, 1, f_foldlevel},
+    {"foldtext",	0, 0, f_foldtext},
+    {"foldtextresult",	1, 1, f_foldtextresult},
+    {"foreground",	0, 0, f_foreground},
+    {"function",	1, 1, f_function},
+    {"garbagecollect",	0, 0, f_garbagecollect},
+    {"get",		2, 3, f_get},
+    {"getbufline",	2, 3, f_getbufline},
+    {"getbufvar",	2, 2, f_getbufvar},
+    {"getchar",		0, 1, f_getchar},
+    {"getcharmod",	0, 0, f_getcharmod},
+    {"getcmdline",	0, 0, f_getcmdline},
+    {"getcmdpos",	0, 0, f_getcmdpos},
+    {"getcmdtype",	0, 0, f_getcmdtype},
+    {"getcwd",		0, 0, f_getcwd},
+    {"getfontname",	0, 1, f_getfontname},
+    {"getfperm",	1, 1, f_getfperm},
+    {"getfsize",	1, 1, f_getfsize},
+    {"getftime",	1, 1, f_getftime},
+    {"getftype",	1, 1, f_getftype},
+    {"getline",		1, 2, f_getline},
+    {"getloclist",	1, 1, f_getqflist},
+    {"getpos",		1, 1, f_getpos},
+    {"getqflist",	0, 0, f_getqflist},
+    {"getreg",		0, 2, f_getreg},
+    {"getregtype",	0, 1, f_getregtype},
+    {"gettabwinvar",	3, 3, f_gettabwinvar},
+    {"getwinposx",	0, 0, f_getwinposx},
+    {"getwinposy",	0, 0, f_getwinposy},
+    {"getwinvar",	2, 2, f_getwinvar},
+    {"glob",		1, 1, f_glob},
+    {"globpath",	2, 2, f_globpath},
+    {"has",		1, 1, f_has},
+    {"has_key",		2, 2, f_has_key},
+    {"haslocaldir",	0, 0, f_haslocaldir},
+    {"hasmapto",	1, 3, f_hasmapto},
+    {"highlightID",	1, 1, f_hlID},		/* obsolete */
+    {"highlight_exists",1, 1, f_hlexists},	/* obsolete */
+    {"histadd",		2, 2, f_histadd},
+    {"histdel",		1, 2, f_histdel},
+    {"histget",		1, 2, f_histget},
+    {"histnr",		1, 1, f_histnr},
+    {"hlID",		1, 1, f_hlID},
+    {"hlexists",	1, 1, f_hlexists},
+    {"hostname",	0, 0, f_hostname},
+    {"iconv",		3, 3, f_iconv},
+    {"indent",		1, 1, f_indent},
+    {"index",		2, 4, f_index},
+    {"input",		1, 3, f_input},
+    {"inputdialog",	1, 3, f_inputdialog},
+    {"inputlist",	1, 1, f_inputlist},
+    {"inputrestore",	0, 0, f_inputrestore},
+    {"inputsave",	0, 0, f_inputsave},
+    {"inputsecret",	1, 2, f_inputsecret},
+    {"insert",		2, 3, f_insert},
+    {"isdirectory",	1, 1, f_isdirectory},
+    {"islocked",	1, 1, f_islocked},
+    {"items",		1, 1, f_items},
+    {"join",		1, 2, f_join},
+    {"keys",		1, 1, f_keys},
+    {"last_buffer_nr",	0, 0, f_last_buffer_nr},/* obsolete */
+    {"len",		1, 1, f_len},
+    {"libcall",		3, 3, f_libcall},
+    {"libcallnr",	3, 3, f_libcallnr},
+    {"line",		1, 1, f_line},
+    {"line2byte",	1, 1, f_line2byte},
+    {"lispindent",	1, 1, f_lispindent},
+    {"localtime",	0, 0, f_localtime},
+    {"map",		2, 2, f_map},
+    {"maparg",		1, 3, f_maparg},
+    {"mapcheck",	1, 3, f_mapcheck},
+    {"match",		2, 4, f_match},
+    {"matcharg",	1, 1, f_matcharg},
+    {"matchend",	2, 4, f_matchend},
+    {"matchlist",	2, 4, f_matchlist},
+    {"matchstr",	2, 4, f_matchstr},
+    {"max",		1, 1, f_max},
+    {"min",		1, 1, f_min},
+#ifdef vim_mkdir
+    {"mkdir",		1, 3, f_mkdir},
+#endif
+    {"mode",		0, 0, f_mode},
+    {"nextnonblank",	1, 1, f_nextnonblank},
+    {"nr2char",		1, 1, f_nr2char},
+    {"pathshorten",	1, 1, f_pathshorten},
+    {"prevnonblank",	1, 1, f_prevnonblank},
+    {"printf",		2, 19, f_printf},
+    {"pumvisible",	0, 0, f_pumvisible},
+    {"range",		1, 3, f_range},
+    {"readfile",	1, 3, f_readfile},
+    {"reltime",		0, 2, f_reltime},
+    {"reltimestr",	1, 1, f_reltimestr},
+    {"remote_expr",	2, 3, f_remote_expr},
+    {"remote_foreground", 1, 1, f_remote_foreground},
+    {"remote_peek",	1, 2, f_remote_peek},
+    {"remote_read",	1, 1, f_remote_read},
+    {"remote_send",	2, 3, f_remote_send},
+    {"remove",		2, 3, f_remove},
+    {"rename",		2, 2, f_rename},
+    {"repeat",		2, 2, f_repeat},
+    {"resolve",		1, 1, f_resolve},
+    {"reverse",		1, 1, f_reverse},
+    {"search",		1, 3, f_search},
+    {"searchdecl",	1, 3, f_searchdecl},
+    {"searchpair",	3, 6, f_searchpair},
+    {"searchpairpos",	3, 6, f_searchpairpos},
+    {"searchpos",	1, 3, f_searchpos},
+    {"server2client",	2, 2, f_server2client},
+    {"serverlist",	0, 0, f_serverlist},
+    {"setbufvar",	3, 3, f_setbufvar},
+    {"setcmdpos",	1, 1, f_setcmdpos},
+    {"setline",		2, 2, f_setline},
+    {"setloclist",	2, 3, f_setloclist},
+    {"setpos",		2, 2, f_setpos},
+    {"setqflist",	1, 2, f_setqflist},
+    {"setreg",		2, 3, f_setreg},
+    {"settabwinvar",	4, 4, f_settabwinvar},
+    {"setwinvar",	3, 3, f_setwinvar},
+    {"shellescape",	1, 1, f_shellescape},
+    {"simplify",	1, 1, f_simplify},
+    {"sort",		1, 2, f_sort},
+    {"soundfold",	1, 1, f_soundfold},
+    {"spellbadword",	0, 1, f_spellbadword},
+    {"spellsuggest",	1, 3, f_spellsuggest},
+    {"split",		1, 3, f_split},
+    {"str2nr",		1, 2, f_str2nr},
+#ifdef HAVE_STRFTIME
+    {"strftime",	1, 2, f_strftime},
+#endif
+    {"stridx",		2, 3, f_stridx},
+    {"string",		1, 1, f_string},
+    {"strlen",		1, 1, f_strlen},
+    {"strpart",		2, 3, f_strpart},
+    {"strridx",		2, 3, f_strridx},
+    {"strtrans",	1, 1, f_strtrans},
+    {"submatch",	1, 1, f_submatch},
+    {"substitute",	4, 4, f_substitute},
+    {"synID",		3, 3, f_synID},
+    {"synIDattr",	2, 3, f_synIDattr},
+    {"synIDtrans",	1, 1, f_synIDtrans},
+    {"system",		1, 2, f_system},
+    {"tabpagebuflist",	0, 1, f_tabpagebuflist},
+    {"tabpagenr",	0, 1, f_tabpagenr},
+    {"tabpagewinnr",	1, 2, f_tabpagewinnr},
+    {"tagfiles",	0, 0, f_tagfiles},
+    {"taglist",		1, 1, f_taglist},
+    {"tempname",	0, 0, f_tempname},
+    {"test",		1, 1, f_test},
+    {"tolower",		1, 1, f_tolower},
+    {"toupper",		1, 1, f_toupper},
+    {"tr",		3, 3, f_tr},
+    {"type",		1, 1, f_type},
+    {"values",		1, 1, f_values},
+    {"virtcol",		1, 1, f_virtcol},
+    {"visualmode",	0, 1, f_visualmode},
+    {"winbufnr",	1, 1, f_winbufnr},
+    {"wincol",		0, 0, f_wincol},
+    {"winheight",	1, 1, f_winheight},
+    {"winline",		0, 0, f_winline},
+    {"winnr",		0, 1, f_winnr},
+    {"winrestcmd",	0, 0, f_winrestcmd},
+    {"winrestview",	1, 1, f_winrestview},
+    {"winsaveview",	0, 0, f_winsaveview},
+    {"winwidth",	1, 1, f_winwidth},
+    {"writefile",	2, 3, f_writefile},
+};
+
+#if defined(FEAT_CMDL_COMPL) || defined(PROTO)
+
+/*
+ * Function given to ExpandGeneric() to obtain the list of internal
+ * or user defined function names.
+ */
+    char_u *
+get_function_name(xp, idx)
+    expand_T	*xp;
+    int		idx;
+{
+    static int	intidx = -1;
+    char_u	*name;
+
+    if (idx == 0)
+	intidx = -1;
+    if (intidx < 0)
+    {
+	name = get_user_func_name(xp, idx);
+	if (name != NULL)
+	    return name;
+    }
+    if (++intidx < (int)(sizeof(functions) / sizeof(struct fst)))
+    {
+	STRCPY(IObuff, functions[intidx].f_name);
+	STRCAT(IObuff, "(");
+	if (functions[intidx].f_max_argc == 0)
+	    STRCAT(IObuff, ")");
+	return IObuff;
+    }
+
+    return NULL;
+}
+
+/*
+ * Function given to ExpandGeneric() to obtain the list of internal or
+ * user defined variable or function names.
+ */
+/*ARGSUSED*/
+    char_u *
+get_expr_name(xp, idx)
+    expand_T	*xp;
+    int		idx;
+{
+    static int	intidx = -1;
+    char_u	*name;
+
+    if (idx == 0)
+	intidx = -1;
+    if (intidx < 0)
+    {
+	name = get_function_name(xp, idx);
+	if (name != NULL)
+	    return name;
+    }
+    return get_user_var_name(xp, ++intidx);
+}
+
+#endif /* FEAT_CMDL_COMPL */
+
+/*
+ * Find internal function in table above.
+ * Return index, or -1 if not found
+ */
+    static int
+find_internal_func(name)
+    char_u	*name;		/* name of the function */
+{
+    int		first = 0;
+    int		last = (int)(sizeof(functions) / sizeof(struct fst)) - 1;
+    int		cmp;
+    int		x;
+
+    /*
+     * Find the function name in the table. Binary search.
+     */
+    while (first <= last)
+    {
+	x = first + ((unsigned)(last - first) >> 1);
+	cmp = STRCMP(name, functions[x].f_name);
+	if (cmp < 0)
+	    last = x - 1;
+	else if (cmp > 0)
+	    first = x + 1;
+	else
+	    return x;
+    }
+    return -1;
+}
+
+/*
+ * Check if "name" is a variable of type VAR_FUNC.  If so, return the function
+ * name it contains, otherwise return "name".
+ */
+    static char_u *
+deref_func_name(name, lenp)
+    char_u	*name;
+    int		*lenp;
+{
+    dictitem_T	*v;
+    int		cc;
+
+    cc = name[*lenp];
+    name[*lenp] = NUL;
+    v = find_var(name, NULL);
+    name[*lenp] = cc;
+    if (v != NULL && v->di_tv.v_type == VAR_FUNC)
+    {
+	if (v->di_tv.vval.v_string == NULL)
+	{
+	    *lenp = 0;
+	    return (char_u *)"";	/* just in case */
+	}
+	*lenp = (int)STRLEN(v->di_tv.vval.v_string);
+	return v->di_tv.vval.v_string;
+    }
+
+    return name;
+}
+
+/*
+ * Allocate a variable for the result of a function.
+ * Return OK or FAIL.
+ */
+    static int
+get_func_tv(name, len, rettv, arg, firstline, lastline, doesrange,
+							   evaluate, selfdict)
+    char_u	*name;		/* name of the function */
+    int		len;		/* length of "name" */
+    typval_T	*rettv;
+    char_u	**arg;		/* argument, pointing to the '(' */
+    linenr_T	firstline;	/* first line of range */
+    linenr_T	lastline;	/* last line of range */
+    int		*doesrange;	/* return: function handled range */
+    int		evaluate;
+    dict_T	*selfdict;	/* Dictionary for "self" */
+{
+    char_u	*argp;
+    int		ret = OK;
+    typval_T	argvars[MAX_FUNC_ARGS + 1];	/* vars for arguments */
+    int		argcount = 0;		/* number of arguments found */
+
+    /*
+     * Get the arguments.
+     */
+    argp = *arg;
+    while (argcount < MAX_FUNC_ARGS)
+    {
+	argp = skipwhite(argp + 1);	    /* skip the '(' or ',' */
+	if (*argp == ')' || *argp == ',' || *argp == NUL)
+	    break;
+	if (eval1(&argp, &argvars[argcount], evaluate) == FAIL)
+	{
+	    ret = FAIL;
+	    break;
+	}
+	++argcount;
+	if (*argp != ',')
+	    break;
+    }
+    if (*argp == ')')
+	++argp;
+    else
+	ret = FAIL;
+
+    if (ret == OK)
+	ret = call_func(name, len, rettv, argcount, argvars,
+			  firstline, lastline, doesrange, evaluate, selfdict);
+    else if (!aborting())
+    {
+	if (argcount == MAX_FUNC_ARGS)
+	    emsg_funcname("E740: Too many arguments for function %s", name);
+	else
+	    emsg_funcname("E116: Invalid arguments for function %s", name);
+    }
+
+    while (--argcount >= 0)
+	clear_tv(&argvars[argcount]);
+
+    *arg = skipwhite(argp);
+    return ret;
+}
+
+
+/*
+ * Call a function with its resolved parameters
+ * Return OK when the function can't be called,  FAIL otherwise.
+ * Also returns OK when an error was encountered while executing the function.
+ */
+    static int
+call_func(name, len, rettv, argcount, argvars, firstline, lastline,
+						doesrange, evaluate, selfdict)
+    char_u	*name;		/* name of the function */
+    int		len;		/* length of "name" */
+    typval_T	*rettv;		/* return value goes here */
+    int		argcount;	/* number of "argvars" */
+    typval_T	*argvars;	/* vars for arguments, must have "argcount"
+				   PLUS ONE elements! */
+    linenr_T	firstline;	/* first line of range */
+    linenr_T	lastline;	/* last line of range */
+    int		*doesrange;	/* return: function handled range */
+    int		evaluate;
+    dict_T	*selfdict;	/* Dictionary for "self" */
+{
+    int		ret = FAIL;
+#define ERROR_UNKNOWN	0
+#define ERROR_TOOMANY	1
+#define ERROR_TOOFEW	2
+#define ERROR_SCRIPT	3
+#define ERROR_DICT	4
+#define ERROR_NONE	5
+#define ERROR_OTHER	6
+    int		error = ERROR_NONE;
+    int		i;
+    int		llen;
+    ufunc_T	*fp;
+    int		cc;
+#define FLEN_FIXED 40
+    char_u	fname_buf[FLEN_FIXED + 1];
+    char_u	*fname;
+
+    /*
+     * In a script change <SID>name() and s:name() to K_SNR 123_name().
+     * Change <SNR>123_name() to K_SNR 123_name().
+     * Use fname_buf[] when it fits, otherwise allocate memory (slow).
+     */
+    cc = name[len];
+    name[len] = NUL;
+    llen = eval_fname_script(name);
+    if (llen > 0)
+    {
+	fname_buf[0] = K_SPECIAL;
+	fname_buf[1] = KS_EXTRA;
+	fname_buf[2] = (int)KE_SNR;
+	i = 3;
+	if (eval_fname_sid(name))	/* "<SID>" or "s:" */
+	{
+	    if (current_SID <= 0)
+		error = ERROR_SCRIPT;
+	    else
+	    {
+		sprintf((char *)fname_buf + 3, "%ld_", (long)current_SID);
+		i = (int)STRLEN(fname_buf);
+	    }
+	}
+	if (i + STRLEN(name + llen) < FLEN_FIXED)
+	{
+	    STRCPY(fname_buf + i, name + llen);
+	    fname = fname_buf;
+	}
+	else
+	{
+	    fname = alloc((unsigned)(i + STRLEN(name + llen) + 1));
+	    if (fname == NULL)
+		error = ERROR_OTHER;
+	    else
+	    {
+		mch_memmove(fname, fname_buf, (size_t)i);
+		STRCPY(fname + i, name + llen);
+	    }
+	}
+    }
+    else
+	fname = name;
+
+    *doesrange = FALSE;
+
+
+    /* execute the function if no errors detected and executing */
+    if (evaluate && error == ERROR_NONE)
+    {
+	rettv->v_type = VAR_NUMBER;	/* default is number rettv */
+	error = ERROR_UNKNOWN;
+
+	if (!builtin_function(fname))
+	{
+	    /*
+	     * User defined function.
+	     */
+	    fp = find_func(fname);
+
+#ifdef FEAT_AUTOCMD
+	    /* Trigger FuncUndefined event, may load the function. */
+	    if (fp == NULL
+		    && apply_autocmds(EVENT_FUNCUNDEFINED,
+						     fname, fname, TRUE, NULL)
+		    && !aborting())
+	    {
+		/* executed an autocommand, search for the function again */
+		fp = find_func(fname);
+	    }
+#endif
+	    /* Try loading a package. */
+	    if (fp == NULL && script_autoload(fname, TRUE) && !aborting())
+	    {
+		/* loaded a package, search for the function again */
+		fp = find_func(fname);
+	    }
+
+	    if (fp != NULL)
+	    {
+		if (fp->uf_flags & FC_RANGE)
+		    *doesrange = TRUE;
+		if (argcount < fp->uf_args.ga_len)
+		    error = ERROR_TOOFEW;
+		else if (!fp->uf_varargs && argcount > fp->uf_args.ga_len)
+		    error = ERROR_TOOMANY;
+		else if ((fp->uf_flags & FC_DICT) && selfdict == NULL)
+		    error = ERROR_DICT;
+		else
+		{
+		    /*
+		     * Call the user function.
+		     * Save and restore search patterns, script variables and
+		     * redo buffer.
+		     */
+		    save_search_patterns();
+		    saveRedobuff();
+		    ++fp->uf_calls;
+		    call_user_func(fp, argcount, argvars, rettv,
+					       firstline, lastline,
+				  (fp->uf_flags & FC_DICT) ? selfdict : NULL);
+		    if (--fp->uf_calls <= 0 && isdigit(*fp->uf_name)
+						      && fp->uf_refcount <= 0)
+			/* Function was unreferenced while being used, free it
+			 * now. */
+			func_free(fp);
+		    restoreRedobuff();
+		    restore_search_patterns();
+		    error = ERROR_NONE;
+		}
+	    }
+	}
+	else
+	{
+	    /*
+	     * Find the function name in the table, call its implementation.
+	     */
+	    i = find_internal_func(fname);
+	    if (i >= 0)
+	    {
+		if (argcount < functions[i].f_min_argc)
+		    error = ERROR_TOOFEW;
+		else if (argcount > functions[i].f_max_argc)
+		    error = ERROR_TOOMANY;
+		else
+		{
+		    argvars[argcount].v_type = VAR_UNKNOWN;
+		    functions[i].f_func(argvars, rettv);
+		    error = ERROR_NONE;
+		}
+	    }
+	}
+	/*
+	 * The function call (or "FuncUndefined" autocommand sequence) might
+	 * have been aborted by an error, an interrupt, or an explicitly thrown
+	 * exception that has not been caught so far.  This situation can be
+	 * tested for by calling aborting().  For an error in an internal
+	 * function or for the "E132" error in call_user_func(), however, the
+	 * throw point at which the "force_abort" flag (temporarily reset by
+	 * emsg()) is normally updated has not been reached yet. We need to
+	 * update that flag first to make aborting() reliable.
+	 */
+	update_force_abort();
+    }
+    if (error == ERROR_NONE)
+	ret = OK;
+
+    /*
+     * Report an error unless the argument evaluation or function call has been
+     * cancelled due to an aborting error, an interrupt, or an exception.
+     */
+    if (!aborting())
+    {
+	switch (error)
+	{
+	    case ERROR_UNKNOWN:
+		    emsg_funcname(N_("E117: Unknown function: %s"), name);
+		    break;
+	    case ERROR_TOOMANY:
+		    emsg_funcname(e_toomanyarg, name);
+		    break;
+	    case ERROR_TOOFEW:
+		    emsg_funcname(N_("E119: Not enough arguments for function: %s"),
+									name);
+		    break;
+	    case ERROR_SCRIPT:
+		    emsg_funcname(N_("E120: Using <SID> not in a script context: %s"),
+									name);
+		    break;
+	    case ERROR_DICT:
+		    emsg_funcname(N_("E725: Calling dict function without Dictionary: %s"),
+									name);
+		    break;
+	}
+    }
+
+    name[len] = cc;
+    if (fname != name && fname != fname_buf)
+	vim_free(fname);
+
+    return ret;
+}
+
+/*
+ * Give an error message with a function name.  Handle <SNR> things.
+ */
+    static void
+emsg_funcname(ermsg, name)
+    char	*ermsg;
+    char_u	*name;
+{
+    char_u	*p;
+
+    if (*name == K_SPECIAL)
+	p = concat_str((char_u *)"<SNR>", name + 3);
+    else
+	p = name;
+    EMSG2(_(ermsg), p);
+    if (p != name)
+	vim_free(p);
+}
+
+/*********************************************
+ * Implementation of the built-in functions
+ */
+
+/*
+ * "add(list, item)" function
+ */
+    static void
+f_add(argvars, rettv)
+    typval_T	*argvars;
+    typval_T	*rettv;
+{
+    list_T	*l;
+
+    rettv->vval.v_number = 1; /* Default: Failed */
+    if (argvars[0].v_type == VAR_LIST)
+    {
+	if ((l = argvars[0].vval.v_list) != NULL
+		&& !tv_check_lock(l->lv_lock, (char_u *)"add()")
+		&& list_append_tv(l, &argvars[1]) == OK)
+	    copy_tv(&argvars[0], rettv);
+    }
+    else
+	EMSG(_(e_listreq));
+}
+
+/*
+ * "append(lnum, string/list)" function
+ */
+    static void
+f_append(argvars, rettv)
+    typval_T	*argvars;
+    typval_T	*rettv;
+{
+    long	lnum;
+    char_u	*line;
+    list_T	*l = NULL;
+    listitem_T	*li = NULL;
+    typval_T	*tv;
+    long	added = 0;
+
+    lnum = get_tv_lnum(argvars);
+    if (lnum >= 0
+	    && lnum <= curbuf->b_ml.ml_line_count
+	    && u_save(lnum, lnum + 1) == OK)
+    {
+	if (argvars[1].v_type == VAR_LIST)
+	{
+	    l = argvars[1].vval.v_list;
+	    if (l == NULL)
+		return;
+	    li = l->lv_first;
+	}
+	rettv->vval.v_number = 0;	/* Default: Success */
+	for (;;)
+	{
+	    if (l == NULL)
+		tv = &argvars[1];	/* append a string */
+	    else if (li == NULL)
+		break;			/* end of list */
+	    else
+		tv = &li->li_tv;	/* append item from list */
+	    line = get_tv_string_chk(tv);
+	    if (line == NULL)		/* type error */
+	    {
+		rettv->vval.v_number = 1;	/* Failed */
+		break;
+	    }
+	    ml_append(lnum + added, line, (colnr_T)0, FALSE);
+	    ++added;
+	    if (l == NULL)
+		break;
+	    li = li->li_next;
+	}
+
+	appended_lines_mark(lnum, added);
+	if (curwin->w_cursor.lnum > lnum)
+	    curwin->w_cursor.lnum += added;
+    }
+    else
+	rettv->vval.v_number = 1;	/* Failed */
+}
+
+/*
+ * "argc()" function
+ */
+/* ARGSUSED */
+    static void
+f_argc(argvars, rettv)
+    typval_T	*argvars;
+    typval_T	*rettv;
+{
+    rettv->vval.v_number = ARGCOUNT;
+}
+
+/*
+ * "argidx()" function
+ */
+/* ARGSUSED */
+    static void
+f_argidx(argvars, rettv)
+    typval_T	*argvars;
+    typval_T	*rettv;
+{
+    rettv->vval.v_number = curwin->w_arg_idx;
+}
+
+/*
+ * "argv(nr)" function
+ */
+    static void
+f_argv(argvars, rettv)
+    typval_T	*argvars;
+    typval_T	*rettv;
+{
+    int		idx;
+
+    if (argvars[0].v_type != VAR_UNKNOWN)
+    {
+	idx = get_tv_number_chk(&argvars[0], NULL);
+	if (idx >= 0 && idx < ARGCOUNT)
+	    rettv->vval.v_string = vim_strsave(alist_name(&ARGLIST[idx]));
+	else
+	    rettv->vval.v_string = NULL;
+	rettv->v_type = VAR_STRING;
+    }
+    else if (rettv_list_alloc(rettv) == OK)
+	for (idx = 0; idx < ARGCOUNT; ++idx)
+	    list_append_string(rettv->vval.v_list,
+					       alist_name(&ARGLIST[idx]), -1);
+}
+
+/*
+ * "browse(save, title, initdir, default)" function
+ */
+/* ARGSUSED */
+    static void
+f_browse(argvars, rettv)
+    typval_T	*argvars;
+    typval_T	*rettv;
+{
+#ifdef FEAT_BROWSE
+    int		save;
+    char_u	*title;
+    char_u	*initdir;
+    char_u	*defname;
+    char_u	buf[NUMBUFLEN];
+    char_u	buf2[NUMBUFLEN];
+    int		error = FALSE;
+
+    save = get_tv_number_chk(&argvars[0], &error);
+    title = get_tv_string_chk(&argvars[1]);
+    initdir = get_tv_string_buf_chk(&argvars[2], buf);
+    defname = get_tv_string_buf_chk(&argvars[3], buf2);
+
+    if (error || title == NULL || initdir == NULL || defname == NULL)
+	rettv->vval.v_string = NULL;
+    else
+	rettv->vval.v_string =
+		 do_browse(save ? BROWSE_SAVE : 0,
+				 title, defname, NULL, initdir, NULL, curbuf);
+#else
+    rettv->vval.v_string = NULL;
+#endif
+    rettv->v_type = VAR_STRING;
+}
+
+/*
+ * "browsedir(title, initdir)" function
+ */
+/* ARGSUSED */
+    static void
+f_browsedir(argvars, rettv)
+    typval_T	*argvars;
+    typval_T	*rettv;
+{
+#ifdef FEAT_BROWSE
+    char_u	*title;
+    char_u	*initdir;
+    char_u	buf[NUMBUFLEN];
+
+    title = get_tv_string_chk(&argvars[0]);
+    initdir = get_tv_string_buf_chk(&argvars[1], buf);
+
+    if (title == NULL || initdir == NULL)
+	rettv->vval.v_string = NULL;
+    else
+	rettv->vval.v_string = do_browse(BROWSE_DIR,
+				    title, NULL, NULL, initdir, NULL, curbuf);
+#else
+    rettv->vval.v_string = NULL;
+#endif
+    rettv->v_type = VAR_STRING;
+}
+
+static buf_T *find_buffer __ARGS((typval_T *avar));
+
+/*
+ * Find a buffer by number or exact name.
+ */
+    static buf_T *
+find_buffer(avar)
+    typval_T	*avar;
+{
+    buf_T	*buf = NULL;
+
+    if (avar->v_type == VAR_NUMBER)
+	buf = buflist_findnr((int)avar->vval.v_number);
+    else if (avar->v_type == VAR_STRING && avar->vval.v_string != NULL)
+    {
+	buf = buflist_findname_exp(avar->vval.v_string);
+	if (buf == NULL)
+	{
+	    /* No full path name match, try a match with a URL or a "nofile"
+	     * buffer, these don't use the full path. */
+	    for (buf = firstbuf; buf != NULL; buf = buf->b_next)
+		if (buf->b_fname != NULL
+			&& (path_with_url(buf->b_fname)
+#ifdef FEAT_QUICKFIX
+			    || bt_nofile(buf)
+#endif
+			   )
+			&& STRCMP(buf->b_fname, avar->vval.v_string) == 0)
+		    break;
+	}
+    }
+    return buf;
+}
+
+/*
+ * "bufexists(expr)" function
+ */
+    static void
+f_bufexists(argvars, rettv)
+    typval_T	*argvars;
+    typval_T	*rettv;
+{
+    rettv->vval.v_number = (find_buffer(&argvars[0]) != NULL);
+}
+
+/*
+ * "buflisted(expr)" function
+ */
+    static void
+f_buflisted(argvars, rettv)
+    typval_T	*argvars;
+    typval_T	*rettv;
+{
+    buf_T	*buf;
+
+    buf = find_buffer(&argvars[0]);
+    rettv->vval.v_number = (buf != NULL && buf->b_p_bl);
+}
+
+/*
+ * "bufloaded(expr)" function
+ */
+    static void
+f_bufloaded(argvars, rettv)
+    typval_T	*argvars;
+    typval_T	*rettv;
+{
+    buf_T	*buf;
+
+    buf = find_buffer(&argvars[0]);
+    rettv->vval.v_number = (buf != NULL && buf->b_ml.ml_mfp != NULL);
+}
+
+static buf_T *get_buf_tv __ARGS((typval_T *tv));
+
+/*
+ * Get buffer by number or pattern.
+ */
+    static buf_T *
+get_buf_tv(tv)
+    typval_T	*tv;
+{
+    char_u	*name = tv->vval.v_string;
+    int		save_magic;
+    char_u	*save_cpo;
+    buf_T	*buf;
+
+    if (tv->v_type == VAR_NUMBER)
+	return buflist_findnr((int)tv->vval.v_number);
+    if (tv->v_type != VAR_STRING)
+	return NULL;
+    if (name == NULL || *name == NUL)
+	return curbuf;
+    if (name[0] == '$' && name[1] == NUL)
+	return lastbuf;
+
+    /* Ignore 'magic' and 'cpoptions' here to make scripts portable */
+    save_magic = p_magic;
+    p_magic = TRUE;
+    save_cpo = p_cpo;
+    p_cpo = (char_u *)"";
+
+    buf = buflist_findnr(buflist_findpat(name, name + STRLEN(name),
+								TRUE, FALSE));
+
+    p_magic = save_magic;
+    p_cpo = save_cpo;
+
+    /* If not found, try expanding the name, like done for bufexists(). */
+    if (buf == NULL)
+	buf = find_buffer(tv);
+
+    return buf;
+}
+
+/*
+ * "bufname(expr)" function
+ */
+    static void
+f_bufname(argvars, rettv)
+    typval_T	*argvars;
+    typval_T	*rettv;
+{
+    buf_T	*buf;
+
+    (void)get_tv_number(&argvars[0]);	    /* issue errmsg if type error */
+    ++emsg_off;
+    buf = get_buf_tv(&argvars[0]);
+    rettv->v_type = VAR_STRING;
+    if (buf != NULL && buf->b_fname != NULL)
+	rettv->vval.v_string = vim_strsave(buf->b_fname);
+    else
+	rettv->vval.v_string = NULL;
+    --emsg_off;
+}
+
+/*
+ * "bufnr(expr)" function
+ */
+    static void
+f_bufnr(argvars, rettv)
+    typval_T	*argvars;
+    typval_T	*rettv;
+{
+    buf_T	*buf;
+    int		error = FALSE;
+    char_u	*name;
+
+    (void)get_tv_number(&argvars[0]);	    /* issue errmsg if type error */
+    ++emsg_off;
+    buf = get_buf_tv(&argvars[0]);
+    --emsg_off;
+
+    /* If the buffer isn't found and the second argument is not zero create a
+     * new buffer. */
+    if (buf == NULL
+	    && argvars[1].v_type != VAR_UNKNOWN
+	    && get_tv_number_chk(&argvars[1], &error) != 0
+	    && !error
+	    && (name = get_tv_string_chk(&argvars[0])) != NULL
+	    && !error)
+	buf = buflist_new(name, NULL, (linenr_T)1, 0);
+
+    if (buf != NULL)
+	rettv->vval.v_number = buf->b_fnum;
+    else
+	rettv->vval.v_number = -1;
+}
+
+/*
+ * "bufwinnr(nr)" function
+ */
+    static void
+f_bufwinnr(argvars, rettv)
+    typval_T	*argvars;
+    typval_T	*rettv;
+{
+#ifdef FEAT_WINDOWS
+    win_T	*wp;
+    int		winnr = 0;
+#endif
+    buf_T	*buf;
+
+    (void)get_tv_number(&argvars[0]);	    /* issue errmsg if type error */
+    ++emsg_off;
+    buf = get_buf_tv(&argvars[0]);
+#ifdef FEAT_WINDOWS
+    for (wp = firstwin; wp; wp = wp->w_next)
+    {
+	++winnr;
+	if (wp->w_buffer == buf)
+	    break;
+    }
+    rettv->vval.v_number = (wp != NULL ? winnr : -1);
+#else
+    rettv->vval.v_number = (curwin->w_buffer == buf ? 1 : -1);
+#endif
+    --emsg_off;
+}
+
+/*
+ * "byte2line(byte)" function
+ */
+/*ARGSUSED*/
+    static void
+f_byte2line(argvars, rettv)
+    typval_T	*argvars;
+    typval_T	*rettv;
+{
+#ifndef FEAT_BYTEOFF
+    rettv->vval.v_number = -1;
+#else
+    long	boff = 0;
+
+    boff = get_tv_number(&argvars[0]) - 1;  /* boff gets -1 on type error */
+    if (boff < 0)
+	rettv->vval.v_number = -1;
+    else
+	rettv->vval.v_number = ml_find_line_or_offset(curbuf,
+							  (linenr_T)0, &boff);
+#endif
+}
+
+/*
+ * "byteidx()" function
+ */
+/*ARGSUSED*/
+    static void
+f_byteidx(argvars, rettv)
+    typval_T	*argvars;
+    typval_T	*rettv;
+{
+#ifdef FEAT_MBYTE
+    char_u	*t;
+#endif
+    char_u	*str;
+    long	idx;
+
+    str = get_tv_string_chk(&argvars[0]);
+    idx = get_tv_number_chk(&argvars[1], NULL);
+    rettv->vval.v_number = -1;
+    if (str == NULL || idx < 0)
+	return;
+
+#ifdef FEAT_MBYTE
+    t = str;
+    for ( ; idx > 0; idx--)
+    {
+	if (*t == NUL)		/* EOL reached */
+	    return;
+	t += (*mb_ptr2len)(t);
+    }
+    rettv->vval.v_number = (varnumber_T)(t - str);
+#else
+    if (idx <= STRLEN(str))
+	rettv->vval.v_number = idx;
+#endif
+}
+
+/*
+ * "call(func, arglist)" function
+ */
+    static void
+f_call(argvars, rettv)
+    typval_T	*argvars;
+    typval_T	*rettv;
+{
+    char_u	*func;
+    typval_T	argv[MAX_FUNC_ARGS + 1];
+    int		argc = 0;
+    listitem_T	*item;
+    int		dummy;
+    dict_T	*selfdict = NULL;
+
+    rettv->vval.v_number = 0;
+    if (argvars[1].v_type != VAR_LIST)
+    {
+	EMSG(_(e_listreq));
+	return;
+    }
+    if (argvars[1].vval.v_list == NULL)
+	return;
+
+    if (argvars[0].v_type == VAR_FUNC)
+	func = argvars[0].vval.v_string;
+    else
+	func = get_tv_string(&argvars[0]);
+    if (*func == NUL)
+	return;		/* type error or empty name */
+
+    if (argvars[2].v_type != VAR_UNKNOWN)
+    {
+	if (argvars[2].v_type != VAR_DICT)
+	{
+	    EMSG(_(e_dictreq));
+	    return;
+	}
+	selfdict = argvars[2].vval.v_dict;
+    }
+
+    for (item = argvars[1].vval.v_list->lv_first; item != NULL;
+							 item = item->li_next)
+    {
+	if (argc == MAX_FUNC_ARGS)
+	{
+	    EMSG(_("E699: Too many arguments"));
+	    break;
+	}
+	/* Make a copy of each argument.  This is needed to be able to set
+	 * v_lock to VAR_FIXED in the copy without changing the original list.
+	 */
+	copy_tv(&item->li_tv, &argv[argc++]);
+    }
+
+    if (item == NULL)
+	(void)call_func(func, (int)STRLEN(func), rettv, argc, argv,
+				 curwin->w_cursor.lnum, curwin->w_cursor.lnum,
+						      &dummy, TRUE, selfdict);
+
+    /* Free the arguments. */
+    while (argc > 0)
+	clear_tv(&argv[--argc]);
+}
+
+/*
+ * "changenr()" function
+ */
+/*ARGSUSED*/
+    static void
+f_changenr(argvars, rettv)
+    typval_T	*argvars;
+    typval_T	*rettv;
+{
+    rettv->vval.v_number = curbuf->b_u_seq_cur;
+}
+
+/*
+ * "char2nr(string)" function
+ */
+    static void
+f_char2nr(argvars, rettv)
+    typval_T	*argvars;
+    typval_T	*rettv;
+{
+#ifdef FEAT_MBYTE
+    if (has_mbyte)
+	rettv->vval.v_number = (*mb_ptr2char)(get_tv_string(&argvars[0]));
+    else
+#endif
+    rettv->vval.v_number = get_tv_string(&argvars[0])[0];
+}
+
+/*
+ * "cindent(lnum)" function
+ */
+    static void
+f_cindent(argvars, rettv)
+    typval_T	*argvars;
+    typval_T	*rettv;
+{
+#ifdef FEAT_CINDENT
+    pos_T	pos;
+    linenr_T	lnum;
+
+    pos = curwin->w_cursor;
+    lnum = get_tv_lnum(argvars);
+    if (lnum >= 1 && lnum <= curbuf->b_ml.ml_line_count)
+    {
+	curwin->w_cursor.lnum = lnum;
+	rettv->vval.v_number = get_c_indent();
+	curwin->w_cursor = pos;
+    }
+    else
+#endif
+	rettv->vval.v_number = -1;
+}
+
+/*
+ * "col(string)" function
+ */
+    static void
+f_col(argvars, rettv)
+    typval_T	*argvars;
+    typval_T	*rettv;
+{
+    colnr_T	col = 0;
+    pos_T	*fp;
+    int		fnum = curbuf->b_fnum;
+
+    fp = var2fpos(&argvars[0], FALSE, &fnum);
+    if (fp != NULL && fnum == curbuf->b_fnum)
+    {
+	if (fp->col == MAXCOL)
+	{
+	    /* '> can be MAXCOL, get the length of the line then */
+	    if (fp->lnum <= curbuf->b_ml.ml_line_count)
+		col = (colnr_T)STRLEN(ml_get(fp->lnum)) + 1;
+	    else
+		col = MAXCOL;
+	}
+	else
+	{
+	    col = fp->col + 1;
+#ifdef FEAT_VIRTUALEDIT
+	    /* col(".") when the cursor is on the NUL at the end of the line
+	     * because of "coladd" can be seen as an extra column. */
+	    if (virtual_active() && fp == &curwin->w_cursor)
+	    {
+		char_u	*p = ml_get_cursor();
+
+		if (curwin->w_cursor.coladd >= (colnr_T)chartabsize(p,
+				 curwin->w_virtcol - curwin->w_cursor.coladd))
+		{
+# ifdef FEAT_MBYTE
+		    int		l;
+
+		    if (*p != NUL && p[(l = (*mb_ptr2len)(p))] == NUL)
+			col += l;
+# else
+		    if (*p != NUL && p[1] == NUL)
+			++col;
+# endif
+		}
+	    }
+#endif
+	}
+    }
+    rettv->vval.v_number = col;
+}
+
+#if defined(FEAT_INS_EXPAND)
+/*
+ * "complete()" function
+ */
+/*ARGSUSED*/
+    static void
+f_complete(argvars, rettv)
+    typval_T	*argvars;
+    typval_T	*rettv;
+{
+    int	    startcol;
+
+    if ((State & INSERT) == 0)
+    {
+	EMSG(_("E785: complete() can only be used in Insert mode"));
+	return;
+    }
+
+    /* Check for undo allowed here, because if something was already inserted
+     * the line was already saved for undo and this check isn't done. */
+    if (!undo_allowed())
+	return;
+
+    if (argvars[1].v_type != VAR_LIST || argvars[1].vval.v_list == NULL)
+    {
+	EMSG(_(e_invarg));
+	return;
+    }
+
+    startcol = get_tv_number_chk(&argvars[0], NULL);
+    if (startcol <= 0)
+	return;
+
+    set_completion(startcol - 1, argvars[1].vval.v_list);
+}
+
+/*
+ * "complete_add()" function
+ */
+/*ARGSUSED*/
+    static void
+f_complete_add(argvars, rettv)
+    typval_T	*argvars;
+    typval_T	*rettv;
+{
+    rettv->vval.v_number = ins_compl_add_tv(&argvars[0], 0);
+}
+
+/*
+ * "complete_check()" function
+ */
+/*ARGSUSED*/
+    static void
+f_complete_check(argvars, rettv)
+    typval_T	*argvars;
+    typval_T	*rettv;
+{
+    int		saved = RedrawingDisabled;
+
+    RedrawingDisabled = 0;
+    ins_compl_check_keys(0);
+    rettv->vval.v_number = compl_interrupted;
+    RedrawingDisabled = saved;
+}
+#endif
+
+/*
+ * "confirm(message, buttons[, default [, type]])" function
+ */
+/*ARGSUSED*/
+    static void
+f_confirm(argvars, rettv)
+    typval_T	*argvars;
+    typval_T	*rettv;
+{
+#if defined(FEAT_GUI_DIALOG) || defined(FEAT_CON_DIALOG)
+    char_u	*message;
+    char_u	*buttons = NULL;
+    char_u	buf[NUMBUFLEN];
+    char_u	buf2[NUMBUFLEN];
+    int		def = 1;
+    int		type = VIM_GENERIC;
+    char_u	*typestr0;
+    int		error = FALSE;
+
+    message = get_tv_string_chk(&argvars[0]);
+    if (message == NULL)
+	error = TRUE;
+    if (argvars[1].v_type != VAR_UNKNOWN)
+    {
+	buttons = get_tv_string_buf_chk(&argvars[1], buf);
+	if (buttons == NULL)
+	    error = TRUE;
+	if (argvars[2].v_type != VAR_UNKNOWN)
+	{
+	    def = get_tv_number_chk(&argvars[2], &error);
+	    if (argvars[3].v_type != VAR_UNKNOWN)
+	    {
+		typestr0 = get_tv_string_buf_chk(&argvars[3], buf2);
+		if (typestr0 == NULL)
+		    error = TRUE;
+		else
+		{
+		    switch (TOUPPER_ASC(*typestr0))
+		    {
+			case 'E': type = VIM_ERROR; break;
+			case 'Q': type = VIM_QUESTION; break;
+			case 'I': type = VIM_INFO; break;
+			case 'W': type = VIM_WARNING; break;
+			case 'G': type = VIM_GENERIC; break;
+		    }
+		}
+	    }
+	}
+    }
+
+    if (buttons == NULL || *buttons == NUL)
+	buttons = (char_u *)_("&Ok");
+
+    if (error)
+	rettv->vval.v_number = 0;
+    else
+	rettv->vval.v_number = do_dialog(type, NULL, message, buttons,
+								   def, NULL);
+#else
+    rettv->vval.v_number = 0;
+#endif
+}
+
+/*
+ * "copy()" function
+ */
+    static void
+f_copy(argvars, rettv)
+    typval_T	*argvars;
+    typval_T	*rettv;
+{
+    item_copy(&argvars[0], rettv, FALSE, 0);
+}
+
+/*
+ * "count()" function
+ */
+    static void
+f_count(argvars, rettv)
+    typval_T	*argvars;
+    typval_T	*rettv;
+{
+    long	n = 0;
+    int		ic = FALSE;
+
+    if (argvars[0].v_type == VAR_LIST)
+    {
+	listitem_T	*li;
+	list_T		*l;
+	long		idx;
+
+	if ((l = argvars[0].vval.v_list) != NULL)
+	{
+	    li = l->lv_first;
+	    if (argvars[2].v_type != VAR_UNKNOWN)
+	    {
+		int error = FALSE;
+
+		ic = get_tv_number_chk(&argvars[2], &error);
+		if (argvars[3].v_type != VAR_UNKNOWN)
+		{
+		    idx = get_tv_number_chk(&argvars[3], &error);
+		    if (!error)
+		    {
+			li = list_find(l, idx);
+			if (li == NULL)
+			    EMSGN(_(e_listidx), idx);
+		    }
+		}
+		if (error)
+		    li = NULL;
+	    }
+
+	    for ( ; li != NULL; li = li->li_next)
+		if (tv_equal(&li->li_tv, &argvars[1], ic))
+		    ++n;
+	}
+    }
+    else if (argvars[0].v_type == VAR_DICT)
+    {
+	int		todo;
+	dict_T		*d;
+	hashitem_T	*hi;
+
+	if ((d = argvars[0].vval.v_dict) != NULL)
+	{
+	    int error = FALSE;
+
+	    if (argvars[2].v_type != VAR_UNKNOWN)
+	    {
+		ic = get_tv_number_chk(&argvars[2], &error);
+		if (argvars[3].v_type != VAR_UNKNOWN)
+		    EMSG(_(e_invarg));
+	    }
+
+	    todo = error ? 0 : (int)d->dv_hashtab.ht_used;
+	    for (hi = d->dv_hashtab.ht_array; todo > 0; ++hi)
+	    {
+		if (!HASHITEM_EMPTY(hi))
+		{
+		    --todo;
+		    if (tv_equal(&HI2DI(hi)->di_tv, &argvars[1], ic))
+			++n;
+		}
+	    }
+	}
+    }
+    else
+	EMSG2(_(e_listdictarg), "count()");
+    rettv->vval.v_number = n;
+}
+
+/*
+ * "cscope_connection([{num} , {dbpath} [, {prepend}]])" function
+ *
+ * Checks the existence of a cscope connection.
+ */
+/*ARGSUSED*/
+    static void
+f_cscope_connection(argvars, rettv)
+    typval_T	*argvars;
+    typval_T	*rettv;
+{
+#ifdef FEAT_CSCOPE
+    int		num = 0;
+    char_u	*dbpath = NULL;
+    char_u	*prepend = NULL;
+    char_u	buf[NUMBUFLEN];
+
+    if (argvars[0].v_type != VAR_UNKNOWN
+	    && argvars[1].v_type != VAR_UNKNOWN)
+    {
+	num = (int)get_tv_number(&argvars[0]);
+	dbpath = get_tv_string(&argvars[1]);
+	if (argvars[2].v_type != VAR_UNKNOWN)
+	    prepend = get_tv_string_buf(&argvars[2], buf);
+    }
+
+    rettv->vval.v_number = cs_connection(num, dbpath, prepend);
+#else
+    rettv->vval.v_number = 0;
+#endif
+}
+
+/*
+ * "cursor(lnum, col)" function
+ *
+ * Moves the cursor to the specified line and column
+ */
+/*ARGSUSED*/
+    static void
+f_cursor(argvars, rettv)
+    typval_T	*argvars;
+    typval_T	*rettv;
+{
+    long	line, col;
+#ifdef FEAT_VIRTUALEDIT
+    long	coladd = 0;
+#endif
+
+    if (argvars[1].v_type == VAR_UNKNOWN)
+    {
+	pos_T	    pos;
+
+	if (list2fpos(argvars, &pos, NULL) == FAIL)
+	    return;
+	line = pos.lnum;
+	col = pos.col;
+#ifdef FEAT_VIRTUALEDIT
+	coladd = pos.coladd;
+#endif
+    }
+    else
+    {
+	line = get_tv_lnum(argvars);
+	col = get_tv_number_chk(&argvars[1], NULL);
+#ifdef FEAT_VIRTUALEDIT
+	if (argvars[2].v_type != VAR_UNKNOWN)
+	    coladd = get_tv_number_chk(&argvars[2], NULL);
+#endif
+    }
+    if (line < 0 || col < 0
+#ifdef FEAT_VIRTUALEDIT
+			    || coladd < 0
+#endif
+	    )
+	return;		/* type error; errmsg already given */
+    if (line > 0)
+	curwin->w_cursor.lnum = line;
+    if (col > 0)
+	curwin->w_cursor.col = col - 1;
+#ifdef FEAT_VIRTUALEDIT
+    curwin->w_cursor.coladd = coladd;
+#endif
+
+    /* Make sure the cursor is in a valid position. */
+    check_cursor();
+#ifdef FEAT_MBYTE
+    /* Correct cursor for multi-byte character. */
+    if (has_mbyte)
+	mb_adjust_cursor();
+#endif
+
+    curwin->w_set_curswant = TRUE;
+}
+
+/*
+ * "deepcopy()" function
+ */
+    static void
+f_deepcopy(argvars, rettv)
+    typval_T	*argvars;
+    typval_T	*rettv;
+{
+    int		noref = 0;
+
+    if (argvars[1].v_type != VAR_UNKNOWN)
+	noref = get_tv_number_chk(&argvars[1], NULL);
+    if (noref < 0 || noref > 1)
+	EMSG(_(e_invarg));
+    else
+	item_copy(&argvars[0], rettv, TRUE, noref == 0 ? ++current_copyID : 0);
+}
+
+/*
+ * "delete()" function
+ */
+    static void
+f_delete(argvars, rettv)
+    typval_T	*argvars;
+    typval_T	*rettv;
+{
+    if (check_restricted() || check_secure())
+	rettv->vval.v_number = -1;
+    else
+	rettv->vval.v_number = mch_remove(get_tv_string(&argvars[0]));
+}
+
+/*
+ * "did_filetype()" function
+ */
+/*ARGSUSED*/
+    static void
+f_did_filetype(argvars, rettv)
+    typval_T	*argvars;
+    typval_T	*rettv;
+{
+#ifdef FEAT_AUTOCMD
+    rettv->vval.v_number = did_filetype;
+#else
+    rettv->vval.v_number = 0;
+#endif
+}
+
+/*
+ * "diff_filler()" function
+ */
+/*ARGSUSED*/
+    static void
+f_diff_filler(argvars, rettv)
+    typval_T	*argvars;
+    typval_T	*rettv;
+{
+#ifdef FEAT_DIFF
+    rettv->vval.v_number = diff_check_fill(curwin, get_tv_lnum(argvars));
+#endif
+}
+
+/*
+ * "diff_hlID()" function
+ */
+/*ARGSUSED*/
+    static void
+f_diff_hlID(argvars, rettv)
+    typval_T	*argvars;
+    typval_T	*rettv;
+{
+#ifdef FEAT_DIFF
+    linenr_T		lnum = get_tv_lnum(argvars);
+    static linenr_T	prev_lnum = 0;
+    static int		changedtick = 0;
+    static int		fnum = 0;
+    static int		change_start = 0;
+    static int		change_end = 0;
+    static hlf_T	hlID = 0;
+    int			filler_lines;
+    int			col;
+
+    if (lnum < 0)	/* ignore type error in {lnum} arg */
+	lnum = 0;
+    if (lnum != prev_lnum
+	    || changedtick != curbuf->b_changedtick
+	    || fnum != curbuf->b_fnum)
+    {
+	/* New line, buffer, change: need to get the values. */
+	filler_lines = diff_check(curwin, lnum);
+	if (filler_lines < 0)
+	{
+	    if (filler_lines == -1)
+	    {
+		change_start = MAXCOL;
+		change_end = -1;
+		if (diff_find_change(curwin, lnum, &change_start, &change_end))
+		    hlID = HLF_ADD;	/* added line */
+		else
+		    hlID = HLF_CHD;	/* changed line */
+	    }
+	    else
+		hlID = HLF_ADD;	/* added line */
+	}
+	else
+	    hlID = (hlf_T)0;
+	prev_lnum = lnum;
+	changedtick = curbuf->b_changedtick;
+	fnum = curbuf->b_fnum;
+    }
+
+    if (hlID == HLF_CHD || hlID == HLF_TXD)
+    {
+	col = get_tv_number(&argvars[1]) - 1; /* ignore type error in {col} */
+	if (col >= change_start && col <= change_end)
+	    hlID = HLF_TXD;			/* changed text */
+	else
+	    hlID = HLF_CHD;			/* changed line */
+    }
+    rettv->vval.v_number = hlID == (hlf_T)0 ? 0 : (int)hlID;
+#endif
+}
+
+/*
+ * "empty({expr})" function
+ */
+    static void
+f_empty(argvars, rettv)
+    typval_T	*argvars;
+    typval_T	*rettv;
+{
+    int		n;
+
+    switch (argvars[0].v_type)
+    {
+	case VAR_STRING:
+	case VAR_FUNC:
+	    n = argvars[0].vval.v_string == NULL
+					  || *argvars[0].vval.v_string == NUL;
+	    break;
+	case VAR_NUMBER:
+	    n = argvars[0].vval.v_number == 0;
+	    break;
+	case VAR_LIST:
+	    n = argvars[0].vval.v_list == NULL
+				  || argvars[0].vval.v_list->lv_first == NULL;
+	    break;
+	case VAR_DICT:
+	    n = argvars[0].vval.v_dict == NULL
+			|| argvars[0].vval.v_dict->dv_hashtab.ht_used == 0;
+	    break;
+	default:
+	    EMSG2(_(e_intern2), "f_empty()");
+	    n = 0;
+    }
+
+    rettv->vval.v_number = n;
+}
+
+/*
+ * "escape({string}, {chars})" function
+ */
+    static void
+f_escape(argvars, rettv)
+    typval_T	*argvars;
+    typval_T	*rettv;
+{
+    char_u	buf[NUMBUFLEN];
+
+    rettv->vval.v_string = vim_strsave_escaped(get_tv_string(&argvars[0]),
+					 get_tv_string_buf(&argvars[1], buf));
+    rettv->v_type = VAR_STRING;
+}
+
+/*
+ * "eval()" function
+ */
+/*ARGSUSED*/
+    static void
+f_eval(argvars, rettv)
+    typval_T	*argvars;
+    typval_T	*rettv;
+{
+    char_u	*s;
+
+    s = get_tv_string_chk(&argvars[0]);
+    if (s != NULL)
+	s = skipwhite(s);
+
+    if (s == NULL || eval1(&s, rettv, TRUE) == FAIL)
+    {
+	rettv->v_type = VAR_NUMBER;
+	rettv->vval.v_number = 0;
+    }
+    else if (*s != NUL)
+	EMSG(_(e_trailing));
+}
+
+/*
+ * "eventhandler()" function
+ */
+/*ARGSUSED*/
+    static void
+f_eventhandler(argvars, rettv)
+    typval_T	*argvars;
+    typval_T	*rettv;
+{
+    rettv->vval.v_number = vgetc_busy;
+}
+
+/*
+ * "executable()" function
+ */
+    static void
+f_executable(argvars, rettv)
+    typval_T	*argvars;
+    typval_T	*rettv;
+{
+    rettv->vval.v_number = mch_can_exe(get_tv_string(&argvars[0]));
+}
+
+/*
+ * "exists()" function
+ */
+    static void
+f_exists(argvars, rettv)
+    typval_T	*argvars;
+    typval_T	*rettv;
+{
+    char_u	*p;
+    char_u	*name;
+    int		n = FALSE;
+    int		len = 0;
+
+    p = get_tv_string(&argvars[0]);
+    if (*p == '$')			/* environment variable */
+    {
+	/* first try "normal" environment variables (fast) */
+	if (mch_getenv(p + 1) != NULL)
+	    n = TRUE;
+	else
+	{
+	    /* try expanding things like $VIM and ${HOME} */
+	    p = expand_env_save(p);
+	    if (p != NULL && *p != '$')
+		n = TRUE;
+	    vim_free(p);
+	}
+    }
+    else if (*p == '&' || *p == '+')			/* option */
+    {
+	n = (get_option_tv(&p, NULL, TRUE) == OK);
+	if (*skipwhite(p) != NUL)
+	    n = FALSE;			/* trailing garbage */
+    }
+    else if (*p == '*')			/* internal or user defined function */
+    {
+	n = function_exists(p + 1);
+    }
+    else if (*p == ':')
+    {
+	n = cmd_exists(p + 1);
+    }
+    else if (*p == '#')
+    {
+#ifdef FEAT_AUTOCMD
+	if (p[1] == '#')
+	    n = autocmd_supported(p + 2);
+	else
+	    n = au_exists(p + 1);
+#endif
+    }
+    else				/* internal variable */
+    {
+	char_u	    *tofree;
+	typval_T    tv;
+
+	/* get_name_len() takes care of expanding curly braces */
+	name = p;
+	len = get_name_len(&p, &tofree, TRUE, FALSE);
+	if (len > 0)
+	{
+	    if (tofree != NULL)
+		name = tofree;
+	    n = (get_var_tv(name, len, &tv, FALSE) == OK);
+	    if (n)
+	    {
+		/* handle d.key, l[idx], f(expr) */
+		n = (handle_subscript(&p, &tv, TRUE, FALSE) == OK);
+		if (n)
+		    clear_tv(&tv);
+	    }
+	}
+	if (*p != NUL)
+	    n = FALSE;
+
+	vim_free(tofree);
+    }
+
+    rettv->vval.v_number = n;
+}
+
+/*
+ * "expand()" function
+ */
+    static void
+f_expand(argvars, rettv)
+    typval_T	*argvars;
+    typval_T	*rettv;
+{
+    char_u	*s;
+    int		len;
+    char_u	*errormsg;
+    int		flags = WILD_SILENT|WILD_USE_NL|WILD_LIST_NOTFOUND;
+    expand_T	xpc;
+    int		error = FALSE;
+
+    rettv->v_type = VAR_STRING;
+    s = get_tv_string(&argvars[0]);
+    if (*s == '%' || *s == '#' || *s == '<')
+    {
+	++emsg_off;
+	rettv->vval.v_string = eval_vars(s, s, &len, NULL, &errormsg, NULL);
+	--emsg_off;
+    }
+    else
+    {
+	/* When the optional second argument is non-zero, don't remove matches
+	 * for 'suffixes' and 'wildignore' */
+	if (argvars[1].v_type != VAR_UNKNOWN
+				    && get_tv_number_chk(&argvars[1], &error))
+	    flags |= WILD_KEEP_ALL;
+	if (!error)
+	{
+	    ExpandInit(&xpc);
+	    xpc.xp_context = EXPAND_FILES;
+	    rettv->vval.v_string = ExpandOne(&xpc, s, NULL, flags, WILD_ALL);
+	}
+	else
+	    rettv->vval.v_string = NULL;
+    }
+}
+
+/*
+ * "extend(list, list [, idx])" function
+ * "extend(dict, dict [, action])" function
+ */
+    static void
+f_extend(argvars, rettv)
+    typval_T	*argvars;
+    typval_T	*rettv;
+{
+    rettv->vval.v_number = 0;
+    if (argvars[0].v_type == VAR_LIST && argvars[1].v_type == VAR_LIST)
+    {
+	list_T		*l1, *l2;
+	listitem_T	*item;
+	long		before;
+	int		error = FALSE;
+
+	l1 = argvars[0].vval.v_list;
+	l2 = argvars[1].vval.v_list;
+	if (l1 != NULL && !tv_check_lock(l1->lv_lock, (char_u *)"extend()")
+		&& l2 != NULL)
+	{
+	    if (argvars[2].v_type != VAR_UNKNOWN)
+	    {
+		before = get_tv_number_chk(&argvars[2], &error);
+		if (error)
+		    return;		/* type error; errmsg already given */
+
+		if (before == l1->lv_len)
+		    item = NULL;
+		else
+		{
+		    item = list_find(l1, before);
+		    if (item == NULL)
+		    {
+			EMSGN(_(e_listidx), before);
+			return;
+		    }
+		}
+	    }
+	    else
+		item = NULL;
+	    list_extend(l1, l2, item);
+
+	    copy_tv(&argvars[0], rettv);
+	}
+    }
+    else if (argvars[0].v_type == VAR_DICT && argvars[1].v_type == VAR_DICT)
+    {
+	dict_T		*d1, *d2;
+	dictitem_T	*di1;
+	char_u		*action;
+	int		i;
+	hashitem_T	*hi2;
+	int		todo;
+
+	d1 = argvars[0].vval.v_dict;
+	d2 = argvars[1].vval.v_dict;
+	if (d1 != NULL && !tv_check_lock(d1->dv_lock, (char_u *)"extend()")
+		&& d2 != NULL)
+	{
+	    /* Check the third argument. */
+	    if (argvars[2].v_type != VAR_UNKNOWN)
+	    {
+		static char *(av[]) = {"keep", "force", "error"};
+
+		action = get_tv_string_chk(&argvars[2]);
+		if (action == NULL)
+		    return;		/* type error; errmsg already given */
+		for (i = 0; i < 3; ++i)
+		    if (STRCMP(action, av[i]) == 0)
+			break;
+		if (i == 3)
+		{
+		    EMSG2(_(e_invarg2), action);
+		    return;
+		}
+	    }
+	    else
+		action = (char_u *)"force";
+
+	    /* Go over all entries in the second dict and add them to the
+	     * first dict. */
+	    todo = (int)d2->dv_hashtab.ht_used;
+	    for (hi2 = d2->dv_hashtab.ht_array; todo > 0; ++hi2)
+	    {
+		if (!HASHITEM_EMPTY(hi2))
+		{
+		    --todo;
+		    di1 = dict_find(d1, hi2->hi_key, -1);
+		    if (di1 == NULL)
+		    {
+			di1 = dictitem_copy(HI2DI(hi2));
+			if (di1 != NULL && dict_add(d1, di1) == FAIL)
+			    dictitem_free(di1);
+		    }
+		    else if (*action == 'e')
+		    {
+			EMSG2(_("E737: Key already exists: %s"), hi2->hi_key);
+			break;
+		    }
+		    else if (*action == 'f')
+		    {
+			clear_tv(&di1->di_tv);
+			copy_tv(&HI2DI(hi2)->di_tv, &di1->di_tv);
+		    }
+		}
+	    }
+
+	    copy_tv(&argvars[0], rettv);
+	}
+    }
+    else
+	EMSG2(_(e_listdictarg), "extend()");
+}
+
+/*
+ * "feedkeys()" function
+ */
+/*ARGSUSED*/
+    static void
+f_feedkeys(argvars, rettv)
+    typval_T    *argvars;
+    typval_T    *rettv;
+{
+    int		remap = TRUE;
+    char_u	*keys, *flags;
+    char_u	nbuf[NUMBUFLEN];
+    int		typed = FALSE;
+    char_u	*keys_esc;
+
+    /* This is not allowed in the sandbox.  If the commands would still be
+     * executed in the sandbox it would be OK, but it probably happens later,
+     * when "sandbox" is no longer set. */
+    if (check_secure())
+	return;
+
+    rettv->vval.v_number = 0;
+    keys = get_tv_string(&argvars[0]);
+    if (*keys != NUL)
+    {
+	if (argvars[1].v_type != VAR_UNKNOWN)
+	{
+	    flags = get_tv_string_buf(&argvars[1], nbuf);
+	    for ( ; *flags != NUL; ++flags)
+	    {
+		switch (*flags)
+		{
+		    case 'n': remap = FALSE; break;
+		    case 'm': remap = TRUE; break;
+		    case 't': typed = TRUE; break;
+		}
+	    }
+	}
+
+	/* Need to escape K_SPECIAL and CSI before putting the string in the
+	 * typeahead buffer. */
+	keys_esc = vim_strsave_escape_csi(keys);
+	if (keys_esc != NULL)
+	{
+	    ins_typebuf(keys_esc, (remap ? REMAP_YES : REMAP_NONE),
+					       typebuf.tb_len, !typed, FALSE);
+	    vim_free(keys_esc);
+	    if (vgetc_busy)
+		typebuf_was_filled = TRUE;
+	}
+    }
+}
+
+/*
+ * "filereadable()" function
+ */
+    static void
+f_filereadable(argvars, rettv)
+    typval_T	*argvars;
+    typval_T	*rettv;
+{
+    FILE	*fd;
+    char_u	*p;
+    int		n;
+
+    p = get_tv_string(&argvars[0]);
+    if (*p && !mch_isdir(p) && (fd = mch_fopen((char *)p, "r")) != NULL)
+    {
+	n = TRUE;
+	fclose(fd);
+    }
+    else
+	n = FALSE;
+
+    rettv->vval.v_number = n;
+}
+
+/*
+ * Return 0 for not writable, 1 for writable file, 2 for a dir which we have
+ * rights to write into.
+ */
+    static void
+f_filewritable(argvars, rettv)
+    typval_T	*argvars;
+    typval_T	*rettv;
+{
+    rettv->vval.v_number = filewritable(get_tv_string(&argvars[0]));
+}
+
+static void findfilendir __ARGS((typval_T *argvars, typval_T *rettv, int dir));
+
+    static void
+findfilendir(argvars, rettv, dir)
+    typval_T	*argvars;
+    typval_T	*rettv;
+    int		dir;
+{
+#ifdef FEAT_SEARCHPATH
+    char_u	*fname;
+    char_u	*fresult = NULL;
+    char_u	*path = *curbuf->b_p_path == NUL ? p_path : curbuf->b_p_path;
+    char_u	*p;
+    char_u	pathbuf[NUMBUFLEN];
+    int		count = 1;
+    int		first = TRUE;
+    int		error = FALSE;
+#endif
+
+    rettv->vval.v_string = NULL;
+    rettv->v_type = VAR_STRING;
+
+#ifdef FEAT_SEARCHPATH
+    fname = get_tv_string(&argvars[0]);
+
+    if (argvars[1].v_type != VAR_UNKNOWN)
+    {
+	p = get_tv_string_buf_chk(&argvars[1], pathbuf);
+	if (p == NULL)
+	    error = TRUE;
+	else
+	{
+	    if (*p != NUL)
+		path = p;
+
+	    if (argvars[2].v_type != VAR_UNKNOWN)
+		count = get_tv_number_chk(&argvars[2], &error);
+	}
+    }
+
+    if (count < 0 && rettv_list_alloc(rettv) == FAIL)
+	error = TRUE;
+
+    if (*fname != NUL && !error)
+    {
+	do
+	{
+	    if (rettv->v_type == VAR_STRING)
+		vim_free(fresult);
+	    fresult = find_file_in_path_option(first ? fname : NULL,
+					       first ? (int)STRLEN(fname) : 0,
+					0, first, path, dir, curbuf->b_ffname,
+					dir ? (char_u *)"" : curbuf->b_p_sua);
+	    first = FALSE;
+
+	    if (fresult != NULL && rettv->v_type == VAR_LIST)
+		list_append_string(rettv->vval.v_list, fresult, -1);
+
+	} while ((rettv->v_type == VAR_LIST || --count > 0) && fresult != NULL);
+    }
+
+    if (rettv->v_type == VAR_STRING)
+	rettv->vval.v_string = fresult;
+#endif
+}
+
+static void filter_map __ARGS((typval_T *argvars, typval_T *rettv, int map));
+static int filter_map_one __ARGS((typval_T *tv, char_u *expr, int map, int *remp));
+
+/*
+ * Implementation of map() and filter().
+ */
+    static void
+filter_map(argvars, rettv, map)
+    typval_T	*argvars;
+    typval_T	*rettv;
+    int		map;
+{
+    char_u	buf[NUMBUFLEN];
+    char_u	*expr;
+    listitem_T	*li, *nli;
+    list_T	*l = NULL;
+    dictitem_T	*di;
+    hashtab_T	*ht;
+    hashitem_T	*hi;
+    dict_T	*d = NULL;
+    typval_T	save_val;
+    typval_T	save_key;
+    int		rem;
+    int		todo;
+    char_u	*ermsg = map ? (char_u *)"map()" : (char_u *)"filter()";
+    int		save_did_emsg;
+
+    rettv->vval.v_number = 0;
+    if (argvars[0].v_type == VAR_LIST)
+    {
+	if ((l = argvars[0].vval.v_list) == NULL
+		|| (map && tv_check_lock(l->lv_lock, ermsg)))
+	    return;
+    }
+    else if (argvars[0].v_type == VAR_DICT)
+    {
+	if ((d = argvars[0].vval.v_dict) == NULL
+		|| (map && tv_check_lock(d->dv_lock, ermsg)))
+	    return;
+    }
+    else
+    {
+	EMSG2(_(e_listdictarg), ermsg);
+	return;
+    }
+
+    expr = get_tv_string_buf_chk(&argvars[1], buf);
+    /* On type errors, the preceding call has already displayed an error
+     * message.  Avoid a misleading error message for an empty string that
+     * was not passed as argument. */
+    if (expr != NULL)
+    {
+	prepare_vimvar(VV_VAL, &save_val);
+	expr = skipwhite(expr);
+
+	/* We reset "did_emsg" to be able to detect whether an error
+	 * occurred during evaluation of the expression. */
+	save_did_emsg = did_emsg;
+	did_emsg = FALSE;
+
+	if (argvars[0].v_type == VAR_DICT)
+	{
+	    prepare_vimvar(VV_KEY, &save_key);
+	    vimvars[VV_KEY].vv_type = VAR_STRING;
+
+	    ht = &d->dv_hashtab;
+	    hash_lock(ht);
+	    todo = (int)ht->ht_used;
+	    for (hi = ht->ht_array; todo > 0; ++hi)
+	    {
+		if (!HASHITEM_EMPTY(hi))
+		{
+		    --todo;
+		    di = HI2DI(hi);
+		    if (tv_check_lock(di->di_tv.v_lock, ermsg))
+			break;
+		    vimvars[VV_KEY].vv_str = vim_strsave(di->di_key);
+		    if (filter_map_one(&di->di_tv, expr, map, &rem) == FAIL
+								  || did_emsg)
+			break;
+		    if (!map && rem)
+			dictitem_remove(d, di);
+		    clear_tv(&vimvars[VV_KEY].vv_tv);
+		}
+	    }
+	    hash_unlock(ht);
+
+	    restore_vimvar(VV_KEY, &save_key);
+	}
+	else
+	{
+	    for (li = l->lv_first; li != NULL; li = nli)
+	    {
+		if (tv_check_lock(li->li_tv.v_lock, ermsg))
+		    break;
+		nli = li->li_next;
+		if (filter_map_one(&li->li_tv, expr, map, &rem) == FAIL
+								  || did_emsg)
+		    break;
+		if (!map && rem)
+		    listitem_remove(l, li);
+	    }
+	}
+
+	restore_vimvar(VV_VAL, &save_val);
+
+	did_emsg |= save_did_emsg;
+    }
+
+    copy_tv(&argvars[0], rettv);
+}
+
+    static int
+filter_map_one(tv, expr, map, remp)
+    typval_T	*tv;
+    char_u	*expr;
+    int		map;
+    int		*remp;
+{
+    typval_T	rettv;
+    char_u	*s;
+
+    copy_tv(tv, &vimvars[VV_VAL].vv_tv);
+    s = expr;
+    if (eval1(&s, &rettv, TRUE) == FAIL)
+	return FAIL;
+    if (*s != NUL)  /* check for trailing chars after expr */
+    {
+	EMSG2(_(e_invexpr2), s);
+	return FAIL;
+    }
+    if (map)
+    {
+	/* map(): replace the list item value */
+	clear_tv(tv);
+	rettv.v_lock = 0;
+	*tv = rettv;
+    }
+    else
+    {
+	int	    error = FALSE;
+
+	/* filter(): when expr is zero remove the item */
+	*remp = (get_tv_number_chk(&rettv, &error) == 0);
+	clear_tv(&rettv);
+	/* On type error, nothing has been removed; return FAIL to stop the
+	 * loop.  The error message was given by get_tv_number_chk(). */
+	if (error)
+	    return FAIL;
+    }
+    clear_tv(&vimvars[VV_VAL].vv_tv);
+    return OK;
+}
+
+/*
+ * "filter()" function
+ */
+    static void
+f_filter(argvars, rettv)
+    typval_T	*argvars;
+    typval_T	*rettv;
+{
+    filter_map(argvars, rettv, FALSE);
+}
+
+/*
+ * "finddir({fname}[, {path}[, {count}]])" function
+ */
+    static void
+f_finddir(argvars, rettv)
+    typval_T	*argvars;
+    typval_T	*rettv;
+{
+    findfilendir(argvars, rettv, TRUE);
+}
+
+/*
+ * "findfile({fname}[, {path}[, {count}]])" function
+ */
+    static void
+f_findfile(argvars, rettv)
+    typval_T	*argvars;
+    typval_T	*rettv;
+{
+    findfilendir(argvars, rettv, FALSE);
+}
+
+/*
+ * "fnamemodify({fname}, {mods})" function
+ */
+    static void
+f_fnamemodify(argvars, rettv)
+    typval_T	*argvars;
+    typval_T	*rettv;
+{
+    char_u	*fname;
+    char_u	*mods;
+    int		usedlen = 0;
+    int		len;
+    char_u	*fbuf = NULL;
+    char_u	buf[NUMBUFLEN];
+
+    fname = get_tv_string_chk(&argvars[0]);
+    mods = get_tv_string_buf_chk(&argvars[1], buf);
+    if (fname == NULL || mods == NULL)
+	fname = NULL;
+    else
+    {
+	len = (int)STRLEN(fname);
+	(void)modify_fname(mods, &usedlen, &fname, &fbuf, &len);
+    }
+
+    rettv->v_type = VAR_STRING;
+    if (fname == NULL)
+	rettv->vval.v_string = NULL;
+    else
+	rettv->vval.v_string = vim_strnsave(fname, len);
+    vim_free(fbuf);
+}
+
+static void foldclosed_both __ARGS((typval_T *argvars, typval_T *rettv, int end));
+
+/*
+ * "foldclosed()" function
+ */
+    static void
+foldclosed_both(argvars, rettv, end)
+    typval_T	*argvars;
+    typval_T	*rettv;
+    int		end;
+{
+#ifdef FEAT_FOLDING
+    linenr_T	lnum;
+    linenr_T	first, last;
+
+    lnum = get_tv_lnum(argvars);
+    if (lnum >= 1 && lnum <= curbuf->b_ml.ml_line_count)
+    {
+	if (hasFoldingWin(curwin, lnum, &first, &last, FALSE, NULL))
+	{
+	    if (end)
+		rettv->vval.v_number = (varnumber_T)last;
+	    else
+		rettv->vval.v_number = (varnumber_T)first;
+	    return;
+	}
+    }
+#endif
+    rettv->vval.v_number = -1;
+}
+
+/*
+ * "foldclosed()" function
+ */
+    static void
+f_foldclosed(argvars, rettv)
+    typval_T	*argvars;
+    typval_T	*rettv;
+{
+    foldclosed_both(argvars, rettv, FALSE);
+}
+
+/*
+ * "foldclosedend()" function
+ */
+    static void
+f_foldclosedend(argvars, rettv)
+    typval_T	*argvars;
+    typval_T	*rettv;
+{
+    foldclosed_both(argvars, rettv, TRUE);
+}
+
+/*
+ * "foldlevel()" function
+ */
+    static void
+f_foldlevel(argvars, rettv)
+    typval_T	*argvars;
+    typval_T	*rettv;
+{
+#ifdef FEAT_FOLDING
+    linenr_T	lnum;
+
+    lnum = get_tv_lnum(argvars);
+    if (lnum >= 1 && lnum <= curbuf->b_ml.ml_line_count)
+	rettv->vval.v_number = foldLevel(lnum);
+    else
+#endif
+	rettv->vval.v_number = 0;
+}
+
+/*
+ * "foldtext()" function
+ */
+/*ARGSUSED*/
+    static void
+f_foldtext(argvars, rettv)
+    typval_T	*argvars;
+    typval_T	*rettv;
+{
+#ifdef FEAT_FOLDING
+    linenr_T	lnum;
+    char_u	*s;
+    char_u	*r;
+    int		len;
+    char	*txt;
+#endif
+
+    rettv->v_type = VAR_STRING;
+    rettv->vval.v_string = NULL;
+#ifdef FEAT_FOLDING
+    if ((linenr_T)vimvars[VV_FOLDSTART].vv_nr > 0
+	    && (linenr_T)vimvars[VV_FOLDEND].vv_nr
+						 <= curbuf->b_ml.ml_line_count
+	    && vimvars[VV_FOLDDASHES].vv_str != NULL)
+    {
+	/* Find first non-empty line in the fold. */
+	lnum = (linenr_T)vimvars[VV_FOLDSTART].vv_nr;
+	while (lnum < (linenr_T)vimvars[VV_FOLDEND].vv_nr)
+	{
+	    if (!linewhite(lnum))
+		break;
+	    ++lnum;
+	}
+
+	/* Find interesting text in this line. */
+	s = skipwhite(ml_get(lnum));
+	/* skip C comment-start */
+	if (s[0] == '/' && (s[1] == '*' || s[1] == '/'))
+	{
+	    s = skipwhite(s + 2);
+	    if (*skipwhite(s) == NUL
+			    && lnum + 1 < (linenr_T)vimvars[VV_FOLDEND].vv_nr)
+	    {
+		s = skipwhite(ml_get(lnum + 1));
+		if (*s == '*')
+		    s = skipwhite(s + 1);
+	    }
+	}
+	txt = _("+-%s%3ld lines: ");
+	r = alloc((unsigned)(STRLEN(txt)
+		    + STRLEN(vimvars[VV_FOLDDASHES].vv_str)    /* for %s */
+		    + 20				    /* for %3ld */
+		    + STRLEN(s)));			    /* concatenated */
+	if (r != NULL)
+	{
+	    sprintf((char *)r, txt, vimvars[VV_FOLDDASHES].vv_str,
+		    (long)((linenr_T)vimvars[VV_FOLDEND].vv_nr
+				- (linenr_T)vimvars[VV_FOLDSTART].vv_nr + 1));
+	    len = (int)STRLEN(r);
+	    STRCAT(r, s);
+	    /* remove 'foldmarker' and 'commentstring' */
+	    foldtext_cleanup(r + len);
+	    rettv->vval.v_string = r;
+	}
+    }
+#endif
+}
+
+/*
+ * "foldtextresult(lnum)" function
+ */
+/*ARGSUSED*/
+    static void
+f_foldtextresult(argvars, rettv)
+    typval_T	*argvars;
+    typval_T	*rettv;
+{
+#ifdef FEAT_FOLDING
+    linenr_T	lnum;
+    char_u	*text;
+    char_u	buf[51];
+    foldinfo_T  foldinfo;
+    int		fold_count;
+#endif
+
+    rettv->v_type = VAR_STRING;
+    rettv->vval.v_string = NULL;
+#ifdef FEAT_FOLDING
+    lnum = get_tv_lnum(argvars);
+    /* treat illegal types and illegal string values for {lnum} the same */
+    if (lnum < 0)
+	lnum = 0;
+    fold_count = foldedCount(curwin, lnum, &foldinfo);
+    if (fold_count > 0)
+    {
+	text = get_foldtext(curwin, lnum, lnum + fold_count - 1,
+							      &foldinfo, buf);
+	if (text == buf)
+	    text = vim_strsave(text);
+	rettv->vval.v_string = text;
+    }
+#endif
+}
+
+/*
+ * "foreground()" function
+ */
+/*ARGSUSED*/
+    static void
+f_foreground(argvars, rettv)
+    typval_T	*argvars;
+    typval_T	*rettv;
+{
+    rettv->vval.v_number = 0;
+#ifdef FEAT_GUI
+    if (gui.in_use)
+	gui_mch_set_foreground();
+#else
+# ifdef WIN32
+    win32_set_foreground();
+# endif
+#endif
+}
+
+/*
+ * "function()" function
+ */
+/*ARGSUSED*/
+    static void
+f_function(argvars, rettv)
+    typval_T	*argvars;
+    typval_T	*rettv;
+{
+    char_u	*s;
+
+    rettv->vval.v_number = 0;
+    s = get_tv_string(&argvars[0]);
+    if (s == NULL || *s == NUL || VIM_ISDIGIT(*s))
+	EMSG2(_(e_invarg2), s);
+    else if (!function_exists(s))
+	EMSG2(_("E700: Unknown function: %s"), s);
+    else
+    {
+	rettv->vval.v_string = vim_strsave(s);
+	rettv->v_type = VAR_FUNC;
+    }
+}
+
+/*
+ * "garbagecollect()" function
+ */
+/*ARGSUSED*/
+    static void
+f_garbagecollect(argvars, rettv)
+    typval_T	*argvars;
+    typval_T	*rettv;
+{
+    /* This is postponed until we are back at the toplevel, because we may be
+     * using Lists and Dicts internally.  E.g.: ":echo [garbagecollect()]". */
+    want_garbage_collect = TRUE;
+}
+
+/*
+ * "get()" function
+ */
+    static void
+f_get(argvars, rettv)
+    typval_T	*argvars;
+    typval_T	*rettv;
+{
+    listitem_T	*li;
+    list_T	*l;
+    dictitem_T	*di;
+    dict_T	*d;
+    typval_T	*tv = NULL;
+
+    if (argvars[0].v_type == VAR_LIST)
+    {
+	if ((l = argvars[0].vval.v_list) != NULL)
+	{
+	    int		error = FALSE;
+
+	    li = list_find(l, get_tv_number_chk(&argvars[1], &error));
+	    if (!error && li != NULL)
+		tv = &li->li_tv;
+	}
+    }
+    else if (argvars[0].v_type == VAR_DICT)
+    {
+	if ((d = argvars[0].vval.v_dict) != NULL)
+	{
+	    di = dict_find(d, get_tv_string(&argvars[1]), -1);
+	    if (di != NULL)
+		tv = &di->di_tv;
+	}
+    }
+    else
+	EMSG2(_(e_listdictarg), "get()");
+
+    if (tv == NULL)
+    {
+	if (argvars[2].v_type == VAR_UNKNOWN)
+	    rettv->vval.v_number = 0;
+	else
+	    copy_tv(&argvars[2], rettv);
+    }
+    else
+	copy_tv(tv, rettv);
+}
+
+static void get_buffer_lines __ARGS((buf_T *buf, linenr_T start, linenr_T end, int retlist, typval_T *rettv));
+
+/*
+ * Get line or list of lines from buffer "buf" into "rettv".
+ * Return a range (from start to end) of lines in rettv from the specified
+ * buffer.
+ * If 'retlist' is TRUE, then the lines are returned as a Vim List.
+ */
+    static void
+get_buffer_lines(buf, start, end, retlist, rettv)
+    buf_T	*buf;
+    linenr_T	start;
+    linenr_T	end;
+    int		retlist;
+    typval_T	*rettv;
+{
+    char_u	*p;
+
+    if (retlist)
+    {
+	if (rettv_list_alloc(rettv) == FAIL)
+	    return;
+    }
+    else
+	rettv->vval.v_number = 0;
+
+    if (buf == NULL || buf->b_ml.ml_mfp == NULL || start < 0)
+	return;
+
+    if (!retlist)
+    {
+	if (start >= 1 && start <= buf->b_ml.ml_line_count)
+	    p = ml_get_buf(buf, start, FALSE);
+	else
+	    p = (char_u *)"";
+
+	rettv->v_type = VAR_STRING;
+	rettv->vval.v_string = vim_strsave(p);
+    }
+    else
+    {
+	if (end < start)
+	    return;
+
+	if (start < 1)
+	    start = 1;
+	if (end > buf->b_ml.ml_line_count)
+	    end = buf->b_ml.ml_line_count;
+	while (start <= end)
+	    if (list_append_string(rettv->vval.v_list,
+				 ml_get_buf(buf, start++, FALSE), -1) == FAIL)
+		break;
+    }
+}
+
+/*
+ * "getbufline()" function
+ */
+    static void
+f_getbufline(argvars, rettv)
+    typval_T	*argvars;
+    typval_T	*rettv;
+{
+    linenr_T	lnum;
+    linenr_T	end;
+    buf_T	*buf;
+
+    (void)get_tv_number(&argvars[0]);	    /* issue errmsg if type error */
+    ++emsg_off;
+    buf = get_buf_tv(&argvars[0]);
+    --emsg_off;
+
+    lnum = get_tv_lnum_buf(&argvars[1], buf);
+    if (argvars[2].v_type == VAR_UNKNOWN)
+	end = lnum;
+    else
+	end = get_tv_lnum_buf(&argvars[2], buf);
+
+    get_buffer_lines(buf, lnum, end, TRUE, rettv);
+}
+
+/*
+ * "getbufvar()" function
+ */
+    static void
+f_getbufvar(argvars, rettv)
+    typval_T	*argvars;
+    typval_T	*rettv;
+{
+    buf_T	*buf;
+    buf_T	*save_curbuf;
+    char_u	*varname;
+    dictitem_T	*v;
+
+    (void)get_tv_number(&argvars[0]);	    /* issue errmsg if type error */
+    varname = get_tv_string_chk(&argvars[1]);
+    ++emsg_off;
+    buf = get_buf_tv(&argvars[0]);
+
+    rettv->v_type = VAR_STRING;
+    rettv->vval.v_string = NULL;
+
+    if (buf != NULL && varname != NULL)
+    {
+	if (*varname == '&')	/* buffer-local-option */
+	{
+	    /* set curbuf to be our buf, temporarily */
+	    save_curbuf = curbuf;
+	    curbuf = buf;
+
+	    get_option_tv(&varname, rettv, TRUE);
+
+	    /* restore previous notion of curbuf */
+	    curbuf = save_curbuf;
+	}
+	else
+	{
+	    if (*varname == NUL)
+		/* let getbufvar({nr}, "") return the "b:" dictionary.  The
+		 * scope prefix before the NUL byte is required by
+		 * find_var_in_ht(). */
+		varname = (char_u *)"b:" + 2;
+	    /* look up the variable */
+	    v = find_var_in_ht(&buf->b_vars.dv_hashtab, varname, FALSE);
+	    if (v != NULL)
+		copy_tv(&v->di_tv, rettv);
+	}
+    }
+
+    --emsg_off;
+}
+
+/*
+ * "getchar()" function
+ */
+    static void
+f_getchar(argvars, rettv)
+    typval_T	*argvars;
+    typval_T	*rettv;
+{
+    varnumber_T		n;
+    int			error = FALSE;
+
+    /* Position the cursor.  Needed after a message that ends in a space. */
+    windgoto(msg_row, msg_col);
+
+    ++no_mapping;
+    ++allow_keys;
+    if (argvars[0].v_type == VAR_UNKNOWN)
+	/* getchar(): blocking wait. */
+	n = safe_vgetc();
+    else if (get_tv_number_chk(&argvars[0], &error) == 1)
+	/* getchar(1): only check if char avail */
+	n = vpeekc();
+    else if (error || vpeekc() == NUL)
+	/* illegal argument or getchar(0) and no char avail: return zero */
+	n = 0;
+    else
+	/* getchar(0) and char avail: return char */
+	n = safe_vgetc();
+    --no_mapping;
+    --allow_keys;
+
+    vimvars[VV_MOUSE_WIN].vv_nr = 0;
+    vimvars[VV_MOUSE_LNUM].vv_nr = 0;
+    vimvars[VV_MOUSE_COL].vv_nr = 0;
+
+    rettv->vval.v_number = n;
+    if (IS_SPECIAL(n) || mod_mask != 0)
+    {
+	char_u		temp[10];   /* modifier: 3, mbyte-char: 6, NUL: 1 */
+	int		i = 0;
+
+	/* Turn a special key into three bytes, plus modifier. */
+	if (mod_mask != 0)
+	{
+	    temp[i++] = K_SPECIAL;
+	    temp[i++] = KS_MODIFIER;
+	    temp[i++] = mod_mask;
+	}
+	if (IS_SPECIAL(n))
+	{
+	    temp[i++] = K_SPECIAL;
+	    temp[i++] = K_SECOND(n);
+	    temp[i++] = K_THIRD(n);
+	}
+#ifdef FEAT_MBYTE
+	else if (has_mbyte)
+	    i += (*mb_char2bytes)(n, temp + i);
+#endif
+	else
+	    temp[i++] = n;
+	temp[i++] = NUL;
+	rettv->v_type = VAR_STRING;
+	rettv->vval.v_string = vim_strsave(temp);
+
+#ifdef FEAT_MOUSE
+	if (n == K_LEFTMOUSE
+		|| n == K_LEFTMOUSE_NM
+		|| n == K_LEFTDRAG
+		|| n == K_LEFTRELEASE
+		|| n == K_LEFTRELEASE_NM
+		|| n == K_MIDDLEMOUSE
+		|| n == K_MIDDLEDRAG
+		|| n == K_MIDDLERELEASE
+		|| n == K_RIGHTMOUSE
+		|| n == K_RIGHTDRAG
+		|| n == K_RIGHTRELEASE
+		|| n == K_X1MOUSE
+		|| n == K_X1DRAG
+		|| n == K_X1RELEASE
+		|| n == K_X2MOUSE
+		|| n == K_X2DRAG
+		|| n == K_X2RELEASE
+		|| n == K_MOUSEDOWN
+		|| n == K_MOUSEUP)
+	{
+	    int		row = mouse_row;
+	    int		col = mouse_col;
+	    win_T	*win;
+	    linenr_T	lnum;
+# ifdef FEAT_WINDOWS
+	    win_T	*wp;
+# endif
+	    int		n = 1;
+
+	    if (row >= 0 && col >= 0)
+	    {
+		/* Find the window at the mouse coordinates and compute the
+		 * text position. */
+		win = mouse_find_win(&row, &col);
+		(void)mouse_comp_pos(win, &row, &col, &lnum);
+# ifdef FEAT_WINDOWS
+		for (wp = firstwin; wp != win; wp = wp->w_next)
+		    ++n;
+# endif
+		vimvars[VV_MOUSE_WIN].vv_nr = n;
+		vimvars[VV_MOUSE_LNUM].vv_nr = lnum;
+		vimvars[VV_MOUSE_COL].vv_nr = col + 1;
+	    }
+	}
+#endif
+    }
+}
+
+/*
+ * "getcharmod()" function
+ */
+/*ARGSUSED*/
+    static void
+f_getcharmod(argvars, rettv)
+    typval_T	*argvars;
+    typval_T	*rettv;
+{
+    rettv->vval.v_number = mod_mask;
+}
+
+/*
+ * "getcmdline()" function
+ */
+/*ARGSUSED*/
+    static void
+f_getcmdline(argvars, rettv)
+    typval_T	*argvars;
+    typval_T	*rettv;
+{
+    rettv->v_type = VAR_STRING;
+    rettv->vval.v_string = get_cmdline_str();
+}
+
+/*
+ * "getcmdpos()" function
+ */
+/*ARGSUSED*/
+    static void
+f_getcmdpos(argvars, rettv)
+    typval_T	*argvars;
+    typval_T	*rettv;
+{
+    rettv->vval.v_number = get_cmdline_pos() + 1;
+}
+
+/*
+ * "getcmdtype()" function
+ */
+/*ARGSUSED*/
+    static void
+f_getcmdtype(argvars, rettv)
+    typval_T	*argvars;
+    typval_T	*rettv;
+{
+    rettv->v_type = VAR_STRING;
+    rettv->vval.v_string = alloc(2);
+    if (rettv->vval.v_string != NULL)
+    {
+	rettv->vval.v_string[0] = get_cmdline_type();
+	rettv->vval.v_string[1] = NUL;
+    }
+}
+
+/*
+ * "getcwd()" function
+ */
+/*ARGSUSED*/
+    static void
+f_getcwd(argvars, rettv)
+    typval_T	*argvars;
+    typval_T	*rettv;
+{
+    char_u	cwd[MAXPATHL];
+
+    rettv->v_type = VAR_STRING;
+    if (mch_dirname(cwd, MAXPATHL) == FAIL)
+	rettv->vval.v_string = NULL;
+    else
+    {
+	rettv->vval.v_string = vim_strsave(cwd);
+#ifdef BACKSLASH_IN_FILENAME
+	if (rettv->vval.v_string != NULL)
+	    slash_adjust(rettv->vval.v_string);
+#endif
+    }
+}
+
+/*
+ * "getfontname()" function
+ */
+/*ARGSUSED*/
+    static void
+f_getfontname(argvars, rettv)
+    typval_T	*argvars;
+    typval_T	*rettv;
+{
+    rettv->v_type = VAR_STRING;
+    rettv->vval.v_string = NULL;
+#ifdef FEAT_GUI
+    if (gui.in_use)
+    {
+	GuiFont font;
+	char_u	*name = NULL;
+
+	if (argvars[0].v_type == VAR_UNKNOWN)
+	{
+	    /* Get the "Normal" font.  Either the name saved by
+	     * hl_set_font_name() or from the font ID. */
+	    font = gui.norm_font;
+	    name = hl_get_font_name();
+	}
+	else
+	{
+	    name = get_tv_string(&argvars[0]);
+	    if (STRCMP(name, "*") == 0)	    /* don't use font dialog */
+		return;
+	    font = gui_mch_get_font(name, FALSE);
+	    if (font == NOFONT)
+		return;	    /* Invalid font name, return empty string. */
+	}
+	rettv->vval.v_string = gui_mch_get_fontname(font, name);
+	if (argvars[0].v_type != VAR_UNKNOWN)
+	    gui_mch_free_font(font);
+    }
+#endif
+}
+
+/*
+ * "getfperm({fname})" function
+ */
+    static void
+f_getfperm(argvars, rettv)
+    typval_T	*argvars;
+    typval_T	*rettv;
+{
+    char_u	*fname;
+    struct stat st;
+    char_u	*perm = NULL;
+    char_u	flags[] = "rwx";
+    int		i;
+
+    fname = get_tv_string(&argvars[0]);
+
+    rettv->v_type = VAR_STRING;
+    if (mch_stat((char *)fname, &st) >= 0)
+    {
+	perm = vim_strsave((char_u *)"---------");
+	if (perm != NULL)
+	{
+	    for (i = 0; i < 9; i++)
+	    {
+		if (st.st_mode & (1 << (8 - i)))
+		    perm[i] = flags[i % 3];
+	    }
+	}
+    }
+    rettv->vval.v_string = perm;
+}
+
+/*
+ * "getfsize({fname})" function
+ */
+    static void
+f_getfsize(argvars, rettv)
+    typval_T	*argvars;
+    typval_T	*rettv;
+{
+    char_u	*fname;
+    struct stat	st;
+
+    fname = get_tv_string(&argvars[0]);
+
+    rettv->v_type = VAR_NUMBER;
+
+    if (mch_stat((char *)fname, &st) >= 0)
+    {
+	if (mch_isdir(fname))
+	    rettv->vval.v_number = 0;
+	else
+	    rettv->vval.v_number = (varnumber_T)st.st_size;
+    }
+    else
+	  rettv->vval.v_number = -1;
+}
+
+/*
+ * "getftime({fname})" function
+ */
+    static void
+f_getftime(argvars, rettv)
+    typval_T	*argvars;
+    typval_T	*rettv;
+{
+    char_u	*fname;
+    struct stat	st;
+
+    fname = get_tv_string(&argvars[0]);
+
+    if (mch_stat((char *)fname, &st) >= 0)
+	rettv->vval.v_number = (varnumber_T)st.st_mtime;
+    else
+	rettv->vval.v_number = -1;
+}
+
+/*
+ * "getftype({fname})" function
+ */
+    static void
+f_getftype(argvars, rettv)
+    typval_T	*argvars;
+    typval_T	*rettv;
+{
+    char_u	*fname;
+    struct stat st;
+    char_u	*type = NULL;
+    char	*t;
+
+    fname = get_tv_string(&argvars[0]);
+
+    rettv->v_type = VAR_STRING;
+    if (mch_lstat((char *)fname, &st) >= 0)
+    {
+#ifdef S_ISREG
+	if (S_ISREG(st.st_mode))
+	    t = "file";
+	else if (S_ISDIR(st.st_mode))
+	    t = "dir";
+# ifdef S_ISLNK
+	else if (S_ISLNK(st.st_mode))
+	    t = "link";
+# endif
+# ifdef S_ISBLK
+	else if (S_ISBLK(st.st_mode))
+	    t = "bdev";
+# endif
+# ifdef S_ISCHR
+	else if (S_ISCHR(st.st_mode))
+	    t = "cdev";
+# endif
+# ifdef S_ISFIFO
+	else if (S_ISFIFO(st.st_mode))
+	    t = "fifo";
+# endif
+# ifdef S_ISSOCK
+	else if (S_ISSOCK(st.st_mode))
+	    t = "fifo";
+# endif
+	else
+	    t = "other";
+#else
+# ifdef S_IFMT
+	switch (st.st_mode & S_IFMT)
+	{
+	    case S_IFREG: t = "file"; break;
+	    case S_IFDIR: t = "dir"; break;
+#  ifdef S_IFLNK
+	    case S_IFLNK: t = "link"; break;
+#  endif
+#  ifdef S_IFBLK
+	    case S_IFBLK: t = "bdev"; break;
+#  endif
+#  ifdef S_IFCHR
+	    case S_IFCHR: t = "cdev"; break;
+#  endif
+#  ifdef S_IFIFO
+	    case S_IFIFO: t = "fifo"; break;
+#  endif
+#  ifdef S_IFSOCK
+	    case S_IFSOCK: t = "socket"; break;
+#  endif
+	    default: t = "other";
+	}
+# else
+	if (mch_isdir(fname))
+	    t = "dir";
+	else
+	    t = "file";
+# endif
+#endif
+	type = vim_strsave((char_u *)t);
+    }
+    rettv->vval.v_string = type;
+}
+
+/*
+ * "getline(lnum, [end])" function
+ */
+    static void
+f_getline(argvars, rettv)
+    typval_T	*argvars;
+    typval_T	*rettv;
+{
+    linenr_T	lnum;
+    linenr_T	end;
+    int		retlist;
+
+    lnum = get_tv_lnum(argvars);
+    if (argvars[1].v_type == VAR_UNKNOWN)
+    {
+	end = 0;
+	retlist = FALSE;
+    }
+    else
+    {
+	end = get_tv_lnum(&argvars[1]);
+	retlist = TRUE;
+    }
+
+    get_buffer_lines(curbuf, lnum, end, retlist, rettv);
+}
+
+/*
+ * "getpos(string)" function
+ */
+    static void
+f_getpos(argvars, rettv)
+    typval_T	*argvars;
+    typval_T	*rettv;
+{
+    pos_T	*fp;
+    list_T	*l;
+    int		fnum = -1;
+
+    if (rettv_list_alloc(rettv) == OK)
+    {
+	l = rettv->vval.v_list;
+	fp = var2fpos(&argvars[0], TRUE, &fnum);
+	if (fnum != -1)
+	    list_append_number(l, (varnumber_T)fnum);
+	else
+	    list_append_number(l, (varnumber_T)0);
+	list_append_number(l, (fp != NULL) ? (varnumber_T)fp->lnum
+							    : (varnumber_T)0);
+	list_append_number(l, (fp != NULL) ? (varnumber_T)fp->col + 1
+							    : (varnumber_T)0);
+	list_append_number(l,
+#ifdef FEAT_VIRTUALEDIT
+				(fp != NULL) ? (varnumber_T)fp->coladd :
+#endif
+							      (varnumber_T)0);
+    }
+    else
+	rettv->vval.v_number = FALSE;
+}
+
+/*
+ * "getqflist()" and "getloclist()" functions
+ */
+/*ARGSUSED*/
+    static void
+f_getqflist(argvars, rettv)
+    typval_T	*argvars;
+    typval_T	*rettv;
+{
+#ifdef FEAT_QUICKFIX
+    win_T	*wp;
+#endif
+
+    rettv->vval.v_number = 0;
+#ifdef FEAT_QUICKFIX
+    if (rettv_list_alloc(rettv) == OK)
+    {
+	wp = NULL;
+	if (argvars[0].v_type != VAR_UNKNOWN)	/* getloclist() */
+	{
+	    wp = find_win_by_nr(&argvars[0], NULL);
+	    if (wp == NULL)
+		return;
+	}
+
+	(void)get_errorlist(wp, rettv->vval.v_list);
+    }
+#endif
+}
+
+/*
+ * "getreg()" function
+ */
+    static void
+f_getreg(argvars, rettv)
+    typval_T	*argvars;
+    typval_T	*rettv;
+{
+    char_u	*strregname;
+    int		regname;
+    int		arg2 = FALSE;
+    int		error = FALSE;
+
+    if (argvars[0].v_type != VAR_UNKNOWN)
+    {
+	strregname = get_tv_string_chk(&argvars[0]);
+	error = strregname == NULL;
+	if (argvars[1].v_type != VAR_UNKNOWN)
+	    arg2 = get_tv_number_chk(&argvars[1], &error);
+    }
+    else
+	strregname = vimvars[VV_REG].vv_str;
+    regname = (strregname == NULL ? '"' : *strregname);
+    if (regname == 0)
+	regname = '"';
+
+    rettv->v_type = VAR_STRING;
+    rettv->vval.v_string = error ? NULL :
+				    get_reg_contents(regname, TRUE, arg2);
+}
+
+/*
+ * "getregtype()" function
+ */
+    static void
+f_getregtype(argvars, rettv)
+    typval_T	*argvars;
+    typval_T	*rettv;
+{
+    char_u	*strregname;
+    int		regname;
+    char_u	buf[NUMBUFLEN + 2];
+    long	reglen = 0;
+
+    if (argvars[0].v_type != VAR_UNKNOWN)
+    {
+	strregname = get_tv_string_chk(&argvars[0]);
+	if (strregname == NULL)	    /* type error; errmsg already given */
+	{
+	    rettv->v_type = VAR_STRING;
+	    rettv->vval.v_string = NULL;
+	    return;
+	}
+    }
+    else
+	/* Default to v:register */
+	strregname = vimvars[VV_REG].vv_str;
+
+    regname = (strregname == NULL ? '"' : *strregname);
+    if (regname == 0)
+	regname = '"';
+
+    buf[0] = NUL;
+    buf[1] = NUL;
+    switch (get_reg_type(regname, &reglen))
+    {
+	case MLINE: buf[0] = 'V'; break;
+	case MCHAR: buf[0] = 'v'; break;
+#ifdef FEAT_VISUAL
+	case MBLOCK:
+		buf[0] = Ctrl_V;
+		sprintf((char *)buf + 1, "%ld", reglen + 1);
+		break;
+#endif
+    }
+    rettv->v_type = VAR_STRING;
+    rettv->vval.v_string = vim_strsave(buf);
+}
+
+/*
+ * "gettabwinvar()" function
+ */
+    static void
+f_gettabwinvar(argvars, rettv)
+    typval_T	*argvars;
+    typval_T	*rettv;
+{
+    getwinvar(argvars, rettv, 1);
+}
+
+/*
+ * "getwinposx()" function
+ */
+/*ARGSUSED*/
+    static void
+f_getwinposx(argvars, rettv)
+    typval_T	*argvars;
+    typval_T	*rettv;
+{
+    rettv->vval.v_number = -1;
+#ifdef FEAT_GUI
+    if (gui.in_use)
+    {
+	int	    x, y;
+
+	if (gui_mch_get_winpos(&x, &y) == OK)
+	    rettv->vval.v_number = x;
+    }
+#endif
+}
+
+/*
+ * "getwinposy()" function
+ */
+/*ARGSUSED*/
+    static void
+f_getwinposy(argvars, rettv)
+    typval_T	*argvars;
+    typval_T	*rettv;
+{
+    rettv->vval.v_number = -1;
+#ifdef FEAT_GUI
+    if (gui.in_use)
+    {
+	int	    x, y;
+
+	if (gui_mch_get_winpos(&x, &y) == OK)
+	    rettv->vval.v_number = y;
+    }
+#endif
+}
+
+/*
+ * Find window specifed by "vp" in tabpage "tp".
+ */
+    static win_T *
+find_win_by_nr(vp, tp)
+    typval_T	*vp;
+    tabpage_T	*tp;	    /* NULL for current tab page */
+{
+#ifdef FEAT_WINDOWS
+    win_T	*wp;
+#endif
+    int		nr;
+
+    nr = get_tv_number_chk(vp, NULL);
+
+#ifdef FEAT_WINDOWS
+    if (nr < 0)
+	return NULL;
+    if (nr == 0)
+	return curwin;
+
+    for (wp = (tp == NULL || tp == curtab) ? firstwin : tp->tp_firstwin;
+						  wp != NULL; wp = wp->w_next)
+	if (--nr <= 0)
+	    break;
+    return wp;
+#else
+    if (nr == 0 || nr == 1)
+	return curwin;
+    return NULL;
+#endif
+}
+
+/*
+ * "getwinvar()" function
+ */
+    static void
+f_getwinvar(argvars, rettv)
+    typval_T	*argvars;
+    typval_T	*rettv;
+{
+    getwinvar(argvars, rettv, 0);
+}
+
+/*
+ * getwinvar() and gettabwinvar()
+ */
+    static void
+getwinvar(argvars, rettv, off)
+    typval_T	*argvars;
+    typval_T	*rettv;
+    int		off;	    /* 1 for gettabwinvar() */
+{
+    win_T	*win, *oldcurwin;
+    char_u	*varname;
+    dictitem_T	*v;
+    tabpage_T	*tp;
+
+#ifdef FEAT_WINDOWS
+    if (off == 1)
+	tp = find_tabpage((int)get_tv_number_chk(&argvars[0], NULL));
+    else
+	tp = curtab;
+#endif
+    win = find_win_by_nr(&argvars[off], tp);
+    varname = get_tv_string_chk(&argvars[off + 1]);
+    ++emsg_off;
+
+    rettv->v_type = VAR_STRING;
+    rettv->vval.v_string = NULL;
+
+    if (win != NULL && varname != NULL)
+    {
+	/* Set curwin to be our win, temporarily.  Also set curbuf, so
+	 * that we can get buffer-local options. */
+	oldcurwin = curwin;
+	curwin = win;
+	curbuf = win->w_buffer;
+
+	if (*varname == '&')	/* window-local-option */
+	    get_option_tv(&varname, rettv, 1);
+	else
+	{
+	    if (*varname == NUL)
+		/* let getwinvar({nr}, "") return the "w:" dictionary.  The
+		 * scope prefix before the NUL byte is required by
+		 * find_var_in_ht(). */
+		varname = (char_u *)"w:" + 2;
+	    /* look up the variable */
+	    v = find_var_in_ht(&win->w_vars.dv_hashtab, varname, FALSE);
+	    if (v != NULL)
+		copy_tv(&v->di_tv, rettv);
+	}
+
+	/* restore previous notion of curwin */
+	curwin = oldcurwin;
+	curbuf = curwin->w_buffer;
+    }
+
+    --emsg_off;
+}
+
+/*
+ * "glob()" function
+ */
+    static void
+f_glob(argvars, rettv)
+    typval_T	*argvars;
+    typval_T	*rettv;
+{
+    expand_T	xpc;
+
+    ExpandInit(&xpc);
+    xpc.xp_context = EXPAND_FILES;
+    rettv->v_type = VAR_STRING;
+    rettv->vval.v_string = ExpandOne(&xpc, get_tv_string(&argvars[0]),
+				     NULL, WILD_USE_NL|WILD_SILENT, WILD_ALL);
+}
+
+/*
+ * "globpath()" function
+ */
+    static void
+f_globpath(argvars, rettv)
+    typval_T	*argvars;
+    typval_T	*rettv;
+{
+    char_u	buf1[NUMBUFLEN];
+    char_u	*file = get_tv_string_buf_chk(&argvars[1], buf1);
+
+    rettv->v_type = VAR_STRING;
+    if (file == NULL)
+	rettv->vval.v_string = NULL;
+    else
+	rettv->vval.v_string = globpath(get_tv_string(&argvars[0]), file);
+}
+
+/*
+ * "has()" function
+ */
+    static void
+f_has(argvars, rettv)
+    typval_T	*argvars;
+    typval_T	*rettv;
+{
+    int		i;
+    char_u	*name;
+    int		n = FALSE;
+    static char	*(has_list[]) =
+    {
+#ifdef AMIGA
+	"amiga",
+# ifdef FEAT_ARP
+	"arp",
+# endif
+#endif
+#ifdef __BEOS__
+	"beos",
+#endif
+#ifdef MSDOS
+# ifdef DJGPP
+	"dos32",
+# else
+	"dos16",
+# endif
+#endif
+#ifdef MACOS
+	"mac",
+#endif
+#if defined(MACOS_X_UNIX)
+	"macunix",
+#endif
+#ifdef OS2
+	"os2",
+#endif
+#ifdef __QNX__
+	"qnx",
+#endif
+#ifdef RISCOS
+	"riscos",
+#endif
+#ifdef UNIX
+	"unix",
+#endif
+#ifdef VMS
+	"vms",
+#endif
+#ifdef WIN16
+	"win16",
+#endif
+#ifdef WIN32
+	"win32",
+#endif
+#if defined(UNIX) && (defined(__CYGWIN32__) || defined(__CYGWIN__))
+	"win32unix",
+#endif
+#ifdef WIN64
+	"win64",
+#endif
+#ifdef EBCDIC
+	"ebcdic",
+#endif
+#ifndef CASE_INSENSITIVE_FILENAME
+	"fname_case",
+#endif
+#ifdef FEAT_ARABIC
+	"arabic",
+#endif
+#ifdef FEAT_AUTOCMD
+	"autocmd",
+#endif
+#ifdef FEAT_BEVAL
+	"balloon_eval",
+# ifndef FEAT_GUI_W32 /* other GUIs always have multiline balloons */
+	"balloon_multiline",
+# endif
+#endif
+#if defined(SOME_BUILTIN_TCAPS) || defined(ALL_BUILTIN_TCAPS)
+	"builtin_terms",
+# ifdef ALL_BUILTIN_TCAPS
+	"all_builtin_terms",
+# endif
+#endif
+#ifdef FEAT_BYTEOFF
+	"byte_offset",
+#endif
+#ifdef FEAT_CINDENT
+	"cindent",
+#endif
+#ifdef FEAT_CLIENTSERVER
+	"clientserver",
+#endif
+#ifdef FEAT_CLIPBOARD
+	"clipboard",
+#endif
+#ifdef FEAT_CMDL_COMPL
+	"cmdline_compl",
+#endif
+#ifdef FEAT_CMDHIST
+	"cmdline_hist",
+#endif
+#ifdef FEAT_COMMENTS
+	"comments",
+#endif
+#ifdef FEAT_CRYPT
+	"cryptv",
+#endif
+#ifdef FEAT_CSCOPE
+	"cscope",
+#endif
+#ifdef CURSOR_SHAPE
+	"cursorshape",
+#endif
+#ifdef DEBUG
+	"debug",
+#endif
+#ifdef FEAT_CON_DIALOG
+	"dialog_con",
+#endif
+#ifdef FEAT_GUI_DIALOG
+	"dialog_gui",
+#endif
+#ifdef FEAT_DIFF
+	"diff",
+#endif
+#ifdef FEAT_DIGRAPHS
+	"digraphs",
+#endif
+#ifdef FEAT_DND
+	"dnd",
+#endif
+#ifdef FEAT_EMACS_TAGS
+	"emacs_tags",
+#endif
+	"eval",	    /* always present, of course! */
+#ifdef FEAT_EX_EXTRA
+	"ex_extra",
+#endif
+#ifdef FEAT_SEARCH_EXTRA
+	"extra_search",
+#endif
+#ifdef FEAT_FKMAP
+	"farsi",
+#endif
+#ifdef FEAT_SEARCHPATH
+	"file_in_path",
+#endif
+#if defined(UNIX) && !defined(USE_SYSTEM)
+	"filterpipe",
+#endif
+#ifdef FEAT_FIND_ID
+	"find_in_path",
+#endif
+#ifdef FEAT_FOLDING
+	"folding",
+#endif
+#ifdef FEAT_FOOTER
+	"footer",
+#endif
+#if !defined(USE_SYSTEM) && defined(UNIX)
+	"fork",
+#endif
+#ifdef FEAT_GETTEXT
+	"gettext",
+#endif
+#ifdef FEAT_GUI
+	"gui",
+#endif
+#ifdef FEAT_GUI_ATHENA
+# ifdef FEAT_GUI_NEXTAW
+	"gui_neXtaw",
+# else
+	"gui_athena",
+# endif
+#endif
+#ifdef FEAT_GUI_GTK
+	"gui_gtk",
+# ifdef HAVE_GTK2
+	"gui_gtk2",
+# endif
+#endif
+#ifdef FEAT_GUI_MAC
+	"gui_mac",
+#endif
+#ifdef FEAT_GUI_MOTIF
+	"gui_motif",
+#endif
+#ifdef FEAT_GUI_PHOTON
+	"gui_photon",
+#endif
+#ifdef FEAT_GUI_W16
+	"gui_win16",
+#endif
+#ifdef FEAT_GUI_W32
+	"gui_win32",
+#endif
+#ifdef FEAT_HANGULIN
+	"hangul_input",
+#endif
+#if defined(HAVE_ICONV_H) && defined(USE_ICONV)
+	"iconv",
+#endif
+#ifdef FEAT_INS_EXPAND
+	"insert_expand",
+#endif
+#ifdef FEAT_JUMPLIST
+	"jumplist",
+#endif
+#ifdef FEAT_KEYMAP
+	"keymap",
+#endif
+#ifdef FEAT_LANGMAP
+	"langmap",
+#endif
+#ifdef FEAT_LIBCALL
+	"libcall",
+#endif
+#ifdef FEAT_LINEBREAK
+	"linebreak",
+#endif
+#ifdef FEAT_LISP
+	"lispindent",
+#endif
+#ifdef FEAT_LISTCMDS
+	"listcmds",
+#endif
+#ifdef FEAT_LOCALMAP
+	"localmap",
+#endif
+#ifdef FEAT_MENU
+	"menu",
+#endif
+#ifdef FEAT_SESSION
+	"mksession",
+#endif
+#ifdef FEAT_MODIFY_FNAME
+	"modify_fname",
+#endif
+#ifdef FEAT_MOUSE
+	"mouse",
+#endif
+#ifdef FEAT_MOUSESHAPE
+	"mouseshape",
+#endif
+#if defined(UNIX) || defined(VMS)
+# ifdef FEAT_MOUSE_DEC
+	"mouse_dec",
+# endif
+# ifdef FEAT_MOUSE_GPM
+	"mouse_gpm",
+# endif
+# ifdef FEAT_MOUSE_JSB
+	"mouse_jsbterm",
+# endif
+# ifdef FEAT_MOUSE_NET
+	"mouse_netterm",
+# endif
+# ifdef FEAT_MOUSE_PTERM
+	"mouse_pterm",
+# endif
+# ifdef FEAT_MOUSE_XTERM
+	"mouse_xterm",
+# endif
+#endif
+#ifdef FEAT_MBYTE
+	"multi_byte",
+#endif
+#ifdef FEAT_MBYTE_IME
+	"multi_byte_ime",
+#endif
+#ifdef FEAT_MULTI_LANG
+	"multi_lang",
+#endif
+#ifdef FEAT_MZSCHEME
+#ifndef DYNAMIC_MZSCHEME
+	"mzscheme",
+#endif
+#endif
+#ifdef FEAT_OLE
+	"ole",
+#endif
+#ifdef FEAT_OSFILETYPE
+	"osfiletype",
+#endif
+#ifdef FEAT_PATH_EXTRA
+	"path_extra",
+#endif
+#ifdef FEAT_PERL
+#ifndef DYNAMIC_PERL
+	"perl",
+#endif
+#endif
+#ifdef FEAT_PYTHON
+#ifndef DYNAMIC_PYTHON
+	"python",
+#endif
+#endif
+#ifdef FEAT_POSTSCRIPT
+	"postscript",
+#endif
+#ifdef FEAT_PRINTER
+	"printer",
+#endif
+#ifdef FEAT_PROFILE
+	"profile",
+#endif
+#ifdef FEAT_RELTIME
+	"reltime",
+#endif
+#ifdef FEAT_QUICKFIX
+	"quickfix",
+#endif
+#ifdef FEAT_RIGHTLEFT
+	"rightleft",
+#endif
+#if defined(FEAT_RUBY) && !defined(DYNAMIC_RUBY)
+	"ruby",
+#endif
+#ifdef FEAT_SCROLLBIND
+	"scrollbind",
+#endif
+#ifdef FEAT_CMDL_INFO
+	"showcmd",
+	"cmdline_info",
+#endif
+#ifdef FEAT_SIGNS
+	"signs",
+#endif
+#ifdef FEAT_SMARTINDENT
+	"smartindent",
+#endif
+#ifdef FEAT_SNIFF
+	"sniff",
+#endif
+#ifdef FEAT_STL_OPT
+	"statusline",
+#endif
+#ifdef FEAT_SUN_WORKSHOP
+	"sun_workshop",
+#endif
+#ifdef FEAT_NETBEANS_INTG
+	"netbeans_intg",
+#endif
+#ifdef FEAT_SPELL
+	"spell",
+#endif
+#ifdef FEAT_SYN_HL
+	"syntax",
+#endif
+#if defined(USE_SYSTEM) || !defined(UNIX)
+	"system",
+#endif
+#ifdef FEAT_TAG_BINS
+	"tag_binary",
+#endif
+#ifdef FEAT_TAG_OLDSTATIC
+	"tag_old_static",
+#endif
+#ifdef FEAT_TAG_ANYWHITE
+	"tag_any_white",
+#endif
+#ifdef FEAT_TCL
+# ifndef DYNAMIC_TCL
+	"tcl",
+# endif
+#endif
+#ifdef TERMINFO
+	"terminfo",
+#endif
+#ifdef FEAT_TERMRESPONSE
+	"termresponse",
+#endif
+#ifdef FEAT_TEXTOBJ
+	"textobjects",
+#endif
+#ifdef HAVE_TGETENT
+	"tgetent",
+#endif
+#ifdef FEAT_TITLE
+	"title",
+#endif
+#ifdef FEAT_TOOLBAR
+	"toolbar",
+#endif
+#ifdef FEAT_USR_CMDS
+	"user-commands",    /* was accidentally included in 5.4 */
+	"user_commands",
+#endif
+#ifdef FEAT_VIMINFO
+	"viminfo",
+#endif
+#ifdef FEAT_VERTSPLIT
+	"vertsplit",
+#endif
+#ifdef FEAT_VIRTUALEDIT
+	"virtualedit",
+#endif
+#ifdef FEAT_VISUAL
+	"visual",
+#endif
+#ifdef FEAT_VISUALEXTRA
+	"visualextra",
+#endif
+#ifdef FEAT_VREPLACE
+	"vreplace",
+#endif
+#ifdef FEAT_WILDIGN
+	"wildignore",
+#endif
+#ifdef FEAT_WILDMENU
+	"wildmenu",
+#endif
+#ifdef FEAT_WINDOWS
+	"windows",
+#endif
+#ifdef FEAT_WAK
+	"winaltkeys",
+#endif
+#ifdef FEAT_WRITEBACKUP
+	"writebackup",
+#endif
+#ifdef FEAT_XIM
+	"xim",
+#endif
+#ifdef FEAT_XFONTSET
+	"xfontset",
+#endif
+#ifdef USE_XSMP
+	"xsmp",
+#endif
+#ifdef USE_XSMP_INTERACT
+	"xsmp_interact",
+#endif
+#ifdef FEAT_XCLIPBOARD
+	"xterm_clipboard",
+#endif
+#ifdef FEAT_XTERM_SAVE
+	"xterm_save",
+#endif
+#if defined(UNIX) && defined(FEAT_X11)
+	"X11",
+#endif
+	NULL
+    };
+
+    name = get_tv_string(&argvars[0]);
+    for (i = 0; has_list[i] != NULL; ++i)
+	if (STRICMP(name, has_list[i]) == 0)
+	{
+	    n = TRUE;
+	    break;
+	}
+
+    if (n == FALSE)
+    {
+	if (STRNICMP(name, "patch", 5) == 0)
+	    n = has_patch(atoi((char *)name + 5));
+	else if (STRICMP(name, "vim_starting") == 0)
+	    n = (starting != 0);
+#if defined(FEAT_BEVAL) && defined(FEAT_GUI_W32)
+	else if (STRICMP(name, "balloon_multiline") == 0)
+	    n = multiline_balloon_available();
+#endif
+#ifdef DYNAMIC_TCL
+	else if (STRICMP(name, "tcl") == 0)
+	    n = tcl_enabled(FALSE);
+#endif
+#if defined(USE_ICONV) && defined(DYNAMIC_ICONV)
+	else if (STRICMP(name, "iconv") == 0)
+	    n = iconv_enabled(FALSE);
+#endif
+#ifdef DYNAMIC_MZSCHEME
+	else if (STRICMP(name, "mzscheme") == 0)
+	    n = mzscheme_enabled(FALSE);
+#endif
+#ifdef DYNAMIC_RUBY
+	else if (STRICMP(name, "ruby") == 0)
+	    n = ruby_enabled(FALSE);
+#endif
+#ifdef DYNAMIC_PYTHON
+	else if (STRICMP(name, "python") == 0)
+	    n = python_enabled(FALSE);
+#endif
+#ifdef DYNAMIC_PERL
+	else if (STRICMP(name, "perl") == 0)
+	    n = perl_enabled(FALSE);
+#endif
+#ifdef FEAT_GUI
+	else if (STRICMP(name, "gui_running") == 0)
+	    n = (gui.in_use || gui.starting);
+# ifdef FEAT_GUI_W32
+	else if (STRICMP(name, "gui_win32s") == 0)
+	    n = gui_is_win32s();
+# endif
+# ifdef FEAT_BROWSE
+	else if (STRICMP(name, "browse") == 0)
+	    n = gui.in_use;	/* gui_mch_browse() works when GUI is running */
+# endif
+#endif
+#ifdef FEAT_SYN_HL
+	else if (STRICMP(name, "syntax_items") == 0)
+	    n = syntax_present(curbuf);
+#endif
+#if defined(WIN3264)
+	else if (STRICMP(name, "win95") == 0)
+	    n = mch_windows95();
+#endif
+#ifdef FEAT_NETBEANS_INTG
+	else if (STRICMP(name, "netbeans_enabled") == 0)
+	    n = usingNetbeans;
+#endif
+    }
+
+    rettv->vval.v_number = n;
+}
+
+/*
+ * "has_key()" function
+ */
+    static void
+f_has_key(argvars, rettv)
+    typval_T	*argvars;
+    typval_T	*rettv;
+{
+    rettv->vval.v_number = 0;
+    if (argvars[0].v_type != VAR_DICT)
+    {
+	EMSG(_(e_dictreq));
+	return;
+    }
+    if (argvars[0].vval.v_dict == NULL)
+	return;
+
+    rettv->vval.v_number = dict_find(argvars[0].vval.v_dict,
+				      get_tv_string(&argvars[1]), -1) != NULL;
+}
+
+/*
+ * "haslocaldir()" function
+ */
+/*ARGSUSED*/
+    static void
+f_haslocaldir(argvars, rettv)
+    typval_T	*argvars;
+    typval_T	*rettv;
+{
+    rettv->vval.v_number = (curwin->w_localdir != NULL);
+}
+
+/*
+ * "hasmapto()" function
+ */
+    static void
+f_hasmapto(argvars, rettv)
+    typval_T	*argvars;
+    typval_T	*rettv;
+{
+    char_u	*name;
+    char_u	*mode;
+    char_u	buf[NUMBUFLEN];
+    int		abbr = FALSE;
+
+    name = get_tv_string(&argvars[0]);
+    if (argvars[1].v_type == VAR_UNKNOWN)
+	mode = (char_u *)"nvo";
+    else
+    {
+	mode = get_tv_string_buf(&argvars[1], buf);
+	if (argvars[2].v_type != VAR_UNKNOWN)
+	    abbr = get_tv_number(&argvars[2]);
+    }
+
+    if (map_to_exists(name, mode, abbr))
+	rettv->vval.v_number = TRUE;
+    else
+	rettv->vval.v_number = FALSE;
+}
+
+/*
+ * "histadd()" function
+ */
+/*ARGSUSED*/
+    static void
+f_histadd(argvars, rettv)
+    typval_T	*argvars;
+    typval_T	*rettv;
+{
+#ifdef FEAT_CMDHIST
+    int		histype;
+    char_u	*str;
+    char_u	buf[NUMBUFLEN];
+#endif
+
+    rettv->vval.v_number = FALSE;
+    if (check_restricted() || check_secure())
+	return;
+#ifdef FEAT_CMDHIST
+    str = get_tv_string_chk(&argvars[0]);	/* NULL on type error */
+    histype = str != NULL ? get_histtype(str) : -1;
+    if (histype >= 0)
+    {
+	str = get_tv_string_buf(&argvars[1], buf);
+	if (*str != NUL)
+	{
+	    add_to_history(histype, str, FALSE, NUL);
+	    rettv->vval.v_number = TRUE;
+	    return;
+	}
+    }
+#endif
+}
+
+/*
+ * "histdel()" function
+ */
+/*ARGSUSED*/
+    static void
+f_histdel(argvars, rettv)
+    typval_T	*argvars;
+    typval_T	*rettv;
+{
+#ifdef FEAT_CMDHIST
+    int		n;
+    char_u	buf[NUMBUFLEN];
+    char_u	*str;
+
+    str = get_tv_string_chk(&argvars[0]);	/* NULL on type error */
+    if (str == NULL)
+	n = 0;
+    else if (argvars[1].v_type == VAR_UNKNOWN)
+	/* only one argument: clear entire history */
+	n = clr_history(get_histtype(str));
+    else if (argvars[1].v_type == VAR_NUMBER)
+	/* index given: remove that entry */
+	n = del_history_idx(get_histtype(str),
+					  (int)get_tv_number(&argvars[1]));
+    else
+	/* string given: remove all matching entries */
+	n = del_history_entry(get_histtype(str),
+				      get_tv_string_buf(&argvars[1], buf));
+    rettv->vval.v_number = n;
+#else
+    rettv->vval.v_number = 0;
+#endif
+}
+
+/*
+ * "histget()" function
+ */
+/*ARGSUSED*/
+    static void
+f_histget(argvars, rettv)
+    typval_T	*argvars;
+    typval_T	*rettv;
+{
+#ifdef FEAT_CMDHIST
+    int		type;
+    int		idx;
+    char_u	*str;
+
+    str = get_tv_string_chk(&argvars[0]);	/* NULL on type error */
+    if (str == NULL)
+	rettv->vval.v_string = NULL;
+    else
+    {
+	type = get_histtype(str);
+	if (argvars[1].v_type == VAR_UNKNOWN)
+	    idx = get_history_idx(type);
+	else
+	    idx = (int)get_tv_number_chk(&argvars[1], NULL);
+						    /* -1 on type error */
+	rettv->vval.v_string = vim_strsave(get_history_entry(type, idx));
+    }
+#else
+    rettv->vval.v_string = NULL;
+#endif
+    rettv->v_type = VAR_STRING;
+}
+
+/*
+ * "histnr()" function
+ */
+/*ARGSUSED*/
+    static void
+f_histnr(argvars, rettv)
+    typval_T	*argvars;
+    typval_T	*rettv;
+{
+    int		i;
+
+#ifdef FEAT_CMDHIST
+    char_u	*history = get_tv_string_chk(&argvars[0]);
+
+    i = history == NULL ? HIST_CMD - 1 : get_histtype(history);
+    if (i >= HIST_CMD && i < HIST_COUNT)
+	i = get_history_idx(i);
+    else
+#endif
+	i = -1;
+    rettv->vval.v_number = i;
+}
+
+/*
+ * "highlightID(name)" function
+ */
+    static void
+f_hlID(argvars, rettv)
+    typval_T	*argvars;
+    typval_T	*rettv;
+{
+    rettv->vval.v_number = syn_name2id(get_tv_string(&argvars[0]));
+}
+
+/*
+ * "highlight_exists()" function
+ */
+    static void
+f_hlexists(argvars, rettv)
+    typval_T	*argvars;
+    typval_T	*rettv;
+{
+    rettv->vval.v_number = highlight_exists(get_tv_string(&argvars[0]));
+}
+
+/*
+ * "hostname()" function
+ */
+/*ARGSUSED*/
+    static void
+f_hostname(argvars, rettv)
+    typval_T	*argvars;
+    typval_T	*rettv;
+{
+    char_u hostname[256];
+
+    mch_get_host_name(hostname, 256);
+    rettv->v_type = VAR_STRING;
+    rettv->vval.v_string = vim_strsave(hostname);
+}
+
+/*
+ * iconv() function
+ */
+/*ARGSUSED*/
+    static void
+f_iconv(argvars, rettv)
+    typval_T	*argvars;
+    typval_T	*rettv;
+{
+#ifdef FEAT_MBYTE
+    char_u	buf1[NUMBUFLEN];
+    char_u	buf2[NUMBUFLEN];
+    char_u	*from, *to, *str;
+    vimconv_T	vimconv;
+#endif
+
+    rettv->v_type = VAR_STRING;
+    rettv->vval.v_string = NULL;
+
+#ifdef FEAT_MBYTE
+    str = get_tv_string(&argvars[0]);
+    from = enc_canonize(enc_skip(get_tv_string_buf(&argvars[1], buf1)));
+    to = enc_canonize(enc_skip(get_tv_string_buf(&argvars[2], buf2)));
+    vimconv.vc_type = CONV_NONE;
+    convert_setup(&vimconv, from, to);
+
+    /* If the encodings are equal, no conversion needed. */
+    if (vimconv.vc_type == CONV_NONE)
+	rettv->vval.v_string = vim_strsave(str);
+    else
+	rettv->vval.v_string = string_convert(&vimconv, str, NULL);
+
+    convert_setup(&vimconv, NULL, NULL);
+    vim_free(from);
+    vim_free(to);
+#endif
+}
+
+/*
+ * "indent()" function
+ */
+    static void
+f_indent(argvars, rettv)
+    typval_T	*argvars;
+    typval_T	*rettv;
+{
+    linenr_T	lnum;
+
+    lnum = get_tv_lnum(argvars);
+    if (lnum >= 1 && lnum <= curbuf->b_ml.ml_line_count)
+	rettv->vval.v_number = get_indent_lnum(lnum);
+    else
+	rettv->vval.v_number = -1;
+}
+
+/*
+ * "index()" function
+ */
+    static void
+f_index(argvars, rettv)
+    typval_T	*argvars;
+    typval_T	*rettv;
+{
+    list_T	*l;
+    listitem_T	*item;
+    long	idx = 0;
+    int		ic = FALSE;
+
+    rettv->vval.v_number = -1;
+    if (argvars[0].v_type != VAR_LIST)
+    {
+	EMSG(_(e_listreq));
+	return;
+    }
+    l = argvars[0].vval.v_list;
+    if (l != NULL)
+    {
+	item = l->lv_first;
+	if (argvars[2].v_type != VAR_UNKNOWN)
+	{
+	    int		error = FALSE;
+
+	    /* Start at specified item.  Use the cached index that list_find()
+	     * sets, so that a negative number also works. */
+	    item = list_find(l, get_tv_number_chk(&argvars[2], &error));
+	    idx = l->lv_idx;
+	    if (argvars[3].v_type != VAR_UNKNOWN)
+		ic = get_tv_number_chk(&argvars[3], &error);
+	    if (error)
+		item = NULL;
+	}
+
+	for ( ; item != NULL; item = item->li_next, ++idx)
+	    if (tv_equal(&item->li_tv, &argvars[1], ic))
+	    {
+		rettv->vval.v_number = idx;
+		break;
+	    }
+    }
+}
+
+static int inputsecret_flag = 0;
+
+static void get_user_input __ARGS((typval_T *argvars, typval_T *rettv, int inputdialog));
+
+/*
+ * This function is used by f_input() and f_inputdialog() functions. The third
+ * argument to f_input() specifies the type of completion to use at the
+ * prompt. The third argument to f_inputdialog() specifies the value to return
+ * when the user cancels the prompt.
+ */
+    static void
+get_user_input(argvars, rettv, inputdialog)
+    typval_T	*argvars;
+    typval_T	*rettv;
+    int		inputdialog;
+{
+    char_u	*prompt = get_tv_string_chk(&argvars[0]);
+    char_u	*p = NULL;
+    int		c;
+    char_u	buf[NUMBUFLEN];
+    int		cmd_silent_save = cmd_silent;
+    char_u	*defstr = (char_u *)"";
+    int		xp_type = EXPAND_NOTHING;
+    char_u	*xp_arg = NULL;
+
+    rettv->v_type = VAR_STRING;
+
+#ifdef NO_CONSOLE_INPUT
+    /* While starting up, there is no place to enter text. */
+    if (no_console_input())
+    {
+	rettv->vval.v_string = NULL;
+	return;
+    }
+#endif
+
+    cmd_silent = FALSE;		/* Want to see the prompt. */
+    if (prompt != NULL)
+    {
+	/* Only the part of the message after the last NL is considered as
+	 * prompt for the command line */
+	p = vim_strrchr(prompt, '\n');
+	if (p == NULL)
+	    p = prompt;
+	else
+	{
+	    ++p;
+	    c = *p;
+	    *p = NUL;
+	    msg_start();
+	    msg_clr_eos();
+	    msg_puts_attr(prompt, echo_attr);
+	    msg_didout = FALSE;
+	    msg_starthere();
+	    *p = c;
+	}
+	cmdline_row = msg_row;
+
+	if (argvars[1].v_type != VAR_UNKNOWN)
+	{
+	    defstr = get_tv_string_buf_chk(&argvars[1], buf);
+	    if (defstr != NULL)
+		stuffReadbuffSpec(defstr);
+
+	    if (!inputdialog && argvars[2].v_type != VAR_UNKNOWN)
+	    {
+		char_u	*xp_name;
+		int	xp_namelen;
+		long	argt;
+
+		rettv->vval.v_string = NULL;
+
+		xp_name = get_tv_string_buf_chk(&argvars[2], buf);
+		if (xp_name == NULL)
+		    return;
+
+		xp_namelen = (int)STRLEN(xp_name);
+
+		if (parse_compl_arg(xp_name, xp_namelen, &xp_type, &argt,
+							     &xp_arg) == FAIL)
+		    return;
+	    }
+	}
+
+	if (defstr != NULL)
+	    rettv->vval.v_string =
+		getcmdline_prompt(inputsecret_flag ? NUL : '@', p, echo_attr,
+				  xp_type, xp_arg);
+
+	vim_free(xp_arg);
+
+	/* since the user typed this, no need to wait for return */
+	need_wait_return = FALSE;
+	msg_didout = FALSE;
+    }
+    cmd_silent = cmd_silent_save;
+}
+
+/*
+ * "input()" function
+ *     Also handles inputsecret() when inputsecret is set.
+ */
+    static void
+f_input(argvars, rettv)
+    typval_T	*argvars;
+    typval_T	*rettv;
+{
+    get_user_input(argvars, rettv, FALSE);
+}
+
+/*
+ * "inputdialog()" function
+ */
+    static void
+f_inputdialog(argvars, rettv)
+    typval_T	*argvars;
+    typval_T	*rettv;
+{
+#if defined(FEAT_GUI_TEXTDIALOG)
+    /* Use a GUI dialog if the GUI is running and 'c' is not in 'guioptions' */
+    if (gui.in_use && vim_strchr(p_go, GO_CONDIALOG) == NULL)
+    {
+	char_u	*message;
+	char_u	buf[NUMBUFLEN];
+	char_u	*defstr = (char_u *)"";
+
+	message = get_tv_string_chk(&argvars[0]);
+	if (argvars[1].v_type != VAR_UNKNOWN
+		&& (defstr = get_tv_string_buf_chk(&argvars[1], buf)) != NULL)
+	    vim_strncpy(IObuff, defstr, IOSIZE - 1);
+	else
+	    IObuff[0] = NUL;
+	if (message != NULL && defstr != NULL
+		&& do_dialog(VIM_QUESTION, NULL, message,
+				(char_u *)_("&OK\n&Cancel"), 1, IObuff) == 1)
+	    rettv->vval.v_string = vim_strsave(IObuff);
+	else
+	{
+	    if (message != NULL && defstr != NULL
+					&& argvars[1].v_type != VAR_UNKNOWN
+					&& argvars[2].v_type != VAR_UNKNOWN)
+		rettv->vval.v_string = vim_strsave(
+				      get_tv_string_buf(&argvars[2], buf));
+	    else
+		rettv->vval.v_string = NULL;
+	}
+	rettv->v_type = VAR_STRING;
+    }
+    else
+#endif
+	get_user_input(argvars, rettv, TRUE);
+}
+
+/*
+ * "inputlist()" function
+ */
+    static void
+f_inputlist(argvars, rettv)
+    typval_T	*argvars;
+    typval_T	*rettv;
+{
+    listitem_T	*li;
+    int		selected;
+    int		mouse_used;
+
+    rettv->vval.v_number = 0;
+#ifdef NO_CONSOLE_INPUT
+    /* While starting up, there is no place to enter text. */
+    if (no_console_input())
+	return;
+#endif
+    if (argvars[0].v_type != VAR_LIST || argvars[0].vval.v_list == NULL)
+    {
+	EMSG2(_(e_listarg), "inputlist()");
+	return;
+    }
+
+    msg_start();
+    msg_row = Rows - 1;	/* for when 'cmdheight' > 1 */
+    lines_left = Rows;	/* avoid more prompt */
+    msg_scroll = TRUE;
+    msg_clr_eos();
+
+    for (li = argvars[0].vval.v_list->lv_first; li != NULL; li = li->li_next)
+    {
+	msg_puts(get_tv_string(&li->li_tv));
+	msg_putchar('\n');
+    }
+
+    /* Ask for choice. */
+    selected = prompt_for_number(&mouse_used);
+    if (mouse_used)
+	selected -= lines_left;
+
+    rettv->vval.v_number = selected;
+}
+
+
+static garray_T	    ga_userinput = {0, 0, sizeof(tasave_T), 4, NULL};
+
+/*
+ * "inputrestore()" function
+ */
+/*ARGSUSED*/
+    static void
+f_inputrestore(argvars, rettv)
+    typval_T	*argvars;
+    typval_T	*rettv;
+{
+    if (ga_userinput.ga_len > 0)
+    {
+	--ga_userinput.ga_len;
+	restore_typeahead((tasave_T *)(ga_userinput.ga_data)
+						       + ga_userinput.ga_len);
+	rettv->vval.v_number = 0; /* OK */
+    }
+    else if (p_verbose > 1)
+    {
+	verb_msg((char_u *)_("called inputrestore() more often than inputsave()"));
+	rettv->vval.v_number = 1; /* Failed */
+    }
+}
+
+/*
+ * "inputsave()" function
+ */
+/*ARGSUSED*/
+    static void
+f_inputsave(argvars, rettv)
+    typval_T	*argvars;
+    typval_T	*rettv;
+{
+    /* Add an entry to the stack of typehead storage. */
+    if (ga_grow(&ga_userinput, 1) == OK)
+    {
+	save_typeahead((tasave_T *)(ga_userinput.ga_data)
+						       + ga_userinput.ga_len);
+	++ga_userinput.ga_len;
+	rettv->vval.v_number = 0; /* OK */
+    }
+    else
+	rettv->vval.v_number = 1; /* Failed */
+}
+
+/*
+ * "inputsecret()" function
+ */
+    static void
+f_inputsecret(argvars, rettv)
+    typval_T	*argvars;
+    typval_T	*rettv;
+{
+    ++cmdline_star;
+    ++inputsecret_flag;
+    f_input(argvars, rettv);
+    --cmdline_star;
+    --inputsecret_flag;
+}
+
+/*
+ * "insert()" function
+ */
+    static void
+f_insert(argvars, rettv)
+    typval_T	*argvars;
+    typval_T	*rettv;
+{
+    long	before = 0;
+    listitem_T	*item;
+    list_T	*l;
+    int		error = FALSE;
+
+    rettv->vval.v_number = 0;
+    if (argvars[0].v_type != VAR_LIST)
+	EMSG2(_(e_listarg), "insert()");
+    else if ((l = argvars[0].vval.v_list) != NULL
+	    && !tv_check_lock(l->lv_lock, (char_u *)"insert()"))
+    {
+	if (argvars[2].v_type != VAR_UNKNOWN)
+	    before = get_tv_number_chk(&argvars[2], &error);
+	if (error)
+	    return;		/* type error; errmsg already given */
+
+	if (before == l->lv_len)
+	    item = NULL;
+	else
+	{
+	    item = list_find(l, before);
+	    if (item == NULL)
+	    {
+		EMSGN(_(e_listidx), before);
+		l = NULL;
+	    }
+	}
+	if (l != NULL)
+	{
+	    list_insert_tv(l, &argvars[1], item);
+	    copy_tv(&argvars[0], rettv);
+	}
+    }
+}
+
+/*
+ * "isdirectory()" function
+ */
+    static void
+f_isdirectory(argvars, rettv)
+    typval_T	*argvars;
+    typval_T	*rettv;
+{
+    rettv->vval.v_number = mch_isdir(get_tv_string(&argvars[0]));
+}
+
+/*
+ * "islocked()" function
+ */
+    static void
+f_islocked(argvars, rettv)
+    typval_T	*argvars;
+    typval_T	*rettv;
+{
+    lval_T	lv;
+    char_u	*end;
+    dictitem_T	*di;
+
+    rettv->vval.v_number = -1;
+    end = get_lval(get_tv_string(&argvars[0]), NULL, &lv, FALSE, FALSE, FALSE,
+							     FNE_CHECK_START);
+    if (end != NULL && lv.ll_name != NULL)
+    {
+	if (*end != NUL)
+	    EMSG(_(e_trailing));
+	else
+	{
+	    if (lv.ll_tv == NULL)
+	    {
+		if (check_changedtick(lv.ll_name))
+		    rettv->vval.v_number = 1;	    /* always locked */
+		else
+		{
+		    di = find_var(lv.ll_name, NULL);
+		    if (di != NULL)
+		    {
+			/* Consider a variable locked when:
+			 * 1. the variable itself is locked
+			 * 2. the value of the variable is locked.
+			 * 3. the List or Dict value is locked.
+			 */
+			rettv->vval.v_number = ((di->di_flags & DI_FLAGS_LOCK)
+						  || tv_islocked(&di->di_tv));
+		    }
+		}
+	    }
+	    else if (lv.ll_range)
+		EMSG(_("E786: Range not allowed"));
+	    else if (lv.ll_newkey != NULL)
+		EMSG2(_(e_dictkey), lv.ll_newkey);
+	    else if (lv.ll_list != NULL)
+		/* List item. */
+		rettv->vval.v_number = tv_islocked(&lv.ll_li->li_tv);
+	    else
+		/* Dictionary item. */
+		rettv->vval.v_number = tv_islocked(&lv.ll_di->di_tv);
+	}
+    }
+
+    clear_lval(&lv);
+}
+
+static void dict_list __ARGS((typval_T *argvars, typval_T *rettv, int what));
+
+/*
+ * Turn a dict into a list:
+ * "what" == 0: list of keys
+ * "what" == 1: list of values
+ * "what" == 2: list of items
+ */
+    static void
+dict_list(argvars, rettv, what)
+    typval_T	*argvars;
+    typval_T	*rettv;
+    int		what;
+{
+    list_T	*l2;
+    dictitem_T	*di;
+    hashitem_T	*hi;
+    listitem_T	*li;
+    listitem_T	*li2;
+    dict_T	*d;
+    int		todo;
+
+    rettv->vval.v_number = 0;
+    if (argvars[0].v_type != VAR_DICT)
+    {
+	EMSG(_(e_dictreq));
+	return;
+    }
+    if ((d = argvars[0].vval.v_dict) == NULL)
+	return;
+
+    if (rettv_list_alloc(rettv) == FAIL)
+	return;
+
+    todo = (int)d->dv_hashtab.ht_used;
+    for (hi = d->dv_hashtab.ht_array; todo > 0; ++hi)
+    {
+	if (!HASHITEM_EMPTY(hi))
+	{
+	    --todo;
+	    di = HI2DI(hi);
+
+	    li = listitem_alloc();
+	    if (li == NULL)
+		break;
+	    list_append(rettv->vval.v_list, li);
+
+	    if (what == 0)
+	    {
+		/* keys() */
+		li->li_tv.v_type = VAR_STRING;
+		li->li_tv.v_lock = 0;
+		li->li_tv.vval.v_string = vim_strsave(di->di_key);
+	    }
+	    else if (what == 1)
+	    {
+		/* values() */
+		copy_tv(&di->di_tv, &li->li_tv);
+	    }
+	    else
+	    {
+		/* items() */
+		l2 = list_alloc();
+		li->li_tv.v_type = VAR_LIST;
+		li->li_tv.v_lock = 0;
+		li->li_tv.vval.v_list = l2;
+		if (l2 == NULL)
+		    break;
+		++l2->lv_refcount;
+
+		li2 = listitem_alloc();
+		if (li2 == NULL)
+		    break;
+		list_append(l2, li2);
+		li2->li_tv.v_type = VAR_STRING;
+		li2->li_tv.v_lock = 0;
+		li2->li_tv.vval.v_string = vim_strsave(di->di_key);
+
+		li2 = listitem_alloc();
+		if (li2 == NULL)
+		    break;
+		list_append(l2, li2);
+		copy_tv(&di->di_tv, &li2->li_tv);
+	    }
+	}
+    }
+}
+
+/*
+ * "items(dict)" function
+ */
+    static void
+f_items(argvars, rettv)
+    typval_T	*argvars;
+    typval_T	*rettv;
+{
+    dict_list(argvars, rettv, 2);
+}
+
+/*
+ * "join()" function
+ */
+    static void
+f_join(argvars, rettv)
+    typval_T	*argvars;
+    typval_T	*rettv;
+{
+    garray_T	ga;
+    char_u	*sep;
+
+    rettv->vval.v_number = 0;
+    if (argvars[0].v_type != VAR_LIST)
+    {
+	EMSG(_(e_listreq));
+	return;
+    }
+    if (argvars[0].vval.v_list == NULL)
+	return;
+    if (argvars[1].v_type == VAR_UNKNOWN)
+	sep = (char_u *)" ";
+    else
+	sep = get_tv_string_chk(&argvars[1]);
+
+    rettv->v_type = VAR_STRING;
+
+    if (sep != NULL)
+    {
+	ga_init2(&ga, (int)sizeof(char), 80);
+	list_join(&ga, argvars[0].vval.v_list, sep, TRUE, 0);
+	ga_append(&ga, NUL);
+	rettv->vval.v_string = (char_u *)ga.ga_data;
+    }
+    else
+	rettv->vval.v_string = NULL;
+}
+
+/*
+ * "keys()" function
+ */
+    static void
+f_keys(argvars, rettv)
+    typval_T	*argvars;
+    typval_T	*rettv;
+{
+    dict_list(argvars, rettv, 0);
+}
+
+/*
+ * "last_buffer_nr()" function.
+ */
+/*ARGSUSED*/
+    static void
+f_last_buffer_nr(argvars, rettv)
+    typval_T	*argvars;
+    typval_T	*rettv;
+{
+    int		n = 0;
+    buf_T	*buf;
+
+    for (buf = firstbuf; buf != NULL; buf = buf->b_next)
+	if (n < buf->b_fnum)
+	    n = buf->b_fnum;
+
+    rettv->vval.v_number = n;
+}
+
+/*
+ * "len()" function
+ */
+    static void
+f_len(argvars, rettv)
+    typval_T	*argvars;
+    typval_T	*rettv;
+{
+    switch (argvars[0].v_type)
+    {
+	case VAR_STRING:
+	case VAR_NUMBER:
+	    rettv->vval.v_number = (varnumber_T)STRLEN(
+					       get_tv_string(&argvars[0]));
+	    break;
+	case VAR_LIST:
+	    rettv->vval.v_number = list_len(argvars[0].vval.v_list);
+	    break;
+	case VAR_DICT:
+	    rettv->vval.v_number = dict_len(argvars[0].vval.v_dict);
+	    break;
+	default:
+	    EMSG(_("E701: Invalid type for len()"));
+	    break;
+    }
+}
+
+static void libcall_common __ARGS((typval_T *argvars, typval_T *rettv, int type));
+
+    static void
+libcall_common(argvars, rettv, type)
+    typval_T	*argvars;
+    typval_T	*rettv;
+    int		type;
+{
+#ifdef FEAT_LIBCALL
+    char_u		*string_in;
+    char_u		**string_result;
+    int			nr_result;
+#endif
+
+    rettv->v_type = type;
+    if (type == VAR_NUMBER)
+	rettv->vval.v_number = 0;
+    else
+	rettv->vval.v_string = NULL;
+
+    if (check_restricted() || check_secure())
+	return;
+
+#ifdef FEAT_LIBCALL
+    /* The first two args must be strings, otherwise its meaningless */
+    if (argvars[0].v_type == VAR_STRING && argvars[1].v_type == VAR_STRING)
+    {
+	string_in = NULL;
+	if (argvars[2].v_type == VAR_STRING)
+	    string_in = argvars[2].vval.v_string;
+	if (type == VAR_NUMBER)
+	    string_result = NULL;
+	else
+	    string_result = &rettv->vval.v_string;
+	if (mch_libcall(argvars[0].vval.v_string,
+			     argvars[1].vval.v_string,
+			     string_in,
+			     argvars[2].vval.v_number,
+			     string_result,
+			     &nr_result) == OK
+		&& type == VAR_NUMBER)
+	    rettv->vval.v_number = nr_result;
+    }
+#endif
+}
+
+/*
+ * "libcall()" function
+ */
+    static void
+f_libcall(argvars, rettv)
+    typval_T	*argvars;
+    typval_T	*rettv;
+{
+    libcall_common(argvars, rettv, VAR_STRING);
+}
+
+/*
+ * "libcallnr()" function
+ */
+    static void
+f_libcallnr(argvars, rettv)
+    typval_T	*argvars;
+    typval_T	*rettv;
+{
+    libcall_common(argvars, rettv, VAR_NUMBER);
+}
+
+/*
+ * "line(string)" function
+ */
+    static void
+f_line(argvars, rettv)
+    typval_T	*argvars;
+    typval_T	*rettv;
+{
+    linenr_T	lnum = 0;
+    pos_T	*fp;
+    int		fnum;
+
+    fp = var2fpos(&argvars[0], TRUE, &fnum);
+    if (fp != NULL)
+	lnum = fp->lnum;
+    rettv->vval.v_number = lnum;
+}
+
+/*
+ * "line2byte(lnum)" function
+ */
+/*ARGSUSED*/
+    static void
+f_line2byte(argvars, rettv)
+    typval_T	*argvars;
+    typval_T	*rettv;
+{
+#ifndef FEAT_BYTEOFF
+    rettv->vval.v_number = -1;
+#else
+    linenr_T	lnum;
+
+    lnum = get_tv_lnum(argvars);
+    if (lnum < 1 || lnum > curbuf->b_ml.ml_line_count + 1)
+	rettv->vval.v_number = -1;
+    else
+	rettv->vval.v_number = ml_find_line_or_offset(curbuf, lnum, NULL);
+    if (rettv->vval.v_number >= 0)
+	++rettv->vval.v_number;
+#endif
+}
+
+/*
+ * "lispindent(lnum)" function
+ */
+    static void
+f_lispindent(argvars, rettv)
+    typval_T	*argvars;
+    typval_T	*rettv;
+{
+#ifdef FEAT_LISP
+    pos_T	pos;
+    linenr_T	lnum;
+
+    pos = curwin->w_cursor;
+    lnum = get_tv_lnum(argvars);
+    if (lnum >= 1 && lnum <= curbuf->b_ml.ml_line_count)
+    {
+	curwin->w_cursor.lnum = lnum;
+	rettv->vval.v_number = get_lisp_indent();
+	curwin->w_cursor = pos;
+    }
+    else
+#endif
+	rettv->vval.v_number = -1;
+}
+
+/*
+ * "localtime()" function
+ */
+/*ARGSUSED*/
+    static void
+f_localtime(argvars, rettv)
+    typval_T	*argvars;
+    typval_T	*rettv;
+{
+    rettv->vval.v_number = (varnumber_T)time(NULL);
+}
+
+static void get_maparg __ARGS((typval_T *argvars, typval_T *rettv, int exact));
+
+    static void
+get_maparg(argvars, rettv, exact)
+    typval_T	*argvars;
+    typval_T	*rettv;
+    int		exact;
+{
+    char_u	*keys;
+    char_u	*which;
+    char_u	buf[NUMBUFLEN];
+    char_u	*keys_buf = NULL;
+    char_u	*rhs;
+    int		mode;
+    garray_T	ga;
+    int		abbr = FALSE;
+
+    /* return empty string for failure */
+    rettv->v_type = VAR_STRING;
+    rettv->vval.v_string = NULL;
+
+    keys = get_tv_string(&argvars[0]);
+    if (*keys == NUL)
+	return;
+
+    if (argvars[1].v_type != VAR_UNKNOWN)
+    {
+	which = get_tv_string_buf_chk(&argvars[1], buf);
+	if (argvars[2].v_type != VAR_UNKNOWN)
+	    abbr = get_tv_number(&argvars[2]);
+    }
+    else
+	which = (char_u *)"";
+    if (which == NULL)
+	return;
+
+    mode = get_map_mode(&which, 0);
+
+    keys = replace_termcodes(keys, &keys_buf, TRUE, TRUE, FALSE);
+    rhs = check_map(keys, mode, exact, FALSE, abbr);
+    vim_free(keys_buf);
+    if (rhs != NULL)
+    {
+	ga_init(&ga);
+	ga.ga_itemsize = 1;
+	ga.ga_growsize = 40;
+
+	while (*rhs != NUL)
+	    ga_concat(&ga, str2special(&rhs, FALSE));
+
+	ga_append(&ga, NUL);
+	rettv->vval.v_string = (char_u *)ga.ga_data;
+    }
+}
+
+/*
+ * "map()" function
+ */
+    static void
+f_map(argvars, rettv)
+    typval_T	*argvars;
+    typval_T	*rettv;
+{
+    filter_map(argvars, rettv, TRUE);
+}
+
+/*
+ * "maparg()" function
+ */
+    static void
+f_maparg(argvars, rettv)
+    typval_T	*argvars;
+    typval_T	*rettv;
+{
+    get_maparg(argvars, rettv, TRUE);
+}
+
+/*
+ * "mapcheck()" function
+ */
+    static void
+f_mapcheck(argvars, rettv)
+    typval_T	*argvars;
+    typval_T	*rettv;
+{
+    get_maparg(argvars, rettv, FALSE);
+}
+
+static void find_some_match __ARGS((typval_T *argvars, typval_T *rettv, int start));
+
+    static void
+find_some_match(argvars, rettv, type)
+    typval_T	*argvars;
+    typval_T	*rettv;
+    int		type;
+{
+    char_u	*str = NULL;
+    char_u	*expr = NULL;
+    char_u	*pat;
+    regmatch_T	regmatch;
+    char_u	patbuf[NUMBUFLEN];
+    char_u	strbuf[NUMBUFLEN];
+    char_u	*save_cpo;
+    long	start = 0;
+    long	nth = 1;
+    colnr_T	startcol = 0;
+    int		match = 0;
+    list_T	*l = NULL;
+    listitem_T	*li = NULL;
+    long	idx = 0;
+    char_u	*tofree = NULL;
+
+    /* Make 'cpoptions' empty, the 'l' flag should not be used here. */
+    save_cpo = p_cpo;
+    p_cpo = (char_u *)"";
+
+    rettv->vval.v_number = -1;
+    if (type == 3)
+    {
+	/* return empty list when there are no matches */
+	if (rettv_list_alloc(rettv) == FAIL)
+	    goto theend;
+    }
+    else if (type == 2)
+    {
+	rettv->v_type = VAR_STRING;
+	rettv->vval.v_string = NULL;
+    }
+
+    if (argvars[0].v_type == VAR_LIST)
+    {
+	if ((l = argvars[0].vval.v_list) == NULL)
+	    goto theend;
+	li = l->lv_first;
+    }
+    else
+	expr = str = get_tv_string(&argvars[0]);
+
+    pat = get_tv_string_buf_chk(&argvars[1], patbuf);
+    if (pat == NULL)
+	goto theend;
+
+    if (argvars[2].v_type != VAR_UNKNOWN)
+    {
+	int	    error = FALSE;
+
+	start = get_tv_number_chk(&argvars[2], &error);
+	if (error)
+	    goto theend;
+	if (l != NULL)
+	{
+	    li = list_find(l, start);
+	    if (li == NULL)
+		goto theend;
+	    idx = l->lv_idx;	/* use the cached index */
+	}
+	else
+	{
+	    if (start < 0)
+		start = 0;
+	    if (start > (long)STRLEN(str))
+		goto theend;
+	    /* When "count" argument is there ignore matches before "start",
+	     * otherwise skip part of the string.  Differs when pattern is "^"
+	     * or "\<". */
+	    if (argvars[3].v_type != VAR_UNKNOWN)
+		startcol = start;
+	    else
+		str += start;
+	}
+
+	if (argvars[3].v_type != VAR_UNKNOWN)
+	    nth = get_tv_number_chk(&argvars[3], &error);
+	if (error)
+	    goto theend;
+    }
+
+    regmatch.regprog = vim_regcomp(pat, RE_MAGIC + RE_STRING);
+    if (regmatch.regprog != NULL)
+    {
+	regmatch.rm_ic = p_ic;
+
+	for (;;)
+	{
+	    if (l != NULL)
+	    {
+		if (li == NULL)
+		{
+		    match = FALSE;
+		    break;
+		}
+		vim_free(tofree);
+		str = echo_string(&li->li_tv, &tofree, strbuf, 0);
+		if (str == NULL)
+		    break;
+	    }
+
+	    match = vim_regexec_nl(&regmatch, str, (colnr_T)startcol);
+
+	    if (match && --nth <= 0)
+		break;
+	    if (l == NULL && !match)
+		break;
+
+	    /* Advance to just after the match. */
+	    if (l != NULL)
+	    {
+		li = li->li_next;
+		++idx;
+	    }
+	    else
+	    {
+#ifdef FEAT_MBYTE
+		startcol = (colnr_T)(regmatch.startp[0]
+				    + (*mb_ptr2len)(regmatch.startp[0]) - str);
+#else
+		startcol = regmatch.startp[0] + 1 - str;
+#endif
+	    }
+	}
+
+	if (match)
+	{
+	    if (type == 3)
+	    {
+		int i;
+
+		/* return list with matched string and submatches */
+		for (i = 0; i < NSUBEXP; ++i)
+		{
+		    if (regmatch.endp[i] == NULL)
+		    {
+			if (list_append_string(rettv->vval.v_list,
+						     (char_u *)"", 0) == FAIL)
+			    break;
+		    }
+		    else if (list_append_string(rettv->vval.v_list,
+				regmatch.startp[i],
+				(int)(regmatch.endp[i] - regmatch.startp[i]))
+			    == FAIL)
+			break;
+		}
+	    }
+	    else if (type == 2)
+	    {
+		/* return matched string */
+		if (l != NULL)
+		    copy_tv(&li->li_tv, rettv);
+		else
+		    rettv->vval.v_string = vim_strnsave(regmatch.startp[0],
+				(int)(regmatch.endp[0] - regmatch.startp[0]));
+	    }
+	    else if (l != NULL)
+		rettv->vval.v_number = idx;
+	    else
+	    {
+		if (type != 0)
+		    rettv->vval.v_number =
+				      (varnumber_T)(regmatch.startp[0] - str);
+		else
+		    rettv->vval.v_number =
+					(varnumber_T)(regmatch.endp[0] - str);
+		rettv->vval.v_number += (varnumber_T)(str - expr);
+	    }
+	}
+	vim_free(regmatch.regprog);
+    }
+
+theend:
+    vim_free(tofree);
+    p_cpo = save_cpo;
+}
+
+/*
+ * "match()" function
+ */
+    static void
+f_match(argvars, rettv)
+    typval_T	*argvars;
+    typval_T	*rettv;
+{
+    find_some_match(argvars, rettv, 1);
+}
+
+/*
+ * "matcharg()" function
+ */
+    static void
+f_matcharg(argvars, rettv)
+    typval_T	*argvars;
+    typval_T	*rettv;
+{
+    if (rettv_list_alloc(rettv) == OK)
+    {
+#ifdef FEAT_SEARCH_EXTRA
+	int	mi = get_tv_number(&argvars[0]);
+
+	if (mi >= 1 && mi <= 3)
+	{
+	    list_append_string(rettv->vval.v_list,
+				 syn_id2name(curwin->w_match_id[mi - 1]), -1);
+	    list_append_string(rettv->vval.v_list,
+					     curwin->w_match_pat[mi - 1], -1);
+	}
+#endif
+    }
+}
+
+/*
+ * "matchend()" function
+ */
+    static void
+f_matchend(argvars, rettv)
+    typval_T	*argvars;
+    typval_T	*rettv;
+{
+    find_some_match(argvars, rettv, 0);
+}
+
+/*
+ * "matchlist()" function
+ */
+    static void
+f_matchlist(argvars, rettv)
+    typval_T	*argvars;
+    typval_T	*rettv;
+{
+    find_some_match(argvars, rettv, 3);
+}
+
+/*
+ * "matchstr()" function
+ */
+    static void
+f_matchstr(argvars, rettv)
+    typval_T	*argvars;
+    typval_T	*rettv;
+{
+    find_some_match(argvars, rettv, 2);
+}
+
+static void max_min __ARGS((typval_T *argvars, typval_T *rettv, int domax));
+
+    static void
+max_min(argvars, rettv, domax)
+    typval_T	*argvars;
+    typval_T	*rettv;
+    int		domax;
+{
+    long	n = 0;
+    long	i;
+    int		error = FALSE;
+
+    if (argvars[0].v_type == VAR_LIST)
+    {
+	list_T		*l;
+	listitem_T	*li;
+
+	l = argvars[0].vval.v_list;
+	if (l != NULL)
+	{
+	    li = l->lv_first;
+	    if (li != NULL)
+	    {
+		n = get_tv_number_chk(&li->li_tv, &error);
+		for (;;)
+		{
+		    li = li->li_next;
+		    if (li == NULL)
+			break;
+		    i = get_tv_number_chk(&li->li_tv, &error);
+		    if (domax ? i > n : i < n)
+			n = i;
+		}
+	    }
+	}
+    }
+    else if (argvars[0].v_type == VAR_DICT)
+    {
+	dict_T		*d;
+	int		first = TRUE;
+	hashitem_T	*hi;
+	int		todo;
+
+	d = argvars[0].vval.v_dict;
+	if (d != NULL)
+	{
+	    todo = (int)d->dv_hashtab.ht_used;
+	    for (hi = d->dv_hashtab.ht_array; todo > 0; ++hi)
+	    {
+		if (!HASHITEM_EMPTY(hi))
+		{
+		    --todo;
+		    i = get_tv_number_chk(&HI2DI(hi)->di_tv, &error);
+		    if (first)
+		    {
+			n = i;
+			first = FALSE;
+		    }
+		    else if (domax ? i > n : i < n)
+			n = i;
+		}
+	    }
+	}
+    }
+    else
+	EMSG(_(e_listdictarg));
+    rettv->vval.v_number = error ? 0 : n;
+}
+
+/*
+ * "max()" function
+ */
+    static void
+f_max(argvars, rettv)
+    typval_T	*argvars;
+    typval_T	*rettv;
+{
+    max_min(argvars, rettv, TRUE);
+}
+
+/*
+ * "min()" function
+ */
+    static void
+f_min(argvars, rettv)
+    typval_T	*argvars;
+    typval_T	*rettv;
+{
+    max_min(argvars, rettv, FALSE);
+}
+
+static int mkdir_recurse __ARGS((char_u *dir, int prot));
+
+/*
+ * Create the directory in which "dir" is located, and higher levels when
+ * needed.
+ */
+    static int
+mkdir_recurse(dir, prot)
+    char_u	*dir;
+    int		prot;
+{
+    char_u	*p;
+    char_u	*updir;
+    int		r = FAIL;
+
+    /* Get end of directory name in "dir".
+     * We're done when it's "/" or "c:/". */
+    p = gettail_sep(dir);
+    if (p <= get_past_head(dir))
+	return OK;
+
+    /* If the directory exists we're done.  Otherwise: create it.*/
+    updir = vim_strnsave(dir, (int)(p - dir));
+    if (updir == NULL)
+	return FAIL;
+    if (mch_isdir(updir))
+	r = OK;
+    else if (mkdir_recurse(updir, prot) == OK)
+	r = vim_mkdir_emsg(updir, prot);
+    vim_free(updir);
+    return r;
+}
+
+#ifdef vim_mkdir
+/*
+ * "mkdir()" function
+ */
+    static void
+f_mkdir(argvars, rettv)
+    typval_T	*argvars;
+    typval_T	*rettv;
+{
+    char_u	*dir;
+    char_u	buf[NUMBUFLEN];
+    int		prot = 0755;
+
+    rettv->vval.v_number = FAIL;
+    if (check_restricted() || check_secure())
+	return;
+
+    dir = get_tv_string_buf(&argvars[0], buf);
+    if (argvars[1].v_type != VAR_UNKNOWN)
+    {
+	if (argvars[2].v_type != VAR_UNKNOWN)
+	    prot = get_tv_number_chk(&argvars[2], NULL);
+	if (prot != -1 && STRCMP(get_tv_string(&argvars[1]), "p") == 0)
+	    mkdir_recurse(dir, prot);
+    }
+    rettv->vval.v_number = prot != -1 ? vim_mkdir_emsg(dir, prot) : 0;
+}
+#endif
+
+/*
+ * "mode()" function
+ */
+/*ARGSUSED*/
+    static void
+f_mode(argvars, rettv)
+    typval_T	*argvars;
+    typval_T	*rettv;
+{
+    char_u	buf[2];
+
+#ifdef FEAT_VISUAL
+    if (VIsual_active)
+    {
+	if (VIsual_select)
+	    buf[0] = VIsual_mode + 's' - 'v';
+	else
+	    buf[0] = VIsual_mode;
+    }
+    else
+#endif
+	if (State == HITRETURN || State == ASKMORE || State == SETWSIZE)
+	buf[0] = 'r';
+    else if (State & INSERT)
+    {
+	if (State & REPLACE_FLAG)
+	    buf[0] = 'R';
+	else
+	    buf[0] = 'i';
+    }
+    else if (State & CMDLINE)
+	buf[0] = 'c';
+    else
+	buf[0] = 'n';
+
+    buf[1] = NUL;
+    rettv->vval.v_string = vim_strsave(buf);
+    rettv->v_type = VAR_STRING;
+}
+
+/*
+ * "nextnonblank()" function
+ */
+    static void
+f_nextnonblank(argvars, rettv)
+    typval_T	*argvars;
+    typval_T	*rettv;
+{
+    linenr_T	lnum;
+
+    for (lnum = get_tv_lnum(argvars); ; ++lnum)
+    {
+	if (lnum < 0 || lnum > curbuf->b_ml.ml_line_count)
+	{
+	    lnum = 0;
+	    break;
+	}
+	if (*skipwhite(ml_get(lnum)) != NUL)
+	    break;
+    }
+    rettv->vval.v_number = lnum;
+}
+
+/*
+ * "nr2char()" function
+ */
+    static void
+f_nr2char(argvars, rettv)
+    typval_T	*argvars;
+    typval_T	*rettv;
+{
+    char_u	buf[NUMBUFLEN];
+
+#ifdef FEAT_MBYTE
+    if (has_mbyte)
+	buf[(*mb_char2bytes)((int)get_tv_number(&argvars[0]), buf)] = NUL;
+    else
+#endif
+    {
+	buf[0] = (char_u)get_tv_number(&argvars[0]);
+	buf[1] = NUL;
+    }
+    rettv->v_type = VAR_STRING;
+    rettv->vval.v_string = vim_strsave(buf);
+}
+
+/*
+ * "pathshorten()" function
+ */
+    static void
+f_pathshorten(argvars, rettv)
+    typval_T	*argvars;
+    typval_T	*rettv;
+{
+    char_u	*p;
+
+    rettv->v_type = VAR_STRING;
+    p = get_tv_string_chk(&argvars[0]);
+    if (p == NULL)
+	rettv->vval.v_string = NULL;
+    else
+    {
+	p = vim_strsave(p);
+	rettv->vval.v_string = p;
+	if (p != NULL)
+	    shorten_dir(p);
+    }
+}
+
+/*
+ * "prevnonblank()" function
+ */
+    static void
+f_prevnonblank(argvars, rettv)
+    typval_T	*argvars;
+    typval_T	*rettv;
+{
+    linenr_T	lnum;
+
+    lnum = get_tv_lnum(argvars);
+    if (lnum < 1 || lnum > curbuf->b_ml.ml_line_count)
+	lnum = 0;
+    else
+	while (lnum >= 1 && *skipwhite(ml_get(lnum)) == NUL)
+	    --lnum;
+    rettv->vval.v_number = lnum;
+}
+
+#ifdef HAVE_STDARG_H
+/* This dummy va_list is here because:
+ * - passing a NULL pointer doesn't work when va_list isn't a pointer
+ * - locally in the function results in a "used before set" warning
+ * - using va_start() to initialize it gives "function with fixed args" error */
+static va_list	ap;
+#endif
+
+/*
+ * "printf()" function
+ */
+    static void
+f_printf(argvars, rettv)
+    typval_T	*argvars;
+    typval_T	*rettv;
+{
+    rettv->v_type = VAR_STRING;
+    rettv->vval.v_string = NULL;
+#ifdef HAVE_STDARG_H	    /* only very old compilers can't do this */
+    {
+	char_u	buf[NUMBUFLEN];
+	int	len;
+	char_u	*s;
+	int	saved_did_emsg = did_emsg;
+	char	*fmt;
+
+	/* Get the required length, allocate the buffer and do it for real. */
+	did_emsg = FALSE;
+	fmt = (char *)get_tv_string_buf(&argvars[0], buf);
+	len = vim_vsnprintf(NULL, 0, fmt, ap, argvars + 1);
+	if (!did_emsg)
+	{
+	    s = alloc(len + 1);
+	    if (s != NULL)
+	    {
+		rettv->vval.v_string = s;
+		(void)vim_vsnprintf((char *)s, len + 1, fmt, ap, argvars + 1);
+	    }
+	}
+	did_emsg |= saved_did_emsg;
+    }
+#endif
+}
+
+/*
+ * "pumvisible()" function
+ */
+/*ARGSUSED*/
+    static void
+f_pumvisible(argvars, rettv)
+    typval_T	*argvars;
+    typval_T	*rettv;
+{
+    rettv->vval.v_number = 0;
+#ifdef FEAT_INS_EXPAND
+    if (pum_visible())
+	rettv->vval.v_number = 1;
+#endif
+}
+
+/*
+ * "range()" function
+ */
+    static void
+f_range(argvars, rettv)
+    typval_T	*argvars;
+    typval_T	*rettv;
+{
+    long	start;
+    long	end;
+    long	stride = 1;
+    long	i;
+    int		error = FALSE;
+
+    start = get_tv_number_chk(&argvars[0], &error);
+    if (argvars[1].v_type == VAR_UNKNOWN)
+    {
+	end = start - 1;
+	start = 0;
+    }
+    else
+    {
+	end = get_tv_number_chk(&argvars[1], &error);
+	if (argvars[2].v_type != VAR_UNKNOWN)
+	    stride = get_tv_number_chk(&argvars[2], &error);
+    }
+
+    rettv->vval.v_number = 0;
+    if (error)
+	return;		/* type error; errmsg already given */
+    if (stride == 0)
+	EMSG(_("E726: Stride is zero"));
+    else if (stride > 0 ? end + 1 < start : end - 1 > start)
+	EMSG(_("E727: Start past end"));
+    else
+    {
+	if (rettv_list_alloc(rettv) == OK)
+	    for (i = start; stride > 0 ? i <= end : i >= end; i += stride)
+		if (list_append_number(rettv->vval.v_list,
+						      (varnumber_T)i) == FAIL)
+		    break;
+    }
+}
+
+/*
+ * "readfile()" function
+ */
+    static void
+f_readfile(argvars, rettv)
+    typval_T	*argvars;
+    typval_T	*rettv;
+{
+    int		binary = FALSE;
+    char_u	*fname;
+    FILE	*fd;
+    listitem_T	*li;
+#define FREAD_SIZE 200	    /* optimized for text lines */
+    char_u	buf[FREAD_SIZE];
+    int		readlen;    /* size of last fread() */
+    int		buflen;	    /* nr of valid chars in buf[] */
+    int		filtd;	    /* how much in buf[] was NUL -> '\n' filtered */
+    int		tolist;	    /* first byte in buf[] still to be put in list */
+    int		chop;	    /* how many CR to chop off */
+    char_u	*prev = NULL;	/* previously read bytes, if any */
+    int		prevlen = 0;    /* length of "prev" if not NULL */
+    char_u	*s;
+    int		len;
+    long	maxline = MAXLNUM;
+    long	cnt = 0;
+
+    if (argvars[1].v_type != VAR_UNKNOWN)
+    {
+	if (STRCMP(get_tv_string(&argvars[1]), "b") == 0)
+	    binary = TRUE;
+	if (argvars[2].v_type != VAR_UNKNOWN)
+	    maxline = get_tv_number(&argvars[2]);
+    }
+
+    if (rettv_list_alloc(rettv) == FAIL)
+	return;
+
+    /* Always open the file in binary mode, library functions have a mind of
+     * their own about CR-LF conversion. */
+    fname = get_tv_string(&argvars[0]);
+    if (*fname == NUL || (fd = mch_fopen((char *)fname, READBIN)) == NULL)
+    {
+	EMSG2(_(e_notopen), *fname == NUL ? (char_u *)_("<empty>") : fname);
+	return;
+    }
+
+    filtd = 0;
+    while (cnt < maxline || maxline < 0)
+    {
+	readlen = (int)fread(buf + filtd, 1, FREAD_SIZE - filtd, fd);
+	buflen = filtd + readlen;
+	tolist = 0;
+	for ( ; filtd < buflen || readlen <= 0; ++filtd)
+	{
+	    if (buf[filtd] == '\n' || readlen <= 0)
+	    {
+		/* Only when in binary mode add an empty list item when the
+		 * last line ends in a '\n'. */
+		if (!binary && readlen == 0 && filtd == 0)
+		    break;
+
+		/* Found end-of-line or end-of-file: add a text line to the
+		 * list. */
+		chop = 0;
+		if (!binary)
+		    while (filtd - chop - 1 >= tolist
+					  && buf[filtd - chop - 1] == '\r')
+			++chop;
+		len = filtd - tolist - chop;
+		if (prev == NULL)
+		    s = vim_strnsave(buf + tolist, len);
+		else
+		{
+		    s = alloc((unsigned)(prevlen + len + 1));
+		    if (s != NULL)
+		    {
+			mch_memmove(s, prev, prevlen);
+			vim_free(prev);
+			prev = NULL;
+			mch_memmove(s + prevlen, buf + tolist, len);
+			s[prevlen + len] = NUL;
+		    }
+		}
+		tolist = filtd + 1;
+
+		li = listitem_alloc();
+		if (li == NULL)
+		{
+		    vim_free(s);
+		    break;
+		}
+		li->li_tv.v_type = VAR_STRING;
+		li->li_tv.v_lock = 0;
+		li->li_tv.vval.v_string = s;
+		list_append(rettv->vval.v_list, li);
+
+		if (++cnt >= maxline && maxline >= 0)
+		    break;
+		if (readlen <= 0)
+		    break;
+	    }
+	    else if (buf[filtd] == NUL)
+		buf[filtd] = '\n';
+	}
+	if (readlen <= 0)
+	    break;
+
+	if (tolist == 0)
+	{
+	    /* "buf" is full, need to move text to an allocated buffer */
+	    if (prev == NULL)
+	    {
+		prev = vim_strnsave(buf, buflen);
+		prevlen = buflen;
+	    }
+	    else
+	    {
+		s = alloc((unsigned)(prevlen + buflen));
+		if (s != NULL)
+		{
+		    mch_memmove(s, prev, prevlen);
+		    mch_memmove(s + prevlen, buf, buflen);
+		    vim_free(prev);
+		    prev = s;
+		    prevlen += buflen;
+		}
+	    }
+	    filtd = 0;
+	}
+	else
+	{
+	    mch_memmove(buf, buf + tolist, buflen - tolist);
+	    filtd -= tolist;
+	}
+    }
+
+    /*
+     * For a negative line count use only the lines at the end of the file,
+     * free the rest.
+     */
+    if (maxline < 0)
+	while (cnt > -maxline)
+	{
+	    listitem_remove(rettv->vval.v_list, rettv->vval.v_list->lv_first);
+	    --cnt;
+	}
+
+    vim_free(prev);
+    fclose(fd);
+}
+
+#if defined(FEAT_RELTIME)
+static int list2proftime __ARGS((typval_T *arg, proftime_T *tm));
+
+/*
+ * Convert a List to proftime_T.
+ * Return FAIL when there is something wrong.
+ */
+    static int
+list2proftime(arg, tm)
+    typval_T	*arg;
+    proftime_T  *tm;
+{
+    long	n1, n2;
+    int	error = FALSE;
+
+    if (arg->v_type != VAR_LIST || arg->vval.v_list == NULL
+					     || arg->vval.v_list->lv_len != 2)
+	return FAIL;
+    n1 = list_find_nr(arg->vval.v_list, 0L, &error);
+    n2 = list_find_nr(arg->vval.v_list, 1L, &error);
+# ifdef WIN3264
+    tm->HighPart = n1;
+    tm->LowPart = n2;
+# else
+    tm->tv_sec = n1;
+    tm->tv_usec = n2;
+# endif
+    return error ? FAIL : OK;
+}
+#endif /* FEAT_RELTIME */
+
+/*
+ * "reltime()" function
+ */
+    static void
+f_reltime(argvars, rettv)
+    typval_T	*argvars;
+    typval_T	*rettv;
+{
+#ifdef FEAT_RELTIME
+    proftime_T	res;
+    proftime_T	start;
+
+    if (argvars[0].v_type == VAR_UNKNOWN)
+    {
+	/* No arguments: get current time. */
+	profile_start(&res);
+    }
+    else if (argvars[1].v_type == VAR_UNKNOWN)
+    {
+	if (list2proftime(&argvars[0], &res) == FAIL)
+	    return;
+	profile_end(&res);
+    }
+    else
+    {
+	/* Two arguments: compute the difference. */
+	if (list2proftime(&argvars[0], &start) == FAIL
+		|| list2proftime(&argvars[1], &res) == FAIL)
+	    return;
+	profile_sub(&res, &start);
+    }
+
+    if (rettv_list_alloc(rettv) == OK)
+    {
+	long	n1, n2;
+
+# ifdef WIN3264
+	n1 = res.HighPart;
+	n2 = res.LowPart;
+# else
+	n1 = res.tv_sec;
+	n2 = res.tv_usec;
+# endif
+	list_append_number(rettv->vval.v_list, (varnumber_T)n1);
+	list_append_number(rettv->vval.v_list, (varnumber_T)n2);
+    }
+#endif
+}
+
+/*
+ * "reltimestr()" function
+ */
+    static void
+f_reltimestr(argvars, rettv)
+    typval_T	*argvars;
+    typval_T	*rettv;
+{
+#ifdef FEAT_RELTIME
+    proftime_T	tm;
+#endif
+
+    rettv->v_type = VAR_STRING;
+    rettv->vval.v_string = NULL;
+#ifdef FEAT_RELTIME
+    if (list2proftime(&argvars[0], &tm) == OK)
+	rettv->vval.v_string = vim_strsave((char_u *)profile_msg(&tm));
+#endif
+}
+
+#if defined(FEAT_CLIENTSERVER) && defined(FEAT_X11)
+static void make_connection __ARGS((void));
+static int check_connection __ARGS((void));
+
+    static void
+make_connection()
+{
+    if (X_DISPLAY == NULL
+# ifdef FEAT_GUI
+	    && !gui.in_use
+# endif
+	    )
+    {
+	x_force_connect = TRUE;
+	setup_term_clip();
+	x_force_connect = FALSE;
+    }
+}
+
+    static int
+check_connection()
+{
+    make_connection();
+    if (X_DISPLAY == NULL)
+    {
+	EMSG(_("E240: No connection to Vim server"));
+	return FAIL;
+    }
+    return OK;
+}
+#endif
+
+#ifdef FEAT_CLIENTSERVER
+static void remote_common __ARGS((typval_T *argvars, typval_T *rettv, int expr));
+
+    static void
+remote_common(argvars, rettv, expr)
+    typval_T	*argvars;
+    typval_T	*rettv;
+    int		expr;
+{
+    char_u	*server_name;
+    char_u	*keys;
+    char_u	*r = NULL;
+    char_u	buf[NUMBUFLEN];
+# ifdef WIN32
+    HWND	w;
+# else
+    Window	w;
+# endif
+
+    if (check_restricted() || check_secure())
+	return;
+
+# ifdef FEAT_X11
+    if (check_connection() == FAIL)
+	return;
+# endif
+
+    server_name = get_tv_string_chk(&argvars[0]);
+    if (server_name == NULL)
+	return;		/* type error; errmsg already given */
+    keys = get_tv_string_buf(&argvars[1], buf);
+# ifdef WIN32
+    if (serverSendToVim(server_name, keys, &r, &w, expr, TRUE) < 0)
+# else
+    if (serverSendToVim(X_DISPLAY, server_name, keys, &r, &w, expr, 0, TRUE)
+									  < 0)
+# endif
+    {
+	if (r != NULL)
+	    EMSG(r);		/* sending worked but evaluation failed */
+	else
+	    EMSG2(_("E241: Unable to send to %s"), server_name);
+	return;
+    }
+
+    rettv->vval.v_string = r;
+
+    if (argvars[2].v_type != VAR_UNKNOWN)
+    {
+	dictitem_T	v;
+	char_u		str[30];
+	char_u		*idvar;
+
+	sprintf((char *)str, PRINTF_HEX_LONG_U, (long_u)w);
+	v.di_tv.v_type = VAR_STRING;
+	v.di_tv.vval.v_string = vim_strsave(str);
+	idvar = get_tv_string_chk(&argvars[2]);
+	if (idvar != NULL)
+	    set_var(idvar, &v.di_tv, FALSE);
+	vim_free(v.di_tv.vval.v_string);
+    }
+}
+#endif
+
+/*
+ * "remote_expr()" function
+ */
+/*ARGSUSED*/
+    static void
+f_remote_expr(argvars, rettv)
+    typval_T	*argvars;
+    typval_T	*rettv;
+{
+    rettv->v_type = VAR_STRING;
+    rettv->vval.v_string = NULL;
+#ifdef FEAT_CLIENTSERVER
+    remote_common(argvars, rettv, TRUE);
+#endif
+}
+
+/*
+ * "remote_foreground()" function
+ */
+/*ARGSUSED*/
+    static void
+f_remote_foreground(argvars, rettv)
+    typval_T	*argvars;
+    typval_T	*rettv;
+{
+    rettv->vval.v_number = 0;
+#ifdef FEAT_CLIENTSERVER
+# ifdef WIN32
+    /* On Win32 it's done in this application. */
+    {
+	char_u	*server_name = get_tv_string_chk(&argvars[0]);
+
+	if (server_name != NULL)
+	    serverForeground(server_name);
+    }
+# else
+    /* Send a foreground() expression to the server. */
+    argvars[1].v_type = VAR_STRING;
+    argvars[1].vval.v_string = vim_strsave((char_u *)"foreground()");
+    argvars[2].v_type = VAR_UNKNOWN;
+    remote_common(argvars, rettv, TRUE);
+    vim_free(argvars[1].vval.v_string);
+# endif
+#endif
+}
+
+/*ARGSUSED*/
+    static void
+f_remote_peek(argvars, rettv)
+    typval_T	*argvars;
+    typval_T	*rettv;
+{
+#ifdef FEAT_CLIENTSERVER
+    dictitem_T	v;
+    char_u	*s = NULL;
+# ifdef WIN32
+    long_u	n = 0;
+# endif
+    char_u	*serverid;
+
+    if (check_restricted() || check_secure())
+    {
+	rettv->vval.v_number = -1;
+	return;
+    }
+    serverid = get_tv_string_chk(&argvars[0]);
+    if (serverid == NULL)
+    {
+	rettv->vval.v_number = -1;
+	return;		/* type error; errmsg already given */
+    }
+# ifdef WIN32
+    sscanf(serverid, SCANF_HEX_LONG_U, &n);
+    if (n == 0)
+	rettv->vval.v_number = -1;
+    else
+    {
+	s = serverGetReply((HWND)n, FALSE, FALSE, FALSE);
+	rettv->vval.v_number = (s != NULL);
+    }
+# else
+    rettv->vval.v_number = 0;
+    if (check_connection() == FAIL)
+	return;
+
+    rettv->vval.v_number = serverPeekReply(X_DISPLAY,
+						serverStrToWin(serverid), &s);
+# endif
+
+    if (argvars[1].v_type != VAR_UNKNOWN && rettv->vval.v_number > 0)
+    {
+	char_u		*retvar;
+
+	v.di_tv.v_type = VAR_STRING;
+	v.di_tv.vval.v_string = vim_strsave(s);
+	retvar = get_tv_string_chk(&argvars[1]);
+	if (retvar != NULL)
+	    set_var(retvar, &v.di_tv, FALSE);
+	vim_free(v.di_tv.vval.v_string);
+    }
+#else
+    rettv->vval.v_number = -1;
+#endif
+}
+
+/*ARGSUSED*/
+    static void
+f_remote_read(argvars, rettv)
+    typval_T	*argvars;
+    typval_T	*rettv;
+{
+    char_u	*r = NULL;
+
+#ifdef FEAT_CLIENTSERVER
+    char_u	*serverid = get_tv_string_chk(&argvars[0]);
+
+    if (serverid != NULL && !check_restricted() && !check_secure())
+    {
+# ifdef WIN32
+	/* The server's HWND is encoded in the 'id' parameter */
+	long_u		n = 0;
+
+	sscanf(serverid, SCANF_HEX_LONG_U, &n);
+	if (n != 0)
+	    r = serverGetReply((HWND)n, FALSE, TRUE, TRUE);
+	if (r == NULL)
+# else
+	if (check_connection() == FAIL || serverReadReply(X_DISPLAY,
+		serverStrToWin(serverid), &r, FALSE) < 0)
+# endif
+	    EMSG(_("E277: Unable to read a server reply"));
+    }
+#endif
+    rettv->v_type = VAR_STRING;
+    rettv->vval.v_string = r;
+}
+
+/*
+ * "remote_send()" function
+ */
+/*ARGSUSED*/
+    static void
+f_remote_send(argvars, rettv)
+    typval_T	*argvars;
+    typval_T	*rettv;
+{
+    rettv->v_type = VAR_STRING;
+    rettv->vval.v_string = NULL;
+#ifdef FEAT_CLIENTSERVER
+    remote_common(argvars, rettv, FALSE);
+#endif
+}
+
+/*
+ * "remove()" function
+ */
+    static void
+f_remove(argvars, rettv)
+    typval_T	*argvars;
+    typval_T	*rettv;
+{
+    list_T	*l;
+    listitem_T	*item, *item2;
+    listitem_T	*li;
+    long	idx;
+    long	end;
+    char_u	*key;
+    dict_T	*d;
+    dictitem_T	*di;
+
+    rettv->vval.v_number = 0;
+    if (argvars[0].v_type == VAR_DICT)
+    {
+	if (argvars[2].v_type != VAR_UNKNOWN)
+	    EMSG2(_(e_toomanyarg), "remove()");
+	else if ((d = argvars[0].vval.v_dict) != NULL
+		&& !tv_check_lock(d->dv_lock, (char_u *)"remove() argument"))
+	{
+	    key = get_tv_string_chk(&argvars[1]);
+	    if (key != NULL)
+	    {
+		di = dict_find(d, key, -1);
+		if (di == NULL)
+		    EMSG2(_(e_dictkey), key);
+		else
+		{
+		    *rettv = di->di_tv;
+		    init_tv(&di->di_tv);
+		    dictitem_remove(d, di);
+		}
+	    }
+	}
+    }
+    else if (argvars[0].v_type != VAR_LIST)
+	EMSG2(_(e_listdictarg), "remove()");
+    else if ((l = argvars[0].vval.v_list) != NULL
+	    && !tv_check_lock(l->lv_lock, (char_u *)"remove() argument"))
+    {
+	int	    error = FALSE;
+
+	idx = get_tv_number_chk(&argvars[1], &error);
+	if (error)
+	    ;		/* type error: do nothing, errmsg already given */
+	else if ((item = list_find(l, idx)) == NULL)
+	    EMSGN(_(e_listidx), idx);
+	else
+	{
+	    if (argvars[2].v_type == VAR_UNKNOWN)
+	    {
+		/* Remove one item, return its value. */
+		list_remove(l, item, item);
+		*rettv = item->li_tv;
+		vim_free(item);
+	    }
+	    else
+	    {
+		/* Remove range of items, return list with values. */
+		end = get_tv_number_chk(&argvars[2], &error);
+		if (error)
+		    ;		/* type error: do nothing */
+		else if ((item2 = list_find(l, end)) == NULL)
+		    EMSGN(_(e_listidx), end);
+		else
+		{
+		    int	    cnt = 0;
+
+		    for (li = item; li != NULL; li = li->li_next)
+		    {
+			++cnt;
+			if (li == item2)
+			    break;
+		    }
+		    if (li == NULL)  /* didn't find "item2" after "item" */
+			EMSG(_(e_invrange));
+		    else
+		    {
+			list_remove(l, item, item2);
+			if (rettv_list_alloc(rettv) == OK)
+			{
+			    l = rettv->vval.v_list;
+			    l->lv_first = item;
+			    l->lv_last = item2;
+			    item->li_prev = NULL;
+			    item2->li_next = NULL;
+			    l->lv_len = cnt;
+			}
+		    }
+		}
+	    }
+	}
+    }
+}
+
+/*
+ * "rename({from}, {to})" function
+ */
+    static void
+f_rename(argvars, rettv)
+    typval_T	*argvars;
+    typval_T	*rettv;
+{
+    char_u	buf[NUMBUFLEN];
+
+    if (check_restricted() || check_secure())
+	rettv->vval.v_number = -1;
+    else
+	rettv->vval.v_number = vim_rename(get_tv_string(&argvars[0]),
+				      get_tv_string_buf(&argvars[1], buf));
+}
+
+/*
+ * "repeat()" function
+ */
+/*ARGSUSED*/
+    static void
+f_repeat(argvars, rettv)
+    typval_T	*argvars;
+    typval_T	*rettv;
+{
+    char_u	*p;
+    int		n;
+    int		slen;
+    int		len;
+    char_u	*r;
+    int		i;
+
+    n = get_tv_number(&argvars[1]);
+    if (argvars[0].v_type == VAR_LIST)
+    {
+	if (rettv_list_alloc(rettv) == OK && argvars[0].vval.v_list != NULL)
+	    while (n-- > 0)
+		if (list_extend(rettv->vval.v_list,
+					argvars[0].vval.v_list, NULL) == FAIL)
+		    break;
+    }
+    else
+    {
+	p = get_tv_string(&argvars[0]);
+	rettv->v_type = VAR_STRING;
+	rettv->vval.v_string = NULL;
+
+	slen = (int)STRLEN(p);
+	len = slen * n;
+	if (len <= 0)
+	    return;
+
+	r = alloc(len + 1);
+	if (r != NULL)
+	{
+	    for (i = 0; i < n; i++)
+		mch_memmove(r + i * slen, p, (size_t)slen);
+	    r[len] = NUL;
+	}
+
+	rettv->vval.v_string = r;
+    }
+}
+
+/*
+ * "resolve()" function
+ */
+    static void
+f_resolve(argvars, rettv)
+    typval_T	*argvars;
+    typval_T	*rettv;
+{
+    char_u	*p;
+
+    p = get_tv_string(&argvars[0]);
+#ifdef FEAT_SHORTCUT
+    {
+	char_u	*v = NULL;
+
+	v = mch_resolve_shortcut(p);
+	if (v != NULL)
+	    rettv->vval.v_string = v;
+	else
+	    rettv->vval.v_string = vim_strsave(p);
+    }
+#else
+# ifdef HAVE_READLINK
+    {
+	char_u	buf[MAXPATHL + 1];
+	char_u	*cpy;
+	int	len;
+	char_u	*remain = NULL;
+	char_u	*q;
+	int	is_relative_to_current = FALSE;
+	int	has_trailing_pathsep = FALSE;
+	int	limit = 100;
+
+	p = vim_strsave(p);
+
+	if (p[0] == '.' && (vim_ispathsep(p[1])
+				   || (p[1] == '.' && (vim_ispathsep(p[2])))))
+	    is_relative_to_current = TRUE;
+
+	len = STRLEN(p);
+	if (len > 0 && after_pathsep(p, p + len))
+	    has_trailing_pathsep = TRUE;
+
+	q = getnextcomp(p);
+	if (*q != NUL)
+	{
+	    /* Separate the first path component in "p", and keep the
+	     * remainder (beginning with the path separator). */
+	    remain = vim_strsave(q - 1);
+	    q[-1] = NUL;
+	}
+
+	for (;;)
+	{
+	    for (;;)
+	    {
+		len = readlink((char *)p, (char *)buf, MAXPATHL);
+		if (len <= 0)
+		    break;
+		buf[len] = NUL;
+
+		if (limit-- == 0)
+		{
+		    vim_free(p);
+		    vim_free(remain);
+		    EMSG(_("E655: Too many symbolic links (cycle?)"));
+		    rettv->vval.v_string = NULL;
+		    goto fail;
+		}
+
+		/* Ensure that the result will have a trailing path separator
+		 * if the argument has one. */
+		if (remain == NULL && has_trailing_pathsep)
+		    add_pathsep(buf);
+
+		/* Separate the first path component in the link value and
+		 * concatenate the remainders. */
+		q = getnextcomp(vim_ispathsep(*buf) ? buf + 1 : buf);
+		if (*q != NUL)
+		{
+		    if (remain == NULL)
+			remain = vim_strsave(q - 1);
+		    else
+		    {
+			cpy = concat_str(q - 1, remain);
+			if (cpy != NULL)
+			{
+			    vim_free(remain);
+			    remain = cpy;
+			}
+		    }
+		    q[-1] = NUL;
+		}
+
+		q = gettail(p);
+		if (q > p && *q == NUL)
+		{
+		    /* Ignore trailing path separator. */
+		    q[-1] = NUL;
+		    q = gettail(p);
+		}
+		if (q > p && !mch_isFullName(buf))
+		{
+		    /* symlink is relative to directory of argument */
+		    cpy = alloc((unsigned)(STRLEN(p) + STRLEN(buf) + 1));
+		    if (cpy != NULL)
+		    {
+			STRCPY(cpy, p);
+			STRCPY(gettail(cpy), buf);
+			vim_free(p);
+			p = cpy;
+		    }
+		}
+		else
+		{
+		    vim_free(p);
+		    p = vim_strsave(buf);
+		}
+	    }
+
+	    if (remain == NULL)
+		break;
+
+	    /* Append the first path component of "remain" to "p". */
+	    q = getnextcomp(remain + 1);
+	    len = q - remain - (*q != NUL);
+	    cpy = vim_strnsave(p, STRLEN(p) + len);
+	    if (cpy != NULL)
+	    {
+		STRNCAT(cpy, remain, len);
+		vim_free(p);
+		p = cpy;
+	    }
+	    /* Shorten "remain". */
+	    if (*q != NUL)
+		STRCPY(remain, q - 1);
+	    else
+	    {
+		vim_free(remain);
+		remain = NULL;
+	    }
+	}
+
+	/* If the result is a relative path name, make it explicitly relative to
+	 * the current directory if and only if the argument had this form. */
+	if (!vim_ispathsep(*p))
+	{
+	    if (is_relative_to_current
+		    && *p != NUL
+		    && !(p[0] == '.'
+			&& (p[1] == NUL
+			    || vim_ispathsep(p[1])
+			    || (p[1] == '.'
+				&& (p[2] == NUL
+				    || vim_ispathsep(p[2]))))))
+	    {
+		/* Prepend "./". */
+		cpy = concat_str((char_u *)"./", p);
+		if (cpy != NULL)
+		{
+		    vim_free(p);
+		    p = cpy;
+		}
+	    }
+	    else if (!is_relative_to_current)
+	    {
+		/* Strip leading "./". */
+		q = p;
+		while (q[0] == '.' && vim_ispathsep(q[1]))
+		    q += 2;
+		if (q > p)
+		    mch_memmove(p, p + 2, STRLEN(p + 2) + (size_t)1);
+	    }
+	}
+
+	/* Ensure that the result will have no trailing path separator
+	 * if the argument had none.  But keep "/" or "//". */
+	if (!has_trailing_pathsep)
+	{
+	    q = p + STRLEN(p);
+	    if (after_pathsep(p, q))
+		*gettail_sep(p) = NUL;
+	}
+
+	rettv->vval.v_string = p;
+    }
+# else
+    rettv->vval.v_string = vim_strsave(p);
+# endif
+#endif
+
+    simplify_filename(rettv->vval.v_string);
+
+#ifdef HAVE_READLINK
+fail:
+#endif
+    rettv->v_type = VAR_STRING;
+}
+
+/*
+ * "reverse({list})" function
+ */
+    static void
+f_reverse(argvars, rettv)
+    typval_T	*argvars;
+    typval_T	*rettv;
+{
+    list_T	*l;
+    listitem_T	*li, *ni;
+
+    rettv->vval.v_number = 0;
+    if (argvars[0].v_type != VAR_LIST)
+	EMSG2(_(e_listarg), "reverse()");
+    else if ((l = argvars[0].vval.v_list) != NULL
+	    && !tv_check_lock(l->lv_lock, (char_u *)"reverse()"))
+    {
+	li = l->lv_last;
+	l->lv_first = l->lv_last = NULL;
+	l->lv_len = 0;
+	while (li != NULL)
+	{
+	    ni = li->li_prev;
+	    list_append(l, li);
+	    li = ni;
+	}
+	rettv->vval.v_list = l;
+	rettv->v_type = VAR_LIST;
+	++l->lv_refcount;
+    }
+}
+
+#define SP_NOMOVE	0x01	    /* don't move cursor */
+#define SP_REPEAT	0x02	    /* repeat to find outer pair */
+#define SP_RETCOUNT	0x04	    /* return matchcount */
+#define SP_SETPCMARK	0x08	    /* set previous context mark */
+#define SP_START	0x10	    /* accept match at start position */
+#define SP_SUBPAT	0x20	    /* return nr of matching sub-pattern */
+#define SP_END		0x40	    /* leave cursor at end of match */
+
+static int get_search_arg __ARGS((typval_T *varp, int *flagsp));
+
+/*
+ * Get flags for a search function.
+ * Possibly sets "p_ws".
+ * Returns BACKWARD, FORWARD or zero (for an error).
+ */
+    static int
+get_search_arg(varp, flagsp)
+    typval_T	*varp;
+    int		*flagsp;
+{
+    int		dir = FORWARD;
+    char_u	*flags;
+    char_u	nbuf[NUMBUFLEN];
+    int		mask;
+
+    if (varp->v_type != VAR_UNKNOWN)
+    {
+	flags = get_tv_string_buf_chk(varp, nbuf);
+	if (flags == NULL)
+	    return 0;		/* type error; errmsg already given */
+	while (*flags != NUL)
+	{
+	    switch (*flags)
+	    {
+		case 'b': dir = BACKWARD; break;
+		case 'w': p_ws = TRUE; break;
+		case 'W': p_ws = FALSE; break;
+		default:  mask = 0;
+			  if (flagsp != NULL)
+			     switch (*flags)
+			     {
+				 case 'c': mask = SP_START; break;
+				 case 'e': mask = SP_END; break;
+				 case 'm': mask = SP_RETCOUNT; break;
+				 case 'n': mask = SP_NOMOVE; break;
+				 case 'p': mask = SP_SUBPAT; break;
+				 case 'r': mask = SP_REPEAT; break;
+				 case 's': mask = SP_SETPCMARK; break;
+			     }
+			  if (mask == 0)
+			  {
+			      EMSG2(_(e_invarg2), flags);
+			      dir = 0;
+			  }
+			  else
+			      *flagsp |= mask;
+	    }
+	    if (dir == 0)
+		break;
+	    ++flags;
+	}
+    }
+    return dir;
+}
+
+/*
+ * Shared by search() and searchpos() functions
+ */
+    static int
+search_cmn(argvars, match_pos, flagsp)
+    typval_T	*argvars;
+    pos_T	*match_pos;
+    int		*flagsp;
+{
+    int		flags;
+    char_u	*pat;
+    pos_T	pos;
+    pos_T	save_cursor;
+    int		save_p_ws = p_ws;
+    int		dir;
+    int		retval = 0;	/* default: FAIL */
+    long	lnum_stop = 0;
+    int		options = SEARCH_KEEP;
+    int		subpatnum;
+
+    pat = get_tv_string(&argvars[0]);
+    dir = get_search_arg(&argvars[1], flagsp);	/* may set p_ws */
+    if (dir == 0)
+	goto theend;
+    flags = *flagsp;
+    if (flags & SP_START)
+	options |= SEARCH_START;
+    if (flags & SP_END)
+	options |= SEARCH_END;
+
+    /* Optional extra argument: line number to stop searching. */
+    if (argvars[1].v_type != VAR_UNKNOWN
+	    && argvars[2].v_type != VAR_UNKNOWN)
+    {
+	lnum_stop = get_tv_number_chk(&argvars[2], NULL);
+	if (lnum_stop < 0)
+	    goto theend;
+    }
+
+    /*
+     * This function does not accept SP_REPEAT and SP_RETCOUNT flags.
+     * Check to make sure only those flags are set.
+     * Also, Only the SP_NOMOVE or the SP_SETPCMARK flag can be set. Both
+     * flags cannot be set. Check for that condition also.
+     */
+    if (((flags & (SP_REPEAT | SP_RETCOUNT)) != 0)
+	    || ((flags & SP_NOMOVE) && (flags & SP_SETPCMARK)))
+    {
+	EMSG2(_(e_invarg2), get_tv_string(&argvars[1]));
+	goto theend;
+    }
+
+    pos = save_cursor = curwin->w_cursor;
+    subpatnum = searchit(curwin, curbuf, &pos, dir, pat, 1L,
+				     options, RE_SEARCH, (linenr_T)lnum_stop);
+    if (subpatnum != FAIL)
+    {
+	if (flags & SP_SUBPAT)
+	    retval = subpatnum;
+	else
+	    retval = pos.lnum;
+	if (flags & SP_SETPCMARK)
+	    setpcmark();
+	curwin->w_cursor = pos;
+	if (match_pos != NULL)
+	{
+	    /* Store the match cursor position */
+	    match_pos->lnum = pos.lnum;
+	    match_pos->col = pos.col + 1;
+	}
+	/* "/$" will put the cursor after the end of the line, may need to
+	 * correct that here */
+	check_cursor();
+    }
+
+    /* If 'n' flag is used: restore cursor position. */
+    if (flags & SP_NOMOVE)
+	curwin->w_cursor = save_cursor;
+theend:
+    p_ws = save_p_ws;
+
+    return retval;
+}
+
+/*
+ * "search()" function
+ */
+    static void
+f_search(argvars, rettv)
+    typval_T	*argvars;
+    typval_T	*rettv;
+{
+    int		flags = 0;
+
+    rettv->vval.v_number = search_cmn(argvars, NULL, &flags);
+}
+
+/*
+ * "searchdecl()" function
+ */
+    static void
+f_searchdecl(argvars, rettv)
+    typval_T	*argvars;
+    typval_T	*rettv;
+{
+    int		locally = 1;
+    int		thisblock = 0;
+    int		error = FALSE;
+    char_u	*name;
+
+    rettv->vval.v_number = 1;	/* default: FAIL */
+
+    name = get_tv_string_chk(&argvars[0]);
+    if (argvars[1].v_type != VAR_UNKNOWN)
+    {
+	locally = get_tv_number_chk(&argvars[1], &error) == 0;
+	if (!error && argvars[2].v_type != VAR_UNKNOWN)
+	    thisblock = get_tv_number_chk(&argvars[2], &error) != 0;
+    }
+    if (!error && name != NULL)
+	rettv->vval.v_number = find_decl(name, (int)STRLEN(name),
+				     locally, thisblock, SEARCH_KEEP) == FAIL;
+}
+
+/*
+ * Used by searchpair() and searchpairpos()
+ */
+    static int
+searchpair_cmn(argvars, match_pos)
+    typval_T	*argvars;
+    pos_T	*match_pos;
+{
+    char_u	*spat, *mpat, *epat;
+    char_u	*skip;
+    int		save_p_ws = p_ws;
+    int		dir;
+    int		flags = 0;
+    char_u	nbuf1[NUMBUFLEN];
+    char_u	nbuf2[NUMBUFLEN];
+    char_u	nbuf3[NUMBUFLEN];
+    int		retval = 0;		/* default: FAIL */
+    long	lnum_stop = 0;
+
+    /* Get the three pattern arguments: start, middle, end. */
+    spat = get_tv_string_chk(&argvars[0]);
+    mpat = get_tv_string_buf_chk(&argvars[1], nbuf1);
+    epat = get_tv_string_buf_chk(&argvars[2], nbuf2);
+    if (spat == NULL || mpat == NULL || epat == NULL)
+	goto theend;	    /* type error */
+
+    /* Handle the optional fourth argument: flags */
+    dir = get_search_arg(&argvars[3], &flags); /* may set p_ws */
+    if (dir == 0)
+	goto theend;
+
+    /* Don't accept SP_END or SP_SUBPAT.
+     * Only one of the SP_NOMOVE or SP_SETPCMARK flags can be set.
+     */
+    if ((flags & (SP_END | SP_SUBPAT)) != 0
+	    || ((flags & SP_NOMOVE) && (flags & SP_SETPCMARK)))
+    {
+	EMSG2(_(e_invarg2), get_tv_string(&argvars[3]));
+	goto theend;
+    }
+
+    /* Optional fifth argument: skip expression */
+    if (argvars[3].v_type == VAR_UNKNOWN
+	    || argvars[4].v_type == VAR_UNKNOWN)
+	skip = (char_u *)"";
+    else
+    {
+	skip = get_tv_string_buf_chk(&argvars[4], nbuf3);
+	if (argvars[5].v_type != VAR_UNKNOWN)
+	{
+	    lnum_stop = get_tv_number_chk(&argvars[5], NULL);
+	    if (lnum_stop < 0)
+		goto theend;
+	}
+    }
+    if (skip == NULL)
+	goto theend;	    /* type error */
+
+    retval = do_searchpair(spat, mpat, epat, dir, skip, flags,
+							match_pos, lnum_stop);
+
+theend:
+    p_ws = save_p_ws;
+
+    return retval;
+}
+
+/*
+ * "searchpair()" function
+ */
+    static void
+f_searchpair(argvars, rettv)
+    typval_T	*argvars;
+    typval_T	*rettv;
+{
+    rettv->vval.v_number = searchpair_cmn(argvars, NULL);
+}
+
+/*
+ * "searchpairpos()" function
+ */
+    static void
+f_searchpairpos(argvars, rettv)
+    typval_T	*argvars;
+    typval_T	*rettv;
+{
+    pos_T	match_pos;
+    int		lnum = 0;
+    int		col = 0;
+
+    rettv->vval.v_number = 0;
+
+    if (rettv_list_alloc(rettv) == FAIL)
+	return;
+
+    if (searchpair_cmn(argvars, &match_pos) > 0)
+    {
+	lnum = match_pos.lnum;
+	col = match_pos.col;
+    }
+
+    list_append_number(rettv->vval.v_list, (varnumber_T)lnum);
+    list_append_number(rettv->vval.v_list, (varnumber_T)col);
+}
+
+/*
+ * Search for a start/middle/end thing.
+ * Used by searchpair(), see its documentation for the details.
+ * Returns 0 or -1 for no match,
+ */
+    long
+do_searchpair(spat, mpat, epat, dir, skip, flags, match_pos, lnum_stop)
+    char_u	*spat;	    /* start pattern */
+    char_u	*mpat;	    /* middle pattern */
+    char_u	*epat;	    /* end pattern */
+    int		dir;	    /* BACKWARD or FORWARD */
+    char_u	*skip;	    /* skip expression */
+    int		flags;	    /* SP_SETPCMARK and other SP_ values */
+    pos_T	*match_pos;
+    linenr_T	lnum_stop;  /* stop at this line if not zero */
+{
+    char_u	*save_cpo;
+    char_u	*pat, *pat2 = NULL, *pat3 = NULL;
+    long	retval = 0;
+    pos_T	pos;
+    pos_T	firstpos;
+    pos_T	foundpos;
+    pos_T	save_cursor;
+    pos_T	save_pos;
+    int		n;
+    int		r;
+    int		nest = 1;
+    int		err;
+    int		options = SEARCH_KEEP;
+
+    /* Make 'cpoptions' empty, the 'l' flag should not be used here. */
+    save_cpo = p_cpo;
+    p_cpo = (char_u *)"";
+
+    /* Make two search patterns: start/end (pat2, for in nested pairs) and
+     * start/middle/end (pat3, for the top pair). */
+    pat2 = alloc((unsigned)(STRLEN(spat) + STRLEN(epat) + 15));
+    pat3 = alloc((unsigned)(STRLEN(spat) + STRLEN(mpat) + STRLEN(epat) + 23));
+    if (pat2 == NULL || pat3 == NULL)
+	goto theend;
+    sprintf((char *)pat2, "\\(%s\\m\\)\\|\\(%s\\m\\)", spat, epat);
+    if (*mpat == NUL)
+	STRCPY(pat3, pat2);
+    else
+	sprintf((char *)pat3, "\\(%s\\m\\)\\|\\(%s\\m\\)\\|\\(%s\\m\\)",
+							    spat, epat, mpat);
+    if (flags & SP_START)
+	options |= SEARCH_START;
+
+    save_cursor = curwin->w_cursor;
+    pos = curwin->w_cursor;
+    clearpos(&firstpos);
+    clearpos(&foundpos);
+    pat = pat3;
+    for (;;)
+    {
+	n = searchit(curwin, curbuf, &pos, dir, pat, 1L,
+					       options, RE_SEARCH, lnum_stop);
+	if (n == FAIL || (firstpos.lnum != 0 && equalpos(pos, firstpos)))
+	    /* didn't find it or found the first match again: FAIL */
+	    break;
+
+	if (firstpos.lnum == 0)
+	    firstpos = pos;
+	if (equalpos(pos, foundpos))
+	{
+	    /* Found the same position again.  Can happen with a pattern that
+	     * has "\zs" at the end and searching backwards.  Advance one
+	     * character and try again. */
+	    if (dir == BACKWARD)
+		decl(&pos);
+	    else
+		incl(&pos);
+	}
+	foundpos = pos;
+
+	/* If the skip pattern matches, ignore this match. */
+	if (*skip != NUL)
+	{
+	    save_pos = curwin->w_cursor;
+	    curwin->w_cursor = pos;
+	    r = eval_to_bool(skip, &err, NULL, FALSE);
+	    curwin->w_cursor = save_pos;
+	    if (err)
+	    {
+		/* Evaluating {skip} caused an error, break here. */
+		curwin->w_cursor = save_cursor;
+		retval = -1;
+		break;
+	    }
+	    if (r)
+		continue;
+	}
+
+	if ((dir == BACKWARD && n == 3) || (dir == FORWARD && n == 2))
+	{
+	    /* Found end when searching backwards or start when searching
+	     * forward: nested pair. */
+	    ++nest;
+	    pat = pat2;		/* nested, don't search for middle */
+	}
+	else
+	{
+	    /* Found end when searching forward or start when searching
+	     * backward: end of (nested) pair; or found middle in outer pair. */
+	    if (--nest == 1)
+		pat = pat3;	/* outer level, search for middle */
+	}
+
+	if (nest == 0)
+	{
+	    /* Found the match: return matchcount or line number. */
+	    if (flags & SP_RETCOUNT)
+		++retval;
+	    else
+		retval = pos.lnum;
+	    if (flags & SP_SETPCMARK)
+		setpcmark();
+	    curwin->w_cursor = pos;
+	    if (!(flags & SP_REPEAT))
+		break;
+	    nest = 1;	    /* search for next unmatched */
+	}
+    }
+
+    if (match_pos != NULL)
+    {
+	/* Store the match cursor position */
+	match_pos->lnum = curwin->w_cursor.lnum;
+	match_pos->col = curwin->w_cursor.col + 1;
+    }
+
+    /* If 'n' flag is used or search failed: restore cursor position. */
+    if ((flags & SP_NOMOVE) || retval == 0)
+	curwin->w_cursor = save_cursor;
+
+theend:
+    vim_free(pat2);
+    vim_free(pat3);
+    p_cpo = save_cpo;
+
+    return retval;
+}
+
+/*
+ * "searchpos()" function
+ */
+    static void
+f_searchpos(argvars, rettv)
+    typval_T	*argvars;
+    typval_T	*rettv;
+{
+    pos_T	match_pos;
+    int		lnum = 0;
+    int		col = 0;
+    int		n;
+    int		flags = 0;
+
+    rettv->vval.v_number = 0;
+
+    if (rettv_list_alloc(rettv) == FAIL)
+	return;
+
+    n = search_cmn(argvars, &match_pos, &flags);
+    if (n > 0)
+    {
+	lnum = match_pos.lnum;
+	col = match_pos.col;
+    }
+
+    list_append_number(rettv->vval.v_list, (varnumber_T)lnum);
+    list_append_number(rettv->vval.v_list, (varnumber_T)col);
+    if (flags & SP_SUBPAT)
+	list_append_number(rettv->vval.v_list, (varnumber_T)n);
+}
+
+
+/*ARGSUSED*/
+    static void
+f_server2client(argvars, rettv)
+    typval_T	*argvars;
+    typval_T	*rettv;
+{
+#ifdef FEAT_CLIENTSERVER
+    char_u	buf[NUMBUFLEN];
+    char_u	*server = get_tv_string_chk(&argvars[0]);
+    char_u	*reply = get_tv_string_buf_chk(&argvars[1], buf);
+
+    rettv->vval.v_number = -1;
+    if (server == NULL || reply == NULL)
+	return;
+    if (check_restricted() || check_secure())
+	return;
+# ifdef FEAT_X11
+    if (check_connection() == FAIL)
+	return;
+# endif
+
+    if (serverSendReply(server, reply) < 0)
+    {
+	EMSG(_("E258: Unable to send to client"));
+	return;
+    }
+    rettv->vval.v_number = 0;
+#else
+    rettv->vval.v_number = -1;
+#endif
+}
+
+/*ARGSUSED*/
+    static void
+f_serverlist(argvars, rettv)
+    typval_T	*argvars;
+    typval_T	*rettv;
+{
+    char_u	*r = NULL;
+
+#ifdef FEAT_CLIENTSERVER
+# ifdef WIN32
+    r = serverGetVimNames();
+# else
+    make_connection();
+    if (X_DISPLAY != NULL)
+	r = serverGetVimNames(X_DISPLAY);
+# endif
+#endif
+    rettv->v_type = VAR_STRING;
+    rettv->vval.v_string = r;
+}
+
+/*
+ * "setbufvar()" function
+ */
+/*ARGSUSED*/
+    static void
+f_setbufvar(argvars, rettv)
+    typval_T	*argvars;
+    typval_T	*rettv;
+{
+    buf_T	*buf;
+    aco_save_T	aco;
+    char_u	*varname, *bufvarname;
+    typval_T	*varp;
+    char_u	nbuf[NUMBUFLEN];
+
+    rettv->vval.v_number = 0;
+
+    if (check_restricted() || check_secure())
+	return;
+    (void)get_tv_number(&argvars[0]);	    /* issue errmsg if type error */
+    varname = get_tv_string_chk(&argvars[1]);
+    buf = get_buf_tv(&argvars[0]);
+    varp = &argvars[2];
+
+    if (buf != NULL && varname != NULL && varp != NULL)
+    {
+	/* set curbuf to be our buf, temporarily */
+	aucmd_prepbuf(&aco, buf);
+
+	if (*varname == '&')
+	{
+	    long	numval;
+	    char_u	*strval;
+	    int		error = FALSE;
+
+	    ++varname;
+	    numval = get_tv_number_chk(varp, &error);
+	    strval = get_tv_string_buf_chk(varp, nbuf);
+	    if (!error && strval != NULL)
+		set_option_value(varname, numval, strval, OPT_LOCAL);
+	}
+	else
+	{
+	    bufvarname = alloc((unsigned)STRLEN(varname) + 3);
+	    if (bufvarname != NULL)
+	    {
+		STRCPY(bufvarname, "b:");
+		STRCPY(bufvarname + 2, varname);
+		set_var(bufvarname, varp, TRUE);
+		vim_free(bufvarname);
+	    }
+	}
+
+	/* reset notion of buffer */
+	aucmd_restbuf(&aco);
+    }
+}
+
+/*
+ * "setcmdpos()" function
+ */
+    static void
+f_setcmdpos(argvars, rettv)
+    typval_T	*argvars;
+    typval_T	*rettv;
+{
+    int		pos = (int)get_tv_number(&argvars[0]) - 1;
+
+    if (pos >= 0)
+	rettv->vval.v_number = set_cmdline_pos(pos);
+}
+
+/*
+ * "setline()" function
+ */
+    static void
+f_setline(argvars, rettv)
+    typval_T	*argvars;
+    typval_T	*rettv;
+{
+    linenr_T	lnum;
+    char_u	*line = NULL;
+    list_T	*l = NULL;
+    listitem_T	*li = NULL;
+    long	added = 0;
+    linenr_T	lcount = curbuf->b_ml.ml_line_count;
+
+    lnum = get_tv_lnum(&argvars[0]);
+    if (argvars[1].v_type == VAR_LIST)
+    {
+	l = argvars[1].vval.v_list;
+	li = l->lv_first;
+    }
+    else
+	line = get_tv_string_chk(&argvars[1]);
+
+    rettv->vval.v_number = 0;		/* OK */
+    for (;;)
+    {
+	if (l != NULL)
+	{
+	    /* list argument, get next string */
+	    if (li == NULL)
+		break;
+	    line = get_tv_string_chk(&li->li_tv);
+	    li = li->li_next;
+	}
+
+	rettv->vval.v_number = 1;	/* FAIL */
+	if (line == NULL || lnum < 1 || lnum > curbuf->b_ml.ml_line_count + 1)
+	    break;
+	if (lnum <= curbuf->b_ml.ml_line_count)
+	{
+	    /* existing line, replace it */
+	    if (u_savesub(lnum) == OK && ml_replace(lnum, line, TRUE) == OK)
+	    {
+		changed_bytes(lnum, 0);
+		if (lnum == curwin->w_cursor.lnum)
+		    check_cursor_col();
+		rettv->vval.v_number = 0;	/* OK */
+	    }
+	}
+	else if (added > 0 || u_save(lnum - 1, lnum) == OK)
+	{
+	    /* lnum is one past the last line, append the line */
+	    ++added;
+	    if (ml_append(lnum - 1, line, (colnr_T)0, FALSE) == OK)
+		rettv->vval.v_number = 0;	/* OK */
+	}
+
+	if (l == NULL)			/* only one string argument */
+	    break;
+	++lnum;
+    }
+
+    if (added > 0)
+	appended_lines_mark(lcount, added);
+}
+
+/*
+ * Used by "setqflist()" and "setloclist()" functions
+ */
+/*ARGSUSED*/
+    static void
+set_qf_ll_list(wp, list_arg, action_arg, rettv)
+    win_T	*wp;
+    typval_T	*list_arg;
+    typval_T	*action_arg;
+    typval_T	*rettv;
+{
+#ifdef FEAT_QUICKFIX
+    char_u	*act;
+    int		action = ' ';
+#endif
+
+    rettv->vval.v_number = -1;
+
+#ifdef FEAT_QUICKFIX
+    if (list_arg->v_type != VAR_LIST)
+	EMSG(_(e_listreq));
+    else
+    {
+	list_T  *l = list_arg->vval.v_list;
+
+	if (action_arg->v_type == VAR_STRING)
+	{
+	    act = get_tv_string_chk(action_arg);
+	    if (act == NULL)
+		return;		/* type error; errmsg already given */
+	    if (*act == 'a' || *act == 'r')
+		action = *act;
+	}
+
+	if (l != NULL && set_errorlist(wp, l, action) == OK)
+	    rettv->vval.v_number = 0;
+    }
+#endif
+}
+
+/*
+ * "setloclist()" function
+ */
+/*ARGSUSED*/
+    static void
+f_setloclist(argvars, rettv)
+    typval_T	*argvars;
+    typval_T	*rettv;
+{
+    win_T	*win;
+
+    rettv->vval.v_number = -1;
+
+    win = find_win_by_nr(&argvars[0], NULL);
+    if (win != NULL)
+	set_qf_ll_list(win, &argvars[1], &argvars[2], rettv);
+}
+
+/*
+ * "setpos()" function
+ */
+/*ARGSUSED*/
+    static void
+f_setpos(argvars, rettv)
+    typval_T	*argvars;
+    typval_T	*rettv;
+{
+    pos_T	pos;
+    int		fnum;
+    char_u	*name;
+
+    name = get_tv_string_chk(argvars);
+    if (name != NULL)
+    {
+	if (list2fpos(&argvars[1], &pos, &fnum) == OK)
+	{
+	    --pos.col;
+	    if (name[0] == '.')		/* cursor */
+	    {
+		if (fnum == curbuf->b_fnum)
+		{
+		    curwin->w_cursor = pos;
+		    check_cursor();
+		}
+		else
+		    EMSG(_(e_invarg));
+	    }
+	    else if (name[0] == '\'')	/* mark */
+		(void)setmark_pos(name[1], &pos, fnum);
+	    else
+		EMSG(_(e_invarg));
+	}
+    }
+}
+
+/*
+ * "setqflist()" function
+ */
+/*ARGSUSED*/
+    static void
+f_setqflist(argvars, rettv)
+    typval_T	*argvars;
+    typval_T	*rettv;
+{
+    set_qf_ll_list(NULL, &argvars[0], &argvars[1], rettv);
+}
+
+/*
+ * "setreg()" function
+ */
+    static void
+f_setreg(argvars, rettv)
+    typval_T	*argvars;
+    typval_T	*rettv;
+{
+    int		regname;
+    char_u	*strregname;
+    char_u	*stropt;
+    char_u	*strval;
+    int		append;
+    char_u	yank_type;
+    long	block_len;
+
+    block_len = -1;
+    yank_type = MAUTO;
+    append = FALSE;
+
+    strregname = get_tv_string_chk(argvars);
+    rettv->vval.v_number = 1;		/* FAIL is default */
+
+    if (strregname == NULL)
+	return;		/* type error; errmsg already given */
+    regname = *strregname;
+    if (regname == 0 || regname == '@')
+	regname = '"';
+    else if (regname == '=')
+	return;
+
+    if (argvars[2].v_type != VAR_UNKNOWN)
+    {
+	stropt = get_tv_string_chk(&argvars[2]);
+	if (stropt == NULL)
+	    return;		/* type error */
+	for (; *stropt != NUL; ++stropt)
+	    switch (*stropt)
+	    {
+		case 'a': case 'A':	/* append */
+		    append = TRUE;
+		    break;
+		case 'v': case 'c':	/* character-wise selection */
+		    yank_type = MCHAR;
+		    break;
+		case 'V': case 'l':	/* line-wise selection */
+		    yank_type = MLINE;
+		    break;
+#ifdef FEAT_VISUAL
+		case 'b': case Ctrl_V:	/* block-wise selection */
+		    yank_type = MBLOCK;
+		    if (VIM_ISDIGIT(stropt[1]))
+		    {
+			++stropt;
+			block_len = getdigits(&stropt) - 1;
+			--stropt;
+		    }
+		    break;
+#endif
+	    }
+    }
+
+    strval = get_tv_string_chk(&argvars[1]);
+    if (strval != NULL)
+	write_reg_contents_ex(regname, strval, -1,
+						append, yank_type, block_len);
+    rettv->vval.v_number = 0;
+}
+
+/*
+ * "settabwinvar()" function
+ */
+    static void
+f_settabwinvar(argvars, rettv)
+    typval_T	*argvars;
+    typval_T	*rettv;
+{
+    setwinvar(argvars, rettv, 1);
+}
+
+/*
+ * "setwinvar()" function
+ */
+    static void
+f_setwinvar(argvars, rettv)
+    typval_T	*argvars;
+    typval_T	*rettv;
+{
+    setwinvar(argvars, rettv, 0);
+}
+
+/*
+ * "setwinvar()" and "settabwinvar()" functions
+ */
+    static void
+setwinvar(argvars, rettv, off)
+    typval_T	*argvars;
+    typval_T	*rettv;
+    int		off;
+{
+    win_T	*win;
+#ifdef FEAT_WINDOWS
+    win_T	*save_curwin;
+    tabpage_T	*save_curtab;
+#endif
+    char_u	*varname, *winvarname;
+    typval_T	*varp;
+    char_u	nbuf[NUMBUFLEN];
+    tabpage_T	*tp;
+
+    rettv->vval.v_number = 0;
+
+    if (check_restricted() || check_secure())
+	return;
+
+#ifdef FEAT_WINDOWS
+    if (off == 1)
+	tp = find_tabpage((int)get_tv_number_chk(&argvars[0], NULL));
+    else
+	tp = curtab;
+#endif
+    win = find_win_by_nr(&argvars[off], tp);
+    varname = get_tv_string_chk(&argvars[off + 1]);
+    varp = &argvars[off + 2];
+
+    if (win != NULL && varname != NULL && varp != NULL)
+    {
+#ifdef FEAT_WINDOWS
+	/* set curwin to be our win, temporarily */
+	save_curwin = curwin;
+	save_curtab = curtab;
+	goto_tabpage_tp(tp);
+	if (!win_valid(win))
+	    return;
+	curwin = win;
+	curbuf = curwin->w_buffer;
+#endif
+
+	if (*varname == '&')
+	{
+	    long	numval;
+	    char_u	*strval;
+	    int		error = FALSE;
+
+	    ++varname;
+	    numval = get_tv_number_chk(varp, &error);
+	    strval = get_tv_string_buf_chk(varp, nbuf);
+	    if (!error && strval != NULL)
+		set_option_value(varname, numval, strval, OPT_LOCAL);
+	}
+	else
+	{
+	    winvarname = alloc((unsigned)STRLEN(varname) + 3);
+	    if (winvarname != NULL)
+	    {
+		STRCPY(winvarname, "w:");
+		STRCPY(winvarname + 2, varname);
+		set_var(winvarname, varp, TRUE);
+		vim_free(winvarname);
+	    }
+	}
+
+#ifdef FEAT_WINDOWS
+	/* Restore current tabpage and window, if still valid (autocomands can
+	 * make them invalid). */
+	if (valid_tabpage(save_curtab))
+	    goto_tabpage_tp(save_curtab);
+	if (win_valid(save_curwin))
+	{
+	    curwin = save_curwin;
+	    curbuf = curwin->w_buffer;
+	}
+#endif
+    }
+}
+
+/*
+ * "shellescape({string})" function
+ */
+    static void
+f_shellescape(argvars, rettv)
+    typval_T	*argvars;
+    typval_T	*rettv;
+{
+    rettv->vval.v_string = vim_strsave_shellescape(get_tv_string(&argvars[0]));
+    rettv->v_type = VAR_STRING;
+}
+
+/*
+ * "simplify()" function
+ */
+    static void
+f_simplify(argvars, rettv)
+    typval_T	*argvars;
+    typval_T	*rettv;
+{
+    char_u	*p;
+
+    p = get_tv_string(&argvars[0]);
+    rettv->vval.v_string = vim_strsave(p);
+    simplify_filename(rettv->vval.v_string);	/* simplify in place */
+    rettv->v_type = VAR_STRING;
+}
+
+static int
+#ifdef __BORLANDC__
+    _RTLENTRYF
+#endif
+	item_compare __ARGS((const void *s1, const void *s2));
+static int
+#ifdef __BORLANDC__
+    _RTLENTRYF
+#endif
+	item_compare2 __ARGS((const void *s1, const void *s2));
+
+static int	item_compare_ic;
+static char_u	*item_compare_func;
+static int	item_compare_func_err;
+#define ITEM_COMPARE_FAIL 999
+
+/*
+ * Compare functions for f_sort() below.
+ */
+    static int
+#ifdef __BORLANDC__
+_RTLENTRYF
+#endif
+item_compare(s1, s2)
+    const void	*s1;
+    const void	*s2;
+{
+    char_u	*p1, *p2;
+    char_u	*tofree1, *tofree2;
+    int		res;
+    char_u	numbuf1[NUMBUFLEN];
+    char_u	numbuf2[NUMBUFLEN];
+
+    p1 = tv2string(&(*(listitem_T **)s1)->li_tv, &tofree1, numbuf1, 0);
+    p2 = tv2string(&(*(listitem_T **)s2)->li_tv, &tofree2, numbuf2, 0);
+    if (item_compare_ic)
+	res = STRICMP(p1, p2);
+    else
+	res = STRCMP(p1, p2);
+    vim_free(tofree1);
+    vim_free(tofree2);
+    return res;
+}
+
+    static int
+#ifdef __BORLANDC__
+_RTLENTRYF
+#endif
+item_compare2(s1, s2)
+    const void	*s1;
+    const void	*s2;
+{
+    int		res;
+    typval_T	rettv;
+    typval_T	argv[3];
+    int		dummy;
+
+    /* shortcut after failure in previous call; compare all items equal */
+    if (item_compare_func_err)
+	return 0;
+
+    /* copy the values.  This is needed to be able to set v_lock to VAR_FIXED
+     * in the copy without changing the original list items. */
+    copy_tv(&(*(listitem_T **)s1)->li_tv, &argv[0]);
+    copy_tv(&(*(listitem_T **)s2)->li_tv, &argv[1]);
+
+    rettv.v_type = VAR_UNKNOWN;		/* clear_tv() uses this */
+    res = call_func(item_compare_func, (int)STRLEN(item_compare_func),
+				 &rettv, 2, argv, 0L, 0L, &dummy, TRUE, NULL);
+    clear_tv(&argv[0]);
+    clear_tv(&argv[1]);
+
+    if (res == FAIL)
+	res = ITEM_COMPARE_FAIL;
+    else
+	/* return value has wrong type */
+	res = get_tv_number_chk(&rettv, &item_compare_func_err);
+    if (item_compare_func_err)
+	res = ITEM_COMPARE_FAIL;
+    clear_tv(&rettv);
+    return res;
+}
+
+/*
+ * "sort({list})" function
+ */
+    static void
+f_sort(argvars, rettv)
+    typval_T	*argvars;
+    typval_T	*rettv;
+{
+    list_T	*l;
+    listitem_T	*li;
+    listitem_T	**ptrs;
+    long	len;
+    long	i;
+
+    rettv->vval.v_number = 0;
+    if (argvars[0].v_type != VAR_LIST)
+	EMSG2(_(e_listarg), "sort()");
+    else
+    {
+	l = argvars[0].vval.v_list;
+	if (l == NULL || tv_check_lock(l->lv_lock, (char_u *)"sort()"))
+	    return;
+	rettv->vval.v_list = l;
+	rettv->v_type = VAR_LIST;
+	++l->lv_refcount;
+
+	len = list_len(l);
+	if (len <= 1)
+	    return;	/* short list sorts pretty quickly */
+
+	item_compare_ic = FALSE;
+	item_compare_func = NULL;
+	if (argvars[1].v_type != VAR_UNKNOWN)
+	{
+	    if (argvars[1].v_type == VAR_FUNC)
+		item_compare_func = argvars[1].vval.v_string;
+	    else
+	    {
+		int	    error = FALSE;
+
+		i = get_tv_number_chk(&argvars[1], &error);
+		if (error)
+		    return;		/* type error; errmsg already given */
+		if (i == 1)
+		    item_compare_ic = TRUE;
+		else
+		    item_compare_func = get_tv_string(&argvars[1]);
+	    }
+	}
+
+	/* Make an array with each entry pointing to an item in the List. */
+	ptrs = (listitem_T **)alloc((int)(len * sizeof(listitem_T *)));
+	if (ptrs == NULL)
+	    return;
+	i = 0;
+	for (li = l->lv_first; li != NULL; li = li->li_next)
+	    ptrs[i++] = li;
+
+	item_compare_func_err = FALSE;
+	/* test the compare function */
+	if (item_compare_func != NULL
+		&& item_compare2((void *)&ptrs[0], (void *)&ptrs[1])
+							 == ITEM_COMPARE_FAIL)
+	    EMSG(_("E702: Sort compare function failed"));
+	else
+	{
+	    /* Sort the array with item pointers. */
+	    qsort((void *)ptrs, (size_t)len, sizeof(listitem_T *),
+		    item_compare_func == NULL ? item_compare : item_compare2);
+
+	    if (!item_compare_func_err)
+	    {
+		/* Clear the List and append the items in the sorted order. */
+		l->lv_first = l->lv_last = NULL;
+		l->lv_len = 0;
+		for (i = 0; i < len; ++i)
+		    list_append(l, ptrs[i]);
+	    }
+	}
+
+	vim_free(ptrs);
+    }
+}
+
+/*
+ * "soundfold({word})" function
+ */
+    static void
+f_soundfold(argvars, rettv)
+    typval_T	*argvars;
+    typval_T	*rettv;
+{
+    char_u	*s;
+
+    rettv->v_type = VAR_STRING;
+    s = get_tv_string(&argvars[0]);
+#ifdef FEAT_SPELL
+    rettv->vval.v_string = eval_soundfold(s);
+#else
+    rettv->vval.v_string = vim_strsave(s);
+#endif
+}
+
+/*
+ * "spellbadword()" function
+ */
+/* ARGSUSED */
+    static void
+f_spellbadword(argvars, rettv)
+    typval_T	*argvars;
+    typval_T	*rettv;
+{
+    char_u	*word = (char_u *)"";
+    hlf_T	attr = HLF_COUNT;
+    int		len = 0;
+
+    if (rettv_list_alloc(rettv) == FAIL)
+	return;
+
+#ifdef FEAT_SPELL
+    if (argvars[0].v_type == VAR_UNKNOWN)
+    {
+	/* Find the start and length of the badly spelled word. */
+	len = spell_move_to(curwin, FORWARD, TRUE, TRUE, &attr);
+	if (len != 0)
+	    word = ml_get_cursor();
+    }
+    else if (curwin->w_p_spell && *curbuf->b_p_spl != NUL)
+    {
+	char_u	*str = get_tv_string_chk(&argvars[0]);
+	int	capcol = -1;
+
+	if (str != NULL)
+	{
+	    /* Check the argument for spelling. */
+	    while (*str != NUL)
+	    {
+		len = spell_check(curwin, str, &attr, &capcol, FALSE);
+		if (attr != HLF_COUNT)
+		{
+		    word = str;
+		    break;
+		}
+		str += len;
+	    }
+	}
+    }
+#endif
+
+    list_append_string(rettv->vval.v_list, word, len);
+    list_append_string(rettv->vval.v_list, (char_u *)(
+			attr == HLF_SPB ? "bad" :
+			attr == HLF_SPR ? "rare" :
+			attr == HLF_SPL ? "local" :
+			attr == HLF_SPC ? "caps" :
+			""), -1);
+}
+
+/*
+ * "spellsuggest()" function
+ */
+/*ARGSUSED*/
+    static void
+f_spellsuggest(argvars, rettv)
+    typval_T	*argvars;
+    typval_T	*rettv;
+{
+#ifdef FEAT_SPELL
+    char_u	*str;
+    int		typeerr = FALSE;
+    int		maxcount;
+    garray_T	ga;
+    int		i;
+    listitem_T	*li;
+    int		need_capital = FALSE;
+#endif
+
+    if (rettv_list_alloc(rettv) == FAIL)
+	return;
+
+#ifdef FEAT_SPELL
+    if (curwin->w_p_spell && *curbuf->b_p_spl != NUL)
+    {
+	str = get_tv_string(&argvars[0]);
+	if (argvars[1].v_type != VAR_UNKNOWN)
+	{
+	    maxcount = get_tv_number_chk(&argvars[1], &typeerr);
+	    if (maxcount <= 0)
+		return;
+	    if (argvars[2].v_type != VAR_UNKNOWN)
+	    {
+		need_capital = get_tv_number_chk(&argvars[2], &typeerr);
+		if (typeerr)
+		    return;
+	    }
+	}
+	else
+	    maxcount = 25;
+
+	spell_suggest_list(&ga, str, maxcount, need_capital, FALSE);
+
+	for (i = 0; i < ga.ga_len; ++i)
+	{
+	    str = ((char_u **)ga.ga_data)[i];
+
+	    li = listitem_alloc();
+	    if (li == NULL)
+		vim_free(str);
+	    else
+	    {
+		li->li_tv.v_type = VAR_STRING;
+		li->li_tv.v_lock = 0;
+		li->li_tv.vval.v_string = str;
+		list_append(rettv->vval.v_list, li);
+	    }
+	}
+	ga_clear(&ga);
+    }
+#endif
+}
+
+    static void
+f_split(argvars, rettv)
+    typval_T	*argvars;
+    typval_T	*rettv;
+{
+    char_u	*str;
+    char_u	*end;
+    char_u	*pat = NULL;
+    regmatch_T	regmatch;
+    char_u	patbuf[NUMBUFLEN];
+    char_u	*save_cpo;
+    int		match;
+    colnr_T	col = 0;
+    int		keepempty = FALSE;
+    int		typeerr = FALSE;
+
+    /* Make 'cpoptions' empty, the 'l' flag should not be used here. */
+    save_cpo = p_cpo;
+    p_cpo = (char_u *)"";
+
+    str = get_tv_string(&argvars[0]);
+    if (argvars[1].v_type != VAR_UNKNOWN)
+    {
+	pat = get_tv_string_buf_chk(&argvars[1], patbuf);
+	if (pat == NULL)
+	    typeerr = TRUE;
+	if (argvars[2].v_type != VAR_UNKNOWN)
+	    keepempty = get_tv_number_chk(&argvars[2], &typeerr);
+    }
+    if (pat == NULL || *pat == NUL)
+	pat = (char_u *)"[\\x01- ]\\+";
+
+    if (rettv_list_alloc(rettv) == FAIL)
+	return;
+    if (typeerr)
+	return;
+
+    regmatch.regprog = vim_regcomp(pat, RE_MAGIC + RE_STRING);
+    if (regmatch.regprog != NULL)
+    {
+	regmatch.rm_ic = FALSE;
+	while (*str != NUL || keepempty)
+	{
+	    if (*str == NUL)
+		match = FALSE;	/* empty item at the end */
+	    else
+		match = vim_regexec_nl(&regmatch, str, col);
+	    if (match)
+		end = regmatch.startp[0];
+	    else
+		end = str + STRLEN(str);
+	    if (keepempty || end > str || (rettv->vval.v_list->lv_len > 0
+			   && *str != NUL && match && end < regmatch.endp[0]))
+	    {
+		if (list_append_string(rettv->vval.v_list, str,
+						    (int)(end - str)) == FAIL)
+		    break;
+	    }
+	    if (!match)
+		break;
+	    /* Advance to just after the match. */
+	    if (regmatch.endp[0] > str)
+		col = 0;
+	    else
+	    {
+		/* Don't get stuck at the same match. */
+#ifdef FEAT_MBYTE
+		col = (*mb_ptr2len)(regmatch.endp[0]);
+#else
+		col = 1;
+#endif
+	    }
+	    str = regmatch.endp[0];
+	}
+
+	vim_free(regmatch.regprog);
+    }
+
+    p_cpo = save_cpo;
+}
+
+/*
+ * "str2nr()" function
+ */
+    static void
+f_str2nr(argvars, rettv)
+    typval_T	*argvars;
+    typval_T	*rettv;
+{
+    int		base = 10;
+    char_u	*p;
+    long	n;
+
+    if (argvars[1].v_type != VAR_UNKNOWN)
+    {
+	base = get_tv_number(&argvars[1]);
+	if (base != 8 && base != 10 && base != 16)
+	{
+	    EMSG(_(e_invarg));
+	    return;
+	}
+    }
+
+    p = skipwhite(get_tv_string(&argvars[0]));
+    vim_str2nr(p, NULL, NULL, base == 8 ? 2 : 0, base == 16 ? 2 : 0, &n, NULL);
+    rettv->vval.v_number = n;
+}
+
+#ifdef HAVE_STRFTIME
+/*
+ * "strftime({format}[, {time}])" function
+ */
+    static void
+f_strftime(argvars, rettv)
+    typval_T	*argvars;
+    typval_T	*rettv;
+{
+    char_u	result_buf[256];
+    struct tm	*curtime;
+    time_t	seconds;
+    char_u	*p;
+
+    rettv->v_type = VAR_STRING;
+
+    p = get_tv_string(&argvars[0]);
+    if (argvars[1].v_type == VAR_UNKNOWN)
+	seconds = time(NULL);
+    else
+	seconds = (time_t)get_tv_number(&argvars[1]);
+    curtime = localtime(&seconds);
+    /* MSVC returns NULL for an invalid value of seconds. */
+    if (curtime == NULL)
+	rettv->vval.v_string = vim_strsave((char_u *)_("(Invalid)"));
+    else
+    {
+# ifdef FEAT_MBYTE
+	vimconv_T   conv;
+	char_u	    *enc;
+
+	conv.vc_type = CONV_NONE;
+	enc = enc_locale();
+	convert_setup(&conv, p_enc, enc);
+	if (conv.vc_type != CONV_NONE)
+	    p = string_convert(&conv, p, NULL);
+# endif
+	if (p != NULL)
+	    (void)strftime((char *)result_buf, sizeof(result_buf),
+							  (char *)p, curtime);
+	else
+	    result_buf[0] = NUL;
+
+# ifdef FEAT_MBYTE
+	if (conv.vc_type != CONV_NONE)
+	    vim_free(p);
+	convert_setup(&conv, enc, p_enc);
+	if (conv.vc_type != CONV_NONE)
+	    rettv->vval.v_string = string_convert(&conv, result_buf, NULL);
+	else
+# endif
+	    rettv->vval.v_string = vim_strsave(result_buf);
+
+# ifdef FEAT_MBYTE
+	/* Release conversion descriptors */
+	convert_setup(&conv, NULL, NULL);
+	vim_free(enc);
+# endif
+    }
+}
+#endif
+
+/*
+ * "stridx()" function
+ */
+    static void
+f_stridx(argvars, rettv)
+    typval_T	*argvars;
+    typval_T	*rettv;
+{
+    char_u	buf[NUMBUFLEN];
+    char_u	*needle;
+    char_u	*haystack;
+    char_u	*save_haystack;
+    char_u	*pos;
+    int		start_idx;
+
+    needle = get_tv_string_chk(&argvars[1]);
+    save_haystack = haystack = get_tv_string_buf_chk(&argvars[0], buf);
+    rettv->vval.v_number = -1;
+    if (needle == NULL || haystack == NULL)
+	return;		/* type error; errmsg already given */
+
+    if (argvars[2].v_type != VAR_UNKNOWN)
+    {
+	int	    error = FALSE;
+
+	start_idx = get_tv_number_chk(&argvars[2], &error);
+	if (error || start_idx >= (int)STRLEN(haystack))
+	    return;
+	if (start_idx >= 0)
+	    haystack += start_idx;
+    }
+
+    pos	= (char_u *)strstr((char *)haystack, (char *)needle);
+    if (pos != NULL)
+	rettv->vval.v_number = (varnumber_T)(pos - save_haystack);
+}
+
+/*
+ * "string()" function
+ */
+    static void
+f_string(argvars, rettv)
+    typval_T	*argvars;
+    typval_T	*rettv;
+{
+    char_u	*tofree;
+    char_u	numbuf[NUMBUFLEN];
+
+    rettv->v_type = VAR_STRING;
+    rettv->vval.v_string = tv2string(&argvars[0], &tofree, numbuf, 0);
+    if (tofree == NULL)
+	rettv->vval.v_string = vim_strsave(rettv->vval.v_string);
+}
+
+/*
+ * "strlen()" function
+ */
+    static void
+f_strlen(argvars, rettv)
+    typval_T	*argvars;
+    typval_T	*rettv;
+{
+    rettv->vval.v_number = (varnumber_T)(STRLEN(
+					      get_tv_string(&argvars[0])));
+}
+
+/*
+ * "strpart()" function
+ */
+    static void
+f_strpart(argvars, rettv)
+    typval_T	*argvars;
+    typval_T	*rettv;
+{
+    char_u	*p;
+    int		n;
+    int		len;
+    int		slen;
+    int		error = FALSE;
+
+    p = get_tv_string(&argvars[0]);
+    slen = (int)STRLEN(p);
+
+    n = get_tv_number_chk(&argvars[1], &error);
+    if (error)
+	len = 0;
+    else if (argvars[2].v_type != VAR_UNKNOWN)
+	len = get_tv_number(&argvars[2]);
+    else
+	len = slen - n;	    /* default len: all bytes that are available. */
+
+    /*
+     * Only return the overlap between the specified part and the actual
+     * string.
+     */
+    if (n < 0)
+    {
+	len += n;
+	n = 0;
+    }
+    else if (n > slen)
+	n = slen;
+    if (len < 0)
+	len = 0;
+    else if (n + len > slen)
+	len = slen - n;
+
+    rettv->v_type = VAR_STRING;
+    rettv->vval.v_string = vim_strnsave(p + n, len);
+}
+
+/*
+ * "strridx()" function
+ */
+    static void
+f_strridx(argvars, rettv)
+    typval_T	*argvars;
+    typval_T	*rettv;
+{
+    char_u	buf[NUMBUFLEN];
+    char_u	*needle;
+    char_u	*haystack;
+    char_u	*rest;
+    char_u	*lastmatch = NULL;
+    int		haystack_len, end_idx;
+
+    needle = get_tv_string_chk(&argvars[1]);
+    haystack = get_tv_string_buf_chk(&argvars[0], buf);
+
+    rettv->vval.v_number = -1;
+    if (needle == NULL || haystack == NULL)
+	return;		/* type error; errmsg already given */
+
+    haystack_len = (int)STRLEN(haystack);
+    if (argvars[2].v_type != VAR_UNKNOWN)
+    {
+	/* Third argument: upper limit for index */
+	end_idx = get_tv_number_chk(&argvars[2], NULL);
+	if (end_idx < 0)
+	    return;	/* can never find a match */
+    }
+    else
+	end_idx = haystack_len;
+
+    if (*needle == NUL)
+    {
+	/* Empty string matches past the end. */
+	lastmatch = haystack + end_idx;
+    }
+    else
+    {
+	for (rest = haystack; *rest != '\0'; ++rest)
+	{
+	    rest = (char_u *)strstr((char *)rest, (char *)needle);
+	    if (rest == NULL || rest > haystack + end_idx)
+		break;
+	    lastmatch = rest;
+	}
+    }
+
+    if (lastmatch == NULL)
+	rettv->vval.v_number = -1;
+    else
+	rettv->vval.v_number = (varnumber_T)(lastmatch - haystack);
+}
+
+/*
+ * "strtrans()" function
+ */
+    static void
+f_strtrans(argvars, rettv)
+    typval_T	*argvars;
+    typval_T	*rettv;
+{
+    rettv->v_type = VAR_STRING;
+    rettv->vval.v_string = transstr(get_tv_string(&argvars[0]));
+}
+
+/*
+ * "submatch()" function
+ */
+    static void
+f_submatch(argvars, rettv)
+    typval_T	*argvars;
+    typval_T	*rettv;
+{
+    rettv->v_type = VAR_STRING;
+    rettv->vval.v_string =
+		    reg_submatch((int)get_tv_number_chk(&argvars[0], NULL));
+}
+
+/*
+ * "substitute()" function
+ */
+    static void
+f_substitute(argvars, rettv)
+    typval_T	*argvars;
+    typval_T	*rettv;
+{
+    char_u	patbuf[NUMBUFLEN];
+    char_u	subbuf[NUMBUFLEN];
+    char_u	flagsbuf[NUMBUFLEN];
+
+    char_u	*str = get_tv_string_chk(&argvars[0]);
+    char_u	*pat = get_tv_string_buf_chk(&argvars[1], patbuf);
+    char_u	*sub = get_tv_string_buf_chk(&argvars[2], subbuf);
+    char_u	*flg = get_tv_string_buf_chk(&argvars[3], flagsbuf);
+
+    rettv->v_type = VAR_STRING;
+    if (str == NULL || pat == NULL || sub == NULL || flg == NULL)
+	rettv->vval.v_string = NULL;
+    else
+	rettv->vval.v_string = do_string_sub(str, pat, sub, flg);
+}
+
+/*
+ * "synID(lnum, col, trans)" function
+ */
+/*ARGSUSED*/
+    static void
+f_synID(argvars, rettv)
+    typval_T	*argvars;
+    typval_T	*rettv;
+{
+    int		id = 0;
+#ifdef FEAT_SYN_HL
+    long	lnum;
+    long	col;
+    int		trans;
+    int		transerr = FALSE;
+
+    lnum = get_tv_lnum(argvars);		/* -1 on type error */
+    col = get_tv_number(&argvars[1]) - 1;	/* -1 on type error */
+    trans = get_tv_number_chk(&argvars[2], &transerr);
+
+    if (!transerr && lnum >= 1 && lnum <= curbuf->b_ml.ml_line_count
+	    && col >= 0 && col < (long)STRLEN(ml_get(lnum)))
+	id = syn_get_id(curwin, lnum, (colnr_T)col, trans, NULL);
+#endif
+
+    rettv->vval.v_number = id;
+}
+
+/*
+ * "synIDattr(id, what [, mode])" function
+ */
+/*ARGSUSED*/
+    static void
+f_synIDattr(argvars, rettv)
+    typval_T	*argvars;
+    typval_T	*rettv;
+{
+    char_u	*p = NULL;
+#ifdef FEAT_SYN_HL
+    int		id;
+    char_u	*what;
+    char_u	*mode;
+    char_u	modebuf[NUMBUFLEN];
+    int		modec;
+
+    id = get_tv_number(&argvars[0]);
+    what = get_tv_string(&argvars[1]);
+    if (argvars[2].v_type != VAR_UNKNOWN)
+    {
+	mode = get_tv_string_buf(&argvars[2], modebuf);
+	modec = TOLOWER_ASC(mode[0]);
+	if (modec != 't' && modec != 'c'
+#ifdef FEAT_GUI
+		&& modec != 'g'
+#endif
+		)
+	    modec = 0;	/* replace invalid with current */
+    }
+    else
+    {
+#ifdef FEAT_GUI
+	if (gui.in_use)
+	    modec = 'g';
+	else
+#endif
+	    if (t_colors > 1)
+	    modec = 'c';
+	else
+	    modec = 't';
+    }
+
+
+    switch (TOLOWER_ASC(what[0]))
+    {
+	case 'b':
+		if (TOLOWER_ASC(what[1]) == 'g')	/* bg[#] */
+		    p = highlight_color(id, what, modec);
+		else					/* bold */
+		    p = highlight_has_attr(id, HL_BOLD, modec);
+		break;
+
+	case 'f':					/* fg[#] */
+		p = highlight_color(id, what, modec);
+		break;
+
+	case 'i':
+		if (TOLOWER_ASC(what[1]) == 'n')	/* inverse */
+		    p = highlight_has_attr(id, HL_INVERSE, modec);
+		else					/* italic */
+		    p = highlight_has_attr(id, HL_ITALIC, modec);
+		break;
+
+	case 'n':					/* name */
+		p = get_highlight_name(NULL, id - 1);
+		break;
+
+	case 'r':					/* reverse */
+		p = highlight_has_attr(id, HL_INVERSE, modec);
+		break;
+
+	case 's':					/* standout */
+		p = highlight_has_attr(id, HL_STANDOUT, modec);
+		break;
+
+	case 'u':
+		if (STRLEN(what) <= 5 || TOLOWER_ASC(what[5]) != 'c')
+							/* underline */
+		    p = highlight_has_attr(id, HL_UNDERLINE, modec);
+		else
+							/* undercurl */
+		    p = highlight_has_attr(id, HL_UNDERCURL, modec);
+		break;
+    }
+
+    if (p != NULL)
+	p = vim_strsave(p);
+#endif
+    rettv->v_type = VAR_STRING;
+    rettv->vval.v_string = p;
+}
+
+/*
+ * "synIDtrans(id)" function
+ */
+/*ARGSUSED*/
+    static void
+f_synIDtrans(argvars, rettv)
+    typval_T	*argvars;
+    typval_T	*rettv;
+{
+    int		id;
+
+#ifdef FEAT_SYN_HL
+    id = get_tv_number(&argvars[0]);
+
+    if (id > 0)
+	id = syn_get_final_id(id);
+    else
+#endif
+	id = 0;
+
+    rettv->vval.v_number = id;
+}
+
+/*
+ * "system()" function
+ */
+    static void
+f_system(argvars, rettv)
+    typval_T	*argvars;
+    typval_T	*rettv;
+{
+    char_u	*res = NULL;
+    char_u	*p;
+    char_u	*infile = NULL;
+    char_u	buf[NUMBUFLEN];
+    int		err = FALSE;
+    FILE	*fd;
+
+    if (check_restricted() || check_secure())
+	return;
+
+    if (argvars[1].v_type != VAR_UNKNOWN)
+    {
+	/*
+	 * Write the string to a temp file, to be used for input of the shell
+	 * command.
+	 */
+	if ((infile = vim_tempname('i')) == NULL)
+	{
+	    EMSG(_(e_notmp));
+	    return;
+	}
+
+	fd = mch_fopen((char *)infile, WRITEBIN);
+	if (fd == NULL)
+	{
+	    EMSG2(_(e_notopen), infile);
+	    goto done;
+	}
+	p = get_tv_string_buf_chk(&argvars[1], buf);
+	if (p == NULL)
+	{
+	    fclose(fd);
+	    goto done;		/* type error; errmsg already given */
+	}
+	if (fwrite(p, STRLEN(p), 1, fd) != 1)
+	    err = TRUE;
+	if (fclose(fd) != 0)
+	    err = TRUE;
+	if (err)
+	{
+	    EMSG(_("E677: Error writing temp file"));
+	    goto done;
+	}
+    }
+
+    res = get_cmd_output(get_tv_string(&argvars[0]), infile,
+						 SHELL_SILENT | SHELL_COOKED);
+
+#ifdef USE_CR
+    /* translate <CR> into <NL> */
+    if (res != NULL)
+    {
+	char_u	*s;
+
+	for (s = res; *s; ++s)
+	{
+	    if (*s == CAR)
+		*s = NL;
+	}
+    }
+#else
+# ifdef USE_CRNL
+    /* translate <CR><NL> into <NL> */
+    if (res != NULL)
+    {
+	char_u	*s, *d;
+
+	d = res;
+	for (s = res; *s; ++s)
+	{
+	    if (s[0] == CAR && s[1] == NL)
+		++s;
+	    *d++ = *s;
+	}
+	*d = NUL;
+    }
+# endif
+#endif
+
+done:
+    if (infile != NULL)
+    {
+	mch_remove(infile);
+	vim_free(infile);
+    }
+    rettv->v_type = VAR_STRING;
+    rettv->vval.v_string = res;
+}
+
+/*
+ * "tabpagebuflist()" function
+ */
+/* ARGSUSED */
+    static void
+f_tabpagebuflist(argvars, rettv)
+    typval_T	*argvars;
+    typval_T	*rettv;
+{
+#ifndef FEAT_WINDOWS
+    rettv->vval.v_number = 0;
+#else
+    tabpage_T	*tp;
+    win_T	*wp = NULL;
+
+    if (argvars[0].v_type == VAR_UNKNOWN)
+	wp = firstwin;
+    else
+    {
+	tp = find_tabpage((int)get_tv_number(&argvars[0]));
+	if (tp != NULL)
+	    wp = (tp == curtab) ? firstwin : tp->tp_firstwin;
+    }
+    if (wp == NULL)
+	rettv->vval.v_number = 0;
+    else
+    {
+	if (rettv_list_alloc(rettv) == FAIL)
+	    rettv->vval.v_number = 0;
+	else
+	{
+	    for (; wp != NULL; wp = wp->w_next)
+		if (list_append_number(rettv->vval.v_list,
+						wp->w_buffer->b_fnum) == FAIL)
+		    break;
+	}
+    }
+#endif
+}
+
+
+/*
+ * "tabpagenr()" function
+ */
+/* ARGSUSED */
+    static void
+f_tabpagenr(argvars, rettv)
+    typval_T	*argvars;
+    typval_T	*rettv;
+{
+    int		nr = 1;
+#ifdef FEAT_WINDOWS
+    char_u	*arg;
+
+    if (argvars[0].v_type != VAR_UNKNOWN)
+    {
+	arg = get_tv_string_chk(&argvars[0]);
+	nr = 0;
+	if (arg != NULL)
+	{
+	    if (STRCMP(arg, "$") == 0)
+		nr = tabpage_index(NULL) - 1;
+	    else
+		EMSG2(_(e_invexpr2), arg);
+	}
+    }
+    else
+	nr = tabpage_index(curtab);
+#endif
+    rettv->vval.v_number = nr;
+}
+
+
+#ifdef FEAT_WINDOWS
+static int get_winnr __ARGS((tabpage_T *tp, typval_T *argvar));
+
+/*
+ * Common code for tabpagewinnr() and winnr().
+ */
+    static int
+get_winnr(tp, argvar)
+    tabpage_T	*tp;
+    typval_T	*argvar;
+{
+    win_T	*twin;
+    int		nr = 1;
+    win_T	*wp;
+    char_u	*arg;
+
+    twin = (tp == curtab) ? curwin : tp->tp_curwin;
+    if (argvar->v_type != VAR_UNKNOWN)
+    {
+	arg = get_tv_string_chk(argvar);
+	if (arg == NULL)
+	    nr = 0;		/* type error; errmsg already given */
+	else if (STRCMP(arg, "$") == 0)
+	    twin = (tp == curtab) ? lastwin : tp->tp_lastwin;
+	else if (STRCMP(arg, "#") == 0)
+	{
+	    twin = (tp == curtab) ? prevwin : tp->tp_prevwin;
+	    if (twin == NULL)
+		nr = 0;
+	}
+	else
+	{
+	    EMSG2(_(e_invexpr2), arg);
+	    nr = 0;
+	}
+    }
+
+    if (nr > 0)
+	for (wp = (tp == curtab) ? firstwin : tp->tp_firstwin;
+					      wp != twin; wp = wp->w_next)
+	{
+	    if (wp == NULL)
+	    {
+		/* didn't find it in this tabpage */
+		nr = 0;
+		break;
+	    }
+	    ++nr;
+	}
+    return nr;
+}
+#endif
+
+/*
+ * "tabpagewinnr()" function
+ */
+/* ARGSUSED */
+    static void
+f_tabpagewinnr(argvars, rettv)
+    typval_T	*argvars;
+    typval_T	*rettv;
+{
+    int		nr = 1;
+#ifdef FEAT_WINDOWS
+    tabpage_T	*tp;
+
+    tp = find_tabpage((int)get_tv_number(&argvars[0]));
+    if (tp == NULL)
+	nr = 0;
+    else
+	nr = get_winnr(tp, &argvars[1]);
+#endif
+    rettv->vval.v_number = nr;
+}
+
+
+/*
+ * "tagfiles()" function
+ */
+/*ARGSUSED*/
+    static void
+f_tagfiles(argvars, rettv)
+    typval_T	*argvars;
+    typval_T	*rettv;
+{
+    char_u	fname[MAXPATHL + 1];
+    tagname_T	tn;
+    int		first;
+
+    if (rettv_list_alloc(rettv) == FAIL)
+    {
+	rettv->vval.v_number = 0;
+	return;
+    }
+
+    for (first = TRUE; ; first = FALSE)
+	if (get_tagfname(&tn, first, fname) == FAIL
+		|| list_append_string(rettv->vval.v_list, fname, -1) == FAIL)
+	    break;
+    tagname_free(&tn);
+}
+
+/*
+ * "taglist()" function
+ */
+    static void
+f_taglist(argvars, rettv)
+    typval_T  *argvars;
+    typval_T  *rettv;
+{
+    char_u  *tag_pattern;
+
+    tag_pattern = get_tv_string(&argvars[0]);
+
+    rettv->vval.v_number = FALSE;
+    if (*tag_pattern == NUL)
+	return;
+
+    if (rettv_list_alloc(rettv) == OK)
+	(void)get_tags(rettv->vval.v_list, tag_pattern);
+}
+
+/*
+ * "tempname()" function
+ */
+/*ARGSUSED*/
+    static void
+f_tempname(argvars, rettv)
+    typval_T	*argvars;
+    typval_T	*rettv;
+{
+    static int	x = 'A';
+
+    rettv->v_type = VAR_STRING;
+    rettv->vval.v_string = vim_tempname(x);
+
+    /* Advance 'x' to use A-Z and 0-9, so that there are at least 34 different
+     * names.  Skip 'I' and 'O', they are used for shell redirection. */
+    do
+    {
+	if (x == 'Z')
+	    x = '0';
+	else if (x == '9')
+	    x = 'A';
+	else
+	{
+#ifdef EBCDIC
+	    if (x == 'I')
+		x = 'J';
+	    else if (x == 'R')
+		x = 'S';
+	    else
+#endif
+		++x;
+	}
+    } while (x == 'I' || x == 'O');
+}
+
+/*
+ * "test(list)" function: Just checking the walls...
+ */
+/*ARGSUSED*/
+    static void
+f_test(argvars, rettv)
+    typval_T	*argvars;
+    typval_T	*rettv;
+{
+    /* Used for unit testing.  Change the code below to your liking. */
+#if 0
+    listitem_T	*li;
+    list_T	*l;
+    char_u	*bad, *good;
+
+    if (argvars[0].v_type != VAR_LIST)
+	return;
+    l = argvars[0].vval.v_list;
+    if (l == NULL)
+	return;
+    li = l->lv_first;
+    if (li == NULL)
+	return;
+    bad = get_tv_string(&li->li_tv);
+    li = li->li_next;
+    if (li == NULL)
+	return;
+    good = get_tv_string(&li->li_tv);
+    rettv->vval.v_number = test_edit_score(bad, good);
+#endif
+}
+
+/*
+ * "tolower(string)" function
+ */
+    static void
+f_tolower(argvars, rettv)
+    typval_T	*argvars;
+    typval_T	*rettv;
+{
+    char_u	*p;
+
+    p = vim_strsave(get_tv_string(&argvars[0]));
+    rettv->v_type = VAR_STRING;
+    rettv->vval.v_string = p;
+
+    if (p != NULL)
+	while (*p != NUL)
+	{
+#ifdef FEAT_MBYTE
+	    int		l;
+
+	    if (enc_utf8)
+	    {
+		int c, lc;
+
+		c = utf_ptr2char(p);
+		lc = utf_tolower(c);
+		l = utf_ptr2len(p);
+		/* TODO: reallocate string when byte count changes. */
+		if (utf_char2len(lc) == l)
+		    utf_char2bytes(lc, p);
+		p += l;
+	    }
+	    else if (has_mbyte && (l = (*mb_ptr2len)(p)) > 1)
+		p += l;		/* skip multi-byte character */
+	    else
+#endif
+	    {
+		*p = TOLOWER_LOC(*p); /* note that tolower() can be a macro */
+		++p;
+	    }
+	}
+}
+
+/*
+ * "toupper(string)" function
+ */
+    static void
+f_toupper(argvars, rettv)
+    typval_T	*argvars;
+    typval_T	*rettv;
+{
+    rettv->v_type = VAR_STRING;
+    rettv->vval.v_string = strup_save(get_tv_string(&argvars[0]));
+}
+
+/*
+ * "tr(string, fromstr, tostr)" function
+ */
+    static void
+f_tr(argvars, rettv)
+    typval_T	*argvars;
+    typval_T	*rettv;
+{
+    char_u	*instr;
+    char_u	*fromstr;
+    char_u	*tostr;
+    char_u	*p;
+#ifdef FEAT_MBYTE
+    int		inlen;
+    int		fromlen;
+    int		tolen;
+    int		idx;
+    char_u	*cpstr;
+    int		cplen;
+    int		first = TRUE;
+#endif
+    char_u	buf[NUMBUFLEN];
+    char_u	buf2[NUMBUFLEN];
+    garray_T	ga;
+
+    instr = get_tv_string(&argvars[0]);
+    fromstr = get_tv_string_buf_chk(&argvars[1], buf);
+    tostr = get_tv_string_buf_chk(&argvars[2], buf2);
+
+    /* Default return value: empty string. */
+    rettv->v_type = VAR_STRING;
+    rettv->vval.v_string = NULL;
+    if (fromstr == NULL || tostr == NULL)
+	    return;		/* type error; errmsg already given */
+    ga_init2(&ga, (int)sizeof(char), 80);
+
+#ifdef FEAT_MBYTE
+    if (!has_mbyte)
+#endif
+	/* not multi-byte: fromstr and tostr must be the same length */
+	if (STRLEN(fromstr) != STRLEN(tostr))
+	{
+#ifdef FEAT_MBYTE
+error:
+#endif
+	    EMSG2(_(e_invarg2), fromstr);
+	    ga_clear(&ga);
+	    return;
+	}
+
+    /* fromstr and tostr have to contain the same number of chars */
+    while (*instr != NUL)
+    {
+#ifdef FEAT_MBYTE
+	if (has_mbyte)
+	{
+	    inlen = (*mb_ptr2len)(instr);
+	    cpstr = instr;
+	    cplen = inlen;
+	    idx = 0;
+	    for (p = fromstr; *p != NUL; p += fromlen)
+	    {
+		fromlen = (*mb_ptr2len)(p);
+		if (fromlen == inlen && STRNCMP(instr, p, inlen) == 0)
+		{
+		    for (p = tostr; *p != NUL; p += tolen)
+		    {
+			tolen = (*mb_ptr2len)(p);
+			if (idx-- == 0)
+			{
+			    cplen = tolen;
+			    cpstr = p;
+			    break;
+			}
+		    }
+		    if (*p == NUL)	/* tostr is shorter than fromstr */
+			goto error;
+		    break;
+		}
+		++idx;
+	    }
+
+	    if (first && cpstr == instr)
+	    {
+		/* Check that fromstr and tostr have the same number of
+		 * (multi-byte) characters.  Done only once when a character
+		 * of instr doesn't appear in fromstr. */
+		first = FALSE;
+		for (p = tostr; *p != NUL; p += tolen)
+		{
+		    tolen = (*mb_ptr2len)(p);
+		    --idx;
+		}
+		if (idx != 0)
+		    goto error;
+	    }
+
+	    ga_grow(&ga, cplen);
+	    mch_memmove((char *)ga.ga_data + ga.ga_len, cpstr, (size_t)cplen);
+	    ga.ga_len += cplen;
+
+	    instr += inlen;
+	}
+	else
+#endif
+	{
+	    /* When not using multi-byte chars we can do it faster. */
+	    p = vim_strchr(fromstr, *instr);
+	    if (p != NULL)
+		ga_append(&ga, tostr[p - fromstr]);
+	    else
+		ga_append(&ga, *instr);
+	    ++instr;
+	}
+    }
+
+    /* add a terminating NUL */
+    ga_grow(&ga, 1);
+    ga_append(&ga, NUL);
+
+    rettv->vval.v_string = ga.ga_data;
+}
+
+/*
+ * "type(expr)" function
+ */
+    static void
+f_type(argvars, rettv)
+    typval_T	*argvars;
+    typval_T	*rettv;
+{
+    int n;
+
+    switch (argvars[0].v_type)
+    {
+	case VAR_NUMBER: n = 0; break;
+	case VAR_STRING: n = 1; break;
+	case VAR_FUNC:   n = 2; break;
+	case VAR_LIST:   n = 3; break;
+	case VAR_DICT:   n = 4; break;
+	default: EMSG2(_(e_intern2), "f_type()"); n = 0; break;
+    }
+    rettv->vval.v_number = n;
+}
+
+/*
+ * "values(dict)" function
+ */
+    static void
+f_values(argvars, rettv)
+    typval_T	*argvars;
+    typval_T	*rettv;
+{
+    dict_list(argvars, rettv, 1);
+}
+
+/*
+ * "virtcol(string)" function
+ */
+    static void
+f_virtcol(argvars, rettv)
+    typval_T	*argvars;
+    typval_T	*rettv;
+{
+    colnr_T	vcol = 0;
+    pos_T	*fp;
+    int		fnum = curbuf->b_fnum;
+
+    fp = var2fpos(&argvars[0], FALSE, &fnum);
+    if (fp != NULL && fp->lnum <= curbuf->b_ml.ml_line_count
+						    && fnum == curbuf->b_fnum)
+    {
+	getvvcol(curwin, fp, NULL, NULL, &vcol);
+	++vcol;
+    }
+
+    rettv->vval.v_number = vcol;
+}
+
+/*
+ * "visualmode()" function
+ */
+/*ARGSUSED*/
+    static void
+f_visualmode(argvars, rettv)
+    typval_T	*argvars;
+    typval_T	*rettv;
+{
+#ifdef FEAT_VISUAL
+    char_u	str[2];
+
+    rettv->v_type = VAR_STRING;
+    str[0] = curbuf->b_visual_mode_eval;
+    str[1] = NUL;
+    rettv->vval.v_string = vim_strsave(str);
+
+    /* A non-zero number or non-empty string argument: reset mode. */
+    if ((argvars[0].v_type == VAR_NUMBER
+		&& argvars[0].vval.v_number != 0)
+	    || (argvars[0].v_type == VAR_STRING
+		&& *get_tv_string(&argvars[0]) != NUL))
+	curbuf->b_visual_mode_eval = NUL;
+#else
+    rettv->vval.v_number = 0; /* return anything, it won't work anyway */
+#endif
+}
+
+/*
+ * "winbufnr(nr)" function
+ */
+    static void
+f_winbufnr(argvars, rettv)
+    typval_T	*argvars;
+    typval_T	*rettv;
+{
+    win_T	*wp;
+
+    wp = find_win_by_nr(&argvars[0], NULL);
+    if (wp == NULL)
+	rettv->vval.v_number = -1;
+    else
+	rettv->vval.v_number = wp->w_buffer->b_fnum;
+}
+
+/*
+ * "wincol()" function
+ */
+/*ARGSUSED*/
+    static void
+f_wincol(argvars, rettv)
+    typval_T	*argvars;
+    typval_T	*rettv;
+{
+    validate_cursor();
+    rettv->vval.v_number = curwin->w_wcol + 1;
+}
+
+/*
+ * "winheight(nr)" function
+ */
+    static void
+f_winheight(argvars, rettv)
+    typval_T	*argvars;
+    typval_T	*rettv;
+{
+    win_T	*wp;
+
+    wp = find_win_by_nr(&argvars[0], NULL);
+    if (wp == NULL)
+	rettv->vval.v_number = -1;
+    else
+	rettv->vval.v_number = wp->w_height;
+}
+
+/*
+ * "winline()" function
+ */
+/*ARGSUSED*/
+    static void
+f_winline(argvars, rettv)
+    typval_T	*argvars;
+    typval_T	*rettv;
+{
+    validate_cursor();
+    rettv->vval.v_number = curwin->w_wrow + 1;
+}
+
+/*
+ * "winnr()" function
+ */
+/* ARGSUSED */
+    static void
+f_winnr(argvars, rettv)
+    typval_T	*argvars;
+    typval_T	*rettv;
+{
+    int		nr = 1;
+
+#ifdef FEAT_WINDOWS
+    nr = get_winnr(curtab, &argvars[0]);
+#endif
+    rettv->vval.v_number = nr;
+}
+
+/*
+ * "winrestcmd()" function
+ */
+/* ARGSUSED */
+    static void
+f_winrestcmd(argvars, rettv)
+    typval_T	*argvars;
+    typval_T	*rettv;
+{
+#ifdef FEAT_WINDOWS
+    win_T	*wp;
+    int		winnr = 1;
+    garray_T	ga;
+    char_u	buf[50];
+
+    ga_init2(&ga, (int)sizeof(char), 70);
+    for (wp = firstwin; wp != NULL; wp = wp->w_next)
+    {
+	sprintf((char *)buf, "%dresize %d|", winnr, wp->w_height);
+	ga_concat(&ga, buf);
+# ifdef FEAT_VERTSPLIT
+	sprintf((char *)buf, "vert %dresize %d|", winnr, wp->w_width);
+	ga_concat(&ga, buf);
+# endif
+	++winnr;
+    }
+    ga_append(&ga, NUL);
+
+    rettv->vval.v_string = ga.ga_data;
+#else
+    rettv->vval.v_string = NULL;
+#endif
+    rettv->v_type = VAR_STRING;
+}
+
+/*
+ * "winrestview()" function
+ */
+/* ARGSUSED */
+    static void
+f_winrestview(argvars, rettv)
+    typval_T	*argvars;
+    typval_T	*rettv;
+{
+    dict_T	*dict;
+
+    if (argvars[0].v_type != VAR_DICT
+	    || (dict = argvars[0].vval.v_dict) == NULL)
+	EMSG(_(e_invarg));
+    else
+    {
+	curwin->w_cursor.lnum = get_dict_number(dict, (char_u *)"lnum");
+	curwin->w_cursor.col = get_dict_number(dict, (char_u *)"col");
+#ifdef FEAT_VIRTUALEDIT
+	curwin->w_cursor.coladd = get_dict_number(dict, (char_u *)"coladd");
+#endif
+	curwin->w_curswant = get_dict_number(dict, (char_u *)"curswant");
+	curwin->w_set_curswant = FALSE;
+
+	set_topline(curwin, get_dict_number(dict, (char_u *)"topline"));
+#ifdef FEAT_DIFF
+	curwin->w_topfill = get_dict_number(dict, (char_u *)"topfill");
+#endif
+	curwin->w_leftcol = get_dict_number(dict, (char_u *)"leftcol");
+	curwin->w_skipcol = get_dict_number(dict, (char_u *)"skipcol");
+
+	check_cursor();
+	changed_cline_bef_curs();
+	invalidate_botline();
+	redraw_later(VALID);
+
+	if (curwin->w_topline == 0)
+	    curwin->w_topline = 1;
+	if (curwin->w_topline > curbuf->b_ml.ml_line_count)
+	    curwin->w_topline = curbuf->b_ml.ml_line_count;
+#ifdef FEAT_DIFF
+	check_topfill(curwin, TRUE);
+#endif
+    }
+}
+
+/*
+ * "winsaveview()" function
+ */
+/* ARGSUSED */
+    static void
+f_winsaveview(argvars, rettv)
+    typval_T	*argvars;
+    typval_T	*rettv;
+{
+    dict_T	*dict;
+
+    dict = dict_alloc();
+    if (dict == NULL)
+	return;
+    rettv->v_type = VAR_DICT;
+    rettv->vval.v_dict = dict;
+    ++dict->dv_refcount;
+
+    dict_add_nr_str(dict, "lnum", (long)curwin->w_cursor.lnum, NULL);
+    dict_add_nr_str(dict, "col", (long)curwin->w_cursor.col, NULL);
+#ifdef FEAT_VIRTUALEDIT
+    dict_add_nr_str(dict, "coladd", (long)curwin->w_cursor.coladd, NULL);
+#endif
+    update_curswant();
+    dict_add_nr_str(dict, "curswant", (long)curwin->w_curswant, NULL);
+
+    dict_add_nr_str(dict, "topline", (long)curwin->w_topline, NULL);
+#ifdef FEAT_DIFF
+    dict_add_nr_str(dict, "topfill", (long)curwin->w_topfill, NULL);
+#endif
+    dict_add_nr_str(dict, "leftcol", (long)curwin->w_leftcol, NULL);
+    dict_add_nr_str(dict, "skipcol", (long)curwin->w_skipcol, NULL);
+}
+
+/*
+ * "winwidth(nr)" function
+ */
+    static void
+f_winwidth(argvars, rettv)
+    typval_T	*argvars;
+    typval_T	*rettv;
+{
+    win_T	*wp;
+
+    wp = find_win_by_nr(&argvars[0], NULL);
+    if (wp == NULL)
+	rettv->vval.v_number = -1;
+    else
+#ifdef FEAT_VERTSPLIT
+	rettv->vval.v_number = wp->w_width;
+#else
+	rettv->vval.v_number = Columns;
+#endif
+}
+
+/*
+ * "writefile()" function
+ */
+    static void
+f_writefile(argvars, rettv)
+    typval_T	*argvars;
+    typval_T	*rettv;
+{
+    int		binary = FALSE;
+    char_u	*fname;
+    FILE	*fd;
+    listitem_T	*li;
+    char_u	*s;
+    int		ret = 0;
+    int		c;
+
+    if (check_restricted() || check_secure())
+	return;
+
+    if (argvars[0].v_type != VAR_LIST)
+    {
+	EMSG2(_(e_listarg), "writefile()");
+	return;
+    }
+    if (argvars[0].vval.v_list == NULL)
+	return;
+
+    if (argvars[2].v_type != VAR_UNKNOWN
+			      && STRCMP(get_tv_string(&argvars[2]), "b") == 0)
+	binary = TRUE;
+
+    /* Always open the file in binary mode, library functions have a mind of
+     * their own about CR-LF conversion. */
+    fname = get_tv_string(&argvars[1]);
+    if (*fname == NUL || (fd = mch_fopen((char *)fname, WRITEBIN)) == NULL)
+    {
+	EMSG2(_(e_notcreate), *fname == NUL ? (char_u *)_("<empty>") : fname);
+	ret = -1;
+    }
+    else
+    {
+	for (li = argvars[0].vval.v_list->lv_first; li != NULL;
+							     li = li->li_next)
+	{
+	    for (s = get_tv_string(&li->li_tv); *s != NUL; ++s)
+	    {
+		if (*s == '\n')
+		    c = putc(NUL, fd);
+		else
+		    c = putc(*s, fd);
+		if (c == EOF)
+		{
+		    ret = -1;
+		    break;
+		}
+	    }
+	    if (!binary || li->li_next != NULL)
+		if (putc('\n', fd) == EOF)
+		{
+		    ret = -1;
+		    break;
+		}
+	    if (ret < 0)
+	    {
+		EMSG(_(e_write));
+		break;
+	    }
+	}
+	fclose(fd);
+    }
+
+    rettv->vval.v_number = ret;
+}
+
+/*
+ * Translate a String variable into a position.
+ * Returns NULL when there is an error.
+ */
+    static pos_T *
+var2fpos(varp, lnum, fnum)
+    typval_T	*varp;
+    int		lnum;		/* TRUE when $ is last line */
+    int		*fnum;		/* set to fnum for '0, 'A, etc. */
+{
+    char_u		*name;
+    static pos_T	pos;
+    pos_T		*pp;
+
+    /* Argument can be [lnum, col, coladd]. */
+    if (varp->v_type == VAR_LIST)
+    {
+	list_T		*l;
+	int		len;
+	int		error = FALSE;
+
+	l = varp->vval.v_list;
+	if (l == NULL)
+	    return NULL;
+
+	/* Get the line number */
+	pos.lnum = list_find_nr(l, 0L, &error);
+	if (error || pos.lnum <= 0 || pos.lnum > curbuf->b_ml.ml_line_count)
+	    return NULL;	/* invalid line number */
+
+	/* Get the column number */
+	pos.col = list_find_nr(l, 1L, &error);
+	if (error)
+	    return NULL;
+	len = (long)STRLEN(ml_get(pos.lnum));
+	/* Accept a position up to the NUL after the line. */
+	if (pos.col == 0 || (int)pos.col > len + 1)
+	    return NULL;	/* invalid column number */
+	--pos.col;
+
+#ifdef FEAT_VIRTUALEDIT
+	/* Get the virtual offset.  Defaults to zero. */
+	pos.coladd = list_find_nr(l, 2L, &error);
+	if (error)
+	    pos.coladd = 0;
+#endif
+
+	return &pos;
+    }
+
+    name = get_tv_string_chk(varp);
+    if (name == NULL)
+	return NULL;
+    if (name[0] == '.')		/* cursor */
+	return &curwin->w_cursor;
+    if (name[0] == '\'')	/* mark */
+    {
+	pp = getmark_fnum(name[1], FALSE, fnum);
+	if (pp == NULL || pp == (pos_T *)-1 || pp->lnum <= 0)
+	    return NULL;
+	return pp;
+    }
+
+#ifdef FEAT_VIRTUALEDIT
+    pos.coladd = 0;
+#endif
+
+    if (name[0] == 'w' && lnum)
+    {
+	pos.col = 0;
+	if (name[1] == '0')		/* "w0": first visible line */
+	{
+	    update_topline();
+	    pos.lnum = curwin->w_topline;
+	    return &pos;
+	}
+	else if (name[1] == '$')	/* "w$": last visible line */
+	{
+	    validate_botline();
+	    pos.lnum = curwin->w_botline - 1;
+	    return &pos;
+	}
+    }
+    else if (name[0] == '$')		/* last column or line */
+    {
+	if (lnum)
+	{
+	    pos.lnum = curbuf->b_ml.ml_line_count;
+	    pos.col = 0;
+	}
+	else
+	{
+	    pos.lnum = curwin->w_cursor.lnum;
+	    pos.col = (colnr_T)STRLEN(ml_get_curline());
+	}
+	return &pos;
+    }
+    return NULL;
+}
+
+/*
+ * Convert list in "arg" into a position and optional file number.
+ * When "fnump" is NULL there is no file number, only 3 items.
+ * Note that the column is passed on as-is, the caller may want to decrement
+ * it to use 1 for the first column.
+ * Return FAIL when conversion is not possible, doesn't check the position for
+ * validity.
+ */
+    static int
+list2fpos(arg, posp, fnump)
+    typval_T	*arg;
+    pos_T	*posp;
+    int		*fnump;
+{
+    list_T	*l = arg->vval.v_list;
+    long	i = 0;
+    long	n;
+
+    /* List must be: [fnum, lnum, col, coladd], where "fnum" is only there
+     * when "fnump" isn't NULL and "coladd" is optional. */
+    if (arg->v_type != VAR_LIST
+	    || l == NULL
+	    || l->lv_len < (fnump == NULL ? 2 : 3)
+	    || l->lv_len > (fnump == NULL ? 3 : 4))
+	return FAIL;
+
+    if (fnump != NULL)
+    {
+	n = list_find_nr(l, i++, NULL);	/* fnum */
+	if (n < 0)
+	    return FAIL;
+	if (n == 0)
+	    n = curbuf->b_fnum;		/* current buffer */
+	*fnump = n;
+    }
+
+    n = list_find_nr(l, i++, NULL);	/* lnum */
+    if (n < 0)
+	return FAIL;
+    posp->lnum = n;
+
+    n = list_find_nr(l, i++, NULL);	/* col */
+    if (n < 0)
+	return FAIL;
+    posp->col = n;
+
+#ifdef FEAT_VIRTUALEDIT
+    n = list_find_nr(l, i, NULL);
+    if (n < 0)
+	posp->coladd = 0;
+    else
+	posp->coladd = n;
+#endif
+
+    return OK;
+}
+
+/*
+ * Get the length of an environment variable name.
+ * Advance "arg" to the first character after the name.
+ * Return 0 for error.
+ */
+    static int
+get_env_len(arg)
+    char_u	**arg;
+{
+    char_u	*p;
+    int		len;
+
+    for (p = *arg; vim_isIDc(*p); ++p)
+	;
+    if (p == *arg)	    /* no name found */
+	return 0;
+
+    len = (int)(p - *arg);
+    *arg = p;
+    return len;
+}
+
+/*
+ * Get the length of the name of a function or internal variable.
+ * "arg" is advanced to the first non-white character after the name.
+ * Return 0 if something is wrong.
+ */
+    static int
+get_id_len(arg)
+    char_u	**arg;
+{
+    char_u	*p;
+    int		len;
+
+    /* Find the end of the name. */
+    for (p = *arg; eval_isnamec(*p); ++p)
+	;
+    if (p == *arg)	    /* no name found */
+	return 0;
+
+    len = (int)(p - *arg);
+    *arg = skipwhite(p);
+
+    return len;
+}
+
+/*
+ * Get the length of the name of a variable or function.
+ * Only the name is recognized, does not handle ".key" or "[idx]".
+ * "arg" is advanced to the first non-white character after the name.
+ * Return -1 if curly braces expansion failed.
+ * Return 0 if something else is wrong.
+ * If the name contains 'magic' {}'s, expand them and return the
+ * expanded name in an allocated string via 'alias' - caller must free.
+ */
+    static int
+get_name_len(arg, alias, evaluate, verbose)
+    char_u	**arg;
+    char_u	**alias;
+    int		evaluate;
+    int		verbose;
+{
+    int		len;
+    char_u	*p;
+    char_u	*expr_start;
+    char_u	*expr_end;
+
+    *alias = NULL;  /* default to no alias */
+
+    if ((*arg)[0] == K_SPECIAL && (*arg)[1] == KS_EXTRA
+						  && (*arg)[2] == (int)KE_SNR)
+    {
+	/* hard coded <SNR>, already translated */
+	*arg += 3;
+	return get_id_len(arg) + 3;
+    }
+    len = eval_fname_script(*arg);
+    if (len > 0)
+    {
+	/* literal "<SID>", "s:" or "<SNR>" */
+	*arg += len;
+    }
+
+    /*
+     * Find the end of the name; check for {} construction.
+     */
+    p = find_name_end(*arg, &expr_start, &expr_end,
+					       len > 0 ? 0 : FNE_CHECK_START);
+    if (expr_start != NULL)
+    {
+	char_u	*temp_string;
+
+	if (!evaluate)
+	{
+	    len += (int)(p - *arg);
+	    *arg = skipwhite(p);
+	    return len;
+	}
+
+	/*
+	 * Include any <SID> etc in the expanded string:
+	 * Thus the -len here.
+	 */
+	temp_string = make_expanded_name(*arg - len, expr_start, expr_end, p);
+	if (temp_string == NULL)
+	    return -1;
+	*alias = temp_string;
+	*arg = skipwhite(p);
+	return (int)STRLEN(temp_string);
+    }
+
+    len += get_id_len(arg);
+    if (len == 0 && verbose)
+	EMSG2(_(e_invexpr2), *arg);
+
+    return len;
+}
+
+/*
+ * Find the end of a variable or function name, taking care of magic braces.
+ * If "expr_start" is not NULL then "expr_start" and "expr_end" are set to the
+ * start and end of the first magic braces item.
+ * "flags" can have FNE_INCL_BR and FNE_CHECK_START.
+ * Return a pointer to just after the name.  Equal to "arg" if there is no
+ * valid name.
+ */
+    static char_u *
+find_name_end(arg, expr_start, expr_end, flags)
+    char_u	*arg;
+    char_u	**expr_start;
+    char_u	**expr_end;
+    int		flags;
+{
+    int		mb_nest = 0;
+    int		br_nest = 0;
+    char_u	*p;
+
+    if (expr_start != NULL)
+    {
+	*expr_start = NULL;
+	*expr_end = NULL;
+    }
+
+    /* Quick check for valid starting character. */
+    if ((flags & FNE_CHECK_START) && !eval_isnamec1(*arg) && *arg != '{')
+	return arg;
+
+    for (p = arg; *p != NUL
+		    && (eval_isnamec(*p)
+			|| *p == '{'
+			|| ((flags & FNE_INCL_BR) && (*p == '[' || *p == '.'))
+			|| mb_nest != 0
+			|| br_nest != 0); mb_ptr_adv(p))
+    {
+	if (*p == '\'')
+	{
+	    /* skip over 'string' to avoid counting [ and ] inside it. */
+	    for (p = p + 1; *p != NUL && *p != '\''; mb_ptr_adv(p))
+		;
+	    if (*p == NUL)
+		break;
+	}
+	else if (*p == '"')
+	{
+	    /* skip over "str\"ing" to avoid counting [ and ] inside it. */
+	    for (p = p + 1; *p != NUL && *p != '"'; mb_ptr_adv(p))
+		if (*p == '\\' && p[1] != NUL)
+		    ++p;
+	    if (*p == NUL)
+		break;
+	}
+
+	if (mb_nest == 0)
+	{
+	    if (*p == '[')
+		++br_nest;
+	    else if (*p == ']')
+		--br_nest;
+	}
+
+	if (br_nest == 0)
+	{
+	    if (*p == '{')
+	    {
+		mb_nest++;
+		if (expr_start != NULL && *expr_start == NULL)
+		    *expr_start = p;
+	    }
+	    else if (*p == '}')
+	    {
+		mb_nest--;
+		if (expr_start != NULL && mb_nest == 0 && *expr_end == NULL)
+		    *expr_end = p;
+	    }
+	}
+    }
+
+    return p;
+}
+
+/*
+ * Expands out the 'magic' {}'s in a variable/function name.
+ * Note that this can call itself recursively, to deal with
+ * constructs like foo{bar}{baz}{bam}
+ * The four pointer arguments point to "foo{expre}ss{ion}bar"
+ *			"in_start"      ^
+ *			"expr_start"	   ^
+ *			"expr_end"		 ^
+ *			"in_end"			    ^
+ *
+ * Returns a new allocated string, which the caller must free.
+ * Returns NULL for failure.
+ */
+    static char_u *
+make_expanded_name(in_start, expr_start, expr_end, in_end)
+    char_u	*in_start;
+    char_u	*expr_start;
+    char_u	*expr_end;
+    char_u	*in_end;
+{
+    char_u	c1;
+    char_u	*retval = NULL;
+    char_u	*temp_result;
+    char_u	*nextcmd = NULL;
+
+    if (expr_end == NULL || in_end == NULL)
+	return NULL;
+    *expr_start	= NUL;
+    *expr_end = NUL;
+    c1 = *in_end;
+    *in_end = NUL;
+
+    temp_result = eval_to_string(expr_start + 1, &nextcmd, FALSE);
+    if (temp_result != NULL && nextcmd == NULL)
+    {
+	retval = alloc((unsigned)(STRLEN(temp_result) + (expr_start - in_start)
+						   + (in_end - expr_end) + 1));
+	if (retval != NULL)
+	{
+	    STRCPY(retval, in_start);
+	    STRCAT(retval, temp_result);
+	    STRCAT(retval, expr_end + 1);
+	}
+    }
+    vim_free(temp_result);
+
+    *in_end = c1;		/* put char back for error messages */
+    *expr_start = '{';
+    *expr_end = '}';
+
+    if (retval != NULL)
+    {
+	temp_result = find_name_end(retval, &expr_start, &expr_end, 0);
+	if (expr_start != NULL)
+	{
+	    /* Further expansion! */
+	    temp_result = make_expanded_name(retval, expr_start,
+						       expr_end, temp_result);
+	    vim_free(retval);
+	    retval = temp_result;
+	}
+    }
+
+    return retval;
+}
+
+/*
+ * Return TRUE if character "c" can be used in a variable or function name.
+ * Does not include '{' or '}' for magic braces.
+ */
+    static int
+eval_isnamec(c)
+    int	    c;
+{
+    return (ASCII_ISALNUM(c) || c == '_' || c == ':' || c == AUTOLOAD_CHAR);
+}
+
+/*
+ * Return TRUE if character "c" can be used as the first character in a
+ * variable or function name (excluding '{' and '}').
+ */
+    static int
+eval_isnamec1(c)
+    int	    c;
+{
+    return (ASCII_ISALPHA(c) || c == '_');
+}
+
+/*
+ * Set number v: variable to "val".
+ */
+    void
+set_vim_var_nr(idx, val)
+    int		idx;
+    long	val;
+{
+    vimvars[idx].vv_nr = val;
+}
+
+/*
+ * Get number v: variable value.
+ */
+    long
+get_vim_var_nr(idx)
+    int		idx;
+{
+    return vimvars[idx].vv_nr;
+}
+
+#if defined(FEAT_AUTOCMD) || defined(PROTO)
+/*
+ * Get string v: variable value.  Uses a static buffer, can only be used once.
+ */
+    char_u *
+get_vim_var_str(idx)
+    int		idx;
+{
+    return get_tv_string(&vimvars[idx].vv_tv);
+}
+#endif
+
+/*
+ * Set v:count, v:count1 and v:prevcount.
+ */
+    void
+set_vcount(count, count1)
+    long	count;
+    long	count1;
+{
+    vimvars[VV_PREVCOUNT].vv_nr = vimvars[VV_COUNT].vv_nr;
+    vimvars[VV_COUNT].vv_nr = count;
+    vimvars[VV_COUNT1].vv_nr = count1;
+}
+
+/*
+ * Set string v: variable to a copy of "val".
+ */
+    void
+set_vim_var_string(idx, val, len)
+    int		idx;
+    char_u	*val;
+    int		len;	    /* length of "val" to use or -1 (whole string) */
+{
+    /* Need to do this (at least) once, since we can't initialize a union.
+     * Will always be invoked when "v:progname" is set. */
+    vimvars[VV_VERSION].vv_nr = VIM_VERSION_100;
+
+    vim_free(vimvars[idx].vv_str);
+    if (val == NULL)
+	vimvars[idx].vv_str = NULL;
+    else if (len == -1)
+	vimvars[idx].vv_str = vim_strsave(val);
+    else
+	vimvars[idx].vv_str = vim_strnsave(val, len);
+}
+
+/*
+ * Set v:register if needed.
+ */
+    void
+set_reg_var(c)
+    int		c;
+{
+    char_u	regname;
+
+    if (c == 0 || c == ' ')
+	regname = '"';
+    else
+	regname = c;
+    /* Avoid free/alloc when the value is already right. */
+    if (vimvars[VV_REG].vv_str == NULL || vimvars[VV_REG].vv_str[0] != c)
+	set_vim_var_string(VV_REG, &regname, 1);
+}
+
+/*
+ * Get or set v:exception.  If "oldval" == NULL, return the current value.
+ * Otherwise, restore the value to "oldval" and return NULL.
+ * Must always be called in pairs to save and restore v:exception!  Does not
+ * take care of memory allocations.
+ */
+    char_u *
+v_exception(oldval)
+    char_u	*oldval;
+{
+    if (oldval == NULL)
+	return vimvars[VV_EXCEPTION].vv_str;
+
+    vimvars[VV_EXCEPTION].vv_str = oldval;
+    return NULL;
+}
+
+/*
+ * Get or set v:throwpoint.  If "oldval" == NULL, return the current value.
+ * Otherwise, restore the value to "oldval" and return NULL.
+ * Must always be called in pairs to save and restore v:throwpoint!  Does not
+ * take care of memory allocations.
+ */
+    char_u *
+v_throwpoint(oldval)
+    char_u	*oldval;
+{
+    if (oldval == NULL)
+	return vimvars[VV_THROWPOINT].vv_str;
+
+    vimvars[VV_THROWPOINT].vv_str = oldval;
+    return NULL;
+}
+
+#if defined(FEAT_AUTOCMD) || defined(PROTO)
+/*
+ * Set v:cmdarg.
+ * If "eap" != NULL, use "eap" to generate the value and return the old value.
+ * If "oldarg" != NULL, restore the value to "oldarg" and return NULL.
+ * Must always be called in pairs!
+ */
+    char_u *
+set_cmdarg(eap, oldarg)
+    exarg_T	*eap;
+    char_u	*oldarg;
+{
+    char_u	*oldval;
+    char_u	*newval;
+    unsigned	len;
+
+    oldval = vimvars[VV_CMDARG].vv_str;
+    if (eap == NULL)
+    {
+	vim_free(oldval);
+	vimvars[VV_CMDARG].vv_str = oldarg;
+	return NULL;
+    }
+
+    if (eap->force_bin == FORCE_BIN)
+	len = 6;
+    else if (eap->force_bin == FORCE_NOBIN)
+	len = 8;
+    else
+	len = 0;
+
+    if (eap->read_edit)
+	len += 7;
+
+    if (eap->force_ff != 0)
+	len += (unsigned)STRLEN(eap->cmd + eap->force_ff) + 6;
+# ifdef FEAT_MBYTE
+    if (eap->force_enc != 0)
+	len += (unsigned)STRLEN(eap->cmd + eap->force_enc) + 7;
+    if (eap->bad_char != 0)
+	len += (unsigned)STRLEN(eap->cmd + eap->bad_char) + 7;
+# endif
+
+    newval = alloc(len + 1);
+    if (newval == NULL)
+	return NULL;
+
+    if (eap->force_bin == FORCE_BIN)
+	sprintf((char *)newval, " ++bin");
+    else if (eap->force_bin == FORCE_NOBIN)
+	sprintf((char *)newval, " ++nobin");
+    else
+	*newval = NUL;
+
+    if (eap->read_edit)
+	STRCAT(newval, " ++edit");
+
+    if (eap->force_ff != 0)
+	sprintf((char *)newval + STRLEN(newval), " ++ff=%s",
+						eap->cmd + eap->force_ff);
+# ifdef FEAT_MBYTE
+    if (eap->force_enc != 0)
+	sprintf((char *)newval + STRLEN(newval), " ++enc=%s",
+					       eap->cmd + eap->force_enc);
+    if (eap->bad_char != 0)
+	sprintf((char *)newval + STRLEN(newval), " ++bad=%s",
+					       eap->cmd + eap->bad_char);
+# endif
+    vimvars[VV_CMDARG].vv_str = newval;
+    return oldval;
+}
+#endif
+
+/*
+ * Get the value of internal variable "name".
+ * Return OK or FAIL.
+ */
+    static int
+get_var_tv(name, len, rettv, verbose)
+    char_u	*name;
+    int		len;		/* length of "name" */
+    typval_T	*rettv;		/* NULL when only checking existence */
+    int		verbose;	/* may give error message */
+{
+    int		ret = OK;
+    typval_T	*tv = NULL;
+    typval_T	atv;
+    dictitem_T	*v;
+    int		cc;
+
+    /* truncate the name, so that we can use strcmp() */
+    cc = name[len];
+    name[len] = NUL;
+
+    /*
+     * Check for "b:changedtick".
+     */
+    if (STRCMP(name, "b:changedtick") == 0)
+    {
+	atv.v_type = VAR_NUMBER;
+	atv.vval.v_number = curbuf->b_changedtick;
+	tv = &atv;
+    }
+
+    /*
+     * Check for user-defined variables.
+     */
+    else
+    {
+	v = find_var(name, NULL);
+	if (v != NULL)
+	    tv = &v->di_tv;
+    }
+
+    if (tv == NULL)
+    {
+	if (rettv != NULL && verbose)
+	    EMSG2(_(e_undefvar), name);
+	ret = FAIL;
+    }
+    else if (rettv != NULL)
+	copy_tv(tv, rettv);
+
+    name[len] = cc;
+
+    return ret;
+}
+
+/*
+ * Handle expr[expr], expr[expr:expr] subscript and .name lookup.
+ * Also handle function call with Funcref variable: func(expr)
+ * Can all be combined: dict.func(expr)[idx]['func'](expr)
+ */
+    static int
+handle_subscript(arg, rettv, evaluate, verbose)
+    char_u	**arg;
+    typval_T	*rettv;
+    int		evaluate;	/* do more than finding the end */
+    int		verbose;	/* give error messages */
+{
+    int		ret = OK;
+    dict_T	*selfdict = NULL;
+    char_u	*s;
+    int		len;
+    typval_T	functv;
+
+    while (ret == OK
+	    && (**arg == '['
+		|| (**arg == '.' && rettv->v_type == VAR_DICT)
+		|| (**arg == '(' && rettv->v_type == VAR_FUNC))
+	    && !vim_iswhite(*(*arg - 1)))
+    {
+	if (**arg == '(')
+	{
+	    /* need to copy the funcref so that we can clear rettv */
+	    functv = *rettv;
+	    rettv->v_type = VAR_UNKNOWN;
+
+	    /* Invoke the function.  Recursive! */
+	    s = functv.vval.v_string;
+	    ret = get_func_tv(s, (int)STRLEN(s), rettv, arg,
+			curwin->w_cursor.lnum, curwin->w_cursor.lnum,
+			&len, evaluate, selfdict);
+
+	    /* Clear the funcref afterwards, so that deleting it while
+	     * evaluating the arguments is possible (see test55). */
+	    clear_tv(&functv);
+
+	    /* Stop the expression evaluation when immediately aborting on
+	     * error, or when an interrupt occurred or an exception was thrown
+	     * but not caught. */
+	    if (aborting())
+	    {
+		if (ret == OK)
+		    clear_tv(rettv);
+		ret = FAIL;
+	    }
+	    dict_unref(selfdict);
+	    selfdict = NULL;
+	}
+	else /* **arg == '[' || **arg == '.' */
+	{
+	    dict_unref(selfdict);
+	    if (rettv->v_type == VAR_DICT)
+	    {
+		selfdict = rettv->vval.v_dict;
+		if (selfdict != NULL)
+		    ++selfdict->dv_refcount;
+	    }
+	    else
+		selfdict = NULL;
+	    if (eval_index(arg, rettv, evaluate, verbose) == FAIL)
+	    {
+		clear_tv(rettv);
+		ret = FAIL;
+	    }
+	}
+    }
+    dict_unref(selfdict);
+    return ret;
+}
+
+/*
+ * Allocate memory for a variable type-value, and make it emtpy (0 or NULL
+ * value).
+ */
+    static typval_T *
+alloc_tv()
+{
+    return (typval_T *)alloc_clear((unsigned)sizeof(typval_T));
+}
+
+/*
+ * Allocate memory for a variable type-value, and assign a string to it.
+ * The string "s" must have been allocated, it is consumed.
+ * Return NULL for out of memory, the variable otherwise.
+ */
+    static typval_T *
+alloc_string_tv(s)
+    char_u	*s;
+{
+    typval_T	*rettv;
+
+    rettv = alloc_tv();
+    if (rettv != NULL)
+    {
+	rettv->v_type = VAR_STRING;
+	rettv->vval.v_string = s;
+    }
+    else
+	vim_free(s);
+    return rettv;
+}
+
+/*
+ * Free the memory for a variable type-value.
+ */
+    void
+free_tv(varp)
+    typval_T *varp;
+{
+    if (varp != NULL)
+    {
+	switch (varp->v_type)
+	{
+	    case VAR_FUNC:
+		func_unref(varp->vval.v_string);
+		/*FALLTHROUGH*/
+	    case VAR_STRING:
+		vim_free(varp->vval.v_string);
+		break;
+	    case VAR_LIST:
+		list_unref(varp->vval.v_list);
+		break;
+	    case VAR_DICT:
+		dict_unref(varp->vval.v_dict);
+		break;
+	    case VAR_NUMBER:
+	    case VAR_UNKNOWN:
+		break;
+	    default:
+		EMSG2(_(e_intern2), "free_tv()");
+		break;
+	}
+	vim_free(varp);
+    }
+}
+
+/*
+ * Free the memory for a variable value and set the value to NULL or 0.
+ */
+    void
+clear_tv(varp)
+    typval_T *varp;
+{
+    if (varp != NULL)
+    {
+	switch (varp->v_type)
+	{
+	    case VAR_FUNC:
+		func_unref(varp->vval.v_string);
+		/*FALLTHROUGH*/
+	    case VAR_STRING:
+		vim_free(varp->vval.v_string);
+		varp->vval.v_string = NULL;
+		break;
+	    case VAR_LIST:
+		list_unref(varp->vval.v_list);
+		varp->vval.v_list = NULL;
+		break;
+	    case VAR_DICT:
+		dict_unref(varp->vval.v_dict);
+		varp->vval.v_dict = NULL;
+		break;
+	    case VAR_NUMBER:
+		varp->vval.v_number = 0;
+		break;
+	    case VAR_UNKNOWN:
+		break;
+	    default:
+		EMSG2(_(e_intern2), "clear_tv()");
+	}
+	varp->v_lock = 0;
+    }
+}
+
+/*
+ * Set the value of a variable to NULL without freeing items.
+ */
+    static void
+init_tv(varp)
+    typval_T *varp;
+{
+    if (varp != NULL)
+	vim_memset(varp, 0, sizeof(typval_T));
+}
+
+/*
+ * Get the number value of a variable.
+ * If it is a String variable, uses vim_str2nr().
+ * For incompatible types, return 0.
+ * get_tv_number_chk() is similar to get_tv_number(), but informs the
+ * caller of incompatible types: it sets *denote to TRUE if "denote"
+ * is not NULL or returns -1 otherwise.
+ */
+    static long
+get_tv_number(varp)
+    typval_T	*varp;
+{
+    int		error = FALSE;
+
+    return get_tv_number_chk(varp, &error);	/* return 0L on error */
+}
+
+    long
+get_tv_number_chk(varp, denote)
+    typval_T	*varp;
+    int		*denote;
+{
+    long	n = 0L;
+
+    switch (varp->v_type)
+    {
+	case VAR_NUMBER:
+	    return (long)(varp->vval.v_number);
+	case VAR_FUNC:
+	    EMSG(_("E703: Using a Funcref as a number"));
+	    break;
+	case VAR_STRING:
+	    if (varp->vval.v_string != NULL)
+		vim_str2nr(varp->vval.v_string, NULL, NULL,
+							TRUE, TRUE, &n, NULL);
+	    return n;
+	case VAR_LIST:
+	    EMSG(_("E745: Using a List as a number"));
+	    break;
+	case VAR_DICT:
+	    EMSG(_("E728: Using a Dictionary as a number"));
+	    break;
+	default:
+	    EMSG2(_(e_intern2), "get_tv_number()");
+	    break;
+    }
+    if (denote == NULL)		/* useful for values that must be unsigned */
+	n = -1;
+    else
+	*denote = TRUE;
+    return n;
+}
+
+/*
+ * Get the lnum from the first argument.
+ * Also accepts ".", "$", etc., but that only works for the current buffer.
+ * Returns -1 on error.
+ */
+    static linenr_T
+get_tv_lnum(argvars)
+    typval_T	*argvars;
+{
+    typval_T	rettv;
+    linenr_T	lnum;
+
+    lnum = get_tv_number_chk(&argvars[0], NULL);
+    if (lnum == 0)  /* no valid number, try using line() */
+    {
+	rettv.v_type = VAR_NUMBER;
+	f_line(argvars, &rettv);
+	lnum = rettv.vval.v_number;
+	clear_tv(&rettv);
+    }
+    return lnum;
+}
+
+/*
+ * Get the lnum from the first argument.
+ * Also accepts "$", then "buf" is used.
+ * Returns 0 on error.
+ */
+    static linenr_T
+get_tv_lnum_buf(argvars, buf)
+    typval_T	*argvars;
+    buf_T	*buf;
+{
+    if (argvars[0].v_type == VAR_STRING
+	    && argvars[0].vval.v_string != NULL
+	    && argvars[0].vval.v_string[0] == '$'
+	    && buf != NULL)
+	return buf->b_ml.ml_line_count;
+    return get_tv_number_chk(&argvars[0], NULL);
+}
+
+/*
+ * Get the string value of a variable.
+ * If it is a Number variable, the number is converted into a string.
+ * get_tv_string() uses a single, static buffer.  YOU CAN ONLY USE IT ONCE!
+ * get_tv_string_buf() uses a given buffer.
+ * If the String variable has never been set, return an empty string.
+ * Never returns NULL;
+ * get_tv_string_chk() and get_tv_string_buf_chk() are similar, but return
+ * NULL on error.
+ */
+    static char_u *
+get_tv_string(varp)
+    typval_T	*varp;
+{
+    static char_u   mybuf[NUMBUFLEN];
+
+    return get_tv_string_buf(varp, mybuf);
+}
+
+    static char_u *
+get_tv_string_buf(varp, buf)
+    typval_T	*varp;
+    char_u	*buf;
+{
+    char_u	*res =  get_tv_string_buf_chk(varp, buf);
+
+    return res != NULL ? res : (char_u *)"";
+}
+
+    char_u *
+get_tv_string_chk(varp)
+    typval_T	*varp;
+{
+    static char_u   mybuf[NUMBUFLEN];
+
+    return get_tv_string_buf_chk(varp, mybuf);
+}
+
+    static char_u *
+get_tv_string_buf_chk(varp, buf)
+    typval_T	*varp;
+    char_u	*buf;
+{
+    switch (varp->v_type)
+    {
+	case VAR_NUMBER:
+	    sprintf((char *)buf, "%ld", (long)varp->vval.v_number);
+	    return buf;
+	case VAR_FUNC:
+	    EMSG(_("E729: using Funcref as a String"));
+	    break;
+	case VAR_LIST:
+	    EMSG(_("E730: using List as a String"));
+	    break;
+	case VAR_DICT:
+	    EMSG(_("E731: using Dictionary as a String"));
+	    break;
+	case VAR_STRING:
+	    if (varp->vval.v_string != NULL)
+		return varp->vval.v_string;
+	    return (char_u *)"";
+	default:
+	    EMSG2(_(e_intern2), "get_tv_string_buf()");
+	    break;
+    }
+    return NULL;
+}
+
+/*
+ * Find variable "name" in the list of variables.
+ * Return a pointer to it if found, NULL if not found.
+ * Careful: "a:0" variables don't have a name.
+ * When "htp" is not NULL we are writing to the variable, set "htp" to the
+ * hashtab_T used.
+ */
+    static dictitem_T *
+find_var(name, htp)
+    char_u	*name;
+    hashtab_T	**htp;
+{
+    char_u	*varname;
+    hashtab_T	*ht;
+
+    ht = find_var_ht(name, &varname);
+    if (htp != NULL)
+	*htp = ht;
+    if (ht == NULL)
+	return NULL;
+    return find_var_in_ht(ht, varname, htp != NULL);
+}
+
+/*
+ * Find variable "varname" in hashtab "ht".
+ * Returns NULL if not found.
+ */
+    static dictitem_T *
+find_var_in_ht(ht, varname, writing)
+    hashtab_T	*ht;
+    char_u	*varname;
+    int		writing;
+{
+    hashitem_T	*hi;
+
+    if (*varname == NUL)
+    {
+	/* Must be something like "s:", otherwise "ht" would be NULL. */
+	switch (varname[-2])
+	{
+	    case 's': return &SCRIPT_SV(current_SID).sv_var;
+	    case 'g': return &globvars_var;
+	    case 'v': return &vimvars_var;
+	    case 'b': return &curbuf->b_bufvar;
+	    case 'w': return &curwin->w_winvar;
+#ifdef FEAT_WINDOWS
+	    case 't': return &curtab->tp_winvar;
+#endif
+	    case 'l': return current_funccal == NULL
+					? NULL : &current_funccal->l_vars_var;
+	    case 'a': return current_funccal == NULL
+				       ? NULL : &current_funccal->l_avars_var;
+	}
+	return NULL;
+    }
+
+    hi = hash_find(ht, varname);
+    if (HASHITEM_EMPTY(hi))
+    {
+	/* For global variables we may try auto-loading the script.  If it
+	 * worked find the variable again.  Don't auto-load a script if it was
+	 * loaded already, otherwise it would be loaded every time when
+	 * checking if a function name is a Funcref variable. */
+	if (ht == &globvarht && !writing
+			    && script_autoload(varname, FALSE) && !aborting())
+	    hi = hash_find(ht, varname);
+	if (HASHITEM_EMPTY(hi))
+	    return NULL;
+    }
+    return HI2DI(hi);
+}
+
+/*
+ * Find the hashtab used for a variable name.
+ * Set "varname" to the start of name without ':'.
+ */
+    static hashtab_T *
+find_var_ht(name, varname)
+    char_u  *name;
+    char_u  **varname;
+{
+    hashitem_T	*hi;
+
+    if (name[1] != ':')
+    {
+	/* The name must not start with a colon or #. */
+	if (name[0] == ':' || name[0] == AUTOLOAD_CHAR)
+	    return NULL;
+	*varname = name;
+
+	/* "version" is "v:version" in all scopes */
+	hi = hash_find(&compat_hashtab, name);
+	if (!HASHITEM_EMPTY(hi))
+	    return &compat_hashtab;
+
+	if (current_funccal == NULL)
+	    return &globvarht;			/* global variable */
+	return &current_funccal->l_vars.dv_hashtab; /* l: variable */
+    }
+    *varname = name + 2;
+    if (*name == 'g')				/* global variable */
+	return &globvarht;
+    /* There must be no ':' or '#' in the rest of the name, unless g: is used
+     */
+    if (vim_strchr(name + 2, ':') != NULL
+			       || vim_strchr(name + 2, AUTOLOAD_CHAR) != NULL)
+	return NULL;
+    if (*name == 'b')				/* buffer variable */
+	return &curbuf->b_vars.dv_hashtab;
+    if (*name == 'w')				/* window variable */
+	return &curwin->w_vars.dv_hashtab;
+#ifdef FEAT_WINDOWS
+    if (*name == 't')				/* tab page variable */
+	return &curtab->tp_vars.dv_hashtab;
+#endif
+    if (*name == 'v')				/* v: variable */
+	return &vimvarht;
+    if (*name == 'a' && current_funccal != NULL) /* function argument */
+	return &current_funccal->l_avars.dv_hashtab;
+    if (*name == 'l' && current_funccal != NULL) /* local function variable */
+	return &current_funccal->l_vars.dv_hashtab;
+    if (*name == 's'				/* script variable */
+	    && current_SID > 0 && current_SID <= ga_scripts.ga_len)
+	return &SCRIPT_VARS(current_SID);
+    return NULL;
+}
+
+/*
+ * Get the string value of a (global/local) variable.
+ * Returns NULL when it doesn't exist.
+ */
+    char_u *
+get_var_value(name)
+    char_u	*name;
+{
+    dictitem_T	*v;
+
+    v = find_var(name, NULL);
+    if (v == NULL)
+	return NULL;
+    return get_tv_string(&v->di_tv);
+}
+
+/*
+ * Allocate a new hashtab for a sourced script.  It will be used while
+ * sourcing this script and when executing functions defined in the script.
+ */
+    void
+new_script_vars(id)
+    scid_T id;
+{
+    int		i;
+    hashtab_T	*ht;
+    scriptvar_T *sv;
+
+    if (ga_grow(&ga_scripts, (int)(id - ga_scripts.ga_len)) == OK)
+    {
+	/* Re-allocating ga_data means that an ht_array pointing to
+	 * ht_smallarray becomes invalid.  We can recognize this: ht_mask is
+	 * at its init value.  Also reset "v_dict", it's always the same. */
+	for (i = 1; i <= ga_scripts.ga_len; ++i)
+	{
+	    ht = &SCRIPT_VARS(i);
+	    if (ht->ht_mask == HT_INIT_SIZE - 1)
+		ht->ht_array = ht->ht_smallarray;
+	    sv = &SCRIPT_SV(i);
+	    sv->sv_var.di_tv.vval.v_dict = &sv->sv_dict;
+	}
+
+	while (ga_scripts.ga_len < id)
+	{
+	    sv = &SCRIPT_SV(ga_scripts.ga_len + 1);
+	    init_var_dict(&sv->sv_dict, &sv->sv_var);
+	    ++ga_scripts.ga_len;
+	}
+    }
+}
+
+/*
+ * Initialize dictionary "dict" as a scope and set variable "dict_var" to
+ * point to it.
+ */
+    void
+init_var_dict(dict, dict_var)
+    dict_T	*dict;
+    dictitem_T	*dict_var;
+{
+    hash_init(&dict->dv_hashtab);
+    dict->dv_refcount = 99999;
+    dict_var->di_tv.vval.v_dict = dict;
+    dict_var->di_tv.v_type = VAR_DICT;
+    dict_var->di_tv.v_lock = VAR_FIXED;
+    dict_var->di_flags = DI_FLAGS_RO | DI_FLAGS_FIX;
+    dict_var->di_key[0] = NUL;
+}
+
+/*
+ * Clean up a list of internal variables.
+ * Frees all allocated variables and the value they contain.
+ * Clears hashtab "ht", does not free it.
+ */
+    void
+vars_clear(ht)
+    hashtab_T *ht;
+{
+    vars_clear_ext(ht, TRUE);
+}
+
+/*
+ * Like vars_clear(), but only free the value if "free_val" is TRUE.
+ */
+    static void
+vars_clear_ext(ht, free_val)
+    hashtab_T	*ht;
+    int		free_val;
+{
+    int		todo;
+    hashitem_T	*hi;
+    dictitem_T	*v;
+
+    hash_lock(ht);
+    todo = (int)ht->ht_used;
+    for (hi = ht->ht_array; todo > 0; ++hi)
+    {
+	if (!HASHITEM_EMPTY(hi))
+	{
+	    --todo;
+
+	    /* Free the variable.  Don't remove it from the hashtab,
+	     * ht_array might change then.  hash_clear() takes care of it
+	     * later. */
+	    v = HI2DI(hi);
+	    if (free_val)
+		clear_tv(&v->di_tv);
+	    if ((v->di_flags & DI_FLAGS_FIX) == 0)
+		vim_free(v);
+	}
+    }
+    hash_clear(ht);
+    ht->ht_used = 0;
+}
+
+/*
+ * Delete a variable from hashtab "ht" at item "hi".
+ * Clear the variable value and free the dictitem.
+ */
+    static void
+delete_var(ht, hi)
+    hashtab_T	*ht;
+    hashitem_T	*hi;
+{
+    dictitem_T	*di = HI2DI(hi);
+
+    hash_remove(ht, hi);
+    clear_tv(&di->di_tv);
+    vim_free(di);
+}
+
+/*
+ * List the value of one internal variable.
+ */
+    static void
+list_one_var(v, prefix)
+    dictitem_T	*v;
+    char_u	*prefix;
+{
+    char_u	*tofree;
+    char_u	*s;
+    char_u	numbuf[NUMBUFLEN];
+
+    s = echo_string(&v->di_tv, &tofree, numbuf, ++current_copyID);
+    list_one_var_a(prefix, v->di_key, v->di_tv.v_type,
+						s == NULL ? (char_u *)"" : s);
+    vim_free(tofree);
+}
+
+    static void
+list_one_var_a(prefix, name, type, string)
+    char_u	*prefix;
+    char_u	*name;
+    int		type;
+    char_u	*string;
+{
+    msg_attr(prefix, 0);    /* don't use msg(), it overwrites "v:statusmsg" */
+    if (name != NULL)	/* "a:" vars don't have a name stored */
+	msg_puts(name);
+    msg_putchar(' ');
+    msg_advance(22);
+    if (type == VAR_NUMBER)
+	msg_putchar('#');
+    else if (type == VAR_FUNC)
+	msg_putchar('*');
+    else if (type == VAR_LIST)
+    {
+	msg_putchar('[');
+	if (*string == '[')
+	    ++string;
+    }
+    else if (type == VAR_DICT)
+    {
+	msg_putchar('{');
+	if (*string == '{')
+	    ++string;
+    }
+    else
+	msg_putchar(' ');
+
+    msg_outtrans(string);
+
+    if (type == VAR_FUNC)
+	msg_puts((char_u *)"()");
+}
+
+/*
+ * Set variable "name" to value in "tv".
+ * If the variable already exists, the value is updated.
+ * Otherwise the variable is created.
+ */
+    static void
+set_var(name, tv, copy)
+    char_u	*name;
+    typval_T	*tv;
+    int		copy;	    /* make copy of value in "tv" */
+{
+    dictitem_T	*v;
+    char_u	*varname;
+    hashtab_T	*ht;
+    char_u	*p;
+
+    if (tv->v_type == VAR_FUNC)
+    {
+	if (!(vim_strchr((char_u *)"wbs", name[0]) != NULL && name[1] == ':')
+		&& !ASCII_ISUPPER((name[0] != NUL && name[1] == ':')
+							 ? name[2] : name[0]))
+	{
+	    EMSG2(_("E704: Funcref variable name must start with a capital: %s"), name);
+	    return;
+	}
+	if (function_exists(name))
+	{
+	    EMSG2(_("E705: Variable name conflicts with existing function: %s"),
+									name);
+	    return;
+	}
+    }
+
+    ht = find_var_ht(name, &varname);
+    if (ht == NULL || *varname == NUL)
+    {
+	EMSG2(_(e_illvar), name);
+	return;
+    }
+
+    v = find_var_in_ht(ht, varname, TRUE);
+    if (v != NULL)
+    {
+	/* existing variable, need to clear the value */
+	if (var_check_ro(v->di_flags, name)
+				      || tv_check_lock(v->di_tv.v_lock, name))
+	    return;
+	if (v->di_tv.v_type != tv->v_type
+		&& !((v->di_tv.v_type == VAR_STRING
+			|| v->di_tv.v_type == VAR_NUMBER)
+		    && (tv->v_type == VAR_STRING
+			|| tv->v_type == VAR_NUMBER)))
+	{
+	    EMSG2(_("E706: Variable type mismatch for: %s"), name);
+	    return;
+	}
+
+	/*
+	 * Handle setting internal v: variables separately: we don't change
+	 * the type.
+	 */
+	if (ht == &vimvarht)
+	{
+	    if (v->di_tv.v_type == VAR_STRING)
+	    {
+		vim_free(v->di_tv.vval.v_string);
+		if (copy || tv->v_type != VAR_STRING)
+		    v->di_tv.vval.v_string = vim_strsave(get_tv_string(tv));
+		else
+		{
+		    /* Take over the string to avoid an extra alloc/free. */
+		    v->di_tv.vval.v_string = tv->vval.v_string;
+		    tv->vval.v_string = NULL;
+		}
+	    }
+	    else if (v->di_tv.v_type != VAR_NUMBER)
+		EMSG2(_(e_intern2), "set_var()");
+	    else
+		v->di_tv.vval.v_number = get_tv_number(tv);
+	    return;
+	}
+
+	clear_tv(&v->di_tv);
+    }
+    else		    /* add a new variable */
+    {
+	/* Can't add "v:" variable. */
+	if (ht == &vimvarht)
+	{
+	    EMSG2(_(e_illvar), name);
+	    return;
+	}
+
+	/* Make sure the variable name is valid. */
+	for (p = varname; *p != NUL; ++p)
+	    if (!eval_isnamec1(*p) && (p == varname || !VIM_ISDIGIT(*p))
+						       && *p != AUTOLOAD_CHAR)
+	    {
+		EMSG2(_(e_illvar), varname);
+		return;
+	    }
+
+	v = (dictitem_T *)alloc((unsigned)(sizeof(dictitem_T)
+							  + STRLEN(varname)));
+	if (v == NULL)
+	    return;
+	STRCPY(v->di_key, varname);
+	if (hash_add(ht, DI2HIKEY(v)) == FAIL)
+	{
+	    vim_free(v);
+	    return;
+	}
+	v->di_flags = 0;
+    }
+
+    if (copy || tv->v_type == VAR_NUMBER)
+	copy_tv(tv, &v->di_tv);
+    else
+    {
+	v->di_tv = *tv;
+	v->di_tv.v_lock = 0;
+	init_tv(tv);
+    }
+}
+
+/*
+ * Return TRUE if di_flags "flags" indicates variable "name" is read-only.
+ * Also give an error message.
+ */
+    static int
+var_check_ro(flags, name)
+    int		flags;
+    char_u	*name;
+{
+    if (flags & DI_FLAGS_RO)
+    {
+	EMSG2(_(e_readonlyvar), name);
+	return TRUE;
+    }
+    if ((flags & DI_FLAGS_RO_SBX) && sandbox)
+    {
+	EMSG2(_(e_readonlysbx), name);
+	return TRUE;
+    }
+    return FALSE;
+}
+
+/*
+ * Return TRUE if di_flags "flags" indicates variable "name" is fixed.
+ * Also give an error message.
+ */
+    static int
+var_check_fixed(flags, name)
+    int		flags;
+    char_u	*name;
+{
+    if (flags & DI_FLAGS_FIX)
+    {
+	EMSG2(_("E795: Cannot delete variable %s"), name);
+	return TRUE;
+    }
+    return FALSE;
+}
+
+/*
+ * Return TRUE if typeval "tv" is set to be locked (immutable).
+ * Also give an error message, using "name".
+ */
+    static int
+tv_check_lock(lock, name)
+    int		lock;
+    char_u	*name;
+{
+    if (lock & VAR_LOCKED)
+    {
+	EMSG2(_("E741: Value is locked: %s"),
+				name == NULL ? (char_u *)_("Unknown") : name);
+	return TRUE;
+    }
+    if (lock & VAR_FIXED)
+    {
+	EMSG2(_("E742: Cannot change value of %s"),
+				name == NULL ? (char_u *)_("Unknown") : name);
+	return TRUE;
+    }
+    return FALSE;
+}
+
+/*
+ * Copy the values from typval_T "from" to typval_T "to".
+ * When needed allocates string or increases reference count.
+ * Does not make a copy of a list or dict but copies the reference!
+ */
+    static void
+copy_tv(from, to)
+    typval_T *from;
+    typval_T *to;
+{
+    to->v_type = from->v_type;
+    to->v_lock = 0;
+    switch (from->v_type)
+    {
+	case VAR_NUMBER:
+	    to->vval.v_number = from->vval.v_number;
+	    break;
+	case VAR_STRING:
+	case VAR_FUNC:
+	    if (from->vval.v_string == NULL)
+		to->vval.v_string = NULL;
+	    else
+	    {
+		to->vval.v_string = vim_strsave(from->vval.v_string);
+		if (from->v_type == VAR_FUNC)
+		    func_ref(to->vval.v_string);
+	    }
+	    break;
+	case VAR_LIST:
+	    if (from->vval.v_list == NULL)
+		to->vval.v_list = NULL;
+	    else
+	    {
+		to->vval.v_list = from->vval.v_list;
+		++to->vval.v_list->lv_refcount;
+	    }
+	    break;
+	case VAR_DICT:
+	    if (from->vval.v_dict == NULL)
+		to->vval.v_dict = NULL;
+	    else
+	    {
+		to->vval.v_dict = from->vval.v_dict;
+		++to->vval.v_dict->dv_refcount;
+	    }
+	    break;
+	default:
+	    EMSG2(_(e_intern2), "copy_tv()");
+	    break;
+    }
+}
+
+/*
+ * Make a copy of an item.
+ * Lists and Dictionaries are also copied.  A deep copy if "deep" is set.
+ * For deepcopy() "copyID" is zero for a full copy or the ID for when a
+ * reference to an already copied list/dict can be used.
+ * Returns FAIL or OK.
+ */
+    static int
+item_copy(from, to, deep, copyID)
+    typval_T	*from;
+    typval_T	*to;
+    int		deep;
+    int		copyID;
+{
+    static int	recurse = 0;
+    int		ret = OK;
+
+    if (recurse >= DICT_MAXNEST)
+    {
+	EMSG(_("E698: variable nested too deep for making a copy"));
+	return FAIL;
+    }
+    ++recurse;
+
+    switch (from->v_type)
+    {
+	case VAR_NUMBER:
+	case VAR_STRING:
+	case VAR_FUNC:
+	    copy_tv(from, to);
+	    break;
+	case VAR_LIST:
+	    to->v_type = VAR_LIST;
+	    to->v_lock = 0;
+	    if (from->vval.v_list == NULL)
+		to->vval.v_list = NULL;
+	    else if (copyID != 0 && from->vval.v_list->lv_copyID == copyID)
+	    {
+		/* use the copy made earlier */
+		to->vval.v_list = from->vval.v_list->lv_copylist;
+		++to->vval.v_list->lv_refcount;
+	    }
+	    else
+		to->vval.v_list = list_copy(from->vval.v_list, deep, copyID);
+	    if (to->vval.v_list == NULL)
+		ret = FAIL;
+	    break;
+	case VAR_DICT:
+	    to->v_type = VAR_DICT;
+	    to->v_lock = 0;
+	    if (from->vval.v_dict == NULL)
+		to->vval.v_dict = NULL;
+	    else if (copyID != 0 && from->vval.v_dict->dv_copyID == copyID)
+	    {
+		/* use the copy made earlier */
+		to->vval.v_dict = from->vval.v_dict->dv_copydict;
+		++to->vval.v_dict->dv_refcount;
+	    }
+	    else
+		to->vval.v_dict = dict_copy(from->vval.v_dict, deep, copyID);
+	    if (to->vval.v_dict == NULL)
+		ret = FAIL;
+	    break;
+	default:
+	    EMSG2(_(e_intern2), "item_copy()");
+	    ret = FAIL;
+    }
+    --recurse;
+    return ret;
+}
+
+/*
+ * ":echo expr1 ..."	print each argument separated with a space, add a
+ *			newline at the end.
+ * ":echon expr1 ..."	print each argument plain.
+ */
+    void
+ex_echo(eap)
+    exarg_T	*eap;
+{
+    char_u	*arg = eap->arg;
+    typval_T	rettv;
+    char_u	*tofree;
+    char_u	*p;
+    int		needclr = TRUE;
+    int		atstart = TRUE;
+    char_u	numbuf[NUMBUFLEN];
+
+    if (eap->skip)
+	++emsg_skip;
+    while (*arg != NUL && *arg != '|' && *arg != '\n' && !got_int)
+    {
+	p = arg;
+	if (eval1(&arg, &rettv, !eap->skip) == FAIL)
+	{
+	    /*
+	     * Report the invalid expression unless the expression evaluation
+	     * has been cancelled due to an aborting error, an interrupt, or an
+	     * exception.
+	     */
+	    if (!aborting())
+		EMSG2(_(e_invexpr2), p);
+	    break;
+	}
+	if (!eap->skip)
+	{
+	    if (atstart)
+	    {
+		atstart = FALSE;
+		/* Call msg_start() after eval1(), evaluating the expression
+		 * may cause a message to appear. */
+		if (eap->cmdidx == CMD_echo)
+		    msg_start();
+	    }
+	    else if (eap->cmdidx == CMD_echo)
+		msg_puts_attr((char_u *)" ", echo_attr);
+	    p = echo_string(&rettv, &tofree, numbuf, ++current_copyID);
+	    if (p != NULL)
+		for ( ; *p != NUL && !got_int; ++p)
+		{
+		    if (*p == '\n' || *p == '\r' || *p == TAB)
+		    {
+			if (*p != TAB && needclr)
+			{
+			    /* remove any text still there from the command */
+			    msg_clr_eos();
+			    needclr = FALSE;
+			}
+			msg_putchar_attr(*p, echo_attr);
+		    }
+		    else
+		    {
+#ifdef FEAT_MBYTE
+			if (has_mbyte)
+			{
+			    int i = (*mb_ptr2len)(p);
+
+			    (void)msg_outtrans_len_attr(p, i, echo_attr);
+			    p += i - 1;
+			}
+			else
+#endif
+			    (void)msg_outtrans_len_attr(p, 1, echo_attr);
+		    }
+		}
+	    vim_free(tofree);
+	}
+	clear_tv(&rettv);
+	arg = skipwhite(arg);
+    }
+    eap->nextcmd = check_nextcmd(arg);
+
+    if (eap->skip)
+	--emsg_skip;
+    else
+    {
+	/* remove text that may still be there from the command */
+	if (needclr)
+	    msg_clr_eos();
+	if (eap->cmdidx == CMD_echo)
+	    msg_end();
+    }
+}
+
+/*
+ * ":echohl {name}".
+ */
+    void
+ex_echohl(eap)
+    exarg_T	*eap;
+{
+    int		id;
+
+    id = syn_name2id(eap->arg);
+    if (id == 0)
+	echo_attr = 0;
+    else
+	echo_attr = syn_id2attr(id);
+}
+
+/*
+ * ":execute expr1 ..."	execute the result of an expression.
+ * ":echomsg expr1 ..."	Print a message
+ * ":echoerr expr1 ..."	Print an error
+ * Each gets spaces around each argument and a newline at the end for
+ * echo commands
+ */
+    void
+ex_execute(eap)
+    exarg_T	*eap;
+{
+    char_u	*arg = eap->arg;
+    typval_T	rettv;
+    int		ret = OK;
+    char_u	*p;
+    garray_T	ga;
+    int		len;
+    int		save_did_emsg;
+
+    ga_init2(&ga, 1, 80);
+
+    if (eap->skip)
+	++emsg_skip;
+    while (*arg != NUL && *arg != '|' && *arg != '\n')
+    {
+	p = arg;
+	if (eval1(&arg, &rettv, !eap->skip) == FAIL)
+	{
+	    /*
+	     * Report the invalid expression unless the expression evaluation
+	     * has been cancelled due to an aborting error, an interrupt, or an
+	     * exception.
+	     */
+	    if (!aborting())
+		EMSG2(_(e_invexpr2), p);
+	    ret = FAIL;
+	    break;
+	}
+
+	if (!eap->skip)
+	{
+	    p = get_tv_string(&rettv);
+	    len = (int)STRLEN(p);
+	    if (ga_grow(&ga, len + 2) == FAIL)
+	    {
+		clear_tv(&rettv);
+		ret = FAIL;
+		break;
+	    }
+	    if (ga.ga_len)
+		((char_u *)(ga.ga_data))[ga.ga_len++] = ' ';
+	    STRCPY((char_u *)(ga.ga_data) + ga.ga_len, p);
+	    ga.ga_len += len;
+	}
+
+	clear_tv(&rettv);
+	arg = skipwhite(arg);
+    }
+
+    if (ret != FAIL && ga.ga_data != NULL)
+    {
+	if (eap->cmdidx == CMD_echomsg)
+	{
+	    MSG_ATTR(ga.ga_data, echo_attr);
+	    out_flush();
+	}
+	else if (eap->cmdidx == CMD_echoerr)
+	{
+	    /* We don't want to abort following commands, restore did_emsg. */
+	    save_did_emsg = did_emsg;
+	    EMSG((char_u *)ga.ga_data);
+	    if (!force_abort)
+		did_emsg = save_did_emsg;
+	}
+	else if (eap->cmdidx == CMD_execute)
+	    do_cmdline((char_u *)ga.ga_data,
+		       eap->getline, eap->cookie, DOCMD_NOWAIT|DOCMD_VERBOSE);
+    }
+
+    ga_clear(&ga);
+
+    if (eap->skip)
+	--emsg_skip;
+
+    eap->nextcmd = check_nextcmd(arg);
+}
+
+/*
+ * Skip over the name of an option: "&option", "&g:option" or "&l:option".
+ * "arg" points to the "&" or '+' when called, to "option" when returning.
+ * Returns NULL when no option name found.  Otherwise pointer to the char
+ * after the option name.
+ */
+    static char_u *
+find_option_end(arg, opt_flags)
+    char_u	**arg;
+    int		*opt_flags;
+{
+    char_u	*p = *arg;
+
+    ++p;
+    if (*p == 'g' && p[1] == ':')
+    {
+	*opt_flags = OPT_GLOBAL;
+	p += 2;
+    }
+    else if (*p == 'l' && p[1] == ':')
+    {
+	*opt_flags = OPT_LOCAL;
+	p += 2;
+    }
+    else
+	*opt_flags = 0;
+
+    if (!ASCII_ISALPHA(*p))
+	return NULL;
+    *arg = p;
+
+    if (p[0] == 't' && p[1] == '_' && p[2] != NUL && p[3] != NUL)
+	p += 4;	    /* termcap option */
+    else
+	while (ASCII_ISALPHA(*p))
+	    ++p;
+    return p;
+}
+
+/*
+ * ":function"
+ */
+    void
+ex_function(eap)
+    exarg_T	*eap;
+{
+    char_u	*theline;
+    int		j;
+    int		c;
+    int		saved_did_emsg;
+    char_u	*name = NULL;
+    char_u	*p;
+    char_u	*arg;
+    char_u	*line_arg = NULL;
+    garray_T	newargs;
+    garray_T	newlines;
+    int		varargs = FALSE;
+    int		mustend = FALSE;
+    int		flags = 0;
+    ufunc_T	*fp;
+    int		indent;
+    int		nesting;
+    char_u	*skip_until = NULL;
+    dictitem_T	*v;
+    funcdict_T	fudi;
+    static int	func_nr = 0;	    /* number for nameless function */
+    int		paren;
+    hashtab_T	*ht;
+    int		todo;
+    hashitem_T	*hi;
+    int		sourcing_lnum_off;
+
+    /*
+     * ":function" without argument: list functions.
+     */
+    if (ends_excmd(*eap->arg))
+    {
+	if (!eap->skip)
+	{
+	    todo = (int)func_hashtab.ht_used;
+	    for (hi = func_hashtab.ht_array; todo > 0 && !got_int; ++hi)
+	    {
+		if (!HASHITEM_EMPTY(hi))
+		{
+		    --todo;
+		    fp = HI2UF(hi);
+		    if (!isdigit(*fp->uf_name))
+			list_func_head(fp, FALSE);
+		}
+	    }
+	}
+	eap->nextcmd = check_nextcmd(eap->arg);
+	return;
+    }
+
+    /*
+     * ":function /pat": list functions matching pattern.
+     */
+    if (*eap->arg == '/')
+    {
+	p = skip_regexp(eap->arg + 1, '/', TRUE, NULL);
+	if (!eap->skip)
+	{
+	    regmatch_T	regmatch;
+
+	    c = *p;
+	    *p = NUL;
+	    regmatch.regprog = vim_regcomp(eap->arg + 1, RE_MAGIC);
+	    *p = c;
+	    if (regmatch.regprog != NULL)
+	    {
+		regmatch.rm_ic = p_ic;
+
+		todo = (int)func_hashtab.ht_used;
+		for (hi = func_hashtab.ht_array; todo > 0 && !got_int; ++hi)
+		{
+		    if (!HASHITEM_EMPTY(hi))
+		    {
+			--todo;
+			fp = HI2UF(hi);
+			if (!isdigit(*fp->uf_name)
+				    && vim_regexec(&regmatch, fp->uf_name, 0))
+			    list_func_head(fp, FALSE);
+		    }
+		}
+	    }
+	}
+	if (*p == '/')
+	    ++p;
+	eap->nextcmd = check_nextcmd(p);
+	return;
+    }
+
+    /*
+     * Get the function name.  There are these situations:
+     * func	    normal function name
+     *		    "name" == func, "fudi.fd_dict" == NULL
+     * dict.func    new dictionary entry
+     *		    "name" == NULL, "fudi.fd_dict" set,
+     *		    "fudi.fd_di" == NULL, "fudi.fd_newkey" == func
+     * dict.func    existing dict entry with a Funcref
+     *		    "name" == func, "fudi.fd_dict" set,
+     *		    "fudi.fd_di" set, "fudi.fd_newkey" == NULL
+     * dict.func    existing dict entry that's not a Funcref
+     *		    "name" == NULL, "fudi.fd_dict" set,
+     *		    "fudi.fd_di" set, "fudi.fd_newkey" == NULL
+     */
+    p = eap->arg;
+    name = trans_function_name(&p, eap->skip, 0, &fudi);
+    paren = (vim_strchr(p, '(') != NULL);
+    if (name == NULL && (fudi.fd_dict == NULL || !paren) && !eap->skip)
+    {
+	/*
+	 * Return on an invalid expression in braces, unless the expression
+	 * evaluation has been cancelled due to an aborting error, an
+	 * interrupt, or an exception.
+	 */
+	if (!aborting())
+	{
+	    if (!eap->skip && fudi.fd_newkey != NULL)
+		EMSG2(_(e_dictkey), fudi.fd_newkey);
+	    vim_free(fudi.fd_newkey);
+	    return;
+	}
+	else
+	    eap->skip = TRUE;
+    }
+
+    /* An error in a function call during evaluation of an expression in magic
+     * braces should not cause the function not to be defined. */
+    saved_did_emsg = did_emsg;
+    did_emsg = FALSE;
+
+    /*
+     * ":function func" with only function name: list function.
+     */
+    if (!paren)
+    {
+	if (!ends_excmd(*skipwhite(p)))
+	{
+	    EMSG(_(e_trailing));
+	    goto ret_free;
+	}
+	eap->nextcmd = check_nextcmd(p);
+	if (eap->nextcmd != NULL)
+	    *p = NUL;
+	if (!eap->skip && !got_int)
+	{
+	    fp = find_func(name);
+	    if (fp != NULL)
+	    {
+		list_func_head(fp, TRUE);
+		for (j = 0; j < fp->uf_lines.ga_len && !got_int; ++j)
+		{
+		    if (FUNCLINE(fp, j) == NULL)
+			continue;
+		    msg_putchar('\n');
+		    msg_outnum((long)(j + 1));
+		    if (j < 9)
+			msg_putchar(' ');
+		    if (j < 99)
+			msg_putchar(' ');
+		    msg_prt_line(FUNCLINE(fp, j), FALSE);
+		    out_flush();	/* show a line at a time */
+		    ui_breakcheck();
+		}
+		if (!got_int)
+		{
+		    msg_putchar('\n');
+		    msg_puts((char_u *)"   endfunction");
+		}
+	    }
+	    else
+		emsg_funcname("E123: Undefined function: %s", name);
+	}
+	goto ret_free;
+    }
+
+    /*
+     * ":function name(arg1, arg2)" Define function.
+     */
+    p = skipwhite(p);
+    if (*p != '(')
+    {
+	if (!eap->skip)
+	{
+	    EMSG2(_("E124: Missing '(': %s"), eap->arg);
+	    goto ret_free;
+	}
+	/* attempt to continue by skipping some text */
+	if (vim_strchr(p, '(') != NULL)
+	    p = vim_strchr(p, '(');
+    }
+    p = skipwhite(p + 1);
+
+    ga_init2(&newargs, (int)sizeof(char_u *), 3);
+    ga_init2(&newlines, (int)sizeof(char_u *), 3);
+
+    if (!eap->skip)
+    {
+	/* Check the name of the function.  Unless it's a dictionary function
+	 * (that we are overwriting). */
+	if (name != NULL)
+	    arg = name;
+	else
+	    arg = fudi.fd_newkey;
+	if (arg != NULL && (fudi.fd_di == NULL
+				     || fudi.fd_di->di_tv.v_type != VAR_FUNC))
+	{
+	    if (*arg == K_SPECIAL)
+		j = 3;
+	    else
+		j = 0;
+	    while (arg[j] != NUL && (j == 0 ? eval_isnamec1(arg[j])
+						      : eval_isnamec(arg[j])))
+		++j;
+	    if (arg[j] != NUL)
+		emsg_funcname(_(e_invarg2), arg);
+	}
+    }
+
+    /*
+     * Isolate the arguments: "arg1, arg2, ...)"
+     */
+    while (*p != ')')
+    {
+	if (p[0] == '.' && p[1] == '.' && p[2] == '.')
+	{
+	    varargs = TRUE;
+	    p += 3;
+	    mustend = TRUE;
+	}
+	else
+	{
+	    arg = p;
+	    while (ASCII_ISALNUM(*p) || *p == '_')
+		++p;
+	    if (arg == p || isdigit(*arg)
+		    || (p - arg == 9 && STRNCMP(arg, "firstline", 9) == 0)
+		    || (p - arg == 8 && STRNCMP(arg, "lastline", 8) == 0))
+	    {
+		if (!eap->skip)
+		    EMSG2(_("E125: Illegal argument: %s"), arg);
+		break;
+	    }
+	    if (ga_grow(&newargs, 1) == FAIL)
+		goto erret;
+	    c = *p;
+	    *p = NUL;
+	    arg = vim_strsave(arg);
+	    if (arg == NULL)
+		goto erret;
+	    ((char_u **)(newargs.ga_data))[newargs.ga_len] = arg;
+	    *p = c;
+	    newargs.ga_len++;
+	    if (*p == ',')
+		++p;
+	    else
+		mustend = TRUE;
+	}
+	p = skipwhite(p);
+	if (mustend && *p != ')')
+	{
+	    if (!eap->skip)
+		EMSG2(_(e_invarg2), eap->arg);
+	    break;
+	}
+    }
+    ++p;	/* skip the ')' */
+
+    /* find extra arguments "range", "dict" and "abort" */
+    for (;;)
+    {
+	p = skipwhite(p);
+	if (STRNCMP(p, "range", 5) == 0)
+	{
+	    flags |= FC_RANGE;
+	    p += 5;
+	}
+	else if (STRNCMP(p, "dict", 4) == 0)
+	{
+	    flags |= FC_DICT;
+	    p += 4;
+	}
+	else if (STRNCMP(p, "abort", 5) == 0)
+	{
+	    flags |= FC_ABORT;
+	    p += 5;
+	}
+	else
+	    break;
+    }
+
+    /* When there is a line break use what follows for the function body.
+     * Makes 'exe "func Test()\n...\nendfunc"' work. */
+    if (*p == '\n')
+	line_arg = p + 1;
+    else if (*p != NUL && *p != '"' && !eap->skip && !did_emsg)
+	EMSG(_(e_trailing));
+
+    /*
+     * Read the body of the function, until ":endfunction" is found.
+     */
+    if (KeyTyped)
+    {
+	/* Check if the function already exists, don't let the user type the
+	 * whole function before telling him it doesn't work!  For a script we
+	 * need to skip the body to be able to find what follows. */
+	if (!eap->skip && !eap->forceit)
+	{
+	    if (fudi.fd_dict != NULL && fudi.fd_newkey == NULL)
+		EMSG(_(e_funcdict));
+	    else if (name != NULL && find_func(name) != NULL)
+		emsg_funcname(e_funcexts, name);
+	}
+
+	if (!eap->skip && did_emsg)
+	    goto erret;
+
+	msg_putchar('\n');	    /* don't overwrite the function name */
+	cmdline_row = msg_row;
+    }
+
+    indent = 2;
+    nesting = 0;
+    for (;;)
+    {
+	msg_scroll = TRUE;
+	need_wait_return = FALSE;
+	sourcing_lnum_off = sourcing_lnum;
+
+	if (line_arg != NULL)
+	{
+	    /* Use eap->arg, split up in parts by line breaks. */
+	    theline = line_arg;
+	    p = vim_strchr(theline, '\n');
+	    if (p == NULL)
+		line_arg += STRLEN(line_arg);
+	    else
+	    {
+		*p = NUL;
+		line_arg = p + 1;
+	    }
+	}
+	else if (eap->getline == NULL)
+	    theline = getcmdline(':', 0L, indent);
+	else
+	    theline = eap->getline(':', eap->cookie, indent);
+	if (KeyTyped)
+	    lines_left = Rows - 1;
+	if (theline == NULL)
+	{
+	    EMSG(_("E126: Missing :endfunction"));
+	    goto erret;
+	}
+
+	/* Detect line continuation: sourcing_lnum increased more than one. */
+	if (sourcing_lnum > sourcing_lnum_off + 1)
+	    sourcing_lnum_off = sourcing_lnum - sourcing_lnum_off - 1;
+	else
+	    sourcing_lnum_off = 0;
+
+	if (skip_until != NULL)
+	{
+	    /* between ":append" and "." and between ":python <<EOF" and "EOF"
+	     * don't check for ":endfunc". */
+	    if (STRCMP(theline, skip_until) == 0)
+	    {
+		vim_free(skip_until);
+		skip_until = NULL;
+	    }
+	}
+	else
+	{
+	    /* skip ':' and blanks*/
+	    for (p = theline; vim_iswhite(*p) || *p == ':'; ++p)
+		;
+
+	    /* Check for "endfunction". */
+	    if (checkforcmd(&p, "endfunction", 4) && nesting-- == 0)
+	    {
+		if (line_arg == NULL)
+		    vim_free(theline);
+		break;
+	    }
+
+	    /* Increase indent inside "if", "while", "for" and "try", decrease
+	     * at "end". */
+	    if (indent > 2 && STRNCMP(p, "end", 3) == 0)
+		indent -= 2;
+	    else if (STRNCMP(p, "if", 2) == 0
+		    || STRNCMP(p, "wh", 2) == 0
+		    || STRNCMP(p, "for", 3) == 0
+		    || STRNCMP(p, "try", 3) == 0)
+		indent += 2;
+
+	    /* Check for defining a function inside this function. */
+	    if (checkforcmd(&p, "function", 2))
+	    {
+		if (*p == '!')
+		    p = skipwhite(p + 1);
+		p += eval_fname_script(p);
+		if (ASCII_ISALPHA(*p))
+		{
+		    vim_free(trans_function_name(&p, TRUE, 0, NULL));
+		    if (*skipwhite(p) == '(')
+		    {
+			++nesting;
+			indent += 2;
+		    }
+		}
+	    }
+
+	    /* Check for ":append" or ":insert". */
+	    p = skip_range(p, NULL);
+	    if ((p[0] == 'a' && (!ASCII_ISALPHA(p[1]) || p[1] == 'p'))
+		    || (p[0] == 'i'
+			&& (!ASCII_ISALPHA(p[1]) || (p[1] == 'n'
+				&& (!ASCII_ISALPHA(p[2]) || (p[2] == 's'))))))
+		skip_until = vim_strsave((char_u *)".");
+
+	    /* Check for ":python <<EOF", ":tcl <<EOF", etc. */
+	    arg = skipwhite(skiptowhite(p));
+	    if (arg[0] == '<' && arg[1] =='<'
+		    && ((p[0] == 'p' && p[1] == 'y'
+				    && (!ASCII_ISALPHA(p[2]) || p[2] == 't'))
+			|| (p[0] == 'p' && p[1] == 'e'
+				    && (!ASCII_ISALPHA(p[2]) || p[2] == 'r'))
+			|| (p[0] == 't' && p[1] == 'c'
+				    && (!ASCII_ISALPHA(p[2]) || p[2] == 'l'))
+			|| (p[0] == 'r' && p[1] == 'u' && p[2] == 'b'
+				    && (!ASCII_ISALPHA(p[3]) || p[3] == 'y'))
+			|| (p[0] == 'm' && p[1] == 'z'
+				    && (!ASCII_ISALPHA(p[2]) || p[2] == 's'))
+			))
+	    {
+		/* ":python <<" continues until a dot, like ":append" */
+		p = skipwhite(arg + 2);
+		if (*p == NUL)
+		    skip_until = vim_strsave((char_u *)".");
+		else
+		    skip_until = vim_strsave(p);
+	    }
+	}
+
+	/* Add the line to the function. */
+	if (ga_grow(&newlines, 1 + sourcing_lnum_off) == FAIL)
+	{
+	    if (line_arg == NULL)
+		vim_free(theline);
+	    goto erret;
+	}
+
+	/* Copy the line to newly allocated memory.  get_one_sourceline()
+	 * allocates 250 bytes per line, this saves 80% on average.  The cost
+	 * is an extra alloc/free. */
+	p = vim_strsave(theline);
+	if (p != NULL)
+	{
+	    if (line_arg == NULL)
+		vim_free(theline);
+	    theline = p;
+	}
+
+	((char_u **)(newlines.ga_data))[newlines.ga_len++] = theline;
+
+	/* Add NULL lines for continuation lines, so that the line count is
+	 * equal to the index in the growarray.   */
+	while (sourcing_lnum_off-- > 0)
+	    ((char_u **)(newlines.ga_data))[newlines.ga_len++] = NULL;
+
+	/* Check for end of eap->arg. */
+	if (line_arg != NULL && *line_arg == NUL)
+	    line_arg = NULL;
+    }
+
+    /* Don't define the function when skipping commands or when an error was
+     * detected. */
+    if (eap->skip || did_emsg)
+	goto erret;
+
+    /*
+     * If there are no errors, add the function
+     */
+    if (fudi.fd_dict == NULL)
+    {
+	v = find_var(name, &ht);
+	if (v != NULL && v->di_tv.v_type == VAR_FUNC)
+	{
+	    emsg_funcname("E707: Function name conflicts with variable: %s",
+									name);
+	    goto erret;
+	}
+
+	fp = find_func(name);
+	if (fp != NULL)
+	{
+	    if (!eap->forceit)
+	    {
+		emsg_funcname(e_funcexts, name);
+		goto erret;
+	    }
+	    if (fp->uf_calls > 0)
+	    {
+		emsg_funcname("E127: Cannot redefine function %s: It is in use",
+									name);
+		goto erret;
+	    }
+	    /* redefine existing function */
+	    ga_clear_strings(&(fp->uf_args));
+	    ga_clear_strings(&(fp->uf_lines));
+	    vim_free(name);
+	    name = NULL;
+	}
+    }
+    else
+    {
+	char	numbuf[20];
+
+	fp = NULL;
+	if (fudi.fd_newkey == NULL && !eap->forceit)
+	{
+	    EMSG(_(e_funcdict));
+	    goto erret;
+	}
+	if (fudi.fd_di == NULL)
+	{
+	    /* Can't add a function to a locked dictionary */
+	    if (tv_check_lock(fudi.fd_dict->dv_lock, eap->arg))
+		goto erret;
+	}
+	    /* Can't change an existing function if it is locked */
+	else if (tv_check_lock(fudi.fd_di->di_tv.v_lock, eap->arg))
+	    goto erret;
+
+	/* Give the function a sequential number.  Can only be used with a
+	 * Funcref! */
+	vim_free(name);
+	sprintf(numbuf, "%d", ++func_nr);
+	name = vim_strsave((char_u *)numbuf);
+	if (name == NULL)
+	    goto erret;
+    }
+
+    if (fp == NULL)
+    {
+	if (fudi.fd_dict == NULL && vim_strchr(name, AUTOLOAD_CHAR) != NULL)
+	{
+	    int	    slen, plen;
+	    char_u  *scriptname;
+
+	    /* Check that the autoload name matches the script name. */
+	    j = FAIL;
+	    if (sourcing_name != NULL)
+	    {
+		scriptname = autoload_name(name);
+		if (scriptname != NULL)
+		{
+		    p = vim_strchr(scriptname, '/');
+		    plen = (int)STRLEN(p);
+		    slen = (int)STRLEN(sourcing_name);
+		    if (slen > plen && fnamecmp(p,
+					    sourcing_name + slen - plen) == 0)
+			j = OK;
+		    vim_free(scriptname);
+		}
+	    }
+	    if (j == FAIL)
+	    {
+		EMSG2(_("E746: Function name does not match script file name: %s"), name);
+		goto erret;
+	    }
+	}
+
+	fp = (ufunc_T *)alloc((unsigned)(sizeof(ufunc_T) + STRLEN(name)));
+	if (fp == NULL)
+	    goto erret;
+
+	if (fudi.fd_dict != NULL)
+	{
+	    if (fudi.fd_di == NULL)
+	    {
+		/* add new dict entry */
+		fudi.fd_di = dictitem_alloc(fudi.fd_newkey);
+		if (fudi.fd_di == NULL)
+		{
+		    vim_free(fp);
+		    goto erret;
+		}
+		if (dict_add(fudi.fd_dict, fudi.fd_di) == FAIL)
+		{
+		    vim_free(fudi.fd_di);
+		    vim_free(fp);
+		    goto erret;
+		}
+	    }
+	    else
+		/* overwrite existing dict entry */
+		clear_tv(&fudi.fd_di->di_tv);
+	    fudi.fd_di->di_tv.v_type = VAR_FUNC;
+	    fudi.fd_di->di_tv.v_lock = 0;
+	    fudi.fd_di->di_tv.vval.v_string = vim_strsave(name);
+	    fp->uf_refcount = 1;
+
+	    /* behave like "dict" was used */
+	    flags |= FC_DICT;
+	}
+
+	/* insert the new function in the function list */
+	STRCPY(fp->uf_name, name);
+	hash_add(&func_hashtab, UF2HIKEY(fp));
+    }
+    fp->uf_args = newargs;
+    fp->uf_lines = newlines;
+#ifdef FEAT_PROFILE
+    fp->uf_tml_count = NULL;
+    fp->uf_tml_total = NULL;
+    fp->uf_tml_self = NULL;
+    fp->uf_profiling = FALSE;
+    if (prof_def_func())
+	func_do_profile(fp);
+#endif
+    fp->uf_varargs = varargs;
+    fp->uf_flags = flags;
+    fp->uf_calls = 0;
+    fp->uf_script_ID = current_SID;
+    goto ret_free;
+
+erret:
+    ga_clear_strings(&newargs);
+    ga_clear_strings(&newlines);
+ret_free:
+    vim_free(skip_until);
+    vim_free(fudi.fd_newkey);
+    vim_free(name);
+    did_emsg |= saved_did_emsg;
+}
+
+/*
+ * Get a function name, translating "<SID>" and "<SNR>".
+ * Also handles a Funcref in a List or Dictionary.
+ * Returns the function name in allocated memory, or NULL for failure.
+ * flags:
+ * TFN_INT:   internal function name OK
+ * TFN_QUIET: be quiet
+ * Advances "pp" to just after the function name (if no error).
+ */
+    static char_u *
+trans_function_name(pp, skip, flags, fdp)
+    char_u	**pp;
+    int		skip;		/* only find the end, don't evaluate */
+    int		flags;
+    funcdict_T	*fdp;		/* return: info about dictionary used */
+{
+    char_u	*name = NULL;
+    char_u	*start;
+    char_u	*end;
+    int		lead;
+    char_u	sid_buf[20];
+    int		len;
+    lval_T	lv;
+
+    if (fdp != NULL)
+	vim_memset(fdp, 0, sizeof(funcdict_T));
+    start = *pp;
+
+    /* Check for hard coded <SNR>: already translated function ID (from a user
+     * command). */
+    if ((*pp)[0] == K_SPECIAL && (*pp)[1] == KS_EXTRA
+						   && (*pp)[2] == (int)KE_SNR)
+    {
+	*pp += 3;
+	len = get_id_len(pp) + 3;
+	return vim_strnsave(start, len);
+    }
+
+    /* A name starting with "<SID>" or "<SNR>" is local to a script.  But
+     * don't skip over "s:", get_lval() needs it for "s:dict.func". */
+    lead = eval_fname_script(start);
+    if (lead > 2)
+	start += lead;
+
+    end = get_lval(start, NULL, &lv, FALSE, skip, flags & TFN_QUIET,
+					      lead > 2 ? 0 : FNE_CHECK_START);
+    if (end == start)
+    {
+	if (!skip)
+	    EMSG(_("E129: Function name required"));
+	goto theend;
+    }
+    if (end == NULL || (lv.ll_tv != NULL && (lead > 2 || lv.ll_range)))
+    {
+	/*
+	 * Report an invalid expression in braces, unless the expression
+	 * evaluation has been cancelled due to an aborting error, an
+	 * interrupt, or an exception.
+	 */
+	if (!aborting())
+	{
+	    if (end != NULL)
+		EMSG2(_(e_invarg2), start);
+	}
+	else
+	    *pp = find_name_end(start, NULL, NULL, FNE_INCL_BR);
+	goto theend;
+    }
+
+    if (lv.ll_tv != NULL)
+    {
+	if (fdp != NULL)
+	{
+	    fdp->fd_dict = lv.ll_dict;
+	    fdp->fd_newkey = lv.ll_newkey;
+	    lv.ll_newkey = NULL;
+	    fdp->fd_di = lv.ll_di;
+	}
+	if (lv.ll_tv->v_type == VAR_FUNC && lv.ll_tv->vval.v_string != NULL)
+	{
+	    name = vim_strsave(lv.ll_tv->vval.v_string);
+	    *pp = end;
+	}
+	else
+	{
+	    if (!skip && !(flags & TFN_QUIET) && (fdp == NULL
+			     || lv.ll_dict == NULL || fdp->fd_newkey == NULL))
+		EMSG(_(e_funcref));
+	    else
+		*pp = end;
+	    name = NULL;
+	}
+	goto theend;
+    }
+
+    if (lv.ll_name == NULL)
+    {
+	/* Error found, but continue after the function name. */
+	*pp = end;
+	goto theend;
+    }
+
+    if (lv.ll_exp_name != NULL)
+    {
+	len = (int)STRLEN(lv.ll_exp_name);
+	if (lead <= 2 && lv.ll_name == lv.ll_exp_name
+					 && STRNCMP(lv.ll_name, "s:", 2) == 0)
+	{
+	    /* When there was "s:" already or the name expanded to get a
+	     * leading "s:" then remove it. */
+	    lv.ll_name += 2;
+	    len -= 2;
+	    lead = 2;
+	}
+    }
+    else
+    {
+	if (lead == 2)	/* skip over "s:" */
+	    lv.ll_name += 2;
+	len = (int)(end - lv.ll_name);
+    }
+
+    /*
+     * Copy the function name to allocated memory.
+     * Accept <SID>name() inside a script, translate into <SNR>123_name().
+     * Accept <SNR>123_name() outside a script.
+     */
+    if (skip)
+	lead = 0;	/* do nothing */
+    else if (lead > 0)
+    {
+	lead = 3;
+	if ((lv.ll_exp_name != NULL && eval_fname_sid(lv.ll_exp_name))
+						       || eval_fname_sid(*pp))
+	{
+	    /* It's "s:" or "<SID>" */
+	    if (current_SID <= 0)
+	    {
+		EMSG(_(e_usingsid));
+		goto theend;
+	    }
+	    sprintf((char *)sid_buf, "%ld_", (long)current_SID);
+	    lead += (int)STRLEN(sid_buf);
+	}
+    }
+    else if (!(flags & TFN_INT) && builtin_function(lv.ll_name))
+    {
+	EMSG2(_("E128: Function name must start with a capital or contain a colon: %s"), lv.ll_name);
+	goto theend;
+    }
+    name = alloc((unsigned)(len + lead + 1));
+    if (name != NULL)
+    {
+	if (lead > 0)
+	{
+	    name[0] = K_SPECIAL;
+	    name[1] = KS_EXTRA;
+	    name[2] = (int)KE_SNR;
+	    if (lead > 3)	/* If it's "<SID>" */
+		STRCPY(name + 3, sid_buf);
+	}
+	mch_memmove(name + lead, lv.ll_name, (size_t)len);
+	name[len + lead] = NUL;
+    }
+    *pp = end;
+
+theend:
+    clear_lval(&lv);
+    return name;
+}
+
+/*
+ * Return 5 if "p" starts with "<SID>" or "<SNR>" (ignoring case).
+ * Return 2 if "p" starts with "s:".
+ * Return 0 otherwise.
+ */
+    static int
+eval_fname_script(p)
+    char_u	*p;
+{
+    if (p[0] == '<' && (STRNICMP(p + 1, "SID>", 4) == 0
+					  || STRNICMP(p + 1, "SNR>", 4) == 0))
+	return 5;
+    if (p[0] == 's' && p[1] == ':')
+	return 2;
+    return 0;
+}
+
+/*
+ * Return TRUE if "p" starts with "<SID>" or "s:".
+ * Only works if eval_fname_script() returned non-zero for "p"!
+ */
+    static int
+eval_fname_sid(p)
+    char_u	*p;
+{
+    return (*p == 's' || TOUPPER_ASC(p[2]) == 'I');
+}
+
+/*
+ * List the head of the function: "name(arg1, arg2)".
+ */
+    static void
+list_func_head(fp, indent)
+    ufunc_T	*fp;
+    int		indent;
+{
+    int		j;
+
+    msg_start();
+    if (indent)
+	MSG_PUTS("   ");
+    MSG_PUTS("function ");
+    if (fp->uf_name[0] == K_SPECIAL)
+    {
+	MSG_PUTS_ATTR("<SNR>", hl_attr(HLF_8));
+	msg_puts(fp->uf_name + 3);
+    }
+    else
+	msg_puts(fp->uf_name);
+    msg_putchar('(');
+    for (j = 0; j < fp->uf_args.ga_len; ++j)
+    {
+	if (j)
+	    MSG_PUTS(", ");
+	msg_puts(FUNCARG(fp, j));
+    }
+    if (fp->uf_varargs)
+    {
+	if (j)
+	    MSG_PUTS(", ");
+	MSG_PUTS("...");
+    }
+    msg_putchar(')');
+    msg_clr_eos();
+    if (p_verbose > 0)
+	last_set_msg(fp->uf_script_ID);
+}
+
+/*
+ * Find a function by name, return pointer to it in ufuncs.
+ * Return NULL for unknown function.
+ */
+    static ufunc_T *
+find_func(name)
+    char_u	*name;
+{
+    hashitem_T	*hi;
+
+    hi = hash_find(&func_hashtab, name);
+    if (!HASHITEM_EMPTY(hi))
+	return HI2UF(hi);
+    return NULL;
+}
+
+#if defined(EXITFREE) || defined(PROTO)
+    void
+free_all_functions()
+{
+    hashitem_T	*hi;
+
+    /* Need to start all over every time, because func_free() may change the
+     * hash table. */
+    while (func_hashtab.ht_used > 0)
+	for (hi = func_hashtab.ht_array; ; ++hi)
+	    if (!HASHITEM_EMPTY(hi))
+	    {
+		func_free(HI2UF(hi));
+		break;
+	    }
+}
+#endif
+
+/*
+ * Return TRUE if a function "name" exists.
+ */
+    static int
+function_exists(name)
+    char_u *name;
+{
+    char_u  *nm = name;
+    char_u  *p;
+    int	    n = FALSE;
+
+    p = trans_function_name(&nm, FALSE, TFN_INT|TFN_QUIET, NULL);
+    nm = skipwhite(nm);
+
+    /* Only accept "funcname", "funcname ", "funcname (..." and
+     * "funcname(...", not "funcname!...". */
+    if (p != NULL && (*nm == NUL || *nm == '('))
+    {
+	if (builtin_function(p))
+	    n = (find_internal_func(p) >= 0);
+	else
+	    n = (find_func(p) != NULL);
+    }
+    vim_free(p);
+    return n;
+}
+
+/*
+ * Return TRUE if "name" looks like a builtin function name: starts with a
+ * lower case letter and doesn't contain a ':' or AUTOLOAD_CHAR.
+ */
+    static int
+builtin_function(name)
+    char_u *name;
+{
+    return ASCII_ISLOWER(name[0]) && vim_strchr(name, ':') == NULL
+				   && vim_strchr(name, AUTOLOAD_CHAR) == NULL;
+}
+
+#if defined(FEAT_PROFILE) || defined(PROTO)
+/*
+ * Start profiling function "fp".
+ */
+    static void
+func_do_profile(fp)
+    ufunc_T	*fp;
+{
+    fp->uf_tm_count = 0;
+    profile_zero(&fp->uf_tm_self);
+    profile_zero(&fp->uf_tm_total);
+    if (fp->uf_tml_count == NULL)
+	fp->uf_tml_count = (int *)alloc_clear((unsigned)
+					 (sizeof(int) * fp->uf_lines.ga_len));
+    if (fp->uf_tml_total == NULL)
+	fp->uf_tml_total = (proftime_T *)alloc_clear((unsigned)
+				  (sizeof(proftime_T) * fp->uf_lines.ga_len));
+    if (fp->uf_tml_self == NULL)
+	fp->uf_tml_self = (proftime_T *)alloc_clear((unsigned)
+				  (sizeof(proftime_T) * fp->uf_lines.ga_len));
+    fp->uf_tml_idx = -1;
+    if (fp->uf_tml_count == NULL || fp->uf_tml_total == NULL
+						   || fp->uf_tml_self == NULL)
+	return;	    /* out of memory */
+
+    fp->uf_profiling = TRUE;
+}
+
+/*
+ * Dump the profiling results for all functions in file "fd".
+ */
+    void
+func_dump_profile(fd)
+    FILE    *fd;
+{
+    hashitem_T	*hi;
+    int		todo;
+    ufunc_T	*fp;
+    int		i;
+    ufunc_T	**sorttab;
+    int		st_len = 0;
+
+    todo = (int)func_hashtab.ht_used;
+    sorttab = (ufunc_T **)alloc((unsigned)(sizeof(ufunc_T) * todo));
+
+    for (hi = func_hashtab.ht_array; todo > 0; ++hi)
+    {
+	if (!HASHITEM_EMPTY(hi))
+	{
+	    --todo;
+	    fp = HI2UF(hi);
+	    if (fp->uf_profiling)
+	    {
+		if (sorttab != NULL)
+		    sorttab[st_len++] = fp;
+
+		if (fp->uf_name[0] == K_SPECIAL)
+		    fprintf(fd, "FUNCTION  <SNR>%s()\n", fp->uf_name + 3);
+		else
+		    fprintf(fd, "FUNCTION  %s()\n", fp->uf_name);
+		if (fp->uf_tm_count == 1)
+		    fprintf(fd, "Called 1 time\n");
+		else
+		    fprintf(fd, "Called %d times\n", fp->uf_tm_count);
+		fprintf(fd, "Total time: %s\n", profile_msg(&fp->uf_tm_total));
+		fprintf(fd, " Self time: %s\n", profile_msg(&fp->uf_tm_self));
+		fprintf(fd, "\n");
+		fprintf(fd, "count  total (s)   self (s)\n");
+
+		for (i = 0; i < fp->uf_lines.ga_len; ++i)
+		{
+		    if (FUNCLINE(fp, i) == NULL)
+			continue;
+		    prof_func_line(fd, fp->uf_tml_count[i],
+			     &fp->uf_tml_total[i], &fp->uf_tml_self[i], TRUE);
+		    fprintf(fd, "%s\n", FUNCLINE(fp, i));
+		}
+		fprintf(fd, "\n");
+	    }
+	}
+    }
+
+    if (sorttab != NULL && st_len > 0)
+    {
+	qsort((void *)sorttab, (size_t)st_len, sizeof(ufunc_T *),
+							      prof_total_cmp);
+	prof_sort_list(fd, sorttab, st_len, "TOTAL", FALSE);
+	qsort((void *)sorttab, (size_t)st_len, sizeof(ufunc_T *),
+							      prof_self_cmp);
+	prof_sort_list(fd, sorttab, st_len, "SELF", TRUE);
+    }
+}
+
+    static void
+prof_sort_list(fd, sorttab, st_len, title, prefer_self)
+    FILE	*fd;
+    ufunc_T	**sorttab;
+    int		st_len;
+    char	*title;
+    int		prefer_self;	/* when equal print only self time */
+{
+    int		i;
+    ufunc_T	*fp;
+
+    fprintf(fd, "FUNCTIONS SORTED ON %s TIME\n", title);
+    fprintf(fd, "count  total (s)   self (s)  function\n");
+    for (i = 0; i < 20 && i < st_len; ++i)
+    {
+	fp = sorttab[i];
+	prof_func_line(fd, fp->uf_tm_count, &fp->uf_tm_total, &fp->uf_tm_self,
+								 prefer_self);
+	if (fp->uf_name[0] == K_SPECIAL)
+	    fprintf(fd, " <SNR>%s()\n", fp->uf_name + 3);
+	else
+	    fprintf(fd, " %s()\n", fp->uf_name);
+    }
+    fprintf(fd, "\n");
+}
+
+/*
+ * Print the count and times for one function or function line.
+ */
+    static void
+prof_func_line(fd, count, total, self, prefer_self)
+    FILE	*fd;
+    int		count;
+    proftime_T	*total;
+    proftime_T	*self;
+    int		prefer_self;	/* when equal print only self time */
+{
+    if (count > 0)
+    {
+	fprintf(fd, "%5d ", count);
+	if (prefer_self && profile_equal(total, self))
+	    fprintf(fd, "           ");
+	else
+	    fprintf(fd, "%s ", profile_msg(total));
+	if (!prefer_self && profile_equal(total, self))
+	    fprintf(fd, "           ");
+	else
+	    fprintf(fd, "%s ", profile_msg(self));
+    }
+    else
+	fprintf(fd, "                            ");
+}
+
+/*
+ * Compare function for total time sorting.
+ */
+    static int
+#ifdef __BORLANDC__
+_RTLENTRYF
+#endif
+prof_total_cmp(s1, s2)
+    const void	*s1;
+    const void	*s2;
+{
+    ufunc_T	*p1, *p2;
+
+    p1 = *(ufunc_T **)s1;
+    p2 = *(ufunc_T **)s2;
+    return profile_cmp(&p1->uf_tm_total, &p2->uf_tm_total);
+}
+
+/*
+ * Compare function for self time sorting.
+ */
+    static int
+#ifdef __BORLANDC__
+_RTLENTRYF
+#endif
+prof_self_cmp(s1, s2)
+    const void	*s1;
+    const void	*s2;
+{
+    ufunc_T	*p1, *p2;
+
+    p1 = *(ufunc_T **)s1;
+    p2 = *(ufunc_T **)s2;
+    return profile_cmp(&p1->uf_tm_self, &p2->uf_tm_self);
+}
+
+#endif
+
+/*
+ * If "name" has a package name try autoloading the script for it.
+ * Return TRUE if a package was loaded.
+ */
+    static int
+script_autoload(name, reload)
+    char_u	*name;
+    int		reload;	    /* load script again when already loaded */
+{
+    char_u	*p;
+    char_u	*scriptname, *tofree;
+    int		ret = FALSE;
+    int		i;
+
+    /* If there is no '#' after name[0] there is no package name. */
+    p = vim_strchr(name, AUTOLOAD_CHAR);
+    if (p == NULL || p == name)
+	return FALSE;
+
+    tofree = scriptname = autoload_name(name);
+
+    /* Find the name in the list of previously loaded package names.  Skip
+     * "autoload/", it's always the same. */
+    for (i = 0; i < ga_loaded.ga_len; ++i)
+	if (STRCMP(((char_u **)ga_loaded.ga_data)[i] + 9, scriptname + 9) == 0)
+	    break;
+    if (!reload && i < ga_loaded.ga_len)
+	ret = FALSE;	    /* was loaded already */
+    else
+    {
+	/* Remember the name if it wasn't loaded already. */
+	if (i == ga_loaded.ga_len && ga_grow(&ga_loaded, 1) == OK)
+	{
+	    ((char_u **)ga_loaded.ga_data)[ga_loaded.ga_len++] = scriptname;
+	    tofree = NULL;
+	}
+
+	/* Try loading the package from $VIMRUNTIME/autoload/<name>.vim */
+	if (source_runtime(scriptname, FALSE) == OK)
+	    ret = TRUE;
+    }
+
+    vim_free(tofree);
+    return ret;
+}
+
+/*
+ * Return the autoload script name for a function or variable name.
+ * Returns NULL when out of memory.
+ */
+    static char_u *
+autoload_name(name)
+    char_u	*name;
+{
+    char_u	*p;
+    char_u	*scriptname;
+
+    /* Get the script file name: replace '#' with '/', append ".vim". */
+    scriptname = alloc((unsigned)(STRLEN(name) + 14));
+    if (scriptname == NULL)
+	return FALSE;
+    STRCPY(scriptname, "autoload/");
+    STRCAT(scriptname, name);
+    *vim_strrchr(scriptname, AUTOLOAD_CHAR) = NUL;
+    STRCAT(scriptname, ".vim");
+    while ((p = vim_strchr(scriptname, AUTOLOAD_CHAR)) != NULL)
+	*p = '/';
+    return scriptname;
+}
+
+#if defined(FEAT_CMDL_COMPL) || defined(PROTO)
+
+/*
+ * Function given to ExpandGeneric() to obtain the list of user defined
+ * function names.
+ */
+    char_u *
+get_user_func_name(xp, idx)
+    expand_T	*xp;
+    int		idx;
+{
+    static long_u	done;
+    static hashitem_T	*hi;
+    ufunc_T		*fp;
+
+    if (idx == 0)
+    {
+	done = 0;
+	hi = func_hashtab.ht_array;
+    }
+    if (done < func_hashtab.ht_used)
+    {
+	if (done++ > 0)
+	    ++hi;
+	while (HASHITEM_EMPTY(hi))
+	    ++hi;
+	fp = HI2UF(hi);
+
+	if (STRLEN(fp->uf_name) + 4 >= IOSIZE)
+	    return fp->uf_name;	/* prevents overflow */
+
+	cat_func_name(IObuff, fp);
+	if (xp->xp_context != EXPAND_USER_FUNC)
+	{
+	    STRCAT(IObuff, "(");
+	    if (!fp->uf_varargs && fp->uf_args.ga_len == 0)
+		STRCAT(IObuff, ")");
+	}
+	return IObuff;
+    }
+    return NULL;
+}
+
+#endif /* FEAT_CMDL_COMPL */
+
+/*
+ * Copy the function name of "fp" to buffer "buf".
+ * "buf" must be able to hold the function name plus three bytes.
+ * Takes care of script-local function names.
+ */
+    static void
+cat_func_name(buf, fp)
+    char_u	*buf;
+    ufunc_T	*fp;
+{
+    if (fp->uf_name[0] == K_SPECIAL)
+    {
+	STRCPY(buf, "<SNR>");
+	STRCAT(buf, fp->uf_name + 3);
+    }
+    else
+	STRCPY(buf, fp->uf_name);
+}
+
+/*
+ * ":delfunction {name}"
+ */
+    void
+ex_delfunction(eap)
+    exarg_T	*eap;
+{
+    ufunc_T	*fp = NULL;
+    char_u	*p;
+    char_u	*name;
+    funcdict_T	fudi;
+
+    p = eap->arg;
+    name = trans_function_name(&p, eap->skip, 0, &fudi);
+    vim_free(fudi.fd_newkey);
+    if (name == NULL)
+    {
+	if (fudi.fd_dict != NULL && !eap->skip)
+	    EMSG(_(e_funcref));
+	return;
+    }
+    if (!ends_excmd(*skipwhite(p)))
+    {
+	vim_free(name);
+	EMSG(_(e_trailing));
+	return;
+    }
+    eap->nextcmd = check_nextcmd(p);
+    if (eap->nextcmd != NULL)
+	*p = NUL;
+
+    if (!eap->skip)
+	fp = find_func(name);
+    vim_free(name);
+
+    if (!eap->skip)
+    {
+	if (fp == NULL)
+	{
+	    EMSG2(_(e_nofunc), eap->arg);
+	    return;
+	}
+	if (fp->uf_calls > 0)
+	{
+	    EMSG2(_("E131: Cannot delete function %s: It is in use"), eap->arg);
+	    return;
+	}
+
+	if (fudi.fd_dict != NULL)
+	{
+	    /* Delete the dict item that refers to the function, it will
+	     * invoke func_unref() and possibly delete the function. */
+	    dictitem_remove(fudi.fd_dict, fudi.fd_di);
+	}
+	else
+	    func_free(fp);
+    }
+}
+
+/*
+ * Free a function and remove it from the list of functions.
+ */
+    static void
+func_free(fp)
+    ufunc_T *fp;
+{
+    hashitem_T	*hi;
+
+    /* clear this function */
+    ga_clear_strings(&(fp->uf_args));
+    ga_clear_strings(&(fp->uf_lines));
+#ifdef FEAT_PROFILE
+    vim_free(fp->uf_tml_count);
+    vim_free(fp->uf_tml_total);
+    vim_free(fp->uf_tml_self);
+#endif
+
+    /* remove the function from the function hashtable */
+    hi = hash_find(&func_hashtab, UF2HIKEY(fp));
+    if (HASHITEM_EMPTY(hi))
+	EMSG2(_(e_intern2), "func_free()");
+    else
+	hash_remove(&func_hashtab, hi);
+
+    vim_free(fp);
+}
+
+/*
+ * Unreference a Function: decrement the reference count and free it when it
+ * becomes zero.  Only for numbered functions.
+ */
+    static void
+func_unref(name)
+    char_u	*name;
+{
+    ufunc_T *fp;
+
+    if (name != NULL && isdigit(*name))
+    {
+	fp = find_func(name);
+	if (fp == NULL)
+	    EMSG2(_(e_intern2), "func_unref()");
+	else if (--fp->uf_refcount <= 0)
+	{
+	    /* Only delete it when it's not being used.  Otherwise it's done
+	     * when "uf_calls" becomes zero. */
+	    if (fp->uf_calls == 0)
+		func_free(fp);
+	}
+    }
+}
+
+/*
+ * Count a reference to a Function.
+ */
+    static void
+func_ref(name)
+    char_u	*name;
+{
+    ufunc_T *fp;
+
+    if (name != NULL && isdigit(*name))
+    {
+	fp = find_func(name);
+	if (fp == NULL)
+	    EMSG2(_(e_intern2), "func_ref()");
+	else
+	    ++fp->uf_refcount;
+    }
+}
+
+/*
+ * Call a user function.
+ */
+    static void
+call_user_func(fp, argcount, argvars, rettv, firstline, lastline, selfdict)
+    ufunc_T	*fp;		/* pointer to function */
+    int		argcount;	/* nr of args */
+    typval_T	*argvars;	/* arguments */
+    typval_T	*rettv;		/* return value */
+    linenr_T	firstline;	/* first line of range */
+    linenr_T	lastline;	/* last line of range */
+    dict_T	*selfdict;	/* Dictionary for "self" */
+{
+    char_u	*save_sourcing_name;
+    linenr_T	save_sourcing_lnum;
+    scid_T	save_current_SID;
+    funccall_T	fc;
+    int		save_did_emsg;
+    static int	depth = 0;
+    dictitem_T	*v;
+    int		fixvar_idx = 0;	/* index in fixvar[] */
+    int		i;
+    int		ai;
+    char_u	numbuf[NUMBUFLEN];
+    char_u	*name;
+#ifdef FEAT_PROFILE
+    proftime_T	wait_start;
+    proftime_T	call_start;
+#endif
+
+    /* If depth of calling is getting too high, don't execute the function */
+    if (depth >= p_mfd)
+    {
+	EMSG(_("E132: Function call depth is higher than 'maxfuncdepth'"));
+	rettv->v_type = VAR_NUMBER;
+	rettv->vval.v_number = -1;
+	return;
+    }
+    ++depth;
+
+    line_breakcheck();		/* check for CTRL-C hit */
+
+    fc.caller = current_funccal;
+    current_funccal = &fc;
+    fc.func = fp;
+    fc.rettv = rettv;
+    rettv->vval.v_number = 0;
+    fc.linenr = 0;
+    fc.returned = FALSE;
+    fc.level = ex_nesting_level;
+    /* Check if this function has a breakpoint. */
+    fc.breakpoint = dbg_find_breakpoint(FALSE, fp->uf_name, (linenr_T)0);
+    fc.dbg_tick = debug_tick;
+
+    /*
+     * Note about using fc.fixvar[]: This is an array of FIXVAR_CNT variables
+     * with names up to VAR_SHORT_LEN long.  This avoids having to alloc/free
+     * each argument variable and saves a lot of time.
+     */
+    /*
+     * Init l: variables.
+     */
+    init_var_dict(&fc.l_vars, &fc.l_vars_var);
+    if (selfdict != NULL)
+    {
+	/* Set l:self to "selfdict".  Use "name" to avoid a warning from
+	 * some compiler that checks the destination size. */
+	v = &fc.fixvar[fixvar_idx++].var;
+	name = v->di_key;
+	STRCPY(name, "self");
+	v->di_flags = DI_FLAGS_RO + DI_FLAGS_FIX;
+	hash_add(&fc.l_vars.dv_hashtab, DI2HIKEY(v));
+	v->di_tv.v_type = VAR_DICT;
+	v->di_tv.v_lock = 0;
+	v->di_tv.vval.v_dict = selfdict;
+	++selfdict->dv_refcount;
+    }
+
+    /*
+     * Init a: variables.
+     * Set a:0 to "argcount".
+     * Set a:000 to a list with room for the "..." arguments.
+     */
+    init_var_dict(&fc.l_avars, &fc.l_avars_var);
+    add_nr_var(&fc.l_avars, &fc.fixvar[fixvar_idx++].var, "0",
+				(varnumber_T)(argcount - fp->uf_args.ga_len));
+    v = &fc.fixvar[fixvar_idx++].var;
+    STRCPY(v->di_key, "000");
+    v->di_flags = DI_FLAGS_RO | DI_FLAGS_FIX;
+    hash_add(&fc.l_avars.dv_hashtab, DI2HIKEY(v));
+    v->di_tv.v_type = VAR_LIST;
+    v->di_tv.v_lock = VAR_FIXED;
+    v->di_tv.vval.v_list = &fc.l_varlist;
+    vim_memset(&fc.l_varlist, 0, sizeof(list_T));
+    fc.l_varlist.lv_refcount = 99999;
+    fc.l_varlist.lv_lock = VAR_FIXED;
+
+    /*
+     * Set a:firstline to "firstline" and a:lastline to "lastline".
+     * Set a:name to named arguments.
+     * Set a:N to the "..." arguments.
+     */
+    add_nr_var(&fc.l_avars, &fc.fixvar[fixvar_idx++].var, "firstline",
+						      (varnumber_T)firstline);
+    add_nr_var(&fc.l_avars, &fc.fixvar[fixvar_idx++].var, "lastline",
+						       (varnumber_T)lastline);
+    for (i = 0; i < argcount; ++i)
+    {
+	ai = i - fp->uf_args.ga_len;
+	if (ai < 0)
+	    /* named argument a:name */
+	    name = FUNCARG(fp, i);
+	else
+	{
+	    /* "..." argument a:1, a:2, etc. */
+	    sprintf((char *)numbuf, "%d", ai + 1);
+	    name = numbuf;
+	}
+	if (fixvar_idx < FIXVAR_CNT && STRLEN(name) <= VAR_SHORT_LEN)
+	{
+	    v = &fc.fixvar[fixvar_idx++].var;
+	    v->di_flags = DI_FLAGS_RO | DI_FLAGS_FIX;
+	}
+	else
+	{
+	    v = (dictitem_T *)alloc((unsigned)(sizeof(dictitem_T)
+							     + STRLEN(name)));
+	    if (v == NULL)
+		break;
+	    v->di_flags = DI_FLAGS_RO;
+	}
+	STRCPY(v->di_key, name);
+	hash_add(&fc.l_avars.dv_hashtab, DI2HIKEY(v));
+
+	/* Note: the values are copied directly to avoid alloc/free.
+	 * "argvars" must have VAR_FIXED for v_lock. */
+	v->di_tv = argvars[i];
+	v->di_tv.v_lock = VAR_FIXED;
+
+	if (ai >= 0 && ai < MAX_FUNC_ARGS)
+	{
+	    list_append(&fc.l_varlist, &fc.l_listitems[ai]);
+	    fc.l_listitems[ai].li_tv = argvars[i];
+	    fc.l_listitems[ai].li_tv.v_lock = VAR_FIXED;
+	}
+    }
+
+    /* Don't redraw while executing the function. */
+    ++RedrawingDisabled;
+    save_sourcing_name = sourcing_name;
+    save_sourcing_lnum = sourcing_lnum;
+    sourcing_lnum = 1;
+    sourcing_name = alloc((unsigned)((save_sourcing_name == NULL ? 0
+		: STRLEN(save_sourcing_name)) + STRLEN(fp->uf_name) + 13));
+    if (sourcing_name != NULL)
+    {
+	if (save_sourcing_name != NULL
+			  && STRNCMP(save_sourcing_name, "function ", 9) == 0)
+	    sprintf((char *)sourcing_name, "%s..", save_sourcing_name);
+	else
+	    STRCPY(sourcing_name, "function ");
+	cat_func_name(sourcing_name + STRLEN(sourcing_name), fp);
+
+	if (p_verbose >= 12)
+	{
+	    ++no_wait_return;
+	    verbose_enter_scroll();
+
+	    smsg((char_u *)_("calling %s"), sourcing_name);
+	    if (p_verbose >= 14)
+	    {
+		char_u	buf[MSG_BUF_LEN];
+		char_u	numbuf2[NUMBUFLEN];
+		char_u	*tofree;
+
+		msg_puts((char_u *)"(");
+		for (i = 0; i < argcount; ++i)
+		{
+		    if (i > 0)
+			msg_puts((char_u *)", ");
+		    if (argvars[i].v_type == VAR_NUMBER)
+			msg_outnum((long)argvars[i].vval.v_number);
+		    else
+		    {
+			trunc_string(tv2string(&argvars[i], &tofree,
+					      numbuf2, 0), buf, MSG_BUF_CLEN);
+			msg_puts(buf);
+			vim_free(tofree);
+		    }
+		}
+		msg_puts((char_u *)")");
+	    }
+	    msg_puts((char_u *)"\n");   /* don't overwrite this either */
+
+	    verbose_leave_scroll();
+	    --no_wait_return;
+	}
+    }
+#ifdef FEAT_PROFILE
+    if (do_profiling == PROF_YES)
+    {
+	if (!fp->uf_profiling && has_profiling(FALSE, fp->uf_name, NULL))
+	    func_do_profile(fp);
+	if (fp->uf_profiling
+		       || (fc.caller != NULL && &fc.caller->func->uf_profiling))
+	{
+	    ++fp->uf_tm_count;
+	    profile_start(&call_start);
+	    profile_zero(&fp->uf_tm_children);
+	}
+	script_prof_save(&wait_start);
+    }
+#endif
+
+    save_current_SID = current_SID;
+    current_SID = fp->uf_script_ID;
+    save_did_emsg = did_emsg;
+    did_emsg = FALSE;
+
+    /* call do_cmdline() to execute the lines */
+    do_cmdline(NULL, get_func_line, (void *)&fc,
+				     DOCMD_NOWAIT|DOCMD_VERBOSE|DOCMD_REPEAT);
+
+    --RedrawingDisabled;
+
+    /* when the function was aborted because of an error, return -1 */
+    if ((did_emsg && (fp->uf_flags & FC_ABORT)) || rettv->v_type == VAR_UNKNOWN)
+    {
+	clear_tv(rettv);
+	rettv->v_type = VAR_NUMBER;
+	rettv->vval.v_number = -1;
+    }
+
+#ifdef FEAT_PROFILE
+    if (do_profiling == PROF_YES && (fp->uf_profiling
+		    || (fc.caller != NULL && &fc.caller->func->uf_profiling)))
+    {
+	profile_end(&call_start);
+	profile_sub_wait(&wait_start, &call_start);
+	profile_add(&fp->uf_tm_total, &call_start);
+	profile_self(&fp->uf_tm_self, &call_start, &fp->uf_tm_children);
+	if (fc.caller != NULL && &fc.caller->func->uf_profiling)
+	{
+	    profile_add(&fc.caller->func->uf_tm_children, &call_start);
+	    profile_add(&fc.caller->func->uf_tml_children, &call_start);
+	}
+    }
+#endif
+
+    /* when being verbose, mention the return value */
+    if (p_verbose >= 12)
+    {
+	++no_wait_return;
+	verbose_enter_scroll();
+
+	if (aborting())
+	    smsg((char_u *)_("%s aborted"), sourcing_name);
+	else if (fc.rettv->v_type == VAR_NUMBER)
+	    smsg((char_u *)_("%s returning #%ld"), sourcing_name,
+					       (long)fc.rettv->vval.v_number);
+	else
+	{
+	    char_u	buf[MSG_BUF_LEN];
+	    char_u	numbuf2[NUMBUFLEN];
+	    char_u	*tofree;
+
+	    /* The value may be very long.  Skip the middle part, so that we
+	     * have some idea how it starts and ends. smsg() would always
+	     * truncate it at the end. */
+	    trunc_string(tv2string(fc.rettv, &tofree, numbuf2, 0),
+							   buf, MSG_BUF_CLEN);
+	    smsg((char_u *)_("%s returning %s"), sourcing_name, buf);
+	    vim_free(tofree);
+	}
+	msg_puts((char_u *)"\n");   /* don't overwrite this either */
+
+	verbose_leave_scroll();
+	--no_wait_return;
+    }
+
+    vim_free(sourcing_name);
+    sourcing_name = save_sourcing_name;
+    sourcing_lnum = save_sourcing_lnum;
+    current_SID = save_current_SID;
+#ifdef FEAT_PROFILE
+    if (do_profiling == PROF_YES)
+	script_prof_restore(&wait_start);
+#endif
+
+    if (p_verbose >= 12 && sourcing_name != NULL)
+    {
+	++no_wait_return;
+	verbose_enter_scroll();
+
+	smsg((char_u *)_("continuing in %s"), sourcing_name);
+	msg_puts((char_u *)"\n");   /* don't overwrite this either */
+
+	verbose_leave_scroll();
+	--no_wait_return;
+    }
+
+    did_emsg |= save_did_emsg;
+    current_funccal = fc.caller;
+
+    /* The a: variables typevals were not alloced, only free the allocated
+     * variables. */
+    vars_clear_ext(&fc.l_avars.dv_hashtab, FALSE);
+
+    vars_clear(&fc.l_vars.dv_hashtab);		/* free all l: variables */
+    --depth;
+}
+
+/*
+ * Add a number variable "name" to dict "dp" with value "nr".
+ */
+    static void
+add_nr_var(dp, v, name, nr)
+    dict_T	*dp;
+    dictitem_T	*v;
+    char	*name;
+    varnumber_T nr;
+{
+    STRCPY(v->di_key, name);
+    v->di_flags = DI_FLAGS_RO | DI_FLAGS_FIX;
+    hash_add(&dp->dv_hashtab, DI2HIKEY(v));
+    v->di_tv.v_type = VAR_NUMBER;
+    v->di_tv.v_lock = VAR_FIXED;
+    v->di_tv.vval.v_number = nr;
+}
+
+/*
+ * ":return [expr]"
+ */
+    void
+ex_return(eap)
+    exarg_T	*eap;
+{
+    char_u	*arg = eap->arg;
+    typval_T	rettv;
+    int		returning = FALSE;
+
+    if (current_funccal == NULL)
+    {
+	EMSG(_("E133: :return not inside a function"));
+	return;
+    }
+
+    if (eap->skip)
+	++emsg_skip;
+
+    eap->nextcmd = NULL;
+    if ((*arg != NUL && *arg != '|' && *arg != '\n')
+	    && eval0(arg, &rettv, &eap->nextcmd, !eap->skip) != FAIL)
+    {
+	if (!eap->skip)
+	    returning = do_return(eap, FALSE, TRUE, &rettv);
+	else
+	    clear_tv(&rettv);
+    }
+    /* It's safer to return also on error. */
+    else if (!eap->skip)
+    {
+	/*
+	 * Return unless the expression evaluation has been cancelled due to an
+	 * aborting error, an interrupt, or an exception.
+	 */
+	if (!aborting())
+	    returning = do_return(eap, FALSE, TRUE, NULL);
+    }
+
+    /* When skipping or the return gets pending, advance to the next command
+     * in this line (!returning).  Otherwise, ignore the rest of the line.
+     * Following lines will be ignored by get_func_line(). */
+    if (returning)
+	eap->nextcmd = NULL;
+    else if (eap->nextcmd == NULL)	    /* no argument */
+	eap->nextcmd = check_nextcmd(arg);
+
+    if (eap->skip)
+	--emsg_skip;
+}
+
+/*
+ * Return from a function.  Possibly makes the return pending.  Also called
+ * for a pending return at the ":endtry" or after returning from an extra
+ * do_cmdline().  "reanimate" is used in the latter case.  "is_cmd" is set
+ * when called due to a ":return" command.  "rettv" may point to a typval_T
+ * with the return rettv.  Returns TRUE when the return can be carried out,
+ * FALSE when the return gets pending.
+ */
+    int
+do_return(eap, reanimate, is_cmd, rettv)
+    exarg_T	*eap;
+    int		reanimate;
+    int		is_cmd;
+    void	*rettv;
+{
+    int		idx;
+    struct condstack *cstack = eap->cstack;
+
+    if (reanimate)
+	/* Undo the return. */
+	current_funccal->returned = FALSE;
+
+    /*
+     * Cleanup (and inactivate) conditionals, but stop when a try conditional
+     * not in its finally clause (which then is to be executed next) is found.
+     * In this case, make the ":return" pending for execution at the ":endtry".
+     * Otherwise, return normally.
+     */
+    idx = cleanup_conditionals(eap->cstack, 0, TRUE);
+    if (idx >= 0)
+    {
+	cstack->cs_pending[idx] = CSTP_RETURN;
+
+	if (!is_cmd && !reanimate)
+	    /* A pending return again gets pending.  "rettv" points to an
+	     * allocated variable with the rettv of the original ":return"'s
+	     * argument if present or is NULL else. */
+	    cstack->cs_rettv[idx] = rettv;
+	else
+	{
+	    /* When undoing a return in order to make it pending, get the stored
+	     * return rettv. */
+	    if (reanimate)
+		rettv = current_funccal->rettv;
+
+	    if (rettv != NULL)
+	    {
+		/* Store the value of the pending return. */
+		if ((cstack->cs_rettv[idx] = alloc_tv()) != NULL)
+		    *(typval_T *)cstack->cs_rettv[idx] = *(typval_T *)rettv;
+		else
+		    EMSG(_(e_outofmem));
+	    }
+	    else
+		cstack->cs_rettv[idx] = NULL;
+
+	    if (reanimate)
+	    {
+		/* The pending return value could be overwritten by a ":return"
+		 * without argument in a finally clause; reset the default
+		 * return value. */
+		current_funccal->rettv->v_type = VAR_NUMBER;
+		current_funccal->rettv->vval.v_number = 0;
+	    }
+	}
+	report_make_pending(CSTP_RETURN, rettv);
+    }
+    else
+    {
+	current_funccal->returned = TRUE;
+
+	/* If the return is carried out now, store the return value.  For
+	 * a return immediately after reanimation, the value is already
+	 * there. */
+	if (!reanimate && rettv != NULL)
+	{
+	    clear_tv(current_funccal->rettv);
+	    *current_funccal->rettv = *(typval_T *)rettv;
+	    if (!is_cmd)
+		vim_free(rettv);
+	}
+    }
+
+    return idx < 0;
+}
+
+/*
+ * Free the variable with a pending return value.
+ */
+    void
+discard_pending_return(rettv)
+    void	*rettv;
+{
+    free_tv((typval_T *)rettv);
+}
+
+/*
+ * Generate a return command for producing the value of "rettv".  The result
+ * is an allocated string.  Used by report_pending() for verbose messages.
+ */
+    char_u *
+get_return_cmd(rettv)
+    void	*rettv;
+{
+    char_u	*s = NULL;
+    char_u	*tofree = NULL;
+    char_u	numbuf[NUMBUFLEN];
+
+    if (rettv != NULL)
+	s = echo_string((typval_T *)rettv, &tofree, numbuf, 0);
+    if (s == NULL)
+	s = (char_u *)"";
+
+    STRCPY(IObuff, ":return ");
+    STRNCPY(IObuff + 8, s, IOSIZE - 8);
+    if (STRLEN(s) + 8 >= IOSIZE)
+	STRCPY(IObuff + IOSIZE - 4, "...");
+    vim_free(tofree);
+    return vim_strsave(IObuff);
+}
+
+/*
+ * Get next function line.
+ * Called by do_cmdline() to get the next line.
+ * Returns allocated string, or NULL for end of function.
+ */
+/* ARGSUSED */
+    char_u *
+get_func_line(c, cookie, indent)
+    int	    c;		    /* not used */
+    void    *cookie;
+    int	    indent;	    /* not used */
+{
+    funccall_T	*fcp = (funccall_T *)cookie;
+    ufunc_T	*fp = fcp->func;
+    char_u	*retval;
+    garray_T	*gap;  /* growarray with function lines */
+
+    /* If breakpoints have been added/deleted need to check for it. */
+    if (fcp->dbg_tick != debug_tick)
+    {
+	fcp->breakpoint = dbg_find_breakpoint(FALSE, fp->uf_name,
+							       sourcing_lnum);
+	fcp->dbg_tick = debug_tick;
+    }
+#ifdef FEAT_PROFILE
+    if (do_profiling == PROF_YES)
+	func_line_end(cookie);
+#endif
+
+    gap = &fp->uf_lines;
+    if (((fp->uf_flags & FC_ABORT) && did_emsg && !aborted_in_try())
+	    || fcp->returned)
+	retval = NULL;
+    else
+    {
+	/* Skip NULL lines (continuation lines). */
+	while (fcp->linenr < gap->ga_len
+			  && ((char_u **)(gap->ga_data))[fcp->linenr] == NULL)
+	    ++fcp->linenr;
+	if (fcp->linenr >= gap->ga_len)
+	    retval = NULL;
+	else
+	{
+	    retval = vim_strsave(((char_u **)(gap->ga_data))[fcp->linenr++]);
+	    sourcing_lnum = fcp->linenr;
+#ifdef FEAT_PROFILE
+	    if (do_profiling == PROF_YES)
+		func_line_start(cookie);
+#endif
+	}
+    }
+
+    /* Did we encounter a breakpoint? */
+    if (fcp->breakpoint != 0 && fcp->breakpoint <= sourcing_lnum)
+    {
+	dbg_breakpoint(fp->uf_name, sourcing_lnum);
+	/* Find next breakpoint. */
+	fcp->breakpoint = dbg_find_breakpoint(FALSE, fp->uf_name,
+							       sourcing_lnum);
+	fcp->dbg_tick = debug_tick;
+    }
+
+    return retval;
+}
+
+#if defined(FEAT_PROFILE) || defined(PROTO)
+/*
+ * Called when starting to read a function line.
+ * "sourcing_lnum" must be correct!
+ * When skipping lines it may not actually be executed, but we won't find out
+ * until later and we need to store the time now.
+ */
+    void
+func_line_start(cookie)
+    void    *cookie;
+{
+    funccall_T	*fcp = (funccall_T *)cookie;
+    ufunc_T	*fp = fcp->func;
+
+    if (fp->uf_profiling && sourcing_lnum >= 1
+				      && sourcing_lnum <= fp->uf_lines.ga_len)
+    {
+	fp->uf_tml_idx = sourcing_lnum - 1;
+	/* Skip continuation lines. */
+	while (fp->uf_tml_idx > 0 && FUNCLINE(fp, fp->uf_tml_idx) == NULL)
+	    --fp->uf_tml_idx;
+	fp->uf_tml_execed = FALSE;
+	profile_start(&fp->uf_tml_start);
+	profile_zero(&fp->uf_tml_children);
+	profile_get_wait(&fp->uf_tml_wait);
+    }
+}
+
+/*
+ * Called when actually executing a function line.
+ */
+    void
+func_line_exec(cookie)
+    void    *cookie;
+{
+    funccall_T	*fcp = (funccall_T *)cookie;
+    ufunc_T	*fp = fcp->func;
+
+    if (fp->uf_profiling && fp->uf_tml_idx >= 0)
+	fp->uf_tml_execed = TRUE;
+}
+
+/*
+ * Called when done with a function line.
+ */
+    void
+func_line_end(cookie)
+    void    *cookie;
+{
+    funccall_T	*fcp = (funccall_T *)cookie;
+    ufunc_T	*fp = fcp->func;
+
+    if (fp->uf_profiling && fp->uf_tml_idx >= 0)
+    {
+	if (fp->uf_tml_execed)
+	{
+	    ++fp->uf_tml_count[fp->uf_tml_idx];
+	    profile_end(&fp->uf_tml_start);
+	    profile_sub_wait(&fp->uf_tml_wait, &fp->uf_tml_start);
+	    profile_add(&fp->uf_tml_total[fp->uf_tml_idx], &fp->uf_tml_start);
+	    profile_self(&fp->uf_tml_self[fp->uf_tml_idx], &fp->uf_tml_start,
+							&fp->uf_tml_children);
+	}
+	fp->uf_tml_idx = -1;
+    }
+}
+#endif
+
+/*
+ * Return TRUE if the currently active function should be ended, because a
+ * return was encountered or an error occured.  Used inside a ":while".
+ */
+    int
+func_has_ended(cookie)
+    void    *cookie;
+{
+    funccall_T  *fcp = (funccall_T *)cookie;
+
+    /* Ignore the "abort" flag if the abortion behavior has been changed due to
+     * an error inside a try conditional. */
+    return (((fcp->func->uf_flags & FC_ABORT) && did_emsg && !aborted_in_try())
+	    || fcp->returned);
+}
+
+/*
+ * return TRUE if cookie indicates a function which "abort"s on errors.
+ */
+    int
+func_has_abort(cookie)
+    void    *cookie;
+{
+    return ((funccall_T *)cookie)->func->uf_flags & FC_ABORT;
+}
+
+#if defined(FEAT_VIMINFO) || defined(FEAT_SESSION)
+typedef enum
+{
+    VAR_FLAVOUR_DEFAULT,
+    VAR_FLAVOUR_SESSION,
+    VAR_FLAVOUR_VIMINFO
+} var_flavour_T;
+
+static var_flavour_T var_flavour __ARGS((char_u *varname));
+
+    static var_flavour_T
+var_flavour(varname)
+    char_u *varname;
+{
+    char_u *p = varname;
+
+    if (ASCII_ISUPPER(*p))
+    {
+	while (*(++p))
+	    if (ASCII_ISLOWER(*p))
+		return VAR_FLAVOUR_SESSION;
+	return VAR_FLAVOUR_VIMINFO;
+    }
+    else
+	return VAR_FLAVOUR_DEFAULT;
+}
+#endif
+
+#if defined(FEAT_VIMINFO) || defined(PROTO)
+/*
+ * Restore global vars that start with a capital from the viminfo file
+ */
+    int
+read_viminfo_varlist(virp, writing)
+    vir_T	*virp;
+    int		writing;
+{
+    char_u	*tab;
+    int		is_string = FALSE;
+    typval_T	tv;
+
+    if (!writing && (find_viminfo_parameter('!') != NULL))
+    {
+	tab = vim_strchr(virp->vir_line + 1, '\t');
+	if (tab != NULL)
+	{
+	    *tab++ = '\0';	/* isolate the variable name */
+	    if (*tab == 'S')	/* string var */
+		is_string = TRUE;
+
+	    tab = vim_strchr(tab, '\t');
+	    if (tab != NULL)
+	    {
+		if (is_string)
+		{
+		    tv.v_type = VAR_STRING;
+		    tv.vval.v_string = viminfo_readstring(virp,
+				       (int)(tab - virp->vir_line + 1), TRUE);
+		}
+		else
+		{
+		    tv.v_type = VAR_NUMBER;
+		    tv.vval.v_number = atol((char *)tab + 1);
+		}
+		set_var(virp->vir_line + 1, &tv, FALSE);
+		if (is_string)
+		    vim_free(tv.vval.v_string);
+	    }
+	}
+    }
+
+    return viminfo_readline(virp);
+}
+
+/*
+ * Write global vars that start with a capital to the viminfo file
+ */
+    void
+write_viminfo_varlist(fp)
+    FILE    *fp;
+{
+    hashitem_T	*hi;
+    dictitem_T	*this_var;
+    int		todo;
+    char	*s;
+    char_u	*p;
+    char_u	*tofree;
+    char_u	numbuf[NUMBUFLEN];
+
+    if (find_viminfo_parameter('!') == NULL)
+	return;
+
+    fprintf(fp, _("\n# global variables:\n"));
+
+    todo = (int)globvarht.ht_used;
+    for (hi = globvarht.ht_array; todo > 0; ++hi)
+    {
+	if (!HASHITEM_EMPTY(hi))
+	{
+	    --todo;
+	    this_var = HI2DI(hi);
+	    if (var_flavour(this_var->di_key) == VAR_FLAVOUR_VIMINFO)
+	    {
+		switch (this_var->di_tv.v_type)
+		{
+		    case VAR_STRING: s = "STR"; break;
+		    case VAR_NUMBER: s = "NUM"; break;
+		    default: continue;
+		}
+		fprintf(fp, "!%s\t%s\t", this_var->di_key, s);
+		p = echo_string(&this_var->di_tv, &tofree, numbuf, 0);
+		if (p != NULL)
+		    viminfo_writestring(fp, p);
+		vim_free(tofree);
+	    }
+	}
+    }
+}
+#endif
+
+#if defined(FEAT_SESSION) || defined(PROTO)
+    int
+store_session_globals(fd)
+    FILE	*fd;
+{
+    hashitem_T	*hi;
+    dictitem_T	*this_var;
+    int		todo;
+    char_u	*p, *t;
+
+    todo = (int)globvarht.ht_used;
+    for (hi = globvarht.ht_array; todo > 0; ++hi)
+    {
+	if (!HASHITEM_EMPTY(hi))
+	{
+	    --todo;
+	    this_var = HI2DI(hi);
+	    if ((this_var->di_tv.v_type == VAR_NUMBER
+			|| this_var->di_tv.v_type == VAR_STRING)
+		    && var_flavour(this_var->di_key) == VAR_FLAVOUR_SESSION)
+	    {
+		/* Escape special characters with a backslash.  Turn a LF and
+		 * CR into \n and \r. */
+		p = vim_strsave_escaped(get_tv_string(&this_var->di_tv),
+							(char_u *)"\\\"\n\r");
+		if (p == NULL)	    /* out of memory */
+		    break;
+		for (t = p; *t != NUL; ++t)
+		    if (*t == '\n')
+			*t = 'n';
+		    else if (*t == '\r')
+			*t = 'r';
+		if ((fprintf(fd, "let %s = %c%s%c",
+				this_var->di_key,
+				(this_var->di_tv.v_type == VAR_STRING) ? '"'
+									: ' ',
+				p,
+				(this_var->di_tv.v_type == VAR_STRING) ? '"'
+								   : ' ') < 0)
+			|| put_eol(fd) == FAIL)
+		{
+		    vim_free(p);
+		    return FAIL;
+		}
+		vim_free(p);
+	    }
+	}
+    }
+    return OK;
+}
+#endif
+
+/*
+ * Display script name where an item was last set.
+ * Should only be invoked when 'verbose' is non-zero.
+ */
+    void
+last_set_msg(scriptID)
+    scid_T scriptID;
+{
+    char_u *p;
+
+    if (scriptID != 0)
+    {
+	p = home_replace_save(NULL, get_scriptname(scriptID));
+	if (p != NULL)
+	{
+	    verbose_enter();
+	    MSG_PUTS(_("\n\tLast set from "));
+	    MSG_PUTS(p);
+	    vim_free(p);
+	    verbose_leave();
+	}
+    }
+}
+
+#endif /* FEAT_EVAL */
+
+#if defined(FEAT_MODIFY_FNAME) || defined(FEAT_EVAL) || defined(PROTO)
+
+
+#ifdef WIN3264
+/*
+ * Functions for ":8" filename modifier: get 8.3 version of a filename.
+ */
+static int get_short_pathname __ARGS((char_u **fnamep, char_u **bufp, int *fnamelen));
+static int shortpath_for_invalid_fname __ARGS((char_u **fname, char_u **bufp, int *fnamelen));
+static int shortpath_for_partial __ARGS((char_u **fnamep, char_u **bufp, int *fnamelen));
+
+/*
+ * Get the short pathname of a file.
+ * Returns 1 on success. *fnamelen is 0 for nonexistent path.
+ */
+    static int
+get_short_pathname(fnamep, bufp, fnamelen)
+    char_u	**fnamep;
+    char_u	**bufp;
+    int		*fnamelen;
+{
+    int		l,len;
+    char_u	*newbuf;
+
+    len = *fnamelen;
+
+    l = GetShortPathName(*fnamep, *fnamep, len);
+    if (l > len - 1)
+    {
+	/* If that doesn't work (not enough space), then save the string
+	 * and try again with a new buffer big enough
+	 */
+	newbuf = vim_strnsave(*fnamep, l);
+	if (newbuf == NULL)
+	    return 0;
+
+	vim_free(*bufp);
+	*fnamep = *bufp = newbuf;
+
+	l = GetShortPathName(*fnamep,*fnamep,l+1);
+
+	/* Really should always succeed, as the buffer is big enough */
+    }
+
+    *fnamelen = l;
+    return 1;
+}
+
+/*
+ * Create a short path name.  Returns the length of the buffer it needs.
+ * Doesn't copy over the end of the buffer passed in.
+ */
+    static int
+shortpath_for_invalid_fname(fname, bufp, fnamelen)
+    char_u	**fname;
+    char_u	**bufp;
+    int		*fnamelen;
+{
+    char_u	*s, *p, *pbuf2, *pbuf3;
+    char_u	ch;
+    int		len, len2, plen, slen;
+
+    /* Make a copy */
+    len2 = *fnamelen;
+    pbuf2 = vim_strnsave(*fname, len2);
+    pbuf3 = NULL;
+
+    s = pbuf2 + len2 - 1; /* Find the end */
+    slen = 1;
+    plen = len2;
+
+    if (after_pathsep(pbuf2, s + 1))
+    {
+	--s;
+	++slen;
+	--plen;
+    }
+
+    do
+    {
+	/* Go back one path-separator */
+	while (s > pbuf2 && !after_pathsep(pbuf2, s + 1))
+	{
+	    --s;
+	    ++slen;
+	    --plen;
+	}
+	if (s <= pbuf2)
+	    break;
+
+	/* Remember the character that is about to be splatted */
+	ch = *s;
+	*s = 0; /* get_short_pathname requires a null-terminated string */
+
+	/* Try it in situ */
+	p = pbuf2;
+	if (!get_short_pathname(&p, &pbuf3, &plen))
+	{
+	    vim_free(pbuf2);
+	    return -1;
+	}
+	*s = ch;    /* Preserve the string */
+    } while (plen == 0);
+
+    if (plen > 0)
+    {
+	/* Remember the length of the new string.  */
+	*fnamelen = len = plen + slen;
+	vim_free(*bufp);
+	if (len > len2)
+	{
+	    /* If there's not enough space in the currently allocated string,
+	     * then copy it to a buffer big enough.
+	     */
+	    *fname= *bufp = vim_strnsave(p, len);
+	    if (*fname == NULL)
+		return -1;
+	}
+	else
+	{
+	    /* Transfer pbuf2 to being the main buffer  (it's big enough) */
+	    *fname = *bufp = pbuf2;
+	    if (p != pbuf2)
+		strncpy(*fname, p, plen);
+	    pbuf2 = NULL;
+	}
+	/* Concat the next bit */
+	strncpy(*fname + plen, s, slen);
+	(*fname)[len] = '\0';
+    }
+    vim_free(pbuf3);
+    vim_free(pbuf2);
+    return 0;
+}
+
+/*
+ * Get a pathname for a partial path.
+ */
+    static int
+shortpath_for_partial(fnamep, bufp, fnamelen)
+    char_u	**fnamep;
+    char_u	**bufp;
+    int		*fnamelen;
+{
+    int		sepcount, len, tflen;
+    char_u	*p;
+    char_u	*pbuf, *tfname;
+    int		hasTilde;
+
+    /* Count up the path seperators from the RHS.. so we know which part
+     * of the path to return.
+     */
+    sepcount = 0;
+    for (p = *fnamep; p < *fnamep + *fnamelen; mb_ptr_adv(p))
+	if (vim_ispathsep(*p))
+	    ++sepcount;
+
+    /* Need full path first (use expand_env() to remove a "~/") */
+    hasTilde = (**fnamep == '~');
+    if (hasTilde)
+	pbuf = tfname = expand_env_save(*fnamep);
+    else
+	pbuf = tfname = FullName_save(*fnamep, FALSE);
+
+    len = tflen = (int)STRLEN(tfname);
+
+    if (!get_short_pathname(&tfname, &pbuf, &len))
+	return -1;
+
+    if (len == 0)
+    {
+	/* Don't have a valid filename, so shorten the rest of the
+	 * path if we can. This CAN give us invalid 8.3 filenames, but
+	 * there's not a lot of point in guessing what it might be.
+	 */
+	len = tflen;
+	if (shortpath_for_invalid_fname(&tfname, &pbuf, &len) == -1)
+	    return -1;
+    }
+
+    /* Count the paths backward to find the beginning of the desired string. */
+    for (p = tfname + len - 1; p >= tfname; --p)
+    {
+#ifdef FEAT_MBYTE
+	if (has_mbyte)
+	    p -= mb_head_off(tfname, p);
+#endif
+	if (vim_ispathsep(*p))
+	{
+	    if (sepcount == 0 || (hasTilde && sepcount == 1))
+		break;
+	    else
+		sepcount --;
+	}
+    }
+    if (hasTilde)
+    {
+	--p;
+	if (p >= tfname)
+	    *p = '~';
+	else
+	    return -1;
+    }
+    else
+	++p;
+
+    /* Copy in the string - p indexes into tfname - allocated at pbuf */
+    vim_free(*bufp);
+    *fnamelen = (int)STRLEN(p);
+    *bufp = pbuf;
+    *fnamep = p;
+
+    return 0;
+}
+#endif /* WIN3264 */
+
+/*
+ * Adjust a filename, according to a string of modifiers.
+ * *fnamep must be NUL terminated when called.  When returning, the length is
+ * determined by *fnamelen.
+ * Returns valid flags.
+ * When there is an error, *fnamep is set to NULL.
+ */
+    int
+modify_fname(src, usedlen, fnamep, bufp, fnamelen)
+    char_u	*src;		/* string with modifiers */
+    int		*usedlen;	/* characters after src that are used */
+    char_u	**fnamep;	/* file name so far */
+    char_u	**bufp;		/* buffer for allocated file name or NULL */
+    int		*fnamelen;	/* length of fnamep */
+{
+    int		valid = 0;
+    char_u	*tail;
+    char_u	*s, *p, *pbuf;
+    char_u	dirname[MAXPATHL];
+    int		c;
+    int		has_fullname = 0;
+#ifdef WIN3264
+    int		has_shortname = 0;
+#endif
+
+repeat:
+    /* ":p" - full path/file_name */
+    if (src[*usedlen] == ':' && src[*usedlen + 1] == 'p')
+    {
+	has_fullname = 1;
+
+	valid |= VALID_PATH;
+	*usedlen += 2;
+
+	/* Expand "~/path" for all systems and "~user/path" for Unix and VMS */
+	if ((*fnamep)[0] == '~'
+#if !defined(UNIX) && !(defined(VMS) && defined(USER_HOME))
+		&& ((*fnamep)[1] == '/'
+# ifdef BACKSLASH_IN_FILENAME
+		    || (*fnamep)[1] == '\\'
+# endif
+		    || (*fnamep)[1] == NUL)
+
+#endif
+	   )
+	{
+	    *fnamep = expand_env_save(*fnamep);
+	    vim_free(*bufp);	/* free any allocated file name */
+	    *bufp = *fnamep;
+	    if (*fnamep == NULL)
+		return -1;
+	}
+
+	/* When "/." or "/.." is used: force expansion to get rid of it. */
+	for (p = *fnamep; *p != NUL; mb_ptr_adv(p))
+	{
+	    if (vim_ispathsep(*p)
+		    && p[1] == '.'
+		    && (p[2] == NUL
+			|| vim_ispathsep(p[2])
+			|| (p[2] == '.'
+			    && (p[3] == NUL || vim_ispathsep(p[3])))))
+		break;
+	}
+
+	/* FullName_save() is slow, don't use it when not needed. */
+	if (*p != NUL || !vim_isAbsName(*fnamep))
+	{
+	    *fnamep = FullName_save(*fnamep, *p != NUL);
+	    vim_free(*bufp);	/* free any allocated file name */
+	    *bufp = *fnamep;
+	    if (*fnamep == NULL)
+		return -1;
+	}
+
+	/* Append a path separator to a directory. */
+	if (mch_isdir(*fnamep))
+	{
+	    /* Make room for one or two extra characters. */
+	    *fnamep = vim_strnsave(*fnamep, (int)STRLEN(*fnamep) + 2);
+	    vim_free(*bufp);	/* free any allocated file name */
+	    *bufp = *fnamep;
+	    if (*fnamep == NULL)
+		return -1;
+	    add_pathsep(*fnamep);
+	}
+    }
+
+    /* ":." - path relative to the current directory */
+    /* ":~" - path relative to the home directory */
+    /* ":8" - shortname path - postponed till after */
+    while (src[*usedlen] == ':'
+		  && ((c = src[*usedlen + 1]) == '.' || c == '~' || c == '8'))
+    {
+	*usedlen += 2;
+	if (c == '8')
+	{
+#ifdef WIN3264
+	    has_shortname = 1; /* Postpone this. */
+#endif
+	    continue;
+	}
+	pbuf = NULL;
+	/* Need full path first (use expand_env() to remove a "~/") */
+	if (!has_fullname)
+	{
+	    if (c == '.' && **fnamep == '~')
+		p = pbuf = expand_env_save(*fnamep);
+	    else
+		p = pbuf = FullName_save(*fnamep, FALSE);
+	}
+	else
+	    p = *fnamep;
+
+	has_fullname = 0;
+
+	if (p != NULL)
+	{
+	    if (c == '.')
+	    {
+		mch_dirname(dirname, MAXPATHL);
+		s = shorten_fname(p, dirname);
+		if (s != NULL)
+		{
+		    *fnamep = s;
+		    if (pbuf != NULL)
+		    {
+			vim_free(*bufp);   /* free any allocated file name */
+			*bufp = pbuf;
+			pbuf = NULL;
+		    }
+		}
+	    }
+	    else
+	    {
+		home_replace(NULL, p, dirname, MAXPATHL, TRUE);
+		/* Only replace it when it starts with '~' */
+		if (*dirname == '~')
+		{
+		    s = vim_strsave(dirname);
+		    if (s != NULL)
+		    {
+			*fnamep = s;
+			vim_free(*bufp);
+			*bufp = s;
+		    }
+		}
+	    }
+	    vim_free(pbuf);
+	}
+    }
+
+    tail = gettail(*fnamep);
+    *fnamelen = (int)STRLEN(*fnamep);
+
+    /* ":h" - head, remove "/file_name", can be repeated  */
+    /* Don't remove the first "/" or "c:\" */
+    while (src[*usedlen] == ':' && src[*usedlen + 1] == 'h')
+    {
+	valid |= VALID_HEAD;
+	*usedlen += 2;
+	s = get_past_head(*fnamep);
+	while (tail > s && after_pathsep(s, tail))
+	    --tail;
+	*fnamelen = (int)(tail - *fnamep);
+#ifdef VMS
+	if (*fnamelen > 0)
+	    *fnamelen += 1; /* the path separator is part of the path */
+#endif
+	while (tail > s && !after_pathsep(s, tail))
+	    mb_ptr_back(*fnamep, tail);
+    }
+
+    /* ":8" - shortname  */
+    if (src[*usedlen] == ':' && src[*usedlen + 1] == '8')
+    {
+	*usedlen += 2;
+#ifdef WIN3264
+	has_shortname = 1;
+#endif
+    }
+
+#ifdef WIN3264
+    /* Check shortname after we have done 'heads' and before we do 'tails'
+     */
+    if (has_shortname)
+    {
+	pbuf = NULL;
+	/* Copy the string if it is shortened by :h */
+	if (*fnamelen < (int)STRLEN(*fnamep))
+	{
+	    p = vim_strnsave(*fnamep, *fnamelen);
+	    if (p == 0)
+		return -1;
+	    vim_free(*bufp);
+	    *bufp = *fnamep = p;
+	}
+
+	/* Split into two implementations - makes it easier.  First is where
+	 * there isn't a full name already, second is where there is.
+	 */
+	if (!has_fullname && !vim_isAbsName(*fnamep))
+	{
+	    if (shortpath_for_partial(fnamep, bufp, fnamelen) == -1)
+		return -1;
+	}
+	else
+	{
+	    int		l;
+
+	    /* Simple case, already have the full-name
+	     * Nearly always shorter, so try first time. */
+	    l = *fnamelen;
+	    if (!get_short_pathname(fnamep, bufp, &l))
+		return -1;
+
+	    if (l == 0)
+	    {
+		/* Couldn't find the filename.. search the paths.
+		 */
+		l = *fnamelen;
+		if (shortpath_for_invalid_fname(fnamep, bufp, &l ) == -1)
+		    return -1;
+	    }
+	    *fnamelen = l;
+	}
+    }
+#endif /* WIN3264 */
+
+    /* ":t" - tail, just the basename */
+    if (src[*usedlen] == ':' && src[*usedlen + 1] == 't')
+    {
+	*usedlen += 2;
+	*fnamelen -= (int)(tail - *fnamep);
+	*fnamep = tail;
+    }
+
+    /* ":e" - extension, can be repeated */
+    /* ":r" - root, without extension, can be repeated */
+    while (src[*usedlen] == ':'
+	    && (src[*usedlen + 1] == 'e' || src[*usedlen + 1] == 'r'))
+    {
+	/* find a '.' in the tail:
+	 * - for second :e: before the current fname
+	 * - otherwise: The last '.'
+	 */
+	if (src[*usedlen + 1] == 'e' && *fnamep > tail)
+	    s = *fnamep - 2;
+	else
+	    s = *fnamep + *fnamelen - 1;
+	for ( ; s > tail; --s)
+	    if (s[0] == '.')
+		break;
+	if (src[*usedlen + 1] == 'e')		/* :e */
+	{
+	    if (s > tail)
+	    {
+		*fnamelen += (int)(*fnamep - (s + 1));
+		*fnamep = s + 1;
+#ifdef VMS
+		/* cut version from the extension */
+		s = *fnamep + *fnamelen - 1;
+		for ( ; s > *fnamep; --s)
+		    if (s[0] == ';')
+			break;
+		if (s > *fnamep)
+		    *fnamelen = s - *fnamep;
+#endif
+	    }
+	    else if (*fnamep <= tail)
+		*fnamelen = 0;
+	}
+	else				/* :r */
+	{
+	    if (s > tail)	/* remove one extension */
+		*fnamelen = (int)(s - *fnamep);
+	}
+	*usedlen += 2;
+    }
+
+    /* ":s?pat?foo?" - substitute */
+    /* ":gs?pat?foo?" - global substitute */
+    if (src[*usedlen] == ':'
+	    && (src[*usedlen + 1] == 's'
+		|| (src[*usedlen + 1] == 'g' && src[*usedlen + 2] == 's')))
+    {
+	char_u	    *str;
+	char_u	    *pat;
+	char_u	    *sub;
+	int	    sep;
+	char_u	    *flags;
+	int	    didit = FALSE;
+
+	flags = (char_u *)"";
+	s = src + *usedlen + 2;
+	if (src[*usedlen + 1] == 'g')
+	{
+	    flags = (char_u *)"g";
+	    ++s;
+	}
+
+	sep = *s++;
+	if (sep)
+	{
+	    /* find end of pattern */
+	    p = vim_strchr(s, sep);
+	    if (p != NULL)
+	    {
+		pat = vim_strnsave(s, (int)(p - s));
+		if (pat != NULL)
+		{
+		    s = p + 1;
+		    /* find end of substitution */
+		    p = vim_strchr(s, sep);
+		    if (p != NULL)
+		    {
+			sub = vim_strnsave(s, (int)(p - s));
+			str = vim_strnsave(*fnamep, *fnamelen);
+			if (sub != NULL && str != NULL)
+			{
+			    *usedlen = (int)(p + 1 - src);
+			    s = do_string_sub(str, pat, sub, flags);
+			    if (s != NULL)
+			    {
+				*fnamep = s;
+				*fnamelen = (int)STRLEN(s);
+				vim_free(*bufp);
+				*bufp = s;
+				didit = TRUE;
+			    }
+			}
+			vim_free(sub);
+			vim_free(str);
+		    }
+		    vim_free(pat);
+		}
+	    }
+	    /* after using ":s", repeat all the modifiers */
+	    if (didit)
+		goto repeat;
+	}
+    }
+
+    return valid;
+}
+
+/*
+ * Perform a substitution on "str" with pattern "pat" and substitute "sub".
+ * "flags" can be "g" to do a global substitute.
+ * Returns an allocated string, NULL for error.
+ */
+    char_u *
+do_string_sub(str, pat, sub, flags)
+    char_u	*str;
+    char_u	*pat;
+    char_u	*sub;
+    char_u	*flags;
+{
+    int		sublen;
+    regmatch_T	regmatch;
+    int		i;
+    int		do_all;
+    char_u	*tail;
+    garray_T	ga;
+    char_u	*ret;
+    char_u	*save_cpo;
+
+    /* Make 'cpoptions' empty, so that the 'l' flag doesn't work here */
+    save_cpo = p_cpo;
+    p_cpo = (char_u *)"";
+
+    ga_init2(&ga, 1, 200);
+
+    do_all = (flags[0] == 'g');
+
+    regmatch.rm_ic = p_ic;
+    regmatch.regprog = vim_regcomp(pat, RE_MAGIC + RE_STRING);
+    if (regmatch.regprog != NULL)
+    {
+	tail = str;
+	while (vim_regexec_nl(&regmatch, str, (colnr_T)(tail - str)))
+	{
+	    /*
+	     * Get some space for a temporary buffer to do the substitution
+	     * into.  It will contain:
+	     * - The text up to where the match is.
+	     * - The substituted text.
+	     * - The text after the match.
+	     */
+	    sublen = vim_regsub(&regmatch, sub, tail, FALSE, TRUE, FALSE);
+	    if (ga_grow(&ga, (int)(STRLEN(tail) + sublen -
+			    (regmatch.endp[0] - regmatch.startp[0]))) == FAIL)
+	    {
+		ga_clear(&ga);
+		break;
+	    }
+
+	    /* copy the text up to where the match is */
+	    i = (int)(regmatch.startp[0] - tail);
+	    mch_memmove((char_u *)ga.ga_data + ga.ga_len, tail, (size_t)i);
+	    /* add the substituted text */
+	    (void)vim_regsub(&regmatch, sub, (char_u *)ga.ga_data
+					  + ga.ga_len + i, TRUE, TRUE, FALSE);
+	    ga.ga_len += i + sublen - 1;
+	    /* avoid getting stuck on a match with an empty string */
+	    if (tail == regmatch.endp[0])
+	    {
+		if (*tail == NUL)
+		    break;
+		*((char_u *)ga.ga_data + ga.ga_len) = *tail++;
+		++ga.ga_len;
+	    }
+	    else
+	    {
+		tail = regmatch.endp[0];
+		if (*tail == NUL)
+		    break;
+	    }
+	    if (!do_all)
+		break;
+	}
+
+	if (ga.ga_data != NULL)
+	    STRCPY((char *)ga.ga_data + ga.ga_len, tail);
+
+	vim_free(regmatch.regprog);
+    }
+
+    ret = vim_strsave(ga.ga_data == NULL ? str : (char_u *)ga.ga_data);
+    ga_clear(&ga);
+    p_cpo = save_cpo;
+
+    return ret;
+}
+
+#endif /* defined(FEAT_MODIFY_FNAME) || defined(FEAT_EVAL) */
--- /dev/null
+++ b/ex_cmds.c
@@ -1,0 +1,7052 @@
+/* vi:set ts=8 sts=4 sw=4:
+ *
+ * VIM - Vi IMproved	by Bram Moolenaar
+ *
+ * Do ":help uganda"  in Vim to read copying and usage conditions.
+ * Do ":help credits" in Vim to see a list of people who contributed.
+ * See README.txt for an overview of the Vim source code.
+ */
+
+/*
+ * ex_cmds.c: some functions for command line commands
+ */
+
+#include "vim.h"
+#ifdef HAVE_FCNTL_H
+# include <fcntl.h>
+#endif
+#include "version.h"
+
+#ifdef FEAT_EX_EXTRA
+static int linelen __ARGS((int *has_tab));
+#endif
+static void do_filter __ARGS((linenr_T line1, linenr_T line2, exarg_T *eap, char_u *cmd, int do_in, int do_out));
+#ifdef FEAT_VIMINFO
+static char_u *viminfo_filename __ARGS((char_u	*));
+static void do_viminfo __ARGS((FILE *fp_in, FILE *fp_out, int want_info, int want_marks, int force_read));
+static int viminfo_encoding __ARGS((vir_T *virp));
+static int read_viminfo_up_to_marks __ARGS((vir_T *virp, int forceit, int writing));
+#endif
+
+static int check_overwrite __ARGS((exarg_T *eap, buf_T *buf, char_u *fname, char_u *ffname, int other));
+static int check_readonly __ARGS((int *forceit, buf_T *buf));
+#ifdef FEAT_AUTOCMD
+static void delbuf_msg __ARGS((char_u *name));
+#endif
+static int
+#ifdef __BORLANDC__
+    _RTLENTRYF
+#endif
+	help_compare __ARGS((const void *s1, const void *s2));
+
+/*
+ * ":ascii" and "ga".
+ */
+/*ARGSUSED*/
+    void
+do_ascii(eap)
+    exarg_T	*eap;
+{
+    int		c;
+    char	buf1[20];
+    char	buf2[20];
+    char_u	buf3[7];
+#ifdef FEAT_MBYTE
+    int		cc[MAX_MCO];
+    int		ci = 0;
+    int		len;
+
+    if (enc_utf8)
+	c = utfc_ptr2char(ml_get_cursor(), cc);
+    else
+#endif
+	c = gchar_cursor();
+    if (c == NUL)
+    {
+	MSG("NUL");
+	return;
+    }
+
+#ifdef FEAT_MBYTE
+    IObuff[0] = NUL;
+    if (!has_mbyte || (enc_dbcs != 0 && c < 0x100) || c < 0x80)
+#endif
+    {
+	if (c == NL)	    /* NUL is stored as NL */
+	    c = NUL;
+	if (vim_isprintc_strict(c) && (c < ' '
+#ifndef EBCDIC
+		    || c > '~'
+#endif
+			       ))
+	{
+	    transchar_nonprint(buf3, c);
+	    sprintf(buf1, "  <%s>", (char *)buf3);
+	}
+	else
+	    buf1[0] = NUL;
+#ifndef EBCDIC
+	if (c >= 0x80)
+	    sprintf(buf2, "  <M-%s>", transchar(c & 0x7f));
+	else
+#endif
+	    buf2[0] = NUL;
+	vim_snprintf((char *)IObuff, IOSIZE,
+		_("<%s>%s%s  %d,  Hex %02x,  Octal %03o"),
+					   transchar(c), buf1, buf2, c, c, c);
+#ifdef FEAT_MBYTE
+	if (enc_utf8)
+	    c = cc[ci++];
+	else
+	    c = 0;
+#endif
+    }
+
+#ifdef FEAT_MBYTE
+    /* Repeat for combining characters. */
+    while (has_mbyte && (c >= 0x100 || (enc_utf8 && c >= 0x80)))
+    {
+	len = (int)STRLEN(IObuff);
+	/* This assumes every multi-byte char is printable... */
+	if (len > 0)
+	    IObuff[len++] = ' ';
+	IObuff[len++] = '<';
+	if (enc_utf8 && utf_iscomposing(c)
+# ifdef USE_GUI
+		&& !gui.in_use
+# endif
+		)
+	    IObuff[len++] = ' '; /* draw composing char on top of a space */
+	len += (*mb_char2bytes)(c, IObuff + len);
+	vim_snprintf((char *)IObuff + len, IOSIZE - len,
+			c < 0x10000 ? _("> %d, Hex %04x, Octal %o")
+				    : _("> %d, Hex %08x, Octal %o"), c, c, c);
+	if (ci == MAX_MCO)
+	    break;
+	if (enc_utf8)
+	    c = cc[ci++];
+	else
+	    c = 0;
+    }
+#endif
+
+    msg(IObuff);
+}
+
+#if defined(FEAT_EX_EXTRA) || defined(PROTO)
+/*
+ * ":left", ":center" and ":right": align text.
+ */
+    void
+ex_align(eap)
+    exarg_T	*eap;
+{
+    pos_T	save_curpos;
+    int		len;
+    int		indent = 0;
+    int		new_indent;
+    int		has_tab;
+    int		width;
+
+#ifdef FEAT_RIGHTLEFT
+    if (curwin->w_p_rl)
+    {
+	/* switch left and right aligning */
+	if (eap->cmdidx == CMD_right)
+	    eap->cmdidx = CMD_left;
+	else if (eap->cmdidx == CMD_left)
+	    eap->cmdidx = CMD_right;
+    }
+#endif
+
+    width = atoi((char *)eap->arg);
+    save_curpos = curwin->w_cursor;
+    if (eap->cmdidx == CMD_left)    /* width is used for new indent */
+    {
+	if (width >= 0)
+	    indent = width;
+    }
+    else
+    {
+	/*
+	 * if 'textwidth' set, use it
+	 * else if 'wrapmargin' set, use it
+	 * if invalid value, use 80
+	 */
+	if (width <= 0)
+	    width = curbuf->b_p_tw;
+	if (width == 0 && curbuf->b_p_wm > 0)
+	    width = W_WIDTH(curwin) - curbuf->b_p_wm;
+	if (width <= 0)
+	    width = 80;
+    }
+
+    if (u_save((linenr_T)(eap->line1 - 1), (linenr_T)(eap->line2 + 1)) == FAIL)
+	return;
+
+    for (curwin->w_cursor.lnum = eap->line1;
+		 curwin->w_cursor.lnum <= eap->line2; ++curwin->w_cursor.lnum)
+    {
+	if (eap->cmdidx == CMD_left)		/* left align */
+	    new_indent = indent;
+	else
+	{
+	    has_tab = FALSE;	/* avoid uninit warnings */
+	    len = linelen(eap->cmdidx == CMD_right ? &has_tab
+						   : NULL) - get_indent();
+
+	    if (len <= 0)			/* skip blank lines */
+		continue;
+
+	    if (eap->cmdidx == CMD_center)
+		new_indent = (width - len) / 2;
+	    else
+	    {
+		new_indent = width - len;	/* right align */
+
+		/*
+		 * Make sure that embedded TABs don't make the text go too far
+		 * to the right.
+		 */
+		if (has_tab)
+		    while (new_indent > 0)
+		    {
+			(void)set_indent(new_indent, 0);
+			if (linelen(NULL) <= width)
+			{
+			    /*
+			     * Now try to move the line as much as possible to
+			     * the right.  Stop when it moves too far.
+			     */
+			    do
+				(void)set_indent(++new_indent, 0);
+			    while (linelen(NULL) <= width);
+			    --new_indent;
+			    break;
+			}
+			--new_indent;
+		    }
+	    }
+	}
+	if (new_indent < 0)
+	    new_indent = 0;
+	(void)set_indent(new_indent, 0);		/* set indent */
+    }
+    changed_lines(eap->line1, 0, eap->line2 + 1, 0L);
+    curwin->w_cursor = save_curpos;
+    beginline(BL_WHITE | BL_FIX);
+}
+
+/*
+ * Get the length of the current line, excluding trailing white space.
+ */
+    static int
+linelen(has_tab)
+    int	    *has_tab;
+{
+    char_u  *line;
+    char_u  *first;
+    char_u  *last;
+    int	    save;
+    int	    len;
+
+    /* find the first non-blank character */
+    line = ml_get_curline();
+    first = skipwhite(line);
+
+    /* find the character after the last non-blank character */
+    for (last = first + STRLEN(first);
+				last > first && vim_iswhite(last[-1]); --last)
+	;
+    save = *last;
+    *last = NUL;
+    len = linetabsize(line);		/* get line length */
+    if (has_tab != NULL)		/* check for embedded TAB */
+	*has_tab = (vim_strrchr(first, TAB) != NULL);
+    *last = save;
+
+    return len;
+}
+
+/* Buffer for two lines used during sorting.  They are allocated to
+ * contain the longest line being sorted. */
+static char_u	*sortbuf1;
+static char_u	*sortbuf2;
+
+static int	sort_ic;		/* ignore case */
+static int	sort_nr;		/* sort on number */
+static int	sort_rx;		/* sort on regex instead of skipping it */
+
+static int	sort_abort;		/* flag to indicate if sorting has been interrupted */
+
+/* Struct to store info to be sorted. */
+typedef struct
+{
+    linenr_T	lnum;			/* line number */
+    long	start_col_nr;		/* starting column number or number */
+    long	end_col_nr;		/* ending column number */
+} sorti_T;
+
+static int
+#ifdef __BORLANDC__
+_RTLENTRYF
+#endif
+sort_compare __ARGS((const void *s1, const void *s2));
+
+    static int
+#ifdef __BORLANDC__
+_RTLENTRYF
+#endif
+sort_compare(s1, s2)
+    const void	*s1;
+    const void	*s2;
+{
+    sorti_T	l1 = *(sorti_T *)s1;
+    sorti_T	l2 = *(sorti_T *)s2;
+    int		result = 0;
+
+    /* If the user interrupts, there's no way to stop qsort() immediately, but
+     * if we return 0 every time, qsort will assume it's done sorting and
+     * exit. */
+    if (sort_abort)
+	return 0;
+    fast_breakcheck();
+    if (got_int)
+	sort_abort = TRUE;
+
+    /* When sorting numbers "start_col_nr" is the number, not the column
+     * number. */
+    if (sort_nr)
+	result = l1.start_col_nr - l2.start_col_nr;
+    else
+    {
+	/* We need to copy one line into "sortbuf1", because there is no
+	 * guarantee that the first pointer becomes invalid when obtaining the
+	 * second one. */
+	STRNCPY(sortbuf1, ml_get(l1.lnum) + l1.start_col_nr,
+					 l1.end_col_nr - l1.start_col_nr + 1);
+	sortbuf1[l1.end_col_nr - l1.start_col_nr] = 0;
+	STRNCPY(sortbuf2, ml_get(l2.lnum) + l2.start_col_nr,
+					 l2.end_col_nr - l2.start_col_nr + 1);
+	sortbuf2[l2.end_col_nr - l2.start_col_nr] = 0;
+
+	result = sort_ic ? STRICMP(sortbuf1, sortbuf2)
+						 : STRCMP(sortbuf1, sortbuf2);
+    }
+
+    /* If two lines have the same value, preserve the original line order. */
+    if (result == 0)
+	return (int)(l1.lnum - l2.lnum);
+    return result;
+}
+
+/*
+ * ":sort".
+ */
+    void
+ex_sort(eap)
+    exarg_T	*eap;
+{
+    regmatch_T	regmatch;
+    int		len;
+    linenr_T	lnum;
+    long	maxlen = 0;
+    sorti_T	*nrs;
+    size_t	count = eap->line2 - eap->line1 + 1;
+    size_t	i;
+    char_u	*p;
+    char_u	*s;
+    char_u	*s2;
+    char_u	c;			/* temporary character storage */
+    int		unique = FALSE;
+    long	deleted;
+    colnr_T	start_col;
+    colnr_T	end_col;
+    int		sort_oct;		/* sort on octal number */
+    int		sort_hex;		/* sort on hex number */
+
+    if (u_save((linenr_T)(eap->line1 - 1), (linenr_T)(eap->line2 + 1)) == FAIL)
+	return;
+    sortbuf1 = NULL;
+    sortbuf2 = NULL;
+    regmatch.regprog = NULL;
+    nrs = (sorti_T *)lalloc((long_u)(count * sizeof(sorti_T)), TRUE);
+    if (nrs == NULL)
+	goto sortend;
+
+    sort_abort = sort_ic = sort_rx = sort_nr = sort_oct = sort_hex = 0;
+
+    for (p = eap->arg; *p != NUL; ++p)
+    {
+	if (vim_iswhite(*p))
+	    ;
+	else if (*p == 'i')
+	    sort_ic = TRUE;
+	else if (*p == 'r')
+	    sort_rx = TRUE;
+	else if (*p == 'n')
+	    sort_nr = 2;
+	else if (*p == 'o')
+	    sort_oct = 2;
+	else if (*p == 'x')
+	    sort_hex = 2;
+	else if (*p == 'u')
+	    unique = TRUE;
+	else if (*p == '"')	/* comment start */
+	    break;
+	else if (check_nextcmd(p) != NULL)
+	{
+	    eap->nextcmd = check_nextcmd(p);
+	    break;
+	}
+	else if (!ASCII_ISALPHA(*p) && regmatch.regprog == NULL)
+	{
+	    s = skip_regexp(p + 1, *p, TRUE, NULL);
+	    if (*s != *p)
+	    {
+		EMSG(_(e_invalpat));
+		goto sortend;
+	    }
+	    *s = NUL;
+	    regmatch.regprog = vim_regcomp(p + 1, RE_MAGIC);
+	    if (regmatch.regprog == NULL)
+		goto sortend;
+	    p = s;		/* continue after the regexp */
+	    regmatch.rm_ic = p_ic;
+	}
+	else
+	{
+	    EMSG2(_(e_invarg2), p);
+	    goto sortend;
+	}
+    }
+
+    /* Can only have one of 'n', 'o' and 'x'. */
+    if (sort_nr + sort_oct + sort_hex > 2)
+    {
+	EMSG(_(e_invarg));
+	goto sortend;
+    }
+
+    /* From here on "sort_nr" is used as a flag for any number sorting. */
+    sort_nr += sort_oct + sort_hex;
+
+    /*
+     * Make an array with all line numbers.  This avoids having to copy all
+     * the lines into allocated memory.
+     * When sorting on strings "start_col_nr" is the offset in the line, for
+     * numbers sorting it's the number to sort on.  This means the pattern
+     * matching and number conversion only has to be done once per line.
+     * Also get the longest line length for allocating "sortbuf".
+     */
+    for (lnum = eap->line1; lnum <= eap->line2; ++lnum)
+    {
+	s = ml_get(lnum);
+	len = (int)STRLEN(s);
+	if (maxlen < len)
+	    maxlen = len;
+
+	start_col = 0;
+	end_col = len;
+	if (regmatch.regprog != NULL && vim_regexec(&regmatch, s, 0))
+	{
+	    if (sort_rx)
+	    {
+		start_col = (colnr_T)(regmatch.startp[0] - s);
+		end_col = (colnr_T)(regmatch.endp[0] - s);
+	    }
+	    else
+		start_col = (colnr_T)(regmatch.endp[0] - s);
+	}
+	else
+	    if (regmatch.regprog != NULL)
+		end_col = 0;
+
+	if (sort_nr)
+	{
+	    /* Make sure vim_str2nr doesn't read any digits past the end
+	     * of the match, by temporarily terminating the string there */
+	    s2 = s + end_col;
+	    c = *s2;
+	    (*s2) = 0;
+	    /* Sorting on number: Store the number itself. */
+	    if (sort_hex)
+		s = skiptohex(s + start_col);
+	    else
+		s = skiptodigit(s + start_col);
+	    vim_str2nr(s, NULL, NULL, sort_oct, sort_hex,
+					&nrs[lnum - eap->line1].start_col_nr, NULL);
+	    (*s2) = c;
+	}
+	else
+	{
+	    /* Store the column to sort at. */
+	    nrs[lnum - eap->line1].start_col_nr = start_col;
+	    nrs[lnum - eap->line1].end_col_nr = end_col;
+	}
+
+	nrs[lnum - eap->line1].lnum = lnum;
+
+	if (regmatch.regprog != NULL)
+	    fast_breakcheck();
+	if (got_int)
+	    goto sortend;
+    }
+
+    /* Allocate a buffer that can hold the longest line. */
+    sortbuf1 = alloc((unsigned)maxlen + 1);
+    if (sortbuf1 == NULL)
+	goto sortend;
+    sortbuf2 = alloc((unsigned)maxlen + 1);
+    if (sortbuf2 == NULL)
+	goto sortend;
+
+    /* Sort the array of line numbers.  Note: can't be interrupted! */
+    qsort((void *)nrs, count, sizeof(sorti_T), sort_compare);
+
+    if (sort_abort)
+	goto sortend;
+
+    /* Insert the lines in the sorted order below the last one. */
+    lnum = eap->line2;
+    for (i = 0; i < count; ++i)
+    {
+	s = ml_get(nrs[eap->forceit ? count - i - 1 : i].lnum);
+	if (!unique || i == 0
+		|| (sort_ic ? STRICMP(s, sortbuf1) : STRCMP(s, sortbuf1)) != 0)
+	{
+	    if (ml_append(lnum++, s, (colnr_T)0, FALSE) == FAIL)
+		break;
+	    if (unique)
+		STRCPY(sortbuf1, s);
+	}
+	fast_breakcheck();
+	if (got_int)
+	    goto sortend;
+    }
+
+    /* delete the original lines if appending worked */
+    if (i == count)
+	for (i = 0; i < count; ++i)
+	    ml_delete(eap->line1, FALSE);
+    else
+	count = 0;
+
+    /* Adjust marks for deleted (or added) lines and prepare for displaying. */
+    deleted = (long)(count - (lnum - eap->line2));
+    if (deleted > 0)
+	mark_adjust(eap->line2 - deleted, eap->line2, (long)MAXLNUM, -deleted);
+    else if (deleted < 0)
+	mark_adjust(eap->line2, MAXLNUM, -deleted, 0L);
+    changed_lines(eap->line1, 0, eap->line2 + 1, -deleted);
+
+    curwin->w_cursor.lnum = eap->line1;
+    beginline(BL_WHITE | BL_FIX);
+
+sortend:
+    vim_free(nrs);
+    vim_free(sortbuf1);
+    vim_free(sortbuf2);
+    vim_free(regmatch.regprog);
+    if (got_int)
+	EMSG(_(e_interr));
+}
+
+/*
+ * ":retab".
+ */
+    void
+ex_retab(eap)
+    exarg_T	*eap;
+{
+    linenr_T	lnum;
+    int		got_tab = FALSE;
+    long	num_spaces = 0;
+    long	num_tabs;
+    long	len;
+    long	col;
+    long	vcol;
+    long	start_col = 0;		/* For start of white-space string */
+    long	start_vcol = 0;		/* For start of white-space string */
+    int		temp;
+    long	old_len;
+    char_u	*ptr;
+    char_u	*new_line = (char_u *)1;    /* init to non-NULL */
+    int		did_undo;		/* called u_save for current line */
+    int		new_ts;
+    int		save_list;
+    linenr_T	first_line = 0;		/* first changed line */
+    linenr_T	last_line = 0;		/* last changed line */
+
+    save_list = curwin->w_p_list;
+    curwin->w_p_list = 0;	    /* don't want list mode here */
+
+    new_ts = getdigits(&(eap->arg));
+    if (new_ts < 0)
+    {
+	EMSG(_(e_positive));
+	return;
+    }
+    if (new_ts == 0)
+	new_ts = curbuf->b_p_ts;
+    for (lnum = eap->line1; !got_int && lnum <= eap->line2; ++lnum)
+    {
+	ptr = ml_get(lnum);
+	col = 0;
+	vcol = 0;
+	did_undo = FALSE;
+	for (;;)
+	{
+	    if (vim_iswhite(ptr[col]))
+	    {
+		if (!got_tab && num_spaces == 0)
+		{
+		    /* First consecutive white-space */
+		    start_vcol = vcol;
+		    start_col = col;
+		}
+		if (ptr[col] == ' ')
+		    num_spaces++;
+		else
+		    got_tab = TRUE;
+	    }
+	    else
+	    {
+		if (got_tab || (eap->forceit && num_spaces > 1))
+		{
+		    /* Retabulate this string of white-space */
+
+		    /* len is virtual length of white string */
+		    len = num_spaces = vcol - start_vcol;
+		    num_tabs = 0;
+		    if (!curbuf->b_p_et)
+		    {
+			temp = new_ts - (start_vcol % new_ts);
+			if (num_spaces >= temp)
+			{
+			    num_spaces -= temp;
+			    num_tabs++;
+			}
+			num_tabs += num_spaces / new_ts;
+			num_spaces -= (num_spaces / new_ts) * new_ts;
+		    }
+		    if (curbuf->b_p_et || got_tab ||
+					(num_spaces + num_tabs < len))
+		    {
+			if (did_undo == FALSE)
+			{
+			    did_undo = TRUE;
+			    if (u_save((linenr_T)(lnum - 1),
+						(linenr_T)(lnum + 1)) == FAIL)
+			    {
+				new_line = NULL;	/* flag out-of-memory */
+				break;
+			    }
+			}
+
+			/* len is actual number of white characters used */
+			len = num_spaces + num_tabs;
+			old_len = (long)STRLEN(ptr);
+			new_line = lalloc(old_len - col + start_col + len + 1,
+									TRUE);
+			if (new_line == NULL)
+			    break;
+			if (start_col > 0)
+			    mch_memmove(new_line, ptr, (size_t)start_col);
+			mch_memmove(new_line + start_col + len,
+				      ptr + col, (size_t)(old_len - col + 1));
+			ptr = new_line + start_col;
+			for (col = 0; col < len; col++)
+			    ptr[col] = (col < num_tabs) ? '\t' : ' ';
+			ml_replace(lnum, new_line, FALSE);
+			if (first_line == 0)
+			    first_line = lnum;
+			last_line = lnum;
+			ptr = new_line;
+			col = start_col + len;
+		    }
+		}
+		got_tab = FALSE;
+		num_spaces = 0;
+	    }
+	    if (ptr[col] == NUL)
+		break;
+	    vcol += chartabsize(ptr + col, (colnr_T)vcol);
+#ifdef FEAT_MBYTE
+	    if (has_mbyte)
+		col += (*mb_ptr2len)(ptr + col);
+	    else
+#endif
+		++col;
+	}
+	if (new_line == NULL)		    /* out of memory */
+	    break;
+	line_breakcheck();
+    }
+    if (got_int)
+	EMSG(_(e_interr));
+
+    if (curbuf->b_p_ts != new_ts)
+	redraw_curbuf_later(NOT_VALID);
+    if (first_line != 0)
+	changed_lines(first_line, 0, last_line + 1, 0L);
+
+    curwin->w_p_list = save_list;	/* restore 'list' */
+
+    curbuf->b_p_ts = new_ts;
+    coladvance(curwin->w_curswant);
+
+    u_clearline();
+}
+#endif
+
+/*
+ * :move command - move lines line1-line2 to line dest
+ *
+ * return FAIL for failure, OK otherwise
+ */
+    int
+do_move(line1, line2, dest)
+    linenr_T	line1;
+    linenr_T	line2;
+    linenr_T	dest;
+{
+    char_u	*str;
+    linenr_T	l;
+    linenr_T	extra;	    /* Num lines added before line1 */
+    linenr_T	num_lines;  /* Num lines moved */
+    linenr_T	last_line;  /* Last line in file after adding new text */
+
+    if (dest >= line1 && dest < line2)
+    {
+	EMSG(_("E134: Move lines into themselves"));
+	return FAIL;
+    }
+
+    num_lines = line2 - line1 + 1;
+
+    /*
+     * First we copy the old text to its new location -- webb
+     * Also copy the flag that ":global" command uses.
+     */
+    if (u_save(dest, dest + 1) == FAIL)
+	return FAIL;
+    for (extra = 0, l = line1; l <= line2; l++)
+    {
+	str = vim_strsave(ml_get(l + extra));
+	if (str != NULL)
+	{
+	    ml_append(dest + l - line1, str, (colnr_T)0, FALSE);
+	    vim_free(str);
+	    if (dest < line1)
+		extra++;
+	}
+    }
+
+    /*
+     * Now we must be careful adjusting our marks so that we don't overlap our
+     * mark_adjust() calls.
+     *
+     * We adjust the marks within the old text so that they refer to the
+     * last lines of the file (temporarily), because we know no other marks
+     * will be set there since these line numbers did not exist until we added
+     * our new lines.
+     *
+     * Then we adjust the marks on lines between the old and new text positions
+     * (either forwards or backwards).
+     *
+     * And Finally we adjust the marks we put at the end of the file back to
+     * their final destination at the new text position -- webb
+     */
+    last_line = curbuf->b_ml.ml_line_count;
+    mark_adjust(line1, line2, last_line - line2, 0L);
+    if (dest >= line2)
+    {
+	mark_adjust(line2 + 1, dest, -num_lines, 0L);
+	curbuf->b_op_start.lnum = dest - num_lines + 1;
+	curbuf->b_op_end.lnum = dest;
+    }
+    else
+    {
+	mark_adjust(dest + 1, line1 - 1, num_lines, 0L);
+	curbuf->b_op_start.lnum = dest + 1;
+	curbuf->b_op_end.lnum = dest + num_lines;
+    }
+    curbuf->b_op_start.col = curbuf->b_op_end.col = 0;
+    mark_adjust(last_line - num_lines + 1, last_line,
+					     -(last_line - dest - extra), 0L);
+
+    /*
+     * Now we delete the original text -- webb
+     */
+    if (u_save(line1 + extra - 1, line2 + extra + 1) == FAIL)
+	return FAIL;
+
+    for (l = line1; l <= line2; l++)
+	ml_delete(line1 + extra, TRUE);
+
+    if (!global_busy && num_lines > p_report)
+    {
+	if (num_lines == 1)
+	    MSG(_("1 line moved"));
+	else
+	    smsg((char_u *)_("%ld lines moved"), num_lines);
+    }
+
+    /*
+     * Leave the cursor on the last of the moved lines.
+     */
+    if (dest >= line1)
+	curwin->w_cursor.lnum = dest;
+    else
+	curwin->w_cursor.lnum = dest + (line2 - line1) + 1;
+
+    if (line1 < dest)
+	changed_lines(line1, 0, dest + num_lines + 1, 0L);
+    else
+	changed_lines(dest + 1, 0, line1 + num_lines, 0L);
+
+    return OK;
+}
+
+/*
+ * ":copy"
+ */
+    void
+ex_copy(line1, line2, n)
+    linenr_T	line1;
+    linenr_T	line2;
+    linenr_T	n;
+{
+    linenr_T	count;
+    char_u	*p;
+
+    count = line2 - line1 + 1;
+    curbuf->b_op_start.lnum = n + 1;
+    curbuf->b_op_end.lnum = n + count;
+    curbuf->b_op_start.col = curbuf->b_op_end.col = 0;
+
+    /*
+     * there are three situations:
+     * 1. destination is above line1
+     * 2. destination is between line1 and line2
+     * 3. destination is below line2
+     *
+     * n = destination (when starting)
+     * curwin->w_cursor.lnum = destination (while copying)
+     * line1 = start of source (while copying)
+     * line2 = end of source (while copying)
+     */
+    if (u_save(n, n + 1) == FAIL)
+	return;
+
+    curwin->w_cursor.lnum = n;
+    while (line1 <= line2)
+    {
+	/* need to use vim_strsave() because the line will be unlocked within
+	 * ml_append() */
+	p = vim_strsave(ml_get(line1));
+	if (p != NULL)
+	{
+	    ml_append(curwin->w_cursor.lnum, p, (colnr_T)0, FALSE);
+	    vim_free(p);
+	}
+	/* situation 2: skip already copied lines */
+	if (line1 == n)
+	    line1 = curwin->w_cursor.lnum;
+	++line1;
+	if (curwin->w_cursor.lnum < line1)
+	    ++line1;
+	if (curwin->w_cursor.lnum < line2)
+	    ++line2;
+	++curwin->w_cursor.lnum;
+    }
+
+    appended_lines_mark(n, count);
+
+    msgmore((long)count);
+}
+
+static char_u	*prevcmd = NULL;	/* the previous command */
+
+#if defined(EXITFREE) || defined(PROTO)
+    void
+free_prev_shellcmd()
+{
+    vim_free(prevcmd);
+}
+#endif
+
+/*
+ * Handle the ":!cmd" command.	Also for ":r !cmd" and ":w !cmd"
+ * Bangs in the argument are replaced with the previously entered command.
+ * Remember the argument.
+ *
+ * RISCOS: Bangs only replaced when followed by a space, since many
+ * pathnames contain one.
+ */
+    void
+do_bang(addr_count, eap, forceit, do_in, do_out)
+    int		addr_count;
+    exarg_T	*eap;
+    int		forceit;
+    int		do_in, do_out;
+{
+    char_u		*arg = eap->arg;	/* command */
+    linenr_T		line1 = eap->line1;	/* start of range */
+    linenr_T		line2 = eap->line2;	/* end of range */
+    char_u		*newcmd = NULL;		/* the new command */
+    int			free_newcmd = FALSE;    /* need to free() newcmd */
+    int			ins_prevcmd;
+    char_u		*t;
+    char_u		*p;
+    char_u		*trailarg;
+    int			len;
+    int			scroll_save = msg_scroll;
+
+    /*
+     * Disallow shell commands for "rvim".
+     * Disallow shell commands from .exrc and .vimrc in current directory for
+     * security reasons.
+     */
+    if (check_restricted() || check_secure())
+	return;
+
+    if (addr_count == 0)		/* :! */
+    {
+	msg_scroll = FALSE;	    /* don't scroll here */
+	autowrite_all();
+	msg_scroll = scroll_save;
+    }
+
+    /*
+     * Try to find an embedded bang, like in :!<cmd> ! [args]
+     * (:!! is indicated by the 'forceit' variable)
+     */
+    ins_prevcmd = forceit;
+    trailarg = arg;
+    do
+    {
+	len = (int)STRLEN(trailarg) + 1;
+	if (newcmd != NULL)
+	    len += (int)STRLEN(newcmd);
+	if (ins_prevcmd)
+	{
+	    if (prevcmd == NULL)
+	    {
+		EMSG(_(e_noprev));
+		vim_free(newcmd);
+		return;
+	    }
+	    len += (int)STRLEN(prevcmd);
+	}
+	if ((t = alloc(len)) == NULL)
+	{
+	    vim_free(newcmd);
+	    return;
+	}
+	*t = NUL;
+	if (newcmd != NULL)
+	    STRCAT(t, newcmd);
+	if (ins_prevcmd)
+	    STRCAT(t, prevcmd);
+	p = t + STRLEN(t);
+	STRCAT(t, trailarg);
+	vim_free(newcmd);
+	newcmd = t;
+
+	/*
+	 * Scan the rest of the argument for '!', which is replaced by the
+	 * previous command.  "\!" is replaced by "!" (this is vi compatible).
+	 */
+	trailarg = NULL;
+	while (*p)
+	{
+	    if (*p == '!'
+#ifdef RISCOS
+			&& (p[1] == ' ' || p[1] == NUL)
+#endif
+					)
+	    {
+		if (p > newcmd && p[-1] == '\\')
+		    mch_memmove(p - 1, p, (size_t)(STRLEN(p) + 1));
+		else
+		{
+		    trailarg = p;
+		    *trailarg++ = NUL;
+		    ins_prevcmd = TRUE;
+		    break;
+		}
+	    }
+	    ++p;
+	}
+    } while (trailarg != NULL);
+
+    vim_free(prevcmd);
+    prevcmd = newcmd;
+
+    if (bangredo)	    /* put cmd in redo buffer for ! command */
+    {
+	AppendToRedobuffLit(prevcmd, -1);
+	AppendToRedobuff((char_u *)"\n");
+	bangredo = FALSE;
+    }
+    /*
+     * Add quotes around the command, for shells that need them.
+     */
+    if (*p_shq != NUL)
+    {
+	newcmd = alloc((unsigned)(STRLEN(prevcmd) + 2 * STRLEN(p_shq) + 1));
+	if (newcmd == NULL)
+	    return;
+	STRCPY(newcmd, p_shq);
+	STRCAT(newcmd, prevcmd);
+	STRCAT(newcmd, p_shq);
+	free_newcmd = TRUE;
+    }
+    if (addr_count == 0)		/* :! */
+    {
+	/* echo the command */
+	msg_start();
+	msg_putchar(':');
+	msg_putchar('!');
+	msg_outtrans(newcmd);
+	msg_clr_eos();
+	windgoto(msg_row, msg_col);
+
+	do_shell(newcmd, 0);
+    }
+    else				/* :range! */
+    {
+	/* Careful: This may recursively call do_bang() again! (because of
+	 * autocommands) */
+	do_filter(line1, line2, eap, newcmd, do_in, do_out);
+#ifdef FEAT_AUTOCMD
+	apply_autocmds(EVENT_SHELLFILTERPOST, NULL, NULL, FALSE, curbuf);
+#endif
+    }
+    if (free_newcmd)
+	vim_free(newcmd);
+}
+
+/*
+ * do_filter: filter lines through a command given by the user
+ *
+ * We mostly use temp files and the call_shell() routine here. This would
+ * normally be done using pipes on a UNIX machine, but this is more portable
+ * to non-unix machines. The call_shell() routine needs to be able
+ * to deal with redirection somehow, and should handle things like looking
+ * at the PATH env. variable, and adding reasonable extensions to the
+ * command name given by the user. All reasonable versions of call_shell()
+ * do this.
+ * Alternatively, if on Unix and redirecting input or output, but not both,
+ * and the 'shelltemp' option isn't set, use pipes.
+ * We use input redirection if do_in is TRUE.
+ * We use output redirection if do_out is TRUE.
+ */
+    static void
+do_filter(line1, line2, eap, cmd, do_in, do_out)
+    linenr_T	line1, line2;
+    exarg_T	*eap;		/* for forced 'ff' and 'fenc' */
+    char_u	*cmd;
+    int		do_in, do_out;
+{
+    char_u	*itmp = NULL;
+    char_u	*otmp = NULL;
+    linenr_T	linecount;
+    linenr_T	read_linecount;
+    pos_T	cursor_save;
+    char_u	*cmd_buf;
+#ifdef FEAT_AUTOCMD
+    buf_T	*old_curbuf = curbuf;
+#endif
+    int		shell_flags = 0;
+
+    if (*cmd == NUL)	    /* no filter command */
+	return;
+
+#ifdef WIN3264
+    /*
+     * Check if external commands are allowed now.
+     */
+    if (can_end_termcap_mode(TRUE) == FALSE)
+	return;
+#endif
+
+    cursor_save = curwin->w_cursor;
+    linecount = line2 - line1 + 1;
+    curwin->w_cursor.lnum = line1;
+    curwin->w_cursor.col = 0;
+    changed_line_abv_curs();
+    invalidate_botline();
+
+    /*
+     * When using temp files:
+     * 1. * Form temp file names
+     * 2. * Write the lines to a temp file
+     * 3.   Run the filter command on the temp file
+     * 4. * Read the output of the command into the buffer
+     * 5. * Delete the original lines to be filtered
+     * 6. * Remove the temp files
+     *
+     * When writing the input with a pipe or when catching the output with a
+     * pipe only need to do 3.
+     */
+
+    if (do_out)
+	shell_flags |= SHELL_DOOUT;
+
+#if !defined(USE_SYSTEM) && defined(UNIX)
+    if (!do_in && do_out && !p_stmp)
+    {
+	/* Use a pipe to fetch stdout of the command, do not use a temp file. */
+	shell_flags |= SHELL_READ;
+	curwin->w_cursor.lnum = line2;
+    }
+    else if (do_in && !do_out && !p_stmp)
+    {
+	/* Use a pipe to write stdin of the command, do not use a temp file. */
+	shell_flags |= SHELL_WRITE;
+	curbuf->b_op_start.lnum = line1;
+	curbuf->b_op_end.lnum = line2;
+    }
+    else if (do_in && do_out && !p_stmp)
+    {
+	/* Use a pipe to write stdin and fetch stdout of the command, do not
+	 * use a temp file. */
+	shell_flags |= SHELL_READ|SHELL_WRITE;
+	curbuf->b_op_start.lnum = line1;
+	curbuf->b_op_end.lnum = line2;
+	curwin->w_cursor.lnum = line2;
+    }
+    else
+#endif
+	if ((do_in && (itmp = vim_tempname('i')) == NULL)
+		|| (do_out && (otmp = vim_tempname('o')) == NULL))
+	{
+	    EMSG(_(e_notmp));
+	    goto filterend;
+	}
+
+/*
+ * The writing and reading of temp files will not be shown.
+ * Vi also doesn't do this and the messages are not very informative.
+ */
+    ++no_wait_return;		/* don't call wait_return() while busy */
+    if (itmp != NULL && buf_write(curbuf, itmp, NULL, line1, line2, eap,
+					   FALSE, FALSE, FALSE, TRUE) == FAIL)
+    {
+	msg_putchar('\n');		/* keep message from buf_write() */
+	--no_wait_return;
+#if defined(FEAT_AUTOCMD) && defined(FEAT_EVAL)
+	if (!aborting())
+#endif
+	    (void)EMSG2(_(e_notcreate), itmp);	/* will call wait_return */
+	goto filterend;
+    }
+#ifdef FEAT_AUTOCMD
+    if (curbuf != old_curbuf)
+	goto filterend;
+#endif
+
+    if (!do_out)
+	msg_putchar('\n');
+
+    cmd_buf = make_filter_cmd(cmd, itmp, otmp);
+    if (cmd_buf == NULL)
+	goto filterend;
+
+    windgoto((int)Rows - 1, 0);
+    cursor_on();
+
+    /*
+     * When not redirecting the output the command can write anything to the
+     * screen. If 'shellredir' is equal to ">", screen may be messed up by
+     * stderr output of external command. Clear the screen later.
+     * If do_in is FALSE, this could be something like ":r !cat", which may
+     * also mess up the screen, clear it later.
+     */
+    if (!do_out || STRCMP(p_srr, ">") == 0 || !do_in)
+	redraw_later_clear();
+
+    if (do_out)
+    {
+	if (u_save((linenr_T)(line2), (linenr_T)(line2 + 1)) == FAIL)
+	    goto error;
+	redraw_curbuf_later(VALID);
+    }
+    read_linecount = curbuf->b_ml.ml_line_count;
+
+    /*
+     * When call_shell() fails wait_return() is called to give the user a
+     * chance to read the error messages. Otherwise errors are ignored, so you
+     * can see the error messages from the command that appear on stdout; use
+     * 'u' to fix the text
+     * Switch to cooked mode when not redirecting stdin, avoids that something
+     * like ":r !cat" hangs.
+     * Pass on the SHELL_DOOUT flag when the output is being redirected.
+     */
+    if (call_shell(cmd_buf, SHELL_FILTER | SHELL_COOKED | shell_flags))
+    {
+	redraw_later_clear();
+	wait_return(FALSE);
+    }
+    vim_free(cmd_buf);
+
+    did_check_timestamps = FALSE;
+    need_check_timestamps = TRUE;
+
+    /* When interrupting the shell command, it may still have produced some
+     * useful output.  Reset got_int here, so that readfile() won't cancel
+     * reading. */
+    ui_breakcheck();
+    got_int = FALSE;
+
+    if (do_out)
+    {
+	if (otmp != NULL)
+	{
+	    if (readfile(otmp, NULL, line2, (linenr_T)0, (linenr_T)MAXLNUM,
+						    eap, READ_FILTER) == FAIL)
+	    {
+#if defined(FEAT_AUTOCMD) && defined(FEAT_EVAL)
+		if (!aborting())
+#endif
+		{
+		    msg_putchar('\n');
+		    EMSG2(_(e_notread), otmp);
+		}
+		goto error;
+	    }
+#ifdef FEAT_AUTOCMD
+	    if (curbuf != old_curbuf)
+		goto filterend;
+#endif
+	}
+
+	read_linecount = curbuf->b_ml.ml_line_count - read_linecount;
+
+	if (shell_flags & SHELL_READ)
+	{
+	    curbuf->b_op_start.lnum = line2 + 1;
+	    curbuf->b_op_end.lnum = curwin->w_cursor.lnum;
+	    appended_lines_mark(line2, read_linecount);
+	}
+
+	if (do_in)
+	{
+	    if (cmdmod.keepmarks || vim_strchr(p_cpo, CPO_REMMARK) == NULL)
+	    {
+		if (read_linecount >= linecount)
+		    /* move all marks from old lines to new lines */
+		    mark_adjust(line1, line2, linecount, 0L);
+		else
+		{
+		    /* move marks from old lines to new lines, delete marks
+		     * that are in deleted lines */
+		    mark_adjust(line1, line1 + read_linecount - 1,
+								linecount, 0L);
+		    mark_adjust(line1 + read_linecount, line2, MAXLNUM, 0L);
+		}
+	    }
+
+	    /*
+	     * Put cursor on first filtered line for ":range!cmd".
+	     * Adjust '[ and '] (set by buf_write()).
+	     */
+	    curwin->w_cursor.lnum = line1;
+	    del_lines(linecount, TRUE);
+	    curbuf->b_op_start.lnum -= linecount;	/* adjust '[ */
+	    curbuf->b_op_end.lnum -= linecount;		/* adjust '] */
+	    write_lnum_adjust(-linecount);		/* adjust last line
+							   for next write */
+#ifdef FEAT_FOLDING
+	    foldUpdate(curwin, curbuf->b_op_start.lnum, curbuf->b_op_end.lnum);
+#endif
+	}
+	else
+	{
+	    /*
+	     * Put cursor on last new line for ":r !cmd".
+	     */
+	    linecount = curbuf->b_op_end.lnum - curbuf->b_op_start.lnum + 1;
+	    curwin->w_cursor.lnum = curbuf->b_op_end.lnum;
+	}
+
+	beginline(BL_WHITE | BL_FIX);	    /* cursor on first non-blank */
+	--no_wait_return;
+
+	if (linecount > p_report)
+	{
+	    if (do_in)
+	    {
+		vim_snprintf((char *)msg_buf, sizeof(msg_buf),
+				    _("%ld lines filtered"), (long)linecount);
+		if (msg(msg_buf) && !msg_scroll)
+		    /* save message to display it after redraw */
+		    set_keep_msg(msg_buf, 0);
+	    }
+	    else
+		msgmore((long)linecount);
+	}
+    }
+    else
+    {
+error:
+	/* put cursor back in same position for ":w !cmd" */
+	curwin->w_cursor = cursor_save;
+	--no_wait_return;
+	wait_return(FALSE);
+    }
+
+filterend:
+
+#ifdef FEAT_AUTOCMD
+    if (curbuf != old_curbuf)
+    {
+	--no_wait_return;
+	EMSG(_("E135: *Filter* Autocommands must not change current buffer"));
+    }
+#endif
+    if (itmp != NULL)
+	mch_remove(itmp);
+    if (otmp != NULL)
+	mch_remove(otmp);
+    vim_free(itmp);
+    vim_free(otmp);
+}
+
+/*
+ * Call a shell to execute a command.
+ * When "cmd" is NULL start an interactive shell.
+ */
+    void
+do_shell(cmd, flags)
+    char_u	*cmd;
+    int		flags;	/* may be SHELL_DOOUT when output is redirected */
+{
+    buf_T	*buf;
+#ifndef FEAT_GUI_MSWIN
+    int		save_nwr;
+#endif
+#ifdef MSWIN
+    int		winstart = FALSE;
+#endif
+
+    /*
+     * Disallow shell commands for "rvim".
+     * Disallow shell commands from .exrc and .vimrc in current directory for
+     * security reasons.
+     */
+    if (check_restricted() || check_secure())
+    {
+	msg_end();
+	return;
+    }
+
+#ifdef MSWIN
+    /*
+     * Check if external commands are allowed now.
+     */
+    if (can_end_termcap_mode(TRUE) == FALSE)
+	return;
+
+    /*
+     * Check if ":!start" is used.
+     */
+    if (cmd != NULL)
+	winstart = (STRNICMP(cmd, "start ", 6) == 0);
+#endif
+
+    /*
+     * For autocommands we want to get the output on the current screen, to
+     * avoid having to type return below.
+     */
+    msg_putchar('\r');			/* put cursor at start of line */
+#ifdef FEAT_AUTOCMD
+    if (!autocmd_busy)
+#endif
+    {
+#ifdef MSWIN
+	if (!winstart)
+#endif
+	    stoptermcap();
+    }
+#ifdef MSWIN
+    if (!winstart)
+#endif
+	msg_putchar('\n');		/* may shift screen one line up */
+
+    /* warning message before calling the shell */
+    if (p_warn
+#ifdef FEAT_AUTOCMD
+		&& !autocmd_busy
+#endif
+		&& msg_silent == 0)
+	for (buf = firstbuf; buf; buf = buf->b_next)
+	    if (bufIsChanged(buf))
+	    {
+#ifdef FEAT_GUI_MSWIN
+		if (!winstart)
+		    starttermcap();	/* don't want a message box here */
+#endif
+		MSG_PUTS(_("[No write since last change]\n"));
+#ifdef FEAT_GUI_MSWIN
+		if (!winstart)
+		    stoptermcap();
+#endif
+		break;
+	    }
+
+    /* This windgoto is required for when the '\n' resulted in a "delete line
+     * 1" command to the terminal. */
+    if (!swapping_screen())
+	windgoto(msg_row, msg_col);
+    cursor_on();
+    (void)call_shell(cmd, SHELL_COOKED | flags);
+    did_check_timestamps = FALSE;
+    need_check_timestamps = TRUE;
+
+    /*
+     * put the message cursor at the end of the screen, avoids wait_return()
+     * to overwrite the text that the external command showed
+     */
+    if (!swapping_screen())
+    {
+	msg_row = Rows - 1;
+	msg_col = 0;
+    }
+
+#ifdef FEAT_AUTOCMD
+    if (autocmd_busy)
+    {
+	if (msg_silent == 0)
+	    redraw_later_clear();
+    }
+    else
+#endif
+    {
+	/*
+	 * For ":sh" there is no need to call wait_return(), just redraw.
+	 * Also for the Win32 GUI (the output is in a console window).
+	 * Otherwise there is probably text on the screen that the user wants
+	 * to read before redrawing, so call wait_return().
+	 */
+#ifndef FEAT_GUI_MSWIN
+	if (cmd == NULL
+# ifdef WIN3264
+		|| (winstart && !need_wait_return)
+# endif
+	   )
+	{
+	    if (msg_silent == 0)
+		redraw_later_clear();
+	    need_wait_return = FALSE;
+	}
+	else
+	{
+	    /*
+	     * If we switch screens when starttermcap() is called, we really
+	     * want to wait for "hit return to continue".
+	     */
+	    save_nwr = no_wait_return;
+	    if (swapping_screen())
+		no_wait_return = FALSE;
+# ifdef AMIGA
+	    wait_return(term_console ? -1 : msg_silent == 0);	/* see below */
+# else
+	    wait_return(msg_silent == 0);
+# endif
+	    no_wait_return = save_nwr;
+	}
+#endif
+
+#ifdef MSWIN
+	if (!winstart) /* if winstart==TRUE, never stopped termcap! */
+#endif
+	    starttermcap();	/* start termcap if not done by wait_return() */
+
+	/*
+	 * In an Amiga window redrawing is caused by asking the window size.
+	 * If we got an interrupt this will not work. The chance that the
+	 * window size is wrong is very small, but we need to redraw the
+	 * screen.  Don't do this if ':' hit in wait_return().	THIS IS UGLY
+	 * but it saves an extra redraw.
+	 */
+#ifdef AMIGA
+	if (skip_redraw)		/* ':' hit in wait_return() */
+	{
+	    if (msg_silent == 0)
+		redraw_later_clear();
+	}
+	else if (term_console)
+	{
+	    OUT_STR(IF_EB("\033[0 q", ESC_STR "[0 q"));	/* get window size */
+	    if (got_int && msg_silent == 0)
+		redraw_later_clear();	/* if got_int is TRUE, redraw needed */
+	    else
+		must_redraw = 0;	/* no extra redraw needed */
+	}
+#endif
+    }
+
+    /* display any error messages now */
+    display_errors();
+
+#ifdef FEAT_AUTOCMD
+    apply_autocmds(EVENT_SHELLCMDPOST, NULL, NULL, FALSE, curbuf);
+#endif
+}
+
+/*
+ * Create a shell command from a command string, input redirection file and
+ * output redirection file.
+ * Returns an allocated string with the shell command, or NULL for failure.
+ */
+    char_u *
+make_filter_cmd(cmd, itmp, otmp)
+    char_u	*cmd;		/* command */
+    char_u	*itmp;		/* NULL or name of input file */
+    char_u	*otmp;		/* NULL or name of output file */
+{
+    char_u	*buf;
+    long_u	len;
+
+    len = (long_u)STRLEN(cmd) + 3;			/* "()" + NUL */
+    if (itmp != NULL)
+	len += (long_u)STRLEN(itmp) + 9;		/* " { < " + " } " */
+    if (otmp != NULL)
+	len += (long_u)STRLEN(otmp) + (long_u)STRLEN(p_srr) + 2; /* "  " */
+    buf = lalloc(len, TRUE);
+    if (buf == NULL)
+	return NULL;
+
+#if (defined(UNIX) && !defined(ARCHIE)) || defined(OS2)
+    /*
+     * Put braces around the command (for concatenated commands) when
+     * redirecting input and/or output.
+     */
+    if (itmp != NULL || otmp != NULL)
+	sprintf((char *)buf, "(%s)", (char *)cmd);
+    else
+	STRCPY(buf, cmd);
+    if (itmp != NULL)
+    {
+	STRCAT(buf, " < ");
+	STRCAT(buf, itmp);
+    }
+#else
+    /*
+     * for shells that don't understand braces around commands, at least allow
+     * the use of commands in a pipe.
+     */
+    STRCPY(buf, cmd);
+    if (itmp != NULL)
+    {
+	char_u	*p;
+
+	/*
+	 * If there is a pipe, we have to put the '<' in front of it.
+	 * Don't do this when 'shellquote' is not empty, otherwise the
+	 * redirection would be inside the quotes.
+	 */
+	if (*p_shq == NUL)
+	{
+	    p = vim_strchr(buf, '|');
+	    if (p != NULL)
+		*p = NUL;
+	}
+# ifdef RISCOS
+	STRCAT(buf, " { < ");	/* Use RISC OS notation for input. */
+	STRCAT(buf, itmp);
+	STRCAT(buf, " } ");
+# else
+	STRCAT(buf, " <");	/* " < " causes problems on Amiga */
+	STRCAT(buf, itmp);
+# endif
+	if (*p_shq == NUL)
+	{
+	    p = vim_strchr(cmd, '|');
+	    if (p != NULL)
+	    {
+		STRCAT(buf, " ");   /* insert a space before the '|' for DOS */
+		STRCAT(buf, p);
+	    }
+	}
+    }
+#endif
+    if (otmp != NULL)
+	append_redir(buf, p_srr, otmp);
+
+    return buf;
+}
+
+/*
+ * Append output redirection for file "fname" to the end of string buffer "buf"
+ * Works with the 'shellredir' and 'shellpipe' options.
+ * The caller should make sure that there is enough room:
+ *	STRLEN(opt) + STRLEN(fname) + 3
+ */
+    void
+append_redir(buf, opt, fname)
+    char_u	*buf;
+    char_u	*opt;
+    char_u	*fname;
+{
+    char_u	*p;
+
+    buf += STRLEN(buf);
+    /* find "%s", skipping "%%" */
+    for (p = opt; (p = vim_strchr(p, '%')) != NULL; ++p)
+	if (p[1] == 's')
+	    break;
+    if (p != NULL)
+    {
+	*buf = ' '; /* not really needed? Not with sh, ksh or bash */
+	sprintf((char *)buf + 1, (char *)opt, (char *)fname);
+    }
+    else
+	sprintf((char *)buf,
+#ifdef FEAT_QUICKFIX
+# ifndef RISCOS
+		opt != p_sp ? " %s%s" :
+# endif
+		" %s %s",
+#else
+# ifndef RISCOS
+		" %s%s",	/* " > %s" causes problems on Amiga */
+# else
+		" %s %s",	/* But is needed for 'shellpipe' and RISC OS */
+# endif
+#endif
+		(char *)opt, (char *)fname);
+}
+
+#ifdef FEAT_VIMINFO
+
+static int no_viminfo __ARGS((void));
+static int  viminfo_errcnt;
+
+    static int
+no_viminfo()
+{
+    /* "vim -i NONE" does not read or write a viminfo file */
+    return (use_viminfo != NULL && STRCMP(use_viminfo, "NONE") == 0);
+}
+
+/*
+ * Report an error for reading a viminfo file.
+ * Count the number of errors.	When there are more than 10, return TRUE.
+ */
+    int
+viminfo_error(errnum, message, line)
+    char    *errnum;
+    char    *message;
+    char_u  *line;
+{
+    vim_snprintf((char *)IObuff, IOSIZE, _("%sviminfo: %s in line: "),
+							     errnum, message);
+    STRNCAT(IObuff, line, IOSIZE - STRLEN(IObuff));
+    if (IObuff[STRLEN(IObuff) - 1] == '\n')
+	IObuff[STRLEN(IObuff) - 1] = NUL;
+    emsg(IObuff);
+    if (++viminfo_errcnt >= 10)
+    {
+	EMSG(_("E136: viminfo: Too many errors, skipping rest of file"));
+	return TRUE;
+    }
+    return FALSE;
+}
+
+/*
+ * read_viminfo() -- Read the viminfo file.  Registers etc. which are already
+ * set are not over-written unless force is TRUE. -- webb
+ */
+    int
+read_viminfo(file, want_info, want_marks, forceit)
+    char_u	*file;
+    int		want_info;
+    int		want_marks;
+    int		forceit;
+{
+    FILE	*fp;
+    char_u	*fname;
+
+    if (no_viminfo())
+	return FAIL;
+
+    fname = viminfo_filename(file);	    /* may set to default if NULL */
+    if (fname == NULL)
+	return FAIL;
+    fp = mch_fopen((char *)fname, READBIN);
+
+    if (p_verbose > 0)
+    {
+	verbose_enter();
+	smsg((char_u *)_("Reading viminfo file \"%s\"%s%s%s"),
+		fname,
+		want_info ? _(" info") : "",
+		want_marks ? _(" marks") : "",
+		fp == NULL ? _(" FAILED") : "");
+	verbose_leave();
+    }
+
+    vim_free(fname);
+    if (fp == NULL)
+	return FAIL;
+
+    viminfo_errcnt = 0;
+    do_viminfo(fp, NULL, want_info, want_marks, forceit);
+
+    fclose(fp);
+
+    return OK;
+}
+
+/*
+ * write_viminfo() -- Write the viminfo file.  The old one is read in first so
+ * that effectively a merge of current info and old info is done.  This allows
+ * multiple vims to run simultaneously, without losing any marks etc.  If
+ * forceit is TRUE, then the old file is not read in, and only internal info is
+ * written to the file. -- webb
+ */
+    void
+write_viminfo(file, forceit)
+    char_u	*file;
+    int		forceit;
+{
+    char_u	*fname;
+    FILE	*fp_in = NULL;	/* input viminfo file, if any */
+    FILE	*fp_out = NULL;	/* output viminfo file */
+    char_u	*tempname = NULL;	/* name of temp viminfo file */
+    struct stat	st_new;		/* mch_stat() of potential new file */
+    char_u	*wp;
+#if defined(UNIX) || defined(VMS)
+    mode_t	umask_save;
+#endif
+#ifdef UNIX
+    int		shortname = FALSE;	/* use 8.3 file name */
+    struct stat	st_old;		/* mch_stat() of existing viminfo file */
+#endif
+#ifdef WIN3264
+    long	perm = -1;
+#endif
+
+    if (no_viminfo())
+	return;
+
+    fname = viminfo_filename(file);	/* may set to default if NULL */
+    if (fname == NULL)
+	return;
+
+    fp_in = mch_fopen((char *)fname, READBIN);
+    if (fp_in == NULL)
+    {
+	/* if it does exist, but we can't read it, don't try writing */
+	if (mch_stat((char *)fname, &st_new) == 0)
+	    goto end;
+#if defined(UNIX) || defined(VMS)
+	/*
+	 * For Unix we create the .viminfo non-accessible for others,
+	 * because it may contain text from non-accessible documents.
+	 */
+	umask_save = umask(077);
+#endif
+	fp_out = mch_fopen((char *)fname, WRITEBIN);
+#if defined(UNIX) || defined(VMS)
+	(void)umask(umask_save);
+#endif
+    }
+    else
+    {
+	/*
+	 * There is an existing viminfo file.  Create a temporary file to
+	 * write the new viminfo into, in the same directory as the
+	 * existing viminfo file, which will be renamed later.
+	 */
+#ifdef UNIX
+	/*
+	 * For Unix we check the owner of the file.  It's not very nice to
+	 * overwrite a user's viminfo file after a "su root", with a
+	 * viminfo file that the user can't read.
+	 */
+	st_old.st_dev = st_old.st_ino = 0;
+	st_old.st_mode = 0600;
+	if (mch_stat((char *)fname, &st_old) == 0
+		&& getuid() != ROOT_UID
+		&& !(st_old.st_uid == getuid()
+			? (st_old.st_mode & 0200)
+			: (st_old.st_gid == getgid()
+				? (st_old.st_mode & 0020)
+				: (st_old.st_mode & 0002))))
+	{
+	    int	tt = msg_didany;
+
+	    /* avoid a wait_return for this message, it's annoying */
+	    EMSG2(_("E137: Viminfo file is not writable: %s"), fname);
+	    msg_didany = tt;
+	    fclose(fp_in);
+	    goto end;
+	}
+#endif
+#ifdef WIN3264
+	/* Get the file attributes of the existing viminfo file. */
+	perm = mch_getperm(fname);
+#endif
+
+	/*
+	 * Make tempname.
+	 * May try twice: Once normal and once with shortname set, just in
+	 * case somebody puts his viminfo file in an 8.3 filesystem.
+	 */
+	for (;;)
+	{
+	    tempname = buf_modname(
+#ifdef UNIX
+				    shortname,
+#else
+# ifdef SHORT_FNAME
+				    TRUE,
+# else
+#  ifdef FEAT_GUI_W32
+				    gui_is_win32s(),
+#  else
+				    FALSE,
+#  endif
+# endif
+#endif
+				    fname,
+#ifdef VMS
+				    (char_u *)"-tmp",
+#else
+# ifdef RISCOS
+				    (char_u *)"/tmp",
+# else
+				    (char_u *)".tmp",
+# endif
+#endif
+				    FALSE);
+	    if (tempname == NULL)		/* out of memory */
+		break;
+
+	    /*
+	     * Check if tempfile already exists.  Never overwrite an
+	     * existing file!
+	     */
+	    if (mch_stat((char *)tempname, &st_new) == 0)
+	    {
+#ifdef UNIX
+		/*
+		 * Check if tempfile is same as original file.  May happen
+		 * when modname() gave the same file back.  E.g.  silly
+		 * link, or file name-length reached.  Try again with
+		 * shortname set.
+		 */
+		if (!shortname && st_new.st_dev == st_old.st_dev
+					    && st_new.st_ino == st_old.st_ino)
+		{
+		    vim_free(tempname);
+		    tempname = NULL;
+		    shortname = TRUE;
+		    continue;
+		}
+#endif
+		/*
+		 * Try another name.  Change one character, just before
+		 * the extension.  This should also work for an 8.3
+		 * file name, when after adding the extension it still is
+		 * the same file as the original.
+		 */
+		wp = tempname + STRLEN(tempname) - 5;
+		if (wp < gettail(tempname))	    /* empty file name? */
+		    wp = gettail(tempname);
+		for (*wp = 'z'; mch_stat((char *)tempname, &st_new) == 0;
+								    --*wp)
+		{
+		    /*
+		     * They all exist?  Must be something wrong! Don't
+		     * write the viminfo file then.
+		     */
+		    if (*wp == 'a')
+		    {
+			vim_free(tempname);
+			tempname = NULL;
+			break;
+		    }
+		}
+	    }
+	    break;
+	}
+
+	if (tempname != NULL)
+	{
+#ifdef VMS
+	    /* fdopen() fails for some reason */
+	    umask_save = umask(077);
+	    fp_out = mch_fopen((char *)tempname, WRITEBIN);
+	    (void)umask(umask_save);
+#else
+	    int	fd;
+
+	    /* Use mch_open() to be able to use O_NOFOLLOW and set file
+	     * protection:
+	     * Unix: same as original file, but strip s-bit.  Reset umask to
+	     * avoid it getting in the way.
+	     * Others: r&w for user only. */
+# ifdef UNIX
+	    umask_save = umask(0);
+	    fd = mch_open((char *)tempname,
+		    O_CREAT|O_EXTRA|O_EXCL|O_WRONLY|O_NOFOLLOW,
+				       (int)((st_old.st_mode & 0777) | 0600));
+	    (void)umask(umask_save);
+# else
+	    fd = mch_open((char *)tempname,
+			    O_CREAT|O_EXTRA|O_EXCL|O_WRONLY|O_NOFOLLOW, 0600);
+# endif
+	    if (fd < 0)
+		fp_out = NULL;
+	    else
+		fp_out = fdopen(fd, WRITEBIN);
+#endif /* VMS */
+
+	    /*
+	     * If we can't create in the same directory, try creating a
+	     * "normal" temp file.
+	     */
+	    if (fp_out == NULL)
+	    {
+		vim_free(tempname);
+		if ((tempname = vim_tempname('o')) != NULL)
+		    fp_out = mch_fopen((char *)tempname, WRITEBIN);
+	    }
+
+#if defined(UNIX) && defined(HAVE_FCHOWN)
+	    /*
+	     * Make sure the owner can read/write it.  This only works for
+	     * root.
+	     */
+	    if (fp_out != NULL)
+		(void)fchown(fileno(fp_out), st_old.st_uid, st_old.st_gid);
+#endif
+	}
+    }
+
+    /*
+     * Check if the new viminfo file can be written to.
+     */
+    if (fp_out == NULL)
+    {
+	EMSG2(_("E138: Can't write viminfo file %s!"),
+		       (fp_in == NULL || tempname == NULL) ? fname : tempname);
+	if (fp_in != NULL)
+	    fclose(fp_in);
+	goto end;
+    }
+
+    if (p_verbose > 0)
+    {
+	verbose_enter();
+	smsg((char_u *)_("Writing viminfo file \"%s\""), fname);
+	verbose_leave();
+    }
+
+    viminfo_errcnt = 0;
+    do_viminfo(fp_in, fp_out, !forceit, !forceit, FALSE);
+
+    fclose(fp_out);	    /* errors are ignored !? */
+    if (fp_in != NULL)
+    {
+	fclose(fp_in);
+
+	/*
+	 * In case of an error keep the original viminfo file.
+	 * Otherwise rename the newly written file.
+	 */
+	if (viminfo_errcnt || vim_rename(tempname, fname) == -1)
+	    mch_remove(tempname);
+
+#ifdef WIN3264
+	/* If the viminfo file was hidden then also hide the new file. */
+	if (perm > 0 && (perm & FILE_ATTRIBUTE_HIDDEN))
+	    mch_hide(fname);
+#endif
+    }
+
+end:
+    vim_free(fname);
+    vim_free(tempname);
+}
+
+/*
+ * Get the viminfo file name to use.
+ * If "file" is given and not empty, use it (has already been expanded by
+ * cmdline functions).
+ * Otherwise use "-i file_name", value from 'viminfo' or the default, and
+ * expand environment variables.
+ * Returns an allocated string.  NULL when out of memory.
+ */
+    static char_u *
+viminfo_filename(file)
+    char_u	*file;
+{
+    if (file == NULL || *file == NUL)
+    {
+	if (use_viminfo != NULL)
+	    file = use_viminfo;
+	else if ((file = find_viminfo_parameter('n')) == NULL || *file == NUL)
+	{
+#ifdef VIMINFO_FILE2
+	    /* don't use $HOME when not defined (turned into "c:/"!). */
+# ifdef VMS
+	    if (mch_getenv((char_u *)"SYS$LOGIN") == NULL)
+# else
+	    if (mch_getenv((char_u *)"HOME") == NULL)
+# endif
+	    {
+		/* don't use $VIM when not available. */
+		expand_env((char_u *)"$VIM", NameBuff, MAXPATHL);
+		if (STRCMP("$VIM", NameBuff) != 0)  /* $VIM was expanded */
+		    file = (char_u *)VIMINFO_FILE2;
+		else
+		    file = (char_u *)VIMINFO_FILE;
+	    }
+	    else
+#endif
+		file = (char_u *)VIMINFO_FILE;
+	}
+	expand_env(file, NameBuff, MAXPATHL);
+	file = NameBuff;
+    }
+    return vim_strsave(file);
+}
+
+/*
+ * do_viminfo() -- Should only be called from read_viminfo() & write_viminfo().
+ */
+    static void
+do_viminfo(fp_in, fp_out, want_info, want_marks, force_read)
+    FILE	*fp_in;
+    FILE	*fp_out;
+    int		want_info;
+    int		want_marks;
+    int		force_read;
+{
+    int		count = 0;
+    int		eof = FALSE;
+    vir_T	vir;
+
+    if ((vir.vir_line = alloc(LSIZE)) == NULL)
+	return;
+    vir.vir_fd = fp_in;
+#ifdef FEAT_MBYTE
+    vir.vir_conv.vc_type = CONV_NONE;
+#endif
+
+    if (fp_in != NULL)
+    {
+	if (want_info)
+	    eof = read_viminfo_up_to_marks(&vir, force_read, fp_out != NULL);
+	else
+	    /* Skip info, find start of marks */
+	    while (!(eof = viminfo_readline(&vir))
+		    && vir.vir_line[0] != '>')
+		;
+    }
+    if (fp_out != NULL)
+    {
+	/* Write the info: */
+	fprintf(fp_out, _("# This viminfo file was generated by Vim %s.\n"),
+							  VIM_VERSION_MEDIUM);
+	fprintf(fp_out, _("# You may edit it if you're careful!\n\n"));
+#ifdef FEAT_MBYTE
+	fprintf(fp_out, _("# Value of 'encoding' when this file was written\n"));
+	fprintf(fp_out, "*encoding=%s\n\n", p_enc);
+#endif
+	write_viminfo_search_pattern(fp_out);
+	write_viminfo_sub_string(fp_out);
+#ifdef FEAT_CMDHIST
+	write_viminfo_history(fp_out);
+#endif
+	write_viminfo_registers(fp_out);
+#ifdef FEAT_EVAL
+	write_viminfo_varlist(fp_out);
+#endif
+	write_viminfo_filemarks(fp_out);
+	write_viminfo_bufferlist(fp_out);
+	count = write_viminfo_marks(fp_out);
+    }
+    if (fp_in != NULL && want_marks)
+	copy_viminfo_marks(&vir, fp_out, count, eof);
+
+    vim_free(vir.vir_line);
+#ifdef FEAT_MBYTE
+    if (vir.vir_conv.vc_type != CONV_NONE)
+	convert_setup(&vir.vir_conv, NULL, NULL);
+#endif
+}
+
+/*
+ * read_viminfo_up_to_marks() -- Only called from do_viminfo().  Reads in the
+ * first part of the viminfo file which contains everything but the marks that
+ * are local to a file.  Returns TRUE when end-of-file is reached. -- webb
+ */
+    static int
+read_viminfo_up_to_marks(virp, forceit, writing)
+    vir_T	*virp;
+    int		forceit;
+    int		writing;
+{
+    int		eof;
+    buf_T	*buf;
+
+#ifdef FEAT_CMDHIST
+    prepare_viminfo_history(forceit ? 9999 : 0);
+#endif
+    eof = viminfo_readline(virp);
+    while (!eof && virp->vir_line[0] != '>')
+    {
+	switch (virp->vir_line[0])
+	{
+		/* Characters reserved for future expansion, ignored now */
+	    case '+': /* "+40 /path/dir file", for running vim without args */
+	    case '|': /* to be defined */
+	    case '^': /* to be defined */
+	    case '<': /* long line - ignored */
+		/* A comment or empty line. */
+	    case NUL:
+	    case '\r':
+	    case '\n':
+	    case '#':
+		eof = viminfo_readline(virp);
+		break;
+	    case '*': /* "*encoding=value" */
+		eof = viminfo_encoding(virp);
+		break;
+	    case '!': /* global variable */
+#ifdef FEAT_EVAL
+		eof = read_viminfo_varlist(virp, writing);
+#else
+		eof = viminfo_readline(virp);
+#endif
+		break;
+	    case '%': /* entry for buffer list */
+		eof = read_viminfo_bufferlist(virp, writing);
+		break;
+	    case '"':
+		eof = read_viminfo_register(virp, forceit);
+		break;
+	    case '/':	    /* Search string */
+	    case '&':	    /* Substitute search string */
+	    case '~':	    /* Last search string, followed by '/' or '&' */
+		eof = read_viminfo_search_pattern(virp, forceit);
+		break;
+	    case '$':
+		eof = read_viminfo_sub_string(virp, forceit);
+		break;
+	    case ':':
+	    case '?':
+	    case '=':
+	    case '@':
+#ifdef FEAT_CMDHIST
+		eof = read_viminfo_history(virp);
+#else
+		eof = viminfo_readline(virp);
+#endif
+		break;
+	    case '-':
+	    case '\'':
+		eof = read_viminfo_filemark(virp, forceit);
+		break;
+	    default:
+		if (viminfo_error("E575: ", _("Illegal starting char"),
+			    virp->vir_line))
+		    eof = TRUE;
+		else
+		    eof = viminfo_readline(virp);
+		break;
+	}
+    }
+
+#ifdef FEAT_CMDHIST
+    /* Finish reading history items. */
+    finish_viminfo_history();
+#endif
+
+    /* Change file names to buffer numbers for fmarks. */
+    for (buf = firstbuf; buf != NULL; buf = buf->b_next)
+	fmarks_check_names(buf);
+
+    return eof;
+}
+
+/*
+ * Compare the 'encoding' value in the viminfo file with the current value of
+ * 'encoding'.  If different and the 'c' flag is in 'viminfo', setup for
+ * conversion of text with iconv() in viminfo_readstring().
+ */
+    static int
+viminfo_encoding(virp)
+    vir_T	*virp;
+{
+#ifdef FEAT_MBYTE
+    char_u	*p;
+    int		i;
+
+    if (get_viminfo_parameter('c') != 0)
+    {
+	p = vim_strchr(virp->vir_line, '=');
+	if (p != NULL)
+	{
+	    /* remove trailing newline */
+	    ++p;
+	    for (i = 0; vim_isprintc(p[i]); ++i)
+		;
+	    p[i] = NUL;
+
+	    convert_setup(&virp->vir_conv, p, p_enc);
+	}
+    }
+#endif
+    return viminfo_readline(virp);
+}
+
+/*
+ * Read a line from the viminfo file.
+ * Returns TRUE for end-of-file;
+ */
+    int
+viminfo_readline(virp)
+    vir_T	*virp;
+{
+    return vim_fgets(virp->vir_line, LSIZE, virp->vir_fd);
+}
+
+/*
+ * check string read from viminfo file
+ * remove '\n' at the end of the line
+ * - replace CTRL-V CTRL-V with CTRL-V
+ * - replace CTRL-V 'n'    with '\n'
+ *
+ * Check for a long line as written by viminfo_writestring().
+ *
+ * Return the string in allocated memory (NULL when out of memory).
+ */
+/*ARGSUSED*/
+    char_u *
+viminfo_readstring(virp, off, convert)
+    vir_T	*virp;
+    int		off;		    /* offset for virp->vir_line */
+    int		convert;	    /* convert the string */
+{
+    char_u	*retval;
+    char_u	*s, *d;
+    long	len;
+
+    if (virp->vir_line[off] == Ctrl_V && vim_isdigit(virp->vir_line[off + 1]))
+    {
+	len = atol((char *)virp->vir_line + off + 1);
+	retval = lalloc(len, TRUE);
+	if (retval == NULL)
+	{
+	    /* Line too long?  File messed up?  Skip next line. */
+	    (void)vim_fgets(virp->vir_line, 10, virp->vir_fd);
+	    return NULL;
+	}
+	(void)vim_fgets(retval, (int)len, virp->vir_fd);
+	s = retval + 1;	    /* Skip the leading '<' */
+    }
+    else
+    {
+	retval = vim_strsave(virp->vir_line + off);
+	if (retval == NULL)
+	    return NULL;
+	s = retval;
+    }
+
+    /* Change CTRL-V CTRL-V to CTRL-V and CTRL-V n to \n in-place. */
+    d = retval;
+    while (*s != NUL && *s != '\n')
+    {
+	if (s[0] == Ctrl_V && s[1] != NUL)
+	{
+	    if (s[1] == 'n')
+		*d++ = '\n';
+	    else
+		*d++ = Ctrl_V;
+	    s += 2;
+	}
+	else
+	    *d++ = *s++;
+    }
+    *d = NUL;
+
+#ifdef FEAT_MBYTE
+    if (convert && virp->vir_conv.vc_type != CONV_NONE && *retval != NUL)
+    {
+	d = string_convert(&virp->vir_conv, retval, NULL);
+	if (d != NULL)
+	{
+	    vim_free(retval);
+	    retval = d;
+	}
+    }
+#endif
+
+    return retval;
+}
+
+/*
+ * write string to viminfo file
+ * - replace CTRL-V with CTRL-V CTRL-V
+ * - replace '\n'   with CTRL-V 'n'
+ * - add a '\n' at the end
+ *
+ * For a long line:
+ * - write " CTRL-V <length> \n " in first line
+ * - write " < <string> \n "	  in second line
+ */
+    void
+viminfo_writestring(fd, p)
+    FILE	*fd;
+    char_u	*p;
+{
+    int		c;
+    char_u	*s;
+    int		len = 0;
+
+    for (s = p; *s != NUL; ++s)
+    {
+	if (*s == Ctrl_V || *s == '\n')
+	    ++len;
+	++len;
+    }
+
+    /* If the string will be too long, write its length and put it in the next
+     * line.  Take into account that some room is needed for what comes before
+     * the string (e.g., variable name).  Add something to the length for the
+     * '<', NL and trailing NUL. */
+    if (len > LSIZE / 2)
+	fprintf(fd, IF_EB("\026%d\n<", CTRL_V_STR "%d\n<"), len + 3);
+
+    while ((c = *p++) != NUL)
+    {
+	if (c == Ctrl_V || c == '\n')
+	{
+	    putc(Ctrl_V, fd);
+	    if (c == '\n')
+		c = 'n';
+	}
+	putc(c, fd);
+    }
+    putc('\n', fd);
+}
+#endif /* FEAT_VIMINFO */
+
+/*
+ * Implementation of ":fixdel", also used by get_stty().
+ *  <BS>    resulting <Del>
+ *   ^?		^H
+ * not ^?	^?
+ */
+/*ARGSUSED*/
+    void
+do_fixdel(eap)
+    exarg_T	*eap;
+{
+    char_u  *p;
+
+    p = find_termcode((char_u *)"kb");
+    add_termcode((char_u *)"kD", p != NULL
+	    && *p == DEL ? (char_u *)CTRL_H_STR : DEL_STR, FALSE);
+}
+
+    void
+print_line_no_prefix(lnum, use_number, list)
+    linenr_T	lnum;
+    int		use_number;
+    int		list;
+{
+    char_u	numbuf[30];
+
+    if (curwin->w_p_nu || use_number)
+    {
+	sprintf((char *)numbuf, "%*ld ", number_width(curwin), (long)lnum);
+	msg_puts_attr(numbuf, hl_attr(HLF_N));	/* Highlight line nrs */
+    }
+    msg_prt_line(ml_get(lnum), list);
+}
+
+/*
+ * Print a text line.  Also in silent mode ("ex -s").
+ */
+    void
+print_line(lnum, use_number, list)
+    linenr_T	lnum;
+    int		use_number;
+    int		list;
+{
+    int		save_silent = silent_mode;
+
+    msg_start();
+    silent_mode = FALSE;
+    info_message = TRUE;	/* use mch_msg(), not mch_errmsg() */
+    print_line_no_prefix(lnum, use_number, list);
+    if (save_silent)
+    {
+	msg_putchar('\n');
+	cursor_on();		/* msg_start() switches it off */
+	out_flush();
+	silent_mode = save_silent;
+	info_message = FALSE;
+    }
+}
+
+/*
+ * ":file[!] [fname]".
+ */
+    void
+ex_file(eap)
+    exarg_T	*eap;
+{
+    char_u	*fname, *sfname, *xfname;
+    buf_T	*buf;
+
+    /* ":0file" removes the file name.  Check for illegal uses ":3file",
+     * "0file name", etc. */
+    if (eap->addr_count > 0
+	    && (*eap->arg != NUL
+		|| eap->line2 > 0
+		|| eap->addr_count > 1))
+    {
+	EMSG(_(e_invarg));
+	return;
+    }
+
+    if (*eap->arg != NUL || eap->addr_count == 1)
+    {
+#ifdef FEAT_AUTOCMD
+	buf = curbuf;
+	apply_autocmds(EVENT_BUFFILEPRE, NULL, NULL, FALSE, curbuf);
+	/* buffer changed, don't change name now */
+	if (buf != curbuf)
+	    return;
+# ifdef FEAT_EVAL
+	if (aborting())	    /* autocmds may abort script processing */
+	    return;
+# endif
+#endif
+	/*
+	 * The name of the current buffer will be changed.
+	 * A new (unlisted) buffer entry needs to be made to hold the old file
+	 * name, which will become the alternate file name.
+	 * But don't set the alternate file name if the buffer didn't have a
+	 * name.
+	 */
+	fname = curbuf->b_ffname;
+	sfname = curbuf->b_sfname;
+	xfname = curbuf->b_fname;
+	curbuf->b_ffname = NULL;
+	curbuf->b_sfname = NULL;
+	if (setfname(curbuf, eap->arg, NULL, TRUE) == FAIL)
+	{
+	    curbuf->b_ffname = fname;
+	    curbuf->b_sfname = sfname;
+	    return;
+	}
+	curbuf->b_flags |= BF_NOTEDITED;
+	if (xfname != NULL && *xfname != NUL)
+	{
+	    buf = buflist_new(fname, xfname, curwin->w_cursor.lnum, 0);
+	    if (buf != NULL && !cmdmod.keepalt)
+		curwin->w_alt_fnum = buf->b_fnum;
+	}
+	vim_free(fname);
+	vim_free(sfname);
+#ifdef FEAT_AUTOCMD
+	apply_autocmds(EVENT_BUFFILEPOST, NULL, NULL, FALSE, curbuf);
+#endif
+	/* Change directories when the 'acd' option is set. */
+	DO_AUTOCHDIR
+    }
+    /* print full file name if :cd used */
+    fileinfo(FALSE, FALSE, eap->forceit);
+}
+
+/*
+ * ":update".
+ */
+    void
+ex_update(eap)
+    exarg_T	*eap;
+{
+    if (curbufIsChanged())
+	(void)do_write(eap);
+}
+
+/*
+ * ":write" and ":saveas".
+ */
+    void
+ex_write(eap)
+    exarg_T	*eap;
+{
+    if (eap->usefilter)		/* input lines to shell command */
+	do_bang(1, eap, FALSE, TRUE, FALSE);
+    else
+	(void)do_write(eap);
+}
+
+/*
+ * write current buffer to file 'eap->arg'
+ * if 'eap->append' is TRUE, append to the file
+ *
+ * if *eap->arg == NUL write to current file
+ *
+ * return FAIL for failure, OK otherwise
+ */
+    int
+do_write(eap)
+    exarg_T	*eap;
+{
+    int		other;
+    char_u	*fname = NULL;		/* init to shut up gcc */
+    char_u	*ffname;
+    int		retval = FAIL;
+    char_u	*free_fname = NULL;
+#ifdef FEAT_BROWSE
+    char_u	*browse_file = NULL;
+#endif
+    buf_T	*alt_buf = NULL;
+
+    if (not_writing())		/* check 'write' option */
+	return FAIL;
+
+    ffname = eap->arg;
+#ifdef FEAT_BROWSE
+    if (cmdmod.browse)
+    {
+	browse_file = do_browse(BROWSE_SAVE, (char_u *)_("Save As"), ffname,
+						    NULL, NULL, NULL, curbuf);
+	if (browse_file == NULL)
+	    goto theend;
+	ffname = browse_file;
+    }
+#endif
+    if (*ffname == NUL)
+    {
+	if (eap->cmdidx == CMD_saveas)
+	{
+	    EMSG(_(e_argreq));
+	    goto theend;
+	}
+	other = FALSE;
+    }
+    else
+    {
+	fname = ffname;
+	free_fname = fix_fname(ffname);
+	/*
+	 * When out-of-memory, keep unexpanded file name, because we MUST be
+	 * able to write the file in this situation.
+	 */
+	if (free_fname != NULL)
+	    ffname = free_fname;
+	other = otherfile(ffname);
+    }
+
+    /*
+     * If we have a new file, put its name in the list of alternate file names.
+     */
+    if (other)
+    {
+	if (vim_strchr(p_cpo, CPO_ALTWRITE) != NULL
+						 || eap->cmdidx == CMD_saveas)
+	    alt_buf = setaltfname(ffname, fname, (linenr_T)1);
+	else
+	    alt_buf = buflist_findname(ffname);
+	if (alt_buf != NULL && alt_buf->b_ml.ml_mfp != NULL)
+	{
+	    /* Overwriting a file that is loaded in another buffer is not a
+	     * good idea. */
+	    EMSG(_(e_bufloaded));
+	    goto theend;
+	}
+    }
+
+    /*
+     * Writing to the current file is not allowed in readonly mode
+     * and a file name is required.
+     * "nofile" and "nowrite" buffers cannot be written implicitly either.
+     */
+    if (!other && (
+#ifdef FEAT_QUICKFIX
+		bt_dontwrite_msg(curbuf) ||
+#endif
+		check_fname() == FAIL || check_readonly(&eap->forceit, curbuf)))
+	goto theend;
+
+    if (!other)
+    {
+	ffname = curbuf->b_ffname;
+	fname = curbuf->b_fname;
+	/*
+	 * Not writing the whole file is only allowed with '!'.
+	 */
+	if (	   (eap->line1 != 1
+		    || eap->line2 != curbuf->b_ml.ml_line_count)
+		&& !eap->forceit
+		&& !eap->append
+		&& !p_wa)
+	{
+#if defined(FEAT_GUI_DIALOG) || defined(FEAT_CON_DIALOG)
+	    if (p_confirm || cmdmod.confirm)
+	    {
+		if (vim_dialog_yesno(VIM_QUESTION, NULL,
+			       (char_u *)_("Write partial file?"), 2) != VIM_YES)
+		    goto theend;
+		eap->forceit = TRUE;
+	    }
+	    else
+#endif
+	    {
+		EMSG(_("E140: Use ! to write partial buffer"));
+		goto theend;
+	    }
+	}
+    }
+
+    if (check_overwrite(eap, curbuf, fname, ffname, other) == OK)
+    {
+	if (eap->cmdidx == CMD_saveas && alt_buf != NULL)
+	{
+#ifdef FEAT_AUTOCMD
+	    buf_T	*was_curbuf = curbuf;
+
+	    apply_autocmds(EVENT_BUFFILEPRE, NULL, NULL, FALSE, curbuf);
+	    apply_autocmds(EVENT_BUFFILEPRE, NULL, NULL, FALSE, alt_buf);
+# ifdef FEAT_EVAL
+	    if (curbuf != was_curbuf || aborting())
+# else
+	    if (curbuf != was_curbuf)
+# endif
+	    {
+		/* buffer changed, don't change name now */
+		retval = FAIL;
+		goto theend;
+	    }
+#endif
+	    /* Exchange the file names for the current and the alternate
+	     * buffer.  This makes it look like we are now editing the buffer
+	     * under the new name.  Must be done before buf_write(), because
+	     * if there is no file name and 'cpo' contains 'F', it will set
+	     * the file name. */
+	    fname = alt_buf->b_fname;
+	    alt_buf->b_fname = curbuf->b_fname;
+	    curbuf->b_fname = fname;
+	    fname = alt_buf->b_ffname;
+	    alt_buf->b_ffname = curbuf->b_ffname;
+	    curbuf->b_ffname = fname;
+	    fname = alt_buf->b_sfname;
+	    alt_buf->b_sfname = curbuf->b_sfname;
+	    curbuf->b_sfname = fname;
+	    buf_name_changed(curbuf);
+#ifdef FEAT_AUTOCMD
+	    apply_autocmds(EVENT_BUFFILEPOST, NULL, NULL, FALSE, curbuf);
+	    apply_autocmds(EVENT_BUFFILEPOST, NULL, NULL, FALSE, alt_buf);
+	    if (!alt_buf->b_p_bl)
+	    {
+		alt_buf->b_p_bl = TRUE;
+		apply_autocmds(EVENT_BUFADD, NULL, NULL, FALSE, alt_buf);
+	    }
+# ifdef FEAT_EVAL
+	    if (curbuf != was_curbuf || aborting())
+# else
+	    if (curbuf != was_curbuf)
+# endif
+	    {
+		/* buffer changed, don't write the file */
+		retval = FAIL;
+		goto theend;
+	    }
+
+	    /* If 'filetype' was empty try detecting it now. */
+	    if (*curbuf->b_p_ft == NUL)
+	    {
+		if (au_has_group((char_u *)"filetypedetect"))
+		    (void)do_doautocmd((char_u *)"filetypedetect BufRead",
+									TRUE);
+		do_modelines(0);
+	    }
+#endif
+	}
+
+	retval = buf_write(curbuf, ffname, fname, eap->line1, eap->line2,
+				 eap, eap->append, eap->forceit, TRUE, FALSE);
+
+	/* After ":saveas fname" reset 'readonly'. */
+	if (eap->cmdidx == CMD_saveas)
+	{
+	    if (retval == OK)
+		curbuf->b_p_ro = FALSE;
+	    /* Change directories when the 'acd' option is set. */
+	    DO_AUTOCHDIR
+	}
+    }
+
+theend:
+#ifdef FEAT_BROWSE
+    vim_free(browse_file);
+#endif
+    vim_free(free_fname);
+    return retval;
+}
+
+/*
+ * Check if it is allowed to overwrite a file.  If b_flags has BF_NOTEDITED,
+ * BF_NEW or BF_READERR, check for overwriting current file.
+ * May set eap->forceit if a dialog says it's OK to overwrite.
+ * Return OK if it's OK, FAIL if it is not.
+ */
+/*ARGSUSED*/
+    static int
+check_overwrite(eap, buf, fname, ffname, other)
+    exarg_T	*eap;
+    buf_T	*buf;
+    char_u	*fname;	    /* file name to be used (can differ from
+			       buf->ffname) */
+    char_u	*ffname;    /* full path version of fname */
+    int		other;	    /* writing under other name */
+{
+    /*
+     * write to other file or b_flags set or not writing the whole file:
+     * overwriting only allowed with '!'
+     */
+    if (       (other
+		|| (buf->b_flags & BF_NOTEDITED)
+		|| ((buf->b_flags & BF_NEW)
+		    && vim_strchr(p_cpo, CPO_OVERNEW) == NULL)
+		|| (buf->b_flags & BF_READERR))
+	    && !p_wa
+	    && vim_fexists(ffname))
+    {
+	if (!eap->forceit && !eap->append)
+	{
+#ifdef UNIX
+	    /* with UNIX it is possible to open a directory */
+	    if (mch_isdir(ffname))
+	    {
+		EMSG2(_(e_isadir2), ffname);
+		return FAIL;
+	    }
+#endif
+#if defined(FEAT_GUI_DIALOG) || defined(FEAT_CON_DIALOG)
+	    if (p_confirm || cmdmod.confirm)
+	    {
+		char_u	buff[IOSIZE];
+
+		dialog_msg(buff, _("Overwrite existing file \"%s\"?"), fname);
+		if (vim_dialog_yesno(VIM_QUESTION, NULL, buff, 2) != VIM_YES)
+		    return FAIL;
+		eap->forceit = TRUE;
+	    }
+	    else
+#endif
+	    {
+		EMSG(_(e_exists));
+		return FAIL;
+	    }
+	}
+
+	/* For ":w! filename" check that no swap file exists for "filename". */
+	if (other && !emsg_silent)
+	{
+	    char_u	dir[MAXPATHL];
+	    char_u	*p;
+	    int		r;
+	    char_u	*swapname;
+
+	    /* We only try the first entry in 'directory', without checking if
+	     * it's writable.  If the "." directory is not writable the write
+	     * will probably fail anyway.
+	     * Use 'shortname' of the current buffer, since there is no buffer
+	     * for the written file. */
+	    if (*p_dir == NUL)
+		STRCPY(dir, ".");
+	    else
+	    {
+		p = p_dir;
+		copy_option_part(&p, dir, MAXPATHL, ",");
+	    }
+	    swapname = makeswapname(fname, ffname, curbuf, dir);
+	    r = vim_fexists(swapname);
+	    if (r)
+	    {
+#if defined(FEAT_GUI_DIALOG) || defined(FEAT_CON_DIALOG)
+		if (p_confirm || cmdmod.confirm)
+		{
+		    char_u	buff[IOSIZE];
+
+		    dialog_msg(buff,
+			    _("Swap file \"%s\" exists, overwrite anyway?"),
+								    swapname);
+		    if (vim_dialog_yesno(VIM_QUESTION, NULL, buff, 2)
+								   != VIM_YES)
+		    {
+			vim_free(swapname);
+			return FAIL;
+		    }
+		    eap->forceit = TRUE;
+		}
+		else
+#endif
+		{
+		    EMSG2(_("E768: Swap file exists: %s (:silent! overrides)"),
+								    swapname);
+		    vim_free(swapname);
+		    return FAIL;
+		}
+	    }
+	    vim_free(swapname);
+	}
+    }
+    return OK;
+}
+
+/*
+ * Handle ":wnext", ":wNext" and ":wprevious" commands.
+ */
+    void
+ex_wnext(eap)
+    exarg_T	*eap;
+{
+    int		i;
+
+    if (eap->cmd[1] == 'n')
+	i = curwin->w_arg_idx + (int)eap->line2;
+    else
+	i = curwin->w_arg_idx - (int)eap->line2;
+    eap->line1 = 1;
+    eap->line2 = curbuf->b_ml.ml_line_count;
+    if (do_write(eap) != FAIL)
+	do_argfile(eap, i);
+}
+
+/*
+ * ":wall", ":wqall" and ":xall": Write all changed files (and exit).
+ */
+    void
+do_wqall(eap)
+    exarg_T	*eap;
+{
+    buf_T	*buf;
+    int		error = 0;
+    int		save_forceit = eap->forceit;
+
+    if (eap->cmdidx == CMD_xall || eap->cmdidx == CMD_wqall)
+	exiting = TRUE;
+
+    for (buf = firstbuf; buf != NULL; buf = buf->b_next)
+    {
+	if (bufIsChanged(buf))
+	{
+	    /*
+	     * Check if there is a reason the buffer cannot be written:
+	     * 1. if the 'write' option is set
+	     * 2. if there is no file name (even after browsing)
+	     * 3. if the 'readonly' is set (even after a dialog)
+	     * 4. if overwriting is allowed (even after a dialog)
+	     */
+	    if (not_writing())
+	    {
+		++error;
+		break;
+	    }
+#ifdef FEAT_BROWSE
+	    /* ":browse wall": ask for file name if there isn't one */
+	    if (buf->b_ffname == NULL && cmdmod.browse)
+		browse_save_fname(buf);
+#endif
+	    if (buf->b_ffname == NULL)
+	    {
+		EMSGN(_("E141: No file name for buffer %ld"), (long)buf->b_fnum);
+		++error;
+	    }
+	    else if (check_readonly(&eap->forceit, buf)
+		    || check_overwrite(eap, buf, buf->b_fname, buf->b_ffname,
+							       FALSE) == FAIL)
+	    {
+		++error;
+	    }
+	    else
+	    {
+		if (buf_write_all(buf, eap->forceit) == FAIL)
+		    ++error;
+#ifdef FEAT_AUTOCMD
+		/* an autocommand may have deleted the buffer */
+		if (!buf_valid(buf))
+		    buf = firstbuf;
+#endif
+	    }
+	    eap->forceit = save_forceit;    /* check_overwrite() may set it */
+	}
+    }
+    if (exiting)
+    {
+	if (!error)
+	    getout(0);		/* exit Vim */
+	not_exiting();
+    }
+}
+
+/*
+ * Check the 'write' option.
+ * Return TRUE and give a message when it's not st.
+ */
+    int
+not_writing()
+{
+    if (p_write)
+	return FALSE;
+    EMSG(_("E142: File not written: Writing is disabled by 'write' option"));
+    return TRUE;
+}
+
+/*
+ * Check if a buffer is read-only.  Ask for overruling in a dialog.
+ * Return TRUE and give an error message when the buffer is readonly.
+ */
+    static int
+check_readonly(forceit, buf)
+    int		*forceit;
+    buf_T	*buf;
+{
+    if (!*forceit && buf->b_p_ro)
+    {
+#if defined(FEAT_GUI_DIALOG) || defined(FEAT_CON_DIALOG)
+	if ((p_confirm || cmdmod.confirm) && buf->b_fname != NULL)
+	{
+	    char_u	buff[IOSIZE];
+
+	    dialog_msg(buff, _("'readonly' option is set for \"%s\".\nDo you wish to write anyway?"),
+		    buf->b_fname);
+
+	    if (vim_dialog_yesno(VIM_QUESTION, NULL, buff, 2) == VIM_YES)
+	    {
+		/* Set forceit, to force the writing of a readonly file */
+		*forceit = TRUE;
+		return FALSE;
+	    }
+	    else
+		return TRUE;
+	}
+	else
+#endif
+	    EMSG(_(e_readonly));
+	return TRUE;
+    }
+    return FALSE;
+}
+
+/*
+ * Try to abandon current file and edit a new or existing file.
+ * 'fnum' is the number of the file, if zero use ffname/sfname.
+ *
+ * Return 1 for "normal" error, 2 for "not written" error, 0 for success
+ * -1 for succesfully opening another file.
+ * 'lnum' is the line number for the cursor in the new file (if non-zero).
+ */
+    int
+getfile(fnum, ffname, sfname, setpm, lnum, forceit)
+    int		fnum;
+    char_u	*ffname;
+    char_u	*sfname;
+    int		setpm;
+    linenr_T	lnum;
+    int		forceit;
+{
+    int		other;
+    int		retval;
+    char_u	*free_me = NULL;
+
+    if (text_locked())
+	return 1;
+#ifdef FEAT_AUTOCMD
+    if (curbuf_locked())
+	return 1;
+#endif
+
+    if (fnum == 0)
+    {
+					/* make ffname full path, set sfname */
+	fname_expand(curbuf, &ffname, &sfname);
+	other = otherfile(ffname);
+	free_me = ffname;		/* has been allocated, free() later */
+    }
+    else
+	other = (fnum != curbuf->b_fnum);
+
+    if (other)
+	++no_wait_return;	    /* don't wait for autowrite message */
+    if (other && !forceit && curbuf->b_nwindows == 1 && !P_HID(curbuf)
+		   && curbufIsChanged() && autowrite(curbuf, forceit) == FAIL)
+    {
+#if defined(FEAT_GUI_DIALOG) || defined(FEAT_CON_DIALOG)
+	if (p_confirm && p_write)
+	    dialog_changed(curbuf, FALSE);
+	if (curbufIsChanged())
+#endif
+	{
+	    if (other)
+		--no_wait_return;
+	    EMSG(_(e_nowrtmsg));
+	    retval = 2;	/* file has been changed */
+	    goto theend;
+	}
+    }
+    if (other)
+	--no_wait_return;
+    if (setpm)
+	setpcmark();
+    if (!other)
+    {
+	if (lnum != 0)
+	    curwin->w_cursor.lnum = lnum;
+	check_cursor_lnum();
+	beginline(BL_SOL | BL_FIX);
+	retval = 0;	/* it's in the same file */
+    }
+    else if (do_ecmd(fnum, ffname, sfname, NULL, lnum,
+		(P_HID(curbuf) ? ECMD_HIDE : 0) + (forceit ? ECMD_FORCEIT : 0)) == OK)
+	retval = -1;	/* opened another file */
+    else
+	retval = 1;	/* error encountered */
+
+theend:
+    vim_free(free_me);
+    return retval;
+}
+
+/*
+ * start editing a new file
+ *
+ *     fnum: file number; if zero use ffname/sfname
+ *   ffname: the file name
+ *		- full path if sfname used,
+ *		- any file name if sfname is NULL
+ *		- empty string to re-edit with the same file name (but may be
+ *		    in a different directory)
+ *		- NULL to start an empty buffer
+ *   sfname: the short file name (or NULL)
+ *	eap: contains the command to be executed after loading the file and
+ *	     forced 'ff' and 'fenc'
+ *  newlnum: if > 0: put cursor on this line number (if possible)
+ *	     if ECMD_LASTL: use last position in loaded file
+ *	     if ECMD_LAST: use last position in all files
+ *	     if ECMD_ONE: use first line
+ *    flags:
+ *	   ECMD_HIDE: if TRUE don't free the current buffer
+ *     ECMD_SET_HELP: set b_help flag of (new) buffer before opening file
+ *	 ECMD_OLDBUF: use existing buffer if it exists
+ *	ECMD_FORCEIT: ! used for Ex command
+ *	 ECMD_ADDBUF: don't edit, just add to buffer list
+ *
+ * return FAIL for failure, OK otherwise
+ */
+    int
+do_ecmd(fnum, ffname, sfname, eap, newlnum, flags)
+    int		fnum;
+    char_u	*ffname;
+    char_u	*sfname;
+    exarg_T	*eap;			/* can be NULL! */
+    linenr_T	newlnum;
+    int		flags;
+{
+    int		other_file;		/* TRUE if editing another file */
+    int		oldbuf;			/* TRUE if using existing buffer */
+#ifdef FEAT_AUTOCMD
+    int		auto_buf = FALSE;	/* TRUE if autocommands brought us
+					   into the buffer unexpectedly */
+    char_u	*new_name = NULL;
+    int		did_set_swapcommand = FALSE;
+#endif
+    buf_T	*buf;
+#if defined(FEAT_AUTOCMD) || defined(FEAT_GUI_DIALOG) || defined(FEAT_CON_DIALOG)
+    buf_T	*old_curbuf = curbuf;
+#endif
+    char_u	*free_fname = NULL;
+#ifdef FEAT_BROWSE
+    char_u	*browse_file = NULL;
+#endif
+    int		retval = FAIL;
+    long	n;
+    linenr_T	lnum;
+    linenr_T	topline = 0;
+    int		newcol = -1;
+    int		solcol = -1;
+    pos_T	*pos;
+#ifdef FEAT_SUN_WORKSHOP
+    char_u	*cp;
+#endif
+    char_u	*command = NULL;
+#ifdef FEAT_SPELL
+    int		did_get_winopts = FALSE;
+#endif
+
+    if (eap != NULL)
+	command = eap->do_ecmd_cmd;
+
+    if (fnum != 0)
+    {
+	if (fnum == curbuf->b_fnum)	/* file is already being edited */
+	    return OK;			/* nothing to do */
+	other_file = TRUE;
+    }
+    else
+    {
+#ifdef FEAT_BROWSE
+	if (cmdmod.browse)
+	{
+	    if (
+# ifdef FEAT_GUI
+		!gui.in_use &&
+# endif
+		    au_has_group((char_u *)"FileExplorer"))
+	    {
+		/* No browsing supported but we do have the file explorer:
+		 * Edit the directory. */
+		if (ffname == NULL || !mch_isdir(ffname))
+		    ffname = (char_u *)".";
+	    }
+	    else
+	    {
+		browse_file = do_browse(0, (char_u *)_("Edit File"), ffname,
+						    NULL, NULL, NULL, curbuf);
+		if (browse_file == NULL)
+		    goto theend;
+		ffname = browse_file;
+	    }
+	}
+#endif
+	/* if no short name given, use ffname for short name */
+	if (sfname == NULL)
+	    sfname = ffname;
+#ifdef USE_FNAME_CASE
+# ifdef USE_LONG_FNAME
+	if (USE_LONG_FNAME)
+# endif
+	    if (sfname != NULL)
+		fname_case(sfname, 0);   /* set correct case for sfname */
+#endif
+
+#ifdef FEAT_LISTCMDS
+	if ((flags & ECMD_ADDBUF) && (ffname == NULL || *ffname == NUL))
+	    goto theend;
+#endif
+
+	if (ffname == NULL)
+	    other_file = TRUE;
+					    /* there is no file name */
+	else if (*ffname == NUL && curbuf->b_ffname == NULL)
+	    other_file = FALSE;
+	else
+	{
+	    if (*ffname == NUL)		    /* re-edit with same file name */
+	    {
+		ffname = curbuf->b_ffname;
+		sfname = curbuf->b_fname;
+	    }
+	    free_fname = fix_fname(ffname); /* may expand to full path name */
+	    if (free_fname != NULL)
+		ffname = free_fname;
+	    other_file = otherfile(ffname);
+#ifdef FEAT_SUN_WORKSHOP
+	    if (usingSunWorkShop && p_acd
+				   && (cp = vim_strrchr(sfname, '/')) != NULL)
+		sfname = ++cp;
+#endif
+	}
+    }
+
+    /*
+     * if the file was changed we may not be allowed to abandon it
+     * - if we are going to re-edit the same file
+     * - or if we are the only window on this file and if ECMD_HIDE is FALSE
+     */
+    if (  ((!other_file && !(flags & ECMD_OLDBUF))
+	    || (curbuf->b_nwindows == 1
+		&& !(flags & (ECMD_HIDE | ECMD_ADDBUF))))
+	&& check_changed(curbuf, p_awa, !other_file,
+					(flags & ECMD_FORCEIT), FALSE))
+    {
+	if (fnum == 0 && other_file && ffname != NULL)
+	    (void)setaltfname(ffname, sfname, newlnum < 0 ? 0 : newlnum);
+	goto theend;
+    }
+
+#ifdef FEAT_VISUAL
+    /*
+     * End Visual mode before switching to another buffer, so the text can be
+     * copied into the GUI selection buffer.
+     */
+    reset_VIsual();
+#endif
+
+#ifdef FEAT_AUTOCMD
+    if ((command != NULL || newlnum > (linenr_T)0)
+	    && *get_vim_var_str(VV_SWAPCOMMAND) == NUL)
+    {
+	int	len;
+	char_u	*p;
+
+	/* Set v:swapcommand for the SwapExists autocommands. */
+	if (command != NULL)
+	    len = (int)STRLEN(command) + 3;
+	else
+	    len = 30;
+	p = alloc((unsigned)len);
+	if (p != NULL)
+	{
+	    if (command != NULL)
+		vim_snprintf((char *)p, len, ":%s\r", command);
+	    else
+		vim_snprintf((char *)p, len, "%ldG", (long)newlnum);
+	    set_vim_var_string(VV_SWAPCOMMAND, p, -1);
+	    did_set_swapcommand = TRUE;
+	    vim_free(p);
+	}
+    }
+#endif
+
+    /*
+     * If we are starting to edit another file, open a (new) buffer.
+     * Otherwise we re-use the current buffer.
+     */
+    if (other_file)
+    {
+#ifdef FEAT_LISTCMDS
+	if (!(flags & ECMD_ADDBUF))
+#endif
+	{
+	    if (!cmdmod.keepalt)
+		curwin->w_alt_fnum = curbuf->b_fnum;
+	    buflist_altfpos();
+	}
+
+	if (fnum)
+	    buf = buflist_findnr(fnum);
+	else
+	{
+#ifdef FEAT_LISTCMDS
+	    if (flags & ECMD_ADDBUF)
+	    {
+		linenr_T	tlnum = 1L;
+
+		if (command != NULL)
+		{
+		    tlnum = atol((char *)command);
+		    if (tlnum <= 0)
+			tlnum = 1L;
+		}
+		(void)buflist_new(ffname, sfname, tlnum, BLN_LISTED);
+		goto theend;
+	    }
+#endif
+	    buf = buflist_new(ffname, sfname, 0L,
+		    BLN_CURBUF | ((flags & ECMD_SET_HELP) ? 0 : BLN_LISTED));
+	}
+	if (buf == NULL)
+	    goto theend;
+	if (buf->b_ml.ml_mfp == NULL)		/* no memfile yet */
+	{
+	    oldbuf = FALSE;
+	    buf->b_nwindows = 0;
+	}
+	else					/* existing memfile */
+	{
+	    oldbuf = TRUE;
+	    (void)buf_check_timestamp(buf, FALSE);
+	    /* Check if autocommands made buffer invalid or changed the current
+	     * buffer. */
+	    if (!buf_valid(buf)
+#ifdef FEAT_AUTOCMD
+		    || curbuf != old_curbuf
+#endif
+		    )
+		goto theend;
+#ifdef FEAT_EVAL
+	    if (aborting())	    /* autocmds may abort script processing */
+		goto theend;
+#endif
+	}
+
+	/* May jump to last used line number for a loaded buffer or when asked
+	 * for explicitly */
+	if ((oldbuf && newlnum == ECMD_LASTL) || newlnum == ECMD_LAST)
+	{
+	    pos = buflist_findfpos(buf);
+	    newlnum = pos->lnum;
+	    solcol = pos->col;
+	}
+
+	/*
+	 * Make the (new) buffer the one used by the current window.
+	 * If the old buffer becomes unused, free it if ECMD_HIDE is FALSE.
+	 * If the current buffer was empty and has no file name, curbuf
+	 * is returned by buflist_new().
+	 */
+	if (buf != curbuf)
+	{
+#ifdef FEAT_AUTOCMD
+	    /*
+	     * Be careful: The autocommands may delete any buffer and change
+	     * the current buffer.
+	     * - If the buffer we are going to edit is deleted, give up.
+	     * - If the current buffer is deleted, prefer to load the new
+	     *   buffer when loading a buffer is required.  This avoids
+	     *   loading another buffer which then must be closed again.
+	     * - If we ended up in the new buffer already, need to skip a few
+	     *	 things, set auto_buf.
+	     */
+	    if (buf->b_fname != NULL)
+		new_name = vim_strsave(buf->b_fname);
+	    au_new_curbuf = buf;
+	    apply_autocmds(EVENT_BUFLEAVE, NULL, NULL, FALSE, curbuf);
+	    if (!buf_valid(buf))	/* new buffer has been deleted */
+	    {
+		delbuf_msg(new_name);	/* frees new_name */
+		goto theend;
+	    }
+# ifdef FEAT_EVAL
+	    if (aborting())	    /* autocmds may abort script processing */
+	    {
+		vim_free(new_name);
+		goto theend;
+	    }
+# endif
+	    if (buf == curbuf)		/* already in new buffer */
+		auto_buf = TRUE;
+	    else
+	    {
+		if (curbuf == old_curbuf)
+#endif
+		    buf_copy_options(buf, BCO_ENTER);
+
+		/* close the link to the current buffer */
+		u_sync(FALSE);
+		close_buffer(curwin, curbuf,
+				      (flags & ECMD_HIDE) ? 0 : DOBUF_UNLOAD);
+
+#ifdef FEAT_AUTOCMD
+# ifdef FEAT_EVAL
+		if (aborting())	    /* autocmds may abort script processing */
+		{
+		    vim_free(new_name);
+		    goto theend;
+		}
+# endif
+		/* Be careful again, like above. */
+		if (!buf_valid(buf))	/* new buffer has been deleted */
+		{
+		    delbuf_msg(new_name);	/* frees new_name */
+		    goto theend;
+		}
+		if (buf == curbuf)		/* already in new buffer */
+		    auto_buf = TRUE;
+		else
+#endif
+		{
+		    curwin->w_buffer = buf;
+		    curbuf = buf;
+		    ++curbuf->b_nwindows;
+		    /* set 'fileformat' */
+		    if (*p_ffs && !oldbuf)
+			set_fileformat(default_fileformat(), OPT_LOCAL);
+		}
+
+		/* May get the window options from the last time this buffer
+		 * was in this window (or another window).  If not used
+		 * before, reset the local window options to the global
+		 * values.  Also restores old folding stuff. */
+		get_winopts(buf);
+#ifdef FEAT_SPELL
+		did_get_winopts = TRUE;
+#endif
+
+#ifdef FEAT_AUTOCMD
+	    }
+	    vim_free(new_name);
+	    au_new_curbuf = NULL;
+#endif
+	}
+	else
+	    ++curbuf->b_nwindows;
+
+	curwin->w_pcmark.lnum = 1;
+	curwin->w_pcmark.col = 0;
+    }
+    else /* !other_file */
+    {
+	if (
+#ifdef FEAT_LISTCMDS
+		(flags & ECMD_ADDBUF) ||
+#endif
+		check_fname() == FAIL)
+	    goto theend;
+	oldbuf = (flags & ECMD_OLDBUF);
+    }
+
+    if ((flags & ECMD_SET_HELP) || keep_help_flag)
+    {
+	char_u	*p;
+
+	curbuf->b_help = TRUE;
+#ifdef FEAT_QUICKFIX
+	set_string_option_direct((char_u *)"buftype", -1,
+				     (char_u *)"help", OPT_FREE|OPT_LOCAL, 0);
+#endif
+
+	/*
+	 * Always set these options after jumping to a help tag, because the
+	 * user may have an autocommand that gets in the way.
+	 * Accept all ASCII chars for keywords, except ' ', '*', '"', '|', and
+	 * latin1 word characters (for translated help files).
+	 * Only set it when needed, buf_init_chartab() is some work.
+	 */
+	p =
+#ifdef EBCDIC
+		(char_u *)"65-255,^*,^|,^\"";
+#else
+		(char_u *)"!-~,^*,^|,^\",192-255";
+#endif
+	if (STRCMP(curbuf->b_p_isk, p) != 0)
+	{
+	    set_string_option_direct((char_u *)"isk", -1, p,
+						       OPT_FREE|OPT_LOCAL, 0);
+	    check_buf_options(curbuf);
+	    (void)buf_init_chartab(curbuf, FALSE);
+	}
+
+	curbuf->b_p_ts = 8;		/* 'tabstop' is 8 */
+	curwin->w_p_list = FALSE;	/* no list mode */
+
+	curbuf->b_p_ma = FALSE;		/* not modifiable */
+	curbuf->b_p_bin = FALSE;	/* reset 'bin' before reading file */
+	curwin->w_p_nu = 0;		/* no line numbers */
+#ifdef FEAT_SCROLLBIND
+	curwin->w_p_scb = FALSE;	/* no scroll binding */
+#endif
+#ifdef FEAT_ARABIC
+	curwin->w_p_arab = FALSE;	/* no arabic mode */
+#endif
+#ifdef FEAT_RIGHTLEFT
+	curwin->w_p_rl  = FALSE;	/* help window is left-to-right */
+#endif
+#ifdef FEAT_FOLDING
+	curwin->w_p_fen = FALSE;	/* No folding in the help window */
+#endif
+#ifdef FEAT_DIFF
+	curwin->w_p_diff = FALSE;	/* No 'diff' */
+#endif
+#ifdef FEAT_SPELL
+	curwin->w_p_spell = FALSE;	/* No spell checking */
+#endif
+
+#ifdef FEAT_AUTOCMD
+	buf = curbuf;
+#endif
+	set_buflisted(FALSE);
+    }
+    else
+    {
+#ifdef FEAT_AUTOCMD
+	buf = curbuf;
+#endif
+	/* Don't make a buffer listed if it's a help buffer.  Useful when
+	 * using CTRL-O to go back to a help file. */
+	if (!curbuf->b_help)
+	    set_buflisted(TRUE);
+    }
+
+#ifdef FEAT_AUTOCMD
+    /* If autocommands change buffers under our fingers, forget about
+     * editing the file. */
+    if (buf != curbuf)
+	goto theend;
+# ifdef FEAT_EVAL
+    if (aborting())	    /* autocmds may abort script processing */
+	goto theend;
+# endif
+
+    /* Since we are starting to edit a file, consider the filetype to be
+     * unset.  Helps for when an autocommand changes files and expects syntax
+     * highlighting to work in the other file. */
+    did_filetype = FALSE;
+#endif
+
+/*
+ * other_file	oldbuf
+ *  FALSE	FALSE	    re-edit same file, buffer is re-used
+ *  FALSE	TRUE	    re-edit same file, nothing changes
+ *  TRUE	FALSE	    start editing new file, new buffer
+ *  TRUE	TRUE	    start editing in existing buffer (nothing to do)
+ */
+    if (!other_file && !oldbuf)		/* re-use the buffer */
+    {
+	set_last_cursor(curwin);	/* may set b_last_cursor */
+	if (newlnum == ECMD_LAST || newlnum == ECMD_LASTL)
+	{
+	    newlnum = curwin->w_cursor.lnum;
+	    solcol = curwin->w_cursor.col;
+	}
+#ifdef FEAT_AUTOCMD
+	buf = curbuf;
+	if (buf->b_fname != NULL)
+	    new_name = vim_strsave(buf->b_fname);
+	else
+	    new_name = NULL;
+#endif
+	buf_freeall(curbuf, FALSE, FALSE);   /* free all things for buffer */
+#ifdef FEAT_AUTOCMD
+	/* If autocommands deleted the buffer we were going to re-edit, give
+	 * up and jump to the end. */
+	if (!buf_valid(buf))
+	{
+	    delbuf_msg(new_name);	/* frees new_name */
+	    goto theend;
+	}
+	vim_free(new_name);
+
+	/* If autocommands change buffers under our fingers, forget about
+	 * re-editing the file.  Should do the buf_clear_file(), but perhaps
+	 * the autocommands changed the buffer... */
+	if (buf != curbuf)
+	    goto theend;
+# ifdef FEAT_EVAL
+	if (aborting())	    /* autocmds may abort script processing */
+	    goto theend;
+# endif
+#endif
+	buf_clear_file(curbuf);
+	curbuf->b_op_start.lnum = 0;	/* clear '[ and '] marks */
+	curbuf->b_op_end.lnum = 0;
+    }
+
+/*
+ * If we get here we are sure to start editing
+ */
+    /* don't redraw until the cursor is in the right line */
+    ++RedrawingDisabled;
+
+    /* Assume success now */
+    retval = OK;
+
+    /*
+     * Reset cursor position, could be used by autocommands.
+     */
+    check_cursor();
+
+    /*
+     * Check if we are editing the w_arg_idx file in the argument list.
+     */
+    check_arg_idx(curwin);
+
+#ifdef FEAT_AUTOCMD
+    if (!auto_buf)
+#endif
+    {
+	/*
+	 * Set cursor and init window before reading the file and executing
+	 * autocommands.  This allows for the autocommands to position the
+	 * cursor.
+	 */
+	curwin_init();
+
+#ifdef FEAT_FOLDING
+	/* It's like all lines in the buffer changed.  Need to update
+	 * automatic folding. */
+	foldUpdateAll(curwin);
+#endif
+
+	/* Change directories when the 'acd' option is set. */
+	DO_AUTOCHDIR
+
+	/*
+	 * Careful: open_buffer() and apply_autocmds() may change the current
+	 * buffer and window.
+	 */
+	lnum = curwin->w_cursor.lnum;
+	topline = curwin->w_topline;
+	if (!oldbuf)			    /* need to read the file */
+	{
+#if defined(HAS_SWAP_EXISTS_ACTION)
+	    swap_exists_action = SEA_DIALOG;
+#endif
+	    curbuf->b_flags |= BF_CHECK_RO; /* set/reset 'ro' flag */
+
+	    /*
+	     * Open the buffer and read the file.
+	     */
+#if defined(FEAT_AUTOCMD) && defined(FEAT_EVAL)
+	    if (should_abort(open_buffer(FALSE, eap)))
+		retval = FAIL;
+#else
+	    (void)open_buffer(FALSE, eap);
+#endif
+
+#if defined(HAS_SWAP_EXISTS_ACTION)
+	    if (swap_exists_action == SEA_QUIT)
+		retval = FAIL;
+	    handle_swap_exists(old_curbuf);
+#endif
+	}
+#ifdef FEAT_AUTOCMD
+	else
+	{
+	    /* Read the modelines, but only to set window-local options.  Any
+	     * buffer-local options have already been set and may have been
+	     * changed by the user. */
+	    do_modelines(OPT_WINONLY);
+
+	    apply_autocmds_retval(EVENT_BUFENTER, NULL, NULL, FALSE, curbuf,
+								    &retval);
+	    apply_autocmds_retval(EVENT_BUFWINENTER, NULL, NULL, FALSE, curbuf,
+								    &retval);
+	}
+	check_arg_idx(curwin);
+#endif
+
+	/*
+	 * If autocommands change the cursor position or topline, we should
+	 * keep it.
+	 */
+	if (curwin->w_cursor.lnum != lnum)
+	{
+	    newlnum = curwin->w_cursor.lnum;
+	    newcol = curwin->w_cursor.col;
+	}
+	if (curwin->w_topline == topline)
+	    topline = 0;
+
+	/* Even when cursor didn't move we need to recompute topline. */
+	changed_line_abv_curs();
+
+#ifdef FEAT_TITLE
+	maketitle();
+#endif
+    }
+
+#ifdef FEAT_DIFF
+    /* Tell the diff stuff that this buffer is new and/or needs updating.
+     * Also needed when re-editing the same buffer, because unloading will
+     * have removed it as a diff buffer. */
+    if (curwin->w_p_diff)
+    {
+	diff_buf_add(curbuf);
+	diff_invalidate(curbuf);
+    }
+#endif
+
+#ifdef FEAT_SPELL
+    /* If the window options were changed may need to set the spell language.
+     * Can only do this after the buffer has been properly setup. */
+    if (did_get_winopts && curwin->w_p_spell && *buf->b_p_spl != NUL)
+	did_set_spelllang(buf);
+#endif
+
+    if (command == NULL)
+    {
+	if (newcol >= 0)	/* position set by autocommands */
+	{
+	    curwin->w_cursor.lnum = newlnum;
+	    curwin->w_cursor.col = newcol;
+	    check_cursor();
+	}
+	else if (newlnum > 0)	/* line number from caller or old position */
+	{
+	    curwin->w_cursor.lnum = newlnum;
+	    check_cursor_lnum();
+	    if (solcol >= 0 && !p_sol)
+	    {
+		/* 'sol' is off: Use last known column. */
+		curwin->w_cursor.col = solcol;
+		check_cursor_col();
+#ifdef FEAT_VIRTUALEDIT
+		curwin->w_cursor.coladd = 0;
+#endif
+		curwin->w_set_curswant = TRUE;
+	    }
+	    else
+		beginline(BL_SOL | BL_FIX);
+	}
+	else			/* no line number, go to last line in Ex mode */
+	{
+	    if (exmode_active)
+		curwin->w_cursor.lnum = curbuf->b_ml.ml_line_count;
+	    beginline(BL_WHITE | BL_FIX);
+	}
+    }
+
+#ifdef FEAT_WINDOWS
+    /* Check if cursors in other windows on the same buffer are still valid */
+    check_lnums(FALSE);
+#endif
+
+    /*
+     * Did not read the file, need to show some info about the file.
+     * Do this after setting the cursor.
+     */
+    if (oldbuf
+#ifdef FEAT_AUTOCMD
+		&& !auto_buf
+#endif
+			    )
+    {
+	int	msg_scroll_save = msg_scroll;
+
+	/* Obey the 'O' flag in 'cpoptions': overwrite any previous file
+	 * message. */
+	if (shortmess(SHM_OVERALL) && !exiting && p_verbose == 0)
+	    msg_scroll = FALSE;
+	if (!msg_scroll)	/* wait a bit when overwriting an error msg */
+	    check_for_delay(FALSE);
+	msg_start();
+	msg_scroll = msg_scroll_save;
+	msg_scrolled_ign = TRUE;
+
+	fileinfo(FALSE, TRUE, FALSE);
+
+	msg_scrolled_ign = FALSE;
+    }
+
+    if (command != NULL)
+	do_cmdline(command, NULL, NULL, DOCMD_VERBOSE);
+
+#ifdef FEAT_KEYMAP
+    if (curbuf->b_kmap_state & KEYMAP_INIT)
+	keymap_init();
+#endif
+
+    --RedrawingDisabled;
+    if (!skip_redraw)
+    {
+	n = p_so;
+	if (topline == 0 && command == NULL)
+	    p_so = 999;			/* force cursor halfway the window */
+	update_topline();
+#ifdef FEAT_SCROLLBIND
+	curwin->w_scbind_pos = curwin->w_topline;
+#endif
+	p_so = n;
+	redraw_curbuf_later(NOT_VALID);	/* redraw this buffer later */
+    }
+
+    if (p_im)
+	need_start_insertmode = TRUE;
+
+    /* Change directories when the 'acd' option is set. */
+    DO_AUTOCHDIR
+
+#if defined(FEAT_SUN_WORKSHOP) || defined(FEAT_NETBEANS_INTG)
+    if (gui.in_use && curbuf->b_ffname != NULL)
+    {
+# ifdef FEAT_SUN_WORKSHOP
+	if (usingSunWorkShop)
+	    workshop_file_opened((char *)curbuf->b_ffname, curbuf->b_p_ro);
+# endif
+# ifdef FEAT_NETBEANS_INTG
+	if (usingNetbeans & ((flags & ECMD_SET_HELP) != ECMD_SET_HELP))
+	    netbeans_file_opened(curbuf);
+# endif
+    }
+#endif
+
+theend:
+#ifdef FEAT_AUTOCMD
+    if (did_set_swapcommand)
+	set_vim_var_string(VV_SWAPCOMMAND, NULL, -1);
+#endif
+#ifdef FEAT_BROWSE
+    vim_free(browse_file);
+#endif
+    vim_free(free_fname);
+    return retval;
+}
+
+#ifdef FEAT_AUTOCMD
+    static void
+delbuf_msg(name)
+    char_u	*name;
+{
+    EMSG2(_("E143: Autocommands unexpectedly deleted new buffer %s"),
+	    name == NULL ? (char_u *)"" : name);
+    vim_free(name);
+    au_new_curbuf = NULL;
+}
+#endif
+
+static int append_indent = 0;	    /* autoindent for first line */
+
+/*
+ * ":insert" and ":append", also used by ":change"
+ */
+    void
+ex_append(eap)
+    exarg_T	*eap;
+{
+    char_u	*theline;
+    int		did_undo = FALSE;
+    linenr_T	lnum = eap->line2;
+    int		indent = 0;
+    char_u	*p;
+    int		vcol;
+    int		empty = (curbuf->b_ml.ml_flags & ML_EMPTY);
+
+    /* the ! flag toggles autoindent */
+    if (eap->forceit)
+	curbuf->b_p_ai = !curbuf->b_p_ai;
+
+    /* First autoindent comes from the line we start on */
+    if (eap->cmdidx != CMD_change && curbuf->b_p_ai && lnum > 0)
+	append_indent = get_indent_lnum(lnum);
+
+    if (eap->cmdidx != CMD_append)
+	--lnum;
+
+    /* when the buffer is empty append to line 0 and delete the dummy line */
+    if (empty && lnum == 1)
+	lnum = 0;
+
+    State = INSERT;		    /* behave like in Insert mode */
+    if (curbuf->b_p_iminsert == B_IMODE_LMAP)
+	State |= LANGMAP;
+
+    for (;;)
+    {
+	msg_scroll = TRUE;
+	need_wait_return = FALSE;
+	if (curbuf->b_p_ai)
+	{
+	    if (append_indent >= 0)
+	    {
+		indent = append_indent;
+		append_indent = -1;
+	    }
+	    else if (lnum > 0)
+		indent = get_indent_lnum(lnum);
+	}
+	ex_keep_indent = FALSE;
+	if (eap->getline == NULL)
+	{
+	    /* No getline() function, use the lines that follow. This ends
+	     * when there is no more. */
+	    if (eap->nextcmd == NULL || *eap->nextcmd == NUL)
+		break;
+	    p = vim_strchr(eap->nextcmd, NL);
+	    if (p == NULL)
+		p = eap->nextcmd + STRLEN(eap->nextcmd);
+	    theline = vim_strnsave(eap->nextcmd, (int)(p - eap->nextcmd));
+	    if (*p != NUL)
+		++p;
+	    eap->nextcmd = p;
+	}
+	else
+	    theline = eap->getline(
+#ifdef FEAT_EVAL
+		    eap->cstack->cs_looplevel > 0 ? -1 :
+#endif
+		    NUL, eap->cookie, indent);
+	lines_left = Rows - 1;
+	if (theline == NULL)
+	    break;
+
+	/* Using ^ CTRL-D in getexmodeline() makes us repeat the indent. */
+	if (ex_keep_indent)
+	    append_indent = indent;
+
+	/* Look for the "." after automatic indent. */
+	vcol = 0;
+	for (p = theline; indent > vcol; ++p)
+	{
+	    if (*p == ' ')
+		++vcol;
+	    else if (*p == TAB)
+		vcol += 8 - vcol % 8;
+	    else
+		break;
+	}
+	if ((p[0] == '.' && p[1] == NUL)
+		|| (!did_undo && u_save(lnum, lnum + 1 + (empty ? 1 : 0))
+								     == FAIL))
+	{
+	    vim_free(theline);
+	    break;
+	}
+
+	/* don't use autoindent if nothing was typed. */
+	if (p[0] == NUL)
+	    theline[0] = NUL;
+
+	did_undo = TRUE;
+	ml_append(lnum, theline, (colnr_T)0, FALSE);
+	appended_lines_mark(lnum, 1L);
+
+	vim_free(theline);
+	++lnum;
+
+	if (empty)
+	{
+	    ml_delete(2L, FALSE);
+	    empty = FALSE;
+	}
+    }
+    State = NORMAL;
+
+    if (eap->forceit)
+	curbuf->b_p_ai = !curbuf->b_p_ai;
+
+    /* "start" is set to eap->line2+1 unless that position is invalid (when
+     * eap->line2 pointed to the end of the buffer and nothing was appended)
+     * "end" is set to lnum when something has been appended, otherwise
+     * it is the same than "start"  -- Acevedo */
+    curbuf->b_op_start.lnum = (eap->line2 < curbuf->b_ml.ml_line_count) ?
+	eap->line2 + 1 : curbuf->b_ml.ml_line_count;
+    if (eap->cmdidx != CMD_append)
+	--curbuf->b_op_start.lnum;
+    curbuf->b_op_end.lnum = (eap->line2 < lnum)
+					     ? lnum : curbuf->b_op_start.lnum;
+    curbuf->b_op_start.col = curbuf->b_op_end.col = 0;
+    curwin->w_cursor.lnum = lnum;
+    check_cursor_lnum();
+    beginline(BL_SOL | BL_FIX);
+
+    need_wait_return = FALSE;	/* don't use wait_return() now */
+    ex_no_reprint = TRUE;
+}
+
+/*
+ * ":change"
+ */
+    void
+ex_change(eap)
+    exarg_T	*eap;
+{
+    linenr_T	lnum;
+
+    if (eap->line2 >= eap->line1
+	    && u_save(eap->line1 - 1, eap->line2 + 1) == FAIL)
+	return;
+
+    /* the ! flag toggles autoindent */
+    if (eap->forceit ? !curbuf->b_p_ai : curbuf->b_p_ai)
+	append_indent = get_indent_lnum(eap->line1);
+
+    for (lnum = eap->line2; lnum >= eap->line1; --lnum)
+    {
+	if (curbuf->b_ml.ml_flags & ML_EMPTY)	    /* nothing to delete */
+	    break;
+	ml_delete(eap->line1, FALSE);
+    }
+    deleted_lines_mark(eap->line1, (long)(eap->line2 - lnum));
+
+    /* ":append" on the line above the deleted lines. */
+    eap->line2 = eap->line1;
+    ex_append(eap);
+}
+
+    void
+ex_z(eap)
+    exarg_T	*eap;
+{
+    char_u	*x;
+    int		bigness;
+    char_u	*kind;
+    int		minus = 0;
+    linenr_T	start, end, curs, i;
+    int		j;
+    linenr_T	lnum = eap->line2;
+
+    /* Vi compatible: ":z!" uses display height, without a count uses
+     * 'scroll' */
+    if (eap->forceit)
+	bigness = curwin->w_height;
+    else if (firstwin == lastwin)
+	bigness = curwin->w_p_scr * 2;
+    else
+	bigness = curwin->w_height - 3;
+    if (bigness < 1)
+	bigness = 1;
+
+    x = eap->arg;
+    kind = x;
+    if (*kind == '-' || *kind == '+' || *kind == '='
+					      || *kind == '^' || *kind == '.')
+	++x;
+    while (*x == '-' || *x == '+')
+	++x;
+
+    if (*x != 0)
+    {
+	if (!VIM_ISDIGIT(*x))
+	{
+	    EMSG(_("E144: non-numeric argument to :z"));
+	    return;
+	}
+	else
+	{
+	    bigness = atoi((char *)x);
+	    p_window = bigness;
+	    if (*kind == '=')
+		bigness += 2;
+	}
+    }
+
+    /* the number of '-' and '+' multiplies the distance */
+    if (*kind == '-' || *kind == '+')
+	for (x = kind + 1; *x == *kind; ++x)
+	    ;
+
+    switch (*kind)
+    {
+	case '-':
+	    start = lnum - bigness * (linenr_T)(x - kind);
+	    end = start + bigness;
+	    curs = end;
+	    break;
+
+	case '=':
+	    start = lnum - (bigness + 1) / 2 + 1;
+	    end = lnum + (bigness + 1) / 2 - 1;
+	    curs = lnum;
+	    minus = 1;
+	    break;
+
+	case '^':
+	    start = lnum - bigness * 2;
+	    end = lnum - bigness;
+	    curs = lnum - bigness;
+	    break;
+
+	case '.':
+	    start = lnum - (bigness + 1) / 2 + 1;
+	    end = lnum + (bigness + 1) / 2 - 1;
+	    curs = end;
+	    break;
+
+	default:  /* '+' */
+	    start = lnum;
+	    if (*kind == '+')
+		start += bigness * (linenr_T)(x - kind - 1) + 1;
+	    else if (eap->addr_count == 0)
+		++start;
+	    end = start + bigness - 1;
+	    curs = end;
+	    break;
+    }
+
+    if (start < 1)
+	start = 1;
+
+    if (end > curbuf->b_ml.ml_line_count)
+	end = curbuf->b_ml.ml_line_count;
+
+    if (curs > curbuf->b_ml.ml_line_count)
+	curs = curbuf->b_ml.ml_line_count;
+
+    for (i = start; i <= end; i++)
+    {
+	if (minus && i == lnum)
+	{
+	    msg_putchar('\n');
+
+	    for (j = 1; j < Columns; j++)
+		msg_putchar('-');
+	}
+
+	print_line(i, eap->flags & EXFLAG_NR, eap->flags & EXFLAG_LIST);
+
+	if (minus && i == lnum)
+	{
+	    msg_putchar('\n');
+
+	    for (j = 1; j < Columns; j++)
+		msg_putchar('-');
+	}
+    }
+
+    curwin->w_cursor.lnum = curs;
+    ex_no_reprint = TRUE;
+}
+
+/*
+ * Check if the restricted flag is set.
+ * If so, give an error message and return TRUE.
+ * Otherwise, return FALSE.
+ */
+    int
+check_restricted()
+{
+    if (restricted)
+    {
+	EMSG(_("E145: Shell commands not allowed in rvim"));
+	return TRUE;
+    }
+    return FALSE;
+}
+
+/*
+ * Check if the secure flag is set (.exrc or .vimrc in current directory).
+ * If so, give an error message and return TRUE.
+ * Otherwise, return FALSE.
+ */
+    int
+check_secure()
+{
+    if (secure)
+    {
+	secure = 2;
+	EMSG(_(e_curdir));
+	return TRUE;
+    }
+#ifdef HAVE_SANDBOX
+    /*
+     * In the sandbox more things are not allowed, including the things
+     * disallowed in secure mode.
+     */
+    if (sandbox != 0)
+    {
+	EMSG(_(e_sandbox));
+	return TRUE;
+    }
+#endif
+    return FALSE;
+}
+
+static char_u	*old_sub = NULL;	/* previous substitute pattern */
+static int	global_need_beginline;	/* call beginline() after ":g" */
+
+/* do_sub()
+ *
+ * Perform a substitution from line eap->line1 to line eap->line2 using the
+ * command pointed to by eap->arg which should be of the form:
+ *
+ * /pattern/substitution/{flags}
+ *
+ * The usual escapes are supported as described in the regexp docs.
+ */
+    void
+do_sub(eap)
+    exarg_T	*eap;
+{
+    linenr_T	lnum;
+    long	i = 0;
+    regmmatch_T regmatch;
+    static int	do_all = FALSE;		/* do multiple substitutions per line */
+    static int	do_ask = FALSE;		/* ask for confirmation */
+    static int	do_count = FALSE;	/* count only */
+    static int	do_error = TRUE;	/* if false, ignore errors */
+    static int	do_print = FALSE;	/* print last line with subs. */
+    static int	do_list = FALSE;	/* list last line with subs. */
+    static int	do_number = FALSE;	/* list last line with line nr*/
+    static int	do_ic = 0;		/* ignore case flag */
+    char_u	*pat = NULL, *sub = NULL;	/* init for GCC */
+    int		delimiter;
+    int		sublen;
+    int		got_quit = FALSE;
+    int		got_match = FALSE;
+    int		temp;
+    int		which_pat;
+    char_u	*cmd;
+    int		save_State;
+    linenr_T	first_line = 0;		/* first changed line */
+    linenr_T	last_line= 0;		/* below last changed line AFTER the
+					 * change */
+    linenr_T	old_line_count = curbuf->b_ml.ml_line_count;
+    linenr_T	line2;
+    long	nmatch;			/* number of lines in match */
+    linenr_T	sub_firstlnum;		/* nr of first sub line */
+    char_u	*sub_firstline;		/* allocated copy of first sub line */
+    int		endcolumn = FALSE;	/* cursor in last column when done */
+    pos_T	old_cursor = curwin->w_cursor;
+
+    cmd = eap->arg;
+    if (!global_busy)
+    {
+	sub_nsubs = 0;
+	sub_nlines = 0;
+    }
+
+#ifdef FEAT_FKMAP	/* reverse the flow of the Farsi characters */
+    if (p_altkeymap && curwin->w_p_rl)
+	lrF_sub(cmd);
+#endif
+
+    if (eap->cmdidx == CMD_tilde)
+	which_pat = RE_LAST;	/* use last used regexp */
+    else
+	which_pat = RE_SUBST;	/* use last substitute regexp */
+
+				/* new pattern and substitution */
+    if (eap->cmd[0] == 's' && *cmd != NUL && !vim_iswhite(*cmd)
+		&& vim_strchr((char_u *)"0123456789cegriIp|\"", *cmd) == NULL)
+    {
+				/* don't accept alphanumeric for separator */
+	if (isalpha(*cmd))
+	{
+	    EMSG(_("E146: Regular expressions can't be delimited by letters"));
+	    return;
+	}
+	/*
+	 * undocumented vi feature:
+	 *  "\/sub/" and "\?sub?" use last used search pattern (almost like
+	 *  //sub/r).  "\&sub&" use last substitute pattern (like //sub/).
+	 */
+	if (*cmd == '\\')
+	{
+	    ++cmd;
+	    if (vim_strchr((char_u *)"/?&", *cmd) == NULL)
+	    {
+		EMSG(_(e_backslash));
+		return;
+	    }
+	    if (*cmd != '&')
+		which_pat = RE_SEARCH;	    /* use last '/' pattern */
+	    pat = (char_u *)"";		    /* empty search pattern */
+	    delimiter = *cmd++;		    /* remember delimiter character */
+	}
+	else		/* find the end of the regexp */
+	{
+	    which_pat = RE_LAST;	    /* use last used regexp */
+	    delimiter = *cmd++;		    /* remember delimiter character */
+	    pat = cmd;			    /* remember start of search pat */
+	    cmd = skip_regexp(cmd, delimiter, p_magic, &eap->arg);
+	    if (cmd[0] == delimiter)	    /* end delimiter found */
+		*cmd++ = NUL;		    /* replace it with a NUL */
+	}
+
+	/*
+	 * Small incompatibility: vi sees '\n' as end of the command, but in
+	 * Vim we want to use '\n' to find/substitute a NUL.
+	 */
+	sub = cmd;	    /* remember the start of the substitution */
+
+	while (cmd[0])
+	{
+	    if (cmd[0] == delimiter)		/* end delimiter found */
+	    {
+		*cmd++ = NUL;			/* replace it with a NUL */
+		break;
+	    }
+	    if (cmd[0] == '\\' && cmd[1] != 0)	/* skip escaped characters */
+		++cmd;
+	    mb_ptr_adv(cmd);
+	}
+
+	if (!eap->skip)
+	{
+	    /* In POSIX vi ":s/pat/%/" uses the previous subst. string. */
+	    if (STRCMP(sub, "%") == 0
+				 && vim_strchr(p_cpo, CPO_SUBPERCENT) != NULL)
+	    {
+		if (old_sub == NULL)	/* there is no previous command */
+		{
+		    EMSG(_(e_nopresub));
+		    return;
+		}
+		sub = old_sub;
+	    }
+	    else
+	    {
+		vim_free(old_sub);
+		old_sub = vim_strsave(sub);
+	    }
+	}
+    }
+    else if (!eap->skip)	/* use previous pattern and substitution */
+    {
+	if (old_sub == NULL)	/* there is no previous command */
+	{
+	    EMSG(_(e_nopresub));
+	    return;
+	}
+	pat = NULL;		/* search_regcomp() will use previous pattern */
+	sub = old_sub;
+
+	/* Vi compatibility quirk: repeating with ":s" keeps the cursor in the
+	 * last column after using "$". */
+	endcolumn = (curwin->w_curswant == MAXCOL);
+    }
+
+    /*
+     * Find trailing options.  When '&' is used, keep old options.
+     */
+    if (*cmd == '&')
+	++cmd;
+    else
+    {
+	if (!p_ed)
+	{
+	    if (p_gd)		/* default is global on */
+		do_all = TRUE;
+	    else
+		do_all = FALSE;
+	    do_ask = FALSE;
+	}
+	do_error = TRUE;
+	do_print = FALSE;
+	do_count = FALSE;
+	do_ic = 0;
+    }
+    while (*cmd)
+    {
+	/*
+	 * Note that 'g' and 'c' are always inverted, also when p_ed is off.
+	 * 'r' is never inverted.
+	 */
+	if (*cmd == 'g')
+	    do_all = !do_all;
+	else if (*cmd == 'c')
+	    do_ask = !do_ask;
+	else if (*cmd == 'n')
+	    do_count = TRUE;
+	else if (*cmd == 'e')
+	    do_error = !do_error;
+	else if (*cmd == 'r')	    /* use last used regexp */
+	    which_pat = RE_LAST;
+	else if (*cmd == 'p')
+	    do_print = TRUE;
+	else if (*cmd == '#')
+	{
+	    do_print = TRUE;
+	    do_number = TRUE;
+	}
+	else if (*cmd == 'l')
+	{
+	    do_print = TRUE;
+	    do_list = TRUE;
+	}
+	else if (*cmd == 'i')	    /* ignore case */
+	    do_ic = 'i';
+	else if (*cmd == 'I')	    /* don't ignore case */
+	    do_ic = 'I';
+	else
+	    break;
+	++cmd;
+    }
+    if (do_count)
+	do_ask = FALSE;
+
+    /*
+     * check for a trailing count
+     */
+    cmd = skipwhite(cmd);
+    if (VIM_ISDIGIT(*cmd))
+    {
+	i = getdigits(&cmd);
+	if (i <= 0 && !eap->skip && do_error)
+	{
+	    EMSG(_(e_zerocount));
+	    return;
+	}
+	eap->line1 = eap->line2;
+	eap->line2 += i - 1;
+	if (eap->line2 > curbuf->b_ml.ml_line_count)
+	    eap->line2 = curbuf->b_ml.ml_line_count;
+    }
+
+    /*
+     * check for trailing command or garbage
+     */
+    cmd = skipwhite(cmd);
+    if (*cmd && *cmd != '"')	    /* if not end-of-line or comment */
+    {
+	eap->nextcmd = check_nextcmd(cmd);
+	if (eap->nextcmd == NULL)
+	{
+	    EMSG(_(e_trailing));
+	    return;
+	}
+    }
+
+    if (eap->skip)	    /* not executing commands, only parsing */
+	return;
+
+    if (!do_count && !curbuf->b_p_ma)
+    {
+	/* Substitution is not allowed in non-'modifiable' buffer */
+	EMSG(_(e_modifiable));
+	return;
+    }
+
+    if (search_regcomp(pat, RE_SUBST, which_pat, SEARCH_HIS, &regmatch) == FAIL)
+    {
+	if (do_error)
+	    EMSG(_(e_invcmd));
+	return;
+    }
+
+    /* the 'i' or 'I' flag overrules 'ignorecase' and 'smartcase' */
+    if (do_ic == 'i')
+	regmatch.rmm_ic = TRUE;
+    else if (do_ic == 'I')
+	regmatch.rmm_ic = FALSE;
+
+    sub_firstline = NULL;
+
+    /*
+     * ~ in the substitute pattern is replaced with the old pattern.
+     * We do it here once to avoid it to be replaced over and over again.
+     * But don't do it when it starts with "\=", then it's an expression.
+     */
+    if (!(sub[0] == '\\' && sub[1] == '='))
+	sub = regtilde(sub, p_magic);
+
+    /*
+     * Check for a match on each line.
+     */
+    line2 = eap->line2;
+    for (lnum = eap->line1; lnum <= line2 && !(got_quit
+#if defined(FEAT_EVAL) && defined(FEAT_AUTOCMD)
+		|| aborting()
+#endif
+		); ++lnum)
+    {
+	sub_firstlnum = lnum;
+	nmatch = vim_regexec_multi(&regmatch, curwin, curbuf, lnum, (colnr_T)0);
+	if (nmatch)
+	{
+	    colnr_T	copycol;
+	    colnr_T	matchcol;
+	    colnr_T	prev_matchcol = MAXCOL;
+	    char_u	*new_end, *new_start = NULL;
+	    unsigned	new_start_len = 0;
+	    char_u	*p1;
+	    int		did_sub = FALSE;
+	    int		lastone;
+	    unsigned	len, needed_len;
+	    long	nmatch_tl = 0;	/* nr of lines matched below lnum */
+	    int		do_again;	/* do it again after joining lines */
+	    int		skip_match = FALSE;
+
+	    /*
+	     * The new text is build up step by step, to avoid too much
+	     * copying.  There are these pieces:
+	     * sub_firstline	The old text, unmodifed.
+	     * copycol		Column in the old text where we started
+	     *			looking for a match; from here old text still
+	     *			needs to be copied to the new text.
+	     * matchcol		Column number of the old text where to look
+	     *			for the next match.  It's just after the
+	     *			previous match or one further.
+	     * prev_matchcol	Column just after the previous match (if any).
+	     *			Mostly equal to matchcol, except for the first
+	     *			match and after skipping an empty match.
+	     * regmatch.*pos	Where the pattern matched in the old text.
+	     * new_start	The new text, all that has been produced so
+	     *			far.
+	     * new_end		The new text, where to append new text.
+	     *
+	     * lnum		The line number where we were looking for the
+	     *			first match in the old line.
+	     * sub_firstlnum	The line number in the buffer where to look
+	     *			for a match.  Can be different from "lnum"
+	     *			when the pattern or substitute string contains
+	     *			line breaks.
+	     *
+	     * Special situations:
+	     * - When the substitute string contains a line break, the part up
+	     *   to the line break is inserted in the text, but the copy of
+	     *   the original line is kept.  "sub_firstlnum" is adjusted for
+	     *   the inserted lines.
+	     * - When the matched pattern contains a line break, the old line
+	     *   is taken from the line at the end of the pattern.  The lines
+	     *   in the match are deleted later, "sub_firstlnum" is adjusted
+	     *   accordingly.
+	     *
+	     * The new text is built up in new_start[].  It has some extra
+	     * room to avoid using alloc()/free() too often.  new_start_len is
+	     * the lenght of the allocated memory at new_start.
+	     *
+	     * Make a copy of the old line, so it won't be taken away when
+	     * updating the screen or handling a multi-line match.  The "old_"
+	     * pointers point into this copy.
+	     */
+	    sub_firstline = vim_strsave(ml_get(sub_firstlnum));
+	    if (sub_firstline == NULL)
+	    {
+		vim_free(new_start);
+		goto outofmem;
+	    }
+	    copycol = 0;
+	    matchcol = 0;
+
+	    /* At first match, remember current cursor position. */
+	    if (!got_match)
+	    {
+		setpcmark();
+		got_match = TRUE;
+	    }
+
+	    /*
+	     * Loop until nothing more to replace in this line.
+	     * 1. Handle match with empty string.
+	     * 2. If do_ask is set, ask for confirmation.
+	     * 3. substitute the string.
+	     * 4. if do_all is set, find next match
+	     * 5. break if there isn't another match in this line
+	     */
+	    for (;;)
+	    {
+		/* Save the line number of the last change for the final
+		 * cursor position (just like Vi). */
+		curwin->w_cursor.lnum = lnum;
+		do_again = FALSE;
+
+		/*
+		 * 1. Match empty string does not count, except for first
+		 * match.  This reproduces the strange vi behaviour.
+		 * This also catches endless loops.
+		 */
+		if (matchcol == prev_matchcol
+			&& regmatch.endpos[0].lnum == 0
+			&& matchcol == regmatch.endpos[0].col)
+		{
+		    if (sub_firstline[matchcol] == NUL)
+			/* We already were at the end of the line.  Don't look
+			 * for a match in this line again. */
+			skip_match = TRUE;
+		    else
+			++matchcol; /* search for a match at next column */
+		    goto skip;
+		}
+
+		/* Normally we continue searching for a match just after the
+		 * previous match. */
+		matchcol = regmatch.endpos[0].col;
+		prev_matchcol = matchcol;
+
+		/*
+		 * 2. If do_count is set only increase the counter.
+		 *    If do_ask is set, ask for confirmation.
+		 */
+		if (do_count)
+		{
+		    /* For a multi-line match, put matchcol at the NUL at
+		     * the end of the line and set nmatch to one, so that
+		     * we continue looking for a match on the next line.
+		     * Avoids that ":s/\nB\@=//gc" get stuck. */
+		    if (nmatch > 1)
+		    {
+			matchcol = (colnr_T)STRLEN(sub_firstline);
+			nmatch = 1;
+		    }
+		    sub_nsubs++;
+		    did_sub = TRUE;
+		    goto skip;
+		}
+
+		if (do_ask)
+		{
+		    /* change State to CONFIRM, so that the mouse works
+		     * properly */
+		    save_State = State;
+		    State = CONFIRM;
+#ifdef FEAT_MOUSE
+		    setmouse();		/* disable mouse in xterm */
+#endif
+		    curwin->w_cursor.col = regmatch.startpos[0].col;
+
+		    /* When 'cpoptions' contains "u" don't sync undo when
+		     * asking for confirmation. */
+		    if (vim_strchr(p_cpo, CPO_UNDO) != NULL)
+			++no_u_sync;
+
+		    /*
+		     * Loop until 'y', 'n', 'q', CTRL-E or CTRL-Y typed.
+		     */
+		    while (do_ask)
+		    {
+			if (exmode_active)
+			{
+			    char_u	*resp;
+			    colnr_T	sc, ec;
+
+			    print_line_no_prefix(lnum, FALSE, FALSE);
+
+			    getvcol(curwin, &curwin->w_cursor, &sc, NULL, NULL);
+			    curwin->w_cursor.col = regmatch.endpos[0].col - 1;
+			    getvcol(curwin, &curwin->w_cursor, NULL, NULL, &ec);
+			    msg_start();
+			    for (i = 0; i < (long)sc; ++i)
+				msg_putchar(' ');
+			    for ( ; i <= (long)ec; ++i)
+				msg_putchar('^');
+
+			    resp = getexmodeline('?', NULL, 0);
+			    if (resp != NULL)
+			    {
+				i = *resp;
+				vim_free(resp);
+			    }
+			}
+			else
+			{
+#ifdef FEAT_FOLDING
+			    int save_p_fen = curwin->w_p_fen;
+
+			    curwin->w_p_fen = FALSE;
+#endif
+			    /* Invert the matched string.
+			     * Remove the inversion afterwards. */
+			    temp = RedrawingDisabled;
+			    RedrawingDisabled = 0;
+
+			    search_match_lines = regmatch.endpos[0].lnum;
+			    search_match_endcol = regmatch.endpos[0].col;
+			    highlight_match = TRUE;
+
+			    update_topline();
+			    validate_cursor();
+			    update_screen(SOME_VALID);
+			    highlight_match = FALSE;
+			    redraw_later(SOME_VALID);
+
+#ifdef FEAT_FOLDING
+			    curwin->w_p_fen = save_p_fen;
+#endif
+			    if (msg_row == Rows - 1)
+				msg_didout = FALSE;	/* avoid a scroll-up */
+			    msg_starthere();
+			    i = msg_scroll;
+			    msg_scroll = 0;		/* truncate msg when
+							   needed */
+			    msg_no_more = TRUE;
+			    /* write message same highlighting as for
+			     * wait_return */
+			    smsg_attr(hl_attr(HLF_R),
+				    (char_u *)_("replace with %s (y/n/a/q/l/^E/^Y)?"), sub);
+			    msg_no_more = FALSE;
+			    msg_scroll = i;
+			    showruler(TRUE);
+			    windgoto(msg_row, msg_col);
+			    RedrawingDisabled = temp;
+
+#ifdef USE_ON_FLY_SCROLL
+			    dont_scroll = FALSE; /* allow scrolling here */
+#endif
+			    ++no_mapping;	/* don't map this key */
+			    ++allow_keys;	/* allow special keys */
+			    i = safe_vgetc();
+			    --allow_keys;
+			    --no_mapping;
+
+			    /* clear the question */
+			    msg_didout = FALSE;	/* don't scroll up */
+			    msg_col = 0;
+			    gotocmdline(TRUE);
+			}
+
+			need_wait_return = FALSE; /* no hit-return prompt */
+			if (i == 'q' || i == ESC || i == Ctrl_C
+#ifdef UNIX
+				|| i == intr_char
+#endif
+				)
+			{
+			    got_quit = TRUE;
+			    break;
+			}
+			if (i == 'n')
+			    break;
+			if (i == 'y')
+			    break;
+			if (i == 'l')
+			{
+			    /* last: replace and then stop */
+			    do_all = FALSE;
+			    line2 = lnum;
+			    break;
+			}
+			if (i == 'a')
+			{
+			    do_ask = FALSE;
+			    break;
+			}
+#ifdef FEAT_INS_EXPAND
+			if (i == Ctrl_E)
+			    scrollup_clamp();
+			else if (i == Ctrl_Y)
+			    scrolldown_clamp();
+#endif
+		    }
+		    State = save_State;
+#ifdef FEAT_MOUSE
+		    setmouse();
+#endif
+		    if (vim_strchr(p_cpo, CPO_UNDO) != NULL)
+			--no_u_sync;
+
+		    if (i == 'n')
+		    {
+			/* For a multi-line match, put matchcol at the NUL at
+			 * the end of the line and set nmatch to one, so that
+			 * we continue looking for a match on the next line.
+			 * Avoids that ":%s/\nB\@=//gc" and ":%s/\n/,\r/gc"
+			 * get stuck when pressing 'n'. */
+			if (nmatch > 1)
+			{
+			    matchcol = (colnr_T)STRLEN(sub_firstline);
+			    skip_match = TRUE;
+			}
+			goto skip;
+		    }
+		    if (got_quit)
+			break;
+		}
+
+		/* Move the cursor to the start of the match, so that we can
+		 * use "\=col("."). */
+		curwin->w_cursor.col = regmatch.startpos[0].col;
+
+		/*
+		 * 3. substitute the string.
+		 */
+		/* get length of substitution part */
+		sublen = vim_regsub_multi(&regmatch, sub_firstlnum,
+				    sub, sub_firstline, FALSE, p_magic, TRUE);
+
+		/* When the match included the "$" of the last line it may
+		 * go beyond the last line of the buffer. */
+		if (nmatch > curbuf->b_ml.ml_line_count - sub_firstlnum + 1)
+		{
+		    nmatch = curbuf->b_ml.ml_line_count - sub_firstlnum + 1;
+		    skip_match = TRUE;
+		}
+
+		/* Need room for:
+		 * - result so far in new_start (not for first sub in line)
+		 * - original text up to match
+		 * - length of substituted part
+		 * - original text after match
+		 */
+		if (nmatch == 1)
+		    p1 = sub_firstline;
+		else
+		{
+		    p1 = ml_get(sub_firstlnum + nmatch - 1);
+		    nmatch_tl += nmatch - 1;
+		}
+		i = regmatch.startpos[0].col - copycol;
+		needed_len = i + ((unsigned)STRLEN(p1) - regmatch.endpos[0].col)
+								 + sublen + 1;
+		if (new_start == NULL)
+		{
+		    /*
+		     * Get some space for a temporary buffer to do the
+		     * substitution into (and some extra space to avoid
+		     * too many calls to alloc()/free()).
+		     */
+		    new_start_len = needed_len + 50;
+		    if ((new_start = alloc_check(new_start_len)) == NULL)
+			goto outofmem;
+		    *new_start = NUL;
+		    new_end = new_start;
+		}
+		else
+		{
+		    /*
+		     * Check if the temporary buffer is long enough to do the
+		     * substitution into.  If not, make it larger (with a bit
+		     * extra to avoid too many calls to alloc()/free()).
+		     */
+		    len = (unsigned)STRLEN(new_start);
+		    needed_len += len;
+		    if (needed_len > new_start_len)
+		    {
+			new_start_len = needed_len + 50;
+			if ((p1 = alloc_check(new_start_len)) == NULL)
+			{
+			    vim_free(new_start);
+			    goto outofmem;
+			}
+			mch_memmove(p1, new_start, (size_t)(len + 1));
+			vim_free(new_start);
+			new_start = p1;
+		    }
+		    new_end = new_start + len;
+		}
+
+		/*
+		 * copy the text up to the part that matched
+		 */
+		mch_memmove(new_end, sub_firstline + copycol, (size_t)i);
+		new_end += i;
+
+		(void)vim_regsub_multi(&regmatch, sub_firstlnum,
+					   sub, new_end, TRUE, p_magic, TRUE);
+		sub_nsubs++;
+		did_sub = TRUE;
+
+		/* Move the cursor to the start of the line, to avoid that it
+		 * is beyond the end of the line after the substitution. */
+		curwin->w_cursor.col = 0;
+
+		/* For a multi-line match, make a copy of the last matched
+		 * line and continue in that one. */
+		if (nmatch > 1)
+		{
+		    sub_firstlnum += nmatch - 1;
+		    vim_free(sub_firstline);
+		    sub_firstline = vim_strsave(ml_get(sub_firstlnum));
+		    /* When going beyond the last line, stop substituting. */
+		    if (sub_firstlnum <= line2)
+			do_again = TRUE;
+		    else
+			do_all = FALSE;
+		}
+
+		/* Remember next character to be copied. */
+		copycol = regmatch.endpos[0].col;
+
+		if (skip_match)
+		{
+		    /* Already hit end of the buffer, sub_firstlnum is one
+		     * less than what it ought to be. */
+		    vim_free(sub_firstline);
+		    sub_firstline = vim_strsave((char_u *)"");
+		    copycol = 0;
+		}
+
+		/*
+		 * Now the trick is to replace CTRL-M chars with a real line
+		 * break.  This would make it impossible to insert a CTRL-M in
+		 * the text.  The line break can be avoided by preceding the
+		 * CTRL-M with a backslash.  To be able to insert a backslash,
+		 * they must be doubled in the string and are halved here.
+		 * That is Vi compatible.
+		 */
+		for (p1 = new_end; *p1; ++p1)
+		{
+		    if (p1[0] == '\\' && p1[1] != NUL)  /* remove backslash */
+			mch_memmove(p1, p1 + 1, STRLEN(p1));
+		    else if (*p1 == CAR)
+		    {
+			if (u_inssub(lnum) == OK)   /* prepare for undo */
+			{
+			    *p1 = NUL;		    /* truncate up to the CR */
+			    ml_append(lnum - 1, new_start,
+					(colnr_T)(p1 - new_start + 1), FALSE);
+			    mark_adjust(lnum + 1, (linenr_T)MAXLNUM, 1L, 0L);
+			    if (do_ask)
+				appended_lines(lnum - 1, 1L);
+			    else
+			    {
+				if (first_line == 0)
+				    first_line = lnum;
+				last_line = lnum + 1;
+			    }
+			    /* All line numbers increase. */
+			    ++sub_firstlnum;
+			    ++lnum;
+			    ++line2;
+			    /* move the cursor to the new line, like Vi */
+			    ++curwin->w_cursor.lnum;
+			    STRCPY(new_start, p1 + 1);	/* copy the rest */
+			    p1 = new_start - 1;
+			}
+		    }
+#ifdef FEAT_MBYTE
+		    else if (has_mbyte)
+			p1 += (*mb_ptr2len)(p1) - 1;
+#endif
+		}
+
+		/*
+		 * 4. If do_all is set, find next match.
+		 * Prevent endless loop with patterns that match empty
+		 * strings, e.g. :s/$/pat/g or :s/[a-z]* /(&)/g.
+		 * But ":s/\n/#/" is OK.
+		 */
+skip:
+		/* We already know that we did the last subst when we are at
+		 * the end of the line, except that a pattern like
+		 * "bar\|\nfoo" may match at the NUL. */
+		lastone = (skip_match
+			|| got_int
+			|| got_quit
+			|| !(do_all || do_again)
+			|| (sub_firstline[matchcol] == NUL && nmatch <= 1
+					 && !re_multiline(regmatch.regprog)));
+		nmatch = -1;
+
+		/*
+		 * Replace the line in the buffer when needed.  This is
+		 * skipped when there are more matches.
+		 * The check for nmatch_tl is needed for when multi-line
+		 * matching must replace the lines before trying to do another
+		 * match, otherwise "\@<=" won't work.
+		 * When asking the user we like to show the already replaced
+		 * text, but don't do it when "\<@=" or "\<@!" is used, it
+		 * changes what matches.
+		 */
+		if (lastone
+			|| (do_ask && !re_lookbehind(regmatch.regprog))
+			|| nmatch_tl > 0
+			|| (nmatch = vim_regexec_multi(&regmatch, curwin,
+				       curbuf, sub_firstlnum, matchcol)) == 0)
+		{
+		    if (new_start != NULL)
+		    {
+			/*
+			 * Copy the rest of the line, that didn't match.
+			 * "matchcol" has to be adjusted, we use the end of
+			 * the line as reference, because the substitute may
+			 * have changed the number of characters.  Same for
+			 * "prev_matchcol".
+			 */
+			STRCAT(new_start, sub_firstline + copycol);
+			matchcol = (colnr_T)STRLEN(sub_firstline) - matchcol;
+			prev_matchcol = (colnr_T)STRLEN(sub_firstline)
+							      - prev_matchcol;
+
+			if (u_savesub(lnum) != OK)
+			    break;
+			ml_replace(lnum, new_start, TRUE);
+
+			if (nmatch_tl > 0)
+			{
+			    /*
+			     * Matched lines have now been substituted and are
+			     * useless, delete them.  The part after the match
+			     * has been appended to new_start, we don't need
+			     * it in the buffer.
+			     */
+			    ++lnum;
+			    if (u_savedel(lnum, nmatch_tl) != OK)
+				break;
+			    for (i = 0; i < nmatch_tl; ++i)
+				ml_delete(lnum, (int)FALSE);
+			    mark_adjust(lnum, lnum + nmatch_tl - 1,
+						   (long)MAXLNUM, -nmatch_tl);
+			    if (do_ask)
+				deleted_lines(lnum, nmatch_tl);
+			    --lnum;
+			    line2 -= nmatch_tl; /* nr of lines decreases */
+			    nmatch_tl = 0;
+			}
+
+			/* When asking, undo is saved each time, must also set
+			 * changed flag each time. */
+			if (do_ask)
+			    changed_bytes(lnum, 0);
+			else
+			{
+			    if (first_line == 0)
+				first_line = lnum;
+			    last_line = lnum + 1;
+			}
+
+			sub_firstlnum = lnum;
+			vim_free(sub_firstline);    /* free the temp buffer */
+			sub_firstline = new_start;
+			new_start = NULL;
+			matchcol = (colnr_T)STRLEN(sub_firstline) - matchcol;
+			prev_matchcol = (colnr_T)STRLEN(sub_firstline)
+							      - prev_matchcol;
+			copycol = 0;
+		    }
+		    if (nmatch == -1 && !lastone)
+			nmatch = vim_regexec_multi(&regmatch, curwin, curbuf,
+						     sub_firstlnum, matchcol);
+
+		    /*
+		     * 5. break if there isn't another match in this line
+		     */
+		    if (nmatch <= 0)
+			break;
+		}
+
+		line_breakcheck();
+	    }
+
+	    if (did_sub)
+		++sub_nlines;
+	    vim_free(sub_firstline);	/* free the copy of the original line */
+	    sub_firstline = NULL;
+	}
+
+	line_breakcheck();
+    }
+
+    if (first_line != 0)
+    {
+	/* Need to subtract the number of added lines from "last_line" to get
+	 * the line number before the change (same as adding the number of
+	 * deleted lines). */
+	i = curbuf->b_ml.ml_line_count - old_line_count;
+	changed_lines(first_line, 0, last_line - i, i);
+    }
+
+outofmem:
+    vim_free(sub_firstline); /* may have to free allocated copy of the line */
+
+    /* ":s/pat//n" doesn't move the cursor */
+    if (do_count)
+	curwin->w_cursor = old_cursor;
+
+    if (sub_nsubs)
+    {
+	/* Set the '[ and '] marks. */
+	curbuf->b_op_start.lnum = eap->line1;
+	curbuf->b_op_end.lnum = line2;
+	curbuf->b_op_start.col = curbuf->b_op_end.col = 0;
+
+	if (!global_busy)
+	{
+	    if (endcolumn)
+		coladvance((colnr_T)MAXCOL);
+	    else
+		beginline(BL_WHITE | BL_FIX);
+	    if (!do_sub_msg(do_count) && do_ask)
+		MSG("");
+	}
+	else
+	    global_need_beginline = TRUE;
+	if (do_print)
+	    print_line(curwin->w_cursor.lnum, do_number, do_list);
+    }
+    else if (!global_busy)
+    {
+	if (got_int)		/* interrupted */
+	    EMSG(_(e_interr));
+	else if (got_match)	/* did find something but nothing substituted */
+	    MSG("");
+	else if (do_error)	/* nothing found */
+	    EMSG2(_(e_patnotf2), get_search_pat());
+    }
+
+    vim_free(regmatch.regprog);
+}
+
+/*
+ * Give message for number of substitutions.
+ * Can also be used after a ":global" command.
+ * Return TRUE if a message was given.
+ */
+    int
+do_sub_msg(count_only)
+    int	    count_only;		/* used 'n' flag for ":s" */
+{
+    int	    len = 0;
+
+    /*
+     * Only report substitutions when:
+     * - more than 'report' substitutions
+     * - command was typed by user, or number of changed lines > 'report'
+     * - giving messages is not disabled by 'lazyredraw'
+     */
+    if (((sub_nsubs > p_report && (KeyTyped || sub_nlines > 1 || p_report < 1))
+		|| count_only)
+	    && messaging())
+    {
+	if (got_int)
+	{
+	    STRCPY(msg_buf, _("(Interrupted) "));
+	    len = (int)STRLEN(msg_buf);
+	}
+	if (sub_nsubs == 1)
+	    vim_snprintf((char *)msg_buf + len, sizeof(msg_buf) - len,
+		    "%s", count_only ? _("1 match") : _("1 substitution"));
+	else
+	    vim_snprintf((char *)msg_buf + len, sizeof(msg_buf) - len,
+		    count_only ? _("%ld matches") : _("%ld substitutions"),
+								   sub_nsubs);
+	len = (int)STRLEN(msg_buf);
+	if (sub_nlines == 1)
+	    vim_snprintf((char *)msg_buf + len, sizeof(msg_buf) - len,
+		    "%s", _(" on 1 line"));
+	else
+	    vim_snprintf((char *)msg_buf + len, sizeof(msg_buf) - len,
+		    _(" on %ld lines"), (long)sub_nlines);
+	if (msg(msg_buf))
+	    /* save message to display it after redraw */
+	    set_keep_msg(msg_buf, 0);
+	return TRUE;
+    }
+    if (got_int)
+    {
+	EMSG(_(e_interr));
+	return TRUE;
+    }
+    return FALSE;
+}
+
+/*
+ * Execute a global command of the form:
+ *
+ * g/pattern/X : execute X on all lines where pattern matches
+ * v/pattern/X : execute X on all lines where pattern does not match
+ *
+ * where 'X' is an EX command
+ *
+ * The command character (as well as the trailing slash) is optional, and
+ * is assumed to be 'p' if missing.
+ *
+ * This is implemented in two passes: first we scan the file for the pattern and
+ * set a mark for each line that (not) matches. secondly we execute the command
+ * for each line that has a mark. This is required because after deleting
+ * lines we do not know where to search for the next match.
+ */
+    void
+ex_global(eap)
+    exarg_T	*eap;
+{
+    linenr_T	lnum;		/* line number according to old situation */
+    int		ndone = 0;
+    int		type;		/* first char of cmd: 'v' or 'g' */
+    char_u	*cmd;		/* command argument */
+
+    char_u	delim;		/* delimiter, normally '/' */
+    char_u	*pat;
+    regmmatch_T	regmatch;
+    int		match;
+    int		which_pat;
+
+    if (global_busy)
+    {
+	EMSG(_("E147: Cannot do :global recursive"));	/* will increment global_busy */
+	return;
+    }
+
+    if (eap->forceit)		    /* ":global!" is like ":vglobal" */
+	type = 'v';
+    else
+	type = *eap->cmd;
+    cmd = eap->arg;
+    which_pat = RE_LAST;	    /* default: use last used regexp */
+    sub_nsubs = 0;
+    sub_nlines = 0;
+
+    /*
+     * undocumented vi feature:
+     *	"\/" and "\?": use previous search pattern.
+     *		 "\&": use previous substitute pattern.
+     */
+    if (*cmd == '\\')
+    {
+	++cmd;
+	if (vim_strchr((char_u *)"/?&", *cmd) == NULL)
+	{
+	    EMSG(_(e_backslash));
+	    return;
+	}
+	if (*cmd == '&')
+	    which_pat = RE_SUBST;	/* use previous substitute pattern */
+	else
+	    which_pat = RE_SEARCH;	/* use previous search pattern */
+	++cmd;
+	pat = (char_u *)"";
+    }
+    else if (*cmd == NUL)
+    {
+	EMSG(_("E148: Regular expression missing from global"));
+	return;
+    }
+    else
+    {
+	delim = *cmd;		/* get the delimiter */
+	if (delim)
+	    ++cmd;		/* skip delimiter if there is one */
+	pat = cmd;		/* remember start of pattern */
+	cmd = skip_regexp(cmd, delim, p_magic, &eap->arg);
+	if (cmd[0] == delim)		    /* end delimiter found */
+	    *cmd++ = NUL;		    /* replace it with a NUL */
+    }
+
+#ifdef FEAT_FKMAP	/* when in Farsi mode, reverse the character flow */
+    if (p_altkeymap && curwin->w_p_rl)
+	lrFswap(pat,0);
+#endif
+
+    if (search_regcomp(pat, RE_BOTH, which_pat, SEARCH_HIS, &regmatch) == FAIL)
+    {
+	EMSG(_(e_invcmd));
+	return;
+    }
+
+    /*
+     * pass 1: set marks for each (not) matching line
+     */
+    for (lnum = eap->line1; lnum <= eap->line2 && !got_int; ++lnum)
+    {
+	/* a match on this line? */
+	match = vim_regexec_multi(&regmatch, curwin, curbuf, lnum, (colnr_T)0);
+	if ((type == 'g' && match) || (type == 'v' && !match))
+	{
+	    ml_setmarked(lnum);
+	    ndone++;
+	}
+	line_breakcheck();
+    }
+
+    /*
+     * pass 2: execute the command for each line that has been marked
+     */
+    if (got_int)
+	MSG(_(e_interr));
+    else if (ndone == 0)
+    {
+	if (type == 'v')
+	    smsg((char_u *)_("Pattern found in every line: %s"), pat);
+	else
+	    smsg((char_u *)_(e_patnotf2), pat);
+    }
+    else
+	global_exe(cmd);
+
+    ml_clearmarked();	   /* clear rest of the marks */
+    vim_free(regmatch.regprog);
+}
+
+/*
+ * Execute "cmd" on lines marked with ml_setmarked().
+ */
+    void
+global_exe(cmd)
+    char_u	*cmd;
+{
+    linenr_T	old_lcount;	/* b_ml.ml_line_count before the command */
+    linenr_T	lnum;		/* line number according to old situation */
+
+    /*
+     * Set current position only once for a global command.
+     * If global_busy is set, setpcmark() will not do anything.
+     * If there is an error, global_busy will be incremented.
+     */
+    setpcmark();
+
+    /* When the command writes a message, don't overwrite the command. */
+    msg_didout = TRUE;
+
+    global_need_beginline = FALSE;
+    global_busy = 1;
+    old_lcount = curbuf->b_ml.ml_line_count;
+    while (!got_int && (lnum = ml_firstmarked()) != 0 && global_busy == 1)
+    {
+	curwin->w_cursor.lnum = lnum;
+	curwin->w_cursor.col = 0;
+	if (*cmd == NUL || *cmd == '\n')
+	    do_cmdline((char_u *)"p", NULL, NULL, DOCMD_NOWAIT);
+	else
+	    do_cmdline(cmd, NULL, NULL, DOCMD_NOWAIT);
+	ui_breakcheck();
+    }
+
+    global_busy = 0;
+    if (global_need_beginline)
+	beginline(BL_WHITE | BL_FIX);
+    else
+	check_cursor();	/* cursor may be beyond the end of the line */
+
+    /* the cursor may not have moved in the text but a change in a previous
+     * line may move it on the screen */
+    changed_line_abv_curs();
+
+    /* If it looks like no message was written, allow overwriting the
+     * command with the report for number of changes. */
+    if (msg_col == 0 && msg_scrolled == 0)
+	msg_didout = FALSE;
+
+    /* If substitutes done, report number of substitutes, otherwise report
+     * number of extra or deleted lines. */
+    if (!do_sub_msg(FALSE))
+	msgmore(curbuf->b_ml.ml_line_count - old_lcount);
+}
+
+#ifdef FEAT_VIMINFO
+    int
+read_viminfo_sub_string(virp, force)
+    vir_T	*virp;
+    int		force;
+{
+    if (old_sub != NULL && force)
+	vim_free(old_sub);
+    if (force || old_sub == NULL)
+	old_sub = viminfo_readstring(virp, 1, TRUE);
+    return viminfo_readline(virp);
+}
+
+    void
+write_viminfo_sub_string(fp)
+    FILE    *fp;
+{
+    if (get_viminfo_parameter('/') != 0 && old_sub != NULL)
+    {
+	fprintf(fp, _("\n# Last Substitute String:\n$"));
+	viminfo_writestring(fp, old_sub);
+    }
+}
+#endif /* FEAT_VIMINFO */
+
+#if defined(EXITFREE) || defined(PROTO)
+    void
+free_old_sub()
+{
+    vim_free(old_sub);
+}
+#endif
+
+#if (defined(FEAT_WINDOWS) && defined(FEAT_QUICKFIX)) || defined(PROTO)
+/*
+ * Set up for a tagpreview.
+ * Return TRUE when it was created.
+ */
+    int
+prepare_tagpreview(undo_sync)
+    int		undo_sync;	/* sync undo when leaving the window */
+{
+    win_T	*wp;
+
+# ifdef FEAT_GUI
+    need_mouse_correct = TRUE;
+# endif
+
+    /*
+     * If there is already a preview window open, use that one.
+     */
+    if (!curwin->w_p_pvw)
+    {
+	for (wp = firstwin; wp != NULL; wp = wp->w_next)
+	    if (wp->w_p_pvw)
+		break;
+	if (wp != NULL)
+	    win_enter(wp, undo_sync);
+	else
+	{
+	    /*
+	     * There is no preview window open yet.  Create one.
+	     */
+	    if (win_split(g_do_tagpreview > 0 ? g_do_tagpreview : 0, 0)
+								      == FAIL)
+		return FALSE;
+	    curwin->w_p_pvw = TRUE;
+	    curwin->w_p_wfh = TRUE;
+# ifdef FEAT_SCROLLBIND
+	    curwin->w_p_scb = FALSE;	    /* don't take over 'scrollbind' */
+# endif
+# ifdef FEAT_DIFF
+	    curwin->w_p_diff = FALSE;	    /* no 'diff' */
+# endif
+# ifdef FEAT_FOLDING
+	    curwin->w_p_fdc = 0;	    /* no 'foldcolumn' */
+# endif
+	    return TRUE;
+	}
+    }
+    return FALSE;
+}
+
+#endif
+
+
+/*
+ * ":help": open a read-only window on a help file
+ */
+    void
+ex_help(eap)
+    exarg_T	*eap;
+{
+    char_u	*arg;
+    char_u	*tag;
+    FILE	*helpfd;	/* file descriptor of help file */
+    int		n;
+    int		i;
+#ifdef FEAT_WINDOWS
+    win_T	*wp;
+#endif
+    int		num_matches;
+    char_u	**matches;
+    char_u	*p;
+    int		empty_fnum = 0;
+    int		alt_fnum = 0;
+    buf_T	*buf;
+#ifdef FEAT_MULTI_LANG
+    int		len;
+    char_u	*lang;
+#endif
+
+    if (eap != NULL)
+    {
+	/*
+	 * A ":help" command ends at the first LF, or at a '|' that is
+	 * followed by some text.  Set nextcmd to the following command.
+	 */
+	for (arg = eap->arg; *arg; ++arg)
+	{
+	    if (*arg == '\n' || *arg == '\r'
+		    || (*arg == '|' && arg[1] != NUL && arg[1] != '|'))
+	    {
+		*arg++ = NUL;
+		eap->nextcmd = arg;
+		break;
+	    }
+	}
+	arg = eap->arg;
+
+	if (eap->forceit && *arg == NUL)
+	{
+	    EMSG(_("E478: Don't panic!"));
+	    return;
+	}
+
+	if (eap->skip)	    /* not executing commands */
+	    return;
+    }
+    else
+	arg = (char_u *)"";
+
+    /* remove trailing blanks */
+    p = arg + STRLEN(arg) - 1;
+    while (p > arg && vim_iswhite(*p) && p[-1] != '\\')
+	*p-- = NUL;
+
+#ifdef FEAT_MULTI_LANG
+    /* Check for a specified language */
+    lang = check_help_lang(arg);
+#endif
+
+    /* When no argument given go to the index. */
+    if (*arg == NUL)
+	arg = (char_u *)"help.txt";
+
+    /*
+     * Check if there is a match for the argument.
+     */
+    n = find_help_tags(arg, &num_matches, &matches,
+						 eap != NULL && eap->forceit);
+
+    i = 0;
+#ifdef FEAT_MULTI_LANG
+    if (n != FAIL && lang != NULL)
+	/* Find first item with the requested language. */
+	for (i = 0; i < num_matches; ++i)
+	{
+	    len = (int)STRLEN(matches[i]);
+	    if (len > 3 && matches[i][len - 3] == '@'
+				  && STRICMP(matches[i] + len - 2, lang) == 0)
+		break;
+	}
+#endif
+    if (i >= num_matches || n == FAIL)
+    {
+#ifdef FEAT_MULTI_LANG
+	if (lang != NULL)
+	    EMSG3(_("E661: Sorry, no '%s' help for %s"), lang, arg);
+	else
+#endif
+	    EMSG2(_("E149: Sorry, no help for %s"), arg);
+	if (n != FAIL)
+	    FreeWild(num_matches, matches);
+	return;
+    }
+
+    /* The first match (in the requested language) is the best match. */
+    tag = vim_strsave(matches[i]);
+    FreeWild(num_matches, matches);
+
+#ifdef FEAT_GUI
+    need_mouse_correct = TRUE;
+#endif
+
+    /*
+     * Re-use an existing help window or open a new one.
+     * Always open a new one for ":tab help".
+     */
+    if (!curwin->w_buffer->b_help
+#ifdef FEAT_WINDOWS
+	    || cmdmod.tab != 0
+#endif
+	    )
+    {
+#ifdef FEAT_WINDOWS
+	if (cmdmod.tab != 0)
+	    wp = NULL;
+	else
+	    for (wp = firstwin; wp != NULL; wp = wp->w_next)
+		if (wp->w_buffer != NULL && wp->w_buffer->b_help)
+		    break;
+	if (wp != NULL && wp->w_buffer->b_nwindows > 0)
+	    win_enter(wp, TRUE);
+	else
+#endif
+	{
+	    /*
+	     * There is no help window yet.
+	     * Try to open the file specified by the "helpfile" option.
+	     */
+	    if ((helpfd = mch_fopen((char *)p_hf, READBIN)) == NULL)
+	    {
+		smsg((char_u *)_("Sorry, help file \"%s\" not found"), p_hf);
+		goto erret;
+	    }
+	    fclose(helpfd);
+
+#ifdef FEAT_WINDOWS
+	    /* Split off help window; put it at far top if no position
+	     * specified, the current window is vertically split and
+	     * narrow. */
+	    n = WSP_HELP;
+# ifdef FEAT_VERTSPLIT
+	    if (cmdmod.split == 0 && curwin->w_width != Columns
+						  && curwin->w_width < 80)
+		n |= WSP_TOP;
+# endif
+	    if (win_split(0, n) == FAIL)
+		goto erret;
+#else
+	    /* use current window */
+	    if (!can_abandon(curbuf, FALSE))
+		goto erret;
+#endif
+
+#ifdef FEAT_WINDOWS
+	    if (curwin->w_height < p_hh)
+		win_setheight((int)p_hh);
+#endif
+
+	    /*
+	     * Open help file (do_ecmd() will set b_help flag, readfile() will
+	     * set b_p_ro flag).
+	     * Set the alternate file to the previously edited file.
+	     */
+	    alt_fnum = curbuf->b_fnum;
+	    (void)do_ecmd(0, NULL, NULL, NULL, ECMD_LASTL,
+						   ECMD_HIDE + ECMD_SET_HELP);
+	    if (!cmdmod.keepalt)
+		curwin->w_alt_fnum = alt_fnum;
+	    empty_fnum = curbuf->b_fnum;
+	}
+    }
+
+    if (!p_im)
+	restart_edit = 0;	    /* don't want insert mode in help file */
+
+    if (tag != NULL)
+	do_tag(tag, DT_HELP, 1, FALSE, TRUE);
+
+    /* Delete the empty buffer if we're not using it.  Careful: autocommands
+     * may have jumped to another window, check that the buffer is not in a
+     * window. */
+    if (empty_fnum != 0 && curbuf->b_fnum != empty_fnum)
+    {
+	buf = buflist_findnr(empty_fnum);
+	if (buf != NULL && buf->b_nwindows == 0)
+	    wipe_buffer(buf, TRUE);
+    }
+
+    /* keep the previous alternate file */
+    if (alt_fnum != 0 && curwin->w_alt_fnum == empty_fnum && !cmdmod.keepalt)
+	curwin->w_alt_fnum = alt_fnum;
+
+erret:
+    vim_free(tag);
+}
+
+
+#if defined(FEAT_MULTI_LANG) || defined(PROTO)
+/*
+ * In an argument search for a language specifiers in the form "@xx".
+ * Changes the "@" to NUL if found, and returns a pointer to "xx".
+ * Returns NULL if not found.
+ */
+    char_u *
+check_help_lang(arg)
+    char_u *arg;
+{
+    int len = (int)STRLEN(arg);
+
+    if (len >= 3 && arg[len - 3] == '@' && ASCII_ISALPHA(arg[len - 2])
+					       && ASCII_ISALPHA(arg[len - 1]))
+    {
+	arg[len - 3] = NUL;		/* remove the '@' */
+	return arg + len - 2;
+    }
+    return NULL;
+}
+#endif
+
+/*
+ * Return a heuristic indicating how well the given string matches.  The
+ * smaller the number, the better the match.  This is the order of priorities,
+ * from best match to worst match:
+ *	- Match with least alpha-numeric characters is better.
+ *	- Match with least total characters is better.
+ *	- Match towards the start is better.
+ *	- Match starting with "+" is worse (feature instead of command)
+ * Assumption is made that the matched_string passed has already been found to
+ * match some string for which help is requested.  webb.
+ */
+    int
+help_heuristic(matched_string, offset, wrong_case)
+    char_u	*matched_string;
+    int		offset;			/* offset for match */
+    int		wrong_case;		/* no matching case */
+{
+    int		num_letters;
+    char_u	*p;
+
+    num_letters = 0;
+    for (p = matched_string; *p; p++)
+	if (ASCII_ISALNUM(*p))
+	    num_letters++;
+
+    /*
+     * Multiply the number of letters by 100 to give it a much bigger
+     * weighting than the number of characters.
+     * If there only is a match while ignoring case, add 5000.
+     * If the match starts in the middle of a word, add 10000 to put it
+     * somewhere in the last half.
+     * If the match is more than 2 chars from the start, multiply by 200 to
+     * put it after matches at the start.
+     */
+    if (ASCII_ISALNUM(matched_string[offset]) && offset > 0
+				 && ASCII_ISALNUM(matched_string[offset - 1]))
+	offset += 10000;
+    else if (offset > 2)
+	offset *= 200;
+    if (wrong_case)
+	offset += 5000;
+    /* Features are less interesting than the subjects themselves, but "+"
+     * alone is not a feature. */
+    if (matched_string[0] == '+' && matched_string[1] != NUL)
+	offset += 100;
+    return (int)(100 * num_letters + STRLEN(matched_string) + offset);
+}
+
+/*
+ * Compare functions for qsort() below, that checks the help heuristics number
+ * that has been put after the tagname by find_tags().
+ */
+    static int
+#ifdef __BORLANDC__
+_RTLENTRYF
+#endif
+help_compare(s1, s2)
+    const void	*s1;
+    const void	*s2;
+{
+    char    *p1;
+    char    *p2;
+
+    p1 = *(char **)s1 + strlen(*(char **)s1) + 1;
+    p2 = *(char **)s2 + strlen(*(char **)s2) + 1;
+    return strcmp(p1, p2);
+}
+
+/*
+ * Find all help tags matching "arg", sort them and return in matches[], with
+ * the number of matches in num_matches.
+ * The matches will be sorted with a "best" match algorithm.
+ * When "keep_lang" is TRUE try keeping the language of the current buffer.
+ */
+    int
+find_help_tags(arg, num_matches, matches, keep_lang)
+    char_u	*arg;
+    int		*num_matches;
+    char_u	***matches;
+    int		keep_lang;
+{
+    char_u	*s, *d;
+    int		i;
+    static char *(mtable[]) = {"*", "g*", "[*", "]*", ":*",
+			       "/*", "/\\*", "\"*", "**",
+			       "/\\(\\)",
+			       "?", ":?", "?<CR>", "g?", "g?g?", "g??", "z?",
+			       "/\\?", "/\\z(\\)", "\\=", ":s\\=",
+			       "[count]", "[quotex]", "[range]",
+			       "[pattern]", "\\|", "\\%$"};
+    static char *(rtable[]) = {"star", "gstar", "[star", "]star", ":star",
+			       "/star", "/\\\\star", "quotestar", "starstar",
+			       "/\\\\(\\\\)",
+			       "?", ":?", "?<CR>", "g?", "g?g?", "g??", "z?",
+			       "/\\\\?", "/\\\\z(\\\\)", "\\\\=", ":s\\\\=",
+			       "\\[count]", "\\[quotex]", "\\[range]",
+			       "\\[pattern]", "\\\\bar", "/\\\\%\\$"};
+    int flags;
+
+    d = IObuff;		    /* assume IObuff is long enough! */
+
+    /*
+     * Recognize a few exceptions to the rule.	Some strings that contain '*'
+     * with "star".  Otherwise '*' is recognized as a wildcard.
+     */
+    for (i = sizeof(mtable) / sizeof(char *); --i >= 0; )
+	if (STRCMP(arg, mtable[i]) == 0)
+	{
+	    STRCPY(d, rtable[i]);
+	    break;
+	}
+
+    if (i < 0)	/* no match in table */
+    {
+	/* Replace "\S" with "/\\S", etc.  Otherwise every tag is matched.
+	 * Also replace "\%^" and "\%(", they match every tag too.
+	 * Also "\zs", "\z1", etc.
+	 * Also "\@<", "\@=", "\@<=", etc.
+	 * And also "\_$" and "\_^". */
+	if (arg[0] == '\\'
+		&& ((arg[1] != NUL && arg[2] == NUL)
+		    || (vim_strchr((char_u *)"%_z@", arg[1]) != NULL
+							   && arg[2] != NUL)))
+	{
+	    STRCPY(d, "/\\\\");
+	    STRCPY(d + 3, arg + 1);
+	    /* Check for "/\\_$", should be "/\\_\$" */
+	    if (d[3] == '_' && d[4] == '$')
+		STRCPY(d + 4, "\\$");
+	}
+	else
+	{
+	  /* replace "[:...:]" with "\[:...:]"; "[+...]" with "\[++...]" */
+	    if (arg[0] == '[' && (arg[1] == ':'
+					 || (arg[1] == '+' && arg[2] == '+')))
+	      *d++ = '\\';
+
+	  for (s = arg; *s; ++s)
+	  {
+	    /*
+	     * Replace "|" with "bar" and '"' with "quote" to match the name of
+	     * the tags for these commands.
+	     * Replace "*" with ".*" and "?" with "." to match command line
+	     * completion.
+	     * Insert a backslash before '~', '$' and '.' to avoid their
+	     * special meaning.
+	     */
+	    if (d - IObuff > IOSIZE - 10)	/* getting too long!? */
+		break;
+	    switch (*s)
+	    {
+		case '|':   STRCPY(d, "bar");
+			    d += 3;
+			    continue;
+		case '"':   STRCPY(d, "quote");
+			    d += 5;
+			    continue;
+		case '*':   *d++ = '.';
+			    break;
+		case '?':   *d++ = '.';
+			    continue;
+		case '$':
+		case '.':
+		case '~':   *d++ = '\\';
+			    break;
+	    }
+
+	    /*
+	     * Replace "^x" by "CTRL-X". Don't do this for "^_" to make
+	     * ":help i_^_CTRL-D" work.
+	     * Insert '-' before and after "CTRL-X" when applicable.
+	     */
+	    if (*s < ' ' || (*s == '^' && s[1] && (ASCII_ISALPHA(s[1])
+			   || vim_strchr((char_u *)"?@[\\]^", s[1]) != NULL)))
+	    {
+		if (d > IObuff && d[-1] != '_')
+		    *d++ = '_';		/* prepend a '_' */
+		STRCPY(d, "CTRL-");
+		d += 5;
+		if (*s < ' ')
+		{
+#ifdef EBCDIC
+		    *d++ = CtrlChar(*s);
+#else
+		    *d++ = *s + '@';
+#endif
+		    if (d[-1] == '\\')
+			*d++ = '\\';	/* double a backslash */
+		}
+		else
+		    *d++ = *++s;
+		if (s[1] != NUL && s[1] != '_')
+		    *d++ = '_';		/* append a '_' */
+		continue;
+	    }
+	    else if (*s == '^')		/* "^" or "CTRL-^" or "^_" */
+		*d++ = '\\';
+
+	    /*
+	     * Insert a backslash before a backslash after a slash, for search
+	     * pattern tags: "/\|" --> "/\\|".
+	     */
+	    else if (s[0] == '\\' && s[1] != '\\'
+					       && *arg == '/' && s == arg + 1)
+		*d++ = '\\';
+
+	    /* "CTRL-\_" -> "CTRL-\\_" to avoid the special meaning of "\_" in
+	     * "CTRL-\_CTRL-N" */
+	    if (STRNICMP(s, "CTRL-\\_", 7) == 0)
+	    {
+		STRCPY(d, "CTRL-\\\\");
+		d += 7;
+		s += 6;
+	    }
+
+	    *d++ = *s;
+
+	    /*
+	     * If tag starts with ', toss everything after a second '. Fixes
+	     * CTRL-] on 'option'. (would include the trailing '.').
+	     */
+	    if (*s == '\'' && s > arg && *arg == '\'')
+		break;
+	  }
+	  *d = NUL;
+	}
+    }
+
+    *matches = (char_u **)"";
+    *num_matches = 0;
+    flags = TAG_HELP | TAG_REGEXP | TAG_NAMES | TAG_VERBOSE;
+    if (keep_lang)
+	flags |= TAG_KEEP_LANG;
+    if (find_tags(IObuff, num_matches, matches, flags, (int)MAXCOL, NULL) == OK
+	    && *num_matches > 0)
+	/* Sort the matches found on the heuristic number that is after the
+	 * tag name. */
+	qsort((void *)*matches, (size_t)*num_matches,
+					      sizeof(char_u *), help_compare);
+    return OK;
+}
+
+/*
+ * After reading a help file: May cleanup a help buffer when syntax
+ * highlighting is not used.
+ */
+    void
+fix_help_buffer()
+{
+    linenr_T	lnum;
+    char_u	*line;
+    int		in_example = FALSE;
+    int		len;
+    char_u	*p;
+    char_u	*rt;
+    int		mustfree;
+
+    /* set filetype to "help". */
+    set_option_value((char_u *)"ft", 0L, (char_u *)"help", OPT_LOCAL);
+
+#ifdef FEAT_SYN_HL
+    if (!syntax_present(curbuf))
+#endif
+    {
+	for (lnum = 1; lnum <= curbuf->b_ml.ml_line_count; ++lnum)
+	{
+	    line = ml_get_buf(curbuf, lnum, FALSE);
+	    len = (int)STRLEN(line);
+	    if (in_example && len > 0 && !vim_iswhite(line[0]))
+	    {
+		/* End of example: non-white or '<' in first column. */
+		if (line[0] == '<')
+		{
+		    /* blank-out a '<' in the first column */
+		    line = ml_get_buf(curbuf, lnum, TRUE);
+		    line[0] = ' ';
+		}
+		in_example = FALSE;
+	    }
+	    if (!in_example && len > 0)
+	    {
+		if (line[len - 1] == '>' && (len == 1 || line[len - 2] == ' '))
+		{
+		    /* blank-out a '>' in the last column (start of example) */
+		    line = ml_get_buf(curbuf, lnum, TRUE);
+		    line[len - 1] = ' ';
+		    in_example = TRUE;
+		}
+		else if (line[len - 1] == '~')
+		{
+		    /* blank-out a '~' at the end of line (header marker) */
+		    line = ml_get_buf(curbuf, lnum, TRUE);
+		    line[len - 1] = ' ';
+		}
+	    }
+	}
+    }
+
+    /*
+     * In the "help.txt" file, add the locally added help files.
+     * This uses the very first line in the help file.
+     */
+    if (fnamecmp(gettail(curbuf->b_fname), "help.txt") == 0)
+    {
+	for (lnum = 1; lnum < curbuf->b_ml.ml_line_count; ++lnum)
+	{
+	    line = ml_get_buf(curbuf, lnum, FALSE);
+	    if (strstr((char *)line, "*local-additions*") != NULL)
+	    {
+		/* Go through all directories in 'runtimepath', skipping
+		 * $VIMRUNTIME. */
+		p = p_rtp;
+		while (*p != NUL)
+		{
+		    copy_option_part(&p, NameBuff, MAXPATHL, ",");
+		    mustfree = FALSE;
+		    rt = vim_getenv((char_u *)"VIMRUNTIME", &mustfree);
+		    if (fullpathcmp(rt, NameBuff, FALSE) != FPC_SAME)
+		    {
+			int	fcount;
+			char_u	**fnames;
+			FILE	*fd;
+			char_u	*s;
+			int	fi;
+#ifdef FEAT_MBYTE
+			vimconv_T	vc;
+			char_u		*cp;
+#endif
+
+			/* Find all "doc/ *.txt" files in this directory. */
+			add_pathsep(NameBuff);
+			STRCAT(NameBuff, "doc/*.txt");
+			if (gen_expand_wildcards(1, &NameBuff, &fcount,
+					     &fnames, EW_FILE|EW_SILENT) == OK
+				&& fcount > 0)
+			{
+			    for (fi = 0; fi < fcount; ++fi)
+			    {
+				fd = mch_fopen((char *)fnames[fi], "r");
+				if (fd != NULL)
+				{
+				    vim_fgets(IObuff, IOSIZE, fd);
+				    if (IObuff[0] == '*'
+					    && (s = vim_strchr(IObuff + 1, '*'))
+								      != NULL)
+				    {
+#ifdef FEAT_MBYTE
+					int	this_utf = MAYBE;
+#endif
+					/* Change tag definition to a
+					 * reference and remove <CR>/<NL>. */
+					IObuff[0] = '|';
+					*s = '|';
+					while (*s != NUL)
+					{
+					    if (*s == '\r' || *s == '\n')
+						*s = NUL;
+#ifdef FEAT_MBYTE
+					    /* The text is utf-8 when a byte
+					     * above 127 is found and no
+					     * illegal byte sequence is found.
+					     */
+					    if (*s >= 0x80 && this_utf != FALSE)
+					    {
+						int	l;
+
+						this_utf = TRUE;
+						l = utf_ptr2len(s);
+						if (l == 1)
+						    this_utf = FALSE;
+						s += l - 1;
+					    }
+#endif
+					    ++s;
+					}
+#ifdef FEAT_MBYTE
+					/* The help file is latin1 or utf-8;
+					 * conversion to the current
+					 * 'encoding' may be required. */
+					vc.vc_type = CONV_NONE;
+					convert_setup(&vc, (char_u *)(
+						    this_utf == TRUE ? "utf-8"
+							  : "latin1"), p_enc);
+					if (vc.vc_type == CONV_NONE)
+					    /* No conversion needed. */
+					    cp = IObuff;
+					else
+					{
+					    /* Do the conversion.  If it fails
+					     * use the unconverted text. */
+					    cp = string_convert(&vc, IObuff,
+									NULL);
+					    if (cp == NULL)
+						cp = IObuff;
+					}
+					convert_setup(&vc, NULL, NULL);
+
+					ml_append(lnum, cp, (colnr_T)0, FALSE);
+					if (cp != IObuff)
+					    vim_free(cp);
+#else
+					ml_append(lnum, IObuff, (colnr_T)0,
+								       FALSE);
+#endif
+					++lnum;
+				    }
+				    fclose(fd);
+				}
+			    }
+			    FreeWild(fcount, fnames);
+			}
+		    }
+		    if (mustfree)
+			vim_free(rt);
+		}
+		break;
+	    }
+	}
+    }
+}
+
+/*
+ * ":exusage"
+ */
+/*ARGSUSED*/
+    void
+ex_exusage(eap)
+    exarg_T	*eap;
+{
+    do_cmdline_cmd((char_u *)"help ex-cmd-index");
+}
+
+/*
+ * ":viusage"
+ */
+/*ARGSUSED*/
+    void
+ex_viusage(eap)
+    exarg_T	*eap;
+{
+    do_cmdline_cmd((char_u *)"help normal-index");
+}
+
+#if defined(FEAT_EX_EXTRA) || defined(PROTO)
+static void helptags_one __ARGS((char_u *dir, char_u *ext, char_u *lang));
+
+/*
+ * ":helptags"
+ */
+    void
+ex_helptags(eap)
+    exarg_T	*eap;
+{
+    garray_T	ga;
+    int		i, j;
+    int		len;
+#ifdef FEAT_MULTI_LANG
+    char_u	lang[2];
+#endif
+    char_u	ext[5];
+    char_u	fname[8];
+    int		filecount;
+    char_u	**files;
+
+    if (!mch_isdir(eap->arg))
+    {
+	EMSG2(_("E150: Not a directory: %s"), eap->arg);
+	return;
+    }
+
+#ifdef FEAT_MULTI_LANG
+    /* Get a list of all files in the directory. */
+    STRCPY(NameBuff, eap->arg);
+    add_pathsep(NameBuff);
+    STRCAT(NameBuff, "*");
+    if (gen_expand_wildcards(1, &NameBuff, &filecount, &files,
+						    EW_FILE|EW_SILENT) == FAIL
+	    || filecount == 0)
+    {
+	EMSG2("E151: No match: %s", NameBuff);
+	return;
+    }
+
+    /* Go over all files in the directory to find out what languages are
+     * present. */
+    ga_init2(&ga, 1, 10);
+    for (i = 0; i < filecount; ++i)
+    {
+	len = (int)STRLEN(files[i]);
+	if (len > 4)
+	{
+	    if (STRICMP(files[i] + len - 4, ".txt") == 0)
+	    {
+		/* ".txt" -> language "en" */
+		lang[0] = 'e';
+		lang[1] = 'n';
+	    }
+	    else if (files[i][len - 4] == '.'
+		    && ASCII_ISALPHA(files[i][len - 3])
+		    && ASCII_ISALPHA(files[i][len - 2])
+		    && TOLOWER_ASC(files[i][len - 1]) == 'x')
+	    {
+		/* ".abx" -> language "ab" */
+		lang[0] = TOLOWER_ASC(files[i][len - 3]);
+		lang[1] = TOLOWER_ASC(files[i][len - 2]);
+	    }
+	    else
+		continue;
+
+	    /* Did we find this language already? */
+	    for (j = 0; j < ga.ga_len; j += 2)
+		if (STRNCMP(lang, ((char_u *)ga.ga_data) + j, 2) == 0)
+		    break;
+	    if (j == ga.ga_len)
+	    {
+		/* New language, add it. */
+		if (ga_grow(&ga, 2) == FAIL)
+		    break;
+		((char_u *)ga.ga_data)[ga.ga_len++] = lang[0];
+		((char_u *)ga.ga_data)[ga.ga_len++] = lang[1];
+	    }
+	}
+    }
+
+    /*
+     * Loop over the found languages to generate a tags file for each one.
+     */
+    for (j = 0; j < ga.ga_len; j += 2)
+    {
+	STRCPY(fname, "tags-xx");
+	fname[5] = ((char_u *)ga.ga_data)[j];
+	fname[6] = ((char_u *)ga.ga_data)[j + 1];
+	if (fname[5] == 'e' && fname[6] == 'n')
+	{
+	    /* English is an exception: use ".txt" and "tags". */
+	    fname[4] = NUL;
+	    STRCPY(ext, ".txt");
+	}
+	else
+	{
+	    /* Language "ab" uses ".abx" and "tags-ab". */
+	    STRCPY(ext, ".xxx");
+	    ext[1] = fname[5];
+	    ext[2] = fname[6];
+	}
+	helptags_one(eap->arg, ext, fname);
+    }
+
+    ga_clear(&ga);
+    FreeWild(filecount, files);
+
+#else
+    /* No language support, just use "*.txt" and "tags". */
+    helptags_one(eap->arg, (char_u *)".txt", (char_u *)"tags");
+#endif
+}
+
+    static void
+helptags_one(dir, ext, tagfname)
+    char_u	*dir;	    /* doc directory */
+    char_u	*ext;	    /* suffix, ".txt", ".itx", ".frx", etc. */
+    char_u	*tagfname;    /* "tags" for English, "tags-it" for Italian. */
+{
+    FILE	*fd_tags;
+    FILE	*fd;
+    garray_T	ga;
+    int		filecount;
+    char_u	**files;
+    char_u	*p1, *p2;
+    int		fi;
+    char_u	*s;
+    int		i;
+    char_u	*fname;
+# ifdef FEAT_MBYTE
+    int		utf8 = MAYBE;
+    int		this_utf8;
+    int		firstline;
+    int		mix = FALSE;	/* detected mixed encodings */
+# endif
+
+    /*
+     * Find all *.txt files.
+     */
+    STRCPY(NameBuff, dir);
+    add_pathsep(NameBuff);
+    STRCAT(NameBuff, "*");
+    STRCAT(NameBuff, ext);
+    if (gen_expand_wildcards(1, &NameBuff, &filecount, &files,
+						    EW_FILE|EW_SILENT) == FAIL
+	    || filecount == 0)
+    {
+	if (!got_int)
+	    EMSG2("E151: No match: %s", NameBuff);
+	return;
+    }
+
+    /*
+     * Open the tags file for writing.
+     * Do this before scanning through all the files.
+     */
+    STRCPY(NameBuff, dir);
+    add_pathsep(NameBuff);
+    STRCAT(NameBuff, tagfname);
+    fd_tags = mch_fopen((char *)NameBuff, "w");
+    if (fd_tags == NULL)
+    {
+	EMSG2(_("E152: Cannot open %s for writing"), NameBuff);
+	FreeWild(filecount, files);
+	return;
+    }
+
+    /*
+     * If generating tags for "$VIMRUNTIME/doc" add the "help-tags" tag.
+     */
+    ga_init2(&ga, (int)sizeof(char_u *), 100);
+    if (fullpathcmp((char_u *)"$VIMRUNTIME/doc", dir, FALSE) == FPC_SAME)
+    {
+	if (ga_grow(&ga, 1) == FAIL)
+	    got_int = TRUE;
+	else
+	{
+	    s = alloc(18 + (unsigned)STRLEN(tagfname));
+	    if (s == NULL)
+		got_int = TRUE;
+	    else
+	    {
+		sprintf((char *)s, "help-tags\t%s\t1\n", tagfname);
+		((char_u **)ga.ga_data)[ga.ga_len] = s;
+		++ga.ga_len;
+	    }
+	}
+    }
+
+    /*
+     * Go over all the files and extract the tags.
+     */
+    for (fi = 0; fi < filecount && !got_int; ++fi)
+    {
+	fd = mch_fopen((char *)files[fi], "r");
+	if (fd == NULL)
+	{
+	    EMSG2(_("E153: Unable to open %s for reading"), files[fi]);
+	    continue;
+	}
+	fname = gettail(files[fi]);
+
+# ifdef FEAT_MBYTE
+	firstline = TRUE;
+# endif
+	while (!vim_fgets(IObuff, IOSIZE, fd) && !got_int)
+	{
+# ifdef FEAT_MBYTE
+	    if (firstline)
+	    {
+		/* Detect utf-8 file by a non-ASCII char in the first line. */
+		this_utf8 = MAYBE;
+		for (s = IObuff; *s != NUL; ++s)
+		    if (*s >= 0x80)
+		    {
+			int l;
+
+			this_utf8 = TRUE;
+			l = utf_ptr2len(s);
+			if (l == 1)
+			{
+			    /* Illegal UTF-8 byte sequence. */
+			    this_utf8 = FALSE;
+			    break;
+			}
+			s += l - 1;
+		    }
+		if (this_utf8 == MAYBE)	    /* only ASCII characters found */
+		    this_utf8 = FALSE;
+		if (utf8 == MAYBE)	    /* first file */
+		    utf8 = this_utf8;
+		else if (utf8 != this_utf8)
+		{
+		    EMSG2(_("E670: Mix of help file encodings within a language: %s"), files[fi]);
+		    mix = !got_int;
+		    got_int = TRUE;
+		}
+		firstline = FALSE;
+	    }
+# endif
+	    p1 = vim_strchr(IObuff, '*');	/* find first '*' */
+	    while (p1 != NULL)
+	    {
+		p2 = vim_strchr(p1 + 1, '*');	/* find second '*' */
+		if (p2 != NULL && p2 > p1 + 1)	/* skip "*" and "**" */
+		{
+		    for (s = p1 + 1; s < p2; ++s)
+			if (*s == ' ' || *s == '\t' || *s == '|')
+			    break;
+
+		    /*
+		     * Only accept a *tag* when it consists of valid
+		     * characters, there is white space before it and is
+		     * followed by a white character or end-of-line.
+		     */
+		    if (s == p2
+			    && (p1 == IObuff || p1[-1] == ' ' || p1[-1] == '\t')
+			    && (vim_strchr((char_u *)" \t\n\r", s[1]) != NULL
+				|| s[1] == '\0'))
+		    {
+			*p2 = '\0';
+			++p1;
+			if (ga_grow(&ga, 1) == FAIL)
+			{
+			    got_int = TRUE;
+			    break;
+			}
+			s = alloc((unsigned)(p2 - p1 + STRLEN(fname) + 2));
+			if (s == NULL)
+			{
+			    got_int = TRUE;
+			    break;
+			}
+			((char_u **)ga.ga_data)[ga.ga_len] = s;
+			++ga.ga_len;
+			sprintf((char *)s, "%s\t%s", p1, fname);
+
+			/* find next '*' */
+			p2 = vim_strchr(p2 + 1, '*');
+		    }
+		}
+		p1 = p2;
+	    }
+	    line_breakcheck();
+	}
+
+	fclose(fd);
+    }
+
+    FreeWild(filecount, files);
+
+    if (!got_int)
+    {
+	/*
+	 * Sort the tags.
+	 */
+	sort_strings((char_u **)ga.ga_data, ga.ga_len);
+
+	/*
+	 * Check for duplicates.
+	 */
+	for (i = 1; i < ga.ga_len; ++i)
+	{
+	    p1 = ((char_u **)ga.ga_data)[i - 1];
+	    p2 = ((char_u **)ga.ga_data)[i];
+	    while (*p1 == *p2)
+	    {
+		if (*p2 == '\t')
+		{
+		    *p2 = NUL;
+		    vim_snprintf((char *)NameBuff, MAXPATHL,
+			    _("E154: Duplicate tag \"%s\" in file %s/%s"),
+				     ((char_u **)ga.ga_data)[i], dir, p2 + 1);
+		    EMSG(NameBuff);
+		    *p2 = '\t';
+		    break;
+		}
+		++p1;
+		++p2;
+	    }
+	}
+
+# ifdef FEAT_MBYTE
+	if (utf8 == TRUE)
+	    fprintf(fd_tags, "!_TAG_FILE_ENCODING\tutf-8\t//\n");
+# endif
+
+	/*
+	 * Write the tags into the file.
+	 */
+	for (i = 0; i < ga.ga_len; ++i)
+	{
+	    s = ((char_u **)ga.ga_data)[i];
+	    if (STRNCMP(s, "help-tags", 9) == 0)
+		/* help-tags entry was added in formatted form */
+		fprintf(fd_tags, (char *)s);
+	    else
+	    {
+		fprintf(fd_tags, "%s\t/*", s);
+		for (p1 = s; *p1 != '\t'; ++p1)
+		{
+		    /* insert backslash before '\\' and '/' */
+		    if (*p1 == '\\' || *p1 == '/')
+			putc('\\', fd_tags);
+		    putc(*p1, fd_tags);
+		}
+		fprintf(fd_tags, "*\n");
+	    }
+	}
+    }
+#ifdef FEAT_MBYTE
+    if (mix)
+	got_int = FALSE;    /* continue with other languages */
+#endif
+
+    for (i = 0; i < ga.ga_len; ++i)
+	vim_free(((char_u **)ga.ga_data)[i]);
+    ga_clear(&ga);
+    fclose(fd_tags);	    /* there is no check for an error... */
+}
+#endif
+
+#if defined(FEAT_SIGNS) || defined(PROTO)
+
+/*
+ * Struct to hold the sign properties.
+ */
+typedef struct sign sign_T;
+
+struct sign
+{
+    sign_T	*sn_next;	/* next sign in list */
+    int		sn_typenr;	/* type number of sign (negative if not equal
+				   to name) */
+    char_u	*sn_name;	/* name of sign */
+    char_u	*sn_icon;	/* name of pixmap */
+#ifdef FEAT_SIGN_ICONS
+    void	*sn_image;	/* icon image */
+#endif
+    char_u	*sn_text;	/* text used instead of pixmap */
+    int		sn_line_hl;	/* highlight ID for line */
+    int		sn_text_hl;	/* highlight ID for text */
+};
+
+static sign_T	*first_sign = NULL;
+static int	last_sign_typenr = MAX_TYPENR;	/* is decremented */
+
+static void sign_list_defined __ARGS((sign_T *sp));
+
+/*
+ * ":sign" command
+ */
+    void
+ex_sign(eap)
+    exarg_T	*eap;
+{
+    char_u	*arg = eap->arg;
+    char_u	*p;
+    int		idx;
+    sign_T	*sp;
+    sign_T	*sp_prev;
+    buf_T	*buf;
+    static char	*cmds[] = {
+			"define",
+#define SIGNCMD_DEFINE	0
+			"undefine",
+#define SIGNCMD_UNDEFINE 1
+			"list",
+#define SIGNCMD_LIST	2
+			"place",
+#define SIGNCMD_PLACE	3
+			"unplace",
+#define SIGNCMD_UNPLACE	4
+			"jump",
+#define SIGNCMD_JUMP	5
+#define SIGNCMD_LAST	6
+    };
+
+    /* Parse the subcommand. */
+    p = skiptowhite(arg);
+    if (*p != NUL)
+	*p++ = NUL;
+    for (idx = 0; ; ++idx)
+    {
+	if (idx == SIGNCMD_LAST)
+	{
+	    EMSG2(_("E160: Unknown sign command: %s"), arg);
+	    return;
+	}
+	if (STRCMP(arg, cmds[idx]) == 0)
+	    break;
+    }
+    arg = skipwhite(p);
+
+    if (idx <= SIGNCMD_LIST)
+    {
+	/*
+	 * Define, undefine or list signs.
+	 */
+	if (idx == SIGNCMD_LIST && *arg == NUL)
+	{
+	    /* ":sign list": list all defined signs */
+	    for (sp = first_sign; sp != NULL; sp = sp->sn_next)
+		sign_list_defined(sp);
+	}
+	else if (*arg == NUL)
+	    EMSG(_("E156: Missing sign name"));
+	else
+	{
+	    p = skiptowhite(arg);
+	    if (*p != NUL)
+		*p++ = NUL;
+	    sp_prev = NULL;
+	    for (sp = first_sign; sp != NULL; sp = sp->sn_next)
+	    {
+		if (STRCMP(sp->sn_name, arg) == 0)
+		    break;
+		sp_prev = sp;
+	    }
+	    if (idx == SIGNCMD_DEFINE)
+	    {
+		/* ":sign define {name} ...": define a sign */
+		if (sp == NULL)
+		{
+		    /* Allocate a new sign. */
+		    sp = (sign_T *)alloc_clear((unsigned)sizeof(sign_T));
+		    if (sp == NULL)
+			return;
+		    if (sp_prev == NULL)
+			first_sign = sp;
+		    else
+			sp_prev->sn_next = sp;
+		    sp->sn_name = vim_strnsave(arg, (int)(p - arg));
+
+		    /* If the name is a number use that for the typenr,
+		     * otherwise use a negative number. */
+		    if (VIM_ISDIGIT(*arg))
+			sp->sn_typenr = atoi((char *)arg);
+		    else
+		    {
+			sign_T	*lp;
+			int	start = last_sign_typenr;
+
+			for (lp = first_sign; lp != NULL; lp = lp->sn_next)
+			{
+			    if (lp->sn_typenr == last_sign_typenr)
+			    {
+				--last_sign_typenr;
+				if (last_sign_typenr == 0)
+				    last_sign_typenr = MAX_TYPENR;
+				if (last_sign_typenr == start)
+				{
+				    EMSG(_("E612: Too many signs defined"));
+				    return;
+				}
+				lp = first_sign;
+				continue;
+			    }
+			}
+
+			sp->sn_typenr = last_sign_typenr--;
+			if (last_sign_typenr == 0)
+			    last_sign_typenr = MAX_TYPENR; /* wrap around */
+		    }
+		}
+
+		/* set values for a defined sign. */
+		for (;;)
+		{
+		    arg = skipwhite(p);
+		    if (*arg == NUL)
+			break;
+		    p = skiptowhite_esc(arg);
+		    if (STRNCMP(arg, "icon=", 5) == 0)
+		    {
+			arg += 5;
+			vim_free(sp->sn_icon);
+			sp->sn_icon = vim_strnsave(arg, (int)(p - arg));
+			backslash_halve(sp->sn_icon);
+#ifdef FEAT_SIGN_ICONS
+			if (gui.in_use)
+			{
+			    out_flush();
+			    if (sp->sn_image != NULL)
+				gui_mch_destroy_sign(sp->sn_image);
+			    sp->sn_image = gui_mch_register_sign(sp->sn_icon);
+			}
+#endif
+		    }
+		    else if (STRNCMP(arg, "text=", 5) == 0)
+		    {
+			char_u	*s;
+			int	cells;
+			int	len;
+
+			arg += 5;
+#ifdef FEAT_MBYTE
+			/* Count cells and check for non-printable chars */
+			if (has_mbyte)
+			{
+			    cells = 0;
+			    for (s = arg; s < p; s += (*mb_ptr2len)(s))
+			    {
+				if (!vim_isprintc((*mb_ptr2char)(s)))
+				    break;
+				cells += (*mb_ptr2cells)(s);
+			    }
+			}
+			else
+#endif
+			{
+			    for (s = arg; s < p; ++s)
+				if (!vim_isprintc(*s))
+				    break;
+			    cells = (int)(s - arg);
+			}
+			/* Currently must be one or two display cells */
+			if (s != p || cells < 1 || cells > 2)
+			{
+			    *p = NUL;
+			    EMSG2(_("E239: Invalid sign text: %s"), arg);
+			    return;
+			}
+
+			vim_free(sp->sn_text);
+			/* Allocate one byte more if we need to pad up
+			 * with a space. */
+			len = (int)(p - arg + ((cells == 1) ? 1 : 0));
+			sp->sn_text = vim_strnsave(arg, len);
+
+			if (sp->sn_text != NULL && cells == 1)
+			    STRCPY(sp->sn_text + len - 1, " ");
+		    }
+		    else if (STRNCMP(arg, "linehl=", 7) == 0)
+		    {
+			arg += 7;
+			sp->sn_line_hl = syn_check_group(arg, (int)(p - arg));
+		    }
+		    else if (STRNCMP(arg, "texthl=", 7) == 0)
+		    {
+			arg += 7;
+			sp->sn_text_hl = syn_check_group(arg, (int)(p - arg));
+		    }
+		    else
+		    {
+			EMSG2(_(e_invarg2), arg);
+			return;
+		    }
+		}
+	    }
+	    else if (sp == NULL)
+		EMSG2(_("E155: Unknown sign: %s"), arg);
+	    else if (idx == SIGNCMD_LIST)
+		/* ":sign list {name}" */
+		sign_list_defined(sp);
+	    else
+	    {
+		/* ":sign undefine {name}" */
+		vim_free(sp->sn_name);
+		vim_free(sp->sn_icon);
+#ifdef FEAT_SIGN_ICONS
+		if (sp->sn_image != NULL)
+		{
+		    out_flush();
+		    gui_mch_destroy_sign(sp->sn_image);
+		}
+#endif
+		vim_free(sp->sn_text);
+		if (sp_prev == NULL)
+		    first_sign = sp->sn_next;
+		else
+		    sp_prev->sn_next = sp->sn_next;
+		vim_free(sp);
+	    }
+	}
+    }
+    else
+    {
+	int		id = -1;
+	linenr_T	lnum = -1;
+	char_u		*sign_name = NULL;
+	char_u		*arg1;
+
+	if (*arg == NUL)
+	{
+	    if (idx == SIGNCMD_PLACE)
+	    {
+		/* ":sign place": list placed signs in all buffers */
+		sign_list_placed(NULL);
+	    }
+	    else if (idx == SIGNCMD_UNPLACE)
+	    {
+		/* ":sign unplace": remove placed sign at cursor */
+		id = buf_findsign_id(curwin->w_buffer, curwin->w_cursor.lnum);
+		if (id > 0)
+		{
+		    buf_delsign(curwin->w_buffer, id);
+		    update_debug_sign(curwin->w_buffer, curwin->w_cursor.lnum);
+		}
+		else
+		    EMSG(_("E159: Missing sign number"));
+	    }
+	    else
+		EMSG(_(e_argreq));
+	    return;
+	}
+
+	if (idx == SIGNCMD_UNPLACE && arg[0] == '*' && arg[1] == NUL)
+	{
+	    /* ":sign unplace *": remove all placed signs */
+	    buf_delete_all_signs();
+	    return;
+	}
+
+	/* first arg could be placed sign id */
+	arg1 = arg;
+	if (VIM_ISDIGIT(*arg))
+	{
+	    id = getdigits(&arg);
+	    if (!vim_iswhite(*arg) && *arg != NUL)
+	    {
+		id = -1;
+		arg = arg1;
+	    }
+	    else
+	    {
+		arg = skipwhite(arg);
+		if (idx == SIGNCMD_UNPLACE && *arg == NUL)
+		{
+		    /* ":sign unplace {id}": remove placed sign by number */
+		    for (buf = firstbuf; buf != NULL; buf = buf->b_next)
+			if ((lnum = buf_delsign(buf, id)) != 0)
+			    update_debug_sign(buf, lnum);
+		    return;
+		}
+	    }
+	}
+
+	/*
+	 * Check for line={lnum} name={name} and file={fname} or buffer={nr}.
+	 * Leave "arg" pointing to {fname}.
+	 */
+	for (;;)
+	{
+	    if (STRNCMP(arg, "line=", 5) == 0)
+	    {
+		arg += 5;
+		lnum = atoi((char *)arg);
+		arg = skiptowhite(arg);
+	    }
+	    else if (STRNCMP(arg, "name=", 5) == 0)
+	    {
+		arg += 5;
+		sign_name = arg;
+		arg = skiptowhite(arg);
+		if (*arg != NUL)
+		    *arg++ = NUL;
+	    }
+	    else if (STRNCMP(arg, "file=", 5) == 0)
+	    {
+		arg += 5;
+		buf = buflist_findname(arg);
+		break;
+	    }
+	    else if (STRNCMP(arg, "buffer=", 7) == 0)
+	    {
+		arg += 7;
+		buf = buflist_findnr((int)getdigits(&arg));
+		if (*skipwhite(arg) != NUL)
+		    EMSG(_(e_trailing));
+		break;
+	    }
+	    else
+	    {
+		EMSG(_(e_invarg));
+		return;
+	    }
+	    arg = skipwhite(arg);
+	}
+
+	if (buf == NULL)
+	{
+	    EMSG2(_("E158: Invalid buffer name: %s"), arg);
+	}
+	else if (id <= 0)
+	{
+	    if (lnum >= 0 || sign_name != NULL)
+		EMSG(_(e_invarg));
+	    else
+		/* ":sign place file={fname}": list placed signs in one file */
+		sign_list_placed(buf);
+	}
+	else if (idx == SIGNCMD_JUMP)
+	{
+	    /* ":sign jump {id} file={fname}" */
+	    if (lnum >= 0 || sign_name != NULL)
+		EMSG(_(e_invarg));
+	    else if ((lnum = buf_findsign(buf, id)) > 0)
+	    {				/* goto a sign ... */
+		if (buf_jump_open_win(buf) != NULL)
+		{			/* ... in a current window */
+		    curwin->w_cursor.lnum = lnum;
+		    check_cursor_lnum();
+		    beginline(BL_WHITE);
+		}
+		else
+		{			/* ... not currently in a window */
+		    char_u	*cmd;
+
+		    cmd = alloc((unsigned)STRLEN(buf->b_fname) + 25);
+		    if (cmd == NULL)
+			return;
+		    sprintf((char *)cmd, "e +%ld %s", (long)lnum, buf->b_fname);
+		    do_cmdline_cmd(cmd);
+		    vim_free(cmd);
+		}
+#ifdef FEAT_FOLDING
+		foldOpenCursor();
+#endif
+	    }
+	    else
+		EMSGN(_("E157: Invalid sign ID: %ld"), id);
+	}
+	else if (idx == SIGNCMD_UNPLACE)
+	{
+	    /* ":sign unplace {id} file={fname}" */
+	    if (lnum >= 0 || sign_name != NULL)
+		EMSG(_(e_invarg));
+	    else
+	    {
+		lnum = buf_delsign(buf, id);
+		update_debug_sign(buf, lnum);
+	    }
+	}
+	    /* idx == SIGNCMD_PLACE */
+	else if (sign_name != NULL)
+	{
+	    for (sp = first_sign; sp != NULL; sp = sp->sn_next)
+		if (STRCMP(sp->sn_name, sign_name) == 0)
+		    break;
+	    if (sp == NULL)
+	    {
+		EMSG2(_("E155: Unknown sign: %s"), sign_name);
+		return;
+	    }
+	    if (lnum > 0)
+		/* ":sign place {id} line={lnum} name={name} file={fname}":
+		 * place a sign */
+		buf_addsign(buf, id, lnum, sp->sn_typenr);
+	    else
+		/* ":sign place {id} file={fname}": change sign type */
+		lnum = buf_change_sign_type(buf, id, sp->sn_typenr);
+	    update_debug_sign(buf, lnum);
+	}
+	else
+	    EMSG(_(e_invarg));
+    }
+}
+
+#if defined(FEAT_SIGN_ICONS) || defined(PROTO)
+/*
+ * Allocate the icons.  Called when the GUI has started.  Allows defining
+ * signs before it starts.
+ */
+    void
+sign_gui_started()
+{
+    sign_T	*sp;
+
+    for (sp = first_sign; sp != NULL; sp = sp->sn_next)
+	if (sp->sn_icon != NULL)
+	    sp->sn_image = gui_mch_register_sign(sp->sn_icon);
+}
+#endif
+
+/*
+ * List one sign.
+ */
+    static void
+sign_list_defined(sp)
+    sign_T	*sp;
+{
+    char_u	*p;
+
+    smsg((char_u *)"sign %s", sp->sn_name);
+    if (sp->sn_icon != NULL)
+    {
+	MSG_PUTS(" icon=");
+	msg_outtrans(sp->sn_icon);
+#ifdef FEAT_SIGN_ICONS
+	if (sp->sn_image == NULL)
+	    MSG_PUTS(_(" (NOT FOUND)"));
+#else
+	MSG_PUTS(_(" (not supported)"));
+#endif
+    }
+    if (sp->sn_text != NULL)
+    {
+	MSG_PUTS(" text=");
+	msg_outtrans(sp->sn_text);
+    }
+    if (sp->sn_line_hl > 0)
+    {
+	MSG_PUTS(" linehl=");
+	p = get_highlight_name(NULL, sp->sn_line_hl - 1);
+	if (p == NULL)
+	    MSG_PUTS("NONE");
+	else
+	    msg_puts(p);
+    }
+    if (sp->sn_text_hl > 0)
+    {
+	MSG_PUTS(" texthl=");
+	p = get_highlight_name(NULL, sp->sn_text_hl - 1);
+	if (p == NULL)
+	    MSG_PUTS("NONE");
+	else
+	    msg_puts(p);
+    }
+}
+
+/*
+ * Get highlighting attribute for sign "typenr".
+ * If "line" is TRUE: line highl, if FALSE: text highl.
+ */
+    int
+sign_get_attr(typenr, line)
+    int		typenr;
+    int		line;
+{
+    sign_T	*sp;
+
+    for (sp = first_sign; sp != NULL; sp = sp->sn_next)
+	if (sp->sn_typenr == typenr)
+	{
+	    if (line)
+	    {
+		if (sp->sn_line_hl > 0)
+		    return syn_id2attr(sp->sn_line_hl);
+	    }
+	    else
+	    {
+		if (sp->sn_text_hl > 0)
+		    return syn_id2attr(sp->sn_text_hl);
+	    }
+	    break;
+	}
+    return 0;
+}
+
+/*
+ * Get text mark for sign "typenr".
+ * Returns NULL if there isn't one.
+ */
+    char_u *
+sign_get_text(typenr)
+    int		typenr;
+{
+    sign_T	*sp;
+
+    for (sp = first_sign; sp != NULL; sp = sp->sn_next)
+	if (sp->sn_typenr == typenr)
+	    return sp->sn_text;
+    return NULL;
+}
+
+#if defined(FEAT_SIGN_ICONS) || defined(PROTO)
+    void *
+sign_get_image(typenr)
+    int		typenr;		/* the attribute which may have a sign */
+{
+    sign_T	*sp;
+
+    for (sp = first_sign; sp != NULL; sp = sp->sn_next)
+	if (sp->sn_typenr == typenr)
+	    return sp->sn_image;
+    return NULL;
+}
+#endif
+
+/*
+ * Get the name of a sign by its typenr.
+ */
+    char_u *
+sign_typenr2name(typenr)
+    int		typenr;
+{
+    sign_T	*sp;
+
+    for (sp = first_sign; sp != NULL; sp = sp->sn_next)
+	if (sp->sn_typenr == typenr)
+	    return sp->sn_name;
+    return (char_u *)_("[Deleted]");
+}
+
+#endif
+
+#if defined(FEAT_GUI) || defined(FEAT_CLIENTSERVER) || defined(PROTO)
+/*
+ * ":drop"
+ * Opens the first argument in a window.  When there are two or more arguments
+ * the argument list is redefined.
+ */
+    void
+ex_drop(eap)
+    exarg_T	*eap;
+{
+    int		split = FALSE;
+    win_T	*wp;
+    buf_T	*buf;
+# ifdef FEAT_WINDOWS
+    tabpage_T	*tp;
+# endif
+
+    /*
+     * Check if the first argument is already being edited in a window.  If
+     * so, jump to that window.
+     * We would actually need to check all arguments, but that's complicated
+     * and mostly only one file is dropped.
+     * This also ignores wildcards, since it is very unlikely the user is
+     * editing a file name with a wildcard character.
+     */
+    set_arglist(eap->arg);
+
+    /*
+     * Expanding wildcards may result in an empty argument list.  E.g. when
+     * editing "foo.pyc" and ".pyc" is in 'wildignore'.  Assume that we
+     * already did an error message for this.
+     */
+    if (ARGCOUNT == 0)
+	return;
+
+# ifdef FEAT_WINDOWS
+    if (cmdmod.tab)
+    {
+	/* ":tab drop file ...": open a tab for each argument that isn't
+	 * edited in a window yet.  It's like ":tab all" but without closing
+	 * windows or tabs. */
+	ex_all(eap);
+    }
+    else
+# endif
+    {
+	/* ":drop file ...": Edit the first argument.  Jump to an existing
+	 * window if possible, edit in current window if the current buffer
+	 * can be abandoned, otherwise open a new window. */
+	buf = buflist_findnr(ARGLIST[0].ae_fnum);
+
+	FOR_ALL_TAB_WINDOWS(tp, wp)
+	{
+	    if (wp->w_buffer == buf)
+	    {
+# ifdef FEAT_WINDOWS
+		goto_tabpage_win(tp, wp);
+# endif
+		curwin->w_arg_idx = 0;
+		return;
+	    }
+	}
+
+	/*
+	 * Check whether the current buffer is changed. If so, we will need
+	 * to split the current window or data could be lost.
+	 * Skip the check if the 'hidden' option is set, as in this case the
+	 * buffer won't be lost.
+	 */
+	if (!P_HID(curbuf))
+	{
+# ifdef FEAT_WINDOWS
+	    ++emsg_off;
+# endif
+	    split = check_changed(curbuf, TRUE, FALSE, FALSE, FALSE);
+# ifdef FEAT_WINDOWS
+	    --emsg_off;
+# else
+	    if (split)
+		return;
+# endif
+	}
+
+	/* Fake a ":sfirst" or ":first" command edit the first argument. */
+	if (split)
+	{
+	    eap->cmdidx = CMD_sfirst;
+	    eap->cmd[0] = 's';
+	}
+	else
+	    eap->cmdidx = CMD_first;
+	ex_rewind(eap);
+    }
+}
+#endif
--- /dev/null
+++ b/ex_cmds.h
@@ -1,0 +1,1170 @@
+/* vi:set ts=8 sts=4 sw=4:
+ *
+ * VIM - Vi IMproved	by Bram Moolenaar
+ *
+ * Do ":help uganda"  in Vim to read copying and usage conditions.
+ * Do ":help credits" in Vim to see a list of people who contributed.
+ */
+
+/*
+ * This file defines the Ex commands.
+ * When DO_DECLARE_EXCMD is defined, the table with ex command names and
+ * options results.
+ * When DO_DECLARE_EXCMD is NOT defined, the enum with all the Ex commands
+ * results.
+ * This clever trick was invented by Ron Aaron.
+ */
+
+/*
+ * When adding an Ex command:
+ * 1. Add an entry in the table below.  Keep it sorted on the shortest
+ *    version of the command name that works.  If it doesn't start with a
+ *    lower case letter, add it at the end.
+ * 2. Add a "case: CMD_xxx" in the big switch in ex_docmd.c.
+ * 3. Add an entry in the index for Ex commands at ":help ex-cmd-index".
+ * 4. Add documentation in ../doc/xxx.txt.  Add a tag for both the short and
+ *    long name of the command.
+ */
+
+#ifdef RANGE
+# undef RANGE			/* SASC on Amiga defines it */
+#endif
+
+#define RANGE		0x001	/* allow a linespecs */
+#define BANG		0x002	/* allow a ! after the command name */
+#define EXTRA		0x004	/* allow extra args after command name */
+#define XFILE		0x008	/* expand wildcards in extra part */
+#define NOSPC		0x010	/* no spaces allowed in the extra part */
+#define	DFLALL		0x020	/* default file range is 1,$ */
+#define WHOLEFOLD	0x040	/* extend range to include whole fold also
+				   when less than two numbers given */
+#define NEEDARG		0x080	/* argument required */
+#define TRLBAR		0x100	/* check for trailing vertical bar */
+#define REGSTR		0x200	/* allow "x for register designation */
+#define COUNT		0x400	/* allow count in argument, after command */
+#define NOTRLCOM	0x800	/* no trailing comment allowed */
+#define ZEROR	       0x1000	/* zero line number allowed */
+#define USECTRLV       0x2000	/* do not remove CTRL-V from argument */
+#define NOTADR	       0x4000	/* number before command is not an address */
+#define EDITCMD	       0x8000	/* allow "+command" argument */
+#define BUFNAME	      0x10000L	/* accepts buffer name */
+#define BUFUNL	      0x20000L	/* accepts unlisted buffer too */
+#define ARGOPT	      0x40000L	/* allow "++opt=val" argument */
+#define SBOXOK	      0x80000L	/* allowed in the sandbox */
+#define CMDWIN	     0x100000L	/* allowed in cmdline window */
+#define MODIFY       0x200000L  /* forbidden in non-'modifiable' buffer */
+#define EXFLAGS      0x400000L	/* allow flags after count in argument */
+#define FILES	(XFILE | EXTRA)	/* multiple extra files allowed */
+#define WORD1	(EXTRA | NOSPC)	/* one extra word allowed */
+#define FILE1	(FILES | NOSPC)	/* 1 file allowed, defaults to current file */
+
+#ifndef DO_DECLARE_EXCMD
+typedef struct exarg exarg_T;
+#endif
+
+/*
+ * This array maps ex command names to command codes.
+ * The order in which command names are listed below is significant --
+ * ambiguous abbreviations are always resolved to be the first possible match
+ * (e.g. "r" is taken to mean "read", not "rewind", because "read" comes
+ * before "rewind").
+ * Not supported commands are included to avoid ambiguities.
+ */
+#ifdef EX
+# undef EX	    /* just in case */
+#endif
+#ifdef DO_DECLARE_EXCMD
+# define EX(a, b, c, d)  {(char_u *)b, c, d}
+
+typedef void (*ex_func_T) __ARGS((exarg_T *eap));
+
+static struct cmdname
+{
+    char_u	*cmd_name;	/* name of the command */
+    ex_func_T   cmd_func;	/* function for this command */
+    long_u	cmd_argt;	/* flags declared above */
+}
+# if defined(FEAT_GUI_W16)
+_far
+# endif
+cmdnames[] =
+#else
+# define EX(a, b, c, d)  a
+enum CMD_index
+#endif
+{
+EX(CMD_append,		"append",	ex_append,
+			BANG|RANGE|ZEROR|TRLBAR|CMDWIN|MODIFY),
+EX(CMD_abbreviate,	"abbreviate",	ex_abbreviate,
+			EXTRA|TRLBAR|NOTRLCOM|USECTRLV|CMDWIN),
+EX(CMD_abclear,		"abclear",	ex_abclear,
+			EXTRA|TRLBAR|CMDWIN),
+EX(CMD_aboveleft,	"aboveleft",	ex_wrongmodifier,
+			NEEDARG|EXTRA|NOTRLCOM),
+EX(CMD_all,		"all",		ex_all,
+			RANGE|NOTADR|COUNT|TRLBAR),
+EX(CMD_amenu,		"amenu",	ex_menu,
+			RANGE|NOTADR|ZEROR|EXTRA|TRLBAR|NOTRLCOM|USECTRLV|CMDWIN),
+EX(CMD_anoremenu,	"anoremenu",	ex_menu,
+			RANGE|NOTADR|ZEROR|EXTRA|TRLBAR|NOTRLCOM|USECTRLV|CMDWIN),
+EX(CMD_args,		"args",		ex_args,
+			BANG|FILES|EDITCMD|ARGOPT|TRLBAR),
+EX(CMD_argadd,		"argadd",	ex_argadd,
+			BANG|NEEDARG|RANGE|NOTADR|ZEROR|FILES|TRLBAR),
+EX(CMD_argdelete,	"argdelete",	ex_argdelete,
+			BANG|RANGE|NOTADR|FILES|TRLBAR),
+EX(CMD_argdo,		"argdo",	ex_listdo,
+			BANG|NEEDARG|EXTRA|NOTRLCOM),
+EX(CMD_argedit,		"argedit",	ex_argedit,
+			BANG|NEEDARG|RANGE|NOTADR|FILE1|EDITCMD|TRLBAR),
+EX(CMD_argglobal,	"argglobal",	ex_args,
+			BANG|FILES|EDITCMD|ARGOPT|TRLBAR),
+EX(CMD_arglocal,	"arglocal",	ex_args,
+			BANG|FILES|EDITCMD|ARGOPT|TRLBAR),
+EX(CMD_argument,	"argument",	ex_argument,
+			BANG|RANGE|NOTADR|COUNT|EXTRA|EDITCMD|ARGOPT|TRLBAR),
+EX(CMD_ascii,		"ascii",	do_ascii,
+			TRLBAR|SBOXOK|CMDWIN),
+EX(CMD_autocmd,		"autocmd",	ex_autocmd,
+			BANG|EXTRA|NOTRLCOM|USECTRLV|CMDWIN),
+EX(CMD_augroup,		"augroup",	ex_autocmd,
+			BANG|WORD1|TRLBAR|CMDWIN),
+EX(CMD_aunmenu,		"aunmenu",	ex_menu,
+			EXTRA|TRLBAR|NOTRLCOM|USECTRLV|CMDWIN),
+EX(CMD_buffer,		"buffer",	ex_buffer,
+			BANG|RANGE|NOTADR|BUFNAME|BUFUNL|COUNT|EXTRA|TRLBAR),
+EX(CMD_bNext,		"bNext",	ex_bprevious,
+			BANG|RANGE|NOTADR|COUNT|TRLBAR),
+EX(CMD_ball,		"ball",		ex_buffer_all,
+			RANGE|NOTADR|COUNT|TRLBAR),
+EX(CMD_badd,		"badd",		ex_edit,
+			NEEDARG|FILE1|EDITCMD|TRLBAR|CMDWIN),
+EX(CMD_bdelete,		"bdelete",	ex_bunload,
+			BANG|RANGE|NOTADR|BUFNAME|COUNT|EXTRA|TRLBAR),
+EX(CMD_behave,		"behave",	ex_behave,
+			NEEDARG|WORD1|TRLBAR|CMDWIN),
+EX(CMD_belowright,	"belowright",	ex_wrongmodifier,
+			NEEDARG|EXTRA|NOTRLCOM),
+EX(CMD_bfirst,		"bfirst",	ex_brewind,
+			BANG|RANGE|NOTADR|TRLBAR),
+EX(CMD_blast,		"blast",	ex_blast,
+			BANG|RANGE|NOTADR|TRLBAR),
+EX(CMD_bmodified,	"bmodified",	ex_bmodified,
+			BANG|RANGE|NOTADR|COUNT|TRLBAR),
+EX(CMD_bnext,		"bnext",	ex_bnext,
+			BANG|RANGE|NOTADR|COUNT|TRLBAR),
+EX(CMD_botright,	"botright",	ex_wrongmodifier,
+			NEEDARG|EXTRA|NOTRLCOM),
+EX(CMD_bprevious,	"bprevious",	ex_bprevious,
+			BANG|RANGE|NOTADR|COUNT|TRLBAR),
+EX(CMD_brewind,		"brewind",	ex_brewind,
+			BANG|RANGE|NOTADR|TRLBAR),
+EX(CMD_break,		"break",	ex_break,
+			TRLBAR|SBOXOK|CMDWIN),
+EX(CMD_breakadd,	"breakadd",	ex_breakadd,
+			EXTRA|TRLBAR|CMDWIN),
+EX(CMD_breakdel,	"breakdel",	ex_breakdel,
+			EXTRA|TRLBAR|CMDWIN),
+EX(CMD_breaklist,	"breaklist",	ex_breaklist,
+			EXTRA|TRLBAR|CMDWIN),
+EX(CMD_browse,		"browse",	ex_wrongmodifier,
+			NEEDARG|EXTRA|NOTRLCOM|CMDWIN),
+EX(CMD_buffers,		"buffers",	buflist_list,
+			BANG|TRLBAR|CMDWIN),
+EX(CMD_bufdo,		"bufdo",	ex_listdo,
+			BANG|NEEDARG|EXTRA|NOTRLCOM),
+EX(CMD_bunload,		"bunload",	ex_bunload,
+			BANG|RANGE|NOTADR|BUFNAME|COUNT|EXTRA|TRLBAR),
+EX(CMD_bwipeout,	"bwipeout",	ex_bunload,
+			BANG|RANGE|NOTADR|BUFNAME|BUFUNL|COUNT|EXTRA|TRLBAR),
+EX(CMD_change,		"change",	ex_change,
+			BANG|WHOLEFOLD|RANGE|COUNT|TRLBAR|CMDWIN|MODIFY),
+EX(CMD_cNext,		"cNext",	ex_cnext,
+			RANGE|NOTADR|COUNT|TRLBAR|BANG),
+EX(CMD_cNfile,		"cNfile",	ex_cnext,
+			RANGE|NOTADR|COUNT|TRLBAR|BANG),
+EX(CMD_cabbrev,		"cabbrev",	ex_abbreviate,
+			EXTRA|TRLBAR|NOTRLCOM|USECTRLV|CMDWIN),
+EX(CMD_cabclear,	"cabclear",	ex_abclear,
+			EXTRA|TRLBAR|CMDWIN),
+EX(CMD_caddbuffer,	"caddbuffer",	ex_cbuffer,
+			RANGE|NOTADR|WORD1|TRLBAR),
+EX(CMD_caddexpr,	"caddexpr",	ex_cexpr,
+			NEEDARG|WORD1|NOTRLCOM|TRLBAR|BANG),
+EX(CMD_caddfile,	"caddfile",	ex_cfile,
+			TRLBAR|FILE1),
+EX(CMD_call,		"call",		ex_call,
+			RANGE|NEEDARG|EXTRA|NOTRLCOM|SBOXOK|CMDWIN),
+EX(CMD_catch,		"catch",	ex_catch,
+			EXTRA|SBOXOK|CMDWIN),
+EX(CMD_cbuffer,		"cbuffer",	ex_cbuffer,
+			BANG|RANGE|NOTADR|WORD1|TRLBAR),
+EX(CMD_cc,		"cc",		ex_cc,
+			RANGE|NOTADR|COUNT|TRLBAR|BANG),
+EX(CMD_cclose,		"cclose",	ex_cclose,
+			RANGE|NOTADR|COUNT|TRLBAR),
+EX(CMD_cd,		"cd",		ex_cd,
+			BANG|FILE1|TRLBAR|CMDWIN),
+EX(CMD_center,		"center",	ex_align,
+			TRLBAR|RANGE|WHOLEFOLD|EXTRA|CMDWIN|MODIFY),
+EX(CMD_cexpr,		"cexpr",	ex_cexpr,
+			NEEDARG|WORD1|NOTRLCOM|TRLBAR|BANG),
+EX(CMD_cfile,		"cfile",	ex_cfile,
+			TRLBAR|FILE1|BANG),
+EX(CMD_cfirst,		"cfirst",	ex_cc,
+			RANGE|NOTADR|COUNT|TRLBAR|BANG),
+EX(CMD_cgetfile,	"cgetfile",	ex_cfile,
+			TRLBAR|FILE1|BANG),
+EX(CMD_cgetbuffer,	"cgetbuffer",	ex_cbuffer,
+			RANGE|NOTADR|WORD1|TRLBAR),
+EX(CMD_cgetexpr,	"cgetexpr",	ex_cexpr,
+			NEEDARG|WORD1|NOTRLCOM|TRLBAR|BANG),
+EX(CMD_chdir,		"chdir",	ex_cd,
+			BANG|FILE1|TRLBAR|CMDWIN),
+EX(CMD_changes,		"changes",	ex_changes,
+			TRLBAR|CMDWIN),
+EX(CMD_checkpath,	"checkpath",	ex_checkpath,
+			TRLBAR|BANG|CMDWIN),
+EX(CMD_checktime,	"checktime",	ex_checktime,
+			RANGE|NOTADR|BUFNAME|COUNT|EXTRA|TRLBAR),
+EX(CMD_clist,		"clist",	qf_list,
+			BANG|EXTRA|TRLBAR|CMDWIN),
+EX(CMD_clast,		"clast",	ex_cc,
+			RANGE|NOTADR|COUNT|TRLBAR|BANG),
+EX(CMD_close,		"close",	ex_close,
+			BANG|TRLBAR|CMDWIN),
+EX(CMD_cmap,		"cmap",		ex_map,
+			EXTRA|TRLBAR|NOTRLCOM|USECTRLV|CMDWIN),
+EX(CMD_cmapclear,	"cmapclear",	ex_mapclear,
+			EXTRA|TRLBAR|CMDWIN),
+EX(CMD_cmenu,		"cmenu",	ex_menu,
+			RANGE|NOTADR|ZEROR|EXTRA|TRLBAR|NOTRLCOM|USECTRLV|CMDWIN),
+EX(CMD_cnext,		"cnext",	ex_cnext,
+			RANGE|NOTADR|COUNT|TRLBAR|BANG),
+EX(CMD_cnewer,		"cnewer",	qf_age,
+			RANGE|NOTADR|COUNT|TRLBAR),
+EX(CMD_cnfile,		"cnfile",	ex_cnext,
+			RANGE|NOTADR|COUNT|TRLBAR|BANG),
+EX(CMD_cnoremap,	"cnoremap",	ex_map,
+			EXTRA|TRLBAR|NOTRLCOM|USECTRLV|CMDWIN),
+EX(CMD_cnoreabbrev,	"cnoreabbrev",	ex_abbreviate,
+			EXTRA|TRLBAR|NOTRLCOM|USECTRLV|CMDWIN),
+EX(CMD_cnoremenu,	"cnoremenu",	ex_menu,
+			RANGE|NOTADR|ZEROR|EXTRA|TRLBAR|NOTRLCOM|USECTRLV|CMDWIN),
+EX(CMD_copy,		"copy",		ex_copymove,
+			RANGE|WHOLEFOLD|EXTRA|TRLBAR|CMDWIN|MODIFY),
+EX(CMD_colder,		"colder",	qf_age,
+			RANGE|NOTADR|COUNT|TRLBAR),
+EX(CMD_colorscheme,	"colorscheme",	ex_colorscheme,
+			NEEDARG|WORD1|TRLBAR|CMDWIN),
+EX(CMD_command,		"command",	ex_command,
+			EXTRA|BANG|NOTRLCOM|USECTRLV|CMDWIN),
+EX(CMD_comclear,	"comclear",	ex_comclear,
+			TRLBAR|CMDWIN),
+EX(CMD_compiler,	"compiler",	ex_compiler,
+			BANG|TRLBAR|WORD1|CMDWIN),
+EX(CMD_continue,	"continue",	ex_continue,
+			TRLBAR|SBOXOK|CMDWIN),
+EX(CMD_confirm,		"confirm",	ex_wrongmodifier,
+			NEEDARG|EXTRA|NOTRLCOM|CMDWIN),
+EX(CMD_copen,		"copen",	ex_copen,
+			RANGE|NOTADR|COUNT|TRLBAR),
+EX(CMD_cprevious,	"cprevious",	ex_cnext,
+			RANGE|NOTADR|COUNT|TRLBAR|BANG),
+EX(CMD_cpfile,		"cpfile",	ex_cnext,
+			RANGE|NOTADR|COUNT|TRLBAR|BANG),
+EX(CMD_cquit,		"cquit",	ex_cquit,
+			TRLBAR|BANG),
+EX(CMD_crewind,		"crewind",	ex_cc,
+			RANGE|NOTADR|COUNT|TRLBAR|BANG),
+EX(CMD_cscope,		"cscope",	do_cscope,
+			EXTRA|NOTRLCOM|SBOXOK|XFILE),
+EX(CMD_cstag,		"cstag",	do_cstag,
+			BANG|TRLBAR|WORD1),
+EX(CMD_cunmap,		"cunmap",	ex_unmap,
+			EXTRA|TRLBAR|NOTRLCOM|USECTRLV|CMDWIN),
+EX(CMD_cunabbrev,	"cunabbrev",	ex_abbreviate,
+			EXTRA|TRLBAR|NOTRLCOM|USECTRLV|CMDWIN),
+EX(CMD_cunmenu,		"cunmenu",	ex_menu,
+			EXTRA|TRLBAR|NOTRLCOM|USECTRLV|CMDWIN),
+EX(CMD_cwindow,		"cwindow",	ex_cwindow,
+			RANGE|NOTADR|COUNT|TRLBAR),
+EX(CMD_delete,		"delete",	ex_operators,
+			RANGE|WHOLEFOLD|REGSTR|COUNT|TRLBAR|CMDWIN|MODIFY),
+EX(CMD_delmarks,	"delmarks",	ex_delmarks,
+			BANG|EXTRA|TRLBAR|CMDWIN),
+EX(CMD_debug,		"debug",	ex_debug,
+			NEEDARG|EXTRA|NOTRLCOM|SBOXOK|CMDWIN),
+EX(CMD_debuggreedy,	"debuggreedy",	ex_debuggreedy,
+			RANGE|NOTADR|ZEROR|TRLBAR|CMDWIN),
+EX(CMD_delcommand,	"delcommand",	ex_delcommand,
+			NEEDARG|WORD1|TRLBAR|CMDWIN),
+EX(CMD_delfunction,	"delfunction",	ex_delfunction,
+			NEEDARG|WORD1|CMDWIN),
+EX(CMD_display,		"display",	ex_display,
+			EXTRA|NOTRLCOM|TRLBAR|SBOXOK|CMDWIN),
+EX(CMD_diffupdate,	"diffupdate",	ex_diffupdate,
+			TRLBAR),
+EX(CMD_diffget,		"diffget",	ex_diffgetput,
+			RANGE|EXTRA|TRLBAR|MODIFY),
+EX(CMD_diffoff,		"diffoff",	ex_diffoff,
+			BANG|TRLBAR),
+EX(CMD_diffpatch,	"diffpatch",	ex_diffpatch,
+			EXTRA|FILE1|TRLBAR|MODIFY),
+EX(CMD_diffput,		"diffput",	ex_diffgetput,
+			RANGE|EXTRA|TRLBAR),
+EX(CMD_diffsplit,	"diffsplit",	ex_diffsplit,
+			EXTRA|FILE1|TRLBAR),
+EX(CMD_diffthis,	"diffthis",	ex_diffthis,
+			TRLBAR),
+EX(CMD_digraphs,	"digraphs",	ex_digraphs,
+			EXTRA|TRLBAR|CMDWIN),
+EX(CMD_djump,		"djump",	ex_findpat,
+			BANG|RANGE|DFLALL|WHOLEFOLD|EXTRA),
+EX(CMD_dlist,		"dlist",	ex_findpat,
+			BANG|RANGE|DFLALL|WHOLEFOLD|EXTRA|CMDWIN),
+EX(CMD_doautocmd,	"doautocmd",	ex_doautocmd,
+			EXTRA|TRLBAR|CMDWIN),
+EX(CMD_doautoall,	"doautoall",	ex_doautoall,
+			EXTRA|TRLBAR|CMDWIN),
+EX(CMD_drop,		"drop",		ex_drop,
+			FILES|EDITCMD|NEEDARG|ARGOPT|TRLBAR),
+EX(CMD_dsearch,		"dsearch",	ex_findpat,
+			BANG|RANGE|DFLALL|WHOLEFOLD|EXTRA|CMDWIN),
+EX(CMD_dsplit,		"dsplit",	ex_findpat,
+			BANG|RANGE|DFLALL|WHOLEFOLD|EXTRA),
+EX(CMD_edit,		"edit",		ex_edit,
+			BANG|FILE1|EDITCMD|ARGOPT|TRLBAR),
+EX(CMD_earlier,		"earlier",	ex_later,
+			TRLBAR|EXTRA|NOSPC|CMDWIN),
+EX(CMD_echo,		"echo",		ex_echo,
+			EXTRA|NOTRLCOM|SBOXOK|CMDWIN),
+EX(CMD_echoerr,		"echoerr",	ex_execute,
+			EXTRA|NOTRLCOM|SBOXOK|CMDWIN),
+EX(CMD_echohl,		"echohl",	ex_echohl,
+			EXTRA|TRLBAR|SBOXOK|CMDWIN),
+EX(CMD_echomsg,		"echomsg",	ex_execute,
+			EXTRA|NOTRLCOM|SBOXOK|CMDWIN),
+EX(CMD_echon,		"echon",	ex_echo,
+			EXTRA|NOTRLCOM|SBOXOK|CMDWIN),
+EX(CMD_else,		"else",		ex_else,
+			TRLBAR|SBOXOK|CMDWIN),
+EX(CMD_elseif,		"elseif",	ex_else,
+			EXTRA|NOTRLCOM|SBOXOK|CMDWIN),
+EX(CMD_emenu,		"emenu",	ex_emenu,
+			NEEDARG|EXTRA|TRLBAR|NOTRLCOM|RANGE|NOTADR|CMDWIN),
+EX(CMD_endif,		"endif",	ex_endif,
+			TRLBAR|SBOXOK|CMDWIN),
+EX(CMD_endfunction,	"endfunction",	ex_endfunction,
+			TRLBAR|CMDWIN),
+EX(CMD_endfor,		"endfor",	ex_endwhile,
+			TRLBAR|SBOXOK|CMDWIN),
+EX(CMD_endtry,		"endtry",	ex_endtry,
+			TRLBAR|SBOXOK|CMDWIN),
+EX(CMD_endwhile,	"endwhile",	ex_endwhile,
+			TRLBAR|SBOXOK|CMDWIN),
+EX(CMD_enew,		"enew",		ex_edit,
+			BANG|TRLBAR),
+EX(CMD_ex,		"ex",		ex_edit,
+			BANG|FILE1|EDITCMD|ARGOPT|TRLBAR),
+EX(CMD_execute,		"execute",	ex_execute,
+			EXTRA|NOTRLCOM|SBOXOK|CMDWIN),
+EX(CMD_exit,		"exit",		ex_exit,
+			RANGE|WHOLEFOLD|BANG|FILE1|ARGOPT|DFLALL|TRLBAR|CMDWIN),
+EX(CMD_exusage,		"exusage",	ex_exusage,
+			TRLBAR),
+EX(CMD_file,		"file",		ex_file,
+			RANGE|NOTADR|ZEROR|BANG|FILE1|TRLBAR),
+EX(CMD_files,		"files",	buflist_list,
+			BANG|TRLBAR|CMDWIN),
+EX(CMD_filetype,	"filetype",	ex_filetype,
+			EXTRA|TRLBAR|CMDWIN),
+EX(CMD_find,		"find",		ex_find,
+			RANGE|NOTADR|BANG|FILE1|EDITCMD|ARGOPT|TRLBAR),
+EX(CMD_finally,		"finally",	ex_finally,
+			TRLBAR|SBOXOK|CMDWIN),
+EX(CMD_finish,		"finish",	ex_finish,
+			TRLBAR|SBOXOK|CMDWIN),
+EX(CMD_first,		"first",	ex_rewind,
+			EXTRA|BANG|EDITCMD|ARGOPT|TRLBAR),
+EX(CMD_fixdel,		"fixdel",	do_fixdel,
+			TRLBAR|CMDWIN),
+EX(CMD_fold,		"fold",		ex_fold,
+			RANGE|WHOLEFOLD|TRLBAR|SBOXOK|CMDWIN),
+EX(CMD_foldclose,	"foldclose",	ex_foldopen,
+			RANGE|BANG|WHOLEFOLD|TRLBAR|SBOXOK|CMDWIN),
+EX(CMD_folddoopen,	"folddoopen",	ex_folddo,
+			RANGE|DFLALL|NEEDARG|EXTRA|NOTRLCOM),
+EX(CMD_folddoclosed,	"folddoclosed",	ex_folddo,
+			RANGE|DFLALL|NEEDARG|EXTRA|NOTRLCOM),
+EX(CMD_foldopen,	"foldopen",	ex_foldopen,
+			RANGE|BANG|WHOLEFOLD|TRLBAR|SBOXOK|CMDWIN),
+EX(CMD_for,		"for",		ex_while,
+			EXTRA|NOTRLCOM|SBOXOK|CMDWIN),
+EX(CMD_function,	"function",	ex_function,
+			EXTRA|BANG|CMDWIN),
+EX(CMD_global,		"global",	ex_global,
+			RANGE|WHOLEFOLD|BANG|EXTRA|DFLALL|SBOXOK|CMDWIN),
+EX(CMD_goto,		"goto",		ex_goto,
+			RANGE|NOTADR|COUNT|TRLBAR|SBOXOK|CMDWIN),
+EX(CMD_grep,		"grep",		ex_make,
+			RANGE|NOTADR|BANG|NEEDARG|EXTRA|NOTRLCOM|TRLBAR|XFILE),
+EX(CMD_grepadd,		"grepadd",	ex_make,
+			RANGE|NOTADR|BANG|NEEDARG|EXTRA|NOTRLCOM|TRLBAR|XFILE),
+EX(CMD_gui,		"gui",		ex_gui,
+			BANG|FILES|EDITCMD|ARGOPT|TRLBAR|CMDWIN),
+EX(CMD_gvim,		"gvim",		ex_gui,
+			BANG|FILES|EDITCMD|ARGOPT|TRLBAR|CMDWIN),
+EX(CMD_help,		"help",		ex_help,
+			BANG|EXTRA|NOTRLCOM),
+EX(CMD_helpfind,	"helpfind",	ex_helpfind,
+			EXTRA|NOTRLCOM),
+EX(CMD_helpgrep,	"helpgrep",	ex_helpgrep,
+			EXTRA|NOTRLCOM|NEEDARG),
+EX(CMD_helptags,	"helptags",	ex_helptags,
+			NEEDARG|FILE1|TRLBAR|CMDWIN),
+EX(CMD_hardcopy,	"hardcopy",	ex_hardcopy,
+			RANGE|COUNT|EXTRA|TRLBAR|DFLALL|BANG),
+EX(CMD_highlight,	"highlight",	ex_highlight,
+			BANG|EXTRA|TRLBAR|SBOXOK|CMDWIN),
+EX(CMD_hide,		"hide",		ex_hide,
+			BANG|EXTRA|NOTRLCOM),
+EX(CMD_history,		"history",	ex_history,
+			EXTRA|TRLBAR|CMDWIN),
+EX(CMD_insert,		"insert",	ex_append,
+			BANG|RANGE|TRLBAR|CMDWIN|MODIFY),
+EX(CMD_iabbrev,		"iabbrev",	ex_abbreviate,
+			EXTRA|TRLBAR|NOTRLCOM|USECTRLV|CMDWIN),
+EX(CMD_iabclear,	"iabclear",	ex_abclear,
+			EXTRA|TRLBAR|CMDWIN),
+EX(CMD_if,		"if",		ex_if,
+			EXTRA|NOTRLCOM|SBOXOK|CMDWIN),
+EX(CMD_ijump,		"ijump",	ex_findpat,
+			BANG|RANGE|DFLALL|WHOLEFOLD|EXTRA),
+EX(CMD_ilist,		"ilist",	ex_findpat,
+			BANG|RANGE|DFLALL|WHOLEFOLD|EXTRA|CMDWIN),
+EX(CMD_imap,		"imap",		ex_map,
+			EXTRA|TRLBAR|NOTRLCOM|USECTRLV|CMDWIN),
+EX(CMD_imapclear,	"imapclear",	ex_mapclear,
+			EXTRA|TRLBAR|CMDWIN),
+EX(CMD_imenu,		"imenu",	ex_menu,
+			RANGE|NOTADR|ZEROR|EXTRA|TRLBAR|NOTRLCOM|USECTRLV|CMDWIN),
+EX(CMD_inoremap,	"inoremap",	ex_map,
+			EXTRA|TRLBAR|NOTRLCOM|USECTRLV|CMDWIN),
+EX(CMD_inoreabbrev,	"inoreabbrev",	ex_abbreviate,
+			EXTRA|TRLBAR|NOTRLCOM|USECTRLV|CMDWIN),
+EX(CMD_inoremenu,	"inoremenu",	ex_menu,
+			RANGE|NOTADR|ZEROR|EXTRA|TRLBAR|NOTRLCOM|USECTRLV|CMDWIN),
+EX(CMD_intro,		"intro",	ex_intro,
+			TRLBAR|CMDWIN),
+EX(CMD_isearch,		"isearch",	ex_findpat,
+			BANG|RANGE|DFLALL|WHOLEFOLD|EXTRA|CMDWIN),
+EX(CMD_isplit,		"isplit",	ex_findpat,
+			BANG|RANGE|DFLALL|WHOLEFOLD|EXTRA),
+EX(CMD_iunmap,		"iunmap",	ex_unmap,
+			EXTRA|TRLBAR|NOTRLCOM|USECTRLV|CMDWIN),
+EX(CMD_iunabbrev,	"iunabbrev",	ex_abbreviate,
+			EXTRA|TRLBAR|NOTRLCOM|USECTRLV|CMDWIN),
+EX(CMD_iunmenu,		"iunmenu",	ex_menu,
+			EXTRA|TRLBAR|NOTRLCOM|USECTRLV|CMDWIN),
+EX(CMD_join,		"join",		ex_join,
+			BANG|RANGE|WHOLEFOLD|COUNT|EXFLAGS|TRLBAR|CMDWIN|MODIFY),
+EX(CMD_jumps,		"jumps",	ex_jumps,
+			TRLBAR|CMDWIN),
+EX(CMD_k,		"k",		ex_mark,
+			RANGE|WORD1|TRLBAR|SBOXOK|CMDWIN),
+EX(CMD_keepmarks,	"keepmarks",	ex_wrongmodifier,
+			NEEDARG|EXTRA|NOTRLCOM),
+EX(CMD_keepjumps,	"keepjumps",	ex_wrongmodifier,
+			NEEDARG|EXTRA|NOTRLCOM),
+EX(CMD_keepalt,		"keepalt",	ex_wrongmodifier,
+			NEEDARG|EXTRA|NOTRLCOM),
+EX(CMD_list,		"list",		ex_print,
+			RANGE|WHOLEFOLD|COUNT|EXFLAGS|TRLBAR|CMDWIN),
+EX(CMD_lNext,		"lNext",	ex_cnext,
+			RANGE|NOTADR|COUNT|TRLBAR|BANG),
+EX(CMD_lNfile,		"lNfile",	ex_cnext,
+			RANGE|NOTADR|COUNT|TRLBAR|BANG),
+EX(CMD_last,		"last",		ex_last,
+			EXTRA|BANG|EDITCMD|ARGOPT|TRLBAR),
+EX(CMD_language,	"language",	ex_language,
+			EXTRA|TRLBAR|CMDWIN),
+EX(CMD_laddexpr,	"laddexpr",	ex_cexpr,
+			NEEDARG|WORD1|NOTRLCOM|TRLBAR|BANG),
+EX(CMD_laddbuffer,	"laddbuffer",	ex_cbuffer,
+			RANGE|NOTADR|WORD1|TRLBAR),
+EX(CMD_laddfile,	"laddfile",	ex_cfile,
+			TRLBAR|FILE1),
+EX(CMD_later,		"later",	ex_later,
+			TRLBAR|EXTRA|NOSPC|CMDWIN),
+EX(CMD_lbuffer,		"lbuffer",	ex_cbuffer,
+			BANG|RANGE|NOTADR|WORD1|TRLBAR),
+EX(CMD_lcd,		"lcd",		ex_cd,
+			BANG|FILE1|TRLBAR|CMDWIN),
+EX(CMD_lchdir,		"lchdir",	ex_cd,
+			BANG|FILE1|TRLBAR|CMDWIN),
+EX(CMD_lclose,		"lclose",	ex_cclose,
+			RANGE|NOTADR|COUNT|TRLBAR),
+EX(CMD_lcscope,		"lcscope",	do_cscope,
+			EXTRA|NOTRLCOM|SBOXOK|XFILE),
+EX(CMD_left,		"left",		ex_align,
+			TRLBAR|RANGE|WHOLEFOLD|EXTRA|CMDWIN|MODIFY),
+EX(CMD_leftabove,	"leftabove",	ex_wrongmodifier,
+			NEEDARG|EXTRA|NOTRLCOM),
+EX(CMD_let,		"let",		ex_let,
+			EXTRA|NOTRLCOM|SBOXOK|CMDWIN),
+EX(CMD_lexpr,		"lexpr",	ex_cexpr,
+			NEEDARG|WORD1|NOTRLCOM|TRLBAR|BANG),
+EX(CMD_lfile,		"lfile",	ex_cfile,
+			TRLBAR|FILE1|BANG),
+EX(CMD_lfirst,		"lfirst",	ex_cc,
+			RANGE|NOTADR|COUNT|TRLBAR|BANG),
+EX(CMD_lgetfile,	"lgetfile",	ex_cfile,
+			TRLBAR|FILE1|BANG),
+EX(CMD_lgetbuffer,	"lgetbuffer",	ex_cbuffer,
+			RANGE|NOTADR|WORD1|TRLBAR),
+EX(CMD_lgetexpr,	"lgetexpr",	ex_cexpr,
+			NEEDARG|WORD1|NOTRLCOM|TRLBAR|BANG),
+EX(CMD_lgrep,		"lgrep",	ex_make,
+			RANGE|NOTADR|BANG|NEEDARG|EXTRA|NOTRLCOM|TRLBAR|XFILE),
+EX(CMD_lgrepadd,	"lgrepadd",	ex_make,
+			RANGE|NOTADR|BANG|NEEDARG|EXTRA|NOTRLCOM|TRLBAR|XFILE),
+EX(CMD_lhelpgrep,	"lhelpgrep",	ex_helpgrep,
+			EXTRA|NOTRLCOM|NEEDARG),
+EX(CMD_ll,		"ll",		ex_cc,
+			RANGE|NOTADR|COUNT|TRLBAR|BANG),
+EX(CMD_llast,		"llast",	ex_cc,
+			RANGE|NOTADR|COUNT|TRLBAR|BANG),
+EX(CMD_llist,		"llist",	qf_list,
+			BANG|EXTRA|TRLBAR|CMDWIN),
+EX(CMD_lmap,		"lmap",		ex_map,
+			EXTRA|TRLBAR|NOTRLCOM|USECTRLV|CMDWIN),
+EX(CMD_lmapclear,	"lmapclear",	ex_mapclear,
+			EXTRA|TRLBAR|CMDWIN),
+EX(CMD_lmake,		"lmake",	ex_make,
+			BANG|EXTRA|NOTRLCOM|TRLBAR|XFILE),
+EX(CMD_lnoremap,	"lnoremap",	ex_map,
+			EXTRA|TRLBAR|NOTRLCOM|USECTRLV|CMDWIN),
+EX(CMD_lnext,		"lnext",	ex_cnext,
+			RANGE|NOTADR|COUNT|TRLBAR|BANG),
+EX(CMD_lnewer,		"lnewer",	qf_age,
+			RANGE|NOTADR|COUNT|TRLBAR),
+EX(CMD_lnfile,		"lnfile",	ex_cnext,
+			RANGE|NOTADR|COUNT|TRLBAR|BANG),
+EX(CMD_loadview,	"loadview",	ex_loadview,
+			FILE1|TRLBAR),
+EX(CMD_loadkeymap,	"loadkeymap",	ex_loadkeymap,
+			CMDWIN),
+EX(CMD_lockmarks,	"lockmarks",	ex_wrongmodifier,
+			NEEDARG|EXTRA|NOTRLCOM),
+EX(CMD_lockvar,		"lockvar",	ex_lockvar,
+			BANG|EXTRA|NEEDARG|SBOXOK|CMDWIN),
+EX(CMD_lolder,		"lolder",	qf_age,
+			RANGE|NOTADR|COUNT|TRLBAR),
+EX(CMD_lopen,		"lopen",	ex_copen,
+			RANGE|NOTADR|COUNT|TRLBAR),
+EX(CMD_lprevious,	"lprevious",	ex_cnext,
+			RANGE|NOTADR|COUNT|TRLBAR|BANG),
+EX(CMD_lpfile,		"lpfile",	ex_cnext,
+			RANGE|NOTADR|COUNT|TRLBAR|BANG),
+EX(CMD_lrewind,		"lrewind",	ex_cc,
+			RANGE|NOTADR|COUNT|TRLBAR|BANG),
+EX(CMD_ltag,		"ltag",	ex_tag,
+			NOTADR|TRLBAR|BANG|WORD1),
+EX(CMD_lunmap,		"lunmap",	ex_unmap,
+			EXTRA|TRLBAR|NOTRLCOM|USECTRLV|CMDWIN),
+EX(CMD_lvimgrep,	"lvimgrep",	ex_vimgrep,
+			RANGE|NOTADR|BANG|NEEDARG|EXTRA|NOTRLCOM|TRLBAR|XFILE),
+EX(CMD_lvimgrepadd,	"lvimgrepadd",	ex_vimgrep,
+			RANGE|NOTADR|BANG|NEEDARG|EXTRA|NOTRLCOM|TRLBAR|XFILE),
+EX(CMD_lwindow,		"lwindow",	ex_cwindow,
+			RANGE|NOTADR|COUNT|TRLBAR),
+EX(CMD_ls,		"ls",		buflist_list,
+			BANG|TRLBAR|CMDWIN),
+EX(CMD_move,		"move",		ex_copymove,
+			RANGE|WHOLEFOLD|EXTRA|TRLBAR|CMDWIN|MODIFY),
+EX(CMD_mark,		"mark",		ex_mark,
+			RANGE|WORD1|TRLBAR|SBOXOK|CMDWIN),
+EX(CMD_make,		"make",		ex_make,
+			BANG|EXTRA|NOTRLCOM|TRLBAR|XFILE),
+EX(CMD_map,		"map",		ex_map,
+			BANG|EXTRA|TRLBAR|NOTRLCOM|USECTRLV|CMDWIN),
+EX(CMD_mapclear,	"mapclear",	ex_mapclear,
+			EXTRA|BANG|TRLBAR|CMDWIN),
+EX(CMD_marks,		"marks",	do_marks,
+			EXTRA|TRLBAR|CMDWIN),
+EX(CMD_match,		"match",	ex_match,
+			RANGE|NOTADR|EXTRA|CMDWIN),
+EX(CMD_menu,		"menu",		ex_menu,
+			RANGE|NOTADR|ZEROR|BANG|EXTRA|TRLBAR|NOTRLCOM|USECTRLV|CMDWIN),
+EX(CMD_menutranslate,	"menutranslate", ex_menutranslate,
+			EXTRA|TRLBAR|NOTRLCOM|USECTRLV|CMDWIN),
+EX(CMD_messages,	"messages",	ex_messages,
+			TRLBAR|CMDWIN),
+EX(CMD_mkexrc,		"mkexrc",	ex_mkrc,
+			BANG|FILE1|TRLBAR|CMDWIN),
+EX(CMD_mksession,	"mksession",	ex_mkrc,
+			BANG|FILE1|TRLBAR),
+EX(CMD_mkspell,		"mkspell",	ex_mkspell,
+			BANG|NEEDARG|EXTRA|NOTRLCOM|TRLBAR|XFILE),
+EX(CMD_mkvimrc,		"mkvimrc",	ex_mkrc,
+			BANG|FILE1|TRLBAR|CMDWIN),
+EX(CMD_mkview,		"mkview",	ex_mkrc,
+			BANG|FILE1|TRLBAR),
+EX(CMD_mode,		"mode",		ex_mode,
+			WORD1|TRLBAR|CMDWIN),
+EX(CMD_mzscheme,	"mzscheme",	ex_mzscheme,
+			RANGE|EXTRA|DFLALL|NEEDARG|CMDWIN|SBOXOK),
+EX(CMD_mzfile,		"mzfile",	ex_mzfile,
+			RANGE|FILE1|NEEDARG|CMDWIN),
+EX(CMD_next,		"next",		ex_next,
+			RANGE|NOTADR|BANG|FILES|EDITCMD|ARGOPT|TRLBAR),
+EX(CMD_nbkey,		"nbkey",	ex_nbkey,
+			EXTRA|NOTADR|NEEDARG),
+EX(CMD_new,		"new",		ex_splitview,
+			BANG|FILE1|RANGE|NOTADR|EDITCMD|ARGOPT|TRLBAR),
+EX(CMD_nmap,		"nmap",		ex_map,
+			EXTRA|TRLBAR|NOTRLCOM|USECTRLV|CMDWIN),
+EX(CMD_nmapclear,	"nmapclear",	ex_mapclear,
+			EXTRA|TRLBAR|CMDWIN),
+EX(CMD_nmenu,		"nmenu",	ex_menu,
+			RANGE|NOTADR|ZEROR|EXTRA|TRLBAR|NOTRLCOM|USECTRLV|CMDWIN),
+EX(CMD_nnoremap,	"nnoremap",	ex_map,
+			EXTRA|TRLBAR|NOTRLCOM|USECTRLV|CMDWIN),
+EX(CMD_nnoremenu,	"nnoremenu",	ex_menu,
+			RANGE|NOTADR|ZEROR|EXTRA|TRLBAR|NOTRLCOM|USECTRLV|CMDWIN),
+EX(CMD_noremap,		"noremap",	ex_map,
+			BANG|EXTRA|TRLBAR|NOTRLCOM|USECTRLV|CMDWIN),
+EX(CMD_nohlsearch,	"nohlsearch",	ex_nohlsearch,
+			TRLBAR|SBOXOK|CMDWIN),
+EX(CMD_noreabbrev,	"noreabbrev",	ex_abbreviate,
+			EXTRA|TRLBAR|NOTRLCOM|USECTRLV|CMDWIN),
+EX(CMD_noremenu,	"noremenu",	ex_menu,
+			RANGE|NOTADR|ZEROR|BANG|EXTRA|TRLBAR|NOTRLCOM|USECTRLV|CMDWIN),
+EX(CMD_normal,		"normal",	ex_normal,
+			RANGE|BANG|EXTRA|NEEDARG|NOTRLCOM|USECTRLV|SBOXOK|CMDWIN),
+EX(CMD_number,		"number",	ex_print,
+			RANGE|WHOLEFOLD|COUNT|EXFLAGS|TRLBAR|CMDWIN),
+EX(CMD_nunmap,		"nunmap",	ex_unmap,
+			EXTRA|TRLBAR|NOTRLCOM|USECTRLV|CMDWIN),
+EX(CMD_nunmenu,		"nunmenu",	ex_menu,
+			EXTRA|TRLBAR|NOTRLCOM|USECTRLV|CMDWIN),
+EX(CMD_open,		"open",		ex_open,
+			RANGE|EXTRA),
+EX(CMD_omap,		"omap",		ex_map,
+			EXTRA|TRLBAR|NOTRLCOM|USECTRLV|CMDWIN),
+EX(CMD_omapclear,	"omapclear",	ex_mapclear,
+			EXTRA|TRLBAR|CMDWIN),
+EX(CMD_omenu,		"omenu",	ex_menu,
+			RANGE|NOTADR|ZEROR|EXTRA|TRLBAR|NOTRLCOM|USECTRLV|CMDWIN),
+EX(CMD_only,		"only",		ex_only,
+			BANG|TRLBAR),
+EX(CMD_onoremap,	"onoremap",	ex_map,
+			EXTRA|TRLBAR|NOTRLCOM|USECTRLV|CMDWIN),
+EX(CMD_onoremenu,	"onoremenu",	ex_menu,
+			RANGE|NOTADR|ZEROR|EXTRA|TRLBAR|NOTRLCOM|USECTRLV|CMDWIN),
+EX(CMD_options,		"options",	ex_options,
+			TRLBAR),
+EX(CMD_ounmap,		"ounmap",	ex_unmap,
+			EXTRA|TRLBAR|NOTRLCOM|USECTRLV|CMDWIN),
+EX(CMD_ounmenu,		"ounmenu",	ex_menu,
+			EXTRA|TRLBAR|NOTRLCOM|USECTRLV|CMDWIN),
+EX(CMD_print,		"print",	ex_print,
+			RANGE|WHOLEFOLD|COUNT|EXFLAGS|TRLBAR|CMDWIN|SBOXOK),
+EX(CMD_pclose,		"pclose",	ex_pclose,
+			BANG|TRLBAR),
+EX(CMD_perl,		"perl",		ex_perl,
+			RANGE|EXTRA|DFLALL|NEEDARG|SBOXOK|CMDWIN),
+EX(CMD_perldo,		"perldo",	ex_perldo,
+			RANGE|EXTRA|DFLALL|NEEDARG|CMDWIN),
+EX(CMD_pedit,		"pedit",	ex_pedit,
+			BANG|FILE1|EDITCMD|ARGOPT|TRLBAR),
+EX(CMD_pop,		"pop",		ex_tag,
+			RANGE|NOTADR|BANG|COUNT|TRLBAR|ZEROR),
+EX(CMD_popup,		"popup",	ex_popup,
+			NEEDARG|EXTRA|BANG|TRLBAR|NOTRLCOM|CMDWIN),
+EX(CMD_ppop,		"ppop",		ex_ptag,
+			RANGE|NOTADR|BANG|COUNT|TRLBAR|ZEROR),
+EX(CMD_preserve,	"preserve",	ex_preserve,
+			TRLBAR),
+EX(CMD_previous,	"previous",	ex_previous,
+			EXTRA|RANGE|NOTADR|COUNT|BANG|EDITCMD|ARGOPT|TRLBAR),
+EX(CMD_promptfind,	"promptfind",	gui_mch_find_dialog,
+			EXTRA|NOTRLCOM|CMDWIN),
+EX(CMD_promptrepl,	"promptrepl",	gui_mch_replace_dialog,
+			EXTRA|NOTRLCOM|CMDWIN),
+EX(CMD_profile,		"profile",	ex_profile,
+			BANG|EXTRA|TRLBAR|CMDWIN),
+EX(CMD_profdel,		"profdel",	ex_breakdel,
+			EXTRA|TRLBAR|CMDWIN),
+EX(CMD_psearch,		"psearch",	ex_psearch,
+			BANG|RANGE|WHOLEFOLD|DFLALL|EXTRA),
+EX(CMD_ptag,		"ptag",		ex_ptag,
+			RANGE|NOTADR|BANG|WORD1|TRLBAR|ZEROR),
+EX(CMD_ptNext,		"ptNext",	ex_ptag,
+			RANGE|NOTADR|BANG|TRLBAR|ZEROR),
+EX(CMD_ptfirst,		"ptfirst",	ex_ptag,
+			RANGE|NOTADR|BANG|TRLBAR|ZEROR),
+EX(CMD_ptjump,		"ptjump",	ex_ptag,
+			BANG|TRLBAR|WORD1),
+EX(CMD_ptlast,		"ptlast",	ex_ptag,
+			BANG|TRLBAR),
+EX(CMD_ptnext,		"ptnext",	ex_ptag,
+			RANGE|NOTADR|BANG|TRLBAR|ZEROR),
+EX(CMD_ptprevious,	"ptprevious",	ex_ptag,
+			RANGE|NOTADR|BANG|TRLBAR|ZEROR),
+EX(CMD_ptrewind,	"ptrewind",	ex_ptag,
+			RANGE|NOTADR|BANG|TRLBAR|ZEROR),
+EX(CMD_ptselect,	"ptselect",	ex_ptag,
+			BANG|TRLBAR|WORD1),
+EX(CMD_put,		"put",		ex_put,
+			RANGE|WHOLEFOLD|BANG|REGSTR|TRLBAR|ZEROR|CMDWIN|MODIFY),
+EX(CMD_pwd,		"pwd",		ex_pwd,
+			TRLBAR|CMDWIN),
+EX(CMD_python,		"python",	ex_python,
+			RANGE|EXTRA|NEEDARG|CMDWIN),
+EX(CMD_pyfile,		"pyfile",	ex_pyfile,
+			RANGE|FILE1|NEEDARG|CMDWIN),
+EX(CMD_quit,		"quit",		ex_quit,
+			BANG|TRLBAR|CMDWIN),
+EX(CMD_quitall,		"quitall",	ex_quit_all,
+			BANG|TRLBAR),
+EX(CMD_qall,		"qall",		ex_quit_all,
+			BANG|TRLBAR|CMDWIN),
+EX(CMD_read,		"read",		ex_read,
+			BANG|RANGE|WHOLEFOLD|FILE1|ARGOPT|TRLBAR|ZEROR|CMDWIN|MODIFY),
+EX(CMD_recover,		"recover",	ex_recover,
+			BANG|FILE1|TRLBAR),
+EX(CMD_redo,		"redo",		ex_redo,
+			TRLBAR|CMDWIN),
+EX(CMD_redir,		"redir",	ex_redir,
+			BANG|FILES|TRLBAR|CMDWIN),
+EX(CMD_redraw,		"redraw",	ex_redraw,
+			BANG|TRLBAR|CMDWIN),
+EX(CMD_redrawstatus,	"redrawstatus",	ex_redrawstatus,
+			BANG|TRLBAR|CMDWIN),
+EX(CMD_registers,	"registers",	ex_display,
+			EXTRA|NOTRLCOM|TRLBAR|CMDWIN),
+EX(CMD_resize,		"resize",	ex_resize,
+			RANGE|NOTADR|TRLBAR|WORD1),
+EX(CMD_retab,		"retab",	ex_retab,
+			TRLBAR|RANGE|WHOLEFOLD|DFLALL|BANG|WORD1|CMDWIN|MODIFY),
+EX(CMD_return,		"return",	ex_return,
+			EXTRA|NOTRLCOM|SBOXOK|CMDWIN),
+EX(CMD_rewind,		"rewind",	ex_rewind,
+			EXTRA|BANG|EDITCMD|ARGOPT|TRLBAR),
+EX(CMD_right,		"right",	ex_align,
+			TRLBAR|RANGE|WHOLEFOLD|EXTRA|CMDWIN|MODIFY),
+EX(CMD_rightbelow,	"rightbelow",	ex_wrongmodifier,
+			NEEDARG|EXTRA|NOTRLCOM),
+EX(CMD_runtime,		"runtime",	ex_runtime,
+			BANG|NEEDARG|FILES|TRLBAR|SBOXOK|CMDWIN),
+EX(CMD_ruby,		"ruby",		ex_ruby,
+			RANGE|EXTRA|NEEDARG|CMDWIN),
+EX(CMD_rubydo,		"rubydo",	ex_rubydo,
+			RANGE|DFLALL|EXTRA|NEEDARG|CMDWIN),
+EX(CMD_rubyfile,	"rubyfile",	ex_rubyfile,
+			RANGE|FILE1|NEEDARG|CMDWIN),
+EX(CMD_rviminfo,	"rviminfo",	ex_viminfo,
+			BANG|FILE1|TRLBAR|CMDWIN),
+EX(CMD_substitute,	"substitute",	do_sub,
+			RANGE|WHOLEFOLD|EXTRA|CMDWIN),
+EX(CMD_sNext,		"sNext",	ex_previous,
+			EXTRA|RANGE|NOTADR|COUNT|BANG|EDITCMD|ARGOPT|TRLBAR),
+EX(CMD_sargument,	"sargument",	ex_argument,
+			BANG|RANGE|NOTADR|COUNT|EXTRA|EDITCMD|ARGOPT|TRLBAR),
+EX(CMD_sall,		"sall",		ex_all,
+			RANGE|NOTADR|COUNT|TRLBAR),
+EX(CMD_sandbox,		"sandbox",	ex_wrongmodifier,
+			NEEDARG|EXTRA|NOTRLCOM),
+EX(CMD_saveas,		"saveas",	ex_write,
+			BANG|DFLALL|FILE1|ARGOPT|CMDWIN|TRLBAR),
+EX(CMD_sbuffer,		"sbuffer",	ex_buffer,
+			BANG|RANGE|NOTADR|BUFNAME|BUFUNL|COUNT|EXTRA|TRLBAR),
+EX(CMD_sbNext,		"sbNext",	ex_bprevious,
+			RANGE|NOTADR|COUNT|TRLBAR),
+EX(CMD_sball,		"sball",	ex_buffer_all,
+			RANGE|NOTADR|COUNT|TRLBAR),
+EX(CMD_sbfirst,		"sbfirst",	ex_brewind,
+			TRLBAR),
+EX(CMD_sblast,		"sblast",	ex_blast,
+			TRLBAR),
+EX(CMD_sbmodified,	"sbmodified",	ex_bmodified,
+			RANGE|NOTADR|COUNT|TRLBAR),
+EX(CMD_sbnext,		"sbnext",	ex_bnext,
+			RANGE|NOTADR|COUNT|TRLBAR),
+EX(CMD_sbprevious,	"sbprevious",	ex_bprevious,
+			RANGE|NOTADR|COUNT|TRLBAR),
+EX(CMD_sbrewind,	"sbrewind",	ex_brewind,
+			TRLBAR),
+EX(CMD_scriptnames,	"scriptnames",	ex_scriptnames,
+			TRLBAR|CMDWIN),
+EX(CMD_scriptencoding,	"scriptencoding", ex_scriptencoding,
+			WORD1|TRLBAR|CMDWIN),
+EX(CMD_scscope,		"scscope",	do_scscope,
+			EXTRA|NOTRLCOM|SBOXOK),
+EX(CMD_set,		"set",		ex_set,
+			TRLBAR|EXTRA|CMDWIN|SBOXOK),
+EX(CMD_setfiletype,	"setfiletype",	ex_setfiletype,
+			TRLBAR|EXTRA|NEEDARG|CMDWIN),
+EX(CMD_setglobal,	"setglobal",	ex_set,
+			TRLBAR|EXTRA|CMDWIN),
+EX(CMD_setlocal,	"setlocal",	ex_set,
+			TRLBAR|EXTRA|CMDWIN),
+EX(CMD_sfind,		"sfind",	ex_splitview,
+			BANG|FILE1|RANGE|NOTADR|EDITCMD|ARGOPT|TRLBAR),
+EX(CMD_sfirst,		"sfirst",	ex_rewind,
+			EXTRA|BANG|EDITCMD|ARGOPT|TRLBAR),
+EX(CMD_shell,		"shell",	ex_shell,
+			TRLBAR|CMDWIN),
+EX(CMD_simalt,		"simalt",	ex_simalt,
+			NEEDARG|WORD1|TRLBAR|CMDWIN),
+EX(CMD_sign,		"sign",		ex_sign,
+			NEEDARG|RANGE|NOTADR|EXTRA|CMDWIN),
+EX(CMD_silent,		"silent",	ex_wrongmodifier,
+			NEEDARG|EXTRA|BANG|NOTRLCOM|SBOXOK|CMDWIN),
+EX(CMD_sleep,		"sleep",	ex_sleep,
+			RANGE|NOTADR|COUNT|EXTRA|TRLBAR|CMDWIN),
+EX(CMD_slast,		"slast",	ex_last,
+			EXTRA|BANG|EDITCMD|ARGOPT|TRLBAR),
+EX(CMD_smagic,		"smagic",	ex_submagic,
+			RANGE|WHOLEFOLD|EXTRA|CMDWIN),
+EX(CMD_smap,		"smap",		ex_map,
+			EXTRA|TRLBAR|NOTRLCOM|USECTRLV|CMDWIN),
+EX(CMD_smapclear,	"smapclear",	ex_mapclear,
+			EXTRA|TRLBAR|CMDWIN),
+EX(CMD_smenu,		"smenu",	ex_menu,
+			RANGE|NOTADR|ZEROR|EXTRA|TRLBAR|NOTRLCOM|USECTRLV|CMDWIN),
+EX(CMD_snext,		"snext",	ex_next,
+			RANGE|NOTADR|BANG|FILES|EDITCMD|ARGOPT|TRLBAR),
+EX(CMD_sniff,		"sniff",	ex_sniff,
+			EXTRA|TRLBAR),
+EX(CMD_snomagic,	"snomagic",	ex_submagic,
+			RANGE|WHOLEFOLD|EXTRA|CMDWIN),
+EX(CMD_snoremap,	"snoremap",	ex_map,
+			EXTRA|TRLBAR|NOTRLCOM|USECTRLV|CMDWIN),
+EX(CMD_snoremenu,	"snoremenu",	ex_menu,
+			RANGE|NOTADR|ZEROR|EXTRA|TRLBAR|NOTRLCOM|USECTRLV|CMDWIN),
+EX(CMD_source,		"source",	ex_source,
+			BANG|FILE1|TRLBAR|SBOXOK|CMDWIN),
+EX(CMD_sort,		"sort",		ex_sort,
+			RANGE|DFLALL|WHOLEFOLD|BANG|EXTRA|NOTRLCOM|MODIFY),
+EX(CMD_split,		"split",	ex_splitview,
+			BANG|FILE1|RANGE|NOTADR|EDITCMD|ARGOPT|TRLBAR),
+EX(CMD_spellgood,	"spellgood",	ex_spell,
+			BANG|RANGE|NOTADR|NEEDARG|EXTRA|TRLBAR),
+EX(CMD_spelldump,	"spelldump",	ex_spelldump,
+			BANG|TRLBAR),
+EX(CMD_spellinfo,	"spellinfo",	ex_spellinfo,
+			TRLBAR),
+EX(CMD_spellrepall,	"spellrepall",	ex_spellrepall,
+			TRLBAR),
+EX(CMD_spellundo,	"spellundo",	ex_spell,
+			BANG|RANGE|NOTADR|NEEDARG|EXTRA|TRLBAR),
+EX(CMD_spellwrong,	"spellwrong",	ex_spell,
+			BANG|RANGE|NOTADR|NEEDARG|EXTRA|TRLBAR),
+EX(CMD_sprevious,	"sprevious",	ex_previous,
+			EXTRA|RANGE|NOTADR|COUNT|BANG|EDITCMD|ARGOPT|TRLBAR),
+EX(CMD_srewind,		"srewind",	ex_rewind,
+			EXTRA|BANG|EDITCMD|ARGOPT|TRLBAR),
+EX(CMD_stop,		"stop",		ex_stop,
+			TRLBAR|BANG|CMDWIN),
+EX(CMD_stag,		"stag",		ex_stag,
+			RANGE|NOTADR|BANG|WORD1|TRLBAR|ZEROR),
+EX(CMD_startinsert,	"startinsert",	ex_startinsert,
+			BANG|TRLBAR|CMDWIN),
+EX(CMD_startgreplace,	"startgreplace", ex_startinsert,
+			BANG|TRLBAR|CMDWIN),
+EX(CMD_startreplace,	"startreplace",	ex_startinsert,
+			BANG|TRLBAR|CMDWIN),
+EX(CMD_stopinsert,	"stopinsert",	ex_stopinsert,
+			BANG|TRLBAR|CMDWIN),
+EX(CMD_stjump,		"stjump",	ex_stag,
+			BANG|TRLBAR|WORD1),
+EX(CMD_stselect,	"stselect",	ex_stag,
+			BANG|TRLBAR|WORD1),
+EX(CMD_sunhide,		"sunhide",	ex_buffer_all,
+			RANGE|NOTADR|COUNT|TRLBAR),
+EX(CMD_sunmap,		"sunmap",	ex_unmap,
+			EXTRA|TRLBAR|NOTRLCOM|USECTRLV|CMDWIN),
+EX(CMD_sunmenu,		"sunmenu",	ex_menu,
+			EXTRA|TRLBAR|NOTRLCOM|USECTRLV|CMDWIN),
+EX(CMD_suspend,		"suspend",	ex_stop,
+			TRLBAR|BANG|CMDWIN),
+EX(CMD_sview,		"sview",	ex_splitview,
+			NEEDARG|RANGE|NOTADR|BANG|FILE1|EDITCMD|ARGOPT|TRLBAR),
+EX(CMD_swapname,	"swapname",	ex_swapname,
+			TRLBAR|CMDWIN),
+EX(CMD_syntax,		"syntax",	ex_syntax,
+			EXTRA|NOTRLCOM|CMDWIN),
+EX(CMD_syncbind,	"syncbind",	ex_syncbind,
+			TRLBAR),
+EX(CMD_t,		"t",		ex_copymove,
+			RANGE|WHOLEFOLD|EXTRA|TRLBAR|CMDWIN|MODIFY),
+EX(CMD_tNext,		"tNext",	ex_tag,
+			RANGE|NOTADR|BANG|TRLBAR|ZEROR),
+EX(CMD_tag,		"tag",		ex_tag,
+			RANGE|NOTADR|BANG|WORD1|TRLBAR|ZEROR),
+EX(CMD_tags,		"tags",		do_tags,
+			TRLBAR|CMDWIN),
+EX(CMD_tab,		"tab",		ex_wrongmodifier,
+			NEEDARG|EXTRA|NOTRLCOM),
+EX(CMD_tabclose,	"tabclose",	ex_tabclose,
+			RANGE|NOTADR|COUNT|BANG|TRLBAR|CMDWIN),
+EX(CMD_tabdo,		"tabdo",	ex_listdo,
+			NEEDARG|EXTRA|NOTRLCOM),
+EX(CMD_tabedit,		"tabedit",	ex_splitview,
+			BANG|FILE1|RANGE|NOTADR|ZEROR|EDITCMD|ARGOPT|TRLBAR),
+EX(CMD_tabfind,		"tabfind",	ex_splitview,
+			BANG|FILE1|RANGE|NOTADR|ZEROR|EDITCMD|ARGOPT|NEEDARG|TRLBAR),
+EX(CMD_tabfirst,	"tabfirst",	ex_tabnext,
+			TRLBAR),
+EX(CMD_tabmove,		"tabmove",	ex_tabmove,
+			RANGE|NOTADR|ZEROR|COUNT|TRLBAR|ZEROR),
+EX(CMD_tablast,		"tablast",	ex_tabnext,
+			TRLBAR),
+EX(CMD_tabnext,		"tabnext",	ex_tabnext,
+			RANGE|NOTADR|COUNT|TRLBAR),
+EX(CMD_tabnew,		"tabnew",	ex_splitview,
+			BANG|FILE1|RANGE|NOTADR|ZEROR|EDITCMD|ARGOPT|TRLBAR),
+EX(CMD_tabonly,		"tabonly",	ex_tabonly,
+			BANG|TRLBAR|CMDWIN),
+EX(CMD_tabprevious,	"tabprevious",	ex_tabnext,
+			RANGE|NOTADR|COUNT|TRLBAR),
+EX(CMD_tabNext,		"tabNext",	ex_tabnext,
+			RANGE|NOTADR|COUNT|TRLBAR),
+EX(CMD_tabrewind,	"tabrewind",	ex_tabnext,
+			TRLBAR),
+EX(CMD_tabs,		"tabs",		ex_tabs,
+			TRLBAR|CMDWIN),
+EX(CMD_tcl,		"tcl",		ex_tcl,
+			RANGE|EXTRA|NEEDARG|CMDWIN),
+EX(CMD_tcldo,		"tcldo",	ex_tcldo,
+			RANGE|DFLALL|EXTRA|NEEDARG|CMDWIN),
+EX(CMD_tclfile,		"tclfile",	ex_tclfile,
+			RANGE|FILE1|NEEDARG|CMDWIN),
+EX(CMD_tearoff,		"tearoff",	ex_tearoff,
+			NEEDARG|EXTRA|TRLBAR|NOTRLCOM|CMDWIN),
+EX(CMD_tfirst,		"tfirst",	ex_tag,
+			RANGE|NOTADR|BANG|TRLBAR|ZEROR),
+EX(CMD_throw,		"throw",	ex_throw,
+			EXTRA|NEEDARG|SBOXOK|CMDWIN),
+EX(CMD_tjump,		"tjump",	ex_tag,
+			BANG|TRLBAR|WORD1),
+EX(CMD_tlast,		"tlast",	ex_tag,
+			BANG|TRLBAR),
+EX(CMD_tmenu,		"tmenu",	ex_menu,
+			RANGE|NOTADR|ZEROR|EXTRA|TRLBAR|NOTRLCOM|USECTRLV|CMDWIN),
+EX(CMD_tnext,		"tnext",	ex_tag,
+			RANGE|NOTADR|BANG|TRLBAR|ZEROR),
+EX(CMD_topleft,		"topleft",	ex_wrongmodifier,
+			NEEDARG|EXTRA|NOTRLCOM),
+EX(CMD_tprevious,	"tprevious",	ex_tag,
+			RANGE|NOTADR|BANG|TRLBAR|ZEROR),
+EX(CMD_trewind,		"trewind",	ex_tag,
+			RANGE|NOTADR|BANG|TRLBAR|ZEROR),
+EX(CMD_try,		"try",		ex_try,
+			TRLBAR|SBOXOK|CMDWIN),
+EX(CMD_tselect,		"tselect",	ex_tag,
+			BANG|TRLBAR|WORD1),
+EX(CMD_tunmenu,		"tunmenu",	ex_menu,
+			EXTRA|TRLBAR|NOTRLCOM|USECTRLV|CMDWIN),
+EX(CMD_undo,		"undo",		ex_undo,
+			RANGE|NOTADR|COUNT|ZEROR|TRLBAR|CMDWIN),
+EX(CMD_undojoin,	"undojoin",	ex_undojoin,
+			TRLBAR|CMDWIN),
+EX(CMD_undolist,	"undolist",	ex_undolist,
+			TRLBAR|CMDWIN),
+EX(CMD_unabbreviate,	"unabbreviate",	ex_abbreviate,
+			EXTRA|TRLBAR|NOTRLCOM|USECTRLV|CMDWIN),
+EX(CMD_unhide,		"unhide",	ex_buffer_all,
+			RANGE|NOTADR|COUNT|TRLBAR),
+EX(CMD_unlet,		"unlet",	ex_unlet,
+			BANG|EXTRA|NEEDARG|SBOXOK|CMDWIN),
+EX(CMD_unlockvar,	"unlockvar",	ex_lockvar,
+			BANG|EXTRA|NEEDARG|SBOXOK|CMDWIN),
+EX(CMD_unmap,		"unmap",	ex_unmap,
+			BANG|EXTRA|TRLBAR|NOTRLCOM|USECTRLV|CMDWIN),
+EX(CMD_unmenu,		"unmenu",	ex_menu,
+			BANG|EXTRA|TRLBAR|NOTRLCOM|USECTRLV|CMDWIN),
+EX(CMD_update,		"update",	ex_update,
+			RANGE|WHOLEFOLD|BANG|FILE1|ARGOPT|DFLALL|TRLBAR),
+EX(CMD_vglobal,		"vglobal",	ex_global,
+			RANGE|WHOLEFOLD|EXTRA|DFLALL|CMDWIN),
+EX(CMD_version,		"version",	ex_version,
+			EXTRA|TRLBAR|CMDWIN),
+EX(CMD_verbose,		"verbose",	ex_wrongmodifier,
+			NEEDARG|RANGE|NOTADR|EXTRA|NOTRLCOM|SBOXOK|CMDWIN),
+EX(CMD_vertical,	"vertical",	ex_wrongmodifier,
+			NEEDARG|EXTRA|NOTRLCOM),
+EX(CMD_visual,		"visual",	ex_edit,
+			BANG|FILE1|EDITCMD|ARGOPT|TRLBAR),
+EX(CMD_view,		"view",		ex_edit,
+			BANG|FILE1|EDITCMD|ARGOPT|TRLBAR),
+EX(CMD_vimgrep,		"vimgrep",	ex_vimgrep,
+			RANGE|NOTADR|BANG|NEEDARG|EXTRA|NOTRLCOM|TRLBAR|XFILE),
+EX(CMD_vimgrepadd,	"vimgrepadd",	ex_vimgrep,
+			RANGE|NOTADR|BANG|NEEDARG|EXTRA|NOTRLCOM|TRLBAR|XFILE),
+EX(CMD_viusage,		"viusage",	ex_viusage,
+			TRLBAR),
+EX(CMD_vmap,		"vmap",		ex_map,
+			EXTRA|TRLBAR|NOTRLCOM|USECTRLV|CMDWIN),
+EX(CMD_vmapclear,	"vmapclear",	ex_mapclear,
+			EXTRA|TRLBAR|CMDWIN),
+EX(CMD_vmenu,		"vmenu",	ex_menu,
+			RANGE|NOTADR|ZEROR|EXTRA|TRLBAR|NOTRLCOM|USECTRLV|CMDWIN),
+EX(CMD_vnoremap,	"vnoremap",	ex_map,
+			EXTRA|TRLBAR|NOTRLCOM|USECTRLV|CMDWIN),
+EX(CMD_vnew,		"vnew",		ex_splitview,
+			BANG|FILE1|RANGE|NOTADR|EDITCMD|ARGOPT|TRLBAR),
+EX(CMD_vnoremenu,	"vnoremenu",	ex_menu,
+			RANGE|NOTADR|ZEROR|EXTRA|TRLBAR|NOTRLCOM|USECTRLV|CMDWIN),
+EX(CMD_vsplit,		"vsplit",	ex_splitview,
+			BANG|FILE1|RANGE|NOTADR|EDITCMD|ARGOPT|TRLBAR),
+EX(CMD_vunmap,		"vunmap",	ex_unmap,
+			EXTRA|TRLBAR|NOTRLCOM|USECTRLV|CMDWIN),
+EX(CMD_vunmenu,		"vunmenu",	ex_menu,
+			EXTRA|TRLBAR|NOTRLCOM|USECTRLV|CMDWIN),
+EX(CMD_write,		"write",	ex_write,
+			RANGE|WHOLEFOLD|BANG|FILE1|ARGOPT|DFLALL|TRLBAR|CMDWIN),
+EX(CMD_wNext,		"wNext",	ex_wnext,
+			RANGE|WHOLEFOLD|NOTADR|BANG|FILE1|ARGOPT|TRLBAR),
+EX(CMD_wall,		"wall",		do_wqall,
+			BANG|TRLBAR|CMDWIN),
+EX(CMD_while,		"while",	ex_while,
+			EXTRA|NOTRLCOM|SBOXOK|CMDWIN),
+EX(CMD_winsize,		"winsize",	ex_winsize,
+			EXTRA|NEEDARG|TRLBAR),
+EX(CMD_wincmd,		"wincmd",	ex_wincmd,
+			NEEDARG|WORD1|RANGE|NOTADR),
+EX(CMD_windo,		"windo",	ex_listdo,
+			BANG|NEEDARG|EXTRA|NOTRLCOM),
+EX(CMD_winpos,		"winpos",	ex_winpos,
+			EXTRA|TRLBAR|CMDWIN),
+EX(CMD_wnext,		"wnext",	ex_wnext,
+			RANGE|NOTADR|BANG|FILE1|ARGOPT|TRLBAR),
+EX(CMD_wprevious,	"wprevious",	ex_wnext,
+			RANGE|NOTADR|BANG|FILE1|ARGOPT|TRLBAR),
+EX(CMD_wq,		"wq",		ex_exit,
+			RANGE|WHOLEFOLD|BANG|FILE1|ARGOPT|DFLALL|TRLBAR),
+EX(CMD_wqall,		"wqall",	do_wqall,
+			BANG|FILE1|ARGOPT|DFLALL|TRLBAR),
+EX(CMD_wsverb,		"wsverb",	ex_wsverb,
+			EXTRA|NOTADR|NEEDARG),
+EX(CMD_wviminfo,	"wviminfo",	ex_viminfo,
+			BANG|FILE1|TRLBAR|CMDWIN),
+EX(CMD_xit,		"xit",		ex_exit,
+			RANGE|WHOLEFOLD|BANG|FILE1|ARGOPT|DFLALL|TRLBAR|CMDWIN),
+EX(CMD_xall,		"xall",		do_wqall,
+			BANG|TRLBAR),
+EX(CMD_xmap,		"xmap",		ex_map,
+			EXTRA|TRLBAR|NOTRLCOM|USECTRLV|CMDWIN),
+EX(CMD_xmapclear,	"xmapclear",	ex_mapclear,
+			EXTRA|TRLBAR|CMDWIN),
+EX(CMD_xmenu,		"xmenu",	ex_menu,
+			RANGE|NOTADR|ZEROR|EXTRA|TRLBAR|NOTRLCOM|USECTRLV|CMDWIN),
+EX(CMD_xnoremap,	"xnoremap",	ex_map,
+			EXTRA|TRLBAR|NOTRLCOM|USECTRLV|CMDWIN),
+EX(CMD_xnoremenu,	"xnoremenu",	ex_menu,
+			RANGE|NOTADR|ZEROR|EXTRA|TRLBAR|NOTRLCOM|USECTRLV|CMDWIN),
+EX(CMD_xunmap,		"xunmap",	ex_unmap,
+			EXTRA|TRLBAR|NOTRLCOM|USECTRLV|CMDWIN),
+EX(CMD_xunmenu,		"xunmenu",	ex_menu,
+			EXTRA|TRLBAR|NOTRLCOM|USECTRLV|CMDWIN),
+EX(CMD_yank,		"yank",		ex_operators,
+			RANGE|WHOLEFOLD|REGSTR|COUNT|TRLBAR|CMDWIN),
+EX(CMD_z,		"z",		ex_z,
+			RANGE|WHOLEFOLD|EXTRA|EXFLAGS|TRLBAR|CMDWIN),
+
+/* commands that don't start with a lowercase letter */
+EX(CMD_bang,		"!",		ex_bang,
+			RANGE|WHOLEFOLD|BANG|FILES|CMDWIN),
+EX(CMD_pound,		"#",		ex_print,
+			RANGE|WHOLEFOLD|COUNT|EXFLAGS|TRLBAR|CMDWIN),
+EX(CMD_and,		"&",		do_sub,
+			RANGE|WHOLEFOLD|EXTRA|CMDWIN|MODIFY),
+EX(CMD_star,		"*",		ex_at,
+			RANGE|WHOLEFOLD|EXTRA|TRLBAR|CMDWIN),
+EX(CMD_lshift,		"<",		ex_operators,
+			RANGE|WHOLEFOLD|COUNT|EXFLAGS|TRLBAR|CMDWIN|MODIFY),
+EX(CMD_equal,		"=",		ex_equal,
+			RANGE|TRLBAR|DFLALL|EXFLAGS|CMDWIN),
+EX(CMD_rshift,		">",		ex_operators,
+			RANGE|WHOLEFOLD|COUNT|EXFLAGS|TRLBAR|CMDWIN|MODIFY),
+EX(CMD_at,		"@",		ex_at,
+			RANGE|WHOLEFOLD|EXTRA|TRLBAR|CMDWIN),
+EX(CMD_Next,		"Next",		ex_previous,
+			EXTRA|RANGE|NOTADR|COUNT|BANG|EDITCMD|ARGOPT|TRLBAR),
+EX(CMD_Print,		"Print",	ex_print,
+			RANGE|WHOLEFOLD|COUNT|EXFLAGS|TRLBAR|CMDWIN),
+EX(CMD_X,		"X",		ex_X,
+			TRLBAR),
+EX(CMD_tilde,		"~",		do_sub,
+			RANGE|WHOLEFOLD|EXTRA|CMDWIN|MODIFY),
+
+#ifndef DO_DECLARE_EXCMD
+#ifdef FEAT_USR_CMDS
+    CMD_SIZE,		/* MUST be after all real commands! */
+    CMD_USER = -1,	/* User-defined command */
+    CMD_USER_BUF = -2	/* User-defined command local to buffer */
+#else
+    CMD_SIZE	/* MUST be the last one! */
+#endif
+#endif
+};
+
+#define USER_CMDIDX(idx) ((int)(idx) < 0)
+
+#ifndef DO_DECLARE_EXCMD
+typedef enum CMD_index cmdidx_T;
+
+/*
+ * Arguments used for Ex commands.
+ */
+struct exarg
+{
+    char_u	*arg;		/* argument of the command */
+    char_u	*nextcmd;	/* next command (NULL if none) */
+    char_u	*cmd;		/* the name of the command (except for :make) */
+    char_u	**cmdlinep;	/* pointer to pointer of allocated cmdline */
+    cmdidx_T	cmdidx;		/* the index for the command */
+    long	argt;		/* flags for the command */
+    int		skip;		/* don't execute the command, only parse it */
+    int		forceit;	/* TRUE if ! present */
+    int		addr_count;	/* the number of addresses given */
+    linenr_T	line1;		/* the first line number */
+    linenr_T	line2;		/* the second line number or count */
+    int		flags;		/* extra flags after count: EXFLAG_ */
+    char_u	*do_ecmd_cmd;	/* +command arg to be used in edited file */
+    linenr_T	do_ecmd_lnum;	/* the line number in an edited file */
+    int		append;		/* TRUE with ":w >>file" command */
+    int		usefilter;	/* TRUE with ":w !command" and ":r!command" */
+    int		amount;		/* number of '>' or '<' for shift command */
+    int		regname;	/* register name (NUL if none) */
+    int		force_bin;	/* 0, FORCE_BIN or FORCE_NOBIN */
+    int		read_edit;	/* ++edit argument */
+    int		force_ff;	/* ++ff= argument (index in cmd[]) */
+#ifdef FEAT_MBYTE
+    int		force_enc;	/* ++enc= argument (index in cmd[]) */
+    int		bad_char;	/* ++bad= argument (index in cmd[]) */
+#endif
+#ifdef FEAT_USR_CMDS
+    int		useridx;	/* user command index */
+#endif
+    char_u	*errmsg;	/* returned error message */
+    char_u	*(*getline) __ARGS((int, void *, int));
+    void	*cookie;	/* argument for getline() */
+#ifdef FEAT_EVAL
+    struct condstack *cstack;	/* condition stack for ":if" etc. */
+#endif
+};
+
+#define FORCE_BIN 1		/* ":edit ++bin file" */
+#define FORCE_NOBIN 2		/* ":edit ++nobin file" */
+
+/* Values for "flags" */
+#define EXFLAG_LIST	0x01	/* 'l': list */
+#define EXFLAG_NR	0x02	/* '#': number */
+#define EXFLAG_PRINT	0x04	/* 'p': print */
+
+#endif
--- /dev/null
+++ b/ex_cmds2.c
@@ -1,0 +1,4049 @@
+/* vi:set ts=8 sts=4 sw=4:
+ *
+ * VIM - Vi IMproved	by Bram Moolenaar
+ *
+ * Do ":help uganda"  in Vim to read copying and usage conditions.
+ * Do ":help credits" in Vim to see a list of people who contributed.
+ * See README.txt for an overview of the Vim source code.
+ */
+
+/*
+ * ex_cmds2.c: some more functions for command line commands
+ */
+
+#if defined(WIN32) && defined(FEAT_CSCOPE)
+# include "vimio.h"
+#endif
+
+#include "vim.h"
+
+#if defined(WIN32) && defined(FEAT_CSCOPE)
+# include <fcntl.h>
+#endif
+
+#include "version.h"
+
+static void	cmd_source __ARGS((char_u *fname, exarg_T *eap));
+
+#ifdef FEAT_EVAL
+/* Growarray to store info about already sourced scripts.
+ * For Unix also store the dev/ino, so that we don't have to stat() each
+ * script when going through the list. */
+typedef struct scriptitem_S
+{
+    char_u	*sn_name;
+# ifdef UNIX
+    int		sn_dev;
+    ino_t	sn_ino;
+# endif
+# ifdef FEAT_PROFILE
+    int		sn_prof_on;	/* TRUE when script is/was profiled */
+    int		sn_pr_force;	/* forceit: profile functions in this script */
+    proftime_T	sn_pr_child;	/* time set when going into first child */
+    int		sn_pr_nest;	/* nesting for sn_pr_child */
+    /* profiling the script as a whole */
+    int		sn_pr_count;	/* nr of times sourced */
+    proftime_T	sn_pr_total;	/* time spend in script + children */
+    proftime_T	sn_pr_self;	/* time spend in script itself */
+    proftime_T	sn_pr_start;	/* time at script start */
+    proftime_T	sn_pr_children; /* time in children after script start */
+    /* profiling the script per line */
+    garray_T	sn_prl_ga;	/* things stored for every line */
+    proftime_T	sn_prl_start;	/* start time for current line */
+    proftime_T	sn_prl_children; /* time spent in children for this line */
+    proftime_T	sn_prl_wait;	/* wait start time for current line */
+    int		sn_prl_idx;	/* index of line being timed; -1 if none */
+    int		sn_prl_execed;	/* line being timed was executed */
+# endif
+} scriptitem_T;
+
+static garray_T script_items = {0, 0, sizeof(scriptitem_T), 4, NULL};
+#define SCRIPT_ITEM(id) (((scriptitem_T *)script_items.ga_data)[(id) - 1])
+
+# ifdef FEAT_PROFILE
+/* Struct used in sn_prl_ga for every line of a script. */
+typedef struct sn_prl_S
+{
+    int		snp_count;	/* nr of times line was executed */
+    proftime_T	sn_prl_total;	/* time spend in a line + children */
+    proftime_T	sn_prl_self;	/* time spend in a line itself */
+} sn_prl_T;
+
+#  define PRL_ITEM(si, idx)	(((sn_prl_T *)(si)->sn_prl_ga.ga_data)[(idx)])
+# endif
+#endif
+
+#if defined(FEAT_EVAL) || defined(PROTO)
+static int debug_greedy = FALSE;	/* batch mode debugging: don't save
+					   and restore typeahead. */
+
+/*
+ * do_debug(): Debug mode.
+ * Repeatedly get Ex commands, until told to continue normal execution.
+ */
+    void
+do_debug(cmd)
+    char_u	*cmd;
+{
+    int		save_msg_scroll = msg_scroll;
+    int		save_State = State;
+    int		save_did_emsg = did_emsg;
+    int		save_cmd_silent = cmd_silent;
+    int		save_msg_silent = msg_silent;
+    int		save_emsg_silent = emsg_silent;
+    int		save_redir_off = redir_off;
+    tasave_T	typeaheadbuf;
+# ifdef FEAT_EX_EXTRA
+    int		save_ex_normal_busy;
+# endif
+    int		n;
+    char_u	*cmdline = NULL;
+    char_u	*p;
+    char	*tail = NULL;
+    static int	last_cmd = 0;
+#define CMD_CONT	1
+#define CMD_NEXT	2
+#define CMD_STEP	3
+#define CMD_FINISH	4
+#define CMD_QUIT	5
+#define CMD_INTERRUPT	6
+
+#ifdef ALWAYS_USE_GUI
+    /* Can't do this when there is no terminal for input/output. */
+    if (!gui.in_use)
+    {
+	/* Break as soon as possible. */
+	debug_break_level = 9999;
+	return;
+    }
+#endif
+
+    /* Make sure we are in raw mode and start termcap mode.  Might have side
+     * effects... */
+    settmode(TMODE_RAW);
+    starttermcap();
+
+    ++RedrawingDisabled;	/* don't redisplay the window */
+    ++no_wait_return;		/* don't wait for return */
+    did_emsg = FALSE;		/* don't use error from debugged stuff */
+    cmd_silent = FALSE;		/* display commands */
+    msg_silent = FALSE;		/* display messages */
+    emsg_silent = FALSE;	/* display error messages */
+    redir_off = TRUE;		/* don't redirect debug commands */
+
+    State = NORMAL;
+#ifdef FEAT_SNIFF
+    want_sniff_request = 0;    /* No K_SNIFF wanted */
+#endif
+
+    if (!debug_did_msg)
+	MSG(_("Entering Debug mode.  Type \"cont\" to continue."));
+    if (sourcing_name != NULL)
+	msg(sourcing_name);
+    if (sourcing_lnum != 0)
+	smsg((char_u *)_("line %ld: %s"), (long)sourcing_lnum, cmd);
+    else
+	smsg((char_u *)_("cmd: %s"), cmd);
+
+    /*
+     * Repeat getting a command and executing it.
+     */
+    for (;;)
+    {
+	msg_scroll = TRUE;
+	need_wait_return = FALSE;
+#ifdef FEAT_SNIFF
+	ProcessSniffRequests();
+#endif
+	/* Save the current typeahead buffer and replace it with an empty one.
+	 * This makes sure we get input from the user here and don't interfere
+	 * with the commands being executed.  Reset "ex_normal_busy" to avoid
+	 * the side effects of using ":normal". Save the stuff buffer and make
+	 * it empty. */
+# ifdef FEAT_EX_EXTRA
+	save_ex_normal_busy = ex_normal_busy;
+	ex_normal_busy = 0;
+# endif
+	if (!debug_greedy)
+	    save_typeahead(&typeaheadbuf);
+
+	cmdline = getcmdline_prompt('>', NULL, 0, EXPAND_NOTHING, NULL);
+
+	if (!debug_greedy)
+	    restore_typeahead(&typeaheadbuf);
+# ifdef FEAT_EX_EXTRA
+	ex_normal_busy = save_ex_normal_busy;
+# endif
+
+	cmdline_row = msg_row;
+	if (cmdline != NULL)
+	{
+	    /* If this is a debug command, set "last_cmd".
+	     * If not, reset "last_cmd".
+	     * For a blank line use previous command. */
+	    p = skipwhite(cmdline);
+	    if (*p != NUL)
+	    {
+		switch (*p)
+		{
+		    case 'c': last_cmd = CMD_CONT;
+			      tail = "ont";
+			      break;
+		    case 'n': last_cmd = CMD_NEXT;
+			      tail = "ext";
+			      break;
+		    case 's': last_cmd = CMD_STEP;
+			      tail = "tep";
+			      break;
+		    case 'f': last_cmd = CMD_FINISH;
+			      tail = "inish";
+			      break;
+		    case 'q': last_cmd = CMD_QUIT;
+			      tail = "uit";
+			      break;
+		    case 'i': last_cmd = CMD_INTERRUPT;
+			      tail = "nterrupt";
+			      break;
+		    default: last_cmd = 0;
+		}
+		if (last_cmd != 0)
+		{
+		    /* Check that the tail matches. */
+		    ++p;
+		    while (*p != NUL && *p == *tail)
+		    {
+			++p;
+			++tail;
+		    }
+		    if (ASCII_ISALPHA(*p))
+			last_cmd = 0;
+		}
+	    }
+
+	    if (last_cmd != 0)
+	    {
+		/* Execute debug command: decided where to break next and
+		 * return. */
+		switch (last_cmd)
+		{
+		    case CMD_CONT:
+			debug_break_level = -1;
+			break;
+		    case CMD_NEXT:
+			debug_break_level = ex_nesting_level;
+			break;
+		    case CMD_STEP:
+			debug_break_level = 9999;
+			break;
+		    case CMD_FINISH:
+			debug_break_level = ex_nesting_level - 1;
+			break;
+		    case CMD_QUIT:
+			got_int = TRUE;
+			debug_break_level = -1;
+			break;
+		    case CMD_INTERRUPT:
+			got_int = TRUE;
+			debug_break_level = 9999;
+			/* Do not repeat ">interrupt" cmd, continue stepping. */
+			last_cmd = CMD_STEP;
+			break;
+		}
+		break;
+	    }
+
+	    /* don't debug this command */
+	    n = debug_break_level;
+	    debug_break_level = -1;
+	    (void)do_cmdline(cmdline, getexline, NULL,
+						DOCMD_VERBOSE|DOCMD_EXCRESET);
+	    debug_break_level = n;
+
+	    vim_free(cmdline);
+	}
+	lines_left = Rows - 1;
+    }
+    vim_free(cmdline);
+
+    --RedrawingDisabled;
+    --no_wait_return;
+    redraw_all_later(NOT_VALID);
+    need_wait_return = FALSE;
+    msg_scroll = save_msg_scroll;
+    lines_left = Rows - 1;
+    State = save_State;
+    did_emsg = save_did_emsg;
+    cmd_silent = save_cmd_silent;
+    msg_silent = save_msg_silent;
+    emsg_silent = save_emsg_silent;
+    redir_off = save_redir_off;
+
+    /* Only print the message again when typing a command before coming back
+     * here. */
+    debug_did_msg = TRUE;
+}
+
+/*
+ * ":debug".
+ */
+    void
+ex_debug(eap)
+    exarg_T	*eap;
+{
+    int		debug_break_level_save = debug_break_level;
+
+    debug_break_level = 9999;
+    do_cmdline_cmd(eap->arg);
+    debug_break_level = debug_break_level_save;
+}
+
+static char_u	*debug_breakpoint_name = NULL;
+static linenr_T	debug_breakpoint_lnum;
+
+/*
+ * When debugging or a breakpoint is set on a skipped command, no debug prompt
+ * is shown by do_one_cmd().  This situation is indicated by debug_skipped, and
+ * debug_skipped_name is then set to the source name in the breakpoint case.  If
+ * a skipped command decides itself that a debug prompt should be displayed, it
+ * can do so by calling dbg_check_skipped().
+ */
+static int	debug_skipped;
+static char_u	*debug_skipped_name;
+
+/*
+ * Go to debug mode when a breakpoint was encountered or "ex_nesting_level" is
+ * at or below the break level.  But only when the line is actually
+ * executed.  Return TRUE and set breakpoint_name for skipped commands that
+ * decide to execute something themselves.
+ * Called from do_one_cmd() before executing a command.
+ */
+    void
+dbg_check_breakpoint(eap)
+    exarg_T	*eap;
+{
+    char_u	*p;
+
+    debug_skipped = FALSE;
+    if (debug_breakpoint_name != NULL)
+    {
+	if (!eap->skip)
+	{
+	    /* replace K_SNR with "<SNR>" */
+	    if (debug_breakpoint_name[0] == K_SPECIAL
+		    && debug_breakpoint_name[1] == KS_EXTRA
+		    && debug_breakpoint_name[2] == (int)KE_SNR)
+		p = (char_u *)"<SNR>";
+	    else
+		p = (char_u *)"";
+	    smsg((char_u *)_("Breakpoint in \"%s%s\" line %ld"),
+		    p,
+		    debug_breakpoint_name + (*p == NUL ? 0 : 3),
+		    (long)debug_breakpoint_lnum);
+	    debug_breakpoint_name = NULL;
+	    do_debug(eap->cmd);
+	}
+	else
+	{
+	    debug_skipped = TRUE;
+	    debug_skipped_name = debug_breakpoint_name;
+	    debug_breakpoint_name = NULL;
+	}
+    }
+    else if (ex_nesting_level <= debug_break_level)
+    {
+	if (!eap->skip)
+	    do_debug(eap->cmd);
+	else
+	{
+	    debug_skipped = TRUE;
+	    debug_skipped_name = NULL;
+	}
+    }
+}
+
+/*
+ * Go to debug mode if skipped by dbg_check_breakpoint() because eap->skip was
+ * set.  Return TRUE when the debug mode is entered this time.
+ */
+    int
+dbg_check_skipped(eap)
+    exarg_T	*eap;
+{
+    int		prev_got_int;
+
+    if (debug_skipped)
+    {
+	/*
+	 * Save the value of got_int and reset it.  We don't want a previous
+	 * interruption cause flushing the input buffer.
+	 */
+	prev_got_int = got_int;
+	got_int = FALSE;
+	debug_breakpoint_name = debug_skipped_name;
+	/* eap->skip is TRUE */
+	eap->skip = FALSE;
+	(void)dbg_check_breakpoint(eap);
+	eap->skip = TRUE;
+	got_int |= prev_got_int;
+	return TRUE;
+    }
+    return FALSE;
+}
+
+/*
+ * The list of breakpoints: dbg_breakp.
+ * This is a grow-array of structs.
+ */
+struct debuggy
+{
+    int		dbg_nr;		/* breakpoint number */
+    int		dbg_type;	/* DBG_FUNC or DBG_FILE */
+    char_u	*dbg_name;	/* function or file name */
+    regprog_T	*dbg_prog;	/* regexp program */
+    linenr_T	dbg_lnum;	/* line number in function or file */
+    int		dbg_forceit;	/* ! used */
+};
+
+static garray_T dbg_breakp = {0, 0, sizeof(struct debuggy), 4, NULL};
+#define BREAKP(idx)		(((struct debuggy *)dbg_breakp.ga_data)[idx])
+#define DEBUGGY(gap, idx)	(((struct debuggy *)gap->ga_data)[idx])
+static int last_breakp = 0;	/* nr of last defined breakpoint */
+
+#ifdef FEAT_PROFILE
+/* Profiling uses file and func names similar to breakpoints. */
+static garray_T prof_ga = {0, 0, sizeof(struct debuggy), 4, NULL};
+#endif
+#define DBG_FUNC	1
+#define DBG_FILE	2
+
+static int dbg_parsearg __ARGS((char_u *arg, garray_T *gap));
+static linenr_T debuggy_find __ARGS((int file,char_u *fname, linenr_T after, garray_T *gap, int *fp));
+
+/*
+ * Parse the arguments of ":profile", ":breakadd" or ":breakdel" and put them
+ * in the entry just after the last one in dbg_breakp.  Note that "dbg_name"
+ * is allocated.
+ * Returns FAIL for failure.
+ */
+    static int
+dbg_parsearg(arg, gap)
+    char_u	*arg;
+    garray_T	*gap;	    /* either &dbg_breakp or &prof_ga */
+{
+    char_u	*p = arg;
+    char_u	*q;
+    struct debuggy *bp;
+    int		here = FALSE;
+
+    if (ga_grow(gap, 1) == FAIL)
+	return FAIL;
+    bp = &DEBUGGY(gap, gap->ga_len);
+
+    /* Find "func" or "file". */
+    if (STRNCMP(p, "func", 4) == 0)
+	bp->dbg_type = DBG_FUNC;
+    else if (STRNCMP(p, "file", 4) == 0)
+	bp->dbg_type = DBG_FILE;
+    else if (
+#ifdef FEAT_PROFILE
+	    gap != &prof_ga &&
+#endif
+	    STRNCMP(p, "here", 4) == 0)
+    {
+	if (curbuf->b_ffname == NULL)
+	{
+	    EMSG(_(e_noname));
+	    return FAIL;
+	}
+	bp->dbg_type = DBG_FILE;
+	here = TRUE;
+    }
+    else
+    {
+	EMSG2(_(e_invarg2), p);
+	return FAIL;
+    }
+    p = skipwhite(p + 4);
+
+    /* Find optional line number. */
+    if (here)
+	bp->dbg_lnum = curwin->w_cursor.lnum;
+    else if (
+#ifdef FEAT_PROFILE
+	    gap != &prof_ga &&
+#endif
+	    VIM_ISDIGIT(*p))
+    {
+	bp->dbg_lnum = getdigits(&p);
+	p = skipwhite(p);
+    }
+    else
+	bp->dbg_lnum = 0;
+
+    /* Find the function or file name.  Don't accept a function name with (). */
+    if ((!here && *p == NUL)
+	    || (here && *p != NUL)
+	    || (bp->dbg_type == DBG_FUNC && strstr((char *)p, "()") != NULL))
+    {
+	EMSG2(_(e_invarg2), arg);
+	return FAIL;
+    }
+
+    if (bp->dbg_type == DBG_FUNC)
+	bp->dbg_name = vim_strsave(p);
+    else if (here)
+	bp->dbg_name = vim_strsave(curbuf->b_ffname);
+    else
+    {
+	/* Expand the file name in the same way as do_source().  This means
+	 * doing it twice, so that $DIR/file gets expanded when $DIR is
+	 * "~/dir". */
+#ifdef RISCOS
+	q = mch_munge_fname(p);
+#else
+	q = expand_env_save(p);
+#endif
+	if (q == NULL)
+	    return FAIL;
+#ifdef RISCOS
+	p = mch_munge_fname(q);
+#else
+	p = expand_env_save(q);
+#endif
+	vim_free(q);
+	if (p == NULL)
+	    return FAIL;
+	if (*p != '*')
+	{
+	    bp->dbg_name = fix_fname(p);
+	    vim_free(p);
+	}
+	else
+	    bp->dbg_name = p;
+    }
+
+    if (bp->dbg_name == NULL)
+	return FAIL;
+    return OK;
+}
+
+/*
+ * ":breakadd".
+ */
+    void
+ex_breakadd(eap)
+    exarg_T	*eap;
+{
+    struct debuggy *bp;
+    char_u	*pat;
+    garray_T	*gap;
+
+    gap = &dbg_breakp;
+#ifdef FEAT_PROFILE
+    if (eap->cmdidx == CMD_profile)
+	gap = &prof_ga;
+#endif
+
+    if (dbg_parsearg(eap->arg, gap) == OK)
+    {
+	bp = &DEBUGGY(gap, gap->ga_len);
+	bp->dbg_forceit = eap->forceit;
+
+	pat = file_pat_to_reg_pat(bp->dbg_name, NULL, NULL, FALSE);
+	if (pat != NULL)
+	{
+	    bp->dbg_prog = vim_regcomp(pat, RE_MAGIC + RE_STRING);
+	    vim_free(pat);
+	}
+	if (pat == NULL || bp->dbg_prog == NULL)
+	    vim_free(bp->dbg_name);
+	else
+	{
+	    if (bp->dbg_lnum == 0)	/* default line number is 1 */
+		bp->dbg_lnum = 1;
+#ifdef FEAT_PROFILE
+	    if (eap->cmdidx != CMD_profile)
+#endif
+	    {
+		DEBUGGY(gap, gap->ga_len).dbg_nr = ++last_breakp;
+		++debug_tick;
+	    }
+	    ++gap->ga_len;
+	}
+    }
+}
+
+/*
+ * ":debuggreedy".
+ */
+    void
+ex_debuggreedy(eap)
+    exarg_T	*eap;
+{
+    if (eap->addr_count == 0 || eap->line2 != 0)
+	debug_greedy = TRUE;
+    else
+	debug_greedy = FALSE;
+}
+
+/*
+ * ":breakdel" and ":profdel".
+ */
+    void
+ex_breakdel(eap)
+    exarg_T	*eap;
+{
+    struct debuggy *bp, *bpi;
+    int		nr;
+    int		todel = -1;
+    int		del_all = FALSE;
+    int		i;
+    linenr_T	best_lnum = 0;
+    garray_T	*gap;
+
+    gap = &dbg_breakp;
+#ifdef FEAT_PROFILE
+    if (eap->cmdidx == CMD_profdel)
+	gap = &prof_ga;
+#endif
+
+    if (vim_isdigit(*eap->arg))
+    {
+	/* ":breakdel {nr}" */
+	nr = atol((char *)eap->arg);
+	for (i = 0; i < gap->ga_len; ++i)
+	    if (DEBUGGY(gap, i).dbg_nr == nr)
+	    {
+		todel = i;
+		break;
+	    }
+    }
+    else if (*eap->arg == '*')
+    {
+	todel = 0;
+	del_all = TRUE;
+    }
+    else
+    {
+	/* ":breakdel {func|file} [lnum] {name}" */
+	if (dbg_parsearg(eap->arg, gap) == FAIL)
+	    return;
+	bp = &DEBUGGY(gap, gap->ga_len);
+	for (i = 0; i < gap->ga_len; ++i)
+	{
+	    bpi = &DEBUGGY(gap, i);
+	    if (bp->dbg_type == bpi->dbg_type
+		    && STRCMP(bp->dbg_name, bpi->dbg_name) == 0
+		    && (bp->dbg_lnum == bpi->dbg_lnum
+			|| (bp->dbg_lnum == 0
+			    && (best_lnum == 0
+				|| bpi->dbg_lnum < best_lnum))))
+	    {
+		todel = i;
+		best_lnum = bpi->dbg_lnum;
+	    }
+	}
+	vim_free(bp->dbg_name);
+    }
+
+    if (todel < 0)
+	EMSG2(_("E161: Breakpoint not found: %s"), eap->arg);
+    else
+    {
+	while (gap->ga_len > 0)
+	{
+	    vim_free(DEBUGGY(gap, todel).dbg_name);
+	    vim_free(DEBUGGY(gap, todel).dbg_prog);
+	    --gap->ga_len;
+	    if (todel < gap->ga_len)
+		mch_memmove(&DEBUGGY(gap, todel), &DEBUGGY(gap, todel + 1),
+			      (gap->ga_len - todel) * sizeof(struct debuggy));
+#ifdef FEAT_PROFILE
+	    if (eap->cmdidx == CMD_breakdel)
+#endif
+		++debug_tick;
+	    if (!del_all)
+		break;
+	}
+
+	/* If all breakpoints were removed clear the array. */
+	if (gap->ga_len == 0)
+	    ga_clear(gap);
+    }
+}
+
+/*
+ * ":breaklist".
+ */
+/*ARGSUSED*/
+    void
+ex_breaklist(eap)
+    exarg_T	*eap;
+{
+    struct debuggy *bp;
+    int		i;
+
+    if (dbg_breakp.ga_len == 0)
+	MSG(_("No breakpoints defined"));
+    else
+	for (i = 0; i < dbg_breakp.ga_len; ++i)
+	{
+	    bp = &BREAKP(i);
+	    smsg((char_u *)_("%3d  %s %s  line %ld"),
+		    bp->dbg_nr,
+		    bp->dbg_type == DBG_FUNC ? "func" : "file",
+		    bp->dbg_name,
+		    (long)bp->dbg_lnum);
+	}
+}
+
+/*
+ * Find a breakpoint for a function or sourced file.
+ * Returns line number at which to break; zero when no matching breakpoint.
+ */
+    linenr_T
+dbg_find_breakpoint(file, fname, after)
+    int		file;	    /* TRUE for a file, FALSE for a function */
+    char_u	*fname;	    /* file or function name */
+    linenr_T	after;	    /* after this line number */
+{
+    return debuggy_find(file, fname, after, &dbg_breakp, NULL);
+}
+
+#if defined(FEAT_PROFILE) || defined(PROTO)
+/*
+ * Return TRUE if profiling is on for a function or sourced file.
+ */
+    int
+has_profiling(file, fname, fp)
+    int		file;	    /* TRUE for a file, FALSE for a function */
+    char_u	*fname;	    /* file or function name */
+    int		*fp;	    /* return: forceit */
+{
+    return (debuggy_find(file, fname, (linenr_T)0, &prof_ga, fp)
+							      != (linenr_T)0);
+}
+#endif
+
+/*
+ * Common code for dbg_find_breakpoint() and has_profiling().
+ */
+    static linenr_T
+debuggy_find(file, fname, after, gap, fp)
+    int		file;	    /* TRUE for a file, FALSE for a function */
+    char_u	*fname;	    /* file or function name */
+    linenr_T	after;	    /* after this line number */
+    garray_T	*gap;	    /* either &dbg_breakp or &prof_ga */
+    int		*fp;	    /* if not NULL: return forceit */
+{
+    struct debuggy *bp;
+    int		i;
+    linenr_T	lnum = 0;
+    regmatch_T	regmatch;
+    char_u	*name = fname;
+    int		prev_got_int;
+
+    /* Return quickly when there are no breakpoints. */
+    if (gap->ga_len == 0)
+	return (linenr_T)0;
+
+    /* Replace K_SNR in function name with "<SNR>". */
+    if (!file && fname[0] == K_SPECIAL)
+    {
+	name = alloc((unsigned)STRLEN(fname) + 3);
+	if (name == NULL)
+	    name = fname;
+	else
+	{
+	    STRCPY(name, "<SNR>");
+	    STRCPY(name + 5, fname + 3);
+	}
+    }
+
+    for (i = 0; i < gap->ga_len; ++i)
+    {
+	/* Skip entries that are not useful or are for a line that is beyond
+	 * an already found breakpoint. */
+	bp = &DEBUGGY(gap, i);
+	if (((bp->dbg_type == DBG_FILE) == file && (
+#ifdef FEAT_PROFILE
+		gap == &prof_ga ||
+#endif
+		(bp->dbg_lnum > after && (lnum == 0 || bp->dbg_lnum < lnum)))))
+	{
+	    regmatch.regprog = bp->dbg_prog;
+	    regmatch.rm_ic = FALSE;
+	    /*
+	     * Save the value of got_int and reset it.  We don't want a
+	     * previous interruption cancel matching, only hitting CTRL-C
+	     * while matching should abort it.
+	     */
+	    prev_got_int = got_int;
+	    got_int = FALSE;
+	    if (vim_regexec(&regmatch, name, (colnr_T)0))
+	    {
+		lnum = bp->dbg_lnum;
+		if (fp != NULL)
+		    *fp = bp->dbg_forceit;
+	    }
+	    got_int |= prev_got_int;
+	}
+    }
+    if (name != fname)
+	vim_free(name);
+
+    return lnum;
+}
+
+/*
+ * Called when a breakpoint was encountered.
+ */
+    void
+dbg_breakpoint(name, lnum)
+    char_u	*name;
+    linenr_T	lnum;
+{
+    /* We need to check if this line is actually executed in do_one_cmd() */
+    debug_breakpoint_name = name;
+    debug_breakpoint_lnum = lnum;
+}
+
+
+# if defined(FEAT_PROFILE) || defined(FEAT_RELTIME) || defined(PROTO)
+/*
+ * Store the current time in "tm".
+ */
+    void
+profile_start(tm)
+    proftime_T *tm;
+{
+# ifdef WIN3264
+    QueryPerformanceCounter(tm);
+# else
+    gettimeofday(tm, NULL);
+# endif
+}
+
+/*
+ * Compute the elapsed time from "tm" till now and store in "tm".
+ */
+    void
+profile_end(tm)
+    proftime_T *tm;
+{
+    proftime_T now;
+
+# ifdef WIN3264
+    QueryPerformanceCounter(&now);
+    tm->QuadPart = now.QuadPart - tm->QuadPart;
+# else
+    gettimeofday(&now, NULL);
+    tm->tv_usec = now.tv_usec - tm->tv_usec;
+    tm->tv_sec = now.tv_sec - tm->tv_sec;
+    if (tm->tv_usec < 0)
+    {
+	tm->tv_usec += 1000000;
+	--tm->tv_sec;
+    }
+# endif
+}
+
+/*
+ * Subtract the time "tm2" from "tm".
+ */
+    void
+profile_sub(tm, tm2)
+    proftime_T *tm, *tm2;
+{
+# ifdef WIN3264
+    tm->QuadPart -= tm2->QuadPart;
+# else
+    tm->tv_usec -= tm2->tv_usec;
+    tm->tv_sec -= tm2->tv_sec;
+    if (tm->tv_usec < 0)
+    {
+	tm->tv_usec += 1000000;
+	--tm->tv_sec;
+    }
+# endif
+}
+
+/*
+ * Return a string that represents the time in "tm".
+ * Uses a static buffer!
+ */
+    char *
+profile_msg(tm)
+    proftime_T *tm;
+{
+    static char buf[50];
+
+# ifdef WIN3264
+    LARGE_INTEGER   fr;
+
+    QueryPerformanceFrequency(&fr);
+    sprintf(buf, "%10.6lf", (double)tm->QuadPart / (double)fr.QuadPart);
+# else
+    sprintf(buf, "%3ld.%06ld", (long)tm->tv_sec, (long)tm->tv_usec);
+#endif
+    return buf;
+}
+
+# endif  /* FEAT_PROFILE || FEAT_RELTIME */
+
+# if defined(FEAT_PROFILE) || defined(PROTO)
+/*
+ * Functions for profiling.
+ */
+static void script_do_profile __ARGS((scriptitem_T *si));
+static void script_dump_profile __ARGS((FILE *fd));
+static proftime_T prof_wait_time;
+
+/*
+ * Set the time in "tm" to zero.
+ */
+    void
+profile_zero(tm)
+    proftime_T *tm;
+{
+# ifdef WIN3264
+    tm->QuadPart = 0;
+# else
+    tm->tv_usec = 0;
+    tm->tv_sec = 0;
+# endif
+}
+
+/*
+ * Add the time "tm2" to "tm".
+ */
+    void
+profile_add(tm, tm2)
+    proftime_T *tm, *tm2;
+{
+# ifdef WIN3264
+    tm->QuadPart += tm2->QuadPart;
+# else
+    tm->tv_usec += tm2->tv_usec;
+    tm->tv_sec += tm2->tv_sec;
+    if (tm->tv_usec >= 1000000)
+    {
+	tm->tv_usec -= 1000000;
+	++tm->tv_sec;
+    }
+# endif
+}
+
+/*
+ * Add the "self" time from the total time and the children's time.
+ */
+    void
+profile_self(self, total, children)
+    proftime_T *self, *total, *children;
+{
+    /* Check that the result won't be negative.  Can happen with recursive
+     * calls. */
+#ifdef WIN3264
+    if (total->QuadPart <= children->QuadPart)
+	return;
+#else
+    if (total->tv_sec < children->tv_sec
+	    || (total->tv_sec == children->tv_sec
+		&& total->tv_usec <= children->tv_usec))
+	return;
+#endif
+    profile_add(self, total);
+    profile_sub(self, children);
+}
+
+/*
+ * Get the current waittime.
+ */
+    void
+profile_get_wait(tm)
+    proftime_T *tm;
+{
+    *tm = prof_wait_time;
+}
+
+/*
+ * Subtract the passed waittime since "tm" from "tma".
+ */
+    void
+profile_sub_wait(tm, tma)
+    proftime_T *tm, *tma;
+{
+    proftime_T tm3 = prof_wait_time;
+
+    profile_sub(&tm3, tm);
+    profile_sub(tma, &tm3);
+}
+
+/*
+ * Return TRUE if "tm1" and "tm2" are equal.
+ */
+    int
+profile_equal(tm1, tm2)
+    proftime_T *tm1, *tm2;
+{
+# ifdef WIN3264
+    return (tm1->QuadPart == tm2->QuadPart);
+# else
+    return (tm1->tv_usec == tm2->tv_usec && tm1->tv_sec == tm2->tv_sec);
+# endif
+}
+
+/*
+ * Return <0, 0 or >0 if "tm1" < "tm2", "tm1" == "tm2" or "tm1" > "tm2"
+ */
+    int
+profile_cmp(tm1, tm2)
+    proftime_T *tm1, *tm2;
+{
+# ifdef WIN3264
+    return (int)(tm2->QuadPart - tm1->QuadPart);
+# else
+    if (tm1->tv_sec == tm2->tv_sec)
+	return tm2->tv_usec - tm1->tv_usec;
+    return tm2->tv_sec - tm1->tv_sec;
+# endif
+}
+
+static char_u	*profile_fname = NULL;
+static proftime_T pause_time;
+
+/*
+ * ":profile cmd args"
+ */
+    void
+ex_profile(eap)
+    exarg_T	*eap;
+{
+    char_u	*e;
+    int		len;
+
+    e = skiptowhite(eap->arg);
+    len = (int)(e - eap->arg);
+    e = skipwhite(e);
+
+    if (len == 5 && STRNCMP(eap->arg, "start", 5) == 0 && *e != NUL)
+    {
+	vim_free(profile_fname);
+	profile_fname = vim_strsave(e);
+	do_profiling = PROF_YES;
+	profile_zero(&prof_wait_time);
+	set_vim_var_nr(VV_PROFILING, 1L);
+    }
+    else if (do_profiling == PROF_NONE)
+	EMSG(_("E750: First use :profile start <fname>"));
+    else if (STRCMP(eap->arg, "pause") == 0)
+    {
+	if (do_profiling == PROF_YES)
+	    profile_start(&pause_time);
+	do_profiling = PROF_PAUSED;
+    }
+    else if (STRCMP(eap->arg, "continue") == 0)
+    {
+	if (do_profiling == PROF_PAUSED)
+	{
+	    profile_end(&pause_time);
+	    profile_add(&prof_wait_time, &pause_time);
+	}
+	do_profiling = PROF_YES;
+    }
+    else
+    {
+	/* The rest is similar to ":breakadd". */
+	ex_breakadd(eap);
+    }
+}
+
+/*
+ * Dump the profiling info.
+ */
+    void
+profile_dump()
+{
+    FILE	*fd;
+
+    if (profile_fname != NULL)
+    {
+	fd = mch_fopen((char *)profile_fname, "w");
+	if (fd == NULL)
+	    EMSG2(_(e_notopen), profile_fname);
+	else
+	{
+	    script_dump_profile(fd);
+	    func_dump_profile(fd);
+	    fclose(fd);
+	}
+    }
+}
+
+/*
+ * Start profiling script "fp".
+ */
+    static void
+script_do_profile(si)
+    scriptitem_T    *si;
+{
+    si->sn_pr_count = 0;
+    profile_zero(&si->sn_pr_total);
+    profile_zero(&si->sn_pr_self);
+
+    ga_init2(&si->sn_prl_ga, sizeof(sn_prl_T), 100);
+    si->sn_prl_idx = -1;
+    si->sn_prof_on = TRUE;
+    si->sn_pr_nest = 0;
+}
+
+/*
+ * save time when starting to invoke another script or function.
+ */
+    void
+script_prof_save(tm)
+    proftime_T	*tm;	    /* place to store wait time */
+{
+    scriptitem_T    *si;
+
+    if (current_SID > 0 && current_SID <= script_items.ga_len)
+    {
+	si = &SCRIPT_ITEM(current_SID);
+	if (si->sn_prof_on && si->sn_pr_nest++ == 0)
+	    profile_start(&si->sn_pr_child);
+    }
+    profile_get_wait(tm);
+}
+
+/*
+ * Count time spent in children after invoking another script or function.
+ */
+    void
+script_prof_restore(tm)
+    proftime_T	*tm;
+{
+    scriptitem_T    *si;
+
+    if (current_SID > 0 && current_SID <= script_items.ga_len)
+    {
+	si = &SCRIPT_ITEM(current_SID);
+	if (si->sn_prof_on && --si->sn_pr_nest == 0)
+	{
+	    profile_end(&si->sn_pr_child);
+	    profile_sub_wait(tm, &si->sn_pr_child); /* don't count wait time */
+	    profile_add(&si->sn_pr_children, &si->sn_pr_child);
+	    profile_add(&si->sn_prl_children, &si->sn_pr_child);
+	}
+    }
+}
+
+static proftime_T inchar_time;
+
+/*
+ * Called when starting to wait for the user to type a character.
+ */
+    void
+prof_inchar_enter()
+{
+    profile_start(&inchar_time);
+}
+
+/*
+ * Called when finished waiting for the user to type a character.
+ */
+    void
+prof_inchar_exit()
+{
+    profile_end(&inchar_time);
+    profile_add(&prof_wait_time, &inchar_time);
+}
+
+/*
+ * Dump the profiling results for all scripts in file "fd".
+ */
+    static void
+script_dump_profile(fd)
+    FILE    *fd;
+{
+    int		    id;
+    scriptitem_T    *si;
+    int		    i;
+    FILE	    *sfd;
+    sn_prl_T	    *pp;
+
+    for (id = 1; id <= script_items.ga_len; ++id)
+    {
+	si = &SCRIPT_ITEM(id);
+	if (si->sn_prof_on)
+	{
+	    fprintf(fd, "SCRIPT  %s\n", si->sn_name);
+	    if (si->sn_pr_count == 1)
+		fprintf(fd, "Sourced 1 time\n");
+	    else
+		fprintf(fd, "Sourced %d times\n", si->sn_pr_count);
+	    fprintf(fd, "Total time: %s\n", profile_msg(&si->sn_pr_total));
+	    fprintf(fd, " Self time: %s\n", profile_msg(&si->sn_pr_self));
+	    fprintf(fd, "\n");
+	    fprintf(fd, "count  total (s)   self (s)\n");
+
+	    sfd = mch_fopen((char *)si->sn_name, "r");
+	    if (sfd == NULL)
+		fprintf(fd, "Cannot open file!\n");
+	    else
+	    {
+		for (i = 0; i < si->sn_prl_ga.ga_len; ++i)
+		{
+		    if (vim_fgets(IObuff, IOSIZE, sfd))
+			break;
+		    pp = &PRL_ITEM(si, i);
+		    if (pp->snp_count > 0)
+		    {
+			fprintf(fd, "%5d ", pp->snp_count);
+			if (profile_equal(&pp->sn_prl_total, &pp->sn_prl_self))
+			    fprintf(fd, "           ");
+			else
+			    fprintf(fd, "%s ", profile_msg(&pp->sn_prl_total));
+			fprintf(fd, "%s ", profile_msg(&pp->sn_prl_self));
+		    }
+		    else
+			fprintf(fd, "                            ");
+		    fprintf(fd, "%s", IObuff);
+		}
+		fclose(sfd);
+	    }
+	    fprintf(fd, "\n");
+	}
+    }
+}
+
+/*
+ * Return TRUE when a function defined in the current script should be
+ * profiled.
+ */
+    int
+prof_def_func()
+{
+    if (current_SID > 0)
+	return SCRIPT_ITEM(current_SID).sn_pr_force;
+    return FALSE;
+}
+
+# endif
+#endif
+
+/*
+ * If 'autowrite' option set, try to write the file.
+ * Careful: autocommands may make "buf" invalid!
+ *
+ * return FAIL for failure, OK otherwise
+ */
+    int
+autowrite(buf, forceit)
+    buf_T	*buf;
+    int		forceit;
+{
+    int		r;
+
+    if (!(p_aw || p_awa) || !p_write
+#ifdef FEAT_QUICKFIX
+	    /* never autowrite a "nofile" or "nowrite" buffer */
+	    || bt_dontwrite(buf)
+#endif
+	    || (!forceit && buf->b_p_ro) || buf->b_ffname == NULL)
+	return FAIL;
+    r = buf_write_all(buf, forceit);
+
+    /* Writing may succeed but the buffer still changed, e.g., when there is a
+     * conversion error.  We do want to return FAIL then. */
+    if (buf_valid(buf) && bufIsChanged(buf))
+	r = FAIL;
+    return r;
+}
+
+/*
+ * flush all buffers, except the ones that are readonly
+ */
+    void
+autowrite_all()
+{
+    buf_T	*buf;
+
+    if (!(p_aw || p_awa) || !p_write)
+	return;
+    for (buf = firstbuf; buf; buf = buf->b_next)
+	if (bufIsChanged(buf) && !buf->b_p_ro)
+	{
+	    (void)buf_write_all(buf, FALSE);
+#ifdef FEAT_AUTOCMD
+	    /* an autocommand may have deleted the buffer */
+	    if (!buf_valid(buf))
+		buf = firstbuf;
+#endif
+	}
+}
+
+/*
+ * return TRUE if buffer was changed and cannot be abandoned.
+ */
+/*ARGSUSED*/
+    int
+check_changed(buf, checkaw, mult_win, forceit, allbuf)
+    buf_T	*buf;
+    int		checkaw;	/* do autowrite if buffer was changed */
+    int		mult_win;	/* check also when several wins for the buf */
+    int		forceit;
+    int		allbuf;		/* may write all buffers */
+{
+    if (       !forceit
+	    && bufIsChanged(buf)
+	    && (mult_win || buf->b_nwindows <= 1)
+	    && (!checkaw || autowrite(buf, forceit) == FAIL))
+    {
+#if defined(FEAT_GUI_DIALOG) || defined(FEAT_CON_DIALOG)
+	if ((p_confirm || cmdmod.confirm) && p_write)
+	{
+	    buf_T	*buf2;
+	    int		count = 0;
+
+	    if (allbuf)
+		for (buf2 = firstbuf; buf2 != NULL; buf2 = buf2->b_next)
+		    if (bufIsChanged(buf2)
+				     && (buf2->b_ffname != NULL
+# ifdef FEAT_BROWSE
+					 || cmdmod.browse
+# endif
+					))
+			++count;
+# ifdef FEAT_AUTOCMD
+	    if (!buf_valid(buf))
+		/* Autocommand deleted buffer, oops!  It's not changed now. */
+		return FALSE;
+# endif
+	    dialog_changed(buf, count > 1);
+# ifdef FEAT_AUTOCMD
+	    if (!buf_valid(buf))
+		/* Autocommand deleted buffer, oops!  It's not changed now. */
+		return FALSE;
+# endif
+	    return bufIsChanged(buf);
+	}
+#endif
+	EMSG(_(e_nowrtmsg));
+	return TRUE;
+    }
+    return FALSE;
+}
+
+#if defined(FEAT_GUI_DIALOG) || defined(FEAT_CON_DIALOG) || defined(PROTO)
+
+#if defined(FEAT_BROWSE) || defined(PROTO)
+/*
+ * When wanting to write a file without a file name, ask the user for a name.
+ */
+    void
+browse_save_fname(buf)
+    buf_T	*buf;
+{
+    if (buf->b_fname == NULL)
+    {
+	char_u *fname;
+
+	fname = do_browse(BROWSE_SAVE, (char_u *)_("Save As"),
+						 NULL, NULL, NULL, NULL, buf);
+	if (fname != NULL)
+	{
+	    if (setfname(buf, fname, NULL, TRUE) == OK)
+		buf->b_flags |= BF_NOTEDITED;
+	    vim_free(fname);
+	}
+    }
+}
+#endif
+
+/*
+ * Ask the user what to do when abondoning a changed buffer.
+ * Must check 'write' option first!
+ */
+    void
+dialog_changed(buf, checkall)
+    buf_T	*buf;
+    int		checkall;	/* may abandon all changed buffers */
+{
+    char_u	buff[IOSIZE];
+    int		ret;
+    buf_T	*buf2;
+
+    dialog_msg(buff, _("Save changes to \"%s\"?"),
+			(buf->b_fname != NULL) ?
+			buf->b_fname : (char_u *)_("Untitled"));
+    if (checkall)
+	ret = vim_dialog_yesnoallcancel(VIM_QUESTION, NULL, buff, 1);
+    else
+	ret = vim_dialog_yesnocancel(VIM_QUESTION, NULL, buff, 1);
+
+    if (ret == VIM_YES)
+    {
+#ifdef FEAT_BROWSE
+	/* May get file name, when there is none */
+	browse_save_fname(buf);
+#endif
+	if (buf->b_fname != NULL)   /* didn't hit Cancel */
+	    (void)buf_write_all(buf, FALSE);
+    }
+    else if (ret == VIM_NO)
+    {
+	unchanged(buf, TRUE);
+    }
+    else if (ret == VIM_ALL)
+    {
+	/*
+	 * Write all modified files that can be written.
+	 * Skip readonly buffers, these need to be confirmed
+	 * individually.
+	 */
+	for (buf2 = firstbuf; buf2 != NULL; buf2 = buf2->b_next)
+	{
+	    if (bufIsChanged(buf2)
+		    && (buf2->b_ffname != NULL
+#ifdef FEAT_BROWSE
+			|| cmdmod.browse
+#endif
+			)
+		    && !buf2->b_p_ro)
+	    {
+#ifdef FEAT_BROWSE
+		/* May get file name, when there is none */
+		browse_save_fname(buf2);
+#endif
+		if (buf2->b_fname != NULL)   /* didn't hit Cancel */
+		    (void)buf_write_all(buf2, FALSE);
+#ifdef FEAT_AUTOCMD
+		/* an autocommand may have deleted the buffer */
+		if (!buf_valid(buf2))
+		    buf2 = firstbuf;
+#endif
+	    }
+	}
+    }
+    else if (ret == VIM_DISCARDALL)
+    {
+	/*
+	 * mark all buffers as unchanged
+	 */
+	for (buf2 = firstbuf; buf2 != NULL; buf2 = buf2->b_next)
+	    unchanged(buf2, TRUE);
+    }
+}
+#endif
+
+/*
+ * Return TRUE if the buffer "buf" can be abandoned, either by making it
+ * hidden, autowriting it or unloading it.
+ */
+    int
+can_abandon(buf, forceit)
+    buf_T	*buf;
+    int		forceit;
+{
+    return (	   P_HID(buf)
+		|| !bufIsChanged(buf)
+		|| buf->b_nwindows > 1
+		|| autowrite(buf, forceit) == OK
+		|| forceit);
+}
+
+/*
+ * Return TRUE if any buffer was changed and cannot be abandoned.
+ * That changed buffer becomes the current buffer.
+ */
+    int
+check_changed_any(hidden)
+    int		hidden;		/* Only check hidden buffers */
+{
+    buf_T	*buf;
+    int		save;
+#ifdef FEAT_WINDOWS
+    win_T	*wp;
+#endif
+
+    for (;;)
+    {
+	/* check curbuf first: if it was changed we can't abandon it */
+	if (!hidden && curbufIsChanged())
+	    buf = curbuf;
+	else
+	{
+	    for (buf = firstbuf; buf != NULL; buf = buf->b_next)
+		if ((!hidden || buf->b_nwindows == 0) && bufIsChanged(buf))
+		    break;
+	}
+	if (buf == NULL)    /* No buffers changed */
+	    return FALSE;
+
+	/* Try auto-writing the buffer.  If this fails but the buffer no
+	 * longer exists it's not changed, that's OK. */
+	if (check_changed(buf, p_awa, TRUE, FALSE, TRUE) && buf_valid(buf))
+	    break;	    /* didn't save - still changes */
+    }
+
+    exiting = FALSE;
+#if defined(FEAT_GUI_DIALOG) || defined(FEAT_CON_DIALOG)
+    /*
+     * When ":confirm" used, don't give an error message.
+     */
+    if (!(p_confirm || cmdmod.confirm))
+#endif
+    {
+	/* There must be a wait_return for this message, do_buffer()
+	 * may cause a redraw.  But wait_return() is a no-op when vgetc()
+	 * is busy (Quit used from window menu), then make sure we don't
+	 * cause a scroll up. */
+	if (vgetc_busy > 0)
+	{
+	    msg_row = cmdline_row;
+	    msg_col = 0;
+	    msg_didout = FALSE;
+	}
+	if (EMSG2(_("E162: No write since last change for buffer \"%s\""),
+		    buf_spname(buf) != NULL ? (char_u *)buf_spname(buf) :
+		    buf->b_fname))
+	{
+	    save = no_wait_return;
+	    no_wait_return = FALSE;
+	    wait_return(FALSE);
+	    no_wait_return = save;
+	}
+    }
+
+#ifdef FEAT_WINDOWS
+    /* Try to find a window that contains the buffer. */
+    if (buf != curbuf)
+	for (wp = firstwin; wp != NULL; wp = wp->w_next)
+	    if (wp->w_buffer == buf)
+	    {
+		win_goto(wp);
+# ifdef FEAT_AUTOCMD
+		/* Paranoia: did autocms wipe out the buffer with changes? */
+		if (!buf_valid(buf))
+		    return TRUE;
+# endif
+		break;
+	    }
+#endif
+
+    /* Open the changed buffer in the current window. */
+    if (buf != curbuf)
+	set_curbuf(buf, DOBUF_GOTO);
+
+    return TRUE;
+}
+
+/*
+ * return FAIL if there is no file name, OK if there is one
+ * give error message for FAIL
+ */
+    int
+check_fname()
+{
+    if (curbuf->b_ffname == NULL)
+    {
+	EMSG(_(e_noname));
+	return FAIL;
+    }
+    return OK;
+}
+
+/*
+ * flush the contents of a buffer, unless it has no file name
+ *
+ * return FAIL for failure, OK otherwise
+ */
+    int
+buf_write_all(buf, forceit)
+    buf_T	*buf;
+    int		forceit;
+{
+    int	    retval;
+#ifdef FEAT_AUTOCMD
+    buf_T	*old_curbuf = curbuf;
+#endif
+
+    retval = (buf_write(buf, buf->b_ffname, buf->b_fname,
+				   (linenr_T)1, buf->b_ml.ml_line_count, NULL,
+						  FALSE, forceit, TRUE, FALSE));
+#ifdef FEAT_AUTOCMD
+    if (curbuf != old_curbuf)
+    {
+	msg_source(hl_attr(HLF_W));
+	MSG(_("Warning: Entered other buffer unexpectedly (check autocommands)"));
+    }
+#endif
+    return retval;
+}
+
+/*
+ * Code to handle the argument list.
+ */
+
+static char_u	*do_one_arg __ARGS((char_u *str));
+static int	do_arglist __ARGS((char_u *str, int what, int after));
+static void	alist_check_arg_idx __ARGS((void));
+static int	editing_arg_idx __ARGS((win_T *win));
+#ifdef FEAT_LISTCMDS
+static int	alist_add_list __ARGS((int count, char_u **files, int after));
+#endif
+#define AL_SET	1
+#define AL_ADD	2
+#define AL_DEL	3
+
+/*
+ * Isolate one argument, taking backticks.
+ * Changes the argument in-place, puts a NUL after it.  Backticks remain.
+ * Return a pointer to the start of the next argument.
+ */
+    static char_u *
+do_one_arg(str)
+    char_u *str;
+{
+    char_u	*p;
+    int		inbacktick;
+
+    inbacktick = FALSE;
+    for (p = str; *str; ++str)
+    {
+	/* When the backslash is used for escaping the special meaning of a
+	 * character we need to keep it until wildcard expansion. */
+	if (rem_backslash(str))
+	{
+	    *p++ = *str++;
+	    *p++ = *str;
+	}
+	else
+	{
+	    /* An item ends at a space not in backticks */
+	    if (!inbacktick && vim_isspace(*str))
+		break;
+	    if (*str == '`')
+		inbacktick ^= TRUE;
+	    *p++ = *str;
+	}
+    }
+    str = skipwhite(str);
+    *p = NUL;
+
+    return str;
+}
+
+/*
+ * Separate the arguments in "str" and return a list of pointers in the
+ * growarray "gap".
+ */
+    int
+get_arglist(gap, str)
+    garray_T	*gap;
+    char_u	*str;
+{
+    ga_init2(gap, (int)sizeof(char_u *), 20);
+    while (*str != NUL)
+    {
+	if (ga_grow(gap, 1) == FAIL)
+	{
+	    ga_clear(gap);
+	    return FAIL;
+	}
+	((char_u **)gap->ga_data)[gap->ga_len++] = str;
+
+	/* Isolate one argument, change it in-place, put a NUL after it. */
+	str = do_one_arg(str);
+    }
+    return OK;
+}
+
+#if defined(FEAT_QUICKFIX) || defined(FEAT_SYN_HL) || defined(PROTO)
+/*
+ * Parse a list of arguments (file names), expand them and return in
+ * "fnames[fcountp]".
+ * Return FAIL or OK.
+ */
+    int
+get_arglist_exp(str, fcountp, fnamesp)
+    char_u	*str;
+    int		*fcountp;
+    char_u	***fnamesp;
+{
+    garray_T	ga;
+    int		i;
+
+    if (get_arglist(&ga, str) == FAIL)
+	return FAIL;
+    i = gen_expand_wildcards(ga.ga_len, (char_u **)ga.ga_data,
+				       fcountp, fnamesp, EW_FILE|EW_NOTFOUND);
+    ga_clear(&ga);
+    return i;
+}
+#endif
+
+#if defined(FEAT_GUI) || defined(FEAT_CLIENTSERVER) || defined(PROTO)
+/*
+ * Redefine the argument list.
+ */
+    void
+set_arglist(str)
+    char_u	*str;
+{
+    do_arglist(str, AL_SET, 0);
+}
+#endif
+
+/*
+ * "what" == AL_SET: Redefine the argument list to 'str'.
+ * "what" == AL_ADD: add files in 'str' to the argument list after "after".
+ * "what" == AL_DEL: remove files in 'str' from the argument list.
+ *
+ * Return FAIL for failure, OK otherwise.
+ */
+/*ARGSUSED*/
+    static int
+do_arglist(str, what, after)
+    char_u	*str;
+    int		what;
+    int		after;		/* 0 means before first one */
+{
+    garray_T	new_ga;
+    int		exp_count;
+    char_u	**exp_files;
+    int		i;
+#ifdef FEAT_LISTCMDS
+    char_u	*p;
+    int		match;
+#endif
+
+    /*
+     * Collect all file name arguments in "new_ga".
+     */
+    if (get_arglist(&new_ga, str) == FAIL)
+	return FAIL;
+
+#ifdef FEAT_LISTCMDS
+    if (what == AL_DEL)
+    {
+	regmatch_T	regmatch;
+	int		didone;
+
+	/*
+	 * Delete the items: use each item as a regexp and find a match in the
+	 * argument list.
+	 */
+#ifdef CASE_INSENSITIVE_FILENAME
+	regmatch.rm_ic = TRUE;		/* Always ignore case */
+#else
+	regmatch.rm_ic = FALSE;		/* Never ignore case */
+#endif
+	for (i = 0; i < new_ga.ga_len && !got_int; ++i)
+	{
+	    p = ((char_u **)new_ga.ga_data)[i];
+	    p = file_pat_to_reg_pat(p, NULL, NULL, FALSE);
+	    if (p == NULL)
+		break;
+	    regmatch.regprog = vim_regcomp(p, p_magic ? RE_MAGIC : 0);
+	    if (regmatch.regprog == NULL)
+	    {
+		vim_free(p);
+		break;
+	    }
+
+	    didone = FALSE;
+	    for (match = 0; match < ARGCOUNT; ++match)
+		if (vim_regexec(&regmatch, alist_name(&ARGLIST[match]),
+								  (colnr_T)0))
+		{
+		    didone = TRUE;
+		    vim_free(ARGLIST[match].ae_fname);
+		    mch_memmove(ARGLIST + match, ARGLIST + match + 1,
+			    (ARGCOUNT - match - 1) * sizeof(aentry_T));
+		    --ALIST(curwin)->al_ga.ga_len;
+		    if (curwin->w_arg_idx > match)
+			--curwin->w_arg_idx;
+		    --match;
+		}
+
+	    vim_free(regmatch.regprog);
+	    vim_free(p);
+	    if (!didone)
+		EMSG2(_(e_nomatch2), ((char_u **)new_ga.ga_data)[i]);
+	}
+	ga_clear(&new_ga);
+    }
+    else
+#endif
+    {
+	i = expand_wildcards(new_ga.ga_len, (char_u **)new_ga.ga_data,
+		&exp_count, &exp_files, EW_DIR|EW_FILE|EW_ADDSLASH|EW_NOTFOUND);
+	ga_clear(&new_ga);
+	if (i == FAIL)
+	    return FAIL;
+	if (exp_count == 0)
+	{
+	    EMSG(_(e_nomatch));
+	    return FAIL;
+	}
+
+#ifdef FEAT_LISTCMDS
+	if (what == AL_ADD)
+	{
+	    (void)alist_add_list(exp_count, exp_files, after);
+	    vim_free(exp_files);
+	}
+	else /* what == AL_SET */
+#endif
+	    alist_set(ALIST(curwin), exp_count, exp_files, FALSE, NULL, 0);
+    }
+
+    alist_check_arg_idx();
+
+    return OK;
+}
+
+/*
+ * Check the validity of the arg_idx for each other window.
+ */
+    static void
+alist_check_arg_idx()
+{
+#ifdef FEAT_WINDOWS
+    win_T	*win;
+    tabpage_T	*tp;
+
+    FOR_ALL_TAB_WINDOWS(tp, win)
+	if (win->w_alist == curwin->w_alist)
+	    check_arg_idx(win);
+#else
+    check_arg_idx(curwin);
+#endif
+}
+
+/*
+ * Return TRUE if window "win" is editing then file at the current argument
+ * index.
+ */
+    static int
+editing_arg_idx(win)
+    win_T	*win;
+{
+    return !(win->w_arg_idx >= WARGCOUNT(win)
+		|| (win->w_buffer->b_fnum
+				      != WARGLIST(win)[win->w_arg_idx].ae_fnum
+		    && (win->w_buffer->b_ffname == NULL
+			 || !(fullpathcmp(
+				 alist_name(&WARGLIST(win)[win->w_arg_idx]),
+				win->w_buffer->b_ffname, TRUE) & FPC_SAME))));
+}
+
+/*
+ * Check if window "win" is editing the w_arg_idx file in its argument list.
+ */
+    void
+check_arg_idx(win)
+    win_T	*win;
+{
+    if (WARGCOUNT(win) > 1 && !editing_arg_idx(win))
+    {
+	/* We are not editing the current entry in the argument list.
+	 * Set "arg_had_last" if we are editing the last one. */
+	win->w_arg_idx_invalid = TRUE;
+	if (win->w_arg_idx != WARGCOUNT(win) - 1
+		&& arg_had_last == FALSE
+#ifdef FEAT_WINDOWS
+		&& ALIST(win) == &global_alist
+#endif
+		&& GARGCOUNT > 0
+		&& win->w_arg_idx < GARGCOUNT
+		&& (win->w_buffer->b_fnum == GARGLIST[GARGCOUNT - 1].ae_fnum
+		    || (win->w_buffer->b_ffname != NULL
+			&& (fullpathcmp(alist_name(&GARGLIST[GARGCOUNT - 1]),
+				win->w_buffer->b_ffname, TRUE) & FPC_SAME))))
+	    arg_had_last = TRUE;
+    }
+    else
+    {
+	/* We are editing the current entry in the argument list.
+	 * Set "arg_had_last" if it's also the last one */
+	win->w_arg_idx_invalid = FALSE;
+	if (win->w_arg_idx == WARGCOUNT(win) - 1
+#ifdef FEAT_WINDOWS
+		&& win->w_alist == &global_alist
+#endif
+		)
+	    arg_had_last = TRUE;
+    }
+}
+
+/*
+ * ":args", ":argslocal" and ":argsglobal".
+ */
+    void
+ex_args(eap)
+    exarg_T	*eap;
+{
+    int		i;
+
+    if (eap->cmdidx != CMD_args)
+    {
+#if defined(FEAT_WINDOWS) && defined(FEAT_LISTCMDS)
+	alist_unlink(ALIST(curwin));
+	if (eap->cmdidx == CMD_argglobal)
+	    ALIST(curwin) = &global_alist;
+	else /* eap->cmdidx == CMD_arglocal */
+	    alist_new();
+#else
+	ex_ni(eap);
+	return;
+#endif
+    }
+
+    if (!ends_excmd(*eap->arg))
+    {
+	/*
+	 * ":args file ..": define new argument list, handle like ":next"
+	 * Also for ":argslocal file .." and ":argsglobal file ..".
+	 */
+	ex_next(eap);
+    }
+    else
+#if defined(FEAT_WINDOWS) && defined(FEAT_LISTCMDS)
+	if (eap->cmdidx == CMD_args)
+#endif
+    {
+	/*
+	 * ":args": list arguments.
+	 */
+	if (ARGCOUNT > 0)
+	{
+	    /* Overwrite the command, for a short list there is no scrolling
+	     * required and no wait_return(). */
+	    gotocmdline(TRUE);
+	    for (i = 0; i < ARGCOUNT; ++i)
+	    {
+		if (i == curwin->w_arg_idx)
+		    msg_putchar('[');
+		msg_outtrans(alist_name(&ARGLIST[i]));
+		if (i == curwin->w_arg_idx)
+		    msg_putchar(']');
+		msg_putchar(' ');
+	    }
+	}
+    }
+#if defined(FEAT_WINDOWS) && defined(FEAT_LISTCMDS)
+    else if (eap->cmdidx == CMD_arglocal)
+    {
+	garray_T	*gap = &curwin->w_alist->al_ga;
+
+	/*
+	 * ":argslocal": make a local copy of the global argument list.
+	 */
+	if (ga_grow(gap, GARGCOUNT) == OK)
+	    for (i = 0; i < GARGCOUNT; ++i)
+		if (GARGLIST[i].ae_fname != NULL)
+		{
+		    AARGLIST(curwin->w_alist)[gap->ga_len].ae_fname =
+					    vim_strsave(GARGLIST[i].ae_fname);
+		    AARGLIST(curwin->w_alist)[gap->ga_len].ae_fnum =
+							  GARGLIST[i].ae_fnum;
+		    ++gap->ga_len;
+		}
+    }
+#endif
+}
+
+/*
+ * ":previous", ":sprevious", ":Next" and ":sNext".
+ */
+    void
+ex_previous(eap)
+    exarg_T	*eap;
+{
+    /* If past the last one already, go to the last one. */
+    if (curwin->w_arg_idx - (int)eap->line2 >= ARGCOUNT)
+	do_argfile(eap, ARGCOUNT - 1);
+    else
+	do_argfile(eap, curwin->w_arg_idx - (int)eap->line2);
+}
+
+/*
+ * ":rewind", ":first", ":sfirst" and ":srewind".
+ */
+    void
+ex_rewind(eap)
+    exarg_T	*eap;
+{
+    do_argfile(eap, 0);
+}
+
+/*
+ * ":last" and ":slast".
+ */
+    void
+ex_last(eap)
+    exarg_T	*eap;
+{
+    do_argfile(eap, ARGCOUNT - 1);
+}
+
+/*
+ * ":argument" and ":sargument".
+ */
+    void
+ex_argument(eap)
+    exarg_T	*eap;
+{
+    int		i;
+
+    if (eap->addr_count > 0)
+	i = eap->line2 - 1;
+    else
+	i = curwin->w_arg_idx;
+    do_argfile(eap, i);
+}
+
+/*
+ * Edit file "argn" of the argument lists.
+ */
+    void
+do_argfile(eap, argn)
+    exarg_T	*eap;
+    int		argn;
+{
+    int		other;
+    char_u	*p;
+    int		old_arg_idx = curwin->w_arg_idx;
+
+    if (argn < 0 || argn >= ARGCOUNT)
+    {
+	if (ARGCOUNT <= 1)
+	    EMSG(_("E163: There is only one file to edit"));
+	else if (argn < 0)
+	    EMSG(_("E164: Cannot go before first file"));
+	else
+	    EMSG(_("E165: Cannot go beyond last file"));
+    }
+    else
+    {
+	setpcmark();
+#ifdef FEAT_GUI
+	need_mouse_correct = TRUE;
+#endif
+
+#ifdef FEAT_WINDOWS
+	/* split window or create new tab page first */
+	if (*eap->cmd == 's' || cmdmod.tab != 0)
+	{
+	    if (win_split(0, 0) == FAIL)
+		return;
+# ifdef FEAT_SCROLLBIND
+	    curwin->w_p_scb = FALSE;
+# endif
+	}
+	else
+#endif
+	{
+	    /*
+	     * if 'hidden' set, only check for changed file when re-editing
+	     * the same buffer
+	     */
+	    other = TRUE;
+	    if (P_HID(curbuf))
+	    {
+		p = fix_fname(alist_name(&ARGLIST[argn]));
+		other = otherfile(p);
+		vim_free(p);
+	    }
+	    if ((!P_HID(curbuf) || !other)
+		  && check_changed(curbuf, TRUE, !other, eap->forceit, FALSE))
+		return;
+	}
+
+	curwin->w_arg_idx = argn;
+	if (argn == ARGCOUNT - 1
+#ifdef FEAT_WINDOWS
+		&& curwin->w_alist == &global_alist
+#endif
+	   )
+	    arg_had_last = TRUE;
+
+	/* Edit the file; always use the last known line number.
+	 * When it fails (e.g. Abort for already edited file) restore the
+	 * argument index. */
+	if (do_ecmd(0, alist_name(&ARGLIST[curwin->w_arg_idx]), NULL,
+		      eap, ECMD_LAST,
+		      (P_HID(curwin->w_buffer) ? ECMD_HIDE : 0) +
+				   (eap->forceit ? ECMD_FORCEIT : 0)) == FAIL)
+	    curwin->w_arg_idx = old_arg_idx;
+	/* like Vi: set the mark where the cursor is in the file. */
+	else if (eap->cmdidx != CMD_argdo)
+	    setmark('\'');
+    }
+}
+
+/*
+ * ":next", and commands that behave like it.
+ */
+    void
+ex_next(eap)
+    exarg_T	*eap;
+{
+    int		i;
+
+    /*
+     * check for changed buffer now, if this fails the argument list is not
+     * redefined.
+     */
+    if (       P_HID(curbuf)
+	    || eap->cmdidx == CMD_snext
+	    || !check_changed(curbuf, TRUE, FALSE, eap->forceit, FALSE))
+    {
+	if (*eap->arg != NUL)		    /* redefine file list */
+	{
+	    if (do_arglist(eap->arg, AL_SET, 0) == FAIL)
+		return;
+	    i = 0;
+	}
+	else
+	    i = curwin->w_arg_idx + (int)eap->line2;
+	do_argfile(eap, i);
+    }
+}
+
+#ifdef FEAT_LISTCMDS
+/*
+ * ":argedit"
+ */
+    void
+ex_argedit(eap)
+    exarg_T	*eap;
+{
+    int		fnum;
+    int		i;
+    char_u	*s;
+
+    /* Add the argument to the buffer list and get the buffer number. */
+    fnum = buflist_add(eap->arg, BLN_LISTED);
+
+    /* Check if this argument is already in the argument list. */
+    for (i = 0; i < ARGCOUNT; ++i)
+	if (ARGLIST[i].ae_fnum == fnum)
+	    break;
+    if (i == ARGCOUNT)
+    {
+	/* Can't find it, add it to the argument list. */
+	s = vim_strsave(eap->arg);
+	if (s == NULL)
+	    return;
+	i = alist_add_list(1, &s,
+	       eap->addr_count > 0 ? (int)eap->line2 : curwin->w_arg_idx + 1);
+	if (i < 0)
+	    return;
+	curwin->w_arg_idx = i;
+    }
+
+    alist_check_arg_idx();
+
+    /* Edit the argument. */
+    do_argfile(eap, i);
+}
+
+/*
+ * ":argadd"
+ */
+    void
+ex_argadd(eap)
+    exarg_T	*eap;
+{
+    do_arglist(eap->arg, AL_ADD,
+	       eap->addr_count > 0 ? (int)eap->line2 : curwin->w_arg_idx + 1);
+#ifdef FEAT_TITLE
+    maketitle();
+#endif
+}
+
+/*
+ * ":argdelete"
+ */
+    void
+ex_argdelete(eap)
+    exarg_T	*eap;
+{
+    int		i;
+    int		n;
+
+    if (eap->addr_count > 0)
+    {
+	/* ":1,4argdel": Delete all arguments in the range. */
+	if (eap->line2 > ARGCOUNT)
+	    eap->line2 = ARGCOUNT;
+	n = eap->line2 - eap->line1 + 1;
+	if (*eap->arg != NUL || n <= 0)
+	    EMSG(_(e_invarg));
+	else
+	{
+	    for (i = eap->line1; i <= eap->line2; ++i)
+		vim_free(ARGLIST[i - 1].ae_fname);
+	    mch_memmove(ARGLIST + eap->line1 - 1, ARGLIST + eap->line2,
+			(size_t)((ARGCOUNT - eap->line2) * sizeof(aentry_T)));
+	    ALIST(curwin)->al_ga.ga_len -= n;
+	    if (curwin->w_arg_idx >= eap->line2)
+		curwin->w_arg_idx -= n;
+	    else if (curwin->w_arg_idx > eap->line1)
+		curwin->w_arg_idx = eap->line1;
+	}
+    }
+    else if (*eap->arg == NUL)
+	EMSG(_(e_argreq));
+    else
+	do_arglist(eap->arg, AL_DEL, 0);
+#ifdef FEAT_TITLE
+    maketitle();
+#endif
+}
+
+/*
+ * ":argdo", ":windo", ":bufdo", ":tabdo"
+ */
+    void
+ex_listdo(eap)
+    exarg_T	*eap;
+{
+    int		i;
+#ifdef FEAT_WINDOWS
+    win_T	*wp;
+    tabpage_T	*tp;
+#endif
+    buf_T	*buf;
+    int		next_fnum = 0;
+#if defined(FEAT_AUTOCMD) && defined(FEAT_SYN_HL)
+    char_u	*save_ei = NULL;
+#endif
+    char_u	*p_shm_save;
+
+#ifndef FEAT_WINDOWS
+    if (eap->cmdidx == CMD_windo)
+    {
+	ex_ni(eap);
+	return;
+    }
+#endif
+
+#if defined(FEAT_AUTOCMD) && defined(FEAT_SYN_HL)
+    if (eap->cmdidx != CMD_windo && eap->cmdidx != CMD_tabdo)
+	/* Don't do syntax HL autocommands.  Skipping the syntax file is a
+	 * great speed improvement. */
+	save_ei = au_event_disable(",Syntax");
+#endif
+
+    if (eap->cmdidx == CMD_windo
+	    || eap->cmdidx == CMD_tabdo
+	    || P_HID(curbuf)
+	    || !check_changed(curbuf, TRUE, FALSE, eap->forceit, FALSE))
+    {
+	/* start at the first argument/window/buffer */
+	i = 0;
+#ifdef FEAT_WINDOWS
+	wp = firstwin;
+	tp = first_tabpage;
+#endif
+	/* set pcmark now */
+	if (eap->cmdidx == CMD_bufdo)
+	    goto_buffer(eap, DOBUF_FIRST, FORWARD, 0);
+	else
+	    setpcmark();
+	listcmd_busy = TRUE;	    /* avoids setting pcmark below */
+
+	while (!got_int)
+	{
+	    if (eap->cmdidx == CMD_argdo)
+	    {
+		/* go to argument "i" */
+		if (i == ARGCOUNT)
+		    break;
+		/* Don't call do_argfile() when already there, it will try
+		 * reloading the file. */
+		if (curwin->w_arg_idx != i || !editing_arg_idx(curwin))
+		{
+		    /* Clear 'shm' to avoid that the file message overwrites
+		     * any output from the command. */
+		    p_shm_save = vim_strsave(p_shm);
+		    set_option_value((char_u *)"shm", 0L, (char_u *)"", 0);
+		    do_argfile(eap, i);
+		    set_option_value((char_u *)"shm", 0L, p_shm_save, 0);
+		    vim_free(p_shm_save);
+		}
+		if (curwin->w_arg_idx != i)
+		    break;
+		++i;
+	    }
+#ifdef FEAT_WINDOWS
+	    else if (eap->cmdidx == CMD_windo)
+	    {
+		/* go to window "wp" */
+		if (!win_valid(wp))
+		    break;
+		win_goto(wp);
+		if (curwin != wp)
+		    break;  /* something must be wrong */
+		wp = curwin->w_next;
+	    }
+	    else if (eap->cmdidx == CMD_tabdo)
+	    {
+		/* go to window "tp" */
+		if (!valid_tabpage(tp))
+		    break;
+		goto_tabpage_tp(tp);
+		tp = tp->tp_next;
+	    }
+#endif
+	    else if (eap->cmdidx == CMD_bufdo)
+	    {
+		/* Remember the number of the next listed buffer, in case
+		 * ":bwipe" is used or autocommands do something strange. */
+		next_fnum = -1;
+		for (buf = curbuf->b_next; buf != NULL; buf = buf->b_next)
+		    if (buf->b_p_bl)
+		    {
+			next_fnum = buf->b_fnum;
+			break;
+		    }
+	    }
+
+	    /* execute the command */
+	    do_cmdline(eap->arg, eap->getline, eap->cookie,
+						DOCMD_VERBOSE + DOCMD_NOWAIT);
+
+	    if (eap->cmdidx == CMD_bufdo)
+	    {
+		/* Done? */
+		if (next_fnum < 0)
+		    break;
+		/* Check if the buffer still exists. */
+		for (buf = firstbuf; buf != NULL; buf = buf->b_next)
+		    if (buf->b_fnum == next_fnum)
+			break;
+		if (buf == NULL)
+		    break;
+
+		/* Go to the next buffer.  Clear 'shm' to avoid that the file
+		 * message overwrites any output from the command. */
+		p_shm_save = vim_strsave(p_shm);
+		set_option_value((char_u *)"shm", 0L, (char_u *)"", 0);
+		goto_buffer(eap, DOBUF_FIRST, FORWARD, next_fnum);
+		set_option_value((char_u *)"shm", 0L, p_shm_save, 0);
+		vim_free(p_shm_save);
+
+		/* If autocommands took us elsewhere, quit here */
+		if (curbuf->b_fnum != next_fnum)
+		    break;
+	    }
+
+	    if (eap->cmdidx == CMD_windo)
+	    {
+		validate_cursor();	/* cursor may have moved */
+#ifdef FEAT_SCROLLBIND
+		/* required when 'scrollbind' has been set */
+		if (curwin->w_p_scb)
+		    do_check_scrollbind(TRUE);
+#endif
+	    }
+	}
+	listcmd_busy = FALSE;
+    }
+
+#if defined(FEAT_AUTOCMD) && defined(FEAT_SYN_HL)
+    if (save_ei != NULL)
+    {
+	au_event_restore(save_ei);
+	apply_autocmds(EVENT_SYNTAX, curbuf->b_p_syn,
+					       curbuf->b_fname, TRUE, curbuf);
+    }
+#endif
+}
+
+/*
+ * Add files[count] to the arglist of the current window after arg "after".
+ * The file names in files[count] must have been allocated and are taken over.
+ * Files[] itself is not taken over.
+ * Returns index of first added argument.  Returns -1 when failed (out of mem).
+ */
+    static int
+alist_add_list(count, files, after)
+    int		count;
+    char_u	**files;
+    int		after;	    /* where to add: 0 = before first one */
+{
+    int		i;
+
+    if (ga_grow(&ALIST(curwin)->al_ga, count) == OK)
+    {
+	if (after < 0)
+	    after = 0;
+	if (after > ARGCOUNT)
+	    after = ARGCOUNT;
+	if (after < ARGCOUNT)
+	    mch_memmove(&(ARGLIST[after + count]), &(ARGLIST[after]),
+				       (ARGCOUNT - after) * sizeof(aentry_T));
+	for (i = 0; i < count; ++i)
+	{
+	    ARGLIST[after + i].ae_fname = files[i];
+	    ARGLIST[after + i].ae_fnum = buflist_add(files[i], BLN_LISTED);
+	}
+	ALIST(curwin)->al_ga.ga_len += count;
+	if (curwin->w_arg_idx >= after)
+	    ++curwin->w_arg_idx;
+	return after;
+    }
+
+    for (i = 0; i < count; ++i)
+	vim_free(files[i]);
+    return -1;
+}
+
+#endif /* FEAT_LISTCMDS */
+
+#ifdef FEAT_EVAL
+/*
+ * ":compiler[!] {name}"
+ */
+    void
+ex_compiler(eap)
+    exarg_T	*eap;
+{
+    char_u	*buf;
+    char_u	*old_cur_comp = NULL;
+    char_u	*p;
+
+    if (*eap->arg == NUL)
+    {
+	/* List all compiler scripts. */
+	do_cmdline_cmd((char_u *)"echo globpath(&rtp, 'compiler/*.vim')");
+					/* ) keep the indenter happy... */
+    }
+    else
+    {
+	buf = alloc((unsigned)(STRLEN(eap->arg) + 14));
+	if (buf != NULL)
+	{
+	    if (eap->forceit)
+	    {
+		/* ":compiler! {name}" sets global options */
+		do_cmdline_cmd((char_u *)
+				   "command -nargs=* CompilerSet set <args>");
+	    }
+	    else
+	    {
+		/* ":compiler! {name}" sets local options.
+		 * To remain backwards compatible "current_compiler" is always
+		 * used.  A user's compiler plugin may set it, the distributed
+		 * plugin will then skip the settings.  Afterwards set
+		 * "b:current_compiler" and restore "current_compiler". */
+		old_cur_comp = get_var_value((char_u *)"current_compiler");
+		if (old_cur_comp != NULL)
+		    old_cur_comp = vim_strsave(old_cur_comp);
+		do_cmdline_cmd((char_u *)
+			      "command -nargs=* CompilerSet setlocal <args>");
+	    }
+	    do_unlet((char_u *)"current_compiler", TRUE);
+	    do_unlet((char_u *)"b:current_compiler", TRUE);
+
+	    sprintf((char *)buf, "compiler/%s.vim", eap->arg);
+	    if (source_runtime(buf, TRUE) == FAIL)
+		EMSG2(_("E666: compiler not supported: %s"), eap->arg);
+	    vim_free(buf);
+
+	    do_cmdline_cmd((char_u *)":delcommand CompilerSet");
+
+	    /* Set "b:current_compiler" from "current_compiler". */
+	    p = get_var_value((char_u *)"current_compiler");
+	    if (p != NULL)
+		set_internal_string_var((char_u *)"b:current_compiler", p);
+
+	    /* Restore "current_compiler" for ":compiler {name}". */
+	    if (!eap->forceit)
+	    {
+		if (old_cur_comp != NULL)
+		{
+		    set_internal_string_var((char_u *)"current_compiler",
+								old_cur_comp);
+		    vim_free(old_cur_comp);
+		}
+		else
+		    do_unlet((char_u *)"current_compiler", TRUE);
+	    }
+	}
+    }
+}
+#endif
+
+/*
+ * ":runtime {name}"
+ */
+    void
+ex_runtime(eap)
+    exarg_T	*eap;
+{
+    source_runtime(eap->arg, eap->forceit);
+}
+
+static void source_callback __ARGS((char_u *fname, void *cookie));
+
+/*ARGSUSED*/
+    static void
+source_callback(fname, cookie)
+    char_u	*fname;
+    void	*cookie;
+{
+    (void)do_source(fname, FALSE, DOSO_NONE);
+}
+
+/*
+ * Source the file "name" from all directories in 'runtimepath'.
+ * "name" can contain wildcards.
+ * When "all" is TRUE, source all files, otherwise only the first one.
+ * return FAIL when no file could be sourced, OK otherwise.
+ */
+    int
+source_runtime(name, all)
+    char_u	*name;
+    int		all;
+{
+    return do_in_runtimepath(name, all, source_callback, NULL);
+}
+
+/*
+ * Find "name" in 'runtimepath'.  When found, invoke the callback function for
+ * it: callback(fname, "cookie")
+ * When "all" is TRUE repeat for all matches, otherwise only the first one is
+ * used.
+ * Returns OK when at least one match found, FAIL otherwise.
+ */
+    int
+do_in_runtimepath(name, all, callback, cookie)
+    char_u	*name;
+    int		all;
+    void	(*callback)__ARGS((char_u *fname, void *ck));
+    void	*cookie;
+{
+    char_u	*rtp;
+    char_u	*np;
+    char_u	*buf;
+    char_u	*rtp_copy;
+    char_u	*tail;
+    int		num_files;
+    char_u	**files;
+    int		i;
+    int		did_one = FALSE;
+#ifdef AMIGA
+    struct Process	*proc = (struct Process *)FindTask(0L);
+    APTR		save_winptr = proc->pr_WindowPtr;
+
+    /* Avoid a requester here for a volume that doesn't exist. */
+    proc->pr_WindowPtr = (APTR)-1L;
+#endif
+
+    /* Make a copy of 'runtimepath'.  Invoking the callback may change the
+     * value. */
+    rtp_copy = vim_strsave(p_rtp);
+    buf = alloc(MAXPATHL);
+    if (buf != NULL && rtp_copy != NULL)
+    {
+	if (p_verbose > 1)
+	{
+	    verbose_enter();
+	    smsg((char_u *)_("Searching for \"%s\" in \"%s\""),
+						 (char *)name, (char *)p_rtp);
+	    verbose_leave();
+	}
+
+	/* Loop over all entries in 'runtimepath'. */
+	rtp = rtp_copy;
+	while (*rtp != NUL && (all || !did_one))
+	{
+	    /* Copy the path from 'runtimepath' to buf[]. */
+	    copy_option_part(&rtp, buf, MAXPATHL, ",");
+	    if (STRLEN(buf) + STRLEN(name) + 2 < MAXPATHL)
+	    {
+		add_pathsep(buf);
+		tail = buf + STRLEN(buf);
+
+		/* Loop over all patterns in "name" */
+		np = name;
+		while (*np != NUL && (all || !did_one))
+		{
+		    /* Append the pattern from "name" to buf[]. */
+		    copy_option_part(&np, tail, (int)(MAXPATHL - (tail - buf)),
+								       "\t ");
+
+		    if (p_verbose > 2)
+		    {
+			verbose_enter();
+			smsg((char_u *)_("Searching for \"%s\""), buf);
+			verbose_leave();
+		    }
+
+		    /* Expand wildcards, invoke the callback for each match. */
+		    if (gen_expand_wildcards(1, &buf, &num_files, &files,
+							       EW_FILE) == OK)
+		    {
+			for (i = 0; i < num_files; ++i)
+			{
+			    (*callback)(files[i], cookie);
+			    did_one = TRUE;
+			    if (!all)
+				break;
+			}
+			FreeWild(num_files, files);
+		    }
+		}
+	    }
+	}
+    }
+    vim_free(buf);
+    vim_free(rtp_copy);
+    if (p_verbose > 0 && !did_one)
+    {
+	verbose_enter();
+	smsg((char_u *)_("not found in 'runtimepath': \"%s\""), name);
+	verbose_leave();
+    }
+
+#ifdef AMIGA
+    proc->pr_WindowPtr = save_winptr;
+#endif
+
+    return did_one ? OK : FAIL;
+}
+
+#if defined(FEAT_EVAL) && defined(FEAT_AUTOCMD)
+/*
+ * ":options"
+ */
+/*ARGSUSED*/
+    void
+ex_options(eap)
+    exarg_T	*eap;
+{
+    cmd_source((char_u *)SYS_OPTWIN_FILE, NULL);
+}
+#endif
+
+/*
+ * ":source {fname}"
+ */
+    void
+ex_source(eap)
+    exarg_T	*eap;
+{
+#ifdef FEAT_BROWSE
+    if (cmdmod.browse)
+    {
+	char_u *fname = NULL;
+
+	fname = do_browse(0, (char_u *)_("Source Vim script"), eap->arg,
+				      NULL, NULL, BROWSE_FILTER_MACROS, NULL);
+	if (fname != NULL)
+	{
+	    cmd_source(fname, eap);
+	    vim_free(fname);
+	}
+    }
+    else
+#endif
+	cmd_source(eap->arg, eap);
+}
+
+    static void
+cmd_source(fname, eap)
+    char_u	*fname;
+    exarg_T	*eap;
+{
+    if (*fname == NUL)
+	EMSG(_(e_argreq));
+
+    else if (eap != NULL && eap->forceit)
+	/* ":source!": read Normal mdoe commands
+	 * Need to execute the commands directly.  This is required at least
+	 * for:
+	 * - ":g" command busy
+	 * - after ":argdo", ":windo" or ":bufdo"
+	 * - another command follows
+	 * - inside a loop
+	 */
+	openscript(fname, global_busy || listcmd_busy || eap->nextcmd != NULL
+#ifdef FEAT_EVAL
+						 || eap->cstack->cs_idx >= 0
+#endif
+						 );
+
+    /* ":source" read ex commands */
+    else if (do_source(fname, FALSE, DOSO_NONE) == FAIL)
+	EMSG2(_(e_notopen), fname);
+}
+
+/*
+ * ":source" and associated commands.
+ */
+/*
+ * Structure used to store info for each sourced file.
+ * It is shared between do_source() and getsourceline().
+ * This is required, because it needs to be handed to do_cmdline() and
+ * sourcing can be done recursively.
+ */
+struct source_cookie
+{
+    FILE	*fp;		/* opened file for sourcing */
+    char_u      *nextline;      /* if not NULL: line that was read ahead */
+    int		finished;	/* ":finish" used */
+#if defined (USE_CRNL) || defined (USE_CR)
+    int		fileformat;	/* EOL_UNKNOWN, EOL_UNIX or EOL_DOS */
+    int		error;		/* TRUE if LF found after CR-LF */
+#endif
+#ifdef FEAT_EVAL
+    linenr_T	breakpoint;	/* next line with breakpoint or zero */
+    char_u	*fname;		/* name of sourced file */
+    int		dbg_tick;	/* debug_tick when breakpoint was set */
+    int		level;		/* top nesting level of sourced file */
+#endif
+#ifdef FEAT_MBYTE
+    vimconv_T	conv;		/* type of conversion */
+#endif
+};
+
+#ifdef FEAT_EVAL
+/*
+ * Return the address holding the next breakpoint line for a source cookie.
+ */
+    linenr_T *
+source_breakpoint(cookie)
+    void *cookie;
+{
+    return &((struct source_cookie *)cookie)->breakpoint;
+}
+
+/*
+ * Return the address holding the debug tick for a source cookie.
+ */
+    int *
+source_dbg_tick(cookie)
+    void *cookie;
+{
+    return &((struct source_cookie *)cookie)->dbg_tick;
+}
+
+/*
+ * Return the nesting level for a source cookie.
+ */
+    int
+source_level(cookie)
+    void *cookie;
+{
+    return ((struct source_cookie *)cookie)->level;
+}
+#endif
+
+static char_u *get_one_sourceline __ARGS((struct source_cookie *sp));
+
+#if defined(WIN32) && defined(FEAT_CSCOPE)
+static FILE *fopen_noinh_readbin __ARGS((char *filename));
+
+/*
+ * Special function to open a file without handle inheritance.
+ */
+    static FILE *
+fopen_noinh_readbin(filename)
+    char    *filename;
+{
+    int	fd_tmp = mch_open(filename, O_RDONLY | O_BINARY | O_NOINHERIT, 0);
+
+    if (fd_tmp == -1)
+	return NULL;
+    return fdopen(fd_tmp, READBIN);
+}
+#endif
+
+
+/*
+ * do_source: Read the file "fname" and execute its lines as EX commands.
+ *
+ * This function may be called recursively!
+ *
+ * return FAIL if file could not be opened, OK otherwise
+ */
+    int
+do_source(fname, check_other, is_vimrc)
+    char_u	*fname;
+    int		check_other;	    /* check for .vimrc and _vimrc */
+    int		is_vimrc;	    /* DOSO_ value */
+{
+    struct source_cookie    cookie;
+    char_u		    *save_sourcing_name;
+    linenr_T		    save_sourcing_lnum;
+    char_u		    *p;
+    char_u		    *fname_exp;
+    int			    retval = FAIL;
+#ifdef FEAT_EVAL
+    scid_T		    save_current_SID;
+    static scid_T	    last_current_SID = 0;
+    void		    *save_funccalp;
+    int			    save_debug_break_level = debug_break_level;
+    scriptitem_T	    *si = NULL;
+# ifdef UNIX
+    struct stat		    st;
+    int			    stat_ok;
+# endif
+#endif
+#ifdef STARTUPTIME
+    struct timeval	    tv_rel;
+    struct timeval	    tv_start;
+#endif
+#ifdef FEAT_PROFILE
+    proftime_T		    wait_start;
+#endif
+
+#ifdef RISCOS
+    p = mch_munge_fname(fname);
+#else
+    p = expand_env_save(fname);
+#endif
+    if (p == NULL)
+	return retval;
+    fname_exp = fix_fname(p);
+    vim_free(p);
+    if (fname_exp == NULL)
+	return retval;
+    if (mch_isdir(fname_exp))
+    {
+	smsg((char_u *)_("Cannot source a directory: \"%s\""), fname);
+	goto theend;
+    }
+
+#ifdef FEAT_AUTOCMD
+    /* Apply SourceCmd autocommands, they should get the file and source it. */
+    if (has_autocmd(EVENT_SOURCECMD, fname_exp, NULL)
+	    && apply_autocmds(EVENT_SOURCECMD, fname_exp, fname_exp,
+							       FALSE, curbuf))
+# ifdef FEAT_EVAL
+	return aborting() ? FAIL : OK;
+# else
+	return OK;
+# endif
+
+    /* Apply SourcePre autocommands, they may get the file. */
+    apply_autocmds(EVENT_SOURCEPRE, fname_exp, fname_exp, FALSE, curbuf);
+#endif
+
+#if defined(WIN32) && defined(FEAT_CSCOPE)
+    cookie.fp = fopen_noinh_readbin((char *)fname_exp);
+#else
+    cookie.fp = mch_fopen((char *)fname_exp, READBIN);
+#endif
+    if (cookie.fp == NULL && check_other)
+    {
+	/*
+	 * Try again, replacing file name ".vimrc" by "_vimrc" or vice versa,
+	 * and ".exrc" by "_exrc" or vice versa.
+	 */
+	p = gettail(fname_exp);
+	if ((*p == '.' || *p == '_')
+		&& (STRICMP(p + 1, "vimrc") == 0
+		    || STRICMP(p + 1, "gvimrc") == 0
+		    || STRICMP(p + 1, "exrc") == 0))
+	{
+	    if (*p == '_')
+		*p = '.';
+	    else
+		*p = '_';
+#if defined(WIN32) && defined(FEAT_CSCOPE)
+	    cookie.fp = fopen_noinh_readbin((char *)fname_exp);
+#else
+	    cookie.fp = mch_fopen((char *)fname_exp, READBIN);
+#endif
+	}
+    }
+
+    if (cookie.fp == NULL)
+    {
+	if (p_verbose > 0)
+	{
+	    verbose_enter();
+	    if (sourcing_name == NULL)
+		smsg((char_u *)_("could not source \"%s\""), fname);
+	    else
+		smsg((char_u *)_("line %ld: could not source \"%s\""),
+							sourcing_lnum, fname);
+	    verbose_leave();
+	}
+	goto theend;
+    }
+
+    /*
+     * The file exists.
+     * - In verbose mode, give a message.
+     * - For a vimrc file, may want to set 'compatible', call vimrc_found().
+     */
+    if (p_verbose > 1)
+    {
+	verbose_enter();
+	if (sourcing_name == NULL)
+	    smsg((char_u *)_("sourcing \"%s\""), fname);
+	else
+	    smsg((char_u *)_("line %ld: sourcing \"%s\""),
+							sourcing_lnum, fname);
+	verbose_leave();
+    }
+    if (is_vimrc == DOSO_VIMRC)
+	vimrc_found(fname_exp, (char_u *)"MYVIMRC");
+    else if (is_vimrc == DOSO_GVIMRC)
+	vimrc_found(fname_exp, (char_u *)"MYGVIMRC");
+
+#ifdef USE_CRNL
+    /* If no automatic file format: Set default to CR-NL. */
+    if (*p_ffs == NUL)
+	cookie.fileformat = EOL_DOS;
+    else
+	cookie.fileformat = EOL_UNKNOWN;
+    cookie.error = FALSE;
+#endif
+
+#ifdef USE_CR
+    /* If no automatic file format: Set default to CR. */
+    if (*p_ffs == NUL)
+	cookie.fileformat = EOL_MAC;
+    else
+	cookie.fileformat = EOL_UNKNOWN;
+    cookie.error = FALSE;
+#endif
+
+    cookie.nextline = NULL;
+    cookie.finished = FALSE;
+
+#ifdef FEAT_EVAL
+    /*
+     * Check if this script has a breakpoint.
+     */
+    cookie.breakpoint = dbg_find_breakpoint(TRUE, fname_exp, (linenr_T)0);
+    cookie.fname = fname_exp;
+    cookie.dbg_tick = debug_tick;
+
+    cookie.level = ex_nesting_level;
+#endif
+#ifdef FEAT_MBYTE
+    cookie.conv.vc_type = CONV_NONE;		/* no conversion */
+
+    /* Try reading the first few bytes to check for a UTF-8 BOM. */
+    {
+	char_u	    buf[3];
+
+	if (fread((char *)buf, sizeof(char_u), (size_t)3, cookie.fp)
+								  == (size_t)3
+		&& buf[0] == 0xef && buf[1] == 0xbb && buf[2] == 0xbf)
+	    /* Found BOM, setup conversion and skip over it. */
+	    convert_setup(&cookie.conv, (char_u *)"utf-8", p_enc);
+	else
+	    /* No BOM found, rewind. */
+	    fseek(cookie.fp, 0L, SEEK_SET);
+    }
+#endif
+
+    /*
+     * Keep the sourcing name/lnum, for recursive calls.
+     */
+    save_sourcing_name = sourcing_name;
+    sourcing_name = fname_exp;
+    save_sourcing_lnum = sourcing_lnum;
+    sourcing_lnum = 0;
+
+#ifdef STARTUPTIME
+    time_push(&tv_rel, &tv_start);
+#endif
+
+#ifdef FEAT_EVAL
+# ifdef FEAT_PROFILE
+    if (do_profiling == PROF_YES)
+	prof_child_enter(&wait_start);		/* entering a child now */
+# endif
+
+    /* Don't use local function variables, if called from a function.
+     * Also starts profiling timer for nested script. */
+    save_funccalp = save_funccal();
+
+    /*
+     * Check if this script was sourced before to finds its SID.
+     * If it's new, generate a new SID.
+     */
+    save_current_SID = current_SID;
+# ifdef UNIX
+    stat_ok = (mch_stat((char *)fname_exp, &st) >= 0);
+# endif
+    for (current_SID = script_items.ga_len; current_SID > 0; --current_SID)
+    {
+	si = &SCRIPT_ITEM(current_SID);
+	if (si->sn_name != NULL
+		&& (
+# ifdef UNIX
+		    /* Compare dev/ino when possible, it catches symbolic
+		     * links.  Also compare file names, the inode may change
+		     * when the file was edited. */
+		    ((stat_ok && si->sn_dev != -1)
+			&& (si->sn_dev == st.st_dev
+			    && si->sn_ino == st.st_ino)) ||
+# endif
+		fnamecmp(si->sn_name, fname_exp) == 0))
+	    break;
+    }
+    if (current_SID == 0)
+    {
+	current_SID = ++last_current_SID;
+	if (ga_grow(&script_items, (int)(current_SID - script_items.ga_len))
+								      == FAIL)
+	    goto almosttheend;
+	while (script_items.ga_len < current_SID)
+	{
+	    ++script_items.ga_len;
+	    SCRIPT_ITEM(script_items.ga_len).sn_name = NULL;
+# ifdef FEAT_PROFILE
+	    SCRIPT_ITEM(script_items.ga_len).sn_prof_on = FALSE;
+# endif
+	}
+	si = &SCRIPT_ITEM(current_SID);
+	si->sn_name = fname_exp;
+	fname_exp = NULL;
+# ifdef UNIX
+	if (stat_ok)
+	{
+	    si->sn_dev = st.st_dev;
+	    si->sn_ino = st.st_ino;
+	}
+	else
+	    si->sn_dev = -1;
+# endif
+
+	/* Allocate the local script variables to use for this script. */
+	new_script_vars(current_SID);
+    }
+
+# ifdef FEAT_PROFILE
+    if (do_profiling == PROF_YES)
+    {
+	int	forceit;
+
+	/* Check if we do profiling for this script. */
+	if (!si->sn_prof_on && has_profiling(TRUE, si->sn_name, &forceit))
+	{
+	    script_do_profile(si);
+	    si->sn_pr_force = forceit;
+	}
+	if (si->sn_prof_on)
+	{
+	    ++si->sn_pr_count;
+	    profile_start(&si->sn_pr_start);
+	    profile_zero(&si->sn_pr_children);
+	}
+    }
+# endif
+#endif
+
+    /*
+     * Call do_cmdline, which will call getsourceline() to get the lines.
+     */
+    do_cmdline(NULL, getsourceline, (void *)&cookie,
+				     DOCMD_VERBOSE|DOCMD_NOWAIT|DOCMD_REPEAT);
+
+    retval = OK;
+
+#ifdef FEAT_PROFILE
+    if (do_profiling == PROF_YES)
+    {
+	/* Get "si" again, "script_items" may have been reallocated. */
+	si = &SCRIPT_ITEM(current_SID);
+	if (si->sn_prof_on)
+	{
+	    profile_end(&si->sn_pr_start);
+	    profile_sub_wait(&wait_start, &si->sn_pr_start);
+	    profile_add(&si->sn_pr_total, &si->sn_pr_start);
+	    profile_self(&si->sn_pr_self, &si->sn_pr_start,
+							 &si->sn_pr_children);
+	}
+    }
+#endif
+
+    if (got_int)
+	EMSG(_(e_interr));
+    sourcing_name = save_sourcing_name;
+    sourcing_lnum = save_sourcing_lnum;
+    if (p_verbose > 1)
+    {
+	verbose_enter();
+	smsg((char_u *)_("finished sourcing %s"), fname);
+	if (sourcing_name != NULL)
+	    smsg((char_u *)_("continuing in %s"), sourcing_name);
+	verbose_leave();
+    }
+#ifdef STARTUPTIME
+    vim_snprintf(IObuff, IOSIZE, "sourcing %s", fname);
+    time_msg(IObuff, &tv_start);
+    time_pop(&tv_rel);
+#endif
+
+#ifdef FEAT_EVAL
+    /*
+     * After a "finish" in debug mode, need to break at first command of next
+     * sourced file.
+     */
+    if (save_debug_break_level > ex_nesting_level
+	    && debug_break_level == ex_nesting_level)
+	++debug_break_level;
+#endif
+
+#ifdef FEAT_EVAL
+almosttheend:
+    current_SID = save_current_SID;
+    restore_funccal(save_funccalp);
+# ifdef FEAT_PROFILE
+    if (do_profiling == PROF_YES)
+	prof_child_exit(&wait_start);		/* leaving a child now */
+# endif
+#endif
+    fclose(cookie.fp);
+    vim_free(cookie.nextline);
+#ifdef FEAT_MBYTE
+    convert_setup(&cookie.conv, NULL, NULL);
+#endif
+
+theend:
+    vim_free(fname_exp);
+    return retval;
+}
+
+#if defined(FEAT_EVAL) || defined(PROTO)
+
+/*
+ * ":scriptnames"
+ */
+/*ARGSUSED*/
+    void
+ex_scriptnames(eap)
+    exarg_T	*eap;
+{
+    int i;
+
+    for (i = 1; i <= script_items.ga_len && !got_int; ++i)
+	if (SCRIPT_ITEM(i).sn_name != NULL)
+	    smsg((char_u *)"%3d: %s", i, SCRIPT_ITEM(i).sn_name);
+}
+
+# if defined(BACKSLASH_IN_FILENAME) || defined(PROTO)
+/*
+ * Fix slashes in the list of script names for 'shellslash'.
+ */
+    void
+scriptnames_slash_adjust()
+{
+    int i;
+
+    for (i = 1; i <= script_items.ga_len; ++i)
+	if (SCRIPT_ITEM(i).sn_name != NULL)
+	    slash_adjust(SCRIPT_ITEM(i).sn_name);
+}
+# endif
+
+/*
+ * Get a pointer to a script name.  Used for ":verbose set".
+ */
+    char_u *
+get_scriptname(id)
+    scid_T	id;
+{
+    if (id == SID_MODELINE)
+	return (char_u *)_("modeline");
+    if (id == SID_CMDARG)
+	return (char_u *)_("--cmd argument");
+    if (id == SID_CARG)
+	return (char_u *)_("-c argument");
+    if (id == SID_ENV)
+	return (char_u *)_("environment variable");
+    if (id == SID_ERROR)
+	return (char_u *)_("error handler");
+    return SCRIPT_ITEM(id).sn_name;
+}
+
+# if defined(EXITFREE) || defined(PROTO)
+    void
+free_scriptnames()
+{
+    int			i;
+
+    for (i = script_items.ga_len; i > 0; --i)
+	vim_free(SCRIPT_ITEM(i).sn_name);
+    ga_clear(&script_items);
+}
+# endif
+
+#endif
+
+#if defined(USE_CR) || defined(PROTO)
+
+# if defined(__MSL__) && (__MSL__ >= 22)
+/*
+ * Newer version of the Metrowerks library handle DOS and UNIX files
+ * without help.
+ * Test with earlier versions, MSL 2.2 is the library supplied with
+ * Codewarrior Pro 2.
+ */
+    char *
+fgets_cr(s, n, stream)
+    char	*s;
+    int		n;
+    FILE	*stream;
+{
+    return fgets(s, n, stream);
+}
+# else
+/*
+ * Version of fgets() which also works for lines ending in a <CR> only
+ * (Macintosh format).
+ * For older versions of the Metrowerks library.
+ * At least CodeWarrior 9 needed this code.
+ */
+    char *
+fgets_cr(s, n, stream)
+    char	*s;
+    int		n;
+    FILE	*stream;
+{
+    int	c = 0;
+    int char_read = 0;
+
+    while (!feof(stream) && c != '\r' && c != '\n' && char_read < n - 1)
+    {
+	c = fgetc(stream);
+	s[char_read++] = c;
+	/* If the file is in DOS format, we need to skip a NL after a CR.  I
+	 * thought it was the other way around, but this appears to work... */
+	if (c == '\n')
+	{
+	    c = fgetc(stream);
+	    if (c != '\r')
+		ungetc(c, stream);
+	}
+    }
+
+    s[char_read] = 0;
+    if (char_read == 0)
+	return NULL;
+
+    if (feof(stream) && char_read == 1)
+	return NULL;
+
+    return s;
+}
+# endif
+#endif
+
+/*
+ * Get one full line from a sourced file.
+ * Called by do_cmdline() when it's called from do_source().
+ *
+ * Return a pointer to the line in allocated memory.
+ * Return NULL for end-of-file or some error.
+ */
+/* ARGSUSED */
+    char_u *
+getsourceline(c, cookie, indent)
+    int		c;		/* not used */
+    void	*cookie;
+    int		indent;		/* not used */
+{
+    struct source_cookie *sp = (struct source_cookie *)cookie;
+    char_u		*line;
+    char_u		*p, *s;
+
+#ifdef FEAT_EVAL
+    /* If breakpoints have been added/deleted need to check for it. */
+    if (sp->dbg_tick < debug_tick)
+    {
+	sp->breakpoint = dbg_find_breakpoint(TRUE, sp->fname, sourcing_lnum);
+	sp->dbg_tick = debug_tick;
+    }
+# ifdef FEAT_PROFILE
+    if (do_profiling == PROF_YES)
+	script_line_end();
+# endif
+#endif
+    /*
+     * Get current line.  If there is a read-ahead line, use it, otherwise get
+     * one now.
+     */
+    if (sp->finished)
+	line = NULL;
+    else if (sp->nextline == NULL)
+	line = get_one_sourceline(sp);
+    else
+    {
+	line = sp->nextline;
+	sp->nextline = NULL;
+	++sourcing_lnum;
+    }
+#ifdef FEAT_PROFILE
+    if (line != NULL && do_profiling == PROF_YES)
+	script_line_start();
+#endif
+
+    /* Only concatenate lines starting with a \ when 'cpoptions' doesn't
+     * contain the 'C' flag. */
+    if (line != NULL && (vim_strchr(p_cpo, CPO_CONCAT) == NULL))
+    {
+	/* compensate for the one line read-ahead */
+	--sourcing_lnum;
+	for (;;)
+	{
+	    sp->nextline = get_one_sourceline(sp);
+	    if (sp->nextline == NULL)
+		break;
+	    p = skipwhite(sp->nextline);
+	    if (*p != '\\')
+		break;
+	    s = alloc((int)(STRLEN(line) + STRLEN(p)));
+	    if (s == NULL)	/* out of memory */
+		break;
+	    STRCPY(s, line);
+	    STRCAT(s, p + 1);
+	    vim_free(line);
+	    line = s;
+	    vim_free(sp->nextline);
+	}
+    }
+
+#ifdef FEAT_MBYTE
+    if (line != NULL && sp->conv.vc_type != CONV_NONE)
+    {
+	/* Convert the encoding of the script line. */
+	s = string_convert(&sp->conv, line, NULL);
+	if (s != NULL)
+	{
+	    vim_free(line);
+	    line = s;
+	}
+    }
+#endif
+
+#ifdef FEAT_EVAL
+    /* Did we encounter a breakpoint? */
+    if (sp->breakpoint != 0 && sp->breakpoint <= sourcing_lnum)
+    {
+	dbg_breakpoint(sp->fname, sourcing_lnum);
+	/* Find next breakpoint. */
+	sp->breakpoint = dbg_find_breakpoint(TRUE, sp->fname, sourcing_lnum);
+	sp->dbg_tick = debug_tick;
+    }
+#endif
+
+    return line;
+}
+
+    static char_u *
+get_one_sourceline(sp)
+    struct source_cookie    *sp;
+{
+    garray_T		ga;
+    int			len;
+    int			c;
+    char_u		*buf;
+#ifdef USE_CRNL
+    int			has_cr;		/* CR-LF found */
+#endif
+#ifdef USE_CR
+    char_u		*scan;
+#endif
+    int			have_read = FALSE;
+
+    /* use a growarray to store the sourced line */
+    ga_init2(&ga, 1, 250);
+
+    /*
+     * Loop until there is a finished line (or end-of-file).
+     */
+    sourcing_lnum++;
+    for (;;)
+    {
+	/* make room to read at least 120 (more) characters */
+	if (ga_grow(&ga, 120) == FAIL)
+	    break;
+	buf = (char_u *)ga.ga_data;
+
+#ifdef USE_CR
+	if (sp->fileformat == EOL_MAC)
+	{
+	    if (fgets_cr((char *)buf + ga.ga_len, ga.ga_maxlen - ga.ga_len,
+							      sp->fp) == NULL)
+		break;
+	}
+	else
+#endif
+	    if (fgets((char *)buf + ga.ga_len, ga.ga_maxlen - ga.ga_len,
+							      sp->fp) == NULL)
+		break;
+	len = ga.ga_len + (int)STRLEN(buf + ga.ga_len);
+#ifdef USE_CRNL
+	/* Ignore a trailing CTRL-Z, when in Dos mode.	Only recognize the
+	 * CTRL-Z by its own, or after a NL. */
+	if (	   (len == 1 || (len >= 2 && buf[len - 2] == '\n'))
+		&& sp->fileformat == EOL_DOS
+		&& buf[len - 1] == Ctrl_Z)
+	{
+	    buf[len - 1] = NUL;
+	    break;
+	}
+#endif
+
+#ifdef USE_CR
+	/* If the read doesn't stop on a new line, and there's
+	 * some CR then we assume a Mac format */
+	if (sp->fileformat == EOL_UNKNOWN)
+	{
+	    if (buf[len - 1] != '\n' && vim_strchr(buf, '\r') != NULL)
+		sp->fileformat = EOL_MAC;
+	    else
+		sp->fileformat = EOL_UNIX;
+	}
+
+	if (sp->fileformat == EOL_MAC)
+	{
+	    scan = vim_strchr(buf, '\r');
+
+	    if (scan != NULL)
+	    {
+		*scan = '\n';
+		if (*(scan + 1) != 0)
+		{
+		    *(scan + 1) = 0;
+		    fseek(sp->fp, (long)(scan - buf - len + 1), SEEK_CUR);
+		}
+	    }
+	    len = STRLEN(buf);
+	}
+#endif
+
+	have_read = TRUE;
+	ga.ga_len = len;
+
+	/* If the line was longer than the buffer, read more. */
+	if (ga.ga_maxlen - ga.ga_len == 1 && buf[len - 1] != '\n')
+	    continue;
+
+	if (len >= 1 && buf[len - 1] == '\n')	/* remove trailing NL */
+	{
+#ifdef USE_CRNL
+	    has_cr = (len >= 2 && buf[len - 2] == '\r');
+	    if (sp->fileformat == EOL_UNKNOWN)
+	    {
+		if (has_cr)
+		    sp->fileformat = EOL_DOS;
+		else
+		    sp->fileformat = EOL_UNIX;
+	    }
+
+	    if (sp->fileformat == EOL_DOS)
+	    {
+		if (has_cr)	    /* replace trailing CR */
+		{
+		    buf[len - 2] = '\n';
+		    --len;
+		    --ga.ga_len;
+		}
+		else	    /* lines like ":map xx yy^M" will have failed */
+		{
+		    if (!sp->error)
+		    {
+			msg_source(hl_attr(HLF_W));
+			EMSG(_("W15: Warning: Wrong line separator, ^M may be missing"));
+		    }
+		    sp->error = TRUE;
+		    sp->fileformat = EOL_UNIX;
+		}
+	    }
+#endif
+	    /* The '\n' is escaped if there is an odd number of ^V's just
+	     * before it, first set "c" just before the 'V's and then check
+	     * len&c parities (is faster than ((len-c)%2 == 0)) -- Acevedo */
+	    for (c = len - 2; c >= 0 && buf[c] == Ctrl_V; c--)
+		;
+	    if ((len & 1) != (c & 1))	/* escaped NL, read more */
+	    {
+		sourcing_lnum++;
+		continue;
+	    }
+
+	    buf[len - 1] = NUL;		/* remove the NL */
+	}
+
+	/*
+	 * Check for ^C here now and then, so recursive :so can be broken.
+	 */
+	line_breakcheck();
+	break;
+    }
+
+    if (have_read)
+	return (char_u *)ga.ga_data;
+
+    vim_free(ga.ga_data);
+    return NULL;
+}
+
+#if defined(FEAT_PROFILE) || defined(PROTO)
+/*
+ * Called when starting to read a script line.
+ * "sourcing_lnum" must be correct!
+ * When skipping lines it may not actually be executed, but we won't find out
+ * until later and we need to store the time now.
+ */
+    void
+script_line_start()
+{
+    scriptitem_T    *si;
+    sn_prl_T	    *pp;
+
+    if (current_SID <= 0 || current_SID > script_items.ga_len)
+	return;
+    si = &SCRIPT_ITEM(current_SID);
+    if (si->sn_prof_on && sourcing_lnum >= 1)
+    {
+	/* Grow the array before starting the timer, so that the time spend
+	 * here isn't counted. */
+	ga_grow(&si->sn_prl_ga, (int)(sourcing_lnum - si->sn_prl_ga.ga_len));
+	si->sn_prl_idx = sourcing_lnum - 1;
+	while (si->sn_prl_ga.ga_len <= si->sn_prl_idx
+		&& si->sn_prl_ga.ga_len < si->sn_prl_ga.ga_maxlen)
+	{
+	    /* Zero counters for a line that was not used before. */
+	    pp = &PRL_ITEM(si, si->sn_prl_ga.ga_len);
+	    pp->snp_count = 0;
+	    profile_zero(&pp->sn_prl_total);
+	    profile_zero(&pp->sn_prl_self);
+	    ++si->sn_prl_ga.ga_len;
+	}
+	si->sn_prl_execed = FALSE;
+	profile_start(&si->sn_prl_start);
+	profile_zero(&si->sn_prl_children);
+	profile_get_wait(&si->sn_prl_wait);
+    }
+}
+
+/*
+ * Called when actually executing a function line.
+ */
+    void
+script_line_exec()
+{
+    scriptitem_T    *si;
+
+    if (current_SID <= 0 || current_SID > script_items.ga_len)
+	return;
+    si = &SCRIPT_ITEM(current_SID);
+    if (si->sn_prof_on && si->sn_prl_idx >= 0)
+	si->sn_prl_execed = TRUE;
+}
+
+/*
+ * Called when done with a function line.
+ */
+    void
+script_line_end()
+{
+    scriptitem_T    *si;
+    sn_prl_T	    *pp;
+
+    if (current_SID <= 0 || current_SID > script_items.ga_len)
+	return;
+    si = &SCRIPT_ITEM(current_SID);
+    if (si->sn_prof_on && si->sn_prl_idx >= 0
+				     && si->sn_prl_idx < si->sn_prl_ga.ga_len)
+    {
+	if (si->sn_prl_execed)
+	{
+	    pp = &PRL_ITEM(si, si->sn_prl_idx);
+	    ++pp->snp_count;
+	    profile_end(&si->sn_prl_start);
+	    profile_sub_wait(&si->sn_prl_wait, &si->sn_prl_start);
+	    profile_add(&pp->sn_prl_total, &si->sn_prl_start);
+	    profile_self(&pp->sn_prl_self, &si->sn_prl_start,
+							&si->sn_prl_children);
+	}
+	si->sn_prl_idx = -1;
+    }
+}
+#endif
+
+/*
+ * ":scriptencoding": Set encoding conversion for a sourced script.
+ * Without the multi-byte feature it's simply ignored.
+ */
+/*ARGSUSED*/
+    void
+ex_scriptencoding(eap)
+    exarg_T	*eap;
+{
+#ifdef FEAT_MBYTE
+    struct source_cookie	*sp;
+    char_u			*name;
+
+    if (!getline_equal(eap->getline, eap->cookie, getsourceline))
+    {
+	EMSG(_("E167: :scriptencoding used outside of a sourced file"));
+	return;
+    }
+
+    if (*eap->arg != NUL)
+    {
+	name = enc_canonize(eap->arg);
+	if (name == NULL)	/* out of memory */
+	    return;
+    }
+    else
+	name = eap->arg;
+
+    /* Setup for conversion from the specified encoding to 'encoding'. */
+    sp = (struct source_cookie *)getline_cookie(eap->getline, eap->cookie);
+    convert_setup(&sp->conv, name, p_enc);
+
+    if (name != eap->arg)
+	vim_free(name);
+#endif
+}
+
+#if defined(FEAT_EVAL) || defined(PROTO)
+/*
+ * ":finish": Mark a sourced file as finished.
+ */
+    void
+ex_finish(eap)
+    exarg_T	*eap;
+{
+    if (getline_equal(eap->getline, eap->cookie, getsourceline))
+	do_finish(eap, FALSE);
+    else
+	EMSG(_("E168: :finish used outside of a sourced file"));
+}
+
+/*
+ * Mark a sourced file as finished.  Possibly makes the ":finish" pending.
+ * Also called for a pending finish at the ":endtry" or after returning from
+ * an extra do_cmdline().  "reanimate" is used in the latter case.
+ */
+    void
+do_finish(eap, reanimate)
+    exarg_T	*eap;
+    int		reanimate;
+{
+    int		idx;
+
+    if (reanimate)
+	((struct source_cookie *)getline_cookie(eap->getline,
+					      eap->cookie))->finished = FALSE;
+
+    /*
+     * Cleanup (and inactivate) conditionals, but stop when a try conditional
+     * not in its finally clause (which then is to be executed next) is found.
+     * In this case, make the ":finish" pending for execution at the ":endtry".
+     * Otherwise, finish normally.
+     */
+    idx = cleanup_conditionals(eap->cstack, 0, TRUE);
+    if (idx >= 0)
+    {
+	eap->cstack->cs_pending[idx] = CSTP_FINISH;
+	report_make_pending(CSTP_FINISH, NULL);
+    }
+    else
+	((struct source_cookie *)getline_cookie(eap->getline,
+					       eap->cookie))->finished = TRUE;
+}
+
+
+/*
+ * Return TRUE when a sourced file had the ":finish" command: Don't give error
+ * message for missing ":endif".
+ * Return FALSE when not sourcing a file.
+ */
+    int
+source_finished(fgetline, cookie)
+    char_u	*(*fgetline) __ARGS((int, void *, int));
+    void	*cookie;
+{
+    return (getline_equal(fgetline, cookie, getsourceline)
+	    && ((struct source_cookie *)getline_cookie(
+						fgetline, cookie))->finished);
+}
+#endif
+
+#if defined(FEAT_LISTCMDS) || defined(PROTO)
+/*
+ * ":checktime [buffer]"
+ */
+    void
+ex_checktime(eap)
+    exarg_T	*eap;
+{
+    buf_T	*buf;
+    int		save_no_check_timestamps = no_check_timestamps;
+
+    no_check_timestamps = 0;
+    if (eap->addr_count == 0)	/* default is all buffers */
+	check_timestamps(FALSE);
+    else
+    {
+	buf = buflist_findnr((int)eap->line2);
+	if (buf != NULL)	/* cannot happen? */
+	    (void)buf_check_timestamp(buf, FALSE);
+    }
+    no_check_timestamps = save_no_check_timestamps;
+}
+#endif
+
+#if (defined(HAVE_LOCALE_H) || defined(X_LOCALE)) \
+	&& (defined(FEAT_EVAL) || defined(FEAT_MULTI_LANG))
+static char *get_locale_val __ARGS((int what));
+
+    static char *
+get_locale_val(what)
+    int		what;
+{
+    char	*loc;
+
+    /* Obtain the locale value from the libraries.  For DJGPP this is
+     * redefined and it doesn't use the arguments. */
+    loc = setlocale(what, NULL);
+
+# ifdef WIN32
+    if (loc != NULL)
+    {
+	char_u	*p;
+
+	/* setocale() returns something like "LC_COLLATE=<name>;LC_..." when
+	 * one of the values (e.g., LC_CTYPE) differs. */
+	p = vim_strchr(loc, '=');
+	if (p != NULL)
+	{
+	    loc = ++p;
+	    while (*p != NUL)	/* remove trailing newline */
+	    {
+		if (*p < ' ' || *p == ';')
+		{
+		    *p = NUL;
+		    break;
+		}
+		++p;
+	    }
+	}
+    }
+# endif
+
+    return loc;
+}
+#endif
+
+
+#ifdef WIN32
+/*
+ * On MS-Windows locale names are strings like "German_Germany.1252", but
+ * gettext expects "de".  Try to translate one into another here for a few
+ * supported languages.
+ */
+    static char_u *
+gettext_lang(char_u *name)
+{
+    int		i;
+    static char *(mtable[]) = {
+			"afrikaans",	"af",
+			"czech",	"cs",
+			"dutch",	"nl",
+			"german",	"de",
+			"english_united kingdom", "en_GB",
+			"spanish",	"es",
+			"french",	"fr",
+			"italian",	"it",
+			"japanese",	"ja",
+			"korean",	"ko",
+			"norwegian",	"no",
+			"polish",	"pl",
+			"russian",	"ru",
+			"slovak",	"sk",
+			"swedish",	"sv",
+			"ukrainian",	"uk",
+			"chinese_china", "zh_CN",
+			"chinese_taiwan", "zh_TW",
+			NULL};
+
+    for (i = 0; mtable[i] != NULL; i += 2)
+	if (STRNICMP(mtable[i], name, STRLEN(mtable[i])) == 0)
+	    return mtable[i + 1];
+    return name;
+}
+#endif
+
+#if defined(FEAT_MULTI_LANG) || defined(PROTO)
+/*
+ * Obtain the current messages language.  Used to set the default for
+ * 'helplang'.  May return NULL or an empty string.
+ */
+    char_u *
+get_mess_lang()
+{
+    char_u *p;
+
+# if (defined(HAVE_LOCALE_H) || defined(X_LOCALE))
+#  if defined(LC_MESSAGES)
+    p = (char_u *)get_locale_val(LC_MESSAGES);
+#  else
+    /* This is necessary for Win32, where LC_MESSAGES is not defined and $LANG
+     * may be set to the LCID number.  LC_COLLATE is the best guess, LC_TIME
+     * and LC_MONETARY may be set differently for a Japanese working in the
+     * US. */
+    p = (char_u *)get_locale_val(LC_COLLATE);
+#  endif
+# else
+    p = mch_getenv((char_u *)"LC_ALL");
+    if (p == NULL || *p == NUL)
+    {
+	p = mch_getenv((char_u *)"LC_MESSAGES");
+	if (p == NULL || *p == NUL)
+	    p = mch_getenv((char_u *)"LANG");
+    }
+# endif
+# ifdef WIN32
+    p = gettext_lang(p);
+# endif
+    return p;
+}
+#endif
+
+/* Complicated #if; matches with where get_mess_env() is used below. */
+#if (defined(FEAT_EVAL) && !((defined(HAVE_LOCALE_H) || defined(X_LOCALE)) \
+	    && defined(LC_MESSAGES))) \
+	|| ((defined(HAVE_LOCALE_H) || defined(X_LOCALE)) \
+		&& (defined(FEAT_GETTEXT) || defined(FEAT_MBYTE)) \
+		&& !defined(LC_MESSAGES))
+static char_u *get_mess_env __ARGS((void));
+
+/*
+ * Get the language used for messages from the environment.
+ */
+    static char_u *
+get_mess_env()
+{
+    char_u	*p;
+
+    p = mch_getenv((char_u *)"LC_ALL");
+    if (p == NULL || *p == NUL)
+    {
+	p = mch_getenv((char_u *)"LC_MESSAGES");
+	if (p == NULL || *p == NUL)
+	{
+	    p = mch_getenv((char_u *)"LANG");
+	    if (p != NULL && VIM_ISDIGIT(*p))
+		p = NULL;		/* ignore something like "1043" */
+# if defined(HAVE_LOCALE_H) || defined(X_LOCALE)
+	    if (p == NULL || *p == NUL)
+		p = (char_u *)get_locale_val(LC_CTYPE);
+# endif
+	}
+    }
+    return p;
+}
+#endif
+
+#if defined(FEAT_EVAL) || defined(PROTO)
+
+/*
+ * Set the "v:lang" variable according to the current locale setting.
+ * Also do "v:lc_time"and "v:ctype".
+ */
+    void
+set_lang_var()
+{
+    char_u	*loc;
+
+# if defined(HAVE_LOCALE_H) || defined(X_LOCALE)
+    loc = (char_u *)get_locale_val(LC_CTYPE);
+# else
+    /* setlocale() not supported: use the default value */
+    loc = (char_u *)"C";
+# endif
+    set_vim_var_string(VV_CTYPE, loc, -1);
+
+    /* When LC_MESSAGES isn't defined use the value from $LC_MESSAGES, fall
+     * back to LC_CTYPE if it's empty. */
+# if (defined(HAVE_LOCALE_H) || defined(X_LOCALE)) && defined(LC_MESSAGES)
+    loc = (char_u *)get_locale_val(LC_MESSAGES);
+# else
+    loc = get_mess_env();
+# endif
+    set_vim_var_string(VV_LANG, loc, -1);
+
+# if defined(HAVE_LOCALE_H) || defined(X_LOCALE)
+    loc = (char_u *)get_locale_val(LC_TIME);
+# endif
+    set_vim_var_string(VV_LC_TIME, loc, -1);
+}
+#endif
+
+#if (defined(HAVE_LOCALE_H) || defined(X_LOCALE)) \
+	&& (defined(FEAT_GETTEXT) || defined(FEAT_MBYTE))
+/*
+ * ":language":  Set the language (locale).
+ */
+    void
+ex_language(eap)
+    exarg_T	*eap;
+{
+    char	*loc;
+    char_u	*p;
+    char_u	*name;
+    int		what = LC_ALL;
+    char	*whatstr = "";
+#ifdef LC_MESSAGES
+# define VIM_LC_MESSAGES LC_MESSAGES
+#else
+# define VIM_LC_MESSAGES 6789
+#endif
+
+    name = eap->arg;
+
+    /* Check for "messages {name}", "ctype {name}" or "time {name}" argument.
+     * Allow abbreviation, but require at least 3 characters to avoid
+     * confusion with a two letter language name "me" or "ct". */
+    p = skiptowhite(eap->arg);
+    if ((*p == NUL || vim_iswhite(*p)) && p - eap->arg >= 3)
+    {
+	if (STRNICMP(eap->arg, "messages", p - eap->arg) == 0)
+	{
+	    what = VIM_LC_MESSAGES;
+	    name = skipwhite(p);
+	    whatstr = "messages ";
+	}
+	else if (STRNICMP(eap->arg, "ctype", p - eap->arg) == 0)
+	{
+	    what = LC_CTYPE;
+	    name = skipwhite(p);
+	    whatstr = "ctype ";
+	}
+	else if (STRNICMP(eap->arg, "time", p - eap->arg) == 0)
+	{
+	    what = LC_TIME;
+	    name = skipwhite(p);
+	    whatstr = "time ";
+	}
+    }
+
+    if (*name == NUL)
+    {
+#ifndef LC_MESSAGES
+	if (what == VIM_LC_MESSAGES)
+	    p = get_mess_env();
+	else
+#endif
+	    p = (char_u *)setlocale(what, NULL);
+	if (p == NULL || *p == NUL)
+	    p = (char_u *)"Unknown";
+	smsg((char_u *)_("Current %slanguage: \"%s\""), whatstr, p);
+    }
+    else
+    {
+#ifndef LC_MESSAGES
+	if (what == VIM_LC_MESSAGES)
+	    loc = "";
+	else
+#endif
+	    loc = setlocale(what, (char *)name);
+	if (loc == NULL)
+	    EMSG2(_("E197: Cannot set language to \"%s\""), name);
+	else
+	{
+#ifdef HAVE_NL_MSG_CAT_CNTR
+	    /* Need to do this for GNU gettext, otherwise cached translations
+	     * will be used again. */
+	    extern int _nl_msg_cat_cntr;
+
+	    ++_nl_msg_cat_cntr;
+#endif
+	    /* Reset $LC_ALL, otherwise it would overrule everything. */
+	    vim_setenv((char_u *)"LC_ALL", (char_u *)"");
+
+	    if (what != LC_TIME)
+	    {
+		/* Tell gettext() what to translate to.  It apparently doesn't
+		 * use the currently effective locale.  Also do this when
+		 * FEAT_GETTEXT isn't defined, so that shell commands use this
+		 * value. */
+		if (what == LC_ALL)
+		{
+		    vim_setenv((char_u *)"LANG", name);
+# ifdef WIN32
+		    /* Apparently MS-Windows printf() may cause a crash when
+		     * we give it 8-bit text while it's expecting text in the
+		     * current locale.  This call avoids that. */
+		    setlocale(LC_CTYPE, "C");
+# endif
+		}
+		if (what != LC_CTYPE)
+		{
+		    char_u	*mname;
+#ifdef WIN32
+		    mname = gettext_lang(name);
+#else
+		    mname = name;
+#endif
+		    vim_setenv((char_u *)"LC_MESSAGES", mname);
+#ifdef FEAT_MULTI_LANG
+		    set_helplang_default(mname);
+#endif
+		}
+
+		/* Set $LC_CTYPE, because it overrules $LANG, and
+		 * gtk_set_locale() calls setlocale() again.  gnome_init()
+		 * sets $LC_CTYPE to "en_US" (that's a bug!). */
+		if (what != VIM_LC_MESSAGES)
+		    vim_setenv((char_u *)"LC_CTYPE", name);
+# ifdef FEAT_GUI_GTK
+		/* Let GTK know what locale we're using.  Not sure this is
+		 * really needed... */
+		if (gui.in_use)
+		    (void)gtk_set_locale();
+# endif
+	    }
+
+# ifdef FEAT_EVAL
+	    /* Set v:lang, v:lc_time and v:ctype to the final result. */
+	    set_lang_var();
+# endif
+	}
+    }
+}
+
+# if defined(FEAT_CMDL_COMPL) || defined(PROTO)
+/*
+ * Function given to ExpandGeneric() to obtain the possible arguments of the
+ * ":language" command.
+ */
+/*ARGSUSED*/
+    char_u *
+get_lang_arg(xp, idx)
+    expand_T	*xp;
+    int		idx;
+{
+    if (idx == 0)
+	return (char_u *)"messages";
+    if (idx == 1)
+	return (char_u *)"ctype";
+    if (idx == 2)
+	return (char_u *)"time";
+    return NULL;
+}
+# endif
+
+#endif
--- /dev/null
+++ b/ex_docmd.c
@@ -1,0 +1,10942 @@
+/* vi:set ts=8 sts=4 sw=4:
+ *
+ * VIM - Vi IMproved	by Bram Moolenaar
+ *
+ * Do ":help uganda"  in Vim to read copying and usage conditions.
+ * Do ":help credits" in Vim to see a list of people who contributed.
+ * See README.txt for an overview of the Vim source code.
+ */
+
+/*
+ * ex_docmd.c: functions for executing an Ex command line.
+ */
+
+#include "vim.h"
+
+#ifdef HAVE_FCNTL_H
+# include <fcntl.h>	    /* for chdir() */
+#endif
+
+static int	quitmore = 0;
+static int	ex_pressedreturn = FALSE;
+#ifndef FEAT_PRINTER
+# define ex_hardcopy	ex_ni
+#endif
+
+#ifdef FEAT_USR_CMDS
+typedef struct ucmd
+{
+    char_u	*uc_name;	/* The command name */
+    long_u	uc_argt;	/* The argument type */
+    char_u	*uc_rep;	/* The command's replacement string */
+    long	uc_def;		/* The default value for a range/count */
+    scid_T	uc_scriptID;	/* SID where the command was defined */
+    int		uc_compl;	/* completion type */
+# if defined(FEAT_EVAL) && defined(FEAT_CMDL_COMPL)
+    char_u	*uc_compl_arg;	/* completion argument if any */
+# endif
+} ucmd_T;
+
+#define UC_BUFFER	1	/* -buffer: local to current buffer */
+
+static garray_T ucmds = {0, 0, sizeof(ucmd_T), 4, NULL};
+
+#define USER_CMD(i) (&((ucmd_T *)(ucmds.ga_data))[i])
+#define USER_CMD_GA(gap, i) (&((ucmd_T *)((gap)->ga_data))[i])
+
+static void do_ucmd __ARGS((exarg_T *eap));
+static void ex_command __ARGS((exarg_T *eap));
+static void ex_delcommand __ARGS((exarg_T *eap));
+# ifdef FEAT_CMDL_COMPL
+static char_u *get_user_command_name __ARGS((int idx));
+# endif
+
+#else
+# define ex_command	ex_ni
+# define ex_comclear	ex_ni
+# define ex_delcommand	ex_ni
+#endif
+
+#ifdef FEAT_EVAL
+static char_u	*do_one_cmd __ARGS((char_u **, int, struct condstack *, char_u *(*fgetline)(int, void *, int), void *cookie));
+#else
+static char_u	*do_one_cmd __ARGS((char_u **, int, char_u *(*fgetline)(int, void *, int), void *cookie));
+static int	if_level = 0;		/* depth in :if */
+#endif
+static char_u	*find_command __ARGS((exarg_T *eap, int *full));
+
+static void	ex_abbreviate __ARGS((exarg_T *eap));
+static void	ex_map __ARGS((exarg_T *eap));
+static void	ex_unmap __ARGS((exarg_T *eap));
+static void	ex_mapclear __ARGS((exarg_T *eap));
+static void	ex_abclear __ARGS((exarg_T *eap));
+#ifndef FEAT_MENU
+# define ex_emenu		ex_ni
+# define ex_menu		ex_ni
+# define ex_menutranslate	ex_ni
+#endif
+#ifdef FEAT_AUTOCMD
+static void	ex_autocmd __ARGS((exarg_T *eap));
+static void	ex_doautocmd __ARGS((exarg_T *eap));
+#else
+# define ex_autocmd		ex_ni
+# define ex_doautocmd		ex_ni
+# define ex_doautoall		ex_ni
+#endif
+#ifdef FEAT_LISTCMDS
+static void	ex_bunload __ARGS((exarg_T *eap));
+static void	ex_buffer __ARGS((exarg_T *eap));
+static void	ex_bmodified __ARGS((exarg_T *eap));
+static void	ex_bnext __ARGS((exarg_T *eap));
+static void	ex_bprevious __ARGS((exarg_T *eap));
+static void	ex_brewind __ARGS((exarg_T *eap));
+static void	ex_blast __ARGS((exarg_T *eap));
+#else
+# define ex_bunload		ex_ni
+# define ex_buffer		ex_ni
+# define ex_bmodified		ex_ni
+# define ex_bnext		ex_ni
+# define ex_bprevious		ex_ni
+# define ex_brewind		ex_ni
+# define ex_blast		ex_ni
+# define buflist_list		ex_ni
+# define ex_checktime		ex_ni
+#endif
+#if !defined(FEAT_LISTCMDS) || !defined(FEAT_WINDOWS)
+# define ex_buffer_all		ex_ni
+#endif
+static char_u	*getargcmd __ARGS((char_u **));
+static char_u	*skip_cmd_arg __ARGS((char_u *p, int rembs));
+static int	getargopt __ARGS((exarg_T *eap));
+#ifndef FEAT_QUICKFIX
+# define ex_make		ex_ni
+# define ex_cbuffer		ex_ni
+# define ex_cc			ex_ni
+# define ex_cnext		ex_ni
+# define ex_cfile		ex_ni
+# define qf_list		ex_ni
+# define qf_age			ex_ni
+# define ex_helpgrep		ex_ni
+# define ex_vimgrep		ex_ni
+#endif
+#if !defined(FEAT_QUICKFIX) || !defined(FEAT_WINDOWS)
+# define ex_cclose		ex_ni
+# define ex_copen		ex_ni
+# define ex_cwindow		ex_ni
+#endif
+#if !defined(FEAT_QUICKFIX) || !defined(FEAT_EVAL)
+# define ex_cexpr		ex_ni
+#endif
+
+static int	check_more __ARGS((int, int));
+static linenr_T get_address __ARGS((char_u **, int skip, int to_other_file));
+static void	get_flags __ARGS((exarg_T *eap));
+#if !defined(FEAT_PERL) || !defined(FEAT_PYTHON) || !defined(FEAT_TCL) \
+	|| !defined(FEAT_RUBY) || !defined(FEAT_MZSCHEME)
+static void	ex_script_ni __ARGS((exarg_T *eap));
+#endif
+static char_u	*invalid_range __ARGS((exarg_T *eap));
+static void	correct_range __ARGS((exarg_T *eap));
+#ifdef FEAT_QUICKFIX
+static char_u	*replace_makeprg __ARGS((exarg_T *eap, char_u *p, char_u **cmdlinep));
+#endif
+static char_u	*repl_cmdline __ARGS((exarg_T *eap, char_u *src, int srclen, char_u *repl, char_u **cmdlinep));
+static void	ex_highlight __ARGS((exarg_T *eap));
+static void	ex_colorscheme __ARGS((exarg_T *eap));
+static void	ex_quit __ARGS((exarg_T *eap));
+static void	ex_cquit __ARGS((exarg_T *eap));
+static void	ex_quit_all __ARGS((exarg_T *eap));
+#ifdef FEAT_WINDOWS
+static void	ex_close __ARGS((exarg_T *eap));
+static void	ex_win_close __ARGS((int forceit, win_T *win, tabpage_T *tp));
+static void	ex_only __ARGS((exarg_T *eap));
+static void	ex_resize __ARGS((exarg_T *eap));
+static void	ex_stag __ARGS((exarg_T *eap));
+static void	ex_tabclose __ARGS((exarg_T *eap));
+static void	ex_tabonly __ARGS((exarg_T *eap));
+static void	ex_tabnext __ARGS((exarg_T *eap));
+static void	ex_tabmove __ARGS((exarg_T *eap));
+static void	ex_tabs __ARGS((exarg_T *eap));
+#else
+# define ex_close		ex_ni
+# define ex_only		ex_ni
+# define ex_all			ex_ni
+# define ex_resize		ex_ni
+# define ex_splitview		ex_ni
+# define ex_stag		ex_ni
+# define ex_tabnext		ex_ni
+# define ex_tabmove		ex_ni
+# define ex_tabs		ex_ni
+# define ex_tabclose		ex_ni
+# define ex_tabonly		ex_ni
+#endif
+#if defined(FEAT_WINDOWS) && defined(FEAT_QUICKFIX)
+static void	ex_pclose __ARGS((exarg_T *eap));
+static void	ex_ptag __ARGS((exarg_T *eap));
+static void	ex_pedit __ARGS((exarg_T *eap));
+#else
+# define ex_pclose		ex_ni
+# define ex_ptag		ex_ni
+# define ex_pedit		ex_ni
+#endif
+static void	ex_hide __ARGS((exarg_T *eap));
+static void	ex_stop __ARGS((exarg_T *eap));
+static void	ex_exit __ARGS((exarg_T *eap));
+static void	ex_print __ARGS((exarg_T *eap));
+#ifdef FEAT_BYTEOFF
+static void	ex_goto __ARGS((exarg_T *eap));
+#else
+# define ex_goto		ex_ni
+#endif
+static void	ex_shell __ARGS((exarg_T *eap));
+static void	ex_preserve __ARGS((exarg_T *eap));
+static void	ex_recover __ARGS((exarg_T *eap));
+#ifndef FEAT_LISTCMDS
+# define ex_argedit		ex_ni
+# define ex_argadd		ex_ni
+# define ex_argdelete		ex_ni
+# define ex_listdo		ex_ni
+#endif
+static void	ex_mode __ARGS((exarg_T *eap));
+static void	ex_wrongmodifier __ARGS((exarg_T *eap));
+static void	ex_find __ARGS((exarg_T *eap));
+static void	ex_open __ARGS((exarg_T *eap));
+static void	ex_edit __ARGS((exarg_T *eap));
+#if !defined(FEAT_GUI) && !defined(FEAT_CLIENTSERVER)
+# define ex_drop		ex_ni
+#endif
+#ifndef FEAT_GUI
+# define ex_gui			ex_nogui
+static void	ex_nogui __ARGS((exarg_T *eap));
+#endif
+#if defined(FEAT_GUI_W32) && defined(FEAT_MENU) && defined(FEAT_TEAROFF)
+static void	ex_tearoff __ARGS((exarg_T *eap));
+#else
+# define ex_tearoff		ex_ni
+#endif
+#if (defined(FEAT_GUI_MSWIN) || defined(FEAT_GUI_GTK)) && defined(FEAT_MENU)
+static void	ex_popup __ARGS((exarg_T *eap));
+#else
+# define ex_popup		ex_ni
+#endif
+#ifndef FEAT_GUI_MSWIN
+# define ex_simalt		ex_ni
+#endif
+#if !defined(FEAT_GUI_MSWIN) && !defined(FEAT_GUI_GTK) && !defined(FEAT_GUI_MOTIF)
+# define gui_mch_find_dialog	ex_ni
+# define gui_mch_replace_dialog ex_ni
+#endif
+#if !defined(FEAT_GUI_GTK)
+# define ex_helpfind		ex_ni
+#endif
+#ifndef FEAT_CSCOPE
+# define do_cscope		ex_ni
+# define do_scscope		ex_ni
+# define do_cstag		ex_ni
+#endif
+#ifndef FEAT_SYN_HL
+# define ex_syntax		ex_ni
+#endif
+#ifndef FEAT_SPELL
+# define ex_spell		ex_ni
+# define ex_mkspell		ex_ni
+# define ex_spelldump		ex_ni
+# define ex_spellinfo		ex_ni
+# define ex_spellrepall		ex_ni
+#endif
+#ifndef FEAT_MZSCHEME
+# define ex_mzscheme		ex_script_ni
+# define ex_mzfile		ex_ni
+#endif
+#ifndef FEAT_PERL
+# define ex_perl		ex_script_ni
+# define ex_perldo		ex_ni
+#endif
+#ifndef FEAT_PYTHON
+# define ex_python		ex_script_ni
+# define ex_pyfile		ex_ni
+#endif
+#ifndef FEAT_TCL
+# define ex_tcl			ex_script_ni
+# define ex_tcldo		ex_ni
+# define ex_tclfile		ex_ni
+#endif
+#ifndef FEAT_RUBY
+# define ex_ruby		ex_script_ni
+# define ex_rubydo		ex_ni
+# define ex_rubyfile		ex_ni
+#endif
+#ifndef FEAT_SNIFF
+# define ex_sniff		ex_ni
+#endif
+#ifndef FEAT_KEYMAP
+# define ex_loadkeymap		ex_ni
+#endif
+static void	ex_swapname __ARGS((exarg_T *eap));
+static void	ex_syncbind __ARGS((exarg_T *eap));
+static void	ex_read __ARGS((exarg_T *eap));
+static void	ex_cd __ARGS((exarg_T *eap));
+static void	ex_pwd __ARGS((exarg_T *eap));
+static void	ex_equal __ARGS((exarg_T *eap));
+static void	ex_sleep __ARGS((exarg_T *eap));
+static void	do_exmap __ARGS((exarg_T *eap, int isabbrev));
+static void	ex_winsize __ARGS((exarg_T *eap));
+#ifdef FEAT_WINDOWS
+static void	ex_wincmd __ARGS((exarg_T *eap));
+#else
+# define ex_wincmd	    ex_ni
+#endif
+#if defined(FEAT_GUI) || defined(UNIX) || defined(VMS) || defined(MSWIN)
+static void	ex_winpos __ARGS((exarg_T *eap));
+#else
+# define ex_winpos	    ex_ni
+#endif
+static void	ex_operators __ARGS((exarg_T *eap));
+static void	ex_put __ARGS((exarg_T *eap));
+static void	ex_copymove __ARGS((exarg_T *eap));
+static void	ex_may_print __ARGS((exarg_T *eap));
+static void	ex_submagic __ARGS((exarg_T *eap));
+static void	ex_join __ARGS((exarg_T *eap));
+static void	ex_at __ARGS((exarg_T *eap));
+static void	ex_bang __ARGS((exarg_T *eap));
+static void	ex_undo __ARGS((exarg_T *eap));
+static void	ex_redo __ARGS((exarg_T *eap));
+static void	ex_later __ARGS((exarg_T *eap));
+static void	ex_redir __ARGS((exarg_T *eap));
+static void	ex_redraw __ARGS((exarg_T *eap));
+static void	ex_redrawstatus __ARGS((exarg_T *eap));
+static void	close_redir __ARGS((void));
+static void	ex_mkrc __ARGS((exarg_T *eap));
+static void	ex_mark __ARGS((exarg_T *eap));
+#ifdef FEAT_USR_CMDS
+static char_u	*uc_fun_cmd __ARGS((void));
+static char_u	*find_ucmd __ARGS((exarg_T *eap, char_u *p, int *full, expand_T *xp, int *compl));
+#endif
+#ifdef FEAT_EX_EXTRA
+static void	ex_normal __ARGS((exarg_T *eap));
+static void	ex_startinsert __ARGS((exarg_T *eap));
+static void	ex_stopinsert __ARGS((exarg_T *eap));
+#else
+# define ex_normal		ex_ni
+# define ex_align		ex_ni
+# define ex_retab		ex_ni
+# define ex_startinsert		ex_ni
+# define ex_stopinsert		ex_ni
+# define ex_helptags		ex_ni
+# define ex_sort		ex_ni
+#endif
+#ifdef FEAT_FIND_ID
+static void	ex_checkpath __ARGS((exarg_T *eap));
+static void	ex_findpat __ARGS((exarg_T *eap));
+#else
+# define ex_findpat		ex_ni
+# define ex_checkpath		ex_ni
+#endif
+#if defined(FEAT_FIND_ID) && defined(FEAT_WINDOWS) && defined(FEAT_QUICKFIX)
+static void	ex_psearch __ARGS((exarg_T *eap));
+#else
+# define ex_psearch		ex_ni
+#endif
+static void	ex_tag __ARGS((exarg_T *eap));
+static void	ex_tag_cmd __ARGS((exarg_T *eap, char_u *name));
+#ifndef FEAT_EVAL
+# define ex_scriptnames		ex_ni
+# define ex_finish		ex_ni
+# define ex_echo		ex_ni
+# define ex_echohl		ex_ni
+# define ex_execute		ex_ni
+# define ex_call		ex_ni
+# define ex_if			ex_ni
+# define ex_endif		ex_ni
+# define ex_else		ex_ni
+# define ex_while		ex_ni
+# define ex_for			ex_ni
+# define ex_continue		ex_ni
+# define ex_break		ex_ni
+# define ex_endwhile		ex_ni
+# define ex_endfor		ex_ni
+# define ex_throw		ex_ni
+# define ex_try			ex_ni
+# define ex_catch		ex_ni
+# define ex_finally		ex_ni
+# define ex_endtry		ex_ni
+# define ex_endfunction		ex_ni
+# define ex_let			ex_ni
+# define ex_unlet		ex_ni
+# define ex_lockvar		ex_ni
+# define ex_unlockvar		ex_ni
+# define ex_function		ex_ni
+# define ex_delfunction		ex_ni
+# define ex_return		ex_ni
+#endif
+static char_u	*arg_all __ARGS((void));
+#ifdef FEAT_SESSION
+static int	makeopens __ARGS((FILE *fd, char_u *dirnow));
+static int	put_view __ARGS((FILE *fd, win_T *wp, int add_edit, unsigned *flagp));
+static void	ex_loadview __ARGS((exarg_T *eap));
+static char_u	*get_view_file __ARGS((int c));
+static int	did_lcd;	/* whether ":lcd" was produced for a session */
+#else
+# define ex_loadview		ex_ni
+#endif
+#ifndef FEAT_EVAL
+# define ex_compiler		ex_ni
+#endif
+#ifdef FEAT_VIMINFO
+static void	ex_viminfo __ARGS((exarg_T *eap));
+#else
+# define ex_viminfo		ex_ni
+#endif
+static void	ex_behave __ARGS((exarg_T *eap));
+#ifdef FEAT_AUTOCMD
+static void	ex_filetype __ARGS((exarg_T *eap));
+static void	ex_setfiletype  __ARGS((exarg_T *eap));
+#else
+# define ex_filetype		ex_ni
+# define ex_setfiletype		ex_ni
+#endif
+#ifndef FEAT_DIFF
+# define ex_diffoff		ex_ni
+# define ex_diffpatch		ex_ni
+# define ex_diffgetput		ex_ni
+# define ex_diffsplit		ex_ni
+# define ex_diffthis		ex_ni
+# define ex_diffupdate		ex_ni
+#endif
+static void	ex_digraphs __ARGS((exarg_T *eap));
+static void	ex_set __ARGS((exarg_T *eap));
+#if !defined(FEAT_EVAL) || !defined(FEAT_AUTOCMD)
+# define ex_options		ex_ni
+#endif
+#ifdef FEAT_SEARCH_EXTRA
+static void	ex_nohlsearch __ARGS((exarg_T *eap));
+static void	ex_match __ARGS((exarg_T *eap));
+#else
+# define ex_nohlsearch		ex_ni
+# define ex_match		ex_ni
+#endif
+#ifdef FEAT_CRYPT
+static void	ex_X __ARGS((exarg_T *eap));
+#else
+# define ex_X			ex_ni
+#endif
+#ifdef FEAT_FOLDING
+static void	ex_fold __ARGS((exarg_T *eap));
+static void	ex_foldopen __ARGS((exarg_T *eap));
+static void	ex_folddo __ARGS((exarg_T *eap));
+#else
+# define ex_fold		ex_ni
+# define ex_foldopen		ex_ni
+# define ex_folddo		ex_ni
+#endif
+#if !((defined(HAVE_LOCALE_H) || defined(X_LOCALE)) \
+	&& (defined(FEAT_GETTEXT) || defined(FEAT_MBYTE)))
+# define ex_language		ex_ni
+#endif
+#ifndef FEAT_SIGNS
+# define ex_sign		ex_ni
+#endif
+#ifndef FEAT_SUN_WORKSHOP
+# define ex_wsverb		ex_ni
+#endif
+#ifndef FEAT_NETBEANS_INTG
+# define ex_nbkey		ex_ni
+#endif
+
+#ifndef FEAT_EVAL
+# define ex_debug		ex_ni
+# define ex_breakadd		ex_ni
+# define ex_debuggreedy		ex_ni
+# define ex_breakdel		ex_ni
+# define ex_breaklist		ex_ni
+#endif
+
+#ifndef FEAT_CMDHIST
+# define ex_history		ex_ni
+#endif
+#ifndef FEAT_JUMPLIST
+# define ex_jumps		ex_ni
+# define ex_changes		ex_ni
+#endif
+
+#ifndef FEAT_PROFILE
+# define ex_profile		ex_ni
+#endif
+
+/*
+ * Declare cmdnames[].
+ */
+#define DO_DECLARE_EXCMD
+#include "ex_cmds.h"
+
+/*
+ * Table used to quickly search for a command, based on its first character.
+ */
+static cmdidx_T cmdidxs[27] =
+{
+	CMD_append,
+	CMD_buffer,
+	CMD_change,
+	CMD_delete,
+	CMD_edit,
+	CMD_file,
+	CMD_global,
+	CMD_help,
+	CMD_insert,
+	CMD_join,
+	CMD_k,
+	CMD_list,
+	CMD_move,
+	CMD_next,
+	CMD_open,
+	CMD_print,
+	CMD_quit,
+	CMD_read,
+	CMD_substitute,
+	CMD_t,
+	CMD_undo,
+	CMD_vglobal,
+	CMD_write,
+	CMD_xit,
+	CMD_yank,
+	CMD_z,
+	CMD_bang
+};
+
+static char_u dollar_command[2] = {'$', 0};
+
+
+#ifdef FEAT_EVAL
+/* Struct for storing a line inside a while/for loop */
+typedef struct
+{
+    char_u	*line;		/* command line */
+    linenr_T	lnum;		/* sourcing_lnum of the line */
+} wcmd_T;
+
+/*
+ * Structure used to store info for line position in a while or for loop.
+ * This is required, because do_one_cmd() may invoke ex_function(), which
+ * reads more lines that may come from the while/for loop.
+ */
+struct loop_cookie
+{
+    garray_T	*lines_gap;		/* growarray with line info */
+    int		current_line;		/* last read line from growarray */
+    int		repeating;		/* TRUE when looping a second time */
+    /* When "repeating" is FALSE use "getline" and "cookie" to get lines */
+    char_u	*(*getline) __ARGS((int, void *, int));
+    void	*cookie;
+};
+
+static char_u	*get_loop_line __ARGS((int c, void *cookie, int indent));
+static int	store_loop_line __ARGS((garray_T *gap, char_u *line));
+static void	free_cmdlines __ARGS((garray_T *gap));
+
+/* Struct to save a few things while debugging.  Used in do_cmdline() only. */
+struct dbg_stuff
+{
+    int		trylevel;
+    int		force_abort;
+    except_T	*caught_stack;
+    char_u	*vv_exception;
+    char_u	*vv_throwpoint;
+    int		did_emsg;
+    int		got_int;
+    int		did_throw;
+    int		need_rethrow;
+    int		check_cstack;
+    except_T	*current_exception;
+};
+
+static void save_dbg_stuff __ARGS((struct dbg_stuff *dsp));
+static void restore_dbg_stuff __ARGS((struct dbg_stuff *dsp));
+
+    static void
+save_dbg_stuff(dsp)
+    struct dbg_stuff *dsp;
+{
+    dsp->trylevel	= trylevel;		trylevel = 0;
+    dsp->force_abort	= force_abort;		force_abort = FALSE;
+    dsp->caught_stack	= caught_stack;		caught_stack = NULL;
+    dsp->vv_exception	= v_exception(NULL);
+    dsp->vv_throwpoint	= v_throwpoint(NULL);
+
+    /* Necessary for debugging an inactive ":catch", ":finally", ":endtry" */
+    dsp->did_emsg	= did_emsg;		did_emsg     = FALSE;
+    dsp->got_int	= got_int;		got_int	     = FALSE;
+    dsp->did_throw	= did_throw;		did_throw    = FALSE;
+    dsp->need_rethrow	= need_rethrow;		need_rethrow = FALSE;
+    dsp->check_cstack	= check_cstack;		check_cstack = FALSE;
+    dsp->current_exception = current_exception;	current_exception = NULL;
+}
+
+    static void
+restore_dbg_stuff(dsp)
+    struct dbg_stuff *dsp;
+{
+    suppress_errthrow = FALSE;
+    trylevel = dsp->trylevel;
+    force_abort = dsp->force_abort;
+    caught_stack = dsp->caught_stack;
+    (void)v_exception(dsp->vv_exception);
+    (void)v_throwpoint(dsp->vv_throwpoint);
+    did_emsg = dsp->did_emsg;
+    got_int = dsp->got_int;
+    did_throw = dsp->did_throw;
+    need_rethrow = dsp->need_rethrow;
+    check_cstack = dsp->check_cstack;
+    current_exception = dsp->current_exception;
+}
+#endif
+
+
+/*
+ * do_exmode(): Repeatedly get commands for the "Ex" mode, until the ":vi"
+ * command is given.
+ */
+    void
+do_exmode(improved)
+    int		improved;	    /* TRUE for "improved Ex" mode */
+{
+    int		save_msg_scroll;
+    int		prev_msg_row;
+    linenr_T	prev_line;
+    int		changedtick;
+
+    if (improved)
+	exmode_active = EXMODE_VIM;
+    else
+	exmode_active = EXMODE_NORMAL;
+    State = NORMAL;
+
+    /* When using ":global /pat/ visual" and then "Q" we return to continue
+     * the :global command. */
+    if (global_busy)
+	return;
+
+    save_msg_scroll = msg_scroll;
+    ++RedrawingDisabled;	    /* don't redisplay the window */
+    ++no_wait_return;		    /* don't wait for return */
+#ifdef FEAT_GUI
+    /* Ignore scrollbar and mouse events in Ex mode */
+    ++hold_gui_events;
+#endif
+#ifdef FEAT_SNIFF
+    want_sniff_request = 0;    /* No K_SNIFF wanted */
+#endif
+
+    MSG(_("Entering Ex mode.  Type \"visual\" to go to Normal mode."));
+    while (exmode_active)
+    {
+#ifdef FEAT_EX_EXTRA
+	/* Check for a ":normal" command and no more characters left. */
+	if (ex_normal_busy > 0 && typebuf.tb_len == 0)
+	{
+	    exmode_active = FALSE;
+	    break;
+	}
+#endif
+	msg_scroll = TRUE;
+	need_wait_return = FALSE;
+	ex_pressedreturn = FALSE;
+	ex_no_reprint = FALSE;
+	changedtick = curbuf->b_changedtick;
+	prev_msg_row = msg_row;
+	prev_line = curwin->w_cursor.lnum;
+#ifdef FEAT_SNIFF
+	ProcessSniffRequests();
+#endif
+	if (improved)
+	{
+	    cmdline_row = msg_row;
+	    do_cmdline(NULL, getexline, NULL, 0);
+	}
+	else
+	    do_cmdline(NULL, getexmodeline, NULL, DOCMD_NOWAIT);
+	lines_left = Rows - 1;
+
+	if ((prev_line != curwin->w_cursor.lnum
+		    || changedtick != curbuf->b_changedtick) && !ex_no_reprint)
+	{
+	    if (curbuf->b_ml.ml_flags & ML_EMPTY)
+		EMSG(_(e_emptybuf));
+	    else
+	    {
+		if (ex_pressedreturn)
+		{
+		    /* go up one line, to overwrite the ":<CR>" line, so the
+		     * output doensn't contain empty lines. */
+		    msg_row = prev_msg_row;
+		    if (prev_msg_row == Rows - 1)
+			msg_row--;
+		}
+		msg_col = 0;
+		print_line_no_prefix(curwin->w_cursor.lnum, FALSE, FALSE);
+		msg_clr_eos();
+	    }
+	}
+	else if (ex_pressedreturn && !ex_no_reprint)	/* must be at EOF */
+	{
+	    if (curbuf->b_ml.ml_flags & ML_EMPTY)
+		EMSG(_(e_emptybuf));
+	    else
+		EMSG(_("E501: At end-of-file"));
+	}
+    }
+
+#ifdef FEAT_GUI
+    --hold_gui_events;
+#endif
+    --RedrawingDisabled;
+    --no_wait_return;
+    update_screen(CLEAR);
+    need_wait_return = FALSE;
+    msg_scroll = save_msg_scroll;
+}
+
+/*
+ * Execute a simple command line.  Used for translated commands like "*".
+ */
+    int
+do_cmdline_cmd(cmd)
+    char_u	*cmd;
+{
+    return do_cmdline(cmd, NULL, NULL,
+				   DOCMD_VERBOSE|DOCMD_NOWAIT|DOCMD_KEYTYPED);
+}
+
+/*
+ * do_cmdline(): execute one Ex command line
+ *
+ * 1. Execute "cmdline" when it is not NULL.
+ *    If "cmdline" is NULL, or more lines are needed, getline() is used.
+ * 2. Split up in parts separated with '|'.
+ *
+ * This function can be called recursively!
+ *
+ * flags:
+ * DOCMD_VERBOSE  - The command will be included in the error message.
+ * DOCMD_NOWAIT   - Don't call wait_return() and friends.
+ * DOCMD_REPEAT   - Repeat execution until getline() returns NULL.
+ * DOCMD_KEYTYPED - Don't reset KeyTyped.
+ * DOCMD_EXCRESET - Reset the exception environment (used for debugging).
+ * DOCMD_KEEPLINE - Store first typed line (for repeating with ".").
+ *
+ * return FAIL if cmdline could not be executed, OK otherwise
+ */
+    int
+do_cmdline(cmdline, getline, cookie, flags)
+    char_u	*cmdline;
+    char_u	*(*getline) __ARGS((int, void *, int));
+    void	*cookie;		/* argument for getline() */
+    int		flags;
+{
+    char_u	*next_cmdline;		/* next cmd to execute */
+    char_u	*cmdline_copy = NULL;	/* copy of cmd line */
+    int		used_getline = FALSE;	/* used "getline" to obtain command */
+    static int	recursive = 0;		/* recursive depth */
+    int		msg_didout_before_start = 0;
+    int		count = 0;		/* line number count */
+    int		did_inc = FALSE;	/* incremented RedrawingDisabled */
+    int		retval = OK;
+#ifdef FEAT_EVAL
+    struct condstack cstack;		/* conditional stack */
+    garray_T	lines_ga;		/* keep lines for ":while"/":for" */
+    int		current_line = 0;	/* active line in lines_ga */
+    char_u	*fname = NULL;		/* function or script name */
+    linenr_T	*breakpoint = NULL;	/* ptr to breakpoint field in cookie */
+    int		*dbg_tick = NULL;	/* ptr to dbg_tick field in cookie */
+    struct dbg_stuff debug_saved;	/* saved things for debug mode */
+    int		initial_trylevel;
+    struct msglist	**saved_msg_list = NULL;
+    struct msglist	*private_msg_list;
+
+    /* "getline" and "cookie" passed to do_one_cmd() */
+    char_u	*(*cmd_getline) __ARGS((int, void *, int));
+    void	*cmd_cookie;
+    struct loop_cookie cmd_loop_cookie;
+    void	*real_cookie;
+    int		getline_is_func;
+#else
+# define cmd_getline getline
+# define cmd_cookie cookie
+#endif
+    static int	call_depth = 0;		/* recursiveness */
+
+#ifdef FEAT_EVAL
+    /* For every pair of do_cmdline()/do_one_cmd() calls, use an extra memory
+     * location for storing error messages to be converted to an exception.
+     * This ensures that the do_errthrow() call in do_one_cmd() does not
+     * combine the messages stored by an earlier invocation of do_one_cmd()
+     * with the command name of the later one.  This would happen when
+     * BufWritePost autocommands are executed after a write error. */
+    saved_msg_list = msg_list;
+    msg_list = &private_msg_list;
+    private_msg_list = NULL;
+#endif
+
+    /* It's possible to create an endless loop with ":execute", catch that
+     * here.  The value of 200 allows nested function calls, ":source", etc. */
+    if (call_depth == 200)
+    {
+	EMSG(_("E169: Command too recursive"));
+#ifdef FEAT_EVAL
+	/* When converting to an exception, we do not include the command name
+	 * since this is not an error of the specific command. */
+	do_errthrow((struct condstack *)NULL, (char_u *)NULL);
+	msg_list = saved_msg_list;
+#endif
+	return FAIL;
+    }
+    ++call_depth;
+
+#ifdef FEAT_EVAL
+    cstack.cs_idx = -1;
+    cstack.cs_looplevel = 0;
+    cstack.cs_trylevel = 0;
+    cstack.cs_emsg_silent_list = NULL;
+    cstack.cs_lflags = 0;
+    ga_init2(&lines_ga, (int)sizeof(wcmd_T), 10);
+
+    real_cookie = getline_cookie(getline, cookie);
+
+    /* Inside a function use a higher nesting level. */
+    getline_is_func = getline_equal(getline, cookie, get_func_line);
+    if (getline_is_func && ex_nesting_level == func_level(real_cookie))
+	++ex_nesting_level;
+
+    /* Get the function or script name and the address where the next breakpoint
+     * line and the debug tick for a function or script are stored. */
+    if (getline_is_func)
+    {
+	fname = func_name(real_cookie);
+	breakpoint = func_breakpoint(real_cookie);
+	dbg_tick = func_dbg_tick(real_cookie);
+    }
+    else if (getline_equal(getline, cookie, getsourceline))
+    {
+	fname = sourcing_name;
+	breakpoint = source_breakpoint(real_cookie);
+	dbg_tick = source_dbg_tick(real_cookie);
+    }
+
+    /*
+     * Initialize "force_abort"  and "suppress_errthrow" at the top level.
+     */
+    if (!recursive)
+    {
+	force_abort = FALSE;
+	suppress_errthrow = FALSE;
+    }
+
+    /*
+     * If requested, store and reset the global values controlling the
+     * exception handling (used when debugging).  Otherwise clear it to avoid
+     * a bogus compiler warning when the optimizer uses inline functions...
+     */
+    if (flags & DOCMD_EXCRESET)
+	save_dbg_stuff(&debug_saved);
+    else
+	memset(&debug_saved, 0, 1);
+
+    initial_trylevel = trylevel;
+
+    /*
+     * "did_throw" will be set to TRUE when an exception is being thrown.
+     */
+    did_throw = FALSE;
+#endif
+    /*
+     * "did_emsg" will be set to TRUE when emsg() is used, in which case we
+     * cancel the whole command line, and any if/endif or loop.
+     * If force_abort is set, we cancel everything.
+     */
+    did_emsg = FALSE;
+
+    /*
+     * KeyTyped is only set when calling vgetc().  Reset it here when not
+     * calling vgetc() (sourced command lines).
+     */
+    if (!(flags & DOCMD_KEYTYPED) && !getline_equal(getline, cookie, getexline))
+	KeyTyped = FALSE;
+
+    /*
+     * Continue executing command lines:
+     * - when inside an ":if", ":while" or ":for"
+     * - for multiple commands on one line, separated with '|'
+     * - when repeating until there are no more lines (for ":source")
+     */
+    next_cmdline = cmdline;
+    do
+    {
+#ifdef FEAT_EVAL
+	getline_is_func = getline_equal(getline, cookie, get_func_line);
+#endif
+
+	/* stop skipping cmds for an error msg after all endif/while/for */
+	if (next_cmdline == NULL
+#ifdef FEAT_EVAL
+		&& !force_abort
+		&& cstack.cs_idx < 0
+		&& !(getline_is_func && func_has_abort(real_cookie))
+#endif
+							)
+	    did_emsg = FALSE;
+
+	/*
+	 * 1. If repeating a line in a loop, get a line from lines_ga.
+	 * 2. If no line given: Get an allocated line with getline().
+	 * 3. If a line is given: Make a copy, so we can mess with it.
+	 */
+
+#ifdef FEAT_EVAL
+	/* 1. If repeating, get a previous line from lines_ga. */
+	if (cstack.cs_looplevel > 0 && current_line < lines_ga.ga_len)
+	{
+	    /* Each '|' separated command is stored separately in lines_ga, to
+	     * be able to jump to it.  Don't use next_cmdline now. */
+	    vim_free(cmdline_copy);
+	    cmdline_copy = NULL;
+
+	    /* Check if a function has returned or, unless it has an unclosed
+	     * try conditional, aborted. */
+	    if (getline_is_func)
+	    {
+# ifdef FEAT_PROFILE
+		if (do_profiling == PROF_YES)
+		    func_line_end(real_cookie);
+# endif
+		if (func_has_ended(real_cookie))
+		{
+		    retval = FAIL;
+		    break;
+		}
+	    }
+#ifdef FEAT_PROFILE
+	    else if (do_profiling == PROF_YES
+			     && getline_equal(getline, cookie, getsourceline))
+		script_line_end();
+#endif
+
+	    /* Check if a sourced file hit a ":finish" command. */
+	    if (source_finished(getline, cookie))
+	    {
+		retval = FAIL;
+		break;
+	    }
+
+	    /* If breakpoints have been added/deleted need to check for it. */
+	    if (breakpoint != NULL && dbg_tick != NULL
+						   && *dbg_tick != debug_tick)
+	    {
+		*breakpoint = dbg_find_breakpoint(
+				getline_equal(getline, cookie, getsourceline),
+							fname, sourcing_lnum);
+		*dbg_tick = debug_tick;
+	    }
+
+	    next_cmdline = ((wcmd_T *)(lines_ga.ga_data))[current_line].line;
+	    sourcing_lnum = ((wcmd_T *)(lines_ga.ga_data))[current_line].lnum;
+
+	    /* Did we encounter a breakpoint? */
+	    if (breakpoint != NULL && *breakpoint != 0
+					      && *breakpoint <= sourcing_lnum)
+	    {
+		dbg_breakpoint(fname, sourcing_lnum);
+		/* Find next breakpoint. */
+		*breakpoint = dbg_find_breakpoint(
+				getline_equal(getline, cookie, getsourceline),
+							fname, sourcing_lnum);
+		*dbg_tick = debug_tick;
+	    }
+# ifdef FEAT_PROFILE
+	    if (do_profiling == PROF_YES)
+	    {
+		if (getline_is_func)
+		    func_line_start(real_cookie);
+		else if (getline_equal(getline, cookie, getsourceline))
+		    script_line_start();
+	    }
+# endif
+	}
+
+	if (cstack.cs_looplevel > 0)
+	{
+	    /* Inside a while/for loop we need to store the lines and use them
+	     * again.  Pass a different "getline" function to do_one_cmd()
+	     * below, so that it stores lines in or reads them from
+	     * "lines_ga".  Makes it possible to define a function inside a
+	     * while/for loop. */
+	    cmd_getline = get_loop_line;
+	    cmd_cookie = (void *)&cmd_loop_cookie;
+	    cmd_loop_cookie.lines_gap = &lines_ga;
+	    cmd_loop_cookie.current_line = current_line;
+	    cmd_loop_cookie.getline = getline;
+	    cmd_loop_cookie.cookie = cookie;
+	    cmd_loop_cookie.repeating = (current_line < lines_ga.ga_len);
+	}
+	else
+	{
+	    cmd_getline = getline;
+	    cmd_cookie = cookie;
+	}
+#endif
+
+	/* 2. If no line given, get an allocated line with getline(). */
+	if (next_cmdline == NULL)
+	{
+	    /*
+	     * Need to set msg_didout for the first line after an ":if",
+	     * otherwise the ":if" will be overwritten.
+	     */
+	    if (count == 1 && getline_equal(getline, cookie, getexline))
+		msg_didout = TRUE;
+	    if (getline == NULL || (next_cmdline = getline(':', cookie,
+#ifdef FEAT_EVAL
+		    cstack.cs_idx < 0 ? 0 : (cstack.cs_idx + 1) * 2
+#else
+		    0
+#endif
+			    )) == NULL)
+	    {
+		/* Don't call wait_return for aborted command line.  The NULL
+		 * returned for the end of a sourced file or executed function
+		 * doesn't do this. */
+		if (KeyTyped && !(flags & DOCMD_REPEAT))
+		    need_wait_return = FALSE;
+		retval = FAIL;
+		break;
+	    }
+	    used_getline = TRUE;
+
+	    /*
+	     * Keep the first typed line.  Clear it when more lines are typed.
+	     */
+	    if (flags & DOCMD_KEEPLINE)
+	    {
+		vim_free(repeat_cmdline);
+		if (count == 0)
+		    repeat_cmdline = vim_strsave(next_cmdline);
+		else
+		    repeat_cmdline = NULL;
+	    }
+	}
+
+	/* 3. Make a copy of the command so we can mess with it. */
+	else if (cmdline_copy == NULL)
+	{
+	    next_cmdline = vim_strsave(next_cmdline);
+	    if (next_cmdline == NULL)
+	    {
+		EMSG(_(e_outofmem));
+		retval = FAIL;
+		break;
+	    }
+	}
+	cmdline_copy = next_cmdline;
+
+#ifdef FEAT_EVAL
+	/*
+	 * Save the current line when inside a ":while" or ":for", and when
+	 * the command looks like a ":while" or ":for", because we may need it
+	 * later.  When there is a '|' and another command, it is stored
+	 * separately, because we need to be able to jump back to it from an
+	 * :endwhile/:endfor.
+	 */
+	if (current_line == lines_ga.ga_len
+		&& (cstack.cs_looplevel || has_loop_cmd(next_cmdline)))
+	{
+	    if (store_loop_line(&lines_ga, next_cmdline) == FAIL)
+	    {
+		retval = FAIL;
+		break;
+	    }
+	}
+	did_endif = FALSE;
+#endif
+
+	if (count++ == 0)
+	{
+	    /*
+	     * All output from the commands is put below each other, without
+	     * waiting for a return. Don't do this when executing commands
+	     * from a script or when being called recursive (e.g. for ":e
+	     * +command file").
+	     */
+	    if (!(flags & DOCMD_NOWAIT) && !recursive)
+	    {
+		msg_didout_before_start = msg_didout;
+		msg_didany = FALSE; /* no output yet */
+		msg_start();
+		msg_scroll = TRUE;  /* put messages below each other */
+		++no_wait_return;   /* dont wait for return until finished */
+		++RedrawingDisabled;
+		did_inc = TRUE;
+	    }
+	}
+
+	if (p_verbose >= 15 && sourcing_name != NULL)
+	{
+	    ++no_wait_return;
+	    verbose_enter_scroll();
+
+	    smsg((char_u *)_("line %ld: %s"),
+					   (long)sourcing_lnum, cmdline_copy);
+	    if (msg_silent == 0)
+		msg_puts((char_u *)"\n");   /* don't overwrite this */
+
+	    verbose_leave_scroll();
+	    --no_wait_return;
+	}
+
+	/*
+	 * 2. Execute one '|' separated command.
+	 *    do_one_cmd() will return NULL if there is no trailing '|'.
+	 *    "cmdline_copy" can change, e.g. for '%' and '#' expansion.
+	 */
+	++recursive;
+	next_cmdline = do_one_cmd(&cmdline_copy, flags & DOCMD_VERBOSE,
+#ifdef FEAT_EVAL
+				&cstack,
+#endif
+				cmd_getline, cmd_cookie);
+	--recursive;
+
+#ifdef FEAT_EVAL
+	if (cmd_cookie == (void *)&cmd_loop_cookie)
+	    /* Use "current_line" from "cmd_loop_cookie", it may have been
+	     * incremented when defining a function. */
+	    current_line = cmd_loop_cookie.current_line;
+#endif
+
+	if (next_cmdline == NULL)
+	{
+	    vim_free(cmdline_copy);
+	    cmdline_copy = NULL;
+#ifdef FEAT_CMDHIST
+	    /*
+	     * If the command was typed, remember it for the ':' register.
+	     * Do this AFTER executing the command to make :@: work.
+	     */
+	    if (getline_equal(getline, cookie, getexline)
+						  && new_last_cmdline != NULL)
+	    {
+		vim_free(last_cmdline);
+		last_cmdline = new_last_cmdline;
+		new_last_cmdline = NULL;
+	    }
+#endif
+	}
+	else
+	{
+	    /* need to copy the command after the '|' to cmdline_copy, for the
+	     * next do_one_cmd() */
+	    mch_memmove(cmdline_copy, next_cmdline, STRLEN(next_cmdline) + 1);
+	    next_cmdline = cmdline_copy;
+	}
+
+
+#ifdef FEAT_EVAL
+	/* reset did_emsg for a function that is not aborted by an error */
+	if (did_emsg && !force_abort
+		&& getline_equal(getline, cookie, get_func_line)
+					      && !func_has_abort(real_cookie))
+	    did_emsg = FALSE;
+
+	if (cstack.cs_looplevel > 0)
+	{
+	    ++current_line;
+
+	    /*
+	     * An ":endwhile", ":endfor" and ":continue" is handled here.
+	     * If we were executing commands, jump back to the ":while" or
+	     * ":for".
+	     * If we were not executing commands, decrement cs_looplevel.
+	     */
+	    if (cstack.cs_lflags & (CSL_HAD_CONT | CSL_HAD_ENDLOOP))
+	    {
+		cstack.cs_lflags &= ~(CSL_HAD_CONT | CSL_HAD_ENDLOOP);
+
+		/* Jump back to the matching ":while" or ":for".  Be careful
+		 * not to use a cs_line[] from an entry that isn't a ":while"
+		 * or ":for": It would make "current_line" invalid and can
+		 * cause a crash. */
+		if (!did_emsg && !got_int && !did_throw
+			&& cstack.cs_idx >= 0
+			&& (cstack.cs_flags[cstack.cs_idx]
+						      & (CSF_WHILE | CSF_FOR))
+			&& cstack.cs_line[cstack.cs_idx] >= 0
+			&& (cstack.cs_flags[cstack.cs_idx] & CSF_ACTIVE))
+		{
+		    current_line = cstack.cs_line[cstack.cs_idx];
+						/* remember we jumped there */
+		    cstack.cs_lflags |= CSL_HAD_LOOP;
+		    line_breakcheck();		/* check if CTRL-C typed */
+
+		    /* Check for the next breakpoint at or after the ":while"
+		     * or ":for". */
+		    if (breakpoint != NULL)
+		    {
+			*breakpoint = dbg_find_breakpoint(
+				getline_equal(getline, cookie, getsourceline),
+									fname,
+			   ((wcmd_T *)lines_ga.ga_data)[current_line].lnum-1);
+			*dbg_tick = debug_tick;
+		    }
+		}
+		else
+		{
+		    /* can only get here with ":endwhile" or ":endfor" */
+		    if (cstack.cs_idx >= 0)
+			rewind_conditionals(&cstack, cstack.cs_idx - 1,
+				   CSF_WHILE | CSF_FOR, &cstack.cs_looplevel);
+		}
+	    }
+
+	    /*
+	     * For a ":while" or ":for" we need to remember the line number.
+	     */
+	    else if (cstack.cs_lflags & CSL_HAD_LOOP)
+	    {
+		cstack.cs_lflags &= ~CSL_HAD_LOOP;
+		cstack.cs_line[cstack.cs_idx] = current_line - 1;
+	    }
+	}
+
+	/*
+	 * When not inside any ":while" loop, clear remembered lines.
+	 */
+	if (cstack.cs_looplevel == 0)
+	{
+	    if (lines_ga.ga_len > 0)
+	    {
+		sourcing_lnum =
+		       ((wcmd_T *)lines_ga.ga_data)[lines_ga.ga_len - 1].lnum;
+		free_cmdlines(&lines_ga);
+	    }
+	    current_line = 0;
+	}
+
+	/*
+	 * A ":finally" makes did_emsg, got_int, and did_throw pending for
+	 * being restored at the ":endtry".  Reset them here and set the
+	 * ACTIVE and FINALLY flags, so that the finally clause gets executed.
+	 * This includes the case where a missing ":endif", ":endwhile" or
+	 * ":endfor" was detected by the ":finally" itself.
+	 */
+	if (cstack.cs_lflags & CSL_HAD_FINA)
+	{
+	    cstack.cs_lflags &= ~CSL_HAD_FINA;
+	    report_make_pending(cstack.cs_pending[cstack.cs_idx]
+		    & (CSTP_ERROR | CSTP_INTERRUPT | CSTP_THROW),
+		    did_throw ? (void *)current_exception : NULL);
+	    did_emsg = got_int = did_throw = FALSE;
+	    cstack.cs_flags[cstack.cs_idx] |= CSF_ACTIVE | CSF_FINALLY;
+	}
+
+	/* Update global "trylevel" for recursive calls to do_cmdline() from
+	 * within this loop. */
+	trylevel = initial_trylevel + cstack.cs_trylevel;
+
+	/*
+	 * If the outermost try conditional (across function calls and sourced
+	 * files) is aborted because of an error, an interrupt, or an uncaught
+	 * exception, cancel everything.  If it is left normally, reset
+	 * force_abort to get the non-EH compatible abortion behavior for
+	 * the rest of the script.
+	 */
+	if (trylevel == 0 && !did_emsg && !got_int && !did_throw)
+	    force_abort = FALSE;
+
+	/* Convert an interrupt to an exception if appropriate. */
+	(void)do_intthrow(&cstack);
+#endif /* FEAT_EVAL */
+
+    }
+    /*
+     * Continue executing command lines when:
+     * - no CTRL-C typed, no aborting error, no exception thrown or try
+     *   conditionals need to be checked for executing finally clauses or
+     *   catching an interrupt exception
+     * - didn't get an error message or lines are not typed
+     * - there is a command after '|', inside a :if, :while, :for or :try, or
+     *   looping for ":source" command or function call.
+     */
+    while (!((got_int
+#ifdef FEAT_EVAL
+		    || (did_emsg && force_abort) || did_throw
+#endif
+	     )
+#ifdef FEAT_EVAL
+		&& cstack.cs_trylevel == 0
+#endif
+	    )
+	    && !(did_emsg && used_getline
+			  && (getline_equal(getline, cookie, getexmodeline)
+				|| getline_equal(getline, cookie, getexline)))
+	    && (next_cmdline != NULL
+#ifdef FEAT_EVAL
+			|| cstack.cs_idx >= 0
+#endif
+			|| (flags & DOCMD_REPEAT)));
+
+    vim_free(cmdline_copy);
+#ifdef FEAT_EVAL
+    free_cmdlines(&lines_ga);
+    ga_clear(&lines_ga);
+
+    if (cstack.cs_idx >= 0)
+    {
+	/*
+	 * If a sourced file or executed function ran to its end, report the
+	 * unclosed conditional.
+	 */
+	if (!got_int && !did_throw
+		&& ((getline_equal(getline, cookie, getsourceline)
+			&& !source_finished(getline, cookie))
+		    || (getline_equal(getline, cookie, get_func_line)
+					    && !func_has_ended(real_cookie))))
+	{
+	    if (cstack.cs_flags[cstack.cs_idx] & CSF_TRY)
+		EMSG(_(e_endtry));
+	    else if (cstack.cs_flags[cstack.cs_idx] & CSF_WHILE)
+		EMSG(_(e_endwhile));
+	    else if (cstack.cs_flags[cstack.cs_idx] & CSF_FOR)
+		EMSG(_(e_endfor));
+	    else
+		EMSG(_(e_endif));
+	}
+
+	/*
+	 * Reset "trylevel" in case of a ":finish" or ":return" or a missing
+	 * ":endtry" in a sourced file or executed function.  If the try
+	 * conditional is in its finally clause, ignore anything pending.
+	 * If it is in a catch clause, finish the caught exception.
+	 * Also cleanup any "cs_forinfo" structures.
+	 */
+	do
+	{
+	    int idx = cleanup_conditionals(&cstack, 0, TRUE);
+
+	    if (idx >= 0)
+		--idx;	    /* remove try block not in its finally clause */
+	    rewind_conditionals(&cstack, idx, CSF_WHILE | CSF_FOR,
+							&cstack.cs_looplevel);
+	}
+	while (cstack.cs_idx >= 0);
+	trylevel = initial_trylevel;
+    }
+
+    /* If a missing ":endtry", ":endwhile", ":endfor", or ":endif" or a memory
+     * lack was reported above and the error message is to be converted to an
+     * exception, do this now after rewinding the cstack. */
+    do_errthrow(&cstack, getline_equal(getline, cookie, get_func_line)
+				  ? (char_u *)"endfunction" : (char_u *)NULL);
+
+    if (trylevel == 0)
+    {
+	/*
+	 * When an exception is being thrown out of the outermost try
+	 * conditional, discard the uncaught exception, disable the conversion
+	 * of interrupts or errors to exceptions, and ensure that no more
+	 * commands are executed.
+	 */
+	if (did_throw)
+	{
+	    void	*p = NULL;
+	    char_u	*saved_sourcing_name;
+	    int		saved_sourcing_lnum;
+	    struct msglist	*messages = NULL, *next;
+
+	    /*
+	     * If the uncaught exception is a user exception, report it as an
+	     * error.  If it is an error exception, display the saved error
+	     * message now.  For an interrupt exception, do nothing; the
+	     * interrupt message is given elsewhere.
+	     */
+	    switch (current_exception->type)
+	    {
+		case ET_USER:
+		    vim_snprintf((char *)IObuff, IOSIZE,
+			    _("E605: Exception not caught: %s"),
+			    current_exception->value);
+		    p = vim_strsave(IObuff);
+		    break;
+		case ET_ERROR:
+		    messages = current_exception->messages;
+		    current_exception->messages = NULL;
+		    break;
+		case ET_INTERRUPT:
+		    break;
+		default:
+		    p = vim_strsave((char_u *)_(e_internal));
+	    }
+
+	    saved_sourcing_name = sourcing_name;
+	    saved_sourcing_lnum = sourcing_lnum;
+	    sourcing_name = current_exception->throw_name;
+	    sourcing_lnum = current_exception->throw_lnum;
+	    current_exception->throw_name = NULL;
+
+	    discard_current_exception();	/* uses IObuff if 'verbose' */
+	    suppress_errthrow = TRUE;
+	    force_abort = TRUE;
+
+	    if (messages != NULL)
+	    {
+		do
+		{
+		    next = messages->next;
+		    emsg(messages->msg);
+		    vim_free(messages->msg);
+		    vim_free(messages);
+		    messages = next;
+		}
+		while (messages != NULL);
+	    }
+	    else if (p != NULL)
+	    {
+		emsg(p);
+		vim_free(p);
+	    }
+	    vim_free(sourcing_name);
+	    sourcing_name = saved_sourcing_name;
+	    sourcing_lnum = saved_sourcing_lnum;
+	}
+
+	/*
+	 * On an interrupt or an aborting error not converted to an exception,
+	 * disable the conversion of errors to exceptions.  (Interrupts are not
+	 * converted any more, here.) This enables also the interrupt message
+	 * when force_abort is set and did_emsg unset in case of an interrupt
+	 * from a finally clause after an error.
+	 */
+	else if (got_int || (did_emsg && force_abort))
+	    suppress_errthrow = TRUE;
+    }
+
+    /*
+     * The current cstack will be freed when do_cmdline() returns.  An uncaught
+     * exception will have to be rethrown in the previous cstack.  If a function
+     * has just returned or a script file was just finished and the previous
+     * cstack belongs to the same function or, respectively, script file, it
+     * will have to be checked for finally clauses to be executed due to the
+     * ":return" or ":finish".  This is done in do_one_cmd().
+     */
+    if (did_throw)
+	need_rethrow = TRUE;
+    if ((getline_equal(getline, cookie, getsourceline)
+		&& ex_nesting_level > source_level(real_cookie))
+	    || (getline_equal(getline, cookie, get_func_line)
+		&& ex_nesting_level > func_level(real_cookie) + 1))
+    {
+	if (!did_throw)
+	    check_cstack = TRUE;
+    }
+    else
+    {
+	/* When leaving a function, reduce nesting level. */
+	if (getline_equal(getline, cookie, get_func_line))
+	    --ex_nesting_level;
+	/*
+	 * Go to debug mode when returning from a function in which we are
+	 * single-stepping.
+	 */
+	if ((getline_equal(getline, cookie, getsourceline)
+		    || getline_equal(getline, cookie, get_func_line))
+		&& ex_nesting_level + 1 <= debug_break_level)
+	    do_debug(getline_equal(getline, cookie, getsourceline)
+		    ? (char_u *)_("End of sourced file")
+		    : (char_u *)_("End of function"));
+    }
+
+    /*
+     * Restore the exception environment (done after returning from the
+     * debugger).
+     */
+    if (flags & DOCMD_EXCRESET)
+	restore_dbg_stuff(&debug_saved);
+
+    msg_list = saved_msg_list;
+#endif /* FEAT_EVAL */
+
+    /*
+     * If there was too much output to fit on the command line, ask the user to
+     * hit return before redrawing the screen. With the ":global" command we do
+     * this only once after the command is finished.
+     */
+    if (did_inc)
+    {
+	--RedrawingDisabled;
+	--no_wait_return;
+	msg_scroll = FALSE;
+
+	/*
+	 * When just finished an ":if"-":else" which was typed, no need to
+	 * wait for hit-return.  Also for an error situation.
+	 */
+	if (retval == FAIL
+#ifdef FEAT_EVAL
+		|| (did_endif && KeyTyped && !did_emsg)
+#endif
+					    )
+	{
+	    need_wait_return = FALSE;
+	    msg_didany = FALSE;		/* don't wait when restarting edit */
+	}
+	else if (need_wait_return)
+	{
+	    /*
+	     * The msg_start() above clears msg_didout. The wait_return we do
+	     * here should not overwrite the command that may be shown before
+	     * doing that.
+	     */
+	    msg_didout |= msg_didout_before_start;
+	    wait_return(FALSE);
+	}
+    }
+
+#ifndef FEAT_EVAL
+    /*
+     * Reset if_level, in case a sourced script file contains more ":if" than
+     * ":endif" (could be ":if x | foo | endif").
+     */
+    if_level = 0;
+#endif
+
+    --call_depth;
+    return retval;
+}
+
+#ifdef FEAT_EVAL
+/*
+ * Obtain a line when inside a ":while" or ":for" loop.
+ */
+    static char_u *
+get_loop_line(c, cookie, indent)
+    int		c;
+    void	*cookie;
+    int		indent;
+{
+    struct loop_cookie	*cp = (struct loop_cookie *)cookie;
+    wcmd_T		*wp;
+    char_u		*line;
+
+    if (cp->current_line + 1 >= cp->lines_gap->ga_len)
+    {
+	if (cp->repeating)
+	    return NULL;	/* trying to read past ":endwhile"/":endfor" */
+
+	/* First time inside the ":while"/":for": get line normally. */
+	if (cp->getline == NULL)
+	    line = getcmdline(c, 0L, indent);
+	else
+	    line = cp->getline(c, cp->cookie, indent);
+	if (line != NULL && store_loop_line(cp->lines_gap, line) == OK)
+	    ++cp->current_line;
+
+	return line;
+    }
+
+    KeyTyped = FALSE;
+    ++cp->current_line;
+    wp = (wcmd_T *)(cp->lines_gap->ga_data) + cp->current_line;
+    sourcing_lnum = wp->lnum;
+    return vim_strsave(wp->line);
+}
+
+/*
+ * Store a line in "gap" so that a ":while" loop can execute it again.
+ */
+    static int
+store_loop_line(gap, line)
+    garray_T	*gap;
+    char_u	*line;
+{
+    if (ga_grow(gap, 1) == FAIL)
+	return FAIL;
+    ((wcmd_T *)(gap->ga_data))[gap->ga_len].line = vim_strsave(line);
+    ((wcmd_T *)(gap->ga_data))[gap->ga_len].lnum = sourcing_lnum;
+    ++gap->ga_len;
+    return OK;
+}
+
+/*
+ * Free the lines stored for a ":while" or ":for" loop.
+ */
+    static void
+free_cmdlines(gap)
+    garray_T	*gap;
+{
+    while (gap->ga_len > 0)
+    {
+	vim_free(((wcmd_T *)(gap->ga_data))[gap->ga_len - 1].line);
+	--gap->ga_len;
+    }
+}
+#endif
+
+/*
+ * If "fgetline" is get_loop_line(), return TRUE if the getline it uses equals
+ * "func".  * Otherwise return TRUE when "fgetline" equals "func".
+ */
+/*ARGSUSED*/
+    int
+getline_equal(fgetline, cookie, func)
+    char_u	*(*fgetline) __ARGS((int, void *, int));
+    void	*cookie;		/* argument for fgetline() */
+    char_u	*(*func) __ARGS((int, void *, int));
+{
+#ifdef FEAT_EVAL
+    char_u		*(*gp) __ARGS((int, void *, int));
+    struct loop_cookie *cp;
+
+    /* When "fgetline" is "get_loop_line()" use the "cookie" to find the
+     * function that's originally used to obtain the lines.  This may be
+     * nested several levels. */
+    gp = fgetline;
+    cp = (struct loop_cookie *)cookie;
+    while (gp == get_loop_line)
+    {
+	gp = cp->getline;
+	cp = cp->cookie;
+    }
+    return gp == func;
+#else
+    return fgetline == func;
+#endif
+}
+
+#if defined(FEAT_EVAL) || defined(FEAT_MBYTE) || defined(PROTO)
+/*
+ * If "fgetline" is get_loop_line(), return the cookie used by the original
+ * getline function.  Otherwise return "cookie".
+ */
+/*ARGSUSED*/
+    void *
+getline_cookie(fgetline, cookie)
+    char_u	*(*fgetline) __ARGS((int, void *, int));
+    void	*cookie;		/* argument for fgetline() */
+{
+# ifdef FEAT_EVAL
+    char_u		*(*gp) __ARGS((int, void *, int));
+    struct loop_cookie *cp;
+
+    /* When "fgetline" is "get_loop_line()" use the "cookie" to find the
+     * cookie that's originally used to obtain the lines.  This may be nested
+     * several levels. */
+    gp = fgetline;
+    cp = (struct loop_cookie *)cookie;
+    while (gp == get_loop_line)
+    {
+	gp = cp->getline;
+	cp = cp->cookie;
+    }
+    return cp;
+# else
+    return cookie;
+# endif
+}
+#endif
+
+/*
+ * Execute one Ex command.
+ *
+ * If 'sourcing' is TRUE, the command will be included in the error message.
+ *
+ * 1. skip comment lines and leading space
+ * 2. handle command modifiers
+ * 3. parse range
+ * 4. parse command
+ * 5. parse arguments
+ * 6. switch on command name
+ *
+ * Note: "fgetline" can be NULL.
+ *
+ * This function may be called recursively!
+ */
+#if (_MSC_VER == 1200)
+/*
+ * Avoid optimisation bug in VC++ version 6.0
+ */
+ #pragma optimize( "g", off )
+#endif
+    static char_u *
+do_one_cmd(cmdlinep, sourcing,
+#ifdef FEAT_EVAL
+			    cstack,
+#endif
+				    fgetline, cookie)
+    char_u		**cmdlinep;
+    int			sourcing;
+#ifdef FEAT_EVAL
+    struct condstack	*cstack;
+#endif
+    char_u		*(*fgetline) __ARGS((int, void *, int));
+    void		*cookie;		/* argument for fgetline() */
+{
+    char_u		*p;
+    linenr_T		lnum;
+    long		n;
+    char_u		*errormsg = NULL;	/* error message */
+    exarg_T		ea;			/* Ex command arguments */
+    long		verbose_save = -1;
+    int			save_msg_scroll = 0;
+    int			did_silent = 0;
+    int			did_esilent = 0;
+#ifdef HAVE_SANDBOX
+    int			did_sandbox = FALSE;
+#endif
+    cmdmod_T		save_cmdmod;
+    int			ni;			/* set when Not Implemented */
+
+    vim_memset(&ea, 0, sizeof(ea));
+    ea.line1 = 1;
+    ea.line2 = 1;
+#ifdef FEAT_EVAL
+    ++ex_nesting_level;
+#endif
+
+	/* when not editing the last file :q has to be typed twice */
+    if (quitmore
+#ifdef FEAT_EVAL
+	    /* avoid that a function call in 'statusline' does this */
+	    && !getline_equal(fgetline, cookie, get_func_line)
+#endif
+	    )
+	--quitmore;
+
+    /*
+     * Reset browse, confirm, etc..  They are restored when returning, for
+     * recursive calls.
+     */
+    save_cmdmod = cmdmod;
+    vim_memset(&cmdmod, 0, sizeof(cmdmod));
+
+    /* "#!anything" is handled like a comment. */
+    if ((*cmdlinep)[0] == '#' && (*cmdlinep)[1] == '!')
+	goto doend;
+
+    /*
+     * Repeat until no more command modifiers are found.
+     */
+    ea.cmd = *cmdlinep;
+    for (;;)
+    {
+/*
+ * 1. skip comment lines and leading white space and colons
+ */
+	while (*ea.cmd == ' ' || *ea.cmd == '\t' || *ea.cmd == ':')
+	    ++ea.cmd;
+
+	/* in ex mode, an empty line works like :+ */
+	if (*ea.cmd == NUL && exmode_active
+			&& (getline_equal(fgetline, cookie, getexmodeline)
+			    || getline_equal(fgetline, cookie, getexline))
+			&& curwin->w_cursor.lnum < curbuf->b_ml.ml_line_count)
+	{
+	    ea.cmd = (char_u *)"+";
+	    ex_pressedreturn = TRUE;
+	}
+
+	/* ignore comment and empty lines */
+	if (*ea.cmd == '"' || *ea.cmd == NUL)
+	{
+	    ex_pressedreturn = TRUE;
+	    goto doend;
+	}
+
+/*
+ * 2. handle command modifiers.
+ */
+	p = ea.cmd;
+	if (VIM_ISDIGIT(*ea.cmd))
+	    p = skipwhite(skipdigits(ea.cmd));
+	switch (*p)
+	{
+	    /* When adding an entry, also modify cmd_exists(). */
+	    case 'a':	if (!checkforcmd(&ea.cmd, "aboveleft", 3))
+			    break;
+#ifdef FEAT_WINDOWS
+			cmdmod.split |= WSP_ABOVE;
+#endif
+			continue;
+
+	    case 'b':	if (checkforcmd(&ea.cmd, "belowright", 3))
+			{
+#ifdef FEAT_WINDOWS
+			    cmdmod.split |= WSP_BELOW;
+#endif
+			    continue;
+			}
+			if (checkforcmd(&ea.cmd, "browse", 3))
+			{
+#ifdef FEAT_BROWSE
+			    cmdmod.browse = TRUE;
+#endif
+			    continue;
+			}
+			if (!checkforcmd(&ea.cmd, "botright", 2))
+			    break;
+#ifdef FEAT_WINDOWS
+			cmdmod.split |= WSP_BOT;
+#endif
+			continue;
+
+	    case 'c':	if (!checkforcmd(&ea.cmd, "confirm", 4))
+			    break;
+#if defined(FEAT_GUI_DIALOG) || defined(FEAT_CON_DIALOG)
+			cmdmod.confirm = TRUE;
+#endif
+			continue;
+
+	    case 'k':	if (checkforcmd(&ea.cmd, "keepmarks", 3))
+			{
+			    cmdmod.keepmarks = TRUE;
+			    continue;
+			}
+			if (checkforcmd(&ea.cmd, "keepalt", 5))
+			{
+			    cmdmod.keepalt = TRUE;
+			    continue;
+			}
+			if (!checkforcmd(&ea.cmd, "keepjumps", 5))
+			    break;
+			cmdmod.keepjumps = TRUE;
+			continue;
+
+			/* ":hide" and ":hide | cmd" are not modifiers */
+	    case 'h':	if (p != ea.cmd || !checkforcmd(&p, "hide", 3)
+					       || *p == NUL || ends_excmd(*p))
+			    break;
+			ea.cmd = p;
+			cmdmod.hide = TRUE;
+			continue;
+
+	    case 'l':	if (checkforcmd(&ea.cmd, "lockmarks", 3))
+			{
+			    cmdmod.lockmarks = TRUE;
+			    continue;
+			}
+
+			if (!checkforcmd(&ea.cmd, "leftabove", 5))
+			    break;
+#ifdef FEAT_WINDOWS
+			cmdmod.split |= WSP_ABOVE;
+#endif
+			continue;
+
+	    case 'n':	if (!checkforcmd(&ea.cmd, "noautocmd", 3))
+			    break;
+#ifdef FEAT_AUTOCMD
+			if (cmdmod.save_ei == NULL)
+			{
+			    /* Set 'eventignore' to "all". Restore the
+			     * existing option value later. */
+			    cmdmod.save_ei = vim_strsave(p_ei);
+			    set_string_option_direct((char_u *)"ei", -1,
+					 (char_u *)"all", OPT_FREE, SID_NONE);
+			}
+#endif
+			continue;
+
+	    case 'r':	if (!checkforcmd(&ea.cmd, "rightbelow", 6))
+			    break;
+#ifdef FEAT_WINDOWS
+			cmdmod.split |= WSP_BELOW;
+#endif
+			continue;
+
+	    case 's':	if (checkforcmd(&ea.cmd, "sandbox", 3))
+			{
+#ifdef HAVE_SANDBOX
+			    if (!did_sandbox)
+				++sandbox;
+			    did_sandbox = TRUE;
+#endif
+			    continue;
+			}
+			if (!checkforcmd(&ea.cmd, "silent", 3))
+			    break;
+			++did_silent;
+			++msg_silent;
+			save_msg_scroll = msg_scroll;
+			if (*ea.cmd == '!' && !vim_iswhite(ea.cmd[-1]))
+			{
+			    /* ":silent!", but not "silent !cmd" */
+			    ea.cmd = skipwhite(ea.cmd + 1);
+			    ++emsg_silent;
+			    ++did_esilent;
+			}
+			continue;
+
+	    case 't':	if (checkforcmd(&p, "tab", 3))
+			{
+#ifdef FEAT_WINDOWS
+			    if (vim_isdigit(*ea.cmd))
+				cmdmod.tab = atoi((char *)ea.cmd) + 1;
+			    else
+				cmdmod.tab = tabpage_index(curtab) + 1;
+			    ea.cmd = p;
+#endif
+			    continue;
+			}
+			if (!checkforcmd(&ea.cmd, "topleft", 2))
+			    break;
+#ifdef FEAT_WINDOWS
+			cmdmod.split |= WSP_TOP;
+#endif
+			continue;
+
+	    case 'v':	if (checkforcmd(&ea.cmd, "vertical", 4))
+			{
+#ifdef FEAT_VERTSPLIT
+			    cmdmod.split |= WSP_VERT;
+#endif
+			    continue;
+			}
+			if (!checkforcmd(&p, "verbose", 4))
+			    break;
+			if (verbose_save < 0)
+			    verbose_save = p_verbose;
+			if (vim_isdigit(*ea.cmd))
+			    p_verbose = atoi((char *)ea.cmd);
+			else
+			    p_verbose = 1;
+			ea.cmd = p;
+			continue;
+	}
+	break;
+    }
+
+#ifdef FEAT_EVAL
+    ea.skip = did_emsg || got_int || did_throw || (cstack->cs_idx >= 0
+			 && !(cstack->cs_flags[cstack->cs_idx] & CSF_ACTIVE));
+#else
+    ea.skip = (if_level > 0);
+#endif
+
+#ifdef FEAT_EVAL
+# ifdef FEAT_PROFILE
+    /* Count this line for profiling if ea.skip is FALSE. */
+    if (do_profiling == PROF_YES && !ea.skip)
+    {
+	if (getline_equal(fgetline, cookie, get_func_line))
+	    func_line_exec(getline_cookie(fgetline, cookie));
+	else if (getline_equal(fgetline, cookie, getsourceline))
+	    script_line_exec();
+    }
+#endif
+
+    /* May go to debug mode.  If this happens and the ">quit" debug command is
+     * used, throw an interrupt exception and skip the next command. */
+    dbg_check_breakpoint(&ea);
+    if (!ea.skip && got_int)
+    {
+	ea.skip = TRUE;
+	(void)do_intthrow(cstack);
+    }
+#endif
+
+/*
+ * 3. parse a range specifier of the form: addr [,addr] [;addr] ..
+ *
+ * where 'addr' is:
+ *
+ * %	      (entire file)
+ * $  [+-NUM]
+ * 'x [+-NUM] (where x denotes a currently defined mark)
+ * .  [+-NUM]
+ * [+-NUM]..
+ * NUM
+ *
+ * The ea.cmd pointer is updated to point to the first character following the
+ * range spec. If an initial address is found, but no second, the upper bound
+ * is equal to the lower.
+ */
+
+    /* repeat for all ',' or ';' separated addresses */
+    for (;;)
+    {
+	ea.line1 = ea.line2;
+	ea.line2 = curwin->w_cursor.lnum;   /* default is current line number */
+	ea.cmd = skipwhite(ea.cmd);
+	lnum = get_address(&ea.cmd, ea.skip, ea.addr_count == 0);
+	if (ea.cmd == NULL)		    /* error detected */
+	    goto doend;
+	if (lnum == MAXLNUM)
+	{
+	    if (*ea.cmd == '%')		    /* '%' - all lines */
+	    {
+		++ea.cmd;
+		ea.line1 = 1;
+		ea.line2 = curbuf->b_ml.ml_line_count;
+		++ea.addr_count;
+	    }
+					    /* '*' - visual area */
+	    else if (*ea.cmd == '*' && vim_strchr(p_cpo, CPO_STAR) == NULL)
+	    {
+		pos_T	    *fp;
+
+		++ea.cmd;
+		if (!ea.skip)
+		{
+		    fp = getmark('<', FALSE);
+		    if (check_mark(fp) == FAIL)
+			goto doend;
+		    ea.line1 = fp->lnum;
+		    fp = getmark('>', FALSE);
+		    if (check_mark(fp) == FAIL)
+			goto doend;
+		    ea.line2 = fp->lnum;
+		    ++ea.addr_count;
+		}
+	    }
+	}
+	else
+	    ea.line2 = lnum;
+	ea.addr_count++;
+
+	if (*ea.cmd == ';')
+	{
+	    if (!ea.skip)
+		curwin->w_cursor.lnum = ea.line2;
+	}
+	else if (*ea.cmd != ',')
+	    break;
+	++ea.cmd;
+    }
+
+    /* One address given: set start and end lines */
+    if (ea.addr_count == 1)
+    {
+	ea.line1 = ea.line2;
+	    /* ... but only implicit: really no address given */
+	if (lnum == MAXLNUM)
+	    ea.addr_count = 0;
+    }
+
+    /* Don't leave the cursor on an illegal line (caused by ';') */
+    check_cursor_lnum();
+
+/*
+ * 4. parse command
+ */
+
+    /*
+     * Skip ':' and any white space
+     */
+    ea.cmd = skipwhite(ea.cmd);
+    while (*ea.cmd == ':')
+	ea.cmd = skipwhite(ea.cmd + 1);
+
+    /*
+     * If we got a line, but no command, then go to the line.
+     * If we find a '|' or '\n' we set ea.nextcmd.
+     */
+    if (*ea.cmd == NUL || *ea.cmd == '"' ||
+			       (ea.nextcmd = check_nextcmd(ea.cmd)) != NULL)
+    {
+	/*
+	 * strange vi behaviour:
+	 * ":3"		jumps to line 3
+	 * ":3|..."	prints line 3
+	 * ":|"		prints current line
+	 */
+	if (ea.skip)	    /* skip this if inside :if */
+	    goto doend;
+	if (*ea.cmd == '|' || (exmode_active && ea.line1 != ea.line2))
+	{
+	    ea.cmdidx = CMD_print;
+	    ea.argt = RANGE+COUNT+TRLBAR;
+	    if ((errormsg = invalid_range(&ea)) == NULL)
+	    {
+		correct_range(&ea);
+		ex_print(&ea);
+	    }
+	}
+	else if (ea.addr_count != 0)
+	{
+	    if (ea.line2 > curbuf->b_ml.ml_line_count)
+	    {
+		/* With '-' in 'cpoptions' a line number past the file is an
+		 * error, otherwise put it at the end of the file. */
+		if (vim_strchr(p_cpo, CPO_MINUS) != NULL)
+		    ea.line2 = -1;
+		else
+		    ea.line2 = curbuf->b_ml.ml_line_count;
+	    }
+
+	    if (ea.line2 < 0)
+		errormsg = (char_u *)_(e_invrange);
+	    else
+	    {
+		if (ea.line2 == 0)
+		    curwin->w_cursor.lnum = 1;
+		else
+		    curwin->w_cursor.lnum = ea.line2;
+		beginline(BL_SOL | BL_FIX);
+	    }
+	}
+	goto doend;
+    }
+
+    /* Find the command and let "p" point to after it. */
+    p = find_command(&ea, NULL);
+
+#ifdef FEAT_USR_CMDS
+    if (p == NULL)
+    {
+	if (!ea.skip)
+	    errormsg = (char_u *)_("E464: Ambiguous use of user-defined command");
+	goto doend;
+    }
+    /* Check for wrong commands. */
+    if (*p == '!' && ea.cmd[1] == 0151 && ea.cmd[0] == 78)
+    {
+	errormsg = uc_fun_cmd();
+	goto doend;
+    }
+#endif
+    if (ea.cmdidx == CMD_SIZE)
+    {
+	if (!ea.skip)
+	{
+	    STRCPY(IObuff, _("E492: Not an editor command"));
+	    if (!sourcing)
+	    {
+		STRCAT(IObuff, ": ");
+		STRNCAT(IObuff, *cmdlinep, 40);
+	    }
+	    errormsg = IObuff;
+	}
+	goto doend;
+    }
+
+    ni = (
+#ifdef FEAT_USR_CMDS
+	    !USER_CMDIDX(ea.cmdidx) &&
+#endif
+	    cmdnames[ea.cmdidx].cmd_func == ex_ni);
+
+#ifndef FEAT_EVAL
+    /*
+     * When the expression evaluation is disabled, recognize the ":if" and
+     * ":endif" commands and ignore everything in between it.
+     */
+    if (ea.cmdidx == CMD_if)
+	++if_level;
+    if (if_level)
+    {
+	if (ea.cmdidx == CMD_endif)
+	    --if_level;
+	goto doend;
+    }
+
+#endif
+
+    if (*p == '!' && ea.cmdidx != CMD_substitute)    /* forced commands */
+    {
+	++p;
+	ea.forceit = TRUE;
+    }
+    else
+	ea.forceit = FALSE;
+
+/*
+ * 5. parse arguments
+ */
+#ifdef FEAT_USR_CMDS
+    if (!USER_CMDIDX(ea.cmdidx))
+#endif
+	ea.argt = (long)cmdnames[(int)ea.cmdidx].cmd_argt;
+
+    if (!ea.skip)
+    {
+#ifdef HAVE_SANDBOX
+	if (sandbox != 0 && !(ea.argt & SBOXOK))
+	{
+	    /* Command not allowed in sandbox. */
+	    errormsg = (char_u *)_(e_sandbox);
+	    goto doend;
+	}
+#endif
+	if (!curbuf->b_p_ma && (ea.argt & MODIFY))
+	{
+	    /* Command not allowed in non-'modifiable' buffer */
+	    errormsg = (char_u *)_(e_modifiable);
+	    goto doend;
+	}
+
+	if (text_locked() && !(ea.argt & CMDWIN)
+# ifdef FEAT_USR_CMDS
+		&& !USER_CMDIDX(ea.cmdidx)
+# endif
+	   )
+	{
+	    /* Command not allowed when editing the command line. */
+#ifdef FEAT_CMDWIN
+	    if (cmdwin_type != 0)
+		errormsg = (char_u *)_(e_cmdwin);
+	    else
+#endif
+		errormsg = (char_u *)_(e_secure);
+	    goto doend;
+	}
+#ifdef FEAT_AUTOCMD
+	/* Disallow editing another buffer when "curbuf_lock" is set.
+	 * Do allow ":edit" (check for argument later).
+	 * Do allow ":checktime" (it's postponed). */
+	if (!(ea.argt & CMDWIN)
+		&& ea.cmdidx != CMD_edit
+		&& ea.cmdidx != CMD_checktime
+# ifdef FEAT_USR_CMDS
+		&& !USER_CMDIDX(ea.cmdidx)
+# endif
+		&& curbuf_locked())
+	    goto doend;
+#endif
+
+	if (!ni && !(ea.argt & RANGE) && ea.addr_count > 0)
+	{
+	    /* no range allowed */
+	    errormsg = (char_u *)_(e_norange);
+	    goto doend;
+	}
+    }
+
+    if (!ni && !(ea.argt & BANG) && ea.forceit)	/* no <!> allowed */
+    {
+	errormsg = (char_u *)_(e_nobang);
+	goto doend;
+    }
+
+    /*
+     * Don't complain about the range if it is not used
+     * (could happen if line_count is accidentally set to 0).
+     */
+    if (!ea.skip && !ni)
+    {
+	/*
+	 * If the range is backwards, ask for confirmation and, if given, swap
+	 * ea.line1 & ea.line2 so it's forwards again.
+	 * When global command is busy, don't ask, will fail below.
+	 */
+	if (!global_busy && ea.line1 > ea.line2)
+	{
+	    if (msg_silent == 0)
+	    {
+		if (sourcing || exmode_active)
+		{
+		    errormsg = (char_u *)_("E493: Backwards range given");
+		    goto doend;
+		}
+		if (ask_yesno((char_u *)
+			_("Backwards range given, OK to swap"), FALSE) != 'y')
+		    goto doend;
+	    }
+	    lnum = ea.line1;
+	    ea.line1 = ea.line2;
+	    ea.line2 = lnum;
+	}
+	if ((errormsg = invalid_range(&ea)) != NULL)
+	    goto doend;
+    }
+
+    if ((ea.argt & NOTADR) && ea.addr_count == 0) /* default is 1, not cursor */
+	ea.line2 = 1;
+
+    correct_range(&ea);
+
+#ifdef FEAT_FOLDING
+    if (((ea.argt & WHOLEFOLD) || ea.addr_count >= 2) && !global_busy)
+    {
+	/* Put the first line at the start of a closed fold, put the last line
+	 * at the end of a closed fold. */
+	(void)hasFolding(ea.line1, &ea.line1, NULL);
+	(void)hasFolding(ea.line2, NULL, &ea.line2);
+    }
+#endif
+
+#ifdef FEAT_QUICKFIX
+    /*
+     * For the ":make" and ":grep" commands we insert the 'makeprg'/'grepprg'
+     * option here, so things like % get expanded.
+     */
+    p = replace_makeprg(&ea, p, cmdlinep);
+    if (p == NULL)
+	goto doend;
+#endif
+
+    /*
+     * Skip to start of argument.
+     * Don't do this for the ":!" command, because ":!! -l" needs the space.
+     */
+    if (ea.cmdidx == CMD_bang)
+	ea.arg = p;
+    else
+	ea.arg = skipwhite(p);
+
+    /*
+     * Check for "++opt=val" argument.
+     * Must be first, allow ":w ++enc=utf8 !cmd"
+     */
+    if (ea.argt & ARGOPT)
+	while (ea.arg[0] == '+' && ea.arg[1] == '+')
+	    if (getargopt(&ea) == FAIL && !ni)
+	    {
+		errormsg = (char_u *)_(e_invarg);
+		goto doend;
+	    }
+
+    if (ea.cmdidx == CMD_write || ea.cmdidx == CMD_update)
+    {
+	if (*ea.arg == '>')			/* append */
+	{
+	    if (*++ea.arg != '>')		/* typed wrong */
+	    {
+		errormsg = (char_u *)_("E494: Use w or w>>");
+		goto doend;
+	    }
+	    ea.arg = skipwhite(ea.arg + 1);
+	    ea.append = TRUE;
+	}
+	else if (*ea.arg == '!' && ea.cmdidx == CMD_write)  /* :w !filter */
+	{
+	    ++ea.arg;
+	    ea.usefilter = TRUE;
+	}
+    }
+
+    if (ea.cmdidx == CMD_read)
+    {
+	if (ea.forceit)
+	{
+	    ea.usefilter = TRUE;		/* :r! filter if ea.forceit */
+	    ea.forceit = FALSE;
+	}
+	else if (*ea.arg == '!')		/* :r !filter */
+	{
+	    ++ea.arg;
+	    ea.usefilter = TRUE;
+	}
+    }
+
+    if (ea.cmdidx == CMD_lshift || ea.cmdidx == CMD_rshift)
+    {
+	ea.amount = 1;
+	while (*ea.arg == *ea.cmd)		/* count number of '>' or '<' */
+	{
+	    ++ea.arg;
+	    ++ea.amount;
+	}
+	ea.arg = skipwhite(ea.arg);
+    }
+
+    /*
+     * Check for "+command" argument, before checking for next command.
+     * Don't do this for ":read !cmd" and ":write !cmd".
+     */
+    if ((ea.argt & EDITCMD) && !ea.usefilter)
+	ea.do_ecmd_cmd = getargcmd(&ea.arg);
+
+    /*
+     * Check for '|' to separate commands and '"' to start comments.
+     * Don't do this for ":read !cmd" and ":write !cmd".
+     */
+    if ((ea.argt & TRLBAR) && !ea.usefilter)
+	separate_nextcmd(&ea);
+
+    /*
+     * Check for <newline> to end a shell command.
+     * Also do this for ":read !cmd", ":write !cmd" and ":global".
+     * Any others?
+     */
+    else if (ea.cmdidx == CMD_bang
+	    || ea.cmdidx == CMD_global
+	    || ea.cmdidx == CMD_vglobal
+	    || ea.usefilter)
+    {
+	for (p = ea.arg; *p; ++p)
+	{
+	    /* Remove one backslash before a newline, so that it's possible to
+	     * pass a newline to the shell and also a newline that is preceded
+	     * with a backslash.  This makes it impossible to end a shell
+	     * command in a backslash, but that doesn't appear useful.
+	     * Halving the number of backslashes is incompatible with previous
+	     * versions. */
+	    if (*p == '\\' && p[1] == '\n')
+		mch_memmove(p, p + 1, STRLEN(p));
+	    else if (*p == '\n')
+	    {
+		ea.nextcmd = p + 1;
+		*p = NUL;
+		break;
+	    }
+	}
+    }
+
+    if ((ea.argt & DFLALL) && ea.addr_count == 0)
+    {
+	ea.line1 = 1;
+	ea.line2 = curbuf->b_ml.ml_line_count;
+    }
+
+    /* accept numbered register only when no count allowed (:put) */
+    if (       (ea.argt & REGSTR)
+	    && *ea.arg != NUL
+#ifdef FEAT_USR_CMDS
+	    && valid_yank_reg(*ea.arg, (ea.cmdidx != CMD_put
+						   && USER_CMDIDX(ea.cmdidx)))
+	    /* Do not allow register = for user commands */
+	    && (!USER_CMDIDX(ea.cmdidx) || *ea.arg != '=')
+#else
+	    && valid_yank_reg(*ea.arg, ea.cmdidx != CMD_put)
+#endif
+	    && !((ea.argt & COUNT) && VIM_ISDIGIT(*ea.arg)))
+    {
+	ea.regname = *ea.arg++;
+#ifdef FEAT_EVAL
+	/* for '=' register: accept the rest of the line as an expression */
+	if (ea.arg[-1] == '=' && ea.arg[0] != NUL)
+	{
+	    set_expr_line(vim_strsave(ea.arg));
+	    ea.arg += STRLEN(ea.arg);
+	}
+#endif
+	ea.arg = skipwhite(ea.arg);
+    }
+
+    /*
+     * Check for a count.  When accepting a BUFNAME, don't use "123foo" as a
+     * count, it's a buffer name.
+     */
+    if ((ea.argt & COUNT) && VIM_ISDIGIT(*ea.arg)
+	    && (!(ea.argt & BUFNAME) || *(p = skipdigits(ea.arg)) == NUL
+							  || vim_iswhite(*p)))
+    {
+	n = getdigits(&ea.arg);
+	ea.arg = skipwhite(ea.arg);
+	if (n <= 0 && !ni && (ea.argt & ZEROR) == 0)
+	{
+	    errormsg = (char_u *)_(e_zerocount);
+	    goto doend;
+	}
+	if (ea.argt & NOTADR)	/* e.g. :buffer 2, :sleep 3 */
+	{
+	    ea.line2 = n;
+	    if (ea.addr_count == 0)
+		ea.addr_count = 1;
+	}
+	else
+	{
+	    ea.line1 = ea.line2;
+	    ea.line2 += n - 1;
+	    ++ea.addr_count;
+	    /*
+	     * Be vi compatible: no error message for out of range.
+	     */
+	    if (ea.line2 > curbuf->b_ml.ml_line_count)
+		ea.line2 = curbuf->b_ml.ml_line_count;
+	}
+    }
+
+    /*
+     * Check for flags: 'l', 'p' and '#'.
+     */
+    if (ea.argt & EXFLAGS)
+	get_flags(&ea);
+						/* no arguments allowed */
+    if (!ni && !(ea.argt & EXTRA) && *ea.arg != NUL
+	    && *ea.arg != '"' && (*ea.arg != '|' || (ea.argt & TRLBAR) == 0))
+    {
+	errormsg = (char_u *)_(e_trailing);
+	goto doend;
+    }
+
+    if (!ni && (ea.argt & NEEDARG) && *ea.arg == NUL)
+    {
+	errormsg = (char_u *)_(e_argreq);
+	goto doend;
+    }
+
+#ifdef FEAT_EVAL
+    /*
+     * Skip the command when it's not going to be executed.
+     * The commands like :if, :endif, etc. always need to be executed.
+     * Also make an exception for commands that handle a trailing command
+     * themselves.
+     */
+    if (ea.skip)
+    {
+	switch (ea.cmdidx)
+	{
+	    /* commands that need evaluation */
+	    case CMD_while:
+	    case CMD_endwhile:
+	    case CMD_for:
+	    case CMD_endfor:
+	    case CMD_if:
+	    case CMD_elseif:
+	    case CMD_else:
+	    case CMD_endif:
+	    case CMD_try:
+	    case CMD_catch:
+	    case CMD_finally:
+	    case CMD_endtry:
+	    case CMD_function:
+				break;
+
+	    /* Commands that handle '|' themselves.  Check: A command should
+	     * either have the TRLBAR flag, appear in this list or appear in
+	     * the list at ":help :bar". */
+	    case CMD_aboveleft:
+	    case CMD_and:
+	    case CMD_belowright:
+	    case CMD_botright:
+	    case CMD_browse:
+	    case CMD_call:
+	    case CMD_confirm:
+	    case CMD_delfunction:
+	    case CMD_djump:
+	    case CMD_dlist:
+	    case CMD_dsearch:
+	    case CMD_dsplit:
+	    case CMD_echo:
+	    case CMD_echoerr:
+	    case CMD_echomsg:
+	    case CMD_echon:
+	    case CMD_execute:
+	    case CMD_help:
+	    case CMD_hide:
+	    case CMD_ijump:
+	    case CMD_ilist:
+	    case CMD_isearch:
+	    case CMD_isplit:
+	    case CMD_keepalt:
+	    case CMD_keepjumps:
+	    case CMD_keepmarks:
+	    case CMD_leftabove:
+	    case CMD_let:
+	    case CMD_lockmarks:
+	    case CMD_match:
+	    case CMD_mzscheme:
+	    case CMD_perl:
+	    case CMD_psearch:
+	    case CMD_python:
+	    case CMD_return:
+	    case CMD_rightbelow:
+	    case CMD_ruby:
+	    case CMD_silent:
+	    case CMD_smagic:
+	    case CMD_snomagic:
+	    case CMD_substitute:
+	    case CMD_syntax:
+	    case CMD_tab:
+	    case CMD_tcl:
+	    case CMD_throw:
+	    case CMD_tilde:
+	    case CMD_topleft:
+	    case CMD_unlet:
+	    case CMD_verbose:
+	    case CMD_vertical:
+				break;
+
+	    default:		goto doend;
+	}
+    }
+#endif
+
+    if (ea.argt & XFILE)
+    {
+	if (expand_filename(&ea, cmdlinep, &errormsg) == FAIL)
+	    goto doend;
+    }
+
+#ifdef FEAT_LISTCMDS
+    /*
+     * Accept buffer name.  Cannot be used at the same time with a buffer
+     * number.  Don't do this for a user command.
+     */
+    if ((ea.argt & BUFNAME) && *ea.arg != NUL && ea.addr_count == 0
+# ifdef FEAT_USR_CMDS
+	    && !USER_CMDIDX(ea.cmdidx)
+# endif
+	    )
+    {
+	/*
+	 * :bdelete, :bwipeout and :bunload take several arguments, separated
+	 * by spaces: find next space (skipping over escaped characters).
+	 * The others take one argument: ignore trailing spaces.
+	 */
+	if (ea.cmdidx == CMD_bdelete || ea.cmdidx == CMD_bwipeout
+						  || ea.cmdidx == CMD_bunload)
+	    p = skiptowhite_esc(ea.arg);
+	else
+	{
+	    p = ea.arg + STRLEN(ea.arg);
+	    while (p > ea.arg && vim_iswhite(p[-1]))
+		--p;
+	}
+	ea.line2 = buflist_findpat(ea.arg, p, (ea.argt & BUFUNL) != 0, FALSE);
+	if (ea.line2 < 0)	    /* failed */
+	    goto doend;
+	ea.addr_count = 1;
+	ea.arg = skipwhite(p);
+    }
+#endif
+
+/*
+ * 6. switch on command name
+ *
+ * The "ea" structure holds the arguments that can be used.
+ */
+    ea.cmdlinep = cmdlinep;
+    ea.getline = fgetline;
+    ea.cookie = cookie;
+#ifdef FEAT_EVAL
+    ea.cstack = cstack;
+#endif
+
+#ifdef FEAT_USR_CMDS
+    if (USER_CMDIDX(ea.cmdidx))
+    {
+	/*
+	 * Execute a user-defined command.
+	 */
+	do_ucmd(&ea);
+    }
+    else
+#endif
+    {
+	/*
+	 * Call the function to execute the command.
+	 */
+	ea.errmsg = NULL;
+	(cmdnames[ea.cmdidx].cmd_func)(&ea);
+	if (ea.errmsg != NULL)
+	    errormsg = (char_u *)_(ea.errmsg);
+    }
+
+#ifdef FEAT_EVAL
+    /*
+     * If the command just executed called do_cmdline(), any throw or ":return"
+     * or ":finish" encountered there must also check the cstack of the still
+     * active do_cmdline() that called this do_one_cmd().  Rethrow an uncaught
+     * exception, or reanimate a returned function or finished script file and
+     * return or finish it again.
+     */
+    if (need_rethrow)
+	do_throw(cstack);
+    else if (check_cstack)
+    {
+	if (source_finished(fgetline, cookie))
+	    do_finish(&ea, TRUE);
+	else if (getline_equal(fgetline, cookie, get_func_line)
+						   && current_func_returned())
+	    do_return(&ea, TRUE, FALSE, NULL);
+    }
+    need_rethrow = check_cstack = FALSE;
+#endif
+
+doend:
+    if (curwin->w_cursor.lnum == 0)	/* can happen with zero line number */
+	curwin->w_cursor.lnum = 1;
+
+    if (errormsg != NULL && *errormsg != NUL && !did_emsg)
+    {
+	if (sourcing)
+	{
+	    if (errormsg != IObuff)
+	    {
+		STRCPY(IObuff, errormsg);
+		errormsg = IObuff;
+	    }
+	    STRCAT(errormsg, ": ");
+	    STRNCAT(errormsg, *cmdlinep, IOSIZE - STRLEN(IObuff));
+	}
+	emsg(errormsg);
+    }
+#ifdef FEAT_EVAL
+    do_errthrow(cstack,
+	    (ea.cmdidx != CMD_SIZE
+# ifdef FEAT_USR_CMDS
+	     && !USER_CMDIDX(ea.cmdidx)
+# endif
+	    ) ? cmdnames[(int)ea.cmdidx].cmd_name : (char_u *)NULL);
+#endif
+
+    if (verbose_save >= 0)
+	p_verbose = verbose_save;
+#ifdef FEAT_AUTOCMD
+    if (cmdmod.save_ei != NULL)
+    {
+	/* Restore 'eventignore' to the value before ":noautocmd". */
+	set_string_option_direct((char_u *)"ei", -1, cmdmod.save_ei,
+							  OPT_FREE, SID_NONE);
+	free_string_option(cmdmod.save_ei);
+    }
+#endif
+
+    cmdmod = save_cmdmod;
+
+    if (did_silent > 0)
+    {
+	/* messages could be enabled for a serious error, need to check if the
+	 * counters don't become negative */
+	msg_silent -= did_silent;
+	if (msg_silent < 0)
+	    msg_silent = 0;
+	emsg_silent -= did_esilent;
+	if (emsg_silent < 0)
+	    emsg_silent = 0;
+	/* Restore msg_scroll, it's set by file I/O commands, even when no
+	 * message is actually displayed. */
+	msg_scroll = save_msg_scroll;
+    }
+
+#ifdef HAVE_SANDBOX
+    if (did_sandbox)
+	--sandbox;
+#endif
+
+    if (ea.nextcmd && *ea.nextcmd == NUL)	/* not really a next command */
+	ea.nextcmd = NULL;
+
+#ifdef FEAT_EVAL
+    --ex_nesting_level;
+#endif
+
+    return ea.nextcmd;
+}
+#if (_MSC_VER == 1200)
+ #pragma optimize( "", on )
+#endif
+
+/*
+ * Check for an Ex command with optional tail.
+ * If there is a match advance "pp" to the argument and return TRUE.
+ */
+    int
+checkforcmd(pp, cmd, len)
+    char_u	**pp;		/* start of command */
+    char	*cmd;		/* name of command */
+    int		len;		/* required length */
+{
+    int		i;
+
+    for (i = 0; cmd[i] != NUL; ++i)
+	if (cmd[i] != (*pp)[i])
+	    break;
+    if (i >= len && !isalpha((*pp)[i]))
+    {
+	*pp = skipwhite(*pp + i);
+	return TRUE;
+    }
+    return FALSE;
+}
+
+/*
+ * Find an Ex command by its name, either built-in or user.
+ * Start of the name can be found at eap->cmd.
+ * Returns pointer to char after the command name.
+ * "full" is set to TRUE if the whole command name matched.
+ * Returns NULL for an ambiguous user command.
+ */
+/*ARGSUSED*/
+    static char_u *
+find_command(eap, full)
+    exarg_T	*eap;
+    int		*full;
+{
+    int		len;
+    char_u	*p;
+    int		i;
+
+    /*
+     * Isolate the command and search for it in the command table.
+     * Exeptions:
+     * - the 'k' command can directly be followed by any character.
+     * - the 's' command can be followed directly by 'c', 'g', 'i', 'I' or 'r'
+     *	    but :sre[wind] is another command, as are :scrip[tnames],
+     *	    :scs[cope], :sim[alt], :sig[ns] and :sil[ent].
+     * - the "d" command can directly be followed by 'l' or 'p' flag.
+     */
+    p = eap->cmd;
+    if (*p == 'k')
+    {
+	eap->cmdidx = CMD_k;
+	++p;
+    }
+    else if (p[0] == 's'
+	    && ((p[1] == 'c' && p[2] != 's' && p[2] != 'r'
+						&& p[3] != 'i' && p[4] != 'p')
+		|| p[1] == 'g'
+		|| (p[1] == 'i' && p[2] != 'm' && p[2] != 'l' && p[2] != 'g')
+		|| p[1] == 'I'
+		|| (p[1] == 'r' && p[2] != 'e')))
+    {
+	eap->cmdidx = CMD_substitute;
+	++p;
+    }
+    else
+    {
+	while (ASCII_ISALPHA(*p))
+	    ++p;
+	/* check for non-alpha command */
+	if (p == eap->cmd && vim_strchr((char_u *)"@*!=><&~#", *p) != NULL)
+	    ++p;
+	len = (int)(p - eap->cmd);
+	if (*eap->cmd == 'd' && (p[-1] == 'l' || p[-1] == 'p'))
+	{
+	    /* Check for ":dl", ":dell", etc. to ":deletel": that's
+	     * :delete with the 'l' flag.  Same for 'p'. */
+	    for (i = 0; i < len; ++i)
+		if (eap->cmd[i] != "delete"[i])
+		    break;
+	    if (i == len - 1)
+	    {
+		--len;
+		if (p[-1] == 'l')
+		    eap->flags |= EXFLAG_LIST;
+		else
+		    eap->flags |= EXFLAG_PRINT;
+	    }
+	}
+
+	if (ASCII_ISLOWER(*eap->cmd))
+	    eap->cmdidx = cmdidxs[CharOrdLow(*eap->cmd)];
+	else
+	    eap->cmdidx = cmdidxs[26];
+
+	for ( ; (int)eap->cmdidx < (int)CMD_SIZE;
+			       eap->cmdidx = (cmdidx_T)((int)eap->cmdidx + 1))
+	    if (STRNCMP(cmdnames[(int)eap->cmdidx].cmd_name, (char *)eap->cmd,
+							    (size_t)len) == 0)
+	    {
+#ifdef FEAT_EVAL
+		if (full != NULL
+			   && cmdnames[(int)eap->cmdidx].cmd_name[len] == NUL)
+		    *full = TRUE;
+#endif
+		break;
+	    }
+
+#ifdef FEAT_USR_CMDS
+	/* Look for a user defined command as a last resort */
+	if (eap->cmdidx == CMD_SIZE && *eap->cmd >= 'A' && *eap->cmd <= 'Z')
+	{
+	    /* User defined commands may contain digits. */
+	    while (ASCII_ISALNUM(*p))
+		++p;
+	    p = find_ucmd(eap, p, full, NULL, NULL);
+	}
+#endif
+	if (p == eap->cmd)
+	    eap->cmdidx = CMD_SIZE;
+    }
+
+    return p;
+}
+
+#ifdef FEAT_USR_CMDS
+/*
+ * Search for a user command that matches "eap->cmd".
+ * Return cmdidx in "eap->cmdidx", flags in "eap->argt", idx in "eap->useridx".
+ * Return a pointer to just after the command.
+ * Return NULL if there is no matching command.
+ */
+    static char_u *
+find_ucmd(eap, p, full, xp, compl)
+    exarg_T	*eap;
+    char_u	*p;	/* end of the command (possibly including count) */
+    int		*full;	/* set to TRUE for a full match */
+    expand_T	*xp;	/* used for completion, NULL otherwise */
+    int		*compl;	/* completion flags or NULL */
+{
+    int		len = (int)(p - eap->cmd);
+    int		j, k, matchlen = 0;
+    ucmd_T	*uc;
+    int		found = FALSE;
+    int		possible = FALSE;
+    char_u	*cp, *np;	    /* Point into typed cmd and test name */
+    garray_T	*gap;
+    int		amb_local = FALSE;  /* Found ambiguous buffer-local command,
+				       only full match global is accepted. */
+
+    /*
+     * Look for buffer-local user commands first, then global ones.
+     */
+    gap = &curbuf->b_ucmds;
+    for (;;)
+    {
+	for (j = 0; j < gap->ga_len; ++j)
+	{
+	    uc = USER_CMD_GA(gap, j);
+	    cp = eap->cmd;
+	    np = uc->uc_name;
+	    k = 0;
+	    while (k < len && *np != NUL && *cp++ == *np++)
+		k++;
+	    if (k == len || (*np == NUL && vim_isdigit(eap->cmd[k])))
+	    {
+		/* If finding a second match, the command is ambiguous.  But
+		 * not if a buffer-local command wasn't a full match and a
+		 * global command is a full match. */
+		if (k == len && found && *np != NUL)
+		{
+		    if (gap == &ucmds)
+			return NULL;
+		    amb_local = TRUE;
+		}
+
+		if (!found || (k == len && *np == NUL))
+		{
+		    /* If we matched up to a digit, then there could
+		     * be another command including the digit that we
+		     * should use instead.
+		     */
+		    if (k == len)
+			found = TRUE;
+		    else
+			possible = TRUE;
+
+		    if (gap == &ucmds)
+			eap->cmdidx = CMD_USER;
+		    else
+			eap->cmdidx = CMD_USER_BUF;
+		    eap->argt = (long)uc->uc_argt;
+		    eap->useridx = j;
+
+# ifdef FEAT_CMDL_COMPL
+		    if (compl != NULL)
+			*compl = uc->uc_compl;
+#  ifdef FEAT_EVAL
+		    if (xp != NULL)
+		    {
+			xp->xp_arg = uc->uc_compl_arg;
+			xp->xp_scriptID = uc->uc_scriptID;
+		    }
+#  endif
+# endif
+		    /* Do not search for further abbreviations
+		     * if this is an exact match. */
+		    matchlen = k;
+		    if (k == len && *np == NUL)
+		    {
+			if (full != NULL)
+			    *full = TRUE;
+			amb_local = FALSE;
+			break;
+		    }
+		}
+	    }
+	}
+
+	/* Stop if we found a full match or searched all. */
+	if (j < gap->ga_len || gap == &ucmds)
+	    break;
+	gap = &ucmds;
+    }
+
+    /* Only found ambiguous matches. */
+    if (amb_local)
+    {
+	if (xp != NULL)
+	    xp->xp_context = EXPAND_UNSUCCESSFUL;
+	return NULL;
+    }
+
+    /* The match we found may be followed immediately by a number.  Move "p"
+     * back to point to it. */
+    if (found || possible)
+	return p + (matchlen - len);
+    return p;
+}
+#endif
+
+#if defined(FEAT_EVAL) || defined(PROTO)
+/*
+ * Return > 0 if an Ex command "name" exists.
+ * Return 2 if there is an exact match.
+ * Return 3 if there is an ambiguous match.
+ */
+    int
+cmd_exists(name)
+    char_u	*name;
+{
+    exarg_T	ea;
+    int		full = FALSE;
+    int		i;
+    int		j;
+    char_u	*p;
+    static struct cmdmod
+    {
+	char	*name;
+	int	minlen;
+    } cmdmods[] = {
+	{"aboveleft", 3},
+	{"belowright", 3},
+	{"botright", 2},
+	{"browse", 3},
+	{"confirm", 4},
+	{"hide", 3},
+	{"keepalt", 5},
+	{"keepjumps", 5},
+	{"keepmarks", 3},
+	{"leftabove", 5},
+	{"lockmarks", 3},
+	{"rightbelow", 6},
+	{"sandbox", 3},
+	{"silent", 3},
+	{"tab", 3},
+	{"topleft", 2},
+	{"verbose", 4},
+	{"vertical", 4},
+    };
+
+    /* Check command modifiers. */
+    for (i = 0; i < sizeof(cmdmods) / sizeof(struct cmdmod); ++i)
+    {
+	for (j = 0; name[j] != NUL; ++j)
+	    if (name[j] != cmdmods[i].name[j])
+		break;
+	if (name[j] == NUL && j >= cmdmods[i].minlen)
+	    return (cmdmods[i].name[j] == NUL ? 2 : 1);
+    }
+
+    /* Check built-in commands and user defined commands.
+     * For ":2match" and ":3match" we need to skip the number. */
+    ea.cmd = (*name == '2' || *name == '3') ? name + 1 : name;
+    ea.cmdidx = (cmdidx_T)0;
+    p = find_command(&ea, &full);
+    if (p == NULL)
+	return 3;
+    if (vim_isdigit(*name) && ea.cmdidx != CMD_match)
+	return 0;
+    if (*skipwhite(p) != NUL)
+	return 0;	/* trailing garbage */
+    return (ea.cmdidx == CMD_SIZE ? 0 : (full ? 2 : 1));
+}
+#endif
+
+/*
+ * This is all pretty much copied from do_one_cmd(), with all the extra stuff
+ * we don't need/want deleted.	Maybe this could be done better if we didn't
+ * repeat all this stuff.  The only problem is that they may not stay
+ * perfectly compatible with each other, but then the command line syntax
+ * probably won't change that much -- webb.
+ */
+    char_u *
+set_one_cmd_context(xp, buff)
+    expand_T	*xp;
+    char_u	*buff;	    /* buffer for command string */
+{
+    char_u		*p;
+    char_u		*cmd, *arg;
+    int			len = 0;
+    exarg_T		ea;
+#if defined(FEAT_USR_CMDS) && defined(FEAT_CMDL_COMPL)
+    int			compl = EXPAND_NOTHING;
+#endif
+#ifdef FEAT_CMDL_COMPL
+    int			delim;
+#endif
+    int			forceit = FALSE;
+    int			usefilter = FALSE;  /* filter instead of file name */
+
+    ExpandInit(xp);
+    xp->xp_pattern = buff;
+    xp->xp_context = EXPAND_COMMANDS;	/* Default until we get past command */
+    ea.argt = 0;
+
+/*
+ * 2. skip comment lines and leading space, colons or bars
+ */
+    for (cmd = buff; vim_strchr((char_u *)" \t:|", *cmd) != NULL; cmd++)
+	;
+    xp->xp_pattern = cmd;
+
+    if (*cmd == NUL)
+	return NULL;
+    if (*cmd == '"')	    /* ignore comment lines */
+    {
+	xp->xp_context = EXPAND_NOTHING;
+	return NULL;
+    }
+
+/*
+ * 3. parse a range specifier of the form: addr [,addr] [;addr] ..
+ */
+    cmd = skip_range(cmd, &xp->xp_context);
+
+/*
+ * 4. parse command
+ */
+    xp->xp_pattern = cmd;
+    if (*cmd == NUL)
+	return NULL;
+    if (*cmd == '"')
+    {
+	xp->xp_context = EXPAND_NOTHING;
+	return NULL;
+    }
+
+    if (*cmd == '|' || *cmd == '\n')
+	return cmd + 1;			/* There's another command */
+
+    /*
+     * Isolate the command and search for it in the command table.
+     * Exceptions:
+     * - the 'k' command can directly be followed by any character, but
+     *   do accept "keepmarks", "keepalt" and "keepjumps".
+     * - the 's' command can be followed directly by 'c', 'g', 'i', 'I' or 'r'
+     */
+    if (*cmd == 'k' && cmd[1] != 'e')
+    {
+	ea.cmdidx = CMD_k;
+	p = cmd + 1;
+    }
+    else
+    {
+	p = cmd;
+	while (ASCII_ISALPHA(*p) || *p == '*')    /* Allow * wild card */
+	    ++p;
+	/* check for non-alpha command */
+	if (p == cmd && vim_strchr((char_u *)"@*!=><&~#", *p) != NULL)
+	    ++p;
+	len = (int)(p - cmd);
+
+	if (len == 0)
+	{
+	    xp->xp_context = EXPAND_UNSUCCESSFUL;
+	    return NULL;
+	}
+	for (ea.cmdidx = (cmdidx_T)0; (int)ea.cmdidx < (int)CMD_SIZE;
+					 ea.cmdidx = (cmdidx_T)((int)ea.cmdidx + 1))
+	    if (STRNCMP(cmdnames[(int)ea.cmdidx].cmd_name, cmd, (size_t)len) == 0)
+		break;
+
+#ifdef FEAT_USR_CMDS
+	if (cmd[0] >= 'A' && cmd[0] <= 'Z')
+	{
+	    while (ASCII_ISALNUM(*p) || *p == '*')	/* Allow * wild card */
+		++p;
+	    len = (int)(p - cmd);
+	}
+#endif
+    }
+
+    /*
+     * If the cursor is touching the command, and it ends in an alpha-numeric
+     * character, complete the command name.
+     */
+    if (*p == NUL && ASCII_ISALNUM(p[-1]))
+	return NULL;
+
+    if (ea.cmdidx == CMD_SIZE)
+    {
+	if (*cmd == 's' && vim_strchr((char_u *)"cgriI", cmd[1]) != NULL)
+	{
+	    ea.cmdidx = CMD_substitute;
+	    p = cmd + 1;
+	}
+#ifdef FEAT_USR_CMDS
+	else if (cmd[0] >= 'A' && cmd[0] <= 'Z')
+	{
+	    ea.cmd = cmd;
+	    p = find_ucmd(&ea, p, NULL, xp,
+# if defined(FEAT_CMDL_COMPL)
+		    &compl
+# else
+		    NULL
+# endif
+		    );
+	    if (p == NULL)
+		ea.cmdidx = CMD_SIZE;	/* ambiguous user command */
+	}
+#endif
+    }
+    if (ea.cmdidx == CMD_SIZE)
+    {
+	/* Not still touching the command and it was an illegal one */
+	xp->xp_context = EXPAND_UNSUCCESSFUL;
+	return NULL;
+    }
+
+    xp->xp_context = EXPAND_NOTHING; /* Default now that we're past command */
+
+    if (*p == '!')		    /* forced commands */
+    {
+	forceit = TRUE;
+	++p;
+    }
+
+/*
+ * 5. parse arguments
+ */
+#ifdef FEAT_USR_CMDS
+    if (!USER_CMDIDX(ea.cmdidx))
+#endif
+	ea.argt = (long)cmdnames[(int)ea.cmdidx].cmd_argt;
+
+    arg = skipwhite(p);
+
+    if (ea.cmdidx == CMD_write || ea.cmdidx == CMD_update)
+    {
+	if (*arg == '>')			/* append */
+	{
+	    if (*++arg == '>')
+		++arg;
+	    arg = skipwhite(arg);
+	}
+	else if (*arg == '!' && ea.cmdidx == CMD_write)	/* :w !filter */
+	{
+	    ++arg;
+	    usefilter = TRUE;
+	}
+    }
+
+    if (ea.cmdidx == CMD_read)
+    {
+	usefilter = forceit;			/* :r! filter if forced */
+	if (*arg == '!')			/* :r !filter */
+	{
+	    ++arg;
+	    usefilter = TRUE;
+	}
+    }
+
+    if (ea.cmdidx == CMD_lshift || ea.cmdidx == CMD_rshift)
+    {
+	while (*arg == *cmd)	    /* allow any number of '>' or '<' */
+	    ++arg;
+	arg = skipwhite(arg);
+    }
+
+    /* Does command allow "+command"? */
+    if ((ea.argt & EDITCMD) && !usefilter && *arg == '+')
+    {
+	/* Check if we're in the +command */
+	p = arg + 1;
+	arg = skip_cmd_arg(arg, FALSE);
+
+	/* Still touching the command after '+'? */
+	if (*arg == NUL)
+	    return p;
+
+	/* Skip space(s) after +command to get to the real argument */
+	arg = skipwhite(arg);
+    }
+
+    /*
+     * Check for '|' to separate commands and '"' to start comments.
+     * Don't do this for ":read !cmd" and ":write !cmd".
+     */
+    if ((ea.argt & TRLBAR) && !usefilter)
+    {
+	p = arg;
+	/* ":redir @" is not the start of a comment */
+	if (ea.cmdidx == CMD_redir && p[0] == '@' && p[1] == '"')
+	    p += 2;
+	while (*p)
+	{
+	    if (*p == Ctrl_V)
+	    {
+		if (p[1] != NUL)
+		    ++p;
+	    }
+	    else if ( (*p == '"' && !(ea.argt & NOTRLCOM))
+		    || *p == '|' || *p == '\n')
+	    {
+		if (*(p - 1) != '\\')
+		{
+		    if (*p == '|' || *p == '\n')
+			return p + 1;
+		    return NULL;    /* It's a comment */
+		}
+	    }
+	    mb_ptr_adv(p);
+	}
+    }
+
+						/* no arguments allowed */
+    if (!(ea.argt & EXTRA) && *arg != NUL &&
+				    vim_strchr((char_u *)"|\"", *arg) == NULL)
+	return NULL;
+
+    /* Find start of last argument (argument just before cursor): */
+    p = buff + STRLEN(buff);
+    while (p != arg && *p != ' ' && *p != TAB)
+	p--;
+    if (*p == ' ' || *p == TAB)
+	p++;
+    xp->xp_pattern = p;
+
+    if (ea.argt & XFILE)
+    {
+	int in_quote = FALSE;
+	char_u *bow = NULL;	/* Beginning of word */
+
+	/*
+	 * Allow spaces within back-quotes to count as part of the argument
+	 * being expanded.
+	 */
+	xp->xp_pattern = skipwhite(arg);
+	for (p = xp->xp_pattern; *p; )
+	{
+	    if (*p == '\\' && p[1] != NUL)
+		++p;
+#ifdef SPACE_IN_FILENAME
+	    else if (vim_iswhite(*p) && (!(ea.argt & NOSPC) || usefilter))
+#else
+	    else if (vim_iswhite(*p))
+#endif
+	    {
+		p = skipwhite(p);
+		if (in_quote)
+		    bow = p;
+		else
+		    xp->xp_pattern = p;
+		--p;
+	    }
+	    else if (*p == '`')
+	    {
+		if (!in_quote)
+		{
+		    xp->xp_pattern = p;
+		    bow = p + 1;
+		}
+		in_quote = !in_quote;
+	    }
+	    mb_ptr_adv(p);
+	}
+
+	/*
+	 * If we are still inside the quotes, and we passed a space, just
+	 * expand from there.
+	 */
+	if (bow != NULL && in_quote)
+	    xp->xp_pattern = bow;
+	xp->xp_context = EXPAND_FILES;
+
+#ifndef BACKSLASH_IN_FILENAME
+	/* For a shell command more chars need to be escaped. */
+	if (usefilter || ea.cmdidx == CMD_bang)
+	{
+	    xp->xp_shell = TRUE;
+
+	    /* When still after the command name expand executables. */
+	    if (xp->xp_pattern == skipwhite(arg))
+		xp->xp_context = EXPAND_SHELLCMD;
+	}
+#endif
+
+	/* Check for environment variable */
+	if (*xp->xp_pattern == '$'
+#if defined(MSDOS) || defined(MSWIN) || defined(OS2)
+		|| *xp->xp_pattern == '%'
+#endif
+		)
+	{
+	    for (p = xp->xp_pattern + 1; *p != NUL; ++p)
+		if (!vim_isIDc(*p))
+		    break;
+	    if (*p == NUL)
+	    {
+		xp->xp_context = EXPAND_ENV_VARS;
+		++xp->xp_pattern;
+#if defined(FEAT_USR_CMDS) && defined(FEAT_CMDL_COMPL)
+		/* Avoid that the assignment uses EXPAND_FILES again. */
+		if (compl != EXPAND_USER_DEFINED && compl != EXPAND_USER_LIST)
+		    compl = EXPAND_ENV_VARS;
+#endif
+	    }
+	}
+    }
+
+/*
+ * 6. switch on command name
+ */
+    switch (ea.cmdidx)
+    {
+	case CMD_cd:
+	case CMD_chdir:
+	case CMD_lcd:
+	case CMD_lchdir:
+	    if (xp->xp_context == EXPAND_FILES)
+		xp->xp_context = EXPAND_DIRECTORIES;
+	    break;
+	case CMD_help:
+	    xp->xp_context = EXPAND_HELP;
+	    xp->xp_pattern = arg;
+	    break;
+
+	/* Command modifiers: return the argument.
+	 * Also for commands with an argument that is a command. */
+	case CMD_aboveleft:
+	case CMD_argdo:
+	case CMD_belowright:
+	case CMD_botright:
+	case CMD_browse:
+	case CMD_bufdo:
+	case CMD_confirm:
+	case CMD_debug:
+	case CMD_folddoclosed:
+	case CMD_folddoopen:
+	case CMD_hide:
+	case CMD_keepalt:
+	case CMD_keepjumps:
+	case CMD_keepmarks:
+	case CMD_leftabove:
+	case CMD_lockmarks:
+	case CMD_rightbelow:
+	case CMD_sandbox:
+	case CMD_silent:
+	case CMD_tab:
+	case CMD_topleft:
+	case CMD_verbose:
+	case CMD_vertical:
+	case CMD_windo:
+	    return arg;
+
+#ifdef FEAT_SEARCH_EXTRA
+	case CMD_match:
+	    if (*arg == NUL || !ends_excmd(*arg))
+	    {
+		/* Dummy call to clear variables. */
+		set_context_in_highlight_cmd(xp, (char_u *)"link n");
+		xp->xp_context = EXPAND_HIGHLIGHT;
+		xp->xp_pattern = arg;
+		arg = skipwhite(skiptowhite(arg));
+		if (*arg != NUL)
+		{
+		    xp->xp_context = EXPAND_NOTHING;
+		    arg = skip_regexp(arg + 1, *arg, p_magic, NULL);
+		}
+	    }
+	    return find_nextcmd(arg);
+#endif
+
+#ifdef FEAT_CMDL_COMPL
+/*
+ * All completion for the +cmdline_compl feature goes here.
+ */
+
+# ifdef FEAT_USR_CMDS
+	case CMD_command:
+	    /* Check for attributes */
+	    while (*arg == '-')
+	    {
+		arg++;	    /* Skip "-" */
+		p = skiptowhite(arg);
+		if (*p == NUL)
+		{
+		    /* Cursor is still in the attribute */
+		    p = vim_strchr(arg, '=');
+		    if (p == NULL)
+		    {
+			/* No "=", so complete attribute names */
+			xp->xp_context = EXPAND_USER_CMD_FLAGS;
+			xp->xp_pattern = arg;
+			return NULL;
+		    }
+
+		    /* For the -complete and -nargs attributes, we complete
+		     * their arguments as well.
+		     */
+		    if (STRNICMP(arg, "complete", p - arg) == 0)
+		    {
+			xp->xp_context = EXPAND_USER_COMPLETE;
+			xp->xp_pattern = p + 1;
+			return NULL;
+		    }
+		    else if (STRNICMP(arg, "nargs", p - arg) == 0)
+		    {
+			xp->xp_context = EXPAND_USER_NARGS;
+			xp->xp_pattern = p + 1;
+			return NULL;
+		    }
+		    return NULL;
+		}
+		arg = skipwhite(p);
+	    }
+
+	    /* After the attributes comes the new command name */
+	    p = skiptowhite(arg);
+	    if (*p == NUL)
+	    {
+		xp->xp_context = EXPAND_USER_COMMANDS;
+		xp->xp_pattern = arg;
+		break;
+	    }
+
+	    /* And finally comes a normal command */
+	    return skipwhite(p);
+
+	case CMD_delcommand:
+	    xp->xp_context = EXPAND_USER_COMMANDS;
+	    xp->xp_pattern = arg;
+	    break;
+# endif
+
+	case CMD_global:
+	case CMD_vglobal:
+	    delim = *arg;	    /* get the delimiter */
+	    if (delim)
+		++arg;		    /* skip delimiter if there is one */
+
+	    while (arg[0] != NUL && arg[0] != delim)
+	    {
+		if (arg[0] == '\\' && arg[1] != NUL)
+		    ++arg;
+		++arg;
+	    }
+	    if (arg[0] != NUL)
+		return arg + 1;
+	    break;
+	case CMD_and:
+	case CMD_substitute:
+	    delim = *arg;
+	    if (delim)
+	    {
+		/* skip "from" part */
+		++arg;
+		arg = skip_regexp(arg, delim, p_magic, NULL);
+	    }
+	    /* skip "to" part */
+	    while (arg[0] != NUL && arg[0] != delim)
+	    {
+		if (arg[0] == '\\' && arg[1] != NUL)
+		    ++arg;
+		++arg;
+	    }
+	    if (arg[0] != NUL)	/* skip delimiter */
+		++arg;
+	    while (arg[0] && vim_strchr((char_u *)"|\"#", arg[0]) == NULL)
+		++arg;
+	    if (arg[0] != NUL)
+		return arg;
+	    break;
+	case CMD_isearch:
+	case CMD_dsearch:
+	case CMD_ilist:
+	case CMD_dlist:
+	case CMD_ijump:
+	case CMD_psearch:
+	case CMD_djump:
+	case CMD_isplit:
+	case CMD_dsplit:
+	    arg = skipwhite(skipdigits(arg));	    /* skip count */
+	    if (*arg == '/')	/* Match regexp, not just whole words */
+	    {
+		for (++arg; *arg && *arg != '/'; arg++)
+		    if (*arg == '\\' && arg[1] != NUL)
+			arg++;
+		if (*arg)
+		{
+		    arg = skipwhite(arg + 1);
+
+		    /* Check for trailing illegal characters */
+		    if (*arg && vim_strchr((char_u *)"|\"\n", *arg) == NULL)
+			xp->xp_context = EXPAND_NOTHING;
+		    else
+			return arg;
+		}
+	    }
+	    break;
+#ifdef FEAT_AUTOCMD
+	case CMD_autocmd:
+	    return set_context_in_autocmd(xp, arg, FALSE);
+
+	case CMD_doautocmd:
+	    return set_context_in_autocmd(xp, arg, TRUE);
+#endif
+	case CMD_set:
+	    set_context_in_set_cmd(xp, arg, 0);
+	    break;
+	case CMD_setglobal:
+	    set_context_in_set_cmd(xp, arg, OPT_GLOBAL);
+	    break;
+	case CMD_setlocal:
+	    set_context_in_set_cmd(xp, arg, OPT_LOCAL);
+	    break;
+	case CMD_tag:
+	case CMD_stag:
+	case CMD_ptag:
+	case CMD_ltag:
+	case CMD_tselect:
+	case CMD_stselect:
+	case CMD_ptselect:
+	case CMD_tjump:
+	case CMD_stjump:
+	case CMD_ptjump:
+	    if (*p_wop != NUL)
+		xp->xp_context = EXPAND_TAGS_LISTFILES;
+	    else
+		xp->xp_context = EXPAND_TAGS;
+	    xp->xp_pattern = arg;
+	    break;
+	case CMD_augroup:
+	    xp->xp_context = EXPAND_AUGROUP;
+	    xp->xp_pattern = arg;
+	    break;
+#ifdef FEAT_SYN_HL
+	case CMD_syntax:
+	    set_context_in_syntax_cmd(xp, arg);
+	    break;
+#endif
+#ifdef FEAT_EVAL
+	case CMD_let:
+	case CMD_if:
+	case CMD_elseif:
+	case CMD_while:
+	case CMD_for:
+	case CMD_echo:
+	case CMD_echon:
+	case CMD_execute:
+	case CMD_echomsg:
+	case CMD_echoerr:
+	case CMD_call:
+	case CMD_return:
+	    set_context_for_expression(xp, arg, ea.cmdidx);
+	    break;
+
+	case CMD_unlet:
+	    while ((xp->xp_pattern = vim_strchr(arg, ' ')) != NULL)
+		arg = xp->xp_pattern + 1;
+	    xp->xp_context = EXPAND_USER_VARS;
+	    xp->xp_pattern = arg;
+	    break;
+
+	case CMD_function:
+	case CMD_delfunction:
+	    xp->xp_context = EXPAND_USER_FUNC;
+	    xp->xp_pattern = arg;
+	    break;
+
+	case CMD_echohl:
+	    xp->xp_context = EXPAND_HIGHLIGHT;
+	    xp->xp_pattern = arg;
+	    break;
+#endif
+	case CMD_highlight:
+	    set_context_in_highlight_cmd(xp, arg);
+	    break;
+#ifdef FEAT_LISTCMDS
+	case CMD_bdelete:
+	case CMD_bwipeout:
+	case CMD_bunload:
+	    while ((xp->xp_pattern = vim_strchr(arg, ' ')) != NULL)
+		arg = xp->xp_pattern + 1;
+	    /*FALLTHROUGH*/
+	case CMD_buffer:
+	case CMD_sbuffer:
+	case CMD_checktime:
+	    xp->xp_context = EXPAND_BUFFERS;
+	    xp->xp_pattern = arg;
+	    break;
+#endif
+#ifdef FEAT_USR_CMDS
+	case CMD_USER:
+	case CMD_USER_BUF:
+	    if (compl != EXPAND_NOTHING)
+	    {
+		/* XFILE: file names are handled above */
+		if (!(ea.argt & XFILE))
+		{
+# ifdef FEAT_MENU
+		    if (compl == EXPAND_MENUS)
+			return set_context_in_menu_cmd(xp, cmd, arg, forceit);
+# endif
+		    if (compl == EXPAND_COMMANDS)
+			return arg;
+		    if (compl == EXPAND_MAPPINGS)
+			return set_context_in_map_cmd(xp, (char_u *)"map",
+					 arg, forceit, FALSE, FALSE, CMD_map);
+		    while ((xp->xp_pattern = vim_strchr(arg, ' ')) != NULL)
+			arg = xp->xp_pattern + 1;
+		    xp->xp_pattern = arg;
+		}
+		xp->xp_context = compl;
+	    }
+	    break;
+#endif
+	case CMD_map:	    case CMD_noremap:
+	case CMD_nmap:	    case CMD_nnoremap:
+	case CMD_vmap:	    case CMD_vnoremap:
+	case CMD_omap:	    case CMD_onoremap:
+	case CMD_imap:	    case CMD_inoremap:
+	case CMD_cmap:	    case CMD_cnoremap:
+	    return set_context_in_map_cmd(xp, cmd, arg, forceit,
+							FALSE, FALSE, ea.cmdidx);
+	case CMD_unmap:
+	case CMD_nunmap:
+	case CMD_vunmap:
+	case CMD_ounmap:
+	case CMD_iunmap:
+	case CMD_cunmap:
+	    return set_context_in_map_cmd(xp, cmd, arg, forceit,
+							 FALSE, TRUE, ea.cmdidx);
+	case CMD_abbreviate:	case CMD_noreabbrev:
+	case CMD_cabbrev:	case CMD_cnoreabbrev:
+	case CMD_iabbrev:	case CMD_inoreabbrev:
+	    return set_context_in_map_cmd(xp, cmd, arg, forceit,
+							 TRUE, FALSE, ea.cmdidx);
+	case CMD_unabbreviate:
+	case CMD_cunabbrev:
+	case CMD_iunabbrev:
+	    return set_context_in_map_cmd(xp, cmd, arg, forceit,
+							  TRUE, TRUE, ea.cmdidx);
+#ifdef FEAT_MENU
+	case CMD_menu:	    case CMD_noremenu:	    case CMD_unmenu:
+	case CMD_amenu:	    case CMD_anoremenu:	    case CMD_aunmenu:
+	case CMD_nmenu:	    case CMD_nnoremenu:	    case CMD_nunmenu:
+	case CMD_vmenu:	    case CMD_vnoremenu:	    case CMD_vunmenu:
+	case CMD_omenu:	    case CMD_onoremenu:	    case CMD_ounmenu:
+	case CMD_imenu:	    case CMD_inoremenu:	    case CMD_iunmenu:
+	case CMD_cmenu:	    case CMD_cnoremenu:	    case CMD_cunmenu:
+	case CMD_tmenu:				    case CMD_tunmenu:
+	case CMD_popup:	    case CMD_tearoff:	    case CMD_emenu:
+	    return set_context_in_menu_cmd(xp, cmd, arg, forceit);
+#endif
+
+	case CMD_colorscheme:
+	    xp->xp_context = EXPAND_COLORS;
+	    xp->xp_pattern = arg;
+	    break;
+
+	case CMD_compiler:
+	    xp->xp_context = EXPAND_COMPILER;
+	    xp->xp_pattern = arg;
+	    break;
+
+#if (defined(HAVE_LOCALE_H) || defined(X_LOCALE)) \
+	&& (defined(FEAT_GETTEXT) || defined(FEAT_MBYTE))
+	case CMD_language:
+	    if (*skiptowhite(arg) == NUL)
+	    {
+		xp->xp_context = EXPAND_LANGUAGE;
+		xp->xp_pattern = arg;
+	    }
+	    else
+		xp->xp_context = EXPAND_NOTHING;
+	    break;
+#endif
+
+#endif /* FEAT_CMDL_COMPL */
+
+	default:
+	    break;
+    }
+    return NULL;
+}
+
+/*
+ * skip a range specifier of the form: addr [,addr] [;addr] ..
+ *
+ * Backslashed delimiters after / or ? will be skipped, and commands will
+ * not be expanded between /'s and ?'s or after "'".
+ *
+ * Also skip white space and ":" characters.
+ * Returns the "cmd" pointer advanced to beyond the range.
+ */
+    char_u *
+skip_range(cmd, ctx)
+    char_u	*cmd;
+    int		*ctx;	/* pointer to xp_context or NULL */
+{
+    int		delim;
+
+    while (vim_strchr((char_u *)" \t0123456789.$%'/?-+,;", *cmd) != NULL)
+    {
+	if (*cmd == '\'')
+	{
+	    if (*++cmd == NUL && ctx != NULL)
+		*ctx = EXPAND_NOTHING;
+	}
+	else if (*cmd == '/' || *cmd == '?')
+	{
+	    delim = *cmd++;
+	    while (*cmd != NUL && *cmd != delim)
+		if (*cmd++ == '\\' && *cmd != NUL)
+		    ++cmd;
+	    if (*cmd == NUL && ctx != NULL)
+		*ctx = EXPAND_NOTHING;
+	}
+	if (*cmd != NUL)
+	    ++cmd;
+    }
+
+    /* Skip ":" and white space. */
+    while (*cmd == ':')
+	cmd = skipwhite(cmd + 1);
+
+    return cmd;
+}
+
+/*
+ * get a single EX address
+ *
+ * Set ptr to the next character after the part that was interpreted.
+ * Set ptr to NULL when an error is encountered.
+ *
+ * Return MAXLNUM when no Ex address was found.
+ */
+    static linenr_T
+get_address(ptr, skip, to_other_file)
+    char_u	**ptr;
+    int		skip;	    /* only skip the address, don't use it */
+    int		to_other_file;  /* flag: may jump to other file */
+{
+    int		c;
+    int		i;
+    long	n;
+    char_u	*cmd;
+    pos_T	pos;
+    pos_T	*fp;
+    linenr_T	lnum;
+
+    cmd = skipwhite(*ptr);
+    lnum = MAXLNUM;
+    do
+    {
+	switch (*cmd)
+	{
+	    case '.':			    /* '.' - Cursor position */
+			++cmd;
+			lnum = curwin->w_cursor.lnum;
+			break;
+
+	    case '$':			    /* '$' - last line */
+			++cmd;
+			lnum = curbuf->b_ml.ml_line_count;
+			break;
+
+	    case '\'':			    /* ''' - mark */
+			if (*++cmd == NUL)
+			{
+			    cmd = NULL;
+			    goto error;
+			}
+			if (skip)
+			    ++cmd;
+			else
+			{
+			    /* Only accept a mark in another file when it is
+			     * used by itself: ":'M". */
+			    fp = getmark(*cmd, to_other_file && cmd[1] == NUL);
+			    ++cmd;
+			    if (fp == (pos_T *)-1)
+				/* Jumped to another file. */
+				lnum = curwin->w_cursor.lnum;
+			    else
+			    {
+				if (check_mark(fp) == FAIL)
+				{
+				    cmd = NULL;
+				    goto error;
+				}
+				lnum = fp->lnum;
+			    }
+			}
+			break;
+
+	    case '/':
+	    case '?':			/* '/' or '?' - search */
+			c = *cmd++;
+			if (skip)	/* skip "/pat/" */
+			{
+			    cmd = skip_regexp(cmd, c, (int)p_magic, NULL);
+			    if (*cmd == c)
+				++cmd;
+			}
+			else
+			{
+			    pos = curwin->w_cursor; /* save curwin->w_cursor */
+			    /*
+			     * When '/' or '?' follows another address, start
+			     * from there.
+			     */
+			    if (lnum != MAXLNUM)
+				curwin->w_cursor.lnum = lnum;
+			    /*
+			     * Start a forward search at the end of the line.
+			     * Start a backward search at the start of the line.
+			     * This makes sure we never match in the current
+			     * line, and can match anywhere in the
+			     * next/previous line.
+			     */
+			    if (c == '/')
+				curwin->w_cursor.col = MAXCOL;
+			    else
+				curwin->w_cursor.col = 0;
+			    searchcmdlen = 0;
+			    if (!do_search(NULL, c, cmd, 1L,
+				      SEARCH_HIS + SEARCH_MSG + SEARCH_START))
+			    {
+				curwin->w_cursor = pos;
+				cmd = NULL;
+				goto error;
+			    }
+			    lnum = curwin->w_cursor.lnum;
+			    curwin->w_cursor = pos;
+			    /* adjust command string pointer */
+			    cmd += searchcmdlen;
+			}
+			break;
+
+	    case '\\':		    /* "\?", "\/" or "\&", repeat search */
+			++cmd;
+			if (*cmd == '&')
+			    i = RE_SUBST;
+			else if (*cmd == '?' || *cmd == '/')
+			    i = RE_SEARCH;
+			else
+			{
+			    EMSG(_(e_backslash));
+			    cmd = NULL;
+			    goto error;
+			}
+
+			if (!skip)
+			{
+			    /*
+			     * When search follows another address, start from
+			     * there.
+			     */
+			    if (lnum != MAXLNUM)
+				pos.lnum = lnum;
+			    else
+				pos.lnum = curwin->w_cursor.lnum;
+
+			    /*
+			     * Start the search just like for the above
+			     * do_search().
+			     */
+			    if (*cmd != '?')
+				pos.col = MAXCOL;
+			    else
+				pos.col = 0;
+			    if (searchit(curwin, curbuf, &pos,
+					*cmd == '?' ? BACKWARD : FORWARD,
+					(char_u *)"", 1L,
+					SEARCH_MSG + SEARCH_START,
+						      i, (linenr_T)0) != FAIL)
+				lnum = pos.lnum;
+			    else
+			    {
+				cmd = NULL;
+				goto error;
+			    }
+			}
+			++cmd;
+			break;
+
+	    default:
+			if (VIM_ISDIGIT(*cmd))	/* absolute line number */
+			    lnum = getdigits(&cmd);
+	}
+
+	for (;;)
+	{
+	    cmd = skipwhite(cmd);
+	    if (*cmd != '-' && *cmd != '+' && !VIM_ISDIGIT(*cmd))
+		break;
+
+	    if (lnum == MAXLNUM)
+		lnum = curwin->w_cursor.lnum;	/* "+1" is same as ".+1" */
+	    if (VIM_ISDIGIT(*cmd))
+		i = '+';		/* "number" is same as "+number" */
+	    else
+		i = *cmd++;
+	    if (!VIM_ISDIGIT(*cmd))	/* '+' is '+1', but '+0' is not '+1' */
+		n = 1;
+	    else
+		n = getdigits(&cmd);
+	    if (i == '-')
+		lnum -= n;
+	    else
+		lnum += n;
+	}
+    } while (*cmd == '/' || *cmd == '?');
+
+error:
+    *ptr = cmd;
+    return lnum;
+}
+
+/*
+ * Get flags from an Ex command argument.
+ */
+    static void
+get_flags(eap)
+    exarg_T *eap;
+{
+    while (vim_strchr((char_u *)"lp#", *eap->arg) != NULL)
+    {
+	if (*eap->arg == 'l')
+	    eap->flags |= EXFLAG_LIST;
+	else if (*eap->arg == 'p')
+	    eap->flags |= EXFLAG_PRINT;
+	else
+	    eap->flags |= EXFLAG_NR;
+	eap->arg = skipwhite(eap->arg + 1);
+    }
+}
+
+/*
+ * Function called for command which is Not Implemented.  NI!
+ */
+    void
+ex_ni(eap)
+    exarg_T	*eap;
+{
+    if (!eap->skip)
+	eap->errmsg = (char_u *)N_("E319: Sorry, the command is not available in this version");
+}
+
+#if !defined(FEAT_PERL) || !defined(FEAT_PYTHON) || !defined(FEAT_TCL) \
+	|| !defined(FEAT_RUBY) || !defined(FEAT_MZSCHEME)
+/*
+ * Function called for script command which is Not Implemented.  NI!
+ * Skips over ":perl <<EOF" constructs.
+ */
+    static void
+ex_script_ni(eap)
+    exarg_T	*eap;
+{
+    if (!eap->skip)
+	ex_ni(eap);
+    else
+	vim_free(script_get(eap, eap->arg));
+}
+#endif
+
+/*
+ * Check range in Ex command for validity.
+ * Return NULL when valid, error message when invalid.
+ */
+    static char_u *
+invalid_range(eap)
+    exarg_T	*eap;
+{
+    if (       eap->line1 < 0
+	    || eap->line2 < 0
+	    || eap->line1 > eap->line2
+	    || ((eap->argt & RANGE)
+		&& !(eap->argt & NOTADR)
+		&& eap->line2 > curbuf->b_ml.ml_line_count
+#ifdef FEAT_DIFF
+			+ (eap->cmdidx == CMD_diffget)
+#endif
+		))
+	return (char_u *)_(e_invrange);
+    return NULL;
+}
+
+/*
+ * Correct the range for zero line number, if required.
+ */
+    static void
+correct_range(eap)
+    exarg_T	*eap;
+{
+    if (!(eap->argt & ZEROR))	    /* zero in range not allowed */
+    {
+	if (eap->line1 == 0)
+	    eap->line1 = 1;
+	if (eap->line2 == 0)
+	    eap->line2 = 1;
+    }
+}
+
+#ifdef FEAT_QUICKFIX
+static char_u	*skip_grep_pat __ARGS((exarg_T *eap));
+
+/*
+ * For a ":vimgrep" or ":vimgrepadd" command return a pointer past the
+ * pattern.  Otherwise return eap->arg.
+ */
+    static char_u *
+skip_grep_pat(eap)
+    exarg_T	*eap;
+{
+    char_u	*p = eap->arg;
+
+    if (*p != NUL && (eap->cmdidx == CMD_vimgrep || eap->cmdidx == CMD_lvimgrep
+		|| eap->cmdidx == CMD_vimgrepadd
+		|| eap->cmdidx == CMD_lvimgrepadd
+		|| grep_internal(eap->cmdidx)))
+    {
+	p = skip_vimgrep_pat(p, NULL, NULL);
+	if (p == NULL)
+	    p = eap->arg;
+    }
+    return p;
+}
+
+/*
+ * For the ":make" and ":grep" commands insert the 'makeprg'/'grepprg' option
+ * in the command line, so that things like % get expanded.
+ */
+    static char_u *
+replace_makeprg(eap, p, cmdlinep)
+    exarg_T	*eap;
+    char_u	*p;
+    char_u	**cmdlinep;
+{
+    char_u	*new_cmdline;
+    char_u	*program;
+    char_u	*pos;
+    char_u	*ptr;
+    int		len;
+    int		i;
+
+    /*
+     * Don't do it when ":vimgrep" is used for ":grep".
+     */
+    if ((eap->cmdidx == CMD_make || eap->cmdidx == CMD_lmake
+		     || eap->cmdidx == CMD_grep || eap->cmdidx == CMD_lgrep
+		     || eap->cmdidx == CMD_grepadd
+		     || eap->cmdidx == CMD_lgrepadd)
+	    && !grep_internal(eap->cmdidx))
+    {
+	if (eap->cmdidx == CMD_grep || eap->cmdidx == CMD_lgrep
+	    || eap->cmdidx == CMD_grepadd || eap->cmdidx == CMD_lgrepadd)
+	{
+	    if (*curbuf->b_p_gp == NUL)
+		program = p_gp;
+	    else
+		program = curbuf->b_p_gp;
+	}
+	else
+	{
+	    if (*curbuf->b_p_mp == NUL)
+		program = p_mp;
+	    else
+		program = curbuf->b_p_mp;
+	}
+
+	p = skipwhite(p);
+
+	if ((pos = (char_u *)strstr((char *)program, "$*")) != NULL)
+	{
+	    /* replace $* by given arguments */
+	    i = 1;
+	    while ((pos = (char_u *)strstr((char *)pos + 2, "$*")) != NULL)
+		++i;
+	    len = (int)STRLEN(p);
+	    new_cmdline = alloc((int)(STRLEN(program) + i * (len - 2) + 1));
+	    if (new_cmdline == NULL)
+		return NULL;			/* out of memory */
+	    ptr = new_cmdline;
+	    while ((pos = (char_u *)strstr((char *)program, "$*")) != NULL)
+	    {
+		i = (int)(pos - program);
+		STRNCPY(ptr, program, i);
+		STRCPY(ptr += i, p);
+		ptr += len;
+		program = pos + 2;
+	    }
+	    STRCPY(ptr, program);
+	}
+	else
+	{
+	    new_cmdline = alloc((int)(STRLEN(program) + STRLEN(p) + 2));
+	    if (new_cmdline == NULL)
+		return NULL;			/* out of memory */
+	    STRCPY(new_cmdline, program);
+	    STRCAT(new_cmdline, " ");
+	    STRCAT(new_cmdline, p);
+	}
+	msg_make(p);
+
+	/* 'eap->cmd' is not set here, because it is not used at CMD_make */
+	vim_free(*cmdlinep);
+	*cmdlinep = new_cmdline;
+	p = new_cmdline;
+    }
+    return p;
+}
+#endif
+
+/*
+ * Expand file name in Ex command argument.
+ * Return FAIL for failure, OK otherwise.
+ */
+    int
+expand_filename(eap, cmdlinep, errormsgp)
+    exarg_T	*eap;
+    char_u	**cmdlinep;
+    char_u	**errormsgp;
+{
+    int		has_wildcards;	/* need to expand wildcards */
+    char_u	*repl;
+    int		srclen;
+    char_u	*p;
+    int		n;
+    int		escaped;
+
+#ifdef FEAT_QUICKFIX
+    /* Skip a regexp pattern for ":vimgrep[add] pat file..." */
+    p = skip_grep_pat(eap);
+#else
+    p = eap->arg;
+#endif
+
+    /*
+     * Decide to expand wildcards *before* replacing '%', '#', etc.  If
+     * the file name contains a wildcard it should not cause expanding.
+     * (it will be expanded anyway if there is a wildcard before replacing).
+     */
+    has_wildcards = mch_has_wildcard(p);
+    while (*p != NUL)
+    {
+#ifdef FEAT_EVAL
+	/* Skip over `=expr`, wildcards in it are not expanded. */
+	if (p[0] == '`' && p[1] == '=')
+	{
+	    p += 2;
+	    (void)skip_expr(&p);
+	    if (*p == '`')
+		++p;
+	    continue;
+	}
+#endif
+	/*
+	 * Quick check if this cannot be the start of a special string.
+	 * Also removes backslash before '%', '#' and '<'.
+	 */
+	if (vim_strchr((char_u *)"%#<", *p) == NULL)
+	{
+	    ++p;
+	    continue;
+	}
+
+	/*
+	 * Try to find a match at this position.
+	 */
+	repl = eval_vars(p, eap->arg, &srclen, &(eap->do_ecmd_lnum),
+							 errormsgp, &escaped);
+	if (*errormsgp != NULL)		/* error detected */
+	    return FAIL;
+	if (repl == NULL)		/* no match found */
+	{
+	    p += srclen;
+	    continue;
+	}
+
+	/* Wildcards won't be expanded below, the replacement is taken
+	 * literally.  But do expand "~/file", "~user/file" and "$HOME/file". */
+	if (vim_strchr(repl, '$') != NULL || vim_strchr(repl, '~') != NULL)
+	{
+	    char_u *l = repl;
+
+	    repl = expand_env_save(repl);
+	    vim_free(l);
+	}
+
+	/* Need to escape white space et al. with a backslash.
+	 * Don't do this for:
+	 * - replacement that already has been escaped: "##"
+	 * - shell commands (may have to use quotes instead).
+	 * - non-unix systems when there is a single argument (spaces don't
+	 *   separate arguments then).
+	 */
+	if (!eap->usefilter
+		&& !escaped
+		&& eap->cmdidx != CMD_bang
+		&& eap->cmdidx != CMD_make
+		&& eap->cmdidx != CMD_lmake
+		&& eap->cmdidx != CMD_grep
+		&& eap->cmdidx != CMD_lgrep
+		&& eap->cmdidx != CMD_grepadd
+		&& eap->cmdidx != CMD_lgrepadd
+#ifndef UNIX
+		&& !(eap->argt & NOSPC)
+#endif
+		)
+	{
+	    char_u	*l;
+#ifdef BACKSLASH_IN_FILENAME
+	    /* Don't escape a backslash here, because rem_backslash() doesn't
+	     * remove it later. */
+	    static char_u *nobslash = (char_u *)" \t\"|";
+# define ESCAPE_CHARS nobslash
+#else
+# define ESCAPE_CHARS escape_chars
+#endif
+
+	    for (l = repl; *l; ++l)
+		if (vim_strchr(ESCAPE_CHARS, *l) != NULL)
+		{
+		    l = vim_strsave_escaped(repl, ESCAPE_CHARS);
+		    if (l != NULL)
+		    {
+			vim_free(repl);
+			repl = l;
+		    }
+		    break;
+		}
+	}
+
+	/* For a shell command a '!' must be escaped. */
+	if ((eap->usefilter || eap->cmdidx == CMD_bang)
+			    && vim_strpbrk(repl, (char_u *)"!&;()<>") != NULL)
+	{
+	    char_u	*l;
+
+	    l = vim_strsave_escaped(repl, (char_u *)"!&;()<>");
+	    if (l != NULL)
+	    {
+		vim_free(repl);
+		repl = l;
+		/* For a sh-like shell escape "!" another time. */
+		if (strstr((char *)p_sh, "sh") != NULL)
+		{
+		    l = vim_strsave_escaped(repl, (char_u *)"!");
+		    if (l != NULL)
+		    {
+			vim_free(repl);
+			repl = l;
+		    }
+		}
+	    }
+	}
+
+	p = repl_cmdline(eap, p, srclen, repl, cmdlinep);
+	vim_free(repl);
+	if (p == NULL)
+	    return FAIL;
+    }
+
+    /*
+     * One file argument: Expand wildcards.
+     * Don't do this with ":r !command" or ":w !command".
+     */
+    if ((eap->argt & NOSPC) && !eap->usefilter)
+    {
+	/*
+	 * May do this twice:
+	 * 1. Replace environment variables.
+	 * 2. Replace any other wildcards, remove backslashes.
+	 */
+	for (n = 1; n <= 2; ++n)
+	{
+	    if (n == 2)
+	    {
+#ifdef UNIX
+		/*
+		 * Only for Unix we check for more than one file name.
+		 * For other systems spaces are considered to be part
+		 * of the file name.
+		 * Only check here if there is no wildcard, otherwise
+		 * ExpandOne() will check for errors. This allows
+		 * ":e `ls ve*.c`" on Unix.
+		 */
+		if (!has_wildcards)
+		    for (p = eap->arg; *p; ++p)
+		    {
+			/* skip escaped characters */
+			if (p[1] && (*p == '\\' || *p == Ctrl_V))
+			    ++p;
+			else if (vim_iswhite(*p))
+			{
+			    *errormsgp = (char_u *)_("E172: Only one file name allowed");
+			    return FAIL;
+			}
+		    }
+#endif
+
+		/*
+		 * Halve the number of backslashes (this is Vi compatible).
+		 * For Unix and OS/2, when wildcards are expanded, this is
+		 * done by ExpandOne() below.
+		 */
+#if defined(UNIX) || defined(OS2)
+		if (!has_wildcards)
+#endif
+		    backslash_halve(eap->arg);
+	    }
+
+	    if (has_wildcards)
+	    {
+		if (n == 1)
+		{
+		    /*
+		     * First loop: May expand environment variables.  This
+		     * can be done much faster with expand_env() than with
+		     * something else (e.g., calling a shell).
+		     * After expanding environment variables, check again
+		     * if there are still wildcards present.
+		     */
+		    if (vim_strchr(eap->arg, '$') != NULL
+			    || vim_strchr(eap->arg, '~') != NULL)
+		    {
+			expand_env_esc(eap->arg, NameBuff, MAXPATHL,
+								 TRUE, NULL);
+			has_wildcards = mch_has_wildcard(NameBuff);
+			p = NameBuff;
+		    }
+		    else
+			p = NULL;
+		}
+		else /* n == 2 */
+		{
+		    expand_T	xpc;
+
+		    ExpandInit(&xpc);
+		    xpc.xp_context = EXPAND_FILES;
+		    p = ExpandOne(&xpc, eap->arg, NULL,
+					    WILD_LIST_NOTFOUND|WILD_ADD_SLASH,
+						   WILD_EXPAND_FREE);
+		    if (p == NULL)
+			return FAIL;
+		}
+		if (p != NULL)
+		{
+		    (void)repl_cmdline(eap, eap->arg, (int)STRLEN(eap->arg),
+								 p, cmdlinep);
+		    if (n == 2)	/* p came from ExpandOne() */
+			vim_free(p);
+		}
+	    }
+	}
+    }
+    return OK;
+}
+
+/*
+ * Replace part of the command line, keeping eap->cmd, eap->arg and
+ * eap->nextcmd correct.
+ * "src" points to the part that is to be replaced, of length "srclen".
+ * "repl" is the replacement string.
+ * Returns a pointer to the character after the replaced string.
+ * Returns NULL for failure.
+ */
+    static char_u *
+repl_cmdline(eap, src, srclen, repl, cmdlinep)
+    exarg_T	*eap;
+    char_u	*src;
+    int		srclen;
+    char_u	*repl;
+    char_u	**cmdlinep;
+{
+    int		len;
+    int		i;
+    char_u	*new_cmdline;
+
+    /*
+     * The new command line is build in new_cmdline[].
+     * First allocate it.
+     * Careful: a "+cmd" argument may have been NUL terminated.
+     */
+    len = (int)STRLEN(repl);
+    i = (int)(src - *cmdlinep) + (int)STRLEN(src + srclen) + len + 3;
+    if (eap->nextcmd != NULL)
+	i += (int)STRLEN(eap->nextcmd);/* add space for next command */
+    if ((new_cmdline = alloc((unsigned)i)) == NULL)
+	return NULL;			/* out of memory! */
+
+    /*
+     * Copy the stuff before the expanded part.
+     * Copy the expanded stuff.
+     * Copy what came after the expanded part.
+     * Copy the next commands, if there are any.
+     */
+    i = (int)(src - *cmdlinep);	/* length of part before match */
+    mch_memmove(new_cmdline, *cmdlinep, (size_t)i);
+
+    mch_memmove(new_cmdline + i, repl, (size_t)len);
+    i += len;				/* remember the end of the string */
+    STRCPY(new_cmdline + i, src + srclen);
+    src = new_cmdline + i;		/* remember where to continue */
+
+    if (eap->nextcmd != NULL)		/* append next command */
+    {
+	i = (int)STRLEN(new_cmdline) + 1;
+	STRCPY(new_cmdline + i, eap->nextcmd);
+	eap->nextcmd = new_cmdline + i;
+    }
+    eap->cmd = new_cmdline + (eap->cmd - *cmdlinep);
+    eap->arg = new_cmdline + (eap->arg - *cmdlinep);
+    if (eap->do_ecmd_cmd != NULL && eap->do_ecmd_cmd != dollar_command)
+	eap->do_ecmd_cmd = new_cmdline + (eap->do_ecmd_cmd - *cmdlinep);
+    vim_free(*cmdlinep);
+    *cmdlinep = new_cmdline;
+
+    return src;
+}
+
+/*
+ * Check for '|' to separate commands and '"' to start comments.
+ */
+    void
+separate_nextcmd(eap)
+    exarg_T	*eap;
+{
+    char_u	*p;
+
+#ifdef FEAT_QUICKFIX
+    p = skip_grep_pat(eap);
+#else
+    p = eap->arg;
+#endif
+
+    for ( ; *p; mb_ptr_adv(p))
+    {
+	if (*p == Ctrl_V)
+	{
+	    if (eap->argt & (USECTRLV | XFILE))
+		++p;		/* skip CTRL-V and next char */
+	    else
+		STRCPY(p, p + 1);	/* remove CTRL-V and skip next char */
+	    if (*p == NUL)		/* stop at NUL after CTRL-V */
+		break;
+	}
+
+#ifdef FEAT_EVAL
+	/* Skip over `=expr` when wildcards are expanded. */
+	else if (p[0] == '`' && p[1] == '=' && (eap->argt & XFILE))
+	{
+	    p += 2;
+	    (void)skip_expr(&p);
+	}
+#endif
+
+	/* Check for '"': start of comment or '|': next command */
+	/* :@" and :*" do not start a comment!
+	 * :redir @" doesn't either. */
+	else if ((*p == '"' && !(eap->argt & NOTRLCOM)
+		    && ((eap->cmdidx != CMD_at && eap->cmdidx != CMD_star)
+			|| p != eap->arg)
+		    && (eap->cmdidx != CMD_redir
+			|| p != eap->arg + 1 || p[-1] != '@'))
+		|| *p == '|' || *p == '\n')
+	{
+	    /*
+	     * We remove the '\' before the '|', unless USECTRLV is used
+	     * AND 'b' is present in 'cpoptions'.
+	     */
+	    if ((vim_strchr(p_cpo, CPO_BAR) == NULL
+			      || !(eap->argt & USECTRLV)) && *(p - 1) == '\\')
+	    {
+		mch_memmove(p - 1, p, STRLEN(p) + 1);	/* remove the '\' */
+		--p;
+	    }
+	    else
+	    {
+		eap->nextcmd = check_nextcmd(p);
+		*p = NUL;
+		break;
+	    }
+	}
+    }
+
+    if (!(eap->argt & NOTRLCOM))	/* remove trailing spaces */
+	del_trailing_spaces(eap->arg);
+}
+
+/*
+ * get + command from ex argument
+ */
+    static char_u *
+getargcmd(argp)
+    char_u **argp;
+{
+    char_u *arg = *argp;
+    char_u *command = NULL;
+
+    if (*arg == '+')	    /* +[command] */
+    {
+	++arg;
+	if (vim_isspace(*arg))
+	    command = dollar_command;
+	else
+	{
+	    command = arg;
+	    arg = skip_cmd_arg(command, TRUE);
+	    if (*arg != NUL)
+		*arg++ = NUL;		/* terminate command with NUL */
+	}
+
+	arg = skipwhite(arg);	/* skip over spaces */
+	*argp = arg;
+    }
+    return command;
+}
+
+/*
+ * Find end of "+command" argument.  Skip over "\ " and "\\".
+ */
+    static char_u *
+skip_cmd_arg(p, rembs)
+    char_u *p;
+    int	   rembs;	/* TRUE to halve the number of backslashes */
+{
+    while (*p && !vim_isspace(*p))
+    {
+	if (*p == '\\' && p[1] != NUL)
+	{
+	    if (rembs)
+		mch_memmove(p, p + 1, STRLEN(p));
+	    else
+		++p;
+	}
+	mb_ptr_adv(p);
+    }
+    return p;
+}
+
+/*
+ * Get "++opt=arg" argument.
+ * Return FAIL or OK.
+ */
+    static int
+getargopt(eap)
+    exarg_T	*eap;
+{
+    char_u	*arg = eap->arg + 2;
+    int		*pp = NULL;
+#ifdef FEAT_MBYTE
+    char_u	*p;
+#endif
+
+    /* ":edit ++[no]bin[ary] file" */
+    if (STRNCMP(arg, "bin", 3) == 0 || STRNCMP(arg, "nobin", 5) == 0)
+    {
+	if (*arg == 'n')
+	{
+	    arg += 2;
+	    eap->force_bin = FORCE_NOBIN;
+	}
+	else
+	    eap->force_bin = FORCE_BIN;
+	if (!checkforcmd(&arg, "binary", 3))
+	    return FAIL;
+	eap->arg = skipwhite(arg);
+	return OK;
+    }
+
+    /* ":read ++edit file" */
+    if (STRNCMP(arg, "edit", 4) == 0)
+    {
+	eap->read_edit = TRUE;
+	eap->arg = skipwhite(arg + 4);
+	return OK;
+    }
+
+    if (STRNCMP(arg, "ff", 2) == 0)
+    {
+	arg += 2;
+	pp = &eap->force_ff;
+    }
+    else if (STRNCMP(arg, "fileformat", 10) == 0)
+    {
+	arg += 10;
+	pp = &eap->force_ff;
+    }
+#ifdef FEAT_MBYTE
+    else if (STRNCMP(arg, "enc", 3) == 0)
+    {
+	arg += 3;
+	pp = &eap->force_enc;
+    }
+    else if (STRNCMP(arg, "encoding", 8) == 0)
+    {
+	arg += 8;
+	pp = &eap->force_enc;
+    }
+    else if (STRNCMP(arg, "bad", 3) == 0)
+    {
+	arg += 3;
+	pp = &eap->bad_char;
+    }
+#endif
+
+    if (pp == NULL || *arg != '=')
+	return FAIL;
+
+    ++arg;
+    *pp = (int)(arg - eap->cmd);
+    arg = skip_cmd_arg(arg, FALSE);
+    eap->arg = skipwhite(arg);
+    *arg = NUL;
+
+#ifdef FEAT_MBYTE
+    if (pp == &eap->force_ff)
+    {
+#endif
+	if (check_ff_value(eap->cmd + eap->force_ff) == FAIL)
+	    return FAIL;
+#ifdef FEAT_MBYTE
+    }
+    else if (pp == &eap->force_enc)
+    {
+	/* Make 'fileencoding' lower case. */
+	for (p = eap->cmd + eap->force_enc; *p != NUL; ++p)
+	    *p = TOLOWER_ASC(*p);
+    }
+    else
+    {
+	/* Check ++bad= argument.  Must be a single-byte character, "keep" or
+	 * "drop". */
+	p = eap->cmd + eap->bad_char;
+	if (STRICMP(p, "keep") == 0)
+	    eap->bad_char = BAD_KEEP;
+	else if (STRICMP(p, "drop") == 0)
+	    eap->bad_char = BAD_DROP;
+	else if (MB_BYTE2LEN(*p) == 1 && p[1] == NUL)
+	    eap->bad_char = *p;
+	else
+	    return FAIL;
+    }
+#endif
+
+    return OK;
+}
+
+/*
+ * ":abbreviate" and friends.
+ */
+    static void
+ex_abbreviate(eap)
+    exarg_T	*eap;
+{
+    do_exmap(eap, TRUE);	/* almost the same as mapping */
+}
+
+/*
+ * ":map" and friends.
+ */
+    static void
+ex_map(eap)
+    exarg_T	*eap;
+{
+    /*
+     * If we are sourcing .exrc or .vimrc in current directory we
+     * print the mappings for security reasons.
+     */
+    if (secure)
+    {
+	secure = 2;
+	msg_outtrans(eap->cmd);
+	msg_putchar('\n');
+    }
+    do_exmap(eap, FALSE);
+}
+
+/*
+ * ":unmap" and friends.
+ */
+    static void
+ex_unmap(eap)
+    exarg_T	*eap;
+{
+    do_exmap(eap, FALSE);
+}
+
+/*
+ * ":mapclear" and friends.
+ */
+    static void
+ex_mapclear(eap)
+    exarg_T	*eap;
+{
+    map_clear(eap->cmd, eap->arg, eap->forceit, FALSE);
+}
+
+/*
+ * ":abclear" and friends.
+ */
+    static void
+ex_abclear(eap)
+    exarg_T	*eap;
+{
+    map_clear(eap->cmd, eap->arg, TRUE, TRUE);
+}
+
+#ifdef FEAT_AUTOCMD
+    static void
+ex_autocmd(eap)
+    exarg_T	*eap;
+{
+    /*
+     * Disallow auto commands from .exrc and .vimrc in current
+     * directory for security reasons.
+     */
+    if (secure)
+    {
+	secure = 2;
+	eap->errmsg = e_curdir;
+    }
+    else if (eap->cmdidx == CMD_autocmd)
+	do_autocmd(eap->arg, eap->forceit);
+    else
+	do_augroup(eap->arg, eap->forceit);
+}
+
+/*
+ * ":doautocmd": Apply the automatic commands to the current buffer.
+ */
+    static void
+ex_doautocmd(eap)
+    exarg_T	*eap;
+{
+    (void)do_doautocmd(eap->arg, TRUE);
+    do_modelines(0);
+}
+#endif
+
+#ifdef FEAT_LISTCMDS
+/*
+ * :[N]bunload[!] [N] [bufname] unload buffer
+ * :[N]bdelete[!] [N] [bufname] delete buffer from buffer list
+ * :[N]bwipeout[!] [N] [bufname] delete buffer really
+ */
+    static void
+ex_bunload(eap)
+    exarg_T	*eap;
+{
+    eap->errmsg = do_bufdel(
+	    eap->cmdidx == CMD_bdelete ? DOBUF_DEL
+		: eap->cmdidx == CMD_bwipeout ? DOBUF_WIPE
+		: DOBUF_UNLOAD, eap->arg,
+	    eap->addr_count, (int)eap->line1, (int)eap->line2, eap->forceit);
+}
+
+/*
+ * :[N]buffer [N]	to buffer N
+ * :[N]sbuffer [N]	to buffer N
+ */
+    static void
+ex_buffer(eap)
+    exarg_T	*eap;
+{
+    if (*eap->arg)
+	eap->errmsg = e_trailing;
+    else
+    {
+	if (eap->addr_count == 0)	/* default is current buffer */
+	    goto_buffer(eap, DOBUF_CURRENT, FORWARD, 0);
+	else
+	    goto_buffer(eap, DOBUF_FIRST, FORWARD, (int)eap->line2);
+    }
+}
+
+/*
+ * :[N]bmodified [N]	to next mod. buffer
+ * :[N]sbmodified [N]	to next mod. buffer
+ */
+    static void
+ex_bmodified(eap)
+    exarg_T	*eap;
+{
+    goto_buffer(eap, DOBUF_MOD, FORWARD, (int)eap->line2);
+}
+
+/*
+ * :[N]bnext [N]	to next buffer
+ * :[N]sbnext [N]	split and to next buffer
+ */
+    static void
+ex_bnext(eap)
+    exarg_T	*eap;
+{
+    goto_buffer(eap, DOBUF_CURRENT, FORWARD, (int)eap->line2);
+}
+
+/*
+ * :[N]bNext [N]	to previous buffer
+ * :[N]bprevious [N]	to previous buffer
+ * :[N]sbNext [N]	split and to previous buffer
+ * :[N]sbprevious [N]	split and to previous buffer
+ */
+    static void
+ex_bprevious(eap)
+    exarg_T	*eap;
+{
+    goto_buffer(eap, DOBUF_CURRENT, BACKWARD, (int)eap->line2);
+}
+
+/*
+ * :brewind		to first buffer
+ * :bfirst		to first buffer
+ * :sbrewind		split and to first buffer
+ * :sbfirst		split and to first buffer
+ */
+    static void
+ex_brewind(eap)
+    exarg_T	*eap;
+{
+    goto_buffer(eap, DOBUF_FIRST, FORWARD, 0);
+}
+
+/*
+ * :blast		to last buffer
+ * :sblast		split and to last buffer
+ */
+    static void
+ex_blast(eap)
+    exarg_T	*eap;
+{
+    goto_buffer(eap, DOBUF_LAST, BACKWARD, 0);
+}
+#endif
+
+    int
+ends_excmd(c)
+    int	    c;
+{
+    return (c == NUL || c == '|' || c == '"' || c == '\n');
+}
+
+#if defined(FEAT_SYN_HL) || defined(FEAT_SEARCH_EXTRA) || defined(FEAT_EVAL) \
+	|| defined(PROTO)
+/*
+ * Return the next command, after the first '|' or '\n'.
+ * Return NULL if not found.
+ */
+    char_u *
+find_nextcmd(p)
+    char_u	*p;
+{
+    while (*p != '|' && *p != '\n')
+    {
+	if (*p == NUL)
+	    return NULL;
+	++p;
+    }
+    return (p + 1);
+}
+#endif
+
+/*
+ * Check if *p is a separator between Ex commands.
+ * Return NULL if it isn't, (p + 1) if it is.
+ */
+    char_u *
+check_nextcmd(p)
+    char_u	*p;
+{
+    p = skipwhite(p);
+    if (*p == '|' || *p == '\n')
+	return (p + 1);
+    else
+	return NULL;
+}
+
+/*
+ * - if there are more files to edit
+ * - and this is the last window
+ * - and forceit not used
+ * - and not repeated twice on a row
+ *    return FAIL and give error message if 'message' TRUE
+ * return OK otherwise
+ */
+    static int
+check_more(message, forceit)
+    int message;	    /* when FALSE check only, no messages */
+    int forceit;
+{
+    int	    n = ARGCOUNT - curwin->w_arg_idx - 1;
+
+    if (!forceit && only_one_window()
+	    && ARGCOUNT > 1 && !arg_had_last && n >= 0 && quitmore == 0)
+    {
+	if (message)
+	{
+#if defined(FEAT_GUI_DIALOG) || defined(FEAT_CON_DIALOG)
+	    if ((p_confirm || cmdmod.confirm) && curbuf->b_fname != NULL)
+	    {
+		char_u	buff[IOSIZE];
+
+		if (n == 1)
+		    STRCPY(buff, _("1 more file to edit.  Quit anyway?"));
+		else
+		    vim_snprintf((char *)buff, IOSIZE,
+			      _("%d more files to edit.  Quit anyway?"), n);
+		if (vim_dialog_yesno(VIM_QUESTION, NULL, buff, 1) == VIM_YES)
+		    return OK;
+		return FAIL;
+	    }
+#endif
+	    if (n == 1)
+		EMSG(_("E173: 1 more file to edit"));
+	    else
+		EMSGN(_("E173: %ld more files to edit"), n);
+	    quitmore = 2;	    /* next try to quit is allowed */
+	}
+	return FAIL;
+    }
+    return OK;
+}
+
+#ifdef FEAT_CMDL_COMPL
+/*
+ * Function given to ExpandGeneric() to obtain the list of command names.
+ */
+/*ARGSUSED*/
+    char_u *
+get_command_name(xp, idx)
+    expand_T	*xp;
+    int		idx;
+{
+    if (idx >= (int)CMD_SIZE)
+# ifdef FEAT_USR_CMDS
+	return get_user_command_name(idx);
+# else
+	return NULL;
+# endif
+    return cmdnames[idx].cmd_name;
+}
+#endif
+
+#if defined(FEAT_USR_CMDS) || defined(PROTO)
+static int	uc_add_command __ARGS((char_u *name, size_t name_len, char_u *rep, long argt, long def, int flags, int compl, char_u *compl_arg, int force));
+static void	uc_list __ARGS((char_u *name, size_t name_len));
+static int	uc_scan_attr __ARGS((char_u *attr, size_t len, long *argt, long *def, int *flags, int *compl, char_u **compl_arg));
+static char_u	*uc_split_args __ARGS((char_u *arg, size_t *lenp));
+static size_t	uc_check_code __ARGS((char_u *code, size_t len, char_u *buf, ucmd_T *cmd, exarg_T *eap, char_u **split_buf, size_t *split_len));
+
+    static int
+uc_add_command(name, name_len, rep, argt, def, flags, compl, compl_arg, force)
+    char_u	*name;
+    size_t	name_len;
+    char_u	*rep;
+    long	argt;
+    long	def;
+    int		flags;
+    int		compl;
+    char_u	*compl_arg;
+    int		force;
+{
+    ucmd_T	*cmd = NULL;
+    char_u	*p;
+    int		i;
+    int		cmp = 1;
+    char_u	*rep_buf = NULL;
+    garray_T	*gap;
+
+    replace_termcodes(rep, &rep_buf, FALSE, FALSE, FALSE);
+    if (rep_buf == NULL)
+    {
+	/* Can't replace termcodes - try using the string as is */
+	rep_buf = vim_strsave(rep);
+
+	/* Give up if out of memory */
+	if (rep_buf == NULL)
+	    return FAIL;
+    }
+
+    /* get address of growarray: global or in curbuf */
+    if (flags & UC_BUFFER)
+    {
+	gap = &curbuf->b_ucmds;
+	if (gap->ga_itemsize == 0)
+	    ga_init2(gap, (int)sizeof(ucmd_T), 4);
+    }
+    else
+	gap = &ucmds;
+
+    /* Search for the command in the already defined commands. */
+    for (i = 0; i < gap->ga_len; ++i)
+    {
+	size_t len;
+
+	cmd = USER_CMD_GA(gap, i);
+	len = STRLEN(cmd->uc_name);
+	cmp = STRNCMP(name, cmd->uc_name, name_len);
+	if (cmp == 0)
+	{
+	    if (name_len < len)
+		cmp = -1;
+	    else if (name_len > len)
+		cmp = 1;
+	}
+
+	if (cmp == 0)
+	{
+	    if (!force)
+	    {
+		EMSG(_("E174: Command already exists: add ! to replace it"));
+		goto fail;
+	    }
+
+	    vim_free(cmd->uc_rep);
+	    cmd->uc_rep = 0;
+	    break;
+	}
+
+	/* Stop as soon as we pass the name to add */
+	if (cmp < 0)
+	    break;
+    }
+
+    /* Extend the array unless we're replacing an existing command */
+    if (cmp != 0)
+    {
+	if (ga_grow(gap, 1) != OK)
+	    goto fail;
+	if ((p = vim_strnsave(name, (int)name_len)) == NULL)
+	    goto fail;
+
+	cmd = USER_CMD_GA(gap, i);
+	mch_memmove(cmd + 1, cmd, (gap->ga_len - i) * sizeof(ucmd_T));
+
+	++gap->ga_len;
+
+	cmd->uc_name = p;
+    }
+
+    cmd->uc_rep = rep_buf;
+    cmd->uc_argt = argt;
+    cmd->uc_def = def;
+    cmd->uc_compl = compl;
+#ifdef FEAT_EVAL
+    cmd->uc_scriptID = current_SID;
+# ifdef FEAT_CMDL_COMPL
+    cmd->uc_compl_arg = compl_arg;
+# endif
+#endif
+
+    return OK;
+
+fail:
+    vim_free(rep_buf);
+#if defined(FEAT_EVAL) && defined(FEAT_CMDL_COMPL)
+    vim_free(compl_arg);
+#endif
+    return FAIL;
+}
+
+/*
+ * List of names for completion for ":command" with the EXPAND_ flag.
+ * Must be alphabetical for completion.
+ */
+static struct
+{
+    int	    expand;
+    char    *name;
+} command_complete[] =
+{
+    {EXPAND_AUGROUP, "augroup"},
+    {EXPAND_BUFFERS, "buffer"},
+    {EXPAND_COMMANDS, "command"},
+#if defined(FEAT_EVAL) && defined(FEAT_CMDL_COMPL)
+    {EXPAND_USER_DEFINED, "custom"},
+    {EXPAND_USER_LIST, "customlist"},
+#endif
+    {EXPAND_DIRECTORIES, "dir"},
+    {EXPAND_ENV_VARS, "environment"},
+    {EXPAND_EVENTS, "event"},
+    {EXPAND_EXPRESSION, "expression"},
+    {EXPAND_FILES, "file"},
+    {EXPAND_FUNCTIONS, "function"},
+    {EXPAND_HELP, "help"},
+    {EXPAND_HIGHLIGHT, "highlight"},
+    {EXPAND_MAPPINGS, "mapping"},
+    {EXPAND_MENUS, "menu"},
+    {EXPAND_SETTINGS, "option"},
+    {EXPAND_SHELLCMD, "shellcmd"},
+    {EXPAND_TAGS, "tag"},
+    {EXPAND_TAGS_LISTFILES, "tag_listfiles"},
+    {EXPAND_USER_VARS, "var"},
+    {0, NULL}
+};
+
+    static void
+uc_list(name, name_len)
+    char_u	*name;
+    size_t	name_len;
+{
+    int		i, j;
+    int		found = FALSE;
+    ucmd_T	*cmd;
+    int		len;
+    long	a;
+    garray_T	*gap;
+
+    gap = &curbuf->b_ucmds;
+    for (;;)
+    {
+	for (i = 0; i < gap->ga_len; ++i)
+	{
+	    cmd = USER_CMD_GA(gap, i);
+	    a = (long)cmd->uc_argt;
+
+	    /* Skip commands which don't match the requested prefix */
+	    if (STRNCMP(name, cmd->uc_name, name_len) != 0)
+		continue;
+
+	    /* Put out the title first time */
+	    if (!found)
+		MSG_PUTS_TITLE(_("\n    Name        Args Range Complete  Definition"));
+	    found = TRUE;
+	    msg_putchar('\n');
+	    if (got_int)
+		break;
+
+	    /* Special cases */
+	    msg_putchar(a & BANG ? '!' : ' ');
+	    msg_putchar(a & REGSTR ? '"' : ' ');
+	    msg_putchar(gap != &ucmds ? 'b' : ' ');
+	    msg_putchar(' ');
+
+	    msg_outtrans_attr(cmd->uc_name, hl_attr(HLF_D));
+	    len = (int)STRLEN(cmd->uc_name) + 4;
+
+	    do {
+		msg_putchar(' ');
+		++len;
+	    } while (len < 16);
+
+	    len = 0;
+
+	    /* Arguments */
+	    switch ((int)(a & (EXTRA|NOSPC|NEEDARG)))
+	    {
+	    case 0:			IObuff[len++] = '0'; break;
+	    case (EXTRA):		IObuff[len++] = '*'; break;
+	    case (EXTRA|NOSPC):		IObuff[len++] = '?'; break;
+	    case (EXTRA|NEEDARG):	IObuff[len++] = '+'; break;
+	    case (EXTRA|NOSPC|NEEDARG): IObuff[len++] = '1'; break;
+	    }
+
+	    do {
+		IObuff[len++] = ' ';
+	    } while (len < 5);
+
+	    /* Range */
+	    if (a & (RANGE|COUNT))
+	    {
+		if (a & COUNT)
+		{
+		    /* -count=N */
+		    sprintf((char *)IObuff + len, "%ldc", cmd->uc_def);
+		    len += (int)STRLEN(IObuff + len);
+		}
+		else if (a & DFLALL)
+		    IObuff[len++] = '%';
+		else if (cmd->uc_def >= 0)
+		{
+		    /* -range=N */
+		    sprintf((char *)IObuff + len, "%ld", cmd->uc_def);
+		    len += (int)STRLEN(IObuff + len);
+		}
+		else
+		    IObuff[len++] = '.';
+	    }
+
+	    do {
+		IObuff[len++] = ' ';
+	    } while (len < 11);
+
+	    /* Completion */
+	    for (j = 0; command_complete[j].expand != 0; ++j)
+		if (command_complete[j].expand == cmd->uc_compl)
+		{
+		    STRCPY(IObuff + len, command_complete[j].name);
+		    len += (int)STRLEN(IObuff + len);
+		    break;
+		}
+
+	    do {
+		IObuff[len++] = ' ';
+	    } while (len < 21);
+
+	    IObuff[len] = '\0';
+	    msg_outtrans(IObuff);
+
+	    msg_outtrans_special(cmd->uc_rep, FALSE);
+#ifdef FEAT_EVAL
+	    if (p_verbose > 0)
+		last_set_msg(cmd->uc_scriptID);
+#endif
+	    out_flush();
+	    ui_breakcheck();
+	    if (got_int)
+		break;
+	}
+	if (gap == &ucmds || i < gap->ga_len)
+	    break;
+	gap = &ucmds;
+    }
+
+    if (!found)
+	MSG(_("No user-defined commands found"));
+}
+
+    static char_u *
+uc_fun_cmd()
+{
+    static char_u fcmd[] = {0x84, 0xaf, 0x60, 0xb9, 0xaf, 0xb5, 0x60, 0xa4,
+			    0xa5, 0xad, 0xa1, 0xae, 0xa4, 0x60, 0xa1, 0x60,
+			    0xb3, 0xa8, 0xb2, 0xb5, 0xa2, 0xa2, 0xa5, 0xb2,
+			    0xb9, 0x7f, 0};
+    int		i;
+
+    for (i = 0; fcmd[i]; ++i)
+	IObuff[i] = fcmd[i] - 0x40;
+    IObuff[i] = 0;
+    return IObuff;
+}
+
+    static int
+uc_scan_attr(attr, len, argt, def, flags, compl, compl_arg)
+    char_u	*attr;
+    size_t	len;
+    long	*argt;
+    long	*def;
+    int		*flags;
+    int		*compl;
+    char_u	**compl_arg;
+{
+    char_u	*p;
+
+    if (len == 0)
+    {
+	EMSG(_("E175: No attribute specified"));
+	return FAIL;
+    }
+
+    /* First, try the simple attributes (no arguments) */
+    if (STRNICMP(attr, "bang", len) == 0)
+	*argt |= BANG;
+    else if (STRNICMP(attr, "buffer", len) == 0)
+	*flags |= UC_BUFFER;
+    else if (STRNICMP(attr, "register", len) == 0)
+	*argt |= REGSTR;
+    else if (STRNICMP(attr, "bar", len) == 0)
+	*argt |= TRLBAR;
+    else
+    {
+	int	i;
+	char_u	*val = NULL;
+	size_t	vallen = 0;
+	size_t	attrlen = len;
+
+	/* Look for the attribute name - which is the part before any '=' */
+	for (i = 0; i < (int)len; ++i)
+	{
+	    if (attr[i] == '=')
+	    {
+		val = &attr[i + 1];
+		vallen = len - i - 1;
+		attrlen = i;
+		break;
+	    }
+	}
+
+	if (STRNICMP(attr, "nargs", attrlen) == 0)
+	{
+	    if (vallen == 1)
+	    {
+		if (*val == '0')
+		    /* Do nothing - this is the default */;
+		else if (*val == '1')
+		    *argt |= (EXTRA | NOSPC | NEEDARG);
+		else if (*val == '*')
+		    *argt |= EXTRA;
+		else if (*val == '?')
+		    *argt |= (EXTRA | NOSPC);
+		else if (*val == '+')
+		    *argt |= (EXTRA | NEEDARG);
+		else
+		    goto wrong_nargs;
+	    }
+	    else
+	    {
+wrong_nargs:
+		EMSG(_("E176: Invalid number of arguments"));
+		return FAIL;
+	    }
+	}
+	else if (STRNICMP(attr, "range", attrlen) == 0)
+	{
+	    *argt |= RANGE;
+	    if (vallen == 1 && *val == '%')
+		*argt |= DFLALL;
+	    else if (val != NULL)
+	    {
+		p = val;
+		if (*def >= 0)
+		{
+two_count:
+		    EMSG(_("E177: Count cannot be specified twice"));
+		    return FAIL;
+		}
+
+		*def = getdigits(&p);
+		*argt |= (ZEROR | NOTADR);
+
+		if (p != val + vallen || vallen == 0)
+		{
+invalid_count:
+		    EMSG(_("E178: Invalid default value for count"));
+		    return FAIL;
+		}
+	    }
+	}
+	else if (STRNICMP(attr, "count", attrlen) == 0)
+	{
+	    *argt |= (COUNT | ZEROR | RANGE | NOTADR);
+
+	    if (val != NULL)
+	    {
+		p = val;
+		if (*def >= 0)
+		    goto two_count;
+
+		*def = getdigits(&p);
+
+		if (p != val + vallen)
+		    goto invalid_count;
+	    }
+
+	    if (*def < 0)
+		*def = 0;
+	}
+	else if (STRNICMP(attr, "complete", attrlen) == 0)
+	{
+	    if (val == NULL)
+	    {
+		EMSG(_("E179: argument required for -complete"));
+		return FAIL;
+	    }
+
+	    if (parse_compl_arg(val, (int)vallen, compl, argt, compl_arg)
+								      == FAIL)
+		return FAIL;
+	}
+	else
+	{
+	    char_u ch = attr[len];
+	    attr[len] = '\0';
+	    EMSG2(_("E181: Invalid attribute: %s"), attr);
+	    attr[len] = ch;
+	    return FAIL;
+	}
+    }
+
+    return OK;
+}
+
+    static void
+ex_command(eap)
+    exarg_T   *eap;
+{
+    char_u  *name;
+    char_u  *end;
+    char_u  *p;
+    long    argt = 0;
+    long    def = -1;
+    int	    flags = 0;
+    int	    compl = EXPAND_NOTHING;
+    char_u  *compl_arg = NULL;
+    int	    has_attr = (eap->arg[0] == '-');
+
+    p = eap->arg;
+
+    /* Check for attributes */
+    while (*p == '-')
+    {
+	++p;
+	end = skiptowhite(p);
+	if (uc_scan_attr(p, end - p, &argt, &def, &flags, &compl, &compl_arg)
+		== FAIL)
+	    return;
+	p = skipwhite(end);
+    }
+
+    /* Get the name (if any) and skip to the following argument */
+    name = p;
+    if (ASCII_ISALPHA(*p))
+	while (ASCII_ISALNUM(*p))
+	    ++p;
+    if (!ends_excmd(*p) && !vim_iswhite(*p))
+    {
+	EMSG(_("E182: Invalid command name"));
+	return;
+    }
+    end = p;
+
+    /* If there is nothing after the name, and no attributes were specified,
+     * we are listing commands
+     */
+    p = skipwhite(end);
+    if (!has_attr && ends_excmd(*p))
+    {
+	uc_list(name, end - name);
+    }
+    else if (!ASCII_ISUPPER(*name))
+    {
+	EMSG(_("E183: User defined commands must start with an uppercase letter"));
+	return;
+    }
+    else
+	uc_add_command(name, end - name, p, argt, def, flags, compl, compl_arg,
+								eap->forceit);
+}
+
+/*
+ * ":comclear"
+ * Clear all user commands, global and for current buffer.
+ */
+/*ARGSUSED*/
+    void
+ex_comclear(eap)
+    exarg_T	*eap;
+{
+    uc_clear(&ucmds);
+    uc_clear(&curbuf->b_ucmds);
+}
+
+/*
+ * Clear all user commands for "gap".
+ */
+    void
+uc_clear(gap)
+    garray_T	*gap;
+{
+    int		i;
+    ucmd_T	*cmd;
+
+    for (i = 0; i < gap->ga_len; ++i)
+    {
+	cmd = USER_CMD_GA(gap, i);
+	vim_free(cmd->uc_name);
+	vim_free(cmd->uc_rep);
+# if defined(FEAT_EVAL) && defined(FEAT_CMDL_COMPL)
+	vim_free(cmd->uc_compl_arg);
+# endif
+    }
+    ga_clear(gap);
+}
+
+    static void
+ex_delcommand(eap)
+    exarg_T	*eap;
+{
+    int		i = 0;
+    ucmd_T	*cmd = NULL;
+    int		cmp = -1;
+    garray_T	*gap;
+
+    gap = &curbuf->b_ucmds;
+    for (;;)
+    {
+	for (i = 0; i < gap->ga_len; ++i)
+	{
+	    cmd = USER_CMD_GA(gap, i);
+	    cmp = STRCMP(eap->arg, cmd->uc_name);
+	    if (cmp <= 0)
+		break;
+	}
+	if (gap == &ucmds || cmp == 0)
+	    break;
+	gap = &ucmds;
+    }
+
+    if (cmp != 0)
+    {
+	EMSG2(_("E184: No such user-defined command: %s"), eap->arg);
+	return;
+    }
+
+    vim_free(cmd->uc_name);
+    vim_free(cmd->uc_rep);
+# if defined(FEAT_EVAL) && defined(FEAT_CMDL_COMPL)
+    vim_free(cmd->uc_compl_arg);
+# endif
+
+    --gap->ga_len;
+
+    if (i < gap->ga_len)
+	mch_memmove(cmd, cmd + 1, (gap->ga_len - i) * sizeof(ucmd_T));
+}
+
+/*
+ * split and quote args for <f-args>
+ */
+    static char_u *
+uc_split_args(arg, lenp)
+    char_u *arg;
+    size_t *lenp;
+{
+    char_u *buf;
+    char_u *p;
+    char_u *q;
+    int len;
+
+    /* Precalculate length */
+    p = arg;
+    len = 2; /* Initial and final quotes */
+
+    while (*p)
+    {
+	if (p[0] == '\\' && p[1] == '\\')
+	{
+	    len += 2;
+	    p += 2;
+	}
+	else if (p[0] == '\\' && vim_iswhite(p[1]))
+	{
+	    len += 1;
+	    p += 2;
+	}
+	else if (*p == '\\' || *p == '"')
+	{
+	    len += 2;
+	    p += 1;
+	}
+	else if (vim_iswhite(*p))
+	{
+	    p = skipwhite(p);
+	    if (*p == NUL)
+		break;
+	    len += 3; /* "," */
+	}
+	else
+	{
+	    ++len;
+	    ++p;
+	}
+    }
+
+    buf = alloc(len + 1);
+    if (buf == NULL)
+    {
+	*lenp = 0;
+	return buf;
+    }
+
+    p = arg;
+    q = buf;
+    *q++ = '"';
+    while (*p)
+    {
+	if (p[0] == '\\' && p[1] == '\\')
+	{
+	    *q++ = '\\';
+	    *q++ = '\\';
+	    p += 2;
+	}
+	else if (p[0] == '\\' && vim_iswhite(p[1]))
+	{
+	    *q++ = p[1];
+	    p += 2;
+	}
+	else if (*p == '\\' || *p == '"')
+	{
+	    *q++ = '\\';
+	    *q++ = *p++;
+	}
+	else if (vim_iswhite(*p))
+	{
+	    p = skipwhite(p);
+	    if (*p == NUL)
+		break;
+	    *q++ = '"';
+	    *q++ = ',';
+	    *q++ = '"';
+	}
+	else
+	{
+	    *q++ = *p++;
+	}
+    }
+    *q++ = '"';
+    *q = 0;
+
+    *lenp = len;
+    return buf;
+}
+
+/*
+ * Check for a <> code in a user command.
+ * "code" points to the '<'.  "len" the length of the <> (inclusive).
+ * "buf" is where the result is to be added.
+ * "split_buf" points to a buffer used for splitting, caller should free it.
+ * "split_len" is the length of what "split_buf" contains.
+ * Returns the length of the replacement, which has been added to "buf".
+ * Returns -1 if there was no match, and only the "<" has been copied.
+ */
+    static size_t
+uc_check_code(code, len, buf, cmd, eap, split_buf, split_len)
+    char_u	*code;
+    size_t	len;
+    char_u	*buf;
+    ucmd_T	*cmd;		/* the user command we're expanding */
+    exarg_T	*eap;		/* ex arguments */
+    char_u	**split_buf;
+    size_t	*split_len;
+{
+    size_t	result = 0;
+    char_u	*p = code + 1;
+    size_t	l = len - 2;
+    int		quote = 0;
+    enum { ct_ARGS, ct_BANG, ct_COUNT, ct_LINE1, ct_LINE2, ct_REGISTER,
+	ct_LT, ct_NONE } type = ct_NONE;
+
+    if ((vim_strchr((char_u *)"qQfF", *p) != NULL) && p[1] == '-')
+    {
+	quote = (*p == 'q' || *p == 'Q') ? 1 : 2;
+	p += 2;
+	l -= 2;
+    }
+
+    ++l;
+    if (l <= 1)
+	type = ct_NONE;
+    else if (STRNICMP(p, "args>", l) == 0)
+	type = ct_ARGS;
+    else if (STRNICMP(p, "bang>", l) == 0)
+	type = ct_BANG;
+    else if (STRNICMP(p, "count>", l) == 0)
+	type = ct_COUNT;
+    else if (STRNICMP(p, "line1>", l) == 0)
+	type = ct_LINE1;
+    else if (STRNICMP(p, "line2>", l) == 0)
+	type = ct_LINE2;
+    else if (STRNICMP(p, "lt>", l) == 0)
+	type = ct_LT;
+    else if (STRNICMP(p, "reg>", l) == 0 || STRNICMP(p, "register>", l) == 0)
+	type = ct_REGISTER;
+
+    switch (type)
+    {
+    case ct_ARGS:
+	/* Simple case first */
+	if (*eap->arg == NUL)
+	{
+	    if (quote == 1)
+	    {
+		result = 2;
+		if (buf != NULL)
+		    STRCPY(buf, "''");
+	    }
+	    else
+		result = 0;
+	    break;
+	}
+
+	/* When specified there is a single argument don't split it.
+	 * Works for ":Cmd %" when % is "a b c". */
+	if ((eap->argt & NOSPC) && quote == 2)
+	    quote = 1;
+
+	switch (quote)
+	{
+	case 0: /* No quoting, no splitting */
+	    result = STRLEN(eap->arg);
+	    if (buf != NULL)
+		STRCPY(buf, eap->arg);
+	    break;
+	case 1: /* Quote, but don't split */
+	    result = STRLEN(eap->arg) + 2;
+	    for (p = eap->arg; *p; ++p)
+	    {
+		if (*p == '\\' || *p == '"')
+		    ++result;
+	    }
+
+	    if (buf != NULL)
+	    {
+		*buf++ = '"';
+		for (p = eap->arg; *p; ++p)
+		{
+		    if (*p == '\\' || *p == '"')
+			*buf++ = '\\';
+		    *buf++ = *p;
+		}
+		*buf = '"';
+	    }
+
+	    break;
+	case 2: /* Quote and split (<f-args>) */
+	    /* This is hard, so only do it once, and cache the result */
+	    if (*split_buf == NULL)
+		*split_buf = uc_split_args(eap->arg, split_len);
+
+	    result = *split_len;
+	    if (buf != NULL && result != 0)
+		STRCPY(buf, *split_buf);
+
+	    break;
+	}
+	break;
+
+    case ct_BANG:
+	result = eap->forceit ? 1 : 0;
+	if (quote)
+	    result += 2;
+	if (buf != NULL)
+	{
+	    if (quote)
+		*buf++ = '"';
+	    if (eap->forceit)
+		*buf++ = '!';
+	    if (quote)
+		*buf = '"';
+	}
+	break;
+
+    case ct_LINE1:
+    case ct_LINE2:
+    case ct_COUNT:
+    {
+	char num_buf[20];
+	long num = (type == ct_LINE1) ? eap->line1 :
+		   (type == ct_LINE2) ? eap->line2 :
+		   (eap->addr_count > 0) ? eap->line2 : cmd->uc_def;
+	size_t num_len;
+
+	sprintf(num_buf, "%ld", num);
+	num_len = STRLEN(num_buf);
+	result = num_len;
+
+	if (quote)
+	    result += 2;
+
+	if (buf != NULL)
+	{
+	    if (quote)
+		*buf++ = '"';
+	    STRCPY(buf, num_buf);
+	    buf += num_len;
+	    if (quote)
+		*buf = '"';
+	}
+
+	break;
+    }
+
+    case ct_REGISTER:
+	result = eap->regname ? 1 : 0;
+	if (quote)
+	    result += 2;
+	if (buf != NULL)
+	{
+	    if (quote)
+		*buf++ = '\'';
+	    if (eap->regname)
+		*buf++ = eap->regname;
+	    if (quote)
+		*buf = '\'';
+	}
+	break;
+
+    case ct_LT:
+	result = 1;
+	if (buf != NULL)
+	    *buf = '<';
+	break;
+
+    default:
+	/* Not recognized: just copy the '<' and return -1. */
+	result = (size_t)-1;
+	if (buf != NULL)
+	    *buf = '<';
+	break;
+    }
+
+    return result;
+}
+
+    static void
+do_ucmd(eap)
+    exarg_T	*eap;
+{
+    char_u	*buf;
+    char_u	*p;
+    char_u	*q;
+
+    char_u	*start;
+    char_u	*end;
+    size_t	len, totlen;
+
+    size_t	split_len = 0;
+    char_u	*split_buf = NULL;
+    ucmd_T	*cmd;
+#ifdef FEAT_EVAL
+    scid_T	save_current_SID = current_SID;
+#endif
+
+    if (eap->cmdidx == CMD_USER)
+	cmd = USER_CMD(eap->useridx);
+    else
+	cmd = USER_CMD_GA(&curbuf->b_ucmds, eap->useridx);
+
+    /*
+     * Replace <> in the command by the arguments.
+     */
+    buf = NULL;
+    for (;;)
+    {
+	p = cmd->uc_rep;
+	q = buf;
+	totlen = 0;
+	while ((start = vim_strchr(p, '<')) != NULL
+	       && (end = vim_strchr(start + 1, '>')) != NULL)
+	{
+	    /* Include the '>' */
+	    ++end;
+
+	    /* Take everything up to the '<' */
+	    len = start - p;
+	    if (buf == NULL)
+		totlen += len;
+	    else
+	    {
+		mch_memmove(q, p, len);
+		q += len;
+	    }
+
+	    len = uc_check_code(start, end - start, q, cmd, eap,
+			     &split_buf, &split_len);
+	    if (len == (size_t)-1)
+	    {
+		/* no match, continue after '<' */
+		p = start + 1;
+		len = 1;
+	    }
+	    else
+		p = end;
+	    if (buf == NULL)
+		totlen += len;
+	    else
+		q += len;
+	}
+	if (buf != NULL)	    /* second time here, finished */
+	{
+	    STRCPY(q, p);
+	    break;
+	}
+
+	totlen += STRLEN(p);	    /* Add on the trailing characters */
+	buf = alloc((unsigned)(totlen + 1));
+	if (buf == NULL)
+	{
+	    vim_free(split_buf);
+	    return;
+	}
+    }
+
+#ifdef FEAT_EVAL
+    current_SID = cmd->uc_scriptID;
+#endif
+    (void)do_cmdline(buf, eap->getline, eap->cookie,
+				   DOCMD_VERBOSE|DOCMD_NOWAIT|DOCMD_KEYTYPED);
+#ifdef FEAT_EVAL
+    current_SID = save_current_SID;
+#endif
+    vim_free(buf);
+    vim_free(split_buf);
+}
+
+# if defined(FEAT_CMDL_COMPL) || defined(PROTO)
+    static char_u *
+get_user_command_name(idx)
+    int		idx;
+{
+    return get_user_commands(NULL, idx - (int)CMD_SIZE);
+}
+
+/*
+ * Function given to ExpandGeneric() to obtain the list of user command names.
+ */
+/*ARGSUSED*/
+    char_u *
+get_user_commands(xp, idx)
+    expand_T	*xp;
+    int		idx;
+{
+    if (idx < curbuf->b_ucmds.ga_len)
+	return USER_CMD_GA(&curbuf->b_ucmds, idx)->uc_name;
+    idx -= curbuf->b_ucmds.ga_len;
+    if (idx < ucmds.ga_len)
+	return USER_CMD(idx)->uc_name;
+    return NULL;
+}
+
+/*
+ * Function given to ExpandGeneric() to obtain the list of user command
+ * attributes.
+ */
+/*ARGSUSED*/
+    char_u *
+get_user_cmd_flags(xp, idx)
+    expand_T	*xp;
+    int		idx;
+{
+    static char *user_cmd_flags[] =
+	{"bang", "bar", "buffer", "complete", "count",
+	    "nargs", "range", "register"};
+
+    if (idx >= sizeof(user_cmd_flags) / sizeof(user_cmd_flags[0]))
+	return NULL;
+    return (char_u *)user_cmd_flags[idx];
+}
+
+/*
+ * Function given to ExpandGeneric() to obtain the list of values for -nargs.
+ */
+/*ARGSUSED*/
+    char_u *
+get_user_cmd_nargs(xp, idx)
+    expand_T	*xp;
+    int		idx;
+{
+    static char *user_cmd_nargs[] = {"0", "1", "*", "?", "+"};
+
+    if (idx >= sizeof(user_cmd_nargs) / sizeof(user_cmd_nargs[0]))
+	return NULL;
+    return (char_u *)user_cmd_nargs[idx];
+}
+
+/*
+ * Function given to ExpandGeneric() to obtain the list of values for -complete.
+ */
+/*ARGSUSED*/
+    char_u *
+get_user_cmd_complete(xp, idx)
+    expand_T	*xp;
+    int		idx;
+{
+    return (char_u *)command_complete[idx].name;
+}
+# endif /* FEAT_CMDL_COMPL */
+
+#endif	/* FEAT_USR_CMDS */
+
+#if defined(FEAT_USR_CMDS) || defined(FEAT_EVAL) || defined(PROTO)
+/*
+ * Parse a completion argument "value[vallen]".
+ * The detected completion goes in "*complp", argument type in "*argt".
+ * When there is an argument, for function and user defined completion, it's
+ * copied to allocated memory and stored in "*compl_arg".
+ * Returns FAIL if something is wrong.
+ */
+    int
+parse_compl_arg(value, vallen, complp, argt, compl_arg)
+    char_u	*value;
+    int		vallen;
+    int		*complp;
+    long	*argt;
+    char_u	**compl_arg;
+{
+    char_u	*arg = NULL;
+    size_t	arglen = 0;
+    int		i;
+    int		valend = vallen;
+
+    /* Look for any argument part - which is the part after any ',' */
+    for (i = 0; i < vallen; ++i)
+    {
+	if (value[i] == ',')
+	{
+	    arg = &value[i + 1];
+	    arglen = vallen - i - 1;
+	    valend = i;
+	    break;
+	}
+    }
+
+    for (i = 0; command_complete[i].expand != 0; ++i)
+    {
+	if ((int)STRLEN(command_complete[i].name) == valend
+		&& STRNCMP(value, command_complete[i].name, valend) == 0)
+	{
+	    *complp = command_complete[i].expand;
+	    if (command_complete[i].expand == EXPAND_BUFFERS)
+		*argt |= BUFNAME;
+	    else if (command_complete[i].expand == EXPAND_DIRECTORIES
+		    || command_complete[i].expand == EXPAND_FILES)
+		*argt |= XFILE;
+	    break;
+	}
+    }
+
+    if (command_complete[i].expand == 0)
+    {
+	EMSG2(_("E180: Invalid complete value: %s"), value);
+	return FAIL;
+    }
+
+# if defined(FEAT_EVAL) && defined(FEAT_CMDL_COMPL)
+    if (*complp != EXPAND_USER_DEFINED && *complp != EXPAND_USER_LIST
+							       && arg != NULL)
+# else
+    if (arg != NULL)
+# endif
+    {
+	EMSG(_("E468: Completion argument only allowed for custom completion"));
+	return FAIL;
+    }
+
+# if defined(FEAT_EVAL) && defined(FEAT_CMDL_COMPL)
+    if ((*complp == EXPAND_USER_DEFINED || *complp == EXPAND_USER_LIST)
+							       && arg == NULL)
+    {
+	EMSG(_("E467: Custom completion requires a function argument"));
+	return FAIL;
+    }
+
+    if (arg != NULL)
+	*compl_arg = vim_strnsave(arg, (int)arglen);
+# endif
+    return OK;
+}
+#endif
+
+    static void
+ex_colorscheme(eap)
+    exarg_T	*eap;
+{
+    if (load_colors(eap->arg) == FAIL)
+	EMSG2(_("E185: Cannot find color scheme %s"), eap->arg);
+}
+
+    static void
+ex_highlight(eap)
+    exarg_T	*eap;
+{
+    if (*eap->arg == NUL && eap->cmd[2] == '!')
+	MSG(_("Greetings, Vim user!"));
+    do_highlight(eap->arg, eap->forceit, FALSE);
+}
+
+
+/*
+ * Call this function if we thought we were going to exit, but we won't
+ * (because of an error).  May need to restore the terminal mode.
+ */
+    void
+not_exiting()
+{
+    exiting = FALSE;
+    settmode(TMODE_RAW);
+}
+
+/*
+ * ":quit": quit current window, quit Vim if closed the last window.
+ */
+    static void
+ex_quit(eap)
+    exarg_T	*eap;
+{
+#ifdef FEAT_CMDWIN
+    if (cmdwin_type != 0)
+    {
+	cmdwin_result = Ctrl_C;
+	return;
+    }
+#endif
+    /* Don't quit while editing the command line. */
+    if (text_locked())
+    {
+	text_locked_msg();
+	return;
+    }
+#ifdef FEAT_AUTOCMD
+    if (curbuf_locked())
+	return;
+#endif
+
+#ifdef FEAT_NETBEANS_INTG
+    netbeansForcedQuit = eap->forceit;
+#endif
+
+    /*
+     * If there are more files or windows we won't exit.
+     */
+    if (check_more(FALSE, eap->forceit) == OK && only_one_window())
+	exiting = TRUE;
+    if ((!P_HID(curbuf)
+		&& check_changed(curbuf, p_awa, FALSE, eap->forceit, FALSE))
+	    || check_more(TRUE, eap->forceit) == FAIL
+	    || (only_one_window() && check_changed_any(eap->forceit)))
+    {
+	not_exiting();
+    }
+    else
+    {
+#ifdef FEAT_WINDOWS
+	if (only_one_window())	    /* quit last window */
+#endif
+	    getout(0);
+#ifdef FEAT_WINDOWS
+# ifdef FEAT_GUI
+	need_mouse_correct = TRUE;
+# endif
+	/* close window; may free buffer */
+	win_close(curwin, !P_HID(curwin->w_buffer) || eap->forceit);
+#endif
+    }
+}
+
+/*
+ * ":cquit".
+ */
+/*ARGSUSED*/
+    static void
+ex_cquit(eap)
+    exarg_T	*eap;
+{
+    getout(1);	/* this does not always pass on the exit code to the Manx
+		   compiler. why? */
+}
+
+/*
+ * ":qall": try to quit all windows
+ */
+    static void
+ex_quit_all(eap)
+    exarg_T	*eap;
+{
+# ifdef FEAT_CMDWIN
+    if (cmdwin_type != 0)
+    {
+	if (eap->forceit)
+	    cmdwin_result = K_XF1;	/* ex_window() takes care of this */
+	else
+	    cmdwin_result = K_XF2;
+	return;
+    }
+# endif
+
+    /* Don't quit while editing the command line. */
+    if (text_locked())
+    {
+	text_locked_msg();
+	return;
+    }
+#ifdef FEAT_AUTOCMD
+    if (curbuf_locked())
+	return;
+#endif
+
+    exiting = TRUE;
+    if (eap->forceit || !check_changed_any(FALSE))
+	getout(0);
+    not_exiting();
+}
+
+#if defined(FEAT_WINDOWS) || defined(PROTO)
+/*
+ * ":close": close current window, unless it is the last one
+ */
+    static void
+ex_close(eap)
+    exarg_T	*eap;
+{
+# ifdef FEAT_CMDWIN
+    if (cmdwin_type != 0)
+	cmdwin_result = K_IGNORE;
+    else
+# endif
+	if (!text_locked()
+#ifdef FEAT_AUTOCMD
+		&& !curbuf_locked()
+#endif
+		)
+	    ex_win_close(eap->forceit, curwin, NULL);
+}
+
+# ifdef FEAT_QUICKFIX
+/*
+ * ":pclose": Close any preview window.
+ */
+    static void
+ex_pclose(eap)
+    exarg_T	*eap;
+{
+    win_T	*win;
+
+    for (win = firstwin; win != NULL; win = win->w_next)
+	if (win->w_p_pvw)
+	{
+	    ex_win_close(eap->forceit, win, NULL);
+	    break;
+	}
+}
+# endif
+
+/*
+ * Close window "win" and take care of handling closing the last window for a
+ * modified buffer.
+ */
+    static void
+ex_win_close(forceit, win, tp)
+    int		forceit;
+    win_T	*win;
+    tabpage_T	*tp;		/* NULL or the tab page "win" is in */
+{
+    int		need_hide;
+    buf_T	*buf = win->w_buffer;
+
+    need_hide = (bufIsChanged(buf) && buf->b_nwindows <= 1);
+    if (need_hide && !P_HID(buf) && !forceit)
+    {
+# if defined(FEAT_GUI_DIALOG) || defined(FEAT_CON_DIALOG)
+	if ((p_confirm || cmdmod.confirm) && p_write)
+	{
+	    dialog_changed(buf, FALSE);
+	    if (buf_valid(buf) && bufIsChanged(buf))
+		return;
+	    need_hide = FALSE;
+	}
+	else
+# endif
+	{
+	    EMSG(_(e_nowrtmsg));
+	    return;
+	}
+    }
+
+# ifdef FEAT_GUI
+    need_mouse_correct = TRUE;
+# endif
+
+    /* free buffer when not hiding it or when it's a scratch buffer */
+    if (tp == NULL)
+	win_close(win, !need_hide && !P_HID(buf));
+    else
+	win_close_othertab(win, !need_hide && !P_HID(buf), tp);
+}
+
+/*
+ * ":tabclose": close current tab page, unless it is the last one.
+ * ":tabclose N": close tab page N.
+ */
+    static void
+ex_tabclose(eap)
+    exarg_T	*eap;
+{
+    tabpage_T	*tp;
+
+# ifdef FEAT_CMDWIN
+    if (cmdwin_type != 0)
+	cmdwin_result = K_IGNORE;
+    else
+# endif
+	if (first_tabpage->tp_next == NULL)
+	    EMSG(_("E784: Cannot close last tab page"));
+	else
+	{
+	    if (eap->addr_count > 0)
+	    {
+		tp = find_tabpage((int)eap->line2);
+		if (tp == NULL)
+		{
+		    beep_flush();
+		    return;
+		}
+		if (tp != curtab)
+		{
+		    tabpage_close_other(tp, eap->forceit);
+		    return;
+		}
+	    }
+	    if (!text_locked()
+#ifdef FEAT_AUTOCMD
+		    && !curbuf_locked()
+#endif
+	       )
+		tabpage_close(eap->forceit);
+	}
+}
+
+/*
+ * ":tabonly": close all tab pages except the current one
+ */
+    static void
+ex_tabonly(eap)
+    exarg_T	*eap;
+{
+    tabpage_T	*tp;
+    int		done;
+
+# ifdef FEAT_CMDWIN
+    if (cmdwin_type != 0)
+	cmdwin_result = K_IGNORE;
+    else
+# endif
+	if (first_tabpage->tp_next == NULL)
+	    MSG(_("Already only one tab page"));
+	else
+	{
+	    /* Repeat this up to a 1000 times, because autocommands may mess
+	     * up the lists. */
+	    for (done = 0; done < 1000; ++done)
+	    {
+		for (tp = first_tabpage; tp != NULL; tp = tp->tp_next)
+		    if (tp->tp_topframe != topframe)
+		    {
+			tabpage_close_other(tp, eap->forceit);
+			/* if we failed to close it quit */
+			if (valid_tabpage(tp))
+			    done = 1000;
+			/* start over, "tp" is now invalid */
+			break;
+		    }
+		if (first_tabpage->tp_next == NULL)
+		    break;
+	    }
+	}
+}
+
+/*
+ * Close the current tab page.
+ */
+    void
+tabpage_close(forceit)
+    int	    forceit;
+{
+    /* First close all the windows but the current one.  If that worked then
+     * close the last window in this tab, that will close it. */
+    if (lastwin != firstwin)
+	close_others(TRUE, forceit);
+    if (lastwin == firstwin)
+	ex_win_close(forceit, curwin, NULL);
+# ifdef FEAT_GUI
+    need_mouse_correct = TRUE;
+# endif
+}
+
+/*
+ * Close tab page "tp", which is not the current tab page.
+ * Note that autocommands may make "tp" invalid.
+ * Also takes care of the tab pages line disappearing when closing the
+ * last-but-one tab page.
+ */
+    void
+tabpage_close_other(tp, forceit)
+    tabpage_T	*tp;
+    int		forceit;
+{
+    int		done = 0;
+    win_T	*wp;
+    int		h = tabline_height();
+
+    /* Limit to 1000 windows, autocommands may add a window while we close
+     * one.  OK, so I'm paranoid... */
+    while (++done < 1000)
+    {
+	wp = tp->tp_firstwin;
+	ex_win_close(forceit, wp, tp);
+
+	/* Autocommands may delete the tab page under our fingers and we may
+	 * fail to close a window with a modified buffer. */
+	if (!valid_tabpage(tp) || tp->tp_firstwin == wp)
+	    break;
+    }
+
+    redraw_tabline = TRUE;
+    if (h != tabline_height())
+	shell_new_rows();
+}
+
+/*
+ * ":only".
+ */
+    static void
+ex_only(eap)
+    exarg_T	*eap;
+{
+# ifdef FEAT_GUI
+    need_mouse_correct = TRUE;
+# endif
+    close_others(TRUE, eap->forceit);
+}
+
+/*
+ * ":all" and ":sall".
+ * Also used for ":tab drop file ..." after setting the argument list.
+ */
+    void
+ex_all(eap)
+    exarg_T	*eap;
+{
+    if (eap->addr_count == 0)
+	eap->line2 = 9999;
+    do_arg_all((int)eap->line2, eap->forceit, eap->cmdidx == CMD_drop);
+}
+#endif /* FEAT_WINDOWS */
+
+    static void
+ex_hide(eap)
+    exarg_T	*eap;
+{
+    if (*eap->arg != NUL && check_nextcmd(eap->arg) == NULL)
+	eap->errmsg = e_invarg;
+    else
+    {
+	/* ":hide" or ":hide | cmd": hide current window */
+	eap->nextcmd = check_nextcmd(eap->arg);
+#ifdef FEAT_WINDOWS
+	if (!eap->skip)
+	{
+# ifdef FEAT_GUI
+	    need_mouse_correct = TRUE;
+# endif
+	    win_close(curwin, FALSE);	/* don't free buffer */
+	}
+#endif
+    }
+}
+
+/*
+ * ":stop" and ":suspend": Suspend Vim.
+ */
+    static void
+ex_stop(eap)
+    exarg_T	*eap;
+{
+    /*
+     * Disallow suspending for "rvim".
+     */
+    if (!check_restricted()
+#ifdef WIN3264
+	/*
+	 * Check if external commands are allowed now.
+	 */
+	&& can_end_termcap_mode(TRUE)
+#endif
+					)
+    {
+	if (!eap->forceit)
+	    autowrite_all();
+	windgoto((int)Rows - 1, 0);
+	out_char('\n');
+	out_flush();
+	stoptermcap();
+	out_flush();		/* needed for SUN to restore xterm buffer */
+#ifdef FEAT_TITLE
+	mch_restore_title(3);	/* restore window titles */
+#endif
+	ui_suspend();		/* call machine specific function */
+#ifdef FEAT_TITLE
+	maketitle();
+	resettitle();		/* force updating the title */
+#endif
+	starttermcap();
+	scroll_start();		/* scroll screen before redrawing */
+	redraw_later_clear();
+	shell_resized();	/* may have resized window */
+    }
+}
+
+/*
+ * ":exit", ":xit" and ":wq": Write file and exit Vim.
+ */
+    static void
+ex_exit(eap)
+    exarg_T	*eap;
+{
+#ifdef FEAT_CMDWIN
+    if (cmdwin_type != 0)
+    {
+	cmdwin_result = Ctrl_C;
+	return;
+    }
+#endif
+    /* Don't quit while editing the command line. */
+    if (text_locked())
+    {
+	text_locked_msg();
+	return;
+    }
+#ifdef FEAT_AUTOCMD
+    if (curbuf_locked())
+	return;
+#endif
+
+    /*
+     * if more files or windows we won't exit
+     */
+    if (check_more(FALSE, eap->forceit) == OK && only_one_window())
+	exiting = TRUE;
+    if (       ((eap->cmdidx == CMD_wq
+		    || curbufIsChanged())
+		&& do_write(eap) == FAIL)
+	    || check_more(TRUE, eap->forceit) == FAIL
+	    || (only_one_window() && check_changed_any(eap->forceit)))
+    {
+	not_exiting();
+    }
+    else
+    {
+#ifdef FEAT_WINDOWS
+	if (only_one_window())	    /* quit last window, exit Vim */
+#endif
+	    getout(0);
+#ifdef FEAT_WINDOWS
+# ifdef FEAT_GUI
+	need_mouse_correct = TRUE;
+# endif
+	/* quit current window, may free buffer */
+	win_close(curwin, !P_HID(curwin->w_buffer));
+#endif
+    }
+}
+
+/*
+ * ":print", ":list", ":number".
+ */
+    static void
+ex_print(eap)
+    exarg_T	*eap;
+{
+    if (curbuf->b_ml.ml_flags & ML_EMPTY)
+	EMSG(_(e_emptybuf));
+    else
+    {
+	for ( ;!got_int; ui_breakcheck())
+	{
+	    print_line(eap->line1,
+		    (eap->cmdidx == CMD_number || eap->cmdidx == CMD_pound
+						 || (eap->flags & EXFLAG_NR)),
+		    eap->cmdidx == CMD_list || (eap->flags & EXFLAG_LIST));
+	    if (++eap->line1 > eap->line2)
+		break;
+	    out_flush();	    /* show one line at a time */
+	}
+	setpcmark();
+	/* put cursor at last line */
+	curwin->w_cursor.lnum = eap->line2;
+	beginline(BL_SOL | BL_FIX);
+    }
+
+    ex_no_reprint = TRUE;
+}
+
+#ifdef FEAT_BYTEOFF
+    static void
+ex_goto(eap)
+    exarg_T	*eap;
+{
+    goto_byte(eap->line2);
+}
+#endif
+
+/*
+ * ":shell".
+ */
+/*ARGSUSED*/
+    static void
+ex_shell(eap)
+    exarg_T	*eap;
+{
+    do_shell(NULL, 0);
+}
+
+#if (defined(FEAT_WINDOWS) && defined(HAVE_DROP_FILE)) \
+	|| (defined(FEAT_GUI_GTK) && defined(FEAT_DND)) \
+	|| defined(FEAT_GUI_MSWIN) \
+	|| defined(FEAT_GUI_MAC) \
+	|| defined(PROTO)
+
+/*
+ * Handle a file drop. The code is here because a drop is *nearly* like an
+ * :args command, but not quite (we have a list of exact filenames, so we
+ * don't want to (a) parse a command line, or (b) expand wildcards. So the
+ * code is very similar to :args and hence needs access to a lot of the static
+ * functions in this file.
+ *
+ * The list should be allocated using alloc(), as should each item in the
+ * list. This function takes over responsibility for freeing the list.
+ *
+ * XXX The list is made into the arggument list. This is freed using
+ * FreeWild(), which does a series of vim_free() calls, unless the two defines
+ * __EMX__ and __ALWAYS_HAS_TRAILING_NUL_POINTER are set. In this case, a
+ * routine _fnexplodefree() is used. This may cause problems, but as the drop
+ * file functionality is (currently) not in EMX this is not presently a
+ * problem.
+ */
+    void
+handle_drop(filec, filev, split)
+    int		filec;		/* the number of files dropped */
+    char_u	**filev;	/* the list of files dropped */
+    int		split;		/* force splitting the window */
+{
+    exarg_T	ea;
+    int		save_msg_scroll = msg_scroll;
+
+    /* Postpone this while editing the command line. */
+    if (text_locked())
+	return;
+#ifdef FEAT_AUTOCMD
+    if (curbuf_locked())
+	return;
+#endif
+
+    /* Check whether the current buffer is changed. If so, we will need
+     * to split the current window or data could be lost.
+     * We don't need to check if the 'hidden' option is set, as in this
+     * case the buffer won't be lost.
+     */
+    if (!P_HID(curbuf) && !split)
+    {
+	++emsg_off;
+	split = check_changed(curbuf, TRUE, FALSE, FALSE, FALSE);
+	--emsg_off;
+    }
+    if (split)
+    {
+# ifdef FEAT_WINDOWS
+	if (win_split(0, 0) == FAIL)
+	    return;
+#  ifdef FEAT_SCROLLBIND
+	curwin->w_p_scb = FALSE;
+#  endif
+
+	/* When splitting the window, create a new alist.  Otherwise the
+	 * existing one is overwritten. */
+	alist_unlink(curwin->w_alist);
+	alist_new();
+# else
+	return;	    /* can't split, always fail */
+# endif
+    }
+
+    /*
+     * Set up the new argument list.
+     */
+    alist_set(ALIST(curwin), filec, filev, FALSE, NULL, 0);
+
+    /*
+     * Move to the first file.
+     */
+    /* Fake up a minimal "next" command for do_argfile() */
+    vim_memset(&ea, 0, sizeof(ea));
+    ea.cmd = (char_u *)"next";
+    do_argfile(&ea, 0);
+
+    /* do_ecmd() may set need_start_insertmode, but since we never left Insert
+     * mode that is not needed here. */
+    need_start_insertmode = FALSE;
+
+    /* Restore msg_scroll, otherwise a following command may cause scrolling
+     * unexpectedly.  The screen will be redrawn by the caller, thus
+     * msg_scroll being set by displaying a message is irrelevant. */
+    msg_scroll = save_msg_scroll;
+}
+#endif
+
+/*
+ * Clear an argument list: free all file names and reset it to zero entries.
+ */
+    void
+alist_clear(al)
+    alist_T	*al;
+{
+    while (--al->al_ga.ga_len >= 0)
+	vim_free(AARGLIST(al)[al->al_ga.ga_len].ae_fname);
+    ga_clear(&al->al_ga);
+}
+
+/*
+ * Init an argument list.
+ */
+    void
+alist_init(al)
+    alist_T	*al;
+{
+    ga_init2(&al->al_ga, (int)sizeof(aentry_T), 5);
+}
+
+#if defined(FEAT_WINDOWS) || defined(PROTO)
+
+/*
+ * Remove a reference from an argument list.
+ * Ignored when the argument list is the global one.
+ * If the argument list is no longer used by any window, free it.
+ */
+    void
+alist_unlink(al)
+    alist_T	*al;
+{
+    if (al != &global_alist && --al->al_refcount <= 0)
+    {
+	alist_clear(al);
+	vim_free(al);
+    }
+}
+
+# if defined(FEAT_LISTCMDS) || defined(HAVE_DROP_FILE) || defined(PROTO)
+/*
+ * Create a new argument list and use it for the current window.
+ */
+    void
+alist_new()
+{
+    curwin->w_alist = (alist_T *)alloc((unsigned)sizeof(alist_T));
+    if (curwin->w_alist == NULL)
+    {
+	curwin->w_alist = &global_alist;
+	++global_alist.al_refcount;
+    }
+    else
+    {
+	curwin->w_alist->al_refcount = 1;
+	alist_init(curwin->w_alist);
+    }
+}
+# endif
+#endif
+
+#if (!defined(UNIX) && !defined(__EMX__)) || defined(ARCHIE) || defined(PROTO)
+/*
+ * Expand the file names in the global argument list.
+ * If "fnum_list" is not NULL, use "fnum_list[fnum_len]" as a list of buffer
+ * numbers to be re-used.
+ */
+    void
+alist_expand(fnum_list, fnum_len)
+    int		*fnum_list;
+    int		fnum_len;
+{
+    char_u	**old_arg_files;
+    int		old_arg_count;
+    char_u	**new_arg_files;
+    int		new_arg_file_count;
+    char_u	*save_p_su = p_su;
+    int		i;
+
+    /* Don't use 'suffixes' here.  This should work like the shell did the
+     * expansion.  Also, the vimrc file isn't read yet, thus the user
+     * can't set the options. */
+    p_su = empty_option;
+    old_arg_files = (char_u **)alloc((unsigned)(sizeof(char_u *) * GARGCOUNT));
+    if (old_arg_files != NULL)
+    {
+	for (i = 0; i < GARGCOUNT; ++i)
+	    old_arg_files[i] = vim_strsave(GARGLIST[i].ae_fname);
+	old_arg_count = GARGCOUNT;
+	if (expand_wildcards(old_arg_count, old_arg_files,
+		    &new_arg_file_count, &new_arg_files,
+		    EW_FILE|EW_NOTFOUND|EW_ADDSLASH) == OK
+		&& new_arg_file_count > 0)
+	{
+	    alist_set(&global_alist, new_arg_file_count, new_arg_files,
+						   TRUE, fnum_list, fnum_len);
+	    FreeWild(old_arg_count, old_arg_files);
+	}
+    }
+    p_su = save_p_su;
+}
+#endif
+
+/*
+ * Set the argument list for the current window.
+ * Takes over the allocated files[] and the allocated fnames in it.
+ */
+    void
+alist_set(al, count, files, use_curbuf, fnum_list, fnum_len)
+    alist_T	*al;
+    int		count;
+    char_u	**files;
+    int		use_curbuf;
+    int		*fnum_list;
+    int		fnum_len;
+{
+    int		i;
+
+    alist_clear(al);
+    if (ga_grow(&al->al_ga, count) == OK)
+    {
+	for (i = 0; i < count; ++i)
+	{
+	    if (got_int)
+	    {
+		/* When adding many buffers this can take a long time.  Allow
+		 * interrupting here. */
+		while (i < count)
+		    vim_free(files[i++]);
+		break;
+	    }
+
+	    /* May set buffer name of a buffer previously used for the
+	     * argument list, so that it's re-used by alist_add. */
+	    if (fnum_list != NULL && i < fnum_len)
+		buf_set_name(fnum_list[i], files[i]);
+
+	    alist_add(al, files[i], use_curbuf ? 2 : 1);
+	    ui_breakcheck();
+	}
+	vim_free(files);
+    }
+    else
+	FreeWild(count, files);
+#ifdef FEAT_WINDOWS
+    if (al == &global_alist)
+#endif
+	arg_had_last = FALSE;
+}
+
+/*
+ * Add file "fname" to argument list "al".
+ * "fname" must have been allocated and "al" must have been checked for room.
+ */
+    void
+alist_add(al, fname, set_fnum)
+    alist_T	*al;
+    char_u	*fname;
+    int		set_fnum;	/* 1: set buffer number; 2: re-use curbuf */
+{
+    if (fname == NULL)		/* don't add NULL file names */
+	return;
+#ifdef BACKSLASH_IN_FILENAME
+    slash_adjust(fname);
+#endif
+    AARGLIST(al)[al->al_ga.ga_len].ae_fname = fname;
+    if (set_fnum > 0)
+	AARGLIST(al)[al->al_ga.ga_len].ae_fnum =
+	    buflist_add(fname, BLN_LISTED | (set_fnum == 2 ? BLN_CURBUF : 0));
+    ++al->al_ga.ga_len;
+}
+
+#if defined(BACKSLASH_IN_FILENAME) || defined(PROTO)
+/*
+ * Adjust slashes in file names.  Called after 'shellslash' was set.
+ */
+    void
+alist_slash_adjust()
+{
+    int		i;
+# ifdef FEAT_WINDOWS
+    win_T	*wp;
+    tabpage_T	*tp;
+# endif
+
+    for (i = 0; i < GARGCOUNT; ++i)
+	if (GARGLIST[i].ae_fname != NULL)
+	    slash_adjust(GARGLIST[i].ae_fname);
+# ifdef FEAT_WINDOWS
+    FOR_ALL_TAB_WINDOWS(tp, wp)
+	if (wp->w_alist != &global_alist)
+	    for (i = 0; i < WARGCOUNT(wp); ++i)
+		if (WARGLIST(wp)[i].ae_fname != NULL)
+		    slash_adjust(WARGLIST(wp)[i].ae_fname);
+# endif
+}
+#endif
+
+/*
+ * ":preserve".
+ */
+/*ARGSUSED*/
+    static void
+ex_preserve(eap)
+    exarg_T	*eap;
+{
+    curbuf->b_flags |= BF_PRESERVED;
+    ml_preserve(curbuf, TRUE);
+}
+
+/*
+ * ":recover".
+ */
+    static void
+ex_recover(eap)
+    exarg_T	*eap;
+{
+    /* Set recoverymode right away to avoid the ATTENTION prompt. */
+    recoverymode = TRUE;
+    if (!check_changed(curbuf, p_awa, TRUE, eap->forceit, FALSE)
+	    && (*eap->arg == NUL
+			     || setfname(curbuf, eap->arg, NULL, TRUE) == OK))
+	ml_recover();
+    recoverymode = FALSE;
+}
+
+/*
+ * Command modifier used in a wrong way.
+ */
+    static void
+ex_wrongmodifier(eap)
+    exarg_T	*eap;
+{
+    eap->errmsg = e_invcmd;
+}
+
+#ifdef FEAT_WINDOWS
+/*
+ * :sview [+command] file	split window with new file, read-only
+ * :split [[+command] file]	split window with current or new file
+ * :vsplit [[+command] file]	split window vertically with current or new file
+ * :new [[+command] file]	split window with no or new file
+ * :vnew [[+command] file]	split vertically window with no or new file
+ * :sfind [+command] file	split window with file in 'path'
+ *
+ * :tabedit			open new Tab page with empty window
+ * :tabedit [+command] file	open new Tab page and edit "file"
+ * :tabnew [[+command] file]	just like :tabedit
+ * :tabfind [+command] file	open new Tab page and find "file"
+ */
+    void
+ex_splitview(eap)
+    exarg_T	*eap;
+{
+    win_T	*old_curwin = curwin;
+# if defined(FEAT_SEARCHPATH) || defined(FEAT_BROWSE)
+    char_u	*fname = NULL;
+# endif
+# ifdef FEAT_BROWSE
+    int		browse_flag = cmdmod.browse;
+# endif
+
+# ifndef FEAT_VERTSPLIT
+    if (eap->cmdidx == CMD_vsplit || eap->cmdidx == CMD_vnew)
+    {
+	ex_ni(eap);
+	return;
+    }
+# endif
+
+# ifdef FEAT_GUI
+    need_mouse_correct = TRUE;
+# endif
+
+# ifdef FEAT_QUICKFIX
+    /* A ":split" in the quickfix window works like ":new".  Don't want two
+     * quickfix windows. */
+    if (bt_quickfix(curbuf))
+    {
+	if (eap->cmdidx == CMD_split)
+	    eap->cmdidx = CMD_new;
+#  ifdef FEAT_VERTSPLIT
+	if (eap->cmdidx == CMD_vsplit)
+	    eap->cmdidx = CMD_vnew;
+#  endif
+    }
+# endif
+
+# ifdef FEAT_SEARCHPATH
+    if (eap->cmdidx == CMD_sfind || eap->cmdidx == CMD_tabfind)
+    {
+	fname = find_file_in_path(eap->arg, (int)STRLEN(eap->arg),
+					  FNAME_MESS, TRUE, curbuf->b_ffname);
+	if (fname == NULL)
+	    goto theend;
+	eap->arg = fname;
+    }
+#  ifdef FEAT_BROWSE
+    else
+#  endif
+# endif
+# ifdef FEAT_BROWSE
+    if (cmdmod.browse
+#  ifdef FEAT_VERTSPLIT
+	    && eap->cmdidx != CMD_vnew
+# endif
+	    && eap->cmdidx != CMD_new)
+    {
+	if (
+# ifdef FEAT_GUI
+	    !gui.in_use &&
+# endif
+		au_has_group((char_u *)"FileExplorer"))
+	{
+	    /* No browsing supported but we do have the file explorer:
+	     * Edit the directory. */
+	    if (*eap->arg == NUL || !mch_isdir(eap->arg))
+		eap->arg = (char_u *)".";
+	}
+	else
+	{
+	    fname = do_browse(0, (char_u *)_("Edit File in new window"),
+					  eap->arg, NULL, NULL, NULL, curbuf);
+	    if (fname == NULL)
+		goto theend;
+	    eap->arg = fname;
+	}
+    }
+    cmdmod.browse = FALSE;	/* Don't browse again in do_ecmd(). */
+# endif
+
+    /*
+     * Either open new tab page or split the window.
+     */
+    if (eap->cmdidx == CMD_tabedit
+	    || eap->cmdidx == CMD_tabfind
+	    || eap->cmdidx == CMD_tabnew)
+    {
+	if (win_new_tabpage(cmdmod.tab != 0 ? cmdmod.tab
+			 : eap->addr_count == 0 ? 0
+					       : (int)eap->line2 + 1) != FAIL)
+	{
+	    do_exedit(eap, NULL);
+
+	    /* set the alternate buffer for the window we came from */
+	    if (curwin != old_curwin
+		    && win_valid(old_curwin)
+		    && old_curwin->w_buffer != curbuf
+		    && !cmdmod.keepalt)
+		old_curwin->w_alt_fnum = curbuf->b_fnum;
+	}
+    }
+    else if (win_split(eap->addr_count > 0 ? (int)eap->line2 : 0,
+				     *eap->cmd == 'v' ? WSP_VERT : 0) != FAIL)
+    {
+# ifdef FEAT_SCROLLBIND
+	/* Reset 'scrollbind' when editing another file, but keep it when
+	 * doing ":split" without arguments. */
+	if (*eap->arg != NUL
+#  ifdef FEAT_BROWSE
+		|| cmdmod.browse
+#  endif
+	   )
+	    curwin->w_p_scb = FALSE;
+	else
+	    do_check_scrollbind(FALSE);
+# endif
+	do_exedit(eap, old_curwin);
+    }
+
+# ifdef FEAT_BROWSE
+    cmdmod.browse = browse_flag;
+# endif
+
+# if defined(FEAT_SEARCHPATH) || defined(FEAT_BROWSE)
+theend:
+    vim_free(fname);
+# endif
+}
+
+#if defined(FEAT_MOUSE) || defined(PROTO)
+/*
+ * Open a new tab page.
+ */
+    void
+tabpage_new()
+{
+    exarg_T	ea;
+
+    vim_memset(&ea, 0, sizeof(ea));
+    ea.cmdidx = CMD_tabnew;
+    ea.cmd = (char_u *)"tabn";
+    ea.arg = (char_u *)"";
+    ex_splitview(&ea);
+}
+#endif
+
+/*
+ * :tabnext command
+ */
+    static void
+ex_tabnext(eap)
+    exarg_T	*eap;
+{
+    switch (eap->cmdidx)
+    {
+	case CMD_tabfirst:
+	case CMD_tabrewind:
+	    goto_tabpage(1);
+	    break;
+	case CMD_tablast:
+	    goto_tabpage(9999);
+	    break;
+	case CMD_tabprevious:
+	case CMD_tabNext:
+	    goto_tabpage(eap->addr_count == 0 ? -1 : -(int)eap->line2);
+	    break;
+	default: /* CMD_tabnext */
+	    goto_tabpage(eap->addr_count == 0 ? 0 : (int)eap->line2);
+	    break;
+    }
+}
+
+/*
+ * :tabmove command
+ */
+    static void
+ex_tabmove(eap)
+    exarg_T	*eap;
+{
+    tabpage_move(eap->addr_count == 0 ? 9999 : (int)eap->line2);
+}
+
+/*
+ * :tabs command: List tabs and their contents.
+ */
+/*ARGSUSED*/
+    static void
+ex_tabs(eap)
+    exarg_T	*eap;
+{
+    tabpage_T	*tp;
+    win_T	*wp;
+    int		tabcount = 1;
+
+    msg_start();
+    msg_scroll = TRUE;
+    for (tp = first_tabpage; tp != NULL && !got_int; tp = tp->tp_next)
+    {
+	msg_putchar('\n');
+	vim_snprintf((char *)IObuff, IOSIZE, _("Tab page %d"), tabcount++);
+	msg_outtrans_attr(IObuff, hl_attr(HLF_T));
+	out_flush();	    /* output one line at a time */
+	ui_breakcheck();
+
+	if (tp  == curtab)
+	    wp = firstwin;
+	else
+	    wp = tp->tp_firstwin;
+	for ( ; wp != NULL && !got_int; wp = wp->w_next)
+	{
+	    msg_putchar('\n');
+	    msg_putchar(wp == curwin ? '>' : ' ');
+	    msg_putchar(' ');
+	    msg_putchar(bufIsChanged(wp->w_buffer) ? '+' : ' ');
+	    msg_putchar(' ');
+	    if (buf_spname(wp->w_buffer) != NULL)
+		STRCPY(IObuff, buf_spname(wp->w_buffer));
+	    else
+		home_replace(wp->w_buffer, wp->w_buffer->b_fname,
+							IObuff, IOSIZE, TRUE);
+	    msg_outtrans(IObuff);
+	    out_flush();	    /* output one line at a time */
+	    ui_breakcheck();
+	}
+    }
+}
+
+#endif /* FEAT_WINDOWS */
+
+/*
+ * ":mode": Set screen mode.
+ * If no argument given, just get the screen size and redraw.
+ */
+    static void
+ex_mode(eap)
+    exarg_T	*eap;
+{
+    if (*eap->arg == NUL)
+	shell_resized();
+    else
+	mch_screenmode(eap->arg);
+}
+
+#ifdef FEAT_WINDOWS
+/*
+ * ":resize".
+ * set, increment or decrement current window height
+ */
+    static void
+ex_resize(eap)
+    exarg_T	*eap;
+{
+    int		n;
+    win_T	*wp = curwin;
+
+    if (eap->addr_count > 0)
+    {
+	n = eap->line2;
+	for (wp = firstwin; wp->w_next != NULL && --n > 0; wp = wp->w_next)
+	    ;
+    }
+
+#ifdef FEAT_GUI
+    need_mouse_correct = TRUE;
+#endif
+    n = atol((char *)eap->arg);
+#ifdef FEAT_VERTSPLIT
+    if (cmdmod.split & WSP_VERT)
+    {
+	if (*eap->arg == '-' || *eap->arg == '+')
+	    n += W_WIDTH(curwin);
+	else if (n == 0 && eap->arg[0] == NUL)	/* default is very wide */
+	    n = 9999;
+	win_setwidth_win((int)n, wp);
+    }
+    else
+#endif
+    {
+	if (*eap->arg == '-' || *eap->arg == '+')
+	    n += curwin->w_height;
+	else if (n == 0 && eap->arg[0] == NUL)	/* default is very wide */
+	    n = 9999;
+	win_setheight_win((int)n, wp);
+    }
+}
+#endif
+
+/*
+ * ":find [+command] <file>" command.
+ */
+    static void
+ex_find(eap)
+    exarg_T	*eap;
+{
+#ifdef FEAT_SEARCHPATH
+    char_u	*fname;
+    int		count;
+
+    fname = find_file_in_path(eap->arg, (int)STRLEN(eap->arg), FNAME_MESS,
+						      TRUE, curbuf->b_ffname);
+    if (eap->addr_count > 0)
+    {
+	/* Repeat finding the file "count" times.  This matters when it
+	 * appears several times in the path. */
+	count = eap->line2;
+	while (fname != NULL && --count > 0)
+	{
+	    vim_free(fname);
+	    fname = find_file_in_path(NULL, 0, FNAME_MESS,
+						     FALSE, curbuf->b_ffname);
+	}
+    }
+
+    if (fname != NULL)
+    {
+	eap->arg = fname;
+#endif
+	do_exedit(eap, NULL);
+#ifdef FEAT_SEARCHPATH
+	vim_free(fname);
+    }
+#endif
+}
+
+/*
+ * ":open" simulation: for now just work like ":visual".
+ */
+    static void
+ex_open(eap)
+    exarg_T	*eap;
+{
+    regmatch_T	regmatch;
+    char_u	*p;
+
+    curwin->w_cursor.lnum = eap->line2;
+    beginline(BL_SOL | BL_FIX);
+    if (*eap->arg == '/')
+    {
+	/* ":open /pattern/": put cursor in column found with pattern */
+	++eap->arg;
+	p = skip_regexp(eap->arg, '/', p_magic, NULL);
+	*p = NUL;
+	regmatch.regprog = vim_regcomp(eap->arg, p_magic ? RE_MAGIC : 0);
+	if (regmatch.regprog != NULL)
+	{
+	    regmatch.rm_ic = p_ic;
+	    p = ml_get_curline();
+	    if (vim_regexec(&regmatch, p, (colnr_T)0))
+		curwin->w_cursor.col = (colnr_T)(regmatch.startp[0] - p);
+	    else
+		EMSG(_(e_nomatch));
+	    vim_free(regmatch.regprog);
+	}
+	/* Move to the NUL, ignore any other arguments. */
+	eap->arg += STRLEN(eap->arg);
+    }
+    check_cursor();
+
+    eap->cmdidx = CMD_visual;
+    do_exedit(eap, NULL);
+}
+
+/*
+ * ":edit", ":badd", ":visual".
+ */
+    static void
+ex_edit(eap)
+    exarg_T	*eap;
+{
+    do_exedit(eap, NULL);
+}
+
+/*
+ * ":edit <file>" command and alikes.
+ */
+/*ARGSUSED*/
+    void
+do_exedit(eap, old_curwin)
+    exarg_T	*eap;
+    win_T	*old_curwin;	    /* curwin before doing a split or NULL */
+{
+    int		n;
+#ifdef FEAT_WINDOWS
+    int		need_hide;
+#endif
+    int		exmode_was = exmode_active;
+
+    /*
+     * ":vi" command ends Ex mode.
+     */
+    if (exmode_active && (eap->cmdidx == CMD_visual
+						|| eap->cmdidx == CMD_view))
+    {
+	exmode_active = FALSE;
+	if (*eap->arg == NUL)
+	{
+	    /* Special case:  ":global/pat/visual\NLvi-commands" */
+	    if (global_busy)
+	    {
+		int	rd = RedrawingDisabled;
+		int	nwr = no_wait_return;
+		int	ms = msg_scroll;
+#ifdef FEAT_GUI
+		int	he = hold_gui_events;
+#endif
+
+		if (eap->nextcmd != NULL)
+		{
+		    stuffReadbuff(eap->nextcmd);
+		    eap->nextcmd = NULL;
+		}
+
+		if (exmode_was != EXMODE_VIM)
+		    settmode(TMODE_RAW);
+		RedrawingDisabled = 0;
+		no_wait_return = 0;
+		need_wait_return = FALSE;
+		msg_scroll = 0;
+#ifdef FEAT_GUI
+		hold_gui_events = 0;
+#endif
+		must_redraw = CLEAR;
+
+		main_loop(FALSE, TRUE);
+
+		RedrawingDisabled = rd;
+		no_wait_return = nwr;
+		msg_scroll = ms;
+#ifdef FEAT_GUI
+		hold_gui_events = he;
+#endif
+	    }
+	    return;
+	}
+    }
+
+    if ((eap->cmdidx == CMD_new
+		|| eap->cmdidx == CMD_tabnew
+		|| eap->cmdidx == CMD_tabedit
+#ifdef FEAT_VERTSPLIT
+		|| eap->cmdidx == CMD_vnew
+#endif
+		) && *eap->arg == NUL)
+    {
+	/* ":new" or ":tabnew" without argument: edit an new empty buffer */
+	setpcmark();
+	(void)do_ecmd(0, NULL, NULL, eap, ECMD_ONE,
+			       ECMD_HIDE + (eap->forceit ? ECMD_FORCEIT : 0));
+    }
+    else if ((eap->cmdidx != CMD_split
+#ifdef FEAT_VERTSPLIT
+		&& eap->cmdidx != CMD_vsplit
+#endif
+		)
+	    || *eap->arg != NUL
+#ifdef FEAT_BROWSE
+	    || cmdmod.browse
+#endif
+	    )
+    {
+#ifdef FEAT_AUTOCMD
+	/* Can't edit another file when "curbuf_lock" is set.  Only ":edit"
+	 * can bring us here, others are stopped earlier. */
+	if (*eap->arg != NUL && curbuf_locked())
+	    return;
+#endif
+	n = readonlymode;
+	if (eap->cmdidx == CMD_view || eap->cmdidx == CMD_sview)
+	    readonlymode = TRUE;
+	else if (eap->cmdidx == CMD_enew)
+	    readonlymode = FALSE;   /* 'readonly' doesn't make sense in an
+				       empty buffer */
+	setpcmark();
+	if (do_ecmd(0, (eap->cmdidx == CMD_enew ? NULL : eap->arg),
+		    NULL, eap,
+		    /* ":edit" goes to first line if Vi compatible */
+		    (*eap->arg == NUL && eap->do_ecmd_lnum == 0
+				      && vim_strchr(p_cpo, CPO_GOTO1) != NULL)
+					       ? ECMD_ONE : eap->do_ecmd_lnum,
+		    (P_HID(curbuf) ? ECMD_HIDE : 0)
+		    + (eap->forceit ? ECMD_FORCEIT : 0)
+#ifdef FEAT_LISTCMDS
+		    + (eap->cmdidx == CMD_badd ? ECMD_ADDBUF : 0 )
+#endif
+		    ) == FAIL)
+	{
+	    /* Editing the file failed.  If the window was split, close it. */
+#ifdef FEAT_WINDOWS
+	    if (old_curwin != NULL)
+	    {
+		need_hide = (curbufIsChanged() && curbuf->b_nwindows <= 1);
+		if (!need_hide || P_HID(curbuf))
+		{
+# if defined(FEAT_AUTOCMD) && defined(FEAT_EVAL)
+		    cleanup_T   cs;
+
+		    /* Reset the error/interrupt/exception state here so that
+		     * aborting() returns FALSE when closing a window. */
+		    enter_cleanup(&cs);
+# endif
+# ifdef FEAT_GUI
+		    need_mouse_correct = TRUE;
+# endif
+		    win_close(curwin, !need_hide && !P_HID(curbuf));
+
+# if defined(FEAT_AUTOCMD) && defined(FEAT_EVAL)
+		    /* Restore the error/interrupt/exception state if not
+		     * discarded by a new aborting error, interrupt, or
+		     * uncaught exception. */
+		    leave_cleanup(&cs);
+# endif
+		}
+	    }
+#endif
+	}
+	else if (readonlymode && curbuf->b_nwindows == 1)
+	{
+	    /* When editing an already visited buffer, 'readonly' won't be set
+	     * but the previous value is kept.  With ":view" and ":sview" we
+	     * want the  file to be readonly, except when another window is
+	     * editing the same buffer. */
+	    curbuf->b_p_ro = TRUE;
+	}
+	readonlymode = n;
+    }
+    else
+    {
+	if (eap->do_ecmd_cmd != NULL)
+	    do_cmdline_cmd(eap->do_ecmd_cmd);
+#ifdef FEAT_TITLE
+	n = curwin->w_arg_idx_invalid;
+#endif
+	check_arg_idx(curwin);
+#ifdef FEAT_TITLE
+	if (n != curwin->w_arg_idx_invalid)
+	    maketitle();
+#endif
+    }
+
+#ifdef FEAT_WINDOWS
+    /*
+     * if ":split file" worked, set alternate file name in old window to new
+     * file
+     */
+    if (old_curwin != NULL
+	    && *eap->arg != NUL
+	    && curwin != old_curwin
+	    && win_valid(old_curwin)
+	    && old_curwin->w_buffer != curbuf
+	    && !cmdmod.keepalt)
+	old_curwin->w_alt_fnum = curbuf->b_fnum;
+#endif
+
+    ex_no_reprint = TRUE;
+}
+
+#ifndef FEAT_GUI
+/*
+ * ":gui" and ":gvim" when there is no GUI.
+ */
+    static void
+ex_nogui(eap)
+    exarg_T	*eap;
+{
+    eap->errmsg = e_nogvim;
+}
+#endif
+
+#if defined(FEAT_GUI_W32) && defined(FEAT_MENU) && defined(FEAT_TEAROFF)
+    static void
+ex_tearoff(eap)
+    exarg_T	*eap;
+{
+    gui_make_tearoff(eap->arg);
+}
+#endif
+
+#if (defined(FEAT_GUI_MSWIN) || defined(FEAT_GUI_GTK)) && defined(FEAT_MENU)
+    static void
+ex_popup(eap)
+    exarg_T	*eap;
+{
+    gui_make_popup(eap->arg, eap->forceit);
+}
+#endif
+
+/*ARGSUSED*/
+    static void
+ex_swapname(eap)
+    exarg_T	*eap;
+{
+    if (curbuf->b_ml.ml_mfp == NULL || curbuf->b_ml.ml_mfp->mf_fname == NULL)
+	MSG(_("No swap file"));
+    else
+	msg(curbuf->b_ml.ml_mfp->mf_fname);
+}
+
+/*
+ * ":syncbind" forces all 'scrollbind' windows to have the same relative
+ * offset.
+ * (1998-11-02 16:21:01  R. Edward Ralston <eralston@computer.org>)
+ */
+/*ARGSUSED*/
+    static void
+ex_syncbind(eap)
+    exarg_T	*eap;
+{
+#ifdef FEAT_SCROLLBIND
+    win_T	*wp;
+    long	topline;
+    long	y;
+    linenr_T	old_linenr = curwin->w_cursor.lnum;
+
+    setpcmark();
+
+    /*
+     * determine max topline
+     */
+    if (curwin->w_p_scb)
+    {
+	topline = curwin->w_topline;
+	for (wp = firstwin; wp; wp = wp->w_next)
+	{
+	    if (wp->w_p_scb && wp->w_buffer)
+	    {
+		y = wp->w_buffer->b_ml.ml_line_count - p_so;
+		if (topline > y)
+		    topline = y;
+	    }
+	}
+	if (topline < 1)
+	    topline = 1;
+    }
+    else
+    {
+	topline = 1;
+    }
+
+
+    /*
+     * set all scrollbind windows to the same topline
+     */
+    wp = curwin;
+    for (curwin = firstwin; curwin; curwin = curwin->w_next)
+    {
+	if (curwin->w_p_scb)
+	{
+	    y = topline - curwin->w_topline;
+	    if (y > 0)
+		scrollup(y, TRUE);
+	    else
+		scrolldown(-y, TRUE);
+	    curwin->w_scbind_pos = topline;
+	    redraw_later(VALID);
+	    cursor_correct();
+#ifdef FEAT_WINDOWS
+	    curwin->w_redr_status = TRUE;
+#endif
+	}
+    }
+    curwin = wp;
+    if (curwin->w_p_scb)
+    {
+	did_syncbind = TRUE;
+	checkpcmark();
+	if (old_linenr != curwin->w_cursor.lnum)
+	{
+	    char_u ctrl_o[2];
+
+	    ctrl_o[0] = Ctrl_O;
+	    ctrl_o[1] = 0;
+	    ins_typebuf(ctrl_o, REMAP_NONE, 0, TRUE, FALSE);
+	}
+    }
+#endif
+}
+
+
+    static void
+ex_read(eap)
+    exarg_T	*eap;
+{
+    int		i;
+    int		empty = (curbuf->b_ml.ml_flags & ML_EMPTY);
+    linenr_T	lnum;
+
+    if (eap->usefilter)			/* :r!cmd */
+	do_bang(1, eap, FALSE, FALSE, TRUE);
+    else
+    {
+	if (u_save(eap->line2, (linenr_T)(eap->line2 + 1)) == FAIL)
+	    return;
+
+#ifdef FEAT_BROWSE
+	if (cmdmod.browse)
+	{
+	    char_u *browseFile;
+
+	    browseFile = do_browse(0, (char_u *)_("Append File"), eap->arg,
+						    NULL, NULL, NULL, curbuf);
+	    if (browseFile != NULL)
+	    {
+		i = readfile(browseFile, NULL,
+			  eap->line2, (linenr_T)0, (linenr_T)MAXLNUM, eap, 0);
+		vim_free(browseFile);
+	    }
+	    else
+		i = OK;
+	}
+	else
+#endif
+	     if (*eap->arg == NUL)
+	{
+	    if (check_fname() == FAIL)	/* check for no file name */
+		return;
+	    i = readfile(curbuf->b_ffname, curbuf->b_fname,
+			  eap->line2, (linenr_T)0, (linenr_T)MAXLNUM, eap, 0);
+	}
+	else
+	{
+	    if (vim_strchr(p_cpo, CPO_ALTREAD) != NULL)
+		(void)setaltfname(eap->arg, eap->arg, (linenr_T)1);
+	    i = readfile(eap->arg, NULL,
+			  eap->line2, (linenr_T)0, (linenr_T)MAXLNUM, eap, 0);
+
+	}
+	if (i == FAIL)
+	{
+#if defined(FEAT_AUTOCMD) && defined(FEAT_EVAL)
+	    if (!aborting())
+#endif
+		EMSG2(_(e_notopen), eap->arg);
+	}
+	else
+	{
+	    if (empty && exmode_active)
+	    {
+		/* Delete the empty line that remains.  Historically ex does
+		 * this but vi doesn't. */
+		if (eap->line2 == 0)
+		    lnum = curbuf->b_ml.ml_line_count;
+		else
+		    lnum = 1;
+		if (*ml_get(lnum) == NUL && u_savedel(lnum, 1L) == OK)
+		{
+		    ml_delete(lnum, FALSE);
+		    deleted_lines_mark(lnum, 1L);
+		    if (curwin->w_cursor.lnum > 1
+					     && curwin->w_cursor.lnum >= lnum)
+			--curwin->w_cursor.lnum;
+		}
+	    }
+	    redraw_curbuf_later(VALID);
+	}
+    }
+}
+
+static char_u	*prev_dir = NULL;
+
+#if defined(EXITFREE) || defined(PROTO)
+    void
+free_cd_dir()
+{
+    vim_free(prev_dir);
+}
+#endif
+
+
+/*
+ * ":cd", ":lcd", ":chdir" and ":lchdir".
+ */
+    static void
+ex_cd(eap)
+    exarg_T	*eap;
+{
+    char_u		*new_dir;
+    char_u		*tofree;
+
+    new_dir = eap->arg;
+#if !defined(UNIX) && !defined(VMS)
+    /* for non-UNIX ":cd" means: print current directory */
+    if (*new_dir == NUL)
+	ex_pwd(NULL);
+    else
+#endif
+    {
+	if (vim_strchr(p_cpo, CPO_CHDIR) != NULL && curbufIsChanged()
+							     && !eap->forceit)
+	{
+	    EMSG(_("E747: Cannot change directory, buffer is modifed (add ! to override)"));
+	    return;
+	}
+
+	/* ":cd -": Change to previous directory */
+	if (STRCMP(new_dir, "-") == 0)
+	{
+	    if (prev_dir == NULL)
+	    {
+		EMSG(_("E186: No previous directory"));
+		return;
+	    }
+	    new_dir = prev_dir;
+	}
+
+	/* Save current directory for next ":cd -" */
+	tofree = prev_dir;
+	if (mch_dirname(NameBuff, MAXPATHL) == OK)
+	    prev_dir = vim_strsave(NameBuff);
+	else
+	    prev_dir = NULL;
+
+#if defined(UNIX) || defined(VMS)
+	/* for UNIX ":cd" means: go to home directory */
+	if (*new_dir == NUL)
+	{
+	    /* use NameBuff for home directory name */
+# ifdef VMS
+	    char_u	*p;
+
+	    p = mch_getenv((char_u *)"SYS$LOGIN");
+	    if (p == NULL || *p == NUL)	/* empty is the same as not set */
+		NameBuff[0] = NUL;
+	    else
+		vim_strncpy(NameBuff, p, MAXPATHL - 1);
+# else
+	    expand_env((char_u *)"$HOME", NameBuff, MAXPATHL);
+# endif
+	    new_dir = NameBuff;
+	}
+#endif
+	if (new_dir == NULL || vim_chdir(new_dir))
+	    EMSG(_(e_failed));
+	else
+	{
+	    vim_free(curwin->w_localdir);
+	    if (eap->cmdidx == CMD_lcd || eap->cmdidx == CMD_lchdir)
+	    {
+		/* If still in global directory, need to remember current
+		 * directory as global directory. */
+		if (globaldir == NULL && prev_dir != NULL)
+		    globaldir = vim_strsave(prev_dir);
+		/* Remember this local directory for the window. */
+		if (mch_dirname(NameBuff, MAXPATHL) == OK)
+		    curwin->w_localdir = vim_strsave(NameBuff);
+	    }
+	    else
+	    {
+		/* We are now in the global directory, no need to remember its
+		 * name. */
+		vim_free(globaldir);
+		globaldir = NULL;
+		curwin->w_localdir = NULL;
+	    }
+
+	    shorten_fnames(TRUE);
+
+	    /* Echo the new current directory if the command was typed. */
+	    if (KeyTyped)
+		ex_pwd(eap);
+	}
+	vim_free(tofree);
+    }
+}
+
+/*
+ * ":pwd".
+ */
+/*ARGSUSED*/
+    static void
+ex_pwd(eap)
+    exarg_T	*eap;
+{
+    if (mch_dirname(NameBuff, MAXPATHL) == OK)
+    {
+#ifdef BACKSLASH_IN_FILENAME
+	slash_adjust(NameBuff);
+#endif
+	msg(NameBuff);
+    }
+    else
+	EMSG(_("E187: Unknown"));
+}
+
+/*
+ * ":=".
+ */
+    static void
+ex_equal(eap)
+    exarg_T	*eap;
+{
+    smsg((char_u *)"%ld", (long)eap->line2);
+    ex_may_print(eap);
+}
+
+    static void
+ex_sleep(eap)
+    exarg_T	*eap;
+{
+    int		n;
+    long	len;
+
+    if (cursor_valid())
+    {
+	n = W_WINROW(curwin) + curwin->w_wrow - msg_scrolled;
+	if (n >= 0)
+	    windgoto((int)n, curwin->w_wcol);
+    }
+
+    len = eap->line2;
+    switch (*eap->arg)
+    {
+	case 'm': break;
+	case NUL: len *= 1000L; break;
+	default: EMSG2(_(e_invarg2), eap->arg); return;
+    }
+    do_sleep(len);
+}
+
+/*
+ * Sleep for "msec" milliseconds, but keep checking for a CTRL-C every second.
+ */
+    void
+do_sleep(msec)
+    long	msec;
+{
+    long	done;
+
+    cursor_on();
+    out_flush();
+    for (done = 0; !got_int && done < msec; done += 1000L)
+    {
+	ui_delay(msec - done > 1000L ? 1000L : msec - done, TRUE);
+	ui_breakcheck();
+    }
+}
+
+    static void
+do_exmap(eap, isabbrev)
+    exarg_T	*eap;
+    int		isabbrev;
+{
+    int	    mode;
+    char_u  *cmdp;
+
+    cmdp = eap->cmd;
+    mode = get_map_mode(&cmdp, eap->forceit || isabbrev);
+
+    switch (do_map((*cmdp == 'n') ? 2 : (*cmdp == 'u'),
+						    eap->arg, mode, isabbrev))
+    {
+	case 1: EMSG(_(e_invarg));
+		break;
+	case 2: EMSG(isabbrev ? _(e_noabbr) : _(e_nomap));
+		break;
+    }
+}
+
+/*
+ * ":winsize" command (obsolete).
+ */
+    static void
+ex_winsize(eap)
+    exarg_T	*eap;
+{
+    int		w, h;
+    char_u	*arg = eap->arg;
+    char_u	*p;
+
+    w = getdigits(&arg);
+    arg = skipwhite(arg);
+    p = arg;
+    h = getdigits(&arg);
+    if (*p != NUL && *arg == NUL)
+	set_shellsize(w, h, TRUE);
+    else
+	EMSG(_("E465: :winsize requires two number arguments"));
+}
+
+#ifdef FEAT_WINDOWS
+    static void
+ex_wincmd(eap)
+    exarg_T	*eap;
+{
+    int		xchar = NUL;
+    char_u	*p;
+
+    if (*eap->arg == 'g' || *eap->arg == Ctrl_G)
+    {
+	/* CTRL-W g and CTRL-W CTRL-G  have an extra command character */
+	if (eap->arg[1] == NUL)
+	{
+	    EMSG(_(e_invarg));
+	    return;
+	}
+	xchar = eap->arg[1];
+	p = eap->arg + 2;
+    }
+    else
+	p = eap->arg + 1;
+
+    eap->nextcmd = check_nextcmd(p);
+    p = skipwhite(p);
+    if (*p != NUL && *p != '"' && eap->nextcmd == NULL)
+	EMSG(_(e_invarg));
+    else
+    {
+	/* Pass flags on for ":vertical wincmd ]". */
+	postponed_split_flags = cmdmod.split;
+	postponed_split_tab = cmdmod.tab;
+	do_window(*eap->arg, eap->addr_count > 0 ? eap->line2 : 0L, xchar);
+	postponed_split_flags = 0;
+	postponed_split_tab = 0;
+    }
+}
+#endif
+
+#if defined(FEAT_GUI) || defined(UNIX) || defined(VMS) || defined(MSWIN)
+/*
+ * ":winpos".
+ */
+    static void
+ex_winpos(eap)
+    exarg_T	*eap;
+{
+    int		x, y;
+    char_u	*arg = eap->arg;
+    char_u	*p;
+
+    if (*arg == NUL)
+    {
+# if defined(FEAT_GUI) || defined(MSWIN)
+#  ifdef FEAT_GUI
+	if (gui.in_use && gui_mch_get_winpos(&x, &y) != FAIL)
+#  else
+	if (mch_get_winpos(&x, &y) != FAIL)
+#  endif
+	{
+	    sprintf((char *)IObuff, _("Window position: X %d, Y %d"), x, y);
+	    msg(IObuff);
+	}
+	else
+# endif
+	    EMSG(_("E188: Obtaining window position not implemented for this platform"));
+    }
+    else
+    {
+	x = getdigits(&arg);
+	arg = skipwhite(arg);
+	p = arg;
+	y = getdigits(&arg);
+	if (*p == NUL || *arg != NUL)
+	{
+	    EMSG(_("E466: :winpos requires two number arguments"));
+	    return;
+	}
+# ifdef FEAT_GUI
+	if (gui.in_use)
+	    gui_mch_set_winpos(x, y);
+	else if (gui.starting)
+	{
+	    /* Remember the coordinates for when the window is opened. */
+	    gui_win_x = x;
+	    gui_win_y = y;
+	}
+#  ifdef HAVE_TGETENT
+	else
+#  endif
+# else
+#  ifdef MSWIN
+	    mch_set_winpos(x, y);
+#  endif
+# endif
+# ifdef HAVE_TGETENT
+	if (*T_CWP)
+	    term_set_winpos(x, y);
+# endif
+    }
+}
+#endif
+
+/*
+ * Handle command that work like operators: ":delete", ":yank", ":>" and ":<".
+ */
+    static void
+ex_operators(eap)
+    exarg_T	*eap;
+{
+    oparg_T	oa;
+
+    clear_oparg(&oa);
+    oa.regname = eap->regname;
+    oa.start.lnum = eap->line1;
+    oa.end.lnum = eap->line2;
+    oa.line_count = eap->line2 - eap->line1 + 1;
+    oa.motion_type = MLINE;
+#ifdef FEAT_VIRTUALEDIT
+    virtual_op = FALSE;
+#endif
+    if (eap->cmdidx != CMD_yank)	/* position cursor for undo */
+    {
+	setpcmark();
+	curwin->w_cursor.lnum = eap->line1;
+	beginline(BL_SOL | BL_FIX);
+    }
+
+    switch (eap->cmdidx)
+    {
+	case CMD_delete:
+	    oa.op_type = OP_DELETE;
+	    op_delete(&oa);
+	    break;
+
+	case CMD_yank:
+	    oa.op_type = OP_YANK;
+	    (void)op_yank(&oa, FALSE, TRUE);
+	    break;
+
+	default:    /* CMD_rshift or CMD_lshift */
+	    if ((eap->cmdidx == CMD_rshift)
+#ifdef FEAT_RIGHTLEFT
+				    ^ curwin->w_p_rl
+#endif
+						    )
+		oa.op_type = OP_RSHIFT;
+	    else
+		oa.op_type = OP_LSHIFT;
+	    op_shift(&oa, FALSE, eap->amount);
+	    break;
+    }
+#ifdef FEAT_VIRTUALEDIT
+    virtual_op = MAYBE;
+#endif
+    ex_may_print(eap);
+}
+
+/*
+ * ":put".
+ */
+    static void
+ex_put(eap)
+    exarg_T	*eap;
+{
+    /* ":0put" works like ":1put!". */
+    if (eap->line2 == 0)
+    {
+	eap->line2 = 1;
+	eap->forceit = TRUE;
+    }
+    curwin->w_cursor.lnum = eap->line2;
+    do_put(eap->regname, eap->forceit ? BACKWARD : FORWARD, 1L,
+						       PUT_LINE|PUT_CURSLINE);
+}
+
+/*
+ * Handle ":copy" and ":move".
+ */
+    static void
+ex_copymove(eap)
+    exarg_T	*eap;
+{
+    long	n;
+
+    n = get_address(&eap->arg, FALSE, FALSE);
+    if (eap->arg == NULL)	    /* error detected */
+    {
+	eap->nextcmd = NULL;
+	return;
+    }
+    get_flags(eap);
+
+    /*
+     * move or copy lines from 'eap->line1'-'eap->line2' to below line 'n'
+     */
+    if (n == MAXLNUM || n < 0 || n > curbuf->b_ml.ml_line_count)
+    {
+	EMSG(_(e_invaddr));
+	return;
+    }
+
+    if (eap->cmdidx == CMD_move)
+    {
+	if (do_move(eap->line1, eap->line2, n) == FAIL)
+	    return;
+    }
+    else
+	ex_copy(eap->line1, eap->line2, n);
+    u_clearline();
+    beginline(BL_SOL | BL_FIX);
+    ex_may_print(eap);
+}
+
+/*
+ * Print the current line if flags were given to the Ex command.
+ */
+    static void
+ex_may_print(eap)
+    exarg_T	*eap;
+{
+    if (eap->flags != 0)
+    {
+	print_line(curwin->w_cursor.lnum, (eap->flags & EXFLAG_NR),
+						  (eap->flags & EXFLAG_LIST));
+	ex_no_reprint = TRUE;
+    }
+}
+
+/*
+ * ":smagic" and ":snomagic".
+ */
+    static void
+ex_submagic(eap)
+    exarg_T	*eap;
+{
+    int		magic_save = p_magic;
+
+    p_magic = (eap->cmdidx == CMD_smagic);
+    do_sub(eap);
+    p_magic = magic_save;
+}
+
+/*
+ * ":join".
+ */
+    static void
+ex_join(eap)
+    exarg_T	*eap;
+{
+    curwin->w_cursor.lnum = eap->line1;
+    if (eap->line1 == eap->line2)
+    {
+	if (eap->addr_count >= 2)   /* :2,2join does nothing */
+	    return;
+	if (eap->line2 == curbuf->b_ml.ml_line_count)
+	{
+	    beep_flush();
+	    return;
+	}
+	++eap->line2;
+    }
+    do_do_join(eap->line2 - eap->line1 + 1, !eap->forceit);
+    beginline(BL_WHITE | BL_FIX);
+    ex_may_print(eap);
+}
+
+/*
+ * ":[addr]@r" or ":[addr]*r": execute register
+ */
+    static void
+ex_at(eap)
+    exarg_T	*eap;
+{
+    int		c;
+
+    curwin->w_cursor.lnum = eap->line2;
+
+#ifdef USE_ON_FLY_SCROLL
+    dont_scroll = TRUE;		/* disallow scrolling here */
+#endif
+
+    /* get the register name.  No name means to use the previous one */
+    c = *eap->arg;
+    if (c == NUL || (c == '*' && *eap->cmd == '*'))
+	c = '@';
+    /* Put the register in the typeahead buffer with the "silent" flag. */
+    if (do_execreg(c, TRUE, vim_strchr(p_cpo, CPO_EXECBUF) != NULL, TRUE)
+								      == FAIL)
+    {
+	beep_flush();
+    }
+    else
+    {
+	int	save_efr = exec_from_reg;
+
+	exec_from_reg = TRUE;
+
+	/*
+	 * Execute from the typeahead buffer.
+	 * Originally this didn't check for the typeahead buffer to be empty,
+	 * thus could read more Ex commands from stdin.  It's not clear why,
+	 * it is certainly unexpected.
+	 */
+	while ((!stuff_empty() || typebuf.tb_len > 0) && vpeekc() == ':')
+	    (void)do_cmdline(NULL, getexline, NULL, DOCMD_NOWAIT|DOCMD_VERBOSE);
+
+	exec_from_reg = save_efr;
+    }
+}
+
+/*
+ * ":!".
+ */
+    static void
+ex_bang(eap)
+    exarg_T	*eap;
+{
+    do_bang(eap->addr_count, eap, eap->forceit, TRUE, TRUE);
+}
+
+/*
+ * ":undo".
+ */
+/*ARGSUSED*/
+    static void
+ex_undo(eap)
+    exarg_T	*eap;
+{
+    if (eap->addr_count == 1)	    /* :undo 123 */
+	undo_time(eap->line2, FALSE, TRUE);
+    else
+	u_undo(1);
+}
+
+/*
+ * ":redo".
+ */
+/*ARGSUSED*/
+    static void
+ex_redo(eap)
+    exarg_T	*eap;
+{
+    u_redo(1);
+}
+
+/*
+ * ":earlier" and ":later".
+ */
+/*ARGSUSED*/
+    static void
+ex_later(eap)
+    exarg_T	*eap;
+{
+    long	count = 0;
+    int		sec = FALSE;
+    char_u	*p = eap->arg;
+
+    if (*p == NUL)
+	count = 1;
+    else if (isdigit(*p))
+    {
+	count = getdigits(&p);
+	switch (*p)
+	{
+	    case 's': ++p; sec = TRUE; break;
+	    case 'm': ++p; sec = TRUE; count *= 60; break;
+	    case 'h': ++p; sec = TRUE; count *= 60 * 60; break;
+	}
+    }
+
+    if (*p != NUL)
+	EMSG2(_(e_invarg2), eap->arg);
+    else
+	undo_time(eap->cmdidx == CMD_earlier ? -count : count, sec, FALSE);
+}
+
+/*
+ * ":redir": start/stop redirection.
+ */
+    static void
+ex_redir(eap)
+    exarg_T	*eap;
+{
+    char	*mode;
+    char_u	*fname;
+    char_u	*arg = eap->arg;
+
+    if (STRICMP(eap->arg, "END") == 0)
+	close_redir();
+    else
+    {
+	if (*arg == '>')
+	{
+	    ++arg;
+	    if (*arg == '>')
+	    {
+		++arg;
+		mode = "a";
+	    }
+	    else
+		mode = "w";
+	    arg = skipwhite(arg);
+
+	    close_redir();
+
+	    /* Expand environment variables and "~/". */
+	    fname = expand_env_save(arg);
+	    if (fname == NULL)
+		return;
+#ifdef FEAT_BROWSE
+	    if (cmdmod.browse)
+	    {
+		char_u	*browseFile;
+
+		browseFile = do_browse(BROWSE_SAVE,
+			(char_u *)_("Save Redirection"),
+			fname, NULL, NULL, BROWSE_FILTER_ALL_FILES, curbuf);
+		if (browseFile == NULL)
+		    return;		/* operation cancelled */
+		vim_free(fname);
+		fname = browseFile;
+		eap->forceit = TRUE;	/* since dialog already asked */
+	    }
+#endif
+
+	    redir_fd = open_exfile(fname, eap->forceit, mode);
+	    vim_free(fname);
+	}
+#ifdef FEAT_EVAL
+	else if (*arg == '@')
+	{
+	    /* redirect to a register a-z (resp. A-Z for appending) */
+	    close_redir();
+	    ++arg;
+	    if (ASCII_ISALPHA(*arg)
+# ifdef FEAT_CLIPBOARD
+		    || *arg == '*'
+		    || *arg == '+'
+# endif
+		    || *arg == '"')
+	    {
+		redir_reg = *arg++;
+		if (*arg == '>' && arg[1] == '>')
+		    arg += 2;
+		else if ((*arg == NUL || (*arg == '>' && arg[1] == NUL)) &&
+			 (islower(redir_reg)
+# ifdef FEAT_CLIPBOARD
+			    || redir_reg == '*'
+			    || redir_reg == '+'
+# endif
+			    || redir_reg == '"'))
+		{
+		    if (*arg == '>')
+			arg++;
+
+		    /* make register empty */
+		    write_reg_contents(redir_reg, (char_u *)"", -1, FALSE);
+		}
+	    }
+	    if (*arg != NUL)
+	    {
+		redir_reg = 0;
+		EMSG2(_(e_invarg2), eap->arg);
+	    }
+	}
+	else if (*arg == '=' && arg[1] == '>')
+	{
+	    int append;
+
+	    /* redirect to a variable */
+	    close_redir();
+	    arg += 2;
+
+	    if (*arg == '>')
+	    {
+		++arg;
+		append = TRUE;
+	    }
+	    else
+		append = FALSE;
+
+	    if (var_redir_start(skipwhite(arg), append) == OK)
+		redir_vname = 1;
+	}
+#endif
+
+	/* TODO: redirect to a buffer */
+
+	else
+	    EMSG2(_(e_invarg2), eap->arg);
+    }
+
+    /* Make sure redirection is not off.  Can happen for cmdline completion
+     * that indirectly invokes a command to catch its output. */
+    if (redir_fd != NULL
+#ifdef FEAT_EVAL
+			  || redir_reg || redir_vname
+#endif
+							)
+	redir_off = FALSE;
+}
+
+/*
+ * ":redraw": force redraw
+ */
+    static void
+ex_redraw(eap)
+    exarg_T	*eap;
+{
+    int		r = RedrawingDisabled;
+    int		p = p_lz;
+
+    RedrawingDisabled = 0;
+    p_lz = FALSE;
+    update_topline();
+    update_screen(eap->forceit ? CLEAR :
+#ifdef FEAT_VISUAL
+	    VIsual_active ? INVERTED :
+#endif
+	    0);
+#ifdef FEAT_TITLE
+    if (need_maketitle)
+	maketitle();
+#endif
+    RedrawingDisabled = r;
+    p_lz = p;
+
+    /* Reset msg_didout, so that a message that's there is overwritten. */
+    msg_didout = FALSE;
+    msg_col = 0;
+
+    out_flush();
+}
+
+/*
+ * ":redrawstatus": force redraw of status line(s)
+ */
+/*ARGSUSED*/
+    static void
+ex_redrawstatus(eap)
+    exarg_T	*eap;
+{
+#if defined(FEAT_WINDOWS)
+    int		r = RedrawingDisabled;
+    int		p = p_lz;
+
+    RedrawingDisabled = 0;
+    p_lz = FALSE;
+    if (eap->forceit)
+	status_redraw_all();
+    else
+	status_redraw_curbuf();
+    update_screen(
+# ifdef FEAT_VISUAL
+	    VIsual_active ? INVERTED :
+# endif
+	    0);
+    RedrawingDisabled = r;
+    p_lz = p;
+    out_flush();
+#endif
+}
+
+    static void
+close_redir()
+{
+    if (redir_fd != NULL)
+    {
+	fclose(redir_fd);
+	redir_fd = NULL;
+    }
+#ifdef FEAT_EVAL
+    redir_reg = 0;
+    if (redir_vname)
+    {
+	var_redir_stop();
+	redir_vname = 0;
+    }
+#endif
+}
+
+#if defined(FEAT_SESSION) && defined(USE_CRNL)
+# define MKSESSION_NL
+static int mksession_nl = FALSE;    /* use NL only in put_eol() */
+#endif
+
+/*
+ * ":mkexrc", ":mkvimrc", ":mkview" and ":mksession".
+ */
+    static void
+ex_mkrc(eap)
+    exarg_T	*eap;
+{
+    FILE	*fd;
+    int		failed = FALSE;
+    char_u	*fname;
+#ifdef FEAT_BROWSE
+    char_u	*browseFile = NULL;
+#endif
+#ifdef FEAT_SESSION
+    int		view_session = FALSE;
+    int		using_vdir = FALSE;	/* using 'viewdir'? */
+    char_u	*viewFile = NULL;
+    unsigned	*flagp;
+#endif
+
+    if (eap->cmdidx == CMD_mksession || eap->cmdidx == CMD_mkview)
+    {
+#ifdef FEAT_SESSION
+	view_session = TRUE;
+#else
+	ex_ni(eap);
+	return;
+#endif
+    }
+
+#ifdef FEAT_SESSION
+    did_lcd = FALSE;
+
+    /* ":mkview" or ":mkview 9": generate file name with 'viewdir' */
+    if (eap->cmdidx == CMD_mkview
+	    && (*eap->arg == NUL
+		|| (vim_isdigit(*eap->arg) && eap->arg[1] == NUL)))
+    {
+	eap->forceit = TRUE;
+	fname = get_view_file(*eap->arg);
+	if (fname == NULL)
+	    return;
+	viewFile = fname;
+	using_vdir = TRUE;
+    }
+    else
+#endif
+	if (*eap->arg != NUL)
+	fname = eap->arg;
+    else if (eap->cmdidx == CMD_mkvimrc)
+	fname = (char_u *)VIMRC_FILE;
+#ifdef FEAT_SESSION
+    else if (eap->cmdidx == CMD_mksession)
+	fname = (char_u *)SESSION_FILE;
+#endif
+    else
+	fname = (char_u *)EXRC_FILE;
+
+#ifdef FEAT_BROWSE
+    if (cmdmod.browse)
+    {
+	browseFile = do_browse(BROWSE_SAVE,
+# ifdef FEAT_SESSION
+		eap->cmdidx == CMD_mkview ? (char_u *)_("Save View") :
+		eap->cmdidx == CMD_mksession ? (char_u *)_("Save Session") :
+# endif
+		(char_u *)_("Save Setup"),
+		fname, (char_u *)"vim", NULL, BROWSE_FILTER_MACROS, NULL);
+	if (browseFile == NULL)
+	    goto theend;
+	fname = browseFile;
+	eap->forceit = TRUE;	/* since dialog already asked */
+    }
+#endif
+
+#if defined(FEAT_SESSION) && defined(vim_mkdir)
+    /* When using 'viewdir' may have to create the directory. */
+    if (using_vdir && !mch_isdir(p_vdir))
+	vim_mkdir_emsg(p_vdir, 0755);
+#endif
+
+    fd = open_exfile(fname, eap->forceit, WRITEBIN);
+    if (fd != NULL)
+    {
+#ifdef FEAT_SESSION
+	if (eap->cmdidx == CMD_mkview)
+	    flagp = &vop_flags;
+	else
+	    flagp = &ssop_flags;
+#endif
+
+#ifdef MKSESSION_NL
+	/* "unix" in 'sessionoptions': use NL line separator */
+	if (view_session && (*flagp & SSOP_UNIX))
+	    mksession_nl = TRUE;
+#endif
+
+	/* Write the version command for :mkvimrc */
+	if (eap->cmdidx == CMD_mkvimrc)
+	    (void)put_line(fd, "version 6.0");
+
+#ifdef FEAT_SESSION
+	if (eap->cmdidx == CMD_mksession)
+	{
+	    if (put_line(fd, "let SessionLoad = 1") == FAIL)
+		failed = TRUE;
+	}
+
+	if (eap->cmdidx != CMD_mkview)
+#endif
+	{
+	    /* Write setting 'compatible' first, because it has side effects.
+	     * For that same reason only do it when needed. */
+	    if (p_cp)
+		(void)put_line(fd, "if !&cp | set cp | endif");
+	    else
+		(void)put_line(fd, "if &cp | set nocp | endif");
+	}
+
+#ifdef FEAT_SESSION
+	if (!view_session
+		|| (eap->cmdidx == CMD_mksession
+		    && (*flagp & SSOP_OPTIONS)))
+#endif
+	    failed |= (makemap(fd, NULL) == FAIL
+				   || makeset(fd, OPT_GLOBAL, FALSE) == FAIL);
+
+#ifdef FEAT_SESSION
+	if (!failed && view_session)
+	{
+	    if (put_line(fd, "let s:so_save = &so | let s:siso_save = &siso | set so=0 siso=0") == FAIL)
+		failed = TRUE;
+	    if (eap->cmdidx == CMD_mksession)
+	    {
+		char_u dirnow[MAXPATHL];	/* current directory */
+
+		/*
+		 * Change to session file's dir.
+		 */
+		if (mch_dirname(dirnow, MAXPATHL) == FAIL
+					    || mch_chdir((char *)dirnow) != 0)
+		    *dirnow = NUL;
+		if (*dirnow != NUL && (ssop_flags & SSOP_SESDIR))
+		{
+		    if (vim_chdirfile(fname) == OK)
+			shorten_fnames(TRUE);
+		}
+		else if (*dirnow != NUL
+			&& (ssop_flags & SSOP_CURDIR) && globaldir != NULL)
+		{
+		    (void)mch_chdir((char *)globaldir);
+		    shorten_fnames(TRUE);
+		}
+
+		failed |= (makeopens(fd, dirnow) == FAIL);
+
+		/* restore original dir */
+		if (*dirnow != NUL && ((ssop_flags & SSOP_SESDIR)
+			|| ((ssop_flags & SSOP_CURDIR) && globaldir != NULL)))
+		{
+		    if (mch_chdir((char *)dirnow) != 0)
+			EMSG(_(e_prev_dir));
+		    shorten_fnames(TRUE);
+		}
+	    }
+	    else
+	    {
+		failed |= (put_view(fd, curwin, !using_vdir, flagp) == FAIL);
+	    }
+	    if (put_line(fd, "let &so = s:so_save | let &siso = s:siso_save")
+								      == FAIL)
+		failed = TRUE;
+	    if (put_line(fd, "doautoall SessionLoadPost") == FAIL)
+		failed = TRUE;
+	    if (eap->cmdidx == CMD_mksession)
+	    {
+		if (put_line(fd, "unlet SessionLoad") == FAIL)
+		    failed = TRUE;
+	    }
+	}
+#endif
+	if (put_line(fd, "\" vim: set ft=vim :") == FAIL)
+	    failed = TRUE;
+
+	failed |= fclose(fd);
+
+	if (failed)
+	    EMSG(_(e_write));
+#if defined(FEAT_EVAL) && defined(FEAT_SESSION)
+	else if (eap->cmdidx == CMD_mksession)
+	{
+	    /* successful session write - set this_session var */
+	    char_u	tbuf[MAXPATHL];
+
+	    if (vim_FullName(fname, tbuf, MAXPATHL, FALSE) == OK)
+		set_vim_var_string(VV_THIS_SESSION, tbuf, -1);
+	}
+#endif
+#ifdef MKSESSION_NL
+	mksession_nl = FALSE;
+#endif
+    }
+
+#ifdef FEAT_BROWSE
+theend:
+    vim_free(browseFile);
+#endif
+#ifdef FEAT_SESSION
+    vim_free(viewFile);
+#endif
+}
+
+#if ((defined(FEAT_SESSION) || defined(FEAT_EVAL)) && defined(vim_mkdir)) \
+	|| defined(PROTO)
+/*ARGSUSED*/
+    int
+vim_mkdir_emsg(name, prot)
+    char_u	*name;
+    int		prot;
+{
+    if (vim_mkdir(name, prot) != 0)
+    {
+	EMSG2(_("E739: Cannot create directory: %s"), name);
+	return FAIL;
+    }
+    return OK;
+}
+#endif
+
+/*
+ * Open a file for writing for an Ex command, with some checks.
+ * Return file descriptor, or NULL on failure.
+ */
+    FILE *
+open_exfile(fname, forceit, mode)
+    char_u	*fname;
+    int		forceit;
+    char	*mode;	    /* "w" for create new file or "a" for append */
+{
+    FILE	*fd;
+
+#ifdef UNIX
+    /* with Unix it is possible to open a directory */
+    if (mch_isdir(fname))
+    {
+	EMSG2(_(e_isadir2), fname);
+	return NULL;
+    }
+#endif
+    if (!forceit && *mode != 'a' && vim_fexists(fname))
+    {
+	EMSG2(_("E189: \"%s\" exists (add ! to override)"), fname);
+	return NULL;
+    }
+
+    if ((fd = mch_fopen((char *)fname, mode)) == NULL)
+	EMSG2(_("E190: Cannot open \"%s\" for writing"), fname);
+
+    return fd;
+}
+
+/*
+ * ":mark" and ":k".
+ */
+    static void
+ex_mark(eap)
+    exarg_T	*eap;
+{
+    pos_T	pos;
+
+    if (*eap->arg == NUL)		/* No argument? */
+	EMSG(_(e_argreq));
+    else if (eap->arg[1] != NUL)	/* more than one character? */
+	EMSG(_(e_trailing));
+    else
+    {
+	pos = curwin->w_cursor;		/* save curwin->w_cursor */
+	curwin->w_cursor.lnum = eap->line2;
+	beginline(BL_WHITE | BL_FIX);
+	if (setmark(*eap->arg) == FAIL)	/* set mark */
+	    EMSG(_("E191: Argument must be a letter or forward/backward quote"));
+	curwin->w_cursor = pos;		/* restore curwin->w_cursor */
+    }
+}
+
+/*
+ * Update w_topline, w_leftcol and the cursor position.
+ */
+    void
+update_topline_cursor()
+{
+    check_cursor();		/* put cursor on valid line */
+    update_topline();
+    if (!curwin->w_p_wrap)
+	validate_cursor();
+    update_curswant();
+}
+
+#ifdef FEAT_EX_EXTRA
+/*
+ * ":normal[!] {commands}": Execute normal mode commands.
+ */
+    static void
+ex_normal(eap)
+    exarg_T	*eap;
+{
+    int		save_msg_scroll = msg_scroll;
+    int		save_restart_edit = restart_edit;
+    int		save_msg_didout = msg_didout;
+    int		save_State = State;
+    tasave_T	tabuf;
+    int		save_insertmode = p_im;
+    int		save_finish_op = finish_op;
+#ifdef FEAT_MBYTE
+    char_u	*arg = NULL;
+    int		l;
+    char_u	*p;
+#endif
+
+    if (ex_normal_lock > 0)
+    {
+	EMSG(_(e_secure));
+	return;
+    }
+    if (ex_normal_busy >= p_mmd)
+    {
+	EMSG(_("E192: Recursive use of :normal too deep"));
+	return;
+    }
+    ++ex_normal_busy;
+
+    msg_scroll = FALSE;	    /* no msg scrolling in Normal mode */
+    restart_edit = 0;	    /* don't go to Insert mode */
+    p_im = FALSE;	    /* don't use 'insertmode' */
+
+#ifdef FEAT_MBYTE
+    /*
+     * vgetc() expects a CSI and K_SPECIAL to have been escaped.  Don't do
+     * this for the K_SPECIAL leading byte, otherwise special keys will not
+     * work.
+     */
+    if (has_mbyte)
+    {
+	int	len = 0;
+
+	/* Count the number of characters to be escaped. */
+	for (p = eap->arg; *p != NUL; ++p)
+	{
+# ifdef FEAT_GUI
+	    if (*p == CSI)  /* leadbyte CSI */
+		len += 2;
+# endif
+	    for (l = (*mb_ptr2len)(p) - 1; l > 0; --l)
+		if (*++p == K_SPECIAL	  /* trailbyte K_SPECIAL or CSI */
+# ifdef FEAT_GUI
+			|| *p == CSI
+# endif
+			)
+		    len += 2;
+	}
+	if (len > 0)
+	{
+	    arg = alloc((unsigned)(STRLEN(eap->arg) + len + 1));
+	    if (arg != NULL)
+	    {
+		len = 0;
+		for (p = eap->arg; *p != NUL; ++p)
+		{
+		    arg[len++] = *p;
+# ifdef FEAT_GUI
+		    if (*p == CSI)
+		    {
+			arg[len++] = KS_EXTRA;
+			arg[len++] = (int)KE_CSI;
+		    }
+# endif
+		    for (l = (*mb_ptr2len)(p) - 1; l > 0; --l)
+		    {
+			arg[len++] = *++p;
+			if (*p == K_SPECIAL)
+			{
+			    arg[len++] = KS_SPECIAL;
+			    arg[len++] = KE_FILLER;
+			}
+# ifdef FEAT_GUI
+			else if (*p == CSI)
+			{
+			    arg[len++] = KS_EXTRA;
+			    arg[len++] = (int)KE_CSI;
+			}
+# endif
+		    }
+		    arg[len] = NUL;
+		}
+	    }
+	}
+    }
+#endif
+
+    /*
+     * Save the current typeahead.  This is required to allow using ":normal"
+     * from an event handler and makes sure we don't hang when the argument
+     * ends with half a command.
+     */
+    save_typeahead(&tabuf);
+    if (tabuf.typebuf_valid)
+    {
+	/*
+	 * Repeat the :normal command for each line in the range.  When no
+	 * range given, execute it just once, without positioning the cursor
+	 * first.
+	 */
+	do
+	{
+	    if (eap->addr_count != 0)
+	    {
+		curwin->w_cursor.lnum = eap->line1++;
+		curwin->w_cursor.col = 0;
+	    }
+
+	    exec_normal_cmd(
+#ifdef FEAT_MBYTE
+		    arg != NULL ? arg :
+#endif
+		    eap->arg, eap->forceit ? REMAP_NONE : REMAP_YES, FALSE);
+	}
+	while (eap->addr_count > 0 && eap->line1 <= eap->line2 && !got_int);
+    }
+
+    /* Might not return to the main loop when in an event handler. */
+    update_topline_cursor();
+
+    /* Restore the previous typeahead. */
+    restore_typeahead(&tabuf);
+
+    --ex_normal_busy;
+    msg_scroll = save_msg_scroll;
+    restart_edit = save_restart_edit;
+    p_im = save_insertmode;
+    finish_op = save_finish_op;
+    msg_didout |= save_msg_didout;	/* don't reset msg_didout now */
+
+    /* Restore the state (needed when called from a function executed for
+     * 'indentexpr'). */
+    State = save_State;
+#ifdef FEAT_MBYTE
+    vim_free(arg);
+#endif
+}
+
+/*
+ * ":startinsert", ":startreplace" and ":startgreplace"
+ */
+    static void
+ex_startinsert(eap)
+    exarg_T	*eap;
+{
+    if (eap->forceit)
+    {
+	coladvance((colnr_T)MAXCOL);
+	curwin->w_curswant = MAXCOL;
+	curwin->w_set_curswant = FALSE;
+    }
+
+    /* Ignore the command when already in Insert mode.  Inserting an
+     * expression register that invokes a function can do this. */
+    if (State & INSERT)
+	return;
+
+    if (eap->cmdidx == CMD_startinsert)
+	restart_edit = 'a';
+    else if (eap->cmdidx == CMD_startreplace)
+	restart_edit = 'R';
+    else
+	restart_edit = 'V';
+
+    if (!eap->forceit)
+    {
+	if (eap->cmdidx == CMD_startinsert)
+	    restart_edit = 'i';
+	curwin->w_curswant = 0;	    /* avoid MAXCOL */
+    }
+}
+
+/*
+ * ":stopinsert"
+ */
+/*ARGSUSED*/
+    static void
+ex_stopinsert(eap)
+    exarg_T	*eap;
+{
+    restart_edit = 0;
+    stop_insert_mode = TRUE;
+}
+#endif
+
+#if defined(FEAT_EX_EXTRA) || defined(FEAT_MENU) || defined(PROTO)
+/*
+ * Execute normal mode command "cmd".
+ * "remap" can be REMAP_NONE or REMAP_YES.
+ */
+    void
+exec_normal_cmd(cmd, remap, silent)
+    char_u	*cmd;
+    int		remap;
+    int		silent;
+{
+    oparg_T	oa;
+
+    /*
+     * Stuff the argument into the typeahead buffer.
+     * Execute normal_cmd() until there is no typeahead left.
+     */
+    clear_oparg(&oa);
+    finish_op = FALSE;
+    ins_typebuf(cmd, remap, 0, TRUE, silent);
+    while ((!stuff_empty() || (!typebuf_typed() && typebuf.tb_len > 0))
+								  && !got_int)
+    {
+	update_topline_cursor();
+	normal_cmd(&oa, FALSE);	/* execute a Normal mode cmd */
+    }
+}
+#endif
+
+#ifdef FEAT_FIND_ID
+    static void
+ex_checkpath(eap)
+    exarg_T	*eap;
+{
+    find_pattern_in_path(NULL, 0, 0, FALSE, FALSE, CHECK_PATH, 1L,
+				   eap->forceit ? ACTION_SHOW_ALL : ACTION_SHOW,
+					      (linenr_T)1, (linenr_T)MAXLNUM);
+}
+
+#if defined(FEAT_WINDOWS) && defined(FEAT_QUICKFIX)
+/*
+ * ":psearch"
+ */
+    static void
+ex_psearch(eap)
+    exarg_T	*eap;
+{
+    g_do_tagpreview = p_pvh;
+    ex_findpat(eap);
+    g_do_tagpreview = 0;
+}
+#endif
+
+    static void
+ex_findpat(eap)
+    exarg_T	*eap;
+{
+    int		whole = TRUE;
+    long	n;
+    char_u	*p;
+    int		action;
+
+    switch (cmdnames[eap->cmdidx].cmd_name[2])
+    {
+	case 'e':	/* ":psearch", ":isearch" and ":dsearch" */
+		if (cmdnames[eap->cmdidx].cmd_name[0] == 'p')
+		    action = ACTION_GOTO;
+		else
+		    action = ACTION_SHOW;
+		break;
+	case 'i':	/* ":ilist" and ":dlist" */
+		action = ACTION_SHOW_ALL;
+		break;
+	case 'u':	/* ":ijump" and ":djump" */
+		action = ACTION_GOTO;
+		break;
+	default:	/* ":isplit" and ":dsplit" */
+		action = ACTION_SPLIT;
+		break;
+    }
+
+    n = 1;
+    if (vim_isdigit(*eap->arg))	/* get count */
+    {
+	n = getdigits(&eap->arg);
+	eap->arg = skipwhite(eap->arg);
+    }
+    if (*eap->arg == '/')   /* Match regexp, not just whole words */
+    {
+	whole = FALSE;
+	++eap->arg;
+	p = skip_regexp(eap->arg, '/', p_magic, NULL);
+	if (*p)
+	{
+	    *p++ = NUL;
+	    p = skipwhite(p);
+
+	    /* Check for trailing illegal characters */
+	    if (!ends_excmd(*p))
+		eap->errmsg = e_trailing;
+	    else
+		eap->nextcmd = check_nextcmd(p);
+	}
+    }
+    if (!eap->skip)
+	find_pattern_in_path(eap->arg, 0, (int)STRLEN(eap->arg),
+			    whole, !eap->forceit,
+			    *eap->cmd == 'd' ?	FIND_DEFINE : FIND_ANY,
+			    n, action, eap->line1, eap->line2);
+}
+#endif
+
+#ifdef FEAT_WINDOWS
+
+# ifdef FEAT_QUICKFIX
+/*
+ * ":ptag", ":ptselect", ":ptjump", ":ptnext", etc.
+ */
+    static void
+ex_ptag(eap)
+    exarg_T	*eap;
+{
+    g_do_tagpreview = p_pvh;
+    ex_tag_cmd(eap, cmdnames[eap->cmdidx].cmd_name + 1);
+}
+
+/*
+ * ":pedit"
+ */
+    static void
+ex_pedit(eap)
+    exarg_T	*eap;
+{
+    win_T	*curwin_save = curwin;
+
+    g_do_tagpreview = p_pvh;
+    prepare_tagpreview(TRUE);
+    keep_help_flag = curwin_save->w_buffer->b_help;
+    do_exedit(eap, NULL);
+    keep_help_flag = FALSE;
+    if (curwin != curwin_save && win_valid(curwin_save))
+    {
+	/* Return cursor to where we were */
+	validate_cursor();
+	redraw_later(VALID);
+	win_enter(curwin_save, TRUE);
+    }
+    g_do_tagpreview = 0;
+}
+# endif
+
+/*
+ * ":stag", ":stselect" and ":stjump".
+ */
+    static void
+ex_stag(eap)
+    exarg_T	*eap;
+{
+    postponed_split = -1;
+    postponed_split_flags = cmdmod.split;
+    postponed_split_tab = cmdmod.tab;
+    ex_tag_cmd(eap, cmdnames[eap->cmdidx].cmd_name + 1);
+    postponed_split_flags = 0;
+    postponed_split_tab = 0;
+}
+#endif
+
+/*
+ * ":tag", ":tselect", ":tjump", ":tnext", etc.
+ */
+    static void
+ex_tag(eap)
+    exarg_T	*eap;
+{
+    ex_tag_cmd(eap, cmdnames[eap->cmdidx].cmd_name);
+}
+
+    static void
+ex_tag_cmd(eap, name)
+    exarg_T	*eap;
+    char_u	*name;
+{
+    int		cmd;
+
+    switch (name[1])
+    {
+	case 'j': cmd = DT_JUMP;	/* ":tjump" */
+		  break;
+	case 's': cmd = DT_SELECT;	/* ":tselect" */
+		  break;
+	case 'p': cmd = DT_PREV;	/* ":tprevious" */
+		  break;
+	case 'N': cmd = DT_PREV;	/* ":tNext" */
+		  break;
+	case 'n': cmd = DT_NEXT;	/* ":tnext" */
+		  break;
+	case 'o': cmd = DT_POP;		/* ":pop" */
+		  break;
+	case 'f':			/* ":tfirst" */
+	case 'r': cmd = DT_FIRST;	/* ":trewind" */
+		  break;
+	case 'l': cmd = DT_LAST;	/* ":tlast" */
+		  break;
+	default:			/* ":tag" */
+#ifdef FEAT_CSCOPE
+		  if (p_cst)
+		  {
+		      do_cstag(eap);
+		      return;
+		  }
+#endif
+		  cmd = DT_TAG;
+		  break;
+    }
+
+    if (name[0] == 'l')
+    {
+#ifndef FEAT_QUICKFIX
+	ex_ni(eap);
+	return;
+#else
+	cmd = DT_LTAG;
+#endif
+    }
+
+    do_tag(eap->arg, cmd, eap->addr_count > 0 ? (int)eap->line2 : 1,
+							  eap->forceit, TRUE);
+}
+
+/*
+ * Evaluate cmdline variables.
+ *
+ * change '%'	    to curbuf->b_ffname
+ *	  '#'	    to curwin->w_altfile
+ *	  '<cword>' to word under the cursor
+ *	  '<cWORD>' to WORD under the cursor
+ *	  '<cfile>' to path name under the cursor
+ *	  '<sfile>' to sourced file name
+ *	  '<afile>' to file name for autocommand
+ *	  '<abuf>'  to buffer number for autocommand
+ *	  '<amatch>' to matching name for autocommand
+ *
+ * When an error is detected, "errormsg" is set to a non-NULL pointer (may be
+ * "" for error without a message) and NULL is returned.
+ * Returns an allocated string if a valid match was found.
+ * Returns NULL if no match was found.	"usedlen" then still contains the
+ * number of characters to skip.
+ */
+    char_u *
+eval_vars(src, srcstart, usedlen, lnump, errormsg, escaped)
+    char_u	*src;		/* pointer into commandline */
+    char_u	*srcstart;	/* beginning of valid memory for src */
+    int		*usedlen;	/* characters after src that are used */
+    linenr_T	*lnump;		/* line number for :e command, or NULL */
+    char_u	**errormsg;	/* pointer to error message */
+    int		*escaped;	/* return value has escaped white space (can
+				 * be NULL) */
+{
+    int		i;
+    char_u	*s;
+    char_u	*result;
+    char_u	*resultbuf = NULL;
+    int		resultlen;
+    buf_T	*buf;
+    int		valid = VALID_HEAD + VALID_PATH;    /* assume valid result */
+    int		spec_idx;
+#ifdef FEAT_MODIFY_FNAME
+    int		skip_mod = FALSE;
+#endif
+    static char *(spec_str[]) =
+	{
+		    "%",
+#define SPEC_PERC   0
+		    "#",
+#define SPEC_HASH   1
+		    "<cword>",		/* cursor word */
+#define SPEC_CWORD  2
+		    "<cWORD>",		/* cursor WORD */
+#define SPEC_CCWORD 3
+		    "<cfile>",		/* cursor path name */
+#define SPEC_CFILE  4
+		    "<sfile>",		/* ":so" file name */
+#define SPEC_SFILE  5
+#ifdef FEAT_AUTOCMD
+		    "<afile>",		/* autocommand file name */
+# define SPEC_AFILE 6
+		    "<abuf>",		/* autocommand buffer number */
+# define SPEC_ABUF  7
+		    "<amatch>",		/* autocommand match name */
+# define SPEC_AMATCH 8
+#endif
+#ifdef FEAT_CLIENTSERVER
+		    "<client>"
+# define SPEC_CLIENT 9
+#endif
+		};
+#define SPEC_COUNT  (sizeof(spec_str) / sizeof(char *))
+
+#if defined(FEAT_AUTOCMD) || defined(FEAT_CLIENTSERVER)
+    char_u	strbuf[30];
+#endif
+
+    *errormsg = NULL;
+    if (escaped != NULL)
+	*escaped = FALSE;
+
+    /*
+     * Check if there is something to do.
+     */
+    for (spec_idx = 0; spec_idx < SPEC_COUNT; ++spec_idx)
+    {
+	*usedlen = (int)STRLEN(spec_str[spec_idx]);
+	if (STRNCMP(src, spec_str[spec_idx], *usedlen) == 0)
+	    break;
+    }
+    if (spec_idx == SPEC_COUNT)	    /* no match */
+    {
+	*usedlen = 1;
+	return NULL;
+    }
+
+    /*
+     * Skip when preceded with a backslash "\%" and "\#".
+     * Note: In "\\%" the % is also not recognized!
+     */
+    if (src > srcstart && src[-1] == '\\')
+    {
+	*usedlen = 0;
+	STRCPY(src - 1, src);		/* remove backslash */
+	return NULL;
+    }
+
+    /*
+     * word or WORD under cursor
+     */
+    if (spec_idx == SPEC_CWORD || spec_idx == SPEC_CCWORD)
+    {
+	resultlen = find_ident_under_cursor(&result, spec_idx == SPEC_CWORD ?
+				      (FIND_IDENT|FIND_STRING) : FIND_STRING);
+	if (resultlen == 0)
+	{
+	    *errormsg = (char_u *)"";
+	    return NULL;
+	}
+    }
+
+    /*
+     * '#': Alternate file name
+     * '%': Current file name
+     *	    File name under the cursor
+     *	    File name for autocommand
+     *	and following modifiers
+     */
+    else
+    {
+	switch (spec_idx)
+	{
+	case SPEC_PERC:		/* '%': current file */
+		if (curbuf->b_fname == NULL)
+		{
+		    result = (char_u *)"";
+		    valid = 0;	    /* Must have ":p:h" to be valid */
+		}
+		else
+#ifdef RISCOS
+		    /* Always use the full path for RISC OS if possible. */
+		    result = curbuf->b_ffname;
+		    if (result == NULL)
+			result = curbuf->b_fname;
+#else
+		    result = curbuf->b_fname;
+#endif
+		break;
+
+	case SPEC_HASH:		/* '#' or "#99": alternate file */
+		if (src[1] == '#')  /* "##": the argument list */
+		{
+		    result = arg_all();
+		    resultbuf = result;
+		    *usedlen = 2;
+		    if (escaped != NULL)
+			*escaped = TRUE;
+#ifdef FEAT_MODIFY_FNAME
+		    skip_mod = TRUE;
+#endif
+		    break;
+		}
+		s = src + 1;
+		i = (int)getdigits(&s);
+		*usedlen = (int)(s - src); /* length of what we expand */
+
+		buf = buflist_findnr(i);
+		if (buf == NULL)
+		{
+		    *errormsg = (char_u *)_("E194: No alternate file name to substitute for '#'");
+		    return NULL;
+		}
+		if (lnump != NULL)
+		    *lnump = ECMD_LAST;
+		if (buf->b_fname == NULL)
+		{
+		    result = (char_u *)"";
+		    valid = 0;	    /* Must have ":p:h" to be valid */
+		}
+		else
+		    result = buf->b_fname;
+		break;
+
+#ifdef FEAT_SEARCHPATH
+	case SPEC_CFILE:	/* file name under cursor */
+		result = file_name_at_cursor(FNAME_MESS|FNAME_HYP, 1L, NULL);
+		if (result == NULL)
+		{
+		    *errormsg = (char_u *)"";
+		    return NULL;
+		}
+		resultbuf = result;	    /* remember allocated string */
+		break;
+#endif
+
+#ifdef FEAT_AUTOCMD
+	case SPEC_AFILE:	/* file name for autocommand */
+		result = autocmd_fname;
+		if (result == NULL)
+		{
+		    *errormsg = (char_u *)_("E495: no autocommand file name to substitute for \"<afile>\"");
+		    return NULL;
+		}
+		break;
+
+	case SPEC_ABUF:		/* buffer number for autocommand */
+		if (autocmd_bufnr <= 0)
+		{
+		    *errormsg = (char_u *)_("E496: no autocommand buffer number to substitute for \"<abuf>\"");
+		    return NULL;
+		}
+		sprintf((char *)strbuf, "%d", autocmd_bufnr);
+		result = strbuf;
+		break;
+
+	case SPEC_AMATCH:	/* match name for autocommand */
+		result = autocmd_match;
+		if (result == NULL)
+		{
+		    *errormsg = (char_u *)_("E497: no autocommand match name to substitute for \"<amatch>\"");
+		    return NULL;
+		}
+		break;
+
+#endif
+	case SPEC_SFILE:	/* file name for ":so" command */
+		result = sourcing_name;
+		if (result == NULL)
+		{
+		    *errormsg = (char_u *)_("E498: no :source file name to substitute for \"<sfile>\"");
+		    return NULL;
+		}
+		break;
+#if defined(FEAT_CLIENTSERVER)
+	case SPEC_CLIENT:	/* Source of last submitted input */
+		sprintf((char *)strbuf, PRINTF_HEX_LONG_U,
+							(long_u)clientWindow);
+		result = strbuf;
+		break;
+#endif
+	}
+
+	resultlen = (int)STRLEN(result);	/* length of new string */
+	if (src[*usedlen] == '<')	/* remove the file name extension */
+	{
+	    ++*usedlen;
+#ifdef RISCOS
+	    if ((s = vim_strrchr(result, '/')) != NULL && s >= gettail(result))
+#else
+	    if ((s = vim_strrchr(result, '.')) != NULL && s >= gettail(result))
+#endif
+		resultlen = (int)(s - result);
+	}
+#ifdef FEAT_MODIFY_FNAME
+	else if (!skip_mod)
+	{
+	    valid |= modify_fname(src, usedlen, &result, &resultbuf,
+								  &resultlen);
+	    if (result == NULL)
+	    {
+		*errormsg = (char_u *)"";
+		return NULL;
+	    }
+	}
+#endif
+    }
+
+    if (resultlen == 0 || valid != VALID_HEAD + VALID_PATH)
+    {
+	if (valid != VALID_HEAD + VALID_PATH)
+	    /* xgettext:no-c-format */
+	    *errormsg = (char_u *)_("E499: Empty file name for '%' or '#', only works with \":p:h\"");
+	else
+	    *errormsg = (char_u *)_("E500: Evaluates to an empty string");
+	result = NULL;
+    }
+    else
+	result = vim_strnsave(result, resultlen);
+    vim_free(resultbuf);
+    return result;
+}
+
+/*
+ * Concatenate all files in the argument list, separated by spaces, and return
+ * it in one allocated string.
+ * Spaces and backslashes in the file names are escaped with a backslash.
+ * Returns NULL when out of memory.
+ */
+    static char_u *
+arg_all()
+{
+    int		len;
+    int		idx;
+    char_u	*retval = NULL;
+    char_u	*p;
+
+    /*
+     * Do this loop two times:
+     * first time: compute the total length
+     * second time: concatenate the names
+     */
+    for (;;)
+    {
+	len = 0;
+	for (idx = 0; idx < ARGCOUNT; ++idx)
+	{
+	    p = alist_name(&ARGLIST[idx]);
+	    if (p != NULL)
+	    {
+		if (len > 0)
+		{
+		    /* insert a space in between names */
+		    if (retval != NULL)
+			retval[len] = ' ';
+		    ++len;
+		}
+		for ( ; *p != NUL; ++p)
+		{
+		    if (*p == ' ' || *p == '\\')
+		    {
+			/* insert a backslash */
+			if (retval != NULL)
+			    retval[len] = '\\';
+			++len;
+		    }
+		    if (retval != NULL)
+			retval[len] = *p;
+		    ++len;
+		}
+	    }
+	}
+
+	/* second time: break here */
+	if (retval != NULL)
+	{
+	    retval[len] = NUL;
+	    break;
+	}
+
+	/* allocate memory */
+	retval = alloc(len + 1);
+	if (retval == NULL)
+	    break;
+    }
+
+    return retval;
+}
+
+#if defined(FEAT_AUTOCMD) || defined(PROTO)
+/*
+ * Expand the <sfile> string in "arg".
+ *
+ * Returns an allocated string, or NULL for any error.
+ */
+    char_u *
+expand_sfile(arg)
+    char_u	*arg;
+{
+    char_u	*errormsg;
+    int		len;
+    char_u	*result;
+    char_u	*newres;
+    char_u	*repl;
+    int		srclen;
+    char_u	*p;
+
+    result = vim_strsave(arg);
+    if (result == NULL)
+	return NULL;
+
+    for (p = result; *p; )
+    {
+	if (STRNCMP(p, "<sfile>", 7) != 0)
+	    ++p;
+	else
+	{
+	    /* replace "<sfile>" with the sourced file name, and do ":" stuff */
+	    repl = eval_vars(p, result, &srclen, NULL, &errormsg, NULL);
+	    if (errormsg != NULL)
+	    {
+		if (*errormsg)
+		    emsg(errormsg);
+		vim_free(result);
+		return NULL;
+	    }
+	    if (repl == NULL)		/* no match (cannot happen) */
+	    {
+		p += srclen;
+		continue;
+	    }
+	    len = (int)STRLEN(result) - srclen + (int)STRLEN(repl) + 1;
+	    newres = alloc(len);
+	    if (newres == NULL)
+	    {
+		vim_free(repl);
+		vim_free(result);
+		return NULL;
+	    }
+	    mch_memmove(newres, result, (size_t)(p - result));
+	    STRCPY(newres + (p - result), repl);
+	    len = (int)STRLEN(newres);
+	    STRCAT(newres, p + srclen);
+	    vim_free(repl);
+	    vim_free(result);
+	    result = newres;
+	    p = newres + len;		/* continue after the match */
+	}
+    }
+
+    return result;
+}
+#endif
+
+#ifdef FEAT_SESSION
+static int ses_winsizes __ARGS((FILE *fd, int restore_size,
+							win_T *tab_firstwin));
+static int ses_win_rec __ARGS((FILE *fd, frame_T *fr));
+static frame_T *ses_skipframe __ARGS((frame_T *fr));
+static int ses_do_frame __ARGS((frame_T *fr));
+static int ses_do_win __ARGS((win_T *wp));
+static int ses_arglist __ARGS((FILE *fd, char *cmd, garray_T *gap, int fullname, unsigned *flagp));
+static int ses_put_fname __ARGS((FILE *fd, char_u *name, unsigned *flagp));
+static int ses_fname __ARGS((FILE *fd, buf_T *buf, unsigned *flagp));
+
+/*
+ * Write openfile commands for the current buffers to an .exrc file.
+ * Return FAIL on error, OK otherwise.
+ */
+    static int
+makeopens(fd, dirnow)
+    FILE	*fd;
+    char_u	*dirnow;	/* Current directory name */
+{
+    buf_T	*buf;
+    int		only_save_windows = TRUE;
+    int		nr;
+    int		cnr = 1;
+    int		restore_size = TRUE;
+    win_T	*wp;
+    char_u	*sname;
+    win_T	*edited_win = NULL;
+    int		tabnr;
+    win_T	*tab_firstwin;
+    frame_T	*tab_topframe;
+
+    if (ssop_flags & SSOP_BUFFERS)
+	only_save_windows = FALSE;		/* Save ALL buffers */
+
+    /*
+     * Begin by setting the this_session variable, and then other
+     * sessionable variables.
+     */
+#ifdef FEAT_EVAL
+    if (put_line(fd, "let v:this_session=expand(\"<sfile>:p\")") == FAIL)
+	return FAIL;
+    if (ssop_flags & SSOP_GLOBALS)
+	if (store_session_globals(fd) == FAIL)
+	    return FAIL;
+#endif
+
+    /*
+     * Close all windows but one.
+     */
+    if (put_line(fd, "silent only") == FAIL)
+	return FAIL;
+
+    /*
+     * Now a :cd command to the session directory or the current directory
+     */
+    if (ssop_flags & SSOP_SESDIR)
+    {
+	if (put_line(fd, "exe \"cd \" . escape(expand(\"<sfile>:p:h\"), ' ')")
+								      == FAIL)
+	    return FAIL;
+    }
+    else if (ssop_flags & SSOP_CURDIR)
+    {
+	sname = home_replace_save(NULL, globaldir != NULL ? globaldir : dirnow);
+	if (sname == NULL
+		|| fputs("cd ", fd) < 0
+		|| ses_put_fname(fd, sname, &ssop_flags) == FAIL
+		|| put_eol(fd) == FAIL)
+	{
+	    vim_free(sname);
+	    return FAIL;
+	}
+	vim_free(sname);
+    }
+
+    /*
+     * If there is an empty, unnamed buffer we will wipe it out later.
+     * Remember the buffer number.
+     */
+    if (put_line(fd, "if expand('%') == '' && !&modified && line('$') <= 1 && getline(1) == ''") == FAIL)
+	return FAIL;
+    if (put_line(fd, "  let s:wipebuf = bufnr('%')") == FAIL)
+	return FAIL;
+    if (put_line(fd, "endif") == FAIL)
+	return FAIL;
+
+    /*
+     * Now save the current files, current buffer first.
+     */
+    if (put_line(fd, "set shortmess=aoO") == FAIL)
+	return FAIL;
+
+    /* Now put the other buffers into the buffer list */
+    for (buf = firstbuf; buf != NULL; buf = buf->b_next)
+    {
+	if (!(only_save_windows && buf->b_nwindows == 0)
+		&& !(buf->b_help && !(ssop_flags & SSOP_HELP))
+		&& buf->b_fname != NULL
+		&& buf->b_p_bl)
+	{
+	    if (fprintf(fd, "badd +%ld ", buf->b_wininfo == NULL ? 1L
+					   : buf->b_wininfo->wi_fpos.lnum) < 0
+		    || ses_fname(fd, buf, &ssop_flags) == FAIL)
+		return FAIL;
+	}
+    }
+
+    /* the global argument list */
+    if (ses_arglist(fd, "args", &global_alist.al_ga,
+			    !(ssop_flags & SSOP_CURDIR), &ssop_flags) == FAIL)
+	return FAIL;
+
+    if (ssop_flags & SSOP_RESIZE)
+    {
+	/* Note: after the restore we still check it worked!*/
+	if (fprintf(fd, "set lines=%ld columns=%ld" , Rows, Columns) < 0
+		|| put_eol(fd) == FAIL)
+	    return FAIL;
+    }
+
+#ifdef FEAT_GUI
+    if (gui.in_use && (ssop_flags & SSOP_WINPOS))
+    {
+	int	x, y;
+
+	if (gui_mch_get_winpos(&x, &y) == OK)
+	{
+	    /* Note: after the restore we still check it worked!*/
+	    if (fprintf(fd, "winpos %d %d", x, y) < 0 || put_eol(fd) == FAIL)
+		return FAIL;
+	}
+    }
+#endif
+
+    /*
+     * May repeat putting Windows for each tab, when "tabpages" is in
+     * 'sessionoptions'.
+     * Don't use goto_tabpage(), it may change directory and trigger
+     * autocommands.
+     */
+    tab_firstwin = firstwin;	/* first window in tab page "tabnr" */
+    tab_topframe = topframe;
+    for (tabnr = 1; ; ++tabnr)
+    {
+	int  need_tabnew = FALSE;
+
+	if ((ssop_flags & SSOP_TABPAGES))
+	{
+	    tabpage_T *tp = find_tabpage(tabnr);
+
+	    if (tp == NULL)
+		break;		/* done all tab pages */
+	    if (tp == curtab)
+	    {
+		tab_firstwin = firstwin;
+		tab_topframe = topframe;
+	    }
+	    else
+	    {
+		tab_firstwin = tp->tp_firstwin;
+		tab_topframe = tp->tp_topframe;
+	    }
+	    if (tabnr > 1)
+		need_tabnew = TRUE;
+	}
+
+	/*
+	 * Before creating the window layout, try loading one file.  If this
+	 * is aborted we don't end up with a number of useless windows.
+	 * This may have side effects! (e.g., compressed or network file).
+	 */
+	for (wp = tab_firstwin; wp != NULL; wp = wp->w_next)
+	{
+	    if (ses_do_win(wp)
+		    && wp->w_buffer->b_ffname != NULL
+		    && !wp->w_buffer->b_help
+#ifdef FEAT_QUICKFIX
+		    && !bt_nofile(wp->w_buffer)
+#endif
+		    )
+	    {
+		if (fputs(need_tabnew ? "tabedit " : "edit ", fd) < 0
+			|| ses_fname(fd, wp->w_buffer, &ssop_flags) == FAIL)
+		    return FAIL;
+		need_tabnew = FALSE;
+		if (!wp->w_arg_idx_invalid)
+		    edited_win = wp;
+		break;
+	    }
+	}
+
+	/* If no file got edited create an empty tab page. */
+	if (need_tabnew && put_line(fd, "tabnew") == FAIL)
+	    return FAIL;
+
+	/*
+	 * Save current window layout.
+	 */
+	if (put_line(fd, "set splitbelow splitright") == FAIL)
+	    return FAIL;
+	if (ses_win_rec(fd, tab_topframe) == FAIL)
+	    return FAIL;
+	if (!p_sb && put_line(fd, "set nosplitbelow") == FAIL)
+	    return FAIL;
+	if (!p_spr && put_line(fd, "set nosplitright") == FAIL)
+	    return FAIL;
+
+	/*
+	 * Check if window sizes can be restored (no windows omitted).
+	 * Remember the window number of the current window after restoring.
+	 */
+	nr = 0;
+	for (wp = tab_firstwin; wp != NULL; wp = W_NEXT(wp))
+	{
+	    if (ses_do_win(wp))
+		++nr;
+	    else
+		restore_size = FALSE;
+	    if (curwin == wp)
+		cnr = nr;
+	}
+
+	/* Go to the first window. */
+	if (put_line(fd, "wincmd t") == FAIL)
+	    return FAIL;
+
+	/*
+	 * If more than one window, see if sizes can be restored.
+	 * First set 'winheight' and 'winwidth' to 1 to avoid the windows being
+	 * resized when moving between windows.
+	 * Do this before restoring the view, so that the topline and the
+	 * cursor can be set.  This is done again below.
+	 */
+	if (put_line(fd, "set winheight=1 winwidth=1") == FAIL)
+	    return FAIL;
+	if (nr > 1 && ses_winsizes(fd, restore_size, tab_firstwin) == FAIL)
+	    return FAIL;
+
+	/*
+	 * Restore the view of the window (options, file, cursor, etc.).
+	 */
+	for (wp = tab_firstwin; wp != NULL; wp = wp->w_next)
+	{
+	    if (!ses_do_win(wp))
+		continue;
+	    if (put_view(fd, wp, wp != edited_win, &ssop_flags) == FAIL)
+		return FAIL;
+	    if (nr > 1 && put_line(fd, "wincmd w") == FAIL)
+		return FAIL;
+	}
+
+	/*
+	 * Restore cursor to the current window if it's not the first one.
+	 */
+	if (cnr > 1 && (fprintf(fd, "%dwincmd w", cnr) < 0
+						      || put_eol(fd) == FAIL))
+	    return FAIL;
+
+	/*
+	 * Restore window sizes again after jumping around in windows, because
+	 * the current window has a minimum size while others may not.
+	 */
+	if (nr > 1 && ses_winsizes(fd, restore_size, tab_firstwin) == FAIL)
+	    return FAIL;
+
+	/* Don't continue in another tab page when doing only the current one
+	 * or when at the last tab page. */
+	if (!(ssop_flags & SSOP_TABPAGES))
+	    break;
+    }
+
+    if (ssop_flags & SSOP_TABPAGES)
+    {
+	if (fprintf(fd, "tabnext %d", tabpage_index(curtab)) < 0
+		|| put_eol(fd) == FAIL)
+	    return FAIL;
+    }
+
+    /*
+     * Wipe out an empty unnamed buffer we started in.
+     */
+    if (put_line(fd, "if exists('s:wipebuf')") == FAIL)
+	return FAIL;
+    if (put_line(fd, "  silent exe 'bwipe ' . s:wipebuf") == FAIL)
+	return FAIL;
+    if (put_line(fd, "endif") == FAIL)
+	return FAIL;
+    if (put_line(fd, "unlet! s:wipebuf") == FAIL)
+	return FAIL;
+
+    /* Re-apply 'winheight', 'winwidth' and 'shortmess'. */
+    if (fprintf(fd, "set winheight=%ld winwidth=%ld shortmess=%s",
+			       p_wh, p_wiw, p_shm) < 0 || put_eol(fd) == FAIL)
+	return FAIL;
+
+    /*
+     * Lastly, execute the x.vim file if it exists.
+     */
+    if (put_line(fd, "let s:sx = expand(\"<sfile>:p:r\").\"x.vim\"") == FAIL
+	    || put_line(fd, "if file_readable(s:sx)") == FAIL
+	    || put_line(fd, "  exe \"source \" . s:sx") == FAIL
+	    || put_line(fd, "endif") == FAIL)
+	return FAIL;
+
+    return OK;
+}
+
+    static int
+ses_winsizes(fd, restore_size, tab_firstwin)
+    FILE	*fd;
+    int		restore_size;
+    win_T	*tab_firstwin;
+{
+    int		n = 0;
+    win_T	*wp;
+
+    if (restore_size && (ssop_flags & SSOP_WINSIZE))
+    {
+	for (wp = tab_firstwin; wp != NULL; wp = wp->w_next)
+	{
+	    if (!ses_do_win(wp))
+		continue;
+	    ++n;
+
+	    /* restore height when not full height */
+	    if (wp->w_height + wp->w_status_height < topframe->fr_height
+		    && (fprintf(fd,
+			  "exe '%dresize ' . ((&lines * %ld + %ld) / %ld)",
+			    n, (long)wp->w_height, Rows / 2, Rows) < 0
+						  || put_eol(fd) == FAIL))
+		return FAIL;
+
+	    /* restore width when not full width */
+	    if (wp->w_width < Columns && (fprintf(fd,
+		   "exe 'vert %dresize ' . ((&columns * %ld + %ld) / %ld)",
+			    n, (long)wp->w_width, Columns / 2, Columns) < 0
+						  || put_eol(fd) == FAIL))
+		return FAIL;
+	}
+    }
+    else
+    {
+	/* Just equalise window sizes */
+	if (put_line(fd, "wincmd =") == FAIL)
+	    return FAIL;
+    }
+    return OK;
+}
+
+/*
+ * Write commands to "fd" to recursively create windows for frame "fr",
+ * horizontally and vertically split.
+ * After the commands the last window in the frame is the current window.
+ * Returns FAIL when writing the commands to "fd" fails.
+ */
+    static int
+ses_win_rec(fd, fr)
+    FILE	*fd;
+    frame_T	*fr;
+{
+    frame_T	*frc;
+    int		count = 0;
+
+    if (fr->fr_layout != FR_LEAF)
+    {
+	/* Find first frame that's not skipped and then create a window for
+	 * each following one (first frame is already there). */
+	frc = ses_skipframe(fr->fr_child);
+	if (frc != NULL)
+	    while ((frc = ses_skipframe(frc->fr_next)) != NULL)
+	    {
+		/* Make window as big as possible so that we have lots of room
+		 * to split. */
+		if (put_line(fd, "wincmd _ | wincmd |") == FAIL
+			|| put_line(fd, fr->fr_layout == FR_COL
+						? "split" : "vsplit") == FAIL)
+		    return FAIL;
+		++count;
+	    }
+
+	/* Go back to the first window. */
+	if (count > 0 && (fprintf(fd, fr->fr_layout == FR_COL
+			? "%dwincmd k" : "%dwincmd h", count) < 0
+						      || put_eol(fd) == FAIL))
+	    return FAIL;
+
+	/* Recursively create frames/windows in each window of this column or
+	 * row. */
+	frc = ses_skipframe(fr->fr_child);
+	while (frc != NULL)
+	{
+	    ses_win_rec(fd, frc);
+	    frc = ses_skipframe(frc->fr_next);
+	    /* Go to next window. */
+	    if (frc != NULL && put_line(fd, "wincmd w") == FAIL)
+		return FAIL;
+	}
+    }
+    return OK;
+}
+
+/*
+ * Skip frames that don't contain windows we want to save in the Session.
+ * Returns NULL when there none.
+ */
+    static frame_T *
+ses_skipframe(fr)
+    frame_T	*fr;
+{
+    frame_T	*frc;
+
+    for (frc = fr; frc != NULL; frc = frc->fr_next)
+	if (ses_do_frame(frc))
+	    break;
+    return frc;
+}
+
+/*
+ * Return TRUE if frame "fr" has a window somewhere that we want to save in
+ * the Session.
+ */
+    static int
+ses_do_frame(fr)
+    frame_T	*fr;
+{
+    frame_T	*frc;
+
+    if (fr->fr_layout == FR_LEAF)
+	return ses_do_win(fr->fr_win);
+    for (frc = fr->fr_child; frc != NULL; frc = frc->fr_next)
+	if (ses_do_frame(frc))
+	    return TRUE;
+    return FALSE;
+}
+
+/*
+ * Return non-zero if window "wp" is to be stored in the Session.
+ */
+    static int
+ses_do_win(wp)
+    win_T	*wp;
+{
+    if (wp->w_buffer->b_fname == NULL
+#ifdef FEAT_QUICKFIX
+	    /* When 'buftype' is "nofile" can't restore the window contents. */
+	    || bt_nofile(wp->w_buffer)
+#endif
+       )
+	return (ssop_flags & SSOP_BLANK);
+    if (wp->w_buffer->b_help)
+	return (ssop_flags & SSOP_HELP);
+    return TRUE;
+}
+
+/*
+ * Write commands to "fd" to restore the view of a window.
+ * Caller must make sure 'scrolloff' is zero.
+ */
+    static int
+put_view(fd, wp, add_edit, flagp)
+    FILE	*fd;
+    win_T	*wp;
+    int		add_edit;	/* add ":edit" command to view */
+    unsigned	*flagp;		/* vop_flags or ssop_flags */
+{
+    win_T	*save_curwin;
+    int		f;
+    int		do_cursor;
+    int		did_next = FALSE;
+
+    /* Always restore cursor position for ":mksession".  For ":mkview" only
+     * when 'viewoptions' contains "cursor". */
+    do_cursor = (flagp == &ssop_flags || *flagp & SSOP_CURSOR);
+
+    /*
+     * Local argument list.
+     */
+    if (wp->w_alist == &global_alist)
+    {
+	if (put_line(fd, "argglobal") == FAIL)
+	    return FAIL;
+    }
+    else
+    {
+	if (ses_arglist(fd, "arglocal", &wp->w_alist->al_ga,
+			flagp == &vop_flags
+			|| !(*flagp & SSOP_CURDIR)
+			|| wp->w_localdir != NULL, flagp) == FAIL)
+	    return FAIL;
+    }
+
+    /* Only when part of a session: restore the argument index.  Some
+     * arguments may have been deleted, check if the index is valid. */
+    if (wp->w_arg_idx != 0 && wp->w_arg_idx <= WARGCOUNT(wp)
+						      && flagp == &ssop_flags)
+    {
+	if (fprintf(fd, "%ldnext", (long)wp->w_arg_idx) < 0
+		|| put_eol(fd) == FAIL)
+	    return FAIL;
+	did_next = TRUE;
+    }
+
+    /* Edit the file.  Skip this when ":next" already did it. */
+    if (add_edit && (!did_next || wp->w_arg_idx_invalid))
+    {
+	/*
+	 * Load the file.
+	 */
+	if (wp->w_buffer->b_ffname != NULL
+#ifdef FEAT_QUICKFIX
+		&& !bt_nofile(wp->w_buffer)
+#endif
+		)
+	{
+	    /*
+	     * Editing a file in this buffer: use ":edit file".
+	     * This may have side effects! (e.g., compressed or network file).
+	     */
+	    if (fputs("edit ", fd) < 0
+		    || ses_fname(fd, wp->w_buffer, flagp) == FAIL)
+		return FAIL;
+	}
+	else
+	{
+	    /* No file in this buffer, just make it empty. */
+	    if (put_line(fd, "enew") == FAIL)
+		return FAIL;
+#ifdef FEAT_QUICKFIX
+	    if (wp->w_buffer->b_ffname != NULL)
+	    {
+		/* The buffer does have a name, but it's not a file name. */
+		if (fputs("file ", fd) < 0
+			|| ses_fname(fd, wp->w_buffer, flagp) == FAIL)
+		    return FAIL;
+	    }
+#endif
+	    do_cursor = FALSE;
+	}
+    }
+
+    /*
+     * Local mappings and abbreviations.
+     */
+    if ((*flagp & (SSOP_OPTIONS | SSOP_LOCALOPTIONS))
+					 && makemap(fd, wp->w_buffer) == FAIL)
+	return FAIL;
+
+    /*
+     * Local options.  Need to go to the window temporarily.
+     * Store only local values when using ":mkview" and when ":mksession" is
+     * used and 'sessionoptions' doesn't include "options".
+     * Some folding options are always stored when "folds" is included,
+     * otherwise the folds would not be restored correctly.
+     */
+    save_curwin = curwin;
+    curwin = wp;
+    curbuf = curwin->w_buffer;
+    if (*flagp & (SSOP_OPTIONS | SSOP_LOCALOPTIONS))
+	f = makeset(fd, OPT_LOCAL,
+			     flagp == &vop_flags || !(*flagp & SSOP_OPTIONS));
+#ifdef FEAT_FOLDING
+    else if (*flagp & SSOP_FOLDS)
+	f = makefoldset(fd);
+#endif
+    else
+	f = OK;
+    curwin = save_curwin;
+    curbuf = curwin->w_buffer;
+    if (f == FAIL)
+	return FAIL;
+
+#ifdef FEAT_FOLDING
+    /*
+     * Save Folds when 'buftype' is empty and for help files.
+     */
+    if ((*flagp & SSOP_FOLDS)
+	    && wp->w_buffer->b_ffname != NULL
+# ifdef FEAT_QUICKFIX
+	    && (*wp->w_buffer->b_p_bt == NUL || wp->w_buffer->b_help)
+# endif
+	    )
+    {
+	if (put_folds(fd, wp) == FAIL)
+	    return FAIL;
+    }
+#endif
+
+    /*
+     * Set the cursor after creating folds, since that moves the cursor.
+     */
+    if (do_cursor)
+    {
+
+	/* Restore the cursor line in the file and relatively in the
+	 * window.  Don't use "G", it changes the jumplist. */
+	if (fprintf(fd, "let s:l = %ld - ((%ld * winheight(0) + %ld) / %ld)",
+		    (long)wp->w_cursor.lnum,
+		    (long)(wp->w_cursor.lnum - wp->w_topline),
+		    (long)wp->w_height / 2, (long)wp->w_height) < 0
+		|| put_eol(fd) == FAIL
+		|| put_line(fd, "if s:l < 1 | let s:l = 1 | endif") == FAIL
+		|| put_line(fd, "exe s:l") == FAIL
+		|| put_line(fd, "normal! zt") == FAIL
+		|| fprintf(fd, "%ld", (long)wp->w_cursor.lnum) < 0
+		|| put_eol(fd) == FAIL)
+	    return FAIL;
+	/* Restore the cursor column and left offset when not wrapping. */
+	if (wp->w_cursor.col == 0)
+	{
+	    if (put_line(fd, "normal! 0") == FAIL)
+		return FAIL;
+	}
+	else
+	{
+	    if (!wp->w_p_wrap && wp->w_leftcol > 0 && wp->w_width > 0)
+	    {
+		if (fprintf(fd,
+			  "let s:c = %ld - ((%ld * winwidth(0) + %ld) / %ld)",
+			    (long)wp->w_cursor.col,
+			    (long)(wp->w_cursor.col - wp->w_leftcol),
+			    (long)wp->w_width / 2, (long)wp->w_width) < 0
+			|| put_eol(fd) == FAIL
+			|| put_line(fd, "if s:c > 0") == FAIL
+			|| fprintf(fd,
+			    "  exe 'normal! 0' . s:c . 'lzs' . (%ld - s:c) . 'l'",
+			    (long)wp->w_cursor.col) < 0
+			|| put_eol(fd) == FAIL
+			|| put_line(fd, "else") == FAIL
+			|| fprintf(fd, "  normal! 0%dl", wp->w_cursor.col) < 0
+			|| put_eol(fd) == FAIL
+			|| put_line(fd, "endif") == FAIL)
+		    return FAIL;
+	    }
+	    else
+	    {
+		if (fprintf(fd, "normal! 0%dl", wp->w_cursor.col) < 0
+			|| put_eol(fd) == FAIL)
+		    return FAIL;
+	    }
+	}
+    }
+
+    /*
+     * Local directory.
+     */
+    if (wp->w_localdir != NULL)
+    {
+	if (fputs("lcd ", fd) < 0
+		|| ses_put_fname(fd, wp->w_localdir, flagp) == FAIL
+		|| put_eol(fd) == FAIL)
+	    return FAIL;
+	did_lcd = TRUE;
+    }
+
+    return OK;
+}
+
+/*
+ * Write an argument list to the session file.
+ * Returns FAIL if writing fails.
+ */
+    static int
+ses_arglist(fd, cmd, gap, fullname, flagp)
+    FILE	*fd;
+    char	*cmd;
+    garray_T	*gap;
+    int		fullname;	/* TRUE: use full path name */
+    unsigned	*flagp;
+{
+    int		i;
+    char_u	buf[MAXPATHL];
+    char_u	*s;
+
+    if (gap->ga_len == 0)
+	return put_line(fd, "silent! argdel *");
+    if (fputs(cmd, fd) < 0)
+	return FAIL;
+    for (i = 0; i < gap->ga_len; ++i)
+    {
+	/* NULL file names are skipped (only happens when out of memory). */
+	s = alist_name(&((aentry_T *)gap->ga_data)[i]);
+	if (s != NULL)
+	{
+	    if (fullname)
+	    {
+		(void)vim_FullName(s, buf, MAXPATHL, FALSE);
+		s = buf;
+	    }
+	    if (fputs(" ", fd) < 0 || ses_put_fname(fd, s, flagp) == FAIL)
+		return FAIL;
+	}
+    }
+    return put_eol(fd);
+}
+
+/*
+ * Write a buffer name to the session file.
+ * Also ends the line.
+ * Returns FAIL if writing fails.
+ */
+    static int
+ses_fname(fd, buf, flagp)
+    FILE	*fd;
+    buf_T	*buf;
+    unsigned	*flagp;
+{
+    char_u	*name;
+
+    /* Use the short file name if the current directory is known at the time
+     * the session file will be sourced.
+     * Don't do this for ":mkview", we don't know the current directory.
+     * Don't do this after ":lcd", we don't keep track of what the current
+     * directory is. */
+    if (buf->b_sfname != NULL
+	    && flagp == &ssop_flags
+	    && (ssop_flags & (SSOP_CURDIR | SSOP_SESDIR))
+	    && !did_lcd)
+	name = buf->b_sfname;
+    else
+	name = buf->b_ffname;
+    if (ses_put_fname(fd, name, flagp) == FAIL || put_eol(fd) == FAIL)
+	return FAIL;
+    return OK;
+}
+
+/*
+ * Write a file name to the session file.
+ * Takes care of the "slash" option in 'sessionoptions' and escapes special
+ * characters.
+ * Returns FAIL if writing fails.
+ */
+    static int
+ses_put_fname(fd, name, flagp)
+    FILE	*fd;
+    char_u	*name;
+    unsigned	*flagp;
+{
+    char_u	*sname;
+    int		retval = OK;
+    int		c;
+
+    sname = home_replace_save(NULL, name);
+    if (sname != NULL)
+	name = sname;
+    while (*name != NUL)
+    {
+#ifdef FEAT_MBYTE
+	{
+	    int l;
+
+	    if (has_mbyte && (l = (*mb_ptr2len)(name)) > 1)
+	    {
+		/* copy a multibyte char */
+		while (--l >= 0)
+		{
+		    if (putc(*name, fd) != *name)
+			retval = FAIL;
+		    ++name;
+		}
+		continue;
+	    }
+	}
+#endif
+	c = *name++;
+	if (c == '\\' && (*flagp & SSOP_SLASH))
+	    /* change a backslash to a forward slash */
+	    c = '/';
+	else if ((vim_strchr(escape_chars, c) != NULL
+#ifdef BACKSLASH_IN_FILENAME
+		    && c != '\\'
+#endif
+		 ) || c == '#' || c == '%')
+	{
+	    /* escape a special character with a backslash */
+	    if (putc('\\', fd) != '\\')
+		retval = FAIL;
+	}
+	if (putc(c, fd) != c)
+	    retval = FAIL;
+    }
+    vim_free(sname);
+    return retval;
+}
+
+/*
+ * ":loadview [nr]"
+ */
+    static void
+ex_loadview(eap)
+    exarg_T	*eap;
+{
+    char_u	*fname;
+
+    fname = get_view_file(*eap->arg);
+    if (fname != NULL)
+    {
+	do_source(fname, FALSE, DOSO_NONE);
+	vim_free(fname);
+    }
+}
+
+/*
+ * Get the name of the view file for the current buffer.
+ */
+    static char_u *
+get_view_file(c)
+    int		c;
+{
+    int		len = 0;
+    char_u	*p, *s;
+    char_u	*retval;
+    char_u	*sname;
+
+    if (curbuf->b_ffname == NULL)
+    {
+	EMSG(_(e_noname));
+	return NULL;
+    }
+    sname = home_replace_save(NULL, curbuf->b_ffname);
+    if (sname == NULL)
+	return NULL;
+
+    /*
+     * We want a file name without separators, because we're not going to make
+     * a directory.
+     * "normal" path separator	-> "=+"
+     * "="			-> "=="
+     * ":" path separator	-> "=-"
+     */
+    for (p = sname; *p; ++p)
+	if (*p == '=' || vim_ispathsep(*p))
+	    ++len;
+    retval = alloc((unsigned)(STRLEN(sname) + len + STRLEN(p_vdir) + 9));
+    if (retval != NULL)
+    {
+	STRCPY(retval, p_vdir);
+	add_pathsep(retval);
+	s = retval + STRLEN(retval);
+	for (p = sname; *p; ++p)
+	{
+	    if (*p == '=')
+	    {
+		*s++ = '=';
+		*s++ = '=';
+	    }
+	    else if (vim_ispathsep(*p))
+	    {
+		*s++ = '=';
+#if defined(BACKSLASH_IN_FILENAME) || defined(AMIGA) || defined(RISCOS) \
+	|| defined(VMS)
+		if (*p == ':')
+		    *s++ = '-';
+		else
+#endif
+		    *s++ = '+';
+	    }
+	    else
+		*s++ = *p;
+	}
+	*s++ = '=';
+	*s++ = c;
+	STRCPY(s, ".vim");
+    }
+
+    vim_free(sname);
+    return retval;
+}
+
+#endif /* FEAT_SESSION */
+
+/*
+ * Write end-of-line character(s) for ":mkexrc", ":mkvimrc" and ":mksession".
+ * Return FAIL for a write error.
+ */
+    int
+put_eol(fd)
+    FILE	*fd;
+{
+    if (
+#ifdef USE_CRNL
+	    (
+# ifdef MKSESSION_NL
+	     !mksession_nl &&
+# endif
+	     (putc('\r', fd) < 0)) ||
+#endif
+	    (putc('\n', fd) < 0))
+	return FAIL;
+    return OK;
+}
+
+/*
+ * Write a line to "fd".
+ * Return FAIL for a write error.
+ */
+    int
+put_line(fd, s)
+    FILE	*fd;
+    char	*s;
+{
+    if (fputs(s, fd) < 0 || put_eol(fd) == FAIL)
+	return FAIL;
+    return OK;
+}
+
+#ifdef FEAT_VIMINFO
+/*
+ * ":rviminfo" and ":wviminfo".
+ */
+    static void
+ex_viminfo(eap)
+    exarg_T	*eap;
+{
+    char_u	*save_viminfo;
+
+    save_viminfo = p_viminfo;
+    if (*p_viminfo == NUL)
+	p_viminfo = (char_u *)"'100";
+    if (eap->cmdidx == CMD_rviminfo)
+    {
+	if (read_viminfo(eap->arg, TRUE, TRUE, eap->forceit) == FAIL)
+	    EMSG(_("E195: Cannot open viminfo file for reading"));
+    }
+    else
+	write_viminfo(eap->arg, eap->forceit);
+    p_viminfo = save_viminfo;
+}
+#endif
+
+#if defined(FEAT_GUI_DIALOG) || defined(FEAT_CON_DIALOG) || defined(PROTO)
+/*
+ * Make a dialog message in "buff[IOSIZE]".
+ * "format" must contain "%s".
+ */
+    void
+dialog_msg(buff, format, fname)
+    char_u	*buff;
+    char	*format;
+    char_u	*fname;
+{
+    if (fname == NULL)
+	fname = (char_u *)_("Untitled");
+    vim_snprintf((char *)buff, IOSIZE, format, fname);
+}
+#endif
+
+/*
+ * ":behave {mswin,xterm}"
+ */
+    static void
+ex_behave(eap)
+    exarg_T	*eap;
+{
+    if (STRCMP(eap->arg, "mswin") == 0)
+    {
+	set_option_value((char_u *)"selection", 0L, (char_u *)"exclusive", 0);
+	set_option_value((char_u *)"selectmode", 0L, (char_u *)"mouse,key", 0);
+	set_option_value((char_u *)"mousemodel", 0L, (char_u *)"popup", 0);
+	set_option_value((char_u *)"keymodel", 0L,
+					     (char_u *)"startsel,stopsel", 0);
+    }
+    else if (STRCMP(eap->arg, "xterm") == 0)
+    {
+	set_option_value((char_u *)"selection", 0L, (char_u *)"inclusive", 0);
+	set_option_value((char_u *)"selectmode", 0L, (char_u *)"", 0);
+	set_option_value((char_u *)"mousemodel", 0L, (char_u *)"extend", 0);
+	set_option_value((char_u *)"keymodel", 0L, (char_u *)"", 0);
+    }
+    else
+	EMSG2(_(e_invarg2), eap->arg);
+}
+
+#ifdef FEAT_AUTOCMD
+static int filetype_detect = FALSE;
+static int filetype_plugin = FALSE;
+static int filetype_indent = FALSE;
+
+/*
+ * ":filetype [plugin] [indent] {on,off,detect}"
+ * on: Load the filetype.vim file to install autocommands for file types.
+ * off: Load the ftoff.vim file to remove all autocommands for file types.
+ * plugin on: load filetype.vim and ftplugin.vim
+ * plugin off: load ftplugof.vim
+ * indent on: load filetype.vim and indent.vim
+ * indent off: load indoff.vim
+ */
+    static void
+ex_filetype(eap)
+    exarg_T	*eap;
+{
+    char_u	*arg = eap->arg;
+    int		plugin = FALSE;
+    int		indent = FALSE;
+
+    if (*eap->arg == NUL)
+    {
+	/* Print current status. */
+	smsg((char_u *)"filetype detection:%s  plugin:%s  indent:%s",
+		filetype_detect ? "ON" : "OFF",
+		filetype_plugin ? (filetype_detect ? "ON" : "(on)") : "OFF",
+		filetype_indent ? (filetype_detect ? "ON" : "(on)") : "OFF");
+	return;
+    }
+
+    /* Accept "plugin" and "indent" in any order. */
+    for (;;)
+    {
+	if (STRNCMP(arg, "plugin", 6) == 0)
+	{
+	    plugin = TRUE;
+	    arg = skipwhite(arg + 6);
+	    continue;
+	}
+	if (STRNCMP(arg, "indent", 6) == 0)
+	{
+	    indent = TRUE;
+	    arg = skipwhite(arg + 6);
+	    continue;
+	}
+	break;
+    }
+    if (STRCMP(arg, "on") == 0 || STRCMP(arg, "detect") == 0)
+    {
+	if (*arg == 'o' || !filetype_detect)
+	{
+	    source_runtime((char_u *)FILETYPE_FILE, TRUE);
+	    filetype_detect = TRUE;
+	    if (plugin)
+	    {
+		source_runtime((char_u *)FTPLUGIN_FILE, TRUE);
+		filetype_plugin = TRUE;
+	    }
+	    if (indent)
+	    {
+		source_runtime((char_u *)INDENT_FILE, TRUE);
+		filetype_indent = TRUE;
+	    }
+	}
+	if (*arg == 'd')
+	{
+	    (void)do_doautocmd((char_u *)"filetypedetect BufRead", TRUE);
+	    do_modelines(0);
+	}
+    }
+    else if (STRCMP(arg, "off") == 0)
+    {
+	if (plugin || indent)
+	{
+	    if (plugin)
+	    {
+		source_runtime((char_u *)FTPLUGOF_FILE, TRUE);
+		filetype_plugin = FALSE;
+	    }
+	    if (indent)
+	    {
+		source_runtime((char_u *)INDOFF_FILE, TRUE);
+		filetype_indent = FALSE;
+	    }
+	}
+	else
+	{
+	    source_runtime((char_u *)FTOFF_FILE, TRUE);
+	    filetype_detect = FALSE;
+	}
+    }
+    else
+	EMSG2(_(e_invarg2), arg);
+}
+
+/*
+ * ":setfiletype {name}"
+ */
+    static void
+ex_setfiletype(eap)
+    exarg_T	*eap;
+{
+    if (!did_filetype)
+	set_option_value((char_u *)"filetype", 0L, eap->arg, OPT_LOCAL);
+}
+#endif
+
+/*ARGSUSED*/
+    static void
+ex_digraphs(eap)
+    exarg_T	*eap;
+{
+#ifdef FEAT_DIGRAPHS
+    if (*eap->arg != NUL)
+	putdigraph(eap->arg);
+    else
+	listdigraphs();
+#else
+    EMSG(_("E196: No digraphs in this version"));
+#endif
+}
+
+    static void
+ex_set(eap)
+    exarg_T	*eap;
+{
+    int		flags = 0;
+
+    if (eap->cmdidx == CMD_setlocal)
+	flags = OPT_LOCAL;
+    else if (eap->cmdidx == CMD_setglobal)
+	flags = OPT_GLOBAL;
+#if defined(FEAT_EVAL) && defined(FEAT_AUTOCMD) && defined(FEAT_BROWSE)
+    if (cmdmod.browse && flags == 0)
+	ex_options(eap);
+    else
+#endif
+	(void)do_set(eap->arg, flags);
+}
+
+#ifdef FEAT_SEARCH_EXTRA
+/*
+ * ":nohlsearch"
+ */
+/*ARGSUSED*/
+    static void
+ex_nohlsearch(eap)
+    exarg_T	*eap;
+{
+    no_hlsearch = TRUE;
+    redraw_all_later(SOME_VALID);
+}
+
+/*
+ * ":[N]match {group} {pattern}"
+ * Sets nextcmd to the start of the next command, if any.  Also called when
+ * skipping commands to find the next command.
+ */
+    static void
+ex_match(eap)
+    exarg_T	*eap;
+{
+    char_u	*p;
+    char_u	*end;
+    int		c;
+    int		mi;
+
+    if (eap->line2 <= 3)
+	mi = eap->line2 - 1;
+    else
+    {
+	EMSG(e_invcmd);
+	return;
+    }
+
+    /* First clear any old pattern. */
+    if (!eap->skip)
+    {
+	vim_free(curwin->w_match[mi].regprog);
+	curwin->w_match[mi].regprog = NULL;
+	vim_free(curwin->w_match_pat[mi]);
+	curwin->w_match_pat[mi] = NULL;
+	redraw_later(SOME_VALID);	/* always need a redraw */
+    }
+
+    if (ends_excmd(*eap->arg))
+	end = eap->arg;
+    else if ((STRNICMP(eap->arg, "none", 4) == 0
+		&& (vim_iswhite(eap->arg[4]) || ends_excmd(eap->arg[4]))))
+	end = eap->arg + 4;
+    else
+    {
+	p = skiptowhite(eap->arg);
+	if (!eap->skip)
+	{
+	    curwin->w_match_id[mi] = syn_namen2id(eap->arg,
+							 (int)(p - eap->arg));
+	    if (curwin->w_match_id[mi] == 0)
+	    {
+		EMSG2(_(e_nogroup), eap->arg);
+		return;
+	    }
+	}
+	p = skipwhite(p);
+	if (*p == NUL)
+	{
+	    /* There must be two arguments. */
+	    EMSG2(_(e_invarg2), eap->arg);
+	    return;
+	}
+	end = skip_regexp(p + 1, *p, TRUE, NULL);
+	if (!eap->skip)
+	{
+	    if (*end != NUL && !ends_excmd(*skipwhite(end + 1)))
+	    {
+		eap->errmsg = e_trailing;
+		return;
+	    }
+	    if (*end != *p)
+	    {
+		EMSG2(_(e_invarg2), p);
+		return;
+	    }
+
+	    c = *end;
+	    *end = NUL;
+	    curwin->w_match[mi].regprog = vim_regcomp(p + 1, RE_MAGIC);
+	    if (curwin->w_match[mi].regprog == NULL)
+	    {
+		EMSG2(_(e_invarg2), p);
+		*end = c;
+		return;
+	    }
+	    curwin->w_match_pat[mi] = vim_strsave(p + 1);
+	    *end = c;
+	}
+    }
+    eap->nextcmd = find_nextcmd(end);
+}
+#endif
+
+#ifdef FEAT_CRYPT
+/*
+ * ":X": Get crypt key
+ */
+/*ARGSUSED*/
+    static void
+ex_X(eap)
+    exarg_T	*eap;
+{
+    (void)get_crypt_key(TRUE, TRUE);
+}
+#endif
+
+#ifdef FEAT_FOLDING
+    static void
+ex_fold(eap)
+    exarg_T	*eap;
+{
+    if (foldManualAllowed(TRUE))
+	foldCreate(eap->line1, eap->line2);
+}
+
+    static void
+ex_foldopen(eap)
+    exarg_T	*eap;
+{
+    opFoldRange(eap->line1, eap->line2, eap->cmdidx == CMD_foldopen,
+							 eap->forceit, FALSE);
+}
+
+    static void
+ex_folddo(eap)
+    exarg_T	*eap;
+{
+    linenr_T	lnum;
+
+    /* First set the marks for all lines closed/open. */
+    for (lnum = eap->line1; lnum <= eap->line2; ++lnum)
+	if (hasFolding(lnum, NULL, NULL) == (eap->cmdidx == CMD_folddoclosed))
+	    ml_setmarked(lnum);
+
+    /* Execute the command on the marked lines. */
+    global_exe(eap->arg);
+    ml_clearmarked();	   /* clear rest of the marks */
+}
+#endif
--- /dev/null
+++ b/ex_eval.c
@@ -1,0 +1,2281 @@
+/* vi:set ts=8 sts=4 sw=4:
+ *
+ * VIM - Vi IMproved	by Bram Moolenaar
+ *
+ * Do ":help uganda"  in Vim to read copying and usage conditions.
+ * Do ":help credits" in Vim to see a list of people who contributed.
+ * See README.txt for an overview of the Vim source code.
+ */
+
+/*
+ * ex_eval.c: functions for Ex command line for the +eval feature.
+ */
+
+#include "vim.h"
+
+#if defined(FEAT_EVAL) || defined(PROTO)
+
+static void	free_msglist __ARGS((struct msglist *l));
+static int	throw_exception __ARGS((void *, int, char_u *));
+static char_u	*get_end_emsg __ARGS((struct condstack *cstack));
+
+/*
+ * Exception handling terms:
+ *
+ *	:try		":try" command		\
+ *	    ...		try block		|
+ *	:catch RE	":catch" command	|
+ *	    ...		catch clause		|- try conditional
+ *	:finally	":finally" command	|
+ *	    ...		finally clause		|
+ *	:endtry		":endtry" command	/
+ *
+ * The try conditional may have any number of catch clauses and at most one
+ * finally clause.  A ":throw" command can be inside the try block, a catch
+ * clause, the finally clause, or in a function called or script sourced from
+ * there or even outside the try conditional.  Try conditionals may be nested.
+ */
+
+/*
+ * Configuration whether an exception is thrown on error or interrupt.  When
+ * the preprocessor macros below evaluate to FALSE, an error (did_emsg) or
+ * interrupt (got_int) under an active try conditional terminates the script
+ * after the non-active finally clauses of all active try conditionals have been
+ * executed.  Otherwise, errors and/or interrupts are converted into catchable
+ * exceptions (did_throw additionally set), which terminate the script only if
+ * not caught.  For user exceptions, only did_throw is set.  (Note: got_int can
+ * be set asyncronously afterwards by a SIGINT, so did_throw && got_int is not
+ * a reliant test that the exception currently being thrown is an interrupt
+ * exception.  Similarly, did_emsg can be set afterwards on an error in an
+ * (unskipped) conditional command inside an inactive conditional, so did_throw
+ * && did_emsg is not a reliant test that the exception currently being thrown
+ * is an error exception.)  -  The macros can be defined as expressions checking
+ * for a variable that is allowed to be changed during execution of a script.
+ */
+#if 0
+/* Expressions used for testing during the development phase. */
+# define THROW_ON_ERROR		(!eval_to_number("$VIMNOERRTHROW"))
+# define THROW_ON_INTERRUPT	(!eval_to_number("$VIMNOINTTHROW"))
+# define THROW_TEST
+#else
+/* Values used for the Vim release. */
+# define THROW_ON_ERROR		TRUE
+# define THROW_ON_INTERRUPT	TRUE
+#endif
+
+static void	catch_exception __ARGS((except_T *excp));
+static void	finish_exception __ARGS((except_T *excp));
+static void	discard_exception __ARGS((except_T *excp, int was_finished));
+static void	report_pending __ARGS((int action, int pending, void *value));
+
+/*
+ * When several errors appear in a row, setting "force_abort" is delayed until
+ * the failing command returned.  "cause_abort" is set to TRUE meanwhile, in
+ * order to indicate that situation.  This is useful when "force_abort" was set
+ * during execution of a function call from an expression: the aborting of the
+ * expression evaluation is done without producing any error messages, but all
+ * error messages on parsing errors during the expression evaluation are given
+ * (even if a try conditional is active).
+ */
+static int cause_abort = FALSE;
+
+/*
+ * Return TRUE when immediately aborting on error, or when an interrupt
+ * occurred or an exception was thrown but not caught.  Use for ":{range}call"
+ * to check whether an aborted function that does not handle a range itself
+ * should be called again for the next line in the range.  Also used for
+ * cancelling expression evaluation after a function call caused an immediate
+ * abort.  Note that the first emsg() call temporarily resets "force_abort"
+ * until the throw point for error messages has been reached.  That is, during
+ * cancellation of an expression evaluation after an aborting function call or
+ * due to a parsing error, aborting() always returns the same value.
+ */
+    int
+aborting()
+{
+    return (did_emsg && force_abort) || got_int || did_throw;
+}
+
+/*
+ * The value of "force_abort" is temporarily reset by the first emsg() call
+ * during an expression evaluation, and "cause_abort" is used instead.  It might
+ * be necessary to restore "force_abort" even before the throw point for the
+ * error message has been reached.  update_force_abort() should be called then.
+ */
+    void
+update_force_abort()
+{
+    if (cause_abort)
+	force_abort = TRUE;
+}
+
+/*
+ * Return TRUE if a command with a subcommand resulting in "retcode" should
+ * abort the script processing.  Can be used to suppress an autocommand after
+ * execution of a failing subcommand as long as the error message has not been
+ * displayed and actually caused the abortion.
+ */
+    int
+should_abort(retcode)
+    int		retcode;
+{
+    return ((retcode == FAIL && trylevel != 0 && !emsg_silent) || aborting());
+}
+
+/*
+ * Return TRUE if a function with the "abort" flag should not be considered
+ * ended on an error.  This means that parsing commands is continued in order
+ * to find finally clauses to be executed, and that some errors in skipped
+ * commands are still reported.
+ */
+    int
+aborted_in_try()
+{
+    /* This function is only called after an error.  In this case, "force_abort"
+     * determines whether searching for finally clauses is necessary. */
+    return force_abort;
+}
+
+/*
+ * cause_errthrow(): Cause a throw of an error exception if appropriate.
+ * Return TRUE if the error message should not be displayed by emsg().
+ * Sets "ignore", if the emsg() call should be ignored completely.
+ *
+ * When several messages appear in the same command, the first is usually the
+ * most specific one and used as the exception value.  The "severe" flag can be
+ * set to TRUE, if a later but severer message should be used instead.
+ */
+    int
+cause_errthrow(mesg, severe, ignore)
+    char_u	*mesg;
+    int		severe;
+    int		*ignore;
+{
+    struct msglist *elem;
+    struct msglist **plist;
+
+    /*
+     * Do nothing when displaying the interrupt message or reporting an
+     * uncaught exception (which has already been discarded then) at the top
+     * level.  Also when no exception can be thrown.  The message will be
+     * displayed by emsg().
+     */
+    if (suppress_errthrow)
+	return FALSE;
+
+    /*
+     * If emsg() has not been called previously, temporarily reset
+     * "force_abort" until the throw point for error messages has been
+     * reached.  This ensures that aborting() returns the same value for all
+     * errors that appear in the same command.  This means particularly that
+     * for parsing errors during expression evaluation emsg() will be called
+     * multiply, even when the expression is evaluated from a finally clause
+     * that was activated due to an aborting error, interrupt, or exception.
+     */
+    if (!did_emsg)
+    {
+	cause_abort = force_abort;
+	force_abort = FALSE;
+    }
+
+    /*
+     * If no try conditional is active and no exception is being thrown and
+     * there has not been an error in a try conditional or a throw so far, do
+     * nothing (for compatibility of non-EH scripts).  The message will then
+     * be displayed by emsg().  When ":silent!" was used and we are not
+     * currently throwing an exception, do nothing.  The message text will
+     * then be stored to v:errmsg by emsg() without displaying it.
+     */
+    if (((trylevel == 0 && !cause_abort) || emsg_silent) && !did_throw)
+	return FALSE;
+
+    /*
+     * Ignore an interrupt message when inside a try conditional or when an
+     * exception is being thrown or when an error in a try conditional or
+     * throw has been detected previously.  This is important in order that an
+     * interrupt exception is catchable by the innermost try conditional and
+     * not replaced by an interrupt message error exception.
+     */
+    if (mesg == (char_u *)_(e_interr))
+    {
+	*ignore = TRUE;
+	return TRUE;
+    }
+
+    /*
+     * Ensure that all commands in nested function calls and sourced files
+     * are aborted immediately.
+     */
+    cause_abort = TRUE;
+
+    /*
+     * When an exception is being thrown, some commands (like conditionals) are
+     * not skipped.  Errors in those commands may affect what of the subsequent
+     * commands are regarded part of catch and finally clauses.  Catching the
+     * exception would then cause execution of commands not intended by the
+     * user, who wouldn't even get aware of the problem.  Therefor, discard the
+     * exception currently being thrown to prevent it from being caught.  Just
+     * execute finally clauses and terminate.
+     */
+    if (did_throw)
+    {
+	/* When discarding an interrupt exception, reset got_int to prevent the
+	 * same interrupt being converted to an exception again and discarding
+	 * the error exception we are about to throw here. */
+	if (current_exception->type == ET_INTERRUPT)
+	    got_int = FALSE;
+	discard_current_exception();
+    }
+
+#ifdef THROW_TEST
+    if (!THROW_ON_ERROR)
+    {
+	/*
+	 * Print error message immediately without searching for a matching
+	 * catch clause; just finally clauses are executed before the script
+	 * is terminated.
+	 */
+	return FALSE;
+    }
+    else
+#endif
+    {
+	/*
+	 * Prepare the throw of an error exception, so that everything will
+	 * be aborted (except for executing finally clauses), until the error
+	 * exception is caught; if still uncaught at the top level, the error
+	 * message will be displayed and the script processing terminated
+	 * then.  -  This function has no access to the conditional stack.
+	 * Thus, the actual throw is made after the failing command has
+	 * returned.  -  Throw only the first of several errors in a row, except
+	 * a severe error is following.
+	 */
+	if (msg_list != NULL)
+	{
+	    plist = msg_list;
+	    while (*plist != NULL)
+		plist = &(*plist)->next;
+
+	    elem = (struct msglist *)alloc((unsigned)sizeof(struct msglist));
+	    if (elem == NULL)
+	    {
+		suppress_errthrow = TRUE;
+		EMSG(_(e_outofmem));
+	    }
+	    else
+	    {
+		elem->msg = vim_strsave(mesg);
+		if (elem->msg == NULL)
+		{
+		    vim_free(elem);
+		    suppress_errthrow = TRUE;
+		    EMSG(_(e_outofmem));
+		}
+		else
+		{
+		    elem->next = NULL;
+		    elem->throw_msg = NULL;
+		    *plist = elem;
+		    if (plist == msg_list || severe)
+		    {
+			char_u	    *tmsg;
+
+			/* Skip the extra "Vim " prefix for message "E458". */
+			tmsg = elem->msg;
+			if (STRNCMP(tmsg, "Vim E", 5) == 0
+				&& VIM_ISDIGIT(tmsg[5])
+				&& VIM_ISDIGIT(tmsg[6])
+				&& VIM_ISDIGIT(tmsg[7])
+				&& tmsg[8] == ':'
+				&& tmsg[9] == ' ')
+			    (*msg_list)->throw_msg = &tmsg[4];
+			else
+			    (*msg_list)->throw_msg = tmsg;
+		    }
+		}
+	    }
+	}
+	return TRUE;
+    }
+}
+
+/*
+ * Free a "msg_list" and the messages it contains.
+ */
+    static void
+free_msglist(l)
+    struct msglist  *l;
+{
+    struct msglist  *messages, *next;
+
+    messages = l;
+    while (messages != NULL)
+    {
+	next = messages->next;
+	vim_free(messages->msg);
+	vim_free(messages);
+	messages = next;
+    }
+}
+
+/*
+ * Throw the message specified in the call to cause_errthrow() above as an
+ * error exception.  If cstack is NULL, postpone the throw until do_cmdline()
+ * has returned (see do_one_cmd()).
+ */
+    void
+do_errthrow(cstack, cmdname)
+    struct condstack	*cstack;
+    char_u		*cmdname;
+{
+    /*
+     * Ensure that all commands in nested function calls and sourced files
+     * are aborted immediately.
+     */
+    if (cause_abort)
+    {
+	cause_abort = FALSE;
+	force_abort = TRUE;
+    }
+
+    /* If no exception is to be thrown or the conversion should be done after
+     * returning to a previous invocation of do_one_cmd(), do nothing. */
+    if (msg_list == NULL || *msg_list == NULL)
+	return;
+
+    if (throw_exception(*msg_list, ET_ERROR, cmdname) == FAIL)
+	free_msglist(*msg_list);
+    else
+    {
+	if (cstack != NULL)
+	    do_throw(cstack);
+	else
+	    need_rethrow = TRUE;
+    }
+    *msg_list = NULL;
+}
+
+/*
+ * do_intthrow(): Replace the current exception by an interrupt or interrupt
+ * exception if appropriate.  Return TRUE if the current exception is discarded,
+ * FALSE otherwise.
+ */
+    int
+do_intthrow(cstack)
+    struct condstack	*cstack;
+{
+    /*
+     * If no interrupt occurred or no try conditional is active and no exception
+     * is being thrown, do nothing (for compatibility of non-EH scripts).
+     */
+    if (!got_int || (trylevel == 0 && !did_throw))
+	return FALSE;
+
+#ifdef THROW_TEST	/* avoid warning for condition always true */
+    if (!THROW_ON_INTERRUPT)
+    {
+	/*
+	 * The interrupt aborts everything except for executing finally clauses.
+	 * Discard any user or error or interrupt exception currently being
+	 * thrown.
+	 */
+	if (did_throw)
+	    discard_current_exception();
+    }
+    else
+#endif
+    {
+	/*
+	 * Throw an interrupt exception, so that everything will be aborted
+	 * (except for executing finally clauses), until the interrupt exception
+	 * is caught; if still uncaught at the top level, the script processing
+	 * will be terminated then.  -  If an interrupt exception is already
+	 * being thrown, do nothing.
+	 *
+	 */
+	if (did_throw)
+	{
+	    if (current_exception->type == ET_INTERRUPT)
+		return FALSE;
+
+	    /* An interrupt exception replaces any user or error exception. */
+	    discard_current_exception();
+	}
+	if (throw_exception("Vim:Interrupt", ET_INTERRUPT, NULL) != FAIL)
+	    do_throw(cstack);
+    }
+
+    return TRUE;
+}
+
+
+/*
+ * Throw a new exception.  Return FAIL when out of memory or it was tried to
+ * throw an illegal user exception.  "value" is the exception string for a user
+ * or interrupt exception, or points to a message list in case of an error
+ * exception.
+ */
+    static int
+throw_exception(value, type, cmdname)
+    void	*value;
+    int		type;
+    char_u	*cmdname;
+{
+    except_T	*excp;
+    char_u	*p, *mesg, *val;
+    int		cmdlen;
+
+    /*
+     * Disallow faking Interrupt or error exceptions as user exceptions.  They
+     * would be treated differently from real interrupt or error exceptions when
+     * no active try block is found, see do_cmdline().
+     */
+    if (type == ET_USER)
+    {
+	if (STRNCMP((char_u *)value, "Vim", 3) == 0 &&
+		(((char_u *)value)[3] == NUL || ((char_u *)value)[3] == ':' ||
+		 ((char_u *)value)[3] == '('))
+	{
+	    EMSG(_("E608: Cannot :throw exceptions with 'Vim' prefix"));
+	    goto fail;
+	}
+    }
+
+    excp = (except_T *)alloc((unsigned)sizeof(except_T));
+    if (excp == NULL)
+	goto nomem;
+
+    if (type == ET_ERROR)
+    {
+	/* Store the original message and prefix the exception value with
+	 * "Vim:" or, if a command name is given, "Vim(cmdname):". */
+	excp->messages = (struct msglist *)value;
+	mesg = excp->messages->throw_msg;
+	if (cmdname != NULL && *cmdname != NUL)
+	{
+	    cmdlen = (int)STRLEN(cmdname);
+	    excp->value = vim_strnsave((char_u *)"Vim(",
+					   4 + cmdlen + 2 + (int)STRLEN(mesg));
+	    if (excp->value == NULL)
+		goto nomem;
+	    STRCPY(&excp->value[4], cmdname);
+	    STRCPY(&excp->value[4 + cmdlen], "):");
+	    val = excp->value + 4 + cmdlen + 2;
+	}
+	else
+	{
+	    excp->value = vim_strnsave((char_u *)"Vim:", 4 + (int)STRLEN(mesg));
+	    if (excp->value == NULL)
+		goto nomem;
+	    val = excp->value + 4;
+	}
+
+	/* msg_add_fname may have been used to prefix the message with a file
+	 * name in quotes.  In the exception value, put the file name in
+	 * parentheses and move it to the end. */
+	for (p = mesg; ; p++)
+	{
+	    if (*p == NUL
+		    || (*p == 'E'
+			&& VIM_ISDIGIT(p[1])
+			&& (p[2] == ':'
+			    || (VIM_ISDIGIT(p[2])
+				&& (p[3] == ':'
+				    || (VIM_ISDIGIT(p[3])
+					&& p[4] == ':'))))))
+	    {
+		if (*p == NUL || p == mesg)
+		    STRCAT(val, mesg);  /* 'E123' missing or at beginning */
+		else
+		{
+		    /* '"filename" E123: message text' */
+		    if (mesg[0] != '"' || p-2 < &mesg[1] ||
+			    p[-2] != '"' || p[-1] != ' ')
+			/* "E123:" is part of the file name. */
+			continue;
+
+		    STRCAT(val, p);
+		    p[-2] = NUL;
+		    sprintf((char *)(val + STRLEN(p)), " (%s)", &mesg[1]);
+		    p[-2] = '"';
+		}
+		break;
+	    }
+	}
+    }
+    else
+	excp->value = value;
+
+    excp->type = type;
+    excp->throw_name = vim_strsave(sourcing_name == NULL
+					      ? (char_u *)"" : sourcing_name);
+    if (excp->throw_name == NULL)
+    {
+	if (type == ET_ERROR)
+	    vim_free(excp->value);
+	goto nomem;
+    }
+    excp->throw_lnum = sourcing_lnum;
+
+    if (p_verbose >= 13 || debug_break_level > 0)
+    {
+	int	save_msg_silent = msg_silent;
+
+	if (debug_break_level > 0)
+	    msg_silent = FALSE;		/* display messages */
+	else
+	    verbose_enter();
+	++no_wait_return;
+	if (debug_break_level > 0 || *p_vfile == NUL)
+	    msg_scroll = TRUE;	    /* always scroll up, don't overwrite */
+
+	smsg((char_u *)_("Exception thrown: %s"), excp->value);
+	msg_puts((char_u *)"\n");   /* don't overwrite this either */
+
+	if (debug_break_level > 0 || *p_vfile == NUL)
+	    cmdline_row = msg_row;
+	--no_wait_return;
+	if (debug_break_level > 0)
+	    msg_silent = save_msg_silent;
+	else
+	    verbose_leave();
+    }
+
+    current_exception = excp;
+    return OK;
+
+nomem:
+    vim_free(excp);
+    suppress_errthrow = TRUE;
+    EMSG(_(e_outofmem));
+fail:
+    current_exception = NULL;
+    return FAIL;
+}
+
+/*
+ * Discard an exception.  "was_finished" is set when the exception has been
+ * caught and the catch clause has been ended normally.
+ */
+    static void
+discard_exception(excp, was_finished)
+    except_T		*excp;
+    int			was_finished;
+{
+    char_u		*saved_IObuff;
+
+    if (excp == NULL)
+    {
+	EMSG(_(e_internal));
+	return;
+    }
+
+    if (p_verbose >= 13 || debug_break_level > 0)
+    {
+	int	save_msg_silent = msg_silent;
+
+	saved_IObuff = vim_strsave(IObuff);
+	if (debug_break_level > 0)
+	    msg_silent = FALSE;		/* display messages */
+	else
+	    verbose_enter();
+	++no_wait_return;
+	if (debug_break_level > 0 || *p_vfile == NUL)
+	    msg_scroll = TRUE;	    /* always scroll up, don't overwrite */
+	smsg(was_finished
+		    ? (char_u *)_("Exception finished: %s")
+		    : (char_u *)_("Exception discarded: %s"),
+		excp->value);
+	msg_puts((char_u *)"\n");   /* don't overwrite this either */
+	if (debug_break_level > 0 || *p_vfile == NUL)
+	    cmdline_row = msg_row;
+	--no_wait_return;
+	if (debug_break_level > 0)
+	    msg_silent = save_msg_silent;
+	else
+	    verbose_leave();
+	STRCPY(IObuff, saved_IObuff);
+	vim_free(saved_IObuff);
+    }
+    if (excp->type != ET_INTERRUPT)
+	vim_free(excp->value);
+    if (excp->type == ET_ERROR)
+	free_msglist(excp->messages);
+    vim_free(excp->throw_name);
+    vim_free(excp);
+}
+
+/*
+ * Discard the exception currently being thrown.
+ */
+    void
+discard_current_exception()
+{
+    discard_exception(current_exception, FALSE);
+    current_exception = NULL;
+    did_throw = FALSE;
+    need_rethrow = FALSE;
+}
+
+/*
+ * Put an exception on the caught stack.
+ */
+    static void
+catch_exception(excp)
+    except_T	*excp;
+{
+    excp->caught = caught_stack;
+    caught_stack = excp;
+    set_vim_var_string(VV_EXCEPTION, excp->value, -1);
+    if (*excp->throw_name != NUL)
+    {
+	if (excp->throw_lnum != 0)
+	    vim_snprintf((char *)IObuff, IOSIZE, _("%s, line %ld"),
+				    excp->throw_name, (long)excp->throw_lnum);
+	else
+	    vim_snprintf((char *)IObuff, IOSIZE, "%s", excp->throw_name);
+	set_vim_var_string(VV_THROWPOINT, IObuff, -1);
+    }
+    else
+	/* throw_name not set on an exception from a command that was typed. */
+	set_vim_var_string(VV_THROWPOINT, NULL, -1);
+
+    if (p_verbose >= 13 || debug_break_level > 0)
+    {
+	int	save_msg_silent = msg_silent;
+
+	if (debug_break_level > 0)
+	    msg_silent = FALSE;		/* display messages */
+	else
+	    verbose_enter();
+	++no_wait_return;
+	if (debug_break_level > 0 || *p_vfile == NUL)
+	    msg_scroll = TRUE;	    /* always scroll up, don't overwrite */
+
+	smsg((char_u *)_("Exception caught: %s"), excp->value);
+	msg_puts((char_u *)"\n");   /* don't overwrite this either */
+
+	if (debug_break_level > 0 || *p_vfile == NUL)
+	    cmdline_row = msg_row;
+	--no_wait_return;
+	if (debug_break_level > 0)
+	    msg_silent = save_msg_silent;
+	else
+	    verbose_leave();
+    }
+}
+
+/*
+ * Remove an exception from the caught stack.
+ */
+    static void
+finish_exception(excp)
+    except_T	*excp;
+{
+    if (excp != caught_stack)
+	EMSG(_(e_internal));
+    caught_stack = caught_stack->caught;
+    if (caught_stack != NULL)
+    {
+	set_vim_var_string(VV_EXCEPTION, caught_stack->value, -1);
+	if (*caught_stack->throw_name != NUL)
+	{
+	    if (caught_stack->throw_lnum != 0)
+		vim_snprintf((char *)IObuff, IOSIZE,
+			_("%s, line %ld"), caught_stack->throw_name,
+			(long)caught_stack->throw_lnum);
+	    else
+		vim_snprintf((char *)IObuff, IOSIZE, "%s",
+						    caught_stack->throw_name);
+	    set_vim_var_string(VV_THROWPOINT, IObuff, -1);
+	}
+	else
+	    /* throw_name not set on an exception from a command that was
+	     * typed. */
+	    set_vim_var_string(VV_THROWPOINT, NULL, -1);
+    }
+    else
+    {
+	set_vim_var_string(VV_EXCEPTION, NULL, -1);
+	set_vim_var_string(VV_THROWPOINT, NULL, -1);
+    }
+
+    /* Discard the exception, but use the finish message for 'verbose'. */
+    discard_exception(excp, TRUE);
+}
+
+/*
+ * Flags specifying the message displayed by report_pending.
+ */
+#define RP_MAKE		0
+#define RP_RESUME	1
+#define RP_DISCARD	2
+
+/*
+ * Report information about something pending in a finally clause if required by
+ * the 'verbose' option or when debugging.  "action" tells whether something is
+ * made pending or something pending is resumed or discarded.  "pending" tells
+ * what is pending.  "value" specifies the return value for a pending ":return"
+ * or the exception value for a pending exception.
+ */
+    static void
+report_pending(action, pending, value)
+    int		action;
+    int		pending;
+    void	*value;
+{
+    char_u	*mesg;
+    char	*s;
+    int		save_msg_silent;
+
+
+    switch (action)
+    {
+	case RP_MAKE:
+	    mesg = (char_u *)_("%s made pending");
+	    break;
+	case RP_RESUME:
+	    mesg = (char_u *)_("%s resumed");
+	    break;
+	/* case RP_DISCARD: */
+	default:
+	    mesg = (char_u *)_("%s discarded");
+	    break;
+    }
+
+    switch (pending)
+    {
+	case CSTP_NONE:
+	    return;
+
+	case CSTP_CONTINUE:
+	    s = ":continue";
+	    break;
+	case CSTP_BREAK:
+	    s = ":break";
+	    break;
+	case CSTP_FINISH:
+	    s = ":finish";
+	    break;
+	case CSTP_RETURN:
+	    /* ":return" command producing value, allocated */
+	    s = (char *)get_return_cmd(value);
+	    break;
+
+	default:
+	    if (pending & CSTP_THROW)
+	    {
+		vim_snprintf((char *)IObuff, IOSIZE,
+						(char *)mesg, _("Exception"));
+		mesg = vim_strnsave(IObuff, (int)STRLEN(IObuff) + 4);
+		STRCAT(mesg, ": %s");
+		s = (char *)((except_T *)value)->value;
+	    }
+	    else if ((pending & CSTP_ERROR) && (pending & CSTP_INTERRUPT))
+		s = _("Error and interrupt");
+	    else if (pending & CSTP_ERROR)
+		s = _("Error");
+	    else /* if (pending & CSTP_INTERRUPT) */
+		s = _("Interrupt");
+    }
+
+    save_msg_silent = msg_silent;
+    if (debug_break_level > 0)
+	msg_silent = FALSE;	/* display messages */
+    ++no_wait_return;
+    msg_scroll = TRUE;		/* always scroll up, don't overwrite */
+    smsg(mesg, (char_u *)s);
+    msg_puts((char_u *)"\n");   /* don't overwrite this either */
+    cmdline_row = msg_row;
+    --no_wait_return;
+    if (debug_break_level > 0)
+	msg_silent = save_msg_silent;
+
+    if (pending == CSTP_RETURN)
+	vim_free(s);
+    else if (pending & CSTP_THROW)
+	vim_free(mesg);
+}
+
+/*
+ * If something is made pending in a finally clause, report it if required by
+ * the 'verbose' option or when debugging.
+ */
+    void
+report_make_pending(pending, value)
+    int		pending;
+    void	*value;
+{
+    if (p_verbose >= 14 || debug_break_level > 0)
+    {
+	if (debug_break_level <= 0)
+	    verbose_enter();
+	report_pending(RP_MAKE, pending, value);
+	if (debug_break_level <= 0)
+	    verbose_leave();
+    }
+}
+
+/*
+ * If something pending in a finally clause is resumed at the ":endtry", report
+ * it if required by the 'verbose' option or when debugging.
+ */
+    void
+report_resume_pending(pending, value)
+    int		pending;
+    void	*value;
+{
+    if (p_verbose >= 14 || debug_break_level > 0)
+    {
+	if (debug_break_level <= 0)
+	    verbose_enter();
+	report_pending(RP_RESUME, pending, value);
+	if (debug_break_level <= 0)
+	    verbose_leave();
+    }
+}
+
+/*
+ * If something pending in a finally clause is discarded, report it if required
+ * by the 'verbose' option or when debugging.
+ */
+    void
+report_discard_pending(pending, value)
+    int		pending;
+    void	*value;
+{
+    if (p_verbose >= 14 || debug_break_level > 0)
+    {
+	if (debug_break_level <= 0)
+	    verbose_enter();
+	report_pending(RP_DISCARD, pending, value);
+	if (debug_break_level <= 0)
+	    verbose_leave();
+    }
+}
+
+
+/*
+ * ":if".
+ */
+    void
+ex_if(eap)
+    exarg_T	*eap;
+{
+    int		error;
+    int		skip;
+    int		result;
+    struct condstack	*cstack = eap->cstack;
+
+    if (cstack->cs_idx == CSTACK_LEN - 1)
+	eap->errmsg = (char_u *)N_("E579: :if nesting too deep");
+    else
+    {
+	++cstack->cs_idx;
+	cstack->cs_flags[cstack->cs_idx] = 0;
+
+	/*
+	 * Don't do something after an error, interrupt, or throw, or when there
+	 * is a surrounding conditional and it was not active.
+	 */
+	skip = did_emsg || got_int || did_throw || (cstack->cs_idx > 0
+		&& !(cstack->cs_flags[cstack->cs_idx - 1] & CSF_ACTIVE));
+
+	result = eval_to_bool(eap->arg, &error, &eap->nextcmd, skip);
+
+	if (!skip && !error)
+	{
+	    if (result)
+		cstack->cs_flags[cstack->cs_idx] = CSF_ACTIVE | CSF_TRUE;
+	}
+	else
+	    /* set TRUE, so this conditional will never get active */
+	    cstack->cs_flags[cstack->cs_idx] = CSF_TRUE;
+    }
+}
+
+/*
+ * ":endif".
+ */
+    void
+ex_endif(eap)
+    exarg_T	*eap;
+{
+    did_endif = TRUE;
+    if (eap->cstack->cs_idx < 0
+	    || (eap->cstack->cs_flags[eap->cstack->cs_idx]
+					   & (CSF_WHILE | CSF_FOR | CSF_TRY)))
+	eap->errmsg = (char_u *)N_("E580: :endif without :if");
+    else
+    {
+	/*
+	 * When debugging or a breakpoint was encountered, display the debug
+	 * prompt (if not already done).  This shows the user that an ":endif"
+	 * is executed when the ":if" or a previous ":elseif" was not TRUE.
+	 * Handle a ">quit" debug command as if an interrupt had occurred before
+	 * the ":endif".  That is, throw an interrupt exception if appropriate.
+	 * Doing this here prevents an exception for a parsing error being
+	 * discarded by throwing the interrupt exception later on.
+	 */
+	if (!(eap->cstack->cs_flags[eap->cstack->cs_idx] & CSF_TRUE)
+						    && dbg_check_skipped(eap))
+	    (void)do_intthrow(eap->cstack);
+
+	--eap->cstack->cs_idx;
+    }
+}
+
+/*
+ * ":else" and ":elseif".
+ */
+    void
+ex_else(eap)
+    exarg_T	*eap;
+{
+    int		error;
+    int		skip;
+    int		result;
+    struct condstack	*cstack = eap->cstack;
+
+    /*
+     * Don't do something after an error, interrupt, or throw, or when there is
+     * a surrounding conditional and it was not active.
+     */
+    skip = did_emsg || got_int || did_throw || (cstack->cs_idx > 0
+	    && !(cstack->cs_flags[cstack->cs_idx - 1] & CSF_ACTIVE));
+
+    if (cstack->cs_idx < 0
+	    || (cstack->cs_flags[cstack->cs_idx]
+					   & (CSF_WHILE | CSF_FOR | CSF_TRY)))
+    {
+	if (eap->cmdidx == CMD_else)
+	{
+	    eap->errmsg = (char_u *)N_("E581: :else without :if");
+	    return;
+	}
+	eap->errmsg = (char_u *)N_("E582: :elseif without :if");
+	skip = TRUE;
+    }
+    else if (cstack->cs_flags[cstack->cs_idx] & CSF_ELSE)
+    {
+	if (eap->cmdidx == CMD_else)
+	{
+	    eap->errmsg = (char_u *)N_("E583: multiple :else");
+	    return;
+	}
+	eap->errmsg = (char_u *)N_("E584: :elseif after :else");
+	skip = TRUE;
+    }
+
+    /* if skipping or the ":if" was TRUE, reset ACTIVE, otherwise set it */
+    if (skip || cstack->cs_flags[cstack->cs_idx] & CSF_TRUE)
+    {
+	if (eap->errmsg == NULL)
+	    cstack->cs_flags[cstack->cs_idx] = CSF_TRUE;
+	skip = TRUE;	/* don't evaluate an ":elseif" */
+    }
+    else
+	cstack->cs_flags[cstack->cs_idx] = CSF_ACTIVE;
+
+    /*
+     * When debugging or a breakpoint was encountered, display the debug prompt
+     * (if not already done).  This shows the user that an ":else" or ":elseif"
+     * is executed when the ":if" or previous ":elseif" was not TRUE.  Handle
+     * a ">quit" debug command as if an interrupt had occurred before the
+     * ":else" or ":elseif".  That is, set "skip" and throw an interrupt
+     * exception if appropriate.  Doing this here prevents that an exception
+     * for a parsing errors is discarded when throwing the interrupt exception
+     * later on.
+     */
+    if (!skip && dbg_check_skipped(eap) && got_int)
+    {
+	(void)do_intthrow(cstack);
+	skip = TRUE;
+    }
+
+    if (eap->cmdidx == CMD_elseif)
+    {
+	result = eval_to_bool(eap->arg, &error, &eap->nextcmd, skip);
+	/* When throwing error exceptions, we want to throw always the first
+	 * of several errors in a row.  This is what actually happens when
+	 * a conditional error was detected above and there is another failure
+	 * when parsing the expression.  Since the skip flag is set in this
+	 * case, the parsing error will be ignored by emsg(). */
+
+	if (!skip && !error)
+	{
+	    if (result)
+		cstack->cs_flags[cstack->cs_idx] = CSF_ACTIVE | CSF_TRUE;
+	    else
+		cstack->cs_flags[cstack->cs_idx] = 0;
+	}
+	else if (eap->errmsg == NULL)
+	    /* set TRUE, so this conditional will never get active */
+	    cstack->cs_flags[cstack->cs_idx] = CSF_TRUE;
+    }
+    else
+	cstack->cs_flags[cstack->cs_idx] |= CSF_ELSE;
+}
+
+/*
+ * Handle ":while" and ":for".
+ */
+    void
+ex_while(eap)
+    exarg_T	*eap;
+{
+    int		error;
+    int		skip;
+    int		result;
+    struct condstack	*cstack = eap->cstack;
+
+    if (cstack->cs_idx == CSTACK_LEN - 1)
+	eap->errmsg = (char_u *)N_("E585: :while/:for nesting too deep");
+    else
+    {
+	/*
+	 * The loop flag is set when we have jumped back from the matching
+	 * ":endwhile" or ":endfor".  When not set, need to initialise this
+	 * cstack entry.
+	 */
+	if ((cstack->cs_lflags & CSL_HAD_LOOP) == 0)
+	{
+	    ++cstack->cs_idx;
+	    ++cstack->cs_looplevel;
+	    cstack->cs_line[cstack->cs_idx] = -1;
+	}
+	cstack->cs_flags[cstack->cs_idx] =
+			       eap->cmdidx == CMD_while ? CSF_WHILE : CSF_FOR;
+
+	/*
+	 * Don't do something after an error, interrupt, or throw, or when
+	 * there is a surrounding conditional and it was not active.
+	 */
+	skip = did_emsg || got_int || did_throw || (cstack->cs_idx > 0
+		&& !(cstack->cs_flags[cstack->cs_idx - 1] & CSF_ACTIVE));
+	if (eap->cmdidx == CMD_while)
+	{
+	    /*
+	     * ":while bool-expr"
+	     */
+	    result = eval_to_bool(eap->arg, &error, &eap->nextcmd, skip);
+	}
+	else
+	{
+	    void *fi;
+
+	    /*
+	     * ":for var in list-expr"
+	     */
+	    if ((cstack->cs_lflags & CSL_HAD_LOOP) != 0)
+	    {
+		/* Jumping here from a ":continue" or ":endfor": use the
+		 * previously evaluated list. */
+		fi = cstack->cs_forinfo[cstack->cs_idx];
+		error = FALSE;
+	    }
+	    else
+	    {
+		/* Evaluate the argument and get the info in a structure. */
+		fi = eval_for_line(eap->arg, &error, &eap->nextcmd, skip);
+		cstack->cs_forinfo[cstack->cs_idx] = fi;
+	    }
+
+	    /* use the element at the start of the list and advance */
+	    if (!error && fi != NULL && !skip)
+		result = next_for_item(fi, eap->arg);
+	    else
+		result = FALSE;
+
+	    if (!result)
+	    {
+		free_for_info(fi);
+		cstack->cs_forinfo[cstack->cs_idx] = NULL;
+	    }
+	}
+
+	/*
+	 * If this cstack entry was just initialised and is active, set the
+	 * loop flag, so do_cmdline() will set the line number in cs_line[].
+	 * If executing the command a second time, clear the loop flag.
+	 */
+	if (!skip && !error && result)
+	{
+	    cstack->cs_flags[cstack->cs_idx] |= (CSF_ACTIVE | CSF_TRUE);
+	    cstack->cs_lflags ^= CSL_HAD_LOOP;
+	}
+	else
+	{
+	    cstack->cs_lflags &= ~CSL_HAD_LOOP;
+	    /* If the ":while" evaluates to FALSE or ":for" is past the end of
+	     * the list, show the debug prompt at the ":endwhile"/":endfor" as
+	     * if there was a ":break" in a ":while"/":for" evaluating to
+	     * TRUE. */
+	    if (!skip && !error)
+		cstack->cs_flags[cstack->cs_idx] |= CSF_TRUE;
+	}
+    }
+}
+
+/*
+ * ":continue"
+ */
+    void
+ex_continue(eap)
+    exarg_T	*eap;
+{
+    int		idx;
+    struct condstack	*cstack = eap->cstack;
+
+    if (cstack->cs_looplevel <= 0 || cstack->cs_idx < 0)
+	eap->errmsg = (char_u *)N_("E586: :continue without :while or :for");
+    else
+    {
+	/* Try to find the matching ":while".  This might stop at a try
+	 * conditional not in its finally clause (which is then to be executed
+	 * next).  Therefor, inactivate all conditionals except the ":while"
+	 * itself (if reached). */
+	idx = cleanup_conditionals(cstack, CSF_WHILE | CSF_FOR, FALSE);
+	if (idx >= 0 && (cstack->cs_flags[idx] & (CSF_WHILE | CSF_FOR)))
+	{
+	    rewind_conditionals(cstack, idx, CSF_TRY, &cstack->cs_trylevel);
+
+	    /*
+	     * Set CSL_HAD_CONT, so do_cmdline() will jump back to the
+	     * matching ":while".
+	     */
+	    cstack->cs_lflags |= CSL_HAD_CONT;	/* let do_cmdline() handle it */
+	}
+	else
+	{
+	    /* If a try conditional not in its finally clause is reached first,
+	     * make the ":continue" pending for execution at the ":endtry". */
+	    cstack->cs_pending[idx] = CSTP_CONTINUE;
+	    report_make_pending(CSTP_CONTINUE, NULL);
+	}
+    }
+}
+
+/*
+ * ":break"
+ */
+    void
+ex_break(eap)
+    exarg_T	*eap;
+{
+    int		idx;
+    struct condstack	*cstack = eap->cstack;
+
+    if (cstack->cs_looplevel <= 0 || cstack->cs_idx < 0)
+	eap->errmsg = (char_u *)N_("E587: :break without :while or :for");
+    else
+    {
+	/* Inactivate conditionals until the matching ":while" or a try
+	 * conditional not in its finally clause (which is then to be
+	 * executed next) is found.  In the latter case, make the ":break"
+	 * pending for execution at the ":endtry". */
+	idx = cleanup_conditionals(cstack, CSF_WHILE | CSF_FOR, TRUE);
+	if (idx >= 0 && !(cstack->cs_flags[idx] & (CSF_WHILE | CSF_FOR)))
+	{
+	    cstack->cs_pending[idx] = CSTP_BREAK;
+	    report_make_pending(CSTP_BREAK, NULL);
+	}
+    }
+}
+
+/*
+ * ":endwhile" and ":endfor"
+ */
+    void
+ex_endwhile(eap)
+    exarg_T	*eap;
+{
+    struct condstack	*cstack = eap->cstack;
+    int			idx;
+    char_u		*err;
+    int			csf;
+    int			fl;
+
+    if (eap->cmdidx == CMD_endwhile)
+    {
+	err = e_while;
+	csf = CSF_WHILE;
+    }
+    else
+    {
+	err = e_for;
+	csf = CSF_FOR;
+    }
+
+    if (cstack->cs_looplevel <= 0 || cstack->cs_idx < 0)
+	eap->errmsg = err;
+    else
+    {
+	fl =  cstack->cs_flags[cstack->cs_idx];
+	if (!(fl & csf))
+	{
+	    /* If we are in a ":while" or ":for" but used the wrong endloop
+	     * command, do not rewind to the next enclosing ":for"/":while". */
+	    if (fl & CSF_WHILE)
+		eap->errmsg = (char_u *)_("E732: Using :endfor with :while");
+	    else if (fl & CSF_FOR)
+		eap->errmsg = (char_u *)_("E733: Using :endwhile with :for");
+	}
+	if (!(fl & (CSF_WHILE | CSF_FOR)))
+	{
+	    if (!(fl & CSF_TRY))
+		eap->errmsg = e_endif;
+	    else if (fl & CSF_FINALLY)
+		eap->errmsg = e_endtry;
+	    /* Try to find the matching ":while" and report what's missing. */
+	    for (idx = cstack->cs_idx; idx > 0; --idx)
+	    {
+		fl =  cstack->cs_flags[idx];
+		if ((fl & CSF_TRY) && !(fl & CSF_FINALLY))
+		{
+		    /* Give up at a try conditional not in its finally clause.
+		     * Ignore the ":endwhile"/":endfor". */
+		    eap->errmsg = err;
+		    return;
+		}
+		if (fl & csf)
+		    break;
+	    }
+	    /* Cleanup and rewind all contained (and unclosed) conditionals. */
+	    (void)cleanup_conditionals(cstack, CSF_WHILE | CSF_FOR, FALSE);
+	    rewind_conditionals(cstack, idx, CSF_TRY, &cstack->cs_trylevel);
+	}
+
+	/*
+	 * When debugging or a breakpoint was encountered, display the debug
+	 * prompt (if not already done).  This shows the user that an
+	 * ":endwhile"/":endfor" is executed when the ":while" was not TRUE or
+	 * after a ":break".  Handle a ">quit" debug command as if an
+	 * interrupt had occurred before the ":endwhile"/":endfor".  That is,
+	 * throw an interrupt exception if appropriate.  Doing this here
+	 * prevents that an exception for a parsing error is discarded when
+	 * throwing the interrupt exception later on.
+	 */
+	else if (cstack->cs_flags[cstack->cs_idx] & CSF_TRUE
+		&& !(cstack->cs_flags[cstack->cs_idx] & CSF_ACTIVE)
+		&& dbg_check_skipped(eap))
+	    (void)do_intthrow(cstack);
+
+	/*
+	 * Set loop flag, so do_cmdline() will jump back to the matching
+	 * ":while" or ":for".
+	 */
+	cstack->cs_lflags |= CSL_HAD_ENDLOOP;
+    }
+}
+
+
+/*
+ * ":throw expr"
+ */
+    void
+ex_throw(eap)
+    exarg_T	*eap;
+{
+    char_u	*arg = eap->arg;
+    char_u	*value;
+
+    if (*arg != NUL && *arg != '|' && *arg != '\n')
+	value = eval_to_string_skip(arg, &eap->nextcmd, eap->skip);
+    else
+    {
+	EMSG(_(e_argreq));
+	value = NULL;
+    }
+
+    /* On error or when an exception is thrown during argument evaluation, do
+     * not throw. */
+    if (!eap->skip && value != NULL)
+    {
+	if (throw_exception(value, ET_USER, NULL) == FAIL)
+	    vim_free(value);
+	else
+	    do_throw(eap->cstack);
+    }
+}
+
+/*
+ * Throw the current exception through the specified cstack.  Common routine
+ * for ":throw" (user exception) and error and interrupt exceptions.  Also
+ * used for rethrowing an uncaught exception.
+ */
+    void
+do_throw(cstack)
+    struct condstack	*cstack;
+{
+    int		idx;
+    int		inactivate_try = FALSE;
+
+    /*
+     * Cleanup and inactivate up to the next surrounding try conditional that
+     * is not in its finally clause.  Normally, do not inactivate the try
+     * conditional itself, so that its ACTIVE flag can be tested below.  But
+     * if a previous error or interrupt has not been converted to an exception,
+     * inactivate the try conditional, too, as if the conversion had been done,
+     * and reset the did_emsg or got_int flag, so this won't happen again at
+     * the next surrounding try conditional.
+     */
+    if (did_emsg && !THROW_ON_ERROR)
+    {
+	inactivate_try = TRUE;
+	did_emsg = FALSE;
+    }
+    if (got_int && !THROW_ON_INTERRUPT)
+    {
+	inactivate_try = TRUE;
+	got_int = FALSE;
+    }
+    idx = cleanup_conditionals(cstack, 0, inactivate_try);
+    if (idx >= 0)
+    {
+	/*
+	 * If this try conditional is active and we are before its first
+	 * ":catch", set THROWN so that the ":catch" commands will check
+	 * whether the exception matches.  When the exception came from any of
+	 * the catch clauses, it will be made pending at the ":finally" (if
+	 * present) and rethrown at the ":endtry".  This will also happen if
+	 * the try conditional is inactive.  This is the case when we are
+	 * throwing an exception due to an error or interrupt on the way from
+	 * a preceding ":continue", ":break", ":return", ":finish", error or
+	 * interrupt (not converted to an exception) to the finally clause or
+	 * from a preceding throw of a user or error or interrupt exception to
+	 * the matching catch clause or the finally clause.
+	 */
+	if (!(cstack->cs_flags[idx] & CSF_CAUGHT))
+	{
+	    if (cstack->cs_flags[idx] & CSF_ACTIVE)
+		cstack->cs_flags[idx] |= CSF_THROWN;
+	    else
+		/* THROWN may have already been set for a catchable exception
+		 * that has been discarded.  Ensure it is reset for the new
+		 * exception. */
+		cstack->cs_flags[idx] &= ~CSF_THROWN;
+	}
+	cstack->cs_flags[idx] &= ~CSF_ACTIVE;
+	cstack->cs_exception[idx] = current_exception;
+    }
+#if 0
+    /* TODO: Add optimization below.  Not yet done because of interface
+     * problems to eval.c and ex_cmds2.c. (Servatius) */
+    else
+    {
+	/*
+	 * There are no catch clauses to check or finally clauses to execute.
+	 * End the current script or function.  The exception will be rethrown
+	 * in the caller.
+	 */
+	if (getline_equal(eap->getline, eap->cookie, get_func_line))
+	    current_funccal->returned = TRUE;
+	elseif (eap->get_func_line == getsourceline)
+	    ((struct source_cookie *)eap->cookie)->finished = TRUE;
+    }
+#endif
+
+    did_throw = TRUE;
+}
+
+/*
+ * ":try"
+ */
+    void
+ex_try(eap)
+    exarg_T	*eap;
+{
+    int		skip;
+    struct condstack	*cstack = eap->cstack;
+
+    if (cstack->cs_idx == CSTACK_LEN - 1)
+	eap->errmsg = (char_u *)N_("E601: :try nesting too deep");
+    else
+    {
+	++cstack->cs_idx;
+	++cstack->cs_trylevel;
+	cstack->cs_flags[cstack->cs_idx] = CSF_TRY;
+	cstack->cs_pending[cstack->cs_idx] = CSTP_NONE;
+
+	/*
+	 * Don't do something after an error, interrupt, or throw, or when there
+	 * is a surrounding conditional and it was not active.
+	 */
+	skip = did_emsg || got_int || did_throw || (cstack->cs_idx > 0
+		&& !(cstack->cs_flags[cstack->cs_idx - 1] & CSF_ACTIVE));
+
+	if (!skip)
+	{
+	    /* Set ACTIVE and TRUE.  TRUE means that the corresponding ":catch"
+	     * commands should check for a match if an exception is thrown and
+	     * that the finally clause needs to be executed. */
+	    cstack->cs_flags[cstack->cs_idx] |= CSF_ACTIVE | CSF_TRUE;
+
+	    /*
+	     * ":silent!", even when used in a try conditional, disables
+	     * displaying of error messages and conversion of errors to
+	     * exceptions.  When the silent commands again open a try
+	     * conditional, save "emsg_silent" and reset it so that errors are
+	     * again converted to exceptions.  The value is restored when that
+	     * try conditional is left.  If it is left normally, the commands
+	     * following the ":endtry" are again silent.  If it is left by
+	     * a ":continue", ":break", ":return", or ":finish", the commands
+	     * executed next are again silent.  If it is left due to an
+	     * aborting error, an interrupt, or an exception, restoring
+	     * "emsg_silent" does not matter since we are already in the
+	     * aborting state and/or the exception has already been thrown.
+	     * The effect is then just freeing the memory that was allocated
+	     * to save the value.
+	     */
+	    if (emsg_silent)
+	    {
+		eslist_T	*elem;
+
+		elem = (eslist_T *)alloc((unsigned)sizeof(struct eslist_elem));
+		if (elem == NULL)
+		    EMSG(_(e_outofmem));
+		else
+		{
+		    elem->saved_emsg_silent = emsg_silent;
+		    elem->next = cstack->cs_emsg_silent_list;
+		    cstack->cs_emsg_silent_list = elem;
+		    cstack->cs_flags[cstack->cs_idx] |= CSF_SILENT;
+		    emsg_silent = 0;
+		}
+	    }
+	}
+
+    }
+}
+
+/*
+ * ":catch /{pattern}/" and ":catch"
+ */
+    void
+ex_catch(eap)
+    exarg_T	*eap;
+{
+    int		idx = 0;
+    int		give_up = FALSE;
+    int		skip = FALSE;
+    int		caught = FALSE;
+    char_u	*end;
+    int		save_char = 0;
+    char_u	*save_cpo;
+    regmatch_T	regmatch;
+    int		prev_got_int;
+    struct condstack	*cstack = eap->cstack;
+    char_u	*pat;
+
+    if (cstack->cs_trylevel <= 0 || cstack->cs_idx < 0)
+    {
+	eap->errmsg = (char_u *)N_("E603: :catch without :try");
+	give_up = TRUE;
+    }
+    else
+    {
+	if (!(cstack->cs_flags[cstack->cs_idx] & CSF_TRY))
+	{
+	    /* Report what's missing if the matching ":try" is not in its
+	     * finally clause. */
+	    eap->errmsg = get_end_emsg(cstack);
+	    skip = TRUE;
+	}
+	for (idx = cstack->cs_idx; idx > 0; --idx)
+	    if (cstack->cs_flags[idx] & CSF_TRY)
+		break;
+	if (cstack->cs_flags[idx] & CSF_FINALLY)
+	{
+	    /* Give up for a ":catch" after ":finally" and ignore it.
+	     * Just parse. */
+	    eap->errmsg = (char_u *)N_("E604: :catch after :finally");
+	    give_up = TRUE;
+	}
+	else
+	    rewind_conditionals(cstack, idx, CSF_WHILE | CSF_FOR,
+						       &cstack->cs_looplevel);
+    }
+
+    if (ends_excmd(*eap->arg))	/* no argument, catch all errors */
+    {
+	pat = (char_u *)".*";
+	end = NULL;
+	eap->nextcmd = find_nextcmd(eap->arg);
+    }
+    else
+    {
+	pat = eap->arg + 1;
+	end = skip_regexp(pat, *eap->arg, TRUE, NULL);
+    }
+
+    if (!give_up)
+    {
+	/*
+	 * Don't do something when no exception has been thrown or when the
+	 * corresponding try block never got active (because of an inactive
+	 * surrounding conditional or after an error or interrupt or throw).
+	 */
+	if (!did_throw || !(cstack->cs_flags[idx] & CSF_TRUE))
+	    skip = TRUE;
+
+	/*
+	 * Check for a match only if an exception is thrown but not caught by
+	 * a previous ":catch".  An exception that has replaced a discarded
+	 * exception is not checked (THROWN is not set then).
+	 */
+	if (!skip && (cstack->cs_flags[idx] & CSF_THROWN)
+		&& !(cstack->cs_flags[idx] & CSF_CAUGHT))
+	{
+	    if (end != NULL && *end != NUL && !ends_excmd(*skipwhite(end + 1)))
+	    {
+		EMSG(_(e_trailing));
+		return;
+	    }
+
+	    /* When debugging or a breakpoint was encountered, display the
+	     * debug prompt (if not already done) before checking for a match.
+	     * This is a helpful hint for the user when the regular expression
+	     * matching fails.  Handle a ">quit" debug command as if an
+	     * interrupt had occurred before the ":catch".  That is, discard
+	     * the original exception, replace it by an interrupt exception,
+	     * and don't catch it in this try block. */
+	    if (!dbg_check_skipped(eap) || !do_intthrow(cstack))
+	    {
+		/* Terminate the pattern and avoid the 'l' flag in 'cpoptions'
+		 * while compiling it. */
+		if (end != NULL)
+		{
+		    save_char = *end;
+		    *end = NUL;
+		}
+		save_cpo  = p_cpo;
+		p_cpo = (char_u *)"";
+		regmatch.regprog = vim_regcomp(pat, TRUE);
+		regmatch.rm_ic = FALSE;
+		if (end != NULL)
+		    *end = save_char;
+		p_cpo = save_cpo;
+		if (regmatch.regprog == NULL)
+		    EMSG2(_(e_invarg2), pat);
+		else
+		{
+		    /*
+		     * Save the value of got_int and reset it.  We don't want
+		     * a previous interruption cancel matching, only hitting
+		     * CTRL-C while matching should abort it.
+		     */
+		    prev_got_int = got_int;
+		    got_int = FALSE;
+		    caught = vim_regexec_nl(&regmatch, current_exception->value,
+			    (colnr_T)0);
+		    got_int |= prev_got_int;
+		    vim_free(regmatch.regprog);
+		}
+	    }
+	}
+
+	if (caught)
+	{
+	    /* Make this ":catch" clause active and reset did_emsg, got_int,
+	     * and did_throw.  Put the exception on the caught stack. */
+	    cstack->cs_flags[idx] |= CSF_ACTIVE | CSF_CAUGHT;
+	    did_emsg = got_int = did_throw = FALSE;
+	    catch_exception((except_T *)cstack->cs_exception[idx]);
+	    /* It's mandatory that the current exception is stored in the cstack
+	     * so that it can be discarded at the next ":catch", ":finally", or
+	     * ":endtry" or when the catch clause is left by a ":continue",
+	     * ":break", ":return", ":finish", error, interrupt, or another
+	     * exception. */
+	    if (cstack->cs_exception[cstack->cs_idx] != current_exception)
+		EMSG(_(e_internal));
+	}
+	else
+	{
+	    /*
+	     * If there is a preceding catch clause and it caught the exception,
+	     * finish the exception now.  This happens also after errors except
+	     * when this ":catch" was after the ":finally" or not within
+	     * a ":try".  Make the try conditional inactive so that the
+	     * following catch clauses are skipped.  On an error or interrupt
+	     * after the preceding try block or catch clause was left by
+	     * a ":continue", ":break", ":return", or ":finish", discard the
+	     * pending action.
+	     */
+	    cleanup_conditionals(cstack, CSF_TRY, TRUE);
+	}
+    }
+
+    if (end != NULL)
+	eap->nextcmd = find_nextcmd(end);
+}
+
+/*
+ * ":finally"
+ */
+    void
+ex_finally(eap)
+    exarg_T	*eap;
+{
+    int		idx;
+    int		skip = FALSE;
+    int		pending = CSTP_NONE;
+    struct condstack	*cstack = eap->cstack;
+
+    if (cstack->cs_trylevel <= 0 || cstack->cs_idx < 0)
+	eap->errmsg = (char_u *)N_("E606: :finally without :try");
+    else
+    {
+	if (!(cstack->cs_flags[cstack->cs_idx] & CSF_TRY))
+	{
+	    eap->errmsg = get_end_emsg(cstack);
+	    for (idx = cstack->cs_idx - 1; idx > 0; --idx)
+		if (cstack->cs_flags[idx] & CSF_TRY)
+		    break;
+	    /* Make this error pending, so that the commands in the following
+	     * finally clause can be executed.  This overrules also a pending
+	     * ":continue", ":break", ":return", or ":finish". */
+	    pending = CSTP_ERROR;
+	}
+	else
+	    idx = cstack->cs_idx;
+
+	if (cstack->cs_flags[idx] & CSF_FINALLY)
+	{
+	    /* Give up for a multiple ":finally" and ignore it. */
+	    eap->errmsg = (char_u *)N_("E607: multiple :finally");
+	    return;
+	}
+	rewind_conditionals(cstack, idx, CSF_WHILE | CSF_FOR,
+						       &cstack->cs_looplevel);
+
+	/*
+	 * Don't do something when the corresponding try block never got active
+	 * (because of an inactive surrounding conditional or after an error or
+	 * interrupt or throw) or for a ":finally" without ":try" or a multiple
+	 * ":finally".  After every other error (did_emsg or the conditional
+	 * errors detected above) or after an interrupt (got_int) or an
+	 * exception (did_throw), the finally clause must be executed.
+	 */
+	skip = !(cstack->cs_flags[cstack->cs_idx] & CSF_TRUE);
+
+	if (!skip)
+	{
+	    /* When debugging or a breakpoint was encountered, display the
+	     * debug prompt (if not already done).  The user then knows that the
+	     * finally clause is executed. */
+	    if (dbg_check_skipped(eap))
+	    {
+		/* Handle a ">quit" debug command as if an interrupt had
+		 * occurred before the ":finally".  That is, discard the
+		 * original exception and replace it by an interrupt
+		 * exception. */
+		(void)do_intthrow(cstack);
+	    }
+
+	    /*
+	     * If there is a preceding catch clause and it caught the exception,
+	     * finish the exception now.  This happens also after errors except
+	     * when this is a multiple ":finally" or one not within a ":try".
+	     * After an error or interrupt, this also discards a pending
+	     * ":continue", ":break", ":finish", or ":return" from the preceding
+	     * try block or catch clause.
+	     */
+	    cleanup_conditionals(cstack, CSF_TRY, FALSE);
+
+	    /*
+	     * Make did_emsg, got_int, did_throw pending.  If set, they overrule
+	     * a pending ":continue", ":break", ":return", or ":finish".  Then
+	     * we have particularly to discard a pending return value (as done
+	     * by the call to cleanup_conditionals() above when did_emsg or
+	     * got_int is set).  The pending values are restored by the
+	     * ":endtry", except if there is a new error, interrupt, exception,
+	     * ":continue", ":break", ":return", or ":finish" in the following
+	     * finally clause.  A missing ":endwhile", ":endfor" or ":endif"
+	     * detected here is treated as if did_emsg and did_throw had
+	     * already been set, respectively in case that the error is not
+	     * converted to an exception, did_throw had already been unset.
+	     * We must not set did_emsg here since that would suppress the
+	     * error message.
+	     */
+	    if (pending == CSTP_ERROR || did_emsg || got_int || did_throw)
+	    {
+		if (cstack->cs_pending[cstack->cs_idx] == CSTP_RETURN)
+		{
+		    report_discard_pending(CSTP_RETURN,
+					   cstack->cs_rettv[cstack->cs_idx]);
+		    discard_pending_return(cstack->cs_rettv[cstack->cs_idx]);
+		}
+		if (pending == CSTP_ERROR && !did_emsg)
+		    pending |= (THROW_ON_ERROR) ? CSTP_THROW : 0;
+		else
+		    pending |= did_throw ? CSTP_THROW : 0;
+		pending |= did_emsg  ? CSTP_ERROR     : 0;
+		pending |= got_int   ? CSTP_INTERRUPT : 0;
+		cstack->cs_pending[cstack->cs_idx] = pending;
+
+		/* It's mandatory that the current exception is stored in the
+		 * cstack so that it can be rethrown at the ":endtry" or be
+		 * discarded if the finally clause is left by a ":continue",
+		 * ":break", ":return", ":finish", error, interrupt, or another
+		 * exception.  When emsg() is called for a missing ":endif" or
+		 * a missing ":endwhile"/":endfor" detected here, the
+		 * exception will be discarded. */
+		if (did_throw && cstack->cs_exception[cstack->cs_idx]
+							 != current_exception)
+		    EMSG(_(e_internal));
+	    }
+
+	    /*
+	     * Set CSL_HAD_FINA, so do_cmdline() will reset did_emsg,
+	     * got_int, and did_throw and make the finally clause active.
+	     * This will happen after emsg() has been called for a missing
+	     * ":endif" or a missing ":endwhile"/":endfor" detected here, so
+	     * that the following finally clause will be executed even then.
+	     */
+	    cstack->cs_lflags |= CSL_HAD_FINA;
+	}
+    }
+}
+
+/*
+ * ":endtry"
+ */
+    void
+ex_endtry(eap)
+    exarg_T	*eap;
+{
+    int		idx;
+    int		skip;
+    int		rethrow = FALSE;
+    int		pending = CSTP_NONE;
+    void	*rettv = NULL;
+    struct condstack	*cstack = eap->cstack;
+
+    if (cstack->cs_trylevel <= 0 || cstack->cs_idx < 0)
+	eap->errmsg = (char_u *)N_("E602: :endtry without :try");
+    else
+    {
+	/*
+	 * Don't do something after an error, interrupt or throw in the try
+	 * block, catch clause, or finally clause preceding this ":endtry" or
+	 * when an error or interrupt occurred after a ":continue", ":break",
+	 * ":return", or ":finish" in a try block or catch clause preceding this
+	 * ":endtry" or when the try block never got active (because of an
+	 * inactive surrounding conditional or after an error or interrupt or
+	 * throw) or when there is a surrounding conditional and it has been
+	 * made inactive by a ":continue", ":break", ":return", or ":finish" in
+	 * the finally clause.  The latter case need not be tested since then
+	 * anything pending has already been discarded. */
+	skip = did_emsg || got_int || did_throw ||
+	    !(cstack->cs_flags[cstack->cs_idx] & CSF_TRUE);
+
+	if (!(cstack->cs_flags[cstack->cs_idx] & CSF_TRY))
+	{
+	    eap->errmsg = get_end_emsg(cstack);
+	    /* Find the matching ":try" and report what's missing. */
+	    idx = cstack->cs_idx;
+	    do
+		--idx;
+	    while (idx > 0 && !(cstack->cs_flags[idx] & CSF_TRY));
+	    rewind_conditionals(cstack, idx, CSF_WHILE | CSF_FOR,
+						       &cstack->cs_looplevel);
+	    skip = TRUE;
+
+	    /*
+	     * If an exception is being thrown, discard it to prevent it from
+	     * being rethrown at the end of this function.  It would be
+	     * discarded by the error message, anyway.  Resets did_throw.
+	     * This does not affect the script termination due to the error
+	     * since "trylevel" is decremented after emsg() has been called.
+	     */
+	    if (did_throw)
+		discard_current_exception();
+	}
+	else
+	{
+	    idx = cstack->cs_idx;
+
+	    /*
+	     * If we stopped with the exception currently being thrown at this
+	     * try conditional since we didn't know that it doesn't have
+	     * a finally clause, we need to rethrow it after closing the try
+	     * conditional.
+	     */
+	    if (did_throw && (cstack->cs_flags[idx] & CSF_TRUE)
+		    && !(cstack->cs_flags[idx] & CSF_FINALLY))
+		rethrow = TRUE;
+	}
+
+	/* If there was no finally clause, show the user when debugging or
+	 * a breakpoint was encountered that the end of the try conditional has
+	 * been reached: display the debug prompt (if not already done).  Do
+	 * this on normal control flow or when an exception was thrown, but not
+	 * on an interrupt or error not converted to an exception or when
+	 * a ":break", ":continue", ":return", or ":finish" is pending.  These
+	 * actions are carried out immediately.
+	 */
+	if ((rethrow || (!skip
+			&& !(cstack->cs_flags[idx] & CSF_FINALLY)
+			&& !cstack->cs_pending[idx]))
+		&& dbg_check_skipped(eap))
+	{
+	    /* Handle a ">quit" debug command as if an interrupt had occurred
+	     * before the ":endtry".  That is, throw an interrupt exception and
+	     * set "skip" and "rethrow". */
+	    if (got_int)
+	    {
+		skip = TRUE;
+		(void)do_intthrow(cstack);
+		/* The do_intthrow() call may have reset did_throw or
+		 * cstack->cs_pending[idx].*/
+		rethrow = FALSE;
+		if (did_throw && !(cstack->cs_flags[idx] & CSF_FINALLY))
+		    rethrow = TRUE;
+	    }
+	}
+
+	/*
+	 * If a ":return" is pending, we need to resume it after closing the
+	 * try conditional; remember the return value.  If there was a finally
+	 * clause making an exception pending, we need to rethrow it.  Make it
+	 * the exception currently being thrown.
+	 */
+	if (!skip)
+	{
+	    pending = cstack->cs_pending[idx];
+	    cstack->cs_pending[idx] = CSTP_NONE;
+	    if (pending == CSTP_RETURN)
+		rettv = cstack->cs_rettv[idx];
+	    else if (pending & CSTP_THROW)
+		current_exception = cstack->cs_exception[idx];
+	}
+
+	/*
+	 * Discard anything pending on an error, interrupt, or throw in the
+	 * finally clause.  If there was no ":finally", discard a pending
+	 * ":continue", ":break", ":return", or ":finish" if an error or
+	 * interrupt occurred afterwards, but before the ":endtry" was reached.
+	 * If an exception was caught by the last of the catch clauses and there
+	 * was no finally clause, finish the exception now.  This happens also
+	 * after errors except when this ":endtry" is not within a ":try".
+	 * Restore "emsg_silent" if it has been reset by this try conditional.
+	 */
+	(void)cleanup_conditionals(cstack, CSF_TRY | CSF_SILENT, TRUE);
+
+	--cstack->cs_idx;
+	--cstack->cs_trylevel;
+
+	if (!skip)
+	{
+	    report_resume_pending(pending,
+		    (pending == CSTP_RETURN) ? rettv :
+		    (pending & CSTP_THROW) ? (void *)current_exception : NULL);
+	    switch (pending)
+	    {
+		case CSTP_NONE:
+		    break;
+
+		/* Reactivate a pending ":continue", ":break", ":return",
+		 * ":finish" from the try block or a catch clause of this try
+		 * conditional.  This is skipped, if there was an error in an
+		 * (unskipped) conditional command or an interrupt afterwards
+		 * or if the finally clause is present and executed a new error,
+		 * interrupt, throw, ":continue", ":break", ":return", or
+		 * ":finish". */
+		case CSTP_CONTINUE:
+		    ex_continue(eap);
+		    break;
+		case CSTP_BREAK:
+		    ex_break(eap);
+		    break;
+		case CSTP_RETURN:
+		    do_return(eap, FALSE, FALSE, rettv);
+		    break;
+		case CSTP_FINISH:
+		    do_finish(eap, FALSE);
+		    break;
+
+		/* When the finally clause was entered due to an error,
+		 * interrupt or throw (as opposed to a ":continue", ":break",
+		 * ":return", or ":finish"), restore the pending values of
+		 * did_emsg, got_int, and did_throw.  This is skipped, if there
+		 * was a new error, interrupt, throw, ":continue", ":break",
+		 * ":return", or ":finish".  in the finally clause. */
+		default:
+		    if (pending & CSTP_ERROR)
+			did_emsg = TRUE;
+		    if (pending & CSTP_INTERRUPT)
+			got_int = TRUE;
+		    if (pending & CSTP_THROW)
+			rethrow = TRUE;
+		    break;
+	    }
+	}
+
+	if (rethrow)
+	    /* Rethrow the current exception (within this cstack). */
+	    do_throw(cstack);
+    }
+}
+
+/*
+ * enter_cleanup() and leave_cleanup()
+ *
+ * Functions to be called before/after invoking a sequence of autocommands for
+ * cleanup for a failed command.  (Failure means here that a call to emsg()
+ * has been made, an interrupt occurred, or there is an uncaught exception
+ * from a previous autocommand execution of the same command.)
+ *
+ * Call enter_cleanup() with a pointer to a cleanup_T and pass the same
+ * pointer to leave_cleanup().  The cleanup_T structure stores the pending
+ * error/interrupt/exception state.
+ */
+
+/*
+ * This function works a bit like ex_finally() except that there was not
+ * actually an extra try block around the part that failed and an error or
+ * interrupt has not (yet) been converted to an exception.  This function
+ * saves the error/interrupt/ exception state and prepares for the call to
+ * do_cmdline() that is going to be made for the cleanup autocommand
+ * execution.
+ */
+    void
+enter_cleanup(csp)
+    cleanup_T	*csp;
+{
+    int		pending = CSTP_NONE;
+
+    /*
+     * Postpone did_emsg, got_int, did_throw.  The pending values will be
+     * restored by leave_cleanup() except if there was an aborting error,
+     * interrupt, or uncaught exception after this function ends.
+     */
+    if (did_emsg || got_int || did_throw || need_rethrow)
+    {
+	csp->pending = (did_emsg     ? CSTP_ERROR     : 0)
+		     | (got_int      ? CSTP_INTERRUPT : 0)
+		     | (did_throw    ? CSTP_THROW     : 0)
+		     | (need_rethrow ? CSTP_THROW     : 0);
+
+	/* If we are currently throwing an exception (did_throw), save it as
+	 * well.  On an error not yet converted to an exception, update
+	 * "force_abort" and reset "cause_abort" (as do_errthrow() would do).
+	 * This is needed for the do_cmdline() call that is going to be made
+	 * for autocommand execution.  We need not save *msg_list because
+	 * there is an extra instance for every call of do_cmdline(), anyway.
+	 */
+	if (did_throw || need_rethrow)
+	    csp->exception = current_exception;
+	else
+	{
+	    csp->exception = NULL;
+	    if (did_emsg)
+	    {
+		force_abort |= cause_abort;
+		cause_abort = FALSE;
+	    }
+	}
+	did_emsg = got_int = did_throw = need_rethrow = FALSE;
+
+	/* Report if required by the 'verbose' option or when debugging.  */
+	report_make_pending(pending, csp->exception);
+    }
+    else
+    {
+	csp->pending = CSTP_NONE;
+	csp->exception = NULL;
+    }
+}
+
+/*
+ * See comment above enter_cleanup() for how this function is used.
+ *
+ * This function is a bit like ex_endtry() except that there was not actually
+ * an extra try block around the part that failed and an error or interrupt
+ * had not (yet) been converted to an exception when the cleanup autocommand
+ * sequence was invoked.
+ *
+ * This function has to be called with the address of the cleanup_T structure
+ * filled by enter_cleanup() as an argument; it restores the error/interrupt/
+ * exception state saved by that function - except there was an aborting
+ * error, an interrupt or an uncaught exception during execution of the
+ * cleanup autocommands.  In the latter case, the saved error/interrupt/
+ * exception state is discarded.
+ */
+    void
+leave_cleanup(csp)
+    cleanup_T	*csp;
+{
+    int		pending = csp->pending;
+
+    if (pending == CSTP_NONE)	/* nothing to do */
+	return;
+
+    /* If there was an aborting error, an interrupt, or an uncaught exception
+     * after the corresponding call to enter_cleanup(), discard what has been
+     * made pending by it.  Report this to the user if required by the
+     * 'verbose' option or when debugging. */
+    if (aborting() || need_rethrow)
+    {
+	if (pending & CSTP_THROW)
+	    /* Cancel the pending exception (includes report). */
+	    discard_exception((except_T *)csp->exception, FALSE);
+	else
+	    report_discard_pending(pending, NULL);
+
+	/* If an error was about to be converted to an exception when
+	 * enter_cleanup() was called, free the message list. */
+	if (msg_list != NULL)
+	{
+	    free_msglist(*msg_list);
+	    *msg_list = NULL;
+	}
+    }
+
+    /*
+     * If there was no new error, interrupt, or throw between the calls
+     * to enter_cleanup() and leave_cleanup(), restore the pending
+     * error/interrupt/exception state.
+     */
+    else
+    {
+	/*
+	 * If there was an exception being thrown when enter_cleanup() was
+	 * called, we need to rethrow it.  Make it the exception currently
+	 * being thrown.
+	 */
+	if (pending & CSTP_THROW)
+	    current_exception = csp->exception;
+
+	/*
+	 * If an error was about to be converted to an exception when
+	 * enter_cleanup() was called, let "cause_abort" take the part of
+	 * "force_abort" (as done by cause_errthrow()).
+	 */
+	else if (pending & CSTP_ERROR)
+	{
+	    cause_abort = force_abort;
+	    force_abort = FALSE;
+	}
+
+	/*
+	 * Restore the pending values of did_emsg, got_int, and did_throw.
+	 */
+	if (pending & CSTP_ERROR)
+	    did_emsg = TRUE;
+	if (pending & CSTP_INTERRUPT)
+	    got_int = TRUE;
+	if (pending & CSTP_THROW)
+	    need_rethrow = TRUE;    /* did_throw will be set by do_one_cmd() */
+
+	/* Report if required by the 'verbose' option or when debugging. */
+	report_resume_pending(pending,
+		   (pending & CSTP_THROW) ? (void *)current_exception : NULL);
+    }
+}
+
+
+/*
+ * Make conditionals inactive and discard what's pending in finally clauses
+ * until the conditional type searched for or a try conditional not in its
+ * finally clause is reached.  If this is in an active catch clause, finish
+ * the caught exception.
+ * Return the cstack index where the search stopped.
+ * Values used for "searched_cond" are (CSF_WHILE | CSF_FOR) or CSF_TRY or 0,
+ * the latter meaning the innermost try conditional not in its finally clause.
+ * "inclusive" tells whether the conditional searched for should be made
+ * inactive itself (a try conditional not in its finally claused possibly find
+ * before is always made inactive).  If "inclusive" is TRUE and
+ * "searched_cond" is CSF_TRY|CSF_SILENT, the saved former value of
+ * "emsg_silent", if reset when the try conditional finally reached was
+ * entered, is restored (unsed by ex_endtry()).  This is normally done only
+ * when such a try conditional is left.
+ */
+    int
+cleanup_conditionals(cstack, searched_cond, inclusive)
+    struct condstack   *cstack;
+    int		searched_cond;
+    int		inclusive;
+{
+    int		idx;
+    int		stop = FALSE;
+
+    for (idx = cstack->cs_idx; idx >= 0; --idx)
+    {
+	if (cstack->cs_flags[idx] & CSF_TRY)
+	{
+	    /*
+	     * Discard anything pending in a finally clause and continue the
+	     * search.  There may also be a pending ":continue", ":break",
+	     * ":return", or ":finish" before the finally clause.  We must not
+	     * discard it, unless an error or interrupt occurred afterwards.
+	     */
+	    if (did_emsg || got_int || (cstack->cs_flags[idx] & CSF_FINALLY))
+	    {
+		switch (cstack->cs_pending[idx])
+		{
+		    case CSTP_NONE:
+			break;
+
+		    case CSTP_CONTINUE:
+		    case CSTP_BREAK:
+		    case CSTP_FINISH:
+			report_discard_pending(cstack->cs_pending[idx], NULL);
+			cstack->cs_pending[idx] = CSTP_NONE;
+			break;
+
+		    case CSTP_RETURN:
+			report_discard_pending(CSTP_RETURN,
+						      cstack->cs_rettv[idx]);
+			discard_pending_return(cstack->cs_rettv[idx]);
+			cstack->cs_pending[idx] = CSTP_NONE;
+			break;
+
+		    default:
+			if (cstack->cs_flags[idx] & CSF_FINALLY)
+			{
+			    if (cstack->cs_pending[idx] & CSTP_THROW)
+			    {
+				/* Cancel the pending exception.  This is in the
+				 * finally clause, so that the stack of the
+				 * caught exceptions is not involved. */
+				discard_exception((except_T *)
+					cstack->cs_exception[idx],
+					FALSE);
+			    }
+			    else
+				report_discard_pending(cstack->cs_pending[idx],
+					NULL);
+			    cstack->cs_pending[idx] = CSTP_NONE;
+			}
+			break;
+		}
+	    }
+
+	    /*
+	     * Stop at a try conditional not in its finally clause.  If this try
+	     * conditional is in an active catch clause, finish the caught
+	     * exception.
+	     */
+	    if (!(cstack->cs_flags[idx] & CSF_FINALLY))
+	    {
+		if ((cstack->cs_flags[idx] & CSF_ACTIVE)
+			&& (cstack->cs_flags[idx] & CSF_CAUGHT))
+		    finish_exception((except_T *)cstack->cs_exception[idx]);
+		/* Stop at this try conditional - except the try block never
+		 * got active (because of an inactive surrounding conditional
+		 * or when the ":try" appeared after an error or interrupt or
+		 * throw). */
+		if (cstack->cs_flags[idx] & CSF_TRUE)
+		{
+		    if (searched_cond == 0 && !inclusive)
+			break;
+		    stop = TRUE;
+		}
+	    }
+	}
+
+	/* Stop on the searched conditional type (even when the surrounding
+	 * conditional is not active or something has been made pending).
+	 * If "inclusive" is TRUE and "searched_cond" is CSF_TRY|CSF_SILENT,
+	 * check first whether "emsg_silent" needs to be restored. */
+	if (cstack->cs_flags[idx] & searched_cond)
+	{
+	    if (!inclusive)
+		break;
+	    stop = TRUE;
+	}
+	cstack->cs_flags[idx] &= ~CSF_ACTIVE;
+	if (stop && searched_cond != (CSF_TRY | CSF_SILENT))
+	    break;
+
+	/*
+	 * When leaving a try conditional that reset "emsg_silent" on its
+	 * entry after saving the original value, restore that value here and
+	 * free the memory used to store it.
+	 */
+	if ((cstack->cs_flags[idx] & CSF_TRY)
+		&& (cstack->cs_flags[idx] & CSF_SILENT))
+	{
+	    eslist_T	*elem;
+
+	    elem = cstack->cs_emsg_silent_list;
+	    cstack->cs_emsg_silent_list = elem->next;
+	    emsg_silent = elem->saved_emsg_silent;
+	    vim_free(elem);
+	    cstack->cs_flags[idx] &= ~CSF_SILENT;
+	}
+	if (stop)
+	    break;
+    }
+    return idx;
+}
+
+/*
+ * Return an appropriate error message for a missing endwhile/endfor/endif.
+ */
+   static char_u *
+get_end_emsg(cstack)
+    struct condstack	*cstack;
+{
+    if (cstack->cs_flags[cstack->cs_idx] & CSF_WHILE)
+	return e_endwhile;
+    if (cstack->cs_flags[cstack->cs_idx] & CSF_FOR)
+	return e_endfor;
+    return e_endif;
+}
+
+
+/*
+ * Rewind conditionals until index "idx" is reached.  "cond_type" and
+ * "cond_level" specify a conditional type and the address of a level variable
+ * which is to be decremented with each skipped conditional of the specified
+ * type.
+ * Also free "for info" structures where needed.
+ */
+    void
+rewind_conditionals(cstack, idx, cond_type, cond_level)
+    struct condstack   *cstack;
+    int		idx;
+    int		cond_type;
+    int		*cond_level;
+{
+    while (cstack->cs_idx > idx)
+    {
+	if (cstack->cs_flags[cstack->cs_idx] & cond_type)
+	    --*cond_level;
+	if (cstack->cs_flags[cstack->cs_idx] & CSF_FOR)
+	    free_for_info(cstack->cs_forinfo[cstack->cs_idx]);
+	--cstack->cs_idx;
+    }
+}
+
+/*
+ * ":endfunction" when not after a ":function"
+ */
+/*ARGSUSED*/
+    void
+ex_endfunction(eap)
+    exarg_T	*eap;
+{
+    EMSG(_("E193: :endfunction not inside a function"));
+}
+
+/*
+ * Return TRUE if the string "p" looks like a ":while" or ":for" command.
+ */
+    int
+has_loop_cmd(p)
+    char_u	*p;
+{
+    p = skipwhite(p);
+    while (*p == ':')
+	p = skipwhite(p + 1);
+    if ((p[0] == 'w' && p[1] == 'h')
+	    || (p[0] == 'f' && p[1] == 'o' && p[2] == 'r'))
+	return TRUE;
+    return FALSE;
+}
+
+#endif /* FEAT_EVAL */
--- /dev/null
+++ b/ex_getln.c
@@ -1,0 +1,6171 @@
+/* vi:set ts=8 sts=4 sw=4:
+ *
+ * VIM - Vi IMproved	by Bram Moolenaar
+ *
+ * Do ":help uganda"  in Vim to read copying and usage conditions.
+ * Do ":help credits" in Vim to see a list of people who contributed.
+ * See README.txt for an overview of the Vim source code.
+ */
+
+/*
+ * ex_getln.c: Functions for entering and editing an Ex command line.
+ */
+
+#include "vim.h"
+
+/*
+ * Variables shared between getcmdline(), redrawcmdline() and others.
+ * These need to be saved when using CTRL-R |, that's why they are in a
+ * structure.
+ */
+struct cmdline_info
+{
+    char_u	*cmdbuff;	/* pointer to command line buffer */
+    int		cmdbufflen;	/* length of cmdbuff */
+    int		cmdlen;		/* number of chars in command line */
+    int		cmdpos;		/* current cursor position */
+    int		cmdspos;	/* cursor column on screen */
+    int		cmdfirstc;	/* ':', '/', '?', '=' or NUL */
+    int		cmdindent;	/* number of spaces before cmdline */
+    char_u	*cmdprompt;	/* message in front of cmdline */
+    int		cmdattr;	/* attributes for prompt */
+    int		overstrike;	/* Typing mode on the command line.  Shared by
+				   getcmdline() and put_on_cmdline(). */
+    int		xp_context;	/* type of expansion */
+# ifdef FEAT_EVAL
+    char_u	*xp_arg;	/* user-defined expansion arg */
+    int		input_fn;	/* when TRUE Invoked for input() function */
+# endif
+};
+
+static struct cmdline_info ccline;	/* current cmdline_info */
+
+static int	cmd_showtail;		/* Only show path tail in lists ? */
+
+#ifdef FEAT_EVAL
+static int	new_cmdpos;	/* position set by set_cmdline_pos() */
+#endif
+
+#ifdef FEAT_CMDHIST
+typedef struct hist_entry
+{
+    int		hisnum;		/* identifying number */
+    char_u	*hisstr;	/* actual entry, separator char after the NUL */
+} histentry_T;
+
+static histentry_T *(history[HIST_COUNT]) = {NULL, NULL, NULL, NULL, NULL};
+static int	hisidx[HIST_COUNT] = {-1, -1, -1, -1, -1};  /* lastused entry */
+static int	hisnum[HIST_COUNT] = {0, 0, 0, 0, 0};
+		    /* identifying (unique) number of newest history entry */
+static int	hislen = 0;		/* actual length of history tables */
+
+static int	hist_char2type __ARGS((int c));
+
+static int	in_history __ARGS((int, char_u *, int));
+# ifdef FEAT_EVAL
+static int	calc_hist_idx __ARGS((int histype, int num));
+# endif
+#endif
+
+#ifdef FEAT_RIGHTLEFT
+static int	cmd_hkmap = 0;	/* Hebrew mapping during command line */
+#endif
+
+#ifdef FEAT_FKMAP
+static int	cmd_fkmap = 0;	/* Farsi mapping during command line */
+#endif
+
+static int	cmdline_charsize __ARGS((int idx));
+static void	set_cmdspos __ARGS((void));
+static void	set_cmdspos_cursor __ARGS((void));
+#ifdef FEAT_MBYTE
+static void	correct_cmdspos __ARGS((int idx, int cells));
+#endif
+static void	alloc_cmdbuff __ARGS((int len));
+static int	realloc_cmdbuff __ARGS((int len));
+static void	draw_cmdline __ARGS((int start, int len));
+static void	save_cmdline __ARGS((struct cmdline_info *ccp));
+static void	restore_cmdline __ARGS((struct cmdline_info *ccp));
+static int	cmdline_paste __ARGS((int regname, int literally, int remcr));
+#if defined(FEAT_XIM) && defined(FEAT_GUI_GTK)
+static void	redrawcmd_preedit __ARGS((void));
+#endif
+#ifdef FEAT_WILDMENU
+static void	cmdline_del __ARGS((int from));
+#endif
+static void	redrawcmdprompt __ARGS((void));
+static void	cursorcmd __ARGS((void));
+static int	ccheck_abbr __ARGS((int));
+static int	nextwild __ARGS((expand_T *xp, int type, int options));
+static void	escape_fname __ARGS((char_u **pp));
+static int	showmatches __ARGS((expand_T *xp, int wildmenu));
+static void	set_expand_context __ARGS((expand_T *xp));
+static int	ExpandFromContext __ARGS((expand_T *xp, char_u *, int *, char_u ***, int));
+static int	expand_showtail __ARGS((expand_T *xp));
+#ifdef FEAT_CMDL_COMPL
+static int	expand_shellcmd __ARGS((char_u *filepat, int *num_file, char_u ***file, int flagsarg));
+static int	ExpandRTDir __ARGS((char_u *pat, int *num_file, char_u ***file, char *dirname));
+# if defined(FEAT_USR_CMDS) && defined(FEAT_EVAL)
+static int	ExpandUserDefined __ARGS((expand_T *xp, regmatch_T *regmatch, int *num_file, char_u ***file));
+static int	ExpandUserList __ARGS((expand_T *xp, int *num_file, char_u ***file));
+# endif
+#endif
+
+#ifdef FEAT_CMDWIN
+static int	ex_window __ARGS((void));
+#endif
+
+/*
+ * getcmdline() - accept a command line starting with firstc.
+ *
+ * firstc == ':'	    get ":" command line.
+ * firstc == '/' or '?'	    get search pattern
+ * firstc == '='	    get expression
+ * firstc == '@'	    get text for input() function
+ * firstc == '>'	    get text for debug mode
+ * firstc == NUL	    get text for :insert command
+ * firstc == -1		    like NUL, and break on CTRL-C
+ *
+ * The line is collected in ccline.cmdbuff, which is reallocated to fit the
+ * command line.
+ *
+ * Careful: getcmdline() can be called recursively!
+ *
+ * Return pointer to allocated string if there is a commandline, NULL
+ * otherwise.
+ */
+/*ARGSUSED*/
+    char_u *
+getcmdline(firstc, count, indent)
+    int		firstc;
+    long	count;		/* only used for incremental search */
+    int		indent;		/* indent for inside conditionals */
+{
+    int		c;
+    int		i;
+    int		j;
+    int		gotesc = FALSE;		/* TRUE when <ESC> just typed */
+    int		do_abbr;		/* when TRUE check for abbr. */
+#ifdef FEAT_CMDHIST
+    char_u	*lookfor = NULL;	/* string to match */
+    int		hiscnt;			/* current history line in use */
+    int		histype;		/* history type to be used */
+#endif
+#ifdef FEAT_SEARCH_EXTRA
+    pos_T	old_cursor;
+    colnr_T	old_curswant;
+    colnr_T	old_leftcol;
+    linenr_T	old_topline;
+# ifdef FEAT_DIFF
+    int		old_topfill;
+# endif
+    linenr_T	old_botline;
+    int		did_incsearch = FALSE;
+    int		incsearch_postponed = FALSE;
+#endif
+    int		did_wild_list = FALSE;	/* did wild_list() recently */
+    int		wim_index = 0;		/* index in wim_flags[] */
+    int		res;
+    int		save_msg_scroll = msg_scroll;
+    int		save_State = State;	/* remember State when called */
+    int		some_key_typed = FALSE;	/* one of the keys was typed */
+#ifdef FEAT_MOUSE
+    /* mouse drag and release events are ignored, unless they are
+     * preceded with a mouse down event */
+    int		ignore_drag_release = TRUE;
+#endif
+#ifdef FEAT_EVAL
+    int		break_ctrl_c = FALSE;
+#endif
+    expand_T	xpc;
+    long	*b_im_ptr = NULL;
+#if defined(FEAT_WILDMENU) || defined(FEAT_EVAL) || defined(FEAT_SEARCH_EXTRA)
+    /* Everything that may work recursively should save and restore the
+     * current command line in save_ccline.  That includes update_screen(), a
+     * custom status line may invoke ":normal". */
+    struct cmdline_info save_ccline;
+#endif
+
+#ifdef FEAT_SNIFF
+    want_sniff_request = 0;
+#endif
+#ifdef FEAT_EVAL
+    if (firstc == -1)
+    {
+	firstc = NUL;
+	break_ctrl_c = TRUE;
+    }
+#endif
+#ifdef FEAT_RIGHTLEFT
+    /* start without Hebrew mapping for a command line */
+    if (firstc == ':' || firstc == '=' || firstc == '>')
+	cmd_hkmap = 0;
+#endif
+
+    ccline.overstrike = FALSE;		    /* always start in insert mode */
+#ifdef FEAT_SEARCH_EXTRA
+    old_cursor = curwin->w_cursor;	    /* needs to be restored later */
+    old_curswant = curwin->w_curswant;
+    old_leftcol = curwin->w_leftcol;
+    old_topline = curwin->w_topline;
+# ifdef FEAT_DIFF
+    old_topfill = curwin->w_topfill;
+# endif
+    old_botline = curwin->w_botline;
+#endif
+
+    /*
+     * set some variables for redrawcmd()
+     */
+    ccline.cmdfirstc = (firstc == '@' ? 0 : firstc);
+    ccline.cmdindent = (firstc > 0 ? indent : 0);
+
+    /* alloc initial ccline.cmdbuff */
+    alloc_cmdbuff(exmode_active ? 250 : indent + 1);
+    if (ccline.cmdbuff == NULL)
+	return NULL;			    /* out of memory */
+    ccline.cmdlen = ccline.cmdpos = 0;
+    ccline.cmdbuff[0] = NUL;
+
+    /* autoindent for :insert and :append */
+    if (firstc <= 0)
+    {
+	copy_spaces(ccline.cmdbuff, indent);
+	ccline.cmdbuff[indent] = NUL;
+	ccline.cmdpos = indent;
+	ccline.cmdspos = indent;
+	ccline.cmdlen = indent;
+    }
+
+    ExpandInit(&xpc);
+
+#ifdef FEAT_RIGHTLEFT
+    if (curwin->w_p_rl && *curwin->w_p_rlc == 's'
+					  && (firstc == '/' || firstc == '?'))
+	cmdmsg_rl = TRUE;
+    else
+	cmdmsg_rl = FALSE;
+#endif
+
+    redir_off = TRUE;		/* don't redirect the typed command */
+    if (!cmd_silent)
+    {
+	i = msg_scrolled;
+	msg_scrolled = 0;		/* avoid wait_return message */
+	gotocmdline(TRUE);
+	msg_scrolled += i;
+	redrawcmdprompt();		/* draw prompt or indent */
+	set_cmdspos();
+    }
+    xpc.xp_context = EXPAND_NOTHING;
+    xpc.xp_backslash = XP_BS_NONE;
+#ifndef BACKSLASH_IN_FILENAME
+    xpc.xp_shell = FALSE;
+#endif
+
+#if defined(FEAT_EVAL)
+    if (ccline.input_fn)
+    {
+	xpc.xp_context = ccline.xp_context;
+	xpc.xp_pattern = ccline.cmdbuff;
+	xpc.xp_arg = ccline.xp_arg;
+    }
+#endif
+
+    /*
+     * Avoid scrolling when called by a recursive do_cmdline(), e.g. when
+     * doing ":@0" when register 0 doesn't contain a CR.
+     */
+    msg_scroll = FALSE;
+
+    State = CMDLINE;
+
+    if (firstc == '/' || firstc == '?' || firstc == '@')
+    {
+	/* Use ":lmap" mappings for search pattern and input(). */
+	if (curbuf->b_p_imsearch == B_IMODE_USE_INSERT)
+	    b_im_ptr = &curbuf->b_p_iminsert;
+	else
+	    b_im_ptr = &curbuf->b_p_imsearch;
+	if (*b_im_ptr == B_IMODE_LMAP)
+	    State |= LANGMAP;
+#ifdef USE_IM_CONTROL
+	im_set_active(*b_im_ptr == B_IMODE_IM);
+#endif
+    }
+#ifdef USE_IM_CONTROL
+    else if (p_imcmdline)
+	im_set_active(TRUE);
+#endif
+
+#ifdef FEAT_MOUSE
+    setmouse();
+#endif
+#ifdef CURSOR_SHAPE
+    ui_cursor_shape();		/* may show different cursor shape */
+#endif
+
+    /* When inside an autocommand for writing "exiting" may be set and
+     * terminal mode set to cooked.  Need to set raw mode here then. */
+    settmode(TMODE_RAW);
+
+#ifdef FEAT_CMDHIST
+    init_history();
+    hiscnt = hislen;		/* set hiscnt to impossible history value */
+    histype = hist_char2type(firstc);
+#endif
+
+#ifdef FEAT_DIGRAPHS
+    do_digraph(-1);		/* init digraph typahead */
+#endif
+
+    /*
+     * Collect the command string, handling editing keys.
+     */
+    for (;;)
+    {
+	redir_off = TRUE;	/* Don't redirect the typed command.
+				   Repeated, because a ":redir" inside
+				   completion may switch it on. */
+#ifdef USE_ON_FLY_SCROLL
+	dont_scroll = FALSE;	/* allow scrolling here */
+#endif
+	quit_more = FALSE;	/* reset after CTRL-D which had a more-prompt */
+
+	cursorcmd();		/* set the cursor on the right spot */
+	c = safe_vgetc();
+	if (KeyTyped)
+	{
+	    some_key_typed = TRUE;
+#ifdef FEAT_RIGHTLEFT
+	    if (cmd_hkmap)
+		c = hkmap(c);
+# ifdef FEAT_FKMAP
+	    if (cmd_fkmap)
+		c = cmdl_fkmap(c);
+# endif
+	    if (cmdmsg_rl && !KeyStuffed)
+	    {
+		/* Invert horizontal movements and operations.  Only when
+		 * typed by the user directly, not when the result of a
+		 * mapping. */
+		switch (c)
+		{
+		    case K_RIGHT:   c = K_LEFT; break;
+		    case K_S_RIGHT: c = K_S_LEFT; break;
+		    case K_C_RIGHT: c = K_C_LEFT; break;
+		    case K_LEFT:    c = K_RIGHT; break;
+		    case K_S_LEFT:  c = K_S_RIGHT; break;
+		    case K_C_LEFT:  c = K_C_RIGHT; break;
+		}
+	    }
+#endif
+	}
+
+	/*
+	 * Ignore got_int when CTRL-C was typed here.
+	 * Don't ignore it in :global, we really need to break then, e.g., for
+	 * ":g/pat/normal /pat" (without the <CR>).
+	 * Don't ignore it for the input() function.
+	 */
+	if ((c == Ctrl_C
+#ifdef UNIX
+		|| c == intr_char
+#endif
+				)
+#if defined(FEAT_EVAL) || defined(FEAT_CRYPT)
+		&& firstc != '@'
+#endif
+#ifdef FEAT_EVAL
+		&& !break_ctrl_c
+#endif
+		&& !global_busy)
+	    got_int = FALSE;
+
+#ifdef FEAT_CMDHIST
+	/* free old command line when finished moving around in the history
+	 * list */
+	if (lookfor != NULL
+		&& c != K_S_DOWN && c != K_S_UP
+		&& c != K_DOWN && c != K_UP
+		&& c != K_PAGEDOWN && c != K_PAGEUP
+		&& c != K_KPAGEDOWN && c != K_KPAGEUP
+		&& c != K_LEFT && c != K_RIGHT
+		&& (xpc.xp_numfiles > 0 || (c != Ctrl_P && c != Ctrl_N)))
+	{
+	    vim_free(lookfor);
+	    lookfor = NULL;
+	}
+#endif
+
+	/*
+	 * <S-Tab> works like CTRL-P (unless 'wc' is <S-Tab>).
+	 */
+	if (c != p_wc && c == K_S_TAB && xpc.xp_numfiles != -1)
+	    c = Ctrl_P;
+
+#ifdef FEAT_WILDMENU
+	/* Special translations for 'wildmenu' */
+	if (did_wild_list && p_wmnu)
+	{
+	    if (c == K_LEFT)
+		c = Ctrl_P;
+	    else if (c == K_RIGHT)
+		c = Ctrl_N;
+	}
+	/* Hitting CR after "emenu Name.": complete submenu */
+	if (xpc.xp_context == EXPAND_MENUNAMES && p_wmnu
+		&& ccline.cmdpos > 1
+		&& ccline.cmdbuff[ccline.cmdpos - 1] == '.'
+		&& ccline.cmdbuff[ccline.cmdpos - 2] != '\\'
+		&& (c == '\n' || c == '\r' || c == K_KENTER))
+	    c = K_DOWN;
+#endif
+
+	/* free expanded names when finished walking through matches */
+	if (xpc.xp_numfiles != -1
+		&& !(c == p_wc && KeyTyped) && c != p_wcm
+		&& c != Ctrl_N && c != Ctrl_P && c != Ctrl_A
+		&& c != Ctrl_L)
+	{
+	    (void)ExpandOne(&xpc, NULL, NULL, 0, WILD_FREE);
+	    did_wild_list = FALSE;
+#ifdef FEAT_WILDMENU
+	    if (!p_wmnu || (c != K_UP && c != K_DOWN))
+#endif
+		xpc.xp_context = EXPAND_NOTHING;
+	    wim_index = 0;
+#ifdef FEAT_WILDMENU
+	    if (p_wmnu && wild_menu_showing != 0)
+	    {
+		int skt = KeyTyped;
+		int old_RedrawingDisabled = RedrawingDisabled;
+
+		if (ccline.input_fn)
+		    RedrawingDisabled = 0;
+
+		if (wild_menu_showing == WM_SCROLLED)
+		{
+		    /* Entered command line, move it up */
+		    cmdline_row--;
+		    redrawcmd();
+		}
+		else if (save_p_ls != -1)
+		{
+		    /* restore 'laststatus' and 'winminheight' */
+		    p_ls = save_p_ls;
+		    p_wmh = save_p_wmh;
+		    last_status(FALSE);
+		    save_cmdline(&save_ccline);
+		    update_screen(VALID);	/* redraw the screen NOW */
+		    restore_cmdline(&save_ccline);
+		    redrawcmd();
+		    save_p_ls = -1;
+		}
+		else
+		{
+# ifdef FEAT_VERTSPLIT
+		    win_redraw_last_status(topframe);
+# else
+		    lastwin->w_redr_status = TRUE;
+# endif
+		    redraw_statuslines();
+		}
+		KeyTyped = skt;
+		wild_menu_showing = 0;
+		if (ccline.input_fn)
+		    RedrawingDisabled = old_RedrawingDisabled;
+	    }
+#endif
+	}
+
+#ifdef FEAT_WILDMENU
+	/* Special translations for 'wildmenu' */
+	if (xpc.xp_context == EXPAND_MENUNAMES && p_wmnu)
+	{
+	    /* Hitting <Down> after "emenu Name.": complete submenu */
+	    if (ccline.cmdbuff[ccline.cmdpos - 1] == '.' && c == K_DOWN)
+		c = p_wc;
+	    else if (c == K_UP)
+	    {
+		/* Hitting <Up>: Remove one submenu name in front of the
+		 * cursor */
+		int found = FALSE;
+
+		j = (int)(xpc.xp_pattern - ccline.cmdbuff);
+		i = 0;
+		while (--j > 0)
+		{
+		    /* check for start of menu name */
+		    if (ccline.cmdbuff[j] == ' '
+			    && ccline.cmdbuff[j - 1] != '\\')
+		    {
+			i = j + 1;
+			break;
+		    }
+		    /* check for start of submenu name */
+		    if (ccline.cmdbuff[j] == '.'
+			    && ccline.cmdbuff[j - 1] != '\\')
+		    {
+			if (found)
+			{
+			    i = j + 1;
+			    break;
+			}
+			else
+			    found = TRUE;
+		    }
+		}
+		if (i > 0)
+		    cmdline_del(i);
+		c = p_wc;
+		xpc.xp_context = EXPAND_NOTHING;
+	    }
+	}
+	if ((xpc.xp_context == EXPAND_FILES
+			      || xpc.xp_context == EXPAND_SHELLCMD) && p_wmnu)
+	{
+	    char_u upseg[5];
+
+	    upseg[0] = PATHSEP;
+	    upseg[1] = '.';
+	    upseg[2] = '.';
+	    upseg[3] = PATHSEP;
+	    upseg[4] = NUL;
+
+	    if (ccline.cmdbuff[ccline.cmdpos - 1] == PATHSEP
+		    && c == K_DOWN
+		    && (ccline.cmdbuff[ccline.cmdpos - 2] != '.'
+			|| ccline.cmdbuff[ccline.cmdpos - 3] != '.'))
+	    {
+		/* go down a directory */
+		c = p_wc;
+	    }
+	    else if (STRNCMP(xpc.xp_pattern, upseg + 1, 3) == 0 && c == K_DOWN)
+	    {
+		/* If in a direct ancestor, strip off one ../ to go down */
+		int found = FALSE;
+
+		j = ccline.cmdpos;
+		i = (int)(xpc.xp_pattern - ccline.cmdbuff);
+		while (--j > i)
+		{
+#ifdef FEAT_MBYTE
+		    if (has_mbyte)
+			j -= (*mb_head_off)(ccline.cmdbuff, ccline.cmdbuff + j);
+#endif
+		    if (vim_ispathsep(ccline.cmdbuff[j]))
+		    {
+			found = TRUE;
+			break;
+		    }
+		}
+		if (found
+			&& ccline.cmdbuff[j - 1] == '.'
+			&& ccline.cmdbuff[j - 2] == '.'
+			&& (vim_ispathsep(ccline.cmdbuff[j - 3]) || j == i + 2))
+		{
+		    cmdline_del(j - 2);
+		    c = p_wc;
+		}
+	    }
+	    else if (c == K_UP)
+	    {
+		/* go up a directory */
+		int found = FALSE;
+
+		j = ccline.cmdpos - 1;
+		i = (int)(xpc.xp_pattern - ccline.cmdbuff);
+		while (--j > i)
+		{
+#ifdef FEAT_MBYTE
+		    if (has_mbyte)
+			j -= (*mb_head_off)(ccline.cmdbuff, ccline.cmdbuff + j);
+#endif
+		    if (vim_ispathsep(ccline.cmdbuff[j])
+#ifdef BACKSLASH_IN_FILENAME
+			    && vim_strchr(" *?[{`$%#", ccline.cmdbuff[j + 1])
+			       == NULL
+#endif
+		       )
+		    {
+			if (found)
+			{
+			    i = j + 1;
+			    break;
+			}
+			else
+			    found = TRUE;
+		    }
+		}
+
+		if (!found)
+		    j = i;
+		else if (STRNCMP(ccline.cmdbuff + j, upseg, 4) == 0)
+		    j += 4;
+		else if (STRNCMP(ccline.cmdbuff + j, upseg + 1, 3) == 0
+			     && j == i)
+		    j += 3;
+		else
+		    j = 0;
+		if (j > 0)
+		{
+		    /* TODO this is only for DOS/UNIX systems - need to put in
+		     * machine-specific stuff here and in upseg init */
+		    cmdline_del(j);
+		    put_on_cmdline(upseg + 1, 3, FALSE);
+		}
+		else if (ccline.cmdpos > i)
+		    cmdline_del(i);
+		c = p_wc;
+	    }
+	}
+#if 0 /* If enabled <Down> on a file takes you _completely_ out of wildmenu */
+	if (p_wmnu
+		&& (xpc.xp_context == EXPAND_FILES
+		    || xpc.xp_context == EXPAND_MENUNAMES)
+		&& (c == K_UP || c == K_DOWN))
+	    xpc.xp_context = EXPAND_NOTHING;
+#endif
+
+#endif	/* FEAT_WILDMENU */
+
+	/* CTRL-\ CTRL-N goes to Normal mode, CTRL-\ CTRL-G goes to Insert
+	 * mode when 'insertmode' is set, CTRL-\ e prompts for an expression. */
+	if (c == Ctrl_BSL)
+	{
+	    ++no_mapping;
+	    ++allow_keys;
+	    c = safe_vgetc();
+	    --no_mapping;
+	    --allow_keys;
+	    /* CTRL-\ e doesn't work when obtaining an expression. */
+	    if (c != Ctrl_N && c != Ctrl_G
+				     && (c != 'e' || ccline.cmdfirstc == '='))
+	    {
+		vungetc(c);
+		c = Ctrl_BSL;
+	    }
+#ifdef FEAT_EVAL
+	    else if (c == 'e')
+	    {
+		char_u		    *p = NULL;
+
+		/*
+		 * Replace the command line with the result of an expression.
+		 * Need to save and restore the current command line, to be
+		 * able to enter a new one...
+		 */
+		if (ccline.cmdpos == ccline.cmdlen)
+		    new_cmdpos = 99999;	/* keep it at the end */
+		else
+		    new_cmdpos = ccline.cmdpos;
+
+		save_cmdline(&save_ccline);
+		c = get_expr_register();
+		restore_cmdline(&save_ccline);
+		if (c == '=')
+		{
+		    /* Need to save and restore ccline.  And set "textlock"
+		     * to avoid nasty things like going to another buffer when
+		     * evaluating an expression. */
+		    save_cmdline(&save_ccline);
+		    ++textlock;
+		    p = get_expr_line();
+		    --textlock;
+		    restore_cmdline(&save_ccline);
+
+		    if (p != NULL && realloc_cmdbuff((int)STRLEN(p) + 1) == OK)
+		    {
+			ccline.cmdlen = (int)STRLEN(p);
+			STRCPY(ccline.cmdbuff, p);
+			vim_free(p);
+
+			/* Restore the cursor or use the position set with
+			 * set_cmdline_pos(). */
+			if (new_cmdpos > ccline.cmdlen)
+			    ccline.cmdpos = ccline.cmdlen;
+			else
+			    ccline.cmdpos = new_cmdpos;
+
+			KeyTyped = FALSE;	/* Don't do p_wc completion. */
+			redrawcmd();
+			goto cmdline_changed;
+		    }
+		}
+		beep_flush();
+		c = ESC;
+	    }
+#endif
+	    else
+	    {
+		if (c == Ctrl_G && p_im && restart_edit == 0)
+		    restart_edit = 'a';
+		gotesc = TRUE;	/* will free ccline.cmdbuff after putting it
+				   in history */
+		goto returncmd;	/* back to Normal mode */
+	    }
+	}
+
+#ifdef FEAT_CMDWIN
+	if (c == cedit_key || c == K_CMDWIN)
+	{
+	    /*
+	     * Open a window to edit the command line (and history).
+	     */
+	    c = ex_window();
+	    some_key_typed = TRUE;
+	}
+# ifdef FEAT_DIGRAPHS
+	else
+# endif
+#endif
+#ifdef FEAT_DIGRAPHS
+	    c = do_digraph(c);
+#endif
+
+	if (c == '\n' || c == '\r' || c == K_KENTER || (c == ESC
+			&& (!KeyTyped || vim_strchr(p_cpo, CPO_ESC) != NULL)))
+	{
+	    /* In Ex mode a backslash escapes a newline. */
+	    if (exmode_active
+		    && c != ESC
+		    && ccline.cmdpos > 0
+		    && ccline.cmdpos == ccline.cmdlen
+		    && ccline.cmdbuff[ccline.cmdpos - 1] == '\\')
+	    {
+		if (c == K_KENTER)
+		    c = '\n';
+	    }
+	    else
+	    {
+		gotesc = FALSE;	/* Might have typed ESC previously, don't
+				       truncate the cmdline now. */
+		if (ccheck_abbr(c + ABBR_OFF))
+		    goto cmdline_changed;
+		if (!cmd_silent)
+		{
+		    windgoto(msg_row, 0);
+		    out_flush();
+		}
+		break;
+	    }
+	}
+
+	/*
+	 * Completion for 'wildchar' or 'wildcharm' key.
+	 * - hitting <ESC> twice means: abandon command line.
+	 * - wildcard expansion is only done when the 'wildchar' key is really
+	 *   typed, not when it comes from a macro
+	 */
+	if ((c == p_wc && !gotesc && KeyTyped) || c == p_wcm)
+	{
+	    if (xpc.xp_numfiles > 0)   /* typed p_wc at least twice */
+	    {
+		/* if 'wildmode' contains "list" may still need to list */
+		if (xpc.xp_numfiles > 1
+			&& !did_wild_list
+			&& (wim_flags[wim_index] & WIM_LIST))
+		{
+		    (void)showmatches(&xpc, FALSE);
+		    redrawcmd();
+		    did_wild_list = TRUE;
+		}
+		if (wim_flags[wim_index] & WIM_LONGEST)
+		    res = nextwild(&xpc, WILD_LONGEST, WILD_NO_BEEP);
+		else if (wim_flags[wim_index] & WIM_FULL)
+		    res = nextwild(&xpc, WILD_NEXT, WILD_NO_BEEP);
+		else
+		    res = OK;	    /* don't insert 'wildchar' now */
+	    }
+	    else		    /* typed p_wc first time */
+	    {
+		wim_index = 0;
+		j = ccline.cmdpos;
+		/* if 'wildmode' first contains "longest", get longest
+		 * common part */
+		if (wim_flags[0] & WIM_LONGEST)
+		    res = nextwild(&xpc, WILD_LONGEST, WILD_NO_BEEP);
+		else
+		    res = nextwild(&xpc, WILD_EXPAND_KEEP, WILD_NO_BEEP);
+
+		/* if interrupted while completing, behave like it failed */
+		if (got_int)
+		{
+		    (void)vpeekc();	/* remove <C-C> from input stream */
+		    got_int = FALSE;	/* don't abandon the command line */
+		    (void)ExpandOne(&xpc, NULL, NULL, 0, WILD_FREE);
+#ifdef FEAT_WILDMENU
+		    xpc.xp_context = EXPAND_NOTHING;
+#endif
+		    goto cmdline_changed;
+		}
+
+		/* when more than one match, and 'wildmode' first contains
+		 * "list", or no change and 'wildmode' contains "longest,list",
+		 * list all matches */
+		if (res == OK && xpc.xp_numfiles > 1)
+		{
+		    /* a "longest" that didn't do anything is skipped (but not
+		     * "list:longest") */
+		    if (wim_flags[0] == WIM_LONGEST && ccline.cmdpos == j)
+			wim_index = 1;
+		    if ((wim_flags[wim_index] & WIM_LIST)
+#ifdef FEAT_WILDMENU
+			    || (p_wmnu && (wim_flags[wim_index] & WIM_FULL) != 0)
+#endif
+			    )
+		    {
+			if (!(wim_flags[0] & WIM_LONGEST))
+			{
+#ifdef FEAT_WILDMENU
+			    int p_wmnu_save = p_wmnu;
+			    p_wmnu = 0;
+#endif
+			    nextwild(&xpc, WILD_PREV, 0); /* remove match */
+#ifdef FEAT_WILDMENU
+			    p_wmnu = p_wmnu_save;
+#endif
+			}
+#ifdef FEAT_WILDMENU
+			(void)showmatches(&xpc, p_wmnu
+				&& ((wim_flags[wim_index] & WIM_LIST) == 0));
+#else
+			(void)showmatches(&xpc, FALSE);
+#endif
+			redrawcmd();
+			did_wild_list = TRUE;
+			if (wim_flags[wim_index] & WIM_LONGEST)
+			    nextwild(&xpc, WILD_LONGEST, WILD_NO_BEEP);
+			else if (wim_flags[wim_index] & WIM_FULL)
+			    nextwild(&xpc, WILD_NEXT, WILD_NO_BEEP);
+		    }
+		    else
+			vim_beep();
+		}
+#ifdef FEAT_WILDMENU
+		else if (xpc.xp_numfiles == -1)
+		    xpc.xp_context = EXPAND_NOTHING;
+#endif
+	    }
+	    if (wim_index < 3)
+		++wim_index;
+	    if (c == ESC)
+		gotesc = TRUE;
+	    if (res == OK)
+		goto cmdline_changed;
+	}
+
+	gotesc = FALSE;
+
+	/* <S-Tab> goes to last match, in a clumsy way */
+	if (c == K_S_TAB && KeyTyped)
+	{
+	    if (nextwild(&xpc, WILD_EXPAND_KEEP, 0) == OK
+		    && nextwild(&xpc, WILD_PREV, 0) == OK
+		    && nextwild(&xpc, WILD_PREV, 0) == OK)
+		goto cmdline_changed;
+	}
+
+	if (c == NUL || c == K_ZERO)	    /* NUL is stored as NL */
+	    c = NL;
+
+	do_abbr = TRUE;		/* default: check for abbreviation */
+
+	/*
+	 * Big switch for a typed command line character.
+	 */
+	switch (c)
+	{
+	case K_BS:
+	case Ctrl_H:
+	case K_DEL:
+	case K_KDEL:
+	case Ctrl_W:
+#ifdef FEAT_FKMAP
+		if (cmd_fkmap && c == K_BS)
+		    c = K_DEL;
+#endif
+		if (c == K_KDEL)
+		    c = K_DEL;
+
+		/*
+		 * delete current character is the same as backspace on next
+		 * character, except at end of line
+		 */
+		if (c == K_DEL && ccline.cmdpos != ccline.cmdlen)
+		    ++ccline.cmdpos;
+#ifdef FEAT_MBYTE
+		if (has_mbyte && c == K_DEL)
+		    ccline.cmdpos += mb_off_next(ccline.cmdbuff,
+					      ccline.cmdbuff + ccline.cmdpos);
+#endif
+		if (ccline.cmdpos > 0)
+		{
+		    char_u *p;
+
+		    j = ccline.cmdpos;
+		    p = ccline.cmdbuff + j;
+#ifdef FEAT_MBYTE
+		    if (has_mbyte)
+		    {
+			p = mb_prevptr(ccline.cmdbuff, p);
+			if (c == Ctrl_W)
+			{
+			    while (p > ccline.cmdbuff && vim_isspace(*p))
+				p = mb_prevptr(ccline.cmdbuff, p);
+			    i = mb_get_class(p);
+			    while (p > ccline.cmdbuff && mb_get_class(p) == i)
+				p = mb_prevptr(ccline.cmdbuff, p);
+			    if (mb_get_class(p) != i)
+				p += (*mb_ptr2len)(p);
+			}
+		    }
+		    else
+#endif
+			if (c == Ctrl_W)
+		    {
+			while (p > ccline.cmdbuff && vim_isspace(p[-1]))
+			    --p;
+			i = vim_iswordc(p[-1]);
+			while (p > ccline.cmdbuff && !vim_isspace(p[-1])
+				&& vim_iswordc(p[-1]) == i)
+			    --p;
+		    }
+		    else
+			--p;
+		    ccline.cmdpos = (int)(p - ccline.cmdbuff);
+		    ccline.cmdlen -= j - ccline.cmdpos;
+		    i = ccline.cmdpos;
+		    while (i < ccline.cmdlen)
+			ccline.cmdbuff[i++] = ccline.cmdbuff[j++];
+
+		    /* Truncate at the end, required for multi-byte chars. */
+		    ccline.cmdbuff[ccline.cmdlen] = NUL;
+		    redrawcmd();
+		}
+		else if (ccline.cmdlen == 0 && c != Ctrl_W
+				   && ccline.cmdprompt == NULL && indent == 0)
+		{
+		    /* In ex and debug mode it doesn't make sense to return. */
+		    if (exmode_active
+#ifdef FEAT_EVAL
+			    || ccline.cmdfirstc == '>'
+#endif
+			    )
+			goto cmdline_not_changed;
+
+		    vim_free(ccline.cmdbuff);	/* no commandline to return */
+		    ccline.cmdbuff = NULL;
+		    if (!cmd_silent)
+		    {
+#ifdef FEAT_RIGHTLEFT
+			if (cmdmsg_rl)
+			    msg_col = Columns;
+			else
+#endif
+			    msg_col = 0;
+			msg_putchar(' ');		/* delete ':' */
+		    }
+		    redraw_cmdline = TRUE;
+		    goto returncmd;		/* back to cmd mode */
+		}
+		goto cmdline_changed;
+
+	case K_INS:
+	case K_KINS:
+#ifdef FEAT_FKMAP
+		/* if Farsi mode set, we are in reverse insert mode -
+		   Do not change the mode */
+		if (cmd_fkmap)
+		    beep_flush();
+		else
+#endif
+		ccline.overstrike = !ccline.overstrike;
+#ifdef CURSOR_SHAPE
+		ui_cursor_shape();	/* may show different cursor shape */
+#endif
+		goto cmdline_not_changed;
+
+	case Ctrl_HAT:
+		if (map_to_exists_mode((char_u *)"", LANGMAP, FALSE))
+		{
+		    /* ":lmap" mappings exists, toggle use of mappings. */
+		    State ^= LANGMAP;
+#ifdef USE_IM_CONTROL
+		    im_set_active(FALSE);	/* Disable input method */
+#endif
+		    if (b_im_ptr != NULL)
+		    {
+			if (State & LANGMAP)
+			    *b_im_ptr = B_IMODE_LMAP;
+			else
+			    *b_im_ptr = B_IMODE_NONE;
+		    }
+		}
+#ifdef USE_IM_CONTROL
+		else
+		{
+		    /* There are no ":lmap" mappings, toggle IM.  When
+		     * 'imdisable' is set don't try getting the status, it's
+		     * always off. */
+		    if ((p_imdisable && b_im_ptr != NULL)
+			    ? *b_im_ptr == B_IMODE_IM : im_get_status())
+		    {
+			im_set_active(FALSE);	/* Disable input method */
+			if (b_im_ptr != NULL)
+			    *b_im_ptr = B_IMODE_NONE;
+		    }
+		    else
+		    {
+			im_set_active(TRUE);	/* Enable input method */
+			if (b_im_ptr != NULL)
+			    *b_im_ptr = B_IMODE_IM;
+		    }
+		}
+#endif
+		if (b_im_ptr != NULL)
+		{
+		    if (b_im_ptr == &curbuf->b_p_iminsert)
+			set_iminsert_global();
+		    else
+			set_imsearch_global();
+		}
+#ifdef CURSOR_SHAPE
+		ui_cursor_shape();	/* may show different cursor shape */
+#endif
+#if defined(FEAT_WINDOWS) && defined(FEAT_KEYMAP)
+		/* Show/unshow value of 'keymap' in status lines later. */
+		status_redraw_curbuf();
+#endif
+		goto cmdline_not_changed;
+
+/*	case '@':   only in very old vi */
+	case Ctrl_U:
+		/* delete all characters left of the cursor */
+		j = ccline.cmdpos;
+		ccline.cmdlen -= j;
+		i = ccline.cmdpos = 0;
+		while (i < ccline.cmdlen)
+		    ccline.cmdbuff[i++] = ccline.cmdbuff[j++];
+		/* Truncate at the end, required for multi-byte chars. */
+		ccline.cmdbuff[ccline.cmdlen] = NUL;
+		redrawcmd();
+		goto cmdline_changed;
+
+#ifdef FEAT_CLIPBOARD
+	case Ctrl_Y:
+		/* Copy the modeless selection, if there is one. */
+		if (clip_star.state != SELECT_CLEARED)
+		{
+		    if (clip_star.state == SELECT_DONE)
+			clip_copy_modeless_selection(TRUE);
+		    goto cmdline_not_changed;
+		}
+		break;
+#endif
+
+	case ESC:	/* get here if p_wc != ESC or when ESC typed twice */
+	case Ctrl_C:
+		/* In exmode it doesn't make sense to return.  Except when
+		 * ":normal" runs out of characters. */
+		if (exmode_active
+#ifdef FEAT_EX_EXTRA
+			&& (ex_normal_busy == 0 || typebuf.tb_len > 0)
+#endif
+		   )
+		    goto cmdline_not_changed;
+
+		gotesc = TRUE;		/* will free ccline.cmdbuff after
+					   putting it in history */
+		goto returncmd;		/* back to cmd mode */
+
+	case Ctrl_R:			/* insert register */
+#ifdef USE_ON_FLY_SCROLL
+		dont_scroll = TRUE;	/* disallow scrolling here */
+#endif
+		putcmdline('"', TRUE);
+		++no_mapping;
+		i = c = safe_vgetc();	/* CTRL-R <char> */
+		if (i == Ctrl_O)
+		    i = Ctrl_R;		/* CTRL-R CTRL-O == CTRL-R CTRL-R */
+		if (i == Ctrl_R)
+		    c = safe_vgetc();	/* CTRL-R CTRL-R <char> */
+		--no_mapping;
+#ifdef FEAT_EVAL
+		/*
+		 * Insert the result of an expression.
+		 * Need to save the current command line, to be able to enter
+		 * a new one...
+		 */
+		new_cmdpos = -1;
+		if (c == '=')
+		{
+		    if (ccline.cmdfirstc == '=')/* can't do this recursively */
+		    {
+			beep_flush();
+			c = ESC;
+		    }
+		    else
+		    {
+			save_cmdline(&save_ccline);
+			c = get_expr_register();
+			restore_cmdline(&save_ccline);
+		    }
+		}
+#endif
+		if (c != ESC)	    /* use ESC to cancel inserting register */
+		{
+		    cmdline_paste(c, i == Ctrl_R, FALSE);
+
+#ifdef FEAT_EVAL
+		    /* When there was a serious error abort getting the
+		     * command line. */
+		    if (aborting())
+		    {
+			gotesc = TRUE;  /* will free ccline.cmdbuff after
+					   putting it in history */
+			goto returncmd; /* back to cmd mode */
+		    }
+#endif
+		    KeyTyped = FALSE;	/* Don't do p_wc completion. */
+#ifdef FEAT_EVAL
+		    if (new_cmdpos >= 0)
+		    {
+			/* set_cmdline_pos() was used */
+			if (new_cmdpos > ccline.cmdlen)
+			    ccline.cmdpos = ccline.cmdlen;
+			else
+			    ccline.cmdpos = new_cmdpos;
+		    }
+#endif
+		}
+		redrawcmd();
+		goto cmdline_changed;
+
+	case Ctrl_D:
+		if (showmatches(&xpc, FALSE) == EXPAND_NOTHING)
+		    break;	/* Use ^D as normal char instead */
+
+		redrawcmd();
+		continue;	/* don't do incremental search now */
+
+	case K_RIGHT:
+	case K_S_RIGHT:
+	case K_C_RIGHT:
+		do
+		{
+		    if (ccline.cmdpos >= ccline.cmdlen)
+			break;
+		    i = cmdline_charsize(ccline.cmdpos);
+		    if (KeyTyped && ccline.cmdspos + i >= Columns * Rows)
+			break;
+		    ccline.cmdspos += i;
+#ifdef FEAT_MBYTE
+		    if (has_mbyte)
+			ccline.cmdpos += (*mb_ptr2len)(ccline.cmdbuff
+							     + ccline.cmdpos);
+		    else
+#endif
+			++ccline.cmdpos;
+		}
+		while ((c == K_S_RIGHT || c == K_C_RIGHT
+			       || (mod_mask & (MOD_MASK_SHIFT|MOD_MASK_CTRL)))
+			&& ccline.cmdbuff[ccline.cmdpos] != ' ');
+#ifdef FEAT_MBYTE
+		if (has_mbyte)
+		    set_cmdspos_cursor();
+#endif
+		goto cmdline_not_changed;
+
+	case K_LEFT:
+	case K_S_LEFT:
+	case K_C_LEFT:
+		do
+		{
+		    if (ccline.cmdpos == 0)
+			break;
+		    --ccline.cmdpos;
+#ifdef FEAT_MBYTE
+		    if (has_mbyte)	/* move to first byte of char */
+			ccline.cmdpos -= (*mb_head_off)(ccline.cmdbuff,
+					      ccline.cmdbuff + ccline.cmdpos);
+#endif
+		    ccline.cmdspos -= cmdline_charsize(ccline.cmdpos);
+		}
+		while ((c == K_S_LEFT || c == K_C_LEFT
+			       || (mod_mask & (MOD_MASK_SHIFT|MOD_MASK_CTRL)))
+			&& ccline.cmdbuff[ccline.cmdpos - 1] != ' ');
+#ifdef FEAT_MBYTE
+		if (has_mbyte)
+		    set_cmdspos_cursor();
+#endif
+		goto cmdline_not_changed;
+
+	case K_IGNORE:
+		goto cmdline_not_changed;	/* Ignore mouse */
+
+#ifdef FEAT_GUI_W32
+	    /* On Win32 ignore <M-F4>, we get it when closing the window was
+	     * cancelled. */
+	case K_F4:
+	    if (mod_mask == MOD_MASK_ALT)
+	    {
+		redrawcmd();	    /* somehow the cmdline is cleared */
+		goto cmdline_not_changed;
+	    }
+	    break;
+#endif
+
+#ifdef FEAT_MOUSE
+	case K_MIDDLEDRAG:
+	case K_MIDDLERELEASE:
+		goto cmdline_not_changed;	/* Ignore mouse */
+
+	case K_MIDDLEMOUSE:
+# ifdef FEAT_GUI
+		/* When GUI is active, also paste when 'mouse' is empty */
+		if (!gui.in_use)
+# endif
+		    if (!mouse_has(MOUSE_COMMAND))
+			goto cmdline_not_changed;   /* Ignore mouse */
+# ifdef FEAT_CLIPBOARD
+		if (clip_star.available)
+		    cmdline_paste('*', TRUE, TRUE);
+		else
+# endif
+		    cmdline_paste(0, TRUE, TRUE);
+		redrawcmd();
+		goto cmdline_changed;
+
+# ifdef FEAT_DND
+	case K_DROP:
+		cmdline_paste('~', TRUE, FALSE);
+		redrawcmd();
+		goto cmdline_changed;
+# endif
+
+	case K_LEFTDRAG:
+	case K_LEFTRELEASE:
+	case K_RIGHTDRAG:
+	case K_RIGHTRELEASE:
+		/* Ignore drag and release events when the button-down wasn't
+		 * seen before. */
+		if (ignore_drag_release)
+		    goto cmdline_not_changed;
+		/* FALLTHROUGH */
+	case K_LEFTMOUSE:
+	case K_RIGHTMOUSE:
+		if (c == K_LEFTRELEASE || c == K_RIGHTRELEASE)
+		    ignore_drag_release = TRUE;
+		else
+		    ignore_drag_release = FALSE;
+# ifdef FEAT_GUI
+		/* When GUI is active, also move when 'mouse' is empty */
+		if (!gui.in_use)
+# endif
+		    if (!mouse_has(MOUSE_COMMAND))
+			goto cmdline_not_changed;   /* Ignore mouse */
+# ifdef FEAT_CLIPBOARD
+		if (mouse_row < cmdline_row && clip_star.available)
+		{
+		    int	    button, is_click, is_drag;
+
+		    /*
+		     * Handle modeless selection.
+		     */
+		    button = get_mouse_button(KEY2TERMCAP1(c),
+							 &is_click, &is_drag);
+		    if (mouse_model_popup() && button == MOUSE_LEFT
+					       && (mod_mask & MOD_MASK_SHIFT))
+		    {
+			/* Translate shift-left to right button. */
+			button = MOUSE_RIGHT;
+			mod_mask &= ~MOD_MASK_SHIFT;
+		    }
+		    clip_modeless(button, is_click, is_drag);
+		    goto cmdline_not_changed;
+		}
+# endif
+
+		set_cmdspos();
+		for (ccline.cmdpos = 0; ccline.cmdpos < ccline.cmdlen;
+							      ++ccline.cmdpos)
+		{
+		    i = cmdline_charsize(ccline.cmdpos);
+		    if (mouse_row <= cmdline_row + ccline.cmdspos / Columns
+				  && mouse_col < ccline.cmdspos % Columns + i)
+			break;
+# ifdef FEAT_MBYTE
+		    if (has_mbyte)
+		    {
+			/* Count ">" for double-wide char that doesn't fit. */
+			correct_cmdspos(ccline.cmdpos, i);
+			ccline.cmdpos += (*mb_ptr2len)(ccline.cmdbuff
+							 + ccline.cmdpos) - 1;
+		    }
+# endif
+		    ccline.cmdspos += i;
+		}
+		goto cmdline_not_changed;
+
+	/* Mouse scroll wheel: ignored here */
+	case K_MOUSEDOWN:
+	case K_MOUSEUP:
+	/* Alternate buttons ignored here */
+	case K_X1MOUSE:
+	case K_X1DRAG:
+	case K_X1RELEASE:
+	case K_X2MOUSE:
+	case K_X2DRAG:
+	case K_X2RELEASE:
+		goto cmdline_not_changed;
+
+#endif	/* FEAT_MOUSE */
+
+#ifdef FEAT_GUI
+	case K_LEFTMOUSE_NM:	/* mousefocus click, ignored */
+	case K_LEFTRELEASE_NM:
+		goto cmdline_not_changed;
+
+	case K_VER_SCROLLBAR:
+		if (msg_scrolled == 0)
+		{
+		    gui_do_scroll();
+		    redrawcmd();
+		}
+		goto cmdline_not_changed;
+
+	case K_HOR_SCROLLBAR:
+		if (msg_scrolled == 0)
+		{
+		    gui_do_horiz_scroll();
+		    redrawcmd();
+		}
+		goto cmdline_not_changed;
+#endif
+#ifdef FEAT_GUI_TABLINE
+	case K_TABLINE:
+	case K_TABMENU:
+		/* Don't want to change any tabs here.  Make sure the same tab
+		 * is still selected. */
+		if (gui_use_tabline())
+		    gui_mch_set_curtab(tabpage_index(curtab));
+		goto cmdline_not_changed;
+#endif
+
+	case K_SELECT:	    /* end of Select mode mapping - ignore */
+		goto cmdline_not_changed;
+
+	case Ctrl_B:	    /* begin of command line */
+	case K_HOME:
+	case K_KHOME:
+	case K_S_HOME:
+	case K_C_HOME:
+		ccline.cmdpos = 0;
+		set_cmdspos();
+		goto cmdline_not_changed;
+
+	case Ctrl_E:	    /* end of command line */
+	case K_END:
+	case K_KEND:
+	case K_S_END:
+	case K_C_END:
+		ccline.cmdpos = ccline.cmdlen;
+		set_cmdspos_cursor();
+		goto cmdline_not_changed;
+
+	case Ctrl_A:	    /* all matches */
+		if (nextwild(&xpc, WILD_ALL, 0) == FAIL)
+		    break;
+		goto cmdline_changed;
+
+	case Ctrl_L:
+#ifdef FEAT_SEARCH_EXTRA
+		if (p_is && !cmd_silent && (firstc == '/' || firstc == '?'))
+		{
+		    /* Add a character from under the cursor for 'incsearch' */
+		    if (did_incsearch
+				   && !equalpos(curwin->w_cursor, old_cursor))
+		    {
+			c = gchar_cursor();
+			if (c != NUL)
+			{
+			    if (c == firstc || vim_strchr((char_u *)(
+					    p_magic ? "\\^$.*[" : "\\^$"), c)
+								      != NULL)
+			    {
+				/* put a backslash before special characters */
+				stuffcharReadbuff(c);
+				c = '\\';
+			    }
+			    break;
+			}
+		    }
+		    goto cmdline_not_changed;
+		}
+#endif
+
+		/* completion: longest common part */
+		if (nextwild(&xpc, WILD_LONGEST, 0) == FAIL)
+		    break;
+		goto cmdline_changed;
+
+	case Ctrl_N:	    /* next match */
+	case Ctrl_P:	    /* previous match */
+		if (xpc.xp_numfiles > 0)
+		{
+		    if (nextwild(&xpc, (c == Ctrl_P) ? WILD_PREV : WILD_NEXT, 0)
+								      == FAIL)
+			break;
+		    goto cmdline_changed;
+		}
+
+#ifdef FEAT_CMDHIST
+	case K_UP:
+	case K_DOWN:
+	case K_S_UP:
+	case K_S_DOWN:
+	case K_PAGEUP:
+	case K_KPAGEUP:
+	case K_PAGEDOWN:
+	case K_KPAGEDOWN:
+		if (hislen == 0 || firstc == NUL)	/* no history */
+		    goto cmdline_not_changed;
+
+		i = hiscnt;
+
+		/* save current command string so it can be restored later */
+		if (lookfor == NULL)
+		{
+		    if ((lookfor = vim_strsave(ccline.cmdbuff)) == NULL)
+			goto cmdline_not_changed;
+		    lookfor[ccline.cmdpos] = NUL;
+		}
+
+		j = (int)STRLEN(lookfor);
+		for (;;)
+		{
+		    /* one step backwards */
+		    if (c == K_UP|| c == K_S_UP || c == Ctrl_P
+			    || c == K_PAGEUP || c == K_KPAGEUP)
+		    {
+			if (hiscnt == hislen)	/* first time */
+			    hiscnt = hisidx[histype];
+			else if (hiscnt == 0 && hisidx[histype] != hislen - 1)
+			    hiscnt = hislen - 1;
+			else if (hiscnt != hisidx[histype] + 1)
+			    --hiscnt;
+			else			/* at top of list */
+			{
+			    hiscnt = i;
+			    break;
+			}
+		    }
+		    else    /* one step forwards */
+		    {
+			/* on last entry, clear the line */
+			if (hiscnt == hisidx[histype])
+			{
+			    hiscnt = hislen;
+			    break;
+			}
+
+			/* not on a history line, nothing to do */
+			if (hiscnt == hislen)
+			    break;
+			if (hiscnt == hislen - 1)   /* wrap around */
+			    hiscnt = 0;
+			else
+			    ++hiscnt;
+		    }
+		    if (hiscnt < 0 || history[histype][hiscnt].hisstr == NULL)
+		    {
+			hiscnt = i;
+			break;
+		    }
+		    if ((c != K_UP && c != K_DOWN)
+			    || hiscnt == i
+			    || STRNCMP(history[histype][hiscnt].hisstr,
+						    lookfor, (size_t)j) == 0)
+			break;
+		}
+
+		if (hiscnt != i)	/* jumped to other entry */
+		{
+		    char_u	*p;
+		    int		len;
+		    int		old_firstc;
+
+		    vim_free(ccline.cmdbuff);
+		    if (hiscnt == hislen)
+			p = lookfor;	/* back to the old one */
+		    else
+			p = history[histype][hiscnt].hisstr;
+
+		    if (histype == HIST_SEARCH
+			    && p != lookfor
+			    && (old_firstc = p[STRLEN(p) + 1]) != firstc)
+		    {
+			/* Correct for the separator character used when
+			 * adding the history entry vs the one used now.
+			 * First loop: count length.
+			 * Second loop: copy the characters. */
+			for (i = 0; i <= 1; ++i)
+			{
+			    len = 0;
+			    for (j = 0; p[j] != NUL; ++j)
+			    {
+				/* Replace old sep with new sep, unless it is
+				 * escaped. */
+				if (p[j] == old_firstc
+					      && (j == 0 || p[j - 1] != '\\'))
+				{
+				    if (i > 0)
+					ccline.cmdbuff[len] = firstc;
+				}
+				else
+				{
+				    /* Escape new sep, unless it is already
+				     * escaped. */
+				    if (p[j] == firstc
+					      && (j == 0 || p[j - 1] != '\\'))
+				    {
+					if (i > 0)
+					    ccline.cmdbuff[len] = '\\';
+					++len;
+				    }
+				    if (i > 0)
+					ccline.cmdbuff[len] = p[j];
+				}
+				++len;
+			    }
+			    if (i == 0)
+			    {
+				alloc_cmdbuff(len);
+				if (ccline.cmdbuff == NULL)
+				    goto returncmd;
+			    }
+			}
+			ccline.cmdbuff[len] = NUL;
+		    }
+		    else
+		    {
+			alloc_cmdbuff((int)STRLEN(p));
+			if (ccline.cmdbuff == NULL)
+			    goto returncmd;
+			STRCPY(ccline.cmdbuff, p);
+		    }
+
+		    ccline.cmdpos = ccline.cmdlen = (int)STRLEN(ccline.cmdbuff);
+		    redrawcmd();
+		    goto cmdline_changed;
+		}
+		beep_flush();
+		goto cmdline_not_changed;
+#endif
+
+	case Ctrl_V:
+	case Ctrl_Q:
+#ifdef FEAT_MOUSE
+		ignore_drag_release = TRUE;
+#endif
+		putcmdline('^', TRUE);
+		c = get_literal();	    /* get next (two) character(s) */
+		do_abbr = FALSE;	    /* don't do abbreviation now */
+#ifdef FEAT_MBYTE
+		/* may need to remove ^ when composing char was typed */
+		if (enc_utf8 && utf_iscomposing(c) && !cmd_silent)
+		{
+		    draw_cmdline(ccline.cmdpos, ccline.cmdlen - ccline.cmdpos);
+		    msg_putchar(' ');
+		    cursorcmd();
+		}
+#endif
+		break;
+
+#ifdef FEAT_DIGRAPHS
+	case Ctrl_K:
+#ifdef FEAT_MOUSE
+		ignore_drag_release = TRUE;
+#endif
+		putcmdline('?', TRUE);
+#ifdef USE_ON_FLY_SCROLL
+		dont_scroll = TRUE;	    /* disallow scrolling here */
+#endif
+		c = get_digraph(TRUE);
+		if (c != NUL)
+		    break;
+
+		redrawcmd();
+		goto cmdline_not_changed;
+#endif /* FEAT_DIGRAPHS */
+
+#ifdef FEAT_RIGHTLEFT
+	case Ctrl__:	    /* CTRL-_: switch language mode */
+		if (!p_ari)
+		    break;
+#ifdef FEAT_FKMAP
+		if (p_altkeymap)
+		{
+		    cmd_fkmap = !cmd_fkmap;
+		    if (cmd_fkmap)	/* in Farsi always in Insert mode */
+			ccline.overstrike = FALSE;
+		}
+		else			    /* Hebrew is default */
+#endif
+		    cmd_hkmap = !cmd_hkmap;
+		goto cmdline_not_changed;
+#endif
+
+	default:
+#ifdef UNIX
+		if (c == intr_char)
+		{
+		    gotesc = TRUE;	/* will free ccline.cmdbuff after
+					   putting it in history */
+		    goto returncmd;	/* back to Normal mode */
+		}
+#endif
+		/*
+		 * Normal character with no special meaning.  Just set mod_mask
+		 * to 0x0 so that typing Shift-Space in the GUI doesn't enter
+		 * the string <S-Space>.  This should only happen after ^V.
+		 */
+		if (!IS_SPECIAL(c))
+		    mod_mask = 0x0;
+		break;
+	}
+	/*
+	 * End of switch on command line character.
+	 * We come here if we have a normal character.
+	 */
+
+	if (do_abbr && (IS_SPECIAL(c) || !vim_iswordc(c)) && ccheck_abbr(
+#ifdef FEAT_MBYTE
+			/* Add ABBR_OFF for characters above 0x100, this is
+			 * what check_abbr() expects. */
+			(has_mbyte && c >= 0x100) ? (c + ABBR_OFF) :
+#endif
+									c))
+	    goto cmdline_changed;
+
+	/*
+	 * put the character in the command line
+	 */
+	if (IS_SPECIAL(c) || mod_mask != 0)
+	    put_on_cmdline(get_special_key_name(c, mod_mask), -1, TRUE);
+	else
+	{
+#ifdef FEAT_MBYTE
+	    if (has_mbyte)
+	    {
+		j = (*mb_char2bytes)(c, IObuff);
+		IObuff[j] = NUL;	/* exclude composing chars */
+		put_on_cmdline(IObuff, j, TRUE);
+	    }
+	    else
+#endif
+	    {
+		IObuff[0] = c;
+		put_on_cmdline(IObuff, 1, TRUE);
+	    }
+	}
+	goto cmdline_changed;
+
+/*
+ * This part implements incremental searches for "/" and "?"
+ * Jump to cmdline_not_changed when a character has been read but the command
+ * line did not change. Then we only search and redraw if something changed in
+ * the past.
+ * Jump to cmdline_changed when the command line did change.
+ * (Sorry for the goto's, I know it is ugly).
+ */
+cmdline_not_changed:
+#ifdef FEAT_SEARCH_EXTRA
+	if (!incsearch_postponed)
+	    continue;
+#endif
+
+cmdline_changed:
+#ifdef FEAT_SEARCH_EXTRA
+	/*
+	 * 'incsearch' highlighting.
+	 */
+	if (p_is && !cmd_silent && (firstc == '/' || firstc == '?'))
+	{
+	    pos_T	end_pos;
+
+	    /* if there is a character waiting, search and redraw later */
+	    if (char_avail())
+	    {
+		incsearch_postponed = TRUE;
+		continue;
+	    }
+	    incsearch_postponed = FALSE;
+	    curwin->w_cursor = old_cursor;  /* start at old position */
+
+	    /* If there is no command line, don't do anything */
+	    if (ccline.cmdlen == 0)
+		i = 0;
+	    else
+	    {
+		cursor_off();		/* so the user knows we're busy */
+		out_flush();
+		++emsg_off;    /* So it doesn't beep if bad expr */
+		i = do_search(NULL, firstc, ccline.cmdbuff, count,
+			SEARCH_KEEP + SEARCH_OPT + SEARCH_NOOF + SEARCH_PEEK);
+		--emsg_off;
+		/* if interrupted while searching, behave like it failed */
+		if (got_int)
+		{
+		    (void)vpeekc();	/* remove <C-C> from input stream */
+		    got_int = FALSE;	/* don't abandon the command line */
+		    i = 0;
+		}
+		else if (char_avail())
+		    /* cancelled searching because a char was typed */
+		    incsearch_postponed = TRUE;
+	    }
+	    if (i != 0)
+		highlight_match = TRUE;		/* highlight position */
+	    else
+		highlight_match = FALSE;	/* remove highlight */
+
+	    /* first restore the old curwin values, so the screen is
+	     * positioned in the same way as the actual search command */
+	    curwin->w_leftcol = old_leftcol;
+	    curwin->w_topline = old_topline;
+# ifdef FEAT_DIFF
+	    curwin->w_topfill = old_topfill;
+# endif
+	    curwin->w_botline = old_botline;
+	    changed_cline_bef_curs();
+	    update_topline();
+
+	    if (i != 0)
+	    {
+		pos_T	    save_pos = curwin->w_cursor;
+
+		/*
+		 * First move cursor to end of match, then to the start.  This
+		 * moves the whole match onto the screen when 'nowrap' is set.
+		 */
+		curwin->w_cursor.lnum += search_match_lines;
+		curwin->w_cursor.col = search_match_endcol;
+		if (curwin->w_cursor.lnum > curbuf->b_ml.ml_line_count)
+		{
+		    curwin->w_cursor.lnum = curbuf->b_ml.ml_line_count;
+		    coladvance((colnr_T)MAXCOL);
+		}
+		validate_cursor();
+		end_pos = curwin->w_cursor;
+		curwin->w_cursor = save_pos;
+	    }
+	    else
+		end_pos = curwin->w_cursor; /* shutup gcc 4 */
+
+	    validate_cursor();
+# ifdef FEAT_WINDOWS
+	    /* May redraw the status line to show the cursor position. */
+	    if (p_ru && curwin->w_status_height > 0)
+		curwin->w_redr_status = TRUE;
+# endif
+
+	    save_cmdline(&save_ccline);
+	    update_screen(SOME_VALID);
+	    restore_cmdline(&save_ccline);
+
+	    /* Leave it at the end to make CTRL-R CTRL-W work. */
+	    if (i != 0)
+		curwin->w_cursor = end_pos;
+
+	    msg_starthere();
+	    redrawcmdline();
+	    did_incsearch = TRUE;
+	}
+#else /* FEAT_SEARCH_EXTRA */
+	;
+#endif
+
+#ifdef FEAT_RIGHTLEFT
+	if (cmdmsg_rl
+# ifdef FEAT_ARABIC
+		|| (p_arshape && !p_tbidi && enc_utf8)
+# endif
+		)
+	    /* Always redraw the whole command line to fix shaping and
+	     * right-left typing.  Not efficient, but it works. */
+	    redrawcmd();
+#endif
+    }
+
+returncmd:
+
+#ifdef FEAT_RIGHTLEFT
+    cmdmsg_rl = FALSE;
+#endif
+
+#ifdef FEAT_FKMAP
+    cmd_fkmap = 0;
+#endif
+
+    ExpandCleanup(&xpc);
+
+#ifdef FEAT_SEARCH_EXTRA
+    if (did_incsearch)
+    {
+	curwin->w_cursor = old_cursor;
+	curwin->w_curswant = old_curswant;
+	curwin->w_leftcol = old_leftcol;
+	curwin->w_topline = old_topline;
+# ifdef FEAT_DIFF
+	curwin->w_topfill = old_topfill;
+# endif
+	curwin->w_botline = old_botline;
+	highlight_match = FALSE;
+	validate_cursor();	/* needed for TAB */
+	redraw_later(SOME_VALID);
+    }
+#endif
+
+    if (ccline.cmdbuff != NULL)
+    {
+	/*
+	 * Put line in history buffer (":" and "=" only when it was typed).
+	 */
+#ifdef FEAT_CMDHIST
+	if (ccline.cmdlen && firstc != NUL
+		&& (some_key_typed || histype == HIST_SEARCH))
+	{
+	    add_to_history(histype, ccline.cmdbuff, TRUE,
+				       histype == HIST_SEARCH ? firstc : NUL);
+	    if (firstc == ':')
+	    {
+		vim_free(new_last_cmdline);
+		new_last_cmdline = vim_strsave(ccline.cmdbuff);
+	    }
+	}
+#endif
+
+	if (gotesc)	    /* abandon command line */
+	{
+	    vim_free(ccline.cmdbuff);
+	    ccline.cmdbuff = NULL;
+	    if (msg_scrolled == 0)
+		compute_cmdrow();
+	    MSG("");
+	    redraw_cmdline = TRUE;
+	}
+    }
+
+    /*
+     * If the screen was shifted up, redraw the whole screen (later).
+     * If the line is too long, clear it, so ruler and shown command do
+     * not get printed in the middle of it.
+     */
+    msg_check();
+    msg_scroll = save_msg_scroll;
+    redir_off = FALSE;
+
+    /* When the command line was typed, no need for a wait-return prompt. */
+    if (some_key_typed)
+	need_wait_return = FALSE;
+
+    State = save_State;
+#ifdef USE_IM_CONTROL
+    if (b_im_ptr != NULL && *b_im_ptr != B_IMODE_LMAP)
+	im_save_status(b_im_ptr);
+    im_set_active(FALSE);
+#endif
+#ifdef FEAT_MOUSE
+    setmouse();
+#endif
+#ifdef CURSOR_SHAPE
+    ui_cursor_shape();		/* may show different cursor shape */
+#endif
+
+    {
+	char_u *p = ccline.cmdbuff;
+
+	/* Make ccline empty, getcmdline() may try to use it. */
+	ccline.cmdbuff = NULL;
+	return p;
+    }
+}
+
+#if (defined(FEAT_CRYPT) || defined(FEAT_EVAL)) || defined(PROTO)
+/*
+ * Get a command line with a prompt.
+ * This is prepared to be called recursively from getcmdline() (e.g. by
+ * f_input() when evaluating an expression from CTRL-R =).
+ * Returns the command line in allocated memory, or NULL.
+ */
+    char_u *
+getcmdline_prompt(firstc, prompt, attr, xp_context, xp_arg)
+    int		firstc;
+    char_u	*prompt;	/* command line prompt */
+    int		attr;		/* attributes for prompt */
+    int		xp_context;	/* type of expansion */
+    char_u	*xp_arg;	/* user-defined expansion argument */
+{
+    char_u		*s;
+    struct cmdline_info	save_ccline;
+    int			msg_col_save = msg_col;
+
+    save_cmdline(&save_ccline);
+    ccline.cmdprompt = prompt;
+    ccline.cmdattr = attr;
+# ifdef FEAT_EVAL
+    ccline.xp_context = xp_context;
+    ccline.xp_arg = xp_arg;
+    ccline.input_fn = (firstc == '@');
+# endif
+    s = getcmdline(firstc, 1L, 0);
+    restore_cmdline(&save_ccline);
+    /* Restore msg_col, the prompt from input() may have changed it. */
+    msg_col = msg_col_save;
+
+    return s;
+}
+#endif
+
+/*
+ * Return TRUE when the text must not be changed and we can't switch to
+ * another window or buffer.  Used when editing the command line, evaluating
+ * 'balloonexpr', etc.
+ */
+    int
+text_locked()
+{
+#ifdef FEAT_CMDWIN
+    if (cmdwin_type != 0)
+	return TRUE;
+#endif
+    return textlock != 0;
+}
+
+/*
+ * Give an error message for a command that isn't allowed while the cmdline
+ * window is open or editing the cmdline in another way.
+ */
+    void
+text_locked_msg()
+{
+#ifdef FEAT_CMDWIN
+    if (cmdwin_type != 0)
+	EMSG(_(e_cmdwin));
+    else
+#endif
+	EMSG(_(e_secure));
+}
+
+#if defined(FEAT_AUTOCMD) || defined(PROTO)
+/*
+ * Check if "curbuf_lock" is set and return TRUE when it is and give an error
+ * message.
+ */
+    int
+curbuf_locked()
+{
+    if (curbuf_lock > 0)
+    {
+	EMSG(_("E788: Not allowed to edit another buffer now"));
+	return TRUE;
+    }
+    return FALSE;
+}
+#endif
+
+    static int
+cmdline_charsize(idx)
+    int		idx;
+{
+#if defined(FEAT_CRYPT) || defined(FEAT_EVAL)
+    if (cmdline_star > 0)	    /* showing '*', always 1 position */
+	return 1;
+#endif
+    return ptr2cells(ccline.cmdbuff + idx);
+}
+
+/*
+ * Compute the offset of the cursor on the command line for the prompt and
+ * indent.
+ */
+    static void
+set_cmdspos()
+{
+    if (ccline.cmdfirstc != NUL)
+	ccline.cmdspos = 1 + ccline.cmdindent;
+    else
+	ccline.cmdspos = 0 + ccline.cmdindent;
+}
+
+/*
+ * Compute the screen position for the cursor on the command line.
+ */
+    static void
+set_cmdspos_cursor()
+{
+    int		i, m, c;
+
+    set_cmdspos();
+    if (KeyTyped)
+    {
+	m = Columns * Rows;
+	if (m < 0)	/* overflow, Columns or Rows at weird value */
+	    m = MAXCOL;
+    }
+    else
+	m = MAXCOL;
+    for (i = 0; i < ccline.cmdlen && i < ccline.cmdpos; ++i)
+    {
+	c = cmdline_charsize(i);
+#ifdef FEAT_MBYTE
+	/* Count ">" for double-wide multi-byte char that doesn't fit. */
+	if (has_mbyte)
+	    correct_cmdspos(i, c);
+#endif
+	/* If the cmdline doesn't fit, put cursor on last visible char. */
+	if ((ccline.cmdspos += c) >= m)
+	{
+	    ccline.cmdpos = i - 1;
+	    ccline.cmdspos -= c;
+	    break;
+	}
+#ifdef FEAT_MBYTE
+	if (has_mbyte)
+	    i += (*mb_ptr2len)(ccline.cmdbuff + i) - 1;
+#endif
+    }
+}
+
+#ifdef FEAT_MBYTE
+/*
+ * Check if the character at "idx", which is "cells" wide, is a multi-byte
+ * character that doesn't fit, so that a ">" must be displayed.
+ */
+    static void
+correct_cmdspos(idx, cells)
+    int		idx;
+    int		cells;
+{
+    if ((*mb_ptr2len)(ccline.cmdbuff + idx) > 1
+		&& (*mb_ptr2cells)(ccline.cmdbuff + idx) > 1
+		&& ccline.cmdspos % Columns + cells > Columns)
+	ccline.cmdspos++;
+}
+#endif
+
+/*
+ * Get an Ex command line for the ":" command.
+ */
+/* ARGSUSED */
+    char_u *
+getexline(c, dummy, indent)
+    int		c;		/* normally ':', NUL for ":append" */
+    void	*dummy;		/* cookie not used */
+    int		indent;		/* indent for inside conditionals */
+{
+    /* When executing a register, remove ':' that's in front of each line. */
+    if (exec_from_reg && vpeekc() == ':')
+	(void)vgetc();
+    return getcmdline(c, 1L, indent);
+}
+
+/*
+ * Get an Ex command line for Ex mode.
+ * In Ex mode we only use the OS supplied line editing features and no
+ * mappings or abbreviations.
+ * Returns a string in allocated memory or NULL.
+ */
+/* ARGSUSED */
+    char_u *
+getexmodeline(promptc, dummy, indent)
+    int		promptc;	/* normally ':', NUL for ":append" and '?' for
+				   :s prompt */
+    void	*dummy;		/* cookie not used */
+    int		indent;		/* indent for inside conditionals */
+{
+    garray_T	line_ga;
+    char_u	*pend;
+    int		startcol = 0;
+    int		c1;
+    int		escaped = FALSE;	/* CTRL-V typed */
+    int		vcol = 0;
+    char_u	*p;
+    int		prev_char = 0;
+
+    /* Switch cursor on now.  This avoids that it happens after the "\n", which
+     * confuses the system function that computes tabstops. */
+    cursor_on();
+
+    /* always start in column 0; write a newline if necessary */
+    compute_cmdrow();
+    if ((msg_col || msg_didout) && promptc != '?')
+	msg_putchar('\n');
+    if (promptc == ':')
+    {
+	/* indent that is only displayed, not in the line itself */
+	if (p_prompt)
+	    msg_putchar(':');
+	while (indent-- > 0)
+	    msg_putchar(' ');
+	startcol = msg_col;
+    }
+
+    ga_init2(&line_ga, 1, 30);
+
+    /* autoindent for :insert and :append is in the line itself */
+    if (promptc <= 0)
+    {
+	vcol = indent;
+	while (indent >= 8)
+	{
+	    ga_append(&line_ga, TAB);
+	    msg_puts((char_u *)"        ");
+	    indent -= 8;
+	}
+	while (indent-- > 0)
+	{
+	    ga_append(&line_ga, ' ');
+	    msg_putchar(' ');
+	}
+    }
+    ++no_mapping;
+    ++allow_keys;
+
+    /*
+     * Get the line, one character at a time.
+     */
+    got_int = FALSE;
+    while (!got_int)
+    {
+	if (ga_grow(&line_ga, 40) == FAIL)
+	    break;
+	pend = (char_u *)line_ga.ga_data + line_ga.ga_len;
+
+	/* Get one character at a time.  Don't use inchar(), it can't handle
+	 * special characters. */
+	c1 = vgetc();
+
+	/*
+	 * Handle line editing.
+	 * Previously this was left to the system, putting the terminal in
+	 * cooked mode, but then CTRL-D and CTRL-T can't be used properly.
+	 */
+	if (got_int)
+	{
+	    msg_putchar('\n');
+	    break;
+	}
+
+	if (!escaped)
+	{
+	    /* CR typed means "enter", which is NL */
+	    if (c1 == '\r')
+		c1 = '\n';
+
+	    if (c1 == BS || c1 == K_BS
+			  || c1 == DEL || c1 == K_DEL || c1 == K_KDEL)
+	    {
+		if (line_ga.ga_len > 0)
+		{
+		    --line_ga.ga_len;
+		    goto redraw;
+		}
+		continue;
+	    }
+
+	    if (c1 == Ctrl_U)
+	    {
+		msg_col = startcol;
+		msg_clr_eos();
+		line_ga.ga_len = 0;
+		continue;
+	    }
+
+	    if (c1 == Ctrl_T)
+	    {
+		p = (char_u *)line_ga.ga_data;
+		p[line_ga.ga_len] = NUL;
+		indent = get_indent_str(p, 8);
+		indent += curbuf->b_p_sw - indent % curbuf->b_p_sw;
+add_indent:
+		while (get_indent_str(p, 8) < indent)
+		{
+		    char_u *s = skipwhite(p);
+
+		    ga_grow(&line_ga, 1);
+		    mch_memmove(s + 1, s, line_ga.ga_len - (s - p) + 1);
+		    *s = ' ';
+		    ++line_ga.ga_len;
+		}
+redraw:
+		/* redraw the line */
+		msg_col = startcol;
+		windgoto(msg_row, msg_col);
+		vcol = 0;
+		for (p = (char_u *)line_ga.ga_data;
+			  p < (char_u *)line_ga.ga_data + line_ga.ga_len; ++p)
+		{
+		    if (*p == TAB)
+		    {
+			do
+			{
+			    msg_putchar(' ');
+			} while (++vcol % 8);
+		    }
+		    else
+		    {
+			msg_outtrans_len(p, 1);
+			vcol += char2cells(*p);
+		    }
+		}
+		msg_clr_eos();
+		continue;
+	    }
+
+	    if (c1 == Ctrl_D)
+	    {
+		/* Delete one shiftwidth. */
+		p = (char_u *)line_ga.ga_data;
+		if (prev_char == '0' || prev_char == '^')
+		{
+		    if (prev_char == '^')
+			ex_keep_indent = TRUE;
+		    indent = 0;
+		    p[--line_ga.ga_len] = NUL;
+		}
+		else
+		{
+		    p[line_ga.ga_len] = NUL;
+		    indent = get_indent_str(p, 8);
+		    --indent;
+		    indent -= indent % curbuf->b_p_sw;
+		}
+		while (get_indent_str(p, 8) > indent)
+		{
+		    char_u *s = skipwhite(p);
+
+		    mch_memmove(s - 1, s, line_ga.ga_len - (s - p) + 1);
+		    --line_ga.ga_len;
+		}
+		goto add_indent;
+	    }
+
+	    if (c1 == Ctrl_V || c1 == Ctrl_Q)
+	    {
+		escaped = TRUE;
+		continue;
+	    }
+
+	    /* Ignore special key codes: mouse movement, K_IGNORE, etc. */
+	    if (IS_SPECIAL(c1))
+		continue;
+	}
+
+	if (IS_SPECIAL(c1))
+	    c1 = '?';
+	((char_u *)line_ga.ga_data)[line_ga.ga_len] = c1;
+	prev_char = c1;
+	if (c1 == '\n')
+	    msg_putchar('\n');
+	else if (c1 == TAB)
+	{
+	    /* Don't use chartabsize(), 'ts' can be different */
+	    do
+	    {
+		msg_putchar(' ');
+	    } while (++vcol % 8);
+	}
+	else
+	{
+	    msg_outtrans_len(
+		     ((char_u *)line_ga.ga_data) + line_ga.ga_len, 1);
+	    vcol += char2cells(c1);
+	}
+	++line_ga.ga_len;
+	escaped = FALSE;
+
+	windgoto(msg_row, msg_col);
+	pend = (char_u *)(line_ga.ga_data) + line_ga.ga_len;
+
+	/* we are done when a NL is entered, but not when it comes after a
+	 * backslash */
+	if (line_ga.ga_len > 0 && pend[-1] == '\n'
+		&& (line_ga.ga_len <= 1 || pend[-2] != '\\'))
+	{
+	    --line_ga.ga_len;
+	    --pend;
+	    *pend = NUL;
+	    break;
+	}
+    }
+
+    --no_mapping;
+    --allow_keys;
+
+    /* make following messages go to the next line */
+    msg_didout = FALSE;
+    msg_col = 0;
+    if (msg_row < Rows - 1)
+	++msg_row;
+    emsg_on_display = FALSE;		/* don't want ui_delay() */
+
+    if (got_int)
+	ga_clear(&line_ga);
+
+    return (char_u *)line_ga.ga_data;
+}
+
+# if defined(MCH_CURSOR_SHAPE) || defined(FEAT_GUI) \
+	|| defined(FEAT_MOUSESHAPE) || defined(PROTO)
+/*
+ * Return TRUE if ccline.overstrike is on.
+ */
+    int
+cmdline_overstrike()
+{
+    return ccline.overstrike;
+}
+
+/*
+ * Return TRUE if the cursor is at the end of the cmdline.
+ */
+    int
+cmdline_at_end()
+{
+    return (ccline.cmdpos >= ccline.cmdlen);
+}
+#endif
+
+#if (defined(FEAT_XIM) && (defined(FEAT_GUI_GTK))) || defined(PROTO)
+/*
+ * Return the virtual column number at the current cursor position.
+ * This is used by the IM code to obtain the start of the preedit string.
+ */
+    colnr_T
+cmdline_getvcol_cursor()
+{
+    if (ccline.cmdbuff == NULL || ccline.cmdpos > ccline.cmdlen)
+	return MAXCOL;
+
+# ifdef FEAT_MBYTE
+    if (has_mbyte)
+    {
+	colnr_T	col;
+	int	i = 0;
+
+	for (col = 0; i < ccline.cmdpos; ++col)
+	    i += (*mb_ptr2len)(ccline.cmdbuff + i);
+
+	return col;
+    }
+    else
+# endif
+	return ccline.cmdpos;
+}
+#endif
+
+#if defined(FEAT_XIM) && defined(FEAT_GUI_GTK)
+/*
+ * If part of the command line is an IM preedit string, redraw it with
+ * IM feedback attributes.  The cursor position is restored after drawing.
+ */
+    static void
+redrawcmd_preedit()
+{
+    if ((State & CMDLINE)
+	    && xic != NULL
+	    /* && im_get_status()  doesn't work when using SCIM */
+	    && !p_imdisable
+	    && im_is_preediting())
+    {
+	int	cmdpos = 0;
+	int	cmdspos;
+	int	old_row;
+	int	old_col;
+	colnr_T	col;
+
+	old_row = msg_row;
+	old_col = msg_col;
+	cmdspos = ((ccline.cmdfirstc != NUL) ? 1 : 0) + ccline.cmdindent;
+
+# ifdef FEAT_MBYTE
+	if (has_mbyte)
+	{
+	    for (col = 0; col < preedit_start_col
+			  && cmdpos < ccline.cmdlen; ++col)
+	    {
+		cmdspos += (*mb_ptr2cells)(ccline.cmdbuff + cmdpos);
+		cmdpos  += (*mb_ptr2len)(ccline.cmdbuff + cmdpos);
+	    }
+	}
+	else
+# endif
+	{
+	    cmdspos += preedit_start_col;
+	    cmdpos  += preedit_start_col;
+	}
+
+	msg_row = cmdline_row + (cmdspos / (int)Columns);
+	msg_col = cmdspos % (int)Columns;
+	if (msg_row >= Rows)
+	    msg_row = Rows - 1;
+
+	for (col = 0; cmdpos < ccline.cmdlen; ++col)
+	{
+	    int char_len;
+	    int char_attr;
+
+	    char_attr = im_get_feedback_attr(col);
+	    if (char_attr < 0)
+		break; /* end of preedit string */
+
+# ifdef FEAT_MBYTE
+	    if (has_mbyte)
+		char_len = (*mb_ptr2len)(ccline.cmdbuff + cmdpos);
+	    else
+# endif
+		char_len = 1;
+
+	    msg_outtrans_len_attr(ccline.cmdbuff + cmdpos, char_len, char_attr);
+	    cmdpos += char_len;
+	}
+
+	msg_row = old_row;
+	msg_col = old_col;
+    }
+}
+#endif /* FEAT_XIM && FEAT_GUI_GTK */
+
+/*
+ * Allocate a new command line buffer.
+ * Assigns the new buffer to ccline.cmdbuff and ccline.cmdbufflen.
+ * Returns the new value of ccline.cmdbuff and ccline.cmdbufflen.
+ */
+    static void
+alloc_cmdbuff(len)
+    int	    len;
+{
+    /*
+     * give some extra space to avoid having to allocate all the time
+     */
+    if (len < 80)
+	len = 100;
+    else
+	len += 20;
+
+    ccline.cmdbuff = alloc(len);    /* caller should check for out-of-memory */
+    ccline.cmdbufflen = len;
+}
+
+/*
+ * Re-allocate the command line to length len + something extra.
+ * return FAIL for failure, OK otherwise
+ */
+    static int
+realloc_cmdbuff(len)
+    int	    len;
+{
+    char_u	*p;
+
+    p = ccline.cmdbuff;
+    alloc_cmdbuff(len);			/* will get some more */
+    if (ccline.cmdbuff == NULL)		/* out of memory */
+    {
+	ccline.cmdbuff = p;		/* keep the old one */
+	return FAIL;
+    }
+    mch_memmove(ccline.cmdbuff, p, (size_t)ccline.cmdlen + 1);
+    vim_free(p);
+    return OK;
+}
+
+#if defined(FEAT_ARABIC) || defined(PROTO)
+static char_u	*arshape_buf = NULL;
+
+# if defined(EXITFREE) || defined(PROTO)
+    void
+free_cmdline_buf()
+{
+    vim_free(arshape_buf);
+}
+# endif
+#endif
+
+/*
+ * Draw part of the cmdline at the current cursor position.  But draw stars
+ * when cmdline_star is TRUE.
+ */
+    static void
+draw_cmdline(start, len)
+    int		start;
+    int		len;
+{
+#if defined(FEAT_CRYPT) || defined(FEAT_EVAL)
+    int		i;
+
+    if (cmdline_star > 0)
+	for (i = 0; i < len; ++i)
+	{
+	    msg_putchar('*');
+# ifdef FEAT_MBYTE
+	    if (has_mbyte)
+		i += (*mb_ptr2len)(ccline.cmdbuff + start + i) - 1;
+# endif
+	}
+    else
+#endif
+#ifdef FEAT_ARABIC
+	if (p_arshape && !p_tbidi && enc_utf8 && len > 0)
+    {
+	static int	buflen = 0;
+	char_u		*p;
+	int		j;
+	int		newlen = 0;
+	int		mb_l;
+	int		pc, pc1 = 0;
+	int		prev_c = 0;
+	int		prev_c1 = 0;
+	int		u8c;
+	int		u8cc[MAX_MCO];
+	int		nc = 0;
+
+	/*
+	 * Do arabic shaping into a temporary buffer.  This is very
+	 * inefficient!
+	 */
+	if (len * 2 + 2 > buflen)
+	{
+	    /* Re-allocate the buffer.  We keep it around to avoid a lot of
+	     * alloc()/free() calls. */
+	    vim_free(arshape_buf);
+	    buflen = len * 2 + 2;
+	    arshape_buf = alloc(buflen);
+	    if (arshape_buf == NULL)
+		return;	/* out of memory */
+	}
+
+	if (utf_iscomposing(utf_ptr2char(ccline.cmdbuff + start)))
+	{
+	    /* Prepend a space to draw the leading composing char on. */
+	    arshape_buf[0] = ' ';
+	    newlen = 1;
+	}
+
+	for (j = start; j < start + len; j += mb_l)
+	{
+	    p = ccline.cmdbuff + j;
+	    u8c = utfc_ptr2char_len(p, u8cc, start + len - j);
+	    mb_l = utfc_ptr2len_len(p, start + len - j);
+	    if (ARABIC_CHAR(u8c))
+	    {
+		/* Do Arabic shaping. */
+		if (cmdmsg_rl)
+		{
+		    /* displaying from right to left */
+		    pc = prev_c;
+		    pc1 = prev_c1;
+		    prev_c1 = u8cc[0];
+		    if (j + mb_l >= start + len)
+			nc = NUL;
+		    else
+			nc = utf_ptr2char(p + mb_l);
+		}
+		else
+		{
+		    /* displaying from left to right */
+		    if (j + mb_l >= start + len)
+			pc = NUL;
+		    else
+		    {
+			int	pcc[MAX_MCO];
+
+			pc = utfc_ptr2char_len(p + mb_l, pcc,
+						      start + len - j - mb_l);
+			pc1 = pcc[0];
+		    }
+		    nc = prev_c;
+		}
+		prev_c = u8c;
+
+		u8c = arabic_shape(u8c, NULL, &u8cc[0], pc, pc1, nc);
+
+		newlen += (*mb_char2bytes)(u8c, arshape_buf + newlen);
+		if (u8cc[0] != 0)
+		{
+		    newlen += (*mb_char2bytes)(u8cc[0], arshape_buf + newlen);
+		    if (u8cc[1] != 0)
+			newlen += (*mb_char2bytes)(u8cc[1],
+							arshape_buf + newlen);
+		}
+	    }
+	    else
+	    {
+		prev_c = u8c;
+		mch_memmove(arshape_buf + newlen, p, mb_l);
+		newlen += mb_l;
+	    }
+	}
+
+	msg_outtrans_len(arshape_buf, newlen);
+    }
+    else
+#endif
+	msg_outtrans_len(ccline.cmdbuff + start, len);
+}
+
+/*
+ * Put a character on the command line.  Shifts the following text to the
+ * right when "shift" is TRUE.  Used for CTRL-V, CTRL-K, etc.
+ * "c" must be printable (fit in one display cell)!
+ */
+    void
+putcmdline(c, shift)
+    int		c;
+    int		shift;
+{
+    if (cmd_silent)
+	return;
+    msg_no_more = TRUE;
+    msg_putchar(c);
+    if (shift)
+	draw_cmdline(ccline.cmdpos, ccline.cmdlen - ccline.cmdpos);
+    msg_no_more = FALSE;
+    cursorcmd();
+}
+
+/*
+ * Undo a putcmdline(c, FALSE).
+ */
+    void
+unputcmdline()
+{
+    if (cmd_silent)
+	return;
+    msg_no_more = TRUE;
+    if (ccline.cmdlen == ccline.cmdpos)
+	msg_putchar(' ');
+    else
+	draw_cmdline(ccline.cmdpos, 1);
+    msg_no_more = FALSE;
+    cursorcmd();
+}
+
+/*
+ * Put the given string, of the given length, onto the command line.
+ * If len is -1, then STRLEN() is used to calculate the length.
+ * If 'redraw' is TRUE then the new part of the command line, and the remaining
+ * part will be redrawn, otherwise it will not.  If this function is called
+ * twice in a row, then 'redraw' should be FALSE and redrawcmd() should be
+ * called afterwards.
+ */
+    int
+put_on_cmdline(str, len, redraw)
+    char_u	*str;
+    int		len;
+    int		redraw;
+{
+    int		retval;
+    int		i;
+    int		m;
+    int		c;
+
+    if (len < 0)
+	len = (int)STRLEN(str);
+
+    /* Check if ccline.cmdbuff needs to be longer */
+    if (ccline.cmdlen + len + 1 >= ccline.cmdbufflen)
+	retval = realloc_cmdbuff(ccline.cmdlen + len);
+    else
+	retval = OK;
+    if (retval == OK)
+    {
+	if (!ccline.overstrike)
+	{
+	    mch_memmove(ccline.cmdbuff + ccline.cmdpos + len,
+					       ccline.cmdbuff + ccline.cmdpos,
+				     (size_t)(ccline.cmdlen - ccline.cmdpos));
+	    ccline.cmdlen += len;
+	}
+	else
+	{
+#ifdef FEAT_MBYTE
+	    if (has_mbyte)
+	    {
+		/* Count nr of characters in the new string. */
+		m = 0;
+		for (i = 0; i < len; i += (*mb_ptr2len)(str + i))
+		    ++m;
+		/* Count nr of bytes in cmdline that are overwritten by these
+		 * characters. */
+		for (i = ccline.cmdpos; i < ccline.cmdlen && m > 0;
+				 i += (*mb_ptr2len)(ccline.cmdbuff + i))
+		    --m;
+		if (i < ccline.cmdlen)
+		{
+		    mch_memmove(ccline.cmdbuff + ccline.cmdpos + len,
+			    ccline.cmdbuff + i, (size_t)(ccline.cmdlen - i));
+		    ccline.cmdlen += ccline.cmdpos + len - i;
+		}
+		else
+		    ccline.cmdlen = ccline.cmdpos + len;
+	    }
+	    else
+#endif
+	    if (ccline.cmdpos + len > ccline.cmdlen)
+		ccline.cmdlen = ccline.cmdpos + len;
+	}
+	mch_memmove(ccline.cmdbuff + ccline.cmdpos, str, (size_t)len);
+	ccline.cmdbuff[ccline.cmdlen] = NUL;
+
+#ifdef FEAT_MBYTE
+	if (enc_utf8)
+	{
+	    /* When the inserted text starts with a composing character,
+	     * backup to the character before it.  There could be two of them.
+	     */
+	    i = 0;
+	    c = utf_ptr2char(ccline.cmdbuff + ccline.cmdpos);
+	    while (ccline.cmdpos > 0 && utf_iscomposing(c))
+	    {
+		i = (*mb_head_off)(ccline.cmdbuff,
+				      ccline.cmdbuff + ccline.cmdpos - 1) + 1;
+		ccline.cmdpos -= i;
+		len += i;
+		c = utf_ptr2char(ccline.cmdbuff + ccline.cmdpos);
+	    }
+# ifdef FEAT_ARABIC
+	    if (i == 0 && ccline.cmdpos > 0 && arabic_maycombine(c))
+	    {
+		/* Check the previous character for Arabic combining pair. */
+		i = (*mb_head_off)(ccline.cmdbuff,
+				      ccline.cmdbuff + ccline.cmdpos - 1) + 1;
+		if (arabic_combine(utf_ptr2char(ccline.cmdbuff
+						     + ccline.cmdpos - i), c))
+		{
+		    ccline.cmdpos -= i;
+		    len += i;
+		}
+		else
+		    i = 0;
+	    }
+# endif
+	    if (i != 0)
+	    {
+		/* Also backup the cursor position. */
+		i = ptr2cells(ccline.cmdbuff + ccline.cmdpos);
+		ccline.cmdspos -= i;
+		msg_col -= i;
+		if (msg_col < 0)
+		{
+		    msg_col += Columns;
+		    --msg_row;
+		}
+	    }
+	}
+#endif
+
+	if (redraw && !cmd_silent)
+	{
+	    msg_no_more = TRUE;
+	    i = cmdline_row;
+	    draw_cmdline(ccline.cmdpos, ccline.cmdlen - ccline.cmdpos);
+	    /* Avoid clearing the rest of the line too often. */
+	    if (cmdline_row != i || ccline.overstrike)
+		msg_clr_eos();
+	    msg_no_more = FALSE;
+	}
+#ifdef FEAT_FKMAP
+	/*
+	 * If we are in Farsi command mode, the character input must be in
+	 * Insert mode. So do not advance the cmdpos.
+	 */
+	if (!cmd_fkmap)
+#endif
+	{
+	    if (KeyTyped)
+	    {
+		m = Columns * Rows;
+		if (m < 0)	/* overflow, Columns or Rows at weird value */
+		    m = MAXCOL;
+	    }
+	    else
+		m = MAXCOL;
+	    for (i = 0; i < len; ++i)
+	    {
+		c = cmdline_charsize(ccline.cmdpos);
+#ifdef FEAT_MBYTE
+		/* count ">" for a double-wide char that doesn't fit. */
+		if (has_mbyte)
+		    correct_cmdspos(ccline.cmdpos, c);
+#endif
+		/* Stop cursor at the end of the screen */
+		if (ccline.cmdspos + c >= m)
+		    break;
+		ccline.cmdspos += c;
+#ifdef FEAT_MBYTE
+		if (has_mbyte)
+		{
+		    c = (*mb_ptr2len)(ccline.cmdbuff + ccline.cmdpos) - 1;
+		    if (c > len - i - 1)
+			c = len - i - 1;
+		    ccline.cmdpos += c;
+		    i += c;
+		}
+#endif
+		++ccline.cmdpos;
+	    }
+	}
+    }
+    if (redraw)
+	msg_check();
+    return retval;
+}
+
+static struct cmdline_info  prev_ccline;
+static int		    prev_ccline_used = FALSE;
+
+/*
+ * Save ccline, because obtaining the "=" register may execute "normal :cmd"
+ * and overwrite it.  But get_cmdline_str() may need it, thus make it
+ * available globally in prev_ccline.
+ */
+    static void
+save_cmdline(ccp)
+    struct cmdline_info *ccp;
+{
+    if (!prev_ccline_used)
+    {
+	vim_memset(&prev_ccline, 0, sizeof(struct cmdline_info));
+	prev_ccline_used = TRUE;
+    }
+    *ccp = prev_ccline;
+    prev_ccline = ccline;
+    ccline.cmdbuff = NULL;
+    ccline.cmdprompt = NULL;
+}
+
+/*
+ * Restore ccline after it has been saved with save_cmdline().
+ */
+    static void
+restore_cmdline(ccp)
+    struct cmdline_info *ccp;
+{
+    ccline = prev_ccline;
+    prev_ccline = *ccp;
+}
+
+#if defined(FEAT_EVAL) || defined(PROTO)
+/*
+ * Save the command line into allocated memory.  Returns a pointer to be
+ * passed to restore_cmdline_alloc() later.
+ * Returns NULL when failed.
+ */
+    char_u *
+save_cmdline_alloc()
+{
+    struct cmdline_info *p;
+
+    p = (struct cmdline_info *)alloc((unsigned)sizeof(struct cmdline_info));
+    if (p != NULL)
+	save_cmdline(p);
+    return (char_u *)p;
+}
+
+/*
+ * Restore the command line from the return value of save_cmdline_alloc().
+ */
+    void
+restore_cmdline_alloc(p)
+    char_u  *p;
+{
+    if (p != NULL)
+    {
+	restore_cmdline((struct cmdline_info *)p);
+	vim_free(p);
+    }
+}
+#endif
+
+/*
+ * paste a yank register into the command line.
+ * used by CTRL-R command in command-line mode
+ * insert_reg() can't be used here, because special characters from the
+ * register contents will be interpreted as commands.
+ *
+ * return FAIL for failure, OK otherwise
+ */
+    static int
+cmdline_paste(regname, literally, remcr)
+    int regname;
+    int literally;	/* Insert text literally instead of "as typed" */
+    int remcr;		/* remove trailing CR */
+{
+    long		i;
+    char_u		*arg;
+    char_u		*p;
+    int			allocated;
+    struct cmdline_info	save_ccline;
+
+    /* check for valid regname; also accept special characters for CTRL-R in
+     * the command line */
+    if (regname != Ctrl_F && regname != Ctrl_P && regname != Ctrl_W
+	    && regname != Ctrl_A && !valid_yank_reg(regname, FALSE))
+	return FAIL;
+
+    /* A register containing CTRL-R can cause an endless loop.  Allow using
+     * CTRL-C to break the loop. */
+    line_breakcheck();
+    if (got_int)
+	return FAIL;
+
+#ifdef FEAT_CLIPBOARD
+    regname = may_get_selection(regname);
+#endif
+
+    /* Need to save and restore ccline.  And set "textlock" to avoid nasty
+     * things like going to another buffer when evaluating an expression. */
+    save_cmdline(&save_ccline);
+    ++textlock;
+    i = get_spec_reg(regname, &arg, &allocated, TRUE);
+    --textlock;
+    restore_cmdline(&save_ccline);
+
+    if (i)
+    {
+	/* Got the value of a special register in "arg". */
+	if (arg == NULL)
+	    return FAIL;
+
+	/* When 'incsearch' is set and CTRL-R CTRL-W used: skip the duplicate
+	 * part of the word. */
+	p = arg;
+	if (p_is && regname == Ctrl_W)
+	{
+	    char_u  *w;
+	    int	    len;
+
+	    /* Locate start of last word in the cmd buffer. */
+	    for (w = ccline.cmdbuff + ccline.cmdlen; w > ccline.cmdbuff; )
+	    {
+#ifdef FEAT_MBYTE
+		if (has_mbyte)
+		{
+		    len = (*mb_head_off)(ccline.cmdbuff, w - 1) + 1;
+		    if (!vim_iswordc(mb_ptr2char(w - len)))
+			break;
+		    w -= len;
+		}
+		else
+#endif
+		{
+		    if (!vim_iswordc(w[-1]))
+			break;
+		    --w;
+		}
+	    }
+	    len = (int)((ccline.cmdbuff + ccline.cmdlen) - w);
+	    if (p_ic ? STRNICMP(w, arg, len) == 0 : STRNCMP(w, arg, len) == 0)
+		p += len;
+	}
+
+	cmdline_paste_str(p, literally);
+	if (allocated)
+	    vim_free(arg);
+	return OK;
+    }
+
+    return cmdline_paste_reg(regname, literally, remcr);
+}
+
+/*
+ * Put a string on the command line.
+ * When "literally" is TRUE, insert literally.
+ * When "literally" is FALSE, insert as typed, but don't leave the command
+ * line.
+ */
+    void
+cmdline_paste_str(s, literally)
+    char_u	*s;
+    int		literally;
+{
+    int		c, cv;
+
+    if (literally)
+	put_on_cmdline(s, -1, TRUE);
+    else
+	while (*s != NUL)
+	{
+	    cv = *s;
+	    if (cv == Ctrl_V && s[1])
+		++s;
+#ifdef FEAT_MBYTE
+	    if (has_mbyte)
+	    {
+		c = mb_ptr2char(s);
+		s += mb_char2len(c);
+	    }
+	    else
+#endif
+		c = *s++;
+	    if (cv == Ctrl_V || c == ESC || c == Ctrl_C || c == CAR || c == NL
+#ifdef UNIX
+		    || c == intr_char
+#endif
+		    || (c == Ctrl_BSL && *s == Ctrl_N))
+		stuffcharReadbuff(Ctrl_V);
+	    stuffcharReadbuff(c);
+	}
+}
+
+#ifdef FEAT_WILDMENU
+/*
+ * Delete characters on the command line, from "from" to the current
+ * position.
+ */
+    static void
+cmdline_del(from)
+    int from;
+{
+    mch_memmove(ccline.cmdbuff + from, ccline.cmdbuff + ccline.cmdpos,
+	    (size_t)(ccline.cmdlen - ccline.cmdpos + 1));
+    ccline.cmdlen -= ccline.cmdpos - from;
+    ccline.cmdpos = from;
+}
+#endif
+
+/*
+ * this function is called when the screen size changes and with incremental
+ * search
+ */
+    void
+redrawcmdline()
+{
+    if (cmd_silent)
+	return;
+    need_wait_return = FALSE;
+    compute_cmdrow();
+    redrawcmd();
+    cursorcmd();
+}
+
+    static void
+redrawcmdprompt()
+{
+    int		i;
+
+    if (cmd_silent)
+	return;
+    if (ccline.cmdfirstc != NUL)
+	msg_putchar(ccline.cmdfirstc);
+    if (ccline.cmdprompt != NULL)
+    {
+	msg_puts_attr(ccline.cmdprompt, ccline.cmdattr);
+	ccline.cmdindent = msg_col + (msg_row - cmdline_row) * Columns;
+	/* do the reverse of set_cmdspos() */
+	if (ccline.cmdfirstc != NUL)
+	    --ccline.cmdindent;
+    }
+    else
+	for (i = ccline.cmdindent; i > 0; --i)
+	    msg_putchar(' ');
+}
+
+/*
+ * Redraw what is currently on the command line.
+ */
+    void
+redrawcmd()
+{
+    if (cmd_silent)
+	return;
+
+    /* when 'incsearch' is set there may be no command line while redrawing */
+    if (ccline.cmdbuff == NULL)
+    {
+	windgoto(cmdline_row, 0);
+	msg_clr_eos();
+	return;
+    }
+
+    msg_start();
+    redrawcmdprompt();
+
+    /* Don't use more prompt, truncate the cmdline if it doesn't fit. */
+    msg_no_more = TRUE;
+    draw_cmdline(0, ccline.cmdlen);
+    msg_clr_eos();
+    msg_no_more = FALSE;
+
+    set_cmdspos_cursor();
+
+    /*
+     * An emsg() before may have set msg_scroll. This is used in normal mode,
+     * in cmdline mode we can reset them now.
+     */
+    msg_scroll = FALSE;		/* next message overwrites cmdline */
+
+    /* Typing ':' at the more prompt may set skip_redraw.  We don't want this
+     * in cmdline mode */
+    skip_redraw = FALSE;
+}
+
+    void
+compute_cmdrow()
+{
+    if (exmode_active || msg_scrolled != 0)
+	cmdline_row = Rows - 1;
+    else
+	cmdline_row = W_WINROW(lastwin) + lastwin->w_height
+						   + W_STATUS_HEIGHT(lastwin);
+}
+
+    static void
+cursorcmd()
+{
+    if (cmd_silent)
+	return;
+
+#ifdef FEAT_RIGHTLEFT
+    if (cmdmsg_rl)
+    {
+	msg_row = cmdline_row  + (ccline.cmdspos / (int)(Columns - 1));
+	msg_col = (int)Columns - (ccline.cmdspos % (int)(Columns - 1)) - 1;
+	if (msg_row <= 0)
+	    msg_row = Rows - 1;
+    }
+    else
+#endif
+    {
+	msg_row = cmdline_row + (ccline.cmdspos / (int)Columns);
+	msg_col = ccline.cmdspos % (int)Columns;
+	if (msg_row >= Rows)
+	    msg_row = Rows - 1;
+    }
+
+    windgoto(msg_row, msg_col);
+#if defined(FEAT_XIM) && defined(FEAT_GUI_GTK)
+    redrawcmd_preedit();
+#endif
+#ifdef MCH_CURSOR_SHAPE
+    mch_update_cursor();
+#endif
+}
+
+    void
+gotocmdline(clr)
+    int		    clr;
+{
+    msg_start();
+#ifdef FEAT_RIGHTLEFT
+    if (cmdmsg_rl)
+	msg_col = Columns - 1;
+    else
+#endif
+	msg_col = 0;	    /* always start in column 0 */
+    if (clr)		    /* clear the bottom line(s) */
+	msg_clr_eos();	    /* will reset clear_cmdline */
+    windgoto(cmdline_row, 0);
+}
+
+/*
+ * Check the word in front of the cursor for an abbreviation.
+ * Called when the non-id character "c" has been entered.
+ * When an abbreviation is recognized it is removed from the text with
+ * backspaces and the replacement string is inserted, followed by "c".
+ */
+    static int
+ccheck_abbr(c)
+    int c;
+{
+    if (p_paste || no_abbr)	    /* no abbreviations or in paste mode */
+	return FALSE;
+
+    return check_abbr(c, ccline.cmdbuff, ccline.cmdpos, 0);
+}
+
+/*
+ * Return FAIL if this is not an appropriate context in which to do
+ * completion of anything, return OK if it is (even if there are no matches).
+ * For the caller, this means that the character is just passed through like a
+ * normal character (instead of being expanded).  This allows :s/^I^D etc.
+ */
+    static int
+nextwild(xp, type, options)
+    expand_T	*xp;
+    int		type;
+    int		options;	/* extra options for ExpandOne() */
+{
+    int		i, j;
+    char_u	*p1;
+    char_u	*p2;
+    int		oldlen;
+    int		difflen;
+    int		v;
+
+    if (xp->xp_numfiles == -1)
+    {
+	set_expand_context(xp);
+	cmd_showtail = expand_showtail(xp);
+    }
+
+    if (xp->xp_context == EXPAND_UNSUCCESSFUL)
+    {
+	beep_flush();
+	return OK;  /* Something illegal on command line */
+    }
+    if (xp->xp_context == EXPAND_NOTHING)
+    {
+	/* Caller can use the character as a normal char instead */
+	return FAIL;
+    }
+
+    MSG_PUTS("...");	    /* show that we are busy */
+    out_flush();
+
+    i = (int)(xp->xp_pattern - ccline.cmdbuff);
+    oldlen = ccline.cmdpos - i;
+
+    if (type == WILD_NEXT || type == WILD_PREV)
+    {
+	/*
+	 * Get next/previous match for a previous expanded pattern.
+	 */
+	p2 = ExpandOne(xp, NULL, NULL, 0, type);
+    }
+    else
+    {
+	/*
+	 * Translate string into pattern and expand it.
+	 */
+	if ((p1 = addstar(&ccline.cmdbuff[i], oldlen, xp->xp_context)) == NULL)
+	    p2 = NULL;
+	else
+	{
+	    p2 = ExpandOne(xp, p1, vim_strnsave(&ccline.cmdbuff[i], oldlen),
+		    WILD_HOME_REPLACE|WILD_ADD_SLASH|WILD_SILENT|WILD_ESCAPE
+							      |options, type);
+	    vim_free(p1);
+	    /* longest match: make sure it is not shorter (happens with :help */
+	    if (p2 != NULL && type == WILD_LONGEST)
+	    {
+		for (j = 0; j < oldlen; ++j)
+		     if (ccline.cmdbuff[i + j] == '*'
+			     || ccline.cmdbuff[i + j] == '?')
+			 break;
+		if ((int)STRLEN(p2) < j)
+		{
+		    vim_free(p2);
+		    p2 = NULL;
+		}
+	    }
+	}
+    }
+
+    if (p2 != NULL && !got_int)
+    {
+	difflen = (int)STRLEN(p2) - oldlen;
+	if (ccline.cmdlen + difflen > ccline.cmdbufflen - 4)
+	{
+	    v = realloc_cmdbuff(ccline.cmdlen + difflen);
+	    xp->xp_pattern = ccline.cmdbuff + i;
+	}
+	else
+	    v = OK;
+	if (v == OK)
+	{
+	    mch_memmove(&ccline.cmdbuff[ccline.cmdpos + difflen],
+		    &ccline.cmdbuff[ccline.cmdpos],
+		    (size_t)(ccline.cmdlen - ccline.cmdpos + 1));
+	    mch_memmove(&ccline.cmdbuff[i], p2, STRLEN(p2));
+	    ccline.cmdlen += difflen;
+	    ccline.cmdpos += difflen;
+	}
+    }
+    vim_free(p2);
+
+    redrawcmd();
+    cursorcmd();
+
+    /* When expanding a ":map" command and no matches are found, assume that
+     * the key is supposed to be inserted literally */
+    if (xp->xp_context == EXPAND_MAPPINGS && p2 == NULL)
+	return FAIL;
+
+    if (xp->xp_numfiles <= 0 && p2 == NULL)
+	beep_flush();
+    else if (xp->xp_numfiles == 1)
+	/* free expanded pattern */
+	(void)ExpandOne(xp, NULL, NULL, 0, WILD_FREE);
+
+    return OK;
+}
+
+/*
+ * Do wildcard expansion on the string 'str'.
+ * Chars that should not be expanded must be preceded with a backslash.
+ * Return a pointer to alloced memory containing the new string.
+ * Return NULL for failure.
+ *
+ * Results are cached in xp->xp_files and xp->xp_numfiles, except when "mode"
+ * is WILD_EXPAND_FREE or WILD_ALL.
+ *
+ * mode = WILD_FREE:	    just free previously expanded matches
+ * mode = WILD_EXPAND_FREE: normal expansion, do not keep matches
+ * mode = WILD_EXPAND_KEEP: normal expansion, keep matches
+ * mode = WILD_NEXT:	    use next match in multiple match, wrap to first
+ * mode = WILD_PREV:	    use previous match in multiple match, wrap to first
+ * mode = WILD_ALL:	    return all matches concatenated
+ * mode = WILD_LONGEST:	    return longest matched part
+ *
+ * options = WILD_LIST_NOTFOUND:    list entries without a match
+ * options = WILD_HOME_REPLACE:	    do home_replace() for buffer names
+ * options = WILD_USE_NL:	    Use '\n' for WILD_ALL
+ * options = WILD_NO_BEEP:	    Don't beep for multiple matches
+ * options = WILD_ADD_SLASH:	    add a slash after directory names
+ * options = WILD_KEEP_ALL:	    don't remove 'wildignore' entries
+ * options = WILD_SILENT:	    don't print warning messages
+ * options = WILD_ESCAPE:	    put backslash before special chars
+ *
+ * The variables xp->xp_context and xp->xp_backslash must have been set!
+ */
+    char_u *
+ExpandOne(xp, str, orig, options, mode)
+    expand_T	*xp;
+    char_u	*str;
+    char_u	*orig;	    /* allocated copy of original of expanded string */
+    int		options;
+    int		mode;
+{
+    char_u	*ss = NULL;
+    static int	findex;
+    static char_u *orig_save = NULL;	/* kept value of orig */
+    int		i;
+    long_u	len;
+    int		non_suf_match;		/* number without matching suffix */
+
+    /*
+     * first handle the case of using an old match
+     */
+    if (mode == WILD_NEXT || mode == WILD_PREV)
+    {
+	if (xp->xp_numfiles > 0)
+	{
+	    if (mode == WILD_PREV)
+	    {
+		if (findex == -1)
+		    findex = xp->xp_numfiles;
+		--findex;
+	    }
+	    else    /* mode == WILD_NEXT */
+		++findex;
+
+	    /*
+	     * When wrapping around, return the original string, set findex to
+	     * -1.
+	     */
+	    if (findex < 0)
+	    {
+		if (orig_save == NULL)
+		    findex = xp->xp_numfiles - 1;
+		else
+		    findex = -1;
+	    }
+	    if (findex >= xp->xp_numfiles)
+	    {
+		if (orig_save == NULL)
+		    findex = 0;
+		else
+		    findex = -1;
+	    }
+#ifdef FEAT_WILDMENU
+	    if (p_wmnu)
+		win_redr_status_matches(xp, xp->xp_numfiles, xp->xp_files,
+							findex, cmd_showtail);
+#endif
+	    if (findex == -1)
+		return vim_strsave(orig_save);
+	    return vim_strsave(xp->xp_files[findex]);
+	}
+	else
+	    return NULL;
+    }
+
+/* free old names */
+    if (xp->xp_numfiles != -1 && mode != WILD_ALL && mode != WILD_LONGEST)
+    {
+	FreeWild(xp->xp_numfiles, xp->xp_files);
+	xp->xp_numfiles = -1;
+	vim_free(orig_save);
+	orig_save = NULL;
+    }
+    findex = 0;
+
+    if (mode == WILD_FREE)	/* only release file name */
+	return NULL;
+
+    if (xp->xp_numfiles == -1)
+    {
+	vim_free(orig_save);
+	orig_save = orig;
+
+	/*
+	 * Do the expansion.
+	 */
+	if (ExpandFromContext(xp, str, &xp->xp_numfiles, &xp->xp_files,
+							     options) == FAIL)
+	{
+#ifdef FNAME_ILLEGAL
+	    /* Illegal file name has been silently skipped.  But when there
+	     * are wildcards, the real problem is that there was no match,
+	     * causing the pattern to be added, which has illegal characters.
+	     */
+	    if (!(options & WILD_SILENT) && (options & WILD_LIST_NOTFOUND))
+		EMSG2(_(e_nomatch2), str);
+#endif
+	}
+	else if (xp->xp_numfiles == 0)
+	{
+	    if (!(options & WILD_SILENT))
+		EMSG2(_(e_nomatch2), str);
+	}
+	else
+	{
+	    /* Escape the matches for use on the command line. */
+	    ExpandEscape(xp, str, xp->xp_numfiles, xp->xp_files, options);
+
+	    /*
+	     * Check for matching suffixes in file names.
+	     */
+	    if (mode != WILD_ALL && mode != WILD_LONGEST)
+	    {
+		if (xp->xp_numfiles)
+		    non_suf_match = xp->xp_numfiles;
+		else
+		    non_suf_match = 1;
+		if ((xp->xp_context == EXPAND_FILES
+			    || xp->xp_context == EXPAND_DIRECTORIES)
+			&& xp->xp_numfiles > 1)
+		{
+		    /*
+		     * More than one match; check suffix.
+		     * The files will have been sorted on matching suffix in
+		     * expand_wildcards, only need to check the first two.
+		     */
+		    non_suf_match = 0;
+		    for (i = 0; i < 2; ++i)
+			if (match_suffix(xp->xp_files[i]))
+			    ++non_suf_match;
+		}
+		if (non_suf_match != 1)
+		{
+		    /* Can we ever get here unless it's while expanding
+		     * interactively?  If not, we can get rid of this all
+		     * together. Don't really want to wait for this message
+		     * (and possibly have to hit return to continue!).
+		     */
+		    if (!(options & WILD_SILENT))
+			EMSG(_(e_toomany));
+		    else if (!(options & WILD_NO_BEEP))
+			beep_flush();
+		}
+		if (!(non_suf_match != 1 && mode == WILD_EXPAND_FREE))
+		    ss = vim_strsave(xp->xp_files[0]);
+	    }
+	}
+    }
+
+    /* Find longest common part */
+    if (mode == WILD_LONGEST && xp->xp_numfiles > 0)
+    {
+	for (len = 0; xp->xp_files[0][len]; ++len)
+	{
+	    for (i = 0; i < xp->xp_numfiles; ++i)
+	    {
+#ifdef CASE_INSENSITIVE_FILENAME
+		if (xp->xp_context == EXPAND_DIRECTORIES
+			|| xp->xp_context == EXPAND_FILES
+			|| xp->xp_context == EXPAND_SHELLCMD
+			|| xp->xp_context == EXPAND_BUFFERS)
+		{
+		    if (TOLOWER_LOC(xp->xp_files[i][len]) !=
+					    TOLOWER_LOC(xp->xp_files[0][len]))
+			break;
+		}
+		else
+#endif
+		     if (xp->xp_files[i][len] != xp->xp_files[0][len])
+		    break;
+	    }
+	    if (i < xp->xp_numfiles)
+	    {
+		if (!(options & WILD_NO_BEEP))
+		    vim_beep();
+		break;
+	    }
+	}
+	ss = alloc((unsigned)len + 1);
+	if (ss)
+	    vim_strncpy(ss, xp->xp_files[0], (size_t)len);
+	findex = -1;			    /* next p_wc gets first one */
+    }
+
+    /* Concatenate all matching names */
+    if (mode == WILD_ALL && xp->xp_numfiles > 0)
+    {
+	len = 0;
+	for (i = 0; i < xp->xp_numfiles; ++i)
+	    len += (long_u)STRLEN(xp->xp_files[i]) + 1;
+	ss = lalloc(len, TRUE);
+	if (ss != NULL)
+	{
+	    *ss = NUL;
+	    for (i = 0; i < xp->xp_numfiles; ++i)
+	    {
+		STRCAT(ss, xp->xp_files[i]);
+		if (i != xp->xp_numfiles - 1)
+		    STRCAT(ss, (options & WILD_USE_NL) ? "\n" : " ");
+	    }
+	}
+    }
+
+    if (mode == WILD_EXPAND_FREE || mode == WILD_ALL)
+	ExpandCleanup(xp);
+
+    return ss;
+}
+
+/*
+ * Prepare an expand structure for use.
+ */
+    void
+ExpandInit(xp)
+    expand_T	*xp;
+{
+    xp->xp_backslash = XP_BS_NONE;
+#ifndef BACKSLASH_IN_FILENAME
+    xp->xp_shell = FALSE;
+#endif
+    xp->xp_numfiles = -1;
+    xp->xp_files = NULL;
+#if defined(FEAT_USR_CMDS) && defined(FEAT_EVAL) && defined(FEAT_CMDL_COMPL)
+    xp->xp_arg = NULL;
+#endif
+}
+
+/*
+ * Cleanup an expand structure after use.
+ */
+    void
+ExpandCleanup(xp)
+    expand_T	*xp;
+{
+    if (xp->xp_numfiles >= 0)
+    {
+	FreeWild(xp->xp_numfiles, xp->xp_files);
+	xp->xp_numfiles = -1;
+    }
+}
+
+    void
+ExpandEscape(xp, str, numfiles, files, options)
+    expand_T	*xp;
+    char_u	*str;
+    int		numfiles;
+    char_u	**files;
+    int		options;
+{
+    int		i;
+    char_u	*p;
+
+    /*
+     * May change home directory back to "~"
+     */
+    if (options & WILD_HOME_REPLACE)
+	tilde_replace(str, numfiles, files);
+
+    if (options & WILD_ESCAPE)
+    {
+	if (xp->xp_context == EXPAND_FILES
+		|| xp->xp_context == EXPAND_SHELLCMD
+		|| xp->xp_context == EXPAND_BUFFERS
+		|| xp->xp_context == EXPAND_DIRECTORIES)
+	{
+	    /*
+	     * Insert a backslash into a file name before a space, \, %, #
+	     * and wildmatch characters, except '~'.
+	     */
+	    for (i = 0; i < numfiles; ++i)
+	    {
+		/* for ":set path=" we need to escape spaces twice */
+		if (xp->xp_backslash == XP_BS_THREE)
+		{
+		    p = vim_strsave_escaped(files[i], (char_u *)" ");
+		    if (p != NULL)
+		    {
+			vim_free(files[i]);
+			files[i] = p;
+#if defined(BACKSLASH_IN_FILENAME)
+			p = vim_strsave_escaped(files[i], (char_u *)" ");
+			if (p != NULL)
+			{
+			    vim_free(files[i]);
+			    files[i] = p;
+			}
+#endif
+		    }
+		}
+#ifdef BACKSLASH_IN_FILENAME
+		{
+		    char_u	buf[20];
+		    int		j = 0;
+
+		    /* Don't escape '[' and '{' if they are in 'isfname'. */
+		    for (p = PATH_ESC_CHARS; *p != NUL; ++p)
+			if ((*p != '[' && *p != '{') || !vim_isfilec(*p))
+			    buf[j++] = *p;
+		    buf[j] = NUL;
+		    p = vim_strsave_escaped(files[i], buf);
+		}
+#else
+		p = vim_strsave_escaped(files[i],
+			     xp->xp_shell ? SHELL_ESC_CHARS : PATH_ESC_CHARS);
+#endif
+		if (p != NULL)
+		{
+		    vim_free(files[i]);
+		    files[i] = p;
+		}
+
+		/* If 'str' starts with "\~", replace "~" at start of
+		 * files[i] with "\~". */
+		if (str[0] == '\\' && str[1] == '~' && files[i][0] == '~')
+		    escape_fname(&files[i]);
+	    }
+	    xp->xp_backslash = XP_BS_NONE;
+
+	    /* If the first file starts with a '+' escape it.  Otherwise it
+	     * could be seen as "+cmd". */
+	    if (*files[0] == '+')
+		escape_fname(&files[0]);
+	}
+	else if (xp->xp_context == EXPAND_TAGS)
+	{
+	    /*
+	     * Insert a backslash before characters in a tag name that
+	     * would terminate the ":tag" command.
+	     */
+	    for (i = 0; i < numfiles; ++i)
+	    {
+		p = vim_strsave_escaped(files[i], (char_u *)"\\|\"");
+		if (p != NULL)
+		{
+		    vim_free(files[i]);
+		    files[i] = p;
+		}
+	    }
+	}
+    }
+}
+
+/*
+ * Put a backslash before the file name in "pp", which is in allocated memory.
+ */
+    static void
+escape_fname(pp)
+    char_u **pp;
+{
+    char_u	*p;
+
+    p = alloc((unsigned)(STRLEN(*pp) + 2));
+    if (p != NULL)
+    {
+	p[0] = '\\';
+	STRCPY(p + 1, *pp);
+	vim_free(*pp);
+	*pp = p;
+    }
+}
+
+/*
+ * For each file name in files[num_files]:
+ * If 'orig_pat' starts with "~/", replace the home directory with "~".
+ */
+    void
+tilde_replace(orig_pat, num_files, files)
+    char_u  *orig_pat;
+    int	    num_files;
+    char_u  **files;
+{
+    int	    i;
+    char_u  *p;
+
+    if (orig_pat[0] == '~' && vim_ispathsep(orig_pat[1]))
+    {
+	for (i = 0; i < num_files; ++i)
+	{
+	    p = home_replace_save(NULL, files[i]);
+	    if (p != NULL)
+	    {
+		vim_free(files[i]);
+		files[i] = p;
+	    }
+	}
+    }
+}
+
+/*
+ * Show all matches for completion on the command line.
+ * Returns EXPAND_NOTHING when the character that triggered expansion should
+ * be inserted like a normal character.
+ */
+/*ARGSUSED*/
+    static int
+showmatches(xp, wildmenu)
+    expand_T	*xp;
+    int		wildmenu;
+{
+#define L_SHOWFILE(m) (showtail ? sm_gettail(files_found[m]) : files_found[m])
+    int		num_files;
+    char_u	**files_found;
+    int		i, j, k;
+    int		maxlen;
+    int		lines;
+    int		columns;
+    char_u	*p;
+    int		lastlen;
+    int		attr;
+    int		showtail;
+
+    if (xp->xp_numfiles == -1)
+    {
+	set_expand_context(xp);
+	i = expand_cmdline(xp, ccline.cmdbuff, ccline.cmdpos,
+						    &num_files, &files_found);
+	showtail = expand_showtail(xp);
+	if (i != EXPAND_OK)
+	    return i;
+
+    }
+    else
+    {
+	num_files = xp->xp_numfiles;
+	files_found = xp->xp_files;
+	showtail = cmd_showtail;
+    }
+
+#ifdef FEAT_WILDMENU
+    if (!wildmenu)
+    {
+#endif
+	msg_didany = FALSE;		/* lines_left will be set */
+	msg_start();			/* prepare for paging */
+	msg_putchar('\n');
+	out_flush();
+	cmdline_row = msg_row;
+	msg_didany = FALSE;		/* lines_left will be set again */
+	msg_start();			/* prepare for paging */
+#ifdef FEAT_WILDMENU
+    }
+#endif
+
+    if (got_int)
+	got_int = FALSE;	/* only int. the completion, not the cmd line */
+#ifdef FEAT_WILDMENU
+    else if (wildmenu)
+	win_redr_status_matches(xp, num_files, files_found, 0, showtail);
+#endif
+    else
+    {
+	/* find the length of the longest file name */
+	maxlen = 0;
+	for (i = 0; i < num_files; ++i)
+	{
+	    if (!showtail && (xp->xp_context == EXPAND_FILES
+			  || xp->xp_context == EXPAND_SHELLCMD
+			  || xp->xp_context == EXPAND_BUFFERS))
+	    {
+		home_replace(NULL, files_found[i], NameBuff, MAXPATHL, TRUE);
+		j = vim_strsize(NameBuff);
+	    }
+	    else
+		j = vim_strsize(L_SHOWFILE(i));
+	    if (j > maxlen)
+		maxlen = j;
+	}
+
+	if (xp->xp_context == EXPAND_TAGS_LISTFILES)
+	    lines = num_files;
+	else
+	{
+	    /* compute the number of columns and lines for the listing */
+	    maxlen += 2;    /* two spaces between file names */
+	    columns = ((int)Columns + 2) / maxlen;
+	    if (columns < 1)
+		columns = 1;
+	    lines = (num_files + columns - 1) / columns;
+	}
+
+	attr = hl_attr(HLF_D);	/* find out highlighting for directories */
+
+	if (xp->xp_context == EXPAND_TAGS_LISTFILES)
+	{
+	    MSG_PUTS_ATTR(_("tagname"), hl_attr(HLF_T));
+	    msg_clr_eos();
+	    msg_advance(maxlen - 3);
+	    MSG_PUTS_ATTR(_(" kind file\n"), hl_attr(HLF_T));
+	}
+
+	/* list the files line by line */
+	for (i = 0; i < lines; ++i)
+	{
+	    lastlen = 999;
+	    for (k = i; k < num_files; k += lines)
+	    {
+		if (xp->xp_context == EXPAND_TAGS_LISTFILES)
+		{
+		    msg_outtrans_attr(files_found[k], hl_attr(HLF_D));
+		    p = files_found[k] + STRLEN(files_found[k]) + 1;
+		    msg_advance(maxlen + 1);
+		    msg_puts(p);
+		    msg_advance(maxlen + 3);
+		    msg_puts_long_attr(p + 2, hl_attr(HLF_D));
+		    break;
+		}
+		for (j = maxlen - lastlen; --j >= 0; )
+		    msg_putchar(' ');
+		if (xp->xp_context == EXPAND_FILES
+					  || xp->xp_context == EXPAND_SHELLCMD
+					  || xp->xp_context == EXPAND_BUFFERS)
+		{
+			    /* highlight directories */
+		    j = (mch_isdir(files_found[k]));
+		    if (showtail)
+			p = L_SHOWFILE(k);
+		    else
+		    {
+			home_replace(NULL, files_found[k], NameBuff, MAXPATHL,
+									TRUE);
+			p = NameBuff;
+		    }
+		}
+		else
+		{
+		    j = FALSE;
+		    p = L_SHOWFILE(k);
+		}
+		lastlen = msg_outtrans_attr(p, j ? attr : 0);
+	    }
+	    if (msg_col > 0)	/* when not wrapped around */
+	    {
+		msg_clr_eos();
+		msg_putchar('\n');
+	    }
+	    out_flush();		    /* show one line at a time */
+	    if (got_int)
+	    {
+		got_int = FALSE;
+		break;
+	    }
+	}
+
+	/*
+	 * we redraw the command below the lines that we have just listed
+	 * This is a bit tricky, but it saves a lot of screen updating.
+	 */
+	cmdline_row = msg_row;	/* will put it back later */
+    }
+
+    if (xp->xp_numfiles == -1)
+	FreeWild(num_files, files_found);
+
+    return EXPAND_OK;
+}
+
+/*
+ * Private gettail for showmatches() (and win_redr_status_matches()):
+ * Find tail of file name path, but ignore trailing "/".
+ */
+    char_u *
+sm_gettail(s)
+    char_u	*s;
+{
+    char_u	*p;
+    char_u	*t = s;
+    int		had_sep = FALSE;
+
+    for (p = s; *p != NUL; )
+    {
+	if (vim_ispathsep(*p)
+#ifdef BACKSLASH_IN_FILENAME
+		&& !rem_backslash(p)
+#endif
+	   )
+	    had_sep = TRUE;
+	else if (had_sep)
+	{
+	    t = p;
+	    had_sep = FALSE;
+	}
+	mb_ptr_adv(p);
+    }
+    return t;
+}
+
+/*
+ * Return TRUE if we only need to show the tail of completion matches.
+ * When not completing file names or there is a wildcard in the path FALSE is
+ * returned.
+ */
+    static int
+expand_showtail(xp)
+    expand_T	*xp;
+{
+    char_u	*s;
+    char_u	*end;
+
+    /* When not completing file names a "/" may mean something different. */
+    if (xp->xp_context != EXPAND_FILES
+	    && xp->xp_context != EXPAND_SHELLCMD
+	    && xp->xp_context != EXPAND_DIRECTORIES)
+	return FALSE;
+
+    end = gettail(xp->xp_pattern);
+    if (end == xp->xp_pattern)		/* there is no path separator */
+	return FALSE;
+
+    for (s = xp->xp_pattern; s < end; s++)
+    {
+	/* Skip escaped wildcards.  Only when the backslash is not a path
+	 * separator, on DOS the '*' "path\*\file" must not be skipped. */
+	if (rem_backslash(s))
+	    ++s;
+	else if (vim_strchr((char_u *)"*?[", *s) != NULL)
+	    return FALSE;
+    }
+    return TRUE;
+}
+
+/*
+ * Prepare a string for expansion.
+ * When expanding file names: The string will be used with expand_wildcards().
+ * Copy the file name into allocated memory and add a '*' at the end.
+ * When expanding other names: The string will be used with regcomp().  Copy
+ * the name into allocated memory and prepend "^".
+ */
+    char_u *
+addstar(fname, len, context)
+    char_u	*fname;
+    int		len;
+    int		context;	/* EXPAND_FILES etc. */
+{
+    char_u	*retval;
+    int		i, j;
+    int		new_len;
+    char_u	*tail;
+
+    if (context != EXPAND_FILES
+	    && context != EXPAND_SHELLCMD
+	    && context != EXPAND_DIRECTORIES)
+    {
+	/*
+	 * Matching will be done internally (on something other than files).
+	 * So we convert the file-matching-type wildcards into our kind for
+	 * use with vim_regcomp().  First work out how long it will be:
+	 */
+
+	/* For help tags the translation is done in find_help_tags().
+	 * For a tag pattern starting with "/" no translation is needed. */
+	if (context == EXPAND_HELP
+		|| context == EXPAND_COLORS
+		|| context == EXPAND_COMPILER
+		|| (context == EXPAND_TAGS && fname[0] == '/'))
+	    retval = vim_strnsave(fname, len);
+	else
+	{
+	    new_len = len + 2;		/* +2 for '^' at start, NUL at end */
+	    for (i = 0; i < len; i++)
+	    {
+		if (fname[i] == '*' || fname[i] == '~')
+		    new_len++;		/* '*' needs to be replaced by ".*"
+					   '~' needs to be replaced by "\~" */
+
+		/* Buffer names are like file names.  "." should be literal */
+		if (context == EXPAND_BUFFERS && fname[i] == '.')
+		    new_len++;		/* "." becomes "\." */
+
+		/* Custom expansion takes care of special things, match
+		 * backslashes literally (perhaps also for other types?) */
+		if ((context == EXPAND_USER_DEFINED
+			  || context == EXPAND_USER_LIST) && fname[i] == '\\')
+		    new_len++;		/* '\' becomes "\\" */
+	    }
+	    retval = alloc(new_len);
+	    if (retval != NULL)
+	    {
+		retval[0] = '^';
+		j = 1;
+		for (i = 0; i < len; i++, j++)
+		{
+		    /* Skip backslash.  But why?  At least keep it for custom
+		     * expansion. */
+		    if (context != EXPAND_USER_DEFINED
+			    && context != EXPAND_USER_LIST
+			    && fname[i] == '\\'
+			    && ++i == len)
+			break;
+
+		    switch (fname[i])
+		    {
+			case '*':   retval[j++] = '.';
+				    break;
+			case '~':   retval[j++] = '\\';
+				    break;
+			case '?':   retval[j] = '.';
+				    continue;
+			case '.':   if (context == EXPAND_BUFFERS)
+					retval[j++] = '\\';
+				    break;
+			case '\\':  if (context == EXPAND_USER_DEFINED
+					    || context == EXPAND_USER_LIST)
+					retval[j++] = '\\';
+				    break;
+		    }
+		    retval[j] = fname[i];
+		}
+		retval[j] = NUL;
+	    }
+	}
+    }
+    else
+    {
+	retval = alloc(len + 4);
+	if (retval != NULL)
+	{
+	    vim_strncpy(retval, fname, len);
+
+	    /*
+	     * Don't add a star to *, ~, ~user, $var or `cmd`.
+	     * * would become **, which walks the whole tree.
+	     * ~ would be at the start of the file name, but not the tail.
+	     * $ could be anywhere in the tail.
+	     * ` could be anywhere in the file name.
+	     */
+	    tail = gettail(retval);
+	    if ((*retval != '~' || tail != retval)
+		    && (len == 0 || retval[len - 1] != '*')
+		    && vim_strchr(tail, '$') == NULL
+		    && vim_strchr(retval, '`') == NULL)
+		retval[len++] = '*';
+	    retval[len] = NUL;
+	}
+    }
+    return retval;
+}
+
+/*
+ * Must parse the command line so far to work out what context we are in.
+ * Completion can then be done based on that context.
+ * This routine sets the variables:
+ *  xp->xp_pattern	    The start of the pattern to be expanded within
+ *				the command line (ends at the cursor).
+ *  xp->xp_context	    The type of thing to expand.  Will be one of:
+ *
+ *  EXPAND_UNSUCCESSFUL	    Used sometimes when there is something illegal on
+ *			    the command line, like an unknown command.	Caller
+ *			    should beep.
+ *  EXPAND_NOTHING	    Unrecognised context for completion, use char like
+ *			    a normal char, rather than for completion.	eg
+ *			    :s/^I/
+ *  EXPAND_COMMANDS	    Cursor is still touching the command, so complete
+ *			    it.
+ *  EXPAND_BUFFERS	    Complete file names for :buf and :sbuf commands.
+ *  EXPAND_FILES	    After command with XFILE set, or after setting
+ *			    with P_EXPAND set.	eg :e ^I, :w>>^I
+ *  EXPAND_DIRECTORIES	    In some cases this is used instead of the latter
+ *			    when we know only directories are of interest.  eg
+ *			    :set dir=^I
+ *  EXPAND_SHELLCMD	    After ":!cmd", ":r !cmd"  or ":w !cmd".
+ *  EXPAND_SETTINGS	    Complete variable names.  eg :set d^I
+ *  EXPAND_BOOL_SETTINGS    Complete boolean variables only,  eg :set no^I
+ *  EXPAND_TAGS		    Complete tags from the files in p_tags.  eg :ta a^I
+ *  EXPAND_TAGS_LISTFILES   As above, but list filenames on ^D, after :tselect
+ *  EXPAND_HELP		    Complete tags from the file 'helpfile'/tags
+ *  EXPAND_EVENTS	    Complete event names
+ *  EXPAND_SYNTAX	    Complete :syntax command arguments
+ *  EXPAND_HIGHLIGHT	    Complete highlight (syntax) group names
+ *  EXPAND_AUGROUP	    Complete autocommand group names
+ *  EXPAND_USER_VARS	    Complete user defined variable names, eg :unlet a^I
+ *  EXPAND_MAPPINGS	    Complete mapping and abbreviation names,
+ *			      eg :unmap a^I , :cunab x^I
+ *  EXPAND_FUNCTIONS	    Complete internal or user defined function names,
+ *			      eg :call sub^I
+ *  EXPAND_USER_FUNC	    Complete user defined function names, eg :delf F^I
+ *  EXPAND_EXPRESSION	    Complete internal or user defined function/variable
+ *			    names in expressions, eg :while s^I
+ *  EXPAND_ENV_VARS	    Complete environment variable names
+ */
+    static void
+set_expand_context(xp)
+    expand_T	*xp;
+{
+    /* only expansion for ':', '>' and '=' command-lines */
+    if (ccline.cmdfirstc != ':'
+#ifdef FEAT_EVAL
+	    && ccline.cmdfirstc != '>' && ccline.cmdfirstc != '='
+	    && !ccline.input_fn
+#endif
+	    )
+    {
+	xp->xp_context = EXPAND_NOTHING;
+	return;
+    }
+    set_cmd_context(xp, ccline.cmdbuff, ccline.cmdlen, ccline.cmdpos);
+}
+
+    void
+set_cmd_context(xp, str, len, col)
+    expand_T	*xp;
+    char_u	*str;	    /* start of command line */
+    int		len;	    /* length of command line (excl. NUL) */
+    int		col;	    /* position of cursor */
+{
+    int		old_char = NUL;
+    char_u	*nextcomm;
+
+    /*
+     * Avoid a UMR warning from Purify, only save the character if it has been
+     * written before.
+     */
+    if (col < len)
+	old_char = str[col];
+    str[col] = NUL;
+    nextcomm = str;
+
+#ifdef FEAT_EVAL
+    if (ccline.cmdfirstc == '=')
+	/* pass CMD_SIZE because there is no real command */
+	set_context_for_expression(xp, str, CMD_SIZE);
+    else if (ccline.input_fn)
+    {
+	xp->xp_context = ccline.xp_context;
+	xp->xp_pattern = ccline.cmdbuff;
+	xp->xp_arg = ccline.xp_arg;
+    }
+    else
+#endif
+	while (nextcomm != NULL)
+	    nextcomm = set_one_cmd_context(xp, nextcomm);
+
+    str[col] = old_char;
+}
+
+/*
+ * Expand the command line "str" from context "xp".
+ * "xp" must have been set by set_cmd_context().
+ * xp->xp_pattern points into "str", to where the text that is to be expanded
+ * starts.
+ * Returns EXPAND_UNSUCCESSFUL when there is something illegal before the
+ * cursor.
+ * Returns EXPAND_NOTHING when there is nothing to expand, might insert the
+ * key that triggered expansion literally.
+ * Returns EXPAND_OK otherwise.
+ */
+    int
+expand_cmdline(xp, str, col, matchcount, matches)
+    expand_T	*xp;
+    char_u	*str;		/* start of command line */
+    int		col;		/* position of cursor */
+    int		*matchcount;	/* return: nr of matches */
+    char_u	***matches;	/* return: array of pointers to matches */
+{
+    char_u	*file_str = NULL;
+
+    if (xp->xp_context == EXPAND_UNSUCCESSFUL)
+    {
+	beep_flush();
+	return EXPAND_UNSUCCESSFUL;  /* Something illegal on command line */
+    }
+    if (xp->xp_context == EXPAND_NOTHING)
+    {
+	/* Caller can use the character as a normal char instead */
+	return EXPAND_NOTHING;
+    }
+
+    /* add star to file name, or convert to regexp if not exp. files. */
+    file_str = addstar(xp->xp_pattern,
+			   (int)(str + col - xp->xp_pattern), xp->xp_context);
+    if (file_str == NULL)
+	return EXPAND_UNSUCCESSFUL;
+
+    /* find all files that match the description */
+    if (ExpandFromContext(xp, file_str, matchcount, matches,
+					  WILD_ADD_SLASH|WILD_SILENT) == FAIL)
+    {
+	*matchcount = 0;
+	*matches = NULL;
+    }
+    vim_free(file_str);
+
+    return EXPAND_OK;
+}
+
+#ifdef FEAT_MULTI_LANG
+/*
+ * Cleanup matches for help tags: remove "@en" if "en" is the only language.
+ */
+static void	cleanup_help_tags __ARGS((int num_file, char_u **file));
+
+    static void
+cleanup_help_tags(num_file, file)
+    int		num_file;
+    char_u	**file;
+{
+    int		i, j;
+    int		len;
+
+    for (i = 0; i < num_file; ++i)
+    {
+	len = (int)STRLEN(file[i]) - 3;
+	if (len > 0 && STRCMP(file[i] + len, "@en") == 0)
+	{
+	    /* Sorting on priority means the same item in another language may
+	     * be anywhere.  Search all items for a match up to the "@en". */
+	    for (j = 0; j < num_file; ++j)
+		if (j != i
+			&& (int)STRLEN(file[j]) == len + 3
+			&& STRNCMP(file[i], file[j], len + 1) == 0)
+		    break;
+	    if (j == num_file)
+		file[i][len] = NUL;
+	}
+    }
+}
+#endif
+
+/*
+ * Do the expansion based on xp->xp_context and "pat".
+ */
+    static int
+ExpandFromContext(xp, pat, num_file, file, options)
+    expand_T	*xp;
+    char_u	*pat;
+    int		*num_file;
+    char_u	***file;
+    int		options;
+{
+#ifdef FEAT_CMDL_COMPL
+    regmatch_T	regmatch;
+#endif
+    int		ret;
+    int		flags;
+
+    flags = EW_DIR;	/* include directories */
+    if (options & WILD_LIST_NOTFOUND)
+	flags |= EW_NOTFOUND;
+    if (options & WILD_ADD_SLASH)
+	flags |= EW_ADDSLASH;
+    if (options & WILD_KEEP_ALL)
+	flags |= EW_KEEPALL;
+    if (options & WILD_SILENT)
+	flags |= EW_SILENT;
+
+    if (xp->xp_context == EXPAND_FILES || xp->xp_context == EXPAND_DIRECTORIES)
+    {
+	/*
+	 * Expand file or directory names.
+	 */
+	int	free_pat = FALSE;
+	int	i;
+
+	/* for ":set path=" and ":set tags=" halve backslashes for escaped
+	 * space */
+	if (xp->xp_backslash != XP_BS_NONE)
+	{
+	    free_pat = TRUE;
+	    pat = vim_strsave(pat);
+	    for (i = 0; pat[i]; ++i)
+		if (pat[i] == '\\')
+		{
+		    if (xp->xp_backslash == XP_BS_THREE
+			    && pat[i + 1] == '\\'
+			    && pat[i + 2] == '\\'
+			    && pat[i + 3] == ' ')
+			STRCPY(pat + i, pat + i + 3);
+		    if (xp->xp_backslash == XP_BS_ONE
+			    && pat[i + 1] == ' ')
+			STRCPY(pat + i, pat + i + 1);
+		}
+	}
+
+	if (xp->xp_context == EXPAND_FILES)
+	    flags |= EW_FILE;
+	else
+	    flags = (flags | EW_DIR) & ~EW_FILE;
+	ret = expand_wildcards(1, &pat, num_file, file, flags);
+	if (free_pat)
+	    vim_free(pat);
+	return ret;
+    }
+
+    *file = (char_u **)"";
+    *num_file = 0;
+    if (xp->xp_context == EXPAND_HELP)
+    {
+	if (find_help_tags(pat, num_file, file, FALSE) == OK)
+	{
+#ifdef FEAT_MULTI_LANG
+	    cleanup_help_tags(*num_file, *file);
+#endif
+	    return OK;
+	}
+	return FAIL;
+    }
+
+#ifndef FEAT_CMDL_COMPL
+    return FAIL;
+#else
+    if (xp->xp_context == EXPAND_SHELLCMD)
+	return expand_shellcmd(pat, num_file, file, flags);
+    if (xp->xp_context == EXPAND_OLD_SETTING)
+	return ExpandOldSetting(num_file, file);
+    if (xp->xp_context == EXPAND_BUFFERS)
+	return ExpandBufnames(pat, num_file, file, options);
+    if (xp->xp_context == EXPAND_TAGS
+	    || xp->xp_context == EXPAND_TAGS_LISTFILES)
+	return expand_tags(xp->xp_context == EXPAND_TAGS, pat, num_file, file);
+    if (xp->xp_context == EXPAND_COLORS)
+	return ExpandRTDir(pat, num_file, file, "colors");
+    if (xp->xp_context == EXPAND_COMPILER)
+	return ExpandRTDir(pat, num_file, file, "compiler");
+# if defined(FEAT_USR_CMDS) && defined(FEAT_EVAL)
+    if (xp->xp_context == EXPAND_USER_LIST)
+	return ExpandUserList(xp, num_file, file);
+# endif
+
+    regmatch.regprog = vim_regcomp(pat, p_magic ? RE_MAGIC : 0);
+    if (regmatch.regprog == NULL)
+	return FAIL;
+
+    /* set ignore-case according to p_ic, p_scs and pat */
+    regmatch.rm_ic = ignorecase(pat);
+
+    if (xp->xp_context == EXPAND_SETTINGS
+	    || xp->xp_context == EXPAND_BOOL_SETTINGS)
+	ret = ExpandSettings(xp, &regmatch, num_file, file);
+    else if (xp->xp_context == EXPAND_MAPPINGS)
+	ret = ExpandMappings(&regmatch, num_file, file);
+# if defined(FEAT_USR_CMDS) && defined(FEAT_EVAL)
+    else if (xp->xp_context == EXPAND_USER_DEFINED)
+	ret = ExpandUserDefined(xp, &regmatch, num_file, file);
+# endif
+    else
+    {
+	static struct expgen
+	{
+	    int		context;
+	    char_u	*((*func)__ARGS((expand_T *, int)));
+	    int		ic;
+	} tab[] =
+	{
+	    {EXPAND_COMMANDS, get_command_name, FALSE},
+#ifdef FEAT_USR_CMDS
+	    {EXPAND_USER_COMMANDS, get_user_commands, FALSE},
+	    {EXPAND_USER_CMD_FLAGS, get_user_cmd_flags, FALSE},
+	    {EXPAND_USER_NARGS, get_user_cmd_nargs, FALSE},
+	    {EXPAND_USER_COMPLETE, get_user_cmd_complete, FALSE},
+#endif
+#ifdef FEAT_EVAL
+	    {EXPAND_USER_VARS, get_user_var_name, FALSE},
+	    {EXPAND_FUNCTIONS, get_function_name, FALSE},
+	    {EXPAND_USER_FUNC, get_user_func_name, FALSE},
+	    {EXPAND_EXPRESSION, get_expr_name, FALSE},
+#endif
+#ifdef FEAT_MENU
+	    {EXPAND_MENUS, get_menu_name, FALSE},
+	    {EXPAND_MENUNAMES, get_menu_names, FALSE},
+#endif
+#ifdef FEAT_SYN_HL
+	    {EXPAND_SYNTAX, get_syntax_name, TRUE},
+#endif
+	    {EXPAND_HIGHLIGHT, get_highlight_name, TRUE},
+#ifdef FEAT_AUTOCMD
+	    {EXPAND_EVENTS, get_event_name, TRUE},
+	    {EXPAND_AUGROUP, get_augroup_name, TRUE},
+#endif
+#if (defined(HAVE_LOCALE_H) || defined(X_LOCALE)) \
+	&& (defined(FEAT_GETTEXT) || defined(FEAT_MBYTE))
+	    {EXPAND_LANGUAGE, get_lang_arg, TRUE},
+#endif
+	    {EXPAND_ENV_VARS, get_env_name, TRUE},
+	};
+	int	i;
+
+	/*
+	 * Find a context in the table and call the ExpandGeneric() with the
+	 * right function to do the expansion.
+	 */
+	ret = FAIL;
+	for (i = 0; i < sizeof(tab) / sizeof(struct expgen); ++i)
+	    if (xp->xp_context == tab[i].context)
+	    {
+		if (tab[i].ic)
+		    regmatch.rm_ic = TRUE;
+		ret = ExpandGeneric(xp, &regmatch, num_file, file, tab[i].func);
+		break;
+	    }
+    }
+
+    vim_free(regmatch.regprog);
+
+    return ret;
+#endif /* FEAT_CMDL_COMPL */
+}
+
+#if defined(FEAT_CMDL_COMPL) || defined(PROTO)
+/*
+ * Expand a list of names.
+ *
+ * Generic function for command line completion.  It calls a function to
+ * obtain strings, one by one.	The strings are matched against a regexp
+ * program.  Matching strings are copied into an array, which is returned.
+ *
+ * Returns OK when no problems encountered, FAIL for error (out of memory).
+ */
+    int
+ExpandGeneric(xp, regmatch, num_file, file, func)
+    expand_T	*xp;
+    regmatch_T	*regmatch;
+    int		*num_file;
+    char_u	***file;
+    char_u	*((*func)__ARGS((expand_T *, int)));
+					  /* returns a string from the list */
+{
+    int		i;
+    int		count = 0;
+    int		round;
+    char_u	*str;
+
+    /* do this loop twice:
+     * round == 0: count the number of matching names
+     * round == 1: copy the matching names into allocated memory
+     */
+    for (round = 0; round <= 1; ++round)
+    {
+	for (i = 0; ; ++i)
+	{
+	    str = (*func)(xp, i);
+	    if (str == NULL)	    /* end of list */
+		break;
+	    if (*str == NUL)	    /* skip empty strings */
+		continue;
+
+	    if (vim_regexec(regmatch, str, (colnr_T)0))
+	    {
+		if (round)
+		{
+		    str = vim_strsave_escaped(str, (char_u *)" \t\\.");
+		    (*file)[count] = str;
+#ifdef FEAT_MENU
+		    if (func == get_menu_names && str != NULL)
+		    {
+			/* test for separator added by get_menu_names() */
+			str += STRLEN(str) - 1;
+			if (*str == '\001')
+			    *str = '.';
+		    }
+#endif
+		}
+		++count;
+	    }
+	}
+	if (round == 0)
+	{
+	    if (count == 0)
+		return OK;
+	    *num_file = count;
+	    *file = (char_u **)alloc((unsigned)(count * sizeof(char_u *)));
+	    if (*file == NULL)
+	    {
+		*file = (char_u **)"";
+		return FAIL;
+	    }
+	    count = 0;
+	}
+    }
+
+    /* Sort the results.  Keep menu's in the specified order. */
+    if (xp->xp_context != EXPAND_MENUNAMES && xp->xp_context != EXPAND_MENUS)
+	sort_strings(*file, *num_file);
+
+    return OK;
+}
+
+/*
+ * Complete a shell command.
+ * Returns FAIL or OK;
+ */
+    static int
+expand_shellcmd(filepat, num_file, file, flagsarg)
+    char_u	*filepat;	/* pattern to match with command names */
+    int		*num_file;	/* return: number of matches */
+    char_u	***file;	/* return: array with matches */
+    int		flagsarg;	/* EW_ flags */
+{
+    char_u	*pat;
+    int		i;
+    char_u	*path;
+    int		mustfree = FALSE;
+    garray_T    ga;
+    char_u	*buf = alloc(MAXPATHL);
+    size_t	l;
+    char_u	*s, *e;
+    int		flags = flagsarg;
+    int		ret;
+
+    if (buf == NULL)
+	return FAIL;
+
+    /* for ":set path=" and ":set tags=" halve backslashes for escaped
+     * space */
+    pat = vim_strsave(filepat);
+    for (i = 0; pat[i]; ++i)
+	if (pat[i] == '\\' && pat[i + 1] == ' ')
+	    STRCPY(pat + i, pat + i + 1);
+
+    flags |= EW_FILE | EW_EXEC;
+
+    /* For an absolute name we don't use $PATH. */
+    if (mch_isFullName(pat))
+	path = (char_u *)" ";
+    else if ((pat[0] == '.' && (vim_ispathsep(pat[1])
+			    || (pat[1] == '.' && vim_ispathsep(pat[2])))))
+	path = (char_u *)".";
+    else
+	path = vim_getenv((char_u *)"PATH", &mustfree);
+
+    /*
+     * Go over all directories in $PATH.  Expand matches in that directory and
+     * collect them in "ga".
+     */
+    ga_init2(&ga, (int)sizeof(char *), 10);
+    for (s = path; *s != NUL; s = e)
+    {
+	if (*s == ' ')
+	    ++s;	/* Skip space used for absolute path name. */
+
+#if defined(MSDOS) || defined(MSWIN) || defined(OS2)
+	e = vim_strchr(s, ';');
+#else
+	e = vim_strchr(s, ':');
+#endif
+	if (e == NULL)
+	    e = s + STRLEN(s);
+
+	l = e - s;
+	if (l > MAXPATHL - 5)
+	    break;
+	vim_strncpy(buf, s, l);
+	add_pathsep(buf);
+	l = STRLEN(buf);
+	vim_strncpy(buf + l, pat, MAXPATHL - 1 - l);
+
+	/* Expand matches in one directory of $PATH. */
+	ret = expand_wildcards(1, &buf, num_file, file, flags);
+	if (ret == OK)
+	{
+	    if (ga_grow(&ga, *num_file) == FAIL)
+		FreeWild(*num_file, *file);
+	    else
+	    {
+		for (i = 0; i < *num_file; ++i)
+		{
+		    s = (*file)[i];
+		    if (STRLEN(s) > l)
+		    {
+			/* Remove the path again. */
+			mch_memmove(s, s + l, STRLEN(s + l) + 1);
+			((char_u **)ga.ga_data)[ga.ga_len++] = s;
+		    }
+		    else
+			vim_free(s);
+		}
+		vim_free(*file);
+	    }
+	}
+	if (*e != NUL)
+	    ++e;
+    }
+    *file = ga.ga_data;
+    *num_file = ga.ga_len;
+
+    vim_free(buf);
+    vim_free(pat);
+    if (mustfree)
+	vim_free(path);
+    return OK;
+}
+
+
+# if defined(FEAT_USR_CMDS) && defined(FEAT_EVAL)
+static void * call_user_expand_func __ARGS((void *(*user_expand_func) __ARGS((char_u *, int, char_u **, int)), expand_T	*xp, int *num_file, char_u ***file));
+
+/*
+ * call "user_expand_func()" to invoke a user defined VimL function and return
+ * the result (either a string or a List).
+ */
+    static void *
+call_user_expand_func(user_expand_func, xp, num_file, file)
+    void	*(*user_expand_func) __ARGS((char_u *, int, char_u **, int));
+    expand_T	*xp;
+    int		*num_file;
+    char_u	***file;
+{
+    char_u	keep;
+    char_u	num[50];
+    char_u	*args[3];
+    int		save_current_SID = current_SID;
+    void	*ret;
+    struct cmdline_info	    save_ccline;
+
+    if (xp->xp_arg == NULL || xp->xp_arg[0] == '\0')
+	return NULL;
+    *num_file = 0;
+    *file = NULL;
+
+    keep = ccline.cmdbuff[ccline.cmdlen];
+    ccline.cmdbuff[ccline.cmdlen] = 0;
+    sprintf((char *)num, "%d", ccline.cmdpos);
+    args[0] = xp->xp_pattern;
+    args[1] = ccline.cmdbuff;
+    args[2] = num;
+
+    /* Save the cmdline, we don't know what the function may do. */
+    save_ccline = ccline;
+    ccline.cmdbuff = NULL;
+    ccline.cmdprompt = NULL;
+    current_SID = xp->xp_scriptID;
+
+    ret = user_expand_func(xp->xp_arg, 3, args, FALSE);
+
+    ccline = save_ccline;
+    current_SID = save_current_SID;
+
+    ccline.cmdbuff[ccline.cmdlen] = keep;
+
+    return ret;
+}
+
+/*
+ * Expand names with a function defined by the user.
+ */
+    static int
+ExpandUserDefined(xp, regmatch, num_file, file)
+    expand_T	*xp;
+    regmatch_T	*regmatch;
+    int		*num_file;
+    char_u	***file;
+{
+    char_u	*retstr;
+    char_u	*s;
+    char_u	*e;
+    char_u      keep;
+    garray_T	ga;
+
+    retstr = call_user_expand_func(call_func_retstr, xp, num_file, file);
+    if (retstr == NULL)
+	return FAIL;
+
+    ga_init2(&ga, (int)sizeof(char *), 3);
+    for (s = retstr; *s != NUL; s = e)
+    {
+	e = vim_strchr(s, '\n');
+	if (e == NULL)
+	    e = s + STRLEN(s);
+	keep = *e;
+	*e = 0;
+
+	if (xp->xp_pattern[0] && vim_regexec(regmatch, s, (colnr_T)0) == 0)
+	{
+	    *e = keep;
+	    if (*e != NUL)
+		++e;
+	    continue;
+	}
+
+	if (ga_grow(&ga, 1) == FAIL)
+	    break;
+
+	((char_u **)ga.ga_data)[ga.ga_len] = vim_strnsave(s, (int)(e - s));
+	++ga.ga_len;
+
+	*e = keep;
+	if (*e != NUL)
+	    ++e;
+    }
+    vim_free(retstr);
+    *file = ga.ga_data;
+    *num_file = ga.ga_len;
+    return OK;
+}
+
+/*
+ * Expand names with a list returned by a function defined by the user.
+ */
+    static int
+ExpandUserList(xp, num_file, file)
+    expand_T	*xp;
+    int		*num_file;
+    char_u	***file;
+{
+    list_T      *retlist;
+    listitem_T	*li;
+    garray_T	ga;
+
+    retlist = call_user_expand_func(call_func_retlist, xp, num_file, file);
+    if (retlist == NULL)
+	return FAIL;
+
+    ga_init2(&ga, (int)sizeof(char *), 3);
+    /* Loop over the items in the list. */
+    for (li = retlist->lv_first; li != NULL; li = li->li_next)
+    {
+	if (li->li_tv.v_type != VAR_STRING)
+	    continue;  /* Skip non-string items */
+
+	if (ga_grow(&ga, 1) == FAIL)
+	    break;
+
+	((char_u **)ga.ga_data)[ga.ga_len] =
+	    vim_strsave(li->li_tv.vval.v_string);
+	++ga.ga_len;
+    }
+    list_unref(retlist);
+
+    *file = ga.ga_data;
+    *num_file = ga.ga_len;
+    return OK;
+}
+#endif
+
+/*
+ * Expand color scheme names: 'runtimepath'/colors/{pat}.vim
+ * or compiler names.
+ */
+    static int
+ExpandRTDir(pat, num_file, file, dirname)
+    char_u	*pat;
+    int		*num_file;
+    char_u	***file;
+    char	*dirname;	/* "colors" or "compiler" */
+{
+    char_u	*all;
+    char_u	*s;
+    char_u	*e;
+    garray_T	ga;
+
+    *num_file = 0;
+    *file = NULL;
+    s = alloc((unsigned)(STRLEN(pat) + STRLEN(dirname) + 7));
+    if (s == NULL)
+	return FAIL;
+    sprintf((char *)s, "%s/%s*.vim", dirname, pat);
+    all = globpath(p_rtp, s);
+    vim_free(s);
+    if (all == NULL)
+	return FAIL;
+
+    ga_init2(&ga, (int)sizeof(char *), 3);
+    for (s = all; *s != NUL; s = e)
+    {
+	e = vim_strchr(s, '\n');
+	if (e == NULL)
+	    e = s + STRLEN(s);
+	if (ga_grow(&ga, 1) == FAIL)
+	    break;
+	if (e - 4 > s && STRNICMP(e - 4, ".vim", 4) == 0)
+	{
+	    for (s = e - 4; s > all; mb_ptr_back(all, s))
+		if (*s == '\n' || vim_ispathsep(*s))
+		    break;
+	    ++s;
+	    ((char_u **)ga.ga_data)[ga.ga_len] =
+					    vim_strnsave(s, (int)(e - s - 4));
+	    ++ga.ga_len;
+	}
+	if (*e != NUL)
+	    ++e;
+    }
+    vim_free(all);
+    *file = ga.ga_data;
+    *num_file = ga.ga_len;
+    return OK;
+}
+
+#endif
+
+#if defined(FEAT_CMDL_COMPL) || defined(FEAT_EVAL) || defined(PROTO)
+/*
+ * Expand "file" for all comma-separated directories in "path".
+ * Returns an allocated string with all matches concatenated, separated by
+ * newlines.  Returns NULL for an error or no matches.
+ */
+    char_u *
+globpath(path, file)
+    char_u	*path;
+    char_u	*file;
+{
+    expand_T	xpc;
+    char_u	*buf;
+    garray_T	ga;
+    int		i;
+    int		len;
+    int		num_p;
+    char_u	**p;
+    char_u	*cur = NULL;
+
+    buf = alloc(MAXPATHL);
+    if (buf == NULL)
+	return NULL;
+
+    ExpandInit(&xpc);
+    xpc.xp_context = EXPAND_FILES;
+
+    ga_init2(&ga, 1, 100);
+
+    /* Loop over all entries in {path}. */
+    while (*path != NUL)
+    {
+	/* Copy one item of the path to buf[] and concatenate the file name. */
+	copy_option_part(&path, buf, MAXPATHL, ",");
+	if (STRLEN(buf) + STRLEN(file) + 2 < MAXPATHL)
+	{
+	    add_pathsep(buf);
+	    STRCAT(buf, file);
+	    if (ExpandFromContext(&xpc, buf, &num_p, &p, WILD_SILENT) != FAIL
+								 && num_p > 0)
+	    {
+		ExpandEscape(&xpc, buf, num_p, p, WILD_SILENT);
+		for (len = 0, i = 0; i < num_p; ++i)
+		    len += (int)STRLEN(p[i]) + 1;
+
+		/* Concatenate new results to previous ones. */
+		if (ga_grow(&ga, len) == OK)
+		{
+		    cur = (char_u *)ga.ga_data + ga.ga_len;
+		    for (i = 0; i < num_p; ++i)
+		    {
+			STRCPY(cur, p[i]);
+			cur += STRLEN(p[i]);
+			*cur++ = '\n';
+		    }
+		    ga.ga_len += len;
+		}
+		FreeWild(num_p, p);
+	    }
+	}
+    }
+    if (cur != NULL)
+	*--cur = 0; /* Replace trailing newline with NUL */
+
+    vim_free(buf);
+    return (char_u *)ga.ga_data;
+}
+
+#endif
+
+#if defined(FEAT_CMDHIST) || defined(PROTO)
+
+/*********************************
+ *  Command line history stuff	 *
+ *********************************/
+
+/*
+ * Translate a history character to the associated type number.
+ */
+    static int
+hist_char2type(c)
+    int	    c;
+{
+    if (c == ':')
+	return HIST_CMD;
+    if (c == '=')
+	return HIST_EXPR;
+    if (c == '@')
+	return HIST_INPUT;
+    if (c == '>')
+	return HIST_DEBUG;
+    return HIST_SEARCH;	    /* must be '?' or '/' */
+}
+
+/*
+ * Table of history names.
+ * These names are used in :history and various hist...() functions.
+ * It is sufficient to give the significant prefix of a history name.
+ */
+
+static char *(history_names[]) =
+{
+    "cmd",
+    "search",
+    "expr",
+    "input",
+    "debug",
+    NULL
+};
+
+/*
+ * init_history() - Initialize the command line history.
+ * Also used to re-allocate the history when the size changes.
+ */
+    void
+init_history()
+{
+    int		newlen;	    /* new length of history table */
+    histentry_T	*temp;
+    int		i;
+    int		j;
+    int		type;
+
+    /*
+     * If size of history table changed, reallocate it
+     */
+    newlen = (int)p_hi;
+    if (newlen != hislen)			/* history length changed */
+    {
+	for (type = 0; type < HIST_COUNT; ++type)   /* adjust the tables */
+	{
+	    if (newlen)
+	    {
+		temp = (histentry_T *)lalloc(
+				(long_u)(newlen * sizeof(histentry_T)), TRUE);
+		if (temp == NULL)   /* out of memory! */
+		{
+		    if (type == 0)  /* first one: just keep the old length */
+		    {
+			newlen = hislen;
+			break;
+		    }
+		    /* Already changed one table, now we can only have zero
+		     * length for all tables. */
+		    newlen = 0;
+		    type = -1;
+		    continue;
+		}
+	    }
+	    else
+		temp = NULL;
+	    if (newlen == 0 || temp != NULL)
+	    {
+		if (hisidx[type] < 0)		/* there are no entries yet */
+		{
+		    for (i = 0; i < newlen; ++i)
+		    {
+			temp[i].hisnum = 0;
+			temp[i].hisstr = NULL;
+		    }
+		}
+		else if (newlen > hislen)	/* array becomes bigger */
+		{
+		    for (i = 0; i <= hisidx[type]; ++i)
+			temp[i] = history[type][i];
+		    j = i;
+		    for ( ; i <= newlen - (hislen - hisidx[type]); ++i)
+		    {
+			temp[i].hisnum = 0;
+			temp[i].hisstr = NULL;
+		    }
+		    for ( ; j < hislen; ++i, ++j)
+			temp[i] = history[type][j];
+		}
+		else				/* array becomes smaller or 0 */
+		{
+		    j = hisidx[type];
+		    for (i = newlen - 1; ; --i)
+		    {
+			if (i >= 0)		/* copy newest entries */
+			    temp[i] = history[type][j];
+			else			/* remove older entries */
+			    vim_free(history[type][j].hisstr);
+			if (--j < 0)
+			    j = hislen - 1;
+			if (j == hisidx[type])
+			    break;
+		    }
+		    hisidx[type] = newlen - 1;
+		}
+		vim_free(history[type]);
+		history[type] = temp;
+	    }
+	}
+	hislen = newlen;
+    }
+}
+
+/*
+ * Check if command line 'str' is already in history.
+ * If 'move_to_front' is TRUE, matching entry is moved to end of history.
+ */
+    static int
+in_history(type, str, move_to_front)
+    int	    type;
+    char_u  *str;
+    int	    move_to_front;	/* Move the entry to the front if it exists */
+{
+    int	    i;
+    int	    last_i = -1;
+
+    if (hisidx[type] < 0)
+	return FALSE;
+    i = hisidx[type];
+    do
+    {
+	if (history[type][i].hisstr == NULL)
+	    return FALSE;
+	if (STRCMP(str, history[type][i].hisstr) == 0)
+	{
+	    if (!move_to_front)
+		return TRUE;
+	    last_i = i;
+	    break;
+	}
+	if (--i < 0)
+	    i = hislen - 1;
+    } while (i != hisidx[type]);
+
+    if (last_i >= 0)
+    {
+	str = history[type][i].hisstr;
+	while (i != hisidx[type])
+	{
+	    if (++i >= hislen)
+		i = 0;
+	    history[type][last_i] = history[type][i];
+	    last_i = i;
+	}
+	history[type][i].hisstr = str;
+	history[type][i].hisnum = ++hisnum[type];
+	return TRUE;
+    }
+    return FALSE;
+}
+
+/*
+ * Convert history name (from table above) to its HIST_ equivalent.
+ * When "name" is empty, return "cmd" history.
+ * Returns -1 for unknown history name.
+ */
+    int
+get_histtype(name)
+    char_u	*name;
+{
+    int		i;
+    int		len = (int)STRLEN(name);
+
+    /* No argument: use current history. */
+    if (len == 0)
+	return hist_char2type(ccline.cmdfirstc);
+
+    for (i = 0; history_names[i] != NULL; ++i)
+	if (STRNICMP(name, history_names[i], len) == 0)
+	    return i;
+
+    if (vim_strchr((char_u *)":=@>?/", name[0]) != NULL && name[1] == NUL)
+	return hist_char2type(name[0]);
+
+    return -1;
+}
+
+static int	last_maptick = -1;	/* last seen maptick */
+
+/*
+ * Add the given string to the given history.  If the string is already in the
+ * history then it is moved to the front.  "histype" may be one of he HIST_
+ * values.
+ */
+    void
+add_to_history(histype, new_entry, in_map, sep)
+    int		histype;
+    char_u	*new_entry;
+    int		in_map;		/* consider maptick when inside a mapping */
+    int		sep;		/* separator character used (search hist) */
+{
+    histentry_T	*hisptr;
+    int		len;
+
+    if (hislen == 0)		/* no history */
+	return;
+
+    /*
+     * Searches inside the same mapping overwrite each other, so that only
+     * the last line is kept.  Be careful not to remove a line that was moved
+     * down, only lines that were added.
+     */
+    if (histype == HIST_SEARCH && in_map)
+    {
+	if (maptick == last_maptick)
+	{
+	    /* Current line is from the same mapping, remove it */
+	    hisptr = &history[HIST_SEARCH][hisidx[HIST_SEARCH]];
+	    vim_free(hisptr->hisstr);
+	    hisptr->hisstr = NULL;
+	    hisptr->hisnum = 0;
+	    --hisnum[histype];
+	    if (--hisidx[HIST_SEARCH] < 0)
+		hisidx[HIST_SEARCH] = hislen - 1;
+	}
+	last_maptick = -1;
+    }
+    if (!in_history(histype, new_entry, TRUE))
+    {
+	if (++hisidx[histype] == hislen)
+	    hisidx[histype] = 0;
+	hisptr = &history[histype][hisidx[histype]];
+	vim_free(hisptr->hisstr);
+
+	/* Store the separator after the NUL of the string. */
+	len = (int)STRLEN(new_entry);
+	hisptr->hisstr = vim_strnsave(new_entry, len + 2);
+	if (hisptr->hisstr != NULL)
+	    hisptr->hisstr[len + 1] = sep;
+
+	hisptr->hisnum = ++hisnum[histype];
+	if (histype == HIST_SEARCH && in_map)
+	    last_maptick = maptick;
+    }
+}
+
+#if defined(FEAT_EVAL) || defined(PROTO)
+
+/*
+ * Get identifier of newest history entry.
+ * "histype" may be one of the HIST_ values.
+ */
+    int
+get_history_idx(histype)
+    int	    histype;
+{
+    if (hislen == 0 || histype < 0 || histype >= HIST_COUNT
+		    || hisidx[histype] < 0)
+	return -1;
+
+    return history[histype][hisidx[histype]].hisnum;
+}
+
+static struct cmdline_info *get_ccline_ptr __ARGS((void));
+
+/*
+ * Get pointer to the command line info to use. cmdline_paste() may clear
+ * ccline and put the previous value in prev_ccline.
+ */
+    static struct cmdline_info *
+get_ccline_ptr()
+{
+    if ((State & CMDLINE) == 0)
+	return NULL;
+    if (ccline.cmdbuff != NULL)
+	return &ccline;
+    if (prev_ccline_used && prev_ccline.cmdbuff != NULL)
+	return &prev_ccline;
+    return NULL;
+}
+
+/*
+ * Get the current command line in allocated memory.
+ * Only works when the command line is being edited.
+ * Returns NULL when something is wrong.
+ */
+    char_u *
+get_cmdline_str()
+{
+    struct cmdline_info *p = get_ccline_ptr();
+
+    if (p == NULL)
+	return NULL;
+    return vim_strnsave(p->cmdbuff, p->cmdlen);
+}
+
+/*
+ * Get the current command line position, counted in bytes.
+ * Zero is the first position.
+ * Only works when the command line is being edited.
+ * Returns -1 when something is wrong.
+ */
+    int
+get_cmdline_pos()
+{
+    struct cmdline_info *p = get_ccline_ptr();
+
+    if (p == NULL)
+	return -1;
+    return p->cmdpos;
+}
+
+/*
+ * Set the command line byte position to "pos".  Zero is the first position.
+ * Only works when the command line is being edited.
+ * Returns 1 when failed, 0 when OK.
+ */
+    int
+set_cmdline_pos(pos)
+    int		pos;
+{
+    struct cmdline_info *p = get_ccline_ptr();
+
+    if (p == NULL)
+	return 1;
+
+    /* The position is not set directly but after CTRL-\ e or CTRL-R = has
+     * changed the command line. */
+    if (pos < 0)
+	new_cmdpos = 0;
+    else
+	new_cmdpos = pos;
+    return 0;
+}
+
+/*
+ * Get the current command-line type.
+ * Returns ':' or '/' or '?' or '@' or '>' or '-'
+ * Only works when the command line is being edited.
+ * Returns NUL when something is wrong.
+ */
+    int
+get_cmdline_type()
+{
+    struct cmdline_info *p = get_ccline_ptr();
+
+    if (p == NULL)
+	return NUL;
+    if (p->cmdfirstc == NUL)
+	return (p->input_fn) ? '@' : '-';
+    return p->cmdfirstc;
+}
+
+/*
+ * Calculate history index from a number:
+ *   num > 0: seen as identifying number of a history entry
+ *   num < 0: relative position in history wrt newest entry
+ * "histype" may be one of the HIST_ values.
+ */
+    static int
+calc_hist_idx(histype, num)
+    int		histype;
+    int		num;
+{
+    int		i;
+    histentry_T	*hist;
+    int		wrapped = FALSE;
+
+    if (hislen == 0 || histype < 0 || histype >= HIST_COUNT
+		    || (i = hisidx[histype]) < 0 || num == 0)
+	return -1;
+
+    hist = history[histype];
+    if (num > 0)
+    {
+	while (hist[i].hisnum > num)
+	    if (--i < 0)
+	    {
+		if (wrapped)
+		    break;
+		i += hislen;
+		wrapped = TRUE;
+	    }
+	if (hist[i].hisnum == num && hist[i].hisstr != NULL)
+	    return i;
+    }
+    else if (-num <= hislen)
+    {
+	i += num + 1;
+	if (i < 0)
+	    i += hislen;
+	if (hist[i].hisstr != NULL)
+	    return i;
+    }
+    return -1;
+}
+
+/*
+ * Get a history entry by its index.
+ * "histype" may be one of the HIST_ values.
+ */
+    char_u *
+get_history_entry(histype, idx)
+    int	    histype;
+    int	    idx;
+{
+    idx = calc_hist_idx(histype, idx);
+    if (idx >= 0)
+	return history[histype][idx].hisstr;
+    else
+	return (char_u *)"";
+}
+
+/*
+ * Clear all entries of a history.
+ * "histype" may be one of the HIST_ values.
+ */
+    int
+clr_history(histype)
+    int		histype;
+{
+    int		i;
+    histentry_T	*hisptr;
+
+    if (hislen != 0 && histype >= 0 && histype < HIST_COUNT)
+    {
+	hisptr = history[histype];
+	for (i = hislen; i--;)
+	{
+	    vim_free(hisptr->hisstr);
+	    hisptr->hisnum = 0;
+	    hisptr++->hisstr = NULL;
+	}
+	hisidx[histype] = -1;	/* mark history as cleared */
+	hisnum[histype] = 0;	/* reset identifier counter */
+	return OK;
+    }
+    return FAIL;
+}
+
+/*
+ * Remove all entries matching {str} from a history.
+ * "histype" may be one of the HIST_ values.
+ */
+    int
+del_history_entry(histype, str)
+    int		histype;
+    char_u	*str;
+{
+    regmatch_T	regmatch;
+    histentry_T	*hisptr;
+    int		idx;
+    int		i;
+    int		last;
+    int		found = FALSE;
+
+    regmatch.regprog = NULL;
+    regmatch.rm_ic = FALSE;	/* always match case */
+    if (hislen != 0
+	    && histype >= 0
+	    && histype < HIST_COUNT
+	    && *str != NUL
+	    && (idx = hisidx[histype]) >= 0
+	    && (regmatch.regprog = vim_regcomp(str, RE_MAGIC + RE_STRING))
+								      != NULL)
+    {
+	i = last = idx;
+	do
+	{
+	    hisptr = &history[histype][i];
+	    if (hisptr->hisstr == NULL)
+		break;
+	    if (vim_regexec(&regmatch, hisptr->hisstr, (colnr_T)0))
+	    {
+		found = TRUE;
+		vim_free(hisptr->hisstr);
+		hisptr->hisstr = NULL;
+		hisptr->hisnum = 0;
+	    }
+	    else
+	    {
+		if (i != last)
+		{
+		    history[histype][last] = *hisptr;
+		    hisptr->hisstr = NULL;
+		    hisptr->hisnum = 0;
+		}
+		if (--last < 0)
+		    last += hislen;
+	    }
+	    if (--i < 0)
+		i += hislen;
+	} while (i != idx);
+	if (history[histype][idx].hisstr == NULL)
+	    hisidx[histype] = -1;
+    }
+    vim_free(regmatch.regprog);
+    return found;
+}
+
+/*
+ * Remove an indexed entry from a history.
+ * "histype" may be one of the HIST_ values.
+ */
+    int
+del_history_idx(histype, idx)
+    int	    histype;
+    int	    idx;
+{
+    int	    i, j;
+
+    i = calc_hist_idx(histype, idx);
+    if (i < 0)
+	return FALSE;
+    idx = hisidx[histype];
+    vim_free(history[histype][i].hisstr);
+
+    /* When deleting the last added search string in a mapping, reset
+     * last_maptick, so that the last added search string isn't deleted again.
+     */
+    if (histype == HIST_SEARCH && maptick == last_maptick && i == idx)
+	last_maptick = -1;
+
+    while (i != idx)
+    {
+	j = (i + 1) % hislen;
+	history[histype][i] = history[histype][j];
+	i = j;
+    }
+    history[histype][i].hisstr = NULL;
+    history[histype][i].hisnum = 0;
+    if (--i < 0)
+	i += hislen;
+    hisidx[histype] = i;
+    return TRUE;
+}
+
+#endif /* FEAT_EVAL */
+
+#if defined(FEAT_CRYPT) || defined(PROTO)
+/*
+ * Very specific function to remove the value in ":set key=val" from the
+ * history.
+ */
+    void
+remove_key_from_history()
+{
+    char_u	*p;
+    int		i;
+
+    i = hisidx[HIST_CMD];
+    if (i < 0)
+	return;
+    p = history[HIST_CMD][i].hisstr;
+    if (p != NULL)
+	for ( ; *p; ++p)
+	    if (STRNCMP(p, "key", 3) == 0 && !isalpha(p[3]))
+	    {
+		p = vim_strchr(p + 3, '=');
+		if (p == NULL)
+		    break;
+		++p;
+		for (i = 0; p[i] && !vim_iswhite(p[i]); ++i)
+		    if (p[i] == '\\' && p[i + 1])
+			++i;
+		mch_memmove(p, p + i, STRLEN(p + i) + 1);
+		--p;
+	    }
+}
+#endif
+
+#endif /* FEAT_CMDHIST */
+
+#if defined(FEAT_QUICKFIX) || defined(FEAT_CMDHIST) || defined(PROTO)
+/*
+ * Get indices "num1,num2" that specify a range within a list (not a range of
+ * text lines in a buffer!) from a string.  Used for ":history" and ":clist".
+ * Returns OK if parsed successfully, otherwise FAIL.
+ */
+    int
+get_list_range(str, num1, num2)
+    char_u	**str;
+    int		*num1;
+    int		*num2;
+{
+    int		len;
+    int		first = FALSE;
+    long	num;
+
+    *str = skipwhite(*str);
+    if (**str == '-' || vim_isdigit(**str))  /* parse "from" part of range */
+    {
+	vim_str2nr(*str, NULL, &len, FALSE, FALSE, &num, NULL);
+	*str += len;
+	*num1 = (int)num;
+	first = TRUE;
+    }
+    *str = skipwhite(*str);
+    if (**str == ',')			/* parse "to" part of range */
+    {
+	*str = skipwhite(*str + 1);
+	vim_str2nr(*str, NULL, &len, FALSE, FALSE, &num, NULL);
+	if (len > 0)
+	{
+	    *num2 = (int)num;
+	    *str = skipwhite(*str + len);
+	}
+	else if (!first)		/* no number given at all */
+	    return FAIL;
+    }
+    else if (first)			/* only one number given */
+	*num2 = *num1;
+    return OK;
+}
+#endif
+
+#if defined(FEAT_CMDHIST) || defined(PROTO)
+/*
+ * :history command - print a history
+ */
+    void
+ex_history(eap)
+    exarg_T	*eap;
+{
+    histentry_T	*hist;
+    int		histype1 = HIST_CMD;
+    int		histype2 = HIST_CMD;
+    int		hisidx1 = 1;
+    int		hisidx2 = -1;
+    int		idx;
+    int		i, j, k;
+    char_u	*end;
+    char_u	*arg = eap->arg;
+
+    if (hislen == 0)
+    {
+	MSG(_("'history' option is zero"));
+	return;
+    }
+
+    if (!(VIM_ISDIGIT(*arg) || *arg == '-' || *arg == ','))
+    {
+	end = arg;
+	while (ASCII_ISALPHA(*end)
+		|| vim_strchr((char_u *)":=@>/?", *end) != NULL)
+	    end++;
+	i = *end;
+	*end = NUL;
+	histype1 = get_histtype(arg);
+	if (histype1 == -1)
+	{
+	    if (STRICMP(arg, "all") == 0)
+	    {
+		histype1 = 0;
+		histype2 = HIST_COUNT-1;
+	    }
+	    else
+	    {
+		*end = i;
+		EMSG(_(e_trailing));
+		return;
+	    }
+	}
+	else
+	    histype2 = histype1;
+	*end = i;
+    }
+    else
+	end = arg;
+    if (!get_list_range(&end, &hisidx1, &hisidx2) || *end != NUL)
+    {
+	EMSG(_(e_trailing));
+	return;
+    }
+
+    for (; !got_int && histype1 <= histype2; ++histype1)
+    {
+	STRCPY(IObuff, "\n      #  ");
+	STRCAT(STRCAT(IObuff, history_names[histype1]), " history");
+	MSG_PUTS_TITLE(IObuff);
+	idx = hisidx[histype1];
+	hist = history[histype1];
+	j = hisidx1;
+	k = hisidx2;
+	if (j < 0)
+	    j = (-j > hislen) ? 0 : hist[(hislen+j+idx+1) % hislen].hisnum;
+	if (k < 0)
+	    k = (-k > hislen) ? 0 : hist[(hislen+k+idx+1) % hislen].hisnum;
+	if (idx >= 0 && j <= k)
+	    for (i = idx + 1; !got_int; ++i)
+	    {
+		if (i == hislen)
+		    i = 0;
+		if (hist[i].hisstr != NULL
+			&& hist[i].hisnum >= j && hist[i].hisnum <= k)
+		{
+		    msg_putchar('\n');
+		    sprintf((char *)IObuff, "%c%6d  ", i == idx ? '>' : ' ',
+							      hist[i].hisnum);
+		    if (vim_strsize(hist[i].hisstr) > (int)Columns - 10)
+			trunc_string(hist[i].hisstr, IObuff + STRLEN(IObuff),
+							   (int)Columns - 10);
+		    else
+			STRCAT(IObuff, hist[i].hisstr);
+		    msg_outtrans(IObuff);
+		    out_flush();
+		}
+		if (i == idx)
+		    break;
+	    }
+    }
+}
+#endif
+
+#if (defined(FEAT_VIMINFO) && defined(FEAT_CMDHIST)) || defined(PROTO)
+static char_u **viminfo_history[HIST_COUNT] = {NULL, NULL, NULL, NULL};
+static int	viminfo_hisidx[HIST_COUNT] = {0, 0, 0, 0};
+static int	viminfo_hislen[HIST_COUNT] = {0, 0, 0, 0};
+static int	viminfo_add_at_front = FALSE;
+
+static int	hist_type2char __ARGS((int type, int use_question));
+
+/*
+ * Translate a history type number to the associated character.
+ */
+    static int
+hist_type2char(type, use_question)
+    int	    type;
+    int	    use_question;	    /* use '?' instead of '/' */
+{
+    if (type == HIST_CMD)
+	return ':';
+    if (type == HIST_SEARCH)
+    {
+	if (use_question)
+	    return '?';
+	else
+	    return '/';
+    }
+    if (type == HIST_EXPR)
+	return '=';
+    return '@';
+}
+
+/*
+ * Prepare for reading the history from the viminfo file.
+ * This allocates history arrays to store the read history lines.
+ */
+    void
+prepare_viminfo_history(asklen)
+    int	    asklen;
+{
+    int	    i;
+    int	    num;
+    int	    type;
+    int	    len;
+
+    init_history();
+    viminfo_add_at_front = (asklen != 0);
+    if (asklen > hislen)
+	asklen = hislen;
+
+    for (type = 0; type < HIST_COUNT; ++type)
+    {
+	/*
+	 * Count the number of empty spaces in the history list.  If there are
+	 * more spaces available than we request, then fill them up.
+	 */
+	for (i = 0, num = 0; i < hislen; i++)
+	    if (history[type][i].hisstr == NULL)
+		num++;
+	len = asklen;
+	if (num > len)
+	    len = num;
+	if (len <= 0)
+	    viminfo_history[type] = NULL;
+	else
+	    viminfo_history[type] =
+		   (char_u **)lalloc((long_u)(len * sizeof(char_u *)), FALSE);
+	if (viminfo_history[type] == NULL)
+	    len = 0;
+	viminfo_hislen[type] = len;
+	viminfo_hisidx[type] = 0;
+    }
+}
+
+/*
+ * Accept a line from the viminfo, store it in the history array when it's
+ * new.
+ */
+    int
+read_viminfo_history(virp)
+    vir_T	*virp;
+{
+    int		type;
+    long_u	len;
+    char_u	*val;
+    char_u	*p;
+
+    type = hist_char2type(virp->vir_line[0]);
+    if (viminfo_hisidx[type] < viminfo_hislen[type])
+    {
+	val = viminfo_readstring(virp, 1, TRUE);
+	if (val != NULL && *val != NUL)
+	{
+	    if (!in_history(type, val + (type == HIST_SEARCH),
+							viminfo_add_at_front))
+	    {
+		/* Need to re-allocate to append the separator byte. */
+		len = STRLEN(val);
+		p = lalloc(len + 2, TRUE);
+		if (p != NULL)
+		{
+		    if (type == HIST_SEARCH)
+		    {
+			/* Search entry: Move the separator from the first
+			 * column to after the NUL. */
+			mch_memmove(p, val + 1, (size_t)len);
+			p[len] = (*val == ' ' ? NUL : *val);
+		    }
+		    else
+		    {
+			/* Not a search entry: No separator in the viminfo
+			 * file, add a NUL separator. */
+			mch_memmove(p, val, (size_t)len + 1);
+			p[len + 1] = NUL;
+		    }
+		    viminfo_history[type][viminfo_hisidx[type]++] = p;
+		}
+	    }
+	}
+	vim_free(val);
+    }
+    return viminfo_readline(virp);
+}
+
+    void
+finish_viminfo_history()
+{
+    int idx;
+    int i;
+    int	type;
+
+    for (type = 0; type < HIST_COUNT; ++type)
+    {
+	if (history[type] == NULL)
+	    return;
+	idx = hisidx[type] + viminfo_hisidx[type];
+	if (idx >= hislen)
+	    idx -= hislen;
+	else if (idx < 0)
+	    idx = hislen - 1;
+	if (viminfo_add_at_front)
+	    hisidx[type] = idx;
+	else
+	{
+	    if (hisidx[type] == -1)
+		hisidx[type] = hislen - 1;
+	    do
+	    {
+		if (history[type][idx].hisstr != NULL)
+		    break;
+		if (++idx == hislen)
+		    idx = 0;
+	    } while (idx != hisidx[type]);
+	    if (idx != hisidx[type] && --idx < 0)
+		idx = hislen - 1;
+	}
+	for (i = 0; i < viminfo_hisidx[type]; i++)
+	{
+	    vim_free(history[type][idx].hisstr);
+	    history[type][idx].hisstr = viminfo_history[type][i];
+	    if (--idx < 0)
+		idx = hislen - 1;
+	}
+	idx += 1;
+	idx %= hislen;
+	for (i = 0; i < viminfo_hisidx[type]; i++)
+	{
+	    history[type][idx++].hisnum = ++hisnum[type];
+	    idx %= hislen;
+	}
+	vim_free(viminfo_history[type]);
+	viminfo_history[type] = NULL;
+    }
+}
+
+    void
+write_viminfo_history(fp)
+    FILE    *fp;
+{
+    int	    i;
+    int	    type;
+    int	    num_saved;
+    char_u  *p;
+    int	    c;
+
+    init_history();
+    if (hislen == 0)
+	return;
+    for (type = 0; type < HIST_COUNT; ++type)
+    {
+	num_saved = get_viminfo_parameter(hist_type2char(type, FALSE));
+	if (num_saved == 0)
+	    continue;
+	if (num_saved < 0)  /* Use default */
+	    num_saved = hislen;
+	fprintf(fp, _("\n# %s History (newest to oldest):\n"),
+			    type == HIST_CMD ? _("Command Line") :
+			    type == HIST_SEARCH ? _("Search String") :
+			    type == HIST_EXPR ?  _("Expression") :
+					_("Input Line"));
+	if (num_saved > hislen)
+	    num_saved = hislen;
+	i = hisidx[type];
+	if (i >= 0)
+	    while (num_saved--)
+	    {
+		p = history[type][i].hisstr;
+		if (p != NULL)
+		{
+		    fputc(hist_type2char(type, TRUE), fp);
+		    /* For the search history: put the separator in the second
+		     * column; use a space if there isn't one. */
+		    if (type == HIST_SEARCH)
+		    {
+			c = p[STRLEN(p) + 1];
+			putc(c == NUL ? ' ' : c, fp);
+		    }
+		    viminfo_writestring(fp, p);
+		}
+		if (--i < 0)
+		    i = hislen - 1;
+	    }
+    }
+}
+#endif /* FEAT_VIMINFO */
+
+#if defined(FEAT_FKMAP) || defined(PROTO)
+/*
+ * Write a character at the current cursor+offset position.
+ * It is directly written into the command buffer block.
+ */
+    void
+cmd_pchar(c, offset)
+    int	    c, offset;
+{
+    if (ccline.cmdpos + offset >= ccline.cmdlen || ccline.cmdpos + offset < 0)
+    {
+	EMSG(_("E198: cmd_pchar beyond the command length"));
+	return;
+    }
+    ccline.cmdbuff[ccline.cmdpos + offset] = (char_u)c;
+    ccline.cmdbuff[ccline.cmdlen] = NUL;
+}
+
+    int
+cmd_gchar(offset)
+    int	    offset;
+{
+    if (ccline.cmdpos + offset >= ccline.cmdlen || ccline.cmdpos + offset < 0)
+    {
+	/*  EMSG(_("cmd_gchar beyond the command length")); */
+	return NUL;
+    }
+    return (int)ccline.cmdbuff[ccline.cmdpos + offset];
+}
+#endif
+
+#if defined(FEAT_CMDWIN) || defined(PROTO)
+/*
+ * Open a window on the current command line and history.  Allow editing in
+ * the window.  Returns when the window is closed.
+ * Returns:
+ *	CR	 if the command is to be executed
+ *	Ctrl_C	 if it is to be abandoned
+ *	K_IGNORE if editing continues
+ */
+    static int
+ex_window()
+{
+    struct cmdline_info	save_ccline;
+    buf_T		*old_curbuf = curbuf;
+    win_T		*old_curwin = curwin;
+    buf_T		*bp;
+    win_T		*wp;
+    int			i;
+    linenr_T		lnum;
+    int			histtype;
+    garray_T		winsizes;
+    char_u		typestr0[2];
+    int			save_restart_edit = restart_edit;
+    int			save_State = State;
+    int			save_exmode = exmode_active;
+#ifdef FEAT_RIGHTLEFT
+    int			save_cmdmsg_rl = cmdmsg_rl;
+#endif
+
+    /* Can't do this recursively.  Can't do it when typing a password. */
+    if (cmdwin_type != 0
+# if defined(FEAT_CRYPT) || defined(FEAT_EVAL)
+	    || cmdline_star > 0
+# endif
+	    )
+    {
+	beep_flush();
+	return K_IGNORE;
+    }
+
+    /* Save current window sizes. */
+    win_size_save(&winsizes);
+
+# ifdef FEAT_AUTOCMD
+    /* Don't execute autocommands while creating the window. */
+    ++autocmd_block;
+# endif
+    /* don't use a new tab page */
+    cmdmod.tab = 0;
+
+    /* Create a window for the command-line buffer. */
+    if (win_split((int)p_cwh, WSP_BOT) == FAIL)
+    {
+	beep_flush();
+	return K_IGNORE;
+    }
+    cmdwin_type = ccline.cmdfirstc;
+    if (cmdwin_type == NUL)
+	cmdwin_type = '-';
+
+    /* Create the command-line buffer empty. */
+    (void)do_ecmd(0, NULL, NULL, NULL, ECMD_ONE, ECMD_HIDE);
+    (void)setfname(curbuf, (char_u *)"command-line", NULL, TRUE);
+    set_option_value((char_u *)"bt", 0L, (char_u *)"nofile", OPT_LOCAL);
+    set_option_value((char_u *)"swf", 0L, NULL, OPT_LOCAL);
+    curbuf->b_p_ma = TRUE;
+# ifdef FEAT_RIGHTLEFT
+    curwin->w_p_rl = cmdmsg_rl;
+    cmdmsg_rl = FALSE;
+# endif
+# ifdef FEAT_SCROLLBIND
+    curwin->w_p_scb = FALSE;
+# endif
+
+# ifdef FEAT_AUTOCMD
+    /* Do execute autocommands for setting the filetype (load syntax). */
+    --autocmd_block;
+# endif
+
+    /* Showing the prompt may have set need_wait_return, reset it. */
+    need_wait_return = FALSE;
+
+    histtype = hist_char2type(ccline.cmdfirstc);
+    if (histtype == HIST_CMD || histtype == HIST_DEBUG)
+    {
+	if (p_wc == TAB)
+	{
+	    add_map((char_u *)"<buffer> <Tab> <C-X><C-V>", INSERT);
+	    add_map((char_u *)"<buffer> <Tab> a<C-X><C-V>", NORMAL);
+	}
+	set_option_value((char_u *)"ft", 0L, (char_u *)"vim", OPT_LOCAL);
+    }
+
+    /* Reset 'textwidth' after setting 'filetype' (the Vim filetype plugin
+     * sets 'textwidth' to 78). */
+    curbuf->b_p_tw = 0;
+
+    /* Fill the buffer with the history. */
+    init_history();
+    if (hislen > 0)
+    {
+	i = hisidx[histtype];
+	if (i >= 0)
+	{
+	    lnum = 0;
+	    do
+	    {
+		if (++i == hislen)
+		    i = 0;
+		if (history[histtype][i].hisstr != NULL)
+		    ml_append(lnum++, history[histtype][i].hisstr,
+							   (colnr_T)0, FALSE);
+	    }
+	    while (i != hisidx[histtype]);
+	}
+    }
+
+    /* Replace the empty last line with the current command-line and put the
+     * cursor there. */
+    ml_replace(curbuf->b_ml.ml_line_count, ccline.cmdbuff, TRUE);
+    curwin->w_cursor.lnum = curbuf->b_ml.ml_line_count;
+    curwin->w_cursor.col = ccline.cmdpos;
+    changed_line_abv_curs();
+    invalidate_botline();
+    redraw_later(SOME_VALID);
+
+    /* Save the command line info, can be used recursively. */
+    save_ccline = ccline;
+    ccline.cmdbuff = NULL;
+    ccline.cmdprompt = NULL;
+
+    /* No Ex mode here! */
+    exmode_active = 0;
+
+    State = NORMAL;
+# ifdef FEAT_MOUSE
+    setmouse();
+# endif
+
+# ifdef FEAT_AUTOCMD
+    /* Trigger CmdwinEnter autocommands. */
+    typestr0[0] = cmdwin_type;
+    typestr0[1] = NUL;
+    apply_autocmds(EVENT_CMDWINENTER, typestr0, typestr0, FALSE, curbuf);
+    if (restart_edit != 0)	/* autocmd with ":startinsert" */
+	stuffcharReadbuff(K_NOP);
+# endif
+
+    i = RedrawingDisabled;
+    RedrawingDisabled = 0;
+
+    /*
+     * Call the main loop until <CR> or CTRL-C is typed.
+     */
+    cmdwin_result = 0;
+    main_loop(TRUE, FALSE);
+
+    RedrawingDisabled = i;
+
+# ifdef FEAT_AUTOCMD
+    /* Trigger CmdwinLeave autocommands. */
+    apply_autocmds(EVENT_CMDWINLEAVE, typestr0, typestr0, FALSE, curbuf);
+# endif
+
+    /* Restore the command line info. */
+    ccline = save_ccline;
+    cmdwin_type = 0;
+
+    exmode_active = save_exmode;
+
+    /* Safety check: The old window or buffer was deleted: It's a a bug when
+     * this happens! */
+    if (!win_valid(old_curwin) || !buf_valid(old_curbuf))
+    {
+	cmdwin_result = Ctrl_C;
+	EMSG(_("E199: Active window or buffer deleted"));
+    }
+    else
+    {
+# if defined(FEAT_AUTOCMD) && defined(FEAT_EVAL)
+	/* autocmds may abort script processing */
+	if (aborting() && cmdwin_result != K_IGNORE)
+	    cmdwin_result = Ctrl_C;
+# endif
+	/* Set the new command line from the cmdline buffer. */
+	vim_free(ccline.cmdbuff);
+	if (cmdwin_result == K_XF1 || cmdwin_result == K_XF2) /* :qa[!] typed */
+	{
+	    char *p = (cmdwin_result == K_XF2) ? "qa" : "qa!";
+
+	    if (histtype == HIST_CMD)
+	    {
+		/* Execute the command directly. */
+		ccline.cmdbuff = vim_strsave((char_u *)p);
+		cmdwin_result = CAR;
+	    }
+	    else
+	    {
+		/* First need to cancel what we were doing. */
+		ccline.cmdbuff = NULL;
+		stuffcharReadbuff(':');
+		stuffReadbuff((char_u *)p);
+		stuffcharReadbuff(CAR);
+	    }
+	}
+	else if (cmdwin_result == K_XF2)	/* :qa typed */
+	{
+	    ccline.cmdbuff = vim_strsave((char_u *)"qa");
+	    cmdwin_result = CAR;
+	}
+	else
+	    ccline.cmdbuff = vim_strsave(ml_get_curline());
+	if (ccline.cmdbuff == NULL)
+	    cmdwin_result = Ctrl_C;
+	else
+	{
+	    ccline.cmdlen = (int)STRLEN(ccline.cmdbuff);
+	    ccline.cmdbufflen = ccline.cmdlen + 1;
+	    ccline.cmdpos = curwin->w_cursor.col;
+	    if (ccline.cmdpos > ccline.cmdlen)
+		ccline.cmdpos = ccline.cmdlen;
+	    if (cmdwin_result == K_IGNORE)
+	    {
+		set_cmdspos_cursor();
+		redrawcmd();
+	    }
+	}
+
+# ifdef FEAT_AUTOCMD
+	/* Don't execute autocommands while deleting the window. */
+	++autocmd_block;
+# endif
+	wp = curwin;
+	bp = curbuf;
+	win_goto(old_curwin);
+	win_close(wp, TRUE);
+	close_buffer(NULL, bp, DOBUF_WIPE);
+
+	/* Restore window sizes. */
+	win_size_restore(&winsizes);
+
+# ifdef FEAT_AUTOCMD
+	--autocmd_block;
+# endif
+    }
+
+    ga_clear(&winsizes);
+    restart_edit = save_restart_edit;
+# ifdef FEAT_RIGHTLEFT
+    cmdmsg_rl = save_cmdmsg_rl;
+# endif
+
+    State = save_State;
+# ifdef FEAT_MOUSE
+    setmouse();
+# endif
+
+    return cmdwin_result;
+}
+#endif /* FEAT_CMDWIN */
+
+/*
+ * Used for commands that either take a simple command string argument, or:
+ *	cmd << endmarker
+ *	  {script}
+ *	endmarker
+ * Returns a pointer to allocated memory with {script} or NULL.
+ */
+    char_u *
+script_get(eap, cmd)
+    exarg_T	*eap;
+    char_u	*cmd;
+{
+    char_u	*theline;
+    char	*end_pattern = NULL;
+    char	dot[] = ".";
+    garray_T	ga;
+
+    if (cmd[0] != '<' || cmd[1] != '<' || eap->getline == NULL)
+	return NULL;
+
+    ga_init2(&ga, 1, 0x400);
+
+    if (cmd[2] != NUL)
+	end_pattern = (char *)skipwhite(cmd + 2);
+    else
+	end_pattern = dot;
+
+    for (;;)
+    {
+	theline = eap->getline(
+#ifdef FEAT_EVAL
+	    eap->cstack->cs_looplevel > 0 ? -1 :
+#endif
+	    NUL, eap->cookie, 0);
+
+	if (theline == NULL || STRCMP(end_pattern, theline) == 0)
+	    break;
+
+	ga_concat(&ga, theline);
+	ga_append(&ga, '\n');
+	vim_free(theline);
+    }
+    ga_append(&ga, NUL);
+
+    return (char_u *)ga.ga_data;
+}
--- /dev/null
+++ b/farsi.c
@@ -1,0 +1,2312 @@
+/* vi:set ts=8 sts=4 sw=4:
+ *
+ * VIM - Vi IMproved	by Bram Moolenaar
+ *
+ * Do ":help uganda"  in Vim to read copying and usage conditions.
+ * Do ":help credits" in Vim to see a list of people who contributed.
+ * See README.txt for an overview of the Vim source code.
+ */
+
+/*
+ * farsi.c: functions for Farsi language
+ *
+ * Included by main.c, when FEAT_FKMAP is defined.
+ */
+
+static int toF_Xor_X_ __ARGS((int c));
+static int F_is_TyE __ARGS((int c));
+static int F_is_TyC_TyD __ARGS((int c));
+static int F_is_TyB_TyC_TyD __ARGS((int src, int offset));
+static int toF_TyB __ARGS((int c));
+static void put_curr_and_l_to_X __ARGS((int c));
+static void put_and_redo __ARGS((int c));
+static void chg_c_toX_orX __ARGS((void));
+static void chg_c_to_X_orX_ __ARGS((void));
+static void chg_c_to_X_or_X __ARGS((void));
+static void chg_l_to_X_orX_ __ARGS((void));
+static void chg_l_toXor_X __ARGS((void));
+static void chg_r_to_Xor_X_ __ARGS((void));
+static int toF_leading __ARGS((int c));
+static int toF_Rjoin __ARGS((int c));
+static int canF_Ljoin __ARGS((int c));
+static int canF_Rjoin __ARGS((int c));
+static int F_isterm __ARGS((int c));
+static int toF_ending __ARGS((int c));
+static void lrswapbuf __ARGS((char_u *buf, int len));
+
+/*
+** Convert the given Farsi character into a _X or _X_ type
+*/
+    static int
+toF_Xor_X_(c)
+    int	c;
+{
+    int tempc;
+
+    switch (c)
+    {
+	case BE:
+		return _BE;
+	case PE:
+		return _PE;
+	case TE:
+		return _TE;
+	case SE:
+		return _SE;
+	case JIM:
+		return _JIM;
+	case CHE:
+		return _CHE;
+	case HE_J:
+		return _HE_J;
+	case XE:
+		return _XE;
+	case SIN:
+		return _SIN;
+	case SHIN:
+		return _SHIN;
+	case SAD:
+		return _SAD;
+	case ZAD:
+		return _ZAD;
+	case AYN:
+		return _AYN;
+	case AYN_:
+		return _AYN_;
+	case GHAYN:
+		return _GHAYN;
+	case GHAYN_:
+		return _GHAYN_;
+	case FE:
+		return _FE;
+	case GHAF:
+		return _GHAF;
+	case KAF:
+		return _KAF;
+	case GAF:
+		return _GAF;
+	case LAM:
+		return _LAM;
+	case MIM:
+		return _MIM;
+	case NOON:
+		return _NOON;
+	case YE:
+	case YE_:
+		return _YE;
+	case YEE:
+	case YEE_:
+		return _YEE;
+	case IE:
+	case IE_:
+		return _IE;
+	case F_HE:
+		tempc = _HE;
+
+		if (p_ri && (curwin->w_cursor.col+1 < STRLEN(ml_get_curline())))
+		{
+		    inc_cursor();
+
+		    if (F_is_TyB_TyC_TyD(SRC_EDT, AT_CURSOR))
+			tempc = _HE_;
+
+		    dec_cursor();
+		}
+		if (!p_ri && STRLEN(ml_get_curline()))
+		{
+		    dec_cursor();
+
+		    if (F_is_TyB_TyC_TyD(SRC_EDT, AT_CURSOR))
+			tempc = _HE_;
+
+		    inc_cursor();
+		}
+
+		return tempc;
+    }
+    return 0;
+}
+
+/*
+** Convert the given Farsi character into Farsi capital character .
+*/
+    int
+toF_TyA(c)
+    int	c ;
+{
+    switch (c)
+    {
+	case ALEF_:
+		return ALEF;
+	case ALEF_U_H_:
+		return ALEF_U_H;
+	case _BE:
+		return BE;
+	case _PE:
+		return PE;
+	case _TE:
+		return TE;
+	case _SE:
+		return SE;
+	case _JIM:
+		return JIM;
+	case _CHE:
+		return CHE;
+	case _HE_J:
+		return HE_J;
+	case _XE:
+		return XE;
+	case _SIN:
+		return SIN;
+	case _SHIN:
+		return SHIN;
+	case _SAD:
+		return SAD;
+	case _ZAD:
+		return ZAD;
+	case _AYN:
+	case AYN_:
+	case _AYN_:
+		return AYN;
+	case _GHAYN:
+	case GHAYN_:
+	case _GHAYN_:
+		return GHAYN;
+	case _FE:
+		return FE;
+	case _GHAF:
+		return GHAF;
+/* I am not sure what it is !!!	    case _KAF_H: */
+	case _KAF:
+		return KAF;
+	case _GAF:
+		return GAF;
+	case _LAM:
+		return LAM;
+	case _MIM:
+		return MIM;
+	case _NOON:
+		return NOON;
+	case _YE:
+	case YE_:
+		return YE;
+	case _YEE:
+	case YEE_:
+		return YEE;
+	case TEE_:
+		return TEE;
+	case _IE:
+	case IE_:
+		return IE;
+	case _HE:
+	case _HE_:
+		return F_HE;
+    }
+    return c;
+}
+
+/*
+** Is the character under the cursor+offset in the given buffer a join type.
+** That is a character that is combined with the others.
+** Note: the offset is used only for command line buffer.
+*/
+    static int
+F_is_TyB_TyC_TyD(src, offset)
+    int		src, offset;
+{
+    int		c;
+
+    if (src == SRC_EDT)
+	c = gchar_cursor();
+    else
+	c = cmd_gchar(AT_CURSOR+offset);
+
+    switch (c)
+    {
+	case _LAM:
+	case _BE:
+	case _PE:
+	case _TE:
+	case _SE:
+	case _JIM:
+	case _CHE:
+	case _HE_J:
+	case _XE:
+	case _SIN:
+	case _SHIN:
+	case _SAD:
+	case _ZAD:
+	case _TA:
+	case _ZA:
+	case _AYN:
+	case _AYN_:
+	case _GHAYN:
+	case _GHAYN_:
+	case _FE:
+	case _GHAF:
+	case _KAF:
+	case _KAF_H:
+	case _GAF:
+	case _MIM:
+	case _NOON:
+	case _YE:
+	case _YEE:
+	case _IE:
+	case _HE_:
+	case _HE:
+		return TRUE;
+    }
+    return FALSE;
+}
+
+/*
+** Is the Farsi character one of the terminating only type.
+*/
+    static int
+F_is_TyE(c)
+    int	    c;
+{
+    switch (c)
+    {
+	case ALEF_A:
+	case ALEF_D_H:
+	case DAL:
+	case ZAL:
+	case RE:
+	case ZE:
+	case JE:
+	case WAW:
+	case WAW_H:
+	case HAMZE:
+		return TRUE;
+    }
+    return FALSE;
+}
+
+/*
+** Is the Farsi character one of the none leading type.
+*/
+    static int
+F_is_TyC_TyD(c)
+    int	    c;
+{
+    switch (c)
+    {
+	case ALEF_:
+	case ALEF_U_H_:
+	case _AYN_:
+	case AYN_:
+	case _GHAYN_:
+	case GHAYN_:
+	case _HE_:
+	case YE_:
+	case IE_:
+	case TEE_:
+	case YEE_:
+		return TRUE;
+    }
+    return FALSE;
+}
+
+/*
+** Convert a none leading Farsi char into a leading type.
+*/
+    static int
+toF_TyB(c)
+    int	    c;
+{
+    switch (c)
+    {
+	case ALEF_:	return ALEF;
+	case ALEF_U_H_:	    return ALEF_U_H;
+	case _AYN_:	return _AYN;
+	case AYN_:	return AYN;	/* exception - there are many of them */
+	case _GHAYN_:	return _GHAYN;
+	case GHAYN_:	return GHAYN;	/* exception - there are many of them */
+	case _HE_:	return _HE;
+	case YE_:	return YE;
+	case IE_:	return IE;
+	case TEE_:	return TEE;
+	case YEE_:	return YEE;
+    }
+    return c;
+}
+
+/*
+** Overwrite the current redo and cursor characters + left adjust
+*/
+    static void
+put_curr_and_l_to_X(c)
+    int		  c;
+{
+    int	tempc;
+
+    if (curwin->w_p_rl && p_ri)
+	return;
+
+    if ( (curwin->w_cursor.col < STRLEN(ml_get_curline())))
+    {
+	if ((p_ri && curwin->w_cursor.col) || !p_ri)
+	{
+	    if (p_ri)
+		dec_cursor();
+	    else
+		inc_cursor();
+
+	    if (F_is_TyC_TyD((tempc = gchar_cursor())))
+	    {
+		pchar_cursor(toF_TyB(tempc));
+		AppendCharToRedobuff(K_BS);
+		AppendCharToRedobuff(tempc);
+	    }
+
+	    if (p_ri)
+		inc_cursor();
+	    else
+		dec_cursor();
+	}
+    }
+
+    put_and_redo(c);
+}
+
+    static void
+put_and_redo(c)
+    int c;
+{
+    pchar_cursor(c);
+    AppendCharToRedobuff(K_BS);
+    AppendCharToRedobuff(c);
+}
+
+/*
+** Change the char. under the cursor to a X_ or X type
+*/
+    static void
+chg_c_toX_orX()
+{
+    int	tempc, curc;
+
+    switch ((curc = gchar_cursor()))
+    {
+	case _BE:
+		tempc = BE;
+		break;
+	case _PE:
+		tempc = PE;
+		break;
+	case _TE:
+		tempc = TE;
+		break;
+	case _SE:
+		tempc = SE;
+		break;
+	case _JIM:
+		tempc = JIM;
+		break;
+	case _CHE:
+		tempc = CHE;
+		break;
+	case _HE_J:
+		tempc = HE_J;
+		break;
+	case _XE:
+		tempc = XE;
+		break;
+	case _SIN:
+		tempc = SIN;
+		break;
+	case _SHIN:
+		tempc = SHIN;
+		break;
+	case _SAD:
+		tempc = SAD;
+		break;
+	case _ZAD:
+		tempc = ZAD;
+		break;
+	case _FE:
+		tempc = FE;
+		break;
+	case _GHAF:
+		tempc = GHAF;
+		break;
+	case _KAF_H:
+	case _KAF:
+		tempc = KAF;
+		break;
+	case _GAF:
+		tempc = GAF;
+		break;
+	case _AYN:
+		tempc = AYN;
+		break;
+	case _AYN_:
+		tempc = AYN_;
+		break;
+	case _GHAYN:
+		tempc = GHAYN;
+		break;
+	case _GHAYN_:
+		tempc = GHAYN_;
+		break;
+	case _LAM:
+		tempc = LAM;
+		break;
+	case _MIM:
+		tempc = MIM;
+		break;
+	case _NOON:
+		tempc = NOON;
+		break;
+	case _HE:
+	case _HE_:
+		tempc = F_HE;
+		break;
+	case _YE:
+	case _IE:
+	case _YEE:
+		if (p_ri)
+		{
+		    inc_cursor();
+		    if (F_is_TyB_TyC_TyD(SRC_EDT, AT_CURSOR))
+			    tempc = (curc == _YE ? YE_ :
+			    (curc == _IE ? IE_ : YEE_));
+		    else
+			    tempc = (curc == _YE ? YE :
+			    (curc == _IE ? IE : YEE));
+		    dec_cursor();
+		}
+		else
+		{
+		    if (curwin->w_cursor.col)
+		    {
+			dec_cursor();
+			if (F_is_TyB_TyC_TyD(SRC_EDT, AT_CURSOR))
+				tempc = (curc == _YE ? YE_ :
+				(curc == _IE ? IE_ : YEE_));
+			else
+				tempc = (curc == _YE ? YE :
+				(curc == _IE ? IE : YEE));
+			inc_cursor();
+		    }
+		    else
+			    tempc = (curc == _YE ? YE :
+			    (curc == _IE ? IE : YEE));
+		}
+		break;
+	default:
+		tempc = 0;
+    }
+
+    if (tempc)
+	put_and_redo(tempc);
+}
+
+/*
+** Change the char. under the cursor to a _X_ or X_ type
+*/
+
+    static void
+chg_c_to_X_orX_()
+{
+    int	tempc;
+
+    switch (gchar_cursor())
+    {
+	case ALEF:
+		tempc = ALEF_;
+		break;
+	case ALEF_U_H:
+		tempc = ALEF_U_H_;
+		break;
+	case _AYN:
+		tempc = _AYN_;
+		break;
+	case AYN:
+		tempc = AYN_;
+		break;
+	case _GHAYN:
+		tempc = _GHAYN_;
+		break;
+	case GHAYN:
+		tempc = GHAYN_;
+		break;
+	case _HE:
+		tempc = _HE_;
+		break;
+	case YE:
+		tempc = YE_;
+		break;
+	case IE:
+		tempc = IE_;
+		break;
+	case TEE:
+		tempc = TEE_;
+		break;
+	case YEE:
+		tempc = YEE_;
+		break;
+	default:
+		tempc = 0;
+    }
+
+    if (tempc)
+	put_and_redo(tempc);
+}
+
+/*
+** Change the char. under the cursor to a _X_ or _X type
+*/
+    static void
+chg_c_to_X_or_X ()
+{
+    int	tempc;
+
+    tempc = gchar_cursor();
+
+    if (curwin->w_cursor.col+1 < STRLEN(ml_get_curline()))
+    {
+	inc_cursor();
+
+	if ((tempc == F_HE) && (F_is_TyB_TyC_TyD(SRC_EDT, AT_CURSOR)))
+	{
+	    tempc = _HE_;
+
+	    dec_cursor();
+
+	    put_and_redo(tempc);
+	    return;
+	}
+
+	dec_cursor();
+    }
+
+    if ((tempc = toF_Xor_X_(tempc)) != 0)
+	put_and_redo(tempc);
+}
+
+/*
+** Change the character left to the cursor to a _X_ or X_ type
+*/
+    static void
+chg_l_to_X_orX_ ()
+{
+    int	tempc;
+
+    if (!curwin->w_cursor.col &&
+	(curwin->w_cursor.col+1 == STRLEN(ml_get_curline())))
+	return;
+
+    if (!curwin->w_cursor.col && p_ri)
+	return;
+
+    if (p_ri)
+	dec_cursor();
+    else
+	inc_cursor();
+
+    switch (gchar_cursor())
+    {
+	case ALEF:
+		tempc = ALEF_;
+		break;
+	case ALEF_U_H:
+		tempc = ALEF_U_H_;
+		break;
+	case _AYN:
+		tempc = _AYN_;
+		break;
+	case AYN:
+		tempc = AYN_;
+		break;
+	case _GHAYN:
+		tempc = _GHAYN_;
+		break;
+	case GHAYN:
+		tempc = GHAYN_;
+		break;
+	case _HE:
+		tempc = _HE_;
+		break;
+	case YE:
+		tempc = YE_;
+		break;
+	case IE:
+		tempc = IE_;
+		break;
+	case TEE:
+		tempc = TEE_;
+		break;
+	case YEE:
+		tempc = YEE_;
+		break;
+	default:
+		tempc = 0;
+    }
+
+    if (tempc)
+	put_and_redo(tempc);
+
+    if (p_ri)
+	inc_cursor();
+    else
+	dec_cursor();
+}
+
+/*
+** Change the character left to the cursor to a X or _X type
+*/
+
+    static void
+chg_l_toXor_X ()
+{
+    int	tempc;
+
+    if (!curwin->w_cursor.col &&
+	(curwin->w_cursor.col+1 == STRLEN(ml_get_curline())))
+	return;
+
+    if (!curwin->w_cursor.col && p_ri)
+	return;
+
+    if (p_ri)
+	dec_cursor();
+    else
+	inc_cursor();
+
+    switch (gchar_cursor())
+    {
+	case ALEF_:
+		tempc = ALEF;
+		break;
+	case ALEF_U_H_:
+		tempc = ALEF_U_H;
+		break;
+	case _AYN_:
+		tempc = _AYN;
+		break;
+	case AYN_:
+		tempc = AYN;
+		break;
+	case _GHAYN_:
+		tempc = _GHAYN;
+		break;
+	case GHAYN_:
+		tempc = GHAYN;
+		break;
+	case _HE_:
+		tempc = _HE;
+		break;
+	case YE_:
+		tempc = YE;
+		break;
+	case IE_:
+		tempc = IE;
+		break;
+	case TEE_:
+		tempc = TEE;
+		break;
+	case YEE_:
+		tempc = YEE;
+		break;
+	default:
+		tempc = 0;
+    }
+
+    if (tempc)
+	put_and_redo(tempc);
+
+    if (p_ri)
+	inc_cursor();
+    else
+	dec_cursor();
+}
+
+/*
+** Change the character right to the cursor to a _X or _X_ type
+*/
+
+    static void
+chg_r_to_Xor_X_()
+{
+    int tempc, c;
+
+    if (curwin->w_cursor.col)
+    {
+	if (!p_ri)
+	    dec_cursor();
+
+	tempc = gchar_cursor();
+
+	if ((c = toF_Xor_X_(tempc)) != 0)
+	    put_and_redo(c);
+
+	if (!p_ri)
+	    inc_cursor();
+
+    }
+}
+
+/*
+** Map Farsi keyboard when in fkmap mode.
+*/
+
+    int
+fkmap(c)
+    int c;
+{
+    int		tempc;
+    static int	revins;
+
+    if (IS_SPECIAL(c))
+	return c;
+
+    if (VIM_ISDIGIT(c) || ((c == '.' || c == '+' || c == '-' ||
+	c == '^' || c == '%' || c == '#' || c == '=')  && revins))
+    {
+	if (!revins)
+	{
+	    if (curwin->w_cursor.col)
+	    {
+		if (!p_ri)
+		    dec_cursor();
+
+		    chg_c_toX_orX ();
+		    chg_l_toXor_X ();
+
+		if (!p_ri)
+		    inc_cursor();
+	    }
+	}
+
+	arrow_used = TRUE;
+	(void)stop_arrow();
+
+	if (!curwin->w_p_rl && revins)
+	    inc_cursor();
+
+	++revins;
+	p_ri=1;
+    }
+    else
+    {
+	if (revins)
+	{
+	    arrow_used = TRUE;
+	    (void)stop_arrow();
+
+	    revins = 0;
+	    if (curwin->w_p_rl)
+	    {
+		while ((F_isdigit(gchar_cursor())
+			    || (gchar_cursor() == F_PERIOD
+				|| gchar_cursor() == F_PLUS
+				|| gchar_cursor() == F_MINUS
+				|| gchar_cursor() == F_MUL
+				|| gchar_cursor() == F_DIVIDE
+				|| gchar_cursor() == F_PERCENT
+				|| gchar_cursor() == F_EQUALS))
+			&& gchar_cursor() != NUL)
+		    ++curwin->w_cursor.col;
+	    }
+	    else
+	    {
+		if (curwin->w_cursor.col)
+		    while ((F_isdigit(gchar_cursor())
+			    || (gchar_cursor() == F_PERIOD
+				|| gchar_cursor() == F_PLUS
+				|| gchar_cursor() == F_MINUS
+				|| gchar_cursor() == F_MUL
+				|| gchar_cursor() == F_DIVIDE
+				|| gchar_cursor() == F_PERCENT
+				|| gchar_cursor() == F_EQUALS))
+			    && --curwin->w_cursor.col)
+			;
+
+		if (!F_isdigit(gchar_cursor()))
+		    ++curwin->w_cursor.col;
+	    }
+	}
+    }
+
+    if (!revins)
+    {
+	if (curwin->w_p_rl)
+	    p_ri=0;
+	if (!curwin->w_p_rl)
+	    p_ri=1;
+    }
+
+    if ((c < 0x100) && (isalpha(c) || c == '&' ||   c == '^' ||	c == ';' ||
+			    c == '\''||	c == ',' || c == '[' ||
+			    c == ']' ||	c == '{' || c == '}'	))
+	chg_r_to_Xor_X_();
+
+    tempc = 0;
+
+    switch (c)
+    {
+	case '`':
+	case ' ':
+	case '.':
+	case '!':
+	case '"':
+	case '$':
+	case '%':
+	case '^':
+	case '&':
+	case '/':
+	case '(':
+	case ')':
+	case '=':
+	case '\\':
+	case '?':
+	case '+':
+	case '-':
+	case '_':
+	case '*':
+	case ':':
+	case '#':
+	case '~':
+	case '@':
+	case '<':
+	case '>':
+	case '{':
+	case '}':
+	case '|':
+	case '0':
+	case '1':
+	case '2':
+	case '3':
+	case '4':
+	case '5':
+	case '6':
+	case '7':
+	case '8':
+	case '9':
+	case 'B':
+	case 'E':
+	case 'F':
+	case 'H':
+	case 'I':
+	case 'K':
+	case 'L':
+	case 'M':
+	case 'O':
+	case 'P':
+	case 'Q':
+	case 'R':
+	case 'T':
+	case 'U':
+	case 'W':
+	case 'Y':
+	case  NL:
+	case  TAB:
+
+	    if (p_ri && c == NL && curwin->w_cursor.col)
+	    {
+		/*
+		** If the char before the cursor is _X_ or X_ do not change
+		** the one under the cursor with X type.
+		*/
+
+		dec_cursor();
+
+		if (F_isalpha(gchar_cursor()))
+		{
+		    inc_cursor();
+		    return NL;
+		}
+
+		inc_cursor();
+	    }
+
+	    if (!p_ri)
+	    if (!curwin->w_cursor.col)
+	    {
+		switch (c)
+		{
+		    case '0':	return FARSI_0;
+		    case '1':	return FARSI_1;
+		    case '2':	return FARSI_2;
+		    case '3':	return FARSI_3;
+		    case '4':	return FARSI_4;
+		    case '5':	return FARSI_5;
+		    case '6':	return FARSI_6;
+		    case '7':	return FARSI_7;
+		    case '8':	return FARSI_8;
+		    case '9':	return FARSI_9;
+		    case 'B':	return F_PSP;
+		    case 'E':	return JAZR_N;
+		    case 'F':	return ALEF_D_H;
+		    case 'H':	return ALEF_A;
+		    case 'I':	return TASH;
+		    case 'K':	return F_LQUOT;
+		    case 'L':	return F_RQUOT;
+		    case 'M':	return HAMZE;
+		    case 'O':	return '[';
+		    case 'P':	return ']';
+		    case 'Q':	return OO;
+		    case 'R':	return MAD_N;
+		    case 'T':	return OW;
+		    case 'U':	return MAD;
+		    case 'W':	return OW_OW;
+		    case 'Y':	return JAZR;
+		    case '`':	return F_PCN;
+		    case '!':	return F_EXCL;
+		    case '@':	return F_COMMA;
+		    case '#':	return F_DIVIDE;
+		    case '$':	return F_CURRENCY;
+		    case '%':	return F_PERCENT;
+		    case '^':	return F_MUL;
+		    case '&':	return F_BCOMMA;
+		    case '*':	return F_STAR;
+		    case '(':	return F_LPARENT;
+		    case ')':	return F_RPARENT;
+		    case '-':	return F_MINUS;
+		    case '_':	return F_UNDERLINE;
+		    case '=':	return F_EQUALS;
+		    case '+':	return F_PLUS;
+		    case '\\':	return F_BSLASH;
+		    case '|':	return F_PIPE;
+		    case ':':	return F_DCOLON;
+		    case '"':	return F_SEMICOLON;
+		    case '.':	return F_PERIOD;
+		    case '/':	return F_SLASH;
+		    case '<':	return F_LESS;
+		    case '>':	return F_GREATER;
+		    case '?':	return F_QUESTION;
+		    case ' ':	return F_BLANK;
+		}
+		break;
+	    }
+	    if (!p_ri)
+		dec_cursor();
+
+	    switch ((tempc = gchar_cursor()))
+	    {
+		case _BE:
+		case _PE:
+		case _TE:
+		case _SE:
+		case _JIM:
+		case _CHE:
+		case _HE_J:
+		case _XE:
+		case _SIN:
+		case _SHIN:
+		case _SAD:
+		case _ZAD:
+		case _FE:
+		case _GHAF:
+		case _KAF:
+		case _KAF_H:
+		case _GAF:
+		case _LAM:
+		case _MIM:
+		case _NOON:
+		case _HE:
+		case _HE_:
+		case _TA:
+		case _ZA:
+			put_curr_and_l_to_X(toF_TyA(tempc));
+			break;
+		case _AYN:
+		case _AYN_:
+
+			if (!p_ri)
+			    if (!curwin->w_cursor.col)
+			    {
+				put_curr_and_l_to_X(AYN);
+				break;
+			    }
+
+			if (p_ri)
+			    inc_cursor();
+			else
+			    dec_cursor();
+
+			if (F_is_TyB_TyC_TyD(SRC_EDT, AT_CURSOR))
+			    tempc = AYN_;
+			else
+			    tempc = AYN;
+
+			if (p_ri)
+			    dec_cursor();
+			else
+			    inc_cursor();
+
+			put_curr_and_l_to_X(tempc);
+
+			break;
+		case _GHAYN:
+		case _GHAYN_:
+
+			if (!p_ri)
+			    if (!curwin->w_cursor.col)
+			    {
+				put_curr_and_l_to_X(GHAYN);
+				break;
+			    }
+
+			if (p_ri)
+			    inc_cursor();
+			else
+			    dec_cursor();
+
+			if (F_is_TyB_TyC_TyD(SRC_EDT, AT_CURSOR))
+			    tempc = GHAYN_;
+			else
+			    tempc = GHAYN;
+
+			if (p_ri)
+			    dec_cursor();
+			else
+			    inc_cursor();
+
+			put_curr_and_l_to_X(tempc);
+			break;
+		case _YE:
+		case _IE:
+		case _YEE:
+			if (!p_ri)
+			    if (!curwin->w_cursor.col)
+			    {
+				put_curr_and_l_to_X((tempc == _YE ? YE :
+					    (tempc == _IE ? IE : YEE)));
+				break;
+			    }
+
+			if (p_ri)
+			    inc_cursor();
+			else
+			    dec_cursor();
+
+			if (F_is_TyB_TyC_TyD(SRC_EDT, AT_CURSOR))
+				tempc = (tempc == _YE ? YE_ :
+				    (tempc == _IE ? IE_ : YEE_));
+			else
+				tempc = (tempc == _YE ? YE :
+				    (tempc == _IE ? IE : YEE));
+
+			if (p_ri)
+			    dec_cursor();
+			else
+			    inc_cursor();
+
+			put_curr_and_l_to_X(tempc);
+			break;
+		}
+
+		if (!p_ri)
+		    inc_cursor();
+
+		tempc = 0;
+
+		switch (c)
+		{
+		    case '0':	return FARSI_0;
+		    case '1':	return FARSI_1;
+		    case '2':	return FARSI_2;
+		    case '3':	return FARSI_3;
+		    case '4':	return FARSI_4;
+		    case '5':	return FARSI_5;
+		    case '6':	return FARSI_6;
+		    case '7':	return FARSI_7;
+		    case '8':	return FARSI_8;
+		    case '9':	return FARSI_9;
+		    case 'B':	return F_PSP;
+		    case 'E':	return JAZR_N;
+		    case 'F':	return ALEF_D_H;
+		    case 'H':	return ALEF_A;
+		    case 'I':	return TASH;
+		    case 'K':	return F_LQUOT;
+		    case 'L':	return F_RQUOT;
+		    case 'M':	return HAMZE;
+		    case 'O':	return '[';
+		    case 'P':	return ']';
+		    case 'Q':	return OO;
+		    case 'R':	return MAD_N;
+		    case 'T':	return OW;
+		    case 'U':	return MAD;
+		    case 'W':	return OW_OW;
+		    case 'Y':	return JAZR;
+		    case '`':	return F_PCN;
+		    case '!':	return F_EXCL;
+		    case '@':	return F_COMMA;
+		    case '#':	return F_DIVIDE;
+		    case '$':	return F_CURRENCY;
+		    case '%':	return F_PERCENT;
+		    case '^':	return F_MUL;
+		    case '&':	return F_BCOMMA;
+		    case '*':	return F_STAR;
+		    case '(':	return F_LPARENT;
+		    case ')':	return F_RPARENT;
+		    case '-':	return F_MINUS;
+		    case '_':	return F_UNDERLINE;
+		    case '=':	return F_EQUALS;
+		    case '+':	return F_PLUS;
+		    case '\\':	return F_BSLASH;
+		    case '|':	return F_PIPE;
+		    case ':':	return F_DCOLON;
+		    case '"':	return F_SEMICOLON;
+		    case '.':	return F_PERIOD;
+		    case '/':	return F_SLASH;
+		    case '<':	return F_LESS;
+		    case '>':	return F_GREATER;
+		    case '?':	return F_QUESTION;
+		    case ' ':	return F_BLANK;
+		}
+		break;
+
+	case 'a':
+		tempc = _SHIN;
+	    break;
+	case 'A':
+		tempc = WAW_H;
+	    break;
+	case 'b':
+		tempc = ZAL;
+	    break;
+	case 'c':
+		tempc = ZE;
+	    break;
+	case 'C':
+		tempc = JE;
+	    break;
+	case 'd':
+		tempc = _YE;
+	    break;
+	case 'D':
+		tempc = _YEE;
+	    break;
+	case 'e':
+		tempc = _SE;
+	    break;
+	case 'f':
+		tempc = _BE;
+	    break;
+	case 'g':
+		tempc = _LAM;
+	    break;
+	case 'G':
+	    if (!curwin->w_cursor.col  &&  STRLEN(ml_get_curline()))
+		{
+
+		if (gchar_cursor() == _LAM)
+		    chg_c_toX_orX ();
+		else
+		    if (p_ri)
+			chg_c_to_X_or_X ();
+	    }
+
+	    if (!p_ri)
+		if (!curwin->w_cursor.col)
+		    return ALEF_U_H;
+
+	    if (!p_ri)
+		dec_cursor();
+
+	    if (gchar_cursor() == _LAM)
+	    {
+		chg_c_toX_orX ();
+		chg_l_toXor_X ();
+		    tempc = ALEF_U_H;
+	    }
+	    else
+		if (F_is_TyB_TyC_TyD(SRC_EDT, AT_CURSOR))
+		{
+			tempc = ALEF_U_H_;
+		    chg_l_toXor_X ();
+		}
+		else
+			tempc = ALEF_U_H;
+
+	    if (!p_ri)
+		inc_cursor();
+
+	    return tempc;
+	case 'h':
+	    if (!curwin->w_cursor.col  &&  STRLEN(ml_get_curline()))
+		{
+		if (p_ri)
+		    chg_c_to_X_or_X ();
+
+	    }
+
+	    if (!p_ri)
+		if (!curwin->w_cursor.col)
+		    return ALEF;
+
+	    if (!p_ri)
+		dec_cursor();
+
+	    if (gchar_cursor() == _LAM)
+	    {
+		chg_l_toXor_X();
+		del_char(FALSE);
+		AppendCharToRedobuff(K_BS);
+
+		if (!p_ri)
+		    dec_cursor();
+
+		    tempc = LA;
+	    }
+	    else
+	    {
+		if (F_is_TyB_TyC_TyD(SRC_EDT, AT_CURSOR))
+		{
+			tempc = ALEF_;
+		    chg_l_toXor_X ();
+		}
+		else
+			tempc = ALEF;
+	    }
+
+	    if (!p_ri)
+		inc_cursor();
+
+	    return tempc;
+	case 'i':
+	    if (!curwin->w_cursor.col  &&  STRLEN(ml_get_curline()))
+		{
+		if (!p_ri && !F_is_TyE(tempc))
+		    chg_c_to_X_orX_ ();
+		if (p_ri)
+		    chg_c_to_X_or_X ();
+
+	    }
+
+	    if (!p_ri && !curwin->w_cursor.col)
+		return _HE;
+
+	    if (!p_ri)
+		dec_cursor();
+
+	    if (F_is_TyB_TyC_TyD(SRC_EDT, AT_CURSOR))
+		    tempc = _HE_;
+	    else
+		    tempc = _HE;
+
+	    if (!p_ri)
+		inc_cursor();
+	    break;
+	case 'j':
+		tempc = _TE;
+	    break;
+	case 'J':
+	    if (!curwin->w_cursor.col  &&  STRLEN(ml_get_curline()))
+		{
+		if (p_ri)
+		    chg_c_to_X_or_X ();
+
+	    }
+
+	    if (!p_ri)
+		if (!curwin->w_cursor.col)
+		    return TEE;
+
+	    if (!p_ri)
+		dec_cursor();
+
+	    if (F_is_TyB_TyC_TyD(SRC_EDT, AT_CURSOR))
+	    {
+		    tempc = TEE_;
+		chg_l_toXor_X ();
+	    }
+	    else
+			tempc = TEE;
+
+	    if (!p_ri)
+		inc_cursor();
+
+	    return tempc;
+	case 'k':
+		tempc = _NOON;
+	    break;
+	case 'l':
+		tempc = _MIM;
+	    break;
+	case 'm':
+		tempc = _PE;
+	    break;
+	case 'n':
+	case 'N':
+		tempc = DAL;
+	    break;
+	case 'o':
+		tempc = _XE;
+	    break;
+	case 'p':
+		tempc = _HE_J;
+	    break;
+	case 'q':
+		tempc = _ZAD;
+	    break;
+	case 'r':
+		tempc = _GHAF;
+	    break;
+	case 's':
+		tempc = _SIN;
+	    break;
+	case 'S':
+		tempc = _IE;
+	    break;
+	case 't':
+		tempc = _FE;
+	    break;
+	case 'u':
+		if (!curwin->w_cursor.col  &&  STRLEN(ml_get_curline()))
+		{
+		    if (!p_ri && !F_is_TyE(tempc))
+			chg_c_to_X_orX_ ();
+		    if (p_ri)
+			chg_c_to_X_or_X ();
+
+		}
+
+		if (!p_ri && !curwin->w_cursor.col)
+		    return _AYN;
+
+		if (!p_ri)
+		    dec_cursor();
+
+		if (F_is_TyB_TyC_TyD(SRC_EDT, AT_CURSOR))
+		    tempc = _AYN_;
+		else
+		    tempc = _AYN;
+
+		if (!p_ri)
+		    inc_cursor();
+	    break;
+	case 'v':
+	case 'V':
+		tempc = RE;
+	    break;
+	case 'w':
+		tempc = _SAD;
+	    break;
+	case 'x':
+	case 'X':
+		tempc = _TA;
+	    break;
+	case 'y':
+	    if (!curwin->w_cursor.col  &&  STRLEN(ml_get_curline()))
+		{
+		if (!p_ri && !F_is_TyE(tempc))
+		    chg_c_to_X_orX_ ();
+		if (p_ri)
+		    chg_c_to_X_or_X ();
+
+	    }
+
+	    if (!p_ri && !curwin->w_cursor.col)
+		return _GHAYN;
+
+	    if (!p_ri)
+		dec_cursor();
+
+	    if (F_is_TyB_TyC_TyD(SRC_EDT, AT_CURSOR))
+		tempc = _GHAYN_;
+	    else
+		tempc = _GHAYN;
+
+	    if (!p_ri)
+		inc_cursor();
+
+	    break;
+	case 'z':
+		tempc = _ZA;
+	    break;
+	case 'Z':
+		tempc = _KAF_H;
+	    break;
+	case ';':
+		tempc = _KAF;
+	    break;
+	case '\'':
+		tempc = _GAF;
+	    break;
+	case ',':
+		tempc = WAW;
+	    break;
+	case '[':
+		tempc = _JIM;
+	    break;
+	case ']':
+		tempc = _CHE;
+	    break;
+    }
+
+    if ((F_isalpha(tempc) || F_isdigit(tempc)))
+    {
+	if (!curwin->w_cursor.col  &&  STRLEN(ml_get_curline()))
+	    {
+	    if (!p_ri && !F_is_TyE(tempc))
+		chg_c_to_X_orX_ ();
+	    if (p_ri)
+		chg_c_to_X_or_X ();
+	}
+
+	if (curwin->w_cursor.col)
+	{
+	    if (!p_ri)
+		dec_cursor();
+
+	    if (F_is_TyE(tempc))
+		chg_l_toXor_X ();
+	    else
+		chg_l_to_X_orX_ ();
+
+	    if (!p_ri)
+		inc_cursor();
+	}
+    }
+    if (tempc)
+	return tempc;
+    return c;
+}
+
+/*
+** Convert a none leading Farsi char into a leading type.
+*/
+    static int
+toF_leading(c)
+    int	    c;
+{
+    switch (c)
+    {
+	case ALEF_:	return ALEF;
+	case ALEF_U_H_:	    return ALEF_U_H;
+	case BE:    return _BE;
+	case PE:    return _PE;
+	case TE:    return _TE;
+	case SE:    return _SE;
+	case JIM:   return _JIM;
+	case CHE:   return _CHE;
+	case HE_J:  return _HE_J;
+	case XE:    return _XE;
+	case SIN:   return _SIN;
+	case SHIN:  return _SHIN;
+	case SAD:   return _SAD;
+	case ZAD:   return _ZAD;
+
+	case AYN:
+	case AYN_:
+	case _AYN_: return _AYN;
+
+	case GHAYN:
+	case GHAYN_:
+	case _GHAYN_:	return _GHAYN;
+
+	case FE:    return _FE;
+	case GHAF:  return _GHAF;
+	case KAF:   return _KAF;
+	case GAF:   return _GAF;
+	case LAM:   return _LAM;
+	case MIM:   return _MIM;
+	case NOON:  return _NOON;
+
+	case _HE_:
+	case F_HE:	return _HE;
+
+	case YE:
+	case YE_:	return _YE;
+
+	case IE_:
+	case IE:	return _IE;
+
+	case YEE:
+	case YEE_:	return _YEE;
+    }
+    return c;
+}
+
+/*
+** Convert a given Farsi char into right joining type.
+*/
+    static int
+toF_Rjoin(c)
+    int	    c;
+{
+    switch (c)
+    {
+	case ALEF:  return ALEF_;
+	case ALEF_U_H:	return ALEF_U_H_;
+	case BE:    return _BE;
+	case PE:    return _PE;
+	case TE:    return _TE;
+	case SE:    return _SE;
+	case JIM:   return _JIM;
+	case CHE:   return _CHE;
+	case HE_J:  return _HE_J;
+	case XE:    return _XE;
+	case SIN:   return _SIN;
+	case SHIN:  return _SHIN;
+	case SAD:   return _SAD;
+	case ZAD:   return _ZAD;
+
+	case AYN:
+	case AYN_:
+	case _AYN:  return _AYN_;
+
+	case GHAYN:
+	case GHAYN_:
+	case _GHAYN_:	return _GHAYN_;
+
+	case FE:    return _FE;
+	case GHAF:  return _GHAF;
+	case KAF:   return _KAF;
+	case GAF:   return _GAF;
+	case LAM:   return _LAM;
+	case MIM:   return _MIM;
+	case NOON:  return _NOON;
+
+	case _HE:
+	case F_HE:	return _HE_;
+
+	case YE:
+	case YE_:	return _YE;
+
+	case IE_:
+	case IE:	return _IE;
+
+	case TEE:	return TEE_;
+
+	case YEE:
+	case YEE_:	return _YEE;
+    }
+    return c;
+}
+
+/*
+** Can a given Farsi character join via its left edj.
+*/
+    static int
+canF_Ljoin(c)
+    int	c;
+{
+    switch (c)
+    {
+	case _BE:
+	case BE:
+	case PE:
+	case _PE:
+	case TE:
+	case _TE:
+	case SE:
+	case _SE:
+	case JIM:
+	case _JIM:
+	case CHE:
+	case _CHE:
+	case HE_J:
+	case _HE_J:
+	case XE:
+	case _XE:
+	case SIN:
+	case _SIN:
+	case SHIN:
+	case _SHIN:
+	case SAD:
+	case _SAD:
+	case ZAD:
+	case _ZAD:
+	case _TA:
+	case _ZA:
+	case AYN:
+	case _AYN:
+	case _AYN_:
+	case AYN_:
+	case GHAYN:
+	case GHAYN_:
+	case _GHAYN_:
+	case _GHAYN:
+	case FE:
+	case _FE:
+	case GHAF:
+	case _GHAF:
+	case _KAF_H:
+	case KAF:
+	case _KAF:
+	case GAF:
+	case _GAF:
+	case LAM:
+	case _LAM:
+	case MIM:
+	case _MIM:
+	case NOON:
+	case _NOON:
+	case IE:
+	case _IE:
+	case IE_:
+	case YE:
+	case _YE:
+	case YE_:
+	case YEE:
+	case _YEE:
+	case YEE_:
+	case F_HE:
+	case _HE:
+	case _HE_:
+	    return TRUE;
+    }
+    return FALSE;
+}
+
+/*
+** Can a given Farsi character join via its right edj.
+*/
+    static int
+canF_Rjoin(c)
+    int	    c;
+{
+    switch (c)
+    {
+	case ALEF:
+	case ALEF_:
+	case ALEF_U_H:
+	case ALEF_U_H_:
+	case DAL:
+	case ZAL:
+	case RE:
+	case JE:
+	case ZE:
+	case TEE:
+	case TEE_:
+	case WAW:
+	case WAW_H:
+	    return TRUE;
+    }
+
+    return canF_Ljoin(c);
+
+}
+
+/*
+** is a given Farsi character a terminating type.
+*/
+    static int
+F_isterm(c)
+    int	    c;
+{
+    switch (c)
+    {
+	case ALEF:
+	case ALEF_:
+	case ALEF_U_H:
+	case ALEF_U_H_:
+	case DAL:
+	case ZAL:
+	case RE:
+	case JE:
+	case ZE:
+	case WAW:
+	case WAW_H:
+	case TEE:
+	case TEE_:
+	    return TRUE;
+    }
+
+    return FALSE;
+}
+
+/*
+** Convert the given Farsi character into a ending type .
+*/
+    static int
+toF_ending(c)
+    int	    c;
+{
+
+    switch (c)
+    {
+	case _BE:
+		return BE;
+	case _PE:
+		return PE;
+	case _TE:
+		return TE;
+	case _SE:
+		return SE;
+	case _JIM:
+		return JIM;
+	case _CHE:
+		return CHE;
+	case _HE_J:
+		return HE_J;
+	case _XE:
+		return XE;
+	case _SIN:
+		return SIN;
+	case _SHIN:
+		return SHIN;
+	case _SAD:
+		return SAD;
+	case _ZAD:
+		return ZAD;
+	case _AYN:
+		return AYN;
+	case _AYN_:
+		return AYN_;
+	case _GHAYN:
+		return GHAYN;
+	case _GHAYN_:
+		return GHAYN_;
+	case _FE:
+		return FE;
+	case _GHAF:
+		return GHAF;
+	case _KAF_H:
+	case _KAF:
+		return KAF;
+	case _GAF:
+		return GAF;
+	case _LAM:
+		return LAM;
+	case _MIM:
+		return MIM;
+	case _NOON:
+		return NOON;
+	case _YE:
+		return YE_;
+	case YE_:
+		return YE;
+	case _YEE:
+		return YEE_;
+	case YEE_:
+		return YEE;
+	case TEE:
+		return TEE_;
+	case _IE:
+		return IE_;
+	case IE_:
+		return IE;
+	case _HE:
+	case _HE_:
+		return F_HE;
+    }
+    return c;
+}
+
+/*
+** Convert the Farsi 3342 standard into Farsi VIM.
+*/
+    void
+conv_to_pvim()
+{
+    char_u	*ptr;
+    int		lnum, llen, i;
+
+    for (lnum = 1; lnum <= curbuf->b_ml.ml_line_count; ++lnum)
+    {
+	ptr = ml_get((linenr_T)lnum);
+
+	llen = (int)STRLEN(ptr);
+
+	for ( i = 0; i < llen-1; i++)
+	{
+	    if (canF_Ljoin(ptr[i]) && canF_Rjoin(ptr[i+1]))
+	    {
+		ptr[i] = toF_leading(ptr[i]);
+		++i;
+
+		while(canF_Rjoin(ptr[i]) && (i < llen))
+		{
+		    ptr[i] = toF_Rjoin(ptr[i]);
+		    if (F_isterm(ptr[i]) || !F_isalpha(ptr[i]))
+			break;
+		    ++i;
+		}
+		if (!F_isalpha(ptr[i]) || !canF_Rjoin(ptr[i]))
+		    ptr[i-1] = toF_ending(ptr[i-1]);
+	    }
+	    else
+		ptr[i] = toF_TyA(ptr[i]);
+	}
+    }
+
+    /*
+     * Following lines contains Farsi encoded character.
+     */
+
+    do_cmdline_cmd((char_u *)"%s/\202\231/\232/g");
+    do_cmdline_cmd((char_u *)"%s/\201\231/\370\334/g");
+
+    /* Assume the screen has been messed up: clear it and redraw. */
+    redraw_later(CLEAR);
+    MSG_ATTR(farsi_text_1, hl_attr(HLF_S));
+}
+
+/*
+ * Convert the Farsi VIM into Farsi 3342 standad.
+ */
+    void
+conv_to_pstd()
+{
+    char_u	*ptr;
+    int		lnum, llen, i;
+
+    /*
+     * Following line contains Farsi encoded character.
+     */
+
+    do_cmdline_cmd((char_u *)"%s/\232/\202\231/g");
+
+    for (lnum = 1; lnum <= curbuf->b_ml.ml_line_count; ++lnum)
+    {
+	ptr = ml_get((linenr_T)lnum);
+
+	llen = (int)STRLEN(ptr);
+
+	for ( i = 0; i < llen; i++)
+	{
+	    ptr[i] = toF_TyA(ptr[i]);
+
+	}
+    }
+
+    /* Assume the screen has been messed up: clear it and redraw. */
+    redraw_later(CLEAR);
+    MSG_ATTR(farsi_text_2, hl_attr(HLF_S));
+}
+
+/*
+ * left-right swap the characters in buf[len].
+ */
+    static void
+lrswapbuf(buf, len)
+    char_u	*buf;
+    int		len;
+{
+    char_u	*s, *e;
+    int		c;
+
+    s = buf;
+    e = buf + len - 1;
+
+    while (e > s)
+    {
+	c = *s;
+	*s = *e;
+	*e = c;
+	++s;
+	--e;
+    }
+}
+
+/*
+ * swap all the characters in reverse direction
+ */
+    char_u *
+lrswap(ibuf)
+    char_u	*ibuf;
+{
+    if (ibuf != NULL && *ibuf != NUL)
+	lrswapbuf(ibuf, (int)STRLEN(ibuf));
+    return ibuf;
+}
+
+/*
+ * swap all the Farsi characters in reverse direction
+ */
+    char_u *
+lrFswap(cmdbuf, len)
+    char_u	*cmdbuf;
+    int		len;
+{
+    int		i, cnt;
+
+    if (cmdbuf == NULL)
+	return cmdbuf;
+
+    if (len == 0 && (len = (int)STRLEN(cmdbuf)) == 0)
+	return cmdbuf;
+
+    for (i = 0; i < len; i++)
+    {
+	for (cnt = 0; i + cnt < len
+			&& (F_isalpha(cmdbuf[i + cnt])
+			    || F_isdigit(cmdbuf[i + cnt])
+			    || cmdbuf[i + cnt] == ' '); ++cnt)
+	    ;
+
+	lrswapbuf(cmdbuf + i, cnt);
+	i += cnt;
+    }
+    return cmdbuf;
+}
+
+/*
+ * Reverse the characters in the search path and substitute section accordingly
+ */
+    char_u *
+lrF_sub(ibuf)
+    char_u	*ibuf;
+{
+    char_u	*p, *ep;
+    int		i, cnt;
+
+    p = ibuf;
+
+    /* Find the boundary of the search path */
+    while (((p = vim_strchr(p + 1, '/')) != NULL) && p[-1] == '\\')
+	;
+
+    if (p == NULL)
+	return ibuf;
+
+    /* Reverse the Farsi characters in the search path. */
+    lrFswap(ibuf, (int)(p-ibuf));
+
+    /* Now find the boundary of the substitute section */
+    if ((ep = (char_u *)strrchr((char *)++p, '/')) != NULL)
+	cnt = (int)(ep - p);
+    else
+	cnt = (int)STRLEN(p);
+
+    /* Reverse the characters in the substitute section and take care of '\' */
+    for (i = 0; i < cnt-1; i++)
+	if (p[i] == '\\')
+	{
+	    p[i] = p[i+1] ;
+	    p[++i] = '\\';
+	}
+
+    lrswapbuf(p, cnt);
+
+    return ibuf;
+}
+
+/*
+ * Map Farsi keyboard when in cmd_fkmap mode.
+ */
+    int
+cmdl_fkmap(c)
+    int c;
+{
+    int	    tempc;
+
+    switch (c)
+    {
+	case '0':
+	case '1':
+	case '2':
+	case '3':
+	case '4':
+	case '5':
+	case '6':
+	case '7':
+	case '8':
+	case '9':
+	case '`':
+	case ' ':
+	case '.':
+	case '!':
+	case '"':
+	case '$':
+	case '%':
+	case '^':
+	case '&':
+	case '/':
+	case '(':
+	case ')':
+	case '=':
+	case '\\':
+	case '?':
+	case '+':
+	case '-':
+	case '_':
+	case '*':
+	case ':':
+	case '#':
+	case '~':
+	case '@':
+	case '<':
+	case '>':
+	case '{':
+	case '}':
+	case '|':
+	case 'B':
+	case 'E':
+	case 'F':
+	case 'H':
+	case 'I':
+	case 'K':
+	case 'L':
+	case 'M':
+	case 'O':
+	case 'P':
+	case 'Q':
+	case 'R':
+	case 'T':
+	case 'U':
+	case 'W':
+	case 'Y':
+	case  NL:
+	case  TAB:
+
+	       switch ((tempc = cmd_gchar(AT_CURSOR)))
+	       {
+	    case _BE:
+	    case _PE:
+	    case _TE:
+	    case _SE:
+	    case _JIM:
+	    case _CHE:
+	    case _HE_J:
+	    case _XE:
+	    case _SIN:
+	    case _SHIN:
+	    case _SAD:
+	    case _ZAD:
+	    case _AYN:
+	    case _GHAYN:
+	    case _FE:
+	    case _GHAF:
+	    case _KAF:
+	    case _GAF:
+	    case _LAM:
+	    case _MIM:
+	    case _NOON:
+	    case _HE:
+	    case _HE_:
+			cmd_pchar(toF_TyA(tempc), AT_CURSOR);
+		break;
+	    case _AYN_:
+			cmd_pchar(AYN_, AT_CURSOR);
+		break;
+	    case _GHAYN_:
+			cmd_pchar(GHAYN_, AT_CURSOR);
+		break;
+	    case _IE:
+		if (F_is_TyB_TyC_TyD(SRC_CMD, AT_CURSOR+1))
+			    cmd_pchar(IE_, AT_CURSOR);
+		else
+			    cmd_pchar(IE, AT_CURSOR);
+		break;
+	    case _YEE:
+		if (F_is_TyB_TyC_TyD(SRC_CMD, AT_CURSOR+1))
+			    cmd_pchar(YEE_, AT_CURSOR);
+			else
+			    cmd_pchar(YEE, AT_CURSOR);
+		break;
+	    case _YE:
+		if (F_is_TyB_TyC_TyD(SRC_CMD, AT_CURSOR+1))
+			    cmd_pchar(YE_, AT_CURSOR);
+			else
+			    cmd_pchar(YE, AT_CURSOR);
+	    }
+
+	    switch (c)
+	    {
+		case '0':   return FARSI_0;
+		case '1':   return FARSI_1;
+		case '2':   return FARSI_2;
+		case '3':   return FARSI_3;
+		case '4':   return FARSI_4;
+		case '5':   return FARSI_5;
+		case '6':   return FARSI_6;
+		case '7':   return FARSI_7;
+		case '8':   return FARSI_8;
+		case '9':   return FARSI_9;
+		case 'B':   return F_PSP;
+		case 'E':   return JAZR_N;
+		case 'F':   return ALEF_D_H;
+		case 'H':   return ALEF_A;
+		case 'I':   return TASH;
+		case 'K':   return F_LQUOT;
+		case 'L':   return F_RQUOT;
+		case 'M':   return HAMZE;
+		case 'O':   return '[';
+		case 'P':   return ']';
+		case 'Q':   return OO;
+		case 'R':   return MAD_N;
+		case 'T':   return OW;
+		case 'U':   return MAD;
+		case 'W':   return OW_OW;
+		case 'Y':   return JAZR;
+		case '`':   return F_PCN;
+		case '!':   return F_EXCL;
+		case '@':   return F_COMMA;
+		case '#':   return F_DIVIDE;
+		case '$':   return F_CURRENCY;
+		case '%':   return F_PERCENT;
+		case '^':   return F_MUL;
+		case '&':   return F_BCOMMA;
+		case '*':   return F_STAR;
+		case '(':   return F_LPARENT;
+		case ')':   return F_RPARENT;
+		case '-':   return F_MINUS;
+		case '_':   return F_UNDERLINE;
+		case '=':   return F_EQUALS;
+		case '+':   return F_PLUS;
+		case '\\':  return F_BSLASH;
+		case '|':   return F_PIPE;
+		case ':':   return F_DCOLON;
+		case '"':   return F_SEMICOLON;
+		case '.':   return F_PERIOD;
+		case '/':   return F_SLASH;
+		case '<':   return F_LESS;
+		case '>':   return F_GREATER;
+		case '?':   return F_QUESTION;
+		case ' ':   return F_BLANK;
+	    }
+
+	    break;
+
+	case 'a':   return _SHIN;
+	case 'A':   return WAW_H;
+	case 'b':   return ZAL;
+	case 'c':   return ZE;
+	case 'C':   return JE;
+	case 'd':   return _YE;
+	case 'D':   return _YEE;
+	case 'e':   return _SE;
+	case 'f':   return _BE;
+	case 'g':   return _LAM;
+	case 'G':
+		    if (cmd_gchar(AT_CURSOR) == _LAM )
+		{
+		    cmd_pchar(LAM, AT_CURSOR);
+			    return ALEF_U_H;
+		}
+
+		if (F_is_TyB_TyC_TyD(SRC_CMD, AT_CURSOR))
+			return ALEF_U_H_;
+		else
+			return ALEF_U_H;
+	case 'h':
+		    if (cmd_gchar(AT_CURSOR) == _LAM )
+		{
+		    cmd_pchar(LA, AT_CURSOR);
+		    redrawcmdline();
+		    return K_IGNORE;
+		}
+
+		if (F_is_TyB_TyC_TyD(SRC_CMD, AT_CURSOR))
+			return ALEF_;
+		else
+			return ALEF;
+	case 'i':
+		if (F_is_TyB_TyC_TyD(SRC_CMD, AT_CURSOR))
+			return _HE_;
+		else
+			return _HE;
+	case 'j':   return _TE;
+	case 'J':
+		if (F_is_TyB_TyC_TyD(SRC_CMD, AT_CURSOR))
+			return TEE_;
+		else
+			return TEE;
+	case 'k':   return _NOON;
+	case 'l':   return _MIM;
+	case 'm':   return _PE;
+	case 'n':
+	case 'N':   return DAL;
+	case 'o':   return _XE;
+	case 'p':   return _HE_J;
+	case 'q':   return _ZAD;
+	case 'r':   return _GHAF;
+	case 's':   return _SIN;
+	case 'S':   return _IE;
+	case 't':   return _FE;
+	case 'u':
+		if (F_is_TyB_TyC_TyD(SRC_CMD, AT_CURSOR))
+			return _AYN_;
+		else
+			return _AYN;
+	case 'v':
+	case 'V':   return RE;
+	case 'w':   return _SAD;
+	case 'x':
+	case 'X':   return _TA;
+	case 'y':
+		if (F_is_TyB_TyC_TyD(SRC_CMD, AT_CURSOR))
+			return _GHAYN_;
+		else
+			return _GHAYN;
+	case 'z':
+	case 'Z':   return _ZA;
+	case ';':   return _KAF;
+	case '\'':  return _GAF;
+	case ',':   return WAW;
+	case '[':   return _JIM;
+	case ']':   return _CHE;
+	}
+
+	return c;
+}
+
+/*
+ * F_isalpha returns TRUE if 'c' is a Farsi alphabet
+ */
+    int
+F_isalpha(c)
+    int	c;
+{
+    return (( c >= TEE_ && c <= _YE)
+	    || (c >= ALEF_A && c <= YE)
+	    || (c >= _IE && c <= YE_));
+}
+
+/*
+ * F_isdigit returns TRUE if 'c' is a Farsi digit
+ */
+    int
+F_isdigit(c)
+    int	c;
+{
+    return (c >= FARSI_0 && c <= FARSI_9);
+}
+
+/*
+ * F_ischar returns TRUE if 'c' is a Farsi character.
+ */
+    int
+F_ischar(c)
+    int	c;
+{
+    return (c >= TEE_ && c <= YE_);
+}
+
+    void
+farsi_fkey(cap)
+    cmdarg_T	*cap;
+{
+    int		c = cap->cmdchar;
+
+    if (c == K_F8)
+    {
+	if (p_altkeymap)
+	{
+	    if (curwin->w_farsi & W_R_L)
+	    {
+		p_fkmap = 0;
+		do_cmdline_cmd((char_u *)"set norl");
+		MSG("");
+	    }
+	    else
+	    {
+		p_fkmap = 1;
+		do_cmdline_cmd((char_u *)"set rl");
+		MSG("");
+	    }
+
+	    curwin->w_farsi = curwin->w_farsi ^ W_R_L;
+	}
+    }
+
+    if (c == K_F9)
+    {
+	if (p_altkeymap && curwin->w_p_rl)
+	{
+	    curwin->w_farsi = curwin->w_farsi ^ W_CONV;
+	    if (curwin->w_farsi & W_CONV)
+		conv_to_pvim();
+	    else
+		conv_to_pstd();
+	}
+    }
+}
--- /dev/null
+++ b/farsi.h
@@ -1,0 +1,234 @@
+/* vi:set ts=8 sts=4 sw=4:
+ *
+ * VIM - Vi IMproved	by Bram Moolenaar
+ *
+ * Do ":help uganda"  in Vim to read copying and usage conditions.
+ * Do ":help credits" in Vim to see a list of people who contributed.
+ */
+
+/*
+ * Farsi characters are categorized into following types:
+ *
+ * TyA	(for capital letter representation)
+ * TyB	(for types that look like _X  e.g. AYN)
+ * TyC	(for types that look like X_  e.g. YE_)
+ * TyD	(for types that look like _X_  e.g. _AYN_)
+ * TyE	(for types that look like X  e.g. RE)
+ */
+
+/*
+ * Farsi character set definition
+ */
+
+/*
+ * Begin of the non-standard part
+ */
+
+#define TEE_		0x80
+#define ALEF_U_H_	0x81
+#define ALEF_		0x82
+#define _BE		0x83
+#define _PE		0x84
+#define _TE		0x85
+#define _SE		0x86
+#define _JIM		0x87
+#define _CHE		0x88
+#define _HE_J		0x89
+#define _XE		0x8a
+#define _SIN		0x8b
+#define _SHIN		0x8c
+#define _SAD		0x8d
+#define _ZAD		0x8e
+#define _AYN		0x8f
+#define _AYN_		0x90
+#define AYN_		0x91
+#define _GHAYN		0x92
+#define _GHAYN_		0x93
+#define GHAYN_		0x94
+#define _FE		0x95
+#define _GHAF		0x96
+#define _KAF		0x97
+#define _GAF		0x98
+#define _LAM		0x99
+#define LA		0x9a
+#define _MIM		0x9b
+#define _NOON		0x9c
+#define _HE		0x9d
+#define _HE_		0x9e
+#define _YE		0x9f
+#define _IE		0xec
+#define IE_		0xed
+#define IE		0xfb
+#define _YEE		0xee
+#define YEE_		0xef
+#define YE_		0xff
+
+/*
+ * End of the non-standard part
+ */
+
+/*
+ * Standard part
+ */
+
+#define F_BLANK		0xa0	/* Farsi ' ' (SP) character */
+#define F_PSP		0xa1	/* PSP for capitalizing of a character */
+#define F_PCN		0xa2	/* PCN for redefining of the hamye meaning */
+#define F_EXCL		0xa3	/* Farsi ! character */
+#define F_CURRENCY	0xa4	/* Farsi Rial character */
+#define F_PERCENT	0xa5	/* Farsi % character */
+#define F_PERIOD	0xa6	/* Farsi '.' character */
+#define F_COMMA		0xa7	/* Farsi ',' character */
+#define F_LPARENT	0xa8	/* Farsi '(' character */
+#define F_RPARENT	0xa9	/* Farsi ')' character */
+#define F_MUL		0xaa	/* Farsi 'x' character */
+#define F_PLUS		0xab	/* Farsi '+' character */
+#define F_BCOMMA	0xac	/* Farsi comma character */
+#define F_MINUS		0xad	/* Farsi '-' character */
+#define F_DIVIDE	0xae	/* Farsi divide (/) character */
+#define F_SLASH		0xaf	/* Farsi '/' character */
+
+#define FARSI_0		0xb0
+#define FARSI_1		0xb1
+#define FARSI_2		0xb2
+#define FARSI_3		0xb3
+#define FARSI_4		0xb4
+#define FARSI_5		0xb5
+#define FARSI_6		0xb6
+#define FARSI_7		0xb7
+#define FARSI_8		0xb8
+#define FARSI_9		0xb9
+
+#define F_DCOLON	0xba	/* Farsi ':' character */
+#define F_SEMICOLON	0xbb	/* Farsi ';' character */
+#define F_GREATER	0xbc	/* Farsi '>' character */
+#define F_EQUALS	0xbd	/* Farsi '=' character */
+#define F_LESS		0xbe	/* Farsi '<' character */
+#define F_QUESTION	0xbf	/* Farsi ? character */
+
+#define ALEF_A	0xc0
+#define ALEF	0xc1
+#define HAMZE	0xc2
+#define BE	0xc3
+#define PE	0xc4
+#define TE	0xc5
+#define SE	0xc6
+#define JIM	0xc7
+#define CHE	0xc8
+#define HE_J	0xc9
+#define XE	0xca
+#define DAL	0xcb
+#define ZAL	0xcc
+#define RE	0xcd
+#define ZE	0xce
+#define JE	0xcf
+#define SIN	0xd0
+#define SHIN	0xd1
+#define SAD	0xd2
+#define ZAD	0xd3
+#define _TA	0xd4
+#define _ZA	0xd5
+#define AYN	0xd6
+#define GHAYN	0xd7
+#define FE	0xd8
+#define GHAF	0xd9
+#define KAF	0xda
+#define GAF	0xdb
+#define LAM	0xdc
+#define MIM	0xdd
+#define NOON	0xde
+#define WAW	0xdf
+#define F_HE	0xe0		/* F_ added for name clash with Perl */
+#define YE	0xe1
+#define TEE	0xfc
+#define _KAF_H	0xfd
+#define YEE	0xfe
+
+#define F_LBRACK	0xe2	/* Farsi '[' character */
+#define F_RBRACK	0xe3	/* Farsi ']' character */
+#define F_LBRACE	0xe4	/* Farsi '{' character */
+#define F_RBRACE	0xe5	/* Farsi '}' character */
+#define F_LQUOT		0xe6	/* Farsi left quotation character */
+#define F_RQUOT		0xe7	/* Farsi right quotation character */
+#define F_STAR		0xe8	/* Farsi '*' character */
+#define F_UNDERLINE	0xe9	/* Farsi '_' character */
+#define F_PIPE		0xea	/* Farsi '|' character */
+#define F_BSLASH	0xeb	/* Farsi '\' character */
+
+#define MAD		0xf0
+#define JAZR		0xf1
+#define OW		0xf2
+#define MAD_N		0xf3
+#define JAZR_N		0xf4
+#define OW_OW		0xf5
+#define TASH		0xf6
+#define OO		0xf7
+#define ALEF_U_H	0xf8
+#define WAW_H		0xf9
+#define ALEF_D_H	0xfa
+
+/*
+ * global definitions
+ * ==================
+ */
+
+#define SRC_EDT	0
+#define SRC_CMD 1
+
+#define AT_CURSOR 0
+
+/*
+ * definitions for the window dependent functions (w_farsi).
+ */
+#define W_CONV 0x1
+#define W_R_L  0x2
+
+
+/* special Farsi text messages */
+
+EXTERN char_u farsi_text_1[]
+#ifdef DO_INIT
+		= { YE_, _SIN, RE, ALEF_, _FE, ' ', 'V', 'I', 'M',
+		    ' ', F_HE, _BE, ' ', SHIN, RE, _GAF, DAL,' ', NOON,
+		    ALEF_, _YE, ALEF_, _PE, '\0'}
+#endif
+		     ;
+
+EXTERN char_u farsi_text_2[]
+#ifdef DO_INIT
+		= { YE_, _SIN, RE, ALEF_, _FE, ' ', FARSI_3, FARSI_3,
+		    FARSI_4, FARSI_2, ' ', DAL, RE, ALEF, DAL, _NOON,
+		    ALEF_, _TE, _SIN, ALEF, ' ', F_HE, _BE, ' ', SHIN,
+		    RE,  _GAF, DAL, ' ', NOON, ALEF_, _YE, ALEF_, _PE, '\0'}
+#endif
+		     ;
+
+EXTERN char_u farsi_text_3[]
+#ifdef DO_INIT
+		= { DAL, WAW, _SHIN, _YE, _MIM, _NOON, ' ', YE_, _NOON,
+		    ALEF_,_BE, _YE, _TE, _SHIN, _PE, ' ', 'R','E','P','L',
+		    'A','C','E', ' ', NOON, ALEF_, _MIM, RE, _FE, ZE, ALEF,
+		    ' ', 'R', 'E', 'V', 'E', 'R', 'S', 'E', ' ', 'I', 'N',
+		    'S', 'E', 'R', 'T', ' ', SHIN, WAW, RE, ' ', ALEF_, _BE,
+		    ' ', YE_, _SIN, RE, ALEF_, _FE, ' ', RE, DAL, ' ', RE,
+		    ALEF_, _KAF,' ', MIM, ALEF_, _GAF, _NOON, _HE, '\0'}
+#endif
+		    ;
+
+#if 0 /* not used */
+EXTERN char_u farsi_text_4[]
+#ifdef DO_INIT
+		= { DAL, WAW, _SHIN, _YE, _MIM, _NOON, ' ', YE_, _NOON,
+		    ALEF_, _BE, _YE, _TE, _SHIN, _PE, ' ', '<', 'C','T','R',
+		    'L','-','B','>', ' ', NOON, ALEF_, _MIM, RE, _FE, ZE,
+		    ALEF, ' ', YE_, _SIN, RE, ALEF_, _FE, ' ', RE, DAL, ' ',
+		    RE, ALEF_, _KAF,' ', MIM, ALEF_, _GAF, _NOON, _HE, '\0'}
+#endif
+		    ;
+#endif
+
+EXTERN char_u farsi_text_5[]
+#ifdef DO_INIT
+		= { ' ', YE_, _SIN, RE, ALEF_, _FE, '\0'}
+#endif
+		    ;
--- /dev/null
+++ b/feature.h
@@ -1,0 +1,1264 @@
+/* vi:set ts=8 sts=4 sw=4:
+ *
+ * VIM - Vi IMproved		by Bram Moolenaar
+ *
+ * Do ":help uganda"  in Vim to read copying and usage conditions.
+ * Do ":help credits" in Vim to see a list of people who contributed.
+ */
+/*
+ * feature.h: Defines for optional code and preferences
+ *
+ * Edit this file to include/exclude parts of Vim, before compiling.
+ * The only other file that may be edited is Makefile, it contains machine
+ * specific options.
+ *
+ * To include specific options, change the "#if*" and "#endif" into comments,
+ * or uncomment the "#define".
+ * To exclude specific options, change the "#define" into a comment.
+ */
+
+/*
+ * When adding a new feature:
+ * - Add a #define below.
+ * - Add a message in the table above ex_version().
+ * - Add a string to f_has().
+ * - Add a feature to ":help feature-list" in doc/eval.txt.
+ * - Add feature to ":help +feature-list" in doc/various.txt.
+ * - Add comment for the documentation of commands that use the feature.
+ */
+
+/*
+ * Basic choices:
+ * ==============
+ *
+ * +tiny		almost no features enabled, not even multiple windows
+ * +small		few features enabled, as basic as possible
+ * +normal		A default selection of features enabled
+ * +big			many features enabled, as rich as possible.
+ * +huge		all possible featues enabled.
+ *
+ * When +small is used, +tiny is also included.  +normal implies +small, etc.
+ */
+
+/*
+ * Uncomment one of these to override the default.  For unix use a configure
+ * argument, see Makefile.
+ */
+#if !defined(FEAT_TINY) && !defined(FEAT_SMALL) && !defined(FEAT_NORMAL) \
+	&& !defined(FEAT_BIG) && !defined(FEAT_HUGE)
+/* #define FEAT_TINY */
+/* #define FEAT_SMALL */
+/* #define FEAT_NORMAL */
+/* #define FEAT_BIG */
+/* #define FEAT_HUGE */
+#endif
+
+/*
+ * These executables are made available with the +big feature, because they
+ * are supposed to have enough RAM: Win32 (console & GUI), dos32, OS/2 and VMS.
+ * The dos16 version has very little RAM available, use +small.
+ */
+#if !defined(FEAT_TINY) && !defined(FEAT_SMALL) && !defined(FEAT_NORMAL) \
+	&& !defined(FEAT_BIG) && !defined(FEAT_HUGE)
+# if defined(MSWIN) || defined(DJGPP) || defined(OS2) || defined(VMS) || defined(MACOS) || defined(AMIGA)
+#  define FEAT_BIG
+# else
+#  ifdef MSDOS
+#   define FEAT_SMALL
+#  else
+#   define FEAT_NORMAL
+#  endif
+# endif
+#endif
+
+/*
+ * Each feature implies including the "smaller" ones.
+ */
+#ifdef FEAT_HUGE
+# define FEAT_BIG
+#endif
+#ifdef FEAT_BIG
+# define FEAT_NORMAL
+#endif
+#ifdef FEAT_NORMAL
+# define FEAT_SMALL
+#endif
+#ifdef FEAT_SMALL
+# define FEAT_TINY
+#endif
+
+/*
+ * Optional code (see ":help +feature-list")
+ * =============
+ */
+
+/*
+ * +windows		Multiple windows.  Without this there is no help
+ *			window and no status lines.
+ */
+#ifdef FEAT_SMALL
+# define FEAT_WINDOWS
+#endif
+
+/*
+ * +listcmds		Vim commands for the buffer list and the argument
+ *			list.  Without this there is no ":buffer" ":bnext",
+ *			":bdel", ":argdelete", etc.
+ */
+#ifdef FEAT_NORMAL
+# define FEAT_LISTCMDS
+#endif
+
+/*
+ * +vertsplit		Vertically split windows.
+ */
+#ifdef FEAT_NORMAL
+# define FEAT_VERTSPLIT
+#endif
+#if defined(FEAT_VERTSPLIT) && !defined(FEAT_WINDOWS)
+# define FEAT_WINDOWS
+#endif
+
+/*
+ * +cmdhist		Command line history.
+ */
+#ifdef FEAT_SMALL
+# define FEAT_CMDHIST
+#endif
+
+/*
+ * Message history is fixed at 100 message, 20 for the tiny version.
+ */
+#ifdef FEAT_SMALL
+# define MAX_MSG_HIST_LEN 100
+#else
+# define MAX_MSG_HIST_LEN 20
+#endif
+
+/*
+ * +jumplist		Jumplist, CTRL-O and CTRL-I commands.
+ */
+#ifdef FEAT_SMALL
+# define FEAT_JUMPLIST
+#endif
+
+/* the cmdline-window requires FEAT_VERTSPLIT and FEAT_CMDHIST */
+#if defined(FEAT_VERTSPLIT) && defined(FEAT_CMDHIST)
+# define FEAT_CMDWIN
+#endif
+
+/*
+ * +folding		Fold lines.
+ */
+#ifdef FEAT_NORMAL
+# define FEAT_FOLDING
+#endif
+
+/*
+ * +digraphs		Digraphs.
+ *			In insert mode and on the command line you will be
+ *			able to use digraphs. The CTRL-K command will work.
+ *			Define OLD_DIGRAPHS to get digraphs compatible with
+ *			Vim 5.x.  The new ones are from RFC 1345.
+ */
+#ifdef FEAT_NORMAL
+# define FEAT_DIGRAPHS
+/* #define OLD_DIGRAPHS */
+#endif
+
+/*
+ * +langmap		'langmap' option.  Only useful when you put your
+ *			keyboard in a special language mode, e.g. for typing
+ *			greek.
+ */
+#ifdef FEAT_BIG
+# define FEAT_LANGMAP
+#endif
+
+/*
+ * +keymap		'keymap' option.  Allows you to map typed keys in
+ *			Insert mode for a special language.
+ */
+#ifdef FEAT_BIG
+# define FEAT_KEYMAP
+#endif
+
+/*
+ * +localmap		Mappings and abbreviations local to a buffer.
+ */
+#ifdef FEAT_NORMAL
+# define FEAT_LOCALMAP
+#endif
+
+/*
+ * +insert_expand	CTRL-N/CTRL-P/CTRL-X in insert mode. Takes about
+ *			4Kbyte of code.
+ */
+#ifdef FEAT_NORMAL
+# define FEAT_INS_EXPAND
+#endif
+
+/*
+ * +cmdline_compl	completion of mappings/abbreviations in cmdline mode.
+ *			Takes a few Kbyte of code.
+ */
+#ifdef FEAT_NORMAL
+# define FEAT_CMDL_COMPL
+#endif
+
+#ifdef FEAT_NORMAL
+# define VIM_BACKTICK		/* internal backtick expansion */
+#endif
+
+/*
+ * +visual		Visual mode.
+ * +visualextra		Extra features for Visual mode (mostly block operators).
+ */
+#ifdef FEAT_SMALL
+# define FEAT_VISUAL
+# ifdef FEAT_NORMAL
+#  define FEAT_VISUALEXTRA
+# endif
+#else
+# ifdef FEAT_CLIPBOARD
+#  undef FEAT_CLIPBOARD	/* can't use clipboard without Visual mode */
+# endif
+#endif
+
+/*
+ * +virtualedit		'virtualedit' option and its implementation
+ */
+#ifdef FEAT_NORMAL
+# define FEAT_VIRTUALEDIT
+#endif
+
+/*
+ * +vreplace		"gR" and "gr" commands.
+ */
+#ifdef FEAT_NORMAL
+# define FEAT_VREPLACE
+#endif
+
+/*
+ * +cmdline_info	'showcmd' and 'ruler' options.
+ */
+#ifdef FEAT_NORMAL
+# define FEAT_CMDL_INFO
+#endif
+
+/*
+ * +linebreak		'showbreak', 'breakat'  and 'linebreak' options.
+ *			Also 'numberwidth'.
+ */
+#ifdef FEAT_NORMAL
+# define FEAT_LINEBREAK
+#endif
+
+/*
+ * +ex_extra		":retab", ":right", ":left", ":center", ":normal".
+ */
+#ifdef FEAT_NORMAL
+# define FEAT_EX_EXTRA
+#endif
+
+/*
+ * +extra_search	'hlsearch' and 'incsearch' options.
+ */
+#ifdef FEAT_NORMAL
+# define FEAT_SEARCH_EXTRA
+#endif
+
+/*
+ * +quickfix		Quickfix commands.
+ */
+#ifdef FEAT_NORMAL
+# define FEAT_QUICKFIX
+#endif
+
+/*
+ * +file_in_path	"gf" and "<cfile>" commands.
+ */
+#ifdef FEAT_NORMAL
+# define FEAT_SEARCHPATH
+#endif
+
+/*
+ * +find_in_path	"[I" ":isearch" "^W^I", ":checkpath", etc.
+ */
+#ifdef FEAT_NORMAL
+# ifdef FEAT_SEARCHPATH	/* FEAT_SEARCHPATH is required */
+#  define FEAT_FIND_ID
+# endif
+#endif
+
+/*
+ * +path_extra		up/downwards searching in 'path' and 'tags'.
+ */
+#ifdef FEAT_NORMAL
+# define FEAT_PATH_EXTRA
+#endif
+
+/*
+ * +rightleft		Right-to-left editing/typing support.
+ */
+#ifdef FEAT_BIG
+# define FEAT_RIGHTLEFT
+#endif
+
+/*
+ * +farsi		Farsi (Persian language) Keymap support.
+ *			Requires FEAT_RIGHTLEFT.
+ */
+#ifdef FEAT_BIG
+# define FEAT_FKMAP
+#endif
+#ifdef FEAT_FKMAP
+# ifndef FEAT_RIGHTLEFT
+#   define FEAT_RIGHTLEFT
+# endif
+#endif
+
+/*
+ * +arabic		Arabic keymap and shaping support.
+ *			Requires FEAT_RIGHTLEFT and FEAT_MBYTE.
+ */
+#if defined(FEAT_BIG) && !defined(WIN16) && SIZEOF_INT >= 4 && !defined(EBCDIC)
+# define FEAT_ARABIC
+#endif
+#ifdef FEAT_ARABIC
+# ifndef FEAT_RIGHTLEFT
+#   define FEAT_RIGHTLEFT
+# endif
+#endif
+
+/*
+ * +emacs_tags		When FEAT_EMACS_TAGS defined: Include support for
+ *			emacs style TAGS file.
+ */
+#ifdef FEAT_BIG
+# define FEAT_EMACS_TAGS
+#endif
+
+/*
+ * +tag_binary		Can use a binary search for the tags file.
+ *
+ * Disabled for EBCDIC:
+ * On OS/390 Unix we have the problem that /bin/sort sorts ASCII instead of
+ * EBCDIC.  With this binary search doesn't work, as VIM expects a tag file
+ * sorted by character values.  I'm not sure how to fix this. Should we really
+ * do a EBCDIC to ASCII conversion for this??
+ */
+#if defined(FEAT_NORMAL) && !defined(EBCDIC)
+# define FEAT_TAG_BINS
+#endif
+
+/*
+ * +tag_old_static	Old style static tags: "file:tag  file  ..".  Slows
+ *			down tag searching a bit.
+ */
+#ifdef FEAT_NORMAL
+# define FEAT_TAG_OLDSTATIC
+#endif
+
+/*
+ * +tag_any_white	Allow any white space to separate the fields in a tags
+ *			file.  When not defined, only a TAB is allowed.
+ */
+/* #define FEAT_TAG_ANYWHITE */
+
+/*
+ * +cscope		Unix only: Cscope support.
+ */
+#if defined(UNIX) && defined(FEAT_BIG) && !defined(FEAT_CSCOPE) && !defined(MACOS_X)
+# define FEAT_CSCOPE
+#endif
+
+/*
+ * +eval		Built-in script language and expression evaluation,
+ *			":let", ":if", etc.
+ */
+#ifdef FEAT_NORMAL
+# define FEAT_EVAL
+#endif
+
+/*
+ * +profile		Profiling for functions and scripts.
+ */
+#if defined(FEAT_HUGE) \
+	&& defined(FEAT_EVAL) \
+	&& ((defined(HAVE_GETTIMEOFDAY) && defined(HAVE_SYS_TIME_H)) \
+		|| defined(WIN3264))
+# define FEAT_PROFILE
+#endif
+
+/*
+ * +reltime		reltime() function
+ */
+#if defined(FEAT_NORMAL) \
+	&& defined(FEAT_EVAL) \
+	&& ((defined(HAVE_GETTIMEOFDAY) && defined(HAVE_SYS_TIME_H)) \
+		|| defined(WIN3264))
+# define FEAT_RELTIME
+#endif
+
+/*
+ * +textobjects		Text objects: "vaw", "das", etc.
+ */
+#if defined(FEAT_NORMAL) && defined(FEAT_EVAL)
+# define FEAT_TEXTOBJ
+#endif
+
+/*
+ *			Insert mode completion with 'completefunc'.
+ */
+#if defined(FEAT_INS_EXPAND) && defined(FEAT_EVAL)
+# define FEAT_COMPL_FUNC
+#endif
+
+/*
+ * +user_commands	Allow the user to define his own commands.
+ */
+#ifdef FEAT_NORMAL
+# define FEAT_USR_CMDS
+#endif
+
+/*
+ * +printer		":hardcopy" command
+ * +postscript		Printing uses PostScript file output.
+ */
+#if defined(FEAT_NORMAL) && (defined(MSWIN) || defined(FEAT_EVAL)) \
+	&& !defined(AMIGA)
+# define FEAT_PRINTER
+#endif
+#if defined(FEAT_PRINTER) && ((defined(MSWIN) && defined(MSWINPS)) \
+	|| (!defined(MSWIN) && defined(FEAT_EVAL)))
+# define FEAT_POSTSCRIPT
+#endif
+
+/*
+ * +modify_fname	modifiers for file name.  E.g., "%:p:h".
+ */
+#ifdef FEAT_NORMAL
+# define FEAT_MODIFY_FNAME
+#endif
+
+/*
+ * +autocmd		":autocmd" command
+ */
+#ifdef FEAT_NORMAL
+# define FEAT_AUTOCMD
+#endif
+
+/*
+ * +diff		Displaying diffs in a nice way.
+ *			Requires +windows and +autocmd.
+ */
+#if defined(FEAT_NORMAL) && defined(FEAT_WINDOWS) && defined(FEAT_AUTOCMD)
+# define FEAT_DIFF
+#endif
+
+/*
+ * +title		'title' and 'icon' options
+ * +statusline		'statusline', 'rulerformat' and special format of
+ *			'titlestring' and 'iconstring' options.
+ * +byte_offset		'%o' in 'statusline' and builtin functions line2byte()
+ *			and byte2line().
+ *			Note: Required for Macintosh.
+ */
+#if defined(FEAT_NORMAL) && !defined(MSDOS)
+# define FEAT_TITLE
+#endif
+
+#ifdef FEAT_NORMAL
+# define FEAT_STL_OPT
+# ifndef FEAT_CMDL_INFO
+#  define FEAT_CMDL_INFO	/* 'ruler' is required for 'statusline' */
+# endif
+#endif
+
+#ifdef FEAT_NORMAL
+# define FEAT_BYTEOFF
+#endif
+
+/*
+ * +wildignore		'wildignore' and 'backupskip' options
+ *			Needed for Unix to make "crontab -e" work.
+ */
+#if defined(FEAT_NORMAL) || defined(UNIX)
+# define FEAT_WILDIGN
+#endif
+
+/*
+ * +wildmenu		'wildmenu' option
+ */
+#if defined(FEAT_NORMAL) && defined(FEAT_WINDOWS)
+# define FEAT_WILDMENU
+#endif
+
+/*
+ * +osfiletype		filetype checking in autocommand patterns.
+ *			Only on systems that support filetypes (RISC OS).
+ */
+#if 0
+# define FEAT_OSFILETYPE
+# define DFLT_OFT "Text"
+#endif
+
+/*
+ * +viminfo		reading/writing the viminfo file. Takes about 8Kbyte
+ *			of code.
+ * VIMINFO_FILE		Location of user .viminfo file (should start with $).
+ * VIMINFO_FILE2	Location of alternate user .viminfo file.
+ */
+#ifdef FEAT_NORMAL
+# define FEAT_VIMINFO
+/* #define VIMINFO_FILE	"$HOME/foo/.viminfo" */
+/* #define VIMINFO_FILE2 "~/bar/.viminfo" */
+#endif
+
+/*
+ * +syntax		syntax highlighting.  When using this, it's a good
+ *			idea to have +autocmd and +eval too.
+ */
+#if defined(FEAT_NORMAL) || defined(PROTO)
+# define FEAT_SYN_HL
+#endif
+
+/*
+ * +spell		spell checking
+ */
+#if defined(FEAT_NORMAL) || defined(PROTO)
+# define FEAT_SPELL
+#endif
+
+/*
+ * +builtin_terms	Choose one out of the following four:
+ *
+ * NO_BUILTIN_TCAPS	Do not include any builtin termcap entries (used only
+ *			with HAVE_TGETENT defined).
+ *
+ * (nothing)		Machine specific termcap entries will be included.
+ *			This is default for win16 to save static data.
+ *
+ * SOME_BUILTIN_TCAPS	Include most useful builtin termcap entries (used only
+ *			with NO_BUILTIN_TCAPS not defined).
+ *			This is the default.
+ *
+ * ALL_BUILTIN_TCAPS	Include all builtin termcap entries
+ *			(used only with NO_BUILTIN_TCAPS not defined).
+ */
+#ifdef HAVE_TGETENT
+/* #define NO_BUILTIN_TCAPS */
+#endif
+
+#if !defined(NO_BUILTIN_TCAPS) && !defined(FEAT_GUI_W16)
+# ifdef FEAT_BIG
+#  define ALL_BUILTIN_TCAPS
+# else
+#  define SOME_BUILTIN_TCAPS		/* default */
+# endif
+#endif
+
+/*
+ * +lispindent		lisp indenting (From Eric Fischer).
+ * +cindent		C code indenting (From Eric Fischer).
+ * +smartindent		smart C code indenting when the 'si' option is set.
+ *
+ * These two need to be defined when making prototypes.
+ */
+#if defined(FEAT_NORMAL) || defined(PROTO)
+# define FEAT_LISP
+#endif
+
+#if defined(FEAT_NORMAL) || defined(PROTO)
+# define FEAT_CINDENT
+#endif
+
+#ifdef FEAT_NORMAL
+# define FEAT_SMARTINDENT
+#endif
+
+/*
+ * +comments		'comments' option.
+ */
+#ifdef FEAT_NORMAL
+# define FEAT_COMMENTS
+#endif
+
+/*
+ * +cryptv		Encryption (by Mohsin Ahmed <mosh@sasi.com>).
+ */
+#if defined(FEAT_NORMAL) || defined(PROTO)
+# define FEAT_CRYPT
+#endif
+
+/*
+ * +mksession		":mksession" command.
+ *			Requires +windows and +vertsplit.
+ */
+#if defined(FEAT_NORMAL) && defined(FEAT_WINDOWS) && defined(FEAT_VERTSPLIT)
+# define FEAT_SESSION
+#endif
+
+/*
+ * +multi_lang		Multi language support. ":menutrans", ":language", etc.
+ * +gettext		Message translations (requires +multi_lang)
+ *			(only when "lang" archive unpacked)
+ */
+#ifdef FEAT_NORMAL
+# define FEAT_MULTI_LANG
+#endif
+#if defined(HAVE_GETTEXT) && defined(FEAT_MULTI_LANG) \
+	&& (defined(HAVE_LOCALE_H) || defined(X_LOCALE))
+# define FEAT_GETTEXT
+#endif
+
+/*
+ * +multi_byte		Generic multi-byte character handling.  Doesn't work
+ *			with 16 bit ints.  Required for GTK+ 2.
+ *
+ * Disabled for EBCDIC:
+ * Multibyte support doesn't work on OS390 Unix currently.
+ */
+#if (defined(FEAT_BIG) || defined(HAVE_GTK2) || defined(FEAT_ARABIC) || defined(PLAN9)) \
+	&& !defined(FEAT_MBYTE) && !defined(WIN16) \
+	&& SIZEOF_INT >= 4 && !defined(EBCDIC)
+# define FEAT_MBYTE
+#endif
+
+/* Define this if you want to use 16 bit Unicode only, reduces memory used for
+ * the screen structures. */
+/* #define UNICODE16 */
+
+/*
+ * +multi_byte_ime	Win32 IME input method.  Requires +multi_byte.
+ *			Only for far-east Windows, so IME can be used to input
+ *			chars.  Not tested much!
+ */
+#if defined(FEAT_GUI_W32) && !defined(FEAT_MBYTE_IME)
+/* #define FEAT_MBYTE_IME */
+# endif
+
+#if defined(FEAT_MBYTE_IME) && !defined(FEAT_MBYTE)
+# define FEAT_MBYTE
+#endif
+
+#if defined(FEAT_MBYTE) && SIZEOF_INT < 4 && !defined(PROTO)
+	Error: Can only handle multi-byte feature with 32 bit int or larger
+#endif
+
+/* Use iconv() when it's available. */
+#if defined(FEAT_MBYTE) && ((defined(HAVE_ICONV_H) && defined(HAVE_ICONV)) \
+		|| defined(DYNAMIC_ICONV))
+# define USE_ICONV
+#endif
+
+/*
+ * +xim			X Input Method.  For entering special languages like
+ *			chinese and Japanese.
+ * +hangul_input	Internal Hangul input method.  Must be included
+ *			through configure: "--enable-hangulin"
+ * Both are for Unix and VMS only.
+ */
+#ifndef FEAT_XIM
+/* #define FEAT_XIM */
+#endif
+
+#if defined(FEAT_XIM) && defined(FEAT_GUI_GTK)
+# define USE_XIM 1		/* needed for GTK include files */
+#endif
+
+#ifdef FEAT_HANGULIN
+# define HANGUL_DEFAULT_KEYBOARD 2	/* 2 or 3 bulsik keyboard */
+# define ESC_CHG_TO_ENG_MODE		/* if defined, when ESC pressed,
+					 * turn to english mode
+					 */
+# if !defined(FEAT_XFONTSET) && defined(HAVE_X11)
+#  define FEAT_XFONTSET			/* Hangul input requires xfontset */
+# endif
+# if defined(FEAT_XIM) && !defined(LINT)
+	Error: You should select only ONE of XIM and HANGUL INPUT
+# endif
+#endif
+#if defined(FEAT_HANGULIN) || defined(FEAT_XIM)
+/* # define X_LOCALE */			/* for OS with incomplete locale
+					   support, like old linux versions. */
+/* # define SLOW_XSERVER */		/* for extremely slow X server */
+#endif
+
+/*
+ * +xfontset		X fontset support.  For outputting wide characters.
+ */
+#ifndef FEAT_XFONTSET
+# if defined(FEAT_MBYTE) && defined(HAVE_X11) && !defined(HAVE_GTK2)
+#  define FEAT_XFONTSET
+# else
+/* #  define FEAT_XFONTSET */
+# endif
+#endif
+
+/*
+ * +libcall		libcall() function
+ */
+/* Using dlopen() also requires dlsym() to be available. */
+#if defined(HAVE_DLOPEN) && defined(HAVE_DLSYM)
+# define USE_DLOPEN
+#endif
+#if defined(FEAT_EVAL) && (defined(WIN3264) || ((defined(UNIX) || defined(VMS)) \
+	&& (defined(USE_DLOPEN) || defined(HAVE_SHL_LOAD))))
+# define FEAT_LIBCALL
+#endif
+
+/*
+ * +scrollbind		synchronization of split windows
+ */
+#if defined(FEAT_NORMAL) && defined(FEAT_WINDOWS)
+# define FEAT_SCROLLBIND
+#endif
+
+/*
+ * +menu		":menu" command
+ */
+#ifdef FEAT_NORMAL
+# define FEAT_MENU
+# ifdef FEAT_GUI_W32
+#  define FEAT_TEAROFF
+# endif
+#endif
+
+/* There are two ways to use XPM. */
+#if (defined(HAVE_XM_XPMP_H) && defined(FEAT_GUI_MOTIF)) \
+		|| defined(HAVE_X11_XPM_H)
+# define HAVE_XPM 1
+#endif
+
+/*
+ * +toolbar		Include code for a toolbar (for the Win32 GUI, GTK
+ *			always has it).  But only if menus are enabled.
+ */
+#if defined(FEAT_NORMAL) && defined(FEAT_MENU) \
+	&& (defined(FEAT_GUI_GTK) \
+		|| defined(FEAT_GUI_MSWIN) \
+		|| ((defined(FEAT_GUI_MOTIF) || defined(FEAT_GUI_ATHENA)) \
+			&& defined(HAVE_XPM)) \
+		|| defined(FEAT_GUI_PHOTON))
+# define FEAT_TOOLBAR
+#endif
+
+
+#if defined(FEAT_TOOLBAR) && !defined(FEAT_MENU)
+# define FEAT_MENU
+#endif
+
+/*
+ * GUI tabline
+ */
+#if defined(FEAT_WINDOWS) && defined(FEAT_NORMAL) \
+    && (defined(FEAT_GUI_GTK) \
+	|| (defined(FEAT_GUI_MOTIF) && defined(HAVE_XM_NOTEBOOK_H)) \
+	|| defined(FEAT_GUI_MAC) \
+	|| (defined(FEAT_GUI_MSWIN) && (!defined(_MSC_VER) || _MSC_VER > 1020)))
+# define FEAT_GUI_TABLINE
+#endif
+
+/*
+ * +browse		":browse" command.
+ */
+#if defined(FEAT_NORMAL) && (defined(FEAT_GUI_MSWIN) || defined(FEAT_GUI_MOTIF) || defined(FEAT_GUI_ATHENA) || defined(FEAT_GUI_GTK) || defined(FEAT_GUI_PHOTON) || defined(FEAT_GUI_MAC))
+# define FEAT_BROWSE
+#endif
+
+/*
+ * +dialog_gui		Use GUI dialog.
+ * +dialog_con		May use Console dialog.
+ *			When none of these defined there is no dialog support.
+ */
+#ifdef FEAT_NORMAL
+# if ((defined(FEAT_GUI_ATHENA) || defined(FEAT_GUI_MOTIF)) \
+		&& defined(HAVE_X11_XPM_H)) \
+	|| defined(FEAT_GUI_GTK) \
+	|| defined(FEAT_GUI_PHOTON) \
+	|| defined(FEAT_GUI_MSWIN) \
+	|| defined(FEAT_GUI_MAC)
+#  define FEAT_CON_DIALOG
+#  define FEAT_GUI_DIALOG
+# else
+#  define FEAT_CON_DIALOG
+# endif
+#endif
+#if !defined(FEAT_GUI_DIALOG) && (defined(FEAT_GUI_MOTIF) \
+	|| defined(FEAT_GUI_ATHENA) || defined(FEAT_GUI_GTK))
+/* need a dialog to show error messages when starting from the desktop */
+# define FEAT_GUI_DIALOG
+#endif
+#if defined(FEAT_GUI_DIALOG) && \
+	(defined(FEAT_GUI_MOTIF) || defined(FEAT_GUI_ATHENA) \
+	 || defined(FEAT_GUI_GTK) || defined(FEAT_GUI_MSWIN) \
+	 || defined(FEAT_GUI_PHOTON) || defined(FEAT_GUI_MAC))
+# define FEAT_GUI_TEXTDIALOG
+#endif
+
+/* Mac specific thing: Codewarrior interface. */
+#ifdef FEAT_GUI_MAC
+# define FEAT_CW_EDITOR
+#endif
+
+/*
+ * Preferences:
+ * ============
+ */
+
+/*
+ * +writebackup		'writebackup' is default on:
+ *			Use a backup file while overwriting a file.  But it's
+ *			deleted again when 'backup' is not set.  Changing this
+ *			is strongly discouraged: You can loose all your
+ *			changes when the computer crashes while writing the
+ *			file.
+ *			VMS note: It does work on VMS as well, but because of
+ *			version handling it does not have any purpose.
+ *			Overwrite will write to the new version.
+ */
+#ifndef VMS
+# define FEAT_WRITEBACKUP
+#endif
+
+/*
+ * +xterm_save		The t_ti and t_te entries for the builtin xterm will
+ *			be set to save the screen when starting Vim and
+ *			restoring it when exiting.
+ */
+/* #define FEAT_XTERM_SAVE */
+
+/*
+ * DEBUG		Output a lot of debugging garbage.
+ */
+/* #define DEBUG */
+
+/*
+ * STARTUPTIME		Time the startup process.  Writes a "vimstartup" file
+ *			with timestamps.
+ */
+/* #define STARTUPTIME "vimstartup" */
+
+/*
+ * MEM_PROFILE		Debugging of memory allocation and freeing.
+ */
+/* #define MEM_PROFILE */
+
+/*
+ * VIMRC_FILE		Name of the .vimrc file in current dir.
+ */
+/* #define VIMRC_FILE	".vimrc" */
+
+/*
+ * EXRC_FILE		Name of the .exrc file in current dir.
+ */
+/* #define EXRC_FILE	".exrc" */
+
+/*
+ * GVIMRC_FILE		Name of the .gvimrc file in current dir.
+ */
+/* #define GVIMRC_FILE	".gvimrc" */
+
+/*
+ * SESSION_FILE		Name of the default ":mksession" file.
+ */
+#define SESSION_FILE	"Session.vim"
+
+/*
+ * USR_VIMRC_FILE	Name of the user .vimrc file.
+ * USR_VIMRC_FILE2	Name of alternate user .vimrc file.
+ * USR_VIMRC_FILE3	Name of alternate user .vimrc file.
+ */
+/* #define USR_VIMRC_FILE	"~/foo/.vimrc" */
+/* #define USR_VIMRC_FILE2	"~/bar/.vimrc" */
+/* #define USR_VIMRC_FILE3	"$VIM/.vimrc" */
+
+/*
+ * EVIM_FILE		Name of the evim.vim script file
+ */
+/* #define EVIM_FILE		"$VIMRUNTIME/evim.vim" */
+
+/*
+ * USR_EXRC_FILE	Name of the user .exrc file.
+ * USR_EXRC_FILE2	Name of the alternate user .exrc file.
+ */
+/* #define USR_EXRC_FILE	"~/foo/.exrc" */
+/* #define USR_EXRC_FILE2	"~/bar/.exrc" */
+
+/*
+ * USR_GVIMRC_FILE	Name of the user .gvimrc file.
+ * USR_GVIMRC_FILE2	Name of the alternate user .gvimrc file.
+ */
+/* #define USR_GVIMRC_FILE	"~/foo/.gvimrc" */
+/* #define USR_GVIMRC_FILE2	"~/bar/.gvimrc" */
+/* #define USR_GVIMRC_FILE3	"$VIM/.gvimrc" */
+
+/*
+ * SYS_VIMRC_FILE	Name of the system-wide .vimrc file.
+ */
+/* #define SYS_VIMRC_FILE	"/etc/vimrc" */
+
+/*
+ * SYS_GVIMRC_FILE	Name of the system-wide .gvimrc file.
+ */
+/* #define SYS_GVIMRC_FILE	"/etc/gvimrc" */
+
+/*
+ * DFLT_HELPFILE	Name of the help file.
+ */
+/* # define DFLT_HELPFILE	"$VIMRUNTIME/doc/help.txt.gz" */
+
+/*
+ * File names for:
+ * FILETYPE_FILE	switch on file type detection
+ * FTPLUGIN_FILE	switch on loading filetype plugin files
+ * INDENT_FILE		switch on loading indent files
+ * FTOFF_FILE		switch off file type detection
+ * FTPLUGOF_FILE	switch off loading settings files
+ * INDOFF_FILE		switch off loading indent files
+ */
+/* # define FILETYPE_FILE	"filetype.vim" */
+/* # define FTPLUGIN_FILE	"ftplugin.vim" */
+/* # define INDENT_FILE		"indent.vim" */
+/* # define FTOFF_FILE		"ftoff.vim" */
+/* # define FTPLUGOF_FILE	"ftplugof.vim" */
+/* # define INDOFF_FILE		"indoff.vim" */
+
+/*
+ * SYS_MENU_FILE	Name of the default menu.vim file.
+ */
+/* # define SYS_MENU_FILE	"$VIMRUNTIME/menu.vim" */
+
+/*
+ * SYS_OPTWIN_FILE	Name of the default optwin.vim file.
+ */
+#ifndef SYS_OPTWIN_FILE
+# define SYS_OPTWIN_FILE	"$VIMRUNTIME/optwin.vim"
+#endif
+
+/*
+ * SYNTAX_FNAME		Name of a syntax file, where %s is the syntax name.
+ */
+/* #define SYNTAX_FNAME	"/foo/%s.vim" */
+
+/*
+ * RUNTIME_DIRNAME	Generic name for the directory of the runtime files.
+ */
+#ifndef RUNTIME_DIRNAME
+# define RUNTIME_DIRNAME "runtime"
+#endif
+
+/*
+ * RUNTIME_GLOBAL	Directory name for global Vim runtime directory.
+ *			Don't define this if the preprocessor can't handle
+ *			string concatenation.
+ *			Also set by "--with-global-runtime" configure argument.
+ */
+/* #define RUNTIME_GLOBAL "/etc/vim" */
+
+/*
+ * MODIFIED_BY		Name of who modified Vim.  Required when distributing
+ *			a modifed version of Vim.
+ *			Also from the "--with-modified-by" configure argument.
+ */
+/* #define MODIFIED_BY "John Doe" */
+
+/*
+ * Machine dependent:
+ * ==================
+ */
+
+/*
+ * +fork		Unix only: fork() support (detected by configure)
+ * +system		Use system() instead of fork/exec for starting a
+ *			shell.  Doesn't work for the GUI!
+ */
+/* #define USE_SYSTEM */
+
+/*
+ * +X11			Unix only.  Include code for xterm title saving and X
+ *			clipboard.  Only works if HAVE_X11 is also defined.
+ */
+#if (defined(FEAT_NORMAL) || defined(FEAT_GUI_MOTIF) || defined(FEAT_GUI_ATHENA))
+# define WANT_X11
+#endif
+
+/*
+ * XSMP - X11 Session Management Protocol
+ * It may be preferred to disable this if the GUI supports it (e.g.,
+ * GNOME/KDE) and implement save-yourself etc. through that, but it may also
+ * be cleaner to have all SM-aware vims do the same thing (libSM does not
+ * depend upon X11).
+ * If your GUI wants to support SM itself, change this ifdef.
+ * I'm assuming that any X11 implementation will cope with this for now.
+ */
+#if defined(HAVE_X11) && defined(WANT_X11) && defined(HAVE_X11_SM_SMLIB_H)
+# define USE_XSMP
+#endif
+#if defined(USE_XSMP_INTERACT) && !defined(USE_XSMP)
+# undef USE_XSMP_INTERACT
+#endif
+
+/*
+ * +mouse_xterm		Unix only: Include code for xterm mouse handling.
+ * +mouse_dec		idem, for Dec mouse handling.
+ * +mouse_jsbterm	idem, for Jsbterm mouse handling.
+ * +mouse_netterm	idem, for Netterm mouse handling.
+ * (none)		MS-DOS mouse support.
+ * +mouse_gpm		Unix only: Include code for Linux console mouse
+ *			handling.
+ * +mouse_pterm		PTerm mouse support for QNX
+ * +mouse		Any mouse support (any of the above enabled).
+ */
+/* OS/2 and Amiga console have no mouse support */
+#if !defined(AMIGA) && !defined(OS2)
+# ifdef FEAT_NORMAL
+#  define FEAT_MOUSE_XTERM
+# endif
+# ifdef FEAT_BIG
+#  define FEAT_MOUSE_NET
+# endif
+# ifdef FEAT_BIG
+#  define FEAT_MOUSE_DEC
+# endif
+# if defined(FEAT_NORMAL) && (defined(MSDOS) || defined(WIN3264))
+#  define DOS_MOUSE
+# endif
+# if defined(FEAT_NORMAL) && defined(__QNX__)
+#  define FEAT_MOUSE_PTERM
+# endif
+#endif
+
+#if defined(FEAT_NORMAL) && defined(HAVE_GPM)
+# define FEAT_MOUSE_GPM
+#endif
+/* Define FEAT_MOUSE when any of the above is defined or FEAT_GUI. */
+#if !defined(FEAT_MOUSE_TTY) && (defined(FEAT_MOUSE_XTERM) \
+	|| defined(FEAT_MOUSE_NET) || defined(FEAT_MOUSE_DEC) \
+	|| defined(DOS_MOUSE) || defined(FEAT_MOUSE_GPM) \
+	|| defined(FEAT_MOUSE_JSB) || defined(FEAT_MOUSE_PTERM))
+# define FEAT_MOUSE_TTY		/* include non-GUI mouse support */
+#endif
+#if !defined(FEAT_MOUSE) && (defined(FEAT_MOUSE_TTY) || defined(FEAT_GUI))
+# define FEAT_MOUSE		/* include generic mouse support */
+#endif
+
+/*
+ * +clipboard		Clipboard support.  Always used for the GUI.
+ * +xterm_clipboard	Unix only: Include code for handling the clipboard
+ *			in an xterm like in the GUI.
+ */
+#ifdef FEAT_GUI
+# ifndef FEAT_CLIPBOARD
+#  define FEAT_CLIPBOARD
+#  ifndef FEAT_VISUAL
+#   define FEAT_VISUAL
+#  endif
+# endif
+#endif
+
+#if defined(FEAT_NORMAL) && defined(FEAT_VISUAL) \
+	&& (defined(UNIX) || defined(VMS)) \
+	&& defined(WANT_X11) && defined(HAVE_X11)
+# define FEAT_XCLIPBOARD
+# ifndef FEAT_CLIPBOARD
+#  define FEAT_CLIPBOARD
+# endif
+#endif
+
+#if defined(FEAT_NORMAL) && defined(FEAT_VISUAL) \
+    && defined(PLAN9)
+# define FEAT_CLIPBOARD
+#endif
+
+/*
+ * +dnd		Drag'n'drop support.  Always used for the GTK+ GUI.
+ */
+#if defined(FEAT_CLIPBOARD) && defined(FEAT_GUI_GTK)
+# define FEAT_DND
+#endif
+
+#if defined(FEAT_GUI_MSWIN) && defined(FEAT_SMALL)
+# define MSWIN_FIND_REPLACE	/* include code for find/replace dialog */
+# define MSWIN_FR_BUFSIZE 256
+#endif
+
+#if defined(FEAT_GUI_GTK) || defined(FEAT_GUI_MOTIF) \
+	|| defined(MSWIN_FIND_REPLACE)
+# define FIND_REPLACE_DIALOG 1
+#endif
+
+/*
+ * +clientserver	Remote control via the remote_send() function
+ *			and the --remote argument
+ */
+#if (defined(WIN32) || defined(FEAT_XCLIPBOARD)) && defined(FEAT_EVAL)
+# define FEAT_CLIENTSERVER
+#endif
+
+/*
+ * +termresponse	send t_RV to obtain terminal response.  Used for xterm
+ *			to check if mouse dragging can be used and if term
+ *			codes can be obtained.
+ */
+#if (defined(FEAT_NORMAL) || defined(FEAT_MOUSE)) && defined(HAVE_TGETENT)
+# define FEAT_TERMRESPONSE
+#endif
+
+/*
+ * cursor shape		Adjust the shape of the cursor to the mode.
+ * mouse shape		Adjust the shape of the mouse pointer to the mode.
+ */
+#ifdef FEAT_NORMAL
+/* MS-DOS console and Win32 console can change cursor shape */
+# if defined(MSDOS) || (defined(WIN3264) && !defined(FEAT_GUI_W32))
+#  define MCH_CURSOR_SHAPE
+# endif
+# if defined(FEAT_GUI_W32) || defined(FEAT_GUI_W16) || defined(FEAT_GUI_MOTIF) \
+	|| defined(FEAT_GUI_ATHENA) || defined(FEAT_GUI_GTK) \
+	|| defined(FEAT_GUI_PHOTON)
+#  define FEAT_MOUSESHAPE
+# endif
+#endif
+
+/* GUI and some consoles can change the shape of the cursor.  The code is also
+ * needed for the 'mouseshape' option. */
+#if defined(FEAT_GUI) || defined(MCH_CURSOR_SHAPE) || defined(FEAT_MOUSESHAPE) \
+	    || (defined(UNIX) && defined(FEAT_NORMAL))
+# define CURSOR_SHAPE
+#endif
+
+#if defined(FEAT_MZSCHEME) && (defined(FEAT_GUI_W32) || defined(FEAT_GUI_GTK)    \
+	|| defined(FEAT_GUI_MOTIF) || defined(FEAT_GUI_ATHENA)	\
+	|| defined(FEAT_GUI_MAC))
+# define MZSCHEME_GUI_THREADS
+#endif
+
+/*
+ * +ARP			Amiga only. Use arp.library, DOS 2.0 is not required.
+ */
+#if !defined(NO_ARP) && !defined(__amigaos4__)
+# define FEAT_ARP
+#endif
+
+/*
+ * +GUI_Athena		To compile Vim with or without the GUI (gvim) you have
+ * +GUI_Motif		to edit the Makefile.
+ */
+
+/*
+ * +ole			Win32 OLE automation: Use Makefile.ovc.
+ */
+
+/*
+ * These features can only be included by using a configure argument.  See the
+ * Makefile for a line to uncomment.
+ * +mzscheme		MzScheme interface: "--enable-mzscheme"
+ * +perl		Perl interface: "--enable-perlinterp"
+ * +python		Python interface: "--enable-pythoninterp"
+ * +tcl			TCL interface: "--enable-tclinterp"
+ * +sniff		Sniff interface: "--enable-sniff"
+ * +sun_workshop	Sun Workshop integration
+ * +netbeans_intg	Netbeans integration
+ */
+
+/*
+ * These features are automatically detected:
+ * +terminfo
+ * +tgetent
+ */
+
+/*
+ * The Sun Workshop features currently only work with Motif.
+ */
+#if !defined(FEAT_GUI_MOTIF) && defined(FEAT_SUN_WORKSHOP)
+# undef FEAT_SUN_WORKSHOP
+#endif
+
+/*
+ * The Netbeans features currently only work with Motif and GTK and Win32.
+ * It also requires +listcmds and +eval.
+ */
+#if ((!defined(FEAT_GUI_MOTIF) && !defined(FEAT_GUI_GTK) && !defined(FEAT_GUI_W32)) \
+		|| !defined(FEAT_LISTCMDS) || !defined(FEAT_EVAL)) \
+	&& defined(FEAT_NETBEANS_INTG)
+# undef FEAT_NETBEANS_INTG
+#endif
+
+/*
+ * +signs		Allow signs to be displayed to the left of text lines.
+ *			Adds the ":sign" command.
+ */
+#if defined(FEAT_BIG) || defined(FEAT_SUN_WORKSHOP) \
+	    || defined(FEAT_NETBEANS_INTG)
+# define FEAT_SIGNS
+# if ((defined(FEAT_GUI_MOTIF) || defined(FEAT_GUI_ATHENA)) \
+		&& defined(HAVE_X11_XPM_H)) \
+	|| defined(FEAT_GUI_GTK) \
+	|| (defined(WIN32) && defined(FEAT_GUI))
+#  define FEAT_SIGN_ICONS
+# endif
+#endif
+
+/*
+ * +balloon_eval	Allow balloon expression evaluation. Used with a
+ *			debugger and for tooltips.
+ *			Only for GUIs where it was implemented.
+ */
+#if (defined(FEAT_GUI_MOTIF) || defined(FEAT_GUI_ATHENA) \
+	|| defined(FEAT_GUI_GTK) || defined(FEAT_GUI_W32)) \
+	&& (   ((defined(FEAT_TOOLBAR) || defined(FEAT_GUI_TABLINE)) \
+		&& !defined(FEAT_GUI_GTK) && !defined(FEAT_GUI_W32)) \
+	    || defined(FEAT_SUN_WORKSHOP) \
+	    || defined(FEAT_NETBEANS_INTG) || defined(FEAT_EVAL))
+# define FEAT_BEVAL
+# if !defined(FEAT_XFONTSET) && !defined(FEAT_GUI_GTK) \
+	&& !defined(FEAT_GUI_W32)
+#  define FEAT_XFONTSET
+# endif
+#endif
+
+#if defined(FEAT_BEVAL) && (defined(FEAT_GUI_MOTIF) || defined(FEAT_GUI_ATHENA))
+# define FEAT_BEVAL_TIP		/* balloon eval used for toolbar tooltip */
+#endif
+
+/* both Motif and Athena are X11 and share some code */
+#if defined(FEAT_GUI_MOTIF) || defined(FEAT_GUI_ATHENA)
+# define FEAT_GUI_X11
+#endif
+
+#if defined(FEAT_SUN_WORKSHOP) || defined(FEAT_NETBEANS_INTG)
+/*
+ * The following features are (currently) only used by Sun Visual WorkShop 6
+ * and NetBeans. These features could be used with other integrations with
+ * debuggers so I've used separate feature defines.
+ */
+# if !defined(FEAT_MENU)
+#  define FEAT_MENU
+# endif
+#endif
+
+#if defined(FEAT_SUN_WORKSHOP)
+/*
+ *			Use an alternative method of X input for a secondary
+ *			command input.
+ */
+# define ALT_X_INPUT
+
+/*
+ * +footer		Motif only: Add a message area at the bottom of the
+ *			main window area.
+ */
+# define FEAT_FOOTER
+
+#endif
+
+/*
+ * +autochdir		'autochdir' option.
+ */
+#if defined(FEAT_SUN_WORKSHOP) || defined(FEAT_NETBEANS_INTG) \
+	    || defined(FEAT_BIG)
+# define FEAT_AUTOCHDIR
+#endif
--- /dev/null
+++ b/fileio.c
@@ -1,0 +1,9519 @@
+/* vi:set ts=8 sts=4 sw=4:
+ *
+ * VIM - Vi IMproved	by Bram Moolenaar
+ *
+ * Do ":help uganda"  in Vim to read copying and usage conditions.
+ * Do ":help credits" in Vim to see a list of people who contributed.
+ * See README.txt for an overview of the Vim source code.
+ */
+
+/*
+ * fileio.c: read from and write to a file
+ */
+
+#if defined(MSDOS) || defined(WIN16) || defined(WIN32) || defined(_WIN64)
+# include "vimio.h"	/* for lseek(), must be before vim.h */
+#endif
+
+#if defined __EMX__
+# include "vimio.h"	/* for mktemp(), CJW 1997-12-03 */
+#endif
+
+#include "vim.h"
+
+#ifdef HAVE_FCNTL_H
+# include <fcntl.h>
+#endif
+
+#ifdef __TANDEM
+# include <limits.h>		/* for SSIZE_MAX */
+#endif
+
+#if defined(HAVE_UTIME) && defined(HAVE_UTIME_H)
+# include <utime.h>		/* for struct utimbuf */
+#endif
+
+#define BUFSIZE		8192	/* size of normal write buffer */
+#define SMBUFSIZE	256	/* size of emergency write buffer */
+
+#ifdef FEAT_CRYPT
+# define CRYPT_MAGIC		"VimCrypt~01!"	/* "01" is the version nr */
+# define CRYPT_MAGIC_LEN	12		/* must be multiple of 4! */
+#endif
+
+/* Is there any system that doesn't have access()? */
+#define USE_MCH_ACCESS
+
+#ifdef FEAT_MBYTE
+static char_u *next_fenc __ARGS((char_u **pp));
+# ifdef FEAT_EVAL
+static char_u *readfile_charconvert __ARGS((char_u *fname, char_u *fenc, int *fdp));
+# endif
+#endif
+#ifdef FEAT_VIMINFO
+static void check_marks_read __ARGS((void));
+#endif
+#ifdef FEAT_CRYPT
+static char_u *check_for_cryptkey __ARGS((char_u *cryptkey, char_u *ptr, long *sizep, long *filesizep, int newfile));
+#endif
+#ifdef UNIX
+static void set_file_time __ARGS((char_u *fname, time_t atime, time_t mtime));
+#endif
+static int set_rw_fname __ARGS((char_u *fname, char_u *sfname));
+static int msg_add_fileformat __ARGS((int eol_type));
+static void msg_add_eol __ARGS((void));
+static int check_mtime __ARGS((buf_T *buf, struct stat *s));
+static int time_differs __ARGS((long t1, long t2));
+#ifdef FEAT_AUTOCMD
+static int apply_autocmds_exarg __ARGS((event_T event, char_u *fname, char_u *fname_io, int force, buf_T *buf, exarg_T *eap));
+static int au_find_group __ARGS((char_u *name));
+
+# define AUGROUP_DEFAULT    -1	    /* default autocmd group */
+# define AUGROUP_ERROR	    -2	    /* errornouse autocmd group */
+# define AUGROUP_ALL	    -3	    /* all autocmd groups */
+#endif
+
+#if defined(FEAT_CRYPT) || defined(FEAT_MBYTE)
+# define HAS_BW_FLAGS
+# define FIO_LATIN1	0x01	/* convert Latin1 */
+# define FIO_UTF8	0x02	/* convert UTF-8 */
+# define FIO_UCS2	0x04	/* convert UCS-2 */
+# define FIO_UCS4	0x08	/* convert UCS-4 */
+# define FIO_UTF16	0x10	/* convert UTF-16 */
+# ifdef WIN3264
+#  define FIO_CODEPAGE	0x20	/* convert MS-Windows codepage */
+#  define FIO_PUT_CP(x) (((x) & 0xffff) << 16)	/* put codepage in top word */
+#  define FIO_GET_CP(x)	(((x)>>16) & 0xffff)	/* get codepage from top word */
+# endif
+# ifdef MACOS_X
+#  define FIO_MACROMAN	0x20	/* convert MacRoman */
+# endif
+# define FIO_ENDIAN_L	0x80	/* little endian */
+# define FIO_ENCRYPTED	0x1000	/* encrypt written bytes */
+# define FIO_NOCONVERT	0x2000	/* skip encoding conversion */
+# define FIO_UCSBOM	0x4000	/* check for BOM at start of file */
+# define FIO_ALL	-1	/* allow all formats */
+#endif
+
+/* When converting, a read() or write() may leave some bytes to be converted
+ * for the next call.  The value is guessed... */
+#define CONV_RESTLEN 30
+
+/* We have to guess how much a sequence of bytes may expand when converting
+ * with iconv() to be able to allocate a buffer. */
+#define ICONV_MULT 8
+
+/*
+ * Structure to pass arguments from buf_write() to buf_write_bytes().
+ */
+struct bw_info
+{
+    int		bw_fd;		/* file descriptor */
+    char_u	*bw_buf;	/* buffer with data to be written */
+    int		bw_len;	/* lenght of data */
+#ifdef HAS_BW_FLAGS
+    int		bw_flags;	/* FIO_ flags */
+#endif
+#ifdef FEAT_MBYTE
+    char_u	bw_rest[CONV_RESTLEN]; /* not converted bytes */
+    int		bw_restlen;	/* nr of bytes in bw_rest[] */
+    int		bw_first;	/* first write call */
+    char_u	*bw_conv_buf;	/* buffer for writing converted chars */
+    int		bw_conv_buflen; /* size of bw_conv_buf */
+    int		bw_conv_error;	/* set for conversion error */
+# ifdef USE_ICONV
+    iconv_t	bw_iconv_fd;	/* descriptor for iconv() or -1 */
+# endif
+#endif
+};
+
+static int  buf_write_bytes __ARGS((struct bw_info *ip));
+
+#ifdef FEAT_MBYTE
+static linenr_T readfile_linenr __ARGS((linenr_T linecnt, char_u *p, char_u *endp));
+static int ucs2bytes __ARGS((unsigned c, char_u **pp, int flags));
+static int same_encoding __ARGS((char_u *a, char_u *b));
+static int get_fio_flags __ARGS((char_u *ptr));
+static char_u *check_for_bom __ARGS((char_u *p, long size, int *lenp, int flags));
+static int make_bom __ARGS((char_u *buf, char_u *name));
+# ifdef WIN3264
+static int get_win_fio_flags __ARGS((char_u *ptr));
+# endif
+# ifdef MACOS_X
+static int get_mac_fio_flags __ARGS((char_u *ptr));
+# endif
+#endif
+static int move_lines __ARGS((buf_T *frombuf, buf_T *tobuf));
+
+
+    void
+filemess(buf, name, s, attr)
+    buf_T	*buf;
+    char_u	*name;
+    char_u	*s;
+    int		attr;
+{
+    int		msg_scroll_save;
+
+    if (msg_silent != 0)
+	return;
+    msg_add_fname(buf, name);	    /* put file name in IObuff with quotes */
+    /* If it's extremely long, truncate it. */
+    if (STRLEN(IObuff) > IOSIZE - 80)
+	IObuff[IOSIZE - 80] = NUL;
+    STRCAT(IObuff, s);
+    /*
+     * For the first message may have to start a new line.
+     * For further ones overwrite the previous one, reset msg_scroll before
+     * calling filemess().
+     */
+    msg_scroll_save = msg_scroll;
+    if (shortmess(SHM_OVERALL) && !exiting && p_verbose == 0)
+	msg_scroll = FALSE;
+    if (!msg_scroll)	/* wait a bit when overwriting an error msg */
+	check_for_delay(FALSE);
+    msg_start();
+    msg_scroll = msg_scroll_save;
+    msg_scrolled_ign = TRUE;
+    /* may truncate the message to avoid a hit-return prompt */
+    msg_outtrans_attr(msg_may_trunc(FALSE, IObuff), attr);
+    msg_clr_eos();
+    out_flush();
+    msg_scrolled_ign = FALSE;
+}
+
+/*
+ * Read lines from file "fname" into the buffer after line "from".
+ *
+ * 1. We allocate blocks with lalloc, as big as possible.
+ * 2. Each block is filled with characters from the file with a single read().
+ * 3. The lines are inserted in the buffer with ml_append().
+ *
+ * (caller must check that fname != NULL, unless READ_STDIN is used)
+ *
+ * "lines_to_skip" is the number of lines that must be skipped
+ * "lines_to_read" is the number of lines that are appended
+ * When not recovering lines_to_skip is 0 and lines_to_read MAXLNUM.
+ *
+ * flags:
+ * READ_NEW	starting to edit a new buffer
+ * READ_FILTER	reading filter output
+ * READ_STDIN	read from stdin instead of a file
+ * READ_BUFFER	read from curbuf instead of a file (converting after reading
+ *		stdin)
+ * READ_DUMMY	read into a dummy buffer (to check if file contents changed)
+ *
+ * return FAIL for failure, OK otherwise
+ */
+    int
+readfile(fname, sfname, from, lines_to_skip, lines_to_read, eap, flags)
+    char_u	*fname;
+    char_u	*sfname;
+    linenr_T	from;
+    linenr_T	lines_to_skip;
+    linenr_T	lines_to_read;
+    exarg_T	*eap;			/* can be NULL! */
+    int		flags;
+{
+    int		fd = 0;
+    int		newfile = (flags & READ_NEW);
+    int		set_options = newfile || (eap != NULL && eap->read_edit);
+    int		check_readonly;
+    int		filtering = (flags & READ_FILTER);
+    int		read_stdin = (flags & READ_STDIN);
+    int		read_buffer = (flags & READ_BUFFER);
+    linenr_T	read_buf_lnum = 1;	/* next line to read from curbuf */
+    colnr_T	read_buf_col = 0;	/* next char to read from this line */
+    char_u	c;
+    linenr_T	lnum = from;
+    char_u	*ptr = NULL;		/* pointer into read buffer */
+    char_u	*buffer = NULL;		/* read buffer */
+    char_u	*new_buffer = NULL;	/* init to shut up gcc */
+    char_u	*line_start = NULL;	/* init to shut up gcc */
+    int		wasempty;		/* buffer was empty before reading */
+    colnr_T	len;
+    long	size = 0;
+    char_u	*p;
+    long	filesize = 0;
+    int		skip_read = FALSE;
+#ifdef FEAT_CRYPT
+    char_u	*cryptkey = NULL;
+#endif
+    int		split = 0;		/* number of split lines */
+#define UNKNOWN	 0x0fffffff		/* file size is unknown */
+    linenr_T	linecnt;
+    int		error = FALSE;		/* errors encountered */
+    int		ff_error = EOL_UNKNOWN; /* file format with errors */
+    long	linerest = 0;		/* remaining chars in line */
+#ifdef UNIX
+    int		perm = 0;
+    int		swap_mode = -1;		/* protection bits for swap file */
+#else
+    int		perm;
+#endif
+    int		fileformat = 0;		/* end-of-line format */
+    int		keep_fileformat = FALSE;
+    struct stat	st;
+    int		file_readonly;
+    linenr_T	skip_count = 0;
+    linenr_T	read_count = 0;
+    int		msg_save = msg_scroll;
+    linenr_T	read_no_eol_lnum = 0;   /* non-zero lnum when last line of
+					 * last read was missing the eol */
+    int		try_mac = (vim_strchr(p_ffs, 'm') != NULL);
+    int		try_dos = (vim_strchr(p_ffs, 'd') != NULL);
+    int		try_unix = (vim_strchr(p_ffs, 'x') != NULL);
+    int		file_rewind = FALSE;
+#ifdef FEAT_MBYTE
+    int		can_retry;
+    linenr_T	conv_error = 0;		/* line nr with conversion error */
+    linenr_T	illegal_byte = 0;	/* line nr with illegal byte */
+    int		keep_dest_enc = FALSE;	/* don't retry when char doesn't fit
+					   in destination encoding */
+    int		bad_char_behavior = BAD_REPLACE;
+					/* BAD_KEEP, BAD_DROP or character to
+					 * replace with */
+    char_u	*tmpname = NULL;	/* name of 'charconvert' output file */
+    int		fio_flags = 0;
+    char_u	*fenc;			/* fileencoding to use */
+    int		fenc_alloced;		/* fenc_next is in allocated memory */
+    char_u	*fenc_next = NULL;	/* next item in 'fencs' or NULL */
+    int		advance_fenc = FALSE;
+    long	real_size = 0;
+# ifdef USE_ICONV
+    iconv_t	iconv_fd = (iconv_t)-1;	/* descriptor for iconv() or -1 */
+#  ifdef FEAT_EVAL
+    int		did_iconv = FALSE;	/* TRUE when iconv() failed and trying
+					   'charconvert' next */
+#  endif
+# endif
+    int		converted = FALSE;	/* TRUE if conversion done */
+    int		notconverted = FALSE;	/* TRUE if conversion wanted but it
+					   wasn't possible */
+    char_u	conv_rest[CONV_RESTLEN];
+    int		conv_restlen = 0;	/* nr of bytes in conv_rest[] */
+#endif
+
+    write_no_eol_lnum = 0;	/* in case it was set by the previous read */
+
+    /*
+     * If there is no file name yet, use the one for the read file.
+     * BF_NOTEDITED is set to reflect this.
+     * Don't do this for a read from a filter.
+     * Only do this when 'cpoptions' contains the 'f' flag.
+     */
+    if (curbuf->b_ffname == NULL
+	    && !filtering
+	    && fname != NULL
+	    && vim_strchr(p_cpo, CPO_FNAMER) != NULL
+	    && !(flags & READ_DUMMY))
+    {
+	if (set_rw_fname(fname, sfname) == FAIL)
+	    return FAIL;
+    }
+
+    /* After reading a file the cursor line changes but we don't want to
+     * display the line. */
+    ex_no_reprint = TRUE;
+
+    /* don't display the file info for another buffer now */
+    need_fileinfo = FALSE;
+
+    /*
+     * For Unix: Use the short file name whenever possible.
+     * Avoids problems with networks and when directory names are changed.
+     * Don't do this for MS-DOS, a "cd" in a sub-shell may have moved us to
+     * another directory, which we don't detect.
+     */
+    if (sfname == NULL)
+	sfname = fname;
+#if defined(UNIX) || defined(__EMX__)
+    fname = sfname;
+#endif
+
+#ifdef FEAT_AUTOCMD
+    /*
+     * The BufReadCmd and FileReadCmd events intercept the reading process by
+     * executing the associated commands instead.
+     */
+    if (!filtering && !read_stdin && !read_buffer)
+    {
+	pos_T	    pos;
+
+	pos = curbuf->b_op_start;
+
+	/* Set '[ mark to the line above where the lines go (line 1 if zero). */
+	curbuf->b_op_start.lnum = ((from == 0) ? 1 : from);
+	curbuf->b_op_start.col = 0;
+
+	if (newfile)
+	{
+	    if (apply_autocmds_exarg(EVENT_BUFREADCMD, NULL, sfname,
+							  FALSE, curbuf, eap))
+#ifdef FEAT_EVAL
+		return aborting() ? FAIL : OK;
+#else
+		return OK;
+#endif
+	}
+	else if (apply_autocmds_exarg(EVENT_FILEREADCMD, sfname, sfname,
+							    FALSE, NULL, eap))
+#ifdef FEAT_EVAL
+	    return aborting() ? FAIL : OK;
+#else
+	    return OK;
+#endif
+
+	curbuf->b_op_start = pos;
+    }
+#endif
+
+    if ((shortmess(SHM_OVER) || curbuf->b_help) && p_verbose == 0)
+	msg_scroll = FALSE;	/* overwrite previous file message */
+    else
+	msg_scroll = TRUE;	/* don't overwrite previous file message */
+
+    /*
+     * If the name ends in a path separator, we can't open it.  Check here,
+     * because reading the file may actually work, but then creating the swap
+     * file may destroy it!  Reported on MS-DOS and Win 95.
+     * If the name is too long we might crash further on, quit here.
+     */
+    if (fname != NULL && *fname != NUL)
+    {
+	p = fname + STRLEN(fname);
+	if (after_pathsep(fname, p) || STRLEN(fname) >= MAXPATHL)
+	{
+	    filemess(curbuf, fname, (char_u *)_("Illegal file name"), 0);
+	    msg_end();
+	    msg_scroll = msg_save;
+	    return FAIL;
+	}
+    }
+
+#ifdef UNIX
+    /*
+     * On Unix it is possible to read a directory, so we have to
+     * check for it before the mch_open().
+     */
+    if (!read_stdin && !read_buffer)
+    {
+	perm = mch_getperm(fname);
+	if (perm >= 0 && !S_ISREG(perm)		    /* not a regular file ... */
+# ifdef S_ISFIFO
+		      && !S_ISFIFO(perm)	    /* ... or fifo */
+# endif
+# ifdef S_ISSOCK
+		      && !S_ISSOCK(perm)	    /* ... or socket */
+# endif
+						)
+	{
+	    if (S_ISDIR(perm))
+		filemess(curbuf, fname, (char_u *)_("is a directory"), 0);
+	    else
+		filemess(curbuf, fname, (char_u *)_("is not a file"), 0);
+	    msg_end();
+	    msg_scroll = msg_save;
+	    return FAIL;
+	}
+
+# if defined(MSDOS) || defined(MSWIN) || defined(OS2)
+	/*
+	 * MS-Windows allows opening a device, but we will probably get stuck
+	 * trying to read it.
+	 */
+	if (!p_odev && mch_nodetype(fname) == NODE_WRITABLE)
+	{
+	    filemess(curbuf, fname, (char_u *)_("is a device (disabled with 'opendevice' option"), 0);
+	    msg_end();
+	    msg_scroll = msg_save;
+	    return FAIL;
+	}
+# endif
+    }
+#endif
+
+    /* set default 'fileformat' */
+    if (set_options)
+    {
+	if (eap != NULL && eap->force_ff != 0)
+	    set_fileformat(get_fileformat_force(curbuf, eap), OPT_LOCAL);
+	else if (*p_ffs != NUL)
+	    set_fileformat(default_fileformat(), OPT_LOCAL);
+    }
+
+    /* set or reset 'binary' */
+    if (eap != NULL && eap->force_bin != 0)
+    {
+	int	oldval = curbuf->b_p_bin;
+
+	curbuf->b_p_bin = (eap->force_bin == FORCE_BIN);
+	set_options_bin(oldval, curbuf->b_p_bin, OPT_LOCAL);
+    }
+
+    /*
+     * When opening a new file we take the readonly flag from the file.
+     * Default is r/w, can be set to r/o below.
+     * Don't reset it when in readonly mode
+     * Only set/reset b_p_ro when BF_CHECK_RO is set.
+     */
+    check_readonly = (newfile && (curbuf->b_flags & BF_CHECK_RO));
+    if (check_readonly && !readonlymode)
+	curbuf->b_p_ro = FALSE;
+
+    if (newfile && !read_stdin && !read_buffer)
+    {
+	/* Remember time of file.
+	 * For RISCOS, also remember the filetype.
+	 */
+	if (mch_stat((char *)fname, &st) >= 0)
+	{
+	    buf_store_time(curbuf, &st, fname);
+	    curbuf->b_mtime_read = curbuf->b_mtime;
+
+#if defined(RISCOS) && defined(FEAT_OSFILETYPE)
+	    /* Read the filetype into the buffer local filetype option. */
+	    mch_read_filetype(fname);
+#endif
+#ifdef UNIX
+	    /*
+	     * Use the protection bits of the original file for the swap file.
+	     * This makes it possible for others to read the name of the
+	     * edited file from the swapfile, but only if they can read the
+	     * edited file.
+	     * Remove the "write" and "execute" bits for group and others
+	     * (they must not write the swapfile).
+	     * Add the "read" and "write" bits for the user, otherwise we may
+	     * not be able to write to the file ourselves.
+	     * Setting the bits is done below, after creating the swap file.
+	     */
+	    swap_mode = (st.st_mode & 0644) | 0600;
+#endif
+#ifdef FEAT_CW_EDITOR
+	    /* Get the FSSpec on MacOS
+	     * TODO: Update it properly when the buffer name changes
+	     */
+	    (void)GetFSSpecFromPath(curbuf->b_ffname, &curbuf->b_FSSpec);
+#endif
+#ifdef VMS
+	    curbuf->b_fab_rfm = st.st_fab_rfm;
+	    curbuf->b_fab_rat = st.st_fab_rat;
+	    curbuf->b_fab_mrs = st.st_fab_mrs;
+#endif
+	}
+	else
+	{
+	    curbuf->b_mtime = 0;
+	    curbuf->b_mtime_read = 0;
+	    curbuf->b_orig_size = 0;
+	    curbuf->b_orig_mode = 0;
+	}
+
+	/* Reset the "new file" flag.  It will be set again below when the
+	 * file doesn't exist. */
+	curbuf->b_flags &= ~(BF_NEW | BF_NEW_W);
+    }
+
+/*
+ * for UNIX: check readonly with perm and mch_access()
+ * for RISCOS: same as Unix, otherwise file gets re-datestamped!
+ * for MSDOS and Amiga: check readonly by trying to open the file for writing
+ */
+    file_readonly = FALSE;
+    if (read_stdin)
+    {
+#if defined(MSDOS) || defined(MSWIN) || defined(OS2)
+	/* Force binary I/O on stdin to avoid CR-LF -> LF conversion. */
+	setmode(0, O_BINARY);
+#endif
+    }
+    else if (!read_buffer)
+    {
+#ifdef USE_MCH_ACCESS
+	if (
+# ifdef UNIX
+	    !(perm & 0222) ||
+# endif
+				mch_access((char *)fname, W_OK))
+	    file_readonly = TRUE;
+	fd = mch_open((char *)fname, O_RDONLY | O_EXTRA, 0);
+#else
+	if (!newfile
+		|| readonlymode
+		|| (fd = mch_open((char *)fname, O_RDWR | O_EXTRA, 0)) < 0)
+	{
+	    file_readonly = TRUE;
+	    /* try to open ro */
+	    fd = mch_open((char *)fname, O_RDONLY | O_EXTRA, 0);
+	}
+#endif
+    }
+
+    if (fd < 0)			    /* cannot open at all */
+    {
+#ifndef UNIX
+	int	isdir_f;
+#endif
+	msg_scroll = msg_save;
+#ifndef UNIX
+	/*
+	 * On MSDOS and Amiga we can't open a directory, check here.
+	 */
+	isdir_f = (mch_isdir(fname));
+	perm = mch_getperm(fname);  /* check if the file exists */
+	if (isdir_f)
+	{
+	    filemess(curbuf, sfname, (char_u *)_("is a directory"), 0);
+	    curbuf->b_p_ro = TRUE;	/* must use "w!" now */
+	}
+	else
+#endif
+	    if (newfile)
+	    {
+		if (perm < 0)
+		{
+		    /*
+		     * Set the 'new-file' flag, so that when the file has
+		     * been created by someone else, a ":w" will complain.
+		     */
+		    curbuf->b_flags |= BF_NEW;
+
+		    /* Create a swap file now, so that other Vims are warned
+		     * that we are editing this file.  Don't do this for a
+		     * "nofile" or "nowrite" buffer type. */
+#ifdef FEAT_QUICKFIX
+		    if (!bt_dontwrite(curbuf))
+#endif
+			check_need_swap(newfile);
+		    if (dir_of_file_exists(fname))
+			filemess(curbuf, sfname, (char_u *)_("[New File]"), 0);
+		    else
+			filemess(curbuf, sfname,
+					   (char_u *)_("[New DIRECTORY]"), 0);
+#ifdef FEAT_VIMINFO
+		    /* Even though this is a new file, it might have been
+		     * edited before and deleted.  Get the old marks. */
+		    check_marks_read();
+#endif
+#ifdef FEAT_MBYTE
+		    if (eap != NULL && eap->force_enc != 0)
+		    {
+			/* set forced 'fileencoding' */
+			fenc = enc_canonize(eap->cmd + eap->force_enc);
+			if (fenc != NULL)
+			    set_string_option_direct((char_u *)"fenc", -1,
+						 fenc, OPT_FREE|OPT_LOCAL, 0);
+			vim_free(fenc);
+		    }
+#endif
+#ifdef FEAT_AUTOCMD
+		    apply_autocmds_exarg(EVENT_BUFNEWFILE, sfname, sfname,
+							  FALSE, curbuf, eap);
+#endif
+		    /* remember the current fileformat */
+		    save_file_ff(curbuf);
+
+#if defined(FEAT_AUTOCMD) && defined(FEAT_EVAL)
+		    if (aborting())   /* autocmds may abort script processing */
+			return FAIL;
+#endif
+		    return OK;	    /* a new file is not an error */
+		}
+		else
+		{
+		    filemess(curbuf, sfname, (char_u *)(
+# ifdef EFBIG
+			    (errno == EFBIG) ? _("[File too big]") :
+# endif
+						_("[Permission Denied]")), 0);
+		    curbuf->b_p_ro = TRUE;	/* must use "w!" now */
+		}
+	    }
+
+	return FAIL;
+    }
+
+    /*
+     * Only set the 'ro' flag for readonly files the first time they are
+     * loaded.	Help files always get readonly mode
+     */
+    if ((check_readonly && file_readonly) || curbuf->b_help)
+	curbuf->b_p_ro = TRUE;
+
+    if (set_options)
+    {
+	curbuf->b_p_eol = TRUE;
+	curbuf->b_start_eol = TRUE;
+#ifdef FEAT_MBYTE
+	curbuf->b_p_bomb = FALSE;
+#endif
+    }
+
+    /* Create a swap file now, so that other Vims are warned that we are
+     * editing this file.
+     * Don't do this for a "nofile" or "nowrite" buffer type. */
+#ifdef FEAT_QUICKFIX
+    if (!bt_dontwrite(curbuf))
+#endif
+    {
+	check_need_swap(newfile);
+#ifdef UNIX
+	/* Set swap file protection bits after creating it. */
+	if (swap_mode > 0 && curbuf->b_ml.ml_mfp->mf_fname != NULL)
+	    (void)mch_setperm(curbuf->b_ml.ml_mfp->mf_fname, (long)swap_mode);
+#endif
+    }
+
+#if defined(HAS_SWAP_EXISTS_ACTION)
+    /* If "Quit" selected at ATTENTION dialog, don't load the file */
+    if (swap_exists_action == SEA_QUIT)
+    {
+	if (!read_buffer && !read_stdin)
+	    close(fd);
+	return FAIL;
+    }
+#endif
+
+    ++no_wait_return;	    /* don't wait for return yet */
+
+    /*
+     * Set '[ mark to the line above where the lines go (line 1 if zero).
+     */
+    curbuf->b_op_start.lnum = ((from == 0) ? 1 : from);
+    curbuf->b_op_start.col = 0;
+
+#ifdef FEAT_AUTOCMD
+    if (!read_buffer)
+    {
+	int	m = msg_scroll;
+	int	n = msg_scrolled;
+	buf_T	*old_curbuf = curbuf;
+
+	/*
+	 * The file must be closed again, the autocommands may want to change
+	 * the file before reading it.
+	 */
+	if (!read_stdin)
+	    close(fd);		/* ignore errors */
+
+	/*
+	 * The output from the autocommands should not overwrite anything and
+	 * should not be overwritten: Set msg_scroll, restore its value if no
+	 * output was done.
+	 */
+	msg_scroll = TRUE;
+	if (filtering)
+	    apply_autocmds_exarg(EVENT_FILTERREADPRE, NULL, sfname,
+							  FALSE, curbuf, eap);
+	else if (read_stdin)
+	    apply_autocmds_exarg(EVENT_STDINREADPRE, NULL, sfname,
+							  FALSE, curbuf, eap);
+	else if (newfile)
+	    apply_autocmds_exarg(EVENT_BUFREADPRE, NULL, sfname,
+							  FALSE, curbuf, eap);
+	else
+	    apply_autocmds_exarg(EVENT_FILEREADPRE, sfname, sfname,
+							    FALSE, NULL, eap);
+	if (msg_scrolled == n)
+	    msg_scroll = m;
+
+#ifdef FEAT_EVAL
+	if (aborting())	    /* autocmds may abort script processing */
+	{
+	    --no_wait_return;
+	    msg_scroll = msg_save;
+	    curbuf->b_p_ro = TRUE;	/* must use "w!" now */
+	    return FAIL;
+	}
+#endif
+	/*
+	 * Don't allow the autocommands to change the current buffer.
+	 * Try to re-open the file.
+	 */
+	if (!read_stdin && (curbuf != old_curbuf
+		|| (fd = mch_open((char *)fname, O_RDONLY | O_EXTRA, 0)) < 0))
+	{
+	    --no_wait_return;
+	    msg_scroll = msg_save;
+	    if (fd < 0)
+		EMSG(_("E200: *ReadPre autocommands made the file unreadable"));
+	    else
+		EMSG(_("E201: *ReadPre autocommands must not change current buffer"));
+	    curbuf->b_p_ro = TRUE;	/* must use "w!" now */
+	    return FAIL;
+	}
+    }
+#endif /* FEAT_AUTOCMD */
+
+    /* Autocommands may add lines to the file, need to check if it is empty */
+    wasempty = (curbuf->b_ml.ml_flags & ML_EMPTY);
+
+    if (!recoverymode && !filtering && !(flags & READ_DUMMY))
+    {
+	/*
+	 * Show the user that we are busy reading the input.  Sometimes this
+	 * may take a while.  When reading from stdin another program may
+	 * still be running, don't move the cursor to the last line, unless
+	 * always using the GUI.
+	 */
+	if (read_stdin)
+	{
+#ifndef ALWAYS_USE_GUI
+	    mch_msg(_("Vim: Reading from stdin...\n"));
+#endif
+#ifdef FEAT_GUI
+	    /* Also write a message in the GUI window, if there is one. */
+	    if (gui.in_use && !gui.dying && !gui.starting)
+	    {
+		p = (char_u *)_("Reading from stdin...");
+		gui_write(p, (int)STRLEN(p));
+	    }
+#endif
+	}
+	else if (!read_buffer)
+	    filemess(curbuf, sfname, (char_u *)"", 0);
+    }
+
+    msg_scroll = FALSE;			/* overwrite the file message */
+
+    /*
+     * Set linecnt now, before the "retry" caused by a wrong guess for
+     * fileformat, and after the autocommands, which may change them.
+     */
+    linecnt = curbuf->b_ml.ml_line_count;
+
+#ifdef FEAT_MBYTE
+    /* "++bad=" argument. */
+    if (eap != NULL && eap->bad_char != 0)
+    {
+	bad_char_behavior = eap->bad_char;
+	if (set_options)
+	    curbuf->b_bad_char = eap->bad_char;
+    }
+    else
+	curbuf->b_bad_char = 0;
+
+    /*
+     * Decide which 'encoding' to use or use first.
+     */
+    if (eap != NULL && eap->force_enc != 0)
+    {
+	fenc = enc_canonize(eap->cmd + eap->force_enc);
+	fenc_alloced = TRUE;
+	keep_dest_enc = TRUE;
+    }
+    else if (curbuf->b_p_bin)
+    {
+	fenc = (char_u *)"";		/* binary: don't convert */
+	fenc_alloced = FALSE;
+    }
+    else if (curbuf->b_help)
+    {
+	char_u	    firstline[80];
+	int	    fc;
+
+	/* Help files are either utf-8 or latin1.  Try utf-8 first, if this
+	 * fails it must be latin1.
+	 * Always do this when 'encoding' is "utf-8".  Otherwise only do
+	 * this when needed to avoid [converted] remarks all the time.
+	 * It is needed when the first line contains non-ASCII characters.
+	 * That is only in *.??x files. */
+	fenc = (char_u *)"latin1";
+	c = enc_utf8;
+	if (!c && !read_stdin)
+	{
+	    fc = fname[STRLEN(fname) - 1];
+	    if (TOLOWER_ASC(fc) == 'x')
+	    {
+		/* Read the first line (and a bit more).  Immediately rewind to
+		 * the start of the file.  If the read() fails "len" is -1. */
+		len = vim_read(fd, firstline, 80);
+		lseek(fd, (off_t)0L, SEEK_SET);
+		for (p = firstline; p < firstline + len; ++p)
+		    if (*p >= 0x80)
+		    {
+			c = TRUE;
+			break;
+		    }
+	    }
+	}
+
+	if (c)
+	{
+	    fenc_next = fenc;
+	    fenc = (char_u *)"utf-8";
+
+	    /* When the file is utf-8 but a character doesn't fit in
+	     * 'encoding' don't retry.  In help text editing utf-8 bytes
+	     * doesn't make sense. */
+	    if (!enc_utf8)
+		keep_dest_enc = TRUE;
+	}
+	fenc_alloced = FALSE;
+    }
+    else if (*p_fencs == NUL)
+    {
+	fenc = curbuf->b_p_fenc;	/* use format from buffer */
+	fenc_alloced = FALSE;
+    }
+    else
+    {
+	fenc_next = p_fencs;		/* try items in 'fileencodings' */
+	fenc = next_fenc(&fenc_next);
+	fenc_alloced = TRUE;
+    }
+#endif
+
+    /*
+     * Jump back here to retry reading the file in different ways.
+     * Reasons to retry:
+     * - encoding conversion failed: try another one from "fenc_next"
+     * - BOM detected and fenc was set, need to setup conversion
+     * - "fileformat" check failed: try another
+     *
+     * Variables set for special retry actions:
+     * "file_rewind"	Rewind the file to start reading it again.
+     * "advance_fenc"	Advance "fenc" using "fenc_next".
+     * "skip_read"	Re-use already read bytes (BOM detected).
+     * "did_iconv"	iconv() conversion failed, try 'charconvert'.
+     * "keep_fileformat" Don't reset "fileformat".
+     *
+     * Other status indicators:
+     * "tmpname"	When != NULL did conversion with 'charconvert'.
+     *			Output file has to be deleted afterwards.
+     * "iconv_fd"	When != -1 did conversion with iconv().
+     */
+retry:
+
+    if (file_rewind)
+    {
+	if (read_buffer)
+	{
+	    read_buf_lnum = 1;
+	    read_buf_col = 0;
+	}
+	else if (read_stdin || lseek(fd, (off_t)0L, SEEK_SET) != 0)
+	{
+	    /* Can't rewind the file, give up. */
+	    error = TRUE;
+	    goto failed;
+	}
+	/* Delete the previously read lines. */
+	while (lnum > from)
+	    ml_delete(lnum--, FALSE);
+	file_rewind = FALSE;
+#ifdef FEAT_MBYTE
+	if (set_options)
+	    curbuf->b_p_bomb = FALSE;
+	conv_error = 0;
+#endif
+    }
+
+    /*
+     * When retrying with another "fenc" and the first time "fileformat"
+     * will be reset.
+     */
+    if (keep_fileformat)
+	keep_fileformat = FALSE;
+    else
+    {
+	if (eap != NULL && eap->force_ff != 0)
+	    fileformat = get_fileformat_force(curbuf, eap);
+	else if (curbuf->b_p_bin)
+	    fileformat = EOL_UNIX;		/* binary: use Unix format */
+	else if (*p_ffs == NUL)
+	    fileformat = get_fileformat(curbuf);/* use format from buffer */
+	else
+	    fileformat = EOL_UNKNOWN;		/* detect from file */
+    }
+
+#ifdef FEAT_MBYTE
+# ifdef USE_ICONV
+    if (iconv_fd != (iconv_t)-1)
+    {
+	/* aborted conversion with iconv(), close the descriptor */
+	iconv_close(iconv_fd);
+	iconv_fd = (iconv_t)-1;
+    }
+# endif
+
+    if (advance_fenc)
+    {
+	/*
+	 * Try the next entry in 'fileencodings'.
+	 */
+	advance_fenc = FALSE;
+
+	if (eap != NULL && eap->force_enc != 0)
+	{
+	    /* Conversion given with "++cc=" wasn't possible, read
+	     * without conversion. */
+	    notconverted = TRUE;
+	    conv_error = 0;
+	    if (fenc_alloced)
+		vim_free(fenc);
+	    fenc = (char_u *)"";
+	    fenc_alloced = FALSE;
+	}
+	else
+	{
+	    if (fenc_alloced)
+		vim_free(fenc);
+	    if (fenc_next != NULL)
+	    {
+		fenc = next_fenc(&fenc_next);
+		fenc_alloced = (fenc_next != NULL);
+	    }
+	    else
+	    {
+		fenc = (char_u *)"";
+		fenc_alloced = FALSE;
+	    }
+	}
+	if (tmpname != NULL)
+	{
+	    mch_remove(tmpname);		/* delete converted file */
+	    vim_free(tmpname);
+	    tmpname = NULL;
+	}
+    }
+
+    /*
+     * Conversion is required when the encoding of the file is different
+     * from 'encoding' or 'encoding' is UTF-16, UCS-2 or UCS-4 (requires
+     * conversion to UTF-8).
+     */
+    fio_flags = 0;
+    converted = (*fenc != NUL && !same_encoding(p_enc, fenc));
+    if (converted || enc_unicode != 0)
+    {
+
+	/* "ucs-bom" means we need to check the first bytes of the file
+	 * for a BOM. */
+	if (STRCMP(fenc, ENC_UCSBOM) == 0)
+	    fio_flags = FIO_UCSBOM;
+
+	/*
+	 * Check if UCS-2/4 or Latin1 to UTF-8 conversion needs to be
+	 * done.  This is handled below after read().  Prepare the
+	 * fio_flags to avoid having to parse the string each time.
+	 * Also check for Unicode to Latin1 conversion, because iconv()
+	 * appears not to handle this correctly.  This works just like
+	 * conversion to UTF-8 except how the resulting character is put in
+	 * the buffer.
+	 */
+	else if (enc_utf8 || STRCMP(p_enc, "latin1") == 0)
+	    fio_flags = get_fio_flags(fenc);
+
+# ifdef WIN3264
+	/*
+	 * Conversion from an MS-Windows codepage to UTF-8 or another codepage
+	 * is handled with MultiByteToWideChar().
+	 */
+	if (fio_flags == 0)
+	    fio_flags = get_win_fio_flags(fenc);
+# endif
+
+# ifdef MACOS_X
+	/* Conversion from Apple MacRoman to latin1 or UTF-8 */
+	if (fio_flags == 0)
+	    fio_flags = get_mac_fio_flags(fenc);
+# endif
+
+# ifdef USE_ICONV
+	/*
+	 * Try using iconv() if we can't convert internally.
+	 */
+	if (fio_flags == 0
+#  ifdef FEAT_EVAL
+		&& !did_iconv
+#  endif
+		)
+	    iconv_fd = (iconv_t)my_iconv_open(
+				  enc_utf8 ? (char_u *)"utf-8" : p_enc, fenc);
+# endif
+
+# ifdef FEAT_EVAL
+	/*
+	 * Use the 'charconvert' expression when conversion is required
+	 * and we can't do it internally or with iconv().
+	 */
+	if (fio_flags == 0 && !read_stdin && !read_buffer && *p_ccv != NUL
+#  ifdef USE_ICONV
+						    && iconv_fd == (iconv_t)-1
+#  endif
+		)
+	{
+#  ifdef USE_ICONV
+	    did_iconv = FALSE;
+#  endif
+	    /* Skip conversion when it's already done (retry for wrong
+	     * "fileformat"). */
+	    if (tmpname == NULL)
+	    {
+		tmpname = readfile_charconvert(fname, fenc, &fd);
+		if (tmpname == NULL)
+		{
+		    /* Conversion failed.  Try another one. */
+		    advance_fenc = TRUE;
+		    if (fd < 0)
+		    {
+			/* Re-opening the original file failed! */
+			EMSG(_("E202: Conversion made file unreadable!"));
+			error = TRUE;
+			goto failed;
+		    }
+		    goto retry;
+		}
+	    }
+	}
+	else
+# endif
+	{
+	    if (fio_flags == 0
+# ifdef USE_ICONV
+		    && iconv_fd == (iconv_t)-1
+# endif
+	       )
+	    {
+		/* Conversion wanted but we can't.
+		 * Try the next conversion in 'fileencodings' */
+		advance_fenc = TRUE;
+		goto retry;
+	    }
+	}
+    }
+
+    /* Set "can_retry" when it's possible to rewind the file and try with
+     * another "fenc" value.  It's FALSE when no other "fenc" to try, reading
+     * stdin or fixed at a specific encoding. */
+    can_retry = (*fenc != NUL && !read_stdin && !keep_dest_enc);
+#endif
+
+    if (!skip_read)
+    {
+	linerest = 0;
+	filesize = 0;
+	skip_count = lines_to_skip;
+	read_count = lines_to_read;
+#ifdef FEAT_MBYTE
+	conv_restlen = 0;
+#endif
+    }
+
+    while (!error && !got_int)
+    {
+	/*
+	 * We allocate as much space for the file as we can get, plus
+	 * space for the old line plus room for one terminating NUL.
+	 * The amount is limited by the fact that read() only can read
+	 * upto max_unsigned characters (and other things).
+	 */
+#if SIZEOF_INT <= 2
+	if (linerest >= 0x7ff0)
+	{
+	    ++split;
+	    *ptr = NL;		    /* split line by inserting a NL */
+	    size = 1;
+	}
+	else
+#endif
+	{
+	    if (!skip_read)
+	    {
+#if SIZEOF_INT > 2
+# if defined(SSIZE_MAX) && (SSIZE_MAX < 0x10000L)
+		size = SSIZE_MAX;		    /* use max I/O size, 52K */
+# else
+		size = 0x10000L;		    /* use buffer >= 64K */
+# endif
+#else
+		size = 0x7ff0L - linerest;	    /* limit buffer to 32K */
+#endif
+
+		for ( ; size >= 10; size = (long)((long_u)size >> 1))
+		{
+		    if ((new_buffer = lalloc((long_u)(size + linerest + 1),
+							      FALSE)) != NULL)
+			break;
+		}
+		if (new_buffer == NULL)
+		{
+		    do_outofmem_msg((long_u)(size * 2 + linerest + 1));
+		    error = TRUE;
+		    break;
+		}
+		if (linerest)	/* copy characters from the previous buffer */
+		    mch_memmove(new_buffer, ptr - linerest, (size_t)linerest);
+		vim_free(buffer);
+		buffer = new_buffer;
+		ptr = buffer + linerest;
+		line_start = buffer;
+
+#ifdef FEAT_MBYTE
+		/* May need room to translate into.
+		 * For iconv() we don't really know the required space, use a
+		 * factor ICONV_MULT.
+		 * latin1 to utf-8: 1 byte becomes up to 2 bytes
+		 * utf-16 to utf-8: 2 bytes become up to 3 bytes, 4 bytes
+		 * become up to 4 bytes, size must be multiple of 2
+		 * ucs-2 to utf-8: 2 bytes become up to 3 bytes, size must be
+		 * multiple of 2
+		 * ucs-4 to utf-8: 4 bytes become up to 6 bytes, size must be
+		 * multiple of 4 */
+		real_size = (int)size;
+# ifdef USE_ICONV
+		if (iconv_fd != (iconv_t)-1)
+		    size = size / ICONV_MULT;
+		else
+# endif
+		    if (fio_flags & FIO_LATIN1)
+		    size = size / 2;
+		else if (fio_flags & (FIO_UCS2 | FIO_UTF16))
+		    size = (size * 2 / 3) & ~1;
+		else if (fio_flags & FIO_UCS4)
+		    size = (size * 2 / 3) & ~3;
+		else if (fio_flags == FIO_UCSBOM)
+		    size = size / ICONV_MULT;	/* worst case */
+# ifdef WIN3264
+		else if (fio_flags & FIO_CODEPAGE)
+		    size = size / ICONV_MULT;	/* also worst case */
+# endif
+# ifdef MACOS_X
+		else if (fio_flags & FIO_MACROMAN)
+		    size = size / ICONV_MULT;	/* also worst case */
+# endif
+#endif
+
+#ifdef FEAT_MBYTE
+		if (conv_restlen > 0)
+		{
+		    /* Insert unconverted bytes from previous line. */
+		    mch_memmove(ptr, conv_rest, conv_restlen);
+		    ptr += conv_restlen;
+		    size -= conv_restlen;
+		}
+#endif
+
+		if (read_buffer)
+		{
+		    /*
+		     * Read bytes from curbuf.  Used for converting text read
+		     * from stdin.
+		     */
+		    if (read_buf_lnum > from)
+			size = 0;
+		    else
+		    {
+			int	n, ni;
+			long	tlen;
+
+			tlen = 0;
+			for (;;)
+			{
+			    p = ml_get(read_buf_lnum) + read_buf_col;
+			    n = (int)STRLEN(p);
+			    if ((int)tlen + n + 1 > size)
+			    {
+				/* Filled up to "size", append partial line.
+				 * Change NL to NUL to reverse the effect done
+				 * below. */
+				n = (int)(size - tlen);
+				for (ni = 0; ni < n; ++ni)
+				{
+				    if (p[ni] == NL)
+					ptr[tlen++] = NUL;
+				    else
+					ptr[tlen++] = p[ni];
+				}
+				read_buf_col += n;
+				break;
+			    }
+			    else
+			    {
+				/* Append whole line and new-line.  Change NL
+				 * to NUL to reverse the effect done below. */
+				for (ni = 0; ni < n; ++ni)
+				{
+				    if (p[ni] == NL)
+					ptr[tlen++] = NUL;
+				    else
+					ptr[tlen++] = p[ni];
+				}
+				ptr[tlen++] = NL;
+				read_buf_col = 0;
+				if (++read_buf_lnum > from)
+				{
+				    /* When the last line didn't have an
+				     * end-of-line don't add it now either. */
+				    if (!curbuf->b_p_eol)
+					--tlen;
+				    size = tlen;
+				    break;
+				}
+			    }
+			}
+		    }
+		}
+		else
+		{
+		    /*
+		     * Read bytes from the file.
+		     */
+		    size = vim_read(fd, ptr, size);
+		}
+
+		if (size <= 0)
+		{
+		    if (size < 0)		    /* read error */
+			error = TRUE;
+#ifdef FEAT_MBYTE
+		    else if (conv_restlen > 0)
+		    {
+			/* Reached end-of-file but some trailing bytes could
+			 * not be converted.  Truncated file? */
+			if (conv_error == 0)
+			    conv_error = linecnt;
+			if (bad_char_behavior != BAD_DROP)
+			{
+			    fio_flags = 0;	/* don't convert this */
+# ifdef USE_ICONV
+			    if (iconv_fd != (iconv_t)-1)
+			    {
+				iconv_close(iconv_fd);
+				iconv_fd = (iconv_t)-1;
+			    }
+# endif
+			    if (bad_char_behavior == BAD_KEEP)
+			    {
+				/* Keep the trailing bytes as-is. */
+				size = conv_restlen;
+				ptr -= conv_restlen;
+			    }
+			    else
+			    {
+				/* Replace the trailing bytes with the
+				 * replacement character. */
+				size = 1;
+				*--ptr = bad_char_behavior;
+			    }
+			    conv_restlen = 0;
+			}
+		    }
+#endif
+		}
+
+#ifdef FEAT_CRYPT
+		/*
+		 * At start of file: Check for magic number of encryption.
+		 */
+		if (filesize == 0)
+		    cryptkey = check_for_cryptkey(cryptkey, ptr, &size,
+							  &filesize, newfile);
+		/*
+		 * Decrypt the read bytes.
+		 */
+		if (cryptkey != NULL && size > 0)
+		    for (p = ptr; p < ptr + size; ++p)
+			ZDECODE(*p);
+#endif
+	    }
+	    skip_read = FALSE;
+
+#ifdef FEAT_MBYTE
+	    /*
+	     * At start of file (or after crypt magic number): Check for BOM.
+	     * Also check for a BOM for other Unicode encodings, but not after
+	     * converting with 'charconvert' or when a BOM has already been
+	     * found.
+	     */
+	    if ((filesize == 0
+# ifdef FEAT_CRYPT
+			|| (filesize == CRYPT_MAGIC_LEN && cryptkey != NULL)
+# endif
+		       )
+		    && (fio_flags == FIO_UCSBOM
+			|| (!curbuf->b_p_bomb
+			    && tmpname == NULL
+			    && (*fenc == 'u' || (*fenc == NUL && enc_utf8)))))
+	    {
+		char_u	*ccname;
+		int	blen;
+
+		/* no BOM detection in a short file or in binary mode */
+		if (size < 2 || curbuf->b_p_bin)
+		    ccname = NULL;
+		else
+		    ccname = check_for_bom(ptr, size, &blen,
+		      fio_flags == FIO_UCSBOM ? FIO_ALL : get_fio_flags(fenc));
+		if (ccname != NULL)
+		{
+		    /* Remove BOM from the text */
+		    filesize += blen;
+		    size -= blen;
+		    mch_memmove(ptr, ptr + blen, (size_t)size);
+		    if (set_options)
+			curbuf->b_p_bomb = TRUE;
+		}
+
+		if (fio_flags == FIO_UCSBOM)
+		{
+		    if (ccname == NULL)
+		    {
+			/* No BOM detected: retry with next encoding. */
+			advance_fenc = TRUE;
+		    }
+		    else
+		    {
+			/* BOM detected: set "fenc" and jump back */
+			if (fenc_alloced)
+			    vim_free(fenc);
+			fenc = ccname;
+			fenc_alloced = FALSE;
+		    }
+		    /* retry reading without getting new bytes or rewinding */
+		    skip_read = TRUE;
+		    goto retry;
+		}
+	    }
+#endif
+	    /*
+	     * Break here for a read error or end-of-file.
+	     */
+	    if (size <= 0)
+		break;
+
+#ifdef FEAT_MBYTE
+
+	    /* Include not converted bytes. */
+	    ptr -= conv_restlen;
+	    size += conv_restlen;
+	    conv_restlen = 0;
+
+# ifdef USE_ICONV
+	    if (iconv_fd != (iconv_t)-1)
+	    {
+		/*
+		 * Attempt conversion of the read bytes to 'encoding' using
+		 * iconv().
+		 */
+		const char	*fromp;
+		char		*top;
+		size_t		from_size;
+		size_t		to_size;
+
+		fromp = (char *)ptr;
+		from_size = size;
+		ptr += size;
+		top = (char *)ptr;
+		to_size = real_size - size;
+
+		/*
+		 * If there is conversion error or not enough room try using
+		 * another conversion.  Except for when there is no
+		 * alternative (help files).
+		 */
+		while ((iconv(iconv_fd, (void *)&fromp, &from_size,
+							       &top, &to_size)
+			    == (size_t)-1 && ICONV_ERRNO != ICONV_EINVAL)
+						  || from_size > CONV_RESTLEN)
+		{
+		    if (can_retry)
+			goto rewind_retry;
+		    if (conv_error == 0)
+			conv_error = readfile_linenr(linecnt,
+							  ptr, (char_u *)top);
+
+		    /* Deal with a bad byte and continue with the next. */
+		    ++fromp;
+		    --from_size;
+		    if (bad_char_behavior == BAD_KEEP)
+		    {
+			*top++ = *(fromp - 1);
+			--to_size;
+		    }
+		    else if (bad_char_behavior != BAD_DROP)
+		    {
+			*top++ = bad_char_behavior;
+			--to_size;
+		    }
+		}
+
+		if (from_size > 0)
+		{
+		    /* Some remaining characters, keep them for the next
+		     * round. */
+		    mch_memmove(conv_rest, (char_u *)fromp, from_size);
+		    conv_restlen = (int)from_size;
+		}
+
+		/* move the linerest to before the converted characters */
+		line_start = ptr - linerest;
+		mch_memmove(line_start, buffer, (size_t)linerest);
+		size = (long)((char_u *)top - ptr);
+	    }
+# endif
+
+# ifdef WIN3264
+	    if (fio_flags & FIO_CODEPAGE)
+	    {
+		char_u	*src, *dst;
+		WCHAR	ucs2buf[3];
+		int	ucs2len;
+		int	codepage = FIO_GET_CP(fio_flags);
+		int	bytelen;
+		int	found_bad;
+		char	replstr[2];
+
+		/*
+		 * Conversion from an MS-Windows codepage or UTF-8 to UTF-8 or
+		 * a codepage, using standard MS-Windows functions.  This
+		 * requires two steps:
+		 * 1. convert from 'fileencoding' to ucs-2
+		 * 2. convert from ucs-2 to 'encoding'
+		 *
+		 * Because there may be illegal bytes AND an incomplete byte
+		 * sequence at the end, we may have to do the conversion one
+		 * character at a time to get it right.
+		 */
+
+		/* Replacement string for WideCharToMultiByte(). */
+		if (bad_char_behavior > 0)
+		    replstr[0] = bad_char_behavior;
+		else
+		    replstr[0] = '?';
+		replstr[1] = NUL;
+
+		/*
+		 * Move the bytes to the end of the buffer, so that we have
+		 * room to put the result at the start.
+		 */
+		src = ptr + real_size - size;
+		mch_memmove(src, ptr, size);
+
+		/*
+		 * Do the conversion.
+		 */
+		dst = ptr;
+		size = size;
+		while (size > 0)
+		{
+		    found_bad = FALSE;
+
+#  ifdef CP_UTF8	/* VC 4.1 doesn't define CP_UTF8 */
+		    if (codepage == CP_UTF8)
+		    {
+			/* Handle CP_UTF8 input ourselves to be able to handle
+			 * trailing bytes properly.
+			 * Get one UTF-8 character from src. */
+			bytelen = (int)utf_ptr2len_len(src, size);
+			if (bytelen > size)
+			{
+			    /* Only got some bytes of a character.  Normally
+			     * it's put in "conv_rest", but if it's too long
+			     * deal with it as if they were illegal bytes. */
+			    if (bytelen <= CONV_RESTLEN)
+				break;
+
+			    /* weird overlong byte sequence */
+			    bytelen = size;
+			    found_bad = TRUE;
+			}
+			else
+			{
+			    int	    u8c = utf_ptr2char(src);
+
+			    if (u8c > 0xffff || (*src >= 0x80 && bytelen == 1))
+				found_bad = TRUE;
+			    ucs2buf[0] = u8c;
+			    ucs2len = 1;
+			}
+		    }
+		    else
+#  endif
+		    {
+			/* We don't know how long the byte sequence is, try
+			 * from one to three bytes. */
+			for (bytelen = 1; bytelen <= size && bytelen <= 3;
+								    ++bytelen)
+			{
+			    ucs2len = MultiByteToWideChar(codepage,
+							 MB_ERR_INVALID_CHARS,
+							 (LPCSTR)src, bytelen,
+								   ucs2buf, 3);
+			    if (ucs2len > 0)
+				break;
+			}
+			if (ucs2len == 0)
+			{
+			    /* If we have only one byte then it's probably an
+			     * incomplete byte sequence.  Otherwise discard
+			     * one byte as a bad character. */
+			    if (size == 1)
+				break;
+			    found_bad = TRUE;
+			    bytelen = 1;
+			}
+		    }
+
+		    if (!found_bad)
+		    {
+			int	i;
+
+			/* Convert "ucs2buf[ucs2len]" to 'enc' in "dst". */
+			if (enc_utf8)
+			{
+			    /* From UCS-2 to UTF-8.  Cannot fail. */
+			    for (i = 0; i < ucs2len; ++i)
+				dst += utf_char2bytes(ucs2buf[i], dst);
+			}
+			else
+			{
+			    BOOL	bad = FALSE;
+			    int		dstlen;
+
+			    /* From UCS-2 to "enc_codepage".  If the
+			     * conversion uses the default character "?",
+			     * the data doesn't fit in this encoding. */
+			    dstlen = WideCharToMultiByte(enc_codepage, 0,
+				    (LPCWSTR)ucs2buf, ucs2len,
+				    (LPSTR)dst, (int)(src - dst),
+				    replstr, &bad);
+			    if (bad)
+				found_bad = TRUE;
+			    else
+				dst += dstlen;
+			}
+		    }
+
+		    if (found_bad)
+		    {
+			/* Deal with bytes we can't convert. */
+			if (can_retry)
+			    goto rewind_retry;
+			if (conv_error == 0)
+			    conv_error = readfile_linenr(linecnt, ptr, dst);
+			if (bad_char_behavior != BAD_DROP)
+			{
+			    if (bad_char_behavior == BAD_KEEP)
+			    {
+				mch_memmove(dst, src, bytelen);
+				dst += bytelen;
+			    }
+			    else
+				*dst++ = bad_char_behavior;
+			}
+		    }
+
+		    src += bytelen;
+		    size -= bytelen;
+		}
+
+		if (size > 0)
+		{
+		    /* An incomplete byte sequence remaining. */
+		    mch_memmove(conv_rest, src, size);
+		    conv_restlen = size;
+		}
+
+		/* The new size is equal to how much "dst" was advanced. */
+		size = (long)(dst - ptr);
+	    }
+	    else
+# endif
+# ifdef MACOS_CONVERT
+	    if (fio_flags & FIO_MACROMAN)
+	    {
+		/*
+		 * Conversion from Apple MacRoman char encoding to UTF-8 or
+		 * latin1.  This is in os_mac_conv.c.
+		 */
+		if (macroman2enc(ptr, &size, real_size) == FAIL)
+		    goto rewind_retry;
+	    }
+	    else
+# endif
+	    if (fio_flags != 0)
+	    {
+		int	u8c;
+		char_u	*dest;
+		char_u	*tail = NULL;
+
+		/*
+		 * "enc_utf8" set: Convert Unicode or Latin1 to UTF-8.
+		 * "enc_utf8" not set: Convert Unicode to Latin1.
+		 * Go from end to start through the buffer, because the number
+		 * of bytes may increase.
+		 * "dest" points to after where the UTF-8 bytes go, "p" points
+		 * to after the next character to convert.
+		 */
+		dest = ptr + real_size;
+		if (fio_flags == FIO_LATIN1 || fio_flags == FIO_UTF8)
+		{
+		    p = ptr + size;
+		    if (fio_flags == FIO_UTF8)
+		    {
+			/* Check for a trailing incomplete UTF-8 sequence */
+			tail = ptr + size - 1;
+			while (tail > ptr && (*tail & 0xc0) == 0x80)
+			    --tail;
+			if (tail + utf_byte2len(*tail) <= ptr + size)
+			    tail = NULL;
+			else
+			    p = tail;
+		    }
+		}
+		else if (fio_flags & (FIO_UCS2 | FIO_UTF16))
+		{
+		    /* Check for a trailing byte */
+		    p = ptr + (size & ~1);
+		    if (size & 1)
+			tail = p;
+		    if ((fio_flags & FIO_UTF16) && p > ptr)
+		    {
+			/* Check for a trailing leading word */
+			if (fio_flags & FIO_ENDIAN_L)
+			{
+			    u8c = (*--p << 8);
+			    u8c += *--p;
+			}
+			else
+			{
+			    u8c = *--p;
+			    u8c += (*--p << 8);
+			}
+			if (u8c >= 0xd800 && u8c <= 0xdbff)
+			    tail = p;
+			else
+			    p += 2;
+		    }
+		}
+		else /*  FIO_UCS4 */
+		{
+		    /* Check for trailing 1, 2 or 3 bytes */
+		    p = ptr + (size & ~3);
+		    if (size & 3)
+			tail = p;
+		}
+
+		/* If there is a trailing incomplete sequence move it to
+		 * conv_rest[]. */
+		if (tail != NULL)
+		{
+		    conv_restlen = (int)((ptr + size) - tail);
+		    mch_memmove(conv_rest, (char_u *)tail, conv_restlen);
+		    size -= conv_restlen;
+		}
+
+
+		while (p > ptr)
+		{
+		    if (fio_flags & FIO_LATIN1)
+			u8c = *--p;
+		    else if (fio_flags & (FIO_UCS2 | FIO_UTF16))
+		    {
+			if (fio_flags & FIO_ENDIAN_L)
+			{
+			    u8c = (*--p << 8);
+			    u8c += *--p;
+			}
+			else
+			{
+			    u8c = *--p;
+			    u8c += (*--p << 8);
+			}
+			if ((fio_flags & FIO_UTF16)
+					    && u8c >= 0xdc00 && u8c <= 0xdfff)
+			{
+			    int u16c;
+
+			    if (p == ptr)
+			    {
+				/* Missing leading word. */
+				if (can_retry)
+				    goto rewind_retry;
+				if (conv_error == 0)
+				    conv_error = readfile_linenr(linecnt,
+								      ptr, p);
+				if (bad_char_behavior == BAD_DROP)
+				    continue;
+				if (bad_char_behavior != BAD_KEEP)
+				    u8c = bad_char_behavior;
+			    }
+
+			    /* found second word of double-word, get the first
+			     * word and compute the resulting character */
+			    if (fio_flags & FIO_ENDIAN_L)
+			    {
+				u16c = (*--p << 8);
+				u16c += *--p;
+			    }
+			    else
+			    {
+				u16c = *--p;
+				u16c += (*--p << 8);
+			    }
+			    u8c = 0x10000 + ((u16c & 0x3ff) << 10)
+							      + (u8c & 0x3ff);
+
+			    /* Check if the word is indeed a leading word. */
+			    if (u16c < 0xd800 || u16c > 0xdbff)
+			    {
+				if (can_retry)
+				    goto rewind_retry;
+				if (conv_error == 0)
+				    conv_error = readfile_linenr(linecnt,
+								      ptr, p);
+				if (bad_char_behavior == BAD_DROP)
+				    continue;
+				if (bad_char_behavior != BAD_KEEP)
+				    u8c = bad_char_behavior;
+			    }
+			}
+		    }
+		    else if (fio_flags & FIO_UCS4)
+		    {
+			if (fio_flags & FIO_ENDIAN_L)
+			{
+			    u8c = (*--p << 24);
+			    u8c += (*--p << 16);
+			    u8c += (*--p << 8);
+			    u8c += *--p;
+			}
+			else	/* big endian */
+			{
+			    u8c = *--p;
+			    u8c += (*--p << 8);
+			    u8c += (*--p << 16);
+			    u8c += (*--p << 24);
+			}
+		    }
+		    else    /* UTF-8 */
+		    {
+			if (*--p < 0x80)
+			    u8c = *p;
+			else
+			{
+			    len = utf_head_off(ptr, p);
+			    p -= len;
+			    u8c = utf_ptr2char(p);
+			    if (len == 0)
+			    {
+				/* Not a valid UTF-8 character, retry with
+				 * another fenc when possible, otherwise just
+				 * report the error. */
+				if (can_retry)
+				    goto rewind_retry;
+				if (conv_error == 0)
+				    conv_error = readfile_linenr(linecnt,
+								      ptr, p);
+				if (bad_char_behavior == BAD_DROP)
+				    continue;
+				if (bad_char_behavior != BAD_KEEP)
+				    u8c = bad_char_behavior;
+			    }
+			}
+		    }
+		    if (enc_utf8)	/* produce UTF-8 */
+		    {
+			dest -= utf_char2len(u8c);
+			(void)utf_char2bytes(u8c, dest);
+		    }
+		    else		/* produce Latin1 */
+		    {
+			--dest;
+			if (u8c >= 0x100)
+			{
+			    /* character doesn't fit in latin1, retry with
+			     * another fenc when possible, otherwise just
+			     * report the error. */
+			    if (can_retry)
+				goto rewind_retry;
+			    if (conv_error == 0)
+				conv_error = readfile_linenr(linecnt, ptr, p);
+			    if (bad_char_behavior == BAD_DROP)
+				++dest;
+			    else if (bad_char_behavior == BAD_KEEP)
+				*dest = u8c;
+			    else if (eap != NULL && eap->bad_char != 0)
+				*dest = bad_char_behavior;
+			    else
+				*dest = 0xBF;
+			}
+			else
+			    *dest = u8c;
+		    }
+		}
+
+		/* move the linerest to before the converted characters */
+		line_start = dest - linerest;
+		mch_memmove(line_start, buffer, (size_t)linerest);
+		size = (long)((ptr + real_size) - dest);
+		ptr = dest;
+	    }
+	    else if (enc_utf8 && conv_error == 0 && !curbuf->b_p_bin)
+	    {
+		/* Reading UTF-8: Check if the bytes are valid UTF-8.
+		 * Need to start before "ptr" when part of the character was
+		 * read in the previous read() call. */
+		for (p = ptr - utf_head_off(buffer, ptr); ; ++p)
+		{
+		    int	 todo = (int)((ptr + size) - p);
+		    int	 l;
+
+		    if (todo <= 0)
+			break;
+		    if (*p >= 0x80)
+		    {
+			/* A length of 1 means it's an illegal byte.  Accept
+			 * an incomplete character at the end though, the next
+			 * read() will get the next bytes, we'll check it
+			 * then. */
+			l = utf_ptr2len_len(p, todo);
+			if (l > todo)
+			{
+			    /* Incomplete byte sequence, the next read()
+			     * should get them and check the bytes. */
+			    p += todo;
+			    break;
+			}
+			if (l == 1)
+			{
+			    /* Illegal byte.  If we can try another encoding
+			     * do that. */
+			    if (can_retry)
+				break;
+
+			    /* Remember the first linenr with an illegal byte */
+			    if (illegal_byte == 0)
+				illegal_byte = readfile_linenr(linecnt, ptr, p);
+# ifdef USE_ICONV
+			    /* When we did a conversion report an error. */
+			    if (iconv_fd != (iconv_t)-1 && conv_error == 0)
+				conv_error = readfile_linenr(linecnt, ptr, p);
+# endif
+
+			    /* Drop, keep or replace the bad byte. */
+			    if (bad_char_behavior == BAD_DROP)
+			    {
+				mch_memmove(p, p+1, todo - 1);
+				--p;
+				--size;
+			    }
+			    else if (bad_char_behavior != BAD_KEEP)
+				*p = bad_char_behavior;
+			}
+			p += l - 1;
+		    }
+		}
+		if (p < ptr + size)
+		{
+		    /* Detected a UTF-8 error. */
+rewind_retry:
+		    /* Retry reading with another conversion. */
+# if defined(FEAT_EVAL) && defined(USE_ICONV)
+		    if (*p_ccv != NUL && iconv_fd != (iconv_t)-1)
+			/* iconv() failed, try 'charconvert' */
+			did_iconv = TRUE;
+		    else
+# endif
+			/* use next item from 'fileencodings' */
+			advance_fenc = TRUE;
+		    file_rewind = TRUE;
+		    goto retry;
+		}
+	    }
+#endif
+
+	    /* count the number of characters (after conversion!) */
+	    filesize += size;
+
+	    /*
+	     * when reading the first part of a file: guess EOL type
+	     */
+	    if (fileformat == EOL_UNKNOWN)
+	    {
+		/* First try finding a NL, for Dos and Unix */
+		if (try_dos || try_unix)
+		{
+		    for (p = ptr; p < ptr + size; ++p)
+		    {
+			if (*p == NL)
+			{
+			    if (!try_unix
+				    || (try_dos && p > ptr && p[-1] == CAR))
+				fileformat = EOL_DOS;
+			    else
+				fileformat = EOL_UNIX;
+			    break;
+			}
+		    }
+
+		    /* Don't give in to EOL_UNIX if EOL_MAC is more likely */
+		    if (fileformat == EOL_UNIX && try_mac)
+		    {
+			/* Need to reset the counters when retrying fenc. */
+			try_mac = 1;
+			try_unix = 1;
+			for (; p >= ptr && *p != CAR; p--)
+			    ;
+			if (p >= ptr)
+			{
+			    for (p = ptr; p < ptr + size; ++p)
+			    {
+				if (*p == NL)
+				    try_unix++;
+				else if (*p == CAR)
+				    try_mac++;
+			    }
+			    if (try_mac > try_unix)
+				fileformat = EOL_MAC;
+			}
+		    }
+		}
+
+		/* No NL found: may use Mac format */
+		if (fileformat == EOL_UNKNOWN && try_mac)
+		    fileformat = EOL_MAC;
+
+		/* Still nothing found?  Use first format in 'ffs' */
+		if (fileformat == EOL_UNKNOWN)
+		    fileformat = default_fileformat();
+
+		/* if editing a new file: may set p_tx and p_ff */
+		if (set_options)
+		    set_fileformat(fileformat, OPT_LOCAL);
+	    }
+	}
+
+	/*
+	 * This loop is executed once for every character read.
+	 * Keep it fast!
+	 */
+	if (fileformat == EOL_MAC)
+	{
+	    --ptr;
+	    while (++ptr, --size >= 0)
+	    {
+		/* catch most common case first */
+		if ((c = *ptr) != NUL && c != CAR && c != NL)
+		    continue;
+		if (c == NUL)
+		    *ptr = NL;	/* NULs are replaced by newlines! */
+		else if (c == NL)
+		    *ptr = CAR;	/* NLs are replaced by CRs! */
+		else
+		{
+		    if (skip_count == 0)
+		    {
+			*ptr = NUL;	    /* end of line */
+			len = (colnr_T) (ptr - line_start + 1);
+			if (ml_append(lnum, line_start, len, newfile) == FAIL)
+			{
+			    error = TRUE;
+			    break;
+			}
+			++lnum;
+			if (--read_count == 0)
+			{
+			    error = TRUE;	/* break loop */
+			    line_start = ptr;	/* nothing left to write */
+			    break;
+			}
+		    }
+		    else
+			--skip_count;
+		    line_start = ptr + 1;
+		}
+	    }
+	}
+	else
+	{
+	    --ptr;
+	    while (++ptr, --size >= 0)
+	    {
+		if ((c = *ptr) != NUL && c != NL)  /* catch most common case */
+		    continue;
+		if (c == NUL)
+		    *ptr = NL;	/* NULs are replaced by newlines! */
+		else
+		{
+		    if (skip_count == 0)
+		    {
+			*ptr = NUL;		/* end of line */
+			len = (colnr_T)(ptr - line_start + 1);
+			if (fileformat == EOL_DOS)
+			{
+			    if (ptr[-1] == CAR)	/* remove CR */
+			    {
+				ptr[-1] = NUL;
+				--len;
+			    }
+			    /*
+			     * Reading in Dos format, but no CR-LF found!
+			     * When 'fileformats' includes "unix", delete all
+			     * the lines read so far and start all over again.
+			     * Otherwise give an error message later.
+			     */
+			    else if (ff_error != EOL_DOS)
+			    {
+				if (   try_unix
+				    && !read_stdin
+				    && (read_buffer
+					|| lseek(fd, (off_t)0L, SEEK_SET) == 0))
+				{
+				    fileformat = EOL_UNIX;
+				    if (set_options)
+					set_fileformat(EOL_UNIX, OPT_LOCAL);
+				    file_rewind = TRUE;
+				    keep_fileformat = TRUE;
+				    goto retry;
+				}
+				ff_error = EOL_DOS;
+			    }
+			}
+			if (ml_append(lnum, line_start, len, newfile) == FAIL)
+			{
+			    error = TRUE;
+			    break;
+			}
+			++lnum;
+			if (--read_count == 0)
+			{
+			    error = TRUE;	    /* break loop */
+			    line_start = ptr;	/* nothing left to write */
+			    break;
+			}
+		    }
+		    else
+			--skip_count;
+		    line_start = ptr + 1;
+		}
+	    }
+	}
+	linerest = (long)(ptr - line_start);
+	ui_breakcheck();
+    }
+
+failed:
+    /* not an error, max. number of lines reached */
+    if (error && read_count == 0)
+	error = FALSE;
+
+    /*
+     * If we get EOF in the middle of a line, note the fact and
+     * complete the line ourselves.
+     * In Dos format ignore a trailing CTRL-Z, unless 'binary' set.
+     */
+    if (!error
+	    && !got_int
+	    && linerest != 0
+	    && !(!curbuf->b_p_bin
+		&& fileformat == EOL_DOS
+		&& *line_start == Ctrl_Z
+		&& ptr == line_start + 1))
+    {
+	/* remember for when writing */
+	if (set_options)
+	    curbuf->b_p_eol = FALSE;
+	*ptr = NUL;
+	if (ml_append(lnum, line_start,
+			(colnr_T)(ptr - line_start + 1), newfile) == FAIL)
+	    error = TRUE;
+	else
+	    read_no_eol_lnum = ++lnum;
+    }
+
+    if (set_options)
+	save_file_ff(curbuf);		/* remember the current file format */
+
+#ifdef FEAT_CRYPT
+    if (cryptkey != curbuf->b_p_key)
+	vim_free(cryptkey);
+#endif
+
+#ifdef FEAT_MBYTE
+    /* If editing a new file: set 'fenc' for the current buffer.
+     * Also for ":read ++edit file". */
+    if (set_options)
+	set_string_option_direct((char_u *)"fenc", -1, fenc,
+						       OPT_FREE|OPT_LOCAL, 0);
+    if (fenc_alloced)
+	vim_free(fenc);
+# ifdef USE_ICONV
+    if (iconv_fd != (iconv_t)-1)
+    {
+	iconv_close(iconv_fd);
+	iconv_fd = (iconv_t)-1;
+    }
+# endif
+#endif
+
+    if (!read_buffer && !read_stdin)
+	close(fd);				/* errors are ignored */
+    vim_free(buffer);
+
+#ifdef HAVE_DUP
+    if (read_stdin)
+    {
+	/* Use stderr for stdin, makes shell commands work. */
+	close(0);
+	dup(2);
+    }
+#endif
+
+#ifdef FEAT_MBYTE
+    if (tmpname != NULL)
+    {
+	mch_remove(tmpname);		/* delete converted file */
+	vim_free(tmpname);
+    }
+#endif
+    --no_wait_return;			/* may wait for return now */
+
+    /*
+     * In recovery mode everything but autocommands is skipped.
+     */
+    if (!recoverymode)
+    {
+	/* need to delete the last line, which comes from the empty buffer */
+	if (newfile && wasempty && !(curbuf->b_ml.ml_flags & ML_EMPTY))
+	{
+#ifdef FEAT_NETBEANS_INTG
+	    netbeansFireChanges = 0;
+#endif
+	    ml_delete(curbuf->b_ml.ml_line_count, FALSE);
+#ifdef FEAT_NETBEANS_INTG
+	    netbeansFireChanges = 1;
+#endif
+	    --linecnt;
+	}
+	linecnt = curbuf->b_ml.ml_line_count - linecnt;
+	if (filesize == 0)
+	    linecnt = 0;
+	if (newfile || read_buffer)
+	{
+	    redraw_curbuf_later(NOT_VALID);
+#ifdef FEAT_DIFF
+	    /* After reading the text into the buffer the diff info needs to
+	     * be updated. */
+	    diff_invalidate(curbuf);
+#endif
+#ifdef FEAT_FOLDING
+	    /* All folds in the window are invalid now.  Mark them for update
+	     * before triggering autocommands. */
+	    foldUpdateAll(curwin);
+#endif
+	}
+	else if (linecnt)		/* appended at least one line */
+	    appended_lines_mark(from, linecnt);
+
+#ifndef ALWAYS_USE_GUI
+	/*
+	 * If we were reading from the same terminal as where messages go,
+	 * the screen will have been messed up.
+	 * Switch on raw mode now and clear the screen.
+	 */
+	if (read_stdin)
+	{
+	    settmode(TMODE_RAW);	/* set to raw mode */
+	    starttermcap();
+	    screenclear();
+	}
+#endif
+
+	if (got_int)
+	{
+	    if (!(flags & READ_DUMMY))
+	    {
+		filemess(curbuf, sfname, (char_u *)_(e_interr), 0);
+		if (newfile)
+		    curbuf->b_p_ro = TRUE;	/* must use "w!" now */
+	    }
+	    msg_scroll = msg_save;
+#ifdef FEAT_VIMINFO
+	    check_marks_read();
+#endif
+	    return OK;		/* an interrupt isn't really an error */
+	}
+
+	if (!filtering && !(flags & READ_DUMMY))
+	{
+	    msg_add_fname(curbuf, sfname);   /* fname in IObuff with quotes */
+	    c = FALSE;
+
+#ifdef UNIX
+# ifdef S_ISFIFO
+	    if (S_ISFIFO(perm))			    /* fifo or socket */
+	    {
+		STRCAT(IObuff, _("[fifo/socket]"));
+		c = TRUE;
+	    }
+# else
+#  ifdef S_IFIFO
+	    if ((perm & S_IFMT) == S_IFIFO)	    /* fifo */
+	    {
+		STRCAT(IObuff, _("[fifo]"));
+		c = TRUE;
+	    }
+#  endif
+#  ifdef S_IFSOCK
+	    if ((perm & S_IFMT) == S_IFSOCK)	    /* or socket */
+	    {
+		STRCAT(IObuff, _("[socket]"));
+		c = TRUE;
+	    }
+#  endif
+# endif
+#endif
+	    if (curbuf->b_p_ro)
+	    {
+		STRCAT(IObuff, shortmess(SHM_RO) ? _("[RO]") : _("[readonly]"));
+		c = TRUE;
+	    }
+	    if (read_no_eol_lnum)
+	    {
+		msg_add_eol();
+		c = TRUE;
+	    }
+	    if (ff_error == EOL_DOS)
+	    {
+		STRCAT(IObuff, _("[CR missing]"));
+		c = TRUE;
+	    }
+	    if (ff_error == EOL_MAC)
+	    {
+		STRCAT(IObuff, _("[NL found]"));
+		c = TRUE;
+	    }
+	    if (split)
+	    {
+		STRCAT(IObuff, _("[long lines split]"));
+		c = TRUE;
+	    }
+#ifdef FEAT_MBYTE
+	    if (notconverted)
+	    {
+		STRCAT(IObuff, _("[NOT converted]"));
+		c = TRUE;
+	    }
+	    else if (converted)
+	    {
+		STRCAT(IObuff, _("[converted]"));
+		c = TRUE;
+	    }
+#endif
+#ifdef FEAT_CRYPT
+	    if (cryptkey != NULL)
+	    {
+		STRCAT(IObuff, _("[crypted]"));
+		c = TRUE;
+	    }
+#endif
+#ifdef FEAT_MBYTE
+	    if (conv_error != 0)
+	    {
+		sprintf((char *)IObuff + STRLEN(IObuff),
+		       _("[CONVERSION ERROR in line %ld]"), (long)conv_error);
+		c = TRUE;
+	    }
+	    else if (illegal_byte > 0)
+	    {
+		sprintf((char *)IObuff + STRLEN(IObuff),
+			 _("[ILLEGAL BYTE in line %ld]"), (long)illegal_byte);
+		c = TRUE;
+	    }
+	    else
+#endif
+		if (error)
+	    {
+		STRCAT(IObuff, _("[READ ERRORS]"));
+		c = TRUE;
+	    }
+	    if (msg_add_fileformat(fileformat))
+		c = TRUE;
+#ifdef FEAT_CRYPT
+	    if (cryptkey != NULL)
+		msg_add_lines(c, (long)linecnt, filesize - CRYPT_MAGIC_LEN);
+	    else
+#endif
+		msg_add_lines(c, (long)linecnt, filesize);
+
+	    vim_free(keep_msg);
+	    keep_msg = NULL;
+	    msg_scrolled_ign = TRUE;
+#ifdef ALWAYS_USE_GUI
+	    /* Don't show the message when reading stdin, it would end up in a
+	     * message box (which might be shown when exiting!) */
+	    if (read_stdin || read_buffer)
+		p = msg_may_trunc(FALSE, IObuff);
+	    else
+#endif
+		p = msg_trunc_attr(IObuff, FALSE, 0);
+	    if (read_stdin || read_buffer || restart_edit != 0
+		    || (msg_scrolled != 0 && !need_wait_return))
+		/* Need to repeat the message after redrawing when:
+		 * - When reading from stdin (the screen will be cleared next).
+		 * - When restart_edit is set (otherwise there will be a delay
+		 *   before redrawing).
+		 * - When the screen was scrolled but there is no wait-return
+		 *   prompt. */
+		set_keep_msg(p, 0);
+	    msg_scrolled_ign = FALSE;
+	}
+
+	/* with errors writing the file requires ":w!" */
+	if (newfile && (error
+#ifdef FEAT_MBYTE
+		    || conv_error != 0
+		    || (illegal_byte > 0 && bad_char_behavior != BAD_KEEP)
+#endif
+		    ))
+	    curbuf->b_p_ro = TRUE;
+
+	u_clearline();	    /* cannot use "U" command after adding lines */
+
+	/*
+	 * In Ex mode: cursor at last new line.
+	 * Otherwise: cursor at first new line.
+	 */
+	if (exmode_active)
+	    curwin->w_cursor.lnum = from + linecnt;
+	else
+	    curwin->w_cursor.lnum = from + 1;
+	check_cursor_lnum();
+	beginline(BL_WHITE | BL_FIX);	    /* on first non-blank */
+
+	/*
+	 * Set '[ and '] marks to the newly read lines.
+	 */
+	curbuf->b_op_start.lnum = from + 1;
+	curbuf->b_op_start.col = 0;
+	curbuf->b_op_end.lnum = from + linecnt;
+	curbuf->b_op_end.col = 0;
+
+#ifdef WIN32
+	/*
+	 * Work around a weird problem: When a file has two links (only
+	 * possible on NTFS) and we write through one link, then stat() it
+	 * throught the other link, the timestamp information may be wrong.
+	 * It's correct again after reading the file, thus reset the timestamp
+	 * here.
+	 */
+	if (newfile && !read_stdin && !read_buffer
+					 && mch_stat((char *)fname, &st) >= 0)
+	{
+	    buf_store_time(curbuf, &st, fname);
+	    curbuf->b_mtime_read = curbuf->b_mtime;
+	}
+#endif
+    }
+    msg_scroll = msg_save;
+
+#ifdef FEAT_VIMINFO
+    /*
+     * Get the marks before executing autocommands, so they can be used there.
+     */
+    check_marks_read();
+#endif
+
+    /*
+     * Trick: We remember if the last line of the read didn't have
+     * an eol for when writing it again.  This is required for
+     * ":autocmd FileReadPost *.gz set bin|'[,']!gunzip" to work.
+     */
+    write_no_eol_lnum = read_no_eol_lnum;
+
+#ifdef FEAT_AUTOCMD
+    if (!read_stdin && !read_buffer)
+    {
+	int m = msg_scroll;
+	int n = msg_scrolled;
+
+	/* Save the fileformat now, otherwise the buffer will be considered
+	 * modified if the format/encoding was automatically detected. */
+	if (set_options)
+	    save_file_ff(curbuf);
+
+	/*
+	 * The output from the autocommands should not overwrite anything and
+	 * should not be overwritten: Set msg_scroll, restore its value if no
+	 * output was done.
+	 */
+	msg_scroll = TRUE;
+	if (filtering)
+	    apply_autocmds_exarg(EVENT_FILTERREADPOST, NULL, sfname,
+							  FALSE, curbuf, eap);
+	else if (newfile)
+	    apply_autocmds_exarg(EVENT_BUFREADPOST, NULL, sfname,
+							  FALSE, curbuf, eap);
+	else
+	    apply_autocmds_exarg(EVENT_FILEREADPOST, sfname, sfname,
+							    FALSE, NULL, eap);
+	if (msg_scrolled == n)
+	    msg_scroll = m;
+#ifdef FEAT_EVAL
+	if (aborting())	    /* autocmds may abort script processing */
+	    return FAIL;
+#endif
+    }
+#endif
+
+    if (recoverymode && error)
+	return FAIL;
+    return OK;
+}
+
+#ifdef FEAT_MBYTE
+
+/*
+ * From the current line count and characters read after that, estimate the
+ * line number where we are now.
+ * Used for error messages that include a line number.
+ */
+    static linenr_T
+readfile_linenr(linecnt, p, endp)
+    linenr_T	linecnt;	/* line count before reading more bytes */
+    char_u	*p;		/* start of more bytes read */
+    char_u	*endp;		/* end of more bytes read */
+{
+    char_u	*s;
+    linenr_T	lnum;
+
+    lnum = curbuf->b_ml.ml_line_count - linecnt + 1;
+    for (s = p; s < endp; ++s)
+	if (*s == '\n')
+	    ++lnum;
+    return lnum;
+}
+#endif
+
+/*
+ * Fill "*eap" to force the 'fileencoding', 'fileformat' and 'binary to be
+ * equal to the buffer "buf".  Used for calling readfile().
+ * Returns OK or FAIL.
+ */
+    int
+prep_exarg(eap, buf)
+    exarg_T	*eap;
+    buf_T	*buf;
+{
+    eap->cmd = alloc((unsigned)(STRLEN(buf->b_p_ff)
+#ifdef FEAT_MBYTE
+		+ STRLEN(buf->b_p_fenc)
+#endif
+						 + 15));
+    if (eap->cmd == NULL)
+	return FAIL;
+
+#ifdef FEAT_MBYTE
+    sprintf((char *)eap->cmd, "e ++ff=%s ++enc=%s", buf->b_p_ff, buf->b_p_fenc);
+    eap->force_enc = 14 + (int)STRLEN(buf->b_p_ff);
+    eap->bad_char = buf->b_bad_char;
+#else
+    sprintf((char *)eap->cmd, "e ++ff=%s", buf->b_p_ff);
+#endif
+    eap->force_ff = 7;
+
+    eap->force_bin = buf->b_p_bin ? FORCE_BIN : FORCE_NOBIN;
+    eap->read_edit = FALSE;
+    eap->forceit = FALSE;
+    return OK;
+}
+
+#ifdef FEAT_MBYTE
+/*
+ * Find next fileencoding to use from 'fileencodings'.
+ * "pp" points to fenc_next.  It's advanced to the next item.
+ * When there are no more items, an empty string is returned and *pp is set to
+ * NULL.
+ * When *pp is not set to NULL, the result is in allocated memory.
+ */
+    static char_u *
+next_fenc(pp)
+    char_u	**pp;
+{
+    char_u	*p;
+    char_u	*r;
+
+    if (**pp == NUL)
+    {
+	*pp = NULL;
+	return (char_u *)"";
+    }
+    p = vim_strchr(*pp, ',');
+    if (p == NULL)
+    {
+	r = enc_canonize(*pp);
+	*pp += STRLEN(*pp);
+    }
+    else
+    {
+	r = vim_strnsave(*pp, (int)(p - *pp));
+	*pp = p + 1;
+	if (r != NULL)
+	{
+	    p = enc_canonize(r);
+	    vim_free(r);
+	    r = p;
+	}
+    }
+    if (r == NULL)	/* out of memory */
+    {
+	r = (char_u *)"";
+	*pp = NULL;
+    }
+    return r;
+}
+
+# ifdef FEAT_EVAL
+/*
+ * Convert a file with the 'charconvert' expression.
+ * This closes the file which is to be read, converts it and opens the
+ * resulting file for reading.
+ * Returns name of the resulting converted file (the caller should delete it
+ * after reading it).
+ * Returns NULL if the conversion failed ("*fdp" is not set) .
+ */
+    static char_u *
+readfile_charconvert(fname, fenc, fdp)
+    char_u	*fname;		/* name of input file */
+    char_u	*fenc;		/* converted from */
+    int		*fdp;		/* in/out: file descriptor of file */
+{
+    char_u	*tmpname;
+    char_u	*errmsg = NULL;
+
+    tmpname = vim_tempname('r');
+    if (tmpname == NULL)
+	errmsg = (char_u *)_("Can't find temp file for conversion");
+    else
+    {
+	close(*fdp);		/* close the input file, ignore errors */
+	*fdp = -1;
+	if (eval_charconvert(fenc, enc_utf8 ? (char_u *)"utf-8" : p_enc,
+						      fname, tmpname) == FAIL)
+	    errmsg = (char_u *)_("Conversion with 'charconvert' failed");
+	if (errmsg == NULL && (*fdp = mch_open((char *)tmpname,
+						  O_RDONLY | O_EXTRA, 0)) < 0)
+	    errmsg = (char_u *)_("can't read output of 'charconvert'");
+    }
+
+    if (errmsg != NULL)
+    {
+	/* Don't use emsg(), it breaks mappings, the retry with
+	 * another type of conversion might still work. */
+	MSG(errmsg);
+	if (tmpname != NULL)
+	{
+	    mch_remove(tmpname);	/* delete converted file */
+	    vim_free(tmpname);
+	    tmpname = NULL;
+	}
+    }
+
+    /* If the input file is closed, open it (caller should check for error). */
+    if (*fdp < 0)
+	*fdp = mch_open((char *)fname, O_RDONLY | O_EXTRA, 0);
+
+    return tmpname;
+}
+# endif
+
+#endif
+
+#ifdef FEAT_VIMINFO
+/*
+ * Read marks for the current buffer from the viminfo file, when we support
+ * buffer marks and the buffer has a name.
+ */
+    static void
+check_marks_read()
+{
+    if (!curbuf->b_marks_read && get_viminfo_parameter('\'') > 0
+						  && curbuf->b_ffname != NULL)
+	read_viminfo(NULL, FALSE, TRUE, FALSE);
+
+    /* Always set b_marks_read; needed when 'viminfo' is changed to include
+     * the ' parameter after opening a buffer. */
+    curbuf->b_marks_read = TRUE;
+}
+#endif
+
+#ifdef FEAT_CRYPT
+/*
+ * Check for magic number used for encryption.
+ * If found, the magic number is removed from ptr[*sizep] and *sizep and
+ * *filesizep are updated.
+ * Return the (new) encryption key, NULL for no encryption.
+ */
+    static char_u *
+check_for_cryptkey(cryptkey, ptr, sizep, filesizep, newfile)
+    char_u	*cryptkey;	/* previous encryption key or NULL */
+    char_u	*ptr;		/* pointer to read bytes */
+    long	*sizep;		/* length of read bytes */
+    long	*filesizep;	/* nr of bytes used from file */
+    int		newfile;	/* editing a new buffer */
+{
+    if (*sizep >= CRYPT_MAGIC_LEN
+	    && STRNCMP(ptr, CRYPT_MAGIC, CRYPT_MAGIC_LEN) == 0)
+    {
+	if (cryptkey == NULL)
+	{
+	    if (*curbuf->b_p_key)
+		cryptkey = curbuf->b_p_key;
+	    else
+	    {
+		/* When newfile is TRUE, store the typed key
+		 * in the 'key' option and don't free it. */
+		cryptkey = get_crypt_key(newfile, FALSE);
+		/* check if empty key entered */
+		if (cryptkey != NULL && *cryptkey == NUL)
+		{
+		    if (cryptkey != curbuf->b_p_key)
+			vim_free(cryptkey);
+		    cryptkey = NULL;
+		}
+	    }
+	}
+
+	if (cryptkey != NULL)
+	{
+	    crypt_init_keys(cryptkey);
+
+	    /* Remove magic number from the text */
+	    *filesizep += CRYPT_MAGIC_LEN;
+	    *sizep -= CRYPT_MAGIC_LEN;
+	    mch_memmove(ptr, ptr + CRYPT_MAGIC_LEN, (size_t)*sizep);
+	}
+    }
+    /* When starting to edit a new file which does not have
+     * encryption, clear the 'key' option, except when
+     * starting up (called with -x argument) */
+    else if (newfile && *curbuf->b_p_key && !starting)
+	set_option_value((char_u *)"key", 0L, (char_u *)"", OPT_LOCAL);
+
+    return cryptkey;
+}
+#endif
+
+#ifdef UNIX
+    static void
+set_file_time(fname, atime, mtime)
+    char_u  *fname;
+    time_t  atime;	    /* access time */
+    time_t  mtime;	    /* modification time */
+{
+# if defined(HAVE_UTIME) && defined(HAVE_UTIME_H)
+    struct utimbuf  buf;
+
+    buf.actime	= atime;
+    buf.modtime	= mtime;
+    (void)utime((char *)fname, &buf);
+# else
+#  if defined(HAVE_UTIMES)
+    struct timeval  tvp[2];
+
+    tvp[0].tv_sec   = atime;
+    tvp[0].tv_usec  = 0;
+    tvp[1].tv_sec   = mtime;
+    tvp[1].tv_usec  = 0;
+#   ifdef NeXT
+    (void)utimes((char *)fname, tvp);
+#   else
+    (void)utimes((char *)fname, (const struct timeval *)&tvp);
+#   endif
+#  endif
+# endif
+}
+#endif /* UNIX */
+
+#if defined(VMS) && !defined(MIN)
+/* Older DECC compiler for VAX doesn't define MIN() */
+# define MIN(a, b) ((a) < (b) ? (a) : (b))
+#endif
+
+/*
+ * buf_write() - write to file "fname" lines "start" through "end"
+ *
+ * We do our own buffering here because fwrite() is so slow.
+ *
+ * If "forceit" is true, we don't care for errors when attempting backups.
+ * In case of an error everything possible is done to restore the original
+ * file.  But when "forceit" is TRUE, we risk loosing it.
+ *
+ * When "reset_changed" is TRUE and "append" == FALSE and "start" == 1 and
+ * "end" == curbuf->b_ml.ml_line_count, reset curbuf->b_changed.
+ *
+ * This function must NOT use NameBuff (because it's called by autowrite()).
+ *
+ * return FAIL for failure, OK otherwise
+ */
+    int
+buf_write(buf, fname, sfname, start, end, eap, append, forceit,
+						      reset_changed, filtering)
+    buf_T	    *buf;
+    char_u	    *fname;
+    char_u	    *sfname;
+    linenr_T	    start, end;
+    exarg_T	    *eap;		/* for forced 'ff' and 'fenc', can be
+					   NULL! */
+    int		    append;		/* append to the file */
+    int		    forceit;
+    int		    reset_changed;
+    int		    filtering;
+{
+    int		    fd;
+    char_u	    *backup = NULL;
+    int		    backup_copy = FALSE; /* copy the original file? */
+    int		    dobackup;
+    char_u	    *ffname;
+    char_u	    *wfname = NULL;	/* name of file to write to */
+    char_u	    *s;
+    char_u	    *ptr;
+    char_u	    c;
+    int		    len;
+    linenr_T	    lnum;
+    long	    nchars;
+    char_u	    *errmsg = NULL;
+    char_u	    *errnum = NULL;
+    char_u	    *buffer;
+    char_u	    smallbuf[SMBUFSIZE];
+    char_u	    *backup_ext;
+    int		    bufsize;
+    long	    perm;		    /* file permissions */
+    int		    retval = OK;
+    int		    newfile = FALSE;	    /* TRUE if file doesn't exist yet */
+    int		    msg_save = msg_scroll;
+    int		    overwriting;	    /* TRUE if writing over original */
+    int		    no_eol = FALSE;	    /* no end-of-line written */
+    int		    device = FALSE;	    /* writing to a device */
+    struct stat	    st_old;
+    int		    prev_got_int = got_int;
+    int		    file_readonly = FALSE;  /* overwritten file is read-only */
+    static char	    *err_readonly = "is read-only (cannot override: \"W\" in 'cpoptions')";
+#if defined(UNIX) || defined(__EMX__XX)	    /*XXX fix me sometime? */
+    int		    made_writable = FALSE;  /* 'w' bit has been set */
+#endif
+					/* writing everything */
+    int		    whole = (start == 1 && end == buf->b_ml.ml_line_count);
+#ifdef FEAT_AUTOCMD
+    linenr_T	    old_line_count = buf->b_ml.ml_line_count;
+#endif
+    int		    attr;
+    int		    fileformat;
+    int		    write_bin;
+    struct bw_info  write_info;		/* info for buf_write_bytes() */
+#ifdef FEAT_MBYTE
+    int		    converted = FALSE;
+    int		    notconverted = FALSE;
+    char_u	    *fenc;		/* effective 'fileencoding' */
+    char_u	    *fenc_tofree = NULL; /* allocated "fenc" */
+#endif
+#ifdef HAS_BW_FLAGS
+    int		    wb_flags = 0;
+#endif
+#ifdef HAVE_ACL
+    vim_acl_T	    acl = NULL;		/* ACL copied from original file to
+					   backup or new file */
+#endif
+
+    if (fname == NULL || *fname == NUL)	/* safety check */
+	return FAIL;
+
+    /*
+     * Disallow writing from .exrc and .vimrc in current directory for
+     * security reasons.
+     */
+    if (check_secure())
+	return FAIL;
+
+    /* Avoid a crash for a long name. */
+    if (STRLEN(fname) >= MAXPATHL)
+    {
+	EMSG(_(e_longname));
+	return FAIL;
+    }
+
+#ifdef FEAT_MBYTE
+    /* must init bw_conv_buf and bw_iconv_fd before jumping to "fail" */
+    write_info.bw_conv_buf = NULL;
+    write_info.bw_conv_error = FALSE;
+    write_info.bw_restlen = 0;
+# ifdef USE_ICONV
+    write_info.bw_iconv_fd = (iconv_t)-1;
+# endif
+#endif
+
+    /* After writing a file changedtick changes but we don't want to display
+     * the line. */
+    ex_no_reprint = TRUE;
+
+    /*
+     * If there is no file name yet, use the one for the written file.
+     * BF_NOTEDITED is set to reflect this (in case the write fails).
+     * Don't do this when the write is for a filter command.
+     * Don't do this when appending.
+     * Only do this when 'cpoptions' contains the 'F' flag.
+     */
+    if (buf->b_ffname == NULL
+	    && reset_changed
+	    && whole
+	    && buf == curbuf
+#ifdef FEAT_QUICKFIX
+	    && !bt_nofile(buf)
+#endif
+	    && !filtering
+	    && (!append || vim_strchr(p_cpo, CPO_FNAMEAPP) != NULL)
+	    && vim_strchr(p_cpo, CPO_FNAMEW) != NULL)
+    {
+	if (set_rw_fname(fname, sfname) == FAIL)
+	    return FAIL;
+	buf = curbuf;	    /* just in case autocmds made "buf" invalid */
+    }
+
+    if (sfname == NULL)
+	sfname = fname;
+    /*
+     * For Unix: Use the short file name whenever possible.
+     * Avoids problems with networks and when directory names are changed.
+     * Don't do this for MS-DOS, a "cd" in a sub-shell may have moved us to
+     * another directory, which we don't detect
+     */
+    ffname = fname;			    /* remember full fname */
+#ifdef UNIX
+    fname = sfname;
+#endif
+
+    if (buf->b_ffname != NULL && fnamecmp(ffname, buf->b_ffname) == 0)
+	overwriting = TRUE;
+    else
+	overwriting = FALSE;
+
+    if (exiting)
+	settmode(TMODE_COOK);	    /* when exiting allow typahead now */
+
+    ++no_wait_return;		    /* don't wait for return yet */
+
+    /*
+     * Set '[ and '] marks to the lines to be written.
+     */
+    buf->b_op_start.lnum = start;
+    buf->b_op_start.col = 0;
+    buf->b_op_end.lnum = end;
+    buf->b_op_end.col = 0;
+
+#ifdef FEAT_AUTOCMD
+    {
+	aco_save_T	aco;
+	int		buf_ffname = FALSE;
+	int		buf_sfname = FALSE;
+	int		buf_fname_f = FALSE;
+	int		buf_fname_s = FALSE;
+	int		did_cmd = FALSE;
+	int		nofile_err = FALSE;
+	int		empty_memline = (buf->b_ml.ml_mfp == NULL);
+
+	/*
+	 * Apply PRE aucocommands.
+	 * Set curbuf to the buffer to be written.
+	 * Careful: The autocommands may call buf_write() recursively!
+	 */
+	if (ffname == buf->b_ffname)
+	    buf_ffname = TRUE;
+	if (sfname == buf->b_sfname)
+	    buf_sfname = TRUE;
+	if (fname == buf->b_ffname)
+	    buf_fname_f = TRUE;
+	if (fname == buf->b_sfname)
+	    buf_fname_s = TRUE;
+
+	/* set curwin/curbuf to buf and save a few things */
+	aucmd_prepbuf(&aco, buf);
+
+	if (append)
+	{
+	    if (!(did_cmd = apply_autocmds_exarg(EVENT_FILEAPPENDCMD,
+					 sfname, sfname, FALSE, curbuf, eap)))
+	    {
+#ifdef FEAT_QUICKFIX
+		if (overwriting && bt_nofile(curbuf))
+		    nofile_err = TRUE;
+		else
+#endif
+		    apply_autocmds_exarg(EVENT_FILEAPPENDPRE,
+					  sfname, sfname, FALSE, curbuf, eap);
+	    }
+	}
+	else if (filtering)
+	{
+	    apply_autocmds_exarg(EVENT_FILTERWRITEPRE,
+					    NULL, sfname, FALSE, curbuf, eap);
+	}
+	else if (reset_changed && whole)
+	{
+	    if (!(did_cmd = apply_autocmds_exarg(EVENT_BUFWRITECMD,
+					 sfname, sfname, FALSE, curbuf, eap)))
+	    {
+#ifdef FEAT_QUICKFIX
+		if (overwriting && bt_nofile(curbuf))
+		    nofile_err = TRUE;
+		else
+#endif
+		    apply_autocmds_exarg(EVENT_BUFWRITEPRE,
+					  sfname, sfname, FALSE, curbuf, eap);
+	    }
+	}
+	else
+	{
+	    if (!(did_cmd = apply_autocmds_exarg(EVENT_FILEWRITECMD,
+					 sfname, sfname, FALSE, curbuf, eap)))
+	    {
+#ifdef FEAT_QUICKFIX
+		if (overwriting && bt_nofile(curbuf))
+		    nofile_err = TRUE;
+		else
+#endif
+		    apply_autocmds_exarg(EVENT_FILEWRITEPRE,
+					  sfname, sfname, FALSE, curbuf, eap);
+	    }
+	}
+
+	/* restore curwin/curbuf and a few other things */
+	aucmd_restbuf(&aco);
+
+	/*
+	 * In three situations we return here and don't write the file:
+	 * 1. the autocommands deleted or unloaded the buffer.
+	 * 2. The autocommands abort script processing.
+	 * 3. If one of the "Cmd" autocommands was executed.
+	 */
+	if (!buf_valid(buf))
+	    buf = NULL;
+	if (buf == NULL || (buf->b_ml.ml_mfp == NULL && !empty_memline)
+				       || did_cmd || nofile_err
+#ifdef FEAT_EVAL
+				       || aborting()
+#endif
+				       )
+	{
+	    --no_wait_return;
+	    msg_scroll = msg_save;
+	    if (nofile_err)
+		EMSG(_("E676: No matching autocommands for acwrite buffer"));
+
+	    if (nofile_err
+#ifdef FEAT_EVAL
+		    || aborting()
+#endif
+		    )
+		/* An aborting error, interrupt or exception in the
+		 * autocommands. */
+		return FAIL;
+	    if (did_cmd)
+	    {
+		if (buf == NULL)
+		    /* The buffer was deleted.  We assume it was written
+		     * (can't retry anyway). */
+		    return OK;
+		if (overwriting)
+		{
+		    /* Assume the buffer was written, update the timestamp. */
+		    ml_timestamp(buf);
+		    if (append)
+			buf->b_flags &= ~BF_NEW;
+		    else
+			buf->b_flags &= ~BF_WRITE_MASK;
+		}
+		if (reset_changed && buf->b_changed && !append
+			&& (overwriting || vim_strchr(p_cpo, CPO_PLUS) != NULL))
+		    /* Buffer still changed, the autocommands didn't work
+		     * properly. */
+		    return FAIL;
+		return OK;
+	    }
+#ifdef FEAT_EVAL
+	    if (!aborting())
+#endif
+		EMSG(_("E203: Autocommands deleted or unloaded buffer to be written"));
+	    return FAIL;
+	}
+
+	/*
+	 * The autocommands may have changed the number of lines in the file.
+	 * When writing the whole file, adjust the end.
+	 * When writing part of the file, assume that the autocommands only
+	 * changed the number of lines that are to be written (tricky!).
+	 */
+	if (buf->b_ml.ml_line_count != old_line_count)
+	{
+	    if (whole)						/* write all */
+		end = buf->b_ml.ml_line_count;
+	    else if (buf->b_ml.ml_line_count > old_line_count)	/* more lines */
+		end += buf->b_ml.ml_line_count - old_line_count;
+	    else						/* less lines */
+	    {
+		end -= old_line_count - buf->b_ml.ml_line_count;
+		if (end < start)
+		{
+		    --no_wait_return;
+		    msg_scroll = msg_save;
+		    EMSG(_("E204: Autocommand changed number of lines in unexpected way"));
+		    return FAIL;
+		}
+	    }
+	}
+
+	/*
+	 * The autocommands may have changed the name of the buffer, which may
+	 * be kept in fname, ffname and sfname.
+	 */
+	if (buf_ffname)
+	    ffname = buf->b_ffname;
+	if (buf_sfname)
+	    sfname = buf->b_sfname;
+	if (buf_fname_f)
+	    fname = buf->b_ffname;
+	if (buf_fname_s)
+	    fname = buf->b_sfname;
+    }
+#endif
+
+#ifdef FEAT_NETBEANS_INTG
+    if (usingNetbeans && isNetbeansBuffer(buf))
+    {
+	if (whole)
+	{
+	    /*
+	     * b_changed can be 0 after an undo, but we still need to write
+	     * the buffer to NetBeans.
+	     */
+	    if (buf->b_changed || isNetbeansModified(buf))
+	    {
+		--no_wait_return;		/* may wait for return now */
+		msg_scroll = msg_save;
+		netbeans_save_buffer(buf);	/* no error checking... */
+		return retval;
+	    }
+	    else
+	    {
+		errnum = (char_u *)"E656: ";
+		errmsg = (char_u *)_("NetBeans dissallows writes of unmodified buffers");
+		buffer = NULL;
+		goto fail;
+	    }
+	}
+	else
+	{
+	    errnum = (char_u *)"E657: ";
+	    errmsg = (char_u *)_("Partial writes disallowed for NetBeans buffers");
+	    buffer = NULL;
+	    goto fail;
+	}
+    }
+#endif
+
+    if (shortmess(SHM_OVER) && !exiting)
+	msg_scroll = FALSE;	    /* overwrite previous file message */
+    else
+	msg_scroll = TRUE;	    /* don't overwrite previous file message */
+    if (!filtering)
+	filemess(buf,
+#ifndef UNIX
+		sfname,
+#else
+		fname,
+#endif
+		    (char_u *)"", 0);	/* show that we are busy */
+    msg_scroll = FALSE;		    /* always overwrite the file message now */
+
+    buffer = alloc(BUFSIZE);
+    if (buffer == NULL)		    /* can't allocate big buffer, use small
+				     * one (to be able to write when out of
+				     * memory) */
+    {
+	buffer = smallbuf;
+	bufsize = SMBUFSIZE;
+    }
+    else
+	bufsize = BUFSIZE;
+
+    /*
+     * Get information about original file (if there is one).
+     */
+#if defined(UNIX) && !defined(ARCHIE)
+    st_old.st_dev = st_old.st_ino = 0;
+    perm = -1;
+    if (mch_stat((char *)fname, &st_old) < 0)
+	newfile = TRUE;
+    else
+    {
+	perm = st_old.st_mode;
+	if (!S_ISREG(st_old.st_mode))		/* not a file */
+	{
+	    if (S_ISDIR(st_old.st_mode))
+	    {
+		errnum = (char_u *)"E502: ";
+		errmsg = (char_u *)_("is a directory");
+		goto fail;
+	    }
+	    if (mch_nodetype(fname) != NODE_WRITABLE)
+	    {
+		errnum = (char_u *)"E503: ";
+		errmsg = (char_u *)_("is not a file or writable device");
+		goto fail;
+	    }
+	    /* It's a device of some kind (or a fifo) which we can write to
+	     * but for which we can't make a backup. */
+	    device = TRUE;
+	    newfile = TRUE;
+	    perm = -1;
+	}
+    }
+#else /* !UNIX */
+    /*
+     * Check for a writable device name.
+     */
+    c = mch_nodetype(fname);
+    if (c == NODE_OTHER)
+    {
+	errnum = (char_u *)"E503: ";
+	errmsg = (char_u *)_("is not a file or writable device");
+	goto fail;
+    }
+    if (c == NODE_WRITABLE)
+    {
+# if defined(MSDOS) || defined(MSWIN) || defined(OS2)
+	/* MS-Windows allows opening a device, but we will probably get stuck
+	 * trying to write to it.  */
+	if (!p_odev)
+	{
+	    errnum = (char_u *)"E796: ";
+	    errmsg = (char_u *)_("writing to device disabled with 'opendevice' option");
+	    goto fail;
+	}
+# endif
+	device = TRUE;
+	newfile = TRUE;
+	perm = -1;
+    }
+    else
+    {
+	perm = mch_getperm(fname);
+	if (perm < 0)
+	    newfile = TRUE;
+	else if (mch_isdir(fname))
+	{
+	    errnum = (char_u *)"E502: ";
+	    errmsg = (char_u *)_("is a directory");
+	    goto fail;
+	}
+	if (overwriting)
+	    (void)mch_stat((char *)fname, &st_old);
+    }
+#endif /* !UNIX */
+
+    if (!device && !newfile)
+    {
+	/*
+	 * Check if the file is really writable (when renaming the file to
+	 * make a backup we won't discover it later).
+	 */
+	file_readonly = (
+# ifdef USE_MCH_ACCESS
+#  ifdef UNIX
+		    (perm & 0222) == 0 ||
+#  endif
+		    mch_access((char *)fname, W_OK)
+# else
+		    (fd = mch_open((char *)fname, O_RDWR | O_EXTRA, 0)) < 0
+						   ? TRUE : (close(fd), FALSE)
+# endif
+		    );
+	if (!forceit && file_readonly)
+	{
+	    if (vim_strchr(p_cpo, CPO_FWRITE) != NULL)
+	    {
+		errnum = (char_u *)"E504: ";
+		errmsg = (char_u *)_(err_readonly);
+	    }
+	    else
+	    {
+		errnum = (char_u *)"E505: ";
+		errmsg = (char_u *)_("is read-only (add ! to override)");
+	    }
+	    goto fail;
+	}
+
+	/*
+	 * Check if the timestamp hasn't changed since reading the file.
+	 */
+	if (overwriting)
+	{
+	    retval = check_mtime(buf, &st_old);
+	    if (retval == FAIL)
+		goto fail;
+	}
+    }
+
+#ifdef HAVE_ACL
+    /*
+     * For systems that support ACL: get the ACL from the original file.
+     */
+    if (!newfile)
+	acl = mch_get_acl(fname);
+#endif
+
+    /*
+     * If 'backupskip' is not empty, don't make a backup for some files.
+     */
+    dobackup = (p_wb || p_bk || *p_pm != NUL);
+#ifdef FEAT_WILDIGN
+    if (dobackup && *p_bsk != NUL && match_file_list(p_bsk, sfname, ffname))
+	dobackup = FALSE;
+#endif
+
+    /*
+     * Save the value of got_int and reset it.  We don't want a previous
+     * interruption cancel writing, only hitting CTRL-C while writing should
+     * abort it.
+     */
+    prev_got_int = got_int;
+    got_int = FALSE;
+
+    /* Mark the buffer as 'being saved' to prevent changed buffer warnings */
+    buf->b_saving = TRUE;
+
+    /*
+     * If we are not appending or filtering, the file exists, and the
+     * 'writebackup', 'backup' or 'patchmode' option is set, need a backup.
+     * When 'patchmode' is set also make a backup when appending.
+     *
+     * Do not make any backup, if 'writebackup' and 'backup' are both switched
+     * off.  This helps when editing large files on almost-full disks.
+     */
+    if (!(append && *p_pm == NUL) && !filtering && perm >= 0 && dobackup)
+    {
+#if defined(UNIX) || defined(WIN32)
+	struct stat st;
+#endif
+
+	if ((bkc_flags & BKC_YES) || append)	/* "yes" */
+	    backup_copy = TRUE;
+#if defined(UNIX) || defined(WIN32)
+	else if ((bkc_flags & BKC_AUTO))	/* "auto" */
+	{
+	    int		i;
+
+# ifdef UNIX
+	    /*
+	     * Don't rename the file when:
+	     * - it's a hard link
+	     * - it's a symbolic link
+	     * - we don't have write permission in the directory
+	     * - we can't set the owner/group of the new file
+	     */
+	    if (st_old.st_nlink > 1
+		    || mch_lstat((char *)fname, &st) < 0
+		    || st.st_dev != st_old.st_dev
+		    || st.st_ino != st_old.st_ino
+#  ifndef HAVE_FCHOWN
+		    || st.st_uid != st_old.st_uid
+		    || st.st_gid != st_old.st_gid
+#  endif
+		    )
+		backup_copy = TRUE;
+	    else
+# else
+#  ifdef WIN32
+	    /* On NTFS file systems hard links are possible. */
+	    if (mch_is_linked(fname))
+		backup_copy = TRUE;
+	    else
+#  endif
+# endif
+	    {
+		/*
+		 * Check if we can create a file and set the owner/group to
+		 * the ones from the original file.
+		 * First find a file name that doesn't exist yet (use some
+		 * arbitrary numbers).
+		 */
+		STRCPY(IObuff, fname);
+		for (i = 4913; ; i += 123)
+		{
+		    sprintf((char *)gettail(IObuff), "%d", i);
+		    if (mch_lstat((char *)IObuff, &st) < 0)
+			break;
+		}
+		fd = mch_open((char *)IObuff,
+				    O_CREAT|O_WRONLY|O_EXCL|O_NOFOLLOW, perm);
+		if (fd < 0)	/* can't write in directory */
+		    backup_copy = TRUE;
+		else
+		{
+# ifdef UNIX
+#  ifdef HAVE_FCHOWN
+		    fchown(fd, st_old.st_uid, st_old.st_gid);
+#  endif
+		    if (mch_stat((char *)IObuff, &st) < 0
+			    || st.st_uid != st_old.st_uid
+			    || st.st_gid != st_old.st_gid
+			    || st.st_mode != perm)
+			backup_copy = TRUE;
+# endif
+		    /* Close the file before removing it, on MS-Windows we
+		     * can't delete an open file. */
+		    close(fd);
+		    mch_remove(IObuff);
+		}
+	    }
+	}
+
+# ifdef UNIX
+	/*
+	 * Break symlinks and/or hardlinks if we've been asked to.
+	 */
+	if ((bkc_flags & BKC_BREAKSYMLINK) || (bkc_flags & BKC_BREAKHARDLINK))
+	{
+	    int	lstat_res;
+
+	    lstat_res = mch_lstat((char *)fname, &st);
+
+	    /* Symlinks. */
+	    if ((bkc_flags & BKC_BREAKSYMLINK)
+		    && lstat_res == 0
+		    && st.st_ino != st_old.st_ino)
+		backup_copy = FALSE;
+
+	    /* Hardlinks. */
+	    if ((bkc_flags & BKC_BREAKHARDLINK)
+		    && st_old.st_nlink > 1
+		    && (lstat_res != 0 || st.st_ino == st_old.st_ino))
+		backup_copy = FALSE;
+	}
+#endif
+
+#endif
+
+	/* make sure we have a valid backup extension to use */
+	if (*p_bex == NUL)
+	{
+#ifdef RISCOS
+	    backup_ext = (char_u *)"/bak";
+#else
+	    backup_ext = (char_u *)".bak";
+#endif
+	}
+	else
+	    backup_ext = p_bex;
+
+	if (backup_copy
+		&& (fd = mch_open((char *)fname, O_RDONLY | O_EXTRA, 0)) >= 0)
+	{
+	    int		bfd;
+	    char_u	*copybuf, *wp;
+	    int		some_error = FALSE;
+	    struct stat	st_new;
+	    char_u	*dirp;
+	    char_u	*rootname;
+#if defined(UNIX) && !defined(SHORT_FNAME)
+	    int		did_set_shortname;
+#endif
+
+	    copybuf = alloc(BUFSIZE + 1);
+	    if (copybuf == NULL)
+	    {
+		some_error = TRUE;	    /* out of memory */
+		goto nobackup;
+	    }
+
+	    /*
+	     * Try to make the backup in each directory in the 'bdir' option.
+	     *
+	     * Unix semantics has it, that we may have a writable file,
+	     * that cannot be recreated with a simple open(..., O_CREAT, ) e.g:
+	     *  - the directory is not writable,
+	     *  - the file may be a symbolic link,
+	     *  - the file may belong to another user/group, etc.
+	     *
+	     * For these reasons, the existing writable file must be truncated
+	     * and reused. Creation of a backup COPY will be attempted.
+	     */
+	    dirp = p_bdir;
+	    while (*dirp)
+	    {
+#ifdef UNIX
+		st_new.st_ino = 0;
+		st_new.st_dev = 0;
+		st_new.st_gid = 0;
+#endif
+
+		/*
+		 * Isolate one directory name, using an entry in 'bdir'.
+		 */
+		(void)copy_option_part(&dirp, copybuf, BUFSIZE, ",");
+		rootname = get_file_in_dir(fname, copybuf);
+		if (rootname == NULL)
+		{
+		    some_error = TRUE;	    /* out of memory */
+		    goto nobackup;
+		}
+
+#if defined(UNIX) && !defined(SHORT_FNAME)
+		did_set_shortname = FALSE;
+#endif
+
+		/*
+		 * May try twice if 'shortname' not set.
+		 */
+		for (;;)
+		{
+		    /*
+		     * Make backup file name.
+		     */
+		    backup = buf_modname(
+#ifdef SHORT_FNAME
+			    TRUE,
+#else
+			    (buf->b_p_sn || buf->b_shortname),
+#endif
+						 rootname, backup_ext, FALSE);
+		    if (backup == NULL)
+		    {
+			vim_free(rootname);
+			some_error = TRUE;		/* out of memory */
+			goto nobackup;
+		    }
+
+		    /*
+		     * Check if backup file already exists.
+		     */
+		    if (mch_stat((char *)backup, &st_new) >= 0)
+		    {
+#ifdef UNIX
+			/*
+			 * Check if backup file is same as original file.
+			 * May happen when modname() gave the same file back.
+			 * E.g. silly link, or file name-length reached.
+			 * If we don't check here, we either ruin the file
+			 * when copying or erase it after writing. jw.
+			 */
+			if (st_new.st_dev == st_old.st_dev
+					    && st_new.st_ino == st_old.st_ino)
+			{
+			    vim_free(backup);
+			    backup = NULL;	/* no backup file to delete */
+# ifndef SHORT_FNAME
+			    /*
+			     * may try again with 'shortname' set
+			     */
+			    if (!(buf->b_shortname || buf->b_p_sn))
+			    {
+				buf->b_shortname = TRUE;
+				did_set_shortname = TRUE;
+				continue;
+			    }
+				/* setting shortname didn't help */
+			    if (did_set_shortname)
+				buf->b_shortname = FALSE;
+# endif
+			    break;
+			}
+#endif
+
+			/*
+			 * If we are not going to keep the backup file, don't
+			 * delete an existing one, try to use another name.
+			 * Change one character, just before the extension.
+			 */
+			if (!p_bk)
+			{
+			    wp = backup + STRLEN(backup) - 1
+							 - STRLEN(backup_ext);
+			    if (wp < backup)	/* empty file name ??? */
+				wp = backup;
+			    *wp = 'z';
+			    while (*wp > 'a'
+				    && mch_stat((char *)backup, &st_new) >= 0)
+				--*wp;
+			    /* They all exist??? Must be something wrong. */
+			    if (*wp == 'a')
+			    {
+				vim_free(backup);
+				backup = NULL;
+			    }
+			}
+		    }
+		    break;
+		}
+		vim_free(rootname);
+
+		/*
+		 * Try to create the backup file
+		 */
+		if (backup != NULL)
+		{
+		    /* remove old backup, if present */
+		    mch_remove(backup);
+		    /* Open with O_EXCL to avoid the file being created while
+		     * we were sleeping (symlink hacker attack?) */
+		    bfd = mch_open((char *)backup,
+				O_WRONLY|O_CREAT|O_EXTRA|O_EXCL|O_NOFOLLOW,
+								 perm & 0777);
+		    if (bfd < 0)
+		    {
+			vim_free(backup);
+			backup = NULL;
+		    }
+		    else
+		    {
+			/* set file protection same as original file, but
+			 * strip s-bit */
+			(void)mch_setperm(backup, perm & 0777);
+
+#ifdef UNIX
+			/*
+			 * Try to set the group of the backup same as the
+			 * original file. If this fails, set the protection
+			 * bits for the group same as the protection bits for
+			 * others.
+			 */
+			if (st_new.st_gid != st_old.st_gid
+# ifdef HAVE_FCHOWN  /* sequent-ptx lacks fchown() */
+				&& fchown(bfd, (uid_t)-1, st_old.st_gid) != 0
+# endif
+						)
+			    mch_setperm(backup,
+					  (perm & 0707) | ((perm & 07) << 3));
+#endif
+
+			/*
+			 * copy the file.
+			 */
+			write_info.bw_fd = bfd;
+			write_info.bw_buf = copybuf;
+#ifdef HAS_BW_FLAGS
+			write_info.bw_flags = FIO_NOCONVERT;
+#endif
+			while ((write_info.bw_len = vim_read(fd, copybuf,
+								BUFSIZE)) > 0)
+			{
+			    if (buf_write_bytes(&write_info) == FAIL)
+			    {
+				errmsg = (char_u *)_("E506: Can't write to backup file (add ! to override)");
+				break;
+			    }
+			    ui_breakcheck();
+			    if (got_int)
+			    {
+				errmsg = (char_u *)_(e_interr);
+				break;
+			    }
+			}
+
+			if (close(bfd) < 0 && errmsg == NULL)
+			    errmsg = (char_u *)_("E507: Close error for backup file (add ! to override)");
+			if (write_info.bw_len < 0)
+			    errmsg = (char_u *)_("E508: Can't read file for backup (add ! to override)");
+#ifdef UNIX
+			set_file_time(backup, st_old.st_atime, st_old.st_mtime);
+#endif
+#ifdef HAVE_ACL
+			mch_set_acl(backup, acl);
+#endif
+			break;
+		    }
+		}
+	    }
+    nobackup:
+	    close(fd);		/* ignore errors for closing read file */
+	    vim_free(copybuf);
+
+	    if (backup == NULL && errmsg == NULL)
+		errmsg = (char_u *)_("E509: Cannot create backup file (add ! to override)");
+	    /* ignore errors when forceit is TRUE */
+	    if ((some_error || errmsg != NULL) && !forceit)
+	    {
+		retval = FAIL;
+		goto fail;
+	    }
+	    errmsg = NULL;
+	}
+	else
+	{
+	    char_u	*dirp;
+	    char_u	*p;
+	    char_u	*rootname;
+
+	    /*
+	     * Make a backup by renaming the original file.
+	     */
+	    /*
+	     * If 'cpoptions' includes the "W" flag, we don't want to
+	     * overwrite a read-only file.  But rename may be possible
+	     * anyway, thus we need an extra check here.
+	     */
+	    if (file_readonly && vim_strchr(p_cpo, CPO_FWRITE) != NULL)
+	    {
+		errnum = (char_u *)"E504: ";
+		errmsg = (char_u *)_(err_readonly);
+		goto fail;
+	    }
+
+	    /*
+	     *
+	     * Form the backup file name - change path/fo.o.h to
+	     * path/fo.o.h.bak Try all directories in 'backupdir', first one
+	     * that works is used.
+	     */
+	    dirp = p_bdir;
+	    while (*dirp)
+	    {
+		/*
+		 * Isolate one directory name and make the backup file name.
+		 */
+		(void)copy_option_part(&dirp, IObuff, IOSIZE, ",");
+		rootname = get_file_in_dir(fname, IObuff);
+		if (rootname == NULL)
+		    backup = NULL;
+		else
+		{
+		    backup = buf_modname(
+#ifdef SHORT_FNAME
+			    TRUE,
+#else
+			    (buf->b_p_sn || buf->b_shortname),
+#endif
+						 rootname, backup_ext, FALSE);
+		    vim_free(rootname);
+		}
+
+		if (backup != NULL)
+		{
+		    /*
+		     * If we are not going to keep the backup file, don't
+		     * delete an existing one, try to use another name.
+		     * Change one character, just before the extension.
+		     */
+		    if (!p_bk && mch_getperm(backup) >= 0)
+		    {
+			p = backup + STRLEN(backup) - 1 - STRLEN(backup_ext);
+			if (p < backup)	/* empty file name ??? */
+			    p = backup;
+			*p = 'z';
+			while (*p > 'a' && mch_getperm(backup) >= 0)
+			    --*p;
+			/* They all exist??? Must be something wrong! */
+			if (*p == 'a')
+			{
+			    vim_free(backup);
+			    backup = NULL;
+			}
+		    }
+		}
+		if (backup != NULL)
+		{
+		    /*
+		     * Delete any existing backup and move the current version
+		     * to the backup.	For safety, we don't remove the backup
+		     * until the write has finished successfully. And if the
+		     * 'backup' option is set, leave it around.
+		     */
+		    /*
+		     * If the renaming of the original file to the backup file
+		     * works, quit here.
+		     */
+		    if (vim_rename(fname, backup) == 0)
+			break;
+
+		    vim_free(backup);   /* don't do the rename below */
+		    backup = NULL;
+		}
+	    }
+	    if (backup == NULL && !forceit)
+	    {
+		errmsg = (char_u *)_("E510: Can't make backup file (add ! to override)");
+		goto fail;
+	    }
+	}
+    }
+
+#if defined(UNIX) && !defined(ARCHIE)
+    /* When using ":w!" and the file was read-only: make it writable */
+    if (forceit && perm >= 0 && !(perm & 0200) && st_old.st_uid == getuid()
+				     && vim_strchr(p_cpo, CPO_FWRITE) == NULL)
+    {
+	perm |= 0200;
+	(void)mch_setperm(fname, perm);
+	made_writable = TRUE;
+    }
+#endif
+
+    /* When using ":w!" and writing to the current file, 'readonly' makes no
+     * sense, reset it, unless 'Z' appears in 'cpoptions'.  */
+    if (forceit && overwriting && vim_strchr(p_cpo, CPO_KEEPRO) == NULL)
+    {
+	buf->b_p_ro = FALSE;
+#ifdef FEAT_TITLE
+	need_maketitle = TRUE;	    /* set window title later */
+#endif
+#ifdef FEAT_WINDOWS
+	status_redraw_all();	    /* redraw status lines later */
+#endif
+    }
+
+    if (end > buf->b_ml.ml_line_count)
+	end = buf->b_ml.ml_line_count;
+    if (buf->b_ml.ml_flags & ML_EMPTY)
+	start = end + 1;
+
+    /*
+     * If the original file is being overwritten, there is a small chance that
+     * we crash in the middle of writing. Therefore the file is preserved now.
+     * This makes all block numbers positive so that recovery does not need
+     * the original file.
+     * Don't do this if there is a backup file and we are exiting.
+     */
+    if (reset_changed && !newfile && overwriting
+					      && !(exiting && backup != NULL))
+    {
+	ml_preserve(buf, FALSE);
+	if (got_int)
+	{
+	    errmsg = (char_u *)_(e_interr);
+	    goto restore_backup;
+	}
+    }
+
+#ifdef MACOS_CLASSIC /* TODO: Is it need for MACOS_X? (Dany) */
+    /*
+     * Before risking to lose the original file verify if there's
+     * a resource fork to preserve, and if cannot be done warn
+     * the users. This happens when overwriting without backups.
+     */
+    if (backup == NULL && overwriting && !append)
+	if (mch_has_resource_fork(fname))
+	{
+	    errmsg = (char_u *)_("E460: The resource fork would be lost (add ! to override)");
+	    goto restore_backup;
+	}
+#endif
+
+#ifdef VMS
+    vms_remove_version(fname); /* remove version */
+#endif
+    /* Default: write the the file directly.  May write to a temp file for
+     * multi-byte conversion. */
+    wfname = fname;
+
+#ifdef FEAT_MBYTE
+    /* Check for forced 'fileencoding' from "++opt=val" argument. */
+    if (eap != NULL && eap->force_enc != 0)
+    {
+	fenc = eap->cmd + eap->force_enc;
+	fenc = enc_canonize(fenc);
+	fenc_tofree = fenc;
+    }
+    else
+	fenc = buf->b_p_fenc;
+
+    /*
+     * The file needs to be converted when 'fileencoding' is set and
+     * 'fileencoding' differs from 'encoding'.
+     */
+    converted = (*fenc != NUL && !same_encoding(p_enc, fenc));
+
+    /*
+     * Check if UTF-8 to UCS-2/4 or Latin1 conversion needs to be done.  Or
+     * Latin1 to Unicode conversion.  This is handled in buf_write_bytes().
+     * Prepare the flags for it and allocate bw_conv_buf when needed.
+     */
+    if (converted && (enc_utf8 || STRCMP(p_enc, "latin1") == 0))
+    {
+	wb_flags = get_fio_flags(fenc);
+	if (wb_flags & (FIO_UCS2 | FIO_UCS4 | FIO_UTF16 | FIO_UTF8))
+	{
+	    /* Need to allocate a buffer to translate into. */
+	    if (wb_flags & (FIO_UCS2 | FIO_UTF16 | FIO_UTF8))
+		write_info.bw_conv_buflen = bufsize * 2;
+	    else /* FIO_UCS4 */
+		write_info.bw_conv_buflen = bufsize * 4;
+	    write_info.bw_conv_buf
+			   = lalloc((long_u)write_info.bw_conv_buflen, TRUE);
+	    if (write_info.bw_conv_buf == NULL)
+		end = 0;
+	}
+    }
+
+# ifdef WIN3264
+    if (converted && wb_flags == 0 && (wb_flags = get_win_fio_flags(fenc)) != 0)
+    {
+	/* Convert UTF-8 -> UCS-2 and UCS-2 -> DBCS.  Worst-case * 4: */
+	write_info.bw_conv_buflen = bufsize * 4;
+	write_info.bw_conv_buf
+			    = lalloc((long_u)write_info.bw_conv_buflen, TRUE);
+	if (write_info.bw_conv_buf == NULL)
+	    end = 0;
+    }
+# endif
+
+# ifdef MACOS_X
+    if (converted && wb_flags == 0 && (wb_flags = get_mac_fio_flags(fenc)) != 0)
+    {
+	write_info.bw_conv_buflen = bufsize * 3;
+	write_info.bw_conv_buf
+			    = lalloc((long_u)write_info.bw_conv_buflen, TRUE);
+	if (write_info.bw_conv_buf == NULL)
+	    end = 0;
+    }
+# endif
+
+# if defined(FEAT_EVAL) || defined(USE_ICONV)
+    if (converted && wb_flags == 0)
+    {
+#  ifdef USE_ICONV
+	/*
+	 * Use iconv() conversion when conversion is needed and it's not done
+	 * internally.
+	 */
+	write_info.bw_iconv_fd = (iconv_t)my_iconv_open(fenc,
+					enc_utf8 ? (char_u *)"utf-8" : p_enc);
+	if (write_info.bw_iconv_fd != (iconv_t)-1)
+	{
+	    /* We're going to use iconv(), allocate a buffer to convert in. */
+	    write_info.bw_conv_buflen = bufsize * ICONV_MULT;
+	    write_info.bw_conv_buf
+			   = lalloc((long_u)write_info.bw_conv_buflen, TRUE);
+	    if (write_info.bw_conv_buf == NULL)
+		end = 0;
+	    write_info.bw_first = TRUE;
+	}
+#   ifdef FEAT_EVAL
+	else
+#   endif
+#  endif
+
+#  ifdef FEAT_EVAL
+	    /*
+	     * When the file needs to be converted with 'charconvert' after
+	     * writing, write to a temp file instead and let the conversion
+	     * overwrite the original file.
+	     */
+	    if (*p_ccv != NUL)
+	    {
+		wfname = vim_tempname('w');
+		if (wfname == NULL)	/* Can't write without a tempfile! */
+		{
+		    errmsg = (char_u *)_("E214: Can't find temp file for writing");
+		    goto restore_backup;
+		}
+	    }
+#  endif
+    }
+# endif
+    if (converted && wb_flags == 0
+#  ifdef USE_ICONV
+	    && write_info.bw_iconv_fd == (iconv_t)-1
+#  endif
+#  ifdef FEAT_EVAL
+	    && wfname == fname
+#  endif
+	    )
+    {
+	if (!forceit)
+	{
+	    errmsg = (char_u *)_("E213: Cannot convert (add ! to write without conversion)");
+	    goto restore_backup;
+	}
+	notconverted = TRUE;
+    }
+#endif
+
+    /*
+     * Open the file "wfname" for writing.
+     * We may try to open the file twice: If we can't write to the
+     * file and forceit is TRUE we delete the existing file and try to create
+     * a new one. If this still fails we may have lost the original file!
+     * (this may happen when the user reached his quotum for number of files).
+     * Appending will fail if the file does not exist and forceit is FALSE.
+     */
+    while ((fd = mch_open((char *)wfname, O_WRONLY | O_EXTRA | (append
+			? (forceit ? (O_APPEND | O_CREAT) : O_APPEND)
+			: (O_CREAT | O_TRUNC))
+			, perm < 0 ? 0666 : (perm & 0777))) < 0)
+    {
+	/*
+	 * A forced write will try to create a new file if the old one is
+	 * still readonly. This may also happen when the directory is
+	 * read-only. In that case the mch_remove() will fail.
+	 */
+	if (errmsg == NULL)
+	{
+#ifdef UNIX
+	    struct stat	st;
+
+	    /* Don't delete the file when it's a hard or symbolic link. */
+	    if ((!newfile && st_old.st_nlink > 1)
+		    || (mch_lstat((char *)fname, &st) == 0
+			&& (st.st_dev != st_old.st_dev
+			    || st.st_ino != st_old.st_ino)))
+		errmsg = (char_u *)_("E166: Can't open linked file for writing");
+	    else
+#endif
+	    {
+		errmsg = (char_u *)_("E212: Can't open file for writing");
+		if (forceit && vim_strchr(p_cpo, CPO_FWRITE) == NULL
+								 && perm >= 0)
+		{
+#ifdef UNIX
+		    /* we write to the file, thus it should be marked
+		       writable after all */
+		    if (!(perm & 0200))
+			made_writable = TRUE;
+		    perm |= 0200;
+		    if (st_old.st_uid != getuid() || st_old.st_gid != getgid())
+			perm &= 0777;
+#endif
+		    if (!append)	    /* don't remove when appending */
+			mch_remove(wfname);
+		    continue;
+		}
+	    }
+	}
+
+restore_backup:
+	{
+	    struct stat st;
+
+	    /*
+	     * If we failed to open the file, we don't need a backup. Throw it
+	     * away.  If we moved or removed the original file try to put the
+	     * backup in its place.
+	     */
+	    if (backup != NULL && wfname == fname)
+	    {
+		if (backup_copy)
+		{
+		    /*
+		     * There is a small chance that we removed the original,
+		     * try to move the copy in its place.
+		     * This may not work if the vim_rename() fails.
+		     * In that case we leave the copy around.
+		     */
+		    /* If file does not exist, put the copy in its place */
+		    if (mch_stat((char *)fname, &st) < 0)
+			vim_rename(backup, fname);
+		    /* if original file does exist throw away the copy */
+		    if (mch_stat((char *)fname, &st) >= 0)
+			mch_remove(backup);
+		}
+		else
+		{
+		    /* try to put the original file back */
+		    vim_rename(backup, fname);
+		}
+	    }
+
+	    /* if original file no longer exists give an extra warning */
+	    if (!newfile && mch_stat((char *)fname, &st) < 0)
+		end = 0;
+	}
+
+#ifdef FEAT_MBYTE
+	if (wfname != fname)
+	    vim_free(wfname);
+#endif
+	goto fail;
+    }
+    errmsg = NULL;
+
+#if defined(MACOS_CLASSIC) || defined(WIN3264)
+    /* TODO: Is it need for MACOS_X? (Dany) */
+    /*
+     * On macintosh copy the original files attributes (i.e. the backup)
+     * This is done in order to preserve the resource fork and the
+     * Finder attribute (label, comments, custom icons, file creator)
+     */
+    if (backup != NULL && overwriting && !append)
+    {
+	if (backup_copy)
+	    (void)mch_copy_file_attribute(wfname, backup);
+	else
+	    (void)mch_copy_file_attribute(backup, wfname);
+    }
+
+    if (!overwriting && !append)
+    {
+	if (buf->b_ffname != NULL)
+	    (void)mch_copy_file_attribute(buf->b_ffname, wfname);
+	/* Should copy resource fork */
+    }
+#endif
+
+    write_info.bw_fd = fd;
+
+#ifdef FEAT_CRYPT
+    if (*buf->b_p_key && !filtering)
+    {
+	crypt_init_keys(buf->b_p_key);
+	/* Write magic number, so that Vim knows that this file is encrypted
+	 * when reading it again.  This also undergoes utf-8 to ucs-2/4
+	 * conversion when needed. */
+	write_info.bw_buf = (char_u *)CRYPT_MAGIC;
+	write_info.bw_len = CRYPT_MAGIC_LEN;
+	write_info.bw_flags = FIO_NOCONVERT;
+	if (buf_write_bytes(&write_info) == FAIL)
+	    end = 0;
+	wb_flags |= FIO_ENCRYPTED;
+    }
+#endif
+
+    write_info.bw_buf = buffer;
+    nchars = 0;
+
+    /* use "++bin", "++nobin" or 'binary' */
+    if (eap != NULL && eap->force_bin != 0)
+	write_bin = (eap->force_bin == FORCE_BIN);
+    else
+	write_bin = buf->b_p_bin;
+
+#ifdef FEAT_MBYTE
+    /*
+     * The BOM is written just after the encryption magic number.
+     * Skip it when appending and the file already existed, the BOM only makes
+     * sense at the start of the file.
+     */
+    if (buf->b_p_bomb && !write_bin && (!append || perm < 0))
+    {
+	write_info.bw_len = make_bom(buffer, fenc);
+	if (write_info.bw_len > 0)
+	{
+	    /* don't convert, do encryption */
+	    write_info.bw_flags = FIO_NOCONVERT | wb_flags;
+	    if (buf_write_bytes(&write_info) == FAIL)
+		end = 0;
+	    else
+		nchars += write_info.bw_len;
+	}
+    }
+#endif
+
+    write_info.bw_len = bufsize;
+#ifdef HAS_BW_FLAGS
+    write_info.bw_flags = wb_flags;
+#endif
+    fileformat = get_fileformat_force(buf, eap);
+    s = buffer;
+    len = 0;
+    for (lnum = start; lnum <= end; ++lnum)
+    {
+	/*
+	 * The next while loop is done once for each character written.
+	 * Keep it fast!
+	 */
+	ptr = ml_get_buf(buf, lnum, FALSE) - 1;
+	while ((c = *++ptr) != NUL)
+	{
+	    if (c == NL)
+		*s = NUL;		/* replace newlines with NULs */
+	    else if (c == CAR && fileformat == EOL_MAC)
+		*s = NL;		/* Mac: replace CRs with NLs */
+	    else
+		*s = c;
+	    ++s;
+	    if (++len != bufsize)
+		continue;
+	    if (buf_write_bytes(&write_info) == FAIL)
+	    {
+		end = 0;		/* write error: break loop */
+		break;
+	    }
+	    nchars += bufsize;
+	    s = buffer;
+	    len = 0;
+	}
+	/* write failed or last line has no EOL: stop here */
+	if (end == 0
+		|| (lnum == end
+		    && write_bin
+		    && (lnum == write_no_eol_lnum
+			|| (lnum == buf->b_ml.ml_line_count && !buf->b_p_eol))))
+	{
+	    ++lnum;			/* written the line, count it */
+	    no_eol = TRUE;
+	    break;
+	}
+	if (fileformat == EOL_UNIX)
+	    *s++ = NL;
+	else
+	{
+	    *s++ = CAR;			/* EOL_MAC or EOL_DOS: write CR */
+	    if (fileformat == EOL_DOS)	/* write CR-NL */
+	    {
+		if (++len == bufsize)
+		{
+		    if (buf_write_bytes(&write_info) == FAIL)
+		    {
+			end = 0;	/* write error: break loop */
+			break;
+		    }
+		    nchars += bufsize;
+		    s = buffer;
+		    len = 0;
+		}
+		*s++ = NL;
+	    }
+	}
+	if (++len == bufsize && end)
+	{
+	    if (buf_write_bytes(&write_info) == FAIL)
+	    {
+		end = 0;		/* write error: break loop */
+		break;
+	    }
+	    nchars += bufsize;
+	    s = buffer;
+	    len = 0;
+
+	    ui_breakcheck();
+	    if (got_int)
+	    {
+		end = 0;		/* Interrupted, break loop */
+		break;
+	    }
+	}
+#ifdef VMS
+	/*
+	 * On VMS there is a problem: newlines get added when writing blocks
+	 * at a time. Fix it by writing a line at a time.
+	 * This is much slower!
+	 * Explanation: VAX/DECC RTL insists that records in some RMS
+	 * structures end with a newline (carriage return) character, and if
+	 * they don't it adds one.
+	 * With other RMS structures it works perfect without this fix.
+	 */
+	if ((buf->b_fab_rat & (FAB$M_FTN | FAB$M_CR)) != 0)
+	{
+	    int b2write;
+
+	    buf->b_fab_mrs = (buf->b_fab_mrs == 0
+		    ? MIN(4096, bufsize)
+		    : MIN(buf->b_fab_mrs, bufsize));
+
+	    b2write = len;
+	    while (b2write > 0)
+	    {
+		write_info.bw_len = MIN(b2write, buf->b_fab_mrs);
+		if (buf_write_bytes(&write_info) == FAIL)
+		{
+		    end = 0;
+		    break;
+		}
+		b2write -= MIN(b2write, buf->b_fab_mrs);
+	    }
+	    write_info.bw_len = bufsize;
+	    nchars += len;
+	    s = buffer;
+	    len = 0;
+	}
+#endif
+    }
+    if (len > 0 && end > 0)
+    {
+	write_info.bw_len = len;
+	if (buf_write_bytes(&write_info) == FAIL)
+	    end = 0;		    /* write error */
+	nchars += len;
+    }
+
+#if defined(UNIX) && defined(HAVE_FSYNC)
+    /* On many journalling file systems there is a bug that causes both the
+     * original and the backup file to be lost when halting the system right
+     * after writing the file.  That's because only the meta-data is
+     * journalled.  Syncing the file slows down the system, but assures it has
+     * been written to disk and we don't lose it.
+     * For a device do try the fsync() but don't complain if it does not work
+     * (could be a pipe).
+     * If the 'fsync' option is FALSE, don't fsync().  Useful for laptops. */
+    if (p_fs && fsync(fd) != 0 && !device)
+    {
+	errmsg = (char_u *)_("E667: Fsync failed");
+	end = 0;
+    }
+#endif
+
+#ifdef UNIX
+    /* When creating a new file, set its owner/group to that of the original
+     * file.  Get the new device and inode number. */
+    if (backup != NULL && !backup_copy)
+    {
+# ifdef HAVE_FCHOWN
+	struct stat	st;
+
+	/* don't change the owner when it's already OK, some systems remove
+	 * permission or ACL stuff */
+	if (mch_stat((char *)wfname, &st) < 0
+		|| st.st_uid != st_old.st_uid
+		|| st.st_gid != st_old.st_gid)
+	{
+	    fchown(fd, st_old.st_uid, st_old.st_gid);
+	    if (perm >= 0)	/* set permission again, may have changed */
+		(void)mch_setperm(wfname, perm);
+	}
+# endif
+	buf_setino(buf);
+    }
+    else if (buf->b_dev < 0)
+	/* Set the inode when creating a new file. */
+	buf_setino(buf);
+#endif
+
+    if (close(fd) != 0)
+    {
+	errmsg = (char_u *)_("E512: Close failed");
+	end = 0;
+    }
+
+#ifdef UNIX
+    if (made_writable)
+	perm &= ~0200;		/* reset 'w' bit for security reasons */
+#endif
+    if (perm >= 0)		/* set perm. of new file same as old file */
+	(void)mch_setperm(wfname, perm);
+#ifdef RISCOS
+    if (!append && !filtering)
+	/* Set the filetype after writing the file. */
+	mch_set_filetype(wfname, buf->b_p_oft);
+#endif
+#ifdef HAVE_ACL
+    /* Probably need to set the ACL before changing the user (can't set the
+     * ACL on a file the user doesn't own). */
+    if (!backup_copy)
+	mch_set_acl(wfname, acl);
+#endif
+
+
+#if defined(FEAT_MBYTE) && defined(FEAT_EVAL)
+    if (wfname != fname)
+    {
+	/*
+	 * The file was written to a temp file, now it needs to be converted
+	 * with 'charconvert' to (overwrite) the output file.
+	 */
+	if (end != 0)
+	{
+	    if (eval_charconvert(enc_utf8 ? (char_u *)"utf-8" : p_enc, fenc,
+						       wfname, fname) == FAIL)
+	    {
+		write_info.bw_conv_error = TRUE;
+		end = 0;
+	    }
+	}
+	mch_remove(wfname);
+	vim_free(wfname);
+    }
+#endif
+
+    if (end == 0)
+    {
+	if (errmsg == NULL)
+	{
+#ifdef FEAT_MBYTE
+	    if (write_info.bw_conv_error)
+		errmsg = (char_u *)_("E513: write error, conversion failed (make 'fenc' empty to override)");
+	    else
+#endif
+		if (got_int)
+		    errmsg = (char_u *)_(e_interr);
+		else
+		    errmsg = (char_u *)_("E514: write error (file system full?)");
+	}
+
+	/*
+	 * If we have a backup file, try to put it in place of the new file,
+	 * because the new file is probably corrupt.  This avoids loosing the
+	 * original file when trying to make a backup when writing the file a
+	 * second time.
+	 * When "backup_copy" is set we need to copy the backup over the new
+	 * file.  Otherwise rename the backup file.
+	 * If this is OK, don't give the extra warning message.
+	 */
+	if (backup != NULL)
+	{
+	    if (backup_copy)
+	    {
+		/* This may take a while, if we were interrupted let the user
+		 * know we got the message. */
+		if (got_int)
+		{
+		    MSG(_(e_interr));
+		    out_flush();
+		}
+		if ((fd = mch_open((char *)backup, O_RDONLY | O_EXTRA, 0)) >= 0)
+		{
+		    if ((write_info.bw_fd = mch_open((char *)fname,
+				    O_WRONLY | O_CREAT | O_TRUNC | O_EXTRA,
+							   perm & 0777)) >= 0)
+		    {
+			/* copy the file. */
+			write_info.bw_buf = smallbuf;
+#ifdef HAS_BW_FLAGS
+			write_info.bw_flags = FIO_NOCONVERT;
+#endif
+			while ((write_info.bw_len = vim_read(fd, smallbuf,
+						      SMBUFSIZE)) > 0)
+			    if (buf_write_bytes(&write_info) == FAIL)
+				break;
+
+			if (close(write_info.bw_fd) >= 0
+						   && write_info.bw_len == 0)
+			    end = 1;		/* success */
+		    }
+		    close(fd);	/* ignore errors for closing read file */
+		}
+	    }
+	    else
+	    {
+		if (vim_rename(backup, fname) == 0)
+		    end = 1;
+	    }
+	}
+	goto fail;
+    }
+
+    lnum -= start;	    /* compute number of written lines */
+    --no_wait_return;	    /* may wait for return now */
+
+#if !(defined(UNIX) || defined(VMS))
+    fname = sfname;	    /* use shortname now, for the messages */
+#endif
+    if (!filtering)
+    {
+	msg_add_fname(buf, fname);	/* put fname in IObuff with quotes */
+	c = FALSE;
+#ifdef FEAT_MBYTE
+	if (write_info.bw_conv_error)
+	{
+	    STRCAT(IObuff, _(" CONVERSION ERROR"));
+	    c = TRUE;
+	}
+	else if (notconverted)
+	{
+	    STRCAT(IObuff, _("[NOT converted]"));
+	    c = TRUE;
+	}
+	else if (converted)
+	{
+	    STRCAT(IObuff, _("[converted]"));
+	    c = TRUE;
+	}
+#endif
+	if (device)
+	{
+	    STRCAT(IObuff, _("[Device]"));
+	    c = TRUE;
+	}
+	else if (newfile)
+	{
+	    STRCAT(IObuff, shortmess(SHM_NEW) ? _("[New]") : _("[New File]"));
+	    c = TRUE;
+	}
+	if (no_eol)
+	{
+	    msg_add_eol();
+	    c = TRUE;
+	}
+	/* may add [unix/dos/mac] */
+	if (msg_add_fileformat(fileformat))
+	    c = TRUE;
+#ifdef FEAT_CRYPT
+	if (wb_flags & FIO_ENCRYPTED)
+	{
+	    STRCAT(IObuff, _("[crypted]"));
+	    c = TRUE;
+	}
+#endif
+	msg_add_lines(c, (long)lnum, nchars);	/* add line/char count */
+	if (!shortmess(SHM_WRITE))
+	{
+	    if (append)
+		STRCAT(IObuff, shortmess(SHM_WRI) ? _(" [a]") : _(" appended"));
+	    else
+		STRCAT(IObuff, shortmess(SHM_WRI) ? _(" [w]") : _(" written"));
+	}
+
+	set_keep_msg(msg_trunc_attr(IObuff, FALSE, 0), 0);
+    }
+
+    /* When written everything correctly: reset 'modified'.  Unless not
+     * writing to the original file and '+' is not in 'cpoptions'. */
+    if (reset_changed && whole && !append
+#ifdef FEAT_MBYTE
+	    && !write_info.bw_conv_error
+#endif
+	    && (overwriting || vim_strchr(p_cpo, CPO_PLUS) != NULL)
+	    )
+    {
+	unchanged(buf, TRUE);
+	u_unchanged(buf);
+    }
+
+    /*
+     * If written to the current file, update the timestamp of the swap file
+     * and reset the BF_WRITE_MASK flags. Also sets buf->b_mtime.
+     */
+    if (overwriting)
+    {
+	ml_timestamp(buf);
+	if (append)
+	    buf->b_flags &= ~BF_NEW;
+	else
+	    buf->b_flags &= ~BF_WRITE_MASK;
+    }
+
+    /*
+     * If we kept a backup until now, and we are in patch mode, then we make
+     * the backup file our 'original' file.
+     */
+    if (*p_pm && dobackup)
+    {
+	char *org = (char *)buf_modname(
+#ifdef SHORT_FNAME
+					TRUE,
+#else
+					(buf->b_p_sn || buf->b_shortname),
+#endif
+							  fname, p_pm, FALSE);
+
+	if (backup != NULL)
+	{
+	    struct stat st;
+
+	    /*
+	     * If the original file does not exist yet
+	     * the current backup file becomes the original file
+	     */
+	    if (org == NULL)
+		EMSG(_("E205: Patchmode: can't save original file"));
+	    else if (mch_stat(org, &st) < 0)
+	    {
+		vim_rename(backup, (char_u *)org);
+		vim_free(backup);	    /* don't delete the file */
+		backup = NULL;
+#ifdef UNIX
+		set_file_time((char_u *)org, st_old.st_atime, st_old.st_mtime);
+#endif
+	    }
+	}
+	/*
+	 * If there is no backup file, remember that a (new) file was
+	 * created.
+	 */
+	else
+	{
+	    int empty_fd;
+
+	    if (org == NULL
+		    || (empty_fd = mch_open(org,
+				      O_CREAT | O_EXTRA | O_EXCL | O_NOFOLLOW,
+					perm < 0 ? 0666 : (perm & 0777))) < 0)
+	      EMSG(_("E206: patchmode: can't touch empty original file"));
+	    else
+	      close(empty_fd);
+	}
+	if (org != NULL)
+	{
+	    mch_setperm((char_u *)org, mch_getperm(fname) & 0777);
+	    vim_free(org);
+	}
+    }
+
+    /*
+     * Remove the backup unless 'backup' option is set
+     */
+    if (!p_bk && backup != NULL && mch_remove(backup) != 0)
+	EMSG(_("E207: Can't delete backup file"));
+
+#ifdef FEAT_SUN_WORKSHOP
+    if (usingSunWorkShop)
+	workshop_file_saved((char *) ffname);
+#endif
+
+    goto nofail;
+
+    /*
+     * Finish up.  We get here either after failure or success.
+     */
+fail:
+    --no_wait_return;		/* may wait for return now */
+nofail:
+
+    /* Done saving, we accept changed buffer warnings again */
+    buf->b_saving = FALSE;
+
+    vim_free(backup);
+    if (buffer != smallbuf)
+	vim_free(buffer);
+#ifdef FEAT_MBYTE
+    vim_free(fenc_tofree);
+    vim_free(write_info.bw_conv_buf);
+# ifdef USE_ICONV
+    if (write_info.bw_iconv_fd != (iconv_t)-1)
+    {
+	iconv_close(write_info.bw_iconv_fd);
+	write_info.bw_iconv_fd = (iconv_t)-1;
+    }
+# endif
+#endif
+#ifdef HAVE_ACL
+    mch_free_acl(acl);
+#endif
+
+    if (errmsg != NULL)
+    {
+	int numlen = errnum != NULL ? (int)STRLEN(errnum) : 0;
+
+	attr = hl_attr(HLF_E);	/* set highlight for error messages */
+	msg_add_fname(buf,
+#ifndef UNIX
+		sfname
+#else
+		fname
+#endif
+		     );		/* put file name in IObuff with quotes */
+	if (STRLEN(IObuff) + STRLEN(errmsg) + numlen >= IOSIZE)
+	    IObuff[IOSIZE - STRLEN(errmsg) - numlen - 1] = NUL;
+	/* If the error message has the form "is ...", put the error number in
+	 * front of the file name. */
+	if (errnum != NULL)
+	{
+	    mch_memmove(IObuff + numlen, IObuff, STRLEN(IObuff) + 1);
+	    mch_memmove(IObuff, errnum, (size_t)numlen);
+	}
+	STRCAT(IObuff, errmsg);
+	emsg(IObuff);
+
+	retval = FAIL;
+	if (end == 0)
+	{
+	    MSG_PUTS_ATTR(_("\nWARNING: Original file may be lost or damaged\n"),
+		    attr | MSG_HIST);
+	    MSG_PUTS_ATTR(_("don't quit the editor until the file is successfully written!"),
+		    attr | MSG_HIST);
+
+	    /* Update the timestamp to avoid an "overwrite changed file"
+	     * prompt when writing again. */
+	    if (mch_stat((char *)fname, &st_old) >= 0)
+	    {
+		buf_store_time(buf, &st_old, fname);
+		buf->b_mtime_read = buf->b_mtime;
+	    }
+	}
+    }
+    msg_scroll = msg_save;
+
+#ifdef FEAT_AUTOCMD
+#ifdef FEAT_EVAL
+    if (!should_abort(retval))
+#else
+    if (!got_int)
+#endif
+    {
+	aco_save_T	aco;
+
+	write_no_eol_lnum = 0;	/* in case it was set by the previous read */
+
+	/*
+	 * Apply POST autocommands.
+	 * Careful: The autocommands may call buf_write() recursively!
+	 */
+	aucmd_prepbuf(&aco, buf);
+
+	if (append)
+	    apply_autocmds_exarg(EVENT_FILEAPPENDPOST, fname, fname,
+							  FALSE, curbuf, eap);
+	else if (filtering)
+	    apply_autocmds_exarg(EVENT_FILTERWRITEPOST, NULL, fname,
+							  FALSE, curbuf, eap);
+	else if (reset_changed && whole)
+	    apply_autocmds_exarg(EVENT_BUFWRITEPOST, fname, fname,
+							  FALSE, curbuf, eap);
+	else
+	    apply_autocmds_exarg(EVENT_FILEWRITEPOST, fname, fname,
+							  FALSE, curbuf, eap);
+
+	/* restore curwin/curbuf and a few other things */
+	aucmd_restbuf(&aco);
+
+#ifdef FEAT_EVAL
+	if (aborting())	    /* autocmds may abort script processing */
+	    retval = FALSE;
+#endif
+    }
+#endif
+
+    got_int |= prev_got_int;
+
+#ifdef MACOS_CLASSIC /* TODO: Is it need for MACOS_X? (Dany) */
+    /* Update machine specific information. */
+    mch_post_buffer_write(buf);
+#endif
+    return retval;
+}
+
+/*
+ * Set the name of the current buffer.  Use when the buffer doesn't have a
+ * name and a ":r" or ":w" command with a file name is used.
+ */
+    static int
+set_rw_fname(fname, sfname)
+    char_u	*fname;
+    char_u	*sfname;
+{
+#ifdef FEAT_AUTOCMD
+    /* It's like the unnamed buffer is deleted.... */
+    if (curbuf->b_p_bl)
+	apply_autocmds(EVENT_BUFDELETE, NULL, NULL, FALSE, curbuf);
+    apply_autocmds(EVENT_BUFWIPEOUT, NULL, NULL, FALSE, curbuf);
+# ifdef FEAT_EVAL
+    if (aborting())	    /* autocmds may abort script processing */
+	return FAIL;
+# endif
+#endif
+
+    if (setfname(curbuf, fname, sfname, FALSE) == OK)
+	curbuf->b_flags |= BF_NOTEDITED;
+
+#ifdef FEAT_AUTOCMD
+    /* ....and a new named one is created */
+    apply_autocmds(EVENT_BUFNEW, NULL, NULL, FALSE, curbuf);
+    if (curbuf->b_p_bl)
+	apply_autocmds(EVENT_BUFADD, NULL, NULL, FALSE, curbuf);
+# ifdef FEAT_EVAL
+    if (aborting())	    /* autocmds may abort script processing */
+	return FAIL;
+# endif
+
+    /* Do filetype detection now if 'filetype' is empty. */
+    if (*curbuf->b_p_ft == NUL)
+    {
+	if (au_has_group((char_u *)"filetypedetect"))
+	    (void)do_doautocmd((char_u *)"filetypedetect BufRead", FALSE);
+	do_modelines(0);
+    }
+#endif
+
+    return OK;
+}
+
+/*
+ * Put file name into IObuff with quotes.
+ */
+    void
+msg_add_fname(buf, fname)
+    buf_T	*buf;
+    char_u	*fname;
+{
+    if (fname == NULL)
+	fname = (char_u *)"-stdin-";
+    home_replace(buf, fname, IObuff + 1, IOSIZE - 4, TRUE);
+    IObuff[0] = '"';
+    STRCAT(IObuff, "\" ");
+}
+
+/*
+ * Append message for text mode to IObuff.
+ * Return TRUE if something appended.
+ */
+    static int
+msg_add_fileformat(eol_type)
+    int	    eol_type;
+{
+#ifndef USE_CRNL
+    if (eol_type == EOL_DOS)
+    {
+	STRCAT(IObuff, shortmess(SHM_TEXT) ? _("[dos]") : _("[dos format]"));
+	return TRUE;
+    }
+#endif
+#ifndef USE_CR
+    if (eol_type == EOL_MAC)
+    {
+	STRCAT(IObuff, shortmess(SHM_TEXT) ? _("[mac]") : _("[mac format]"));
+	return TRUE;
+    }
+#endif
+#if defined(USE_CRNL) || defined(USE_CR)
+    if (eol_type == EOL_UNIX)
+    {
+	STRCAT(IObuff, shortmess(SHM_TEXT) ? _("[unix]") : _("[unix format]"));
+	return TRUE;
+    }
+#endif
+    return FALSE;
+}
+
+/*
+ * Append line and character count to IObuff.
+ */
+    void
+msg_add_lines(insert_space, lnum, nchars)
+    int	    insert_space;
+    long    lnum;
+    long    nchars;
+{
+    char_u  *p;
+
+    p = IObuff + STRLEN(IObuff);
+
+    if (insert_space)
+	*p++ = ' ';
+    if (shortmess(SHM_LINES))
+	sprintf((char *)p, "%ldL, %ldC", lnum, nchars);
+    else
+    {
+	if (lnum == 1)
+	    STRCPY(p, _("1 line, "));
+	else
+	    sprintf((char *)p, _("%ld lines, "), lnum);
+	p += STRLEN(p);
+	if (nchars == 1)
+	    STRCPY(p, _("1 character"));
+	else
+	    sprintf((char *)p, _("%ld characters"), nchars);
+    }
+}
+
+/*
+ * Append message for missing line separator to IObuff.
+ */
+    static void
+msg_add_eol()
+{
+    STRCAT(IObuff, shortmess(SHM_LAST) ? _("[noeol]") : _("[Incomplete last line]"));
+}
+
+/*
+ * Check modification time of file, before writing to it.
+ * The size isn't checked, because using a tool like "gzip" takes care of
+ * using the same timestamp but can't set the size.
+ */
+    static int
+check_mtime(buf, st)
+    buf_T		*buf;
+    struct stat		*st;
+{
+    if (buf->b_mtime_read != 0
+	    && time_differs((long)st->st_mtime, buf->b_mtime_read))
+    {
+	msg_scroll = TRUE;	    /* don't overwrite messages here */
+	msg_silent = 0;		    /* must give this prompt */
+	/* don't use emsg() here, don't want to flush the buffers */
+	MSG_ATTR(_("WARNING: The file has been changed since reading it!!!"),
+						       hl_attr(HLF_E));
+	if (ask_yesno((char_u *)_("Do you really want to write to it"),
+								 TRUE) == 'n')
+	    return FAIL;
+	msg_scroll = FALSE;	    /* always overwrite the file message now */
+    }
+    return OK;
+}
+
+    static int
+time_differs(t1, t2)
+    long	t1, t2;
+{
+#if defined(__linux__) || defined(MSDOS) || defined(MSWIN)
+    /* On a FAT filesystem, esp. under Linux, there are only 5 bits to store
+     * the seconds.  Since the roundoff is done when flushing the inode, the
+     * time may change unexpectedly by one second!!! */
+    return (t1 - t2 > 1 || t2 - t1 > 1);
+#else
+    return (t1 != t2);
+#endif
+}
+
+/*
+ * Call write() to write a number of bytes to the file.
+ * Also handles encryption and 'encoding' conversion.
+ *
+ * Return FAIL for failure, OK otherwise.
+ */
+    static int
+buf_write_bytes(ip)
+    struct bw_info *ip;
+{
+    int		wlen;
+    char_u	*buf = ip->bw_buf;	/* data to write */
+    int		len = ip->bw_len;	/* length of data */
+#ifdef HAS_BW_FLAGS
+    int		flags = ip->bw_flags;	/* extra flags */
+#endif
+
+#ifdef FEAT_MBYTE
+    /*
+     * Skip conversion when writing the crypt magic number or the BOM.
+     */
+    if (!(flags & FIO_NOCONVERT))
+    {
+	char_u		*p;
+	unsigned	c;
+	int		n;
+
+	if (flags & FIO_UTF8)
+	{
+	    /*
+	     * Convert latin1 in the buffer to UTF-8 in the file.
+	     */
+	    p = ip->bw_conv_buf;	/* translate to buffer */
+	    for (wlen = 0; wlen < len; ++wlen)
+		p += utf_char2bytes(buf[wlen], p);
+	    buf = ip->bw_conv_buf;
+	    len = (int)(p - ip->bw_conv_buf);
+	}
+	else if (flags & (FIO_UCS4 | FIO_UTF16 | FIO_UCS2 | FIO_LATIN1))
+	{
+	    /*
+	     * Convert UTF-8 bytes in the buffer to UCS-2, UCS-4, UTF-16 or
+	     * Latin1 chars in the file.
+	     */
+	    if (flags & FIO_LATIN1)
+		p = buf;	/* translate in-place (can only get shorter) */
+	    else
+		p = ip->bw_conv_buf;	/* translate to buffer */
+	    for (wlen = 0; wlen < len; wlen += n)
+	    {
+		if (wlen == 0 && ip->bw_restlen != 0)
+		{
+		    int		l;
+
+		    /* Use remainder of previous call.  Append the start of
+		     * buf[] to get a full sequence.  Might still be too
+		     * short! */
+		    l = CONV_RESTLEN - ip->bw_restlen;
+		    if (l > len)
+			l = len;
+		    mch_memmove(ip->bw_rest + ip->bw_restlen, buf, (size_t)l);
+		    n = utf_ptr2len_len(ip->bw_rest, ip->bw_restlen + l);
+		    if (n > ip->bw_restlen + len)
+		    {
+			/* We have an incomplete byte sequence at the end to
+			 * be written.  We can't convert it without the
+			 * remaining bytes.  Keep them for the next call. */
+			if (ip->bw_restlen + len > CONV_RESTLEN)
+			    return FAIL;
+			ip->bw_restlen += len;
+			break;
+		    }
+		    if (n > 1)
+			c = utf_ptr2char(ip->bw_rest);
+		    else
+			c = ip->bw_rest[0];
+		    if (n >= ip->bw_restlen)
+		    {
+			n -= ip->bw_restlen;
+			ip->bw_restlen = 0;
+		    }
+		    else
+		    {
+			ip->bw_restlen -= n;
+			mch_memmove(ip->bw_rest, ip->bw_rest + n,
+						      (size_t)ip->bw_restlen);
+			n = 0;
+		    }
+		}
+		else
+		{
+		    n = utf_ptr2len_len(buf + wlen, len - wlen);
+		    if (n > len - wlen)
+		    {
+			/* We have an incomplete byte sequence at the end to
+			 * be written.  We can't convert it without the
+			 * remaining bytes.  Keep them for the next call. */
+			if (len - wlen > CONV_RESTLEN)
+			    return FAIL;
+			ip->bw_restlen = len - wlen;
+			mch_memmove(ip->bw_rest, buf + wlen,
+						      (size_t)ip->bw_restlen);
+			break;
+		    }
+		    if (n > 1)
+			c = utf_ptr2char(buf + wlen);
+		    else
+			c = buf[wlen];
+		}
+
+		ip->bw_conv_error |= ucs2bytes(c, &p, flags);
+	    }
+	    if (flags & FIO_LATIN1)
+		len = (int)(p - buf);
+	    else
+	    {
+		buf = ip->bw_conv_buf;
+		len = (int)(p - ip->bw_conv_buf);
+	    }
+	}
+
+# ifdef WIN3264
+	else if (flags & FIO_CODEPAGE)
+	{
+	    /*
+	     * Convert UTF-8 or codepage to UCS-2 and then to MS-Windows
+	     * codepage.
+	     */
+	    char_u	*from;
+	    size_t	fromlen;
+	    char_u	*to;
+	    int		u8c;
+	    BOOL	bad = FALSE;
+	    int		needed;
+
+	    if (ip->bw_restlen > 0)
+	    {
+		/* Need to concatenate the remainder of the previous call and
+		 * the bytes of the current call.  Use the end of the
+		 * conversion buffer for this. */
+		fromlen = len + ip->bw_restlen;
+		from = ip->bw_conv_buf + ip->bw_conv_buflen - fromlen;
+		mch_memmove(from, ip->bw_rest, (size_t)ip->bw_restlen);
+		mch_memmove(from + ip->bw_restlen, buf, (size_t)len);
+	    }
+	    else
+	    {
+		from = buf;
+		fromlen = len;
+	    }
+
+	    to = ip->bw_conv_buf;
+	    if (enc_utf8)
+	    {
+		/* Convert from UTF-8 to UCS-2, to the start of the buffer.
+		 * The buffer has been allocated to be big enough. */
+		while (fromlen > 0)
+		{
+		    n = (int)utf_ptr2len_len(from, (int)fromlen);
+		    if (n > (int)fromlen)	/* incomplete byte sequence */
+			break;
+		    u8c = utf_ptr2char(from);
+		    *to++ = (u8c & 0xff);
+		    *to++ = (u8c >> 8);
+		    fromlen -= n;
+		    from += n;
+		}
+
+		/* Copy remainder to ip->bw_rest[] to be used for the next
+		 * call. */
+		if (fromlen > CONV_RESTLEN)
+		{
+		    /* weird overlong sequence */
+		    ip->bw_conv_error = TRUE;
+		    return FAIL;
+		}
+		mch_memmove(ip->bw_rest, from, fromlen);
+		ip->bw_restlen = (int)fromlen;
+	    }
+	    else
+	    {
+		/* Convert from enc_codepage to UCS-2, to the start of the
+		 * buffer.  The buffer has been allocated to be big enough. */
+		ip->bw_restlen = 0;
+		needed = MultiByteToWideChar(enc_codepage,
+			     MB_ERR_INVALID_CHARS, (LPCSTR)from, (int)fromlen,
+								     NULL, 0);
+		if (needed == 0)
+		{
+		    /* When conversion fails there may be a trailing byte. */
+		    needed = MultiByteToWideChar(enc_codepage,
+			 MB_ERR_INVALID_CHARS, (LPCSTR)from, (int)fromlen - 1,
+								     NULL, 0);
+		    if (needed == 0)
+		    {
+			/* Conversion doesn't work. */
+			ip->bw_conv_error = TRUE;
+			return FAIL;
+		    }
+		    /* Save the trailing byte for the next call. */
+		    ip->bw_rest[0] = from[fromlen - 1];
+		    ip->bw_restlen = 1;
+		}
+		needed = MultiByteToWideChar(enc_codepage, MB_ERR_INVALID_CHARS,
+				(LPCSTR)from, (int)(fromlen - ip->bw_restlen),
+							  (LPWSTR)to, needed);
+		if (needed == 0)
+		{
+		    /* Safety check: Conversion doesn't work. */
+		    ip->bw_conv_error = TRUE;
+		    return FAIL;
+		}
+		to += needed * 2;
+	    }
+
+	    fromlen = to - ip->bw_conv_buf;
+	    buf = to;
+#  ifdef CP_UTF8	/* VC 4.1 doesn't define CP_UTF8 */
+	    if (FIO_GET_CP(flags) == CP_UTF8)
+	    {
+		/* Convert from UCS-2 to UTF-8, using the remainder of the
+		 * conversion buffer.  Fails when out of space. */
+		for (from = ip->bw_conv_buf; fromlen > 1; fromlen -= 2)
+		{
+		    u8c = *from++;
+		    u8c += (*from++ << 8);
+		    to += utf_char2bytes(u8c, to);
+		    if (to + 6 >= ip->bw_conv_buf + ip->bw_conv_buflen)
+		    {
+			ip->bw_conv_error = TRUE;
+			return FAIL;
+		    }
+		}
+		len = (int)(to - buf);
+	    }
+	    else
+#endif
+	    {
+		/* Convert from UCS-2 to the codepage, using the remainder of
+		 * the conversion buffer.  If the conversion uses the default
+		 * character "0", the data doesn't fit in this encoding, so
+		 * fail. */
+		len = WideCharToMultiByte(FIO_GET_CP(flags), 0,
+			(LPCWSTR)ip->bw_conv_buf, (int)fromlen / sizeof(WCHAR),
+			(LPSTR)to, (int)(ip->bw_conv_buflen - fromlen), 0,
+									&bad);
+		if (bad)
+		{
+		    ip->bw_conv_error = TRUE;
+		    return FAIL;
+		}
+	    }
+	}
+# endif
+
+# ifdef MACOS_CONVERT
+	else if (flags & FIO_MACROMAN)
+	{
+	    /*
+	     * Convert UTF-8 or latin1 to Apple MacRoman.
+	     */
+	    char_u	*from;
+	    size_t	fromlen;
+
+	    if (ip->bw_restlen > 0)
+	    {
+		/* Need to concatenate the remainder of the previous call and
+		 * the bytes of the current call.  Use the end of the
+		 * conversion buffer for this. */
+		fromlen = len + ip->bw_restlen;
+		from = ip->bw_conv_buf + ip->bw_conv_buflen - fromlen;
+		mch_memmove(from, ip->bw_rest, (size_t)ip->bw_restlen);
+		mch_memmove(from + ip->bw_restlen, buf, (size_t)len);
+	    }
+	    else
+	    {
+		from = buf;
+		fromlen = len;
+	    }
+
+	    if (enc2macroman(from, fromlen,
+			ip->bw_conv_buf, &len, ip->bw_conv_buflen,
+			ip->bw_rest, &ip->bw_restlen) == FAIL)
+	    {
+		ip->bw_conv_error = TRUE;
+		return FAIL;
+	    }
+	    buf = ip->bw_conv_buf;
+	}
+# endif
+
+# ifdef USE_ICONV
+	if (ip->bw_iconv_fd != (iconv_t)-1)
+	{
+	    const char	*from;
+	    size_t	fromlen;
+	    char	*to;
+	    size_t	tolen;
+
+	    /* Convert with iconv(). */
+	    if (ip->bw_restlen > 0)
+	    {
+		/* Need to concatenate the remainder of the previous call and
+		 * the bytes of the current call.  Use the end of the
+		 * conversion buffer for this. */
+		fromlen = len + ip->bw_restlen;
+		from = (char *)ip->bw_conv_buf + ip->bw_conv_buflen - fromlen;
+		mch_memmove((void *)from, ip->bw_rest, (size_t)ip->bw_restlen);
+		mch_memmove((void *)(from + ip->bw_restlen), buf, (size_t)len);
+		tolen = ip->bw_conv_buflen - fromlen;
+	    }
+	    else
+	    {
+		from = (const char *)buf;
+		fromlen = len;
+		tolen = ip->bw_conv_buflen;
+	    }
+	    to = (char *)ip->bw_conv_buf;
+
+	    if (ip->bw_first)
+	    {
+		size_t	save_len = tolen;
+
+		/* output the initial shift state sequence */
+		(void)iconv(ip->bw_iconv_fd, NULL, NULL, &to, &tolen);
+
+		/* There is a bug in iconv() on Linux (which appears to be
+		 * wide-spread) which sets "to" to NULL and messes up "tolen".
+		 */
+		if (to == NULL)
+		{
+		    to = (char *)ip->bw_conv_buf;
+		    tolen = save_len;
+		}
+		ip->bw_first = FALSE;
+	    }
+
+	    /*
+	     * If iconv() has an error or there is not enough room, fail.
+	     */
+	    if ((iconv(ip->bw_iconv_fd, (void *)&from, &fromlen, &to, &tolen)
+			== (size_t)-1 && ICONV_ERRNO != ICONV_EINVAL)
+						    || fromlen > CONV_RESTLEN)
+	    {
+		ip->bw_conv_error = TRUE;
+		return FAIL;
+	    }
+
+	    /* copy remainder to ip->bw_rest[] to be used for the next call. */
+	    if (fromlen > 0)
+		mch_memmove(ip->bw_rest, (void *)from, fromlen);
+	    ip->bw_restlen = (int)fromlen;
+
+	    buf = ip->bw_conv_buf;
+	    len = (int)((char_u *)to - ip->bw_conv_buf);
+	}
+# endif
+    }
+#endif /* FEAT_MBYTE */
+
+#ifdef FEAT_CRYPT
+    if (flags & FIO_ENCRYPTED)		/* encrypt the data */
+    {
+	int ztemp, t, i;
+
+	for (i = 0; i < len; i++)
+	{
+	    ztemp  = buf[i];
+	    buf[i] = ZENCODE(ztemp, t);
+	}
+    }
+#endif
+
+    /* Repeat the write(), it may be interrupted by a signal. */
+    while (len > 0)
+    {
+	wlen = vim_write(ip->bw_fd, buf, len);
+	if (wlen <= 0)		    /* error! */
+	    return FAIL;
+	len -= wlen;
+	buf += wlen;
+    }
+    return OK;
+}
+
+#ifdef FEAT_MBYTE
+/*
+ * Convert a Unicode character to bytes.
+ */
+    static int
+ucs2bytes(c, pp, flags)
+    unsigned	c;		/* in: character */
+    char_u	**pp;		/* in/out: pointer to result */
+    int		flags;		/* FIO_ flags */
+{
+    char_u	*p = *pp;
+    int		error = FALSE;
+    int		cc;
+
+
+    if (flags & FIO_UCS4)
+    {
+	if (flags & FIO_ENDIAN_L)
+	{
+	    *p++ = c;
+	    *p++ = (c >> 8);
+	    *p++ = (c >> 16);
+	    *p++ = (c >> 24);
+	}
+	else
+	{
+	    *p++ = (c >> 24);
+	    *p++ = (c >> 16);
+	    *p++ = (c >> 8);
+	    *p++ = c;
+	}
+    }
+    else if (flags & (FIO_UCS2 | FIO_UTF16))
+    {
+	if (c >= 0x10000)
+	{
+	    if (flags & FIO_UTF16)
+	    {
+		/* Make two words, ten bits of the character in each.  First
+		 * word is 0xd800 - 0xdbff, second one 0xdc00 - 0xdfff */
+		c -= 0x10000;
+		if (c >= 0x100000)
+		    error = TRUE;
+		cc = ((c >> 10) & 0x3ff) + 0xd800;
+		if (flags & FIO_ENDIAN_L)
+		{
+		    *p++ = cc;
+		    *p++ = ((unsigned)cc >> 8);
+		}
+		else
+		{
+		    *p++ = ((unsigned)cc >> 8);
+		    *p++ = cc;
+		}
+		c = (c & 0x3ff) + 0xdc00;
+	    }
+	    else
+		error = TRUE;
+	}
+	if (flags & FIO_ENDIAN_L)
+	{
+	    *p++ = c;
+	    *p++ = (c >> 8);
+	}
+	else
+	{
+	    *p++ = (c >> 8);
+	    *p++ = c;
+	}
+    }
+    else    /* Latin1 */
+    {
+	if (c >= 0x100)
+	{
+	    error = TRUE;
+	    *p++ = 0xBF;
+	}
+	else
+	    *p++ = c;
+    }
+
+    *pp = p;
+    return error;
+}
+
+/*
+ * Return TRUE if "a" and "b" are the same 'encoding'.
+ * Ignores difference between "ansi" and "latin1", "ucs-4" and "ucs-4be", etc.
+ */
+    static int
+same_encoding(a, b)
+    char_u	*a;
+    char_u	*b;
+{
+    int		f;
+
+    if (STRCMP(a, b) == 0)
+	return TRUE;
+    f = get_fio_flags(a);
+    return (f != 0 && get_fio_flags(b) == f);
+}
+
+/*
+ * Check "ptr" for a unicode encoding and return the FIO_ flags needed for the
+ * internal conversion.
+ * if "ptr" is an empty string, use 'encoding'.
+ */
+    static int
+get_fio_flags(ptr)
+    char_u	*ptr;
+{
+    int		prop;
+
+    if (*ptr == NUL)
+	ptr = p_enc;
+
+    prop = enc_canon_props(ptr);
+    if (prop & ENC_UNICODE)
+    {
+	if (prop & ENC_2BYTE)
+	{
+	    if (prop & ENC_ENDIAN_L)
+		return FIO_UCS2 | FIO_ENDIAN_L;
+	    return FIO_UCS2;
+	}
+	if (prop & ENC_4BYTE)
+	{
+	    if (prop & ENC_ENDIAN_L)
+		return FIO_UCS4 | FIO_ENDIAN_L;
+	    return FIO_UCS4;
+	}
+	if (prop & ENC_2WORD)
+	{
+	    if (prop & ENC_ENDIAN_L)
+		return FIO_UTF16 | FIO_ENDIAN_L;
+	    return FIO_UTF16;
+	}
+	return FIO_UTF8;
+    }
+    if (prop & ENC_LATIN1)
+	return FIO_LATIN1;
+    /* must be ENC_DBCS, requires iconv() */
+    return 0;
+}
+
+#ifdef WIN3264
+/*
+ * Check "ptr" for a MS-Windows codepage name and return the FIO_ flags needed
+ * for the conversion MS-Windows can do for us.  Also accept "utf-8".
+ * Used for conversion between 'encoding' and 'fileencoding'.
+ */
+    static int
+get_win_fio_flags(ptr)
+    char_u	*ptr;
+{
+    int		cp;
+
+    /* Cannot do this when 'encoding' is not utf-8 and not a codepage. */
+    if (!enc_utf8 && enc_codepage <= 0)
+	return 0;
+
+    cp = encname2codepage(ptr);
+    if (cp == 0)
+    {
+#  ifdef CP_UTF8	/* VC 4.1 doesn't define CP_UTF8 */
+	if (STRCMP(ptr, "utf-8") == 0)
+	    cp = CP_UTF8;
+	else
+#  endif
+	    return 0;
+    }
+    return FIO_PUT_CP(cp) | FIO_CODEPAGE;
+}
+#endif
+
+#ifdef MACOS_X
+/*
+ * Check "ptr" for a Carbon supported encoding and return the FIO_ flags
+ * needed for the internal conversion to/from utf-8 or latin1.
+ */
+    static int
+get_mac_fio_flags(ptr)
+    char_u	*ptr;
+{
+    if ((enc_utf8 || STRCMP(p_enc, "latin1") == 0)
+				     && (enc_canon_props(ptr) & ENC_MACROMAN))
+	return FIO_MACROMAN;
+    return 0;
+}
+#endif
+
+/*
+ * Check for a Unicode BOM (Byte Order Mark) at the start of p[size].
+ * "size" must be at least 2.
+ * Return the name of the encoding and set "*lenp" to the length.
+ * Returns NULL when no BOM found.
+ */
+    static char_u *
+check_for_bom(p, size, lenp, flags)
+    char_u	*p;
+    long	size;
+    int		*lenp;
+    int		flags;
+{
+    char	*name = NULL;
+    int		len = 2;
+
+    if (p[0] == 0xef && p[1] == 0xbb && size >= 3 && p[2] == 0xbf
+	    && (flags == FIO_ALL || flags == 0))
+    {
+	name = "utf-8";		/* EF BB BF */
+	len = 3;
+    }
+    else if (p[0] == 0xff && p[1] == 0xfe)
+    {
+	if (size >= 4 && p[2] == 0 && p[3] == 0
+	    && (flags == FIO_ALL || flags == (FIO_UCS4 | FIO_ENDIAN_L)))
+	{
+	    name = "ucs-4le";	/* FF FE 00 00 */
+	    len = 4;
+	}
+	else if (flags == FIO_ALL || flags == (FIO_UCS2 | FIO_ENDIAN_L))
+	    name = "ucs-2le";	/* FF FE */
+	else if (flags == (FIO_UTF16 | FIO_ENDIAN_L))
+	    name = "utf-16le";	/* FF FE */
+    }
+    else if (p[0] == 0xfe && p[1] == 0xff
+	    && (flags == FIO_ALL || flags == FIO_UCS2 || flags == FIO_UTF16))
+    {
+	if (flags == FIO_UTF16)
+	    name = "utf-16";	/* FE FF */
+	else
+	    name = "ucs-2";	/* FE FF */
+    }
+    else if (size >= 4 && p[0] == 0 && p[1] == 0 && p[2] == 0xfe
+	    && p[3] == 0xff && (flags == FIO_ALL || flags == FIO_UCS4))
+    {
+	name = "ucs-4";		/* 00 00 FE FF */
+	len = 4;
+    }
+
+    *lenp = len;
+    return (char_u *)name;
+}
+
+/*
+ * Generate a BOM in "buf[4]" for encoding "name".
+ * Return the length of the BOM (zero when no BOM).
+ */
+    static int
+make_bom(buf, name)
+    char_u	*buf;
+    char_u	*name;
+{
+    int		flags;
+    char_u	*p;
+
+    flags = get_fio_flags(name);
+
+    /* Can't put a BOM in a non-Unicode file. */
+    if (flags == FIO_LATIN1 || flags == 0)
+	return 0;
+
+    if (flags == FIO_UTF8)	/* UTF-8 */
+    {
+	buf[0] = 0xef;
+	buf[1] = 0xbb;
+	buf[2] = 0xbf;
+	return 3;
+    }
+    p = buf;
+    (void)ucs2bytes(0xfeff, &p, flags);
+    return (int)(p - buf);
+}
+#endif
+
+/*
+ * Try to find a shortname by comparing the fullname with the current
+ * directory.
+ * Returns NULL if not shorter name possible, pointer into "full_path"
+ * otherwise.
+ */
+    char_u *
+shorten_fname(full_path, dir_name)
+    char_u	*full_path;
+    char_u	*dir_name;
+{
+    int		len;
+    char_u	*p;
+
+    if (full_path == NULL)
+	return NULL;
+    len = (int)STRLEN(dir_name);
+    if (fnamencmp(dir_name, full_path, len) == 0)
+    {
+	p = full_path + len;
+#if defined(MSDOS) || defined(MSWIN) || defined(OS2)
+	/*
+	 * MSDOS: when a file is in the root directory, dir_name will end in a
+	 * slash, since C: by itself does not define a specific dir. In this
+	 * case p may already be correct. <negri>
+	 */
+	if (!((len > 2) && (*(p - 2) == ':')))
+#endif
+	{
+	    if (vim_ispathsep(*p))
+		++p;
+#ifndef VMS   /* the path separator is always part of the path */
+	    else
+		p = NULL;
+#endif
+	}
+    }
+#if defined(MSDOS) || defined(MSWIN) || defined(OS2)
+    /*
+     * When using a file in the current drive, remove the drive name:
+     * "A:\dir\file" -> "\dir\file".  This helps when moving a session file on
+     * a floppy from "A:\dir" to "B:\dir".
+     */
+    else if (len > 3
+	    && TOUPPER_LOC(full_path[0]) == TOUPPER_LOC(dir_name[0])
+	    && full_path[1] == ':'
+	    && vim_ispathsep(full_path[2]))
+	p = full_path + 2;
+#endif
+    else
+	p = NULL;
+    return p;
+}
+
+/*
+ * Shorten filenames for all buffers.
+ * When "force" is TRUE: Use full path from now on for files currently being
+ * edited, both for file name and swap file name.  Try to shorten the file
+ * names a bit, if safe to do so.
+ * When "force" is FALSE: Only try to shorten absolute file names.
+ * For buffers that have buftype "nofile" or "scratch": never change the file
+ * name.
+ */
+    void
+shorten_fnames(force)
+    int		force;
+{
+    char_u	dirname[MAXPATHL];
+    buf_T	*buf;
+    char_u	*p;
+
+    mch_dirname(dirname, MAXPATHL);
+    for (buf = firstbuf; buf != NULL; buf = buf->b_next)
+    {
+	if (buf->b_fname != NULL
+#ifdef FEAT_QUICKFIX
+		&& !bt_nofile(buf)
+#endif
+		&& !path_with_url(buf->b_fname)
+		&& (force
+		    || buf->b_sfname == NULL
+		    || mch_isFullName(buf->b_sfname)))
+	{
+	    vim_free(buf->b_sfname);
+	    buf->b_sfname = NULL;
+	    p = shorten_fname(buf->b_ffname, dirname);
+	    if (p != NULL)
+	    {
+		buf->b_sfname = vim_strsave(p);
+		buf->b_fname = buf->b_sfname;
+	    }
+	    if (p == NULL || buf->b_fname == NULL)
+		buf->b_fname = buf->b_ffname;
+	}
+
+	/* Always make the swap file name a full path, a "nofile" buffer may
+	 * also have a swap file. */
+	mf_fullname(buf->b_ml.ml_mfp);
+    }
+#ifdef FEAT_WINDOWS
+    status_redraw_all();
+    redraw_tabline = TRUE;
+#endif
+}
+
+#if (defined(FEAT_DND) && defined(FEAT_GUI_GTK)) \
+	|| defined(FEAT_GUI_MSWIN) \
+	|| defined(FEAT_GUI_MAC) \
+	|| defined(PROTO)
+/*
+ * Shorten all filenames in "fnames[count]" by current directory.
+ */
+    void
+shorten_filenames(fnames, count)
+    char_u	**fnames;
+    int		count;
+{
+    int		i;
+    char_u	dirname[MAXPATHL];
+    char_u	*p;
+
+    if (fnames == NULL || count < 1)
+	return;
+    mch_dirname(dirname, sizeof(dirname));
+    for (i = 0; i < count; ++i)
+    {
+	if ((p = shorten_fname(fnames[i], dirname)) != NULL)
+	{
+	    /* shorten_fname() returns pointer in given "fnames[i]".  If free
+	     * "fnames[i]" first, "p" becomes invalid.  So we need to copy
+	     * "p" first then free fnames[i]. */
+	    p = vim_strsave(p);
+	    vim_free(fnames[i]);
+	    fnames[i] = p;
+	}
+    }
+}
+#endif
+
+/*
+ * add extention to file name - change path/fo.o.h to path/fo.o.h.ext or
+ * fo_o_h.ext for MSDOS or when shortname option set.
+ *
+ * Assumed that fname is a valid name found in the filesystem we assure that
+ * the return value is a different name and ends in 'ext'.
+ * "ext" MUST be at most 4 characters long if it starts with a dot, 3
+ * characters otherwise.
+ * Space for the returned name is allocated, must be freed later.
+ * Returns NULL when out of memory.
+ */
+    char_u *
+modname(fname, ext, prepend_dot)
+    char_u *fname, *ext;
+    int	    prepend_dot;	/* may prepend a '.' to file name */
+{
+    return buf_modname(
+#ifdef SHORT_FNAME
+			TRUE,
+#else
+			(curbuf->b_p_sn || curbuf->b_shortname),
+#endif
+						     fname, ext, prepend_dot);
+}
+
+    char_u *
+buf_modname(shortname, fname, ext, prepend_dot)
+    int	    shortname;		/* use 8.3 file name */
+    char_u  *fname, *ext;
+    int	    prepend_dot;	/* may prepend a '.' to file name */
+{
+    char_u	*retval;
+    char_u	*s;
+    char_u	*e;
+    char_u	*ptr;
+    int		fnamelen, extlen;
+
+    extlen = (int)STRLEN(ext);
+
+    /*
+     * If there is no file name we must get the name of the current directory
+     * (we need the full path in case :cd is used).
+     */
+    if (fname == NULL || *fname == NUL)
+    {
+	retval = alloc((unsigned)(MAXPATHL + extlen + 3));
+	if (retval == NULL)
+	    return NULL;
+	if (mch_dirname(retval, MAXPATHL) == FAIL ||
+				     (fnamelen = (int)STRLEN(retval)) == 0)
+	{
+	    vim_free(retval);
+	    return NULL;
+	}
+	if (!after_pathsep(retval, retval + fnamelen))
+	{
+	    retval[fnamelen++] = PATHSEP;
+	    retval[fnamelen] = NUL;
+	}
+#ifndef SHORT_FNAME
+	prepend_dot = FALSE;	    /* nothing to prepend a dot to */
+#endif
+    }
+    else
+    {
+	fnamelen = (int)STRLEN(fname);
+	retval = alloc((unsigned)(fnamelen + extlen + 3));
+	if (retval == NULL)
+	    return NULL;
+	STRCPY(retval, fname);
+#ifdef VMS
+	vms_remove_version(retval); /* we do not need versions here */
+#endif
+    }
+
+    /*
+     * search backwards until we hit a '/', '\' or ':' replacing all '.'
+     * by '_' for MSDOS or when shortname option set and ext starts with a dot.
+     * Then truncate what is after the '/', '\' or ':' to 8 characters for
+     * MSDOS and 26 characters for AMIGA, a lot more for UNIX.
+     */
+    for (ptr = retval + fnamelen; ptr > retval; mb_ptr_back(retval, ptr))
+    {
+#ifndef RISCOS
+	if (*ext == '.'
+# ifdef USE_LONG_FNAME
+		    && (!USE_LONG_FNAME || shortname)
+# else
+#  ifndef SHORT_FNAME
+		    && shortname
+#  endif
+# endif
+								)
+	    if (*ptr == '.')	/* replace '.' by '_' */
+		*ptr = '_';
+#endif
+	if (vim_ispathsep(*ptr))
+	{
+	    ++ptr;
+	    break;
+	}
+    }
+
+    /* the file name has at most BASENAMELEN characters. */
+#ifndef SHORT_FNAME
+    if (STRLEN(ptr) > (unsigned)BASENAMELEN)
+	ptr[BASENAMELEN] = '\0';
+#endif
+
+    s = ptr + STRLEN(ptr);
+
+    /*
+     * For 8.3 file names we may have to reduce the length.
+     */
+#ifdef USE_LONG_FNAME
+    if (!USE_LONG_FNAME || shortname)
+#else
+# ifndef SHORT_FNAME
+    if (shortname)
+# endif
+#endif
+    {
+	/*
+	 * If there is no file name, or the file name ends in '/', and the
+	 * extension starts with '.', put a '_' before the dot, because just
+	 * ".ext" is invalid.
+	 */
+	if (fname == NULL || *fname == NUL
+				   || vim_ispathsep(fname[STRLEN(fname) - 1]))
+	{
+#ifdef RISCOS
+	    if (*ext == '/')
+#else
+	    if (*ext == '.')
+#endif
+		*s++ = '_';
+	}
+	/*
+	 * If the extension starts with '.', truncate the base name at 8
+	 * characters
+	 */
+#ifdef RISCOS
+	/* We normally use '/', but swap files are '_' */
+	else if (*ext == '/' || *ext == '_')
+#else
+	else if (*ext == '.')
+#endif
+	{
+	    if (s - ptr > (size_t)8)
+	    {
+		s = ptr + 8;
+		*s = '\0';
+	    }
+	}
+	/*
+	 * If the extension doesn't start with '.', and the file name
+	 * doesn't have an extension yet, append a '.'
+	 */
+#ifdef RISCOS
+	else if ((e = vim_strchr(ptr, '/')) == NULL)
+	    *s++ = '/';
+#else
+	else if ((e = vim_strchr(ptr, '.')) == NULL)
+	    *s++ = '.';
+#endif
+	/*
+	 * If the extension doesn't start with '.', and there already is an
+	 * extension, it may need to be truncated
+	 */
+	else if ((int)STRLEN(e) + extlen > 4)
+	    s = e + 4 - extlen;
+    }
+#if defined(OS2) || defined(USE_LONG_FNAME) || defined(WIN3264)
+    /*
+     * If there is no file name, and the extension starts with '.', put a
+     * '_' before the dot, because just ".ext" may be invalid if it's on a
+     * FAT partition, and on HPFS it doesn't matter.
+     */
+    else if ((fname == NULL || *fname == NUL) && *ext == '.')
+	*s++ = '_';
+#endif
+
+    /*
+     * Append the extention.
+     * ext can start with '.' and cannot exceed 3 more characters.
+     */
+    STRCPY(s, ext);
+
+#ifndef SHORT_FNAME
+    /*
+     * Prepend the dot.
+     */
+    if (prepend_dot && !shortname && *(e = gettail(retval)) !=
+#ifdef RISCOS
+	    '/'
+#else
+	    '.'
+#endif
+#ifdef USE_LONG_FNAME
+	    && USE_LONG_FNAME
+#endif
+				)
+    {
+	mch_memmove(e + 1, e, STRLEN(e) + 1);
+#ifdef RISCOS
+	*e = '/';
+#else
+	*e = '.';
+#endif
+    }
+#endif
+
+    /*
+     * Check that, after appending the extension, the file name is really
+     * different.
+     */
+    if (fname != NULL && STRCMP(fname, retval) == 0)
+    {
+	/* we search for a character that can be replaced by '_' */
+	while (--s >= ptr)
+	{
+	    if (*s != '_')
+	    {
+		*s = '_';
+		break;
+	    }
+	}
+	if (s < ptr)	/* fname was "________.<ext>", how tricky! */
+	    *ptr = 'v';
+    }
+    return retval;
+}
+
+/*
+ * Like fgets(), but if the file line is too long, it is truncated and the
+ * rest of the line is thrown away.  Returns TRUE for end-of-file.
+ */
+    int
+vim_fgets(buf, size, fp)
+    char_u	*buf;
+    int		size;
+    FILE	*fp;
+{
+    char	*eof;
+#define FGETS_SIZE 200
+    char	tbuf[FGETS_SIZE];
+
+    buf[size - 2] = NUL;
+#ifdef USE_CR
+    eof = fgets_cr((char *)buf, size, fp);
+#else
+    eof = fgets((char *)buf, size, fp);
+#endif
+    if (buf[size - 2] != NUL && buf[size - 2] != '\n')
+    {
+	buf[size - 1] = NUL;	    /* Truncate the line */
+
+	/* Now throw away the rest of the line: */
+	do
+	{
+	    tbuf[FGETS_SIZE - 2] = NUL;
+#ifdef USE_CR
+	    fgets_cr((char *)tbuf, FGETS_SIZE, fp);
+#else
+	    fgets((char *)tbuf, FGETS_SIZE, fp);
+#endif
+	} while (tbuf[FGETS_SIZE - 2] != NUL && tbuf[FGETS_SIZE - 2] != '\n');
+    }
+    return (eof == NULL);
+}
+
+#if defined(USE_CR) || defined(PROTO)
+/*
+ * Like vim_fgets(), but accept any line terminator: CR, CR-LF or LF.
+ * Returns TRUE for end-of-file.
+ * Only used for the Mac, because it's much slower than vim_fgets().
+ */
+    int
+tag_fgets(buf, size, fp)
+    char_u	*buf;
+    int		size;
+    FILE	*fp;
+{
+    int		i = 0;
+    int		c;
+    int		eof = FALSE;
+
+    for (;;)
+    {
+	c = fgetc(fp);
+	if (c == EOF)
+	{
+	    eof = TRUE;
+	    break;
+	}
+	if (c == '\r')
+	{
+	    /* Always store a NL for end-of-line. */
+	    if (i < size - 1)
+		buf[i++] = '\n';
+	    c = fgetc(fp);
+	    if (c != '\n')	/* Macintosh format: single CR. */
+		ungetc(c, fp);
+	    break;
+	}
+	if (i < size - 1)
+	    buf[i++] = c;
+	if (c == '\n')
+	    break;
+    }
+    buf[i] = NUL;
+    return eof;
+}
+#endif
+
+/*
+ * rename() only works if both files are on the same file system, this
+ * function will (attempts to?) copy the file across if rename fails -- webb
+ * Return -1 for failure, 0 for success.
+ */
+    int
+vim_rename(from, to)
+    char_u	*from;
+    char_u	*to;
+{
+    int		fd_in;
+    int		fd_out;
+    int		n;
+    char	*errmsg = NULL;
+    char	*buffer;
+#ifdef AMIGA
+    BPTR	flock;
+#endif
+    struct stat	st;
+    long	perm;
+#ifdef HAVE_ACL
+    vim_acl_T	acl;		/* ACL from original file */
+#endif
+
+    /*
+     * When the names are identical, there is nothing to do.
+     */
+    if (fnamecmp(from, to) == 0)
+	return 0;
+
+    /*
+     * Fail if the "from" file doesn't exist.  Avoids that "to" is deleted.
+     */
+    if (mch_stat((char *)from, &st) < 0)
+	return -1;
+
+    /*
+     * Delete the "to" file, this is required on some systems to make the
+     * mch_rename() work, on other systems it makes sure that we don't have
+     * two files when the mch_rename() fails.
+     */
+
+#ifdef AMIGA
+    /*
+     * With MSDOS-compatible filesystems (crossdos, messydos) it is possible
+     * that the name of the "to" file is the same as the "from" file, even
+     * though the names are different. To avoid the chance of accidentally
+     * deleting the "from" file (horror!) we lock it during the remove.
+     *
+     * When used for making a backup before writing the file: This should not
+     * happen with ":w", because startscript() should detect this problem and
+     * set buf->b_shortname, causing modname() to return a correct ".bak" file
+     * name.  This problem does exist with ":w filename", but then the
+     * original file will be somewhere else so the backup isn't really
+     * important. If autoscripting is off the rename may fail.
+     */
+    flock = Lock((UBYTE *)from, (long)ACCESS_READ);
+#endif
+    mch_remove(to);
+#ifdef AMIGA
+    if (flock)
+	UnLock(flock);
+#endif
+
+    /*
+     * First try a normal rename, return if it works.
+     */
+    if (mch_rename((char *)from, (char *)to) == 0)
+	return 0;
+
+    /*
+     * Rename() failed, try copying the file.
+     */
+    perm = mch_getperm(from);
+#ifdef HAVE_ACL
+    /* For systems that support ACL: get the ACL from the original file. */
+    acl = mch_get_acl(from);
+#endif
+    fd_in = mch_open((char *)from, O_RDONLY|O_EXTRA, 0);
+    if (fd_in == -1)
+	return -1;
+
+    /* Create the new file with same permissions as the original. */
+    fd_out = mch_open((char *)to,
+		       O_CREAT|O_EXCL|O_WRONLY|O_EXTRA|O_NOFOLLOW, (int)perm);
+    if (fd_out == -1)
+    {
+	close(fd_in);
+	return -1;
+    }
+
+    buffer = (char *)alloc(BUFSIZE);
+    if (buffer == NULL)
+    {
+	close(fd_in);
+	close(fd_out);
+	return -1;
+    }
+
+    while ((n = vim_read(fd_in, buffer, BUFSIZE)) > 0)
+	if (vim_write(fd_out, buffer, n) != n)
+	{
+	    errmsg = _("E208: Error writing to \"%s\"");
+	    break;
+	}
+
+    vim_free(buffer);
+    close(fd_in);
+    if (close(fd_out) < 0)
+	errmsg = _("E209: Error closing \"%s\"");
+    if (n < 0)
+    {
+	errmsg = _("E210: Error reading \"%s\"");
+	to = from;
+    }
+#ifndef UNIX	    /* for Unix mch_open() already set the permission */
+    mch_setperm(to, perm);
+#endif
+#ifdef HAVE_ACL
+    mch_set_acl(to, acl);
+#endif
+    if (errmsg != NULL)
+    {
+	EMSG2(errmsg, to);
+	return -1;
+    }
+    mch_remove(from);
+    return 0;
+}
+
+static int already_warned = FALSE;
+
+/*
+ * Check if any not hidden buffer has been changed.
+ * Postpone the check if there are characters in the stuff buffer, a global
+ * command is being executed, a mapping is being executed or an autocommand is
+ * busy.
+ * Returns TRUE if some message was written (screen should be redrawn and
+ * cursor positioned).
+ */
+    int
+check_timestamps(focus)
+    int		focus;		/* called for GUI focus event */
+{
+    buf_T	*buf;
+    int		didit = 0;
+    int		n;
+
+    /* Don't check timestamps while system() or another low-level function may
+     * cause us to lose and gain focus. */
+    if (no_check_timestamps > 0)
+	return FALSE;
+
+    /* Avoid doing a check twice.  The OK/Reload dialog can cause a focus
+     * event and we would keep on checking if the file is steadily growing.
+     * Do check again after typing something. */
+    if (focus && did_check_timestamps)
+    {
+	need_check_timestamps = TRUE;
+	return FALSE;
+    }
+
+    if (!stuff_empty() || global_busy || !typebuf_typed()
+#ifdef FEAT_AUTOCMD
+			|| autocmd_busy || curbuf_lock > 0
+#endif
+					)
+	need_check_timestamps = TRUE;		/* check later */
+    else
+    {
+	++no_wait_return;
+	did_check_timestamps = TRUE;
+	already_warned = FALSE;
+	for (buf = firstbuf; buf != NULL; )
+	{
+	    /* Only check buffers in a window. */
+	    if (buf->b_nwindows > 0)
+	    {
+		n = buf_check_timestamp(buf, focus);
+		if (didit < n)
+		    didit = n;
+		if (n > 0 && !buf_valid(buf))
+		{
+		    /* Autocommands have removed the buffer, start at the
+		     * first one again. */
+		    buf = firstbuf;
+		    continue;
+		}
+	    }
+	    buf = buf->b_next;
+	}
+	--no_wait_return;
+	need_check_timestamps = FALSE;
+	if (need_wait_return && didit == 2)
+	{
+	    /* make sure msg isn't overwritten */
+	    msg_puts((char_u *)"\n");
+	    out_flush();
+	}
+    }
+    return didit;
+}
+
+/*
+ * Move all the lines from buffer "frombuf" to buffer "tobuf".
+ * Return OK or FAIL.  When FAIL "tobuf" is incomplete and/or "frombuf" is not
+ * empty.
+ */
+    static int
+move_lines(frombuf, tobuf)
+    buf_T	*frombuf;
+    buf_T	*tobuf;
+{
+    buf_T	*tbuf = curbuf;
+    int		retval = OK;
+    linenr_T	lnum;
+    char_u	*p;
+
+    /* Copy the lines in "frombuf" to "tobuf". */
+    curbuf = tobuf;
+    for (lnum = 1; lnum <= frombuf->b_ml.ml_line_count; ++lnum)
+    {
+	p = vim_strsave(ml_get_buf(frombuf, lnum, FALSE));
+	if (p == NULL || ml_append(lnum - 1, p, 0, FALSE) == FAIL)
+	{
+	    vim_free(p);
+	    retval = FAIL;
+	    break;
+	}
+	vim_free(p);
+    }
+
+    /* Delete all the lines in "frombuf". */
+    if (retval != FAIL)
+    {
+	curbuf = frombuf;
+	for (lnum = curbuf->b_ml.ml_line_count; lnum > 0; --lnum)
+	    if (ml_delete(lnum, FALSE) == FAIL)
+	    {
+		/* Oops!  We could try putting back the saved lines, but that
+		 * might fail again... */
+		retval = FAIL;
+		break;
+	    }
+    }
+
+    curbuf = tbuf;
+    return retval;
+}
+
+/*
+ * Check if buffer "buf" has been changed.
+ * Also check if the file for a new buffer unexpectedly appeared.
+ * return 1 if a changed buffer was found.
+ * return 2 if a message has been displayed.
+ * return 0 otherwise.
+ */
+/*ARGSUSED*/
+    int
+buf_check_timestamp(buf, focus)
+    buf_T	*buf;
+    int		focus;		/* called for GUI focus event */
+{
+    struct stat	st;
+    int		stat_res;
+    int		retval = 0;
+    char_u	*path;
+    char_u	*tbuf;
+    char	*mesg = NULL;
+    char	*mesg2 = "";
+    int		helpmesg = FALSE;
+    int		reload = FALSE;
+#if defined(FEAT_CON_DIALOG) || defined(FEAT_GUI_DIALOG)
+    int		can_reload = FALSE;
+#endif
+    size_t	orig_size = buf->b_orig_size;
+    int		orig_mode = buf->b_orig_mode;
+#ifdef FEAT_GUI
+    int		save_mouse_correct = need_mouse_correct;
+#endif
+#ifdef FEAT_AUTOCMD
+    static int	busy = FALSE;
+    int		n;
+    char_u	*s;
+#endif
+    char	*reason;
+
+    /* If there is no file name, the buffer is not loaded, 'buftype' is
+     * set, we are in the middle of a save or being called recursively: ignore
+     * this buffer. */
+    if (buf->b_ffname == NULL
+	    || buf->b_ml.ml_mfp == NULL
+#if defined(FEAT_QUICKFIX)
+	    || *buf->b_p_bt != NUL
+#endif
+	    || buf->b_saving
+#ifdef FEAT_AUTOCMD
+	    || busy
+#endif
+#ifdef FEAT_NETBEANS_INTG
+	    || isNetbeansBuffer(buf)
+#endif
+	    )
+	return 0;
+
+    if (       !(buf->b_flags & BF_NOTEDITED)
+	    && buf->b_mtime != 0
+	    && ((stat_res = mch_stat((char *)buf->b_ffname, &st)) < 0
+		|| time_differs((long)st.st_mtime, buf->b_mtime)
+#ifdef HAVE_ST_MODE
+		|| (int)st.st_mode != buf->b_orig_mode
+#else
+		|| mch_getperm(buf->b_ffname) != buf->b_orig_mode
+#endif
+		))
+    {
+	retval = 1;
+
+	/* set b_mtime to stop further warnings (e.g., when executing
+	 * FileChangedShell autocmd) */
+	if (stat_res < 0)
+	{
+	    buf->b_mtime = 0;
+	    buf->b_orig_size = 0;
+	    buf->b_orig_mode = 0;
+	}
+	else
+	    buf_store_time(buf, &st, buf->b_ffname);
+
+	/* Don't do anything for a directory.  Might contain the file
+	 * explorer. */
+	if (mch_isdir(buf->b_fname))
+	    ;
+
+	/*
+	 * If 'autoread' is set, the buffer has no changes and the file still
+	 * exists, reload the buffer.  Use the buffer-local option value if it
+	 * was set, the global option value otherwise.
+	 */
+	else if ((buf->b_p_ar >= 0 ? buf->b_p_ar : p_ar)
+				       && !bufIsChanged(buf) && stat_res >= 0)
+	    reload = TRUE;
+	else
+	{
+	    if (stat_res < 0)
+		reason = "deleted";
+	    else if (bufIsChanged(buf))
+		reason = "conflict";
+	    else if (orig_size != buf->b_orig_size || buf_contents_changed(buf))
+		reason = "changed";
+	    else if (orig_mode != buf->b_orig_mode)
+		reason = "mode";
+	    else
+		reason = "time";
+
+#ifdef FEAT_AUTOCMD
+	    /*
+	     * Only give the warning if there are no FileChangedShell
+	     * autocommands.
+	     * Avoid being called recursively by setting "busy".
+	     */
+	    busy = TRUE;
+# ifdef FEAT_EVAL
+	    set_vim_var_string(VV_FCS_REASON, (char_u *)reason, -1);
+	    set_vim_var_string(VV_FCS_CHOICE, (char_u *)"", -1);
+# endif
+	    n = apply_autocmds(EVENT_FILECHANGEDSHELL,
+				      buf->b_fname, buf->b_fname, FALSE, buf);
+	    busy = FALSE;
+	    if (n)
+	    {
+		if (!buf_valid(buf))
+		    EMSG(_("E246: FileChangedShell autocommand deleted buffer"));
+# ifdef FEAT_EVAL
+		s = get_vim_var_str(VV_FCS_CHOICE);
+		if (STRCMP(s, "reload") == 0 && *reason != 'd')
+		    reload = TRUE;
+		else if (STRCMP(s, "ask") == 0)
+		    n = FALSE;
+		else
+# endif
+		    return 2;
+	    }
+	    if (!n)
+#endif
+	    {
+		if (*reason == 'd')
+		    mesg = _("E211: File \"%s\" no longer available");
+		else
+		{
+		    helpmesg = TRUE;
+#if defined(FEAT_CON_DIALOG) || defined(FEAT_GUI_DIALOG)
+		    can_reload = TRUE;
+#endif
+		    /*
+		     * Check if the file contents really changed to avoid
+		     * giving a warning when only the timestamp was set (e.g.,
+		     * checked out of CVS).  Always warn when the buffer was
+		     * changed.
+		     */
+		    if (reason[2] == 'n')
+		    {
+			mesg = _("W12: Warning: File \"%s\" has changed and the buffer was changed in Vim as well");
+			mesg2 = _("See \":help W12\" for more info.");
+		    }
+		    else if (reason[1] == 'h')
+		    {
+			mesg = _("W11: Warning: File \"%s\" has changed since editing started");
+			mesg2 = _("See \":help W11\" for more info.");
+		    }
+		    else if (*reason == 'm')
+		    {
+			mesg = _("W16: Warning: Mode of file \"%s\" has changed since editing started");
+			mesg2 = _("See \":help W16\" for more info.");
+		    }
+		    /* Else: only timestamp changed, ignored */
+		}
+	    }
+	}
+
+    }
+    else if ((buf->b_flags & BF_NEW) && !(buf->b_flags & BF_NEW_W)
+						&& vim_fexists(buf->b_ffname))
+    {
+	retval = 1;
+	mesg = _("W13: Warning: File \"%s\" has been created after editing started");
+	buf->b_flags |= BF_NEW_W;
+#if defined(FEAT_CON_DIALOG) || defined(FEAT_GUI_DIALOG)
+	can_reload = TRUE;
+#endif
+    }
+
+    if (mesg != NULL)
+    {
+	path = home_replace_save(buf, buf->b_fname);
+	if (path != NULL)
+	{
+	    if (!helpmesg)
+		mesg2 = "";
+	    tbuf = alloc((unsigned)(STRLEN(path) + STRLEN(mesg)
+							+ STRLEN(mesg2) + 2));
+	    sprintf((char *)tbuf, mesg, path);
+#if defined(FEAT_CON_DIALOG) || defined(FEAT_GUI_DIALOG)
+	    if (can_reload)
+	    {
+		if (*mesg2 != NUL)
+		{
+		    STRCAT(tbuf, "\n");
+		    STRCAT(tbuf, mesg2);
+		}
+		if (do_dialog(VIM_WARNING, (char_u *)_("Warning"), tbuf,
+				(char_u *)_("&OK\n&Load File"), 1, NULL) == 2)
+		    reload = TRUE;
+	    }
+	    else
+#endif
+	    if (State > NORMAL_BUSY || (State & CMDLINE) || already_warned)
+	    {
+		if (*mesg2 != NUL)
+		{
+		    STRCAT(tbuf, "; ");
+		    STRCAT(tbuf, mesg2);
+		}
+		EMSG(tbuf);
+		retval = 2;
+	    }
+	    else
+	    {
+# ifdef FEAT_AUTOCMD
+		if (!autocmd_busy)
+# endif
+		{
+		    msg_start();
+		    msg_puts_attr(tbuf, hl_attr(HLF_E) + MSG_HIST);
+		    if (*mesg2 != NUL)
+			msg_puts_attr((char_u *)mesg2,
+						   hl_attr(HLF_W) + MSG_HIST);
+		    msg_clr_eos();
+		    (void)msg_end();
+		    if (emsg_silent == 0)
+		    {
+			out_flush();
+# ifdef FEAT_GUI
+			if (!focus)
+# endif
+			    /* give the user some time to think about it */
+			    ui_delay(1000L, TRUE);
+
+			/* don't redraw and erase the message */
+			redraw_cmdline = FALSE;
+		    }
+		}
+		already_warned = TRUE;
+	    }
+
+	    vim_free(path);
+	    vim_free(tbuf);
+	}
+    }
+
+    if (reload)
+	/* Reload the buffer. */
+	buf_reload(buf, orig_mode);
+
+#ifdef FEAT_AUTOCMD
+    if (buf_valid(buf))
+	(void)apply_autocmds(EVENT_FILECHANGEDSHELLPOST,
+				      buf->b_fname, buf->b_fname, FALSE, buf);
+#endif
+#ifdef FEAT_GUI
+    /* restore this in case an autocommand has set it; it would break
+     * 'mousefocus' */
+    need_mouse_correct = save_mouse_correct;
+#endif
+
+    return retval;
+}
+
+/*
+ * Reload a buffer that is already loaded.
+ * Used when the file was changed outside of Vim.
+ * "orig_mode" is buf->b_orig_mode before the need for reloading was detected.
+ * buf->b_orig_mode may have been reset already.
+ */
+    void
+buf_reload(buf, orig_mode)
+    buf_T	*buf;
+    int		orig_mode;
+{
+    exarg_T	ea;
+    pos_T	old_cursor;
+    linenr_T	old_topline;
+    int		old_ro = buf->b_p_ro;
+    buf_T	*savebuf;
+    int		saved = OK;
+    aco_save_T	aco;
+
+    /* set curwin/curbuf for "buf" and save some things */
+    aucmd_prepbuf(&aco, buf);
+
+    /* We only want to read the text from the file, not reset the syntax
+     * highlighting, clear marks, diff status, etc.  Force the fileformat
+     * and encoding to be the same. */
+    if (prep_exarg(&ea, buf) == OK)
+    {
+	old_cursor = curwin->w_cursor;
+	old_topline = curwin->w_topline;
+
+	/*
+	 * To behave like when a new file is edited (matters for
+	 * BufReadPost autocommands) we first need to delete the current
+	 * buffer contents.  But if reading the file fails we should keep
+	 * the old contents.  Can't use memory only, the file might be
+	 * too big.  Use a hidden buffer to move the buffer contents to.
+	 */
+	if (bufempty())
+	    savebuf = NULL;
+	else
+	{
+	    /* Allocate a buffer without putting it in the buffer list. */
+	    savebuf = buflist_new(NULL, NULL, (linenr_T)1, BLN_DUMMY);
+	    if (savebuf != NULL && buf == curbuf)
+	    {
+		/* Open the memline. */
+		curbuf = savebuf;
+		curwin->w_buffer = savebuf;
+		saved = ml_open(curbuf);
+		curbuf = buf;
+		curwin->w_buffer = buf;
+	    }
+	    if (savebuf == NULL || saved == FAIL || buf != curbuf
+				      || move_lines(buf, savebuf) == FAIL)
+	    {
+		EMSG2(_("E462: Could not prepare for reloading \"%s\""),
+							    buf->b_fname);
+		saved = FAIL;
+	    }
+	}
+
+	if (saved == OK)
+	{
+	    curbuf->b_flags |= BF_CHECK_RO;	/* check for RO again */
+#ifdef FEAT_AUTOCMD
+	    keep_filetype = TRUE;		/* don't detect 'filetype' */
+#endif
+	    if (readfile(buf->b_ffname, buf->b_fname, (linenr_T)0,
+			(linenr_T)0,
+			(linenr_T)MAXLNUM, &ea, READ_NEW) == FAIL)
+	    {
+#if defined(FEAT_AUTOCMD) && defined(FEAT_EVAL)
+		if (!aborting())
+#endif
+		    EMSG2(_("E321: Could not reload \"%s\""), buf->b_fname);
+		if (savebuf != NULL && buf_valid(savebuf) && buf == curbuf)
+		{
+		    /* Put the text back from the save buffer.  First
+		     * delete any lines that readfile() added. */
+		    while (!bufempty())
+			if (ml_delete(buf->b_ml.ml_line_count, FALSE) == FAIL)
+			    break;
+		    (void)move_lines(savebuf, buf);
+		}
+	    }
+	    else if (buf == curbuf)
+	    {
+		/* Mark the buffer as unmodified and free undo info. */
+		unchanged(buf, TRUE);
+		u_blockfree(buf);
+		u_clearall(buf);
+	    }
+	}
+	vim_free(ea.cmd);
+
+	if (savebuf != NULL && buf_valid(savebuf))
+	    wipe_buffer(savebuf, FALSE);
+
+#ifdef FEAT_DIFF
+	/* Invalidate diff info if necessary. */
+	diff_invalidate(curbuf);
+#endif
+
+	/* Restore the topline and cursor position and check it (lines may
+	 * have been removed). */
+	if (old_topline > curbuf->b_ml.ml_line_count)
+	    curwin->w_topline = curbuf->b_ml.ml_line_count;
+	else
+	    curwin->w_topline = old_topline;
+	curwin->w_cursor = old_cursor;
+	check_cursor();
+	update_topline();
+#ifdef FEAT_AUTOCMD
+	keep_filetype = FALSE;
+#endif
+#ifdef FEAT_FOLDING
+	{
+	    win_T *wp;
+
+	    /* Update folds unless they are defined manually. */
+	    FOR_ALL_WINDOWS(wp)
+		if (wp->w_buffer == curwin->w_buffer
+			&& !foldmethodIsManual(wp))
+		    foldUpdateAll(wp);
+	}
+#endif
+	/* If the mode didn't change and 'readonly' was set, keep the old
+	 * value; the user probably used the ":view" command.  But don't
+	 * reset it, might have had a read error. */
+	if (orig_mode == curbuf->b_orig_mode)
+	    curbuf->b_p_ro |= old_ro;
+    }
+
+    /* restore curwin/curbuf and a few other things */
+    aucmd_restbuf(&aco);
+    /* Careful: autocommands may have made "buf" invalid! */
+}
+
+/*ARGSUSED*/
+    void
+buf_store_time(buf, st, fname)
+    buf_T	*buf;
+    struct stat	*st;
+    char_u	*fname;
+{
+    buf->b_mtime = (long)st->st_mtime;
+    buf->b_orig_size = (size_t)st->st_size;
+#ifdef HAVE_ST_MODE
+    buf->b_orig_mode = (int)st->st_mode;
+#else
+    buf->b_orig_mode = mch_getperm(fname);
+#endif
+}
+
+/*
+ * Adjust the line with missing eol, used for the next write.
+ * Used for do_filter(), when the input lines for the filter are deleted.
+ */
+    void
+write_lnum_adjust(offset)
+    linenr_T	offset;
+{
+    if (write_no_eol_lnum != 0)		/* only if there is a missing eol */
+	write_no_eol_lnum += offset;
+}
+
+#if defined(TEMPDIRNAMES) || defined(PROTO)
+static long	temp_count = 0;		/* Temp filename counter. */
+
+/*
+ * Delete the temp directory and all files it contains.
+ */
+    void
+vim_deltempdir()
+{
+    char_u	**files;
+    int		file_count;
+    int		i;
+
+    if (vim_tempdir != NULL)
+    {
+	sprintf((char *)NameBuff, "%s*", vim_tempdir);
+	if (gen_expand_wildcards(1, &NameBuff, &file_count, &files,
+					      EW_DIR|EW_FILE|EW_SILENT) == OK)
+	{
+	    for (i = 0; i < file_count; ++i)
+		mch_remove(files[i]);
+	    FreeWild(file_count, files);
+	}
+	gettail(NameBuff)[-1] = NUL;
+	(void)mch_rmdir(NameBuff);
+
+	vim_free(vim_tempdir);
+	vim_tempdir = NULL;
+    }
+}
+#endif
+
+/*
+ * vim_tempname(): Return a unique name that can be used for a temp file.
+ *
+ * The temp file is NOT created.
+ *
+ * The returned pointer is to allocated memory.
+ * The returned pointer is NULL if no valid name was found.
+ */
+/*ARGSUSED*/
+    char_u  *
+vim_tempname(extra_char)
+    int	    extra_char;	    /* character to use in the name instead of '?' */
+{
+#ifdef USE_TMPNAM
+    char_u	itmp[L_tmpnam];	/* use tmpnam() */
+#else
+    char_u	itmp[TEMPNAMELEN];
+#endif
+
+#ifdef TEMPDIRNAMES
+    static char	*(tempdirs[]) = {TEMPDIRNAMES};
+    int		i;
+    long	nr;
+    long	off;
+# ifndef EEXIST
+    struct stat	st;
+# endif
+
+    /*
+     * This will create a directory for private use by this instance of Vim.
+     * This is done once, and the same directory is used for all temp files.
+     * This method avoids security problems because of symlink attacks et al.
+     * It's also a bit faster, because we only need to check for an existing
+     * file when creating the directory and not for each temp file.
+     */
+    if (vim_tempdir == NULL)
+    {
+	/*
+	 * Try the entries in TEMPDIRNAMES to create the temp directory.
+	 */
+	for (i = 0; i < sizeof(tempdirs) / sizeof(char *); ++i)
+	{
+	    /* expand $TMP, leave room for "/v1100000/999999999" */
+	    expand_env((char_u *)tempdirs[i], itmp, TEMPNAMELEN - 20);
+	    if (mch_isdir(itmp))		/* directory exists */
+	    {
+# ifdef __EMX__
+		/* If $TMP contains a forward slash (perhaps using bash or
+		 * tcsh), don't add a backslash, use a forward slash!
+		 * Adding 2 backslashes didn't work. */
+		if (vim_strchr(itmp, '/') != NULL)
+		    STRCAT(itmp, "/");
+		else
+# endif
+		    add_pathsep(itmp);
+
+		/* Get an arbitrary number of up to 6 digits.  When it's
+		 * unlikely that it already exists it will be faster,
+		 * otherwise it doesn't matter.  The use of mkdir() avoids any
+		 * security problems because of the predictable number. */
+		nr = (mch_get_pid() + (long)time(NULL)) % 1000000L;
+
+		/* Try up to 10000 different values until we find a name that
+		 * doesn't exist. */
+		for (off = 0; off < 10000L; ++off)
+		{
+		    int		r;
+#if defined(UNIX) || defined(VMS)
+		    mode_t	umask_save;
+#endif
+
+		    sprintf((char *)itmp + STRLEN(itmp), "v%ld", nr + off);
+# ifndef EEXIST
+		    /* If mkdir() does not set errno to EEXIST, check for
+		     * existing file here.  There is a race condition then,
+		     * although it's fail-safe. */
+		    if (mch_stat((char *)itmp, &st) >= 0)
+			continue;
+# endif
+#if defined(UNIX) || defined(VMS)
+		    /* Make sure the umask doesn't remove the executable bit.
+		     * "repl" has been reported to use "177". */
+		    umask_save = umask(077);
+#endif
+		    r = vim_mkdir(itmp, 0700);
+#if defined(UNIX) || defined(VMS)
+		    (void)umask(umask_save);
+#endif
+		    if (r == 0)
+		    {
+			char_u	*buf;
+
+			/* Directory was created, use this name.
+			 * Expand to full path; When using the current
+			 * directory a ":cd" would confuse us. */
+			buf = alloc((unsigned)MAXPATHL + 1);
+			if (buf != NULL)
+			{
+			    if (vim_FullName(itmp, buf, MAXPATHL, FALSE)
+								      == FAIL)
+				STRCPY(buf, itmp);
+# ifdef __EMX__
+			    if (vim_strchr(buf, '/') != NULL)
+				STRCAT(buf, "/");
+			    else
+# endif
+				add_pathsep(buf);
+			    vim_tempdir = vim_strsave(buf);
+			    vim_free(buf);
+			}
+			break;
+		    }
+# ifdef EEXIST
+		    /* If the mkdir() didn't fail because the file/dir exists,
+		     * we probably can't create any dir here, try another
+		     * place. */
+		    if (errno != EEXIST)
+# endif
+			break;
+		}
+		if (vim_tempdir != NULL)
+		    break;
+	    }
+	}
+    }
+
+    if (vim_tempdir != NULL)
+    {
+	/* There is no need to check if the file exists, because we own the
+	 * directory and nobody else creates a file in it. */
+	sprintf((char *)itmp, "%s%ld", vim_tempdir, temp_count++);
+	return vim_strsave(itmp);
+    }
+
+    return NULL;
+
+#else /* TEMPDIRNAMES */
+
+# ifdef WIN3264
+    char	szTempFile[_MAX_PATH + 1];
+    char	buf4[4];
+    char_u	*retval;
+    char_u	*p;
+
+    STRCPY(itmp, "");
+    if (GetTempPath(_MAX_PATH, szTempFile) == 0)
+	szTempFile[0] = NUL;	/* GetTempPath() failed, use current dir */
+    strcpy(buf4, "VIM");
+    buf4[2] = extra_char;   /* make it "VIa", "VIb", etc. */
+    if (GetTempFileName(szTempFile, buf4, 0, itmp) == 0)
+	return NULL;
+    /* GetTempFileName() will create the file, we don't want that */
+    (void)DeleteFile(itmp);
+
+    /* Backslashes in a temp file name cause problems when filtering with
+     * "sh".  NOTE: This also checks 'shellcmdflag' to help those people who
+     * didn't set 'shellslash'. */
+    retval = vim_strsave(itmp);
+    if (*p_shcf == '-' || p_ssl)
+	for (p = retval; *p; ++p)
+	    if (*p == '\\')
+		*p = '/';
+    return retval;
+
+# else /* WIN3264 */
+
+#  ifdef USE_TMPNAM
+    /* tmpnam() will make its own name */
+    if (*tmpnam((char *)itmp) == NUL)
+	return NULL;
+#  else
+    char_u	*p;
+
+#   ifdef VMS_TEMPNAM
+    /* mktemp() is not working on VMS.  It seems to be
+     * a do-nothing function. Therefore we use tempnam().
+     */
+    sprintf((char *)itmp, "VIM%c", extra_char);
+    p = (char_u *)tempnam("tmp:", (char *)itmp);
+    if (p != NULL)
+    {
+	/* VMS will use '.LOG' if we don't explicitly specify an extension,
+	 * and VIM will then be unable to find the file later */
+	STRCPY(itmp, p);
+	STRCAT(itmp, ".txt");
+	free(p);
+    }
+    else
+	return NULL;
+#   else
+    STRCPY(itmp, TEMPNAME);
+    if ((p = vim_strchr(itmp, '?')) != NULL)
+	*p = extra_char;
+    if (mktemp((char *)itmp) == NULL)
+	return NULL;
+#   endif
+#  endif
+
+    return vim_strsave(itmp);
+# endif /* WIN3264 */
+#endif /* TEMPDIRNAMES */
+}
+
+#if defined(BACKSLASH_IN_FILENAME) || defined(PROTO)
+/*
+ * Convert all backslashes in fname to forward slashes in-place.
+ */
+    void
+forward_slash(fname)
+    char_u	*fname;
+{
+    char_u	*p;
+
+    for (p = fname; *p != NUL; ++p)
+# ifdef  FEAT_MBYTE
+	/* The Big5 encoding can have '\' in the trail byte. */
+	if (enc_dbcs != 0 && (*mb_ptr2len)(p) > 1)
+	    ++p;
+	else
+# endif
+	if (*p == '\\')
+	    *p = '/';
+}
+#endif
+
+
+/*
+ * Code for automatic commands.
+ *
+ * Only included when "FEAT_AUTOCMD" has been defined.
+ */
+
+#if defined(FEAT_AUTOCMD) || defined(PROTO)
+
+/*
+ * The autocommands are stored in a list for each event.
+ * Autocommands for the same pattern, that are consecutive, are joined
+ * together, to avoid having to match the pattern too often.
+ * The result is an array of Autopat lists, which point to AutoCmd lists:
+ *
+ * first_autopat[0] --> Autopat.next  -->  Autopat.next -->  NULL
+ *			Autopat.cmds	   Autopat.cmds
+ *			    |			 |
+ *			    V			 V
+ *			AutoCmd.next	   AutoCmd.next
+ *			    |			 |
+ *			    V			 V
+ *			AutoCmd.next		NULL
+ *			    |
+ *			    V
+ *			   NULL
+ *
+ * first_autopat[1] --> Autopat.next  -->  NULL
+ *			Autopat.cmds
+ *			    |
+ *			    V
+ *			AutoCmd.next
+ *			    |
+ *			    V
+ *			   NULL
+ *   etc.
+ *
+ *   The order of AutoCmds is important, this is the order in which they were
+ *   defined and will have to be executed.
+ */
+typedef struct AutoCmd
+{
+    char_u	    *cmd;		/* The command to be executed (NULL
+					   when command has been removed) */
+    char	    nested;		/* If autocommands nest here */
+    char	    last;		/* last command in list */
+#ifdef FEAT_EVAL
+    scid_T	    scriptID;		/* script ID where defined */
+#endif
+    struct AutoCmd  *next;		/* Next AutoCmd in list */
+} AutoCmd;
+
+typedef struct AutoPat
+{
+    int		    group;		/* group ID */
+    char_u	    *pat;		/* pattern as typed (NULL when pattern
+					   has been removed) */
+    int		    patlen;		/* strlen() of pat */
+    regprog_T	    *reg_prog;		/* compiled regprog for pattern */
+    char	    allow_dirs;		/* Pattern may match whole path */
+    char	    last;		/* last pattern for apply_autocmds() */
+    AutoCmd	    *cmds;		/* list of commands to do */
+    struct AutoPat  *next;		/* next AutoPat in AutoPat list */
+    int		    buflocal_nr;	/* !=0 for buffer-local AutoPat */
+} AutoPat;
+
+static struct event_name
+{
+    char	*name;	/* event name */
+    event_T	event;	/* event number */
+} event_names[] =
+{
+    {"BufAdd",		EVENT_BUFADD},
+    {"BufCreate",	EVENT_BUFADD},
+    {"BufDelete",	EVENT_BUFDELETE},
+    {"BufEnter",	EVENT_BUFENTER},
+    {"BufFilePost",	EVENT_BUFFILEPOST},
+    {"BufFilePre",	EVENT_BUFFILEPRE},
+    {"BufHidden",	EVENT_BUFHIDDEN},
+    {"BufLeave",	EVENT_BUFLEAVE},
+    {"BufNew",		EVENT_BUFNEW},
+    {"BufNewFile",	EVENT_BUFNEWFILE},
+    {"BufRead",		EVENT_BUFREADPOST},
+    {"BufReadCmd",	EVENT_BUFREADCMD},
+    {"BufReadPost",	EVENT_BUFREADPOST},
+    {"BufReadPre",	EVENT_BUFREADPRE},
+    {"BufUnload",	EVENT_BUFUNLOAD},
+    {"BufWinEnter",	EVENT_BUFWINENTER},
+    {"BufWinLeave",	EVENT_BUFWINLEAVE},
+    {"BufWipeout",	EVENT_BUFWIPEOUT},
+    {"BufWrite",	EVENT_BUFWRITEPRE},
+    {"BufWritePost",	EVENT_BUFWRITEPOST},
+    {"BufWritePre",	EVENT_BUFWRITEPRE},
+    {"BufWriteCmd",	EVENT_BUFWRITECMD},
+    {"CmdwinEnter",	EVENT_CMDWINENTER},
+    {"CmdwinLeave",	EVENT_CMDWINLEAVE},
+    {"ColorScheme",	EVENT_COLORSCHEME},
+    {"CursorHold",	EVENT_CURSORHOLD},
+    {"CursorHoldI",	EVENT_CURSORHOLDI},
+    {"CursorMoved",	EVENT_CURSORMOVED},
+    {"CursorMovedI",	EVENT_CURSORMOVEDI},
+    {"EncodingChanged",	EVENT_ENCODINGCHANGED},
+    {"FileEncoding",	EVENT_ENCODINGCHANGED},
+    {"FileAppendPost",	EVENT_FILEAPPENDPOST},
+    {"FileAppendPre",	EVENT_FILEAPPENDPRE},
+    {"FileAppendCmd",	EVENT_FILEAPPENDCMD},
+    {"FileChangedShell",EVENT_FILECHANGEDSHELL},
+    {"FileChangedShellPost",EVENT_FILECHANGEDSHELLPOST},
+    {"FileChangedRO",	EVENT_FILECHANGEDRO},
+    {"FileReadPost",	EVENT_FILEREADPOST},
+    {"FileReadPre",	EVENT_FILEREADPRE},
+    {"FileReadCmd",	EVENT_FILEREADCMD},
+    {"FileType",	EVENT_FILETYPE},
+    {"FileWritePost",	EVENT_FILEWRITEPOST},
+    {"FileWritePre",	EVENT_FILEWRITEPRE},
+    {"FileWriteCmd",	EVENT_FILEWRITECMD},
+    {"FilterReadPost",	EVENT_FILTERREADPOST},
+    {"FilterReadPre",	EVENT_FILTERREADPRE},
+    {"FilterWritePost",	EVENT_FILTERWRITEPOST},
+    {"FilterWritePre",	EVENT_FILTERWRITEPRE},
+    {"FocusGained",	EVENT_FOCUSGAINED},
+    {"FocusLost",	EVENT_FOCUSLOST},
+    {"FuncUndefined",	EVENT_FUNCUNDEFINED},
+    {"GUIEnter",	EVENT_GUIENTER},
+    {"GUIFailed",	EVENT_GUIFAILED},
+    {"InsertChange",	EVENT_INSERTCHANGE},
+    {"InsertEnter",	EVENT_INSERTENTER},
+    {"InsertLeave",	EVENT_INSERTLEAVE},
+    {"MenuPopup",	EVENT_MENUPOPUP},
+    {"QuickFixCmdPost",	EVENT_QUICKFIXCMDPOST},
+    {"QuickFixCmdPre",	EVENT_QUICKFIXCMDPRE},
+    {"RemoteReply",	EVENT_REMOTEREPLY},
+    {"SessionLoadPost",	EVENT_SESSIONLOADPOST},
+    {"ShellCmdPost",	EVENT_SHELLCMDPOST},
+    {"ShellFilterPost",	EVENT_SHELLFILTERPOST},
+    {"SourcePre",	EVENT_SOURCEPRE},
+    {"SourceCmd",	EVENT_SOURCECMD},
+    {"SpellFileMissing",EVENT_SPELLFILEMISSING},
+    {"StdinReadPost",	EVENT_STDINREADPOST},
+    {"StdinReadPre",	EVENT_STDINREADPRE},
+    {"SwapExists",	EVENT_SWAPEXISTS},
+    {"Syntax",		EVENT_SYNTAX},
+    {"TabEnter",	EVENT_TABENTER},
+    {"TabLeave",	EVENT_TABLEAVE},
+    {"TermChanged",	EVENT_TERMCHANGED},
+    {"TermResponse",	EVENT_TERMRESPONSE},
+    {"User",		EVENT_USER},
+    {"VimEnter",	EVENT_VIMENTER},
+    {"VimLeave",	EVENT_VIMLEAVE},
+    {"VimLeavePre",	EVENT_VIMLEAVEPRE},
+    {"WinEnter",	EVENT_WINENTER},
+    {"WinLeave",	EVENT_WINLEAVE},
+    {"VimResized",	EVENT_VIMRESIZED},
+    {NULL,		(event_T)0}
+};
+
+static AutoPat *first_autopat[NUM_EVENTS] =
+{
+    NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+    NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+    NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+    NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+    NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+    NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL
+};
+
+/*
+ * struct used to keep status while executing autocommands for an event.
+ */
+typedef struct AutoPatCmd
+{
+    AutoPat	*curpat;	/* next AutoPat to examine */
+    AutoCmd	*nextcmd;	/* next AutoCmd to execute */
+    int		group;		/* group being used */
+    char_u	*fname;		/* fname to match with */
+    char_u	*sfname;	/* sfname to match with */
+    char_u	*tail;		/* tail of fname */
+    event_T	event;		/* current event */
+    int		arg_bufnr;	/* initially equal to <abuf>, set to zero when
+				   buf is deleted */
+    struct AutoPatCmd   *next;	/* chain of active apc-s for auto-invalidation*/
+} AutoPatCmd;
+
+static AutoPatCmd *active_apc_list = NULL; /* stack of active autocommands */
+
+/*
+ * augroups stores a list of autocmd group names.
+ */
+static garray_T augroups = {0, 0, sizeof(char_u *), 10, NULL};
+#define AUGROUP_NAME(i) (((char_u **)augroups.ga_data)[i])
+
+/*
+ * The ID of the current group.  Group 0 is the default one.
+ */
+static int current_augroup = AUGROUP_DEFAULT;
+
+static int au_need_clean = FALSE;   /* need to delete marked patterns */
+
+static void show_autocmd __ARGS((AutoPat *ap, event_T event));
+static void au_remove_pat __ARGS((AutoPat *ap));
+static void au_remove_cmds __ARGS((AutoPat *ap));
+static void au_cleanup __ARGS((void));
+static int au_new_group __ARGS((char_u *name));
+static void au_del_group __ARGS((char_u *name));
+static event_T event_name2nr __ARGS((char_u *start, char_u **end));
+static char_u *event_nr2name __ARGS((event_T event));
+static char_u *find_end_event __ARGS((char_u *arg, int have_group));
+static int event_ignored __ARGS((event_T event));
+static int au_get_grouparg __ARGS((char_u **argp));
+static int do_autocmd_event __ARGS((event_T event, char_u *pat, int nested, char_u *cmd, int forceit, int group));
+static char_u *getnextac __ARGS((int c, void *cookie, int indent));
+static int apply_autocmds_group __ARGS((event_T event, char_u *fname, char_u *fname_io, int force, int group, buf_T *buf, exarg_T *eap));
+static void auto_next_pat __ARGS((AutoPatCmd *apc, int stop_at_last));
+
+
+static event_T	last_event;
+static int	last_group;
+
+/*
+ * Show the autocommands for one AutoPat.
+ */
+    static void
+show_autocmd(ap, event)
+    AutoPat	*ap;
+    event_T	event;
+{
+    AutoCmd *ac;
+
+    /* Check for "got_int" (here and at various places below), which is set
+     * when "q" has been hit for the "--more--" prompt */
+    if (got_int)
+	return;
+    if (ap->pat == NULL)		/* pattern has been removed */
+	return;
+
+    msg_putchar('\n');
+    if (got_int)
+	return;
+    if (event != last_event || ap->group != last_group)
+    {
+	if (ap->group != AUGROUP_DEFAULT)
+	{
+	    if (AUGROUP_NAME(ap->group) == NULL)
+		msg_puts_attr((char_u *)_("--Deleted--"), hl_attr(HLF_E));
+	    else
+		msg_puts_attr(AUGROUP_NAME(ap->group), hl_attr(HLF_T));
+	    msg_puts((char_u *)"  ");
+	}
+	msg_puts_attr(event_nr2name(event), hl_attr(HLF_T));
+	last_event = event;
+	last_group = ap->group;
+	msg_putchar('\n');
+	if (got_int)
+	    return;
+    }
+    msg_col = 4;
+    msg_outtrans(ap->pat);
+
+    for (ac = ap->cmds; ac != NULL; ac = ac->next)
+    {
+	if (ac->cmd != NULL)		/* skip removed commands */
+	{
+	    if (msg_col >= 14)
+		msg_putchar('\n');
+	    msg_col = 14;
+	    if (got_int)
+		return;
+	    msg_outtrans(ac->cmd);
+#ifdef FEAT_EVAL
+	    if (p_verbose > 0)
+		last_set_msg(ac->scriptID);
+#endif
+	    if (got_int)
+		return;
+	    if (ac->next != NULL)
+	    {
+		msg_putchar('\n');
+		if (got_int)
+		    return;
+	    }
+	}
+    }
+}
+
+/*
+ * Mark an autocommand pattern for deletion.
+ */
+    static void
+au_remove_pat(ap)
+    AutoPat *ap;
+{
+    vim_free(ap->pat);
+    ap->pat = NULL;
+    ap->buflocal_nr = -1;
+    au_need_clean = TRUE;
+}
+
+/*
+ * Mark all commands for a pattern for deletion.
+ */
+    static void
+au_remove_cmds(ap)
+    AutoPat *ap;
+{
+    AutoCmd *ac;
+
+    for (ac = ap->cmds; ac != NULL; ac = ac->next)
+    {
+	vim_free(ac->cmd);
+	ac->cmd = NULL;
+    }
+    au_need_clean = TRUE;
+}
+
+/*
+ * Cleanup autocommands and patterns that have been deleted.
+ * This is only done when not executing autocommands.
+ */
+    static void
+au_cleanup()
+{
+    AutoPat	*ap, **prev_ap;
+    AutoCmd	*ac, **prev_ac;
+    event_T	event;
+
+    if (autocmd_busy || !au_need_clean)
+	return;
+
+    /* loop over all events */
+    for (event = (event_T)0; (int)event < (int)NUM_EVENTS;
+					    event = (event_T)((int)event + 1))
+    {
+	/* loop over all autocommand patterns */
+	prev_ap = &(first_autopat[(int)event]);
+	for (ap = *prev_ap; ap != NULL; ap = *prev_ap)
+	{
+	    /* loop over all commands for this pattern */
+	    prev_ac = &(ap->cmds);
+	    for (ac = *prev_ac; ac != NULL; ac = *prev_ac)
+	    {
+		/* remove the command if the pattern is to be deleted or when
+		 * the command has been marked for deletion */
+		if (ap->pat == NULL || ac->cmd == NULL)
+		{
+		    *prev_ac = ac->next;
+		    vim_free(ac->cmd);
+		    vim_free(ac);
+		}
+		else
+		    prev_ac = &(ac->next);
+	    }
+
+	    /* remove the pattern if it has been marked for deletion */
+	    if (ap->pat == NULL)
+	    {
+		*prev_ap = ap->next;
+		vim_free(ap->reg_prog);
+		vim_free(ap);
+	    }
+	    else
+		prev_ap = &(ap->next);
+	}
+    }
+
+    au_need_clean = FALSE;
+}
+
+/*
+ * Called when buffer is freed, to remove/invalidate related buffer-local
+ * autocmds.
+ */
+    void
+aubuflocal_remove(buf)
+    buf_T	*buf;
+{
+    AutoPat	*ap;
+    event_T	event;
+    AutoPatCmd	*apc;
+
+    /* invalidate currently executing autocommands */
+    for (apc = active_apc_list; apc; apc = apc->next)
+	if (buf->b_fnum == apc->arg_bufnr)
+	    apc->arg_bufnr = 0;
+
+    /* invalidate buflocals looping through events */
+    for (event = (event_T)0; (int)event < (int)NUM_EVENTS;
+					    event = (event_T)((int)event + 1))
+	/* loop over all autocommand patterns */
+	for (ap = first_autopat[(int)event]; ap != NULL; ap = ap->next)
+	    if (ap->buflocal_nr == buf->b_fnum)
+	    {
+		au_remove_pat(ap);
+		if (p_verbose >= 6)
+		{
+		    verbose_enter();
+		    smsg((char_u *)
+			    _("auto-removing autocommand: %s <buffer=%d>"),
+					   event_nr2name(event), buf->b_fnum);
+		    verbose_leave();
+		}
+	    }
+    au_cleanup();
+}
+
+/*
+ * Add an autocmd group name.
+ * Return it's ID.  Returns AUGROUP_ERROR (< 0) for error.
+ */
+    static int
+au_new_group(name)
+    char_u	*name;
+{
+    int		i;
+
+    i = au_find_group(name);
+    if (i == AUGROUP_ERROR)	/* the group doesn't exist yet, add it */
+    {
+	/* First try using a free entry. */
+	for (i = 0; i < augroups.ga_len; ++i)
+	    if (AUGROUP_NAME(i) == NULL)
+		break;
+	if (i == augroups.ga_len && ga_grow(&augroups, 1) == FAIL)
+	    return AUGROUP_ERROR;
+
+	AUGROUP_NAME(i) = vim_strsave(name);
+	if (AUGROUP_NAME(i) == NULL)
+	    return AUGROUP_ERROR;
+	if (i == augroups.ga_len)
+	    ++augroups.ga_len;
+    }
+
+    return i;
+}
+
+    static void
+au_del_group(name)
+    char_u	*name;
+{
+    int	    i;
+
+    i = au_find_group(name);
+    if (i == AUGROUP_ERROR)	/* the group doesn't exist */
+	EMSG2(_("E367: No such group: \"%s\""), name);
+    else
+    {
+	vim_free(AUGROUP_NAME(i));
+	AUGROUP_NAME(i) = NULL;
+    }
+}
+
+/*
+ * Find the ID of an autocmd group name.
+ * Return it's ID.  Returns AUGROUP_ERROR (< 0) for error.
+ */
+    static int
+au_find_group(name)
+    char_u	*name;
+{
+    int	    i;
+
+    for (i = 0; i < augroups.ga_len; ++i)
+	if (AUGROUP_NAME(i) != NULL && STRCMP(AUGROUP_NAME(i), name) == 0)
+	    return i;
+    return AUGROUP_ERROR;
+}
+
+/*
+ * Return TRUE if augroup "name" exists.
+ */
+    int
+au_has_group(name)
+    char_u	*name;
+{
+    return au_find_group(name) != AUGROUP_ERROR;
+}
+
+/*
+ * ":augroup {name}".
+ */
+    void
+do_augroup(arg, del_group)
+    char_u	*arg;
+    int		del_group;
+{
+    int	    i;
+
+    if (del_group)
+    {
+	if (*arg == NUL)
+	    EMSG(_(e_argreq));
+	else
+	    au_del_group(arg);
+    }
+    else if (STRICMP(arg, "end") == 0)   /* ":aug end": back to group 0 */
+	current_augroup = AUGROUP_DEFAULT;
+    else if (*arg)		    /* ":aug xxx": switch to group xxx */
+    {
+	i = au_new_group(arg);
+	if (i != AUGROUP_ERROR)
+	    current_augroup = i;
+    }
+    else			    /* ":aug": list the group names */
+    {
+	msg_start();
+	for (i = 0; i < augroups.ga_len; ++i)
+	{
+	    if (AUGROUP_NAME(i) != NULL)
+	    {
+		msg_puts(AUGROUP_NAME(i));
+		msg_puts((char_u *)"  ");
+	    }
+	}
+	msg_clr_eos();
+	msg_end();
+    }
+}
+
+#if defined(EXITFREE) || defined(PROTO)
+    void
+free_all_autocmds()
+{
+    for (current_augroup = -1; current_augroup < augroups.ga_len;
+							    ++current_augroup)
+	do_autocmd((char_u *)"", TRUE);
+    ga_clear_strings(&augroups);
+}
+#endif
+
+/*
+ * Return the event number for event name "start".
+ * Return NUM_EVENTS if the event name was not found.
+ * Return a pointer to the next event name in "end".
+ */
+    static event_T
+event_name2nr(start, end)
+    char_u  *start;
+    char_u  **end;
+{
+    char_u	*p;
+    int		i;
+    int		len;
+
+    /* the event name ends with end of line, a blank or a comma */
+    for (p = start; *p && !vim_iswhite(*p) && *p != ','; ++p)
+	;
+    for (i = 0; event_names[i].name != NULL; ++i)
+    {
+	len = (int)STRLEN(event_names[i].name);
+	if (len == p - start && STRNICMP(event_names[i].name, start, len) == 0)
+	    break;
+    }
+    if (*p == ',')
+	++p;
+    *end = p;
+    if (event_names[i].name == NULL)
+	return NUM_EVENTS;
+    return event_names[i].event;
+}
+
+/*
+ * Return the name for event "event".
+ */
+    static char_u *
+event_nr2name(event)
+    event_T	event;
+{
+    int	    i;
+
+    for (i = 0; event_names[i].name != NULL; ++i)
+	if (event_names[i].event == event)
+	    return (char_u *)event_names[i].name;
+    return (char_u *)"Unknown";
+}
+
+/*
+ * Scan over the events.  "*" stands for all events.
+ */
+    static char_u *
+find_end_event(arg, have_group)
+    char_u  *arg;
+    int	    have_group;	    /* TRUE when group name was found */
+{
+    char_u  *pat;
+    char_u  *p;
+
+    if (*arg == '*')
+    {
+	if (arg[1] && !vim_iswhite(arg[1]))
+	{
+	    EMSG2(_("E215: Illegal character after *: %s"), arg);
+	    return NULL;
+	}
+	pat = arg + 1;
+    }
+    else
+    {
+	for (pat = arg; *pat && !vim_iswhite(*pat); pat = p)
+	{
+	    if ((int)event_name2nr(pat, &p) >= (int)NUM_EVENTS)
+	    {
+		if (have_group)
+		    EMSG2(_("E216: No such event: %s"), pat);
+		else
+		    EMSG2(_("E216: No such group or event: %s"), pat);
+		return NULL;
+	    }
+	}
+    }
+    return pat;
+}
+
+/*
+ * Return TRUE if "event" is included in 'eventignore'.
+ */
+    static int
+event_ignored(event)
+    event_T	event;
+{
+    char_u	*p = p_ei;
+
+    while (*p != NUL)
+    {
+	if (STRNICMP(p, "all", 3) == 0 && (p[3] == NUL || p[3] == ','))
+	    return TRUE;
+	if (event_name2nr(p, &p) == event)
+	    return TRUE;
+    }
+
+    return FALSE;
+}
+
+/*
+ * Return OK when the contents of p_ei is valid, FAIL otherwise.
+ */
+    int
+check_ei()
+{
+    char_u	*p = p_ei;
+
+    while (*p)
+    {
+	if (STRNICMP(p, "all", 3) == 0 && (p[3] == NUL || p[3] == ','))
+	{
+	    p += 3;
+	    if (*p == ',')
+		++p;
+	}
+	else if (event_name2nr(p, &p) == NUM_EVENTS)
+	    return FAIL;
+    }
+
+    return OK;
+}
+
+# if defined(FEAT_SYN_HL) || defined(PROTO)
+
+/*
+ * Add "what" to 'eventignore' to skip loading syntax highlighting for every
+ * buffer loaded into the window.  "what" must start with a comma.
+ * Returns the old value of 'eventignore' in allocated memory.
+ */
+    char_u *
+au_event_disable(what)
+    char	*what;
+{
+    char_u	*new_ei;
+    char_u	*save_ei;
+
+    save_ei = vim_strsave(p_ei);
+    if (save_ei != NULL)
+    {
+	new_ei = vim_strnsave(p_ei, (int)(STRLEN(p_ei) + STRLEN(what)));
+	if (new_ei != NULL)
+	{
+	    STRCAT(new_ei, what);
+	    set_string_option_direct((char_u *)"ei", -1, new_ei,
+							  OPT_FREE, SID_NONE);
+	    vim_free(new_ei);
+	}
+    }
+    return save_ei;
+}
+
+    void
+au_event_restore(old_ei)
+    char_u	*old_ei;
+{
+    if (old_ei != NULL)
+    {
+	set_string_option_direct((char_u *)"ei", -1, old_ei,
+							  OPT_FREE, SID_NONE);
+	vim_free(old_ei);
+    }
+}
+# endif  /* FEAT_SYN_HL */
+
+/*
+ * do_autocmd() -- implements the :autocmd command.  Can be used in the
+ *  following ways:
+ *
+ * :autocmd <event> <pat> <cmd>	    Add <cmd> to the list of commands that
+ *				    will be automatically executed for <event>
+ *				    when editing a file matching <pat>, in
+ *				    the current group.
+ * :autocmd <event> <pat>	    Show the auto-commands associated with
+ *				    <event> and <pat>.
+ * :autocmd <event>		    Show the auto-commands associated with
+ *				    <event>.
+ * :autocmd			    Show all auto-commands.
+ * :autocmd! <event> <pat> <cmd>    Remove all auto-commands associated with
+ *				    <event> and <pat>, and add the command
+ *				    <cmd>, for the current group.
+ * :autocmd! <event> <pat>	    Remove all auto-commands associated with
+ *				    <event> and <pat> for the current group.
+ * :autocmd! <event>		    Remove all auto-commands associated with
+ *				    <event> for the current group.
+ * :autocmd!			    Remove ALL auto-commands for the current
+ *				    group.
+ *
+ *  Multiple events and patterns may be given separated by commas.  Here are
+ *  some examples:
+ * :autocmd bufread,bufenter *.c,*.h	set tw=0 smartindent noic
+ * :autocmd bufleave	     *		set tw=79 nosmartindent ic infercase
+ *
+ * :autocmd * *.c		show all autocommands for *.c files.
+ *
+ * Mostly a {group} argument can optionally appear before <event>.
+ */
+    void
+do_autocmd(arg, forceit)
+    char_u  *arg;
+    int	    forceit;
+{
+    char_u	*pat;
+    char_u	*envpat = NULL;
+    char_u	*cmd;
+    event_T	event;
+    int		need_free = FALSE;
+    int		nested = FALSE;
+    int		group;
+
+    /*
+     * Check for a legal group name.  If not, use AUGROUP_ALL.
+     */
+    group = au_get_grouparg(&arg);
+    if (arg == NULL)	    /* out of memory */
+	return;
+
+    /*
+     * Scan over the events.
+     * If we find an illegal name, return here, don't do anything.
+     */
+    pat = find_end_event(arg, group != AUGROUP_ALL);
+    if (pat == NULL)
+	return;
+
+    /*
+     * Scan over the pattern.  Put a NUL at the end.
+     */
+    pat = skipwhite(pat);
+    cmd = pat;
+    while (*cmd && (!vim_iswhite(*cmd) || cmd[-1] == '\\'))
+	cmd++;
+    if (*cmd)
+	*cmd++ = NUL;
+
+    /* Expand environment variables in the pattern.  Set 'shellslash', we want
+     * forward slashes here. */
+    if (vim_strchr(pat, '$') != NULL || vim_strchr(pat, '~') != NULL)
+    {
+#ifdef BACKSLASH_IN_FILENAME
+	int	p_ssl_save = p_ssl;
+
+	p_ssl = TRUE;
+#endif
+	envpat = expand_env_save(pat);
+#ifdef BACKSLASH_IN_FILENAME
+	p_ssl = p_ssl_save;
+#endif
+	if (envpat != NULL)
+	    pat = envpat;
+    }
+
+    /*
+     * Check for "nested" flag.
+     */
+    cmd = skipwhite(cmd);
+    if (*cmd != NUL && STRNCMP(cmd, "nested", 6) == 0 && vim_iswhite(cmd[6]))
+    {
+	nested = TRUE;
+	cmd = skipwhite(cmd + 6);
+    }
+
+    /*
+     * Find the start of the commands.
+     * Expand <sfile> in it.
+     */
+    if (*cmd != NUL)
+    {
+	cmd = expand_sfile(cmd);
+	if (cmd == NULL)	    /* some error */
+	    return;
+	need_free = TRUE;
+    }
+
+    /*
+     * Print header when showing autocommands.
+     */
+    if (!forceit && *cmd == NUL)
+    {
+	/* Highlight title */
+	MSG_PUTS_TITLE(_("\n--- Auto-Commands ---"));
+    }
+
+    /*
+     * Loop over the events.
+     */
+    last_event = (event_T)-1;		/* for listing the event name */
+    last_group = AUGROUP_ERROR;		/* for listing the group name */
+    if (*arg == '*' || *arg == NUL)
+    {
+	for (event = (event_T)0; (int)event < (int)NUM_EVENTS;
+					    event = (event_T)((int)event + 1))
+	    if (do_autocmd_event(event, pat,
+					 nested, cmd, forceit, group) == FAIL)
+		break;
+    }
+    else
+    {
+	while (*arg && !vim_iswhite(*arg))
+	    if (do_autocmd_event(event_name2nr(arg, &arg), pat,
+					nested,	cmd, forceit, group) == FAIL)
+		break;
+    }
+
+    if (need_free)
+	vim_free(cmd);
+    vim_free(envpat);
+}
+
+/*
+ * Find the group ID in a ":autocmd" or ":doautocmd" argument.
+ * The "argp" argument is advanced to the following argument.
+ *
+ * Returns the group ID, AUGROUP_ERROR for error (out of memory).
+ */
+    static int
+au_get_grouparg(argp)
+    char_u	**argp;
+{
+    char_u	*group_name;
+    char_u	*p;
+    char_u	*arg = *argp;
+    int		group = AUGROUP_ALL;
+
+    p = skiptowhite(arg);
+    if (p > arg)
+    {
+	group_name = vim_strnsave(arg, (int)(p - arg));
+	if (group_name == NULL)		/* out of memory */
+	    return AUGROUP_ERROR;
+	group = au_find_group(group_name);
+	if (group == AUGROUP_ERROR)
+	    group = AUGROUP_ALL;	/* no match, use all groups */
+	else
+	    *argp = skipwhite(p);	/* match, skip over group name */
+	vim_free(group_name);
+    }
+    return group;
+}
+
+/*
+ * do_autocmd() for one event.
+ * If *pat == NUL do for all patterns.
+ * If *cmd == NUL show entries.
+ * If forceit == TRUE delete entries.
+ * If group is not AUGROUP_ALL, only use this group.
+ */
+    static int
+do_autocmd_event(event, pat, nested, cmd, forceit, group)
+    event_T	event;
+    char_u	*pat;
+    int		nested;
+    char_u	*cmd;
+    int		forceit;
+    int		group;
+{
+    AutoPat	*ap;
+    AutoPat	**prev_ap;
+    AutoCmd	*ac;
+    AutoCmd	**prev_ac;
+    int		brace_level;
+    char_u	*endpat;
+    int		findgroup;
+    int		allgroups;
+    int		patlen;
+    int		is_buflocal;
+    int		buflocal_nr;
+    char_u	buflocal_pat[25];	/* for "<buffer=X>" */
+
+    if (group == AUGROUP_ALL)
+	findgroup = current_augroup;
+    else
+	findgroup = group;
+    allgroups = (group == AUGROUP_ALL && !forceit && *cmd == NUL);
+
+    /*
+     * Show or delete all patterns for an event.
+     */
+    if (*pat == NUL)
+    {
+	for (ap = first_autopat[(int)event]; ap != NULL; ap = ap->next)
+	{
+	    if (forceit)  /* delete the AutoPat, if it's in the current group */
+	    {
+		if (ap->group == findgroup)
+		    au_remove_pat(ap);
+	    }
+	    else if (group == AUGROUP_ALL || ap->group == group)
+		show_autocmd(ap, event);
+	}
+    }
+
+    /*
+     * Loop through all the specified patterns.
+     */
+    for ( ; *pat; pat = (*endpat == ',' ? endpat + 1 : endpat))
+    {
+	/*
+	 * Find end of the pattern.
+	 * Watch out for a comma in braces, like "*.\{obj,o\}".
+	 */
+	brace_level = 0;
+	for (endpat = pat; *endpat && (*endpat != ',' || brace_level
+					     || endpat[-1] == '\\'); ++endpat)
+	{
+	    if (*endpat == '{')
+		brace_level++;
+	    else if (*endpat == '}')
+		brace_level--;
+	}
+	if (pat == endpat)		/* ignore single comma */
+	    continue;
+	patlen = (int)(endpat - pat);
+
+	/*
+	 * detect special <buflocal[=X]> buffer-local patterns
+	 */
+	is_buflocal = FALSE;
+	buflocal_nr = 0;
+
+	if (patlen >= 7 && STRNCMP(pat, "<buffer", 7) == 0
+						    && pat[patlen - 1] == '>')
+	{
+	    /* Error will be printed only for addition. printing and removing
+	     * will proceed silently. */
+	    is_buflocal = TRUE;
+	    if (patlen == 8)
+		buflocal_nr = curbuf->b_fnum;
+	    else if (patlen > 9 && pat[7] == '=')
+	    {
+		/* <buffer=abuf> */
+		if (patlen == 13 && STRNICMP(pat, "<buffer=abuf>", 13))
+		    buflocal_nr = autocmd_bufnr;
+		/* <buffer=123> */
+		else if (skipdigits(pat + 8) == pat + patlen - 1)
+		    buflocal_nr = atoi((char *)pat + 8);
+	    }
+	}
+
+	if (is_buflocal)
+	{
+	    /* normalize pat into standard "<buffer>#N" form */
+	    sprintf((char *)buflocal_pat, "<buffer=%d>", buflocal_nr);
+	    pat = buflocal_pat;			/* can modify pat and patlen */
+	    patlen = (int)STRLEN(buflocal_pat);	/*   but not endpat */
+	}
+
+	/*
+	 * Find AutoPat entries with this pattern.
+	 */
+	prev_ap = &first_autopat[(int)event];
+	while ((ap = *prev_ap) != NULL)
+	{
+	    if (ap->pat != NULL)
+	    {
+		/* Accept a pattern when:
+		 * - a group was specified and it's that group, or a group was
+		 *   not specified and it's the current group, or a group was
+		 *   not specified and we are listing
+		 * - the length of the pattern matches
+		 * - the pattern matches.
+		 * For <buffer[=X]>, this condition works because we normalize
+		 * all buffer-local patterns.
+		 */
+		if ((allgroups || ap->group == findgroup)
+			&& ap->patlen == patlen
+			&& STRNCMP(pat, ap->pat, patlen) == 0)
+		{
+		    /*
+		     * Remove existing autocommands.
+		     * If adding any new autocmd's for this AutoPat, don't
+		     * delete the pattern from the autopat list, append to
+		     * this list.
+		     */
+		    if (forceit)
+		    {
+			if (*cmd != NUL && ap->next == NULL)
+			{
+			    au_remove_cmds(ap);
+			    break;
+			}
+			au_remove_pat(ap);
+		    }
+
+		    /*
+		     * Show autocmd's for this autopat, or buflocals <buffer=X>
+		     */
+		    else if (*cmd == NUL)
+			show_autocmd(ap, event);
+
+		    /*
+		     * Add autocmd to this autopat, if it's the last one.
+		     */
+		    else if (ap->next == NULL)
+			break;
+		}
+	    }
+	    prev_ap = &ap->next;
+	}
+
+	/*
+	 * Add a new command.
+	 */
+	if (*cmd != NUL)
+	{
+	    /*
+	     * If the pattern we want to add a command to does appear at the
+	     * end of the list (or not is not in the list at all), add the
+	     * pattern at the end of the list.
+	     */
+	    if (ap == NULL)
+	    {
+		/* refuse to add buffer-local ap if buffer number is invalid */
+		if (is_buflocal && (buflocal_nr == 0
+				      || buflist_findnr(buflocal_nr) == NULL))
+		{
+		    EMSGN(_("E680: <buffer=%d>: invalid buffer number "),
+								 buflocal_nr);
+		    return FAIL;
+		}
+
+		ap = (AutoPat *)alloc((unsigned)sizeof(AutoPat));
+		if (ap == NULL)
+		    return FAIL;
+		ap->pat = vim_strnsave(pat, patlen);
+		ap->patlen = patlen;
+		if (ap->pat == NULL)
+		{
+		    vim_free(ap);
+		    return FAIL;
+		}
+
+		if (is_buflocal)
+		{
+		    ap->buflocal_nr = buflocal_nr;
+		    ap->reg_prog = NULL;
+		}
+		else
+		{
+		    char_u	*reg_pat;
+
+		    ap->buflocal_nr = 0;
+		    reg_pat = file_pat_to_reg_pat(pat, endpat,
+							 &ap->allow_dirs, TRUE);
+		    if (reg_pat != NULL)
+			ap->reg_prog = vim_regcomp(reg_pat, RE_MAGIC);
+		    vim_free(reg_pat);
+		    if (reg_pat == NULL || ap->reg_prog == NULL)
+		    {
+			vim_free(ap->pat);
+			vim_free(ap);
+			return FAIL;
+		    }
+		}
+		ap->cmds = NULL;
+		*prev_ap = ap;
+		ap->next = NULL;
+		if (group == AUGROUP_ALL)
+		    ap->group = current_augroup;
+		else
+		    ap->group = group;
+	    }
+
+	    /*
+	     * Add the autocmd at the end of the AutoCmd list.
+	     */
+	    prev_ac = &(ap->cmds);
+	    while ((ac = *prev_ac) != NULL)
+		prev_ac = &ac->next;
+	    ac = (AutoCmd *)alloc((unsigned)sizeof(AutoCmd));
+	    if (ac == NULL)
+		return FAIL;
+	    ac->cmd = vim_strsave(cmd);
+#ifdef FEAT_EVAL
+	    ac->scriptID = current_SID;
+#endif
+	    if (ac->cmd == NULL)
+	    {
+		vim_free(ac);
+		return FAIL;
+	    }
+	    ac->next = NULL;
+	    *prev_ac = ac;
+	    ac->nested = nested;
+	}
+    }
+
+    au_cleanup();	/* may really delete removed patterns/commands now */
+    return OK;
+}
+
+/*
+ * Implementation of ":doautocmd [group] event [fname]".
+ * Return OK for success, FAIL for failure;
+ */
+    int
+do_doautocmd(arg, do_msg)
+    char_u	*arg;
+    int		do_msg;	    /* give message for no matching autocmds? */
+{
+    char_u	*fname;
+    int		nothing_done = TRUE;
+    int		group;
+
+    /*
+     * Check for a legal group name.  If not, use AUGROUP_ALL.
+     */
+    group = au_get_grouparg(&arg);
+    if (arg == NULL)	    /* out of memory */
+	return FAIL;
+
+    if (*arg == '*')
+    {
+	EMSG(_("E217: Can't execute autocommands for ALL events"));
+	return FAIL;
+    }
+
+    /*
+     * Scan over the events.
+     * If we find an illegal name, return here, don't do anything.
+     */
+    fname = find_end_event(arg, group != AUGROUP_ALL);
+    if (fname == NULL)
+	return FAIL;
+
+    fname = skipwhite(fname);
+
+    /*
+     * Loop over the events.
+     */
+    while (*arg && !vim_iswhite(*arg))
+	if (apply_autocmds_group(event_name2nr(arg, &arg),
+				      fname, NULL, TRUE, group, curbuf, NULL))
+	    nothing_done = FALSE;
+
+    if (nothing_done && do_msg)
+	MSG(_("No matching autocommands"));
+
+#ifdef FEAT_EVAL
+    return aborting() ? FAIL : OK;
+#else
+    return OK;
+#endif
+}
+
+/*
+ * ":doautoall": execute autocommands for each loaded buffer.
+ */
+    void
+ex_doautoall(eap)
+    exarg_T	*eap;
+{
+    int		retval;
+    aco_save_T	aco;
+    buf_T	*buf;
+
+    /*
+     * This is a bit tricky: For some commands curwin->w_buffer needs to be
+     * equal to curbuf, but for some buffers there may not be a window.
+     * So we change the buffer for the current window for a moment.  This
+     * gives problems when the autocommands make changes to the list of
+     * buffers or windows...
+     */
+    for (buf = firstbuf; buf != NULL; buf = buf->b_next)
+    {
+	if (curbuf->b_ml.ml_mfp != NULL)
+	{
+	    /* find a window for this buffer and save some values */
+	    aucmd_prepbuf(&aco, buf);
+
+	    /* execute the autocommands for this buffer */
+	    retval = do_doautocmd(eap->arg, FALSE);
+
+	    /* Execute the modeline settings, but don't set window-local
+	     * options if we are using the current window for another buffer. */
+	    do_modelines(aco.save_curwin == NULL ? OPT_NOWIN : 0);
+
+	    /* restore the current window */
+	    aucmd_restbuf(&aco);
+
+	    /* stop if there is some error or buffer was deleted */
+	    if (retval == FAIL || !buf_valid(buf))
+		break;
+	}
+    }
+
+    check_cursor();	    /* just in case lines got deleted */
+}
+
+/*
+ * Prepare for executing autocommands for (hidden) buffer "buf".
+ * Search a window for the current buffer.  Save the cursor position and
+ * screen offset.
+ * Set "curbuf" and "curwin" to match "buf".
+ * When FEAT_AUTOCMD is not defined another version is used, see below.
+ */
+    void
+aucmd_prepbuf(aco, buf)
+    aco_save_T	*aco;		/* structure to save values in */
+    buf_T	*buf;		/* new curbuf */
+{
+    win_T	*win;
+
+    aco->new_curbuf = buf;
+
+    /* Find a window that is for the new buffer */
+    if (buf == curbuf)		/* be quick when buf is curbuf */
+	win = curwin;
+    else
+#ifdef FEAT_WINDOWS
+	for (win = firstwin; win != NULL; win = win->w_next)
+	    if (win->w_buffer == buf)
+		break;
+#else
+	win = NULL;
+#endif
+
+    /*
+     * Prefer to use an existing window for the buffer, it has the least side
+     * effects (esp. if "buf" is curbuf).
+     * Otherwise, use curwin for "buf".  It might make some items in the
+     * window invalid.  At least save the cursor and topline.
+     */
+    if (win != NULL)
+    {
+	/* there is a window for "buf", make it the curwin */
+	aco->save_curwin = curwin;
+	curwin = win;
+	aco->save_buf = win->w_buffer;
+	aco->new_curwin = win;
+    }
+    else
+    {
+	/* there is no window for "buf", use curwin */
+	aco->save_curwin = NULL;
+	aco->save_buf = curbuf;
+	--curbuf->b_nwindows;
+	curwin->w_buffer = buf;
+	++buf->b_nwindows;
+
+	/* save cursor and topline, set them to safe values */
+	aco->save_cursor = curwin->w_cursor;
+	curwin->w_cursor.lnum = 1;
+	curwin->w_cursor.col = 0;
+	aco->save_topline = curwin->w_topline;
+	curwin->w_topline = 1;
+#ifdef FEAT_DIFF
+	aco->save_topfill = curwin->w_topfill;
+	curwin->w_topfill = 0;
+#endif
+    }
+
+    curbuf = buf;
+}
+
+/*
+ * Cleanup after executing autocommands for a (hidden) buffer.
+ * Restore the window as it was (if possible).
+ * When FEAT_AUTOCMD is not defined another version is used, see below.
+ */
+    void
+aucmd_restbuf(aco)
+    aco_save_T	*aco;		/* structure holding saved values */
+{
+    if (aco->save_curwin != NULL)
+    {
+	/* restore curwin */
+#ifdef FEAT_WINDOWS
+	if (win_valid(aco->save_curwin))
+#endif
+	{
+	    /* restore the buffer which was previously edited by curwin, if
+	     * it's still the same window and it's valid */
+	    if (curwin == aco->new_curwin
+		    && buf_valid(aco->save_buf)
+		    && aco->save_buf->b_ml.ml_mfp != NULL)
+	    {
+		--curbuf->b_nwindows;
+		curbuf = aco->save_buf;
+		curwin->w_buffer = curbuf;
+		++curbuf->b_nwindows;
+	    }
+
+	    curwin = aco->save_curwin;
+	    curbuf = curwin->w_buffer;
+	}
+    }
+    else
+    {
+	/* restore buffer for curwin if it still exists and is loaded */
+	if (buf_valid(aco->save_buf) && aco->save_buf->b_ml.ml_mfp != NULL)
+	{
+	    --curbuf->b_nwindows;
+	    curbuf = aco->save_buf;
+	    curwin->w_buffer = curbuf;
+	    ++curbuf->b_nwindows;
+	    curwin->w_cursor = aco->save_cursor;
+	    check_cursor();
+	    /* check topline < line_count, in case lines got deleted */
+	    if (aco->save_topline <= curbuf->b_ml.ml_line_count)
+	    {
+		curwin->w_topline = aco->save_topline;
+#ifdef FEAT_DIFF
+		curwin->w_topfill = aco->save_topfill;
+#endif
+	    }
+	    else
+	    {
+		curwin->w_topline = curbuf->b_ml.ml_line_count;
+#ifdef FEAT_DIFF
+		curwin->w_topfill = 0;
+#endif
+	    }
+	}
+    }
+}
+
+static int	autocmd_nested = FALSE;
+
+/*
+ * Execute autocommands for "event" and file name "fname".
+ * Return TRUE if some commands were executed.
+ */
+    int
+apply_autocmds(event, fname, fname_io, force, buf)
+    event_T	event;
+    char_u	*fname;	    /* NULL or empty means use actual file name */
+    char_u	*fname_io;  /* fname to use for <afile> on cmdline */
+    int		force;	    /* when TRUE, ignore autocmd_busy */
+    buf_T	*buf;	    /* buffer for <abuf> */
+{
+    return apply_autocmds_group(event, fname, fname_io, force,
+						      AUGROUP_ALL, buf, NULL);
+}
+
+/*
+ * Like apply_autocmds(), but with extra "eap" argument.  This takes care of
+ * setting v:filearg.
+ */
+    static int
+apply_autocmds_exarg(event, fname, fname_io, force, buf, eap)
+    event_T	event;
+    char_u	*fname;
+    char_u	*fname_io;
+    int		force;
+    buf_T	*buf;
+    exarg_T	*eap;
+{
+    return apply_autocmds_group(event, fname, fname_io, force,
+						       AUGROUP_ALL, buf, eap);
+}
+
+/*
+ * Like apply_autocmds(), but handles the caller's retval.  If the script
+ * processing is being aborted or if retval is FAIL when inside a try
+ * conditional, no autocommands are executed.  If otherwise the autocommands
+ * cause the script to be aborted, retval is set to FAIL.
+ */
+    int
+apply_autocmds_retval(event, fname, fname_io, force, buf, retval)
+    event_T	event;
+    char_u	*fname;	    /* NULL or empty means use actual file name */
+    char_u	*fname_io;  /* fname to use for <afile> on cmdline */
+    int		force;	    /* when TRUE, ignore autocmd_busy */
+    buf_T	*buf;	    /* buffer for <abuf> */
+    int		*retval;    /* pointer to caller's retval */
+{
+    int		did_cmd;
+
+#ifdef FEAT_EVAL
+    if (should_abort(*retval))
+	return FALSE;
+#endif
+
+    did_cmd = apply_autocmds_group(event, fname, fname_io, force,
+						      AUGROUP_ALL, buf, NULL);
+    if (did_cmd
+#ifdef FEAT_EVAL
+	    && aborting()
+#endif
+	    )
+	*retval = FAIL;
+    return did_cmd;
+}
+
+/*
+ * Return TRUE when there is a CursorHold autocommand defined.
+ */
+    int
+has_cursorhold()
+{
+    return (first_autopat[(int)(get_real_state() == NORMAL_BUSY
+			    ? EVENT_CURSORHOLD : EVENT_CURSORHOLDI)] != NULL);
+}
+
+/*
+ * Return TRUE if the CursorHold event can be triggered.
+ */
+    int
+trigger_cursorhold()
+{
+    int		state;
+
+    if (!did_cursorhold && has_cursorhold() && !Recording
+#ifdef FEAT_INS_EXPAND
+	    && !ins_compl_active()
+#endif
+	    )
+    {
+	state = get_real_state();
+	if (state == NORMAL_BUSY || (state & INSERT) != 0)
+	    return TRUE;
+    }
+    return FALSE;
+}
+
+/*
+ * Return TRUE when there is a CursorMoved autocommand defined.
+ */
+    int
+has_cursormoved()
+{
+    return (first_autopat[(int)EVENT_CURSORMOVED] != NULL);
+}
+
+/*
+ * Return TRUE when there is a CursorMovedI autocommand defined.
+ */
+    int
+has_cursormovedI()
+{
+    return (first_autopat[(int)EVENT_CURSORMOVEDI] != NULL);
+}
+
+    static int
+apply_autocmds_group(event, fname, fname_io, force, group, buf, eap)
+    event_T	event;
+    char_u	*fname;	    /* NULL or empty means use actual file name */
+    char_u	*fname_io;  /* fname to use for <afile> on cmdline, NULL means
+			       use fname */
+    int		force;	    /* when TRUE, ignore autocmd_busy */
+    int		group;	    /* group ID, or AUGROUP_ALL */
+    buf_T	*buf;	    /* buffer for <abuf> */
+    exarg_T	*eap;	    /* command arguments */
+{
+    char_u	*sfname = NULL;	/* short file name */
+    char_u	*tail;
+    int		save_changed;
+    buf_T	*old_curbuf;
+    int		retval = FALSE;
+    char_u	*save_sourcing_name;
+    linenr_T	save_sourcing_lnum;
+    char_u	*save_autocmd_fname;
+    int		save_autocmd_bufnr;
+    char_u	*save_autocmd_match;
+    int		save_autocmd_busy;
+    int		save_autocmd_nested;
+    static int	nesting = 0;
+    AutoPatCmd	patcmd;
+    AutoPat	*ap;
+#ifdef FEAT_EVAL
+    scid_T	save_current_SID;
+    void	*save_funccalp;
+    char_u	*save_cmdarg;
+    long	save_cmdbang;
+#endif
+    static int	filechangeshell_busy = FALSE;
+#ifdef FEAT_PROFILE
+    proftime_T	wait_time;
+#endif
+
+    /*
+     * Quickly return if there are no autocommands for this event or
+     * autocommands are blocked.
+     */
+    if (first_autopat[(int)event] == NULL || autocmd_block > 0)
+	goto BYPASS_AU;
+
+    /*
+     * When autocommands are busy, new autocommands are only executed when
+     * explicitly enabled with the "nested" flag.
+     */
+    if (autocmd_busy && !(force || autocmd_nested))
+	goto BYPASS_AU;
+
+#ifdef FEAT_EVAL
+    /*
+     * Quickly return when immediately aborting on error, or when an interrupt
+     * occurred or an exception was thrown but not caught.
+     */
+    if (aborting())
+	goto BYPASS_AU;
+#endif
+
+    /*
+     * FileChangedShell never nests, because it can create an endless loop.
+     */
+    if (filechangeshell_busy && (event == EVENT_FILECHANGEDSHELL
+				      || event == EVENT_FILECHANGEDSHELLPOST))
+	goto BYPASS_AU;
+
+    /*
+     * Ignore events in 'eventignore'.
+     */
+    if (event_ignored(event))
+	goto BYPASS_AU;
+
+    /*
+     * Allow nesting of autocommands, but restrict the depth, because it's
+     * possible to create an endless loop.
+     */
+    if (nesting == 10)
+    {
+	EMSG(_("E218: autocommand nesting too deep"));
+	goto BYPASS_AU;
+    }
+
+    /*
+     * Check if these autocommands are disabled.  Used when doing ":all" or
+     * ":ball".
+     */
+    if (       (autocmd_no_enter
+		&& (event == EVENT_WINENTER || event == EVENT_BUFENTER))
+	    || (autocmd_no_leave
+		&& (event == EVENT_WINLEAVE || event == EVENT_BUFLEAVE)))
+	goto BYPASS_AU;
+
+    /*
+     * Save the autocmd_* variables and info about the current buffer.
+     */
+    save_autocmd_fname = autocmd_fname;
+    save_autocmd_bufnr = autocmd_bufnr;
+    save_autocmd_match = autocmd_match;
+    save_autocmd_busy = autocmd_busy;
+    save_autocmd_nested = autocmd_nested;
+    save_changed = curbuf->b_changed;
+    old_curbuf = curbuf;
+
+    /*
+     * Set the file name to be used for <afile>.
+     */
+    if (fname_io == NULL)
+    {
+	if (fname != NULL && *fname != NUL)
+	    autocmd_fname = fname;
+	else if (buf != NULL)
+	    autocmd_fname = buf->b_fname;
+	else
+	    autocmd_fname = NULL;
+    }
+    else
+	autocmd_fname = fname_io;
+
+    /*
+     * Set the buffer number to be used for <abuf>.
+     */
+    if (buf == NULL)
+	autocmd_bufnr = 0;
+    else
+	autocmd_bufnr = buf->b_fnum;
+
+    /*
+     * When the file name is NULL or empty, use the file name of buffer "buf".
+     * Always use the full path of the file name to match with, in case
+     * "allow_dirs" is set.
+     */
+    if (fname == NULL || *fname == NUL)
+    {
+	if (buf == NULL)
+	    fname = NULL;
+	else
+	{
+#ifdef FEAT_SYN_HL
+	    if (event == EVENT_SYNTAX)
+		fname = buf->b_p_syn;
+	    else
+#endif
+		if (event == EVENT_FILETYPE)
+		    fname = buf->b_p_ft;
+		else
+		{
+		    if (buf->b_sfname != NULL)
+			sfname = vim_strsave(buf->b_sfname);
+		    fname = buf->b_ffname;
+		}
+	}
+	if (fname == NULL)
+	    fname = (char_u *)"";
+	fname = vim_strsave(fname);	/* make a copy, so we can change it */
+    }
+    else
+    {
+	sfname = vim_strsave(fname);
+	/* Don't try expanding FileType, Syntax, WindowID or QuickFixCmd* */
+	if (event == EVENT_FILETYPE
+		|| event == EVENT_SYNTAX
+		|| event == EVENT_REMOTEREPLY
+		|| event == EVENT_SPELLFILEMISSING
+		|| event == EVENT_QUICKFIXCMDPRE
+		|| event == EVENT_QUICKFIXCMDPOST)
+	    fname = vim_strsave(fname);
+	else
+	    fname = FullName_save(fname, FALSE);
+    }
+    if (fname == NULL)	    /* out of memory */
+    {
+	vim_free(sfname);
+	retval = FALSE;
+	goto BYPASS_AU;
+    }
+
+#ifdef BACKSLASH_IN_FILENAME
+    /*
+     * Replace all backslashes with forward slashes.  This makes the
+     * autocommand patterns portable between Unix and MS-DOS.
+     */
+    if (sfname != NULL)
+	forward_slash(sfname);
+    forward_slash(fname);
+#endif
+
+#ifdef VMS
+    /* remove version for correct match */
+    if (sfname != NULL)
+	vms_remove_version(sfname);
+    vms_remove_version(fname);
+#endif
+
+    /*
+     * Set the name to be used for <amatch>.
+     */
+    autocmd_match = fname;
+
+
+    /* Don't redraw while doing auto commands. */
+    ++RedrawingDisabled;
+    save_sourcing_name = sourcing_name;
+    sourcing_name = NULL;	/* don't free this one */
+    save_sourcing_lnum = sourcing_lnum;
+    sourcing_lnum = 0;		/* no line number here */
+
+#ifdef FEAT_EVAL
+    save_current_SID = current_SID;
+
+# ifdef FEAT_PROFILE
+    if (do_profiling == PROF_YES)
+	prof_child_enter(&wait_time); /* doesn't count for the caller itself */
+# endif
+
+    /* Don't use local function variables, if called from a function */
+    save_funccalp = save_funccal();
+#endif
+
+    /*
+     * When starting to execute autocommands, save the search patterns.
+     */
+    if (!autocmd_busy)
+    {
+	save_search_patterns();
+	saveRedobuff();
+	did_filetype = keep_filetype;
+    }
+
+    /*
+     * Note that we are applying autocmds.  Some commands need to know.
+     */
+    autocmd_busy = TRUE;
+    filechangeshell_busy = (event == EVENT_FILECHANGEDSHELL);
+    ++nesting;		/* see matching decrement below */
+
+    /* Remember that FileType was triggered.  Used for did_filetype(). */
+    if (event == EVENT_FILETYPE)
+	did_filetype = TRUE;
+
+    tail = gettail(fname);
+
+    /* Find first autocommand that matches */
+    patcmd.curpat = first_autopat[(int)event];
+    patcmd.nextcmd = NULL;
+    patcmd.group = group;
+    patcmd.fname = fname;
+    patcmd.sfname = sfname;
+    patcmd.tail = tail;
+    patcmd.event = event;
+    patcmd.arg_bufnr = autocmd_bufnr;
+    patcmd.next = NULL;
+    auto_next_pat(&patcmd, FALSE);
+
+    /* found one, start executing the autocommands */
+    if (patcmd.curpat != NULL)
+    {
+	/* add to active_apc_list */
+	patcmd.next = active_apc_list;
+	active_apc_list = &patcmd;
+
+#ifdef FEAT_EVAL
+	/* set v:cmdarg (only when there is a matching pattern) */
+	save_cmdbang = get_vim_var_nr(VV_CMDBANG);
+	if (eap != NULL)
+	{
+	    save_cmdarg = set_cmdarg(eap, NULL);
+	    set_vim_var_nr(VV_CMDBANG, (long)eap->forceit);
+	}
+	else
+	    save_cmdarg = NULL;	/* avoid gcc warning */
+#endif
+	retval = TRUE;
+	/* mark the last pattern, to avoid an endless loop when more patterns
+	 * are added when executing autocommands */
+	for (ap = patcmd.curpat; ap->next != NULL; ap = ap->next)
+	    ap->last = FALSE;
+	ap->last = TRUE;
+	check_lnums(TRUE);	/* make sure cursor and topline are valid */
+	do_cmdline(NULL, getnextac, (void *)&patcmd,
+				     DOCMD_NOWAIT|DOCMD_VERBOSE|DOCMD_REPEAT);
+#ifdef FEAT_EVAL
+	if (eap != NULL)
+	{
+	    (void)set_cmdarg(NULL, save_cmdarg);
+	    set_vim_var_nr(VV_CMDBANG, save_cmdbang);
+	}
+#endif
+	/* delete from active_apc_list */
+	if (active_apc_list == &patcmd)	    /* just in case */
+	    active_apc_list = patcmd.next;
+    }
+
+    --RedrawingDisabled;
+    autocmd_busy = save_autocmd_busy;
+    filechangeshell_busy = FALSE;
+    autocmd_nested = save_autocmd_nested;
+    vim_free(sourcing_name);
+    sourcing_name = save_sourcing_name;
+    sourcing_lnum = save_sourcing_lnum;
+    autocmd_fname = save_autocmd_fname;
+    autocmd_bufnr = save_autocmd_bufnr;
+    autocmd_match = save_autocmd_match;
+#ifdef FEAT_EVAL
+    current_SID = save_current_SID;
+    restore_funccal(save_funccalp);
+# ifdef FEAT_PROFILE
+    if (do_profiling == PROF_YES)
+	prof_child_exit(&wait_time);
+# endif
+#endif
+    vim_free(fname);
+    vim_free(sfname);
+    --nesting;		/* see matching increment above */
+
+    /*
+     * When stopping to execute autocommands, restore the search patterns and
+     * the redo buffer.
+     */
+    if (!autocmd_busy)
+    {
+	restore_search_patterns();
+	restoreRedobuff();
+	did_filetype = FALSE;
+    }
+
+    /*
+     * Some events don't set or reset the Changed flag.
+     * Check if still in the same buffer!
+     */
+    if (curbuf == old_curbuf
+	    && (event == EVENT_BUFREADPOST
+		|| event == EVENT_BUFWRITEPOST
+		|| event == EVENT_FILEAPPENDPOST
+		|| event == EVENT_VIMLEAVE
+		|| event == EVENT_VIMLEAVEPRE))
+    {
+#ifdef FEAT_TITLE
+	if (curbuf->b_changed != save_changed)
+	    need_maketitle = TRUE;
+#endif
+	curbuf->b_changed = save_changed;
+    }
+
+    au_cleanup();	/* may really delete removed patterns/commands now */
+
+BYPASS_AU:
+    /* When wiping out a buffer make sure all its buffer-local autocommands
+     * are deleted. */
+    if (event == EVENT_BUFWIPEOUT && buf != NULL)
+	aubuflocal_remove(buf);
+
+    return retval;
+}
+
+/*
+ * Find next autocommand pattern that matches.
+ */
+    static void
+auto_next_pat(apc, stop_at_last)
+    AutoPatCmd	*apc;
+    int		stop_at_last;	    /* stop when 'last' flag is set */
+{
+    AutoPat	*ap;
+    AutoCmd	*cp;
+    char_u	*name;
+    char	*s;
+
+    vim_free(sourcing_name);
+    sourcing_name = NULL;
+
+    for (ap = apc->curpat; ap != NULL && !got_int; ap = ap->next)
+    {
+	apc->curpat = NULL;
+
+	/* only use a pattern when it has not been removed, has commands and
+	 * the group matches. For buffer-local autocommands only check the
+	 * buffer number. */
+	if (ap->pat != NULL && ap->cmds != NULL
+		&& (apc->group == AUGROUP_ALL || apc->group == ap->group))
+	{
+	    /* execution-condition */
+	    if (ap->buflocal_nr == 0
+		    ? (match_file_pat(NULL, ap->reg_prog, apc->fname,
+				      apc->sfname, apc->tail, ap->allow_dirs))
+		    : ap->buflocal_nr == apc->arg_bufnr)
+	    {
+		name = event_nr2name(apc->event);
+		s = _("%s Auto commands for \"%s\"");
+		sourcing_name = alloc((unsigned)(STRLEN(s)
+					    + STRLEN(name) + ap->patlen + 1));
+		if (sourcing_name != NULL)
+		{
+		    sprintf((char *)sourcing_name, s,
+					       (char *)name, (char *)ap->pat);
+		    if (p_verbose >= 8)
+		    {
+			verbose_enter();
+			smsg((char_u *)_("Executing %s"), sourcing_name);
+			verbose_leave();
+		    }
+		}
+
+		apc->curpat = ap;
+		apc->nextcmd = ap->cmds;
+		/* mark last command */
+		for (cp = ap->cmds; cp->next != NULL; cp = cp->next)
+		    cp->last = FALSE;
+		cp->last = TRUE;
+	    }
+	    line_breakcheck();
+	    if (apc->curpat != NULL)	    /* found a match */
+		break;
+	}
+	if (stop_at_last && ap->last)
+	    break;
+    }
+}
+
+/*
+ * Get next autocommand command.
+ * Called by do_cmdline() to get the next line for ":if".
+ * Returns allocated string, or NULL for end of autocommands.
+ */
+/* ARGSUSED */
+    static char_u *
+getnextac(c, cookie, indent)
+    int	    c;		    /* not used */
+    void    *cookie;
+    int	    indent;	    /* not used */
+{
+    AutoPatCmd	    *acp = (AutoPatCmd *)cookie;
+    char_u	    *retval;
+    AutoCmd	    *ac;
+
+    /* Can be called again after returning the last line. */
+    if (acp->curpat == NULL)
+	return NULL;
+
+    /* repeat until we find an autocommand to execute */
+    for (;;)
+    {
+	/* skip removed commands */
+	while (acp->nextcmd != NULL && acp->nextcmd->cmd == NULL)
+	    if (acp->nextcmd->last)
+		acp->nextcmd = NULL;
+	    else
+		acp->nextcmd = acp->nextcmd->next;
+
+	if (acp->nextcmd != NULL)
+	    break;
+
+	/* at end of commands, find next pattern that matches */
+	if (acp->curpat->last)
+	    acp->curpat = NULL;
+	else
+	    acp->curpat = acp->curpat->next;
+	if (acp->curpat != NULL)
+	    auto_next_pat(acp, TRUE);
+	if (acp->curpat == NULL)
+	    return NULL;
+    }
+
+    ac = acp->nextcmd;
+
+    if (p_verbose >= 9)
+    {
+	verbose_enter_scroll();
+	smsg((char_u *)_("autocommand %s"), ac->cmd);
+	msg_puts((char_u *)"\n");   /* don't overwrite this either */
+	verbose_leave_scroll();
+    }
+    retval = vim_strsave(ac->cmd);
+    autocmd_nested = ac->nested;
+#ifdef FEAT_EVAL
+    current_SID = ac->scriptID;
+#endif
+    if (ac->last)
+	acp->nextcmd = NULL;
+    else
+	acp->nextcmd = ac->next;
+    return retval;
+}
+
+/*
+ * Return TRUE if there is a matching autocommand for "fname".
+ * To account for buffer-local autocommands, function needs to know
+ * in which buffer the file will be opened.
+ */
+    int
+has_autocmd(event, sfname, buf)
+    event_T	event;
+    char_u	*sfname;
+    buf_T       *buf;
+{
+    AutoPat	*ap;
+    char_u	*fname;
+    char_u	*tail = gettail(sfname);
+    int		retval = FALSE;
+
+    fname = FullName_save(sfname, FALSE);
+    if (fname == NULL)
+	return FALSE;
+
+#ifdef BACKSLASH_IN_FILENAME
+    /*
+     * Replace all backslashes with forward slashes.  This makes the
+     * autocommand patterns portable between Unix and MS-DOS.
+     */
+    sfname = vim_strsave(sfname);
+    if (sfname != NULL)
+	forward_slash(sfname);
+    forward_slash(fname);
+#endif
+
+    for (ap = first_autopat[(int)event]; ap != NULL; ap = ap->next)
+	if (ap->pat != NULL && ap->cmds != NULL
+	      && (ap->buflocal_nr == 0
+		? match_file_pat(NULL, ap->reg_prog,
+					  fname, sfname, tail, ap->allow_dirs)
+		: buf != NULL && ap->buflocal_nr == buf->b_fnum
+	   ))
+	{
+	    retval = TRUE;
+	    break;
+	}
+
+    vim_free(fname);
+#ifdef BACKSLASH_IN_FILENAME
+    vim_free(sfname);
+#endif
+
+    return retval;
+}
+
+#if defined(FEAT_CMDL_COMPL) || defined(PROTO)
+/*
+ * Function given to ExpandGeneric() to obtain the list of autocommand group
+ * names.
+ */
+/*ARGSUSED*/
+    char_u *
+get_augroup_name(xp, idx)
+    expand_T	*xp;
+    int		idx;
+{
+    if (idx == augroups.ga_len)		/* add "END" add the end */
+	return (char_u *)"END";
+    if (idx >= augroups.ga_len)		/* end of list */
+	return NULL;
+    if (AUGROUP_NAME(idx) == NULL)	/* skip deleted entries */
+	return (char_u *)"";
+    return AUGROUP_NAME(idx);		/* return a name */
+}
+
+static int include_groups = FALSE;
+
+    char_u  *
+set_context_in_autocmd(xp, arg, doautocmd)
+    expand_T	*xp;
+    char_u	*arg;
+    int		doautocmd;	/* TRUE for :doautocmd, FALSE for :autocmd */
+{
+    char_u	*p;
+    int		group;
+
+    /* check for a group name, skip it if present */
+    include_groups = FALSE;
+    p = arg;
+    group = au_get_grouparg(&arg);
+    if (group == AUGROUP_ERROR)
+	return NULL;
+    /* If there only is a group name that's what we expand. */
+    if (*arg == NUL && group != AUGROUP_ALL && !vim_iswhite(arg[-1]))
+    {
+	arg = p;
+	group = AUGROUP_ALL;
+    }
+
+    /* skip over event name */
+    for (p = arg; *p != NUL && !vim_iswhite(*p); ++p)
+	if (*p == ',')
+	    arg = p + 1;
+    if (*p == NUL)
+    {
+	if (group == AUGROUP_ALL)
+	    include_groups = TRUE;
+	xp->xp_context = EXPAND_EVENTS;	    /* expand event name */
+	xp->xp_pattern = arg;
+	return NULL;
+    }
+
+    /* skip over pattern */
+    arg = skipwhite(p);
+    while (*arg && (!vim_iswhite(*arg) || arg[-1] == '\\'))
+	arg++;
+    if (*arg)
+	return arg;			    /* expand (next) command */
+
+    if (doautocmd)
+	xp->xp_context = EXPAND_FILES;	    /* expand file names */
+    else
+	xp->xp_context = EXPAND_NOTHING;    /* pattern is not expanded */
+    return NULL;
+}
+
+/*
+ * Function given to ExpandGeneric() to obtain the list of event names.
+ */
+/*ARGSUSED*/
+    char_u *
+get_event_name(xp, idx)
+    expand_T	*xp;
+    int		idx;
+{
+    if (idx < augroups.ga_len)		/* First list group names, if wanted */
+    {
+	if (!include_groups || AUGROUP_NAME(idx) == NULL)
+	    return (char_u *)"";	/* skip deleted entries */
+	return AUGROUP_NAME(idx);	/* return a name */
+    }
+    return (char_u *)event_names[idx - augroups.ga_len].name;
+}
+
+#endif	/* FEAT_CMDL_COMPL */
+
+/*
+ * Return TRUE if autocmd is supported.
+ */
+    int
+autocmd_supported(name)
+    char_u	*name;
+{
+    char_u *p;
+
+    return (event_name2nr(name, &p) != NUM_EVENTS);
+}
+
+/*
+ * Return TRUE if an autocommand is defined for a group, event and
+ * pattern:  The group can be omitted to accept any group. "event" and "pattern"
+ * can be NULL to accept any event and pattern. "pattern" can be NULL to accept
+ * any pattern. Buffer-local patterns <buffer> or <buffer=N> are accepted.
+ * Used for:
+ *	exists("#Group") or
+ *	exists("#Group#Event") or
+ *	exists("#Group#Event#pat") or
+ *	exists("#Event") or
+ *	exists("#Event#pat")
+ */
+    int
+au_exists(arg)
+    char_u	*arg;
+{
+    char_u	*arg_save;
+    char_u	*pattern = NULL;
+    char_u	*event_name;
+    char_u	*p;
+    event_T	event;
+    AutoPat	*ap;
+    buf_T	*buflocal_buf = NULL;
+    int		group;
+    int		retval = FALSE;
+
+    /* Make a copy so that we can change the '#' chars to a NUL. */
+    arg_save = vim_strsave(arg);
+    if (arg_save == NULL)
+	return FALSE;
+    p = vim_strchr(arg_save, '#');
+    if (p != NULL)
+	*p++ = NUL;
+
+    /* First, look for an autocmd group name */
+    group = au_find_group(arg_save);
+    if (group == AUGROUP_ERROR)
+    {
+	/* Didn't match a group name, assume the first argument is an event. */
+	group = AUGROUP_ALL;
+	event_name = arg_save;
+    }
+    else
+    {
+	if (p == NULL)
+	{
+	    /* "Group": group name is present and it's recognized */
+	    retval = TRUE;
+	    goto theend;
+	}
+
+	/* Must be "Group#Event" or "Group#Event#pat". */
+	event_name = p;
+	p = vim_strchr(event_name, '#');
+	if (p != NULL)
+	    *p++ = NUL;	    /* "Group#Event#pat" */
+    }
+
+    pattern = p;	    /* "pattern" is NULL when there is no pattern */
+
+    /* find the index (enum) for the event name */
+    event = event_name2nr(event_name, &p);
+
+    /* return FALSE if the event name is not recognized */
+    if (event == NUM_EVENTS)
+	goto theend;
+
+    /* Find the first autocommand for this event.
+     * If there isn't any, return FALSE;
+     * If there is one and no pattern given, return TRUE; */
+    ap = first_autopat[(int)event];
+    if (ap == NULL)
+	goto theend;
+    if (pattern == NULL)
+    {
+	retval = TRUE;
+	goto theend;
+    }
+
+    /* if pattern is "<buffer>", special handling is needed which uses curbuf */
+    /* for pattern "<buffer=N>, fnamecmp() will work fine */
+    if (STRICMP(pattern, "<buffer>") == 0)
+	buflocal_buf = curbuf;
+
+    /* Check if there is an autocommand with the given pattern. */
+    for ( ; ap != NULL; ap = ap->next)
+	/* only use a pattern when it has not been removed and has commands. */
+	/* For buffer-local autocommands, fnamecmp() works fine. */
+	if (ap->pat != NULL && ap->cmds != NULL
+	    && (group == AUGROUP_ALL || ap->group == group)
+	    && (buflocal_buf == NULL
+		 ? fnamecmp(ap->pat, pattern) == 0
+		 : ap->buflocal_nr == buflocal_buf->b_fnum))
+	{
+	    retval = TRUE;
+	    break;
+	}
+
+theend:
+    vim_free(arg_save);
+    return retval;
+}
+
+#else	/* FEAT_AUTOCMD */
+
+/*
+ * Prepare for executing commands for (hidden) buffer "buf".
+ * This is the non-autocommand version, it simply saves "curbuf" and sets
+ * "curbuf" and "curwin" to match "buf".
+ */
+    void
+aucmd_prepbuf(aco, buf)
+    aco_save_T	*aco;		/* structure to save values in */
+    buf_T	*buf;		/* new curbuf */
+{
+    aco->save_buf = buf;
+    curbuf = buf;
+    curwin->w_buffer = buf;
+}
+
+/*
+ * Restore after executing commands for a (hidden) buffer.
+ * This is the non-autocommand version.
+ */
+    void
+aucmd_restbuf(aco)
+    aco_save_T	*aco;		/* structure holding saved values */
+{
+    curbuf = aco->save_buf;
+    curwin->w_buffer = curbuf;
+}
+
+#endif	/* FEAT_AUTOCMD */
+
+
+#if defined(FEAT_AUTOCMD) || defined(FEAT_WILDIGN) || defined(PROTO)
+/*
+ * Try matching a filename with a "pattern" ("prog" is NULL), or use the
+ * precompiled regprog "prog" ("pattern" is NULL).  That avoids calling
+ * vim_regcomp() often.
+ * Used for autocommands and 'wildignore'.
+ * Returns TRUE if there is a match, FALSE otherwise.
+ */
+    int
+match_file_pat(pattern, prog, fname, sfname, tail, allow_dirs)
+    char_u	*pattern;		/* pattern to match with */
+    regprog_T	*prog;			/* pre-compiled regprog or NULL */
+    char_u	*fname;			/* full path of file name */
+    char_u	*sfname;		/* short file name or NULL */
+    char_u	*tail;			/* tail of path */
+    int		allow_dirs;		/* allow matching with dir */
+{
+    regmatch_T	regmatch;
+    int		result = FALSE;
+#ifdef FEAT_OSFILETYPE
+    int		no_pattern = FALSE; /* TRUE if check is filetype only */
+    char_u	*type_start;
+    char_u	c;
+    int		match = FALSE;
+#endif
+
+#ifdef CASE_INSENSITIVE_FILENAME
+    regmatch.rm_ic = TRUE;		/* Always ignore case */
+#else
+    regmatch.rm_ic = FALSE;		/* Don't ever ignore case */
+#endif
+#ifdef FEAT_OSFILETYPE
+    if (*pattern == '<')
+    {
+	/* There is a filetype condition specified with this pattern.
+	 * Check the filetype matches first. If not, don't bother with the
+	 * pattern (set regprog to NULL).
+	 * Always use magic for the regexp.
+	 */
+
+	for (type_start = pattern + 1; (c = *pattern); pattern++)
+	{
+	    if ((c == ';' || c == '>') && match == FALSE)
+	    {
+		*pattern = NUL;	    /* Terminate the string */
+		match = mch_check_filetype(fname, type_start);
+		*pattern = c;	    /* Restore the terminator */
+		type_start = pattern + 1;
+	    }
+	    if (c == '>')
+		break;
+	}
+
+	/* (c should never be NUL, but check anyway) */
+	if (match == FALSE || c == NUL)
+	    regmatch.regprog = NULL;	/* Doesn't match - don't check pat. */
+	else if (*pattern == NUL)
+	{
+	    regmatch.regprog = NULL;	/* Vim will try to free regprog later */
+	    no_pattern = TRUE;	/* Always matches - don't check pat. */
+	}
+	else
+	    regmatch.regprog = vim_regcomp(pattern + 1, RE_MAGIC);
+    }
+    else
+#endif
+    {
+	if (prog != NULL)
+	    regmatch.regprog = prog;
+	else
+	    regmatch.regprog = vim_regcomp(pattern, RE_MAGIC);
+    }
+
+    /*
+     * Try for a match with the pattern with:
+     * 1. the full file name, when the pattern has a '/'.
+     * 2. the short file name, when the pattern has a '/'.
+     * 3. the tail of the file name, when the pattern has no '/'.
+     */
+    if (
+#ifdef FEAT_OSFILETYPE
+	    /* If the check is for a filetype only and we don't care
+	     * about the path then skip all the regexp stuff.
+	     */
+	    no_pattern ||
+#endif
+	    (regmatch.regprog != NULL
+	     && ((allow_dirs
+		     && (vim_regexec(&regmatch, fname, (colnr_T)0)
+			 || (sfname != NULL
+			     && vim_regexec(&regmatch, sfname, (colnr_T)0))))
+		 || (!allow_dirs && vim_regexec(&regmatch, tail, (colnr_T)0)))))
+	result = TRUE;
+
+    if (prog == NULL)
+	vim_free(regmatch.regprog);
+    return result;
+}
+#endif
+
+#if defined(FEAT_WILDIGN) || defined(PROTO)
+/*
+ * Return TRUE if a file matches with a pattern in "list".
+ * "list" is a comma-separated list of patterns, like 'wildignore'.
+ * "sfname" is the short file name or NULL, "ffname" the long file name.
+ */
+    int
+match_file_list(list, sfname, ffname)
+    char_u	*list;
+    char_u	*sfname;
+    char_u	*ffname;
+{
+    char_u	buf[100];
+    char_u	*tail;
+    char_u	*regpat;
+    char	allow_dirs;
+    int		match;
+    char_u	*p;
+
+    tail = gettail(sfname);
+
+    /* try all patterns in 'wildignore' */
+    p = list;
+    while (*p)
+    {
+	copy_option_part(&p, buf, 100, ",");
+	regpat = file_pat_to_reg_pat(buf, NULL, &allow_dirs, FALSE);
+	if (regpat == NULL)
+	    break;
+	match = match_file_pat(regpat, NULL, ffname, sfname,
+						       tail, (int)allow_dirs);
+	vim_free(regpat);
+	if (match)
+	    return TRUE;
+    }
+    return FALSE;
+}
+#endif
+
+/*
+ * Convert the given pattern "pat" which has shell style wildcards in it, into
+ * a regular expression, and return the result in allocated memory.  If there
+ * is a directory path separator to be matched, then TRUE is put in
+ * allow_dirs, otherwise FALSE is put there -- webb.
+ * Handle backslashes before special characters, like "\*" and "\ ".
+ *
+ * If FEAT_OSFILETYPE defined then pass initial <type> through unchanged. Eg:
+ * '<html>myfile' becomes '<html>^myfile$' -- leonard.
+ *
+ * Returns NULL when out of memory.
+ */
+/*ARGSUSED*/
+    char_u *
+file_pat_to_reg_pat(pat, pat_end, allow_dirs, no_bslash)
+    char_u	*pat;
+    char_u	*pat_end;	/* first char after pattern or NULL */
+    char	*allow_dirs;	/* Result passed back out in here */
+    int		no_bslash;	/* Don't use a backward slash as pathsep */
+{
+    int		size;
+    char_u	*endp;
+    char_u	*reg_pat;
+    char_u	*p;
+    int		i;
+    int		nested = 0;
+    int		add_dollar = TRUE;
+#ifdef FEAT_OSFILETYPE
+    int		check_length = 0;
+#endif
+
+    if (allow_dirs != NULL)
+	*allow_dirs = FALSE;
+    if (pat_end == NULL)
+	pat_end = pat + STRLEN(pat);
+
+#ifdef FEAT_OSFILETYPE
+    /* Find out how much of the string is the filetype check */
+    if (*pat == '<')
+    {
+	/* Count chars until the next '>' */
+	for (p = pat + 1; p < pat_end && *p != '>'; p++)
+	    ;
+	if (p < pat_end)
+	{
+	    /* Pattern is of the form <.*>.*  */
+	    check_length = p - pat + 1;
+	    if (p + 1 >= pat_end)
+	    {
+		/* The 'pattern' is a filetype check ONLY */
+		reg_pat = (char_u *)alloc(check_length + 1);
+		if (reg_pat != NULL)
+		{
+		    mch_memmove(reg_pat, pat, (size_t)check_length);
+		    reg_pat[check_length] = NUL;
+		}
+		return reg_pat;
+	    }
+	}
+	/* else: there was no closing '>' - assume it was a normal pattern */
+
+    }
+    pat += check_length;
+    size = 2 + check_length;
+#else
+    size = 2;		/* '^' at start, '$' at end */
+#endif
+
+    for (p = pat; p < pat_end; p++)
+    {
+	switch (*p)
+	{
+	    case '*':
+	    case '.':
+	    case ',':
+	    case '{':
+	    case '}':
+	    case '~':
+		size += 2;	/* extra backslash */
+		break;
+#ifdef BACKSLASH_IN_FILENAME
+	    case '\\':
+	    case '/':
+		size += 4;	/* could become "[\/]" */
+		break;
+#endif
+	    default:
+		size++;
+# ifdef  FEAT_MBYTE
+		if (enc_dbcs != 0 && (*mb_ptr2len)(p) > 1)
+		{
+		    ++p;
+		    ++size;
+		}
+# endif
+		break;
+	}
+    }
+    reg_pat = alloc(size + 1);
+    if (reg_pat == NULL)
+	return NULL;
+
+#ifdef FEAT_OSFILETYPE
+    /* Copy the type check in to the start. */
+    if (check_length)
+	mch_memmove(reg_pat, pat - check_length, (size_t)check_length);
+    i = check_length;
+#else
+    i = 0;
+#endif
+
+    if (pat[0] == '*')
+	while (pat[0] == '*' && pat < pat_end - 1)
+	    pat++;
+    else
+	reg_pat[i++] = '^';
+    endp = pat_end - 1;
+    if (*endp == '*')
+    {
+	while (endp - pat > 0 && *endp == '*')
+	    endp--;
+	add_dollar = FALSE;
+    }
+    for (p = pat; *p && nested >= 0 && p <= endp; p++)
+    {
+	switch (*p)
+	{
+	    case '*':
+		reg_pat[i++] = '.';
+		reg_pat[i++] = '*';
+		while (p[1] == '*')	/* "**" matches like "*" */
+		    ++p;
+		break;
+	    case '.':
+#ifdef RISCOS
+		if (allow_dirs != NULL)
+		     *allow_dirs = TRUE;
+		/* FALLTHROUGH */
+#endif
+	    case '~':
+		reg_pat[i++] = '\\';
+		reg_pat[i++] = *p;
+		break;
+	    case '?':
+#ifdef RISCOS
+	    case '#':
+#endif
+		reg_pat[i++] = '.';
+		break;
+	    case '\\':
+		if (p[1] == NUL)
+		    break;
+#ifdef BACKSLASH_IN_FILENAME
+		if (!no_bslash)
+		{
+		    /* translate:
+		     * "\x" to "\\x"  e.g., "dir\file"
+		     * "\*" to "\\.*" e.g., "dir\*.c"
+		     * "\?" to "\\."  e.g., "dir\??.c"
+		     * "\+" to "\+"   e.g., "fileX\+.c"
+		     */
+		    if ((vim_isfilec(p[1]) || p[1] == '*' || p[1] == '?')
+			    && p[1] != '+')
+		    {
+			reg_pat[i++] = '[';
+			reg_pat[i++] = '\\';
+			reg_pat[i++] = '/';
+			reg_pat[i++] = ']';
+			if (allow_dirs != NULL)
+			    *allow_dirs = TRUE;
+			break;
+		    }
+		}
+#endif
+		if (*++p == '?'
+#ifdef BACKSLASH_IN_FILENAME
+			&& no_bslash
+#endif
+			)
+		    reg_pat[i++] = '?';
+		else
+		    if (*p == ',')
+			reg_pat[i++] = ',';
+		    else
+		    {
+			if (allow_dirs != NULL && vim_ispathsep(*p)
+#ifdef BACKSLASH_IN_FILENAME
+				&& (!no_bslash || *p != '\\')
+#endif
+				)
+			    *allow_dirs = TRUE;
+			reg_pat[i++] = '\\';
+			reg_pat[i++] = *p;
+		    }
+		break;
+#ifdef BACKSLASH_IN_FILENAME
+	    case '/':
+		reg_pat[i++] = '[';
+		reg_pat[i++] = '\\';
+		reg_pat[i++] = '/';
+		reg_pat[i++] = ']';
+		if (allow_dirs != NULL)
+		    *allow_dirs = TRUE;
+		break;
+#endif
+	    case '{':
+		reg_pat[i++] = '\\';
+		reg_pat[i++] = '(';
+		nested++;
+		break;
+	    case '}':
+		reg_pat[i++] = '\\';
+		reg_pat[i++] = ')';
+		--nested;
+		break;
+	    case ',':
+		if (nested)
+		{
+		    reg_pat[i++] = '\\';
+		    reg_pat[i++] = '|';
+		}
+		else
+		    reg_pat[i++] = ',';
+		break;
+	    default:
+# ifdef  FEAT_MBYTE
+		if (enc_dbcs != 0 && (*mb_ptr2len)(p) > 1)
+		    reg_pat[i++] = *p++;
+		else
+# endif
+		if (allow_dirs != NULL && vim_ispathsep(*p))
+		    *allow_dirs = TRUE;
+		reg_pat[i++] = *p;
+		break;
+	}
+    }
+    if (add_dollar)
+	reg_pat[i++] = '$';
+    reg_pat[i] = NUL;
+    if (nested != 0)
+    {
+	if (nested < 0)
+	    EMSG(_("E219: Missing {."));
+	else
+	    EMSG(_("E220: Missing }."));
+	vim_free(reg_pat);
+	reg_pat = NULL;
+    }
+    return reg_pat;
+}
--- /dev/null
+++ b/fold.c
@@ -1,0 +1,3338 @@
+/* vim:set ts=8 sts=4 sw=4:
+ * vim600:fdm=marker fdl=1 fdc=3:
+ *
+ * VIM - Vi IMproved	by Bram Moolenaar
+ *
+ * Do ":help uganda"  in Vim to read copying and usage conditions.
+ * Do ":help credits" in Vim to see a list of people who contributed.
+ * See README.txt for an overview of the Vim source code.
+ */
+
+/*
+ * fold.c: code for folding
+ */
+
+#include "vim.h"
+
+#if defined(FEAT_FOLDING) || defined(PROTO)
+
+/* local declarations. {{{1 */
+/* typedef fold_T {{{2 */
+/*
+ * The toplevel folds for each window are stored in the w_folds growarray.
+ * Each toplevel fold can contain an array of second level folds in the
+ * fd_nested growarray.
+ * The info stored in both growarrays is the same: An array of fold_T.
+ */
+typedef struct
+{
+    linenr_T	fd_top;		/* first line of fold; for nested fold
+				 * relative to parent */
+    linenr_T	fd_len;		/* number of lines in the fold */
+    garray_T	fd_nested;	/* array of nested folds */
+    char	fd_flags;	/* see below */
+    char	fd_small;	/* TRUE, FALSE or MAYBE: fold smaller than
+				   'foldminlines'; MAYBE applies to nested
+				   folds too */
+} fold_T;
+
+#define FD_OPEN		0	/* fold is open (nested ones can be closed) */
+#define FD_CLOSED	1	/* fold is closed */
+#define FD_LEVEL	2	/* depends on 'foldlevel' (nested folds too) */
+
+#define MAX_LEVEL	20	/* maximum fold depth */
+
+/* static functions {{{2 */
+static void newFoldLevelWin __ARGS((win_T *wp));
+static int checkCloseRec __ARGS((garray_T *gap, linenr_T lnum, int level));
+static int foldFind __ARGS((garray_T *gap, linenr_T lnum, fold_T **fpp));
+static int foldLevelWin __ARGS((win_T *wp, linenr_T lnum));
+static void checkupdate __ARGS((win_T *wp));
+static void setFoldRepeat __ARGS((linenr_T lnum, long count, int open));
+static linenr_T setManualFold __ARGS((linenr_T lnum, int opening, int recurse, int *donep));
+static linenr_T setManualFoldWin __ARGS((win_T *wp, linenr_T lnum, int opening, int recurse, int *donep));
+static void foldOpenNested __ARGS((fold_T *fpr));
+static void deleteFoldEntry __ARGS((garray_T *gap, int idx, int recursive));
+static void foldMarkAdjustRecurse __ARGS((garray_T *gap, linenr_T line1, linenr_T line2, long amount, long amount_after));
+static int getDeepestNestingRecurse __ARGS((garray_T *gap));
+static int check_closed __ARGS((win_T *win, fold_T *fp, int *use_levelp, int level, int *maybe_smallp, linenr_T lnum_off));
+static void checkSmall __ARGS((win_T *wp, fold_T *fp, linenr_T lnum_off));
+static void setSmallMaybe __ARGS((garray_T *gap));
+static void foldCreateMarkers __ARGS((linenr_T start, linenr_T end));
+static void foldAddMarker __ARGS((linenr_T lnum, char_u *marker, int markerlen));
+static void deleteFoldMarkers __ARGS((fold_T *fp, int recursive, linenr_T lnum_off));
+static void foldDelMarker __ARGS((linenr_T lnum, char_u *marker, int markerlen));
+static void foldUpdateIEMS __ARGS((win_T *wp, linenr_T top, linenr_T bot));
+static void parseMarker __ARGS((win_T *wp));
+
+static char *e_nofold = N_("E490: No fold found");
+
+/*
+ * While updating the folds lines between invalid_top and invalid_bot have an
+ * undefined fold level.  Only used for the window currently being updated.
+ */
+static linenr_T invalid_top = (linenr_T)0;
+static linenr_T invalid_bot = (linenr_T)0;
+
+/*
+ * When using 'foldexpr' we sometimes get the level of the next line, which
+ * calls foldlevel() to get the level of the current line, which hasn't been
+ * stored yet.  To get around this chicken-egg problem the level of the
+ * previous line is stored here when available.  prev_lnum is zero when the
+ * level is not available.
+ */
+static linenr_T prev_lnum = 0;
+static int prev_lnum_lvl = -1;
+
+/* Flags used for "done" argument of setManualFold. */
+#define DONE_NOTHING	0
+#define DONE_ACTION	1	/* did close or open a fold */
+#define DONE_FOLD	2	/* did find a fold */
+
+static int foldstartmarkerlen;
+static char_u *foldendmarker;
+static int foldendmarkerlen;
+
+/* Exported folding functions. {{{1 */
+/* copyFoldingState() {{{2 */
+#if defined(FEAT_WINDOWS) || defined(PROTO)
+/*
+ * Copy that folding state from window "wp_from" to window "wp_to".
+ */
+    void
+copyFoldingState(wp_from, wp_to)
+    win_T	*wp_from;
+    win_T	*wp_to;
+{
+    wp_to->w_fold_manual = wp_from->w_fold_manual;
+    wp_to->w_foldinvalid = wp_from->w_foldinvalid;
+    cloneFoldGrowArray(&wp_from->w_folds, &wp_to->w_folds);
+}
+#endif
+
+/* hasAnyFolding() {{{2 */
+/*
+ * Return TRUE if there may be folded lines in the current window.
+ */
+    int
+hasAnyFolding(win)
+    win_T	*win;
+{
+    /* very simple now, but can become more complex later */
+    return (win->w_p_fen
+	    && (!foldmethodIsManual(win) || win->w_folds.ga_len > 0));
+}
+
+/* hasFolding() {{{2 */
+/*
+ * Return TRUE if line "lnum" in the current window is part of a closed
+ * fold.
+ * When returning TRUE, *firstp and *lastp are set to the first and last
+ * lnum of the sequence of folded lines (skipped when NULL).
+ */
+    int
+hasFolding(lnum, firstp, lastp)
+    linenr_T	lnum;
+    linenr_T	*firstp;
+    linenr_T	*lastp;
+{
+    return hasFoldingWin(curwin, lnum, firstp, lastp, TRUE, NULL);
+}
+
+/* hasFoldingWin() {{{2 */
+    int
+hasFoldingWin(win, lnum, firstp, lastp, cache, infop)
+    win_T	*win;
+    linenr_T	lnum;
+    linenr_T	*firstp;
+    linenr_T	*lastp;
+    int		cache;		/* when TRUE: use cached values of window */
+    foldinfo_T	*infop;		/* where to store fold info */
+{
+    int		had_folded = FALSE;
+    linenr_T	first = 0;
+    linenr_T	last = 0;
+    linenr_T	lnum_rel = lnum;
+    int		x;
+    fold_T	*fp;
+    int		level = 0;
+    int		use_level = FALSE;
+    int		maybe_small = FALSE;
+    garray_T	*gap;
+    int		low_level = 0;;
+
+    checkupdate(win);
+    /*
+     * Return quickly when there is no folding at all in this window.
+     */
+    if (!hasAnyFolding(win))
+    {
+	if (infop != NULL)
+	    infop->fi_level = 0;
+	return FALSE;
+    }
+
+    if (cache)
+    {
+	/*
+	 * First look in cached info for displayed lines.  This is probably
+	 * the fastest, but it can only be used if the entry is still valid.
+	 */
+	x = find_wl_entry(win, lnum);
+	if (x >= 0)
+	{
+	    first = win->w_lines[x].wl_lnum;
+	    last = win->w_lines[x].wl_lastlnum;
+	    had_folded = win->w_lines[x].wl_folded;
+	}
+    }
+
+    if (first == 0)
+    {
+	/*
+	 * Recursively search for a fold that contains "lnum".
+	 */
+	gap = &win->w_folds;
+	for (;;)
+	{
+	    if (!foldFind(gap, lnum_rel, &fp))
+		break;
+
+	    /* Remember lowest level of fold that starts in "lnum". */
+	    if (lnum_rel == fp->fd_top && low_level == 0)
+		low_level = level + 1;
+
+	    first += fp->fd_top;
+	    last += fp->fd_top;
+
+	    /* is this fold closed? */
+	    had_folded = check_closed(win, fp, &use_level, level,
+					       &maybe_small, lnum - lnum_rel);
+	    if (had_folded)
+	    {
+		/* Fold closed: Set last and quit loop. */
+		last += fp->fd_len - 1;
+		break;
+	    }
+
+	    /* Fold found, but it's open: Check nested folds.  Line number is
+	     * relative to containing fold. */
+	    gap = &fp->fd_nested;
+	    lnum_rel -= fp->fd_top;
+	    ++level;
+	}
+    }
+
+    if (!had_folded)
+    {
+	if (infop != NULL)
+	{
+	    infop->fi_level = level;
+	    infop->fi_lnum = lnum - lnum_rel;
+	    infop->fi_low_level = low_level == 0 ? level : low_level;
+	}
+	return FALSE;
+    }
+
+    if (lastp != NULL)
+	*lastp = last;
+    if (firstp != NULL)
+	*firstp = first;
+    if (infop != NULL)
+    {
+	infop->fi_level = level + 1;
+	infop->fi_lnum = first;
+	infop->fi_low_level = low_level == 0 ? level + 1 : low_level;
+    }
+    return TRUE;
+}
+
+/* foldLevel() {{{2 */
+/*
+ * Return fold level at line number "lnum" in the current window.
+ */
+    int
+foldLevel(lnum)
+    linenr_T	lnum;
+{
+    /* While updating the folds lines between invalid_top and invalid_bot have
+     * an undefined fold level.  Otherwise update the folds first. */
+    if (invalid_top == (linenr_T)0)
+	checkupdate(curwin);
+    else if (lnum == prev_lnum && prev_lnum_lvl >= 0)
+	return prev_lnum_lvl;
+    else if (lnum >= invalid_top && lnum <= invalid_bot)
+	return -1;
+
+    /* Return quickly when there is no folding at all in this window. */
+    if (!hasAnyFolding(curwin))
+	return 0;
+
+    return foldLevelWin(curwin, lnum);
+}
+
+/* lineFolded()	{{{2 */
+/*
+ * Low level function to check if a line is folded.  Doesn't use any caching.
+ * Return TRUE if line is folded.
+ * Return FALSE if line is not folded.
+ * Return MAYBE if the line is folded when next to a folded line.
+ */
+    int
+lineFolded(win, lnum)
+    win_T	*win;
+    linenr_T	lnum;
+{
+    return foldedCount(win, lnum, NULL) != 0;
+}
+
+/* foldedCount() {{{2 */
+/*
+ * Count the number of lines that are folded at line number "lnum".
+ * Normally "lnum" is the first line of a possible fold, and the returned
+ * number is the number of lines in the fold.
+ * Doesn't use caching from the displayed window.
+ * Returns number of folded lines from "lnum", or 0 if line is not folded.
+ * When "infop" is not NULL, fills *infop with the fold level info.
+ */
+    long
+foldedCount(win, lnum, infop)
+    win_T	*win;
+    linenr_T	lnum;
+    foldinfo_T	*infop;
+{
+    linenr_T	last;
+
+    if (hasFoldingWin(win, lnum, NULL, &last, FALSE, infop))
+	return (long)(last - lnum + 1);
+    return 0;
+}
+
+/* foldmethodIsManual() {{{2 */
+/*
+ * Return TRUE if 'foldmethod' is "manual"
+ */
+    int
+foldmethodIsManual(wp)
+    win_T	*wp;
+{
+    return (wp->w_p_fdm[3] == 'u');
+}
+
+/* foldmethodIsIndent() {{{2 */
+/*
+ * Return TRUE if 'foldmethod' is "indent"
+ */
+    int
+foldmethodIsIndent(wp)
+    win_T	*wp;
+{
+    return (wp->w_p_fdm[0] == 'i');
+}
+
+/* foldmethodIsExpr() {{{2 */
+/*
+ * Return TRUE if 'foldmethod' is "expr"
+ */
+    int
+foldmethodIsExpr(wp)
+    win_T	*wp;
+{
+    return (wp->w_p_fdm[1] == 'x');
+}
+
+/* foldmethodIsMarker() {{{2 */
+/*
+ * Return TRUE if 'foldmethod' is "marker"
+ */
+    int
+foldmethodIsMarker(wp)
+    win_T	*wp;
+{
+    return (wp->w_p_fdm[2] == 'r');
+}
+
+/* foldmethodIsSyntax() {{{2 */
+/*
+ * Return TRUE if 'foldmethod' is "syntax"
+ */
+    int
+foldmethodIsSyntax(wp)
+    win_T	*wp;
+{
+    return (wp->w_p_fdm[0] == 's');
+}
+
+/* foldmethodIsDiff() {{{2 */
+/*
+ * Return TRUE if 'foldmethod' is "diff"
+ */
+    int
+foldmethodIsDiff(wp)
+    win_T	*wp;
+{
+    return (wp->w_p_fdm[0] == 'd');
+}
+
+/* closeFold() {{{2 */
+/*
+ * Close fold for current window at line "lnum".
+ * Repeat "count" times.
+ */
+    void
+closeFold(lnum, count)
+    linenr_T	lnum;
+    long	count;
+{
+    setFoldRepeat(lnum, count, FALSE);
+}
+
+/* closeFoldRecurse() {{{2 */
+/*
+ * Close fold for current window at line "lnum" recursively.
+ */
+    void
+closeFoldRecurse(lnum)
+    linenr_T	lnum;
+{
+    (void)setManualFold(lnum, FALSE, TRUE, NULL);
+}
+
+/* opFoldRange() {{{2 */
+/*
+ * Open or Close folds for current window in lines "first" to "last".
+ * Used for "zo", "zO", "zc" and "zC" in Visual mode.
+ */
+    void
+opFoldRange(first, last, opening, recurse, had_visual)
+    linenr_T	first;
+    linenr_T	last;
+    int		opening;	/* TRUE to open, FALSE to close */
+    int		recurse;	/* TRUE to do it recursively */
+    int		had_visual;	/* TRUE when Visual selection used */
+{
+    int		done = DONE_NOTHING;	/* avoid error messages */
+    linenr_T	lnum;
+    linenr_T	lnum_next;
+
+    for (lnum = first; lnum <= last; lnum = lnum_next + 1)
+    {
+	lnum_next = lnum;
+	/* Opening one level only: next fold to open is after the one going to
+	 * be opened. */
+	if (opening && !recurse)
+	    (void)hasFolding(lnum, NULL, &lnum_next);
+	(void)setManualFold(lnum, opening, recurse, &done);
+	/* Closing one level only: next line to close a fold is after just
+	 * closed fold. */
+	if (!opening && !recurse)
+	    (void)hasFolding(lnum, NULL, &lnum_next);
+    }
+    if (done == DONE_NOTHING)
+	EMSG(_(e_nofold));
+#ifdef FEAT_VISUAL
+    /* Force a redraw to remove the Visual highlighting. */
+    if (had_visual)
+	redraw_curbuf_later(INVERTED);
+#endif
+}
+
+/* openFold() {{{2 */
+/*
+ * Open fold for current window at line "lnum".
+ * Repeat "count" times.
+ */
+    void
+openFold(lnum, count)
+    linenr_T	lnum;
+    long	count;
+{
+    setFoldRepeat(lnum, count, TRUE);
+}
+
+/* openFoldRecurse() {{{2 */
+/*
+ * Open fold for current window at line "lnum" recursively.
+ */
+    void
+openFoldRecurse(lnum)
+    linenr_T	lnum;
+{
+    (void)setManualFold(lnum, TRUE, TRUE, NULL);
+}
+
+/* foldOpenCursor() {{{2 */
+/*
+ * Open folds until the cursor line is not in a closed fold.
+ */
+    void
+foldOpenCursor()
+{
+    int		done;
+
+    checkupdate(curwin);
+    if (hasAnyFolding(curwin))
+	for (;;)
+	{
+	    done = DONE_NOTHING;
+	    (void)setManualFold(curwin->w_cursor.lnum, TRUE, FALSE, &done);
+	    if (!(done & DONE_ACTION))
+		break;
+	}
+}
+
+/* newFoldLevel() {{{2 */
+/*
+ * Set new foldlevel for current window.
+ */
+    void
+newFoldLevel()
+{
+    newFoldLevelWin(curwin);
+
+#ifdef FEAT_DIFF
+    if (foldmethodIsDiff(curwin) && curwin->w_p_scb)
+    {
+	win_T	    *wp;
+
+	/*
+	 * Set the same foldlevel in other windows in diff mode.
+	 */
+	FOR_ALL_WINDOWS(wp)
+	{
+	    if (wp != curwin && foldmethodIsDiff(wp) && wp->w_p_scb)
+	    {
+		wp->w_p_fdl = curwin->w_p_fdl;
+		newFoldLevelWin(wp);
+	    }
+	}
+    }
+#endif
+}
+
+    static void
+newFoldLevelWin(wp)
+    win_T	*wp;
+{
+    fold_T	*fp;
+    int		i;
+
+    checkupdate(wp);
+    if (wp->w_fold_manual)
+    {
+	/* Set all flags for the first level of folds to FD_LEVEL.  Following
+	 * manual open/close will then change the flags to FD_OPEN or
+	 * FD_CLOSED for those folds that don't use 'foldlevel'. */
+	fp = (fold_T *)wp->w_folds.ga_data;
+	for (i = 0; i < wp->w_folds.ga_len; ++i)
+	    fp[i].fd_flags = FD_LEVEL;
+	wp->w_fold_manual = FALSE;
+    }
+    changed_window_setting_win(wp);
+}
+
+/* foldCheckClose() {{{2 */
+/*
+ * Apply 'foldlevel' to all folds that don't contain the cursor.
+ */
+    void
+foldCheckClose()
+{
+    if (*p_fcl != NUL)	/* can only be "all" right now */
+    {
+	checkupdate(curwin);
+	if (checkCloseRec(&curwin->w_folds, curwin->w_cursor.lnum,
+							(int)curwin->w_p_fdl))
+	    changed_window_setting();
+    }
+}
+
+/* checkCloseRec() {{{2 */
+    static int
+checkCloseRec(gap, lnum, level)
+    garray_T	*gap;
+    linenr_T	lnum;
+    int		level;
+{
+    fold_T	*fp;
+    int		retval = FALSE;
+    int		i;
+
+    fp = (fold_T *)gap->ga_data;
+    for (i = 0; i < gap->ga_len; ++i)
+    {
+	/* Only manually opened folds may need to be closed. */
+	if (fp[i].fd_flags == FD_OPEN)
+	{
+	    if (level <= 0 && (lnum < fp[i].fd_top
+				      || lnum >= fp[i].fd_top + fp[i].fd_len))
+	    {
+		fp[i].fd_flags = FD_LEVEL;
+		retval = TRUE;
+	    }
+	    else
+		retval |= checkCloseRec(&fp[i].fd_nested, lnum - fp[i].fd_top,
+								   level - 1);
+	}
+    }
+    return retval;
+}
+
+/* foldCreateAllowed() {{{2 */
+/*
+ * Return TRUE if it's allowed to manually create or delete a fold.
+ * Give an error message and return FALSE if not.
+ */
+    int
+foldManualAllowed(create)
+    int		create;
+{
+    if (foldmethodIsManual(curwin) || foldmethodIsMarker(curwin))
+	return TRUE;
+    if (create)
+	EMSG(_("E350: Cannot create fold with current 'foldmethod'"));
+    else
+	EMSG(_("E351: Cannot delete fold with current 'foldmethod'"));
+    return FALSE;
+}
+
+/* foldCreate() {{{2 */
+/*
+ * Create a fold from line "start" to line "end" (inclusive) in the current
+ * window.
+ */
+    void
+foldCreate(start, end)
+    linenr_T	start;
+    linenr_T	end;
+{
+    fold_T	*fp;
+    garray_T	*gap;
+    garray_T	fold_ga;
+    int		i, j;
+    int		cont;
+    int		use_level = FALSE;
+    int		closed = FALSE;
+    int		level = 0;
+    linenr_T	start_rel = start;
+    linenr_T	end_rel = end;
+
+    if (start > end)
+    {
+	/* reverse the range */
+	end = start_rel;
+	start = end_rel;
+	start_rel = start;
+	end_rel = end;
+    }
+
+    /* When 'foldmethod' is "marker" add markers, which creates the folds. */
+    if (foldmethodIsMarker(curwin))
+    {
+	foldCreateMarkers(start, end);
+	return;
+    }
+
+    checkupdate(curwin);
+
+    /* Find the place to insert the new fold. */
+    gap = &curwin->w_folds;
+    for (;;)
+    {
+	if (!foldFind(gap, start_rel, &fp))
+	    break;
+	if (fp->fd_top + fp->fd_len > end_rel)
+	{
+	    /* New fold is completely inside this fold: Go one level deeper. */
+	    gap = &fp->fd_nested;
+	    start_rel -= fp->fd_top;
+	    end_rel -= fp->fd_top;
+	    if (use_level || fp->fd_flags == FD_LEVEL)
+	    {
+		use_level = TRUE;
+		if (level >= curwin->w_p_fdl)
+		    closed = TRUE;
+	    }
+	    else if (fp->fd_flags == FD_CLOSED)
+		closed = TRUE;
+	    ++level;
+	}
+	else
+	{
+	    /* This fold and new fold overlap: Insert here and move some folds
+	     * inside the new fold. */
+	    break;
+	}
+    }
+
+    i = (int)(fp - (fold_T *)gap->ga_data);
+    if (ga_grow(gap, 1) == OK)
+    {
+	fp = (fold_T *)gap->ga_data + i;
+	ga_init2(&fold_ga, (int)sizeof(fold_T), 10);
+
+	/* Count number of folds that will be contained in the new fold. */
+	for (cont = 0; i + cont < gap->ga_len; ++cont)
+	    if (fp[cont].fd_top > end_rel)
+		break;
+	if (cont > 0 && ga_grow(&fold_ga, cont) == OK)
+	{
+	    /* If the first fold starts before the new fold, let the new fold
+	     * start there.  Otherwise the existing fold would change. */
+	    if (start_rel > fp->fd_top)
+		start_rel = fp->fd_top;
+
+	    /* When last contained fold isn't completely contained, adjust end
+	     * of new fold. */
+	    if (end_rel < fp[cont - 1].fd_top + fp[cont - 1].fd_len - 1)
+		end_rel = fp[cont - 1].fd_top + fp[cont - 1].fd_len - 1;
+	    /* Move contained folds to inside new fold. */
+	    mch_memmove(fold_ga.ga_data, fp, sizeof(fold_T) * cont);
+	    fold_ga.ga_len += cont;
+	    i += cont;
+
+	    /* Adjust line numbers in contained folds to be relative to the
+	     * new fold. */
+	    for (j = 0; j < cont; ++j)
+		((fold_T *)fold_ga.ga_data)[j].fd_top -= start_rel;
+	}
+	/* Move remaining entries to after the new fold. */
+	if (i < gap->ga_len)
+	    mch_memmove(fp + 1, (fold_T *)gap->ga_data + i,
+				     sizeof(fold_T) * (gap->ga_len - i));
+	gap->ga_len = gap->ga_len + 1 - cont;
+
+	/* insert new fold */
+	fp->fd_nested = fold_ga;
+	fp->fd_top = start_rel;
+	fp->fd_len = end_rel - start_rel + 1;
+
+	/* We want the new fold to be closed.  If it would remain open because
+	 * of using 'foldlevel', need to adjust fd_flags of containing folds.
+	 */
+	if (use_level && !closed && level < curwin->w_p_fdl)
+	    closeFold(start, 1L);
+	if (!use_level)
+	    curwin->w_fold_manual = TRUE;
+	fp->fd_flags = FD_CLOSED;
+	fp->fd_small = MAYBE;
+
+	/* redraw */
+	changed_window_setting();
+    }
+}
+
+/* deleteFold() {{{2 */
+/*
+ * Delete a fold at line "start" in the current window.
+ * When "end" is not 0, delete all folds from "start" to "end".
+ * When "recursive" is TRUE delete recursively.
+ */
+    void
+deleteFold(start, end, recursive, had_visual)
+    linenr_T	start;
+    linenr_T	end;
+    int		recursive;
+    int		had_visual;	/* TRUE when Visual selection used */
+{
+    garray_T	*gap;
+    fold_T	*fp;
+    garray_T	*found_ga;
+    fold_T	*found_fp = NULL;
+    linenr_T	found_off = 0;
+    int		use_level = FALSE;
+    int		maybe_small = FALSE;
+    int		level = 0;
+    linenr_T	lnum = start;
+    linenr_T	lnum_off;
+    int		did_one = FALSE;
+    linenr_T	first_lnum = MAXLNUM;
+    linenr_T	last_lnum = 0;
+
+    checkupdate(curwin);
+
+    while (lnum <= end)
+    {
+	/* Find the deepest fold for "start". */
+	gap = &curwin->w_folds;
+	found_ga = NULL;
+	lnum_off = 0;
+	for (;;)
+	{
+	    if (!foldFind(gap, lnum - lnum_off, &fp))
+		break;
+	    /* lnum is inside this fold, remember info */
+	    found_ga = gap;
+	    found_fp = fp;
+	    found_off = lnum_off;
+
+	    /* if "lnum" is folded, don't check nesting */
+	    if (check_closed(curwin, fp, &use_level, level,
+						      &maybe_small, lnum_off))
+		break;
+
+	    /* check nested folds */
+	    gap = &fp->fd_nested;
+	    lnum_off += fp->fd_top;
+	    ++level;
+	}
+	if (found_ga == NULL)
+	{
+	    ++lnum;
+	}
+	else
+	{
+	    lnum = found_fp->fd_top + found_fp->fd_len + found_off;
+	    did_one = TRUE;
+
+	    if (foldmethodIsManual(curwin))
+		deleteFoldEntry(found_ga,
+		    (int)(found_fp - (fold_T *)found_ga->ga_data), recursive);
+	    else
+	    {
+		if (found_fp->fd_top + found_off < first_lnum)
+		    first_lnum = found_fp->fd_top;
+		if (lnum > last_lnum)
+		    last_lnum = lnum;
+		parseMarker(curwin);
+		deleteFoldMarkers(found_fp, recursive, found_off);
+	    }
+
+	    /* redraw window */
+	    changed_window_setting();
+	}
+    }
+    if (!did_one)
+    {
+	EMSG(_(e_nofold));
+#ifdef FEAT_VISUAL
+	/* Force a redraw to remove the Visual highlighting. */
+	if (had_visual)
+	    redraw_curbuf_later(INVERTED);
+#endif
+    }
+    if (last_lnum > 0)
+	changed_lines(first_lnum, (colnr_T)0, last_lnum, 0L);
+}
+
+/* clearFolding() {{{2 */
+/*
+ * Remove all folding for window "win".
+ */
+    void
+clearFolding(win)
+    win_T	*win;
+{
+    deleteFoldRecurse(&win->w_folds);
+    win->w_foldinvalid = FALSE;
+}
+
+/* foldUpdate() {{{2 */
+/*
+ * Update folds for changes in the buffer of a window.
+ * Note that inserted/deleted lines must have already been taken care of by
+ * calling foldMarkAdjust().
+ * The changes in lines from top to bot (inclusive).
+ */
+    void
+foldUpdate(wp, top, bot)
+    win_T	*wp;
+    linenr_T	top;
+    linenr_T	bot;
+{
+    fold_T	*fp;
+
+    /* Mark all folds from top to bot as maybe-small. */
+    (void)foldFind(&curwin->w_folds, curwin->w_cursor.lnum, &fp);
+    while (fp < (fold_T *)curwin->w_folds.ga_data + curwin->w_folds.ga_len
+	    && fp->fd_top < bot)
+    {
+	fp->fd_small = MAYBE;
+	++fp;
+    }
+
+    if (foldmethodIsIndent(wp)
+	    || foldmethodIsExpr(wp)
+	    || foldmethodIsMarker(wp)
+#ifdef FEAT_DIFF
+	    || foldmethodIsDiff(wp)
+#endif
+	    || foldmethodIsSyntax(wp))
+	foldUpdateIEMS(wp, top, bot);
+}
+
+/* foldUpdateAll() {{{2 */
+/*
+ * Update all lines in a window for folding.
+ * Used when a fold setting changes or after reloading the buffer.
+ * The actual updating is postponed until fold info is used, to avoid doing
+ * every time a setting is changed or a syntax item is added.
+ */
+    void
+foldUpdateAll(win)
+    win_T	*win;
+{
+    win->w_foldinvalid = TRUE;
+    redraw_win_later(win, NOT_VALID);
+}
+
+/* foldMoveTo() {{{2 */
+/*
+ * If "updown" is FALSE: Move to the start or end of the fold.
+ * If "updown" is TRUE: move to fold at the same level.
+ * If not moved return FAIL.
+ */
+    int
+foldMoveTo(updown, dir, count)
+    int		updown;
+    int		dir;	    /* FORWARD or BACKWARD */
+    long	count;
+{
+    long	n;
+    int		retval = FAIL;
+    linenr_T	lnum_off;
+    linenr_T	lnum_found;
+    linenr_T	lnum;
+    int		use_level;
+    int		maybe_small;
+    garray_T	*gap;
+    fold_T	*fp;
+    int		level;
+    int		last;
+
+    checkupdate(curwin);
+
+    /* Repeat "count" times. */
+    for (n = 0; n < count; ++n)
+    {
+	/* Find nested folds.  Stop when a fold is closed.  The deepest fold
+	 * that moves the cursor is used. */
+	lnum_off = 0;
+	gap = &curwin->w_folds;
+	use_level = FALSE;
+	maybe_small = FALSE;
+	lnum_found = curwin->w_cursor.lnum;
+	level = 0;
+	last = FALSE;
+	for (;;)
+	{
+	    if (!foldFind(gap, curwin->w_cursor.lnum - lnum_off, &fp))
+	    {
+		if (!updown)
+		    break;
+
+		/* When moving up, consider a fold above the cursor; when
+		 * moving down consider a fold below the cursor. */
+		if (dir == FORWARD)
+		{
+		    if (fp - (fold_T *)gap->ga_data >= gap->ga_len)
+			break;
+		    --fp;
+		}
+		else
+		{
+		    if (fp == (fold_T *)gap->ga_data)
+			break;
+		}
+		/* don't look for contained folds, they will always move
+		 * the cursor too far. */
+		last = TRUE;
+	    }
+
+	    if (!last)
+	    {
+		/* Check if this fold is closed. */
+		if (check_closed(curwin, fp, &use_level, level,
+						      &maybe_small, lnum_off))
+		    last = TRUE;
+
+		/* "[z" and "]z" stop at closed fold */
+		if (last && !updown)
+		    break;
+	    }
+
+	    if (updown)
+	    {
+		if (dir == FORWARD)
+		{
+		    /* to start of next fold if there is one */
+		    if (fp + 1 - (fold_T *)gap->ga_data < gap->ga_len)
+		    {
+			lnum = fp[1].fd_top + lnum_off;
+			if (lnum > curwin->w_cursor.lnum)
+			    lnum_found = lnum;
+		    }
+		}
+		else
+		{
+		    /* to end of previous fold if there is one */
+		    if (fp > (fold_T *)gap->ga_data)
+		    {
+			lnum = fp[-1].fd_top + lnum_off + fp[-1].fd_len - 1;
+			if (lnum < curwin->w_cursor.lnum)
+			    lnum_found = lnum;
+		    }
+		}
+	    }
+	    else
+	    {
+		/* Open fold found, set cursor to its start/end and then check
+		 * nested folds. */
+		if (dir == FORWARD)
+		{
+		    lnum = fp->fd_top + lnum_off + fp->fd_len - 1;
+		    if (lnum > curwin->w_cursor.lnum)
+			lnum_found = lnum;
+		}
+		else
+		{
+		    lnum = fp->fd_top + lnum_off;
+		    if (lnum < curwin->w_cursor.lnum)
+			lnum_found = lnum;
+		}
+	    }
+
+	    if (last)
+		break;
+
+	    /* Check nested folds (if any). */
+	    gap = &fp->fd_nested;
+	    lnum_off += fp->fd_top;
+	    ++level;
+	}
+	if (lnum_found != curwin->w_cursor.lnum)
+	{
+	    if (retval == FAIL)
+		setpcmark();
+	    curwin->w_cursor.lnum = lnum_found;
+	    curwin->w_cursor.col = 0;
+	    retval = OK;
+	}
+	else
+	    break;
+    }
+
+    return retval;
+}
+
+/* foldInitWin() {{{2 */
+/*
+ * Init the fold info in a new window.
+ */
+    void
+foldInitWin(newwin)
+    win_T	*newwin;
+{
+    ga_init2(&newwin->w_folds, (int)sizeof(fold_T), 10);
+}
+
+/* find_wl_entry() {{{2 */
+/*
+ * Find an entry in the win->w_lines[] array for buffer line "lnum".
+ * Only valid entries are considered (for entries where wl_valid is FALSE the
+ * line number can be wrong).
+ * Returns index of entry or -1 if not found.
+ */
+    int
+find_wl_entry(win, lnum)
+    win_T	*win;
+    linenr_T	lnum;
+{
+    int		i;
+
+    if (win->w_lines_valid > 0)
+	for (i = 0; i < win->w_lines_valid; ++i)
+	    if (win->w_lines[i].wl_valid)
+	    {
+		if (lnum < win->w_lines[i].wl_lnum)
+		    return -1;
+		if (lnum <= win->w_lines[i].wl_lastlnum)
+		    return i;
+	    }
+    return -1;
+}
+
+/* foldAdjustVisual() {{{2 */
+#ifdef FEAT_VISUAL
+/*
+ * Adjust the Visual area to include any fold at the start or end completely.
+ */
+    void
+foldAdjustVisual()
+{
+    pos_T	*start, *end;
+    char_u	*ptr;
+
+    if (!VIsual_active || !hasAnyFolding(curwin))
+	return;
+
+    if (ltoreq(VIsual, curwin->w_cursor))
+    {
+	start = &VIsual;
+	end = &curwin->w_cursor;
+    }
+    else
+    {
+	start = &curwin->w_cursor;
+	end = &VIsual;
+    }
+    if (hasFolding(start->lnum, &start->lnum, NULL))
+	start->col = 0;
+    if (hasFolding(end->lnum, NULL, &end->lnum))
+    {
+	ptr = ml_get(end->lnum);
+	end->col = (colnr_T)STRLEN(ptr);
+	if (end->col > 0 && *p_sel == 'o')
+	    --end->col;
+#ifdef FEAT_MBYTE
+	/* prevent cursor from moving on the trail byte */
+	if (has_mbyte)
+	    mb_adjust_cursor();
+#endif
+    }
+}
+#endif
+
+/* cursor_foldstart() {{{2 */
+/*
+ * Move the cursor to the first line of a closed fold.
+ */
+    void
+foldAdjustCursor()
+{
+    (void)hasFolding(curwin->w_cursor.lnum, &curwin->w_cursor.lnum, NULL);
+}
+
+/* Internal functions for "fold_T" {{{1 */
+/* cloneFoldGrowArray() {{{2 */
+/*
+ * Will "clone" (i.e deep copy) a garray_T of folds.
+ *
+ * Return FAIL if the operation cannot be completed, otherwise OK.
+ */
+    void
+cloneFoldGrowArray(from, to)
+    garray_T	*from;
+    garray_T	*to;
+{
+    int		i;
+    fold_T	*from_p;
+    fold_T	*to_p;
+
+    ga_init2(to, from->ga_itemsize, from->ga_growsize);
+    if (from->ga_len == 0 || ga_grow(to, from->ga_len) == FAIL)
+	return;
+
+    from_p = (fold_T *)from->ga_data;
+    to_p = (fold_T *)to->ga_data;
+
+    for (i = 0; i < from->ga_len; i++)
+    {
+	to_p->fd_top = from_p->fd_top;
+	to_p->fd_len = from_p->fd_len;
+	to_p->fd_flags = from_p->fd_flags;
+	to_p->fd_small = from_p->fd_small;
+	cloneFoldGrowArray(&from_p->fd_nested, &to_p->fd_nested);
+	++to->ga_len;
+	++from_p;
+	++to_p;
+    }
+}
+
+/* foldFind() {{{2 */
+/*
+ * Search for line "lnum" in folds of growarray "gap".
+ * Set *fpp to the fold struct for the fold that contains "lnum" or
+ * the first fold below it (careful: it can be beyond the end of the array!).
+ * Returns FALSE when there is no fold that contains "lnum".
+ */
+    static int
+foldFind(gap, lnum, fpp)
+    garray_T	*gap;
+    linenr_T	lnum;
+    fold_T	**fpp;
+{
+    linenr_T	low, high;
+    fold_T	*fp;
+    int		i;
+
+    /*
+     * Perform a binary search.
+     * "low" is lowest index of possible match.
+     * "high" is highest index of possible match.
+     */
+    fp = (fold_T *)gap->ga_data;
+    low = 0;
+    high = gap->ga_len - 1;
+    while (low <= high)
+    {
+	i = (low + high) / 2;
+	if (fp[i].fd_top > lnum)
+	    /* fold below lnum, adjust high */
+	    high = i - 1;
+	else if (fp[i].fd_top + fp[i].fd_len <= lnum)
+	    /* fold above lnum, adjust low */
+	    low = i + 1;
+	else
+	{
+	    /* lnum is inside this fold */
+	    *fpp = fp + i;
+	    return TRUE;
+	}
+    }
+    *fpp = fp + low;
+    return FALSE;
+}
+
+/* foldLevelWin() {{{2 */
+/*
+ * Return fold level at line number "lnum" in window "wp".
+ */
+    static int
+foldLevelWin(wp, lnum)
+    win_T	*wp;
+    linenr_T	lnum;
+{
+    fold_T	*fp;
+    linenr_T	lnum_rel = lnum;
+    int		level =  0;
+    garray_T	*gap;
+
+    /* Recursively search for a fold that contains "lnum". */
+    gap = &wp->w_folds;
+    for (;;)
+    {
+	if (!foldFind(gap, lnum_rel, &fp))
+	    break;
+	/* Check nested folds.  Line number is relative to containing fold. */
+	gap = &fp->fd_nested;
+	lnum_rel -= fp->fd_top;
+	++level;
+    }
+
+    return level;
+}
+
+/* checkupdate() {{{2 */
+/*
+ * Check if the folds in window "wp" are invalid and update them if needed.
+ */
+    static void
+checkupdate(wp)
+    win_T	*wp;
+{
+    if (wp->w_foldinvalid)
+    {
+	foldUpdate(wp, (linenr_T)1, (linenr_T)MAXLNUM); /* will update all */
+	wp->w_foldinvalid = FALSE;
+    }
+}
+
+/* setFoldRepeat() {{{2 */
+/*
+ * Open or close fold for current window at line "lnum".
+ * Repeat "count" times.
+ */
+    static void
+setFoldRepeat(lnum, count, open)
+    linenr_T	lnum;
+    long	count;
+    int		open;
+{
+    int		done;
+    long	n;
+
+    for (n = 0; n < count; ++n)
+    {
+	done = DONE_NOTHING;
+	(void)setManualFold(lnum, open, FALSE, &done);
+	if (!(done & DONE_ACTION))
+	{
+	    /* Only give an error message when no fold could be opened. */
+	    if (n == 0 && !(done & DONE_FOLD))
+		EMSG(_(e_nofold));
+	    break;
+	}
+    }
+}
+
+/* setManualFold() {{{2 */
+/*
+ * Open or close the fold in the current window which contains "lnum".
+ * Also does this for other windows in diff mode when needed.
+ */
+    static linenr_T
+setManualFold(lnum, opening, recurse, donep)
+    linenr_T	lnum;
+    int		opening;    /* TRUE when opening, FALSE when closing */
+    int		recurse;    /* TRUE when closing/opening recursive */
+    int		*donep;
+{
+#ifdef FEAT_DIFF
+    if (foldmethodIsDiff(curwin) && curwin->w_p_scb)
+    {
+	win_T	    *wp;
+	linenr_T    dlnum;
+
+	/*
+	 * Do the same operation in other windows in diff mode.  Calculate the
+	 * line number from the diffs.
+	 */
+	FOR_ALL_WINDOWS(wp)
+	{
+	    if (wp != curwin && foldmethodIsDiff(wp) && wp->w_p_scb)
+	    {
+		dlnum = diff_lnum_win(curwin->w_cursor.lnum, wp);
+		if (dlnum != 0)
+		    (void)setManualFoldWin(wp, dlnum, opening, recurse, NULL);
+	    }
+	}
+    }
+#endif
+
+    return setManualFoldWin(curwin, lnum, opening, recurse, donep);
+}
+
+/* setManualFoldWin() {{{2 */
+/*
+ * Open or close the fold in window "wp" which contains "lnum".
+ * "donep", when not NULL, points to flag that is set to DONE_FOLD when some
+ * fold was found and to DONE_ACTION when some fold was opened or closed.
+ * When "donep" is NULL give an error message when no fold was found for
+ * "lnum", but only if "wp" is "curwin".
+ * Return the line number of the next line that could be closed.
+ * It's only valid when "opening" is TRUE!
+ */
+    static linenr_T
+setManualFoldWin(wp, lnum, opening, recurse, donep)
+    win_T	*wp;
+    linenr_T	lnum;
+    int		opening;    /* TRUE when opening, FALSE when closing */
+    int		recurse;    /* TRUE when closing/opening recursive */
+    int		*donep;
+{
+    fold_T	*fp;
+    fold_T	*fp2;
+    fold_T	*found = NULL;
+    int		j;
+    int		level = 0;
+    int		use_level = FALSE;
+    int		found_fold = FALSE;
+    garray_T	*gap;
+    linenr_T	next = MAXLNUM;
+    linenr_T	off = 0;
+    int		done = 0;
+
+    checkupdate(wp);
+
+    /*
+     * Find the fold, open or close it.
+     */
+    gap = &wp->w_folds;
+    for (;;)
+    {
+	if (!foldFind(gap, lnum, &fp))
+	{
+	    /* If there is a following fold, continue there next time. */
+	    if (fp < (fold_T *)gap->ga_data + gap->ga_len)
+		next = fp->fd_top + off;
+	    break;
+	}
+
+	/* lnum is inside this fold */
+	found_fold = TRUE;
+
+	/* If there is a following fold, continue there next time. */
+	if (fp + 1 < (fold_T *)gap->ga_data + gap->ga_len)
+	    next = fp[1].fd_top + off;
+
+	/* Change from level-dependent folding to manual. */
+	if (use_level || fp->fd_flags == FD_LEVEL)
+	{
+	    use_level = TRUE;
+	    if (level >= wp->w_p_fdl)
+		fp->fd_flags = FD_CLOSED;
+	    else
+		fp->fd_flags = FD_OPEN;
+	    fp2 = (fold_T *)fp->fd_nested.ga_data;
+	    for (j = 0; j < fp->fd_nested.ga_len; ++j)
+		fp2[j].fd_flags = FD_LEVEL;
+	}
+
+	/* Simple case: Close recursively means closing the fold. */
+	if (!opening && recurse)
+	{
+	    if (fp->fd_flags != FD_CLOSED)
+	    {
+		done |= DONE_ACTION;
+		fp->fd_flags = FD_CLOSED;
+	    }
+	}
+	else if (fp->fd_flags == FD_CLOSED)
+	{
+	    /* When opening, open topmost closed fold. */
+	    if (opening)
+	    {
+		fp->fd_flags = FD_OPEN;
+		done |= DONE_ACTION;
+		if (recurse)
+		    foldOpenNested(fp);
+	    }
+	    break;
+	}
+
+	/* fold is open, check nested folds */
+	found = fp;
+	gap = &fp->fd_nested;
+	lnum -= fp->fd_top;
+	off += fp->fd_top;
+	++level;
+    }
+    if (found_fold)
+    {
+	/* When closing and not recurse, close deepest open fold. */
+	if (!opening && found != NULL)
+	{
+	    found->fd_flags = FD_CLOSED;
+	    done |= DONE_ACTION;
+	}
+	wp->w_fold_manual = TRUE;
+	if (done & DONE_ACTION)
+	    changed_window_setting_win(wp);
+	done |= DONE_FOLD;
+    }
+    else if (donep == NULL && wp == curwin)
+	EMSG(_(e_nofold));
+
+    if (donep != NULL)
+	*donep |= done;
+
+    return next;
+}
+
+/* foldOpenNested() {{{2 */
+/*
+ * Open all nested folds in fold "fpr" recursively.
+ */
+    static void
+foldOpenNested(fpr)
+    fold_T	*fpr;
+{
+    int		i;
+    fold_T	*fp;
+
+    fp = (fold_T *)fpr->fd_nested.ga_data;
+    for (i = 0; i < fpr->fd_nested.ga_len; ++i)
+    {
+	foldOpenNested(&fp[i]);
+	fp[i].fd_flags = FD_OPEN;
+    }
+}
+
+/* deleteFoldEntry() {{{2 */
+/*
+ * Delete fold "idx" from growarray "gap".
+ * When "recursive" is TRUE also delete all the folds contained in it.
+ * When "recursive" is FALSE contained folds are moved one level up.
+ */
+    static void
+deleteFoldEntry(gap, idx, recursive)
+    garray_T	*gap;
+    int		idx;
+    int		recursive;
+{
+    fold_T	*fp;
+    int		i;
+    long	moved;
+    fold_T	*nfp;
+
+    fp = (fold_T *)gap->ga_data + idx;
+    if (recursive || fp->fd_nested.ga_len == 0)
+    {
+	/* recursively delete the contained folds */
+	deleteFoldRecurse(&fp->fd_nested);
+	--gap->ga_len;
+	if (idx < gap->ga_len)
+	    mch_memmove(fp, fp + 1, sizeof(fold_T) * (gap->ga_len - idx));
+    }
+    else
+    {
+	/* move nested folds one level up, to overwrite the fold that is
+	 * deleted. */
+	moved = fp->fd_nested.ga_len;
+	if (ga_grow(gap, (int)(moved - 1)) == OK)
+	{
+	    /* adjust fd_top and fd_flags for the moved folds */
+	    nfp = (fold_T *)fp->fd_nested.ga_data;
+	    for (i = 0; i < moved; ++i)
+	    {
+		nfp[i].fd_top += fp->fd_top;
+		if (fp->fd_flags == FD_LEVEL)
+		    nfp[i].fd_flags = FD_LEVEL;
+		if (fp->fd_small == MAYBE)
+		    nfp[i].fd_small = MAYBE;
+	    }
+
+	    /* move the existing folds down to make room */
+	    if (idx < gap->ga_len)
+		mch_memmove(fp + moved, fp + 1,
+					sizeof(fold_T) * (gap->ga_len - idx));
+	    /* move the contained folds one level up */
+	    mch_memmove(fp, nfp, (size_t)(sizeof(fold_T) * moved));
+	    vim_free(nfp);
+	    gap->ga_len += moved - 1;
+	}
+    }
+}
+
+/* deleteFoldRecurse() {{{2 */
+/*
+ * Delete nested folds in a fold.
+ */
+    void
+deleteFoldRecurse(gap)
+    garray_T	*gap;
+{
+    int		i;
+
+    for (i = 0; i < gap->ga_len; ++i)
+	deleteFoldRecurse(&(((fold_T *)(gap->ga_data))[i].fd_nested));
+    ga_clear(gap);
+}
+
+/* foldMarkAdjust() {{{2 */
+/*
+ * Update line numbers of folds for inserted/deleted lines.
+ */
+    void
+foldMarkAdjust(wp, line1, line2, amount, amount_after)
+    win_T	*wp;
+    linenr_T	line1;
+    linenr_T	line2;
+    long	amount;
+    long	amount_after;
+{
+    /* If deleting marks from line1 to line2, but not deleting all those
+     * lines, set line2 so that only deleted lines have their folds removed. */
+    if (amount == MAXLNUM && line2 >= line1 && line2 - line1 >= -amount_after)
+	line2 = line1 - amount_after - 1;
+    /* If appending a line in Insert mode, it should be included in the fold
+     * just above the line. */
+    if ((State & INSERT) && amount == (linenr_T)1 && line2 == MAXLNUM)
+	--line1;
+    foldMarkAdjustRecurse(&wp->w_folds, line1, line2, amount, amount_after);
+}
+
+/* foldMarkAdjustRecurse() {{{2 */
+    static void
+foldMarkAdjustRecurse(gap, line1, line2, amount, amount_after)
+    garray_T	*gap;
+    linenr_T	line1;
+    linenr_T	line2;
+    long	amount;
+    long	amount_after;
+{
+    fold_T	*fp;
+    int		i;
+    linenr_T	last;
+    linenr_T	top;
+
+    /* In Insert mode an inserted line at the top of a fold is considered part
+     * of the fold, otherwise it isn't. */
+    if ((State & INSERT) && amount == (linenr_T)1 && line2 == MAXLNUM)
+	top = line1 + 1;
+    else
+	top = line1;
+
+    /* Find the fold containing or just below "line1". */
+    (void)foldFind(gap, line1, &fp);
+
+    /*
+     * Adjust all folds below "line1" that are affected.
+     */
+    for (i = (int)(fp - (fold_T *)gap->ga_data); i < gap->ga_len; ++i, ++fp)
+    {
+	/*
+	 * Check for these situations:
+	 *	  1  2	3
+	 *	  1  2	3
+	 * line1     2	3  4  5
+	 *	     2	3  4  5
+	 *	     2	3  4  5
+	 * line2     2	3  4  5
+	 *		3     5  6
+	 *		3     5  6
+	 */
+
+	last = fp->fd_top + fp->fd_len - 1; /* last line of fold */
+
+	/* 1. fold completely above line1: nothing to do */
+	if (last < line1)
+	    continue;
+
+	/* 6. fold below line2: only adjust for amount_after */
+	if (fp->fd_top > line2)
+	{
+	    if (amount_after == 0)
+		break;
+	    fp->fd_top += amount_after;
+	}
+	else
+	{
+	    if (fp->fd_top >= top && last <= line2)
+	    {
+		/* 4. fold completely contained in range */
+		if (amount == MAXLNUM)
+		{
+		    /* Deleting lines: delete the fold completely */
+		    deleteFoldEntry(gap, i, TRUE);
+		    --i;    /* adjust index for deletion */
+		    --fp;
+		}
+		else
+		    fp->fd_top += amount;
+	    }
+	    else
+	    {
+		/* 2, 3, or 5: need to correct nested folds too */
+		foldMarkAdjustRecurse(&fp->fd_nested, line1 - fp->fd_top,
+				  line2 - fp->fd_top, amount, amount_after);
+		if (fp->fd_top < top)
+		{
+		    if (last <= line2)
+		    {
+			/* 2. fold contains line1, line2 is below fold */
+			if (amount == MAXLNUM)
+			    fp->fd_len = line1 - fp->fd_top;
+			else
+			    fp->fd_len += amount;
+		    }
+		    else
+		    {
+			/* 3. fold contains line1 and line2 */
+			fp->fd_len += amount_after;
+		    }
+		}
+		else
+		{
+		    /* 5. fold is below line1 and contains line2 */
+		    if (amount == MAXLNUM)
+		    {
+			fp->fd_len -= line2 - fp->fd_top + 1;
+			fp->fd_top = line1;
+		    }
+		    else
+		    {
+			fp->fd_len += amount_after - amount;
+			fp->fd_top += amount;
+		    }
+		}
+	    }
+	}
+    }
+}
+
+/* getDeepestNesting() {{{2 */
+/*
+ * Get the lowest 'foldlevel' value that makes the deepest nested fold in the
+ * current window open.
+ */
+    int
+getDeepestNesting()
+{
+    checkupdate(curwin);
+    return getDeepestNestingRecurse(&curwin->w_folds);
+}
+
+    static int
+getDeepestNestingRecurse(gap)
+    garray_T	*gap;
+{
+    int		i;
+    int		level;
+    int		maxlevel = 0;
+    fold_T	*fp;
+
+    fp = (fold_T *)gap->ga_data;
+    for (i = 0; i < gap->ga_len; ++i)
+    {
+	level = getDeepestNestingRecurse(&fp[i].fd_nested) + 1;
+	if (level > maxlevel)
+	    maxlevel = level;
+    }
+
+    return maxlevel;
+}
+
+/* check_closed() {{{2 */
+/*
+ * Check if a fold is closed and update the info needed to check nested folds.
+ */
+    static int
+check_closed(win, fp, use_levelp, level, maybe_smallp, lnum_off)
+    win_T	*win;
+    fold_T	*fp;
+    int		*use_levelp;	    /* TRUE: outer fold had FD_LEVEL */
+    int		level;		    /* folding depth */
+    int		*maybe_smallp;	    /* TRUE: outer this had fd_small == MAYBE */
+    linenr_T	lnum_off;	    /* line number offset for fp->fd_top */
+{
+    int		closed = FALSE;
+
+    /* Check if this fold is closed.  If the flag is FD_LEVEL this
+     * fold and all folds it contains depend on 'foldlevel'. */
+    if (*use_levelp || fp->fd_flags == FD_LEVEL)
+    {
+	*use_levelp = TRUE;
+	if (level >= win->w_p_fdl)
+	    closed = TRUE;
+    }
+    else if (fp->fd_flags == FD_CLOSED)
+	closed = TRUE;
+
+    /* Small fold isn't closed anyway. */
+    if (fp->fd_small == MAYBE)
+	*maybe_smallp = TRUE;
+    if (closed)
+    {
+	if (*maybe_smallp)
+	    fp->fd_small = MAYBE;
+	checkSmall(win, fp, lnum_off);
+	if (fp->fd_small == TRUE)
+	    closed = FALSE;
+    }
+    return closed;
+}
+
+/* checkSmall() {{{2 */
+/*
+ * Update fd_small field of fold "fp".
+ */
+    static void
+checkSmall(wp, fp, lnum_off)
+    win_T	*wp;
+    fold_T	*fp;
+    linenr_T	lnum_off;	/* offset for fp->fd_top */
+{
+    int		count;
+    int		n;
+
+    if (fp->fd_small == MAYBE)
+    {
+	/* Mark any nested folds to maybe-small */
+	setSmallMaybe(&fp->fd_nested);
+
+	if (fp->fd_len > curwin->w_p_fml)
+	    fp->fd_small = FALSE;
+	else
+	{
+	    count = 0;
+	    for (n = 0; n < fp->fd_len; ++n)
+	    {
+		count += plines_win_nofold(wp, fp->fd_top + lnum_off + n);
+		if (count > curwin->w_p_fml)
+		{
+		    fp->fd_small = FALSE;
+		    return;
+		}
+	    }
+	    fp->fd_small = TRUE;
+	}
+    }
+}
+
+/* setSmallMaybe() {{{2 */
+/*
+ * Set small flags in "gap" to MAYBE.
+ */
+    static void
+setSmallMaybe(gap)
+    garray_T	*gap;
+{
+    int		i;
+    fold_T	*fp;
+
+    fp = (fold_T *)gap->ga_data;
+    for (i = 0; i < gap->ga_len; ++i)
+	fp[i].fd_small = MAYBE;
+}
+
+/* foldCreateMarkers() {{{2 */
+/*
+ * Create a fold from line "start" to line "end" (inclusive) in the current
+ * window by adding markers.
+ */
+    static void
+foldCreateMarkers(start, end)
+    linenr_T	start;
+    linenr_T	end;
+{
+    if (!curbuf->b_p_ma)
+    {
+	EMSG(_(e_modifiable));
+	return;
+    }
+    parseMarker(curwin);
+
+    foldAddMarker(start, curwin->w_p_fmr, foldstartmarkerlen);
+    foldAddMarker(end, foldendmarker, foldendmarkerlen);
+
+    /* Update both changes here, to avoid all folds after the start are
+     * changed when the start marker is inserted and the end isn't. */
+    changed_lines(start, (colnr_T)0, end, 0L);
+}
+
+/* foldAddMarker() {{{2 */
+/*
+ * Add "marker[markerlen]" in 'commentstring' to line "lnum".
+ */
+    static void
+foldAddMarker(lnum, marker, markerlen)
+    linenr_T	lnum;
+    char_u	*marker;
+    int		markerlen;
+{
+    char_u	*cms = curbuf->b_p_cms;
+    char_u	*line;
+    int		line_len;
+    char_u	*newline;
+    char_u	*p = (char_u *)strstr((char *)curbuf->b_p_cms, "%s");
+
+    /* Allocate a new line: old-line + 'cms'-start + marker + 'cms'-end */
+    line = ml_get(lnum);
+    line_len = (int)STRLEN(line);
+
+    if (u_save(lnum - 1, lnum + 1) == OK)
+    {
+	newline = alloc((unsigned)(line_len + markerlen + STRLEN(cms) + 1));
+	if (newline == NULL)
+	    return;
+	STRCPY(newline, line);
+	if (p == NULL)
+	    vim_strncpy(newline + line_len, marker, markerlen);
+	else
+	{
+	    STRCPY(newline + line_len, cms);
+	    STRNCPY(newline + line_len + (p - cms), marker, markerlen);
+	    STRCPY(newline + line_len + (p - cms) + markerlen, p + 2);
+	}
+
+	ml_replace(lnum, newline, FALSE);
+    }
+}
+
+/* deleteFoldMarkers() {{{2 */
+/*
+ * Delete the markers for a fold, causing it to be deleted.
+ */
+    static void
+deleteFoldMarkers(fp, recursive, lnum_off)
+    fold_T	*fp;
+    int		recursive;
+    linenr_T	lnum_off;	/* offset for fp->fd_top */
+{
+    int		i;
+
+    if (recursive)
+	for (i = 0; i < fp->fd_nested.ga_len; ++i)
+	    deleteFoldMarkers((fold_T *)fp->fd_nested.ga_data + i, TRUE,
+						       lnum_off + fp->fd_top);
+    foldDelMarker(fp->fd_top + lnum_off, curwin->w_p_fmr, foldstartmarkerlen);
+    foldDelMarker(fp->fd_top + lnum_off + fp->fd_len - 1,
+					     foldendmarker, foldendmarkerlen);
+}
+
+/* foldDelMarker() {{{2 */
+/*
+ * Delete marker "marker[markerlen]" at the end of line "lnum".
+ * Delete 'commentstring' if it matches.
+ * If the marker is not found, there is no error message.  Could a missing
+ * close-marker.
+ */
+    static void
+foldDelMarker(lnum, marker, markerlen)
+    linenr_T	lnum;
+    char_u	*marker;
+    int		markerlen;
+{
+    char_u	*line;
+    char_u	*newline;
+    char_u	*p;
+    int		len;
+    char_u	*cms = curbuf->b_p_cms;
+    char_u	*cms2;
+
+    line = ml_get(lnum);
+    for (p = line; *p != NUL; ++p)
+	if (STRNCMP(p, marker, markerlen) == 0)
+	{
+	    /* Found the marker, include a digit if it's there. */
+	    len = markerlen;
+	    if (VIM_ISDIGIT(p[len]))
+		++len;
+	    if (*cms != NUL)
+	    {
+		/* Also delete 'commentstring' if it matches. */
+		cms2 = (char_u *)strstr((char *)cms, "%s");
+		if (p - line >= cms2 - cms
+			&& STRNCMP(p - (cms2 - cms), cms, cms2 - cms) == 0
+			&& STRNCMP(p + len, cms2 + 2, STRLEN(cms2 + 2)) == 0)
+		{
+		    p -= cms2 - cms;
+		    len += (int)STRLEN(cms) - 2;
+		}
+	    }
+	    if (u_save(lnum - 1, lnum + 1) == OK)
+	    {
+		/* Make new line: text-before-marker + text-after-marker */
+		newline = alloc((unsigned)(STRLEN(line) - len + 1));
+		if (newline != NULL)
+		{
+		    STRNCPY(newline, line, p - line);
+		    STRCPY(newline + (p - line), p + len);
+		    ml_replace(lnum, newline, FALSE);
+		}
+	    }
+	    break;
+	}
+}
+
+/* get_foldtext() {{{2 */
+/*
+ * Return the text for a closed fold at line "lnum", with last line "lnume".
+ * When 'foldtext' isn't set puts the result in "buf[51]".  Otherwise the
+ * result is in allocated memory.
+ */
+    char_u *
+get_foldtext(wp, lnum, lnume, foldinfo, buf)
+    win_T	*wp;
+    linenr_T	lnum, lnume;
+    foldinfo_T	*foldinfo;
+    char_u	*buf;
+{
+    char_u	*text = NULL;
+
+#ifdef FEAT_EVAL
+    if (*wp->w_p_fdt != NUL)
+    {
+	char_u	dashes[51];
+	win_T	*save_curwin;
+	int	level;
+	char_u	*p;
+
+	/* Set "v:foldstart" and "v:foldend". */
+	set_vim_var_nr(VV_FOLDSTART, lnum);
+	set_vim_var_nr(VV_FOLDEND, lnume);
+
+	/* Set "v:folddashes" to a string of "level" dashes. */
+	/* Set "v:foldlevel" to "level". */
+	level = foldinfo->fi_level;
+	if (level > 50)
+	    level = 50;
+	vim_memset(dashes, '-', (size_t)level);
+	dashes[level] = NUL;
+	set_vim_var_string(VV_FOLDDASHES, dashes, -1);
+	set_vim_var_nr(VV_FOLDLEVEL, (long)level);
+	save_curwin = curwin;
+	curwin = wp;
+	curbuf = wp->w_buffer;
+
+	++emsg_off;
+	text = eval_to_string_safe(wp->w_p_fdt, NULL,
+			 was_set_insecurely((char_u *)"foldtext", OPT_LOCAL));
+	--emsg_off;
+
+	curwin = save_curwin;
+	curbuf = curwin->w_buffer;
+	set_vim_var_string(VV_FOLDDASHES, NULL, -1);
+
+	if (text != NULL)
+	{
+	    /* Replace unprintable characters, if there are any.  But
+	     * replace a TAB with a space. */
+	    for (p = text; *p != NUL; ++p)
+	    {
+# ifdef FEAT_MBYTE
+		int	len;
+
+		if (has_mbyte && (len = (*mb_ptr2len)(p)) > 1)
+		{
+		    if (!vim_isprintc((*mb_ptr2char)(p)))
+			break;
+		    p += len - 1;
+		}
+		else
+# endif
+		    if (*p == TAB)
+			*p = ' ';
+		    else if (ptr2cells(p) > 1)
+			break;
+	    }
+	    if (*p != NUL)
+	    {
+		p = transstr(text);
+		vim_free(text);
+		text = p;
+	    }
+	}
+    }
+    if (text == NULL)
+#endif
+    {
+	sprintf((char *)buf, _("+--%3ld lines folded "),
+						    (long)(lnume - lnum + 1));
+	text = buf;
+    }
+    return text;
+}
+
+/* foldtext_cleanup() {{{2 */
+/*
+ * Remove 'foldmarker' and 'commentstring' from "str" (in-place).
+ */
+    void
+foldtext_cleanup(str)
+    char_u	*str;
+{
+    char_u	*cms_start;	/* first part or the whole comment */
+    int		cms_slen = 0;	/* length of cms_start */
+    char_u	*cms_end;	/* last part of the comment or NULL */
+    int		cms_elen = 0;	/* length of cms_end */
+    char_u	*s;
+    char_u	*p;
+    int		len;
+    int		did1 = FALSE;
+    int		did2 = FALSE;
+
+    /* Ignore leading and trailing white space in 'commentstring'. */
+    cms_start = skipwhite(curbuf->b_p_cms);
+    cms_slen = (int)STRLEN(cms_start);
+    while (cms_slen > 0 && vim_iswhite(cms_start[cms_slen - 1]))
+	--cms_slen;
+
+    /* locate "%s" in 'commentstring', use the part before and after it. */
+    cms_end = (char_u *)strstr((char *)cms_start, "%s");
+    if (cms_end != NULL)
+    {
+	cms_elen = cms_slen - (int)(cms_end - cms_start);
+	cms_slen = (int)(cms_end - cms_start);
+
+	/* exclude white space before "%s" */
+	while (cms_slen > 0 && vim_iswhite(cms_start[cms_slen - 1]))
+	    --cms_slen;
+
+	/* skip "%s" and white space after it */
+	s = skipwhite(cms_end + 2);
+	cms_elen -= (int)(s - cms_end);
+	cms_end = s;
+    }
+    parseMarker(curwin);
+
+    for (s = str; *s != NUL; )
+    {
+	len = 0;
+	if (STRNCMP(s, curwin->w_p_fmr, foldstartmarkerlen) == 0)
+	    len = foldstartmarkerlen;
+	else if (STRNCMP(s, foldendmarker, foldendmarkerlen) == 0)
+	    len = foldendmarkerlen;
+	if (len > 0)
+	{
+	    if (VIM_ISDIGIT(s[len]))
+		++len;
+
+	    /* May remove 'commentstring' start.  Useful when it's a double
+	     * quote and we already removed a double quote. */
+	    for (p = s; p > str && vim_iswhite(p[-1]); --p)
+		;
+	    if (p >= str + cms_slen
+			   && STRNCMP(p - cms_slen, cms_start, cms_slen) == 0)
+	    {
+		len += (int)(s - p) + cms_slen;
+		s = p - cms_slen;
+	    }
+	}
+	else if (cms_end != NULL)
+	{
+	    if (!did1 && cms_slen > 0 && STRNCMP(s, cms_start, cms_slen) == 0)
+	    {
+		len = cms_slen;
+		did1 = TRUE;
+	    }
+	    else if (!did2 && cms_elen > 0
+					&& STRNCMP(s, cms_end, cms_elen) == 0)
+	    {
+		len = cms_elen;
+		did2 = TRUE;
+	    }
+	}
+	if (len != 0)
+	{
+	    while (vim_iswhite(s[len]))
+		++len;
+	    mch_memmove(s, s + len, STRLEN(s + len) + 1);
+	}
+	else
+	{
+	    mb_ptr_adv(s);
+	}
+    }
+}
+
+/* Folding by indent, expr, marker and syntax. {{{1 */
+/* Define "fline_T", passed to get fold level for a line. {{{2 */
+typedef struct
+{
+    win_T	*wp;		/* window */
+    linenr_T	lnum;		/* current line number */
+    linenr_T	off;		/* offset between lnum and real line number */
+    linenr_T	lnum_save;	/* line nr used by foldUpdateIEMSRecurse() */
+    int		lvl;		/* current level (-1 for undefined) */
+    int		lvl_next;	/* level used for next line */
+    int		start;		/* number of folds that are forced to start at
+				   this line. */
+    int		end;		/* level of fold that is forced to end below
+				   this line */
+    int		had_end;	/* level of fold that is forced to end above
+				   this line (copy of "end" of prev. line) */
+} fline_T;
+
+/* Flag is set when redrawing is needed. */
+static int fold_changed;
+
+/* Function declarations. {{{2 */
+static linenr_T foldUpdateIEMSRecurse __ARGS((garray_T *gap, int level, linenr_T startlnum, fline_T *flp, void (*getlevel)__ARGS((fline_T *)), linenr_T bot, int topflags));
+static int foldInsert __ARGS((garray_T *gap, int i));
+static void foldSplit __ARGS((garray_T *gap, int i, linenr_T top, linenr_T bot));
+static void foldRemove __ARGS((garray_T *gap, linenr_T top, linenr_T bot));
+static void foldMerge __ARGS((fold_T *fp1, garray_T *gap, fold_T *fp2));
+static void foldlevelIndent __ARGS((fline_T *flp));
+#ifdef FEAT_DIFF
+static void foldlevelDiff __ARGS((fline_T *flp));
+#endif
+static void foldlevelExpr __ARGS((fline_T *flp));
+static void foldlevelMarker __ARGS((fline_T *flp));
+static void foldlevelSyntax __ARGS((fline_T *flp));
+
+/* foldUpdateIEMS() {{{2 */
+/*
+ * Update the folding for window "wp", at least from lines "top" to "bot".
+ * Return TRUE if any folds did change.
+ */
+    static void
+foldUpdateIEMS(wp, top, bot)
+    win_T	*wp;
+    linenr_T	top;
+    linenr_T	bot;
+{
+    linenr_T	start;
+    linenr_T	end;
+    fline_T	fline;
+    void	(*getlevel)__ARGS((fline_T *));
+    int		level;
+    fold_T	*fp;
+
+    /* Avoid problems when being called recursively. */
+    if (invalid_top != (linenr_T)0)
+	return;
+
+    if (wp->w_foldinvalid)
+    {
+	/* Need to update all folds. */
+	top = 1;
+	bot = wp->w_buffer->b_ml.ml_line_count;
+	wp->w_foldinvalid = FALSE;
+
+	/* Mark all folds a maybe-small. */
+	setSmallMaybe(&wp->w_folds);
+    }
+
+#ifdef FEAT_DIFF
+    /* add the context for "diff" folding */
+    if (foldmethodIsDiff(wp))
+    {
+	if (top > diff_context)
+	    top -= diff_context;
+	else
+	    top = 1;
+	bot += diff_context;
+    }
+#endif
+
+    /* When deleting lines at the end of the buffer "top" can be past the end
+     * of the buffer. */
+    if (top > wp->w_buffer->b_ml.ml_line_count)
+	top = wp->w_buffer->b_ml.ml_line_count;
+
+    fold_changed = FALSE;
+    fline.wp = wp;
+    fline.off = 0;
+    fline.lvl = 0;
+    fline.lvl_next = -1;
+    fline.start = 0;
+    fline.end = MAX_LEVEL + 1;
+    fline.had_end = MAX_LEVEL + 1;
+
+    invalid_top = top;
+    invalid_bot = bot;
+
+    if (foldmethodIsMarker(wp))
+    {
+	getlevel = foldlevelMarker;
+
+	/* Init marker variables to speed up foldlevelMarker(). */
+	parseMarker(wp);
+
+	/* Need to get the level of the line above top, it is used if there is
+	 * no marker at the top. */
+	if (top > 1)
+	{
+	    /* Get the fold level at top - 1. */
+	    level = foldLevelWin(wp, top - 1);
+
+	    /* The fold may end just above the top, check for that. */
+	    fline.lnum = top - 1;
+	    fline.lvl = level;
+	    getlevel(&fline);
+
+	    /* If a fold started here, we already had the level, if it stops
+	     * here, we need to use lvl_next.  Could also start and end a fold
+	     * in the same line. */
+	    if (fline.lvl > level)
+		fline.lvl = level - (fline.lvl - fline.lvl_next);
+	    else
+		fline.lvl = fline.lvl_next;
+	}
+	fline.lnum = top;
+	getlevel(&fline);
+    }
+    else
+    {
+	fline.lnum = top;
+	if (foldmethodIsExpr(wp))
+	{
+	    getlevel = foldlevelExpr;
+	    /* start one line back, because a "<1" may indicate the end of a
+	     * fold in the topline */
+	    if (top > 1)
+		--fline.lnum;
+	}
+	else if (foldmethodIsSyntax(wp))
+	    getlevel = foldlevelSyntax;
+#ifdef FEAT_DIFF
+	else if (foldmethodIsDiff(wp))
+	    getlevel = foldlevelDiff;
+#endif
+	else
+	    getlevel = foldlevelIndent;
+
+	/* Backup to a line for which the fold level is defined.  Since it's
+	 * always defined for line one, we will stop there. */
+	fline.lvl = -1;
+	for ( ; !got_int; --fline.lnum)
+	{
+	    /* Reset lvl_next each time, because it will be set to a value for
+	     * the next line, but we search backwards here. */
+	    fline.lvl_next = -1;
+	    getlevel(&fline);
+	    if (fline.lvl >= 0)
+		break;
+	}
+    }
+
+    start = fline.lnum;
+    end = bot;
+    /* Do at least one line. */
+    if (start > end && end < wp->w_buffer->b_ml.ml_line_count)
+	end = start;
+    while (!got_int)
+    {
+	/* Always stop at the end of the file ("end" can be past the end of
+	 * the file). */
+	if (fline.lnum > wp->w_buffer->b_ml.ml_line_count)
+	    break;
+	if (fline.lnum > end)
+	{
+	    /* For "marker", "expr"  and "syntax"  methods: If a change caused
+	     * a fold to be removed, we need to continue at least until where
+	     * it ended. */
+	    if (getlevel != foldlevelMarker
+		    && getlevel != foldlevelSyntax
+		    && getlevel != foldlevelExpr)
+		break;
+	    if ((start <= end
+			&& foldFind(&wp->w_folds, end, &fp)
+			&& fp->fd_top + fp->fd_len - 1 > end)
+		    || (fline.lvl == 0
+			&& foldFind(&wp->w_folds, fline.lnum, &fp)
+			&& fp->fd_top < fline.lnum))
+		end = fp->fd_top + fp->fd_len - 1;
+	    else if (getlevel == foldlevelSyntax
+		    && foldLevelWin(wp, fline.lnum) != fline.lvl)
+		/* For "syntax" method: Compare the foldlevel that the syntax
+		 * tells us to the foldlevel from the existing folds.  If they
+		 * don't match continue updating folds. */
+		end = fline.lnum;
+	    else
+		break;
+	}
+
+	/* A level 1 fold starts at a line with foldlevel > 0. */
+	if (fline.lvl > 0)
+	{
+	    invalid_top = fline.lnum;
+	    invalid_bot = end;
+	    end = foldUpdateIEMSRecurse(&wp->w_folds,
+				   1, start, &fline, getlevel, end, FD_LEVEL);
+	    start = fline.lnum;
+	}
+	else
+	{
+	    if (fline.lnum == wp->w_buffer->b_ml.ml_line_count)
+		break;
+	    ++fline.lnum;
+	    fline.lvl = fline.lvl_next;
+	    getlevel(&fline);
+	}
+    }
+
+    /* There can't be any folds from start until end now. */
+    foldRemove(&wp->w_folds, start, end);
+
+    /* If some fold changed, need to redraw and position cursor. */
+    if (fold_changed && wp->w_p_fen)
+	changed_window_setting();
+
+    /* If we updated folds past "bot", need to redraw more lines.  Don't do
+     * this in other situations, the changed lines will be redrawn anyway and
+     * this method can cause the whole window to be updated. */
+    if (end != bot)
+    {
+	if (wp->w_redraw_top == 0 || wp->w_redraw_top > top)
+	    wp->w_redraw_top = top;
+	if (wp->w_redraw_bot < end)
+	    wp->w_redraw_bot = end;
+    }
+
+    invalid_top = (linenr_T)0;
+}
+
+/* foldUpdateIEMSRecurse() {{{2 */
+/*
+ * Update a fold that starts at "flp->lnum".  At this line there is always a
+ * valid foldlevel, and its level >= "level".
+ * "flp" is valid for "flp->lnum" when called and it's valid when returning.
+ * "flp->lnum" is set to the lnum just below the fold, if it ends before
+ * "bot", it's "bot" plus one if the fold continues and it's bigger when using
+ * the marker method and a text change made following folds to change.
+ * When returning, "flp->lnum_save" is the line number that was used to get
+ * the level when the level at "flp->lnum" is invalid.
+ * Remove any folds from "startlnum" up to here at this level.
+ * Recursively update nested folds.
+ * Below line "bot" there are no changes in the text.
+ * "flp->lnum", "flp->lnum_save" and "bot" are relative to the start of the
+ * outer fold.
+ * "flp->off" is the offset to the real line number in the buffer.
+ *
+ * All this would be a lot simpler if all folds in the range would be deleted
+ * and then created again.  But we would loose all information about the
+ * folds, even when making changes that don't affect the folding (e.g. "vj~").
+ *
+ * Returns bot, which may have been increased for lines that also need to be
+ * updated as a result of a detected change in the fold.
+ */
+    static linenr_T
+foldUpdateIEMSRecurse(gap, level, startlnum, flp, getlevel, bot, topflags)
+    garray_T	*gap;
+    int		level;
+    linenr_T	startlnum;
+    fline_T	*flp;
+    void	(*getlevel)__ARGS((fline_T *));
+    linenr_T	bot;
+    int		topflags;	/* flags used by containing fold */
+{
+    linenr_T	ll;
+    fold_T	*fp = NULL;
+    fold_T	*fp2;
+    int		lvl = level;
+    linenr_T	startlnum2 = startlnum;
+    linenr_T	firstlnum = flp->lnum;	/* first lnum we got */
+    int		i;
+    int		finish = FALSE;
+    linenr_T	linecount = flp->wp->w_buffer->b_ml.ml_line_count - flp->off;
+    int		concat;
+
+    /*
+     * If using the marker method, the start line is not the start of a fold
+     * at the level we're dealing with and the level is non-zero, we must use
+     * the previous fold.  But ignore a fold that starts at or below
+     * startlnum, it must be deleted.
+     */
+    if (getlevel == foldlevelMarker && flp->start <= flp->lvl - level
+							      && flp->lvl > 0)
+    {
+	foldFind(gap, startlnum - 1, &fp);
+	if (fp >= ((fold_T *)gap->ga_data) + gap->ga_len
+						   || fp->fd_top >= startlnum)
+	    fp = NULL;
+    }
+
+    /*
+     * Loop over all lines in this fold, or until "bot" is hit.
+     * Handle nested folds inside of this fold.
+     * "flp->lnum" is the current line.  When finding the end of the fold, it
+     * is just below the end of the fold.
+     * "*flp" contains the level of the line "flp->lnum" or a following one if
+     * there are lines with an invalid fold level.  "flp->lnum_save" is the
+     * line number that was used to get the fold level (below "flp->lnum" when
+     * it has an invalid fold level).  When called the fold level is always
+     * valid, thus "flp->lnum_save" is equal to "flp->lnum".
+     */
+    flp->lnum_save = flp->lnum;
+    while (!got_int)
+    {
+	/* Updating folds can be slow, check for CTRL-C. */
+	line_breakcheck();
+
+	/* Set "lvl" to the level of line "flp->lnum".  When flp->start is set
+	 * and after the first line of the fold, set the level to zero to
+	 * force the fold to end.  Do the same when had_end is set: Previous
+	 * line was marked as end of a fold. */
+	lvl = flp->lvl;
+	if (lvl > MAX_LEVEL)
+	    lvl = MAX_LEVEL;
+	if (flp->lnum > firstlnum
+		&& (level > lvl - flp->start || level >= flp->had_end))
+	    lvl = 0;
+
+	if (flp->lnum > bot && !finish && fp != NULL)
+	{
+	    /* For "marker" and "syntax" methods:
+	     * - If a change caused a nested fold to be removed, we need to
+	     *   delete it and continue at least until where it ended.
+	     * - If a change caused a nested fold to be created, or this fold
+	     *   to continue below its original end, need to finish this fold.
+	     */
+	    if (getlevel != foldlevelMarker
+		    && getlevel != foldlevelExpr
+		    && getlevel != foldlevelSyntax)
+		break;
+	    i = 0;
+	    fp2 = fp;
+	    if (lvl >= level)
+	    {
+		/* Compute how deep the folds currently are, if it's deeper
+		 * than "lvl" then some must be deleted, need to update
+		 * at least one nested fold. */
+		ll = flp->lnum - fp->fd_top;
+		while (foldFind(&fp2->fd_nested, ll, &fp2))
+		{
+		    ++i;
+		    ll -= fp2->fd_top;
+		}
+	    }
+	    if (lvl < level + i)
+	    {
+		foldFind(&fp->fd_nested, flp->lnum - fp->fd_top, &fp2);
+		if (fp2 != NULL)
+		    bot = fp2->fd_top + fp2->fd_len - 1 + fp->fd_top;
+	    }
+	    else if (fp->fd_top + fp->fd_len <= flp->lnum && lvl >= level)
+		finish = TRUE;
+	    else
+		break;
+	}
+
+	/* At the start of the first nested fold and at the end of the current
+	 * fold: check if existing folds at this level, before the current
+	 * one, need to be deleted or truncated. */
+	if (fp == NULL
+		&& (lvl != level
+		    || flp->lnum_save >= bot
+		    || flp->start != 0
+		    || flp->had_end <= MAX_LEVEL
+		    || flp->lnum == linecount))
+	{
+	    /*
+	     * Remove or update folds that have lines between startlnum and
+	     * firstlnum.
+	     */
+	    while (!got_int)
+	    {
+		/* set concat to 1 if it's allowed to concatenated this fold
+		 * with a previous one that touches it. */
+		if (flp->start != 0 || flp->had_end <= MAX_LEVEL)
+		    concat = 0;
+		else
+		    concat = 1;
+
+		/* Find an existing fold to re-use.  Preferably one that
+		 * includes startlnum, otherwise one that ends just before
+		 * startlnum or starts after it. */
+		if (foldFind(gap, startlnum, &fp)
+			|| (fp < ((fold_T *)gap->ga_data) + gap->ga_len
+			    && fp->fd_top <= firstlnum)
+			|| foldFind(gap, firstlnum - concat, &fp)
+			|| (fp < ((fold_T *)gap->ga_data) + gap->ga_len
+			    && ((lvl < level && fp->fd_top < flp->lnum)
+				|| (lvl >= level
+					   && fp->fd_top <= flp->lnum_save))))
+		{
+		    if (fp->fd_top + fp->fd_len + concat > firstlnum)
+		    {
+			/* Use existing fold for the new fold.  If it starts
+			 * before where we started looking, extend it.  If it
+			 * starts at another line, update nested folds to keep
+			 * their position, compensating for the new fd_top. */
+			if (fp->fd_top >= startlnum && fp->fd_top != firstlnum)
+			{
+			    if (fp->fd_top > firstlnum)
+				/* like lines are inserted */
+				foldMarkAdjustRecurse(&fp->fd_nested,
+					(linenr_T)0, (linenr_T)MAXLNUM,
+					(long)(fp->fd_top - firstlnum), 0L);
+			    else
+				/* like lines are deleted */
+				foldMarkAdjustRecurse(&fp->fd_nested,
+					(linenr_T)0,
+					(long)(firstlnum - fp->fd_top - 1),
+					(linenr_T)MAXLNUM,
+					(long)(fp->fd_top - firstlnum));
+			    fp->fd_len += fp->fd_top - firstlnum;
+			    fp->fd_top = firstlnum;
+			    fold_changed = TRUE;
+			}
+			else if (flp->start != 0 && lvl == level
+						   && fp->fd_top != firstlnum)
+			{
+			    /* Existing fold that includes startlnum must stop
+			     * if we find the start of a new fold at the same
+			     * level.  Split it.  Delete contained folds at
+			     * this point to split them too. */
+			    foldRemove(&fp->fd_nested, flp->lnum - fp->fd_top,
+						      flp->lnum - fp->fd_top);
+			    i = (int)(fp - (fold_T *)gap->ga_data);
+			    foldSplit(gap, i, flp->lnum, flp->lnum - 1);
+			    fp = (fold_T *)gap->ga_data + i + 1;
+			    /* If using the "marker" or "syntax" method, we
+			     * need to continue until the end of the fold is
+			     * found. */
+			    if (getlevel == foldlevelMarker
+				    || getlevel == foldlevelExpr
+				    || getlevel == foldlevelSyntax)
+				finish = TRUE;
+			}
+			break;
+		    }
+		    if (fp->fd_top >= startlnum)
+		    {
+			/* A fold that starts at or after startlnum and stops
+			 * before the new fold must be deleted.  Continue
+			 * looking for the next one. */
+			deleteFoldEntry(gap,
+				     (int)(fp - (fold_T *)gap->ga_data), TRUE);
+		    }
+		    else
+		    {
+			/* A fold has some lines above startlnum, truncate it
+			 * to stop just above startlnum.  */
+			fp->fd_len = startlnum - fp->fd_top;
+			foldMarkAdjustRecurse(&fp->fd_nested,
+				(linenr_T)fp->fd_len, (linenr_T)MAXLNUM,
+						       (linenr_T)MAXLNUM, 0L);
+			fold_changed = TRUE;
+		    }
+		}
+		else
+		{
+		    /* Insert new fold.  Careful: ga_data may be NULL and it
+		     * may change! */
+		    i = (int)(fp - (fold_T *)gap->ga_data);
+		    if (foldInsert(gap, i) != OK)
+			return bot;
+		    fp = (fold_T *)gap->ga_data + i;
+		    /* The new fold continues until bot, unless we find the
+		     * end earlier. */
+		    fp->fd_top = firstlnum;
+		    fp->fd_len = bot - firstlnum + 1;
+		    /* When the containing fold is open, the new fold is open.
+		     * The new fold is closed if the fold above it is closed.
+		     * The first fold depends on the containing fold. */
+		    if (topflags == FD_OPEN)
+		    {
+			flp->wp->w_fold_manual = TRUE;
+			fp->fd_flags = FD_OPEN;
+		    }
+		    else if (i <= 0)
+		    {
+			fp->fd_flags = topflags;
+			if (topflags != FD_LEVEL)
+			    flp->wp->w_fold_manual = TRUE;
+		    }
+		    else
+			fp->fd_flags = (fp - 1)->fd_flags;
+		    fp->fd_small = MAYBE;
+		    /* If using the "marker", "expr" or "syntax" method, we
+		     * need to continue until the end of the fold is found. */
+		    if (getlevel == foldlevelMarker
+			    || getlevel == foldlevelExpr
+			    || getlevel == foldlevelSyntax)
+			finish = TRUE;
+		    fold_changed = TRUE;
+		    break;
+		}
+	    }
+	}
+
+	if (lvl < level || flp->lnum > linecount)
+	{
+	    /*
+	     * Found a line with a lower foldlevel, this fold ends just above
+	     * "flp->lnum".
+	     */
+	    break;
+	}
+
+	/*
+	 * The fold includes the line "flp->lnum" and "flp->lnum_save".
+	 * Check "fp" for safety.
+	 */
+	if (lvl > level && fp != NULL)
+	{
+	    /*
+	     * There is a nested fold, handle it recursively.
+	     */
+	    /* At least do one line (can happen when finish is TRUE). */
+	    if (bot < flp->lnum)
+		bot = flp->lnum;
+
+	    /* Line numbers in the nested fold are relative to the start of
+	     * this fold. */
+	    flp->lnum = flp->lnum_save - fp->fd_top;
+	    flp->off += fp->fd_top;
+	    i = (int)(fp - (fold_T *)gap->ga_data);
+	    bot = foldUpdateIEMSRecurse(&fp->fd_nested, level + 1,
+				       startlnum2 - fp->fd_top, flp, getlevel,
+					      bot - fp->fd_top, fp->fd_flags);
+	    fp = (fold_T *)gap->ga_data + i;
+	    flp->lnum += fp->fd_top;
+	    flp->lnum_save += fp->fd_top;
+	    flp->off -= fp->fd_top;
+	    bot += fp->fd_top;
+	    startlnum2 = flp->lnum;
+
+	    /* This fold may end at the same line, don't incr. flp->lnum. */
+	}
+	else
+	{
+	    /*
+	     * Get the level of the next line, then continue the loop to check
+	     * if it ends there.
+	     * Skip over undefined lines, to find the foldlevel after it.
+	     * For the last line in the file the foldlevel is always valid.
+	     */
+	    flp->lnum = flp->lnum_save;
+	    ll = flp->lnum + 1;
+	    while (!got_int)
+	    {
+		/* Make the previous level available to foldlevel(). */
+		prev_lnum = flp->lnum;
+		prev_lnum_lvl = flp->lvl;
+
+		if (++flp->lnum > linecount)
+		    break;
+		flp->lvl = flp->lvl_next;
+		getlevel(flp);
+		if (flp->lvl >= 0 || flp->had_end <= MAX_LEVEL)
+		    break;
+	    }
+	    prev_lnum = 0;
+	    if (flp->lnum > linecount)
+		break;
+
+	    /* leave flp->lnum_save to lnum of the line that was used to get
+	     * the level, flp->lnum to the lnum of the next line. */
+	    flp->lnum_save = flp->lnum;
+	    flp->lnum = ll;
+	}
+    }
+
+    if (fp == NULL)	/* only happens when got_int is set */
+	return bot;
+
+    /*
+     * Get here when:
+     * lvl < level: the folds ends just above "flp->lnum"
+     * lvl >= level: fold continues below "bot"
+     */
+
+    /* Current fold at least extends until lnum. */
+    if (fp->fd_len < flp->lnum - fp->fd_top)
+    {
+	fp->fd_len = flp->lnum - fp->fd_top;
+	fold_changed = TRUE;
+    }
+
+    /* Delete contained folds from the end of the last one found until where
+     * we stopped looking. */
+    foldRemove(&fp->fd_nested, startlnum2 - fp->fd_top,
+						  flp->lnum - 1 - fp->fd_top);
+
+    if (lvl < level)
+    {
+	/* End of fold found, update the length when it got shorter. */
+	if (fp->fd_len != flp->lnum - fp->fd_top)
+	{
+	    if (fp->fd_top + fp->fd_len > bot + 1)
+	    {
+		/* fold continued below bot */
+		if (getlevel == foldlevelMarker
+			|| getlevel == foldlevelExpr
+			|| getlevel == foldlevelSyntax)
+		{
+		    /* marker method: truncate the fold and make sure the
+		     * previously included lines are processed again */
+		    bot = fp->fd_top + fp->fd_len - 1;
+		    fp->fd_len = flp->lnum - fp->fd_top;
+		}
+		else
+		{
+		    /* indent or expr method: split fold to create a new one
+		     * below bot */
+		    i = (int)(fp - (fold_T *)gap->ga_data);
+		    foldSplit(gap, i, flp->lnum, bot);
+		    fp = (fold_T *)gap->ga_data + i;
+		}
+	    }
+	    else
+		fp->fd_len = flp->lnum - fp->fd_top;
+	    fold_changed = TRUE;
+	}
+    }
+
+    /* delete following folds that end before the current line */
+    for (;;)
+    {
+	fp2 = fp + 1;
+	if (fp2 >= (fold_T *)gap->ga_data + gap->ga_len
+						  || fp2->fd_top > flp->lnum)
+	    break;
+	if (fp2->fd_top + fp2->fd_len > flp->lnum)
+	{
+	    if (fp2->fd_top < flp->lnum)
+	    {
+		/* Make fold that includes lnum start at lnum. */
+		foldMarkAdjustRecurse(&fp2->fd_nested,
+			(linenr_T)0, (long)(flp->lnum - fp2->fd_top - 1),
+			(linenr_T)MAXLNUM, (long)(fp2->fd_top - flp->lnum));
+		fp2->fd_len -= flp->lnum - fp2->fd_top;
+		fp2->fd_top = flp->lnum;
+		fold_changed = TRUE;
+	    }
+
+	    if (lvl >= level)
+	    {
+		/* merge new fold with existing fold that follows */
+		foldMerge(fp, gap, fp2);
+	    }
+	    break;
+	}
+	fold_changed = TRUE;
+	deleteFoldEntry(gap, (int)(fp2 - (fold_T *)gap->ga_data), TRUE);
+    }
+
+    /* Need to redraw the lines we inspected, which might be further down than
+     * was asked for. */
+    if (bot < flp->lnum - 1)
+	bot = flp->lnum - 1;
+
+    return bot;
+}
+
+/* foldInsert() {{{2 */
+/*
+ * Insert a new fold in "gap" at position "i".
+ * Returns OK for success, FAIL for failure.
+ */
+    static int
+foldInsert(gap, i)
+    garray_T	*gap;
+    int		i;
+{
+    fold_T	*fp;
+
+    if (ga_grow(gap, 1) != OK)
+	return FAIL;
+    fp = (fold_T *)gap->ga_data + i;
+    if (i < gap->ga_len)
+	mch_memmove(fp + 1, fp, sizeof(fold_T) * (gap->ga_len - i));
+    ++gap->ga_len;
+    ga_init2(&fp->fd_nested, (int)sizeof(fold_T), 10);
+    return OK;
+}
+
+/* foldSplit() {{{2 */
+/*
+ * Split the "i"th fold in "gap", which starts before "top" and ends below
+ * "bot" in two pieces, one ending above "top" and the other starting below
+ * "bot".
+ * The caller must first have taken care of any nested folds from "top" to
+ * "bot"!
+ */
+    static void
+foldSplit(gap, i, top, bot)
+    garray_T	*gap;
+    int		i;
+    linenr_T	top;
+    linenr_T	bot;
+{
+    fold_T	*fp;
+    fold_T	*fp2;
+    garray_T	*gap1;
+    garray_T	*gap2;
+    int		idx;
+    int		len;
+
+    /* The fold continues below bot, need to split it. */
+    if (foldInsert(gap, i + 1) == FAIL)
+	return;
+    fp = (fold_T *)gap->ga_data + i;
+    fp[1].fd_top = bot + 1;
+    fp[1].fd_len = fp->fd_len - (fp[1].fd_top - fp->fd_top);
+    fp[1].fd_flags = fp->fd_flags;
+
+    /* Move nested folds below bot to new fold.  There can't be
+     * any between top and bot, they have been removed by the caller. */
+    gap1 = &fp->fd_nested;
+    gap2 = &fp[1].fd_nested;
+    (void)(foldFind(gap1, bot + 1 - fp->fd_top, &fp2));
+    len = (int)((fold_T *)gap1->ga_data + gap1->ga_len - fp2);
+    if (len > 0 && ga_grow(gap2, len) == OK)
+    {
+	for (idx = 0; idx < len; ++idx)
+	{
+	    ((fold_T *)gap2->ga_data)[idx] = fp2[idx];
+	    ((fold_T *)gap2->ga_data)[idx].fd_top
+						 -= fp[1].fd_top - fp->fd_top;
+	}
+	gap2->ga_len = len;
+	gap1->ga_len -= len;
+    }
+    fp->fd_len = top - fp->fd_top;
+    fold_changed = TRUE;
+}
+
+/* foldRemove() {{{2 */
+/*
+ * Remove folds within the range "top" to and including "bot".
+ * Check for these situations:
+ *      1  2  3
+ *      1  2  3
+ * top     2  3  4  5
+ *	   2  3  4  5
+ * bot	   2  3  4  5
+ *	      3     5  6
+ *	      3     5  6
+ *
+ * 1: not changed
+ * 2: truncate to stop above "top"
+ * 3: split in two parts, one stops above "top", other starts below "bot".
+ * 4: deleted
+ * 5: made to start below "bot".
+ * 6: not changed
+ */
+    static void
+foldRemove(gap, top, bot)
+    garray_T	*gap;
+    linenr_T	top;
+    linenr_T	bot;
+{
+    fold_T	*fp = NULL;
+
+    if (bot < top)
+	return;		/* nothing to do */
+
+    for (;;)
+    {
+	/* Find fold that includes top or a following one. */
+	if (foldFind(gap, top, &fp) && fp->fd_top < top)
+	{
+	    /* 2: or 3: need to delete nested folds */
+	    foldRemove(&fp->fd_nested, top - fp->fd_top, bot - fp->fd_top);
+	    if (fp->fd_top + fp->fd_len > bot + 1)
+	    {
+		/* 3: need to split it. */
+		foldSplit(gap, (int)(fp - (fold_T *)gap->ga_data), top, bot);
+	    }
+	    else
+	    {
+		/* 2: truncate fold at "top". */
+		fp->fd_len = top - fp->fd_top;
+	    }
+	    fold_changed = TRUE;
+	    continue;
+	}
+	if (fp >= (fold_T *)(gap->ga_data) + gap->ga_len
+		|| fp->fd_top > bot)
+	{
+	    /* 6: Found a fold below bot, can stop looking. */
+	    break;
+	}
+	if (fp->fd_top >= top)
+	{
+	    /* Found an entry below top. */
+	    fold_changed = TRUE;
+	    if (fp->fd_top + fp->fd_len - 1 > bot)
+	    {
+		/* 5: Make fold that includes bot start below bot. */
+		foldMarkAdjustRecurse(&fp->fd_nested,
+			(linenr_T)0, (long)(bot - fp->fd_top),
+			(linenr_T)MAXLNUM, (long)(fp->fd_top - bot - 1));
+		fp->fd_len -= bot - fp->fd_top + 1;
+		fp->fd_top = bot + 1;
+		break;
+	    }
+
+	    /* 4: Delete completely contained fold. */
+	    deleteFoldEntry(gap, (int)(fp - (fold_T *)gap->ga_data), TRUE);
+	}
+    }
+}
+
+/* foldMerge() {{{2 */
+/*
+ * Merge two adjacent folds (and the nested ones in them).
+ * This only works correctly when the folds are really adjacent!  Thus "fp1"
+ * must end just above "fp2".
+ * The resulting fold is "fp1", nested folds are moved from "fp2" to "fp1".
+ * Fold entry "fp2" in "gap" is deleted.
+ */
+    static void
+foldMerge(fp1, gap, fp2)
+    fold_T	*fp1;
+    garray_T	*gap;
+    fold_T	*fp2;
+{
+    fold_T	*fp3;
+    fold_T	*fp4;
+    int		idx;
+    garray_T	*gap1 = &fp1->fd_nested;
+    garray_T	*gap2 = &fp2->fd_nested;
+
+    /* If the last nested fold in fp1 touches the first nested fold in fp2,
+     * merge them recursively. */
+    if (foldFind(gap1, fp1->fd_len - 1L, &fp3) && foldFind(gap2, 0L, &fp4))
+	foldMerge(fp3, gap2, fp4);
+
+    /* Move nested folds in fp2 to the end of fp1. */
+    if (gap2->ga_len > 0 && ga_grow(gap1, gap2->ga_len) == OK)
+    {
+	for (idx = 0; idx < gap2->ga_len; ++idx)
+	{
+	    ((fold_T *)gap1->ga_data)[gap1->ga_len]
+					= ((fold_T *)gap2->ga_data)[idx];
+	    ((fold_T *)gap1->ga_data)[gap1->ga_len].fd_top += fp1->fd_len;
+	    ++gap1->ga_len;
+	}
+	gap2->ga_len = 0;
+    }
+
+    fp1->fd_len += fp2->fd_len;
+    deleteFoldEntry(gap, (int)(fp2 - (fold_T *)gap->ga_data), TRUE);
+    fold_changed = TRUE;
+}
+
+/* foldlevelIndent() {{{2 */
+/*
+ * Low level function to get the foldlevel for the "indent" method.
+ * Doesn't use any caching.
+ * Returns a level of -1 if the foldlevel depends on surrounding lines.
+ */
+    static void
+foldlevelIndent(flp)
+    fline_T	*flp;
+{
+    char_u	*s;
+    buf_T	*buf;
+    linenr_T	lnum = flp->lnum + flp->off;
+
+    buf = flp->wp->w_buffer;
+    s = skipwhite(ml_get_buf(buf, lnum, FALSE));
+
+    /* empty line or lines starting with a character in 'foldignore': level
+     * depends on surrounding lines */
+    if (*s == NUL || vim_strchr(flp->wp->w_p_fdi, *s) != NULL)
+    {
+	/* first and last line can't be undefined, use level 0 */
+	if (lnum == 1 || lnum == buf->b_ml.ml_line_count)
+	    flp->lvl = 0;
+	else
+	    flp->lvl = -1;
+    }
+    else
+	flp->lvl = get_indent_buf(buf, lnum) / buf->b_p_sw;
+    if (flp->lvl > flp->wp->w_p_fdn)
+    {
+	flp->lvl = flp->wp->w_p_fdn;
+	if (flp->lvl < 0)
+	    flp->lvl = 0;
+    }
+}
+
+/* foldlevelDiff() {{{2 */
+#ifdef FEAT_DIFF
+/*
+ * Low level function to get the foldlevel for the "diff" method.
+ * Doesn't use any caching.
+ */
+    static void
+foldlevelDiff(flp)
+    fline_T	*flp;
+{
+    if (diff_infold(flp->wp, flp->lnum + flp->off))
+	flp->lvl = 1;
+    else
+	flp->lvl = 0;
+}
+#endif
+
+/* foldlevelExpr() {{{2 */
+/*
+ * Low level function to get the foldlevel for the "expr" method.
+ * Doesn't use any caching.
+ * Returns a level of -1 if the foldlevel depends on surrounding lines.
+ */
+    static void
+foldlevelExpr(flp)
+    fline_T	*flp;
+{
+#ifndef FEAT_EVAL
+    flp->start = FALSE;
+    flp->lvl = 0;
+#else
+    win_T	*win;
+    int		n;
+    int		c;
+    linenr_T	lnum = flp->lnum + flp->off;
+    int		save_keytyped;
+
+    win = curwin;
+    curwin = flp->wp;
+    curbuf = flp->wp->w_buffer;
+    set_vim_var_nr(VV_LNUM, lnum);
+
+    flp->start = 0;
+    flp->had_end = flp->end;
+    flp->end = MAX_LEVEL + 1;
+    if (lnum <= 1)
+	flp->lvl = 0;
+
+    /* KeyTyped may be reset to 0 when calling a function which invokes
+     * do_cmdline().  To make 'foldopen' work correctly restore KeyTyped. */
+    save_keytyped = KeyTyped;
+    n = eval_foldexpr(flp->wp->w_p_fde, &c);
+    KeyTyped = save_keytyped;
+
+    switch (c)
+    {
+	/* "a1", "a2", .. : add to the fold level */
+	case 'a': if (flp->lvl >= 0)
+		  {
+		      flp->lvl += n;
+		      flp->lvl_next = flp->lvl;
+		  }
+		  flp->start = n;
+		  break;
+
+	/* "s1", "s2", .. : subtract from the fold level */
+	case 's': if (flp->lvl >= 0)
+		  {
+		      if (n > flp->lvl)
+			  flp->lvl_next = 0;
+		      else
+			  flp->lvl_next = flp->lvl - n;
+		      flp->end = flp->lvl_next + 1;
+		  }
+		  break;
+
+	/* ">1", ">2", .. : start a fold with a certain level */
+	case '>': flp->lvl = n;
+		  flp->lvl_next = n;
+		  flp->start = 1;
+		  break;
+
+	/* "<1", "<2", .. : end a fold with a certain level */
+	case '<': flp->lvl_next = n - 1;
+		  flp->end = n;
+		  break;
+
+	/* "=": No change in level */
+	case '=': flp->lvl_next = flp->lvl;
+		  break;
+
+	/* "-1", "0", "1", ..: set fold level */
+	default:  if (n < 0)
+		      /* Use the current level for the next line, so that "a1"
+		       * will work there. */
+		      flp->lvl_next = flp->lvl;
+		  else
+		      flp->lvl_next = n;
+		  flp->lvl = n;
+		  break;
+    }
+
+    /* If the level is unknown for the first or the last line in the file, use
+     * level 0. */
+    if (flp->lvl < 0)
+    {
+	if (lnum <= 1)
+	{
+	    flp->lvl = 0;
+	    flp->lvl_next = 0;
+	}
+	if (lnum == curbuf->b_ml.ml_line_count)
+	    flp->lvl_next = 0;
+    }
+
+    curwin = win;
+    curbuf = curwin->w_buffer;
+#endif
+}
+
+/* parseMarker() {{{2 */
+/*
+ * Parse 'foldmarker' and set "foldendmarker", "foldstartmarkerlen" and
+ * "foldendmarkerlen".
+ * Relies on the option value to have been checked for correctness already.
+ */
+    static void
+parseMarker(wp)
+    win_T	*wp;
+{
+    foldendmarker = vim_strchr(wp->w_p_fmr, ',');
+    foldstartmarkerlen = (int)(foldendmarker++ - wp->w_p_fmr);
+    foldendmarkerlen = (int)STRLEN(foldendmarker);
+}
+
+/* foldlevelMarker() {{{2 */
+/*
+ * Low level function to get the foldlevel for the "marker" method.
+ * "foldendmarker", "foldstartmarkerlen" and "foldendmarkerlen" must have been
+ * set before calling this.
+ * Requires that flp->lvl is set to the fold level of the previous line!
+ * Careful: This means you can't call this function twice on the same line.
+ * Doesn't use any caching.
+ * Sets flp->start when a start marker was found.
+ */
+    static void
+foldlevelMarker(flp)
+    fline_T	*flp;
+{
+    char_u	*startmarker;
+    int		cstart;
+    int		cend;
+    int		start_lvl = flp->lvl;
+    char_u	*s;
+    int		n;
+
+    /* cache a few values for speed */
+    startmarker = flp->wp->w_p_fmr;
+    cstart = *startmarker;
+    ++startmarker;
+    cend = *foldendmarker;
+
+    /* Default: no start found, next level is same as current level */
+    flp->start = 0;
+    flp->lvl_next = flp->lvl;
+
+    s = ml_get_buf(flp->wp->w_buffer, flp->lnum + flp->off, FALSE);
+    while (*s)
+    {
+	if (*s == cstart
+		  && STRNCMP(s + 1, startmarker, foldstartmarkerlen - 1) == 0)
+	{
+	    /* found startmarker: set flp->lvl */
+	    s += foldstartmarkerlen;
+	    if (VIM_ISDIGIT(*s))
+	    {
+		n = atoi((char *)s);
+		if (n > 0)
+		{
+		    flp->lvl = n;
+		    flp->lvl_next = n;
+		    if (n <= start_lvl)
+			flp->start = 1;
+		    else
+			flp->start = n - start_lvl;
+		}
+	    }
+	    else
+	    {
+		++flp->lvl;
+		++flp->lvl_next;
+		++flp->start;
+	    }
+	}
+	else if (*s == cend
+	      && STRNCMP(s + 1, foldendmarker + 1, foldendmarkerlen - 1) == 0)
+	{
+	    /* found endmarker: set flp->lvl_next */
+	    s += foldendmarkerlen;
+	    if (VIM_ISDIGIT(*s))
+	    {
+		n = atoi((char *)s);
+		if (n > 0)
+		{
+		    flp->lvl = n;
+		    flp->lvl_next = n - 1;
+		    /* never start a fold with an end marker */
+		    if (flp->lvl_next > flp->lvl)
+			flp->lvl_next = flp->lvl;
+		}
+	    }
+	    else
+		--flp->lvl_next;
+	}
+	else
+	    mb_ptr_adv(s);
+    }
+
+    /* The level can't go negative, must be missing a start marker. */
+    if (flp->lvl_next < 0)
+	flp->lvl_next = 0;
+}
+
+/* foldlevelSyntax() {{{2 */
+/*
+ * Low level function to get the foldlevel for the "syntax" method.
+ * Doesn't use any caching.
+ */
+    static void
+foldlevelSyntax(flp)
+    fline_T	*flp;
+{
+#ifndef FEAT_SYN_HL
+    flp->start = 0;
+    flp->lvl = 0;
+#else
+    linenr_T	lnum = flp->lnum + flp->off;
+    int		n;
+
+    /* Use the maximum fold level at the start of this line and the next. */
+    flp->lvl = syn_get_foldlevel(flp->wp, lnum);
+    flp->start = 0;
+    if (lnum < flp->wp->w_buffer->b_ml.ml_line_count)
+    {
+	n = syn_get_foldlevel(flp->wp, lnum + 1);
+	if (n > flp->lvl)
+	{
+	    flp->start = n - flp->lvl;	/* fold(s) start here */
+	    flp->lvl = n;
+	}
+    }
+#endif
+}
+
+/* functions for storing the fold state in a View {{{1 */
+/* put_folds() {{{2 */
+#if defined(FEAT_SESSION) || defined(PROTO)
+static int put_folds_recurse __ARGS((FILE *fd, garray_T *gap, linenr_T off));
+static int put_foldopen_recurse __ARGS((FILE *fd, garray_T *gap, linenr_T off));
+
+/*
+ * Write commands to "fd" to restore the manual folds in window "wp".
+ * Return FAIL if writing fails.
+ */
+    int
+put_folds(fd, wp)
+    FILE	*fd;
+    win_T	*wp;
+{
+    if (foldmethodIsManual(wp))
+    {
+	if (put_line(fd, "silent! normal! zE") == FAIL
+		|| put_folds_recurse(fd, &wp->w_folds, (linenr_T)0) == FAIL)
+	    return FAIL;
+    }
+
+    /* If some folds are manually opened/closed, need to restore that. */
+    if (wp->w_fold_manual)
+	return put_foldopen_recurse(fd, &wp->w_folds, (linenr_T)0);
+
+    return OK;
+}
+
+/* put_folds_recurse() {{{2 */
+/*
+ * Write commands to "fd" to recreate manually created folds.
+ * Returns FAIL when writing failed.
+ */
+    static int
+put_folds_recurse(fd, gap, off)
+    FILE	*fd;
+    garray_T	*gap;
+    linenr_T	off;
+{
+    int		i;
+    fold_T	*fp;
+
+    fp = (fold_T *)gap->ga_data;
+    for (i = 0; i < gap->ga_len; i++)
+    {
+	/* Do nested folds first, they will be created closed. */
+	if (put_folds_recurse(fd, &fp->fd_nested, off + fp->fd_top) == FAIL)
+	    return FAIL;
+	if (fprintf(fd, "%ld,%ldfold", fp->fd_top + off,
+					fp->fd_top + off + fp->fd_len - 1) < 0
+		|| put_eol(fd) == FAIL)
+	    return FAIL;
+	++fp;
+    }
+    return OK;
+}
+
+/* put_foldopen_recurse() {{{2 */
+/*
+ * Write commands to "fd" to open and close manually opened/closed folds.
+ * Returns FAIL when writing failed.
+ */
+    static int
+put_foldopen_recurse(fd, gap, off)
+    FILE	*fd;
+    garray_T	*gap;
+    linenr_T	off;
+{
+    int		i;
+    fold_T	*fp;
+
+    fp = (fold_T *)gap->ga_data;
+    for (i = 0; i < gap->ga_len; i++)
+    {
+	if (fp->fd_flags != FD_LEVEL)
+	{
+	    if (fp->fd_nested.ga_len > 0)
+	    {
+		/* open/close nested folds while this fold is open */
+		if (fprintf(fd, "%ld", fp->fd_top + off) < 0
+			|| put_eol(fd) == FAIL
+			|| put_line(fd, "normal zo") == FAIL)
+		    return FAIL;
+		if (put_foldopen_recurse(fd, &fp->fd_nested, off + fp->fd_top)
+			== FAIL)
+		    return FAIL;
+	    }
+	    if (fprintf(fd, "%ld", fp->fd_top + off) < 0
+		    || put_eol(fd) == FAIL
+		    || fprintf(fd, "normal z%c",
+				    fp->fd_flags == FD_CLOSED ? 'c' : 'o') < 0
+		    || put_eol(fd) == FAIL)
+		return FAIL;
+	}
+	++fp;
+    }
+
+    return OK;
+}
+#endif /* FEAT_SESSION */
+
+/* }}}1 */
+#endif /* defined(FEAT_FOLDING) || defined(PROTO) */
--- /dev/null
+++ b/getchar.c
@@ -1,0 +1,5067 @@
+/* vi:set ts=8 sts=4 sw=4:
+ *
+ * VIM - Vi IMproved	by Bram Moolenaar
+ *
+ * Do ":help uganda"  in Vim to read copying and usage conditions.
+ * Do ":help credits" in Vim to see a list of people who contributed.
+ * See README.txt for an overview of the Vim source code.
+ */
+
+/*
+ * getchar.c
+ *
+ * functions related with getting a character from the user/mapping/redo/...
+ *
+ * manipulations with redo buffer and stuff buffer
+ * mappings and abbreviations
+ */
+
+#include "vim.h"
+
+/*
+ * These buffers are used for storing:
+ * - stuffed characters: A command that is translated into another command.
+ * - redo characters: will redo the last change.
+ * - recorded chracters: for the "q" command.
+ *
+ * The bytes are stored like in the typeahead buffer:
+ * - K_SPECIAL introduces a special key (two more bytes follow).  A literal
+ *   K_SPECIAL is stored as K_SPECIAL KS_SPECIAL KE_FILLER.
+ * - CSI introduces a GUI termcap code (also when gui.in_use is FALSE,
+ *   otherwise switching the GUI on would make mappings invalid).
+ *   A literal CSI is stored as CSI KS_EXTRA KE_CSI.
+ * These translations are also done on multi-byte characters!
+ *
+ * Escaping CSI bytes is done by the system-specific input functions, called
+ * by ui_inchar().
+ * Escaping K_SPECIAL is done by inchar().
+ * Un-escaping is done by vgetc().
+ */
+
+#define MINIMAL_SIZE 20			/* minimal size for b_str */
+
+static struct buffheader redobuff = {{NULL, {NUL}}, NULL, 0, 0};
+static struct buffheader old_redobuff = {{NULL, {NUL}}, NULL, 0, 0};
+#if defined(FEAT_AUTOCMD) || defined(FEAT_EVAL) || defined(PROTO)
+static struct buffheader save_redobuff = {{NULL, {NUL}}, NULL, 0, 0};
+static struct buffheader save_old_redobuff = {{NULL, {NUL}}, NULL, 0, 0};
+#endif
+static struct buffheader recordbuff = {{NULL, {NUL}}, NULL, 0, 0};
+
+static int typeahead_char = 0;		/* typeahead char that's not flushed */
+
+/*
+ * when block_redo is TRUE redo buffer will not be changed
+ * used by edit() to repeat insertions and 'V' command for redoing
+ */
+static int	block_redo = FALSE;
+
+/*
+ * Make a hash value for a mapping.
+ * "mode" is the lower 4 bits of the State for the mapping.
+ * "c1" is the first character of the "lhs".
+ * Returns a value between 0 and 255, index in maphash.
+ * Put Normal/Visual mode mappings mostly separately from Insert/Cmdline mode.
+ */
+#define MAP_HASH(mode, c1) (((mode) & (NORMAL + VISUAL + SELECTMODE + OP_PENDING)) ? (c1) : ((c1) ^ 0x80))
+
+/*
+ * Each mapping is put in one of the 256 hash lists, to speed up finding it.
+ */
+static mapblock_T	*(maphash[256]);
+static int		maphash_valid = FALSE;
+
+/*
+ * List used for abbreviations.
+ */
+static mapblock_T	*first_abbr = NULL; /* first entry in abbrlist */
+
+static int		KeyNoremap = 0;	    /* remapping flags */
+
+/*
+ * variables used by vgetorpeek() and flush_buffers()
+ *
+ * typebuf.tb_buf[] contains all characters that are not consumed yet.
+ * typebuf.tb_buf[typebuf.tb_off] is the first valid character.
+ * typebuf.tb_buf[typebuf.tb_off + typebuf.tb_len - 1] is the last valid char.
+ * typebuf.tb_buf[typebuf.tb_off + typebuf.tb_len] must be NUL.
+ * The head of the buffer may contain the result of mappings, abbreviations
+ * and @a commands.  The length of this part is typebuf.tb_maplen.
+ * typebuf.tb_silent is the part where <silent> applies.
+ * After the head are characters that come from the terminal.
+ * typebuf.tb_no_abbr_cnt is the number of characters in typebuf.tb_buf that
+ * should not be considered for abbreviations.
+ * Some parts of typebuf.tb_buf may not be mapped. These parts are remembered
+ * in typebuf.tb_noremap[], which is the same length as typebuf.tb_buf and
+ * contains RM_NONE for the characters that are not to be remapped.
+ * typebuf.tb_noremap[typebuf.tb_off] is the first valid flag.
+ * (typebuf has been put in globals.h, because check_termcode() needs it).
+ */
+#define RM_YES		0	/* tb_noremap: remap */
+#define RM_NONE		1	/* tb_noremap: don't remap */
+#define RM_SCRIPT	2	/* tb_noremap: remap local script mappings */
+#define RM_ABBR		4	/* tb_noremap: don't remap, do abbrev. */
+
+/* typebuf.tb_buf has three parts: room in front (for result of mappings), the
+ * middle for typeahead and room for new characters (which needs to be 3 *
+ * MAXMAPLEN) for the Amiga).
+ */
+#define TYPELEN_INIT	(5 * (MAXMAPLEN + 3))
+static char_u	typebuf_init[TYPELEN_INIT];	/* initial typebuf.tb_buf */
+static char_u	noremapbuf_init[TYPELEN_INIT];	/* initial typebuf.tb_noremap */
+
+static int	last_recorded_len = 0;	/* number of last recorded chars */
+
+static char_u	*get_buffcont __ARGS((struct buffheader *, int));
+static void	add_buff __ARGS((struct buffheader *, char_u *, long n));
+static void	add_num_buff __ARGS((struct buffheader *, long));
+static void	add_char_buff __ARGS((struct buffheader *, int));
+static int	read_stuff __ARGS((int advance));
+static void	start_stuff __ARGS((void));
+static int	read_redo __ARGS((int, int));
+static void	copy_redo __ARGS((int));
+static void	init_typebuf __ARGS((void));
+static void	gotchars __ARGS((char_u *, int));
+static void	may_sync_undo __ARGS((void));
+static void	closescript __ARGS((void));
+static int	vgetorpeek __ARGS((int));
+static void	map_free __ARGS((mapblock_T **));
+static void	validate_maphash __ARGS((void));
+static void	showmap __ARGS((mapblock_T *mp, int local));
+#ifdef FEAT_EVAL
+static char_u	*eval_map_expr __ARGS((char_u *str));
+#endif
+
+/*
+ * Free and clear a buffer.
+ */
+    void
+free_buff(buf)
+    struct buffheader	*buf;
+{
+    struct buffblock	*p, *np;
+
+    for (p = buf->bh_first.b_next; p != NULL; p = np)
+    {
+	np = p->b_next;
+	vim_free(p);
+    }
+    buf->bh_first.b_next = NULL;
+}
+
+/*
+ * Return the contents of a buffer as a single string.
+ * K_SPECIAL and CSI in the returned string are escaped.
+ */
+    static char_u *
+get_buffcont(buffer, dozero)
+    struct buffheader	*buffer;
+    int			dozero;	    /* count == zero is not an error */
+{
+    long_u	    count = 0;
+    char_u	    *p = NULL;
+    char_u	    *p2;
+    char_u	    *str;
+    struct buffblock *bp;
+
+    /* compute the total length of the string */
+    for (bp = buffer->bh_first.b_next; bp != NULL; bp = bp->b_next)
+	count += (long_u)STRLEN(bp->b_str);
+
+    if ((count || dozero) && (p = lalloc(count + 1, TRUE)) != NULL)
+    {
+	p2 = p;
+	for (bp = buffer->bh_first.b_next; bp != NULL; bp = bp->b_next)
+	    for (str = bp->b_str; *str; )
+		*p2++ = *str++;
+	*p2 = NUL;
+    }
+    return (p);
+}
+
+/*
+ * Return the contents of the record buffer as a single string
+ * and clear the record buffer.
+ * K_SPECIAL and CSI in the returned string are escaped.
+ */
+    char_u *
+get_recorded()
+{
+    char_u	*p;
+    size_t	len;
+
+    p = get_buffcont(&recordbuff, TRUE);
+    free_buff(&recordbuff);
+
+    /*
+     * Remove the characters that were added the last time, these must be the
+     * (possibly mapped) characters that stopped the recording.
+     */
+    len = STRLEN(p);
+    if ((int)len >= last_recorded_len)
+    {
+	len -= last_recorded_len;
+	p[len] = NUL;
+    }
+
+    /*
+     * When stopping recording from Insert mode with CTRL-O q, also remove the
+     * CTRL-O.
+     */
+    if (len > 0 && restart_edit != 0 && p[len - 1] == Ctrl_O)
+	p[len - 1] = NUL;
+
+    return (p);
+}
+
+/*
+ * Return the contents of the redo buffer as a single string.
+ * K_SPECIAL and CSI in the returned string are escaped.
+ */
+    char_u *
+get_inserted()
+{
+    return(get_buffcont(&redobuff, FALSE));
+}
+
+/*
+ * Add string "s" after the current block of buffer "buf".
+ * K_SPECIAL and CSI should have been escaped already.
+ */
+    static void
+add_buff(buf, s, slen)
+    struct buffheader	*buf;
+    char_u		*s;
+    long		slen;	/* length of "s" or -1 */
+{
+    struct buffblock *p;
+    long_u	    len;
+
+    if (slen < 0)
+	slen = (long)STRLEN(s);
+    if (slen == 0)				/* don't add empty strings */
+	return;
+
+    if (buf->bh_first.b_next == NULL)	/* first add to list */
+    {
+	buf->bh_space = 0;
+	buf->bh_curr = &(buf->bh_first);
+    }
+    else if (buf->bh_curr == NULL)	/* buffer has already been read */
+    {
+	EMSG(_("E222: Add to read buffer"));
+	return;
+    }
+    else if (buf->bh_index != 0)
+	STRCPY(buf->bh_first.b_next->b_str,
+				 buf->bh_first.b_next->b_str + buf->bh_index);
+    buf->bh_index = 0;
+
+    if (buf->bh_space >= (int)slen)
+    {
+	len = (long_u)STRLEN(buf->bh_curr->b_str);
+	vim_strncpy(buf->bh_curr->b_str + len, s, (size_t)slen);
+	buf->bh_space -= slen;
+    }
+    else
+    {
+	if (slen < MINIMAL_SIZE)
+	    len = MINIMAL_SIZE;
+	else
+	    len = slen;
+	p = (struct buffblock *)lalloc((long_u)(sizeof(struct buffblock) + len),
+									TRUE);
+	if (p == NULL)
+	    return; /* no space, just forget it */
+	buf->bh_space = (int)(len - slen);
+	vim_strncpy(p->b_str, s, (size_t)slen);
+
+	p->b_next = buf->bh_curr->b_next;
+	buf->bh_curr->b_next = p;
+	buf->bh_curr = p;
+    }
+    return;
+}
+
+/*
+ * Add number "n" to buffer "buf".
+ */
+    static void
+add_num_buff(buf, n)
+    struct buffheader *buf;
+    long	      n;
+{
+    char_u	number[32];
+
+    sprintf((char *)number, "%ld", n);
+    add_buff(buf, number, -1L);
+}
+
+/*
+ * Add character 'c' to buffer "buf".
+ * Translates special keys, NUL, CSI, K_SPECIAL and multibyte characters.
+ */
+    static void
+add_char_buff(buf, c)
+    struct buffheader	*buf;
+    int			c;
+{
+#ifdef FEAT_MBYTE
+    char_u	bytes[MB_MAXBYTES + 1];
+    int		len;
+    int		i;
+#endif
+    char_u	temp[4];
+
+#ifdef FEAT_MBYTE
+    if (IS_SPECIAL(c))
+	len = 1;
+    else
+	len = (*mb_char2bytes)(c, bytes);
+    for (i = 0; i < len; ++i)
+    {
+	if (!IS_SPECIAL(c))
+	    c = bytes[i];
+#endif
+
+	if (IS_SPECIAL(c) || c == K_SPECIAL || c == NUL)
+	{
+	    /* translate special key code into three byte sequence */
+	    temp[0] = K_SPECIAL;
+	    temp[1] = K_SECOND(c);
+	    temp[2] = K_THIRD(c);
+	    temp[3] = NUL;
+	}
+#ifdef FEAT_GUI
+	else if (c == CSI)
+	{
+	    /* Translate a CSI to a CSI - KS_EXTRA - KE_CSI sequence */
+	    temp[0] = CSI;
+	    temp[1] = KS_EXTRA;
+	    temp[2] = (int)KE_CSI;
+	    temp[3] = NUL;
+	}
+#endif
+	else
+	{
+	    temp[0] = c;
+	    temp[1] = NUL;
+	}
+	add_buff(buf, temp, -1L);
+#ifdef FEAT_MBYTE
+    }
+#endif
+}
+
+/*
+ * Get one byte from the stuff buffer.
+ * If advance == TRUE go to the next char.
+ * No translation is done K_SPECIAL and CSI are escaped.
+ */
+    static int
+read_stuff(advance)
+    int		advance;
+{
+    char_u		c;
+    struct buffblock	*curr;
+
+    if (stuffbuff.bh_first.b_next == NULL)  /* buffer is empty */
+	return NUL;
+
+    curr = stuffbuff.bh_first.b_next;
+    c = curr->b_str[stuffbuff.bh_index];
+
+    if (advance)
+    {
+	if (curr->b_str[++stuffbuff.bh_index] == NUL)
+	{
+	    stuffbuff.bh_first.b_next = curr->b_next;
+	    vim_free(curr);
+	    stuffbuff.bh_index = 0;
+	}
+    }
+    return c;
+}
+
+/*
+ * Prepare the stuff buffer for reading (if it contains something).
+ */
+    static void
+start_stuff()
+{
+    if (stuffbuff.bh_first.b_next != NULL)
+    {
+	stuffbuff.bh_curr = &(stuffbuff.bh_first);
+	stuffbuff.bh_space = 0;
+    }
+}
+
+/*
+ * Return TRUE if the stuff buffer is empty.
+ */
+    int
+stuff_empty()
+{
+    return (stuffbuff.bh_first.b_next == NULL);
+}
+
+/*
+ * Set a typeahead character that won't be flushed.
+ */
+    void
+typeahead_noflush(c)
+    int		c;
+{
+    typeahead_char = c;
+}
+
+/*
+ * Remove the contents of the stuff buffer and the mapped characters in the
+ * typeahead buffer (used in case of an error).  If 'typeahead' is true,
+ * flush all typeahead characters (used when interrupted by a CTRL-C).
+ */
+    void
+flush_buffers(typeahead)
+    int typeahead;
+{
+    init_typebuf();
+
+    start_stuff();
+    while (read_stuff(TRUE) != NUL)
+	;
+
+    if (typeahead)	    /* remove all typeahead */
+    {
+	/*
+	 * We have to get all characters, because we may delete the first part
+	 * of an escape sequence.
+	 * In an xterm we get one char at a time and we have to get them all.
+	 */
+	while (inchar(typebuf.tb_buf, typebuf.tb_buflen - 1, 10L,
+						  typebuf.tb_change_cnt) != 0)
+	    ;
+	typebuf.tb_off = MAXMAPLEN;
+	typebuf.tb_len = 0;
+    }
+    else		    /* remove mapped characters only */
+    {
+	typebuf.tb_off += typebuf.tb_maplen;
+	typebuf.tb_len -= typebuf.tb_maplen;
+    }
+    typebuf.tb_maplen = 0;
+    typebuf.tb_silent = 0;
+    cmd_silent = FALSE;
+    typebuf.tb_no_abbr_cnt = 0;
+}
+
+/*
+ * The previous contents of the redo buffer is kept in old_redobuffer.
+ * This is used for the CTRL-O <.> command in insert mode.
+ */
+    void
+ResetRedobuff()
+{
+    if (!block_redo)
+    {
+	free_buff(&old_redobuff);
+	old_redobuff = redobuff;
+	redobuff.bh_first.b_next = NULL;
+    }
+}
+
+#if defined(FEAT_AUTOCMD) || defined(FEAT_EVAL) || defined(PROTO)
+/*
+ * Save redobuff and old_redobuff to save_redobuff and save_old_redobuff.
+ * Used before executing autocommands and user functions.
+ */
+static int save_level = 0;
+
+    void
+saveRedobuff()
+{
+    char_u	*s;
+
+    if (save_level++ == 0)
+    {
+	save_redobuff = redobuff;
+	redobuff.bh_first.b_next = NULL;
+	save_old_redobuff = old_redobuff;
+	old_redobuff.bh_first.b_next = NULL;
+
+	/* Make a copy, so that ":normal ." in a function works. */
+	s = get_buffcont(&save_redobuff, FALSE);
+	if (s != NULL)
+	{
+	    add_buff(&redobuff, s, -1L);
+	    vim_free(s);
+	}
+    }
+}
+
+/*
+ * Restore redobuff and old_redobuff from save_redobuff and save_old_redobuff.
+ * Used after executing autocommands and user functions.
+ */
+    void
+restoreRedobuff()
+{
+    if (--save_level == 0)
+    {
+	free_buff(&redobuff);
+	redobuff = save_redobuff;
+	free_buff(&old_redobuff);
+	old_redobuff = save_old_redobuff;
+    }
+}
+#endif
+
+/*
+ * Append "s" to the redo buffer.
+ * K_SPECIAL and CSI should already have been escaped.
+ */
+    void
+AppendToRedobuff(s)
+    char_u	   *s;
+{
+    if (!block_redo)
+	add_buff(&redobuff, s, -1L);
+}
+
+/*
+ * Append to Redo buffer literally, escaping special characters with CTRL-V.
+ * K_SPECIAL and CSI are escaped as well.
+ */
+    void
+AppendToRedobuffLit(str, len)
+    char_u	*str;
+    int		len;	    /* length of "str" or -1 for up to the NUL */
+{
+    char_u	*s = str;
+    int		c;
+    char_u	*start;
+
+    if (block_redo)
+	return;
+
+    while (len < 0 ? *s != NUL : s - str < len)
+    {
+	/* Put a string of normal characters in the redo buffer (that's
+	 * faster). */
+	start = s;
+	while (*s >= ' '
+#ifndef EBCDIC
+		&& *s < DEL	/* EBCDIC: all chars above space are normal */
+#endif
+		&& (len < 0 || s - str < len))
+	    ++s;
+
+	/* Don't put '0' or '^' as last character, just in case a CTRL-D is
+	 * typed next. */
+	if (*s == NUL && (s[-1] == '0' || s[-1] == '^'))
+	    --s;
+	if (s > start)
+	    add_buff(&redobuff, start, (long)(s - start));
+
+	if (*s == NUL || (len >= 0 && s - str >= len))
+	    break;
+
+	/* Handle a special or multibyte character. */
+#ifdef FEAT_MBYTE
+	if (has_mbyte)
+	    /* Handle composing chars separately. */
+	    c = mb_cptr2char_adv(&s);
+	else
+#endif
+	    c = *s++;
+	if (c < ' ' || c == DEL || (*s == NUL && (c == '0' || c == '^')))
+	    add_char_buff(&redobuff, Ctrl_V);
+
+	/* CTRL-V '0' must be inserted as CTRL-V 048 (EBCDIC: xf0) */
+	if (*s == NUL && c == '0')
+#ifdef EBCDIC
+	    add_buff(&redobuff, (char_u *)"xf0", 3L);
+#else
+	    add_buff(&redobuff, (char_u *)"048", 3L);
+#endif
+	else
+	    add_char_buff(&redobuff, c);
+    }
+}
+
+/*
+ * Append a character to the redo buffer.
+ * Translates special keys, NUL, CSI, K_SPECIAL and multibyte characters.
+ */
+    void
+AppendCharToRedobuff(c)
+    int		   c;
+{
+    if (!block_redo)
+	add_char_buff(&redobuff, c);
+}
+
+/*
+ * Append a number to the redo buffer.
+ */
+    void
+AppendNumberToRedobuff(n)
+    long	    n;
+{
+    if (!block_redo)
+	add_num_buff(&redobuff, n);
+}
+
+/*
+ * Append string "s" to the stuff buffer.
+ * CSI and K_SPECIAL must already have been escaped.
+ */
+    void
+stuffReadbuff(s)
+    char_u	*s;
+{
+    add_buff(&stuffbuff, s, -1L);
+}
+
+    void
+stuffReadbuffLen(s, len)
+    char_u	*s;
+    long	len;
+{
+    add_buff(&stuffbuff, s, len);
+}
+
+#if defined(FEAT_EVAL) || defined(PROTO)
+/*
+ * Stuff "s" into the stuff buffer, leaving special key codes unmodified and
+ * escaping other K_SPECIAL and CSI bytes.
+ */
+    void
+stuffReadbuffSpec(s)
+    char_u	*s;
+{
+    while (*s != NUL)
+    {
+	if (*s == K_SPECIAL && s[1] != NUL && s[2] != NUL)
+	{
+	    /* Insert special key literally. */
+	    stuffReadbuffLen(s, 3L);
+	    s += 3;
+	}
+	else
+#ifdef FEAT_MBYTE
+	    stuffcharReadbuff(mb_ptr2char_adv(&s));
+#else
+	    stuffcharReadbuff(*s++);
+#endif
+    }
+}
+#endif
+
+/*
+ * Append a character to the stuff buffer.
+ * Translates special keys, NUL, CSI, K_SPECIAL and multibyte characters.
+ */
+    void
+stuffcharReadbuff(c)
+    int		   c;
+{
+    add_char_buff(&stuffbuff, c);
+}
+
+/*
+ * Append a number to the stuff buffer.
+ */
+    void
+stuffnumReadbuff(n)
+    long    n;
+{
+    add_num_buff(&stuffbuff, n);
+}
+
+/*
+ * Read a character from the redo buffer.  Translates K_SPECIAL, CSI and
+ * multibyte characters.
+ * The redo buffer is left as it is.
+ * if init is TRUE, prepare for redo, return FAIL if nothing to redo, OK
+ * otherwise
+ * if old is TRUE, use old_redobuff instead of redobuff
+ */
+    static int
+read_redo(init, old_redo)
+    int		init;
+    int		old_redo;
+{
+    static struct buffblock	*bp;
+    static char_u		*p;
+    int				c;
+#ifdef FEAT_MBYTE
+    int				n;
+    char_u			buf[MB_MAXBYTES];
+    int				i;
+#endif
+
+    if (init)
+    {
+	if (old_redo)
+	    bp = old_redobuff.bh_first.b_next;
+	else
+	    bp = redobuff.bh_first.b_next;
+	if (bp == NULL)
+	    return FAIL;
+	p = bp->b_str;
+	return OK;
+    }
+    if ((c = *p) != NUL)
+    {
+	/* Reverse the conversion done by add_char_buff() */
+#ifdef FEAT_MBYTE
+	/* For a multi-byte character get all the bytes and return the
+	 * converted character. */
+	if (has_mbyte && (c != K_SPECIAL || p[1] == KS_SPECIAL))
+	    n = MB_BYTE2LEN_CHECK(c);
+	else
+	    n = 1;
+	for (i = 0; ; ++i)
+#endif
+	{
+	    if (c == K_SPECIAL) /* special key or escaped K_SPECIAL */
+	    {
+		c = TO_SPECIAL(p[1], p[2]);
+		p += 2;
+	    }
+#ifdef FEAT_GUI
+	    if (c == CSI)	/* escaped CSI */
+		p += 2;
+#endif
+	    if (*++p == NUL && bp->b_next != NULL)
+	    {
+		bp = bp->b_next;
+		p = bp->b_str;
+	    }
+#ifdef FEAT_MBYTE
+	    buf[i] = c;
+	    if (i == n - 1)	/* last byte of a character */
+	    {
+		if (n != 1)
+		    c = (*mb_ptr2char)(buf);
+		break;
+	    }
+	    c = *p;
+	    if (c == NUL)	/* cannot happen? */
+		break;
+#endif
+	}
+    }
+
+    return c;
+}
+
+/*
+ * Copy the rest of the redo buffer into the stuff buffer (in a slow way).
+ * If old_redo is TRUE, use old_redobuff instead of redobuff.
+ * The escaped K_SPECIAL and CSI are copied without translation.
+ */
+    static void
+copy_redo(old_redo)
+    int	    old_redo;
+{
+    int	    c;
+
+    while ((c = read_redo(FALSE, old_redo)) != NUL)
+	stuffcharReadbuff(c);
+}
+
+/*
+ * Stuff the redo buffer into the stuffbuff.
+ * Insert the redo count into the command.
+ * If "old_redo" is TRUE, the last but one command is repeated
+ * instead of the last command (inserting text). This is used for
+ * CTRL-O <.> in insert mode
+ *
+ * return FAIL for failure, OK otherwise
+ */
+    int
+start_redo(count, old_redo)
+    long    count;
+    int	    old_redo;
+{
+    int	    c;
+
+    /* init the pointers; return if nothing to redo */
+    if (read_redo(TRUE, old_redo) == FAIL)
+	return FAIL;
+
+    c = read_redo(FALSE, old_redo);
+
+    /* copy the buffer name, if present */
+    if (c == '"')
+    {
+	add_buff(&stuffbuff, (char_u *)"\"", 1L);
+	c = read_redo(FALSE, old_redo);
+
+	/* if a numbered buffer is used, increment the number */
+	if (c >= '1' && c < '9')
+	    ++c;
+	add_char_buff(&stuffbuff, c);
+	c = read_redo(FALSE, old_redo);
+    }
+
+#ifdef FEAT_VISUAL
+    if (c == 'v')   /* redo Visual */
+    {
+	VIsual = curwin->w_cursor;
+	VIsual_active = TRUE;
+	VIsual_select = FALSE;
+	VIsual_reselect = TRUE;
+	redo_VIsual_busy = TRUE;
+	c = read_redo(FALSE, old_redo);
+    }
+#endif
+
+    /* try to enter the count (in place of a previous count) */
+    if (count)
+    {
+	while (VIM_ISDIGIT(c))	/* skip "old" count */
+	    c = read_redo(FALSE, old_redo);
+	add_num_buff(&stuffbuff, count);
+    }
+
+    /* copy from the redo buffer into the stuff buffer */
+    add_char_buff(&stuffbuff, c);
+    copy_redo(old_redo);
+    return OK;
+}
+
+/*
+ * Repeat the last insert (R, o, O, a, A, i or I command) by stuffing
+ * the redo buffer into the stuffbuff.
+ * return FAIL for failure, OK otherwise
+ */
+    int
+start_redo_ins()
+{
+    int	    c;
+
+    if (read_redo(TRUE, FALSE) == FAIL)
+	return FAIL;
+    start_stuff();
+
+    /* skip the count and the command character */
+    while ((c = read_redo(FALSE, FALSE)) != NUL)
+    {
+	if (vim_strchr((char_u *)"AaIiRrOo", c) != NULL)
+	{
+	    if (c == 'O' || c == 'o')
+		stuffReadbuff(NL_STR);
+	    break;
+	}
+    }
+
+    /* copy the typed text from the redo buffer into the stuff buffer */
+    copy_redo(FALSE);
+    block_redo = TRUE;
+    return OK;
+}
+
+    void
+stop_redo_ins()
+{
+    block_redo = FALSE;
+}
+
+/*
+ * Initialize typebuf.tb_buf to point to typebuf_init.
+ * alloc() cannot be used here: In out-of-memory situations it would
+ * be impossible to type anything.
+ */
+    static void
+init_typebuf()
+{
+    if (typebuf.tb_buf == NULL)
+    {
+	typebuf.tb_buf = typebuf_init;
+	typebuf.tb_noremap = noremapbuf_init;
+	typebuf.tb_buflen = TYPELEN_INIT;
+	typebuf.tb_len = 0;
+	typebuf.tb_off = 0;
+	typebuf.tb_change_cnt = 1;
+    }
+}
+
+/*
+ * insert a string in position 'offset' in the typeahead buffer (for "@r"
+ * and ":normal" command, vgetorpeek() and check_termcode())
+ *
+ * If noremap is REMAP_YES, new string can be mapped again.
+ * If noremap is REMAP_NONE, new string cannot be mapped again.
+ * If noremap is REMAP_SKIP, fist char of new string cannot be mapped again,
+ * but abbreviations are allowed.
+ * If noremap is REMAP_SCRIPT, new string cannot be mapped again, except for
+ *			script-local mappings.
+ * If noremap is > 0, that many characters of the new string cannot be mapped.
+ *
+ * If nottyped is TRUE, the string does not return KeyTyped (don't use when
+ * offset is non-zero!).
+ *
+ * If silent is TRUE, cmd_silent is set when the characters are obtained.
+ *
+ * return FAIL for failure, OK otherwise
+ */
+    int
+ins_typebuf(str, noremap, offset, nottyped, silent)
+    char_u	*str;
+    int		noremap;
+    int		offset;
+    int		nottyped;
+    int		silent;
+{
+    char_u	*s1, *s2;
+    int		newlen;
+    int		addlen;
+    int		i;
+    int		newoff;
+    int		val;
+    int		nrm;
+
+    init_typebuf();
+    if (++typebuf.tb_change_cnt == 0)
+	typebuf.tb_change_cnt = 1;
+
+    addlen = (int)STRLEN(str);
+
+    /*
+     * Easy case: there is room in front of typebuf.tb_buf[typebuf.tb_off]
+     */
+    if (offset == 0 && addlen <= typebuf.tb_off)
+    {
+	typebuf.tb_off -= addlen;
+	mch_memmove(typebuf.tb_buf + typebuf.tb_off, str, (size_t)addlen);
+    }
+
+    /*
+     * Need to allocate a new buffer.
+     * In typebuf.tb_buf there must always be room for 3 * MAXMAPLEN + 4
+     * characters.  We add some extra room to avoid having to allocate too
+     * often.
+     */
+    else
+    {
+	newoff = MAXMAPLEN + 4;
+	newlen = typebuf.tb_len + addlen + newoff + 4 * (MAXMAPLEN + 4);
+	if (newlen < 0)		    /* string is getting too long */
+	{
+	    EMSG(_(e_toocompl));    /* also calls flush_buffers */
+	    setcursor();
+	    return FAIL;
+	}
+	s1 = alloc(newlen);
+	if (s1 == NULL)		    /* out of memory */
+	    return FAIL;
+	s2 = alloc(newlen);
+	if (s2 == NULL)		    /* out of memory */
+	{
+	    vim_free(s1);
+	    return FAIL;
+	}
+	typebuf.tb_buflen = newlen;
+
+	/* copy the old chars, before the insertion point */
+	mch_memmove(s1 + newoff, typebuf.tb_buf + typebuf.tb_off,
+							      (size_t)offset);
+	/* copy the new chars */
+	mch_memmove(s1 + newoff + offset, str, (size_t)addlen);
+	/* copy the old chars, after the insertion point, including the	NUL at
+	 * the end */
+	mch_memmove(s1 + newoff + offset + addlen,
+				     typebuf.tb_buf + typebuf.tb_off + offset,
+				       (size_t)(typebuf.tb_len - offset + 1));
+	if (typebuf.tb_buf != typebuf_init)
+	    vim_free(typebuf.tb_buf);
+	typebuf.tb_buf = s1;
+
+	mch_memmove(s2 + newoff, typebuf.tb_noremap + typebuf.tb_off,
+							      (size_t)offset);
+	mch_memmove(s2 + newoff + offset + addlen,
+		   typebuf.tb_noremap + typebuf.tb_off + offset,
+					   (size_t)(typebuf.tb_len - offset));
+	if (typebuf.tb_noremap != noremapbuf_init)
+	    vim_free(typebuf.tb_noremap);
+	typebuf.tb_noremap = s2;
+
+	typebuf.tb_off = newoff;
+    }
+    typebuf.tb_len += addlen;
+
+    /* If noremap == REMAP_SCRIPT: do remap script-local mappings. */
+    if (noremap == REMAP_SCRIPT)
+	val = RM_SCRIPT;
+    else if (noremap == REMAP_SKIP)
+	val = RM_ABBR;
+    else
+	val = RM_NONE;
+
+    /*
+     * Adjust typebuf.tb_noremap[] for the new characters:
+     * If noremap == REMAP_NONE or REMAP_SCRIPT: new characters are
+     *			(sometimes) not remappable
+     * If noremap == REMAP_YES: all the new characters are mappable
+     * If noremap  > 0: "noremap" characters are not remappable, the rest
+     *			mappable
+     */
+    if (noremap == REMAP_SKIP)
+	nrm = 1;
+    else if (noremap < 0)
+	nrm = addlen;
+    else
+	nrm = noremap;
+    for (i = 0; i < addlen; ++i)
+	typebuf.tb_noremap[typebuf.tb_off + i + offset] =
+						  (--nrm >= 0) ? val : RM_YES;
+
+    /* tb_maplen and tb_silent only remember the length of mapped and/or
+     * silent mappings at the start of the buffer, assuming that a mapped
+     * sequence doesn't result in typed characters. */
+    if (nottyped || typebuf.tb_maplen > offset)
+	typebuf.tb_maplen += addlen;
+    if (silent || typebuf.tb_silent > offset)
+    {
+	typebuf.tb_silent += addlen;
+	cmd_silent = TRUE;
+    }
+    if (typebuf.tb_no_abbr_cnt && offset == 0)	/* and not used for abbrev.s */
+	typebuf.tb_no_abbr_cnt += addlen;
+
+    return OK;
+}
+
+/*
+ * Put character "c" back into the typeahead buffer.
+ * Can be used for a character obtained by vgetc() that needs to be put back.
+ * Uses cmd_silent, KeyTyped and KeyNoremap to restore the flags belonging to
+ * the char.
+ */
+    void
+ins_char_typebuf(c)
+    int	    c;
+{
+#ifdef FEAT_MBYTE
+    char_u	buf[MB_MAXBYTES];
+#else
+    char_u	buf[4];
+#endif
+    if (IS_SPECIAL(c))
+    {
+	buf[0] = K_SPECIAL;
+	buf[1] = K_SECOND(c);
+	buf[2] = K_THIRD(c);
+	buf[3] = NUL;
+    }
+    else
+    {
+#ifdef FEAT_MBYTE
+	buf[(*mb_char2bytes)(c, buf)] = NUL;
+#else
+	buf[0] = c;
+	buf[1] = NUL;
+#endif
+    }
+    (void)ins_typebuf(buf, KeyNoremap, 0, !KeyTyped, cmd_silent);
+}
+
+/*
+ * Return TRUE if the typeahead buffer was changed (while waiting for a
+ * character to arrive).  Happens when a message was received from a client or
+ * from feedkeys().
+ * But check in a more generic way to avoid trouble: When "typebuf.tb_buf"
+ * changed it was reallocated and the old pointer can no longer be used.
+ * Or "typebuf.tb_off" may have been changed and we would overwrite characters
+ * that was just added.
+ */
+    int
+typebuf_changed(tb_change_cnt)
+    int		tb_change_cnt;	/* old value of typebuf.tb_change_cnt */
+{
+    return (tb_change_cnt != 0 && (typebuf.tb_change_cnt != tb_change_cnt
+#if defined(FEAT_CLIENTSERVER) || defined(FEAT_EVAL)
+	    || typebuf_was_filled
+#endif
+	   ));
+}
+
+/*
+ * Return TRUE if there are no characters in the typeahead buffer that have
+ * not been typed (result from a mapping or come from ":normal").
+ */
+    int
+typebuf_typed()
+{
+    return typebuf.tb_maplen == 0;
+}
+
+#if defined(FEAT_VISUAL) || defined(PROTO)
+/*
+ * Return the number of characters that are mapped (or not typed).
+ */
+    int
+typebuf_maplen()
+{
+    return typebuf.tb_maplen;
+}
+#endif
+
+/*
+ * remove "len" characters from typebuf.tb_buf[typebuf.tb_off + offset]
+ */
+    void
+del_typebuf(len, offset)
+    int	len;
+    int	offset;
+{
+    int	    i;
+
+    if (len == 0)
+	return;		/* nothing to do */
+
+    typebuf.tb_len -= len;
+
+    /*
+     * Easy case: Just increase typebuf.tb_off.
+     */
+    if (offset == 0 && typebuf.tb_buflen - (typebuf.tb_off + len)
+							 >= 3 * MAXMAPLEN + 3)
+	typebuf.tb_off += len;
+    /*
+     * Have to move the characters in typebuf.tb_buf[] and typebuf.tb_noremap[]
+     */
+    else
+    {
+	i = typebuf.tb_off + offset;
+	/*
+	 * Leave some extra room at the end to avoid reallocation.
+	 */
+	if (typebuf.tb_off > MAXMAPLEN)
+	{
+	    mch_memmove(typebuf.tb_buf + MAXMAPLEN,
+			     typebuf.tb_buf + typebuf.tb_off, (size_t)offset);
+	    mch_memmove(typebuf.tb_noremap + MAXMAPLEN,
+			 typebuf.tb_noremap + typebuf.tb_off, (size_t)offset);
+	    typebuf.tb_off = MAXMAPLEN;
+	}
+	/* adjust typebuf.tb_buf (include the NUL at the end) */
+	mch_memmove(typebuf.tb_buf + typebuf.tb_off + offset,
+						     typebuf.tb_buf + i + len,
+				       (size_t)(typebuf.tb_len - offset + 1));
+	/* adjust typebuf.tb_noremap[] */
+	mch_memmove(typebuf.tb_noremap + typebuf.tb_off + offset,
+						 typebuf.tb_noremap + i + len,
+					   (size_t)(typebuf.tb_len - offset));
+    }
+
+    if (typebuf.tb_maplen > offset)		/* adjust tb_maplen */
+    {
+	if (typebuf.tb_maplen < offset + len)
+	    typebuf.tb_maplen = offset;
+	else
+	    typebuf.tb_maplen -= len;
+    }
+    if (typebuf.tb_silent > offset)		/* adjust tb_silent */
+    {
+	if (typebuf.tb_silent < offset + len)
+	    typebuf.tb_silent = offset;
+	else
+	    typebuf.tb_silent -= len;
+    }
+    if (typebuf.tb_no_abbr_cnt > offset)	/* adjust tb_no_abbr_cnt */
+    {
+	if (typebuf.tb_no_abbr_cnt < offset + len)
+	    typebuf.tb_no_abbr_cnt = offset;
+	else
+	    typebuf.tb_no_abbr_cnt -= len;
+    }
+
+#if defined(FEAT_CLIENTSERVER) || defined(FEAT_EVAL)
+    /* Reset the flag that text received from a client or from feedkeys()
+     * was inserted in the typeahead buffer. */
+    typebuf_was_filled = FALSE;
+#endif
+    if (++typebuf.tb_change_cnt == 0)
+	typebuf.tb_change_cnt = 1;
+}
+
+/*
+ * Write typed characters to script file.
+ * If recording is on put the character in the recordbuffer.
+ */
+    static void
+gotchars(chars, len)
+    char_u	*chars;
+    int		len;
+{
+    char_u	*s = chars;
+    int		c;
+    char_u	buf[2];
+    int		todo = len;
+
+    /* remember how many chars were last recorded */
+    if (Recording)
+	last_recorded_len += len;
+
+    buf[1] = NUL;
+    while (todo--)
+    {
+	/* Handle one byte at a time; no translation to be done. */
+	c = *s++;
+	updatescript(c);
+
+	if (Recording)
+	{
+	    buf[0] = c;
+	    add_buff(&recordbuff, buf, 1L);
+	}
+    }
+    may_sync_undo();
+
+#ifdef FEAT_EVAL
+    /* output "debug mode" message next time in debug mode */
+    debug_did_msg = FALSE;
+#endif
+
+    /* Since characters have been typed, consider the following to be in
+     * another mapping.  Search string will be kept in history. */
+    ++maptick;
+}
+
+/*
+ * Sync undo.  Called when typed characters are obtained from the typeahead
+ * buffer, or when a menu is used.
+ * Do not sync:
+ * - In Insert mode, unless cursor key has been used.
+ * - While reading a script file.
+ * - When no_u_sync is non-zero.
+ */
+    static void
+may_sync_undo()
+{
+    if ((!(State & (INSERT + CMDLINE)) || arrow_used)
+					       && scriptin[curscript] == NULL)
+	u_sync(FALSE);
+}
+
+/*
+ * Make "typebuf" empty and allocate new buffers.
+ * Returns FAIL when out of memory.
+ */
+    int
+alloc_typebuf()
+{
+    typebuf.tb_buf = alloc(TYPELEN_INIT);
+    typebuf.tb_noremap = alloc(TYPELEN_INIT);
+    if (typebuf.tb_buf == NULL || typebuf.tb_noremap == NULL)
+    {
+	free_typebuf();
+	return FAIL;
+    }
+    typebuf.tb_buflen = TYPELEN_INIT;
+    typebuf.tb_off = 0;
+    typebuf.tb_len = 0;
+    typebuf.tb_maplen = 0;
+    typebuf.tb_silent = 0;
+    typebuf.tb_no_abbr_cnt = 0;
+    if (++typebuf.tb_change_cnt == 0)
+	typebuf.tb_change_cnt = 1;
+    return OK;
+}
+
+/*
+ * Free the buffers of "typebuf".
+ */
+    void
+free_typebuf()
+{
+    vim_free(typebuf.tb_buf);
+    vim_free(typebuf.tb_noremap);
+}
+
+/*
+ * When doing ":so! file", the current typeahead needs to be saved, and
+ * restored when "file" has been read completely.
+ */
+static typebuf_T saved_typebuf[NSCRIPT];
+
+    int
+save_typebuf()
+{
+    init_typebuf();
+    saved_typebuf[curscript] = typebuf;
+    /* If out of memory: restore typebuf and close file. */
+    if (alloc_typebuf() == FAIL)
+    {
+	closescript();
+	return FAIL;
+    }
+    return OK;
+}
+
+#if defined(FEAT_EVAL) || defined(FEAT_EX_EXTRA) || defined(PROTO)
+
+/*
+ * Save all three kinds of typeahead, so that the user must type at a prompt.
+ */
+    void
+save_typeahead(tp)
+    tasave_T	*tp;
+{
+    tp->save_typebuf = typebuf;
+    tp->typebuf_valid = (alloc_typebuf() == OK);
+    if (!tp->typebuf_valid)
+	typebuf = tp->save_typebuf;
+
+    tp->save_stuffbuff = stuffbuff;
+    stuffbuff.bh_first.b_next = NULL;
+# ifdef USE_INPUT_BUF
+    tp->save_inputbuf = get_input_buf();
+# endif
+}
+
+/*
+ * Restore the typeahead to what it was before calling save_typeahead().
+ * The allocated memory is freed, can only be called once!
+ */
+    void
+restore_typeahead(tp)
+    tasave_T	*tp;
+{
+    if (tp->typebuf_valid)
+    {
+	free_typebuf();
+	typebuf = tp->save_typebuf;
+    }
+
+    free_buff(&stuffbuff);
+    stuffbuff = tp->save_stuffbuff;
+# ifdef USE_INPUT_BUF
+    set_input_buf(tp->save_inputbuf);
+# endif
+}
+#endif
+
+/*
+ * Open a new script file for the ":source!" command.
+ */
+    void
+openscript(name, directly)
+    char_u	*name;
+    int		directly;	/* when TRUE execute directly */
+{
+    if (curscript + 1 == NSCRIPT)
+    {
+	EMSG(_(e_nesting));
+	return;
+    }
+
+    if (scriptin[curscript] != NULL)	/* already reading script */
+	++curscript;
+				/* use NameBuff for expanded name */
+    expand_env(name, NameBuff, MAXPATHL);
+    if ((scriptin[curscript] = mch_fopen((char *)NameBuff, READBIN)) == NULL)
+    {
+	EMSG2(_(e_notopen), name);
+	if (curscript)
+	    --curscript;
+	return;
+    }
+    if (save_typebuf() == FAIL)
+	return;
+
+    /*
+     * Execute the commands from the file right now when using ":source!"
+     * after ":global" or ":argdo" or in a loop.  Also when another command
+     * follows.  This means the display won't be updated.  Don't do this
+     * always, "make test" would fail.
+     */
+    if (directly)
+    {
+	oparg_T	oa;
+	int	oldcurscript;
+	int	save_State = State;
+	int	save_restart_edit = restart_edit;
+	int	save_insertmode = p_im;
+	int	save_finish_op = finish_op;
+	int	save_msg_scroll = msg_scroll;
+
+	State = NORMAL;
+	msg_scroll = FALSE;	/* no msg scrolling in Normal mode */
+	restart_edit = 0;	/* don't go to Insert mode */
+	p_im = FALSE;		/* don't use 'insertmode' */
+	clear_oparg(&oa);
+	finish_op = FALSE;
+
+	oldcurscript = curscript;
+	do
+	{
+	    update_topline_cursor();	/* update cursor position and topline */
+	    normal_cmd(&oa, FALSE);	/* execute one command */
+	    vpeekc();			/* check for end of file */
+	}
+	while (scriptin[oldcurscript] != NULL);
+
+	State = save_State;
+	msg_scroll = save_msg_scroll;
+	restart_edit = save_restart_edit;
+	p_im = save_insertmode;
+	finish_op = save_finish_op;
+    }
+}
+
+/*
+ * Close the currently active input script.
+ */
+    static void
+closescript()
+{
+    free_typebuf();
+    typebuf = saved_typebuf[curscript];
+
+    fclose(scriptin[curscript]);
+    scriptin[curscript] = NULL;
+    if (curscript > 0)
+	--curscript;
+}
+
+#if defined(EXITFREE) || defined(PROTO)
+    void
+close_all_scripts()
+{
+    while (scriptin[0] != NULL)
+	closescript();
+}
+#endif
+
+#if defined(FEAT_INS_EXPAND) || defined(PROTO)
+/*
+ * Return TRUE when reading keys from a script file.
+ */
+    int
+using_script()
+{
+    return scriptin[curscript] != NULL;
+}
+#endif
+
+/*
+ * This function is called just before doing a blocking wait.  Thus after
+ * waiting 'updatetime' for a character to arrive.
+ */
+    void
+before_blocking()
+{
+    updatescript(0);
+#ifdef FEAT_EVAL
+    if (may_garbage_collect)
+	garbage_collect();
+#endif
+}
+
+/*
+ * updatescipt() is called when a character can be written into the script file
+ * or when we have waited some time for a character (c == 0)
+ *
+ * All the changed memfiles are synced if c == 0 or when the number of typed
+ * characters reaches 'updatecount' and 'updatecount' is non-zero.
+ */
+    void
+updatescript(c)
+    int c;
+{
+    static int	    count = 0;
+
+    if (c && scriptout)
+	putc(c, scriptout);
+    if (c == 0 || (p_uc > 0 && ++count >= p_uc))
+    {
+	ml_sync_all(c == 0, TRUE);
+	count = 0;
+    }
+}
+
+#define KL_PART_KEY -1		/* keylen value for incomplete key-code */
+#define KL_PART_MAP -2		/* keylen value for incomplete mapping */
+
+static int old_char = -1;	/* character put back by vungetc() */
+static int old_mod_mask;	/* mod_mask for ungotten character */
+
+/*
+ * Get the next input character.
+ * Can return a special key or a multi-byte character.
+ * Can return NUL when called recursively, use safe_vgetc() if that's not
+ * wanted.
+ * This translates escaped K_SPECIAL and CSI bytes to a K_SPECIAL or CSI byte.
+ * Collects the bytes of a multibyte character into the whole character.
+ * Returns the modifers in the global "mod_mask".
+ */
+    int
+vgetc()
+{
+    int		c, c2;
+#ifdef FEAT_MBYTE
+    int		n;
+    char_u	buf[MB_MAXBYTES];
+    int		i;
+#endif
+
+#ifdef FEAT_EVAL
+    /* Do garbage collection when garbagecollect() was called previously and
+     * we are now at the toplevel. */
+    if (may_garbage_collect && want_garbage_collect)
+	garbage_collect();
+#endif
+
+    /*
+     * If a character was put back with vungetc, it was already processed.
+     * Return it directly.
+     */
+    if (old_char != -1)
+    {
+	c = old_char;
+	old_char = -1;
+	mod_mask = old_mod_mask;
+    }
+    else
+    {
+      mod_mask = 0x0;
+      last_recorded_len = 0;
+      for (;;)			/* this is done twice if there are modifiers */
+      {
+	if (mod_mask)		/* no mapping after modifier has been read */
+	{
+	    ++no_mapping;
+	    ++allow_keys;
+	}
+	c = vgetorpeek(TRUE);
+	if (mod_mask)
+	{
+	    --no_mapping;
+	    --allow_keys;
+	}
+
+	/* Get two extra bytes for special keys */
+	if (c == K_SPECIAL
+#ifdef FEAT_GUI
+		|| c == CSI
+#endif
+	   )
+	{
+	    int	    save_allow_keys = allow_keys;
+
+	    ++no_mapping;
+	    allow_keys = 0;		/* make sure BS is not found */
+	    c2 = vgetorpeek(TRUE);	/* no mapping for these chars */
+	    c = vgetorpeek(TRUE);
+	    --no_mapping;
+	    allow_keys = save_allow_keys;
+	    if (c2 == KS_MODIFIER)
+	    {
+		mod_mask = c;
+		continue;
+	    }
+	    c = TO_SPECIAL(c2, c);
+
+#if defined(FEAT_GUI_W32) && defined(FEAT_MENU) && defined(FEAT_TEAROFF)
+	    /* Handle K_TEAROFF here, the caller of vgetc() doesn't need to
+	     * know that a menu was torn off */
+	    if (c == K_TEAROFF)
+	    {
+		char_u	name[200];
+		int	i;
+
+		/* get menu path, it ends with a <CR> */
+		for (i = 0; (c = vgetorpeek(TRUE)) != '\r'; )
+		{
+		    name[i] = c;
+		    if (i < 199)
+			++i;
+		}
+		name[i] = NUL;
+		gui_make_tearoff(name);
+		continue;
+	    }
+#endif
+#if defined(FEAT_GUI) && defined(HAVE_GTK2) && defined(FEAT_MENU)
+	    /* GTK: <F10> normally selects the menu, but it's passed until
+	     * here to allow mapping it.  Intercept and invoke the GTK
+	     * behavior if it's not mapped. */
+	    if (c == K_F10 && gui.menubar != NULL)
+	    {
+		gtk_menu_shell_select_first(GTK_MENU_SHELL(gui.menubar), FALSE);
+		continue;
+	    }
+#endif
+
+#ifdef FEAT_GUI
+	    /* Translate K_CSI to CSI.  The special key is only used to avoid
+	     * it being recognized as the start of a special key. */
+	    if (c == K_CSI)
+		c = CSI;
+#endif
+	}
+#ifdef MSDOS
+	/*
+	 * If K_NUL was typed, it is replaced by K_NUL, 3 in mch_inchar().
+	 * Delete the 3 here.
+	 */
+	else if (c == K_NUL && vpeekc() == 3)
+	    (void)vgetorpeek(TRUE);
+#endif
+
+	/* a keypad or special function key was not mapped, use it like
+	 * its ASCII equivalent */
+	switch (c)
+	{
+	    case K_KPLUS:		c = '+'; break;
+	    case K_KMINUS:		c = '-'; break;
+	    case K_KDIVIDE:		c = '/'; break;
+	    case K_KMULTIPLY:	c = '*'; break;
+	    case K_KENTER:		c = CAR; break;
+	    case K_KPOINT:
+#ifdef WIN32
+				    /* Can be either '.' or a ',', *
+				     * depending on the type of keypad. */
+				    c = MapVirtualKey(VK_DECIMAL, 2); break;
+#else
+				    c = '.'; break;
+#endif
+	    case K_K0:		c = '0'; break;
+	    case K_K1:		c = '1'; break;
+	    case K_K2:		c = '2'; break;
+	    case K_K3:		c = '3'; break;
+	    case K_K4:		c = '4'; break;
+	    case K_K5:		c = '5'; break;
+	    case K_K6:		c = '6'; break;
+	    case K_K7:		c = '7'; break;
+	    case K_K8:		c = '8'; break;
+	    case K_K9:		c = '9'; break;
+
+	    case K_XHOME:
+	    case K_ZHOME:	if (mod_mask == MOD_MASK_SHIFT)
+				{
+				    c = K_S_HOME;
+				    mod_mask = 0;
+				}
+				else if (mod_mask == MOD_MASK_CTRL)
+				{
+				    c = K_C_HOME;
+				    mod_mask = 0;
+				}
+				else
+				    c = K_HOME;
+				break;
+	    case K_XEND:
+	    case K_ZEND:	if (mod_mask == MOD_MASK_SHIFT)
+				{
+				    c = K_S_END;
+				    mod_mask = 0;
+				}
+				else if (mod_mask == MOD_MASK_CTRL)
+				{
+				    c = K_C_END;
+				    mod_mask = 0;
+				}
+				else
+				    c = K_END;
+				break;
+
+	    case K_XUP:		c = K_UP; break;
+	    case K_XDOWN:	c = K_DOWN; break;
+	    case K_XLEFT:	c = K_LEFT; break;
+	    case K_XRIGHT:	c = K_RIGHT; break;
+	}
+
+#ifdef FEAT_MBYTE
+	/* For a multi-byte character get all the bytes and return the
+	 * converted character.
+	 * Note: This will loop until enough bytes are received!
+	 */
+	if (has_mbyte && (n = MB_BYTE2LEN_CHECK(c)) > 1)
+	{
+	    ++no_mapping;
+	    buf[0] = c;
+	    for (i = 1; i < n; ++i)
+	    {
+		buf[i] = vgetorpeek(TRUE);
+		if (buf[i] == K_SPECIAL
+#ifdef FEAT_GUI
+			|| buf[i] == CSI
+#endif
+			)
+		{
+		    /* Must be a K_SPECIAL - KS_SPECIAL - KE_FILLER sequence,
+		     * which represents a K_SPECIAL (0x80),
+		     * or a CSI - KS_EXTRA - KE_CSI sequence, which represents
+		     * a CSI (0x9B),
+		     * of a K_SPECIAL - KS_EXTRA - KE_CSI, which is CSI too. */
+		    c = vgetorpeek(TRUE);
+		    if (vgetorpeek(TRUE) == (int)KE_CSI && c == KS_EXTRA)
+			buf[i] = CSI;
+		}
+	    }
+	    --no_mapping;
+	    c = (*mb_ptr2char)(buf);
+	}
+#endif
+
+	break;
+      }
+    }
+
+#ifdef FEAT_EVAL
+    /*
+     * In the main loop "may_garbage_collect" can be set to do garbage
+     * collection in the first next vgetc().  It's disabled after that to
+     * avoid internally used Lists and Dicts to be freed.
+     */
+    may_garbage_collect = FALSE;
+#endif
+
+    return c;
+}
+
+/*
+ * Like vgetc(), but never return a NUL when called recursively, get a key
+ * directly from the user (ignoring typeahead).
+ */
+    int
+safe_vgetc()
+{
+    int	c;
+
+    c = vgetc();
+    if (c == NUL)
+	c = get_keystroke();
+    return c;
+}
+
+/*
+ * Check if a character is available, such that vgetc() will not block.
+ * If the next character is a special character or multi-byte, the returned
+ * character is not valid!.
+ */
+    int
+vpeekc()
+{
+    if (old_char != -1)
+	return old_char;
+    return vgetorpeek(FALSE);
+}
+
+#if defined(FEAT_TERMRESPONSE) || defined(PROTO)
+/*
+ * Like vpeekc(), but don't allow mapping.  Do allow checking for terminal
+ * codes.
+ */
+    int
+vpeekc_nomap()
+{
+    int		c;
+
+    ++no_mapping;
+    ++allow_keys;
+    c = vpeekc();
+    --no_mapping;
+    --allow_keys;
+    return c;
+}
+#endif
+
+#if defined(FEAT_INS_EXPAND) || defined(PROTO)
+/*
+ * Check if any character is available, also half an escape sequence.
+ * Trick: when no typeahead found, but there is something in the typeahead
+ * buffer, it must be an ESC that is recognized as the start of a key code.
+ */
+    int
+vpeekc_any()
+{
+    int		c;
+
+    c = vpeekc();
+    if (c == NUL && typebuf.tb_len > 0)
+	c = ESC;
+    return c;
+}
+#endif
+
+/*
+ * Call vpeekc() without causing anything to be mapped.
+ * Return TRUE if a character is available, FALSE otherwise.
+ */
+    int
+char_avail()
+{
+    int	    retval;
+
+    ++no_mapping;
+    retval = vpeekc();
+    --no_mapping;
+    return (retval != NUL);
+}
+
+    void
+vungetc(c)	/* unget one character (can only be done once!) */
+    int		c;
+{
+    old_char = c;
+    old_mod_mask = mod_mask;
+}
+
+/*
+ * get a character:
+ * 1. from the stuffbuffer
+ *	This is used for abbreviated commands like "D" -> "d$".
+ *	Also used to redo a command for ".".
+ * 2. from the typeahead buffer
+ *	Stores text obtained previously but not used yet.
+ *	Also stores the result of mappings.
+ *	Also used for the ":normal" command.
+ * 3. from the user
+ *	This may do a blocking wait if "advance" is TRUE.
+ *
+ * if "advance" is TRUE (vgetc()):
+ *	really get the character.
+ *	KeyTyped is set to TRUE in the case the user typed the key.
+ *	KeyStuffed is TRUE if the character comes from the stuff buffer.
+ * if "advance" is FALSE (vpeekc()):
+ *	just look whether there is a character available.
+ *
+ * When "no_mapping" is zero, checks for mappings in the current mode.
+ * Only returns one byte (of a multi-byte character).
+ * K_SPECIAL and CSI may be escaped, need to get two more bytes then.
+ */
+    static int
+vgetorpeek(advance)
+    int	    advance;
+{
+    int		c, c1;
+    int		keylen;
+    char_u	*s;
+    mapblock_T	*mp;
+#ifdef FEAT_LOCALMAP
+    mapblock_T	*mp2;
+#endif
+    mapblock_T	*mp_match;
+    int		mp_match_len = 0;
+    int		timedout = FALSE;	    /* waited for more than 1 second
+						for mapping to complete */
+    int		mapdepth = 0;	    /* check for recursive mapping */
+    int		mode_deleted = FALSE;   /* set when mode has been deleted */
+    int		local_State;
+    int		mlen;
+    int		max_mlen;
+    int		i;
+#ifdef FEAT_CMDL_INFO
+    int		new_wcol, new_wrow;
+#endif
+#ifdef FEAT_GUI
+# ifdef FEAT_MENU
+    int		idx;
+# endif
+    int		shape_changed = FALSE;  /* adjusted cursor shape */
+#endif
+    int		n;
+#ifdef FEAT_LANGMAP
+    int		nolmaplen;
+#endif
+    int		old_wcol, old_wrow;
+    int		wait_tb_len;
+
+    /*
+     * This function doesn't work very well when called recursively.  This may
+     * happen though, because of:
+     * 1. The call to add_to_showcmd().	char_avail() is then used to check if
+     * there is a character available, which calls this function.  In that
+     * case we must return NUL, to indicate no character is available.
+     * 2. A GUI callback function writes to the screen, causing a
+     * wait_return().
+     * Using ":normal" can also do this, but it saves the typeahead buffer,
+     * thus it should be OK.  But don't get a key from the user then.
+     */
+    if (vgetc_busy > 0
+#ifdef FEAT_EX_EXTRA
+	    && ex_normal_busy == 0
+#endif
+	    )
+	return NUL;
+
+    local_State = get_real_state();
+
+    ++vgetc_busy;
+
+    if (advance)
+	KeyStuffed = FALSE;
+
+    init_typebuf();
+    start_stuff();
+    if (advance && typebuf.tb_maplen == 0)
+	Exec_reg = FALSE;
+    do
+    {
+/*
+ * get a character: 1. from the stuffbuffer
+ */
+	if (typeahead_char != 0)
+	{
+	    c = typeahead_char;
+	    if (advance)
+		typeahead_char = 0;
+	}
+	else
+	    c = read_stuff(advance);
+	if (c != NUL && !got_int)
+	{
+	    if (advance)
+	    {
+		/* KeyTyped = FALSE;  When the command that stuffed something
+		 * was typed, behave like the stuffed command was typed.
+		 * needed for CTRL-W CTRl-] to open a fold, for example. */
+		KeyStuffed = TRUE;
+	    }
+	    if (typebuf.tb_no_abbr_cnt == 0)
+		typebuf.tb_no_abbr_cnt = 1;	/* no abbreviations now */
+	}
+	else
+	{
+	    /*
+	     * Loop until we either find a matching mapped key, or we
+	     * are sure that it is not a mapped key.
+	     * If a mapped key sequence is found we go back to the start to
+	     * try re-mapping.
+	     */
+	    for (;;)
+	    {
+		/*
+		 * ui_breakcheck() is slow, don't use it too often when
+		 * inside a mapping.  But call it each time for typed
+		 * characters.
+		 */
+		if (typebuf.tb_maplen)
+		    line_breakcheck();
+		else
+		    ui_breakcheck();		/* check for CTRL-C */
+		keylen = 0;
+		if (got_int)
+		{
+		    /* flush all input */
+		    c = inchar(typebuf.tb_buf, typebuf.tb_buflen - 1, 0L,
+						       typebuf.tb_change_cnt);
+		    /*
+		     * If inchar() returns TRUE (script file was active) or we
+		     * are inside a mapping, get out of insert mode.
+		     * Otherwise we behave like having gotten a CTRL-C.
+		     * As a result typing CTRL-C in insert mode will
+		     * really insert a CTRL-C.
+		     */
+		    if ((c || typebuf.tb_maplen)
+					      && (State & (INSERT + CMDLINE)))
+			c = ESC;
+		    else
+			c = Ctrl_C;
+		    flush_buffers(TRUE);	/* flush all typeahead */
+
+		    if (advance)
+		    {
+			/* Also record this character, it might be needed to
+			 * get out of Insert mode. */
+			*typebuf.tb_buf = c;
+			gotchars(typebuf.tb_buf, 1);
+		    }
+		    cmd_silent = FALSE;
+
+		    break;
+		}
+		else if (typebuf.tb_len > 0)
+		{
+		    /*
+		     * Check for a mappable key sequence.
+		     * Walk through one maphash[] list until we find an
+		     * entry that matches.
+		     *
+		     * Don't look for mappings if:
+		     * - no_mapping set: mapping disabled (e.g. for CTRL-V)
+		     * - maphash_valid not set: no mappings present.
+		     * - typebuf.tb_buf[typebuf.tb_off] should not be remapped
+		     * - in insert or cmdline mode and 'paste' option set
+		     * - waiting for "hit return to continue" and CR or SPACE
+		     *	 typed
+		     * - waiting for a char with --more--
+		     * - in Ctrl-X mode, and we get a valid char for that mode
+		     */
+		    mp = NULL;
+		    max_mlen = 0;
+		    c1 = typebuf.tb_buf[typebuf.tb_off];
+		    if (no_mapping == 0 && maphash_valid
+			    && (no_zero_mapping == 0 || c1 != '0')
+			    && (typebuf.tb_maplen == 0
+				|| (p_remap
+				    && (typebuf.tb_noremap[typebuf.tb_off]
+						    & (RM_NONE|RM_ABBR)) == 0))
+			    && !(p_paste && (State & (INSERT + CMDLINE)))
+			    && !(State == HITRETURN && (c1 == CAR || c1 == ' '))
+			    && State != ASKMORE
+			    && State != CONFIRM
+#ifdef FEAT_INS_EXPAND
+			    && !((ctrl_x_mode != 0 && vim_is_ctrl_x_key(c1))
+				    || ((compl_cont_status & CONT_LOCAL)
+					&& (c1 == Ctrl_N || c1 == Ctrl_P)))
+#endif
+			    )
+		    {
+#ifdef FEAT_LANGMAP
+			if (c1 == K_SPECIAL)
+			    nolmaplen = 2;
+			else
+			{
+			    LANGMAP_ADJUST(c1, TRUE);
+			    nolmaplen = 0;
+			}
+#endif
+#ifdef FEAT_LOCALMAP
+			/* First try buffer-local mappings. */
+			mp = curbuf->b_maphash[MAP_HASH(local_State, c1)];
+			mp2 = maphash[MAP_HASH(local_State, c1)];
+			if (mp == NULL)
+			{
+			    mp = mp2;
+			    mp2 = NULL;
+			}
+#else
+			mp = maphash[MAP_HASH(local_State, c1)];
+#endif
+			/*
+			 * Loop until a partly matching mapping is found or
+			 * all (local) mappings have been checked.
+			 * The longest full match is remembered in "mp_match".
+			 * A full match is only accepted if there is no partly
+			 * match, so "aa" and "aaa" can both be mapped.
+			 */
+			mp_match = NULL;
+			mp_match_len = 0;
+			for ( ; mp != NULL;
+#ifdef FEAT_LOCALMAP
+				mp->m_next == NULL ? (mp = mp2, mp2 = NULL) :
+#endif
+				(mp = mp->m_next))
+			{
+			    /*
+			     * Only consider an entry if the first character
+			     * matches and it is for the current state.
+			     * Skip ":lmap" mappings if keys were mapped.
+			     */
+			    if (mp->m_keys[0] == c1
+				    && (mp->m_mode & local_State)
+				    && ((mp->m_mode & LANGMAP) == 0
+					|| typebuf.tb_maplen == 0))
+			    {
+#ifdef FEAT_LANGMAP
+				int	nomap = nolmaplen;
+				int	c2;
+#endif
+				/* find the match length of this mapping */
+				for (mlen = 1; mlen < typebuf.tb_len; ++mlen)
+				{
+#ifdef FEAT_LANGMAP
+				    c2 = typebuf.tb_buf[typebuf.tb_off + mlen];
+				    if (nomap > 0)
+					--nomap;
+				    else if (c2 == K_SPECIAL)
+					nomap = 2;
+				    else
+					LANGMAP_ADJUST(c2, TRUE);
+				    if (mp->m_keys[mlen] != c2)
+#else
+				    if (mp->m_keys[mlen] !=
+					typebuf.tb_buf[typebuf.tb_off + mlen])
+#endif
+					break;
+				}
+
+#ifdef FEAT_MBYTE
+				/* Don't allow mapping the first byte(s) of a
+				 * multi-byte char.  Happens when mapping
+				 * <M-a> and then changing 'encoding'. */
+				if (has_mbyte && MB_BYTE2LEN(c1)
+						  > (*mb_ptr2len)(mp->m_keys))
+				    mlen = 0;
+#endif
+				/*
+				 * Check an entry whether it matches.
+				 * - Full match: mlen == keylen
+				 * - Partly match: mlen == typebuf.tb_len
+				 */
+				keylen = mp->m_keylen;
+				if (mlen == keylen
+				     || (mlen == typebuf.tb_len
+						  && typebuf.tb_len < keylen))
+				{
+				    /*
+				     * If only script-local mappings are
+				     * allowed, check if the mapping starts
+				     * with K_SNR.
+				     */
+				    s = typebuf.tb_noremap + typebuf.tb_off;
+				    if (*s == RM_SCRIPT
+					    && (mp->m_keys[0] != K_SPECIAL
+						|| mp->m_keys[1] != KS_EXTRA
+						|| mp->m_keys[2]
+							      != (int)KE_SNR))
+					continue;
+				    /*
+				     * If one of the typed keys cannot be
+				     * remapped, skip the entry.
+				     */
+				    for (n = mlen; --n >= 0; )
+					if (*s++ & (RM_NONE|RM_ABBR))
+					    break;
+				    if (n >= 0)
+					continue;
+
+				    if (keylen > typebuf.tb_len)
+				    {
+					if (!timedout)
+					{
+					    /* break at a partly match */
+					    keylen = KL_PART_MAP;
+					    break;
+					}
+				    }
+				    else if (keylen > mp_match_len)
+				    {
+					/* found a longer match */
+					mp_match = mp;
+					mp_match_len = keylen;
+				    }
+				}
+				else
+				    /* No match; may have to check for
+				     * termcode at next character. */
+				    if (max_mlen < mlen)
+					max_mlen = mlen;
+			    }
+			}
+
+			/* If no partly match found, use the longest full
+			 * match. */
+			if (keylen != KL_PART_MAP)
+			{
+			    mp = mp_match;
+			    keylen = mp_match_len;
+			}
+		    }
+
+		    /* Check for match with 'pastetoggle' */
+		    if (*p_pt != NUL && mp == NULL && (State & (INSERT|NORMAL)))
+		    {
+			for (mlen = 0; mlen < typebuf.tb_len && p_pt[mlen];
+								       ++mlen)
+			    if (p_pt[mlen] != typebuf.tb_buf[typebuf.tb_off
+								      + mlen])
+				    break;
+			if (p_pt[mlen] == NUL)	/* match */
+			{
+			    /* write chars to script file(s) */
+			    if (mlen > typebuf.tb_maplen)
+				gotchars(typebuf.tb_buf + typebuf.tb_off
+							  + typebuf.tb_maplen,
+						    mlen - typebuf.tb_maplen);
+
+			    del_typebuf(mlen, 0); /* remove the chars */
+			    set_option_value((char_u *)"paste",
+						     (long)!p_paste, NULL, 0);
+			    if (!(State & INSERT))
+			    {
+				msg_col = 0;
+				msg_row = Rows - 1;
+				msg_clr_eos();		/* clear ruler */
+			    }
+			    showmode();
+			    setcursor();
+			    continue;
+			}
+			/* Need more chars for partly match. */
+			if (mlen == typebuf.tb_len)
+			    keylen = KL_PART_KEY;
+			else if (max_mlen < mlen)
+			    /* no match, may have to check for termcode at
+			     * next character */
+			    max_mlen = mlen + 1;
+		    }
+
+		    if ((mp == NULL || max_mlen >= mp_match_len)
+						     && keylen != KL_PART_MAP)
+		    {
+			/*
+			 * When no matching mapping found or found a
+			 * non-matching mapping that matches at least what the
+			 * matching mapping matched:
+			 * Check if we have a terminal code, when:
+			 *  mapping is allowed,
+			 *  keys have not been mapped,
+			 *  and not an ESC sequence, not in insert mode or
+			 *	p_ek is on,
+			 *  and when not timed out,
+			 */
+			if ((no_mapping == 0 || allow_keys != 0)
+				&& (typebuf.tb_maplen == 0
+				    || (p_remap && typebuf.tb_noremap[
+						   typebuf.tb_off] == RM_YES))
+				&& !timedout)
+			{
+			    keylen = check_termcode(max_mlen + 1, NULL, 0);
+
+			    /*
+			     * When getting a partial match, but the last
+			     * characters were not typed, don't wait for a
+			     * typed character to complete the termcode.
+			     * This helps a lot when a ":normal" command ends
+			     * in an ESC.
+			     */
+			    if (keylen < 0
+				       && typebuf.tb_len == typebuf.tb_maplen)
+				keylen = 0;
+			}
+			else
+			    keylen = 0;
+			if (keylen == 0)	/* no matching terminal code */
+			{
+#ifdef AMIGA			/* check for window bounds report */
+			    if (typebuf.tb_maplen == 0 && (typebuf.tb_buf[
+					       typebuf.tb_off] & 0xff) == CSI)
+			    {
+				for (s = typebuf.tb_buf + typebuf.tb_off + 1;
+					s < typebuf.tb_buf + typebuf.tb_off
+							      + typebuf.tb_len
+				   && (VIM_ISDIGIT(*s) || *s == ';'
+								|| *s == ' ');
+					++s)
+				    ;
+				if (*s == 'r' || *s == '|') /* found one */
+				{
+				    del_typebuf((int)(s + 1 -
+				       (typebuf.tb_buf + typebuf.tb_off)), 0);
+				    /* get size and redraw screen */
+				    shell_resized();
+				    continue;
+				}
+				if (*s == NUL)	    /* need more characters */
+				    keylen = KL_PART_KEY;
+			    }
+			    if (keylen >= 0)
+#endif
+			      /* When there was a matching mapping and no
+			       * termcode could be replaced after another one,
+			       * use that mapping. */
+			      if (mp == NULL)
+			      {
+/*
+ * get a character: 2. from the typeahead buffer
+ */
+				c = typebuf.tb_buf[typebuf.tb_off] & 255;
+				if (advance)	/* remove chars from tb_buf */
+				{
+				    cmd_silent = (typebuf.tb_silent > 0);
+				    if (typebuf.tb_maplen > 0)
+					KeyTyped = FALSE;
+				    else
+				    {
+					KeyTyped = TRUE;
+					/* write char to script file(s) */
+					gotchars(typebuf.tb_buf
+							 + typebuf.tb_off, 1);
+				    }
+				    KeyNoremap = typebuf.tb_noremap[
+							      typebuf.tb_off];
+				    del_typebuf(1, 0);
+				}
+				break;	    /* got character, break for loop */
+			      }
+			}
+			if (keylen > 0)	    /* full matching terminal code */
+			{
+#if defined(FEAT_GUI) && defined(FEAT_MENU)
+			    if (typebuf.tb_buf[typebuf.tb_off] == K_SPECIAL
+					 && typebuf.tb_buf[typebuf.tb_off + 1]
+								   == KS_MENU)
+			    {
+				/*
+				 * Using a menu may cause a break in undo!
+				 * It's like using gotchars(), but without
+				 * recording or writing to a script file.
+				 */
+				may_sync_undo();
+				del_typebuf(3, 0);
+				idx = get_menu_index(current_menu, local_State);
+				if (idx != MENU_INDEX_INVALID)
+				{
+# ifdef FEAT_VISUAL
+				    /*
+				     * In Select mode and a Visual mode menu
+				     * is used:  Switch to Visual mode
+				     * temporarily.  Append K_SELECT to switch
+				     * back to Select mode.
+				     */
+				    if (VIsual_active && VIsual_select
+					    && (current_menu->modes & VISUAL))
+				    {
+					VIsual_select = FALSE;
+					(void)ins_typebuf(K_SELECT_STRING,
+						  REMAP_NONE, 0, TRUE, FALSE);
+				    }
+# endif
+				    ins_typebuf(current_menu->strings[idx],
+						current_menu->noremap[idx],
+						0, TRUE,
+						   current_menu->silent[idx]);
+				}
+			    }
+#endif /* FEAT_GUI */
+			    continue;	/* try mapping again */
+			}
+
+			/* Partial match: get some more characters.  When a
+			 * matching mapping was found use that one. */
+			if (mp == NULL || keylen < 0)
+			    keylen = KL_PART_KEY;
+			else
+			    keylen = mp_match_len;
+		    }
+
+		    /* complete match */
+		    if (keylen >= 0 && keylen <= typebuf.tb_len)
+		    {
+			/* write chars to script file(s) */
+			if (keylen > typebuf.tb_maplen)
+			    gotchars(typebuf.tb_buf + typebuf.tb_off
+							  + typebuf.tb_maplen,
+						  keylen - typebuf.tb_maplen);
+
+			cmd_silent = (typebuf.tb_silent > 0);
+			del_typebuf(keylen, 0);	/* remove the mapped keys */
+
+			/*
+			 * Put the replacement string in front of mapstr.
+			 * The depth check catches ":map x y" and ":map y x".
+			 */
+			if (++mapdepth >= p_mmd)
+			{
+			    EMSG(_("E223: recursive mapping"));
+			    if (State & CMDLINE)
+				redrawcmdline();
+			    else
+				setcursor();
+			    flush_buffers(FALSE);
+			    mapdepth = 0;	/* for next one */
+			    c = -1;
+			    break;
+			}
+
+#ifdef FEAT_VISUAL
+			/*
+			 * In Select mode and a Visual mode mapping is used:
+			 * Switch to Visual mode temporarily.  Append K_SELECT
+			 * to switch back to Select mode.
+			 */
+			if (VIsual_active && VIsual_select
+						     && (mp->m_mode & VISUAL))
+			{
+			    VIsual_select = FALSE;
+			    (void)ins_typebuf(K_SELECT_STRING, REMAP_NONE,
+							      0, TRUE, FALSE);
+			}
+#endif
+
+#ifdef FEAT_EVAL
+			/*
+			 * Handle ":map <expr>": evaluate the {rhs} as an
+			 * expression.  Save and restore the typeahead so that
+			 * getchar() can be used.  Also save and restore the
+			 * command line for "normal :".
+			 */
+			if (mp->m_expr)
+			{
+			    tasave_T	tabuf;
+			    int		save_vgetc_busy = vgetc_busy;
+
+			    save_typeahead(&tabuf);
+			    if (tabuf.typebuf_valid)
+			    {
+				vgetc_busy = 0;
+				s = eval_map_expr(mp->m_str);
+				vgetc_busy = save_vgetc_busy;
+			    }
+			    else
+				s = NULL;
+			    restore_typeahead(&tabuf);
+			}
+			else
+#endif
+			    s = mp->m_str;
+
+			/*
+			 * Insert the 'to' part in the typebuf.tb_buf.
+			 * If 'from' field is the same as the start of the
+			 * 'to' field, don't remap the first character (but do
+			 * allow abbreviations).
+			 * If m_noremap is set, don't remap the whole 'to'
+			 * part.
+			 */
+			if (s == NULL)
+			    i = FAIL;
+			else
+			{
+			    i = ins_typebuf(s,
+				    mp->m_noremap != REMAP_YES
+					    ? mp->m_noremap
+					    : STRNCMP(s, mp->m_keys,
+							  (size_t)keylen) != 0
+						     ? REMAP_YES : REMAP_SKIP,
+				0, TRUE, cmd_silent || mp->m_silent);
+#ifdef FEAT_EVAL
+			    if (mp->m_expr)
+				vim_free(s);
+#endif
+			}
+			if (i == FAIL)
+			{
+			    c = -1;
+			    break;
+			}
+			continue;
+		    }
+		}
+
+/*
+ * get a character: 3. from the user - handle <Esc> in Insert mode
+ */
+		/*
+		 * special case: if we get an <ESC> in insert mode and there
+		 * are no more characters at once, we pretend to go out of
+		 * insert mode.  This prevents the one second delay after
+		 * typing an <ESC>.  If we get something after all, we may
+		 * have to redisplay the mode. That the cursor is in the wrong
+		 * place does not matter.
+		 */
+		c = 0;
+#ifdef FEAT_CMDL_INFO
+		new_wcol = curwin->w_wcol;
+		new_wrow = curwin->w_wrow;
+#endif
+		if (	   advance
+			&& typebuf.tb_len == 1
+			&& typebuf.tb_buf[typebuf.tb_off] == ESC
+			&& !no_mapping
+#ifdef FEAT_EX_EXTRA
+			&& ex_normal_busy == 0
+#endif
+			&& typebuf.tb_maplen == 0
+			&& (State & INSERT)
+			&& (p_timeout || (keylen == KL_PART_KEY && p_ttimeout))
+			&& (c = inchar(typebuf.tb_buf + typebuf.tb_off
+						     + typebuf.tb_len, 3, 25L,
+						 typebuf.tb_change_cnt)) == 0)
+		{
+		    colnr_T	col = 0, vcol;
+		    char_u	*ptr;
+
+		    if (mode_displayed)
+		    {
+			unshowmode(TRUE);
+			mode_deleted = TRUE;
+		    }
+#ifdef FEAT_GUI
+		    /* may show different cursor shape */
+		    if (gui.in_use)
+		    {
+			int	    save_State;
+
+			save_State = State;
+			State = NORMAL;
+			gui_update_cursor(TRUE, FALSE);
+			State = save_State;
+			shape_changed = TRUE;
+		    }
+#endif
+		    validate_cursor();
+		    old_wcol = curwin->w_wcol;
+		    old_wrow = curwin->w_wrow;
+
+		    /* move cursor left, if possible */
+		    if (curwin->w_cursor.col != 0)
+		    {
+			if (curwin->w_wcol > 0)
+			{
+			    if (did_ai)
+			    {
+				/*
+				 * We are expecting to truncate the trailing
+				 * white-space, so find the last non-white
+				 * character -- webb
+				 */
+				col = vcol = curwin->w_wcol = 0;
+				ptr = ml_get_curline();
+				while (col < curwin->w_cursor.col)
+				{
+				    if (!vim_iswhite(ptr[col]))
+					curwin->w_wcol = vcol;
+				    vcol += lbr_chartabsize(ptr + col,
+							       (colnr_T)vcol);
+#ifdef FEAT_MBYTE
+				    if (has_mbyte)
+					col += (*mb_ptr2len)(ptr + col);
+				    else
+#endif
+					++col;
+				}
+				curwin->w_wrow = curwin->w_cline_row
+					   + curwin->w_wcol / W_WIDTH(curwin);
+				curwin->w_wcol %= W_WIDTH(curwin);
+				curwin->w_wcol += curwin_col_off();
+#ifdef FEAT_MBYTE
+				col = 0;	/* no correction needed */
+#endif
+			    }
+			    else
+			    {
+				--curwin->w_wcol;
+#ifdef FEAT_MBYTE
+				col = curwin->w_cursor.col - 1;
+#endif
+			    }
+			}
+			else if (curwin->w_p_wrap && curwin->w_wrow)
+			{
+			    --curwin->w_wrow;
+			    curwin->w_wcol = W_WIDTH(curwin) - 1;
+#ifdef FEAT_MBYTE
+			    col = curwin->w_cursor.col - 1;
+#endif
+			}
+#ifdef FEAT_MBYTE
+			if (has_mbyte && col > 0 && curwin->w_wcol > 0)
+			{
+			    /* Correct when the cursor is on the right halve
+			     * of a double-wide character. */
+			    ptr = ml_get_curline();
+			    col -= (*mb_head_off)(ptr, ptr + col);
+			    if ((*mb_ptr2cells)(ptr + col) > 1)
+				--curwin->w_wcol;
+			}
+#endif
+		    }
+		    setcursor();
+		    out_flush();
+#ifdef FEAT_CMDL_INFO
+		    new_wcol = curwin->w_wcol;
+		    new_wrow = curwin->w_wrow;
+#endif
+		    curwin->w_wcol = old_wcol;
+		    curwin->w_wrow = old_wrow;
+		}
+		if (c < 0)
+		    continue;	/* end of input script reached */
+		typebuf.tb_len += c;
+
+		/* buffer full, don't map */
+		if (typebuf.tb_len >= typebuf.tb_maplen + MAXMAPLEN)
+		{
+		    timedout = TRUE;
+		    continue;
+		}
+
+#ifdef FEAT_EX_EXTRA
+		if (ex_normal_busy > 0)
+		{
+# ifdef FEAT_CMDWIN
+		    static int tc = 0;
+# endif
+
+		    /* No typeahead left and inside ":normal".  Must return
+		     * something to avoid getting stuck.  When an incomplete
+		     * mapping is present, behave like it timed out. */
+		    if (typebuf.tb_len > 0)
+		    {
+			timedout = TRUE;
+			continue;
+		    }
+		    /* When 'insertmode' is set, ESC just beeps in Insert
+		     * mode.  Use CTRL-L to make edit() return.
+		     * For the command line only CTRL-C always breaks it.
+		     * For the cmdline window: Alternate between ESC and
+		     * CTRL-C: ESC for most situations and CTRL-C to close the
+		     * cmdline window. */
+		    if (p_im && (State & INSERT))
+			c = Ctrl_L;
+		    else if ((State & CMDLINE)
+# ifdef FEAT_CMDWIN
+			    || (cmdwin_type > 0 && tc == ESC)
+# endif
+			    )
+			c = Ctrl_C;
+		    else
+			c = ESC;
+# ifdef FEAT_CMDWIN
+		    tc = c;
+# endif
+		    break;
+		}
+#endif
+
+/*
+ * get a character: 3. from the user - update display
+ */
+		/* In insert mode a screen update is skipped when characters
+		 * are still available.  But when those available characters
+		 * are part of a mapping, and we are going to do a blocking
+		 * wait here.  Need to update the screen to display the
+		 * changed text so far. */
+		if ((State & INSERT) && advance && must_redraw != 0)
+		{
+		    update_screen(0);
+		    setcursor(); /* put cursor back where it belongs */
+		}
+
+		/*
+		 * If we have a partial match (and are going to wait for more
+		 * input from the user), show the partially matched characters
+		 * to the user with showcmd.
+		 */
+#ifdef FEAT_CMDL_INFO
+		i = 0;
+#endif
+		c1 = 0;
+		if (typebuf.tb_len > 0 && advance && !exmode_active)
+		{
+		    if (((State & (NORMAL | INSERT)) || State == LANGMAP)
+			    && State != HITRETURN)
+		    {
+			/* this looks nice when typing a dead character map */
+			if (State & INSERT
+			    && ptr2cells(typebuf.tb_buf + typebuf.tb_off
+						   + typebuf.tb_len - 1) == 1)
+			{
+			    edit_putchar(typebuf.tb_buf[typebuf.tb_off
+						+ typebuf.tb_len - 1], FALSE);
+			    setcursor(); /* put cursor back where it belongs */
+			    c1 = 1;
+			}
+#ifdef FEAT_CMDL_INFO
+			/* need to use the col and row from above here */
+			old_wcol = curwin->w_wcol;
+			old_wrow = curwin->w_wrow;
+			curwin->w_wcol = new_wcol;
+			curwin->w_wrow = new_wrow;
+			push_showcmd();
+			if (typebuf.tb_len > SHOWCMD_COLS)
+			    i = typebuf.tb_len - SHOWCMD_COLS;
+			while (i < typebuf.tb_len)
+			    (void)add_to_showcmd(typebuf.tb_buf[typebuf.tb_off
+								      + i++]);
+			curwin->w_wcol = old_wcol;
+			curwin->w_wrow = old_wrow;
+#endif
+		    }
+
+		    /* this looks nice when typing a dead character map */
+		    if ((State & CMDLINE)
+#if defined(FEAT_CRYPT) || defined(FEAT_EVAL)
+			    && cmdline_star == 0
+#endif
+			    && ptr2cells(typebuf.tb_buf + typebuf.tb_off
+						   + typebuf.tb_len - 1) == 1)
+		    {
+			putcmdline(typebuf.tb_buf[typebuf.tb_off
+						+ typebuf.tb_len - 1], FALSE);
+			c1 = 1;
+		    }
+		}
+
+/*
+ * get a character: 3. from the user - get it
+ */
+		wait_tb_len = typebuf.tb_len;
+		c = inchar(typebuf.tb_buf + typebuf.tb_off + typebuf.tb_len,
+			typebuf.tb_buflen - typebuf.tb_off - typebuf.tb_len - 1,
+			!advance
+			    ? 0
+			    : ((typebuf.tb_len == 0
+				    || !(p_timeout || (p_ttimeout
+						   && keylen == KL_PART_KEY)))
+				    ? -1L
+				    : ((keylen == KL_PART_KEY && p_ttm >= 0)
+					    ? p_ttm
+					    : p_tm)), typebuf.tb_change_cnt);
+
+#ifdef FEAT_CMDL_INFO
+		if (i != 0)
+		    pop_showcmd();
+#endif
+		if (c1 == 1)
+		{
+		    if (State & INSERT)
+			edit_unputchar();
+		    if (State & CMDLINE)
+			unputcmdline();
+		    setcursor();	/* put cursor back where it belongs */
+		}
+
+		if (c < 0)
+		    continue;		/* end of input script reached */
+		if (c == NUL)		/* no character available */
+		{
+		    if (!advance)
+			break;
+		    if (wait_tb_len > 0)	/* timed out */
+		    {
+			timedout = TRUE;
+			continue;
+		    }
+		}
+		else
+		{	    /* allow mapping for just typed characters */
+		    while (typebuf.tb_buf[typebuf.tb_off
+						     + typebuf.tb_len] != NUL)
+			typebuf.tb_noremap[typebuf.tb_off
+						 + typebuf.tb_len++] = RM_YES;
+#ifdef USE_IM_CONTROL
+		    /* Get IM status right after getting keys, not after the
+		     * timeout for a mapping (focus may be lost by then). */
+		    vgetc_im_active = im_get_status();
+#endif
+		}
+	    }	    /* for (;;) */
+	}	/* if (!character from stuffbuf) */
+
+			/* if advance is FALSE don't loop on NULs */
+    } while (c < 0 || (advance && c == NUL));
+
+    /*
+     * The "INSERT" message is taken care of here:
+     *	 if we return an ESC to exit insert mode, the message is deleted
+     *	 if we don't return an ESC but deleted the message before, redisplay it
+     */
+    if (advance && p_smd && msg_silent == 0 && (State & INSERT))
+    {
+	if (c == ESC && !mode_deleted && !no_mapping && mode_displayed)
+	{
+	    if (typebuf.tb_len && !KeyTyped)
+		redraw_cmdline = TRUE;	    /* delete mode later */
+	    else
+		unshowmode(FALSE);
+	}
+	else if (c != ESC && mode_deleted)
+	{
+	    if (typebuf.tb_len && !KeyTyped)
+		redraw_cmdline = TRUE;	    /* show mode later */
+	    else
+		showmode();
+	}
+    }
+#ifdef FEAT_GUI
+    /* may unshow different cursor shape */
+    if (gui.in_use && shape_changed)
+	gui_update_cursor(TRUE, FALSE);
+#endif
+
+    --vgetc_busy;
+
+    return c;
+}
+
+/*
+ * inchar() - get one character from
+ *	1. a scriptfile
+ *	2. the keyboard
+ *
+ *  As much characters as we can get (upto 'maxlen') are put in "buf" and
+ *  NUL terminated (buffer length must be 'maxlen' + 1).
+ *  Minimum for "maxlen" is 3!!!!
+ *
+ *  "tb_change_cnt" is the value of typebuf.tb_change_cnt if "buf" points into
+ *  it.  When typebuf.tb_change_cnt changes (e.g., when a message is received
+ *  from a remote client) "buf" can no longer be used.  "tb_change_cnt" is 0
+ *  otherwise.
+ *
+ *  If we got an interrupt all input is read until none is available.
+ *
+ *  If wait_time == 0  there is no waiting for the char.
+ *  If wait_time == n  we wait for n msec for a character to arrive.
+ *  If wait_time == -1 we wait forever for a character to arrive.
+ *
+ *  Return the number of obtained characters.
+ *  Return -1 when end of input script reached.
+ */
+    int
+inchar(buf, maxlen, wait_time, tb_change_cnt)
+    char_u	*buf;
+    int		maxlen;
+    long	wait_time;	    /* milli seconds */
+    int		tb_change_cnt;
+{
+    int		len = 0;	    /* init for GCC */
+    int		retesc = FALSE;	    /* return ESC with gotint */
+    int		script_char;
+
+    if (wait_time == -1L || wait_time > 100L)  /* flush output before waiting */
+    {
+	cursor_on();
+	out_flush();
+#ifdef FEAT_GUI
+	if (gui.in_use)
+	{
+	    gui_update_cursor(FALSE, FALSE);
+# ifdef FEAT_MOUSESHAPE
+	    if (postponed_mouseshape)
+		update_mouseshape(-1);
+# endif
+	}
+#endif
+    }
+
+    /*
+     * Don't reset these when at the hit-return prompt, otherwise a endless
+     * recursive loop may result (write error in swapfile, hit-return, timeout
+     * on char wait, flush swapfile, write error....).
+     */
+    if (State != HITRETURN)
+    {
+	did_outofmem_msg = FALSE;   /* display out of memory message (again) */
+	did_swapwrite_msg = FALSE;  /* display swap file write error again */
+    }
+    undo_off = FALSE;		    /* restart undo now */
+
+    /*
+     * first try script file
+     *	If interrupted: Stop reading script files.
+     */
+    script_char = -1;
+    while (scriptin[curscript] != NULL && script_char < 0)
+    {
+	if (got_int || (script_char = getc(scriptin[curscript])) < 0)
+	{
+	    /* Reached EOF.
+	     * Careful: closescript() frees typebuf.tb_buf[] and buf[] may
+	     * point inside typebuf.tb_buf[].  Don't use buf[] after this! */
+	    closescript();
+	    /*
+	     * When reading script file is interrupted, return an ESC to get
+	     * back to normal mode.
+	     * Otherwise return -1, because typebuf.tb_buf[] has changed.
+	     */
+	    if (got_int)
+		retesc = TRUE;
+	    else
+		return -1;
+	}
+	else
+	{
+	    buf[0] = script_char;
+	    len = 1;
+	}
+    }
+
+    if (script_char < 0)	/* did not get a character from script */
+    {
+	/*
+	 * If we got an interrupt, skip all previously typed characters and
+	 * return TRUE if quit reading script file.
+	 * Stop reading typeahead when a single CTRL-C was read,
+	 * fill_input_buf() returns this when not able to read from stdin.
+	 * Don't use buf[] here, closescript() may have freed typebuf.tb_buf[]
+	 * and buf may be pointing inside typebuf.tb_buf[].
+	 */
+	if (got_int)
+	{
+#define DUM_LEN MAXMAPLEN * 3 + 3
+	    char_u	dum[DUM_LEN + 1];
+
+	    for (;;)
+	    {
+		len = ui_inchar(dum, DUM_LEN, 0L, 0);
+		if (len == 0 || (len == 1 && dum[0] == 3))
+		    break;
+	    }
+	    return retesc;
+	}
+
+	/*
+	 * Always flush the output characters when getting input characters
+	 * from the user.
+	 */
+	out_flush();
+
+	/*
+	 * Fill up to a third of the buffer, because each character may be
+	 * tripled below.
+	 */
+	len = ui_inchar(buf, maxlen / 3, wait_time, tb_change_cnt);
+    }
+
+    if (typebuf_changed(tb_change_cnt))
+	return 0;
+
+    return fix_input_buffer(buf, len, script_char >= 0);
+}
+
+/*
+ * Fix typed characters for use by vgetc() and check_termcode().
+ * buf[] must have room to triple the number of bytes!
+ * Returns the new length.
+ */
+    int
+fix_input_buffer(buf, len, script)
+    char_u	*buf;
+    int		len;
+    int		script;		/* TRUE when reading from a script */
+{
+    int		i;
+    char_u	*p = buf;
+
+    /*
+     * Two characters are special: NUL and K_SPECIAL.
+     * When compiled With the GUI CSI is also special.
+     * Replace	     NUL by K_SPECIAL KS_ZERO	 KE_FILLER
+     * Replace K_SPECIAL by K_SPECIAL KS_SPECIAL KE_FILLER
+     * Replace       CSI by K_SPECIAL KS_EXTRA   KE_CSI
+     * Don't replace K_SPECIAL when reading a script file.
+     */
+    for (i = len; --i >= 0; ++p)
+    {
+#ifdef FEAT_GUI
+	/* When the GUI is used any character can come after a CSI, don't
+	 * escape it. */
+	if (gui.in_use && p[0] == CSI && i >= 2)
+	{
+	    p += 2;
+	    i -= 2;
+	}
+	/* When the GUI is not used CSI needs to be escaped. */
+	else if (!gui.in_use && p[0] == CSI)
+	{
+	    mch_memmove(p + 3, p + 1, (size_t)i);
+	    *p++ = K_SPECIAL;
+	    *p++ = KS_EXTRA;
+	    *p = (int)KE_CSI;
+	    len += 2;
+	}
+	else
+#endif
+	if (p[0] == NUL || (p[0] == K_SPECIAL && !script
+#ifdef FEAT_AUTOCMD
+		    /* timeout may generate K_CURSORHOLD */
+		    && (i < 2 || p[1] != KS_EXTRA || p[2] != (int)KE_CURSORHOLD)
+#endif
+#if defined(WIN3264) && !defined(FEAT_GUI)
+		    /* Win32 console passes modifiers */
+		    && (i < 2 || p[1] != KS_MODIFIER)
+#endif
+		    ))
+	{
+	    mch_memmove(p + 3, p + 1, (size_t)i);
+	    p[2] = K_THIRD(p[0]);
+	    p[1] = K_SECOND(p[0]);
+	    p[0] = K_SPECIAL;
+	    p += 2;
+	    len += 2;
+	}
+    }
+    *p = NUL;		/* add trailing NUL */
+    return len;
+}
+
+#if defined(USE_INPUT_BUF) || defined(PROTO)
+/*
+ * Return TRUE when bytes are in the input buffer or in the typeahead buffer.
+ * Normally the input buffer would be sufficient, but the server_to_input_buf()
+ * or feedkeys() may insert characters in the typeahead buffer while we are
+ * waiting for input to arrive.
+ */
+    int
+input_available()
+{
+    return (!vim_is_input_buf_empty()
+# if defined(FEAT_CLIENTSERVER) || defined(FEAT_EVAL)
+	    || typebuf_was_filled
+# endif
+	    );
+}
+#endif
+
+/*
+ * map[!]		    : show all key mappings
+ * map[!] {lhs}		    : show key mapping for {lhs}
+ * map[!] {lhs} {rhs}	    : set key mapping for {lhs} to {rhs}
+ * noremap[!] {lhs} {rhs}   : same, but no remapping for {rhs}
+ * unmap[!] {lhs}	    : remove key mapping for {lhs}
+ * abbr			    : show all abbreviations
+ * abbr {lhs}		    : show abbreviations for {lhs}
+ * abbr {lhs} {rhs}	    : set abbreviation for {lhs} to {rhs}
+ * noreabbr {lhs} {rhs}	    : same, but no remapping for {rhs}
+ * unabbr {lhs}		    : remove abbreviation for {lhs}
+ *
+ * maptype: 0 for :map, 1 for :unmap, 2 for noremap.
+ *
+ * arg is pointer to any arguments. Note: arg cannot be a read-only string,
+ * it will be modified.
+ *
+ * for :map   mode is NORMAL + VISUAL + SELECTMODE + OP_PENDING
+ * for :map!  mode is INSERT + CMDLINE
+ * for :cmap  mode is CMDLINE
+ * for :imap  mode is INSERT
+ * for :lmap  mode is LANGMAP
+ * for :nmap  mode is NORMAL
+ * for :vmap  mode is VISUAL + SELECTMODE
+ * for :xmap  mode is VISUAL
+ * for :smap  mode is SELECTMODE
+ * for :omap  mode is OP_PENDING
+ *
+ * for :abbr  mode is INSERT + CMDLINE
+ * for :iabbr mode is INSERT
+ * for :cabbr mode is CMDLINE
+ *
+ * Return 0 for success
+ *	  1 for invalid arguments
+ *	  2 for no match
+ *	  4 for out of mem
+ *	  5 for entry not unique
+ */
+    int
+do_map(maptype, arg, mode, abbrev)
+    int		maptype;
+    char_u	*arg;
+    int		mode;
+    int		abbrev;		/* not a mapping but an abbreviation */
+{
+    char_u	*keys;
+    mapblock_T	*mp, **mpp;
+    char_u	*rhs;
+    char_u	*p;
+    int		n;
+    int		len = 0;	/* init for GCC */
+    char_u	*newstr;
+    int		hasarg;
+    int		haskey;
+    int		did_it = FALSE;
+#ifdef FEAT_LOCALMAP
+    int		did_local = FALSE;
+#endif
+    int		round;
+    char_u	*keys_buf = NULL;
+    char_u	*arg_buf = NULL;
+    int		retval = 0;
+    int		do_backslash;
+    int		hash;
+    int		new_hash;
+    mapblock_T	**abbr_table;
+    mapblock_T	**map_table;
+    int		unique = FALSE;
+    int		silent = FALSE;
+    int		special = FALSE;
+#ifdef FEAT_EVAL
+    int		expr = FALSE;
+#endif
+    int		noremap;
+
+    keys = arg;
+    map_table = maphash;
+    abbr_table = &first_abbr;
+
+    /* For ":noremap" don't remap, otherwise do remap. */
+    if (maptype == 2)
+	noremap = REMAP_NONE;
+    else
+	noremap = REMAP_YES;
+
+    /* Accept <buffer>, <silent>, <expr> <script> and <unique> in any order. */
+    for (;;)
+    {
+#ifdef FEAT_LOCALMAP
+	/*
+	 * Check for "<buffer>": mapping local to buffer.
+	 */
+	if (STRNCMP(keys, "<buffer>", 8) == 0)
+	{
+	    keys = skipwhite(keys + 8);
+	    map_table = curbuf->b_maphash;
+	    abbr_table = &curbuf->b_first_abbr;
+	    continue;
+	}
+#endif
+
+	/*
+	 * Check for "<silent>": don't echo commands.
+	 */
+	if (STRNCMP(keys, "<silent>", 8) == 0)
+	{
+	    keys = skipwhite(keys + 8);
+	    silent = TRUE;
+	    continue;
+	}
+
+	/*
+	 * Check for "<special>": accept special keys in <>
+	 */
+	if (STRNCMP(keys, "<special>", 9) == 0)
+	{
+	    keys = skipwhite(keys + 9);
+	    special = TRUE;
+	    continue;
+	}
+
+#ifdef FEAT_EVAL
+	/*
+	 * Check for "<script>": remap script-local mappings only
+	 */
+	if (STRNCMP(keys, "<script>", 8) == 0)
+	{
+	    keys = skipwhite(keys + 8);
+	    noremap = REMAP_SCRIPT;
+	    continue;
+	}
+
+	/*
+	 * Check for "<expr>": {rhs} is an expression.
+	 */
+	if (STRNCMP(keys, "<expr>", 6) == 0)
+	{
+	    keys = skipwhite(keys + 6);
+	    expr = TRUE;
+	    continue;
+	}
+#endif
+	/*
+	 * Check for "<unique>": don't overwrite an existing mapping.
+	 */
+	if (STRNCMP(keys, "<unique>", 8) == 0)
+	{
+	    keys = skipwhite(keys + 8);
+	    unique = TRUE;
+	    continue;
+	}
+	break;
+    }
+
+    validate_maphash();
+
+    /*
+     * find end of keys and skip CTRL-Vs (and backslashes) in it
+     * Accept backslash like CTRL-V when 'cpoptions' does not contain 'B'.
+     * with :unmap white space is included in the keys, no argument possible
+     */
+    p = keys;
+    do_backslash = (vim_strchr(p_cpo, CPO_BSLASH) == NULL);
+    while (*p && (maptype == 1 || !vim_iswhite(*p)))
+    {
+	if ((p[0] == Ctrl_V || (do_backslash && p[0] == '\\')) &&
+								  p[1] != NUL)
+	    ++p;		/* skip CTRL-V or backslash */
+	++p;
+    }
+    if (*p != NUL)
+	*p++ = NUL;
+    p = skipwhite(p);
+    rhs = p;
+    hasarg = (*rhs != NUL);
+    haskey = (*keys != NUL);
+
+    /* check for :unmap without argument */
+    if (maptype == 1 && !haskey)
+    {
+	retval = 1;
+	goto theend;
+    }
+
+    /*
+     * If mapping has been given as ^V<C_UP> say, then replace the term codes
+     * with the appropriate two bytes. If it is a shifted special key, unshift
+     * it too, giving another two bytes.
+     * replace_termcodes() may move the result to allocated memory, which
+     * needs to be freed later (*keys_buf and *arg_buf).
+     * replace_termcodes() also removes CTRL-Vs and sometimes backslashes.
+     */
+    if (haskey)
+	keys = replace_termcodes(keys, &keys_buf, TRUE, TRUE, special);
+    if (hasarg)
+    {
+	if (STRICMP(rhs, "<nop>") == 0)	    /* "<Nop>" means nothing */
+	    rhs = (char_u *)"";
+	else
+	    rhs = replace_termcodes(rhs, &arg_buf, FALSE, TRUE, special);
+    }
+
+#ifdef FEAT_FKMAP
+    /*
+     * when in right-to-left mode and alternate keymap option set,
+     * reverse the character flow in the rhs in Farsi.
+     */
+    if (p_altkeymap && curwin->w_p_rl)
+	lrswap(rhs);
+#endif
+
+    /*
+     * check arguments and translate function keys
+     */
+    if (haskey)
+    {
+	len = (int)STRLEN(keys);
+	if (len > MAXMAPLEN)		/* maximum length of MAXMAPLEN chars */
+	{
+	    retval = 1;
+	    goto theend;
+	}
+
+	if (abbrev && maptype != 1)
+	{
+	    /*
+	     * If an abbreviation ends in a keyword character, the
+	     * rest must be all keyword-char or all non-keyword-char.
+	     * Otherwise we won't be able to find the start of it in a
+	     * vi-compatible way.
+	     */
+#ifdef FEAT_MBYTE
+	    if (has_mbyte)
+	    {
+		int	first, last;
+		int	same = -1;
+
+		first = vim_iswordp(keys);
+		last = first;
+		p = keys + (*mb_ptr2len)(keys);
+		n = 1;
+		while (p < keys + len)
+		{
+		    ++n;			/* nr of (multi-byte) chars */
+		    last = vim_iswordp(p);	/* type of last char */
+		    if (same == -1 && last != first)
+			same = n - 1;		/* count of same char type */
+		    p += (*mb_ptr2len)(p);
+		}
+		if (last && n > 2 && same >= 0 && same < n - 1)
+		{
+		    retval = 1;
+		    goto theend;
+		}
+	    }
+	    else
+#endif
+		if (vim_iswordc(keys[len - 1]))	/* ends in keyword char */
+		    for (n = 0; n < len - 2; ++n)
+			if (vim_iswordc(keys[n]) != vim_iswordc(keys[len - 2]))
+			{
+			    retval = 1;
+			    goto theend;
+			}
+	    /* An abbrevation cannot contain white space. */
+	    for (n = 0; n < len; ++n)
+		if (vim_iswhite(keys[n]))
+		{
+		    retval = 1;
+		    goto theend;
+		}
+	}
+    }
+
+    if (haskey && hasarg && abbrev)	/* if we will add an abbreviation */
+	no_abbr = FALSE;		/* reset flag that indicates there are
+							    no abbreviations */
+
+    if (!haskey || (maptype != 1 && !hasarg))
+	msg_start();
+
+#ifdef FEAT_LOCALMAP
+    /*
+     * Check if a new local mapping wasn't already defined globally.
+     */
+    if (map_table == curbuf->b_maphash && haskey && hasarg && maptype != 1)
+    {
+	/* need to loop over all global hash lists */
+	for (hash = 0; hash < 256 && !got_int; ++hash)
+	{
+	    if (abbrev)
+	    {
+		if (hash != 0)	/* there is only one abbreviation list */
+		    break;
+		mp = first_abbr;
+	    }
+	    else
+		mp = maphash[hash];
+	    for ( ; mp != NULL && !got_int; mp = mp->m_next)
+	    {
+		/* check entries with the same mode */
+		if ((mp->m_mode & mode) != 0
+			&& mp->m_keylen == len
+			&& unique
+			&& STRNCMP(mp->m_keys, keys, (size_t)len) == 0)
+		{
+		    if (abbrev)
+			EMSG2(_("E224: global abbreviation already exists for %s"),
+				mp->m_keys);
+		    else
+			EMSG2(_("E225: global mapping already exists for %s"),
+				mp->m_keys);
+		    retval = 5;
+		    goto theend;
+		}
+	    }
+	}
+    }
+
+    /*
+     * When listing global mappings, also list buffer-local ones here.
+     */
+    if (map_table != curbuf->b_maphash && !hasarg && maptype != 1)
+    {
+	/* need to loop over all global hash lists */
+	for (hash = 0; hash < 256 && !got_int; ++hash)
+	{
+	    if (abbrev)
+	    {
+		if (hash != 0)	/* there is only one abbreviation list */
+		    break;
+		mp = curbuf->b_first_abbr;
+	    }
+	    else
+		mp = curbuf->b_maphash[hash];
+	    for ( ; mp != NULL && !got_int; mp = mp->m_next)
+	    {
+		/* check entries with the same mode */
+		if ((mp->m_mode & mode) != 0)
+		{
+		    if (!haskey)		    /* show all entries */
+		    {
+			showmap(mp, TRUE);
+			did_local = TRUE;
+		    }
+		    else
+		    {
+			n = mp->m_keylen;
+			if (STRNCMP(mp->m_keys, keys,
+					    (size_t)(n < len ? n : len)) == 0)
+			{
+			    showmap(mp, TRUE);
+			    did_local = TRUE;
+			}
+		    }
+		}
+	    }
+	}
+    }
+#endif
+
+    /*
+     * Find an entry in the maphash[] list that matches.
+     * For :unmap we may loop two times: once to try to unmap an entry with a
+     * matching 'from' part, a second time, if the first fails, to unmap an
+     * entry with a matching 'to' part. This was done to allow ":ab foo bar"
+     * to be unmapped by typing ":unab foo", where "foo" will be replaced by
+     * "bar" because of the abbreviation.
+     */
+    for (round = 0; (round == 0 || maptype == 1) && round <= 1
+					      && !did_it && !got_int; ++round)
+    {
+	/* need to loop over all hash lists */
+	for (hash = 0; hash < 256 && !got_int; ++hash)
+	{
+	    if (abbrev)
+	    {
+		if (hash > 0)	/* there is only one abbreviation list */
+		    break;
+		mpp = abbr_table;
+	    }
+	    else
+		mpp = &(map_table[hash]);
+	    for (mp = *mpp; mp != NULL && !got_int; mp = *mpp)
+	    {
+
+		if (!(mp->m_mode & mode))   /* skip entries with wrong mode */
+		{
+		    mpp = &(mp->m_next);
+		    continue;
+		}
+		if (!haskey)		    /* show all entries */
+		{
+		    showmap(mp, map_table != maphash);
+		    did_it = TRUE;
+		}
+		else			    /* do we have a match? */
+		{
+		    if (round)	    /* second round: Try unmap "rhs" string */
+		    {
+			n = (int)STRLEN(mp->m_str);
+			p = mp->m_str;
+		    }
+		    else
+		    {
+			n = mp->m_keylen;
+			p = mp->m_keys;
+		    }
+		    if (STRNCMP(p, keys, (size_t)(n < len ? n : len)) == 0)
+		    {
+			if (maptype == 1)	/* delete entry */
+			{
+			    /* Only accept a full match.  For abbreviations we
+			     * ignore trailing space when matching with the
+			     * "lhs", since an abbreviation can't have
+			     * trailing space. */
+			    if (n != len && (!abbrev || round || n > len
+					       || *skipwhite(keys + n) != NUL))
+			    {
+				mpp = &(mp->m_next);
+				continue;
+			    }
+			    /*
+			     * We reset the indicated mode bits. If nothing is
+			     * left the entry is deleted below.
+			     */
+			    mp->m_mode &= ~mode;
+			    did_it = TRUE;	/* remember we did something */
+			}
+			else if (!hasarg)	/* show matching entry */
+			{
+			    showmap(mp, map_table != maphash);
+			    did_it = TRUE;
+			}
+			else if (n != len)	/* new entry is ambiguous */
+			{
+			    mpp = &(mp->m_next);
+			    continue;
+			}
+			else if (unique)
+			{
+			    if (abbrev)
+				EMSG2(_("E226: abbreviation already exists for %s"),
+									   p);
+			    else
+				EMSG2(_("E227: mapping already exists for %s"), p);
+			    retval = 5;
+			    goto theend;
+			}
+			else			/* new rhs for existing entry */
+			{
+			    mp->m_mode &= ~mode;	/* remove mode bits */
+			    if (mp->m_mode == 0 && !did_it) /* reuse entry */
+			    {
+				newstr = vim_strsave(rhs);
+				if (newstr == NULL)
+				{
+				    retval = 4;		/* no mem */
+				    goto theend;
+				}
+				vim_free(mp->m_str);
+				mp->m_str = newstr;
+				mp->m_noremap = noremap;
+				mp->m_silent = silent;
+				mp->m_mode = mode;
+#ifdef FEAT_EVAL
+				mp->m_expr = expr;
+				mp->m_script_ID = current_SID;
+#endif
+				did_it = TRUE;
+			    }
+			}
+			if (mp->m_mode == 0)	/* entry can be deleted */
+			{
+			    map_free(mpp);
+			    continue;		/* continue with *mpp */
+			}
+
+			/*
+			 * May need to put this entry into another hash list.
+			 */
+			new_hash = MAP_HASH(mp->m_mode, mp->m_keys[0]);
+			if (!abbrev && new_hash != hash)
+			{
+			    *mpp = mp->m_next;
+			    mp->m_next = map_table[new_hash];
+			    map_table[new_hash] = mp;
+
+			    continue;		/* continue with *mpp */
+			}
+		    }
+		}
+		mpp = &(mp->m_next);
+	    }
+	}
+    }
+
+    if (maptype == 1)			    /* delete entry */
+    {
+	if (!did_it)
+	    retval = 2;			    /* no match */
+	goto theend;
+    }
+
+    if (!haskey || !hasarg)		    /* print entries */
+    {
+	if (!did_it
+#ifdef FEAT_LOCALMAP
+		&& !did_local
+#endif
+		)
+	{
+	    if (abbrev)
+		MSG(_("No abbreviation found"));
+	    else
+		MSG(_("No mapping found"));
+	}
+	goto theend;			    /* listing finished */
+    }
+
+    if (did_it)			/* have added the new entry already */
+	goto theend;
+
+    /*
+     * Get here when adding a new entry to the maphash[] list or abbrlist.
+     */
+    mp = (mapblock_T *)alloc((unsigned)sizeof(mapblock_T));
+    if (mp == NULL)
+    {
+	retval = 4;	    /* no mem */
+	goto theend;
+    }
+
+    /* If CTRL-C has been mapped, don't always use it for Interrupting */
+    if (*keys == Ctrl_C)
+	mapped_ctrl_c = TRUE;
+
+    mp->m_keys = vim_strsave(keys);
+    mp->m_str = vim_strsave(rhs);
+    if (mp->m_keys == NULL || mp->m_str == NULL)
+    {
+	vim_free(mp->m_keys);
+	vim_free(mp->m_str);
+	vim_free(mp);
+	retval = 4;	/* no mem */
+	goto theend;
+    }
+    mp->m_keylen = (int)STRLEN(mp->m_keys);
+    mp->m_noremap = noremap;
+    mp->m_silent = silent;
+    mp->m_mode = mode;
+#ifdef FEAT_EVAL
+    mp->m_expr = expr;
+    mp->m_script_ID = current_SID;
+#endif
+
+    /* add the new entry in front of the abbrlist or maphash[] list */
+    if (abbrev)
+    {
+	mp->m_next = *abbr_table;
+	*abbr_table = mp;
+    }
+    else
+    {
+	n = MAP_HASH(mp->m_mode, mp->m_keys[0]);
+	mp->m_next = map_table[n];
+	map_table[n] = mp;
+    }
+
+theend:
+    vim_free(keys_buf);
+    vim_free(arg_buf);
+    return retval;
+}
+
+/*
+ * Delete one entry from the abbrlist or maphash[].
+ * "mpp" is a pointer to the m_next field of the PREVIOUS entry!
+ */
+    static void
+map_free(mpp)
+    mapblock_T	**mpp;
+{
+    mapblock_T	*mp;
+
+    mp = *mpp;
+    vim_free(mp->m_keys);
+    vim_free(mp->m_str);
+    *mpp = mp->m_next;
+    vim_free(mp);
+}
+
+/*
+ * Initialize maphash[] for first use.
+ */
+    static void
+validate_maphash()
+{
+    if (!maphash_valid)
+    {
+	vim_memset(maphash, 0, sizeof(maphash));
+	maphash_valid = TRUE;
+    }
+}
+
+/*
+ * Get the mapping mode from the command name.
+ */
+    int
+get_map_mode(cmdp, forceit)
+    char_u	**cmdp;
+    int		forceit;
+{
+    char_u	*p;
+    int		modec;
+    int		mode;
+
+    p = *cmdp;
+    modec = *p++;
+    if (modec == 'i')
+	mode = INSERT;				/* :imap */
+    else if (modec == 'l')
+	mode = LANGMAP;				/* :lmap */
+    else if (modec == 'c')
+	mode = CMDLINE;				/* :cmap */
+    else if (modec == 'n' && *p != 'o')		    /* avoid :noremap */
+	mode = NORMAL;				/* :nmap */
+    else if (modec == 'v')
+	mode = VISUAL + SELECTMODE;		/* :vmap */
+    else if (modec == 'x')
+	mode = VISUAL;				/* :xmap */
+    else if (modec == 's')
+	mode = SELECTMODE;			/* :smap */
+    else if (modec == 'o')
+	mode = OP_PENDING;			/* :omap */
+    else
+    {
+	--p;
+	if (forceit)
+	    mode = INSERT + CMDLINE;		/* :map ! */
+	else
+	    mode = VISUAL + SELECTMODE + NORMAL + OP_PENDING;/* :map */
+    }
+
+    *cmdp = p;
+    return mode;
+}
+
+/*
+ * Clear all mappings or abbreviations.
+ * 'abbr' should be FALSE for mappings, TRUE for abbreviations.
+ */
+/*ARGSUSED*/
+    void
+map_clear(cmdp, arg, forceit, abbr)
+    char_u	*cmdp;
+    char_u	*arg;
+    int		forceit;
+    int		abbr;
+{
+    int		mode;
+#ifdef FEAT_LOCALMAP
+    int		local;
+
+    local = (STRCMP(arg, "<buffer>") == 0);
+    if (!local && *arg != NUL)
+    {
+	EMSG(_(e_invarg));
+	return;
+    }
+#endif
+
+    mode = get_map_mode(&cmdp, forceit);
+    map_clear_int(curbuf, mode,
+#ifdef FEAT_LOCALMAP
+	    local,
+#else
+	    FALSE,
+#endif
+	    abbr);
+}
+
+/*
+ * Clear all mappings in "mode".
+ */
+/*ARGSUSED*/
+    void
+map_clear_int(buf, mode, local, abbr)
+    buf_T	*buf;	    /* buffer for local mappings */
+    int		mode;	    /* mode in which to delete */
+    int		local;	    /* TRUE for buffer-local mappings */
+    int		abbr;	    /* TRUE for abbreviations */
+{
+    mapblock_T	*mp, **mpp;
+    int		hash;
+    int		new_hash;
+
+    validate_maphash();
+
+    for (hash = 0; hash < 256; ++hash)
+    {
+	if (abbr)
+	{
+	    if (hash > 0)	/* there is only one abbrlist */
+		break;
+#ifdef FEAT_LOCALMAP
+	    if (local)
+		mpp = &buf->b_first_abbr;
+	    else
+#endif
+		mpp = &first_abbr;
+	}
+	else
+	{
+#ifdef FEAT_LOCALMAP
+	    if (local)
+		mpp = &buf->b_maphash[hash];
+	    else
+#endif
+		mpp = &maphash[hash];
+	}
+	while (*mpp != NULL)
+	{
+	    mp = *mpp;
+	    if (mp->m_mode & mode)
+	    {
+		mp->m_mode &= ~mode;
+		if (mp->m_mode == 0) /* entry can be deleted */
+		{
+		    map_free(mpp);
+		    continue;
+		}
+		/*
+		 * May need to put this entry into another hash list.
+		 */
+		new_hash = MAP_HASH(mp->m_mode, mp->m_keys[0]);
+		if (!abbr && new_hash != hash)
+		{
+		    *mpp = mp->m_next;
+#ifdef FEAT_LOCALMAP
+		    if (local)
+		    {
+			mp->m_next = buf->b_maphash[new_hash];
+			buf->b_maphash[new_hash] = mp;
+		    }
+		    else
+#endif
+		    {
+			mp->m_next = maphash[new_hash];
+			maphash[new_hash] = mp;
+		    }
+		    continue;		/* continue with *mpp */
+		}
+	    }
+	    mpp = &(mp->m_next);
+	}
+    }
+}
+
+    static void
+showmap(mp, local)
+    mapblock_T	*mp;
+    int		local;	    /* TRUE for buffer-local map */
+{
+    int len = 1;
+
+    if (msg_didout || msg_silent != 0)
+	msg_putchar('\n');
+    if ((mp->m_mode & (INSERT + CMDLINE)) == INSERT + CMDLINE)
+	msg_putchar('!');			/* :map! */
+    else if (mp->m_mode & INSERT)
+	msg_putchar('i');			/* :imap */
+    else if (mp->m_mode & LANGMAP)
+	msg_putchar('l');			/* :lmap */
+    else if (mp->m_mode & CMDLINE)
+	msg_putchar('c');			/* :cmap */
+    else if ((mp->m_mode & (NORMAL + VISUAL + SELECTMODE + OP_PENDING))
+				 == NORMAL + VISUAL + SELECTMODE + OP_PENDING)
+	msg_putchar(' ');			/* :map */
+    else
+    {
+	len = 0;
+	if (mp->m_mode & NORMAL)
+	{
+	    msg_putchar('n');		/* :nmap */
+	    ++len;
+	}
+	if (mp->m_mode & OP_PENDING)
+	{
+	    msg_putchar('o');		/* :omap */
+	    ++len;
+	}
+	if ((mp->m_mode & (VISUAL + SELECTMODE)) == VISUAL + SELECTMODE)
+	{
+	    msg_putchar('v');		/* :vmap */
+	    ++len;
+	}
+	else
+	{
+	    if (mp->m_mode & VISUAL)
+	    {
+		msg_putchar('x');		/* :xmap */
+		++len;
+	    }
+	    if (mp->m_mode & SELECTMODE)
+	    {
+		msg_putchar('s');		/* :smap */
+		++len;
+	    }
+	}
+    }
+    while (++len <= 3)
+	msg_putchar(' ');
+
+    /* Get length of what we write */
+    len = msg_outtrans_special(mp->m_keys, TRUE);
+    do
+    {
+	msg_putchar(' ');		/* padd with blanks */
+	++len;
+    } while (len < 12);
+
+    if (mp->m_noremap == REMAP_NONE)
+	msg_puts_attr((char_u *)"*", hl_attr(HLF_8));
+    else if (mp->m_noremap == REMAP_SCRIPT)
+	msg_puts_attr((char_u *)"&", hl_attr(HLF_8));
+    else
+	msg_putchar(' ');
+
+    if (local)
+	msg_putchar('@');
+    else
+	msg_putchar(' ');
+
+    /* Use FALSE below if we only want things like <Up> to show up as such on
+     * the rhs, and not M-x etc, TRUE gets both -- webb
+     */
+    if (*mp->m_str == NUL)
+	msg_puts_attr((char_u *)"<Nop>", hl_attr(HLF_8));
+    else
+	msg_outtrans_special(mp->m_str, FALSE);
+#ifdef FEAT_EVAL
+    if (p_verbose > 0)
+	last_set_msg(mp->m_script_ID);
+#endif
+    out_flush();			/* show one line at a time */
+}
+
+#if defined(FEAT_EVAL) || defined(PROTO)
+/*
+ * Return TRUE if a map exists that has "str" in the rhs for mode "modechars".
+ * Recognize termcap codes in "str".
+ * Also checks mappings local to the current buffer.
+ */
+    int
+map_to_exists(str, modechars, abbr)
+    char_u	*str;
+    char_u	*modechars;
+    int		abbr;
+{
+    int		mode = 0;
+    char_u	*rhs;
+    char_u	*buf;
+    int		retval;
+
+    rhs = replace_termcodes(str, &buf, FALSE, TRUE, FALSE);
+
+    if (vim_strchr(modechars, 'n') != NULL)
+	mode |= NORMAL;
+    if (vim_strchr(modechars, 'v') != NULL)
+	mode |= VISUAL + SELECTMODE;
+    if (vim_strchr(modechars, 'x') != NULL)
+	mode |= VISUAL;
+    if (vim_strchr(modechars, 's') != NULL)
+	mode |= SELECTMODE;
+    if (vim_strchr(modechars, 'o') != NULL)
+	mode |= OP_PENDING;
+    if (vim_strchr(modechars, 'i') != NULL)
+	mode |= INSERT;
+    if (vim_strchr(modechars, 'l') != NULL)
+	mode |= LANGMAP;
+    if (vim_strchr(modechars, 'c') != NULL)
+	mode |= CMDLINE;
+
+    retval = map_to_exists_mode(rhs, mode, abbr);
+    vim_free(buf);
+
+    return retval;
+}
+#endif
+
+/*
+ * Return TRUE if a map exists that has "str" in the rhs for mode "mode".
+ * Also checks mappings local to the current buffer.
+ */
+    int
+map_to_exists_mode(rhs, mode, abbr)
+    char_u	*rhs;
+    int		mode;
+    int		abbr;
+{
+    mapblock_T	*mp;
+    int		hash;
+# ifdef FEAT_LOCALMAP
+    int		expand_buffer = FALSE;
+
+    validate_maphash();
+
+    /* Do it twice: once for global maps and once for local maps. */
+    for (;;)
+    {
+# endif
+	for (hash = 0; hash < 256; ++hash)
+	{
+	    if (abbr)
+	    {
+		if (hash > 0)		/* there is only one abbr list */
+		    break;
+#ifdef FEAT_LOCALMAP
+		if (expand_buffer)
+		    mp = curbuf->b_first_abbr;
+		else
+#endif
+		    mp = first_abbr;
+	    }
+# ifdef FEAT_LOCALMAP
+	    else if (expand_buffer)
+		mp = curbuf->b_maphash[hash];
+# endif
+	    else
+		mp = maphash[hash];
+	    for (; mp; mp = mp->m_next)
+	    {
+		if ((mp->m_mode & mode)
+			&& strstr((char *)mp->m_str, (char *)rhs) != NULL)
+		    return TRUE;
+	    }
+	}
+# ifdef FEAT_LOCALMAP
+	if (expand_buffer)
+	    break;
+	expand_buffer = TRUE;
+    }
+# endif
+
+    return FALSE;
+}
+
+#if defined(FEAT_CMDL_COMPL) || defined(PROTO)
+/*
+ * Used below when expanding mapping/abbreviation names.
+ */
+static int	expand_mapmodes = 0;
+static int	expand_isabbrev = 0;
+#ifdef FEAT_LOCALMAP
+static int	expand_buffer = FALSE;
+#endif
+
+/*
+ * Work out what to complete when doing command line completion of mapping
+ * or abbreviation names.
+ */
+    char_u *
+set_context_in_map_cmd(xp, cmd, arg, forceit, isabbrev, isunmap, cmdidx)
+    expand_T	*xp;
+    char_u	*cmd;
+    char_u	*arg;
+    int		forceit;	/* TRUE if '!' given */
+    int		isabbrev;	/* TRUE if abbreviation */
+    int		isunmap;	/* TRUE if unmap/unabbrev command */
+    cmdidx_T	cmdidx;
+{
+    if (forceit && cmdidx != CMD_map && cmdidx != CMD_unmap)
+	xp->xp_context = EXPAND_NOTHING;
+    else
+    {
+	if (isunmap)
+	    expand_mapmodes = get_map_mode(&cmd, forceit || isabbrev);
+	else
+	{
+	    expand_mapmodes = INSERT + CMDLINE;
+	    if (!isabbrev)
+		expand_mapmodes += VISUAL + SELECTMODE + NORMAL + OP_PENDING;
+	}
+	expand_isabbrev = isabbrev;
+	xp->xp_context = EXPAND_MAPPINGS;
+#ifdef FEAT_LOCALMAP
+	expand_buffer = FALSE;
+#endif
+	for (;;)
+	{
+#ifdef FEAT_LOCALMAP
+	    if (STRNCMP(arg, "<buffer>", 8) == 0)
+	    {
+		expand_buffer = TRUE;
+		arg = skipwhite(arg + 8);
+		continue;
+	    }
+#endif
+	    if (STRNCMP(arg, "<unique>", 8) == 0)
+	    {
+		arg = skipwhite(arg + 8);
+		continue;
+	    }
+	    if (STRNCMP(arg, "<silent>", 8) == 0)
+	    {
+		arg = skipwhite(arg + 8);
+		continue;
+	    }
+#ifdef FEAT_EVAL
+	    if (STRNCMP(arg, "<script>", 8) == 0)
+	    {
+		arg = skipwhite(arg + 8);
+		continue;
+	    }
+	    if (STRNCMP(arg, "<expr>", 6) == 0)
+	    {
+		arg = skipwhite(arg + 6);
+		continue;
+	    }
+#endif
+	    break;
+	}
+	xp->xp_pattern = arg;
+    }
+
+    return NULL;
+}
+
+/*
+ * Find all mapping/abbreviation names that match regexp 'prog'.
+ * For command line expansion of ":[un]map" and ":[un]abbrev" in all modes.
+ * Return OK if matches found, FAIL otherwise.
+ */
+    int
+ExpandMappings(regmatch, num_file, file)
+    regmatch_T	*regmatch;
+    int		*num_file;
+    char_u	***file;
+{
+    mapblock_T	*mp;
+    int		hash;
+    int		count;
+    int		round;
+    char_u	*p;
+    int		i;
+
+    validate_maphash();
+
+    *num_file = 0;		    /* return values in case of FAIL */
+    *file = NULL;
+
+    /*
+     * round == 1: Count the matches.
+     * round == 2: Build the array to keep the matches.
+     */
+    for (round = 1; round <= 2; ++round)
+    {
+	count = 0;
+
+	for (i = 0; i < 5; ++i)
+	{
+	    if (i == 0)
+		p = (char_u *)"<silent>";
+	    else if (i == 1)
+		p = (char_u *)"<unique>";
+#ifdef FEAT_EVAL
+	    else if (i == 2)
+		p = (char_u *)"<script>";
+	    else if (i == 3)
+		p = (char_u *)"<expr>";
+#endif
+#ifdef FEAT_LOCALMAP
+	    else if (i == 4 && !expand_buffer)
+		p = (char_u *)"<buffer>";
+#endif
+	    else
+		continue;
+
+	    if (vim_regexec(regmatch, p, (colnr_T)0))
+	    {
+		if (round == 1)
+		    ++count;
+		else
+		    (*file)[count++] = vim_strsave(p);
+	    }
+	}
+
+	for (hash = 0; hash < 256; ++hash)
+	{
+	    if (expand_isabbrev)
+	    {
+		if (hash > 0)	/* only one abbrev list */
+		    break; /* for (hash) */
+		mp = first_abbr;
+	    }
+#ifdef FEAT_LOCALMAP
+	    else if (expand_buffer)
+		mp = curbuf->b_maphash[hash];
+#endif
+	    else
+		mp = maphash[hash];
+	    for (; mp; mp = mp->m_next)
+	    {
+		if (mp->m_mode & expand_mapmodes)
+		{
+		    p = translate_mapping(mp->m_keys, TRUE);
+		    if (p != NULL && vim_regexec(regmatch, p, (colnr_T)0))
+		    {
+			if (round == 1)
+			    ++count;
+			else
+			{
+			    (*file)[count++] = p;
+			    p = NULL;
+			}
+		    }
+		    vim_free(p);
+		}
+	    } /* for (mp) */
+	} /* for (hash) */
+
+	if (count == 0)			/* no match found */
+	    break; /* for (round) */
+
+	if (round == 1)
+	{
+	    *file = (char_u **)alloc((unsigned)(count * sizeof(char_u *)));
+	    if (*file == NULL)
+		return FAIL;
+	}
+    } /* for (round) */
+
+    if (count > 1)
+    {
+	char_u	**ptr1;
+	char_u	**ptr2;
+	char_u	**ptr3;
+
+	/* Sort the matches */
+	sort_strings(*file, count);
+
+	/* Remove multiple entries */
+	ptr1 = *file;
+	ptr2 = ptr1 + 1;
+	ptr3 = ptr1 + count;
+
+	while (ptr2 < ptr3)
+	{
+	    if (STRCMP(*ptr1, *ptr2))
+		*++ptr1 = *ptr2++;
+	    else
+	    {
+		vim_free(*ptr2++);
+		count--;
+	    }
+	}
+    }
+
+    *num_file = count;
+    return (count == 0 ? FAIL : OK);
+}
+#endif /* FEAT_CMDL_COMPL */
+
+/*
+ * Check for an abbreviation.
+ * Cursor is at ptr[col]. When inserting, mincol is where insert started.
+ * "c" is the character typed before check_abbr was called.  It may have
+ * ABBR_OFF added to avoid prepending a CTRL-V to it.
+ *
+ * Historic vi practice: The last character of an abbreviation must be an id
+ * character ([a-zA-Z0-9_]). The characters in front of it must be all id
+ * characters or all non-id characters. This allows for abbr. "#i" to
+ * "#include".
+ *
+ * Vim addition: Allow for abbreviations that end in a non-keyword character.
+ * Then there must be white space before the abbr.
+ *
+ * return TRUE if there is an abbreviation, FALSE if not
+ */
+    int
+check_abbr(c, ptr, col, mincol)
+    int		c;
+    char_u	*ptr;
+    int		col;
+    int		mincol;
+{
+    int		len;
+    int		scol;		/* starting column of the abbr. */
+    int		j;
+    char_u	*s;
+#ifdef FEAT_MBYTE
+    char_u	tb[MB_MAXBYTES + 4];
+#else
+    char_u	tb[4];
+#endif
+    mapblock_T	*mp;
+#ifdef FEAT_LOCALMAP
+    mapblock_T	*mp2;
+#endif
+#ifdef FEAT_MBYTE
+    int		clen = 0;	/* length in characters */
+#endif
+    int		is_id = TRUE;
+    int		vim_abbr;
+
+    if (typebuf.tb_no_abbr_cnt)	/* abbrev. are not recursive */
+	return FALSE;
+    if ((KeyNoremap & (RM_NONE|RM_SCRIPT)) != 0)
+	/* no remapping implies no abbreviation */
+	return FALSE;
+
+    /*
+     * Check for word before the cursor: If it ends in a keyword char all
+     * chars before it must be al keyword chars or non-keyword chars, but not
+     * white space. If it ends in a non-keyword char we accept any characters
+     * before it except white space.
+     */
+    if (col == 0)				/* cannot be an abbr. */
+	return FALSE;
+
+#ifdef FEAT_MBYTE
+    if (has_mbyte)
+    {
+	char_u *p;
+
+	p = mb_prevptr(ptr, ptr + col);
+	if (!vim_iswordp(p))
+	    vim_abbr = TRUE;			/* Vim added abbr. */
+	else
+	{
+	    vim_abbr = FALSE;			/* vi compatible abbr. */
+	    if (p > ptr)
+		is_id = vim_iswordp(mb_prevptr(ptr, p));
+	}
+	clen = 1;
+	while (p > ptr + mincol)
+	{
+	    p = mb_prevptr(ptr, p);
+	    if (vim_isspace(*p) || (!vim_abbr && is_id != vim_iswordp(p)))
+	    {
+		p += (*mb_ptr2len)(p);
+		break;
+	    }
+	    ++clen;
+	}
+	scol = (int)(p - ptr);
+    }
+    else
+#endif
+    {
+	if (!vim_iswordc(ptr[col - 1]))
+	    vim_abbr = TRUE;			/* Vim added abbr. */
+	else
+	{
+	    vim_abbr = FALSE;			/* vi compatible abbr. */
+	    if (col > 1)
+		is_id = vim_iswordc(ptr[col - 2]);
+	}
+	for (scol = col - 1; scol > 0 && !vim_isspace(ptr[scol - 1])
+		&& (vim_abbr || is_id == vim_iswordc(ptr[scol - 1])); --scol)
+	    ;
+    }
+
+    if (scol < mincol)
+	scol = mincol;
+    if (scol < col)		/* there is a word in front of the cursor */
+    {
+	ptr += scol;
+	len = col - scol;
+#ifdef FEAT_LOCALMAP
+	mp = curbuf->b_first_abbr;
+	mp2 = first_abbr;
+	if (mp == NULL)
+	{
+	    mp = mp2;
+	    mp2 = NULL;
+	}
+#else
+	mp = first_abbr;
+#endif
+	for ( ; mp;
+#ifdef FEAT_LOCALMAP
+		mp->m_next == NULL ? (mp = mp2, mp2 = NULL) :
+#endif
+		(mp = mp->m_next))
+	{
+	    /* find entries with right mode and keys */
+	    if (       (mp->m_mode & State)
+		    && mp->m_keylen == len
+		    && !STRNCMP(mp->m_keys, ptr, (size_t)len))
+		break;
+	}
+	if (mp != NULL)
+	{
+	    /*
+	     * Found a match:
+	     * Insert the rest of the abbreviation in typebuf.tb_buf[].
+	     * This goes from end to start.
+	     *
+	     * Characters 0x000 - 0x100: normal chars, may need CTRL-V,
+	     * except K_SPECIAL: Becomes K_SPECIAL KS_SPECIAL KE_FILLER
+	     * Characters where IS_SPECIAL() == TRUE: key codes, need
+	     * K_SPECIAL. Other characters (with ABBR_OFF): don't use CTRL-V.
+	     *
+	     * Character CTRL-] is treated specially - it completes the
+	     * abbreviation, but is not inserted into the input stream.
+	     */
+	    j = 0;
+					/* special key code, split up */
+	    if (c != Ctrl_RSB)
+	    {
+		if (IS_SPECIAL(c) || c == K_SPECIAL)
+		{
+		    tb[j++] = K_SPECIAL;
+		    tb[j++] = K_SECOND(c);
+		    tb[j++] = K_THIRD(c);
+		}
+		else
+		{
+		    if (c < ABBR_OFF && (c < ' ' || c > '~'))
+			tb[j++] = Ctrl_V;	/* special char needs CTRL-V */
+#ifdef FEAT_MBYTE
+		    if (has_mbyte)
+		    {
+			/* if ABBR_OFF has been added, remove it here */
+			if (c >= ABBR_OFF)
+			    c -= ABBR_OFF;
+			j += (*mb_char2bytes)(c, tb + j);
+		    }
+		    else
+#endif
+			tb[j++] = c;
+		}
+		tb[j] = NUL;
+					/* insert the last typed char */
+		(void)ins_typebuf(tb, 1, 0, TRUE, mp->m_silent);
+	    }
+#ifdef FEAT_EVAL
+	    if (mp->m_expr)
+		s = eval_map_expr(mp->m_str);
+	    else
+#endif
+		s = mp->m_str;
+	    if (s != NULL)
+	    {
+					/* insert the to string */
+		(void)ins_typebuf(s, mp->m_noremap, 0, TRUE, mp->m_silent);
+					/* no abbrev. for these chars */
+		typebuf.tb_no_abbr_cnt += (int)STRLEN(s) + j + 1;
+#ifdef FEAT_EVAL
+		if (mp->m_expr)
+		    vim_free(s);
+#endif
+	    }
+
+	    tb[0] = Ctrl_H;
+	    tb[1] = NUL;
+#ifdef FEAT_MBYTE
+	    if (has_mbyte)
+		len = clen;	/* Delete characters instead of bytes */
+#endif
+	    while (len-- > 0)		/* delete the from string */
+		(void)ins_typebuf(tb, 1, 0, TRUE, mp->m_silent);
+	    return TRUE;
+	}
+    }
+    return FALSE;
+}
+
+#ifdef FEAT_EVAL
+/*
+ * Evaluate the RHS of a mapping or abbreviations and take care of escaping
+ * special characters.
+ */
+    static char_u *
+eval_map_expr(str)
+    char_u	*str;
+{
+    char_u	*res;
+    char_u	*p;
+    char_u	*save_cmd;
+    pos_T	save_cursor;
+
+    save_cmd = save_cmdline_alloc();
+    if (save_cmd == NULL)
+	return NULL;
+
+    /* Forbid changing text or using ":normal" to avoid most of the bad side
+     * effects.  Also restore the cursor position. */
+    ++textlock;
+#ifdef FEAT_EX_EXTRA
+    ++ex_normal_lock;
+#endif
+    save_cursor = curwin->w_cursor;
+    p = eval_to_string(str, NULL, FALSE);
+    --textlock;
+#ifdef FEAT_EX_EXTRA
+    --ex_normal_lock;
+#endif
+    curwin->w_cursor = save_cursor;
+
+    restore_cmdline_alloc(save_cmd);
+    if (p == NULL)
+	return NULL;
+    res = vim_strsave_escape_csi(p);
+    vim_free(p);
+
+    return res;
+}
+#endif
+
+/*
+ * Copy "p" to allocated memory, escaping K_SPECIAL and CSI so that the result
+ * can be put in the typeahead buffer.
+ * Returns NULL when out of memory.
+ */
+    char_u *
+vim_strsave_escape_csi(p)
+    char_u *p;
+{
+    char_u	*res;
+    char_u	*s, *d;
+
+    /* Need a buffer to hold up to three times as much. */
+    res = alloc((unsigned)(STRLEN(p) * 3) + 1);
+    if (res != NULL)
+    {
+	d = res;
+	for (s = p; *s != NUL; )
+	{
+	    if (s[0] == K_SPECIAL && s[1] != NUL && s[2] != NUL)
+	    {
+		/* Copy special key unmodified. */
+		*d++ = *s++;
+		*d++ = *s++;
+		*d++ = *s++;
+	    }
+	    else
+	    {
+		/* Add character, possibly multi-byte to destination, escaping
+		 * CSI and K_SPECIAL. */
+		d = add_char2buf(PTR2CHAR(s), d);
+		mb_ptr_adv(s);
+	    }
+	}
+	*d = NUL;
+    }
+    return res;
+}
+
+/*
+ * Remove escaping from CSI and K_SPECIAL characters.  Reverse of
+ * vim_strsave_escape_csi().  Works in-place.
+ */
+    void
+vim_unescape_csi(p)
+    char_u *p;
+{
+    char_u	*s = p, *d = p;
+
+    while (*s != NUL)
+    {
+	if (s[0] == K_SPECIAL && s[1] == KS_SPECIAL && s[2] == KE_FILLER)
+	{
+	    *d++ = K_SPECIAL;
+	    s += 3;
+	}
+	else if ((s[0] == K_SPECIAL || s[0] == CSI)
+				   && s[1] == KS_EXTRA && s[2] == (int)KE_CSI)
+	{
+	    *d++ = CSI;
+	    s += 3;
+	}
+	else
+	    *d++ = *s++;
+    }
+    *d = NUL;
+}
+
+/*
+ * Write map commands for the current mappings to an .exrc file.
+ * Return FAIL on error, OK otherwise.
+ */
+    int
+makemap(fd, buf)
+    FILE	*fd;
+    buf_T	*buf;	    /* buffer for local mappings or NULL */
+{
+    mapblock_T	*mp;
+    char_u	c1, c2;
+    char_u	*p;
+    char	*cmd;
+    int		abbr;
+    int		hash;
+    int		did_cpo = FALSE;
+    int		i;
+
+    validate_maphash();
+
+    /*
+     * Do the loop twice: Once for mappings, once for abbreviations.
+     * Then loop over all map hash lists.
+     */
+    for (abbr = 0; abbr < 2; ++abbr)
+	for (hash = 0; hash < 256; ++hash)
+	{
+	    if (abbr)
+	    {
+		if (hash > 0)		/* there is only one abbr list */
+		    break;
+#ifdef FEAT_LOCALMAP
+		if (buf != NULL)
+		    mp = buf->b_first_abbr;
+		else
+#endif
+		    mp = first_abbr;
+	    }
+	    else
+	    {
+#ifdef FEAT_LOCALMAP
+		if (buf != NULL)
+		    mp = buf->b_maphash[hash];
+		else
+#endif
+		    mp = maphash[hash];
+	    }
+
+	    for ( ; mp; mp = mp->m_next)
+	    {
+		/* skip script-local mappings */
+		if (mp->m_noremap == REMAP_SCRIPT)
+		    continue;
+
+		/* skip mappings that contain a <SNR> (script-local thing),
+		 * they probably don't work when loaded again */
+		for (p = mp->m_str; *p != NUL; ++p)
+		    if (p[0] == K_SPECIAL && p[1] == KS_EXTRA
+						       && p[2] == (int)KE_SNR)
+			break;
+		if (*p != NUL)
+		    continue;
+
+		c1 = NUL;
+		c2 = NUL;
+		if (abbr)
+		    cmd = "abbr";
+		else
+		    cmd = "map";
+		switch (mp->m_mode)
+		{
+		    case NORMAL + VISUAL + SELECTMODE + OP_PENDING:
+			break;
+		    case NORMAL:
+			c1 = 'n';
+			break;
+		    case VISUAL + SELECTMODE:
+			c1 = 'v';
+			break;
+		    case VISUAL:
+			c1 = 'x';
+			break;
+		    case SELECTMODE:
+			c1 = 's';
+			break;
+		    case OP_PENDING:
+			c1 = 'o';
+			break;
+		    case NORMAL + VISUAL + SELECTMODE:
+			c1 = 'n';
+			c2 = 'v';
+			break;
+		    case VISUAL + SELECTMODE + OP_PENDING:
+			c1 = 'v';
+			c2 = 'o';
+			break;
+		    case NORMAL + OP_PENDING:
+			c1 = 'n';
+			c2 = 'o';
+			break;
+		    case CMDLINE + INSERT:
+			if (!abbr)
+			    cmd = "map!";
+			break;
+		    case CMDLINE:
+			c1 = 'c';
+			break;
+		    case INSERT:
+			c1 = 'i';
+			break;
+		    case LANGMAP:
+			c1 = 'l';
+			break;
+		    default:
+			EMSG(_("E228: makemap: Illegal mode"));
+			return FAIL;
+		}
+		do	/* may do this twice if c2 is set */
+		{
+		    /* When outputting <> form, need to make sure that 'cpo'
+		     * is set to the Vim default. */
+		    if (!did_cpo)
+		    {
+			if (*mp->m_str == NUL)		/* will use <Nop> */
+			    did_cpo = TRUE;
+			else
+			    for (i = 0; i < 2; ++i)
+				for (p = (i ? mp->m_str : mp->m_keys); *p; ++p)
+				    if (*p == K_SPECIAL || *p == NL)
+					did_cpo = TRUE;
+			if (did_cpo)
+			{
+			    if (fprintf(fd, "let s:cpo_save=&cpo") < 0
+				    || put_eol(fd) < 0
+				    || fprintf(fd, "set cpo&vim") < 0
+				    || put_eol(fd) < 0)
+				return FAIL;
+			}
+		    }
+		    if (c1 && putc(c1, fd) < 0)
+			return FAIL;
+		    if (mp->m_noremap != REMAP_YES && fprintf(fd, "nore") < 0)
+			return FAIL;
+		    if (fprintf(fd, cmd) < 0)
+			return FAIL;
+		    if (buf != NULL && fputs(" <buffer>", fd) < 0)
+			return FAIL;
+		    if (mp->m_silent && fputs(" <silent>", fd) < 0)
+			return FAIL;
+#ifdef FEAT_EVAL
+		    if (mp->m_noremap == REMAP_SCRIPT
+						 && fputs("<script>", fd) < 0)
+			return FAIL;
+		    if (mp->m_expr && fputs(" <expr>", fd) < 0)
+			return FAIL;
+#endif
+
+		    if (       putc(' ', fd) < 0
+			    || put_escstr(fd, mp->m_keys, 0) == FAIL
+			    || putc(' ', fd) < 0
+			    || put_escstr(fd, mp->m_str, 1) == FAIL
+			    || put_eol(fd) < 0)
+			return FAIL;
+		    c1 = c2;
+		    c2 = NUL;
+		}
+		while (c1);
+	    }
+	}
+
+    if (did_cpo)
+	if (fprintf(fd, "let &cpo=s:cpo_save") < 0
+		|| put_eol(fd) < 0
+		|| fprintf(fd, "unlet s:cpo_save") < 0
+		|| put_eol(fd) < 0)
+	    return FAIL;
+    return OK;
+}
+
+/*
+ * write escape string to file
+ * "what": 0 for :map lhs, 1 for :map rhs, 2 for :set
+ *
+ * return FAIL for failure, OK otherwise
+ */
+    int
+put_escstr(fd, strstart, what)
+    FILE	*fd;
+    char_u	*strstart;
+    int		what;
+{
+    char_u	*str = strstart;
+    int		c;
+    int		modifiers;
+
+    /* :map xx <Nop> */
+    if (*str == NUL && what == 1)
+    {
+	if (fprintf(fd, "<Nop>") < 0)
+	    return FAIL;
+	return OK;
+    }
+
+    for ( ; *str != NUL; ++str)
+    {
+#ifdef FEAT_MBYTE
+	char_u	*p;
+
+	/* Check for a multi-byte character, which may contain escaped
+	 * K_SPECIAL and CSI bytes */
+	p = mb_unescape(&str);
+	if (p != NULL)
+	{
+	    while (*p != NUL)
+		if (fputc(*p++, fd) < 0)
+		    return FAIL;
+	    --str;
+	    continue;
+	}
+#endif
+
+	c = *str;
+	/*
+	 * Special key codes have to be translated to be able to make sense
+	 * when they are read back.
+	 */
+	if (c == K_SPECIAL && what != 2)
+	{
+	    modifiers = 0x0;
+	    if (str[1] == KS_MODIFIER)
+	    {
+		modifiers = str[2];
+		str += 3;
+		c = *str;
+	    }
+	    if (c == K_SPECIAL)
+	    {
+		c = TO_SPECIAL(str[1], str[2]);
+		str += 2;
+	    }
+	    if (IS_SPECIAL(c) || modifiers)	/* special key */
+	    {
+		if (fprintf(fd, (char *)get_special_key_name(c, modifiers)) < 0)
+		    return FAIL;
+		continue;
+	    }
+	}
+
+	/*
+	 * A '\n' in a map command should be written as <NL>.
+	 * A '\n' in a set command should be written as \^V^J.
+	 */
+	if (c == NL)
+	{
+	    if (what == 2)
+	    {
+		if (fprintf(fd, IF_EB("\\\026\n", "\\" CTRL_V_STR "\n")) < 0)
+		    return FAIL;
+	    }
+	    else
+	    {
+		if (fprintf(fd, "<NL>") < 0)
+		    return FAIL;
+	    }
+	    continue;
+	}
+
+	/*
+	 * Some characters have to be escaped with CTRL-V to
+	 * prevent them from misinterpreted in DoOneCmd().
+	 * A space, Tab and '"' has to be escaped with a backslash to
+	 * prevent it to be misinterpreted in do_set().
+	 * A space has to be escaped with a CTRL-V when it's at the start of a
+	 * ":map" rhs.
+	 * A '<' has to be escaped with a CTRL-V to prevent it being
+	 * interpreted as the start of a special key name.
+	 * A space in the lhs of a :map needs a CTRL-V.
+	 */
+	if (what == 2 && (vim_iswhite(c) || c == '"' || c == '\\'))
+	{
+	    if (putc('\\', fd) < 0)
+		return FAIL;
+	}
+	else if (c < ' ' || c > '~' || c == '|'
+		|| (what == 0 && c == ' ')
+		|| (what == 1 && str == strstart && c == ' ')
+		|| (what != 2 && c == '<'))
+	{
+	    if (putc(Ctrl_V, fd) < 0)
+		return FAIL;
+	}
+	if (putc(c, fd) < 0)
+	    return FAIL;
+    }
+    return OK;
+}
+
+/*
+ * Check all mappings for the presence of special key codes.
+ * Used after ":set term=xxx".
+ */
+    void
+check_map_keycodes()
+{
+    mapblock_T	*mp;
+    char_u	*p;
+    int		i;
+    char_u	buf[3];
+    char_u	*save_name;
+    int		abbr;
+    int		hash;
+#ifdef FEAT_LOCALMAP
+    buf_T	*bp;
+#endif
+
+    validate_maphash();
+    save_name = sourcing_name;
+    sourcing_name = (char_u *)"mappings"; /* avoids giving error messages */
+
+#ifdef FEAT_LOCALMAP
+    /* This this once for each buffer, and then once for global
+     * mappings/abbreviations with bp == NULL */
+    for (bp = firstbuf; ; bp = bp->b_next)
+    {
+#endif
+	/*
+	 * Do the loop twice: Once for mappings, once for abbreviations.
+	 * Then loop over all map hash lists.
+	 */
+	for (abbr = 0; abbr <= 1; ++abbr)
+	    for (hash = 0; hash < 256; ++hash)
+	    {
+		if (abbr)
+		{
+		    if (hash)	    /* there is only one abbr list */
+			break;
+#ifdef FEAT_LOCALMAP
+		    if (bp != NULL)
+			mp = bp->b_first_abbr;
+		    else
+#endif
+			mp = first_abbr;
+		}
+		else
+		{
+#ifdef FEAT_LOCALMAP
+		    if (bp != NULL)
+			mp = bp->b_maphash[hash];
+		    else
+#endif
+			mp = maphash[hash];
+		}
+		for ( ; mp != NULL; mp = mp->m_next)
+		{
+		    for (i = 0; i <= 1; ++i)	/* do this twice */
+		    {
+			if (i == 0)
+			    p = mp->m_keys;	/* once for the "from" part */
+			else
+			    p = mp->m_str;	/* and once for the "to" part */
+			while (*p)
+			{
+			    if (*p == K_SPECIAL)
+			    {
+				++p;
+				if (*p < 128)   /* for "normal" tcap entries */
+				{
+				    buf[0] = p[0];
+				    buf[1] = p[1];
+				    buf[2] = NUL;
+				    (void)add_termcap_entry(buf, FALSE);
+				}
+				++p;
+			    }
+			    ++p;
+			}
+		    }
+		}
+	    }
+#ifdef FEAT_LOCALMAP
+	if (bp == NULL)
+	    break;
+    }
+#endif
+    sourcing_name = save_name;
+}
+
+#ifdef FEAT_EVAL
+/*
+ * Check the string "keys" against the lhs of all mappings
+ * Return pointer to rhs of mapping (mapblock->m_str)
+ * NULL otherwise
+ */
+    char_u *
+check_map(keys, mode, exact, ign_mod, abbr)
+    char_u	*keys;
+    int		mode;
+    int		exact;		/* require exact match */
+    int		ign_mod;	/* ignore preceding modifier */
+    int		abbr;		/* do abbreviations */
+{
+    int		hash;
+    int		len, minlen;
+    mapblock_T	*mp;
+    char_u	*s;
+#ifdef FEAT_LOCALMAP
+    int		local;
+#endif
+
+    validate_maphash();
+
+    len = (int)STRLEN(keys);
+#ifdef FEAT_LOCALMAP
+    for (local = 1; local >= 0; --local)
+#endif
+	/* loop over all hash lists */
+	for (hash = 0; hash < 256; ++hash)
+	{
+	    if (abbr)
+	    {
+		if (hash > 0)		/* there is only one list. */
+		    break;
+#ifdef FEAT_LOCALMAP
+		if (local)
+		    mp = curbuf->b_first_abbr;
+		else
+#endif
+		    mp = first_abbr;
+	    }
+#ifdef FEAT_LOCALMAP
+	    else if (local)
+		mp = curbuf->b_maphash[hash];
+#endif
+	    else
+		mp = maphash[hash];
+	    for ( ; mp != NULL; mp = mp->m_next)
+	    {
+		/* skip entries with wrong mode, wrong length and not matching
+		 * ones */
+		if ((mp->m_mode & mode) && (!exact || mp->m_keylen == len))
+		{
+		    if (len > mp->m_keylen)
+			minlen = mp->m_keylen;
+		    else
+			minlen = len;
+		    s = mp->m_keys;
+		    if (ign_mod && s[0] == K_SPECIAL && s[1] == KS_MODIFIER
+							       && s[2] != NUL)
+		    {
+			s += 3;
+			if (len > mp->m_keylen - 3)
+			    minlen = mp->m_keylen - 3;
+		    }
+		    if (STRNCMP(s, keys, minlen) == 0)
+			return mp->m_str;
+		}
+	    }
+	}
+
+    return NULL;
+}
+#endif
+
+#if defined(MSDOS) || defined(MSWIN) || defined(OS2) || defined(MACOS)
+
+#define VIS_SEL	(VISUAL+SELECTMODE)	/* abbreviation */
+
+/*
+ * Default mappings for some often used keys.
+ */
+static struct initmap
+{
+    char_u	*arg;
+    int		mode;
+} initmappings[] =
+{
+#if defined(MSDOS) || defined(MSWIN) || defined(OS2)
+	/* Use the Windows (CUA) keybindings. */
+# ifdef FEAT_GUI
+#  if 0	    /* These are now used to move tab pages */
+	{(char_u *)"<C-PageUp> H", NORMAL+VIS_SEL},
+	{(char_u *)"<C-PageUp> <C-O>H",INSERT},
+	{(char_u *)"<C-PageDown> L$", NORMAL+VIS_SEL},
+	{(char_u *)"<C-PageDown> <C-O>L<C-O>$", INSERT},
+#  endif
+
+	/* paste, copy and cut */
+	{(char_u *)"<S-Insert> \"*P", NORMAL},
+	{(char_u *)"<S-Insert> \"-d\"*P", VIS_SEL},
+	{(char_u *)"<S-Insert> <C-R><C-O>*", INSERT+CMDLINE},
+	{(char_u *)"<C-Insert> \"*y", VIS_SEL},
+	{(char_u *)"<S-Del> \"*d", VIS_SEL},
+	{(char_u *)"<C-Del> \"*d", VIS_SEL},
+	{(char_u *)"<C-X> \"*d", VIS_SEL},
+	/* Missing: CTRL-C (cancel) and CTRL-V (block selection) */
+# else
+#  if 0	    /* These are now used to move tab pages */
+	{(char_u *)"\316\204 H", NORMAL+VIS_SEL},    /* CTRL-PageUp is "H" */
+	{(char_u *)"\316\204 \017H",INSERT},	    /* CTRL-PageUp is "^OH"*/
+	{(char_u *)"\316v L$", NORMAL+VIS_SEL},	    /* CTRL-PageDown is "L$" */
+	{(char_u *)"\316v \017L\017$", INSERT},	    /* CTRL-PageDown ="^OL^O$"*/
+#  endif
+	{(char_u *)"\316w <C-Home>", NORMAL+VIS_SEL},
+	{(char_u *)"\316w <C-Home>", INSERT+CMDLINE},
+	{(char_u *)"\316u <C-End>", NORMAL+VIS_SEL},
+	{(char_u *)"\316u <C-End>", INSERT+CMDLINE},
+
+	/* paste, copy and cut */
+#  ifdef FEAT_CLIPBOARD
+#   ifdef DJGPP
+	{(char_u *)"\316\122 \"*P", NORMAL},	    /* SHIFT-Insert is "*P */
+	{(char_u *)"\316\122 \"-d\"*P", VIS_SEL},    /* SHIFT-Insert is "-d"*P */
+	{(char_u *)"\316\122 \022\017*", INSERT},  /* SHIFT-Insert is ^R^O* */
+	{(char_u *)"\316\222 \"*y", VIS_SEL},	    /* CTRL-Insert is "*y */
+#    if 0 /* Shift-Del produces the same code as Del */
+	{(char_u *)"\316\123 \"*d", VIS_SEL},	    /* SHIFT-Del is "*d */
+#    endif
+	{(char_u *)"\316\223 \"*d", VIS_SEL},	    /* CTRL-Del is "*d */
+	{(char_u *)"\030 \"-d", VIS_SEL},	    /* CTRL-X is "-d */
+#   else
+	{(char_u *)"\316\324 \"*P", NORMAL},	    /* SHIFT-Insert is "*P */
+	{(char_u *)"\316\324 \"-d\"*P", VIS_SEL},    /* SHIFT-Insert is "-d"*P */
+	{(char_u *)"\316\324 \022\017*", INSERT},  /* SHIFT-Insert is ^R^O* */
+	{(char_u *)"\316\325 \"*y", VIS_SEL},	    /* CTRL-Insert is "*y */
+	{(char_u *)"\316\327 \"*d", VIS_SEL},	    /* SHIFT-Del is "*d */
+	{(char_u *)"\316\330 \"*d", VIS_SEL},	    /* CTRL-Del is "*d */
+	{(char_u *)"\030 \"-d", VIS_SEL},	    /* CTRL-X is "-d */
+#   endif
+#  else
+	{(char_u *)"\316\324 P", NORMAL},	    /* SHIFT-Insert is P */
+	{(char_u *)"\316\324 \"-dP", VIS_SEL},	    /* SHIFT-Insert is "-dP */
+	{(char_u *)"\316\324 \022\017\"", INSERT}, /* SHIFT-Insert is ^R^O" */
+	{(char_u *)"\316\325 y", VIS_SEL},	    /* CTRL-Insert is y */
+	{(char_u *)"\316\327 d", VIS_SEL},	    /* SHIFT-Del is d */
+	{(char_u *)"\316\330 d", VIS_SEL},	    /* CTRL-Del is d */
+#  endif
+# endif
+#endif
+
+#if defined(MACOS)
+	/* Use the Standard MacOS binding. */
+	/* paste, copy and cut */
+	{(char_u *)"<D-v> \"*P", NORMAL},
+	{(char_u *)"<D-v> \"-d\"*P", VIS_SEL},
+	{(char_u *)"<D-v> <C-R>*", INSERT+CMDLINE},
+	{(char_u *)"<D-c> \"*y", VIS_SEL},
+	{(char_u *)"<D-x> \"*d", VIS_SEL},
+	{(char_u *)"<Backspace> \"-d", VIS_SEL},
+#endif
+};
+
+# undef VIS_SEL
+#endif
+
+/*
+ * Set up default mappings.
+ */
+    void
+init_mappings()
+{
+#if defined(MSDOS) || defined(MSWIN) || defined(OS2) || defined(MACOS)
+    int		i;
+
+    for (i = 0; i < sizeof(initmappings) / sizeof(struct initmap); ++i)
+	add_map(initmappings[i].arg, initmappings[i].mode);
+#endif
+}
+
+#if defined(MSDOS) || defined(MSWIN) || defined(OS2) \
+	|| defined(FEAT_CMDWIN) || defined(MACOS) || defined(PROTO)
+/*
+ * Add a mapping "map" for mode "mode".
+ * Need to put string in allocated memory, because do_map() will modify it.
+ */
+    void
+add_map(map, mode)
+    char_u	*map;
+    int		mode;
+{
+    char_u	*s;
+    char_u	*cpo_save = p_cpo;
+
+    p_cpo = (char_u *)"";	/* Allow <> notation */
+    s = vim_strsave(map);
+    if (s != NULL)
+    {
+	(void)do_map(0, s, mode, FALSE);
+	vim_free(s);
+    }
+    p_cpo = cpo_save;
+}
+#endif
--- /dev/null
+++ b/globals.h
@@ -1,0 +1,1545 @@
+/* vi:set ts=8 sts=4 sw=4:
+ *
+ * VIM - Vi IMproved	by Bram Moolenaar
+ *
+ * Do ":help uganda"  in Vim to read copying and usage conditions.
+ * Do ":help credits" in Vim to see a list of people who contributed.
+ */
+
+/*
+ * definition of global variables
+ */
+
+/*
+ * Number of Rows and Columns in the screen.
+ * Must be long to be able to use them as options in option.c.
+ * Note: Use screen_Rows and screen_Columns to access items in ScreenLines[].
+ * They may have different values when the screen wasn't (re)allocated yet
+ * after setting Rows or Columns (e.g., when starting up).
+ */
+EXTERN long	Rows			/* nr of rows in the screen */
+#ifdef DO_INIT
+# if defined(MSDOS) || defined(WIN3264) || defined(OS2)
+			    = 25L
+# else
+			    = 24L
+# endif
+#endif
+			    ;
+EXTERN long	Columns INIT(= 80);	/* nr of columns in the screen */
+
+/*
+ * The characters that are currently on the screen are kept in ScreenLines[].
+ * It is a single block of characters, the size of the screen plus one line.
+ * The attributes for those characters are kept in ScreenAttrs[].
+ *
+ * "LineOffset[n]" is the offset from ScreenLines[] for the start of line 'n'.
+ * The same value is used for ScreenLinesUC[] and ScreenAttrs[].
+ *
+ * Note: before the screen is initialized and when out of memory these can be
+ * NULL.
+ */
+EXTERN schar_T	*ScreenLines INIT(= NULL);
+EXTERN sattr_T	*ScreenAttrs INIT(= NULL);
+EXTERN unsigned	*LineOffset INIT(= NULL);
+EXTERN char_u	*LineWraps INIT(= NULL);	/* line wraps to next line */
+
+#ifdef FEAT_MBYTE
+/*
+ * When using Unicode characters (in UTF-8 encoding) the character in
+ * ScreenLinesUC[] contains the Unicode for the character at this position, or
+ * NUL when the character in ScreenLines[] is to be used (ASCII char).
+ * The composing characters are to be drawn on top of the original character.
+ * Note: These three are only allocated when enc_utf8 is set!
+ */
+EXTERN u8char_T	*ScreenLinesUC INIT(= NULL);	/* decoded UTF-8 characters */
+EXTERN u8char_T	*ScreenLinesC[MAX_MCO];		/* composing characters */
+EXTERN int	Screen_mco INIT(= 0);		/* value of p_mco used when
+						   allocating ScreenLinesC[] */
+
+/* Only used for euc-jp: Second byte of a character that starts with 0x8e.
+ * These are single-width. */
+EXTERN schar_T	*ScreenLines2 INIT(= NULL);
+#endif
+
+#ifdef FEAT_WINDOWS
+/*
+ * Indexes for tab page line:
+ *	N > 0 for label of tab page N
+ *	N == 0 for no label
+ *	N < 0 for closing tab page -N
+ *	N == -999 for closing current tab page
+ */
+EXTERN short	*TabPageIdxs INIT(= NULL);
+#endif
+
+EXTERN int	screen_Rows INIT(= 0);	    /* actual size of ScreenLines[] */
+EXTERN int	screen_Columns INIT(= 0);   /* actual size of ScreenLines[] */
+
+/*
+ * When vgetc() is called, it sets mod_mask to the set of modifiers that are
+ * held down based on the MOD_MASK_* symbols that are read first.
+ */
+EXTERN int	mod_mask INIT(= 0x0);		/* current key modifiers */
+
+/*
+ * Cmdline_row is the row where the command line starts, just below the
+ * last window.
+ * When the cmdline gets longer than the available space the screen gets
+ * scrolled up. After a CTRL-D (show matches), after hitting ':' after
+ * "hit return", and for the :global command, the command line is
+ * temporarily moved.  The old position is restored with the next call to
+ * update_screen().
+ */
+EXTERN int	cmdline_row;
+
+EXTERN int	redraw_cmdline INIT(= FALSE);	/* cmdline must be redrawn */
+EXTERN int	clear_cmdline INIT(= FALSE);	/* cmdline must be cleared */
+EXTERN int	mode_displayed INIT(= FALSE);	/* mode is being displayed */
+#if defined(FEAT_CRYPT) || defined(FEAT_EVAL)
+EXTERN int	cmdline_star INIT(= FALSE);	/* cmdline is crypted */
+#endif
+
+EXTERN int	exec_from_reg INIT(= FALSE);	/* executing register */
+
+EXTERN int	screen_cleared INIT(= FALSE);	/* screen has been cleared */
+
+/*
+ * When '$' is included in 'cpoptions' option set:
+ * When a change command is given that deletes only part of a line, a dollar
+ * is put at the end of the changed text. dollar_vcol is set to the virtual
+ * column of this '$'.
+ */
+EXTERN colnr_T	dollar_vcol INIT(= 0);
+
+#ifdef FEAT_INS_EXPAND
+/*
+ * Variables for Insert mode completion.
+ */
+
+/* Length in bytes of the text being completed (this is deleted to be replaced
+ * by the match.) */
+EXTERN int	compl_length INIT(= 0);
+
+/* Set when character typed while looking for matches and it means we should
+ * stop looking for matches. */
+EXTERN int	compl_interrupted INIT(= FALSE);
+
+/* List of flags for method of completion. */
+EXTERN int	compl_cont_status INIT(= 0);
+# define CONT_ADDING	1	/* "normal" or "adding" expansion */
+# define CONT_INTRPT	(2 + 4)	/* a ^X interrupted the current expansion */
+				/* it's set only iff N_ADDS is set */
+# define CONT_N_ADDS	4	/* next ^X<> will add-new or expand-current */
+# define CONT_S_IPOS	8	/* next ^X<> will set initial_pos?
+				 * if so, word-wise-expansion will set SOL */
+# define CONT_SOL	16	/* pattern includes start of line, just for
+				 * word-wise expansion, not set for ^X^L */
+# define CONT_LOCAL	32	/* for ctrl_x_mode 0, ^X^P/^X^N do a local
+				 * expansion, (eg use complete=.) */
+#endif
+
+/*
+ * Functions for putting characters in the command line,
+ * while keeping ScreenLines[] updated.
+ */
+#ifdef FEAT_RIGHTLEFT
+EXTERN int	cmdmsg_rl INIT(= FALSE);    /* cmdline is drawn right to left */
+#endif
+EXTERN int	msg_col;
+EXTERN int	msg_row;
+EXTERN int	msg_scrolled;	/* Number of screen lines that windows have
+				 * scrolled because of printing messages. */
+EXTERN int	msg_scrolled_ign INIT(= FALSE);
+				/* when TRUE don't set need_wait_return in
+				   msg_puts_attr() when msg_scrolled is
+				   non-zero */
+
+EXTERN char_u	*keep_msg INIT(= NULL);	    /* msg to be shown after redraw */
+EXTERN int	keep_msg_attr INIT(= 0);    /* highlight attr for keep_msg */
+EXTERN int	keep_msg_more INIT(= FALSE); /* keep_msg was set by msgmore() */
+EXTERN int	need_fileinfo INIT(= FALSE);/* do fileinfo() after redraw */
+EXTERN int	msg_scroll INIT(= FALSE);   /* msg_start() will scroll */
+EXTERN int	msg_didout INIT(= FALSE);   /* msg_outstr() was used in line */
+EXTERN int	msg_didany INIT(= FALSE);   /* msg_outstr() was used at all */
+EXTERN int	msg_nowait INIT(= FALSE);   /* don't wait for this msg */
+EXTERN int	emsg_off INIT(= 0);	    /* don't display errors for now,
+					       unless 'debug' is set. */
+EXTERN int	info_message INIT(= FALSE); /* printing informative message */
+EXTERN int      msg_hist_off INIT(= FALSE); /* don't add messages to history */
+#ifdef FEAT_EVAL
+EXTERN int	emsg_skip INIT(= 0);	    /* don't display errors for
+					       expression that is skipped */
+EXTERN int	emsg_severe INIT(= FALSE);   /* use message of next of several
+					       emsg() calls for throw */
+EXTERN int	did_endif INIT(= FALSE);    /* just had ":endif" */
+#endif
+EXTERN int	did_emsg;		    /* set by emsg() when the message
+					       is displayed or thrown */
+EXTERN int	called_emsg;		    /* always set by emsg() */
+EXTERN int	ex_exitval INIT(= 0);	    /* exit value for ex mode */
+EXTERN int	emsg_on_display INIT(= FALSE);	/* there is an error message */
+EXTERN int	rc_did_emsg INIT(= FALSE);  /* vim_regcomp() called emsg() */
+
+EXTERN int	no_wait_return INIT(= 0);   /* don't wait for return for now */
+EXTERN int	need_wait_return INIT(= 0); /* need to wait for return later */
+EXTERN int	did_wait_return INIT(= FALSE);	/* wait_return() was used and
+						   nothing written since then */
+#ifdef FEAT_TITLE
+EXTERN int	need_maketitle INIT(= TRUE); /* call maketitle() soon */
+#endif
+
+EXTERN int	quit_more INIT(= FALSE);    /* 'q' hit at "--more--" msg */
+#if defined(UNIX) || defined(__EMX__) || defined(VMS) || defined(MACOS_X)
+EXTERN int	newline_on_exit INIT(= FALSE);	/* did msg in altern. screen */
+EXTERN int	intr_char INIT(= 0);	    /* extra interrupt character */
+#endif
+#if (defined(UNIX) || defined(VMS)) && defined(FEAT_X11)
+EXTERN int	x_no_connect INIT(= FALSE); /* don't connect to X server */
+# if defined(FEAT_CLIENTSERVER)
+EXTERN int	x_force_connect INIT(= FALSE); /* Do connect to X server.
+						  Overrules x_no_connect and
+						  "exclude" in 'clipboard'. */
+# endif
+#endif
+EXTERN int	ex_keep_indent INIT(= FALSE); /* getexmodeline(): keep indent */
+EXTERN int	vgetc_busy INIT(= 0);	    /* when inside vgetc() then > 0 */
+
+EXTERN int	didset_vim INIT(= FALSE);   /* did set $VIM ourselves */
+EXTERN int	didset_vimruntime INIT(= FALSE);   /* idem for $VIMRUNTIME */
+
+/*
+ * Lines left before a "more" message.	Ex mode needs to be able to reset this
+ * after you type something.
+ */
+EXTERN int	lines_left INIT(= -1);	    /* lines left for listing */
+EXTERN int	msg_no_more INIT(= FALSE);  /* don't use more prompt, truncate
+					       messages */
+
+EXTERN char_u	*sourcing_name INIT( = NULL);/* name of error message source */
+EXTERN linenr_T	sourcing_lnum INIT(= 0);    /* line number of the source file */
+
+#ifdef FEAT_EVAL
+EXTERN int	ex_nesting_level INIT(= 0);	/* nesting level */
+EXTERN int	debug_break_level INIT(= -1);	/* break below this level */
+EXTERN int	debug_did_msg INIT(= FALSE);	/* did "debug mode" message */
+EXTERN int	debug_tick INIT(= 0);		/* breakpoint change count */
+# ifdef FEAT_PROFILE
+EXTERN int	do_profiling INIT(= PROF_NONE);	/* PROF_ values */
+# endif
+
+/*
+ * The exception currently being thrown.  Used to pass an exception to
+ * a different cstack.  Also used for discarding an exception before it is
+ * caught or made pending.  Only valid when did_throw is TRUE.
+ */
+EXTERN except_T *current_exception;
+
+/*
+ * did_throw: An exception is being thrown.  Reset when the exception is caught
+ * or as long as it is pending in a finally clause.
+ */
+EXTERN int did_throw INIT(= FALSE);
+
+/*
+ * need_rethrow: set to TRUE when a throw that cannot be handled in do_cmdline()
+ * must be propagated to the cstack of the previously called do_cmdline().
+ */
+EXTERN int need_rethrow INIT(= FALSE);
+
+/*
+ * check_cstack: set to TRUE when a ":finish" or ":return" that cannot be
+ * handled in do_cmdline() must be propagated to the cstack of the previously
+ * called do_cmdline().
+ */
+EXTERN int check_cstack INIT(= FALSE);
+
+/*
+ * Number of nested try conditionals (across function calls and ":source"
+ * commands).
+ */
+EXTERN int trylevel INIT(= 0);
+
+/*
+ * When "force_abort" is TRUE, always skip commands after an error message,
+ * even after the outermost ":endif", ":endwhile" or ":endfor" or for a
+ * function without the "abort" flag.  It is set to TRUE when "trylevel" is
+ * non-zero (and ":silent!" was not used) or an exception is being thrown at
+ * the time an error is detected.  It is set to FALSE when "trylevel" gets
+ * zero again and there was no error or interrupt or throw.
+ */
+EXTERN int force_abort INIT(= FALSE);
+
+/*
+ * "msg_list" points to a variable in the stack of do_cmdline() which keeps
+ * the list of arguments of several emsg() calls, one of which is to be
+ * converted to an error exception immediately after the failing command
+ * returns.  The message to be used for the exception value is pointed to by
+ * the "throw_msg" field of the first element in the list.  It is usually the
+ * same as the "msg" field of that element, but can be identical to the "msg"
+ * field of a later list element, when the "emsg_severe" flag was set when the
+ * emsg() call was made.
+ */
+EXTERN struct msglist **msg_list INIT(= NULL);
+
+/*
+ * suppress_errthrow: When TRUE, don't convert an error to an exception.  Used
+ * when displaying the interrupt message or reporting an exception that is still
+ * uncaught at the top level (which has already been discarded then).  Also used
+ * for the error message when no exception can be thrown.
+ */
+EXTERN int suppress_errthrow INIT(= FALSE);
+
+/*
+ * The stack of all caught and not finished exceptions.  The exception on the
+ * top of the stack is the one got by evaluation of v:exception.  The complete
+ * stack of all caught and pending exceptions is embedded in the various
+ * cstacks; the pending exceptions, however, are not on the caught stack.
+ */
+EXTERN except_T *caught_stack INIT(= NULL);
+
+#endif
+
+#ifdef FEAT_EVAL
+/* Garbage collection can only take place when we are sure there are no Lists
+ * or Dictionaries being used internally.  This is flagged with
+ * "may_garbage_collect" when we are at the toplevel.
+ * "want_garbage_collect" is set by the garbagecollect() function, which means
+ * we do garbage collection before waiting for a char at the toplevel. */
+EXTERN int	may_garbage_collect INIT(= FALSE);
+EXTERN int	want_garbage_collect INIT(= FALSE);
+
+/* ID of script being sourced or was sourced to define the current function. */
+EXTERN scid_T	current_SID INIT(= 0);
+#endif
+
+#if defined(FEAT_EVAL) || defined(FEAT_SYN_HL)
+/* Magic number used for hashitem "hi_key" value indicating a deleted item.
+ * Only the address is used. */
+EXTERN char_u	hash_removed;
+#endif
+
+
+EXTERN int	scroll_region INIT(= FALSE); /* term supports scroll region */
+EXTERN int	t_colors INIT(= 0);	    /* int value of T_CCO */
+
+/*
+ * When highlight_match is TRUE, highlight a match, starting at the cursor
+ * position.  Search_match_lines is the number of lines after the match (0 for
+ * a match within one line), search_match_endcol the column number of the
+ * character just after the match in the last line.
+ */
+EXTERN int	highlight_match INIT(= FALSE);	/* show search match pos */
+EXTERN linenr_T	search_match_lines;		/* lines of of matched string */
+EXTERN colnr_T	search_match_endcol;		/* col nr of match end */
+
+EXTERN int	no_smartcase INIT(= FALSE);	/* don't use 'smartcase' once */
+
+EXTERN int	need_check_timestamps INIT(= FALSE); /* need to check file
+							timestamps asap */
+EXTERN int	did_check_timestamps INIT(= FALSE); /* did check timestamps
+						       recently */
+EXTERN int	no_check_timestamps INIT(= 0);	/* Don't check timestamps */
+
+EXTERN int	highlight_attr[HLF_COUNT];  /* Highl. attr for each context. */
+#ifdef FEAT_STL_OPT
+# define USER_HIGHLIGHT
+#endif
+#ifdef USER_HIGHLIGHT
+EXTERN int	highlight_user[9];		/* User[1-9] attributes */
+# ifdef FEAT_STL_OPT
+EXTERN int	highlight_stlnc[9];		/* On top of user */
+# endif
+#endif
+#ifdef FEAT_GUI
+EXTERN char_u	*use_gvimrc INIT(= NULL);	/* "-U" cmdline argument */
+#endif
+EXTERN int	cterm_normal_fg_color INIT(= 0);
+EXTERN int	cterm_normal_fg_bold INIT(= 0);
+EXTERN int	cterm_normal_bg_color INIT(= 0);
+
+#ifdef FEAT_AUTOCMD
+EXTERN int	autocmd_busy INIT(= FALSE);	/* Is apply_autocmds() busy? */
+EXTERN int	autocmd_no_enter INIT(= FALSE); /* *Enter autocmds disabled */
+EXTERN int	autocmd_no_leave INIT(= FALSE); /* *Leave autocmds disabled */
+EXTERN int	autocmd_block INIT(= 0);	/* block all autocmds */
+EXTERN int	modified_was_set;		/* did ":set modified" */
+EXTERN int	did_filetype INIT(= FALSE);	/* FileType event found */
+EXTERN int	keep_filetype INIT(= FALSE);	/* value for did_filetype when
+						   starting to execute
+						   autocommands */
+
+/* When deleting the current buffer, another one must be loaded.  If we know
+ * which one is preferred, au_new_curbuf is set to it */
+EXTERN buf_T	*au_new_curbuf INIT(= NULL);
+#endif
+
+#ifdef FEAT_MOUSE
+/*
+ * Mouse coordinates, set by check_termcode()
+ */
+EXTERN int	mouse_row;
+EXTERN int	mouse_col;
+EXTERN int	mouse_past_bottom INIT(= FALSE);/* mouse below last line */
+EXTERN int	mouse_past_eol INIT(= FALSE);	/* mouse right of line */
+EXTERN int	mouse_dragging INIT(= 0);	/* extending Visual area with
+						   mouse dragging */
+# if defined(FEAT_MOUSE_DEC)
+/*
+ * When the DEC mouse has been pressed but not yet released we enable
+ * automatic querys for the mouse position.
+ */
+EXTERN int	WantQueryMouse INIT(= FALSE);
+# endif
+
+# ifdef FEAT_GUI
+/* When the window layout is about to be changed, need_mouse_correct is set,
+ * so that gui_mouse_correct() is called afterwards, to correct the mouse
+ * pointer when focus-follow-mouse is being used. */
+EXTERN int	need_mouse_correct INIT(= FALSE);
+
+/* When double clicking, topline must be the same */
+EXTERN linenr_T gui_prev_topline INIT(= 0);
+#  ifdef FEAT_DIFF
+EXTERN int	gui_prev_topfill INIT(= 0);
+#  endif
+# endif
+
+# ifdef FEAT_MOUSESHAPE
+EXTERN int	drag_status_line INIT(= FALSE);	/* dragging the status line */
+EXTERN int	postponed_mouseshape INIT(= FALSE); /* postponed updating the
+						       mouse pointer shape */
+#  ifdef FEAT_VERTSPLIT
+EXTERN int	drag_sep_line INIT(= FALSE);	/* dragging vert separator */
+#  endif
+# endif
+
+#endif
+
+#ifdef FEAT_DIFF
+/* Value set from 'diffopt'. */
+EXTERN int	diff_context INIT(= 6);		/* context for folds */
+EXTERN int	diff_foldcolumn INIT(= 2);	/* 'foldcolumn' for diff mode */
+EXTERN int	diff_need_scrollbind INIT(= FALSE);
+#endif
+
+#ifdef FEAT_MENU
+/* The root of the menu hierarchy. */
+EXTERN vimmenu_T	*root_menu INIT(= NULL);
+/*
+ * While defining the system menu, sys_menu is TRUE.  This avoids
+ * overruling of menus that the user already defined.
+ */
+EXTERN int	sys_menu INIT(= FALSE);
+#endif
+
+/* While redrawing the screen this flag is set.  It means the screen size
+ * ('lines' and 'rows') must not be changed. */
+EXTERN int	updating_screen INIT(= FALSE);
+
+#ifdef FEAT_GUI
+# ifdef FEAT_MENU
+/* Menu item just selected, set by check_termcode() */
+EXTERN vimmenu_T	*current_menu;
+
+/* Set to TRUE after adding/removing menus to ensure they are updated */
+EXTERN int force_menu_update INIT(= FALSE);
+# endif
+# ifdef FEAT_GUI_TABLINE
+/* Tab in tab pages line just selected, set by check_termcode() */
+EXTERN int	    current_tab;
+
+/* Menu entry in tab pages line menu just selected, set by check_termcode() */
+EXTERN int	    current_tabmenu;
+#  define TABLINE_MENU_CLOSE	1
+#  define TABLINE_MENU_NEW	2
+#  define TABLINE_MENU_OPEN	3
+# endif
+
+/* Scrollbar moved and new value, set by check_termcode() */
+EXTERN int	current_scrollbar;
+EXTERN long_u	scrollbar_value;
+
+/* found "-rv" or "-reverse" in command line args */
+EXTERN int	found_reverse_arg INIT(= FALSE);
+
+/* "-fn" or "-font" command line argument */
+EXTERN char	*font_argument INIT(= NULL);
+
+# ifdef FEAT_GUI_GTK
+/* "-bg" or "-background" command line argument */
+EXTERN char	*background_argument INIT(= NULL);
+
+/* "-fg" or "-foreground" command line argument */
+EXTERN char	*foreground_argument INIT(= NULL);
+# endif
+
+/*
+ * While executing external commands or in Ex mode, should not insert GUI
+ * events in the input buffer: Set hold_gui_events to non-zero.
+ */
+EXTERN int	hold_gui_events INIT(= 0);
+
+/*
+ * When resizing the shell is postponed, remember the new size, and call
+ * gui_resize_shell() later.
+ */
+EXTERN int	new_pixel_width INIT(= 0);
+EXTERN int	new_pixel_height INIT(= 0);
+
+/* Window position from ":winpos", to be used when opening the GUI window. */
+EXTERN int	gui_win_x INIT(= -1);
+EXTERN int	gui_win_y INIT(= -1);
+#endif
+
+#ifdef FEAT_CLIPBOARD
+EXTERN VimClipboard clip_star;	/* PRIMARY selection in X11 */
+# ifdef FEAT_X11
+EXTERN VimClipboard clip_plus;	/* CLIPBOARD selection in X11 */
+# else
+#  define clip_plus clip_star	/* there is only one clipboard */
+# endif
+EXTERN int	clip_unnamed INIT(= FALSE);
+EXTERN int	clip_autoselect INIT(= FALSE);
+EXTERN int	clip_autoselectml INIT(= FALSE);
+EXTERN regprog_T *clip_exclude_prog INIT(= NULL);
+#endif
+
+/*
+ * All windows are linked in a list. firstwin points to the first entry,
+ * lastwin to the last entry (can be the same as firstwin) and curwin to the
+ * currently active window.
+ * Without the FEAT_WINDOWS they are all equal.
+ */
+#ifdef FEAT_WINDOWS
+EXTERN win_T	*firstwin;		/* first window */
+EXTERN win_T	*lastwin;		/* last window */
+EXTERN win_T	*prevwin INIT(= NULL);	/* previous window */
+# define W_NEXT(wp) ((wp)->w_next)
+# define FOR_ALL_WINDOWS(wp) for (wp = firstwin; wp != NULL; wp = wp->w_next)
+#define FOR_ALL_TAB_WINDOWS(tp, wp) \
+    for ((tp) = first_tabpage; (tp) != NULL; (tp) = (tp)->tp_next) \
+	for ((wp) = ((tp) == curtab) \
+		? firstwin : (tp)->tp_firstwin; (wp); (wp) = (wp)->w_next)
+#else
+# define firstwin curwin
+# define lastwin curwin
+# define W_NEXT(wp) NULL
+# define FOR_ALL_WINDOWS(wp) wp = curwin;
+# define FOR_ALL_TAB_WINDOWS(tp, wp) wp = curwin;
+#endif
+
+EXTERN win_T	*curwin;	/* currently active window */
+
+/*
+ * The window layout is kept in a tree of frames.  topframe points to the top
+ * of the tree.
+ */
+EXTERN frame_T	*topframe;	/* top of the window frame tree */
+
+#ifdef FEAT_WINDOWS
+/*
+ * Tab pages are alternative topframes.  "first_tabpage" points to the first
+ * one in the list, "curtab" is the current one.
+ */
+EXTERN tabpage_T    *first_tabpage;
+EXTERN tabpage_T    *curtab;
+EXTERN int	    redraw_tabline INIT(= FALSE);  /* need to redraw tabline */
+#endif
+
+/*
+ * All buffers are linked in a list. 'firstbuf' points to the first entry,
+ * 'lastbuf' to the last entry and 'curbuf' to the currently active buffer.
+ */
+EXTERN buf_T	*firstbuf INIT(= NULL);	/* first buffer */
+EXTERN buf_T	*lastbuf INIT(= NULL);	/* last buffer */
+EXTERN buf_T	*curbuf INIT(= NULL);	/* currently active buffer */
+
+/* Flag that is set when switching off 'swapfile'.  It means that all blocks
+ * are to be loaded into memory.  Shouldn't be global... */
+EXTERN int	mf_dont_release INIT(= FALSE);	/* don't release blocks */
+
+/*
+ * List of files being edited (global argument list).  curwin->w_alist points
+ * to this when the window is using the global argument list.
+ */
+EXTERN alist_T	global_alist;	/* global argument list */
+EXTERN int	arg_had_last INIT(= FALSE); /* accessed last file in
+					       global_alist */
+
+EXTERN int	ru_col;		/* column for ruler */
+#ifdef FEAT_STL_OPT
+EXTERN int	ru_wid;		/* 'rulerfmt' width of ruler when non-zero */
+#endif
+EXTERN int	sc_col;		/* column for shown command */
+
+#ifdef TEMPDIRNAMES
+EXTERN char_u	*vim_tempdir INIT(= NULL); /* Name of Vim's own temp dir.
+					      Ends in a slash. */
+#endif
+
+/*
+ * When starting or exiting some things are done differently (e.g. screen
+ * updating).
+ */
+EXTERN int	starting INIT(= NO_SCREEN);
+				/* first NO_SCREEN, then NO_BUFFERS and then
+				 * set to 0 when starting up finished */
+EXTERN int	exiting INIT(= FALSE);
+				/* TRUE when planning to exit Vim.  Might
+				 * still keep on running if there is a changed
+				 * buffer. */
+EXTERN int	really_exiting INIT(= FALSE);
+				/* TRUE when we are sure to exit, e.g., after
+				 * a deadly signal */
+EXTERN int	full_screen INIT(= FALSE);
+				/* TRUE when doing full-screen output
+				 * otherwise only writing some messages */
+
+EXTERN int	restricted INIT(= FALSE);
+				/* TRUE when started as "rvim" */
+EXTERN int	secure INIT(= FALSE);
+				/* non-zero when only "safe" commands are
+				 * allowed, e.g. when sourcing .exrc or .vimrc
+				 * in current directory */
+
+EXTERN int	textlock INIT(= 0);
+				/* non-zero when changing text and jumping to
+				 * another window or buffer is not allowed */
+
+#ifdef FEAT_AUTOCMD
+EXTERN int	curbuf_lock INIT(= 0);
+				/* non-zero when the current buffer can't be
+				 * changed.  Used for FileChangedRO. */
+#endif
+#ifdef FEAT_EVAL
+# define HAVE_SANDBOX
+EXTERN int	sandbox INIT(= 0);
+				/* Non-zero when evaluating an expression in a
+				 * "sandbox".  Several things are not allowed
+				 * then. */
+#endif
+
+EXTERN int	silent_mode INIT(= FALSE);
+				/* set to TRUE when "-s" commandline argument
+				 * used for ex */
+
+#ifdef FEAT_VISUAL
+EXTERN pos_T	VIsual;		/* start position of active Visual selection */
+EXTERN int	VIsual_active INIT(= FALSE);
+				/* whether Visual mode is active */
+EXTERN int	VIsual_select INIT(= FALSE);
+				/* whether Select mode is active */
+EXTERN int	VIsual_reselect;
+				/* whether to restart the selection after a
+				 * Select mode mapping or menu */
+
+EXTERN int	VIsual_mode INIT(= 'v');
+				/* type of Visual mode */
+
+EXTERN int	redo_VIsual_busy INIT(= FALSE);
+				/* TRUE when redoing Visual */
+#endif
+
+#ifdef FEAT_MOUSE
+/*
+ * When pasting text with the middle mouse button in visual mode with
+ * restart_edit set, remember where it started so we can set Insstart.
+ */
+EXTERN pos_T	where_paste_started;
+#endif
+
+/*
+ * This flag is used to make auto-indent work right on lines where only a
+ * <RETURN> or <ESC> is typed. It is set when an auto-indent is done, and
+ * reset when any other editing is done on the line. If an <ESC> or <RETURN>
+ * is received, and did_ai is TRUE, the line is truncated.
+ */
+EXTERN int     did_ai INIT(= FALSE);
+
+/*
+ * Column of first char after autoindent.  0 when no autoindent done.  Used
+ * when 'backspace' is 0, to avoid backspacing over autoindent.
+ */
+EXTERN colnr_T	ai_col INIT(= 0);
+
+#ifdef FEAT_COMMENTS
+/*
+ * This is a character which will end a start-middle-end comment when typed as
+ * the first character on a new line.  It is taken from the last character of
+ * the "end" comment leader when the COM_AUTO_END flag is given for that
+ * comment end in 'comments'.  It is only valid when did_ai is TRUE.
+ */
+EXTERN int     end_comment_pending INIT(= NUL);
+#endif
+
+#ifdef FEAT_SCROLLBIND
+/*
+ * This flag is set after a ":syncbind" to let the check_scrollbind() function
+ * know that it should not attempt to perform scrollbinding due to the scroll
+ * that was a result of the ":syncbind." (Otherwise, check_scrollbind() will
+ * undo some of the work done by ":syncbind.")  -ralston
+ */
+EXTERN int     did_syncbind INIT(= FALSE);
+#endif
+
+#ifdef FEAT_SMARTINDENT
+/*
+ * This flag is set when a smart indent has been performed. When the next typed
+ * character is a '{' the inserted tab will be deleted again.
+ */
+EXTERN int	did_si INIT(= FALSE);
+
+/*
+ * This flag is set after an auto indent. If the next typed character is a '}'
+ * one indent will be removed.
+ */
+EXTERN int	can_si INIT(= FALSE);
+
+/*
+ * This flag is set after an "O" command. If the next typed character is a '{'
+ * one indent will be removed.
+ */
+EXTERN int	can_si_back INIT(= FALSE);
+#endif
+
+EXTERN pos_T	saved_cursor		/* w_cursor before formatting text. */
+# ifdef DO_INIT
+	= INIT_POS_T
+# endif
+	;
+
+/*
+ * Stuff for insert mode.
+ */
+EXTERN pos_T	Insstart;		/* This is where the latest
+					 * insert/append mode started. */
+#ifdef FEAT_VREPLACE
+/*
+ * Stuff for VREPLACE mode.
+ */
+EXTERN int	orig_line_count INIT(= 0);  /* Line count when "gR" started */
+EXTERN int	vr_lines_changed INIT(= 0); /* #Lines changed by "gR" so far */
+#endif
+
+#if defined(FEAT_X11) && defined(FEAT_XCLIPBOARD)
+/* argument to SETJMP() for handling X IO errors */
+EXTERN JMP_BUF x_jump_env;
+#endif
+
+#if defined(HAVE_SETJMP_H)
+/*
+ * Stuff for setjmp() and longjmp().
+ * Used to protect areas where we could crash.
+ */
+EXTERN JMP_BUF lc_jump_env;	/* argument to SETJMP() */
+# ifdef SIGHASARG
+EXTERN int lc_signal;		/* catched signal number, 0 when no was signal
+				   catched; used for mch_libcall() */
+# endif
+EXTERN int lc_active INIT(= FALSE); /* TRUE when lc_jump_env is valid. */
+#endif
+
+#if defined(FEAT_MBYTE) || defined(FEAT_POSTSCRIPT)
+/*
+ * These flags are set based upon 'fileencoding'.
+ * Note that "enc_utf8" is also set for "unicode", because the characters are
+ * internally stored as UTF-8 (to avoid trouble with NUL bytes).
+ */
+# define DBCS_JPN	932	/* japan */
+# define DBCS_JPNU	9932	/* euc-jp */
+# define DBCS_KOR	949	/* korea */
+# define DBCS_KORU	9949	/* euc-kr */
+# define DBCS_CHS	936	/* chinese */
+# define DBCS_CHSU	9936	/* euc-cn */
+# define DBCS_CHT	950	/* taiwan */
+# define DBCS_CHTU	9950	/* euc-tw */
+# define DBCS_2BYTE	1	/* 2byte- */
+# define DBCS_DEBUG	-1
+#endif
+
+#ifdef FEAT_MBYTE
+EXTERN int	enc_dbcs INIT(= 0);		/* One of DBCS_xxx values if
+						   DBCS encoding */
+EXTERN int	enc_unicode INIT(= 0);	/* 2: UCS-2 or UTF-16, 4: UCS-4 */
+EXTERN int	enc_utf8 INIT(= FALSE);		/* UTF-8 encoded Unicode */
+EXTERN int	enc_latin1like INIT(= TRUE);	/* 'encoding' is latin1 comp. */
+# ifdef WIN3264
+/* Codepage nr of 'encoding'.  Negative means it's not been set yet, zero
+ * means 'encoding' is not a valid codepage. */
+EXTERN int	enc_codepage INIT(= -1);
+EXTERN int	enc_latin9 INIT(= FALSE);	/* 'encoding' is latin9 */
+# endif
+EXTERN int	has_mbyte INIT(= 0);		/* any multi-byte encoding */
+
+#if defined(WIN3264) && defined(FEAT_MBYTE)
+EXTERN int	wide_WindowProc INIT(= FALSE);	/* use wide WindowProc() */
+#endif
+
+/*
+ * To speed up BYTELEN() we fill a table with the byte lengths whenever
+ * enc_utf8 or enc_dbcs changes.
+ */
+EXTERN char	mb_bytelen_tab[256];
+
+/* Variables that tell what conversion is used for keyboard input and display
+ * output. */
+EXTERN vimconv_T input_conv;			/* type of input conversion */
+EXTERN vimconv_T output_conv;			/* type of output conversion */
+
+/*
+ * Function pointers, used to quickly get to the right function.  Each has
+ * three possible values: latin_ (8-bit), utfc_ or utf_ (utf-8) and dbcs_
+ * (DBCS).
+ * The value is set in mb_init();
+ */
+/* length of char in bytes, including following composing chars */
+EXTERN int (*mb_ptr2len) __ARGS((char_u *p)) INIT(= latin_ptr2len);
+/* byte length of char */
+EXTERN int (*mb_char2len) __ARGS((int c)) INIT(= latin_char2len);
+/* convert char to bytes, return the length */
+EXTERN int (*mb_char2bytes) __ARGS((int c, char_u *buf)) INIT(= latin_char2bytes);
+EXTERN int (*mb_ptr2cells) __ARGS((char_u *p)) INIT(= latin_ptr2cells);
+EXTERN int (*mb_char2cells) __ARGS((int c)) INIT(= latin_char2cells);
+EXTERN int (*mb_off2cells) __ARGS((unsigned off)) INIT(= latin_off2cells);
+EXTERN int (*mb_ptr2char) __ARGS((char_u *p)) INIT(= latin_ptr2char);
+EXTERN int (*mb_head_off) __ARGS((char_u *base, char_u *p)) INIT(= latin_head_off);
+
+# if defined(USE_ICONV) && defined(DYNAMIC_ICONV)
+/* Pointers to functions and variables to be loaded at runtime */
+EXTERN size_t (*iconv) (iconv_t cd, const char **inbuf, size_t *inbytesleft, char **outbuf, size_t *outbytesleft);
+EXTERN iconv_t (*iconv_open) (const char *tocode, const char *fromcode);
+EXTERN int (*iconv_close) (iconv_t cd);
+EXTERN int (*iconvctl) (iconv_t cd, int request, void *argument);
+EXTERN int* (*iconv_errno) (void);
+# endif
+
+#endif /* FEAT_MBYTE */
+
+#ifdef FEAT_XIM
+# ifdef FEAT_GUI_GTK
+#  ifdef HAVE_GTK2
+EXTERN GtkIMContext	*xic INIT(= NULL);
+#  else
+EXTERN GdkICAttr	*xic_attr INIT(= NULL);
+EXTERN GdkIC		*xic INIT(= NULL);
+EXTERN char		*draw_feedback INIT(= NULL);
+#  endif
+/*
+ * Start and end column of the preedit area in virtual columns from the start
+ * of the text line.  When there is no preedit area they are set to MAXCOL.
+ * "preedit_end_col" is needed for coloring the preedited string.  Drawing the
+ * color between "preedit_start_col" and curpos did not work, because some XIM
+ * set the cursor position to the first char of the string.
+ */
+EXTERN colnr_T		preedit_start_col INIT(= MAXCOL);
+EXTERN colnr_T		preedit_end_col INIT(= MAXCOL);
+
+/* "xim_changed_while_preediting" is set when changed() can set the 'modified'
+ * flag even while preediting. */
+EXTERN int		xim_changed_while_preediting INIT(= FALSE);
+# else
+EXTERN XIC		xic INIT(= NULL);
+# endif
+# ifdef FEAT_GUI
+EXTERN guicolor_T	xim_fg_color INIT(= INVALCOLOR);
+EXTERN guicolor_T	xim_bg_color INIT(= INVALCOLOR);
+# endif
+#endif
+
+#ifdef FEAT_HANGULIN
+EXTERN int		composing_hangul INIT(= 0);
+EXTERN char_u		composing_hangul_buffer[5];
+#endif
+
+/*
+ * "State" is the main state of Vim.
+ * There are other variables that modify the state:
+ * "Visual_mode"    When State is NORMAL or INSERT.
+ * "finish_op"	    When State is NORMAL, after typing the operator and before
+ *		    typing the motion command.
+ */
+EXTERN int	State INIT(= NORMAL);	/* This is the current state of the
+					 * command interpreter. */
+
+EXTERN int	finish_op INIT(= FALSE);/* TRUE while an operator is pending */
+
+/*
+ * ex mode (Q) state
+ */
+EXTERN int exmode_active INIT(= 0);	/* zero, EXMODE_NORMAL or EXMODE_VIM */
+EXTERN int ex_no_reprint INIT(= FALSE); /* no need to print after z or p */
+
+EXTERN int Recording INIT(= FALSE);	/* TRUE when recording into a reg. */
+EXTERN int Exec_reg INIT(= FALSE);	/* TRUE when executing a register */
+
+EXTERN int no_mapping INIT(= FALSE);	/* currently no mapping allowed */
+EXTERN int no_zero_mapping INIT(= 0);	/* mapping zero not allowed */
+EXTERN int allow_keys INIT(= FALSE);	/* allow key codes when no_mapping
+					     * is set */
+EXTERN int no_u_sync INIT(= 0);		/* Don't call u_sync() */
+
+EXTERN int restart_edit INIT(= 0);	/* call edit when next cmd finished */
+EXTERN int arrow_used;			/* Normally FALSE, set to TRUE after
+					 * hitting cursor key in insert mode.
+					 * Used by vgetorpeek() to decide when
+					 * to call u_sync() */
+EXTERN int	ins_at_eol INIT(= FALSE); /* put cursor after eol when
+					   restarting edit after CTRL-O */
+#ifdef FEAT_INS_EXPAND
+EXTERN char_u	*edit_submode INIT(= NULL); /* msg for CTRL-X submode */
+EXTERN char_u	*edit_submode_pre INIT(= NULL); /* prepended to edit_submode */
+EXTERN char_u	*edit_submode_extra INIT(= NULL);/* appended to edit_submode */
+EXTERN hlf_T	edit_submode_highl;	/* highl. method for extra info */
+EXTERN int	ctrl_x_mode INIT(= 0);	/* Which Ctrl-X mode are we in? */
+#endif
+
+EXTERN int	no_abbr INIT(= TRUE);	/* TRUE when no abbreviations loaded */
+#ifdef MSDOS
+EXTERN int	beep_count INIT(= 0);	/* nr of beeps since last char typed */
+#endif
+
+#ifdef USE_EXE_NAME
+EXTERN char_u	*exe_name;		/* the name of the executable */
+#endif
+
+#ifdef USE_ON_FLY_SCROLL
+EXTERN int	dont_scroll INIT(= FALSE);/* don't use scrollbars when TRUE */
+#endif
+EXTERN int	mapped_ctrl_c INIT(= FALSE); /* CTRL-C is mapped */
+EXTERN int	ctrl_c_interrupts INIT(= TRUE);	/* CTRL-C sets got_int */
+
+EXTERN cmdmod_T	cmdmod;			/* Ex command modifiers */
+
+EXTERN int	msg_silent INIT(= 0);	/* don't print messages */
+EXTERN int	emsg_silent INIT(= 0);	/* don't print error messages */
+EXTERN int	cmd_silent INIT(= FALSE); /* don't echo the command line */
+
+#if defined(FEAT_GUI_DIALOG) || defined(FEAT_CON_DIALOG) \
+	|| defined(FEAT_AUTOCMD)
+# define HAS_SWAP_EXISTS_ACTION
+EXTERN int	swap_exists_action INIT(= SEA_NONE);
+					/* For dialog when swap file already
+					 * exists. */
+EXTERN int	swap_exists_did_quit INIT(= FALSE);
+					/* Selected "quit" at the dialog. */
+#endif
+
+EXTERN char_u	*IObuff;		/* sprintf's are done in this buffer,
+					   size is IOSIZE */
+EXTERN char_u	*NameBuff;		/* file names are expanded in this
+					 * buffer, size is MAXPATHL */
+EXTERN char_u	msg_buf[MSG_BUF_LEN];	/* small buffer for messages */
+
+/* When non-zero, postpone redrawing. */
+EXTERN int	RedrawingDisabled INIT(= 0);
+
+EXTERN int	readonlymode INIT(= FALSE); /* Set to TRUE for "view" */
+EXTERN int	recoverymode INIT(= FALSE); /* Set to TRUE for "-r" option */
+
+EXTERN struct buffheader stuffbuff	/* stuff buffer */
+#ifdef DO_INIT
+		    = {{NULL, {NUL}}, NULL, 0, 0}
+#endif
+		    ;
+EXTERN typebuf_T typebuf		/* typeahead buffer */
+#ifdef DO_INIT
+		    = {NULL, NULL}
+#endif
+		    ;
+#ifdef FEAT_EX_EXTRA
+EXTERN int	ex_normal_busy INIT(= 0); /* recursiveness of ex_normal() */
+EXTERN int	ex_normal_lock INIT(= 0); /* forbid use of ex_normal() */
+#endif
+EXTERN int	stop_insert_mode;	/* for ":stopinsert" and 'insertmode' */
+
+EXTERN int	KeyTyped;		/* TRUE if user typed current char */
+EXTERN int	KeyStuffed;		/* TRUE if current char from stuffbuf */
+#ifdef USE_IM_CONTROL
+EXTERN int	vgetc_im_active;	/* Input Method was active for last
+					   character obtained from vgetc() */
+#endif
+EXTERN int	maptick INIT(= 0);	/* tick for each non-mapped char */
+
+EXTERN char_u	chartab[256];		/* table used in charset.c; See
+					   init_chartab() for explanation */
+
+EXTERN int	must_redraw INIT(= 0);	    /* type of redraw necessary */
+EXTERN int	skip_redraw INIT(= FALSE);  /* skip redraw once */
+EXTERN int	do_redraw INIT(= FALSE);    /* extra redraw once */
+
+EXTERN int	need_highlight_changed INIT(= TRUE);
+EXTERN char_u	*use_viminfo INIT(= NULL);  /* name of viminfo file to use */
+
+#define NSCRIPT 15
+EXTERN FILE	*scriptin[NSCRIPT];	    /* streams to read script from */
+EXTERN int	curscript INIT(= 0);	    /* index in scriptin[] */
+EXTERN FILE	*scriptout  INIT(= NULL);   /* stream to write script to */
+EXTERN int	read_cmd_fd INIT(= 0);	    /* fd to read commands from */
+
+EXTERN int	got_int INIT(= FALSE);	    /* set to TRUE when interrupt
+						signal occurred */
+#ifdef USE_TERM_CONSOLE
+EXTERN int	term_console INIT(= FALSE); /* set to TRUE when console used */
+#endif
+EXTERN int	termcap_active INIT(= FALSE);	/* set by starttermcap() */
+EXTERN int	cur_tmode INIT(= TMODE_COOK);	/* input terminal mode */
+EXTERN int	bangredo INIT(= FALSE);	    /* set to TRUE with ! command */
+EXTERN int	searchcmdlen;		    /* length of previous search cmd */
+#ifdef FEAT_SYN_HL
+EXTERN int	reg_do_extmatch INIT(= 0);  /* Used when compiling regexp:
+					     * REX_SET to allow \z\(...\),
+					     * REX_USE to allow \z\1 et al. */
+EXTERN reg_extmatch_T *re_extmatch_in INIT(= NULL); /* Used by vim_regexec():
+					     * strings for \z\1...\z\9 */
+EXTERN reg_extmatch_T *re_extmatch_out INIT(= NULL); /* Set by vim_regexec()
+					     * to store \z\(...\) matches */
+#endif
+
+EXTERN int	did_outofmem_msg INIT(= FALSE);
+					    /* set after out of memory msg */
+EXTERN int	did_swapwrite_msg INIT(= FALSE);
+					    /* set after swap write error msg */
+EXTERN int	undo_off INIT(= FALSE);	    /* undo switched off for now */
+EXTERN int	global_busy INIT(= 0);	    /* set when :global is executing */
+EXTERN int	listcmd_busy INIT(= FALSE); /* set when :argdo, :windo or
+					       :bufdo is executing */
+EXTERN int	need_start_insertmode INIT(= FALSE);
+					    /* start insert mode soon */
+EXTERN char_u	*last_cmdline INIT(= NULL); /* last command line (for ":) */
+EXTERN char_u	*repeat_cmdline INIT(= NULL); /* command line for "." */
+#ifdef FEAT_CMDHIST
+EXTERN char_u	*new_last_cmdline INIT(= NULL);	/* new value for last_cmdline */
+#endif
+#ifdef FEAT_AUTOCMD
+EXTERN char_u	*autocmd_fname INIT(= NULL); /* fname for <afile> on cmdline */
+EXTERN int	autocmd_bufnr INIT(= 0);     /* fnum for <abuf> on cmdline */
+EXTERN char_u	*autocmd_match INIT(= NULL); /* name for <amatch> on cmdline */
+EXTERN int	did_cursorhold INIT(= FALSE); /* set when CursorHold t'gerd */
+EXTERN pos_T	last_cursormoved	    /* for CursorMoved event */
+# ifdef DO_INIT
+			= INIT_POS_T
+# endif
+			;
+#endif
+
+EXTERN linenr_T	write_no_eol_lnum INIT(= 0); /* non-zero lnum when last line
+						of next binary write should
+						not have an end-of-line */
+
+#ifdef FEAT_WINDOWS
+EXTERN int	postponed_split INIT(= 0);  /* for CTRL-W CTRL-] command */
+EXTERN int	postponed_split_flags INIT(= 0);  /* args for win_split() */
+EXTERN int	postponed_split_tab INIT(= 0);  /* cmdmod.tab */
+# ifdef FEAT_QUICKFIX
+EXTERN int	g_do_tagpreview INIT(= 0);  /* for tag preview commands:
+					       height of preview window */
+# endif
+#endif
+EXTERN int	replace_offset INIT(= 0);   /* offset for replace_push() */
+
+EXTERN char_u	*escape_chars INIT(= (char_u *)" \t\\\"|");
+					    /* need backslash in cmd line */
+
+EXTERN int	keep_help_flag INIT(= FALSE); /* doing :ta from help file */
+
+/*
+ * When a string option is NULL (which only happens in out-of-memory
+ * situations), it is set to empty_option, to avoid having to check for NULL
+ * everywhere.
+ */
+EXTERN char_u	*empty_option INIT(= (char_u *)"");
+
+EXTERN int  redir_off INIT(= FALSE);	/* no redirection for a moment */
+EXTERN FILE *redir_fd INIT(= NULL);	/* message redirection file */
+#ifdef FEAT_EVAL
+EXTERN int  redir_reg INIT(= 0);	/* message redirection register */
+EXTERN int  redir_vname INIT(= 0);	/* message redirection variable */
+#endif
+
+#ifdef FEAT_LANGMAP
+EXTERN char_u	langmap_mapchar[256];	/* mapping for language keys */
+#endif
+
+#ifdef FEAT_WILDMENU
+EXTERN int  save_p_ls INIT(= -1);	/* Save 'laststatus' setting */
+EXTERN int  save_p_wmh INIT(= -1);	/* Save 'winminheight' setting */
+EXTERN int  wild_menu_showing INIT(= 0);
+#define WM_SHOWN	1		/* wildmenu showing */
+#define WM_SCROLLED	2		/* wildmenu showing with scroll */
+#endif
+
+#ifdef MSWIN
+EXTERN char_u	toupper_tab[256];	/* table for toupper() */
+EXTERN char_u	tolower_tab[256];	/* table for tolower() */
+#endif
+
+#ifdef FEAT_LINEBREAK
+EXTERN char	breakat_flags[256];	/* which characters are in 'breakat' */
+#endif
+
+/* these are in version.c */
+extern char *Version;
+#if defined(HAVE_DATE_TIME) && defined(VMS) && defined(VAXC)
+extern char longVersion[];
+#else
+extern char *longVersion;
+#endif
+
+/*
+ * Some file names are stored in pathdef.c, which is generated from the
+ * Makefile to make their value depend on the Makefile.
+ */
+#ifdef HAVE_PATHDEF
+extern char_u *default_vim_dir;
+extern char_u *default_vimruntime_dir;
+extern char_u *all_cflags;
+extern char_u *all_lflags;
+# ifdef VMS
+extern char_u *compiler_version;
+extern char_u *compiled_arch;
+# endif
+extern char_u *compiled_user;
+extern char_u *compiled_sys;
+#endif
+
+/* When a window has a local directory, the absolute path of the global
+ * current directory is stored here (in allocated memory).  If the current
+ * directory is not a local directory, globaldir is NULL. */
+EXTERN char_u	*globaldir INIT(= NULL);
+
+/* Characters from 'listchars' option */
+EXTERN int	lcs_eol INIT(= '$');
+EXTERN int	lcs_ext INIT(= NUL);
+EXTERN int	lcs_prec INIT(= NUL);
+EXTERN int	lcs_nbsp INIT(= NUL);
+EXTERN int	lcs_tab1 INIT(= NUL);
+EXTERN int	lcs_tab2 INIT(= NUL);
+EXTERN int	lcs_trail INIT(= NUL);
+
+#if defined(FEAT_WINDOWS) || defined(FEAT_WILDMENU) || defined(FEAT_STL_OPT) \
+	|| defined(FEAT_FOLDING)
+/* Characters from 'fillchars' option */
+EXTERN int	fill_stl INIT(= ' ');
+EXTERN int	fill_stlnc INIT(= ' ');
+#endif
+#if defined(FEAT_WINDOWS) || defined(FEAT_FOLDING)
+EXTERN int	fill_vert INIT(= ' ');
+EXTERN int	fill_fold INIT(= '-');
+EXTERN int	fill_diff INIT(= '-');
+#endif
+
+#ifdef FEAT_VISUAL
+/* Whether 'keymodel' contains "stopsel" and "startsel". */
+EXTERN int	km_stopsel INIT(= FALSE);
+EXTERN int	km_startsel INIT(= FALSE);
+#endif
+
+#ifdef FEAT_CMDWIN
+EXTERN int	cedit_key INIT(= -1);	/* key value of 'cedit' option */
+EXTERN int	cmdwin_type INIT(= 0);	/* type of cmdline window or 0 */
+EXTERN int	cmdwin_result INIT(= 0); /* result of cmdline window or 0 */
+#endif
+
+EXTERN char_u no_lines_msg[]	INIT(= N_("--No lines in buffer--"));
+
+/*
+ * When ":global" is used to number of substitutions and changed lines is
+ * accumulated until it's finished.
+ * Also used for ":spellrepall".
+ */
+EXTERN long	sub_nsubs;	/* total number of substitutions */
+EXTERN linenr_T	sub_nlines;	/* total number of lines changed */
+
+/* table to store parsed 'wildmode' */
+EXTERN char_u	wim_flags[4];
+
+#if defined(FEAT_TITLE) && defined(FEAT_STL_OPT)
+/* whether titlestring and iconstring contains statusline syntax */
+# define STL_IN_ICON	1
+# define STL_IN_TITLE	2
+EXTERN int      stl_syntax INIT(= 0);
+#endif
+
+#ifdef FEAT_SEARCH_EXTRA
+/* don't use 'hlsearch' temporarily */
+EXTERN int	no_hlsearch INIT(= FALSE);
+#endif
+
+#ifdef FEAT_BEVAL
+EXTERN BalloonEval	*balloonEval INIT(= NULL);
+# if defined(FEAT_NETBEANS_INTG) || defined(FEAT_SUN_WORKSHOP)
+EXTERN int bevalServers INIT(= 0);
+#  define BEVAL_NETBEANS		0x01
+#  define BEVAL_WORKSHOP		0x02
+# endif
+#endif
+
+#ifdef CURSOR_SHAPE
+/* the table is in misc2.c, because of initializations */
+extern cursorentry_T shape_table[SHAPE_IDX_COUNT];
+#endif
+
+#ifdef FEAT_PRINTER
+/*
+ * Printer stuff shared between hardcopy.c and machine-specific printing code.
+ */
+# define OPT_PRINT_TOP		0
+# define OPT_PRINT_BOT		1
+# define OPT_PRINT_LEFT		2
+# define OPT_PRINT_RIGHT	3
+# define OPT_PRINT_HEADERHEIGHT	4
+# define OPT_PRINT_SYNTAX	5
+# define OPT_PRINT_NUMBER	6
+# define OPT_PRINT_WRAP		7
+# define OPT_PRINT_DUPLEX	8
+# define OPT_PRINT_PORTRAIT	9
+# define OPT_PRINT_PAPER	10
+# define OPT_PRINT_COLLATE	11
+# define OPT_PRINT_JOBSPLIT	12
+# define OPT_PRINT_FORMFEED	13
+
+# define OPT_PRINT_NUM_OPTIONS	14
+
+EXTERN option_table_T printer_opts[OPT_PRINT_NUM_OPTIONS]
+# ifdef DO_INIT
+ =
+{
+    {"top",	TRUE, 0, NULL, 0, FALSE},
+    {"bottom",	TRUE, 0, NULL, 0, FALSE},
+    {"left",	TRUE, 0, NULL, 0, FALSE},
+    {"right",	TRUE, 0, NULL, 0, FALSE},
+    {"header",	TRUE, 0, NULL, 0, FALSE},
+    {"syntax",	FALSE, 0, NULL, 0, FALSE},
+    {"number",	FALSE, 0, NULL, 0, FALSE},
+    {"wrap",	FALSE, 0, NULL, 0, FALSE},
+    {"duplex",	FALSE, 0, NULL, 0, FALSE},
+    {"portrait", FALSE, 0, NULL, 0, FALSE},
+    {"paper",	FALSE, 0, NULL, 0, FALSE},
+    {"collate",	FALSE, 0, NULL, 0, FALSE},
+    {"jobsplit", FALSE, 0, NULL, 0, FALSE},
+    {"formfeed", FALSE, 0, NULL, 0, FALSE},
+}
+# endif
+;
+
+/* For prt_get_unit(). */
+# define PRT_UNIT_NONE	-1
+# define PRT_UNIT_PERC	0
+# define PRT_UNIT_INCH	1
+# define PRT_UNIT_MM	2
+# define PRT_UNIT_POINT	3
+# define PRT_UNIT_NAMES {"pc", "in", "mm", "pt"}
+#endif
+
+#if (defined(FEAT_PRINTER) && defined(FEAT_STL_OPT)) \
+	    || defined(FEAT_GUI_TABLINE)
+/* Page number used for %N in 'pageheader' and 'guitablabel'. */
+EXTERN linenr_T printer_page_num;
+#endif
+
+#ifdef FEAT_XCLIPBOARD
+EXTERN char	*xterm_display INIT(= NULL);	/* xterm display name; points
+						   into argv[] */
+EXTERN Display	*xterm_dpy INIT(= NULL);	/* xterm display pointer */
+#endif
+#if defined(FEAT_XCLIPBOARD) || defined(FEAT_GUI_X11)
+EXTERN XtAppContext app_context INIT(= (XtAppContext)NULL);
+#endif
+
+#ifdef FEAT_GUI_GTK
+EXTERN guint32	gtk_socket_id INIT(= 0);
+EXTERN int	echo_wid_arg INIT(= FALSE);	/* --echo-wid argument */
+#endif
+
+#if defined(FEAT_CLIENTSERVER) || defined(FEAT_EVAL)
+EXTERN int	typebuf_was_filled INIT(= FALSE); /* received text from client
+						     or from feedkeys() */
+#endif
+
+#ifdef FEAT_CLIENTSERVER
+EXTERN char_u	*serverName INIT(= NULL);	/* name of the server */
+# ifdef FEAT_X11
+EXTERN Window	commWindow INIT(= None);
+EXTERN Window	clientWindow INIT(= None);
+EXTERN Atom	commProperty INIT(= None);
+EXTERN char_u	*serverDelayedStartName INIT(= NULL);
+# else
+# ifdef PROTO
+typedef int HWND;
+# endif
+EXTERN HWND	clientWindow INIT(= 0);
+# endif
+#endif
+
+#if defined(UNIX) || defined(VMS)
+EXTERN int	term_is_xterm INIT(= FALSE);	/* xterm-like 'term' */
+#endif
+
+#ifdef BACKSLASH_IN_FILENAME
+EXTERN char	psepc INIT(= '\\');	/* normal path separator character */
+EXTERN char	psepcN INIT(= '/');	/* abnormal path separator character */
+EXTERN char	pseps[2]		/* normal path separator string */
+# ifdef DO_INIT
+			= {'\\', 0}
+# endif
+			;
+#endif
+
+#ifdef FEAT_VIRTUALEDIT
+/* Set to TRUE when an operator is being executed with virtual editing, MAYBE
+ * when no operator is being executed, FALSE otherwise. */
+EXTERN int	virtual_op INIT(= MAYBE);
+#endif
+
+#ifdef FEAT_SYN_HL
+/* Display tick, incremented for each call to update_screen() */
+EXTERN disptick_T	display_tick INIT(= 0);
+#endif
+
+#ifdef FEAT_SPELL
+/* Line in which spell checking wasn't highlighted because it touched the
+ * cursor position in Insert mode. */
+EXTERN linenr_T		spell_redraw_lnum INIT(= 0);
+#endif
+
+#ifdef ALT_X_INPUT
+/* we need to be able to go into the dispatch loop while processing a command
+ * received via alternate input. However, we don't want to process another
+ * command until the first is completed.
+ */
+EXTERN int	suppress_alternate_input INIT(= FALSE);
+#endif
+
+#ifdef USE_MCH_ERRMSG
+/* Grow array to collect error messages in until they can be displayed. */
+EXTERN garray_T error_ga
+# ifdef DO_INIT
+	= {0, 0, 0, 0, NULL}
+# endif
+	;
+#endif
+
+#ifdef FEAT_NETBEANS_INTG
+EXTERN char *netbeansArg INIT(= NULL);	/* the -nb[:host:port:passwd] arg */
+EXTERN int netbeansCloseFile INIT(= 0);	/* send killed if != 0 */
+EXTERN int netbeansFireChanges INIT(= 1); /* send buffer changes if != 0 */
+EXTERN int netbeansForcedQuit INIT(= 0);/* don't write modified files */
+EXTERN int netbeansReadFile INIT(= 1);	/* OK to read from disk if != 0 */
+EXTERN int netbeansSuppressNoLines INIT(= 0); /* skip "No lines in buffer" */
+EXTERN int usingNetbeans INIT(= 0);	/* set if -nb flag is used */
+#endif
+
+/*
+ * The error messages that can be shared are included here.
+ * Excluded are errors that are only used once and debugging messages.
+ */
+EXTERN char_u e_abort[]		INIT(= N_("E470: Command aborted"));
+EXTERN char_u e_argreq[]	INIT(= N_("E471: Argument required"));
+EXTERN char_u e_backslash[]	INIT(= N_("E10: \\ should be followed by /, ? or &"));
+#ifdef FEAT_CMDWIN
+EXTERN char_u e_cmdwin[]	INIT(= N_("E11: Invalid in command-line window; <CR> executes, CTRL-C quits"));
+#endif
+EXTERN char_u e_curdir[]	INIT(= N_("E12: Command not allowed from exrc/vimrc in current dir or tag search"));
+#ifdef FEAT_EVAL
+EXTERN char_u e_endif[]		INIT(= N_("E171: Missing :endif"));
+EXTERN char_u e_endtry[]	INIT(= N_("E600: Missing :endtry"));
+EXTERN char_u e_endwhile[]	INIT(= N_("E170: Missing :endwhile"));
+EXTERN char_u e_endfor[]	INIT(= N_("E170: Missing :endfor"));
+EXTERN char_u e_while[]		INIT(= N_("E588: :endwhile without :while"));
+EXTERN char_u e_for[]		INIT(= N_("E588: :endfor without :for"));
+#endif
+EXTERN char_u e_exists[]	INIT(= N_("E13: File exists (add ! to override)"));
+EXTERN char_u e_failed[]	INIT(= N_("E472: Command failed"));
+#if defined(FEAT_GUI) && defined(FEAT_XFONTSET)
+EXTERN char_u e_fontset[]	INIT(= N_("E234: Unknown fontset: %s"));
+#endif
+#if defined(FEAT_GUI_X11) || defined(FEAT_GUI_GTK) || defined(MACOS) \
+	|| defined(FEAT_GUI_PHOTON) || defined(FEAT_GUI_MSWIN)
+EXTERN char_u e_font[]		INIT(= N_("E235: Unknown font: %s"));
+#endif
+#if (defined(FEAT_GUI_X11) || defined(FEAT_GUI_GTK)) && !defined(HAVE_GTK2)
+EXTERN char_u e_fontwidth[]	INIT(= N_("E236: Font \"%s\" is not fixed-width"));
+#endif
+EXTERN char_u e_internal[]	INIT(= N_("E473: Internal error"));
+EXTERN char_u e_interr[]	INIT(= N_("Interrupted"));
+EXTERN char_u e_invaddr[]	INIT(= N_("E14: Invalid address"));
+EXTERN char_u e_invarg[]	INIT(= N_("E474: Invalid argument"));
+EXTERN char_u e_invarg2[]	INIT(= N_("E475: Invalid argument: %s"));
+#ifdef FEAT_EVAL
+EXTERN char_u e_invexpr2[]	INIT(= N_("E15: Invalid expression: %s"));
+#endif
+EXTERN char_u e_invrange[]	INIT(= N_("E16: Invalid range"));
+EXTERN char_u e_invcmd[]	INIT(= N_("E476: Invalid command"));
+#if defined(UNIX) || defined(FEAT_SYN_HL)
+EXTERN char_u e_isadir2[]	INIT(= N_("E17: \"%s\" is a directory"));
+#endif
+#ifdef FEAT_LIBCALL
+EXTERN char_u e_libcall[]	INIT(= N_("E364: Library call failed for \"%s()\""));
+#endif
+#if defined(DYNAMIC_PERL) || defined(DYNAMIC_PYTHON) || defined(DYNAMIC_RUBY) \
+	|| defined(DYNAMIC_TCL) || defined(DYNAMIC_ICONV) \
+	|| defined(DYNAMIC_GETTEXT) || defined(DYNAMIC_MZSCHEME)
+EXTERN char_u e_loadlib[]	INIT(= N_("E370: Could not load library %s"));
+EXTERN char_u e_loadfunc[]	INIT(= N_("E448: Could not load library function %s"));
+#endif
+EXTERN char_u e_markinval[]	INIT(= N_("E19: Mark has invalid line number"));
+EXTERN char_u e_marknotset[]	INIT(= N_("E20: Mark not set"));
+EXTERN char_u e_modifiable[]	INIT(= N_("E21: Cannot make changes, 'modifiable' is off"));
+EXTERN char_u e_nesting[]	INIT(= N_("E22: Scripts nested too deep"));
+EXTERN char_u e_noalt[]		INIT(= N_("E23: No alternate file"));
+EXTERN char_u e_noabbr[]	INIT(= N_("E24: No such abbreviation"));
+EXTERN char_u e_nobang[]	INIT(= N_("E477: No ! allowed"));
+#ifndef FEAT_GUI
+EXTERN char_u e_nogvim[]	INIT(= N_("E25: GUI cannot be used: Not enabled at compile time"));
+#endif
+#ifndef FEAT_RIGHTLEFT
+EXTERN char_u e_nohebrew[]	INIT(= N_("E26: Hebrew cannot be used: Not enabled at compile time\n"));
+#endif
+#ifndef FEAT_FKMAP
+EXTERN char_u e_nofarsi[]	INIT(= N_("E27: Farsi cannot be used: Not enabled at compile time\n"));
+#endif
+#ifndef FEAT_ARABIC
+EXTERN char_u e_noarabic[]	INIT(= N_("E800: Arabic cannot be used: Not enabled at compile time\n"));
+#endif
+#if defined(FEAT_SEARCH_EXTRA) || defined(FEAT_SYN_HL)
+EXTERN char_u e_nogroup[]	INIT(= N_("E28: No such highlight group name: %s"));
+#endif
+EXTERN char_u e_noinstext[]	INIT(= N_("E29: No inserted text yet"));
+EXTERN char_u e_nolastcmd[]	INIT(= N_("E30: No previous command line"));
+EXTERN char_u e_nomap[]		INIT(= N_("E31: No such mapping"));
+EXTERN char_u e_nomatch[]	INIT(= N_("E479: No match"));
+EXTERN char_u e_nomatch2[]	INIT(= N_("E480: No match: %s"));
+EXTERN char_u e_noname[]	INIT(= N_("E32: No file name"));
+EXTERN char_u e_nopresub[]	INIT(= N_("E33: No previous substitute regular expression"));
+EXTERN char_u e_noprev[]	INIT(= N_("E34: No previous command"));
+EXTERN char_u e_noprevre[]	INIT(= N_("E35: No previous regular expression"));
+EXTERN char_u e_norange[]	INIT(= N_("E481: No range allowed"));
+#ifdef FEAT_WINDOWS
+EXTERN char_u e_noroom[]	INIT(= N_("E36: Not enough room"));
+#endif
+#ifdef FEAT_CLIENTSERVER
+EXTERN char_u e_noserver[]	INIT(= N_("E247: no registered server named \"%s\""));
+#endif
+EXTERN char_u e_notcreate[]	INIT(= N_("E482: Can't create file %s"));
+EXTERN char_u e_notmp[]		INIT(= N_("E483: Can't get temp file name"));
+EXTERN char_u e_notopen[]	INIT(= N_("E484: Can't open file %s"));
+EXTERN char_u e_notread[]	INIT(= N_("E485: Can't read file %s"));
+EXTERN char_u e_nowrtmsg[]	INIT(= N_("E37: No write since last change (add ! to override)"));
+EXTERN char_u e_null[]		INIT(= N_("E38: Null argument"));
+#ifdef FEAT_DIGRAPHS
+EXTERN char_u e_number_exp[]	INIT(= N_("E39: Number expected"));
+#endif
+#ifdef FEAT_QUICKFIX
+EXTERN char_u e_openerrf[]	INIT(= N_("E40: Can't open errorfile %s"));
+#endif
+#if defined(FEAT_GUI_GTK) || defined(FEAT_GUI_X11)
+EXTERN char_u e_opendisp[]	INIT(= N_("E233: cannot open display"));
+#endif
+EXTERN char_u e_outofmem[]	INIT(= N_("E41: Out of memory!"));
+#ifdef FEAT_INS_EXPAND
+EXTERN char_u e_patnotf[]	INIT(= N_("Pattern not found"));
+#endif
+EXTERN char_u e_patnotf2[]	INIT(= N_("E486: Pattern not found: %s"));
+EXTERN char_u e_positive[]	INIT(= N_("E487: Argument must be positive"));
+#if defined(UNIX) || defined(PLAN9) || defined(FEAT_SESSION)
+EXTERN char_u e_prev_dir[]	INIT(= N_("E459: Cannot go back to previous directory"));
+#endif
+
+#ifdef FEAT_QUICKFIX
+EXTERN char_u e_quickfix[]	INIT(= N_("E42: No Errors"));
+EXTERN char_u e_loclist[]	INIT(= N_("E776: No location list"));
+#endif
+EXTERN char_u e_re_damg[]	INIT(= N_("E43: Damaged match string"));
+EXTERN char_u e_re_corr[]	INIT(= N_("E44: Corrupted regexp program"));
+EXTERN char_u e_readonly[]	INIT(= N_("E45: 'readonly' option is set (add ! to override)"));
+#ifdef FEAT_EVAL
+EXTERN char_u e_readonlyvar[]	INIT(= N_("E46: Cannot change read-only variable \"%s\""));
+EXTERN char_u e_readonlysbx[]	INIT(= N_("E794: Cannot set variable in the sandbox: \"%s\""));
+#endif
+#ifdef FEAT_QUICKFIX
+EXTERN char_u e_readerrf[]	INIT(= N_("E47: Error while reading errorfile"));
+#endif
+#ifdef HAVE_SANDBOX
+EXTERN char_u e_sandbox[]	INIT(= N_("E48: Not allowed in sandbox"));
+#endif
+EXTERN char_u e_secure[]	INIT(= N_("E523: Not allowed here"));
+#if defined(AMIGA) || defined(MACOS) || defined(MSWIN) || defined(RISCOS) \
+	|| defined(UNIX) || defined(VMS) || defined(OS2) || defined(PLAN9)
+EXTERN char_u e_screenmode[]	INIT(= N_("E359: Screen mode setting not supported"));
+#endif
+EXTERN char_u e_scroll[]	INIT(= N_("E49: Invalid scroll size"));
+EXTERN char_u e_shellempty[]	INIT(= N_("E91: 'shell' option is empty"));
+#if defined(FEAT_SIGN_ICONS) && !defined(HAVE_GTK2)
+EXTERN char_u e_signdata[]	INIT(= N_("E255: Couldn't read in sign data!"));
+#endif
+EXTERN char_u e_swapclose[]	INIT(= N_("E72: Close error on swap file"));
+EXTERN char_u e_tagstack[]	INIT(= N_("E73: tag stack empty"));
+EXTERN char_u e_toocompl[]	INIT(= N_("E74: Command too complex"));
+EXTERN char_u e_longname[]	INIT(= N_("E75: Name too long"));
+EXTERN char_u e_toomsbra[]	INIT(= N_("E76: Too many ["));
+EXTERN char_u e_toomany[]	INIT(= N_("E77: Too many file names"));
+EXTERN char_u e_trailing[]	INIT(= N_("E488: Trailing characters"));
+EXTERN char_u e_umark[]		INIT(= N_("E78: Unknown mark"));
+EXTERN char_u e_wildexpand[]	INIT(= N_("E79: Cannot expand wildcards"));
+#ifdef FEAT_WINDOWS
+EXTERN char_u e_winheight[]	INIT(= N_("E591: 'winheight' cannot be smaller than 'winminheight'"));
+# ifdef FEAT_VERTSPLIT
+EXTERN char_u e_winwidth[]	INIT(= N_("E592: 'winwidth' cannot be smaller than 'winminwidth'"));
+# endif
+#endif
+EXTERN char_u e_write[]		INIT(= N_("E80: Error while writing"));
+EXTERN char_u e_zerocount[]	INIT(= N_("Zero count"));
+#ifdef FEAT_EVAL
+EXTERN char_u e_usingsid[]	INIT(= N_("E81: Using <SID> not in a script context"));
+#endif
+#ifdef FEAT_CLIENTSERVER
+EXTERN char_u e_invexprmsg[]	INIT(= N_("E449: Invalid expression received"));
+#endif
+#ifdef FEAT_NETBEANS_INTG
+EXTERN char_u e_guarded[]	INIT(= N_("E463: Region is guarded, cannot modify"));
+EXTERN char_u e_nbreadonly[]	INIT(= N_("E744: NetBeans does not allow changes in read-only files"));
+#endif
+EXTERN char_u e_intern2[]	INIT(= N_("E685: Internal error: %s"));
+EXTERN char_u e_maxmempat[]	INIT(= N_("E363: pattern uses more memory than 'maxmempattern'"));
+EXTERN char_u e_emptybuf[]	INIT(= N_("E749: empty buffer"));
+
+#ifdef FEAT_EX_EXTRA
+EXTERN char_u e_invalpat[]	INIT(= N_("E682: Invalid search pattern or delimiter"));
+#endif
+EXTERN char_u e_bufloaded[]	INIT(= N_("E139: File is loaded in another buffer"));
+#if defined(FEAT_SYN_HL) || \
+	(defined(FEAT_INS_EXPAND) && defined(FEAT_COMPL_FUNC))
+EXTERN char_u e_notset[]	INIT(= N_("E764: Option '%s' is not set"));
+#endif
+
+#ifdef MACOS_X_UNIX
+EXTERN short disallow_gui	INIT(= FALSE);
+#endif
+
+EXTERN char top_bot_msg[] INIT(= N_("search hit TOP, continuing at BOTTOM"));
+EXTERN char bot_top_msg[] INIT(= N_("search hit BOTTOM, continuing at TOP"));
+
+/*
+ * Comms. with the session manager (XSMP)
+ */
+#ifdef USE_XSMP
+EXTERN int xsmp_icefd INIT(= -1);   /* The actual connection */
+#endif
+
+/* For undo we need to know the lowest time possible. */
+EXTERN time_t starttime;
+
+/*
+ * Optional Farsi support.  Include it here, so EXTERN and INIT are defined.
+ */
+#ifdef FEAT_FKMAP
+# include "farsi.h"
+#endif
+
+/*
+ * Optional Arabic support. Include it here, so EXTERN and INIT are defined.
+ */
+#ifdef FEAT_ARABIC
+# include "arabic.h"
+#endif
--- /dev/null
+++ b/gui.c
@@ -1,0 +1,5180 @@
+/* vi:set ts=8 sts=4 sw=4:
+ *
+ * VIM - Vi IMproved		by Bram Moolenaar
+ *				GUI/Motif support by Robert Webb
+ *
+ * Do ":help uganda"  in Vim to read copying and usage conditions.
+ * Do ":help credits" in Vim to see a list of people who contributed.
+ * See README.txt for an overview of the Vim source code.
+ */
+
+#include "vim.h"
+
+/* Structure containing all the GUI information */
+gui_T gui;
+
+#if defined(FEAT_MBYTE) && !defined(HAVE_GTK2)
+static void set_guifontwide __ARGS((char_u *font_name));
+#endif
+static void gui_check_pos __ARGS((void));
+static void gui_position_components __ARGS((int));
+static void gui_outstr __ARGS((char_u *, int));
+static int gui_screenchar __ARGS((int off, int flags, guicolor_T fg, guicolor_T bg, int back));
+#ifdef HAVE_GTK2
+static int gui_screenstr __ARGS((int off, int len, int flags, guicolor_T fg, guicolor_T bg, int back));
+#endif
+static void gui_delete_lines __ARGS((int row, int count));
+static void gui_insert_lines __ARGS((int row, int count));
+static void fill_mouse_coord __ARGS((char_u *p, int col, int row));
+#if defined(FEAT_GUI_TABLINE) || defined(PROTO)
+static int gui_has_tabline __ARGS((void));
+#endif
+static void gui_do_scrollbar __ARGS((win_T *wp, int which, int enable));
+static colnr_T scroll_line_len __ARGS((linenr_T lnum));
+static void gui_update_horiz_scrollbar __ARGS((int));
+static void gui_set_fg_color __ARGS((char_u *name));
+static void gui_set_bg_color __ARGS((char_u *name));
+static win_T *xy2win __ARGS((int x, int y));
+
+static int can_update_cursor = TRUE; /* can display the cursor */
+
+/*
+ * The Athena scrollbars can move the thumb to after the end of the scrollbar,
+ * this makes the thumb indicate the part of the text that is shown.  Motif
+ * can't do this.
+ */
+#if defined(FEAT_GUI_ATHENA) || defined(FEAT_GUI_MAC)
+# define SCROLL_PAST_END
+#endif
+
+/*
+ * gui_start -- Called when user wants to start the GUI.
+ *
+ * Careful: This function can be called recursively when there is a ":gui"
+ * command in the .gvimrc file.  Only the first call should fork, not the
+ * recursive call.
+ */
+    void
+gui_start()
+{
+    char_u	*old_term;
+#if defined(UNIX) && !defined(__BEOS__) && !defined(MACOS_X)
+# define MAY_FORK
+    int		dofork = TRUE;
+#endif
+    static int	recursive = 0;
+
+    old_term = vim_strsave(T_NAME);
+
+    /*
+     * Set_termname() will call gui_init() to start the GUI.
+     * Set the "starting" flag, to indicate that the GUI will start.
+     *
+     * We don't want to open the GUI shell until after we've read .gvimrc,
+     * otherwise we don't know what font we will use, and hence we don't know
+     * what size the shell should be.  So if there are errors in the .gvimrc
+     * file, they will have to go to the terminal: Set full_screen to FALSE.
+     * full_screen will be set to TRUE again by a successful termcapinit().
+     */
+    settmode(TMODE_COOK);		/* stop RAW mode */
+    if (full_screen)
+	cursor_on();			/* needed for ":gui" in .vimrc */
+    gui.starting = TRUE;
+    full_screen = FALSE;
+
+#ifdef MAY_FORK
+    if (!gui.dofork || vim_strchr(p_go, GO_FORG) || recursive)
+	dofork = FALSE;
+#endif
+    ++recursive;
+
+    termcapinit((char_u *)"builtin_gui");
+    gui.starting = recursive - 1;
+
+    if (!gui.in_use)			/* failed to start GUI */
+    {
+	termcapinit(old_term);		/* back to old term settings */
+	settmode(TMODE_RAW);		/* restart RAW mode */
+#ifdef FEAT_TITLE
+	set_title_defaults();		/* set 'title' and 'icon' again */
+#endif
+    }
+
+    vim_free(old_term);
+
+#if defined(FEAT_GUI_GTK) || defined(FEAT_GUI_X11)
+    if (gui.in_use)
+	/* Display error messages in a dialog now. */
+	display_errors();
+#endif
+
+#if defined(MAY_FORK) && !defined(__QNXNTO__)
+    /*
+     * Quit the current process and continue in the child.
+     * Makes "gvim file" disconnect from the shell it was started in.
+     * Don't do this when Vim was started with "-f" or the 'f' flag is present
+     * in 'guioptions'.
+     */
+    if (gui.in_use && dofork)
+    {
+	int	pipefd[2];	/* pipe between parent and child */
+	int	pipe_error;
+	char	dummy;
+	pid_t	pid = -1;
+
+	/* Setup a pipe between the child and the parent, so that the parent
+	 * knows when the child has done the setsid() call and is allowed to
+	 * exit. */
+	pipe_error = (pipe(pipefd) < 0);
+	pid = fork();
+	if (pid > 0)	    /* Parent */
+	{
+	    /* Give the child some time to do the setsid(), otherwise the
+	     * exit() may kill the child too (when starting gvim from inside a
+	     * gvim). */
+	    if (pipe_error)
+		ui_delay(300L, TRUE);
+	    else
+	    {
+		/* The read returns when the child closes the pipe (or when
+		 * the child dies for some reason). */
+		close(pipefd[1]);
+		(void)read(pipefd[0], &dummy, (size_t)1);
+		close(pipefd[0]);
+	    }
+
+	    /* When swapping screens we may need to go to the next line, e.g.,
+	     * after a hit-enter prompt and using ":gui". */
+	    if (newline_on_exit)
+		mch_errmsg("\r\n");
+
+	    /*
+	     * The parent must skip the normal exit() processing, the child
+	     * will do it.  For example, GTK messes up signals when exiting.
+	     */
+	    _exit(0);
+	}
+
+# if defined(HAVE_SETSID) || defined(HAVE_SETPGID)
+	/*
+	 * Change our process group.  On some systems/shells a CTRL-C in the
+	 * shell where Vim was started would otherwise kill gvim!
+	 */
+	if (pid == 0)	    /* child */
+#  if defined(HAVE_SETSID)
+	    (void)setsid();
+#  else
+	    (void)setpgid(0, 0);
+#  endif
+# endif
+	if (!pipe_error)
+	{
+	    close(pipefd[0]);
+	    close(pipefd[1]);
+	}
+
+# if defined(FEAT_GUI_GNOME) && defined(FEAT_SESSION)
+	/* Tell the session manager our new PID */
+	gui_mch_forked();
+# endif
+    }
+#else
+# if defined(__QNXNTO__)
+    if (gui.in_use && dofork)
+	procmgr_daemon(0, PROCMGR_DAEMON_KEEPUMASK | PROCMGR_DAEMON_NOCHDIR |
+		PROCMGR_DAEMON_NOCLOSE | PROCMGR_DAEMON_NODEVNULL);
+# endif
+#endif
+
+#ifdef FEAT_AUTOCMD
+    /* If the GUI started successfully, trigger the GUIEnter event, otherwise
+     * the GUIFailed event. */
+    apply_autocmds(gui.in_use ? EVENT_GUIENTER : EVENT_GUIFAILED,
+						   NULL, NULL, FALSE, curbuf);
+#endif
+
+    --recursive;
+}
+
+/*
+ * Call this when vim starts up, whether or not the GUI is started
+ */
+    void
+gui_prepare(argc, argv)
+    int	    *argc;
+    char    **argv;
+{
+    gui.in_use = FALSE;		    /* No GUI yet (maybe later) */
+    gui.starting = FALSE;	    /* No GUI yet (maybe later) */
+    gui_mch_prepare(argc, argv);
+}
+
+/*
+ * Try initializing the GUI and check if it can be started.
+ * Used from main() to check early if "vim -g" can start the GUI.
+ * Used from gui_init() to prepare for starting the GUI.
+ * Returns FAIL or OK.
+ */
+    int
+gui_init_check()
+{
+    static int result = MAYBE;
+
+    if (result != MAYBE)
+    {
+	if (result == FAIL)
+	    EMSG(_("E229: Cannot start the GUI"));
+	return result;
+    }
+
+    gui.shell_created = FALSE;
+    gui.dying = FALSE;
+    gui.in_focus = TRUE;		/* so the guicursor setting works */
+    gui.dragged_sb = SBAR_NONE;
+    gui.dragged_wp = NULL;
+    gui.pointer_hidden = FALSE;
+    gui.col = 0;
+    gui.row = 0;
+    gui.num_cols = Columns;
+    gui.num_rows = Rows;
+
+    gui.cursor_is_valid = FALSE;
+    gui.scroll_region_top = 0;
+    gui.scroll_region_bot = Rows - 1;
+    gui.scroll_region_left = 0;
+    gui.scroll_region_right = Columns - 1;
+    gui.highlight_mask = HL_NORMAL;
+    gui.char_width = 1;
+    gui.char_height = 1;
+    gui.char_ascent = 0;
+    gui.border_width = 0;
+
+    gui.norm_font = NOFONT;
+#ifndef HAVE_GTK2
+    gui.bold_font = NOFONT;
+    gui.ital_font = NOFONT;
+    gui.boldital_font = NOFONT;
+# ifdef FEAT_XFONTSET
+    gui.fontset = NOFONTSET;
+# endif
+#endif
+
+#ifdef FEAT_MENU
+# ifndef HAVE_GTK2
+#  ifdef FONTSET_ALWAYS
+    gui.menu_fontset = NOFONTSET;
+#  else
+    gui.menu_font = NOFONT;
+#  endif
+# endif
+    gui.menu_is_active = TRUE;	    /* default: include menu */
+# ifndef FEAT_GUI_GTK
+    gui.menu_height = MENU_DEFAULT_HEIGHT;
+    gui.menu_width = 0;
+# endif
+#endif
+#if defined(FEAT_TOOLBAR) && (defined(FEAT_GUI_MOTIF) || defined(FEAT_GUI_ATHENA))
+    gui.toolbar_height = 0;
+#endif
+#if defined(FEAT_FOOTER) && defined(FEAT_GUI_MOTIF)
+    gui.footer_height = 0;
+#endif
+#ifdef FEAT_BEVAL_TIP
+    gui.tooltip_fontset = NOFONTSET;
+#endif
+
+    gui.scrollbar_width = gui.scrollbar_height = SB_DEFAULT_WIDTH;
+    gui.prev_wrap = -1;
+
+#ifdef ALWAYS_USE_GUI
+    result = OK;
+#else
+    result = gui_mch_init_check();
+#endif
+    return result;
+}
+
+/*
+ * This is the call which starts the GUI.
+ */
+    void
+gui_init()
+{
+    win_T	*wp;
+    static int	recursive = 0;
+
+    /*
+     * It's possible to use ":gui" in a .gvimrc file.  The first halve of this
+     * function will then be executed at the first call, the rest by the
+     * recursive call.  This allow the shell to be opened halfway reading a
+     * gvimrc file.
+     */
+    if (!recursive)
+    {
+	++recursive;
+
+	clip_init(TRUE);
+
+	/* If can't initialize, don't try doing the rest */
+	if (gui_init_check() == FAIL)
+	{
+	    --recursive;
+	    clip_init(FALSE);
+	    return;
+	}
+
+	/*
+	 * Reset 'paste'.  It's useful in the terminal, but not in the GUI.  It
+	 * breaks the Paste toolbar button.
+	 */
+	set_option_value((char_u *)"paste", 0L, NULL, 0);
+
+	/*
+	 * Set up system-wide default menus.
+	 */
+#if defined(SYS_MENU_FILE) && defined(FEAT_MENU)
+	if (vim_strchr(p_go, GO_NOSYSMENU) == NULL)
+	{
+	    sys_menu = TRUE;
+	    do_source((char_u *)SYS_MENU_FILE, FALSE, DOSO_NONE);
+	    sys_menu = FALSE;
+	}
+#endif
+
+	/*
+	 * Switch on the mouse by default, unless the user changed it already.
+	 * This can then be changed in the .gvimrc.
+	 */
+	if (!option_was_set((char_u *)"mouse"))
+	    set_string_option_direct((char_u *)"mouse", -1,
+					   (char_u *)"a", OPT_FREE, SID_NONE);
+
+	/*
+	 * If -U option given, use only the initializations from that file and
+	 * nothing else.  Skip all initializations for "-U NONE" or "-u NORC".
+	 */
+	if (use_gvimrc != NULL)
+	{
+	    if (STRCMP(use_gvimrc, "NONE") != 0
+		    && STRCMP(use_gvimrc, "NORC") != 0
+		    && do_source(use_gvimrc, FALSE, DOSO_NONE) != OK)
+		EMSG2(_("E230: Cannot read from \"%s\""), use_gvimrc);
+	}
+	else
+	{
+	    /*
+	     * Get system wide defaults for gvim, only when file name defined.
+	     */
+#ifdef SYS_GVIMRC_FILE
+	    do_source((char_u *)SYS_GVIMRC_FILE, FALSE, DOSO_NONE);
+#endif
+
+	    /*
+	     * Try to read GUI initialization commands from the following
+	     * places:
+	     * - environment variable GVIMINIT
+	     * - the user gvimrc file (~/.gvimrc)
+	     * - the second user gvimrc file ($VIM/.gvimrc for Dos)
+	     * - the third user gvimrc file ($VIM/.gvimrc for Amiga)
+	     * The first that exists is used, the rest is ignored.
+	     */
+	    if (process_env((char_u *)"GVIMINIT", FALSE) == FAIL
+		 && do_source((char_u *)USR_GVIMRC_FILE, TRUE,
+							  DOSO_GVIMRC) == FAIL
+#ifdef USR_GVIMRC_FILE2
+		 && do_source((char_u *)USR_GVIMRC_FILE2, TRUE,
+							  DOSO_GVIMRC) == FAIL
+#endif
+				)
+	    {
+#ifdef USR_GVIMRC_FILE3
+		(void)do_source((char_u *)USR_GVIMRC_FILE3, TRUE, DOSO_GVIMRC);
+#endif
+	    }
+
+	    /*
+	     * Read initialization commands from ".gvimrc" in current
+	     * directory.  This is only done if the 'exrc' option is set.
+	     * Because of security reasons we disallow shell and write
+	     * commands now, except for unix if the file is owned by the user
+	     * or 'secure' option has been reset in environment of global
+	     * ".gvimrc".
+	     * Only do this if GVIMRC_FILE is not the same as USR_GVIMRC_FILE,
+	     * USR_GVIMRC_FILE2, USR_GVIMRC_FILE3 or SYS_GVIMRC_FILE.
+	     */
+	    if (p_exrc)
+	    {
+#ifdef UNIX
+		{
+		    struct stat s;
+
+		    /* if ".gvimrc" file is not owned by user, set 'secure'
+		     * mode */
+		    if (mch_stat(GVIMRC_FILE, &s) || s.st_uid != getuid())
+			secure = p_secure;
+		}
+#else
+		secure = p_secure;
+#endif
+
+		if (       fullpathcmp((char_u *)USR_GVIMRC_FILE,
+				     (char_u *)GVIMRC_FILE, FALSE) != FPC_SAME
+#ifdef SYS_GVIMRC_FILE
+			&& fullpathcmp((char_u *)SYS_GVIMRC_FILE,
+				     (char_u *)GVIMRC_FILE, FALSE) != FPC_SAME
+#endif
+#ifdef USR_GVIMRC_FILE2
+			&& fullpathcmp((char_u *)USR_GVIMRC_FILE2,
+				     (char_u *)GVIMRC_FILE, FALSE) != FPC_SAME
+#endif
+#ifdef USR_GVIMRC_FILE3
+			&& fullpathcmp((char_u *)USR_GVIMRC_FILE3,
+				     (char_u *)GVIMRC_FILE, FALSE) != FPC_SAME
+#endif
+			)
+		    do_source((char_u *)GVIMRC_FILE, TRUE, DOSO_GVIMRC);
+
+		if (secure == 2)
+		    need_wait_return = TRUE;
+		secure = 0;
+	    }
+	}
+
+	if (need_wait_return || msg_didany)
+	    wait_return(TRUE);
+
+	--recursive;
+    }
+
+    /* If recursive call opened the shell, return here from the first call */
+    if (gui.in_use)
+	return;
+
+    /*
+     * Create the GUI shell.
+     */
+    gui.in_use = TRUE;		/* Must be set after menus have been set up */
+    if (gui_mch_init() == FAIL)
+	goto error;
+
+    /* Avoid a delay for an error message that was printed in the terminal
+     * where Vim was started. */
+    emsg_on_display = FALSE;
+    msg_scrolled = 0;
+    clear_sb_text();
+    need_wait_return = FALSE;
+    msg_didany = FALSE;
+
+    /*
+     * Check validity of any generic resources that may have been loaded.
+     */
+    if (gui.border_width < 0)
+	gui.border_width = 0;
+
+    /*
+     * Set up the fonts.  First use a font specified with "-fn" or "-font".
+     */
+    if (font_argument != NULL)
+	set_option_value((char_u *)"gfn", 0L, (char_u *)font_argument, 0);
+    if (
+#ifdef FEAT_XFONTSET
+	    (*p_guifontset == NUL
+	     || gui_init_font(p_guifontset, TRUE) == FAIL) &&
+#endif
+	    gui_init_font(*p_guifont == NUL ? hl_get_font_name()
+						  : p_guifont, FALSE) == FAIL)
+    {
+	EMSG(_("E665: Cannot start GUI, no valid font found"));
+	goto error2;
+    }
+#ifdef FEAT_MBYTE
+    if (gui_get_wide_font() == FAIL)
+	EMSG(_("E231: 'guifontwide' invalid"));
+#endif
+
+    gui.num_cols = Columns;
+    gui.num_rows = Rows;
+    gui_reset_scroll_region();
+
+    /* Create initial scrollbars */
+    FOR_ALL_WINDOWS(wp)
+    {
+	gui_create_scrollbar(&wp->w_scrollbars[SBAR_LEFT], SBAR_LEFT, wp);
+	gui_create_scrollbar(&wp->w_scrollbars[SBAR_RIGHT], SBAR_RIGHT, wp);
+    }
+    gui_create_scrollbar(&gui.bottom_sbar, SBAR_BOTTOM, NULL);
+
+#ifdef FEAT_MENU
+    gui_create_initial_menus(root_menu);
+#endif
+#ifdef FEAT_SUN_WORKSHOP
+    if (usingSunWorkShop)
+	workshop_init();
+#endif
+#ifdef FEAT_SIGN_ICONS
+    sign_gui_started();
+#endif
+
+    /* Configure the desired menu and scrollbars */
+    gui_init_which_components(NULL);
+
+    /* All components of the GUI have been created now */
+    gui.shell_created = TRUE;
+
+#ifndef FEAT_GUI_GTK
+    /* Set the shell size, adjusted for the screen size.  For GTK this only
+     * works after the shell has been opened, thus it is further down. */
+    gui_set_shellsize(FALSE, TRUE, RESIZE_BOTH);
+#endif
+#if defined(FEAT_GUI_MOTIF) && defined(FEAT_MENU)
+    /* Need to set the size of the menubar after all the menus have been
+     * created. */
+    gui_mch_compute_menu_height((Widget)0);
+#endif
+
+    /*
+     * Actually open the GUI shell.
+     */
+    if (gui_mch_open() != FAIL)
+    {
+#ifdef FEAT_TITLE
+	maketitle();
+	resettitle();
+#endif
+	init_gui_options();
+#ifdef FEAT_ARABIC
+	/* Our GUI can't do bidi. */
+	p_tbidi = FALSE;
+#endif
+#if defined(FEAT_GUI_GTK)
+	/* Give GTK+ a chance to put all widget's into place. */
+	gui_mch_update();
+
+# ifdef FEAT_MENU
+	/* If there is no 'm' in 'guioptions' we need to remove the menu now.
+	 * It was still there to make F10 work. */
+	if (vim_strchr(p_go, GO_MENUS) == NULL)
+	{
+	    --gui.starting;
+	    gui_mch_enable_menu(FALSE);
+	    ++gui.starting;
+	    gui_mch_update();
+	}
+# endif
+
+	/* Now make sure the shell fits on the screen. */
+	gui_set_shellsize(FALSE, TRUE, RESIZE_BOTH);
+#endif
+	/* When 'lines' was set while starting up the topframe may have to be
+	 * resized. */
+	win_new_shellsize();
+
+#ifdef FEAT_BEVAL
+	/* Always create the Balloon Evaluation area, but disable it when
+	 * 'ballooneval' is off */
+# ifdef FEAT_GUI_GTK
+	balloonEval = gui_mch_create_beval_area(gui.drawarea, NULL,
+						     &general_beval_cb, NULL);
+# else
+#  if defined(FEAT_GUI_MOTIF) || defined(FEAT_GUI_ATHENA)
+	{
+	    extern Widget	textArea;
+	    balloonEval = gui_mch_create_beval_area(textArea, NULL,
+						     &general_beval_cb, NULL);
+	}
+#  else
+#   ifdef FEAT_GUI_W32
+	balloonEval = gui_mch_create_beval_area(NULL, NULL,
+						     &general_beval_cb, NULL);
+#   endif
+#  endif
+# endif
+	if (!p_beval)
+	    gui_mch_disable_beval_area(balloonEval);
+#endif
+
+#ifdef FEAT_NETBEANS_INTG
+	if (starting == 0 && usingNetbeans)
+	    /* Tell the client that it can start sending commands. */
+	    netbeans_startup_done();
+#endif
+#if defined(FEAT_XIM) && defined(FEAT_GUI_GTK)
+	if (!im_xim_isvalid_imactivate())
+	    EMSG(_("E599: Value of 'imactivatekey' is invalid"));
+#endif
+	/* When 'cmdheight' was set during startup it may not have taken
+	 * effect yet. */
+	if (p_ch != 1L)
+	    command_height();
+
+	return;
+    }
+
+error2:
+#ifdef FEAT_GUI_X11
+    /* undo gui_mch_init() */
+    gui_mch_uninit();
+#endif
+
+error:
+    gui.in_use = FALSE;
+    clip_init(FALSE);
+}
+
+
+    void
+gui_exit(rc)
+    int		rc;
+{
+#ifndef __BEOS__
+    /* don't free the fonts, it leads to a BUS error
+     * richard@whitequeen.com Jul 99 */
+    free_highlight_fonts();
+#endif
+    gui.in_use = FALSE;
+    gui_mch_exit(rc);
+}
+
+#if defined(FEAT_GUI_GTK) || defined(FEAT_GUI_X11) || defined(FEAT_GUI_MSWIN) \
+	|| defined(FEAT_GUI_PHOTON) || defined(FEAT_GUI_MAC) || defined(PROTO)
+# define NEED_GUI_UPDATE_SCREEN 1
+/*
+ * Called when the GUI shell is closed by the user.  If there are no changed
+ * files Vim exits, otherwise there will be a dialog to ask the user what to
+ * do.
+ * When this function returns, Vim should NOT exit!
+ */
+    void
+gui_shell_closed()
+{
+    cmdmod_T	    save_cmdmod;
+
+    save_cmdmod = cmdmod;
+
+    /* Only exit when there are no changed files */
+    exiting = TRUE;
+# ifdef FEAT_BROWSE
+    cmdmod.browse = TRUE;
+# endif
+# if defined(FEAT_GUI_DIALOG) || defined(FEAT_CON_DIALOG)
+    cmdmod.confirm = TRUE;
+# endif
+    /* If there are changed buffers, present the user with a dialog if
+     * possible, otherwise give an error message. */
+    if (!check_changed_any(FALSE))
+	getout(0);
+
+    exiting = FALSE;
+    cmdmod = save_cmdmod;
+    gui_update_screen();	/* redraw, window may show changed buffer */
+}
+#endif
+
+/*
+ * Set the font.  "font_list" is a a comma separated list of font names.  The
+ * first font name that works is used.  If none is found, use the default
+ * font.
+ * If "fontset" is TRUE, the "font_list" is used as one name for the fontset.
+ * Return OK when able to set the font.  When it failed FAIL is returned and
+ * the fonts are unchanged.
+ */
+/*ARGSUSED*/
+    int
+gui_init_font(font_list, fontset)
+    char_u	*font_list;
+    int		fontset;
+{
+#define FONTLEN 320
+    char_u	font_name[FONTLEN];
+    int		font_list_empty = FALSE;
+    int		ret = FAIL;
+
+    if (!gui.in_use)
+	return FAIL;
+
+    font_name[0] = NUL;
+    if (*font_list == NUL)
+	font_list_empty = TRUE;
+    else
+    {
+#ifdef FEAT_XFONTSET
+	/* When using a fontset, the whole list of fonts is one name. */
+	if (fontset)
+	    ret = gui_mch_init_font(font_list, TRUE);
+	else
+#endif
+	    while (*font_list != NUL)
+	    {
+		/* Isolate one comma separated font name. */
+		(void)copy_option_part(&font_list, font_name, FONTLEN, ",");
+
+		/* Careful!!!  The Win32 version of gui_mch_init_font(), when
+		 * called with "*" will change p_guifont to the selected font
+		 * name, which frees the old value.  This makes font_list
+		 * invalid.  Thus when OK is returned here, font_list must no
+		 * longer be used! */
+		if (gui_mch_init_font(font_name, FALSE) == OK)
+		{
+#if defined(FEAT_MBYTE) && !defined(HAVE_GTK2)
+		    /* If it's a Unicode font, try setting 'guifontwide' to a
+		     * similar double-width font. */
+		    if ((p_guifontwide == NULL || *p_guifontwide == NUL)
+				&& strstr((char *)font_name, "10646") != NULL)
+			set_guifontwide(font_name);
+#endif
+		    ret = OK;
+		    break;
+		}
+	    }
+    }
+
+    if (ret != OK
+	    && STRCMP(font_list, "*") != 0
+	    && (font_list_empty || gui.norm_font == NOFONT))
+    {
+	/*
+	 * Couldn't load any font in 'font_list', keep the current font if
+	 * there is one.  If 'font_list' is empty, or if there is no current
+	 * font, tell gui_mch_init_font() to try to find a font we can load.
+	 */
+	ret = gui_mch_init_font(NULL, FALSE);
+    }
+
+    if (ret == OK)
+    {
+#ifndef HAVE_GTK2
+	/* Set normal font as current font */
+# ifdef FEAT_XFONTSET
+	if (gui.fontset != NOFONTSET)
+	    gui_mch_set_fontset(gui.fontset);
+	else
+# endif
+	    gui_mch_set_font(gui.norm_font);
+#endif
+	gui_set_shellsize(FALSE,
+#ifdef MSWIN
+		TRUE
+#else
+		FALSE
+#endif
+		, RESIZE_BOTH);
+    }
+
+    return ret;
+}
+
+#if defined(FEAT_MBYTE) || defined(PROTO)
+# ifndef HAVE_GTK2
+/*
+ * Try setting 'guifontwide' to a font twice as wide as "name".
+ */
+    static void
+set_guifontwide(name)
+    char_u	*name;
+{
+    int		i = 0;
+    char_u	wide_name[FONTLEN + 10]; /* room for 2 * width and '*' */
+    char_u	*wp = NULL;
+    char_u	*p;
+    GuiFont	font;
+
+    wp = wide_name;
+    for (p = name; *p != NUL; ++p)
+    {
+	*wp++ = *p;
+	if (*p == '-')
+	{
+	    ++i;
+	    if (i == 6)		/* font type: change "--" to "-*-" */
+	    {
+		if (p[1] == '-')
+		    *wp++ = '*';
+	    }
+	    else if (i == 12)	/* found the width */
+	    {
+		++p;
+		i = getdigits(&p);
+		if (i != 0)
+		{
+		    /* Double the width specification. */
+		    sprintf((char *)wp, "%d%s", i * 2, p);
+		    font = gui_mch_get_font(wide_name, FALSE);
+		    if (font != NOFONT)
+		    {
+			gui_mch_free_font(gui.wide_font);
+			gui.wide_font = font;
+			set_string_option_direct((char_u *)"gfw", -1,
+						      wide_name, OPT_FREE, 0);
+		    }
+		}
+		break;
+	    }
+	}
+    }
+}
+# endif /* !HAVE_GTK2 */
+
+/*
+ * Get the font for 'guifontwide'.
+ * Return FAIL for an invalid font name.
+ */
+    int
+gui_get_wide_font()
+{
+    GuiFont	font = NOFONT;
+    char_u	font_name[FONTLEN];
+    char_u	*p;
+
+    if (!gui.in_use)	    /* Can't allocate font yet, assume it's OK. */
+	return OK;	    /* Will give an error message later. */
+
+    if (p_guifontwide != NULL && *p_guifontwide != NUL)
+    {
+	for (p = p_guifontwide; *p != NUL; )
+	{
+	    /* Isolate one comma separated font name. */
+	    (void)copy_option_part(&p, font_name, FONTLEN, ",");
+	    font = gui_mch_get_font(font_name, FALSE);
+	    if (font != NOFONT)
+		break;
+	}
+	if (font == NOFONT)
+	    return FAIL;
+    }
+
+    gui_mch_free_font(gui.wide_font);
+#ifdef HAVE_GTK2
+    /* Avoid unnecessary overhead if 'guifontwide' is equal to 'guifont'. */
+    if (font != NOFONT && gui.norm_font != NOFONT
+			 && pango_font_description_equal(font, gui.norm_font))
+    {
+	gui.wide_font = NOFONT;
+	gui_mch_free_font(font);
+    }
+    else
+#endif
+	gui.wide_font = font;
+    return OK;
+}
+#endif
+
+    void
+gui_set_cursor(row, col)
+    int	    row;
+    int	    col;
+{
+    gui.row = row;
+    gui.col = col;
+}
+
+/*
+ * gui_check_pos - check if the cursor is on the screen.
+ */
+    static void
+gui_check_pos()
+{
+    if (gui.row >= screen_Rows)
+	gui.row = screen_Rows - 1;
+    if (gui.col >= screen_Columns)
+	gui.col = screen_Columns - 1;
+    if (gui.cursor_row >= screen_Rows || gui.cursor_col >= screen_Columns)
+	gui.cursor_is_valid = FALSE;
+}
+
+/*
+ * Redraw the cursor if necessary or when forced.
+ * Careful: The contents of ScreenLines[] must match what is on the screen,
+ * otherwise this goes wrong.  May need to call out_flush() first.
+ */
+    void
+gui_update_cursor(force, clear_selection)
+    int		force;		/* when TRUE, update even when not moved */
+    int		clear_selection;/* clear selection under cursor */
+{
+    int		cur_width = 0;
+    int		cur_height = 0;
+    int		old_hl_mask;
+    int		idx;
+    int		id;
+    guicolor_T	cfg, cbg, cc;	/* cursor fore-/background color */
+    int		cattr;		/* cursor attributes */
+    int		attr;
+    attrentry_T *aep = NULL;
+
+    /* Don't update the cursor when halfway busy scrolling.
+     * ScreenLines[] isn't valid then. */
+    if (!can_update_cursor)
+	return;
+
+    gui_check_pos();
+    if (!gui.cursor_is_valid || force
+		    || gui.row != gui.cursor_row || gui.col != gui.cursor_col)
+    {
+	gui_undraw_cursor();
+	if (gui.row < 0)
+	    return;
+#ifdef USE_IM_CONTROL
+	if (gui.row != gui.cursor_row || gui.col != gui.cursor_col)
+	    im_set_position(gui.row, gui.col);
+#endif
+	gui.cursor_row = gui.row;
+	gui.cursor_col = gui.col;
+
+	/* Only write to the screen after ScreenLines[] has been initialized */
+	if (!screen_cleared || ScreenLines == NULL)
+	    return;
+
+	/* Clear the selection if we are about to write over it */
+	if (clear_selection)
+	    clip_may_clear_selection(gui.row, gui.row);
+	/* Check that the cursor is inside the shell (resizing may have made
+	 * it invalid) */
+	if (gui.row >= screen_Rows || gui.col >= screen_Columns)
+	    return;
+
+	gui.cursor_is_valid = TRUE;
+
+	/*
+	 * How the cursor is drawn depends on the current mode.
+	 */
+	idx = get_shape_idx(FALSE);
+	if (State & LANGMAP)
+	    id = shape_table[idx].id_lm;
+	else
+	    id = shape_table[idx].id;
+
+	/* get the colors and attributes for the cursor.  Default is inverted */
+	cfg = INVALCOLOR;
+	cbg = INVALCOLOR;
+	cattr = HL_INVERSE;
+	gui_mch_set_blinking(shape_table[idx].blinkwait,
+			     shape_table[idx].blinkon,
+			     shape_table[idx].blinkoff);
+	if (id > 0)
+	{
+	    cattr = syn_id2colors(id, &cfg, &cbg);
+#if defined(USE_IM_CONTROL) || defined(FEAT_HANGULIN)
+	    {
+		static int iid;
+		guicolor_T fg, bg;
+
+		if (im_get_status())
+		{
+		    iid = syn_name2id((char_u *)"CursorIM");
+		    if (iid > 0)
+		    {
+			syn_id2colors(iid, &fg, &bg);
+			if (bg != INVALCOLOR)
+			    cbg = bg;
+			if (fg != INVALCOLOR)
+			    cfg = fg;
+		    }
+		}
+	    }
+#endif
+	}
+
+	/*
+	 * Get the attributes for the character under the cursor.
+	 * When no cursor color was given, use the character color.
+	 */
+	attr = ScreenAttrs[LineOffset[gui.row] + gui.col];
+	if (attr > HL_ALL)
+	    aep = syn_gui_attr2entry(attr);
+	if (aep != NULL)
+	{
+	    attr = aep->ae_attr;
+	    if (cfg == INVALCOLOR)
+		cfg = ((attr & HL_INVERSE)  ? aep->ae_u.gui.bg_color
+					    : aep->ae_u.gui.fg_color);
+	    if (cbg == INVALCOLOR)
+		cbg = ((attr & HL_INVERSE)  ? aep->ae_u.gui.fg_color
+					    : aep->ae_u.gui.bg_color);
+	}
+	if (cfg == INVALCOLOR)
+	    cfg = (attr & HL_INVERSE) ? gui.back_pixel : gui.norm_pixel;
+	if (cbg == INVALCOLOR)
+	    cbg = (attr & HL_INVERSE) ? gui.norm_pixel : gui.back_pixel;
+
+#ifdef FEAT_XIM
+	if (aep != NULL)
+	{
+	    xim_bg_color = ((attr & HL_INVERSE) ? aep->ae_u.gui.fg_color
+						: aep->ae_u.gui.bg_color);
+	    xim_fg_color = ((attr & HL_INVERSE) ? aep->ae_u.gui.bg_color
+						: aep->ae_u.gui.fg_color);
+	    if (xim_bg_color == INVALCOLOR)
+		xim_bg_color = (attr & HL_INVERSE) ? gui.norm_pixel
+						   : gui.back_pixel;
+	    if (xim_fg_color == INVALCOLOR)
+		xim_fg_color = (attr & HL_INVERSE) ? gui.back_pixel
+						   : gui.norm_pixel;
+	}
+	else
+	{
+	    xim_bg_color = (attr & HL_INVERSE) ? gui.norm_pixel
+					       : gui.back_pixel;
+	    xim_fg_color = (attr & HL_INVERSE) ? gui.back_pixel
+					       : gui.norm_pixel;
+	}
+#endif
+
+	attr &= ~HL_INVERSE;
+	if (cattr & HL_INVERSE)
+	{
+	    cc = cbg;
+	    cbg = cfg;
+	    cfg = cc;
+	}
+	cattr &= ~HL_INVERSE;
+
+	/*
+	 * When we don't have window focus, draw a hollow cursor.
+	 */
+	if (!gui.in_focus)
+	{
+	    gui_mch_draw_hollow_cursor(cbg);
+	    return;
+	}
+
+	old_hl_mask = gui.highlight_mask;
+	if (shape_table[idx].shape == SHAPE_BLOCK
+#ifdef FEAT_HANGULIN
+		|| composing_hangul
+#endif
+	   )
+	{
+	    /*
+	     * Draw the text character with the cursor colors.	Use the
+	     * character attributes plus the cursor attributes.
+	     */
+	    gui.highlight_mask = (cattr | attr);
+#ifdef FEAT_HANGULIN
+	    if (composing_hangul)
+		(void)gui_outstr_nowrap(composing_hangul_buffer, 2,
+			GUI_MON_IS_CURSOR | GUI_MON_NOCLEAR, cfg, cbg, 0);
+	    else
+#endif
+		(void)gui_screenchar(LineOffset[gui.row] + gui.col,
+			GUI_MON_IS_CURSOR | GUI_MON_NOCLEAR, cfg, cbg, 0);
+	}
+	else
+	{
+#if defined(FEAT_MBYTE) && defined(FEAT_RIGHTLEFT)
+	    int	    col_off = FALSE;
+#endif
+	    /*
+	     * First draw the partial cursor, then overwrite with the text
+	     * character, using a transparent background.
+	     */
+	    if (shape_table[idx].shape == SHAPE_VER)
+	    {
+		cur_height = gui.char_height;
+		cur_width = (gui.char_width * shape_table[idx].percentage
+								  + 99) / 100;
+	    }
+	    else
+	    {
+		cur_height = (gui.char_height * shape_table[idx].percentage
+								  + 99) / 100;
+		cur_width = gui.char_width;
+	    }
+#ifdef FEAT_MBYTE
+	    if (has_mbyte && (*mb_off2cells)(LineOffset[gui.row] + gui.col) > 1)
+	    {
+		/* Double wide character. */
+		if (shape_table[idx].shape != SHAPE_VER)
+		    cur_width += gui.char_width;
+# ifdef FEAT_RIGHTLEFT
+		if (CURSOR_BAR_RIGHT)
+		{
+		    /* gui.col points to the left halve of the character but
+		     * the vertical line needs to be on the right halve.
+		     * A double-wide horizontal line is also drawn from the
+		     * right halve in gui_mch_draw_part_cursor(). */
+		    col_off = TRUE;
+		    ++gui.col;
+		}
+# endif
+	    }
+#endif
+	    gui_mch_draw_part_cursor(cur_width, cur_height, cbg);
+#if defined(FEAT_MBYTE) && defined(FEAT_RIGHTLEFT)
+	    if (col_off)
+		--gui.col;
+#endif
+
+#ifndef FEAT_GUI_MSWIN	    /* doesn't seem to work for MSWindows */
+	    gui.highlight_mask = ScreenAttrs[LineOffset[gui.row] + gui.col];
+	    (void)gui_screenchar(LineOffset[gui.row] + gui.col,
+		    GUI_MON_TRS_CURSOR | GUI_MON_NOCLEAR,
+		    (guicolor_T)0, (guicolor_T)0, 0);
+#endif
+	}
+	gui.highlight_mask = old_hl_mask;
+    }
+}
+
+#if defined(FEAT_MENU) || defined(PROTO)
+    void
+gui_position_menu()
+{
+# if !defined(FEAT_GUI_GTK) && !defined(FEAT_GUI_MOTIF)
+    if (gui.menu_is_active && gui.in_use)
+	gui_mch_set_menu_pos(0, 0, gui.menu_width, gui.menu_height);
+# endif
+}
+#endif
+
+/*
+ * Position the various GUI components (text area, menu).  The vertical
+ * scrollbars are NOT handled here.  See gui_update_scrollbars().
+ */
+/*ARGSUSED*/
+    static void
+gui_position_components(total_width)
+    int	    total_width;
+{
+    int	    text_area_x;
+    int	    text_area_y;
+    int	    text_area_width;
+    int	    text_area_height;
+
+    /* avoid that moving components around generates events */
+    ++hold_gui_events;
+
+    text_area_x = 0;
+    if (gui.which_scrollbars[SBAR_LEFT])
+	text_area_x += gui.scrollbar_width;
+
+    text_area_y = 0;
+#if defined(FEAT_MENU) && !(defined(FEAT_GUI_GTK) || defined(FEAT_GUI_PHOTON))
+    gui.menu_width = total_width;
+    if (gui.menu_is_active)
+	text_area_y += gui.menu_height;
+#endif
+#if defined(FEAT_TOOLBAR) && defined(FEAT_GUI_MSWIN)
+    if (vim_strchr(p_go, GO_TOOLBAR) != NULL)
+	text_area_y = TOOLBAR_BUTTON_HEIGHT + TOOLBAR_BORDER_HEIGHT;
+#endif
+
+# if defined(FEAT_GUI_TABLINE) && (defined(FEAT_GUI_MSWIN) \
+ 	|| defined(FEAT_GUI_MOTIF) || defined(FEAT_GUI_MAC))
+    if (gui_has_tabline())
+	text_area_y += gui.tabline_height;
+#endif
+
+#if defined(FEAT_TOOLBAR) && (defined(FEAT_GUI_MOTIF) || defined(FEAT_GUI_ATHENA))
+    if (vim_strchr(p_go, GO_TOOLBAR) != NULL)
+    {
+# ifdef FEAT_GUI_ATHENA
+	gui_mch_set_toolbar_pos(0, text_area_y,
+				gui.menu_width, gui.toolbar_height);
+# endif
+	text_area_y += gui.toolbar_height;
+    }
+#endif
+
+    text_area_width = gui.num_cols * gui.char_width + gui.border_offset * 2;
+    text_area_height = gui.num_rows * gui.char_height + gui.border_offset * 2;
+
+    gui_mch_set_text_area_pos(text_area_x,
+			      text_area_y,
+			      text_area_width,
+			      text_area_height
+#if defined(FEAT_XIM) && !defined(HAVE_GTK2)
+				  + xim_get_status_area_height()
+#endif
+			      );
+#ifdef FEAT_MENU
+    gui_position_menu();
+#endif
+    if (gui.which_scrollbars[SBAR_BOTTOM])
+	gui_mch_set_scrollbar_pos(&gui.bottom_sbar,
+				  text_area_x,
+				  text_area_y + text_area_height,
+				  text_area_width,
+				  gui.scrollbar_height);
+    gui.left_sbar_x = 0;
+    gui.right_sbar_x = text_area_x + text_area_width;
+
+    --hold_gui_events;
+}
+
+/*
+ * Get the width of the widgets and decorations to the side of the text area.
+ */
+    int
+gui_get_base_width()
+{
+    int	    base_width;
+
+    base_width = 2 * gui.border_offset;
+    if (gui.which_scrollbars[SBAR_LEFT])
+	base_width += gui.scrollbar_width;
+    if (gui.which_scrollbars[SBAR_RIGHT])
+	base_width += gui.scrollbar_width;
+    return base_width;
+}
+
+/*
+ * Get the height of the widgets and decorations above and below the text area.
+ */
+    int
+gui_get_base_height()
+{
+    int	    base_height;
+
+    base_height = 2 * gui.border_offset;
+    if (gui.which_scrollbars[SBAR_BOTTOM])
+	base_height += gui.scrollbar_height;
+#ifdef FEAT_GUI_GTK
+    /* We can't take the sizes properly into account until anything is
+     * realized.  Therefore we recalculate all the values here just before
+     * setting the size. (--mdcki) */
+#else
+# ifdef FEAT_MENU
+    if (gui.menu_is_active)
+	base_height += gui.menu_height;
+# endif
+# ifdef FEAT_TOOLBAR
+    if (vim_strchr(p_go, GO_TOOLBAR) != NULL)
+#  if defined(FEAT_GUI_MSWIN) && defined(FEAT_TOOLBAR)
+	base_height += (TOOLBAR_BUTTON_HEIGHT + TOOLBAR_BORDER_HEIGHT);
+#  else
+	base_height += gui.toolbar_height;
+#  endif
+# endif
+# if defined(FEAT_GUI_TABLINE) && (defined(FEAT_GUI_MSWIN) \
+	|| defined(FEAT_GUI_MOTIF))
+    if (gui_has_tabline())
+	base_height += gui.tabline_height;
+# endif
+# ifdef FEAT_FOOTER
+    if (vim_strchr(p_go, GO_FOOTER) != NULL)
+	base_height += gui.footer_height;
+# endif
+# if defined(FEAT_GUI_MOTIF) && defined(FEAT_MENU)
+    base_height += gui_mch_text_area_extra_height();
+# endif
+#endif
+    return base_height;
+}
+
+/*
+ * Should be called after the GUI shell has been resized.  Its arguments are
+ * the new width and height of the shell in pixels.
+ */
+    void
+gui_resize_shell(pixel_width, pixel_height)
+    int		pixel_width;
+    int		pixel_height;
+{
+    static int	busy = FALSE;
+
+    if (!gui.shell_created)	    /* ignore when still initializing */
+	return;
+
+    /*
+     * Can't resize the screen while it is being redrawn.  Remember the new
+     * size and handle it later.
+     */
+    if (updating_screen || busy)
+    {
+	new_pixel_width = pixel_width;
+	new_pixel_height = pixel_height;
+	return;
+    }
+
+again:
+    busy = TRUE;
+
+    /* Flush pending output before redrawing */
+    out_flush();
+
+    gui.num_cols = (pixel_width - gui_get_base_width()) / gui.char_width;
+    gui.num_rows = (pixel_height - gui_get_base_height()
+#if !defined(FEAT_GUI_PHOTON) && !defined(FEAT_GUI_MSWIN)
+				    + (gui.char_height / 2)
+#endif
+					) / gui.char_height;
+
+    gui_position_components(pixel_width);
+
+    gui_reset_scroll_region();
+    /*
+     * At the "more" and ":confirm" prompt there is no redraw, put the cursor
+     * at the last line here (why does it have to be one row too low?).
+     */
+    if (State == ASKMORE || State == CONFIRM)
+	gui.row = gui.num_rows;
+
+    /* Only comparing Rows and Columns may be sufficient, but let's stay on
+     * the safe side. */
+    if (gui.num_rows != screen_Rows || gui.num_cols != screen_Columns
+	    || gui.num_rows != Rows || gui.num_cols != Columns)
+	shell_resized();
+
+    gui_update_scrollbars(TRUE);
+    gui_update_cursor(FALSE, TRUE);
+#if defined(FEAT_XIM) && !defined(HAVE_GTK2)
+    xim_set_status_area();
+#endif
+
+    busy = FALSE;
+
+    /*
+     * We could have been called again while redrawing the screen.
+     * Need to do it all again with the latest size then.
+     */
+    if (new_pixel_height)
+    {
+	pixel_width = new_pixel_width;
+	pixel_height = new_pixel_height;
+	new_pixel_width = 0;
+	new_pixel_height = 0;
+	goto again;
+    }
+}
+
+/*
+ * Check if gui_resize_shell() must be called.
+ */
+    void
+gui_may_resize_shell()
+{
+    int		h, w;
+
+    if (new_pixel_height)
+    {
+	/* careful: gui_resize_shell() may postpone the resize again if we
+	 * were called indirectly by it */
+	w = new_pixel_width;
+	h = new_pixel_height;
+	new_pixel_width = 0;
+	new_pixel_height = 0;
+	gui_resize_shell(w, h);
+    }
+}
+
+    int
+gui_get_shellsize()
+{
+    Rows = gui.num_rows;
+    Columns = gui.num_cols;
+    return OK;
+}
+
+/*
+ * Set the size of the Vim shell according to Rows and Columns.
+ * If "fit_to_display" is TRUE then the size may be reduced to fit the window
+ * on the screen.
+ */
+/*ARGSUSED*/
+    void
+gui_set_shellsize(mustset, fit_to_display, direction)
+    int		mustset;		/* set by the user */
+    int		fit_to_display;
+    int		direction;		/* RESIZE_HOR, RESIZE_VER */
+{
+    int		base_width;
+    int		base_height;
+    int		width;
+    int		height;
+    int		min_width;
+    int		min_height;
+    int		screen_w;
+    int		screen_h;
+
+    if (!gui.shell_created)
+	return;
+
+#ifdef MSWIN
+    /* If not setting to a user specified size and maximized, calculate the
+     * number of characters that fit in the maximized window. */
+    if (!mustset && gui_mch_maximized())
+    {
+	gui_mch_newfont();
+	return;
+    }
+#endif
+
+    base_width = gui_get_base_width();
+    base_height = gui_get_base_height();
+#ifdef USE_SUN_WORKSHOP
+    if (!mustset && usingSunWorkShop
+				&& workshop_get_width_height(&width, &height))
+    {
+	Columns = (width - base_width + gui.char_width - 1) / gui.char_width;
+	Rows = (height - base_height + gui.char_height - 1) / gui.char_height;
+    }
+    else
+#endif
+    {
+	width = Columns * gui.char_width + base_width;
+	height = Rows * gui.char_height + base_height;
+    }
+
+    if (fit_to_display)
+    {
+	gui_mch_get_screen_dimensions(&screen_w, &screen_h);
+	if ((direction & RESIZE_HOR) && width > screen_w)
+	{
+	    Columns = (screen_w - base_width) / gui.char_width;
+	    if (Columns < MIN_COLUMNS)
+		Columns = MIN_COLUMNS;
+	    width = Columns * gui.char_width + base_width;
+	}
+	if ((direction & RESIZE_VERT) && height > screen_h)
+	{
+	    Rows = (screen_h - base_height) / gui.char_height;
+	    check_shellsize();
+	    height = Rows * gui.char_height + base_height;
+	}
+    }
+    gui.num_cols = Columns;
+    gui.num_rows = Rows;
+
+    min_width = base_width + MIN_COLUMNS * gui.char_width;
+    min_height = base_height + MIN_LINES * gui.char_height;
+# ifdef FEAT_WINDOWS
+    min_height += tabline_height() * gui.char_height;
+# endif
+
+    gui_mch_set_shellsize(width, height, min_width, min_height,
+					  base_width, base_height, direction);
+    if (fit_to_display)
+    {
+	int	    x, y;
+
+	/* Some window managers put the Vim window left of/above the screen. */
+	gui_mch_update();
+	if (gui_mch_get_winpos(&x, &y) == OK && (x < 0 || y < 0))
+	    gui_mch_set_winpos(x < 0 ? 0 : x, y < 0 ? 0 : y);
+    }
+
+    gui_position_components(width);
+    gui_update_scrollbars(TRUE);
+    gui_reset_scroll_region();
+}
+
+/*
+ * Called when Rows and/or Columns has changed.
+ */
+    void
+gui_new_shellsize()
+{
+    gui_reset_scroll_region();
+}
+
+/*
+ * Make scroll region cover whole screen.
+ */
+    void
+gui_reset_scroll_region()
+{
+    gui.scroll_region_top = 0;
+    gui.scroll_region_bot = gui.num_rows - 1;
+    gui.scroll_region_left = 0;
+    gui.scroll_region_right = gui.num_cols - 1;
+}
+
+    void
+gui_start_highlight(mask)
+    int	    mask;
+{
+    if (mask > HL_ALL)		    /* highlight code */
+	gui.highlight_mask = mask;
+    else			    /* mask */
+	gui.highlight_mask |= mask;
+}
+
+    void
+gui_stop_highlight(mask)
+    int	    mask;
+{
+    if (mask > HL_ALL)		    /* highlight code */
+	gui.highlight_mask = HL_NORMAL;
+    else			    /* mask */
+	gui.highlight_mask &= ~mask;
+}
+
+/*
+ * Clear a rectangular region of the screen from text pos (row1, col1) to
+ * (row2, col2) inclusive.
+ */
+    void
+gui_clear_block(row1, col1, row2, col2)
+    int	    row1;
+    int	    col1;
+    int	    row2;
+    int	    col2;
+{
+    /* Clear the selection if we are about to write over it */
+    clip_may_clear_selection(row1, row2);
+
+    gui_mch_clear_block(row1, col1, row2, col2);
+
+    /* Invalidate cursor if it was in this block */
+    if (       gui.cursor_row >= row1 && gui.cursor_row <= row2
+	    && gui.cursor_col >= col1 && gui.cursor_col <= col2)
+	gui.cursor_is_valid = FALSE;
+}
+
+/*
+ * Write code to update the cursor later.  This avoids the need to flush the
+ * output buffer before calling gui_update_cursor().
+ */
+    void
+gui_update_cursor_later()
+{
+    OUT_STR(IF_EB("\033|s", ESC_STR "|s"));
+}
+
+    void
+gui_write(s, len)
+    char_u	*s;
+    int		len;
+{
+    char_u	*p;
+    int		arg1 = 0, arg2 = 0;
+    /* this doesn't make sense, disabled until someone can explain why it
+     * would be needed */
+#if 0 && (defined(RISCOS) || defined(WIN16))
+    int		force_cursor = TRUE;	/* JK230798, stop Vim being smart or
+					   our redraw speed will suffer */
+#else
+    int		force_cursor = FALSE;	/* force cursor update */
+#endif
+    int		force_scrollbar = FALSE;
+    static win_T	*old_curwin = NULL;
+
+/* #define DEBUG_GUI_WRITE */
+#ifdef DEBUG_GUI_WRITE
+    {
+	int i;
+	char_u *str;
+
+	printf("gui_write(%d):\n    ", len);
+	for (i = 0; i < len; i++)
+	    if (s[i] == ESC)
+	    {
+		if (i != 0)
+		    printf("\n    ");
+		printf("<ESC>");
+	    }
+	    else
+	    {
+		str = transchar_byte(s[i]);
+		if (str[0] && str[1])
+		    printf("<%s>", (char *)str);
+		else
+		    printf("%s", (char *)str);
+	    }
+	printf("\n");
+    }
+#endif
+    while (len)
+    {
+	if (s[0] == ESC && s[1] == '|')
+	{
+	    p = s + 2;
+	    if (VIM_ISDIGIT(*p))
+	    {
+		arg1 = getdigits(&p);
+		if (p > s + len)
+		    break;
+		if (*p == ';')
+		{
+		    ++p;
+		    arg2 = getdigits(&p);
+		    if (p > s + len)
+			break;
+		}
+	    }
+	    switch (*p)
+	    {
+		case 'C':	/* Clear screen */
+		    clip_scroll_selection(9999);
+		    gui_mch_clear_all();
+		    gui.cursor_is_valid = FALSE;
+		    force_scrollbar = TRUE;
+		    break;
+		case 'M':	/* Move cursor */
+		    gui_set_cursor(arg1, arg2);
+		    break;
+		case 's':	/* force cursor (shape) update */
+		    force_cursor = TRUE;
+		    break;
+		case 'R':	/* Set scroll region */
+		    if (arg1 < arg2)
+		    {
+			gui.scroll_region_top = arg1;
+			gui.scroll_region_bot = arg2;
+		    }
+		    else
+		    {
+			gui.scroll_region_top = arg2;
+			gui.scroll_region_bot = arg1;
+		    }
+		    break;
+#ifdef FEAT_VERTSPLIT
+		case 'V':	/* Set vertical scroll region */
+		    if (arg1 < arg2)
+		    {
+			gui.scroll_region_left = arg1;
+			gui.scroll_region_right = arg2;
+		    }
+		    else
+		    {
+			gui.scroll_region_left = arg2;
+			gui.scroll_region_right = arg1;
+		    }
+		    break;
+#endif
+		case 'd':	/* Delete line */
+		    gui_delete_lines(gui.row, 1);
+		    break;
+		case 'D':	/* Delete lines */
+		    gui_delete_lines(gui.row, arg1);
+		    break;
+		case 'i':	/* Insert line */
+		    gui_insert_lines(gui.row, 1);
+		    break;
+		case 'I':	/* Insert lines */
+		    gui_insert_lines(gui.row, arg1);
+		    break;
+		case '$':	/* Clear to end-of-line */
+		    gui_clear_block(gui.row, gui.col, gui.row,
+							    (int)Columns - 1);
+		    break;
+		case 'h':	/* Turn on highlighting */
+		    gui_start_highlight(arg1);
+		    break;
+		case 'H':	/* Turn off highlighting */
+		    gui_stop_highlight(arg1);
+		    break;
+		case 'f':	/* flash the window (visual bell) */
+		    gui_mch_flash(arg1 == 0 ? 20 : arg1);
+		    break;
+		default:
+		    p = s + 1;	/* Skip the ESC */
+		    break;
+	    }
+	    len -= (int)(++p - s);
+	    s = p;
+	}
+	else if (
+#ifdef EBCDIC
+		CtrlChar(s[0]) != 0	/* Ctrl character */
+#else
+		s[0] < 0x20		/* Ctrl character */
+#endif
+#ifdef FEAT_SIGN_ICONS
+		&& s[0] != SIGN_BYTE
+# ifdef FEAT_NETBEANS_INTG
+		&& s[0] != MULTISIGN_BYTE
+# endif
+#endif
+		)
+	{
+	    if (s[0] == '\n')		/* NL */
+	    {
+		gui.col = 0;
+		if (gui.row < gui.scroll_region_bot)
+		    gui.row++;
+		else
+		    gui_delete_lines(gui.scroll_region_top, 1);
+	    }
+	    else if (s[0] == '\r')	/* CR */
+	    {
+		gui.col = 0;
+	    }
+	    else if (s[0] == '\b')	/* Backspace */
+	    {
+		if (gui.col)
+		    --gui.col;
+	    }
+	    else if (s[0] == Ctrl_L)	/* cursor-right */
+	    {
+		++gui.col;
+	    }
+	    else if (s[0] == Ctrl_G)	/* Beep */
+	    {
+		gui_mch_beep();
+	    }
+	    /* Other Ctrl character: shouldn't happen! */
+
+	    --len;	/* Skip this char */
+	    ++s;
+	}
+	else
+	{
+	    p = s;
+	    while (len > 0 && (
+#ifdef EBCDIC
+			CtrlChar(*p) == 0
+#else
+			*p >= 0x20
+#endif
+#ifdef FEAT_SIGN_ICONS
+			|| *p == SIGN_BYTE
+# ifdef FEAT_NETBEANS_INTG
+			|| *p == MULTISIGN_BYTE
+# endif
+#endif
+			))
+	    {
+		len--;
+		p++;
+	    }
+	    gui_outstr(s, (int)(p - s));
+	    s = p;
+	}
+    }
+
+    /* Postponed update of the cursor (won't work if "can_update_cursor" isn't
+     * set). */
+    if (force_cursor)
+	gui_update_cursor(TRUE, TRUE);
+
+    /* When switching to another window the dragging must have stopped.
+     * Required for GTK, dragged_sb isn't reset. */
+    if (old_curwin != curwin)
+	gui.dragged_sb = SBAR_NONE;
+
+    /* Update the scrollbars after clearing the screen or when switched
+     * to another window.
+     * Update the horizontal scrollbar always, it's difficult to check all
+     * situations where it might change. */
+    if (force_scrollbar || old_curwin != curwin)
+	gui_update_scrollbars(force_scrollbar);
+    else
+	gui_update_horiz_scrollbar(FALSE);
+    old_curwin = curwin;
+
+    /*
+     * We need to make sure this is cleared since Athena doesn't tell us when
+     * he is done dragging.  Do the same for GTK.
+     */
+#if defined(FEAT_GUI_ATHENA) || defined(FEAT_GUI_GTK)
+    gui.dragged_sb = SBAR_NONE;
+#endif
+
+    gui_mch_flush();		    /* In case vim decides to take a nap */
+}
+
+/*
+ * When ScreenLines[] is invalid, updating the cursor should not be done, it
+ * produces wrong results.  Call gui_dont_update_cursor() before that code and
+ * gui_can_update_cursor() afterwards.
+ */
+    void
+gui_dont_update_cursor()
+{
+    if (gui.in_use)
+    {
+	/* Undraw the cursor now, we probably can't do it after the change. */
+	gui_undraw_cursor();
+	can_update_cursor = FALSE;
+    }
+}
+
+    void
+gui_can_update_cursor()
+{
+    can_update_cursor = TRUE;
+    /* No need to update the cursor right now, there is always more output
+     * after scrolling. */
+}
+
+    static void
+gui_outstr(s, len)
+    char_u  *s;
+    int	    len;
+{
+    int	    this_len;
+#ifdef FEAT_MBYTE
+    int	    cells;
+#endif
+
+    if (len == 0)
+	return;
+
+    if (len < 0)
+	len = (int)STRLEN(s);
+
+    while (len > 0)
+    {
+#ifdef FEAT_MBYTE
+	if (has_mbyte)
+	{
+	    /* Find out how many chars fit in the current line. */
+	    cells = 0;
+	    for (this_len = 0; this_len < len; )
+	    {
+		cells += (*mb_ptr2cells)(s + this_len);
+		if (gui.col + cells > Columns)
+		    break;
+		this_len += (*mb_ptr2len)(s + this_len);
+	    }
+	    if (this_len > len)
+		this_len = len;	    /* don't include following composing char */
+	}
+	else
+#endif
+	    if (gui.col + len > Columns)
+	    this_len = Columns - gui.col;
+	else
+	    this_len = len;
+
+	(void)gui_outstr_nowrap(s, this_len,
+					  0, (guicolor_T)0, (guicolor_T)0, 0);
+	s += this_len;
+	len -= this_len;
+#ifdef FEAT_MBYTE
+	/* fill up for a double-width char that doesn't fit. */
+	if (len > 0 && gui.col < Columns)
+	    (void)gui_outstr_nowrap((char_u *)" ", 1,
+					  0, (guicolor_T)0, (guicolor_T)0, 0);
+#endif
+	/* The cursor may wrap to the next line. */
+	if (gui.col >= Columns)
+	{
+	    gui.col = 0;
+	    gui.row++;
+	}
+    }
+}
+
+/*
+ * Output one character (may be one or two display cells).
+ * Caller must check for valid "off".
+ * Returns FAIL or OK, just like gui_outstr_nowrap().
+ */
+    static int
+gui_screenchar(off, flags, fg, bg, back)
+    int		off;	    /* Offset from start of screen */
+    int		flags;
+    guicolor_T	fg, bg;	    /* colors for cursor */
+    int		back;	    /* backup this many chars when using bold trick */
+{
+#ifdef FEAT_MBYTE
+    char_u	buf[MB_MAXBYTES + 1];
+
+    /* Don't draw right halve of a double-width UTF-8 char. "cannot happen" */
+    if (enc_utf8 && ScreenLines[off] == 0)
+	return OK;
+
+    if (enc_utf8 && ScreenLinesUC[off] != 0)
+	/* Draw UTF-8 multi-byte character. */
+	return gui_outstr_nowrap(buf, utfc_char2bytes(off, buf),
+							 flags, fg, bg, back);
+
+    if (enc_dbcs == DBCS_JPNU && ScreenLines[off] == 0x8e)
+    {
+	buf[0] = ScreenLines[off];
+	buf[1] = ScreenLines2[off];
+	return gui_outstr_nowrap(buf, 2, flags, fg, bg, back);
+    }
+
+    /* Draw non-multi-byte character or DBCS character. */
+    return gui_outstr_nowrap(ScreenLines + off,
+	    enc_dbcs ? (*mb_ptr2len)(ScreenLines + off) : 1,
+							 flags, fg, bg, back);
+#else
+    return gui_outstr_nowrap(ScreenLines + off, 1, flags, fg, bg, back);
+#endif
+}
+
+#ifdef HAVE_GTK2
+/*
+ * Output the string at the given screen position.  This is used in place
+ * of gui_screenchar() where possible because Pango needs as much context
+ * as possible to work nicely.  It's a lot faster as well.
+ */
+    static int
+gui_screenstr(off, len, flags, fg, bg, back)
+    int		off;	    /* Offset from start of screen */
+    int		len;	    /* string length in screen cells */
+    int		flags;
+    guicolor_T	fg, bg;	    /* colors for cursor */
+    int		back;	    /* backup this many chars when using bold trick */
+{
+    char_u  *buf;
+    int	    outlen = 0;
+    int	    i;
+    int	    retval;
+
+    if (len <= 0) /* "cannot happen"? */
+	return OK;
+
+    if (enc_utf8)
+    {
+	buf = alloc((unsigned)(len * MB_MAXBYTES + 1));
+	if (buf == NULL)
+	    return OK; /* not much we could do here... */
+
+	for (i = off; i < off + len; ++i)
+	{
+	    if (ScreenLines[i] == 0)
+		continue; /* skip second half of double-width char */
+
+	    if (ScreenLinesUC[i] == 0)
+		buf[outlen++] = ScreenLines[i];
+	    else
+		outlen += utfc_char2bytes(i, buf + outlen);
+	}
+
+	buf[outlen] = NUL; /* only to aid debugging */
+	retval = gui_outstr_nowrap(buf, outlen, flags, fg, bg, back);
+	vim_free(buf);
+
+	return retval;
+    }
+    else if (enc_dbcs == DBCS_JPNU)
+    {
+	buf = alloc((unsigned)(len * 2 + 1));
+	if (buf == NULL)
+	    return OK; /* not much we could do here... */
+
+	for (i = off; i < off + len; ++i)
+	{
+	    buf[outlen++] = ScreenLines[i];
+
+	    /* handle double-byte single-width char */
+	    if (ScreenLines[i] == 0x8e)
+		buf[outlen++] = ScreenLines2[i];
+	    else if (MB_BYTE2LEN(ScreenLines[i]) == 2)
+		buf[outlen++] = ScreenLines[++i];
+	}
+
+	buf[outlen] = NUL; /* only to aid debugging */
+	retval = gui_outstr_nowrap(buf, outlen, flags, fg, bg, back);
+	vim_free(buf);
+
+	return retval;
+    }
+    else
+    {
+	return gui_outstr_nowrap(&ScreenLines[off], len,
+				 flags, fg, bg, back);
+    }
+}
+#endif /* HAVE_GTK2 */
+
+/*
+ * Output the given string at the current cursor position.  If the string is
+ * too long to fit on the line, then it is truncated.
+ * "flags":
+ * GUI_MON_IS_CURSOR should only be used when this function is being called to
+ * actually draw (an inverted) cursor.
+ * GUI_MON_TRS_CURSOR is used to draw the cursor text with a transparent
+ * background.
+ * GUI_MON_NOCLEAR is used to avoid clearing the selection when drawing over
+ * it.
+ * Returns OK, unless "back" is non-zero and using the bold trick, then return
+ * FAIL (the caller should start drawing "back" chars back).
+ */
+    int
+gui_outstr_nowrap(s, len, flags, fg, bg, back)
+    char_u	*s;
+    int		len;
+    int		flags;
+    guicolor_T	fg, bg;	    /* colors for cursor */
+    int		back;	    /* backup this many chars when using bold trick */
+{
+    long_u	highlight_mask;
+    long_u	hl_mask_todo;
+    guicolor_T	fg_color;
+    guicolor_T	bg_color;
+    guicolor_T	sp_color;
+#if !defined(MSWIN16_FASTTEXT) && !defined(HAVE_GTK2)
+    GuiFont	font = NOFONT;
+# ifdef FEAT_XFONTSET
+    GuiFontset	fontset = NOFONTSET;
+# endif
+#endif
+    attrentry_T	*aep = NULL;
+    int		draw_flags;
+    int		col = gui.col;
+#ifdef FEAT_SIGN_ICONS
+    int		draw_sign = FALSE;
+# ifdef FEAT_NETBEANS_INTG
+    int		multi_sign = FALSE;
+# endif
+#endif
+
+    if (len < 0)
+	len = (int)STRLEN(s);
+    if (len == 0)
+	return OK;
+
+#ifdef FEAT_SIGN_ICONS
+    if (*s == SIGN_BYTE
+# ifdef FEAT_NETBEANS_INTG
+	  || *s == MULTISIGN_BYTE
+# endif
+    )
+    {
+# ifdef FEAT_NETBEANS_INTG
+	if (*s == MULTISIGN_BYTE)
+	    multi_sign = TRUE;
+# endif
+	/* draw spaces instead */
+	s = (char_u *)"  ";
+	if (len == 1 && col > 0)
+	    --col;
+	len = 2;
+	draw_sign = TRUE;
+	highlight_mask = 0;
+    }
+    else
+#endif
+    if (gui.highlight_mask > HL_ALL)
+    {
+	aep = syn_gui_attr2entry(gui.highlight_mask);
+	if (aep == NULL)	    /* highlighting not set */
+	    highlight_mask = 0;
+	else
+	    highlight_mask = aep->ae_attr;
+    }
+    else
+	highlight_mask = gui.highlight_mask;
+    hl_mask_todo = highlight_mask;
+
+#if !defined(MSWIN16_FASTTEXT) && !defined(HAVE_GTK2)
+    /* Set the font */
+    if (aep != NULL && aep->ae_u.gui.font != NOFONT)
+	font = aep->ae_u.gui.font;
+# ifdef FEAT_XFONTSET
+    else if (aep != NULL && aep->ae_u.gui.fontset != NOFONTSET)
+	fontset = aep->ae_u.gui.fontset;
+# endif
+    else
+    {
+# ifdef FEAT_XFONTSET
+	if (gui.fontset != NOFONTSET)
+	    fontset = gui.fontset;
+	else
+# endif
+	    if (hl_mask_todo & (HL_BOLD | HL_STANDOUT))
+	{
+	    if ((hl_mask_todo & HL_ITALIC) && gui.boldital_font != NOFONT)
+	    {
+		font = gui.boldital_font;
+		hl_mask_todo &= ~(HL_BOLD | HL_STANDOUT | HL_ITALIC);
+	    }
+	    else if (gui.bold_font != NOFONT)
+	    {
+		font = gui.bold_font;
+		hl_mask_todo &= ~(HL_BOLD | HL_STANDOUT);
+	    }
+	    else
+		font = gui.norm_font;
+	}
+	else if ((hl_mask_todo & HL_ITALIC) && gui.ital_font != NOFONT)
+	{
+	    font = gui.ital_font;
+	    hl_mask_todo &= ~HL_ITALIC;
+	}
+	else
+	    font = gui.norm_font;
+    }
+# ifdef FEAT_XFONTSET
+    if (fontset != NOFONTSET)
+	gui_mch_set_fontset(fontset);
+    else
+# endif
+	gui_mch_set_font(font);
+#endif
+
+    draw_flags = 0;
+
+    /* Set the color */
+    bg_color = gui.back_pixel;
+    if ((flags & GUI_MON_IS_CURSOR) && gui.in_focus)
+    {
+	draw_flags |= DRAW_CURSOR;
+	fg_color = fg;
+	bg_color = bg;
+	sp_color = fg;
+    }
+    else if (aep != NULL)
+    {
+	fg_color = aep->ae_u.gui.fg_color;
+	if (fg_color == INVALCOLOR)
+	    fg_color = gui.norm_pixel;
+	bg_color = aep->ae_u.gui.bg_color;
+	if (bg_color == INVALCOLOR)
+	    bg_color = gui.back_pixel;
+	sp_color = aep->ae_u.gui.sp_color;
+	if (sp_color == INVALCOLOR)
+	    sp_color = fg_color;
+    }
+    else
+    {
+	fg_color = gui.norm_pixel;
+	sp_color = fg_color;
+    }
+
+    if (highlight_mask & (HL_INVERSE | HL_STANDOUT))
+    {
+#if defined(AMIGA) || defined(RISCOS)
+	gui_mch_set_colors(bg_color, fg_color);
+#else
+	gui_mch_set_fg_color(bg_color);
+	gui_mch_set_bg_color(fg_color);
+#endif
+    }
+    else
+    {
+#if defined(AMIGA) || defined(RISCOS)
+	gui_mch_set_colors(fg_color, bg_color);
+#else
+	gui_mch_set_fg_color(fg_color);
+	gui_mch_set_bg_color(bg_color);
+#endif
+    }
+    gui_mch_set_sp_color(sp_color);
+
+    /* Clear the selection if we are about to write over it */
+    if (!(flags & GUI_MON_NOCLEAR))
+	clip_may_clear_selection(gui.row, gui.row);
+
+
+#ifndef MSWIN16_FASTTEXT
+    /* If there's no bold font, then fake it */
+    if (hl_mask_todo & (HL_BOLD | HL_STANDOUT))
+	draw_flags |= DRAW_BOLD;
+#endif
+
+    /*
+     * When drawing bold or italic characters the spill-over from the left
+     * neighbor may be destroyed.  Let the caller backup to start redrawing
+     * just after a blank.
+     */
+    if (back != 0 && ((draw_flags & DRAW_BOLD) || (highlight_mask & HL_ITALIC)))
+	return FAIL;
+
+#if defined(RISCOS) || defined(HAVE_GTK2)
+    /* If there's no italic font, then fake it.
+     * For GTK2, we don't need a different font for italic style. */
+    if (hl_mask_todo & HL_ITALIC)
+	draw_flags |= DRAW_ITALIC;
+
+    /* Do we underline the text? */
+    if (hl_mask_todo & HL_UNDERLINE)
+	draw_flags |= DRAW_UNDERL;
+#else
+    /* Do we underline the text? */
+    if ((hl_mask_todo & HL_UNDERLINE)
+# ifndef MSWIN16_FASTTEXT
+	    || (hl_mask_todo & HL_ITALIC)
+# endif
+       )
+	draw_flags |= DRAW_UNDERL;
+#endif
+    /* Do we undercurl the text? */
+    if (hl_mask_todo & HL_UNDERCURL)
+	draw_flags |= DRAW_UNDERC;
+
+    /* Do we draw transparently? */
+    if (flags & GUI_MON_TRS_CURSOR)
+	draw_flags |= DRAW_TRANSP;
+
+    /*
+     * Draw the text.
+     */
+#ifdef HAVE_GTK2
+    /* The value returned is the length in display cells */
+    len = gui_gtk2_draw_string(gui.row, col, s, len, draw_flags);
+#else
+# ifdef FEAT_MBYTE
+    if (enc_utf8)
+    {
+	int	start;		/* index of bytes to be drawn */
+	int	cells;		/* cellwidth of bytes to be drawn */
+	int	thislen;	/* length of bytes to be drawin */
+	int	cn;		/* cellwidth of current char */
+	int	i;		/* index of current char */
+	int	c;		/* current char value */
+	int	cl;		/* byte length of current char */
+	int	comping;	/* current char is composing */
+	int	scol = col;	/* screen column */
+	int	dowide;		/* use 'guifontwide' */
+
+	/* Break the string at a composing character, it has to be drawn on
+	 * top of the previous character. */
+	start = 0;
+	cells = 0;
+	for (i = 0; i < len; i += cl)
+	{
+	    c = utf_ptr2char(s + i);
+	    cn = utf_char2cells(c);
+	    if (cn > 1
+#  ifdef FEAT_XFONTSET
+		    && fontset == NOFONTSET
+#  endif
+		    && gui.wide_font != NOFONT)
+		dowide = TRUE;
+	    else
+		dowide = FALSE;
+	    comping = utf_iscomposing(c);
+	    if (!comping)	/* count cells from non-composing chars */
+		cells += cn;
+	    cl = utf_ptr2len(s + i);
+	    if (cl == 0)	/* hit end of string */
+		len = i + cl;	/* len must be wrong "cannot happen" */
+
+	    /* print the string so far if it's the last character or there is
+	     * a composing character. */
+	    if (i + cl >= len || (comping && i > start) || dowide
+#  if defined(FEAT_GUI_X11) || defined(FEAT_GUI_GTK)
+		    || (cn > 1
+#   ifdef FEAT_XFONTSET
+			/* No fontset: At least draw char after wide char at
+			 * right position. */
+			&& fontset == NOFONTSET
+#   endif
+		       )
+#  endif
+	       )
+	    {
+		if (comping || dowide)
+		    thislen = i - start;
+		else
+		    thislen = i - start + cl;
+		if (thislen > 0)
+		{
+		    gui_mch_draw_string(gui.row, scol, s + start, thislen,
+								  draw_flags);
+		    start += thislen;
+		}
+		scol += cells;
+		cells = 0;
+		if (dowide)
+		{
+		    gui_mch_set_font(gui.wide_font);
+		    gui_mch_draw_string(gui.row, scol - cn,
+						   s + start, cl, draw_flags);
+		    gui_mch_set_font(font);
+		    start += cl;
+		}
+
+#  if defined(FEAT_GUI_X11) || defined(FEAT_GUI_GTK)
+		/* No fontset: draw a space to fill the gap after a wide char
+		 * */
+		if (cn > 1 && (draw_flags & DRAW_TRANSP) == 0
+#   ifdef FEAT_XFONTSET
+			&& fontset == NOFONTSET
+#   endif
+			&& !dowide)
+		    gui_mch_draw_string(gui.row, scol - 1, (char_u *)" ",
+							       1, draw_flags);
+#  endif
+	    }
+	    /* Draw a composing char on top of the previous char. */
+	    if (comping)
+	    {
+#  if (defined(__APPLE_CC__) || defined(__MRC__)) && TARGET_API_MAC_CARBON
+		/* Carbon ATSUI autodraws composing char over previous char */
+		gui_mch_draw_string(gui.row, scol, s + i, cl,
+						    draw_flags | DRAW_TRANSP);
+#  else
+		gui_mch_draw_string(gui.row, scol - cn, s + i, cl,
+						    draw_flags | DRAW_TRANSP);
+#  endif
+		start = i + cl;
+	    }
+	}
+	/* The stuff below assumes "len" is the length in screen columns. */
+	len = scol - col;
+    }
+    else
+# endif
+    {
+	gui_mch_draw_string(gui.row, col, s, len, draw_flags);
+# ifdef FEAT_MBYTE
+	if (enc_dbcs == DBCS_JPNU)
+	{
+	    int		clen = 0;
+	    int		i;
+
+	    /* Get the length in display cells, this can be different from the
+	     * number of bytes for "euc-jp". */
+	    for (i = 0; i < len; i += (*mb_ptr2len)(s + i))
+		clen += (*mb_ptr2cells)(s + i);
+	    len = clen;
+	}
+# endif
+    }
+#endif /* !HAVE_GTK2 */
+
+    if (!(flags & (GUI_MON_IS_CURSOR | GUI_MON_TRS_CURSOR)))
+	gui.col = col + len;
+
+    /* May need to invert it when it's part of the selection. */
+    if (flags & GUI_MON_NOCLEAR)
+	clip_may_redraw_selection(gui.row, col, len);
+
+    if (!(flags & (GUI_MON_IS_CURSOR | GUI_MON_TRS_CURSOR)))
+    {
+	/* Invalidate the old physical cursor position if we wrote over it */
+	if (gui.cursor_row == gui.row
+		&& gui.cursor_col >= col
+		&& gui.cursor_col < col + len)
+	    gui.cursor_is_valid = FALSE;
+    }
+
+#ifdef FEAT_SIGN_ICONS
+    if (draw_sign)
+	/* Draw the sign on top of the spaces. */
+	gui_mch_drawsign(gui.row, col, gui.highlight_mask);
+# ifdef FEAT_NETBEANS_INTG
+    if (multi_sign)
+	netbeans_draw_multisign_indicator(gui.row);
+# endif
+#endif
+
+    return OK;
+}
+
+/*
+ * Un-draw the cursor.	Actually this just redraws the character at the given
+ * position.  The character just before it too, for when it was in bold.
+ */
+    void
+gui_undraw_cursor()
+{
+    if (gui.cursor_is_valid)
+    {
+#ifdef FEAT_HANGULIN
+	if (composing_hangul
+		    && gui.col == gui.cursor_col && gui.row == gui.cursor_row)
+	    (void)gui_outstr_nowrap(composing_hangul_buffer, 2,
+		    GUI_MON_IS_CURSOR | GUI_MON_NOCLEAR,
+		    gui.norm_pixel, gui.back_pixel, 0);
+	else
+	{
+#endif
+	if (gui_redraw_block(gui.cursor_row, gui.cursor_col,
+			      gui.cursor_row, gui.cursor_col, GUI_MON_NOCLEAR)
+		&& gui.cursor_col > 0)
+	    (void)gui_redraw_block(gui.cursor_row, gui.cursor_col - 1,
+			 gui.cursor_row, gui.cursor_col - 1, GUI_MON_NOCLEAR);
+#ifdef FEAT_HANGULIN
+	    if (composing_hangul)
+		(void)gui_redraw_block(gui.cursor_row, gui.cursor_col + 1,
+			gui.cursor_row, gui.cursor_col + 1, GUI_MON_NOCLEAR);
+	}
+#endif
+	/* Cursor_is_valid is reset when the cursor is undrawn, also reset it
+	 * here in case it wasn't needed to undraw it. */
+	gui.cursor_is_valid = FALSE;
+    }
+}
+
+    void
+gui_redraw(x, y, w, h)
+    int		x;
+    int		y;
+    int		w;
+    int		h;
+{
+    int		row1, col1, row2, col2;
+
+    row1 = Y_2_ROW(y);
+    col1 = X_2_COL(x);
+    row2 = Y_2_ROW(y + h - 1);
+    col2 = X_2_COL(x + w - 1);
+
+    (void)gui_redraw_block(row1, col1, row2, col2, GUI_MON_NOCLEAR);
+
+    /*
+     * We may need to redraw the cursor, but don't take it upon us to change
+     * its location after a scroll.
+     * (maybe be more strict even and test col too?)
+     * These things may be outside the update/clipping region and reality may
+     * not reflect Vims internal ideas if these operations are clipped away.
+     */
+    if (gui.row == gui.cursor_row)
+	gui_update_cursor(TRUE, TRUE);
+}
+
+/*
+ * Draw a rectangular block of characters, from row1 to row2 (inclusive) and
+ * from col1 to col2 (inclusive).
+ * Return TRUE when the character before the first drawn character has
+ * different attributes (may have to be redrawn too).
+ */
+    int
+gui_redraw_block(row1, col1, row2, col2, flags)
+    int		row1;
+    int		col1;
+    int		row2;
+    int		col2;
+    int		flags;	/* flags for gui_outstr_nowrap() */
+{
+    int		old_row, old_col;
+    long_u	old_hl_mask;
+    int		off;
+    sattr_T	first_attr;
+    int		idx, len;
+    int		back, nback;
+    int		retval = FALSE;
+#ifdef FEAT_MBYTE
+    int		orig_col1, orig_col2;
+#endif
+
+    /* Don't try to update when ScreenLines is not valid */
+    if (!screen_cleared || ScreenLines == NULL)
+	return retval;
+
+    /* Don't try to draw outside the shell! */
+    /* Check everything, strange values may be caused by a big border width */
+    col1 = check_col(col1);
+    col2 = check_col(col2);
+    row1 = check_row(row1);
+    row2 = check_row(row2);
+
+    /* Remember where our cursor was */
+    old_row = gui.row;
+    old_col = gui.col;
+    old_hl_mask = gui.highlight_mask;
+#ifdef FEAT_MBYTE
+    orig_col1 = col1;
+    orig_col2 = col2;
+#endif
+
+    for (gui.row = row1; gui.row <= row2; gui.row++)
+    {
+#ifdef FEAT_MBYTE
+	/* When only half of a double-wide character is in the block, include
+	 * the other half. */
+	col1 = orig_col1;
+	col2 = orig_col2;
+	off = LineOffset[gui.row];
+	if (enc_dbcs != 0)
+	{
+	    if (col1 > 0)
+		col1 -= dbcs_screen_head_off(ScreenLines + off,
+						    ScreenLines + off + col1);
+	    col2 += dbcs_screen_tail_off(ScreenLines + off,
+						    ScreenLines + off + col2);
+	}
+	else if (enc_utf8)
+	{
+	    if (ScreenLines[off + col1] == 0)
+		--col1;
+# ifdef HAVE_GTK2
+	    if (col2 + 1 < Columns && ScreenLines[off + col2 + 1] == 0)
+		++col2;
+# endif
+	}
+#endif
+	gui.col = col1;
+	off = LineOffset[gui.row] + gui.col;
+	len = col2 - col1 + 1;
+
+	/* Find how many chars back this highlighting starts, or where a space
+	 * is.  Needed for when the bold trick is used */
+	for (back = 0; back < col1; ++back)
+	    if (ScreenAttrs[off - 1 - back] != ScreenAttrs[off]
+		    || ScreenLines[off - 1 - back] == ' ')
+		break;
+	retval = (col1 > 0 && ScreenAttrs[off - 1] != 0 && back == 0
+					      && ScreenLines[off - 1] != ' ');
+
+	/* Break it up in strings of characters with the same attributes. */
+	/* Print UTF-8 characters individually. */
+	while (len > 0)
+	{
+	    first_attr = ScreenAttrs[off];
+	    gui.highlight_mask = first_attr;
+#if defined(FEAT_MBYTE) && !defined(HAVE_GTK2)
+	    if (enc_utf8 && ScreenLinesUC[off] != 0)
+	    {
+		/* output multi-byte character separately */
+		nback = gui_screenchar(off, flags,
+					  (guicolor_T)0, (guicolor_T)0, back);
+		if (gui.col < Columns && ScreenLines[off + 1] == 0)
+		    idx = 2;
+		else
+		    idx = 1;
+	    }
+	    else if (enc_dbcs == DBCS_JPNU && ScreenLines[off] == 0x8e)
+	    {
+		/* output double-byte, single-width character separately */
+		nback = gui_screenchar(off, flags,
+					  (guicolor_T)0, (guicolor_T)0, back);
+		idx = 1;
+	    }
+	    else
+#endif
+	    {
+#ifdef HAVE_GTK2
+		for (idx = 0; idx < len; ++idx)
+		{
+		    if (enc_utf8 && ScreenLines[off + idx] == 0)
+			continue; /* skip second half of double-width char */
+		    if (ScreenAttrs[off + idx] != first_attr)
+			break;
+		}
+		/* gui_screenstr() takes care of multibyte chars */
+		nback = gui_screenstr(off, idx, flags,
+				      (guicolor_T)0, (guicolor_T)0, back);
+#else
+		for (idx = 0; idx < len && ScreenAttrs[off + idx] == first_attr;
+									idx++)
+		{
+# ifdef FEAT_MBYTE
+		    /* Stop at a multi-byte Unicode character. */
+		    if (enc_utf8 && ScreenLinesUC[off + idx] != 0)
+			break;
+		    if (enc_dbcs == DBCS_JPNU)
+		    {
+			/* Stop at a double-byte single-width char. */
+			if (ScreenLines[off + idx] == 0x8e)
+			    break;
+			if (len > 1 && (*mb_ptr2len)(ScreenLines
+							    + off + idx) == 2)
+			    ++idx;  /* skip second byte of double-byte char */
+		    }
+# endif
+		}
+		nback = gui_outstr_nowrap(ScreenLines + off, idx, flags,
+					  (guicolor_T)0, (guicolor_T)0, back);
+#endif
+	    }
+	    if (nback == FAIL)
+	    {
+		/* Must back up to start drawing where a bold or italic word
+		 * starts. */
+		off -= back;
+		len += back;
+		gui.col -= back;
+	    }
+	    else
+	    {
+		off += idx;
+		len -= idx;
+	    }
+	    back = 0;
+	}
+    }
+
+    /* Put the cursor back where it was */
+    gui.row = old_row;
+    gui.col = old_col;
+    gui.highlight_mask = (int)old_hl_mask;
+
+    return retval;
+}
+
+    static void
+gui_delete_lines(row, count)
+    int	    row;
+    int	    count;
+{
+    if (count <= 0)
+	return;
+
+    if (row + count > gui.scroll_region_bot)
+	/* Scrolled out of region, just blank the lines out */
+	gui_clear_block(row, gui.scroll_region_left,
+			      gui.scroll_region_bot, gui.scroll_region_right);
+    else
+    {
+	gui_mch_delete_lines(row, count);
+
+	/* If the cursor was in the deleted lines it's now gone.  If the
+	 * cursor was in the scrolled lines adjust its position. */
+	if (gui.cursor_row >= row
+		&& gui.cursor_col >= gui.scroll_region_left
+		&& gui.cursor_col <= gui.scroll_region_right)
+	{
+	    if (gui.cursor_row < row + count)
+		gui.cursor_is_valid = FALSE;
+	    else if (gui.cursor_row <= gui.scroll_region_bot)
+		gui.cursor_row -= count;
+	}
+    }
+}
+
+    static void
+gui_insert_lines(row, count)
+    int	    row;
+    int	    count;
+{
+    if (count <= 0)
+	return;
+
+    if (row + count > gui.scroll_region_bot)
+	/* Scrolled out of region, just blank the lines out */
+	gui_clear_block(row, gui.scroll_region_left,
+			      gui.scroll_region_bot, gui.scroll_region_right);
+    else
+    {
+	gui_mch_insert_lines(row, count);
+
+	if (gui.cursor_row >= gui.row
+		&& gui.cursor_col >= gui.scroll_region_left
+		&& gui.cursor_col <= gui.scroll_region_right)
+	{
+	    if (gui.cursor_row <= gui.scroll_region_bot - count)
+		gui.cursor_row += count;
+	    else if (gui.cursor_row <= gui.scroll_region_bot)
+		gui.cursor_is_valid = FALSE;
+	}
+    }
+}
+
+/*
+ * The main GUI input routine.	Waits for a character from the keyboard.
+ * wtime == -1	    Wait forever.
+ * wtime == 0	    Don't wait.
+ * wtime > 0	    Wait wtime milliseconds for a character.
+ * Returns OK if a character was found to be available within the given time,
+ * or FAIL otherwise.
+ */
+    int
+gui_wait_for_chars(wtime)
+    long    wtime;
+{
+    int	    retval;
+
+    /*
+     * If we're going to wait a bit, update the menus and mouse shape for the
+     * current State.
+     */
+    if (wtime != 0)
+    {
+#ifdef FEAT_MENU
+	gui_update_menus(0);
+#endif
+    }
+
+    gui_mch_update();
+    if (input_available())	/* Got char, return immediately */
+	return OK;
+    if (wtime == 0)	/* Don't wait for char */
+	return FAIL;
+
+    /* Before waiting, flush any output to the screen. */
+    gui_mch_flush();
+
+    if (wtime > 0)
+    {
+	/* Blink when waiting for a character.	Probably only does something
+	 * for showmatch() */
+	gui_mch_start_blink();
+	retval = gui_mch_wait_for_chars(wtime);
+	gui_mch_stop_blink();
+	return retval;
+    }
+
+    /*
+     * While we are waiting indefinitely for a character, blink the cursor.
+     */
+    gui_mch_start_blink();
+
+    retval = FAIL;
+    /*
+     * We may want to trigger the CursorHold event.  First wait for
+     * 'updatetime' and if nothing is typed within that time put the
+     * K_CURSORHOLD key in the input buffer.
+     */
+    if (gui_mch_wait_for_chars(p_ut) == OK)
+	retval = OK;
+#ifdef FEAT_AUTOCMD
+    else if (trigger_cursorhold())
+    {
+	char_u	buf[3];
+
+	/* Put K_CURSORHOLD in the input buffer. */
+	buf[0] = CSI;
+	buf[1] = KS_EXTRA;
+	buf[2] = (int)KE_CURSORHOLD;
+	add_to_input_buf(buf, 3);
+
+	retval = OK;
+    }
+#endif
+
+    if (retval == FAIL)
+    {
+	/* Blocking wait. */
+	before_blocking();
+	retval = gui_mch_wait_for_chars(-1L);
+    }
+
+    gui_mch_stop_blink();
+    return retval;
+}
+
+/*
+ * Fill p[4] with mouse coordinates encoded for check_termcode().
+ */
+    static void
+fill_mouse_coord(p, col, row)
+    char_u	*p;
+    int		col;
+    int		row;
+{
+    p[0] = (char_u)(col / 128 + ' ' + 1);
+    p[1] = (char_u)(col % 128 + ' ' + 1);
+    p[2] = (char_u)(row / 128 + ' ' + 1);
+    p[3] = (char_u)(row % 128 + ' ' + 1);
+}
+
+/*
+ * Generic mouse support function.  Add a mouse event to the input buffer with
+ * the given properties.
+ *  button	    --- may be any of MOUSE_LEFT, MOUSE_MIDDLE, MOUSE_RIGHT,
+ *			MOUSE_X1, MOUSE_X2
+ *			MOUSE_DRAG, or MOUSE_RELEASE.
+ *			MOUSE_4 and MOUSE_5 are used for a scroll wheel.
+ *  x, y	    --- Coordinates of mouse in pixels.
+ *  repeated_click  --- TRUE if this click comes only a short time after a
+ *			previous click.
+ *  modifiers	    --- Bit field which may be any of the following modifiers
+ *			or'ed together: MOUSE_SHIFT | MOUSE_CTRL | MOUSE_ALT.
+ * This function will ignore drag events where the mouse has not moved to a new
+ * character.
+ */
+    void
+gui_send_mouse_event(button, x, y, repeated_click, modifiers)
+    int	    button;
+    int	    x;
+    int	    y;
+    int	    repeated_click;
+    int_u   modifiers;
+{
+    static int	    prev_row = 0, prev_col = 0;
+    static int	    prev_button = -1;
+    static int	    num_clicks = 1;
+    char_u	    string[10];
+    enum key_extra  button_char;
+    int		    row, col;
+#ifdef FEAT_CLIPBOARD
+    int		    checkfor;
+    int		    did_clip = FALSE;
+#endif
+
+    /*
+     * Scrolling may happen at any time, also while a selection is present.
+     */
+    switch (button)
+    {
+	case MOUSE_X1:
+	    button_char = KE_X1MOUSE;
+	    goto button_set;
+	case MOUSE_X2:
+	    button_char = KE_X2MOUSE;
+	    goto button_set;
+	case MOUSE_4:
+	    button_char = KE_MOUSEDOWN;
+	    goto button_set;
+	case MOUSE_5:
+	    button_char = KE_MOUSEUP;
+button_set:
+	    {
+		/* Don't put events in the input queue now. */
+		if (hold_gui_events)
+		    return;
+
+		string[3] = CSI;
+		string[4] = KS_EXTRA;
+		string[5] = (int)button_char;
+
+		/* Pass the pointer coordinates of the scroll event so that we
+		 * know which window to scroll. */
+		row = gui_xy2colrow(x, y, &col);
+		string[6] = (char_u)(col / 128 + ' ' + 1);
+		string[7] = (char_u)(col % 128 + ' ' + 1);
+		string[8] = (char_u)(row / 128 + ' ' + 1);
+		string[9] = (char_u)(row % 128 + ' ' + 1);
+
+		if (modifiers == 0)
+		    add_to_input_buf(string + 3, 7);
+		else
+		{
+		    string[0] = CSI;
+		    string[1] = KS_MODIFIER;
+		    string[2] = 0;
+		    if (modifiers & MOUSE_SHIFT)
+			string[2] |= MOD_MASK_SHIFT;
+		    if (modifiers & MOUSE_CTRL)
+			string[2] |= MOD_MASK_CTRL;
+		    if (modifiers & MOUSE_ALT)
+			string[2] |= MOD_MASK_ALT;
+		    add_to_input_buf(string, 10);
+		}
+		return;
+	    }
+    }
+
+#ifdef FEAT_CLIPBOARD
+    /* If a clipboard selection is in progress, handle it */
+    if (clip_star.state == SELECT_IN_PROGRESS)
+    {
+	clip_process_selection(button, X_2_COL(x), Y_2_ROW(y), repeated_click);
+	return;
+    }
+
+    /* Determine which mouse settings to look for based on the current mode */
+    switch (get_real_state())
+    {
+	case NORMAL_BUSY:
+	case OP_PENDING:
+	case NORMAL:		checkfor = MOUSE_NORMAL;	break;
+	case VISUAL:		checkfor = MOUSE_VISUAL;	break;
+	case SELECTMODE:	checkfor = MOUSE_VISUAL;	break;
+	case REPLACE:
+	case REPLACE+LANGMAP:
+#ifdef FEAT_VREPLACE
+	case VREPLACE:
+	case VREPLACE+LANGMAP:
+#endif
+	case INSERT:
+	case INSERT+LANGMAP:	checkfor = MOUSE_INSERT;	break;
+	case ASKMORE:
+	case HITRETURN:		/* At the more- and hit-enter prompt pass the
+				   mouse event for a click on or below the
+				   message line. */
+				if (Y_2_ROW(y) >= msg_row)
+				    checkfor = MOUSE_NORMAL;
+				else
+				    checkfor = MOUSE_RETURN;
+				break;
+
+	    /*
+	     * On the command line, use the clipboard selection on all lines
+	     * but the command line.  But not when pasting.
+	     */
+	case CMDLINE:
+	case CMDLINE+LANGMAP:
+	    if (Y_2_ROW(y) < cmdline_row && button != MOUSE_MIDDLE)
+		checkfor = MOUSE_NONE;
+	    else
+		checkfor = MOUSE_COMMAND;
+	    break;
+
+	default:
+	    checkfor = MOUSE_NONE;
+	    break;
+    };
+
+    /*
+     * Allow clipboard selection of text on the command line in "normal"
+     * modes.  Don't do this when dragging the status line, or extending a
+     * Visual selection.
+     */
+    if ((State == NORMAL || State == NORMAL_BUSY || (State & INSERT))
+	    && Y_2_ROW(y) >= topframe->fr_height
+# ifdef FEAT_WINDOWS
+						+ firstwin->w_winrow
+# endif
+	    && button != MOUSE_DRAG
+# ifdef FEAT_MOUSESHAPE
+	    && !drag_status_line
+#  ifdef FEAT_VERTSPLIT
+	    && !drag_sep_line
+#  endif
+# endif
+	    )
+	checkfor = MOUSE_NONE;
+
+    /*
+     * Use modeless selection when holding CTRL and SHIFT pressed.
+     */
+    if ((modifiers & MOUSE_CTRL) && (modifiers & MOUSE_SHIFT))
+	checkfor = MOUSE_NONEF;
+
+    /*
+     * In Ex mode, always use modeless selection.
+     */
+    if (exmode_active)
+	checkfor = MOUSE_NONE;
+
+    /*
+     * If the mouse settings say to not use the mouse, use the modeless
+     * selection.  But if Visual is active, assume that only the Visual area
+     * will be selected.
+     * Exception: On the command line, both the selection is used and a mouse
+     * key is send.
+     */
+    if (!mouse_has(checkfor) || checkfor == MOUSE_COMMAND)
+    {
+#ifdef FEAT_VISUAL
+	/* Don't do modeless selection in Visual mode. */
+	if (checkfor != MOUSE_NONEF && VIsual_active && (State & NORMAL))
+	    return;
+#endif
+
+	/*
+	 * When 'mousemodel' is "popup", shift-left is translated to right.
+	 * But not when also using Ctrl.
+	 */
+	if (mouse_model_popup() && button == MOUSE_LEFT
+		&& (modifiers & MOUSE_SHIFT) && !(modifiers & MOUSE_CTRL))
+	{
+	    button = MOUSE_RIGHT;
+	    modifiers &= ~ MOUSE_SHIFT;
+	}
+
+	/* If the selection is done, allow the right button to extend it.
+	 * If the selection is cleared, allow the right button to start it
+	 * from the cursor position. */
+	if (button == MOUSE_RIGHT)
+	{
+	    if (clip_star.state == SELECT_CLEARED)
+	    {
+		if (State & CMDLINE)
+		{
+		    col = msg_col;
+		    row = msg_row;
+		}
+		else
+		{
+		    col = curwin->w_wcol;
+		    row = curwin->w_wrow + W_WINROW(curwin);
+		}
+		clip_start_selection(col, row, FALSE);
+	    }
+	    clip_process_selection(button, X_2_COL(x), Y_2_ROW(y),
+							      repeated_click);
+	    did_clip = TRUE;
+	}
+	/* Allow the left button to start the selection */
+	else if (button ==
+# ifdef RISCOS
+		/* Only start a drag on a drag event. Otherwise
+		 * we don't get a release event. */
+		    MOUSE_DRAG
+# else
+		    MOUSE_LEFT
+# endif
+				)
+	{
+	    clip_start_selection(X_2_COL(x), Y_2_ROW(y), repeated_click);
+	    did_clip = TRUE;
+	}
+# ifdef RISCOS
+	else if (button == MOUSE_LEFT)
+	{
+	    clip_clear_selection();
+	    did_clip = TRUE;
+	}
+# endif
+
+	/* Always allow pasting */
+	if (button != MOUSE_MIDDLE)
+	{
+	    if (!mouse_has(checkfor) || button == MOUSE_RELEASE)
+		return;
+	    if (checkfor != MOUSE_COMMAND)
+		button = MOUSE_LEFT;
+	}
+	repeated_click = FALSE;
+    }
+
+    if (clip_star.state != SELECT_CLEARED && !did_clip)
+	clip_clear_selection();
+#endif
+
+    /* Don't put events in the input queue now. */
+    if (hold_gui_events)
+	return;
+
+    row = gui_xy2colrow(x, y, &col);
+
+    /*
+     * If we are dragging and the mouse hasn't moved far enough to be on a
+     * different character, then don't send an event to vim.
+     */
+    if (button == MOUSE_DRAG)
+    {
+	if (row == prev_row && col == prev_col)
+	    return;
+	/* Dragging above the window, set "row" to -1 to cause a scroll. */
+	if (y < 0)
+	    row = -1;
+    }
+
+    /*
+     * If topline has changed (window scrolled) since the last click, reset
+     * repeated_click, because we don't want starting Visual mode when
+     * clicking on a different character in the text.
+     */
+    if (curwin->w_topline != gui_prev_topline
+#ifdef FEAT_DIFF
+	    || curwin->w_topfill != gui_prev_topfill
+#endif
+	    )
+	repeated_click = FALSE;
+
+    string[0] = CSI;	/* this sequence is recognized by check_termcode() */
+    string[1] = KS_MOUSE;
+    string[2] = KE_FILLER;
+    if (button != MOUSE_DRAG && button != MOUSE_RELEASE)
+    {
+	if (repeated_click)
+	{
+	    /*
+	     * Handle multiple clicks.	They only count if the mouse is still
+	     * pointing at the same character.
+	     */
+	    if (button != prev_button || row != prev_row || col != prev_col)
+		num_clicks = 1;
+	    else if (++num_clicks > 4)
+		num_clicks = 1;
+	}
+	else
+	    num_clicks = 1;
+	prev_button = button;
+	gui_prev_topline = curwin->w_topline;
+#ifdef FEAT_DIFF
+	gui_prev_topfill = curwin->w_topfill;
+#endif
+
+	string[3] = (char_u)(button | 0x20);
+	SET_NUM_MOUSE_CLICKS(string[3], num_clicks);
+    }
+    else
+	string[3] = (char_u)button;
+
+    string[3] |= modifiers;
+    fill_mouse_coord(string + 4, col, row);
+    add_to_input_buf(string, 8);
+
+    if (row < 0)
+	prev_row = 0;
+    else
+	prev_row = row;
+    prev_col = col;
+
+    /*
+     * We need to make sure this is cleared since Athena doesn't tell us when
+     * he is done dragging.  Neither does GTK+ 2 -- at least for now.
+     */
+#if defined(FEAT_GUI_ATHENA) || defined(HAVE_GTK2)
+    gui.dragged_sb = SBAR_NONE;
+#endif
+}
+
+/*
+ * Convert x and y coordinate to column and row in text window.
+ * Corrects for multi-byte character.
+ * returns column in "*colp" and row as return value;
+ */
+    int
+gui_xy2colrow(x, y, colp)
+    int		x;
+    int		y;
+    int		*colp;
+{
+    int		col = check_col(X_2_COL(x));
+    int		row = check_row(Y_2_ROW(y));
+
+#ifdef FEAT_MBYTE
+    *colp = mb_fix_col(col, row);
+#else
+    *colp = col;
+#endif
+    return row;
+}
+
+#if defined(FEAT_MENU) || defined(PROTO)
+/*
+ * Callback function for when a menu entry has been selected.
+ */
+    void
+gui_menu_cb(menu)
+    vimmenu_T *menu;
+{
+    char_u  bytes[sizeof(long_u)];
+
+    /* Don't put events in the input queue now. */
+    if (hold_gui_events)
+	return;
+
+    bytes[0] = CSI;
+    bytes[1] = KS_MENU;
+    bytes[2] = KE_FILLER;
+    add_to_input_buf(bytes, 3);
+    add_long_to_buf((long_u)menu, bytes);
+    add_to_input_buf_csi(bytes, sizeof(long_u));
+}
+#endif
+
+static int	prev_which_scrollbars[3];
+
+/*
+ * Set which components are present.
+ * If "oldval" is not NULL, "oldval" is the previous value, the new value is
+ * in p_go.
+ */
+/*ARGSUSED*/
+    void
+gui_init_which_components(oldval)
+    char_u	*oldval;
+{
+#ifdef FEAT_MENU
+    static int	prev_menu_is_active = -1;
+#endif
+#ifdef FEAT_TOOLBAR
+    static int	prev_toolbar = -1;
+    int		using_toolbar = FALSE;
+#endif
+#ifdef FEAT_GUI_TABLINE
+    int		using_tabline;
+#endif
+#ifdef FEAT_FOOTER
+    static int	prev_footer = -1;
+    int		using_footer = FALSE;
+#endif
+#if defined(FEAT_MENU) && !defined(WIN16)
+    static int	prev_tearoff = -1;
+    int		using_tearoff = FALSE;
+#endif
+
+    char_u	*p;
+    int		i;
+#ifdef FEAT_MENU
+    int		grey_old, grey_new;
+    char_u	*temp;
+#endif
+    win_T	*wp;
+    int		need_set_size;
+    int		fix_size;
+
+#ifdef FEAT_MENU
+    if (oldval != NULL && gui.in_use)
+    {
+	/*
+	 * Check if the menu's go from grey to non-grey or vise versa.
+	 */
+	grey_old = (vim_strchr(oldval, GO_GREY) != NULL);
+	grey_new = (vim_strchr(p_go, GO_GREY) != NULL);
+	if (grey_old != grey_new)
+	{
+	    temp = p_go;
+	    p_go = oldval;
+	    gui_update_menus(MENU_ALL_MODES);
+	    p_go = temp;
+	}
+    }
+    gui.menu_is_active = FALSE;
+#endif
+
+    for (i = 0; i < 3; i++)
+	gui.which_scrollbars[i] = FALSE;
+    for (p = p_go; *p; p++)
+	switch (*p)
+	{
+	    case GO_LEFT:
+		gui.which_scrollbars[SBAR_LEFT] = TRUE;
+		break;
+	    case GO_RIGHT:
+		gui.which_scrollbars[SBAR_RIGHT] = TRUE;
+		break;
+#ifdef FEAT_VERTSPLIT
+	    case GO_VLEFT:
+		if (win_hasvertsplit())
+		    gui.which_scrollbars[SBAR_LEFT] = TRUE;
+		break;
+	    case GO_VRIGHT:
+		if (win_hasvertsplit())
+		    gui.which_scrollbars[SBAR_RIGHT] = TRUE;
+		break;
+#endif
+	    case GO_BOT:
+		gui.which_scrollbars[SBAR_BOTTOM] = TRUE;
+		break;
+#ifdef FEAT_MENU
+	    case GO_MENUS:
+		gui.menu_is_active = TRUE;
+		break;
+#endif
+	    case GO_GREY:
+		/* make menu's have grey items, ignored here */
+		break;
+#ifdef FEAT_TOOLBAR
+	    case GO_TOOLBAR:
+		using_toolbar = TRUE;
+		break;
+#endif
+#ifdef FEAT_FOOTER
+	    case GO_FOOTER:
+		using_footer = TRUE;
+		break;
+#endif
+	    case GO_TEAROFF:
+#if defined(FEAT_MENU) && !defined(WIN16)
+		using_tearoff = TRUE;
+#endif
+		break;
+	    default:
+		/* Ignore options that are not supported */
+		break;
+	}
+
+    if (gui.in_use)
+    {
+	need_set_size = 0;
+	fix_size = FALSE;
+
+#ifdef FEAT_GUI_TABLINE
+	/* Update the GUI tab line, it may appear or disappear.  This may
+	 * cause the non-GUI tab line to disappear or appear. */
+	using_tabline = gui_has_tabline();
+	if (!gui_mch_showing_tabline() != !using_tabline)
+	{
+	    /* We don't want a resize event change "Rows" here, save and
+	     * restore it.  Resizing is handled below. */
+	    i = Rows;
+	    gui_update_tabline();
+	    Rows = i;
+	    need_set_size = RESIZE_VERT;
+	    if (using_tabline)
+		fix_size = TRUE;
+	    if (!gui_use_tabline())
+		redraw_tabline = TRUE;    /* may draw non-GUI tab line */
+	}
+#endif
+
+	for (i = 0; i < 3; i++)
+	{
+	    /* The scrollbar needs to be updated when it is shown/unshown and
+	     * when switching tab pages.  But the size only changes when it's
+	     * shown/unshown.  Thus we need two places to remember whether a
+	     * scrollbar is there or not. */
+	    if (gui.which_scrollbars[i] != prev_which_scrollbars[i]
+#ifdef FEAT_WINDOWS
+		    || gui.which_scrollbars[i]
+					!= curtab->tp_prev_which_scrollbars[i]
+#endif
+		    )
+	    {
+		if (i == SBAR_BOTTOM)
+		    gui_mch_enable_scrollbar(&gui.bottom_sbar,
+						     gui.which_scrollbars[i]);
+		else
+		{
+		    FOR_ALL_WINDOWS(wp)
+		    {
+			gui_do_scrollbar(wp, i, gui.which_scrollbars[i]);
+		    }
+		}
+		if (gui.which_scrollbars[i] != prev_which_scrollbars[i])
+		{
+		    if (i == SBAR_BOTTOM)
+			need_set_size = RESIZE_VERT;
+		    else
+			need_set_size = RESIZE_HOR;
+		    if (gui.which_scrollbars[i])
+			fix_size = TRUE;
+		}
+	    }
+#ifdef FEAT_WINDOWS
+	    curtab->tp_prev_which_scrollbars[i] = gui.which_scrollbars[i];
+#endif
+	    prev_which_scrollbars[i] = gui.which_scrollbars[i];
+	}
+
+#ifdef FEAT_MENU
+	if (gui.menu_is_active != prev_menu_is_active)
+	{
+	    /* We don't want a resize event change "Rows" here, save and
+	     * restore it.  Resizing is handled below. */
+	    i = Rows;
+	    gui_mch_enable_menu(gui.menu_is_active);
+	    Rows = i;
+	    prev_menu_is_active = gui.menu_is_active;
+	    need_set_size = RESIZE_VERT;
+	    if (gui.menu_is_active)
+		fix_size = TRUE;
+	}
+#endif
+
+#ifdef FEAT_TOOLBAR
+	if (using_toolbar != prev_toolbar)
+	{
+	    gui_mch_show_toolbar(using_toolbar);
+	    prev_toolbar = using_toolbar;
+	    need_set_size = RESIZE_VERT;
+	    if (using_toolbar)
+		fix_size = TRUE;
+	}
+#endif
+#ifdef FEAT_FOOTER
+	if (using_footer != prev_footer)
+	{
+	    gui_mch_enable_footer(using_footer);
+	    prev_footer = using_footer;
+	    need_set_size = RESIZE_VERT;
+	    if (using_footer)
+		fix_size = TRUE;
+	}
+#endif
+#if defined(FEAT_MENU) && !defined(WIN16) && !(defined(WIN3264) && !defined(FEAT_TEAROFF))
+	if (using_tearoff != prev_tearoff)
+	{
+	    gui_mch_toggle_tearoffs(using_tearoff);
+	    prev_tearoff = using_tearoff;
+	}
+#endif
+	if (need_set_size)
+	{
+#ifdef FEAT_GUI_GTK
+	    long    c = Columns;
+#endif
+	    /* Adjust the size of the window to make the text area keep the
+	     * same size and to avoid that part of our window is off-screen
+	     * and a scrollbar can't be used, for example. */
+	    gui_set_shellsize(FALSE, fix_size, need_set_size);
+
+#ifdef FEAT_GUI_GTK
+	    /* GTK has the annoying habit of sending us resize events when
+	     * changing the window size ourselves.  This mostly happens when
+	     * waiting for a character to arrive, quite unpredictably, and may
+	     * change Columns and Rows when we don't want it.  Wait for a
+	     * character here to avoid this effect.
+	     * If you remove this, please test this command for resizing
+	     * effects (with optional left scrollbar): ":vsp|q|vsp|q|vsp|q".
+	     * Don't do this while starting up though.
+	     * And don't change Rows, it may have be reduced intentionally
+	     * when adding menu/toolbar/tabline. */
+	    if (!gui.starting)
+		(void)char_avail();
+	    Columns = c;
+#endif
+	}
+#ifdef FEAT_WINDOWS
+	/* When the console tabline appears or disappears the window positions
+	 * change. */
+	if (firstwin->w_winrow != tabline_height())
+	    shell_new_rows();	/* recompute window positions and heights */
+#endif
+    }
+}
+
+#if defined(FEAT_GUI_TABLINE) || defined(PROTO)
+/*
+ * Return TRUE if the GUI is taking care of the tabline.
+ * It may still be hidden if 'showtabline' is zero.
+ */
+    int
+gui_use_tabline()
+{
+    return gui.in_use && vim_strchr(p_go, GO_TABLINE) != NULL;
+}
+
+/*
+ * Return TRUE if the GUI is showing the tabline.
+ * This uses 'showtabline'.
+ */
+    static int
+gui_has_tabline()
+{
+    if (!gui_use_tabline()
+	    || p_stal == 0
+	    || (p_stal == 1 && first_tabpage->tp_next == NULL))
+	return FALSE;
+    return TRUE;
+}
+
+/*
+ * Update the tabline.
+ * This may display/undisplay the tabline and update the labels.
+ */
+    void
+gui_update_tabline()
+{
+    int	    showit = gui_has_tabline();
+    int	    shown = gui_mch_showing_tabline();
+
+    if (!gui.starting && starting == 0)
+    {
+	/* Updating the tabline uses direct GUI commands, flush
+	 * outstanding instructions first. (esp. clear screen) */
+	out_flush();
+	gui_mch_flush();
+
+	if (!showit != !shown)
+	    gui_mch_show_tabline(showit);
+	if (showit != 0)
+	    gui_mch_update_tabline();
+
+	/* When the tabs change from hidden to shown or from shown to
+	 * hidden the size of the text area should remain the same. */
+	if (!showit != !shown)
+	    gui_set_shellsize(FALSE, showit, RESIZE_VERT);
+    }
+}
+
+/*
+ * Get the label or tooltip for tab page "tp" into NameBuff[].
+ */
+    void
+get_tabline_label(tp, tooltip)
+    tabpage_T	*tp;
+    int		tooltip;	/* TRUE: get tooltip */
+{
+    int		modified = FALSE;
+    char_u	buf[40];
+    int		wincount;
+    win_T	*wp;
+    char_u	**opt;
+
+    /* Use 'guitablabel' or 'guitabtooltip' if it's set. */
+    opt = (tooltip ? &p_gtt : &p_gtl);
+    if (**opt != NUL)
+    {
+	int	use_sandbox = FALSE;
+	int	save_called_emsg = called_emsg;
+	char_u	res[MAXPATHL];
+	tabpage_T *save_curtab;
+	char_u	*opt_name = (char_u *)(tooltip ? "guitabtooltip"
+							     : "guitablabel");
+
+	called_emsg = FALSE;
+
+	printer_page_num = tabpage_index(tp);
+# ifdef FEAT_EVAL
+	set_vim_var_nr(VV_LNUM, printer_page_num);
+	use_sandbox = was_set_insecurely(opt_name, 0);
+# endif
+	/* It's almost as going to the tabpage, but without autocommands. */
+	curtab->tp_firstwin = firstwin;
+	curtab->tp_lastwin = lastwin;
+	curtab->tp_curwin = curwin;
+	save_curtab = curtab;
+	curtab = tp;
+	topframe = curtab->tp_topframe;
+	firstwin = curtab->tp_firstwin;
+	lastwin = curtab->tp_lastwin;
+	curwin = curtab->tp_curwin;
+	curbuf = curwin->w_buffer;
+
+	/* Can't use NameBuff directly, build_stl_str_hl() uses it. */
+	build_stl_str_hl(curwin, res, MAXPATHL, *opt, use_sandbox,
+						 0, (int)Columns, NULL, NULL);
+	STRCPY(NameBuff, res);
+
+	/* Back to the original curtab. */
+	curtab = save_curtab;
+	topframe = curtab->tp_topframe;
+	firstwin = curtab->tp_firstwin;
+	lastwin = curtab->tp_lastwin;
+	curwin = curtab->tp_curwin;
+	curbuf = curwin->w_buffer;
+
+	if (called_emsg)
+	    set_string_option_direct(opt_name, -1,
+					   (char_u *)"", OPT_FREE, SID_ERROR);
+	called_emsg |= save_called_emsg;
+    }
+
+    /* If 'guitablabel'/'guitabtooltip' is not set or the result is empty then
+     * use a default label. */
+    if (**opt == NUL || *NameBuff == NUL)
+    {
+	/* Get the buffer name into NameBuff[] and shorten it. */
+	get_trans_bufname(tp == curtab ? curbuf : tp->tp_curwin->w_buffer);
+	if (!tooltip)
+	    shorten_dir(NameBuff);
+
+	wp = (tp == curtab) ? firstwin : tp->tp_firstwin;
+	for (wincount = 0; wp != NULL; wp = wp->w_next, ++wincount)
+	    if (bufIsChanged(wp->w_buffer))
+		modified = TRUE;
+	if (modified || wincount > 1)
+	{
+	    if (wincount > 1)
+		vim_snprintf((char *)buf, sizeof(buf), "%d", wincount);
+	    else
+		buf[0] = NUL;
+	    if (modified)
+		STRCAT(buf, "+");
+	    STRCAT(buf, " ");
+	    mch_memmove(NameBuff + STRLEN(buf), NameBuff, STRLEN(NameBuff) + 1);
+	    mch_memmove(NameBuff, buf, STRLEN(buf));
+	}
+    }
+}
+
+/*
+ * Send the event for clicking to select tab page "nr".
+ * Returns TRUE if it was done, FALSE when skipped because we are already at
+ * that tab page or the cmdline window is open.
+ */
+    int
+send_tabline_event(nr)
+    int	    nr;
+{
+    char_u string[3];
+
+    if (nr == tabpage_index(curtab))
+	return FALSE;
+
+    /* Don't put events in the input queue now. */
+    if (hold_gui_events
+# ifdef FEAT_CMDWIN
+	    || cmdwin_type != 0
+# endif
+	    )
+    {
+	/* Set it back to the current tab page. */
+	gui_mch_set_curtab(tabpage_index(curtab));
+	return FALSE;
+    }
+
+    string[0] = CSI;
+    string[1] = KS_TABLINE;
+    string[2] = KE_FILLER;
+    add_to_input_buf(string, 3);
+    string[0] = nr;
+    add_to_input_buf_csi(string, 1);
+    return TRUE;
+}
+
+/*
+ * Send a tabline menu event
+ */
+    void
+send_tabline_menu_event(tabidx, event)
+    int	    tabidx;
+    int	    event;
+{
+    char_u	    string[3];
+
+    /* Don't put events in the input queue now. */
+    if (hold_gui_events)
+	return;
+
+    string[0] = CSI;
+    string[1] = KS_TABMENU;
+    string[2] = KE_FILLER;
+    add_to_input_buf(string, 3);
+    string[0] = tabidx;
+    string[1] = (char_u)(long)event;
+    add_to_input_buf_csi(string, 2);
+}
+
+#endif
+
+/*
+ * Scrollbar stuff:
+ */
+
+#if defined(FEAT_WINDOWS) || defined(PROTO)
+/*
+ * Remove all scrollbars.  Used before switching to another tab page.
+ */
+    void
+gui_remove_scrollbars()
+{
+    int	    i;
+    win_T   *wp;
+
+    for (i = 0; i < 3; i++)
+    {
+	if (i == SBAR_BOTTOM)
+	    gui_mch_enable_scrollbar(&gui.bottom_sbar, FALSE);
+	else
+	{
+	    FOR_ALL_WINDOWS(wp)
+	    {
+		gui_do_scrollbar(wp, i, FALSE);
+	    }
+	}
+	curtab->tp_prev_which_scrollbars[i] = -1;
+    }
+}
+#endif
+
+    void
+gui_create_scrollbar(sb, type, wp)
+    scrollbar_T	*sb;
+    int		type;
+    win_T	*wp;
+{
+    static int	sbar_ident = 0;
+
+    sb->ident = sbar_ident++;	/* No check for too big, but would it happen? */
+    sb->wp = wp;
+    sb->type = type;
+    sb->value = 0;
+#ifdef FEAT_GUI_ATHENA
+    sb->pixval = 0;
+#endif
+    sb->size = 1;
+    sb->max = 1;
+    sb->top = 0;
+    sb->height = 0;
+#ifdef FEAT_VERTSPLIT
+    sb->width = 0;
+#endif
+    sb->status_height = 0;
+    gui_mch_create_scrollbar(sb, (wp == NULL) ? SBAR_HORIZ : SBAR_VERT);
+}
+
+/*
+ * Find the scrollbar with the given index.
+ */
+    scrollbar_T *
+gui_find_scrollbar(ident)
+    long	ident;
+{
+    win_T	*wp;
+
+    if (gui.bottom_sbar.ident == ident)
+	return &gui.bottom_sbar;
+    FOR_ALL_WINDOWS(wp)
+    {
+	if (wp->w_scrollbars[SBAR_LEFT].ident == ident)
+	    return &wp->w_scrollbars[SBAR_LEFT];
+	if (wp->w_scrollbars[SBAR_RIGHT].ident == ident)
+	    return &wp->w_scrollbars[SBAR_RIGHT];
+    }
+    return NULL;
+}
+
+/*
+ * For most systems: Put a code in the input buffer for a dragged scrollbar.
+ *
+ * For Win32, Macintosh and GTK+ 2:
+ * Scrollbars seem to grab focus and vim doesn't read the input queue until
+ * you stop dragging the scrollbar.  We get here each time the scrollbar is
+ * dragged another pixel, but as far as the rest of vim goes, it thinks
+ * we're just hanging in the call to DispatchMessage() in
+ * process_message().  The DispatchMessage() call that hangs was passed a
+ * mouse button click event in the scrollbar window. -- webb.
+ *
+ * Solution: Do the scrolling right here.  But only when allowed.
+ * Ignore the scrollbars while executing an external command or when there
+ * are still characters to be processed.
+ */
+    void
+gui_drag_scrollbar(sb, value, still_dragging)
+    scrollbar_T	*sb;
+    long	value;
+    int		still_dragging;
+{
+#ifdef FEAT_WINDOWS
+    win_T	*wp;
+#endif
+    int		sb_num;
+#ifdef USE_ON_FLY_SCROLL
+    colnr_T	old_leftcol = curwin->w_leftcol;
+# ifdef FEAT_SCROLLBIND
+    linenr_T	old_topline = curwin->w_topline;
+# endif
+# ifdef FEAT_DIFF
+    int		old_topfill = curwin->w_topfill;
+# endif
+#else
+    char_u	bytes[sizeof(long_u)];
+    int		byte_count;
+#endif
+
+    if (sb == NULL)
+	return;
+
+    /* Don't put events in the input queue now. */
+    if (hold_gui_events)
+	return;
+
+#ifdef FEAT_CMDWIN
+    if (cmdwin_type != 0 && sb->wp != curwin)
+	return;
+#endif
+
+    if (still_dragging)
+    {
+	if (sb->wp == NULL)
+	    gui.dragged_sb = SBAR_BOTTOM;
+	else if (sb == &sb->wp->w_scrollbars[SBAR_LEFT])
+	    gui.dragged_sb = SBAR_LEFT;
+	else
+	    gui.dragged_sb = SBAR_RIGHT;
+	gui.dragged_wp = sb->wp;
+    }
+    else
+    {
+	gui.dragged_sb = SBAR_NONE;
+#ifdef HAVE_GTK2
+	/* Keep the "dragged_wp" value until after the scrolling, for when the
+	 * moust button is released.  GTK2 doesn't send the button-up event. */
+	gui.dragged_wp = NULL;
+#endif
+    }
+
+    /* Vertical sbar info is kept in the first sbar (the left one) */
+    if (sb->wp != NULL)
+	sb = &sb->wp->w_scrollbars[0];
+
+    /*
+     * Check validity of value
+     */
+    if (value < 0)
+	value = 0;
+#ifdef SCROLL_PAST_END
+    else if (value > sb->max)
+	value = sb->max;
+#else
+    if (value > sb->max - sb->size + 1)
+	value = sb->max - sb->size + 1;
+#endif
+
+    sb->value = value;
+
+#ifdef USE_ON_FLY_SCROLL
+    /* When not allowed to do the scrolling right now, return. */
+    if (dont_scroll || input_available())
+	return;
+#endif
+#ifdef FEAT_INS_EXPAND
+    /* Disallow scrolling the current window when the completion popup menu is
+     * visible. */
+    if ((sb->wp == NULL || sb->wp == curwin) && pum_visible())
+	return;
+#endif
+
+#ifdef FEAT_RIGHTLEFT
+    if (sb->wp == NULL && curwin->w_p_rl)
+    {
+	value = sb->max + 1 - sb->size - value;
+	if (value < 0)
+	    value = 0;
+    }
+#endif
+
+    if (sb->wp != NULL)		/* vertical scrollbar */
+    {
+	sb_num = 0;
+#ifdef FEAT_WINDOWS
+	for (wp = firstwin; wp != sb->wp && wp != NULL; wp = wp->w_next)
+	    sb_num++;
+	if (wp == NULL)
+	    return;
+#else
+	if (sb->wp != curwin)
+	    return;
+#endif
+
+#ifdef USE_ON_FLY_SCROLL
+	current_scrollbar = sb_num;
+	scrollbar_value = value;
+	if (State & NORMAL)
+	{
+	    gui_do_scroll();
+	    setcursor();
+	}
+	else if (State & INSERT)
+	{
+	    ins_scroll();
+	    setcursor();
+	}
+	else if (State & CMDLINE)
+	{
+	    if (msg_scrolled == 0)
+	    {
+		gui_do_scroll();
+		redrawcmdline();
+	    }
+	}
+# ifdef FEAT_FOLDING
+	/* Value may have been changed for closed fold. */
+	sb->value = sb->wp->w_topline - 1;
+# endif
+
+	/* When dragging one scrollbar and there is another one at the other
+	 * side move the thumb of that one too. */
+	if (gui.which_scrollbars[SBAR_RIGHT] && gui.which_scrollbars[SBAR_LEFT])
+	    gui_mch_set_scrollbar_thumb(
+		    &sb->wp->w_scrollbars[
+			    sb == &sb->wp->w_scrollbars[SBAR_RIGHT]
+						    ? SBAR_LEFT : SBAR_RIGHT],
+		    sb->value, sb->size, sb->max);
+
+#else
+	bytes[0] = CSI;
+	bytes[1] = KS_VER_SCROLLBAR;
+	bytes[2] = KE_FILLER;
+	bytes[3] = (char_u)sb_num;
+	byte_count = 4;
+#endif
+    }
+    else
+    {
+#ifdef USE_ON_FLY_SCROLL
+	scrollbar_value = value;
+
+	if (State & NORMAL)
+	    gui_do_horiz_scroll();
+	else if (State & INSERT)
+	    ins_horscroll();
+	else if (State & CMDLINE)
+	{
+	    if (msg_scrolled == 0)
+	    {
+		gui_do_horiz_scroll();
+		redrawcmdline();
+	    }
+	}
+	if (old_leftcol != curwin->w_leftcol)
+	{
+	    updateWindow(curwin);   /* update window, status and cmdline */
+	    setcursor();
+	}
+#else
+	bytes[0] = CSI;
+	bytes[1] = KS_HOR_SCROLLBAR;
+	bytes[2] = KE_FILLER;
+	byte_count = 3;
+#endif
+    }
+
+#ifdef USE_ON_FLY_SCROLL
+# ifdef FEAT_SCROLLBIND
+    /*
+     * synchronize other windows, as necessary according to 'scrollbind'
+     */
+    if (curwin->w_p_scb
+	    && ((sb->wp == NULL && curwin->w_leftcol != old_leftcol)
+		|| (sb->wp == curwin && (curwin->w_topline != old_topline
+#  ifdef FEAT_DIFF
+					   || curwin->w_topfill != old_topfill
+#  endif
+			))))
+    {
+	do_check_scrollbind(TRUE);
+	/* need to update the window right here */
+	for (wp = firstwin; wp != NULL; wp = wp->w_next)
+	    if (wp->w_redr_type > 0)
+		updateWindow(wp);
+	setcursor();
+    }
+# endif
+    out_flush();
+    gui_update_cursor(FALSE, TRUE);
+#else
+    add_to_input_buf(bytes, byte_count);
+    add_long_to_buf((long_u)value, bytes);
+    add_to_input_buf_csi(bytes, sizeof(long_u));
+#endif
+}
+
+/*
+ * Scrollbar stuff:
+ */
+
+    void
+gui_update_scrollbars(force)
+    int		force;	    /* Force all scrollbars to get updated */
+{
+    win_T	*wp;
+    scrollbar_T	*sb;
+    long	val, size, max;		/* need 32 bits here */
+    int		which_sb;
+    int		h, y;
+#ifdef FEAT_VERTSPLIT
+    static win_T *prev_curwin = NULL;
+#endif
+
+    /* Update the horizontal scrollbar */
+    gui_update_horiz_scrollbar(force);
+
+#ifndef WIN3264
+    /* Return straight away if there is neither a left nor right scrollbar.
+     * On MS-Windows this is required anyway for scrollwheel messages. */
+    if (!gui.which_scrollbars[SBAR_LEFT] && !gui.which_scrollbars[SBAR_RIGHT])
+	return;
+#endif
+
+    /*
+     * Don't want to update a scrollbar while we're dragging it.  But if we
+     * have both a left and right scrollbar, and we drag one of them, we still
+     * need to update the other one.
+     */
+    if (!force && (gui.dragged_sb == SBAR_LEFT || gui.dragged_sb == SBAR_RIGHT)
+	    && gui.which_scrollbars[SBAR_LEFT]
+	    && gui.which_scrollbars[SBAR_RIGHT])
+    {
+	/*
+	 * If we have two scrollbars and one of them is being dragged, just
+	 * copy the scrollbar position from the dragged one to the other one.
+	 */
+	which_sb = SBAR_LEFT + SBAR_RIGHT - gui.dragged_sb;
+	if (gui.dragged_wp != NULL)
+	    gui_mch_set_scrollbar_thumb(
+		    &gui.dragged_wp->w_scrollbars[which_sb],
+		    gui.dragged_wp->w_scrollbars[0].value,
+		    gui.dragged_wp->w_scrollbars[0].size,
+		    gui.dragged_wp->w_scrollbars[0].max);
+    }
+
+    /* avoid that moving components around generates events */
+    ++hold_gui_events;
+
+    for (wp = firstwin; wp != NULL; wp = W_NEXT(wp))
+    {
+	if (wp->w_buffer == NULL)	/* just in case */
+	    continue;
+	/* Skip a scrollbar that is being dragged. */
+	if (!force && (gui.dragged_sb == SBAR_LEFT
+					     || gui.dragged_sb == SBAR_RIGHT)
+		&& gui.dragged_wp == wp)
+	    continue;
+
+#ifdef SCROLL_PAST_END
+	max = wp->w_buffer->b_ml.ml_line_count - 1;
+#else
+	max = wp->w_buffer->b_ml.ml_line_count + wp->w_height - 2;
+#endif
+	if (max < 0)			/* empty buffer */
+	    max = 0;
+	val = wp->w_topline - 1;
+	size = wp->w_height;
+#ifdef SCROLL_PAST_END
+	if (val > max)			/* just in case */
+	    val = max;
+#else
+	if (size > max + 1)		/* just in case */
+	    size = max + 1;
+	if (val > max - size + 1)
+	    val = max - size + 1;
+#endif
+	if (val < 0)			/* minimal value is 0 */
+	    val = 0;
+
+	/*
+	 * Scrollbar at index 0 (the left one) contains all the information.
+	 * It would be the same info for left and right so we just store it for
+	 * one of them.
+	 */
+	sb = &wp->w_scrollbars[0];
+
+	/*
+	 * Note: no check for valid w_botline.	If it's not valid the
+	 * scrollbars will be updated later anyway.
+	 */
+	if (size < 1 || wp->w_botline - 2 > max)
+	{
+	    /*
+	     * This can happen during changing files.  Just don't update the
+	     * scrollbar for now.
+	     */
+	    sb->height = 0;	    /* Force update next time */
+	    if (gui.which_scrollbars[SBAR_LEFT])
+		gui_do_scrollbar(wp, SBAR_LEFT, FALSE);
+	    if (gui.which_scrollbars[SBAR_RIGHT])
+		gui_do_scrollbar(wp, SBAR_RIGHT, FALSE);
+	    continue;
+	}
+	if (force || sb->height != wp->w_height
+#ifdef FEAT_WINDOWS
+	    || sb->top != wp->w_winrow
+	    || sb->status_height != wp->w_status_height
+# ifdef FEAT_VERTSPLIT
+	    || sb->width != wp->w_width
+	    || prev_curwin != curwin
+# endif
+#endif
+	    )
+	{
+	    /* Height, width or position of scrollbar has changed.  For
+	     * vertical split: curwin changed. */
+	    sb->height = wp->w_height;
+#ifdef FEAT_WINDOWS
+	    sb->top = wp->w_winrow;
+	    sb->status_height = wp->w_status_height;
+# ifdef FEAT_VERTSPLIT
+	    sb->width = wp->w_width;
+# endif
+#endif
+
+	    /* Calculate height and position in pixels */
+	    h = (sb->height + sb->status_height) * gui.char_height;
+	    y = sb->top * gui.char_height + gui.border_offset;
+#if defined(FEAT_MENU) && !defined(FEAT_GUI_GTK) && !defined(FEAT_GUI_MOTIF) && !defined(FEAT_GUI_PHOTON)
+	    if (gui.menu_is_active)
+		y += gui.menu_height;
+#endif
+
+#if defined(FEAT_TOOLBAR) && (defined(FEAT_GUI_MSWIN) || defined(FEAT_GUI_ATHENA))
+	    if (vim_strchr(p_go, GO_TOOLBAR) != NULL)
+# ifdef FEAT_GUI_ATHENA
+		y += gui.toolbar_height;
+# else
+#  ifdef FEAT_GUI_MSWIN
+		y += TOOLBAR_BUTTON_HEIGHT + TOOLBAR_BORDER_HEIGHT;
+#  endif
+# endif
+#endif
+
+#if defined(FEAT_GUI_TABLINE) && defined(FEAT_GUI_MSWIN)
+	    if (gui_has_tabline())
+		y += gui.tabline_height;
+#endif
+
+#ifdef FEAT_WINDOWS
+	    if (wp->w_winrow == 0)
+#endif
+	    {
+		/* Height of top scrollbar includes width of top border */
+		h += gui.border_offset;
+		y -= gui.border_offset;
+	    }
+	    if (gui.which_scrollbars[SBAR_LEFT])
+	    {
+		gui_mch_set_scrollbar_pos(&wp->w_scrollbars[SBAR_LEFT],
+					  gui.left_sbar_x, y,
+					  gui.scrollbar_width, h);
+		gui_do_scrollbar(wp, SBAR_LEFT, TRUE);
+	    }
+	    if (gui.which_scrollbars[SBAR_RIGHT])
+	    {
+		gui_mch_set_scrollbar_pos(&wp->w_scrollbars[SBAR_RIGHT],
+					  gui.right_sbar_x, y,
+					  gui.scrollbar_width, h);
+		gui_do_scrollbar(wp, SBAR_RIGHT, TRUE);
+	    }
+	}
+
+	/* Reduce the number of calls to gui_mch_set_scrollbar_thumb() by
+	 * checking if the thumb moved at least a pixel.  Only do this for
+	 * Athena, most other GUIs require the update anyway to make the
+	 * arrows work. */
+#ifdef FEAT_GUI_ATHENA
+	if (max == 0)
+	    y = 0;
+	else
+	    y = (val * (sb->height + 2) * gui.char_height + max / 2) / max;
+	if (force || sb->pixval != y || sb->size != size || sb->max != max)
+#else
+	if (force || sb->value != val || sb->size != size || sb->max != max)
+#endif
+	{
+	    /* Thumb of scrollbar has moved */
+	    sb->value = val;
+#ifdef FEAT_GUI_ATHENA
+	    sb->pixval = y;
+#endif
+	    sb->size = size;
+	    sb->max = max;
+	    if (gui.which_scrollbars[SBAR_LEFT]
+		    && (gui.dragged_sb != SBAR_LEFT || gui.dragged_wp != wp))
+		gui_mch_set_scrollbar_thumb(&wp->w_scrollbars[SBAR_LEFT],
+					    val, size, max);
+	    if (gui.which_scrollbars[SBAR_RIGHT]
+		    && (gui.dragged_sb != SBAR_RIGHT || gui.dragged_wp != wp))
+		gui_mch_set_scrollbar_thumb(&wp->w_scrollbars[SBAR_RIGHT],
+					    val, size, max);
+	}
+    }
+#ifdef FEAT_VERTSPLIT
+    prev_curwin = curwin;
+#endif
+    --hold_gui_events;
+}
+
+/*
+ * Enable or disable a scrollbar.
+ * Check for scrollbars for vertically split windows which are not enabled
+ * sometimes.
+ */
+    static void
+gui_do_scrollbar(wp, which, enable)
+    win_T	*wp;
+    int		which;	    /* SBAR_LEFT or SBAR_RIGHT */
+    int		enable;	    /* TRUE to enable scrollbar */
+{
+#ifdef FEAT_VERTSPLIT
+    int		midcol = curwin->w_wincol + curwin->w_width / 2;
+    int		has_midcol = (wp->w_wincol <= midcol
+				     && wp->w_wincol + wp->w_width >= midcol);
+
+    /* Only enable scrollbars that contain the middle column of the current
+     * window. */
+    if (gui.which_scrollbars[SBAR_RIGHT] != gui.which_scrollbars[SBAR_LEFT])
+    {
+	/* Scrollbars only on one side.  Don't enable scrollbars that don't
+	 * contain the middle column of the current window. */
+	if (!has_midcol)
+	    enable = FALSE;
+    }
+    else
+    {
+	/* Scrollbars on both sides.  Don't enable scrollbars that neither
+	 * contain the middle column of the current window nor are on the far
+	 * side. */
+	if (midcol > Columns / 2)
+	{
+	    if (which == SBAR_LEFT ? wp->w_wincol != 0 : !has_midcol)
+		enable = FALSE;
+	}
+	else
+	{
+	    if (which == SBAR_RIGHT ? wp->w_wincol + wp->w_width != Columns
+								: !has_midcol)
+		enable = FALSE;
+	}
+    }
+#endif
+    gui_mch_enable_scrollbar(&wp->w_scrollbars[which], enable);
+}
+
+/*
+ * Scroll a window according to the values set in the globals current_scrollbar
+ * and scrollbar_value.  Return TRUE if the cursor in the current window moved
+ * or FALSE otherwise.
+ */
+    int
+gui_do_scroll()
+{
+    win_T	*wp, *save_wp;
+    int		i;
+    long	nlines;
+    pos_T	old_cursor;
+    linenr_T	old_topline;
+#ifdef FEAT_DIFF
+    int		old_topfill;
+#endif
+
+    for (wp = firstwin, i = 0; i < current_scrollbar; wp = W_NEXT(wp), i++)
+	if (wp == NULL)
+	    break;
+    if (wp == NULL)
+	/* Couldn't find window */
+	return FALSE;
+
+    /*
+     * Compute number of lines to scroll.  If zero, nothing to do.
+     */
+    nlines = (long)scrollbar_value + 1 - (long)wp->w_topline;
+    if (nlines == 0)
+	return FALSE;
+
+    save_wp = curwin;
+    old_topline = wp->w_topline;
+#ifdef FEAT_DIFF
+    old_topfill = wp->w_topfill;
+#endif
+    old_cursor = wp->w_cursor;
+    curwin = wp;
+    curbuf = wp->w_buffer;
+    if (nlines < 0)
+	scrolldown(-nlines, gui.dragged_wp == NULL);
+    else
+	scrollup(nlines, gui.dragged_wp == NULL);
+    /* Reset dragged_wp after using it.  "dragged_sb" will have been reset for
+     * the mouse-up event already, but we still want it to behave like when
+     * dragging.  But not the next click in an arrow. */
+    if (gui.dragged_sb == SBAR_NONE)
+	gui.dragged_wp = NULL;
+
+    if (old_topline != wp->w_topline
+#ifdef FEAT_DIFF
+	    || old_topfill != wp->w_topfill
+#endif
+	    )
+    {
+	if (p_so != 0)
+	{
+	    cursor_correct();		/* fix window for 'so' */
+	    update_topline();		/* avoid up/down jump */
+	}
+	if (old_cursor.lnum != wp->w_cursor.lnum)
+	    coladvance(wp->w_curswant);
+#ifdef FEAT_SCROLLBIND
+	wp->w_scbind_pos = wp->w_topline;
+#endif
+    }
+
+    /* Make sure wp->w_leftcol and wp->w_skipcol are correct. */
+    validate_cursor();
+
+    curwin = save_wp;
+    curbuf = save_wp->w_buffer;
+
+    /*
+     * Don't call updateWindow() when nothing has changed (it will overwrite
+     * the status line!).
+     */
+    if (old_topline != wp->w_topline
+	    || wp->w_redr_type != 0
+#ifdef FEAT_DIFF
+	    || old_topfill != wp->w_topfill
+#endif
+	    )
+    {
+	redraw_win_later(wp, VALID);
+	updateWindow(wp);   /* update window, status line, and cmdline */
+    }
+
+#ifdef FEAT_INS_EXPAND
+    /* May need to redraw the popup menu. */
+    if (pum_visible())
+	pum_redraw();
+#endif
+
+    return (wp == curwin && !equalpos(curwin->w_cursor, old_cursor));
+}
+
+
+/*
+ * Horizontal scrollbar stuff:
+ */
+
+/*
+ * Return length of line "lnum" for horizontal scrolling.
+ */
+    static colnr_T
+scroll_line_len(lnum)
+    linenr_T	lnum;
+{
+    char_u	*p;
+    colnr_T	col;
+    int		w;
+
+    p = ml_get(lnum);
+    col = 0;
+    if (*p != NUL)
+	for (;;)
+	{
+	    w = chartabsize(p, col);
+	    mb_ptr_adv(p);
+	    if (*p == NUL)		/* don't count the last character */
+		break;
+	    col += w;
+	}
+    return col;
+}
+
+/* Remember which line is currently the longest, so that we don't have to
+ * search for it when scrolling horizontally. */
+static linenr_T longest_lnum = 0;
+
+    static void
+gui_update_horiz_scrollbar(force)
+    int		force;
+{
+    long	value, size, max;	/* need 32 bit ints here */
+
+    if (!gui.which_scrollbars[SBAR_BOTTOM])
+	return;
+
+    if (!force && gui.dragged_sb == SBAR_BOTTOM)
+	return;
+
+    if (!force && curwin->w_p_wrap && gui.prev_wrap)
+	return;
+
+    /*
+     * It is possible for the cursor to be invalid if we're in the middle of
+     * something (like changing files).  If so, don't do anything for now.
+     */
+    if (curwin->w_cursor.lnum > curbuf->b_ml.ml_line_count)
+    {
+	gui.bottom_sbar.value = -1;
+	return;
+    }
+
+    size = W_WIDTH(curwin);
+    if (curwin->w_p_wrap)
+    {
+	value = 0;
+#ifdef SCROLL_PAST_END
+	max = 0;
+#else
+	max = W_WIDTH(curwin) - 1;
+#endif
+    }
+    else
+    {
+	value = curwin->w_leftcol;
+
+	/* Calculate maximum for horizontal scrollbar.  Check for reasonable
+	 * line numbers, topline and botline can be invalid when displaying is
+	 * postponed. */
+	if (vim_strchr(p_go, GO_HORSCROLL) == NULL
+		&& curwin->w_topline <= curwin->w_cursor.lnum
+		&& curwin->w_botline > curwin->w_cursor.lnum
+		&& curwin->w_botline <= curbuf->b_ml.ml_line_count + 1)
+	{
+	    linenr_T	lnum;
+	    colnr_T	n;
+
+	    /* Use maximum of all visible lines.  Remember the lnum of the
+	     * longest line, clostest to the cursor line.  Used when scrolling
+	     * below. */
+	    max = 0;
+	    for (lnum = curwin->w_topline; lnum < curwin->w_botline; ++lnum)
+	    {
+		n = scroll_line_len(lnum);
+		if (n > (colnr_T)max)
+		{
+		    max = n;
+		    longest_lnum = lnum;
+		}
+		else if (n == (colnr_T)max
+			&& abs((int)(lnum - curwin->w_cursor.lnum))
+			   < abs((int)(longest_lnum - curwin->w_cursor.lnum)))
+		    longest_lnum = lnum;
+	    }
+	}
+	else
+	    /* Use cursor line only. */
+	    max = scroll_line_len(curwin->w_cursor.lnum);
+#ifdef FEAT_VIRTUALEDIT
+	if (virtual_active())
+	{
+	    /* May move the cursor even further to the right. */
+	    if (curwin->w_virtcol >= (colnr_T)max)
+		max = curwin->w_virtcol;
+	}
+#endif
+
+#ifndef SCROLL_PAST_END
+	max += W_WIDTH(curwin) - 1;
+#endif
+	/* The line number isn't scrolled, thus there is less space when
+	 * 'number' is set (also for 'foldcolumn'). */
+	size -= curwin_col_off();
+#ifndef SCROLL_PAST_END
+	max -= curwin_col_off();
+#endif
+    }
+
+#ifndef SCROLL_PAST_END
+    if (value > max - size + 1)
+	value = max - size + 1;	    /* limit the value to allowable range */
+#endif
+
+#ifdef FEAT_RIGHTLEFT
+    if (curwin->w_p_rl)
+    {
+	value = max + 1 - size - value;
+	if (value < 0)
+	{
+	    size += value;
+	    value = 0;
+	}
+    }
+#endif
+    if (!force && value == gui.bottom_sbar.value && size == gui.bottom_sbar.size
+						&& max == gui.bottom_sbar.max)
+	return;
+
+    gui.bottom_sbar.value = value;
+    gui.bottom_sbar.size = size;
+    gui.bottom_sbar.max = max;
+    gui.prev_wrap = curwin->w_p_wrap;
+
+    gui_mch_set_scrollbar_thumb(&gui.bottom_sbar, value, size, max);
+}
+
+/*
+ * Do a horizontal scroll.  Return TRUE if the cursor moved, FALSE otherwise.
+ */
+    int
+gui_do_horiz_scroll()
+{
+    /* no wrapping, no scrolling */
+    if (curwin->w_p_wrap)
+	return FALSE;
+
+    if (curwin->w_leftcol == scrollbar_value)
+	return FALSE;
+
+    curwin->w_leftcol = (colnr_T)scrollbar_value;
+
+    /* When the line of the cursor is too short, move the cursor to the
+     * longest visible line.  Do a sanity check on "longest_lnum", just in
+     * case. */
+    if (vim_strchr(p_go, GO_HORSCROLL) == NULL
+	    && longest_lnum >= curwin->w_topline
+	    && longest_lnum < curwin->w_botline
+	    && !virtual_active())
+    {
+	if (scrollbar_value > scroll_line_len(curwin->w_cursor.lnum))
+	{
+	    curwin->w_cursor.lnum = longest_lnum;
+	    curwin->w_cursor.col = 0;
+	}
+    }
+
+    return leftcol_changed();
+}
+
+/*
+ * Check that none of the colors are the same as the background color
+ */
+    void
+gui_check_colors()
+{
+    if (gui.norm_pixel == gui.back_pixel || gui.norm_pixel == INVALCOLOR)
+    {
+	gui_set_bg_color((char_u *)"White");
+	if (gui.norm_pixel == gui.back_pixel || gui.norm_pixel == INVALCOLOR)
+	    gui_set_fg_color((char_u *)"Black");
+    }
+}
+
+    static void
+gui_set_fg_color(name)
+    char_u	*name;
+{
+    gui.norm_pixel = gui_get_color(name);
+    hl_set_fg_color_name(vim_strsave(name));
+}
+
+    static void
+gui_set_bg_color(name)
+    char_u	*name;
+{
+    gui.back_pixel = gui_get_color(name);
+    hl_set_bg_color_name(vim_strsave(name));
+}
+
+/*
+ * Allocate a color by name.
+ * Returns INVALCOLOR and gives an error message when failed.
+ */
+    guicolor_T
+gui_get_color(name)
+    char_u	*name;
+{
+    guicolor_T	t;
+
+    if (*name == NUL)
+	return INVALCOLOR;
+    t = gui_mch_get_color(name);
+
+    if (t == INVALCOLOR
+#if defined(FEAT_GUI_X11) || defined(FEAT_GUI_GTK)
+	    && gui.in_use
+#endif
+	    )
+	EMSG2(_("E254: Cannot allocate color %s"), name);
+    return t;
+}
+
+/*
+ * Return the grey value of a color (range 0-255).
+ */
+    int
+gui_get_lightness(pixel)
+    guicolor_T	pixel;
+{
+    long_u	rgb = gui_mch_get_rgb(pixel);
+
+    return  (int)(  (((rgb >> 16) & 0xff) * 299)
+		   + (((rgb >> 8) & 0xff) * 587)
+		   +  ((rgb	  & 0xff) * 114)) / 1000;
+}
+
+#if defined(FEAT_GUI_X11) || defined(PROTO)
+    void
+gui_new_scrollbar_colors()
+{
+    win_T	*wp;
+
+    /* Nothing to do if GUI hasn't started yet. */
+    if (!gui.in_use)
+	return;
+
+    FOR_ALL_WINDOWS(wp)
+    {
+	gui_mch_set_scrollbar_colors(&(wp->w_scrollbars[SBAR_LEFT]));
+	gui_mch_set_scrollbar_colors(&(wp->w_scrollbars[SBAR_RIGHT]));
+    }
+    gui_mch_set_scrollbar_colors(&gui.bottom_sbar);
+}
+#endif
+
+/*
+ * Call this when focus has changed.
+ */
+    void
+gui_focus_change(in_focus)
+    int		in_focus;
+{
+/*
+ * Skip this code to avoid drawing the cursor when debugging and switching
+ * between the debugger window and gvim.
+ */
+#if 1
+    gui.in_focus = in_focus;
+    out_flush();		/* make sure output has been written */
+    gui_update_cursor(TRUE, FALSE);
+
+# ifdef FEAT_XIM
+    xim_set_focus(in_focus);
+# endif
+
+    ui_focus_change(in_focus);
+#endif
+}
+
+/*
+ * Called when the mouse moved (but not when dragging).
+ */
+    void
+gui_mouse_moved(x, y)
+    int		x;
+    int		y;
+{
+    win_T	*wp;
+    char_u	st[8];
+
+    /* Ignore this while still starting up. */
+    if (!gui.in_use || gui.starting)
+	return;
+
+#ifdef FEAT_MOUSESHAPE
+    /* Get window pointer, and update mouse shape as well. */
+    wp = xy2win(x, y);
+#endif
+
+    /* Only handle this when 'mousefocus' set and ... */
+    if (p_mousef
+	    && !hold_gui_events		/* not holding events */
+	    && (State & (NORMAL|INSERT))/* Normal/Visual/Insert mode */
+	    && State != HITRETURN	/* but not hit-return prompt */
+	    && msg_scrolled == 0	/* no scrolled message */
+	    && !need_mouse_correct	/* not moving the pointer */
+	    && gui.in_focus)		/* gvim in focus */
+    {
+	/* Don't move the mouse when it's left or right of the Vim window */
+	if (x < 0 || x > Columns * gui.char_width)
+	    return;
+#ifndef FEAT_MOUSESHAPE
+	wp = xy2win(x, y);
+#endif
+	if (wp == curwin || wp == NULL)
+	    return;	/* still in the same old window, or none at all */
+
+#ifdef FEAT_WINDOWS
+	/* Ignore position in the tab pages line. */
+	if (Y_2_ROW(y) < tabline_height())
+	    return;
+#endif
+
+	/*
+	 * format a mouse click on status line input
+	 * ala gui_send_mouse_event(0, x, y, 0, 0);
+	 * Trick: Use a column number -1, so that get_pseudo_mouse_code() will
+	 * generate a K_LEFTMOUSE_NM key code.
+	 */
+	if (finish_op)
+	{
+	    /* abort the current operator first */
+	    st[0] = ESC;
+	    add_to_input_buf(st, 1);
+	}
+	st[0] = CSI;
+	st[1] = KS_MOUSE;
+	st[2] = KE_FILLER;
+	st[3] = (char_u)MOUSE_LEFT;
+	fill_mouse_coord(st + 4,
+#ifdef FEAT_VERTSPLIT
+		wp->w_wincol == 0 ? -1 : wp->w_wincol + MOUSE_COLOFF,
+#else
+		-1,
+#endif
+		wp->w_height + W_WINROW(wp));
+
+	add_to_input_buf(st, 8);
+	st[3] = (char_u)MOUSE_RELEASE;
+	add_to_input_buf(st, 8);
+#ifdef FEAT_GUI_GTK
+	/* Need to wake up the main loop */
+	if (gtk_main_level() > 0)
+	    gtk_main_quit();
+#endif
+    }
+}
+
+/*
+ * Called when mouse should be moved to window with focus.
+ */
+    void
+gui_mouse_correct()
+{
+    int		x, y;
+    win_T	*wp = NULL;
+
+    need_mouse_correct = FALSE;
+
+    if (!(gui.in_use && p_mousef))
+	return;
+
+    gui_mch_getmouse(&x, &y);
+    /* Don't move the mouse when it's left or right of the Vim window */
+    if (x < 0 || x > Columns * gui.char_width)
+	return;
+    if (y >= 0
+# ifdef FEAT_WINDOWS
+	    && Y_2_ROW(y) >= tabline_height()
+# endif
+       )
+	wp = xy2win(x, y);
+    if (wp != curwin && wp != NULL)	/* If in other than current window */
+    {
+	validate_cline_row();
+	gui_mch_setmouse((int)W_ENDCOL(curwin) * gui.char_width - 3,
+		(W_WINROW(curwin) + curwin->w_wrow) * gui.char_height
+						     + (gui.char_height) / 2);
+    }
+}
+
+/*
+ * Find window where the mouse pointer "y" coordinate is in.
+ */
+/*ARGSUSED*/
+    static win_T *
+xy2win(x, y)
+    int		x;
+    int		y;
+{
+#ifdef FEAT_WINDOWS
+    int		row;
+    int		col;
+    win_T	*wp;
+
+    row = Y_2_ROW(y);
+    col = X_2_COL(x);
+    if (row < 0 || col < 0)		/* before first window */
+	return NULL;
+    wp = mouse_find_win(&row, &col);
+# ifdef FEAT_MOUSESHAPE
+    if (State == HITRETURN || State == ASKMORE)
+    {
+	if (Y_2_ROW(y) >= msg_row)
+	    update_mouseshape(SHAPE_IDX_MOREL);
+	else
+	    update_mouseshape(SHAPE_IDX_MORE);
+    }
+    else if (row > wp->w_height)	/* below status line */
+	update_mouseshape(SHAPE_IDX_CLINE);
+#  ifdef FEAT_VERTSPLIT
+    else if (!(State & CMDLINE) && W_VSEP_WIDTH(wp) > 0 && col == wp->w_width
+	    && (row != wp->w_height || !stl_connected(wp)) && msg_scrolled == 0)
+	update_mouseshape(SHAPE_IDX_VSEP);
+#  endif
+    else if (!(State & CMDLINE) && W_STATUS_HEIGHT(wp) > 0
+				  && row == wp->w_height && msg_scrolled == 0)
+	update_mouseshape(SHAPE_IDX_STATUS);
+    else
+	update_mouseshape(-2);
+# endif
+    return wp;
+#else
+    return firstwin;
+#endif
+}
+
+/*
+ * ":gui" and ":gvim": Change from the terminal version to the GUI version.
+ * File names may be given to redefine the args list.
+ */
+    void
+ex_gui(eap)
+    exarg_T	*eap;
+{
+    char_u	*arg = eap->arg;
+
+    /*
+     * Check for "-f" argument: foreground, don't fork.
+     * Also don't fork when started with "gvim -f".
+     * Do fork when using "gui -b".
+     */
+    if (arg[0] == '-'
+	    && (arg[1] == 'f' || arg[1] == 'b')
+	    && (arg[2] == NUL || vim_iswhite(arg[2])))
+    {
+	gui.dofork = (arg[1] == 'b');
+	eap->arg = skipwhite(eap->arg + 2);
+    }
+    if (!gui.in_use)
+    {
+	/* Clear the command.  Needed for when forking+exiting, to avoid part
+	 * of the argument ending up after the shell prompt. */
+	msg_clr_eos_force();
+	gui_start();
+    }
+    if (!ends_excmd(*eap->arg))
+	ex_next(eap);
+}
+
+#if ((defined(FEAT_GUI_X11) || defined(FEAT_GUI_GTK) || defined(FEAT_GUI_W32) \
+	|| defined(FEAT_GUI_PHOTON)) && defined(FEAT_TOOLBAR)) || defined(PROTO)
+/*
+ * This is shared between Athena, Motif and GTK.
+ */
+static void gfp_setname __ARGS((char_u *fname, void *cookie));
+
+/*
+ * Callback function for do_in_runtimepath().
+ */
+    static void
+gfp_setname(fname, cookie)
+    char_u	*fname;
+    void	*cookie;
+{
+    char_u	*gfp_buffer = cookie;
+
+    if (STRLEN(fname) >= MAXPATHL)
+	*gfp_buffer = NUL;
+    else
+	STRCPY(gfp_buffer, fname);
+}
+
+/*
+ * Find the path of bitmap "name" with extension "ext" in 'runtimepath'.
+ * Return FAIL for failure and OK if buffer[MAXPATHL] contains the result.
+ */
+    int
+gui_find_bitmap(name, buffer, ext)
+    char_u	*name;
+    char_u	*buffer;
+    char	*ext;
+{
+    if (STRLEN(name) > MAXPATHL - 14)
+	return FAIL;
+    vim_snprintf((char *)buffer, MAXPATHL, "bitmaps/%s.%s", name, ext);
+    if (do_in_runtimepath(buffer, FALSE, gfp_setname, buffer) == FAIL
+							    || *buffer == NUL)
+	return FAIL;
+    return OK;
+}
+
+# if !defined(HAVE_GTK2) || defined(PROTO)
+/*
+ * Given the name of the "icon=" argument, try finding the bitmap file for the
+ * icon.  If it is an absolute path name, use it as it is.  Otherwise append
+ * "ext" and search for it in 'runtimepath'.
+ * The result is put in "buffer[MAXPATHL]".  If something fails "buffer"
+ * contains "name".
+ */
+    void
+gui_find_iconfile(name, buffer, ext)
+    char_u	*name;
+    char_u	*buffer;
+    char	*ext;
+{
+    char_u	buf[MAXPATHL + 1];
+
+    expand_env(name, buffer, MAXPATHL);
+    if (!mch_isFullName(buffer) && gui_find_bitmap(buffer, buf, ext) == OK)
+	STRCPY(buffer, buf);
+}
+# endif
+#endif
+
+#if defined(FEAT_GUI_GTK) || defined(FEAT_GUI_X11) || defined(PROTO)
+    void
+display_errors()
+{
+    char_u	*p;
+
+    if (isatty(2))
+	fflush(stderr);
+    else if (error_ga.ga_data != NULL)
+    {
+	/* avoid putting up a message box with blanks only */
+	for (p = (char_u *)error_ga.ga_data; *p != NUL; ++p)
+	    if (!isspace(*p))
+	    {
+		/* Truncate a very long message, it will go off-screen. */
+		if (STRLEN(p) > 2000)
+		    STRCPY(p + 2000 - 14, "...(truncated)");
+		(void)do_dialog(VIM_ERROR, (char_u *)_("Error"),
+					      p, (char_u *)_("&Ok"), 1, NULL);
+		break;
+	    }
+	ga_clear(&error_ga);
+    }
+}
+#endif
+
+#if defined(NO_CONSOLE_INPUT) || defined(PROTO)
+/*
+ * Return TRUE if still starting up and there is no place to enter text.
+ * For GTK and X11 we check if stderr is not a tty, which means we were
+ * (probably) started from the desktop.  Also check stdin, "vim >& file" does
+ * allow typing on stdin.
+ */
+    int
+no_console_input()
+{
+    return ((!gui.in_use || gui.starting)
+# ifndef NO_CONSOLE
+	    && !isatty(0) && !isatty(2)
+# endif
+	    );
+}
+#endif
+
+#if defined(FIND_REPLACE_DIALOG) || defined(FEAT_SUN_WORKSHOP) \
+	|| defined(NEED_GUI_UPDATE_SCREEN) \
+	|| defined(PROTO)
+/*
+ * Update the current window and the screen.
+ */
+    void
+gui_update_screen()
+{
+    update_topline();
+    validate_cursor();
+    update_screen(0);	/* may need to update the screen */
+    setcursor();
+    out_flush();		/* make sure output has been written */
+    gui_update_cursor(TRUE, FALSE);
+    gui_mch_flush();
+}
+#endif
+
+#if defined(FIND_REPLACE_DIALOG) || defined(PROTO)
+static void concat_esc __ARGS((garray_T *gap, char_u *text, int what));
+
+/*
+ * Get the text to use in a find/replace dialog.  Uses the last search pattern
+ * if the argument is empty.
+ * Returns an allocated string.
+ */
+    char_u *
+get_find_dialog_text(arg, wwordp, mcasep)
+    char_u	*arg;
+    int		*wwordp;	/* return: TRUE if \< \> found */
+    int		*mcasep;	/* return: TRUE if \C found */
+{
+    char_u	*text;
+
+    if (*arg == NUL)
+	text = last_search_pat();
+    else
+	text = arg;
+    if (text != NULL)
+    {
+	text = vim_strsave(text);
+	if (text != NULL)
+	{
+	    int len = (int)STRLEN(text);
+	    int i;
+
+	    /* Remove "\V" */
+	    if (len >= 2 && STRNCMP(text, "\\V", 2) == 0)
+	    {
+		mch_memmove(text, text + 2, (size_t)(len - 1));
+		len -= 2;
+	    }
+
+	    /* Recognize "\c" and "\C" and remove. */
+	    if (len >= 2 && *text == '\\' && (text[1] == 'c' || text[1] == 'C'))
+	    {
+		*mcasep = (text[1] == 'C');
+		mch_memmove(text, text + 2, (size_t)(len - 1));
+		len -= 2;
+	    }
+
+	    /* Recognize "\<text\>" and remove. */
+	    if (len >= 4
+		    && STRNCMP(text, "\\<", 2) == 0
+		    && STRNCMP(text + len - 2, "\\>", 2) == 0)
+	    {
+		*wwordp = TRUE;
+		mch_memmove(text, text + 2, (size_t)(len - 4));
+		text[len - 4] = NUL;
+	    }
+
+	    /* Recognize "\/" or "\?" and remove. */
+	    for (i = 0; i + 1 < len; ++i)
+		if (text[i] == '\\' && (text[i + 1] == '/'
+						       || text[i + 1] == '?'))
+		{
+		    mch_memmove(text + i, text + i + 1, (size_t)(len - i));
+		    --len;
+		}
+	}
+    }
+    return text;
+}
+
+/*
+ * Concatenate "text" to grow array "gap", escaping "what" with a backslash.
+ */
+    static void
+concat_esc(gap, text, what)
+    garray_T	*gap;
+    char_u	*text;
+    int		what;
+{
+    while (*text != NUL)
+    {
+#ifdef FEAT_MBYTE
+	int l = (*mb_ptr2len)(text);
+
+	if (l > 1)
+	{
+	    while (--l >= 0)
+		ga_append(gap, *text++);
+	    continue;
+	}
+#endif
+	if (*text == what)
+	    ga_append(gap, '\\');
+	ga_append(gap, *text);
+	++text;
+    }
+}
+
+/*
+ * Handle the press of a button in the find-replace dialog.
+ * Return TRUE when something was added to the input buffer.
+ */
+    int
+gui_do_findrepl(flags, find_text, repl_text, down)
+    int		flags;		/* one of FRD_REPLACE, FRD_FINDNEXT, etc. */
+    char_u	*find_text;
+    char_u	*repl_text;
+    int		down;		/* Search downwards. */
+{
+    garray_T	ga;
+    int		i;
+    int		type = (flags & FRD_TYPE_MASK);
+    char_u	*p;
+    regmatch_T	regmatch;
+    int		save_did_emsg = did_emsg;
+
+    ga_init2(&ga, 1, 100);
+    if (type == FRD_REPLACEALL)
+	ga_concat(&ga, (char_u *)"%s/");
+
+    ga_concat(&ga, (char_u *)"\\V");
+    if (flags & FRD_MATCH_CASE)
+	ga_concat(&ga, (char_u *)"\\C");
+    else
+	ga_concat(&ga, (char_u *)"\\c");
+    if (flags & FRD_WHOLE_WORD)
+	ga_concat(&ga, (char_u *)"\\<");
+    if (type == FRD_REPLACEALL || down)
+	concat_esc(&ga, find_text, '/');	/* escape slashes */
+    else
+	concat_esc(&ga, find_text, '?');	/* escape '?' */
+    if (flags & FRD_WHOLE_WORD)
+	ga_concat(&ga, (char_u *)"\\>");
+
+    if (type == FRD_REPLACEALL)
+    {
+	ga_concat(&ga, (char_u *)"/");
+						/* escape / and \ */
+	p = vim_strsave_escaped(repl_text, (char_u *)"/\\");
+	if (p != NULL)
+	    ga_concat(&ga, p);
+	vim_free(p);
+	ga_concat(&ga, (char_u *)"/g");
+    }
+    ga_append(&ga, NUL);
+
+    if (type == FRD_REPLACE)
+    {
+	/* Do the replacement when the text at the cursor matches.  Thus no
+	 * replacement is done if the cursor was moved! */
+	regmatch.regprog = vim_regcomp(ga.ga_data, RE_MAGIC + RE_STRING);
+	regmatch.rm_ic = 0;
+	if (regmatch.regprog != NULL)
+	{
+	    p = ml_get_cursor();
+	    if (vim_regexec_nl(&regmatch, p, (colnr_T)0)
+						   && regmatch.startp[0] == p)
+	    {
+		/* Clear the command line to remove any old "No match"
+		 * error. */
+		msg_end_prompt();
+
+		if (u_save_cursor() == OK)
+		{
+		    /* A button was pressed thus undo should be synced. */
+		    u_sync(FALSE);
+
+		    del_bytes((long)(regmatch.endp[0] - regmatch.startp[0]),
+								FALSE, FALSE);
+		    ins_str(repl_text);
+		}
+	    }
+	    else
+		MSG(_("No match at cursor, finding next"));
+	    vim_free(regmatch.regprog);
+	}
+    }
+
+    if (type == FRD_REPLACEALL)
+    {
+	/* A button was pressed, thus undo should be synced. */
+	u_sync(FALSE);
+	do_cmdline_cmd(ga.ga_data);
+    }
+    else
+    {
+	/* Search for the next match. */
+	i = msg_scroll;
+	do_search(NULL, down ? '/' : '?', ga.ga_data, 1L,
+						    SEARCH_MSG + SEARCH_MARK);
+	msg_scroll = i;	    /* don't let an error message set msg_scroll */
+    }
+
+    /* Don't want to pass did_emsg to other code, it may cause disabling
+     * syntax HL if we were busy redrawing. */
+    did_emsg = save_did_emsg;
+
+    if (State & (NORMAL | INSERT))
+    {
+	gui_update_screen();		/* update the screen */
+	msg_didout = 0;			/* overwrite any message */
+	need_wait_return = FALSE;	/* don't wait for return */
+    }
+
+    vim_free(ga.ga_data);
+    return (ga.ga_len > 0);
+}
+
+#endif
+
+#if (defined(FEAT_DND) && defined(FEAT_GUI_GTK)) \
+	|| defined(FEAT_GUI_MSWIN) \
+	|| defined(FEAT_GUI_MAC) \
+	|| defined(PROTO)
+
+#ifdef FEAT_WINDOWS
+static void gui_wingoto_xy __ARGS((int x, int y));
+
+/*
+ * Jump to the window at specified point (x, y).
+ */
+    static void
+gui_wingoto_xy(x, y)
+    int x;
+    int y;
+{
+    int		row = Y_2_ROW(y);
+    int		col = X_2_COL(x);
+    win_T	*wp;
+
+    if (row >= 0 && col >= 0)
+    {
+	wp = mouse_find_win(&row, &col);
+	if (wp != NULL && wp != curwin)
+	    win_goto(wp);
+    }
+}
+#endif
+
+/*
+ * Process file drop.  Mouse cursor position, key modifiers, name of files
+ * and count of files are given.  Argument "fnames[count]" has full pathnames
+ * of dropped files, they will be freed in this function, and caller can't use
+ * fnames after call this function.
+ */
+/*ARGSUSED*/
+    void
+gui_handle_drop(x, y, modifiers, fnames, count)
+    int		x;
+    int		y;
+    int_u	modifiers;
+    char_u	**fnames;
+    int		count;
+{
+    int		i;
+    char_u	*p;
+
+    /*
+     * When the cursor is at the command line, add the file names to the
+     * command line, don't edit the files.
+     */
+    if (State & CMDLINE)
+    {
+	shorten_filenames(fnames, count);
+	for (i = 0; i < count; ++i)
+	{
+	    if (fnames[i] != NULL)
+	    {
+		if (i > 0)
+		    add_to_input_buf((char_u*)" ", 1);
+
+		/* We don't know what command is used thus we can't be sure
+		 * about which characters need to be escaped.  Only escape the
+		 * most common ones. */
+# ifdef BACKSLASH_IN_FILENAME
+		p = vim_strsave_escaped(fnames[i], (char_u *)" \t\"|");
+# else
+		p = vim_strsave_escaped(fnames[i], (char_u *)"\\ \t\"|");
+# endif
+		if (p != NULL)
+		    add_to_input_buf(p, (int)STRLEN(p));
+		vim_free(p);
+		vim_free(fnames[i]);
+	    }
+	}
+	vim_free(fnames);
+    }
+    else
+    {
+	/* Go to the window under mouse cursor, then shorten given "fnames" by
+	 * current window, because a window can have local current dir. */
+# ifdef FEAT_WINDOWS
+	gui_wingoto_xy(x, y);
+# endif
+	shorten_filenames(fnames, count);
+
+	/* If Shift held down, remember the first item. */
+	if ((modifiers & MOUSE_SHIFT) != 0)
+	    p = vim_strsave(fnames[0]);
+	else
+	    p = NULL;
+
+	/* Handle the drop, :edit or :split to get to the file.  This also
+	 * frees fnames[].  Skip this if there is only one item it's a
+	 * directory and Shift is held down. */
+	if (count == 1 && (modifiers & MOUSE_SHIFT) != 0
+						     && mch_isdir(fnames[0]))
+	{
+	    vim_free(fnames[0]);
+	    vim_free(fnames);
+	}
+	else
+	    handle_drop(count, fnames, (modifiers & MOUSE_CTRL) != 0);
+
+	/* If Shift held down, change to first file's directory.  If the first
+	 * item is a directory, change to that directory (and let the explorer
+	 * plugin show the contents). */
+	if (p != NULL)
+	{
+	    if (mch_isdir(p))
+	    {
+		if (mch_chdir((char *)p) == 0)
+		    shorten_fnames(TRUE);
+	    }
+	    else if (vim_chdirfile(p) == OK)
+		shorten_fnames(TRUE);
+	    vim_free(p);
+	}
+
+	/* Update the screen display */
+	update_screen(NOT_VALID);
+# ifdef FEAT_MENU
+	gui_update_menus(0);
+# endif
+	setcursor();
+	out_flush();
+	gui_update_cursor(FALSE, FALSE);
+	gui_mch_flush();
+    }
+}
+#endif
--- /dev/null
+++ b/gui.h
@@ -1,0 +1,567 @@
+/* vi:set ts=8 sts=4 sw=4:
+ *
+ * VIM - Vi IMproved		by Bram Moolenaar
+ *				Motif support by Robert Webb
+ *
+ * Do ":help uganda"  in Vim to read copying and usage conditions.
+ * Do ":help credits" in Vim to see a list of people who contributed.
+ */
+
+#ifdef FEAT_GUI_MOTIF
+# include <Xm/Xm.h>
+#endif
+
+#ifdef FEAT_GUI_ATHENA
+# include <X11/Intrinsic.h>
+# include <X11/StringDefs.h>
+#endif
+
+#ifdef FEAT_BEVAL
+# include "gui_beval.h"
+#endif
+
+#ifdef FEAT_GUI_GTK
+# ifdef VMS /* undef MIN and MAX because Intrinsic.h redefines them anyway */
+#  ifdef MAX
+#   undef MAX
+#  endif
+#  ifdef MIN
+#   undef MIN
+#  endif
+# endif
+# include <X11/Intrinsic.h>
+# include <gtk/gtk.h>
+#endif
+
+#ifdef FEAT_GUI_MAC
+# include <Types.h>
+/*# include <Memory.h>*/
+# include <Quickdraw.h>
+# include <Fonts.h>
+# include <Events.h>
+# include <Menus.h>
+# if !(defined (TARGET_API_MAC_CARBON) && (TARGET_API_MAC_CARBON))
+#   include <Windows.h>
+# endif
+# include <Controls.h>
+/*# include <TextEdit.h>*/
+# include <Dialogs.h>
+# include <OSUtils.h>
+/*
+# include <ToolUtils.h>
+# include <SegLoad.h>*/
+#endif
+
+#ifdef RISCOS
+# include "gui_riscos.h"
+#endif
+
+#ifdef FEAT_GUI_PHOTON
+# include <Ph.h>
+# include <Pt.h>
+# include "photon/PxProto.h"
+#endif
+
+/*
+ * On some systems, when we compile with the GUI, we always use it.  On Mac
+ * there is no terminal version, and on Windows we can't figure out how to
+ * fork one off with :gui.
+ */
+#if defined(FEAT_GUI_MSWIN) || (defined(FEAT_GUI_MAC) && !defined(MACOS_X_UNIX))
+# define ALWAYS_USE_GUI
+#endif
+
+/*
+ * On some systems scrolling needs to be done right away instead of in the
+ * main loop.
+ */
+#if defined(FEAT_GUI_MSWIN) || defined(FEAT_GUI_MAC) || defined(HAVE_GTK2)
+# define USE_ON_FLY_SCROLL
+#endif
+
+/*
+ * GUIs that support dropping files on a running Vim.
+ */
+#if defined(FEAT_GUI_MSWIN) || defined(FEAT_GUI_MAC) \
+	|| defined(FEAT_GUI_GTK)
+# define HAVE_DROP_FILE
+#endif
+
+/*
+ * This define makes menus always use a fontset.
+ * We're not sure if this code always works, thus it can be disabled.
+ */
+#ifdef FEAT_XFONTSET
+# define FONTSET_ALWAYS
+#endif
+
+/*
+ * These macros convert between character row/column and pixel coordinates.
+ * TEXT_X   - Convert character column into X pixel coord for drawing strings.
+ * TEXT_Y   - Convert character row into Y pixel coord for drawing strings.
+ * FILL_X   - Convert character column into X pixel coord for filling the area
+ *		under the character.
+ * FILL_Y   - Convert character row into Y pixel coord for filling the area
+ *		under the character.
+ * X_2_COL  - Convert X pixel coord into character column.
+ * Y_2_ROW  - Convert Y pixel coord into character row.
+ */
+#ifdef FEAT_GUI_W32
+# define TEXT_X(col)	((col) * gui.char_width)
+# define TEXT_Y(row)	((row) * gui.char_height + gui.char_ascent)
+# define FILL_X(col)	((col) * gui.char_width)
+# define FILL_Y(row)	((row) * gui.char_height)
+# define X_2_COL(x)	((x) / gui.char_width)
+# define Y_2_ROW(y)	((y) / gui.char_height)
+#else
+# define TEXT_X(col)	((col) * gui.char_width  + gui.border_offset)
+# define FILL_X(col)	((col) * gui.char_width  + gui.border_offset)
+# define X_2_COL(x)	(((x) - gui.border_offset) / gui.char_width)
+# define TEXT_Y(row)	((row) * gui.char_height + gui.char_ascent \
+							+ gui.border_offset)
+# define FILL_Y(row)	((row) * gui.char_height + gui.border_offset)
+# define Y_2_ROW(y)	(((y) - gui.border_offset) / gui.char_height)
+#endif
+
+/* Indices for arrays of scrollbars */
+#define SBAR_NONE	    -1
+#define SBAR_LEFT	    0
+#define SBAR_RIGHT	    1
+#define SBAR_BOTTOM	    2
+
+/* Orientations for scrollbars */
+#define SBAR_VERT	    0
+#define SBAR_HORIZ	    1
+
+/* Default size of scrollbar */
+#define SB_DEFAULT_WIDTH    16
+
+/* Default height of the menu bar */
+#define MENU_DEFAULT_HEIGHT 1		/* figure it out at runtime */
+
+/* Flags for gui_mch_outstr_nowrap() */
+#define GUI_MON_WRAP_CURSOR	0x01	/* wrap cursor at end of line */
+#define GUI_MON_INVERT		0x02	/* invert the characters */
+#define GUI_MON_IS_CURSOR	0x04	/* drawing cursor */
+#define GUI_MON_TRS_CURSOR	0x08	/* drawing transparent cursor */
+#define GUI_MON_NOCLEAR		0x10	/* don't clear selection */
+
+/* Flags for gui_mch_draw_string() */
+#define DRAW_TRANSP		0x01	/* draw with transparent bg */
+#define DRAW_BOLD		0x02	/* draw bold text */
+#define DRAW_UNDERL		0x04	/* draw underline text */
+#define DRAW_UNDERC		0x08	/* draw undercurl text */
+#if defined(RISCOS) || defined(HAVE_GTK2)
+# define DRAW_ITALIC		0x10	/* draw italic text */
+#endif
+#define DRAW_CURSOR		0x20	/* drawing block cursor (win32) */
+
+/* For our own tearoff menu item */
+#define TEAR_STRING		"-->Detach"
+#define TEAR_LEN		(9)	/* length of above string */
+
+/* for the toolbar */
+#ifdef FEAT_GUI_W16
+# define TOOLBAR_BUTTON_HEIGHT	15
+# define TOOLBAR_BUTTON_WIDTH	16
+#else
+# define TOOLBAR_BUTTON_HEIGHT	18
+# define TOOLBAR_BUTTON_WIDTH	18
+#endif
+#define TOOLBAR_BORDER_HEIGHT	12  /* room above+below buttons for MSWindows */
+
+#ifdef FEAT_GUI_MSWIN
+# define TABLINE_HEIGHT 22
+#endif
+#ifdef FEAT_GUI_MOTIF
+# define TABLINE_HEIGHT 30
+#endif
+
+#if defined(NO_CONSOLE) || defined(FEAT_GUI_GTK) || defined(FEAT_GUI_X11)
+# define NO_CONSOLE_INPUT	/* use no_console_input() to check if there
+				   is no console input possible */
+#endif
+
+typedef struct GuiScrollbar
+{
+    long	ident;		/* Unique identifier for each scrollbar */
+    win_T	*wp;		/* Scrollbar's window, NULL for bottom */
+    int		type;		/* one of SBAR_{LEFT,RIGHT,BOTTOM} */
+    long	value;		/* Represents top line number visible */
+#ifdef FEAT_GUI_ATHENA
+    int		pixval;		/* pixel count of value */
+#endif
+    long	size;		/* Size of scrollbar thumb */
+    long	max;		/* Number of lines in buffer */
+
+    /* Values measured in characters: */
+    int		top;		/* Top of scroll bar (chars from row 0) */
+    int		height;		/* Current height of scroll bar in rows */
+#ifdef FEAT_VERTSPLIT
+    int		width;		/* Current width of scroll bar in cols */
+#endif
+    int		status_height;	/* Height of status line */
+#ifdef FEAT_GUI_X11
+    Widget	id;		/* Id of real scroll bar */
+#endif
+#ifdef FEAT_GUI_GTK
+    GtkWidget *id;		/* Id of real scroll bar */
+    unsigned long handler_id;   /* Id of "value_changed" signal handler */
+#endif
+
+#ifdef FEAT_GUI_MSWIN
+    HWND	id;		/* Id of real scroll bar */
+    int		scroll_shift;	/* The scrollbar stuff can handle only up to
+				   32767 lines.  When the file is longer,
+				   scroll_shift is set to the number of shifts
+				   to reduce the count.  */
+#endif
+#ifdef FEAT_GUI_MAC
+    ControlHandle id;		/* A handle to the scrollbar */
+#endif
+#ifdef RISCOS
+    int		id;		/* Window handle of scrollbar window */
+#endif
+#ifdef FEAT_GUI_PHOTON
+    PtWidget_t	*id;
+#endif
+} scrollbar_T;
+
+typedef long	    guicolor_T;	/* handle for a GUI color; for X11 this should
+				   be "Pixel", but that's an unsigned and we
+				   need a signed value */
+#define INVALCOLOR (guicolor_T)-11111	/* number for invalid color; on 32 bit
+				   displays there is a tiny chance this is an
+				   actual color */
+
+#ifdef FEAT_GUI_GTK
+# ifdef HAVE_GTK2
+  typedef PangoFontDescription	*GuiFont;       /* handle for a GUI font */
+  typedef PangoFontDescription  *GuiFontset;    /* handle for a GUI fontset */
+# else
+  typedef GdkFont	*GuiFont;	/* handle for a GUI font */
+  typedef GdkFont	*GuiFontset;	/* handle for a GUI fontset */
+# endif
+# define NOFONT		(GuiFont)NULL
+# define NOFONTSET	(GuiFontset)NULL
+#else
+# ifdef FEAT_GUI_PHOTON
+  typedef char		*GuiFont;
+  typedef char		*GuiFontset;
+#  define NOFONT	(GuiFont)NULL
+#  define NOFONTSET	(GuiFontset)NULL
+# else
+#  ifdef FEAT_GUI_X11
+  typedef XFontStruct	*GuiFont;	/* handle for a GUI font */
+  typedef XFontSet	GuiFontset;	/* handle for a GUI fontset */
+#   define NOFONT	(GuiFont)0
+#   define NOFONTSET	(GuiFontset)0
+#  else
+  typedef long_u	GuiFont;	/* handle for a GUI font */
+  typedef long_u	GuiFontset;	/* handle for a GUI fontset */
+#   define NOFONT	(GuiFont)0
+#   define NOFONTSET	(GuiFontset)0
+#  endif
+# endif
+#endif
+
+typedef struct Gui
+{
+    int		in_focus;	    /* Vim has input focus */
+    int		in_use;		    /* Is the GUI being used? */
+    int		starting;	    /* GUI will start in a little while */
+    int		shell_created;	    /* Has the shell been created yet? */
+    int		dying;		    /* Is vim dying? Then output to terminal */
+    int		dofork;		    /* Use fork() when GUI is starting */
+    int		dragged_sb;	    /* Which scrollbar being dragged, if any? */
+    win_T	*dragged_wp;	    /* Which WIN's sb being dragged, if any? */
+    int		pointer_hidden;	    /* Is the mouse pointer hidden? */
+    int		col;		    /* Current cursor column in GUI display */
+    int		row;		    /* Current cursor row in GUI display */
+    int		cursor_col;	    /* Physical cursor column in GUI display */
+    int		cursor_row;	    /* Physical cursor row in GUI display */
+    char	cursor_is_valid;    /* There is a cursor at cursor_row/col */
+    int		num_cols;	    /* Number of columns */
+    int		num_rows;	    /* Number of rows */
+    int		scroll_region_top;  /* Top (first) line of scroll region */
+    int		scroll_region_bot;  /* Bottom (last) line of scroll region */
+    int		scroll_region_left;  /* Left (first) column of scroll region */
+    int		scroll_region_right;  /* Right (last) col. of scroll region */
+    int		highlight_mask;	    /* Highlight attribute mask */
+    int		scrollbar_width;    /* Width of vertical scrollbars */
+    int		scrollbar_height;   /* Height of horizontal scrollbar */
+    int		left_sbar_x;	    /* Calculated x coord for left scrollbar */
+    int		right_sbar_x;	    /* Calculated x coord for right scrollbar */
+
+#ifdef FEAT_MENU
+# ifndef FEAT_GUI_GTK
+    int		menu_height;	    /* Height of the menu bar */
+    int		menu_width;	    /* Width of the menu bar */
+# endif
+    char	menu_is_active;	    /* TRUE if menu is present */
+# ifdef FEAT_GUI_ATHENA
+    char	menu_height_fixed;  /* TRUE if menu height fixed */
+# endif
+#endif
+
+    scrollbar_T bottom_sbar;	    /* Bottom scrollbar */
+    int		which_scrollbars[3];/* Which scrollbar boxes are active? */
+    int		prev_wrap;	    /* For updating the horizontal scrollbar */
+    int		char_width;	    /* Width of char cell in pixels */
+    int		char_height;	    /* Height of char cell in pixels, includes
+				       'linespace' */
+    int		char_ascent;	    /* Ascent of char in pixels */
+    int		border_width;	    /* Width of our border around text area */
+    int		border_offset;	    /* Total pixel offset for all borders */
+
+    GuiFont	norm_font;	    /* Normal font */
+#ifndef HAVE_GTK2
+    GuiFont	bold_font;	    /* Bold font */
+    GuiFont	ital_font;	    /* Italic font */
+    GuiFont	boldital_font;	    /* Bold-Italic font */
+#else
+    int		font_can_bold;	    /* Whether norm_font supports bold weight.
+				     * The styled font variants are not used. */
+#endif
+
+#if defined(FEAT_MENU) && !defined(HAVE_GTK2)
+# ifdef FONTSET_ALWAYS
+    GuiFontset	menu_fontset;	    /* set of fonts for multi-byte chars */
+# else
+    GuiFont	menu_font;	    /* menu item font */
+# endif
+#endif
+#ifdef FEAT_MBYTE
+    GuiFont	wide_font;	    /* 'guifontwide' font */
+#endif
+#ifdef FEAT_XFONTSET
+    GuiFontset	fontset;	    /* set of fonts for multi-byte chars */
+#endif
+    guicolor_T	back_pixel;	    /* Color of background */
+    guicolor_T	norm_pixel;	    /* Color of normal text */
+    guicolor_T	def_back_pixel;	    /* default Color of background */
+    guicolor_T	def_norm_pixel;	    /* default Color of normal text */
+
+#ifdef FEAT_GUI_X11
+    char	*rsrc_menu_fg_name;	/* Color of menu & dialog foreground */
+    guicolor_T	menu_fg_pixel;		/* Same in Pixel format */
+    char	*rsrc_menu_bg_name;	/* Color of menu & dialog background */
+    guicolor_T	menu_bg_pixel;		/* Same in Pixel format */
+    char	*rsrc_scroll_fg_name;	/* Color of scrollbar foreground */
+    guicolor_T	scroll_fg_pixel;	/* Same in Pixel format */
+    char	*rsrc_scroll_bg_name;	/* Color of scrollbar background */
+    guicolor_T	scroll_bg_pixel;	/* Same in Pixel format */
+
+# ifdef FEAT_GUI_MOTIF
+    guicolor_T	menu_def_fg_pixel;  /* Default menu foreground */
+    guicolor_T	menu_def_bg_pixel;  /* Default menu background */
+    guicolor_T	scroll_def_fg_pixel;  /* Default scrollbar foreground */
+    guicolor_T	scroll_def_bg_pixel;  /* Default scrollbar background */
+# endif
+    Display	*dpy;		    /* X display */
+    Window	wid;		    /* Window id of text area */
+    int		visibility;	    /* Is shell partially/fully obscured? */
+    GC		text_gc;
+    GC		back_gc;
+    GC		invert_gc;
+    Cursor	blank_pointer;	    /* Blank pointer */
+
+    /* X Resources */
+    char_u	*rsrc_font_name;    /* Resource font name, used if 'guifont'
+				       not set */
+    char_u	*rsrc_bold_font_name; /* Resource bold font name */
+    char_u	*rsrc_ital_font_name; /* Resource italic font name */
+    char_u	*rsrc_boldital_font_name;  /* Resource bold-italic font name */
+    char_u	*rsrc_menu_font_name;    /* Resource menu Font name */
+    Bool	rsrc_rev_video;	    /* Use reverse video? */
+
+    char_u	*geom;		    /* Geometry, eg "80x24" */
+    Bool	color_approx;	    /* Some color was approximated */
+#endif
+
+#ifdef FEAT_GUI_GTK
+    int		visibility;	    /* Is shell partially/fully obscured? */
+    GdkCursor	*blank_pointer;	    /* Blank pointer */
+
+    /* X Resources */
+    char_u	*geom;		    /* Geometry, eg "80x24" */
+
+    GtkWidget	*mainwin;	    /* top level GTK window */
+    GtkWidget	*formwin;	    /* manages all the windows below */
+    GtkWidget	*drawarea;	    /* the "text" area */
+# ifdef FEAT_MENU
+    GtkWidget	*menubar;	    /* menubar */
+# endif
+# ifdef FEAT_TOOLBAR
+    GtkWidget	*toolbar;	    /* toolbar */
+# endif
+# ifdef FEAT_GUI_GNOME
+    GtkWidget	*menubar_h;	    /* menubar handle */
+    GtkWidget	*toolbar_h;	    /* toolbar handle */
+# endif
+    GdkColor	*fgcolor;	    /* GDK-styled foreground color */
+    GdkColor	*bgcolor;	    /* GDK-styled background color */
+    GdkColor	*spcolor;	    /* GDK-styled special color */
+# ifndef HAVE_GTK2
+    GuiFont	current_font;
+# endif
+    GdkGC	*text_gc;	    /* cached GC for normal text */
+# ifdef HAVE_GTK2
+    PangoContext     *text_context; /* the context used for all text */
+    PangoFont	     *ascii_font;   /* cached font for ASCII strings */
+    PangoGlyphString *ascii_glyphs; /* cached code point -> glyph map */
+# endif
+# ifdef FEAT_GUI_TABLINE
+    GtkWidget	*tabline;	    /* tab pages line handle */
+# endif
+
+    GtkAccelGroup *accel_group;
+# ifndef HAVE_GTK2
+    GtkWidget	*fontdlg;	    /* font selection dialog window */
+    char_u	*fontname;	    /* font name from font selection dialog */
+# endif
+    GtkWidget	*filedlg;	    /* file selection dialog */
+    char_u	*browse_fname;	    /* file name from filedlg */
+#endif	/* FEAT_GUI_GTK */
+
+#if defined(FEAT_GUI_TABLINE) \
+ 	&& (defined(FEAT_GUI_W32) || defined(FEAT_GUI_MOTIF) \
+                 || defined(FEAT_GUI_MAC))
+    int		tabline_height;
+#endif
+
+#ifdef FEAT_FOOTER
+    int		footer_height;	    /* height of the message footer */
+#endif
+
+#if defined(FEAT_TOOLBAR) \
+	&& (defined(FEAT_GUI_ATHENA) || defined(FEAT_GUI_MOTIF))
+    int		toolbar_height;	    /* height of the toolbar */
+#endif
+
+#ifdef FEAT_BEVAL_TIP
+    /* Tooltip properties; also used for balloon evaluation */
+    char_u	*rsrc_tooltip_font_name; /* tooltip font name */
+    char	*rsrc_tooltip_fg_name;	/* tooltip foreground color name */
+    char	*rsrc_tooltip_bg_name;	/* tooltip background color name */
+    guicolor_T	tooltip_fg_pixel;	/* tooltip foreground color */
+    guicolor_T	tooltip_bg_pixel;	/* tooltip background color */
+    XFontSet	tooltip_fontset;	/* tooltip fontset */
+#endif
+
+#ifdef FEAT_GUI_MSWIN
+    GuiFont	currFont;	    /* Current font */
+    guicolor_T	currFgColor;	    /* Current foreground text color */
+    guicolor_T	currBgColor;	    /* Current background text color */
+    guicolor_T	currSpColor;	    /* Current special text color */
+#endif
+
+#ifdef FEAT_GUI_MAC
+    WindowPtr	VimWindow;
+    MenuHandle	MacOSHelpMenu;	    /* Help menu provided by the MacOS */
+    int		MacOSHelpItems;	    /* Nr of help-items supplied by MacOS */
+    int		MacOSHaveCntxMenu;  /* Contextual menu available */
+    WindowPtr	wid;		    /* Window id of text area */
+    int		visibility;	    /* Is window partially/fully obscured? */
+#endif
+
+#ifdef RISCOS
+    int		window_handle;
+    char_u	*window_title;
+    int		window_title_size;
+    int		fg_colour;		/* in 0xBBGGRR format */
+    int		bg_colour;
+#endif
+
+#ifdef FEAT_GUI_PHOTON
+    PtWidget_t	*vimWindow;		/* PtWindow */
+    PtWidget_t	*vimTextArea;		/* PtRaw */
+    PtWidget_t	*vimContainer;		/* PtPanel */
+# if defined(FEAT_MENU) || defined(FEAT_TOOLBAR)
+    PtWidget_t	*vimToolBarGroup;
+# endif
+# ifdef FEAT_MENU
+    PtWidget_t	*vimMenuBar;
+# endif
+# ifdef FEAT_TOOLBAR
+    PtWidget_t	*vimToolBar;
+    int		toolbar_height;
+# endif
+    PhEvent_t	*event_buffer;
+#endif
+
+#ifdef FEAT_XIM
+    char	*rsrc_input_method;
+    char	*rsrc_preedit_type_name;
+#endif
+} gui_T;
+
+extern gui_T gui;			/* this is defined in gui.c */
+
+/* definitions of available window positionings for gui_*_position_in_parent()
+ */
+typedef enum
+{
+    VW_POS_MOUSE,
+    VW_POS_CENTER,
+    VW_POS_TOP_CENTER
+} gui_win_pos_T;
+
+#ifdef FIND_REPLACE_DIALOG
+/*
+ * Flags used to distinguish the different contexts in which the
+ * find/replace callback may be called.
+ */
+# define FRD_FINDNEXT	1	/* Find next in find dialog */
+# define FRD_R_FINDNEXT	2	/* Find next in repl dialog */
+# define FRD_REPLACE	3	/* Replace once */
+# define FRD_REPLACEALL	4	/* Replace remaining matches */
+# define FRD_UNDO	5	/* Undo replaced text */
+# define FRD_TYPE_MASK   7	/* Mask for the callback type */
+/* Flags which change the way searching is done. */
+# define FRD_WHOLE_WORD	0x08	/* match whole word only */
+# define FRD_MATCH_CASE	0x10	/* match case */
+#endif
+
+#ifdef HAVE_GTK2
+/*
+ * Convenience macros to convert from 'encoding' to 'termencoding' and
+ * vice versa.	If no conversion is necessary the passed-in pointer is
+ * returned as is, without allocating any memory.  Thus additional _FREE()
+ * macros are provided.  The _FREE() macros also set the pointer to NULL,
+ * in order to avoid bugs due to illegal memory access only happening if
+ * 'encoding' != utf-8...
+ *
+ * Defining these macros as pure expressions looks a bit tricky but
+ * avoids depending on the context of the macro expansion.  One of the
+ * rare occasions where the comma operator comes in handy :)
+ *
+ * Note: Do NOT keep the result around when handling control back to
+ * the main Vim!  The user could change 'encoding' at any time.
+ */
+# define CONVERT_TO_UTF8(String)				\
+    ((output_conv.vc_type == CONV_NONE || (String) == NULL)	\
+	    ? (String)						\
+	    : string_convert(&output_conv, (String), NULL))
+
+# define CONVERT_TO_UTF8_FREE(String)				\
+    ((String) = ((output_conv.vc_type == CONV_NONE)		\
+			? (char_u *)NULL			\
+			: (vim_free(String), (char_u *)NULL)))
+
+# define CONVERT_FROM_UTF8(String)				\
+    ((input_conv.vc_type == CONV_NONE || (String) == NULL)	\
+	    ? (String)						\
+	    : string_convert(&input_conv, (String), NULL))
+
+# define CONVERT_FROM_UTF8_FREE(String)				\
+    ((String) = ((input_conv.vc_type == CONV_NONE)		\
+			? (char_u *)NULL			\
+			: (vim_free(String), (char_u *)NULL)))
+
+#else
+# define CONVERT_TO_UTF8(String) (String)
+# define CONVERT_TO_UTF8_FREE(String) ((String) = (char_u *)NULL)
+# define CONVERT_FROM_UTF8(String) (String)
+# define CONVERT_FROM_UTF8_FREE(String) ((String) = (char_u *)NULL)
+#endif /* HAVE_GTK2 */
--- /dev/null
+++ b/gui_beval.c
@@ -1,0 +1,1379 @@
+/* vi:set ts=8 sts=4 sw=4:
+ *
+ * VIM - Vi IMproved	by Bram Moolenaar
+ *			Visual Workshop integration by Gordon Prieur
+ *
+ * Do ":help uganda"  in Vim to read copying and usage conditions.
+ * Do ":help credits" in Vim to see a list of people who contributed.
+ * See README.txt for an overview of the Vim source code.
+ */
+
+#include "vim.h"
+
+#if defined(FEAT_BEVAL) || defined(PROTO)
+
+/*
+ * Common code, invoked when the mouse is resting for a moment.
+ */
+/*ARGSUSED*/
+    void
+general_beval_cb(beval, state)
+    BalloonEval *beval;
+    int state;
+{
+    win_T	*wp;
+    int		col;
+    int		use_sandbox;
+    linenr_T	lnum;
+    char_u	*text;
+    static char_u  *result = NULL;
+    long	winnr = 0;
+    char_u	*bexpr;
+    buf_T	*save_curbuf;
+#ifdef FEAT_WINDOWS
+    win_T	*cw;
+#endif
+    static int	recursive = FALSE;
+
+    /* Don't do anything when 'ballooneval' is off, messages scrolled the
+     * windows up or we have no beval area. */
+    if (!p_beval || balloonEval == NULL || msg_scrolled > 0)
+	return;
+
+    /* Don't do this recursively.  Happens when the expression evaluation
+     * takes a long time and invokes something that checks for CTRL-C typed. */
+    if (recursive)
+	return;
+    recursive = TRUE;
+
+#ifdef FEAT_EVAL
+    if (get_beval_info(balloonEval, TRUE, &wp, &lnum, &text, &col) == OK)
+    {
+	bexpr = (*wp->w_buffer->b_p_bexpr == NUL) ? p_bexpr
+						    : wp->w_buffer->b_p_bexpr;
+	if (*bexpr != NUL)
+	{
+# ifdef FEAT_WINDOWS
+	    /* Convert window pointer to number. */
+	    for (cw = firstwin; cw != wp; cw = cw->w_next)
+		++winnr;
+# endif
+
+	    set_vim_var_nr(VV_BEVAL_BUFNR, (long)wp->w_buffer->b_fnum);
+	    set_vim_var_nr(VV_BEVAL_WINNR, winnr);
+	    set_vim_var_nr(VV_BEVAL_LNUM, (long)lnum);
+	    set_vim_var_nr(VV_BEVAL_COL, (long)(col + 1));
+	    set_vim_var_string(VV_BEVAL_TEXT, text, -1);
+	    vim_free(text);
+
+	    /*
+	     * Temporarily change the curbuf, so that we can determine whether
+	     * the buffer-local balloonexpr option was set insecurely.
+	     */
+	    save_curbuf = curbuf;
+	    curbuf = wp->w_buffer;
+	    use_sandbox = was_set_insecurely((char_u *)"balloonexpr",
+				 *curbuf->b_p_bexpr == NUL ? 0 : OPT_LOCAL);
+	    curbuf = save_curbuf;
+	    if (use_sandbox)
+		++sandbox;
+	    ++textlock;
+
+	    vim_free(result);
+	    result = eval_to_string(bexpr, NULL, TRUE);
+
+	    if (use_sandbox)
+		--sandbox;
+	    --textlock;
+
+	    set_vim_var_string(VV_BEVAL_TEXT, NULL, -1);
+	    if (result != NULL && result[0] != NUL)
+	    {
+		gui_mch_post_balloon(beval, result);
+		recursive = FALSE;
+		return;
+	    }
+	}
+    }
+#endif
+#ifdef FEAT_NETBEANS_INTG
+    if (bevalServers & BEVAL_NETBEANS)
+	netbeans_beval_cb(beval, state);
+#endif
+#ifdef FEAT_SUN_WORKSHOP
+    if (bevalServers & BEVAL_WORKSHOP)
+	workshop_beval_cb(beval, state);
+#endif
+
+    recursive = FALSE;
+}
+
+/* on Win32 only get_beval_info() is required */
+#if !defined(FEAT_GUI_W32) || defined(PROTO)
+
+#ifdef FEAT_GUI_GTK
+# include <gdk/gdkkeysyms.h>
+# include <gtk/gtk.h>
+#else
+# include <X11/keysym.h>
+# ifdef FEAT_GUI_MOTIF
+#  include <Xm/PushB.h>
+#  include <Xm/Separator.h>
+#  include <Xm/List.h>
+#  include <Xm/Label.h>
+#  include <Xm/AtomMgr.h>
+#  include <Xm/Protocols.h>
+# else
+   /* Assume Athena */
+#  include <X11/Shell.h>
+#  ifdef FEAT_GUI_NEXTAW
+#   include <X11/neXtaw/Label.h>
+#  else
+#   include <X11/Xaw/Label.h>
+#  endif
+# endif
+#endif
+
+#include "gui_beval.h"
+
+#ifndef FEAT_GUI_GTK
+extern Widget vimShell;
+
+/*
+ * Currently, we assume that there can be only one BalloonEval showing
+ * on-screen at any given moment.  This variable will hold the currently
+ * showing BalloonEval or NULL if none is showing.
+ */
+static BalloonEval *current_beval = NULL;
+#endif
+
+#ifdef FEAT_GUI_GTK
+static void addEventHandler __ARGS((GtkWidget *, BalloonEval *));
+static void removeEventHandler __ARGS((BalloonEval *));
+static gint target_event_cb __ARGS((GtkWidget *, GdkEvent *, gpointer));
+static gint mainwin_event_cb __ARGS((GtkWidget *, GdkEvent *, gpointer));
+static void pointer_event __ARGS((BalloonEval *, int, int, unsigned));
+static void key_event __ARGS((BalloonEval *, unsigned, int));
+static gint timeout_cb __ARGS((gpointer));
+static gint balloon_expose_event_cb __ARGS((GtkWidget *, GdkEventExpose *, gpointer));
+# ifndef HAVE_GTK2
+static void balloon_draw_cb __ARGS((GtkWidget *, GdkRectangle *, gpointer));
+# endif
+#else
+static void addEventHandler __ARGS((Widget, BalloonEval *));
+static void removeEventHandler __ARGS((BalloonEval *));
+static void pointerEventEH __ARGS((Widget, XtPointer, XEvent *, Boolean *));
+static void pointerEvent __ARGS((BalloonEval *, XEvent *));
+static void timerRoutine __ARGS((XtPointer, XtIntervalId *));
+#endif
+static void cancelBalloon __ARGS((BalloonEval *));
+static void requestBalloon __ARGS((BalloonEval *));
+static void drawBalloon __ARGS((BalloonEval *));
+static void undrawBalloon __ARGS((BalloonEval *beval));
+static void createBalloonEvalWindow __ARGS((BalloonEval *));
+
+
+
+/*
+ * Create a balloon-evaluation area for a Widget.
+ * There can be either a "mesg" for a fixed string or "mesgCB" to generate a
+ * message by calling this callback function.
+ * When "mesg" is not NULL it must remain valid for as long as the balloon is
+ * used.  It is not freed here.
+ * Returns a pointer to the resulting object (NULL when out of memory).
+ */
+    BalloonEval *
+gui_mch_create_beval_area(target, mesg, mesgCB, clientData)
+    void	*target;
+    char_u	*mesg;
+    void	(*mesgCB)__ARGS((BalloonEval *, int));
+    void	*clientData;
+{
+#ifndef FEAT_GUI_GTK
+    char	*display_name;	    /* get from gui.dpy */
+    int		screen_num;
+    char	*p;
+#endif
+    BalloonEval	*beval;
+
+    if (mesg != NULL && mesgCB != NULL)
+    {
+	EMSG(_("E232: Cannot create BalloonEval with both message and callback"));
+	return NULL;
+    }
+
+    beval = (BalloonEval *)alloc(sizeof(BalloonEval));
+    if (beval != NULL)
+    {
+#ifdef FEAT_GUI_GTK
+	beval->target = GTK_WIDGET(target);
+	beval->balloonShell = NULL;
+	beval->timerID = 0;
+#else
+	beval->target = (Widget)target;
+	beval->balloonShell = NULL;
+	beval->timerID = (XtIntervalId)NULL;
+	beval->appContext = XtWidgetToApplicationContext((Widget)target);
+#endif
+	beval->showState = ShS_NEUTRAL;
+	beval->x = 0;
+	beval->y = 0;
+	beval->msg = mesg;
+	beval->msgCB = mesgCB;
+	beval->clientData = clientData;
+
+	/*
+	 * Set up event handler which will keep its eyes on the pointer,
+	 * and when the pointer rests in a certain spot for a given time
+	 * interval, show the beval.
+	 */
+	addEventHandler(beval->target, beval);
+	createBalloonEvalWindow(beval);
+
+#ifndef FEAT_GUI_GTK
+	/*
+	 * Now create and save the screen width and height. Used in drawing.
+	 */
+	display_name = DisplayString(gui.dpy);
+	p = strrchr(display_name, '.');
+	if (p != NULL)
+	    screen_num = atoi(++p);
+	else
+	    screen_num = 0;
+	beval->screen_width = DisplayWidth(gui.dpy, screen_num);
+	beval->screen_height = DisplayHeight(gui.dpy, screen_num);
+#endif
+    }
+
+    return beval;
+}
+
+#if defined(FEAT_BEVAL_TIP) || defined(PROTO)
+/*
+ * Destroy a balloon-eval and free its associated memory.
+ */
+    void
+gui_mch_destroy_beval_area(beval)
+    BalloonEval	*beval;
+{
+    cancelBalloon(beval);
+    removeEventHandler(beval);
+    /* Children will automatically be destroyed */
+# ifdef FEAT_GUI_GTK
+    gtk_widget_destroy(beval->balloonShell);
+# else
+    XtDestroyWidget(beval->balloonShell);
+# endif
+    vim_free(beval);
+}
+#endif
+
+    void
+gui_mch_enable_beval_area(beval)
+    BalloonEval	*beval;
+{
+    if (beval != NULL)
+	addEventHandler(beval->target, beval);
+}
+
+    void
+gui_mch_disable_beval_area(beval)
+    BalloonEval	*beval;
+{
+    if (beval != NULL)
+	removeEventHandler(beval);
+}
+
+#if defined(FEAT_BEVAL_TIP) || defined(PROTO)
+/*
+ * This function returns the BalloonEval * associated with the currently
+ * displayed tooltip.  Returns NULL if there is no tooltip currently showing.
+ *
+ * Assumption: Only one tooltip can be shown at a time.
+ */
+    BalloonEval *
+gui_mch_currently_showing_beval()
+{
+    return current_beval;
+}
+#endif
+#endif /* !FEAT_GUI_W32 */
+
+#if defined(FEAT_SUN_WORKSHOP) || defined(FEAT_NETBEANS_INTG) \
+    || defined(FEAT_EVAL) || defined(PROTO)
+/*
+ * Get the text and position to be evaluated for "beval".
+ * If "getword" is true the returned text is not the whole line but the
+ * relevant word in allocated memory.
+ * Returns OK or FAIL.
+ */
+    int
+get_beval_info(beval, getword, winp, lnump, textp, colp)
+    BalloonEval	*beval;
+    int		getword;
+    win_T	**winp;
+    linenr_T	*lnump;
+    char_u	**textp;
+    int		*colp;
+{
+    win_T	*wp;
+    int		row, col;
+    char_u	*lbuf;
+    linenr_T	lnum;
+
+    *textp = NULL;
+    row = Y_2_ROW(beval->y);
+    col = X_2_COL(beval->x);
+#ifdef FEAT_WINDOWS
+    wp = mouse_find_win(&row, &col);
+#else
+    wp = firstwin;
+#endif
+    if (wp != NULL && row < wp->w_height && col < W_WIDTH(wp))
+    {
+	/* Found a window and the cursor is in the text.  Now find the line
+	 * number. */
+	if (!mouse_comp_pos(wp, &row, &col, &lnum))
+	{
+	    /* Not past end of the file. */
+	    lbuf = ml_get_buf(wp->w_buffer, lnum, FALSE);
+	    if (col <= win_linetabsize(wp, lbuf, (colnr_T)MAXCOL))
+	    {
+		/* Not past end of line. */
+		if (getword)
+		{
+		    /* For Netbeans we get the relevant part of the line
+		     * instead of the whole line. */
+		    int		len;
+		    pos_T	*spos = NULL, *epos = NULL;
+
+		    if (VIsual_active)
+		    {
+			if (lt(VIsual, curwin->w_cursor))
+			{
+			    spos = &VIsual;
+			    epos = &curwin->w_cursor;
+			}
+			else
+			{
+			    spos = &curwin->w_cursor;
+			    epos = &VIsual;
+			}
+		    }
+
+		    col = vcol2col(wp, lnum, col) - 1;
+
+		    if (VIsual_active
+			    && wp->w_buffer == curwin->w_buffer
+			    && (lnum == spos->lnum
+				? col >= (int)spos->col
+				: lnum > spos->lnum)
+			    && (lnum == epos->lnum
+				? col <= (int)epos->col
+				: lnum < epos->lnum))
+		    {
+			/* Visual mode and pointing to the line with the
+			 * Visual selection: return selected text, with a
+			 * maximum of one line. */
+			if (spos->lnum != epos->lnum || spos->col == epos->col)
+			    return FAIL;
+
+			lbuf = ml_get_buf(curwin->w_buffer, VIsual.lnum, FALSE);
+			lbuf = vim_strnsave(lbuf + spos->col,
+				     epos->col - spos->col + (*p_sel != 'e'));
+			lnum = spos->lnum;
+			col = spos->col;
+		    }
+		    else
+		    {
+			/* Find the word under the cursor. */
+			++emsg_off;
+			len = find_ident_at_pos(wp, lnum, (colnr_T)col, &lbuf,
+					FIND_IDENT + FIND_STRING + FIND_EVAL);
+			--emsg_off;
+			if (len == 0)
+			    return FAIL;
+			lbuf = vim_strnsave(lbuf, len);
+		    }
+		}
+
+		*winp = wp;
+		*lnump = lnum;
+		*textp = lbuf;
+		*colp = col;
+		beval->ts = wp->w_buffer->b_p_ts;
+		return OK;
+	    }
+	}
+    }
+
+    return FAIL;
+}
+
+# if !defined(FEAT_GUI_W32) || defined(PROTO)
+
+/*
+ * Show a balloon with "mesg".
+ */
+    void
+gui_mch_post_balloon(beval, mesg)
+    BalloonEval	*beval;
+    char_u	*mesg;
+{
+    beval->msg = mesg;
+    if (mesg != NULL)
+	drawBalloon(beval);
+    else
+	undrawBalloon(beval);
+}
+# endif /* FEAT_GUI_W32 */
+#endif /* FEAT_SUN_WORKSHOP || FEAT_NETBEANS_INTG || PROTO */
+
+#if !defined(FEAT_GUI_W32) || defined(PROTO)
+#if defined(FEAT_BEVAL_TIP) || defined(PROTO)
+/*
+ * Hide the given balloon.
+ */
+    void
+gui_mch_unpost_balloon(beval)
+    BalloonEval	*beval;
+{
+    undrawBalloon(beval);
+}
+#endif
+
+#ifdef FEAT_GUI_GTK
+/*
+ * We can unconditionally use ANSI-style prototypes here since
+ * GTK+ requires an ANSI C compiler anyway.
+ */
+    static void
+addEventHandler(GtkWidget *target, BalloonEval *beval)
+{
+    /*
+     * Connect to the generic "event" signal instead of the individual
+     * signals for each event type, because the former is emitted earlier.
+     * This allows us to catch events independently of the signal handlers
+     * in gui_gtk_x11.c.
+     */
+    /* Should use GTK_OBJECT() here, but that causes a lint warning... */
+    gtk_signal_connect((GtkObject*)(target), "event",
+		       GTK_SIGNAL_FUNC(target_event_cb),
+		       beval);
+    /*
+     * Nasty:  Key press events go to the main window thus the drawing area
+     * will never see them.  This means we have to connect to the main window
+     * as well in order to catch those events.
+     */
+    if (gtk_socket_id == 0 && gui.mainwin != NULL
+	    && gtk_widget_is_ancestor(target, gui.mainwin))
+    {
+	gtk_signal_connect((GtkObject*)(gui.mainwin), "event",
+			   GTK_SIGNAL_FUNC(mainwin_event_cb),
+			   beval);
+    }
+}
+
+    static void
+removeEventHandler(BalloonEval *beval)
+{
+    /* LINTED: avoid warning: dubious operation on enum */
+    gtk_signal_disconnect_by_func((GtkObject*)(beval->target),
+				  GTK_SIGNAL_FUNC(target_event_cb),
+				  beval);
+
+    if (gtk_socket_id == 0 && gui.mainwin != NULL
+	    && gtk_widget_is_ancestor(beval->target, gui.mainwin))
+    {
+	/* LINTED: avoid warning: dubious operation on enum */
+	gtk_signal_disconnect_by_func((GtkObject*)(gui.mainwin),
+				      GTK_SIGNAL_FUNC(mainwin_event_cb),
+				      beval);
+    }
+}
+
+    static gint
+target_event_cb(GtkWidget *widget, GdkEvent *event, gpointer data)
+{
+    BalloonEval *beval = (BalloonEval *)data;
+
+    switch (event->type)
+    {
+	case GDK_ENTER_NOTIFY:
+	    pointer_event(beval, (int)event->crossing.x,
+				 (int)event->crossing.y,
+				 event->crossing.state);
+	    break;
+	case GDK_MOTION_NOTIFY:
+	    if (event->motion.is_hint)
+	    {
+		int		x;
+		int		y;
+		GdkModifierType	state;
+		/*
+		 * GDK_POINTER_MOTION_HINT_MASK is set, thus we cannot obtain
+		 * the coordinates from the GdkEventMotion struct directly.
+		 */
+		gdk_window_get_pointer(widget->window, &x, &y, &state);
+		pointer_event(beval, x, y, (unsigned int)state);
+	    }
+	    else
+	    {
+		pointer_event(beval, (int)event->motion.x,
+				     (int)event->motion.y,
+				     event->motion.state);
+	    }
+	    break;
+	case GDK_LEAVE_NOTIFY:
+	    /*
+	     * Ignore LeaveNotify events that are not "normal".
+	     * Apparently we also get it when somebody else grabs focus.
+	     */
+	    if (event->crossing.mode == GDK_CROSSING_NORMAL)
+		cancelBalloon(beval);
+	    break;
+	case GDK_BUTTON_PRESS:
+# ifdef HAVE_GTK2
+	case GDK_SCROLL:
+# endif
+	    cancelBalloon(beval);
+	    break;
+	case GDK_KEY_PRESS:
+	    key_event(beval, event->key.keyval, TRUE);
+	    break;
+	case GDK_KEY_RELEASE:
+	    key_event(beval, event->key.keyval, FALSE);
+	    break;
+	default:
+	    break;
+    }
+
+    return FALSE; /* continue emission */
+}
+
+/*ARGSUSED*/
+    static gint
+mainwin_event_cb(GtkWidget *widget, GdkEvent *event, gpointer data)
+{
+    BalloonEval *beval = (BalloonEval *)data;
+
+    switch (event->type)
+    {
+	case GDK_KEY_PRESS:
+	    key_event(beval, event->key.keyval, TRUE);
+	    break;
+	case GDK_KEY_RELEASE:
+	    key_event(beval, event->key.keyval, FALSE);
+	    break;
+	default:
+	    break;
+    }
+
+    return FALSE; /* continue emission */
+}
+
+    static void
+pointer_event(BalloonEval *beval, int x, int y, unsigned state)
+{
+    int distance;
+
+    distance = ABS(x - beval->x) + ABS(y - beval->y);
+
+    if (distance > 4)
+    {
+	/*
+	 * Moved out of the balloon location: cancel it.
+	 * Remember button state
+	 */
+	beval->state = state;
+	cancelBalloon(beval);
+
+	/* Mouse buttons are pressed - no balloon now */
+	if (!(state & ((int)GDK_BUTTON1_MASK | (int)GDK_BUTTON2_MASK
+						    | (int)GDK_BUTTON3_MASK)))
+	{
+	    beval->x = x;
+	    beval->y = y;
+
+	    if (state & (int)GDK_MOD1_MASK)
+	    {
+		/*
+		 * Alt is pressed -- enter super-evaluate-mode,
+		 * where there is no time delay
+		 */
+		if (beval->msgCB != NULL)
+		{
+		    beval->showState = ShS_PENDING;
+		    (*beval->msgCB)(beval, state);
+		}
+	    }
+	    else
+	    {
+		beval->timerID = gtk_timeout_add((guint32)p_bdlay,
+						 &timeout_cb, beval);
+	    }
+	}
+    }
+}
+
+    static void
+key_event(BalloonEval *beval, unsigned keyval, int is_keypress)
+{
+    if (beval->showState == ShS_SHOWING && beval->msgCB != NULL)
+    {
+	switch (keyval)
+	{
+	    case GDK_Shift_L:
+	    case GDK_Shift_R:
+		beval->showState = ShS_UPDATE_PENDING;
+		(*beval->msgCB)(beval, (is_keypress)
+						   ? (int)GDK_SHIFT_MASK : 0);
+		break;
+	    case GDK_Control_L:
+	    case GDK_Control_R:
+		beval->showState = ShS_UPDATE_PENDING;
+		(*beval->msgCB)(beval, (is_keypress)
+						 ? (int)GDK_CONTROL_MASK : 0);
+		break;
+	    default:
+		/* Don't do this for key release, we apparently get these with
+		 * focus changes in some GTK version. */
+		if (is_keypress)
+		    cancelBalloon(beval);
+		break;
+	}
+    }
+    else
+	cancelBalloon(beval);
+}
+
+    static gint
+timeout_cb(gpointer data)
+{
+    BalloonEval *beval = (BalloonEval *)data;
+
+    beval->timerID = 0;
+    /*
+     * If the timer event happens then the mouse has stopped long enough for
+     * a request to be started. The request will only send to the debugger if
+     * there the mouse is pointing at real data.
+     */
+    requestBalloon(beval);
+
+    return FALSE; /* don't call me again */
+}
+
+/*ARGSUSED2*/
+    static gint
+balloon_expose_event_cb(GtkWidget *widget, GdkEventExpose *event, gpointer data)
+{
+    gtk_paint_flat_box(widget->style, widget->window,
+		       GTK_STATE_NORMAL, GTK_SHADOW_OUT,
+		       &event->area, widget, "tooltip",
+		       0, 0, -1, -1);
+
+    return FALSE; /* continue emission */
+}
+
+# ifndef HAVE_GTK2
+/*ARGSUSED2*/
+    static void
+balloon_draw_cb(GtkWidget *widget, GdkRectangle *area, gpointer data)
+{
+    GtkWidget	    *child;
+    GdkRectangle    child_area;
+
+    gtk_paint_flat_box(widget->style, widget->window,
+		       GTK_STATE_NORMAL, GTK_SHADOW_OUT,
+		       area, widget, "tooltip",
+		       0, 0, -1, -1);
+
+    child = GTK_BIN(widget)->child;
+
+    if (gtk_widget_intersect(child, area, &child_area))
+	gtk_widget_draw(child, &child_area);
+}
+# endif
+
+#else /* !FEAT_GUI_GTK */
+
+    static void
+addEventHandler(target, beval)
+    Widget	target;
+    BalloonEval	*beval;
+{
+    XtAddEventHandler(target,
+			PointerMotionMask | EnterWindowMask |
+			LeaveWindowMask | ButtonPressMask | KeyPressMask |
+			KeyReleaseMask,
+			False,
+			pointerEventEH, (XtPointer)beval);
+}
+
+    static void
+removeEventHandler(beval)
+    BalloonEval	*beval;
+{
+    XtRemoveEventHandler(beval->target,
+			PointerMotionMask | EnterWindowMask |
+			LeaveWindowMask | ButtonPressMask | KeyPressMask |
+			KeyReleaseMask,
+			False,
+			pointerEventEH, (XtPointer)beval);
+}
+
+
+/*
+ * The X event handler. All it does is call the real event handler.
+ */
+/*ARGSUSED*/
+    static void
+pointerEventEH(w, client_data, event, unused)
+    Widget	w;
+    XtPointer	client_data;
+    XEvent	*event;
+    Boolean	*unused;
+{
+    BalloonEval *beval = (BalloonEval *)client_data;
+    pointerEvent(beval, event);
+}
+
+
+/*
+ * The real event handler. Called by pointerEventEH() whenever an event we are
+ * interested in occurs.
+ */
+
+    static void
+pointerEvent(beval, event)
+    BalloonEval	*beval;
+    XEvent	*event;
+{
+    Position	distance;	    /* a measure of how much the ponter moved */
+    Position	delta;		    /* used to compute distance */
+
+    switch (event->type)
+    {
+	case EnterNotify:
+	case MotionNotify:
+	    delta = event->xmotion.x - beval->x;
+	    if (delta < 0)
+		delta = -delta;
+	    distance = delta;
+	    delta = event->xmotion.y - beval->y;
+	    if (delta < 0)
+		delta = -delta;
+	    distance += delta;
+	    if (distance > 4)
+	    {
+		/*
+		 * Moved out of the balloon location: cancel it.
+		 * Remember button state
+		 */
+		beval->state = event->xmotion.state;
+		if (beval->state & (Button1Mask|Button2Mask|Button3Mask))
+		{
+		    /* Mouse buttons are pressed - no balloon now */
+		    cancelBalloon(beval);
+		}
+		else if (beval->state & (Mod1Mask|Mod2Mask|Mod3Mask))
+		{
+		    /*
+		     * Alt is pressed -- enter super-evaluate-mode,
+		     * where there is no time delay
+		     */
+		    beval->x = event->xmotion.x;
+		    beval->y = event->xmotion.y;
+		    beval->x_root = event->xmotion.x_root;
+		    beval->y_root = event->xmotion.y_root;
+		    cancelBalloon(beval);
+		    if (beval->msgCB != NULL)
+		    {
+			beval->showState = ShS_PENDING;
+			(*beval->msgCB)(beval, beval->state);
+		    }
+		}
+		else
+		{
+		    beval->x = event->xmotion.x;
+		    beval->y = event->xmotion.y;
+		    beval->x_root = event->xmotion.x_root;
+		    beval->y_root = event->xmotion.y_root;
+		    cancelBalloon(beval);
+		    beval->timerID = XtAppAddTimeOut( beval->appContext,
+					(long_u)p_bdlay, timerRoutine, beval);
+		}
+	    }
+	    break;
+
+	/*
+	 * Motif and Athena version: Keystrokes will be caught by the
+	 * "textArea" widget, and handled in gui_x11_key_hit_cb().
+	 */
+	case KeyPress:
+	    if (beval->showState == ShS_SHOWING && beval->msgCB != NULL)
+	    {
+		Modifiers   modifier;
+		KeySym	    keysym;
+
+		XtTranslateKeycode(gui.dpy,
+				       event->xkey.keycode, event->xkey.state,
+				       &modifier, &keysym);
+		if (keysym == XK_Shift_L || keysym == XK_Shift_R)
+		{
+		    beval->showState = ShS_UPDATE_PENDING;
+		    (*beval->msgCB)(beval, ShiftMask);
+		}
+		else if (keysym == XK_Control_L || keysym == XK_Control_R)
+		{
+		    beval->showState = ShS_UPDATE_PENDING;
+		    (*beval->msgCB)(beval, ControlMask);
+		}
+		else
+		    cancelBalloon(beval);
+	    }
+	    else
+		cancelBalloon(beval);
+	    break;
+
+	case KeyRelease:
+	    if (beval->showState == ShS_SHOWING && beval->msgCB != NULL)
+	    {
+		Modifiers modifier;
+		KeySym keysym;
+
+		XtTranslateKeycode(gui.dpy, event->xkey.keycode,
+				event->xkey.state, &modifier, &keysym);
+		if ((keysym == XK_Shift_L) || (keysym == XK_Shift_R)) {
+		    beval->showState = ShS_UPDATE_PENDING;
+		    (*beval->msgCB)(beval, 0);
+		}
+		else if ((keysym == XK_Control_L) || (keysym == XK_Control_R))
+		{
+		    beval->showState = ShS_UPDATE_PENDING;
+		    (*beval->msgCB)(beval, 0);
+		}
+		else
+		    cancelBalloon(beval);
+	    }
+	    else
+		cancelBalloon(beval);
+	    break;
+
+	case LeaveNotify:
+		/* Ignore LeaveNotify events that are not "normal".
+		 * Apparently we also get it when somebody else grabs focus.
+		 * Happens for me every two seconds (some clipboard tool?) */
+		if (event->xcrossing.mode == NotifyNormal)
+		    cancelBalloon(beval);
+		break;
+
+	case ButtonPress:
+		cancelBalloon(beval);
+		break;
+
+	default:
+	    break;
+    }
+}
+
+/*ARGSUSED*/
+    static void
+timerRoutine(dx, id)
+    XtPointer	    dx;
+    XtIntervalId    *id;
+{
+    BalloonEval *beval = (BalloonEval *)dx;
+
+    beval->timerID = (XtIntervalId)NULL;
+
+    /*
+     * If the timer event happens then the mouse has stopped long enough for
+     * a request to be started. The request will only send to the debugger if
+     * there the mouse is pointing at real data.
+     */
+    requestBalloon(beval);
+}
+
+#endif /* !FEAT_GUI_GTK */
+
+    static void
+requestBalloon(beval)
+    BalloonEval	*beval;
+{
+    if (beval->showState != ShS_PENDING)
+    {
+	/* Determine the beval to display */
+	if (beval->msgCB != NULL)
+	{
+	    beval->showState = ShS_PENDING;
+	    (*beval->msgCB)(beval, beval->state);
+	}
+	else if (beval->msg != NULL)
+	    drawBalloon(beval);
+    }
+}
+
+#ifdef FEAT_GUI_GTK
+
+# ifdef HAVE_GTK2
+/*
+ * Convert the string to UTF-8 if 'encoding' is not "utf-8".
+ * Replace any non-printable characters and invalid bytes sequences with
+ * "^X" or "<xx>" escapes, and apply SpecialKey highlighting to them.
+ * TAB and NL are passed through unscathed.
+ */
+#  define IS_NONPRINTABLE(c) (((c) < 0x20 && (c) != TAB && (c) != NL) \
+			      || (c) == DEL)
+    static void
+set_printable_label_text(GtkLabel *label, char_u *text)
+{
+    char_u	    *convbuf = NULL;
+    char_u	    *buf;
+    char_u	    *p;
+    char_u	    *pdest;
+    unsigned int    len;
+    int		    charlen;
+    int		    uc;
+    PangoAttrList   *attr_list;
+
+    /* Convert to UTF-8 if it isn't already */
+    if (output_conv.vc_type != CONV_NONE)
+    {
+	convbuf = string_convert(&output_conv, text, NULL);
+	if (convbuf != NULL)
+	    text = convbuf;
+    }
+
+    /* First let's see how much we need to allocate */
+    len = 0;
+    for (p = text; *p != NUL; p += charlen)
+    {
+	if ((*p & 0x80) == 0)	/* be quick for ASCII */
+	{
+	    charlen = 1;
+	    len += IS_NONPRINTABLE(*p) ? 2 : 1;	/* nonprintable: ^X */
+	}
+	else
+	{
+	    charlen = utf_ptr2len(p);
+	    uc = utf_ptr2char(p);
+
+	    if (charlen != utf_char2len(uc))
+		charlen = 1; /* reject overlong sequences */
+
+	    if (charlen == 1 || uc < 0xa0)	/* illegal byte or    */
+		len += 4;			/* control char: <xx> */
+	    else if (!utf_printable(uc))
+		/* Note: we assume here that utf_printable() doesn't
+		 * care about characters outside the BMP. */
+		len += 6;			/* nonprintable: <xxxx> */
+	    else
+		len += charlen;
+	}
+    }
+
+    attr_list = pango_attr_list_new();
+    buf = alloc(len + 1);
+
+    /* Now go for the real work */
+    if (buf != NULL)
+    {
+	attrentry_T	*aep;
+	PangoAttribute	*attr;
+	guicolor_T	pixel;
+	GdkColor	color = { 0, 0, 0, 0 };
+
+	/* Look up the RGB values of the SpecialKey foreground color. */
+	aep = syn_gui_attr2entry(hl_attr(HLF_8));
+	pixel = (aep != NULL) ? aep->ae_u.gui.fg_color : INVALCOLOR;
+	if (pixel != INVALCOLOR)
+	    gdk_colormap_query_color(gtk_widget_get_colormap(gui.drawarea),
+				     (unsigned long)pixel, &color);
+
+	pdest = buf;
+	p = text;
+	while (*p != NUL)
+	{
+	    /* Be quick for ASCII */
+	    if ((*p & 0x80) == 0 && !IS_NONPRINTABLE(*p))
+	    {
+		*pdest++ = *p++;
+	    }
+	    else
+	    {
+		charlen = utf_ptr2len(p);
+		uc = utf_ptr2char(p);
+
+		if (charlen != utf_char2len(uc))
+		    charlen = 1; /* reject overlong sequences */
+
+		if (charlen == 1 || uc < 0xa0 || !utf_printable(uc))
+		{
+		    int	outlen;
+
+		    /* Careful: we can't just use transchar_byte() here,
+		     * since 'encoding' is not necessarily set to "utf-8". */
+		    if (*p & 0x80 && charlen == 1)
+		    {
+			transchar_hex(pdest, *p);	/* <xx> */
+			outlen = 4;
+		    }
+		    else if (uc >= 0x80)
+		    {
+			/* Note: we assume here that utf_printable() doesn't
+			 * care about characters outside the BMP. */
+			transchar_hex(pdest, uc);	/* <xx> or <xxxx> */
+			outlen = (uc < 0x100) ? 4 : 6;
+		    }
+		    else
+		    {
+			transchar_nonprint(pdest, *p);	/* ^X */
+			outlen = 2;
+		    }
+		    if (pixel != INVALCOLOR)
+		    {
+			attr = pango_attr_foreground_new(
+				color.red, color.green, color.blue);
+			attr->start_index = pdest - buf;
+			attr->end_index   = pdest - buf + outlen;
+			pango_attr_list_insert(attr_list, attr);
+		    }
+		    pdest += outlen;
+		    p += charlen;
+		}
+		else
+		{
+		    do
+			*pdest++ = *p++;
+		    while (--charlen != 0);
+		}
+	    }
+	}
+	*pdest = NUL;
+    }
+
+    vim_free(convbuf);
+
+    gtk_label_set_text(label, (const char *)buf);
+    vim_free(buf);
+
+    gtk_label_set_attributes(label, attr_list);
+    pango_attr_list_unref(attr_list);
+}
+#  undef IS_NONPRINTABLE
+# endif /* HAVE_GTK2 */
+
+/*
+ * Draw a balloon.
+ */
+    static void
+drawBalloon(BalloonEval *beval)
+{
+    if (beval->msg != NULL)
+    {
+	GtkRequisition	requisition;
+	int		screen_w;
+	int		screen_h;
+	int		x;
+	int		y;
+	int		x_offset = EVAL_OFFSET_X;
+	int		y_offset = EVAL_OFFSET_Y;
+# ifdef HAVE_GTK2
+	PangoLayout	*layout;
+# endif
+# ifdef HAVE_GTK_MULTIHEAD
+	GdkScreen	*screen;
+
+	screen = gtk_widget_get_screen(beval->target);
+	gtk_window_set_screen(GTK_WINDOW(beval->balloonShell), screen);
+	screen_w = gdk_screen_get_width(screen);
+	screen_h = gdk_screen_get_height(screen);
+# else
+	screen_w = gdk_screen_width();
+	screen_h = gdk_screen_height();
+# endif
+	gtk_widget_ensure_style(beval->balloonShell);
+	gtk_widget_ensure_style(beval->balloonLabel);
+
+# ifdef HAVE_GTK2
+	set_printable_label_text(GTK_LABEL(beval->balloonLabel), beval->msg);
+	/*
+	 * Dirty trick:  Enable wrapping mode on the label's layout behind its
+	 * back.  This way GtkLabel won't try to constrain the wrap width to a
+	 * builtin maximum value of about 65 Latin characters.
+	 */
+	layout = gtk_label_get_layout(GTK_LABEL(beval->balloonLabel));
+#  ifdef PANGO_WRAP_WORD_CHAR
+	pango_layout_set_wrap(layout, PANGO_WRAP_WORD_CHAR);
+#  else
+	pango_layout_set_wrap(layout, PANGO_WRAP_WORD);
+#  endif
+	pango_layout_set_width(layout,
+		/* try to come up with some reasonable width */
+		PANGO_SCALE * CLAMP(gui.num_cols * gui.char_width,
+				    screen_w / 2,
+				    MAX(20, screen_w - 20)));
+
+	/* Calculate the balloon's width and height. */
+	gtk_widget_size_request(beval->balloonShell, &requisition);
+# else
+	gtk_label_set_line_wrap(GTK_LABEL(beval->balloonLabel), FALSE);
+	gtk_label_set_text(GTK_LABEL(beval->balloonLabel),
+			   (const char *)beval->msg);
+
+	/* Calculate the balloon's width and height. */
+	gtk_widget_size_request(beval->balloonShell, &requisition);
+	/*
+	 * Unfortunately, the dirty trick used above to get around the builtin
+	 * maximum wrap width of GtkLabel doesn't work with GTK+ 1.  Thus if
+	 * and only if it's absolutely necessary to avoid drawing off-screen,
+	 * do enable wrapping now and recalculate the size request.
+	 */
+	if (requisition.width > screen_w)
+	{
+	    gtk_label_set_line_wrap(GTK_LABEL(beval->balloonLabel), TRUE);
+	    gtk_widget_size_request(beval->balloonShell, &requisition);
+	}
+# endif
+
+	/* Compute position of the balloon area */
+	gdk_window_get_origin(beval->target->window, &x, &y);
+	x += beval->x;
+	y += beval->y;
+
+	/* Get out of the way of the mouse pointer */
+	if (x + x_offset + requisition.width > screen_w)
+	    y_offset += 15;
+	if (y + y_offset + requisition.height > screen_h)
+	    y_offset = -requisition.height - EVAL_OFFSET_Y;
+
+	/* Sanitize values */
+	x = CLAMP(x + x_offset, 0, MAX(0, screen_w - requisition.width));
+	y = CLAMP(y + y_offset, 0, MAX(0, screen_h - requisition.height));
+
+	/* Show the balloon */
+	gtk_widget_set_uposition(beval->balloonShell, x, y);
+	gtk_widget_show(beval->balloonShell);
+
+	beval->showState = ShS_SHOWING;
+    }
+}
+
+/*
+ * Undraw a balloon.
+ */
+    static void
+undrawBalloon(BalloonEval *beval)
+{
+    if (beval->balloonShell != NULL)
+	gtk_widget_hide(beval->balloonShell);
+    beval->showState = ShS_NEUTRAL;
+}
+
+    static void
+cancelBalloon(BalloonEval *beval)
+{
+    if (beval->showState == ShS_SHOWING
+	    || beval->showState == ShS_UPDATE_PENDING)
+	undrawBalloon(beval);
+
+    if (beval->timerID != 0)
+    {
+	gtk_timeout_remove(beval->timerID);
+	beval->timerID = 0;
+    }
+    beval->showState = ShS_NEUTRAL;
+}
+
+    static void
+createBalloonEvalWindow(BalloonEval *beval)
+{
+    beval->balloonShell = gtk_window_new(GTK_WINDOW_POPUP);
+
+    gtk_widget_set_app_paintable(beval->balloonShell, TRUE);
+    gtk_window_set_policy(GTK_WINDOW(beval->balloonShell), FALSE, FALSE, TRUE);
+    gtk_widget_set_name(beval->balloonShell, "gtk-tooltips");
+    gtk_container_border_width(GTK_CONTAINER(beval->balloonShell), 4);
+
+    gtk_signal_connect((GtkObject*)(beval->balloonShell), "expose_event",
+		       GTK_SIGNAL_FUNC(balloon_expose_event_cb), NULL);
+# ifndef HAVE_GTK2
+    gtk_signal_connect((GtkObject*)(beval->balloonShell), "draw",
+		       GTK_SIGNAL_FUNC(balloon_draw_cb), NULL);
+# endif
+    beval->balloonLabel = gtk_label_new(NULL);
+
+    gtk_label_set_line_wrap(GTK_LABEL(beval->balloonLabel), FALSE);
+    gtk_label_set_justify(GTK_LABEL(beval->balloonLabel), GTK_JUSTIFY_LEFT);
+    gtk_misc_set_alignment(GTK_MISC(beval->balloonLabel), 0.5f, 0.5f);
+    gtk_widget_set_name(beval->balloonLabel, "vim-balloon-label");
+    gtk_widget_show(beval->balloonLabel);
+
+    gtk_container_add(GTK_CONTAINER(beval->balloonShell), beval->balloonLabel);
+}
+
+#else /* !FEAT_GUI_GTK */
+
+/*
+ * Draw a balloon.
+ */
+    static void
+drawBalloon(beval)
+    BalloonEval	*beval;
+{
+    Dimension	w;
+    Dimension	h;
+    Position tx;
+    Position ty;
+
+    if (beval->msg != NULL)
+    {
+	/* Show the Balloon */
+
+	/* Calculate the label's width and height */
+#ifdef FEAT_GUI_MOTIF
+	XmString s;
+
+	/* For the callback function we parse NL characters to create a
+	 * multi-line label.  This doesn't work for all languages, but
+	 * XmStringCreateLocalized() doesn't do multi-line labels... */
+	if (beval->msgCB != NULL)
+	    s = XmStringCreateLtoR((char *)beval->msg, XmFONTLIST_DEFAULT_TAG);
+	else
+	    s = XmStringCreateLocalized((char *)beval->msg);
+	{
+	    XmFontList fl;
+
+	    fl = gui_motif_fontset2fontlist(&gui.tooltip_fontset);
+	    if (fl != NULL)
+	    {
+		XmStringExtent(fl, s, &w, &h);
+		XmFontListFree(fl);
+	    }
+	}
+	w += gui.border_offset << 1;
+	h += gui.border_offset << 1;
+	XtVaSetValues(beval->balloonLabel, XmNlabelString, s, NULL);
+	XmStringFree(s);
+#else /* Athena */
+	/* Assume XtNinternational == True */
+	XFontSet	fset;
+	XFontSetExtents *ext;
+
+	XtVaGetValues(beval->balloonLabel, XtNfontSet, &fset, NULL);
+	ext = XExtentsOfFontSet(fset);
+	h = ext->max_ink_extent.height;
+	w = XmbTextEscapement(fset,
+			      (char *)beval->msg,
+			      (int)STRLEN(beval->msg));
+	w += gui.border_offset << 1;
+	h += gui.border_offset << 1;
+	XtVaSetValues(beval->balloonLabel, XtNlabel, beval->msg, NULL);
+#endif
+
+	/* Compute position of the balloon area */
+	tx = beval->x_root + EVAL_OFFSET_X;
+	ty = beval->y_root + EVAL_OFFSET_Y;
+	if ((tx + w) > beval->screen_width)
+	    tx = beval->screen_width - w;
+	if ((ty + h) > beval->screen_height)
+	    ty = beval->screen_height - h;
+#ifdef FEAT_GUI_MOTIF
+	XtVaSetValues(beval->balloonShell,
+		XmNx, tx,
+		XmNy, ty,
+		NULL);
+#else
+	/* Athena */
+	XtVaSetValues(beval->balloonShell,
+		XtNx, tx,
+		XtNy, ty,
+		NULL);
+#endif
+
+	XtPopup(beval->balloonShell, XtGrabNone);
+
+	beval->showState = ShS_SHOWING;
+
+	current_beval = beval;
+    }
+}
+
+/*
+ * Undraw a balloon.
+ */
+    static void
+undrawBalloon(beval)
+    BalloonEval *beval;
+{
+    if (beval->balloonShell != (Widget)0)
+	XtPopdown(beval->balloonShell);
+    beval->showState = ShS_NEUTRAL;
+
+    current_beval = NULL;
+}
+
+    static void
+cancelBalloon(beval)
+    BalloonEval	*beval;
+{
+    if (beval->showState == ShS_SHOWING
+	    || beval->showState == ShS_UPDATE_PENDING)
+	undrawBalloon(beval);
+
+    if (beval->timerID != (XtIntervalId)NULL)
+    {
+	XtRemoveTimeOut(beval->timerID);
+	beval->timerID = (XtIntervalId)NULL;
+    }
+    beval->showState = ShS_NEUTRAL;
+}
+
+
+    static void
+createBalloonEvalWindow(beval)
+    BalloonEval	*beval;
+{
+    Arg		args[12];
+    int		n;
+
+    n = 0;
+#ifdef FEAT_GUI_MOTIF
+    XtSetArg(args[n], XmNallowShellResize, True); n++;
+    beval->balloonShell = XtAppCreateShell("balloonEval", "BalloonEval",
+		    overrideShellWidgetClass, gui.dpy, args, n);
+#else
+    /* Athena */
+    XtSetArg(args[n], XtNallowShellResize, True); n++;
+    beval->balloonShell = XtAppCreateShell("balloonEval", "BalloonEval",
+		    overrideShellWidgetClass, gui.dpy, args, n);
+#endif
+
+    n = 0;
+#ifdef FEAT_GUI_MOTIF
+    {
+	XmFontList fl;
+
+	fl = gui_motif_fontset2fontlist(&gui.tooltip_fontset);
+	XtSetArg(args[n], XmNforeground, gui.tooltip_fg_pixel); n++;
+	XtSetArg(args[n], XmNbackground, gui.tooltip_bg_pixel); n++;
+	XtSetArg(args[n], XmNfontList, fl); n++;
+	XtSetArg(args[n], XmNalignment, XmALIGNMENT_BEGINNING); n++;
+	beval->balloonLabel = XtCreateManagedWidget("balloonLabel",
+			xmLabelWidgetClass, beval->balloonShell, args, n);
+    }
+#else /* FEAT_GUI_ATHENA */
+    XtSetArg(args[n], XtNforeground, gui.tooltip_fg_pixel); n++;
+    XtSetArg(args[n], XtNbackground, gui.tooltip_bg_pixel); n++;
+    XtSetArg(args[n], XtNinternational, True); n++;
+    XtSetArg(args[n], XtNfontSet, gui.tooltip_fontset); n++;
+    beval->balloonLabel = XtCreateManagedWidget("balloonLabel",
+		    labelWidgetClass, beval->balloonShell, args, n);
+#endif
+}
+
+#endif /* !FEAT_GUI_GTK */
+#endif /* !FEAT_GUI_W32 */
+
+#endif /* FEAT_BEVAL */
--- /dev/null
+++ b/gui_beval.h
@@ -1,0 +1,76 @@
+/* vi:set ts=8 sts=4 sw=4:
+ *
+ * VIM - Vi IMproved	by Bram Moolenaar
+ *			Visual Workshop integration by Gordon Prieur
+ *
+ * Do ":help uganda"  in Vim to read copying and usage conditions.
+ * Do ":help credits" in Vim to see a list of people who contributed.
+ */
+
+#if !defined(GUI_BEVAL_H) && (defined(FEAT_BEVAL) || defined(PROTO))
+#define GUI_BEVAL_H
+
+#ifdef FEAT_GUI_GTK
+# include <gtk/gtkwidget.h>
+#else
+# if defined(FEAT_GUI_X11)
+#  include <X11/Intrinsic.h>
+# endif
+#endif
+
+typedef enum
+{
+    ShS_NEUTRAL,			/* nothing showing or pending */
+    ShS_PENDING,			/* data requested from debugger */
+    ShS_UPDATE_PENDING,			/* switching information displayed */
+    ShS_SHOWING				/* the balloon is being displayed */
+} BeState;
+
+typedef struct BalloonEvalStruct
+{
+#ifdef FEAT_GUI_GTK
+    GtkWidget		*target;	/* widget we are monitoring */
+    GtkWidget		*balloonShell;
+    GtkWidget		*balloonLabel;
+    unsigned int	timerID;	/* timer for run */
+    BeState		showState;	/* tells us whats currently going on */
+    int			x;
+    int			y;
+    unsigned int	state;		/* Button/Modifier key state */
+#else
+# if !defined(FEAT_GUI_W32)
+    Widget		target;		/* widget we are monitoring */
+    Widget		balloonShell;
+    Widget		balloonLabel;
+    XtIntervalId	timerID;	/* timer for run */
+    BeState		showState;	/* tells us whats currently going on */
+    XtAppContext	appContext;	/* used in event handler */
+    Position		x;
+    Position		y;
+    Position		x_root;
+    Position		y_root;
+    int			state;		/* Button/Modifier key state */
+# else
+    HWND		target;
+    HWND		balloon;
+    int			x;
+    int			y;
+    BeState		showState;	/* tells us whats currently going on */
+# endif
+#endif
+    int			ts;		/* tabstop setting for this buffer */
+    char_u		*msg;
+    void		(*msgCB)__ARGS((struct BalloonEvalStruct *, int));
+    void		*clientData;	/* For callback */
+#if !defined(FEAT_GUI_GTK) && !defined(FEAT_GUI_W32)
+    Dimension		screen_width;	/* screen width in pixels */
+    Dimension		screen_height;	/* screen height in pixels */
+#endif
+} BalloonEval;
+
+#define EVAL_OFFSET_X 15 /* displacement of beval topleft corner from pointer */
+#define EVAL_OFFSET_Y 10
+
+#include "gui_beval.pro"
+
+#endif /* GUI_BEVAL_H and FEAT_BEVAL */
--- /dev/null
+++ b/hardcopy.c
@@ -1,0 +1,3655 @@
+/* vi:set ts=8 sts=4 sw=4:
+ *
+ * VIM - Vi IMproved	by Bram Moolenaar
+ *
+ * Do ":help uganda"  in Vim to read copying and usage conditions.
+ * Do ":help credits" in Vim to see a list of people who contributed.
+ * See README.txt for an overview of the Vim source code.
+ */
+
+/*
+ * hardcopy.c: printing to paper
+ */
+
+#include "vim.h"
+#include "version.h"
+
+#if defined(FEAT_PRINTER) || defined(PROTO)
+/*
+ * To implement printing on a platform, the following functions must be
+ * defined:
+ *
+ * int mch_print_init(prt_settings_T *psettings, char_u *jobname, int forceit)
+ * Called once.  Code should display printer dialogue (if appropriate) and
+ * determine printer font and margin settings.  Reset has_color if the printer
+ * doesn't support colors at all.
+ * Returns FAIL to abort.
+ *
+ * int mch_print_begin(prt_settings_T *settings)
+ * Called to start the print job.
+ * Return FALSE to abort.
+ *
+ * int mch_print_begin_page(char_u *msg)
+ * Called at the start of each page.
+ * "msg" indicates the progress of the print job, can be NULL.
+ * Return FALSE to abort.
+ *
+ * int mch_print_end_page()
+ * Called at the end of each page.
+ * Return FALSE to abort.
+ *
+ * int mch_print_blank_page()
+ * Called to generate a blank page for collated, duplex, multiple copy
+ * document.  Return FALSE to abort.
+ *
+ * void mch_print_end(prt_settings_T *psettings)
+ * Called at normal end of print job.
+ *
+ * void mch_print_cleanup()
+ * Called if print job ends normally or is abandoned. Free any memory, close
+ * devices and handles.  Also called when mch_print_begin() fails, but not
+ * when mch_print_init() fails.
+ *
+ * void mch_print_set_font(int Bold, int Italic, int Underline);
+ * Called whenever the font style changes.
+ *
+ * void mch_print_set_bg(long_u bgcol);
+ * Called to set the background color for the following text. Parameter is an
+ * RGB value.
+ *
+ * void mch_print_set_fg(long_u fgcol);
+ * Called to set the foreground color for the following text. Parameter is an
+ * RGB value.
+ *
+ * mch_print_start_line(int margin, int page_line)
+ * Sets the current position at the start of line "page_line".
+ * If margin is TRUE start in the left margin (for header and line number).
+ *
+ * int mch_print_text_out(char_u *p, int len);
+ * Output one character of text p[len] at the current position.
+ * Return TRUE if there is no room for another character in the same line.
+ *
+ * Note that the generic code has no idea of margins. The machine code should
+ * simply make the page look smaller!  The header and the line numbers are
+ * printed in the margin.
+ */
+
+#ifdef FEAT_SYN_HL
+static const long_u  cterm_color_8[8] =
+{
+    (long_u)0x000000L, (long_u)0xff0000L, (long_u)0x00ff00L, (long_u)0xffff00L,
+    (long_u)0x0000ffL, (long_u)0xff00ffL, (long_u)0x00ffffL, (long_u)0xffffffL
+};
+
+static const long_u  cterm_color_16[16] =
+{
+    (long_u)0x000000L, (long_u)0x0000c0L, (long_u)0x008000L, (long_u)0x004080L,
+    (long_u)0xc00000L, (long_u)0xc000c0L, (long_u)0x808000L, (long_u)0xc0c0c0L,
+    (long_u)0x808080L, (long_u)0x6060ffL, (long_u)0x00ff00L, (long_u)0x00ffffL,
+    (long_u)0xff8080L, (long_u)0xff40ffL, (long_u)0xffff00L, (long_u)0xffffffL
+};
+
+static int		current_syn_id;
+#endif
+
+#define PRCOLOR_BLACK	(long_u)0
+#define PRCOLOR_WHITE	(long_u)0xFFFFFFL
+
+static int	curr_italic;
+static int	curr_bold;
+static int	curr_underline;
+static long_u	curr_bg;
+static long_u	curr_fg;
+static int	page_count;
+
+#if defined(FEAT_MBYTE) && defined(FEAT_POSTSCRIPT)
+# define OPT_MBFONT_USECOURIER  0
+# define OPT_MBFONT_ASCII       1
+# define OPT_MBFONT_REGULAR     2
+# define OPT_MBFONT_BOLD	3
+# define OPT_MBFONT_OBLIQUE     4
+# define OPT_MBFONT_BOLDOBLIQUE 5
+# define OPT_MBFONT_NUM_OPTIONS 6
+
+static option_table_T mbfont_opts[OPT_MBFONT_NUM_OPTIONS] =
+{
+    {"c",	FALSE, 0, NULL, 0, FALSE},
+    {"a",	FALSE, 0, NULL, 0, FALSE},
+    {"r",	FALSE, 0, NULL, 0, FALSE},
+    {"b",	FALSE, 0, NULL, 0, FALSE},
+    {"i",	FALSE, 0, NULL, 0, FALSE},
+    {"o",	FALSE, 0, NULL, 0, FALSE},
+};
+#endif
+
+/*
+ * These values determine the print position on a page.
+ */
+typedef struct
+{
+    int		lead_spaces;	    /* remaining spaces for a TAB */
+    int		print_pos;	    /* virtual column for computing TABs */
+    colnr_T	column;		    /* byte column */
+    linenr_T	file_line;	    /* line nr in the buffer */
+    long_u	bytes_printed;	    /* bytes printed so far */
+    int		ff;		    /* seen form feed character */
+} prt_pos_T;
+
+static char_u *parse_list_options __ARGS((char_u *option_str, option_table_T *table, int table_size));
+
+#ifdef FEAT_SYN_HL
+static long_u darken_rgb __ARGS((long_u rgb));
+static long_u prt_get_term_color __ARGS((int colorindex));
+#endif
+static void prt_set_fg __ARGS((long_u fg));
+static void prt_set_bg __ARGS((long_u bg));
+static void prt_set_font __ARGS((int bold, int italic, int underline));
+static void prt_line_number __ARGS((prt_settings_T *psettings, int page_line, linenr_T lnum));
+static void prt_header __ARGS((prt_settings_T *psettings, int pagenum, linenr_T lnum));
+static void prt_message __ARGS((char_u *s));
+static colnr_T hardcopy_line __ARGS((prt_settings_T *psettings, int page_line, prt_pos_T *ppos));
+#ifdef FEAT_SYN_HL
+static void prt_get_attr __ARGS((int hl_id, prt_text_attr_T* pattr, int modec));
+#endif
+
+/*
+ * Parse 'printoptions' and set the flags in "printer_opts".
+ * Returns an error message or NULL;
+ */
+    char_u *
+parse_printoptions()
+{
+    return parse_list_options(p_popt, printer_opts, OPT_PRINT_NUM_OPTIONS);
+}
+
+#if (defined(FEAT_MBYTE) && defined(FEAT_POSTSCRIPT)) || defined(PROTO)
+/*
+ * Parse 'printoptions' and set the flags in "printer_opts".
+ * Returns an error message or NULL;
+ */
+    char_u *
+parse_printmbfont()
+{
+    return parse_list_options(p_pmfn, mbfont_opts, OPT_MBFONT_NUM_OPTIONS);
+}
+#endif
+
+/*
+ * Parse a list of options in the form
+ * option:value,option:value,option:value
+ *
+ * "value" can start with a number which is parsed out, e.g.  margin:12mm
+ *
+ * Returns an error message for an illegal option, NULL otherwise.
+ * Only used for the printer at the moment...
+ */
+    static char_u *
+parse_list_options(option_str, table, table_size)
+    char_u		*option_str;
+    option_table_T	*table;
+    int			table_size;
+{
+    char_u	*stringp;
+    char_u	*colonp;
+    char_u	*commap;
+    char_u	*p;
+    int		idx = 0;		/* init for GCC */
+    int		len;
+
+    for (idx = 0; idx < table_size; ++idx)
+	table[idx].present = FALSE;
+
+    /*
+     * Repeat for all comma separated parts.
+     */
+    stringp = option_str;
+    while (*stringp)
+    {
+	colonp = vim_strchr(stringp, ':');
+	if (colonp == NULL)
+	    return (char_u *)N_("E550: Missing colon");
+	commap = vim_strchr(stringp, ',');
+	if (commap == NULL)
+	    commap = option_str + STRLEN(option_str);
+
+	len = (int)(colonp - stringp);
+
+	for (idx = 0; idx < table_size; ++idx)
+	    if (STRNICMP(stringp, table[idx].name, len) == 0)
+		break;
+
+	if (idx == table_size)
+	    return (char_u *)N_("E551: Illegal component");
+
+	p = colonp + 1;
+	table[idx].present = TRUE;
+
+	if (table[idx].hasnum)
+	{
+	    if (!VIM_ISDIGIT(*p))
+		return (char_u *)N_("E552: digit expected");
+
+	    table[idx].number = getdigits(&p); /*advances p*/
+	}
+
+	table[idx].string = p;
+	table[idx].strlen = (int)(commap - p);
+
+	stringp = commap;
+	if (*stringp == ',')
+	    ++stringp;
+    }
+
+    return NULL;
+}
+
+
+#ifdef FEAT_SYN_HL
+/*
+ * If using a dark background, the colors will probably be too bright to show
+ * up well on white paper, so reduce their brightness.
+ */
+    static long_u
+darken_rgb(rgb)
+    long_u	rgb;
+{
+    return	((rgb >> 17) << 16)
+	    +	(((rgb & 0xff00) >> 9) << 8)
+	    +	((rgb & 0xff) >> 1);
+}
+
+    static long_u
+prt_get_term_color(colorindex)
+    int	    colorindex;
+{
+    /* TODO: Should check for xterm with 88 or 256 colors. */
+    if (t_colors > 8)
+	return cterm_color_16[colorindex % 16];
+    return cterm_color_8[colorindex % 8];
+}
+
+    static void
+prt_get_attr(hl_id, pattr, modec)
+    int			hl_id;
+    prt_text_attr_T	*pattr;
+    int			modec;
+{
+    int     colorindex;
+    long_u  fg_color;
+    long_u  bg_color;
+    char    *color;
+
+    pattr->bold = (highlight_has_attr(hl_id, HL_BOLD, modec) != NULL);
+    pattr->italic = (highlight_has_attr(hl_id, HL_ITALIC, modec) != NULL);
+    pattr->underline = (highlight_has_attr(hl_id, HL_UNDERLINE, modec) != NULL);
+    pattr->undercurl = (highlight_has_attr(hl_id, HL_UNDERCURL, modec) != NULL);
+
+# ifdef FEAT_GUI
+    if (gui.in_use)
+    {
+	bg_color = highlight_gui_color_rgb(hl_id, FALSE);
+	if (bg_color == PRCOLOR_BLACK)
+	    bg_color = PRCOLOR_WHITE;
+
+	fg_color = highlight_gui_color_rgb(hl_id, TRUE);
+    }
+    else
+# endif
+    {
+	bg_color = PRCOLOR_WHITE;
+
+	color = (char *)highlight_color(hl_id, (char_u *)"fg", modec);
+	if (color == NULL)
+	    colorindex = 0;
+	else
+	    colorindex = atoi(color);
+
+	if (colorindex >= 0 && colorindex < t_colors)
+	    fg_color = prt_get_term_color(colorindex);
+	else
+	    fg_color = PRCOLOR_BLACK;
+    }
+
+    if (fg_color == PRCOLOR_WHITE)
+	fg_color = PRCOLOR_BLACK;
+    else if (*p_bg == 'd')
+	fg_color = darken_rgb(fg_color);
+
+    pattr->fg_color = fg_color;
+    pattr->bg_color = bg_color;
+}
+#endif /* FEAT_SYN_HL */
+
+    static void
+prt_set_fg(fg)
+    long_u fg;
+{
+    if (fg != curr_fg)
+    {
+	curr_fg = fg;
+	mch_print_set_fg(fg);
+    }
+}
+
+    static void
+prt_set_bg(bg)
+    long_u bg;
+{
+    if (bg != curr_bg)
+    {
+	curr_bg = bg;
+	mch_print_set_bg(bg);
+    }
+}
+
+    static void
+prt_set_font(bold, italic, underline)
+    int		bold;
+    int		italic;
+    int		underline;
+{
+    if (curr_bold != bold
+	    || curr_italic != italic
+	    || curr_underline != underline)
+    {
+	curr_underline = underline;
+	curr_italic = italic;
+	curr_bold = bold;
+	mch_print_set_font(bold, italic, underline);
+    }
+}
+
+/*
+ * Print the line number in the left margin.
+ */
+    static void
+prt_line_number(psettings, page_line, lnum)
+    prt_settings_T *psettings;
+    int		page_line;
+    linenr_T	lnum;
+{
+    int		i;
+    char_u	tbuf[20];
+
+    prt_set_fg(psettings->number.fg_color);
+    prt_set_bg(psettings->number.bg_color);
+    prt_set_font(psettings->number.bold, psettings->number.italic, psettings->number.underline);
+    mch_print_start_line(TRUE, page_line);
+
+    /* Leave two spaces between the number and the text; depends on
+     * PRINT_NUMBER_WIDTH. */
+    sprintf((char *)tbuf, "%6ld", (long)lnum);
+    for (i = 0; i < 6; i++)
+	(void)mch_print_text_out(&tbuf[i], 1);
+
+#ifdef FEAT_SYN_HL
+    if (psettings->do_syntax)
+	/* Set colors for next character. */
+	current_syn_id = -1;
+    else
+#endif
+    {
+	/* Set colors and font back to normal. */
+	prt_set_fg(PRCOLOR_BLACK);
+	prt_set_bg(PRCOLOR_WHITE);
+	prt_set_font(FALSE, FALSE, FALSE);
+    }
+}
+
+/*
+ * Get the currently effective header height.
+ */
+    int
+prt_header_height()
+{
+    if (printer_opts[OPT_PRINT_HEADERHEIGHT].present)
+	return printer_opts[OPT_PRINT_HEADERHEIGHT].number;
+    return 2;
+}
+
+/*
+ * Return TRUE if using a line number for printing.
+ */
+    int
+prt_use_number()
+{
+    return (printer_opts[OPT_PRINT_NUMBER].present
+	    && TOLOWER_ASC(printer_opts[OPT_PRINT_NUMBER].string[0]) == 'y');
+}
+
+/*
+ * Return the unit used in a margin item in 'printoptions'.
+ * Returns PRT_UNIT_NONE if not recognized.
+ */
+    int
+prt_get_unit(idx)
+    int		idx;
+{
+    int		u = PRT_UNIT_NONE;
+    int		i;
+    static char *(units[4]) = PRT_UNIT_NAMES;
+
+    if (printer_opts[idx].present)
+	for (i = 0; i < 4; ++i)
+	    if (STRNICMP(printer_opts[idx].string, units[i], 2) == 0)
+	    {
+		u = i;
+		break;
+	    }
+    return u;
+}
+
+/*
+ * Print the page header.
+ */
+/*ARGSUSED*/
+    static void
+prt_header(psettings, pagenum, lnum)
+    prt_settings_T  *psettings;
+    int		pagenum;
+    linenr_T	lnum;
+{
+    int		width = psettings->chars_per_line;
+    int		page_line;
+    char_u	*tbuf;
+    char_u	*p;
+#ifdef FEAT_MBYTE
+    int		l;
+#endif
+
+    /* Also use the space for the line number. */
+    if (prt_use_number())
+	width += PRINT_NUMBER_WIDTH;
+
+    tbuf = alloc(width + IOSIZE);
+    if (tbuf == NULL)
+	return;
+
+#ifdef FEAT_STL_OPT
+    if (*p_header != NUL)
+    {
+	linenr_T	tmp_lnum, tmp_topline, tmp_botline;
+	int		use_sandbox = FALSE;
+
+	/*
+	 * Need to (temporarily) set current line number and first/last line
+	 * number on the 'window'.  Since we don't know how long the page is,
+	 * set the first and current line number to the top line, and guess
+	 * that the page length is 64.
+	 */
+	tmp_lnum = curwin->w_cursor.lnum;
+	tmp_topline = curwin->w_topline;
+	tmp_botline = curwin->w_botline;
+	curwin->w_cursor.lnum = lnum;
+	curwin->w_topline = lnum;
+	curwin->w_botline = lnum + 63;
+	printer_page_num = pagenum;
+
+# ifdef FEAT_EVAL
+	use_sandbox = was_set_insecurely((char_u *)"printheader", 0);
+# endif
+	build_stl_str_hl(curwin, tbuf, (size_t)(width + IOSIZE),
+						  p_header, use_sandbox,
+						  ' ', width, NULL, NULL);
+
+	/* Reset line numbers */
+	curwin->w_cursor.lnum = tmp_lnum;
+	curwin->w_topline = tmp_topline;
+	curwin->w_botline = tmp_botline;
+    }
+    else
+#endif
+	sprintf((char *)tbuf, _("Page %d"), pagenum);
+
+    prt_set_fg(PRCOLOR_BLACK);
+    prt_set_bg(PRCOLOR_WHITE);
+    prt_set_font(TRUE, FALSE, FALSE);
+
+    /* Use a negative line number to indicate printing in the top margin. */
+    page_line = 0 - prt_header_height();
+    mch_print_start_line(TRUE, page_line);
+    for (p = tbuf; *p != NUL; )
+    {
+	if (mch_print_text_out(p,
+#ifdef FEAT_MBYTE
+		(l = (*mb_ptr2len)(p))
+#else
+		1
+#endif
+		    ))
+	{
+	    ++page_line;
+	    if (page_line >= 0) /* out of room in header */
+		break;
+	    mch_print_start_line(TRUE, page_line);
+	}
+#ifdef FEAT_MBYTE
+	p += l;
+#else
+	p++;
+#endif
+    }
+
+    vim_free(tbuf);
+
+#ifdef FEAT_SYN_HL
+    if (psettings->do_syntax)
+	/* Set colors for next character. */
+	current_syn_id = -1;
+    else
+#endif
+    {
+	/* Set colors and font back to normal. */
+	prt_set_fg(PRCOLOR_BLACK);
+	prt_set_bg(PRCOLOR_WHITE);
+	prt_set_font(FALSE, FALSE, FALSE);
+    }
+}
+
+/*
+ * Display a print status message.
+ */
+    static void
+prt_message(s)
+    char_u	*s;
+{
+    screen_fill((int)Rows - 1, (int)Rows, 0, (int)Columns, ' ', ' ', 0);
+    screen_puts(s, (int)Rows - 1, 0, hl_attr(HLF_R));
+    out_flush();
+}
+
+    void
+ex_hardcopy(eap)
+    exarg_T	*eap;
+{
+    linenr_T		lnum;
+    int			collated_copies, uncollated_copies;
+    prt_settings_T	settings;
+    long_u		bytes_to_print = 0;
+    int			page_line;
+    int			jobsplit;
+
+    memset(&settings, 0, sizeof(prt_settings_T));
+    settings.has_color = TRUE;
+
+# ifdef FEAT_POSTSCRIPT
+    if (*eap->arg == '>')
+    {
+	char_u	*errormsg = NULL;
+
+	/* Expand things like "%.ps". */
+	if (expand_filename(eap, eap->cmdlinep, &errormsg) == FAIL)
+	{
+	    if (errormsg != NULL)
+		EMSG(errormsg);
+	    return;
+	}
+	settings.outfile = skipwhite(eap->arg + 1);
+    }
+    else if (*eap->arg != NUL)
+	settings.arguments = eap->arg;
+# endif
+
+    /*
+     * Initialise for printing.  Ask the user for settings, unless forceit is
+     * set.
+     * The mch_print_init() code should set up margins if applicable. (It may
+     * not be a real printer - for example the engine might generate HTML or
+     * PS.)
+     */
+    if (mch_print_init(&settings,
+			curbuf->b_fname == NULL
+			    ? (char_u *)buf_spname(curbuf)
+			    : curbuf->b_sfname == NULL
+				? curbuf->b_fname
+				: curbuf->b_sfname,
+			eap->forceit) == FAIL)
+	return;
+
+#ifdef FEAT_SYN_HL
+# ifdef  FEAT_GUI
+    if (gui.in_use)
+	settings.modec = 'g';
+    else
+# endif
+	if (t_colors > 1)
+	    settings.modec = 'c';
+	else
+	    settings.modec = 't';
+
+    if (!syntax_present(curbuf))
+	settings.do_syntax = FALSE;
+    else if (printer_opts[OPT_PRINT_SYNTAX].present
+	    && TOLOWER_ASC(printer_opts[OPT_PRINT_SYNTAX].string[0]) != 'a')
+	settings.do_syntax =
+	       (TOLOWER_ASC(printer_opts[OPT_PRINT_SYNTAX].string[0]) == 'y');
+    else
+	settings.do_syntax = settings.has_color;
+#endif
+
+    /* Set up printing attributes for line numbers */
+    settings.number.fg_color = PRCOLOR_BLACK;
+    settings.number.bg_color = PRCOLOR_WHITE;
+    settings.number.bold = FALSE;
+    settings.number.italic = TRUE;
+    settings.number.underline = FALSE;
+#ifdef FEAT_SYN_HL
+    /*
+     * Syntax highlighting of line numbers.
+     */
+    if (prt_use_number() && settings.do_syntax)
+    {
+	int		id;
+
+	id = syn_name2id((char_u *)"LineNr");
+	if (id > 0)
+	    id = syn_get_final_id(id);
+
+	prt_get_attr(id, &settings.number, settings.modec);
+    }
+#endif
+
+    /*
+     * Estimate the total lines to be printed
+     */
+    for (lnum = eap->line1; lnum <= eap->line2; lnum++)
+	bytes_to_print += (long_u)STRLEN(skipwhite(ml_get(lnum)));
+    if (bytes_to_print == 0)
+    {
+	MSG(_("No text to be printed"));
+	goto print_fail_no_begin;
+    }
+
+    /* Set colors and font to normal. */
+    curr_bg = (long_u)0xffffffffL;
+    curr_fg = (long_u)0xffffffffL;
+    curr_italic = MAYBE;
+    curr_bold = MAYBE;
+    curr_underline = MAYBE;
+
+    prt_set_fg(PRCOLOR_BLACK);
+    prt_set_bg(PRCOLOR_WHITE);
+    prt_set_font(FALSE, FALSE, FALSE);
+#ifdef FEAT_SYN_HL
+    current_syn_id = -1;
+#endif
+
+    jobsplit = (printer_opts[OPT_PRINT_JOBSPLIT].present
+	   && TOLOWER_ASC(printer_opts[OPT_PRINT_JOBSPLIT].string[0]) == 'y');
+
+    if (!mch_print_begin(&settings))
+	goto print_fail_no_begin;
+
+    /*
+     * Loop over collated copies: 1 2 3, 1 2 3, ...
+     */
+    page_count = 0;
+    for (collated_copies = 0;
+	    collated_copies < settings.n_collated_copies;
+	    collated_copies++)
+    {
+	prt_pos_T	prtpos;		/* current print position */
+	prt_pos_T	page_prtpos;	/* print position at page start */
+	int		side;
+
+	memset(&page_prtpos, 0, sizeof(prt_pos_T));
+	page_prtpos.file_line = eap->line1;
+	prtpos = page_prtpos;
+
+	if (jobsplit && collated_copies > 0)
+	{
+	    /* Splitting jobs: Stop a previous job and start a new one. */
+	    mch_print_end(&settings);
+	    if (!mch_print_begin(&settings))
+		goto print_fail_no_begin;
+	}
+
+	/*
+	 * Loop over all pages in the print job: 1 2 3 ...
+	 */
+	for (page_count = 0; prtpos.file_line <= eap->line2; ++page_count)
+	{
+	    /*
+	     * Loop over uncollated copies: 1 1 1, 2 2 2, 3 3 3, ...
+	     * For duplex: 12 12 12 34 34 34, ...
+	     */
+	    for (uncollated_copies = 0;
+		    uncollated_copies < settings.n_uncollated_copies;
+		    uncollated_copies++)
+	    {
+		/* Set the print position to the start of this page. */
+		prtpos = page_prtpos;
+
+		/*
+		 * Do front and rear side of a page.
+		 */
+		for (side = 0; side <= settings.duplex; ++side)
+		{
+		    /*
+		     * Print one page.
+		     */
+
+		    /* Check for interrupt character every page. */
+		    ui_breakcheck();
+		    if (got_int || settings.user_abort)
+			goto print_fail;
+
+		    sprintf((char *)IObuff, _("Printing page %d (%d%%)"),
+			    page_count + 1 + side,
+			    prtpos.bytes_printed > 1000000
+				? (int)(prtpos.bytes_printed /
+						       (bytes_to_print / 100))
+				: (int)((prtpos.bytes_printed * 100)
+							   / bytes_to_print));
+		    if (!mch_print_begin_page(IObuff))
+			goto print_fail;
+
+		    if (settings.n_collated_copies > 1)
+			sprintf((char *)IObuff + STRLEN(IObuff),
+				_(" Copy %d of %d"),
+				collated_copies + 1,
+				settings.n_collated_copies);
+		    prt_message(IObuff);
+
+		    /*
+		     * Output header if required
+		     */
+		    if (prt_header_height() > 0)
+			prt_header(&settings, page_count + 1 + side,
+							prtpos.file_line);
+
+		    for (page_line = 0; page_line < settings.lines_per_page;
+								  ++page_line)
+		    {
+			prtpos.column = hardcopy_line(&settings,
+							   page_line, &prtpos);
+			if (prtpos.column == 0)
+			{
+			    /* finished a file line */
+			    prtpos.bytes_printed +=
+				  STRLEN(skipwhite(ml_get(prtpos.file_line)));
+			    if (++prtpos.file_line > eap->line2)
+				break; /* reached the end */
+			}
+			else if (prtpos.ff)
+			{
+			    /* Line had a formfeed in it - start new page but
+			     * stay on the current line */
+			    break;
+			}
+		    }
+
+		    if (!mch_print_end_page())
+			goto print_fail;
+		    if (prtpos.file_line > eap->line2)
+			break; /* reached the end */
+		}
+
+		/*
+		 * Extra blank page for duplexing with odd number of pages and
+		 * more copies to come.
+		 */
+		if (prtpos.file_line > eap->line2 && settings.duplex
+								 && side == 0
+		    && uncollated_copies + 1 < settings.n_uncollated_copies)
+		{
+		    if (!mch_print_blank_page())
+			goto print_fail;
+		}
+	    }
+	    if (settings.duplex && prtpos.file_line <= eap->line2)
+		++page_count;
+
+	    /* Remember the position where the next page starts. */
+	    page_prtpos = prtpos;
+	}
+
+	vim_snprintf((char *)IObuff, IOSIZE, _("Printed: %s"),
+							    settings.jobname);
+	prt_message(IObuff);
+    }
+
+print_fail:
+    if (got_int || settings.user_abort)
+    {
+	sprintf((char *)IObuff, "%s", _("Printing aborted"));
+	prt_message(IObuff);
+    }
+    mch_print_end(&settings);
+
+print_fail_no_begin:
+    mch_print_cleanup();
+}
+
+/*
+ * Print one page line.
+ * Return the next column to print, or zero if the line is finished.
+ */
+    static colnr_T
+hardcopy_line(psettings, page_line, ppos)
+    prt_settings_T	*psettings;
+    int			page_line;
+    prt_pos_T		*ppos;
+{
+    colnr_T	col;
+    char_u	*line;
+    int		need_break = FALSE;
+    int		outputlen;
+    int		tab_spaces;
+    long_u	print_pos;
+#ifdef FEAT_SYN_HL
+    prt_text_attr_T attr;
+    int		id;
+#endif
+
+    if (ppos->column == 0 || ppos->ff)
+    {
+	print_pos = 0;
+	tab_spaces = 0;
+	if (!ppos->ff && prt_use_number())
+	    prt_line_number(psettings, page_line, ppos->file_line);
+	ppos->ff = FALSE;
+    }
+    else
+    {
+	/* left over from wrap halfway a tab */
+	print_pos = ppos->print_pos;
+	tab_spaces = ppos->lead_spaces;
+    }
+
+    mch_print_start_line(0, page_line);
+    line = ml_get(ppos->file_line);
+
+    /*
+     * Loop over the columns until the end of the file line or right margin.
+     */
+    for (col = ppos->column; line[col] != NUL && !need_break; col += outputlen)
+    {
+	outputlen = 1;
+#ifdef FEAT_MBYTE
+	if (has_mbyte && (outputlen = (*mb_ptr2len)(line + col)) < 1)
+	    outputlen = 1;
+#endif
+#ifdef FEAT_SYN_HL
+	/*
+	 * syntax highlighting stuff.
+	 */
+	if (psettings->do_syntax)
+	{
+	    id = syn_get_id(curwin, ppos->file_line, col, 1, NULL);
+	    if (id > 0)
+		id = syn_get_final_id(id);
+	    else
+		id = 0;
+	    /* Get the line again, a multi-line regexp may invalidate it. */
+	    line = ml_get(ppos->file_line);
+
+	    if (id != current_syn_id)
+	    {
+		current_syn_id = id;
+		prt_get_attr(id, &attr, psettings->modec);
+		prt_set_font(attr.bold, attr.italic, attr.underline);
+		prt_set_fg(attr.fg_color);
+		prt_set_bg(attr.bg_color);
+	    }
+	}
+#endif
+
+	/*
+	 * Appropriately expand any tabs to spaces.
+	 */
+	if (line[col] == TAB || tab_spaces != 0)
+	{
+	    if (tab_spaces == 0)
+		tab_spaces = (int)(curbuf->b_p_ts - (print_pos % curbuf->b_p_ts));
+
+	    while (tab_spaces > 0)
+	    {
+		need_break = mch_print_text_out((char_u *)" ", 1);
+		print_pos++;
+		tab_spaces--;
+		if (need_break)
+		    break;
+	    }
+	    /* Keep the TAB if we didn't finish it. */
+	    if (need_break && tab_spaces > 0)
+		break;
+	}
+	else if (line[col] == FF
+		&& printer_opts[OPT_PRINT_FORMFEED].present
+		&& TOLOWER_ASC(printer_opts[OPT_PRINT_FORMFEED].string[0])
+								       == 'y')
+	{
+	    ppos->ff = TRUE;
+	    need_break = 1;
+	}
+	else
+	{
+	    need_break = mch_print_text_out(line + col, outputlen);
+#ifdef FEAT_MBYTE
+	    if (has_mbyte)
+		print_pos += (*mb_ptr2cells)(line + col);
+	    else
+#endif
+		print_pos++;
+	}
+    }
+
+    ppos->lead_spaces = tab_spaces;
+    ppos->print_pos = (int)print_pos;
+
+    /*
+     * Start next line of file if we clip lines, or have reached end of the
+     * line, unless we are doing a formfeed.
+     */
+    if (!ppos->ff
+	    && (line[col] == NUL
+		|| (printer_opts[OPT_PRINT_WRAP].present
+		    && TOLOWER_ASC(printer_opts[OPT_PRINT_WRAP].string[0])
+								     == 'n')))
+	return 0;
+    return col;
+}
+
+# if defined(FEAT_POSTSCRIPT) || defined(PROTO)
+
+/*
+ * PS printer stuff.
+ *
+ * Sources of information to help maintain the PS printing code:
+ *
+ * 1. PostScript Language Reference, 3rd Edition,
+ *      Addison-Wesley, 1999, ISBN 0-201-37922-8
+ * 2. PostScript Language Program Design,
+ *      Addison-Wesley, 1988, ISBN 0-201-14396-8
+ * 3. PostScript Tutorial and Cookbook,
+ *      Addison Wesley, 1985, ISBN 0-201-10179-3
+ * 4. PostScript Language Document Structuring Conventions Specification,
+ *    version 3.0,
+ *      Adobe Technote 5001, 25th September 1992
+ * 5. PostScript Printer Description File Format Specification, Version 4.3,
+ *      Adobe technote 5003, 9th February 1996
+ * 6. Adobe Font Metrics File Format Specification, Version 4.1,
+ *      Adobe Technote 5007, 7th October 1998
+ * 7. Adobe CMap and CIDFont Files Specification, Version 1.0,
+ *      Adobe Technote 5014, 8th October 1996
+ * 8. Adobe CJKV Character Collections and CMaps for CID-Keyed Fonts,
+ *      Adoboe Technote 5094, 8th September, 2001
+ * 9. CJKV Information Processing, 2nd Edition,
+ *      O'Reilly, 2002, ISBN 1-56592-224-7
+ *
+ * Some of these documents can be found in PDF form on Adobe's web site -
+ * http://www.adobe.com
+ */
+
+#define NUM_ELEMENTS(arr)   (sizeof(arr)/sizeof((arr)[0]))
+
+#define PRT_PS_DEFAULT_DPI	    (72)    /* Default user space resolution */
+#define PRT_PS_DEFAULT_FONTSIZE     (10)
+#define PRT_PS_DEFAULT_BUFFER_SIZE  (80)
+
+struct prt_mediasize_S
+{
+    char	*name;
+    float	width;		/* width and height in points for portrait */
+    float	height;
+};
+
+#define PRT_MEDIASIZE_LEN  (sizeof(prt_mediasize) / sizeof(struct prt_mediasize_S))
+
+static struct prt_mediasize_S prt_mediasize[] =
+{
+    {"A4",		595.0,  842.0},
+    {"letter",		612.0,  792.0},
+    {"10x14",		720.0, 1008.0},
+    {"A3",		842.0, 1191.0},
+    {"A5",		420.0,  595.0},
+    {"B4",		729.0, 1032.0},
+    {"B5",		516.0,  729.0},
+    {"executive",	522.0,  756.0},
+    {"folio",		595.0,  935.0},
+    {"ledger",	       1224.0,  792.0},   /* Yes, it is wider than taller! */
+    {"legal",		612.0, 1008.0},
+    {"quarto",		610.0,  780.0},
+    {"statement",	396.0,  612.0},
+    {"tabloid",		792.0, 1224.0}
+};
+
+/* PS font names, must be in Roman, Bold, Italic, Bold-Italic order */
+struct prt_ps_font_S
+{
+    int		wx;
+    int		uline_offset;
+    int		uline_width;
+    int		bbox_min_y;
+    int		bbox_max_y;
+    char	*(ps_fontname[4]);
+};
+
+#define PRT_PS_FONT_ROMAN	(0)
+#define PRT_PS_FONT_BOLD	(1)
+#define PRT_PS_FONT_OBLIQUE	(2)
+#define PRT_PS_FONT_BOLDOBLIQUE (3)
+
+/* Standard font metrics for Courier family */
+static struct prt_ps_font_S prt_ps_courier_font =
+{
+    600,
+    -100, 50,
+    -250, 805,
+    {"Courier", "Courier-Bold", "Courier-Oblique", "Courier-BoldOblique"}
+};
+
+#ifdef FEAT_MBYTE
+/* Generic font metrics for multi-byte fonts */
+static struct prt_ps_font_S prt_ps_mb_font =
+{
+    1000,
+    -100, 50,
+    -250, 805,
+    {NULL, NULL, NULL, NULL}
+};
+#endif
+
+/* Pointer to current font set being used */
+static struct prt_ps_font_S* prt_ps_font;
+
+/* Structures to map user named encoding and mapping to PS equivalents for
+ * building CID font name */
+struct prt_ps_encoding_S
+{
+    char	*encoding;
+    char	*cmap_encoding;
+    int		needs_charset;
+};
+
+struct prt_ps_charset_S
+{
+    char	*charset;
+    char	*cmap_charset;
+    int		has_charset;
+};
+
+#ifdef FEAT_MBYTE
+
+#define CS_JIS_C_1978   (0x01)
+#define CS_JIS_X_1983   (0x02)
+#define CS_JIS_X_1990   (0x04)
+#define CS_NEC		(0x08)
+#define CS_MSWINDOWS	(0x10)
+#define CS_CP932	(0x20)
+#define CS_KANJITALK6	(0x40)
+#define CS_KANJITALK7   (0x80)
+
+/* Japanese encodings and charsets */
+static struct prt_ps_encoding_S j_encodings[] =
+{
+    {"iso-2022-jp", NULL,       (CS_JIS_C_1978|CS_JIS_X_1983|CS_JIS_X_1990|
+								    CS_NEC)},
+    {"euc-jp",	    "EUC",	(CS_JIS_C_1978|CS_JIS_X_1983|CS_JIS_X_1990)},
+    {"sjis",	    "RKSJ",	(CS_JIS_C_1978|CS_JIS_X_1983|CS_MSWINDOWS|
+						CS_KANJITALK6|CS_KANJITALK7)},
+    {"cp932",       "RKSJ",     CS_JIS_X_1983},
+    {"ucs-2",       "UCS2",     CS_JIS_X_1990},
+    {"utf-8",       "UTF8" ,    CS_JIS_X_1990}
+};
+static struct prt_ps_charset_S j_charsets[] =
+{
+    {"JIS_C_1978",  "78",       CS_JIS_C_1978},
+    {"JIS_X_1983",  NULL,       CS_JIS_X_1983},
+    {"JIS_X_1990",  "Hojo",     CS_JIS_X_1990},
+    {"NEC",	    "Ext",	CS_NEC},
+    {"MSWINDOWS",   "90ms",     CS_MSWINDOWS},
+    {"CP932",       "90ms",     CS_JIS_X_1983},
+    {"KANJITALK6",  "83pv",     CS_KANJITALK6},
+    {"KANJITALK7",  "90pv",     CS_KANJITALK7}
+};
+
+#define CS_GB_2312_80       (0x01)
+#define CS_GBT_12345_90     (0x02)
+#define CS_GBK2K	    (0x04)
+#define CS_SC_MAC	    (0x08)
+#define CS_GBT_90_MAC	    (0x10)
+#define CS_GBK		    (0x20)
+#define CS_SC_ISO10646      (0x40)
+
+/* Simplified Chinese encodings and charsets */
+static struct prt_ps_encoding_S sc_encodings[] =
+{
+    {"iso-2022",    NULL,       (CS_GB_2312_80|CS_GBT_12345_90)},
+    {"gb18030",     NULL,       CS_GBK2K},
+    {"euc-cn",      "EUC",      (CS_GB_2312_80|CS_GBT_12345_90|CS_SC_MAC|
+								CS_GBT_90_MAC)},
+    {"gbk",	    "EUC",	CS_GBK},
+    {"ucs-2",       "UCS2",     CS_SC_ISO10646},
+    {"utf-8",       "UTF8",     CS_SC_ISO10646}
+};
+static struct prt_ps_charset_S sc_charsets[] =
+{
+    {"GB_2312-80",  "GB",       CS_GB_2312_80},
+    {"GBT_12345-90","GBT",      CS_GBT_12345_90},
+    {"MAC",	    "GBpc",	CS_SC_MAC},
+    {"GBT-90_MAC",  "GBTpc",	CS_GBT_90_MAC},
+    {"GBK",	    "GBK",	CS_GBK},
+    {"GB18030",     "GBK2K",    CS_GBK2K},
+    {"ISO10646",    "UniGB",    CS_SC_ISO10646}
+};
+
+#define CS_CNS_PLANE_1      (0x01)
+#define CS_CNS_PLANE_2      (0x02)
+#define CS_CNS_PLANE_1_2    (0x04)
+#define CS_B5		    (0x08)
+#define CS_ETEN		    (0x10)
+#define CS_HK_GCCS	    (0x20)
+#define CS_HK_SCS	    (0x40)
+#define CS_HK_SCS_ETEN	    (0x80)
+#define CS_MTHKL	    (0x100)
+#define CS_MTHKS	    (0x200)
+#define CS_DLHKL	    (0x400)
+#define CS_DLHKS	    (0x800)
+#define CS_TC_ISO10646	    (0x1000)
+
+/* Traditional Chinese encodings and charsets */
+static struct prt_ps_encoding_S tc_encodings[] =
+{
+    {"iso-2022",    NULL,       (CS_CNS_PLANE_1|CS_CNS_PLANE_2)},
+    {"euc-tw",      "EUC",      CS_CNS_PLANE_1_2},
+    {"big5",	    "B5",	(CS_B5|CS_ETEN|CS_HK_GCCS|CS_HK_SCS|
+				    CS_HK_SCS_ETEN|CS_MTHKL|CS_MTHKS|CS_DLHKL|
+								    CS_DLHKS)},
+    {"cp950",       "B5",       CS_B5},
+    {"ucs-2",       "UCS2",     CS_TC_ISO10646},
+    {"utf-8",       "UTF8",     CS_TC_ISO10646},
+    {"utf-16",      "UTF16",    CS_TC_ISO10646},
+    {"utf-32",      "UTF32",    CS_TC_ISO10646}
+};
+static struct prt_ps_charset_S tc_charsets[] =
+{
+    {"CNS_1992_1",  "CNS1",     CS_CNS_PLANE_1},
+    {"CNS_1992_2",  "CNS2",     CS_CNS_PLANE_2},
+    {"CNS_1993",    "CNS",      CS_CNS_PLANE_1_2},
+    {"BIG5",	    NULL,	CS_B5},
+    {"CP950",	    NULL,	CS_B5},
+    {"ETEN",	    "ETen",	CS_ETEN},
+    {"HK_GCCS",     "HKgccs",	CS_HK_GCCS},
+    {"SCS",	    "HKscs",	CS_HK_SCS},
+    {"SCS_ETEN",    "ETHK",     CS_HK_SCS_ETEN},
+    {"MTHKL",       "HKm471",   CS_MTHKL},
+    {"MTHKS",       "HKm314",   CS_MTHKS},
+    {"DLHKL",       "HKdla",    CS_DLHKL},
+    {"DLHKS",       "HKdlb",    CS_DLHKS},
+    {"ISO10646",    "UniCNS",   CS_TC_ISO10646}
+};
+
+#define CS_KR_X_1992	    (0x01)
+#define CS_KR_MAC	    (0x02)
+#define CS_KR_X_1992_MS     (0x04)
+#define CS_KR_ISO10646      (0x08)
+
+/* Korean encodings and charsets */
+static struct prt_ps_encoding_S k_encodings[] =
+{
+    {"iso-2022-kr", NULL,       CS_KR_X_1992},
+    {"euc-kr",      "EUC",      (CS_KR_X_1992|CS_KR_MAC)},
+    {"johab",       "Johab",    CS_KR_X_1992},
+    {"cp1361",      "Johab",    CS_KR_X_1992},
+    {"uhc",	    "UHC",	CS_KR_X_1992_MS},
+    {"cp949",       "UHC",      CS_KR_X_1992_MS},
+    {"ucs-2",       "UCS2",     CS_KR_ISO10646},
+    {"utf-8",       "UTF8",     CS_KR_ISO10646}
+};
+static struct prt_ps_charset_S k_charsets[] =
+{
+    {"KS_X_1992",   "KSC",      CS_KR_X_1992},
+    {"CP1361",      "KSC",      CS_KR_X_1992},
+    {"MAC",	    "KSCpc",	CS_KR_MAC},
+    {"MSWINDOWS",   "KSCms",    CS_KR_X_1992_MS},
+    {"CP949",       "KSCms",    CS_KR_X_1992_MS},
+    {"WANSUNG",     "KSCms",    CS_KR_X_1992_MS},
+    {"ISO10646",    "UniKS",    CS_KR_ISO10646}
+};
+
+/* Collections of encodings and charsets for multi-byte printing */
+struct prt_ps_mbfont_S
+{
+    int				num_encodings;
+    struct prt_ps_encoding_S	*encodings;
+    int				num_charsets;
+    struct prt_ps_charset_S	*charsets;
+    char			*ascii_enc;
+    char			*defcs;
+};
+
+static struct prt_ps_mbfont_S prt_ps_mbfonts[] =
+{
+    {
+	NUM_ELEMENTS(j_encodings),
+	j_encodings,
+	NUM_ELEMENTS(j_charsets),
+	j_charsets,
+	"jis_roman",
+	"JIS_X_1983"
+    },
+    {
+	NUM_ELEMENTS(sc_encodings),
+	sc_encodings,
+	NUM_ELEMENTS(sc_charsets),
+	sc_charsets,
+	"gb_roman",
+	"GB_2312-80"
+    },
+    {
+	NUM_ELEMENTS(tc_encodings),
+	tc_encodings,
+	NUM_ELEMENTS(tc_charsets),
+	tc_charsets,
+	"cns_roman",
+	"BIG5"
+    },
+    {
+	NUM_ELEMENTS(k_encodings),
+	k_encodings,
+	NUM_ELEMENTS(k_charsets),
+	k_charsets,
+	"ks_roman",
+	"KS_X_1992"
+    }
+};
+#endif /* FEAT_MBYTE */
+
+struct prt_ps_resource_S
+{
+    char_u  name[64];
+    char_u  filename[MAXPATHL + 1];
+    int     type;
+    char_u  title[256];
+    char_u  version[256];
+};
+
+/* Types of PS resource file currently used */
+#define PRT_RESOURCE_TYPE_PROCSET   (0)
+#define PRT_RESOURCE_TYPE_ENCODING  (1)
+#define PRT_RESOURCE_TYPE_CMAP      (2)
+
+/* The PS prolog file version number has to match - if the prolog file is
+ * updated, increment the number in the file and here.  Version checking was
+ * added as of VIM 6.2.
+ * The CID prolog file version number behaves as per PS prolog.
+ * Table of VIM and prolog versions:
+ *
+ * VIM      Prolog  CIDProlog
+ * 6.2      1.3
+ * 7.0      1.4	    1.0
+ */
+#define PRT_PROLOG_VERSION  ((char_u *)"1.4")
+#define PRT_CID_PROLOG_VERSION  ((char_u *)"1.0")
+
+/* String versions of PS resource types - indexed by constants above so don't
+ * re-order!
+ */
+static char *prt_resource_types[] =
+{
+    "procset",
+    "encoding",
+    "cmap"
+};
+
+/* Strings to look for in a PS resource file */
+#define PRT_RESOURCE_HEADER	    "%!PS-Adobe-"
+#define PRT_RESOURCE_RESOURCE	    "Resource-"
+#define PRT_RESOURCE_PROCSET	    "ProcSet"
+#define PRT_RESOURCE_ENCODING	    "Encoding"
+#define PRT_RESOURCE_CMAP	    "CMap"
+
+
+/* Data for table based DSC comment recognition, easy to extend if VIM needs to
+ * read more comments. */
+#define PRT_DSC_MISC_TYPE	    (-1)
+#define PRT_DSC_TITLE_TYPE	    (1)
+#define PRT_DSC_VERSION_TYPE	    (2)
+#define PRT_DSC_ENDCOMMENTS_TYPE    (3)
+
+#define PRT_DSC_TITLE		    "%%Title:"
+#define PRT_DSC_VERSION		    "%%Version:"
+#define PRT_DSC_ENDCOMMENTS	    "%%EndComments:"
+
+struct prt_dsc_comment_S
+{
+    char	*string;
+    int		len;
+    int		type;
+};
+
+struct prt_dsc_line_S
+{
+    int		type;
+    char_u	*string;
+    int		len;
+};
+
+
+#define SIZEOF_CSTR(s)      (sizeof(s) - 1)
+static struct prt_dsc_comment_S prt_dsc_table[] =
+{
+    {PRT_DSC_TITLE,       SIZEOF_CSTR(PRT_DSC_TITLE),     PRT_DSC_TITLE_TYPE},
+    {PRT_DSC_VERSION,     SIZEOF_CSTR(PRT_DSC_VERSION),
+							PRT_DSC_VERSION_TYPE},
+    {PRT_DSC_ENDCOMMENTS, SIZEOF_CSTR(PRT_DSC_ENDCOMMENTS),
+						     PRT_DSC_ENDCOMMENTS_TYPE}
+};
+
+static void prt_write_file_raw_len __ARGS((char_u *buffer, int bytes));
+static void prt_write_file __ARGS((char_u *buffer));
+static void prt_write_file_len __ARGS((char_u *buffer, int bytes));
+static void prt_write_string __ARGS((char *s));
+static void prt_write_int __ARGS((int i));
+static void prt_write_boolean __ARGS((int b));
+static void prt_def_font __ARGS((char *new_name, char *encoding, int height, char *font));
+static void prt_real_bits __ARGS((double real, int precision, int *pinteger, int *pfraction));
+static void prt_write_real __ARGS((double val, int prec));
+static void prt_def_var __ARGS((char *name, double value, int prec));
+static void prt_flush_buffer __ARGS((void));
+static void prt_resource_name __ARGS((char_u *filename, void *cookie));
+static int prt_find_resource __ARGS((char *name, struct prt_ps_resource_S *resource));
+static int prt_open_resource __ARGS((struct prt_ps_resource_S *resource));
+static int prt_check_resource __ARGS((struct prt_ps_resource_S *resource, char_u *version));
+static void prt_dsc_start __ARGS((void));
+static void prt_dsc_noarg __ARGS((char *comment));
+static void prt_dsc_textline __ARGS((char *comment, char *text));
+static void prt_dsc_text __ARGS((char *comment, char *text));
+static void prt_dsc_ints __ARGS((char *comment, int count, int *ints));
+static void prt_dsc_requirements __ARGS((int duplex, int tumble, int collate, int color, int num_copies));
+static void prt_dsc_docmedia __ARGS((char *paper_name, double width, double height, double weight, char *colour, char *type));
+static void prt_dsc_resources __ARGS((char *comment, char *type, char *strings));
+static void prt_dsc_font_resource __ARGS((char *resource, struct prt_ps_font_S *ps_font));
+static float to_device_units __ARGS((int idx, double physsize, int def_number));
+static void prt_page_margins __ARGS((double width, double height, double *left, double *right, double *top, double *bottom));
+static void prt_font_metrics __ARGS((int font_scale));
+static int prt_get_cpl __ARGS((void));
+static int prt_get_lpp __ARGS((void));
+static int prt_add_resource __ARGS((struct prt_ps_resource_S *resource));
+static int prt_resfile_next_line __ARGS((void));
+static int prt_resfile_strncmp __ARGS((int offset, char *string, int len));
+static int prt_resfile_skip_nonws __ARGS((int offset));
+static int prt_resfile_skip_ws __ARGS((int offset));
+static int prt_next_dsc __ARGS((struct prt_dsc_line_S *p_dsc_line));
+#ifdef FEAT_MBYTE
+static int prt_build_cid_fontname __ARGS((int font, char_u *name, int name_len));
+static void prt_def_cidfont __ARGS((char *new_name, int height, char *cidfont));
+static void prt_dup_cidfont __ARGS((char *original_name, char *new_name));
+static int prt_match_encoding __ARGS((char *p_encoding, struct prt_ps_mbfont_S *p_cmap, struct prt_ps_encoding_S **pp_mbenc));
+static int prt_match_charset __ARGS((char *p_charset, struct prt_ps_mbfont_S *p_cmap, struct prt_ps_charset_S **pp_mbchar));
+#endif
+
+/*
+ * Variables for the output PostScript file.
+ */
+static FILE *prt_ps_fd;
+static int prt_file_error;
+static char_u *prt_ps_file_name = NULL;
+
+/*
+ * Various offsets and dimensions in default PostScript user space (points).
+ * Used for text positioning calculations
+ */
+static float prt_page_width;
+static float prt_page_height;
+static float prt_left_margin;
+static float prt_right_margin;
+static float prt_top_margin;
+static float prt_bottom_margin;
+static float prt_line_height;
+static float prt_first_line_height;
+static float prt_char_width;
+static float prt_number_width;
+static float prt_bgcol_offset;
+static float prt_pos_x_moveto = 0.0;
+static float prt_pos_y_moveto = 0.0;
+
+/*
+ * Various control variables used to decide when and how to change the
+ * PostScript graphics state.
+ */
+static int prt_need_moveto;
+static int prt_do_moveto;
+static int prt_need_font;
+static int prt_font;
+static int prt_need_underline;
+static int prt_underline;
+static int prt_do_underline;
+static int prt_need_fgcol;
+static int prt_fgcol;
+static int prt_need_bgcol;
+static int prt_do_bgcol;
+static int prt_bgcol;
+static int prt_new_bgcol;
+static int prt_attribute_change;
+static float prt_text_run;
+static int prt_page_num;
+static int prt_bufsiz;
+
+/*
+ * Variables controlling physical printing.
+ */
+static int prt_media;
+static int prt_portrait;
+static int prt_num_copies;
+static int prt_duplex;
+static int prt_tumble;
+static int prt_collate;
+
+/*
+ * Buffers used when generating PostScript output
+ */
+static char_u prt_line_buffer[257];
+static garray_T prt_ps_buffer;
+
+# ifdef FEAT_MBYTE
+static int prt_do_conv;
+static vimconv_T prt_conv;
+
+static int prt_out_mbyte;
+static int prt_custom_cmap;
+static char prt_cmap[80];
+static int prt_use_courier;
+static int prt_in_ascii;
+static int prt_half_width;
+static char *prt_ascii_encoding;
+static char_u prt_hexchar[] = "0123456789abcdef";
+# endif
+
+    static void
+prt_write_file_raw_len(buffer, bytes)
+    char_u	*buffer;
+    int		bytes;
+{
+    if (!prt_file_error
+	    && fwrite(buffer, sizeof(char_u), bytes, prt_ps_fd)
+							     != (size_t)bytes)
+    {
+	EMSG(_("E455: Error writing to PostScript output file"));
+	prt_file_error = TRUE;
+    }
+}
+
+    static void
+prt_write_file(buffer)
+    char_u	*buffer;
+{
+    prt_write_file_len(buffer, (int)STRLEN(buffer));
+}
+
+    static void
+prt_write_file_len(buffer, bytes)
+    char_u	*buffer;
+    int		bytes;
+{
+#ifdef EBCDIC
+    ebcdic2ascii(buffer, bytes);
+#endif
+    prt_write_file_raw_len(buffer, bytes);
+}
+
+/*
+ * Write a string.
+ */
+    static void
+prt_write_string(s)
+    char	*s;
+{
+    vim_snprintf((char *)prt_line_buffer, sizeof(prt_line_buffer), "%s", s);
+    prt_write_file(prt_line_buffer);
+}
+
+/*
+ * Write an int and a space.
+ */
+    static void
+prt_write_int(i)
+    int		i;
+{
+    sprintf((char *)prt_line_buffer, "%d ", i);
+    prt_write_file(prt_line_buffer);
+}
+
+/*
+ * Write a boolean and a space.
+ */
+    static void
+prt_write_boolean(b)
+    int		b;
+{
+    sprintf((char *)prt_line_buffer, "%s ", (b ? "T" : "F"));
+    prt_write_file(prt_line_buffer);
+}
+
+/*
+ * Write PostScript to re-encode and define the font.
+ */
+    static void
+prt_def_font(new_name, encoding, height, font)
+    char	*new_name;
+    char	*encoding;
+    int		height;
+    char	*font;
+{
+    vim_snprintf((char *)prt_line_buffer, sizeof(prt_line_buffer),
+			  "/_%s /VIM-%s /%s ref\n", new_name, encoding, font);
+    prt_write_file(prt_line_buffer);
+#ifdef FEAT_MBYTE
+    if (prt_out_mbyte)
+	sprintf((char *)prt_line_buffer, "/%s %d %f /_%s sffs\n",
+		       new_name, height, 500./prt_ps_courier_font.wx, new_name);
+    else
+#endif
+	vim_snprintf((char *)prt_line_buffer, sizeof(prt_line_buffer),
+			     "/%s %d /_%s ffs\n", new_name, height, new_name);
+    prt_write_file(prt_line_buffer);
+}
+
+#ifdef FEAT_MBYTE
+/*
+ * Write a line to define the CID font.
+ */
+    static void
+prt_def_cidfont(new_name, height, cidfont)
+    char	*new_name;
+    int		height;
+    char	*cidfont;
+{
+    vim_snprintf((char *)prt_line_buffer, sizeof(prt_line_buffer),
+	      "/_%s /%s[/%s] vim_composefont\n", new_name, prt_cmap, cidfont);
+    prt_write_file(prt_line_buffer);
+    vim_snprintf((char *)prt_line_buffer, sizeof(prt_line_buffer),
+			     "/%s %d /_%s ffs\n", new_name, height, new_name);
+    prt_write_file(prt_line_buffer);
+}
+
+/*
+ * Write a line to define a duplicate of a CID font
+ */
+    static void
+prt_dup_cidfont(original_name, new_name)
+    char	*original_name;
+    char	*new_name;
+{
+    vim_snprintf((char *)prt_line_buffer, sizeof(prt_line_buffer),
+				       "/%s %s d\n", new_name, original_name);
+    prt_write_file(prt_line_buffer);
+}
+#endif
+
+/*
+ * Convert a real value into an integer and fractional part as integers, with
+ * the fractional part being in the range [0,10^precision).  The fractional part
+ * is also rounded based on the precision + 1'th fractional digit.
+ */
+    static void
+prt_real_bits(real, precision, pinteger, pfraction)
+    double      real;
+    int		precision;
+    int		*pinteger;
+    int		*pfraction;
+{
+    int     i;
+    int     integer;
+    float   fraction;
+
+    integer = (int)real;
+    fraction = (float)(real - integer);
+    if (real < (double)integer)
+	fraction = -fraction;
+    for (i = 0; i < precision; i++)
+	fraction *= 10.0;
+
+    *pinteger = integer;
+    *pfraction = (int)(fraction + 0.5);
+}
+
+/*
+ * Write a real and a space.  Save bytes if real value has no fractional part!
+ * We use prt_real_bits() as %f in sprintf uses the locale setting to decide
+ * what decimal point character to use, but PS always requires a '.'.
+ */
+    static void
+prt_write_real(val, prec)
+    double	val;
+    int		prec;
+{
+    int     integer;
+    int     fraction;
+
+    prt_real_bits(val, prec, &integer, &fraction);
+    /* Emit integer part */
+    sprintf((char *)prt_line_buffer, "%d", integer);
+    prt_write_file(prt_line_buffer);
+    /* Only emit fraction if necessary */
+    if (fraction != 0)
+    {
+	/* Remove any trailing zeros */
+	while ((fraction % 10) == 0)
+	{
+	    prec--;
+	    fraction /= 10;
+	}
+	/* Emit fraction left padded with zeros */
+	sprintf((char *)prt_line_buffer, ".%0*d", prec, fraction);
+	prt_write_file(prt_line_buffer);
+    }
+    sprintf((char *)prt_line_buffer, " ");
+    prt_write_file(prt_line_buffer);
+}
+
+/*
+ * Write a line to define a numeric variable.
+ */
+    static void
+prt_def_var(name, value, prec)
+    char	*name;
+    double	value;
+    int		prec;
+{
+    vim_snprintf((char *)prt_line_buffer, sizeof(prt_line_buffer),
+								"/%s ", name);
+    prt_write_file(prt_line_buffer);
+    prt_write_real(value, prec);
+    sprintf((char *)prt_line_buffer, "d\n");
+    prt_write_file(prt_line_buffer);
+}
+
+/* Convert size from font space to user space at current font scale */
+#define PRT_PS_FONT_TO_USER(scale, size)    ((size) * ((scale)/1000.0))
+
+    static void
+prt_flush_buffer()
+{
+    if (prt_ps_buffer.ga_len > 0)
+    {
+	/* Any background color must be drawn first */
+	if (prt_do_bgcol && (prt_new_bgcol != PRCOLOR_WHITE))
+	{
+	    int     r, g, b;
+
+	    if (prt_do_moveto)
+	    {
+		prt_write_real(prt_pos_x_moveto, 2);
+		prt_write_real(prt_pos_y_moveto, 2);
+		prt_write_string("m\n");
+		prt_do_moveto = FALSE;
+	    }
+
+	    /* Size of rect of background color on which text is printed */
+	    prt_write_real(prt_text_run, 2);
+	    prt_write_real(prt_line_height, 2);
+
+	    /* Lastly add the color of the background */
+	    r = ((unsigned)prt_new_bgcol & 0xff0000) >> 16;
+	    g = ((unsigned)prt_new_bgcol & 0xff00) >> 8;
+	    b = prt_new_bgcol & 0xff;
+	    prt_write_real(r / 255.0, 3);
+	    prt_write_real(g / 255.0, 3);
+	    prt_write_real(b / 255.0, 3);
+	    prt_write_string("bg\n");
+	}
+	/* Draw underlines before the text as it makes it slightly easier to
+	 * find the starting point.
+	 */
+	if (prt_do_underline)
+	{
+	    if (prt_do_moveto)
+	    {
+		prt_write_real(prt_pos_x_moveto, 2);
+		prt_write_real(prt_pos_y_moveto, 2);
+		prt_write_string("m\n");
+		prt_do_moveto = FALSE;
+	    }
+
+	    /* Underline length of text run */
+	    prt_write_real(prt_text_run, 2);
+	    prt_write_string("ul\n");
+	}
+	/* Draw the text
+	 * Note: we write text out raw - EBCDIC conversion is handled in the
+	 * PostScript world via the font encoding vector. */
+#ifdef FEAT_MBYTE
+	if (prt_out_mbyte)
+	    prt_write_string("<");
+	else
+#endif
+	    prt_write_string("(");
+	prt_write_file_raw_len(prt_ps_buffer.ga_data, prt_ps_buffer.ga_len);
+#ifdef FEAT_MBYTE
+	if (prt_out_mbyte)
+	    prt_write_string(">");
+	else
+#endif
+	    prt_write_string(")");
+	/* Add a moveto if need be and use the appropriate show procedure */
+	if (prt_do_moveto)
+	{
+	    prt_write_real(prt_pos_x_moveto, 2);
+	    prt_write_real(prt_pos_y_moveto, 2);
+	    /* moveto and a show */
+	    prt_write_string("ms\n");
+	    prt_do_moveto = FALSE;
+	}
+	else /* Simple show */
+	    prt_write_string("s\n");
+
+	ga_clear(&prt_ps_buffer);
+	ga_init2(&prt_ps_buffer, (int)sizeof(char), prt_bufsiz);
+    }
+}
+
+
+    static void
+prt_resource_name(filename, cookie)
+    char_u  *filename;
+    void    *cookie;
+{
+    char_u *resource_filename = cookie;
+
+    if (STRLEN(filename) >= MAXPATHL)
+	*resource_filename = NUL;
+    else
+	STRCPY(resource_filename, filename);
+}
+
+    static int
+prt_find_resource(name, resource)
+    char	*name;
+    struct prt_ps_resource_S *resource;
+{
+    char_u	buffer[MAXPATHL + 1];
+
+    STRCPY(resource->name, name);
+    /* Look for named resource file in runtimepath */
+    STRCPY(buffer, "print");
+    add_pathsep(buffer);
+    STRCAT(buffer, name);
+    STRCAT(buffer, ".ps");
+    resource->filename[0] = NUL;
+    return (do_in_runtimepath(buffer, FALSE, prt_resource_name,
+							   resource->filename)
+	    && resource->filename[0] != NUL);
+}
+
+/* PS CR and LF characters have platform independent values */
+#define PSLF  (0x0a)
+#define PSCR  (0x0d)
+
+/* Static buffer to read initial comments in a resource file, some can have a
+ * couple of KB of comments! */
+#define PRT_FILE_BUFFER_LEN (2048)
+struct prt_resfile_buffer_S
+{
+    char_u  buffer[PRT_FILE_BUFFER_LEN];
+    int     len;
+    int     line_start;
+    int     line_end;
+};
+
+static struct prt_resfile_buffer_S prt_resfile;
+
+    static int
+prt_resfile_next_line()
+{
+    int     idx;
+
+    /* Move to start of next line and then find end of line */
+    idx = prt_resfile.line_end + 1;
+    while (idx < prt_resfile.len)
+    {
+	if (prt_resfile.buffer[idx] != PSLF && prt_resfile.buffer[idx] != PSCR)
+	    break;
+	idx++;
+    }
+    prt_resfile.line_start = idx;
+
+    while (idx < prt_resfile.len)
+    {
+	if (prt_resfile.buffer[idx] == PSLF || prt_resfile.buffer[idx] == PSCR)
+	    break;
+	idx++;
+    }
+    prt_resfile.line_end = idx;
+
+    return (idx < prt_resfile.len);
+}
+
+    static int
+prt_resfile_strncmp(offset, string, len)
+    int     offset;
+    char    *string;
+    int     len;
+{
+    /* Force not equal if string is longer than remainder of line */
+    if (len > (prt_resfile.line_end - (prt_resfile.line_start + offset)))
+	return 1;
+
+    return STRNCMP(&prt_resfile.buffer[prt_resfile.line_start + offset],
+								string, len);
+}
+
+    static int
+prt_resfile_skip_nonws(offset)
+    int     offset;
+{
+    int     idx;
+
+    idx = prt_resfile.line_start + offset;
+    while (idx < prt_resfile.line_end)
+    {
+	if (isspace(prt_resfile.buffer[idx]))
+	    return idx - prt_resfile.line_start;
+	idx++;
+    }
+    return -1;
+}
+
+    static int
+prt_resfile_skip_ws(offset)
+    int     offset;
+{
+    int     idx;
+
+    idx = prt_resfile.line_start + offset;
+    while (idx < prt_resfile.line_end)
+    {
+	if (!isspace(prt_resfile.buffer[idx]))
+	    return idx - prt_resfile.line_start;
+	idx++;
+    }
+    return -1;
+}
+
+/* prt_next_dsc() - returns detail on next DSC comment line found.  Returns true
+ * if a DSC comment is found, else false */
+    static int
+prt_next_dsc(p_dsc_line)
+    struct prt_dsc_line_S *p_dsc_line;
+{
+    int     comment;
+    int     offset;
+
+    /* Move to start of next line */
+    if (!prt_resfile_next_line())
+	return FALSE;
+
+    /* DSC comments always start %% */
+    if (prt_resfile_strncmp(0, "%%", 2) != 0)
+	return FALSE;
+
+    /* Find type of DSC comment */
+    for (comment = 0; comment < NUM_ELEMENTS(prt_dsc_table); comment++)
+	if (prt_resfile_strncmp(0, prt_dsc_table[comment].string,
+					    prt_dsc_table[comment].len) == 0)
+	    break;
+
+    if (comment != NUM_ELEMENTS(prt_dsc_table))
+    {
+	/* Return type of comment */
+	p_dsc_line->type = prt_dsc_table[comment].type;
+	offset = prt_dsc_table[comment].len;
+    }
+    else
+    {
+	/* Unrecognised DSC comment, skip to ws after comment leader */
+	p_dsc_line->type = PRT_DSC_MISC_TYPE;
+	offset = prt_resfile_skip_nonws(0);
+	if (offset == -1)
+	    return FALSE;
+    }
+
+    /* Skip ws to comment value */
+    offset = prt_resfile_skip_ws(offset);
+    if (offset == -1)
+	return FALSE;
+
+    p_dsc_line->string = &prt_resfile.buffer[prt_resfile.line_start + offset];
+    p_dsc_line->len = prt_resfile.line_end - (prt_resfile.line_start + offset);
+
+    return TRUE;
+}
+
+/* Improved hand crafted parser to get the type, title, and version number of a
+ * PS resource file so the file details can be added to the DSC header comments.
+ */
+    static int
+prt_open_resource(resource)
+    struct prt_ps_resource_S *resource;
+{
+    int		offset;
+    int		seen_all;
+    int		seen_title;
+    int		seen_version;
+    FILE	*fd_resource;
+    struct prt_dsc_line_S dsc_line;
+
+    fd_resource = mch_fopen((char *)resource->filename, READBIN);
+    if (fd_resource == NULL)
+    {
+	EMSG2(_("E624: Can't open file \"%s\""), resource->filename);
+	return FALSE;
+    }
+    vim_memset(prt_resfile.buffer, NUL, PRT_FILE_BUFFER_LEN);
+
+    /* Parse first line to ensure valid resource file */
+    prt_resfile.len = (int)fread((char *)prt_resfile.buffer, sizeof(char_u),
+					    PRT_FILE_BUFFER_LEN, fd_resource);
+    if (ferror(fd_resource))
+    {
+	EMSG2(_("E457: Can't read PostScript resource file \"%s\""),
+		resource->filename);
+	fclose(fd_resource);
+	return FALSE;
+    }
+
+    prt_resfile.line_end = -1;
+    prt_resfile.line_start = 0;
+    if (!prt_resfile_next_line())
+	return FALSE;
+
+    offset = 0;
+
+    if (prt_resfile_strncmp(offset, PRT_RESOURCE_HEADER,
+				       (int)STRLEN(PRT_RESOURCE_HEADER)) != 0)
+    {
+	EMSG2(_("E618: file \"%s\" is not a PostScript resource file"),
+		resource->filename);
+	fclose(fd_resource);
+	return FALSE;
+    }
+
+    /* Skip over any version numbers and following ws */
+    offset += (int)STRLEN(PRT_RESOURCE_HEADER);
+    offset = prt_resfile_skip_nonws(offset);
+    if (offset == -1)
+	return FALSE;
+    offset = prt_resfile_skip_ws(offset);
+    if (offset == -1)
+	return FALSE;
+
+    if (prt_resfile_strncmp(offset, PRT_RESOURCE_RESOURCE,
+				     (int)STRLEN(PRT_RESOURCE_RESOURCE)) != 0)
+    {
+	EMSG2(_("E619: file \"%s\" is not a supported PostScript resource file"),
+		resource->filename);
+	fclose(fd_resource);
+	return FALSE;
+    }
+    offset += (int)STRLEN(PRT_RESOURCE_RESOURCE);
+
+    /* Decide type of resource in the file */
+    if (prt_resfile_strncmp(offset, PRT_RESOURCE_PROCSET,
+				      (int)STRLEN(PRT_RESOURCE_PROCSET)) == 0)
+	resource->type = PRT_RESOURCE_TYPE_PROCSET;
+    else if (prt_resfile_strncmp(offset, PRT_RESOURCE_ENCODING,
+				     (int)STRLEN(PRT_RESOURCE_ENCODING)) == 0)
+	resource->type = PRT_RESOURCE_TYPE_ENCODING;
+    else if (prt_resfile_strncmp(offset, PRT_RESOURCE_CMAP,
+					 (int)STRLEN(PRT_RESOURCE_CMAP)) == 0)
+	resource->type = PRT_RESOURCE_TYPE_CMAP;
+    else
+    {
+	EMSG2(_("E619: file \"%s\" is not a supported PostScript resource file"),
+		resource->filename);
+	fclose(fd_resource);
+	return FALSE;
+    }
+
+    /* Look for title and version of resource */
+    resource->title[0] = '\0';
+    resource->version[0] = '\0';
+    seen_title = FALSE;
+    seen_version = FALSE;
+    seen_all = FALSE;
+    while (!seen_all && prt_next_dsc(&dsc_line))
+    {
+	switch (dsc_line.type)
+	{
+	case PRT_DSC_TITLE_TYPE:
+	    vim_strncpy(resource->title, dsc_line.string, dsc_line.len);
+	    seen_title = TRUE;
+	    if (seen_version)
+		seen_all = TRUE;
+	    break;
+
+	case PRT_DSC_VERSION_TYPE:
+	    vim_strncpy(resource->version, dsc_line.string, dsc_line.len);
+	    seen_version = TRUE;
+	    if (seen_title)
+		seen_all = TRUE;
+	    break;
+
+	case PRT_DSC_ENDCOMMENTS_TYPE:
+	    /* Wont find title or resource after this comment, stop searching */
+	    seen_all = TRUE;
+	    break;
+
+	case PRT_DSC_MISC_TYPE:
+	    /* Not interested in whatever comment this line had */
+	    break;
+	}
+    }
+
+    if (!seen_title || !seen_version)
+    {
+	EMSG2(_("E619: file \"%s\" is not a supported PostScript resource file"),
+		resource->filename);
+	fclose(fd_resource);
+	return FALSE;
+    }
+
+    fclose(fd_resource);
+
+    return TRUE;
+}
+
+    static int
+prt_check_resource(resource, version)
+    struct prt_ps_resource_S *resource;
+    char_u  *version;
+{
+    /* Version number m.n should match, the revision number does not matter */
+    if (STRNCMP(resource->version, version, STRLEN(version)))
+    {
+	EMSG2(_("E621: \"%s\" resource file has wrong version"),
+		resource->name);
+	return FALSE;
+    }
+
+    /* Other checks to be added as needed */
+    return TRUE;
+}
+
+    static void
+prt_dsc_start()
+{
+    prt_write_string("%!PS-Adobe-3.0\n");
+}
+
+    static void
+prt_dsc_noarg(comment)
+    char	*comment;
+{
+    vim_snprintf((char *)prt_line_buffer, sizeof(prt_line_buffer),
+							 "%%%%%s\n", comment);
+    prt_write_file(prt_line_buffer);
+}
+
+    static void
+prt_dsc_textline(comment, text)
+    char	*comment;
+    char	*text;
+{
+    vim_snprintf((char *)prt_line_buffer, sizeof(prt_line_buffer),
+					       "%%%%%s: %s\n", comment, text);
+    prt_write_file(prt_line_buffer);
+}
+
+    static void
+prt_dsc_text(comment, text)
+    char	*comment;
+    char	*text;
+{
+    /* TODO - should scan 'text' for any chars needing escaping! */
+    vim_snprintf((char *)prt_line_buffer, sizeof(prt_line_buffer),
+					     "%%%%%s: (%s)\n", comment, text);
+    prt_write_file(prt_line_buffer);
+}
+
+#define prt_dsc_atend(c)	prt_dsc_text((c), "atend")
+
+    static void
+prt_dsc_ints(comment, count, ints)
+    char	*comment;
+    int		count;
+    int		*ints;
+{
+    int		i;
+
+    vim_snprintf((char *)prt_line_buffer, sizeof(prt_line_buffer),
+							  "%%%%%s:", comment);
+    prt_write_file(prt_line_buffer);
+
+    for (i = 0; i < count; i++)
+    {
+	sprintf((char *)prt_line_buffer, " %d", ints[i]);
+	prt_write_file(prt_line_buffer);
+    }
+
+    prt_write_string("\n");
+}
+
+    static void
+prt_dsc_resources(comment, type, string)
+    char	*comment;	/* if NULL add to previous */
+    char	*type;
+    char	*string;
+{
+    if (comment != NULL)
+	vim_snprintf((char *)prt_line_buffer, sizeof(prt_line_buffer),
+						 "%%%%%s: %s", comment, type);
+    else
+	vim_snprintf((char *)prt_line_buffer, sizeof(prt_line_buffer),
+							    "%%%%+ %s", type);
+    prt_write_file(prt_line_buffer);
+
+    vim_snprintf((char *)prt_line_buffer, sizeof(prt_line_buffer),
+							     " %s\n", string);
+    prt_write_file(prt_line_buffer);
+}
+
+    static void
+prt_dsc_font_resource(resource, ps_font)
+    char	*resource;
+    struct prt_ps_font_S *ps_font;
+{
+    int     i;
+
+    prt_dsc_resources(resource, "font",
+				    ps_font->ps_fontname[PRT_PS_FONT_ROMAN]);
+    for (i = PRT_PS_FONT_BOLD ; i <= PRT_PS_FONT_BOLDOBLIQUE ; i++)
+	if (ps_font->ps_fontname[i] != NULL)
+	    prt_dsc_resources(NULL, "font", ps_font->ps_fontname[i]);
+}
+
+    static void
+prt_dsc_requirements(duplex, tumble, collate, color, num_copies)
+    int		duplex;
+    int		tumble;
+    int		collate;
+    int		color;
+    int		num_copies;
+{
+    /* Only output the comment if we need to.
+     * Note: tumble is ignored if we are not duplexing
+     */
+    if (!(duplex || collate || color || (num_copies > 1)))
+	return;
+
+    sprintf((char *)prt_line_buffer, "%%%%Requirements:");
+    prt_write_file(prt_line_buffer);
+
+    if (duplex)
+    {
+	prt_write_string(" duplex");
+	if (tumble)
+	    prt_write_string("(tumble)");
+    }
+    if (collate)
+	prt_write_string(" collate");
+    if (color)
+	prt_write_string(" color");
+    if (num_copies > 1)
+    {
+	prt_write_string(" numcopies(");
+	/* Note: no space wanted so dont use prt_write_int() */
+	sprintf((char *)prt_line_buffer, "%d", num_copies);
+	prt_write_file(prt_line_buffer);
+	prt_write_string(")");
+    }
+    prt_write_string("\n");
+}
+
+    static void
+prt_dsc_docmedia(paper_name, width, height, weight, colour, type)
+    char	*paper_name;
+    double	width;
+    double	height;
+    double	weight;
+    char	*colour;
+    char	*type;
+{
+    vim_snprintf((char *)prt_line_buffer, sizeof(prt_line_buffer),
+					"%%%%DocumentMedia: %s ", paper_name);
+    prt_write_file(prt_line_buffer);
+    prt_write_real(width, 2);
+    prt_write_real(height, 2);
+    prt_write_real(weight, 2);
+    if (colour == NULL)
+	prt_write_string("()");
+    else
+	prt_write_string(colour);
+    prt_write_string(" ");
+    if (type == NULL)
+	prt_write_string("()");
+    else
+	prt_write_string(type);
+    prt_write_string("\n");
+}
+
+    void
+mch_print_cleanup()
+{
+#ifdef FEAT_MBYTE
+    if (prt_out_mbyte)
+    {
+	int     i;
+
+	/* Free off all CID font names created, but first clear duplicate
+	 * pointers to the same string (when the same font is used for more than
+	 * one style).
+	 */
+	for (i = PRT_PS_FONT_ROMAN; i <= PRT_PS_FONT_BOLDOBLIQUE; i++)
+	{
+	    if (prt_ps_mb_font.ps_fontname[i] != NULL)
+		vim_free(prt_ps_mb_font.ps_fontname[i]);
+	    prt_ps_mb_font.ps_fontname[i] = NULL;
+	}
+    }
+
+    if (prt_do_conv)
+    {
+	convert_setup(&prt_conv, NULL, NULL);
+	prt_do_conv = FALSE;
+    }
+#endif
+    if (prt_ps_fd != NULL)
+    {
+	fclose(prt_ps_fd);
+	prt_ps_fd = NULL;
+	prt_file_error = FALSE;
+    }
+    if (prt_ps_file_name != NULL)
+    {
+	vim_free(prt_ps_file_name);
+	prt_ps_file_name = NULL;
+    }
+}
+
+    static float
+to_device_units(idx, physsize, def_number)
+    int		idx;
+    double	physsize;
+    int		def_number;
+{
+    float	ret;
+    int		u;
+    int		nr;
+
+    u = prt_get_unit(idx);
+    if (u == PRT_UNIT_NONE)
+    {
+	u = PRT_UNIT_PERC;
+	nr = def_number;
+    }
+    else
+	nr = printer_opts[idx].number;
+
+    switch (u)
+    {
+	case PRT_UNIT_INCH:
+	    ret = (float)(nr * PRT_PS_DEFAULT_DPI);
+	    break;
+	case PRT_UNIT_MM:
+	    ret = (float)(nr * PRT_PS_DEFAULT_DPI) / (float)25.4;
+	    break;
+	case PRT_UNIT_POINT:
+	    ret = (float)nr;
+	    break;
+	case PRT_UNIT_PERC:
+	default:
+	    ret = (float)(physsize * nr) / 100;
+	    break;
+    }
+
+    return ret;
+}
+
+/*
+ * Calculate margins for given width and height from printoptions settings.
+ */
+    static void
+prt_page_margins(width, height, left, right, top, bottom)
+    double	width;
+    double	height;
+    double	*left;
+    double	*right;
+    double	*top;
+    double	*bottom;
+{
+    *left   = to_device_units(OPT_PRINT_LEFT, width, 10);
+    *right  = width - to_device_units(OPT_PRINT_RIGHT, width, 5);
+    *top    = height - to_device_units(OPT_PRINT_TOP, height, 5);
+    *bottom = to_device_units(OPT_PRINT_BOT, height, 5);
+}
+
+    static void
+prt_font_metrics(font_scale)
+    int		font_scale;
+{
+    prt_line_height = (float)font_scale;
+    prt_char_width = (float)PRT_PS_FONT_TO_USER(font_scale, prt_ps_font->wx);
+}
+
+
+    static int
+prt_get_cpl()
+{
+    if (prt_use_number())
+    {
+	prt_number_width = PRINT_NUMBER_WIDTH * prt_char_width;
+#ifdef FEAT_MBYTE
+	/* If we are outputting multi-byte characters then line numbers will be
+	 * printed with half width characters
+	 */
+	if (prt_out_mbyte)
+	    prt_number_width /= 2;
+#endif
+	prt_left_margin += prt_number_width;
+    }
+    else
+	prt_number_width = 0.0;
+
+    return (int)((prt_right_margin - prt_left_margin) / prt_char_width);
+}
+
+#ifdef FEAT_MBYTE
+    static int
+prt_build_cid_fontname(font, name, name_len)
+    int     font;
+    char_u  *name;
+    int     name_len;
+{
+    char    *fontname;
+
+    fontname = (char *)alloc(name_len + 1);
+    if (fontname == NULL)
+	return FALSE;
+    vim_strncpy((char_u *)fontname, name, name_len);
+    prt_ps_mb_font.ps_fontname[font] = fontname;
+
+    return TRUE;
+}
+#endif
+
+/*
+ * Get number of lines of text that fit on a page (excluding the header).
+ */
+    static int
+prt_get_lpp()
+{
+    int lpp;
+
+    /*
+     * Calculate offset to lower left corner of background rect based on actual
+     * font height (based on its bounding box) and the line height, handling the
+     * case where the font height can exceed the line height.
+     */
+    prt_bgcol_offset = (float)PRT_PS_FONT_TO_USER(prt_line_height,
+					   prt_ps_font->bbox_min_y);
+    if ((prt_ps_font->bbox_max_y - prt_ps_font->bbox_min_y) < 1000.0)
+    {
+	prt_bgcol_offset -= (float)PRT_PS_FONT_TO_USER(prt_line_height,
+				(1000.0 - (prt_ps_font->bbox_max_y -
+					    prt_ps_font->bbox_min_y)) / 2);
+    }
+
+    /* Get height for topmost line based on background rect offset. */
+    prt_first_line_height = prt_line_height + prt_bgcol_offset;
+
+    /* Calculate lpp */
+    lpp = (int)((prt_top_margin - prt_bottom_margin) / prt_line_height);
+
+    /* Adjust top margin if there is a header */
+    prt_top_margin -= prt_line_height * prt_header_height();
+
+    return lpp - prt_header_height();
+}
+
+#ifdef FEAT_MBYTE
+    static int
+prt_match_encoding(p_encoding, p_cmap, pp_mbenc)
+    char			*p_encoding;
+    struct prt_ps_mbfont_S	*p_cmap;
+    struct prt_ps_encoding_S	**pp_mbenc;
+{
+    int				mbenc;
+    int				enc_len;
+    struct prt_ps_encoding_S	*p_mbenc;
+
+    *pp_mbenc = NULL;
+    /* Look for recognised encoding */
+    enc_len = (int)STRLEN(p_encoding);
+    p_mbenc = p_cmap->encodings;
+    for (mbenc = 0; mbenc < p_cmap->num_encodings; mbenc++)
+    {
+	if (STRNICMP(p_mbenc->encoding, p_encoding, enc_len) == 0)
+	{
+	    *pp_mbenc = p_mbenc;
+	    return TRUE;
+	}
+	p_mbenc++;
+    }
+    return FALSE;
+}
+
+    static int
+prt_match_charset(p_charset, p_cmap, pp_mbchar)
+    char		    *p_charset;
+    struct prt_ps_mbfont_S  *p_cmap;
+    struct prt_ps_charset_S **pp_mbchar;
+{
+    int			    mbchar;
+    int			    char_len;
+    struct prt_ps_charset_S *p_mbchar;
+
+    /* Look for recognised character set, using default if one is not given */
+    if (*p_charset == NUL)
+	p_charset = p_cmap->defcs;
+    char_len = (int)STRLEN(p_charset);
+    p_mbchar = p_cmap->charsets;
+    for (mbchar = 0; mbchar < p_cmap->num_charsets; mbchar++)
+    {
+	if (STRNICMP(p_mbchar->charset, p_charset, char_len) == 0)
+	{
+	    *pp_mbchar = p_mbchar;
+	    return TRUE;
+	}
+	p_mbchar++;
+    }
+    return FALSE;
+}
+#endif
+
+/*ARGSUSED*/
+    int
+mch_print_init(psettings, jobname, forceit)
+    prt_settings_T *psettings;
+    char_u	*jobname;
+    int		forceit;
+{
+    int		i;
+    char	*paper_name;
+    int		paper_strlen;
+    int		fontsize;
+    char_u	*p;
+    double      left;
+    double      right;
+    double      top;
+    double      bottom;
+#ifdef FEAT_MBYTE
+    int		props;
+    int		cmap = 0;
+    char_u	*p_encoding;
+    struct prt_ps_encoding_S *p_mbenc;
+    struct prt_ps_encoding_S *p_mbenc_first;
+    struct prt_ps_charset_S  *p_mbchar = NULL;
+#endif
+
+#if 0
+    /*
+     * TODO:
+     * If "forceit" is false: pop up a dialog to select:
+     *	- printer name
+     *	- copies
+     *	- collated/uncollated
+     *	- duplex off/long side/short side
+     *	- paper size
+     *	- portrait/landscape
+     *	- font size
+     *
+     * If "forceit" is true: use the default printer and settings
+     */
+    if (forceit)
+	s_pd.Flags |= PD_RETURNDEFAULT;
+#endif
+
+    /*
+     * Set up font and encoding.
+     */
+#ifdef FEAT_MBYTE
+    p_encoding = enc_skip(p_penc);
+    if (*p_encoding == NUL)
+	p_encoding = enc_skip(p_enc);
+
+    /* Look for a multi-byte font that matches the encoding and character set.
+     * Only look if multi-byte character set is defined, or using multi-byte
+     * encoding other than Unicode.  This is because a Unicode encoding does not
+     * uniquely identify a CJK character set to use. */
+    p_mbenc = NULL;
+    props = enc_canon_props(p_encoding);
+    if (!(props & ENC_8BIT) && ((*p_pmcs != NUL) || !(props & ENC_UNICODE)))
+    {
+	p_mbenc_first = NULL;
+	for (cmap = 0; cmap < NUM_ELEMENTS(prt_ps_mbfonts); cmap++)
+	    if (prt_match_encoding((char *)p_encoding, &prt_ps_mbfonts[cmap],
+								    &p_mbenc))
+	    {
+		if (p_mbenc_first == NULL)
+		    p_mbenc_first = p_mbenc;
+		if (prt_match_charset((char *)p_pmcs, &prt_ps_mbfonts[cmap],
+								   &p_mbchar))
+		    break;
+	    }
+
+	/* Use first encoding matched if no charset matched */
+	if (p_mbchar == NULL && p_mbenc_first != NULL)
+	    p_mbenc = p_mbenc_first;
+    }
+
+    prt_out_mbyte = (p_mbenc != NULL);
+    if (prt_out_mbyte)
+    {
+	/* Build CMap name - will be same for all multi-byte fonts used */
+	prt_cmap[0] = NUL;
+
+	prt_custom_cmap = (p_mbchar == NULL);
+	if (!prt_custom_cmap)
+	{
+	    /* Check encoding and character set are compatible */
+	    if ((p_mbenc->needs_charset & p_mbchar->has_charset) == 0)
+	    {
+		EMSG(_("E673: Incompatible multi-byte encoding and character set."));
+		return FALSE;
+	    }
+
+	    /* Add charset name if not empty */
+	    if (p_mbchar->cmap_charset != NULL)
+	    {
+		vim_strncpy((char_u *)prt_cmap,
+		      (char_u *)p_mbchar->cmap_charset, sizeof(prt_cmap) - 3);
+		STRCAT(prt_cmap, "-");
+	    }
+	}
+	else
+	{
+	    /* Add custom CMap character set name */
+	    if (*p_pmcs == NUL)
+	    {
+		EMSG(_("E674: printmbcharset cannot be empty with multi-byte encoding."));
+		return FALSE;
+	    }
+	    vim_strncpy((char_u *)prt_cmap, p_pmcs, sizeof(prt_cmap) - 3);
+	    STRCAT(prt_cmap, "-");
+	}
+
+	/* CMap name ends with (optional) encoding name and -H for horizontal */
+	if (p_mbenc->cmap_encoding != NULL && STRLEN(prt_cmap)
+		      + STRLEN(p_mbenc->cmap_encoding) + 3 < sizeof(prt_cmap))
+	{
+	    STRCAT(prt_cmap, p_mbenc->cmap_encoding);
+	    STRCAT(prt_cmap, "-");
+	}
+	STRCAT(prt_cmap, "H");
+
+	if (!mbfont_opts[OPT_MBFONT_REGULAR].present)
+	{
+	    EMSG(_("E675: No default font specified for multi-byte printing."));
+	    return FALSE;
+	}
+
+	/* Derive CID font names with fallbacks if not defined */
+	if (!prt_build_cid_fontname(PRT_PS_FONT_ROMAN,
+				    mbfont_opts[OPT_MBFONT_REGULAR].string,
+				    mbfont_opts[OPT_MBFONT_REGULAR].strlen))
+	    return FALSE;
+	if (mbfont_opts[OPT_MBFONT_BOLD].present)
+	    if (!prt_build_cid_fontname(PRT_PS_FONT_BOLD,
+					mbfont_opts[OPT_MBFONT_BOLD].string,
+					mbfont_opts[OPT_MBFONT_BOLD].strlen))
+		return FALSE;
+	if (mbfont_opts[OPT_MBFONT_OBLIQUE].present)
+	    if (!prt_build_cid_fontname(PRT_PS_FONT_OBLIQUE,
+					mbfont_opts[OPT_MBFONT_OBLIQUE].string,
+					mbfont_opts[OPT_MBFONT_OBLIQUE].strlen))
+		return FALSE;
+	if (mbfont_opts[OPT_MBFONT_BOLDOBLIQUE].present)
+	    if (!prt_build_cid_fontname(PRT_PS_FONT_BOLDOBLIQUE,
+				   mbfont_opts[OPT_MBFONT_BOLDOBLIQUE].string,
+				  mbfont_opts[OPT_MBFONT_BOLDOBLIQUE].strlen))
+		return FALSE;
+
+	/* Check if need to use Courier for ASCII code range, and if so pick up
+	 * the encoding to use */
+	prt_use_courier = mbfont_opts[OPT_MBFONT_USECOURIER].present &&
+	    (TOLOWER_ASC(mbfont_opts[OPT_MBFONT_USECOURIER].string[0]) == 'y');
+	if (prt_use_courier)
+	{
+	    /* Use national ASCII variant unless ASCII wanted */
+	    if (mbfont_opts[OPT_MBFONT_ASCII].present &&
+		(TOLOWER_ASC(mbfont_opts[OPT_MBFONT_ASCII].string[0]) == 'y'))
+		prt_ascii_encoding = "ascii";
+	    else
+		prt_ascii_encoding = prt_ps_mbfonts[cmap].ascii_enc;
+	}
+
+	prt_ps_font = &prt_ps_mb_font;
+    }
+    else
+#endif
+    {
+#ifdef FEAT_MBYTE
+	prt_use_courier = FALSE;
+#endif
+	prt_ps_font = &prt_ps_courier_font;
+    }
+
+    /*
+     * Find the size of the paper and set the margins.
+     */
+    prt_portrait = (!printer_opts[OPT_PRINT_PORTRAIT].present
+	   || TOLOWER_ASC(printer_opts[OPT_PRINT_PORTRAIT].string[0]) == 'y');
+    if (printer_opts[OPT_PRINT_PAPER].present)
+    {
+	paper_name = (char *)printer_opts[OPT_PRINT_PAPER].string;
+	paper_strlen = printer_opts[OPT_PRINT_PAPER].strlen;
+    }
+    else
+    {
+	paper_name = "A4";
+	paper_strlen = 2;
+    }
+    for (i = 0; i < PRT_MEDIASIZE_LEN; ++i)
+	if (STRLEN(prt_mediasize[i].name) == (unsigned)paper_strlen
+		&& STRNICMP(prt_mediasize[i].name, paper_name,
+							   paper_strlen) == 0)
+	    break;
+    if (i == PRT_MEDIASIZE_LEN)
+	i = 0;
+    prt_media = i;
+
+    /*
+     * Set PS pagesize based on media dimensions and print orientation.
+     * Note: Media and page sizes have defined meanings in PostScript and should
+     * be kept distinct.  Media is the paper (or transparency, or ...) that is
+     * printed on, whereas the page size is the area that the PostScript
+     * interpreter renders into.
+     */
+    if (prt_portrait)
+    {
+	prt_page_width = prt_mediasize[i].width;
+	prt_page_height = prt_mediasize[i].height;
+    }
+    else
+    {
+	prt_page_width = prt_mediasize[i].height;
+	prt_page_height = prt_mediasize[i].width;
+    }
+
+    /*
+     * Set PS page margins based on the PS pagesize, not the mediasize - this
+     * needs to be done before the cpl and lpp are calculated.
+     */
+    prt_page_margins(prt_page_width, prt_page_height, &left, &right, &top,
+								    &bottom);
+    prt_left_margin = (float)left;
+    prt_right_margin = (float)right;
+    prt_top_margin = (float)top;
+    prt_bottom_margin = (float)bottom;
+
+    /*
+     * Set up the font size.
+     */
+    fontsize = PRT_PS_DEFAULT_FONTSIZE;
+    for (p = p_pfn; (p = vim_strchr(p, ':')) != NULL; ++p)
+	if (p[1] == 'h' && VIM_ISDIGIT(p[2]))
+	    fontsize = atoi((char *)p + 2);
+    prt_font_metrics(fontsize);
+
+    /*
+     * Return the number of characters per line, and lines per page for the
+     * generic print code.
+     */
+    psettings->chars_per_line = prt_get_cpl();
+    psettings->lines_per_page = prt_get_lpp();
+
+    /* Catch margin settings that leave no space for output! */
+    if (psettings->chars_per_line <= 0 || psettings->lines_per_page <= 0)
+	return FAIL;
+
+    /*
+     * Sort out the number of copies to be printed.  PS by default will do
+     * uncollated copies for you, so once we know how many uncollated copies are
+     * wanted cache it away and lie to the generic code that we only want one
+     * uncollated copy.
+     */
+    psettings->n_collated_copies = 1;
+    psettings->n_uncollated_copies = 1;
+    prt_num_copies = 1;
+    prt_collate = (!printer_opts[OPT_PRINT_COLLATE].present
+	    || TOLOWER_ASC(printer_opts[OPT_PRINT_COLLATE].string[0]) == 'y');
+    if (prt_collate)
+    {
+	/* TODO: Get number of collated copies wanted. */
+	psettings->n_collated_copies = 1;
+    }
+    else
+    {
+	/* TODO: Get number of uncollated copies wanted and update the cached
+	 * count.
+	 */
+	prt_num_copies = 1;
+    }
+
+    psettings->jobname = jobname;
+
+    /*
+     * Set up printer duplex and tumble based on Duplex option setting - default
+     * is long sided duplex printing (i.e. no tumble).
+     */
+    prt_duplex = TRUE;
+    prt_tumble = FALSE;
+    psettings->duplex = 1;
+    if (printer_opts[OPT_PRINT_DUPLEX].present)
+    {
+	if (STRNICMP(printer_opts[OPT_PRINT_DUPLEX].string, "off", 3) == 0)
+	{
+	    prt_duplex = FALSE;
+	    psettings->duplex = 0;
+	}
+	else if (STRNICMP(printer_opts[OPT_PRINT_DUPLEX].string, "short", 5)
+									 == 0)
+	    prt_tumble = TRUE;
+    }
+
+    /* For now user abort not supported */
+    psettings->user_abort = 0;
+
+    /* If the user didn't specify a file name, use a temp file. */
+    if (psettings->outfile == NULL)
+    {
+	prt_ps_file_name = vim_tempname('p');
+	if (prt_ps_file_name == NULL)
+	{
+	    EMSG(_(e_notmp));
+	    return FAIL;
+	}
+	prt_ps_fd = mch_fopen((char *)prt_ps_file_name, WRITEBIN);
+    }
+    else
+    {
+	p = expand_env_save(psettings->outfile);
+	if (p != NULL)
+	{
+	    prt_ps_fd = mch_fopen((char *)p, WRITEBIN);
+	    vim_free(p);
+	}
+    }
+    if (prt_ps_fd == NULL)
+    {
+	EMSG(_("E324: Can't open PostScript output file"));
+	mch_print_cleanup();
+	return FAIL;
+    }
+
+    prt_bufsiz = psettings->chars_per_line;
+#ifdef FEAT_MBYTE
+    if (prt_out_mbyte)
+	prt_bufsiz *= 2;
+#endif
+    ga_init2(&prt_ps_buffer, (int)sizeof(char), prt_bufsiz);
+
+    prt_page_num = 0;
+
+    prt_attribute_change = FALSE;
+    prt_need_moveto = FALSE;
+    prt_need_font = FALSE;
+    prt_need_fgcol = FALSE;
+    prt_need_bgcol = FALSE;
+    prt_need_underline = FALSE;
+
+    prt_file_error = FALSE;
+
+    return OK;
+}
+
+    static int
+prt_add_resource(resource)
+    struct prt_ps_resource_S *resource;
+{
+    FILE*	fd_resource;
+    char_u	resource_buffer[512];
+    size_t	bytes_read;
+
+    fd_resource = mch_fopen((char *)resource->filename, READBIN);
+    if (fd_resource == NULL)
+    {
+	EMSG2(_("E456: Can't open file \"%s\""), resource->filename);
+	return FALSE;
+    }
+    prt_dsc_resources("BeginResource", prt_resource_types[resource->type],
+						     (char *)resource->title);
+
+    prt_dsc_textline("BeginDocument", (char *)resource->filename);
+
+    for (;;)
+    {
+	bytes_read = fread((char *)resource_buffer, sizeof(char_u),
+			   sizeof(resource_buffer), fd_resource);
+	if (ferror(fd_resource))
+	{
+	    EMSG2(_("E457: Can't read PostScript resource file \"%s\""),
+							    resource->filename);
+	    fclose(fd_resource);
+	    return FALSE;
+	}
+	if (bytes_read == 0)
+	    break;
+	prt_write_file_raw_len(resource_buffer, (int)bytes_read);
+	if (prt_file_error)
+	{
+	    fclose(fd_resource);
+	    return FALSE;
+	}
+    }
+    fclose(fd_resource);
+
+    prt_dsc_noarg("EndDocument");
+
+    prt_dsc_noarg("EndResource");
+
+    return TRUE;
+}
+
+    int
+mch_print_begin(psettings)
+    prt_settings_T *psettings;
+{
+    time_t	now;
+    int		bbox[4];
+    char	*p_time;
+    double      left;
+    double      right;
+    double      top;
+    double      bottom;
+    struct prt_ps_resource_S res_prolog;
+    struct prt_ps_resource_S res_encoding;
+    char	buffer[256];
+    char_u      *p_encoding;
+    char_u	*p;
+#ifdef FEAT_MBYTE
+    struct prt_ps_resource_S res_cidfont;
+    struct prt_ps_resource_S res_cmap;
+#endif
+
+    /*
+     * PS DSC Header comments - no PS code!
+     */
+    prt_dsc_start();
+    prt_dsc_textline("Title", (char *)psettings->jobname);
+    if (!get_user_name((char_u *)buffer, 256))
+	STRCPY(buffer, "Unknown");
+    prt_dsc_textline("For", buffer);
+    prt_dsc_textline("Creator", VIM_VERSION_LONG);
+    /* Note: to ensure Clean8bit I don't think we can use LC_TIME */
+    now = time(NULL);
+    p_time = ctime(&now);
+    /* Note: ctime() adds a \n so we have to remove it :-( */
+    p = vim_strchr((char_u *)p_time, '\n');
+    if (p != NULL)
+	*p = NUL;
+    prt_dsc_textline("CreationDate", p_time);
+    prt_dsc_textline("DocumentData", "Clean8Bit");
+    prt_dsc_textline("Orientation", "Portrait");
+    prt_dsc_atend("Pages");
+    prt_dsc_textline("PageOrder", "Ascend");
+    /* The bbox does not change with orientation - it is always in the default
+     * user coordinate system!  We have to recalculate right and bottom
+     * coordinates based on the font metrics for the bbox to be accurate. */
+    prt_page_margins(prt_mediasize[prt_media].width,
+					    prt_mediasize[prt_media].height,
+					    &left, &right, &top, &bottom);
+    bbox[0] = (int)left;
+    if (prt_portrait)
+    {
+	/* In portrait printing the fixed point is the top left corner so we
+	 * derive the bbox from that point.  We have the expected cpl chars
+	 * across the media and lpp lines down the media.
+	 */
+	bbox[1] = (int)(top - (psettings->lines_per_page + prt_header_height())
+							    * prt_line_height);
+	bbox[2] = (int)(left + psettings->chars_per_line * prt_char_width
+									+ 0.5);
+	bbox[3] = (int)(top + 0.5);
+    }
+    else
+    {
+	/* In landscape printing the fixed point is the bottom left corner so we
+	 * derive the bbox from that point.  We have lpp chars across the media
+	 * and cpl lines up the media.
+	 */
+	bbox[1] = (int)bottom;
+	bbox[2] = (int)(left + ((psettings->lines_per_page
+			      + prt_header_height()) * prt_line_height) + 0.5);
+	bbox[3] = (int)(bottom + psettings->chars_per_line * prt_char_width
+									+ 0.5);
+    }
+    prt_dsc_ints("BoundingBox", 4, bbox);
+    /* The media width and height does not change with landscape printing! */
+    prt_dsc_docmedia(prt_mediasize[prt_media].name,
+				prt_mediasize[prt_media].width,
+				prt_mediasize[prt_media].height,
+				(double)0, NULL, NULL);
+    /* Define fonts needed */
+#ifdef FEAT_MBYTE
+    if (!prt_out_mbyte || prt_use_courier)
+#endif
+	prt_dsc_font_resource("DocumentNeededResources", &prt_ps_courier_font);
+#ifdef FEAT_MBYTE
+    if (prt_out_mbyte)
+    {
+	prt_dsc_font_resource((prt_use_courier ? NULL
+				 : "DocumentNeededResources"), &prt_ps_mb_font);
+	if (!prt_custom_cmap)
+	    prt_dsc_resources(NULL, "cmap", prt_cmap);
+    }
+#endif
+
+    /* Search for external resources VIM supplies */
+    if (!prt_find_resource("prolog", &res_prolog))
+    {
+	EMSG(_("E456: Can't find PostScript resource file \"prolog.ps\""));
+	return FALSE;
+    }
+    if (!prt_open_resource(&res_prolog))
+	return FALSE;
+    if (!prt_check_resource(&res_prolog, PRT_PROLOG_VERSION))
+	return FALSE;
+#ifdef FEAT_MBYTE
+    if (prt_out_mbyte)
+    {
+	/* Look for required version of multi-byte printing procset */
+	if (!prt_find_resource("cidfont", &res_cidfont))
+	{
+	    EMSG(_("E456: Can't find PostScript resource file \"cidfont.ps\""));
+	    return FALSE;
+	}
+	if (!prt_open_resource(&res_cidfont))
+	    return FALSE;
+	if (!prt_check_resource(&res_cidfont, PRT_CID_PROLOG_VERSION))
+	    return FALSE;
+    }
+#endif
+
+    /* Find an encoding to use for printing.
+     * Check 'printencoding'. If not set or not found, then use 'encoding'. If
+     * that cannot be found then default to "latin1".
+     * Note: VIM specific encoding header is always skipped.
+     */
+#ifdef FEAT_MBYTE
+    if (!prt_out_mbyte)
+    {
+#endif
+	p_encoding = enc_skip(p_penc);
+	if (*p_encoding == NUL
+		|| !prt_find_resource((char *)p_encoding, &res_encoding))
+	{
+	    /* 'printencoding' not set or not supported - find alternate */
+#ifdef FEAT_MBYTE
+	    int		props;
+
+	    p_encoding = enc_skip(p_enc);
+	    props = enc_canon_props(p_encoding);
+	    if (!(props & ENC_8BIT)
+		    || !prt_find_resource((char *)p_encoding, &res_encoding))
+		/* 8-bit 'encoding' is not supported */
+#endif
+		{
+		/* Use latin1 as default printing encoding */
+		p_encoding = (char_u *)"latin1";
+		if (!prt_find_resource((char *)p_encoding, &res_encoding))
+		{
+		    EMSG2(_("E456: Can't find PostScript resource file \"%s.ps\""),
+			    p_encoding);
+		    return FALSE;
+		}
+	    }
+	}
+	if (!prt_open_resource(&res_encoding))
+	    return FALSE;
+	/* For the moment there are no checks on encoding resource files to
+	 * perform */
+#ifdef FEAT_MBYTE
+    }
+    else
+    {
+	p_encoding = enc_skip(p_penc);
+	if (*p_encoding == NUL)
+	    p_encoding = enc_skip(p_enc);
+	if (prt_use_courier)
+	{
+	    /* Include ASCII range encoding vector */
+	    if (!prt_find_resource(prt_ascii_encoding, &res_encoding))
+	    {
+		EMSG2(_("E456: Can't find PostScript resource file \"%s.ps\""),
+							  prt_ascii_encoding);
+		return FALSE;
+	    }
+	    if (!prt_open_resource(&res_encoding))
+		return FALSE;
+	    /* For the moment there are no checks on encoding resource files to
+	     * perform */
+	}
+    }
+
+    prt_conv.vc_type = CONV_NONE;
+    if (!(enc_canon_props(p_enc) & enc_canon_props(p_encoding) & ENC_8BIT)) {
+	/* Set up encoding conversion if required */
+	if (FAIL == convert_setup(&prt_conv, p_enc, p_encoding))
+	{
+	    EMSG2(_("E620: Unable to convert to print encoding \"%s\""),
+		    p_encoding);
+	    return FALSE;
+	}
+	prt_do_conv = TRUE;
+    }
+    prt_do_conv = prt_conv.vc_type != CONV_NONE;
+
+    if (prt_out_mbyte && prt_custom_cmap)
+    {
+	/* Find user supplied CMap */
+	if (!prt_find_resource(prt_cmap, &res_cmap))
+	{
+	    EMSG2(_("E456: Can't find PostScript resource file \"%s.ps\""),
+								    prt_cmap);
+	    return FALSE;
+	}
+	if (!prt_open_resource(&res_cmap))
+	    return FALSE;
+    }
+#endif
+
+    /* List resources supplied */
+    STRCPY(buffer, res_prolog.title);
+    STRCAT(buffer, " ");
+    STRCAT(buffer, res_prolog.version);
+    prt_dsc_resources("DocumentSuppliedResources", "procset", buffer);
+#ifdef FEAT_MBYTE
+    if (prt_out_mbyte)
+    {
+	STRCPY(buffer, res_cidfont.title);
+	STRCAT(buffer, " ");
+	STRCAT(buffer, res_cidfont.version);
+	prt_dsc_resources(NULL, "procset", buffer);
+
+	if (prt_custom_cmap)
+	{
+	    STRCPY(buffer, res_cmap.title);
+	    STRCAT(buffer, " ");
+	    STRCAT(buffer, res_cmap.version);
+	    prt_dsc_resources(NULL, "cmap", buffer);
+	}
+    }
+    if (!prt_out_mbyte || prt_use_courier)
+#endif
+    {
+	STRCPY(buffer, res_encoding.title);
+	STRCAT(buffer, " ");
+	STRCAT(buffer, res_encoding.version);
+	prt_dsc_resources(NULL, "encoding", buffer);
+    }
+    prt_dsc_requirements(prt_duplex, prt_tumble, prt_collate,
+#ifdef FEAT_SYN_HL
+					psettings->do_syntax
+#else
+					0
+#endif
+					, prt_num_copies);
+    prt_dsc_noarg("EndComments");
+
+    /*
+     * PS Document page defaults
+     */
+    prt_dsc_noarg("BeginDefaults");
+
+    /* List font resources most likely common to all pages */
+#ifdef FEAT_MBYTE
+    if (!prt_out_mbyte || prt_use_courier)
+#endif
+	prt_dsc_font_resource("PageResources", &prt_ps_courier_font);
+#ifdef FEAT_MBYTE
+    if (prt_out_mbyte)
+    {
+	prt_dsc_font_resource((prt_use_courier ? NULL : "PageResources"),
+							    &prt_ps_mb_font);
+	if (!prt_custom_cmap)
+	    prt_dsc_resources(NULL, "cmap", prt_cmap);
+    }
+#endif
+
+    /* Paper will be used for all pages */
+    prt_dsc_textline("PageMedia", prt_mediasize[prt_media].name);
+
+    prt_dsc_noarg("EndDefaults");
+
+    /*
+     * PS Document prolog inclusion - all required procsets.
+     */
+    prt_dsc_noarg("BeginProlog");
+
+    /* Add required procsets - NOTE: order is important! */
+    if (!prt_add_resource(&res_prolog))
+	return FALSE;
+#ifdef FEAT_MBYTE
+    if (prt_out_mbyte)
+    {
+	/* Add CID font procset, and any user supplied CMap */
+	if (!prt_add_resource(&res_cidfont))
+	    return FALSE;
+	if (prt_custom_cmap && !prt_add_resource(&res_cmap))
+	    return FALSE;
+    }
+#endif
+
+#ifdef FEAT_MBYTE
+    if (!prt_out_mbyte || prt_use_courier)
+#endif
+	/* There will be only one Roman font encoding to be included in the PS
+	 * file. */
+	if (!prt_add_resource(&res_encoding))
+	    return FALSE;
+
+    prt_dsc_noarg("EndProlog");
+
+    /*
+     * PS Document setup - must appear after the prolog
+     */
+    prt_dsc_noarg("BeginSetup");
+
+    /* Device setup - page size and number of uncollated copies */
+    prt_write_int((int)prt_mediasize[prt_media].width);
+    prt_write_int((int)prt_mediasize[prt_media].height);
+    prt_write_int(0);
+    prt_write_string("sps\n");
+    prt_write_int(prt_num_copies);
+    prt_write_string("nc\n");
+    prt_write_boolean(prt_duplex);
+    prt_write_boolean(prt_tumble);
+    prt_write_string("dt\n");
+    prt_write_boolean(prt_collate);
+    prt_write_string("c\n");
+
+    /* Font resource inclusion and definition */
+#ifdef FEAT_MBYTE
+    if (!prt_out_mbyte || prt_use_courier)
+    {
+	/* When using Courier for ASCII range when printing multi-byte, need to
+	 * pick up ASCII encoding to use with it. */
+	if (prt_use_courier)
+	    p_encoding = (char_u *)prt_ascii_encoding;
+#endif
+	prt_dsc_resources("IncludeResource", "font",
+			  prt_ps_courier_font.ps_fontname[PRT_PS_FONT_ROMAN]);
+	prt_def_font("F0", (char *)p_encoding, (int)prt_line_height,
+		     prt_ps_courier_font.ps_fontname[PRT_PS_FONT_ROMAN]);
+	prt_dsc_resources("IncludeResource", "font",
+			  prt_ps_courier_font.ps_fontname[PRT_PS_FONT_BOLD]);
+	prt_def_font("F1", (char *)p_encoding, (int)prt_line_height,
+		     prt_ps_courier_font.ps_fontname[PRT_PS_FONT_BOLD]);
+	prt_dsc_resources("IncludeResource", "font",
+			  prt_ps_courier_font.ps_fontname[PRT_PS_FONT_OBLIQUE]);
+	prt_def_font("F2", (char *)p_encoding, (int)prt_line_height,
+		     prt_ps_courier_font.ps_fontname[PRT_PS_FONT_OBLIQUE]);
+	prt_dsc_resources("IncludeResource", "font",
+			  prt_ps_courier_font.ps_fontname[PRT_PS_FONT_BOLDOBLIQUE]);
+	prt_def_font("F3", (char *)p_encoding, (int)prt_line_height,
+		     prt_ps_courier_font.ps_fontname[PRT_PS_FONT_BOLDOBLIQUE]);
+#ifdef FEAT_MBYTE
+    }
+    if (prt_out_mbyte)
+    {
+	/* Define the CID fonts to be used in the job.	Typically CJKV fonts do
+	 * not have an italic form being a western style, so where no font is
+	 * defined for these faces VIM falls back to an existing face.
+	 * Note: if using Courier for the ASCII range then the printout will
+	 * have bold/italic/bolditalic regardless of the setting of printmbfont.
+	 */
+	prt_dsc_resources("IncludeResource", "font",
+			  prt_ps_mb_font.ps_fontname[PRT_PS_FONT_ROMAN]);
+	if (!prt_custom_cmap)
+	    prt_dsc_resources("IncludeResource", "cmap", prt_cmap);
+	prt_def_cidfont("CF0", (int)prt_line_height,
+			prt_ps_mb_font.ps_fontname[PRT_PS_FONT_ROMAN]);
+
+	if (prt_ps_mb_font.ps_fontname[PRT_PS_FONT_BOLD] != NULL)
+	{
+	    prt_dsc_resources("IncludeResource", "font",
+			      prt_ps_mb_font.ps_fontname[PRT_PS_FONT_BOLD]);
+	    if (!prt_custom_cmap)
+		prt_dsc_resources("IncludeResource", "cmap", prt_cmap);
+	    prt_def_cidfont("CF1", (int)prt_line_height,
+			    prt_ps_mb_font.ps_fontname[PRT_PS_FONT_BOLD]);
+	}
+	else
+	    /* Use ROMAN for BOLD */
+	    prt_dup_cidfont("CF0", "CF1");
+
+	if (prt_ps_mb_font.ps_fontname[PRT_PS_FONT_OBLIQUE] != NULL)
+	{
+	    prt_dsc_resources("IncludeResource", "font",
+			      prt_ps_mb_font.ps_fontname[PRT_PS_FONT_OBLIQUE]);
+	    if (!prt_custom_cmap)
+		prt_dsc_resources("IncludeResource", "cmap", prt_cmap);
+	    prt_def_cidfont("CF2", (int)prt_line_height,
+			    prt_ps_mb_font.ps_fontname[PRT_PS_FONT_OBLIQUE]);
+	}
+	else
+	    /* Use ROMAN for OBLIQUE */
+	    prt_dup_cidfont("CF0", "CF2");
+
+	if (prt_ps_mb_font.ps_fontname[PRT_PS_FONT_BOLDOBLIQUE] != NULL)
+	{
+	    prt_dsc_resources("IncludeResource", "font",
+			      prt_ps_mb_font.ps_fontname[PRT_PS_FONT_BOLDOBLIQUE]);
+	    if (!prt_custom_cmap)
+		prt_dsc_resources("IncludeResource", "cmap", prt_cmap);
+	    prt_def_cidfont("CF3", (int)prt_line_height,
+			    prt_ps_mb_font.ps_fontname[PRT_PS_FONT_BOLDOBLIQUE]);
+	}
+	else
+	    /* Use BOLD for BOLDOBLIQUE */
+	    prt_dup_cidfont("CF1", "CF3");
+    }
+#endif
+
+    /* Misc constant vars used for underlining and background rects */
+    prt_def_var("UO", PRT_PS_FONT_TO_USER(prt_line_height,
+						prt_ps_font->uline_offset), 2);
+    prt_def_var("UW", PRT_PS_FONT_TO_USER(prt_line_height,
+						 prt_ps_font->uline_width), 2);
+    prt_def_var("BO", prt_bgcol_offset, 2);
+
+    prt_dsc_noarg("EndSetup");
+
+    /* Fail if any problems writing out to the PS file */
+    return !prt_file_error;
+}
+
+    void
+mch_print_end(psettings)
+    prt_settings_T *psettings;
+{
+    prt_dsc_noarg("Trailer");
+
+    /*
+     * Output any info we don't know in toto until we finish
+     */
+    prt_dsc_ints("Pages", 1, &prt_page_num);
+
+    prt_dsc_noarg("EOF");
+
+    /* Write CTRL-D to close serial communication link if used.
+     * NOTHING MUST BE WRITTEN AFTER THIS! */
+    prt_write_file((char_u *)IF_EB("\004", "\067"));
+
+    if (!prt_file_error && psettings->outfile == NULL
+					&& !got_int && !psettings->user_abort)
+    {
+	/* Close the file first. */
+	if (prt_ps_fd != NULL)
+	{
+	    fclose(prt_ps_fd);
+	    prt_ps_fd = NULL;
+	}
+	prt_message((char_u *)_("Sending to printer..."));
+
+	/* Not printing to a file: use 'printexpr' to print the file. */
+	if (eval_printexpr(prt_ps_file_name, psettings->arguments) == FAIL)
+	    EMSG(_("E365: Failed to print PostScript file"));
+	else
+	    prt_message((char_u *)_("Print job sent."));
+    }
+
+    mch_print_cleanup();
+}
+
+    int
+mch_print_end_page()
+{
+    prt_flush_buffer();
+
+    prt_write_string("re sp\n");
+
+    prt_dsc_noarg("PageTrailer");
+
+    return !prt_file_error;
+}
+
+/*ARGSUSED*/
+    int
+mch_print_begin_page(str)
+    char_u	*str;
+{
+    int		page_num[2];
+
+    prt_page_num++;
+
+    page_num[0] = page_num[1] = prt_page_num;
+    prt_dsc_ints("Page", 2, page_num);
+
+    prt_dsc_noarg("BeginPageSetup");
+
+    prt_write_string("sv\n0 g\n");
+#ifdef FEAT_MBYTE
+    prt_in_ascii = !prt_out_mbyte;
+    if (prt_out_mbyte)
+	prt_write_string("CF0 sf\n");
+    else
+#endif
+	prt_write_string("F0 sf\n");
+    prt_fgcol = PRCOLOR_BLACK;
+    prt_bgcol = PRCOLOR_WHITE;
+    prt_font = PRT_PS_FONT_ROMAN;
+
+    /* Set up page transformation for landscape printing. */
+    if (!prt_portrait)
+    {
+	prt_write_int(-((int)prt_mediasize[prt_media].width));
+	prt_write_string("sl\n");
+    }
+
+    prt_dsc_noarg("EndPageSetup");
+
+    /* We have reset the font attributes, force setting them again. */
+    curr_bg = (long_u)0xffffffff;
+    curr_fg = (long_u)0xffffffff;
+    curr_bold = MAYBE;
+
+    return !prt_file_error;
+}
+
+    int
+mch_print_blank_page()
+{
+    return (mch_print_begin_page(NULL) ? (mch_print_end_page()) : FALSE);
+}
+
+static float prt_pos_x = 0;
+static float prt_pos_y = 0;
+
+    void
+mch_print_start_line(margin, page_line)
+    int		margin;
+    int		page_line;
+{
+    prt_pos_x = prt_left_margin;
+    if (margin)
+	prt_pos_x -= prt_number_width;
+
+    prt_pos_y = prt_top_margin - prt_first_line_height -
+					page_line * prt_line_height;
+
+    prt_attribute_change = TRUE;
+    prt_need_moveto = TRUE;
+#ifdef FEAT_MBYTE
+    prt_half_width = FALSE;
+#endif
+}
+
+/*ARGSUSED*/
+    int
+mch_print_text_out(p, len)
+    char_u	*p;
+    int		len;
+{
+    int		need_break;
+    char_u	ch;
+    char_u      ch_buff[8];
+    float       char_width;
+    float       next_pos;
+#ifdef FEAT_MBYTE
+    int		in_ascii;
+    int		half_width;
+#endif
+
+    char_width = prt_char_width;
+
+#ifdef FEAT_MBYTE
+    /* Ideally VIM would create a rearranged CID font to combine a Roman and
+     * CJKV font to do what VIM is doing here - use a Roman font for characters
+     * in the ASCII range, and the original CID font for everything else.
+     * The problem is that GhostScript still (as of 8.13) does not support
+     * rearranged fonts even though they have been documented by Adobe for 7
+     * years!  If they ever do, a lot of this code will disappear.
+     */
+    if (prt_use_courier)
+    {
+	in_ascii = (len == 1 && *p < 0x80);
+	if (prt_in_ascii)
+	{
+	    if (!in_ascii)
+	    {
+		/* No longer in ASCII range - need to switch font */
+		prt_in_ascii = FALSE;
+		prt_need_font = TRUE;
+		prt_attribute_change = TRUE;
+	    }
+	}
+	else if (in_ascii)
+	{
+	    /* Now in ASCII range - need to switch font */
+	    prt_in_ascii = TRUE;
+	    prt_need_font = TRUE;
+	    prt_attribute_change = TRUE;
+	}
+    }
+    if (prt_out_mbyte)
+    {
+	half_width = ((*mb_ptr2cells)(p) == 1);
+	if (half_width)
+	    char_width /= 2;
+	if (prt_half_width)
+	{
+	    if (!half_width)
+	    {
+		prt_half_width = FALSE;
+		prt_pos_x += prt_char_width/4;
+		prt_need_moveto = TRUE;
+		prt_attribute_change = TRUE;
+	    }
+	}
+	else if (half_width)
+	{
+	    prt_half_width = TRUE;
+	    prt_pos_x += prt_char_width/4;
+	    prt_need_moveto = TRUE;
+	    prt_attribute_change = TRUE;
+	}
+    }
+#endif
+
+    /* Output any required changes to the graphics state, after flushing any
+     * text buffered so far.
+     */
+    if (prt_attribute_change)
+    {
+	prt_flush_buffer();
+	/* Reset count of number of chars that will be printed */
+	prt_text_run = 0;
+
+	if (prt_need_moveto)
+	{
+	    prt_pos_x_moveto = prt_pos_x;
+	    prt_pos_y_moveto = prt_pos_y;
+	    prt_do_moveto = TRUE;
+
+	    prt_need_moveto = FALSE;
+	}
+	if (prt_need_font)
+	{
+#ifdef FEAT_MBYTE
+	    if (!prt_in_ascii)
+		prt_write_string("CF");
+	    else
+#endif
+		prt_write_string("F");
+	    prt_write_int(prt_font);
+	    prt_write_string("sf\n");
+	    prt_need_font = FALSE;
+	}
+	if (prt_need_fgcol)
+	{
+	    int     r, g, b;
+	    r = ((unsigned)prt_fgcol & 0xff0000) >> 16;
+	    g = ((unsigned)prt_fgcol & 0xff00) >> 8;
+	    b = prt_fgcol & 0xff;
+
+	    prt_write_real(r / 255.0, 3);
+	    if (r == g && g == b)
+		prt_write_string("g\n");
+	    else
+	    {
+		prt_write_real(g / 255.0, 3);
+		prt_write_real(b / 255.0, 3);
+		prt_write_string("r\n");
+	    }
+	    prt_need_fgcol = FALSE;
+	}
+
+	if (prt_bgcol != PRCOLOR_WHITE)
+	{
+	    prt_new_bgcol = prt_bgcol;
+	    if (prt_need_bgcol)
+		prt_do_bgcol = TRUE;
+	}
+	else
+	    prt_do_bgcol = FALSE;
+	prt_need_bgcol = FALSE;
+
+	if (prt_need_underline)
+	    prt_do_underline = prt_underline;
+	prt_need_underline = FALSE;
+
+	prt_attribute_change = FALSE;
+    }
+
+#ifdef FEAT_MBYTE
+    if (prt_do_conv)
+    {
+	/* Convert from multi-byte to 8-bit encoding */
+	p = string_convert(&prt_conv, p, &len);
+	if (p == NULL)
+	    p = (char_u *)"";
+    }
+
+    if (prt_out_mbyte)
+    {
+	/* Multi-byte character strings are represented more efficiently as hex
+	 * strings when outputting clean 8 bit PS.
+	 */
+	do
+	{
+	    ch = prt_hexchar[(unsigned)(*p) >> 4];
+	    ga_append(&prt_ps_buffer, ch);
+	    ch = prt_hexchar[(*p) & 0xf];
+	    ga_append(&prt_ps_buffer, ch);
+	    p++;
+	}
+	while (--len);
+    }
+    else
+#endif
+    {
+	/* Add next character to buffer of characters to output.
+	 * Note: One printed character may require several PS characters to
+	 * represent it, but we only count them as one printed character.
+	 */
+	ch = *p;
+	if (ch < 32 || ch == '(' || ch == ')' || ch == '\\')
+	{
+	    /* Convert non-printing characters to either their escape or octal
+	     * sequence, ensures PS sent over a serial line does not interfere
+	     * with the comms protocol.  Note: For EBCDIC we need to write out
+	     * the escape sequences as ASCII codes!
+	     * Note 2: Char codes < 32 are identical in EBCDIC and ASCII AFAIK!
+	     */
+	    ga_append(&prt_ps_buffer, IF_EB('\\', 0134));
+	    switch (ch)
+	    {
+		case BS:   ga_append(&prt_ps_buffer, IF_EB('b', 0142)); break;
+		case TAB:  ga_append(&prt_ps_buffer, IF_EB('t', 0164)); break;
+		case NL:   ga_append(&prt_ps_buffer, IF_EB('n', 0156)); break;
+		case FF:   ga_append(&prt_ps_buffer, IF_EB('f', 0146)); break;
+		case CAR:  ga_append(&prt_ps_buffer, IF_EB('r', 0162)); break;
+		case '(':  ga_append(&prt_ps_buffer, IF_EB('(', 0050)); break;
+		case ')':  ga_append(&prt_ps_buffer, IF_EB(')', 0051)); break;
+		case '\\': ga_append(&prt_ps_buffer, IF_EB('\\', 0134)); break;
+
+		default:
+			   sprintf((char *)ch_buff, "%03o", (unsigned int)ch);
+#ifdef EBCDIC
+			   ebcdic2ascii(ch_buff, 3);
+#endif
+			   ga_append(&prt_ps_buffer, ch_buff[0]);
+			   ga_append(&prt_ps_buffer, ch_buff[1]);
+			   ga_append(&prt_ps_buffer, ch_buff[2]);
+			   break;
+	    }
+	}
+	else
+	    ga_append(&prt_ps_buffer, ch);
+    }
+
+#ifdef FEAT_MBYTE
+    /* Need to free any translated characters */
+    if (prt_do_conv && (*p != NUL))
+	vim_free(p);
+#endif
+
+    prt_text_run += char_width;
+    prt_pos_x += char_width;
+
+    /* The downside of fp - use relative error on right margin check */
+    next_pos = prt_pos_x + prt_char_width;
+    need_break = (next_pos > prt_right_margin) &&
+		    ((next_pos - prt_right_margin) > (prt_right_margin*1e-5));
+
+    if (need_break)
+	prt_flush_buffer();
+
+    return need_break;
+}
+
+    void
+mch_print_set_font(iBold, iItalic, iUnderline)
+    int		iBold;
+    int		iItalic;
+    int		iUnderline;
+{
+    int		font = 0;
+
+    if (iBold)
+	font |= 0x01;
+    if (iItalic)
+	font |= 0x02;
+
+    if (font != prt_font)
+    {
+	prt_font = font;
+	prt_attribute_change = TRUE;
+	prt_need_font = TRUE;
+    }
+    if (prt_underline != iUnderline)
+    {
+	prt_underline = iUnderline;
+	prt_attribute_change = TRUE;
+	prt_need_underline = TRUE;
+    }
+}
+
+    void
+mch_print_set_bg(bgcol)
+    long_u	bgcol;
+{
+    prt_bgcol = (int)bgcol;
+    prt_attribute_change = TRUE;
+    prt_need_bgcol = TRUE;
+}
+
+    void
+mch_print_set_fg(fgcol)
+    long_u	fgcol;
+{
+    if (fgcol != (long_u)prt_fgcol)
+    {
+	prt_fgcol = (int)fgcol;
+	prt_attribute_change = TRUE;
+	prt_need_fgcol = TRUE;
+    }
+}
+
+# endif /*FEAT_POSTSCRIPT*/
+#endif /*FEAT_PRINTER*/
--- /dev/null
+++ b/hashtab.c
@@ -1,0 +1,518 @@
+/* vi:set ts=8 sts=4 sw=4:
+ *
+ * VIM - Vi IMproved	by Bram Moolenaar
+ *
+ * Do ":help uganda"  in Vim to read copying and usage conditions.
+ * Do ":help credits" in Vim to see a list of people who contributed.
+ * See README.txt for an overview of the Vim source code.
+ */
+
+/*
+ * hashtab.c: Handling of a hashtable with Vim-specific properties.
+ *
+ * Each item in a hashtable has a NUL terminated string key.  A key can appear
+ * only once in the table.
+ *
+ * A hash number is computed from the key for quick lookup.  When the hashes
+ * of two different keys point to the same entry an algorithm is used to
+ * iterate over other entries in the table until the right one is found.
+ * To make the iteration work removed keys are different from entries where a
+ * key was never present.
+ *
+ * The mechanism has been partly based on how Python Dictionaries are
+ * implemented.  The algorithm is from Knuth Vol. 3, Sec. 6.4.
+ *
+ * The hashtable grows to accommodate more entries when needed.  At least 1/3
+ * of the entries is empty to keep the lookup efficient (at the cost of extra
+ * memory).
+ */
+
+#include "vim.h"
+
+#if defined(FEAT_EVAL) || defined(FEAT_SYN_HL) || defined(PROTO)
+
+#if 0
+# define HT_DEBUG	/* extra checks for table consistency  and statistics */
+
+static long hash_count_lookup = 0;	/* count number of hashtab lookups */
+static long hash_count_perturb = 0;	/* count number of "misses" */
+#endif
+
+/* Magic value for algorithm that walks through the array. */
+#define PERTURB_SHIFT 5
+
+static int hash_may_resize __ARGS((hashtab_T *ht, int minitems));
+
+#if 0 /* currently not used */
+/*
+ * Create an empty hash table.
+ * Returns NULL when out of memory.
+ */
+    hashtab_T *
+hash_create()
+{
+    hashtab_T *ht;
+
+    ht = (hashtab_T *)alloc(sizeof(hashtab_T));
+    if (ht != NULL)
+	hash_init(ht);
+    return ht;
+}
+#endif
+
+/*
+ * Initialize an empty hash table.
+ */
+    void
+hash_init(ht)
+    hashtab_T *ht;
+{
+    /* This zeroes all "ht_" entries and all the "hi_key" in "ht_smallarray". */
+    vim_memset(ht, 0, sizeof(hashtab_T));
+    ht->ht_array = ht->ht_smallarray;
+    ht->ht_mask = HT_INIT_SIZE - 1;
+}
+
+/*
+ * Free the array of a hash table.  Does not free the items it contains!
+ * If "ht" is not freed then you should call hash_init() next!
+ */
+    void
+hash_clear(ht)
+    hashtab_T *ht;
+{
+    if (ht->ht_array != ht->ht_smallarray)
+	vim_free(ht->ht_array);
+}
+
+/*
+ * Free the array of a hash table and all the keys it contains.  The keys must
+ * have been allocated.  "off" is the offset from the start of the allocate
+ * memory to the location of the key (it's always positive).
+ */
+    void
+hash_clear_all(ht, off)
+    hashtab_T	*ht;
+    int		off;
+{
+    long	todo;
+    hashitem_T	*hi;
+
+    todo = (long)ht->ht_used;
+    for (hi = ht->ht_array; todo > 0; ++hi)
+    {
+	if (!HASHITEM_EMPTY(hi))
+	{
+	    vim_free(hi->hi_key - off);
+	    --todo;
+	}
+    }
+    hash_clear(ht);
+}
+
+/*
+ * Find "key" in hashtable "ht".  "key" must not be NULL.
+ * Always returns a pointer to a hashitem.  If the item was not found then
+ * HASHITEM_EMPTY() is TRUE.  The pointer is then the place where the key
+ * would be added.
+ * WARNING: The returned pointer becomes invalid when the hashtable is changed
+ * (adding, setting or removing an item)!
+ */
+    hashitem_T *
+hash_find(ht, key)
+    hashtab_T	*ht;
+    char_u	*key;
+{
+    return hash_lookup(ht, key, hash_hash(key));
+}
+
+/*
+ * Like hash_find(), but caller computes "hash".
+ */
+    hashitem_T *
+hash_lookup(ht, key, hash)
+    hashtab_T	*ht;
+    char_u	*key;
+    hash_T	hash;
+{
+    hash_T	perturb;
+    hashitem_T	*freeitem;
+    hashitem_T	*hi;
+    int		idx;
+
+#ifdef HT_DEBUG
+    ++hash_count_lookup;
+#endif
+
+    /*
+     * Quickly handle the most common situations:
+     * - return if there is no item at all
+     * - skip over a removed item
+     * - return if the item matches
+     */
+    idx = (int)(hash & ht->ht_mask);
+    hi = &ht->ht_array[idx];
+
+    if (hi->hi_key == NULL)
+	return hi;
+    if (hi->hi_key == HI_KEY_REMOVED)
+	freeitem = hi;
+    else if (hi->hi_hash == hash && STRCMP(hi->hi_key, key) == 0)
+	return hi;
+    else
+	freeitem = NULL;
+
+    /*
+     * Need to search through the table to find the key.  The algorithm
+     * to step through the table starts with large steps, gradually becoming
+     * smaller down to (1/4 table size + 1).  This means it goes through all
+     * table entries in the end.
+     * When we run into a NULL key it's clear that the key isn't there.
+     * Return the first available slot found (can be a slot of a removed
+     * item).
+     */
+    for (perturb = hash; ; perturb >>= PERTURB_SHIFT)
+    {
+#ifdef HT_DEBUG
+	++hash_count_perturb;	    /* count a "miss" for hashtab lookup */
+#endif
+	idx = (int)((idx << 2) + idx + perturb + 1);
+	hi = &ht->ht_array[idx & ht->ht_mask];
+	if (hi->hi_key == NULL)
+	    return freeitem == NULL ? hi : freeitem;
+	if (hi->hi_hash == hash
+		&& hi->hi_key != HI_KEY_REMOVED
+		&& STRCMP(hi->hi_key, key) == 0)
+	    return hi;
+	if (hi->hi_key == HI_KEY_REMOVED && freeitem == NULL)
+	    freeitem = hi;
+    }
+}
+
+/*
+ * Print the efficiency of hashtable lookups.
+ * Useful when trying different hash algorithms.
+ * Called when exiting.
+ */
+    void
+hash_debug_results()
+{
+#ifdef HT_DEBUG
+    fprintf(stderr, "\r\n\r\n\r\n\r\n");
+    fprintf(stderr, "Number of hashtable lookups: %ld\r\n", hash_count_lookup);
+    fprintf(stderr, "Number of perturb loops: %ld\r\n", hash_count_perturb);
+    fprintf(stderr, "Percentage of perturb loops: %ld%%\r\n",
+				hash_count_perturb * 100 / hash_count_lookup);
+#endif
+}
+
+/*
+ * Add item with key "key" to hashtable "ht".
+ * Returns FAIL when out of memory or the key is already present.
+ */
+    int
+hash_add(ht, key)
+    hashtab_T	*ht;
+    char_u	*key;
+{
+    hash_T	hash = hash_hash(key);
+    hashitem_T	*hi;
+
+    hi = hash_lookup(ht, key, hash);
+    if (!HASHITEM_EMPTY(hi))
+    {
+	EMSG2(_(e_intern2), "hash_add()");
+	return FAIL;
+    }
+    return hash_add_item(ht, hi, key, hash);
+}
+
+/*
+ * Add item "hi" with "key" to hashtable "ht".  "key" must not be NULL and
+ * "hi" must have been obtained with hash_lookup() and point to an empty item.
+ * "hi" is invalid after this!
+ * Returns OK or FAIL (out of memory).
+ */
+    int
+hash_add_item(ht, hi, key, hash)
+    hashtab_T	*ht;
+    hashitem_T	*hi;
+    char_u	*key;
+    hash_T	hash;
+{
+    /* If resizing failed before and it fails again we can't add an item. */
+    if (ht->ht_error && hash_may_resize(ht, 0) == FAIL)
+	return FAIL;
+
+    ++ht->ht_used;
+    if (hi->hi_key == NULL)
+	++ht->ht_filled;
+    hi->hi_key = key;
+    hi->hi_hash = hash;
+
+    /* When the space gets low may resize the array. */
+    return hash_may_resize(ht, 0);
+}
+
+#if 0  /* not used */
+/*
+ * Overwrite hashtable item "hi" with "key".  "hi" must point to the item that
+ * is to be overwritten.  Thus the number of items in the hashtable doesn't
+ * change.
+ * Although the key must be identical, the pointer may be different, thus it's
+ * set anyway (the key is part of an item with that key).
+ * The caller must take care of freeing the old item.
+ * "hi" is invalid after this!
+ */
+    void
+hash_set(hi, key)
+    hashitem_T	*hi;
+    char_u	*key;
+{
+    hi->hi_key = key;
+}
+#endif
+
+/*
+ * Remove item "hi" from  hashtable "ht".  "hi" must have been obtained with
+ * hash_lookup().
+ * The caller must take care of freeing the item itself.
+ */
+    void
+hash_remove(ht, hi)
+    hashtab_T	*ht;
+    hashitem_T	*hi;
+{
+    --ht->ht_used;
+    hi->hi_key = HI_KEY_REMOVED;
+    hash_may_resize(ht, 0);
+}
+
+/*
+ * Lock a hashtable: prevent that ht_array changes.
+ * Don't use this when items are to be added!
+ * Must call hash_unlock() later.
+ */
+    void
+hash_lock(ht)
+    hashtab_T	*ht;
+{
+    ++ht->ht_locked;
+}
+
+#if 0	    /* currently not used */
+/*
+ * Lock a hashtable at the specified number of entries.
+ * Caller must make sure no more than "size" entries will be added.
+ * Must call hash_unlock() later.
+ */
+    void
+hash_lock_size(ht, size)
+    hashtab_T	*ht;
+    int		size;
+{
+    (void)hash_may_resize(ht, size);
+    ++ht->ht_locked;
+}
+#endif
+
+/*
+ * Unlock a hashtable: allow ht_array changes again.
+ * Table will be resized (shrink) when necessary.
+ * This must balance a call to hash_lock().
+ */
+    void
+hash_unlock(ht)
+    hashtab_T	*ht;
+{
+    --ht->ht_locked;
+    (void)hash_may_resize(ht, 0);
+}
+
+/*
+ * Shrink a hashtable when there is too much empty space.
+ * Grow a hashtable when there is not enough empty space.
+ * Returns OK or FAIL (out of memory).
+ */
+    static int
+hash_may_resize(ht, minitems)
+    hashtab_T	*ht;
+    int		minitems;		/* minimal number of items */
+{
+    hashitem_T	temparray[HT_INIT_SIZE];
+    hashitem_T	*oldarray, *newarray;
+    hashitem_T	*olditem, *newitem;
+    int		newi;
+    int		todo;
+    long_u	oldsize, newsize;
+    long_u	minsize;
+    long_u	newmask;
+    hash_T	perturb;
+
+    /* Don't resize a locked table. */
+    if (ht->ht_locked > 0)
+	return OK;
+
+#ifdef HT_DEBUG
+    if (ht->ht_used > ht->ht_filled)
+	EMSG("hash_may_resize(): more used than filled");
+    if (ht->ht_filled >= ht->ht_mask + 1)
+	EMSG("hash_may_resize(): table completely filled");
+#endif
+
+    if (minitems == 0)
+    {
+	/* Return quickly for small tables with at least two NULL items.  NULL
+	 * items are required for the lookup to decide a key isn't there. */
+	if (ht->ht_filled < HT_INIT_SIZE - 1
+					 && ht->ht_array == ht->ht_smallarray)
+	    return OK;
+
+	/*
+	 * Grow or refill the array when it's more than 2/3 full (including
+	 * removed items, so that they get cleaned up).
+	 * Shrink the array when it's less than 1/5 full.  When growing it is
+	 * at least 1/4 full (avoids repeated grow-shrink operations)
+	 */
+	oldsize = ht->ht_mask + 1;
+	if (ht->ht_filled * 3 < oldsize * 2 && ht->ht_used > oldsize / 5)
+	    return OK;
+
+	if (ht->ht_used > 1000)
+	    minsize = ht->ht_used * 2;  /* it's big, don't make too much room */
+	else
+	    minsize = ht->ht_used * 4;  /* make plenty of room */
+    }
+    else
+    {
+	/* Use specified size. */
+	if ((long_u)minitems < ht->ht_used)	/* just in case... */
+	    minitems = (int)ht->ht_used;
+	minsize = minitems * 3 / 2;	/* array is up to 2/3 full */
+    }
+
+    newsize = HT_INIT_SIZE;
+    while (newsize < minsize)
+    {
+	newsize <<= 1;		/* make sure it's always a power of 2 */
+	if (newsize == 0)
+	    return FAIL;	/* overflow */
+    }
+
+    if (newsize == HT_INIT_SIZE)
+    {
+	/* Use the small array inside the hashdict structure. */
+	newarray = ht->ht_smallarray;
+	if (ht->ht_array == newarray)
+	{
+	    /* Moving from ht_smallarray to ht_smallarray!  Happens when there
+	     * are many removed items.  Copy the items to be able to clean up
+	     * removed items. */
+	    mch_memmove(temparray, newarray, sizeof(temparray));
+	    oldarray = temparray;
+	}
+	else
+	    oldarray = ht->ht_array;
+    }
+    else
+    {
+	/* Allocate an array. */
+	newarray = (hashitem_T *)alloc((unsigned)
+					      (sizeof(hashitem_T) * newsize));
+	if (newarray == NULL)
+	{
+	    /* Out of memory.  When there are NULL items still return OK.
+	     * Otherwise set ht_error, because lookup may result in a hang if
+	     * we add another item. */
+	    if (ht->ht_filled < ht->ht_mask)
+		return OK;
+	    ht->ht_error = TRUE;
+	    return FAIL;
+	}
+	oldarray = ht->ht_array;
+    }
+    vim_memset(newarray, 0, (size_t)(sizeof(hashitem_T) * newsize));
+
+    /*
+     * Move all the items from the old array to the new one, placing them in
+     * the right spot.  The new array won't have any removed items, thus this
+     * is also a cleanup action.
+     */
+    newmask = newsize - 1;
+    todo = (int)ht->ht_used;
+    for (olditem = oldarray; todo > 0; ++olditem)
+	if (!HASHITEM_EMPTY(olditem))
+	{
+	    /*
+	     * The algorithm to find the spot to add the item is identical to
+	     * the algorithm to find an item in hash_lookup().  But we only
+	     * need to search for a NULL key, thus it's simpler.
+	     */
+	    newi = (int)(olditem->hi_hash & newmask);
+	    newitem = &newarray[newi];
+
+	    if (newitem->hi_key != NULL)
+		for (perturb = olditem->hi_hash; ; perturb >>= PERTURB_SHIFT)
+		{
+		    newi = (int)((newi << 2) + newi + perturb + 1);
+		    newitem = &newarray[newi & newmask];
+		    if (newitem->hi_key == NULL)
+			break;
+		}
+	    *newitem = *olditem;
+	    --todo;
+	}
+
+    if (ht->ht_array != ht->ht_smallarray)
+	vim_free(ht->ht_array);
+    ht->ht_array = newarray;
+    ht->ht_mask = newmask;
+    ht->ht_filled = ht->ht_used;
+    ht->ht_error = FALSE;
+
+    return OK;
+}
+
+/*
+ * Get the hash number for a key.
+ * If you think you know a better hash function: Compile with HT_DEBUG set and
+ * run a script that uses hashtables a lot.  Vim will then print statistics
+ * when exiting.  Try that with the current hash algorithm and yours.  The
+ * lower the percentage the better.
+ */
+    hash_T
+hash_hash(key)
+    char_u	*key;
+{
+    hash_T	hash;
+    char_u	*p;
+
+    if ((hash = *key) == 0)
+	return (hash_T)0;	/* Empty keys are not allowed, but we don't
+				   want to crash if we get one. */
+    p = key + 1;
+
+#if 0
+    /* ElfHash algorithm, which is supposed to have an even distribution.
+     * Suggested by Charles Campbell. */
+    hash_T	g;
+
+    while (*p != NUL)
+    {
+	hash = (hash << 4) + *p++;	/* clear low 4 bits of hash, add char */
+	g = hash & 0xf0000000L;		/* g has high 4 bits of hash only */
+	if (g != 0)
+	    hash ^= g >> 24;		/* xor g's high 4 bits into hash */
+    }
+#else
+
+    /* A simplistic algorithm that appears to do very well.
+     * Suggested by George Reilly. */
+    while (*p != NUL)
+	hash = hash * 101 + *p++;
+#endif
+
+    return hash;
+}
+
+#endif
--- /dev/null
+++ b/keymap.h
@@ -1,0 +1,480 @@
+/* vi:set ts=8 sts=4 sw=4:
+ *
+ * VIM - Vi IMproved	by Bram Moolenaar
+ *
+ * Do ":help uganda"  in Vim to read copying and usage conditions.
+ * Do ":help credits" in Vim to see a list of people who contributed.
+ */
+
+/*
+ * Keycode definitions for special keys.
+ *
+ * Any special key code sequences are replaced by these codes.
+ */
+
+/*
+ * For MSDOS some keys produce codes larger than 0xff. They are split into two
+ * chars, the first one is K_NUL (same value used in term.h).
+ */
+#define K_NUL			(0xce)	/* for MSDOS: special key follows */
+
+/*
+ * K_SPECIAL is the first byte of a special key code and is always followed by
+ * two bytes.
+ * The second byte can have any value. ASCII is used for normal termcap
+ * entries, 0x80 and higher for special keys, see below.
+ * The third byte is guaranteed to be between 0x02 and 0x7f.
+ */
+
+#define K_SPECIAL		(0x80)
+
+/*
+ * Positive characters are "normal" characters.
+ * Negative characters are special key codes.  Only characters below -0x200
+ * are used to so that the absolute value can't be mistaken for a single-byte
+ * character.
+ */
+#define IS_SPECIAL(c)		((c) < 0)
+
+/*
+ * Characters 0x0100 - 0x01ff have a special meaning for abbreviations.
+ * Multi-byte characters also have ABBR_OFF added, thus are above 0x0200.
+ */
+#define ABBR_OFF		0x100
+
+/*
+ * NUL cannot be in the input string, therefore it is replaced by
+ *	K_SPECIAL   KS_ZERO	KE_FILLER
+ */
+#define KS_ZERO			255
+
+/*
+ * K_SPECIAL cannot be in the input string, therefore it is replaced by
+ *	K_SPECIAL   KS_SPECIAL	KE_FILLER
+ */
+#define KS_SPECIAL		254
+
+/*
+ * KS_EXTRA is used for keys that have no termcap name
+ *	K_SPECIAL   KS_EXTRA	KE_xxx
+ */
+#define KS_EXTRA		253
+
+/*
+ * KS_MODIFIER is used when a modifier is given for a (special) key
+ *	K_SPECIAL   KS_MODIFIER	bitmask
+ */
+#define KS_MODIFIER		252
+
+/*
+ * These are used for the GUI
+ *	K_SPECIAL   KS_xxx	KE_FILLER
+ */
+#define KS_MOUSE		251
+#define KS_MENU			250
+#define KS_VER_SCROLLBAR	249
+#define KS_HOR_SCROLLBAR	248
+
+/*
+ * These are used for DEC mouse
+ */
+#define KS_NETTERM_MOUSE	247
+#define KS_DEC_MOUSE		246
+
+/*
+ * Used for switching Select mode back on after a mapping or menu.
+ */
+#define KS_SELECT		245
+#define K_SELECT_STRING		(char_u *)"\200\365X"
+
+/*
+ * Used for tearing off a menu.
+ */
+#define KS_TEAROFF		244
+
+/* used for JSB term mouse */
+#define KS_JSBTERM_MOUSE	243
+
+/* used a termcap entry that produces a normal character */
+#define KS_KEY			242
+
+/* Used for the qnx pterm mouse */
+#define KS_PTERM_MOUSE		241
+
+/* Used for click in a tab pages label. */
+#define KS_TABLINE		240
+
+/* Used for menu in a tab pages line. */
+#define KS_TABMENU		239
+
+/*
+ * Filler used after KS_SPECIAL and others
+ */
+#define KE_FILLER		('X')
+
+/*
+ * translation of three byte code "K_SPECIAL a b" into int "K_xxx" and back
+ */
+#define TERMCAP2KEY(a, b)	(-((a) + ((int)(b) << 8)))
+#define KEY2TERMCAP0(x)		((-(x)) & 0xff)
+#define KEY2TERMCAP1(x)		(((unsigned)(-(x)) >> 8) & 0xff)
+
+/*
+ * get second or third byte when translating special key code into three bytes
+ */
+#define K_SECOND(c)	((c) == K_SPECIAL ? KS_SPECIAL : (c) == NUL ? KS_ZERO : KEY2TERMCAP0(c))
+
+#define K_THIRD(c)	(((c) == K_SPECIAL || (c) == NUL) ? KE_FILLER : KEY2TERMCAP1(c))
+
+/*
+ * get single int code from second byte after K_SPECIAL
+ */
+#define TO_SPECIAL(a, b)    ((a) == KS_SPECIAL ? K_SPECIAL : (a) == KS_ZERO ? K_ZERO : TERMCAP2KEY(a, b))
+
+/*
+ * Codes for keys that do not have a termcap name.
+ *
+ * K_SPECIAL KS_EXTRA KE_xxx
+ */
+enum key_extra
+{
+    KE_NAME = 3		/* name of this terminal entry */
+
+    , KE_S_UP		/* shift-up */
+    , KE_S_DOWN		/* shift-down */
+
+    , KE_S_F1		/* shifted function keys */
+    , KE_S_F2
+    , KE_S_F3
+    , KE_S_F4
+    , KE_S_F5
+    , KE_S_F6
+    , KE_S_F7
+    , KE_S_F8
+    , KE_S_F9
+    , KE_S_F10
+
+    , KE_S_F11
+    , KE_S_F12
+    , KE_S_F13
+    , KE_S_F14
+    , KE_S_F15
+    , KE_S_F16
+    , KE_S_F17
+    , KE_S_F18
+    , KE_S_F19
+    , KE_S_F20
+
+    , KE_S_F21
+    , KE_S_F22
+    , KE_S_F23
+    , KE_S_F24
+    , KE_S_F25
+    , KE_S_F26
+    , KE_S_F27
+    , KE_S_F28
+    , KE_S_F29
+    , KE_S_F30
+
+    , KE_S_F31
+    , KE_S_F32
+    , KE_S_F33
+    , KE_S_F34
+    , KE_S_F35
+    , KE_S_F36
+    , KE_S_F37
+
+    , KE_MOUSE		/* mouse event start */
+
+/*
+ * Symbols for pseudo keys which are translated from the real key symbols
+ * above.
+ */
+    , KE_LEFTMOUSE	/* Left mouse button click */
+    , KE_LEFTDRAG	/* Drag with left mouse button down */
+    , KE_LEFTRELEASE	/* Left mouse button release */
+    , KE_MIDDLEMOUSE	/* Middle mouse button click */
+    , KE_MIDDLEDRAG	/* Drag with middle mouse button down */
+    , KE_MIDDLERELEASE	/* Middle mouse button release */
+    , KE_RIGHTMOUSE	/* Right mouse button click */
+    , KE_RIGHTDRAG	/* Drag with right mouse button down */
+    , KE_RIGHTRELEASE	/* Right mouse button release */
+
+    , KE_IGNORE		/* Ignored mouse drag/release */
+
+    , KE_TAB		/* unshifted TAB key */
+    , KE_S_TAB_OLD	/* shifted TAB key (no longer used) */
+
+    , KE_SNIFF		/* SNiFF+ input waiting */
+
+    , KE_XF1		/* extra vt100 function keys for xterm */
+    , KE_XF2
+    , KE_XF3
+    , KE_XF4
+    , KE_XEND		/* extra (vt100) end key for xterm */
+    , KE_ZEND		/* extra (vt100) end key for xterm */
+    , KE_XHOME		/* extra (vt100) home key for xterm */
+    , KE_ZHOME		/* extra (vt100) home key for xterm */
+    , KE_XUP		/* extra vt100 cursor keys for xterm */
+    , KE_XDOWN
+    , KE_XLEFT
+    , KE_XRIGHT
+
+    , KE_LEFTMOUSE_NM	/* non-mappable Left mouse button click */
+    , KE_LEFTRELEASE_NM	/* non-mappable left mouse button release */
+
+    , KE_S_XF1		/* extra vt100 shifted function keys for xterm */
+    , KE_S_XF2
+    , KE_S_XF3
+    , KE_S_XF4
+
+    , KE_MOUSEDOWN	/* scroll wheel pseudo-button Down */
+    , KE_MOUSEUP	/* scroll wheel pseudo-button Up */
+
+    , KE_KINS		/* keypad Insert key */
+    , KE_KDEL		/* keypad Delete key */
+
+    , KE_CSI		/* CSI typed directly */
+    , KE_SNR		/* <SNR> */
+    , KE_PLUG		/* <Plug> */
+    , KE_CMDWIN		/* open command-line window from Command-line Mode */
+
+    , KE_C_LEFT		/* control-left */
+    , KE_C_RIGHT	/* control-right */
+    , KE_C_HOME		/* control-home */
+    , KE_C_END		/* control-end */
+
+    , KE_X1MOUSE	/* X1/X2 mouse-buttons */
+    , KE_X1DRAG
+    , KE_X1RELEASE
+    , KE_X2MOUSE
+    , KE_X2DRAG
+    , KE_X2RELEASE
+
+    , KE_DROP		/* DnD data is available */
+    , KE_CURSORHOLD	/* CursorHold event */
+    , KE_NOP		/* doesn't do something */
+};
+
+/*
+ * the three byte codes are replaced with the following int when using vgetc()
+ */
+#define K_ZERO		TERMCAP2KEY(KS_ZERO, KE_FILLER)
+
+#define K_UP		TERMCAP2KEY('k', 'u')
+#define K_DOWN		TERMCAP2KEY('k', 'd')
+#define K_LEFT		TERMCAP2KEY('k', 'l')
+#define K_RIGHT		TERMCAP2KEY('k', 'r')
+#define K_S_UP		TERMCAP2KEY(KS_EXTRA, KE_S_UP)
+#define K_S_DOWN	TERMCAP2KEY(KS_EXTRA, KE_S_DOWN)
+#define K_S_LEFT	TERMCAP2KEY('#', '4')
+#define K_C_LEFT	TERMCAP2KEY(KS_EXTRA, KE_C_LEFT)
+#define K_S_RIGHT	TERMCAP2KEY('%', 'i')
+#define K_C_RIGHT	TERMCAP2KEY(KS_EXTRA, KE_C_RIGHT)
+#define K_S_HOME	TERMCAP2KEY('#', '2')
+#define K_C_HOME	TERMCAP2KEY(KS_EXTRA, KE_C_HOME)
+#define K_S_END		TERMCAP2KEY('*', '7')
+#define K_C_END		TERMCAP2KEY(KS_EXTRA, KE_C_END)
+#define K_TAB		TERMCAP2KEY(KS_EXTRA, KE_TAB)
+#define K_S_TAB		TERMCAP2KEY('k', 'B')
+
+/* extra set of function keys F1-F4, for vt100 compatible xterm */
+#define K_XF1		TERMCAP2KEY(KS_EXTRA, KE_XF1)
+#define K_XF2		TERMCAP2KEY(KS_EXTRA, KE_XF2)
+#define K_XF3		TERMCAP2KEY(KS_EXTRA, KE_XF3)
+#define K_XF4		TERMCAP2KEY(KS_EXTRA, KE_XF4)
+
+/* extra set of cursor keys for vt100 compatible xterm */
+#define K_XUP		TERMCAP2KEY(KS_EXTRA, KE_XUP)
+#define K_XDOWN		TERMCAP2KEY(KS_EXTRA, KE_XDOWN)
+#define K_XLEFT		TERMCAP2KEY(KS_EXTRA, KE_XLEFT)
+#define K_XRIGHT	TERMCAP2KEY(KS_EXTRA, KE_XRIGHT)
+
+#define K_F1		TERMCAP2KEY('k', '1')	/* function keys */
+#define K_F2		TERMCAP2KEY('k', '2')
+#define K_F3		TERMCAP2KEY('k', '3')
+#define K_F4		TERMCAP2KEY('k', '4')
+#define K_F5		TERMCAP2KEY('k', '5')
+#define K_F6		TERMCAP2KEY('k', '6')
+#define K_F7		TERMCAP2KEY('k', '7')
+#define K_F8		TERMCAP2KEY('k', '8')
+#define K_F9		TERMCAP2KEY('k', '9')
+#define K_F10		TERMCAP2KEY('k', ';')
+
+#define K_F11		TERMCAP2KEY('F', '1')
+#define K_F12		TERMCAP2KEY('F', '2')
+#define K_F13		TERMCAP2KEY('F', '3')
+#define K_F14		TERMCAP2KEY('F', '4')
+#define K_F15		TERMCAP2KEY('F', '5')
+#define K_F16		TERMCAP2KEY('F', '6')
+#define K_F17		TERMCAP2KEY('F', '7')
+#define K_F18		TERMCAP2KEY('F', '8')
+#define K_F19		TERMCAP2KEY('F', '9')
+#define K_F20		TERMCAP2KEY('F', 'A')
+
+#define K_F21		TERMCAP2KEY('F', 'B')
+#define K_F22		TERMCAP2KEY('F', 'C')
+#define K_F23		TERMCAP2KEY('F', 'D')
+#define K_F24		TERMCAP2KEY('F', 'E')
+#define K_F25		TERMCAP2KEY('F', 'F')
+#define K_F26		TERMCAP2KEY('F', 'G')
+#define K_F27		TERMCAP2KEY('F', 'H')
+#define K_F28		TERMCAP2KEY('F', 'I')
+#define K_F29		TERMCAP2KEY('F', 'J')
+#define K_F30		TERMCAP2KEY('F', 'K')
+
+#define K_F31		TERMCAP2KEY('F', 'L')
+#define K_F32		TERMCAP2KEY('F', 'M')
+#define K_F33		TERMCAP2KEY('F', 'N')
+#define K_F34		TERMCAP2KEY('F', 'O')
+#define K_F35		TERMCAP2KEY('F', 'P')
+#define K_F36		TERMCAP2KEY('F', 'Q')
+#define K_F37		TERMCAP2KEY('F', 'R')
+
+/* extra set of shifted function keys F1-F4, for vt100 compatible xterm */
+#define K_S_XF1		TERMCAP2KEY(KS_EXTRA, KE_S_XF1)
+#define K_S_XF2		TERMCAP2KEY(KS_EXTRA, KE_S_XF2)
+#define K_S_XF3		TERMCAP2KEY(KS_EXTRA, KE_S_XF3)
+#define K_S_XF4		TERMCAP2KEY(KS_EXTRA, KE_S_XF4)
+
+#define K_S_F1		TERMCAP2KEY(KS_EXTRA, KE_S_F1)	/* shifted func. keys */
+#define K_S_F2		TERMCAP2KEY(KS_EXTRA, KE_S_F2)
+#define K_S_F3		TERMCAP2KEY(KS_EXTRA, KE_S_F3)
+#define K_S_F4		TERMCAP2KEY(KS_EXTRA, KE_S_F4)
+#define K_S_F5		TERMCAP2KEY(KS_EXTRA, KE_S_F5)
+#define K_S_F6		TERMCAP2KEY(KS_EXTRA, KE_S_F6)
+#define K_S_F7		TERMCAP2KEY(KS_EXTRA, KE_S_F7)
+#define K_S_F8		TERMCAP2KEY(KS_EXTRA, KE_S_F8)
+#define K_S_F9		TERMCAP2KEY(KS_EXTRA, KE_S_F9)
+#define K_S_F10		TERMCAP2KEY(KS_EXTRA, KE_S_F10)
+
+#define K_S_F11		TERMCAP2KEY(KS_EXTRA, KE_S_F11)
+#define K_S_F12		TERMCAP2KEY(KS_EXTRA, KE_S_F12)
+/* K_S_F13 to K_S_F37  are currently not used */
+
+#define K_HELP		TERMCAP2KEY('%', '1')
+#define K_UNDO		TERMCAP2KEY('&', '8')
+
+#define K_BS		TERMCAP2KEY('k', 'b')
+
+#define K_INS		TERMCAP2KEY('k', 'I')
+#define K_KINS		TERMCAP2KEY(KS_EXTRA, KE_KINS)
+#define K_DEL		TERMCAP2KEY('k', 'D')
+#define K_KDEL		TERMCAP2KEY(KS_EXTRA, KE_KDEL)
+#define K_HOME		TERMCAP2KEY('k', 'h')
+#define K_KHOME		TERMCAP2KEY('K', '1')	/* keypad home (upper left) */
+#define K_XHOME		TERMCAP2KEY(KS_EXTRA, KE_XHOME)
+#define K_ZHOME		TERMCAP2KEY(KS_EXTRA, KE_ZHOME)
+#define K_END		TERMCAP2KEY('@', '7')
+#define K_KEND		TERMCAP2KEY('K', '4')	/* keypad end (lower left) */
+#define K_XEND		TERMCAP2KEY(KS_EXTRA, KE_XEND)
+#define K_ZEND		TERMCAP2KEY(KS_EXTRA, KE_ZEND)
+#define K_PAGEUP	TERMCAP2KEY('k', 'P')
+#define K_PAGEDOWN	TERMCAP2KEY('k', 'N')
+#define K_KPAGEUP	TERMCAP2KEY('K', '3')	/* keypad pageup (upper R.) */
+#define K_KPAGEDOWN	TERMCAP2KEY('K', '5')	/* keypad pagedown (lower R.) */
+
+#define K_KPLUS		TERMCAP2KEY('K', '6')	/* keypad plus */
+#define K_KMINUS	TERMCAP2KEY('K', '7')	/* keypad minus */
+#define K_KDIVIDE	TERMCAP2KEY('K', '8')	/* keypad / */
+#define K_KMULTIPLY	TERMCAP2KEY('K', '9')	/* keypad * */
+#define K_KENTER	TERMCAP2KEY('K', 'A')	/* keypad Enter */
+#define K_KPOINT	TERMCAP2KEY('K', 'B')	/* keypad . or ,*/
+
+#define K_K0		TERMCAP2KEY('K', 'C')	/* keypad 0 */
+#define K_K1		TERMCAP2KEY('K', 'D')	/* keypad 1 */
+#define K_K2		TERMCAP2KEY('K', 'E')	/* keypad 2 */
+#define K_K3		TERMCAP2KEY('K', 'F')	/* keypad 3 */
+#define K_K4		TERMCAP2KEY('K', 'G')	/* keypad 4 */
+#define K_K5		TERMCAP2KEY('K', 'H')	/* keypad 5 */
+#define K_K6		TERMCAP2KEY('K', 'I')	/* keypad 6 */
+#define K_K7		TERMCAP2KEY('K', 'J')	/* keypad 7 */
+#define K_K8		TERMCAP2KEY('K', 'K')	/* keypad 8 */
+#define K_K9		TERMCAP2KEY('K', 'L')	/* keypad 9 */
+
+#define K_MOUSE		TERMCAP2KEY(KS_MOUSE, KE_FILLER)
+#define K_MENU		TERMCAP2KEY(KS_MENU, KE_FILLER)
+#define K_VER_SCROLLBAR	TERMCAP2KEY(KS_VER_SCROLLBAR, KE_FILLER)
+#define K_HOR_SCROLLBAR   TERMCAP2KEY(KS_HOR_SCROLLBAR, KE_FILLER)
+
+#define K_NETTERM_MOUSE	TERMCAP2KEY(KS_NETTERM_MOUSE, KE_FILLER)
+#define K_DEC_MOUSE	TERMCAP2KEY(KS_DEC_MOUSE, KE_FILLER)
+#define K_JSBTERM_MOUSE	TERMCAP2KEY(KS_JSBTERM_MOUSE, KE_FILLER)
+#define K_PTERM_MOUSE	TERMCAP2KEY(KS_PTERM_MOUSE, KE_FILLER)
+
+#define K_SELECT	TERMCAP2KEY(KS_SELECT, KE_FILLER)
+#define K_TEAROFF	TERMCAP2KEY(KS_TEAROFF, KE_FILLER)
+
+#define K_TABLINE	TERMCAP2KEY(KS_TABLINE, KE_FILLER)
+#define K_TABMENU	TERMCAP2KEY(KS_TABMENU, KE_FILLER)
+
+/*
+ * Symbols for pseudo keys which are translated from the real key symbols
+ * above.
+ */
+#define K_LEFTMOUSE	TERMCAP2KEY(KS_EXTRA, KE_LEFTMOUSE)
+#define K_LEFTMOUSE_NM	TERMCAP2KEY(KS_EXTRA, KE_LEFTMOUSE_NM)
+#define K_LEFTDRAG	TERMCAP2KEY(KS_EXTRA, KE_LEFTDRAG)
+#define K_LEFTRELEASE	TERMCAP2KEY(KS_EXTRA, KE_LEFTRELEASE)
+#define K_LEFTRELEASE_NM TERMCAP2KEY(KS_EXTRA, KE_LEFTRELEASE_NM)
+#define K_MIDDLEMOUSE	TERMCAP2KEY(KS_EXTRA, KE_MIDDLEMOUSE)
+#define K_MIDDLEDRAG	TERMCAP2KEY(KS_EXTRA, KE_MIDDLEDRAG)
+#define K_MIDDLERELEASE	TERMCAP2KEY(KS_EXTRA, KE_MIDDLERELEASE)
+#define K_RIGHTMOUSE	TERMCAP2KEY(KS_EXTRA, KE_RIGHTMOUSE)
+#define K_RIGHTDRAG	TERMCAP2KEY(KS_EXTRA, KE_RIGHTDRAG)
+#define K_RIGHTRELEASE	TERMCAP2KEY(KS_EXTRA, KE_RIGHTRELEASE)
+#define K_X1MOUSE       TERMCAP2KEY(KS_EXTRA, KE_X1MOUSE)
+#define K_X1MOUSE       TERMCAP2KEY(KS_EXTRA, KE_X1MOUSE)
+#define K_X1DRAG	TERMCAP2KEY(KS_EXTRA, KE_X1DRAG)
+#define K_X1RELEASE     TERMCAP2KEY(KS_EXTRA, KE_X1RELEASE)
+#define K_X2MOUSE       TERMCAP2KEY(KS_EXTRA, KE_X2MOUSE)
+#define K_X2DRAG	TERMCAP2KEY(KS_EXTRA, KE_X2DRAG)
+#define K_X2RELEASE     TERMCAP2KEY(KS_EXTRA, KE_X2RELEASE)
+
+#define K_IGNORE	TERMCAP2KEY(KS_EXTRA, KE_IGNORE)
+#define K_NOP		TERMCAP2KEY(KS_EXTRA, KE_NOP)
+
+#define K_SNIFF		TERMCAP2KEY(KS_EXTRA, KE_SNIFF)
+
+#define K_MOUSEDOWN	TERMCAP2KEY(KS_EXTRA, KE_MOUSEDOWN)
+#define K_MOUSEUP	TERMCAP2KEY(KS_EXTRA, KE_MOUSEUP)
+
+#define K_CSI		TERMCAP2KEY(KS_EXTRA, KE_CSI)
+#define K_SNR		TERMCAP2KEY(KS_EXTRA, KE_SNR)
+#define K_PLUG		TERMCAP2KEY(KS_EXTRA, KE_PLUG)
+#define K_CMDWIN	TERMCAP2KEY(KS_EXTRA, KE_CMDWIN)
+
+#define K_DROP		TERMCAP2KEY(KS_EXTRA, KE_DROP)
+
+#define K_CURSORHOLD	TERMCAP2KEY(KS_EXTRA, KE_CURSORHOLD)
+
+/* Bits for modifier mask */
+/* 0x01 cannot be used, because the modifier must be 0x02 or higher */
+#define MOD_MASK_SHIFT	    0x02
+#define MOD_MASK_CTRL	    0x04
+#define MOD_MASK_ALT	    0x08	/* aka META */
+#define MOD_MASK_META	    0x10	/* META when it's different from ALT */
+#define MOD_MASK_2CLICK	    0x20	/* use MOD_MASK_MULTI_CLICK */
+#define MOD_MASK_3CLICK	    0x40	/* use MOD_MASK_MULTI_CLICK */
+#define MOD_MASK_4CLICK	    0x60	/* use MOD_MASK_MULTI_CLICK */
+#ifdef MACOS
+# define MOD_MASK_CMD	    0x80
+#endif
+
+#define MOD_MASK_MULTI_CLICK	(MOD_MASK_2CLICK|MOD_MASK_3CLICK|MOD_MASK_4CLICK)
+
+/*
+ * The length of the longest special key name, including modifiers.
+ * Current longest is <M-C-S-T-4-MiddleRelease> (length includes '<' and '>').
+ */
+#define MAX_KEY_NAME_LEN    25
+
+/* Maximum length of a special key event as tokens.  This includes modifiers.
+ * The longest event is something like <M-C-S-T-4-LeftDrag> which would be the
+ * following string of tokens:
+ *
+ * <K_SPECIAL> <KS_MODIFIER> bitmask <K_SPECIAL> <KS_EXTRA> <KT_LEFTDRAG>.
+ *
+ * This is a total of 6 tokens, and is currently the longest one possible.
+ */
+#define MAX_KEY_CODE_LEN    6
--- /dev/null
+++ b/lib/vimfiles/autoload/README.txt
@@ -1,0 +1,22 @@
+The autoload directory is for standard Vim autoload scripts.
+
+These are functions used by plugins and for general use.  They will be loaded
+automatically when the function is invoked.  See ":help autoload".
+
+gzip.vim	for editing compressed files
+netrw*.vim	browsing (remote) directories and editing remote files
+tar.vim		browsing tar files
+zip.vim		browsing zip files
+paste.vim	common code for mswin.vim, menu.vim and macmap.vim
+spellfile.vim	downloading of a missing spell file
+
+Omni completion files:
+ccomplete.vim		C
+csscomplete.vim		HTML / CSS
+htmlcomplete.vim	HTML
+javascriptcomplete.vim  Javascript
+phpcomplete.vim		PHP
+pythoncomplete.vim	Python
+rubycomplete.vim	Ruby
+syntaxcomplete.vim	from syntax highlighting
+xmlcomplete.vim		XML (uses files in the xml directory)
--- /dev/null
+++ b/lib/vimfiles/autoload/ada.vim
@@ -1,0 +1,595 @@
+"------------------------------------------------------------------------------
+"  Description: Perform Ada specific completion & tagging.
+"     Language: Ada (2005)
+"	   $Id: ada.vim,v 1.1 2007/05/05 18:02:22 vimboss Exp $
+"   Maintainer: Martin Krischik
+"		Neil Bird <neil@fnxweb.com>
+"      $Author: vimboss $
+"	 $Date: 2007/05/05 18:02:22 $
+"      Version: 4.2
+"    $Revision: 1.1 $
+"     $HeadURL: https://svn.sourceforge.net/svnroot/gnuada/trunk/tools/vim/autoload/ada.vim $
+"      History: 24.05.2006 MK Unified Headers
+"		26.05.2006 MK ' should not be in iskeyword.
+"		16.07.2006 MK Ada-Mode as vim-ball
+"		02.10.2006 MK Better folding.
+"		15.10.2006 MK Bram's suggestion for runtime integration
+"		05.11.2006 MK Bram suggested not to use include protection for
+"			      autoload
+"		05.11.2006 MK Bram suggested to save on spaces
+"    Help Page: ft-ada-functions
+"------------------------------------------------------------------------------
+
+if version < 700
+   finish
+endif 
+
+" Section: Constants {{{1
+"
+let g:ada#DotWordRegex	   = '\a\w*\(\_s*\.\_s*\a\w*\)*'
+let g:ada#WordRegex	   = '\a\w*'
+let g:ada#Comment	   = "\\v^(\"[^\"]*\"|'.'|[^\"']){-}\\zs\\s*--.*"
+let g:ada#Keywords	   = []
+
+" Section: g:ada#Keywords {{{1
+"
+" Section: add Ada keywords {{{2
+"
+for Item in ['abort', 'else', 'new', 'return', 'abs', 'elsif', 'not', 'reverse', 'abstract', 'end', 'null', 'accept', 'entry', 'select', 'access', 'exception', 'of', 'separate', 'aliased', 'exit', 'or', 'subtype', 'all', 'others', 'synchronized', 'and', 'for', 'out', 'array', 'function', 'overriding', 'tagged', 'at', 'task', 'generic', 'package', 'terminate', 'begin', 'goto', 'pragma', 'then', 'body', 'private', 'type', 'if', 'procedure', 'case', 'in', 'protected', 'until', 'constant', 'interface', 'use', 'is', 'raise', 'declare', 'range', 'when', 'delay', 'limited', 'record', 'while', 'delta', 'loop', 'rem', 'with', 'digits', 'renames', 'do', 'mod', 'requeue', 'xor']
+    let g:ada#Keywords += [{
+	    \ 'word':  Item,
+	    \ 'menu':  'keyword',
+	    \ 'info':  'Ada keyword.',
+	    \ 'kind':  'k',
+	    \ 'icase': 1}]
+endfor
+
+" Section: GNAT Project Files {{{3
+"
+if exists ('g:ada_with_gnat_project_files')
+    for Item in ['project']
+       let g:ada#Keywords += [{
+	       \ 'word':  Item,
+	       \ 'menu':  'keyword',
+	       \ 'info':  'GNAT projectfile keyword.',
+	       \ 'kind':  'k',
+	       \ 'icase': 1}]
+    endfor
+endif
+
+" Section: add	standart exception {{{2
+"
+for Item in ['Constraint_Error', 'Program_Error', 'Storage_Error', 'Tasking_Error', 'Status_Error', 'Mode_Error', 'Name_Error', 'Use_Error', 'Device_Error', 'End_Error', 'Data_Error', 'Layout_Error', 'Length_Error', 'Pattern_Error', 'Index_Error', 'Translation_Error', 'Time_Error', 'Argument_Error', 'Tag_Error', 'Picture_Error', 'Terminator_Error', 'Conversion_Error', 'Pointer_Error', 'Dereference_Error', 'Update_Error']
+    let g:ada#Keywords += [{
+	    \ 'word':  Item,
+	    \ 'menu':  'exception',
+	    \ 'info':  'Ada standart exception.',
+	    \ 'kind':  'x',
+	    \ 'icase': 1}]
+endfor
+
+" Section: add	GNAT exception {{{3
+"
+if exists ('g:ada_gnat_extensions')
+    for Item in ['Assert_Failure']
+	let g:ada#Keywords += [{
+		\ 'word':  Item,
+		\ 'menu':  'exception',
+		\ 'info':  'GNAT exception.',
+		\ 'kind':  'x',
+		\ 'icase': 1}]
+    endfor
+endif
+
+" Section: add Ada buildin types {{{2
+"
+for Item in ['Boolean', 'Integer', 'Natural', 'Positive', 'Float', 'Character', 'Wide_Character', 'Wide_Wide_Character', 'String', 'Wide_String', 'Wide_Wide_String', 'Duration']
+    let g:ada#Keywords += [{
+	    \ 'word':  Item,
+	    \ 'menu':  'type',
+	    \ 'info':  'Ada buildin type.',
+	    \ 'kind':  't',
+	    \ 'icase': 1}]
+endfor
+
+" Section: add GNAT buildin types {{{3
+"
+if exists ('g:ada_gnat_extensions')
+    for Item in ['Short_Integer', 'Short_Short_Integer', 'Long_Integer', 'Long_Long_Integer', 'Short_Float', 'Short_Short_Float', 'Long_Float', 'Long_Long_Float']
+	let g:ada#Keywords += [{
+		\ 'word':  Item,
+		\ 'menu':  'type',
+		\ 'info':  'GNAT buildin type.',
+		\ 'kind':  't',
+		\ 'icase': 1}]
+    endfor
+endif
+
+" Section: add Ada Attributes {{{2
+"
+for Item in ['''Access', '''Address', '''Adjacent', '''Aft', '''Alignment', '''Base', '''Bit_Order', '''Body_Version', '''Callable', '''Caller', '''Ceiling', '''Class', '''Component_Size', '''Compose', '''Constrained', '''Copy_Sign', '''Count', '''Definite', '''Delta', '''Denorm', '''Digits', '''Emax', '''Exponent', '''External_Tag', '''Epsilon', '''First', '''First_Bit', '''Floor', '''Fore', '''Fraction', '''Identity', '''Image', '''Input', '''Large', '''Last', '''Last_Bit', '''Leading_Part', '''Length', '''Machine', '''Machine_Emax', '''Machine_Emin', '''Machine_Mantissa', '''Machine_Overflows', '''Machine_Radix', '''Machine_Rounding', '''Machine_Rounds', '''Mantissa', '''Max', '''Max_Size_In_Storage_Elements', '''Min', '''Mod', '''Model', '''Model_Emin', '''Model_Epsilon', '''Model_Mantissa', '''Model_Small', '''Modulus', '''Output', '''Partition_ID', '''Pos', '''Position', '''Pred', '''Priority', '''Range', '''Read', '''Remainder', '''Round', '''Rounding', '''Safe_Emax', '''Safe_First', '''Safe_Large', '''Safe_Last', '''Safe_Small', '''Scale', '''Scaling', '''Signed_Zeros', '''Size', '''Small', '''Storage_Pool', '''Storage_Size', '''Stream_Size', '''Succ', '''Tag', '''Terminated', '''Truncation', '''Unbiased_Rounding', '''Unchecked_Access', '''Val', '''Valid', '''Value', '''Version', '''Wide_Image', '''Wide_Value', '''Wide_Wide_Image', '''Wide_Wide_Value', '''Wide_Wide_Width', '''Wide_Width', '''Width', '''Write']
+    let g:ada#Keywords += [{
+	    \ 'word':  Item,
+	    \ 'menu':  'attribute',
+	    \ 'info':  'Ada attribute.',
+	    \ 'kind':  'a',
+	    \ 'icase': 1}]
+endfor
+
+" Section: add GNAT Attributes {{{3
+"
+if exists ('g:ada_gnat_extensions')
+    for Item in ['''Abort_Signal', '''Address_Size', '''Asm_Input', '''Asm_Output', '''AST_Entry', '''Bit', '''Bit_Position', '''Code_Address', '''Default_Bit_Order', '''Elaborated', '''Elab_Body', '''Elab_Spec', '''Emax', '''Enum_Rep', '''Epsilon', '''Fixed_Value', '''Has_Access_Values', '''Has_Discriminants', '''Img', '''Integer_Value', '''Machine_Size', '''Max_Interrupt_Priority', '''Max_Priority', '''Maximum_Alignment', '''Mechanism_Code', '''Null_Parameter', '''Object_Size', '''Passed_By_Reference', '''Range_Length', '''Storage_Unit', '''Target_Name', '''Tick', '''To_Address', '''Type_Class', '''UET_Address', '''Unconstrained_Array', '''Universal_Literal_String', '''Unrestricted_Access', '''VADS_Size', '''Value_Size', '''Wchar_T_Size', '''Word_Size']
+    let g:ada#Keywords += [{
+	    \ 'word':  Item,
+	    \ 'menu':  'attribute',
+	    \ 'info':  'GNAT attribute.',
+	    \ 'kind':  'a',
+	    \ 'icase': 1}]
+    endfor
+endif
+
+" Section: add Ada Pragmas {{{2
+"
+for Item in ['All_Calls_Remote', 'Assert', 'Assertion_Policy', 'Asynchronous', 'Atomic', 'Atomic_Components', 'Attach_Handler', 'Controlled', 'Convention', 'Detect_Blocking', 'Discard_Names', 'Elaborate', 'Elaborate_All', 'Elaborate_Body', 'Export', 'Import', 'Inline', 'Inspection_Point', 'Interface (Obsolescent)', 'Interrupt_Handler', 'Interrupt_Priority', 'Linker_Options', 'List', 'Locking_Policy', 'Memory_Size (Obsolescent)', 'No_Return', 'Normalize_Scalars', 'Optimize', 'Pack', 'Page', 'Partition_Elaboration_Policy', 'Preelaborable_Initialization', 'Preelaborate', 'Priority', 'Priority_Specific_Dispatching', 'Profile', 'Pure', 'Queueing_Policy', 'Relative_Deadline', 'Remote_Call_Interface', 'Remote_Types', 'Restrictions', 'Reviewable', 'Shared (Obsolescent)', 'Shared_Passive', 'Storage_Size', 'Storage_Unit (Obsolescent)', 'Suppress', 'System_Name (Obsolescent)', 'Task_Dispatching_Policy', 'Unchecked_Union', 'Unsuppress', 'Volatile', 'Volatile_Components']
+    let g:ada#Keywords += [{
+	    \ 'word':  Item,
+	    \ 'menu':  'pragma',
+	    \ 'info':  'Ada pragma.',
+	    \ 'kind':  'p',
+	    \ 'icase': 1}]
+endfor
+
+" Section: add GNAT Pragmas {{{3
+"
+if exists ('g:ada_gnat_extensions')
+    for Item in ['Abort_Defer', 'Ada_83', 'Ada_95', 'Ada_05', 'Annotate', 'Ast_Entry', 'C_Pass_By_Copy', 'Comment', 'Common_Object', 'Compile_Time_Warning', 'Complex_Representation', 'Component_Alignment', 'Convention_Identifier', 'CPP_Class', 'CPP_Constructor', 'CPP_Virtual', 'CPP_Vtable', 'Debug', 'Elaboration_Checks', 'Eliminate', 'Export_Exception', 'Export_Function', 'Export_Object', 'Export_Procedure', 'Export_Value', 'Export_Valued_Procedure', 'Extend_System', 'External', 'External_Name_Casing', 'Finalize_Storage_Only', 'Float_Representation', 'Ident', 'Import_Exception', 'Import_Function', 'Import_Object', 'Import_Procedure', 'Import_Valued_Procedure', 'Initialize_Scalars', 'Inline_Always', 'Inline_Generic', 'Interface_Name', 'Interrupt_State', 'Keep_Names', 'License', 'Link_With', 'Linker_Alias', 'Linker_Section', 'Long_Float', 'Machine_Attribute', 'Main_Storage', 'Obsolescent', 'Passive', 'Polling', 'Profile_Warnings', 'Propagate_Exceptions', 'Psect_Object', 'Pure_Function', 'Restriction_Warnings', 'Source_File_Name', 'Source_File_Name_Project', 'Source_Reference', 'Stream_Convert', 'Style_Checks', 'Subtitle', 'Suppress_All', 'Suppress_Exception_Locations', 'Suppress_Initialization', 'Task_Info', 'Task_Name', 'Task_Storage', 'Thread_Body', 'Time_Slice', 'Title', 'Unimplemented_Unit', 'Universal_Data', 'Unreferenced', 'Unreserve_All_Interrupts', 'Use_VADS_Size', 'Validity_Checks', 'Warnings', 'Weak_External']
+	let g:ada#Keywords += [{
+		\ 'word':  Item,
+		\ 'menu':  'pragma',
+		\ 'info':  'GNAT pragma.',
+		\ 'kind':  'p',
+		\ 'icase': 1}]
+    endfor
+endif
+" 1}}}
+
+" Section: g:ada#Ctags_Kinds {{{1
+"
+let g:ada#Ctags_Kinds = {
+   \ 'P': ["packspec",	  "package specifications"],
+   \ 'p': ["package",	  "packages"],
+   \ 'T': ["typespec",	  "type specifications"],
+   \ 't': ["type",	  "types"],
+   \ 'U': ["subspec",	  "subtype specifications"],
+   \ 'u': ["subtype",	  "subtypes"],
+   \ 'c': ["component",   "record type components"],
+   \ 'l': ["literal",	  "enum type literals"],
+   \ 'V': ["varspec",	  "variable specifications"],
+   \ 'v': ["variable",	  "variables"],
+   \ 'f': ["formal",	  "generic formal parameters"],
+   \ 'n': ["constant",	  "constants"],
+   \ 'x': ["exception",   "user defined exceptions"],
+   \ 'R': ["subprogspec", "subprogram specifications"],
+   \ 'r': ["subprogram",  "subprograms"],
+   \ 'K': ["taskspec",	  "task specifications"],
+   \ 'k': ["task",	  "tasks"],
+   \ 'O': ["protectspec", "protected data specifications"],
+   \ 'o': ["protected",   "protected data"],
+   \ 'E': ["entryspec",   "task/protected data entry specifications"],
+   \ 'e': ["entry",	  "task/protected data entries"],
+   \ 'b': ["label",	  "labels"],
+   \ 'i': ["identifier",  "loop/declare identifiers"],
+   \ 'a': ["autovar",	  "automatic variables"],
+   \ 'y': ["annon",	  "loops and blocks with no identifier"]}
+
+" Section: ada#Word (...) {{{1
+"
+" Extract current Ada word across multiple lines
+" AdaWord ([line, column])\
+"
+function ada#Word (...)
+   if a:0 > 1
+      let l:Line_Nr    = a:1
+      let l:Column_Nr  = a:2 - 1
+   else
+      let l:Line_Nr    = line('.')
+      let l:Column_Nr  = col('.') - 1
+   endif
+
+   let l:Line = substitute (getline (l:Line_Nr), g:ada#Comment, '', '' )
+
+   " Cope with tag searching for items in comments; if we are, don't loop
+   " backards looking for previous lines
+   if l:Column_Nr > strlen(l:Line)
+      " We were in a comment
+      let l:Line = getline(l:Line_Nr)
+      let l:Search_Prev_Lines = 0
+   else
+      let l:Search_Prev_Lines = 1
+   endif
+
+   " Go backwards until we find a match (Ada ID) that *doesn't* include our
+   " location - i.e., the previous ID. This is because the current 'correct'
+   " match will toggle matching/not matching as we traverse characters
+   " backwards. Thus, we have to find the previous unrelated match, exclude
+   " it, then use the next full match (ours).
+   " Remember to convert vim column 'l:Column_Nr' [1..n] to string offset [0..(n-1)]
+   " ... but start, here, one after the required char.
+   let l:New_Column = l:Column_Nr + 1
+   while 1
+      let l:New_Column = l:New_Column - 1
+      if l:New_Column < 0
+	 " Have to include previous l:Line from file
+	 let l:Line_Nr = l:Line_Nr - 1
+	 if l:Line_Nr < 1  ||  !l:Search_Prev_Lines
+	    " Start of file or matching in a comment
+	    let l:Line_Nr     = 1
+	    let l:New_Column  = 0
+	    let l:Our_Match   = match (l:Line, g:ada#WordRegex )
+	    break
+	 endif
+	 " Get previous l:Line, and prepend it to our search string
+	 let l:New_Line    = substitute (getline (l:Line_Nr), g:ada#Comment, '', '' )
+	 let l:New_Column  = strlen (l:New_Line) - 1
+	 let l:Column_Nr   = l:Column_Nr + l:New_Column
+	 let l:Line	   = l:New_Line . l:Line
+      endif
+      " Check to see if this is a match excluding 'us'
+      let l:Match_End = l:New_Column +
+		      \ matchend (strpart (l:Line,l:New_Column), g:ada#WordRegex ) - 1
+      if l:Match_End >= l:New_Column  &&
+       \ l:Match_End < l:Column_Nr
+	 " Yes
+	 let l:Our_Match = l:Match_End+1 +
+			 \ match (strpart (l:Line,l:Match_End+1), g:ada#WordRegex )
+	 break
+      endif
+   endwhile
+
+   " Got anything?
+   if l:Our_Match < 0
+      return ''
+   else
+      let l:Line = strpart (l:Line, l:Our_Match)
+   endif
+
+   " Now simply add further lines until the match gets no bigger
+   let l:Match_String = matchstr (l:Line, g:ada#WordRegex)
+   let l:Last_Line    = line ('$')
+   let l:Line_Nr      = line ('.') + 1
+   while l:Line_Nr <= l:Last_Line
+      let l:Last_Match = l:Match_String
+      let l:Line = l:Line .
+	 \ substitute (getline (l:Line_Nr), g:ada#Comment, '', '')
+      let l:Match_String = matchstr (l:Line, g:ada#WordRegex)
+      if l:Match_String == l:Last_Match
+	 break
+      endif
+   endwhile
+
+   " Strip whitespace & return
+   return substitute (l:Match_String, '\s\+', '', 'g')
+endfunction ada#Word
+
+" Section: ada#List_Tag (...) {{{1
+"
+"  List tags in quickfix window
+"
+function ada#List_Tag (...)
+   if a:0 > 1
+      let l:Tag_Word = ada#Word (a:1, a:2)
+   elseif a:0 > 0
+      let l:Tag_Word = a:1
+   else
+      let l:Tag_Word = ada#Word ()
+   endif
+
+   echo "Searching for" l:Tag_Word
+
+   let l:Pattern = '^' . l:Tag_Word . '$'
+   let l:Tag_List = taglist (l:Pattern)
+   let l:Error_List = []
+   "
+   " add symbols
+   "
+   for Tag_Item in l:Tag_List
+      if l:Tag_Item['kind'] == ''
+	 let l:Tag_Item['kind'] = 's'
+      endif
+
+      let l:Error_List += [
+	 \ l:Tag_Item['filename'] . '|' .
+	 \ l:Tag_Item['cmd']	  . '|' .
+	 \ l:Tag_Item['kind']	  . "\t" .
+	 \ l:Tag_Item['name'] ]
+   endfor
+   set errorformat=%f\|%l\|%m
+   cexpr l:Error_List
+   cwindow
+endfunction ada#List_Tag
+
+" Section: ada#Jump_Tag (Word, Mode) {{{1
+"
+" Word tag - include '.' and if Ada make uppercase
+"
+function ada#Jump_Tag (Word, Mode)
+   if a:Word == ''
+      " Get current word
+      let l:Word = ada#Word()
+      if l:Word == ''
+	 throw "NOT_FOUND: no identifier found."
+      endif
+   else
+      let l:Word = a:Word
+   endif
+
+   echo "Searching for " . l:Word
+
+   try
+      execute a:Mode l:Word
+   catch /.*:E426:.*/
+      let ignorecase = &ignorecase
+      set ignorecase
+      execute a:Mode l:Word
+      let &ignorecase = ignorecase
+   endtry
+
+   return
+endfunction ada#Jump_Tag
+
+" Section: ada#Insert_Backspace () {{{1
+"
+" Backspace at end of line after auto-inserted commentstring '-- ' wipes it
+"
+function ada#Insert_Backspace ()
+   let l:Line = getline ('.')
+   if col ('.') > strlen (l:Line) &&
+    \ match (l:Line, '-- $') != -1 &&
+    \ match (&comments,'--') != -1
+      return "\<bs>\<bs>\<bs>"
+   else
+      return "\<bs>"
+   endif
+
+   return
+endfunction ada#InsertBackspace
+
+" Section: Insert Completions {{{1
+"
+" Section: ada#User_Complete(findstart, base) {{{2
+"
+" This function is used for the 'complete' option.
+"
+function! ada#User_Complete(findstart, base)
+   if a:findstart == 1
+      "
+      " locate the start of the word
+      "
+      let line = getline ('.')
+      let start = col ('.') - 1
+      while start > 0 && line[start - 1] =~ '\i\|'''
+	 let start -= 1
+      endwhile
+      return start
+   else
+      "
+      " look up matches
+      "
+      let l:Pattern = '^' . a:base . '.*$'
+      "
+      " add keywords
+      "
+      for Tag_Item in g:ada#Keywords
+	 if l:Tag_Item['word'] =~? l:Pattern
+	    if complete_add (l:Tag_Item) == 0
+	       return []
+	    endif
+	    if complete_check ()
+	       return []
+	    endif
+	 endif
+      endfor
+      return []
+   endif
+endfunction ada#User_Complete
+
+" Section: ada#Completion (cmd) {{{2
+"
+" Word completion (^N/^R/^X^]) - force '.' inclusion
+function ada#Completion (cmd)
+   set iskeyword+=46
+   return a:cmd . "\<C-R>=ada#Completion_End ()\<CR>"
+endfunction ada#Completion
+
+" Section: ada#Completion_End () {{{2
+"
+function ada#Completion_End ()
+   set iskeyword-=46
+   return ''
+endfunction ada#Completion_End
+
+" Section: ada#Create_Tags {{{1
+"
+function ada#Create_Tags (option)
+   if a:option == 'file'
+      let l:Filename = fnamemodify (bufname ('%'), ':p')
+   elseif a:option == 'dir'
+      let l:Filename =
+	 \ fnamemodify (bufname ('%'), ':p:h') . "*.ada " .
+	 \ fnamemodify (bufname ('%'), ':p:h') . "*.adb " .
+	 \ fnamemodify (bufname ('%'), ':p:h') . "*.ads"
+   else
+      let l:Filename = a:option
+   endif
+   execute '!ctags --excmd=number ' . l:Filename
+endfunction ada#Create_Tags
+
+function ada#Switch_Session (New_Session)   "{{{1
+   if a:New_Session != v:this_session
+      "
+      "  We actualy got a new session - otherwise there
+      "  is nothing to do.
+      "
+      if strlen (v:this_session) > 0
+	 execute 'mksession! ' . v:this_session
+      endif
+
+      let v:this_session = a:New_Session
+
+      if filereadable (v:this_session)
+	 execute 'source ' . v:this_session
+      endif
+
+      augroup ada_session
+	 autocmd!
+	 autocmd VimLeavePre * execute 'mksession! ' . v:this_session
+      augroup END
+   endif
+
+   return
+endfunction ada#Switch_Session	 "}}}1
+
+" Section: GNAT Pretty Printer folding {{{1
+"
+if exists('g:ada_folding') && g:ada_folding[0] == 'g'
+   "
+   " Lines consisting only of ')' ';' are due to a gnat pretty bug and
+   " have the same level as the line above (can't happen in the first
+   " line).
+   "
+   let s:Fold_Collate = '^\([;)]*$\|'
+
+   "
+   " some lone statements are folded with the line above
+   "
+   if stridx (g:ada_folding, 'i') >= 0
+      let s:Fold_Collate .= '\s\+\<is\>$\|'
+   endif
+   if stridx (g:ada_folding, 'b') >= 0
+      let s:Fold_Collate .= '\s\+\<begin\>$\|'
+   endif
+   if stridx (g:ada_folding, 'p') >= 0
+      let s:Fold_Collate .= '\s\+\<private\>$\|'
+   endif
+   if stridx (g:ada_folding, 'x') >= 0
+      let s:Fold_Collate .= '\s\+\<exception\>$\|'
+   endif
+
+   " We also handle empty lines and
+   " comments here.
+   let s:Fold_Collate .= '--\)'
+
+   function ada#Pretty_Print_Folding (Line)			     " {{{2
+      let l:Text = getline (a:Line)
+
+      if l:Text =~ s:Fold_Collate
+	 "
+	 "  fold with line above
+	 "
+	 let l:Level = "="
+      elseif l:Text =~ '^\s\+('
+	 "
+	 " gnat outdents a line which stards with a ( by one characters so
+	 " that parameters which follow are aligned.
+	 "
+	 let l:Level = (indent (a:Line) + 1) / &shiftwidth
+      else
+	 let l:Level = indent (a:Line) / &shiftwidth
+      endif
+
+      return l:Level
+   endfunction ada#Pretty_Print_Folding				     " }}}2
+endif
+
+" Section: Options and Menus {{{1
+"
+" Section: ada#Switch_Syntax_Options {{{2
+"
+function ada#Switch_Syntax_Option (option)
+   syntax off
+   if exists ('g:ada_' . a:option)
+      unlet g:ada_{a:option}
+      echo  a:option . 'now off'
+   else
+      let g:ada_{a:option}=1
+      echo  a:option . 'now on'
+   endif
+   syntax on
+endfunction ada#Switch_Syntax_Option
+
+" Section: ada#Map_Menu {{{2
+"
+function ada#Map_Menu (Text, Keys, Command)
+   if a:Keys[0] == ':'
+      execute
+	\ "50amenu " .
+	\ "Ada."     . escape(a:Text, ' ') .
+	\ "<Tab>"    . a:Keys .
+	\ " :"	     . a:Command . "<CR>"
+      execute
+	\ "command -buffer " .
+	\ a:Keys[1:] .
+	\" :" . a:Command . "<CR>"
+   elseif a:Keys[0] == '<'
+      execute
+	\ "50amenu " .
+	\ "Ada."     . escape(a:Text, ' ') .
+	\ "<Tab>"    . a:Keys .
+	\ " :"	     . a:Command . "<CR>"
+      execute
+	\ "nnoremap <buffer> "	 .
+	\ a:Keys		 .
+	\" :" . a:Command . "<CR>"
+      execute
+	\ "inoremap <buffer> "	 .
+	\ a:Keys		 .
+	\" <C-O>:" . a:Command . "<CR>"
+   else
+      execute
+	\ "50amenu " .
+	\ "Ada."  . escape(a:Text, ' ') .
+	\ "<Tab>" . escape(g:mapleader . "a" . a:Keys , '\') .
+	\ " :"	  . a:Command . "<CR>"
+      execute
+	\ "nnoremap <buffer>" .
+	\ escape(g:mapleader . "a" . a:Keys , '\') .
+	\" :" . a:Command
+      execute
+	\ "inoremap <buffer>" .
+	\ escape(g:mapleader . "a" . a:Keys , '\') .
+	\" <C-O>:" . a:Command
+   endif
+   return
+endfunction
+
+" Section: ada#Map_Popup {{{2
+"
+function ada#Map_Popup (Text, Keys, Command)
+   execute
+     \ "50amenu " .
+     \ "PopUp."   . escape(a:Text, ' ') .
+     \ "<Tab>"	  . escape(g:mapleader . "a" . a:Keys , '\') .
+     \ " :"	  . a:Command . "<CR>"
+
+   call ada#Map_Menu (a:Text, a:Keys, a:Command)
+   return
+endfunction ada#Map_Popup
+
+" }}}1
+
+lockvar  g:ada#WordRegex
+lockvar  g:ada#DotWordRegex
+lockvar  g:ada#Comment
+lockvar! g:ada#Keywords
+lockvar! g:ada#Ctags_Kinds
+
+finish " 1}}}
+
+"------------------------------------------------------------------------------
+"   Copyright (C) 2006	Martin Krischik
+"
+"   Vim is Charityware - see ":help license" or uganda.txt for licence details.
+"------------------------------------------------------------------------------
+" vim: textwidth=78 wrap tabstop=8 shiftwidth=3 softtabstop=3 noexpandtab
+" vim: foldmethod=marker
--- /dev/null
+++ b/lib/vimfiles/autoload/adacomplete.vim
@@ -1,0 +1,109 @@
+"------------------------------------------------------------------------------
+"  Description: Vim Ada omnicompletion file
+"     Language:	Ada (2005)
+"	   $Id: adacomplete.vim,v 1.1 2007/05/05 17:34:16 vimboss Exp $
+"   Maintainer:	Martin Krischik
+"      $Author: vimboss $
+"	 $Date: 2007/05/05 17:34:16 $
+"      Version: 4.2
+"    $Revision: 1.1 $
+"     $HeadURL: https://svn.sourceforge.net/svnroot/gnuada/trunk/tools/vim/autoload/adacomplete.vim $
+"      History: 24.05.2006 MK Unified Headers
+"		26.05.2006 MK improved search for begin of word.
+"		16.07.2006 MK Ada-Mode as vim-ball
+"		15.10.2006 MK Bram's suggestion for runtime integration
+"		05.11.2006 MK Bram suggested not to use include protection for
+"			      autoload
+"		05.11.2006 MK Bram suggested agaist using setlocal omnifunc 
+"		05.11.2006 MK Bram suggested to save on spaces
+"    Help Page: ft-ada-omni
+"------------------------------------------------------------------------------
+
+if version < 700
+   finish
+endif
+
+" Section: adacomplete#Complete () {{{1
+"
+" This function is used for the 'omnifunc' option.
+"
+function! adacomplete#Complete (findstart, base)
+   if a:findstart == 1
+      return ada#User_Complete (a:findstart, a:base)
+   else
+      "
+      " look up matches
+      "
+      if exists ("g:ada_omni_with_keywords")
+	 call ada#User_Complete (a:findstart, a:base)
+      endif
+      "
+      "  search tag file for matches
+      "
+      let l:Pattern  = '^' . a:base . '.*$'
+      let l:Tag_List = taglist (l:Pattern)
+      "
+      " add symbols
+      "
+      for Tag_Item in l:Tag_List
+	 if l:Tag_Item['kind'] == ''
+	    "
+	    " Tag created by gnat xref
+	    "
+	    let l:Match_Item = {
+	       \ 'word':  l:Tag_Item['name'],
+	       \ 'menu':  l:Tag_Item['filename'],
+	       \ 'info':  "Symbol from file " . l:Tag_Item['filename'] . " line " . l:Tag_Item['cmd'],
+	       \ 'kind':  's',
+	       \ 'icase': 1}
+	 else
+	    "
+	    " Tag created by ctags
+	    "
+	    let l:Info	= 'Symbol		 : ' . l:Tag_Item['name']  . "\n"
+	    let l:Info .= 'Of type		 : ' . g:ada#Ctags_Kinds[l:Tag_Item['kind']][1]  . "\n"
+	    let l:Info .= 'Defined in File	 : ' . l:Tag_Item['filename'] . "\n"
+
+	    if has_key( l:Tag_Item, 'package')
+	       let l:Info .= 'Package		    : ' . l:Tag_Item['package'] . "\n"
+	       let l:Menu  = l:Tag_Item['package']
+	    elseif has_key( l:Tag_Item, 'separate')
+	       let l:Info .= 'Separate from Package : ' . l:Tag_Item['separate'] . "\n"
+	       let l:Menu  = l:Tag_Item['separate']
+	    elseif has_key( l:Tag_Item, 'packspec')
+	       let l:Info .= 'Package Specification : ' . l:Tag_Item['packspec'] . "\n"
+	       let l:Menu  = l:Tag_Item['packspec']
+	    elseif has_key( l:Tag_Item, 'type')
+	       let l:Info .= 'Datetype		    : ' . l:Tag_Item['type'] . "\n"
+	       let l:Menu  = l:Tag_Item['type']
+	    else
+	       let l:Menu  = l:Tag_Item['filename']
+	    endif
+
+	    let l:Match_Item = {
+	       \ 'word':  l:Tag_Item['name'],
+	       \ 'menu':  l:Menu,
+	       \ 'info':  l:Info,
+	       \ 'kind':  l:Tag_Item['kind'],
+	       \ 'icase': 1}
+	 endif
+	 if complete_add (l:Match_Item) == 0
+	    return []
+	 endif
+	 if complete_check ()
+	    return []
+	 endif
+      endfor
+      return []
+   endif
+endfunction adacomplete#Complete
+
+finish " 1}}}
+
+"------------------------------------------------------------------------------
+"   Copyright (C) 2006	Martin Krischik
+"
+"   Vim is Charityware - see ":help license" or uganda.txt for licence details.
+"------------------------------------------------------------------------------
+" vim: textwidth=78 wrap tabstop=8 shiftwidth=3 softtabstop=3 noexpandtab
+" vim: foldmethod=marker
--- /dev/null
+++ b/lib/vimfiles/autoload/ccomplete.vim
@@ -1,0 +1,584 @@
+" Vim completion script
+" Language:	C
+" Maintainer:	Bram Moolenaar <Bram@vim.org>
+" Last Change:	2006 May 08
+
+
+" This function is used for the 'omnifunc' option.
+function! ccomplete#Complete(findstart, base)
+  if a:findstart
+    " Locate the start of the item, including ".", "->" and "[...]".
+    let line = getline('.')
+    let start = col('.') - 1
+    let lastword = -1
+    while start > 0
+      if line[start - 1] =~ '\w'
+	let start -= 1
+      elseif line[start - 1] =~ '\.'
+	if lastword == -1
+	  let lastword = start
+	endif
+	let start -= 1
+      elseif start > 1 && line[start - 2] == '-' && line[start - 1] == '>'
+	if lastword == -1
+	  let lastword = start
+	endif
+	let start -= 2
+      elseif line[start - 1] == ']'
+	" Skip over [...].
+	let n = 0
+	let start -= 1
+	while start > 0
+	  let start -= 1
+	  if line[start] == '['
+	    if n == 0
+	      break
+	    endif
+	    let n -= 1
+	  elseif line[start] == ']'  " nested []
+	    let n += 1
+	  endif
+	endwhile
+      else
+	break
+      endif
+    endwhile
+
+    " Return the column of the last word, which is going to be changed.
+    " Remember the text that comes before it in s:prepended.
+    if lastword == -1
+      let s:prepended = ''
+      return start
+    endif
+    let s:prepended = strpart(line, start, lastword - start)
+    return lastword
+  endif
+
+  " Return list of matches.
+
+  let base = s:prepended . a:base
+
+  " Don't do anything for an empty base, would result in all the tags in the
+  " tags file.
+  if base == ''
+    return []
+  endif
+
+  " init cache for vimgrep to empty
+  let s:grepCache = {}
+
+  " Split item in words, keep empty word after "." or "->".
+  " "aa" -> ['aa'], "aa." -> ['aa', ''], "aa.bb" -> ['aa', 'bb'], etc.
+  " We can't use split, because we need to skip nested [...].
+  let items = []
+  let s = 0
+  while 1
+    let e = match(base, '\.\|->\|\[', s)
+    if e < 0
+      if s == 0 || base[s - 1] != ']'
+	call add(items, strpart(base, s))
+      endif
+      break
+    endif
+    if s == 0 || base[s - 1] != ']'
+      call add(items, strpart(base, s, e - s))
+    endif
+    if base[e] == '.'
+      let s = e + 1	" skip over '.'
+    elseif base[e] == '-'
+      let s = e + 2	" skip over '->'
+    else
+      " Skip over [...].
+      let n = 0
+      let s = e
+      let e += 1
+      while e < len(base)
+	if base[e] == ']'
+	  if n == 0
+	    break
+	  endif
+	  let n -= 1
+	elseif base[e] == '['  " nested [...]
+	  let n += 1
+	endif
+	let e += 1
+      endwhile
+      let e += 1
+      call add(items, strpart(base, s, e - s))
+      let s = e
+    endif
+  endwhile
+
+  " Find the variable items[0].
+  " 1. in current function (like with "gd")
+  " 2. in tags file(s) (like with ":tag")
+  " 3. in current file (like with "gD")
+  let res = []
+  if searchdecl(items[0], 0, 1) == 0
+    " Found, now figure out the type.
+    " TODO: join previous line if it makes sense
+    let line = getline('.')
+    let col = col('.')
+    if len(items) == 1
+      " Completing one word and it's a local variable: May add '[', '.' or
+      " '->'.
+      let match = items[0]
+      let kind = 'v'
+      if match(line, '\<' . match . '\s*\[') > 0
+	let match .= '['
+      else
+	let res = s:Nextitem(strpart(line, 0, col), [''], 0, 1)
+	if len(res) > 0
+	  " There are members, thus add "." or "->".
+	  if match(line, '\*[ \t(]*' . match . '\>') > 0
+	    let match .= '->'
+	  else
+	    let match .= '.'
+	  endif
+	endif
+      endif
+      let res = [{'match': match, 'tagline' : '', 'kind' : kind, 'info' : line}]
+    else
+      " Completing "var.", "var.something", etc.
+      let res = s:Nextitem(strpart(line, 0, col), items[1:], 0, 1)
+    endif
+  endif
+
+  if len(items) == 1
+    " Only one part, no "." or "->": complete from tags file.
+    let tags = taglist('^' . base)
+
+    " Remove members, these can't appear without something in front.
+    call filter(tags, 'has_key(v:val, "kind") ? v:val["kind"] != "m" : 1')
+
+    " Remove static matches in other files.
+    call filter(tags, '!has_key(v:val, "static") || !v:val["static"] || bufnr("%") == bufnr(v:val["filename"])')
+
+    call extend(res, map(tags, 's:Tag2item(v:val)'))
+  endif
+
+  if len(res) == 0
+    " Find the variable in the tags file(s)
+    let diclist = taglist('^' . items[0] . '$')
+
+    " Remove members, these can't appear without something in front.
+    call filter(diclist, 'has_key(v:val, "kind") ? v:val["kind"] != "m" : 1')
+
+    let res = []
+    for i in range(len(diclist))
+      " New ctags has the "typeref" field.  Patched version has "typename".
+      if has_key(diclist[i], 'typename')
+	call extend(res, s:StructMembers(diclist[i]['typename'], items[1:], 1))
+      elseif has_key(diclist[i], 'typeref')
+	call extend(res, s:StructMembers(diclist[i]['typeref'], items[1:], 1))
+      endif
+
+      " For a variable use the command, which must be a search pattern that
+      " shows the declaration of the variable.
+      if diclist[i]['kind'] == 'v'
+	let line = diclist[i]['cmd']
+	if line[0] == '/' && line[1] == '^'
+	  let col = match(line, '\<' . items[0] . '\>')
+	  call extend(res, s:Nextitem(strpart(line, 2, col - 2), items[1:], 0, 1))
+	endif
+      endif
+    endfor
+  endif
+
+  if len(res) == 0 && searchdecl(items[0], 1) == 0
+    " Found, now figure out the type.
+    " TODO: join previous line if it makes sense
+    let line = getline('.')
+    let col = col('.')
+    let res = s:Nextitem(strpart(line, 0, col), items[1:], 0, 1)
+  endif
+
+  " If the last item(s) are [...] they need to be added to the matches.
+  let last = len(items) - 1
+  let brackets = ''
+  while last >= 0
+    if items[last][0] != '['
+      break
+    endif
+    let brackets = items[last] . brackets
+    let last -= 1
+  endwhile
+
+  return map(res, 's:Tagline2item(v:val, brackets)')
+endfunc
+
+function! s:GetAddition(line, match, memarg, bracket)
+  " Guess if the item is an array.
+  if a:bracket && match(a:line, a:match . '\s*\[') > 0
+    return '['
+  endif
+
+  " Check if the item has members.
+  if len(s:SearchMembers(a:memarg, [''], 0)) > 0
+    " If there is a '*' before the name use "->".
+    if match(a:line, '\*[ \t(]*' . a:match . '\>') > 0
+      return '->'
+    else
+      return '.'
+    endif
+  endif
+  return ''
+endfunction
+
+" Turn the tag info "val" into an item for completion.
+" "val" is is an item in the list returned by taglist().
+" If it is a variable we may add "." or "->".  Don't do it for other types,
+" such as a typedef, by not including the info that s:GetAddition() uses.
+function! s:Tag2item(val)
+  let res = {'match': a:val['name']}
+
+  let res['extra'] = s:Tagcmd2extra(a:val['cmd'], a:val['name'], a:val['filename'])
+
+  let s = s:Dict2info(a:val)
+  if s != ''
+    let res['info'] = s
+  endif
+
+  let res['tagline'] = ''
+  if has_key(a:val, "kind")
+    let kind = a:val['kind']
+    let res['kind'] = kind
+    if kind == 'v'
+      let res['tagline'] = "\t" . a:val['cmd']
+      let res['dict'] = a:val
+    elseif kind == 'f'
+      let res['match'] = a:val['name'] . '('
+    endif
+  endif
+
+  return res
+endfunction
+
+" Use all the items in dictionary for the "info" entry.
+function! s:Dict2info(dict)
+  let info = ''
+  for k in sort(keys(a:dict))
+    let info  .= k . repeat(' ', 10 - len(k))
+    if k == 'cmd'
+      let info .= substitute(matchstr(a:dict['cmd'], '/^\s*\zs.*\ze$/'), '\\\(.\)', '\1', 'g')
+    else
+      let info .= a:dict[k]
+    endif
+    let info .= "\n"
+  endfor
+  return info
+endfunc
+
+" Parse a tag line and return a dictionary with items like taglist()
+function! s:ParseTagline(line)
+  let l = split(a:line, "\t")
+  let d = {}
+  if len(l) >= 3
+    let d['name'] = l[0]
+    let d['filename'] = l[1]
+    let d['cmd'] = l[2]
+    let n = 2
+    if l[2] =~ '^/'
+      " Find end of cmd, it may contain Tabs.
+      while n < len(l) && l[n] !~ '/;"$'
+	let n += 1
+	let d['cmd'] .= "  " . l[n]
+      endwhile
+    endif
+    for i in range(n + 1, len(l) - 1)
+      if l[i] == 'file:'
+	let d['static'] = 1
+      elseif l[i] !~ ':'
+	let d['kind'] = l[i]
+      else
+	let d[matchstr(l[i], '[^:]*')] = matchstr(l[i], ':\zs.*')
+      endif
+    endfor
+  endif
+
+  return d
+endfunction
+
+" Turn a match item "val" into an item for completion.
+" "val['match']" is the matching item.
+" "val['tagline']" is the tagline in which the last part was found.
+function! s:Tagline2item(val, brackets)
+  let line = a:val['tagline']
+  let add = s:GetAddition(line, a:val['match'], [a:val], a:brackets == '')
+  let res = {'word': a:val['match'] . a:brackets . add }
+
+  if has_key(a:val, 'info')
+    " Use info from Tag2item().
+    let res['info'] = a:val['info']
+  else
+    " Parse the tag line and add each part to the "info" entry.
+    let s = s:Dict2info(s:ParseTagline(line))
+    if s != ''
+      let res['info'] = s
+    endif
+  endif
+
+  if has_key(a:val, 'kind')
+    let res['kind'] = a:val['kind']
+  elseif add == '('
+    let res['kind'] = 'f'
+  else
+    let s = matchstr(line, '\t\(kind:\)\=\zs\S\ze\(\t\|$\)')
+    if s != ''
+      let res['kind'] = s
+    endif
+  endif
+
+  if has_key(a:val, 'extra')
+    let res['menu'] = a:val['extra']
+    return res
+  endif
+
+  " Isolate the command after the tag and filename.
+  let s = matchstr(line, '[^\t]*\t[^\t]*\t\zs\(/^.*$/\|[^\t]*\)\ze\(;"\t\|\t\|$\)')
+  if s != ''
+    let res['menu'] = s:Tagcmd2extra(s, a:val['match'], matchstr(line, '[^\t]*\t\zs[^\t]*\ze\t'))
+  endif
+  return res
+endfunction
+
+" Turn a command from a tag line to something that is useful in the menu
+function! s:Tagcmd2extra(cmd, name, fname)
+  if a:cmd =~ '^/^'
+    " The command is a search command, useful to see what it is.
+    let x = matchstr(a:cmd, '^/^\s*\zs.*\ze$/')
+    let x = substitute(x, '\<' . a:name . '\>', '@@', '')
+    let x = substitute(x, '\\\(.\)', '\1', 'g')
+    let x = x . ' - ' . a:fname
+  elseif a:cmd =~ '^\d*$'
+    " The command is a line number, the file name is more useful.
+    let x = a:fname . ' - ' . a:cmd
+  else
+    " Not recognized, use command and file name.
+    let x = a:cmd . ' - ' . a:fname
+  endif
+  return x
+endfunction
+
+" Find composing type in "lead" and match items[0] with it.
+" Repeat this recursively for items[1], if it's there.
+" When resolving typedefs "depth" is used to avoid infinite recursion.
+" Return the list of matches.
+function! s:Nextitem(lead, items, depth, all)
+
+  " Use the text up to the variable name and split it in tokens.
+  let tokens = split(a:lead, '\s\+\|\<')
+
+  " Try to recognize the type of the variable.  This is rough guessing...
+  let res = []
+  for tidx in range(len(tokens))
+
+    " Skip tokens starting with a non-ID character.
+    if tokens[tidx] !~ '^\h'
+      continue
+    endif
+
+    " Recognize "struct foobar" and "union foobar".
+    " Also do "class foobar" when it's C++ after all (doesn't work very well
+    " though).
+    if (tokens[tidx] == 'struct' || tokens[tidx] == 'union' || tokens[tidx] == 'class') && tidx + 1 < len(tokens)
+      let res = s:StructMembers(tokens[tidx] . ':' . tokens[tidx + 1], a:items, a:all)
+      break
+    endif
+
+    " TODO: add more reserved words
+    if index(['int', 'short', 'char', 'float', 'double', 'static', 'unsigned', 'extern'], tokens[tidx]) >= 0
+      continue
+    endif
+
+    " Use the tags file to find out if this is a typedef.
+    let diclist = taglist('^' . tokens[tidx] . '$')
+    for tagidx in range(len(diclist))
+      let item = diclist[tagidx]
+
+      " New ctags has the "typeref" field.  Patched version has "typename".
+      if has_key(item, 'typeref')
+	call extend(res, s:StructMembers(item['typeref'], a:items, a:all))
+	continue
+      endif
+      if has_key(item, 'typename')
+	call extend(res, s:StructMembers(item['typename'], a:items, a:all))
+	continue
+      endif
+
+      " Only handle typedefs here.
+      if item['kind'] != 't'
+	continue
+      endif
+
+      " Skip matches local to another file.
+      if has_key(item, 'static') && item['static'] && bufnr('%') != bufnr(item['filename'])
+	continue
+      endif
+
+      " For old ctags we recognize "typedef struct aaa" and
+      " "typedef union bbb" in the tags file command.
+      let cmd = item['cmd']
+      let ei = matchend(cmd, 'typedef\s\+')
+      if ei > 1
+	let cmdtokens = split(strpart(cmd, ei), '\s\+\|\<')
+	if len(cmdtokens) > 1
+	  if cmdtokens[0] == 'struct' || cmdtokens[0] == 'union' || cmdtokens[0] == 'class'
+	    let name = ''
+	    " Use the first identifier after the "struct" or "union"
+	    for ti in range(len(cmdtokens) - 1)
+	      if cmdtokens[ti] =~ '^\w'
+		let name = cmdtokens[ti]
+		break
+	      endif
+	    endfor
+	    if name != ''
+	      call extend(res, s:StructMembers(cmdtokens[0] . ':' . name, a:items, a:all))
+	    endif
+	  elseif a:depth < 10
+	    " Could be "typedef other_T some_T".
+	    call extend(res, s:Nextitem(cmdtokens[0], a:items, a:depth + 1, a:all))
+	  endif
+	endif
+      endif
+    endfor
+    if len(res) > 0
+      break
+    endif
+  endfor
+
+  return res
+endfunction
+
+
+" Search for members of structure "typename" in tags files.
+" Return a list with resulting matches.
+" Each match is a dictionary with "match" and "tagline" entries.
+" When "all" is non-zero find all, otherwise just return 1 if there is any
+" member.
+function! s:StructMembers(typename, items, all)
+  " Todo: What about local structures?
+  let fnames = join(map(tagfiles(), 'escape(v:val, " \\#%")'))
+  if fnames == ''
+    return []
+  endif
+
+  let typename = a:typename
+  let qflist = []
+  let cached = 0
+  if a:all == 0
+    let n = '1'	" stop at first found match
+    if has_key(s:grepCache, a:typename)
+      let qflist = s:grepCache[a:typename]
+      let cached = 1
+    endif
+  else
+    let n = ''
+  endif
+  if !cached
+    while 1
+      exe 'silent! ' . n . 'vimgrep /\t' . typename . '\(\t\|$\)/j ' . fnames
+
+      let qflist = getqflist()
+      if len(qflist) > 0 || match(typename, "::") < 0
+	break
+      endif
+      " No match for "struct:context::name", remove "context::" and try again.
+      let typename = substitute(typename, ':[^:]*::', ':', '')
+    endwhile
+
+    if a:all == 0
+      " Store the result to be able to use it again later.
+      let s:grepCache[a:typename] = qflist
+    endif
+  endif
+
+  " Put matching members in matches[].
+  let matches = []
+  for l in qflist
+    let memb = matchstr(l['text'], '[^\t]*')
+    if memb =~ '^' . a:items[0]
+      " Skip matches local to another file.
+      if match(l['text'], "\tfile:") < 0 || bufnr('%') == bufnr(matchstr(l['text'], '\t\zs[^\t]*'))
+	let item = {'match': memb, 'tagline': l['text']}
+
+	" Add the kind of item.
+	let s = matchstr(l['text'], '\t\(kind:\)\=\zs\S\ze\(\t\|$\)')
+	if s != ''
+	  let item['kind'] = s
+	  if s == 'f'
+	    let item['match'] = memb . '('
+	  endif
+	endif
+
+	call add(matches, item)
+      endif
+    endif
+  endfor
+
+  if len(matches) > 0
+    " Skip over [...] items
+    let idx = 1
+    while 1
+      if idx >= len(a:items)
+	return matches		" No further items, return the result.
+      endif
+      if a:items[idx][0] != '['
+	break
+      endif
+      let idx += 1
+    endwhile
+
+    " More items following.  For each of the possible members find the
+    " matching following members.
+    return s:SearchMembers(matches, a:items[idx :], a:all)
+  endif
+
+  " Failed to find anything.
+  return []
+endfunction
+
+" For matching members, find matches for following items.
+" When "all" is non-zero find all, otherwise just return 1 if there is any
+" member.
+function! s:SearchMembers(matches, items, all)
+  let res = []
+  for i in range(len(a:matches))
+    let typename = ''
+    if has_key(a:matches[i], 'dict')
+      if has_key(a:matches[i].dict, 'typename')
+	let typename = a:matches[i].dict['typename']
+      elseif has_key(a:matches[i].dict, 'typeref')
+	let typename = a:matches[i].dict['typeref']
+      endif
+      let line = "\t" . a:matches[i].dict['cmd']
+    else
+      let line = a:matches[i]['tagline']
+      let e = matchend(line, '\ttypename:')
+      if e < 0
+	let e = matchend(line, '\ttyperef:')
+      endif
+      if e > 0
+	" Use typename field
+	let typename = matchstr(line, '[^\t]*', e)
+      endif
+    endif
+
+    if typename != ''
+      call extend(res, s:StructMembers(typename, a:items, a:all))
+    else
+      " Use the search command (the declaration itself).
+      let s = match(line, '\t\zs/^')
+      if s > 0
+	let e = match(line, '\<' . a:matches[i]['match'] . '\>', s)
+	if e > 0
+	  call extend(res, s:Nextitem(strpart(line, s, e - s), a:items, 0, a:all))
+	endif
+      endif
+    endif
+    if a:all == 0 && len(res) > 0
+      break
+    endif
+  endfor
+  return res
+endfunc
--- /dev/null
+++ b/lib/vimfiles/autoload/csscomplete.vim
@@ -1,0 +1,429 @@
+" Vim completion script
+" Language:	CSS 2.1
+" Maintainer:	Mikolaj Machowski ( mikmach AT wp DOT pl )
+" Last Change:	2007 May 5
+
+	let s:values = split("azimuth background background-attachment background-color background-image background-position background-repeat border bottom border-collapse border-color border-spacing border-style border-top border-right border-bottom border-left border-top-color border-right-color border-bottom-color border-left-color  border-top-style border-right-style border-bottom-style border-left-style border-top-width border-right-width border-bottom-width border-left-width border-width caption-side clear clip color content counter-increment counter-reset cue cue-after cue-before cursor display direction elevation empty-cells float font font-family font-size font-style font-variant font-weight height left letter-spacing line-height list-style list-style-image list-style-position list-style-type margin margin-right margin-left margin-top margin-bottom max-height max-width min-height min-width orphans outline outline-color outline-style outline-width overflow padding padding-top padding-right padding-bottom padding-left page-break-after page-break-before page-break-inside pause pause-after pause-before pitch pitch-range play-during position quotes right richness speak speak-header speak-numeral speak-punctuation speech-rate stress table-layout text-align text-decoration text-indent text-transform top unicode-bidi vertical-align visibility voice-family volume white-space width widows word-spacing z-index")
+
+function! csscomplete#CompleteCSS(findstart, base)
+
+if a:findstart
+	" We need whole line to proper checking
+	let line = getline('.')
+	let start = col('.') - 1
+	let compl_begin = col('.') - 2
+	while start >= 0 && line[start - 1] =~ '\%(\k\|-\)'
+		let start -= 1
+	endwhile
+	let b:compl_context = line[0:compl_begin]
+	return start
+endif
+
+" There are few chars important for context:
+" ^ ; : { } /* */
+" Where ^ is start of line and /* */ are comment borders
+" Depending on their relative position to cursor we will know what should
+" be completed. 
+" 1. if nearest are ^ or { or ; current word is property
+" 2. if : it is value (with exception of pseudo things)
+" 3. if } we are outside of css definitions
+" 4. for comments ignoring is be the easiest but assume they are the same
+"    as 1. 
+" 5. if @ complete at-rule
+" 6. if ! complete important
+if exists("b:compl_context")
+	let line = b:compl_context
+	unlet! b:compl_context
+else
+	let line = a:base
+endif
+
+let res = []
+let res2 = []
+let borders = {}
+
+" Check last occurrence of sequence
+
+let openbrace  = strridx(line, '{')
+let closebrace = strridx(line, '}')
+let colon      = strridx(line, ':')
+let semicolon  = strridx(line, ';')
+let opencomm   = strridx(line, '/*')
+let closecomm  = strridx(line, '*/')
+let style      = strridx(line, 'style\s*=')
+let atrule     = strridx(line, '@')
+let exclam     = strridx(line, '!')
+
+if openbrace > -1
+	let borders[openbrace] = "openbrace"
+endif
+if closebrace > -1
+	let borders[closebrace] = "closebrace"
+endif
+if colon > -1
+	let borders[colon] = "colon"
+endif
+if semicolon > -1
+	let borders[semicolon] = "semicolon"
+endif
+if opencomm > -1
+	let borders[opencomm] = "opencomm"
+endif
+if closecomm > -1
+	let borders[closecomm] = "closecomm"
+endif
+if style > -1
+	let borders[style] = "style"
+endif
+if atrule > -1
+	let borders[atrule] = "atrule"
+endif
+if exclam > -1
+	let borders[exclam] = "exclam"
+endif
+
+
+if len(borders) == 0 || borders[max(keys(borders))] =~ '^\%(openbrace\|semicolon\|opencomm\|closecomm\|style\)$'
+	" Complete properties
+
+
+	let entered_property = matchstr(line, '.\{-}\zs[a-zA-Z-]*$')
+
+	for m in s:values
+		if m =~? '^'.entered_property
+			call add(res, m . ':')
+		elseif m =~? entered_property
+			call add(res2, m . ':')
+		endif
+	endfor
+
+	return res + res2
+
+elseif borders[max(keys(borders))] == 'colon'
+	" Get name of property
+	let prop = tolower(matchstr(line, '\zs[a-zA-Z-]*\ze\s*:[^:]\{-}$'))
+
+	if prop == 'azimuth'
+		let values = ["left-side", "far-left", "left", "center-left", "center", "center-right", "right", "far-right", "right-side", "behind", "leftwards", "rightwards"]
+	elseif prop == 'background-attachment'
+		let values = ["scroll", "fixed"]
+	elseif prop == 'background-color'
+		let values = ["transparent", "rgb(", "#"]
+	elseif prop == 'background-image'
+		let values = ["url(", "none"]
+	elseif prop == 'background-position'
+		let vals = matchstr(line, '.*:\s*\zs.*')
+		if vals =~ '^\%([a-zA-Z]\+\)\?$'
+			let values = ["top", "center", "bottom"]
+		elseif vals =~ '^[a-zA-Z]\+\s\+\%([a-zA-Z]\+\)\?$'
+			let values = ["left", "center", "right"]
+		else
+			return []
+		endif
+	elseif prop == 'background-repeat'
+		let values = ["repeat", "repeat-x", "repeat-y", "no-repeat"]
+	elseif prop == 'background'
+		let values = ["url(", "scroll", "fixed", "transparent", "rgb(", "#", "none", "top", "center", "bottom" , "left", "right", "repeat", "repeat-x", "repeat-y", "no-repeat"]
+	elseif prop == 'border-collapse'
+		let values = ["collapse", "separate"]
+	elseif prop == 'border-color'
+		let values = ["rgb(", "#", "transparent"]
+	elseif prop == 'border-spacing'
+		return []
+	elseif prop == 'border-style'
+		let values = ["none", "hidden", "dotted", "dashed", "solid", "double", "groove", "ridge", "inset", "outset"]
+	elseif prop =~ 'border-\%(top\|right\|bottom\|left\)$'
+		let vals = matchstr(line, '.*:\s*\zs.*')
+		if vals =~ '^\%([a-zA-Z0-9.]\+\)\?$'
+			let values = ["thin", "thick", "medium"]
+		elseif vals =~ '^[a-zA-Z0-9.]\+\s\+\%([a-zA-Z]\+\)\?$'
+			let values = ["none", "hidden", "dotted", "dashed", "solid", "double", "groove", "ridge", "inset", "outset"]
+		elseif vals =~ '^[a-zA-Z0-9.]\+\s\+[a-zA-Z]\+\s\+\%([a-zA-Z(]\+\)\?$'
+			let values = ["rgb(", "#", "transparent"]
+		else
+			return []
+		endif
+	elseif prop =~ 'border-\%(top\|right\|bottom\|left\)-color'
+		let values = ["rgb(", "#", "transparent"]
+	elseif prop =~ 'border-\%(top\|right\|bottom\|left\)-style'
+		let values = ["none", "hidden", "dotted", "dashed", "solid", "double", "groove", "ridge", "inset", "outset"]
+	elseif prop =~ 'border-\%(top\|right\|bottom\|left\)-width'
+		let values = ["thin", "thick", "medium"]
+	elseif prop == 'border-width'
+		let values = ["thin", "thick", "medium"]
+	elseif prop == 'border'
+		let vals = matchstr(line, '.*:\s*\zs.*')
+		if vals =~ '^\%([a-zA-Z0-9.]\+\)\?$'
+			let values = ["thin", "thick", "medium"]
+		elseif vals =~ '^[a-zA-Z0-9.]\+\s\+\%([a-zA-Z]\+\)\?$'
+			let values = ["none", "hidden", "dotted", "dashed", "solid", "double", "groove", "ridge", "inset", "outset"]
+		elseif vals =~ '^[a-zA-Z0-9.]\+\s\+[a-zA-Z]\+\s\+\%([a-zA-Z(]\+\)\?$'
+			let values = ["rgb(", "#", "transparent"]
+		else
+			return []
+		endif
+	elseif prop == 'bottom'
+		let values = ["auto"]
+	elseif prop == 'caption-side'
+		let values = ["top", "bottom"]
+	elseif prop == 'clear'
+		let values = ["none", "left", "right", "both"]
+	elseif prop == 'clip'
+		let values = ["auto", "rect("]
+	elseif prop == 'color'
+		let values = ["rgb(", "#"]
+	elseif prop == 'content'
+		let values = ["normal", "attr(", "open-quote", "close-quote", "no-open-quote", "no-close-quote"]
+	elseif prop =~ 'counter-\%(increment\|reset\)$'
+		let values = ["none"]
+	elseif prop =~ '^\%(cue-after\|cue-before\|cue\)$'
+		let values = ["url(", "none"]
+	elseif prop == 'cursor'
+		let values = ["url(", "auto", "crosshair", "default", "pointer", "move", "e-resize", "ne-resize", "nw-resize", "n-resize", "se-resize", "sw-resize", "s-resize", "w-resize", "text", "wait", "help", "progress"]
+	elseif prop == 'direction'
+		let values = ["ltr", "rtl"]
+	elseif prop == 'display'
+		let values = ["inline", "block", "list-item", "run-in", "inline-block", "table", "inline-table", "table-row-group", "table-header-group", "table-footer-group", "table-row", "table-column-group", "table-column", "table-cell", "table-caption", "none"]
+	elseif prop == 'elevation'
+		let values = ["below", "level", "above", "higher", "lower"]
+	elseif prop == 'empty-cells'
+		let values = ["show", "hide"]
+	elseif prop == 'float'
+		let values = ["left", "right", "none"]
+	elseif prop == 'font-family'
+		let values = ["sans-serif", "serif", "monospace", "cursive", "fantasy"]
+	elseif prop == 'font-size'
+		 let values = ["xx-small", "x-small", "small", "medium", "large", "x-large", "xx-large", "larger", "smaller"]
+	elseif prop == 'font-style'
+		let values = ["normal", "italic", "oblique"]
+	elseif prop == 'font-variant'
+		let values = ["normal", "small-caps"]
+	elseif prop == 'font-weight'
+		let values = ["normal", "bold", "bolder", "lighter", "100", "200", "300", "400", "500", "600", "700", "800", "900"]
+	elseif prop == 'font'
+		let values = ["normal", "italic", "oblique", "small-caps", "bold", "bolder", "lighter", "100", "200", "300", "400", "500", "600", "700", "800", "900", "xx-small", "x-small", "small", "medium", "large", "x-large", "xx-large", "larger", "smaller", "sans-serif", "serif", "monospace", "cursive", "fantasy", "caption", "icon", "menu", "message-box", "small-caption", "status-bar"]
+	elseif prop =~ '^\%(height\|width\)$'
+		let values = ["auto"]
+	elseif prop =~ '^\%(left\|rigth\)$'
+		let values = ["auto"]
+	elseif prop == 'letter-spacing'
+		let values = ["normal"]
+	elseif prop == 'line-height'
+		let values = ["normal"]
+	elseif prop == 'list-style-image'
+		let values = ["url(", "none"]
+	elseif prop == 'list-style-position'
+		let values = ["inside", "outside"]
+	elseif prop == 'list-style-type'
+		let values = ["disc", "circle", "square", "decimal", "decimal-leading-zero", "lower-roman", "upper-roman", "lower-latin", "upper-latin", "none"]
+	elseif prop == 'list-style'
+		return []
+	elseif prop == 'margin'
+		let values = ["auto"]
+	elseif prop =~ 'margin-\%(right\|left\|top\|bottom\)$'
+		let values = ["auto"]
+	elseif prop == 'max-height'
+		let values = ["auto"]
+	elseif prop == 'max-width'
+		let values = ["none"]
+	elseif prop == 'min-height'
+		let values = ["none"]
+	elseif prop == 'min-width'
+		let values = ["none"]
+	elseif prop == 'orphans'
+		return []
+	elseif prop == 'outline-color'
+		let values = ["rgb(", "#"]
+	elseif prop == 'outline-style'
+		let values = ["none", "hidden", "dotted", "dashed", "solid", "double", "groove", "ridge", "inset", "outset"]
+	elseif prop == 'outline-width'
+		let values = ["thin", "thick", "medium"]
+	elseif prop == 'outline'
+		let vals = matchstr(line, '.*:\s*\zs.*')
+		if vals =~ '^\%([a-zA-Z0-9,()#]\+\)\?$'
+			let values = ["rgb(", "#"]
+		elseif vals =~ '^[a-zA-Z0-9,()#]\+\s\+\%([a-zA-Z]\+\)\?$'
+			let values = ["none", "hidden", "dotted", "dashed", "solid", "double", "groove", "ridge", "inset", "outset"]
+		elseif vals =~ '^[a-zA-Z0-9,()#]\+\s\+[a-zA-Z]\+\s\+\%([a-zA-Z(]\+\)\?$'
+			let values = ["thin", "thick", "medium"]
+		else
+			return []
+		endif
+	elseif prop == 'overflow'
+		let values = ["visible", "hidden", "scroll", "auto"]
+	elseif prop == 'padding'
+		return []
+	elseif prop =~ 'padding-\%(top\|right\|bottom\|left\)$'
+		return []
+	elseif prop =~ 'page-break-\%(after\|before\)$'
+		let values = ["auto", "always", "avoid", "left", "right"]
+	elseif prop == 'page-break-inside'
+		let values = ["auto", "avoid"]
+	elseif prop =~ 'pause-\%(after\|before\)$'
+		return []
+	elseif prop == 'pause'
+		return []
+	elseif prop == 'pitch-range'
+		return []
+	elseif prop == 'pitch'
+		let values = ["x-low", "low", "medium", "high", "x-high"]
+	elseif prop == 'play-during'
+		let values = ["url(", "mix", "repeat", "auto", "none"]
+	elseif prop == 'position'
+		let values = ["static", "relative", "absolute", "fixed"]
+	elseif prop == 'quotes'
+		let values = ["none"]
+	elseif prop == 'richness'
+		return []
+	elseif prop == 'speak-header'
+		let values = ["once", "always"]
+	elseif prop == 'speak-numeral'
+		let values = ["digits", "continuous"]
+	elseif prop == 'speak-punctuation'
+		let values = ["code", "none"]
+	elseif prop == 'speak'
+		let values = ["normal", "none", "spell-out"]
+	elseif prop == 'speech-rate'
+		let values = ["x-slow", "slow", "medium", "fast", "x-fast", "faster", "slower"]
+	elseif prop == 'stress'
+		return []
+	elseif prop == 'table-layout'
+		let values = ["auto", "fixed"]
+	elseif prop == 'text-align'
+		let values = ["left", "right", "center", "justify"]
+	elseif prop == 'text-decoration'
+		let values = ["none", "underline", "overline", "line-through", "blink"]
+	elseif prop == 'text-indent'
+		return []
+	elseif prop == 'text-transform'
+		let values = ["capitalize", "uppercase", "lowercase", "none"]
+	elseif prop == 'top'
+		let values = ["auto"]
+	elseif prop == 'unicode-bidi'
+		let values = ["normal", "embed", "bidi-override"]
+	elseif prop == 'vertical-align'
+		let values = ["baseline", "sub", "super", "top", "text-top", "middle", "bottom", "text-bottom"]
+	elseif prop == 'visibility'
+		let values = ["visible", "hidden", "collapse"]
+	elseif prop == 'voice-family'
+		return []
+	elseif prop == 'volume'
+		let values = ["silent", "x-soft", "soft", "medium", "loud", "x-loud"]
+	elseif prop == 'white-space'
+		let values = ["normal", "pre", "nowrap", "pre-wrap", "pre-line"]
+	elseif prop == 'widows'
+		return []
+	elseif prop == 'word-spacing'
+		let values = ["normal"]
+	elseif prop == 'z-index'
+		let values = ["auto"]
+	else
+		" If no property match it is possible we are outside of {} and
+		" trying to complete pseudo-(class|element)
+		let element = tolower(matchstr(line, '\zs[a-zA-Z1-6]*\ze:[^:[:space:]]\{-}$'))
+		if stridx(',a,abbr,acronym,address,area,b,base,bdo,big,blockquote,body,br,button,caption,cite,code,col,colgroup,dd,del,dfn,div,dl,dt,em,fieldset,form,head,h1,h2,h3,h4,h5,h6,hr,html,i,img,input,ins,kbd,label,legend,li,link,map,meta,noscript,object,ol,optgroup,option,p,param,pre,q,samp,script,select,small,span,strong,style,sub,sup,table,tbody,td,textarea,tfoot,th,thead,title,tr,tt,ul,var,', ','.element.',') > -1
+			let values = ["first-child", "link", "visited", "hover", "active", "focus", "lang", "first-line", "first-letter", "before", "after"]
+		else
+			return []
+		endif
+	endif
+
+	" Complete values
+	let entered_value = matchstr(line, '.\{-}\zs[a-zA-Z0-9#,.(_-]*$')
+
+	for m in values
+		if m =~? '^'.entered_value
+			call add(res, m)
+		elseif m =~? entered_value
+			call add(res2, m)
+		endif
+	endfor
+
+	return res + res2
+
+elseif borders[max(keys(borders))] == 'closebrace'
+
+	return []
+
+elseif borders[max(keys(borders))] == 'exclam'
+
+	" Complete values
+	let entered_imp = matchstr(line, '.\{-}!\s*\zs[a-zA-Z ]*$')
+
+	let values = ["important"]
+
+	for m in values
+		if m =~? '^'.entered_imp
+			call add(res, m)
+		endif
+	endfor
+
+	return res
+
+elseif borders[max(keys(borders))] == 'atrule'
+
+	let afterat = matchstr(line, '.*@\zs.*')
+
+	if afterat =~ '\s'
+
+		let atrulename = matchstr(line, '.*@\zs[a-zA-Z-]\+\ze')
+
+		if atrulename == 'media'
+			let values = ["screen", "tty", "tv", "projection", "handheld", "print", "braille", "aural", "all"]
+
+			let entered_atruleafter = matchstr(line, '.*@media\s\+\zs.*$')
+
+		elseif atrulename == 'import'
+			let entered_atruleafter = matchstr(line, '.*@import\s\+\zs.*$')
+
+			if entered_atruleafter =~ "^[\"']"
+				let filestart = matchstr(entered_atruleafter, '^.\zs.*')
+				let files = split(glob(filestart.'*'), '\n')
+				let values = map(copy(files), '"\"".v:val')
+
+			elseif entered_atruleafter =~ "^url("
+				let filestart = matchstr(entered_atruleafter, "^url([\"']\\?\\zs.*")
+				let files = split(glob(filestart.'*'), '\n')
+				let values = map(copy(files), '"url(".v:val')
+				
+			else
+				let values = ['"', 'url(']
+
+			endif
+
+		else
+			return []
+
+		endif
+
+		for m in values
+			if m =~? '^'.entered_atruleafter
+				call add(res, m)
+			elseif m =~? entered_atruleafter
+				call add(res2, m)
+			endif
+		endfor
+
+		return res + res2
+
+	endif
+
+	let values = ["charset", "page", "media", "import", "font-face"]
+
+	let entered_atrule = matchstr(line, '.*@\zs[a-zA-Z-]*$')
+
+	for m in values
+		if m =~? '^'.entered_atrule
+			call add(res, m .' ')
+		elseif m =~? entered_atrule
+			call add(res2, m .' ')
+		endif
+	endfor
+
+	return res + res2
+
+endif
+
+return []
+
+endfunction
--- /dev/null
+++ b/lib/vimfiles/autoload/decada.vim
@@ -1,0 +1,75 @@
+"------------------------------------------------------------------------------
+"  Description: Vim Ada/Dec Ada compiler file
+"     Language: Ada (Dec Ada)
+"          $Id: decada.vim,v 1.1 2007/05/05 17:25:32 vimboss Exp $
+"    Copyright: Copyright (C) 2006 Martin Krischik
+"   Maintainer:	Martin Krischik
+"      $Author: vimboss $
+"        $Date: 2007/05/05 17:25:32 $
+"      Version: 4.2
+"    $Revision: 1.1 $
+"     $HeadURL: https://svn.sourceforge.net/svnroot/gnuada/trunk/tools/vim/autoload/decada.vim $
+"      History: 21.07.2006 MK New Dec Ada
+"               15.10.2006 MK Bram's suggestion for runtime integration
+"               05.11.2006 MK Bram suggested not to use include protection for
+"                             autoload
+"		05.11.2006 MK Bram suggested to save on spaces
+"    Help Page: compiler-decada
+"------------------------------------------------------------------------------
+
+if version < 700
+   finish
+endif
+
+function decada#Unit_Name () dict				     " {{{1
+    "	Convert filename into acs unit:
+    "	    1:  remove the file extenstion.
+    "	    2:  replace all double '_' or '-' with an dot (which denotes a separate)
+    "	    3:  remove a trailing '_' (wich denotes a specification)
+    return substitute (substitute (expand ("%:t:r"), '__\|-', ".", "g"), '_$', "", '')
+endfunction decada#Unit_Name					     " }}}1
+
+function decada#Make () dict					     " {{{1
+    let l:make_prg   = substitute (g:self.Make_Command, '%<', self.Unit_Name(), '')
+    let &errorformat = g:self.Error_Format
+    let &makeprg     = l:make_prg
+    wall
+    make
+    copen
+    set wrap
+    wincmd W
+endfunction decada#Build					     " }}}1
+
+function decada#Set_Session (...) dict				     " {{{1
+   if a:0 > 0
+      call ada#Switch_Session (a:1)
+   elseif argc() == 0 && strlen (v:servername) > 0
+      call ada#Switch_Session (
+	 \ expand('~')[0:-2] . ".vimfiles.session]" .
+	 \ v:servername . ".vim")
+   endif
+   return
+endfunction decada#Set_Session					     " }}}1
+
+function decada#New ()						     " }}}1
+   let Retval = {
+      \ 'Make'		: function ('decada#Make'),
+      \ 'Unit_Name'	: function ('decada#Unit_Name'),
+      \ 'Set_Session'   : function ('decada#Set_Session'),
+      \ 'Project_Dir'   : '',
+      \ 'Make_Command'  : 'ACS COMPILE /Wait /Log /NoPreLoad /Optimize=Development /Debug %<',
+      \ 'Error_Format'  : '%+A%%ADAC-%t-%m,%C  %#%m,%Zat line number %l in file %f,' .
+			\ '%+I%%ada-I-%m,%C  %#%m,%Zat line number %l in file %f'}
+
+   return Retval 
+endfunction decada#New						     " }}}1
+
+finish " 1}}}
+
+"------------------------------------------------------------------------------
+"   Copyright (C) 2006  Martin Krischik
+"
+"   Vim is Charityware - see ":help license" or uganda.txt for licence details.
+"------------------------------------------------------------------------------
+" vim: textwidth=78 wrap tabstop=8 shiftwidth=3 softtabstop=3 noexpandtab
+" vim: foldmethod=marker
--- /dev/null
+++ b/lib/vimfiles/autoload/getscript.vim
@@ -1,0 +1,542 @@
+" ---------------------------------------------------------------------
+" getscript.vim
+"  Author:	Charles E. Campbell, Jr.
+"  Date:	May 11, 2007
+"  Version:	27
+"  Installing:	:help glvs-install
+"  Usage:	:help glvs
+"
+" GetLatestVimScripts: 642 1 :AutoInstall: getscript.vim
+"redraw!|call inputsave()|call input("Press <cr> to continue")|call inputrestore()
+" ---------------------------------------------------------------------
+" Initialization:	{{{1
+" if you're sourcing this file, surely you can't be
+" expecting vim to be in its vi-compatible mode
+if &cp
+ echoerr "GetLatestVimScripts is not vi-compatible; not loaded (you need to set nocp)"
+ finish
+endif
+let s:keepcpo = &cpo
+set cpo&vim
+"DechoTabOn
+
+if exists("g:loaded_getscript")
+ finish
+endif
+let g:loaded_getscript= "v27"
+
+" ---------------------------------------------------------------------
+"  Global Variables: {{{1
+" allow user to change the command for obtaining scripts (does fetch work?)
+if !exists("g:GetLatestVimScripts_wget")
+ if executable("wget")
+  let g:GetLatestVimScripts_wget= "wget"
+ elseif executable("curl")
+  let g:GetLatestVimScripts_wget= "curl"
+ else
+  let g:GetLatestVimScripts_wget    = 'echo "GetLatestVimScripts needs wget or curl"'
+  let g:GetLatestVimScripts_options = ""
+ endif
+endif
+
+" options that wget and curl require:
+if !exists("g:GetLatestVimScripts_options")
+ if g:GetLatestVimScripts_wget == "wget"
+  let g:GetLatestVimScripts_options= "-q -O"
+ elseif g:GetLatestVimScripts_wget == "curl"
+  let g:GetLatestVimScripts_options= "-s -O"
+ else
+  let g:GetLatestVimScripts_options= ""
+ endif
+endif
+
+" by default, allow autoinstall lines to work
+if !exists("g:GetLatestVimScripts_allowautoinstall")
+ let g:GetLatestVimScripts_allowautoinstall= 1
+endif
+
+"" For debugging:
+"let g:GetLatestVimScripts_wget    = "echo"
+"let g:GetLatestVimScripts_options = "options"
+
+" ---------------------------------------------------------------------
+" Check If AutoInstall Capable: {{{1
+let s:autoinstall= ""
+if g:GetLatestVimScripts_allowautoinstall
+
+ if (has("win32") || has("gui_win32") || has("gui_win32s") || has("win16") || has("win64") || has("win32unix") || has("win95")) && &shell != "bash"
+  " windows (but not cygwin/bash)
+  let s:dotvim= "vimfiles"
+  if !exists("g:GetLatestVimScripts_mv")
+   let g:GetLatestVimScripts_mv= "ren"
+  endif
+
+ else
+  " unix
+  let s:dotvim= ".vim"
+  if !exists("g:GetLatestVimScripts_mv")
+   let g:GetLatestVimScripts_mv= "mv"
+  endif
+ endif
+
+ if exists('$HOME') && isdirectory(expand("$HOME")."/".s:dotvim)
+  let s:autoinstall= $HOME."/".s:dotvim
+ endif
+" call Decho("s:autoinstall<".s:autoinstall.">")
+"else "Decho
+" call Decho("g:GetLatestVimScripts_allowautoinstall=".g:GetLatestVimScripts_allowautoinstall.": :AutoInstall: disabled")
+endif
+
+" ---------------------------------------------------------------------
+"  Public Interface: {{{1
+com!        -nargs=0 GetLatestVimScripts call getscript#GetLatestVimScripts()
+com!        -nargs=0 GetScript           call getscript#GetLatestVimScripts()
+silent! com -nargs=0 GLVS                call getscript#GetLatestVimScripts()
+
+" ---------------------------------------------------------------------
+"  GetOneScript: (Get Latest Vim Script) this function operates {{{1
+"    on the current line, interpreting two numbers and text as
+"    ScriptID, SourceID, and Filename.
+"    It downloads any scripts that have newer versions from vim.sf.net.
+fun! s:GetOneScript(...)
+"   call Dfunc("GetOneScript()")
+
+ " set options to allow progress to be shown on screen
+  let t_ti= &t_ti
+  let t_te= &t_te
+  let rs  = &rs
+  set t_ti= t_te= nors
+
+ " put current line on top-of-screen and interpret it into
+ " a      script identifer  : used to obtain webpage
+ "        source identifier : used to identify current version
+ " and an associated comment: used to report on what's being considered
+  if a:0 >= 3
+   let scriptid = a:1
+   let srcid    = a:2
+   let fname    = a:3
+   let cmmnt    = ""
+"   call Decho("scriptid<".scriptid.">")
+"   call Decho("srcid   <".srcid.">")
+"   call Decho("fname   <".fname.">")
+  else
+   let curline  = getline(".")
+   if curline =~ '^\s*#'
+"    call Dret("GetOneScript : skipping a pure comment line")
+    return
+   endif
+   let parsepat = '^\s*\(\d\+\)\s\+\(\d\+\)\s\+\(.\{-}\)\(\s*#.*\)\=$'
+   try
+    let scriptid = substitute(curline,parsepat,'\1','e')
+   catch /^Vim\%((\a\+)\)\=:E486/
+    let scriptid= 0
+   endtry
+   try
+    let srcid    = substitute(curline,parsepat,'\2','e')
+   catch /^Vim\%((\a\+)\)\=:E486/
+    let srcid= 0
+   endtry
+   try
+    let fname= substitute(curline,parsepat,'\3','e')
+   catch /^Vim\%((\a\+)\)\=:E486/
+    let fname= ""
+   endtry
+   try
+    let cmmnt= substitute(curline,parsepat,'\4','e')
+   catch /^Vim\%((\a\+)\)\=:E486/
+    let cmmnt= ""
+   endtry
+"   call Decho("curline <".curline.">")
+"   call Decho("parsepat<".parsepat.">")
+"   call Decho("scriptid<".scriptid.">")
+"   call Decho("srcid   <".srcid.">")
+"   call Decho("fname   <".fname.">")
+  endif
+
+  if scriptid == 0 || srcid == 0
+   " When looking for :AutoInstall: lines, skip scripts that
+   " have  0 0 scriptname
+"   call Dret("GetOneScript : skipping a scriptid==srcid==0 line")
+   return
+  endif
+
+  let doautoinstall= 0
+  if fname =~ ":AutoInstall:"
+"   call Decho("fname<".fname."> has :AutoInstall:...")
+   let aicmmnt= substitute(fname,'\s\+:AutoInstall:\s\+',' ','')
+"   call Decho("aicmmnt<".aicmmnt."> s:autoinstall=".s:autoinstall)
+   if s:autoinstall != ""
+    let doautoinstall = g:GetLatestVimScripts_allowautoinstall
+   endif
+  else
+   let aicmmnt= fname
+  endif
+"  call Decho("aicmmnt<".aicmmnt.">: doautoinstall=".doautoinstall)
+
+  exe "norm z\<CR>"
+  redraw!
+"  call Decho('considering <'.aicmmnt.'> scriptid='.scriptid.' srcid='.srcid)
+  echomsg 'considering <'.aicmmnt.'> scriptid='.scriptid.' srcid='.srcid
+
+  " grab a copy of the plugin's vim.sf.net webpage
+  let scriptaddr = 'http://vim.sf.net/script.php?script_id='.scriptid
+  let tmpfile    = tempname()
+  let v:errmsg   = ""
+
+  " make up to three tries at downloading the description
+  let itry= 1
+  while itry <= 3
+"   	call Decho("try#".itry." to download description of <".aicmmnt."> with addr=".scriptaddr)
+  	if has("win32") || has("win16") || has("win95")
+"     call Decho("silent !".g:GetLatestVimScripts_wget." ".g:GetLatestVimScripts_options." ".tmpfile.' "'.scriptaddr.'"')
+     exe "silent !".g:GetLatestVimScripts_wget." ".g:GetLatestVimScripts_options." ".tmpfile.' "'.scriptaddr.'"'
+	else
+"     call Decho("silent !".g:GetLatestVimScripts_wget." ".g:GetLatestVimScripts_options." ".tmpfile." '".scriptaddr."'")
+     exe "silent !".g:GetLatestVimScripts_wget." ".g:GetLatestVimScripts_options." ".tmpfile." '".scriptaddr."'"
+	endif
+	if itry == 1
+    exe "silent vsplit ".tmpfile
+	else
+	 silent! e %
+	endif
+  
+   " find the latest source-id in the plugin's webpage
+   silent! 1
+   let findpkg= search('Click on the package to download','W')
+   if findpkg > 0
+    break
+   endif
+   let itry= itry + 1
+  endwhile
+"  call Decho(" --- end downloading tries while loop --- itry=".itry)
+
+  " testing: did finding "Click on the package..." fail?
+  if findpkg == 0 || itry >= 4
+    silent q!
+    call delete(tmpfile)
+   " restore options
+    let &t_ti        = t_ti
+    let &t_te        = t_te
+    let &rs          = rs
+    let s:downerrors = s:downerrors + 1
+"    call Decho("***warning*** couldn'".'t find "Click on the package..." in description page for <'.aicmmnt.">")
+    echomsg "***warning*** couldn'".'t find "Click on the package..." in description page for <'.aicmmnt.">"
+"    call Dret("GetOneScript : srch for /Click on the package/ failed")
+    return
+  endif
+"  call Decho('found "Click on the package to download"')
+
+  let findsrcid= search('src_id=','W')
+  if findsrcid == 0
+    silent q!
+    call delete(tmpfile)
+   " restore options
+	let &t_ti        = t_ti
+	let &t_te        = t_te
+	let &rs          = rs
+	let s:downerrors = s:downerrors + 1
+"  	call Decho("***warning*** couldn'".'t find "src_id=" in description page for <'.aicmmnt.">")
+  	echomsg "***warning*** couldn'".'t find "src_id=" in description page for <'.aicmmnt.">"
+"	call Dret("GetOneScript : srch for /src_id/ failed")
+  	return
+  endif
+"  call Decho('found "src_id=" in description page')
+
+  let srcidpat   = '^\s*<td class.*src_id=\(\d\+\)">\([^<]\+\)<.*$'
+  let latestsrcid= substitute(getline("."),srcidpat,'\1','')
+  let sname      = substitute(getline("."),srcidpat,'\2','') " script name actually downloaded
+"  call Decho("srcidpat<".srcidpat."> latestsrcid<".latestsrcid."> sname<".sname.">")
+  silent q!
+  call delete(tmpfile)
+
+  " convert the strings-of-numbers into numbers
+  let srcid       = srcid       + 0
+  let latestsrcid = latestsrcid + 0
+"  call Decho("srcid=".srcid." latestsrcid=".latestsrcid." sname<".sname.">")
+
+  " has the plugin's most-recent srcid increased, which indicates
+  " that it has been updated
+  if latestsrcid > srcid
+"   call Decho("[latestsrcid=".latestsrcid."] <= [srcid=".srcid."]: need to update <".sname.">")
+
+   let s:downloads= s:downloads + 1
+   if sname == bufname("%")
+    " GetLatestVimScript has to be careful about downloading itself
+    let sname= "NEW_".sname
+   endif
+
+   " the plugin has been updated since we last obtained it, so download a new copy
+"   call Decho("...downloading new <".sname.">")
+   echomsg "...downloading new <".sname.">"
+   if has("win32") || has("gui_win32") || has("gui_win32s") || has("win16") || has("win64") || has("win32unix") || has("win95")
+"    call Decho("windows: silent !".g:GetLatestVimScripts_wget." ".g:GetLatestVimScripts_options." ".sname.' "'.'http://vim.sf.net/scripts/download_script.php?src_id='.latestsrcid.'"')
+    exe "silent !".g:GetLatestVimScripts_wget." ".g:GetLatestVimScripts_options." ".sname.' "'.'http://vim.sf.net/scripts/download_script.php?src_id='.latestsrcid.'"'
+   else
+"    call Decho("unix: silent !".g:GetLatestVimScripts_wget." ".g:GetLatestVimScripts_options." ".sname." '".'http://vim.sf.net/scripts/download_script.php?src_id='.latestsrcid."'")
+    exe "silent !".g:GetLatestVimScripts_wget." ".g:GetLatestVimScripts_options." ".sname." '".'http://vim.sf.net/scripts/download_script.php?src_id='.latestsrcid."'"
+   endif
+
+   " AutoInstall: only if doautoinstall is so indicating
+   if doautoinstall
+"     call Decho("attempting to do autoinstall: getcwd<".getcwd()."> filereadable(".sname.")=".filereadable(sname))
+     if filereadable(sname)
+"       call Decho("move <".sname."> to ".s:autoinstall)
+       exe "silent !".g:GetLatestVimScripts_mv." ".sname." ".s:autoinstall
+       let curdir= escape(substitute(getcwd(),'\','/','ge'),"|[]*'\" #")
+"       call Decho("exe cd ".s:autoinstall)
+       exe "cd ".s:autoinstall
+      
+       " decompress
+       if sname =~ '\.bz2$'
+"         call Decho("decompress: attempt to bunzip2 ".sname)
+         exe "silent !bunzip2 ".sname
+         let sname= substitute(sname,'\.bz2$','','')
+"         call Decho("decompress: new sname<".sname."> after bunzip2")
+       elseif sname =~ '\.gz$'
+"         call Decho("decompress: attempt to gunzip ".sname)
+         exe "silent !gunzip ".sname
+         let sname= substitute(sname,'\.gz$','','')
+"         call Decho("decompress: new sname<".sname."> after gunzip")
+       endif
+      
+       " distribute archive(.zip, .tar, .vba) contents
+       if sname =~ '\.zip$'
+"         call Decho("dearchive: attempt to unzip ".sname)
+         exe "silent !unzip -o ".sname
+       elseif sname =~ '\.tar$'
+"         call Decho("dearchive: attempt to untar ".sname)
+         exe "silent !tar -xvf ".sname
+       elseif sname =~ '\.vba$'
+"         call Decho("dearchive: attempt to handle a vimball: ".sname)
+         silent 1split
+         exe "silent e ".sname
+         silent so %
+         silent q
+       endif
+      
+       if sname =~ '.vim$'
+"         call Decho("dearchive: attempt to simply move ".sname." to plugin")
+         exe "silent !".g:GetLatestVimScripts_mv." ".sname." plugin"
+       endif
+      
+       " helptags step
+       let docdir= substitute(&rtp,',.*','','e')."/doc"
+"       call Decho("helptags: docdir<".docdir.">")
+       exe "helptags ".docdir
+       exe "cd ".curdir
+     endif
+     if fname !~ ':AutoInstall:'
+      let modline=scriptid." ".latestsrcid." :AutoInstall: ".fname.cmmnt
+     else
+      let modline=scriptid." ".latestsrcid." ".fname.cmmnt
+     endif
+   else
+     let modline=scriptid." ".latestsrcid." ".fname.cmmnt
+   endif
+
+   " update the data in the <GetLatestVimScripts.dat> file
+   call setline(line("."),modline)
+"   call Decho("update data in ".expand("%")."#".line(".").": modline<".modline.">")
+"  else " Decho
+"   call Decho("[latestsrcid=".latestsrcid."] <= [srcid=".srcid."], no need to update")
+  endif
+
+ " restore options
+  let &t_ti= t_ti
+  let &t_te= t_te
+  let &rs  = rs
+
+"  call Dret("GetOneScript")
+endfun
+
+" ---------------------------------------------------------------------
+" GetLatestVimScripts: this function gets the latest versions of {{{1
+"                      scripts based on the list in
+"   (first dir in runtimepath)/GetLatest/GetLatestVimScripts.dat
+fun! getscript#GetLatestVimScripts()
+"  call Dfunc("GetLatestVimScripts() autoinstall<".s:autoinstall.">")
+
+" insure that wget is executable
+  if executable(g:GetLatestVimScripts_wget) != 1
+   echoerr "GetLatestVimScripts needs ".g:GetLatestVimScripts_wget." which apparently is not available on your system"
+"   call Dret("GetLatestVimScripts : wget not executable/availble")
+   return
+  endif
+
+  " Find the .../GetLatest subdirectory under the runtimepath
+  for datadir in split(&rtp,',') + ['']
+   if isdirectory(datadir."/GetLatest")
+"    call Decho("found directory<".datadir.">")
+    let datadir= datadir . "/GetLatest"
+    break
+   endif
+   if filereadable(datadir."GetLatestVimScripts.dat")
+"    call Decho("found ".datadir."/GetLatestVimScripts.dat")
+    break
+   endif
+  endfor
+
+  " Sanity checks: readability and writability
+  if datadir == ""
+   echoerr 'Missing "GetLatest/" on your runtimepath - see :help glvs-dist-install'
+"   call Dret("GetLatestVimScripts : unable to find a GetLatest subdirectory")
+   return
+  endif
+
+  if filewritable(datadir) != 2
+   echoerr "(getLatestVimScripts) Your ".datadir." isn't writable"
+"   call Dret("GetLatestVimScripts : non-writable directory<".datadir.">")
+   return
+  endif
+  let datafile= datadir."/GetLatestVimScripts.dat"
+  if !filereadable(datafile)
+   echoerr "Your data file<".datafile."> isn't readable"
+"   call Dret("GetLatestVimScripts : non-readable datafile<".datafile.">")
+   return
+  endif
+  if !filewritable(datafile)
+   echoerr "Your data file<".datafile."> isn't writable"
+"   call Dret("GetLatestVimScripts : non-writable datafile<".datafile.">")
+   return
+  endif
+"  call Decho("datadir  <".datadir.">")
+"  call Decho("datafile <".datafile.">")
+
+  " don't let any events interfere (like winmanager's, taglist's, etc)
+  let eikeep= &ei
+  set ei=all
+
+  " record current directory, change to datadir, open split window with
+  " datafile
+  let origdir= getcwd()
+  exe "cd ".escape(substitute(datadir,'\','/','ge'),"|[]*'\" #")
+  split
+  exe "e ".escape(substitute(datafile,'\','/','ge'),"|[]*'\" #")
+  res 1000
+  let s:downloads = 0
+  let s:downerrors= 0
+
+  " Check on dependencies mentioned in plugins
+"  call Decho(" ")
+"  call Decho("searching plugins for GetLatestVimScripts dependencies")
+  let lastline    = line("$")
+"  call Decho("lastline#".lastline)
+  let plugins     = split(globpath(&rtp,"plugin/*.vim"))
+  let foundscript = 0
+  let firstdir= ""
+
+  for plugin in plugins
+
+   " don't process plugins in system directories
+   if firstdir == ""
+    let firstdir= substitute(plugin,'[/\\][^/\\]\+$','','')
+"    call Decho("firstdir<".firstdir.">")
+   else
+    let curdir= substitute(plugin,'[/\\][^/\\]\+$','','')
+"    call Decho("curdir<".curdir.">")
+    if curdir != firstdir
+     break
+    endif
+   endif
+
+   " read plugin in
+   $
+"   call Decho(" ")
+"   call Decho(".dependency checking<".plugin."> line$=".line("$"))
+   exe "silent r ".plugin
+
+   while search('^"\s\+GetLatestVimScripts:\s\+\d\+\s\+\d\+','W') != 0
+    let newscript= substitute(getline("."),'^"\s\+GetLatestVimScripts:\s\+\d\+\s\+\d\+\s\+\(.*\)$','\1','e')
+    let llp1     = lastline+1
+"    call Decho("..newscript<".newscript.">")
+
+    " don't process ""GetLatestVimScripts lines
+    if newscript !~ '^"'
+     " found a "GetLatestVimScripts: # #" line in the script; check if its already in the datafile
+     let curline     = line(".")
+     let noai_script = substitute(newscript,'\s*:AutoInstall:\s*','','e')
+     exe llp1
+     let srchline    = search('\<'.noai_script.'\>','bW')
+"     call Decho("..noai_script<".noai_script."> srch=".srchline."curline#".line(".")." lastline#".lastline)
+
+     if srchline == 0
+      " found a new script to permanently include in the datafile
+      let keep_rega   = @a
+      let @a          = substitute(getline(curline),'^"\s\+GetLatestVimScripts:\s\+','','')
+      exe lastline."put a"
+      echomsg "Appending <".@a."> to ".datafile." for ".newscript
+"      call Decho("..APPEND (".noai_script.")<".@a."> to GetLatestVimScripts.dat")
+      let @a          = keep_rega
+      let lastline    = llp1
+      let curline     = curline     + 1
+      let foundscript = foundscript + 1
+"     else	" Decho
+"      call Decho("..found <".noai_script."> (already in datafile at line#".srchline.")")
+     endif
+
+     let curline = curline + 1
+     exe curline
+    endif
+   endwhile
+
+   let llp1= lastline + 1
+"   call Decho(".deleting lines: ".llp1.",$d")
+   exe "silent! ".llp1.",$d"
+  endfor
+"  call Decho("--- end dependency checking loop ---  foundscript=".foundscript)
+"  call Decho(" ")
+
+  if foundscript == 0
+   set nomod
+  endif
+
+  " Check on out-of-date scripts using GetLatest/GetLatestVimScripts.dat
+"  call Decho("begin: checking out-of-date scripts using datafile<".datafile.">")
+  set lz
+  1
+"  /^-----/,$g/^\s*\d/call Decho(getline("."))
+  1
+  /^-----/,$g/^\s*\d/call s:GetOneScript()
+"  call Decho("--- end out-of-date checking --- ")
+
+  " Final report (an echomsg)
+  try
+   silent! ?^-------?
+  catch /^Vim\%((\a\+)\)\=:E114/
+"   call Dret("GetLatestVimScripts : nothing done!")
+   return
+  endtry
+  exe "norm! kz\<CR>"
+  redraw!
+  let s:msg = ""
+  if s:downloads == 1
+  let s:msg = "Downloaded one updated script to <".datadir.">"
+  elseif s:downloads == 2
+   let s:msg= "Downloaded two updated scripts to <".datadir.">"
+  elseif s:downloads > 1
+   let s:msg= "Downloaded ".s:downloads." updated scripts to <".datadir.">"
+  else
+   let s:msg= "Everything was already current"
+  endif
+  if s:downerrors > 0
+   let s:msg= s:msg." (".s:downerrors." downloading errors)"
+  endif
+  echomsg s:msg
+  " save the file
+  if &mod
+   silent! w!
+  endif
+  q
+
+  " restore events and current directory
+  exe "cd ".escape(substitute(origdir,'\','/','ge'),"|[]*'\" #")
+  let &ei= eikeep
+  set nolz
+"  call Dret("GetLatestVimScripts : did ".s:downloads." downloads")
+endfun
+" ---------------------------------------------------------------------
+
+" Restore Options: {{{1
+let &cpo= s:keepcpo
+
+" vim: ts=8 sts=2 fdm=marker nowrap
--- /dev/null
+++ b/lib/vimfiles/autoload/gnat.vim
@@ -1,0 +1,139 @@
+"------------------------------------------------------------------------------
+"  Description: Vim Ada/GNAT compiler file
+"     Language: Ada (GNAT)
+"          $Id: gnat.vim,v 1.1 2007/05/05 18:18:20 vimboss Exp $
+"    Copyright: Copyright (C) 2006 Martin Krischik
+"   Maintainer:	Martin Krischik
+"      $Author: vimboss $
+"        $Date: 2007/05/05 18:18:20 $
+"      Version: 4.2
+"    $Revision: 1.1 $
+"     $HeadURL: https://svn.sourceforge.net/svnroot/gnuada/trunk/tools/vim/autoload/gnat.vim $
+"      History: 24.05.2006 MK Unified Headers
+"		16.07.2006 MK Ada-Mode as vim-ball
+"		05.08.2006 MK Add session support
+"               15.10.2006 MK Bram's suggestion for runtime integration
+"               05.11.2006 MK Bram suggested not to use include protection for
+"                             autoload
+"		05.11.2006 MK Bram suggested to save on spaces
+"    Help Page: compiler-gnat
+"------------------------------------------------------------------------------
+
+if version < 700
+    finish
+endif
+
+function gnat#Make () dict					     " {{{1
+   let &l:makeprg	 = self.Get_Command('Make')
+   let &l:errorformat = self.Error_Format
+   wall
+   make
+   copen
+   set wrap
+   wincmd W
+endfunction gnat#Make						     " }}}1
+
+function gnat#Pretty () dict					     " {{{1
+   execute "!" . self.Get_Command('Pretty')
+endfunction gnat#Make						     " }}}1
+
+function gnat#Find () dict					     " {{{1
+   execute "!" . self.Get_Command('Find')
+endfunction gnat#Find						     " }}}1
+
+function gnat#Tags () dict					     " {{{1
+   execute "!" . self.Get_Command('Tags')
+   edit tags
+   call gnat#Insert_Tags_Header ()
+   update
+   quit
+endfunction gnat#Tags						     " }}}1
+
+function gnat#Set_Project_File (...) dict			     " {{{1
+   if a:0 > 0
+      let self.Project_File = a:1
+
+      if ! filereadable (self.Project_File)
+	 let self.Project_File = findfile (
+	    \ fnamemodify (self.Project_File, ':r'),
+	    \ $ADA_PROJECT_PATH,
+	    \ 1)
+      endif
+   elseif strlen (self.Project_File) > 0
+      let self.Project_File = browse (0, 'GNAT Project File?', '', self.Project_File)
+   elseif expand ("%:e") == 'gpr'
+      let self.Project_File = browse (0, 'GNAT Project File?', '', expand ("%:e"))
+   else
+      let self.Project_File = browse (0, 'GNAT Project File?', '', 'default.gpr')
+   endif
+
+   if strlen (v:this_session) > 0
+      execute 'mksession! ' . v:this_session
+   endif
+
+   if strlen (self.Project_File) > 0
+      call ada#Switch_Session (
+	 \ expand('~') . "/vimfiles/session/" .
+	 \ fnamemodify (self.Project_File, ":t:r") . ".vim")
+   else
+      call ada#Switch_Session ('')
+   endif
+
+   return
+endfunction gnat#Set_Project_File				     " }}}1
+
+function gnat#Get_Command (Command) dict			     " {{{1
+   let l:Command = eval ('self.' . a:Command . '_Command')
+   return eval (l:Command)
+endfunction gnat#Get_Command					     " }}}1
+
+function gnat#Set_Session (...) dict				     " {{{1
+   if argc() == 1 && fnamemodify (argv(0), ':e') == 'gpr'
+      call self.Set_Project_File (argv(0))
+   elseif  strlen (v:servername) > 0
+      call self.Set_Project_File (v:servername . '.gpr')
+   endif
+endfunction gnat#Set_Session					     " }}}1
+
+function gnat#New ()						     " {{{1
+   let l:Retval = {
+      \ 'Make'	      : function ('gnat#Make'),
+      \ 'Pretty'	      : function ('gnat#Pretty'),
+      \ 'Find'	      : function ('gnat#Find'),
+      \ 'Tags'	      : function ('gnat#Tags'),
+      \ 'Set_Project_File' : function ('gnat#Set_Project_File'),
+      \ 'Set_Session'      : function ('gnat#Set_Session'),
+      \ 'Get_Command'      : function ('gnat#Get_Command'),
+      \ 'Project_File'     : '',
+      \ 'Make_Command'     : '"gnat make -P " . self.Project_File . "  -F -gnatef  "',
+      \ 'Pretty_Command'   : '"gnat pretty -P " . self.Project_File . " "',
+      \ 'Find_Program'     : '"gnat find -P " . self.Project_File . " -F "',
+      \ 'Tags_Command'     : '"gnat xref -P " . self.Project_File . " -v  *.AD*"',
+      \ 'Error_Format'     : '%f:%l:%c: %trror: %m,'   .
+			   \ '%f:%l:%c: %tarning: %m,' .
+			   \ '%f:%l:%c: (%ttyle) %m'}
+
+   return l:Retval
+endfunction gnat#New						  " }}}1
+
+function gnat#Insert_Tags_Header ()				  " {{{1
+   1insert
+!_TAG_FILE_FORMAT       1	 /extended format; --format=1 will not append ;" to lines/
+!_TAG_FILE_SORTED       1	 /0=unsorted, 1=sorted, 2=foldcase/
+!_TAG_PROGRAM_AUTHOR    AdaCore	 /info@adacore.com/
+!_TAG_PROGRAM_NAME      gnatxref //
+!_TAG_PROGRAM_URL       http://www.adacore.com  /official site/
+!_TAG_PROGRAM_VERSION   5.05w   //
+.
+   return
+endfunction gnat#Insert_Tags_Header				  " }}}1
+
+finish " 1}}}
+
+"------------------------------------------------------------------------------
+"   Copyright (C) 2006  Martin Krischik
+"
+"   Vim is Charityware - see ":help license" or uganda.txt for licence details.
+"------------------------------------------------------------------------------
+" vim: textwidth=0 wrap tabstop=8 shiftwidth=3 softtabstop=3 noexpandtab
+" vim: foldmethod=marker
--- /dev/null
+++ b/lib/vimfiles/autoload/gzip.vim
@@ -1,0 +1,200 @@
+" Vim autoload file for editing compressed files.
+" Maintainer: Bram Moolenaar <Bram@vim.org>
+" Last Change: 2007 May 10
+
+" These functions are used by the gzip plugin.
+
+" Function to check that executing "cmd [-f]" works.
+" The result is cached in s:have_"cmd" for speed.
+fun s:check(cmd)
+  let name = substitute(a:cmd, '\(\S*\).*', '\1', '')
+  if !exists("s:have_" . name)
+    let e = executable(name)
+    if e < 0
+      let r = system(name . " --version")
+      let e = (r !~ "not found" && r != "")
+    endif
+    exe "let s:have_" . name . "=" . e
+  endif
+  exe "return s:have_" . name
+endfun
+
+" Set b:gzip_comp_arg to the gzip argument to be used for compression, based on
+" the flags in the compressed file.
+" The only compression methods that can be detected are max speed (-1) and max
+" compression (-9).
+fun s:set_compression(line)
+  " get the Compression Method
+  let l:cm = char2nr(a:line[2])
+  " if it's 8 (DEFLATE), we can check for the compression level
+  if l:cm == 8
+    " get the eXtra FLags
+    let l:xfl = char2nr(a:line[8])
+    " max compression
+    if l:xfl == 2
+      let b:gzip_comp_arg = "-9"
+    " min compression
+    elseif l:xfl == 4
+      let b:gzip_comp_arg = "-1"
+    endif
+  endif
+endfun
+
+
+" After reading compressed file: Uncompress text in buffer with "cmd"
+fun gzip#read(cmd)
+  " don't do anything if the cmd is not supported
+  if !s:check(a:cmd)
+    return
+  endif
+
+  " for gzip check current compression level and set b:gzip_comp_arg.
+  silent! unlet b:gzip_comp_arg
+  if a:cmd[0] == 'g'
+    call s:set_compression(getline(1))
+  endif
+
+  " make 'patchmode' empty, we don't want a copy of the written file
+  let pm_save = &pm
+  set pm=
+  " remove 'a' and 'A' from 'cpo' to avoid the alternate file changes
+  let cpo_save = &cpo
+  set cpo-=a cpo-=A
+  " set 'modifiable'
+  let ma_save = &ma
+  setlocal ma
+  " Reset 'foldenable', otherwise line numbers get adjusted.
+  if has("folding")
+    let fen_save = &fen
+    setlocal nofen
+  endif
+
+  " when filtering the whole buffer, it will become empty
+  let empty = line("'[") == 1 && line("']") == line("$")
+  let tmp = tempname()
+  let tmpe = tmp . "." . expand("<afile>:e")
+  " write the just read lines to a temp file "'[,']w tmp.gz"
+  execute "silent '[,']w " . escape(tmpe, ' ')
+  " uncompress the temp file: call system("gzip -dn tmp.gz")
+  call system(a:cmd . " " . s:escape(tmpe))
+  if !filereadable(tmp)
+    " uncompress didn't work!  Keep the compressed file then.
+    echoerr "Error: Could not read uncompressed file"
+    let ok = 0
+  else
+    let ok = 1
+    " delete the compressed lines; remember the line number
+    let l = line("'[") - 1
+    if exists(":lockmarks")
+      lockmarks '[,']d _
+    else
+      '[,']d _
+    endif
+    " read in the uncompressed lines "'[-1r tmp"
+    " Use ++edit if the buffer was empty, keep the 'ff' and 'fenc' options.
+    setlocal nobin
+    if exists(":lockmarks")
+      if empty
+	execute "silent lockmarks " . l . "r ++edit " . tmp
+      else
+	execute "silent lockmarks " . l . "r " . tmp
+      endif
+    else
+      execute "silent " . l . "r " . tmp
+    endif
+
+    " if buffer became empty, delete trailing blank line
+    if empty
+      silent $delete _
+      1
+    endif
+    " delete the temp file and the used buffers
+    call delete(tmp)
+    silent! exe "bwipe " . tmp
+    silent! exe "bwipe " . tmpe
+  endif
+
+  " Restore saved option values.
+  let &pm = pm_save
+  let &cpo = cpo_save
+  let &l:ma = ma_save
+  if has("folding")
+    let &l:fen = fen_save
+  endif
+
+  " When uncompressed the whole buffer, do autocommands
+  if ok && empty
+    if &verbose >= 8
+      execute "doau BufReadPost " . expand("%:r")
+    else
+      execute "silent! doau BufReadPost " . expand("%:r")
+    endif
+  endif
+endfun
+
+" After writing compressed file: Compress written file with "cmd"
+fun gzip#write(cmd)
+  " don't do anything if the cmd is not supported
+  if s:check(a:cmd)
+    " Rename the file before compressing it.
+    let nm = resolve(expand("<afile>"))
+    let nmt = s:tempname(nm)
+    if rename(nm, nmt) == 0
+      if exists("b:gzip_comp_arg")
+	call system(a:cmd . " " . b:gzip_comp_arg . " " . s:escape(nmt))
+      else
+	call system(a:cmd . " " . s:escape(nmt))
+      endif
+      call rename(nmt . "." . expand("<afile>:e"), nm)
+    endif
+  endif
+endfun
+
+" Before appending to compressed file: Uncompress file with "cmd"
+fun gzip#appre(cmd)
+  " don't do anything if the cmd is not supported
+  if s:check(a:cmd)
+    let nm = expand("<afile>")
+
+    " for gzip check current compression level and set b:gzip_comp_arg.
+    silent! unlet b:gzip_comp_arg
+    if a:cmd[0] == 'g'
+      call s:set_compression(readfile(nm, "b", 1)[0])
+    endif
+
+    " Rename to a weird name to avoid the risk of overwriting another file
+    let nmt = expand("<afile>:p:h") . "/X~=@l9q5"
+    let nmte = nmt . "." . expand("<afile>:e")
+    if rename(nm, nmte) == 0
+      if &patchmode != "" && getfsize(nm . &patchmode) == -1
+	" Create patchmode file by creating the decompressed file new
+	call system(a:cmd . " -c " . s:escape(nmte) . " > " . s:escape(nmt))
+	call rename(nmte, nm . &patchmode)
+      else
+	call system(a:cmd . " " . s:escape(nmte))
+      endif
+      call rename(nmt, nm)
+    endif
+  endif
+endfun
+
+" find a file name for the file to be compressed.  Use "name" without an
+" extension if possible.  Otherwise use a weird name to avoid overwriting an
+" existing file.
+fun s:tempname(name)
+  let fn = fnamemodify(a:name, ":r")
+  if !filereadable(fn) && !isdirectory(fn)
+    return fn
+  endif
+  return fnamemodify(a:name, ":p:h") . "/X~=@l9q5"
+endfun
+
+fun s:escape(name)
+  " shellescape() was added by patch 7.0.111
+  if exists("*shellescape")
+    return shellescape(a:name)
+  endif
+  return "'" . a:name . "'"
+endfun
+
+" vim: set sw=2 :
--- /dev/null
+++ b/lib/vimfiles/autoload/htmlcomplete.vim
@@ -1,0 +1,765 @@
+" Vim completion script
+" Language:	HTML and XHTML
+" Maintainer:	Mikolaj Machowski ( mikmach AT wp DOT pl )
+" Last Change:	2006 Oct 19
+
+function! htmlcomplete#CompleteTags(findstart, base)
+  if a:findstart
+    " locate the start of the word
+    let line = getline('.')
+    let start = col('.') - 1
+	let curline = line('.')
+	let compl_begin = col('.') - 2
+    while start >= 0 && line[start - 1] =~ '\(\k\|[!:.-]\)'
+		let start -= 1
+    endwhile
+	" Handling of entities {{{
+	if start >= 0 && line[start - 1] =~ '&'
+		let b:entitiescompl = 1
+		let b:compl_context = ''
+		return start
+	endif
+	" }}}
+	" Handling of <style> tag {{{
+	let stylestart = searchpair('<style\>', '', '<\/style\>', "bnW")
+	let styleend   = searchpair('<style\>', '', '<\/style\>', "nW")
+	if stylestart != 0 && styleend != 0
+		if stylestart <= curline && styleend >= curline
+			let start = col('.') - 1
+			let b:csscompl = 1
+			while start >= 0 && line[start - 1] =~ '\(\k\|-\)'
+				let start -= 1
+			endwhile
+		endif
+	endif
+	" }}}
+	" Handling of <script> tag {{{
+	let scriptstart = searchpair('<script\>', '', '<\/script\>', "bnW")
+	let scriptend   = searchpair('<script\>', '', '<\/script\>', "nW")
+	if scriptstart != 0 && scriptend != 0
+		if scriptstart <= curline && scriptend >= curline
+			let start = col('.') - 1
+			let b:jscompl = 1
+			let b:jsrange = [scriptstart, scriptend]
+			while start >= 0 && line[start - 1] =~ '\k'
+				let start -= 1
+			endwhile
+			" We are inside of <script> tag. But we should also get contents
+			" of all linked external files and (secondary, less probably) other <script> tags
+			" This logic could possible be done in separate function - may be
+			" reused in events scripting (also with option could be reused for
+			" CSS
+			let b:js_extfiles = []
+			let l = line('.')
+			let c = col('.')
+			call cursor(1,1)
+			while search('<\@<=script\>', 'W') && line('.') <= l
+				if synIDattr(synID(line('.'),col('.')-1,0),"name") !~? 'comment'
+					let sname = matchstr(getline('.'), '<script[^>]*src\s*=\s*\([''"]\)\zs.\{-}\ze\1')
+					if filereadable(sname)
+						let b:js_extfiles += readfile(sname)
+					endif
+				endif
+			endwhile
+			call cursor(1,1)
+			let js_scripttags = []
+			while search('<script\>', 'W') && line('.') < l
+				if matchstr(getline('.'), '<script[^>]*src') == ''
+					let js_scripttag = getline(line('.'), search('</script>', 'W'))
+					let js_scripttags += js_scripttag
+				endif
+			endwhile
+			let b:js_extfiles += js_scripttags
+			call cursor(l,c)
+			unlet! l c
+		endif
+	endif
+	" }}}
+	if !exists("b:csscompl") && !exists("b:jscompl")
+		let b:compl_context = getline('.')[0:(compl_begin)]
+		if b:compl_context !~ '<[^>]*$'
+			" Look like we may have broken tag. Check previous lines.
+			let i = 1
+			while 1
+				let context_line = getline(curline-i)
+				if context_line =~ '<[^>]*$'
+					" Yep, this is this line
+					let context_lines = getline(curline-i, curline-1) + [b:compl_context]
+					let b:compl_context = join(context_lines, ' ')
+					break
+				elseif context_line =~ '>[^<]*$' || i == curline
+					" We are in normal tag line, no need for completion at all
+					" OR reached first line without tag at all
+					let b:compl_context = ''
+					break
+				endif
+				let i += 1
+			endwhile
+			" Make sure we don't have counter
+			unlet! i
+		endif
+		let b:compl_context = matchstr(b:compl_context, '.*\zs<.*')
+
+		" Return proper start for on-events. Without that beginning of
+		" completion will be badly reported
+		if b:compl_context =~? 'on[a-z]*\s*=\s*\(''[^'']*\|"[^"]*\)$'
+			let start = col('.') - 1
+			while start >= 0 && line[start - 1] =~ '\k'
+				let start -= 1
+			endwhile
+		endif
+		" If b:compl_context begins with <? we are inside of PHP code. It
+		" wasn't closed so PHP completion passed it to HTML
+		if &filetype =~? 'php' && b:compl_context =~ '^<?'
+			let b:phpcompl = 1
+			let start = col('.') - 1
+			while start >= 0 && line[start - 1] =~ '[a-zA-Z_0-9\x7f-\xff$]'
+				let start -= 1
+			endwhile
+		endif
+	else
+		let b:compl_context = getline('.')[0:compl_begin]
+	endif
+    return start
+  else
+	" Initialize base return lists
+    let res = []
+    let res2 = []
+	" a:base is very short - we need context
+	let context = b:compl_context
+	" Check if we should do CSS completion inside of <style> tag
+	" or JS completion inside of <script> tag or PHP completion in case of <?
+	" tag AND &ft==php
+	if exists("b:csscompl")
+		unlet! b:csscompl
+		let context = b:compl_context
+		unlet! b:compl_context
+		return csscomplete#CompleteCSS(0, context)
+	elseif exists("b:jscompl")
+		unlet! b:jscompl
+		return javascriptcomplete#CompleteJS(0, a:base)
+	elseif exists("b:phpcompl")
+		unlet! b:phpcompl
+		let context = b:compl_context
+		return phpcomplete#CompletePHP(0, a:base)
+	else
+		if len(b:compl_context) == 0 && !exists("b:entitiescompl")
+			return []
+		endif
+		let context = matchstr(b:compl_context, '.\zs.*')
+	endif
+	unlet! b:compl_context
+	" Entities completion {{{
+	if exists("b:entitiescompl")
+		unlet! b:entitiescompl
+
+		if !exists("b:html_doctype")
+			call htmlcomplete#CheckDoctype()
+		endif
+		if !exists("b:html_omni")
+			"runtime! autoload/xml/xhtml10s.vim
+			call htmlcomplete#LoadData()
+		endif
+
+	    let entities =  b:html_omni['vimxmlentities']
+
+		if len(a:base) == 1
+			for m in entities
+				if m =~ '^'.a:base
+					call add(res, m.';')
+				endif
+			endfor
+			return res
+		else
+			for m in entities
+				if m =~? '^'.a:base
+					call add(res, m.';')
+				elseif m =~? a:base
+					call add(res2, m.';')
+				endif
+			endfor
+
+			return res + res2
+		endif
+
+
+	endif
+	" }}}
+	if context =~ '>'
+		" Generally if context contains > it means we are outside of tag and
+		" should abandon action - with one exception: <style> span { bo
+		if context =~ 'style[^>]\{-}>[^<]\{-}$'
+			return csscomplete#CompleteCSS(0, context)
+		elseif context =~ 'script[^>]\{-}>[^<]\{-}$'
+			let b:jsrange = [line('.'), search('<\/script\>', 'nW')]
+			return javascriptcomplete#CompleteJS(0, context)
+		else
+			return []
+		endif
+	endif
+
+	" If context contains > it means we are already outside of tag and we
+	" should abandon action
+	" If context contains white space it is attribute.
+	" It can be also value of attribute.
+	" We have to get first word to offer proper completions
+	if context == ''
+		let tag = ''
+	else
+		let tag = split(context)[0]
+		" Detect if tag is uppercase to return in proper case,
+		" we need to make it lowercase for processing
+		if tag =~ '^[A-Z]*$'
+			let uppercase_tag = 1
+			let tag = tolower(tag)
+		else
+			let uppercase_tag = 0
+		endif
+	endif
+	" Get last word, it should be attr name
+	let attr = matchstr(context, '.*\s\zs.*')
+	" Possible situations where any prediction would be difficult:
+	" 1. Events attributes
+	if context =~ '\s'
+		" Sort out style, class, and on* cases
+		if context =~? "\\(on[a-z]*\\|id\\|style\\|class\\)\\s*=\\s*[\"']"
+			" Id, class completion {{{
+			if context =~? "\\(id\\|class\\)\\s*=\\s*[\"'][a-zA-Z0-9_ -]*$"
+				if context =~? "class\\s*=\\s*[\"'][a-zA-Z0-9_ -]*$"
+					let search_for = "class"
+				elseif context =~? "id\\s*=\\s*[\"'][a-zA-Z0-9_ -]*$"
+					let search_for = "id"
+				endif
+				" Handle class name completion
+				" 1. Find lines of <link stylesheet>
+				" 1a. Check file for @import
+				" 2. Extract filename(s?) of stylesheet,
+				call cursor(1,1)
+				let head = getline(search('<head\>'), search('<\/head>'))
+				let headjoined = join(copy(head), ' ')
+				if headjoined =~ '<style'
+					" Remove possibly confusing CSS operators
+					let stylehead = substitute(headjoined, '+>\*[,', ' ', 'g')
+					if search_for == 'class'
+						let styleheadlines = split(stylehead)
+						let headclasslines = filter(copy(styleheadlines), "v:val =~ '\\([a-zA-Z0-9:]\\+\\)\\?\\.[a-zA-Z0-9_-]\\+'")
+					else
+						let stylesheet = split(headjoined, '[{}]')
+						" Get all lines which fit id syntax
+						let classlines = filter(copy(stylesheet), "v:val =~ '#[a-zA-Z0-9_-]\\+'")
+						" Filter out possible color definitions
+						call filter(classlines, "v:val !~ ':\\s*#[a-zA-Z0-9_-]\\+'")
+						" Filter out complex border definitions
+						call filter(classlines, "v:val !~ '\\(none\\|hidden\\|dotted\\|dashed\\|solid\\|double\\|groove\\|ridge\\|inset\\|outset\\)\\s*#[a-zA-Z0-9_-]\\+'")
+						let templines = join(classlines, ' ')
+						let headclasslines = split(templines)
+						call filter(headclasslines, "v:val =~ '#[a-zA-Z0-9_-]\\+'")
+					endif
+					let internal = 1
+				else
+					let internal = 0
+				endif
+				let styletable = []
+				let secimportfiles = []
+				let filestable = filter(copy(head), "v:val =~ '\\(@import\\|link.*stylesheet\\)'")
+				for line in filestable
+					if line =~ "@import"
+						let styletable += [matchstr(line, "import\\s\\+\\(url(\\)\\?[\"']\\?\\zs\\f\\+\\ze")]
+					elseif line =~ "<link"
+						let styletable += [matchstr(line, "href\\s*=\\s*[\"']\\zs\\f\\+\\ze")]
+					endif
+				endfor
+				for file in styletable
+					if filereadable(file)
+						let stylesheet = readfile(file)
+						let secimport = filter(copy(stylesheet), "v:val =~ '@import'")
+						if len(secimport) > 0
+							for line in secimport
+								let secfile = matchstr(line, "import\\s\\+\\(url(\\)\\?[\"']\\?\\zs\\f\\+\\ze")
+								let secfile = fnamemodify(file, ":p:h").'/'.secfile
+								let secimportfiles += [secfile]
+							endfor
+						endif
+					endif
+				endfor
+				let cssfiles = styletable + secimportfiles
+				let classes = []
+				for file in cssfiles
+					if filereadable(file)
+						let stylesheet = readfile(file)
+						let stylefile = join(stylesheet, ' ')
+						let stylefile = substitute(stylefile, '+>\*[,', ' ', 'g')
+						if search_for == 'class'
+							let stylesheet = split(stylefile)
+							let classlines = filter(copy(stylesheet), "v:val =~ '\\([a-zA-Z0-9:]\\+\\)\\?\\.[a-zA-Z0-9_-]\\+'")
+						else
+							let stylesheet = split(stylefile, '[{}]')
+							" Get all lines which fit id syntax
+							let classlines = filter(copy(stylesheet), "v:val =~ '#[a-zA-Z0-9_-]\\+'")
+							" Filter out possible color definitions
+							call filter(classlines, "v:val !~ ':\\s*#[a-zA-Z0-9_-]\\+'")
+							" Filter out complex border definitions
+							call filter(classlines, "v:val !~ '\\(none\\|hidden\\|dotted\\|dashed\\|solid\\|double\\|groove\\|ridge\\|inset\\|outset\\)\\s*#[a-zA-Z0-9_-]\\+'")
+							let templines = join(classlines, ' ')
+							let stylelines = split(templines)
+							let classlines = filter(stylelines, "v:val =~ '#[a-zA-Z0-9_-]\\+'")
+
+						endif
+					endif
+					" We gathered classes definitions from all external files
+					let classes += classlines
+				endfor
+				if internal == 1
+					let classes += headclasslines
+				endif
+
+				if search_for == 'class'
+					let elements = {}
+					for element in classes
+						if element =~ '^\.'
+							let class = matchstr(element, '^\.\zs[a-zA-Z][a-zA-Z0-9_-]*\ze')
+							let class = substitute(class, ':.*', '', '')
+							if has_key(elements, 'common')
+								let elements['common'] .= ' '.class
+							else
+								let elements['common'] = class
+							endif
+						else
+							let class = matchstr(element, '[a-zA-Z1-6]*\.\zs[a-zA-Z][a-zA-Z0-9_-]*\ze')
+							let tagname = tolower(matchstr(element, '[a-zA-Z1-6]*\ze.'))
+							if tagname != ''
+								if has_key(elements, tagname)
+									let elements[tagname] .= ' '.class
+								else
+									let elements[tagname] = class
+								endif
+							endif
+						endif
+					endfor
+
+					if has_key(elements, tag) && has_key(elements, 'common')
+						let values = split(elements[tag]." ".elements['common'])
+					elseif has_key(elements, tag) && !has_key(elements, 'common')
+						let values = split(elements[tag])
+					elseif !has_key(elements, tag) && has_key(elements, 'common')
+						let values = split(elements['common'])
+					else
+						return []
+					endif
+
+				elseif search_for == 'id'
+					" Find used IDs
+					" 1. Catch whole file
+					let filelines = getline(1, line('$'))
+					" 2. Find lines with possible id
+					let used_id_lines = filter(filelines, 'v:val =~ "id\\s*=\\s*[\"''][a-zA-Z0-9_-]\\+"')
+					" 3a. Join all filtered lines
+					let id_string = join(used_id_lines, ' ')
+					" 3b. And split them to be sure each id is in separate item
+					let id_list = split(id_string, 'id\s*=\s*')
+					" 4. Extract id values
+					let used_id = map(id_list, 'matchstr(v:val, "[\"'']\\zs[a-zA-Z0-9_-]\\+\\ze")')
+					let joined_used_id = ','.join(used_id, ',').','
+
+					let allvalues = map(classes, 'matchstr(v:val, ".*#\\zs[a-zA-Z0-9_-]\\+")')
+
+					let values = []
+
+					for element in classes
+						if joined_used_id !~ ','.element.','
+							let values += [element]
+						endif
+
+					endfor
+
+				endif
+
+				" We need special version of sbase
+				let classbase = matchstr(context, ".*[\"']")
+				let classquote = matchstr(classbase, '.$')
+
+				let entered_class = matchstr(attr, ".*=\\s*[\"']\\zs.*")
+
+				for m in sort(values)
+					if m =~? '^'.entered_class
+						call add(res, m . classquote)
+					elseif m =~? entered_class
+						call add(res2, m . classquote)
+					endif
+				endfor
+
+				return res + res2
+
+			elseif context =~? "style\\s*=\\s*[\"'][^\"']*$"
+				return csscomplete#CompleteCSS(0, context)
+
+			endif
+			" }}}
+			" Complete on-events {{{
+			if context =~? 'on[a-z]*\s*=\s*\(''[^'']*\|"[^"]*\)$'
+				" We have to:
+				" 1. Find external files
+				let b:js_extfiles = []
+				let l = line('.')
+				let c = col('.')
+				call cursor(1,1)
+				while search('<\@<=script\>', 'W') && line('.') <= l
+					if synIDattr(synID(line('.'),col('.')-1,0),"name") !~? 'comment'
+						let sname = matchstr(getline('.'), '<script[^>]*src\s*=\s*\([''"]\)\zs.\{-}\ze\1')
+						if filereadable(sname)
+							let b:js_extfiles += readfile(sname)
+						endif
+					endif
+				endwhile
+				" 2. Find at least one <script> tag
+				call cursor(1,1)
+				let js_scripttags = []
+				while search('<script\>', 'W') && line('.') < l
+					if matchstr(getline('.'), '<script[^>]*src') == ''
+						let js_scripttag = getline(line('.'), search('</script>', 'W'))
+						let js_scripttags += js_scripttag
+					endif
+				endwhile
+				let b:js_extfiles += js_scripttags
+
+				" 3. Proper call for javascriptcomplete#CompleteJS
+				call cursor(l,c)
+				let js_context = matchstr(a:base, '\k\+$')
+				let js_shortcontext = substitute(a:base, js_context.'$', '', '')
+				let b:compl_context = context
+				let b:jsrange = [l, l]
+				unlet! l c
+				return javascriptcomplete#CompleteJS(0, js_context)
+
+			endif
+
+			" }}}
+			let stripbase = matchstr(context, ".*\\(on[a-zA-Z]*\\|style\\|class\\)\\s*=\\s*[\"']\\zs.*")
+			" Now we have context stripped from all chars up to style/class.
+			" It may fail with some strange style value combinations.
+			if stripbase !~ "[\"']"
+				return []
+			endif
+		endif
+		" Value of attribute completion {{{
+		" If attr contains =\s*[\"'] we catched value of attribute
+		if attr =~ "=\s*[\"']" || attr =~ "=\s*$"
+			" Let do attribute specific completion
+			let attrname = matchstr(attr, '.*\ze\s*=')
+			let entered_value = matchstr(attr, ".*=\\s*[\"']\\?\\zs.*")
+			let values = []
+			" Load data {{{
+			if !exists("b:html_doctype")
+				call htmlcomplete#CheckDoctype()
+			endif
+			if !exists("b:html_omni")
+				"runtime! autoload/xml/xhtml10s.vim
+				call htmlcomplete#LoadData()
+			endif
+			" }}}
+			if attrname == 'href'
+				" Now we are looking for local anchors defined by name or id
+				if entered_value =~ '^#'
+					let file = join(getline(1, line('$')), ' ')
+					" Split it be sure there will be one id/name element in
+					" item, it will be also first word [a-zA-Z0-9_-] in element
+					let oneelement = split(file, "\\(meta \\)\\@<!\\(name\\|id\\)\\s*=\\s*[\"']")
+					for i in oneelement
+						let values += ['#'.matchstr(i, "^[a-zA-Z][a-zA-Z0-9%_-]*")]
+					endfor
+				endif
+			else
+				if has_key(b:html_omni, tag) && has_key(b:html_omni[tag][1], attrname)
+					let values = b:html_omni[tag][1][attrname]
+				else
+					return []
+				endif
+			endif
+
+			if len(values) == 0
+				return []
+			endif
+
+			" We need special version of sbase
+			let attrbase = matchstr(context, ".*[\"']")
+			let attrquote = matchstr(attrbase, '.$')
+			if attrquote !~ "['\"]"
+				let attrquoteopen = '"'
+				let attrquote = '"'
+			else
+				let attrquoteopen = ''
+			endif
+
+			for m in values
+				" This if is needed to not offer all completions as-is
+				" alphabetically but sort them. Those beginning with entered
+				" part will be as first choices
+				if m =~ '^'.entered_value
+					call add(res, attrquoteopen . m . attrquote)
+				elseif m =~ entered_value
+					call add(res2, attrquoteopen . m . attrquote)
+				endif
+			endfor
+
+			return res + res2
+
+		endif
+		" }}}
+		" Attribute completion {{{
+		" Shorten context to not include last word
+		let sbase = matchstr(context, '.*\ze\s.*')
+
+		" Load data {{{
+		if !exists("b:html_doctype")
+			call htmlcomplete#CheckDoctype()
+		endif
+		if !exists("b:html_omni")
+			call htmlcomplete#LoadData()
+		endif
+		" }}}
+
+		if has_key(b:html_omni, tag)
+			let attrs = keys(b:html_omni[tag][1])
+		else
+			return []
+		endif
+
+		for m in sort(attrs)
+			if m =~ '^'.attr
+				call add(res, m)
+			elseif m =~ attr
+				call add(res2, m)
+			endif
+		endfor
+		let menu = res + res2
+		if has_key(b:html_omni, 'vimxmlattrinfo')
+			let final_menu = []
+			for i in range(len(menu))
+				let item = menu[i]
+				if has_key(b:html_omni['vimxmlattrinfo'], item)
+					let m_menu = b:html_omni['vimxmlattrinfo'][item][0]
+					let m_info = b:html_omni['vimxmlattrinfo'][item][1]
+				else
+					let m_menu = ''
+					let m_info = ''
+				endif
+				if len(b:html_omni[tag][1][item]) > 0 && b:html_omni[tag][1][item][0] =~ '^\(BOOL\|'.item.'\)$'
+					let item = item
+					let m_menu = 'Bool'
+				else
+					let item .= '="'
+				endif
+				let final_menu += [{'word':item, 'menu':m_menu, 'info':m_info}]
+			endfor
+		else
+			let final_menu = []
+			for i in range(len(menu))
+				let item = menu[i]
+				if len(b:html_omni[tag][1][item]) > 0 && b:html_omni[tag][1][item][0] =~ '^\(BOOL\|'.item.'\)$'
+					let item = item
+				else
+					let item .= '="'
+				endif
+				let final_menu += [item]
+			endfor
+			return final_menu
+
+		endif
+		return final_menu
+
+	endif
+	" }}}
+	" Close tag {{{
+	let b:unaryTagsStack = "base meta link hr br param img area input col"
+	if context =~ '^\/'
+		if context =~ '^\/.'
+			return []
+		else
+			let opentag = xmlcomplete#GetLastOpenTag("b:unaryTagsStack")
+			return [opentag.">"]
+		endif
+	endif
+	" }}}
+	" Load data {{{
+	if !exists("b:html_doctype")
+		call htmlcomplete#CheckDoctype()
+	endif
+	if !exists("b:html_omni")
+		"runtime! autoload/xml/xhtml10s.vim
+		call htmlcomplete#LoadData()
+	endif
+	" }}}
+	" Tag completion {{{
+	" Deal with tag completion.
+	let opentag = tolower(xmlcomplete#GetLastOpenTag("b:unaryTagsStack"))
+	" MM: TODO: GLOT works always the same but with some weird situation it
+	" behaves as intended in HTML but screws in PHP
+	if opentag == '' || &filetype == 'php' && !has_key(b:html_omni, opentag)
+		" Hack for sometimes failing GetLastOpenTag.
+		" As far as I tested fail isn't GLOT fault but problem
+		" of invalid document - not properly closed tags and other mish-mash.
+		" Also when document is empty. Return list of *all* tags.
+	    let tags = keys(b:html_omni)
+		call filter(tags, 'v:val !~ "^vimxml"')
+	else
+		if has_key(b:html_omni, opentag)
+			let tags = b:html_omni[opentag][0]
+		else
+			return []
+		endif
+	endif
+	" }}}
+
+	if exists("uppercase_tag") && uppercase_tag == 1
+		let context = tolower(context)
+	endif
+	" Handle XML keywords: DOCTYPE
+	if opentag == ''
+		let tags += [
+				\ '!DOCTYPE html PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">',
+				\ '!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd">',
+				\ '!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">',
+				\ '!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Frameset//EN" "http://www.w3.org/TR/REC-html40/frameset.dtd">',
+				\ '!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">',
+				\ '!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">',
+				\ '!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Frameset//EN" "http://www.w3.org/TR/html4/frameset.dtd">',
+				\ '!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">',
+				\ '!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">',
+				\ '!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Frameset//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-frameset.dtd">',
+				\ '!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/1999/xhtml">'
+				\ ]
+	endif
+
+	for m in sort(tags)
+		if m =~ '^'.context
+			call add(res, m)
+		elseif m =~ context
+			call add(res2, m)
+		endif
+	endfor
+	let menu = res + res2
+	if has_key(b:html_omni, 'vimxmltaginfo')
+		let final_menu = []
+		for i in range(len(menu))
+			let item = menu[i]
+			if has_key(b:html_omni['vimxmltaginfo'], item)
+				let m_menu = b:html_omni['vimxmltaginfo'][item][0]
+				let m_info = b:html_omni['vimxmltaginfo'][item][1]
+			else
+				let m_menu = ''
+				let m_info = ''
+			endif
+			if &filetype == 'html' && exists("uppercase_tag") && uppercase_tag == 1 && item !~ 'DOCTYPE'
+				let item = toupper(item)
+			endif
+			if item =~ 'DOCTYPE'
+				let abbr = 'DOCTYPE '.matchstr(item, 'DTD \zsX\?HTML .\{-}\ze\/\/')
+			else
+				let abbr = item
+			endif
+			let final_menu += [{'abbr':abbr, 'word':item, 'menu':m_menu, 'info':m_info}]
+		endfor
+	else
+		let final_menu = menu
+	endif
+	return final_menu
+
+	" }}}
+  endif
+endfunction
+
+function! htmlcomplete#LoadData() " {{{
+	if !exists("b:html_omni_flavor")
+		if &filetype == 'html'
+			let b:html_omni_flavor = 'html401t'
+		else
+			let b:html_omni_flavor = 'xhtml10s'
+		endif
+	endif
+	" With that if we still have bloated memory but create new buffer
+	" variables only by linking to existing g:variable, not sourcing whole
+	" file.
+	if exists('g:xmldata_'.b:html_omni_flavor)
+		exe 'let b:html_omni = g:xmldata_'.b:html_omni_flavor
+	else
+		exe 'runtime! autoload/xml/'.b:html_omni_flavor.'.vim'
+		exe 'let b:html_omni = g:xmldata_'.b:html_omni_flavor
+	endif
+endfunction
+" }}}
+function! htmlcomplete#CheckDoctype() " {{{
+	if exists('b:html_omni_flavor')
+		let old_flavor = b:html_omni_flavor
+	else
+		let old_flavor = ''
+	endif
+	let i = 1
+	while i < 10 && i < line("$")
+		let line = getline(i)
+		if line =~ '<!DOCTYPE.*\<DTD HTML 3\.2'
+			let b:html_omni_flavor = 'html32'
+			let b:html_doctype = 1
+			break
+		elseif line =~ '<!DOCTYPE.*\<DTD HTML 4\.0 Transitional'
+			let b:html_omni_flavor = 'html40t'
+			let b:html_doctype = 1
+			break
+		elseif line =~ '<!DOCTYPE.*\<DTD HTML 4\.0 Frameset'
+			let b:html_omni_flavor = 'html40f'
+			let b:html_doctype = 1
+			break
+		elseif line =~ '<!DOCTYPE.*\<DTD HTML 4\.0'
+			let b:html_omni_flavor = 'html40s'
+			let b:html_doctype = 1
+			break
+		elseif line =~ '<!DOCTYPE.*\<DTD HTML 4\.01 Transitional'
+			let b:html_omni_flavor = 'html401t'
+			let b:html_doctype = 1
+			break
+		elseif line =~ '<!DOCTYPE.*\<DTD HTML 4\.01 Frameset'
+			let b:html_omni_flavor = 'html401f'
+			let b:html_doctype = 1
+			break
+		elseif line =~ '<!DOCTYPE.*\<DTD HTML 4\.01'
+			let b:html_omni_flavor = 'html401s'
+			let b:html_doctype = 1
+			break
+		elseif line =~ '<!DOCTYPE.*\<DTD XHTML 1\.0 Transitional'
+			let b:html_omni_flavor = 'xhtml10t'
+			let b:html_doctype = 1
+			break
+		elseif line =~ '<!DOCTYPE.*\<DTD XHTML 1\.0 Frameset'
+			let b:html_omni_flavor = 'xhtml10f'
+			let b:html_doctype = 1
+			break
+		elseif line =~ '<!DOCTYPE.*\<DTD XHTML 1\.0 Strict'
+			let b:html_omni_flavor = 'xhtml10s'
+			let b:html_doctype = 1
+			break
+		elseif line =~ '<!DOCTYPE.*\<DTD XHTML 1\.1'
+			let b:html_omni_flavor = 'xhtml11'
+			let b:html_doctype = 1
+			break
+		endif
+		let i += 1
+	endwhile
+	if !exists("b:html_doctype")
+		return
+	else
+		" Tie g:xmldata with b:html_omni this way we need to sourca data file only
+		" once, not every time per buffer.
+		if old_flavor == b:html_omni_flavor
+			return
+		else
+			if exists('g:xmldata_'.b:html_omni_flavor)
+				exe 'let b:html_omni = g:xmldata_'.b:html_omni_flavor
+			else
+				exe 'runtime! autoload/xml/'.b:html_omni_flavor.'.vim'
+				exe 'let b:html_omni = g:xmldata_'.b:html_omni_flavor
+			endif
+			return
+		endif
+	endif
+endfunction
+" }}}
+" vim:set foldmethod=marker:
--- /dev/null
+++ b/lib/vimfiles/autoload/javascriptcomplete.vim
@@ -1,0 +1,625 @@
+" Vim completion script
+" Language:	Java Script
+" Maintainer:	Mikolaj Machowski ( mikmach AT wp DOT pl )
+" Last Change:	2006 Apr 30
+
+function! javascriptcomplete#CompleteJS(findstart, base)
+  if a:findstart
+	" locate the start of the word
+	let line = getline('.')
+	let start = col('.') - 1
+	let curline = line('.')
+	let compl_begin = col('.') - 2
+	" Bit risky but JS is rather limited language and local chars shouldn't
+	" fint way into names
+	while start >= 0 && line[start - 1] =~ '\k'
+		let start -= 1
+	endwhile
+	let b:compl_context = getline('.')[0:compl_begin]
+	return start
+  else
+	" Initialize base return lists
+	let res = []
+	let res2 = []
+	" a:base is very short - we need context
+	" Shortcontext is context without a:base, useful for checking if we are
+	" looking for objects and for what objects we are looking for
+	let context = b:compl_context
+	let shortcontext = substitute(context, a:base.'$', '', '')
+	unlet! b:compl_context
+
+	if exists("b:jsrange")
+		let file = getline(b:jsrange[0],b:jsrange[1])
+		unlet! b:jsrange
+
+		if len(b:js_extfiles) > 0
+			let file = b:js_extfiles + file
+		endif
+
+	else
+		let file = getline(1, '$')
+	endif
+
+
+	" Completion of properties, methods, etc. {{{
+	if shortcontext =~ '\.$'
+		" Complete methods and properties for objects
+		" DOM separate
+		let doms = ['style.']
+		" Arrays
+		let arrayprop = ['constructor', 'index', 'input', 'length', 'prototype']
+		let arraymeth = ['concat', 'join', 'pop', 'push', 'reverse', 'shift',
+					\ 'splice', 'sort', 'toSource', 'toString', 'unshift', 'valueOf',
+					\ 'watch', 'unwatch']
+		call map(arraymeth, 'v:val."("')
+		let arrays = arrayprop + arraymeth
+
+		" Boolean - complete subset of array values
+		" properties - constructor, prototype
+		" methods    - toSource, toString, valueOf
+
+		" Date
+		" properties - constructor, prototype
+		let datemeth = ['getDate', 'getDay', 'getFullYear', 'getHours', 'getMilliseconds',
+					\ 'getMinutes', 'getMonth', 'getSeconds', 'getTime', 'getTimezoneOffset',
+					\ 'getUTCDate', 'getUTCDay', 'getUTCFullYear', 'getUTCHours', 'getUTCMilliseconds',
+					\ 'getUTCMinutes', 'getUTCMonth', 'getUTCSeconds',
+					\ 'getYear', 'parse', 'parse',
+					\ 'setDate', 'setDay', 'setFullYear', 'setHours', 'setMilliseconds',
+					\ 'setMinutes', 'setMonth', 'setSeconds',
+					\ 'setUTCDate', 'setUTCDay', 'setUTCFullYear', 'setUTCHours', 'setUTCMilliseconds',
+					\ 'setUTCMinutes', 'setUTCMonth', 'setUTCSeconds', 'setYear', 'setTime',
+					\ 'toGMTString', 'toLocaleString', 'toLocaleDateString', 'toLocaleTimeString',
+					\ 'toSource', 'toString', 'toUTCString', 'UTC', 'valueOf', 'watch', 'unwatch']
+		call map(datemeth, 'v:val."("')
+		let dates = datemeth
+
+		" Function
+		let funcprop = ['arguments', 'arguments.callee', 'arguments.caller', 'arguments.length',
+					\ 'arity', 'constructor', 'length', 'prototype']
+		let funcmeth = ['apply', 'call', 'toSource', 'toString', 'valueOf']
+		call map(funcmeth, 'v:val."("')
+		let funcs = funcprop + funcmeth
+
+		" Math
+		let mathprop = ['E', 'LN2', 'LN10', 'LOG2E', 'LOG10E', 'PI', 'SQRT1_2', 'SQRT']
+		let mathmeth = ['abs', 'acos', 'asin', 'atan', 'atan2', 'ceil', 'cos', 'exp', 'floor',
+					\ 'log', 'max', 'min', 'pow', 'random', 'round', 'sin', 'sqrt', 'tan',
+					\ 'watch', 'unwatch']
+		call map(mathmeth, 'v:val."("')
+		let maths = mathprop + mathmeth
+
+		" Number
+		let numbprop = ['MAX_VALUE', 'MIN_VALUE', 'NaN', 'NEGATIVE_INFINITY', 'POSITIVE_INFINITY', 
+					\ 'constructor', 'prototype']
+		let numbmeth = ['toExponential', 'toFixed', 'toPrecision', 'toSource', 'toString', 'valueOf',
+					\ 'watch', 'unwatch']
+		call map(numbmeth, 'v:val."("')
+		let numbs = numbprop + numbmeth
+
+		" Object
+		let objeprop = ['constructor', 'prototype']
+		let objemeth = ['eval', 'toSource', 'toString', 'unwatch', 'watch', 'valueOf']
+		call map(objemeth, 'v:val."("')
+		let objes = objeprop + objemeth
+
+		" RegExp
+		let regeprop = ['constructor', 'global', 'ignoreCase', 'lastIndex', 'multiline', 'source', 'prototype']
+		let regemeth = ['exec', 'test', 'toSource', 'toString', 'watch', 'unwatch']
+		call map(regemeth, 'v:val."("')
+		let reges = regeprop + regemeth
+
+		" String
+		let striprop = ['constructor', 'length', 'prototype']
+		let strimeth = ['anchor', 'big', 'blink', 'bold', 'charAt', 'charCodeAt', 'concat',
+					\ 'fixed', 'fontcolor', 'fontsize', 'fromCharCode', 'indexOf', 'italics',
+					\ 'lastIndexOf', 'link', 'match', 'replace', 'search', 'slice', 'small',
+					\ 'split', 'strike', 'sub', 'substr', 'substring', 'sup', 'toLowerCase',
+					\ 'toSource', 'toString', 'toUpperCase', 'watch', 'unwatch']
+		call map(strimeth, 'v:val."("')
+		let stris = striprop + strimeth
+
+		" User created properties
+		let user_props1 = filter(copy(file), 'v:val =~ "this\\.\\k"')
+		let juser_props1 = join(user_props1, ' ')
+		let user_props1 = split(juser_props1, '\zethis\.')
+		unlet! juser_props1
+		call map(user_props1, 'matchstr(v:val, "this\\.\\zs\\k\\+\\ze")')
+
+		let user_props2 = filter(copy(file), 'v:val =~ "\\.prototype\\.\\k"')
+		let juser_props2 = join(user_props2, ' ')
+		let user_props2 = split(juser_props2, '\zeprototype\.')
+		unlet! juser_props2
+		call map(user_props2, 'matchstr(v:val, "prototype\\.\\zs\\k\\+\\ze")')
+		let user_props = user_props1 + user_props2
+
+		" HTML DOM properties
+		" Anchors - anchor.
+		let anchprop = ['accessKey', 'charset', 'coords', 'href', 'hreflang', 'id', 'innerHTML',
+					\ 'name', 'rel', 'rev', 'shape', 'tabIndex', 'target', 'type', 'onBlur', 'onFocus']
+		let anchmeth = ['blur', 'focus']
+		call map(anchmeth, 'v:val."("')
+		let anths = anchprop + anchmeth
+		" Area - area.
+		let areaprop = ['accessKey', 'alt', 'coords', 'hash', 'host', 'hostname', 'href', 'id',
+					\ 'noHref', 'pathname', 'port', 'protocol', 'search', 'shape', 'tabIndex', 'target']
+		let areameth = ['onClick', 'onDblClick', 'onMouseOut', 'onMouseOver']
+		call map(areameth, 'v:val."("')
+		let areas = areaprop + areameth
+		" Base - base.
+		let baseprop = ['href', 'id', 'target']
+		let bases = baseprop
+		" Body - body.
+		let bodyprop = ['aLink', 'background', 'gbColor', 'id', 'link', 'scrollLeft', 'scrollTop',
+					\ 'text', 'vLink']
+		let bodys = bodyprop
+		" Document - document.
+		let docuprop = ['anchors', 'applets', 'childNodes', 'embeds', 'forms', 'images', 'links', 'stylesheets',
+					\ 'body', 'cookie', 'documentElement', 'domain', 'lastModified', 'referrer', 'title', 'URL']
+		let documeth = ['close', 'createAttribute', 'createElement', 'createTextNode', 'focus', 'getElementById',
+					\ 'getElementsByName', 'getElementsByTagName', 'open', 'write', 'writeln',
+					\ 'onClick', 'onDblClick', 'onFocus', 'onKeyDown', 'onKeyPress', 'onKeyUp',
+					\ 'onMouseDown', 'onMouseMove', 'onMouseOut', 'onMouseOver', 'onMouseUp', 'onResize']
+		call map(documeth, 'v:val."("')
+		let docuxprop = ['attributes', 'childNodes', 'doctype', 'documentElement', 'firstChild',
+					\ 'implementation', 'namespaceURI', 'nextSibling', 'nodeName', 'nodeType',
+					\ 'nodeValue', 'ownerDocument', 'parentNode', 'previousSibling']
+		let docuxmeth = ['createAttribute', 'createCDATASection',
+					\ 'createComment', 'createDocument', 'createDocumentFragment',
+					\ 'createElement', 'createEntityReference', 'createProcessingInstruction',
+					\ 'createTextNode']
+		call map(docuxmeth, 'v:val."("')
+		let docus = docuprop + docuxprop + documeth + docuxmeth
+		" Form - form.
+		let formprop = ['elements', 'acceptCharset', 'action', 'encoding', 'enctype', 'id', 'length',
+					\ 'method', 'name', 'tabIndex', 'target']
+		let formmeth = ['reset', 'submit', 'onReset', 'onSubmit']
+		call map(formmeth, 'v:val."("')
+		let forms = formprop + formmeth
+		" Frame - frame.
+		let framprop = ['contentDocument', 'frameBorder', 'id', 'longDesc', 'marginHeight', 'marginWidth',
+					\ 'name', 'noResize', 'scrolling', 'src']
+		let frammeth = ['blur', 'focus']
+		call map(frammeth, 'v:val."("')
+		let frams = framprop + frammeth
+		" Frameset - frameset.
+		let fsetprop = ['cols', 'id', 'rows']
+		let fsetmeth = ['blur', 'focus']
+		call map(fsetmeth, 'v:val."("')
+		let fsets = fsetprop + fsetmeth
+		" History - history.
+		let histprop = ['length']
+		let histmeth = ['back', 'forward', 'go']
+		call map(histmeth, 'v:val."("')
+		let hists = histprop + histmeth
+		" Iframe - iframe.
+		let ifraprop = ['align', 'frameBorder', 'height', 'id', 'longDesc', 'marginHeight', 'marginWidth',
+					\ 'name', 'scrolling', 'src', 'width']
+		let ifras = ifraprop
+		" Image - image.
+		let imagprop = ['align', 'alt', 'border', 'complete', 'height', 'hspace', 'id', 'isMap', 'longDesc',
+					\ 'lowSrc', 'name', 'src', 'useMap', 'vspace', 'width']
+		let imagmeth = ['onAbort', 'onError', 'onLoad']
+		call map(imagmeth, 'v:val."("')
+		let imags = histprop + imagmeth
+		" Button - accessible only by other properties
+		let buttprop = ['accessKey', 'disabled', 'form', 'id', 'name', 'tabIndex', 'type', 'value']
+		let buttmeth = ['blur', 'click', 'focus', 'onBlur', 'onClick', 'onFocus', 'onMouseDown', 'onMouseUp']
+		call map(buttmeth, 'v:val."("')
+		let butts = buttprop + buttmeth
+		" Checkbox - accessible only by other properties
+		let checprop = ['accept', 'accessKey', 'align', 'alt', 'checked', 'defaultChecked', 
+					\ 'disabled', 'form', 'id', 'name', 'tabIndex', 'type', 'value'] 
+		let checmeth = ['blur', 'click', 'focus', 'onBlur', 'onClick', 'onFocus', 'onMouseDown', 'onMouseUp']
+		call map(checmeth, 'v:val."("')
+		let checs = checprop + checmeth
+		" File upload - accessible only by other properties
+		let fileprop = ['accept', 'accessKey', 'align', 'alt', 'defaultValue', 
+					\ 'disabled', 'form', 'id', 'name', 'tabIndex', 'type', 'value'] 
+		let filemeth = ['blur', 'focus', 'onBlur', 'onClick', 'onFocus', 'onMouseDown', 'onMouseUp']
+		call map(filemeth, 'v:val."("')
+		let files = fileprop + filemeth
+		" Hidden - accessible only by other properties
+		let hiddprop = ['defaultValue', 'form', 'id', 'name', 'type', 'value'] 
+		let hidds = hiddprop
+		" Password - accessible only by other properties
+		let passprop = ['accept', 'accessKey', 'defaultValue', 
+					\ 'disabled', 'form', 'id', 'maxLength', 'name', 'readOnly', 'size', 'tabIndex', 
+					\ 'type', 'value'] 
+		let passmeth = ['blur', 'click', 'focus', 'select', 'onBlur', 'onFocus', 'onKeyDown', 
+					\ 'onKeyPress', 'onKeyUp']
+		call map(passmeth, 'v:val."("')
+		let passs = passprop + passmeth
+		" Radio - accessible only by other properties
+		let radiprop = ['accept', 'accessKey', 'align', 'alt', 'checked', 'defaultChecked', 
+					\ 'disabled', 'form', 'id', 'name', 'tabIndex', 'type', 'value'] 
+		let radimeth = ['blur', 'click', 'focus', 'select', 'onBlur', 'onFocus']
+		call map(radimeth, 'v:val."("')
+		let radis = radiprop + radimeth
+		" Reset - accessible only by other properties
+		let reseprop = ['accept', 'accessKey', 'align', 'alt', 'defaultValue', 
+					\ 'disabled', 'form', 'id', 'name', 'size', 'tabIndex', 'type', 'value'] 
+		let resemeth = ['blur', 'click', 'focus', 'select', 'onBlur', 'onFocus']
+		call map(resemeth, 'v:val."("')
+		let reses = reseprop + resemeth
+		" Submit - accessible only by other properties
+		let submprop = ['accept', 'accessKey', 'align', 'alt', 'defaultValue', 
+					\ 'disabled', 'form', 'id', 'name', 'size', 'tabIndex', 'type', 'value'] 
+		let submmeth = ['blur', 'click', 'focus', 'select', 'onClick', 'onSelectStart']
+		call map(submmeth, 'v:val."("')
+		let subms = submprop + submmeth
+		" Text - accessible only by other properties
+		let textprop = ['accept', 'accessKey', 'align', 'alt', 'defaultValue', 
+					\ 'disabled', 'form', 'id', 'maxLength', 'name', 'readOnly', 
+					\ 'size', 'tabIndex', 'type', 'value'] 
+		let textmeth = ['blur', 'focus', 'select', 'onBlur', 'onChange', 'onFocus', 'onKeyDown',
+					\ 'onKeyPress', 'onKeyUp', 'onSelect']
+		call map(textmeth, 'v:val."("')
+		let texts = textprop + textmeth
+		" Link - link.
+		let linkprop = ['charset', 'disabled', 'href', 'hreflang', 'id', 'media',
+					\ 'rel', 'rev', 'target', 'type']
+		let linkmeth = ['onLoad']
+		call map(linkmeth, 'v:val."("')
+		let links = linkprop + linkmeth
+		" Location - location.
+		let locaprop = ['href', 'hash', 'host', 'hostname', 'pathname', 'port', 'protocol',
+					\ 'search']
+		let locameth = ['assign', 'reload', 'replace']
+		call map(locameth, 'v:val."("')
+		let locas = locaprop + locameth
+		" Meta - meta.
+		let metaprop = ['charset', 'content', 'disabled', 'httpEquiv', 'name', 'scheme']
+		let metas = metaprop
+		" Navigator - navigator.
+		let naviprop = ['plugins', 'appCodeName', 'appName', 'appVersion', 'cookieEnabled',
+					\ 'platform', 'userAgent']
+		let navimeth = ['javaEnabled', 'taintEnabled']
+		call map(navimeth, 'v:val."("')
+		let navis = naviprop + navimeth
+		" Object - object.
+		let objeprop = ['align', 'archive', 'border', 'code', 'codeBase', 'codeType', 'data',
+					\ 'declare', 'form', 'height', 'hspace', 'id', 'name', 'standby', 'tabIndex',
+					\ 'type', 'useMap', 'vspace', 'width']
+		let objes = objeprop
+		" Option - accessible only by other properties
+		let optiprop = ['defaultSelected', 
+					\ 'disabled', 'form', 'id', 'index', 'label', 'selected', 'text', 'value']
+		let optis = optiprop
+		" Screen - screen.
+		let screprop = ['availHeight', 'availWidth', 'colorDepth', 'height', 'width']
+		let scres = screprop
+		" Select - accessible only by other properties
+		let seleprop = ['options', 'disabled', 'form', 'id', 'length', 'multiple', 'name', 
+					\ 'selectedIndex', 'size', 'tabIndex', 'type', 'value'] 
+		let selemeth = ['blur', 'focus', 'remove', 'onBlur', 'onChange', 'onFocus']
+		call map(selemeth, 'v:val."("')
+		let seles = seleprop + selemeth
+		" Style - style.
+		let stylprop = ['background', 'backgroundAttachment', 'backgroundColor', 'backgroundImage',
+					\ 'backgroundPosition', 'backgroundRepeat',
+					\ 'border', 'borderBottom', 'borderLeft', 'borderRight', 'borderTop',
+					\ 'borderBottomColor', 'borderLeftColor', 'borderRightColor', 'borderTopColor',
+					\ 'borderBottomStyle', 'borderLeftStyle', 'borderRightStyle', 'borderTopStyle',
+					\ 'borderBottomWidth', 'borderLeftWidth', 'borderRightWidth', 'borderTopWidth',
+					\ 'borderColor', 'borderStyle', 'borderWidth', 'margin', 'marginBottom',
+					\ 'marginLeft', 'marginRight', 'marginTop', 'outline', 'outlineStyle', 'outlineWidth',
+					\ 'outlineColor', 'outlineStyle', 'outlineWidth', 'padding', 'paddingBottom',
+					\ 'paddingLeft', 'paddingRight', 'paddingTop',
+					\ 'clear', 'clip', 'clipBottom', 'clipLeft', 'clipRight', 'clipTop', 'content',
+					\ 'counterIncrement', 'counterReset', 'cssFloat', 'cursor', 'direction',
+					\ 'display', 'markerOffset', 'marks', 'maxHeight', 'maxWidth', 'minHeight',
+					\ 'minWidth', 'overflow', 'overflowX', 'overflowY', 'verticalAlign', 'visibility',
+					\ 'width',
+					\ 'listStyle', 'listStyleImage', 'listStylePosition', 'listStyleType',
+					\ 'cssText', 'bottom', 'height', 'left', 'position', 'right', 'top', 'width', 'zindex',
+					\ 'orphans', 'widows', 'page', 'pageBreakAfter', 'pageBreakBefore', 'pageBreakInside',
+					\ 'borderCollapse', 'borderSpacing', 'captionSide', 'emptyCells', 'tableLayout',
+					\ 'color', 'font', 'fontFamily', 'fontSize', 'fontSizeAdjust', 'fontStretch',
+					\ 'fontStyle', 'fontVariant', 'fontWeight', 'letterSpacing', 'lineHeight', 'quotes',
+					\ 'textAlign', 'textIndent', 'textShadow', 'textTransform', 'textUnderlinePosition',
+					\ 'unicodeBidi', 'whiteSpace', 'wordSpacing']
+		let styls = stylprop
+		" Table - table.
+		let tablprop = ['rows', 'tBodies', 'align', 'bgColor', 'border', 'caption', 'cellPadding',
+					\ 'cellSpacing', 'frame', 'height', 'rules', 'summary', 'tFoot', 'tHead', 'width']
+		let tablmeth = ['createCaption', 'createTFoot', 'createTHead', 'deleteCaption', 'deleteRow',
+					\ 'deleteTFoot', 'deleteTHead', 'insertRow']
+		call map(tablmeth, 'v:val."("')
+		let tabls = tablprop + tablmeth
+		" Table data - TableData.
+		let tdatprop = ['abbr', 'align', 'axis', 'bgColor', 'cellIndex', 'ch', 'chOff',
+					\ 'colSpan', 'headers', 'noWrap', 'rowSpan', 'scope', 'vAlign', 'width']
+		let tdats = tdatprop
+		" Table row - TableRow.
+		let trowprop = ['cells', 'align', 'bgColor', 'ch', 'chOff', 'rowIndex', 'sectionRowIndex',
+					\ 'vAlign']
+		let trowmeth = ['deleteCell', 'insertCell']
+		call map(trowmeth, 'v:val."("')
+		let trows = trowprop + trowmeth
+		" Textarea - accessible only by other properties
+		let tareprop = ['accessKey', 'cols', 'defaultValue', 
+					\ 'disabled', 'form', 'id', 'name', 'readOnly', 'rows', 
+					\ 'tabIndex', 'type', 'value', 'selectionStart', 'selectionEnd'] 
+		let taremeth = ['blur', 'focus', 'select', 'onBlur', 'onChange', 'onFocus']
+		call map(taremeth, 'v:val."("')
+		let tares = tareprop + taremeth
+		" Window - window.
+		let windprop = ['frames', 'closed', 'defaultStatus', 'encodeURI', 'event', 'history',
+					\ 'length', 'location', 'name', 'onload', 'opener', 'parent', 'screen', 'self',
+					\ 'status', 'top', 'XMLHttpRequest', 'ActiveXObject']
+		let windmeth = ['alert', 'blur', 'clearInterval', 'clearTimeout', 'close', 'confirm', 'focus',
+					\ 'moveBy', 'moveTo', 'open', 'print', 'prompt', 'scrollBy', 'scrollTo', 'setInterval',
+					\ 'setTimeout']
+		call map(windmeth, 'v:val."("')
+		let winds = windprop + windmeth
+		" XMLHttpRequest - access by new xxx()
+		let xmlhprop = ['onreadystatechange', 'readyState', 'responseText', 'responseXML',
+					\ 'status', 'statusText', 'parseError']
+		let xmlhmeth = ['abort', 'getAllResponseHeaders', 'getResponseHeaders', 'open',
+					\ 'send', 'setRequestHeader']
+		call map(xmlhmeth, 'v:val."("')
+		let xmlhs = xmlhprop + xmlhmeth
+
+		" XML DOM
+		" Attributes - element.attributes[x].
+		let xdomattrprop = ['name', 'specified', 'value']
+		" Element - anyelement.
+		let xdomelemprop = ['attributes', 'childNodes', 'firstChild', 'lastChild', 
+					\ 'namespaceURI', 'nextSibling', 'nodeName', 'nodeType', 'nodeValue',
+					\ 'ownerDocument', 'parentNode', 'prefix', 'previousSibling', 'tagName']
+		let xdomelemmeth = ['appendChild', 'cloneNode', 'getAttribute', 'getAttributeNode',
+					\ 'getElementsByTagName', 'hasChildNodes', 'insertBefore', 'normalize',
+					\ 'removeAttribute', 'removeAttributeNode', 'removeChild', 'replaceChild',
+					\ 'setAttribute', 'setAttributeNode']
+		call map(xdomelemmeth, 'v:val."("')
+		let xdomelems = xdomelemprop + xdomelemmeth
+		" Node - anynode.
+		let xdomnodeprop = ['attributes', 'childNodes', 'firstChild', 'lastChild', 
+					\ 'namespaceURI', 'nextSibling', 'nodeName', 'nodeType', 'nodeValue',
+					\ 'ownerDocument', 'parentNode', 'prefix', 'previousSibling']
+		let xdomnodemeth = ['appendChild', 'cloneNode',
+					\ 'hasChildNodes', 'insertBefore', 'removeChild', 'replaceChild']
+		call map(xdomnodemeth, 'v:val."("')
+		let xdomnodes = xdomnodeprop + xdomnodemeth
+		" NodeList 
+		let xdomnliss = ['length', 'item(']
+		" Error - parseError.
+		let xdomerror = ['errorCode', 'reason', 'line', 'linepos', 'srcText', 'url', 'filepos']
+
+		" Find object type declaration to reduce number of suggestions. {{{
+		" 1. Get object name
+		" 2. Find object declaration line
+		" 3. General declaration follows "= new Type" syntax, additional else
+		"    for regexp "= /re/"
+		" 4. Make correction for Microsoft.XMLHTTP ActiveXObject
+		" 5. Repeat for external files
+		let object = matchstr(shortcontext, '\zs\k\+\ze\(\[.\{-}\]\)\?\.$')
+		if len(object) > 0
+			let decl_line = search(object.'.\{-}=\s*new\s*', 'bn')
+			if decl_line > 0
+				let object_type = matchstr(getline(decl_line), object.'.\{-}=\s*new\s*\zs\k\+\ze')
+				if object_type == 'ActiveXObject' && matchstr(getline(decl_line), object.'.\{-}=\s*new\s*ActiveXObject\s*(.Microsoft\.XMLHTTP.)') != ''
+						let object_type = 'XMLHttpRequest'
+				endif
+			else
+				let decl_line = search('var\s*'.object.'\s*=\s*\/', 'bn')
+				if decl_line > 0
+					let object_type = 'RegExp'
+				endif
+			endif
+			" We didn't find var declaration in current file but we may have
+			" something in external files.
+			if decl_line == 0 && exists("b:js_extfiles")
+				let dext_line = filter(copy(b:js_extfiles), 'v:val =~ "'.object.'.\\{-}=\\s*new\\s*"')
+				if len(dext_line) > 0
+					let object_type = matchstr(dext_line[-1], object.'.\{-}=\s*new\s*\zs\k\+\ze')
+					if object_type == 'ActiveXObject' && matchstr(dext_line[-1], object.'.\{-}=\s*new\s*ActiveXObject\s*(.Microsoft\.XMLHTTP.)') != ''
+							let object_type = 'XMLHttpRequest'
+					endif
+				else
+					let dext_line = filter(copy(b:js_extfiles), 'v:val =~ "var\s*'.object.'\\s*=\\s*\\/"')
+					if len(dext_line) > 0
+						let object_type = 'RegExp'
+					endif
+				endif
+			endif
+		endif
+		" }}}
+
+		if !exists('object_type')
+			let object_type = ''
+		endif
+
+		if object_type == 'Date'
+			let values = dates
+		elseif object_type == 'Image'
+			let values = imags
+		elseif object_type == 'Array'
+			let values = arrays
+		elseif object_type == 'Boolean'
+			" TODO: a bit more than real boolean
+			let values = arrays
+		elseif object_type == 'XMLHttpRequest'
+			let values = xmlhs
+		elseif object_type == 'String'
+			let values = stris
+		elseif object_type == 'RegExp'
+			let values = reges
+		elseif object_type == 'Math'
+			let values = maths
+		endif
+
+		if !exists('values')
+		" List of properties
+		if shortcontext =~ 'Math\.$'
+			let values = maths
+		elseif shortcontext =~ 'anchors\(\[.\{-}\]\)\?\.$'
+			let values = anths
+		elseif shortcontext =~ 'area\.$'
+			let values = areas
+		elseif shortcontext =~ 'base\.$'
+			let values = bases
+		elseif shortcontext =~ 'body\.$'
+			let values = bodys
+		elseif shortcontext =~ 'document\.$'
+			let values = docus
+		elseif shortcontext =~ 'forms\(\[.\{-}\]\)\?\.$'
+			let values = forms
+		elseif shortcontext =~ 'frameset\.$'
+			let values = fsets
+		elseif shortcontext =~ 'history\.$'
+			let values = hists
+		elseif shortcontext =~ 'iframe\.$'
+			let values = ifras
+		elseif shortcontext =~ 'images\(\[.\{-}\]\)\?\.$'
+			let values = imags
+		elseif shortcontext =~ 'links\(\[.\{-}\]\)\?\.$'
+			let values = links
+		elseif shortcontext =~ 'location\.$'
+			let values = locas
+		elseif shortcontext =~ 'meta\.$'
+			let values = metas
+		elseif shortcontext =~ 'navigator\.$'
+			let values = navis
+		elseif shortcontext =~ 'object\.$'
+			let values = objes
+		elseif shortcontext =~ 'screen\.$'
+			let values = scres
+		elseif shortcontext =~ 'style\.$'
+			let values = styls
+		elseif shortcontext =~ 'table\.$'
+			let values = tabls
+		elseif shortcontext =~ 'TableData\.$'
+			let values = tdats
+		elseif shortcontext =~ 'TableRow\.$'
+			let values = trows
+		elseif shortcontext =~ 'window\.$'
+			let values = winds
+		elseif shortcontext =~ 'parseError\.$'
+			let values = xdomerror
+		elseif shortcontext =~ 'attributes\[\d\+\]\.$'
+			let values = xdomattrprop
+		else
+			let values = user_props + arrays + dates + funcs + maths + numbs + objes + reges + stris
+			let values += doms + anths + areas + bases + bodys + docus + forms + frams + fsets + hists
+			let values += ifras + imags + links + locas + metas + navis + objes + scres
+			let values += tabls + trows + tares + winds
+			let values += xdomnodes + xdomnliss + xdomelems
+		endif
+		endif
+
+		for m in values
+			if m =~? '^'.a:base
+				call add(res, m)
+			elseif m =~? a:base
+				call add(res2, m)
+			endif
+		endfor
+
+		unlet! values
+		return res + res2
+
+	endif
+	" }}}
+
+	" Get variables data.
+	let variables = filter(copy(file), 'v:val =~ "var\\s"')
+	call map(variables, 'matchstr(v:val, ".\\{-}var\\s\\+\\zs.*\\ze")')
+	call map(variables, 'substitute(v:val, ";\\|$", ",", "g")')
+	let vars = []
+	" This loop (and next one) is necessary to get variable names from
+	" constructs like: var var1, var2, var3 = "something";
+	for i in range(len(variables))
+		let comma_separated = split(variables[i], ',\s*')
+		call map(comma_separated, 'matchstr(v:val, "\\k\\+")')
+		let vars += comma_separated
+	endfor
+
+	let variables = sort(vars)
+	unlet! vars
+
+	" Add "no var" variables.
+	let undeclared_variables = filter(copy(file), 'v:val =~ "^\\s*\\k\\+\\s*="')
+	let u_vars = []
+	for i in range(len(undeclared_variables))
+		let  split_equal = split(undeclared_variables[i], '\s*=')
+		call map(split_equal, 'matchstr(v:val, "\\k\\+$")')
+		let u_vars += split_equal
+	endfor
+
+	let variables += sort(u_vars)
+	unlet! u_vars
+
+	" Get functions
+	let functions = filter(copy(file), 'v:val =~ "^\\s*function\\s"')
+	let arguments = copy(functions)
+	call map(functions, 'matchstr(v:val, "^\\s*function\\s\\+\\zs\\k\\+")')
+	call map(functions, 'v:val."("')
+	let functions = sort(functions)
+
+	" Create table to keep arguments for additional 'menu' info
+	let b:js_menuinfo = {}
+	for i in arguments
+		let g:ia = i
+		let f_elements = matchlist(i, 'function\s\+\(\k\+\)\s*(\(.\{-}\))')
+		if len(f_elements) == 3
+			let b:js_menuinfo[f_elements[1].'('] = f_elements[2]
+		endif
+	endfor
+
+	" Get functions arguments
+	call map(arguments, 'matchstr(v:val, "function.\\{-}(\\zs.\\{-}\\ze)")')
+	let jargs = join(arguments, ',')
+	let jargs = substitute(jargs, '\s', '', 'g')
+	let arguments = split(jargs, ',')
+	let arguments = sort(arguments)
+
+	" Built-in functions
+	let builtin = ['alert(', 'confirm(']
+
+	" Top-level HTML DOM objects
+	let htmldom = ['document', 'anchor', 'area', 'base', 'body', 'document', 'event', 'form', 'frame', 'frameset', 'history', 'iframe', 'image', 'input', 'link', 'location', 'meta', 'navigator', 'object', 'option', 'screen', 'select', 'table', 'tableData', 'tableHeader', 'tableRow', 'textarea', 'window']
+	call map(htmldom, 'v:val."."')
+
+	" Top-level properties
+	let properties = ['decodeURI', 'decodeURIComponent', 'encodeURI', 'encodeURIComponent',
+				\ 'eval', 'Infinity', 'isFinite', 'isNaN', 'NaN', 'Number', 'parseFloat',
+				\ 'parseInt', 'String', 'undefined', 'escape', 'unescape']
+
+	" Keywords
+	let keywords = ["Array", "Boolean", "Date", "Function", "Math", "Number", "Object", "RegExp", "String", "XMLHttpRequest", "ActiveXObject", "abstract", "boolean", "break", "byte", "case", "catch", "char", "class", "const", "continue", "debugger", "default", "delete", "do", "double ", "else", "enum", "export", "extends", "false", "final", "finally", "float", "for", "function", "goto", "if", "implements", "import", "in ", "instanceof", "int", "interface", "long", "native", "new", "null", "package", "private", "protected", "public", "return", "short", "static", "super ", "switch", "synchronized", "this", "throw", "throws", "transient", "true", "try", "typeof", "var", "void", "volatile", "while", "with"]
+
+	let values = variables + functions + htmldom + arguments + builtin + properties + keywords
+
+	for m in values
+		if m =~? '^'.a:base
+			call add(res, m)
+		elseif m =~? a:base
+			call add(res2, m)
+		endif
+	endfor
+
+	let menu = res + res2
+	let final_menu = []
+	for i in range(len(menu))
+		let item = menu[i]
+		if item =~ '($'
+			let kind = 'f'
+			if has_key(b:js_menuinfo, item)
+				let m_info = b:js_menuinfo[item]
+			else
+				let m_info = ''
+			endif
+		else
+			let kind = 'v'
+			let m_info = ''
+		endif
+		let final_menu += [{'word':item, 'menu':m_info, 'kind':kind}]
+	endfor
+	let g:fm = final_menu
+	return final_menu
+
+endfunction
+
+" vim:set foldmethod=marker:
--- /dev/null
+++ b/lib/vimfiles/autoload/netrw.vim
@@ -1,0 +1,5353 @@
+" netrw.vim: Handles file transfer and remote directory listing across
+"            AUTOLOAD SECTION
+" Date:		May 05, 2007
+" Version:	109
+" Maintainer:	Charles E Campbell, Jr <NdrOchip@ScampbellPfamily.AbizM-NOSPAM>
+" GetLatestVimScripts: 1075 1 :AutoInstall: netrw.vim
+" Copyright:    Copyright (C) 1999-2007 Charles E. Campbell, Jr. {{{1
+"               Permission is hereby granted to use and distribute this code,
+"               with or without modifications, provided that this copyright
+"               notice is copied with it. Like anything else that's free,
+"               netrw.vim, netrwPlugin.vim, and netrwSettings.vim are provided
+"               *as is* and comes with no warranty of any kind, either
+"               expressed or implied. By using this plugin, you agree that
+"               in no event will the copyright holder be liable for any damages
+"               resulting from the use of this software.
+"               of this software.
+" COMBAK: worked with tmpfile s:GetTempname() in NetRead() NetWrite()
+"         !!NEEDS DEBUGGING && TESTING!!!
+"redraw!|call inputsave()|call input("Press <cr> to continue")|call inputrestore()
+"
+"  But be doers of the Word, and not only hearers, deluding your own selves {{{1
+"  (James 1:22 RSV)
+" =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
+" Load Once: {{{1
+if &cp || exists("g:loaded_netrw")
+  finish
+endif
+if !exists("s:NOTE")
+ let s:NOTE    = 0
+ let s:WARNING = 1
+ let s:ERROR   = 2
+endif
+let g:loaded_netrw = "v109"
+if v:version < 700
+ call netrw#ErrorMsg(s:WARNING,"you need vim version 7.0 or later for version ".g:loaded_netrw." of netrw",1)
+ finish
+endif
+let s:keepcpo= &cpo
+setlocal cpo&vim
+"DechoTabOn
+"call Decho("doing autoload/netrw.vim version ".g:loaded_netrw)
+
+" ======================
+"  Netrw Variables: {{{1
+" ======================
+
+" ---------------------------------------------------------------------
+"  Netrw Constants: {{{2
+if !exists("g:NETRW_BOOKMARKMAX")
+ let g:NETRW_BOOKMARKMAX= 0
+endif
+if !exists("g:NETRW_DIRHIST_CNT")
+ let g:NETRW_DIRHIST_CNT= 0
+endif
+if !exists("s:LONGLIST")
+ let s:THINLIST = 0
+ let s:LONGLIST = 1
+ let s:WIDELIST = 2
+ let s:TREELIST = 3
+ let s:MAXLIST  = 4
+endif
+
+" ---------------------------------------------------------------------
+" Default values for netrw's global protocol variables {{{2
+if !exists("g:netrw_dav_cmd")
+  let g:netrw_dav_cmd	= "cadaver"
+endif
+if !exists("g:netrw_fetch_cmd")
+ if executable("fetch")
+  let g:netrw_fetch_cmd	= "fetch -o"
+ else
+  let g:netrw_fetch_cmd	= ""
+ endif
+endif
+if !exists("g:netrw_ftp_cmd")
+  let g:netrw_ftp_cmd	= "ftp"
+endif
+if !exists("g:netrw_http_cmd")
+ if executable("curl")
+  let g:netrw_http_cmd	= "curl -o"
+ elseif executable("wget")
+  let g:netrw_http_cmd	= "wget -q -O"
+ elseif executable("fetch")
+  let g:netrw_http_cmd	= "fetch -o"
+ else
+  let g:netrw_http_cmd	= ""
+ endif
+endif
+if !exists("g:netrw_rcp_cmd")
+  let g:netrw_rcp_cmd	= "rcp"
+endif
+if !exists("g:netrw_rsync_cmd")
+  let g:netrw_rsync_cmd	= "rsync"
+endif
+if !exists("g:netrw_scp_cmd")
+  let g:netrw_scp_cmd	= "scp -q"
+endif
+if !exists("g:netrw_sftp_cmd")
+  let g:netrw_sftp_cmd	= "sftp"
+endif
+if !exists("g:netrw_ssh_cmd")
+ let g:netrw_ssh_cmd= "ssh"
+endif
+
+if (has("win32") || has("win95") || has("win64") || has("win16"))
+  \ && exists("g:netrw_use_nt_rcp")
+  \ && g:netrw_use_nt_rcp
+  \ && executable( $SystemRoot .'/system32/rcp.exe')
+ let s:netrw_has_nt_rcp = 1
+ let s:netrw_rcpmode    = '-b'
+else
+ let s:netrw_has_nt_rcp = 0
+ let s:netrw_rcpmode    = ''
+endif
+
+" ---------------------------------------------------------------------
+" Default values for netrw's global variables {{{2
+" Default values - a-c ---------- {{{3
+if !exists("g:netrw_alto")
+ let g:netrw_alto= &sb
+endif
+if !exists("g:netrw_altv")
+ let g:netrw_altv= &spr
+endif
+if !exists("g:netrw_browse_split")
+ let g:netrw_browse_split= 0
+endif
+if !exists("g:netrw_chgwin")
+ let g:netrw_chgwin    = -1
+endif
+if !exists("g:netrw_cygwin")
+ if has("win32") || has("win95") || has("win64") || has("win16")
+  if &shell =~ '\%(\<bash\>\|\<zsh\>\)\%(\.exe\)\=$'
+   let g:netrw_cygwin= 1
+  else
+   let g:netrw_cygwin= 0
+  endif
+ else
+  let g:netrw_cygwin= 0
+ endif
+else
+ let g:netrw_cygwin= 0
+endif
+" Default values - d-f ---------- {{{3
+if !exists("g:NETRW_DIRHIST_CNT")
+ let g:NETRW_DIRHIST_CNT= 0
+endif
+if !exists("g:netrw_dirhistmax")
+ let g:netrw_dirhistmax= 10
+endif
+if !exists("g:netrw_ftp_browse_reject")
+ let g:netrw_ftp_browse_reject='^total\s\+\d\+$\|^Trying\s\+\d\+.*$\|^KERBEROS_V\d rejected\|^Security extensions not\|No such file\|: connect to address [0-9a-fA-F:]*: No route to host$'
+endif
+if !exists("g:netrw_ftp_list_cmd")
+ if has("unix") || (exists("g:netrw_cygwin") && g:netrw_cygwin)
+  let g:netrw_ftp_list_cmd     = "ls -lF"
+  let g:netrw_ftp_timelist_cmd = "ls -tlF"
+  let g:netrw_ftp_sizelist_cmd = "ls -slF"
+ else
+  let g:netrw_ftp_list_cmd     = "dir"
+  let g:netrw_ftp_timelist_cmd = "dir"
+  let g:netrw_ftp_sizelist_cmd = "dir"
+ endif
+endif
+if !exists("g:netrw_ftpmode")
+ let g:netrw_ftpmode= "binary"
+endif
+" Default values - h-lh ---------- {{{3
+if !exists("g:netrw_hide")
+ let g:netrw_hide= 1
+endif
+if !exists("g:netrw_ignorenetrc")
+ if &shell =~ '\c\<\%(cmd\|4nt\)\.exe$'
+  let g:netrw_ignorenetrc= 1
+ else
+  let g:netrw_ignorenetrc= 0
+ endif
+endif
+if !exists("g:netrw_keepdir")
+ let g:netrw_keepdir= 1
+endif
+if !exists("g:netrw_list_cmd")
+ if g:netrw_scp_cmd =~ '^pscp' && executable("pscp")
+  " provide a 'pscp' listing command
+  if (has("win32") || has("win95") || has("win64") || has("win16")) && filereadable("c:\\private.ppk")
+   let g:netrw_scp_cmd ="pscp -i C:\\private.ppk"
+  endif
+  let g:netrw_list_cmd= g:netrw_scp_cmd." -ls USEPORT HOSTNAME:"
+ elseif executable(g:netrw_ssh_cmd)
+  " provide a default listing command
+  let g:netrw_list_cmd= g:netrw_ssh_cmd." USEPORT HOSTNAME ls -FLa"
+ else
+"  call Decho(g:netrw_ssh_cmd." is not executable")
+  let g:netrw_list_cmd= ""
+ endif
+endif
+if !exists("g:netrw_list_hide")
+ let g:netrw_list_hide= ""
+endif
+" Default values - lh-lz ---------- {{{3
+if !exists("g:netrw_local_mkdir")
+ let g:netrw_local_mkdir= "mkdir"
+endif
+if !exists("g:netrw_local_rmdir")
+ let g:netrw_local_rmdir= "rmdir"
+endif
+if !exists("g:netrw_liststyle")
+ let g:netrw_liststyle= s:THINLIST
+endif
+if g:netrw_liststyle < 0 || g:netrw_liststyle >= s:MAXLIST
+ " sanity check
+ let g:netrw_liststyle= s:THINLIST
+endif
+if g:netrw_liststyle == s:LONGLIST && g:netrw_scp_cmd !~ '^pscp'
+ let g:netrw_list_cmd= g:netrw_list_cmd." -l"
+endif
+" Default values - m-r ---------- {{{3
+if !exists("g:netrw_maxfilenamelen")
+ let g:netrw_maxfilenamelen= 32
+endif
+if !exists("g:netrw_menu")
+ let g:netrw_menu= 1
+endif
+if !exists("g:netrw_mkdir_cmd")
+ let g:netrw_mkdir_cmd= g:netrw_ssh_cmd." USEPORT HOSTNAME mkdir"
+endif
+if !exists("g:netrw_scpport")
+ let g:netrw_scpport= "-P"
+endif
+if !exists("g:netrw_sshport")
+ let g:netrw_sshport= "-p"
+endif
+if !exists("g:netrw_rename_cmd")
+ let g:netrw_rename_cmd= g:netrw_ssh_cmd." USEPORT HOSTNAME mv"
+endif
+if !exists("g:netrw_rm_cmd")
+ let g:netrw_rm_cmd    = g:netrw_ssh_cmd." USEPORT HOSTNAME rm"
+endif
+if !exists("g:netrw_rmdir_cmd")
+ let g:netrw_rmdir_cmd = g:netrw_ssh_cmd." USEPORT HOSTNAME rmdir"
+endif
+if !exists("g:netrw_rmf_cmd")
+ let g:netrw_rmf_cmd    = g:netrw_ssh_cmd." USEPORT HOSTNAME rm -f"
+endif
+" Default values - s ---------- {{{3
+if exists("g:netrw_silent") && g:netrw_silent != 0
+ let g:netrw_silentxfer= "silent "
+else
+ let g:netrw_silentxfer= ""
+endif
+if !exists("g:netrw_fastbrowse")
+ let g:netrw_fastbrowse= 1
+endif
+if !exists("g:netrw_shq")
+ if exists("&shq") && &shq != ""
+  let g:netrw_shq= &shq
+ elseif has("win32") || has("win95") || has("win64") || has("win16")
+  if g:netrw_cygwin
+   let g:netrw_shq= "'"
+  else
+   let g:netrw_shq= '"'
+  endif
+ else
+  let g:netrw_shq= "'"
+ endif
+" call Decho("g:netrw_shq<".g:netrw_shq.">")
+endif
+if !exists("g:netrw_sort_by")
+ " alternatives: date size
+ let g:netrw_sort_by= "name"
+endif
+if !exists("g:netrw_sort_direction")
+ " alternative: reverse  (z y x ...)
+ let g:netrw_sort_direction= "normal"
+endif
+if !exists("g:netrw_sort_sequence")
+ let g:netrw_sort_sequence= '[\/]$,\.h$,\.c$,\.cpp$,\.[a-np-z]$,*,\.info$,\.swp$,\.o$\.obj$,\.bak$'
+endif
+if !exists("g:netrw_ssh_browse_reject")
+  let g:netrw_ssh_browse_reject='^total\s\+\d\+$'
+endif
+if !has("patch192")
+ if !exists("g:netrw_use_noswf")
+  let g:netrw_use_noswf= 1
+ endif
+else
+  let g:netrw_use_noswf= 0
+endif
+" Default values - t-w ---------- {{{3
+if !exists("g:netrw_timefmt")
+ let g:netrw_timefmt= "%c"
+endif
+if !exists("g:NetrwTopLvlMenu")
+ let g:NetrwTopLvlMenu= "Netrw."
+endif
+if !exists("g:netrw_use_errorwindow")
+ let g:netrw_use_errorwindow= 1
+endif
+if !exists("g:netrw_win95ftp")
+ let g:netrw_win95ftp= 1
+endif
+if !exists("g:netrw_winsize")
+ let g:netrw_winsize= ""
+endif
+" ---------------------------------------------------------------------
+" Default values for netrw's script variables: {{{2
+if !exists("s:netrw_cd_escape")
+  let s:netrw_cd_escape="[]#*$%'\" ?`!&();<>\\"
+endif
+if !exists("g:netrw_fname_escape")
+ let g:netrw_fname_escape= ' ?&;'
+endif
+if !exists("g:netrw_tmpfile_escape")
+ let g:netrw_tmpfile_escape= ' ?&;'
+endif
+if !exists("s:netrw_glob_escape")
+  let s:netrw_glob_escape= '[]*?`{~$'
+endif
+
+" BufEnter event ignored by decho when following variable is true
+"  Has a side effect that doau BufReadPost doesn't work, so
+"  files read by network transfer aren't appropriately highlighted.
+"let g:decho_bufenter = 1	"Decho
+
+" ==============================
+"  Netrw Utility Functions: {{{1
+" ==============================
+
+" ------------------------------------------------------------------------
+" NetSavePosn: saves position of cursor on screen {{{2
+fun! netrw#NetSavePosn()
+"  call Dfunc("netrw#NetSavePosn()")
+  " Save current line and column
+  let w:netrw_winnr= winnr()
+  let w:netrw_line = line(".")
+  let w:netrw_col  = virtcol(".")
+
+  " Save top-of-screen line
+  norm! H0
+  let w:netrw_hline= line(".")
+
+  call netrw#NetRestorePosn()
+"  call Dret("netrw#NetSavePosn : winnr=".w:netrw_winnr." line=".w:netrw_line." col=".w:netrw_col." hline=".w:netrw_hline)
+endfun
+
+" ------------------------------------------------------------------------
+" NetRestorePosn: restores the cursor and file position as saved by NetSavePosn() {{{2
+fun! netrw#NetRestorePosn()
+"  call Dfunc("netrw#NetRestorePosn() winnr=".(exists("w:netrw_winnr")? w:netrw_winnr : -1)." line=".(exists("w:netrw_line")? w:netrw_line : -1)." col=".(exists("w:netrw_col")? w:netrw_col : -1)." hline=".(exists("w:netrw_hline")? w:netrw_hline : -1))
+  let eikeep= &ei
+  set ei=all
+  if expand("%") == "NetrwMessage"
+   exe s:winBeforeErr."wincmd w"
+  endif
+
+  " restore window
+  if exists("w:netrw_winnr")
+"   call Decho("restore window: exe silent! ".w:netrw_winnr."wincmd w")
+   exe "silent! ".w:netrw_winnr."wincmd w"
+  endif
+  if v:shell_error == 0
+   " as suggested by Bram M: redraw on no error
+   " allows protocol error messages to remain visible
+   redraw!
+  endif
+
+  " restore top-of-screen line
+  if exists("w:netrw_hline")
+"   call Decho("restore topofscreen: exe norm! ".w:netrw_hline."G0z")
+   exe "norm! ".w:netrw_hline."G0z\<CR>"
+  endif
+
+  " restore position
+  if exists("w:netrw_line") && exists("w:netrw_col")
+"   call Decho("restore posn: exe norm! ".w:netrw_line."G0".w:netrw_col."|")
+   exe "norm! ".w:netrw_line."G0".w:netrw_col."\<bar>"
+  endif
+
+  let &ei= eikeep
+"  call Dret("netrw#NetRestorePosn")
+endfun
+
+" ===============================
+" NetOptionSave: save options and set to "standard" form {{{2
+"DechoTabOn
+fun! s:NetOptionSave()
+"  call Dfunc("s:NetOptionSave() win#".winnr()." buf#".bufnr("."))
+  if !exists("w:netrw_optionsave")
+   let w:netrw_optionsave= 1
+  else
+"   call Dret("s:NetOptionSave : netoptionsave=".w:netrw_optionsave)
+   return
+  endif
+
+  " Save current settings and current directory
+  let s:yykeep          = @@
+  if exists("&l:acd")
+   let w:netrw_acdkeep  = &l:acd
+  endif
+  let w:netrw_aikeep    = &l:ai
+  let w:netrw_awkeep    = &l:aw
+  let w:netrw_cikeep    = &l:ci
+  let w:netrw_cinkeep   = &l:cin
+  let w:netrw_cinokeep  = &l:cino
+  let w:netrw_comkeep   = &l:com
+  let w:netrw_cpokeep   = &l:cpo
+  if g:netrw_keepdir
+   let w:netrw_dirkeep  = getcwd()
+  endif
+  let w:netrw_fokeep    = &l:fo           " formatoptions
+  let w:netrw_gdkeep    = &l:gd           " gdefault
+  let w:netrw_hidkeep   = &l:hidden
+  let w:netrw_magickeep = &l:magic
+  let w:netrw_repkeep   = &l:report
+  let w:netrw_spellkeep = &l:spell
+  let w:netrw_twkeep    = &l:tw           " textwidth
+  let w:netrw_wigkeep   = &l:wig          " wildignore
+  if has("win32") && !has("win95")
+   let w:netrw_swfkeep= &l:swf            " swapfile
+  endif
+  call s:NetrwSafeOptions()
+  if &go =~ 'a' | silent! let w:netrw_regstar = @* | endif
+  silent! let w:netrw_regslash= @/
+
+"  call Dret("s:NetOptionSave")
+"  call Dret("s:NetOptionSave : win#".winnr()." buf#".bufnr("."))
+endfun
+
+" ------------------------------------------------------------------------
+" NetOptionRestore: restore options {{{2
+fun! s:NetOptionRestore()
+"  call Dfunc("s:NetOptionRestore() win#".winnr()." buf#".bufnr("."))
+  if !exists("w:netrw_optionsave")
+"   call Dret("s:NetOptionRestore : w:netrw_optionsave doesn't exist")
+   return
+  endif
+  unlet w:netrw_optionsave
+
+  if exists("&acd")
+   if exists("w:netrw_acdkeep") |let &l:acd    = w:netrw_acdkeep     |unlet w:netrw_acdkeep  |endif
+  endif
+  if exists("w:netrw_aikeep")   |let &l:ai     = w:netrw_aikeep      |unlet w:netrw_aikeep   |endif
+  if exists("w:netrw_awkeep")   |let &l:aw     = w:netrw_awkeep      |unlet w:netrw_awkeep   |endif
+  if exists("w:netrw_cikeep")   |let &l:ci     = w:netrw_cikeep      |unlet w:netrw_cikeep   |endif
+  if exists("w:netrw_cinkeep")  |let &l:cin    = w:netrw_cinkeep     |unlet w:netrw_cinkeep  |endif
+  if exists("w:netrw_cinokeep") |let &l:cino   = w:netrw_cinokeep    |unlet w:netrw_cinokeep |endif
+  if exists("w:netrw_comkeep")  |let &l:com    = w:netrw_comkeep     |unlet w:netrw_comkeep  |endif
+  if exists("w:netrw_cpokeep")  |let &l:cpo    = w:netrw_cpokeep     |unlet w:netrw_cpokeep  |endif
+  if exists("w:netrw_dirkeep")  |exe "lcd ".w:netrw_dirkeep          |unlet w:netrw_dirkeep  |endif
+  if exists("w:netrw_fokeep")   |let &l:fo     = w:netrw_fokeep      |unlet w:netrw_fokeep   |endif
+  if exists("w:netrw_gdkeep")   |let &l:gd     = w:netrw_gdkeep      |unlet w:netrw_gdkeep   |endif
+  if exists("w:netrw_hidkeep")  |let &l:hidden = w:netrw_hidkeep     |unlet w:netrw_hidkeep  |endif
+  if exists("w:netrw_magic")    |let &l:magic  = w:netrw_magic       |unlet w:netrw_magic    |endif
+  if exists("w:netrw_repkeep")  |let &l:report = w:netrw_repkeep     |unlet w:netrw_repkeep  |endif
+  if exists("w:netrw_spellkeep")|let &l:spell  = w:netrw_spellkeep   |unlet w:netrw_spellkeep|endif
+  if exists("w:netrw_twkeep")   |let &l:tw     = w:netrw_twkeep      |unlet w:netrw_twkeep   |endif
+  if exists("w:netrw_wigkeep")  |let &l:wig    = w:netrw_wigkeep     |unlet w:netrw_wigkeep  |endif
+  if exists("s:yykeep")         |let  @@       = s:yykeep            |unlet s:yykeep         |endif
+  if exists("w:netrw_swfkeep")
+   if &directory == ""
+    " user hasn't specified a swapfile directory;
+    " netrw will temporarily set the swapfile directory
+    " to the current directory as returned by getcwd().
+    let &l:directory   = getcwd()
+    silent! let &l:swf = w:netrw_swfkeep
+    setlocal directory=
+    unlet w:netrw_swfkeep
+   elseif &l:swf != w:netrw_swfkeep
+    " following line causes a Press ENTER in windows -- can't seem to work around it!!! (COMBAK)
+    silent! let &l:swf= w:netrw_swfkeep
+    unlet w:netrw_swfkeep
+   endif
+  endif
+  if exists("w:netrw_regstar") |silent! let @*= w:netrw_regstar |unlet w:netrw_regstar |endif
+  if exists("w:netrw_regslash")|silent! let @/= w:netrw_regslash|unlet w:netrw_regslash|endif
+
+"  call Dret("s:NetOptionRestore : win#".winnr()." buf#".bufnr("."))
+endfun
+
+" ---------------------------------------------------------------------
+" NetrwSafeOptions: sets options to help netrw do its job {{{2
+fun! s:NetrwSafeOptions()
+"  call Dfunc("s:NetrwSafeOptions()")
+  setlocal cino=
+  setlocal com=
+  setlocal cpo-=aA
+  if exists("&acd")
+   setlocal noacd nocin noai noci magic nospell nohid wig= noaw
+   setlocal fo=nroql2
+  else
+   setlocal nocin noai noci magic nospell nohid wig= noaw
+   setlocal fo=nroql2
+  endif
+  setlocal tw=0
+  setlocal report=10000
+  if g:netrw_use_noswf && has("win32") && !has("win95")
+   setlocal noswf
+  endif
+"  call Dret("s:NetrwSafeOptions")
+endfun
+
+" ------------------------------------------------------------------------
+"  Netrw Transfer Functions: {{{1
+" ===============================
+
+" ------------------------------------------------------------------------
+" NetRead: responsible for reading a file over the net {{{2
+"   mode: =0 read remote file and insert before current line
+"         =1 read remote file and insert after current line
+"         =2 replace with remote file
+"         =3 obtain file, but leave in temporary format
+fun! netrw#NetRead(mode,...)
+"  call Dfunc("netrw#NetRead(mode=".a:mode.",...) a:0=".a:0." ".g:loaded_netrw)
+
+  " save options {{{3
+  call s:NetOptionSave()
+
+  " interpret mode into a readcmd {{{3
+  if     a:mode == 0 " read remote file before current line
+   let readcmd = "0r"
+  elseif a:mode == 1 " read file after current line
+   let readcmd = "r"
+  elseif a:mode == 2 " replace with remote file
+   let readcmd = "%r"
+  elseif a:mode == 3 " skip read of file (leave as temporary)
+   let readcmd = "t"
+  else
+   exe a:mode
+   let readcmd = "r"
+  endif
+  let ichoice = (a:0 == 0)? 0 : 1
+"  call Decho("readcmd<".readcmd."> ichoice=".ichoice)
+
+  " Get Temporary Filename {{{3
+  let tmpfile= s:GetTempfile("")
+  if tmpfile == ""
+"   call Dret("netrw#NetRead : unable to get a tempfile!")
+   return
+  endif
+
+  while ichoice <= a:0
+
+   " attempt to repeat with previous host-file-etc
+   if exists("b:netrw_lastfile") && a:0 == 0
+"    call Decho("using b:netrw_lastfile<" . b:netrw_lastfile . ">")
+    let choice = b:netrw_lastfile
+    let ichoice= ichoice + 1
+
+   else
+    exe "let choice= a:" . ichoice
+"    call Decho("no lastfile: choice<" . choice . ">")
+
+    if match(choice,"?") == 0
+     " give help
+     echomsg 'NetRead Usage:'
+     echomsg ':Nread machine:path                         uses rcp'
+     echomsg ':Nread "machine path"                       uses ftp   with <.netrc>'
+     echomsg ':Nread "machine id password path"           uses ftp'
+     echomsg ':Nread dav://machine[:port]/path            uses cadaver'
+     echomsg ':Nread fetch://machine/path                 uses fetch'
+     echomsg ':Nread ftp://[user@]machine[:port]/path     uses ftp   autodetects <.netrc>'
+     echomsg ':Nread http://[user@]machine/path           uses http  wget'
+     echomsg ':Nread rcp://[user@]machine/path            uses rcp'
+     echomsg ':Nread rsync://machine[:port]/path          uses rsync'
+     echomsg ':Nread scp://[user@]machine[[:#]port]/path  uses scp'
+     echomsg ':Nread sftp://[user@]machine[[:#]port]/path uses sftp'
+     sleep 4
+     break
+
+    elseif match(choice,'^"') != -1
+     " Reconstruct Choice if choice starts with '"'
+"     call Decho("reconstructing choice")
+     if match(choice,'"$') != -1
+      " case "..."
+      let choice=strpart(choice,1,strlen(choice)-2)
+     else
+       "  case "... ... ..."
+      let choice      = strpart(choice,1,strlen(choice)-1)
+      let wholechoice = ""
+
+      while match(choice,'"$') == -1
+       let wholechoice = wholechoice . " " . choice
+       let ichoice     = ichoice + 1
+       if ichoice > a:0
+       	if !exists("g:netrw_quiet")
+	 call netrw#ErrorMsg(s:ERROR,"Unbalanced string in filename '". wholechoice ."'",3)
+	endif
+"        call Dret("netrw#NetRead :2 getcwd<".getcwd().">")
+        return
+       endif
+       let choice= a:{ichoice}
+      endwhile
+      let choice= strpart(wholechoice,1,strlen(wholechoice)-1) . " " . strpart(choice,0,strlen(choice)-1)
+     endif
+    endif
+   endif
+
+"   call Decho("choice<" . choice . ">")
+   let ichoice= ichoice + 1
+
+   " Determine method of read (ftp, rcp, etc) {{{3
+   call s:NetMethod(choice)
+   let tmpfile= s:GetTempfile(b:netrw_fname) " apply correct suffix
+
+   " Check if NetBrowse() should be handling this request
+"   call Decho("checking if NetBrowse() should handle choice<".choice."> with netrw_list_cmd<".g:netrw_list_cmd.">")
+   if choice =~ "^.*[\/]$" && b:netrw_method != 5 && choice !~ '^http://'
+"    call Decho("yes, choice matches '^.*[\/]$'")
+    keepjumps call s:NetBrowse(0,choice)
+"    call Dret("netrw#NetRead :3 getcwd<".getcwd().">")
+    return
+   endif
+
+   " ============
+   " Perform Protocol-Based Read {{{3
+   " ===========================
+   if exists("g:netrw_silent") && g:netrw_silent == 0 && &ch >= 1
+    echo "(netrw) Processing your read request..."
+   endif
+
+   ".........................................
+   " rcp:  NetRead Method #1 {{{3
+   if  b:netrw_method == 1 " read with rcp
+"    call Decho("read via rcp (method #1)")
+   " ER: nothing done with g:netrw_uid yet?
+   " ER: on Win2K" rcp machine[.user]:file tmpfile
+   " ER: if machine contains '.' adding .user is required (use $USERNAME)
+   " ER: the tmpfile is full path: rcp sees C:\... as host C
+   if s:netrw_has_nt_rcp == 1
+    if exists("g:netrw_uid") &&	( g:netrw_uid != "" )
+     let uid_machine = g:netrw_machine .'.'. g:netrw_uid
+    else
+     " Any way needed it machine contains a '.'
+     let uid_machine = g:netrw_machine .'.'. $USERNAME
+    endif
+   else
+    if exists("g:netrw_uid") &&	( g:netrw_uid != "" )
+     let uid_machine = g:netrw_uid .'@'. g:netrw_machine
+    else
+     let uid_machine = g:netrw_machine
+    endif
+   endif
+"   call Decho("executing: !".g:netrw_rcp_cmd." ".s:netrw_rcpmode." ".uid_machine.":".escape(b:netrw_fname,' ?&;')." ".tmpfile)
+   exe g:netrw_silentxfer."!".g:netrw_rcp_cmd." ".s:netrw_rcpmode." ".uid_machine.":".escape(b:netrw_fname,' ?&;')." ".tmpfile
+   let result           = s:NetGetFile(readcmd, tmpfile, b:netrw_method)
+   let b:netrw_lastfile = choice
+
+   ".........................................
+   " ftp + <.netrc>:  NetRead Method #2 {{{3
+   elseif b:netrw_method  == 2		" read with ftp + <.netrc>
+"     call Decho("read via ftp+.netrc (method #2)")
+     let netrw_fname= b:netrw_fname
+     new
+     setlocal ff=unix
+     exe "put ='".g:netrw_ftpmode."'"
+"     call Decho("filter input: ".getline("."))
+     if exists("g:netrw_ftpextracmd")
+      exe "put ='".g:netrw_ftpextracmd."'"
+"      call Decho("filter input: ".getline("."))
+     endif
+     exe "put ='".'get \"'.netrw_fname.'\" '.tmpfile."'"
+"     call Decho("filter input: ".getline("."))
+     if exists("g:netrw_port") && g:netrw_port != ""
+"      call Decho("executing: %!".g:netrw_ftp_cmd." -i ".g:netrw_machine." ".g:netrw_port)
+      exe g:netrw_silentxfer."%!".g:netrw_ftp_cmd." -i ".g:netrw_machine." ".g:netrw_port
+     else
+"      call Decho("executing: %!".g:netrw_ftp_cmd." -i ".g:netrw_machine)
+      exe g:netrw_silentxfer."%!".g:netrw_ftp_cmd." -i ".g:netrw_machine
+     endif
+     " If the result of the ftp operation isn't blank, show an error message (tnx to Doug Claar)
+     if getline(1) !~ "^$" && !exists("g:netrw_quiet") && getline(1) !~ '^Trying '
+      let debugkeep= &debug
+      setlocal debug=msg
+      call netrw#ErrorMsg(s:ERROR,getline(1),4)
+      let &debug= debugkeep
+     endif
+     bd!
+     let result           = s:NetGetFile(readcmd, tmpfile, b:netrw_method)
+     let b:netrw_lastfile = choice
+
+   ".........................................
+   " ftp + machine,id,passwd,filename:  NetRead Method #3 {{{3
+   elseif b:netrw_method == 3		" read with ftp + machine, id, passwd, and fname
+    " Construct execution string (four lines) which will be passed through filter
+"    call Decho("read via ftp+mipf (method #3)")
+    let netrw_fname= escape(b:netrw_fname,g:netrw_fname_escape)
+    new
+    setlocal ff=unix
+    if exists("g:netrw_port") && g:netrw_port != ""
+     put ='open '.g:netrw_machine.' '.g:netrw_port
+"     call Decho("filter input: ".getline("."))
+    else
+     put ='open '.g:netrw_machine
+"     call Decho("filter input: ".getline("."))
+    endif
+
+    if exists("g:netrw_ftp") && g:netrw_ftp == 1
+     put =g:netrw_uid
+"     call Decho("filter input: ".getline("."))
+     put ='\"'.g:netrw_passwd.'\"'
+"     call Decho("filter input: ".getline("."))
+    else
+     put ='user \"'.g:netrw_uid.'\" \"'.g:netrw_passwd.'\"'
+"     call Decho("filter input: ".getline("."))
+    endif
+
+    if exists("g:netrw_ftpmode") && g:netrw_ftpmode != ""
+     put =g:netrw_ftpmode
+"     call Decho("filter input: ".getline("."))
+    endif
+    if exists("g:netrw_ftpextracmd")
+     exe "put ='".g:netrw_ftpextracmd."'"
+"     call Decho("filter input: ".getline("."))
+    endif
+    put ='get \"'.netrw_fname.'\" '.tmpfile
+"    call Decho("filter input: ".getline("."))
+
+    " perform ftp:
+    " -i       : turns off interactive prompting from ftp
+    " -n  unix : DON'T use <.netrc>, even though it exists
+    " -n  win32: quit being obnoxious about password
+    norm! 1Gdd
+"    call Decho("executing: %!".g:netrw_ftp_cmd." -i -n")
+    exe g:netrw_silentxfer."%!".g:netrw_ftp_cmd." -i -n"
+    " If the result of the ftp operation isn't blank, show an error message (tnx to Doug Claar)
+    if getline(1) !~ "^$"
+"     call Decho("error<".getline(1).">")
+     if !exists("g:netrw_quiet")
+      call netrw#ErrorMsg(s:ERROR,getline(1),5)
+     endif
+    endif
+    bd!
+    let result           = s:NetGetFile(readcmd, tmpfile, b:netrw_method)
+    let b:netrw_lastfile = choice
+
+   ".........................................
+   " scp: NetRead Method #4 {{{3
+   elseif     b:netrw_method  == 4	" read with scp
+"    call Decho("read via scp (method #4)")
+    if exists("g:netrw_port") && g:netrw_port != ""
+     let useport= " ".g:netrw_scpport." ".g:netrw_port
+    else
+     let useport= ""
+    endif
+"    call  Decho("executing: !".g:netrw_scp_cmd.useport." '".g:netrw_machine.":".escape(b:netrw_fname,g:netrw_fname_escape)."' ".tmpfile)
+    exe g:netrw_silentxfer."!".g:netrw_scp_cmd.useport." ".g:netrw_shq.g:netrw_machine.":".escape(b:netrw_fname,g:netrw_fname_escape).g:netrw_shq." ".tmpfile
+    let result           = s:NetGetFile(readcmd, tmpfile, b:netrw_method)
+    let b:netrw_lastfile = choice
+
+   ".........................................
+   " http: NetRead Method #5 (wget) {{{3
+   elseif     b:netrw_method  == 5
+"    call Decho("read via http (method #5)")
+    if g:netrw_http_cmd == ""
+     if !exists("g:netrw_quiet")
+      call netrw#ErrorMsg(s:ERROR,"neither the wget nor the fetch command is available",6)
+     endif
+"     call Dret("netrw#NetRead :4 getcwd<".getcwd().">")
+     return
+    endif
+
+    if match(b:netrw_fname,"#") == -1
+     " simple wget
+     let netrw_fname= escape(b:netrw_fname,g:netrw_fname_escape)
+"     call Decho("executing: !".g:netrw_http_cmd." ".tmpfile." http://".g:netrw_machine.netrw_fname)
+     exe g:netrw_silentxfer."!".g:netrw_http_cmd." ".tmpfile." http://".g:netrw_machine.netrw_fname
+     let result = s:NetGetFile(readcmd, tmpfile, b:netrw_method)
+
+    else
+     " wget plus a jump to an in-page marker (ie. http://abc/def.html#aMarker)
+     let netrw_html= substitute(netrw_fname,"#.*$","","")
+     let netrw_tag = substitute(netrw_fname,"^.*#","","")
+"     call Decho("netrw_html<".netrw_html.">")
+"     call Decho("netrw_tag <".netrw_tag.">")
+"     call Decho("executing: !".g:netrw_http_cmd." ".tmpfile." http://".g:netrw_machine.netrw_html)
+     exe g:netrw_silentxfer."!".g:netrw_http_cmd." ".tmpfile." http://".g:netrw_machine.netrw_html
+     let result = s:NetGetFile(readcmd, tmpfile, b:netrw_method)
+"     call Decho('<\s*a\s*name=\s*"'.netrw_tag.'"/')
+     exe 'norm! 1G/<\s*a\s*name=\s*"'.netrw_tag.'"/'."\<CR>"
+    endif
+    let b:netrw_lastfile = choice
+    setlocal ro
+
+   ".........................................
+   " cadaver: NetRead Method #6 {{{3
+   elseif     b:netrw_method  == 6
+"    call Decho("read via cadaver (method #6)")
+
+    " Construct execution string (four lines) which will be passed through filter
+    let netrw_fname= escape(b:netrw_fname,g:netrw_fname_escape)
+    new
+    setlocal ff=unix
+    if exists("g:netrw_port") && g:netrw_port != ""
+     put ='open '.g:netrw_machine.' '.g:netrw_port
+    else
+     put ='open '.g:netrw_machine
+    endif
+    put ='user '.g:netrw_uid.' '.g:netrw_passwd
+    put ='get '.netrw_fname.' '.tmpfile
+    put ='quit'
+
+    " perform cadaver operation:
+    norm! 1Gdd
+"    call Decho("executing: %!".g:netrw_dav_cmd)
+    exe g:netrw_silentxfer."%!".g:netrw_dav_cmd
+    bd!
+    let result           = s:NetGetFile(readcmd, tmpfile, b:netrw_method)
+    let b:netrw_lastfile = choice
+
+   ".........................................
+   " rsync: NetRead Method #7 {{{3
+   elseif     b:netrw_method  == 7
+"    call Decho("read via rsync (method #7)")
+    let netrw_fname= escape(b:netrw_fname,g:netrw_fname_escape)
+"    call Decho("executing: !".g:netrw_rsync_cmd." ".g:netrw_machine.":".netrw_fname." ".tmpfile)
+    exe g:netrw_silentxfer."!".g:netrw_rsync_cmd." ".g:netrw_machine.":".netrw_fname." ".tmpfile
+    let result		= s:NetGetFile(readcmd,tmpfile, b:netrw_method)
+    let b:netrw_lastfile = choice
+
+   ".........................................
+   " fetch: NetRead Method #8 {{{3
+   "    fetch://[user@]host[:http]/path
+   elseif     b:netrw_method  == 8
+"    call Decho("read via fetch (method #8)")
+    let netrw_fname= escape(b:netrw_fname,g:netrw_fname_escape)
+    if g:netrw_fetch_cmd == ""
+     if !exists("g:netrw_quiet")
+      call netrw#ErrorMsg(s:ERROR,"fetch command not available",7)
+     endif
+"     call Dret("NetRead")
+    endif
+    if exists("g:netrw_option") && g:netrw_option == ":http"
+     let netrw_option= "http"
+    else
+     let netrw_option= "ftp"
+    endif
+"    call Decho("read via fetch for ".netrw_option)
+
+    if exists("g:netrw_uid") && g:netrw_uid != "" && exists("g:netrw_passwd") && g:netrw_passwd != ""
+"     call Decho("executing: !".g:netrw_fetch_cmd." ".tmpfile." ".netrw_option."://".g:netrw_uid.':'.g:netrw_passwd.'@'.g:netrw_machine."/".netrw_fname)
+     exe g:netrw_silentxfer."!".g:netrw_fetch_cmd." ".tmpfile." ".netrw_option."://".g:netrw_uid.':'.g:netrw_passwd.'@'.g:netrw_machine."/".netrw_fname
+    else
+"     call Decho("executing: !".g:netrw_fetch_cmd." ".tmpfile." ".netrw_option."://".g:netrw_machine."/".netrw_fname)
+     exe g:netrw_silentxfer."!".g:netrw_fetch_cmd." ".tmpfile." ".netrw_option."://".g:netrw_machine."/".netrw_fname
+    endif
+
+    let result		= s:NetGetFile(readcmd,tmpfile, b:netrw_method)
+    let b:netrw_lastfile = choice
+    setlocal ro
+
+   ".........................................
+   " sftp: NetRead Method #9 {{{3
+   elseif     b:netrw_method  == 9
+"    call Decho("read via sftp (method #9)")
+    let netrw_fname= escape(b:netrw_fname,g:netrw_fname_escape)
+"    call Decho("executing: !".g:netrw_sftp_cmd." ".g:netrw_machine.":".netrw_fname." ".tmpfile)
+    exe g:netrw_silentxfer."!".g:netrw_sftp_cmd." ".g:netrw_machine.":".netrw_fname." ".tmpfile
+    let result		= s:NetGetFile(readcmd, tmpfile, b:netrw_method)
+    let b:netrw_lastfile = choice
+
+   ".........................................
+   " Complain {{{3
+   else
+    call netrw#ErrorMsg(s:WARNING,"unable to comply with your request<" . choice . ">",8)
+   endif
+  endwhile
+
+  " cleanup {{{3
+  if exists("b:netrw_method")
+"   call Decho("cleanup b:netrw_method and b:netrw_fname")
+   unlet b:netrw_method
+   unlet b:netrw_fname
+  endif
+  if s:FileReadable(tmpfile) && tmpfile !~ '.tar.bz2$' && tmpfile !~ '.tar.gz$' && tmpfile !~ '.zip' && tmpfile !~ '.tar' && readcmd != 't'
+"   call Decho("cleanup by deleting tmpfile<".tmpfile.">")
+   call s:System("delete",tmpfile)
+  endif
+  call s:NetOptionRestore()
+
+"  call Dret("netrw#NetRead :5 getcwd<".getcwd().">")
+endfun
+
+" ------------------------------------------------------------------------
+" NetWrite: responsible for writing a file over the net {{{2
+fun! netrw#NetWrite(...) range
+"  call Dfunc("netrw#NetWrite(a:0=".a:0.") ".g:loaded_netrw)
+
+  " option handling
+  let mod= 0
+  call s:NetOptionSave()
+
+  " Get Temporary Filename {{{3
+  let tmpfile= s:GetTempfile("")
+  if tmpfile == ""
+"   call Dret("netrw#NetWrite : unable to get a tempfile!")
+   return
+  endif
+
+  if a:0 == 0
+   let ichoice = 0
+  else
+   let ichoice = 1
+  endif
+
+  let curbufname= expand("%")
+"  call Decho("curbufname<".curbufname.">")
+  if &binary
+   " For binary writes, always write entire file.
+   " (line numbers don't really make sense for that).
+   " Also supports the writing of tar and zip files.
+"   call Decho("(write entire file) silent exe w! ".v:cmdarg." ".tmpfile)
+   silent exe "w! ".v:cmdarg." ".tmpfile
+  elseif g:netrw_cygwin
+   " write (selected portion of) file to temporary
+   let cygtmpfile= substitute(tmpfile,'/cygdrive/\(.\)','\1:','')
+"   call Decho("(write selected portion) silent exe ".a:firstline."," . a:lastline . "w! ".v:cmdarg." ".cygtmpfile)
+   silent exe a:firstline."," . a:lastline . "w! ".v:cmdarg." ".cygtmpfile
+  else
+   " write (selected portion of) file to temporary
+"   call Decho("(write selected portion) silent exe ".a:firstline."," . a:lastline . "w! ".v:cmdarg." ".tmpfile)
+   silent exe a:firstline."," . a:lastline . "w! ".v:cmdarg." ".tmpfile
+  endif
+
+  if curbufname == ""
+   " if the file is [No Name], and one attempts to Nwrite it, the buffer takes
+   " on the temporary file's name.  Deletion of the temporary file during
+   " cleanup then causes an error message.
+   0file!
+  endif
+
+  " While choice loop: {{{3
+  while ichoice <= a:0
+
+   " Process arguments: {{{4
+   " attempt to repeat with previous host-file-etc
+   if exists("b:netrw_lastfile") && a:0 == 0
+"    call Decho("using b:netrw_lastfile<" . b:netrw_lastfile . ">")
+    let choice = b:netrw_lastfile
+    let ichoice= ichoice + 1
+   else
+    exe "let choice= a:" . ichoice
+
+    " Reconstruct Choice if choice starts with '"'
+    if match(choice,"?") == 0
+     echomsg 'NetWrite Usage:"'
+     echomsg ':Nwrite machine:path                        uses rcp'
+     echomsg ':Nwrite "machine path"                      uses ftp with <.netrc>'
+     echomsg ':Nwrite "machine id password path"          uses ftp'
+     echomsg ':Nwrite dav://[user@]machine/path           uses cadaver'
+     echomsg ':Nwrite fetch://[user@]machine/path         uses fetch'
+     echomsg ':Nwrite ftp://machine[#port]/path           uses ftp  (autodetects <.netrc>)'
+     echomsg ':Nwrite rcp://machine/path                  uses rcp'
+     echomsg ':Nwrite rsync://[user@]machine/path         uses rsync'
+     echomsg ':Nwrite scp://[user@]machine[[:#]port]/path uses scp'
+     echomsg ':Nwrite sftp://[user@]machine/path          uses sftp'
+     sleep 4
+     break
+
+    elseif match(choice,"^\"") != -1
+     if match(choice,"\"$") != -1
+       " case "..."
+      let choice=strpart(choice,1,strlen(choice)-2)
+     else
+      "  case "... ... ..."
+      let choice      = strpart(choice,1,strlen(choice)-1)
+      let wholechoice = ""
+
+      while match(choice,"\"$") == -1
+       let wholechoice= wholechoice . " " . choice
+       let ichoice    = ichoice + 1
+       if choice > a:0
+       	if !exists("g:netrw_quiet")
+	 call netrw#ErrorMsg(s:ERROR,"Unbalanced string in filename '". wholechoice ."'",13)
+	endif
+"        call Dret("netrw#NetWrite")
+        return
+       endif
+       let choice= a:{ichoice}
+      endwhile
+      let choice= strpart(wholechoice,1,strlen(wholechoice)-1) . " " . strpart(choice,0,strlen(choice)-1)
+     endif
+    endif
+   endif
+   let ichoice= ichoice + 1
+"   call Decho("choice<" . choice . "> ichoice=".ichoice)
+
+   " Determine method of write (ftp, rcp, etc) {{{4
+   call s:NetMethod(choice)
+
+   " =============
+   " Perform Protocol-Based Write {{{4
+   " ============================
+   if exists("g:netrw_silent") && g:netrw_silent == 0 && &ch >= 1
+    echo "(netrw) Processing your write request..."
+   endif
+
+   ".........................................
+   " rcp: NetWrite Method #1 {{{4
+   if  b:netrw_method == 1
+"    call Decho("write via rcp (method #1)")
+    if s:netrw_has_nt_rcp == 1
+     if exists("g:netrw_uid") &&  ( g:netrw_uid != "" )
+      let uid_machine = g:netrw_machine .'.'. g:netrw_uid
+     else
+      let uid_machine = g:netrw_machine .'.'. $USERNAME
+     endif
+    else
+     if exists("g:netrw_uid") &&  ( g:netrw_uid != "" )
+      let uid_machine = g:netrw_uid .'@'. g:netrw_machine
+     else
+      let uid_machine = g:netrw_machine
+     endif
+    endif
+    let netrw_fname= escape(b:netrw_fname,g:netrw_fname_escape)
+"    call Decho("executing: !".g:netrw_rcp_cmd." ".s:netrw_rcpmode." ".g:netrw_shq.tmpfile.g:netrw_shq." ".uid_machine.":".netrw_fname)
+    exe g:netrw_silentxfer."!".g:netrw_rcp_cmd." ".s:netrw_rcpmode." ".g:netrw_shq.tmpfile.g:netrw_shq." ".uid_machine.":".netrw_fname
+    let b:netrw_lastfile = choice
+
+   ".........................................
+   " ftp + <.netrc>: NetWrite Method #2 {{{4
+   elseif b:netrw_method == 2
+"    call Decho("write via ftp+.netrc (method #2)")
+    let netrw_fname= b:netrw_fname
+    new
+    setlocal ff=unix
+    exe "put ='".g:netrw_ftpmode."'"
+"    call Decho(" filter input: ".getline("."))
+    if exists("g:netrw_ftpextracmd")
+     exe "put ='".g:netrw_ftpextracmd."'"
+"     call Decho("filter input: ".getline("."))
+    endif
+    exe "put ='".'put \"'.tmpfile.'\" \"'.netrw_fname.'\"'."'"
+"    call Decho(" filter input: ".getline("."))
+    if exists("g:netrw_port") && g:netrw_port != ""
+"     call Decho("executing: %!".g:netrw_ftp_cmd." -i ".g:netrw_machine." ".g:netrw_port)
+     exe g:netrw_silentxfer."%!".g:netrw_ftp_cmd." -i ".g:netrw_machine." ".g:netrw_port
+    else
+"     call Decho("executing: %!".g:netrw_ftp_cmd." -i ".g:netrw_machine)
+     exe g:netrw_silentxfer."%!".g:netrw_ftp_cmd." -i ".g:netrw_machine
+    endif
+    " If the result of the ftp operation isn't blank, show an error message (tnx to Doug Claar)
+    if getline(1) !~ "^$"
+     if !exists("g:netrw_quiet")
+      call netrw#ErrorMsg(s:ERROR,getline(1),14)
+     endif
+     let mod=1
+    endif
+    bd!
+    let b:netrw_lastfile = choice
+
+   ".........................................
+   " ftp + machine, id, passwd, filename: NetWrite Method #3 {{{4
+   elseif b:netrw_method == 3
+    " Construct execution string (four lines) which will be passed through filter
+"    call Decho("read via ftp+mipf (method #3)")
+    let netrw_fname= b:netrw_fname
+    new
+    setlocal ff=unix
+    if exists("g:netrw_port") && g:netrw_port != ""
+     put ='open '.g:netrw_machine.' '.g:netrw_port
+"     call Decho("filter input: ".getline("."))
+    else
+     put ='open '.g:netrw_machine
+"     call Decho("filter input: ".getline("."))
+    endif
+    if exists("g:netrw_ftp") && g:netrw_ftp == 1
+     put =g:netrw_uid
+"     call Decho("filter input: ".getline("."))
+     put ='\"'.g:netrw_passwd.'\"'
+"     call Decho("filter input: ".getline("."))
+    else
+     put ='user \"'.g:netrw_uid.'\" \"'.g:netrw_passwd.'\"'
+"     call Decho("filter input: ".getline("."))
+    endif
+    put ='put \"'.tmpfile.'\" \"'.netrw_fname.'\"'
+"    call Decho("filter input: ".getline("."))
+    " save choice/id/password for future use
+    let b:netrw_lastfile = choice
+
+    " perform ftp:
+    " -i       : turns off interactive prompting from ftp
+    " -n  unix : DON'T use <.netrc>, even though it exists
+    " -n  win32: quit being obnoxious about password
+    norm! 1Gdd
+"    call Decho("executing: %!".g:netrw_ftp_cmd." -i -n")
+    exe g:netrw_silentxfer."%!".g:netrw_ftp_cmd." -i -n"
+    " If the result of the ftp operation isn't blank, show an error message (tnx to Doug Claar)
+    if getline(1) !~ "^$"
+     if  !exists("g:netrw_quiet")
+      call netrw#ErrorMsg(s:ERROR,getline(1),15)
+     endif
+     let mod=1
+    endif
+    bd!
+
+   ".........................................
+   " scp: NetWrite Method #4 {{{4
+   elseif     b:netrw_method == 4
+"    call Decho("write via scp (method #4)")
+    let netrw_fname= escape(b:netrw_fname,g:netrw_fname_escape)
+    if exists("g:netrw_port") && g:netrw_port != ""
+     let useport= " ".g:netrw_scpport." ".g:netrw_port
+    else
+     let useport= ""
+    endif
+"    call Decho("exe ".g:netrw_silentxfer."!".g:netrw_scp_cmd.useport." ".g:netrw_shq.tmpfile.g:netrw_shq." ".g:netrw_shq.g:netrw_machine.":".netrw_fname.g:netrw_shq)
+    exe g:netrw_silentxfer."!".g:netrw_scp_cmd.useport." ".g:netrw_shq.tmpfile.g:netrw_shq." ".g:netrw_shq.g:netrw_machine.":".netrw_fname.g:netrw_shq
+    let b:netrw_lastfile = choice
+
+   ".........................................
+   " http: NetWrite Method #5 {{{4
+   elseif     b:netrw_method == 5
+"    call Decho("write via http (method #5)")
+    if !exists("g:netrw_quiet")
+     call netrw#ErrorMsg(s:ERROR,"currently <netrw.vim> does not support writing using http:",16)
+    endif
+
+   ".........................................
+   " dav: NetWrite Method #6 (cadaver) {{{4
+   elseif     b:netrw_method == 6
+"    call Decho("write via cadaver (method #6)")
+
+    " Construct execution string (four lines) which will be passed through filter
+    let netrw_fname= escape(b:netrw_fname,g:netrw_fname_escape)
+    new
+    setlocal ff=unix
+    if exists("g:netrw_port") && g:netrw_port != ""
+     put ='open '.g:netrw_machine.' '.g:netrw_port
+    else
+     put ='open '.g:netrw_machine
+    endif
+    put ='user '.g:netrw_uid.' '.g:netrw_passwd
+    put ='put '.tmpfile.' '.netrw_fname
+
+    " perform cadaver operation:
+    norm! 1Gdd
+"    call Decho("executing: %!".g:netrw_dav_cmd)
+    exe g:netrw_silentxfer."%!".g:netrw_dav_cmd
+    bd!
+    let b:netrw_lastfile = choice
+
+   ".........................................
+   " rsync: NetWrite Method #7 {{{4
+   elseif     b:netrw_method == 7
+"    call Decho("write via rsync (method #7)")
+    let netrw_fname= escape(b:netrw_fname,g:netrw_fname_escape)
+"    call Decho("executing: !".g:netrw_rsync_cmd." ".tmpfile." ".g:netrw_machine.":".netrw_fname)
+    exe g:netrw_silentxfer."!".g:netrw_rsync_cmd." ".tmpfile." ".g:netrw_machine.":".netrw_fname
+    let b:netrw_lastfile = choice
+
+   ".........................................
+   " sftp: NetWrite Method #9 {{{4
+   elseif     b:netrw_method == 9
+"    call Decho("read via sftp (method #9)")
+    let netrw_fname= escape(b:netrw_fname,g:netrw_fname_escape)
+    if exists("g:netrw_uid") &&  ( g:netrw_uid != "" )
+     let uid_machine = g:netrw_uid .'@'. g:netrw_machine
+    else
+     let uid_machine = g:netrw_machine
+    endif
+    new
+    setlocal ff=unix
+    put ='put \"'.escape(tmpfile,'\').'\" '.netrw_fname
+"    call Decho("filter input: ".getline("."))
+    norm! 1Gdd
+"    call Decho("executing: %!".g:netrw_sftp_cmd.' '.uid_machine)
+    exe g:netrw_silentxfer."%!".g:netrw_sftp_cmd.' '.uid_machine
+    bd!
+    let b:netrw_lastfile= choice
+
+   ".........................................
+   " Complain {{{4
+   else
+    call netrw#ErrorMsg(s:WARNING,"unable to comply with your request<" . choice . ">",17)
+   endif
+  endwhile
+
+  " Cleanup: {{{3
+"  call Decho("cleanup")
+  if s:FileReadable(tmpfile)
+"   call Decho("tmpfile<".tmpfile."> readable, will now delete it")
+   call s:System("delete",tmpfile)
+  endif
+  call s:NetOptionRestore()
+
+  if a:firstline == 1 && a:lastline == line("$")
+   " restore modifiability; usually equivalent to set nomod
+   let &mod= mod
+  endif
+
+"  call Dret("netrw#NetWrite")
+endfun
+
+" ---------------------------------------------------------------------
+" NetSource: source a remotely hosted vim script {{{2
+" uses NetRead to get a copy of the file into a temporarily file,
+"              then sources that file,
+"              then removes that file.
+fun! netrw#NetSource(...)
+"  call Dfunc("netrw#NetSource() a:0=".a:0)
+  if a:0 > 0 && a:1 == '?'
+   " give help
+   echomsg 'NetSource Usage:'
+   echomsg ':Nsource dav://machine[:port]/path            uses cadaver'
+   echomsg ':Nsource fetch://machine/path                 uses fetch'
+   echomsg ':Nsource ftp://[user@]machine[:port]/path     uses ftp   autodetects <.netrc>'
+   echomsg ':Nsource http://[user@]machine/path           uses http  wget'
+   echomsg ':Nsource rcp://[user@]machine/path            uses rcp'
+   echomsg ':Nsource rsync://machine[:port]/path          uses rsync'
+   echomsg ':Nsource scp://[user@]machine[[:#]port]/path  uses scp'
+   echomsg ':Nsource sftp://[user@]machine[[:#]port]/path uses sftp'
+   sleep 4
+  else
+   let i= 1
+   while i <= a:0
+    call netrw#NetRead(3,a:{i})
+"    call Decho("s:netread_tmpfile<".s:netrw_tmpfile.">")
+    if s:FileReadable(s:netrw_tmpfile)
+"     call Decho("exe so ".s:netrw_tmpfile)
+     exe "so ".s:netrw_tmpfile
+     call delete(s:netrw_tmpfile)
+     unlet s:netrw_tmpfile
+    else
+     call netrw#ErrorMsg(s:ERROR,"unable to source <".a:{i}.">!",48)
+    endif
+    let i= i + 1
+   endwhile
+  endif
+"  call Dret("netrw#NetSource")
+endfun
+
+" ===========================================
+" NetGetFile: Function to read temporary file "tfile" with command "readcmd". {{{2
+"    readcmd == %r : replace buffer with newly read file
+"            == 0r : read file at top of buffer
+"            == r  : read file after current line
+"            == t  : leave file in temporary form (ie. don't read into buffer)
+fun! s:NetGetFile(readcmd, tfile, method)
+"  call Dfunc("NetGetFile(readcmd<".a:readcmd.">,tfile<".a:tfile."> method<".a:method.">)")
+
+  " readcmd=='t': simply do nothing
+  if a:readcmd == 't'
+"   call Dret("NetGetFile : skip read of <".a:tfile.">")
+   return
+  endif
+
+  " get name of remote filename (ie. url and all)
+  let rfile= bufname("%")
+"  call Decho("rfile<".rfile.">")
+
+  if exists("*NetReadFixup")
+   " for the use of NetReadFixup (not otherwise used internally)
+   let line2= line("$")
+  endif
+
+  if a:readcmd[0] == '%'
+  " get file into buffer
+"   call Decho("get file into buffer")
+
+   " rename the current buffer to the temp file (ie. tfile)
+   if g:netrw_cygwin
+    let tfile= substitute(a:tfile,'/cygdrive/\(.\)','\1:','')
+   else
+    let tfile= a:tfile
+   endif
+"   call Decho("keepalt exe file ".tfile)
+   keepalt exe "silent! keepalt file ".tfile
+
+   " edit temporary file (ie. read the temporary file in)
+   if     rfile =~ '\.zip$'
+"    call Decho("handling remote zip file with zip#Browse(tfile<".tfile.">)")
+    call zip#Browse(tfile)
+   elseif rfile =~ '\.tar$'
+"    call Decho("handling remote tar file with tar#Browse(tfile<".tfile.">)")
+    call tar#Browse(tfile)
+   elseif rfile =~ '\.tar\.gz'
+"    call Decho("handling remote gzip-compressed tar file")
+    call tar#Browse(tfile)
+   elseif rfile =~ '\.tar\.bz2'
+"    call Decho("handling remote bz2-compressed tar file")
+    call tar#Browse(tfile)
+   else
+"    call Decho("edit temporary file")
+    e!
+   endif
+
+   " rename buffer back to remote filename
+   exe "silent! keepalt file ".escape(rfile,' ')
+   filetype detect
+"   call Dredir("renamed buffer back to remote filename<".rfile."> : expand(%)<".expand("%").">","ls!")
+   let line1 = 1
+   let line2 = line("$")
+
+  elseif s:FileReadable(a:tfile)
+   " read file after current line
+"   call Decho("read file<".a:tfile."> after current line")
+   let curline = line(".")
+   let lastline= line("$")
+"   call Decho("exe<".a:readcmd." ".v:cmdarg." ".a:tfile.">  line#".curline)
+   exe a:readcmd." ".v:cmdarg." ".a:tfile
+   let line1= curline + 1
+   let line2= line("$") - lastline + 1
+
+  else
+   " not readable
+"   call Decho("tfile<".a:tfile."> not readable")
+   call netrw#ErrorMsg(s:WARNING,"file <".a:tfile."> not readable",9)
+"   call Dret("NetGetFile : tfile<".a:tfile."> not readable")
+   return
+  endif
+
+  " User-provided (ie. optional) fix-it-up command
+  if exists("*NetReadFixup")
+"   call Decho("calling NetReadFixup(method<".a:method."> line1=".line1." line2=".line2.")")
+   call NetReadFixup(a:method, line1, line2)
+"  else " Decho
+"   call Decho("NetReadFixup() not called, doesn't exist  (line1=".line1." line2=".line2.")")
+  endif
+
+  " update the Buffers menu
+  if has("gui") && has("gui_running")
+   silent! emenu Buffers.Refresh\ menu
+  endif
+
+"  call Decho("readcmd<".a:readcmd."> cmdarg<".v:cmdarg."> tfile<".a:tfile."> readable=".s:FileReadable(a:tfile))
+
+ " make sure file is being displayed
+  redraw!
+"  call Dret("NetGetFile")
+endfun
+
+" ------------------------------------------------------------------------
+" NetMethod:  determine method of transfer {{{2
+"  method == 1: rcp
+"	     2: ftp + <.netrc>
+"	     3: ftp + machine, id, password, and [path]filename
+"	     4: scp
+"	     5: http (wget)
+"	     6: cadaver
+"	     7: rsync
+"	     8: fetch
+"	     9: sftp
+fun! s:NetMethod(choice)  " globals: method machine id passwd fname
+"   call Dfunc("NetMethod(a:choice<".a:choice.">)")
+
+  " initialization
+  let b:netrw_method  = 0
+  let g:netrw_machine = ""
+  let b:netrw_fname   = ""
+  let g:netrw_port    = ""
+  let g:netrw_choice  = a:choice
+
+  " Patterns:
+  " mipf     : a:machine a:id password filename	     Use ftp
+  " mf	    : a:machine filename		     Use ftp + <.netrc> or g:netrw_uid g:netrw_passwd
+  " ftpurm   : ftp://[user@]host[[#:]port]/filename  Use ftp + <.netrc> or g:netrw_uid g:netrw_passwd
+  " rcpurm   : rcp://[user@]host/filename	     Use rcp
+  " rcphf    : [user@]host:filename		     Use rcp
+  " scpurm   : scp://[user@]host[[#:]port]/filename  Use scp
+  " httpurm  : http://[user@]host/filename	     Use wget
+  " davurm   : [s]dav://host[:port]/path             Use cadaver
+  " rsyncurm : rsync://host[:port]/path              Use rsync
+  " fetchurm : fetch://[user@]host[:http]/filename   Use fetch (defaults to ftp, override for http)
+  " sftpurm  : sftp://[user@]host/filename  Use scp
+  let mipf     = '^\(\S\+\)\s\+\(\S\+\)\s\+\(\S\+\)\s\+\(\S\+\)$'
+  let mf       = '^\(\S\+\)\s\+\(\S\+\)$'
+  let ftpurm   = '^ftp://\(\([^/@]\{-}\)@\)\=\([^/#:]\{-}\)\([#:]\d\+\)\=/\(.*\)$'
+  let rcpurm   = '^rcp://\%(\([^/@]\{-}\)@\)\=\([^/]\{-}\)/\(.*\)$'
+  let rcphf    = '^\(\(\h\w*\)@\)\=\(\h\w*\):\([^@]\+\)$'
+  let scpurm   = '^scp://\([^/#:]\+\)\%([#:]\(\d\+\)\)\=/\(.*\)$'
+  let httpurm  = '^http://\([^/]\{-}\)\(/.*\)\=$'
+  let davurm   = '^s\=dav://\([^/]\+\)/\(.*/\)\([-_.~[:alnum:]]\+\)$'
+  let rsyncurm = '^rsync://\([^/]\{-}\)/\(.*\)\=$'
+  let fetchurm = '^fetch://\(\([^/@]\{-}\)@\)\=\([^/#:]\{-}\)\(:http\)\=/\(.*\)$'
+  let sftpurm  = '^sftp://\([^/]\{-}\)/\(.*\)\=$'
+
+"  call Decho("determine method:")
+  " Determine Method
+  " rcp://user@hostname/...path-to-file
+  if match(a:choice,rcpurm) == 0
+"   call Decho("rcp://...")
+   let b:netrw_method  = 1
+   let userid          = substitute(a:choice,rcpurm,'\1',"")
+   let g:netrw_machine = substitute(a:choice,rcpurm,'\2',"")
+   let b:netrw_fname   = substitute(a:choice,rcpurm,'\3',"")
+   if userid != ""
+    let g:netrw_uid= userid
+   endif
+
+  " scp://user@hostname/...path-to-file
+  elseif match(a:choice,scpurm) == 0
+"   call Decho("scp://...")
+   let b:netrw_method  = 4
+   let g:netrw_machine = substitute(a:choice,scpurm,'\1',"")
+   let g:netrw_port    = substitute(a:choice,scpurm,'\2',"")
+   let b:netrw_fname   = substitute(a:choice,scpurm,'\3',"")
+
+  " http://user@hostname/...path-to-file
+  elseif match(a:choice,httpurm) == 0
+"   call Decho("http://...")
+   let b:netrw_method = 5
+   let g:netrw_machine= substitute(a:choice,httpurm,'\1',"")
+   let b:netrw_fname  = substitute(a:choice,httpurm,'\2',"")
+
+  " dav://hostname[:port]/..path-to-file..
+  elseif match(a:choice,davurm) == 0
+"   call Decho("dav://...")
+   let b:netrw_method= 6
+   if a:choice =~ '^s'
+    let g:netrw_machine= 'https://'.substitute(a:choice,davurm,'\1/\2',"")
+   else
+    let g:netrw_machine= 'http://'.substitute(a:choice,davurm,'\1/\2',"")
+   endif
+   let b:netrw_fname  = substitute(a:choice,davurm,'\3',"")
+
+  " rsync://user@hostname/...path-to-file
+  elseif match(a:choice,rsyncurm) == 0
+"   call Decho("rsync://...")
+   let b:netrw_method = 7
+   let g:netrw_machine= substitute(a:choice,rsyncurm,'\1',"")
+   let b:netrw_fname  = substitute(a:choice,rsyncurm,'\2',"")
+
+  " ftp://[user@]hostname[[:#]port]/...path-to-file
+  elseif match(a:choice,ftpurm) == 0
+"   call Decho("ftp://...")
+   let userid	      = substitute(a:choice,ftpurm,'\2',"")
+   let g:netrw_machine= substitute(a:choice,ftpurm,'\3',"")
+   let g:netrw_port   = substitute(a:choice,ftpurm,'\4',"")
+   let b:netrw_fname  = substitute(a:choice,ftpurm,'\5',"")
+   if userid != ""
+    let g:netrw_uid= userid
+   endif
+   if exists("g:netrw_uid") && exists("g:netrw_passwd")
+    let b:netrw_method = 3
+   else
+    if s:FileReadable(expand("$HOME/.netrc")) && !g:netrw_ignorenetrc
+     let b:netrw_method= 2
+    else
+     if !exists("g:netrw_uid") || g:netrw_uid == ""
+      call NetUserPass()
+     elseif !exists("g:netrw_passwd") || g:netrw_passwd == ""
+      call NetUserPass(g:netrw_uid)
+    " else just use current g:netrw_uid and g:netrw_passwd
+     endif
+     let b:netrw_method= 3
+    endif
+   endif
+
+  elseif match(a:choice,fetchurm) == 0
+"   call Decho("fetch://...")
+   let b:netrw_method = 8
+   let g:netrw_userid = substitute(a:choice,fetchurm,'\2',"")
+   let g:netrw_machine= substitute(a:choice,fetchurm,'\3',"")
+   let b:netrw_option = substitute(a:choice,fetchurm,'\4',"")
+   let b:netrw_fname  = substitute(a:choice,fetchurm,'\5',"")
+
+  " Issue an ftp : "machine id password [path/]filename"
+  elseif match(a:choice,mipf) == 0
+"   call Decho("(ftp) host id pass file")
+   let b:netrw_method  = 3
+   let g:netrw_machine = substitute(a:choice,mipf,'\1',"")
+   let g:netrw_uid     = substitute(a:choice,mipf,'\2',"")
+   let g:netrw_passwd  = substitute(a:choice,mipf,'\3',"")
+   let b:netrw_fname   = substitute(a:choice,mipf,'\4',"")
+
+  " Issue an ftp: "hostname [path/]filename"
+  elseif match(a:choice,mf) == 0
+"   call Decho("(ftp) host file")
+   if exists("g:netrw_uid") && exists("g:netrw_passwd")
+    let b:netrw_method  = 3
+    let g:netrw_machine = substitute(a:choice,mf,'\1',"")
+    let b:netrw_fname   = substitute(a:choice,mf,'\2',"")
+
+   elseif s:FileReadable(expand("$HOME/.netrc"))
+    let b:netrw_method  = 2
+    let g:netrw_machine = substitute(a:choice,mf,'\1',"")
+    let b:netrw_fname   = substitute(a:choice,mf,'\2',"")
+   endif
+
+  " sftp://user@hostname/...path-to-file
+  elseif match(a:choice,sftpurm) == 0
+"   call Decho("sftp://...")
+   let b:netrw_method = 9
+   let g:netrw_machine= substitute(a:choice,sftpurm,'\1',"")
+   let b:netrw_fname  = substitute(a:choice,sftpurm,'\2',"")
+
+  " Issue an rcp: hostname:filename"  (this one should be last)
+  elseif match(a:choice,rcphf) == 0
+"   call Decho("(rcp) [user@]host:file) rcphf<".rcphf.">")
+   let b:netrw_method = 1
+   let userid	     = substitute(a:choice,rcphf,'\2',"")
+   let g:netrw_machine= substitute(a:choice,rcphf,'\3',"")
+   let b:netrw_fname  = substitute(a:choice,rcphf,'\4',"")
+"   call Decho('\1<'.substitute(a:choice,rcphf,'\1',"").">")
+"   call Decho('\2<'.substitute(a:choice,rcphf,'\2',"").">")
+"   call Decho('\3<'.substitute(a:choice,rcphf,'\3',"").">")
+"   call Decho('\4<'.substitute(a:choice,rcphf,'\4',"").">")
+   if userid != ""
+    let g:netrw_uid= userid
+   endif
+
+  else
+   if !exists("g:netrw_quiet")
+    call netrw#ErrorMsg(s:WARNING,"cannot determine method",45)
+   endif
+   let b:netrw_method  = -1
+  endif
+
+  " remove any leading [:#] from port number
+  if g:netrw_port != ""
+    let g:netrw_port = substitute(g:netrw_port,'[#:]\+','','')
+  endif
+
+"  call Decho("a:choice       <".a:choice.">")
+"  call Decho("b:netrw_method <".b:netrw_method.">")
+"  call Decho("g:netrw_machine<".g:netrw_machine.">")
+"  call Decho("g:netrw_port   <".g:netrw_port.">")
+"  if exists("g:netrw_uid")		"Decho
+"   call Decho("g:netrw_uid    <".g:netrw_uid.">")
+"  endif					"Decho
+"  if exists("g:netrw_passwd")		"Decho
+"   call Decho("g:netrw_passwd <".g:netrw_passwd.">")
+"  endif					"Decho
+"  call Decho("b:netrw_fname  <".b:netrw_fname.">")
+"  call Dret("NetMethod : b:netrw_method=".b:netrw_method)
+endfun
+
+" ------------------------------------------------------------------------
+" NetReadFixup: this sort of function is typically written by the user {{{2
+"               to handle extra junk that their system's ftp dumps
+"               into the transfer.  This function is provided as an
+"               example and as a fix for a Windows 95 problem: in my
+"               experience, win95's ftp always dumped four blank lines
+"               at the end of the transfer.
+if has("win95") && exists("g:netrw_win95ftp") && g:netrw_win95ftp
+ fun! NetReadFixup(method, line1, line2)
+"   call Dfunc("NetReadFixup(method<".a:method."> line1=".a:line1." line2=".a:line2.")")
+   if method == 3   " ftp (no <.netrc>)
+    let fourblanklines= line2 - 3
+    silent fourblanklines.",".line2."g/^\s*/d"
+   endif
+"   call Dret("NetReadFixup")
+ endfun
+endif
+
+" ---------------------------------------------------------------------
+" NetUserPass: set username and password for subsequent ftp transfer {{{2
+"   Usage:  :call NetUserPass()			-- will prompt for userid and password
+"	    :call NetUserPass("uid")		-- will prompt for password
+"	    :call NetUserPass("uid","password") -- sets global userid and password
+fun! NetUserPass(...)
+
+ " get/set userid
+ if a:0 == 0
+"  call Dfunc("NetUserPass(a:0<".a:0.">)")
+  if !exists("g:netrw_uid") || g:netrw_uid == ""
+   " via prompt
+   let g:netrw_uid= input('Enter username: ')
+  endif
+ else	" from command line
+"  call Dfunc("NetUserPass(a:1<".a:1.">) {")
+  let g:netrw_uid= a:1
+ endif
+
+ " get password
+ if a:0 <= 1 " via prompt
+"  call Decho("a:0=".a:0." case <=1:")
+  let g:netrw_passwd= inputsecret("Enter Password: ")
+ else " from command line
+"  call Decho("a:0=".a:0." case >1: a:2<".a:2.">")
+  let g:netrw_passwd=a:2
+ endif
+
+"  call Dret("NetUserPass")
+endfun
+
+" ===========================================
+"  Shared Browsing Support:    {{{1
+" ===========================================
+
+" ---------------------------------------------------------------------
+" s:BrowserMaps: {{{2
+fun! s:BrowserMaps(islocal)
+"  call Dfunc("s:BrowserMaps(islocal=".a:islocal.") b:netrw_curdir<".b:netrw_curdir.">")
+  if a:islocal
+   nnoremap <buffer> <silent> <cr>	:call netrw#LocalBrowseCheck(<SID>NetBrowseChgDir(1,<SID>NetGetWord()))<cr>
+   nnoremap <buffer> <silent> <leftmouse> <leftmouse>:call netrw#LocalBrowseCheck(<SID>NetBrowseChgDir(1,<SID>NetGetWord()))<cr>
+   nnoremap <buffer> <silent> <c-l>	:call <SID>NetRefresh(1,<SID>NetBrowseChgDir(1,'./'))<cr>
+   nnoremap <buffer> <silent> -		:exe "norm! 0"<bar>call netrw#LocalBrowseCheck(<SID>NetBrowseChgDir(1,'../'))<cr>
+   nnoremap <buffer> <silent> a		:call <SID>NetHide(1)<cr>
+   nnoremap <buffer> <silent> mb	:<c-u>call <SID>NetBookmarkDir(0,b:netrw_curdir)<cr>
+   nnoremap <buffer> <silent> gb	:<c-u>call <SID>NetBookmarkDir(1,b:netrw_curdir)<cr>
+   nnoremap <buffer> <silent> c		:exe "cd ".b:netrw_curdir<cr>
+   nnoremap <buffer> <silent> C		:let g:netrw_chgwin= winnr()<cr>
+   nnoremap <buffer> <silent> d		:call <SID>NetMakeDir("")<cr>
+   nnoremap <buffer> <silent> <c-h>	:call <SID>NetHideEdit(1)<cr>
+   nnoremap <buffer> <silent> i		:call <SID>NetListStyle(1)<cr>
+   nnoremap <buffer> <silent> o		:call <SID>NetSplit(3)<cr>
+   nnoremap <buffer> <silent> O		:call <SID>LocalObtain()<cr>
+   nnoremap <buffer> <silent> p		:call <SID>NetPreview(<SID>NetBrowseChgDir(1,<SID>NetGetWord(),1))<cr>
+   nnoremap <buffer> <silent> P		:call <SID>NetPrevWinOpen(1)<cr>
+   nnoremap <buffer> <silent> q		:<c-u>call <SID>NetBookmarkDir(2,b:netrw_curdir)<cr>
+   nnoremap <buffer> <silent> r		:let g:netrw_sort_direction= (g:netrw_sort_direction =~ 'n')? 'r' : 'n'<bar>exe "norm! 0"<bar>call <SID>NetRefresh(1,<SID>NetBrowseChgDir(1,'./'))<cr>
+   nnoremap <buffer> <silent> s		:call <SID>NetSortStyle(1)<cr>
+   nnoremap <buffer> <silent> S		:call <SID>NetSortSequence(1)<cr>
+   nnoremap <buffer> <silent> t		:call <SID>NetSplit(4)<cr>
+   nnoremap <buffer> <silent> u		:<c-u>call <SID>NetBookmarkDir(4,expand("%"))<cr>
+   nnoremap <buffer> <silent> U		:<c-u>call <SID>NetBookmarkDir(5,expand("%"))<cr>
+   nnoremap <buffer> <silent> v		:call <SID>NetSplit(5)<cr>
+   nnoremap <buffer> <silent> x		:call netrw#NetBrowseX(<SID>NetBrowseChgDir(1,<SID>NetGetWord(),0),0)"<cr>
+   if s:didstarstar || !mapcheck("<s-down>","n")
+    nnoremap <buffer> <silent> <s-down>	:Nexplore<cr>
+   endif
+   if s:didstarstar || !mapcheck("<s-up>","n")
+    nnoremap <buffer> <silent> <s-up>	:Pexplore<cr>
+   endif
+   exe 'nnoremap <buffer> <silent> <del>	:call <SID>LocalBrowseRm("'.b:netrw_curdir.'")<cr>'
+   exe 'vnoremap <buffer> <silent> <del>	:call <SID>LocalBrowseRm("'.b:netrw_curdir.'")<cr>'
+   exe 'nnoremap <buffer> <silent> <rightmouse> <leftmouse>:call <SID>LocalBrowseRm("'.b:netrw_curdir.'")<cr>'
+   exe 'vnoremap <buffer> <silent> <rightmouse> <leftmouse>:call <SID>LocalBrowseRm("'.b:netrw_curdir.'")<cr>'
+   exe 'nnoremap <buffer> <silent> D		:call <SID>LocalBrowseRm("'.b:netrw_curdir.'")<cr>'
+   exe 'vnoremap <buffer> <silent> D		:call <SID>LocalBrowseRm("'.b:netrw_curdir.'")<cr>'
+   exe 'nnoremap <buffer> <silent> R		:call <SID>LocalBrowseRename("'.b:netrw_curdir.'")<cr>'
+   exe 'vnoremap <buffer> <silent> R		:call <SID>LocalBrowseRename("'.b:netrw_curdir.'")<cr>'
+   exe 'nnoremap <buffer> <silent> <Leader>m	:call <SID>NetMakeDir("")<cr>'
+   nnoremap <buffer> <F1>		:he netrw-dir<cr>
+
+  else " remote
+   call s:RemotePathAnalysis(b:netrw_curdir)
+   nnoremap <buffer> <silent> <cr>	:call <SID>NetBrowse(0,<SID>NetBrowseChgDir(0,<SID>NetGetWord()))<cr>
+   nnoremap <buffer> <silent> <leftmouse> <leftmouse>:call <SID>NetBrowse(0,<SID>NetBrowseChgDir(0,<SID>NetGetWord()))<cr>
+   nnoremap <buffer> <silent> <c-l>	:call <SID>NetRefresh(0,<SID>NetBrowseChgDir(0,'./'))<cr>
+   nnoremap <buffer> <silent> -		:exe "norm! 0"<bar>call <SID>NetBrowse(0,<SID>NetBrowseChgDir(0,'../'))<cr>
+   nnoremap <buffer> <silent> a		:call <SID>NetHide(0)<cr>
+   nnoremap <buffer> <silent> mb	:<c-u>call <SID>NetBookmarkDir(0,b:netrw_curdir)<cr>
+   nnoremap <buffer> <silent> gb	:<c-u>call <SID>NetBookmarkDir(1,b:netrw_cur)<cr>
+   nnoremap <buffer> <silent> C		:let g:netrw_chgwin= winnr()<cr>
+   nnoremap <buffer> <silent> <c-h>	:call <SID>NetHideEdit(0)<cr>
+   nnoremap <buffer> <silent> i		:call <SID>NetListStyle(0)<cr>
+   nnoremap <buffer> <silent> o		:call <SID>NetSplit(0)<cr>
+   nnoremap <buffer> <silent> O		:call netrw#NetObtain(0)<cr>
+   vnoremap <buffer> <silent> O		:call netrw#NetObtain(1)<cr>
+   nnoremap <buffer> <silent> p		:call <SID>NetPreview(<SID>NetBrowseChgDir(1,<SID>NetGetWord(),1))<cr>
+   nnoremap <buffer> <silent> P		:call <SID>NetPrevWinOpen(0)<cr>
+   nnoremap <buffer> <silent> q		:<c-u>call <SID>NetBookmarkDir(2,b:netrw_curdir)<cr>
+   nnoremap <buffer> <silent> r		:let g:netrw_sort_direction= (g:netrw_sort_direction =~ 'n')? 'r' : 'n'<bar>exe "norm! 0"<bar>call <SID>NetBrowse(0,<SID>NetBrowseChgDir(0,'./'))<cr>
+   nnoremap <buffer> <silent> s		:call <SID>NetSortStyle(0)<cr>
+   nnoremap <buffer> <silent> S		:call <SID>NetSortSequence(0)<cr>
+   nnoremap <buffer> <silent> t		:call <SID>NetSplit(1)<cr>
+   nnoremap <buffer> <silent> u		:<c-u>call <SID>NetBookmarkDir(4,b:netrw_curdir)<cr>
+   nnoremap <buffer> <silent> U		:<c-u>call <SID>NetBookmarkDir(5,b:netrw_curdir)<cr>
+   nnoremap <buffer> <silent> v		:call <SID>NetSplit(2)<cr>
+   nnoremap <buffer> <silent> x		:call netrw#NetBrowseX(<SID>NetBrowseChgDir(0,<SID>NetGetWord()),1)<cr>
+   exe 'nnoremap <buffer> <silent> <del>	:call <SID>NetBrowseRm("'.s:user.s:machine.'","'.s:path.'")<cr>'
+   exe 'vnoremap <buffer> <silent> <del>	:call <SID>NetBrowseRm("'.s:user.s:machine.'","'.s:path.'")<cr>'
+   exe 'nnoremap <buffer> <silent> <rightmouse> <leftmouse>:call <SID>NetBrowseRm("'.s:user.s:machine.'","'.s:path.'")<cr>'
+   exe 'vnoremap <buffer> <silent> <rightmouse> <leftmouse>:call <SID>NetBrowseRm("'.s:user.s:machine.'","'.s:path.'")<cr>'
+   exe 'nnoremap <buffer> <silent> d	:call <SID>NetMakeDir("'.s:user.s:machine.'")<cr>'
+   exe 'nnoremap <buffer> <silent> D	:call <SID>NetBrowseRm("'.s:user.s:machine.'","'.s:path.'")<cr>'
+   exe 'vnoremap <buffer> <silent> D	:call <SID>NetBrowseRm("'.s:user.s:machine.'","'.s:path.'")<cr>'
+   exe 'nnoremap <buffer> <silent> R	:call <SID>NetBrowseRename("'.s:user.s:machine.'","'.s:path.'")<cr>'
+   exe 'vnoremap <buffer> <silent> R	:call <SID>NetBrowseRename("'.s:user.s:machine.'","'.s:path.'")<cr>'
+   nnoremap <buffer> <F1>			:he netrw-browse-cmds<cr>
+  endif
+"  call Dret("s:BrowserMaps")
+endfun
+
+" ---------------------------------------------------------------------
+" s:NetBrowse: This function uses the command in g:netrw_list_cmd to get a list {{{2
+"  of the contents of a remote directory.  It is assumed that the
+"  g:netrw_list_cmd has a string, USEPORT HOSTNAME, that needs to be substituted
+"  with the requested remote hostname first.
+fun! s:NetBrowse(islocal,dirname)
+  if !exists("w:netrw_liststyle")|let w:netrw_liststyle= g:netrw_liststyle|endif
+"  call Dfunc("NetBrowse(islocal=".a:islocal." dirname<".a:dirname.">) liststyle=".w:netrw_liststyle." ".g:loaded_netrw." buf#".bufnr("%")."<".bufname("%").">")
+"  call Dredir("ls!")
+
+  if exists("s:netrw_skipbrowse")
+   unlet s:netrw_skipbrowse
+"   call Dret("NetBrowse : s:netrw_skipbrowse=".s:netrw_skipbrowse)
+   return
+  endif
+
+  call s:NetOptionSave()
+
+  if a:islocal && exists("w:netrw_acdkeep") && w:netrw_acdkeep
+"   call Decho("handle w:netrw_acdkeep:")
+"   call Decho("cd ".escape(a:dirname,s:netrw_cd_escape)." (due to 'acd')")
+   exe 'cd '.escape(a:dirname,s:netrw_cd_escape)
+"   call Decho("getcwd<".getcwd().">")
+
+  elseif !a:islocal && a:dirname !~ '[\/]$' && a:dirname !~ '^"'
+   " looks like a regular file, attempt transfer
+"   call Decho("attempt transfer as regular file<".a:dirname.">")
+
+   " remove any filetype indicator from end of dirname, except for the {{{3
+   " "this is a directory" indicator (/).
+   " There shouldn't be one of those here, anyway.
+   let path= substitute(a:dirname,'[*=@|]\r\=$','','e')
+"   call Decho("new path<".path.">")
+   call s:RemotePathAnalysis(a:dirname)
+
+   " remote-read the requested file into current buffer {{{3
+   mark '
+   call s:NetrwEnew(a:dirname)
+   let b:netrw_curdir= a:dirname
+   call s:NetrwSafeOptions()
+   setlocal ma noro
+"   call Decho("exe silent! keepalt file ".s:method."://".s:user.s:machine."/".escape(s:path,s:netrw_cd_escape)." (bt=".&bt.")")
+   exe "silent! keepalt file ".s:method."://".s:user.s:machine."/".escape(s:path,s:netrw_cd_escape)
+   exe "silent keepalt doau BufReadPre ".s:fname
+   silent call netrw#NetRead(2,s:method."://".s:user.s:machine."/".s:path)
+   exe "silent keepalt doau BufReadPost ".s:fname
+
+   " save certain window-oriented variables into buffer-oriented variables {{{3
+   call s:SetBufWinVars()
+   call s:NetOptionRestore()
+   setlocal nomod nowrap
+
+"   call Dret("NetBrowse : file<".s:fname.">")
+   return
+  endif
+
+  " use buffer-oriented WinVars if buffer ones exist but window ones don't {{{3
+  call s:UseBufWinVars()
+
+  " set up some variables {{{3
+  let b:netrw_browser_active = 1
+  let dirname                = a:dirname
+  let s:last_sort_by         = g:netrw_sort_by
+
+  call s:NetMenu(1)                      " set up menu {{{3
+  if s:NetGetBuffer(a:islocal,dirname)   " set up buffer {{{3
+"   call Dret("NetBrowse : re-using buffer")
+   return
+  endif
+
+  " set b:netrw_curdir to the new directory name {{{3
+"  call Decho("set b:netrw_curdir to the new directory name:")
+   let b:netrw_curdir= dirname
+  if b:netrw_curdir =~ '[/\\]$'
+   let b:netrw_curdir= substitute(b:netrw_curdir,'[/\\]$','','e')
+  endif
+  if b:netrw_curdir == ''
+   if has("amiga")
+    " On the Amiga, the empty string connotes the current directory
+    let b:netrw_curdir= getcwd()
+   else
+    " under unix, when the root directory is encountered, the result
+    " from the preceding substitute is an empty string.
+    let b:netrw_curdir= '/'
+   endif
+  endif
+  if !a:islocal && b:netrw_curdir !~ '/$'
+   let b:netrw_curdir= b:netrw_curdir.'/'
+  endif
+"  call Decho("b:netrw_curdir<".b:netrw_curdir.">")
+
+  " ------------
+  " (local only) {{{3
+  " ------------
+  if a:islocal
+"   call Decho("local only:")
+
+   " Set up ShellCmdPost handling.  Append current buffer to browselist
+   call s:LocalFastBrowser()
+
+  " handle g:netrw_keepdir: set vim's current directory to netrw's notion of the current directory {{{3
+   if !g:netrw_keepdir
+"    call Decho("handle keepdir: (g:netrw_keepdir=".g:netrw_keepdir.")")
+"    call Decho('exe cd '.escape(b:netrw_curdir,s:netrw_cd_escape))
+    try
+     exe 'cd '.escape(b:netrw_curdir,s:netrw_cd_escape)
+    catch /^Vim\%((\a\+)\)\=:E472/
+     call netrw#ErrorMsg(s:ERROR,"unable to change directory to <".b:netrw_curdir."> (permissions?)",33)
+     if exists("w:netrw_prvdir")
+      let b:netrw_curdir= w:netrw_prvdir
+     else
+      call s:NetOptionRestore()
+      let b:netrw_curdir= dirname
+"      call Dret("NetBrowse : reusing buffer#".(exists("bufnum")? bufnum : 'N/A')."<".dirname."> getcwd<".getcwd().">")
+      return
+     endif
+    endtry
+   endif
+
+  " --------------------------------
+  " remote handling: {{{3
+  " --------------------------------
+  else
+"   call Decho("remote only:")
+
+   " analyze a:dirname and g:netrw_list_cmd {{{4
+"   call Decho("b:netrw_curdir<".(exists("b:netrw_curdir")? b:netrw_curdir : "doesn't exist")."> a:dirname<".a:dirname.">")
+   if a:dirname == "NetrwTreeListing"
+    let dirname= b:netrw_curdir
+"    call Decho("(dirname was NetrwTreeListing) dirname<".dirname.">")
+   elseif exists("w:netrw_liststyle") && w:netrw_liststyle == s:TREELIST && exists("b:netrw_curdir")
+    let dirname= substitute(b:netrw_curdir,'\\','/','g')
+    if dirname !~ '/$'
+     let dirname= dirname.'/'
+    endif
+    let b:netrw_curdir = dirname
+"    call Decho("(liststyle is TREELIST) dirname<".dirname.">")
+   else
+    let dirname = substitute(a:dirname,'\\','/','g')
+"    call Decho("(normal) dirname<".dirname.">")
+   endif
+
+   let dirpat  = '^\(\w\{-}\)://\(\w\+@\)\=\([^/]\+\)/\(.*\)$'
+   if dirname !~ dirpat
+    if !exists("g:netrw_quiet")
+     call netrw#ErrorMsg(s:ERROR,"netrw doesn't understand your dirname<".dirname.">",20)
+    endif
+     call s:NetOptionRestore()
+"    call Dret("NetBrowse : badly formatted dirname<".dirname.">")
+    return
+   endif
+   let b:netrw_curdir= dirname
+"   call Decho("b:netrw_curdir<".b:netrw_curdir."> (remote)")
+  endif  " (additional remote handling)
+
+  " -----------------------
+  " Directory Listing: {{{3
+  " -----------------------
+  setlocal noro ma
+  call s:BrowserMaps(a:islocal)
+  call s:PerformListing(a:islocal)
+
+"  call Dret("NetBrowse")
+  return
+endfun
+
+" ---------------------------------------------------------------------
+" s:NetGetBuffer: {{{2
+"   returns 0=cleared buffer
+"           1=re-used buffer
+fun! s:NetGetBuffer(islocal,dirname)
+"  call Dfunc("s:NetGetBuffer(islocal=".a:islocal." dirname<".a:dirname.">)")
+
+  " re-use buffer if possible {{{3
+  if exists("w:netrw_liststyle") && w:netrw_liststyle == s:TREELIST
+   " find NetrwTreeList buffer if there is one
+   let dirname= "NetrwTreeListing"
+   let bufnum = bufnr('\<NetrwTreeListing\>')
+   if bufnum != -1
+"    call Dret("s:NetGetBuffer : bufnum#".bufnum."<NetrwTreeListing>")
+    return
+   endif
+
+  else
+   " find buffer number of buffer named precisely the same as dirname {{{3
+"   call Dredir("ls!")
+   let dirname= a:dirname
+"   call Decho("find buffer<".dirname.">'s number ")
+   let bufnum= bufnr(escape(dirname,'\'))
+"   call Decho("findbuf1: bufnum=bufnr('".escape(dirname,'\')."')=".bufnum." (initial)")
+   let ibuf= 1
+   if bufnum > 0 && bufname(bufnum) != dirname
+    let buflast = bufnr("$")
+"    call Decho("findbuf2: buflast=".buflast)
+    while ibuf <= buflast
+     let bname= bufname(ibuf)
+"     call Decho("findbuf3: dirname<".dirname."> bufname(".ibuf.")<".bname.">")
+     if bname != '' && bname !~ '/' && dirname =~ '/'.bname.'$' | break | endif
+     if bname =~ '^'.dirname.'\=$' | break | endif
+     let ibuf= ibuf + 1
+    endwhile
+    if ibuf > buflast
+     let bufnum= -1
+    else
+     let bufnum= ibuf
+    endif
+"    call Decho("findbuf4: bufnum=".bufnum)
+   endif
+  endif
+
+  " get enew buffer and name it -or- re-use buffer {{{3
+  mark '
+  if bufnum < 0 || !bufexists(bufnum)
+"   call Decho("get enew buffer")
+   call s:NetrwEnew(dirname)
+   call s:NetrwSafeOptions()
+   " name the buffer
+   if exists("w:netrw_liststyle") && w:netrw_liststyle == s:TREELIST
+"    call Decho('silent! keepalt file NetrwTreeListing')
+    silent! keepalt file NetrwTreeListing
+   else
+"    call Decho('exe silent! keepalt file '.escape(dirname,s:netrw_cd_escape))
+"    let v:errmsg= "" " Decho
+    let escdirname= escape(dirname,s:netrw_cd_escape)
+    exe 'silent! keepalt file '.escdirname
+"    call Decho("errmsg<".v:errmsg."> bufnr(".escdirname.")=".bufnr(escdirname)."<".bufname(bufnr(escdirname)).">")
+   endif
+"   call Decho("named enew buffer#".bufnr("%")."<".bufname("%").">")
+
+  else " Re-use the buffer
+
+"   call Decho("re-use buffer:")
+   let eikeep= &ei
+   set ei=all
+   if getline(2) =~ '^" Netrw Directory Listing'
+"    call Decho("re-use buffer#".bufnum."<".((bufnum > 0)? bufname(bufnum) : "")."> using:  keepalt b ".bufnum)
+    exe "keepalt b ".bufnum
+   else
+"    call Decho("reusing buffer#".bufnum."<".((bufnum > 0)? bufname(bufnum) : "")."> using:  b ".bufnum)
+    exe "b ".bufnum
+   endif
+   let &ei= eikeep
+   if line("$") <= 1
+    call s:NetrwListSettings(a:islocal)
+"    call Dret("s:NetGetBuffer 0 : re-using buffer#".bufnr("%").", but its empty, so refresh it")
+    return 0
+   elseif exists("w:netrw_liststyle") && w:netrw_liststyle == s:TREELIST
+"    call Decho("clear buffer<".expand("%")."> with :%d")
+    silent %d
+    call s:NetrwListSettings(a:islocal)
+"    call Dret("s:NetGetBuffer 0 : re-using buffer#".bufnr("%").", but treelist mode always needs a refresh")
+    return 0
+   else
+"    call Dret("s:NetGetBuffer 1 : buf#".bufnr("%"))
+    return 1
+   endif
+  endif
+
+  " do netrw settings: make this buffer not-a-file, modifiable, not line-numbered, etc {{{3
+  "     fastbrowse  Local  Remote   Hiding a buffer implies it may be re-used (fast)
+  "  slow   0         D      D      Deleting a buffer implies it will not be re-used (slow)
+  "  med    1         D      H
+  "  fast   2         H      H
+  let fname= expand("%")
+  call s:NetrwListSettings(a:islocal)
+  exe "file ".escape(fname,' ')
+
+  " delete all lines from buffer {{{3
+"  call Decho("clear buffer<".expand("%")."> with :%d")
+  keepalt silent! %d
+
+"  call Dret("s:NetGetBuffer 0 : buf#".bufnr("%"))
+  return 0
+endfun
+
+" ---------------------------------------------------------------------
+" s:NetrwListSettings: {{{2
+fun! s:NetrwListSettings(islocal)
+"  call Dfunc("s:NetrwListSettings(islocal=".a:islocal.")")
+  let fname= bufname("%")
+  setlocal bt=nofile nobl ma nonu nowrap noro
+  exe "file ".escape(fname,' ')
+  if g:netrw_use_noswf
+   setlocal noswf
+  endif
+"  call Dredir("ls!")
+"  call Decho("exe setlocal ts=".g:netrw_maxfilenamelen)
+  exe "setlocal ts=".g:netrw_maxfilenamelen
+  if g:netrw_fastbrowse > a:islocal
+   setlocal bh=hide
+  else
+   setlocal bh=delete
+  endif
+"  call Dret("s:NetrwListSettings")
+endfun
+
+" ---------------------------------------------------------------------
+" s:PerformListing: {{{2
+fun! s:PerformListing(islocal)
+"  call Dfunc("s:PerformListing(islocal=".a:islocal.") buf(%)=".bufnr("%")."<".bufname("%").">")
+
+"   if exists("g:netrw_silent") && g:netrw_silent == 0 && &ch >= 1	" Decho
+"    call Decho("(netrw) Processing your browsing request...")
+"   endif								" Decho
+
+"   call Decho('w:netrw_liststyle='.(exists("w:netrw_liststyle")? w:netrw_liststyle : 'n/a'))
+   if exists("w:netrw_liststyle") && w:netrw_liststyle == s:TREELIST && exists("w:netrw_treedict")
+    " force a refresh for tree listings
+"    call Decho("force refresh for treelisting: clear buffer<".expand("%")."> with :%d")
+    setlocal ma noro
+    keepjumps %d
+   endif
+
+  " save current directory on directory history list
+  call s:NetBookmarkDir(3,b:netrw_curdir)
+
+  " Set up the banner {{{3
+"  call Decho("set up banner")
+  keepjumps put ='\" ============================================================================'
+  keepjumps put ='\" Netrw Directory Listing                                        (netrw '.g:loaded_netrw.')'
+  keepjumps put ='\"   '.b:netrw_curdir
+  keepjumps 1d
+  let w:netrw_bannercnt= 3
+  exe w:netrw_bannercnt
+
+  let sortby= g:netrw_sort_by
+  if g:netrw_sort_direction =~ "^r"
+   let sortby= sortby." reversed"
+  endif
+
+  " Sorted by... {{{3
+"  call Decho("handle specified sorting: g:netrw_sort_by<".g:netrw_sort_by.">")
+  if g:netrw_sort_by =~ "^n"
+"   call Decho("directories will be sorted by name")
+   " sorted by name
+   keepjumps put ='\"   Sorted by      '.sortby
+   keepjumps put ='\"   Sort sequence: '.g:netrw_sort_sequence
+   let w:netrw_bannercnt= w:netrw_bannercnt + 2
+  else
+"   call Decho("directories will be sorted by size or time")
+   " sorted by size or date
+   keepjumps put ='\"   Sorted by '.sortby
+   let w:netrw_bannercnt= w:netrw_bannercnt + 1
+  endif
+  exe w:netrw_bannercnt
+
+  " Hiding...  -or-  Showing... {{{3
+"  call Decho("handle hiding/showing (g:netrw_hide=".g:netrw_list_hide." g:netrw_list_hide<".g:netrw_list_hide.">)")
+  if g:netrw_list_hide != "" && g:netrw_hide
+   if g:netrw_hide == 1
+    keepjumps put ='\"   Hiding:        '.g:netrw_list_hide
+   else
+    keepjumps put ='\"   Showing:       '.g:netrw_list_hide
+   endif
+   let w:netrw_bannercnt= w:netrw_bannercnt + 1
+  endif
+  exe w:netrw_bannercnt
+  keepjumps put ='\"   Quick Help: <F1>:help  -:go up dir  D:delete  R:rename  s:sort-by  x:exec'
+  keepjumps put ='\" ============================================================================'
+  let w:netrw_bannercnt= w:netrw_bannercnt + 2
+
+  " bannercnt should index the line just after the banner
+  let w:netrw_bannercnt= w:netrw_bannercnt + 1
+  exe w:netrw_bannercnt
+"  call Decho("bannercnt=".w:netrw_bannercnt." (should index line just after banner) line($)=".line("$"))
+
+  " set up syntax highlighting {{{3
+"  call Decho("set up syntax highlighting")
+  if has("syntax")
+   setlocal ft=netrw
+   if !exists("g:syntax_on") || !g:syntax_on
+    setlocal ft=
+   endif
+  endif
+
+  " get list of files
+  if a:islocal
+   call s:LocalListing()
+  else " remote
+   call s:RemoteListing()
+  endif
+"  call Decho("w:netrw_bannercnt=".w:netrw_bannercnt." (banner complete)")
+
+  " manipulate the directory listing (hide, sort) {{{3
+  if line("$") >= w:netrw_bannercnt
+"   call Decho("manipulate directory listing (hide)")
+"   call Decho("g:netrw_hide=".g:netrw_hide." g:netrw_list_hide<".g:netrw_list_hide.">")
+   if g:netrw_hide && g:netrw_list_hide != ""
+    call s:NetListHide()
+   endif
+   if line("$") >= w:netrw_bannercnt
+"    call Decho("manipulate directory listing (sort) : g:netrw_sort_by<".g:netrw_sort_by.">")
+
+    if g:netrw_sort_by =~ "^n"
+     " sort by name
+     call s:SetSort()
+
+     if w:netrw_bannercnt < line("$")
+"      call Decho("g:netrw_sort_direction=".g:netrw_sort_direction." (bannercnt=".w:netrw_bannercnt.")")
+      if g:netrw_sort_direction =~ 'n'
+       " normal direction sorting
+       exe 'silent keepjumps '.w:netrw_bannercnt.',$sort'
+      else
+       " reverse direction sorting
+       exe 'silent keepjumps '.w:netrw_bannercnt.',$sort!'
+      endif
+     endif
+     " remove priority pattern prefix
+"     call Decho("remove priority pattern prefix")
+     exe 'silent keepjumps '.w:netrw_bannercnt.',$s/^\d\{3}\///e'
+
+    elseif a:islocal
+     if w:netrw_bannercnt < line("$")
+"      call Decho("g:netrw_sort_direction=".g:netrw_sort_direction)
+      if g:netrw_sort_direction =~ 'n'
+"       call Decho('exe silent keepjumps '.w:netrw_bannercnt.',$sort')
+       exe 'silent keepjumps '.w:netrw_bannercnt.',$sort'
+      else
+"       call Decho('exe silent keepjumps '.w:netrw_bannercnt.',$sort!')
+       exe 'silent keepjumps '.w:netrw_bannercnt.',$sort!'
+      endif
+     endif
+     exe 'silent keepjumps '.w:netrw_bannercnt.',$s/^\d\{-}\///e'
+    endif
+
+   elseif g:netrw_sort_direction =~ 'r'
+"    call Decho('reverse the sorted listing')
+    exe 'silent keepjumps '.w:netrw_bannercnt.'g/^/m '.w:netrw_bannercnt
+   endif
+  endif
+
+  " convert to wide/tree listing {{{3
+"  call Decho("modify display if wide/tree listing style")
+  call s:NetWideListing()
+  call s:NetTreeListing(b:netrw_curdir)
+
+  if exists("w:netrw_bannercnt") && line("$") > w:netrw_bannercnt
+   " place cursor on the top-left corner of the file listing
+"   call Decho("place cursor on top-left corner of file listing")
+   exe 'silent '.w:netrw_bannercnt
+   norm! 0
+  endif
+
+  " record previous current directory
+  let w:netrw_prvdir= b:netrw_curdir
+"  call Decho("record netrw_prvdir<".w:netrw_prvdir.">")
+
+  " save certain window-oriented variables into buffer-oriented variables {{{3
+  call s:SetBufWinVars()
+  call s:NetOptionRestore()
+
+  " set display to netrw display settings
+"  call Decho("set display to netrw display settings (noma nomod etc)")
+  setlocal noma nomod nonu nobl nowrap ro
+  if exists("s:treecurpos")
+   call setpos('.',s:treecurpos)
+   unlet s:treecurpos
+  endif
+
+"  call Dret("s:PerformListing : curpos<".string(getpos(".")).">")
+endfun
+
+" ---------------------------------------------------------------------
+"  s:NetBrowseChgDir: constructs a new directory based on the current {{{2
+"                     directory and a new directory name
+fun! s:NetBrowseChgDir(islocal,newdir,...)
+"  call Dfunc("s:NetBrowseChgDir(islocal=".a:islocal."> newdir<".a:newdir.">) a:0=".a:0." curpos<".string(getpos("."))."> b:netrw_curdir<".(exists("b:netrw_curdir")? b:netrw_curdir : "").">")
+
+  if !exists("b:netrw_curdir")
+"   call Decho("(NetBrowseChgDir) b:netrw_curdir doesn't exist!")
+   echoerr "(NetBrowseChgDir) b:netrw_curdir doesn't exist!"
+"   call Dret("s:NetBrowseChgDir")
+   return
+  endif
+
+  call netrw#NetSavePosn()
+  let nbcd_curpos = getpos('.')
+  let dirname     = substitute(b:netrw_curdir,'\\','/','ge')
+  let newdir      = a:newdir
+
+  " set up o/s-dependent directory recognition pattern
+  if has("amiga")
+   let dirpat= '[\/:]$'
+  else
+   let dirpat= '[\/]$'
+  endif
+"  call Decho("dirname<".dirname.">  dirpat<".dirpat.">")
+
+  if dirname !~ dirpat
+   " apparently vim is "recognizing" that it is in a directory and
+   " is removing the trailing "/".  Bad idea, so I have to put it back.
+   let dirname= dirname.'/'
+"   call Decho("adjusting dirname<".dirname.">")
+  endif
+
+  if newdir !~ dirpat
+   " handling a file
+"   call Decho('case "handling a file": newdir<'.newdir.'> !~ dirpat<'.dirpat.">")
+   if exists("w:netrw_liststyle") && w:netrw_liststyle == s:TREELIST && exists("w:netrw_treedict") && newdir !~ '^\(/\|\a:\)'
+    let dirname= s:NetTreeDir().newdir
+"    call Decho("tree listing")
+   elseif newdir =~ '^\(/\|\a:\)'
+    let dirname= newdir
+   else
+    let dirname= s:ComposePath(dirname,newdir)
+   endif
+"   call Decho("handling a file: dirname<".dirname."> (a:0=".a:0.")")
+   " this lets NetBrowseX avoid the edit
+   if a:0 < 1
+"    call Decho("dirname<".dirname."> netrw_cd_escape<".s:netrw_cd_escape."> browse_split=".g:netrw_browse_split)
+"    call Decho("about to edit<".escape(dirname,s:netrw_cd_escape).">  didsplit=".(exists("s:didsplit")? s:didsplit : "doesn't exist"))
+    if !exists("s:didsplit")
+     if     g:netrw_browse_split == 1
+      new
+      wincmd _
+     elseif g:netrw_browse_split == 2
+      rightb vert new
+      wincmd |
+     elseif g:netrw_browse_split == 3
+      tabnew
+     else
+      " handling a file, didn't split, so remove menu
+"      call Decho("handling a file+didn't split, so remove menu")
+      call s:NetMenu(0)
+      " optional change to window
+      if g:netrw_chgwin >= 1 
+       exe g:netrw_chgwin."wincmd w"
+      endif
+     endif
+    endif
+    " edit the file
+    " its local only: LocalBrowseCheck() doesn't edit a file, but NetBrowse() will
+    if a:islocal
+"     call Decho("edit file: exe e! ".escape(dirname,s:netrw_cd_escape))
+     exe "e! ".escape(dirname,s:netrw_cd_escape)
+    endif
+    setlocal ma nomod noro
+   endif
+
+  elseif newdir =~ '^/'
+   " just go to the new directory spec
+"   call Decho('case "just go to new directory spec": newdir<'.newdir.'>')
+   let dirname= newdir
+
+  elseif newdir == './'
+   " refresh the directory list
+"   call Decho('case "refresh directory listing": newdir == "./"')
+
+  elseif newdir == '../'
+   " go up one directory
+"   call Decho('case "go up one directory": newdir == "../"')
+
+   if w:netrw_liststyle == s:TREELIST && exists("w:netrw_treedict")
+    " force a refresh
+"    call Decho("clear buffer<".expand("%")."> with :%d")
+    setlocal noro ma
+    keepjumps %d
+   endif
+
+   if has("amiga")
+    " amiga
+"    call Decho('case "go up one directory": newdir == "../" and amiga')
+    if a:islocal
+     let dirname= substitute(dirname,'^\(.*[/:]\)\([^/]\+$\)','\1','')
+     let dirname= substitute(dirname,'/$','','')
+    else
+     let dirname= substitute(dirname,'^\(.*[/:]\)\([^/]\+/$\)','\1','')
+    endif
+"    call Decho("amiga: dirname<".dirname."> (go up one dir)")
+
+   else
+    " unix or cygwin
+"    call Decho('case "go up one directory": newdir == "../" and unix or cygwin')
+    if a:islocal
+     let dirname= substitute(dirname,'^\(.*\)/\([^/]\+\)/$','\1','')
+     if dirname == ""
+      let dirname= '/'
+     endif
+    else
+     let dirname= substitute(dirname,'^\(\a\+://.\{-}/\{1,2}\)\(.\{-}\)\([^/]\+\)/$','\1\2','')
+    endif
+"    call Decho("unix: dirname<".dirname."> (go up one dir)")
+   endif
+
+  elseif w:netrw_liststyle == s:TREELIST && exists("w:netrw_treedict")
+"   call Decho('case liststyle is TREELIST and w:netrw_treedict exists')
+   " force a refresh (for TREELIST, wait for NetTreeDir() to force the refresh)
+   setlocal noro ma
+   if !(exists("w:netrw_liststyle") && w:netrw_liststyle == s:TREELIST && exists("b:netrw_curdir"))
+"    call Decho("clear buffer<".expand("%")."> with :%d")
+    keepjumps %d
+   endif
+   let treedir      = s:NetTreeDir()
+   let s:treecurpos = nbcd_curpos
+   let haskey= 0
+"   call Decho("w:netrw_treedict<".string(w:netrw_treedict).">")
+
+   " search treedict for tree dir as-is
+   if has_key(w:netrw_treedict,treedir)
+"    call Decho('....searched for treedir<'.treedir.'> : found it!')
+    let haskey= 1
+   else
+"    call Decho('....searched for treedir<'.treedir.'> : not found')
+   endif
+
+   " search treedict for treedir with a / appended
+   if !haskey && treedir !~ '/$'
+    if has_key(w:netrw_treedict,treedir."/")
+     let treedir= treedir."/"
+"     call Decho('....searched.for treedir<'.treedir.'> found it!')
+     let haskey = 1
+    else
+"     call Decho('....searched for treedir<'.treedir.'/> : not found')
+    endif
+   endif
+
+   " search treedict for treedir with any trailing / elided
+   if !haskey && treedir =~ '/$'
+    let treedir= substitute(treedir,'/$','','')
+    if has_key(w:netrw_treedict,treedir)
+"     call Decho('....searched.for treedir<'.treedir.'> found it!')
+     let haskey = 1
+    else
+"     call Decho('....searched for treedir<'.treedir.'> : not found')
+    endif
+   endif
+
+   if haskey
+    " close tree listing for selected subdirectory
+"    call Decho("closing selected subdirectory<".dirname.">")
+    call remove(w:netrw_treedict,treedir)
+"    call Decho("removed     entry<".dirname."> from treedict")
+"    call Decho("yielding treedict<".string(w:netrw_treedict).">")
+    let dirname= w:netrw_treetop
+   else
+    " go down one directory
+    let dirname= substitute(treedir,'/*$','/','')
+"    call Decho("go down one dir: treedir<".treedir.">")
+   endif
+
+  else
+   " go down one directory
+   let dirname= s:ComposePath(dirname,newdir)
+"   call Decho("go down one dir: dirname<".dirname."> newdir<".newdir.">")
+  endif
+
+"  call Dret("s:NetBrowseChgDir <".dirname."> : curpos<".string(getpos(".")).">")
+  return dirname
+endfun
+
+" ---------------------------------------------------------------------
+" s:NetHide: this function is invoked by the "a" map for browsing {{{2
+"          and switches the hiding mode
+fun! s:NetHide(islocal)
+"  call Dfunc("NetHide(islocal=".a:islocal.")")
+   let g:netrw_hide=(g:netrw_hide+1)%3
+   exe "norm! 0"
+   if g:netrw_hide && g:netrw_list_hide == ""
+    call netrw#ErrorMsg(s:WARNING,"your hiding list is empty!",49)
+"    call Dret("NetHide")
+    return
+   endif
+   call netrw#NetSavePosn()
+   call s:NetRefresh(a:islocal,s:NetBrowseChgDir(a:islocal,'./'))
+"  call Dret("NetHide")
+endfun
+
+" ---------------------------------------------------------------------
+
+" ===========================================
+" s:NetPreview: {{{2
+fun! s:NetPreview(path) range
+"  call Dfunc("NetPreview(path<".a:path.">)")
+  if has("quickfix")
+   if !isdirectory(a:path)
+    exe "pedit ".escape(a:path,g:netrw_fname_escape)
+   elseif !exists("g:netrw_quiet")
+    call netrw#ErrorMsg(s:WARNING,"sorry, cannot preview a directory such as <".a:path.">",38)
+   endif
+  elseif !exists("g:netrw_quiet")
+   call netrw#ErrorMsg(s:WARNING,"sorry, to preview your vim needs the quickfix feature compiled in",39)
+  endif
+"  call Dret("NetPreview")
+endfun
+
+" ---------------------------------------------------------------------
+" s:NetSortStyle: change sorting style (name - time - size) and refresh display {{{2
+fun! s:NetSortStyle(islocal)
+"  call Dfunc("s:NetSortStyle(islocal=".a:islocal.") netrw_sort_by<".g:netrw_sort_by.">")
+  call s:NetSaveWordPosn()
+
+  let g:netrw_sort_by= (g:netrw_sort_by =~ 'n')? 'time' : (g:netrw_sort_by =~ 't')? 'size' : 'name'
+  norm! 0
+  call netrw#NetSavePosn()
+  call s:NetRefresh(a:islocal,s:NetBrowseChgDir(a:islocal,'./'))
+
+"  call Dret("s:NetSortStyle : netrw_sort_by<".g:netrw_sort_by.">")
+endfun
+
+" ---------------------------------------------------------------------
+"  Remote Directory Browsing Support:    {{{1
+" ===========================================
+
+" ---------------------------------------------------------------------
+" s:RemoteListing: {{{2
+fun! s:RemoteListing()
+"  call Dfunc("s:RemoteListing() b:netrw_curdir<".b:netrw_curdir.">)")
+
+  call s:RemotePathAnalysis(b:netrw_curdir)
+
+  " sanity check:
+  if exists("b:netrw_method") && b:netrw_method =~ '[235]'
+"   call Decho("b:netrw_method=".b:netrw_method)
+   if !executable("ftp")
+    if !exists("g:netrw_quiet")
+     call netrw#ErrorMsg(s:ERROR,"this system doesn't support remote directory listing via ftp",18)
+    endif
+    call s:NetOptionRestore()
+"    call Dret("s:RemoteListing")
+    return
+   endif
+
+  elseif !exists("g:netrw_list_cmd") || g:netrw_list_cmd == ''
+   if !exists("g:netrw_quiet")
+    if g:netrw_list_cmd == ""
+     call netrw#ErrorMsg(s:ERROR,g:netrw_ssh_cmd." is not executable on your system",47)
+    else
+     call netrw#ErrorMsg(s:ERROR,"this system doesn't support remote directory listing via ".g:netrw_list_cmd,19)
+    endif
+   endif
+
+   call s:NetOptionRestore()
+"   call Dret("s:RemoteListing")
+   return
+  endif  " (remote handling sanity check)
+
+  if exists("b:netrw_method")
+"   call Decho("setting w:netrw_method<".b:netrw_method.">")
+   let w:netrw_method= b:netrw_method
+  endif
+
+  if s:method == "ftp"
+   " use ftp to get remote file listing
+"   call Decho("use ftp to get remote file listing")
+   let s:method  = "ftp"
+   let listcmd = g:netrw_ftp_list_cmd
+   if g:netrw_sort_by =~ '^t'
+    let listcmd= g:netrw_ftp_timelist_cmd
+   elseif g:netrw_sort_by =~ '^s'
+    let listcmd= g:netrw_ftp_sizelist_cmd
+   endif
+"   call Decho("listcmd<".listcmd."> (using g:netrw_ftp_list_cmd)")
+   call s:NetBrowseFtpCmd(s:path,listcmd)
+"   exe "keepjumps ".w:netrw_bannercnt.',$g/^./call Decho("raw listing: ".getline("."))'
+
+   if w:netrw_liststyle == s:THINLIST || w:netrw_liststyle == s:WIDELIST || w:netrw_liststyle == s:TREELIST
+    " shorten the listing
+"    call Decho("generate short listing")
+    exe "keepjumps ".w:netrw_bannercnt
+
+    " cleanup
+    if g:netrw_ftp_browse_reject != ""
+     exe "silent! g/".g:netrw_ftp_browse_reject."/keepjumps d"
+    endif
+    silent! keepjumps %s/\r$//e
+
+    " if there's no ../ listed, then put ./ and ../ in
+    let line1= line(".")
+    exe "keepjumps ".w:netrw_bannercnt
+    let line2= search('^\.\.\/\%(\s\|$\)','cnW')
+    if line2 == 0
+"     call Decho("netrw is putting ./ and ../ into listing")
+     keepjumps put='../'
+     keepjumps put='./'
+    endif
+    exe "keepjumps ".line1
+    keepjumps norm! 0
+
+"    call Decho("line1=".line1." line2=".line2." line(.)=".line("."))
+    if search('^\d\{2}-\d\{2}-\d\{2}\s','n') " M$ ftp site cleanup
+"     call Decho("M$ ftp cleanup")
+     exe 'silent! keepjumps '.w:netrw_bannercnt.',$s/^\d\{2}-\d\{2}-\d\{2}\s\+\d\+:\d\+[AaPp][Mm]\s\+\%(<DIR>\|\d\+\)\s\+//'
+    else " normal ftp cleanup
+"     call Decho("normal ftp cleanup")
+     exe 'silent! keepjumps '.w:netrw_bannercnt.',$s/^\(\%(\S\+\s\+\)\{7}\S\+\)\s\+\(\S.*\)$/\2/e'
+     exe "silent! keepjumps ".w:netrw_bannercnt.',$g/ -> /s# -> .*/$#/#e'
+     exe "silent! keepjumps ".w:netrw_bannercnt.',$g/ -> /s# -> .*$#/#e'
+    endif
+   endif
+
+  else
+   " use ssh to get remote file listing {{{3
+"   call Decho("use ssh to get remote file listing: s:netrw_shq<".g:netrw_shq."> s:path<".s:path."> s:netrw_cd_escape<".s:netrw_cd_escape.">")
+   let listcmd= s:MakeSshCmd(g:netrw_list_cmd)
+"   call Decho("listcmd<".listcmd."> (using g:netrw_list_cmd)")
+   if g:netrw_scp_cmd =~ '^pscp'
+"    call Decho("1: exe silent r! ".listcmd.g:netrw_shq.s:path.g:netrw_shq)
+    exe "silent r! ".listcmd.g:netrw_shq.s:path.g:netrw_shq
+    " remove rubbish and adjust listing format of 'pscp' to 'ssh ls -FLa' like
+    g/^Listing directory/d
+    g/^d[-rwx][-rwx][-rwx]/s+$+/+e
+    silent g/^l[-rwx][-rwx][-rwx]/s+$+@+e
+    if g:netrw_liststyle != s:LONGLIST 
+     g/^[dlsp-][-rwx][-rwx][-rwx]/s/^.*\s\(\S\+\)$/\1/e
+    endif
+   else
+    if s:path == ""
+"     call Decho("2: exe silent r! ".listcmd)
+     exe "silent r! ".listcmd
+    else
+"     call Decho("3: exe silent r! ".listcmd." ".g:netrw_shq.s:path.g:netrw_shq)
+     exe "silent r! ".listcmd." ".g:netrw_shq.s:path.g:netrw_shq
+    endif
+   endif
+
+   " cleanup
+   if g:netrw_ftp_browse_reject != ""
+"    call Decho("(cleanup) exe silent! g/".g:netrw_ssh_browse_reject."/keepjumps d")
+    exe "silent! g/".g:netrw_ssh_browse_reject."/keepjumps d"
+   endif
+  endif
+
+  if w:netrw_liststyle == s:LONGLIST
+   " do a long listing; these substitutions need to be done prior to sorting {{{3
+"   call Decho("fix long listing:")
+
+   if s:method == "ftp"
+    " cleanup
+    exe "keepjumps ".w:netrw_bannercnt
+    while getline(".") =~ g:netrw_ftp_browse_reject
+     keepjumps d
+    endwhile
+    " if there's no ../ listed, then put ./ and ../ in
+    let line1= line(".")
+    keepjumps 1
+    silent keepjumps call search('^\.\.\/\%(\s\|$\)','W')
+    let line2= line(".")
+    if line2 == 0
+     exe 'keepjumps '.w:netrw_bannercnt."put='./'"
+     if b:netrw_curdir != '/'
+      exe 'keepjumps '.w:netrw_bannercnt."put='../'"
+     endif
+    endif
+   exe "keepjumps ".line1
+   keepjumps norm! 0
+   endif
+
+   if search('^\d\{2}-\d\{2}-\d\{2}\s','n') " M$ ftp site cleanup
+"    call Decho("M$ ftp site listing cleanup")
+    exe 'silent! keepjumps '.w:netrw_bannercnt.',$s/^\(\d\{2}-\d\{2}-\d\{2}\s\+\d\+:\d\+[AaPp][Mm]\s\+\%(<DIR>\|\d\+\)\s\+\)\(\w.*\)$/\2\t\1/'
+   elseif exists("w:netrw_bannercnt") && w:netrw_bannercnt <= line("$")
+"    call Decho("normal ftp site listing cleanup: bannercnt=".w:netrw_bannercnt." line($)=".line("$"))
+    exe 'silent keepjumps '.w:netrw_bannercnt.',$s/ -> .*$//e'
+    exe 'silent keepjumps '.w:netrw_bannercnt.',$s/^\(\%(\S\+\s\+\)\{7}\S\+\)\s\+\(\S.*\)$/\2\t\1/e'
+    exe 'silent keepjumps '.w:netrw_bannercnt
+   endif
+  endif
+
+"  if exists("w:netrw_bannercnt") && w:netrw_bannercnt <= line("$") " Decho
+"   exe "keepjumps ".w:netrw_bannercnt.',$g/^./call Decho("listing: ".getline("."))'
+"  endif " Decho
+"  call Dret("s:RemoteListing")
+endfun
+
+" ---------------------------------------------------------------------
+"  NetGetWord: it gets the directory named under the cursor {{{2
+fun! s:NetGetWord()
+"  call Dfunc("NetGetWord() line#".line(".")." liststyle=".g:netrw_liststyle." virtcol=".virtcol("."))
+  call s:UseBufWinVars()
+
+  " insure that w:netrw_liststyle is set up
+  if !exists("w:netrw_liststyle")
+   if exists("g:netrw_liststyle")
+    let w:netrw_liststyle= g:netrw_liststyle
+   else
+    let w:netrw_liststyle= s:THINLIST
+   endif
+"   call Decho("w:netrw_liststyle=".w:netrw_liststyle)
+  endif
+
+  if exists("w:netrw_bannercnt") && line(".") < w:netrw_bannercnt
+   " Active Banner support
+"   call Decho("active banner handling")
+   norm! 0
+   let dirname= "./"
+   let curline= getline(".")
+
+   if curline =~ '"\s*Sorted by\s'
+    norm s
+    let s:netrw_skipbrowse= 1
+    echo 'Pressing "s" also works'
+
+   elseif curline =~ '"\s*Sort sequence:'
+    let s:netrw_skipbrowse= 1
+    echo 'Press "S" to edit sorting sequence'
+
+   elseif curline =~ '"\s*Quick Help:'
+    norm ?
+    let s:netrw_skipbrowse= 1
+    echo 'Pressing "?" also works'
+
+   elseif curline =~ '"\s*\%(Hiding\|Showing\):'
+    norm a
+    let s:netrw_skipbrowse= 1
+    echo 'Pressing "a" also works'
+
+   elseif line("$") > w:netrw_bannercnt
+    exe 'silent keepjumps '.w:netrw_bannercnt
+   endif
+
+  elseif w:netrw_liststyle == s:THINLIST
+"   call Decho("thin column handling")
+   norm! 0
+   let dirname= getline(".")
+
+  elseif w:netrw_liststyle == s:LONGLIST
+"   call Decho("long column handling")
+   norm! 0
+   let dirname= substitute(getline("."),'^\(\%(\S\+ \)*\S\+\).\{-}$','\1','e')
+
+  elseif w:netrw_liststyle == s:TREELIST
+"   call Decho("treelist handling")
+   let dirname= substitute(getline("."),'^\(| \)*','','e')
+
+  else
+"   call Decho("obtain word from wide listing")
+   let dirname= getline(".")
+
+   if !exists("b:netrw_cpf")
+    let b:netrw_cpf= 0
+    exe 'silent keepjumps '.w:netrw_bannercnt.',$g/^./if virtcol("$") > b:netrw_cpf|let b:netrw_cpf= virtcol("$")|endif'
+"    call Decho("computed cpf")
+   endif
+
+"   call Decho("buf#".bufnr("%")."<".bufname("%").">")
+   let filestart = (virtcol(".")/b:netrw_cpf)*b:netrw_cpf
+"   call Decho("filestart= ([virtcol=".virtcol(".")."]/[b:netrw_cpf=".b:netrw_cpf."])*b:netrw_cpf=".filestart."  bannercnt=".w:netrw_bannercnt)
+"   call Decho("1: dirname<".dirname.">")
+   if filestart > 0|let dirname= substitute(dirname,'^.\{'.filestart.'}','','')|endif
+"   call Decho("2: dirname<".dirname.">")
+   let dirname   = substitute(dirname,'^\(.\{'.b:netrw_cpf.'}\).*$','\1','e')
+"   call Decho("3: dirname<".dirname.">")
+   let dirname   = substitute(dirname,'\s\+$','','e')
+"   call Decho("4: dirname<".dirname.">")
+  endif
+
+"  call Dret("NetGetWord <".dirname.">")
+  return dirname
+endfun
+
+" ---------------------------------------------------------------------
+" NetBrowseRm: remove/delete a remote file or directory {{{2
+fun! s:NetBrowseRm(usrhost,path) range
+"  call Dfunc("NetBrowseRm(usrhost<".a:usrhost."> path<".a:path.">) virtcol=".virtcol("."))
+"  call Decho("firstline=".a:firstline." lastline=".a:lastline)
+
+  " preparation for removing multiple files/directories
+  let ctr= a:firstline
+  let all= 0
+
+  " remove multiple files and directories
+  while ctr <= a:lastline
+   exe ctr
+
+   let rmfile= s:NetGetWord()
+"   call Decho("rmfile<".rmfile.">")
+
+   if rmfile !~ '^"' && (rmfile =~ '@$' || rmfile !~ '[\/]$')
+    " attempt to remove file
+"    call Decho("attempt to remove file")
+    if !all
+     echohl Statement
+     call inputsave()
+     let ok= input("Confirm deletion of file<".rmfile."> ","[{y(es)},n(o),a(ll),q(uit)] ")
+     call inputrestore()
+     echohl NONE
+     if ok == ""
+      let ok="no"
+     endif
+     let ok= substitute(ok,'\[{y(es)},n(o),a(ll),q(uit)]\s*','','e')
+     if ok =~ 'a\%[ll]'
+      let all= 1
+     endif
+    endif
+
+    if all || ok =~ 'y\%[es]' || ok == ""
+     if exists("w:netrw_method") && (w:netrw_method == 2 || w:netrw_method == 3)
+      silent! keepjumps .,$d
+      call s:NetBrowseFtpCmd(a:path,"delete ".rmfile)
+     else
+      let netrw_rm_cmd= s:MakeSshCmd(g:netrw_rm_cmd)
+"      call Decho("attempt to remove file: system(".netrw_rm_cmd.")")
+      let ret= s:System("system",netrw_rm_cmd)
+"      call Decho("returned=".ret." errcode=".v:shell_error)
+     endif
+    elseif ok =~ 'q\%[uit]'
+     break
+    endif
+
+   else
+    " attempt to remove directory
+"    call Decho("attempt to remove directory")
+    if !all
+     call inputsave()
+     let ok= input("Confirm deletion of directory<".rmfile."> ","[{y(es)},n(o),a(ll),q(uit)] ")
+     call inputrestore()
+     if ok == ""
+      let ok="no"
+     endif
+     let ok= substitute(ok,'\[{y(es)},n(o),a(ll),q(uit)]\s*','','e')
+     if ok =~ 'a\%[ll]'
+      let all= 1
+     endif
+    endif
+
+    if all || ok =~ 'y\%[es]' || ok == ""
+     if exists("w:netrw_method") && (w:netrw_method == 2 || w:netrw_method == 3)
+      call s:NetBrowseFtpCmd(a:path,"rmdir ".rmfile)
+     else
+      let rmfile          = substitute(a:path.rmfile,'/$','','')
+      let netrw_rmdir_cmd = s:MakeSshCmd(g:netrw_rmdir_cmd).' '.rmfile
+"      call Decho("attempt to remove dir: system(".netrw_rmdir_cmd.")")
+      let ret= s:System("system",netrw_rmdir_cmd)
+"      call Decho("returned=".ret." errcode=".v:shell_error)
+
+      if v:shell_error != 0
+"       call Decho("v:shell_error not 0")
+       let netrw_rmf_cmd= s:MakeSshCmd(g:netrw_rmf_cmd).' '.substitute(rmfile,'[\/]$','','e')
+"       call Decho("2nd attempt to remove dir: system(".netrw_rmf_cmd.")")
+       let ret= s:System("system",netrw_rmf_cmd)
+"       call Decho("returned=".ret." errcode=".v:shell_error)
+
+       if v:shell_error != 0 && !exists("g:netrw_quiet")
+       	call netrw#ErrorMsg(s:ERROR,"unable to remove directory<".rmfile."> -- is it empty?",22)
+       endif
+      endif
+     endif
+
+    elseif ok =~ 'q\%[uit]'
+     break
+    endif
+   endif
+
+   let ctr= ctr + 1
+  endwhile
+
+  " refresh the (remote) directory listing
+"  call Decho("refresh remote directory listing")
+  call netrw#NetSavePosn()
+  call s:NetRefresh(0,s:NetBrowseChgDir(0,'./'))
+
+"  call Dret("NetBrowseRm")
+endfun
+
+" ---------------------------------------------------------------------
+" NetBrowseRename: rename a remote file or directory {{{2
+fun! s:NetBrowseRename(usrhost,path) range
+"  call Dfunc("NetBrowseRename(usrhost<".a:usrhost."> path<".a:path.">)")
+
+  " preparation for removing multiple files/directories
+  let ctr        = a:firstline
+  let rename_cmd = s:MakeSshCmd(g:netrw_rename_cmd)
+
+  " attempt to rename files/directories
+  while ctr <= a:lastline
+   exe "keepjumps ".ctr
+
+   norm! 0
+   let oldname= s:NetGetWord()
+"   call Decho("oldname<".oldname.">")
+
+   call inputsave()
+   let newname= input("Moving ".oldname." to : ",oldname)
+   call inputrestore()
+
+   if exists("w:netrw_method") && (w:netrw_method == 2 || w:netrw_method == 3)
+    call s:NetBrowseFtpCmd(a:path,"rename ".oldname." ".newname)
+   else
+    let oldname= a:path.oldname
+    let newname= a:path.newname
+"    call Decho("system(rename_cmd".' "'.escape(oldname," ").'" "'.escape(newname,s:netrw_cd_escape).'"')
+    let ret= s:System("system",rename_cmd.' "'.escape(oldname,s:netrw_cd_escape).'" "'.escape(newname,s:netrw_cd_escape).'"')
+   endif
+
+   let ctr= ctr + 1
+  endwhile
+
+  " refresh the directory
+  let curline= line(".")
+  call s:NetBrowse(0,s:NetBrowseChgDir(0,'./'))
+  exe "keepjumps ".curline
+"  call Dret("NetBrowseRename")
+endfun
+
+" ---------------------------------------------------------------------
+" NetRefresh: {{{2
+fun! s:NetRefresh(islocal,dirname)
+"  call Dfunc("NetRefresh(islocal<".a:islocal.">,dirname=".a:dirname.") hide=".g:netrw_hide." sortdir=".g:netrw_sort_direction)
+  " at the current time (Mar 19, 2007) all calls to NetRefresh() call NetBrowseChgDir() first.
+  " NetBrowseChgDir() may clear the display; hence a NetSavePosn() may not work if its placed here.
+  " Also, NetBrowseChgDir() now does a NetSavePosn() itself.
+  setlocal ma noro
+"  call Decho("clear buffer<".expand("%")."> with :%d")
+  %d
+  if a:islocal
+   call netrw#LocalBrowseCheck(a:dirname)
+  else
+   call s:NetBrowse(a:islocal,a:dirname)
+  endif
+  call netrw#NetRestorePosn()
+  redraw!
+"  call Dret("NetRefresh")
+endfun
+
+" ---------------------------------------------------------------------
+" NetSplit: mode {{{2
+"           =0 : net   and o
+"           =1 : net   and t
+"           =2 : net   and v
+"           =3 : local and o
+"           =4 : local and t
+"           =5 : local and v
+fun! s:NetSplit(mode)
+"  call Dfunc("NetSplit(mode=".a:mode.") alto=".g:netrw_alto." altv=".g:netrw_altv)
+
+  call s:SaveWinVars()
+
+  if a:mode == 0
+   " remote and o
+   exe (g:netrw_alto? "bel " : "abo ").g:netrw_winsize."wincmd s"
+   let s:didsplit= 1
+   call s:RestoreWinVars()
+   call s:NetBrowse(0,s:NetBrowseChgDir(0,s:NetGetWord()))
+   unlet s:didsplit
+
+  elseif a:mode == 1
+   " remote and t
+   let cursorword  = s:NetGetWord()
+   tabnew
+   let s:didsplit= 1
+   call s:RestoreWinVars()
+   call s:NetBrowse(0,s:NetBrowseChgDir(0,cursorword))
+   unlet s:didsplit
+
+  elseif a:mode == 2
+   " remote and v
+   exe (g:netrw_altv? "rightb " : "lefta ").g:netrw_winsize."wincmd v"
+   let s:didsplit= 1
+   call s:RestoreWinVars()
+   call s:NetBrowse(0,s:NetBrowseChgDir(0,s:NetGetWord()))
+   unlet s:didsplit
+
+  elseif a:mode == 3
+   " local and o
+   exe (g:netrw_alto? "bel " : "abo ").g:netrw_winsize."wincmd s"
+   let s:didsplit= 1
+   call s:RestoreWinVars()
+   call netrw#LocalBrowseCheck(s:NetBrowseChgDir(1,s:NetGetWord()))
+   unlet s:didsplit
+
+  elseif a:mode == 4
+   " local and t
+   let netrw_curdir= b:netrw_curdir
+   let cursorword  = s:NetGetWord()
+   tabnew
+   let b:netrw_curdir= netrw_curdir
+   let s:didsplit= 1
+   call s:RestoreWinVars()
+   call netrw#LocalBrowseCheck(s:NetBrowseChgDir(1,cursorword))
+   unlet s:didsplit
+
+  elseif a:mode == 5
+   " local and v
+   exe (g:netrw_altv? "rightb " : "lefta ").g:netrw_winsize."wincmd v"
+   let s:didsplit= 1
+   call s:RestoreWinVars()
+   call netrw#LocalBrowseCheck(s:NetBrowseChgDir(1,s:NetGetWord()))
+   unlet s:didsplit
+
+  else
+   call netrw#ErrorMsg(s:ERROR,"(NetSplit) unsupported mode=".a:mode,45)
+  endif
+
+"  call Dret("NetSplit")
+endfun
+
+" ---------------------------------------------------------------------
+" NetBrowseX:  allows users to write custom functions to operate on {{{2
+"              files given their extension.  Passes 0=local, 1=remote
+fun! netrw#NetBrowseX(fname,remote)
+"  call Dfunc("NetBrowseX(fname<".a:fname."> remote=".a:remote.")")
+
+  " set up the filename
+  " (lower case the extension, make a local copy of a remote file)
+  let exten= substitute(a:fname,'.*\.\(.\{-}\)','\1','e')
+  if has("win32") || has("win95") || has("win64") || has("win16")
+   let exten= substitute(exten,'^.*$','\L&\E','')
+  endif
+  let fname= escape(a:fname,"%#")
+"  call Decho("fname<".fname."> after escape()")
+
+  " seems kde systems often have gnome-open due to dependencies, even though
+  " gnome-open's subsidiary display tools are largely absent.  Kde systems
+  " usually have "kdeinit" running, though...  (tnx Mikolaj Machowski)
+  if !exists("s:haskdeinit")
+   if has("unix")
+    let s:haskdeinit= s:System("system",'ps -e') =~ 'kdeinit'
+    if v:shell_error
+     let s:haskdeinit = 0
+    endif
+   else
+    let s:haskdeinit= 0
+   endif
+"   call Decho("setting s:haskdeinit=".s:haskdeinit)
+  endif
+
+  if a:remote == 1
+   " create a local copy
+   let fname= fnamemodify(tempname(),":t:r").".".exten
+"   call Decho("a:remote=".a:remote.": create a local copy of <".a:fname."> as <".fname.">")
+   exe "silent keepjumps bot 1new ".a:fname
+   setlocal bh=delete
+"   call Decho("exe w! ".fname)
+   exe "w! ".fname
+   q
+  endif
+"  call Decho("exten<".exten."> "."netrwFileHandlers#NFH_".exten."():exists=".exists("*netrwFileHandlers#NFH_".exten))
+
+  " set up redirection
+  if &srr =~ "%s"
+   let redir= substitute(&srr,"%s","/dev/null","")
+  else
+   let redir= &srr . "/dev/null"
+  endif
+"  call Decho("redir{".redir."} srr{".&srr."}")
+
+  " execute the file handler
+  if exists("g:netrw_browsex_viewer") && g:netrw_browsex_viewer == '-'
+"  call Decho("g:netrw_browsex_viewer<".g:netrw_browsex_viewer.">")
+   let ret= netrwFileHandlers#Invoke(exten,fname)
+
+  elseif exists("g:netrw_browsex_viewer") && executable(g:netrw_browsex_viewer)
+"   call Decho("g:netrw_browsex_viewer<".g:netrw_browsex_viewer.">")
+"   call Decho("exe silent !".g:netrw_browsex_viewer." '".escape(fname,'%#')."' ".redir)
+   exe "silent !".g:netrw_browsex_viewer." '".escape(fname,'%#')."'".redir
+   let ret= v:shell_error
+
+  elseif has("win32") || has("win64")
+"   call Decho('exe silent !start rundll32 url.dll,FileProtocolHandler "'.escape(fname, '%#').'"')
+   exe 'silent !start rundll32 url.dll,FileProtocolHandler "'.escape(fname, '%#').'"'
+   call inputsave()|call input("Press <cr> to continue")|call inputrestore()
+   let ret= v:shell_error
+
+  elseif has("unix") && executable("gnome-open") && !s:haskdeinit
+"   call Decho("exe silent !gnome-open '".escape(fname,'%#')."' ".redir)
+   exe "silent !gnome-open '".escape(fname,'%#')."'".redir
+   let ret= v:shell_error
+
+  elseif has("unix") && executable("kfmclient") && s:haskdeinit
+"   call Decho("exe silent !kfmclient exec '".escape(fname,'%#')."' ".redir)
+   exe "silent !kfmclient exec '".escape(fname,'%#')."' ".redir
+   let ret= v:shell_error
+
+  else
+   " netrwFileHandlers#Invoke() always returns 0
+   let ret= netrwFileHandlers#Invoke(exten,fname)
+  endif
+
+  " if unsuccessful, attempt netrwFileHandlers#Invoke()
+  if ret
+   let ret= netrwFileHandlers#Invoke(exten,fname)
+  endif
+
+  redraw!
+
+  " cleanup: remove temporary file,
+  "          delete current buffer if success with handler,
+  "          return to prior buffer (directory listing)
+  if a:remote == 1 && fname != a:fname
+"   call Decho("deleting temporary file<".fname.">")
+   call s:System("delete",fname)
+  endif
+
+  if a:remote == 1
+   setlocal bh=delete bt=nofile
+   if g:netrw_use_noswf
+    setlocal noswf
+   endif
+   exe "norm! \<c-o>"
+   redraw!
+  endif
+
+"  call Dret("NetBrowseX")
+endfun
+
+" ---------------------------------------------------------------------
+" NetBrowseFtpCmd: unfortunately, not all ftp servers honor options for ls {{{2
+"  This function assumes that a long listing will be received.  Size, time,
+"  and reverse sorts will be requested of the server but not otherwise
+"  enforced here.
+fun! s:NetBrowseFtpCmd(path,listcmd)
+"  call Dfunc("NetBrowseFtpCmd(path<".a:path."> listcmd<".a:listcmd.">) netrw_method=".w:netrw_method)
+"  call Decho("line($)=".line("$")." bannercnt=".w:netrw_bannercnt)
+
+  " because WinXX ftp uses unix style input
+  let ffkeep= &ff
+  setlocal ma ff=unix noro
+
+  " clear off any older non-banner lines
+  " note that w:netrw_bannercnt indexes the line after the banner
+"  call Decho('exe silent! keepjumps '.w:netrw_bannercnt.",$d  (clear off old non-banner lines)")
+  exe "silent! keepjumps ".w:netrw_bannercnt.",$d"
+
+  ".........................................
+  if w:netrw_method == 2 || w:netrw_method == 5 
+   " ftp + <.netrc>:  Method #2
+   if a:path != ""
+    put ='cd \"'.a:path.'\"'
+   endif
+   if exists("g:netrw_ftpextracmd")
+    exe "put ='".g:netrw_ftpextracmd."'"
+"    call Decho("filter input: ".getline("."))
+   endif
+   exe "put ='".a:listcmd."'"
+"   exe w:netrw_bannercnt.',$g/^./call Decho("ftp#".line(".").": ".getline("."))'
+   if exists("g:netrw_port") && g:netrw_port != ""
+"    call Decho("exe ".g:netrw_silentxfer.w:netrw_bannercnt.",$!".g:netrw_ftp_cmd." -i ".g:netrw_machine." ".g:netrw_port)
+    exe g:netrw_silentxfer.w:netrw_bannercnt.",$!".g:netrw_ftp_cmd." -i ".g:netrw_machine." ".g:netrw_port
+   else
+"    call Decho("exe ".g:netrw_silentxfer.w:netrw_bannercnt.",$!".g:netrw_ftp_cmd." -i ".g:netrw_machine)
+    exe g:netrw_silentxfer.w:netrw_bannercnt.",$!".g:netrw_ftp_cmd." -i ".g:netrw_machine
+   endif
+
+   ".........................................
+  elseif w:netrw_method == 3
+   " ftp + machine,id,passwd,filename:  Method #3
+    setlocal ff=unix
+    if exists("g:netrw_port") && g:netrw_port != ""
+     put ='open '.g:netrw_machine.' '.g:netrw_port
+    else
+     put ='open '.g:netrw_machine
+    endif
+
+    if exists("g:netrw_ftp") && g:netrw_ftp == 1
+     put =g:netrw_uid
+     put ='\"'.g:netrw_passwd.'\"'
+    else
+     put ='user \"'.g:netrw_uid.'\" \"'.g:netrw_passwd.'\"'
+    endif
+
+   if a:path != ""
+    put ='cd \"'.a:path.'\"'
+   endif
+   if exists("g:netrw_ftpextracmd")
+    exe "put ='".g:netrw_ftpextracmd."'"
+"    call Decho("filter input: ".getline("."))
+   endif
+   exe "put ='".a:listcmd."'"
+
+    " perform ftp:
+    " -i       : turns off interactive prompting from ftp
+    " -n  unix : DON'T use <.netrc>, even though it exists
+    " -n  win32: quit being obnoxious about password
+"    exe w:netrw_bannercnt.',$g/^./call Decho("ftp#".line(".").": ".getline("."))'
+"    call Decho("exe ".g:netrw_silentxfer.w:netrw_bannercnt.",$!".g:netrw_ftp_cmd." -i -n")
+    exe g:netrw_silentxfer.w:netrw_bannercnt.",$!".g:netrw_ftp_cmd." -i -n"
+
+   ".........................................
+  else
+   call netrw#ErrorMsg(s:WARNING,"unable to comply with your request<" . choice . ">",23)
+  endif
+
+  " cleanup for Windows
+  if has("win32") || has("win95") || has("win64") || has("win16")
+   silent! keepjumps %s/\r$//e
+  endif
+  if a:listcmd == "dir"
+   " infer directory/link based on the file permission string
+   silent! keepjumps g/d\%([-r][-w][-x]\)\{3}/s@$@/@
+   silent! keepjumps g/l\%([-r][-w][-x]\)\{3}/s/$/@/
+   if w:netrw_liststyle == s:THINLIST || w:netrw_liststyle == s:WIDELIST || w:netrw_liststyle == s:TREELIST
+    exe "silent! keepjumps ".w:netrw_bannercnt.',$s/^\%(\S\+\s\+\)\{8}//e'
+   endif
+  endif
+
+  " ftp's listing doesn't seem to include ./ or ../
+  if !search('^\.\/$\|\s\.\/$','wn')
+   exe 'keepjumps '.w:netrw_bannercnt
+   put ='./'
+  endif
+  if !search('^\.\.\/$\|\s\.\.\/$','wn')
+   exe 'keepjumps '.w:netrw_bannercnt
+   put ='../'
+  endif
+
+  " restore settings
+  let &ff= ffkeep
+"  call Dret("NetBrowseFtpCmd")
+endfun
+
+" ---------------------------------------------------------------------
+" NetListHide: uses [range]g~...~d to delete files that match comma {{{2
+" separated patterns given in g:netrw_list_hide
+fun! s:NetListHide()
+"  call Dfunc("NetListHide() hide=".g:netrw_hide." listhide<".g:netrw_list_hide.">")
+
+  " find a character not in the "hide" string to use as a separator for :g and :v commands
+  " How-it-works: take the hiding command, convert it into a range.  Duplicate
+  " characters don't matter.  Remove all such characters from the '/~...90'
+  " string.  Use the first character left as a separator character.
+  let listhide= g:netrw_list_hide
+  let sep     = strpart(substitute('/~@#$%^&*{};:,<.>?|1234567890','['.escape(listhide,'-]^\').']','','ge'),1,1)
+"  call Decho("sep=".sep)
+
+  while listhide != ""
+   if listhide =~ ','
+    let hide     = substitute(listhide,',.*$','','e')
+    let listhide = substitute(listhide,'^.\{-},\(.*\)$','\1','e')
+   else
+    let hide     = listhide
+    let listhide= ""
+   endif
+
+   " Prune the list by hiding any files which match
+   if g:netrw_hide == 1
+"    call Decho("hiding<".hide."> listhide<".listhide.">")
+    exe 'silent keepjumps '.w:netrw_bannercnt.',$g'.sep.hide.sep.'d'
+   elseif g:netrw_hide == 2
+"    call Decho("showing<".hide."> listhide<".listhide.">")
+    exe 'silent keepjumps '.w:netrw_bannercnt.',$g'.sep.hide.sep.'s@^@ /-KEEP-/ @'
+   endif
+  endwhile
+  if g:netrw_hide == 2
+   exe 'silent keepjumps '.w:netrw_bannercnt.',$v@^ /-KEEP-/ @d'
+   exe 'silent keepjumps '.w:netrw_bannercnt.',$s@^\%( /-KEEP-/ \)\+@@e'
+  endif
+
+"  call Dret("NetListHide")
+endfun
+
+" ---------------------------------------------------------------------
+" NetHideEdit: allows user to edit the file/directory hiding list
+fun! s:NetHideEdit(islocal)
+"  call Dfunc("NetHideEdit(islocal=".a:islocal.")")
+
+  " save current cursor position
+  let s:nhe_curpos= getpos(".")
+
+  " get new hiding list from user
+  call inputsave()
+  let newhide= input("Edit Hiding List: ",g:netrw_list_hide)
+  call inputrestore()
+  let g:netrw_list_hide= newhide
+"  call Decho("new g:netrw_list_hide<".g:netrw_list_hide.">")
+
+  " refresh the listing
+  silent call s:NetRefresh(a:islocal,s:NetBrowseChgDir(a:islocal,"./"))
+
+  " restore cursor position
+  call setpos('.',s:nhe_curpos)
+  unlet s:nhe_curpos
+
+"  call Dret("NetHideEdit")
+endfun
+
+" ---------------------------------------------------------------------
+" NetSortSequence: allows user to edit the sorting sequence
+fun! s:NetSortSequence(islocal)
+"  call Dfunc("NetSortSequence(islocal=".a:islocal.")")
+
+  call inputsave()
+  let newsortseq= input("Edit Sorting Sequence: ",g:netrw_sort_sequence)
+  call inputrestore()
+
+  " refresh the listing
+  let g:netrw_sort_sequence= newsortseq
+  call netrw#NetSavePosn()
+  call s:NetRefresh(a:islocal,s:NetBrowseChgDir(a:islocal,'./'))
+
+"  call Dret("NetSortSequence")
+endfun
+
+" ---------------------------------------------------------------------
+"  NetListStyle: {{{2
+"  islocal=0: remote browsing
+"         =1: local browsing
+fun! s:NetListStyle(islocal)
+"  call Dfunc("NetListStyle(islocal=".a:islocal.") w:netrw_liststyle=".w:netrw_liststyle)
+  let fname             = s:NetGetWord()
+  if !exists("w:netrw_liststyle")|let w:netrw_liststyle= g:netrw_liststyle|endif
+  let w:netrw_liststyle = (w:netrw_liststyle + 1) % s:MAXLIST
+"  call Decho("fname<".fname.">")
+"  call Decho("chgd w:netrw_liststyle to ".w:netrw_liststyle)
+"  call Decho("b:netrw_curdir<".(exists("b:netrw_curdir")? b:netrw_curdir : "doesn't exist").">")
+
+  if w:netrw_liststyle == s:THINLIST
+   " use one column listing
+"   call Decho("use one column list")
+   let g:netrw_list_cmd = substitute(g:netrw_list_cmd,' -l','','ge')
+
+  elseif w:netrw_liststyle == s:LONGLIST
+   " use long list
+"   call Decho("use long list")
+   let g:netrw_list_cmd = g:netrw_list_cmd." -l"
+
+  elseif w:netrw_liststyle == s:WIDELIST
+   " give wide list
+"   call Decho("use wide list")
+   let g:netrw_list_cmd = substitute(g:netrw_list_cmd,' -l','','ge')
+
+  elseif w:netrw_liststyle == s:TREELIST
+"   call Decho("use tree list")
+   let g:netrw_list_cmd = substitute(g:netrw_list_cmd,' -l','','ge')
+
+  else
+   call netrw#ErrorMsg(s:WARNING,"bad value for g:netrw_liststyle (=".w:netrw_liststyle.")",46)
+   let g:netrw_liststyle = s:THINLIST
+   let w:netrw_liststyle = g:netrw_liststyle
+   let g:netrw_list_cmd  = substitute(g:netrw_list_cmd,' -l','','ge')
+  endif
+  setlocal ma noro
+
+  " clear buffer - this will cause NetBrowse/LocalBrowseCheck to do a refresh
+"  call Decho("clear buffer<".expand("%")."> with :%d")
+  %d
+
+  " refresh the listing
+  call netrw#NetSavePosn()
+  call s:NetRefresh(a:islocal,s:NetBrowseChgDir(a:islocal,'./'))
+
+  " keep cursor on the filename
+  silent keepjumps $
+  let result= search('\%(^\%(|\+\s\)\=\|\s\{2,}\)\zs'.escape(fname,'.\[]*$^').'\%(\s\{2,}\|$\)','bc')
+"  call Decho("search result=".result." w:netrw_bannercnt=".(exists("w:netrw_bannercnt")? w:netrw_bannercnt : 'N/A'))
+  if result <= 0 && exists("w:netrw_bannercnt")
+   exe w:netrw_bannercnt
+  endif
+
+"  call Dret("NetListStyle".(exists("w:netrw_liststyle")? ' : w:netrw_liststyle='.w:netrw_liststyle : ""))
+endfun
+
+" ---------------------------------------------------------------------
+" NetWideListing: {{{2
+fun! s:NetWideListing()
+
+  if w:netrw_liststyle == s:WIDELIST
+"   call Dfunc("NetWideListing() w:netrw_liststyle=".w:netrw_liststyle.' fo='.&fo.' l:fo='.&l:fo)
+   " look for longest filename (cpf=characters per filename)
+   " cpf: characters per file
+   " fpl: files per line
+   " fpc: files per column
+   setlocal ma noro
+   let b:netrw_cpf= 0
+   if line("$") >= w:netrw_bannercnt
+    exe 'silent keepjumps '.w:netrw_bannercnt.',$g/^./if virtcol("$") > b:netrw_cpf|let b:netrw_cpf= virtcol("$")|endif'
+   else
+"    call Dret("NetWideListing")
+    return
+   endif
+"   call Decho("max file strlen+1=".b:netrw_cpf)
+   let b:netrw_cpf= b:netrw_cpf + 1
+
+   " determine qty files per line (fpl)
+   let w:netrw_fpl= winwidth(0)/b:netrw_cpf
+   if w:netrw_fpl <= 0
+    let w:netrw_fpl= 1
+   endif
+"   call Decho("fpl= ".winwidth(0)."/[b:netrw_cpf=".b:netrw_cpf.']='.w:netrw_fpl)
+
+   " make wide display
+   exe 'silent keepjumps '.w:netrw_bannercnt.',$s/^.*$/\=escape(printf("%-'.b:netrw_cpf.'s",submatch(0)),"\\")/'
+   let fpc         = (line("$") - w:netrw_bannercnt + w:netrw_fpl)/w:netrw_fpl
+   let newcolstart = w:netrw_bannercnt + fpc
+   let newcolend   = newcolstart + fpc - 1
+"   call Decho("bannercnt=".w:netrw_bannercnt." fpl=".w:netrw_fpl." fpc=".fpc." newcol[".newcolstart.",".newcolend."]")
+   silent! let keepregstar = @*
+   while line("$") >= newcolstart
+    if newcolend > line("$") | let newcolend= line("$") | endif
+    let newcolqty= newcolend - newcolstart
+    exe newcolstart
+    if newcolqty == 0
+     exe "silent keepjumps norm! 0\<c-v>$hx".w:netrw_bannercnt."G$p"
+    else
+     exe "silent keepjumps norm! 0\<c-v>".newcolqty.'j$hx'.w:netrw_bannercnt.'G$p'
+    endif
+    exe "silent keepjumps ".newcolstart.','.newcolend.'d'
+    exe 'silent keepjumps '.w:netrw_bannercnt
+   endwhile
+   silent! let @*= keepregstar
+   exe "silent keepjumps ".w:netrw_bannercnt.',$s/\s\+$//e'
+   setlocal noma nomod ro
+"   call Dret("NetWideListing")
+  endif
+
+endfun
+
+" ---------------------------------------------------------------------
+" NetTreeDir: determine tree directory given current cursor position {{{2
+" (full path directory with trailing slash returned)
+fun! s:NetTreeDir()
+"  call Dfunc("NetTreeDir() curline#".line(".")."<".getline(".")."> b:netrw_curdir<".b:netrw_curdir."> tab#".tabpagenr()." win#".winnr()." buf#".bufnr("%")."<".bufname("%").">")
+
+  let treedir= b:netrw_curdir
+"  call Decho("set initial treedir<".treedir.">")
+  let s:treecurpos= getpos(".")
+
+  if w:netrw_liststyle == s:TREELIST
+"   call Decho("w:netrrw_liststyle is TREELIST:")
+"   call Decho("line#".line(".")." getline(.)<".getline('.')."> treecurpos<".string(s:treecurpos).">")
+   if getline('.') =~ '/$'
+    let treedir= substitute(getline('.'),'^\%(| \)*\([^|].\{-}\)$','\1','e')
+   else
+    let treedir= ""
+   endif
+
+"   call Decho("treedir<".treedir.">")
+
+   " detect user attempting to close treeroot
+   if getline('.') !~ '|' && getline('.') != '..'
+"    call Decho("user attempted to close treeroot")
+    " now force a refresh
+"    call Decho("clear buffer<".expand("%")."> with :%d")
+    keepjumps %d
+"    call Dret("NetTreeDir <".treedir."> : (side effect) s:treecurpos<".string(s:treecurpos).">")
+    return b:netrw_curdir
+   endif
+
+   " elide all non-depth information
+   let depth = substitute(getline('.'),'^\(\%(| \)*\)[^|].\{-}$','\1','e')
+"   call Decho("depth<".depth."> 1st subst")
+
+   " elide first depth
+   let depth = substitute(depth,'^| ','','')
+"   call Decho("depth<".depth."> 2nd subst")
+
+   " construct treedir by searching backwards at correct depth
+"   call Decho("constructing treedir<".treedir."> depth<".depth.">")
+   while depth != "" && search('^'.depth.'[^|].\{-}/$','bW')
+    let dirname= substitute(getline("."),'^\(| \)*','','e')
+    let treedir= dirname.treedir
+    let depth  = substitute(depth,'^| ','','')
+"    call Decho("constructing treedir<".treedir.">: dirname<".dirname."> while depth<".depth.">")
+   endwhile
+   if w:netrw_treetop =~ '/$'
+    let treedir= w:netrw_treetop.treedir
+   else
+    let treedir= w:netrw_treetop.'/'.treedir
+   endif
+"   call Decho("bufnr(.)=".bufnr(".")." line($)=".line("$")." line(.)=".line("."))
+  endif
+  let treedir= substitute(treedir,'//$','/','')
+
+"  " now force a refresh
+"  call Decho("clear buffer<".expand("%")."> with :%d")
+"  setlocal ma noro
+"  keepjumps %d
+
+"  call Dret("NetTreeDir <".treedir."> : (side effect) s:treecurpos<".string(s:treecurpos).">")
+  return treedir
+endfun
+
+" ---------------------------------------------------------------------
+" NetTreeDisplay: recursive tree display {{{2
+fun! s:NetTreeDisplay(dir,depth)
+"  call Dfunc("NetTreeDisplay(dir<".a:dir."> depth<".a:depth.">)")
+
+  " insure that there are no folds
+  setlocal nofen
+
+  " install ../ and shortdir
+  if a:depth == ""
+   call setline(line("$")+1,'../')
+"   call Decho("setline#".line("$")." ../ (depth is zero)")
+  endif
+  if a:dir =~ '^\a\+://'
+   if a:dir == w:netrw_treetop
+    let shortdir= a:dir
+   else
+    let shortdir= substitute(a:dir,'^.*/\([^/]\+\)/$','\1/','e')
+   endif
+   call setline(line("$")+1,a:depth.shortdir)
+  else
+   let shortdir= substitute(a:dir,'^.*/','','e')
+   call setline(line("$")+1,a:depth.shortdir.'/')
+  endif
+"  call Decho("setline#".line("$")." shortdir<".a:depth.shortdir.">")
+
+  " append a / to dir if its missing one
+  let dir= a:dir
+  if dir !~ '/$'
+   let dir= dir.'/'
+  endif
+
+  " display subtrees (if any)
+  let depth= "| ".a:depth
+"  call Decho("display subtrees with depth<".depth."> and current leaves")
+  for entry in w:netrw_treedict[a:dir]
+   let direntry= substitute(dir.entry,'/$','','e')
+"   call Decho("dir<".dir."> entry<".entry."> direntry<".direntry.">")
+   if entry =~ '/$' && has_key(w:netrw_treedict,direntry)
+"    call Decho("<".direntry."> is a key in treedict - display subtree for it")
+    call s:NetTreeDisplay(direntry,depth)
+   elseif entry =~ '/$' && has_key(w:netrw_treedict,direntry.'/')
+"    call Decho("<".direntry."/> is a key in treedict - display subtree for it")
+    call s:NetTreeDisplay(direntry.'/',depth)
+   else
+"    call Decho("<".entry."> is not a key in treedict (no subtree)")
+    call setline(line("$")+1,depth.entry)
+   endif
+  endfor
+"  call Dret("NetTreeDisplay")
+endfun
+
+" ---------------------------------------------------------------------
+" NetTreeListing: displays tree listing from treetop on down, using NetTreeDisplay() {{{2
+fun! s:NetTreeListing(dirname)
+  if w:netrw_liststyle == s:TREELIST
+"   call Dfunc("NetTreeListing() bufname<".expand("%").">")
+"   call Decho("curdir<".a:dirname.">")
+
+   " update the treetop
+"   call Decho("update the treetop")
+   if !exists("w:netrw_treetop")
+    let w:netrw_treetop= a:dirname
+"    call Decho("w:netrw_treetop<".w:netrw_treetop."> (reusing)")
+   elseif (w:netrw_treetop =~ ('^'.a:dirname) && strlen(a:dirname) < strlen(w:netrw_treetop)) || a:dirname !~ ('^'.w:netrw_treetop)
+    let w:netrw_treetop= a:dirname
+"    call Decho("w:netrw_treetop<".w:netrw_treetop."> (went up)")
+   endif
+
+   " insure that we have at least an empty treedict
+   if !exists("w:netrw_treedict")
+    let w:netrw_treedict= {}
+   endif
+
+   " update the directory listing for the current directory
+"   call Decho("updating dictionary with ".a:dirname.":[..directory listing..]")
+"   call Decho("bannercnt=".w:netrw_bannercnt." line($)=".line("$"))
+   exe "silent! keepjumps ".w:netrw_bannercnt.',$g@^\.\.\=/$@d'
+   let w:netrw_treedict[a:dirname]= getline(w:netrw_bannercnt,line("$"))
+"   call Decho("treedict=".string(w:netrw_treedict))
+   exe "silent! keepjumps ".w:netrw_bannercnt.",$d"
+
+   " if past banner, record word
+   if exists("w:netrw_bannercnt") && line(".") > w:netrw_bannercnt
+    let fname= expand("<cword>")
+   else
+    let fname= ""
+   endif
+
+   " display from treetop on down
+   call s:NetTreeDisplay(w:netrw_treetop,"")
+
+   " place cursor
+   if !exists("s:nbcd_curpos")
+    if fname != ""
+"     call Decho("(NetTreeListing) place cursor <".fname.">")
+     call search('\<'.fname.'\>','cw')
+    elseif exists("w:netrw_bannercnt")
+     exe (w:netrw_bannercnt+1)
+"     call Decho("(NetTreeListing) place cursor line#".(w:netrw_bannercnt+1))
+    endif
+   endif
+
+"   call Dret("NetTreeListing : bufname<".expand("%").">")
+  endif
+endfun
+
+" ---------------------------------------------------------------------
+" NetSaveWordPosn: used by the "s" command in both remote and local {{{2
+" browsing.  Along with NetRestoreWordPosn(), it keeps the cursor on
+" the same word even though the sorting has changed its order of appearance.
+fun! s:NetSaveWordPosn()
+"  call Dfunc("NetSaveWordPosn()")
+  let s:netrw_saveword= '^'.escape(getline("."),s:netrw_cd_escape).'$'
+"  call Dret("NetSaveWordPosn : saveword<".s:netrw_saveword.">")
+endfun
+
+" ---------------------------------------------------------------------
+" NetRestoreWordPosn: used by the "s" command; see NetSaveWordPosn() above {{{2
+fun! s:NetRestoreWordPosn()
+"  call Dfunc("NetRestoreWordPosn()")
+  silent! call search(s:netrw_saveword,'w')
+"  call Dret("NetRestoreWordPosn")
+endfun
+
+" ---------------------------------------------------------------------
+" NetMakeDir: this function makes a directory (both local and remote) {{{2
+fun! s:NetMakeDir(usrhost)
+"  call Dfunc("NetMakeDir(usrhost<".a:usrhost.">)")
+
+  " get name of new directory from user.  A bare <CR> will skip.
+  " if its currently a directory, also request will be skipped, but with
+  " a message.
+  call inputsave()
+  let newdirname= input("Please give directory name: ")
+  call inputrestore()
+"  call Decho("newdirname<".newdirname.">")
+
+  if newdirname == ""
+"   call Dret("NetMakeDir : user aborted with bare <cr>")
+   return
+  endif
+
+  if a:usrhost == ""
+
+   " Local mkdir:
+   " sanity checks
+   let fullnewdir= b:netrw_curdir.'/'.newdirname
+"   call Decho("fullnewdir<".fullnewdir.">")
+   if isdirectory(fullnewdir)
+    if !exists("g:netrw_quiet")
+     call netrw#ErrorMsg(s:WARNING,"<".newdirname."> is already a directory!",24)
+    endif
+"    call Dret("NetMakeDir : directory<".newdirname."> exists previously")
+    return
+   endif
+   if s:FileReadable(fullnewdir)
+    if !exists("g:netrw_quiet")
+     call netrw#ErrorMsg(s:WARNING,"<".newdirname."> is already a file!",25)
+    endif
+"    call Dret("NetMakeDir : file<".newdirname."> exists previously")
+    return
+   endif
+
+   " requested new local directory is neither a pre-existing file or
+   " directory, so make it!
+   if exists("*mkdir")
+    call mkdir(fullnewdir,"p")
+   else
+    let netrw_origdir= s:NetGetcwd(1)
+    exe 'keepjumps cd '.b:netrw_curdir
+"    call Decho("netrw_origdir<".netrw_origdir.">: cd b:netrw_curdir<".b:netrw_curdir.">")
+"    call Decho("exe silent! !".g:netrw_local_mkdir.' '.g:netrw_shq.newdirname.g:netrw_shq)
+    exe "silent! !".g:netrw_local_mkdir.' '.g:netrw_shq.newdirname.g:netrw_shq
+    if !g:netrw_keepdir | exe 'keepjumps cd '.netrw_origdir | endif
+    if !g:netrw_keepdir
+     exe 'keepjumps cd '.netrw_origdir
+"     call Decho("netrw_keepdir=".g:netrw_keepdir.": cd ".netrw_origdir)
+    endif
+   endif
+
+   if v:shell_error == 0
+    " refresh listing
+"    call Decho("refresh listing")
+    call netrw#NetSavePosn()
+    call s:NetRefresh(1,s:NetBrowseChgDir(1,'./'))
+   elseif !exists("g:netrw_quiet")
+    call netrw#ErrorMsg(s:ERROR,"unable to make directory<".newdirname.">",26)
+   endif
+   redraw!
+
+  else
+   " Remote mkdir:
+   let mkdircmd  = s:MakeSshCmd(g:netrw_mkdir_cmd)
+   let newdirname= substitute(b:netrw_curdir,'^\%(.\{-}/\)\{3}\(.*\)$','\1','').newdirname
+"   call Decho("exe silent! !".mkdircmd." ".g:netrw_shq.newdirname.g:netrw_shq)
+   exe "silent! !".mkdircmd." ".g:netrw_shq.newdirname.g:netrw_shq
+   if v:shell_error == 0
+    " refresh listing
+    call netrw#NetSavePosn()
+    call s:NetRefresh(0,s:NetBrowseChgDir(0,'./'))
+   elseif !exists("g:netrw_quiet")
+    call netrw#ErrorMsg(s:ERROR,"unable to make directory<".newdirname.">",27)
+   endif
+   redraw!
+  endif
+
+"  call Dret("NetMakeDir")
+endfun
+
+" ---------------------------------------------------------------------
+"  NetBookmarkDir: {{{2
+"    0: (user: <b>)   bookmark current directory
+"    1: (user: <B>)   change to the bookmarked directory
+"    2: (user: <q>)   list bookmarks
+"    3: (browsing)    record current directory history
+"    4: (user: <u>)   go up   (previous) bookmark
+"    5: (user: <U>)   go down (next)     bookmark
+fun! s:NetBookmarkDir(chg,curdir)
+"  call Dfunc("NetBookmarkDir(chg=".a:chg." curdir<".a:curdir.">) cnt=".v:count." bookmarkcnt=".g:NETRW_BOOKMARKMAX." histcnt=".g:NETRW_DIRHIST_CNT." bookmax=".g:NETRW_BOOKMARKMAX." histmax=".g:netrw_dirhistmax)
+
+  if a:chg == 0
+   " bookmark the current directory
+"   call Decho("(user: <b>) bookmark the current directory")
+   if v:count > 0
+    " handle bookmark# specified via the count
+    let g:NETRW_BOOKMARKDIR_{v:count}= a:curdir
+    if !exists("g:NETRW_BOOKMARKMAX")
+     let g:NETRW_BOOKMARKMAX= v:count
+    elseif v:count > g:NETRW_BOOKMARKMAX
+     let g:NETRW_BOOKMARKMAX= v:count
+    endif
+   else
+    " handle no count specified
+    let g:NETRW_BOOKMARKMAX                       = g:NETRW_BOOKMARKMAX + 1
+    let g:NETRW_BOOKMARKDIR_{g:NETRW_BOOKMARKMAX} = a:curdir
+   endif
+   echo "bookmarked the current directory"
+
+  elseif a:chg == 1
+   " change to the bookmarked directory
+"   call Decho("(user: <B>) change to the bookmarked directory")
+   if exists("g:NETRW_BOOKMARKDIR_{v:count}")
+    exe "e ".g:NETRW_BOOKMARKDIR_{v:count}
+   else
+    echomsg "Sorry, bookmark#".v:count." doesn't exist!"
+   endif
+
+  elseif a:chg == 2
+   redraw!
+   let didwork= 0
+   " list user's bookmarks
+"   call Decho("(user: <q>) list user's bookmarks")
+   if exists("g:NETRW_BOOKMARKMAX")
+"    call Decho("list bookmarks [0,".g:NETRW_BOOKMARKMAX."]")
+    let cnt= 0
+    while cnt <= g:NETRW_BOOKMARKMAX
+     if exists("g:NETRW_BOOKMARKDIR_{cnt}")
+"      call Decho("Netrw Bookmark#".cnt.": ".g:NETRW_BOOKMARKDIR_{cnt})
+      echo "Netrw Bookmark#".cnt.": ".g:NETRW_BOOKMARKDIR_{cnt}
+      let didwork= 1
+     endif
+     let cnt= cnt + 1
+    endwhile
+   endif
+
+   " list directory history
+   let cnt     = g:NETRW_DIRHIST_CNT
+   let first   = 1
+   let histcnt = 0
+   while ( first || cnt != g:NETRW_DIRHIST_CNT )
+"    call Decho("first=".first." cnt=".cnt." dirhist_cnt=".g:NETRW_DIRHIST_CNT)
+    let histcnt= histcnt + 1
+    if exists("g:NETRW_DIRHIST_{cnt}")
+"     call Decho("Netrw  History#".histcnt.": ".g:NETRW_DIRHIST_{cnt})
+     echo "Netrw  History#".histcnt.": ".g:NETRW_DIRHIST_{cnt}
+     let didwork= 1
+    endif
+    let first = 0
+    let cnt   = ( cnt - 1 ) % g:netrw_dirhistmax
+    if cnt < 0
+     let cnt= cnt + g:netrw_dirhistmax
+    endif
+   endwhile
+   if didwork
+    call inputsave()|call input("Press <cr> to continue")|call inputrestore()
+   endif
+
+  elseif a:chg == 3
+   " saves most recently visited directories (when they differ)
+"   call Decho("(browsing) record curdir history")
+   if !exists("g:NETRW_DIRHIST_0") || g:NETRW_DIRHIST_{g:NETRW_DIRHIST_CNT} != a:curdir
+    let g:NETRW_DIRHIST_CNT= ( g:NETRW_DIRHIST_CNT + 1 ) % g:netrw_dirhistmax
+"    let g:NETRW_DIRHIST_{g:NETRW_DIRHIST_CNT}= substitute(a:curdir,'[/\\]$','','e')
+    let g:NETRW_DIRHIST_{g:NETRW_DIRHIST_CNT}= a:curdir
+"    call Decho("save dirhist#".g:NETRW_DIRHIST_CNT."<".g:NETRW_DIRHIST_{g:NETRW_DIRHIST_CNT}.">")
+   endif
+
+  elseif a:chg == 4
+   " u: change to the previous directory stored on the history list
+"   call Decho("(user: <u>) chg to prev dir from history")
+   let g:NETRW_DIRHIST_CNT= ( g:NETRW_DIRHIST_CNT - 1 ) % g:netrw_dirhistmax
+   if g:NETRW_DIRHIST_CNT < 0
+    let g:NETRW_DIRHIST_CNT= g:NETRW_DIRHIST_CNT + g:netrw_dirhistmax
+   endif
+   if exists("g:NETRW_DIRHIST_{g:NETRW_DIRHIST_CNT}")
+"    call Decho("changedir u#".g:NETRW_DIRHIST_CNT."<".g:NETRW_DIRHIST_{g:NETRW_DIRHIST_CNT}.">")
+    if exists("w:netrw_liststyle") && w:netrw_liststyle == s:TREELIST && exists("b:netrw_curdir")
+     setlocal ma noro
+     %d
+     setlocal nomod
+    endif
+"    call Decho("exe e! ".g:NETRW_DIRHIST_{g:NETRW_DIRHIST_CNT})
+    exe "e! ".g:NETRW_DIRHIST_{g:NETRW_DIRHIST_CNT}
+   else
+    let g:NETRW_DIRHIST_CNT= ( g:NETRW_DIRHIST_CNT + 1 ) % g:netrw_dirhistmax
+    echo "Sorry, no predecessor directory exists yet"
+   endif
+
+  elseif a:chg == 5
+   " U: change to the subsequent directory stored on the history list
+"   call Decho("(user: <U>) chg to next dir from history")
+   let g:NETRW_DIRHIST_CNT= ( g:NETRW_DIRHIST_CNT + 1 ) % g:netrw_dirhistmax
+   if exists("g:NETRW_DIRHIST_{g:NETRW_DIRHIST_CNT}")
+"    call Decho("changedir U#".g:NETRW_DIRHIST_CNT."<".g:NETRW_DIRHIST_{g:NETRW_DIRHIST_CNT}.">")
+    if exists("w:netrw_liststyle") && w:netrw_liststyle == s:TREELIST && exists("b:netrw_curdir")
+     setlocal ma noro
+     %d
+     setlocal nomod
+    endif
+"    call Decho("exe e! ".g:NETRW_DIRHIST_{g:NETRW_DIRHIST_CNT})
+    exe "e! ".g:NETRW_DIRHIST_{g:NETRW_DIRHIST_CNT}
+   else
+    let g:NETRW_DIRHIST_CNT= ( g:NETRW_DIRHIST_CNT - 1 ) % g:netrw_dirhistmax
+    if g:NETRW_DIRHIST_CNT < 0
+     let g:NETRW_DIRHIST_CNT= g:NETRW_DIRHIST_CNT + g:netrw_dirhistmax
+    endif
+    echo "Sorry, no successor directory exists yet"
+   endif
+  endif
+  call s:NetBookmarkMenu()
+"  call Dret("NetBookmarkDir")
+endfun
+
+" ---------------------------------------------------------------------
+" NetBookmarkMenu: {{{2
+fun! s:NetBookmarkMenu()
+  if !exists("s:netrw_menucnt")
+   return
+  endif
+"  call Dfunc("NetBookmarkMenu() bookmarkcnt=".g:NETRW_BOOKMARKMAX." histcnt=".g:NETRW_DIRHIST_CNT." menucnt=".s:netrw_menucnt)
+  if has("menu") && has("gui_running") && &go =~ 'm'
+   if exists("g:NetrwTopLvlMenu")
+    exe 'silent! unmenu '.g:NetrwTopLvlMenu.'Bookmark'
+   endif
+
+   " show bookmarked places
+   let cnt       = 0
+   while cnt <= g:NETRW_BOOKMARKMAX
+    if exists("g:NETRW_BOOKMARKDIR_{cnt}")
+     let bmdir= escape(g:NETRW_BOOKMARKDIR_{cnt},'.')
+"     call Decho('silent! menu '.g:NetrwMenuPriority.".2.".cnt." ".g:NetrwTopLvlMenu.'Bookmark.'.bmdir.'	:e '.g:NETRW_BOOKMARKDIR_{cnt})
+     exe 'silent! menu '.g:NetrwMenuPriority.".2.".cnt." ".g:NetrwTopLvlMenu.'Bookmarks.'.bmdir.'	:e '.g:NETRW_BOOKMARKDIR_{cnt}."\<cr>"
+    endif
+    let cnt= cnt + 1
+   endwhile
+
+   " show directory browsing history
+   let cnt     = g:NETRW_DIRHIST_CNT
+   let first   = 1
+   let histcnt = 0
+   while ( first || cnt != g:NETRW_DIRHIST_CNT )
+    let histcnt  = histcnt + 1
+    let priority = g:NETRW_DIRHIST_CNT + histcnt
+    if exists("g:NETRW_DIRHIST_{cnt}")
+     let bmdir= escape(g:NETRW_DIRHIST_{cnt},'.')
+"     call Decho('silent! menu '.g:NetrwMenuPriority.".3.".priority." ".g:NetrwTopLvlMenu.'History.'.bmdir.'	:e '.g:NETRW_DIRHIST_{cnt})
+     exe 'silent! menu '.g:NetrwMenuPriority.".3.".priority." ".g:NetrwTopLvlMenu.'History.'.bmdir.'	:e '.g:NETRW_DIRHIST_{cnt}."\<cr>"
+    endif
+    let first = 0
+    let cnt   = ( cnt - 1 ) % g:netrw_dirhistmax
+    if cnt < 0
+     let cnt= cnt + g:netrw_dirhistmax
+    endif
+   endwhile
+  endif
+"  call Dret("NetBookmarkMenu")
+endfun
+
+" ---------------------------------------------------------------------
+" NetObtain: obtain file under cursor (for remote browsing support) {{{2
+fun! netrw#NetObtain(vismode,...) range
+"  call Dfunc("NetObtain(vismode=".a:vismode.") a:0=".a:0)
+
+  if a:vismode == 0
+   " normal mode
+   let fname= expand("<cWORD>")
+"   call Decho("no arguments, use <".fname.">")
+  elseif a:vismode == 1
+   " visual mode
+   let keeprega = @a
+   norm! gv"ay
+   if g:netrw_liststyle == s:THINLIST
+    " thin listing
+    let filelist= split(@a,'\n')
+   elseif g:netrw_liststyle == s:LONGLIST
+    " long listing
+    let filelist= split(substitute(@a,'\t.\{-}\n','\n','g'),'\n')
+   else
+    " wide listing
+	let filelist = split(substitute(@a,'\s\{2,}','\n','g'),'\n')
+	let filelist = map(filelist,'substitute(v:val,"^\\s\\+","","")')
+	let filelist = map(filelist,'substitute(v:val,"\\s\\+$","","")')
+   endif
+"   call Decho("filelist<".string(filelist).">")
+   let @a= keeprega
+   for f in filelist
+    if f != ""
+     call netrw#NetObtain(2,f)
+    endif
+   endfor
+"   call Dret("NetObtain : visual mode handler")
+   return
+  elseif a:vismode == 2
+   " multiple file mode
+   let fname= a:1
+"   call Decho("visual mode handling: <".fname.">")
+  endif
+
+  " NetrwStatusLine support - for obtaining support
+  call s:SetupNetrwStatusLine('%f %h%m%r%=%9*Obtaining '.fname)
+
+  if exists("w:netrw_method") && w:netrw_method =~ '[235]'
+"   call Decho("method=".w:netrw_method)
+   if executable("ftp")
+"    call Decho("ftp is executable, method=".w:netrw_method)
+    let curdir = b:netrw_curdir
+    let path   = substitute(curdir,'ftp://[^/]\+/','','e')
+    let curline= line(".")
+    let endline= line("$")+1
+    setlocal ma noro
+    keepjumps $
+"    call Decho("getcwd<".getcwd().">")
+"    call Decho("curdir<".curdir.">")
+"    call Decho("path<".path.">")
+"    call Decho("curline=".curline)
+"    call Decho("endline=".endline)
+
+    ".........................................
+    if w:netrw_method == 2
+     " ftp + <.netrc>: Method #2
+     setlocal ff=unix
+     if path != ""
+      put ='cd '.path
+"      call Decho("ftp:  cd ".path)
+     endif
+     put ='get '.fname
+"     call Decho("ftp:  get ".fname)
+     put ='quit'
+"     call Decho("ftp:  quit")
+     if exists("g:netrw_port") && g:netrw_port != ""
+"      call Decho("exe ".g:netrw_silentxfer.endline.",$!".g:netrw_ftp_cmd." -i ".g:netrw_machine." ".g:netrw_port)
+      exe g:netrw_silentxfer.endline.",$!".g:netrw_ftp_cmd." -i ".g:netrw_machine." ".g:netrw_port
+     else
+"      call Decho("exe ".g:netrw_silentxfer.endline.",$!".g:netrw_ftp_cmd." -i ".g:netrw_machine)
+      exe g:netrw_silentxfer.endline.",$!".g:netrw_ftp_cmd." -i ".g:netrw_machine
+     endif
+
+   ".........................................
+  elseif w:netrw_method == 3
+   " ftp + machine,id,passwd,filename: Method #3
+    setlocal ff=unix
+    if exists("g:netrw_port") && g:netrw_port != ""
+     put ='open '.g:netrw_machine.' '.g:netrw_port
+"     call Decho('ftp:  open '.g:netrw_machine.' '.g:netrw_port)
+    else
+     put ='open '.g:netrw_machine
+"     call Decho('ftp:  open '.g:netrw_machine)
+    endif
+
+    if exists("g:netrw_ftp") && g:netrw_ftp == 1
+     put =g:netrw_uid
+     put ='\"'.g:netrw_passwd.'\"'
+"     call Decho('ftp:  g:netrw_uid')
+"     call Decho('ftp:  g:netrw_passwd')
+    else
+     put ='user \"'.g:netrw_uid.'\" \"'.g:netrw_passwd.'\"'
+"     call Decho('user '.g:netrw_uid.' '.g:netrw_passwd)
+    endif
+
+   if path != ""
+    put ='cd '.path
+"    call Decho('cd '.a:path)
+   endif
+   put ='get '.fname
+"   call Decho("ftp:  get ".fname)
+   put ='quit'
+"   call Decho("ftp:  quit")
+
+    " perform ftp:
+    " -i       : turns off interactive prompting from ftp
+    " -n  unix : DON'T use <.netrc>, even though it exists
+    " -n  win32: quit being obnoxious about password
+"    call Decho("exe ".g:netrw_silentxfer.curline.",$!".g:netrw_ftp_cmd." -i -n")
+    exe g:netrw_silentxfer.endline.",$!".g:netrw_ftp_cmd." -i -n"
+
+    ".........................................
+    else
+     call netrw#ErrorMsg(s:WARNING,"unable to comply with your request<" . choice . ">",28)
+    endif
+    " restore
+    exe "silent! ".endline.",$d"
+    exe "keepjumps ".curline
+    setlocal noma nomod ro
+   else
+"    call Decho("ftp not executable")
+    if !exists("g:netrw_quiet")
+     call netrw#ErrorMsg(s:ERROR,"this system doesn't support ftp",29)
+    endif
+    " restore status line
+    let &stl        = s:netrw_users_stl
+    let &laststatus = s:netrw_users_ls
+    " restore NetMethod
+    if exists("keep_netrw_method")
+     call s:NetMethod(keep_netrw_choice)
+     let w:netrw_method  = keep_netrw_wmethod
+    endif
+"    call Dret("NetObtain")
+    return
+   endif
+
+  ".........................................
+  else
+   " scp: Method#4
+"   call Decho("using scp")
+   let curdir = b:netrw_curdir
+   let path   = substitute(curdir,'scp://[^/]\+/','','e')
+"   call Decho("path<".path.">")
+   if exists("g:netrw_port") && g:netrw_port != ""
+    let useport= " ".g:netrw_scpport." ".g:netrw_port
+   else
+    let useport= ""
+   endif
+"   call Decho("executing: !".g:netrw_scp_cmd.useport." ".g:netrw_machine.":".path.escape(fname,' ?&')." .")
+   exe g:netrw_silentxfer."!".g:netrw_scp_cmd.useport." ".g:netrw_machine.":".path.escape(fname,' ?&')." ."
+   endif
+  endif
+
+  " restore status line
+  let &stl        = s:netrw_users_stl
+  let &laststatus = s:netrw_users_ls
+  redraw!
+
+  " restore NetMethod
+  if exists("keep_netrw_method")
+   call s:NetMethod(keep_netrw_choice)
+   let w:netrw_method  = keep_netrw_wmethod
+  endif
+
+"  call Dret("NetObtain")
+endfun
+
+" ---------------------------------------------------------------------
+" NetPrevWinOpen: open file/directory in previous window.  {{{2
+"   If there's only one window, then the window will first be split.
+fun! s:NetPrevWinOpen(islocal)
+"  call Dfunc("NetPrevWinOpen(islocal=".a:islocal.")")
+
+  " get last window number and the word currently under the cursor
+  let lastwinnr = winnr("$")
+  let curword   = s:NetGetWord()
+"  call Decho("lastwinnr=".lastwinnr." curword<".curword.">")
+
+  let didsplit  = 0
+  if lastwinnr == 1
+   " if only one window, open a new one first
+"   call Decho("only one window, so open a new one (g:netrw_alto=".g:netrw_alto.")")
+   exe (g:netrw_alto? "bel " : "abo ").g:netrw_winsize."wincmd s"
+   let didsplit  = 1
+
+  else
+   wincmd p
+   " if the previous window's buffer has been changed (is modified),
+   " and it doesn't appear in any other extant window, then ask the
+   " user if s/he wants to abandon modifications therein.
+   let bnr    = winbufnr(0)
+   let bnrcnt = 0
+   if &mod
+    windo if winbufnr(0) == bnr | let bnrcnt=bnrcnt+1 | endif
+"    call Decho("bnr=".bnr." bnrcnt=".bnrcnt)
+    if bnrcnt == 1
+     let bufname= bufname(winbufnr(winnr()))
+     let choice= confirm("Save modified file<".bufname.">?","&Yes\n&No\n&Cancel")
+
+     if choice == 1
+      " Yes -- write file & then browse
+      let v:errmsg= ""
+      silent w
+      if v:errmsg != ""
+       call netrw#ErrorMsg(s:ERROR,"unable to write <".bufname.">!",30)
+       if didsplit
+       	q
+       else
+       	wincmd p
+       endif
+"       call Dret("NetPrevWinOpen : unable to write <".bufname.">")
+       return
+      endif
+
+     elseif choice == 2
+      " No -- don't worry about changed file, just browse anyway
+      setlocal nomod
+      call netrw#ErrorMsg(s:WARNING,bufname." changes abandoned",31)
+
+     else
+      " Cancel -- don't do this
+      if didsplit
+       q
+      else
+       wincmd p
+      endif
+"      call Dret("NetPrevWinOpen : cancelled")
+      return
+     endif
+    endif
+   endif
+  endif
+
+  if a:islocal
+   call netrw#LocalBrowseCheck(s:NetBrowseChgDir(a:islocal,curword))
+  else
+   call s:NetBrowse(a:islocal,s:NetBrowseChgDir(a:islocal,curword))
+  endif
+"  call Dret("NetPrevWinOpen")
+endfun
+
+" ---------------------------------------------------------------------
+" NetMenu: generates the menu for gvim and netrw {{{2
+fun! s:NetMenu(domenu)
+
+  if !exists("g:NetrwMenuPriority")
+   let g:NetrwMenuPriority= 80
+  endif
+
+  if has("menu") && has("gui_running") && &go =~ 'm' && g:netrw_menu
+"   call Dfunc("NetMenu(domenu=".a:domenu.")")
+
+   if !exists("s:netrw_menu_enabled") && a:domenu
+"    call Decho("initialize menu")
+    let s:netrw_menu_enabled= 1
+    exe 'silent! menu '.g:NetrwMenuPriority.'.1 '.g:NetrwTopLvlMenu.'Help<tab><F1>	<F1>'
+    call s:NetBookmarkMenu() " provide some history!
+    exe 'silent! menu '.g:NetrwMenuPriority.'.4 '.g:NetrwTopLvlMenu.'Go\ Up\ Directory<tab>-	-'
+    exe 'silent! menu '.g:NetrwMenuPriority.'.5 '.g:NetrwTopLvlMenu.'Apply\ Special\ Viewer<tab>x	x'
+    exe 'silent! menu '.g:NetrwMenuPriority.'.6 '.g:NetrwTopLvlMenu.'Bookmark\ Current\ Directory<tab>mb	mb'
+    exe 'silent! menu '.g:NetrwMenuPriority.'.7 '.g:NetrwTopLvlMenu.'Goto\ Bookmarked\ Directory<tab>gb	gb'
+    exe 'silent! menu '.g:NetrwMenuPriority.'.8 '.g:NetrwTopLvlMenu.'Change\ To\ Recently\ Used\ Directory<tab>u	u'
+    exe 'silent! menu '.g:NetrwMenuPriority.'.9 '.g:NetrwTopLvlMenu.'Change\ To\ Subsequently\ Used\ Directory<tab>U	U'
+    exe 'silent! menu '.g:NetrwMenuPriority.'.10 '.g:NetrwTopLvlMenu.'Delete\ File/Directory<tab>D	D'
+    exe 'silent! menu '.g:NetrwMenuPriority.'.11 '.g:NetrwTopLvlMenu.'Edit\ File\ Hiding\ List<tab>'."<ctrl-h>	\<c-h>"
+    exe 'silent! menu '.g:NetrwMenuPriority.'.12 '.g:NetrwTopLvlMenu.'Edit\ File/Directory<tab><cr>	'."\<cr>"
+    exe 'silent! menu '.g:NetrwMenuPriority.'.13 '.g:NetrwTopLvlMenu.'Edit\ File/Directory,\ New\ Window<tab>o	o'
+    exe 'silent! menu '.g:NetrwMenuPriority.'.14 '.g:NetrwTopLvlMenu.'Edit\ File/Directory,\ New\ Vertical\ Window<tab>v	v'
+    exe 'silent! menu '.g:NetrwMenuPriority.'.15 '.g:NetrwTopLvlMenu.'List\ Bookmarks\ and\ History<tab>q	q'
+    exe 'silent! menu '.g:NetrwMenuPriority.'.16 '.g:NetrwTopLvlMenu.'Listing\ Style\ (thin-long-wide)<tab>i	i'
+    exe 'silent! menu '.g:NetrwMenuPriority.'.17 '.g:NetrwTopLvlMenu.'Make\ Subdirectory<tab>d	d'
+    exe 'silent! menu '.g:NetrwMenuPriority.'.18 '.g:NetrwTopLvlMenu.'Normal-Hide-Show<tab>a	a'
+    exe 'silent! menu '.g:NetrwMenuPriority.'.19 '.g:NetrwTopLvlMenu.'Obtain\ File<tab>O	O'
+    exe 'silent! menu '.g:NetrwMenuPriority.'.20 '.g:NetrwTopLvlMenu.'Preview\ File/Directory<tab>p	p'
+    exe 'silent! menu '.g:NetrwMenuPriority.'.21 '.g:NetrwTopLvlMenu.'Previous\ Window\ Browser<tab>P	P'
+    exe 'silent! menu '.g:NetrwMenuPriority.'.22 '.g:NetrwTopLvlMenu.'Refresh\ Listing<tab>'."<ctrl-l>	\<c-l>"
+    exe 'silent! menu '.g:NetrwMenuPriority.'.23 '.g:NetrwTopLvlMenu.'Rename\ File/Directory<tab>R	R'
+    exe 'silent! menu '.g:NetrwMenuPriority.'.24 '.g:NetrwTopLvlMenu.'Reverse\ Sorting\ Order<tab>'."r	r"
+    exe 'silent! menu '.g:NetrwMenuPriority.'.25 '.g:NetrwTopLvlMenu.'Select\ Sorting\ Style<tab>s	s'
+    exe 'silent! menu '.g:NetrwMenuPriority.'.26 '.g:NetrwTopLvlMenu.'Sorting\ Sequence\ Edit<tab>S	S'
+    exe 'silent! menu '.g:NetrwMenuPriority.'.27 '.g:NetrwTopLvlMenu.'Set\ Current\ Directory<tab>c	c'
+    exe 'silent! menu '.g:NetrwMenuPriority.'.28 '.g:NetrwTopLvlMenu.'Settings/Options<tab>:NetrwSettings	'.":NetrwSettings\<cr>"
+    let s:netrw_menucnt= 28
+
+   elseif !a:domenu
+    let s:netrwcnt = 0
+    let curwin     = winnr()
+    windo if getline(2) =~ "Netrw" | let s:netrwcnt= s:netrwcnt + 1 | endif
+    exe curwin."wincmd w"
+    
+    if s:netrwcnt <= 1
+"     call Decho("clear menus")
+     exe 'silent! unmenu '.g:NetrwTopLvlMenu.'Help'
+     exe 'silent! unmenu '.g:NetrwTopLvlMenu.'Apply\ Special\ Viewer'
+     exe 'silent! unmenu '.g:NetrwTopLvlMenu.'Bookmark\ Current\ Directory'
+     exe 'silent! unmenu '.g:NetrwTopLvlMenu.'Go\ Up\ Directory'
+     exe 'silent! unmenu '.g:NetrwTopLvlMenu.'Goto\ Bookmarked\ Directory'
+     exe 'silent! unmenu '.g:NetrwTopLvlMenu.'Change\ To\ Recently\ Used\ Directory'
+     exe 'silent! unmenu '.g:NetrwTopLvlMenu.'Change\ To\ Subsequently\ Used\ Directory'
+     exe 'silent! unmenu '.g:NetrwTopLvlMenu.'Delete\ File/Directory'
+     exe 'silent! unmenu '.g:NetrwTopLvlMenu.'Edit\ File/Directory'
+     exe 'silent! unmenu '.g:NetrwTopLvlMenu.'Edit\ File/Directory,\ New\ Window'
+     exe 'silent! unmenu '.g:NetrwTopLvlMenu.'Edit\ File/Directory,\ New\ Vertical\ Window'
+     exe 'silent! unmenu '.g:NetrwTopLvlMenu.'Edit\ File\ Hiding\ List'
+     exe 'silent! unmenu '.g:NetrwTopLvlMenu.'Edit\ File'
+     exe 'silent! unmenu '.g:NetrwTopLvlMenu.'Enter\ File/Directory'
+     exe 'silent! unmenu '.g:NetrwTopLvlMenu.'Enter\ File/Directory\ (vertical\ split)'
+     exe 'silent! unmenu '.g:NetrwTopLvlMenu.'List\ Bookmarks\ and\ History'
+     exe 'silent! unmenu '.g:NetrwTopLvlMenu.'Listing\ Style\ (thin-long-wide)'
+     exe 'silent! unmenu '.g:NetrwTopLvlMenu.'Make\ Subdirectory'
+     exe 'silent! unmenu '.g:NetrwTopLvlMenu.'Normal-Hide-Show'
+     exe 'silent! unmenu '.g:NetrwTopLvlMenu.'Obtain\ File'
+     exe 'silent! unmenu '.g:NetrwTopLvlMenu.'Preview\ File/Directory'
+     exe 'silent! unmenu '.g:NetrwTopLvlMenu.'Previous\ Window\ Browser'
+     exe 'silent! unmenu '.g:NetrwTopLvlMenu.'Refresh\ Listing'
+     exe 'silent! unmenu '.g:NetrwTopLvlMenu.'Rename\ File/Directory'
+     exe 'silent! unmenu '.g:NetrwTopLvlMenu.'Reverse\ Sorting\ Order'
+     exe 'silent! unmenu '.g:NetrwTopLvlMenu.'Select\ Sorting\ Style'
+     exe 'silent! unmenu '.g:NetrwTopLvlMenu.'Sorting\ Sequence\ Edit'
+     exe 'silent! unmenu '.g:NetrwTopLvlMenu.'Set\ Current\ Directory'
+     exe 'silent! unmenu '.g:NetrwTopLvlMenu.'Settings/Options'
+     exe 'silent! unmenu '.g:NetrwTopLvlMenu.'Bookmarks'
+     silent! unlet s:netrw_menu_enabled
+    endif
+   endif
+"   call Dret("NetMenu")
+  endif
+
+endfun
+
+" ==========================================
+"  Local Directory Browsing Support:    {{{1
+" ==========================================
+
+" ---------------------------------------------------------------------
+" LocalBrowseCheck: {{{2
+fun! netrw#LocalBrowseCheck(dirname)
+  " unfortunate interaction -- split window debugging can't be
+"  " used here, must use DechoRemOn or DechoTabOn -- the BufEnter
+  " event triggers another call to LocalBrowseCheck() when attempts
+  " to write to the DBG buffer are made.
+"  call Dfunc("LocalBrowseCheck(dirname<".a:dirname.">")
+  if isdirectory(a:dirname)
+   silent! call s:NetBrowse(1,a:dirname)
+  endif
+"  call Dret("LocalBrowseCheck")
+  " not a directory, ignore it
+endfun
+
+" ---------------------------------------------------------------------
+"  LocalListing: does the job of "ls" for local directories {{{2
+fun! s:LocalListing()
+"  call Dfunc("LocalListing() &ma=".&ma." &mod=".&mod." &ro=".&ro." buf(%)=".buf("%"))
+"  if exists("b:netrw_curdir") |call Decho('b:netrw_curdir<'.b:netrw_curdir.">")  |else|call Decho("b:netrw_curdir doesn't exist") |endif
+"  if exists("g:netrw_sort_by")|call Decho('g:netrw_sort_by<'.g:netrw_sort_by.">")|else|call Decho("g:netrw_sort_by doesn't exist")|endif
+
+  " get the list of files contained in the current directory
+  let dirname    = escape(b:netrw_curdir,s:netrw_glob_escape)
+  let dirnamelen = strlen(b:netrw_curdir)
+  let filelist   = glob(s:ComposePath(dirname,"*"))
+"  call Decho("glob(dirname<".dirname."/*>)=".filelist)
+  if filelist != ""
+   let filelist= filelist."\n"
+  endif
+  let filelist= filelist.glob(s:ComposePath(dirname,".*"))
+"  call Decho("glob(dirname<".dirname."/.*>)=".glob(dirname.".*"))
+
+  " if the directory name includes a "$", and possibly other characters,
+  " the glob() doesn't include "." and ".." entries.
+  if filelist !~ '[\\/]\.[\\/]\=\(\n\|$\)'
+"   call Decho("forcibly tacking on .")
+   if filelist == ""
+    let filelist= s:ComposePath(dirname,"./")
+   else
+    let filelist= filelist."\n".s:ComposePath(b:netrw_curdir,"./")
+   endif
+"  call Decho("filelist<".filelist.">")
+  endif
+  if filelist !~ '[\\/]\.\.[\\/]\=\(\n\|$\)'
+"   call Decho("forcibly tacking on ..")
+   let filelist= filelist."\n".s:ComposePath(b:netrw_curdir,"../")
+"   call Decho("filelist<".filelist.">")
+  endif
+  if b:netrw_curdir == '/'
+   " remove .. from filelist when current directory is root directory
+   let filelist= substitute(filelist,'/\.\.\n','','')
+"   call Decho("remove .. from filelist")
+  endif
+  let filelist= substitute(filelist,'\n\{2,}','\n','ge')
+  if (has("win32") || has("win95") || has("win64") || has("win16"))
+   let filelist= substitute(filelist,'\','/','ge')
+  else
+   let filelist= substitute(filelist,'\','\\','ge')
+  endif
+
+"  call Decho("dirname<".dirname.">")
+"  call Decho("dirnamelen<".dirnamelen.">")
+"  call Decho("filelist<".filelist.">")
+
+  while filelist != ""
+   if filelist =~ '\n'
+    let filename = substitute(filelist,'\n.*$','','e')
+    let filelist = substitute(filelist,'^.\{-}\n\(.*\)$','\1','e')
+   else
+    let filename = filelist
+    let filelist = ""
+   endif
+   let pfile= filename
+   if isdirectory(filename)
+    let pfile= filename."/"
+   endif
+   if pfile =~ '//$'
+    let pfile= substitute(pfile,'//$','/','e')
+   endif
+   let pfile= strpart(pfile,dirnamelen)
+   let pfile= substitute(pfile,'^[/\\]','','e')
+"   call Decho(" ")
+"   call Decho("filename<".filename.">")
+"   call Decho("pfile   <".pfile.">")
+
+   if w:netrw_liststyle == s:LONGLIST
+    let sz   = getfsize(filename)
+    let fsz  = strpart("               ",1,15-strlen(sz)).sz
+    let pfile= pfile."\t".fsz." ".strftime(g:netrw_timefmt,getftime(filename))
+"    call Decho("sz=".sz." fsz=".fsz)
+   endif
+
+   if     g:netrw_sort_by =~ "^t"
+    " sort by time (handles time up to 1 quintillion seconds, US)
+"    call Decho("getftime(".filename.")=".getftime(filename))
+    let t  = getftime(filename)
+    let ft = strpart("000000000000000000",1,18-strlen(t)).t
+"    call Decho("exe keepjumps put ='".ft.'/'.filename."'")
+    let ftpfile= ft.'/'.pfile
+    keepjumps silent! put=ftpfile
+
+   elseif g:netrw_sort_by =~ "^s"
+    " sort by size (handles file sizes up to 1 quintillion bytes, US)
+"    call Decho("getfsize(".filename.")=".getfsize(filename))
+    let sz   = getfsize(filename)
+    let fsz  = strpart("000000000000000000",1,18-strlen(sz)).sz
+"    call Decho("exe keepjumps put ='".fsz.'/'.filename."'")
+    let fszpfile= fsz.'/'.pfile
+    keepjumps silent! put =fszpfile
+
+   else 
+    " sort by name
+"    call Decho("exe keepjumps put ='".pfile."'")
+    keepjumps silent! put=pfile
+   endif
+  endwhile
+
+  " cleanup any windows mess at end-of-line
+  silent! keepjumps %s/\r$//e
+  setlocal ts=32
+"  call Decho("setlocal ts=32")
+
+"  call Dret("LocalListing")
+endfun
+
+" ---------------------------------------------------------------------
+" LocalBrowseShellCmdRefresh: this function is called after a user has {{{2
+" performed any shell command.  The idea is to cause all local-browsing
+" buffers to be refreshed after a user has executed some shell command,
+" on the chance that s/he removed/created a file/directory with it.
+fun! s:LocalBrowseShellCmdRefresh()
+"  call Dfunc("LocalBrowseShellCmdRefresh() browselist=".string(s:netrw_browselist))
+  " determine which buffers currently reside in a tab
+  let itab       = 1
+  let buftablist = []
+  while itab <= tabpagenr("$")
+   let buftablist= buftablist + tabpagebuflist()
+   let itab= itab + 1
+   tabn
+  endwhile
+"  call Decho("buftablist".string(buftablist))
+  "  GO through all buffers on netrw_browselist (ie. just local-netrw buffers):
+  "   | refresh any netrw window
+  "   | wipe out any non-displaying netrw buffer
+  let curwin = winnr()
+  let ibl    = 0
+  for ibuf in s:netrw_browselist
+"   call Decho("bufwinnr(".ibuf.") index(buftablist,".ibuf.")=".index(buftablist,ibuf))
+   if bufwinnr(ibuf) == -1 && index(buftablist,ibuf) == -1
+"    call Decho("wiping  buf#".ibuf,"<".bufname(ibuf).">")
+    exe "silent! bw ".ibuf
+    call remove(s:netrw_browselist,ibl)
+"    call Decho("browselist=".string(s:netrw_browselist))
+    continue
+   elseif index(tabpagebuflist(),ibuf) != -1
+"    call Decho("refresh buf#".ibuf.'-> win#'.bufwinnr(ibuf))
+    exe bufwinnr(ibuf)."wincmd w"
+    call s:NetRefresh(1,s:NetBrowseChgDir(1,'./'))
+   endif
+   let ibl= ibl + 1
+  endfor
+  exe curwin."wincmd w"
+
+"  call Dret("LocalBrowseShellCmdRefresh")
+endfun
+
+" ---------------------------------------------------------------------
+" LocalBrowseRm: {{{2
+fun! s:LocalBrowseRm(path) range
+"  call Dfunc("LocalBrowseRm(path<".a:path.">)")
+"  call Decho("firstline=".a:firstline." lastline=".a:lastline)
+
+  " preparation for removing multiple files/directories
+  let ctr           = a:firstline
+  let ret           = 0
+  let all= 0
+
+  " remove multiple files and directories
+  while ctr <= a:lastline
+   exe "keepjumps ".ctr
+
+   " sanity checks
+   if line(".") < w:netrw_bannercnt
+    let ctr= ctr + 1
+    continue
+   endif
+   let curword= s:NetGetWord()
+   if curword == "./" || curword == "../"
+    let ctr= ctr + 1
+    continue
+   endif
+
+   norm! 0
+   let rmfile= s:ComposePath(a:path,curword)
+"   call Decho("rmfile<".rmfile.">")
+
+   if rmfile !~ '^"' && (rmfile =~ '@$' || rmfile !~ '[\/]$')
+    " attempt to remove file
+    if !all
+     echohl Statement
+     call inputsave()
+     let ok= input("Confirm deletion of file<".rmfile."> ","[{y(es)},n(o),a(ll),q(uit)] ")
+     call inputrestore()
+     echohl NONE
+     if ok == ""
+      let ok="no"
+     endif
+"     call Decho("response: ok<".ok.">")
+     let ok= substitute(ok,'\[{y(es)},n(o),a(ll),q(uit)]\s*','','e')
+"     call Decho("response: ok<".ok."> (after sub)")
+     if ok =~ 'a\%[ll]'
+      let all= 1
+     endif
+    endif
+
+    if all || ok =~ 'y\%[es]' || ok == ""
+     let ret= s:System("delete",rmfile)
+"     call Decho("errcode=".v:shell_error." ret=".ret)
+    elseif ok =~ 'q\%[uit]'
+     break
+    endif
+
+   else
+    " attempt to remove directory
+    if !all
+     echohl Statement
+     call inputsave()
+     let ok= input("Confirm deletion of directory<".rmfile."> ","[{y(es)},n(o),a(ll),q(uit)] ")
+     call inputrestore()
+     let ok= substitute(ok,'\[{y(es)},n(o),a(ll),q(uit)]\s*','','e')
+     if ok == ""
+      let ok="no"
+     endif
+     if ok =~ 'a\%[ll]'
+      let all= 1
+     endif
+    endif
+    let rmfile= substitute(rmfile,'[\/]$','','e')
+
+    if all || ok =~ 'y\%[es]' || ok == ""
+"     call Decho("1st attempt: system(".g:netrw_local_rmdir.' "'.rmfile.'")')
+     call s:System("system",g:netrw_local_rmdir.' "'.rmfile.'"')
+"     call Decho("v:shell_error=".v:shell_error)
+
+     if v:shell_error != 0
+"      call Decho("2nd attempt to remove directory<".rmfile.">")
+      let errcode= s:System("delete",rmfile)
+"      call Decho("errcode=".errcode)
+
+      if errcode != 0
+       if has("unix")
+"        call Decho("3rd attempt to remove directory<".rmfile.">")
+        call s:System("system","rm ".rmfile)
+        if v:shell_error != 0 && !exists("g:netrw_quiet")
+	 call netrw#ErrorMsg(s:ERROR,"unable to remove directory<".rmfile."> -- is it empty?",34)
+endif
+       elseif !exists("g:netrw_quiet")
+       	call netrw#ErrorMsg(s:ERROR,"unable to remove directory<".rmfile."> -- is it empty?",35)
+       endif
+      endif
+     endif
+
+    elseif ok =~ 'q\%[uit]'
+     break
+    endif
+   endif
+
+   let ctr= ctr + 1
+  endwhile
+
+  " refresh the directory
+  let curline= line(".")
+"  call Decho("refresh the directory")
+  call s:NetRefresh(1,s:NetBrowseChgDir(1,'./'))
+  exe curline
+
+"  call Dret("LocalBrowseRm")
+endfun
+
+" ---------------------------------------------------------------------
+" LocalBrowseRename: rename a remote file or directory {{{2
+fun! s:LocalBrowseRename(path) range
+"  call Dfunc("LocalBrowseRename(path<".a:path.">)")
+
+  " preparation for removing multiple files/directories
+  let ctr= a:firstline
+
+  " attempt to rename files/directories
+  while ctr <= a:lastline
+   exe "keepjumps ".ctr
+
+   " sanity checks
+   if line(".") < w:netrw_bannercnt
+    let ctr= ctr + 1
+    continue
+   endif
+   let curword= s:NetGetWord()
+   if curword == "./" || curword == "../"
+    let ctr= ctr + 1
+    continue
+   endif
+
+   norm! 0
+   let oldname= s:ComposePath(a:path,curword)
+"   call Decho("oldname<".oldname.">")
+
+   call inputsave()
+   let newname= input("Moving ".oldname." to : ",substitute(oldname,'/*$','','e'))
+   call inputrestore()
+
+   let ret= rename(oldname,newname)
+"   call Decho("renaming <".oldname."> to <".newname.">")
+
+   let ctr= ctr + 1
+  endwhile
+
+  " refresh the directory
+"  call Decho("refresh the directory listing")
+  call netrw#NetSavePosn()
+  call s:NetRefresh(1,s:NetBrowseChgDir(1,'./'))
+"  call Dret("LocalBrowseRename")
+endfun
+
+" ---------------------------------------------------------------------
+" LocalFastBrowser: handles setting up/taking down fast browsing for the {{{2
+"                   local browser
+"     fastbrowse  Local  Remote   Hiding a buffer implies it may be re-used (fast)
+"  slow   0         D      D      Deleting a buffer implies it will not be re-used (slow)
+"  med    1         D      H
+"  fast   2         H      H
+fun! s:LocalFastBrowser()
+"  call Dfunc("LocalFastBrowser() g:netrw_fastbrowse=".g:netrw_fastbrowse)
+
+  " initialize browselist, a list of buffer numbers that the local browser has used
+  if !exists("s:netrw_browselist")
+"   call Decho("initialize s:netrw_browselist")
+   let s:netrw_browselist= []
+  endif
+
+  " append current buffer to fastbrowse list
+  if g:netrw_fastbrowse <= 1 && (empty(s:netrw_browselist) || bufnr("%") > s:netrw_browselist[-1])
+"   call Decho("appendng current buffer to browselist")
+   call add(s:netrw_browselist,bufnr("%"))
+"   call Decho("browselist=".string(s:netrw_browselist))
+  endif
+
+  " enable autocmd events to handle refreshing/removing local browser buffers
+  "    If local browse buffer is currently showing: refresh it
+  "    If local browse buffer is currently hidden : wipe it
+  if !exists("s:netrw_browser_shellcmd") && g:netrw_fastbrowse <= 1
+"   call Decho("setting up local-browser shell command refresh")
+   let s:netrw_browser_shellcmd= 1
+   augroup AuNetrwShellCmd
+    au!
+    if (has("win32") || has("win95") || has("win64") || has("win16"))
+     au ShellCmdPost *	call s:LocalBrowseShellCmdRefresh()
+    else
+     au ShellCmdPost,FocusGained *	call s:LocalBrowseShellCmdRefresh()
+    endif
+   augroup END
+  endif
+
+  " user must have changed fastbrowse to its fast setting, so remove
+  " the associated autocmd events
+  if g:netrw_fastbrowse > 1 && exists("s:netrw_browser_shellcmd")
+"   call Decho("remove AuNetrwShellCmd autcmd group")
+   unlet s:netrw_browser_shellcmd
+   augroup AuNetrwShellCmd
+    au!
+   augroup END
+   augroup! AuNetrwShellCmd
+  endif
+
+"  call Dret("LocalFastBrowser")
+endfun
+
+" ---------------------------------------------------------------------
+" LocalObtain: copy selected file to current working directory {{{2
+fun! s:LocalObtain()
+"  call Dfunc("LocalObtain()")
+  if exists("b:netrw_curdir") && getcwd() != b:netrw_curdir
+   let fname= expand("<cWORD>")
+   let fcopy= readfile(b:netrw_curdir."/".fname,"b")
+   call writefile(fcopy,getcwd()."/".fname,"b")
+  elseif !exists("b:netrw_curdir")
+   call netrw#ErrorMsg(s:ERROR,"local browsing directory doesn't exist!",36)
+  else
+   call netrw#ErrorMsg(s:ERROR,"local browsing directory and current directory are identical",37)
+  endif
+"  call Dret("LocalObtain")
+endfun
+
+" ---------------------------------------------------------------------
+" netrw#Explore: launch the local browser in the directory of the current file {{{2
+"          dosplit==0: the window will be split iff the current file has
+"                      been modified
+"          dosplit==1: the window will be split before running the local
+"                      browser
+fun! netrw#Explore(indx,dosplit,style,...)
+"  call Dfunc("netrw#Explore(indx=".a:indx." dosplit=".a:dosplit." style=".a:style.",a:1<".a:1.">) &modified=".&modified." a:0=".a:0)
+  if !exists("b:netrw_curdir")
+   let b:netrw_curdir= getcwd()
+"   call Decho("set b:netrw_curdir<".b:netrw_curdir."> (used getcwd)")
+  endif
+  let curfile= b:netrw_curdir
+"  call Decho("curfile<".curfile.">")
+
+  " save registers
+  silent! let keepregstar = @*
+  silent! let keepregplus = @+
+  silent! let keepregslash= @/
+
+  " if dosplit or file has been modified
+  if a:dosplit || &modified || a:style == 6
+"   call Decho("case: dosplit=".a:dosplit." modified=".&modified." a:style=".a:style)
+   call s:SaveWinVars()
+
+   if a:style == 0      " Explore, Sexplore
+"    call Decho("style=0: Explore or Sexplore")
+    exe g:netrw_winsize."wincmd s"
+
+   elseif a:style == 1  "Explore!, Sexplore!
+"    call Decho("style=1: Explore! or Sexplore!")
+    exe g:netrw_winsize."wincmd v"
+
+   elseif a:style == 2  " Hexplore
+"    call Decho("style=2: Hexplore")
+    exe "bel ".g:netrw_winsize."wincmd s"
+
+   elseif a:style == 3  " Hexplore!
+"    call Decho("style=3: Hexplore!")
+    exe "abo ".g:netrw_winsize."wincmd s"
+
+   elseif a:style == 4  " Vexplore
+"    call Decho("style=4: Vexplore")
+    exe "lefta ".g:netrw_winsize."wincmd v"
+
+   elseif a:style == 5  " Vexplore!
+"    call Decho("style=5: Vexplore!")
+    exe "rightb ".g:netrw_winsize."wincmd v"
+
+   elseif a:style == 6  " Texplore
+    call s:SaveBufVars()
+"    call Decho("style  = 6: Texplore")
+    tabnew
+    call s:RestoreBufVars()
+   endif
+   call s:RestoreWinVars()
+  endif
+  norm! 0
+
+  if a:0 > 0
+"   call Decho("a:1<".a:1.">")
+   if a:1 =~ '^\~' && (has("unix") || (exists("g:netrw_cygwin") && g:netrw_cygwin))
+    let dirname= substitute(a:1,'\~',expand("$HOME"),'')
+"    call Decho("using dirname<".dirname.">  (case: ~ && unix||cygwin)")
+   elseif a:1 == '.'
+    let dirname= exists("b:netrw_curdir")? b:netrw_curdir : getcwd()
+    if dirname !~ '/$'
+     let dirname= dirname."/"
+    endif
+"    call Decho("using dirname<".dirname.">  (case: ".(exists("b:netrw_curdir")? "b:netrw_curdir" : "getcwd()").")")
+   elseif a:1 =~ '\$'
+    let dirname= expand(a:1)
+   else
+    let dirname= a:1
+"    call Decho("using dirname<".dirname.">")
+   endif
+  endif
+
+  if dirname =~ '^\*/'
+   " Explore */pattern
+"   call Decho("case Explore */pattern")
+   let pattern= substitute(dirname,'^\*/\(.*\)$','\1','')
+"   call Decho("Explore */pat: dirname<".dirname."> -> pattern<".pattern.">")
+   if &hls | let keepregslash= s:ExplorePatHls(pattern) | endif
+  elseif dirname =~ '^\*\*//'
+   " Explore **//pattern
+"   call Decho("case Explore **//pattern")
+   let pattern     = substitute(dirname,'^\*\*//','','')
+   let starstarpat = 1
+"   call Decho("Explore **//pat: dirname<".dirname."> -> pattern<".pattern.">")
+  endif
+
+  if dirname == "" && a:indx >= 0
+   " Explore Hexplore Vexplore Sexplore
+"   call Decho("case Explore Hexplore Vexplore Sexplore")
+   let newdir= substitute(expand("%:p"),'^\(.*[/\\]\)[^/\\]*$','\1','e')
+   if newdir =~ '^scp:' || newdir =~ '^ftp:'
+"    call Decho("calling NetBrowse(0,newdir<".newdir.">)")
+    call s:NetBrowse(0,newdir)
+   else
+    if newdir == ""|let newdir= getcwd()|endif
+"    call Decho("calling LocalBrowseCheck(newdir<".newdir.">)")
+    call netrw#LocalBrowseCheck(newdir)
+   endif
+   call search('\<'.substitute(curfile,'^.*/','','e').'\>','cW')
+
+  elseif dirname =~ '^\*\*/' || a:indx < 0 || dirname =~ '^\*/'
+   " Nexplore, Pexplore, Explore **/... , or Explore */pattern
+"   call Decho("case Nexplore, Pexplore, <s-down>, <s-up>, Explore dirname<".dirname.">")
+   if !mapcheck("<s-up>","n") && !mapcheck("<s-down>","n") && exists("b:netrw_curdir")
+"    call Decho("set up <s-up> and <s-down> maps")
+    let s:didstarstar= 1
+    nnoremap <buffer> <silent> <s-up>	:Pexplore<cr>
+    nnoremap <buffer> <silent> <s-down>	:Nexplore<cr>
+   endif
+
+   if has("path_extra")
+"    call Decho("has path_extra")
+    if !exists("w:netrw_explore_indx")
+     let w:netrw_explore_indx= 0
+    endif
+    let indx = a:indx
+"    call Decho("set indx= [a:indx=".indx."]")
+"
+    if indx == -1
+     "Nexplore
+"     call Decho("case Nexplore: (indx=".indx.")")
+     if !exists("w:netrw_explore_list") " sanity check
+      call netrw#ErrorMsg(s:WARNING,"using Nexplore or <s-down> improperly; see help for netrw-starstar",40)
+      silent! let @* = keepregstar
+      silent! let @+ = keepregstar
+      silent! let @/ = keepregslash
+"      call Dret("netrw#Explore")
+      return
+     endif
+     let indx= w:netrw_explore_indx
+     if indx < 0                        | let indx= 0                           | endif
+     if indx >= w:netrw_explore_listlen | let indx= w:netrw_explore_listlen - 1 | endif
+     let curfile= w:netrw_explore_list[indx]
+"     call Decho("indx=".indx." curfile<".curfile.">")
+     while indx < w:netrw_explore_listlen && curfile == w:netrw_explore_list[indx]
+      let indx= indx + 1
+"      call Decho("indx=".indx." (Nexplore while loop)")
+     endwhile
+     if indx >= w:netrw_explore_listlen | let indx= w:netrw_explore_listlen - 1 | endif
+"     call Decho("Nexplore: indx= [w:netrw_explore_indx=".w:netrw_explore_indx."]=".indx)
+
+    elseif indx == -2
+     "Pexplore
+"     call Decho("case Pexplore: (indx=".indx.")")
+     if !exists("w:netrw_explore_list") " sanity check
+      call netrw#ErrorMsg(s:WARNING,"using Pexplore or <s-up> improperly; see help for netrw-starstar",41)
+      silent! let @* = keepregstar
+      silent! let @+ = keepregstar
+      silent! let @/ = keepregslash
+"      call Dret("netrw#Explore")
+      return
+     endif
+     let indx= w:netrw_explore_indx
+     if indx < 0                        | let indx= 0                           | endif
+     if indx >= w:netrw_explore_listlen | let indx= w:netrw_explore_listlen - 1 | endif
+     let curfile= w:netrw_explore_list[indx]
+"     call Decho("indx=".indx." curfile<".curfile.">")
+     while indx >= 0 && curfile == w:netrw_explore_list[indx]
+      let indx= indx - 1
+"      call Decho("indx=".indx." (Pexplore while loop)")
+     endwhile
+     if indx < 0                        | let indx= 0                           | endif
+"     call Decho("Pexplore: indx= [w:netrw_explore_indx=".w:netrw_explore_indx."]=".indx)
+
+    else
+     " Explore -- initialize
+     " build list of files to Explore with Nexplore/Pexplore
+"     call Decho("case Explore: initialize (indx=".indx.")")
+     let w:netrw_explore_indx= 0
+     if !exists("b:netrw_curdir")
+      let b:netrw_curdir= getcwd()
+     endif
+"     call Decho("b:netrw_curdir<".b:netrw_curdir.">")
+
+     if exists("pattern")
+"      call Decho("pattern exists: building list pattern<".pattern."> cwd<".getcwd().">")
+      if exists("starstarpat")
+"       call Decho("starstarpat<".starstarpat.">")
+       try
+        exe "silent vimgrep /".pattern."/gj "."**/*"
+       catch /^Vim\%((\a\+)\)\=:E480/
+       	call netrw#ErrorMsg(s:WARNING,'no files matched pattern<'.pattern.'>',45)
+        if &hls | let keepregslash= s:ExplorePatHls(pattern) | endif
+        silent! let @* = keepregstar
+        silent! let @+ = keepregstar
+	silent! let @/ = keepregslash
+"        call Dret("netrw#Explore : no files matched pattern")
+        return
+       endtry
+       let s:netrw_curdir       = b:netrw_curdir
+       let w:netrw_explore_list = getqflist()
+       let w:netrw_explore_list = map(w:netrw_explore_list,'s:netrw_curdir."/".bufname(v:val.bufnr)')
+      else
+"       call Decho("no starstarpat")
+       exe "vimgrep /".pattern."/gj ".b:netrw_curdir."/*"
+       let w:netrw_explore_list = map(getqflist(),'bufname(v:val.bufnr)')
+       if &hls | let keepregslash= s:ExplorePatHls(pattern) | endif
+      endif
+     else
+"      call Decho("no pattern: building list based on ".b:netrw_curdir."/".dirname)
+      let w:netrw_explore_list= split(expand(b:netrw_curdir."/".dirname),'\n')
+      if &hls | let keepregslash= s:ExplorePatHls(dirname) | endif
+     endif
+
+     let w:netrw_explore_listlen = len(w:netrw_explore_list)
+"     call Decho("w:netrw_explore_list<".string(w:netrw_explore_list)."> listlen=".w:netrw_explore_listlen)
+
+     if w:netrw_explore_listlen == 0 || (w:netrw_explore_listlen == 1 && w:netrw_explore_list[0] =~ '\*\*\/')
+      call netrw#ErrorMsg(s:WARNING,"no files matched",42)
+      silent! let @* = keepregstar
+      silent! let @+ = keepregstar
+      silent! let @/ = keepregslash
+"      call Dret("netrw#Explore : no files matched")
+      return
+     endif
+    endif
+
+    " NetrwStatusLine support - for exploring support
+    let w:netrw_explore_indx= indx
+"    call Decho("explorelist<".join(w:netrw_explore_list,',')."> len=".w:netrw_explore_listlen)
+
+    " wrap the indx around, but issue a note
+    if indx >= w:netrw_explore_listlen || indx < 0
+"     call Decho("wrap indx (indx=".indx." listlen=".w:netrw_explore_listlen.")")
+     let indx                = (indx < 0)? ( w:netrw_explore_listlen - 1 ) : 0
+     let w:netrw_explore_indx= indx
+     call netrw#ErrorMsg(s:NOTE,"no more files match Explore pattern",43)
+     sleep 1
+    endif
+
+    exe "let dirfile= w:netrw_explore_list[".indx."]"
+"    call Decho("dirfile=w:netrw_explore_list[indx=".indx."]= <".dirfile.">")
+    let newdir= substitute(dirfile,'/[^/]*$','','e')
+"    call Decho("newdir<".newdir.">")
+
+"    call Decho("calling LocalBrowseCheck(newdir<".newdir.">)")
+    call netrw#LocalBrowseCheck(newdir)
+    if !exists("w:netrw_liststyle")
+     let w:netrw_liststyle= g:netrw_liststyle
+    endif
+    if w:netrw_liststyle == s:THINLIST || w:netrw_liststyle == s:LONGLIST
+     call search('^'.substitute(dirfile,"^.*/","","").'\>',"W")
+    else
+     call search('\<'.substitute(dirfile,"^.*/","","").'\>',"w")
+    endif
+    let w:netrw_explore_mtchcnt = indx + 1
+    let w:netrw_explore_bufnr   = bufnr("%")
+    let w:netrw_explore_line    = line(".")
+    call s:SetupNetrwStatusLine('%f %h%m%r%=%9*%{NetrwStatusLine()}')
+"    call Decho("explore: mtchcnt=".w:netrw_explore_mtchcnt." bufnr=".w:netrw_explore_bufnr." line#".w:netrw_explore_line)
+
+   else
+"    call Decho("vim does not have path_extra")
+    if !exists("g:netrw_quiet")
+     call netrw#ErrorMsg(s:WARNING,"your vim needs the +path_extra feature for Exploring with **!",44)
+    endif
+    silent! let @* = keepregstar
+    silent! let @+ = keepregstar
+    silent! let @/ = keepregslash
+"    call Dret("netrw#Explore : missing +path_extra")
+    return
+   endif
+
+  else
+"   call Decho("case Explore newdir<".dirname.">")
+   if exists("w:netrw_liststyle") && w:netrw_liststyle == s:TREELIST && dirname =~ '/'
+    silent! unlet w:netrw_treedict
+    silent! unlet w:netrw_treetop
+   endif
+   let newdir= dirname
+   if !exists("b:netrw_curdir")
+    call netrw#LocalBrowseCheck(getcwd())
+   else
+    call netrw#LocalBrowseCheck(s:NetBrowseChgDir(1,newdir))
+   endif
+  endif
+
+  silent! let @* = keepregstar
+  silent! let @+ = keepregstar
+  silent! let @/ = keepregslash
+"  call Dret("netrw#Explore : @/<".@/.">")
+endfun
+
+" ---------------------------------------------------------------------
+" s:ExplorePatHls: converts an Explore pattern into a regular expression search pattern {{{2
+fun! s:ExplorePatHls(pattern)
+"  call Dfunc("s:ExplorePatHls(pattern<".a:pattern.">)")
+  let repat= substitute(a:pattern,'^**/\{1,2}','','')
+"  call Decho("repat<".repat.">")
+  let repat= escape(repat,'][.\')
+"  call Decho("repat<".repat.">")
+  let repat= '\<'.substitute(repat,'\*','\\(\\S\\+ \\)*\\S\\+','g').'\>'
+"  call Dret("s:ExplorePatHls repat<".repat.">")
+  return repat
+endfun
+
+" ---------------------------------------------------------------------
+" SetupNetrwStatusLine: {{{2
+fun! s:SetupNetrwStatusLine(statline)
+"  call Dfunc("SetupNetrwStatusLine(statline<".a:statline.">)")
+
+  if !exists("s:netrw_setup_statline")
+   let s:netrw_setup_statline= 1
+"   call Decho("do first-time status line setup")
+
+   if !exists("s:netrw_users_stl")
+    let s:netrw_users_stl= &stl
+   endif
+   if !exists("s:netrw_users_ls")
+    let s:netrw_users_ls= &laststatus
+   endif
+
+   " set up User9 highlighting as needed
+   let keepa= @a
+   redir @a
+   try
+    hi User9
+   catch /^Vim\%((\a\+)\)\=:E411/
+    if &bg == "dark"
+     hi User9 ctermfg=yellow ctermbg=blue guifg=yellow guibg=blue
+    else
+     hi User9 ctermbg=yellow ctermfg=blue guibg=yellow guifg=blue
+    endif
+   endtry
+   redir END
+   let @a= keepa
+  endif
+
+  " set up status line (may use User9 highlighting)
+  " insure that windows have a statusline
+  " make sure statusline is displayed
+  let &stl=a:statline
+  setlocal laststatus=2
+"  call Decho("stl=".&stl)
+  redraw!
+
+"  call Dret("SetupNetrwStatusLine : stl=".&stl)
+endfun
+
+" ---------------------------------------------------------------------
+" NetrwStatusLine: {{{2
+fun! NetrwStatusLine()
+
+" vvv NetrwStatusLine() debugging vvv
+"  let g:stlmsg=""
+"  if !exists("w:netrw_explore_bufnr")
+"   let g:stlmsg="!X<explore_bufnr>"
+"  elseif w:netrw_explore_bufnr != bufnr("%")
+"   let g:stlmsg="explore_bufnr!=".bufnr("%")
+"  endif
+"  if !exists("w:netrw_explore_line")
+"   let g:stlmsg=" !X<explore_line>"
+"  elseif w:netrw_explore_line != line(".")
+"   let g:stlmsg=" explore_line!={line(.)<".line(".").">"
+"  endif
+"  if !exists("w:netrw_explore_list")
+"   let g:stlmsg=" !X<explore_list>"
+"  endif
+" ^^^ NetrwStatusLine() debugging ^^^
+
+  if !exists("w:netrw_explore_bufnr") || w:netrw_explore_bufnr != bufnr("%") || !exists("w:netrw_explore_line") || w:netrw_explore_line != line(".") || !exists("w:netrw_explore_list")
+   " restore user's status line
+   let &stl        = s:netrw_users_stl
+   let &laststatus = s:netrw_users_ls
+   if exists("w:netrw_explore_bufnr")|unlet w:netrw_explore_bufnr|endif
+   if exists("w:netrw_explore_line")|unlet w:netrw_explore_line|endif
+   return ""
+  else
+   return "Match ".w:netrw_explore_mtchcnt." of ".w:netrw_explore_listlen
+  endif
+endfun
+
+" ---------------------------------------------------------------------
+" NetGetcwd: get the current directory. {{{2
+"   Change backslashes to forward slashes, if any.
+"   If doesc is true, escape certain troublesome characters
+fun! s:NetGetcwd(doesc)
+"  call Dfunc("NetGetcwd(doesc=".a:doesc.")")
+  let curdir= substitute(getcwd(),'\\','/','ge')
+  if curdir !~ '[\/]$'
+   let curdir= curdir.'/'
+  endif
+  if a:doesc
+   let curdir= escape(curdir,s:netrw_cd_escape)
+  endif
+"  call Dret("NetGetcwd <".curdir.">")
+  return curdir
+endfun
+
+" ---------------------------------------------------------------------
+" SetSort: sets up the sort based on the g:netrw_sort_sequence {{{2
+"          What this function does is to compute a priority for the patterns
+"          in the g:netrw_sort_sequence.  It applies a substitute to any
+"          "files" that satisfy each pattern, putting the priority / in
+"          front.  An "*" pattern handles the default priority.
+fun! s:SetSort()
+"  call Dfunc("SetSort() bannercnt=".w:netrw_bannercnt)
+  if w:netrw_liststyle == s:LONGLIST
+   let seqlist  = substitute(g:netrw_sort_sequence,'\$','\\%(\t\\|\$\\)','ge')
+  else
+   let seqlist  = g:netrw_sort_sequence
+  endif
+  " sanity check -- insure that * appears somewhere
+  if seqlist == ""
+   let seqlist= '*'
+  elseif seqlist !~ '\*'
+   let seqlist= seqlist.',*'
+  endif
+  let priority = 1
+  while seqlist != ""
+   if seqlist =~ ','
+    let seq     = substitute(seqlist,',.*$','','e')
+    let seqlist = substitute(seqlist,'^.\{-},\(.*\)$','\1','e')
+   else
+    let seq     = seqlist
+    let seqlist = ""
+   endif
+   let eseq= escape(seq,'/')
+   if priority < 10
+    let spriority= "00".priority.'\/'
+   elseif priority < 100
+    let spriority= "0".priority.'\/'
+   else
+    let spriority= priority.'\/'
+   endif
+"   call Decho("priority=".priority." spriority<".spriority."> seq<".seq."> seqlist<".seqlist.">")
+
+   " sanity check
+   if w:netrw_bannercnt > line("$")
+    " apparently no files were left after a Hiding pattern was used
+"    call Dret("SetSort : no files left after hiding")
+    return
+   endif
+   if seq == '*'
+    exe 'silent keepjumps '.w:netrw_bannercnt.',$v/^\d\{3}\//s/^/'.spriority.'/'
+   else
+    exe 'silent keepjumps '.w:netrw_bannercnt.',$g/'.eseq.'/s/^/'.spriority.'/'
+   endif
+   let priority = priority + 1
+  endwhile
+
+  " Following line associated with priority -- items that satisfy a priority
+  " pattern get prefixed by ###/ which permits easy sorting by priority.
+  " Sometimes files can satisfy multiple priority patterns -- only the latest
+  " priority pattern needs to be retained.  So, at this point, these excess
+  " priority prefixes need to be removed, but not directories that happen to
+  " be just digits themselves.
+  exe 'silent keepjumps '.w:netrw_bannercnt.',$s/^\(\d\{3}\/\)\%(\d\{3}\/\)\+\ze./\1/e'
+
+"  call Dret("SetSort")
+endfun
+
+" =====================================================================
+" Support Functions: {{{1
+
+" ---------------------------------------------------------------------
+"  ComposePath: Appends a new part to a path taking different systems into consideration {{{2
+fun! s:ComposePath(base,subdir)
+"  call Dfunc("s:ComposePath(base<".a:base."> subdir<".a:subdir.">)")
+  if(has("amiga"))
+   let ec = a:base[strlen(a:base)-1]
+   if ec != '/' && ec != ':'
+    let ret = a:base . "/" . a:subdir
+   else
+    let ret = a:base . a:subdir
+   endif
+  elseif a:base =~ '^\a\+://'
+   let urlbase = substitute(a:base,'^\(\a\+://.\{-}/\)\(.*\)$','\1','')
+   let curpath = substitute(a:base,'^\(\a\+://.\{-}/\)\(.*\)$','\2','')
+   let ret     = urlbase.curpath.a:subdir
+"   call Decho("urlbase<".urlbase.">")
+"   call Decho("curpath<".curpath.">")
+"   call Decho("ret<".ret.">")
+  else
+   let ret = substitute(a:base."/".a:subdir,"//","/","g")
+  endif
+"  call Dret("s:ComposePath ".ret)
+  return ret
+endfun
+
+" ---------------------------------------------------------------------
+" netrw#ErrorMsg: {{{2
+"   0=note     = s:NOTE
+"   1=warning  = s:WARNING
+"   2=error    = s:ERROR
+"   Mar 19, 2007 : max errnum currently is 49
+fun! netrw#ErrorMsg(level,msg,errnum)
+"  call Dfunc("netrw#ErrorMsg(level=".a:level." msg<".a:msg."> errnum=".a:errnum.") g:netrw_use_errorwindow=".g:netrw_use_errorwindow)
+
+  if a:level == 1
+   let level= "**warning** (netrw) "
+  elseif a:level == 2
+   let level= "**error** (netrw) "
+  else
+   let level= "**note** (netrw) "
+  endif
+
+  if g:netrw_use_errorwindow
+   " (default) netrw creates a one-line window to show error/warning
+   " messages (reliably displayed)
+
+   " record current window number for NetRestorePosn()'s benefit
+   let s:winBeforeErr= winnr()
+ 
+   " getting messages out reliably is just plain difficult!
+   " This attempt splits the current window, creating a one line window.
+   if bufexists("NetrwMessage") && bufwinnr("NetrwMessage") > 0
+    exe bufwinnr("NetrwMessage")."wincmd w"
+    set ma noro
+    call setline(line("$")+1,level.a:msg)
+    $
+   else
+    bo 1split
+    enew
+    setlocal bt=nofile
+    file NetrwMessage
+    call setline(line("$"),level.a:msg)
+   endif
+   if &fo !~ '[ta]'
+    syn clear
+    syn match netrwMesgNote	"^\*\*note\*\*"
+    syn match netrwMesgWarning	"^\*\*warning\*\*"
+    syn match netrwMesgError	"^\*\*error\*\*"
+    hi link netrwMesgWarning WarningMsg
+    hi link netrwMesgError   Error
+   endif
+   setlocal noma ro bh=wipe
+
+  else
+   " (optional) netrw will show messages using echomsg.  Even if the
+   " message doesn't appear, at least it'll be recallable via :messages
+   redraw!
+   if a:level == s:WARNING
+    echohl WarningMsg
+   elseif a:level == s:ERROR
+    echohl Error
+   endif
+   echomsg level.a:msg
+"   call Decho("echomsg ***netrw*** ".a:msg)
+   echohl None
+  endif
+
+"  call Dret("netrw#ErrorMsg")
+endfun
+
+" ---------------------------------------------------------------------
+"  netrw#RFC2396: converts %xx into characters {{{2
+fun! netrw#RFC2396(fname)
+"  call Dfunc("netrw#RFC2396(fname<".a:fname.">)")
+  let fname = escape(substitute(a:fname,'%\(\x\x\)','\=nr2char("0x".submatch(1))','ge')," \t")
+"  call Dret("netrw#RFC2396 ".fname)
+  return fname
+endfun
+
+" ---------------------------------------------------------------------
+" s:FileReadable: o/s independent filereadable {{{2
+fun! s:FileReadable(fname)
+"  call Dfunc("s:FileReadable(fname<".a:fname.">)")
+
+  if g:netrw_cygwin
+   let ret= filereadable(substitute(a:fname,'/cygdrive/\(.\)','\1:/',''))
+  else
+   let ret= filereadable(a:fname)
+  endif
+
+"  call Dret("s:FileReadable ".ret)
+  return ret
+endfun
+
+" ---------------------------------------------------------------------
+"  s:GetTempfile: gets a tempname that'll work for various o/s's {{{2
+"                 Places correct suffix on end of temporary filename,
+"                 using the suffix provided with fname
+fun! s:GetTempfile(fname)
+"  call Dfunc("s:GetTempfile(fname<".a:fname.">)")
+
+  if !exists("b:netrw_tmpfile")
+   " get a brand new temporary filename
+   let tmpfile= tempname()
+"   call Decho("tmpfile<".tmpfile."> : from tempname()")
+ 
+   let tmpfile= escape(substitute(tmpfile,'\','/','ge'),g:netrw_tmpfile_escape)
+"   call Decho("tmpfile<".tmpfile."> : chgd any \\ -> /")
+ 
+   " sanity check -- does the temporary file's directory exist?
+   if !isdirectory(substitute(tmpfile,'[^/]\+$','','e'))
+    call netrw#ErrorMsg(s:ERROR,"your <".substitute(tmpfile,'[^/]\+$','','e')."> directory is missing!",2)
+"    call Dret("s:GetTempfile getcwd<".getcwd().">")
+    return ""
+   endif
+ 
+   " let netrw#NetSource() know about the tmpfile
+   let s:netrw_tmpfile= tmpfile " used by netrw#NetSource()
+"   call Decho("tmpfile<".tmpfile."> s:netrw_tmpfile<".s:netrw_tmpfile.">")
+ 
+   " o/s dependencies
+   if g:netrw_cygwin == 1
+    let tmpfile = substitute(tmpfile,'^\(\a\):','/cygdrive/\1','e')
+   elseif has("win32") || has("win95") || has("win64") || has("win16")
+    let tmpfile = substitute(tmpfile,'/','\\','g')
+   else
+    let tmpfile = tmpfile  
+   endif
+   let b:netrw_tmpfile= tmpfile
+"   call Decho("o/s dependent fixed tempname<".tmpfile.">")
+  else
+   " re-use temporary filename
+   let tmpfile= b:netrw_tmpfile
+"   call Decho("tmpfile<".tmpfile."> re-using")
+  endif
+
+  " use fname's suffix for the temporary file
+  if a:fname != ""
+   if a:fname =~ '\.[^./]\+$'
+"    call Decho("using fname<".a:fname.">'s suffix")
+    if a:fname =~ '.tar.gz' || a:fname =~ '.tar.bz2'
+     let suffix = ".tar".substitute(a:fname,'^.*\(\.[^./]\+\)$','\1','e')
+    else
+     let suffix = substitute(a:fname,'^.*\(\.[^./]\+\)$','\1','e')
+    endif
+    let suffix = escape(suffix,g:netrw_tmpfile_escape)
+"    call Decho("suffix<".suffix.">")
+    let tmpfile= substitute(tmpfile,'\.tmp$','','e')
+"    call Decho("chgd tmpfile<".tmpfile."> (removed any .tmp suffix)")
+    let tmpfile .= suffix
+"    call Decho("chgd tmpfile<".tmpfile."> (added ".suffix." suffix) netrw_fname<".b:netrw_fname.">")
+    let s:netrw_tmpfile= tmpfile " supports netrw#NetSource()
+   endif
+  endif
+
+"  call Dret("s:GetTempfile <".tmpfile.">")
+  return tmpfile
+endfun  
+
+" ---------------------------------------------------------------------
+" s:MakeSshCmd: transforms input command using USEPORT HOSTNAME into {{{2
+"               a correct command
+fun! s:MakeSshCmd(sshcmd)
+"  call Dfunc("s:MakeSshCmd(sshcmd<".a:sshcmd.">)")
+  let sshcmd = substitute(a:sshcmd,'\<HOSTNAME\>',s:user.s:machine,'')
+  if exists("g:netrw_port") && g:netrw_port != ""
+   let sshcmd= substitute(sshcmd,"USEPORT",g:netrw_sshport.' '.g:netrw_port,'')
+  elseif exists("s:port") && s:port != ""
+   let sshcmd= substitute(sshcmd,"USEPORT",g:netrw_sshport.' '.s:port,'')
+  else
+   let sshcmd= substitute(sshcmd,"USEPORT ",'','')
+  endif
+"  call Dret("s:MakeSshCmd <".sshcmd.">")
+  return sshcmd
+endfun
+
+" ---------------------------------------------------------------------
+" s:NetrwEnew: opens a new buffer, passes netrw buffer variables through {{{2
+fun! s:NetrwEnew(curdir)
+"  call Dfunc("s:NetrwEnew(curdir<".a:curdir.">) buf#".bufnr("%")."<".bufname("%").">")
+
+  " grab a function-local copy of buffer variables
+  if exists("b:netrw_bannercnt")      |let netrw_bannercnt       = b:netrw_bannercnt      |endif
+  if exists("b:netrw_browser_active") |let netrw_browser_active  = b:netrw_browser_active |endif
+  if exists("b:netrw_cpf")            |let netrw_cpf             = b:netrw_cpf            |endif
+  if exists("b:netrw_curdir")         |let netrw_curdir          = b:netrw_curdir         |endif
+  if exists("b:netrw_explore_bufnr")  |let netrw_explore_bufnr   = b:netrw_explore_bufnr  |endif
+  if exists("b:netrw_explore_indx")   |let netrw_explore_indx    = b:netrw_explore_indx   |endif
+  if exists("b:netrw_explore_line")   |let netrw_explore_line    = b:netrw_explore_line   |endif
+  if exists("b:netrw_explore_list")   |let netrw_explore_list    = b:netrw_explore_list   |endif
+  if exists("b:netrw_explore_listlen")|let netrw_explore_listlen = b:netrw_explore_listlen|endif
+  if exists("b:netrw_explore_mtchcnt")|let netrw_explore_mtchcnt = b:netrw_explore_mtchcnt|endif
+  if exists("b:netrw_fname")          |let netrw_fname           = b:netrw_fname          |endif
+  if exists("b:netrw_lastfile")       |let netrw_lastfile        = b:netrw_lastfile       |endif
+  if exists("b:netrw_liststyle")      |let netrw_liststyle       = b:netrw_liststyle      |endif
+  if exists("b:netrw_method")         |let netrw_method          = b:netrw_method         |endif
+  if exists("b:netrw_option")         |let netrw_option          = b:netrw_option         |endif
+  if exists("b:netrw_prvdir")         |let netrw_prvdir          = b:netrw_prvdir         |endif
+
+  if getline(2) =~ '^" Netrw Directory Listing'
+"   call Decho("generate a buffer with keepjumps keepalt enew! (1)")
+   keepjumps keepalt enew!
+  else
+"   call Decho("generate a buffer with keepjumps enew! (2)")
+   keepjumps enew!
+  endif
+
+  " copy function-local variables to buffer variable equivalents
+  if exists("netrw_bannercnt")      |let b:netrw_bannercnt       = netrw_bannercnt      |endif
+  if exists("netrw_browser_active") |let b:netrw_browser_active  = netrw_browser_active |endif
+  if exists("netrw_cpf")            |let b:netrw_cpf             = netrw_cpf            |endif
+  if exists("netrw_curdir")         |let b:netrw_curdir          = netrw_curdir         |endif
+  if exists("netrw_explore_bufnr")  |let b:netrw_explore_bufnr   = netrw_explore_bufnr  |endif
+  if exists("netrw_explore_indx")   |let b:netrw_explore_indx    = netrw_explore_indx   |endif
+  if exists("netrw_explore_line")   |let b:netrw_explore_line    = netrw_explore_line   |endif
+  if exists("netrw_explore_list")   |let b:netrw_explore_list    = netrw_explore_list   |endif
+  if exists("netrw_explore_listlen")|let b:netrw_explore_listlen = netrw_explore_listlen|endif
+  if exists("netrw_explore_mtchcnt")|let b:netrw_explore_mtchcnt = netrw_explore_mtchcnt|endif
+  if exists("netrw_fname")          |let b:netrw_fname           = netrw_fname          |endif
+  if exists("netrw_lastfile")       |let b:netrw_lastfile        = netrw_lastfile       |endif
+  if exists("netrw_liststyle")      |let b:netrw_liststyle       = netrw_liststyle      |endif
+  if exists("netrw_method")         |let b:netrw_method          = netrw_method         |endif
+  if exists("netrw_option")         |let b:netrw_option          = netrw_option         |endif
+  if exists("netrw_prvdir")         |let b:netrw_prvdir          = netrw_prvdir         |endif
+
+  let b:netrw_curdir= a:curdir
+  if b:netrw_curdir =~ '/$'
+   if exists("w:netrw_liststyle") && w:netrw_liststyle == s:TREELIST
+    file NetrwTreeListing
+   else
+    exe "silent! file ".b:netrw_curdir
+   endif
+  endif
+
+"  call Dret("s:NetrwEnew : buf#".bufnr("%")."<".bufname("%").">")
+endfun
+
+" ------------------------------------------------------------------------
+" s:RemotePathAnalysis: {{{2
+fun! s:RemotePathAnalysis(dirname)
+"  call Dfunc("s:RemotePathAnalysis()")
+
+  let dirpat  = '^\(\w\{-}\)://\(\w\+@\)\=\([^/:#]\+\)\%([:#]\(\d\+\)\)\=/\(.*\)$'
+  let s:method  = substitute(a:dirname,dirpat,'\1','')
+  let s:user    = substitute(a:dirname,dirpat,'\2','')
+  let s:machine = substitute(a:dirname,dirpat,'\3','')
+  let s:port    = substitute(a:dirname,dirpat,'\4','')
+  let s:path    = substitute(a:dirname,dirpat,'\5','')
+  let s:fname   = substitute(a:dirname,'^.*/\ze.','','')
+
+"  call Decho("set up s:method <".s:method .">")
+"  call Decho("set up s:user   <".s:user   .">")
+"  call Decho("set up s:machine<".s:machine.">")
+"  call Decho("set up s:port   <".s:port.">")
+"  call Decho("set up s:path   <".s:path   .">")
+"  call Decho("set up s:fname  <".s:fname  .">")
+
+"  call Dret("s:RemotePathAnalysis")
+endfun
+
+" ---------------------------------------------------------------------
+" s:RestoreBufVars: {{{2
+fun! s:RestoreBufVars()
+"  call Dfunc("s:RestoreBufVars()")
+
+  if exists("s:netrw_curdir")        |let b:netrw_curdir         = s:netrw_curdir        |endif
+  if exists("s:netrw_lastfile")      |let b:netrw_lastfile       = s:netrw_lastfile      |endif
+  if exists("s:netrw_method")        |let b:netrw_method         = s:netrw_method        |endif
+  if exists("s:netrw_fname")         |let b:netrw_fname          = s:netrw_fname         |endif
+  if exists("s:netrw_machine")       |let b:netrw_machine        = s:netrw_machine       |endif
+  if exists("s:netrw_browser_active")|let b:netrw_browser_active = s:netrw_browser_active|endif
+
+"  call Dret("s:RestoreBufVars")
+endfun
+
+" ---------------------------------------------------------------------
+" s:RestoreWinVars: (used by Explore() and NetSplit()) {{{2
+fun! s:RestoreWinVars()
+"  call Dfunc("s:RestoreWinVars()")
+  if exists("s:bannercnt")      |let w:netrw_bannercnt       = s:bannercnt      |unlet s:bannercnt      |endif
+  if exists("s:col")            |let w:netrw_col             = s:col            |unlet s:col            |endif
+  if exists("s:curdir")         |let w:netrw_curdir          = s:curdir         |unlet s:curdir         |endif
+  if exists("s:explore_bufnr")  |let w:netrw_explore_bufnr   = s:explore_bufnr  |unlet s:explore_bufnr  |endif
+  if exists("s:explore_indx")   |let w:netrw_explore_indx    = s:explore_indx   |unlet s:explore_indx   |endif
+  if exists("s:explore_line")   |let w:netrw_explore_line    = s:explore_line   |unlet s:explore_line   |endif
+  if exists("s:explore_listlen")|let w:netrw_explore_listlen = s:explore_listlen|unlet s:explore_listlen|endif
+  if exists("s:explore_list")   |let w:netrw_explore_list    = s:explore_list   |unlet s:explore_list   |endif
+  if exists("s:explore_mtchcnt")|let w:netrw_explore_mtchcnt = s:explore_mtchcnt|unlet s:explore_mtchcnt|endif
+  if exists("s:fpl")            |let w:netrw_fpl             = s:fpl            |unlet s:fpl            |endif
+  if exists("s:hline")          |let w:netrw_hline           = s:hline          |unlet s:hline          |endif
+  if exists("s:line")           |let w:netrw_line            = s:line           |unlet s:line           |endif
+  if exists("s:liststyle")      |let w:netrw_liststyle       = s:liststyle      |unlet s:liststyle      |endif
+  if exists("s:method")         |let w:netrw_method          = s:method         |unlet s:method         |endif
+  if exists("s:prvdir")         |let w:netrw_prvdir          = s:prvdir         |unlet s:prvdir         |endif
+  if exists("s:treedict")       |let w:netrw_treedict        = s:treedict       |unlet s:treedict       |endif
+  if exists("s:treetop")        |let w:netrw_treetop         = s:treetop        |unlet s:treetop        |endif
+  if exists("s:winnr")          |let w:netrw_winnr           = s:winnr          |unlet s:winnr          |endif
+"  call Dret("s:RestoreWinVars")
+endfun
+
+" ---------------------------------------------------------------------
+" s:SaveBufVars: {{{2
+fun! s:SaveBufVars()
+"  call Dfunc("s:SaveBufVars()")
+
+  if exists("b:netrw_curdir")        |let s:netrw_curdir         = b:netrw_curdir        |endif
+  if exists("b:netrw_lastfile")      |let s:netrw_lastfile       = b:netrw_lastfile      |endif
+  if exists("b:netrw_method")        |let s:netrw_method         = b:netrw_method        |endif
+  if exists("b:netrw_fname")         |let s:netrw_fname          = b:netrw_fname         |endif
+  if exists("b:netrw_machine")       |let s:netrw_machine        = b:netrw_machine       |endif
+  if exists("b:netrw_browser_active")|let s:netrw_browser_active = b:netrw_browser_active|endif
+
+"  call Dret("s:SaveBufVars")
+endfun
+
+" ---------------------------------------------------------------------
+" s:SaveWinVars: (used by Explore() and NetSplit()) {{{2
+fun! s:SaveWinVars()
+"  call Dfunc("s:SaveWinVars()")
+  if exists("w:netrw_bannercnt")      |let s:bannercnt       = w:netrw_bannercnt      |endif
+  if exists("w:netrw_col")            |let s:col             = w:netrw_col            |endif
+  if exists("w:netrw_curdir")         |let s:curdir          = w:netrw_curdir         |endif
+  if exists("w:netrw_explore_bufnr")  |let s:explore_bufnr   = w:netrw_explore_bufnr  |endif
+  if exists("w:netrw_explore_indx")   |let s:explore_indx    = w:netrw_explore_indx   |endif
+  if exists("w:netrw_explore_line")   |let s:explore_line    = w:netrw_explore_line   |endif
+  if exists("w:netrw_explore_listlen")|let s:explore_listlen = w:netrw_explore_listlen|endif
+  if exists("w:netrw_explore_list")   |let s:explore_list    = w:netrw_explore_list   |endif
+  if exists("w:netrw_explore_mtchcnt")|let s:explore_mtchcnt = w:netrw_explore_mtchcnt|endif
+  if exists("w:netrw_fpl")            |let s:fpl             = w:netrw_fpl            |endif
+  if exists("w:netrw_hline")          |let s:hline           = w:netrw_hline          |endif
+  if exists("w:netrw_line")           |let s:line            = w:netrw_line           |endif
+  if exists("w:netrw_liststyle")      |let s:liststyle       = w:netrw_liststyle      |endif
+  if exists("w:netrw_method")         |let s:method          = w:netrw_method         |endif
+  if exists("w:netrw_prvdir")         |let s:prvdir          = w:netrw_prvdir         |endif
+  if exists("w:netrw_treedict")       |let s:treedict        = w:netrw_treedict       |endif
+  if exists("w:netrw_treetop")        |let s:treetop         = w:netrw_treetop        |endif
+  if exists("w:netrw_winnr")          |let s:winnr           = w:netrw_winnr          |endif
+"  call Dret("s:SaveWinVars")
+endfun
+
+" ---------------------------------------------------------------------
+" s:SetBufWinVars: (used by NetBrowse() and LocalBrowseCheck()) {{{2
+"   To allow separate windows to have their own activities, such as
+"   Explore **/pattern, several variables have been made window-oriented.
+"   However, when the user splits a browser window (ex: ctrl-w s), these
+"   variables are not inherited by the new window.  SetBufWinVars() and
+"   UseBufWinVars() get around that.
+fun! s:SetBufWinVars()
+"  call Dfunc("s:SetBufWinVars()")
+  if exists("w:netrw_liststyle")      |let b:netrw_liststyle      = w:netrw_liststyle      |endif
+  if exists("w:netrw_bannercnt")      |let b:netrw_bannercnt      = w:netrw_bannercnt      |endif
+  if exists("w:netrw_method")         |let b:netrw_method         = w:netrw_method         |endif
+  if exists("w:netrw_prvdir")         |let b:netrw_prvdir         = w:netrw_prvdir         |endif
+  if exists("w:netrw_explore_indx")   |let b:netrw_explore_indx   = w:netrw_explore_indx   |endif
+  if exists("w:netrw_explore_listlen")|let b:netrw_explore_listlen= w:netrw_explore_listlen|endif
+  if exists("w:netrw_explore_mtchcnt")|let b:netrw_explore_mtchcnt= w:netrw_explore_mtchcnt|endif
+  if exists("w:netrw_explore_bufnr")  |let b:netrw_explore_bufnr  = w:netrw_explore_bufnr  |endif
+  if exists("w:netrw_explore_line")   |let b:netrw_explore_line   = w:netrw_explore_line   |endif
+  if exists("w:netrw_explore_list")   |let b:netrw_explore_list   = w:netrw_explore_list   |endif
+"  call Dret("s:SetBufWinVars")
+endfun
+
+" ---------------------------------------------------------------------
+" s:System: using Steve Hall's idea to insure that Windows paths stay {{{2
+"              acceptable.  No effect on Unix paths.
+"  Examples of use:  let result= s:System("system",path)
+"                    let result= s:System("delete",path)
+fun! s:System(cmd,path)
+"  call Dfunc("s:System(cmd<".a:cmd."> path<".a:path.">)")
+
+  let path = a:path
+  if (has("win32") || has("win95") || has("win64") || has("win16"))
+   " system call prep
+   " remove trailing slash (Win95)
+   let path = substitute(path, '\(\\\|/\)$', '', 'g')
+   " remove escaped spaces
+   let path = substitute(path, '\ ', ' ', 'g')
+   " convert slashes to backslashes
+   let path = substitute(path, '/', '\', 'g')
+   if exists("+shellslash")
+    let sskeep= &shellslash
+    setlocal noshellslash
+    exe "let result= ".a:cmd."('".path."')"
+    let &shellslash = sskeep
+   else
+    exe "let result= ".a:cmd."(".g:netrw_shq.path.g:netrw_shq.")"
+   endif
+  else
+   exe "let result= ".a:cmd."('".path."')"
+  endif
+
+"  call Decho("result<".result.">")
+"  call Dret("s:System")
+  return result
+endfun
+
+" ---------------------------------------------------------------------
+" s:UseBufWinVars: (used by NetBrowse() and LocalBrowseCheck() {{{2
+"              Matching function to BufferWinVars()
+fun! s:UseBufWinVars()
+"  call Dfunc("s:UseBufWinVars()")
+  if exists("b:netrw_liststyle")       && !exists("w:netrw_liststyle")      |let w:netrw_liststyle       = b:netrw_liststyle      |endif
+  if exists("b:netrw_bannercnt")       && !exists("w:netrw_bannercnt")      |let w:netrw_bannercnt       = b:netrw_bannercnt      |endif
+  if exists("b:netrw_method")          && !exists("w:netrw_method")         |let w:netrw_method          = b:netrw_method         |endif
+  if exists("b:netrw_prvdir")          && !exists("w:netrw_prvdir")         |let w:netrw_prvdir          = b:netrw_prvdir         |endif
+  if exists("b:netrw_explore_indx")    && !exists("w:netrw_explore_indx")   |let w:netrw_explore_indx    = b:netrw_explore_indx   |endif
+  if exists("b:netrw_explore_listlen") && !exists("w:netrw_explore_listlen")|let w:netrw_explore_listlen = b:netrw_explore_listlen|endif
+  if exists("b:netrw_explore_mtchcnt") && !exists("w:netrw_explore_mtchcnt")|let w:netrw_explore_mtchcnt = b:netrw_explore_mtchcnt|endif
+  if exists("b:netrw_explore_bufnr")   && !exists("w:netrw_explore_bufnr")  |let w:netrw_explore_bufnr   = b:netrw_explore_bufnr  |endif
+  if exists("b:netrw_explore_line")    && !exists("w:netrw_explore_line")   |let w:netrw_explore_line    = b:netrw_explore_line   |endif
+  if exists("b:netrw_explore_list")    && !exists("w:netrw_explore_list")   |let w:netrw_explore_list    = b:netrw_explore_list   |endif
+"  call Dret("s:UseBufWinVars")
+endfun
+
+" ---------------------------------------------------------------------
+" Settings Restoration: {{{2
+let &cpo= s:keepcpo
+unlet s:keepcpo
+
+" ------------------------------------------------------------------------
+" Modelines: {{{1
+" vim:ts=8 fdm=marker
--- /dev/null
+++ b/lib/vimfiles/autoload/netrwFileHandlers.vim
@@ -1,0 +1,355 @@
+" netrwFileHandlers: contains various extension-based file handlers for
+"                    netrw's browsers' x command ("eXecute launcher")
+" Author:	Charles E. Campbell, Jr.
+" Date:		May 30, 2006
+" Version:	9
+" Copyright:    Copyright (C) 1999-2005 Charles E. Campbell, Jr. {{{1
+"               Permission is hereby granted to use and distribute this code,
+"               with or without modifications, provided that this copyright
+"               notice is copied with it. Like anything else that's free,
+"               netrwFileHandlers.vim is provided *as is* and comes with no
+"               warranty of any kind, either expressed or implied. In no
+"               event will the copyright holder be liable for any damages
+"               resulting from the use of this software.
+"
+" Rom 6:23 (WEB) For the wages of sin is death, but the free gift of God {{{1
+"                is eternal life in Christ Jesus our Lord.
+
+" ---------------------------------------------------------------------
+" Load Once: {{{1
+if exists("g:loaded_netrwFileHandlers") || &cp
+ finish
+endif
+let s:keepcpo= &cpo
+set cpo&vim
+let g:loaded_netrwFileHandlers= "v9"
+
+" ---------------------------------------------------------------------
+" netrwFileHandlers#Invoke: {{{1
+fun! netrwFileHandlers#Invoke(exten,fname)
+"  call Dfunc("netrwFileHandlers#Invoke(exten<".a:exten."> fname<".a:fname.">)")
+  let fname= a:fname
+  " list of supported special characters.  Consider rcs,v --- that can be
+  " supported with a NFH_rcsCOMMAv() handler
+  if a:fname =~ '[@:,$!=\-+%?;~]'
+   let specials= {
+\   '@' : 'AT',
+\   ':' : 'COLON',
+\   ',' : 'COMMA',
+\   '$' : 'DOLLAR',
+\   '!' : 'EXCLAMATION',
+\   '=' : 'EQUAL',
+\   '-' : 'MINUS',
+\   '+' : 'PLUS',
+\   '%' : 'PERCENT',
+\   '?' : 'QUESTION',
+\   ';' : 'SEMICOLON',
+\   '~' : 'TILDE'}
+   let fname= substitute(a:fname,'[@:,$!=\-+%?;~]','\=specials[submatch(0)]','ge')
+"   call Decho('fname<'.fname.'> done with dictionary')
+  endif
+
+  if a:exten != "" && exists("*NFH_".a:exten)
+   " support user NFH_*() functions
+"   call Decho("let ret= netrwFileHandlers#NFH_".a:exten.'("'.fname.'")')
+   exe "let ret= NFH_".a:exten.'("'.fname.'")'
+  elseif a:exten != "" && exists("*s:NFH_".a:exten)
+   " use builtin-NFH_*() functions
+"   call Decho("let ret= netrwFileHandlers#NFH_".a:exten.'("'.fname.'")')
+   exe "let ret= s:NFH_".a:exten.'("'.fname.'")'
+  endif
+  
+"  call Dret("netrwFileHandlers#Invoke 0 : ret=".ret)
+  return 0
+endfun
+
+" ---------------------------------------------------------------------
+" s:NFH_html: handles html when the user hits "x" when the {{{1
+"                        cursor is atop a *.html file
+fun! s:NFH_html(pagefile)
+"  call Dfunc("s:NFH_html(".a:pagefile.")")
+
+  let page= substitute(a:pagefile,'^','file://','')
+
+  if executable("mozilla")
+"   call Decho("executing !mozilla ".page)
+   exe "!mozilla ".g:netrw_shq.page.g:netrw_shq
+  elseif executable("netscape")
+"   call Decho("executing !netscape ".page)
+   exe "!netscape ".g:netrw_shq..page.g:netrw_shq
+  else
+"   call Dret("s:NFH_html 0")
+   return 0
+  endif
+
+"  call Dret("s:NFH_html 1")
+  return 1
+endfun
+
+" ---------------------------------------------------------------------
+" s:NFH_htm: handles html when the user hits "x" when the {{{1
+"                        cursor is atop a *.htm file
+fun! s:NFH_htm(pagefile)
+"  call Dfunc("s:NFH_htm(".a:pagefile.")")
+
+  let page= substitute(a:pagefile,'^','file://','')
+
+  if executable("mozilla")
+"   call Decho("executing !mozilla ".page)
+   exe "!mozilla ".g:netrw_shq.page.g:netrw_shq
+  elseif executable("netscape")
+"   call Decho("executing !netscape ".page)
+   exe "!netscape ".g:netrw_shq.page.g:netrw_shq
+  else
+"   call Dret("s:NFH_htm 0")
+   return 0
+  endif
+
+"  call Dret("s:NFH_htm 1")
+  return 1
+endfun
+
+" ---------------------------------------------------------------------
+" s:NFH_jpg: {{{1
+fun! s:NFH_jpg(jpgfile)
+"  call Dfunc("s:NFH_jpg(jpgfile<".a:jpgfile.">)")
+
+  if executable("gimp")
+   exe "silent! !gimp -s ".g:netrw_shq.a:jpgfile.g:netrw_shq
+  elseif executable(expand("$SystemRoot")."/SYSTEM32/MSPAINT.EXE")
+"   call Decho("silent! !".expand("$SystemRoot")."/SYSTEM32/MSPAINT ".escape(a:jpgfile," []|'"))
+   exe "!".expand("$SystemRoot")."/SYSTEM32/MSPAINT ".g:netrw_shq.a:jpgfile.g:netrw_shq
+  else
+"   call Dret("s:NFH_jpg 0")
+   return 0
+  endif
+
+"  call Dret("s:NFH_jpg 1")
+  return 1
+endfun
+
+" ---------------------------------------------------------------------
+" s:NFH_gif: {{{1
+fun! s:NFH_gif(giffile)
+"  call Dfunc("s:NFH_gif(giffile<".a:giffile.">)")
+
+  if executable("gimp")
+   exe "silent! !gimp -s ".g:netrw_shq.a:giffile.g:netrw_shq
+  elseif executable(expand("$SystemRoot")."/SYSTEM32/MSPAINT.EXE")
+   exe "silent! !".expand("$SystemRoot")."/SYSTEM32/MSPAINT ".g:netrw_shq.a:giffile.g:netrw_shq
+  else
+"   call Dret("s:NFH_gif 0")
+   return 0
+  endif
+
+"  call Dret("s:NFH_gif 1")
+  return 1
+endfun
+
+" ---------------------------------------------------------------------
+" s:NFH_png: {{{1
+fun! s:NFH_png(pngfile)
+"  call Dfunc("s:NFH_png(pngfile<".a:pngfile.">)")
+
+  if executable("gimp")
+   exe "silent! !gimp -s ".g:netrw_shq.a:pngfile.g:netrw_shq
+  elseif executable(expand("$SystemRoot")."/SYSTEM32/MSPAINT.EXE")
+   exe "silent! !".expand("$SystemRoot")."/SYSTEM32/MSPAINT ".g:netrw_shq.a:pngfile.g:netrw_shq
+  else
+"   call Dret("s:NFH_png 0")
+   return 0
+  endif
+
+"  call Dret("s:NFH_png 1")
+  return 1
+endfun
+
+" ---------------------------------------------------------------------
+" s:NFH_pnm: {{{1
+fun! s:NFH_pnm(pnmfile)
+"  call Dfunc("s:NFH_pnm(pnmfile<".a:pnmfile.">)")
+
+  if executable("gimp")
+   exe "silent! !gimp -s ".g:netrw_shq.a:pnmfile.g:netrw_shq
+  elseif executable(expand("$SystemRoot")."/SYSTEM32/MSPAINT.EXE")
+   exe "silent! !".expand("$SystemRoot")."/SYSTEM32/MSPAINT ".g:netrw_shq.a:pnmfile.g:netrw_shq
+  else
+"   call Dret("s:NFH_pnm 0")
+   return 0
+  endif
+
+"  call Dret("s:NFH_pnm 1")
+  return 1
+endfun
+
+" ---------------------------------------------------------------------
+" s:NFH_bmp: visualize bmp files {{{1
+fun! s:NFH_bmp(bmpfile)
+"  call Dfunc("s:NFH_bmp(bmpfile<".a:bmpfile.">)")
+
+  if executable("gimp")
+   exe "silent! !gimp -s ".a:bmpfile
+  elseif executable(expand("$SystemRoot")."/SYSTEM32/MSPAINT.EXE")
+   exe "silent! !".expand("$SystemRoot")."/SYSTEM32/MSPAINT ".g:netrw_shq.a:bmpfile.g:netrw_shq
+  else
+"   call Dret("s:NFH_bmp 0")
+   return 0
+  endif
+
+"  call Dret("s:NFH_bmp 1")
+  return 1
+endfun
+
+" ---------------------------------------------------------------------
+" s:NFH_pdf: visualize pdf files {{{1
+fun! s:NFH_pdf(pdf)
+"  call Dfunc("s:NFH_pdf(pdf<".a:pdf.">)")
+  if executable("gs")
+   exe 'silent! !gs '.g:netrw_shq.a:pdf.g:netrw_shq
+  elseif executable("pdftotext")
+   exe 'silent! pdftotext -nopgbrk '.g:netrw_shq.a:pdf.g:netrw_shq
+  else
+"  call Dret("s:NFH_pdf 0")
+   return 0
+  endif
+
+"  call Dret("s:NFH_pdf 1")
+  return 1
+endfun
+
+" ---------------------------------------------------------------------
+" s:NFH_doc: visualize doc files {{{1
+fun! s:NFH_doc(doc)
+"  call Dfunc("s:NFH_doc(doc<".a:doc.">)")
+
+  if executable("oowriter")
+   exe 'silent! !oowriter '.g:netrw_shq.a:doc.g:netrw_shq
+   redraw!
+  else
+"  call Dret("s:NFH_doc 0")
+   return 0
+  endif
+
+"  call Dret("s:NFH_doc 1")
+  return 1
+endfun
+
+" ---------------------------------------------------------------------
+" s:NFH_sxw: visualize sxw files {{{1
+fun! s:NFH_sxw(sxw)
+"  call Dfunc("s:NFH_sxw(sxw<".a:sxw.">)")
+
+  if executable("oowriter")
+   exe 'silent! !oowriter '.g:netrw_shq.a:sxw.g:netrw_shq
+   redraw!
+  else
+"   call Dret("s:NFH_sxw 0")
+   return 0
+  endif
+
+"  call Dret("s:NFH_sxw 1")
+  return 1
+endfun
+
+" ---------------------------------------------------------------------
+" s:NFH_xls: visualize xls files {{{1
+fun! s:NFH_xls(xls)
+"  call Dfunc("s:NFH_xls(xls<".a:xls.">)")
+
+  if executable("oocalc")
+   exe 'silent! !oocalc '.g:netrw_shq.a:xls.g:netrw_shq
+   redraw!
+  else
+"  call Dret("s:NFH_xls 0")
+   return 0
+  endif
+
+"  call Dret("s:NFH_xls 1")
+  return 1
+endfun
+
+" ---------------------------------------------------------------------
+" s:NFH_ps: handles PostScript files {{{1
+fun! s:NFH_ps(ps)
+"  call Dfunc("s:NFH_ps(ps<".a:ps.">)")
+  if executable("gs")
+"   call Decho("exe silent! !gs ".a:ps)
+   exe "silent! !gs ".g:netrw_shq.a:ps.g:netrw_shq
+   redraw!
+  elseif executable("ghostscript")
+"   call Decho("exe silent! !ghostscript ".a:ps)
+   exe "silent! !ghostscript ".g:netrw_shq.a:ps.g:netrw_shq
+   redraw!
+  elseif executable("gswin32")
+"   call Decho("exe silent! !gswin32 ".g:netrw_shq.a:ps.g:netrw_shq)
+   exe "silent! !gswin32 ".g:netrw_shq.a:ps.g:netrw_shq
+   redraw!
+  else
+"   call Dret("s:NFH_ps 0")
+   return 0
+  endif
+
+"  call Dret("s:NFH_ps 1")
+  return 1
+endfun
+
+" ---------------------------------------------------------------------
+" s:NFH_eps: handles encapsulated PostScript files {{{1
+fun! s:NFH_eps(eps)
+"  call Dfunc("s:NFH_eps()")
+  if executable("gs")
+   exe "silent! !gs ".g:netrw_shq.a:eps.g:netrw_shq
+   redraw!
+  elseif executable("ghostscript")
+   exe "silent! !ghostscript ".g:netrw_shq.a:eps.g:netrw_shq
+   redraw!
+  elseif executable("ghostscript")
+   exe "silent! !ghostscript ".g:netrw_shq.a:eps.g:netrw_shq
+   redraw!
+  elseif executable("gswin32")
+   exe "silent! !gswin32 ".g:netrw_shq.a:eps.g:netrw_shq
+   redraw!
+  else
+"   call Dret("s:NFH_eps 0")
+   return 0
+  endif
+"  call Dret("s:NFH_eps 0")
+  return 1
+endfun
+
+" ---------------------------------------------------------------------
+" s:NFH_fig: handles xfig files {{{1
+fun! s:NFH_fig(fig)
+"  call Dfunc("s:NFH_fig()")
+  if executable("xfig")
+   exe "silent! !xfig ".a:fig
+   redraw!
+  else
+"   call Dret("s:NFH_fig 0")
+   return 0
+  endif
+
+"  call Dret("s:NFH_fig 1")
+  return 1
+endfun
+
+" ---------------------------------------------------------------------
+" s:NFH_obj: handles tgif's obj files {{{1
+fun! s:NFH_obj(obj)
+"  call Dfunc("s:NFH_obj()")
+  if has("unix") && executable("tgif")
+   exe "silent! !tgif ".a:obj
+   redraw!
+  else
+"   call Dret("s:NFH_obj 0")
+   return 0
+  endif
+
+"  call Dret("s:NFH_obj 1")
+  return 1
+endfun
+
+let &cpo= s:keepcpo
+" ---------------------------------------------------------------------
+"  Modelines: {{{1
+"  vim: fdm=marker
--- /dev/null
+++ b/lib/vimfiles/autoload/netrwSettings.vim
@@ -1,0 +1,189 @@
+" netrwSettings.vim: makes netrw settings simpler
+" Date:		Mar 26, 2007
+" Maintainer:	Charles E Campbell, Jr <drchipNOSPAM at campbellfamily dot biz>
+" Version:	9
+" Copyright:    Copyright (C) 1999-2007 Charles E. Campbell, Jr. {{{1
+"               Permission is hereby granted to use and distribute this code,
+"               with or without modifications, provided that this copyright
+"               notice is copied with it. Like anything else that's free,
+"               netrwSettings.vim is provided *as is* and comes with no
+"               warranty of any kind, either expressed or implied. By using
+"               this plugin, you agree that in no event will the copyright
+"               holder be liable for any damages resulting from the use
+"               of this software.
+"
+" Mat 4:23 (WEB) Jesus went about in all Galilee, teaching in their {{{1
+"                synagogues, preaching the gospel of the kingdom, and healing
+"                every disease and every sickness among the people.
+" Load Once: {{{1
+if exists("g:loaded_netrwSettings") || &cp
+  finish
+endif
+let g:loaded_netrwSettings  = "v9"
+
+" ---------------------------------------------------------------------
+" NetrwSettings: {{{1
+fun! netrwSettings#NetrwSettings()
+  " this call is here largely just to insure that netrw has been loaded
+  call netrw#NetSavePosn()
+  if !exists("g:loaded_netrw")
+   echohl WarningMsg | echomsg "***sorry*** netrw needs to be loaded prior to using NetrwSettings" | echohl None
+   return
+  endif
+
+  above wincmd s
+  enew
+  setlocal noswapfile bh=wipe
+  set ft=vim
+  file Netrw\ Settings
+
+  " these variables have the following default effects when they don't
+  " exist (ie. have not been set by the user in his/her .vimrc)
+  if !exists("g:netrw_liststyle")
+   let g:netrw_liststyle= 0
+   let g:netrw_list_cmd= "ssh HOSTNAME ls -FLa"
+  endif
+  if !exists("g:netrw_silent")
+   let g:netrw_silent= 0
+  endif
+  if !exists("g:netrw_use_nt_rcp")
+   let g:netrw_use_nt_rcp= 0
+  endif
+  if !exists("g:netrw_ftp")
+   let g:netrw_ftp= 0
+  endif
+  if !exists("g:netrw_ignorenetrc")
+   let g:netrw_ignorenetrc= 0
+  endif
+
+  put ='+ ---------------------------------------------'
+  put ='+  NetrwSettings:  by Charles E. Campbell, Jr.'
+  put ='+ Press <F1> with cursor atop any line for help'
+  put ='+ ---------------------------------------------'
+  let s:netrw_settings_stop= line(".")
+
+  put =''
+  put ='+ Netrw Protocol Commands'
+  put = 'let g:netrw_dav_cmd           = '.g:netrw_dav_cmd
+  put = 'let g:netrw_fetch_cmd         = '.g:netrw_fetch_cmd
+  put = 'let g:netrw_ftp_cmd           = '.g:netrw_ftp_cmd
+  put = 'let g:netrw_http_cmd          = '.g:netrw_http_cmd
+  put = 'let g:netrw_rcp_cmd           = '.g:netrw_rcp_cmd
+  put = 'let g:netrw_rsync_cmd         = '.g:netrw_rsync_cmd
+  put = 'let g:netrw_scp_cmd           = '.g:netrw_scp_cmd
+  put = 'let g:netrw_sftp_cmd          = '.g:netrw_sftp_cmd
+  put = 'let g:netrw_ssh_cmd           = '.g:netrw_ssh_cmd
+  let s:netrw_protocol_stop= line(".")
+  put = ''
+
+  put ='+Netrw Transfer Control'
+  put = 'let g:netrw_cygwin            = '.g:netrw_cygwin
+  put = 'let g:netrw_ftp               = '.g:netrw_ftp
+  put = 'let g:netrw_ftpmode           = '.g:netrw_ftpmode
+  put = 'let g:netrw_ignorenetrc       = '.g:netrw_ignorenetrc
+  put = 'let g:netrw_sshport           = '.g:netrw_sshport
+  let shqline= line("$")
+  put = 'let g:netrw_shq...'
+  put = 'let g:netrw_use_nt_rcp        = '.g:netrw_use_nt_rcp
+  put = 'let g:netrw_win95ftp          = '.g:netrw_win95ftp
+  let s:netrw_xfer_stop= line(".")
+  put =''
+  put ='+ Netrw Messages'
+  put ='let g:netrw_use_errorwindow    = '.g:netrw_use_errorwindow
+
+  put = ''
+  put ='+ Netrw Browser Control'
+  put = 'let g:netrw_alto              = '.g:netrw_alto
+  put = 'let g:netrw_altv              = '.g:netrw_altv
+  put = 'let g:netrw_browse_split      = '.g:netrw_browse_split
+  if exists("g:netrw_browsex_viewer")
+   put = 'let g:netrw_browsex_viewer    = '.g:netrw_browsex_viewer
+  else
+   put = 'let g:netrw_browsex_viewer    = (not defined)'
+  endif
+  put = 'let g:netrw_dirhistmax        = '.g:netrw_dirhistmax
+  put = 'let g:netrw_fastbrowse        = '.g:netrw_fastbrowse
+  put = 'let g:netrw_ftp_browse_reject = '.g:netrw_ftp_browse_reject
+  put = 'let g:netrw_ftp_list_cmd      = '.g:netrw_ftp_list_cmd
+  put = 'let g:netrw_ftp_sizelist_cmd  = '.g:netrw_ftp_sizelist_cmd
+  put = 'let g:netrw_ftp_timelist_cmd  = '.g:netrw_ftp_timelist_cmd
+  put = 'let g:netrw_hide              = '.g:netrw_hide
+  put = 'let g:netrw_keepdir           = '.g:netrw_keepdir
+  put = 'let g:netrw_list_cmd          = '.g:netrw_list_cmd
+  put = 'let g:netrw_list_hide         = '.g:netrw_list_hide
+  put = 'let g:netrw_local_mkdir       = '.g:netrw_local_mkdir
+  put = 'let g:netrw_local_rmdir       = '.g:netrw_local_rmdir
+  put = 'let g:netrw_liststyle         = '.g:netrw_liststyle
+  put = 'let g:netrw_maxfilenamelen    = '.g:netrw_maxfilenamelen
+  put = 'let g:netrw_menu              = '.g:netrw_menu
+  put = 'let g:netrw_mkdir_cmd         = '.g:netrw_mkdir_cmd
+  put = 'let g:netrw_rename_cmd        = '.g:netrw_rename_cmd
+  put = 'let g:netrw_rm_cmd            = '.g:netrw_rm_cmd
+  put = 'let g:netrw_rmdir_cmd         = '.g:netrw_rmdir_cmd
+  put = 'let g:netrw_rmf_cmd           = '.g:netrw_rmf_cmd
+  put = 'let g:netrw_silent            = '.g:netrw_silent
+  put = 'let g:netrw_sort_by           = '.g:netrw_sort_by
+  put = 'let g:netrw_sort_direction    = '.g:netrw_sort_direction
+  put = 'let g:netrw_sort_sequence     = '.g:netrw_sort_sequence
+  put = 'let g:netrw_ssh_browse_reject = '.g:netrw_ssh_browse_reject
+  put = 'let g:netrw_scpport           = '.g:netrw_scpport
+  put = 'let g:netrw_sshport           = '.g:netrw_sshport
+  put = 'let g:netrw_timefmt           = '.g:netrw_timefmt
+  put = 'let g:netrw_use_noswf         = '.g:netrw_use_noswf
+  put = 'let g:netrw_winsize           = '.g:netrw_winsize
+
+  put =''
+  put ='+ For help, place cursor on line and press <F1>'
+
+  1d
+  silent %s/^+/"/e
+  res 99
+  silent %s/= \([^0-9].*\)$/= '\1'/e
+  silent %s/= $/= ''/e
+  1
+
+  " Put in shq setting.
+  " (deferred so as to avoid the quote manipulation just preceding)
+  if g:netrw_shq == "'"
+   call setline(shqline,'let g:netrw_shq               = "'.g:netrw_shq.'"')
+  else
+   call setline(shqline,"let g:netrw_shq               = '".g:netrw_shq."'")
+  endif
+
+  set nomod
+
+  nmap <buffer> <silent> <F1>                       :call NetrwSettingHelp()<cr>
+  nnoremap <buffer> <silent> <leftmouse> <leftmouse>:call NetrwSettingHelp()<cr>
+  let tmpfile= tempname()
+  exe 'au BufWriteCmd	Netrw\ Settings	silent w! '.tmpfile.'|so '.tmpfile.'|call delete("'.tmpfile.'")|set nomod'
+endfun
+
+" ---------------------------------------------------------------------
+" NetrwSettingHelp: {{{2
+fun! NetrwSettingHelp()
+"  call Dfunc("NetrwSettingHelp()")
+  let curline = getline(".")
+  if curline =~ '='
+   let varhelp = substitute(curline,'^\s*let ','','e')
+   let varhelp = substitute(varhelp,'\s*=.*$','','e')
+"   call Decho("trying help ".varhelp)
+   try
+    exe "he ".varhelp
+   catch /^Vim\%((\a\+)\)\=:E149/
+   	echo "***sorry*** no help available for <".varhelp.">"
+   endtry
+  elseif line(".") < s:netrw_settings_stop
+   he netrw-settings
+  elseif line(".") < s:netrw_protocol_stop
+   he netrw-externapp
+  elseif line(".") < s:netrw_xfer_stop
+   he netrw-variables
+  else
+   he netrw-browse-var
+  endif
+"  call Dret("NetrwSettingHelp")
+endfun
+
+" ---------------------------------------------------------------------
+" Modelines: {{{1
+" vim:ts=8 fdm=marker
--- /dev/null
+++ b/lib/vimfiles/autoload/paste.vim
@@ -1,0 +1,35 @@
+" Vim support file to help with paste mappings and menus
+" Maintainer:	Bram Moolenaar <Bram@vim.org>
+" Last Change:	2006 Jun 23
+
+" Define the string to use for items that are present both in Edit, Popup and
+" Toolbar menu.  Also used in mswin.vim and macmap.vim.
+
+" Pasting blockwise and linewise selections is not possible in Insert and
+" Visual mode without the +virtualedit feature.  They are pasted as if they
+" were characterwise instead.  Add to that some tricks to leave the cursor in
+" the right position, also for "gi".
+if has("virtualedit")
+  let paste#paste_cmd = {'n': ":call paste#Paste()<CR>"}
+  let paste#paste_cmd['v'] = '"-c<Esc>' . paste#paste_cmd['n']
+  let paste#paste_cmd['i'] = 'x<BS><Esc>' . paste#paste_cmd['n'] . 'gi'
+
+  func! paste#Paste()
+    let ove = &ve
+    set ve=all
+    normal! `^
+    if @+ != ''
+      normal! "+gP
+    endif
+    let c = col(".")
+    normal! i
+    if col(".") < c	" compensate for i<ESC> moving the cursor left
+      normal! l
+    endif
+    let &ve = ove
+  endfunc
+else
+  let paste#paste_cmd = {'n': "\"=@+.'xy'<CR>gPFx\"_2x"}
+  let paste#paste_cmd['v'] = '"-c<Esc>gix<Esc>' . paste#paste_cmd['n'] . '"_x'
+  let paste#paste_cmd['i'] = 'x<Esc>' . paste#paste_cmd['n'] . '"_s'
+endif
--- /dev/null
+++ b/lib/vimfiles/autoload/phpcomplete.vim
@@ -1,0 +1,5148 @@
+" Vim completion script
+" Language:	PHP
+" Maintainer:	Mikolaj Machowski ( mikmach AT wp DOT pl )
+" Last Change:	2006 May 9
+"
+"   TODO:
+"   - Class aware completion:
+"      a) caching?
+"   - Switching to HTML (XML?) completion (SQL) inside of phpStrings
+"   - allow also for XML completion <- better do html_flavor for HTML
+"     completion
+"   - outside of <?php?> getting parent tag may cause problems. Heh, even in
+"     perfect conditions GetLastOpenTag doesn't cooperate... Inside of
+"     phpStrings this can be even a bonus but outside of <?php?> it is not the
+"     best situation
+
+function! phpcomplete#CompletePHP(findstart, base)
+	if a:findstart
+		unlet! b:php_menu
+		" Check if we are inside of PHP markup
+		let pos = getpos('.')
+		let phpbegin = searchpairpos('<?', '', '?>', 'bWn',
+				\ 'synIDattr(synID(line("."), col("."), 0), "name") =~? "string\|comment"')
+		let phpend   = searchpairpos('<?', '', '?>', 'Wn',
+				\ 'synIDattr(synID(line("."), col("."), 0), "name") =~? "string\|comment"')
+
+		if phpbegin == [0,0] && phpend == [0,0]
+			" We are outside of any PHP markup. Complete HTML
+			let htmlbegin = htmlcomplete#CompleteTags(1, '')
+			let cursor_col = pos[2]
+			let base = getline('.')[htmlbegin : cursor_col]
+			let b:php_menu = htmlcomplete#CompleteTags(0, base)
+			return htmlbegin
+		else
+			" locate the start of the word
+			let line = getline('.')
+			let start = col('.') - 1
+			let curline = line('.')
+			let compl_begin = col('.') - 2
+			while start >= 0 && line[start - 1] =~ '[a-zA-Z_0-9\x7f-\xff$]'
+				let start -= 1
+			endwhile
+			let b:compl_context = getline('.')[0:compl_begin]
+			return start
+
+			" We can be also inside of phpString with HTML tags. Deal with
+			" it later (time, not lines).
+		endif
+
+	endif
+	" If exists b:php_menu it means completion was already constructed we
+	" don't need to do anything more
+	if exists("b:php_menu")
+		return b:php_menu
+	endif
+	" Initialize base return lists
+	let res = []
+	let res2 = []
+	" a:base is very short - we need context
+	if exists("b:compl_context")
+		let context = b:compl_context
+		unlet! b:compl_context
+	endif
+
+	if !exists('g:php_builtin_functions')
+		call phpcomplete#LoadData()
+	endif
+
+	let scontext = substitute(context, '\$\?[a-zA-Z_\x7f-\xff][a-zA-Z_0-9\x7f-\xff]*$', '', '')
+
+	if scontext =~ '\(=\s*new\|extends\)\s\+$'
+		" Complete class name
+		" Internal solution for finding classes in current file.
+		let file = getline(1, '$')
+		call filter(file,
+				\ 'v:val =~ "class\\s\\+[a-zA-Z_\\x7f-\\xff][a-zA-Z_0-9\\x7f-\\xff]*\\s*("')
+		let fnames = join(map(tagfiles(), 'escape(v:val, " \\#%")'))
+		let jfile = join(file, ' ')
+		let int_values = split(jfile, 'class\s\+')
+		let int_classes = {}
+		for i in int_values
+			let c_name = matchstr(i, '^[a-zA-Z_\x7f-\xff][a-zA-Z_0-9\x7f-\xff]*')
+			if c_name != ''
+				let int_classes[c_name] = ''
+			endif
+		endfor
+
+		" Prepare list of classes from tags file
+		let ext_classes = {}
+		let fnames = join(map(tagfiles(), 'escape(v:val, " \\#%")'))
+		if fnames != ''
+			exe 'silent! vimgrep /^'.a:base.'.*\tc\(\t\|$\)/j '.fnames
+			let qflist = getqflist()
+			if len(qflist) > 0
+				for field in qflist
+					" [:space:] thing: we don't have to be so strict when
+					" dealing with tags files - entries there were already
+					" checked by ctags.
+					let item = matchstr(field['text'], '^[^[:space:]]\+')
+					let ext_classes[item] = ''
+				endfor
+			endif
+		endif
+
+		" Prepare list of built in classes from g:php_builtin_functions
+		if !exists("g:php_omni_bi_classes")
+			let g:php_omni_bi_classes = {}
+			for i in keys(g:php_builtin_object_functions)
+				let g:php_omni_bi_classes[substitute(i, '::.*$', '', '')] = ''
+			endfor
+		endif
+
+		let classes = sort(keys(int_classes))
+		let classes += sort(keys(ext_classes))
+		let classes += sort(keys(g:php_omni_bi_classes))
+
+		for m in classes
+			if m =~ '^'.a:base
+				call add(res, m)
+			endif
+		endfor
+
+		let final_menu = []
+		for i in res
+			let final_menu += [{'word':i, 'kind':'c'}]
+		endfor
+
+		return final_menu
+
+	elseif scontext =~ '\(->\|::\)$'
+		" Complete user functions and variables
+		" Internal solution for current file.
+		" That seems as unnecessary repeating of functions but there are
+		" few not so subtle differences as not appending of $ and addition
+		" of 'kind' tag (not necessary in regular completion)
+
+		if scontext =~ '->$' && scontext !~ '\$this->$'
+
+			" Get name of the class
+			let classname = phpcomplete#GetClassName(scontext)
+
+			" Get location of class definition, we have to iterate through all
+			" tags files separately because we need relative path from current
+			" file to the exact file (tags file can be in different dir)
+			if classname != ''
+				let classlocation = phpcomplete#GetClassLocation(classname)
+			else
+				let classlocation = ''
+			endif
+
+			if classlocation == 'VIMPHP_BUILTINOBJECT'
+
+				for object in keys(g:php_builtin_object_functions)
+					if object =~ '^'.classname
+						let res += [{'word':substitute(object, '.*::', '', ''),
+							   	\    'info': g:php_builtin_object_functions[object]}]
+					endif
+				endfor
+
+				return res
+
+			endif
+
+			if filereadable(classlocation)
+				let classfile = readfile(classlocation)
+				let classcontent = ''
+				let classcontent .= "\n".phpcomplete#GetClassContents(classfile, classname)
+				let sccontent = split(classcontent, "\n")
+
+				" YES, YES, YES! - we have whole content including extends!
+				" Now we need to get two elements: public functions and public
+				" vars
+				" NO, NO, NO! - third separate filtering looking for content
+				" :(, but all of them have differences. To squeeze them into
+				" one implementation would require many additional arguments
+				" and ifs. No good solution
+				" Functions declared with public keyword or without any
+				" keyword are public
+				let functions = filter(deepcopy(sccontent),
+						\ 'v:val =~ "^\\s*\\(static\\s\\+\\|public\\s\\+\\)*function"')
+				let jfuncs = join(functions, ' ')
+				let sfuncs = split(jfuncs, 'function\s\+')
+				let c_functions = {}
+				for i in sfuncs
+					let f_name = matchstr(i,
+							\ '^&\?\zs[a-zA-Z_\x7f-\xff][a-zA-Z_0-9\x7f-\xff]*\ze')
+					let f_args = matchstr(i,
+							\ '^&\?[a-zA-Z_\x7f-\xff][a-zA-Z_0-9\x7f-\xff]*\s*(\zs.\{-}\ze)\_s*{')
+					if f_name != ''
+						let c_functions[f_name.'('] = f_args
+					endif
+				endfor
+				" Variables declared with var or with public keyword are
+				" public
+				let variables = filter(deepcopy(sccontent),
+						\ 'v:val =~ "^\\s*\\(public\\|var\\)\\s\\+\\$"')
+				let jvars = join(variables, ' ')
+				let svars = split(jvars, '\$')
+				let c_variables = {}
+				for i in svars
+					let c_var = matchstr(i,
+							\ '^\zs[a-zA-Z_\x7f-\xff][a-zA-Z_0-9\x7f-\xff]*\ze')
+					if c_var != ''
+						let c_variables[c_var] = ''
+					endif
+				endfor
+
+				let all_values = {}
+				call extend(all_values, c_functions)
+				call extend(all_values, c_variables)
+
+				for m in sort(keys(all_values))
+					if m =~ '^'.a:base && m !~ '::'
+						call add(res, m)
+					elseif m =~ '::'.a:base
+						call add(res2, m)
+					endif
+				endfor
+
+				let start_list = res + res2
+
+				let final_list = []
+				for i in start_list
+					if has_key(c_variables, i)
+						let class = ' '
+						if all_values[i] != ''
+							let class = i.' class '
+						endif
+						let final_list +=
+								\ [{'word':i,
+								\   'info':class.all_values[i],
+								\   'kind':'v'}]
+					else
+						let final_list +=
+								\ [{'word':substitute(i, '.*::', '', ''),
+								\   'info':i.all_values[i].')',
+								\   'kind':'f'}]
+					endif
+				endfor
+
+				return final_list
+
+			endif
+
+		endif
+
+		if a:base =~ '^\$'
+			let adddollar = '$'
+		else
+			let adddollar = ''
+		endif
+		let file = getline(1, '$')
+		let jfile = join(file, ' ')
+		let sfile = split(jfile, '\$')
+		let int_vars = {}
+		for i in sfile
+			if i =~ '^\$[a-zA-Z_\x7f-\xff][a-zA-Z_0-9\x7f-\xff]*\s*=\s*new'
+				let val = matchstr(i, '^[a-zA-Z_\x7f-\xff][a-zA-Z_0-9\x7f-\xff]*').'->'
+			else
+				let val = matchstr(i, '^[a-zA-Z_\x7f-\xff][a-zA-Z_0-9\x7f-\xff]*')
+			endif
+			if val !~ ''
+				let int_vars[adddollar.val] = ''
+			endif
+		endfor
+
+		" ctags has good support for PHP, use tags file for external
+		" variables
+		let fnames = join(map(tagfiles(), 'escape(v:val, " \\#%")'))
+		let ext_vars = {}
+		if fnames != ''
+			let sbase = substitute(a:base, '^\$', '', '')
+			exe 'silent! vimgrep /^'.sbase.'.*\tv\(\t\|$\)/j '.fnames
+			let qflist = getqflist()
+			if len(qflist) > 0
+				for field in qflist
+					let item = matchstr(field['text'], '^[^[:space:]]\+')
+					" Add -> if it is possible object declaration
+					let classname = ''
+					if field['text'] =~ item.'\s*=\s*new\s\+'
+						let item = item.'->'
+						let classname = matchstr(field['text'],
+								\ '=\s*new\s\+\zs[a-zA-Z_0-9\x7f-\xff]\+\ze')
+					endif
+					let ext_vars[adddollar.item] = classname
+				endfor
+			endif
+		endif
+
+		" Now we have all variables in int_vars dictionary
+		call extend(int_vars, ext_vars)
+
+		" Internal solution for finding functions in current file.
+		let file = getline(1, '$')
+		call filter(file,
+				\ 'v:val =~ "function\\s\\+&\\?[a-zA-Z_\\x7f-\\xff][a-zA-Z_0-9\\x7f-\\xff]*\\s*("')
+		let fnames = join(map(tagfiles(), 'escape(v:val, " \\#%")'))
+		let jfile = join(file, ' ')
+		let int_values = split(jfile, 'function\s\+')
+		let int_functions = {}
+		for i in int_values
+			let f_name = matchstr(i,
+					\ '^&\?\zs[a-zA-Z_\x7f-\xff][a-zA-Z_0-9\x7f-\xff]*\ze')
+			let f_args = matchstr(i,
+					\ '^&\?[a-zA-Z_\x7f-\xff][a-zA-Z_0-9\x7f-\xff]*\s*(\zs.\{-}\ze)\_s*{')
+			let int_functions[f_name.'('] = f_args.')'
+		endfor
+
+		" Prepare list of functions from tags file
+		let ext_functions = {}
+		if fnames != ''
+			exe 'silent! vimgrep /^'.a:base.'.*\tf\(\t\|$\)/j '.fnames
+			let qflist = getqflist()
+			if len(qflist) > 0
+				for field in qflist
+					" File name
+					let item = matchstr(field['text'], '^[^[:space:]]\+')
+					let fname = matchstr(field['text'], '\t\zs\f\+\ze')
+					let prototype = matchstr(field['text'],
+							\ 'function\s\+&\?[^[:space:]]\+\s*(\s*\zs.\{-}\ze\s*)\s*{\?')
+					let ext_functions[item.'('] = prototype.') - '.fname
+				endfor
+			endif
+		endif
+
+		let all_values = {}
+		call extend(all_values, int_functions)
+		call extend(all_values, ext_functions)
+		call extend(all_values, int_vars) " external variables are already in
+		call extend(all_values, g:php_builtin_object_functions)
+
+		for m in sort(keys(all_values))
+			if m =~ '\(^\|::\)'.a:base
+				call add(res, m)
+			endif
+		endfor
+
+		let start_list = res
+
+		let final_list = []
+		for i in start_list
+			if has_key(int_vars, i)
+				let class = ' '
+				if all_values[i] != ''
+					let class = i.' class '
+				endif
+				let final_list += [{'word':i, 'info':class.all_values[i], 'kind':'v'}]
+			else
+				let final_list +=
+						\ [{'word':substitute(i, '.*::', '', ''),
+						\   'info':i.all_values[i],
+						\   'kind':'f'}]
+			endif
+		endfor
+
+		return final_list
+	endif
+
+	if a:base =~ '^\$'
+		" Complete variables
+		" Built-in variables {{{
+		let g:php_builtin_vars = {'$GLOBALS':'',
+								\ '$_SERVER':'',
+								\ '$_GET':'',
+								\ '$_POST':'',
+								\ '$_COOKIE':'',
+								\ '$_FILES':'',
+								\ '$_ENV':'',
+								\ '$_REQUEST':'',
+								\ '$_SESSION':'',
+								\ '$HTTP_SERVER_VARS':'',
+								\ '$HTTP_ENV_VARS':'',
+								\ '$HTTP_COOKIE_VARS':'',
+								\ '$HTTP_GET_VARS':'',
+								\ '$HTTP_POST_VARS':'',
+								\ '$HTTP_POST_FILES':'',
+								\ '$HTTP_SESSION_VARS':'',
+								\ '$php_errormsg':'',
+								\ '$this':''
+								\ }
+		" }}}
+
+		" Internal solution for current file.
+		let file = getline(1, '$')
+		let jfile = join(file, ' ')
+		let int_vals = split(jfile, '\ze\$')
+		let int_vars = {}
+		for i in int_vals
+			if i =~ '^\$[a-zA-Z_\x7f-\xff][a-zA-Z_0-9\x7f-\xff]*\s*=\s*new'
+				let val = matchstr(i,
+						\ '^\$[a-zA-Z_\x7f-\xff][a-zA-Z_0-9\x7f-\xff]*').'->'
+			else
+				let val = matchstr(i,
+						\ '^\$[a-zA-Z_\x7f-\xff][a-zA-Z_0-9\x7f-\xff]*')
+			endif
+			if val != ''
+				let int_vars[val] = ''
+			endif
+		endfor
+
+		call extend(int_vars,g:php_builtin_vars)
+
+		" ctags has support for PHP, use tags file for external variables
+		let fnames = join(map(tagfiles(), 'escape(v:val, " \\#%")'))
+		let ext_vars = {}
+		if fnames != ''
+			let sbase = substitute(a:base, '^\$', '', '')
+			exe 'silent! vimgrep /^'.sbase.'.*\tv\(\t\|$\)/j '.fnames
+			let qflist = getqflist()
+			if len(qflist) > 0
+				for field in qflist
+					let item = '$'.matchstr(field['text'], '^[^[:space:]]\+')
+					let m_menu = ''
+					" Add -> if it is possible object declaration
+					if field['text'] =~ item.'\s*=\s*new\s\+'
+						let item = item.'->'
+						let m_menu = matchstr(field['text'],
+								\ '=\s*new\s\+\zs[a-zA-Z_0-9\x7f-\xff]\+\ze')
+					endif
+					let ext_vars[item] = m_menu
+				endfor
+			endif
+		endif
+
+		call extend(int_vars, ext_vars)
+		let g:a0 = keys(int_vars)
+
+		for m in sort(keys(int_vars))
+			if m =~ '^\'.a:base
+				call add(res, m)
+			endif
+		endfor
+
+		let int_list = res
+
+		let int_dict = []
+		for i in int_list
+			if int_vars[i] != ''
+				let class = ' '
+				if int_vars[i] != ''
+					let class = i.' class '
+				endif
+				let int_dict += [{'word':i, 'info':class.int_vars[i], 'kind':'v'}]
+			else
+				let int_dict += [{'word':i, 'kind':'v'}]
+			endif
+		endfor
+
+		return int_dict
+
+	else
+		" Complete everything else -
+		"  + functions,  DONE
+		"  + keywords of language DONE
+		"  + defines (constant definitions), DONE
+		"  + extend keywords for predefined constants, DONE
+		"  + classes (after new), DONE
+		"  + limit choice after -> and :: to funcs and vars DONE
+
+		" Internal solution for finding functions in current file.
+		let file = getline(1, '$')
+		call filter(file,
+				\ 'v:val =~ "function\\s\\+&\\?[a-zA-Z_\\x7f-\\xff][a-zA-Z_0-9\\x7f-\\xff]*\\s*("')
+		let fnames = join(map(tagfiles(), 'escape(v:val, " \\#%")'))
+		let jfile = join(file, ' ')
+		let int_values = split(jfile, 'function\s\+')
+		let int_functions = {}
+		for i in int_values
+			let f_name = matchstr(i,
+					\ '^&\?\zs[a-zA-Z_\x7f-\xff][a-zA-Z_0-9\x7f-\xff]*\ze')
+			let f_args = matchstr(i,
+					\ '^&\?[a-zA-Z_\x7f-\xff][a-zA-Z_0-9\x7f-\xff]*\s*(\s*\zs.\{-}\ze\s*)\_s*{')
+			let int_functions[f_name.'('] = f_args.')'
+		endfor
+
+		" Prepare list of functions from tags file
+		let ext_functions = {}
+		if fnames != ''
+			exe 'silent! vimgrep /^'.a:base.'.*\tf\(\t\|$\)/j '.fnames
+			let qflist = getqflist()
+			if len(qflist) > 0
+				for field in qflist
+					" File name
+					let item = matchstr(field['text'], '^[^[:space:]]\+')
+					let fname = matchstr(field['text'], '\t\zs\f\+\ze')
+					let prototype = matchstr(field['text'],
+							\ 'function\s\+&\?[^[:space:]]\+\s*(\s*\zs.\{-}\ze\s*)\s*{\?')
+					let ext_functions[item.'('] = prototype.') - '.fname
+				endfor
+			endif
+		endif
+
+		" All functions
+		call extend(int_functions, ext_functions)
+		call extend(int_functions, g:php_builtin_functions)
+
+		" Internal solution for finding constants in current file
+		let file = getline(1, '$')
+		call filter(file, 'v:val =~ "define\\s*("')
+		let jfile = join(file, ' ')
+		let int_values = split(jfile, 'define\s*(\s*')
+		let int_constants = {}
+		for i in int_values
+			let c_name = matchstr(i, '\(["'']\)\zs[a-zA-Z_\x7f-\xff][a-zA-Z_0-9\x7f-\xff]*\ze\1')
+			" let c_value = matchstr(i,
+			" \ '\(["'']\)[a-zA-Z_\x7f-\xff][a-zA-Z_0-9\x7f-\xff]*\1\s*,\s*\zs.\{-}\ze\s*)')
+			if c_name != ''
+				let int_constants[c_name] = '' " c_value
+			endif
+		endfor
+
+		" Prepare list of constants from tags file
+		let fnames = join(map(tagfiles(), 'escape(v:val, " \\#%")'))
+		let ext_constants = {}
+		if fnames != ''
+			exe 'silent! vimgrep /^'.a:base.'.*\td\(\t\|$\)/j '.fnames
+			let qflist = getqflist()
+			if len(qflist) > 0
+				for field in qflist
+					let item = matchstr(field['text'], '^[^[:space:]]\+')
+					let ext_constants[item] = ''
+				endfor
+			endif
+		endif
+
+		" All constants
+		call extend(int_constants, ext_constants)
+		" Treat keywords as constants
+
+		let all_values = {}
+
+		" One big dictionary of functions
+		call extend(all_values, int_functions)
+
+		" Add constants
+		call extend(all_values, int_constants)
+		" Add keywords
+		call extend(all_values, g:php_keywords)
+
+		for m in sort(keys(all_values))
+			if m =~ '^'.a:base
+				call add(res, m)
+			endif
+		endfor
+
+		let int_list = res
+
+		let final_list = []
+		for i in int_list
+			if has_key(int_functions, i)
+				let final_list +=
+						\ [{'word':i,
+						\   'info':i.int_functions[i],
+						\   'kind':'f'}]
+			elseif has_key(int_constants, i)
+				let final_list += [{'word':i, 'kind':'d'}]
+			else
+				let final_list += [{'word':i}]
+			endif
+		endfor
+
+		return final_list
+
+	endif
+
+endfunction
+
+function! phpcomplete#GetClassName(scontext) " {{{
+	" Get class name
+	" Class name can be detected in few ways:
+	" @var $myVar class
+	" line above
+	" or line in tags file
+
+	let object = matchstr(a:scontext, '\zs[a-zA-Z_0-9\x7f-\xff]\+\ze->')
+	let i = 1
+	while i < line('.')
+		let line = getline(line('.')-i)
+		if line =~ '^\s*\*\/\?\s*$'
+			let i += 1
+			continue
+		else
+			if line =~ '@var\s\+\$'.object.'\s\+[a-zA-Z_0-9\x7f-\xff]\+'
+				let classname = matchstr(line, '@var\s\+\$'.object.'\s\+\zs[a-zA-Z_0-9\x7f-\xff]\+')
+				return classname
+			else
+				break
+			endif
+		endif
+	endwhile
+
+	" OK, first way failed, now check tags file(s)
+	let fnames = join(map(tagfiles(), 'escape(v:val, " \\#%")'))
+	exe 'silent! vimgrep /^'.object.'.*\$'.object.'.*=\s*new\s\+.*\tv\(\t\|$\)/j '.fnames
+	let qflist = getqflist()
+	if len(qflist) == 0
+		return ''
+	else
+		" In all properly managed projects it should be one item list, even if it
+		" *is* longer we cannot solve conflicts, assume it is first element
+		let classname = matchstr(qflist[0]['text'], '=\s*new\s\+\zs[a-zA-Z_0-9\x7f-\xff]\+\ze')
+		return classname
+	endif
+
+endfunction
+" }}}
+function! phpcomplete#GetClassLocation(classname) " {{{
+	" Check classname may be name of built in object
+	if !exists("g:php_omni_bi_classes")
+		let g:php_omni_bi_classes = {}
+		for i in keys(g:php_builtin_object_functions)
+			let g:php_omni_bi_classes[substitute(i, '::.*$', '', '')] = ''
+		endfor
+	endif
+	if has_key(g:php_omni_bi_classes, a:classname)
+		return 'VIMPHP_BUILTINOBJECT'
+	endif
+
+	" Get class location
+	for fname in tagfiles()
+		let fhead = fnamemodify(fname, ":h")
+		if fhead != ''
+			let psep = '/' " Note: slash is potential problem!
+			let fhead .= psep
+		endif
+		let fname = escape(fname, " \\")
+		exe 'silent! vimgrep /^'.a:classname.'.*\tc\(\t\|$\)/j '.fname
+		let qflist = getqflist()
+		" As in GetClassName we can manage only one element if it exists
+		if len(qflist) > 0
+			let classlocation = matchstr(qflist[0]['text'], '\t\zs\f\+\ze\t')
+		else
+			return ''
+		endif
+		" And only one class location
+		if classlocation != ''
+			let classlocation = fhead.classlocation
+			return classlocation
+		else
+			return ''
+		endif
+	endfor
+
+endfunction
+" }}}
+
+function! phpcomplete#GetClassContents(file, name) " {{{
+	let cfile = join(a:file, "\n")
+	" We use new buffer and (later) normal! because
+	" this is the most efficient way. The other way
+	" is to go through the looong string looking for
+	" matching {}
+	below 1new
+	0put =cfile
+	call search('class\s\+'.a:name)
+	let cfline = line('.')
+	" Catch extends
+	if getline('.') =~ 'extends'
+		let extends_class = matchstr(getline('.'),
+				\ 'class\s\+'.a:name.'\s\+extends\s\+\zs[a-zA-Z_0-9\x7f-\xff]\+\ze')
+	else
+		let extends_class = ''
+	endif
+	call search('{')
+	normal! %
+	let classc = getline(cfline, ".")
+	let classcontent = join(classc, "\n")
+
+	bw! %
+	if extends_class != ''
+		let classlocation = phpcomplete#GetClassLocation(extends_class)
+		if filereadable(classlocation)
+			let classfile = readfile(classlocation)
+			let classcontent .= "\n".phpcomplete#GetClassContents(classfile, extends_class)
+		endif
+	endif
+
+	return classcontent
+endfunction
+" }}}
+
+function! phpcomplete#LoadData() " {{{
+" Keywords/reserved words, all other special things {{{
+" Later it is possible to add some help to values, or type of
+" defined variable
+let g:php_keywords = {
+\ 'PHP_SELF':'',
+\ 'argv':'',
+\ 'argc':'',
+\ 'GATEWAY_INTERFACE':'',
+\ 'SERVER_ADDR':'',
+\ 'SERVER_NAME':'',
+\ 'SERVER_SOFTWARE':'',
+\ 'SERVER_PROTOCOL':'',
+\ 'REQUEST_METHOD':'',
+\ 'REQUEST_TIME':'',
+\ 'QUERY_STRING':'',
+\ 'DOCUMENT_ROOT':'',
+\ 'HTTP_ACCEPT':'',
+\ 'HTTP_ACCEPT_CHARSET':'',
+\ 'HTTP_ACCEPT_ENCODING':'',
+\ 'HTTP_ACCEPT_LANGUAGE':'',
+\ 'HTTP_CONNECTION':'',
+\ 'HTTP_POST':'',
+\ 'HTTP_REFERER':'',
+\ 'HTTP_USER_AGENT':'',
+\ 'HTTPS':'',
+\ 'REMOTE_ADDR':'',
+\ 'REMOTE_HOST':'',
+\ 'REMOTE_PORT':'',
+\ 'SCRIPT_FILENAME':'',
+\ 'SERVER_ADMIN':'',
+\ 'SERVER_PORT':'',
+\ 'SERVER_SIGNATURE':'',
+\ 'PATH_TRANSLATED':'',
+\ 'SCRIPT_NAME':'',
+\ 'REQUEST_URI':'',
+\ 'PHP_AUTH_DIGEST':'',
+\ 'PHP_AUTH_USER':'',
+\ 'PHP_AUTH_PW':'',
+\ 'AUTH_TYPE':'',
+\ 'and':'',
+\ 'or':'',
+\ 'xor':'',
+\ '__FILE__':'',
+\ 'exception':'',
+\ '__LINE__':'',
+\ 'as':'',
+\ 'break':'',
+\ 'case':'',
+\ 'class':'',
+\ 'const':'',
+\ 'continue':'',
+\ 'declare':'',
+\ 'default':'',
+\ 'do':'',
+\ 'echo':'',
+\ 'else':'',
+\ 'elseif':'',
+\ 'enddeclare':'',
+\ 'endfor':'',
+\ 'endforeach':'',
+\ 'endif':'',
+\ 'endswitch':'',
+\ 'endwhile':'',
+\ 'extends':'',
+\ 'for':'',
+\ 'foreach':'',
+\ 'function':'',
+\ 'global':'',
+\ 'if':'',
+\ 'new':'',
+\ 'static':'',
+\ 'switch':'',
+\ 'use':'',
+\ 'var':'',
+\ 'while':'',
+\ '__FUNCTION__':'',
+\ '__CLASS__':'',
+\ '__METHOD__':'',
+\ 'final':'',
+\ 'php_user_filter':'',
+\ 'interface':'',
+\ 'implements':'',
+\ 'public':'',
+\ 'private':'',
+\ 'protected':'',
+\ 'abstract':'',
+\ 'clone':'',
+\ 'try':'',
+\ 'catch':'',
+\ 'throw':'',
+\ 'cfunction':'',
+\ 'old_function':'',
+\ 'this':'',
+\ 'PHP_VERSION': '',
+\ 'PHP_OS': '',
+\ 'PHP_SAPI': '',
+\ 'PHP_EOL': '',
+\ 'PHP_INT_MAX': '',
+\ 'PHP_INT_SIZE': '',
+\ 'DEFAULT_INCLUDE_PATH': '',
+\ 'PEAR_INSTALL_DIR': '',
+\ 'PEAR_EXTENSION_DIR': '',
+\ 'PHP_EXTENSION_DIR': '',
+\ 'PHP_PREFIX': '',
+\ 'PHP_BINDIR': '',
+\ 'PHP_LIBDIR': '',
+\ 'PHP_DATADIR': '',
+\ 'PHP_SYSCONFDIR': '',
+\ 'PHP_LOCALSTATEDIR': '',
+\ 'PHP_CONFIG_FILE_PATH': '',
+\ 'PHP_CONFIG_FILE_SCAN_DIR': '',
+\ 'PHP_SHLIB_SUFFIX': '',
+\ 'PHP_OUTPUT_HANDLER_START': '',
+\ 'PHP_OUTPUT_HANDLER_CONT': '',
+\ 'PHP_OUTPUT_HANDLER_END': '',
+\ 'E_ERROR': '',
+\ 'E_WARNING': '',
+\ 'E_PARSE': '',
+\ 'E_NOTICE': '',
+\ 'E_CORE_ERROR': '',
+\ 'E_CORE_WARNING': '',
+\ 'E_COMPILE_ERROR': '',
+\ 'E_COMPILE_WARNING': '',
+\ 'E_USER_ERROR': '',
+\ 'E_USER_WARNING': '',
+\ 'E_USER_NOTICE': '',
+\ 'E_ALL': '',
+\ 'E_STRICT': '',
+\ '__COMPILER_HALT_OFFSET__': '',
+\ 'EXTR_OVERWRITE': '',
+\ 'EXTR_SKIP': '',
+\ 'EXTR_PREFIX_SAME': '',
+\ 'EXTR_PREFIX_ALL': '',
+\ 'EXTR_PREFIX_INVALID': '',
+\ 'EXTR_PREFIX_IF_EXISTS': '',
+\ 'EXTR_IF_EXISTS': '',
+\ 'SORT_ASC': '',
+\ 'SORT_DESC': '',
+\ 'SORT_REGULAR': '',
+\ 'SORT_NUMERIC': '',
+\ 'SORT_STRING': '',
+\ 'CASE_LOWER': '',
+\ 'CASE_UPPER': '',
+\ 'COUNT_NORMAL': '',
+\ 'COUNT_RECURSIVE': '',
+\ 'ASSERT_ACTIVE': '',
+\ 'ASSERT_CALLBACK': '',
+\ 'ASSERT_BAIL': '',
+\ 'ASSERT_WARNING': '',
+\ 'ASSERT_QUIET_EVAL': '',
+\ 'CONNECTION_ABORTED': '',
+\ 'CONNECTION_NORMAL': '',
+\ 'CONNECTION_TIMEOUT': '',
+\ 'INI_USER': '',
+\ 'INI_PERDIR': '',
+\ 'INI_SYSTEM': '',
+\ 'INI_ALL': '',
+\ 'M_E': '',
+\ 'M_LOG2E': '',
+\ 'M_LOG10E': '',
+\ 'M_LN2': '',
+\ 'M_LN10': '',
+\ 'M_PI': '',
+\ 'M_PI_2': '',
+\ 'M_PI_4': '',
+\ 'M_1_PI': '',
+\ 'M_2_PI': '',
+\ 'M_2_SQRTPI': '',
+\ 'M_SQRT2': '',
+\ 'M_SQRT1_2': '',
+\ 'CRYPT_SALT_LENGTH': '',
+\ 'CRYPT_STD_DES': '',
+\ 'CRYPT_EXT_DES': '',
+\ 'CRYPT_MD5': '',
+\ 'CRYPT_BLOWFISH': '',
+\ 'DIRECTORY_SEPARATOR': '',
+\ 'SEEK_SET': '',
+\ 'SEEK_CUR': '',
+\ 'SEEK_END': '',
+\ 'LOCK_SH': '',
+\ 'LOCK_EX': '',
+\ 'LOCK_UN': '',
+\ 'LOCK_NB': '',
+\ 'HTML_SPECIALCHARS': '',
+\ 'HTML_ENTITIES': '',
+\ 'ENT_COMPAT': '',
+\ 'ENT_QUOTES': '',
+\ 'ENT_NOQUOTES': '',
+\ 'INFO_GENERAL': '',
+\ 'INFO_CREDITS': '',
+\ 'INFO_CONFIGURATION': '',
+\ 'INFO_MODULES': '',
+\ 'INFO_ENVIRONMENT': '',
+\ 'INFO_VARIABLES': '',
+\ 'INFO_LICENSE': '',
+\ 'INFO_ALL': '',
+\ 'CREDITS_GROUP': '',
+\ 'CREDITS_GENERAL': '',
+\ 'CREDITS_SAPI': '',
+\ 'CREDITS_MODULES': '',
+\ 'CREDITS_DOCS': '',
+\ 'CREDITS_FULLPAGE': '',
+\ 'CREDITS_QA': '',
+\ 'CREDITS_ALL': '',
+\ 'STR_PAD_LEFT': '',
+\ 'STR_PAD_RIGHT': '',
+\ 'STR_PAD_BOTH': '',
+\ 'PATHINFO_DIRNAME': '',
+\ 'PATHINFO_BASENAME': '',
+\ 'PATHINFO_EXTENSION': '',
+\ 'PATH_SEPARATOR': '',
+\ 'CHAR_MAX': '',
+\ 'LC_CTYPE': '',
+\ 'LC_NUMERIC': '',
+\ 'LC_TIME': '',
+\ 'LC_COLLATE': '',
+\ 'LC_MONETARY': '',
+\ 'LC_ALL': '',
+\ 'LC_MESSAGES': '',
+\ 'ABDAY_1': '',
+\ 'ABDAY_2': '',
+\ 'ABDAY_3': '',
+\ 'ABDAY_4': '',
+\ 'ABDAY_5': '',
+\ 'ABDAY_6': '',
+\ 'ABDAY_7': '',
+\ 'DAY_1': '',
+\ 'DAY_2': '',
+\ 'DAY_3': '',
+\ 'DAY_4': '',
+\ 'DAY_5': '',
+\ 'DAY_6': '',
+\ 'DAY_7': '',
+\ 'ABMON_1': '',
+\ 'ABMON_2': '',
+\ 'ABMON_3': '',
+\ 'ABMON_4': '',
+\ 'ABMON_5': '',
+\ 'ABMON_6': '',
+\ 'ABMON_7': '',
+\ 'ABMON_8': '',
+\ 'ABMON_9': '',
+\ 'ABMON_10': '',
+\ 'ABMON_11': '',
+\ 'ABMON_12': '',
+\ 'MON_1': '',
+\ 'MON_2': '',
+\ 'MON_3': '',
+\ 'MON_4': '',
+\ 'MON_5': '',
+\ 'MON_6': '',
+\ 'MON_7': '',
+\ 'MON_8': '',
+\ 'MON_9': '',
+\ 'MON_10': '',
+\ 'MON_11': '',
+\ 'MON_12': '',
+\ 'AM_STR': '',
+\ 'PM_STR': '',
+\ 'D_T_FMT': '',
+\ 'D_FMT': '',
+\ 'T_FMT': '',
+\ 'T_FMT_AMPM': '',
+\ 'ERA': '',
+\ 'ERA_YEAR': '',
+\ 'ERA_D_T_FMT': '',
+\ 'ERA_D_FMT': '',
+\ 'ERA_T_FMT': '',
+\ 'ALT_DIGITS': '',
+\ 'INT_CURR_SYMBOL': '',
+\ 'CURRENCY_SYMBOL': '',
+\ 'CRNCYSTR': '',
+\ 'MON_DECIMAL_POINT': '',
+\ 'MON_THOUSANDS_SEP': '',
+\ 'MON_GROUPING': '',
+\ 'POSITIVE_SIGN': '',
+\ 'NEGATIVE_SIGN': '',
+\ 'INT_FRAC_DIGITS': '',
+\ 'FRAC_DIGITS': '',
+\ 'P_CS_PRECEDES': '',
+\ 'P_SEP_BY_SPACE': '',
+\ 'N_CS_PRECEDES': '',
+\ 'N_SEP_BY_SPACE': '',
+\ 'P_SIGN_POSN': '',
+\ 'N_SIGN_POSN': '',
+\ 'DECIMAL_POINT': '',
+\ 'RADIXCHAR': '',
+\ 'THOUSANDS_SEP': '',
+\ 'THOUSEP': '',
+\ 'GROUPING': '',
+\ 'YESEXPR': '',
+\ 'NOEXPR': '',
+\ 'YESSTR': '',
+\ 'NOSTR': '',
+\ 'CODESET': '',
+\ 'LOG_EMERG': '',
+\ 'LOG_ALERT': '',
+\ 'LOG_CRIT': '',
+\ 'LOG_ERR': '',
+\ 'LOG_WARNING': '',
+\ 'LOG_NOTICE': '',
+\ 'LOG_INFO': '',
+\ 'LOG_DEBUG': '',
+\ 'LOG_KERN': '',
+\ 'LOG_USER': '',
+\ 'LOG_MAIL': '',
+\ 'LOG_DAEMON': '',
+\ 'LOG_AUTH': '',
+\ 'LOG_SYSLOG': '',
+\ 'LOG_LPR': '',
+\ 'LOG_NEWS': '',
+\ 'LOG_UUCP': '',
+\ 'LOG_CRON': '',
+\ 'LOG_AUTHPRIV': '',
+\ 'LOG_LOCAL0': '',
+\ 'LOG_LOCAL1': '',
+\ 'LOG_LOCAL2': '',
+\ 'LOG_LOCAL3': '',
+\ 'LOG_LOCAL4': '',
+\ 'LOG_LOCAL5': '',
+\ 'LOG_LOCAL6': '',
+\ 'LOG_LOCAL7': '',
+\ 'LOG_PID': '',
+\ 'LOG_CONS': '',
+\ 'LOG_ODELAY': '',
+\ 'LOG_NDELAY': '',
+\ 'LOG_NOWAIT': '',
+\ 'LOG_PERROR': '',
+\ }
+" }}}
+" PHP builtin functions {{{
+" To create from scratch list of functions:
+" 1. Download multi html file PHP documentation
+" 2. run for i in `ls | grep "^function\."`; do grep -A4 Description $i >> funcs; done
+" 3. Open funcs in Vim and
+"    a) g/Description/normal! 5J
+"    b) remove all html tags (it will require few s/// and g//)
+"    c) :%s/^\([^[:space:]]\+\) \([^[:space:]]\+\) ( \(.*\))/\\ '\2(': '\3| \1',
+"       This will create Dictionary
+"    d) remove all /^[^\\] lines
+let g:php_builtin_functions = {
+\ 'abs(': 'mixed number | number',
+\ 'acosh(': 'float arg | float',
+\ 'acos(': 'float arg | float',
+\ 'addcslashes(': 'string str, string charlist | string',
+\ 'addslashes(': 'string str | string',
+\ 'aggregate(': 'object object, string class_name | void',
+\ 'aggregate_info(': 'object object | array',
+\ 'aggregate_methods_by_list(': 'object object, string class_name, array methods_list [, bool exclude] | void',
+\ 'aggregate_methods_by_regexp(': 'object object, string class_name, string regexp [, bool exclude] | void',
+\ 'aggregate_methods(': 'object object, string class_name | void',
+\ 'aggregate_properties_by_list(': 'object object, string class_name, array properties_list [, bool exclude] | void',
+\ 'aggregate_properties_by_regexp(': 'object object, string class_name, string regexp [, bool exclude] | void',
+\ 'aggregate_properties(': 'object object, string class_name | void',
+\ 'apache_child_terminate(': 'void  | bool',
+\ 'apache_getenv(': 'string variable [, bool walk_to_top] | string',
+\ 'apache_get_modules(': 'void  | array',
+\ 'apache_get_version(': 'void  | string',
+\ 'apache_lookup_uri(': 'string filename | object',
+\ 'apache_note(': 'string note_name [, string note_value] | string',
+\ 'apache_request_headers(': 'void  | array',
+\ 'apache_reset_timeout(': 'void  | bool',
+\ 'apache_response_headers(': 'void  | array',
+\ 'apache_setenv(': 'string variable, string value [, bool walk_to_top] | bool',
+\ 'apc_cache_info(': '[string cache_type] | array',
+\ 'apc_clear_cache(': '[string cache_type] | bool',
+\ 'apc_define_constants(': 'string key, array constants [, bool case_sensitive] | bool',
+\ 'apc_delete(': 'string key | bool',
+\ 'apc_fetch(': 'string key | mixed',
+\ 'apc_load_constants(': 'string key [, bool case_sensitive] | bool',
+\ 'apc_sma_info(': 'void  | array',
+\ 'apc_store(': 'string key, mixed var [, int ttl] | bool',
+\ 'apd_breakpoint(': 'int debug_level | bool',
+\ 'apd_callstack(': 'void  | array',
+\ 'apd_clunk(': 'string warning [, string delimiter] | void',
+\ 'apd_continue(': 'int debug_level | bool',
+\ 'apd_croak(': 'string warning [, string delimiter] | void',
+\ 'apd_dump_function_table(': 'void  | void',
+\ 'apd_dump_persistent_resources(': 'void  | array',
+\ 'apd_dump_regular_resources(': 'void  | array',
+\ 'apd_echo(': 'string output | bool',
+\ 'apd_get_active_symbols(': ' | array',
+\ 'apd_set_pprof_trace(': '[string dump_directory] | void',
+\ 'apd_set_session(': 'int debug_level | void',
+\ 'apd_set_session_trace(': 'int debug_level [, string dump_directory] | void',
+\ 'apd_set_socket_session_trace(': 'string ip_address_or_unix_socket_file, int socket_type, int port, int debug_level | bool',
+\ 'array_change_key_case(': 'array input [, int case] | array',
+\ 'array_chunk(': 'array input, int size [, bool preserve_keys] | array',
+\ 'array_combine(': 'array keys, array values | array',
+\ 'array_count_values(': 'array input | array',
+\ 'array_diff_assoc(': 'array array1, array array2 [, array ...] | array',
+\ 'array_diff(': 'array array1, array array2 [, array ...] | array',
+\ 'array_diff_key(': 'array array1, array array2 [, array ...] | array',
+\ 'array_diff_uassoc(': 'array array1, array array2 [, array ..., callback key_compare_func] | array',
+\ 'array_diff_ukey(': 'array array1, array array2 [, array ..., callback key_compare_func] | array',
+\ 'array_fill(': 'int start_index, int num, mixed value | array',
+\ 'array_filter(': 'array input [, callback callback] | array',
+\ 'array_flip(': 'array trans | array',
+\ 'array(': '[mixed ...] | array',
+\ 'array_intersect_assoc(': 'array array1, array array2 [, array ...] | array',
+\ 'array_intersect(': 'array array1, array array2 [, array ...] | array',
+\ 'array_intersect_key(': 'array array1, array array2 [, array ...] | array',
+\ 'array_intersect_uassoc(': 'array array1, array array2 [, array ..., callback key_compare_func] | array',
+\ 'array_intersect_ukey(': 'array array1, array array2 [, array ..., callback key_compare_func] | array',
+\ 'array_key_exists(': 'mixed key, array search | bool',
+\ 'array_keys(': 'array input [, mixed search_value [, bool strict]] | array',
+\ 'array_map(': 'callback callback, array arr1 [, array ...] | array',
+\ 'array_merge(': 'array array1 [, array array2 [, array ...]] | array',
+\ 'array_merge_recursive(': 'array array1 [, array ...] | array',
+\ 'array_multisort(': 'array ar1 [, mixed arg [, mixed ... [, array ...]]] | bool',
+\ 'array_pad(': 'array input, int pad_size, mixed pad_value | array',
+\ 'array_pop(': 'array &#38;array | mixed',
+\ 'array_product(': 'array array | number',
+\ 'array_push(': 'array &#38;array, mixed var [, mixed ...] | int',
+\ 'array_rand(': 'array input [, int num_req] | mixed',
+\ 'array_reduce(': 'array input, callback function [, int initial] | mixed',
+\ 'array_reverse(': 'array array [, bool preserve_keys] | array',
+\ 'array_search(': 'mixed needle, array haystack [, bool strict] | mixed',
+\ 'array_shift(': 'array &#38;array | mixed',
+\ 'array_slice(': 'array array, int offset [, int length [, bool preserve_keys]] | array',
+\ 'array_splice(': 'array &#38;input, int offset [, int length [, array replacement]] | array',
+\ 'array_sum(': 'array array | number',
+\ 'array_udiff_assoc(': 'array array1, array array2 [, array ..., callback data_compare_func] | array',
+\ 'array_udiff(': 'array array1, array array2 [, array ..., callback data_compare_func] | array',
+\ 'array_udiff_uassoc(': 'array array1, array array2 [, array ..., callback data_compare_func, callback key_compare_func] | array',
+\ 'array_uintersect_assoc(': 'array array1, array array2 [, array ..., callback data_compare_func] | array',
+\ 'array_uintersect(': 'array array1, array array2 [, array ..., callback data_compare_func] | array',
+\ 'array_uintersect_uassoc(': 'array array1, array array2 [, array ..., callback data_compare_func, callback key_compare_func] | array',
+\ 'array_unique(': 'array array | array',
+\ 'array_unshift(': 'array &#38;array, mixed var [, mixed ...] | int',
+\ 'array_values(': 'array input | array',
+\ 'array_walk(': 'array &#38;array, callback funcname [, mixed userdata] | bool',
+\ 'array_walk_recursive(': 'array &#38;input, callback funcname [, mixed userdata] | bool',
+\ 'arsort(': 'array &#38;array [, int sort_flags] | bool',
+\ 'ascii2ebcdic(': 'string ascii_str | int',
+\ 'asinh(': 'float arg | float',
+\ 'asin(': 'float arg | float',
+\ 'asort(': 'array &#38;array [, int sort_flags] | bool',
+\ 'aspell_check(': 'int dictionary_link, string word | bool',
+\ 'aspell_check_raw(': 'int dictionary_link, string word | bool',
+\ 'aspell_new(': 'string master [, string personal] | int',
+\ 'aspell_suggest(': 'int dictionary_link, string word | array',
+\ 'assert(': 'mixed assertion | bool',
+\ 'assert_options(': 'int what [, mixed value] | mixed',
+\ 'atan2(': 'float y, float x | float',
+\ 'atanh(': 'float arg | float',
+\ 'atan(': 'float arg | float',
+\ 'base64_decode(': 'string encoded_data | string',
+\ 'base64_encode(': 'string data | string',
+\ 'base_convert(': 'string number, int frombase, int tobase | string',
+\ 'basename(': 'string path [, string suffix] | string',
+\ 'bcadd(': 'string left_operand, string right_operand [, int scale] | string',
+\ 'bccomp(': 'string left_operand, string right_operand [, int scale] | int',
+\ 'bcdiv(': 'string left_operand, string right_operand [, int scale] | string',
+\ 'bcmod(': 'string left_operand, string modulus | string',
+\ 'bcmul(': 'string left_operand, string right_operand [, int scale] | string',
+\ 'bcompiler_load_exe(': 'string filename | bool',
+\ 'bcompiler_load(': 'string filename | bool',
+\ 'bcompiler_parse_class(': 'string class, string callback | bool',
+\ 'bcompiler_read(': 'resource filehandle | bool',
+\ 'bcompiler_write_class(': 'resource filehandle, string className [, string extends] | bool',
+\ 'bcompiler_write_constant(': 'resource filehandle, string constantName | bool',
+\ 'bcompiler_write_exe_footer(': 'resource filehandle, int startpos | bool',
+\ 'bcompiler_write_file(': 'resource filehandle, string filename | bool',
+\ 'bcompiler_write_footer(': 'resource filehandle | bool',
+\ 'bcompiler_write_function(': 'resource filehandle, string functionName | bool',
+\ 'bcompiler_write_functions_from_file(': 'resource filehandle, string fileName | bool',
+\ 'bcompiler_write_header(': 'resource filehandle [, string write_ver] | bool',
+\ 'bcpow(': 'string x, string y [, int scale] | string',
+\ 'bcpowmod(': 'string x, string y, string modulus [, int scale] | string',
+\ 'bcscale(': 'int scale | bool',
+\ 'bcsqrt(': 'string operand [, int scale] | string',
+\ 'bcsub(': 'string left_operand, string right_operand [, int scale] | string',
+\ 'bin2hex(': 'string str | string',
+\ 'bindec(': 'string binary_string | number',
+\ 'bind_textdomain_codeset(': 'string domain, string codeset | string',
+\ 'bindtextdomain(': 'string domain, string directory | string',
+\ 'bzclose(': 'resource bz | int',
+\ 'bzcompress(': 'string source [, int blocksize [, int workfactor]] | mixed',
+\ 'bzdecompress(': 'string source [, int small] | mixed',
+\ 'bzerrno(': 'resource bz | int',
+\ 'bzerror(': 'resource bz | array',
+\ 'bzerrstr(': 'resource bz | string',
+\ 'bzflush(': 'resource bz | int',
+\ 'bzopen(': 'string filename, string mode | resource',
+\ 'bzread(': 'resource bz [, int length] | string',
+\ 'bzwrite(': 'resource bz, string data [, int length] | int',
+\ 'cal_days_in_month(': 'int calendar, int month, int year | int',
+\ 'cal_from_jd(': 'int jd, int calendar | array',
+\ 'cal_info(': '[int calendar] | array',
+\ 'call_user_func_array(': 'callback function, array param_arr | mixed',
+\ 'call_user_func(': 'callback function [, mixed parameter [, mixed ...]] | mixed',
+\ 'call_user_method_array(': 'string method_name, object &#38;obj, array paramarr | mixed',
+\ 'call_user_method(': 'string method_name, object &#38;obj [, mixed parameter [, mixed ...]] | mixed',
+\ 'cal_to_jd(': 'int calendar, int month, int day, int year | int',
+\ 'ccvs_add(': 'string session, string invoice, string argtype, string argval | string',
+\ 'ccvs_auth(': 'string session, string invoice | string',
+\ 'ccvs_command(': 'string session, string type, string argval | string',
+\ 'ccvs_count(': 'string session, string type | int',
+\ 'ccvs_delete(': 'string session, string invoice | string',
+\ 'ccvs_done(': 'string sess | string',
+\ 'ccvs_init(': 'string name | string',
+\ 'ccvs_lookup(': 'string session, string invoice, int inum | string',
+\ 'ccvs_new(': 'string session, string invoice | string',
+\ 'ccvs_report(': 'string session, string type | string',
+\ 'ccvs_return(': 'string session, string invoice | string',
+\ 'ccvs_reverse(': 'string session, string invoice | string',
+\ 'ccvs_sale(': 'string session, string invoice | string',
+\ 'ccvs_status(': 'string session, string invoice | string',
+\ 'ccvs_textvalue(': 'string session | string',
+\ 'ccvs_void(': 'string session, string invoice | string',
+\ 'ceil(': 'float value | float',
+\ 'chdir(': 'string directory | bool',
+\ 'checkdate(': 'int month, int day, int year | bool',
+\ 'checkdnsrr(': 'string host [, string type] | int',
+\ 'chgrp(': 'string filename, mixed group | bool',
+\ 'chmod(': 'string filename, int mode | bool',
+\ 'chown(': 'string filename, mixed user | bool',
+\ 'chr(': 'int ascii | string',
+\ 'chroot(': 'string directory | bool',
+\ 'chunk_split(': 'string body [, int chunklen [, string end]] | string',
+\ 'class_exists(': 'string class_name [, bool autoload] | bool',
+\ 'class_implements(': 'mixed class [, bool autoload] | array',
+\ 'classkit_import(': 'string filename | array',
+\ 'classkit_method_add(': 'string classname, string methodname, string args, string code [, int flags] | bool',
+\ 'classkit_method_copy(': 'string dClass, string dMethod, string sClass [, string sMethod] | bool',
+\ 'classkit_method_redefine(': 'string classname, string methodname, string args, string code [, int flags] | bool',
+\ 'classkit_method_remove(': 'string classname, string methodname | bool',
+\ 'classkit_method_rename(': 'string classname, string methodname, string newname | bool',
+\ 'class_parents(': 'mixed class [, bool autoload] | array',
+\ 'clearstatcache(': 'void  | void',
+\ 'closedir(': 'resource dir_handle | void',
+\ 'closelog(': 'void  | bool',
+\ 'com_addref(': 'void  | void',
+\ 'com_create_guid(': 'void  | string',
+\ 'com_event_sink(': 'variant comobject, object sinkobject [, mixed sinkinterface] | bool',
+\ 'com_get_active_object(': 'string progid [, int code_page] | variant',
+\ 'com_get(': 'resource com_object, string property | mixed',
+\ 'com_invoke(': 'resource com_object, string function_name [, mixed function_parameters] | mixed',
+\ 'com_isenum(': 'variant com_module | bool',
+\ 'com_load(': 'string module_name [, string server_name [, int codepage]] | resource',
+\ 'com_load_typelib(': 'string typelib_name [, bool case_insensitive] | bool',
+\ 'com_message_pump(': '[int timeoutms] | bool',
+\ 'compact(': 'mixed varname [, mixed ...] | array',
+\ 'com_print_typeinfo(': 'object comobject [, string dispinterface [, bool wantsink]] | bool',
+\ 'com_release(': 'void  | void',
+\ 'com_set(': 'resource com_object, string property, mixed value | void',
+\ 'connection_aborted(': 'void  | int',
+\ 'connection_status(': 'void  | int',
+\ 'connection_timeout(': 'void  | bool',
+\ 'constant(': 'string name | mixed',
+\ 'convert_cyr_string(': 'string str, string from, string to | string',
+\ 'convert_uudecode(': 'string data | string',
+\ 'convert_uuencode(': 'string data | string',
+\ 'copy(': 'string source, string dest | bool',
+\ 'cosh(': 'float arg | float',
+\ 'cos(': 'float arg | float',
+\ 'count_chars(': 'string string [, int mode] | mixed',
+\ 'count(': 'mixed var [, int mode] | int',
+\ 'cpdf_add_annotation(': 'int pdf_document, float llx, float lly, float urx, float ury, string title, string content [, int mode] | bool',
+\ 'cpdf_add_outline(': 'int pdf_document, int lastoutline, int sublevel, int open, int pagenr, string text | int',
+\ 'cpdf_arc(': 'int pdf_document, float x_coor, float y_coor, float radius, float start, float end [, int mode] | bool',
+\ 'cpdf_begin_text(': 'int pdf_document | bool',
+\ 'cpdf_circle(': 'int pdf_document, float x_coor, float y_coor, float radius [, int mode] | bool',
+\ 'cpdf_clip(': 'int pdf_document | bool',
+\ 'cpdf_close(': 'int pdf_document | bool',
+\ 'cpdf_closepath_fill_stroke(': 'int pdf_document | bool',
+\ 'cpdf_closepath(': 'int pdf_document | bool',
+\ 'cpdf_closepath_stroke(': 'int pdf_document | bool',
+\ 'cpdf_continue_text(': 'int pdf_document, string text | bool',
+\ 'cpdf_curveto(': 'int pdf_document, float x1, float y1, float x2, float y2, float x3, float y3 [, int mode] | bool',
+\ 'cpdf_end_text(': 'int pdf_document | bool',
+\ 'cpdf_fill(': 'int pdf_document | bool',
+\ 'cpdf_fill_stroke(': 'int pdf_document | bool',
+\ 'cpdf_finalize(': 'int pdf_document | bool',
+\ 'cpdf_finalize_page(': 'int pdf_document, int page_number | bool',
+\ 'cpdf_global_set_document_limits(': 'int maxpages, int maxfonts, int maximages, int maxannotations, int maxobjects | bool',
+\ 'cpdf_import_jpeg(': 'int pdf_document, string file_name, float x_coor, float y_coor, float angle, float width, float height, float x_scale, float y_scale, int gsave [, int mode] | bool',
+\ 'cpdf_lineto(': 'int pdf_document, float x_coor, float y_coor [, int mode] | bool',
+\ 'cpdf_moveto(': 'int pdf_document, float x_coor, float y_coor [, int mode] | bool',
+\ 'cpdf_newpath(': 'int pdf_document | bool',
+\ 'cpdf_open(': 'int compression [, string filename [, array doc_limits]] | int',
+\ 'cpdf_output_buffer(': 'int pdf_document | bool',
+\ 'cpdf_page_init(': 'int pdf_document, int page_number, int orientation, float height, float width [, float unit] | bool',
+\ 'cpdf_place_inline_image(': 'int pdf_document, int image, float x_coor, float y_coor, float angle, float width, float height, int gsave [, int mode] | bool',
+\ 'cpdf_rect(': 'int pdf_document, float x_coor, float y_coor, float width, float height [, int mode] | bool',
+\ 'cpdf_restore(': 'int pdf_document | bool',
+\ 'cpdf_rlineto(': 'int pdf_document, float x_coor, float y_coor [, int mode] | bool',
+\ 'cpdf_rmoveto(': 'int pdf_document, float x_coor, float y_coor [, int mode] | bool',
+\ 'cpdf_rotate(': 'int pdf_document, float angle | bool',
+\ 'cpdf_rotate_text(': 'int pdfdoc, float angle | bool',
+\ 'cpdf_save(': 'int pdf_document | bool',
+\ 'cpdf_save_to_file(': 'int pdf_document, string filename | bool',
+\ 'cpdf_scale(': 'int pdf_document, float x_scale, float y_scale | bool',
+\ 'cpdf_set_action_url(': 'int pdfdoc, float xll, float yll, float xur, float xur, string url [, int mode] | bool',
+\ 'cpdf_set_char_spacing(': 'int pdf_document, float space | bool',
+\ 'cpdf_set_creator(': 'int pdf_document, string creator | bool',
+\ 'cpdf_set_current_page(': 'int pdf_document, int page_number | bool',
+\ 'cpdf_setdash(': 'int pdf_document, float white, float black | bool',
+\ 'cpdf_setflat(': 'int pdf_document, float value | bool',
+\ 'cpdf_set_font_directories(': 'int pdfdoc, string pfmdir, string pfbdir | bool',
+\ 'cpdf_set_font(': 'int pdf_document, string font_name, float size, string encoding | bool',
+\ 'cpdf_set_font_map_file(': 'int pdfdoc, string filename | bool',
+\ 'cpdf_setgray_fill(': 'int pdf_document, float value | bool',
+\ 'cpdf_setgray(': 'int pdf_document, float gray_value | bool',
+\ 'cpdf_setgray_stroke(': 'int pdf_document, float gray_value | bool',
+\ 'cpdf_set_horiz_scaling(': 'int pdf_document, float scale | bool',
+\ 'cpdf_set_keywords(': 'int pdf_document, string keywords | bool',
+\ 'cpdf_set_leading(': 'int pdf_document, float distance | bool',
+\ 'cpdf_setlinecap(': 'int pdf_document, int value | bool',
+\ 'cpdf_setlinejoin(': 'int pdf_document, int value | bool',
+\ 'cpdf_setlinewidth(': 'int pdf_document, float width | bool',
+\ 'cpdf_setmiterlimit(': 'int pdf_document, float value | bool',
+\ 'cpdf_set_page_animation(': 'int pdf_document, int transition, float duration, float direction, int orientation, int inout | bool',
+\ 'cpdf_setrgbcolor_fill(': 'int pdf_document, float red_value, float green_value, float blue_value | bool',
+\ 'cpdf_setrgbcolor(': 'int pdf_document, float red_value, float green_value, float blue_value | bool',
+\ 'cpdf_setrgbcolor_stroke(': 'int pdf_document, float red_value, float green_value, float blue_value | bool',
+\ 'cpdf_set_subject(': 'int pdf_document, string subject | bool',
+\ 'cpdf_set_text_matrix(': 'int pdf_document, array matrix | bool',
+\ 'cpdf_set_text_pos(': 'int pdf_document, float x_coor, float y_coor [, int mode] | bool',
+\ 'cpdf_set_text_rendering(': 'int pdf_document, int rendermode | bool',
+\ 'cpdf_set_text_rise(': 'int pdf_document, float value | bool',
+\ 'cpdf_set_title(': 'int pdf_document, string title | bool',
+\ 'cpdf_set_viewer_preferences(': 'int pdfdoc, array preferences | bool',
+\ 'cpdf_set_word_spacing(': 'int pdf_document, float space | bool',
+\ 'cpdf_show(': 'int pdf_document, string text | bool',
+\ 'cpdf_show_xy(': 'int pdf_document, string text, float x_coor, float y_coor [, int mode] | bool',
+\ 'cpdf_stringwidth(': 'int pdf_document, string text | float',
+\ 'cpdf_stroke(': 'int pdf_document | bool',
+\ 'cpdf_text(': 'int pdf_document, string text [, float x_coor, float y_coor [, int mode [, float orientation [, int alignmode]]]] | bool',
+\ 'cpdf_translate(': 'int pdf_document, float x_coor, float y_coor | bool',
+\ 'crack_check(': 'resource dictionary, string password | bool',
+\ 'crack_closedict(': '[resource dictionary] | bool',
+\ 'crack_getlastmessage(': 'void  | string',
+\ 'crack_opendict(': 'string dictionary | resource',
+\ 'crc32(': 'string str | int',
+\ 'create_function(': 'string args, string code | string',
+\ 'crypt(': 'string str [, string salt] | string',
+\ 'ctype_alnum(': 'string text | bool',
+\ 'ctype_alpha(': 'string text | bool',
+\ 'ctype_cntrl(': 'string text | bool',
+\ 'ctype_digit(': 'string text | bool',
+\ 'ctype_graph(': 'string text | bool',
+\ 'ctype_lower(': 'string text | bool',
+\ 'ctype_print(': 'string text | bool',
+\ 'ctype_punct(': 'string text | bool',
+\ 'ctype_space(': 'string text | bool',
+\ 'ctype_upper(': 'string text | bool',
+\ 'ctype_xdigit(': 'string text | bool',
+\ 'curl_close(': 'resource ch | void',
+\ 'curl_copy_handle(': 'resource ch | resource',
+\ 'curl_errno(': 'resource ch | int',
+\ 'curl_error(': 'resource ch | string',
+\ 'curl_exec(': 'resource ch | mixed',
+\ 'curl_getinfo(': 'resource ch [, int opt] | mixed',
+\ 'curl_init(': '[string url] | resource',
+\ 'curl_multi_add_handle(': 'resource mh, resource ch | int',
+\ 'curl_multi_close(': 'resource mh | void',
+\ 'curl_multi_exec(': 'resource mh, int &#38;still_running | int',
+\ 'curl_multi_getcontent(': 'resource ch | string',
+\ 'curl_multi_info_read(': 'resource mh | array',
+\ 'curl_multi_init(': 'void  | resource',
+\ 'curl_multi_remove_handle(': 'resource mh, resource ch | int',
+\ 'curl_multi_select(': 'resource mh [, float timeout] | int',
+\ 'curl_setopt(': 'resource ch, int option, mixed value | bool',
+\ 'curl_version(': '[int version] | array',
+\ 'current(': 'array &#38;array | mixed',
+\ 'cybercash_base64_decode(': 'string inbuff | string',
+\ 'cybercash_base64_encode(': 'string inbuff | string',
+\ 'cybercash_decr(': 'string wmk, string sk, string inbuff | array',
+\ 'cybercash_encr(': 'string wmk, string sk, string inbuff | array',
+\ 'cybermut_creerformulairecm(': 'string url_cm, string version, string tpe, string price, string ref_command, string text_free, string url_return, string url_return_ok, string url_return_err, string language, string code_company, string text_button | string',
+\ 'cybermut_creerreponsecm(': 'string sentence | string',
+\ 'cybermut_testmac(': 'string code_mac, string version, string tpe, string cdate, string price, string ref_command, string text_free, string code_return | bool',
+\ 'cyrus_authenticate(': 'resource connection [, string mechlist [, string service [, string user [, int minssf [, int maxssf [, string authname [, string password]]]]]]] | void',
+\ 'cyrus_bind(': 'resource connection, array callbacks | bool',
+\ 'cyrus_close(': 'resource connection | bool',
+\ 'cyrus_connect(': '[string host [, string port [, int flags]]] | resource',
+\ 'cyrus_query(': 'resource connection, string query | array',
+\ 'cyrus_unbind(': 'resource connection, string trigger_name | bool',
+\ 'date_default_timezone_get(': 'void  | string',
+\ 'date_default_timezone_set(': 'string timezone_identifier | bool',
+\ 'date(': 'string format [, int timestamp] | string',
+\ 'date_sunrise(': 'int timestamp [, int format [, float latitude [, float longitude [, float zenith [, float gmt_offset]]]]] | mixed',
+\ 'date_sunset(': 'int timestamp [, int format [, float latitude [, float longitude [, float zenith [, float gmt_offset]]]]] | mixed',
+\ 'db2_autocommit(': 'resource connection [, bool value] | mixed',
+\ 'db2_bind_param(': 'resource stmt, int parameter-number, string variable-name [, int parameter-type [, int data-type [, int precision [, int scale]]]] | bool',
+\ 'db2_client_info(': 'resource connection | object',
+\ 'db2_close(': 'resource connection | bool',
+\ 'db2_column_privileges(': 'resource connection [, string qualifier [, string schema [, string table-name [, string column-name]]]] | resource',
+\ 'db2_columns(': 'resource connection [, string qualifier [, string schema [, string table-name [, string column-name]]]] | resource',
+\ 'db2_commit(': 'resource connection | bool',
+\ 'db2_connect(': 'string database, string username, string password [, array options] | resource',
+\ 'db2_conn_error(': '[resource connection] | string',
+\ 'db2_conn_errormsg(': '[resource connection] | string',
+\ 'db2_cursor_type(': 'resource stmt | int',
+\ 'db2_exec(': 'resource connection, string statement [, array options] | resource',
+\ 'db2_execute(': 'resource stmt [, array parameters] | bool',
+\ 'db2_fetch_array(': 'resource stmt [, int row_number] | array',
+\ 'db2_fetch_assoc(': 'resource stmt [, int row_number] | array',
+\ 'db2_fetch_both(': 'resource stmt [, int row_number] | array',
+\ 'db2_fetch_object(': 'resource stmt [, int row_number] | object',
+\ 'db2_fetch_row(': 'resource stmt [, int row_number] | bool',
+\ 'db2_field_display_size(': 'resource stmt, mixed column | int',
+\ 'db2_field_name(': 'resource stmt, mixed column | string',
+\ 'db2_field_num(': 'resource stmt, mixed column | int',
+\ 'db2_field_precision(': 'resource stmt, mixed column | int',
+\ 'db2_field_scale(': 'resource stmt, mixed column | int',
+\ 'db2_field_type(': 'resource stmt, mixed column | string',
+\ 'db2_field_width(': 'resource stmt, mixed column | int',
+\ 'db2_foreign_keys(': 'resource connection, string qualifier, string schema, string table-name | resource',
+\ 'db2_free_result(': 'resource stmt | bool',
+\ 'db2_free_stmt(': 'resource stmt | bool',
+\ 'db2_next_result(': 'resource stmt | resource',
+\ 'db2_num_fields(': 'resource stmt | int',
+\ 'db2_num_rows(': 'resource stmt | int',
+\ 'db2_pconnect(': 'string database, string username, string password [, array options] | resource',
+\ 'db2_prepare(': 'resource connection, string statement [, array options] | resource',
+\ 'db2_primary_keys(': 'resource connection, string qualifier, string schema, string table-name | resource',
+\ 'db2_procedure_columns(': 'resource connection, string qualifier, string schema, string procedure, string parameter | resource',
+\ 'db2_procedures(': 'resource connection, string qualifier, string schema, string procedure | resource',
+\ 'db2_result(': 'resource stmt, mixed column | mixed',
+\ 'db2_rollback(': 'resource connection | bool',
+\ 'db2_server_info(': 'resource connection | object',
+\ 'db2_special_columns(': 'resource connection, string qualifier, string schema, string table_name, int scope | resource',
+\ 'db2_statistics(': 'resource connection, string qualifier, string schema, string table-name, bool unique | resource',
+\ 'db2_stmt_error(': '[resource stmt] | string',
+\ 'db2_stmt_errormsg(': '[resource stmt] | string',
+\ 'db2_table_privileges(': 'resource connection [, string qualifier [, string schema [, string table_name]]] | resource',
+\ 'db2_tables(': 'resource connection [, string qualifier [, string schema [, string table-name [, string table-type]]]] | resource',
+\ 'dba_close(': 'resource handle | void',
+\ 'dba_delete(': 'string key, resource handle | bool',
+\ 'dba_exists(': 'string key, resource handle | bool',
+\ 'dba_fetch(': 'string key, resource handle | string',
+\ 'dba_firstkey(': 'resource handle | string',
+\ 'dba_handlers(': '[bool full_info] | array',
+\ 'dba_insert(': 'string key, string value, resource handle | bool',
+\ 'dba_key_split(': 'mixed key | mixed',
+\ 'dba_list(': 'void  | array',
+\ 'dba_nextkey(': 'resource handle | string',
+\ 'dba_open(': 'string path, string mode [, string handler [, mixed ...]] | resource',
+\ 'dba_optimize(': 'resource handle | bool',
+\ 'dba_popen(': 'string path, string mode [, string handler [, mixed ...]] | resource',
+\ 'dba_replace(': 'string key, string value, resource handle | bool',
+\ 'dbase_add_record(': 'int dbase_identifier, array record | bool',
+\ 'dbase_close(': 'int dbase_identifier | bool',
+\ 'dbase_create(': 'string filename, array fields | int',
+\ 'dbase_delete_record(': 'int dbase_identifier, int record_number | bool',
+\ 'dbase_get_header_info(': 'int dbase_identifier | array',
+\ 'dbase_get_record(': 'int dbase_identifier, int record_number | array',
+\ 'dbase_get_record_with_names(': 'int dbase_identifier, int record_number | array',
+\ 'dbase_numfields(': 'int dbase_identifier | int',
+\ 'dbase_numrecords(': 'int dbase_identifier | int',
+\ 'dbase_open(': 'string filename, int mode | int',
+\ 'dbase_pack(': 'int dbase_identifier | bool',
+\ 'dbase_replace_record(': 'int dbase_identifier, array record, int record_number | bool',
+\ 'dba_sync(': 'resource handle | bool',
+\ 'dblist(': 'void  | string',
+\ 'dbmclose(': 'resource dbm_identifier | bool',
+\ 'dbmdelete(': 'resource dbm_identifier, string key | bool',
+\ 'dbmexists(': 'resource dbm_identifier, string key | bool',
+\ 'dbmfetch(': 'resource dbm_identifier, string key | string',
+\ 'dbmfirstkey(': 'resource dbm_identifier | string',
+\ 'dbminsert(': 'resource dbm_identifier, string key, string value | int',
+\ 'dbmnextkey(': 'resource dbm_identifier, string key | string',
+\ 'dbmopen(': 'string filename, string flags | resource',
+\ 'dbmreplace(': 'resource dbm_identifier, string key, string value | int',
+\ 'dbplus_add(': 'resource relation, array tuple | int',
+\ 'dbplus_aql(': 'string query [, string server [, string dbpath]] | resource',
+\ 'dbplus_chdir(': '[string newdir] | string',
+\ 'dbplus_close(': 'resource relation | mixed',
+\ 'dbplus_curr(': 'resource relation, array &#38;tuple | int',
+\ 'dbplus_errcode(': '[int errno] | string',
+\ 'dbplus_errno(': 'void  | int',
+\ 'dbplus_find(': 'resource relation, array constraints, mixed tuple | int',
+\ 'dbplus_first(': 'resource relation, array &#38;tuple | int',
+\ 'dbplus_flush(': 'resource relation | int',
+\ 'dbplus_freealllocks(': 'void  | int',
+\ 'dbplus_freelock(': 'resource relation, string tname | int',
+\ 'dbplus_freerlocks(': 'resource relation | int',
+\ 'dbplus_getlock(': 'resource relation, string tname | int',
+\ 'dbplus_getunique(': 'resource relation, int uniqueid | int',
+\ 'dbplus_info(': 'resource relation, string key, array &#38;result | int',
+\ 'dbplus_last(': 'resource relation, array &#38;tuple | int',
+\ 'dbplus_lockrel(': 'resource relation | int',
+\ 'dbplus_next(': 'resource relation, array &#38;tuple | int',
+\ 'dbplus_open(': 'string name | resource',
+\ 'dbplus_prev(': 'resource relation, array &#38;tuple | int',
+\ 'dbplus_rchperm(': 'resource relation, int mask, string user, string group | int',
+\ 'dbplus_rcreate(': 'string name, mixed domlist [, bool overwrite] | resource',
+\ 'dbplus_rcrtexact(': 'string name, resource relation [, bool overwrite] | mixed',
+\ 'dbplus_rcrtlike(': 'string name, resource relation [, int overwrite] | mixed',
+\ 'dbplus_resolve(': 'string relation_name | array',
+\ 'dbplus_restorepos(': 'resource relation, array tuple | int',
+\ 'dbplus_rkeys(': 'resource relation, mixed domlist | mixed',
+\ 'dbplus_ropen(': 'string name | resource',
+\ 'dbplus_rquery(': 'string query [, string dbpath] | resource',
+\ 'dbplus_rrename(': 'resource relation, string name | int',
+\ 'dbplus_rsecindex(': 'resource relation, mixed domlist, int type | mixed',
+\ 'dbplus_runlink(': 'resource relation | int',
+\ 'dbplus_rzap(': 'resource relation | int',
+\ 'dbplus_savepos(': 'resource relation | int',
+\ 'dbplus_setindexbynumber(': 'resource relation, int idx_number | int',
+\ 'dbplus_setindex(': 'resource relation, string idx_name | int',
+\ 'dbplus_sql(': 'string query [, string server [, string dbpath]] | resource',
+\ 'dbplus_tcl(': 'int sid, string script | string',
+\ 'dbplus_tremove(': 'resource relation, array tuple [, array &#38;current] | int',
+\ 'dbplus_undo(': 'resource relation | int',
+\ 'dbplus_undoprepare(': 'resource relation | int',
+\ 'dbplus_unlockrel(': 'resource relation | int',
+\ 'dbplus_unselect(': 'resource relation | int',
+\ 'dbplus_update(': 'resource relation, array old, array new | int',
+\ 'dbplus_xlockrel(': 'resource relation | int',
+\ 'dbplus_xunlockrel(': 'resource relation | int',
+\ 'dbx_close(': 'object link_identifier | bool',
+\ 'dbx_compare(': 'array row_a, array row_b, string column_key [, int flags] | int',
+\ 'dbx_connect(': 'mixed module, string host, string database, string username, string password [, int persistent] | object',
+\ 'dbx_error(': 'object link_identifier | string',
+\ 'dbx_escape_string(': 'object link_identifier, string text | string',
+\ 'dbx_fetch_row(': 'object result_identifier | mixed',
+\ 'dbx_query(': 'object link_identifier, string sql_statement [, int flags] | mixed',
+\ 'dbx_sort(': 'object result, string user_compare_function | bool',
+\ 'dcgettext(': 'string domain, string message, int category | string',
+\ 'dcngettext(': 'string domain, string msgid1, string msgid2, int n, int category | string',
+\ 'deaggregate(': 'object object [, string class_name] | void',
+\ 'debug_backtrace(': 'void  | array',
+\ 'debugger_off(': 'void  | int',
+\ 'debugger_on(': 'string address | int',
+\ 'debug_print_backtrace(': 'void  | void',
+\ 'debug_zval_dump(': 'mixed variable | void',
+\ 'decbin(': 'int number | string',
+\ 'dechex(': 'int number | string',
+\ 'decoct(': 'int number | string',
+\ 'defined(': 'string name | bool',
+\ 'define(': 'string name, mixed value [, bool case_insensitive] | bool',
+\ 'define_syslog_variables(': 'void  | void',
+\ 'deg2rad(': 'float number | float',
+\ 'delete(': 'string file | void',
+\ 'dgettext(': 'string domain, string message | string',
+\ 'dio_close(': 'resource fd | void',
+\ 'dio_fcntl(': 'resource fd, int cmd [, mixed args] | mixed',
+\ 'dio_open(': 'string filename, int flags [, int mode] | resource',
+\ 'dio_read(': 'resource fd [, int len] | string',
+\ 'dio_seek(': 'resource fd, int pos [, int whence] | int',
+\ 'dio_stat(': 'resource fd | array',
+\ 'dio_tcsetattr(': 'resource fd, array options | bool',
+\ 'dio_truncate(': 'resource fd, int offset | bool',
+\ 'dio_write(': 'resource fd, string data [, int len] | int',
+\ 'dirname(': 'string path | string',
+\ 'disk_free_space(': 'string directory | float',
+\ 'disk_total_space(': 'string directory | float',
+\ 'dl(': 'string library | int',
+\ 'dngettext(': 'string domain, string msgid1, string msgid2, int n | string',
+\ 'dns_check_record(': 'string host [, string type] | bool',
+\ 'dns_get_mx(': 'string hostname, array &#38;mxhosts [, array &#38;weight] | bool',
+\ 'dns_get_record(': 'string hostname [, int type [, array &#38;authns, array &#38;addtl]] | array',
+\ 'DomDocument-&#62;add_root(': 'string name | domelement',
+\ 'DomDocument-&#62;create_attribute(': 'string name, string value | domattribute',
+\ 'DomDocument-&#62;create_cdata_section(': 'string content | domcdata',
+\ 'DomDocument-&#62;create_comment(': 'string content | domcomment',
+\ 'DomDocument-&#62;create_element(': 'string name | domelement',
+\ 'DomDocument-&#62;create_element_ns(': 'string uri, string name [, string prefix] | domelement',
+\ 'DomDocument-&#62;create_entity_reference(': 'string content | domentityreference',
+\ 'DomDocument-&#62;create_processing_instruction(': 'string content | domprocessinginstruction',
+\ 'DomDocument-&#62;create_text_node(': 'string content | domtext',
+\ 'DomDocument-&#62;doctype(': 'void  | domdocumenttype',
+\ 'DomDocument-&#62;document_element(': 'void  | domelement',
+\ 'DomDocument-&#62;dump_file(': 'string filename [, bool compressionmode [, bool format]] | string',
+\ 'DomDocument-&#62;dump_mem(': '[bool format [, string encoding]] | string',
+\ 'DomDocument-&#62;get_element_by_id(': 'string id | domelement',
+\ 'DomDocument-&#62;get_elements_by_tagname(': 'string name | array',
+\ 'DomDocument-&#62;html_dump_mem(': 'void  | string',
+\ 'DomDocument-&#62;xinclude(': 'void  | int',
+\ 'dom_import_simplexml(': 'SimpleXMLElement node | DOMElement',
+\ 'DomNode-&#62;append_sibling(': 'domelement newnode | domelement',
+\ 'DomNode-&#62;attributes(': 'void  | array',
+\ 'DomNode-&#62;child_nodes(': 'void  | array',
+\ 'DomNode-&#62;clone_node(': 'void  | domelement',
+\ 'DomNode-&#62;dump_node(': 'void  | string',
+\ 'DomNode-&#62;first_child(': 'void  | domelement',
+\ 'DomNode-&#62;get_content(': 'void  | string',
+\ 'DomNode-&#62;has_attributes(': 'void  | bool',
+\ 'DomNode-&#62;has_child_nodes(': 'void  | bool',
+\ 'DomNode-&#62;insert_before(': 'domelement newnode, domelement refnode | domelement',
+\ 'DomNode-&#62;is_blank_node(': 'void  | bool',
+\ 'DomNode-&#62;last_child(': 'void  | domelement',
+\ 'DomNode-&#62;next_sibling(': 'void  | domelement',
+\ 'DomNode-&#62;node_name(': 'void  | string',
+\ 'DomNode-&#62;node_type(': 'void  | int',
+\ 'DomNode-&#62;node_value(': 'void  | string',
+\ 'DomNode-&#62;owner_document(': 'void  | domdocument',
+\ 'DomNode-&#62;parent_node(': 'void  | domnode',
+\ 'DomNode-&#62;prefix(': 'void  | string',
+\ 'DomNode-&#62;previous_sibling(': 'void  | domelement',
+\ 'DomNode-&#62;remove_child(': 'domtext oldchild | domtext',
+\ 'DomNode-&#62;replace_child(': 'domelement oldnode, domelement newnode | domelement',
+\ 'DomNode-&#62;replace_node(': 'domelement newnode | domelement',
+\ 'DomNode-&#62;set_content(': 'string content | bool',
+\ 'DomNode-&#62;set_name(': 'void  | bool',
+\ 'DomNode-&#62;set_namespace(': 'string uri [, string prefix] | void',
+\ 'DomNode-&#62;unlink_node(': 'void  | void',
+\ 'domxml_new_doc(': 'string version | DomDocument',
+\ 'domxml_open_file(': 'string filename [, int mode [, array &#38;error]] | DomDocument',
+\ 'domxml_open_mem(': 'string str [, int mode [, array &#38;error]] | DomDocument',
+\ 'domxml_version(': 'void  | string',
+\ 'domxml_xmltree(': 'string str | DomDocument',
+\ 'domxml_xslt_stylesheet_doc(': 'DomDocument xsl_doc | DomXsltStylesheet',
+\ 'domxml_xslt_stylesheet_file(': 'string xsl_file | DomXsltStylesheet',
+\ 'domxml_xslt_stylesheet(': 'string xsl_buf | DomXsltStylesheet',
+\ 'domxml_xslt_version(': 'void  | int',
+\ 'dotnet_load(': 'string assembly_name [, string datatype_name [, int codepage]] | int',
+\ 'each(': 'array &#38;array | array',
+\ 'easter_date(': '[int year] | int',
+\ 'easter_days(': '[int year [, int method]] | int',
+\ 'ebcdic2ascii(': 'string ebcdic_str | int',
+\ 'echo(': 'string arg1 [, string ...] | void',
+\ 'empty(': 'mixed var | bool',
+\ 'end(': 'array &#38;array | mixed',
+\ 'ereg(': 'string pattern, string string [, array &#38;regs] | int',
+\ 'eregi(': 'string pattern, string string [, array &#38;regs] | int',
+\ 'eregi_replace(': 'string pattern, string replacement, string string | string',
+\ 'ereg_replace(': 'string pattern, string replacement, string string | string',
+\ 'error_log(': 'string message [, int message_type [, string destination [, string extra_headers]]] | bool',
+\ 'error_reporting(': '[int level] | int',
+\ 'escapeshellarg(': 'string arg | string',
+\ 'escapeshellcmd(': 'string command | string',
+\ 'eval(': 'string code_str | mixed',
+\ 'exec(': 'string command [, array &#38;output [, int &#38;return_var]] | string',
+\ 'exif_imagetype(': 'string filename | int',
+\ 'exif_read_data(': 'string filename [, string sections [, bool arrays [, bool thumbnail]]] | array',
+\ 'exif_tagname(': 'string index | string',
+\ 'exif_thumbnail(': 'string filename [, int &#38;width [, int &#38;height [, int &#38;imagetype]]] | string',
+\ 'exit(': '[string status] | void',
+\ 'expect_expectl(': 'resource expect, array cases, string &#38;match | mixed',
+\ 'expect_popen(': 'string command | resource',
+\ 'exp(': 'float arg | float',
+\ 'explode(': 'string separator, string string [, int limit] | array',
+\ 'expm1(': 'float number | float',
+\ 'extension_loaded(': 'string name | bool',
+\ 'extract(': 'array var_array [, int extract_type [, string prefix]] | int',
+\ 'ezmlm_hash(': 'string addr | int',
+\ 'fam_cancel_monitor(': 'resource fam, resource fam_monitor | bool',
+\ 'fam_close(': 'resource fam | void',
+\ 'fam_monitor_collection(': 'resource fam, string dirname, int depth, string mask | resource',
+\ 'fam_monitor_directory(': 'resource fam, string dirname | resource',
+\ 'fam_monitor_file(': 'resource fam, string filename | resource',
+\ 'fam_next_event(': 'resource fam | array',
+\ 'fam_open(': '[string appname] | resource',
+\ 'fam_pending(': 'resource fam | int',
+\ 'fam_resume_monitor(': 'resource fam, resource fam_monitor | bool',
+\ 'fam_suspend_monitor(': 'resource fam, resource fam_monitor | bool',
+\ 'fbsql_affected_rows(': '[resource link_identifier] | int',
+\ 'fbsql_autocommit(': 'resource link_identifier [, bool OnOff] | bool',
+\ 'fbsql_blob_size(': 'string blob_handle [, resource link_identifier] | int',
+\ 'fbsql_change_user(': 'string user, string password [, string database [, resource link_identifier]] | resource',
+\ 'fbsql_clob_size(': 'string clob_handle [, resource link_identifier] | int',
+\ 'fbsql_close(': '[resource link_identifier] | bool',
+\ 'fbsql_commit(': '[resource link_identifier] | bool',
+\ 'fbsql_connect(': '[string hostname [, string username [, string password]]] | resource',
+\ 'fbsql_create_blob(': 'string blob_data [, resource link_identifier] | string',
+\ 'fbsql_create_clob(': 'string clob_data [, resource link_identifier] | string',
+\ 'fbsql_create_db(': 'string database_name [, resource link_identifier [, string database_options]] | bool',
+\ 'fbsql_database(': 'resource link_identifier [, string database] | string',
+\ 'fbsql_database_password(': 'resource link_identifier [, string database_password] | string',
+\ 'fbsql_data_seek(': 'resource result_identifier, int row_number | bool',
+\ 'fbsql_db_query(': 'string database, string query [, resource link_identifier] | resource',
+\ 'fbsql_db_status(': 'string database_name [, resource link_identifier] | int',
+\ 'fbsql_drop_db(': 'string database_name [, resource link_identifier] | bool',
+\ 'fbsql_errno(': '[resource link_identifier] | int',
+\ 'fbsql_error(': '[resource link_identifier] | string',
+\ 'fbsql_fetch_array(': 'resource result [, int result_type] | array',
+\ 'fbsql_fetch_assoc(': 'resource result | array',
+\ 'fbsql_fetch_field(': 'resource result [, int field_offset] | object',
+\ 'fbsql_fetch_lengths(': 'resource result | array',
+\ 'fbsql_fetch_object(': 'resource result [, int result_type] | object',
+\ 'fbsql_fetch_row(': 'resource result | array',
+\ 'fbsql_field_flags(': 'resource result [, int field_offset] | string',
+\ 'fbsql_field_len(': 'resource result [, int field_offset] | int',
+\ 'fbsql_field_name(': 'resource result [, int field_index] | string',
+\ 'fbsql_field_seek(': 'resource result [, int field_offset] | bool',
+\ 'fbsql_field_table(': 'resource result [, int field_offset] | string',
+\ 'fbsql_field_type(': 'resource result [, int field_offset] | string',
+\ 'fbsql_free_result(': 'resource result | bool',
+\ 'fbsql_get_autostart_info(': '[resource link_identifier] | array',
+\ 'fbsql_hostname(': 'resource link_identifier [, string host_name] | string',
+\ 'fbsql_insert_id(': '[resource link_identifier] | int',
+\ 'fbsql_list_dbs(': '[resource link_identifier] | resource',
+\ 'fbsql_list_fields(': 'string database_name, string table_name [, resource link_identifier] | resource',
+\ 'fbsql_list_tables(': 'string database [, resource link_identifier] | resource',
+\ 'fbsql_next_result(': 'resource result_id | bool',
+\ 'fbsql_num_fields(': 'resource result | int',
+\ 'fbsql_num_rows(': 'resource result | int',
+\ 'fbsql_password(': 'resource link_identifier [, string password] | string',
+\ 'fbsql_pconnect(': '[string hostname [, string username [, string password]]] | resource',
+\ 'fbsql_query(': 'string query [, resource link_identifier [, int batch_size]] | resource',
+\ 'fbsql_read_blob(': 'string blob_handle [, resource link_identifier] | string',
+\ 'fbsql_read_clob(': 'string clob_handle [, resource link_identifier] | string',
+\ 'fbsql_result(': 'resource result [, int row [, mixed field]] | mixed',
+\ 'fbsql_rollback(': '[resource link_identifier] | bool',
+\ 'fbsql_select_db(': '[string database_name [, resource link_identifier]] | bool',
+\ 'fbsql_set_lob_mode(': 'resource result, string database_name | bool',
+\ 'fbsql_set_password(': 'resource link_identifier, string user, string password, string old_password | bool',
+\ 'fbsql_set_transaction(': 'resource link_identifier, int Locking, int Isolation | void',
+\ 'fbsql_start_db(': 'string database_name [, resource link_identifier [, string database_options]] | bool',
+\ 'fbsql_stop_db(': 'string database_name [, resource link_identifier] | bool',
+\ 'fbsql_tablename(': 'resource result, int i | string',
+\ 'fbsql_username(': 'resource link_identifier [, string username] | string',
+\ 'fbsql_warnings(': '[bool OnOff] | bool',
+\ 'fclose(': 'resource handle | bool',
+\ 'fdf_add_doc_javascript(': 'resource fdfdoc, string script_name, string script_code | bool',
+\ 'fdf_add_template(': 'resource fdfdoc, int newpage, string filename, string template, int rename | bool',
+\ 'fdf_close(': 'resource fdf_document | void',
+\ 'fdf_create(': 'void  | resource',
+\ 'fdf_enum_values(': 'resource fdfdoc, callback function [, mixed userdata] | bool',
+\ 'fdf_errno(': 'void  | int',
+\ 'fdf_error(': '[int error_code] | string',
+\ 'fdf_get_ap(': 'resource fdf_document, string field, int face, string filename | bool',
+\ 'fdf_get_attachment(': 'resource fdf_document, string fieldname, string savepath | array',
+\ 'fdf_get_encoding(': 'resource fdf_document | string',
+\ 'fdf_get_file(': 'resource fdf_document | string',
+\ 'fdf_get_flags(': 'resource fdfdoc, string fieldname, int whichflags | int',
+\ 'fdf_get_opt(': 'resource fdfdof, string fieldname [, int element] | mixed',
+\ 'fdf_get_status(': 'resource fdf_document | string',
+\ 'fdf_get_value(': 'resource fdf_document, string fieldname [, int which] | mixed',
+\ 'fdf_get_version(': '[resource fdf_document] | string',
+\ 'fdf_header(': 'void  | void',
+\ 'fdf_next_field_name(': 'resource fdf_document [, string fieldname] | string',
+\ 'fdf_open(': 'string filename | resource',
+\ 'fdf_open_string(': 'string fdf_data | resource',
+\ 'fdf_remove_item(': 'resource fdfdoc, string fieldname, int item | bool',
+\ 'fdf_save(': 'resource fdf_document [, string filename] | bool',
+\ 'fdf_save_string(': 'resource fdf_document | string',
+\ 'fdf_set_ap(': 'resource fdf_document, string field_name, int face, string filename, int page_number | bool',
+\ 'fdf_set_encoding(': 'resource fdf_document, string encoding | bool',
+\ 'fdf_set_file(': 'resource fdf_document, string url [, string target_frame] | bool',
+\ 'fdf_set_flags(': 'resource fdf_document, string fieldname, int whichFlags, int newFlags | bool',
+\ 'fdf_set_javascript_action(': 'resource fdf_document, string fieldname, int trigger, string script | bool',
+\ 'fdf_set_on_import_javascript(': 'resource fdfdoc, string script, bool before_data_import | bool',
+\ 'fdf_set_opt(': 'resource fdf_document, string fieldname, int element, string str1, string str2 | bool',
+\ 'fdf_set_status(': 'resource fdf_document, string status | bool',
+\ 'fdf_set_submit_form_action(': 'resource fdf_document, string fieldname, int trigger, string script, int flags | bool',
+\ 'fdf_set_target_frame(': 'resource fdf_document, string frame_name | bool',
+\ 'fdf_set_value(': 'resource fdf_document, string fieldname, mixed value [, int isName] | bool',
+\ 'fdf_set_version(': 'resource fdf_document, string version | bool',
+\ 'feof(': 'resource handle | bool',
+\ 'fflush(': 'resource handle | bool',
+\ 'fgetc(': 'resource handle | string',
+\ 'fgetcsv(': 'resource handle [, int length [, string delimiter [, string enclosure]]] | array',
+\ 'fgets(': 'resource handle [, int length] | string',
+\ 'fgetss(': 'resource handle [, int length [, string allowable_tags]] | string',
+\ 'fileatime(': 'string filename | int',
+\ 'filectime(': 'string filename | int',
+\ 'file_exists(': 'string filename | bool',
+\ 'file_get_contents(': 'string filename [, bool use_include_path [, resource context [, int offset [, int maxlen]]]] | string',
+\ 'filegroup(': 'string filename | int',
+\ 'file(': 'string filename [, int use_include_path [, resource context]] | array',
+\ 'fileinode(': 'string filename | int',
+\ 'filemtime(': 'string filename | int',
+\ 'fileowner(': 'string filename | int',
+\ 'fileperms(': 'string filename | int',
+\ 'filepro_fieldcount(': 'void  | int',
+\ 'filepro_fieldname(': 'int field_number | string',
+\ 'filepro_fieldtype(': 'int field_number | string',
+\ 'filepro_fieldwidth(': 'int field_number | int',
+\ 'filepro(': 'string directory | bool',
+\ 'filepro_retrieve(': 'int row_number, int field_number | string',
+\ 'filepro_rowcount(': 'void  | int',
+\ 'file_put_contents(': 'string filename, mixed data [, int flags [, resource context]] | int',
+\ 'filesize(': 'string filename | int',
+\ 'filetype(': 'string filename | string',
+\ 'floatval(': 'mixed var | float',
+\ 'flock(': 'resource handle, int operation [, int &#38;wouldblock] | bool',
+\ 'floor(': 'float value | float',
+\ 'flush(': 'void  | void',
+\ 'fmod(': 'float x, float y | float',
+\ 'fnmatch(': 'string pattern, string string [, int flags] | bool',
+\ 'fopen(': 'string filename, string mode [, bool use_include_path [, resource zcontext]] | resource',
+\ 'fpassthru(': 'resource handle | int',
+\ 'fprintf(': 'resource handle, string format [, mixed args [, mixed ...]] | int',
+\ 'fputcsv(': 'resource handle [, array fields [, string delimiter [, string enclosure]]] | int',
+\ 'fread(': 'resource handle, int length | string',
+\ 'frenchtojd(': 'int month, int day, int year | int',
+\ 'fribidi_log2vis(': 'string str, string direction, int charset | string',
+\ 'fscanf(': 'resource handle, string format [, mixed &#38;...] | mixed',
+\ 'fseek(': 'resource handle, int offset [, int whence] | int',
+\ 'fsockopen(': 'string target [, int port [, int &#38;errno [, string &#38;errstr [, float timeout]]]] | resource',
+\ 'fstat(': 'resource handle | array',
+\ 'ftell(': 'resource handle | int',
+\ 'ftok(': 'string pathname, string proj | int',
+\ 'ftp_alloc(': 'resource ftp_stream, int filesize [, string &#38;result] | bool',
+\ 'ftp_cdup(': 'resource ftp_stream | bool',
+\ 'ftp_chdir(': 'resource ftp_stream, string directory | bool',
+\ 'ftp_chmod(': 'resource ftp_stream, int mode, string filename | int',
+\ 'ftp_close(': 'resource ftp_stream | bool',
+\ 'ftp_connect(': 'string host [, int port [, int timeout]] | resource',
+\ 'ftp_delete(': 'resource ftp_stream, string path | bool',
+\ 'ftp_exec(': 'resource ftp_stream, string command | bool',
+\ 'ftp_fget(': 'resource ftp_stream, resource handle, string remote_file, int mode [, int resumepos] | bool',
+\ 'ftp_fput(': 'resource ftp_stream, string remote_file, resource handle, int mode [, int startpos] | bool',
+\ 'ftp_get(': 'resource ftp_stream, string local_file, string remote_file, int mode [, int resumepos] | bool',
+\ 'ftp_get_option(': 'resource ftp_stream, int option | mixed',
+\ 'ftp_login(': 'resource ftp_stream, string username, string password | bool',
+\ 'ftp_mdtm(': 'resource ftp_stream, string remote_file | int',
+\ 'ftp_mkdir(': 'resource ftp_stream, string directory | string',
+\ 'ftp_nb_continue(': 'resource ftp_stream | int',
+\ 'ftp_nb_fget(': 'resource ftp_stream, resource handle, string remote_file, int mode [, int resumepos] | int',
+\ 'ftp_nb_fput(': 'resource ftp_stream, string remote_file, resource handle, int mode [, int startpos] | int',
+\ 'ftp_nb_get(': 'resource ftp_stream, string local_file, string remote_file, int mode [, int resumepos] | int',
+\ 'ftp_nb_put(': 'resource ftp_stream, string remote_file, string local_file, int mode [, int startpos] | int',
+\ 'ftp_nlist(': 'resource ftp_stream, string directory | array',
+\ 'ftp_pasv(': 'resource ftp_stream, bool pasv | bool',
+\ 'ftp_put(': 'resource ftp_stream, string remote_file, string local_file, int mode [, int startpos] | bool',
+\ 'ftp_pwd(': 'resource ftp_stream | string',
+\ 'ftp_raw(': 'resource ftp_stream, string command | array',
+\ 'ftp_rawlist(': 'resource ftp_stream, string directory [, bool recursive] | array',
+\ 'ftp_rename(': 'resource ftp_stream, string oldname, string newname | bool',
+\ 'ftp_rmdir(': 'resource ftp_stream, string directory | bool',
+\ 'ftp_set_option(': 'resource ftp_stream, int option, mixed value | bool',
+\ 'ftp_site(': 'resource ftp_stream, string command | bool',
+\ 'ftp_size(': 'resource ftp_stream, string remote_file | int',
+\ 'ftp_ssl_connect(': 'string host [, int port [, int timeout]] | resource',
+\ 'ftp_systype(': 'resource ftp_stream | string',
+\ 'ftruncate(': 'resource handle, int size | bool',
+\ 'func_get_arg(': 'int arg_num | mixed',
+\ 'func_get_args(': 'void  | array',
+\ 'func_num_args(': 'void  | int',
+\ 'function_exists(': 'string function_name | bool',
+\ 'fwrite(': 'resource handle, string string [, int length] | int',
+\ 'gd_info(': 'void  | array',
+\ 'getallheaders(': 'void  | array',
+\ 'get_browser(': '[string user_agent [, bool return_array]] | mixed',
+\ 'get_cfg_var(': 'string varname | string',
+\ 'get_class(': '[object obj] | string',
+\ 'get_class_methods(': 'mixed class_name | array',
+\ 'get_class_vars(': 'string class_name | array',
+\ 'get_current_user(': 'void  | string',
+\ 'getcwd(': 'void  | string',
+\ 'getdate(': '[int timestamp] | array',
+\ 'get_declared_classes(': 'void  | array',
+\ 'get_declared_interfaces(': 'void  | array',
+\ 'get_defined_constants(': '[mixed categorize] | array',
+\ 'get_defined_functions(': 'void  | array',
+\ 'get_defined_vars(': 'void  | array',
+\ 'getenv(': 'string varname | string',
+\ 'get_extension_funcs(': 'string module_name | array',
+\ 'get_headers(': 'string url [, int format] | array',
+\ 'gethostbyaddr(': 'string ip_address | string',
+\ 'gethostbyname(': 'string hostname | string',
+\ 'gethostbynamel(': 'string hostname | array',
+\ 'get_html_translation_table(': '[int table [, int quote_style]] | array',
+\ 'getimagesize(': 'string filename [, array &#38;imageinfo] | array',
+\ 'get_included_files(': 'void  | array',
+\ 'get_include_path(': 'void  | string',
+\ 'getlastmod(': 'void  | int',
+\ 'get_loaded_extensions(': 'void  | array',
+\ 'get_magic_quotes_gpc(': 'void  | int',
+\ 'get_magic_quotes_runtime(': 'void  | int',
+\ 'get_meta_tags(': 'string filename [, bool use_include_path] | array',
+\ 'getmxrr(': 'string hostname, array &#38;mxhosts [, array &#38;weight] | bool',
+\ 'getmygid(': 'void  | int',
+\ 'getmyinode(': 'void  | int',
+\ 'getmypid(': 'void  | int',
+\ 'getmyuid(': 'void  | int',
+\ 'get_object_vars(': 'object obj | array',
+\ 'getopt(': 'string options | array',
+\ 'get_parent_class(': '[mixed obj] | string',
+\ 'getprotobyname(': 'string name | int',
+\ 'getprotobynumber(': 'int number | string',
+\ 'getrandmax(': 'void  | int',
+\ 'get_resource_type(': 'resource handle | string',
+\ 'getrusage(': '[int who] | array',
+\ 'getservbyname(': 'string service, string protocol | int',
+\ 'getservbyport(': 'int port, string protocol | string',
+\ 'gettext(': 'string message | string',
+\ 'gettimeofday(': '[bool return_float] | mixed',
+\ 'gettype(': 'mixed var | string',
+\ 'glob(': 'string pattern [, int flags] | array',
+\ 'gmdate(': 'string format [, int timestamp] | string',
+\ 'gmmktime(': '[int hour [, int minute [, int second [, int month [, int day [, int year [, int is_dst]]]]]]] | int',
+\ 'gmp_abs(': 'resource a | resource',
+\ 'gmp_add(': 'resource a, resource b | resource',
+\ 'gmp_and(': 'resource a, resource b | resource',
+\ 'gmp_clrbit(': 'resource &#38;a, int index | void',
+\ 'gmp_cmp(': 'resource a, resource b | int',
+\ 'gmp_com(': 'resource a | resource',
+\ 'gmp_divexact(': 'resource n, resource d | resource',
+\ 'gmp_div_q(': 'resource a, resource b [, int round] | resource',
+\ 'gmp_div_qr(': 'resource n, resource d [, int round] | array',
+\ 'gmp_div_r(': 'resource n, resource d [, int round] | resource',
+\ 'gmp_fact(': 'int a | resource',
+\ 'gmp_gcdext(': 'resource a, resource b | array',
+\ 'gmp_gcd(': 'resource a, resource b | resource',
+\ 'gmp_hamdist(': 'resource a, resource b | int',
+\ 'gmp_init(': 'mixed number [, int base] | resource',
+\ 'gmp_intval(': 'resource gmpnumber | int',
+\ 'gmp_invert(': 'resource a, resource b | resource',
+\ 'gmp_jacobi(': 'resource a, resource p | int',
+\ 'gmp_legendre(': 'resource a, resource p | int',
+\ 'gmp_mod(': 'resource n, resource d | resource',
+\ 'gmp_mul(': 'resource a, resource b | resource',
+\ 'gmp_neg(': 'resource a | resource',
+\ 'gmp_or(': 'resource a, resource b | resource',
+\ 'gmp_perfect_square(': 'resource a | bool',
+\ 'gmp_popcount(': 'resource a | int',
+\ 'gmp_pow(': 'resource base, int exp | resource',
+\ 'gmp_powm(': 'resource base, resource exp, resource mod | resource',
+\ 'gmp_prob_prime(': 'resource a [, int reps] | int',
+\ 'gmp_random(': 'int limiter | resource',
+\ 'gmp_scan0(': 'resource a, int start | int',
+\ 'gmp_scan1(': 'resource a, int start | int',
+\ 'gmp_setbit(': 'resource &#38;a, int index [, bool set_clear] | void',
+\ 'gmp_sign(': 'resource a | int',
+\ 'gmp_sqrt(': 'resource a | resource',
+\ 'gmp_sqrtrem(': 'resource a | array',
+\ 'gmp_strval(': 'resource gmpnumber [, int base] | string',
+\ 'gmp_sub(': 'resource a, resource b | resource',
+\ 'gmp_xor(': 'resource a, resource b | resource',
+\ 'gmstrftime(': 'string format [, int timestamp] | string',
+\ 'gnupg_adddecryptkey(': 'resource identifier, string fingerprint, string passphrase | bool',
+\ 'gnupg_addencryptkey(': 'resource identifier, string fingerprint | bool',
+\ 'gnupg_addsignkey(': 'resource identifier, string fingerprint [, string passphrase] | bool',
+\ 'gnupg_cleardecryptkeys(': 'resource identifier | bool',
+\ 'gnupg_clearencryptkeys(': 'resource identifier | bool',
+\ 'gnupg_clearsignkeys(': 'resource identifier | bool',
+\ 'gnupg_decrypt(': 'resource identifier, string text | string',
+\ 'gnupg_decryptverify(': 'resource identifier, string text, string plaintext | array',
+\ 'gnupg_encrypt(': 'resource identifier, string plaintext | string',
+\ 'gnupg_encryptsign(': 'resource identifier, string plaintext | string',
+\ 'gnupg_export(': 'resource identifier, string fingerprint | string',
+\ 'gnupg_geterror(': 'resource identifier | string',
+\ 'gnupg_getprotocol(': 'resource identifier | int',
+\ 'gnupg_import(': 'resource identifier, string keydata | array',
+\ 'gnupg_keyinfo(': 'resource identifier, string pattern | array',
+\ 'gnupg_setarmor(': 'resource identifier, int armor | bool',
+\ 'gnupg_seterrormode(': 'resource identifier, int errormode | void',
+\ 'gnupg_setsignmode(': 'resource identifier, int signmode | bool',
+\ 'gnupg_sign(': 'resource identifier, string plaintext | string',
+\ 'gnupg_verify(': 'resource identifier, string signed_text, string signature [, string plaintext] | array',
+\ 'gopher_parsedir(': 'string dirent | array',
+\ 'gregoriantojd(': 'int month, int day, int year | int',
+\ 'gzclose(': 'resource zp | bool',
+\ 'gzcompress(': 'string data [, int level] | string',
+\ 'gzdeflate(': 'string data [, int level] | string',
+\ 'gzencode(': 'string data [, int level [, int encoding_mode]] | string',
+\ 'gzeof(': 'resource zp | int',
+\ 'gzfile(': 'string filename [, int use_include_path] | array',
+\ 'gzgetc(': 'resource zp | string',
+\ 'gzgets(': 'resource zp, int length | string',
+\ 'gzgetss(': 'resource zp, int length [, string allowable_tags] | string',
+\ 'gzinflate(': 'string data [, int length] | string',
+\ 'gzopen(': 'string filename, string mode [, int use_include_path] | resource',
+\ 'gzpassthru(': 'resource zp | int',
+\ 'gzread(': 'resource zp, int length | string',
+\ 'gzrewind(': 'resource zp | bool',
+\ 'gzseek(': 'resource zp, int offset | int',
+\ 'gztell(': 'resource zp | int',
+\ 'gzuncompress(': 'string data [, int length] | string',
+\ 'gzwrite(': 'resource zp, string string [, int length] | int',
+\ '__halt_compiler(': 'void  | void',
+\ 'hash_algos(': 'void  | array',
+\ 'hash_file(': 'string algo, string filename [, bool raw_output] | string',
+\ 'hash_final(': 'resource context [, bool raw_output] | string',
+\ 'hash_hmac_file(': 'string algo, string filename, string key [, bool raw_output] | string',
+\ 'hash_hmac(': 'string algo, string data, string key [, bool raw_output] | string',
+\ 'hash(': 'string algo, string data [, bool raw_output] | string',
+\ 'hash_init(': 'string algo [, int options, string key] | resource',
+\ 'hash_update_file(': 'resource context, string filename [, resource context] | bool',
+\ 'hash_update(': 'resource context, string data | bool',
+\ 'hash_update_stream(': 'resource context, resource handle [, int length] | int',
+\ 'header(': 'string string [, bool replace [, int http_response_code]] | void',
+\ 'headers_list(': 'void  | array',
+\ 'headers_sent(': '[string &#38;file [, int &#38;line]] | bool',
+\ 'hebrevc(': 'string hebrew_text [, int max_chars_per_line] | string',
+\ 'hebrev(': 'string hebrew_text [, int max_chars_per_line] | string',
+\ 'hexdec(': 'string hex_string | number',
+\ 'highlight_file(': 'string filename [, bool return] | mixed',
+\ 'highlight_string(': 'string str [, bool return] | mixed',
+\ 'htmlentities(': 'string string [, int quote_style [, string charset]] | string',
+\ 'html_entity_decode(': 'string string [, int quote_style [, string charset]] | string',
+\ 'htmlspecialchars_decode(': 'string string [, int quote_style] | string',
+\ 'htmlspecialchars(': 'string string [, int quote_style [, string charset]] | string',
+\ 'http_build_query(': 'array formdata [, string numeric_prefix] | string',
+\ 'hw_api_attribute(': '[string name [, string value]] | HW_API_Attribute',
+\ 'hw_api_attribute-&#62;key(': 'void  | string',
+\ 'hw_api_attribute-&#62;langdepvalue(': 'string language | string',
+\ 'hw_api_attribute-&#62;value(': 'void  | string',
+\ 'hw_api_attribute-&#62;values(': 'void  | array',
+\ 'hw_api-&#62;checkin(': 'array parameter | bool',
+\ 'hw_api-&#62;checkout(': 'array parameter | bool',
+\ 'hw_api-&#62;children(': 'array parameter | array',
+\ 'hw_api-&#62;content(': 'array parameter | HW_API_Content',
+\ 'hw_api_content-&#62;mimetype(': 'void  | string',
+\ 'hw_api_content-&#62;read(': 'string buffer, int len | string',
+\ 'hw_api-&#62;copy(': 'array parameter | hw_api_object',
+\ 'hw_api-&#62;dbstat(': 'array parameter | hw_api_object',
+\ 'hw_api-&#62;dcstat(': 'array parameter | hw_api_object',
+\ 'hw_api-&#62;dstanchors(': 'array parameter | array',
+\ 'hw_api-&#62;dstofsrcanchor(': 'array parameter | hw_api_object',
+\ 'hw_api_error-&#62;count(': 'void  | int',
+\ 'hw_api_error-&#62;reason(': 'void  | HW_API_Reason',
+\ 'hw_api-&#62;find(': 'array parameter | array',
+\ 'hw_api-&#62;ftstat(': 'array parameter | hw_api_object',
+\ 'hwapi_hgcsp(': 'string hostname [, int port] | HW_API',
+\ 'hw_api-&#62;hwstat(': 'array parameter | hw_api_object',
+\ 'hw_api-&#62;identify(': 'array parameter | bool',
+\ 'hw_api-&#62;info(': 'array parameter | array',
+\ 'hw_api-&#62;insertanchor(': 'array parameter | hw_api_object',
+\ 'hw_api-&#62;insertcollection(': 'array parameter | hw_api_object',
+\ 'hw_api-&#62;insertdocument(': 'array parameter | hw_api_object',
+\ 'hw_api-&#62;insert(': 'array parameter | hw_api_object',
+\ 'hw_api-&#62;link(': 'array parameter | bool',
+\ 'hw_api-&#62;lock(': 'array parameter | bool',
+\ 'hw_api-&#62;move(': 'array parameter | bool',
+\ 'hw_api_content(': 'string content, string mimetype | HW_API_Content',
+\ 'hw_api_object-&#62;assign(': 'array parameter | bool',
+\ 'hw_api_object-&#62;attreditable(': 'array parameter | bool',
+\ 'hw_api-&#62;objectbyanchor(': 'array parameter | hw_api_object',
+\ 'hw_api_object-&#62;count(': 'array parameter | int',
+\ 'hw_api-&#62;object(': 'array parameter | hw_api_object',
+\ 'hw_api_object-&#62;insert(': 'HW_API_Attribute attribute | bool',
+\ 'hw_api_object(': 'array parameter | hw_api_object',
+\ 'hw_api_object-&#62;remove(': 'string name | bool',
+\ 'hw_api_object-&#62;title(': 'array parameter | string',
+\ 'hw_api_object-&#62;value(': 'string name | string',
+\ 'hw_api-&#62;parents(': 'array parameter | array',
+\ 'hw_api_reason-&#62;description(': 'void  | string',
+\ 'hw_api_reason-&#62;type(': 'void  | HW_API_Reason',
+\ 'hw_api-&#62;remove(': 'array parameter | bool',
+\ 'hw_api-&#62;replace(': 'array parameter | hw_api_object',
+\ 'hw_api-&#62;setcommittedversion(': 'array parameter | hw_api_object',
+\ 'hw_api-&#62;srcanchors(': 'array parameter | array',
+\ 'hw_api-&#62;srcsofdst(': 'array parameter | array',
+\ 'hw_api-&#62;unlock(': 'array parameter | bool',
+\ 'hw_api-&#62;user(': 'array parameter | hw_api_object',
+\ 'hw_api-&#62;userlist(': 'array parameter | array',
+\ 'hw_array2objrec(': 'array object_array | string',
+\ 'hw_changeobject(': 'int link, int objid, array attributes | bool',
+\ 'hw_children(': 'int connection, int objectID | array',
+\ 'hw_childrenobj(': 'int connection, int objectID | array',
+\ 'hw_close(': 'int connection | bool',
+\ 'hw_connect(': 'string host, int port [, string username, string password] | int',
+\ 'hw_connection_info(': 'int link | void',
+\ 'hw_cp(': 'int connection, array object_id_array, int destination_id | int',
+\ 'hw_deleteobject(': 'int connection, int object_to_delete | bool',
+\ 'hw_docbyanchor(': 'int connection, int anchorID | int',
+\ 'hw_docbyanchorobj(': 'int connection, int anchorID | string',
+\ 'hw_document_attributes(': 'int hw_document | string',
+\ 'hw_document_bodytag(': 'int hw_document [, string prefix] | string',
+\ 'hw_document_content(': 'int hw_document | string',
+\ 'hw_document_setcontent(': 'int hw_document, string content | bool',
+\ 'hw_document_size(': 'int hw_document | int',
+\ 'hw_dummy(': 'int link, int id, int msgid | string',
+\ 'hw_edittext(': 'int connection, int hw_document | bool',
+\ 'hw_error(': 'int connection | int',
+\ 'hw_errormsg(': 'int connection | string',
+\ 'hw_free_document(': 'int hw_document | bool',
+\ 'hw_getanchors(': 'int connection, int objectID | array',
+\ 'hw_getanchorsobj(': 'int connection, int objectID | array',
+\ 'hw_getandlock(': 'int connection, int objectID | string',
+\ 'hw_getchildcoll(': 'int connection, int objectID | array',
+\ 'hw_getchildcollobj(': 'int connection, int objectID | array',
+\ 'hw_getchilddoccoll(': 'int connection, int objectID | array',
+\ 'hw_getchilddoccollobj(': 'int connection, int objectID | array',
+\ 'hw_getobjectbyquerycoll(': 'int connection, int objectID, string query, int max_hits | array',
+\ 'hw_getobjectbyquerycollobj(': 'int connection, int objectID, string query, int max_hits | array',
+\ 'hw_getobjectbyquery(': 'int connection, string query, int max_hits | array',
+\ 'hw_getobjectbyqueryobj(': 'int connection, string query, int max_hits | array',
+\ 'hw_getobject(': 'int connection, mixed objectID [, string query] | mixed',
+\ 'hw_getparents(': 'int connection, int objectID | array',
+\ 'hw_getparentsobj(': 'int connection, int objectID | array',
+\ 'hw_getrellink(': 'int link, int rootid, int sourceid, int destid | string',
+\ 'hw_getremotechildren(': 'int connection, string object_record | mixed',
+\ 'hw_getremote(': 'int connection, int objectID | int',
+\ 'hw_getsrcbydestobj(': 'int connection, int objectID | array',
+\ 'hw_gettext(': 'int connection, int objectID [, mixed rootID/prefix] | int',
+\ 'hw_getusername(': 'int connection | string',
+\ 'hw_identify(': 'int link, string username, string password | string',
+\ 'hw_incollections(': 'int connection, array object_id_array, array collection_id_array, int return_collections | array',
+\ 'hw_info(': 'int connection | string',
+\ 'hw_inscoll(': 'int connection, int objectID, array object_array | int',
+\ 'hw_insdoc(': 'resource connection, int parentID, string object_record [, string text] | int',
+\ 'hw_insertanchors(': 'int hwdoc, array anchorecs, array dest [, array urlprefixes] | bool',
+\ 'hw_insertdocument(': 'int connection, int parent_id, int hw_document | int',
+\ 'hw_insertobject(': 'int connection, string object_rec, string parameter | int',
+\ 'hw_mapid(': 'int connection, int server_id, int object_id | int',
+\ 'hw_modifyobject(': 'int connection, int object_to_change, array remove, array add [, int mode] | bool',
+\ 'hw_mv(': 'int connection, array object_id_array, int source_id, int destination_id | int',
+\ 'hw_new_document(': 'string object_record, string document_data, int document_size | int',
+\ 'hw_objrec2array(': 'string object_record [, array format] | array',
+\ 'hw_output_document(': 'int hw_document | bool',
+\ 'hw_pconnect(': 'string host, int port [, string username, string password] | int',
+\ 'hw_pipedocument(': 'int connection, int objectID [, array url_prefixes] | int',
+\ 'hw_root(': ' | int',
+\ 'hw_setlinkroot(': 'int link, int rootid | int',
+\ 'hw_stat(': 'int link | string',
+\ 'hw_unlock(': 'int connection, int objectID | bool',
+\ 'hw_who(': 'int connection | array',
+\ 'hypot(': 'float x, float y | float',
+\ 'i18n_loc_get_default(': 'void  | string',
+\ 'i18n_loc_set_default(': 'string name | bool',
+\ 'ibase_add_user(': 'resource service_handle, string user_name, string password [, string first_name [, string middle_name [, string last_name]]] | bool',
+\ 'ibase_affected_rows(': '[resource link_identifier] | int',
+\ 'ibase_backup(': 'resource service_handle, string source_db, string dest_file [, int options [, bool verbose]] | mixed',
+\ 'ibase_blob_add(': 'resource blob_handle, string data | void',
+\ 'ibase_blob_cancel(': 'resource blob_handle | bool',
+\ 'ibase_blob_close(': 'resource blob_handle | mixed',
+\ 'ibase_blob_create(': '[resource link_identifier] | resource',
+\ 'ibase_blob_echo(': 'resource link_identifier, string blob_id | bool',
+\ 'ibase_blob_get(': 'resource blob_handle, int len | string',
+\ 'ibase_blob_import(': 'resource link_identifier, resource file_handle | string',
+\ 'ibase_blob_info(': 'resource link_identifier, string blob_id | array',
+\ 'ibase_blob_open(': 'resource link_identifier, string blob_id | resource',
+\ 'ibase_close(': '[resource connection_id] | bool',
+\ 'ibase_commit(': '[resource link_or_trans_identifier] | bool',
+\ 'ibase_commit_ret(': '[resource link_or_trans_identifier] | bool',
+\ 'ibase_connect(': '[string database [, string username [, string password [, string charset [, int buffers [, int dialect [, string role [, int sync]]]]]]]] | resource',
+\ 'ibase_db_info(': 'resource service_handle, string db, int action [, int argument] | string',
+\ 'ibase_delete_user(': 'resource service_handle, string user_name | bool',
+\ 'ibase_drop_db(': '[resource connection] | bool',
+\ 'ibase_errcode(': 'void  | int',
+\ 'ibase_errmsg(': 'void  | string',
+\ 'ibase_execute(': 'resource query [, mixed bind_arg [, mixed ...]] | resource',
+\ 'ibase_fetch_assoc(': 'resource result [, int fetch_flag] | array',
+\ 'ibase_fetch_object(': 'resource result_id [, int fetch_flag] | object',
+\ 'ibase_fetch_row(': 'resource result_identifier [, int fetch_flag] | array',
+\ 'ibase_field_info(': 'resource result, int field_number | array',
+\ 'ibase_free_event_handler(': 'resource event | bool',
+\ 'ibase_free_query(': 'resource query | bool',
+\ 'ibase_free_result(': 'resource result_identifier | bool',
+\ 'ibase_gen_id(': 'string generator [, int increment [, resource link_identifier]] | mixed',
+\ 'ibase_maintain_db(': 'resource service_handle, string db, int action [, int argument] | bool',
+\ 'ibase_modify_user(': 'resource service_handle, string user_name, string password [, string first_name [, string middle_name [, string last_name]]] | bool',
+\ 'ibase_name_result(': 'resource result, string name | bool',
+\ 'ibase_num_fields(': 'resource result_id | int',
+\ 'ibase_num_params(': 'resource query | int',
+\ 'ibase_param_info(': 'resource query, int param_number | array',
+\ 'ibase_pconnect(': '[string database [, string username [, string password [, string charset [, int buffers [, int dialect [, string role [, int sync]]]]]]]] | resource',
+\ 'ibase_prepare(': 'string query | resource',
+\ 'ibase_query(': '[resource link_identifier, string query [, int bind_args]] | resource',
+\ 'ibase_restore(': 'resource service_handle, string source_file, string dest_db [, int options [, bool verbose]] | mixed',
+\ 'ibase_rollback(': '[resource link_or_trans_identifier] | bool',
+\ 'ibase_rollback_ret(': '[resource link_or_trans_identifier] | bool',
+\ 'ibase_server_info(': 'resource service_handle, int action | string',
+\ 'ibase_service_attach(': 'string host, string dba_username, string dba_password | resource',
+\ 'ibase_service_detach(': 'resource service_handle | bool',
+\ 'ibase_set_event_handler(': 'callback event_handler, string event_name1 [, string event_name2 [, string ...]] | resource',
+\ 'ibase_timefmt(': 'string format [, int columntype] | int',
+\ 'ibase_trans(': '[int trans_args [, resource link_identifier]] | resource',
+\ 'ibase_wait_event(': 'string event_name1 [, string event_name2 [, string ...]] | string',
+\ 'icap_close(': 'int icap_stream [, int flags] | int',
+\ 'icap_create_calendar(': 'int stream_id, string calendar | string',
+\ 'icap_delete_calendar(': 'int stream_id, string calendar | string',
+\ 'icap_delete_event(': 'int stream_id, int uid | string',
+\ 'icap_fetch_event(': 'int stream_id, int event_id [, int options] | int',
+\ 'icap_list_alarms(': 'int stream_id, array date, array time | int',
+\ 'icap_list_events(': 'int stream_id, int begin_date [, int end_date] | array',
+\ 'icap_open(': 'string calendar, string username, string password, string options | resource',
+\ 'icap_rename_calendar(': 'int stream_id, string old_name, string new_name | string',
+\ 'icap_reopen(': 'int stream_id, string calendar [, int options] | int',
+\ 'icap_snooze(': 'int stream_id, int uid | string',
+\ 'icap_store_event(': 'int stream_id, object event | string',
+\ 'iconv_get_encoding(': '[string type] | mixed',
+\ 'iconv(': 'string in_charset, string out_charset, string str | string',
+\ 'iconv_mime_decode_headers(': 'string encoded_headers [, int mode [, string charset]] | array',
+\ 'iconv_mime_decode(': 'string encoded_header [, int mode [, string charset]] | string',
+\ 'iconv_mime_encode(': 'string field_name, string field_value [, array preferences] | string',
+\ 'iconv_set_encoding(': 'string type, string charset | bool',
+\ 'iconv_strlen(': 'string str [, string charset] | int',
+\ 'iconv_strpos(': 'string haystack, string needle [, int offset [, string charset]] | int',
+\ 'iconv_strrpos(': 'string haystack, string needle [, string charset] | int',
+\ 'iconv_substr(': 'string str, int offset [, int length [, string charset]] | string',
+\ 'id3_get_frame_long_name(': 'string frameId | string',
+\ 'id3_get_frame_short_name(': 'string frameId | string',
+\ 'id3_get_genre_id(': 'string genre | int',
+\ 'id3_get_genre_list(': 'void  | array',
+\ 'id3_get_genre_name(': 'int genre_id | string',
+\ 'id3_get_tag(': 'string filename [, int version] | array',
+\ 'id3_get_version(': 'string filename | int',
+\ 'id3_remove_tag(': 'string filename [, int version] | bool',
+\ 'id3_set_tag(': 'string filename, array tag [, int version] | bool',
+\ 'idate(': 'string format [, int timestamp] | int',
+\ 'ifx_affected_rows(': 'int result_id | int',
+\ 'ifx_blobinfile_mode(': 'int mode | void',
+\ 'ifx_byteasvarchar(': 'int mode | void',
+\ 'ifx_close(': '[int link_identifier] | int',
+\ 'ifx_connect(': '[string database [, string userid [, string password]]] | int',
+\ 'ifx_copy_blob(': 'int bid | int',
+\ 'ifx_create_blob(': 'int type, int mode, string param | int',
+\ 'ifx_create_char(': 'string param | int',
+\ 'ifx_do(': 'int result_id | int',
+\ 'ifx_error(': 'void  | string',
+\ 'ifx_errormsg(': '[int errorcode] | string',
+\ 'ifx_fetch_row(': 'int result_id [, mixed position] | array',
+\ 'ifx_fieldproperties(': 'int result_id | array',
+\ 'ifx_fieldtypes(': 'int result_id | array',
+\ 'ifx_free_blob(': 'int bid | int',
+\ 'ifx_free_char(': 'int bid | int',
+\ 'ifx_free_result(': 'int result_id | int',
+\ 'ifx_get_blob(': 'int bid | int',
+\ 'ifx_get_char(': 'int bid | int',
+\ 'ifx_getsqlca(': 'int result_id | array',
+\ 'ifx_htmltbl_result(': 'int result_id [, string html_table_options] | int',
+\ 'ifx_nullformat(': 'int mode | void',
+\ 'ifx_num_fields(': 'int result_id | int',
+\ 'ifx_num_rows(': 'int result_id | int',
+\ 'ifx_pconnect(': '[string database [, string userid [, string password]]] | int',
+\ 'ifx_prepare(': 'string query, int conn_id [, int cursor_def, mixed blobidarray] | int',
+\ 'ifx_query(': 'string query, int link_identifier [, int cursor_type [, mixed blobidarray]] | int',
+\ 'ifx_textasvarchar(': 'int mode | void',
+\ 'ifx_update_blob(': 'int bid, string content | bool',
+\ 'ifx_update_char(': 'int bid, string content | int',
+\ 'ifxus_close_slob(': 'int bid | int',
+\ 'ifxus_create_slob(': 'int mode | int',
+\ 'ifxus_free_slob(': 'int bid | int',
+\ 'ifxus_open_slob(': 'int bid, int mode | int',
+\ 'ifxus_read_slob(': 'int bid, int nbytes | int',
+\ 'ifxus_seek_slob(': 'int bid, int mode, int offset | int',
+\ 'ifxus_tell_slob(': 'int bid | int',
+\ 'ifxus_write_slob(': 'int bid, string content | int',
+\ 'ignore_user_abort(': '[bool setting] | int',
+\ 'iis_add_server(': 'string path, string comment, string server_ip, int port, string host_name, int rights, int start_server | int',
+\ 'iis_get_dir_security(': 'int server_instance, string virtual_path | int',
+\ 'iis_get_script_map(': 'int server_instance, string virtual_path, string script_extension | string',
+\ 'iis_get_server_by_comment(': 'string comment | int',
+\ 'iis_get_server_by_path(': 'string path | int',
+\ 'iis_get_server_rights(': 'int server_instance, string virtual_path | int',
+\ 'iis_get_service_state(': 'string service_id | int',
+\ 'iis_remove_server(': 'int server_instance | int',
+\ 'iis_set_app_settings(': 'int server_instance, string virtual_path, string application_scope | int',
+\ 'iis_set_dir_security(': 'int server_instance, string virtual_path, int directory_flags | int',
+\ 'iis_set_script_map(': 'int server_instance, string virtual_path, string script_extension, string engine_path, int allow_scripting | int',
+\ 'iis_set_server_rights(': 'int server_instance, string virtual_path, int directory_flags | int',
+\ 'iis_start_server(': 'int server_instance | int',
+\ 'iis_start_service(': 'string service_id | int',
+\ 'iis_stop_server(': 'int server_instance | int',
+\ 'iis_stop_service(': 'string service_id | int',
+\ 'image2wbmp(': 'resource image [, string filename [, int threshold]] | int',
+\ 'imagealphablending(': 'resource image, bool blendmode | bool',
+\ 'imageantialias(': 'resource im, bool on | bool',
+\ 'imagearc(': 'resource image, int cx, int cy, int w, int h, int s, int e, int color | bool',
+\ 'imagechar(': 'resource image, int font, int x, int y, string c, int color | bool',
+\ 'imagecharup(': 'resource image, int font, int x, int y, string c, int color | bool',
+\ 'imagecolorallocatealpha(': 'resource image, int red, int green, int blue, int alpha | int',
+\ 'imagecolorallocate(': 'resource image, int red, int green, int blue | int',
+\ 'imagecolorat(': 'resource image, int x, int y | int',
+\ 'imagecolorclosestalpha(': 'resource image, int red, int green, int blue, int alpha | int',
+\ 'imagecolorclosest(': 'resource image, int red, int green, int blue | int',
+\ 'imagecolorclosesthwb(': 'resource image, int red, int green, int blue | int',
+\ 'imagecolordeallocate(': 'resource image, int color | bool',
+\ 'imagecolorexactalpha(': 'resource image, int red, int green, int blue, int alpha | int',
+\ 'imagecolorexact(': 'resource image, int red, int green, int blue | int',
+\ 'imagecolormatch(': 'resource image1, resource image2 | bool',
+\ 'imagecolorresolvealpha(': 'resource image, int red, int green, int blue, int alpha | int',
+\ 'imagecolorresolve(': 'resource image, int red, int green, int blue | int',
+\ 'imagecolorset(': 'resource image, int index, int red, int green, int blue | void',
+\ 'imagecolorsforindex(': 'resource image, int index | array',
+\ 'imagecolorstotal(': 'resource image | int',
+\ 'imagecolortransparent(': 'resource image [, int color] | int',
+\ 'imageconvolution(': 'resource image, array matrix3x3, float div, float offset | bool',
+\ 'imagecopy(': 'resource dst_im, resource src_im, int dst_x, int dst_y, int src_x, int src_y, int src_w, int src_h | bool',
+\ 'imagecopymergegray(': 'resource dst_im, resource src_im, int dst_x, int dst_y, int src_x, int src_y, int src_w, int src_h, int pct | bool',
+\ 'imagecopymerge(': 'resource dst_im, resource src_im, int dst_x, int dst_y, int src_x, int src_y, int src_w, int src_h, int pct | bool',
+\ 'imagecopyresampled(': 'resource dst_image, resource src_image, int dst_x, int dst_y, int src_x, int src_y, int dst_w, int dst_h, int src_w, int src_h | bool',
+\ 'imagecopyresized(': 'resource dst_image, resource src_image, int dst_x, int dst_y, int src_x, int src_y, int dst_w, int dst_h, int src_w, int src_h | bool',
+\ 'imagecreatefromgd2(': 'string filename | resource',
+\ 'imagecreatefromgd2part(': 'string filename, int srcX, int srcY, int width, int height | resource',
+\ 'imagecreatefromgd(': 'string filename | resource',
+\ 'imagecreatefromgif(': 'string filename | resource',
+\ 'imagecreatefromjpeg(': 'string filename | resource',
+\ 'imagecreatefrompng(': 'string filename | resource',
+\ 'imagecreatefromstring(': 'string image | resource',
+\ 'imagecreatefromwbmp(': 'string filename | resource',
+\ 'imagecreatefromxbm(': 'string filename | resource',
+\ 'imagecreatefromxpm(': 'string filename | resource',
+\ 'imagecreate(': 'int x_size, int y_size | resource',
+\ 'imagecreatetruecolor(': 'int x_size, int y_size | resource',
+\ 'imagedashedline(': 'resource image, int x1, int y1, int x2, int y2, int color | bool',
+\ 'imagedestroy(': 'resource image | bool',
+\ 'imageellipse(': 'resource image, int cx, int cy, int w, int h, int color | bool',
+\ 'imagefilledarc(': 'resource image, int cx, int cy, int w, int h, int s, int e, int color, int style | bool',
+\ 'imagefilledellipse(': 'resource image, int cx, int cy, int w, int h, int color | bool',
+\ 'imagefilledpolygon(': 'resource image, array points, int num_points, int color | bool',
+\ 'imagefilledrectangle(': 'resource image, int x1, int y1, int x2, int y2, int color | bool',
+\ 'imagefill(': 'resource image, int x, int y, int color | bool',
+\ 'imagefilltoborder(': 'resource image, int x, int y, int border, int color | bool',
+\ 'imagefilter(': 'resource src_im, int filtertype [, int arg1 [, int arg2 [, int arg3]]] | bool',
+\ 'imagefontheight(': 'int font | int',
+\ 'imagefontwidth(': 'int font | int',
+\ 'imageftbbox(': 'float size, float angle, string font_file, string text [, array extrainfo] | array',
+\ 'imagefttext(': 'resource image, float size, float angle, int x, int y, int col, string font_file, string text [, array extrainfo] | array',
+\ 'imagegammacorrect(': 'resource image, float inputgamma, float outputgamma | bool',
+\ 'imagegd2(': 'resource image [, string filename [, int chunk_size [, int type]]] | bool',
+\ 'imagegd(': 'resource image [, string filename] | bool',
+\ 'imagegif(': 'resource image [, string filename] | bool',
+\ 'imageinterlace(': 'resource image [, int interlace] | int',
+\ 'imageistruecolor(': 'resource image | bool',
+\ 'imagejpeg(': 'resource image [, string filename [, int quality]] | bool',
+\ 'imagelayereffect(': 'resource image, int effect | bool',
+\ 'imageline(': 'resource image, int x1, int y1, int x2, int y2, int color | bool',
+\ 'imageloadfont(': 'string file | int',
+\ 'imagepalettecopy(': 'resource destination, resource source | void',
+\ 'imagepng(': 'resource image [, string filename] | bool',
+\ 'imagepolygon(': 'resource image, array points, int num_points, int color | bool',
+\ 'imagepsbbox(': 'string text, int font, int size [, int space, int tightness, float angle] | array',
+\ 'imagepscopyfont(': 'resource fontindex | int',
+\ 'imagepsencodefont(': 'resource font_index, string encodingfile | bool',
+\ 'imagepsextendfont(': 'int font_index, float extend | bool',
+\ 'imagepsfreefont(': 'resource fontindex | bool',
+\ 'imagepsloadfont(': 'string filename | resource',
+\ 'imagepsslantfont(': 'resource font_index, float slant | bool',
+\ 'imagepstext(': 'resource image, string text, resource font, int size, int foreground, int background, int x, int y [, int space, int tightness, float angle, int antialias_steps] | array',
+\ 'imagerectangle(': 'resource image, int x1, int y1, int x2, int y2, int col | bool',
+\ 'imagerotate(': 'resource src_im, float angle, int bgd_color [, int ignore_transparent] | resource',
+\ 'imagesavealpha(': 'resource image, bool saveflag | bool',
+\ 'imagesetbrush(': 'resource image, resource brush | bool',
+\ 'imagesetpixel(': 'resource image, int x, int y, int color | bool',
+\ 'imagesetstyle(': 'resource image, array style | bool',
+\ 'imagesetthickness(': 'resource image, int thickness | bool',
+\ 'imagesettile(': 'resource image, resource tile | bool',
+\ 'imagestring(': 'resource image, int font, int x, int y, string s, int col | bool',
+\ 'imagestringup(': 'resource image, int font, int x, int y, string s, int col | bool',
+\ 'imagesx(': 'resource image | int',
+\ 'imagesy(': 'resource image | int',
+\ 'imagetruecolortopalette(': 'resource image, bool dither, int ncolors | bool',
+\ 'imagettfbbox(': 'float size, float angle, string fontfile, string text | array',
+\ 'imagettftext(': 'resource image, float size, float angle, int x, int y, int color, string fontfile, string text | array',
+\ 'imagetypes(': 'void  | int',
+\ 'image_type_to_extension(': 'int imagetype [, bool include_dot] | string',
+\ 'image_type_to_mime_type(': 'int imagetype | string',
+\ 'imagewbmp(': 'resource image [, string filename [, int foreground]] | bool',
+\ 'imagexbm(': 'resource image, string filename [, int foreground] | bool',
+\ 'imap_8bit(': 'string string | string',
+\ 'imap_alerts(': 'void  | array',
+\ 'imap_append(': 'resource imap_stream, string mbox, string message [, string options] | bool',
+\ 'imap_base64(': 'string text | string',
+\ 'imap_binary(': 'string string | string',
+\ 'imap_body(': 'resource imap_stream, int msg_number [, int options] | string',
+\ 'imap_bodystruct(': 'resource stream_id, int msg_no, string section | object',
+\ 'imap_check(': 'resource imap_stream | object',
+\ 'imap_clearflag_full(': 'resource stream, string sequence, string flag [, string options] | bool',
+\ 'imap_close(': 'resource imap_stream [, int flag] | bool',
+\ 'imap_createmailbox(': 'resource imap_stream, string mbox | bool',
+\ 'imap_delete(': 'int imap_stream, int msg_number [, int options] | bool',
+\ 'imap_deletemailbox(': 'resource imap_stream, string mbox | bool',
+\ 'imap_errors(': 'void  | array',
+\ 'imap_expunge(': 'resource imap_stream | bool',
+\ 'imap_fetchbody(': 'resource imap_stream, int msg_number, string part_number [, int options] | string',
+\ 'imap_fetchheader(': 'resource imap_stream, int msgno [, int options] | string',
+\ 'imap_fetch_overview(': 'resource imap_stream, string sequence [, int options] | array',
+\ 'imap_fetchstructure(': 'resource imap_stream, int msg_number [, int options] | object',
+\ 'imap_getacl(': 'resource stream_id, string mailbox | array',
+\ 'imap_getmailboxes(': 'resource imap_stream, string ref, string pattern | array',
+\ 'imap_get_quota(': 'resource imap_stream, string quota_root | array',
+\ 'imap_get_quotaroot(': 'resource imap_stream, string quota_root | array',
+\ 'imap_getsubscribed(': 'resource imap_stream, string ref, string pattern | array',
+\ 'imap_headerinfo(': 'resource imap_stream, int msg_number [, int fromlength [, int subjectlength [, string defaulthost]]] | object',
+\ 'imap_headers(': 'resource imap_stream | array',
+\ 'imap_last_error(': 'void  | string',
+\ 'imap_list(': 'resource imap_stream, string ref, string pattern | array',
+\ 'imap_listscan(': 'resource imap_stream, string ref, string pattern, string content | array',
+\ 'imap_lsub(': 'resource imap_stream, string ref, string pattern | array',
+\ 'imap_mailboxmsginfo(': 'resource imap_stream | object',
+\ 'imap_mail_compose(': 'array envelope, array body | string',
+\ 'imap_mail_copy(': 'resource imap_stream, string msglist, string mbox [, int options] | bool',
+\ 'imap_mail(': 'string to, string subject, string message [, string additional_headers [, string cc [, string bcc [, string rpath]]]] | bool',
+\ 'imap_mail_move(': 'resource imap_stream, string msglist, string mbox [, int options] | bool',
+\ 'imap_mime_header_decode(': 'string text | array',
+\ 'imap_msgno(': 'resource imap_stream, int uid | int',
+\ 'imap_num_msg(': 'resource imap_stream | int',
+\ 'imap_num_recent(': 'resource imap_stream | int',
+\ 'imap_open(': 'string mailbox, string username, string password [, int options] | resource',
+\ 'imap_ping(': 'resource imap_stream | bool',
+\ 'imap_qprint(': 'string string | string',
+\ 'imap_renamemailbox(': 'resource imap_stream, string old_mbox, string new_mbox | bool',
+\ 'imap_reopen(': 'resource imap_stream, string mailbox [, int options] | bool',
+\ 'imap_rfc822_parse_adrlist(': 'string address, string default_host | array',
+\ 'imap_rfc822_parse_headers(': 'string headers [, string defaulthost] | object',
+\ 'imap_rfc822_write_address(': 'string mailbox, string host, string personal | string',
+\ 'imap_search(': 'resource imap_stream, string criteria [, int options [, string charset]] | array',
+\ 'imap_setacl(': 'resource stream_id, string mailbox, string id, string rights | bool',
+\ 'imap_setflag_full(': 'resource stream, string sequence, string flag [, string options] | bool',
+\ 'imap_set_quota(': 'resource imap_stream, string quota_root, int quota_limit | bool',
+\ 'imap_sort(': 'resource stream, int criteria, int reverse [, int options [, string search_criteria [, string charset]]] | array',
+\ 'imap_status(': 'resource imap_stream, string mailbox, int options | object',
+\ 'imap_subscribe(': 'resource imap_stream, string mbox | bool',
+\ 'imap_thread(': 'resource stream_id [, int options] | array',
+\ 'imap_timeout(': 'int timeout_type [, int timeout] | mixed',
+\ 'imap_uid(': 'resource imap_stream, int msgno | int',
+\ 'imap_undelete(': 'resource imap_stream, int msg_number [, int flags] | bool',
+\ 'imap_unsubscribe(': 'string imap_stream, string mbox | bool',
+\ 'imap_utf7_decode(': 'string text | string',
+\ 'imap_utf7_encode(': 'string data | string',
+\ 'imap_utf8(': 'string mime_encoded_text | string',
+\ 'implode(': 'string glue, array pieces | string',
+\ 'import_request_variables(': 'string types [, string prefix] | bool',
+\ 'in_array(': 'mixed needle, array haystack [, bool strict] | bool',
+\ 'inet_ntop(': 'string in_addr | string',
+\ 'inet_pton(': 'string address | string',
+\ 'ingres_autocommit(': '[resource link] | bool',
+\ 'ingres_close(': '[resource link] | bool',
+\ 'ingres_commit(': '[resource link] | bool',
+\ 'ingres_connect(': '[string database [, string username [, string password]]] | resource',
+\ 'ingres_cursor(': '[resource link] | string',
+\ 'ingres_errno(': '[resource link] | int',
+\ 'ingres_error(': '[resource link] | string',
+\ 'ingres_errsqlstate(': '[resource link] | string',
+\ 'ingres_fetch_array(': '[int result_type [, resource link]] | array',
+\ 'ingres_fetch_object(': '[int result_type [, resource link]] | object',
+\ 'ingres_fetch_row(': '[resource link] | array',
+\ 'ingres_field_length(': 'int index [, resource link] | int',
+\ 'ingres_field_name(': 'int index [, resource link] | string',
+\ 'ingres_field_nullable(': 'int index [, resource link] | bool',
+\ 'ingres_field_precision(': 'int index [, resource link] | int',
+\ 'ingres_field_scale(': 'int index [, resource link] | int',
+\ 'ingres_field_type(': 'int index [, resource link] | string',
+\ 'ingres_num_fields(': '[resource link] | int',
+\ 'ingres_num_rows(': '[resource link] | int',
+\ 'ingres_pconnect(': '[string database [, string username [, string password]]] | resource',
+\ 'ingres_query(': 'string query [, resource link] | bool',
+\ 'ingres_rollback(': '[resource link] | bool',
+\ 'ini_get_all(': '[string extension] | array',
+\ 'ini_get(': 'string varname | string',
+\ 'ini_restore(': 'string varname | void',
+\ 'ini_set(': 'string varname, string newvalue | string',
+\ 'interface_exists(': 'string interface_name [, bool autoload] | bool',
+\ 'intval(': 'mixed var [, int base] | int',
+\ 'ip2long(': 'string ip_address | int',
+\ 'iptcembed(': 'string iptcdata, string jpeg_file_name [, int spool] | mixed',
+\ 'iptcparse(': 'string iptcblock | array',
+\ 'ircg_channel_mode(': 'resource connection, string channel, string mode_spec, string nick | bool',
+\ 'ircg_disconnect(': 'resource connection, string reason | bool',
+\ 'ircg_eval_ecmascript_params(': 'string params | array',
+\ 'ircg_fetch_error_msg(': 'resource connection | array',
+\ 'ircg_get_username(': 'resource connection | string',
+\ 'ircg_html_encode(': 'string html_string [, bool auto_links [, bool conv_br]] | string',
+\ 'ircg_ignore_add(': 'resource connection, string nick | void',
+\ 'ircg_ignore_del(': 'resource connection, string nick | bool',
+\ 'ircg_invite(': 'resource connection, string channel, string nickname | bool',
+\ 'ircg_is_conn_alive(': 'resource connection | bool',
+\ 'ircg_join(': 'resource connection, string channel [, string key] | bool',
+\ 'ircg_kick(': 'resource connection, string channel, string nick, string reason | bool',
+\ 'ircg_list(': 'resource connection, string channel | bool',
+\ 'ircg_lookup_format_messages(': 'string name | bool',
+\ 'ircg_lusers(': 'resource connection | bool',
+\ 'ircg_msg(': 'resource connection, string recipient, string message [, bool suppress] | bool',
+\ 'ircg_names(': 'int connection, string channel [, string target] | bool',
+\ 'ircg_nick(': 'resource connection, string nick | bool',
+\ 'ircg_nickname_escape(': 'string nick | string',
+\ 'ircg_nickname_unescape(': 'string nick | string',
+\ 'ircg_notice(': 'resource connection, string recipient, string message | bool',
+\ 'ircg_oper(': 'resource connection, string name, string password | bool',
+\ 'ircg_part(': 'resource connection, string channel | bool',
+\ 'ircg_pconnect(': 'string username [, string server_ip [, int server_port [, string msg_format [, array ctcp_messages [, array user_settings [, bool bailout_on_trivial]]]]]] | resource',
+\ 'ircg_register_format_messages(': 'string name, array messages | bool',
+\ 'ircg_set_current(': 'resource connection | bool',
+\ 'ircg_set_file(': 'resource connection, string path | bool',
+\ 'ircg_set_on_die(': 'resource connection, string host, int port, string data | bool',
+\ 'ircg_topic(': 'resource connection, string channel, string new_topic | bool',
+\ 'ircg_who(': 'resource connection, string mask [, bool ops_only] | bool',
+\ 'ircg_whois(': 'resource connection, string nick | bool',
+\ 'is_a(': 'object object, string class_name | bool',
+\ 'is_array(': 'mixed var | bool',
+\ 'is_bool(': 'mixed var | bool',
+\ 'is_callable(': 'mixed var [, bool syntax_only [, string &#38;callable_name]] | bool',
+\ 'is_dir(': 'string filename | bool',
+\ 'is_executable(': 'string filename | bool',
+\ 'is_file(': 'string filename | bool',
+\ 'is_finite(': 'float val | bool',
+\ 'is_float(': 'mixed var | bool',
+\ 'is_infinite(': 'float val | bool',
+\ 'is_int(': 'mixed var | bool',
+\ 'is_link(': 'string filename | bool',
+\ 'is_nan(': 'float val | bool',
+\ 'is_null(': 'mixed var | bool',
+\ 'is_numeric(': 'mixed var | bool',
+\ 'is_object(': 'mixed var | bool',
+\ 'is_readable(': 'string filename | bool',
+\ 'is_resource(': 'mixed var | bool',
+\ 'is_scalar(': 'mixed var | bool',
+\ 'isset(': 'mixed var [, mixed var [, ...]] | bool',
+\ 'is_soap_fault(': 'mixed obj | bool',
+\ 'is_string(': 'mixed var | bool',
+\ 'is_subclass_of(': 'mixed object, string class_name | bool',
+\ 'is_uploaded_file(': 'string filename | bool',
+\ 'is_writable(': 'string filename | bool',
+\ 'iterator_count(': 'IteratorAggregate iterator | int',
+\ 'iterator_to_array(': 'IteratorAggregate iterator | array',
+\ 'java_last_exception_clear(': 'void  | void',
+\ 'java_last_exception_get(': 'void  | object',
+\ 'jddayofweek(': 'int julianday [, int mode] | mixed',
+\ 'jdmonthname(': 'int julianday, int mode | string',
+\ 'jdtofrench(': 'int juliandaycount | string',
+\ 'jdtogregorian(': 'int julianday | string',
+\ 'jdtojewish(': 'int juliandaycount [, bool hebrew [, int fl]] | string',
+\ 'jdtojulian(': 'int julianday | string',
+\ 'jdtounix(': 'int jday | int',
+\ 'jewishtojd(': 'int month, int day, int year | int',
+\ 'jpeg2wbmp(': 'string jpegname, string wbmpname, int d_height, int d_width, int threshold | int',
+\ 'juliantojd(': 'int month, int day, int year | int',
+\ 'kadm5_chpass_principal(': 'resource handle, string principal, string password | bool',
+\ 'kadm5_create_principal(': 'resource handle, string principal [, string password [, array options]] | bool',
+\ 'kadm5_delete_principal(': 'resource handle, string principal | bool',
+\ 'kadm5_destroy(': 'resource handle | bool',
+\ 'kadm5_flush(': 'resource handle | bool',
+\ 'kadm5_get_policies(': 'resource handle | array',
+\ 'kadm5_get_principal(': 'resource handle, string principal | array',
+\ 'kadm5_get_principals(': 'resource handle | array',
+\ 'kadm5_init_with_password(': 'string admin_server, string realm, string principal, string password | resource',
+\ 'kadm5_modify_principal(': 'resource handle, string principal, array options | bool',
+\ 'key(': 'array &#38;array | mixed',
+\ 'krsort(': 'array &#38;array [, int sort_flags] | bool',
+\ 'ksort(': 'array &#38;array [, int sort_flags] | bool',
+\ 'lcg_value(': 'void  | float',
+\ 'ldap_8859_to_t61(': 'string value | string',
+\ 'ldap_add(': 'resource link_identifier, string dn, array entry | bool',
+\ 'ldap_bind(': 'resource link_identifier [, string bind_rdn [, string bind_password]] | bool',
+\ 'ldap_compare(': 'resource link_identifier, string dn, string attribute, string value | mixed',
+\ 'ldap_connect(': '[string hostname [, int port]] | resource',
+\ 'ldap_count_entries(': 'resource link_identifier, resource result_identifier | int',
+\ 'ldap_delete(': 'resource link_identifier, string dn | bool',
+\ 'ldap_dn2ufn(': 'string dn | string',
+\ 'ldap_err2str(': 'int errno | string',
+\ 'ldap_errno(': 'resource link_identifier | int',
+\ 'ldap_error(': 'resource link_identifier | string',
+\ 'ldap_explode_dn(': 'string dn, int with_attrib | array',
+\ 'ldap_first_attribute(': 'resource link_identifier, resource result_entry_identifier, int &#38;ber_identifier | string',
+\ 'ldap_first_entry(': 'resource link_identifier, resource result_identifier | resource',
+\ 'ldap_first_reference(': 'resource link, resource result | resource',
+\ 'ldap_free_result(': 'resource result_identifier | bool',
+\ 'ldap_get_attributes(': 'resource link_identifier, resource result_entry_identifier | array',
+\ 'ldap_get_dn(': 'resource link_identifier, resource result_entry_identifier | string',
+\ 'ldap_get_entries(': 'resource link_identifier, resource result_identifier | array',
+\ 'ldap_get_option(': 'resource link_identifier, int option, mixed &#38;retval | bool',
+\ 'ldap_get_values(': 'resource link_identifier, resource result_entry_identifier, string attribute | array',
+\ 'ldap_get_values_len(': 'resource link_identifier, resource result_entry_identifier, string attribute | array',
+\ 'ldap_list(': 'resource link_identifier, string base_dn, string filter [, array attributes [, int attrsonly [, int sizelimit [, int timelimit [, int deref]]]]] | resource',
+\ 'ldap_mod_add(': 'resource link_identifier, string dn, array entry | bool',
+\ 'ldap_mod_del(': 'resource link_identifier, string dn, array entry | bool',
+\ 'ldap_modify(': 'resource link_identifier, string dn, array entry | bool',
+\ 'ldap_mod_replace(': 'resource link_identifier, string dn, array entry | bool',
+\ 'ldap_next_attribute(': 'resource link_identifier, resource result_entry_identifier, resource &#38;ber_identifier | string',
+\ 'ldap_next_entry(': 'resource link_identifier, resource result_entry_identifier | resource',
+\ 'ldap_next_reference(': 'resource link, resource entry | resource',
+\ 'ldap_parse_reference(': 'resource link, resource entry, array &#38;referrals | bool',
+\ 'ldap_parse_result(': 'resource link, resource result, int &#38;errcode [, string &#38;matcheddn [, string &#38;errmsg [, array &#38;referrals]]] | bool',
+\ 'ldap_read(': 'resource link_identifier, string base_dn, string filter [, array attributes [, int attrsonly [, int sizelimit [, int timelimit [, int deref]]]]] | resource',
+\ 'ldap_rename(': 'resource link_identifier, string dn, string newrdn, string newparent, bool deleteoldrdn | bool',
+\ 'ldap_sasl_bind(': 'resource link [, string binddn [, string password [, string sasl_mech [, string sasl_realm [, string sasl_authz_id [, string props]]]]]] | bool',
+\ 'ldap_search(': 'resource link_identifier, string base_dn, string filter [, array attributes [, int attrsonly [, int sizelimit [, int timelimit [, int deref]]]]] | resource',
+\ 'ldap_set_option(': 'resource link_identifier, int option, mixed newval | bool',
+\ 'ldap_set_rebind_proc(': 'resource link, callback callback | bool',
+\ 'ldap_sort(': 'resource link, resource result, string sortfilter | bool',
+\ 'ldap_start_tls(': 'resource link | bool',
+\ 'ldap_t61_to_8859(': 'string value | string',
+\ 'ldap_unbind(': 'resource link_identifier | bool',
+\ 'levenshtein(': 'string str1, string str2 [, int cost_ins [, int cost_rep, int cost_del]] | int',
+\ 'libxml_clear_errors(': 'void  | void',
+\ 'libxml_get_errors(': 'void  | array',
+\ 'libxml_get_last_error(': 'void  | LibXMLError',
+\ 'libxml_set_streams_context(': 'resource streams_context | void',
+\ 'libxml_use_internal_errors(': '[bool use_errors] | bool',
+\ 'link(': 'string target, string link | bool',
+\ 'linkinfo(': 'string path | int',
+\ 'list(': 'mixed varname, mixed ... | void',
+\ 'localeconv(': 'void  | array',
+\ 'localtime(': '[int timestamp [, bool is_associative]] | array',
+\ 'log10(': 'float arg | float',
+\ 'log1p(': 'float number | float',
+\ 'log(': 'float arg [, float base] | float',
+\ 'long2ip(': 'int proper_address | string',
+\ 'lstat(': 'string filename | array',
+\ 'ltrim(': 'string str [, string charlist] | string',
+\ 'lzf_compress(': 'string data | string',
+\ 'lzf_decompress(': 'string data | string',
+\ 'lzf_optimized_for(': 'void  | int',
+\ 'mail(': 'string to, string subject, string message [, string additional_headers [, string additional_parameters]] | bool',
+\ 'mailparse_determine_best_xfer_encoding(': 'resource fp | string',
+\ 'mailparse_msg_create(': 'void  | resource',
+\ 'mailparse_msg_extract_part_file(': 'resource rfc2045, string filename [, callback callbackfunc] | string',
+\ 'mailparse_msg_extract_part(': 'resource rfc2045, string msgbody [, callback callbackfunc] | void',
+\ 'mailparse_msg_free(': 'resource rfc2045buf | bool',
+\ 'mailparse_msg_get_part_data(': 'resource rfc2045 | array',
+\ 'mailparse_msg_get_part(': 'resource rfc2045, string mimesection | resource',
+\ 'mailparse_msg_get_structure(': 'resource rfc2045 | array',
+\ 'mailparse_msg_parse_file(': 'string filename | resource',
+\ 'mailparse_msg_parse(': 'resource rfc2045buf, string data | bool',
+\ 'mailparse_rfc822_parse_addresses(': 'string addresses | array',
+\ 'mailparse_stream_encode(': 'resource sourcefp, resource destfp, string encoding | bool',
+\ 'mailparse_uudecode_all(': 'resource fp | array',
+\ 'maxdb_connect_errno(': 'void  | int',
+\ 'maxdb_connect_error(': 'void  | string',
+\ 'maxdb_debug(': 'string debug | void',
+\ 'maxdb_disable_rpl_parse(': 'resource link | bool',
+\ 'maxdb_dump_debug_info(': 'resource link | bool',
+\ 'maxdb_embedded_connect(': '[string dbname] | resource',
+\ 'maxdb_enable_reads_from_master(': 'resource link | bool',
+\ 'maxdb_enable_rpl_parse(': 'resource link | bool',
+\ 'maxdb_get_client_info(': 'void  | string',
+\ 'maxdb_get_client_version(': 'void  | int',
+\ 'maxdb_init(': 'void  | resource',
+\ 'maxdb_master_query(': 'resource link, string query | bool',
+\ 'maxdb_more_results(': 'resource link | bool',
+\ 'maxdb_next_result(': 'resource link | bool',
+\ 'maxdb_report(': 'int flags | bool',
+\ 'maxdb_rollback(': 'resource link | bool',
+\ 'maxdb_rpl_parse_enabled(': 'resource link | int',
+\ 'maxdb_rpl_probe(': 'resource link | bool',
+\ 'maxdb_rpl_query_type(': 'resource link | int',
+\ 'maxdb_select_db(': 'resource link, string dbname | bool',
+\ 'maxdb_send_query(': 'resource link, string query | bool',
+\ 'maxdb_server_end(': 'void  | void',
+\ 'maxdb_server_init(': '[array server [, array groups]] | bool',
+\ 'maxdb_stmt_sqlstate(': 'resource stmt | string',
+\ 'max(': 'number arg1, number arg2 [, number ...] | mixed',
+\ 'mb_convert_case(': 'string str, int mode [, string encoding] | string',
+\ 'mb_convert_encoding(': 'string str, string to_encoding [, mixed from_encoding] | string',
+\ 'mb_convert_kana(': 'string str [, string option [, string encoding]] | string',
+\ 'mb_convert_variables(': 'string to_encoding, mixed from_encoding, mixed &#38;vars [, mixed &#38;...] | string',
+\ 'mb_decode_mimeheader(': 'string str | string',
+\ 'mb_decode_numericentity(': 'string str, array convmap [, string encoding] | string',
+\ 'mb_detect_encoding(': 'string str [, mixed encoding_list [, bool strict]] | string',
+\ 'mb_detect_order(': '[mixed encoding_list] | mixed',
+\ 'mb_encode_mimeheader(': 'string str [, string charset [, string transfer_encoding [, string linefeed]]] | string',
+\ 'mb_encode_numericentity(': 'string str, array convmap [, string encoding] | string',
+\ 'mb_ereg(': 'string pattern, string string [, array regs] | int',
+\ 'mb_eregi(': 'string pattern, string string [, array regs] | int',
+\ 'mb_eregi_replace(': 'string pattern, string replace, string string [, string option] | string',
+\ 'mb_ereg_match(': 'string pattern, string string [, string option] | bool',
+\ 'mb_ereg_replace(': 'string pattern, string replacement, string string [, string option] | string',
+\ 'mb_ereg_search_getpos(': 'void  | int',
+\ 'mb_ereg_search_getregs(': 'void  | array',
+\ 'mb_ereg_search(': '[string pattern [, string option]] | bool',
+\ 'mb_ereg_search_init(': 'string string [, string pattern [, string option]] | bool',
+\ 'mb_ereg_search_pos(': '[string pattern [, string option]] | array',
+\ 'mb_ereg_search_regs(': '[string pattern [, string option]] | array',
+\ 'mb_ereg_search_setpos(': 'int position | bool',
+\ 'mb_get_info(': '[string type] | mixed',
+\ 'mb_http_input(': '[string type] | mixed',
+\ 'mb_http_output(': '[string encoding] | mixed',
+\ 'mb_internal_encoding(': '[string encoding] | mixed',
+\ 'mb_language(': '[string language] | mixed',
+\ 'mb_list_encodings(': 'void  | array',
+\ 'mb_output_handler(': 'string contents, int status | string',
+\ 'mb_parse_str(': 'string encoded_string [, array &#38;result] | bool',
+\ 'mb_preferred_mime_name(': 'string encoding | string',
+\ 'mb_regex_encoding(': '[string encoding] | mixed',
+\ 'mb_regex_set_options(': '[string options] | string',
+\ 'mb_send_mail(': 'string to, string subject, string message [, string additional_headers [, string additional_parameter]] | bool',
+\ 'mb_split(': 'string pattern, string string [, int limit] | array',
+\ 'mb_strcut(': 'string str, int start [, int length [, string encoding]] | string',
+\ 'mb_strimwidth(': 'string str, int start, int width [, string trimmarker [, string encoding]] | string',
+\ 'mb_strlen(': 'string str [, string encoding] | int',
+\ 'mb_strpos(': 'string haystack, string needle [, int offset [, string encoding]] | int',
+\ 'mb_strrpos(': 'string haystack, string needle [, string encoding] | int',
+\ 'mb_strtolower(': 'string str [, string encoding] | string',
+\ 'mb_strtoupper(': 'string str [, string encoding] | string',
+\ 'mb_strwidth(': 'string str [, string encoding] | int',
+\ 'mb_substitute_character(': '[mixed substrchar] | mixed',
+\ 'mb_substr_count(': 'string haystack, string needle [, string encoding] | int',
+\ 'mb_substr(': 'string str, int start [, int length [, string encoding]] | string',
+\ 'mcal_append_event(': 'int mcal_stream | int',
+\ 'mcal_close(': 'int mcal_stream [, int flags] | bool',
+\ 'mcal_create_calendar(': 'int stream, string calendar | bool',
+\ 'mcal_date_compare(': 'int a_year, int a_month, int a_day, int b_year, int b_month, int b_day | int',
+\ 'mcal_date_valid(': 'int year, int month, int day | bool',
+\ 'mcal_day_of_week(': 'int year, int month, int day | int',
+\ 'mcal_day_of_year(': 'int year, int month, int day | int',
+\ 'mcal_days_in_month(': 'int month, int leap_year | int',
+\ 'mcal_delete_calendar(': 'int stream, string calendar | bool',
+\ 'mcal_delete_event(': 'int mcal_stream, int event_id | bool',
+\ 'mcal_event_add_attribute(': 'int stream, string attribute, string value | bool',
+\ 'mcal_event_init(': 'int stream | void',
+\ 'mcal_event_set_alarm(': 'int stream, int alarm | void',
+\ 'mcal_event_set_category(': 'int stream, string category | void',
+\ 'mcal_event_set_class(': 'int stream, int class | void',
+\ 'mcal_event_set_description(': 'int stream, string description | void',
+\ 'mcal_event_set_end(': 'int stream, int year, int month, int day [, int hour [, int min [, int sec]]] | void',
+\ 'mcal_event_set_recur_daily(': 'int stream, int year, int month, int day, int interval | void',
+\ 'mcal_event_set_recur_monthly_mday(': 'int stream, int year, int month, int day, int interval | void',
+\ 'mcal_event_set_recur_monthly_wday(': 'int stream, int year, int month, int day, int interval | void',
+\ 'mcal_event_set_recur_none(': 'int stream | void',
+\ 'mcal_event_set_recur_weekly(': 'int stream, int year, int month, int day, int interval, int weekdays | void',
+\ 'mcal_event_set_recur_yearly(': 'int stream, int year, int month, int day, int interval | void',
+\ 'mcal_event_set_start(': 'int stream, int year, int month, int day [, int hour [, int min [, int sec]]] | void',
+\ 'mcal_event_set_title(': 'int stream, string title | void',
+\ 'mcal_expunge(': 'int stream | bool',
+\ 'mcal_fetch_current_stream_event(': 'int stream | object',
+\ 'mcal_fetch_event(': 'int mcal_stream, int event_id [, int options] | object',
+\ 'mcal_is_leap_year(': 'int year | bool',
+\ 'mcal_list_alarms(': 'int mcal_stream [, int begin_year, int begin_month, int begin_day, int end_year, int end_month, int end_day] | array',
+\ 'mcal_list_events(': 'int mcal_stream [, int begin_year, int begin_month, int begin_day, int end_year, int end_month, int end_day] | array',
+\ 'mcal_next_recurrence(': 'int stream, int weekstart, array next | object',
+\ 'mcal_open(': 'string calendar, string username, string password [, int options] | int',
+\ 'mcal_popen(': 'string calendar, string username, string password [, int options] | int',
+\ 'mcal_rename_calendar(': 'int stream, string old_name, string new_name | bool',
+\ 'mcal_reopen(': 'int mcal_stream, string calendar [, int options] | bool',
+\ 'mcal_snooze(': 'int stream_id, int event_id | bool',
+\ 'mcal_store_event(': 'int mcal_stream | int',
+\ 'mcal_time_valid(': 'int hour, int minutes, int seconds | bool',
+\ 'mcal_week_of_year(': 'int day, int month, int year | int',
+\ 'm_checkstatus(': 'resource conn, int identifier | int',
+\ 'm_completeauthorizations(': 'resource conn, int &#38;array | int',
+\ 'm_connect(': 'resource conn | int',
+\ 'm_connectionerror(': 'resource conn | string',
+\ 'mcrypt_cbc(': 'int cipher, string key, string data, int mode [, string iv] | string',
+\ 'mcrypt_cfb(': 'int cipher, string key, string data, int mode, string iv | string',
+\ 'mcrypt_create_iv(': 'int size [, int source] | string',
+\ 'mcrypt_decrypt(': 'string cipher, string key, string data, string mode [, string iv] | string',
+\ 'mcrypt_ecb(': 'int cipher, string key, string data, int mode | string',
+\ 'mcrypt_enc_get_algorithms_name(': 'resource td | string',
+\ 'mcrypt_enc_get_block_size(': 'resource td | int',
+\ 'mcrypt_enc_get_iv_size(': 'resource td | int',
+\ 'mcrypt_enc_get_key_size(': 'resource td | int',
+\ 'mcrypt_enc_get_modes_name(': 'resource td | string',
+\ 'mcrypt_enc_get_supported_key_sizes(': 'resource td | array',
+\ 'mcrypt_enc_is_block_algorithm(': 'resource td | bool',
+\ 'mcrypt_enc_is_block_algorithm_mode(': 'resource td | bool',
+\ 'mcrypt_enc_is_block_mode(': 'resource td | bool',
+\ 'mcrypt_encrypt(': 'string cipher, string key, string data, string mode [, string iv] | string',
+\ 'mcrypt_enc_self_test(': 'resource td | int',
+\ 'mcrypt_generic_deinit(': 'resource td | bool',
+\ 'mcrypt_generic_end(': 'resource td | bool',
+\ 'mcrypt_generic(': 'resource td, string data | string',
+\ 'mcrypt_generic_init(': 'resource td, string key, string iv | int',
+\ 'mcrypt_get_block_size(': 'int cipher | int',
+\ 'mcrypt_get_cipher_name(': 'int cipher | string',
+\ 'mcrypt_get_iv_size(': 'string cipher, string mode | int',
+\ 'mcrypt_get_key_size(': 'int cipher | int',
+\ 'mcrypt_list_algorithms(': '[string lib_dir] | array',
+\ 'mcrypt_list_modes(': '[string lib_dir] | array',
+\ 'mcrypt_module_close(': 'resource td | bool',
+\ 'mcrypt_module_get_algo_block_size(': 'string algorithm [, string lib_dir] | int',
+\ 'mcrypt_module_get_algo_key_size(': 'string algorithm [, string lib_dir] | int',
+\ 'mcrypt_module_get_supported_key_sizes(': 'string algorithm [, string lib_dir] | array',
+\ 'mcrypt_module_is_block_algorithm(': 'string algorithm [, string lib_dir] | bool',
+\ 'mcrypt_module_is_block_algorithm_mode(': 'string mode [, string lib_dir] | bool',
+\ 'mcrypt_module_is_block_mode(': 'string mode [, string lib_dir] | bool',
+\ 'mcrypt_module_open(': 'string algorithm, string algorithm_directory, string mode, string mode_directory | resource',
+\ 'mcrypt_module_self_test(': 'string algorithm [, string lib_dir] | bool',
+\ 'mcrypt_ofb(': 'int cipher, string key, string data, int mode, string iv | string',
+\ 'md5_file(': 'string filename [, bool raw_output] | string',
+\ 'md5(': 'string str [, bool raw_output] | string',
+\ 'mdecrypt_generic(': 'resource td, string data | string',
+\ 'm_deletetrans(': 'resource conn, int identifier | bool',
+\ 'm_destroyconn(': 'resource conn | bool',
+\ 'm_destroyengine(': 'void  | void',
+\ 'memcache_debug(': 'bool on_off | bool',
+\ 'memory_get_usage(': 'void  | int',
+\ 'metaphone(': 'string str [, int phones] | string',
+\ 'method_exists(': 'object object, string method_name | bool',
+\ 'm_getcellbynum(': 'resource conn, int identifier, int column, int row | string',
+\ 'm_getcell(': 'resource conn, int identifier, string column, int row | string',
+\ 'm_getcommadelimited(': 'resource conn, int identifier | string',
+\ 'm_getheader(': 'resource conn, int identifier, int column_num | string',
+\ 'mhash_count(': 'void  | int',
+\ 'mhash_get_block_size(': 'int hash | int',
+\ 'mhash_get_hash_name(': 'int hash | string',
+\ 'mhash(': 'int hash, string data [, string key] | string',
+\ 'mhash_keygen_s2k(': 'int hash, string password, string salt, int bytes | string',
+\ 'microtime(': '[bool get_as_float] | mixed',
+\ 'mime_content_type(': 'string filename | string',
+\ 'ming_keypress(': 'string str | int',
+\ 'ming_setcubicthreshold(': 'int threshold | void',
+\ 'ming_setscale(': 'int scale | void',
+\ 'ming_useConstants(': 'int use | void',
+\ 'ming_useswfversion(': 'int version | void',
+\ 'min(': 'number arg1, number arg2 [, number ...] | mixed',
+\ 'm_initconn(': 'void  | resource',
+\ 'm_initengine(': 'string location | int',
+\ 'm_iscommadelimited(': 'resource conn, int identifier | int',
+\ 'mkdir(': 'string pathname [, int mode [, bool recursive [, resource context]]] | bool',
+\ 'mktime(': '[int hour [, int minute [, int second [, int month [, int day [, int year [, int is_dst]]]]]]] | int',
+\ 'm_maxconntimeout(': 'resource conn, int secs | bool',
+\ 'm_monitor(': 'resource conn | int',
+\ 'm_numcolumns(': 'resource conn, int identifier | int',
+\ 'm_numrows(': 'resource conn, int identifier | int',
+\ 'money_format(': 'string format, float number | string',
+\ 'move_uploaded_file(': 'string filename, string destination | bool',
+\ 'm_parsecommadelimited(': 'resource conn, int identifier | int',
+\ 'm_responsekeys(': 'resource conn, int identifier | array',
+\ 'm_responseparam(': 'resource conn, int identifier, string key | string',
+\ 'm_returnstatus(': 'resource conn, int identifier | int',
+\ 'msession_connect(': 'string host, string port | bool',
+\ 'msession_count(': 'void  | int',
+\ 'msession_create(': 'string session | bool',
+\ 'msession_destroy(': 'string name | bool',
+\ 'msession_disconnect(': 'void  | void',
+\ 'msession_find(': 'string name, string value | array',
+\ 'msession_get_array(': 'string session | array',
+\ 'msession_get_data(': 'string session | string',
+\ 'msession_get(': 'string session, string name, string value | string',
+\ 'msession_inc(': 'string session, string name | string',
+\ 'msession_list(': 'void  | array',
+\ 'msession_listvar(': 'string name | array',
+\ 'msession_lock(': 'string name | int',
+\ 'msession_plugin(': 'string session, string val [, string param] | string',
+\ 'msession_randstr(': 'int param | string',
+\ 'msession_set_array(': 'string session, array tuples | void',
+\ 'msession_set_data(': 'string session, string value | bool',
+\ 'msession_set(': 'string session, string name, string value | bool',
+\ 'msession_timeout(': 'string session [, int param] | int',
+\ 'msession_uniq(': 'int param | string',
+\ 'msession_unlock(': 'string session, int key | int',
+\ 'm_setblocking(': 'resource conn, int tf | int',
+\ 'm_setdropfile(': 'resource conn, string directory | int',
+\ 'm_setip(': 'resource conn, string host, int port | int',
+\ 'm_setssl_cafile(': 'resource conn, string cafile | int',
+\ 'm_setssl_files(': 'resource conn, string sslkeyfile, string sslcertfile | int',
+\ 'm_setssl(': 'resource conn, string host, int port | int',
+\ 'm_settimeout(': 'resource conn, int seconds | int',
+\ 'msg_get_queue(': 'int key [, int perms] | resource',
+\ 'msg_receive(': 'resource queue, int desiredmsgtype, int &#38;msgtype, int maxsize, mixed &#38;message [, bool unserialize [, int flags [, int &#38;errorcode]]] | bool',
+\ 'msg_remove_queue(': 'resource queue | bool',
+\ 'msg_send(': 'resource queue, int msgtype, mixed message [, bool serialize [, bool blocking [, int &#38;errorcode]]] | bool',
+\ 'msg_set_queue(': 'resource queue, array data | bool',
+\ 'msg_stat_queue(': 'resource queue | array',
+\ 'msql_affected_rows(': 'resource result | int',
+\ 'msql_close(': '[resource link_identifier] | bool',
+\ 'msql_connect(': '[string hostname] | resource',
+\ 'msql_create_db(': 'string database_name [, resource link_identifier] | bool',
+\ 'msql_data_seek(': 'resource result, int row_number | bool',
+\ 'msql_db_query(': 'string database, string query [, resource link_identifier] | resource',
+\ 'msql_drop_db(': 'string database_name [, resource link_identifier] | bool',
+\ 'msql_error(': 'void  | string',
+\ 'msql_fetch_array(': 'resource result [, int result_type] | array',
+\ 'msql_fetch_field(': 'resource result [, int field_offset] | object',
+\ 'msql_fetch_object(': 'resource result | object',
+\ 'msql_fetch_row(': 'resource result | array',
+\ 'msql_field_flags(': 'resource result, int field_offset | string',
+\ 'msql_field_len(': 'resource result, int field_offset | int',
+\ 'msql_field_name(': 'resource result, int field_offset | string',
+\ 'msql_field_seek(': 'resource result, int field_offset | bool',
+\ 'msql_field_table(': 'resource result, int field_offset | int',
+\ 'msql_field_type(': 'resource result, int field_offset | string',
+\ 'msql_free_result(': 'resource result | bool',
+\ 'msql_list_dbs(': '[resource link_identifier] | resource',
+\ 'msql_list_fields(': 'string database, string tablename [, resource link_identifier] | resource',
+\ 'msql_list_tables(': 'string database [, resource link_identifier] | resource',
+\ 'msql_num_fields(': 'resource result | int',
+\ 'msql_num_rows(': 'resource query_identifier | int',
+\ 'msql_pconnect(': '[string hostname] | resource',
+\ 'msql_query(': 'string query [, resource link_identifier] | resource',
+\ 'msql_result(': 'resource result, int row [, mixed field] | string',
+\ 'msql_select_db(': 'string database_name [, resource link_identifier] | bool',
+\ 'm_sslcert_gen_hash(': 'string filename | string',
+\ 'mssql_bind(': 'resource stmt, string param_name, mixed &#38;var, int type [, int is_output [, int is_null [, int maxlen]]] | bool',
+\ 'mssql_close(': '[resource link_identifier] | bool',
+\ 'mssql_connect(': '[string servername [, string username [, string password]]] | resource',
+\ 'mssql_data_seek(': 'resource result_identifier, int row_number | bool',
+\ 'mssql_execute(': 'resource stmt [, bool skip_results] | mixed',
+\ 'mssql_fetch_array(': 'resource result [, int result_type] | array',
+\ 'mssql_fetch_assoc(': 'resource result_id | array',
+\ 'mssql_fetch_batch(': 'resource result_index | int',
+\ 'mssql_fetch_field(': 'resource result [, int field_offset] | object',
+\ 'mssql_fetch_object(': 'resource result | object',
+\ 'mssql_fetch_row(': 'resource result | array',
+\ 'mssql_field_length(': 'resource result [, int offset] | int',
+\ 'mssql_field_name(': 'resource result [, int offset] | string',
+\ 'mssql_field_seek(': 'resource result, int field_offset | bool',
+\ 'mssql_field_type(': 'resource result [, int offset] | string',
+\ 'mssql_free_result(': 'resource result | bool',
+\ 'mssql_free_statement(': 'resource statement | bool',
+\ 'mssql_get_last_message(': 'void  | string',
+\ 'mssql_guid_string(': 'string binary [, int short_format] | string',
+\ 'mssql_init(': 'string sp_name [, resource conn_id] | resource',
+\ 'mssql_min_error_severity(': 'int severity | void',
+\ 'mssql_min_message_severity(': 'int severity | void',
+\ 'mssql_next_result(': 'resource result_id | bool',
+\ 'mssql_num_fields(': 'resource result | int',
+\ 'mssql_num_rows(': 'resource result | int',
+\ 'mssql_pconnect(': '[string servername [, string username [, string password]]] | resource',
+\ 'mssql_query(': 'string query [, resource link_identifier [, int batch_size]] | mixed',
+\ 'mssql_result(': 'resource result, int row, mixed field | string',
+\ 'mssql_rows_affected(': 'resource conn_id | int',
+\ 'mssql_select_db(': 'string database_name [, resource link_identifier] | bool',
+\ 'mt_getrandmax(': 'void  | int',
+\ 'mt_rand(': '[int min, int max] | int',
+\ 'm_transactionssent(': 'resource conn | int',
+\ 'm_transinqueue(': 'resource conn | int',
+\ 'm_transkeyval(': 'resource conn, int identifier, string key, string value | int',
+\ 'm_transnew(': 'resource conn | int',
+\ 'm_transsend(': 'resource conn, int identifier | int',
+\ 'mt_srand(': '[int seed] | void',
+\ 'muscat_close(': 'resource muscat_handle | void',
+\ 'muscat_get(': 'resource muscat_handle | string',
+\ 'muscat_give(': 'resource muscat_handle, string string | void',
+\ 'muscat_setup(': 'int size [, string muscat_dir] | resource',
+\ 'muscat_setup_net(': 'string muscat_host | resource',
+\ 'm_uwait(': 'int microsecs | int',
+\ 'm_validateidentifier(': 'resource conn, int tf | int',
+\ 'm_verifyconnection(': 'resource conn, int tf | bool',
+\ 'm_verifysslcert(': 'resource conn, int tf | bool',
+\ 'mysql_affected_rows(': '[resource link_identifier] | int',
+\ 'mysql_change_user(': 'string user, string password [, string database [, resource link_identifier]] | int',
+\ 'mysql_client_encoding(': '[resource link_identifier] | string',
+\ 'mysql_close(': '[resource link_identifier] | bool',
+\ 'mysql_connect(': '[string server [, string username [, string password [, bool new_link [, int client_flags]]]]] | resource',
+\ 'mysql_create_db(': 'string database_name [, resource link_identifier] | bool',
+\ 'mysql_data_seek(': 'resource result, int row_number | bool',
+\ 'mysql_db_name(': 'resource result, int row [, mixed field] | string',
+\ 'mysql_db_query(': 'string database, string query [, resource link_identifier] | resource',
+\ 'mysql_drop_db(': 'string database_name [, resource link_identifier] | bool',
+\ 'mysql_errno(': '[resource link_identifier] | int',
+\ 'mysql_error(': '[resource link_identifier] | string',
+\ 'mysql_escape_string(': 'string unescaped_string | string',
+\ 'mysql_fetch_array(': 'resource result [, int result_type] | array',
+\ 'mysql_fetch_assoc(': 'resource result | array',
+\ 'mysql_fetch_field(': 'resource result [, int field_offset] | object',
+\ 'mysql_fetch_lengths(': 'resource result | array',
+\ 'mysql_fetch_object(': 'resource result | object',
+\ 'mysql_fetch_row(': 'resource result | array',
+\ 'mysql_field_flags(': 'resource result, int field_offset | string',
+\ 'mysql_field_len(': 'resource result, int field_offset | int',
+\ 'mysql_field_name(': 'resource result, int field_offset | string',
+\ 'mysql_field_seek(': 'resource result, int field_offset | bool',
+\ 'mysql_field_table(': 'resource result, int field_offset | string',
+\ 'mysql_field_type(': 'resource result, int field_offset | string',
+\ 'mysql_free_result(': 'resource result | bool',
+\ 'mysql_get_client_info(': 'void  | string',
+\ 'mysql_get_host_info(': '[resource link_identifier] | string',
+\ 'mysql_get_proto_info(': '[resource link_identifier] | int',
+\ 'mysql_get_server_info(': '[resource link_identifier] | string',
+\ 'mysqli_connect_errno(': 'void  | int',
+\ 'mysqli_connect_error(': 'void  | string',
+\ 'mysqli_debug(': 'string debug | bool',
+\ 'mysqli_disable_rpl_parse(': 'mysqli link | bool',
+\ 'mysqli_dump_debug_info(': 'mysqli link | bool',
+\ 'mysqli_embedded_connect(': '[string dbname] | mysqli',
+\ 'mysqli_enable_reads_from_master(': 'mysqli link | bool',
+\ 'mysqli_enable_rpl_parse(': 'mysqli link | bool',
+\ 'mysqli_get_client_info(': 'void  | string',
+\ 'mysqli_get_client_version(': 'void  | int',
+\ 'mysqli_init(': 'void  | mysqli',
+\ 'mysqli_master_query(': 'mysqli link, string query | bool',
+\ 'mysqli_more_results(': 'mysqli link | bool',
+\ 'mysqli_next_result(': 'mysqli link | bool',
+\ 'mysql_info(': '[resource link_identifier] | string',
+\ 'mysql_insert_id(': '[resource link_identifier] | int',
+\ 'mysqli_report(': 'int flags | bool',
+\ 'mysqli_rollback(': 'mysqli link | bool',
+\ 'mysqli_rpl_parse_enabled(': 'mysqli link | int',
+\ 'mysqli_rpl_probe(': 'mysqli link | bool',
+\ 'mysqli_select_db(': 'mysqli link, string dbname | bool',
+\ 'mysqli_server_end(': 'void  | void',
+\ 'mysqli_server_init(': '[array server [, array groups]] | bool',
+\ 'mysqli_set_charset(': 'mysqli link, string charset | bool',
+\ 'mysqli_stmt_sqlstate(': 'mysqli_stmt stmt | string',
+\ 'mysql_list_dbs(': '[resource link_identifier] | resource',
+\ 'mysql_list_fields(': 'string database_name, string table_name [, resource link_identifier] | resource',
+\ 'mysql_list_processes(': '[resource link_identifier] | resource',
+\ 'mysql_list_tables(': 'string database [, resource link_identifier] | resource',
+\ 'mysql_num_fields(': 'resource result | int',
+\ 'mysql_num_rows(': 'resource result | int',
+\ 'mysql_pconnect(': '[string server [, string username [, string password [, int client_flags]]]] | resource',
+\ 'mysql_ping(': '[resource link_identifier] | bool',
+\ 'mysql_query(': 'string query [, resource link_identifier] | resource',
+\ 'mysql_real_escape_string(': 'string unescaped_string [, resource link_identifier] | string',
+\ 'mysql_result(': 'resource result, int row [, mixed field] | string',
+\ 'mysql_select_db(': 'string database_name [, resource link_identifier] | bool',
+\ 'mysql_stat(': '[resource link_identifier] | string',
+\ 'mysql_tablename(': 'resource result, int i | string',
+\ 'mysql_thread_id(': '[resource link_identifier] | int',
+\ 'mysql_unbuffered_query(': 'string query [, resource link_identifier] | resource',
+\ 'natcasesort(': 'array &#38;array | bool',
+\ 'natsort(': 'array &#38;array | bool',
+\ 'ncurses_addch(': 'int ch | int',
+\ 'ncurses_addchnstr(': 'string s, int n | int',
+\ 'ncurses_addchstr(': 'string s | int',
+\ 'ncurses_addnstr(': 'string s, int n | int',
+\ 'ncurses_addstr(': 'string text | int',
+\ 'ncurses_assume_default_colors(': 'int fg, int bg | int',
+\ 'ncurses_attroff(': 'int attributes | int',
+\ 'ncurses_attron(': 'int attributes | int',
+\ 'ncurses_attrset(': 'int attributes | int',
+\ 'ncurses_baudrate(': 'void  | int',
+\ 'ncurses_beep(': 'void  | int',
+\ 'ncurses_bkgd(': 'int attrchar | int',
+\ 'ncurses_bkgdset(': 'int attrchar | void',
+\ 'ncurses_border(': 'int left, int right, int top, int bottom, int tl_corner, int tr_corner, int bl_corner, int br_corner | int',
+\ 'ncurses_bottom_panel(': 'resource panel | int',
+\ 'ncurses_can_change_color(': 'void  | bool',
+\ 'ncurses_cbreak(': 'void  | bool',
+\ 'ncurses_clear(': 'void  | bool',
+\ 'ncurses_clrtobot(': 'void  | bool',
+\ 'ncurses_clrtoeol(': 'void  | bool',
+\ 'ncurses_color_content(': 'int color, int &#38;r, int &#38;g, int &#38;b | int',
+\ 'ncurses_color_set(': 'int pair | int',
+\ 'ncurses_curs_set(': 'int visibility | int',
+\ 'ncurses_define_key(': 'string definition, int keycode | int',
+\ 'ncurses_def_prog_mode(': 'void  | bool',
+\ 'ncurses_def_shell_mode(': 'void  | bool',
+\ 'ncurses_delay_output(': 'int milliseconds | int',
+\ 'ncurses_delch(': 'void  | bool',
+\ 'ncurses_deleteln(': 'void  | bool',
+\ 'ncurses_del_panel(': 'resource panel | bool',
+\ 'ncurses_delwin(': 'resource window | bool',
+\ 'ncurses_doupdate(': 'void  | bool',
+\ 'ncurses_echochar(': 'int character | int',
+\ 'ncurses_echo(': 'void  | bool',
+\ 'ncurses_end(': 'void  | int',
+\ 'ncurses_erasechar(': 'void  | string',
+\ 'ncurses_erase(': 'void  | bool',
+\ 'ncurses_filter(': 'void  | void',
+\ 'ncurses_flash(': 'void  | bool',
+\ 'ncurses_flushinp(': 'void  | bool',
+\ 'ncurses_getch(': 'void  | int',
+\ 'ncurses_getmaxyx(': 'resource window, int &#38;y, int &#38;x | void',
+\ 'ncurses_getmouse(': 'array &#38;mevent | bool',
+\ 'ncurses_getyx(': 'resource window, int &#38;y, int &#38;x | void',
+\ 'ncurses_halfdelay(': 'int tenth | int',
+\ 'ncurses_has_colors(': 'void  | bool',
+\ 'ncurses_has_ic(': 'void  | bool',
+\ 'ncurses_has_il(': 'void  | bool',
+\ 'ncurses_has_key(': 'int keycode | int',
+\ 'ncurses_hide_panel(': 'resource panel | int',
+\ 'ncurses_hline(': 'int charattr, int n | int',
+\ 'ncurses_inch(': 'void  | string',
+\ 'ncurses_init_color(': 'int color, int r, int g, int b | int',
+\ 'ncurses_init(': 'void  | void',
+\ 'ncurses_init_pair(': 'int pair, int fg, int bg | int',
+\ 'ncurses_insch(': 'int character | int',
+\ 'ncurses_insdelln(': 'int count | int',
+\ 'ncurses_insertln(': 'void  | bool',
+\ 'ncurses_insstr(': 'string text | int',
+\ 'ncurses_instr(': 'string &#38;buffer | int',
+\ 'ncurses_isendwin(': 'void  | bool',
+\ 'ncurses_keyok(': 'int keycode, bool enable | int',
+\ 'ncurses_keypad(': 'resource window, bool bf | int',
+\ 'ncurses_killchar(': 'void  | string',
+\ 'ncurses_longname(': 'void  | string',
+\ 'ncurses_meta(': 'resource window, bool 8bit | int',
+\ 'ncurses_mouseinterval(': 'int milliseconds | int',
+\ 'ncurses_mousemask(': 'int newmask, int &#38;oldmask | int',
+\ 'ncurses_mouse_trafo(': 'int &#38;y, int &#38;x, bool toscreen | bool',
+\ 'ncurses_move(': 'int y, int x | int',
+\ 'ncurses_move_panel(': 'resource panel, int startx, int starty | int',
+\ 'ncurses_mvaddch(': 'int y, int x, int c | int',
+\ 'ncurses_mvaddchnstr(': 'int y, int x, string s, int n | int',
+\ 'ncurses_mvaddchstr(': 'int y, int x, string s | int',
+\ 'ncurses_mvaddnstr(': 'int y, int x, string s, int n | int',
+\ 'ncurses_mvaddstr(': 'int y, int x, string s | int',
+\ 'ncurses_mvcur(': 'int old_y, int old_x, int new_y, int new_x | int',
+\ 'ncurses_mvdelch(': 'int y, int x | int',
+\ 'ncurses_mvgetch(': 'int y, int x | int',
+\ 'ncurses_mvhline(': 'int y, int x, int attrchar, int n | int',
+\ 'ncurses_mvinch(': 'int y, int x | int',
+\ 'ncurses_mvvline(': 'int y, int x, int attrchar, int n | int',
+\ 'ncurses_mvwaddstr(': 'resource window, int y, int x, string text | int',
+\ 'ncurses_napms(': 'int milliseconds | int',
+\ 'ncurses_newpad(': 'int rows, int cols | resource',
+\ 'ncurses_new_panel(': 'resource window | resource',
+\ 'ncurses_newwin(': 'int rows, int cols, int y, int x | resource',
+\ 'ncurses_nl(': 'void  | bool',
+\ 'ncurses_nocbreak(': 'void  | bool',
+\ 'ncurses_noecho(': 'void  | bool',
+\ 'ncurses_nonl(': 'void  | bool',
+\ 'ncurses_noqiflush(': 'void  | void',
+\ 'ncurses_noraw(': 'void  | bool',
+\ 'ncurses_pair_content(': 'int pair, int &#38;f, int &#38;b | int',
+\ 'ncurses_panel_above(': 'resource panel | resource',
+\ 'ncurses_panel_below(': 'resource panel | resource',
+\ 'ncurses_panel_window(': 'resource panel | resource',
+\ 'ncurses_pnoutrefresh(': 'resource pad, int pminrow, int pmincol, int sminrow, int smincol, int smaxrow, int smaxcol | int',
+\ 'ncurses_prefresh(': 'resource pad, int pminrow, int pmincol, int sminrow, int smincol, int smaxrow, int smaxcol | int',
+\ 'ncurses_putp(': 'string text | int',
+\ 'ncurses_qiflush(': 'void  | void',
+\ 'ncurses_raw(': 'void  | bool',
+\ 'ncurses_refresh(': 'int ch | int',
+\ 'ncurses_replace_panel(': 'resource panel, resource window | int',
+\ 'ncurses_reset_prog_mode(': 'void  | int',
+\ 'ncurses_reset_shell_mode(': 'void  | int',
+\ 'ncurses_resetty(': 'void  | bool',
+\ 'ncurses_savetty(': 'void  | bool',
+\ 'ncurses_scr_dump(': 'string filename | int',
+\ 'ncurses_scr_init(': 'string filename | int',
+\ 'ncurses_scrl(': 'int count | int',
+\ 'ncurses_scr_restore(': 'string filename | int',
+\ 'ncurses_scr_set(': 'string filename | int',
+\ 'ncurses_show_panel(': 'resource panel | int',
+\ 'ncurses_slk_attr(': 'void  | bool',
+\ 'ncurses_slk_attroff(': 'int intarg | int',
+\ 'ncurses_slk_attron(': 'int intarg | int',
+\ 'ncurses_slk_attrset(': 'int intarg | int',
+\ 'ncurses_slk_clear(': 'void  | bool',
+\ 'ncurses_slk_color(': 'int intarg | int',
+\ 'ncurses_slk_init(': 'int format | bool',
+\ 'ncurses_slk_noutrefresh(': 'void  | bool',
+\ 'ncurses_slk_refresh(': 'void  | bool',
+\ 'ncurses_slk_restore(': 'void  | bool',
+\ 'ncurses_slk_set(': 'int labelnr, string label, int format | bool',
+\ 'ncurses_slk_touch(': 'void  | bool',
+\ 'ncurses_standend(': 'void  | int',
+\ 'ncurses_standout(': 'void  | int',
+\ 'ncurses_start_color(': 'void  | int',
+\ 'ncurses_termattrs(': 'void  | bool',
+\ 'ncurses_termname(': 'void  | string',
+\ 'ncurses_timeout(': 'int millisec | void',
+\ 'ncurses_top_panel(': 'resource panel | int',
+\ 'ncurses_typeahead(': 'int fd | int',
+\ 'ncurses_ungetch(': 'int keycode | int',
+\ 'ncurses_ungetmouse(': 'array mevent | bool',
+\ 'ncurses_update_panels(': 'void  | void',
+\ 'ncurses_use_default_colors(': 'void  | bool',
+\ 'ncurses_use_env(': 'bool flag | void',
+\ 'ncurses_use_extended_names(': 'bool flag | int',
+\ 'ncurses_vidattr(': 'int intarg | int',
+\ 'ncurses_vline(': 'int charattr, int n | int',
+\ 'ncurses_waddch(': 'resource window, int ch | int',
+\ 'ncurses_waddstr(': 'resource window, string str [, int n] | int',
+\ 'ncurses_wattroff(': 'resource window, int attrs | int',
+\ 'ncurses_wattron(': 'resource window, int attrs | int',
+\ 'ncurses_wattrset(': 'resource window, int attrs | int',
+\ 'ncurses_wborder(': 'resource window, int left, int right, int top, int bottom, int tl_corner, int tr_corner, int bl_corner, int br_corner | int',
+\ 'ncurses_wclear(': 'resource window | int',
+\ 'ncurses_wcolor_set(': 'resource window, int color_pair | int',
+\ 'ncurses_werase(': 'resource window | int',
+\ 'ncurses_wgetch(': 'resource window | int',
+\ 'ncurses_whline(': 'resource window, int charattr, int n | int',
+\ 'ncurses_wmouse_trafo(': 'resource window, int &#38;y, int &#38;x, bool toscreen | bool',
+\ 'ncurses_wmove(': 'resource window, int y, int x | int',
+\ 'ncurses_wnoutrefresh(': 'resource window | int',
+\ 'ncurses_wrefresh(': 'resource window | int',
+\ 'ncurses_wstandend(': 'resource window | int',
+\ 'ncurses_wstandout(': 'resource window | int',
+\ 'ncurses_wvline(': 'resource window, int charattr, int n | int',
+\ 'newt_bell(': 'void  | void',
+\ 'newt_button_bar(': 'array &#38;buttons | resource',
+\ 'newt_button(': 'int left, int top, string text | resource',
+\ 'newt_centered_window(': 'int width, int height [, string title] | int',
+\ 'newt_checkbox_get_value(': 'resource checkbox | string',
+\ 'newt_checkbox(': 'int left, int top, string text, string def_value [, string seq] | resource',
+\ 'newt_checkbox_set_flags(': 'resource checkbox, int flags, int sense | void',
+\ 'newt_checkbox_set_value(': 'resource checkbox, string value | void',
+\ 'newt_checkbox_tree_add_item(': 'resource checkboxtree, string text, mixed data, int flags, int index [, int ...] | void',
+\ 'newt_checkbox_tree_find_item(': 'resource checkboxtree, mixed data | array',
+\ 'newt_checkbox_tree_get_current(': 'resource checkboxtree | mixed',
+\ 'newt_checkbox_tree_get_entry_value(': 'resource checkboxtree, mixed data | string',
+\ 'newt_checkbox_tree_get_multi_selection(': 'resource checkboxtree, string seqnum | array',
+\ 'newt_checkbox_tree_get_selection(': 'resource checkboxtree | array',
+\ 'newt_checkbox_tree(': 'int left, int top, int height [, int flags] | resource',
+\ 'newt_checkbox_tree_multi(': 'int left, int top, int height, string seq [, int flags] | resource',
+\ 'newt_checkbox_tree_set_current(': 'resource checkboxtree, mixed data | void',
+\ 'newt_checkbox_tree_set_entry(': 'resource checkboxtree, mixed data, string text | void',
+\ 'newt_checkbox_tree_set_entry_value(': 'resource checkboxtree, mixed data, string value | void',
+\ 'newt_checkbox_tree_set_width(': 'resource checkbox_tree, int width | void',
+\ 'newt_clear_key_buffer(': 'void  | void',
+\ 'newt_cls(': 'void  | void',
+\ 'newt_compact_button(': 'int left, int top, string text | resource',
+\ 'newt_component_add_callback(': 'resource component, mixed func_name, mixed data | void',
+\ 'newt_component_takes_focus(': 'resource component, bool takes_focus | void',
+\ 'newt_create_grid(': 'int cols, int rows | resource',
+\ 'newt_cursor_off(': 'void  | void',
+\ 'newt_cursor_on(': 'void  | void',
+\ 'newt_delay(': 'int microseconds | void',
+\ 'newt_draw_form(': 'resource form | void',
+\ 'newt_draw_root_text(': 'int left, int top, string text | void',
+\ 'newt_entry_get_value(': 'resource entry | string',
+\ 'newt_entry(': 'int left, int top, int width [, string init_value [, int flags]] | resource',
+\ 'newt_entry_set_filter(': 'resource entry, callback filter, mixed data | void',
+\ 'newt_entry_set_flags(': 'resource entry, int flags, int sense | void',
+\ 'newt_entry_set(': 'resource entry, string value [, bool cursor_at_end] | void',
+\ 'newt_finished(': 'void  | int',
+\ 'newt_form_add_component(': 'resource form, resource component | void',
+\ 'newt_form_add_components(': 'resource form, array components | void',
+\ 'newt_form_add_host_key(': 'resource form, int key | void',
+\ 'newt_form_destroy(': 'resource form | void',
+\ 'newt_form_get_current(': 'resource form | resource',
+\ 'newt_form(': '[resource vert_bar [, string help [, int flags]]] | resource',
+\ 'newt_form_run(': 'resource form, array &#38;exit_struct | void',
+\ 'newt_form_set_background(': 'resource from, int background | void',
+\ 'newt_form_set_height(': 'resource form, int height | void',
+\ 'newt_form_set_size(': 'resource form | void',
+\ 'newt_form_set_timer(': 'resource form, int milliseconds | void',
+\ 'newt_form_set_width(': 'resource form, int width | void',
+\ 'newt_form_watch_fd(': 'resource form, resource stream [, int flags] | void',
+\ 'newt_get_screen_size(': 'int &#38;cols, int &#38;rows | void',
+\ 'newt_grid_add_components_to_form(': 'resource grid, resource form, bool recurse | void',
+\ 'newt_grid_basic_window(': 'resource text, resource middle, resource buttons | resource',
+\ 'newt_grid_free(': 'resource grid, bool recurse | void',
+\ 'newt_grid_get_size(': 'resouce grid, int &#38;width, int &#38;height | void',
+\ 'newt_grid_h_close_stacked(': 'int element1_type, resource element1 [, int ... [, resource ...]] | resource',
+\ 'newt_grid_h_stacked(': 'int element1_type, resource element1 [, int ... [, resource ...]] | resource',
+\ 'newt_grid_place(': 'resource grid, int left, int top | void',
+\ 'newt_grid_set_field(': 'resource grid, int col, int row, int type, resource val, int pad_left, int pad_top, int pad_right, int pad_bottom, int anchor [, int flags] | void',
+\ 'newt_grid_simple_window(': 'resource text, resource middle, resource buttons | resource',
+\ 'newt_grid_v_close_stacked(': 'int element1_type, resource element1 [, int ... [, resource ...]] | resource',
+\ 'newt_grid_v_stacked(': 'int element1_type, resource element1 [, int ... [, resource ...]] | resource',
+\ 'newt_grid_wrapped_window_at(': 'resource grid, string title, int left, int top | void',
+\ 'newt_grid_wrapped_window(': 'resource grid, string title | void',
+\ 'newt_init(': 'void  | int',
+\ 'newt_label(': 'int left, int top, string text | resource',
+\ 'newt_label_set_text(': 'resource label, string text | void',
+\ 'newt_listbox_append_entry(': 'resource listbox, string text, mixed data | void',
+\ 'newt_listbox_clear(': 'resource listobx | void',
+\ 'newt_listbox_clear_selection(': 'resource listbox | void',
+\ 'newt_listbox_delete_entry(': 'resource listbox, mixed key | void',
+\ 'newt_listbox_get_current(': 'resource listbox | string',
+\ 'newt_listbox_get_selection(': 'resource listbox | array',
+\ 'newt_listbox(': 'int left, int top, int height [, int flags] | resource',
+\ 'newt_listbox_insert_entry(': 'resource listbox, string text, mixed data, mixed key | void',
+\ 'newt_listbox_item_count(': 'resource listbox | int',
+\ 'newt_listbox_select_item(': 'resource listbox, mixed key, int sense | void',
+\ 'newt_listbox_set_current_by_key(': 'resource listbox, mixed key | void',
+\ 'newt_listbox_set_current(': 'resource listbox, int num | void',
+\ 'newt_listbox_set_data(': 'resource listbox, int num, mixed data | void',
+\ 'newt_listbox_set_entry(': 'resource listbox, int num, string text | void',
+\ 'newt_listbox_set_width(': 'resource listbox, int width | void',
+\ 'newt_listitem_get_data(': 'resource item | mixed',
+\ 'newt_listitem(': 'int left, int top, string text, bool is_default, resouce prev_item, mixed data [, int flags] | resource',
+\ 'newt_listitem_set(': 'resource item, string text | void',
+\ 'newt_open_window(': 'int left, int top, int width, int height [, string title] | int',
+\ 'newt_pop_help_line(': 'void  | void',
+\ 'newt_pop_window(': 'void  | void',
+\ 'newt_push_help_line(': '[string text] | void',
+\ 'newt_radiobutton(': 'int left, int top, string text, bool is_default [, resource prev_button] | resource',
+\ 'newt_radio_get_current(': 'resource set_member | resource',
+\ 'newt_redraw_help_line(': 'void  | void',
+\ 'newt_reflow_text(': 'string text, int width, int flex_down, int flex_up, int &#38;actual_width, int &#38;actual_height | string',
+\ 'newt_refresh(': 'void  | void',
+\ 'newt_resize_screen(': '[bool redraw] | void',
+\ 'newt_resume(': 'void  | void',
+\ 'newt_run_form(': 'resource form | resource',
+\ 'newt_scale(': 'int left, int top, int width, int full_value | resource',
+\ 'newt_scale_set(': 'resource scale, int amount | void',
+\ 'newt_scrollbar_set(': 'resource scrollbar, int where, int total | void',
+\ 'newt_set_help_callback(': 'mixed function | void',
+\ 'newt_set_suspend_callback(': 'callback function, mixed data | void',
+\ 'newt_suspend(': 'void  | void',
+\ 'newt_texbox_set_text(': 'resource textbox, string text | void',
+\ 'newt_textbox_get_num_lines(': 'resource textbox | int',
+\ 'newt_textbox(': 'int left, int top, int width, int height [, int flags] | resource',
+\ 'newt_textbox_reflowed(': 'int left, int top, char *text, int width, int flex_down, int flex_up [, int flags] | resource',
+\ 'newt_textbox_set_height(': 'resource textbox, int height | void',
+\ 'newt_vertical_scrollbar(': 'int left, int top, int height [, int normal_colorset [, int thumb_colorset]] | resource',
+\ 'newt_wait_for_key(': 'void  | void',
+\ 'newt_win_choice(': 'string title, string button1_text, string button2_text, string format [, mixed args [, mixed ...]] | int',
+\ 'newt_win_entries(': 'string title, string text, int suggested_width, int flex_down, int flex_up, int data_width, array &#38;items, string button1 [, string ...] | int',
+\ 'newt_win_menu(': 'string title, string text, int suggestedWidth, int flexDown, int flexUp, int maxListHeight, array items, int &#38;listItem [, string button1 [, string ...]] | int',
+\ 'newt_win_message(': 'string title, string button_text, string format [, mixed args [, mixed ...]] | void',
+\ 'newt_win_messagev(': 'string title, string button_text, string format, array args | void',
+\ 'newt_win_ternary(': 'string title, string button1_text, string button2_text, string button3_text, string format [, mixed args [, mixed ...]] | int',
+\ 'next(': 'array &#38;array | mixed',
+\ 'ngettext(': 'string msgid1, string msgid2, int n | string',
+\ 'nl2br(': 'string string | string',
+\ 'nl_langinfo(': 'int item | string',
+\ 'notes_body(': 'string server, string mailbox, int msg_number | array',
+\ 'notes_copy_db(': 'string from_database_name, string to_database_name | bool',
+\ 'notes_create_db(': 'string database_name | bool',
+\ 'notes_create_note(': 'string database_name, string form_name | bool',
+\ 'notes_drop_db(': 'string database_name | bool',
+\ 'notes_find_note(': 'string database_name, string name [, string type] | int',
+\ 'notes_header_info(': 'string server, string mailbox, int msg_number | object',
+\ 'notes_list_msgs(': 'string db | bool',
+\ 'notes_mark_read(': 'string database_name, string user_name, string note_id | bool',
+\ 'notes_mark_unread(': 'string database_name, string user_name, string note_id | bool',
+\ 'notes_nav_create(': 'string database_name, string name | bool',
+\ 'notes_search(': 'string database_name, string keywords | array',
+\ 'notes_unread(': 'string database_name, string user_name | array',
+\ 'notes_version(': 'string database_name | float',
+\ 'nsapi_request_headers(': 'void  | array',
+\ 'nsapi_response_headers(': 'void  | array',
+\ 'nsapi_virtual(': 'string uri | bool',
+\ 'number_format(': 'float number [, int decimals [, string dec_point, string thousands_sep]] | string',
+\ 'ob_clean(': 'void  | void',
+\ 'ob_end_clean(': 'void  | bool',
+\ 'ob_end_flush(': 'void  | bool',
+\ 'ob_flush(': 'void  | void',
+\ 'ob_get_clean(': 'void  | string',
+\ 'ob_get_contents(': 'void  | string',
+\ 'ob_get_flush(': 'void  | string',
+\ 'ob_get_length(': 'void  | int',
+\ 'ob_get_level(': 'void  | int',
+\ 'ob_gzhandler(': 'string buffer, int mode | string',
+\ 'ob_iconv_handler(': 'string contents, int status | string',
+\ 'ob_implicit_flush(': '[int flag] | void',
+\ 'ob_list_handlers(': 'void  | array',
+\ 'ob_start(': '[callback output_callback [, int chunk_size [, bool erase]]] | bool',
+\ 'ob_tidyhandler(': 'string input [, int mode] | string',
+\ 'oci_bind_by_name(': 'resource stmt, string ph_name, mixed &#38;variable [, int maxlength [, int type]] | bool',
+\ 'oci_cancel(': 'resource stmt | bool',
+\ 'oci_close(': 'resource connection | bool',
+\ 'oci_commit(': 'resource connection | bool',
+\ 'oci_connect(': 'string username, string password [, string db [, string charset [, int session_mode]]] | resource',
+\ 'oci_define_by_name(': 'resource statement, string column_name, mixed &#38;variable [, int type] | bool',
+\ 'oci_error(': '[resource source] | array',
+\ 'oci_execute(': 'resource stmt [, int mode] | bool',
+\ 'oci_fetch_all(': 'resource statement, array &#38;output [, int skip [, int maxrows [, int flags]]] | int',
+\ 'oci_fetch_array(': 'resource statement [, int mode] | array',
+\ 'oci_fetch_assoc(': 'resource statement | array',
+\ 'oci_fetch(': 'resource statement | bool',
+\ 'ocifetchinto(': 'resource statement, array &#38;result [, int mode] | int',
+\ 'oci_fetch_object(': 'resource statement | object',
+\ 'oci_fetch_row(': 'resource statement | array',
+\ 'oci_field_is_null(': 'resource stmt, mixed field | bool',
+\ 'oci_field_name(': 'resource statement, int field | string',
+\ 'oci_field_precision(': 'resource statement, int field | int',
+\ 'oci_field_scale(': 'resource statement, int field | int',
+\ 'oci_field_size(': 'resource stmt, mixed field | int',
+\ 'oci_field_type(': 'resource stmt, int field | mixed',
+\ 'oci_field_type_raw(': 'resource statement, int field | int',
+\ 'oci_free_statement(': 'resource statement | bool',
+\ 'oci_internal_debug(': 'int onoff | void',
+\ 'oci_lob_copy(': 'OCI-Lob lob_to, OCI-Lob lob_from [, int length] | bool',
+\ 'oci_lob_is_equal(': 'OCI-Lob lob1, OCI-Lob lob2 | bool',
+\ 'oci_new_collection(': 'resource connection, string tdo [, string schema] | OCI-Collection',
+\ 'oci_new_connect(': 'string username, string password [, string db [, string charset [, int session_mode]]] | resource',
+\ 'oci_new_cursor(': 'resource connection | resource',
+\ 'oci_new_descriptor(': 'resource connection [, int type] | OCI-Lob',
+\ 'oci_num_fields(': 'resource statement | int',
+\ 'oci_num_rows(': 'resource stmt | int',
+\ 'oci_parse(': 'resource connection, string query | resource',
+\ 'oci_password_change(': 'resource connection, string username, string old_password, string new_password | bool',
+\ 'oci_pconnect(': 'string username, string password [, string db [, string charset [, int session_mode]]] | resource',
+\ 'oci_result(': 'resource statement, mixed field | mixed',
+\ 'oci_rollback(': 'resource connection | bool',
+\ 'oci_server_version(': 'resource connection | string',
+\ 'oci_set_prefetch(': 'resource statement [, int rows] | bool',
+\ 'oci_statement_type(': 'resource statement | string',
+\ 'octdec(': 'string octal_string | number',
+\ 'odbc_autocommit(': 'resource connection_id [, bool OnOff] | mixed',
+\ 'odbc_binmode(': 'resource result_id, int mode | bool',
+\ 'odbc_close_all(': 'void  | void',
+\ 'odbc_close(': 'resource connection_id | void',
+\ 'odbc_columnprivileges(': 'resource connection_id, string qualifier, string owner, string table_name, string column_name | resource',
+\ 'odbc_columns(': 'resource connection_id [, string qualifier [, string schema [, string table_name [, string column_name]]]] | resource',
+\ 'odbc_commit(': 'resource connection_id | bool',
+\ 'odbc_connect(': 'string dsn, string user, string password [, int cursor_type] | resource',
+\ 'odbc_cursor(': 'resource result_id | string',
+\ 'odbc_data_source(': 'resource connection_id, int fetch_type | array',
+\ 'odbc_do(': 'resource conn_id, string query | resource',
+\ 'odbc_error(': '[resource connection_id] | string',
+\ 'odbc_errormsg(': '[resource connection_id] | string',
+\ 'odbc_exec(': 'resource connection_id, string query_string [, int flags] | resource',
+\ 'odbc_execute(': 'resource result_id [, array parameters_array] | bool',
+\ 'odbc_fetch_array(': 'resource result [, int rownumber] | array',
+\ 'odbc_fetch_into(': 'resource result_id, array &#38;result_array [, int rownumber] | int',
+\ 'odbc_fetch_object(': 'resource result [, int rownumber] | object',
+\ 'odbc_fetch_row(': 'resource result_id [, int row_number] | bool',
+\ 'odbc_field_len(': 'resource result_id, int field_number | int',
+\ 'odbc_field_name(': 'resource result_id, int field_number | string',
+\ 'odbc_field_num(': 'resource result_id, string field_name | int',
+\ 'odbc_field_precision(': 'resource result_id, int field_number | int',
+\ 'odbc_field_scale(': 'resource result_id, int field_number | int',
+\ 'odbc_field_type(': 'resource result_id, int field_number | string',
+\ 'odbc_foreignkeys(': 'resource connection_id, string pk_qualifier, string pk_owner, string pk_table, string fk_qualifier, string fk_owner, string fk_table | resource',
+\ 'odbc_free_result(': 'resource result_id | bool',
+\ 'odbc_gettypeinfo(': 'resource connection_id [, int data_type] | resource',
+\ 'odbc_longreadlen(': 'resource result_id, int length | bool',
+\ 'odbc_next_result(': 'resource result_id | bool',
+\ 'odbc_num_fields(': 'resource result_id | int',
+\ 'odbc_num_rows(': 'resource result_id | int',
+\ 'odbc_pconnect(': 'string dsn, string user, string password [, int cursor_type] | resource',
+\ 'odbc_prepare(': 'resource connection_id, string query_string | resource',
+\ 'odbc_primarykeys(': 'resource connection_id, string qualifier, string owner, string table | resource',
+\ 'odbc_procedurecolumns(': 'resource connection_id [, string qualifier, string owner, string proc, string column] | resource',
+\ 'odbc_procedures(': 'resource connection_id [, string qualifier, string owner, string name] | resource',
+\ 'odbc_result_all(': 'resource result_id [, string format] | int',
+\ 'odbc_result(': 'resource result_id, mixed field | mixed',
+\ 'odbc_rollback(': 'resource connection_id | bool',
+\ 'odbc_setoption(': 'resource id, int function, int option, int param | bool',
+\ 'odbc_specialcolumns(': 'resource connection_id, int type, string qualifier, string owner, string table, int scope, int nullable | resource',
+\ 'odbc_statistics(': 'resource connection_id, string qualifier, string owner, string table_name, int unique, int accuracy | resource',
+\ 'odbc_tableprivileges(': 'resource connection_id, string qualifier, string owner, string name | resource',
+\ 'odbc_tables(': 'resource connection_id [, string qualifier [, string owner [, string name [, string types]]]] | resource',
+\ 'openal_buffer_create(': 'void  | resource',
+\ 'openal_buffer_data(': 'resource buffer, int format, string data, int freq | bool',
+\ 'openal_buffer_destroy(': 'resource buffer | bool',
+\ 'openal_buffer_get(': 'resource buffer, int property | int',
+\ 'openal_buffer_loadwav(': 'resource buffer, string wavfile | bool',
+\ 'openal_context_create(': 'resource device | resource',
+\ 'openal_context_current(': 'resource context | bool',
+\ 'openal_context_destroy(': 'resource context | bool',
+\ 'openal_context_process(': 'resource context | bool',
+\ 'openal_context_suspend(': 'resource context | bool',
+\ 'openal_device_close(': 'resource device | bool',
+\ 'openal_device_open(': '[string device_desc] | resource',
+\ 'openal_listener_get(': 'int property | mixed',
+\ 'openal_listener_set(': 'int property, mixed setting | bool',
+\ 'openal_source_create(': 'void  | resource',
+\ 'openal_source_destroy(': 'resource source | bool',
+\ 'openal_source_get(': 'resource source, int property | mixed',
+\ 'openal_source_pause(': 'resource source | bool',
+\ 'openal_source_play(': 'resource source | bool',
+\ 'openal_source_rewind(': 'resource source | bool',
+\ 'openal_source_set(': 'resource source, int property, mixed setting | bool',
+\ 'openal_source_stop(': 'resource source | bool',
+\ 'openal_stream(': 'resource source, int format, int rate | resource',
+\ 'opendir(': 'string path [, resource context] | resource',
+\ 'openlog(': 'string ident, int option, int facility | bool',
+\ 'openssl_csr_export(': 'resource csr, string &#38;out [, bool notext] | bool',
+\ 'openssl_csr_export_to_file(': 'resource csr, string outfilename [, bool notext] | bool',
+\ 'openssl_csr_new(': 'array dn, resource &#38;privkey [, array configargs [, array extraattribs]] | mixed',
+\ 'openssl_csr_sign(': 'mixed csr, mixed cacert, mixed priv_key, int days [, array configargs [, int serial]] | resource',
+\ 'openssl_error_string(': 'void  | string',
+\ 'openssl_free_key(': 'resource key_identifier | void',
+\ 'openssl_open(': 'string sealed_data, string &#38;open_data, string env_key, mixed priv_key_id | bool',
+\ 'openssl_pkcs7_decrypt(': 'string infilename, string outfilename, mixed recipcert [, mixed recipkey] | bool',
+\ 'openssl_pkcs7_encrypt(': 'string infile, string outfile, mixed recipcerts, array headers [, int flags [, int cipherid]] | bool',
+\ 'openssl_pkcs7_sign(': 'string infilename, string outfilename, mixed signcert, mixed privkey, array headers [, int flags [, string extracerts]] | bool',
+\ 'openssl_pkcs7_verify(': 'string filename, int flags [, string outfilename [, array cainfo [, string extracerts]]] | mixed',
+\ 'openssl_pkey_export(': 'mixed key, string &#38;out [, string passphrase [, array configargs]] | bool',
+\ 'openssl_pkey_export_to_file(': 'mixed key, string outfilename [, string passphrase [, array configargs]] | bool',
+\ 'openssl_pkey_free(': 'resource key | void',
+\ 'openssl_pkey_get_private(': 'mixed key [, string passphrase] | resource',
+\ 'openssl_pkey_get_public(': 'mixed certificate | resource',
+\ 'openssl_pkey_new(': '[array configargs] | resource',
+\ 'openssl_private_decrypt(': 'string data, string &#38;decrypted, mixed key [, int padding] | bool',
+\ 'openssl_private_encrypt(': 'string data, string &#38;crypted, mixed key [, int padding] | bool',
+\ 'openssl_public_decrypt(': 'string data, string &#38;decrypted, mixed key [, int padding] | bool',
+\ 'openssl_public_encrypt(': 'string data, string &#38;crypted, mixed key [, int padding] | bool',
+\ 'openssl_seal(': 'string data, string &#38;sealed_data, array &#38;env_keys, array pub_key_ids | int',
+\ 'openssl_sign(': 'string data, string &#38;signature, mixed priv_key_id [, int signature_alg] | bool',
+\ 'openssl_verify(': 'string data, string signature, mixed pub_key_id | int',
+\ 'openssl_x509_check_private_key(': 'mixed cert, mixed key | bool',
+\ 'openssl_x509_checkpurpose(': 'mixed x509cert, int purpose [, array cainfo [, string untrustedfile]] | int',
+\ 'openssl_x509_export(': 'mixed x509, string &#38;output [, bool notext] | bool',
+\ 'openssl_x509_export_to_file(': 'mixed x509, string outfilename [, bool notext] | bool',
+\ 'openssl_x509_free(': 'resource x509cert | void',
+\ 'openssl_x509_parse(': 'mixed x509cert [, bool shortnames] | array',
+\ 'openssl_x509_read(': 'mixed x509certdata | resource',
+\ 'ora_bind(': 'resource cursor, string PHP_variable_name, string SQL_parameter_name, int length [, int type] | bool',
+\ 'ora_close(': 'resource cursor | bool',
+\ 'ora_columnname(': 'resource cursor, int column | string',
+\ 'ora_columnsize(': 'resource cursor, int column | int',
+\ 'ora_columntype(': 'resource cursor, int column | string',
+\ 'ora_commit(': 'resource conn | bool',
+\ 'ora_commitoff(': 'resource conn | bool',
+\ 'ora_commiton(': 'resource conn | bool',
+\ 'ora_do(': 'resource conn, string query | resource',
+\ 'ora_errorcode(': '[resource cursor_or_connection] | int',
+\ 'ora_error(': '[resource cursor_or_connection] | string',
+\ 'ora_exec(': 'resource cursor | bool',
+\ 'ora_fetch(': 'resource cursor | bool',
+\ 'ora_fetch_into(': 'resource cursor, array &#38;result [, int flags] | int',
+\ 'ora_getcolumn(': 'resource cursor, int column | string',
+\ 'ora_logoff(': 'resource connection | bool',
+\ 'ora_logon(': 'string user, string password | resource',
+\ 'ora_numcols(': 'resource cursor | int',
+\ 'ora_numrows(': 'resource cursor | int',
+\ 'ora_open(': 'resource connection | resource',
+\ 'ora_parse(': 'resource cursor, string sql_statement [, int defer] | bool',
+\ 'ora_plogon(': 'string user, string password | resource',
+\ 'ora_rollback(': 'resource connection | bool',
+\ 'OrbitEnum(': 'string id | new',
+\ 'OrbitObject(': 'string ior | new',
+\ 'OrbitStruct(': 'string id | new',
+\ 'ord(': 'string string | int',
+\ 'output_add_rewrite_var(': 'string name, string value | bool',
+\ 'output_reset_rewrite_vars(': 'void  | bool',
+\ 'overload(': '[string class_name] | void',
+\ 'override_function(': 'string function_name, string function_args, string function_code | bool',
+\ 'ovrimos_close(': 'int connection | void',
+\ 'ovrimos_commit(': 'int connection_id | bool',
+\ 'ovrimos_connect(': 'string host, string db, string user, string password | int',
+\ 'ovrimos_cursor(': 'int result_id | string',
+\ 'ovrimos_exec(': 'int connection_id, string query | int',
+\ 'ovrimos_execute(': 'int result_id [, array parameters_array] | bool',
+\ 'ovrimos_fetch_into(': 'int result_id, array &#38;result_array [, string how [, int rownumber]] | bool',
+\ 'ovrimos_fetch_row(': 'int result_id [, int how [, int row_number]] | bool',
+\ 'ovrimos_field_len(': 'int result_id, int field_number | int',
+\ 'ovrimos_field_name(': 'int result_id, int field_number | string',
+\ 'ovrimos_field_num(': 'int result_id, string field_name | int',
+\ 'ovrimos_field_type(': 'int result_id, int field_number | int',
+\ 'ovrimos_free_result(': 'int result_id | bool',
+\ 'ovrimos_longreadlen(': 'int result_id, int length | bool',
+\ 'ovrimos_num_fields(': 'int result_id | int',
+\ 'ovrimos_num_rows(': 'int result_id | int',
+\ 'ovrimos_prepare(': 'int connection_id, string query | int',
+\ 'ovrimos_result_all(': 'int result_id [, string format] | int',
+\ 'ovrimos_result(': 'int result_id, mixed field | string',
+\ 'ovrimos_rollback(': 'int connection_id | bool',
+\ 'pack(': 'string format [, mixed args [, mixed ...]] | string',
+\ 'parse_ini_file(': 'string filename [, bool process_sections] | array',
+\ 'parsekit_compile_file(': 'string filename [, array &#38;errors [, int options]] | array',
+\ 'parsekit_compile_string(': 'string phpcode [, array &#38;errors [, int options]] | array',
+\ 'parsekit_func_arginfo(': 'mixed function | array',
+\ 'parse_str(': 'string str [, array &#38;arr] | void',
+\ 'parse_url(': 'string url | array',
+\ 'passthru(': 'string command [, int &#38;return_var] | void',
+\ 'pathinfo(': 'string path [, int options] | mixed',
+\ 'pclose(': 'resource handle | int',
+\ 'pcntl_alarm(': 'int seconds | int',
+\ 'pcntl_exec(': 'string path [, array args [, array envs]] | void',
+\ 'pcntl_fork(': 'void  | int',
+\ 'pcntl_getpriority(': '[int pid [, int process_identifier]] | int',
+\ 'pcntl_setpriority(': 'int priority [, int pid [, int process_identifier]] | bool',
+\ 'pcntl_signal(': 'int signo, callback handle [, bool restart_syscalls] | bool',
+\ 'pcntl_wait(': 'int &#38;status [, int options] | int',
+\ 'pcntl_waitpid(': 'int pid, int &#38;status [, int options] | int',
+\ 'pcntl_wexitstatus(': 'int status | int',
+\ 'pcntl_wifexited(': 'int status | bool',
+\ 'pcntl_wifsignaled(': 'int status | bool',
+\ 'pcntl_wifstopped(': 'int status | bool',
+\ 'pcntl_wstopsig(': 'int status | int',
+\ 'pcntl_wtermsig(': 'int status | int',
+\ 'pdf_activate_item(': 'resource pdfdoc, int id | bool',
+\ 'pdf_add_launchlink(': 'resource pdfdoc, float llx, float lly, float urx, float ury, string filename | bool',
+\ 'pdf_add_locallink(': 'resource pdfdoc, float lowerleftx, float lowerlefty, float upperrightx, float upperrighty, int page, string dest | bool',
+\ 'pdf_add_nameddest(': 'resource pdfdoc, string name, string optlist | bool',
+\ 'pdf_add_note(': 'resource pdfdoc, float llx, float lly, float urx, float ury, string contents, string title, string icon, int open | bool',
+\ 'pdf_add_pdflink(': 'resource pdfdoc, float bottom_left_x, float bottom_left_y, float up_right_x, float up_right_y, string filename, int page, string dest | bool',
+\ 'pdf_add_thumbnail(': 'resource pdfdoc, int image | bool',
+\ 'pdf_add_weblink(': 'resource pdfdoc, float lowerleftx, float lowerlefty, float upperrightx, float upperrighty, string url | bool',
+\ 'pdf_arc(': 'resource p, float x, float y, float r, float alpha, float beta | bool',
+\ 'pdf_arcn(': 'resource p, float x, float y, float r, float alpha, float beta | bool',
+\ 'pdf_attach_file(': 'resource pdfdoc, float llx, float lly, float urx, float ury, string filename, string description, string author, string mimetype, string icon | bool',
+\ 'pdf_begin_document(': 'resource pdfdoc, string filename, string optlist | int',
+\ 'pdf_begin_font(': 'resource pdfdoc, string filename, float a, float b, float c, float d, float e, float f, string optlist | bool',
+\ 'pdf_begin_glyph(': 'resource pdfdoc, string glyphname, float wx, float llx, float lly, float urx, float ury | bool',
+\ 'pdf_begin_item(': 'resource pdfdoc, string tag, string optlist | int',
+\ 'pdf_begin_layer(': 'resource pdfdoc, int layer | bool',
+\ 'pdf_begin_page_ext(': 'resource pdfdoc, float width, float height, string optlist | bool',
+\ 'pdf_begin_page(': 'resource pdfdoc, float width, float height | bool',
+\ 'pdf_begin_pattern(': 'resource pdfdoc, float width, float height, float xstep, float ystep, int painttype | int',
+\ 'pdf_begin_template(': 'resource pdfdoc, float width, float height | int',
+\ 'pdf_circle(': 'resource pdfdoc, float x, float y, float r | bool',
+\ 'pdf_clip(': 'resource p | bool',
+\ 'pdf_close(': 'resource p | bool',
+\ 'pdf_close_image(': 'resource p, int image | void',
+\ 'pdf_closepath_fill_stroke(': 'resource p | bool',
+\ 'pdf_closepath(': 'resource p | bool',
+\ 'pdf_closepath_stroke(': 'resource p | bool',
+\ 'pdf_close_pdi(': 'resource p, int doc | bool',
+\ 'pdf_close_pdi_page(': 'resource p, int page | bool',
+\ 'pdf_concat(': 'resource p, float a, float b, float c, float d, float e, float f | bool',
+\ 'pdf_continue_text(': 'resource p, string text | bool',
+\ 'pdf_create_action(': 'resource pdfdoc, string type, string optlist | int',
+\ 'pdf_create_annotation(': 'resource pdfdoc, float llx, float lly, float urx, float ury, string type, string optlist | bool',
+\ 'pdf_create_bookmark(': 'resource pdfdoc, string text, string optlist | int',
+\ 'pdf_create_fieldgroup(': 'resource pdfdoc, string name, string optlist | bool',
+\ 'pdf_create_field(': 'resource pdfdoc, float llx, float lly, float urx, float ury, string name, string type, string optlist | bool',
+\ 'pdf_create_gstate(': 'resource pdfdoc, string optlist | int',
+\ 'pdf_create_pvf(': 'resource pdfdoc, string filename, string data, string optlist | bool',
+\ 'pdf_create_textflow(': 'resource pdfdoc, string text, string optlist | int',
+\ 'pdf_curveto(': 'resource p, float x1, float y1, float x2, float y2, float x3, float y3 | bool',
+\ 'pdf_define_layer(': 'resource pdfdoc, string name, string optlist | int',
+\ 'pdf_delete(': 'resource pdfdoc | bool',
+\ 'pdf_delete_pvf(': 'resource pdfdoc, string filename | int',
+\ 'pdf_delete_textflow(': 'resource pdfdoc, int textflow | bool',
+\ 'pdf_encoding_set_char(': 'resource pdfdoc, string encoding, int slot, string glyphname, int uv | bool',
+\ 'pdf_end_document(': 'resource pdfdoc, string optlist | bool',
+\ 'pdf_end_font(': 'resource pdfdoc | bool',
+\ 'pdf_end_glyph(': 'resource pdfdoc | bool',
+\ 'pdf_end_item(': 'resource pdfdoc, int id | bool',
+\ 'pdf_end_layer(': 'resource pdfdoc | bool',
+\ 'pdf_end_page_ext(': 'resource pdfdoc, string optlist | bool',
+\ 'pdf_end_page(': 'resource p | bool',
+\ 'pdf_end_pattern(': 'resource p | bool',
+\ 'pdf_end_template(': 'resource p | bool',
+\ 'pdf_fill(': 'resource p | bool',
+\ 'pdf_fill_imageblock(': 'resource pdfdoc, int page, string blockname, int image, string optlist | int',
+\ 'pdf_fill_pdfblock(': 'resource pdfdoc, int page, string blockname, int contents, string optlist | int',
+\ 'pdf_fill_stroke(': 'resource p | bool',
+\ 'pdf_fill_textblock(': 'resource pdfdoc, int page, string blockname, string text, string optlist | int',
+\ 'pdf_findfont(': 'resource p, string fontname, string encoding, int embed | int',
+\ 'pdf_fit_image(': 'resource pdfdoc, int image, float x, float y, string optlist | bool',
+\ 'pdf_fit_pdi_page(': 'resource pdfdoc, int page, float x, float y, string optlist | bool',
+\ 'pdf_fit_textflow(': 'resource pdfdoc, int textflow, float llx, float lly, float urx, float ury, string optlist | string',
+\ 'pdf_fit_textline(': 'resource pdfdoc, string text, float x, float y, string optlist | bool',
+\ 'pdf_get_apiname(': 'resource pdfdoc | string',
+\ 'pdf_get_buffer(': 'resource p | string',
+\ 'pdf_get_errmsg(': 'resource pdfdoc | string',
+\ 'pdf_get_errnum(': 'resource pdfdoc | int',
+\ 'pdf_get_majorversion(': 'void  | int',
+\ 'pdf_get_minorversion(': 'void  | int',
+\ 'pdf_get_parameter(': 'resource p, string key, float modifier | string',
+\ 'pdf_get_pdi_parameter(': 'resource p, string key, int doc, int page, int reserved | string',
+\ 'pdf_get_pdi_value(': 'resource p, string key, int doc, int page, int reserved | float',
+\ 'pdf_get_value(': 'resource p, string key, float modifier | float',
+\ 'pdf_info_textflow(': 'resource pdfdoc, int textflow, string keyword | float',
+\ 'pdf_initgraphics(': 'resource p | bool',
+\ 'pdf_lineto(': 'resource p, float x, float y | bool',
+\ 'pdf_load_font(': 'resource pdfdoc, string fontname, string encoding, string optlist | int',
+\ 'pdf_load_iccprofile(': 'resource pdfdoc, string profilename, string optlist | int',
+\ 'pdf_load_image(': 'resource pdfdoc, string imagetype, string filename, string optlist | int',
+\ 'pdf_makespotcolor(': 'resource p, string spotname | int',
+\ 'pdf_moveto(': 'resource p, float x, float y | bool',
+\ 'pdf_new(': ' | resource',
+\ 'pdf_open_ccitt(': 'resource pdfdoc, string filename, int width, int height, int BitReverse, int k, int Blackls1 | int',
+\ 'pdf_open_file(': 'resource p, string filename | bool',
+\ 'pdf_open_image_file(': 'resource p, string imagetype, string filename, string stringparam, int intparam | int',
+\ 'pdf_open_image(': 'resource p, string imagetype, string source, string data, int length, int width, int height, int components, int bpc, string params | int',
+\ 'pdf_open_memory_image(': 'resource p, resource image | int',
+\ 'pdf_open_pdi(': 'resource pdfdoc, string filename, string optlist, int len | int',
+\ 'pdf_open_pdi_page(': 'resource p, int doc, int pagenumber, string optlist | int',
+\ 'pdf_place_image(': 'resource pdfdoc, int image, float x, float y, float scale | bool',
+\ 'pdf_place_pdi_page(': 'resource pdfdoc, int page, float x, float y, float sx, float sy | bool',
+\ 'pdf_process_pdi(': 'resource pdfdoc, int doc, int page, string optlist | int',
+\ 'pdf_rect(': 'resource p, float x, float y, float width, float height | bool',
+\ 'pdf_restore(': 'resource p | bool',
+\ 'pdf_resume_page(': 'resource pdfdoc, string optlist | bool',
+\ 'pdf_rotate(': 'resource p, float phi | bool',
+\ 'pdf_save(': 'resource p | bool',
+\ 'pdf_scale(': 'resource p, float sx, float sy | bool',
+\ 'pdf_set_border_color(': 'resource p, float red, float green, float blue | bool',
+\ 'pdf_set_border_dash(': 'resource pdfdoc, float black, float white | bool',
+\ 'pdf_set_border_style(': 'resource pdfdoc, string style, float width | bool',
+\ 'pdf_setcolor(': 'resource p, string fstype, string colorspace, float c1, float c2, float c3, float c4 | bool',
+\ 'pdf_setdash(': 'resource pdfdoc, float b, float w | bool',
+\ 'pdf_setdashpattern(': 'resource pdfdoc, string optlist | bool',
+\ 'pdf_setflat(': 'resource pdfdoc, float flatness | bool',
+\ 'pdf_setfont(': 'resource pdfdoc, int font, float fontsize | bool',
+\ 'pdf_setgray_fill(': 'resource p, float g | bool',
+\ 'pdf_setgray(': 'resource p, float g | bool',
+\ 'pdf_setgray_stroke(': 'resource p, float g | bool',
+\ 'pdf_set_gstate(': 'resource pdfdoc, int gstate | bool',
+\ 'pdf_set_info(': 'resource p, string key, string value | bool',
+\ 'pdf_set_layer_dependency(': 'resource pdfdoc, string type, string optlist | bool',
+\ 'pdf_setlinecap(': 'resource p, int linecap | bool',
+\ 'pdf_setlinejoin(': 'resource p, int value | bool',
+\ 'pdf_setlinewidth(': 'resource p, float width | bool',
+\ 'pdf_setmatrix(': 'resource p, float a, float b, float c, float d, float e, float f | bool',
+\ 'pdf_setmiterlimit(': 'resource pdfdoc, float miter | bool',
+\ 'pdf_set_parameter(': 'resource p, string key, string value | bool',
+\ 'pdf_setrgbcolor_fill(': 'resource p, float red, float green, float blue | bool',
+\ 'pdf_setrgbcolor(': 'resource p, float red, float green, float blue | bool',
+\ 'pdf_setrgbcolor_stroke(': 'resource p, float red, float green, float blue | bool',
+\ 'pdf_set_text_pos(': 'resource p, float x, float y | bool',
+\ 'pdf_set_value(': 'resource p, string key, float value | bool',
+\ 'pdf_shading(': 'resource pdfdoc, string shtype, float x0, float y0, float x1, float y1, float c1, float c2, float c3, float c4, string optlist | int',
+\ 'pdf_shading_pattern(': 'resource pdfdoc, int shading, string optlist | int',
+\ 'pdf_shfill(': 'resource pdfdoc, int shading | bool',
+\ 'pdf_show_boxed(': 'resource p, string text, float left, float top, float width, float height, string mode, string feature | int',
+\ 'pdf_show(': 'resource pdfdoc, string text | bool',
+\ 'pdf_show_xy(': 'resource p, string text, float x, float y | bool',
+\ 'pdf_skew(': 'resource p, float alpha, float beta | bool',
+\ 'pdf_stringwidth(': 'resource p, string text, int font, float fontsize | float',
+\ 'pdf_stroke(': 'resource p | bool',
+\ 'pdf_suspend_page(': 'resource pdfdoc, string optlist | bool',
+\ 'pdf_translate(': 'resource p, float tx, float ty | bool',
+\ 'pdf_utf16_to_utf8(': 'resource pdfdoc, string utf16string | string',
+\ 'pdf_utf8_to_utf16(': 'resource pdfdoc, string utf8string, string ordering | string',
+\ 'pdf_xshow(': 'resource pdfdoc, string text | bool',
+\ 'pfpro_cleanup(': 'void  | bool',
+\ 'pfpro_init(': 'void  | bool',
+\ 'pfpro_process(': 'array parameters [, string address [, int port [, int timeout [, string proxy_address [, int proxy_port [, string proxy_logon [, string proxy_password]]]]]]] | array',
+\ 'pfpro_process_raw(': 'string parameters [, string address [, int port [, int timeout [, string proxy_address [, int proxy_port [, string proxy_logon [, string proxy_password]]]]]]] | string',
+\ 'pfpro_version(': 'void  | string',
+\ 'pfsockopen(': 'string hostname [, int port [, int &#38;errno [, string &#38;errstr [, float timeout]]]] | resource',
+\ 'pg_affected_rows(': 'resource result | int',
+\ 'pg_cancel_query(': 'resource connection | bool',
+\ 'pg_client_encoding(': '[resource connection] | string',
+\ 'pg_close(': '[resource connection] | bool',
+\ 'pg_connect(': 'string connection_string [, int connect_type] | resource',
+\ 'pg_connection_busy(': 'resource connection | bool',
+\ 'pg_connection_reset(': 'resource connection | bool',
+\ 'pg_connection_status(': 'resource connection | int',
+\ 'pg_convert(': 'resource connection, string table_name, array assoc_array [, int options] | array',
+\ 'pg_copy_from(': 'resource connection, string table_name, array rows [, string delimiter [, string null_as]] | bool',
+\ 'pg_copy_to(': 'resource connection, string table_name [, string delimiter [, string null_as]] | array',
+\ 'pg_dbname(': '[resource connection] | string',
+\ 'pg_delete(': 'resource connection, string table_name, array assoc_array [, int options] | mixed',
+\ 'pg_end_copy(': '[resource connection] | bool',
+\ 'pg_escape_bytea(': 'string data | string',
+\ 'pg_escape_string(': 'string data | string',
+\ 'pg_execute(': 'resource connection, string stmtname, array params | resource',
+\ 'pg_fetch_all_columns(': 'resource result [, int column] | array',
+\ 'pg_fetch_all(': 'resource result | array',
+\ 'pg_fetch_array(': 'resource result [, int row [, int result_type]] | array',
+\ 'pg_fetch_assoc(': 'resource result [, int row] | array',
+\ 'pg_fetch_object(': 'resource result [, int row [, int result_type]] | object',
+\ 'pg_fetch_result(': 'resource result, int row, mixed field | string',
+\ 'pg_fetch_row(': 'resource result [, int row] | array',
+\ 'pg_field_is_null(': 'resource result, int row, mixed field | int',
+\ 'pg_field_name(': 'resource result, int field_number | string',
+\ 'pg_field_num(': 'resource result, string field_name | int',
+\ 'pg_field_prtlen(': 'resource result, int row_number, mixed field_name_or_number | int',
+\ 'pg_field_size(': 'resource result, int field_number | int',
+\ 'pg_field_type(': 'resource result, int field_number | string',
+\ 'pg_field_type_oid(': 'resource result, int field_number | int',
+\ 'pg_free_result(': 'resource result | bool',
+\ 'pg_get_notify(': 'resource connection [, int result_type] | array',
+\ 'pg_get_pid(': 'resource connection | int',
+\ 'pg_get_result(': '[resource connection] | resource',
+\ 'pg_host(': '[resource connection] | string',
+\ 'pg_insert(': 'resource connection, string table_name, array assoc_array [, int options] | mixed',
+\ 'pg_last_error(': '[resource connection] | string',
+\ 'pg_last_notice(': 'resource connection | string',
+\ 'pg_last_oid(': 'resource result | string',
+\ 'pg_lo_close(': 'resource large_object | bool',
+\ 'pg_lo_create(': '[resource connection] | int',
+\ 'pg_lo_export(': 'resource connection, int oid, string pathname | bool',
+\ 'pg_lo_import(': 'resource connection, string pathname | int',
+\ 'pg_lo_open(': 'resource connection, int oid, string mode | resource',
+\ 'pg_lo_read_all(': 'resource large_object | int',
+\ 'pg_lo_read(': 'resource large_object [, int len] | string',
+\ 'pg_lo_seek(': 'resource large_object, int offset [, int whence] | bool',
+\ 'pg_lo_tell(': 'resource large_object | int',
+\ 'pg_lo_unlink(': 'resource connection, int oid | bool',
+\ 'pg_lo_write(': 'resource large_object, string data [, int len] | int',
+\ 'pg_meta_data(': 'resource connection, string table_name | array',
+\ 'pg_num_fields(': 'resource result | int',
+\ 'pg_num_rows(': 'resource result | int',
+\ 'pg_options(': '[resource connection] | string',
+\ 'pg_parameter_status(': 'resource connection, string param_name | string',
+\ 'pg_pconnect(': 'string connection_string [, int connect_type] | resource',
+\ 'pg_ping(': '[resource connection] | bool',
+\ 'pg_port(': '[resource connection] | int',
+\ 'pg_prepare(': 'resource connection, string stmtname, string query | resource',
+\ 'pg_put_line(': 'string data | bool',
+\ 'pg_query(': 'string query | resource',
+\ 'pg_query_params(': 'resource connection, string query, array params | resource',
+\ 'pg_result_error_field(': 'resource result, int fieldcode | string',
+\ 'pg_result_error(': 'resource result | string',
+\ 'pg_result_seek(': 'resource result, int offset | bool',
+\ 'pg_result_status(': 'resource result [, int type] | mixed',
+\ 'pg_select(': 'resource connection, string table_name, array assoc_array [, int options] | mixed',
+\ 'pg_send_execute(': 'resource connection, string stmtname, array params | bool',
+\ 'pg_send_prepare(': 'resource connection, string stmtname, string query | bool',
+\ 'pg_send_query(': 'resource connection, string query | bool',
+\ 'pg_send_query_params(': 'resource connection, string query, array params | bool',
+\ 'pg_set_client_encoding(': 'string encoding | int',
+\ 'pg_set_error_verbosity(': 'resource connection, int verbosity | int',
+\ 'pg_trace(': 'string pathname [, string mode [, resource connection]] | bool',
+\ 'pg_transaction_status(': 'resource connection | int',
+\ 'pg_tty(': '[resource connection] | string',
+\ 'pg_unescape_bytea(': 'string data | string',
+\ 'pg_untrace(': '[resource connection] | bool',
+\ 'pg_update(': 'resource connection, string table_name, array data, array condition [, int options] | mixed',
+\ 'pg_version(': '[resource connection] | array',
+\ 'php_check_syntax(': 'string file_name [, string &#38;error_message] | bool',
+\ 'phpcredits(': '[int flag] | bool',
+\ 'phpinfo(': '[int what] | bool',
+\ 'php_ini_scanned_files(': 'void  | string',
+\ 'php_logo_guid(': 'void  | string',
+\ 'php_sapi_name(': 'void  | string',
+\ 'php_strip_whitespace(': 'string filename | string',
+\ 'php_uname(': '[string mode] | string',
+\ 'phpversion(': '[string extension] | string',
+\ 'pi(': 'void  | float',
+\ 'png2wbmp(': 'string pngname, string wbmpname, int d_height, int d_width, int threshold | int',
+\ 'popen(': 'string command, string mode | resource',
+\ 'posix_access(': 'string file [, int mode] | bool',
+\ 'posix_ctermid(': 'void  | string',
+\ 'posix_getcwd(': 'void  | string',
+\ 'posix_getegid(': 'void  | int',
+\ 'posix_geteuid(': 'void  | int',
+\ 'posix_getgid(': 'void  | int',
+\ 'posix_getgrgid(': 'int gid | array',
+\ 'posix_getgrnam(': 'string name | array',
+\ 'posix_getgroups(': 'void  | array',
+\ 'posix_get_last_error(': 'void  | int',
+\ 'posix_getlogin(': 'void  | string',
+\ 'posix_getpgid(': 'int pid | int',
+\ 'posix_getpgrp(': 'void  | int',
+\ 'posix_getpid(': 'void  | int',
+\ 'posix_getppid(': 'void  | int',
+\ 'posix_getpwnam(': 'string username | array',
+\ 'posix_getpwuid(': 'int uid | array',
+\ 'posix_getrlimit(': 'void  | array',
+\ 'posix_getsid(': 'int pid | int',
+\ 'posix_getuid(': 'void  | int',
+\ 'posix_isatty(': 'int fd | bool',
+\ 'posix_kill(': 'int pid, int sig | bool',
+\ 'posix_mkfifo(': 'string pathname, int mode | bool',
+\ 'posix_mknod(': 'string pathname, int mode [, int major [, int minor]] | bool',
+\ 'posix_setegid(': 'int gid | bool',
+\ 'posix_seteuid(': 'int uid | bool',
+\ 'posix_setgid(': 'int gid | bool',
+\ 'posix_setpgid(': 'int pid, int pgid | bool',
+\ 'posix_setsid(': 'void  | int',
+\ 'posix_setuid(': 'int uid | bool',
+\ 'posix_strerror(': 'int errno | string',
+\ 'posix_times(': 'void  | array',
+\ 'posix_ttyname(': 'int fd | string',
+\ 'posix_uname(': 'void  | array',
+\ 'pow(': 'number base, number exp | number',
+\ 'preg_grep(': 'string pattern, array input [, int flags] | array',
+\ 'preg_match_all(': 'string pattern, string subject, array &#38;matches [, int flags [, int offset]] | int',
+\ 'preg_match(': 'string pattern, string subject [, array &#38;matches [, int flags [, int offset]]] | int',
+\ 'preg_quote(': 'string str [, string delimiter] | string',
+\ 'preg_replace_callback(': 'mixed pattern, callback callback, mixed subject [, int limit [, int &#38;count]] | mixed',
+\ 'preg_replace(': 'mixed pattern, mixed replacement, mixed subject [, int limit [, int &#38;count]] | mixed',
+\ 'preg_split(': 'string pattern, string subject [, int limit [, int flags]] | array',
+\ 'prev(': 'array &#38;array | mixed',
+\ 'printer_abort(': 'resource handle | void',
+\ 'printer_close(': 'resource handle | void',
+\ 'printer_create_brush(': 'int style, string color | resource',
+\ 'printer_create_dc(': 'resource handle | void',
+\ 'printer_create_font(': 'string face, int height, int width, int font_weight, bool italic, bool underline, bool strikeout, int orientation | resource',
+\ 'printer_create_pen(': 'int style, int width, string color | resource',
+\ 'printer_delete_brush(': 'resource handle | void',
+\ 'printer_delete_dc(': 'resource handle | bool',
+\ 'printer_delete_font(': 'resource handle | void',
+\ 'printer_delete_pen(': 'resource handle | void',
+\ 'printer_draw_bmp(': 'resource handle, string filename, int x, int y [, int width, int height] | bool',
+\ 'printer_draw_chord(': 'resource handle, int rec_x, int rec_y, int rec_x1, int rec_y1, int rad_x, int rad_y, int rad_x1, int rad_y1 | void',
+\ 'printer_draw_elipse(': 'resource handle, int ul_x, int ul_y, int lr_x, int lr_y | void',
+\ 'printer_draw_line(': 'resource printer_handle, int from_x, int from_y, int to_x, int to_y | void',
+\ 'printer_draw_pie(': 'resource handle, int rec_x, int rec_y, int rec_x1, int rec_y1, int rad1_x, int rad1_y, int rad2_x, int rad2_y | void',
+\ 'printer_draw_rectangle(': 'resource handle, int ul_x, int ul_y, int lr_x, int lr_y | void',
+\ 'printer_draw_roundrect(': 'resource handle, int ul_x, int ul_y, int lr_x, int lr_y, int width, int height | void',
+\ 'printer_draw_text(': 'resource printer_handle, string text, int x, int y | void',
+\ 'printer_end_doc(': 'resource handle | bool',
+\ 'printer_end_page(': 'resource handle | bool',
+\ 'printer_get_option(': 'resource handle, string option | mixed',
+\ 'printer_list(': 'int enumtype [, string name [, int level]] | array',
+\ 'printer_logical_fontheight(': 'resource handle, int height | int',
+\ 'printer_open(': '[string devicename] | resource',
+\ 'printer_select_brush(': 'resource printer_handle, resource brush_handle | void',
+\ 'printer_select_font(': 'resource printer_handle, resource font_handle | void',
+\ 'printer_select_pen(': 'resource printer_handle, resource pen_handle | void',
+\ 'printer_set_option(': 'resource handle, int option, mixed value | bool',
+\ 'printer_start_doc(': 'resource handle [, string document] | bool',
+\ 'printer_start_page(': 'resource handle | bool',
+\ 'printer_write(': 'resource handle, string content | bool',
+\ 'printf(': 'string format [, mixed args [, mixed ...]] | int',
+\ 'print(': 'string arg | int',
+\ 'print_r(': 'mixed expression [, bool return] | bool',
+\ 'proc_close(': 'resource process | int',
+\ 'proc_get_status(': 'resource process | array',
+\ 'proc_nice(': 'int increment | bool',
+\ 'proc_open(': 'string cmd, array descriptorspec, array &#38;pipes [, string cwd [, array env [, array other_options]]] | resource',
+\ 'proc_terminate(': 'resource process [, int signal] | int',
+\ 'property_exists(': 'mixed class, string property | bool',
+\ 'ps_add_bookmark(': 'resource psdoc, string text [, int parent [, int open]] | int',
+\ 'ps_add_launchlink(': 'resource psdoc, float llx, float lly, float urx, float ury, string filename | bool',
+\ 'ps_add_locallink(': 'resource psdoc, float llx, float lly, float urx, float ury, int page, string dest | bool',
+\ 'ps_add_note(': 'resource psdoc, float llx, float lly, float urx, float ury, string contents, string title, string icon, int open | bool',
+\ 'ps_add_pdflink(': 'resource psdoc, float llx, float lly, float urx, float ury, string filename, int page, string dest | bool',
+\ 'ps_add_weblink(': 'resource psdoc, float llx, float lly, float urx, float ury, string url | bool',
+\ 'ps_arc(': 'resource psdoc, float x, float y, float radius, float alpha, float beta | bool',
+\ 'ps_arcn(': 'resource psdoc, float x, float y, float radius, float alpha, float beta | bool',
+\ 'ps_begin_page(': 'resource psdoc, float width, float height | bool',
+\ 'ps_begin_pattern(': 'resource psdoc, float width, float height, float xstep, float ystep, int painttype | bool',
+\ 'ps_begin_template(': 'resource psdoc, float width, float height | bool',
+\ 'ps_circle(': 'resource psdoc, float x, float y, float radius | bool',
+\ 'ps_clip(': 'resource psdoc | bool',
+\ 'ps_close(': 'resource psdoc | bool',
+\ 'ps_close_image(': 'resource psdoc, int imageid | void',
+\ 'ps_closepath(': 'resource psdoc | bool',
+\ 'ps_closepath_stroke(': 'resource psdoc | bool',
+\ 'ps_continue_text(': 'resource psdoc, string text | bool',
+\ 'ps_curveto(': 'resource psdoc, float x1, float y1, float x2, float y2, float x3, float y3 | bool',
+\ 'ps_delete(': 'resource psdoc | bool',
+\ 'ps_end_page(': 'resource psdoc | bool',
+\ 'ps_end_pattern(': 'resource psdoc | bool',
+\ 'ps_end_template(': 'resource psdoc | bool',
+\ 'ps_fill(': 'resource psdoc | bool',
+\ 'ps_fill_stroke(': 'resource psdoc | bool',
+\ 'ps_findfont(': 'resource psdoc, string fontname, string encoding [, bool embed] | int',
+\ 'ps_get_buffer(': 'resource psdoc | string',
+\ 'ps_get_parameter(': 'resource psdoc, string name [, float modifier] | string',
+\ 'ps_get_value(': 'resource psdoc, string name [, float modifier] | float',
+\ 'ps_hyphenate(': 'resource psdoc, string text | array',
+\ 'ps_lineto(': 'resource psdoc, float x, float y | bool',
+\ 'ps_makespotcolor(': 'resource psdoc, string name [, float reserved] | int',
+\ 'ps_moveto(': 'resource psdoc, float x, float y | bool',
+\ 'ps_new(': 'void  | resource',
+\ 'ps_open_file(': 'resource psdoc [, string filename] | bool',
+\ 'ps_open_image_file(': 'resource psdoc, string type, string filename [, string stringparam [, int intparam]] | int',
+\ 'ps_open_image(': 'resource psdoc, string type, string source, string data, int lenght, int width, int height, int components, int bpc, string params | int',
+\ 'pspell_add_to_personal(': 'int dictionary_link, string word | bool',
+\ 'pspell_add_to_session(': 'int dictionary_link, string word | bool',
+\ 'pspell_check(': 'int dictionary_link, string word | bool',
+\ 'pspell_clear_session(': 'int dictionary_link | bool',
+\ 'pspell_config_create(': 'string language [, string spelling [, string jargon [, string encoding]]] | int',
+\ 'pspell_config_data_dir(': 'int conf, string directory | bool',
+\ 'pspell_config_dict_dir(': 'int conf, string directory | bool',
+\ 'pspell_config_ignore(': 'int dictionary_link, int n | bool',
+\ 'pspell_config_mode(': 'int dictionary_link, int mode | bool',
+\ 'pspell_config_personal(': 'int dictionary_link, string file | bool',
+\ 'pspell_config_repl(': 'int dictionary_link, string file | bool',
+\ 'pspell_config_runtogether(': 'int dictionary_link, bool flag | bool',
+\ 'pspell_config_save_repl(': 'int dictionary_link, bool flag | bool',
+\ 'pspell_new_config(': 'int config | int',
+\ 'pspell_new(': 'string language [, string spelling [, string jargon [, string encoding [, int mode]]]] | int',
+\ 'pspell_new_personal(': 'string personal, string language [, string spelling [, string jargon [, string encoding [, int mode]]]] | int',
+\ 'pspell_save_wordlist(': 'int dictionary_link | bool',
+\ 'pspell_store_replacement(': 'int dictionary_link, string misspelled, string correct | bool',
+\ 'pspell_suggest(': 'int dictionary_link, string word | array',
+\ 'ps_place_image(': 'resource psdoc, int imageid, float x, float y, float scale | bool',
+\ 'ps_rect(': 'resource psdoc, float x, float y, float width, float height | bool',
+\ 'ps_restore(': 'resource psdoc | bool',
+\ 'ps_rotate(': 'resource psdoc, float rot | bool',
+\ 'ps_save(': 'resource psdoc | bool',
+\ 'ps_scale(': 'resource psdoc, float x, float y | bool',
+\ 'ps_set_border_color(': 'resource psdoc, float red, float green, float blue | bool',
+\ 'ps_set_border_dash(': 'resource psdoc, float black, float white | bool',
+\ 'ps_set_border_style(': 'resource psdoc, string style, float width | bool',
+\ 'ps_setcolor(': 'resource psdoc, string type, string colorspace, float c1, float c2, float c3, float c4 | bool',
+\ 'ps_setdash(': 'resource psdoc, float on, float off | bool',
+\ 'ps_setflat(': 'resource psdoc, float value | bool',
+\ 'ps_setfont(': 'resource psdoc, int fontid, float size | bool',
+\ 'ps_setgray(': 'resource psdoc, float gray | bool',
+\ 'ps_set_info(': 'resource p, string key, string val | bool',
+\ 'ps_setlinecap(': 'resource psdoc, int type | bool',
+\ 'ps_setlinejoin(': 'resource psdoc, int type | bool',
+\ 'ps_setlinewidth(': 'resource psdoc, float width | bool',
+\ 'ps_setmiterlimit(': 'resource psdoc, float value | bool',
+\ 'ps_set_parameter(': 'resource psdoc, string name, string value | bool',
+\ 'ps_setpolydash(': 'resource psdoc, float arr | bool',
+\ 'ps_set_text_pos(': 'resource psdoc, float x, float y | bool',
+\ 'ps_set_value(': 'resource psdoc, string name, float value | bool',
+\ 'ps_shading(': 'resource psdoc, string type, float x0, float y0, float x1, float y1, float c1, float c2, float c3, float c4, string optlist | int',
+\ 'ps_shading_pattern(': 'resource psdoc, int shadingid, string optlist | int',
+\ 'ps_shfill(': 'resource psdoc, int shadingid | bool',
+\ 'ps_show_boxed(': 'resource psdoc, string text, float left, float bottom, float width, float height, string hmode [, string feature] | int',
+\ 'ps_show(': 'resource psdoc, string text | bool',
+\ 'ps_show_xy(': 'resource psdoc, string text, float x, float y | bool',
+\ 'ps_string_geometry(': 'resource psdoc, string text [, int fontid [, float size]] | array',
+\ 'ps_stringwidth(': 'resource psdoc, string text [, int fontid [, float size]] | float',
+\ 'ps_stroke(': 'resource psdoc | bool',
+\ 'ps_symbol(': 'resource psdoc, int ord | bool',
+\ 'ps_symbol_name(': 'resource psdoc, int ord [, int fontid] | string',
+\ 'ps_symbol_width(': 'resource psdoc, int ord [, int fontid [, float size]] | float',
+\ 'ps_translate(': 'resource psdoc, float x, float y | bool',
+\ 'putenv(': 'string setting | bool',
+\ 'px_close(': 'resource pxdoc | bool',
+\ 'px_create_fp(': 'resource pxdoc, resource file, array fielddesc | bool',
+\ 'px_date2string(': 'resource pxdoc, int value, string format | string',
+\ 'px_delete(': 'resource pxdoc | bool',
+\ 'px_delete_record(': 'resource pxdoc, int num | bool',
+\ 'px_get_field(': 'resource pxdoc, int fieldno | array',
+\ 'px_get_info(': 'resource pxdoc | array',
+\ 'px_get_parameter(': 'resource pxdoc, string name | string',
+\ 'px_get_record(': 'resource pxdoc, int num [, int mode] | array',
+\ 'px_get_schema(': 'resource pxdoc [, int mode] | array',
+\ 'px_get_value(': 'resource pxdoc, string name | float',
+\ 'px_insert_record(': 'resource pxdoc, array data | int',
+\ 'px_new(': 'void  | resource',
+\ 'px_numfields(': 'resource pxdoc | int',
+\ 'px_numrecords(': 'resource pxdoc | int',
+\ 'px_open_fp(': 'resource pxdoc, resource file | bool',
+\ 'px_put_record(': 'resource pxdoc, array record [, int recpos] | bool',
+\ 'px_retrieve_record(': 'resource pxdoc, int num [, int mode] | array',
+\ 'px_set_blob_file(': 'resource pxdoc, string filename | bool',
+\ 'px_set_parameter(': 'resource pxdoc, string name, string value | bool',
+\ 'px_set_tablename(': 'resource pxdoc, string name | void',
+\ 'px_set_targetencoding(': 'resource pxdoc, string encoding | bool',
+\ 'px_set_value(': 'resource pxdoc, string name, float value | bool',
+\ 'px_timestamp2string(': 'resource pxdoc, float value, string format | string',
+\ 'px_update_record(': 'resource pxdoc, array data, int num | bool',
+\ 'qdom_error(': 'void  | string',
+\ 'qdom_tree(': 'string doc | QDomDocument',
+\ 'quoted_printable_decode(': 'string str | string',
+\ 'quotemeta(': 'string str | string',
+\ 'rad2deg(': 'float number | float',
+\ 'radius_acct_open(': 'void  | resource',
+\ 'radius_add_server(': 'resource radius_handle, string hostname, int port, string secret, int timeout, int max_tries | bool',
+\ 'radius_auth_open(': 'void  | resource',
+\ 'radius_close(': 'resource radius_handle | bool',
+\ 'radius_config(': 'resource radius_handle, string file | bool',
+\ 'radius_create_request(': 'resource radius_handle, int type | bool',
+\ 'radius_cvt_addr(': 'string data | string',
+\ 'radius_cvt_int(': 'string data | int',
+\ 'radius_cvt_string(': 'string data | string',
+\ 'radius_demangle(': 'resource radius_handle, string mangled | string',
+\ 'radius_demangle_mppe_key(': 'resource radius_handle, string mangled | string',
+\ 'radius_get_attr(': 'resource radius_handle | mixed',
+\ 'radius_get_vendor_attr(': 'string data | array',
+\ 'radius_put_addr(': 'resource radius_handle, int type, string addr | bool',
+\ 'radius_put_attr(': 'resource radius_handle, int type, string value | bool',
+\ 'radius_put_int(': 'resource radius_handle, int type, int value | bool',
+\ 'radius_put_string(': 'resource radius_handle, int type, string value | bool',
+\ 'radius_put_vendor_addr(': 'resource radius_handle, int vendor, int type, string addr | bool',
+\ 'radius_put_vendor_attr(': 'resource radius_handle, int vendor, int type, string value | bool',
+\ 'radius_put_vendor_int(': 'resource radius_handle, int vendor, int type, int value | bool',
+\ 'radius_put_vendor_string(': 'resource radius_handle, int vendor, int type, string value | bool',
+\ 'radius_request_authenticator(': 'resource radius_handle | string',
+\ 'radius_send_request(': 'resource radius_handle | int',
+\ 'radius_server_secret(': 'resource radius_handle | string',
+\ 'radius_strerror(': 'resource radius_handle | string',
+\ 'rand(': '[int min, int max] | int',
+\ 'range(': 'mixed low, mixed high [, number step] | array',
+\ 'rar_close(': 'resource rar_file | bool',
+\ 'rar_entry_get(': 'resource rar_file, string entry_name | RarEntry',
+\ 'rar_list(': 'resource rar_file | array',
+\ 'rar_open(': 'string filename [, string password] | resource',
+\ 'rawurldecode(': 'string str | string',
+\ 'rawurlencode(': 'string str | string',
+\ 'readdir(': 'resource dir_handle | string',
+\ 'readfile(': 'string filename [, bool use_include_path [, resource context]] | int',
+\ 'readgzfile(': 'string filename [, int use_include_path] | int',
+\ 'readline_add_history(': 'string line | bool',
+\ 'readline_callback_handler_install(': 'string prompt, callback callback | bool',
+\ 'readline_callback_handler_remove(': 'void  | bool',
+\ 'readline_callback_read_char(': 'void  | void',
+\ 'readline_clear_history(': 'void  | bool',
+\ 'readline_completion_function(': 'callback function | bool',
+\ 'readline(': 'string prompt | string',
+\ 'readline_info(': '[string varname [, string newvalue]] | mixed',
+\ 'readline_list_history(': 'void  | array',
+\ 'readline_on_new_line(': 'void  | void',
+\ 'readline_read_history(': '[string filename] | bool',
+\ 'readline_redisplay(': 'void  | void',
+\ 'readline_write_history(': '[string filename] | bool',
+\ 'readlink(': 'string path | string',
+\ 'realpath(': 'string path | string',
+\ 'recode_file(': 'string request, resource input, resource output | bool',
+\ 'recode_string(': 'string request, string string | string',
+\ 'register_shutdown_function(': 'callback function [, mixed parameter [, mixed ...]] | void',
+\ 'register_tick_function(': 'callback function [, mixed arg [, mixed ...]] | bool',
+\ 'rename_function(': 'string original_name, string new_name | bool',
+\ 'rename(': 'string oldname, string newname [, resource context] | bool',
+\ 'reset(': 'array &#38;array | mixed',
+\ 'restore_error_handler(': 'void  | bool',
+\ 'restore_exception_handler(': 'void  | bool',
+\ 'restore_include_path(': 'void  | void',
+\ 'rewinddir(': 'resource dir_handle | void',
+\ 'rewind(': 'resource handle | bool',
+\ 'rmdir(': 'string dirname [, resource context] | bool',
+\ 'round(': 'float val [, int precision] | float',
+\ 'rpm_close(': 'resource rpmr | boolean',
+\ 'rpm_get_tag(': 'resource rpmr, int tagnum | mixed',
+\ 'rpm_is_valid(': 'string filename | boolean',
+\ 'rpm_open(': 'string filename | resource',
+\ 'rpm_version(': 'void  | string',
+\ 'rsort(': 'array &#38;array [, int sort_flags] | bool',
+\ 'rtrim(': 'string str [, string charlist] | string',
+\ 'runkit_class_adopt(': 'string classname, string parentname | bool',
+\ 'runkit_class_emancipate(': 'string classname | bool',
+\ 'runkit_constant_add(': 'string constname, mixed value | bool',
+\ 'runkit_constant_redefine(': 'string constname, mixed newvalue | bool',
+\ 'runkit_constant_remove(': 'string constname | bool',
+\ 'runkit_function_add(': 'string funcname, string arglist, string code | bool',
+\ 'runkit_function_copy(': 'string funcname, string targetname | bool',
+\ 'runkit_function_redefine(': 'string funcname, string arglist, string code | bool',
+\ 'runkit_function_remove(': 'string funcname | bool',
+\ 'runkit_function_rename(': 'string funcname, string newname | bool',
+\ 'runkit_import(': 'string filename [, int flags] | bool',
+\ 'runkit_lint_file(': 'string filename | bool',
+\ 'runkit_lint(': 'string code | bool',
+\ 'runkit_method_add(': 'string classname, string methodname, string args, string code [, int flags] | bool',
+\ 'runkit_method_copy(': 'string dClass, string dMethod, string sClass [, string sMethod] | bool',
+\ 'runkit_method_redefine(': 'string classname, string methodname, string args, string code [, int flags] | bool',
+\ 'runkit_method_remove(': 'string classname, string methodname | bool',
+\ 'runkit_method_rename(': 'string classname, string methodname, string newname | bool',
+\ 'runkit_return_value_used(': 'void  | bool',
+\ 'runkit_sandbox_output_handler(': 'object sandbox [, mixed callback] | mixed',
+\ 'runkit_superglobals(': 'void  | array',
+\ 'satellite_caught_exception(': 'void  | bool',
+\ 'satellite_exception_id(': 'void  | string',
+\ 'satellite_exception_value(': 'void  | OrbitStruct',
+\ 'satellite_get_repository_id(': 'object obj | int',
+\ 'satellite_load_idl(': 'string file | bool',
+\ 'satellite_object_to_string(': 'object obj | string',
+\ 'scandir(': 'string directory [, int sorting_order [, resource context]] | array',
+\ 'sem_acquire(': 'resource sem_identifier | bool',
+\ 'sem_get(': 'int key [, int max_acquire [, int perm [, int auto_release]]] | resource',
+\ 'sem_release(': 'resource sem_identifier | bool',
+\ 'sem_remove(': 'resource sem_identifier | bool',
+\ 'serialize(': 'mixed value | string',
+\ 'sesam_affected_rows(': 'string result_id | int',
+\ 'sesam_commit(': 'void  | bool',
+\ 'sesam_connect(': 'string catalog, string schema, string user | bool',
+\ 'sesam_diagnostic(': 'void  | array',
+\ 'sesam_disconnect(': 'void  | bool',
+\ 'sesam_errormsg(': 'void  | string',
+\ 'sesam_execimm(': 'string query | string',
+\ 'sesam_fetch_array(': 'string result_id [, int whence [, int offset]] | array',
+\ 'sesam_fetch_result(': 'string result_id [, int max_rows] | mixed',
+\ 'sesam_fetch_row(': 'string result_id [, int whence [, int offset]] | array',
+\ 'sesam_field_array(': 'string result_id | array',
+\ 'sesam_field_name(': 'string result_id, int index | int',
+\ 'sesam_free_result(': 'string result_id | int',
+\ 'sesam_num_fields(': 'string result_id | int',
+\ 'sesam_query(': 'string query [, bool scrollable] | string',
+\ 'sesam_rollback(': 'void  | bool',
+\ 'sesam_seek_row(': 'string result_id, int whence [, int offset] | bool',
+\ 'sesam_settransaction(': 'int isolation_level, int read_only | bool',
+\ 'session_cache_expire(': '[int new_cache_expire] | int',
+\ 'session_cache_limiter(': '[string cache_limiter] | string',
+\ 'session_decode(': 'string data | bool',
+\ 'session_destroy(': 'void  | bool',
+\ 'session_encode(': 'void  | string',
+\ 'session_get_cookie_params(': 'void  | array',
+\ 'session_id(': '[string id] | string',
+\ 'session_is_registered(': 'string name | bool',
+\ 'session_module_name(': '[string module] | string',
+\ 'session_name(': '[string name] | string',
+\ 'session_pgsql_add_error(': 'int error_level [, string error_message] | bool',
+\ 'session_pgsql_get_error(': '[bool with_error_message] | array',
+\ 'session_pgsql_get_field(': 'void  | string',
+\ 'session_pgsql_reset(': 'void  | bool',
+\ 'session_pgsql_set_field(': 'string value | bool',
+\ 'session_pgsql_status(': 'void  | array',
+\ 'session_regenerate_id(': '[bool delete_old_session] | bool',
+\ 'session_register(': 'mixed name [, mixed ...] | bool',
+\ 'session_save_path(': '[string path] | string',
+\ 'session_set_cookie_params(': 'int lifetime [, string path [, string domain [, bool secure]]] | void',
+\ 'session_set_save_handler(': 'callback open, callback close, callback read, callback write, callback destroy, callback gc | bool',
+\ 'session_start(': 'void  | bool',
+\ 'session_unregister(': 'string name | bool',
+\ 'session_unset(': 'void  | void',
+\ 'session_write_close(': 'void  | void',
+\ 'setcookie(': 'string name [, string value [, int expire [, string path [, string domain [, bool secure]]]]] | bool',
+\ 'set_error_handler(': 'callback error_handler [, int error_types] | mixed',
+\ 'set_exception_handler(': 'callback exception_handler | string',
+\ 'set_include_path(': 'string new_include_path | string',
+\ 'setlocale(': 'int category, string locale [, string ...] | string',
+\ 'set_magic_quotes_runtime(': 'int new_setting | bool',
+\ 'setrawcookie(': 'string name [, string value [, int expire [, string path [, string domain [, bool secure]]]]] | bool',
+\ 'set_time_limit(': 'int seconds | void',
+\ 'settype(': 'mixed &#38;var, string type | bool',
+\ 'sha1_file(': 'string filename [, bool raw_output] | string',
+\ 'sha1(': 'string str [, bool raw_output] | string',
+\ 'shell_exec(': 'string cmd | string',
+\ 'shm_attach(': 'int key [, int memsize [, int perm]] | int',
+\ 'shm_detach(': 'int shm_identifier | bool',
+\ 'shm_get_var(': 'int shm_identifier, int variable_key | mixed',
+\ 'shmop_close(': 'int shmid | void',
+\ 'shmop_delete(': 'int shmid | bool',
+\ 'shmop_open(': 'int key, string flags, int mode, int size | int',
+\ 'shmop_read(': 'int shmid, int start, int count | string',
+\ 'shmop_size(': 'int shmid | int',
+\ 'shmop_write(': 'int shmid, string data, int offset | int',
+\ 'shm_put_var(': 'int shm_identifier, int variable_key, mixed variable | bool',
+\ 'shm_remove(': 'int shm_identifier | bool',
+\ 'shm_remove_var(': 'int shm_identifier, int variable_key | bool',
+\ 'shuffle(': 'array &#38;array | bool',
+\ 'similar_text(': 'string first, string second [, float &#38;percent] | int',
+\ 'SimpleXMLElement-&#62;asXML(': '[string filename] | mixed',
+\ 'simplexml_element-&#62;attributes(': '[string data] | SimpleXMLElement',
+\ 'simplexml_element-&#62;children(': '[string nsprefix] | SimpleXMLElement',
+\ 'SimpleXMLElement-&#62;xpath(': 'string path | array',
+\ 'simplexml_import_dom(': 'DOMNode node [, string class_name] | SimpleXMLElement',
+\ 'simplexml_load_file(': 'string filename [, string class_name [, int options]] | object',
+\ 'simplexml_load_string(': 'string data [, string class_name [, int options]] | object',
+\ 'sinh(': 'float arg | float',
+\ 'sin(': 'float arg | float',
+\ 'sleep(': 'int seconds | int',
+\ 'snmpget(': 'string hostname, string community, string object_id [, int timeout [, int retries]] | string',
+\ 'snmpgetnext(': 'string host, string community, string object_id [, int timeout [, int retries]] | string',
+\ 'snmp_get_quick_print(': 'void  | bool',
+\ 'snmp_get_valueretrieval(': 'void  | int',
+\ 'snmp_read_mib(': 'string filename | bool',
+\ 'snmprealwalk(': 'string host, string community, string object_id [, int timeout [, int retries]] | array',
+\ 'snmp_set_enum_print(': 'int enum_print | void',
+\ 'snmpset(': 'string hostname, string community, string object_id, string type, mixed value [, int timeout [, int retries]] | bool',
+\ 'snmp_set_oid_numeric_print(': 'int oid_numeric_print | void',
+\ 'snmp_set_quick_print(': 'bool quick_print | void',
+\ 'snmp_set_valueretrieval(': 'int method | void',
+\ 'snmpwalk(': 'string hostname, string community, string object_id [, int timeout [, int retries]] | array',
+\ 'snmpwalkoid(': 'string hostname, string community, string object_id [, int timeout [, int retries]] | array',
+\ 'socket_accept(': 'resource socket | resource',
+\ 'socket_bind(': 'resource socket, string address [, int port] | bool',
+\ 'socket_clear_error(': '[resource socket] | void',
+\ 'socket_close(': 'resource socket | void',
+\ 'socket_connect(': 'resource socket, string address [, int port] | bool',
+\ 'socket_create(': 'int domain, int type, int protocol | resource',
+\ 'socket_create_listen(': 'int port [, int backlog] | resource',
+\ 'socket_create_pair(': 'int domain, int type, int protocol, array &#38;fd | bool',
+\ 'socket_get_option(': 'resource socket, int level, int optname | mixed',
+\ 'socket_getpeername(': 'resource socket, string &#38;addr [, int &#38;port] | bool',
+\ 'socket_getsockname(': 'resource socket, string &#38;addr [, int &#38;port] | bool',
+\ 'socket_last_error(': '[resource socket] | int',
+\ 'socket_listen(': 'resource socket [, int backlog] | bool',
+\ 'socket_read(': 'resource socket, int length [, int type] | string',
+\ 'socket_recvfrom(': 'resource socket, string &#38;buf, int len, int flags, string &#38;name [, int &#38;port] | int',
+\ 'socket_recv(': 'resource socket, string &#38;buf, int len, int flags | int',
+\ 'socket_select(': 'array &#38;read, array &#38;write, array &#38;except, int tv_sec [, int tv_usec] | int',
+\ 'socket_send(': 'resource socket, string buf, int len, int flags | int',
+\ 'socket_sendto(': 'resource socket, string buf, int len, int flags, string addr [, int port] | int',
+\ 'socket_set_block(': 'resource socket | bool',
+\ 'socket_set_nonblock(': 'resource socket | bool',
+\ 'socket_set_option(': 'resource socket, int level, int optname, mixed optval | bool',
+\ 'socket_shutdown(': 'resource socket [, int how] | bool',
+\ 'socket_strerror(': 'int errno | string',
+\ 'socket_write(': 'resource socket, string buffer [, int length] | int',
+\ 'sort(': 'array &#38;array [, int sort_flags] | bool',
+\ 'soundex(': 'string str | string',
+\ 'spl_classes(': 'void  | array',
+\ 'split(': 'string pattern, string string [, int limit] | array',
+\ 'spliti(': 'string pattern, string string [, int limit] | array',
+\ 'sprintf(': 'string format [, mixed args [, mixed ...]] | string',
+\ 'sqlite_array_query(': 'resource dbhandle, string query [, int result_type [, bool decode_binary]] | array',
+\ 'sqlite_busy_timeout(': 'resource dbhandle, int milliseconds | void',
+\ 'sqlite_changes(': 'resource dbhandle | int',
+\ 'sqlite_close(': 'resource dbhandle | void',
+\ 'sqlite_column(': 'resource result, mixed index_or_name [, bool decode_binary] | mixed',
+\ 'sqlite_create_aggregate(': 'resource dbhandle, string function_name, callback step_func, callback finalize_func [, int num_args] | void',
+\ 'sqlite_create_function(': 'resource dbhandle, string function_name, callback callback [, int num_args] | void',
+\ 'sqlite_current(': 'resource result [, int result_type [, bool decode_binary]] | array',
+\ 'sqlite_error_string(': 'int error_code | string',
+\ 'sqlite_escape_string(': 'string item | string',
+\ 'sqlite_exec(': 'resource dbhandle, string query [, string &#38;error_msg] | bool',
+\ 'sqlite_factory(': 'string filename [, int mode [, string &#38;error_message]] | SQLiteDatabase',
+\ 'sqlite_fetch_all(': 'resource result [, int result_type [, bool decode_binary]] | array',
+\ 'sqlite_fetch_array(': 'resource result [, int result_type [, bool decode_binary]] | array',
+\ 'sqlite_fetch_column_types(': 'string table_name, resource dbhandle [, int result_type] | array',
+\ 'sqlite_fetch_object(': 'resource result [, string class_name [, array ctor_params [, bool decode_binary]]] | object',
+\ 'sqlite_fetch_single(': 'resource result [, bool decode_binary] | string',
+\ 'sqlite_field_name(': 'resource result, int field_index | string',
+\ 'sqlite_has_more(': 'resource result | bool',
+\ 'sqlite_has_prev(': 'resource result | bool',
+\ 'sqlite_key(': 'resource result | int',
+\ 'sqlite_last_error(': 'resource dbhandle | int',
+\ 'sqlite_last_insert_rowid(': 'resource dbhandle | int',
+\ 'sqlite_libencoding(': 'void  | string',
+\ 'sqlite_libversion(': 'void  | string',
+\ 'sqlite_next(': 'resource result | bool',
+\ 'sqlite_num_fields(': 'resource result | int',
+\ 'sqlite_num_rows(': 'resource result | int',
+\ 'sqlite_open(': 'string filename [, int mode [, string &#38;error_message]] | resource',
+\ 'sqlite_popen(': 'string filename [, int mode [, string &#38;error_message]] | resource',
+\ 'sqlite_prev(': 'resource result | bool',
+\ 'sqlite_query(': 'resource dbhandle, string query [, int result_type [, string &#38;error_msg]] | resource',
+\ 'sqlite_rewind(': 'resource result | bool',
+\ 'sqlite_seek(': 'resource result, int rownum | bool',
+\ 'sqlite_single_query(': 'resource db, string query [, bool first_row_only [, bool decode_binary]] | array',
+\ 'sqlite_udf_decode_binary(': 'string data | string',
+\ 'sqlite_udf_encode_binary(': 'string data | string',
+\ 'sqlite_unbuffered_query(': 'resource dbhandle, string query [, int result_type [, string &#38;error_msg]] | resource',
+\ 'sqlite_valid(': 'resource result | bool',
+\ 'sql_regcase(': 'string string | string',
+\ 'sqrt(': 'float arg | float',
+\ 'srand(': '[int seed] | void',
+\ 'sscanf(': 'string str, string format [, mixed &#38;...] | mixed',
+\ 'ssh2_auth_hostbased_file(': 'resource session, string username, string hostname, string pubkeyfile, string privkeyfile [, string passphrase [, string local_username]] | bool',
+\ 'ssh2_auth_none(': 'resource session, string username | mixed',
+\ 'ssh2_auth_password(': 'resource session, string username, string password | bool',
+\ 'ssh2_auth_pubkey_file(': 'resource session, string username, string pubkeyfile, string privkeyfile [, string passphrase] | bool',
+\ 'ssh2_connect(': 'string host [, int port [, array methods [, array callbacks]]] | resource',
+\ 'ssh2_exec(': 'resource session, string command [, string pty [, array env [, int width [, int height [, int width_height_type]]]]] | resource',
+\ 'ssh2_fetch_stream(': 'resource channel, int streamid | resource',
+\ 'ssh2_fingerprint(': 'resource session [, int flags] | string',
+\ 'ssh2_methods_negotiated(': 'resource session | array',
+\ 'ssh2_publickey_add(': 'resource pkey, string algoname, string blob [, bool overwrite [, array attributes]] | bool',
+\ 'ssh2_publickey_init(': 'resource session | resource',
+\ 'ssh2_publickey_list(': 'resource pkey | array',
+\ 'ssh2_publickey_remove(': 'resource pkey, string algoname, string blob | bool',
+\ 'ssh2_scp_recv(': 'resource session, string remote_file, string local_file | bool',
+\ 'ssh2_scp_send(': 'resource session, string local_file, string remote_file [, int create_mode] | bool',
+\ 'ssh2_sftp(': 'resource session | resource',
+\ 'ssh2_sftp_lstat(': 'resource sftp, string path | array',
+\ 'ssh2_sftp_mkdir(': 'resource sftp, string dirname [, int mode [, bool recursive]] | bool',
+\ 'ssh2_sftp_readlink(': 'resource sftp, string link | string',
+\ 'ssh2_sftp_realpath(': 'resource sftp, string filename | string',
+\ 'ssh2_sftp_rename(': 'resource sftp, string from, string to | bool',
+\ 'ssh2_sftp_rmdir(': 'resource sftp, string dirname | bool',
+\ 'ssh2_sftp_stat(': 'resource sftp, string path | array',
+\ 'ssh2_sftp_symlink(': 'resource sftp, string target, string link | bool',
+\ 'ssh2_sftp_unlink(': 'resource sftp, string filename | bool',
+\ 'ssh2_shell(': 'resource session [, string term_type [, array env [, int width [, int height [, int width_height_type]]]]] | resource',
+\ 'ssh2_tunnel(': 'resource session, string host, int port | resource',
+\ 'stat(': 'string filename | array',
+\ 'stats_absolute_deviation(': 'array a | float',
+\ 'stats_cdf_beta(': 'float par1, float par2, float par3, int which | float',
+\ 'stats_cdf_binomial(': 'float par1, float par2, float par3, int which | float',
+\ 'stats_cdf_cauchy(': 'float par1, float par2, float par3, int which | float',
+\ 'stats_cdf_chisquare(': 'float par1, float par2, int which | float',
+\ 'stats_cdf_exponential(': 'float par1, float par2, int which | float',
+\ 'stats_cdf_f(': 'float par1, float par2, float par3, int which | float',
+\ 'stats_cdf_gamma(': 'float par1, float par2, float par3, int which | float',
+\ 'stats_cdf_laplace(': 'float par1, float par2, float par3, int which | float',
+\ 'stats_cdf_logistic(': 'float par1, float par2, float par3, int which | float',
+\ 'stats_cdf_negative_binomial(': 'float par1, float par2, float par3, int which | float',
+\ 'stats_cdf_noncentral_chisquare(': 'float par1, float par2, float par3, int which | float',
+\ 'stats_cdf_noncentral_f(': 'float par1, float par2, float par3, float par4, int which | float',
+\ 'stats_cdf_poisson(': 'float par1, float par2, int which | float',
+\ 'stats_cdf_t(': 'float par1, float par2, int which | float',
+\ 'stats_cdf_uniform(': 'float par1, float par2, float par3, int which | float',
+\ 'stats_cdf_weibull(': 'float par1, float par2, float par3, int which | float',
+\ 'stats_covariance(': 'array a, array b | float',
+\ 'stats_dens_beta(': 'float x, float a, float b | float',
+\ 'stats_dens_cauchy(': 'float x, float ave, float stdev | float',
+\ 'stats_dens_chisquare(': 'float x, float dfr | float',
+\ 'stats_dens_exponential(': 'float x, float scale | float',
+\ 'stats_dens_f(': 'float x, float dfr1, float dfr2 | float',
+\ 'stats_dens_gamma(': 'float x, float shape, float scale | float',
+\ 'stats_dens_laplace(': 'float x, float ave, float stdev | float',
+\ 'stats_dens_logistic(': 'float x, float ave, float stdev | float',
+\ 'stats_dens_negative_binomial(': 'float x, float n, float pi | float',
+\ 'stats_dens_normal(': 'float x, float ave, float stdev | float',
+\ 'stats_dens_pmf_binomial(': 'float x, float n, float pi | float',
+\ 'stats_dens_pmf_hypergeometric(': 'float n1, float n2, float N1, float N2 | float',
+\ 'stats_dens_pmf_poisson(': 'float x, float lb | float',
+\ 'stats_dens_t(': 'float x, float dfr | float',
+\ 'stats_dens_weibull(': 'float x, float a, float b | float',
+\ 'stats_den_uniform(': 'float x, float a, float b | float',
+\ 'stats_harmonic_mean(': 'array a | number',
+\ 'stats_kurtosis(': 'array a | float',
+\ 'stats_rand_gen_beta(': 'float a, float b | float',
+\ 'stats_rand_gen_chisquare(': 'float df | float',
+\ 'stats_rand_gen_exponential(': 'float av | float',
+\ 'stats_rand_gen_f(': 'float dfn, float dfd | float',
+\ 'stats_rand_gen_funiform(': 'float low, float high | float',
+\ 'stats_rand_gen_gamma(': 'float a, float r | float',
+\ 'stats_rand_gen_ibinomial(': 'int n, float pp | int',
+\ 'stats_rand_gen_ibinomial_negative(': 'int n, float p | int',
+\ 'stats_rand_gen_int(': 'void  | int',
+\ 'stats_rand_gen_ipoisson(': 'float mu | int',
+\ 'stats_rand_gen_iuniform(': 'int low, int high | int',
+\ 'stats_rand_gen_noncenral_chisquare(': 'float df, float xnonc | float',
+\ 'stats_rand_gen_noncentral_f(': 'float dfn, float dfd, float xnonc | float',
+\ 'stats_rand_gen_noncentral_t(': 'float df, float xnonc | float',
+\ 'stats_rand_gen_normal(': 'float av, float sd | float',
+\ 'stats_rand_gen_t(': 'float df | float',
+\ 'stats_rand_get_seeds(': 'void  | array',
+\ 'stats_rand_phrase_to_seeds(': 'string phrase | array',
+\ 'stats_rand_ranf(': 'void  | float',
+\ 'stats_rand_setall(': 'int iseed1, int iseed2 | void',
+\ 'stats_skew(': 'array a | float',
+\ 'stats_standard_deviation(': 'array a [, bool sample] | float',
+\ 'stats_stat_binomial_coef(': 'int x, int n | float',
+\ 'stats_stat_correlation(': 'array arr1, array arr2 | float',
+\ 'stats_stat_gennch(': 'int n | float',
+\ 'stats_stat_independent_t(': 'array arr1, array arr2 | float',
+\ 'stats_stat_innerproduct(': 'array arr1, array arr2 | float',
+\ 'stats_stat_noncentral_t(': 'float par1, float par2, float par3, int which | float',
+\ 'stats_stat_paired_t(': 'array arr1, array arr2 | float',
+\ 'stats_stat_percentile(': 'float df, float xnonc | float',
+\ 'stats_stat_powersum(': 'array arr, float power | float',
+\ 'stats_variance(': 'array a [, bool sample] | float',
+\ 'strcasecmp(': 'string str1, string str2 | int',
+\ 'strcmp(': 'string str1, string str2 | int',
+\ 'strcoll(': 'string str1, string str2 | int',
+\ 'strcspn(': 'string str1, string str2 [, int start [, int length]] | int',
+\ 'stream_bucket_append(': 'resource brigade, resource bucket | void',
+\ 'stream_bucket_make_writeable(': 'resource brigade | object',
+\ 'stream_bucket_new(': 'resource stream, string buffer | object',
+\ 'stream_bucket_prepend(': 'resource brigade, resource bucket | void',
+\ 'stream_context_create(': '[array options] | resource',
+\ 'stream_context_get_default(': '[array options] | resource',
+\ 'stream_context_get_options(': 'resource stream_or_context | array',
+\ 'stream_context_set_option(': 'resource stream_or_context, string wrapper, string option, mixed value | bool',
+\ 'stream_context_set_params(': 'resource stream_or_context, array params | bool',
+\ 'stream_copy_to_stream(': 'resource source, resource dest [, int maxlength [, int offset]] | int',
+\ 'stream_filter_append(': 'resource stream, string filtername [, int read_write [, mixed params]] | resource',
+\ 'stream_filter_prepend(': 'resource stream, string filtername [, int read_write [, mixed params]] | resource',
+\ 'stream_filter_register(': 'string filtername, string classname | bool',
+\ 'stream_filter_remove(': 'resource stream_filter | bool',
+\ 'stream_get_contents(': 'resource handle [, int maxlength [, int offset]] | string',
+\ 'stream_get_filters(': 'void  | array',
+\ 'stream_get_line(': 'resource handle, int length [, string ending] | string',
+\ 'stream_get_meta_data(': 'resource stream | array',
+\ 'stream_get_transports(': 'void  | array',
+\ 'stream_get_wrappers(': 'void  | array',
+\ 'stream_select(': 'array &#38;read, array &#38;write, array &#38;except, int tv_sec [, int tv_usec] | int',
+\ 'stream_set_blocking(': 'resource stream, int mode | bool',
+\ 'stream_set_timeout(': 'resource stream, int seconds [, int microseconds] | bool',
+\ 'stream_set_write_buffer(': 'resource stream, int buffer | int',
+\ 'stream_socket_accept(': 'resource server_socket [, float timeout [, string &#38;peername]] | resource',
+\ 'stream_socket_client(': 'string remote_socket [, int &#38;errno [, string &#38;errstr [, float timeout [, int flags [, resource context]]]]] | resource',
+\ 'stream_socket_enable_crypto(': 'resource stream, bool enable [, int crypto_type [, resource session_stream]] | mixed',
+\ 'stream_socket_get_name(': 'resource handle, bool want_peer | string',
+\ 'stream_socket_pair(': 'int domain, int type, int protocol | array',
+\ 'stream_socket_recvfrom(': 'resource socket, int length [, int flags [, string &#38;address]] | string',
+\ 'stream_socket_sendto(': 'resource socket, string data [, int flags [, string address]] | int',
+\ 'stream_socket_server(': 'string local_socket [, int &#38;errno [, string &#38;errstr [, int flags [, resource context]]]] | resource',
+\ 'stream_wrapper_register(': 'string protocol, string classname | bool',
+\ 'stream_wrapper_restore(': 'string protocol | bool',
+\ 'stream_wrapper_unregister(': 'string protocol | bool',
+\ 'strftime(': 'string format [, int timestamp] | string',
+\ 'stripcslashes(': 'string str | string',
+\ 'stripos(': 'string haystack, string needle [, int offset] | int',
+\ 'stripslashes(': 'string str | string',
+\ 'strip_tags(': 'string str [, string allowable_tags] | string',
+\ 'str_ireplace(': 'mixed search, mixed replace, mixed subject [, int &#38;count] | mixed',
+\ 'stristr(': 'string haystack, string needle | string',
+\ 'strlen(': 'string string | int',
+\ 'strnatcasecmp(': 'string str1, string str2 | int',
+\ 'strnatcmp(': 'string str1, string str2 | int',
+\ 'strncasecmp(': 'string str1, string str2, int len | int',
+\ 'strncmp(': 'string str1, string str2, int len | int',
+\ 'str_pad(': 'string input, int pad_length [, string pad_string [, int pad_type]] | string',
+\ 'strpbrk(': 'string haystack, string char_list | string',
+\ 'strpos(': 'string haystack, mixed needle [, int offset] | int',
+\ 'strptime(': 'string date, string format | array',
+\ 'strrchr(': 'string haystack, string needle | string',
+\ 'str_repeat(': 'string input, int multiplier | string',
+\ 'str_replace(': 'mixed search, mixed replace, mixed subject [, int &#38;count] | mixed',
+\ 'strrev(': 'string string | string',
+\ 'strripos(': 'string haystack, string needle [, int offset] | int',
+\ 'str_rot13(': 'string str | string',
+\ 'strrpos(': 'string haystack, string needle [, int offset] | int',
+\ 'str_shuffle(': 'string str | string',
+\ 'str_split(': 'string string [, int split_length] | array',
+\ 'strspn(': 'string str1, string str2 [, int start [, int length]] | int',
+\ 'strstr(': 'string haystack, string needle | string',
+\ 'strtok(': 'string str, string token | string',
+\ 'strtolower(': 'string str | string',
+\ 'strtotime(': 'string time [, int now] | int',
+\ 'strtoupper(': 'string string | string',
+\ 'strtr(': 'string str, string from, string to | string',
+\ 'strval(': 'mixed var | string',
+\ 'str_word_count(': 'string string [, int format [, string charlist]] | mixed',
+\ 'substr_compare(': 'string main_str, string str, int offset [, int length [, bool case_insensitivity]] | int',
+\ 'substr_count(': 'string haystack, string needle [, int offset [, int length]] | int',
+\ 'substr(': 'string string, int start [, int length] | string',
+\ 'substr_replace(': 'mixed string, string replacement, int start [, int length] | mixed',
+\ 'swf_actiongeturl(': 'string url, string target | void',
+\ 'swf_actiongotoframe(': 'int framenumber | void',
+\ 'swf_actiongotolabel(': 'string label | void',
+\ 'swfaction(': 'string script | SWFAction',
+\ 'swf_actionnextframe(': 'void  | void',
+\ 'swf_actionplay(': 'void  | void',
+\ 'swf_actionprevframe(': 'void  | void',
+\ 'swf_actionsettarget(': 'string target | void',
+\ 'swf_actionstop(': 'void  | void',
+\ 'swf_actiontogglequality(': 'void  | void',
+\ 'swf_actionwaitforframe(': 'int framenumber, int skipcount | void',
+\ 'swf_addbuttonrecord(': 'int states, int shapeid, int depth | void',
+\ 'swf_addcolor(': 'float r, float g, float b, float a | void',
+\ 'swfbitmap-&#62;getheight(': 'void  | float',
+\ 'swfbitmap-&#62;getwidth(': 'void  | float',
+\ 'swfbitmap(': 'mixed file [, mixed alphafile] | SWFBitmap',
+\ 'swfbutton-&#62;addaction(': 'resource action, int flags | void',
+\ 'swfbutton-&#62;addshape(': 'resource shape, int flags | void',
+\ 'swfbutton(': 'void  | SWFButton',
+\ 'swfbutton-&#62;setaction(': 'resource action | void',
+\ 'swfbutton-&#62;setdown(': 'resource shape | void',
+\ 'swfbutton-&#62;sethit(': 'resource shape | void',
+\ 'swfbutton-&#62;setover(': 'resource shape | void',
+\ 'swfbutton-&#62;setup(': 'resource shape | void',
+\ 'swf_closefile(': '[int return_file] | void',
+\ 'swf_definebitmap(': 'int objid, string image_name | void',
+\ 'swf_definefont(': 'int fontid, string fontname | void',
+\ 'swf_defineline(': 'int objid, float x1, float y1, float x2, float y2, float width | void',
+\ 'swf_definepoly(': 'int objid, array coords, int npoints, float width | void',
+\ 'swf_definerect(': 'int objid, float x1, float y1, float x2, float y2, float width | void',
+\ 'swf_definetext(': 'int objid, string str, int docenter | void',
+\ 'swfdisplayitem-&#62;addcolor(': 'int red, int green, int blue [, int a] | void',
+\ 'swfdisplayitem-&#62;move(': 'int dx, int dy | void',
+\ 'swfdisplayitem-&#62;moveto(': 'int x, int y | void',
+\ 'swfdisplayitem-&#62;multcolor(': 'int red, int green, int blue [, int a] | void',
+\ 'swfdisplayitem-&#62;remove(': 'void  | void',
+\ 'swfdisplayitem-&#62;rotate(': 'float ddegrees | void',
+\ 'swfdisplayitem-&#62;rotateto(': 'float degrees | void',
+\ 'swfdisplayitem-&#62;scale(': 'int dx, int dy | void',
+\ 'swfdisplayitem-&#62;scaleto(': 'int x [, int y] | void',
+\ 'swfdisplayitem-&#62;setdepth(': 'float depth | void',
+\ 'swfdisplayitem-&#62;setname(': 'string name | void',
+\ 'swfdisplayitem-&#62;setratio(': 'float ratio | void',
+\ 'swfdisplayitem-&#62;skewx(': 'float ddegrees | void',
+\ 'swfdisplayitem-&#62;skewxto(': 'float degrees | void',
+\ 'swfdisplayitem-&#62;skewy(': 'float ddegrees | void',
+\ 'swfdisplayitem-&#62;skewyto(': 'float degrees | void',
+\ 'swf_endbutton(': 'void  | void',
+\ 'swf_enddoaction(': 'void  | void',
+\ 'swf_endshape(': 'void  | void',
+\ 'swf_endsymbol(': 'void  | void',
+\ 'swffill(': 'void  | SWFFill',
+\ 'swffill-&#62;moveto(': 'int x, int y | void',
+\ 'swffill-&#62;rotateto(': 'float degrees | void',
+\ 'swffill-&#62;scaleto(': 'int x [, int y] | void',
+\ 'swffill-&#62;skewxto(': 'float x | void',
+\ 'swffill-&#62;skewyto(': 'float y | void',
+\ 'swffont-&#62;getwidth(': 'string string | float',
+\ 'swffont(': 'string filename | SWFFont',
+\ 'swf_fontsize(': 'float size | void',
+\ 'swf_fontslant(': 'float slant | void',
+\ 'swf_fonttracking(': 'float tracking | void',
+\ 'swf_getbitmapinfo(': 'int bitmapid | array',
+\ 'swf_getfontinfo(': 'void  | array',
+\ 'swf_getframe(': 'void  | int',
+\ 'swfgradient-&#62;addentry(': 'float ratio, int red, int green, int blue [, int a] | void',
+\ 'swfgradient(': 'void  | SWFGradient',
+\ 'swf_labelframe(': 'string name | void',
+\ 'swf_lookat(': 'float view_x, float view_y, float view_z, float reference_x, float reference_y, float reference_z, float twist | void',
+\ 'swf_modifyobject(': 'int depth, int how | void',
+\ 'swfmorph-&#62;getshape1(': 'void  | mixed',
+\ 'swfmorph-&#62;getshape2(': 'void  | mixed',
+\ 'swfmorph(': 'void  | SWFMorph',
+\ 'swfmovie-&#62;add(': 'resource instance | void',
+\ 'swfmovie(': 'void  | SWFMovie',
+\ 'swfmovie-&#62;nextframe(': 'void  | void',
+\ 'swfmovie-&#62;output(': '[int compression] | int',
+\ 'swfmovie-&#62;remove(': 'resource instance | void',
+\ 'swfmovie-&#62;save(': 'string filename [, int compression] | int',
+\ 'swfmovie-&#62;setbackground(': 'int red, int green, int blue | void',
+\ 'swfmovie-&#62;setdimension(': 'int width, int height | void',
+\ 'swfmovie-&#62;setframes(': 'string numberofframes | void',
+\ 'swfmovie-&#62;setrate(': 'int rate | void',
+\ 'swfmovie-&#62;streammp3(': 'mixed mp3File | void',
+\ 'swf_mulcolor(': 'float r, float g, float b, float a | void',
+\ 'swf_nextid(': 'void  | int',
+\ 'swf_oncondition(': 'int transition | void',
+\ 'swf_openfile(': 'string filename, float width, float height, float framerate, float r, float g, float b | void',
+\ 'swf_ortho2(': 'float xmin, float xmax, float ymin, float ymax | void',
+\ 'swf_ortho(': 'float xmin, float xmax, float ymin, float ymax, float zmin, float zmax | void',
+\ 'swf_perspective(': 'float fovy, float aspect, float near, float far | void',
+\ 'swf_placeobject(': 'int objid, int depth | void',
+\ 'swf_polarview(': 'float dist, float azimuth, float incidence, float twist | void',
+\ 'swf_popmatrix(': 'void  | void',
+\ 'swf_posround(': 'int round | void',
+\ 'SWFPrebuiltClip(': '[string file] | SWFPrebuiltClip',
+\ 'swf_pushmatrix(': 'void  | void',
+\ 'swf_removeobject(': 'int depth | void',
+\ 'swf_rotate(': 'float angle, string axis | void',
+\ 'swf_scale(': 'float x, float y, float z | void',
+\ 'swf_setfont(': 'int fontid | void',
+\ 'swf_setframe(': 'int framenumber | void',
+\ 'SWFShape-&#62;addFill(': 'int red, int green, int blue [, int a] | SWFFill',
+\ 'swf_shapearc(': 'float x, float y, float r, float ang1, float ang2 | void',
+\ 'swf_shapecurveto3(': 'float x1, float y1, float x2, float y2, float x3, float y3 | void',
+\ 'swf_shapecurveto(': 'float x1, float y1, float x2, float y2 | void',
+\ 'swfshape-&#62;drawcurve(': 'int controldx, int controldy, int anchordx, int anchordy [, int targetdx, int targetdy] | int',
+\ 'swfshape-&#62;drawcurveto(': 'int controlx, int controly, int anchorx, int anchory [, int targetx, int targety] | int',
+\ 'swfshape-&#62;drawline(': 'int dx, int dy | void',
+\ 'swfshape-&#62;drawlineto(': 'int x, int y | void',
+\ 'swf_shapefillbitmapclip(': 'int bitmapid | void',
+\ 'swf_shapefillbitmaptile(': 'int bitmapid | void',
+\ 'swf_shapefilloff(': 'void  | void',
+\ 'swf_shapefillsolid(': 'float r, float g, float b, float a | void',
+\ 'swfshape(': 'void  | SWFShape',
+\ 'swf_shapelinesolid(': 'float r, float g, float b, float a, float width | void',
+\ 'swf_shapelineto(': 'float x, float y | void',
+\ 'swfshape-&#62;movepen(': 'int dx, int dy | void',
+\ 'swfshape-&#62;movepento(': 'int x, int y | void',
+\ 'swf_shapemoveto(': 'float x, float y | void',
+\ 'swfshape-&#62;setleftfill(': 'swfgradient fill | void',
+\ 'swfshape-&#62;setline(': 'swfshape shape | void',
+\ 'swfshape-&#62;setrightfill(': 'swfgradient fill | void',
+\ 'swf_showframe(': 'void  | void',
+\ 'SWFSound(': 'string filename, int flags | SWFSound',
+\ 'swfsprite-&#62;add(': 'resource object | void',
+\ 'swfsprite(': 'void  | SWFSprite',
+\ 'swfsprite-&#62;nextframe(': 'void  | void',
+\ 'swfsprite-&#62;remove(': 'resource object | void',
+\ 'swfsprite-&#62;setframes(': 'int numberofframes | void',
+\ 'swf_startbutton(': 'int objid, int type | void',
+\ 'swf_startdoaction(': 'void  | void',
+\ 'swf_startshape(': 'int objid | void',
+\ 'swf_startsymbol(': 'int objid | void',
+\ 'swftext-&#62;addstring(': 'string string | void',
+\ 'swftextfield-&#62;addstring(': 'string string | void',
+\ 'swftextfield-&#62;align(': 'int alignement | void',
+\ 'swftextfield(': '[int flags] | SWFTextField',
+\ 'swftextfield-&#62;setbounds(': 'int width, int height | void',
+\ 'swftextfield-&#62;setcolor(': 'int red, int green, int blue [, int a] | void',
+\ 'swftextfield-&#62;setfont(': 'string font | void',
+\ 'swftextfield-&#62;setheight(': 'int height | void',
+\ 'swftextfield-&#62;setindentation(': 'int width | void',
+\ 'swftextfield-&#62;setleftmargin(': 'int width | void',
+\ 'swftextfield-&#62;setlinespacing(': 'int height | void',
+\ 'swftextfield-&#62;setmargins(': 'int left, int right | void',
+\ 'swftextfield-&#62;setname(': 'string name | void',
+\ 'swftextfield-&#62;setrightmargin(': 'int width | void',
+\ 'swftext-&#62;getwidth(': 'string string | float',
+\ 'swftext(': 'void  | SWFText',
+\ 'swftext-&#62;moveto(': 'int x, int y | void',
+\ 'swftext-&#62;setcolor(': 'int red, int green, int blue [, int a] | void',
+\ 'swftext-&#62;setfont(': 'string font | void',
+\ 'swftext-&#62;setheight(': 'int height | void',
+\ 'swftext-&#62;setspacing(': 'float spacing | void',
+\ 'swf_textwidth(': 'string str | float',
+\ 'swf_translate(': 'float x, float y, float z | void',
+\ 'SWFVideoStream(': '[string file] | SWFVideoStream',
+\ 'swf_viewport(': 'float xmin, float xmax, float ymin, float ymax | void',
+\ 'sybase_affected_rows(': '[resource link_identifier] | int',
+\ 'sybase_close(': '[resource link_identifier] | bool',
+\ 'sybase_connect(': '[string servername [, string username [, string password [, string charset [, string appname]]]]] | resource',
+\ 'sybase_data_seek(': 'resource result_identifier, int row_number | bool',
+\ 'sybase_deadlock_retry_count(': 'int retry_count | void',
+\ 'sybase_fetch_array(': 'resource result | array',
+\ 'sybase_fetch_assoc(': 'resource result | array',
+\ 'sybase_fetch_field(': 'resource result [, int field_offset] | object',
+\ 'sybase_fetch_object(': 'resource result [, mixed object] | object',
+\ 'sybase_fetch_row(': 'resource result | array',
+\ 'sybase_field_seek(': 'resource result, int field_offset | bool',
+\ 'sybase_free_result(': 'resource result | bool',
+\ 'sybase_get_last_message(': 'void  | string',
+\ 'sybase_min_client_severity(': 'int severity | void',
+\ 'sybase_min_error_severity(': 'int severity | void',
+\ 'sybase_min_message_severity(': 'int severity | void',
+\ 'sybase_min_server_severity(': 'int severity | void',
+\ 'sybase_num_fields(': 'resource result | int',
+\ 'sybase_num_rows(': 'resource result | int',
+\ 'sybase_pconnect(': '[string servername [, string username [, string password [, string charset [, string appname]]]]] | resource',
+\ 'sybase_query(': 'string query [, resource link_identifier] | mixed',
+\ 'sybase_result(': 'resource result, int row, mixed field | string',
+\ 'sybase_select_db(': 'string database_name [, resource link_identifier] | bool',
+\ 'sybase_set_message_handler(': 'callback handler [, resource connection] | bool',
+\ 'sybase_unbuffered_query(': 'string query, resource link_identifier [, bool store_result] | resource',
+\ 'symlink(': 'string target, string link | bool',
+\ 'sys_getloadavg(': 'void  | array',
+\ 'syslog(': 'int priority, string message | bool',
+\ 'system(': 'string command [, int &#38;return_var] | string',
+\ 'tanh(': 'float arg | float',
+\ 'tan(': 'float arg | float',
+\ 'tcpwrap_check(': 'string daemon, string address [, string user [, bool nodns]] | bool',
+\ 'tempnam(': 'string dir, string prefix | string',
+\ 'textdomain(': 'string text_domain | string',
+\ 'tidy_access_count(': 'tidy object | int',
+\ 'tidy_config_count(': 'tidy object | int',
+\ 'tidy_error_count(': 'tidy object | int',
+\ 'tidy_get_output(': 'tidy object | string',
+\ 'tidy_load_config(': 'string filename, string encoding | void',
+\ 'tidy_node-&#62;get_attr(': 'int attrib_id | tidy_attr',
+\ 'tidy_node-&#62;get_nodes(': 'int node_id | array',
+\ 'tidyNode-&#62;hasChildren(': 'void  | bool',
+\ 'tidyNode-&#62;hasSiblings(': 'void  | bool',
+\ 'tidyNode-&#62;isAsp(': 'void  | bool',
+\ 'tidyNode-&#62;isComment(': 'void  | bool',
+\ 'tidyNode-&#62;isHtml(': 'void  | bool',
+\ 'tidyNode-&#62;isJste(': 'void  | bool',
+\ 'tidyNode-&#62;isPhp(': 'void  | bool',
+\ 'tidyNode-&#62;isText(': 'void  | bool',
+\ 'tidy_node-&#62;next(': 'void  | tidy_node',
+\ 'tidy_node-&#62;prev(': 'void  | tidy_node',
+\ 'tidy_repair_file(': 'string filename [, mixed config [, string encoding [, bool use_include_path]]] | string',
+\ 'tidy_repair_string(': 'string data [, mixed config [, string encoding]] | string',
+\ 'tidy_reset_config(': 'void  | bool',
+\ 'tidy_save_config(': 'string filename | bool',
+\ 'tidy_set_encoding(': 'string encoding | bool',
+\ 'tidy_setopt(': 'string option, mixed value | bool',
+\ 'tidy_warning_count(': 'tidy object | int',
+\ 'time(': 'void  | int',
+\ 'time_nanosleep(': 'int seconds, int nanoseconds | mixed',
+\ 'time_sleep_until(': 'float timestamp | bool',
+\ 'tmpfile(': 'void  | resource',
+\ 'token_get_all(': 'string source | array',
+\ 'token_name(': 'int token | string',
+\ 'touch(': 'string filename [, int time [, int atime]] | bool',
+\ 'trigger_error(': 'string error_msg [, int error_type] | bool',
+\ 'trim(': 'string str [, string charlist] | string',
+\ 'uasort(': 'array &#38;array, callback cmp_function | bool',
+\ 'ucfirst(': 'string str | string',
+\ 'ucwords(': 'string str | string',
+\ 'udm_add_search_limit(': 'resource agent, int var, string val | bool',
+\ 'udm_alloc_agent_array(': 'array databases | resource',
+\ 'udm_alloc_agent(': 'string dbaddr [, string dbmode] | resource',
+\ 'udm_api_version(': 'void  | int',
+\ 'udm_cat_list(': 'resource agent, string category | array',
+\ 'udm_cat_path(': 'resource agent, string category | array',
+\ 'udm_check_charset(': 'resource agent, string charset | bool',
+\ 'udm_check_stored(': 'resource agent, int link, string doc_id | int',
+\ 'udm_clear_search_limits(': 'resource agent | bool',
+\ 'udm_close_stored(': 'resource agent, int link | int',
+\ 'udm_crc32(': 'resource agent, string str | int',
+\ 'udm_errno(': 'resource agent | int',
+\ 'udm_error(': 'resource agent | string',
+\ 'udm_find(': 'resource agent, string query | resource',
+\ 'udm_free_agent(': 'resource agent | int',
+\ 'udm_free_ispell_data(': 'int agent | bool',
+\ 'udm_free_res(': 'resource res | bool',
+\ 'udm_get_doc_count(': 'resource agent | int',
+\ 'udm_get_res_field(': 'resource res, int row, int field | string',
+\ 'udm_get_res_param(': 'resource res, int param | string',
+\ 'udm_hash32(': 'resource agent, string str | int',
+\ 'udm_load_ispell_data(': 'resource agent, int var, string val1, string val2, int flag | bool',
+\ 'udm_open_stored(': 'resource agent, string storedaddr | int',
+\ 'udm_set_agent_param(': 'resource agent, int var, string val | bool',
+\ 'uksort(': 'array &#38;array, callback cmp_function | bool',
+\ 'umask(': '[int mask] | int',
+\ 'unicode_encode(': 'unicode input, string encoding | string',
+\ 'unicode_semantics(': 'void  | bool',
+\ 'uniqid(': '[string prefix [, bool more_entropy]] | string',
+\ 'unixtojd(': '[int timestamp] | int',
+\ 'unlink(': 'string filename [, resource context] | bool',
+\ 'unpack(': 'string format, string data | array',
+\ 'unregister_tick_function(': 'string function_name | void',
+\ 'unserialize(': 'string str | mixed',
+\ 'unset(': 'mixed var [, mixed var [, mixed ...]] | void',
+\ 'urldecode(': 'string str | string',
+\ 'urlencode(': 'string str | string',
+\ 'use_soap_error_handler(': '[bool handler] | bool',
+\ 'usleep(': 'int micro_seconds | void',
+\ 'usort(': 'array &#38;array, callback cmp_function | bool',
+\ 'utf8_decode(': 'string data | string',
+\ 'utf8_encode(': 'string data | string',
+\ 'var_dump(': 'mixed expression [, mixed expression [, ...]] | void',
+\ 'var_export(': 'mixed expression [, bool return] | mixed',
+\ 'variant_abs(': 'mixed val | mixed',
+\ 'variant_add(': 'mixed left, mixed right | mixed',
+\ 'variant_and(': 'mixed left, mixed right | mixed',
+\ 'variant_cast(': 'variant variant, int type | variant',
+\ 'variant_cat(': 'mixed left, mixed right | mixed',
+\ 'variant_cmp(': 'mixed left, mixed right [, int lcid [, int flags]] | int',
+\ 'variant_date_from_timestamp(': 'int timestamp | variant',
+\ 'variant_date_to_timestamp(': 'variant variant | int',
+\ 'variant_div(': 'mixed left, mixed right | mixed',
+\ 'variant_eqv(': 'mixed left, mixed right | mixed',
+\ 'variant_fix(': 'mixed variant | mixed',
+\ 'variant_get_type(': 'variant variant | int',
+\ 'variant_idiv(': 'mixed left, mixed right | mixed',
+\ 'variant_imp(': 'mixed left, mixed right | mixed',
+\ 'variant_int(': 'mixed variant | mixed',
+\ 'variant_mod(': 'mixed left, mixed right | mixed',
+\ 'variant_mul(': 'mixed left, mixed right | mixed',
+\ 'variant_neg(': 'mixed variant | mixed',
+\ 'variant_not(': 'mixed variant | mixed',
+\ 'variant_or(': 'mixed left, mixed right | mixed',
+\ 'variant_pow(': 'mixed left, mixed right | mixed',
+\ 'variant_round(': 'mixed variant, int decimals | mixed',
+\ 'variant_set(': 'variant variant, mixed value | void',
+\ 'variant_set_type(': 'variant variant, int type | void',
+\ 'variant_sub(': 'mixed left, mixed right | mixed',
+\ 'variant_xor(': 'mixed left, mixed right | mixed',
+\ 'version_compare(': 'string version1, string version2 [, string operator] | mixed',
+\ 'vfprintf(': 'resource handle, string format, array args | int',
+\ 'virtual(': 'string filename | bool',
+\ 'vpopmail_add_alias_domain_ex(': 'string olddomain, string newdomain | bool',
+\ 'vpopmail_add_alias_domain(': 'string domain, string aliasdomain | bool',
+\ 'vpopmail_add_domain_ex(': 'string domain, string passwd [, string quota [, string bounce [, bool apop]]] | bool',
+\ 'vpopmail_add_domain(': 'string domain, string dir, int uid, int gid | bool',
+\ 'vpopmail_add_user(': 'string user, string domain, string password [, string gecos [, bool apop]] | bool',
+\ 'vpopmail_alias_add(': 'string user, string domain, string alias | bool',
+\ 'vpopmail_alias_del_domain(': 'string domain | bool',
+\ 'vpopmail_alias_del(': 'string user, string domain | bool',
+\ 'vpopmail_alias_get_all(': 'string domain | array',
+\ 'vpopmail_alias_get(': 'string alias, string domain | array',
+\ 'vpopmail_auth_user(': 'string user, string domain, string password [, string apop] | bool',
+\ 'vpopmail_del_domain_ex(': 'string domain | bool',
+\ 'vpopmail_del_domain(': 'string domain | bool',
+\ 'vpopmail_del_user(': 'string user, string domain | bool',
+\ 'vpopmail_error(': 'void  | string',
+\ 'vpopmail_passwd(': 'string user, string domain, string password [, bool apop] | bool',
+\ 'vpopmail_set_user_quota(': 'string user, string domain, string quota | bool',
+\ 'vprintf(': 'string format, array args | int',
+\ 'vsprintf(': 'string format, array args | string',
+\ 'w32api_deftype(': 'string typename, string member1_type, string member1_name [, string ... [, string ...]] | bool',
+\ 'w32api_init_dtype(': 'string typename, mixed value [, mixed ...] | resource',
+\ 'w32api_invoke_function(': 'string funcname, mixed argument [, mixed ...] | mixed',
+\ 'w32api_register_function(': 'string library, string function_name, string return_type | bool',
+\ 'w32api_set_call_method(': 'int method | void',
+\ 'wddx_add_vars(': 'int packet_id, mixed name_var [, mixed ...] | bool',
+\ 'wddx_packet_end(': 'resource packet_id | string',
+\ 'wddx_packet_start(': '[string comment] | resource',
+\ 'wddx_serialize_value(': 'mixed var [, string comment] | string',
+\ 'wddx_serialize_vars(': 'mixed var_name [, mixed ...] | string',
+\ 'wddx_unserialize(': 'string packet | mixed',
+\ 'win32_create_service(': 'array details [, string machine] | int',
+\ 'win32_delete_service(': 'string servicename [, string machine] | int',
+\ 'win32_get_last_control_message(': 'void  | int',
+\ 'win32_ps_list_procs(': 'void  | array',
+\ 'win32_ps_stat_mem(': 'void  | array',
+\ 'win32_ps_stat_proc(': '[int pid] | array',
+\ 'win32_query_service_status(': 'string servicename [, string machine] | mixed',
+\ 'win32_set_service_status(': 'int status | bool',
+\ 'win32_start_service_ctrl_dispatcher(': 'string name | bool',
+\ 'win32_start_service(': 'string servicename [, string machine] | int',
+\ 'win32_stop_service(': 'string servicename [, string machine] | int',
+\ 'wordwrap(': 'string str [, int width [, string break [, bool cut]]] | string',
+\ 'xattr_get(': 'string filename, string name [, int flags] | string',
+\ 'xattr_list(': 'string filename [, int flags] | array',
+\ 'xattr_remove(': 'string filename, string name [, int flags] | bool',
+\ 'xattr_set(': 'string filename, string name, string value [, int flags] | bool',
+\ 'xattr_supported(': 'string filename [, int flags] | bool',
+\ 'xdiff_file_diff_binary(': 'string file1, string file2, string dest | bool',
+\ 'xdiff_file_diff(': 'string file1, string file2, string dest [, int context [, bool minimal]] | bool',
+\ 'xdiff_file_merge3(': 'string file1, string file2, string file3, string dest | mixed',
+\ 'xdiff_file_patch_binary(': 'string file, string patch, string dest | bool',
+\ 'xdiff_file_patch(': 'string file, string patch, string dest [, int flags] | mixed',
+\ 'xdiff_string_diff_binary(': 'string str1, string str2 | string',
+\ 'xdiff_string_diff(': 'string str1, string str2 [, int context [, bool minimal]] | string',
+\ 'xdiff_string_merge3(': 'string str1, string str2, string str3 [, string &#38;error] | mixed',
+\ 'xdiff_string_patch_binary(': 'string str, string patch | string',
+\ 'xdiff_string_patch(': 'string str, string patch [, int flags [, string &#38;error]] | string',
+\ 'xml_error_string(': 'int code | string',
+\ 'xml_get_current_byte_index(': 'resource parser | int',
+\ 'xml_get_current_column_number(': 'resource parser | int',
+\ 'xml_get_current_line_number(': 'resource parser | int',
+\ 'xml_get_error_code(': 'resource parser | int',
+\ 'xml_parse(': 'resource parser, string data [, bool is_final] | int',
+\ 'xml_parse_into_struct(': 'resource parser, string data, array &#38;values [, array &#38;index] | int',
+\ 'xml_parser_create(': '[string encoding] | resource',
+\ 'xml_parser_create_ns(': '[string encoding [, string separator]] | resource',
+\ 'xml_parser_free(': 'resource parser | bool',
+\ 'xml_parser_get_option(': 'resource parser, int option | mixed',
+\ 'xml_parser_set_option(': 'resource parser, int option, mixed value | bool',
+\ 'xmlrpc_decode(': 'string xml [, string encoding] | array',
+\ 'xmlrpc_decode_request(': 'string xml, string &#38;method [, string encoding] | array',
+\ 'xmlrpc_encode(': 'mixed value | string',
+\ 'xmlrpc_encode_request(': 'string method, mixed params [, array output_options] | string',
+\ 'xmlrpc_get_type(': 'mixed value | string',
+\ 'xmlrpc_is_fault(': 'array arg | bool',
+\ 'xmlrpc_parse_method_descriptions(': 'string xml | array',
+\ 'xmlrpc_server_add_introspection_data(': 'resource server, array desc | int',
+\ 'xmlrpc_server_call_method(': 'resource server, string xml, mixed user_data [, array output_options] | string',
+\ 'xmlrpc_server_create(': 'void  | resource',
+\ 'xmlrpc_server_destroy(': 'resource server | int',
+\ 'xmlrpc_server_register_introspection_callback(': 'resource server, string function | bool',
+\ 'xmlrpc_server_register_method(': 'resource server, string method_name, string function | bool',
+\ 'xmlrpc_set_type(': 'string &#38;value, string type | bool',
+\ 'xml_set_character_data_handler(': 'resource parser, callback handler | bool',
+\ 'xml_set_default_handler(': 'resource parser, callback handler | bool',
+\ 'xml_set_element_handler(': 'resource parser, callback start_element_handler, callback end_element_handler | bool',
+\ 'xml_set_end_namespace_decl_handler(': 'resource parser, callback handler | bool',
+\ 'xml_set_external_entity_ref_handler(': 'resource parser, callback handler | bool',
+\ 'xml_set_notation_decl_handler(': 'resource parser, callback handler | bool',
+\ 'xml_set_object(': 'resource parser, object &#38;object | bool',
+\ 'xml_set_processing_instruction_handler(': 'resource parser, callback handler | bool',
+\ 'xml_set_start_namespace_decl_handler(': 'resource parser, callback handler | bool',
+\ 'xml_set_unparsed_entity_decl_handler(': 'resource parser, callback handler | bool',
+\ 'xmlwriter_end_attribute(': 'resource xmlwriter | bool',
+\ 'xmlwriter_end_cdata(': 'resource xmlwriter | bool',
+\ 'xmlwriter_end_comment(': 'resource xmlwriter | bool',
+\ 'xmlwriter_end_document(': 'resource xmlwriter | bool',
+\ 'xmlwriter_end_dtd_attlist(': 'resource xmlwriter | bool',
+\ 'xmlwriter_end_dtd_element(': 'resource xmlwriter | bool',
+\ 'xmlwriter_end_dtd_entity(': 'resource xmlwriter | bool',
+\ 'xmlwriter_end_dtd(': 'resource xmlwriter | bool',
+\ 'xmlwriter_end_element(': 'resource xmlwriter | bool',
+\ 'xmlwriter_end_pi(': 'resource xmlwriter | bool',
+\ 'xmlwriter_flush(': 'resource xmlwriter [, bool empty] | mixed',
+\ 'xmlwriter_full_end_element(': 'resource xmlwriter | bool',
+\ 'xmlwriter_open_memory(': 'void  | resource',
+\ 'xmlwriter_open_uri(': 'string source | resource',
+\ 'xmlwriter_output_memory(': 'resource xmlwriter [, bool flush] | string',
+\ 'xmlwriter_set_indent(': 'resource xmlwriter, bool indent | bool',
+\ 'xmlwriter_set_indent_string(': 'resource xmlwriter, string indentString | bool',
+\ 'xmlwriter_start_attribute(': 'resource xmlwriter, string name | bool',
+\ 'xmlwriter_start_attribute_ns(': 'resource xmlwriter, string prefix, string name, string uri | bool',
+\ 'xmlwriter_start_cdata(': 'resource xmlwriter | bool',
+\ 'xmlwriter_start_comment(': 'resource xmlwriter | bool',
+\ 'xmlwriter_start_document(': 'resource xmlwriter [, string version [, string encoding [, string standalone]]] | bool',
+\ 'xmlwriter_start_dtd_attlist(': 'resource xmlwriter, string name | bool',
+\ 'xmlwriter_start_dtd_element(': 'resource xmlwriter, string name | bool',
+\ 'xmlwriter_start_dtd_entity(': 'resource xmlwriter, string name, bool isparam | bool',
+\ 'xmlwriter_start_dtd(': 'resource xmlwriter, string name [, string pubid [, string sysid]] | bool',
+\ 'xmlwriter_start_element(': 'resource xmlwriter, string name | bool',
+\ 'xmlwriter_start_element_ns(': 'resource xmlwriter, string prefix, string name, string uri | bool',
+\ 'xmlwriter_start_pi(': 'resource xmlwriter, string target | bool',
+\ 'xmlwriter_text(': 'resource xmlwriter, string content | bool',
+\ 'xmlwriter_write_attribute(': 'resource xmlwriter, string name, string content | bool',
+\ 'xmlwriter_write_attribute_ns(': 'resource xmlwriter, string prefix, string name, string uri, string content | bool',
+\ 'xmlwriter_write_cdata(': 'resource xmlwriter, string content | bool',
+\ 'xmlwriter_write_comment(': 'resource xmlwriter, string content | bool',
+\ 'xmlwriter_write_dtd_attlist(': 'resource xmlwriter, string name, string content | bool',
+\ 'xmlwriter_write_dtd_element(': 'resource xmlwriter, string name, string content | bool',
+\ 'xmlwriter_write_dtd_entity(': 'resource xmlwriter, string name, string content | bool',
+\ 'xmlwriter_write_dtd(': 'resource xmlwriter, string name [, string pubid [, string sysid [, string subset]]] | bool',
+\ 'xmlwriter_write_element(': 'resource xmlwriter, string name, string content | bool',
+\ 'xmlwriter_write_element_ns(': 'resource xmlwriter, string prefix, string name, string uri, string content | bool',
+\ 'xmlwriter_write_pi(': 'resource xmlwriter, string target, string content | bool',
+\ 'xmlwriter_write_raw(': 'resource xmlwriter, string content | bool',
+\ 'xpath_new_context(': 'domdocument dom_document | XPathContext',
+\ 'xpath_register_ns_auto(': 'XPathContext xpath_context [, object context_node] | bool',
+\ 'xpath_register_ns(': 'XPathContext xpath_context, string prefix, string uri | bool',
+\ 'xptr_new_context(': 'void  | XPathContext',
+\ 'xslt_backend_info(': 'void  | string',
+\ 'xslt_backend_name(': 'void  | string',
+\ 'xslt_backend_version(': 'void  | string',
+\ 'xslt_create(': 'void  | resource',
+\ 'xslt_errno(': 'resource xh | int',
+\ 'xslt_error(': 'resource xh | string',
+\ 'xslt_free(': 'resource xh | void',
+\ 'xslt_getopt(': 'resource processor | int',
+\ 'xslt_process(': 'resource xh, string xmlcontainer, string xslcontainer [, string resultcontainer [, array arguments [, array parameters]]] | mixed',
+\ 'xslt_set_base(': 'resource xh, string uri | void',
+\ 'xslt_set_encoding(': 'resource xh, string encoding | void',
+\ 'xslt_set_error_handler(': 'resource xh, mixed handler | void',
+\ 'xslt_set_log(': 'resource xh [, mixed log] | void',
+\ 'xslt_set_object(': 'resource processor, object &#38;obj | bool',
+\ 'xslt_setopt(': 'resource processor, int newmask | mixed',
+\ 'xslt_set_sax_handler(': 'resource xh, array handlers | void',
+\ 'xslt_set_sax_handlers(': 'resource processor, array handlers | void',
+\ 'xslt_set_scheme_handler(': 'resource xh, array handlers | void',
+\ 'xslt_set_scheme_handlers(': 'resource processor, array handlers | void',
+\ 'yaz_addinfo(': 'resource id | string',
+\ 'yaz_ccl_conf(': 'resource id, array config | void',
+\ 'yaz_ccl_parse(': 'resource id, string query, array &#38;result | bool',
+\ 'yaz_close(': 'resource id | bool',
+\ 'yaz_connect(': 'string zurl [, mixed options] | mixed',
+\ 'yaz_database(': 'resource id, string databases | bool',
+\ 'yaz_element(': 'resource id, string elementset | bool',
+\ 'yaz_errno(': 'resource id | int',
+\ 'yaz_error(': 'resource id | string',
+\ 'yaz_es_result(': 'resource id | array',
+\ 'yaz_get_option(': 'resource id, string name | string',
+\ 'yaz_hits(': 'resource id [, array searchresult] | int',
+\ 'yaz_itemorder(': 'resource id, array args | void',
+\ 'yaz_present(': 'resource id | bool',
+\ 'yaz_range(': 'resource id, int start, int number | void',
+\ 'yaz_record(': 'resource id, int pos, string type | string',
+\ 'yaz_scan(': 'resource id, string type, string startterm [, array flags] | void',
+\ 'yaz_scan_result(': 'resource id [, array &#38;result] | array',
+\ 'yaz_schema(': 'resource id, string schema | void',
+\ 'yaz_search(': 'resource id, string type, string query | bool',
+\ 'yaz_set_option(': 'resource id, string name, string value | void',
+\ 'yaz_sort(': 'resource id, string criteria | void',
+\ 'yaz_syntax(': 'resource id, string syntax | void',
+\ 'yaz_wait(': '[array &#38;options] | mixed',
+\ 'yp_all(': 'string domain, string map, string callback | void',
+\ 'yp_cat(': 'string domain, string map | array',
+\ 'yp_errno(': 'void  | int',
+\ 'yp_err_string(': 'int errorcode | string',
+\ 'yp_first(': 'string domain, string map | array',
+\ 'yp_get_default_domain(': 'void  | string',
+\ 'yp_master(': 'string domain, string map | string',
+\ 'yp_match(': 'string domain, string map, string key | string',
+\ 'yp_next(': 'string domain, string map, string key | array',
+\ 'yp_order(': 'string domain, string map | int',
+\ 'zend_logo_guid(': 'void  | string',
+\ 'zend_version(': 'void  | string',
+\ 'zip_close(': 'resource zip | void',
+\ 'zip_entry_close(': 'resource zip_entry | void',
+\ 'zip_entry_compressedsize(': 'resource zip_entry | int',
+\ 'zip_entry_compressionmethod(': 'resource zip_entry | string',
+\ 'zip_entry_filesize(': 'resource zip_entry | int',
+\ 'zip_entry_name(': 'resource zip_entry | string',
+\ 'zip_entry_open(': 'resource zip, resource zip_entry [, string mode] | bool',
+\ 'zip_entry_read(': 'resource zip_entry [, int length] | string',
+\ 'zip_open(': 'string filename | resource',
+\ 'zip_read(': 'resource zip | resource',
+\ 'zlib_get_coding_type(': 'void  | string'
+\ }
+" }}}
+" built-in object functions {{{
+let g:php_builtin_object_functions = {
+\ 'ArrayIterator::current(': 'void  | mixed',
+\ 'ArrayIterator::key(': 'void  | mixed',
+\ 'ArrayIterator::next(': 'void  | void',
+\ 'ArrayIterator::rewind(': 'void  | void',
+\ 'ArrayIterator::seek(': 'int position | void',
+\ 'ArrayIterator::valid(': 'void  | bool',
+\ 'ArrayObject::append(': 'mixed newval | void',
+\ 'ArrayObject::__construct(': 'mixed input | ArrayObject',
+\ 'ArrayObject::count(': 'void  | int',
+\ 'ArrayObject::getIterator(': 'void  | ArrayIterator',
+\ 'ArrayObject::offsetExists(': 'mixed index | bool',
+\ 'ArrayObject::offsetGet(': 'mixed index | bool',
+\ 'ArrayObject::offsetSet(': 'mixed index, mixed newval | void',
+\ 'ArrayObject::offsetUnset(': 'mixed index | void',
+\ 'CachingIterator::hasNext(': 'void  | bool',
+\ 'CachingIterator::next(': 'void  | void',
+\ 'CachingIterator::rewind(': 'void  | void',
+\ 'CachingIterator::__toString(': 'void  | string',
+\ 'CachingIterator::valid(': 'void  | bool',
+\ 'CachingRecursiveIterator::getChildren(': 'void  | CachingRecursiveIterator',
+\ 'CachingRecursiveIterator::hasChildren(': 'void  | bolean',
+\ 'DirectoryIterator::__construct(': 'string path | DirectoryIterator',
+\ 'DirectoryIterator::current(': 'void  | DirectoryIterator',
+\ 'DirectoryIterator::getATime(': 'void  | int',
+\ 'DirectoryIterator::getChildren(': 'void  | RecursiveDirectoryIterator',
+\ 'DirectoryIterator::getCTime(': 'void  | int',
+\ 'DirectoryIterator::getFilename(': 'void  | string',
+\ 'DirectoryIterator::getGroup(': 'void  | int',
+\ 'DirectoryIterator::getInode(': 'void  | int',
+\ 'DirectoryIterator::getMTime(': 'void  | int',
+\ 'DirectoryIterator::getOwner(': 'void  | int',
+\ 'DirectoryIterator::getPath(': 'void  | string',
+\ 'DirectoryIterator::getPathname(': 'void  | string',
+\ 'DirectoryIterator::getPerms(': 'void  | int',
+\ 'DirectoryIterator::getSize(': 'void  | int',
+\ 'DirectoryIterator::getType(': 'void  | string',
+\ 'DirectoryIterator::isDir(': 'void  | bool',
+\ 'DirectoryIterator::isDot(': 'void  | bool',
+\ 'DirectoryIterator::isExecutable(': 'void  | bool',
+\ 'DirectoryIterator::isFile(': 'void  | bool',
+\ 'DirectoryIterator::isLink(': 'void  | bool',
+\ 'DirectoryIterator::isReadable(': 'void  | bool',
+\ 'DirectoryIterator::isWritable(': 'void  | bool',
+\ 'DirectoryIterator::key(': 'void  | string',
+\ 'DirectoryIterator::next(': 'void  | void',
+\ 'DirectoryIterator::rewind(': 'void  | void',
+\ 'DirectoryIterator::valid(': 'void  | string',
+\ 'FilterIterator::current(': 'void  | mixed',
+\ 'FilterIterator::getInnerIterator(': 'void  | Iterator',
+\ 'FilterIterator::key(': 'void  | mixed',
+\ 'FilterIterator::next(': 'void  | void',
+\ 'FilterIterator::rewind(': 'void  | void',
+\ 'FilterIterator::valid(': 'void  | bool',
+\ 'LimitIterator::getPosition(': 'void  | int',
+\ 'LimitIterator::next(': 'void  | void',
+\ 'LimitIterator::rewind(': 'void  | void',
+\ 'LimitIterator::seek(': 'int position | void',
+\ 'LimitIterator::valid(': 'void  | bool',
+\ 'Memcache::add(': 'string key, mixed var [, int flag [, int expire]] | bool',
+\ 'Memcache::addServer(': 'string host [, int port [, bool persistent [, int weight [, int timeout [, int retry_interval]]]]] | bool',
+\ 'Memcache::close(': 'void  | bool',
+\ 'Memcache::connect(': 'string host [, int port [, int timeout]] | bool',
+\ 'Memcache::decrement(': 'string key [, int value] | int',
+\ 'Memcache::delete(': 'string key [, int timeout] | bool',
+\ 'Memcache::flush(': 'void  | bool',
+\ 'Memcache::getExtendedStats(': 'void  | array',
+\ 'Memcache::get(': 'string key | string',
+\ 'Memcache::getStats(': 'void  | array',
+\ 'Memcache::getVersion(': 'void  | string',
+\ 'Memcache::increment(': 'string key [, int value] | int',
+\ 'Memcache::pconnect(': 'string host [, int port [, int timeout]] | bool',
+\ 'Memcache::replace(': 'string key, mixed var [, int flag [, int expire]] | bool',
+\ 'Memcache::setCompressThreshold(': 'int threshold [, float min_savings] | bool',
+\ 'Memcache::set(': 'string key, mixed var [, int flag [, int expire]] | bool',
+\ 'ParentIterator::getChildren(': 'void  | ParentIterator',
+\ 'ParentIterator::hasChildren(': 'void  | bool',
+\ 'ParentIterator::next(': 'void  | void',
+\ 'ParentIterator::rewind(': 'void  | void',
+\ 'PDO::beginTransaction(': 'void  | bool',
+\ 'PDO::commit(': 'void  | bool',
+\ 'PDO::__construct(': 'string dsn [, string username [, string password [, array driver_options]]] | PDO',
+\ 'PDO::errorCode(': 'void  | string',
+\ 'PDO::errorInfo(': 'void  | array',
+\ 'PDO::exec(': 'string statement | int',
+\ 'PDO::getAttribute(': 'int attribute | mixed',
+\ 'PDO::getAvailableDrivers(': 'void  | array',
+\ 'PDO::lastInsertId(': '[string name] | string',
+\ 'PDO::prepare(': 'string statement [, array driver_options] | PDOStatement',
+\ 'PDO::query(': 'string statement | PDOStatement',
+\ 'PDO::quote(': 'string string [, int parameter_type] | string',
+\ 'PDO::rollBack(': 'void  | bool',
+\ 'PDO::setAttribute(': 'int attribute, mixed value | bool',
+\ 'PDO::sqliteCreateAggregate(': 'string function_name, callback step_func, callback finalize_func [, int num_args] | bool',
+\ 'PDO::sqliteCreateFunction(': 'string function_name, callback callback [, int num_args] | bool',
+\ 'PDOStatement::bindColumn(': 'mixed column, mixed &#38;param [, int type] | bool',
+\ 'PDOStatement::bindParam(': 'mixed parameter, mixed &#38;variable [, int data_type [, int length [, mixed driver_options]]] | bool',
+\ 'PDOStatement::bindValue(': 'mixed parameter, mixed value [, int data_type] | bool',
+\ 'PDOStatement::closeCursor(': 'void  | bool',
+\ 'PDOStatement::columnCount(': 'void  | int',
+\ 'PDOStatement::errorCode(': 'void  | string',
+\ 'PDOStatement::errorInfo(': 'void  | array',
+\ 'PDOStatement::execute(': '[array input_parameters] | bool',
+\ 'PDOStatement::fetchAll(': '[int fetch_style [, int column_index]] | array',
+\ 'PDOStatement::fetchColumn(': '[int column_number] | string',
+\ 'PDOStatement::fetch(': '[int fetch_style [, int cursor_orientation [, int cursor_offset]]] | mixed',
+\ 'PDOStatement::fetchObject(': '[string class_name [, array ctor_args]] | mixed',
+\ 'PDOStatement::getAttribute(': 'int attribute | mixed',
+\ 'PDOStatement::getColumnMeta(': 'int column | mixed',
+\ 'PDOStatement::nextRowset(': 'void  | bool',
+\ 'PDOStatement::rowCount(': 'void  | int',
+\ 'PDOStatement::setAttribute(': 'int attribute, mixed value | bool',
+\ 'PDOStatement::setFetchMode(': 'int mode | bool',
+\ 'Rar::extract(': 'string dir [, string filepath] | bool',
+\ 'Rar::getAttr(': 'void  | int',
+\ 'Rar::getCrc(': 'void  | int',
+\ 'Rar::getFileTime(': 'void  | string',
+\ 'Rar::getHostOs(': 'void  | int',
+\ 'Rar::getMethod(': 'void  | int',
+\ 'Rar::getName(': 'void  | string',
+\ 'Rar::getPackedSize(': 'void  | int',
+\ 'Rar::getUnpackedSize(': 'void  | int',
+\ 'Rar::getVersion(': 'void  | int',
+\ 'RecursiveDirectoryIterator::getChildren(': 'void  | object',
+\ 'RecursiveDirectoryIterator::hasChildren(': '[bool allow_links] | bool',
+\ 'RecursiveDirectoryIterator::key(': 'void  | string',
+\ 'RecursiveDirectoryIterator::next(': 'void  | void',
+\ 'RecursiveDirectoryIterator::rewind(': 'void  | void',
+\ 'RecursiveIteratorIterator::current(': 'void  | mixed',
+\ 'RecursiveIteratorIterator::getDepth(': 'void  | int',
+\ 'RecursiveIteratorIterator::getSubIterator(': 'void  | RecursiveIterator',
+\ 'RecursiveIteratorIterator::key(': 'void  | mixed',
+\ 'RecursiveIteratorIterator::next(': 'void  | void',
+\ 'RecursiveIteratorIterator::rewind(': 'void  | void',
+\ 'RecursiveIteratorIterator::valid(': 'void  | bolean',
+\ 'SDO_DAS_ChangeSummary::beginLogging(': 'void  | void',
+\ 'SDO_DAS_ChangeSummary::endLogging(': 'void  | void',
+\ 'SDO_DAS_ChangeSummary::getChangedDataObjects(': 'void  | SDO_List',
+\ 'SDO_DAS_ChangeSummary::getChangeType(': 'SDO_DataObject dataObject | int',
+\ 'SDO_DAS_ChangeSummary::getOldContainer(': 'SDO_DataObject data_object | SDO_DataObject',
+\ 'SDO_DAS_ChangeSummary::getOldValues(': 'SDO_DataObject data_object | SDO_List',
+\ 'SDO_DAS_ChangeSummary::isLogging(': 'void  | bool',
+\ 'SDO_DAS_DataFactory::addPropertyToType(': 'string parent_type_namespace_uri, string parent_type_name, string property_name, string type_namespace_uri, string type_name [, array options] | void',
+\ 'SDO_DAS_DataFactory::addType(': 'string type_namespace_uri, string type_name [, array options] | void',
+\ 'SDO_DAS_DataFactory::getDataFactory(': 'void  | SDO_DAS_DataFactory',
+\ 'SDO_DAS_DataObject::getChangeSummary(': 'void  | SDO_DAS_ChangeSummary',
+\ 'SDO_DAS_Relational::applyChanges(': 'PDO database_handle, SDODataObject root_data_object | void',
+\ 'SDO_DAS_Relational::__construct(': 'array database_metadata [, string application_root_type [, array SDO_containment_references_metadata]] | SDO_DAS_Relational',
+\ 'SDO_DAS_Relational::createRootDataObject(': 'void  | SDODataObject',
+\ 'SDO_DAS_Relational::executePreparedQuery(': 'PDO database_handle, PDOStatement prepared_statement, array value_list [, array column_specifier] | SDODataObject',
+\ 'SDO_DAS_Relational::executeQuery(': 'PDO database_handle, string SQL_statement [, array column_specifier] | SDODataObject',
+\ 'SDO_DAS_Setting::getListIndex(': 'void  | int',
+\ 'SDO_DAS_Setting::getPropertyIndex(': 'void  | int',
+\ 'SDO_DAS_Setting::getPropertyName(': 'void  | string',
+\ 'SDO_DAS_Setting::getValue(': 'void  | mixed',
+\ 'SDO_DAS_Setting::isSet(': 'void  | bool',
+\ 'SDO_DAS_XML::addTypes(': 'string xsd_file | void',
+\ 'SDO_DAS_XML::createDataObject(': 'string namespace_uri, string type_name | SDO_DataObject',
+\ 'SDO_DAS_XML::createDocument(': '[string document_element_name] | SDO_DAS_XML_Document',
+\ 'SDO_DAS_XML::create(': '[string xsd_file] | SDO_DAS_XML',
+\ 'SDO_DAS_XML_Document::getRootDataObject(': 'void  | SDO_DataObject',
+\ 'SDO_DAS_XML_Document::getRootElementName(': 'void  | string',
+\ 'SDO_DAS_XML_Document::getRootElementURI(': 'void  | string',
+\ 'SDO_DAS_XML_Document::setEncoding(': 'string encoding | void',
+\ 'SDO_DAS_XML_Document::setXMLDeclaration(': 'bool xmlDeclatation | void',
+\ 'SDO_DAS_XML_Document::setXMLVersion(': 'string xmlVersion | void',
+\ 'SDO_DAS_XML::loadFile(': 'string xml_file | SDO_XMLDocument',
+\ 'SDO_DAS_XML::loadString(': 'string xml_string | SDO_DAS_XML_Document',
+\ 'SDO_DAS_XML::saveFile(': 'SDO_XMLDocument xdoc, string xml_file [, int indent] | void',
+\ 'SDO_DAS_XML::saveString(': 'SDO_XMLDocument xdoc [, int indent] | string',
+\ 'SDO_DataFactory::create(': 'string type_namespace_uri, string type_name | void',
+\ 'SDO_DataObject::clear(': 'void  | void',
+\ 'SDO_DataObject::createDataObject(': 'mixed identifier | SDO_DataObject',
+\ 'SDO_DataObject::getContainer(': 'void  | SDO_DataObject',
+\ 'SDO_DataObject::getSequence(': 'void  | SDO_Sequence',
+\ 'SDO_DataObject::getTypeName(': 'void  | string',
+\ 'SDO_DataObject::getTypeNamespaceURI(': 'void  | string',
+\ 'SDO_Exception::getCause(': 'void  | mixed',
+\ 'SDO_List::insert(': 'mixed value [, int index] | void',
+\ 'SDO_Model_Property::getContainingType(': 'void  | SDO_Model_Type',
+\ 'SDO_Model_Property::getDefault(': 'void  | mixed',
+\ 'SDO_Model_Property::getName(': 'void  | string',
+\ 'SDO_Model_Property::getType(': 'void  | SDO_Model_Type',
+\ 'SDO_Model_Property::isContainment(': 'void  | bool',
+\ 'SDO_Model_Property::isMany(': 'void  | bool',
+\ 'SDO_Model_ReflectionDataObject::__construct(': 'SDO_DataObject data_object | SDO_Model_ReflectionDataObject',
+\ 'SDO_Model_ReflectionDataObject::export(': 'SDO_Model_ReflectionDataObject rdo [, bool return] | mixed',
+\ 'SDO_Model_ReflectionDataObject::getContainmentProperty(': 'void  | SDO_Model_Property',
+\ 'SDO_Model_ReflectionDataObject::getInstanceProperties(': 'void  | array',
+\ 'SDO_Model_ReflectionDataObject::getType(': 'void  | SDO_Model_Type',
+\ 'SDO_Model_Type::getBaseType(': 'void  | SDO_Model_Type',
+\ 'SDO_Model_Type::getName(': 'void  | string',
+\ 'SDO_Model_Type::getNamespaceURI(': 'void  | string',
+\ 'SDO_Model_Type::getProperties(': 'void  | array',
+\ 'SDO_Model_Type::getProperty(': 'mixed identifier | SDO_Model_Property',
+\ 'SDO_Model_Type::isAbstractType(': 'void  | bool',
+\ 'SDO_Model_Type::isDataType(': 'void  | bool',
+\ 'SDO_Model_Type::isInstance(': 'SDO_DataObject data_object | bool',
+\ 'SDO_Model_Type::isOpenType(': 'void  | bool',
+\ 'SDO_Model_Type::isSequencedType(': 'void  | bool',
+\ 'SDO_Sequence::getProperty(': 'int sequence_index | SDO_Model_Property',
+\ 'SDO_Sequence::insert(': 'mixed value [, int sequenceIndex [, mixed propertyIdentifier]] | void',
+\ 'SDO_Sequence::move(': 'int toIndex, int fromIndex | void',
+\ 'SimpleXMLIterator::current(': 'void  | mixed',
+\ 'SimpleXMLIterator::getChildren(': 'void  | object',
+\ 'SimpleXMLIterator::hasChildren(': 'void  | bool',
+\ 'SimpleXMLIterator::key(': 'void  | mixed',
+\ 'SimpleXMLIterator::next(': 'void  | void',
+\ 'SimpleXMLIterator::rewind(': 'void  | void',
+\ 'SimpleXMLIterator::valid(': 'void  | bool',
+\ 'SWFButton::addASound(': 'SWFSound sound, int flags | SWFSoundInstance',
+\ 'SWFButton::setMenu(': 'int flag | void',
+\ 'SWFDisplayItem::addAction(': 'SWFAction action, int flags | void',
+\ 'SWFDisplayItem::endMask(': 'void  | void',
+\ 'SWFDisplayItem::getRot(': 'void  | float',
+\ 'SWFDisplayItem::getX(': 'void  | float',
+\ 'SWFDisplayItem::getXScale(': 'void  | float',
+\ 'SWFDisplayItem::getXSkew(': 'void  | float',
+\ 'SWFDisplayItem::getY(': 'void  | float',
+\ 'SWFDisplayItem::getYScale(': 'void  | float',
+\ 'SWFDisplayItem::getYSkew(': 'void  | float',
+\ 'SWFDisplayItem::setMaskLevel(': 'int level | void',
+\ 'SWFDisplayItem::setMatrix(': 'float a, float b, float c, float d, float x, float y | void',
+\ 'SWFFontChar::addChars(': 'string char | void',
+\ 'SWFFontChar::addUTF8Chars(': 'string char | void',
+\ 'SWFFont::getAscent(': 'void  | float',
+\ 'SWFFont::getDescent(': 'void  | float',
+\ 'SWFFont::getLeading(': 'void  | float',
+\ 'SWFFont::getShape(': 'int code | string',
+\ 'SWFFont::getUTF8Width(': 'string string | float',
+\ 'SWFMovie::addExport(': 'SWFCharacter char, string name | void',
+\ 'SWFMovie::addFont(': 'SWFFont font | SWFFontChar',
+\ 'SWFMovie::importChar(': 'string libswf, string name | SWFSprite',
+\ 'SWFMovie::importFont(': 'string libswf, string name | SWFFontChar',
+\ 'SWFMovie::labelFrame(': 'string label | void',
+\ 'SWFMovie::saveToFile(': 'stream x [, int compression] | int',
+\ 'SWFMovie::startSound(': 'SWFSound sound | SWFSoundInstance',
+\ 'SWFMovie::stopSound(': 'SWFSound sound | void',
+\ 'SWFMovie::writeExports(': 'void  | void',
+\ 'SWFShape::drawArc(': 'float r, float startAngle, float endAngle | void',
+\ 'SWFShape::drawCircle(': 'float r | void',
+\ 'SWFShape::drawCubic(': 'float bx, float by, float cx, float cy, float dx, float dy | int',
+\ 'SWFShape::drawCubicTo(': 'float bx, float by, float cx, float cy, float dx, float dy | int',
+\ 'SWFShape::drawGlyph(': 'SWFFont font, string character [, int size] | void',
+\ 'SWFSoundInstance::loopCount(': 'int point | void',
+\ 'SWFSoundInstance::loopInPoint(': 'int point | void',
+\ 'SWFSoundInstance::loopOutPoint(': 'int point | void',
+\ 'SWFSoundInstance::noMultiple(': 'void  | void',
+\ 'SWFSprite::labelFrame(': 'string label | void',
+\ 'SWFSprite::startSound(': 'SWFSound sound | SWFSoundInstance',
+\ 'SWFSprite::stopSound(': 'SWFSound sound | void',
+\ 'SWFText::addUTF8String(': 'string text | void',
+\ 'SWFTextField::addChars(': 'string chars | void',
+\ 'SWFTextField::setPadding(': 'float padding | void',
+\ 'SWFText::getAscent(': 'void  | float',
+\ 'SWFText::getDescent(': 'void  | float',
+\ 'SWFText::getLeading(': 'void  | float',
+\ 'SWFText::getUTF8Width(': 'string string | float',
+\ 'SWFVideoStream::getNumFrames(': 'void  | int',
+\ 'SWFVideoStream::setDimension(': 'int x, int y | void',
+\ 'tidy::__construct(': '[string filename [, mixed config [, string encoding [, bool use_include_path]]]] | tidy'
+\ }
+			" }}}
+" Add control structures (they are outside regular pattern of PHP functions)
+let php_control = {
+			\ 'include(': 'string filename | resource',
+			\ 'include_once(': 'string filename | resource',
+			\ 'require(': 'string filename | resource',
+			\ 'require_once(': 'string filename | resource',
+			\ }
+call extend(g:php_builtin_functions, php_control)
+endfunction
+" }}}
+" vim:set foldmethod=marker:
--- /dev/null
+++ b/lib/vimfiles/autoload/pythoncomplete.vim
@@ -1,0 +1,599 @@
+"pythoncomplete.vim - Omni Completion for python
+" Maintainer: Aaron Griffin <aaronmgriffin@gmail.com>
+" Version: 0.7
+" Last Updated: 19 Oct 2006
+"
+" Changes
+" TODO:
+" User defined docstrings aren't handled right...
+" 'info' item output can use some formatting work
+" Add an "unsafe eval" mode, to allow for return type evaluation
+" Complete basic syntax along with import statements
+"   i.e. "import url<c-x,c-o>"
+" Continue parsing on invalid line??
+"
+" v 0.7
+"   * Fixed function list sorting (_ and __ at the bottom)
+"   * Removed newline removal from docs.  It appears vim handles these better in
+"   recent patches
+"
+" v 0.6:
+"   * Fixed argument completion
+"   * Removed the 'kind' completions, as they are better indicated
+"   with real syntax
+"   * Added tuple assignment parsing (whoops, that was forgotten)
+"   * Fixed import handling when flattening scope
+"
+" v 0.5:
+" Yeah, I skipped a version number - 0.4 was never public.
+"  It was a bugfix version on top of 0.3.  This is a complete
+"  rewrite.
+"
+
+if !has('python')
+    echo "Error: Required vim compiled with +python"
+    finish
+endif
+
+function! pythoncomplete#Complete(findstart, base)
+    "findstart = 1 when we need to get the text length
+    if a:findstart == 1
+        let line = getline('.')
+        let idx = col('.')
+        while idx > 0
+            let idx -= 1
+            let c = line[idx]
+            if c =~ '\w'
+                continue
+            elseif ! c =~ '\.'
+                let idx = -1
+                break
+            else
+                break
+            endif
+        endwhile
+
+        return idx
+    "findstart = 0 when we need to return the list of completions
+    else
+        "vim no longer moves the cursor upon completion... fix that
+        let line = getline('.')
+        let idx = col('.')
+        let cword = ''
+        while idx > 0
+            let idx -= 1
+            let c = line[idx]
+            if c =~ '\w' || c =~ '\.' || c == '('
+                let cword = c . cword
+                continue
+            elseif strlen(cword) > 0 || idx == 0
+                break
+            endif
+        endwhile
+        execute "python vimcomplete('" . cword . "', '" . a:base . "')"
+        return g:pythoncomplete_completions
+    endif
+endfunction
+
+function! s:DefPython()
+python << PYTHONEOF
+import sys, tokenize, cStringIO, types
+from token import NAME, DEDENT, NEWLINE, STRING
+
+debugstmts=[]
+def dbg(s): debugstmts.append(s)
+def showdbg():
+    for d in debugstmts: print "DBG: %s " % d
+
+def vimcomplete(context,match):
+    global debugstmts
+    debugstmts = []
+    try:
+        import vim
+        def complsort(x,y):
+            try:
+                xa = x['abbr']
+                ya = y['abbr']
+                if xa[0] == '_':
+                    if xa[1] == '_' and ya[0:2] == '__':
+                        return xa > ya
+                    elif ya[0:2] == '__':
+                        return -1
+                    elif y[0] == '_':
+                        return xa > ya
+                    else:
+                        return 1
+                elif ya[0] == '_':
+                    return -1
+                else:
+                   return xa > ya
+            except:
+                return 0
+        cmpl = Completer()
+        cmpl.evalsource('\n'.join(vim.current.buffer),vim.eval("line('.')"))
+        all = cmpl.get_completions(context,match)
+        all.sort(complsort)
+        dictstr = '['
+        # have to do this for double quoting
+        for cmpl in all:
+            dictstr += '{'
+            for x in cmpl: dictstr += '"%s":"%s",' % (x,cmpl[x])
+            dictstr += '"icase":0},'
+        if dictstr[-1] == ',': dictstr = dictstr[:-1]
+        dictstr += ']'
+        #dbg("dict: %s" % dictstr)
+        vim.command("silent let g:pythoncomplete_completions = %s" % dictstr)
+        #dbg("Completion dict:\n%s" % all)
+    except vim.error:
+        dbg("VIM Error: %s" % vim.error)
+
+class Completer(object):
+    def __init__(self):
+       self.compldict = {}
+       self.parser = PyParser()
+
+    def evalsource(self,text,line=0):
+        sc = self.parser.parse(text,line)
+        src = sc.get_code()
+        dbg("source: %s" % src)
+        try: exec(src) in self.compldict
+        except: dbg("parser: %s, %s" % (sys.exc_info()[0],sys.exc_info()[1]))
+        for l in sc.locals:
+            try: exec(l) in self.compldict
+            except: dbg("locals: %s, %s [%s]" % (sys.exc_info()[0],sys.exc_info()[1],l))
+
+    def _cleanstr(self,doc):
+        return doc.replace('"',' ').replace("'",' ')
+
+    def get_arguments(self,func_obj):
+        def _ctor(obj):
+            try: return class_ob.__init__.im_func
+            except AttributeError:
+                for base in class_ob.__bases__:
+                    rc = _find_constructor(base)
+                    if rc is not None: return rc
+            return None
+
+        arg_offset = 1
+        if type(func_obj) == types.ClassType: func_obj = _ctor(func_obj)
+        elif type(func_obj) == types.MethodType: func_obj = func_obj.im_func
+        else: arg_offset = 0
+        
+        arg_text=''
+        if type(func_obj) in [types.FunctionType, types.LambdaType]:
+            try:
+                cd = func_obj.func_code
+                real_args = cd.co_varnames[arg_offset:cd.co_argcount]
+                defaults = func_obj.func_defaults or ''
+                defaults = map(lambda name: "=%s" % name, defaults)
+                defaults = [""] * (len(real_args)-len(defaults)) + defaults
+                items = map(lambda a,d: a+d, real_args, defaults)
+                if func_obj.func_code.co_flags & 0x4:
+                    items.append("...")
+                if func_obj.func_code.co_flags & 0x8:
+                    items.append("***")
+                arg_text = (','.join(items)) + ')'
+
+            except:
+                dbg("arg completion: %s: %s" % (sys.exc_info()[0],sys.exc_info()[1]))
+                pass
+        if len(arg_text) == 0:
+            # The doc string sometimes contains the function signature
+            #  this works for alot of C modules that are part of the
+            #  standard library
+            doc = func_obj.__doc__
+            if doc:
+                doc = doc.lstrip()
+                pos = doc.find('\n')
+                if pos > 0:
+                    sigline = doc[:pos]
+                    lidx = sigline.find('(')
+                    ridx = sigline.find(')')
+                    if lidx > 0 and ridx > 0:
+                        arg_text = sigline[lidx+1:ridx] + ')'
+        if len(arg_text) == 0: arg_text = ')'
+        return arg_text
+
+    def get_completions(self,context,match):
+        dbg("get_completions('%s','%s')" % (context,match))
+        stmt = ''
+        if context: stmt += str(context)
+        if match: stmt += str(match)
+        try:
+            result = None
+            all = {}
+            ridx = stmt.rfind('.')
+            if len(stmt) > 0 and stmt[-1] == '(':
+                result = eval(_sanitize(stmt[:-1]), self.compldict)
+                doc = result.__doc__
+                if doc == None: doc = ''
+                args = self.get_arguments(result)
+                return [{'word':self._cleanstr(args),'info':self._cleanstr(doc)}]
+            elif ridx == -1:
+                match = stmt
+                all = self.compldict
+            else:
+                match = stmt[ridx+1:]
+                stmt = _sanitize(stmt[:ridx])
+                result = eval(stmt, self.compldict)
+                all = dir(result)
+
+            dbg("completing: stmt:%s" % stmt)
+            completions = []
+
+            try: maindoc = result.__doc__
+            except: maindoc = ' '
+            if maindoc == None: maindoc = ' '
+            for m in all:
+                if m == "_PyCmplNoType": continue #this is internal
+                try:
+                    dbg('possible completion: %s' % m)
+                    if m.find(match) == 0:
+                        if result == None: inst = all[m]
+                        else: inst = getattr(result,m)
+                        try: doc = inst.__doc__
+                        except: doc = maindoc
+                        typestr = str(inst)
+                        if doc == None or doc == '': doc = maindoc
+
+                        wrd = m[len(match):]
+                        c = {'word':wrd, 'abbr':m,  'info':self._cleanstr(doc)}
+                        if "function" in typestr:
+                            c['word'] += '('
+                            c['abbr'] += '(' + self._cleanstr(self.get_arguments(inst))
+                        elif "method" in typestr:
+                            c['word'] += '('
+                            c['abbr'] += '(' + self._cleanstr(self.get_arguments(inst))
+                        elif "module" in typestr:
+                            c['word'] += '.'
+                        elif "class" in typestr:
+                            c['word'] += '('
+                            c['abbr'] += '('
+                        completions.append(c)
+                except:
+                    i = sys.exc_info()
+                    dbg("inner completion: %s,%s [stmt='%s']" % (i[0],i[1],stmt))
+            return completions
+        except:
+            i = sys.exc_info()
+            dbg("completion: %s,%s [stmt='%s']" % (i[0],i[1],stmt))
+            return []
+
+class Scope(object):
+    def __init__(self,name,indent):
+        self.subscopes = []
+        self.docstr = ''
+        self.locals = []
+        self.parent = None
+        self.name = name
+        self.indent = indent
+
+    def add(self,sub):
+        #print 'push scope: [%s@%s]' % (sub.name,sub.indent)
+        sub.parent = self
+        self.subscopes.append(sub)
+        return sub
+
+    def doc(self,str):
+        """ Clean up a docstring """
+        d = str.replace('\n',' ')
+        d = d.replace('\t',' ')
+        while d.find('  ') > -1: d = d.replace('  ',' ')
+        while d[0] in '"\'\t ': d = d[1:]
+        while d[-1] in '"\'\t ': d = d[:-1]
+        self.docstr = d
+
+    def local(self,loc):
+        if not self._hasvaralready(loc):
+            self.locals.append(loc)
+
+    def copy_decl(self,indent=0):
+        """ Copy a scope's declaration only, at the specified indent level - not local variables """
+        return Scope(self.name,indent)
+
+    def _hasvaralready(self,test):
+        "Convienance function... keep out duplicates"
+        if test.find('=') > -1:
+            var = test.split('=')[0].strip()
+            for l in self.locals:
+                if l.find('=') > -1 and var == l.split('=')[0].strip():
+                    return True
+        return False
+
+    def get_code(self):
+        # we need to start with this, to fix up broken completions
+        # hopefully this name is unique enough...
+        str = '"""'+self.docstr+'"""\n'
+        for l in self.locals:
+            if l.startswith('import'): str += l+'\n'
+        str += 'class _PyCmplNoType:\n    def __getattr__(self,name):\n        return None\n'
+        for sub in self.subscopes:
+            str += sub.get_code()
+        for l in self.locals:
+            if not l.startswith('import'): str += l+'\n'
+
+        return str
+
+    def pop(self,indent):
+        #print 'pop scope: [%s] to [%s]' % (self.indent,indent)
+        outer = self
+        while outer.parent != None and outer.indent >= indent:
+            outer = outer.parent
+        return outer
+
+    def currentindent(self):
+        #print 'parse current indent: %s' % self.indent
+        return '    '*self.indent
+
+    def childindent(self):
+        #print 'parse child indent: [%s]' % (self.indent+1)
+        return '    '*(self.indent+1)
+
+class Class(Scope):
+    def __init__(self, name, supers, indent):
+        Scope.__init__(self,name,indent)
+        self.supers = supers
+    def copy_decl(self,indent=0):
+        c = Class(self.name,self.supers,indent)
+        for s in self.subscopes:
+            c.add(s.copy_decl(indent+1))
+        return c
+    def get_code(self):
+        str = '%sclass %s' % (self.currentindent(),self.name)
+        if len(self.supers) > 0: str += '(%s)' % ','.join(self.supers)
+        str += ':\n'
+        if len(self.docstr) > 0: str += self.childindent()+'"""'+self.docstr+'"""\n'
+        if len(self.subscopes) > 0:
+            for s in self.subscopes: str += s.get_code()
+        else:
+            str += '%spass\n' % self.childindent()
+        return str
+
+
+class Function(Scope):
+    def __init__(self, name, params, indent):
+        Scope.__init__(self,name,indent)
+        self.params = params
+    def copy_decl(self,indent=0):
+        return Function(self.name,self.params,indent)
+    def get_code(self):
+        str = "%sdef %s(%s):\n" % \
+            (self.currentindent(),self.name,','.join(self.params))
+        if len(self.docstr) > 0: str += self.childindent()+'"""'+self.docstr+'"""\n'
+        str += "%spass\n" % self.childindent()
+        return str
+
+class PyParser:
+    def __init__(self):
+        self.top = Scope('global',0)
+        self.scope = self.top
+
+    def _parsedotname(self,pre=None):
+        #returns (dottedname, nexttoken)
+        name = []
+        if pre == None:
+            tokentype, token, indent = self.next()
+            if tokentype != NAME and token != '*':
+                return ('', token)
+        else: token = pre
+        name.append(token)
+        while True:
+            tokentype, token, indent = self.next()
+            if token != '.': break
+            tokentype, token, indent = self.next()
+            if tokentype != NAME: break
+            name.append(token)
+        return (".".join(name), token)
+
+    def _parseimportlist(self):
+        imports = []
+        while True:
+            name, token = self._parsedotname()
+            if not name: break
+            name2 = ''
+            if token == 'as': name2, token = self._parsedotname()
+            imports.append((name, name2))
+            while token != "," and "\n" not in token:
+                tokentype, token, indent = self.next()
+            if token != ",": break
+        return imports
+
+    def _parenparse(self):
+        name = ''
+        names = []
+        level = 1
+        while True:
+            tokentype, token, indent = self.next()
+            if token in (')', ',') and level == 1:
+                names.append(name)
+                name = ''
+            if token == '(':
+                level += 1
+            elif token == ')':
+                level -= 1
+                if level == 0: break
+            elif token == ',' and level == 1:
+                pass
+            else:
+                name += str(token)
+        return names
+
+    def _parsefunction(self,indent):
+        self.scope=self.scope.pop(indent)
+        tokentype, fname, ind = self.next()
+        if tokentype != NAME: return None
+
+        tokentype, open, ind = self.next()
+        if open != '(': return None
+        params=self._parenparse()
+
+        tokentype, colon, ind = self.next()
+        if colon != ':': return None
+
+        return Function(fname,params,indent)
+
+    def _parseclass(self,indent):
+        self.scope=self.scope.pop(indent)
+        tokentype, cname, ind = self.next()
+        if tokentype != NAME: return None
+
+        super = []
+        tokentype, next, ind = self.next()
+        if next == '(':
+            super=self._parenparse()
+        elif next != ':': return None
+
+        return Class(cname,super,indent)
+
+    def _parseassignment(self):
+        assign=''
+        tokentype, token, indent = self.next()
+        if tokentype == tokenize.STRING or token == 'str':  
+            return '""'
+        elif token == '(' or token == 'tuple':
+            return '()'
+        elif token == '[' or token == 'list':
+            return '[]'
+        elif token == '{' or token == 'dict':
+            return '{}'
+        elif tokentype == tokenize.NUMBER:
+            return '0'
+        elif token == 'open' or token == 'file':
+            return 'file'
+        elif token == 'None':
+            return '_PyCmplNoType()'
+        elif token == 'type':
+            return 'type(_PyCmplNoType)' #only for method resolution
+        else:
+            assign += token
+            level = 0
+            while True:
+                tokentype, token, indent = self.next()
+                if token in ('(','{','['):
+                    level += 1
+                elif token in (']','}',')'):
+                    level -= 1
+                    if level == 0: break
+                elif level == 0:
+                    if token in (';','\n'): break
+                    assign += token
+        return "%s" % assign
+
+    def next(self):
+        type, token, (lineno, indent), end, self.parserline = self.gen.next()
+        if lineno == self.curline:
+            #print 'line found [%s] scope=%s' % (line.replace('\n',''),self.scope.name)
+            self.currentscope = self.scope
+        return (type, token, indent)
+
+    def _adjustvisibility(self):
+        newscope = Scope('result',0)
+        scp = self.currentscope
+        while scp != None:
+            if type(scp) == Function:
+                slice = 0
+                #Handle 'self' params
+                if scp.parent != None and type(scp.parent) == Class:
+                    slice = 1
+                    p = scp.params[0]
+                    i = p.find('=')
+                    if i != -1: p = p[:i]
+                    newscope.local('%s = %s' % (scp.params[0],scp.parent.name))
+                for p in scp.params[slice:]:
+                    i = p.find('=')
+                    if i == -1:
+                        newscope.local('%s = _PyCmplNoType()' % p)
+                    else:
+                        newscope.local('%s = %s' % (p[:i],_sanitize(p[i+1])))
+
+            for s in scp.subscopes:
+                ns = s.copy_decl(0)
+                newscope.add(ns)
+            for l in scp.locals: newscope.local(l)
+            scp = scp.parent
+
+        self.currentscope = newscope
+        return self.currentscope
+
+    #p.parse(vim.current.buffer[:],vim.eval("line('.')"))
+    def parse(self,text,curline=0):
+        self.curline = int(curline)
+        buf = cStringIO.StringIO(''.join(text) + '\n')
+        self.gen = tokenize.generate_tokens(buf.readline)
+        self.currentscope = self.scope
+
+        try:
+            freshscope=True
+            while True:
+                tokentype, token, indent = self.next()
+                #dbg( 'main: token=[%s] indent=[%s]' % (token,indent))
+
+                if tokentype == DEDENT or token == "pass":
+                    self.scope = self.scope.pop(indent)
+                elif token == 'def':
+                    func = self._parsefunction(indent)
+                    if func == None:
+                        print "function: syntax error..."
+                        continue
+                    freshscope = True
+                    self.scope = self.scope.add(func)
+                elif token == 'class':
+                    cls = self._parseclass(indent)
+                    if cls == None:
+                        print "class: syntax error..."
+                        continue
+                    freshscope = True
+                    self.scope = self.scope.add(cls)
+                    
+                elif token == 'import':
+                    imports = self._parseimportlist()
+                    for mod, alias in imports:
+                        loc = "import %s" % mod
+                        if len(alias) > 0: loc += " as %s" % alias
+                        self.scope.local(loc)
+                    freshscope = False
+                elif token == 'from':
+                    mod, token = self._parsedotname()
+                    if not mod or token != "import":
+                        print "from: syntax error..."
+                        continue
+                    names = self._parseimportlist()
+                    for name, alias in names:
+                        loc = "from %s import %s" % (mod,name)
+                        if len(alias) > 0: loc += " as %s" % alias
+                        self.scope.local(loc)
+                    freshscope = False
+                elif tokentype == STRING:
+                    if freshscope: self.scope.doc(token)
+                elif tokentype == NAME:
+                    name,token = self._parsedotname(token) 
+                    if token == '=':
+                        stmt = self._parseassignment()
+                        if stmt != None:
+                            self.scope.local("%s = %s" % (name,stmt))
+                    freshscope = False
+        except StopIteration: #thrown on EOF
+            pass
+        except:
+            dbg("parse error: %s, %s @ %s" %
+                (sys.exc_info()[0], sys.exc_info()[1], self.parserline))
+        return self._adjustvisibility()
+
+def _sanitize(str):
+    val = ''
+    level = 0
+    for c in str:
+        if c in ('(','{','['):
+            level += 1
+        elif c in (']','}',')'):
+            level -= 1
+        elif level == 0:
+            val += c
+    return val
+
+sys.path.extend(['.','..'])
+PYTHONEOF
+endfunction
+
+call s:DefPython()
+" vim: set et ts=4:
--- /dev/null
+++ b/lib/vimfiles/autoload/rubycomplete.vim
@@ -1,0 +1,802 @@
+" Vim completion script
+" Language:             Ruby
+" Maintainer:           Mark Guzman <segfault@hasno.info>
+" Info:                 $Id: rubycomplete.vim,v 1.6 2007/05/05 17:17:50 vimboss Exp $
+" URL:                  http://vim-ruby.rubyforge.org
+" Anon CVS:             See above site
+" Release Coordinator:  Doug Kearns <dougkearns@gmail.com>
+" Maintainer Version:   0.8
+" ----------------------------------------------------------------------------
+"
+" Ruby IRB/Complete author: Keiju ISHITSUKA(keiju@ishitsuka.com)
+" ----------------------------------------------------------------------------
+
+" {{{ requirement checks
+if !has('ruby')
+    s:ErrMsg( "Error: Rubycomplete requires vim compiled with +ruby" )
+    s:ErrMsg( "Error: falling back to syntax completion" )
+    " lets fall back to syntax completion
+    setlocal omnifunc=syntaxcomplete#Complete
+    finish
+endif
+
+if version < 700
+    s:ErrMsg( "Error: Required vim >= 7.0" )
+    finish
+endif
+" }}} requirement checks
+
+" {{{ configuration failsafe initialization
+if !exists("g:rubycomplete_rails")
+    let g:rubycomplete_rails = 0
+endif
+
+if !exists("g:rubycomplete_classes_in_global")
+    let g:rubycomplete_classes_in_global = 0
+endif
+
+if !exists("g:rubycomplete_buffer_loading")
+    let g:rubycomplete_classes_in_global = 0
+endif
+
+if !exists("g:rubycomplete_include_object")
+    let g:rubycomplete_include_object = 0
+endif
+
+if !exists("g:rubycomplete_include_objectspace")
+    let g:rubycomplete_include_objectspace = 0
+endif
+" }}} configuration failsafe initialization
+
+" {{{ vim-side support functions
+let s:rubycomplete_debug = 0
+
+function! s:ErrMsg(msg)
+    echohl ErrorMsg
+    echo a:msg
+    echohl None
+endfunction
+
+function! s:dprint(msg)
+    if s:rubycomplete_debug == 1
+        echom a:msg
+    endif
+endfunction
+
+function! s:GetBufferRubyModule(name, ...)
+    if a:0 == 1
+        let [snum,enum] = s:GetBufferRubyEntity(a:name, "module", a:1)
+    else
+        let [snum,enum] = s:GetBufferRubyEntity(a:name, "module")
+    endif
+    return snum . '..' . enum
+endfunction
+
+function! s:GetBufferRubyClass(name, ...)
+    if a:0 >= 1
+        let [snum,enum] = s:GetBufferRubyEntity(a:name, "class", a:1)
+    else
+        let [snum,enum] = s:GetBufferRubyEntity(a:name, "class")
+    endif
+    return snum . '..' . enum
+endfunction
+
+function! s:GetBufferRubySingletonMethods(name)
+endfunction
+
+function! s:GetBufferRubyEntity( name, type, ... )
+    let lastpos = getpos(".")
+    let lastline = lastpos
+    if (a:0 >= 1)
+        let lastline = [ 0, a:1, 0, 0 ]
+        call cursor( a:1, 0 )
+    endif
+
+    let stopline = 1
+
+    let crex = '^\s*\<' . a:type . '\>\s*\<' . a:name . '\>\s*\(<\s*.*\s*\)\?'
+    let [lnum,lcol] = searchpos( crex, 'w' )
+    "let [lnum,lcol] = searchpairpos( crex . '\zs', '', '\(end\|}\)', 'w' )
+
+    if lnum == 0 && lcol == 0
+        call cursor(lastpos[1], lastpos[2])
+        return [0,0]
+    endif
+
+    let curpos = getpos(".")
+    let [enum,ecol] = searchpairpos( crex, '', '\(end\|}\)', 'wr' )
+    call cursor(lastpos[1], lastpos[2])
+
+    if lnum > enum
+        return [0,0]
+    endif
+    " we found a the class def
+    return [lnum,enum]
+endfunction
+
+function! s:IsInClassDef()
+    return s:IsPosInClassDef( line('.') )
+endfunction
+
+function! s:IsPosInClassDef(pos)
+    let [snum,enum] = s:GetBufferRubyEntity( '.*', "class" )
+    let ret = 'nil'
+
+    if snum < a:pos && a:pos < enum
+        let ret = snum . '..' . enum
+    endif
+
+    return ret
+endfunction
+
+function! s:GetRubyVarType(v)
+    let stopline = 1
+    let vtp = ''
+    let pos = getpos('.')
+    let sstr = '^\s*#\s*@var\s*'.a:v.'\>\s\+[^ \t]\+\s*$'
+    let [lnum,lcol] = searchpos(sstr,'nb',stopline)
+    if lnum != 0 && lcol != 0
+        call setpos('.',pos)
+        let str = getline(lnum)
+        let vtp = substitute(str,sstr,'\1','')
+        return vtp
+    endif
+    call setpos('.',pos)
+    let ctors = '\(now\|new\|open\|get_instance'
+    if exists('g:rubycomplete_rails') && g:rubycomplete_rails == 1 && s:rubycomplete_rails_loaded == 1
+        let ctors = ctors.'\|find\|create'
+    else
+    endif
+    let ctors = ctors.'\)'
+
+    let fstr = '=\s*\([^ \t]\+.' . ctors .'\>\|[\[{"''/]\|%[xwQqr][(\[{@]\|[A-Za-z0-9@:\-()\.]\+...\?\|lambda\|&\)'
+    let sstr = ''.a:v.'\>\s*[+\-*/]*'.fstr
+    let [lnum,lcol] = searchpos(sstr,'nb',stopline)
+    if lnum != 0 && lcol != 0
+        let str = matchstr(getline(lnum),fstr,lcol)
+        let str = substitute(str,'^=\s*','','')
+
+        call setpos('.',pos)
+        if str == '"' || str == '''' || stridx(tolower(str), '%q[') != -1
+            return 'String'
+        elseif str == '[' || stridx(str, '%w[') != -1
+            return 'Array'
+        elseif str == '{'
+            return 'Hash'
+        elseif str == '/' || str == '%r{'
+            return 'Regexp'
+        elseif strlen(str) >= 4 && stridx(str,'..') != -1
+            return 'Range'
+        elseif stridx(str, 'lambda') != -1 || str == '&'
+            return 'Proc'
+        elseif strlen(str) > 4
+            let l = stridx(str,'.')
+            return str[0:l-1]
+        end
+        return ''
+    endif
+    call setpos('.',pos)
+    return ''
+endfunction
+
+"}}} vim-side support functions
+
+"{{{ vim-side completion function
+function! rubycomplete#Init()
+    execute "ruby VimRubyCompletion.preload_rails"
+endfunction
+
+function! rubycomplete#Complete(findstart, base)
+     "findstart = 1 when we need to get the text length
+    if a:findstart
+        let line = getline('.')
+        let idx = col('.')
+        while idx > 0
+            let idx -= 1
+            let c = line[idx-1]
+            if c =~ '\w'
+                continue
+            elseif ! c =~ '\.'
+                idx = -1
+                break
+            else
+                break
+            endif
+        endwhile
+
+        return idx
+    "findstart = 0 when we need to return the list of completions
+    else
+        let g:rubycomplete_completions = []
+        execute "ruby VimRubyCompletion.get_completions('" . a:base . "')"
+        return g:rubycomplete_completions
+    endif
+endfunction
+"}}} vim-side completion function
+
+"{{{ ruby-side code
+function! s:DefRuby()
+ruby << RUBYEOF
+# {{{ ruby completion
+
+begin
+    require 'rubygems' # let's assume this is safe...?
+rescue Exception
+    #ignore?
+end
+class VimRubyCompletion
+# {{{ constants
+  @@debug = false
+  @@ReservedWords = [
+        "BEGIN", "END",
+        "alias", "and",
+        "begin", "break",
+        "case", "class",
+        "def", "defined", "do",
+        "else", "elsif", "end", "ensure",
+        "false", "for",
+        "if", "in",
+        "module",
+        "next", "nil", "not",
+        "or",
+        "redo", "rescue", "retry", "return",
+        "self", "super",
+        "then", "true",
+        "undef", "unless", "until",
+        "when", "while",
+        "yield",
+      ]
+
+  @@Operators = [ "%", "&", "*", "**", "+",  "-",  "/",
+        "<", "<<", "<=", "<=>", "==", "===", "=~", ">", ">=", ">>",
+        "[]", "[]=", "^", ]
+# }}} constants
+
+# {{{ buffer analysis magic
+  def load_requires
+    buf = VIM::Buffer.current
+    enum = buf.line_number
+    nums = Range.new( 1, enum )
+    nums.each do |x|
+      ln = buf[x]
+      begin
+        eval( "require %s" % $1 ) if /.*require\s*(.*)$/.match( ln )
+      rescue Exception
+        #ignore?
+      end
+    end
+  end
+
+  def load_buffer_class(name)
+    dprint "load_buffer_class(%s) START" % name
+    classdef = get_buffer_entity(name, 's:GetBufferRubyClass("%s")')
+    return if classdef == nil
+
+    pare = /^\s*class\s*(.*)\s*<\s*(.*)\s*\n/.match( classdef )
+    load_buffer_class( $2 ) if pare != nil  && $2 != name # load parent class if needed
+
+    mixre = /.*\n\s*include\s*(.*)\s*\n/.match( classdef )
+    load_buffer_module( $2 ) if mixre != nil && $2 != name # load mixins if needed
+
+    begin
+      eval classdef
+    rescue Exception
+      VIM::evaluate( "s:ErrMsg( 'Problem loading class \"%s\", was it already completed?' )" % name )
+    end
+    dprint "load_buffer_class(%s) END" % name
+  end
+
+  def load_buffer_module(name)
+    dprint "load_buffer_module(%s) START" % name
+    classdef = get_buffer_entity(name, 's:GetBufferRubyModule("%s")')
+    return if classdef == nil
+
+    begin
+      eval classdef
+    rescue Exception
+      VIM::evaluate( "s:ErrMsg( 'Problem loading module \"%s\", was it already completed?' )" % name )
+    end
+    dprint "load_buffer_module(%s) END" % name
+  end
+
+  def get_buffer_entity(name, vimfun)
+    loading_allowed = VIM::evaluate("exists('g:rubycomplete_buffer_loading') && g:rubycomplete_buffer_loading")
+    return nil if loading_allowed != '1'
+    return nil if /(\"|\')+/.match( name )
+    buf = VIM::Buffer.current
+    nums = eval( VIM::evaluate( vimfun % name ) )
+    return nil if nums == nil
+    return nil if nums.min == nums.max && nums.min == 0
+
+    dprint "get_buffer_entity START"
+    visited = []
+    clscnt = 0
+    bufname = VIM::Buffer.current.name
+    classdef = ""
+    cur_line = VIM::Buffer.current.line_number
+    while (nums != nil && !(nums.min == 0 && nums.max == 0) )
+      dprint "visited: %s" % visited.to_s
+      break if visited.index( nums )
+      visited << nums
+
+      nums.each do |x|
+        if x != cur_line
+          next if x == 0
+          ln = buf[x]
+          if /^\s*(module|class|def|include)\s+/.match(ln)
+            clscnt += 1 if $1 == "class"
+            #dprint "\$1: %s" % $1
+            classdef += "%s\n" % ln
+            classdef += "end\n" if /def\s+/.match(ln)
+            dprint ln
+          end
+        end
+      end
+
+      nm = "%s(::.*)*\", %s, \"" % [ name, nums.last ]
+      nums = eval( VIM::evaluate( vimfun % nm ) )
+      dprint "nm: \"%s\"" % nm
+      dprint "vimfun: %s" % (vimfun % nm)
+      dprint "got nums: %s" % nums.to_s
+    end
+    if classdef.length > 1
+        classdef += "end\n"*clscnt
+        # classdef = "class %s\n%s\nend\n" % [ bufname.gsub( /\/|\\/, "_" ), classdef ]
+    end
+
+    dprint "get_buffer_entity END"
+    dprint "classdef====start"
+    lns = classdef.split( "\n" )
+    lns.each { |x| dprint x }
+    dprint "classdef====end"
+    return classdef
+  end
+
+  def get_var_type( receiver )
+    if /(\"|\')+/.match( receiver )
+      "String"
+    else
+      VIM::evaluate("s:GetRubyVarType('%s')" % receiver)
+    end
+  end
+
+  def dprint( txt )
+    print txt if @@debug
+  end
+
+  def get_buffer_entity_list( type )
+    # this will be a little expensive.
+    loading_allowed = VIM::evaluate("exists('g:rubycomplete_buffer_loading') && g:rubycomplete_buffer_loading")
+    allow_aggressive_load = VIM::evaluate("exists('g:rubycomplete_classes_in_global') && g:rubycomplete_classes_in_global")
+    return [] if allow_aggressive_load != '1' || loading_allowed != '1'
+
+    buf = VIM::Buffer.current
+    eob = buf.length
+    ret = []
+    rg = 1..eob
+    re = eval( "/^\s*%s\s*([A-Za-z0-9_:-]*)(\s*<\s*([A-Za-z0-9_:-]*))?\s*/" % type )
+
+    rg.each do |x|
+      if re.match( buf[x] )
+        next if type == "def" && eval( VIM::evaluate("s:IsPosInClassDef(%s)" % x) ) != nil
+        ret.push $1
+      end
+    end
+
+    return ret
+  end
+
+  def get_buffer_modules
+    return get_buffer_entity_list( "modules" )
+  end
+
+  def get_buffer_methods
+    return get_buffer_entity_list( "def" )
+  end
+
+  def get_buffer_classes
+    return get_buffer_entity_list( "class" )
+  end
+
+
+  def load_rails
+    allow_rails = VIM::evaluate("exists('g:rubycomplete_rails') && g:rubycomplete_rails")
+    return if allow_rails != '1'
+
+    buf_path = VIM::evaluate('expand("%:p")')
+    file_name = VIM::evaluate('expand("%:t")')
+    vim_dir = VIM::evaluate('getcwd()')
+    file_dir = buf_path.gsub( file_name, '' )
+    file_dir.gsub!( /\\/, "/" )
+    vim_dir.gsub!( /\\/, "/" )
+    vim_dir << "/"
+    dirs = [ vim_dir, file_dir ]
+    sdirs = [ "", "./", "../", "../../", "../../../", "../../../../" ]
+    rails_base = nil
+
+    dirs.each do |dir|
+      sdirs.each do |sub|
+        trail = "%s%s" % [ dir, sub ]
+        tcfg = "%sconfig" % trail
+
+        if File.exists?( tcfg )
+          rails_base = trail
+          break
+        end
+      end
+      break if rails_base
+    end
+
+    return if rails_base == nil
+    $:.push rails_base unless $:.index( rails_base )
+
+    rails_config = rails_base + "config/"
+    rails_lib = rails_base + "lib/"
+    $:.push rails_config unless $:.index( rails_config )
+    $:.push rails_lib unless $:.index( rails_lib )
+
+    bootfile = rails_config + "boot.rb"
+    envfile = rails_config + "environment.rb"
+    if File.exists?( bootfile ) && File.exists?( envfile )
+      begin
+        require bootfile
+        require envfile
+        begin
+          require 'console_app'
+          require 'console_with_helpers'
+        rescue Exception
+          dprint "Rails 1.1+ Error %s" % $!
+          # assume 1.0
+        end
+        #eval( "Rails::Initializer.run" ) #not necessary?
+        VIM::command('let s:rubycomplete_rails_loaded = 1')
+        dprint "rails loaded"
+      rescue Exception
+        dprint "Rails Error %s" % $!
+        VIM::evaluate( "s:ErrMsg('Error loading rails environment')" )
+      end
+    end
+  end
+
+  def get_rails_helpers
+    allow_rails = VIM::evaluate("exists('g:rubycomplete_rails') && g:rubycomplete_rails")
+    rails_loaded = VIM::evaluate('s:rubycomplete_rails_loaded')
+    return [] if allow_rails != '1' || rails_loaded != '1'
+
+    buf_path = VIM::evaluate('expand("%:p")')
+    buf_path.gsub!( /\\/, "/" )
+    path_elm = buf_path.split( "/" )
+    dprint "buf_path: %s" % buf_path
+    types = [ "app", "db", "lib", "test", "components", "script" ]
+
+    i = nil
+    ret = []
+    type = nil
+    types.each do |t|
+      i = path_elm.index( t )
+      break if i
+    end
+    type = path_elm[i]
+    type.downcase!
+
+    dprint "type: %s" % type
+    case type
+      when "app"
+        i += 1
+        subtype = path_elm[i]
+        subtype.downcase!
+
+        dprint "subtype: %s" % subtype
+        case subtype
+          when "views"
+            ret += ActionView::Base.instance_methods
+            ret += ActionView::Base.methods
+          when "controllers"
+            ret += ActionController::Base.instance_methods
+            ret += ActionController::Base.methods
+          when "models"
+            ret += ActiveRecord::Base.instance_methods
+            ret += ActiveRecord::Base.methods
+        end
+
+      when "db"
+        ret += ActiveRecord::ConnectionAdapters::SchemaStatements.instance_methods
+        ret += ActiveRecord::ConnectionAdapters::SchemaStatements.methods
+    end
+
+
+    return ret
+  end
+
+  def add_rails_columns( cls )
+    allow_rails = VIM::evaluate("exists('g:rubycomplete_rails') && g:rubycomplete_rails")
+    rails_loaded = VIM::evaluate('s:rubycomplete_rails_loaded')
+    return [] if allow_rails != '1' || rails_loaded != '1'
+
+    begin
+        eval( "#{cls}.establish_connection" )
+        return [] unless eval( "#{cls}.ancestors.include?(ActiveRecord::Base).to_s" )
+        col = eval( "#{cls}.column_names" )
+        return col if col
+    rescue
+        dprint "add_rails_columns err: (cls: %s) %s" % [ cls, $! ]
+        return []
+    end
+    return []
+  end
+
+  def clean_sel(sel, msg)
+    sel.delete_if { |x| x == nil }
+    sel.uniq!
+    sel.grep(/^#{Regexp.quote(msg)}/) if msg != nil
+  end
+
+  def get_rails_view_methods
+    allow_rails = VIM::evaluate("exists('g:rubycomplete_rails') && g:rubycomplete_rails")
+    rails_loaded = VIM::evaluate('s:rubycomplete_rails_loaded')
+    return [] if allow_rails != '1' || rails_loaded != '1'
+
+    buf_path = VIM::evaluate('expand("%:p")')
+    buf_path.gsub!( /\\/, "/" )
+    pelm = buf_path.split( "/" )
+    idx = pelm.index( "views" )
+
+    return [] unless idx
+    idx += 1
+
+    clspl = pelm[idx].camelize.pluralize
+    cls = clspl.singularize
+
+    ret = []
+    begin
+      ret += eval( "#{cls}.instance_methods" )
+      ret += eval( "#{clspl}Helper.instance_methods" )
+    rescue Exception
+      dprint "Error: Unable to load rails view helpers for %s: %s" % [ cls, $! ]
+    end
+
+    return ret
+  end
+# }}} buffer analysis magic
+
+# {{{ main completion code
+  def self.preload_rails
+    a = VimRubyCompletion.new
+    require 'Thread'
+    Thread.new(a) do |b|
+      begin
+      b.load_rails
+      rescue
+      end
+    end
+    a.load_rails
+  rescue
+  end
+
+  def self.get_completions(base)
+    b = VimRubyCompletion.new
+    b.get_completions base
+  end
+
+  def get_completions(base)
+    loading_allowed = VIM::evaluate("exists('g:rubycomplete_buffer_loading') && g:rubycomplete_buffer_loading")
+    if loading_allowed == '1'
+      load_requires
+      load_rails
+    end
+
+    input = VIM::Buffer.current.line
+    cpos = VIM::Window.current.cursor[1] - 1
+    input = input[0..cpos]
+    input += base
+    input.sub!(/.*[ \t\n\"\\'`><=;|&{(]/, '') # Readline.basic_word_break_characters
+    input.sub!(/self\./, '')
+    input.sub!(/.*((\.\.[\[(]?)|([\[(]))/, '')
+
+    dprint 'input %s' % input
+    message = nil
+    receiver = nil
+    methods = []
+    variables = []
+    classes = []
+    constants = []
+
+    case input
+      when /^(\/[^\/]*\/)\.([^.]*)$/ # Regexp
+        receiver = $1
+        message = Regexp.quote($2)
+        methods = Regexp.instance_methods(true)
+
+      when /^([^\]]*\])\.([^.]*)$/ # Array
+        receiver = $1
+        message = Regexp.quote($2)
+        methods = Array.instance_methods(true)
+
+      when /^([^\}]*\})\.([^.]*)$/ # Proc or Hash
+        receiver = $1
+        message = Regexp.quote($2)
+        methods = Proc.instance_methods(true) | Hash.instance_methods(true)
+
+      when /^(:[^:.]*)$/ # Symbol
+        dprint "symbol"
+        if Symbol.respond_to?(:all_symbols)
+          receiver = $1
+          message = $1.sub( /:/, '' )
+          methods = Symbol.all_symbols.collect{|s| s.id2name}
+          methods.delete_if { |c| c.match( /'/ ) }
+        end
+
+      when /^::([A-Z][^:\.\(]*)$/ # Absolute Constant or class methods
+        dprint "const or cls"
+        receiver = $1
+        methods = Object.constants
+        methods.grep(/^#{receiver}/).collect{|e| "::" + e}
+
+      when /^(((::)?[A-Z][^:.\(]*)+)::?([^:.]*)$/ # Constant or class methods
+        receiver = $1
+        message = Regexp.quote($4)
+        dprint "const or cls 2 [recv: \'%s\', msg: \'%s\']" % [ receiver, message ]
+        load_buffer_class( receiver )
+        begin
+          classes = eval("#{receiver}.constants")
+          #methods = eval("#{receiver}.methods")
+        rescue Exception
+          dprint "exception: %s" % $!
+          methods = []
+        end
+        methods.grep(/^#{message}/).collect{|e| receiver + "::" + e}
+
+      when /^(:[^:.]+)\.([^.]*)$/ # Symbol
+        dprint "symbol"
+        receiver = $1
+        message = Regexp.quote($2)
+        methods = Symbol.instance_methods(true)
+
+      when /^([0-9_]+(\.[0-9_]+)?(e[0-9]+)?)\.([^.]*)$/ # Numeric
+        dprint "numeric"
+        receiver = $1
+        message = Regexp.quote($4)
+        begin
+          methods = eval(receiver).methods
+        rescue Exception
+          methods = []
+        end
+
+      when /^(\$[^.]*)$/ #global
+        dprint "global"
+        methods = global_variables.grep(Regexp.new(Regexp.quote($1)))
+
+      when /^((\.?[^.]+)+)\.([^.]*)$/ # variable
+        dprint "variable"
+        receiver = $1
+        message = Regexp.quote($3)
+        load_buffer_class( receiver )
+
+        cv = eval("self.class.constants")
+        vartype = get_var_type( receiver )
+        dprint "vartype: %s" % vartype
+        if vartype != ''
+          load_buffer_class( vartype )
+
+          begin
+            methods = eval("#{vartype}.instance_methods")
+            variables = eval("#{vartype}.instance_variables")
+          rescue Exception
+            dprint "load_buffer_class err: %s" % $!
+          end
+        elsif (cv).include?(receiver)
+          # foo.func and foo is local var.
+          methods = eval("#{receiver}.methods")
+          vartype = receiver
+        elsif /^[A-Z]/ =~ receiver and /\./ !~ receiver
+          vartype = receiver
+          # Foo::Bar.func
+          begin
+            methods = eval("#{receiver}.methods")
+          rescue Exception
+          end
+        else
+          # func1.func2
+          ObjectSpace.each_object(Module){|m|
+            next if m.name != "IRB::Context" and
+              /^(IRB|SLex|RubyLex|RubyToken)/ =~ m.name
+            methods.concat m.instance_methods(false)
+          }
+        end
+        variables += add_rails_columns( "#{vartype}" ) if vartype && vartype.length > 0
+
+      when /^\(?\s*[A-Za-z0-9:^@.%\/+*\(\)]+\.\.\.?[A-Za-z0-9:^@.%\/+*\(\)]+\s*\)?\.([^.]*)/
+        message = $1
+        methods = Range.instance_methods(true)
+
+      when /^\.([^.]*)$/ # unknown(maybe String)
+        message = Regexp.quote($1)
+        methods = String.instance_methods(true)
+
+    else
+      dprint "default/other"
+      inclass = eval( VIM::evaluate("s:IsInClassDef()") )
+
+      if inclass != nil
+        dprint "inclass"
+        classdef = "%s\n" % VIM::Buffer.current[ inclass.min ]
+        found = /^\s*class\s*([A-Za-z0-9_-]*)(\s*<\s*([A-Za-z0-9_:-]*))?\s*\n$/.match( classdef )
+
+        if found != nil
+          receiver = $1
+          message = input
+          load_buffer_class( receiver )
+          begin
+            methods = eval( "#{receiver}.instance_methods" )
+            variables += add_rails_columns( "#{receiver}" )
+          rescue Exception
+            found = nil
+          end
+        end
+      end
+
+      if inclass == nil || found == nil
+        dprint "inclass == nil"
+        methods = get_buffer_methods
+        methods += get_rails_view_methods
+
+        cls_const = Class.constants
+        constants = cls_const.select { |c| /^[A-Z_-]+$/.match( c ) }
+        classes = eval("self.class.constants") - constants
+        classes += get_buffer_classes
+        classes += get_buffer_modules
+
+        include_objectspace = VIM::evaluate("exists('g:rubycomplete_include_objectspace') && g:rubycomplete_include_objectspace")
+        ObjectSpace.each_object(Class) { |cls| classes << cls.to_s } if include_objectspace == "1"
+        message = receiver = input
+      end
+
+      methods += get_rails_helpers
+      methods += Kernel.public_methods
+    end
+
+
+    include_object = VIM::evaluate("exists('g:rubycomplete_include_object') && g:rubycomplete_include_object")
+    methods = clean_sel( methods, message )
+    methods = (methods-Object.instance_methods) if include_object == "0"
+    rbcmeth = (VimRubyCompletion.instance_methods-Object.instance_methods) # lets remove those rubycomplete methods
+    methods = (methods-rbcmeth)
+
+    variables = clean_sel( variables, message )
+    classes = clean_sel( classes, message ) - ["VimRubyCompletion"]
+    constants = clean_sel( constants, message )
+
+    valid = []
+    valid += methods.collect { |m| { :name => m, :type => 'm' } }
+    valid += variables.collect { |v| { :name => v, :type => 'v' } }
+    valid += classes.collect { |c| { :name => c, :type => 't' } }
+    valid += constants.collect { |d| { :name => d, :type => 'd' } }
+    valid.sort! { |x,y| x[:name] <=> y[:name] }
+
+    outp = ""
+
+    rg = 0..valid.length
+    rg.step(150) do |x|
+      stpos = 0+x
+      enpos = 150+x
+      valid[stpos..enpos].each { |c| outp += "{'word':'%s','item':'%s','kind':'%s'}," % [ c[:name], c[:name], c[:type] ] }
+      outp.sub!(/,$/, '')
+
+      VIM::command("call extend(g:rubycomplete_completions, [%s])" % outp)
+      outp = ""
+    end
+  end
+# }}} main completion code
+
+end # VimRubyCompletion
+# }}} ruby completion
+RUBYEOF
+endfunction
+
+let s:rubycomplete_rails_loaded = 0
+
+call s:DefRuby()
+"}}} ruby-side code
+
+
+" vim:tw=78:sw=4:ts=8:et:fdm=marker:ft=vim:norl:
--- /dev/null
+++ b/lib/vimfiles/autoload/spellfile.vim
@@ -1,0 +1,168 @@
+" Vim script to download a missing spell file
+" Maintainer:	Bram Moolenaar <Bram@vim.org>
+" Last Change:	2007 May 08
+
+if !exists('g:spellfile_URL')
+  let g:spellfile_URL = 'ftp://ftp.vim.org/pub/vim/runtime/spell'
+endif
+let s:spellfile_URL = ''    " Start with nothing so that s:donedict is reset.
+
+" This function is used for the spellfile plugin.
+function! spellfile#LoadFile(lang)
+  " If the netrw plugin isn't loaded we silently skip everything.
+  if !exists(":Nread")
+    if &verbose
+      echomsg 'spellfile#LoadFile(): Nread command is not available.'
+    endif
+    return
+  endif
+
+  " If the URL changes we try all files again.
+  if s:spellfile_URL != g:spellfile_URL
+    let s:donedict = {}
+    let s:spellfile_URL = g:spellfile_URL
+  endif
+
+  " I will say this only once!
+  if has_key(s:donedict, a:lang . &enc)
+    if &verbose
+      echomsg 'spellfile#LoadFile(): Tried this language/encoding before.'
+    endif
+    return
+  endif
+  let s:donedict[a:lang . &enc] = 1
+
+  " Find spell directories we can write in.
+  let dirlist = []
+  let dirchoices = '&Cancel'
+  for dir in split(globpath(&rtp, 'spell'), "\n")
+    if filewritable(dir) == 2
+      call add(dirlist, dir)
+      let dirchoices .= "\n&" . len(dirlist)
+    endif
+  endfor
+  if len(dirlist) == 0
+    if &verbose
+      echomsg 'spellfile#LoadFile(): There is no writable spell directory.'
+    endif
+    return
+  endif
+
+  let msg = 'Cannot find spell file for "' . a:lang . '" in ' . &enc
+  let msg .= "\nDo you want me to try downloading it?"
+  if confirm(msg, "&Yes\n&No", 2) == 1
+    let enc = &encoding
+    if enc == 'iso-8859-15'
+      let enc = 'latin1'
+    endif
+    let fname = a:lang . '.' . enc . '.spl'
+
+    " Split the window, read the file into a new buffer.
+    " Remember the buffer number, we check it below.
+    new
+    let newbufnr = winbufnr(0)
+    setlocal bin
+    echo 'Downloading ' . fname . '...'
+    call spellfile#Nread(fname)
+    if getline(2) !~ 'VIMspell'
+      " Didn't work, perhaps there is an ASCII one.
+      " Careful: Nread() may have opened a new window for the error message,
+      " we need to go back to our own buffer and window.
+      if newbufnr != winbufnr(0)
+	let winnr = bufwinnr(newbufnr)
+	if winnr == -1
+	  " Our buffer has vanished!?  Open a new window.
+	  echomsg "download buffer disappeared, opening a new one"
+	  new
+	  setlocal bin
+	else
+	  exe winnr . "wincmd w"
+	endif
+      endif
+      if newbufnr == winbufnr(0)
+	" We are back the old buffer, remove any (half-finished) download.
+        g/^/d
+      else
+	let newbufnr = winbufnr(0)
+      endif
+
+      let fname = a:lang . '.ascii.spl'
+      echo 'Could not find it, trying ' . fname . '...'
+      call spellfile#Nread(fname)
+      if getline(2) !~ 'VIMspell'
+	echo 'Sorry, downloading failed'
+	exe newbufnr . "bwipe!"
+	return
+      endif
+    endif
+
+    " Delete the empty first line and mark the file unmodified.
+    1d
+    set nomod
+
+    let msg = "In which directory do you want to write the file:"
+    for i in range(len(dirlist))
+      let msg .= "\n" . (i + 1) . '. ' . dirlist[i]
+    endfor
+    let dirchoice = confirm(msg, dirchoices) - 2
+    if dirchoice >= 0
+      exe "write " . escape(dirlist[dirchoice], ' ') . '/' . fname
+
+      " Also download the .sug file, if the user wants to.
+      let msg = "Do you want me to try getting the .sug file?\n"
+      let msg .= "This will improve making suggestions for spelling mistakes,\n"
+      let msg .= "but it uses quite a bit of memory."
+      if confirm(msg, "&No\n&Yes") == 2
+	g/^/d
+	let fname = substitute(fname, '\.spl$', '.sug', '')
+	echo 'Downloading ' . fname . '...'
+	call spellfile#Nread(fname)
+	if getline(2) =~ 'VIMsug'
+	  1d
+	  exe "write " . escape(dirlist[dirchoice], ' ') . '/' . fname
+	  set nomod
+	else
+	  echo 'Sorry, downloading failed'
+	  " Go back to our own buffer/window, Nread() may have taken us to
+	  " another window.
+	  if newbufnr != winbufnr(0)
+	    let winnr = bufwinnr(newbufnr)
+	    if winnr != -1
+	      exe winnr . "wincmd w"
+	    endif
+	  endif
+	  if newbufnr == winbufnr(0)
+	    set nomod
+	  endif
+	endif
+      endif
+    endif
+
+    " Wipe out the buffer we used.
+    exe newbufnr . "bwipe"
+  endif
+endfunc
+
+" Read "fname" from the server.
+function! spellfile#Nread(fname)
+  " We do our own error handling, don't want a window for it.
+  if exists("g:netrw_use_errorwindow")
+    let save_ew = g:netrw_use_errorwindow
+  endif
+  let g:netrw_use_errorwindow=0
+
+  if g:spellfile_URL =~ '^ftp://'
+    " for an ftp server use a default login and password to avoid a prompt
+    let machine = substitute(g:spellfile_URL, 'ftp://\([^/]*\).*', '\1', '')
+    let dir = substitute(g:spellfile_URL, 'ftp://[^/]*/\(.*\)', '\1', '')
+    exe 'Nread "' . machine . ' anonymous vim7user ' . dir . '/' . a:fname . '"'
+  else
+    exe 'Nread ' g:spellfile_URL . '/' . a:fname
+  endif
+
+  if exists("save_ew")
+    let g:netrw_use_errorwindow = save_ew
+  else
+    unlet g:netrw_use_errorwindow
+  endif
+endfunc
--- /dev/null
+++ b/lib/vimfiles/autoload/sqlcomplete.vim
@@ -1,0 +1,691 @@
+" Vim OMNI completion script for SQL
+" Language:    SQL
+" Maintainer:  David Fishburn <fishburn@ianywhere.com>
+" Version:     5.0
+" Last Change: Mon Jun 05 2006 3:30:04 PM
+" Usage:       For detailed help
+"              ":help sql.txt" 
+"              or ":help ft-sql-omni" 
+"              or read $VIMRUNTIME/doc/sql.txt
+
+" Set completion with CTRL-X CTRL-O to autoloaded function.
+" This check is in place in case this script is
+" sourced directly instead of using the autoload feature. 
+if exists('&omnifunc')
+    " Do not set the option if already set since this
+    " results in an E117 warning.
+    if &omnifunc == ""
+        setlocal omnifunc=sqlcomplete#Complete
+    endif
+endif
+
+if exists('g:loaded_sql_completion')
+    finish 
+endif
+let g:loaded_sql_completion = 50
+
+" Maintains filename of dictionary
+let s:sql_file_table        = ""
+let s:sql_file_procedure    = ""
+let s:sql_file_view         = ""
+
+" Define various arrays to be used for caching
+let s:tbl_name              = []
+let s:tbl_alias             = []
+let s:tbl_cols              = []
+let s:syn_list              = []
+let s:syn_value             = []
+ 
+" Used in conjunction with the syntaxcomplete plugin
+let s:save_inc              = ""
+let s:save_exc              = ""
+if exists('g:omni_syntax_group_include_sql')
+    let s:save_inc = g:omni_syntax_group_include_sql
+endif
+if exists('g:omni_syntax_group_exclude_sql')
+    let s:save_exc = g:omni_syntax_group_exclude_sql
+endif
+ 
+" Used with the column list
+let s:save_prev_table       = ""
+
+" Default the option to verify table alias
+if !exists('g:omni_sql_use_tbl_alias')
+    let g:omni_sql_use_tbl_alias = 'a'
+endif
+" Default syntax items to precache
+if !exists('g:omni_sql_precache_syntax_groups')
+    let g:omni_sql_precache_syntax_groups = [
+                \ 'syntax',
+                \ 'sqlKeyword',
+                \ 'sqlFunction',
+                \ 'sqlOption',
+                \ 'sqlType',
+                \ 'sqlStatement'
+                \ ]
+endif
+" Set ignorecase to the ftplugin standard
+if !exists('g:omni_sql_ignorecase')
+    let g:omni_sql_ignorecase = &ignorecase
+endif
+" During table completion, should the table list also
+" include the owner name
+if !exists('g:omni_sql_include_owner')
+    let g:omni_sql_include_owner = 0
+    if exists('g:loaded_dbext')
+        if g:loaded_dbext >= 300
+            " New to dbext 3.00, by default the table lists include the owner
+            " name of the table.  This is used when determining how much of
+            " whatever has been typed should be replaced as part of the 
+            " code replacement.
+            let g:omni_sql_include_owner = 1
+        endif
+    endif
+endif
+
+" This function is used for the 'omnifunc' option.
+function! sqlcomplete#Complete(findstart, base)
+
+    " Default to table name completion
+    let compl_type = 'table'
+    " Allow maps to specify what type of object completion they want
+    if exists('b:sql_compl_type')
+        let compl_type = b:sql_compl_type
+    endif
+
+    " First pass through this function determines how much of the line should
+    " be replaced by whatever is chosen from the completion list
+    if a:findstart
+        " Locate the start of the item, including "."
+        let line     = getline('.')
+        let start    = col('.') - 1
+        let lastword = -1
+        let begindot = 0
+        " Check if the first character is a ".", for column completion
+        if line[start - 1] == '.'
+            let begindot = 1
+        endif
+        while start > 0
+            if line[start - 1] =~ '\w'
+                let start -= 1
+            elseif line[start - 1] =~ '\.' && 
+                        \ compl_type =~ 'column\|table\|view\|procedure'
+                " If lastword has already been set for column completion
+                " break from the loop, since we do not also want to pickup
+                " a table name if it was also supplied.
+                if lastword != -1 && compl_type == 'column' 
+                    break
+                endif
+                " If column completion was specified stop at the "." if
+                " a . was specified, otherwise, replace all the way up
+                " to the owner name (if included).
+                if lastword == -1 && compl_type == 'column' && begindot == 1
+                    let lastword = start
+                endif
+                " If omni_sql_include_owner = 0, do not include the table
+                " name as part of the substitution, so break here
+                if lastword == -1 && 
+                            \ compl_type =~ 'table\|view\|procedure\column_csv' && 
+                            \ g:omni_sql_include_owner == 0
+                    let lastword = start
+                    break
+                endif
+                let start -= 1
+            else
+                break
+            endif
+        endwhile
+
+        " Return the column of the last word, which is going to be changed.
+        " Remember the text that comes before it in s:prepended.
+        if lastword == -1
+            let s:prepended = ''
+            return start
+        endif
+        let s:prepended = strpart(line, start, lastword - start)
+        return lastword
+    endif
+
+    " Second pass through this function will determine what data to put inside
+    " of the completion list
+    " s:prepended is set by the first pass
+    let base = s:prepended . a:base
+
+    " Default the completion list to an empty list
+    let compl_list = []
+
+    " Default to table name completion
+    let compl_type = 'table'
+    " Allow maps to specify what type of object completion they want
+    if exists('b:sql_compl_type')
+        let compl_type = b:sql_compl_type
+        unlet b:sql_compl_type
+    endif
+
+    if compl_type == 'tableReset'
+        let compl_type = 'table'
+        let base = ''
+    endif
+
+    if compl_type == 'table' ||
+                \ compl_type == 'procedure' ||
+                \ compl_type == 'view' 
+
+        " This type of completion relies upon the dbext.vim plugin
+        if s:SQLCCheck4dbext() == -1
+            return []
+        endif
+
+        " Allow the user to override the dbext plugin to specify whether
+        " the owner/creator should be included in the list
+        let saved_dbext_show_owner      = 1
+        if exists('g:dbext_default_dict_show_owner')
+            let saved_dbext_show_owner  = g:dbext_default_dict_show_owner
+        endif
+        let g:dbext_default_dict_show_owner = g:omni_sql_include_owner
+
+        let compl_type_uc = substitute(compl_type, '\w\+', '\u&', '')
+        if s:sql_file_{compl_type} == ""
+            let s:sql_file_{compl_type} = DB_getDictionaryName(compl_type_uc)
+        endif
+        let s:sql_file_{compl_type} = DB_getDictionaryName(compl_type_uc)
+        if s:sql_file_{compl_type} != ""
+            if filereadable(s:sql_file_{compl_type})
+                let compl_list = readfile(s:sql_file_{compl_type})
+                " let dic_list = readfile(s:sql_file_{compl_type})
+                " if !empty(dic_list)
+                "     for elem in dic_list
+                "         let kind = (compl_type=='table'?'m':(compl_type=='procedure'?'f':'v'))
+                "         let item = {'word':elem, 'menu':elem, 'kind':kind, 'info':compl_type}
+                "         let compl_list += [item]
+                "     endfor
+                " endif
+            endif
+        endif
+
+        let g:dbext_default_dict_show_owner = saved_dbext_show_owner
+    elseif compl_type =~? 'column'
+
+        " This type of completion relies upon the dbext.vim plugin
+        if s:SQLCCheck4dbext() == -1
+            return []
+        endif
+
+        if base == ""
+            " The last time we displayed a column list we stored
+            " the table name.  If the user selects a column list 
+            " without a table name of alias present, assume they want
+            " the previous column list displayed.
+            let base = s:save_prev_table
+        endif
+
+        let owner  = ''
+        let column = ''
+
+        if base =~ '\.'
+            " Check if the owner/creator has been specified
+            let owner  = matchstr( base, '^\zs.*\ze\..*\..*' )
+            let table  = matchstr( base, '^\(.*\.\)\?\zs.*\ze\..*' )
+            let column = matchstr( base, '.*\.\zs.*' )
+
+            " It is pretty well impossible to determine if the user
+            " has entered:
+            "    owner.table
+            "    table.column_prefix
+            " So there are a couple of things we can do to mitigate 
+            " this issue.
+            "    1.  Check if the dbext plugin has the option turned
+            "        on to even allow owners
+            "    2.  Based on 1, if the user is showing a table list
+            "        and the DrillIntoTable (using <C-Right>) then 
+            "        this will be owner.table.  In this case, we can
+            "        check to see the table.column exists in the 
+            "        cached table list.  If it does, then we have
+            "        determined the user has actually chosen 
+            "        owner.table, not table.column_prefix.
+            let found = -1
+            if g:omni_sql_include_owner == 1 && owner == ''
+                if filereadable(s:sql_file_table)
+                    let tbl_list = readfile(s:sql_file_table)
+                    let found    = index( tbl_list, ((table != '')?(table.'.'):'').column)
+                endif
+            endif
+            " If the table.column was found in the table list, we can safely assume
+            " the owner was not provided and shift the items appropriately.
+            " OR
+            " If the user has indicated not to use table owners at all and
+            " the base ends in a '.' we know they are not providing a column
+            " name, so we can shift the items appropriately.
+            if found != -1 || (g:omni_sql_include_owner == 0 && base !~ '\.$')
+                let owner  = table
+                let table  = column
+                let column = ''
+            endif
+        else
+            let table  = base
+        endif
+
+        " Get anything after the . and consider this the table name
+        " If an owner has been specified, then we must consider the 
+        " base to be a partial column name
+        " let base  = matchstr( base, '^\(.*\.\)\?\zs.*' )
+
+        if table != ""
+            let s:save_prev_table = base
+            let list_type         = ''
+
+            if compl_type == 'column_csv'
+                " Return one array element, with a comma separated
+                " list of values instead of multiple array entries
+                " for each column in the table.
+                let list_type     = 'csv'
+            endif
+
+            let compl_list  = s:SQLCGetColumns(table, list_type)
+            if column != ''
+                " If no column prefix has been provided and the table
+                " name was provided, append it to each of the items
+                " returned.
+                let compl_list = map(compl_list, "table.'.'.v:val")
+                if owner != ''
+                    " If an owner has been provided append it to each of the
+                    " items returned.
+                    let compl_list = map(compl_list, "owner.'.'.v:val")
+                endif
+            else
+                let base = ''
+            endif
+
+            if compl_type == 'column_csv'
+                " Join the column array into 1 single element array
+                " but make the columns column separated
+                let compl_list        = [join(compl_list, ', ')]
+            endif
+        endif
+    elseif compl_type == 'resetCache'
+        " Reset all cached items
+        let s:tbl_name  = []
+        let s:tbl_alias = []
+        let s:tbl_cols  = []
+        let s:syn_list  = []
+        let s:syn_value = []
+
+        let msg = "All SQL cached items have been removed."
+        call s:SQLCWarningMsg(msg)
+        " Leave time for the user to read the error message
+        :sleep 2
+    else
+        let compl_list = s:SQLCGetSyntaxList(compl_type)
+    endif
+
+    if base != ''
+        " Filter the list based on the first few characters the user
+        " entered
+        let expr = 'v:val '.(g:omni_sql_ignorecase==1?'=~?':'=~#').' "\\(^'.base.'\\|\\([^.]*\\)\\?'.base.'\\)"'
+        let compl_list = filter(deepcopy(compl_list), expr)
+    endif
+
+    if exists('b:sql_compl_savefunc') && b:sql_compl_savefunc != ""
+        let &omnifunc = b:sql_compl_savefunc
+    endif
+
+    return compl_list
+endfunc
+
+function! sqlcomplete#PreCacheSyntax(...)
+    let syn_group_arr = []
+    if a:0 > 0 
+        let syn_group_arr = a:1
+    else
+        let syn_group_arr = g:omni_sql_precache_syntax_groups
+    endif
+    " For each group specified in the list, precache all
+    " the sytnax items.
+    if !empty(syn_group_arr)
+        for group_name in syn_group_arr
+            call s:SQLCGetSyntaxList(group_name)
+        endfor
+    endif
+endfunction
+
+function! sqlcomplete#Map(type)
+    " Tell the SQL plugin what you want to complete
+    let b:sql_compl_type=a:type
+    " Record previous omnifunc, if the SQL completion
+    " is being used in conjunction with other filetype
+    " completion plugins
+    if &omnifunc != "" && &omnifunc != 'sqlcomplete#Complete'
+        " Record the previous omnifunc, the plugin
+        " will automatically set this back so that it
+        " does not interfere with other ftplugins settings
+        let b:sql_compl_savefunc=&omnifunc
+    endif
+    " Set the OMNI func for the SQL completion plugin
+    let &omnifunc='sqlcomplete#Complete'
+endfunction
+
+function! sqlcomplete#DrillIntoTable()
+    " If the omni popup window is visible
+    if pumvisible()
+        call sqlcomplete#Map('column')
+        " C-Y, makes the currently highlighted entry active
+        " and trigger the omni popup to be redisplayed
+        call feedkeys("\<C-Y>\<C-X>\<C-O>")
+    else
+        if has('win32')
+            " If the popup is not visible, simple perform the normal
+            " <C-Right> behaviour
+            exec "normal! \<C-Right>"
+        endif
+    endif
+    return ""
+endfunction
+
+function! sqlcomplete#DrillOutOfColumns()
+    " If the omni popup window is visible
+    if pumvisible()
+        call sqlcomplete#Map('tableReset')
+        " Trigger the omni popup to be redisplayed
+        call feedkeys("\<C-X>\<C-O>")
+    else
+        if has('win32')
+            " If the popup is not visible, simple perform the normal
+            " <C-Left> behaviour
+            exec "normal! \<C-Left>"
+        endif
+    endif
+    return ""
+endfunction
+
+function! s:SQLCWarningMsg(msg)
+    echohl WarningMsg
+    echomsg a:msg 
+    echohl None
+endfunction
+      
+function! s:SQLCErrorMsg(msg)
+    echohl ErrorMsg
+    echomsg a:msg 
+    echohl None
+endfunction
+      
+function! s:SQLCGetSyntaxList(syn_group)
+    let syn_group  = a:syn_group
+    let compl_list = []
+
+    " Check if we have already cached the syntax list
+    let list_idx = index(s:syn_list, syn_group, 0, &ignorecase)
+    if list_idx > -1
+        " Return previously cached value
+        let compl_list = s:syn_value[list_idx]
+    else
+        " Request the syntax list items from the 
+        " syntax completion plugin
+        if syn_group == 'syntax'
+            " Handle this special case.  This allows the user
+            " to indicate they want all the syntax items available,
+            " so do not specify a specific include list.
+            let g:omni_syntax_group_include_sql = ''
+        else
+            " The user has specified a specific syntax group
+            let g:omni_syntax_group_include_sql = syn_group
+        endif
+        let g:omni_syntax_group_exclude_sql = ''
+        let syn_value                       = OmniSyntaxList()
+        let g:omni_syntax_group_include_sql = s:save_inc
+        let g:omni_syntax_group_exclude_sql = s:save_exc
+        " Cache these values for later use
+        let s:syn_list  = add( s:syn_list,  syn_group )
+        let s:syn_value = add( s:syn_value, syn_value )
+        let compl_list  = syn_value
+    endif
+
+    return compl_list
+endfunction
+
+function! s:SQLCCheck4dbext()
+    if !exists('g:loaded_dbext')
+        let msg = "The dbext plugin must be loaded for dynamic SQL completion"
+        call s:SQLCErrorMsg(msg)
+        " Leave time for the user to read the error message
+        :sleep 2
+        return -1
+    elseif g:loaded_dbext < 300
+        let msg = "The dbext plugin must be at least version 3.00 " .
+                    \ " for dynamic SQL completion"
+        call s:SQLCErrorMsg(msg)
+        " Leave time for the user to read the error message
+        :sleep 2
+        return -1
+    endif
+    return 1
+endfunction
+
+function! s:SQLCAddAlias(table_name, table_alias, cols)
+    " Strip off the owner if included
+    let table_name  = matchstr(a:table_name, '\%(.\{-}\.\)\?\zs\(.*\)' )
+    let table_alias = a:table_alias
+    let cols        = a:cols
+
+    if g:omni_sql_use_tbl_alias != 'n' 
+        if table_alias == ''
+            if 'da' =~? g:omni_sql_use_tbl_alias
+                if table_name =~ '_'
+                    " Treat _ as separators since people often use these
+                    " for word separators
+                    let save_keyword = &iskeyword
+                    setlocal iskeyword-=_
+
+                    " Get the first letter of each word
+                    " [[:alpha:]] is used instead of \w 
+                    " to catch extended accented characters
+                    "
+                    let table_alias = substitute( 
+                                \ table_name, 
+                                \ '\<[[:alpha:]]\+\>_\?', 
+                                \ '\=strpart(submatch(0), 0, 1)', 
+                                \ 'g'
+                                \ )
+                    " Restore original value
+                    let &iskeyword = save_keyword
+                elseif table_name =~ '\u\U'
+                    let table_alias = substitute(
+                                \ table_name, '\(\u\)\U*', '\1', 'g')
+                else
+                    let table_alias = strpart(table_name, 0, 1)
+                endif
+            endif
+        endif
+        if table_alias != ''
+            " Following a word character, make sure there is a . and no spaces
+            let table_alias = substitute(table_alias, '\w\zs\.\?\s*$', '.', '')
+            if 'a' =~? g:omni_sql_use_tbl_alias && a:table_alias == ''
+                let table_alias = inputdialog("Enter table alias:", table_alias)
+            endif
+        endif
+        if table_alias != ''
+            let cols = substitute(cols, '\<\w', table_alias.'&', 'g')
+        endif
+    endif
+
+    return cols
+endfunction
+
+function! s:SQLCGetObjectOwner(object) 
+    " The owner regex matches a word at the start of the string which is
+    " followed by a dot, but doesn't include the dot in the result.
+    " ^    - from beginning of line
+    " "\?  - ignore any quotes
+    " \zs  - start the match now
+    " \w\+ - get owner name
+    " \ze  - end the match
+    " "\?  - ignore any quotes
+    " \.   - must by followed by a .
+    let owner = matchstr( a:object, '^"\?\zs\w\+\ze"\?\.' )
+    return owner
+endfunction 
+
+function! s:SQLCGetColumns(table_name, list_type)
+    " Check if the table name was provided as part of the column name
+    let table_name   = matchstr(a:table_name, '^[a-zA-Z0-9_]\+\ze\.\?')
+    let table_cols   = []
+    let table_alias  = ''
+    let move_to_top  = 1
+
+    if g:loaded_dbext >= 300
+        let saveSettingAlias = DB_listOption('use_tbl_alias')
+        exec 'DBSetOption use_tbl_alias=n'
+    endif
+
+    " Check if we have already cached the column list for this table
+    " by its name
+    let list_idx = index(s:tbl_name, table_name, 0, &ignorecase)
+    if list_idx > -1
+        let table_cols = split(s:tbl_cols[list_idx])
+    else
+        " Check if we have already cached the column list for this table 
+        " by its alias, assuming the table_name provided was actually
+        " the alias for the table instead
+        "     select *
+        "       from area a
+        "      where a.
+        let list_idx = index(s:tbl_alias, table_name, 0, &ignorecase)
+        if list_idx > -1
+            let table_alias = table_name
+            let table_name  = s:tbl_name[list_idx]
+            let table_cols  = split(s:tbl_cols[list_idx])
+        endif
+    endif
+
+    " If we have not found a cached copy of the table
+    " And the table ends in a "." or we are looking for a column list
+    " if list_idx == -1 && (a:table_name =~ '\.' || b:sql_compl_type =~ 'column')
+    " if list_idx == -1 && (a:table_name =~ '\.' || a:list_type =~ 'csv')
+    if list_idx == -1 
+         let saveY      = @y
+         let saveSearch = @/
+         let saveWScan  = &wrapscan
+         let curline    = line(".")
+         let curcol     = col(".")
+
+         " Do not let searchs wrap
+         setlocal nowrapscan
+         " If . was entered, look at the word just before the .
+         " We are looking for something like this:
+         "    select * 
+         "      from customer c
+         "     where c.
+         " So when . is pressed, we need to find 'c'
+         "
+
+         " Search backwards to the beginning of the statement
+         " and do NOT wrap
+         " exec 'silent! normal! v?\<\(select\|update\|delete\|;\)\>'."\n".'"yy'
+         exec 'silent! normal! ?\<\(select\|update\|delete\|;\)\>'."\n"
+
+         " Start characterwise visual mode
+         " Advance right one character
+         " Search foward until one of the following:
+         "     1.  Another select/update/delete statement
+         "     2.  A ; at the end of a line (the delimiter)
+         "     3.  The end of the file (incase no delimiter)
+         " Yank the visually selected text into the "y register.
+         exec 'silent! normal! vl/\(\<select\>\|\<update\>\|\<delete\>\|;\s*$\|\%$\)'."\n".'"yy'
+
+         let query = @y
+         let query = substitute(query, "\n", ' ', 'g')
+         let found = 0
+
+         " if query =~? '^\(select\|update\|delete\)'
+         if query =~? '^\(select\)'
+             let found = 1
+             "  \(\(\<\w\+\>\)\.\)\?   - 
+             " 'from.\{-}'  - Starting at the from clause
+             " '\zs\(\(\<\w\+\>\)\.\)\?' - Get the owner name (optional)
+             " '\<\w\+\>\ze' - Get the table name 
+             " '\s\+\<'.table_name.'\>' - Followed by the alias
+             " '\s*\.\@!.*'  - Cannot be followed by a .
+             " '\(\<where\>\|$\)' - Must be followed by a WHERE clause
+             " '.*'  - Exclude the rest of the line in the match
+             let table_name_new = matchstr(@y, 
+                         \ 'from.\{-}'.
+                         \ '\zs\(\(\<\w\+\>\)\.\)\?'.
+                         \ '\<\w\+\>\ze'.
+                         \ '\s\+\%(as\s\+\)\?\<'.
+                         \ matchstr(table_name, '.\{-}\ze\.\?$').
+                         \ '\>'.
+                         \ '\s*\.\@!.*'.
+                         \ '\(\<where\>\|$\)'.
+                         \ '.*'
+                         \ )
+             if table_name_new != ''
+                 let table_alias = table_name
+                 let table_name  = table_name_new
+
+                 let list_idx = index(s:tbl_name, table_name, 0, &ignorecase)
+                 if list_idx > -1
+                     let table_cols  = split(s:tbl_cols[list_idx])
+                     let s:tbl_name[list_idx]  = table_name
+                     let s:tbl_alias[list_idx] = table_alias
+                 else
+                     let list_idx = index(s:tbl_alias, table_name, 0, &ignorecase)
+                     if list_idx > -1
+                         let table_cols = split(s:tbl_cols[list_idx])
+                         let s:tbl_name[list_idx]  = table_name
+                         let s:tbl_alias[list_idx] = table_alias
+                     endif
+                 endif
+
+             endif
+         else
+             " Simply assume it is a table name provided with a . on the end
+             let found = 1
+         endif
+
+         let @y        = saveY
+         let @/        = saveSearch
+         let &wrapscan = saveWScan
+
+         " Return to previous location
+         call cursor(curline, curcol)
+         
+         if found == 0
+             if g:loaded_dbext > 300
+                 exec 'DBSetOption use_tbl_alias='.saveSettingAlias
+             endif
+
+             " Not a SQL statement, do not display a list
+             return []
+         endif
+    endif 
+
+    if empty(table_cols)
+        " Specify silent mode, no messages to the user (tbl, 1)
+        " Specify do not comma separate (tbl, 1, 1)
+        let table_cols_str = DB_getListColumn(table_name, 1, 1)
+
+        if table_cols_str != ""
+            let s:tbl_name  = add( s:tbl_name,  table_name )
+            let s:tbl_alias = add( s:tbl_alias, table_alias )
+            let s:tbl_cols  = add( s:tbl_cols,  table_cols_str )
+            let table_cols  = split(table_cols_str)
+        endif
+
+    endif
+
+    if g:loaded_dbext > 300
+        exec 'DBSetOption use_tbl_alias='.saveSettingAlias
+    endif
+
+    " If the user has asked for a comma separate list of column
+    " values, ask the user if they want to prepend each column
+    " with a tablename alias.
+    if a:list_type == 'csv' && !empty(table_cols)
+        let cols       = join(table_cols, ', ')
+        let cols       = s:SQLCAddAlias(table_name, table_alias, cols)
+        let table_cols = [cols]
+    endif
+
+    return table_cols
+endfunction
+
--- /dev/null
+++ b/lib/vimfiles/autoload/syntaxcomplete.vim
@@ -1,0 +1,376 @@
+" Vim completion script
+" Language:    All languages, uses existing syntax highlighting rules
+" Maintainer:  David Fishburn <fishburn@ianywhere.com>
+" Version:     3.0
+" Last Change: Wed Nov 08 2006 10:46:46 AM
+" Usage:       For detailed help, ":help ft-syntax-omni" 
+
+" Set completion with CTRL-X CTRL-O to autoloaded function.
+" This check is in place in case this script is
+" sourced directly instead of using the autoload feature. 
+if exists('+omnifunc')
+    " Do not set the option if already set since this
+    " results in an E117 warning.
+    if &omnifunc == ""
+        setlocal omnifunc=syntaxcomplete#Complete
+    endif
+endif
+
+if exists('g:loaded_syntax_completion')
+    finish 
+endif
+let g:loaded_syntax_completion = 30
+
+" Set ignorecase to the ftplugin standard
+" This is the default setting, but if you define a buffer local
+" variable you can override this on a per filetype.
+if !exists('g:omni_syntax_ignorecase')
+    let g:omni_syntax_ignorecase = &ignorecase
+endif
+
+" Indicates whether we should use the iskeyword option to determine
+" how to split words.
+" This is the default setting, but if you define a buffer local
+" variable you can override this on a per filetype.
+if !exists('g:omni_syntax_use_iskeyword')
+    let g:omni_syntax_use_iskeyword = 1
+endif
+
+" Only display items in the completion window that are at least
+" this many characters in length.
+" This is the default setting, but if you define a buffer local
+" variable you can override this on a per filetype.
+if !exists('g:omni_syntax_minimum_length')
+    let g:omni_syntax_minimum_length = 0
+endif
+
+" This script will build a completion list based on the syntax
+" elements defined by the files in $VIMRUNTIME/syntax.
+let s:syn_remove_words = 'match,matchgroup=,contains,'.
+            \ 'links to,start=,end=,nextgroup='
+
+let s:cache_name = []
+let s:cache_list = []
+let s:prepended  = ''
+
+" This function is used for the 'omnifunc' option.
+function! syntaxcomplete#Complete(findstart, base)
+
+    " Only display items in the completion window that are at least
+    " this many characters in length
+    if !exists('b:omni_syntax_ignorecase')
+        if exists('g:omni_syntax_ignorecase')
+            let b:omni_syntax_ignorecase = g:omni_syntax_ignorecase
+        else
+            let b:omni_syntax_ignorecase = &ignorecase
+        endif
+    endif
+
+    if a:findstart
+        " Locate the start of the item, including "."
+        let line = getline('.')
+        let start = col('.') - 1
+        let lastword = -1
+        while start > 0
+            " if line[start - 1] =~ '\S'
+            "     let start -= 1
+            " elseif line[start - 1] =~ '\.'
+            if line[start - 1] =~ '\k'
+                let start -= 1
+                let lastword = a:findstart
+            else
+                break
+            endif
+        endwhile
+
+        " Return the column of the last word, which is going to be changed.
+        " Remember the text that comes before it in s:prepended.
+        if lastword == -1
+            let s:prepended = ''
+            return start
+        endif
+        let s:prepended = strpart(line, start, (col('.') - 1) - start)
+        return start
+    endif
+
+    " let base = s:prepended . a:base
+    let base = s:prepended
+
+    let filetype = substitute(&filetype, '\.', '_', 'g')
+    let list_idx = index(s:cache_name, filetype, 0, &ignorecase)
+    if list_idx > -1
+        let compl_list = s:cache_list[list_idx]
+    else
+        let compl_list   = OmniSyntaxList()
+        let s:cache_name = add( s:cache_name,  filetype )
+        let s:cache_list = add( s:cache_list,  compl_list )
+    endif
+
+    " Return list of matches.
+
+    if base != ''
+        " let compstr    = join(compl_list, ' ')
+        " let expr       = (b:omni_syntax_ignorecase==0?'\C':'').'\<\%('.base.'\)\@!\w\+\s*'
+        " let compstr    = substitute(compstr, expr, '', 'g')
+        " let compl_list = split(compstr, '\s\+')
+
+        " Filter the list based on the first few characters the user
+        " entered
+        let expr = 'v:val '.(g:omni_syntax_ignorecase==1?'=~?':'=~#')." '^".escape(base, '\\/.*$^~[]').".*'"
+        let compl_list = filter(deepcopy(compl_list), expr)
+    endif
+
+    return compl_list
+endfunc
+
+function! OmniSyntaxList()
+    " Default to returning a dictionary, if use_dictionary is set to 0
+    " a list will be returned.
+    " let use_dictionary = 1
+    " if a:0 > 0 && a:1 != ''
+    "     let use_dictionary = a:1
+    " endif
+
+    " Only display items in the completion window that are at least
+    " this many characters in length
+    if !exists('b:omni_syntax_use_iskeyword')
+        if exists('g:omni_syntax_use_iskeyword')
+            let b:omni_syntax_use_iskeyword = g:omni_syntax_use_iskeyword
+        else
+            let b:omni_syntax_use_iskeyword = 1
+        endif
+    endif
+
+    " Only display items in the completion window that are at least
+    " this many characters in length
+    if !exists('b:omni_syntax_minimum_length')
+        if exists('g:omni_syntax_minimum_length')
+            let b:omni_syntax_minimum_length = g:omni_syntax_minimum_length
+        else
+            let b:omni_syntax_minimum_length = 0
+        endif
+    endif
+
+    let saveL = @l
+    
+    " Loop through all the syntax groupnames, and build a
+    " syntax file which contains these names.  This can 
+    " work generically for any filetype that does not already
+    " have a plugin defined.
+    " This ASSUMES the syntax groupname BEGINS with the name
+    " of the filetype.  From my casual viewing of the vim7\syntax 
+    " directory.
+    redir @l
+    silent! exec 'syntax list '
+    redir END
+
+    let syntax_full = "\n".@l
+    let @l = saveL
+
+    if syntax_full =~ 'E28' 
+                \ || syntax_full =~ 'E411'
+                \ || syntax_full =~ 'E415'
+                \ || syntax_full =~ 'No Syntax items'
+        return []
+    endif
+
+    let filetype = substitute(&filetype, '\.', '_', 'g')
+
+    " Default the include group to include the requested syntax group
+    let syntax_group_include_{filetype} = ''
+    " Check if there are any overrides specified for this filetype
+    if exists('g:omni_syntax_group_include_'.filetype)
+        let syntax_group_include_{filetype} =
+                    \ substitute( g:omni_syntax_group_include_{filetype},'\s\+','','g') 
+        if syntax_group_include_{filetype} =~ '\w'
+            let syntax_group_include_{filetype} = 
+                        \ substitute( syntax_group_include_{filetype}, 
+                        \ '\s*,\s*', '\\|', 'g'
+                        \ )
+        endif
+    endif
+
+    " Default the exclude group to nothing
+    let syntax_group_exclude_{filetype} = ''
+    " Check if there are any overrides specified for this filetype
+    if exists('g:omni_syntax_group_exclude_'.filetype)
+        let syntax_group_exclude_{filetype} =
+                    \ substitute( g:omni_syntax_group_exclude_{filetype},'\s\+','','g') 
+        if syntax_group_exclude_{filetype} =~ '\w' 
+            let syntax_group_exclude_{filetype} = 
+                        \ substitute( syntax_group_exclude_{filetype}, 
+                        \ '\s*,\s*', '\\|', 'g'
+                        \ )
+        endif
+    endif
+
+    " Sometimes filetypes can be composite names, like c.doxygen
+    " Loop through each individual part looking for the syntax
+    " items specific to each individual filetype.
+    let syn_list = ''
+    let ftindex  = 0
+    let ftindex  = match(&filetype, '\w\+', ftindex)
+
+    while ftindex > -1
+        let ft_part_name = matchstr( &filetype, '\w\+', ftindex )
+
+        " Syntax rules can contain items for more than just the current 
+        " filetype.  They can contain additional items added by the user
+        " via autocmds or their vimrc.
+        " Some syntax files can be combined (html, php, jsp).
+        " We want only items that begin with the filetype we are interested in.
+        let next_group_regex = '\n' .
+                    \ '\zs'.ft_part_name.'\w\+\ze'.
+                    \ '\s\+xxx\s\+' 
+        let index    = 0
+        let index    = match(syntax_full, next_group_regex, index)
+
+        while index > -1
+            let group_name = matchstr( syntax_full, '\w\+', index )
+
+            let get_syn_list = 1
+            " if syntax_group_include_{&filetype} == ''
+            "     if syntax_group_exclude_{&filetype} != ''
+            "         if '\<'.syntax_group_exclude_{&filetype}.'\>' =~ '\<'.group_name.'\>'
+            "             let get_syn_list = 0
+            "         endif
+            "     endif
+            " else
+            "     if '\<'.syntax_group_include_{&filetype}.'\>' !~ '\<'.group_name.'\>'
+            "         let get_syn_list = 0
+            "     endif
+            " endif
+            if syntax_group_exclude_{filetype} != ''
+                if '\<'.syntax_group_exclude_{filetype}.'\>' =~ '\<'.group_name.'\>'
+                    let get_syn_list = 0
+                endif
+            endif
+        
+            if get_syn_list == 1
+                if syntax_group_include_{filetype} != ''
+                    if '\<'.syntax_group_include_{filetype}.'\>' !~ '\<'.group_name.'\>'
+                        let get_syn_list = 0
+                    endif
+                endif
+            endif
+
+            if get_syn_list == 1
+                " Pass in the full syntax listing, plus the group name we 
+                " are interested in.
+                let extra_syn_list = s:SyntaxCSyntaxGroupItems(group_name, syntax_full)
+
+                " if !empty(extra_syn_list)
+                "     for elem in extra_syn_list
+                "         let item = {'word':elem, 'kind':'t', 'info':group_name}
+                "         let compl_list += [item]
+                "     endfor
+                " endif
+
+                let syn_list = syn_list . extra_syn_list . "\n"
+            endif
+
+            let index = index + strlen(group_name)
+            let index = match(syntax_full, next_group_regex, index)
+        endwhile
+
+        let ftindex  = ftindex + len(ft_part_name)
+        let ftindex  = match( &filetype, '\w\+', ftindex )
+    endwhile
+
+    " Convert the string to a List and sort it.
+    let compl_list = sort(split(syn_list))
+
+    if &filetype == 'vim'
+        let short_compl_list = []
+        for i in range(len(compl_list))
+            if i == len(compl_list)-1
+                let next = i
+            else
+                let next = i + 1
+            endif
+            if  compl_list[next] !~ '^'.compl_list[i].'.$'
+                let short_compl_list += [compl_list[i]]
+            endif
+        endfor
+
+        return short_compl_list
+    else
+        return compl_list
+    endif
+endfunction
+
+function! s:SyntaxCSyntaxGroupItems( group_name, syntax_full )
+
+    let syn_list = ""
+
+    " From the full syntax listing, strip out the portion for the
+    " request group.
+    " Query:
+    "     \n           - must begin with a newline
+    "     a:group_name - the group name we are interested in
+    "     \s\+xxx\s\+  - group names are always followed by xxx
+    "     \zs          - start the match
+    "     .\{-}        - everything ...
+    "     \ze          - end the match
+    "     \n\w         - at the first newline starting with a character
+    let syntax_group = matchstr(a:syntax_full, 
+                \ "\n".a:group_name.'\s\+xxx\s\+\zs.\{-}\ze'."\n".'\w'
+                \ )
+
+    if syntax_group != ""
+        " let syn_list = substitute( @l, '^.*xxx\s*\%(contained\s*\)\?', "", '' )
+        " let syn_list = substitute( @l, '^.*xxx\s*', "", '' )
+
+        " We only want the words for the lines begining with
+        " containedin, but there could be other items.
+        
+        " Tried to remove all lines that do not begin with contained
+        " but this does not work in all cases since you can have
+        "    contained nextgroup=...
+        " So this will strip off the ending of lines with known
+        " keywords.
+        let syn_list = substitute( 
+                    \    syntax_group, '\<\('.
+                    \    substitute(
+                    \      escape(s:syn_remove_words, '\\/.*$^~[]')
+                    \      , ',', '\\|', 'g'
+                    \    ).
+                    \    '\).\{-}\%($\|'."\n".'\)'
+                    \    , "\n", 'g' 
+                    \  )
+
+        " Now strip off the newline + blank space + contained
+        let syn_list = substitute( 
+                    \    syn_list, '\%(^\|\n\)\@<=\s*\<\(contained\)'
+                    \    , "", 'g' 
+                    \ )
+
+        if b:omni_syntax_use_iskeyword == 0
+            " There are a number of items which have non-word characters in
+            " them, *'T_F1'*.  vim.vim is one such file.
+            " This will replace non-word characters with spaces.
+            let syn_list = substitute( syn_list, '[^0-9A-Za-z_ ]', ' ', 'g' )
+        else
+            let accept_chars = ','.&iskeyword.','
+            " Remove all character ranges
+            let accept_chars = substitute(accept_chars, ',[^,]\+-[^,]\+,', ',', 'g')
+            " Remove all numeric specifications
+            let accept_chars = substitute(accept_chars, ',\d\{-},', ',', 'g')
+            " Remove all commas
+            let accept_chars = substitute(accept_chars, ',', '', 'g')
+            " Escape special regex characters
+            let accept_chars = escape(accept_chars, '\\/.*$^~[]' )
+            " Remove all characters that are not acceptable
+            let syn_list = substitute( syn_list, '[^0-9A-Za-z_ '.accept_chars.']', ' ', 'g' )
+        endif
+
+        if b:omni_syntax_minimum_length > 0
+            " If the user specified a minimum length, enforce it
+            let syn_list = substitute(' '.syn_list.' ', ' \S\{,'.b:omni_syntax_minimum_length.'}\ze ', ' ', 'g')
+        endif
+    else
+        let syn_list = ''
+    endif
+
+    return syn_list
+endfunction
--- /dev/null
+++ b/lib/vimfiles/autoload/tar.vim
@@ -1,0 +1,390 @@
+" tar.vim: Handles browsing tarfiles
+"            AUTOLOAD PORTION
+" Date:			Sep 29, 2006
+" Version:		11
+" Maintainer:	Charles E Campbell, Jr <NdrOchip@ScampbellPfamily.AbizM-NOSPAM>
+" License:		Vim License  (see vim's :help license)
+"
+"	Contains many ideas from Michael Toren's <tar.vim>
+"
+" Copyright:    Copyright (C) 2005 Charles E. Campbell, Jr. {{{1
+"               Permission is hereby granted to use and distribute this code,
+"               with or without modifications, provided that this copyright
+"               notice is copied with it. Like anything else that's free,
+"               tarPlugin.vim is provided *as is* and comes with no warranty
+"               of any kind, either expressed or implied. By using this
+"               plugin, you agree that in no event will the copyright
+"               holder be liable for any damages resulting from the use
+"               of this software.
+
+" ---------------------------------------------------------------------
+" Load Once: {{{1
+let s:keepcpo= &cpo
+set cpo&vim
+if &cp || exists("g:loaded_tar") || v:version < 700
+ finish
+endif
+let g:loaded_tar= "v11"
+"call Decho("loading autoload/tar.vim")
+
+" ---------------------------------------------------------------------
+"  Default Settings: {{{1
+if !exists("g:tar_browseoptions")
+ let g:tar_browseoptions= "Ptf"
+endif
+if !exists("g:tar_readoptions")
+ let g:tar_readoptions= "OPxf"
+endif
+if !exists("g:tar_cmd")
+ let g:tar_cmd= "tar"
+endif
+if !exists("g:tar_writeoptions")
+ let g:tar_writeoptions= "uf"
+endif
+if !exists("g:tar_shq")
+ if has("unix")
+  let g:tar_shq= "'"
+ else
+  let g:tar_shq= '"'
+ endif
+endif
+
+" ----------------
+"  Functions: {{{1
+" ----------------
+
+" ---------------------------------------------------------------------
+" tar#Browse: {{{2
+fun! tar#Browse(tarfile)
+"  call Dfunc("tar#Browse(tarfile<".a:tarfile.">)")
+  let repkeep= &report
+  set report=10
+
+  " sanity checks
+  if !executable(g:tar_cmd)
+   redraw!
+   echohl Error | echo '***error*** (tar#Browse) "'.g:tar_cmd.'" not available on your system'
+"   call inputsave()|call input("Press <cr> to continue")|call inputrestore()
+   let &report= repkeep
+"   call Dret("tar#Browse")
+   return
+  endif
+  if !filereadable(a:tarfile)
+"   call Decho('a:tarfile<'.a:tarfile.'> not filereadable')
+   if a:tarfile !~# '^\a\+://'
+    " if its an url, don't complain, let url-handlers such as vim do its thing
+    redraw!
+    echohl Error | echo "***error*** (tar#Browse) File not readable<".a:tarfile.">" | echohl None
+"    call inputsave()|call input("Press <cr> to continue")|call inputrestore()
+   endif
+   let &report= repkeep
+"   call Dret("tar#Browse : file<".a:tarfile."> not readable")
+   return
+  endif
+  if &ma != 1
+   set ma
+  endif
+  let w:tarfile= a:tarfile
+
+  setlocal noswapfile
+  setlocal buftype=nofile
+  setlocal bufhidden=hide
+  setlocal nobuflisted
+  setlocal nowrap
+  set ft=tar
+
+  " give header
+"  call Decho("printing header")
+  exe "$put ='".'\"'." tar.vim version ".g:loaded_tar."'"
+  exe "$put ='".'\"'." Browsing tarfile ".a:tarfile."'"
+  exe "$put ='".'\"'." Select a file with cursor and press ENTER"."'"
+  0d
+  $
+
+  let tarfile= a:tarfile
+  if has("win32") && executable("cygpath")
+   " assuming cygwin
+   let tarfile=substitute(system("cygpath -u ".tarfile),'\n$','','e')
+  endif
+  let curlast= line("$")
+  if tarfile =~# '\.\(gz\|tgz\)$'
+"   call Decho("exe silent r! gzip -d -c ".g:tar_shq.tarfile.g:tar_shq."| ".g:tar_cmd." -".g:tar_browseoptions." - ")
+   exe "silent r! gzip -d -c ".g:tar_shq.tarfile.g:tar_shq."| ".g:tar_cmd." -".g:tar_browseoptions." - "
+  elseif tarfile =~# '\.bz2$'
+"   call Decho("exe silent r! bzip2 -d -c ".g:tar_shq.tarfile.g:tar_shq."| ".g:tar_cmd." -".g:tar_browseoptions." - ")
+   exe "silent r! bzip2 -d -c ".g:tar_shq.tarfile.g:tar_shq."| ".g:tar_cmd." -".g:tar_browseoptions." - "
+  else
+"   call Decho("exe silent r! ".g:tar_cmd." -".g:tar_browseoptions." ".g:tar_shq.tarfile.g:tar_shq)
+   exe "silent r! ".g:tar_cmd." -".g:tar_browseoptions." ".g:tar_shq.tarfile.g:tar_shq
+  endif
+  if v:shell_error != 0
+   redraw!
+   echohl WarningMsg | echo "***warning*** (tar#Browse) please check your g:tar_browseoptions<".g:tar_browseoptions.">"
+"   call inputsave()|call input("Press <cr> to continue")|call inputrestore()
+"   call Dret("tar#Browse : a:tarfile<".a:tarfile.">")
+   return
+  endif
+  if line("$") == curlast || ( line("$") == (curlast + 1) && getline("$") =~ '\c\%(warning\|error\|inappropriate\|unrecognized\)')
+   redraw!
+   echohl WarningMsg | echo "***warning*** (tar#Browse) ".a:tarfile." doesn't appear to be a tar file" | echohl None
+"   call inputsave()|call input("Press <cr> to continue")|call inputrestore()
+   silent %d
+   let eikeep= &ei
+   set ei=BufReadCmd,FileReadCmd
+   exe "r ".a:tarfile
+   let &ei= eikeep
+   1d
+"   call Dret("tar#Browse : a:tarfile<".a:tarfile.">")
+   return
+  endif
+
+  setlocal noma nomod ro
+  noremap <silent> <buffer> <cr> :call <SID>TarBrowseSelect()<cr>
+
+  let &report= repkeep
+"  call Dret("tar#Browse : w:tarfile<".w:tarfile.">")
+endfun
+
+" ---------------------------------------------------------------------
+" TarBrowseSelect: {{{2
+fun! s:TarBrowseSelect()
+"  call Dfunc("TarBrowseSelect() w:tarfile<".w:tarfile."> curfile<".expand("%").">")
+  let repkeep= &report
+  set report=10
+  let fname= getline(".")
+"  call Decho("fname<".fname.">")
+
+  " sanity check
+  if fname =~ '^"'
+   let &report= repkeep
+"   call Dret("TarBrowseSelect")
+   return
+  endif
+
+  " about to make a new window, need to use w:tarfile
+  let tarfile= w:tarfile
+  let curfile= expand("%")
+  if has("win32") && executable("cygpath")
+   " assuming cygwin
+   let tarfile=substitute(system("cygpath -u ".tarfile),'\n$','','e')
+  endif
+
+  new
+  wincmd _
+  let s:tblfile_{winnr()}= curfile
+  call tar#Read("tarfile:".tarfile.':'.fname,1)
+  filetype detect
+
+  let &report= repkeep
+"  call Dret("TarBrowseSelect : s:tblfile_".winnr()."<".s:tblfile_{winnr()}.">")
+endfun
+
+" ---------------------------------------------------------------------
+" tar#Read: {{{2
+fun! tar#Read(fname,mode)
+"  call Dfunc("tar#Read(fname<".a:fname.">,mode=".a:mode.")")
+  let repkeep= &report
+  set report=10
+  let tarfile = substitute(a:fname,'tarfile:\(.\{-}\):.*$','\1','')
+  let fname   = substitute(a:fname,'tarfile:.\{-}:\(.*\)$','\1','')
+  if has("win32") && executable("cygpath")
+   " assuming cygwin
+   let tarfile=substitute(system("cygpath -u ".tarfile),'\n$','','e')
+  endif
+"  call Decho("tarfile<".tarfile.">")
+"  call Decho("fname<".fname.">")
+
+  if tarfile =~# '\.\(gz\|tgz\)$'
+"   call Decho("exe silent r! gzip -d -c ".g:tar_shq.tarfile.g:tar_shq."| ".g:tar_cmd." -OPxf - '".fname."'")
+   exe "silent r! gzip -d -c ".g:tar_shq.tarfile.g:tar_shq."| ".g:tar_cmd." -".g:tar_readoptions." - '".fname."'"
+  elseif tarfile =~# '\.bz2$'
+"   call Decho("exe silent r! bzip2 -d -c ".g:tar_shq.tarfile.g:tar_shq."| ".g:tar_cmd." -".g:tar_readoptions." - '".fname."'")
+   exe "silent r! bzip2 -d -c ".g:tar_shq.tarfile.g:tar_shq."| ".g:tar_cmd." -".g:tar_readoptions." - '".fname."'"
+  else
+"   call Decho("exe silent r! ".g:tar_cmd." -".g:tar_readoptions." ".g:tar_shq.tarfile.g:tar_shq." ".g:tar_shq.fname.g:tar_shq)
+   exe "silent r! ".g:tar_cmd." -".g:tar_readoptions." ".g:tar_shq.tarfile.g:tar_shq." ".g:tar_shq.fname.g:tar_shq
+  endif
+  let w:tarfile= a:fname
+  exe "file tarfile:".fname
+
+  " cleanup
+  0d
+  set nomod
+
+  let &report= repkeep
+"  call Dret("tar#Read : w:tarfile<".w:tarfile.">")
+endfun
+
+" ---------------------------------------------------------------------
+" tar#Write: {{{2
+fun! tar#Write(fname)
+"  call Dfunc("tar#Write(fname<".a:fname.">) w:tarfile<".w:tarfile."> tblfile_".winnr()."<".s:tblfile_{winnr()}.">")
+  let repkeep= &report
+  set report=10
+
+  " sanity checks
+  if !executable(g:tar_cmd)
+   redraw!
+   echohl Error | echo '***error*** (tar#Browse) "'.g:tar_cmd.'" not available on your system'
+"   call inputsave()|call input("Press <cr> to continue")|call inputrestore()
+   let &report= repkeep
+"   call Dret("tar#Write")
+   return
+  endif
+  if !exists("*mkdir")
+   redraw!
+   echohl Error | echo "***error*** (tar#Write) sorry, mkdir() doesn't work on your system" | echohl None
+"   call inputsave()|call input("Press <cr> to continue")|call inputrestore()
+   let &report= repkeep
+"   call Dret("tar#Write")
+   return
+  endif
+
+  let curdir= getcwd()
+  let tmpdir= tempname()
+"  call Decho("orig tempname<".tmpdir.">")
+  if tmpdir =~ '\.'
+   let tmpdir= substitute(tmpdir,'\.[^.]*$','','e')
+  endif
+"  call Decho("tmpdir<".tmpdir.">")
+  call mkdir(tmpdir,"p")
+
+  " attempt to change to the indicated directory
+  try
+   exe "cd ".escape(tmpdir,' \')
+  catch /^Vim\%((\a\+)\)\=:E344/
+   redraw!
+   echohl Error | echo "***error*** (tar#Write) cannot cd to temporary directory" | Echohl None
+"   call inputsave()|call input("Press <cr> to continue")|call inputrestore()
+   let &report= repkeep
+"   call Dret("tar#Write")
+   return
+  endtry
+"  call Decho("current directory now: ".getcwd())
+
+  " place temporary files under .../_ZIPVIM_/
+  if isdirectory("_ZIPVIM_")
+   call s:Rmdir("_ZIPVIM_")
+  endif
+  call mkdir("_ZIPVIM_")
+  cd _ZIPVIM_
+"  call Decho("current directory now: ".getcwd())
+
+  let tarfile = substitute(w:tarfile,'tarfile:\(.\{-}\):.*$','\1','')
+  let fname   = substitute(w:tarfile,'tarfile:.\{-}:\(.*\)$','\1','')
+
+  " handle compressed archives
+  if tarfile =~# '\.gz'
+   call system("gzip -d ".tarfile)
+   let tarfile = substitute(tarfile,'\.gz','','e')
+   let compress= "gzip '".tarfile."'"
+  elseif tarfile =~# '\.tgz'
+   call system("gzip -d ".tarfile)
+   let tarfile = substitute(tarfile,'\.tgz','.tar','e')
+   let compress= "gzip '".tarfile."'"
+   let tgz     = 1
+  elseif tarfile =~# '\.bz2'
+   call system("bzip2 -d ".tarfile)
+   let tarfile = substitute(tarfile,'\.bz2','','e')
+   let compress= "bzip2 '".tarfile."'"
+  endif
+
+  if v:shell_error != 0
+   redraw!
+   echohl Error | echo "***error*** (tar#Write) sorry, unable to update ".tarfile." with ".fname | echohl None
+"   call inputsave()|call input("Press <cr> to continue")|call inputrestore()
+  else
+
+"   call Decho("tarfile<".tarfile."> fname<".fname.">")
+ 
+   if fname =~ '/'
+    let dirpath = substitute(fname,'/[^/]\+$','','e')
+    if executable("cygpath")
+     let dirpath = substitute(system("cygpath ".dirpath),'\n','','e')
+    endif
+    call mkdir(dirpath,"p")
+   endif
+   if tarfile !~ '/'
+    let tarfile= curdir.'/'.tarfile
+   endif
+"   call Decho("tarfile<".tarfile."> fname<".fname.">")
+ 
+   exe "w! ".fname
+   if executable("cygpath")
+    let tarfile = substitute(system("cygpath ".tarfile),'\n','','e')
+   endif
+ 
+   " delete old file from tarfile
+"   call Decho("tar --delete -f '".tarfile."' '".fname."'")
+   call system("tar --delete -f '".tarfile."' '".fname."'")
+   if v:shell_error != 0
+    redraw!
+    echohl Error | echo "***error*** (tar#Write) sorry, unable to update ".tarfile." with ".fname | echohl None
+"    call inputsave()|call input("Press <cr> to continue")|call inputrestore()
+   else
+ 
+    " update tarfile with new file 
+"    call Decho("tar -".g:tar_writeoptions." '".tarfile."' '".fname."'")
+    call system("tar -".g:tar_writeoptions." '".tarfile."' '".fname."'")
+    if v:shell_error != 0
+     redraw!
+     echohl Error | echo "***error*** (tar#Write) sorry, unable to update ".tarfile." with ".fname | echohl None
+"     call inputsave()|call input("Press <cr> to continue")|call inputrestore()
+    elseif exists("compress")
+"     call Decho("call system(".compress.")")
+     call system(compress)
+     if exists("tgz")
+"      call Decho("rename(".tarfile.".gz,".substitute(tarfile,'\.tar$','.tgz','e').")")
+      call rename(tarfile.".gz",substitute(tarfile,'\.tar$','.tgz','e'))
+     endif
+    endif
+   endif
+
+   " support writing tarfiles across a network
+   if s:tblfile_{winnr()} =~ '^\a\+://'
+"    call Decho("handle writing <".tarfile."> across network to <".s:tblfile_{winnr()}.">")
+    let tblfile= s:tblfile_{winnr()}
+    1split|enew
+    let binkeep= &binary
+    let eikeep = &ei
+    set binary ei=all
+    exe "e! ".tarfile
+    call netrw#NetWrite(tblfile)
+    let &ei     = eikeep
+    let &binary = binkeep
+    q!
+    unlet s:tblfile_{winnr()}
+   endif
+  endif
+  
+  " cleanup and restore current directory
+  cd ..
+  call s:Rmdir("_ZIPVIM_")
+  exe "cd ".escape(curdir,' \')
+  setlocal nomod
+
+  let &report= repkeep
+"  call Dret("tar#Write")
+endfun
+
+" ---------------------------------------------------------------------
+" Rmdir: {{{2
+fun! s:Rmdir(fname)
+"  call Dfunc("Rmdir(fname<".a:fname.">)")
+  if has("unix")
+   call system("/bin/rm -rf ".a:fname)
+  elseif has("win32") || has("win95") || has("win64") || has("win16")
+   if &shell =~? "sh$"
+    call system("/bin/rm -rf ".a:fname)
+   else
+    call system("del /S ".a:fname)
+   endif
+  endif
+"  call Dret("Rmdir")
+endfun
+
+" ------------------------------------------------------------------------
+" Modelines And Restoration: {{{1
+let &cpo= s:keepcpo
+unlet s:keepcpo
+"  vim:ts=8 fdm=marker
--- /dev/null
+++ b/lib/vimfiles/autoload/vimball.vim
@@ -1,0 +1,630 @@
+" vimball.vim : construct a file containing both paths and files
+" Author:	Charles E. Campbell, Jr.
+" Date:		May 07, 2007
+" Version:	22
+" GetLatestVimScripts: 1502 1 :AutoInstall: vimball.vim
+" Copyright: (c) 2004-2006 by Charles E. Campbell, Jr.
+"            The VIM LICENSE applies to Vimball.vim, and Vimball.txt
+"            (see |copyright|) except use "Vimball" instead of "Vim".
+"            No warranty, express or implied.
+"  *** ***   Use At-Your-Own-Risk!   *** ***
+
+" ---------------------------------------------------------------------
+"  Load Once: {{{1
+if &cp || exists("g:loaded_vimball") || v:version < 700
+ finish
+endif
+let s:keepcpo        = &cpo
+let g:loaded_vimball = "v22"
+set cpo&vim
+
+" =====================================================================
+" Constants: {{{1
+if !exists("s:USAGE")
+ let s:USAGE   = 0
+ let s:WARNING = 1
+ let s:ERROR   = 2
+endif
+
+" =====================================================================
+"  Functions: {{{1
+
+" ---------------------------------------------------------------------
+" vimball#MkVimball: creates a vimball given a list of paths to files {{{2
+" Vimball Format:
+"     path
+"     filesize
+"     [file]
+"     path
+"     filesize
+"     [file]
+fun! vimball#MkVimball(line1,line2,writelevel,...) range
+"  call Dfunc("MkVimball(line1=".a:line1." line2=".a:line2." writelevel=".a:writelevel." vimballname<".a:1.">) a:0=".a:0)
+  if a:1 =~ '.vim' || a:1 =~ '.txt'
+   let vbname= substitute(a:1,'\.\a\{3}$','.vba','')
+  else
+   let vbname= a:1
+  endif
+  if vbname !~ '\.vba$'
+   let vbname= vbname.'.vba'
+  endif
+"  call Decho("vbname<".vbname.">")
+  if a:1 =~ '[\/]'
+   call vimball#ShowMesg(s:ERROR,"(MkVimball) vimball name<".a:1."> should not include slashes")
+"   call Dret("MkVimball : vimball name<".a:1."> should not include slashes")
+   return
+  endif
+  if !a:writelevel && filereadable(vbname)
+   call vimball#ShowMesg(s:ERROR,"(MkVimball) file<".vbname."> exists; use ! to insist")
+"   call Dret("MkVimball : file<".vbname."> already exists; use ! to insist")
+   return
+  endif
+
+  " user option bypass
+  call s:SaveSettings()
+
+  if a:0 >= 2
+   " allow user to specify where to get the files
+   let home= expand(a:2)
+  else
+   " use first existing directory from rtp
+   let home= s:VimballHome()
+  endif
+
+  " save current directory
+  let curdir = getcwd()
+  call s:ChgDir(home)
+
+  " record current tab, initialize while loop index
+  let curtabnr = tabpagenr()
+  let linenr   = a:line1
+"  call Decho("curtabnr=".curtabnr)
+
+  while linenr <= a:line2
+   let svfile  = getline(linenr)
+"   call Decho("svfile<".svfile.">")
+ 
+   if !filereadable(svfile)
+    call vimball#ShowMesg(s:ERROR,"unable to read file<".svfile.">")
+	call s:ChgDir(curdir)
+	call s:RestoreSettings()
+"    call Dret("MkVimball")
+    return
+   endif
+ 
+   " create/switch to mkvimball tab
+   if !exists("vbtabnr")
+    tabnew
+    silent! file Vimball
+    let vbtabnr= tabpagenr()
+   else
+    exe "tabn ".vbtabnr
+   endif
+ 
+   let lastline= line("$") + 1
+   if lastline == 2 && getline("$") == ""
+	call setline(1,'" Vimball Archiver by Charles E. Campbell, Jr., Ph.D.')
+	call setline(2,'UseVimball')
+	call setline(3,'finish')
+	let lastline= line("$") + 1
+   endif
+   call setline(lastline  ,substitute(svfile,'$','	[[[1',''))
+   call setline(lastline+1,0)
+
+   " write the file from the tab
+   let svfilepath= s:Path(svfile,'')
+"   call Decho("exe $r ".svfilepath)
+   exe "$r ".svfilepath
+
+   call setline(lastline+1,line("$") - lastline - 1)
+"   call Decho("lastline=".lastline." line$=".line("$"))
+
+  " restore to normal tab
+   exe "tabn ".curtabnr
+   let linenr= linenr + 1
+  endwhile
+
+  " write the vimball
+  exe "tabn ".vbtabnr
+  call s:ChgDir(curdir)
+  if a:writelevel
+   let vbnamepath= s:Path(vbname,'')
+"   call Decho("exe w! ".vbnamepath)
+   exe "w! ".vbnamepath
+  else
+   let vbnamepath= s:Path(vbname,'')
+"   call Decho("exe w ".vbnamepath)
+   exe "w ".vbnamepath
+  endif
+"  call Decho("Vimball<".vbname."> created")
+  echo "Vimball<".vbname."> created"
+
+  " remove the evidence
+  setlocal nomod bh=wipe
+  exe "tabn ".curtabnr
+  exe "tabc ".vbtabnr
+
+  " restore options
+  call s:RestoreSettings()
+
+"  call Dret("MkVimball")
+endfun
+
+" ---------------------------------------------------------------------
+" vimball#Vimball: extract and distribute contents from a vimball {{{2
+fun! vimball#Vimball(really,...)
+"  call Dfunc("vimball#Vimball(really=".a:really.") a:0=".a:0)
+
+  if getline(1) !~ '^" Vimball Archiver by Charles E. Campbell, Jr., Ph.D.$'
+   echoerr "(Vimball) The current file does not appear to be a Vimball!"
+"   call Dret("vimball#Vimball")
+   return
+  endif
+
+  " set up standard settings
+  call s:SaveSettings()
+  let curtabnr = tabpagenr()
+
+  " set up vimball tab
+"  call Decho("setting up vimball tab")
+  tabnew
+  silent! file Vimball
+  let vbtabnr= tabpagenr()
+  let didhelp= ""
+
+  " go to vim plugin home
+  if a:0 > 0
+   let home= expand(a:1)
+  else
+   let home= s:VimballHome()
+  endif
+"  call Decho("home<".home.">")
+
+  " save current directory and remove older same-named vimball, if any
+  let curdir = getcwd()
+"  call Decho("home<".home.">")
+"  call Decho("curdir<".curdir.">")
+
+  call s:ChgDir(home)
+  call vimball#RmVimball()
+
+  let linenr  = 4
+  let filecnt = 0
+
+  " give title to listing of (extracted) files from Vimball Archive
+  if a:really
+   echohl Title | echomsg "Vimball Archive" | echohl None
+  else
+   echohl Title | echomsg "Vimball Archive Listing" | echohl None
+   echohl Statement | echomsg "files would be placed under: ".home | echohl None
+  endif
+
+  " apportion vimball contents to various files
+"  call Decho("exe tabn ".curtabnr)
+  exe "tabn ".curtabnr
+"  call Decho("linenr=".linenr." line$=".line("$"))
+  while 1 < linenr && linenr < line("$")
+   let fname   = substitute(getline(linenr),'\t\[\[\[1$','','')
+   let fname   = substitute(fname,'\\','/','g')
+   let fsize   = getline(linenr+1)
+   let filecnt = filecnt + 1
+"   call Decho("fname<".fname."> fsize=".fsize." filecnt=".filecnt)
+
+   if a:really
+    echomsg "extracted <".fname.">: ".fsize." lines"
+   else
+    echomsg "would extract <".fname.">: ".fsize." lines"
+   endif
+"   call Decho("using L#".linenr.": will extract file<".fname.">")
+"   call Decho("using L#".(linenr+1).": fsize=".fsize)
+
+   " Allow AsNeeded/ directory to take place of plugin/ directory
+   " when AsNeeded/filename is filereadable
+   if fname =~ '\<plugin/'
+   	let anfname= substitute(fname,'\<plugin/','AsNeeded/','')
+	if filereadable(anfname)
+"	 call Decho("using anfname<".anfname."> instead of <".fname.">")
+	 let fname= anfname
+	endif
+   endif
+
+   " make directories if they don't exist yet
+   if a:really
+"    call Decho("making directories if they don't exist yet (fname<".fname.">)")
+    let fnamebuf= substitute(fname,'\\','/','g')
+	let dirpath = substitute(home,'\\','/','g')
+    while fnamebuf =~ '/'
+     let dirname  = dirpath."/".substitute(fnamebuf,'/.*$','','')
+	 let dirpath  = dirname
+     let fnamebuf = substitute(fnamebuf,'^.\{-}/\(.*\)$','\1','')
+"	 call Decho("dirname<".dirname.">")
+     if !isdirectory(dirname)
+"      call Decho("making <".dirname.">")
+      call mkdir(dirname)
+	  call s:RecordInVar(home,"rmdir('".dirname."')")
+     endif
+    endwhile
+   endif
+   call s:ChgDir(home)
+
+   " grab specified qty of lines and place into "a" buffer
+   " (skip over path/filename and qty-lines)
+   let linenr   = linenr + 2
+   let lastline = linenr + fsize - 1
+"   call Decho("exe ".linenr.",".lastline."yank a")
+   exe "silent ".linenr.",".lastline."yank a"
+
+   " copy "a" buffer into tab
+"   call Decho('copy "a buffer into tab#'.vbtabnr)
+   exe "tabn ".vbtabnr
+   silent! %d
+   silent put a
+   1
+   silent d
+
+   " write tab to file
+   if a:really
+    let fnamepath= s:Path(home."/".fname,'')
+"    call Decho("exe w! ".fnamepath)
+    exe "silent w! ".fnamepath
+    echo "wrote ".fnamepath
+	call s:RecordInVar(home,"call delete('".fnamepath."')")
+   endif
+
+   " return to tab with vimball
+"   call Decho("exe tabn ".curtabnr)
+   exe "tabn ".curtabnr
+
+   " set up help if its a doc/*.txt file
+"   call Decho("didhelp<".didhelp."> fname<".fname.">")
+   if a:really && didhelp == "" && fname =~ 'doc/[^/]\+\.txt$'
+   	let didhelp= substitute(fname,'^\(.*\<doc\)[/\\][^.]*\.txt$','\1','')
+"	call Decho("didhelp<".didhelp.">")
+   endif
+
+   " update for next file
+"   let oldlinenr = linenr " Decho
+   let linenr    = linenr + fsize
+"   call Decho("update linenr= [linenr=".oldlinenr."] + [fsize=".fsize."] = ".linenr)
+  endwhile
+
+  " set up help
+"  call Decho("about to set up help: didhelp<".didhelp.">")
+  if didhelp != ""
+   let htpath= escape(substitute(s:Path(home."/".didhelp,'"'),'"','','g'),' ')
+"   call Decho("exe helptags ".htpath)
+   exe "helptags ".htpath
+   echo "did helptags"
+  endif
+
+  " make sure a "Press ENTER..." prompt appears to keep the messages showing!
+  while filecnt <= &ch
+   echomsg " "
+   let filecnt= filecnt + 1
+  endwhile
+
+  " record actions in <.VimballRecord>
+  call s:RecordInFile(home)
+
+  " restore events, delete tab and buffer
+  exe "tabn ".vbtabnr
+  setlocal nomod bh=wipe
+  exe "tabn ".curtabnr
+  exe "tabc ".vbtabnr
+  call s:RestoreSettings()
+  call s:ChgDir(curdir)
+
+"  call Dret("vimball#Vimball")
+endfun
+
+" ---------------------------------------------------------------------
+" vimball#RmVimball: remove any files, remove any directories made by any {{{2
+"               previous vimball extraction based on a file of the current
+"               name.
+"  Usage:  RmVimball  (assume current file is a vimball; remove)
+"          RmVimball vimballname
+fun! vimball#RmVimball(...)
+"  call Dfunc("vimball#RmVimball() a:0=".a:0)
+  if exists("g:vimball_norecord")
+"   call Dret("vimball#RmVimball : (g:vimball_norecord)")
+   return
+  endif
+  let eikeep= &ei
+  set ei=all
+"  call Decho("turned off all events")
+
+  if a:0 == 0
+   let curfile= '^'.expand("%:tr")
+  else
+   if a:1 =~ '[\/]'
+    call vimball#ShowMesg(s:USAGE,"RmVimball vimballname [path]")
+"    call Dret("vimball#RmVimball : suspect a:1<".a:1.">")
+    return
+   endif
+   let curfile= a:1
+  endif
+  if curfile !~ '.vba$'
+   let curfile= curfile.".vba: "
+  else
+   let curfile= curfile.": "
+  endif
+  if a:0 >= 2
+   let home= expand(a:2)
+  else
+   let home= s:VimballHome()
+  endif
+  let curdir = getcwd()
+"  call Decho("home   <".home.">")
+"  call Decho("curfile<".curfile.">")
+"  call Decho("curdir <".curdir.">")
+
+  call s:ChgDir(home)
+  if filereadable(".VimballRecord")
+"   call Decho(".VimballRecord is readable")
+"   call Decho("curfile<".curfile.">")
+   keepalt keepjumps 1split 
+   silent! keepalt keepjumps e .VimballRecord
+   let keepsrch= @/
+   if search(curfile,'cw')
+   	let exestring= substitute(getline("."),curfile,'','')
+"	call Decho("exe ".exestring)
+	silent! keepalt keepjumps exe exestring
+	silent! keepalt keepjumps d
+   else
+"   	call Decho("unable to find <".curfile."> in .VimballRecord")
+   endif
+   silent! keepalt keepjumps g/^\s*$/d
+   silent! keepalt keepjumps wq!
+   let @/= keepsrch
+  endif
+  call s:ChgDir(curdir)
+
+  " restoring events
+"  call Decho("restoring events")
+  let &ei= eikeep
+
+"  call Dret("vimball#RmVimball")
+endfun
+
+" ---------------------------------------------------------------------
+" vimball#Decompress: attempts to automatically decompress vimballs {{{2
+fun! vimball#Decompress(fname)
+"  call Dfunc("Decompress(fname<".a:fname.">)")
+
+  " decompression:
+  if     expand("%") =~ '.*\.gz'  && executable("gunzip")
+   exe "!gunzip ".a:fname
+   let fname= substitute(a:fname,'\.gz$','','')
+   exe "e ".escape(fname,' \')
+   call vimball#ShowMesg(s:USAGE,"Source this file to extract it! (:so %)")
+  elseif expand("%") =~ '.*\.bz2' && executable("bunzip2")
+   exe "!bunzip2 ".a:fname
+   let fname= substitute(a:fname,'\.bz2$','','')
+   exe "e ".escape(fname,' \')
+   call vimball#ShowMesg(s:USAGE,"Source this file to extract it! (:so %)")
+  elseif expand("%") =~ '.*\.zip' && executable("unzip")
+   exe "!unzip ".a:fname
+   let fname= substitute(a:fname,'\.zip$','','')
+   exe "e ".escape(fname,' \')
+   call vimball#ShowMesg(s:USAGE,"Source this file to extract it! (:so %)")
+  endif
+  set noma bt=nofile fmr=[[[,]]] fdm=marker
+
+"  call Dret("Decompress")
+endfun
+
+" ---------------------------------------------------------------------
+" vimball#ShowMesg: {{{2
+fun! vimball#ShowMesg(level,msg)
+"  call Dfunc("vimball#ShowMesg(level=".a:level." msg<".a:msg.">)")
+  let rulerkeep   = &ruler
+  let showcmdkeep = &showcmd
+  set noruler noshowcmd
+  redraw!
+
+  if &fo =~ '[ta]'
+   echomsg "***vimball*** " a:msg
+  else
+   if a:level == s:WARNING || a:level == s:USAGE
+    echohl WarningMsg
+   elseif a:level == s:ERROR
+    echohl Error
+   endif
+   echomsg "***vimball*** " a:msg
+   echohl None
+  endif
+
+  if a:level != s:USAGE
+   call inputsave()|let ok= input("Press <cr> to continue")|call inputrestore()
+  endif
+
+  let &ruler   = rulerkeep
+  let &showcmd = showcmdkeep
+
+"  call Dret("vimball#ShowMesg")
+endfun
+
+" ---------------------------------------------------------------------
+let &cpo= s:keepcpo
+unlet s:keepcpo
+" =====================================================================
+" s:ChgDir: change directory (in spite of Windoze) {{{2
+fun! s:ChgDir(newdir)
+"  call Dfunc("ChgDir(newdir<".a:newdir.">)")
+  if (has("win32") || has("win95") || has("win64") || has("win16"))
+    exe 'silent cd '.escape(substitute(a:newdir,'/','\\','g'),' ')
+  else
+   exe 'silent cd '.escape(a:newdir,' ')
+  endif
+"  call Dret("ChgDir")
+endfun
+
+" ---------------------------------------------------------------------
+" s:Path: prepend and append quotes, do escaping, as necessary {{{2
+fun! s:Path(cmd,quote)
+"  call Dfunc("Path(cmd<".a:cmd."> quote<".a:quote.">)")
+  if (has("win32") || has("win95") || has("win64") || has("win16"))
+   let cmdpath= a:quote.substitute(a:cmd,'/','\\','g').a:quote
+  else
+   let cmdpath= a:quote.a:cmd.a:quote
+  endif
+  if a:quote == ""
+   let cmdpath= escape(cmdpath,' ')
+  endif
+"  call Dret("Path <".cmdpath.">")
+  return cmdpath
+endfun
+
+" ---------------------------------------------------------------------
+" s:RecordInVar: record a un-vimball command in the .VimballRecord file {{{2
+fun! s:RecordInVar(home,cmd)
+"  call Dfunc("RecordInVar(home<".a:home."> cmd<".a:cmd.">)")
+  if a:cmd =~ '^rmdir'
+"   if !exists("s:recorddir")
+"    let s:recorddir= substitute(a:cmd,'^rmdir',"call s:Rmdir",'')
+"   else
+"    let s:recorddir= s:recorddir."|".substitute(a:cmd,'^rmdir',"call s:Rmdir",'')
+"   endif
+"   call Decho("recorddir=".s:recorddir)
+  elseif !exists("s:recordfile")
+   let s:recordfile= a:cmd
+"   call Decho("recordfile=".s:recordfile)
+  else
+   let s:recordfile= s:recordfile."|".a:cmd
+"   call Decho("recordfile=".s:recordfile)
+  endif
+"  call Dret("RecordInVar")
+endfun
+
+" ---------------------------------------------------------------------
+" s:RecordInFile: {{{2
+fun! s:RecordInFile(home)
+"  call Dfunc("RecordInFile()")
+  if exists("g:vimball_norecord")
+"   call Dret("RecordInFile : (g:vimball_norecord)")
+   return
+  endif
+
+  if exists("s:recordfile") || exists("s:recorddir")
+   let curdir= getcwd()
+   call s:ChgDir(a:home)
+   keepalt keepjumps 1split 
+   let cmd= expand("%:tr").": "
+   silent! keepalt keepjumps e .VimballRecord
+   $
+   if exists("s:recordfile") && exists("s:recorddir")
+   	let cmd= cmd.s:recordfile."|".s:recorddir
+   elseif exists("s:recorddir")
+   	let cmd= cmd.s:recorddir
+   elseif exists("s:recordfile")
+   	let cmd= cmd.s:recordfile
+   else
+"    call Dret("RecordInFile")
+	return
+   endif
+   keepalt keepjumps put=cmd
+   silent! keepalt keepjumps g/^\s*$/d
+   silent! keepalt keepjumps wq!
+   call s:ChgDir(curdir)
+   if exists("s:recorddir") |unlet s:recorddir |endif
+   if exists("s:recordfile")|unlet s:recordfile|endif
+  else
+"   call Decho("s:record[file|dir] doesn't exist")
+  endif
+
+"  call Dret("RecordInFile")
+endfun
+
+" ---------------------------------------------------------------------
+" s:Rmdir: {{{2
+"fun! s:Rmdir(dirname)
+""  call Dfunc("s:Rmdir(dirname<".a:dirname.">)")
+"  if (has("win32") || has("win95") || has("win64") || has("win16")) && &shell !~? 'sh$'
+"    call system("del ".a:dirname)
+"  else
+"   call system("rmdir ".a:dirname)
+"  endif
+""  call Dret("s:Rmdir")
+"endfun
+
+" ---------------------------------------------------------------------
+" s:VimballHome: determine/get home directory path (usually from rtp) {{{2
+fun! s:VimballHome()
+"  call Dfunc("VimballHome()")
+  if exists("g:vimball_home")
+   let home= g:vimball_home
+  else
+   " go to vim plugin home
+   for home in split(&rtp,',') + ['']
+    if isdirectory(home) && filewritable(home) | break | endif
+   endfor
+   if home == ""
+    " just pick the first directory
+    let home= substitute(&rtp,',.*$','','')
+   endif
+   if (has("win32") || has("win95") || has("win64") || has("win16"))
+    let home= substitute(home,'/','\\','g')
+   endif
+  endif
+"  call Dret("VimballHome <".home.">")
+  return home
+endfun
+
+" ---------------------------------------------------------------------
+" s:SaveSettings: {{{2
+fun! s:SaveSettings()
+"  call Dfunc("SaveSettings()")
+  let s:makeep  = getpos("'a")
+  let s:regakeep= @a
+  if exists("&acd")
+   let s:acdkeep = &acd
+  endif
+  let s:eikeep  = &ei
+  let s:fenkeep = &fen
+  let s:hidkeep = &hidden
+  let s:ickeep  = &ic
+  let s:lzkeep  = &lz
+  let s:pmkeep  = &pm
+  let s:repkeep = &report
+  let s:vekeep  = &ve
+  if exists("&acd")
+   set ei=all ve=all noacd nofen noic report=999 nohid bt= ma lz pm=
+  else
+   set ei=all ve=all nofen noic report=999 nohid bt= ma lz pm=
+  endif
+"  call Dret("SaveSettings")
+endfun
+
+" ---------------------------------------------------------------------
+" s:RestoreSettings: {{{2
+fun! s:RestoreSettings()
+"  call Dfunc("RestoreSettings()")
+  let @a      = s:regakeep
+  if exists("&acd")
+   let &acd   = s:acdkeep
+  endif
+  let &fen    = s:fenkeep
+  let &hidden = s:hidkeep
+  let &ic     = s:ickeep
+  let &lz     = s:lzkeep
+  let &pm     = s:pmkeep
+  let &report = s:repkeep
+  let &ve     = s:vekeep
+  let &ei     = s:eikeep
+  if s:makeep[0] != 0
+   " restore mark a
+"   call Decho("restore mark-a: makeep=".string(makeep))
+   call setpos("'a",s:makeep)
+  endif
+  if exists("&acd")
+   unlet s:regakeep s:acdkeep s:eikeep s:fenkeep s:hidkeep s:ickeep s:repkeep s:vekeep s:makeep s:lzkeep s:pmkeep
+  else
+   unlet s:regakeep s:eikeep s:fenkeep s:hidkeep s:ickeep s:repkeep s:vekeep s:makeep s:lzkeep s:pmkeep
+  endif
+  set bt=nofile noma
+"  call Dret("RestoreSettings")
+endfun
+
+" ---------------------------------------------------------------------
+" Modelines: {{{1
+" vim: fdm=marker
--- /dev/null
+++ b/lib/vimfiles/autoload/xml/html32.vim
@@ -1,0 +1,384 @@
+let g:xmldata_html32 = {
+\ 'vimxmlentities': ['AElig', 'Aacute', 'Acirc', 'Agrave', 'Aring', 'Atilde', 'Auml', 'Ccedil', 'ETH', 'Eacute', 'Ecirc', 'Egrave', 'Euml', 'Iacute', 'Icirc', 'Igrave', 'Iuml', 'Ntilde', 'Oacute', 'Ocirc', 'Ograve', 'Oslash', 'Otilde', 'Ouml', 'THORN', 'Uacute', 'Ucirc', 'Ugrave', 'Uuml', 'Yacute', 'aacute', 'acirc', 'acute', 'aelig', 'agrave', 'amp', 'aring', 'atilde', 'auml', 'brvbar', 'ccedil', 'cedil', 'cent', 'copy', 'curren', 'deg', 'divide', 'eacute', 'ecirc', 'egrave', 'eth', 'euml', 'frac12', 'frac14', 'frac34', 'gt', 'iacute', 'icirc', 'iexcl', 'igrave', 'iquest', 'iuml', 'laquo', 'lt', 'macr', 'micro', 'middot', 'nbsp', 'not', 'ntilde', 'oacute', 'ocirc', 'ograve', 'ordf', 'ordm', 'oslash', 'otilde', 'ouml', 'para', 'plusmn', 'pound', 'raquo', 'reg', 'sect', 'shy', 'sup1', 'sup2', 'sup3', 'szlig', 'thorn', 'times', 'uacute', 'ucirc', 'ugrave', 'uml', 'uuml', 'yacute', 'yen', 'yuml'],
+\ 'vimxmlroot': ['html'],
+\ 'a': [
+\ ['tt', 'i', 'b', 'u', 'strike', 'big', 'small', 'sub', 'sup', 'em', 'strong', 'dfn', 'code', 'samp', 'kbd', 'var', 'cite', 'img', 'applet', 'font', 'basefont', 'br', 'script', 'map', 'input', 'select', 'textarea'],
+\ { 'rel': [], 'href': [], 'name': [], 'rev': [], 'title': []}
+\ ],
+\ 'address': [
+\ ['tt', 'i', 'b', 'u', 'strike', 'big', 'small', 'sub', 'sup', 'em', 'strong', 'dfn', 'code', 'samp', 'kbd', 'var', 'cite', 'a', 'img', 'applet', 'font', 'basefont', 'br', 'script', 'map', 'input', 'select', 'textarea', 'p'],
+\ { }
+\ ],
+\ 'applet': [
+\ ['param', 'tt', 'i', 'b', 'u', 'strike', 'big', 'small', 'sub', 'sup', 'em', 'strong', 'dfn', 'code', 'samp', 'kbd', 'var', 'cite', 'a', 'img', 'applet', 'font', 'basefont', 'br', 'script', 'map', 'input', 'select', 'textarea'],
+\ { 'width': [], 'vspace': [], 'alt': [], 'align': ['top', 'middle', 'bottom', 'left', 'right'], 'name': [], 'height': [], 'hspace': [], 'codebase': [], 'code': []}
+\ ],
+\ 'area': [
+\ [],
+\ { 'alt': [], 'coords': [], 'nohref': ['BOOL'], 'href': [], 'shape': ['rect', 'circle', 'poly']}
+\ ],
+\ 'b': [
+\ ['tt', 'i', 'b', 'u', 'strike', 'big', 'small', 'sub', 'sup', 'em', 'strong', 'dfn', 'code', 'samp', 'kbd', 'var', 'cite', 'a', 'img', 'applet', 'font', 'basefont', 'br', 'script', 'map', 'input', 'select', 'textarea'],
+\ { }
+\ ],
+\ 'base': [
+\ [],
+\ { 'href': []}
+\ ],
+\ 'basefont': [
+\ [],
+\ { 'size': []}
+\ ],
+\ 'big': [
+\ ['tt', 'i', 'b', 'u', 'strike', 'big', 'small', 'sub', 'sup', 'em', 'strong', 'dfn', 'code', 'samp', 'kbd', 'var', 'cite', 'a', 'img', 'applet', 'font', 'basefont', 'br', 'script', 'map', 'input', 'select', 'textarea'],
+\ { }
+\ ],
+\ 'blockquote': [
+\ ['h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'tt', 'i', 'b', 'u', 'strike', 'big', 'small', 'sub', 'sup', 'em', 'strong', 'dfn', 'code', 'samp', 'kbd', 'var', 'cite', 'a', 'img', 'applet', 'font', 'basefont', 'br', 'script', 'map', 'input', 'select', 'textarea', 'p', 'ul', 'ol', 'dir', 'menu', 'pre', 'xmp', 'listing', 'dl', 'div', 'center', 'blockquote', 'form', 'isindex', 'hr', 'table', 'address'],
+\ { }
+\ ],
+\ 'body': [
+\ ['h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'tt', 'i', 'b', 'u', 'strike', 'big', 'small', 'sub', 'sup', 'em', 'strong', 'dfn', 'code', 'samp', 'kbd', 'var', 'cite', 'a', 'img', 'applet', 'font', 'basefont', 'br', 'script', 'map', 'input', 'select', 'textarea', 'p', 'ul', 'ol', 'dir', 'menu', 'pre', 'xmp', 'listing', 'dl', 'div', 'center', 'blockquote', 'form', 'isindex', 'hr', 'table', 'address'],
+\ { 'link': [], 'vlink': [], 'background': [], 'alink': [], 'bgcolor': [], 'text': []}
+\ ],
+\ 'br': [
+\ [],
+\ { 'clear': ['none', 'left', 'all', 'right', 'none']}
+\ ],
+\ 'caption': [
+\ ['tt', 'i', 'b', 'u', 'strike', 'big', 'small', 'sub', 'sup', 'em', 'strong', 'dfn', 'code', 'samp', 'kbd', 'var', 'cite', 'a', 'img', 'applet', 'font', 'basefont', 'br', 'script', 'map', 'input', 'select', 'textarea'],
+\ { 'align': ['top', 'bottom']}
+\ ],
+\ 'center': [
+\ ['h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'tt', 'i', 'b', 'u', 'strike', 'big', 'small', 'sub', 'sup', 'em', 'strong', 'dfn', 'code', 'samp', 'kbd', 'var', 'cite', 'a', 'img', 'applet', 'font', 'basefont', 'br', 'script', 'map', 'input', 'select', 'textarea', 'p', 'ul', 'ol', 'dir', 'menu', 'pre', 'xmp', 'listing', 'dl', 'div', 'center', 'blockquote', 'form', 'isindex', 'hr', 'table', 'address'],
+\ { }
+\ ],
+\ 'cite': [
+\ ['tt', 'i', 'b', 'u', 'strike', 'big', 'small', 'sub', 'sup', 'em', 'strong', 'dfn', 'code', 'samp', 'kbd', 'var', 'cite', 'a', 'img', 'applet', 'font', 'basefont', 'br', 'script', 'map', 'input', 'select', 'textarea'],
+\ { }
+\ ],
+\ 'code': [
+\ ['tt', 'i', 'b', 'u', 'strike', 'big', 'small', 'sub', 'sup', 'em', 'strong', 'dfn', 'code', 'samp', 'kbd', 'var', 'cite', 'a', 'img', 'applet', 'font', 'basefont', 'br', 'script', 'map', 'input', 'select', 'textarea'],
+\ { }
+\ ],
+\ 'dd': [
+\ ['tt', 'i', 'b', 'u', 'strike', 'big', 'small', 'sub', 'sup', 'em', 'strong', 'dfn', 'code', 'samp', 'kbd', 'var', 'cite', 'a', 'img', 'applet', 'font', 'basefont', 'br', 'script', 'map', 'input', 'select', 'textarea', 'p', 'ul', 'ol', 'dir', 'menu', 'pre', 'xmp', 'listing', 'dl', 'div', 'center', 'blockquote', 'form', 'isindex', 'hr', 'table'],
+\ { }
+\ ],
+\ 'dfn': [
+\ ['tt', 'i', 'b', 'u', 'strike', 'big', 'small', 'sub', 'sup', 'em', 'strong', 'dfn', 'code', 'samp', 'kbd', 'var', 'cite', 'a', 'img', 'applet', 'font', 'basefont', 'br', 'script', 'map', 'input', 'select', 'textarea'],
+\ { }
+\ ],
+\ 'dir': [
+\ ['li'],
+\ { 'compact': ['BOOL']}
+\ ],
+\ 'div': [
+\ ['h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'tt', 'i', 'b', 'u', 'strike', 'big', 'small', 'sub', 'sup', 'em', 'strong', 'dfn', 'code', 'samp', 'kbd', 'var', 'cite', 'a', 'img', 'applet', 'font', 'basefont', 'br', 'script', 'map', 'input', 'select', 'textarea', 'p', 'ul', 'ol', 'dir', 'menu', 'pre', 'xmp', 'listing', 'dl', 'div', 'center', 'blockquote', 'form', 'isindex', 'hr', 'table', 'address'],
+\ { 'align': ['left', 'center', 'right']}
+\ ],
+\ 'dl': [
+\ ['dt', 'dd'],
+\ { 'compact': ['BOOL']}
+\ ],
+\ 'dt': [
+\ ['tt', 'i', 'b', 'u', 'strike', 'big', 'small', 'sub', 'sup', 'em', 'strong', 'dfn', 'code', 'samp', 'kbd', 'var', 'cite', 'a', 'img', 'applet', 'font', 'basefont', 'br', 'script', 'map', 'input', 'select', 'textarea'],
+\ { }
+\ ],
+\ 'em': [
+\ ['tt', 'i', 'b', 'u', 'strike', 'big', 'small', 'sub', 'sup', 'em', 'strong', 'dfn', 'code', 'samp', 'kbd', 'var', 'cite', 'a', 'img', 'applet', 'font', 'basefont', 'br', 'script', 'map', 'input', 'select', 'textarea'],
+\ { }
+\ ],
+\ 'font': [
+\ ['tt', 'i', 'b', 'u', 'strike', 'big', 'small', 'sub', 'sup', 'em', 'strong', 'dfn', 'code', 'samp', 'kbd', 'var', 'cite', 'a', 'img', 'applet', 'font', 'basefont', 'br', 'script', 'map', 'input', 'select', 'textarea'],
+\ { 'size': [], 'color': []}
+\ ],
+\ 'form': [
+\ ['h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'tt', 'i', 'b', 'u', 'strike', 'big', 'small', 'sub', 'sup', 'em', 'strong', 'dfn', 'code', 'samp', 'kbd', 'var', 'cite', 'a', 'img', 'applet', 'font', 'basefont', 'br', 'script', 'map', 'input', 'select', 'textarea', 'p', 'ul', 'ol', 'dir', 'menu', 'pre', 'xmp', 'listing', 'dl', 'div', 'center', 'blockquote', 'isindex', 'hr', 'table', 'address'],
+\ { 'enctype': ['application/x-www-form-urlencoded'], 'action': [], 'method': ['GET', 'POST']}
+\ ],
+\ 'h1': [
+\ ['tt', 'i', 'b', 'u', 'strike', 'big', 'small', 'sub', 'sup', 'em', 'strong', 'dfn', 'code', 'samp', 'kbd', 'var', 'cite', 'a', 'img', 'applet', 'font', 'basefont', 'br', 'script', 'map', 'input', 'select', 'textarea'],
+\ { 'align': ['left', 'center', 'right']}
+\ ],
+\ 'h2': [
+\ ['tt', 'i', 'b', 'u', 'strike', 'big', 'small', 'sub', 'sup', 'em', 'strong', 'dfn', 'code', 'samp', 'kbd', 'var', 'cite', 'a', 'img', 'applet', 'font', 'basefont', 'br', 'script', 'map', 'input', 'select', 'textarea'],
+\ { 'align': ['left', 'center', 'right']}
+\ ],
+\ 'h3': [
+\ ['tt', 'i', 'b', 'u', 'strike', 'big', 'small', 'sub', 'sup', 'em', 'strong', 'dfn', 'code', 'samp', 'kbd', 'var', 'cite', 'a', 'img', 'applet', 'font', 'basefont', 'br', 'script', 'map', 'input', 'select', 'textarea'],
+\ { 'align': ['left', 'center', 'right']}
+\ ],
+\ 'h4': [
+\ ['tt', 'i', 'b', 'u', 'strike', 'big', 'small', 'sub', 'sup', 'em', 'strong', 'dfn', 'code', 'samp', 'kbd', 'var', 'cite', 'a', 'img', 'applet', 'font', 'basefont', 'br', 'script', 'map', 'input', 'select', 'textarea'],
+\ { 'align': ['left', 'center', 'right']}
+\ ],
+\ 'h5': [
+\ ['tt', 'i', 'b', 'u', 'strike', 'big', 'small', 'sub', 'sup', 'em', 'strong', 'dfn', 'code', 'samp', 'kbd', 'var', 'cite', 'a', 'img', 'applet', 'font', 'basefont', 'br', 'script', 'map', 'input', 'select', 'textarea'],
+\ { 'align': ['left', 'center', 'right']}
+\ ],
+\ 'h6': [
+\ ['tt', 'i', 'b', 'u', 'strike', 'big', 'small', 'sub', 'sup', 'em', 'strong', 'dfn', 'code', 'samp', 'kbd', 'var', 'cite', 'a', 'img', 'applet', 'font', 'basefont', 'br', 'script', 'map', 'input', 'select', 'textarea'],
+\ { 'align': ['left', 'center', 'right']}
+\ ],
+\ 'head': [
+\ ['title', 'isindex', 'base', 'script', 'style', 'meta', 'link'],
+\ { }
+\ ],
+\ 'hr': [
+\ [],
+\ { 'width': [], 'align': ['left', 'right', 'center'], 'size': [], 'noshade': ['BOOL']}
+\ ],
+\ 'html': [
+\ ['head', 'body', 'plaintext'],
+\ { 'version': ['-//W3C//DTD HTML 3.2 Final//EN']}
+\ ],
+\ 'i': [
+\ ['tt', 'i', 'b', 'u', 'strike', 'big', 'small', 'sub', 'sup', 'em', 'strong', 'dfn', 'code', 'samp', 'kbd', 'var', 'cite', 'a', 'img', 'applet', 'font', 'basefont', 'br', 'script', 'map', 'input', 'select', 'textarea'],
+\ { }
+\ ],
+\ 'img': [
+\ [],
+\ { 'width': [], 'vspace': [], 'alt': [], 'align': ['top', 'middle', 'bottom', 'left', 'right'], 'usemap': [], 'ismap': ['BOOL'], 'src': [], 'height': [], 'border': [], 'hspace': []}
+\ ],
+\ 'input': [
+\ [],
+\ { 'maxlength': [], 'align': ['top', 'middle', 'bottom', 'left', 'right'], 'value': [], 'src': [], 'name': [], 'size': [], 'checked': ['BOOL'], 'type': ['TEXT', 'PASSWORD', 'CHECKBOX', 'RADIO', 'SUBMIT', 'RESET', 'FILE', 'IMAGE']}
+\ ],
+\ 'isindex': [
+\ [],
+\ { 'prompt': []}
+\ ],
+\ 'kbd': [
+\ ['tt', 'i', 'b', 'u', 'strike', 'big', 'small', 'sub', 'sup', 'em', 'strong', 'dfn', 'code', 'samp', 'kbd', 'var', 'cite', 'a', 'img', 'applet', 'font', 'basefont', 'br', 'script', 'map', 'input', 'select', 'textarea'],
+\ { }
+\ ],
+\ 'li': [
+\ ['tt', 'i', 'b', 'u', 'strike', 'big', 'small', 'sub', 'sup', 'em', 'strong', 'dfn', 'code', 'samp', 'kbd', 'var', 'cite', 'a', 'img', 'applet', 'font', 'basefont', 'br', 'script', 'map', 'input', 'select', 'textarea', 'p', 'ul', 'ol', 'dir', 'menu', 'pre', 'xmp', 'listing', 'dl', 'div', 'center', 'blockquote', 'form', 'isindex', 'hr', 'table'],
+\ { 'value': [], 'type': []}
+\ ],
+\ 'link': [
+\ [],
+\ { 'rel': [], 'href': [], 'rev': [], 'title': []}
+\ ],
+\ 'listing': [
+\ [],
+\ { }
+\ ],
+\ 'map': [
+\ ['area'],
+\ { 'name': []}
+\ ],
+\ 'menu': [
+\ ['li'],
+\ { 'compact': ['BOOL']}
+\ ],
+\ 'meta': [
+\ [],
+\ { 'http-equiv': [], 'name': [], 'content': []}
+\ ],
+\ 'ol': [
+\ ['li'],
+\ { 'compact': ['BOOL'], 'type': [], 'start': []}
+\ ],
+\ 'option': [
+\ [''],
+\ { 'value': [], 'selected': ['BOOL']}
+\ ],
+\ 'p': [
+\ ['tt', 'i', 'b', 'u', 'strike', 'big', 'small', 'sub', 'sup', 'em', 'strong', 'dfn', 'code', 'samp', 'kbd', 'var', 'cite', 'a', 'img', 'applet', 'font', 'basefont', 'br', 'script', 'map', 'input', 'select', 'textarea'],
+\ { 'align': ['left', 'center', 'right']}
+\ ],
+\ 'param': [
+\ [],
+\ { 'value': [], 'name': []}
+\ ],
+\ 'plaintext': [
+\ [],
+\ { }
+\ ],
+\ 'pre': [
+\ ['tt', 'i', 'b', 'u', 'strike', 'em', 'strong', 'dfn', 'code', 'samp', 'kbd', 'var', 'cite', 'a', 'applet', 'basefont', 'br', 'script', 'map', 'input', 'select', 'textarea'],
+\ { 'width': ['#implied']}
+\ ],
+\ 'samp': [
+\ ['tt', 'i', 'b', 'u', 'strike', 'big', 'small', 'sub', 'sup', 'em', 'strong', 'dfn', 'code', 'samp', 'kbd', 'var', 'cite', 'a', 'img', 'applet', 'font', 'basefont', 'br', 'script', 'map', 'input', 'select', 'textarea'],
+\ { }
+\ ],
+\ 'script': [
+\ [],
+\ { }
+\ ],
+\ 'select': [
+\ ['option'],
+\ { 'name': [], 'size': [], 'multiple': ['BOOL']}
+\ ],
+\ 'small': [
+\ ['tt', 'i', 'b', 'u', 'strike', 'big', 'small', 'sub', 'sup', 'em', 'strong', 'dfn', 'code', 'samp', 'kbd', 'var', 'cite', 'a', 'img', 'applet', 'font', 'basefont', 'br', 'script', 'map', 'input', 'select', 'textarea'],
+\ { }
+\ ],
+\ 'strike': [
+\ ['tt', 'i', 'b', 'u', 'strike', 'big', 'small', 'sub', 'sup', 'em', 'strong', 'dfn', 'code', 'samp', 'kbd', 'var', 'cite', 'a', 'img', 'applet', 'font', 'basefont', 'br', 'script', 'map', 'input', 'select', 'textarea'],
+\ { }
+\ ],
+\ 'strong': [
+\ ['tt', 'i', 'b', 'u', 'strike', 'big', 'small', 'sub', 'sup', 'em', 'strong', 'dfn', 'code', 'samp', 'kbd', 'var', 'cite', 'a', 'img', 'applet', 'font', 'basefont', 'br', 'script', 'map', 'input', 'select', 'textarea'],
+\ { }
+\ ],
+\ 'style': [
+\ [],
+\ { }
+\ ],
+\ 'sub': [
+\ ['tt', 'i', 'b', 'u', 'strike', 'big', 'small', 'sub', 'sup', 'em', 'strong', 'dfn', 'code', 'samp', 'kbd', 'var', 'cite', 'a', 'img', 'applet', 'font', 'basefont', 'br', 'script', 'map', 'input', 'select', 'textarea'],
+\ { }
+\ ],
+\ 'sup': [
+\ ['tt', 'i', 'b', 'u', 'strike', 'big', 'small', 'sub', 'sup', 'em', 'strong', 'dfn', 'code', 'samp', 'kbd', 'var', 'cite', 'a', 'img', 'applet', 'font', 'basefont', 'br', 'script', 'map', 'input', 'select', 'textarea'],
+\ { }
+\ ],
+\ 'table': [
+\ ['caption', 'tr'],
+\ { 'width': [], 'align': ['left', 'center', 'right'], 'border': [], 'cellspacing': [], 'cellpadding': []}
+\ ],
+\ 'td': [
+\ ['h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'tt', 'i', 'b', 'u', 'strike', 'big', 'small', 'sub', 'sup', 'em', 'strong', 'dfn', 'code', 'samp', 'kbd', 'var', 'cite', 'a', 'img', 'applet', 'font', 'basefont', 'br', 'script', 'map', 'input', 'select', 'textarea', 'p', 'ul', 'ol', 'dir', 'menu', 'pre', 'xmp', 'listing', 'dl', 'div', 'center', 'blockquote', 'form', 'isindex', 'hr', 'table', 'address'],
+\ { 'width': [], 'align': ['left', 'center', 'right'], 'nowrap': ['BOOL'], 'valign': ['top', 'middle', 'bottom'], 'height': [], 'rowspan': ['1'], 'colspan': ['1']}
+\ ],
+\ 'textarea': [
+\ [''],
+\ { 'name': [], 'rows': [], 'cols': []}
+\ ],
+\ 'th': [
+\ ['h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'tt', 'i', 'b', 'u', 'strike', 'big', 'small', 'sub', 'sup', 'em', 'strong', 'dfn', 'code', 'samp', 'kbd', 'var', 'cite', 'a', 'img', 'applet', 'font', 'basefont', 'br', 'script', 'map', 'input', 'select', 'textarea', 'p', 'ul', 'ol', 'dir', 'menu', 'pre', 'xmp', 'listing', 'dl', 'div', 'center', 'blockquote', 'form', 'isindex', 'hr', 'table', 'address'],
+\ { 'width': [], 'align': ['left', 'center', 'right'], 'nowrap': ['BOOL'], 'valign': ['top', 'middle', 'bottom'], 'height': [], 'rowspan': ['1'], 'colspan': ['1']}
+\ ],
+\ 'title': [
+\ [''],
+\ { }
+\ ],
+\ 'tr': [
+\ ['th', 'td'],
+\ { 'align': ['left', 'center', 'right'], 'valign': ['top', 'middle', 'bottom']}
+\ ],
+\ 'tt': [
+\ ['tt', 'i', 'b', 'u', 'strike', 'big', 'small', 'sub', 'sup', 'em', 'strong', 'dfn', 'code', 'samp', 'kbd', 'var', 'cite', 'a', 'img', 'applet', 'font', 'basefont', 'br', 'script', 'map', 'input', 'select', 'textarea'],
+\ { }
+\ ],
+\ 'u': [
+\ ['tt', 'i', 'b', 'u', 'strike', 'big', 'small', 'sub', 'sup', 'em', 'strong', 'dfn', 'code', 'samp', 'kbd', 'var', 'cite', 'a', 'img', 'applet', 'font', 'basefont', 'br', 'script', 'map', 'input', 'select', 'textarea'],
+\ { }
+\ ],
+\ 'ul': [
+\ ['li'],
+\ { 'compact': ['BOOL'], 'type': ['disc', 'square', 'circle']}
+\ ],
+\ 'var': [
+\ ['tt', 'i', 'b', 'u', 'strike', 'big', 'small', 'sub', 'sup', 'em', 'strong', 'dfn', 'code', 'samp', 'kbd', 'var', 'cite', 'a', 'img', 'applet', 'font', 'basefont', 'br', 'script', 'map', 'input', 'select', 'textarea'],
+\ { }
+\ ],
+\ 'xmp': [
+\ [],
+\ { }
+\ ],
+\ 'vimxmlattrinfo' : {
+\ 'accept' : ['ContentType', ''],
+\ 'accesskey' : ['Character', ''],
+\ 'action' : ['*URI', ''],
+\ 'align' : ['String', ''],
+\ 'alt' : ['*Text', ''],
+\ 'archive' : ['UriList', ''],
+\ 'axis' : ['CDATA', ''],
+\ 'border' : ['Pixels', ''],
+\ 'cellpadding' : ['Length', ''],
+\ 'cellspacing' : ['Length', ''],
+\ 'char' : ['Character', ''],
+\ 'charoff' : ['Length', ''],
+\ 'charset' : ['LangCode', ''],
+\ 'checked' : ['Bool', ''],
+\ 'class' : ['CDATA', ''],
+\ 'codetype' : ['ContentType', ''],
+\ 'cols' : ['*Number', ''],
+\ 'colspan' : ['Number', ''],
+\ 'content' : ['*CDATA', ''],
+\ 'coords' : ['Coords', ''],
+\ 'data' : ['URI', ''],
+\ 'datetime' : ['DateTime', ''],
+\ 'declare' : ['Bool', ''],
+\ 'defer' : ['Bool', ''],
+\ 'dir' : ['String', ''],
+\ 'disabled' : ['Bool', ''],
+\ 'enctype' : ['ContentType', ''],
+\ 'for' : ['ID', ''],
+\ 'headers' : ['IDREFS', ''],
+\ 'height' : ['Number', ''],
+\ 'href' : ['*URI', ''],
+\ 'hreflang' : ['LangCode', ''],
+\ 'id' : ['ID', ''],
+\ 'ismap' : ['Bool', ''],
+\ 'label' : ['*Text', ''],
+\ 'lang' : ['LangCode', ''],
+\ 'longdesc' : ['URI', ''],
+\ 'maxlength' : ['Number', ''],
+\ 'media' : ['MediaDesc', ''],
+\ 'method' : ['String', ''],
+\ 'multiple' : ['Bool', ''],
+\ 'name' : ['CDATA', ''],
+\ 'nohref' : ['Bool', ''],
+\ 'onblur' : ['Script', ''],
+\ 'onchange' : ['Script', ''],
+\ 'onclick' : ['Script', ''],
+\ 'ondblclick' : ['Script', ''],
+\ 'onfocus' : ['Script', ''],
+\ 'onkeydown' : ['Script', ''],
+\ 'onkeypress' : ['Script', ''],
+\ 'onkeyup' : ['Script', ''],
+\ 'onload' : ['Script', ''],
+\ 'onmousedown' : ['Script', ''],
+\ 'onmousemove' : ['Script', ''],
+\ 'onmouseout' : ['Script', ''],
+\ 'onmouseover' : ['Script', ''],
+\ 'onmouseup' : ['Script', ''],
+\ 'onreset' : ['Script', ''],
+\ 'onselect' : ['Script', ''],
+\ 'onsubmit' : ['Script', ''],
+\ 'onunload' : ['Script', ''],
+\ 'profile' : ['URI', ''],
+\ 'readonly' : ['Bool', ''],
+\ 'rel' : ['LinkTypes', ''],
+\ 'rev' : ['LinkTypes', ''],
+\ 'rows' : ['*Number', ''],
+\ 'rules' : ['String', ''],
+\ 'scheme' : ['CDATA', ''],
+\ 'selected' : ['Bool', ''],
+\ 'shape' : ['Shape', ''],
+\ 'size' : ['CDATA', ''],
+\ 'span' : ['Number', ''],
+\ 'src' : ['*URI', ''],
+\ 'standby' : ['Text', ''],
+\ 'style' : ['StyleSheet', ''],
+\ 'summary' : ['*Text', ''],
+\ 'tabindex' : ['Number', ''],
+\ 'title' : ['Text', ''],
+\ 'type' : ['*ContentType', ''],
+\ 'usemap' : ['URI', ''],
+\ 'valign' : ['String', ''],
+\ 'valuetype' : ['String', ''],
+\ 'width' : ['Number', ''],
+\ 'xmlns' : ['URI', '']
+\ },
+\ 'vimxmltaginfo': {
+\ 'area': ['/>', ''],
+\ 'base': ['/>', ''],
+\ 'basefont': ['/>', ''],
+\ 'br': ['/>', ''],
+\ 'hr': ['/>', ''],
+\ 'img': ['/>', ''],
+\ 'input': ['/>', ''],
+\ 'isindex': ['/>', ''],
+\ 'link': ['/>', ''],
+\ 'meta': ['/>', ''],
+\ 'param': ['/>', ''],
+\ }
+\ }
+" vim:ft=vim:ff=unix
--- /dev/null
+++ b/lib/vimfiles/autoload/xml/html401f.vim
@@ -1,0 +1,469 @@
+let g:xmldata_html401t = {
+\ 'vimxmlentities': ['AElig', 'Aacute', 'Acirc', 'Agrave', 'Alpha', 'Aring', 'Atilde', 'Auml', 'Beta', 'Ccedil', 'Chi', 'Dagger', 'Delta', 'ETH', 'Eacute', 'Ecirc', 'Egrave', 'Epsilon', 'Eta', 'Euml', 'Gamma', 'Iacute', 'Icirc', 'Igrave', 'Iota', 'Iuml', 'Kappa', 'Lambda', 'Mu', 'Ntilde', 'Nu', 'OElig', 'Oacute', 'Ocirc', 'Ograve', 'Omega', 'Omicron', 'Oslash', 'Otilde', 'Ouml', 'Phi', 'Pi', 'Prime', 'Psi', 'Rho', 'Scaron', 'Sigma', 'THORN', 'Tau', 'Theta', 'Uacute', 'Ucirc', 'Ugrave', 'Upsilon', 'Uuml', 'Xi', 'Yacute', 'Yuml', 'Zeta', 'aacute', 'acirc', 'acute', 'aelig', 'agrave', 'alefsym', 'alpha', 'amp', 'and', 'ang', 'apos', 'aring', 'asymp', 'atilde', 'auml', 'bdquo', 'beta', 'brvbar', 'bull', 'cap', 'ccedil', 'cedil', 'cent', 'chi', 'circ', 'clubs', 'cong', 'copy', 'crarr', 'cup', 'curren', 'dArr', 'dagger', 'darr', 'deg', 'delta', 'diams', 'divide', 'eacute', 'ecirc', 'egrave', 'empty', 'emsp', 'ensp', 'epsilon', 'equiv', 'eta', 'eth', 'euml', 'euro', 'exist', 'fnof', 'forall', 'frac12', 'frac14', 'frac34', 'frasl', 'gamma', 'ge', 'gt', 'hArr', 'harr', 'hearts', 'hellip', 'iacute', 'icirc', 'iexcl', 'igrave', 'image', 'infin', 'int', 'iota', 'iquest', 'isin', 'iuml', 'kappa', 'lArr', 'lambda', 'lang', 'laquo', 'larr', 'lceil', 'ldquo', 'le', 'lfloor', 'lowast', 'loz', 'lrm', 'lsaquo', 'lsquo', 'lt', 'macr', 'mdash', 'micro', 'middot', 'minus', 'mu', 'nabla', 'nbsp', 'ndash', 'ne', 'ni', 'not', 'notin', 'nsub', 'ntilde', 'nu', 'oacute', 'ocirc', 'oelig', 'ograve', 'oline', 'omega', 'omicron', 'oplus', 'or', 'ordf', 'ordm', 'oslash', 'otilde', 'otimes', 'ouml', 'para', 'part', 'permil', 'perp', 'phi', 'pi', 'piv', 'plusmn', 'pound', 'prime', 'prod', 'prop', 'psi', 'quot', 'rArr', 'radic', 'rang', 'raquo', 'rarr', 'rceil', 'rdquo', 'real', 'reg', 'rfloor', 'rho', 'rlm', 'rsaquo', 'rsquo', 'sbquo', 'scaron', 'sdot', 'sect', 'shy', 'sigma', 'sigmaf', 'sim', 'spades', 'sub', 'sube', 'sum', 'sup', 'sup1', 'sup2', 'sup3', 'supe', 'szlig', 'tau', 'there4', 'theta', 'thetasym', 'thinsp', 'thorn', 'tilde', 'times', 'trade', 'uArr', 'uacute', 'uarr', 'ucirc', 'ugrave', 'uml', 'upsih', 'upsilon', 'uuml', 'weierp', 'xi', 'yacute', 'yen', 'yuml', 'zeta', 'zwj', 'zwnj'],
+\ 'vimxmlroot': ['html'],
+\ 'a': [
+\ ['tt', 'i', 'b', 'u', 's', 'strike', 'big', 'small', 'em', 'strong', 'dfn', 'code', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'img', 'applet', 'object', 'font', 'basefont', 'br', 'script', 'map', 'q', 'sub', 'sup', 'span', 'bdo', 'iframe', 'input', 'select', 'textarea', 'label', 'button'],
+\ { 'rel': [], 'accesskey': [], 'coords': [], 'ondblclick': [], 'dir': ['ltr', 'rtl'], 'onblur': [], 'onkeydown': [], 'onfocus': [], 'target': [], 'onkeyup': [], 'href': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'tabindex': [], 'lang': [], 'onmouseout': [], 'onmousemove': [], 'style': [], 'name': [], 'charset': [], 'hreflang': [], 'onkeypress': [], 'onmousedown': [], 'rev': [], 'class': [], 'title': [], 'onclick': [], 'type': [], 'shape': ['rect', 'circle', 'poly', 'default']}
+\ ],
+\ 'abbr': [
+\ ['tt', 'i', 'b', 'u', 's', 'strike', 'big', 'small', 'em', 'strong', 'dfn', 'code', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'a', 'img', 'applet', 'object', 'font', 'basefont', 'br', 'script', 'map', 'q', 'sub', 'sup', 'span', 'bdo', 'iframe', 'input', 'select', 'textarea', 'label', 'button'],
+\ { 'ondblclick': [], 'dir': ['ltr', 'rtl'], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'style': [], 'onmousemove': [], 'onmouseout': [], 'onmousedown': [], 'onkeypress': [], 'onclick': [], 'title': [], 'class': []}
+\ ],
+\ 'acronym': [
+\ ['tt', 'i', 'b', 'u', 's', 'strike', 'big', 'small', 'em', 'strong', 'dfn', 'code', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'a', 'img', 'applet', 'object', 'font', 'basefont', 'br', 'script', 'map', 'q', 'sub', 'sup', 'span', 'bdo', 'iframe', 'input', 'select', 'textarea', 'label', 'button'],
+\ { 'ondblclick': [], 'dir': ['ltr', 'rtl'], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'style': [], 'onmousemove': [], 'onmouseout': [], 'onmousedown': [], 'onkeypress': [], 'onclick': [], 'title': [], 'class': []}
+\ ],
+\ 'address': [
+\ ['tt', 'i', 'b', 'u', 's', 'strike', 'big', 'small', 'em', 'strong', 'dfn', 'code', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'a', 'img', 'applet', 'object', 'font', 'basefont', 'br', 'script', 'map', 'q', 'sub', 'sup', 'span', 'bdo', 'iframe', 'input', 'select', 'textarea', 'label', 'button', 'p'],
+\ { 'ondblclick': [], 'dir': ['ltr', 'rtl'], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'style': [], 'onmousemove': [], 'onmouseout': [], 'onmousedown': [], 'onkeypress': [], 'onclick': [], 'title': [], 'class': []}
+\ ],
+\ 'applet': [
+\ ['param', 'p', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'ul', 'ol', 'dir', 'menu', 'pre', 'dl', 'div', 'center', 'noscript', 'noframes', 'blockquote', 'form', 'isindex', 'hr', 'table', 'fieldset', 'address', 'tt', 'i', 'b', 'u', 's', 'strike', 'big', 'small', 'em', 'strong', 'dfn', 'code', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'a', 'img', 'applet', 'object', 'font', 'basefont', 'br', 'script', 'map', 'q', 'sub', 'sup', 'span', 'bdo', 'iframe', 'input', 'select', 'textarea', 'label', 'button'],
+\ { 'width': [], 'object': [], 'id': [], 'code': [], 'vspace': [], 'archive': [], 'alt': [], 'align': ['top', 'middle', 'bottom', 'left', 'right'], 'style': [], 'name': [], 'height': [], 'hspace': [], 'title': [], 'class': [], 'codebase': []}
+\ ],
+\ 'area': [
+\ [],
+\ { 'accesskey': [], 'coords': [], 'ondblclick': [], 'dir': ['ltr', 'rtl'], 'onblur': [], 'onkeydown': [], 'target': [], 'nohref': ['BOOL'], 'onfocus': [], 'onkeyup': [], 'href': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'alt': [], 'tabindex': [], 'onmouseout': [], 'onmousemove': [], 'style': [], 'onkeypress': [], 'onmousedown': [], 'shape': ['rect', 'circle', 'poly', 'default'], 'class': [], 'title': [], 'onclick': []}
+\ ],
+\ 'b': [
+\ ['tt', 'i', 'b', 'u', 's', 'strike', 'big', 'small', 'em', 'strong', 'dfn', 'code', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'a', 'img', 'applet', 'object', 'font', 'basefont', 'br', 'script', 'map', 'q', 'sub', 'sup', 'span', 'bdo', 'iframe', 'input', 'select', 'textarea', 'label', 'button'],
+\ { 'ondblclick': [], 'dir': ['ltr', 'rtl'], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'style': [], 'onmousemove': [], 'onmouseout': [], 'onmousedown': [], 'onkeypress': [], 'onclick': [], 'title': [], 'class': []}
+\ ],
+\ 'base': [
+\ [],
+\ { 'target': [], 'href': []}
+\ ],
+\ 'basefont': [
+\ [],
+\ { 'size': [], 'face': [], 'color': [], 'id': []}
+\ ],
+\ 'bdo': [
+\ ['tt', 'i', 'b', 'u', 's', 'strike', 'big', 'small', 'em', 'strong', 'dfn', 'code', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'a', 'img', 'applet', 'object', 'font', 'basefont', 'br', 'script', 'map', 'q', 'sub', 'sup', 'span', 'bdo', 'iframe', 'input', 'select', 'textarea', 'label', 'button'],
+\ { 'dir': ['ltr', 'rtl'], 'id': [], 'lang': [], 'style': [], 'class': [], 'title': []}
+\ ],
+\ 'big': [
+\ ['tt', 'i', 'b', 'u', 's', 'strike', 'big', 'small', 'em', 'strong', 'dfn', 'code', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'a', 'img', 'applet', 'object', 'font', 'basefont', 'br', 'script', 'map', 'q', 'sub', 'sup', 'span', 'bdo', 'iframe', 'input', 'select', 'textarea', 'label', 'button'],
+\ { 'ondblclick': [], 'dir': ['ltr', 'rtl'], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'style': [], 'onmousemove': [], 'onmouseout': [], 'onmousedown': [], 'onkeypress': [], 'onclick': [], 'title': [], 'class': []}
+\ ],
+\ 'blockquote': [
+\ ['p', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'ul', 'ol', 'dir', 'menu', 'pre', 'dl', 'div', 'center', 'noscript', 'noframes', 'blockquote', 'form', 'isindex', 'hr', 'table', 'fieldset', 'address', 'tt', 'i', 'b', 'u', 's', 'strike', 'big', 'small', 'em', 'strong', 'dfn', 'code', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'a', 'img', 'applet', 'object', 'font', 'basefont', 'br', 'script', 'map', 'q', 'sub', 'sup', 'span', 'bdo', 'iframe', 'input', 'select', 'textarea', 'label', 'button'],
+\ { 'ondblclick': [], 'dir': ['ltr', 'rtl'], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'cite': [], 'onmouseover': [], 'lang': [], 'style': [], 'onmousemove': [], 'onmouseout': [], 'onmousedown': [], 'onkeypress': [], 'onclick': [], 'title': [], 'class': []}
+\ ],
+\ 'body': [
+\ ['p', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'ul', 'ol', 'dir', 'menu', 'pre', 'dl', 'div', 'center', 'noscript', 'noframes', 'blockquote', 'form', 'isindex', 'hr', 'table', 'fieldset', 'address', 'tt', 'i', 'b', 'u', 's', 'strike', 'big', 'small', 'em', 'strong', 'dfn', 'code', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'a', 'img', 'applet', 'object', 'font', 'basefont', 'br', 'script', 'map', 'q', 'sub', 'sup', 'span', 'bdo', 'iframe', 'input', 'select', 'textarea', 'label', 'button', 'ins', 'del'],
+\ { 'vlink': [], 'ondblclick': [], 'dir': ['ltr', 'rtl'], 'onkeydown': [], 'alink': [], 'onkeyup': [], 'bgcolor': [], 'text': [], 'onmouseup': [], 'id': [], 'link': [], 'onmouseover': [], 'lang': [], 'onmouseout': [], 'onmousemove': [], 'style': [], 'background': [], 'onunload': [], 'onkeypress': [], 'onmousedown': [], 'onload': [], 'class': [], 'title': [], 'onclick': []}
+\ ],
+\ 'br': [
+\ [],
+\ { 'clear': ['none', 'left', 'all', 'right', 'none'], 'id': [], 'style': [], 'class': [], 'title': []}
+\ ],
+\ 'button': [
+\ ['p', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'ul', 'ol', 'dir', 'menu', 'pre', 'dl', 'div', 'center', 'noscript', 'noframes', 'blockquote', 'hr', 'table', 'address', 'tt', 'i', 'b', 'u', 's', 'strike', 'big', 'small', 'em', 'strong', 'dfn', 'code', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'img', 'applet', 'object', 'font', 'basefont', 'br', 'script', 'map', 'q', 'sub', 'sup', 'span', 'bdo'],
+\ { 'accesskey': [], 'disabled': ['BOOL'], 'ondblclick': [], 'dir': ['ltr', 'rtl'], 'onblur': [], 'onkeydown': [], 'onfocus': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'tabindex': [], 'value': [], 'name': [], 'onmouseout': [], 'onmousemove': [], 'style': [], 'onkeypress': [], 'onmousedown': [], 'class': [], 'title': [], 'onclick': [], 'type': ['submit', 'button', 'submit', 'reset']}
+\ ],
+\ 'caption': [
+\ ['tt', 'i', 'b', 'u', 's', 'strike', 'big', 'small', 'em', 'strong', 'dfn', 'code', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'a', 'img', 'applet', 'object', 'font', 'basefont', 'br', 'script', 'map', 'q', 'sub', 'sup', 'span', 'bdo', 'iframe', 'input', 'select', 'textarea', 'label', 'button'],
+\ { 'ondblclick': [], 'dir': ['ltr', 'rtl'], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'align': ['top', 'bottom', 'left', 'right'], 'lang': [], 'onmouseout': [], 'onmousemove': [], 'style': [], 'onkeypress': [], 'onmousedown': [], 'class': [], 'title': [], 'onclick': []}
+\ ],
+\ 'center': [
+\ ['p', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'ul', 'ol', 'dir', 'menu', 'pre', 'dl', 'div', 'center', 'noscript', 'noframes', 'blockquote', 'form', 'isindex', 'hr', 'table', 'fieldset', 'address', 'tt', 'i', 'b', 'u', 's', 'strike', 'big', 'small', 'em', 'strong', 'dfn', 'code', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'a', 'img', 'applet', 'object', 'font', 'basefont', 'br', 'script', 'map', 'q', 'sub', 'sup', 'span', 'bdo', 'iframe', 'input', 'select', 'textarea', 'label', 'button'],
+\ { 'ondblclick': [], 'dir': ['ltr', 'rtl'], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'style': [], 'onmousemove': [], 'onmouseout': [], 'onmousedown': [], 'onkeypress': [], 'onclick': [], 'title': [], 'class': []}
+\ ],
+\ 'cite': [
+\ ['tt', 'i', 'b', 'u', 's', 'strike', 'big', 'small', 'em', 'strong', 'dfn', 'code', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'a', 'img', 'applet', 'object', 'font', 'basefont', 'br', 'script', 'map', 'q', 'sub', 'sup', 'span', 'bdo', 'iframe', 'input', 'select', 'textarea', 'label', 'button'],
+\ { 'ondblclick': [], 'dir': ['ltr', 'rtl'], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'style': [], 'onmousemove': [], 'onmouseout': [], 'onmousedown': [], 'onkeypress': [], 'onclick': [], 'title': [], 'class': []}
+\ ],
+\ 'code': [
+\ ['tt', 'i', 'b', 'u', 's', 'strike', 'big', 'small', 'em', 'strong', 'dfn', 'code', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'a', 'img', 'applet', 'object', 'font', 'basefont', 'br', 'script', 'map', 'q', 'sub', 'sup', 'span', 'bdo', 'iframe', 'input', 'select', 'textarea', 'label', 'button'],
+\ { 'ondblclick': [], 'dir': ['ltr', 'rtl'], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'style': [], 'onmousemove': [], 'onmouseout': [], 'onmousedown': [], 'onkeypress': [], 'onclick': [], 'title': [], 'class': []}
+\ ],
+\ 'col': [
+\ [],
+\ { 'width': [], 'ondblclick': [], 'dir': ['ltr', 'rtl'], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'charoff': [], 'onmouseover': [], 'lang': [], 'align': ['left', 'center', 'right', 'justify', 'char'], 'valign': ['top', 'middle', 'bottom', 'baseline'], 'onmouseout': [], 'onmousemove': [], 'style': [], 'onkeypress': [], 'onmousedown': [], 'char': [], 'span': ['1'], 'class': [], 'title': [], 'onclick': []}
+\ ],
+\ 'colgroup': [
+\ ['col'],
+\ { 'width': [], 'ondblclick': [], 'dir': ['ltr', 'rtl'], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'charoff': [], 'onmouseover': [], 'lang': [], 'align': ['left', 'center', 'right', 'justify', 'char'], 'valign': ['top', 'middle', 'bottom', 'baseline'], 'onmouseout': [], 'onmousemove': [], 'style': [], 'onkeypress': [], 'onmousedown': [], 'char': [], 'span': ['1'], 'class': [], 'title': [], 'onclick': []}
+\ ],
+\ 'dd': [
+\ ['p', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'ul', 'ol', 'dir', 'menu', 'pre', 'dl', 'div', 'center', 'noscript', 'noframes', 'blockquote', 'form', 'isindex', 'hr', 'table', 'fieldset', 'address', 'tt', 'i', 'b', 'u', 's', 'strike', 'big', 'small', 'em', 'strong', 'dfn', 'code', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'a', 'img', 'applet', 'object', 'font', 'basefont', 'br', 'script', 'map', 'q', 'sub', 'sup', 'span', 'bdo', 'iframe', 'input', 'select', 'textarea', 'label', 'button'],
+\ { 'ondblclick': [], 'dir': ['ltr', 'rtl'], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'style': [], 'onmousemove': [], 'onmouseout': [], 'onmousedown': [], 'onkeypress': [], 'onclick': [], 'title': [], 'class': []}
+\ ],
+\ 'del': [
+\ ['p', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'ul', 'ol', 'dir', 'menu', 'pre', 'dl', 'div', 'center', 'noscript', 'noframes', 'blockquote', 'form', 'isindex', 'hr', 'table', 'fieldset', 'address', 'tt', 'i', 'b', 'u', 's', 'strike', 'big', 'small', 'em', 'strong', 'dfn', 'code', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'a', 'img', 'applet', 'object', 'font', 'basefont', 'br', 'script', 'map', 'q', 'sub', 'sup', 'span', 'bdo', 'iframe', 'input', 'select', 'textarea', 'label', 'button'],
+\ { 'ondblclick': [], 'dir': ['ltr', 'rtl'], 'datetime': [], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'cite': [], 'onmouseover': [], 'lang': [], 'onmouseout': [], 'onmousemove': [], 'style': [], 'onkeypress': [], 'onmousedown': [], 'class': [], 'title': [], 'onclick': []}
+\ ],
+\ 'dfn': [
+\ ['tt', 'i', 'b', 'u', 's', 'strike', 'big', 'small', 'em', 'strong', 'dfn', 'code', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'a', 'img', 'applet', 'object', 'font', 'basefont', 'br', 'script', 'map', 'q', 'sub', 'sup', 'span', 'bdo', 'iframe', 'input', 'select', 'textarea', 'label', 'button'],
+\ { 'ondblclick': [], 'dir': ['ltr', 'rtl'], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'style': [], 'onmousemove': [], 'onmouseout': [], 'onmousedown': [], 'onkeypress': [], 'onclick': [], 'title': [], 'class': []}
+\ ],
+\ 'dir': [
+\ ['li'],
+\ { 'ondblclick': [], 'dir': ['ltr', 'rtl'], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'compact': ['BOOL'], 'onmouseover': [], 'lang': [], 'style': [], 'onmousemove': [], 'onmouseout': [], 'onmousedown': [], 'onkeypress': [], 'onclick': [], 'title': [], 'class': []}
+\ ],
+\ 'div': [
+\ ['p', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'ul', 'ol', 'dir', 'menu', 'pre', 'dl', 'div', 'center', 'noscript', 'noframes', 'blockquote', 'form', 'isindex', 'hr', 'table', 'fieldset', 'address', 'tt', 'i', 'b', 'u', 's', 'strike', 'big', 'small', 'em', 'strong', 'dfn', 'code', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'a', 'img', 'applet', 'object', 'font', 'basefont', 'br', 'script', 'map', 'q', 'sub', 'sup', 'span', 'bdo', 'iframe', 'input', 'select', 'textarea', 'label', 'button'],
+\ { 'ondblclick': [], 'dir': ['ltr', 'rtl'], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'align': ['left', 'center', 'right', 'justify'], 'lang': [], 'onmouseout': [], 'onmousemove': [], 'style': [], 'onkeypress': [], 'onmousedown': [], 'class': [], 'title': [], 'onclick': []}
+\ ],
+\ 'dl': [
+\ ['dt', 'dd'],
+\ { 'ondblclick': [], 'dir': ['ltr', 'rtl'], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'compact': ['BOOL'], 'onmouseover': [], 'lang': [], 'style': [], 'onmousemove': [], 'onmouseout': [], 'onmousedown': [], 'onkeypress': [], 'onclick': [], 'title': [], 'class': []}
+\ ],
+\ 'dt': [
+\ ['tt', 'i', 'b', 'u', 's', 'strike', 'big', 'small', 'em', 'strong', 'dfn', 'code', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'a', 'img', 'applet', 'object', 'font', 'basefont', 'br', 'script', 'map', 'q', 'sub', 'sup', 'span', 'bdo', 'iframe', 'input', 'select', 'textarea', 'label', 'button'],
+\ { 'ondblclick': [], 'dir': ['ltr', 'rtl'], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'style': [], 'onmousemove': [], 'onmouseout': [], 'onmousedown': [], 'onkeypress': [], 'onclick': [], 'title': [], 'class': []}
+\ ],
+\ 'em': [
+\ ['tt', 'i', 'b', 'u', 's', 'strike', 'big', 'small', 'em', 'strong', 'dfn', 'code', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'a', 'img', 'applet', 'object', 'font', 'basefont', 'br', 'script', 'map', 'q', 'sub', 'sup', 'span', 'bdo', 'iframe', 'input', 'select', 'textarea', 'label', 'button'],
+\ { 'ondblclick': [], 'dir': ['ltr', 'rtl'], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'style': [], 'onmousemove': [], 'onmouseout': [], 'onmousedown': [], 'onkeypress': [], 'onclick': [], 'title': [], 'class': []}
+\ ],
+\ 'fieldset': [
+\ ['legend', 'p', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'ul', 'ol', 'dir', 'menu', 'pre', 'dl', 'div', 'center', 'noscript', 'noframes', 'blockquote', 'form', 'isindex', 'hr', 'table', 'fieldset', 'address', 'tt', 'i', 'b', 'u', 's', 'strike', 'big', 'small', 'em', 'strong', 'dfn', 'code', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'a', 'img', 'applet', 'object', 'font', 'basefont', 'br', 'script', 'map', 'q', 'sub', 'sup', 'span', 'bdo', 'iframe', 'input', 'select', 'textarea', 'label', 'button'],
+\ { 'ondblclick': [], 'dir': ['ltr', 'rtl'], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'style': [], 'onmousemove': [], 'onmouseout': [], 'onmousedown': [], 'onkeypress': [], 'onclick': [], 'title': [], 'class': []}
+\ ],
+\ 'font': [
+\ ['tt', 'i', 'b', 'u', 's', 'strike', 'big', 'small', 'em', 'strong', 'dfn', 'code', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'a', 'img', 'applet', 'object', 'font', 'basefont', 'br', 'script', 'map', 'q', 'sub', 'sup', 'span', 'bdo', 'iframe', 'input', 'select', 'textarea', 'label', 'button'],
+\ { 'dir': ['ltr', 'rtl'], 'size': [], 'face': [], 'color': [], 'id': [], 'lang': [], 'style': [], 'class': [], 'title': []}
+\ ],
+\ 'form': [
+\ ['p', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'ul', 'ol', 'dir', 'menu', 'pre', 'dl', 'div', 'center', 'noscript', 'noframes', 'blockquote', 'isindex', 'hr', 'table', 'fieldset', 'address', 'tt', 'i', 'b', 'u', 's', 'strike', 'big', 'small', 'em', 'strong', 'dfn', 'code', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'a', 'img', 'applet', 'object', 'font', 'basefont', 'br', 'script', 'map', 'q', 'sub', 'sup', 'span', 'bdo', 'iframe', 'input', 'select', 'textarea', 'label', 'button'],
+\ { 'enctype': ['application/x-www-form-urlencoded'], 'onsubmit': [], 'ondblclick': [], 'dir': ['ltr', 'rtl'], 'onkeydown': [], 'target': [], 'onkeyup': [], 'onmouseup': [], 'onreset': [], 'id': [], 'method': ['GET', 'POST'], 'onmouseover': [], 'lang': [], 'accept': [], 'onmouseout': [], 'onmousemove': [], 'style': [], 'name': [], 'accept-charset': [], 'onkeypress': [], 'onmousedown': [], 'action': [], 'class': [], 'title': [], 'onclick': []}
+\ ],
+\ 'h1': [
+\ ['tt', 'i', 'b', 'u', 's', 'strike', 'big', 'small', 'em', 'strong', 'dfn', 'code', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'a', 'img', 'applet', 'object', 'font', 'basefont', 'br', 'script', 'map', 'q', 'sub', 'sup', 'span', 'bdo', 'iframe', 'input', 'select', 'textarea', 'label', 'button'],
+\ { 'ondblclick': [], 'dir': ['ltr', 'rtl'], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'align': ['left', 'center', 'right', 'justify'], 'lang': [], 'onmouseout': [], 'onmousemove': [], 'style': [], 'onkeypress': [], 'onmousedown': [], 'class': [], 'title': [], 'onclick': []}
+\ ],
+\ 'h2': [
+\ ['tt', 'i', 'b', 'u', 's', 'strike', 'big', 'small', 'em', 'strong', 'dfn', 'code', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'a', 'img', 'applet', 'object', 'font', 'basefont', 'br', 'script', 'map', 'q', 'sub', 'sup', 'span', 'bdo', 'iframe', 'input', 'select', 'textarea', 'label', 'button'],
+\ { 'ondblclick': [], 'dir': ['ltr', 'rtl'], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'align': ['left', 'center', 'right', 'justify'], 'lang': [], 'onmouseout': [], 'onmousemove': [], 'style': [], 'onkeypress': [], 'onmousedown': [], 'class': [], 'title': [], 'onclick': []}
+\ ],
+\ 'h3': [
+\ ['tt', 'i', 'b', 'u', 's', 'strike', 'big', 'small', 'em', 'strong', 'dfn', 'code', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'a', 'img', 'applet', 'object', 'font', 'basefont', 'br', 'script', 'map', 'q', 'sub', 'sup', 'span', 'bdo', 'iframe', 'input', 'select', 'textarea', 'label', 'button'],
+\ { 'ondblclick': [], 'dir': ['ltr', 'rtl'], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'align': ['left', 'center', 'right', 'justify'], 'lang': [], 'onmouseout': [], 'onmousemove': [], 'style': [], 'onkeypress': [], 'onmousedown': [], 'class': [], 'title': [], 'onclick': []}
+\ ],
+\ 'h4': [
+\ ['tt', 'i', 'b', 'u', 's', 'strike', 'big', 'small', 'em', 'strong', 'dfn', 'code', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'a', 'img', 'applet', 'object', 'font', 'basefont', 'br', 'script', 'map', 'q', 'sub', 'sup', 'span', 'bdo', 'iframe', 'input', 'select', 'textarea', 'label', 'button'],
+\ { 'ondblclick': [], 'dir': ['ltr', 'rtl'], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'align': ['left', 'center', 'right', 'justify'], 'lang': [], 'onmouseout': [], 'onmousemove': [], 'style': [], 'onkeypress': [], 'onmousedown': [], 'class': [], 'title': [], 'onclick': []}
+\ ],
+\ 'h5': [
+\ ['tt', 'i', 'b', 'u', 's', 'strike', 'big', 'small', 'em', 'strong', 'dfn', 'code', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'a', 'img', 'applet', 'object', 'font', 'basefont', 'br', 'script', 'map', 'q', 'sub', 'sup', 'span', 'bdo', 'iframe', 'input', 'select', 'textarea', 'label', 'button'],
+\ { 'ondblclick': [], 'dir': ['ltr', 'rtl'], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'align': ['left', 'center', 'right', 'justify'], 'lang': [], 'onmouseout': [], 'onmousemove': [], 'style': [], 'onkeypress': [], 'onmousedown': [], 'class': [], 'title': [], 'onclick': []}
+\ ],
+\ 'h6': [
+\ ['tt', 'i', 'b', 'u', 's', 'strike', 'big', 'small', 'em', 'strong', 'dfn', 'code', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'a', 'img', 'applet', 'object', 'font', 'basefont', 'br', 'script', 'map', 'q', 'sub', 'sup', 'span', 'bdo', 'iframe', 'input', 'select', 'textarea', 'label', 'button'],
+\ { 'ondblclick': [], 'dir': ['ltr', 'rtl'], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'align': ['left', 'center', 'right', 'justify'], 'lang': [], 'onmouseout': [], 'onmousemove': [], 'style': [], 'onkeypress': [], 'onmousedown': [], 'class': [], 'title': [], 'onclick': []}
+\ ],
+\ 'head': [
+\ ['title', 'isindex', 'base', 'script', 'style', 'meta', 'link', 'object'],
+\ { 'profile': [], 'dir': ['ltr', 'rtl'], 'lang': []}
+\ ],
+\ 'hr': [
+\ [],
+\ { 'width': [], 'ondblclick': [], 'dir': ['ltr', 'rtl'], 'size': [], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'align': ['left', 'center', 'right'], 'lang': [], 'onmouseout': [], 'onmousemove': [], 'style': [], 'noshade': ['BOOL'], 'onkeypress': [], 'onmousedown': [], 'class': [], 'title': [], 'onclick': []}
+\ ],
+\ 'html': [
+\ ['head', 'frameset'],
+\ { 'xmlns': ['http://www.w3.org/1999/xhtml'], 'dir': ['ltr', 'rtl'], 'id': [], 'lang': [], 'xml:lang': []}
+\ ],
+\ 'frameset': [
+\ ['frameset', 'frame', 'noframes'],
+\ { 'rows': [], 'cols': [], 'id': [], 'style': [], 'onunload': [], 'onload': [], 'class': [], 'title': []}
+\ ],
+\ 'frame': [
+\ [],
+\ { 'scrolling': ['auto', 'yes', 'no', 'auto'], 'noresize': ['BOOL'], 'marginwidth': [], 'id': [], 'marginheight': [], 'longdesc': [], 'src': [], 'style': [], 'name': [], 'frameborder': ['1', '0'], 'title': [], 'class': []}
+\ ],
+\ 'i': [
+\ ['tt', 'i', 'b', 'u', 's', 'strike', 'big', 'small', 'em', 'strong', 'dfn', 'code', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'a', 'img', 'applet', 'object', 'font', 'basefont', 'br', 'script', 'map', 'q', 'sub', 'sup', 'span', 'bdo', 'iframe', 'input', 'select', 'textarea', 'label', 'button'],
+\ { 'ondblclick': [], 'dir': ['ltr', 'rtl'], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'style': [], 'onmousemove': [], 'onmouseout': [], 'onmousedown': [], 'onkeypress': [], 'onclick': [], 'title': [], 'class': []}
+\ ],
+\ 'iframe': [
+\ ['p', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'ul', 'ol', 'dir', 'menu', 'pre', 'dl', 'div', 'center', 'noscript', 'noframes', 'blockquote', 'form', 'isindex', 'hr', 'table', 'fieldset', 'address', 'tt', 'i', 'b', 'u', 's', 'strike', 'big', 'small', 'em', 'strong', 'dfn', 'code', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'a', 'img', 'applet', 'object', 'font', 'basefont', 'br', 'script', 'map', 'q', 'sub', 'sup', 'span', 'bdo', 'iframe', 'input', 'select', 'textarea', 'label', 'button'],
+\ { 'width': [], 'scrolling': ['auto', 'yes', 'no', 'auto'], 'marginwidth': [], 'id': [], 'marginheight': [], 'align': ['top', 'middle', 'bottom', 'left', 'right'], 'longdesc': [], 'src': [], 'style': [], 'name': [], 'height': [], 'frameborder': ['1', '0'], 'title': [], 'class': []}
+\ ],
+\ 'img': [
+\ [],
+\ { 'width': [], 'usemap': [], 'ismap': ['BOOL'], 'ondblclick': [], 'dir': ['ltr', 'rtl'], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'vspace': [], 'onmouseover': [], 'alt': [], 'lang': [], 'align': ['top', 'middle', 'bottom', 'left', 'right'], 'src': [], 'longdesc': [], 'onmouseout': [], 'onmousemove': [], 'style': [], 'name': [], 'height': [], 'border': [], 'hspace': [], 'onkeypress': [], 'onmousedown': [], 'class': [], 'title': [], 'onclick': []}
+\ ],
+\ 'input': [
+\ [],
+\ { 'ondblclick': [], 'onkeydown': [], 'readonly': ['BOOL'], 'onchange': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'align': ['top', 'middle', 'bottom', 'left', 'right'], 'value': [], 'src': [], 'name': [], 'checked': ['BOOL'], 'onkeypress': [], 'onmousedown': [], 'type': ['TEXT', 'PASSWORD', 'CHECKBOX', 'RADIO', 'SUBMIT', 'RESET', 'FILE', 'IMAGE', 'BUTTON'], 'class': [], 'title': [], 'onclick': [], 'accesskey': [], 'disabled': ['BOOL'], 'usemap': [], 'ismap': ['BOOL'], 'dir': ['ltr', 'rtl'], 'size': [], 'onblur': [], 'onfocus': [], 'maxlength': [], 'onselect': [], 'tabindex': [], 'accept': [], 'alt': [], 'style': [], 'onmousemove': [], 'onmouseout': []}
+\ ],
+\ 'ins': [
+\ ['p', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'ul', 'ol', 'dir', 'menu', 'pre', 'dl', 'div', 'center', 'noscript', 'noframes', 'blockquote', 'form', 'isindex', 'hr', 'table', 'fieldset', 'address', 'tt', 'i', 'b', 'u', 's', 'strike', 'big', 'small', 'em', 'strong', 'dfn', 'code', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'a', 'img', 'applet', 'object', 'font', 'basefont', 'br', 'script', 'map', 'q', 'sub', 'sup', 'span', 'bdo', 'iframe', 'input', 'select', 'textarea', 'label', 'button'],
+\ { 'ondblclick': [], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'onkeypress': [], 'onmousedown': [], 'class': [], 'title': [], 'onclick': [], 'dir': ['ltr', 'rtl'], 'datetime': [], 'cite': [], 'onmouseout': [], 'onmousemove': [], 'style': []}
+\ ],
+\ 'isindex': [
+\ [],
+\ { 'id': [], 'lang': [], 'prompt': [], 'class': [], 'title': [], 'dir': ['ltr', 'rtl'], 'style': []}
+\ ],
+\ 'kbd': [
+\ ['tt', 'i', 'b', 'u', 's', 'strike', 'big', 'small', 'em', 'strong', 'dfn', 'code', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'a', 'img', 'applet', 'object', 'font', 'basefont', 'br', 'script', 'map', 'q', 'sub', 'sup', 'span', 'bdo', 'iframe', 'input', 'select', 'textarea', 'label', 'button'],
+\ { 'ondblclick': [], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'onmousedown': [], 'onkeypress': [], 'onclick': [], 'title': [], 'class': [], 'dir': ['ltr', 'rtl'], 'style': [], 'onmousemove': [], 'onmouseout': []}
+\ ],
+\ 'label': [
+\ ['tt', 'i', 'b', 'u', 's', 'strike', 'big', 'small', 'em', 'strong', 'dfn', 'code', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'a', 'img', 'applet', 'object', 'font', 'basefont', 'br', 'script', 'map', 'q', 'sub', 'sup', 'span', 'bdo', 'iframe', 'input', 'select', 'textarea', 'button'],
+\ { 'ondblclick': [], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'for': [], 'onkeypress': [], 'onmousedown': [], 'class': [], 'title': [], 'onclick': [], 'accesskey': [], 'dir': ['ltr', 'rtl'], 'onblur': [], 'onfocus': [], 'onmouseout': [], 'onmousemove': [], 'style': []}
+\ ],
+\ 'legend': [
+\ ['tt', 'i', 'b', 'u', 's', 'strike', 'big', 'small', 'em', 'strong', 'dfn', 'code', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'a', 'img', 'applet', 'object', 'font', 'basefont', 'br', 'script', 'map', 'q', 'sub', 'sup', 'span', 'bdo', 'iframe', 'input', 'select', 'textarea', 'label', 'button'],
+\ { 'ondblclick': [], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'align': ['top', 'bottom', 'left', 'right'], 'lang': [], 'onkeypress': [], 'onmousedown': [], 'class': [], 'title': [], 'onclick': [], 'accesskey': [], 'dir': ['ltr', 'rtl'], 'onmouseout': [], 'onmousemove': [], 'style': []}
+\ ],
+\ 'li': [
+\ ['p', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'ul', 'ol', 'dir', 'menu', 'pre', 'dl', 'div', 'center', 'noscript', 'noframes', 'blockquote', 'form', 'isindex', 'hr', 'table', 'fieldset', 'address', 'tt', 'i', 'b', 'u', 's', 'strike', 'big', 'small', 'em', 'strong', 'dfn', 'code', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'a', 'img', 'applet', 'object', 'font', 'basefont', 'br', 'script', 'map', 'q', 'sub', 'sup', 'span', 'bdo', 'iframe', 'input', 'select', 'textarea', 'label', 'button'],
+\ { 'ondblclick': [], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'value': [], 'onkeypress': [], 'onmousedown': [], 'type': [], 'class': [], 'title': [], 'onclick': [], 'dir': ['ltr', 'rtl'], 'onmouseout': [], 'onmousemove': [], 'style': []}
+\ ],
+\ 'link': [
+\ [],
+\ { 'rel': [], 'ondblclick': [], 'onkeydown': [], 'target': [], 'onkeyup': [], 'href': [], 'media': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'charset': [], 'hreflang': [], 'onkeypress': [], 'onmousedown': [], 'rev': [], 'class': [], 'title': [], 'onclick': [], 'type': [], 'dir': ['ltr', 'rtl'], 'onmouseout': [], 'onmousemove': [], 'style': []}
+\ ],
+\ 'map': [
+\ ['p', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'ul', 'ol', 'dir', 'menu', 'pre', 'dl', 'div', 'center', 'noscript', 'noframes', 'blockquote', 'form', 'isindex', 'hr', 'table', 'fieldset', 'address', 'area'],
+\ { 'ondblclick': [], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'name': [], 'onkeypress': [], 'onmousedown': [], 'class': [], 'title': [], 'onclick': [], 'dir': ['ltr', 'rtl'], 'onmouseout': [], 'onmousemove': [], 'style': []}
+\ ],
+\ 'menu': [
+\ ['li'],
+\ { 'ondblclick': [], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'compact': ['BOOL'], 'onmouseover': [], 'lang': [], 'onmousedown': [], 'onkeypress': [], 'onclick': [], 'title': [], 'class': [], 'dir': ['ltr', 'rtl'], 'style': [], 'onmousemove': [], 'onmouseout': []}
+\ ],
+\ 'meta': [
+\ [],
+\ { 'http-equiv': [], 'content': [], 'lang': [], 'name': [], 'scheme': [], 'dir': ['ltr', 'rtl']}
+\ ],
+\ 'noframes': [
+\ ['p', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'ul', 'ol', 'dir', 'menu', 'pre', 'dl', 'div', 'center', 'noscript', 'noframes', 'blockquote', 'form', 'isindex', 'hr', 'table', 'fieldset', 'address', 'tt', 'i', 'b', 'u', 's', 'strike', 'big', 'small', 'em', 'strong', 'dfn', 'code', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'a', 'img', 'applet', 'object', 'font', 'basefont', 'br', 'script', 'map', 'q', 'sub', 'sup', 'span', 'bdo', 'iframe', 'input', 'select', 'textarea', 'label', 'button'],
+\ { 'ondblclick': [], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'onmousedown': [], 'onkeypress': [], 'onclick': [], 'title': [], 'class': [], 'dir': ['ltr', 'rtl'], 'style': [], 'onmousemove': [], 'onmouseout': []}
+\ ],
+\ 'noscript': [
+\ ['p', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'ul', 'ol', 'dir', 'menu', 'pre', 'dl', 'div', 'center', 'noscript', 'noframes', 'blockquote', 'form', 'isindex', 'hr', 'table', 'fieldset', 'address', 'tt', 'i', 'b', 'u', 's', 'strike', 'big', 'small', 'em', 'strong', 'dfn', 'code', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'a', 'img', 'applet', 'object', 'font', 'basefont', 'br', 'script', 'map', 'q', 'sub', 'sup', 'span', 'bdo', 'iframe', 'input', 'select', 'textarea', 'label', 'button'],
+\ { 'ondblclick': [], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'onmousedown': [], 'onkeypress': [], 'onclick': [], 'title': [], 'class': [], 'dir': ['ltr', 'rtl'], 'style': [], 'onmousemove': [], 'onmouseout': []}
+\ ],
+\ 'object': [
+\ ['param', 'p', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'ul', 'ol', 'dir', 'menu', 'pre', 'dl', 'div', 'center', 'noscript', 'noframes', 'blockquote', 'form', 'isindex', 'hr', 'table', 'fieldset', 'address', 'tt', 'i', 'b', 'u', 's', 'strike', 'big', 'small', 'em', 'strong', 'dfn', 'code', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'a', 'img', 'applet', 'object', 'font', 'basefont', 'br', 'script', 'map', 'q', 'sub', 'sup', 'span', 'bdo', 'iframe', 'input', 'select', 'textarea', 'label', 'button'],
+\ { 'ondblclick': [], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'align': ['top', 'middle', 'bottom', 'left', 'right'], 'name': [], 'data': [], 'declare': ['BOOL'], 'onkeypress': [], 'onmousedown': [], 'class': [], 'title': [], 'onclick': [], 'type': [], 'width': [], 'usemap': [], 'dir': ['ltr', 'rtl'], 'vspace': [], 'tabindex': [], 'standby': [], 'archive': [], 'classid': [], 'style': [], 'onmousemove': [], 'onmouseout': [], 'height': [], 'border': [], 'codetype': [], 'hspace': [], 'codebase': []}
+\ ],
+\ 'ol': [
+\ ['li'],
+\ { 'ondblclick': [], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'compact': ['BOOL'], 'onmouseover': [], 'lang': [], 'onkeypress': [], 'onmousedown': [], 'type': [], 'class': [], 'title': [], 'onclick': [], 'start': [], 'dir': ['ltr', 'rtl'], 'onmouseout': [], 'onmousemove': [], 'style': []}
+\ ],
+\ 'optgroup': [
+\ ['option'],
+\ { 'ondblclick': [], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'onkeypress': [], 'onmousedown': [], 'class': [], 'title': [], 'onclick': [], 'label': [], 'disabled': ['BOOL'], 'dir': ['ltr', 'rtl'], 'onmouseout': [], 'onmousemove': [], 'style': []}
+\ ],
+\ 'option': [
+\ [''],
+\ { 'ondblclick': [], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'value': [], 'onkeypress': [], 'onmousedown': [], 'class': [], 'title': [], 'onclick': [], 'label': [], 'disabled': ['BOOL'], 'dir': ['ltr', 'rtl'], 'onmouseout': [], 'onmousemove': [], 'style': [], 'selected': ['BOOL']}
+\ ],
+\ 'p': [
+\ ['tt', 'i', 'b', 'u', 's', 'strike', 'big', 'small', 'em', 'strong', 'dfn', 'code', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'a', 'img', 'applet', 'object', 'font', 'basefont', 'br', 'script', 'map', 'q', 'sub', 'sup', 'span', 'bdo', 'iframe', 'input', 'select', 'textarea', 'label', 'button'],
+\ { 'ondblclick': [], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'align': ['left', 'center', 'right', 'justify'], 'lang': [], 'onkeypress': [], 'onmousedown': [], 'class': [], 'title': [], 'onclick': [], 'dir': ['ltr', 'rtl'], 'onmouseout': [], 'onmousemove': [], 'style': []}
+\ ],
+\ 'param': [
+\ [],
+\ { 'id': [], 'value': [], 'name': [], 'type': [], 'valuetype': ['DATA', 'REF', 'OBJECT']}
+\ ],
+\ 'pre': [
+\ ['tt', 'i', 'b', 'u', 's', 'strike', 'em', 'strong', 'dfn', 'code', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'a', 'br', 'script', 'map', 'q', 'span', 'bdo', 'iframe', 'input', 'select', 'textarea', 'label', 'button'],
+\ { 'ondblclick': [], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'onmousedown': [], 'onkeypress': [], 'onclick': [], 'title': [], 'class': [], 'width': [], 'dir': ['ltr', 'rtl'], 'style': [], 'onmousemove': [], 'onmouseout': []}
+\ ],
+\ 'q': [
+\ ['tt', 'i', 'b', 'u', 's', 'strike', 'big', 'small', 'em', 'strong', 'dfn', 'code', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'a', 'img', 'applet', 'object', 'font', 'basefont', 'br', 'script', 'map', 'q', 'sub', 'sup', 'span', 'bdo', 'iframe', 'input', 'select', 'textarea', 'label', 'button'],
+\ { 'ondblclick': [], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'onmousedown': [], 'onkeypress': [], 'onclick': [], 'title': [], 'class': [], 'dir': ['ltr', 'rtl'], 'cite': [], 'style': [], 'onmousemove': [], 'onmouseout': []}
+\ ],
+\ 's': [
+\ ['tt', 'i', 'b', 'u', 's', 'strike', 'big', 'small', 'em', 'strong', 'dfn', 'code', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'a', 'img', 'applet', 'object', 'font', 'basefont', 'br', 'script', 'map', 'q', 'sub', 'sup', 'span', 'bdo', 'iframe', 'input', 'select', 'textarea', 'label', 'button'],
+\ { 'ondblclick': [], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'onmousedown': [], 'onkeypress': [], 'onclick': [], 'title': [], 'class': [], 'dir': ['ltr', 'rtl'], 'style': [], 'onmousemove': [], 'onmouseout': []}
+\ ],
+\ 'samp': [
+\ ['tt', 'i', 'b', 'u', 's', 'strike', 'big', 'small', 'em', 'strong', 'dfn', 'code', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'a', 'img', 'applet', 'object', 'font', 'basefont', 'br', 'script', 'map', 'q', 'sub', 'sup', 'span', 'bdo', 'iframe', 'input', 'select', 'textarea', 'label', 'button'],
+\ { 'ondblclick': [], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'onmousedown': [], 'onkeypress': [], 'onclick': [], 'title': [], 'class': [], 'dir': ['ltr', 'rtl'], 'style': [], 'onmousemove': [], 'onmouseout': []}
+\ ],
+\ 'script': [
+\ [],
+\ { 'src': [], 'for': [], 'charset': [], 'event': [], 'type': [], 'defer': ['BOOL'], 'language': []}
+\ ],
+\ 'select': [
+\ ['optgroup', 'option'],
+\ { 'ondblclick': [], 'onkeydown': [], 'onchange': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'name': [], 'onkeypress': [], 'onmousedown': [], 'class': [], 'title': [], 'onclick': [], 'disabled': ['BOOL'], 'dir': ['ltr', 'rtl'], 'size': [], 'onblur': [], 'onfocus': [], 'tabindex': [], 'onmouseout': [], 'onmousemove': [], 'style': [], 'multiple': ['BOOL']}
+\ ],
+\ 'small': [
+\ ['tt', 'i', 'b', 'u', 's', 'strike', 'big', 'small', 'em', 'strong', 'dfn', 'code', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'a', 'img', 'applet', 'object', 'font', 'basefont', 'br', 'script', 'map', 'q', 'sub', 'sup', 'span', 'bdo', 'iframe', 'input', 'select', 'textarea', 'label', 'button'],
+\ { 'ondblclick': [], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'onmousedown': [], 'onkeypress': [], 'onclick': [], 'title': [], 'class': [], 'dir': ['ltr', 'rtl'], 'style': [], 'onmousemove': [], 'onmouseout': []}
+\ ],
+\ 'span': [
+\ ['tt', 'i', 'b', 'u', 's', 'strike', 'big', 'small', 'em', 'strong', 'dfn', 'code', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'a', 'img', 'applet', 'object', 'font', 'basefont', 'br', 'script', 'map', 'q', 'sub', 'sup', 'span', 'bdo', 'iframe', 'input', 'select', 'textarea', 'label', 'button'],
+\ { 'ondblclick': [], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'onmousedown': [], 'onkeypress': [], 'onclick': [], 'title': [], 'class': [], 'dir': ['ltr', 'rtl'], 'style': [], 'onmousemove': [], 'onmouseout': []}
+\ ],
+\ 'strike': [
+\ ['tt', 'i', 'b', 'u', 's', 'strike', 'big', 'small', 'em', 'strong', 'dfn', 'code', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'a', 'img', 'applet', 'object', 'font', 'basefont', 'br', 'script', 'map', 'q', 'sub', 'sup', 'span', 'bdo', 'iframe', 'input', 'select', 'textarea', 'label', 'button'],
+\ { 'ondblclick': [], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'onmousedown': [], 'onkeypress': [], 'onclick': [], 'title': [], 'class': [], 'dir': ['ltr', 'rtl'], 'style': [], 'onmousemove': [], 'onmouseout': []}
+\ ],
+\ 'strong': [
+\ ['tt', 'i', 'b', 'u', 's', 'strike', 'big', 'small', 'em', 'strong', 'dfn', 'code', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'a', 'img', 'applet', 'object', 'font', 'basefont', 'br', 'script', 'map', 'q', 'sub', 'sup', 'span', 'bdo', 'iframe', 'input', 'select', 'textarea', 'label', 'button'],
+\ { 'ondblclick': [], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'onmousedown': [], 'onkeypress': [], 'onclick': [], 'title': [], 'class': [], 'dir': ['ltr', 'rtl'], 'style': [], 'onmousemove': [], 'onmouseout': []}
+\ ],
+\ 'style': [
+\ [],
+\ { 'media': [], 'lang': [], 'type': [], 'title': [], 'dir': ['ltr', 'rtl']}
+\ ],
+\ 'sub': [
+\ ['tt', 'i', 'b', 'u', 's', 'strike', 'big', 'small', 'em', 'strong', 'dfn', 'code', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'a', 'img', 'applet', 'object', 'font', 'basefont', 'br', 'script', 'map', 'q', 'sub', 'sup', 'span', 'bdo', 'iframe', 'input', 'select', 'textarea', 'label', 'button'],
+\ { 'ondblclick': [], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'onmousedown': [], 'onkeypress': [], 'onclick': [], 'title': [], 'class': [], 'dir': ['ltr', 'rtl'], 'style': [], 'onmousemove': [], 'onmouseout': []}
+\ ],
+\ 'sup': [
+\ ['tt', 'i', 'b', 'u', 's', 'strike', 'big', 'small', 'em', 'strong', 'dfn', 'code', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'a', 'img', 'applet', 'object', 'font', 'basefont', 'br', 'script', 'map', 'q', 'sub', 'sup', 'span', 'bdo', 'iframe', 'input', 'select', 'textarea', 'label', 'button'],
+\ { 'ondblclick': [], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'onmousedown': [], 'onkeypress': [], 'onclick': [], 'title': [], 'class': [], 'dir': ['ltr', 'rtl'], 'style': [], 'onmousemove': [], 'onmouseout': []}
+\ ],
+\ 'table': [
+\ ['caption', 'col', 'colgroup', 'thead', 'tfoot', 'tbody'],
+\ { 'ondblclick': [], 'onkeydown': [], 'onkeyup': [], 'datapagesize': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'align': ['left', 'center', 'right'], 'onkeypress': [], 'onmousedown': [], 'class': [], 'title': [], 'onclick': [], 'width': [], 'frame': ['void', 'above', 'below', 'hsides', 'lhs', 'rhs', 'vsides', 'box', 'border'], 'rules': ['none', 'groups', 'rows', 'cols', 'all'], 'dir': ['ltr', 'rtl'], 'summary': [], 'bgcolor': [], 'cellspacing': [], 'onmouseout': [], 'onmousemove': [], 'style': [], 'border': [], 'cellpadding': []}
+\ ],
+\ 'tbody': [
+\ ['tr'],
+\ { 'ondblclick': [], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'align': ['left', 'center', 'right', 'justify', 'char'], 'lang': [], 'valign': ['top', 'middle', 'bottom', 'baseline'], 'onkeypress': [], 'onmousedown': [], 'class': [], 'title': [], 'onclick': [], 'dir': ['ltr', 'rtl'], 'charoff': [], 'onmouseout': [], 'onmousemove': [], 'style': [], 'char': []}
+\ ],
+\ 'td': [
+\ ['p', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'ul', 'ol', 'dir', 'menu', 'pre', 'dl', 'div', 'center', 'noscript', 'noframes', 'blockquote', 'form', 'isindex', 'hr', 'table', 'fieldset', 'address', 'tt', 'i', 'b', 'u', 's', 'strike', 'big', 'small', 'em', 'strong', 'dfn', 'code', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'a', 'img', 'applet', 'object', 'font', 'basefont', 'br', 'script', 'map', 'q', 'sub', 'sup', 'span', 'bdo', 'iframe', 'input', 'select', 'textarea', 'label', 'button'],
+\ { 'ondblclick': [], 'axis': [], 'onkeydown': [], 'abbr': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'scope': ['row', 'col', 'rowgroup', 'colgroup'], 'onmouseover': [], 'lang': [], 'align': ['left', 'center', 'right', 'justify', 'char'], 'valign': ['top', 'middle', 'bottom', 'baseline'], 'onkeypress': [], 'onmousedown': [], 'class': [], 'title': [], 'onclick': [], 'width': [], 'headers': [], 'nowrap': ['BOOL'], 'dir': ['ltr', 'rtl'], 'rowspan': ['1'], 'colspan': ['1'], 'bgcolor': [], 'charoff': [], 'onmouseout': [], 'onmousemove': [], 'style': [], 'height': [], 'char': []}
+\ ],
+\ 'textarea': [
+\ [''],
+\ { 'ondblclick': [], 'cols': [], 'onkeydown': [], 'readonly': ['BOOL'], 'onchange': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'name': [], 'onkeypress': [], 'onmousedown': [], 'class': [], 'title': [], 'onclick': [], 'accesskey': [], 'disabled': ['BOOL'], 'rows': [], 'dir': ['ltr', 'rtl'], 'onblur': [], 'onfocus': [], 'onselect': [], 'tabindex': [], 'onmouseout': [], 'onmousemove': [], 'style': []}
+\ ],
+\ 'tfoot': [
+\ ['tr'],
+\ { 'ondblclick': [], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'align': ['left', 'center', 'right', 'justify', 'char'], 'lang': [], 'valign': ['top', 'middle', 'bottom', 'baseline'], 'onkeypress': [], 'onmousedown': [], 'class': [], 'title': [], 'onclick': [], 'dir': ['ltr', 'rtl'], 'charoff': [], 'onmouseout': [], 'onmousemove': [], 'style': [], 'char': []}
+\ ],
+\ 'th': [
+\ ['p', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'ul', 'ol', 'dir', 'menu', 'pre', 'dl', 'div', 'center', 'noscript', 'noframes', 'blockquote', 'form', 'isindex', 'hr', 'table', 'fieldset', 'address', 'tt', 'i', 'b', 'u', 's', 'strike', 'big', 'small', 'em', 'strong', 'dfn', 'code', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'a', 'img', 'applet', 'object', 'font', 'basefont', 'br', 'script', 'map', 'q', 'sub', 'sup', 'span', 'bdo', 'iframe', 'input', 'select', 'textarea', 'label', 'button'],
+\ { 'ondblclick': [], 'axis': [], 'onkeydown': [], 'abbr': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'scope': ['row', 'col', 'rowgroup', 'colgroup'], 'onmouseover': [], 'lang': [], 'align': ['left', 'center', 'right', 'justify', 'char'], 'valign': ['top', 'middle', 'bottom', 'baseline'], 'onkeypress': [], 'onmousedown': [], 'class': [], 'title': [], 'onclick': [], 'width': [], 'headers': [], 'nowrap': ['BOOL'], 'dir': ['ltr', 'rtl'], 'rowspan': ['1'], 'colspan': ['1'], 'bgcolor': [], 'charoff': [], 'onmouseout': [], 'onmousemove': [], 'style': [], 'height': [], 'char': []}
+\ ],
+\ 'thead': [
+\ ['tr'],
+\ { 'ondblclick': [], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'align': ['left', 'center', 'right', 'justify', 'char'], 'lang': [], 'valign': ['top', 'middle', 'bottom', 'baseline'], 'onkeypress': [], 'onmousedown': [], 'class': [], 'title': [], 'onclick': [], 'dir': ['ltr', 'rtl'], 'charoff': [], 'onmouseout': [], 'onmousemove': [], 'style': [], 'char': []}
+\ ],
+\ 'title': [
+\ [''],
+\ { 'lang': [], 'dir': ['ltr', 'rtl']}
+\ ],
+\ 'tr': [
+\ ['th', 'td'],
+\ { 'ondblclick': [], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'align': ['left', 'center', 'right', 'justify', 'char'], 'lang': [], 'valign': ['top', 'middle', 'bottom', 'baseline'], 'onkeypress': [], 'onmousedown': [], 'class': [], 'title': [], 'onclick': [], 'dir': ['ltr', 'rtl'], 'bgcolor': [], 'charoff': [], 'onmouseout': [], 'onmousemove': [], 'style': [], 'char': []}
+\ ],
+\ 'tt': [
+\ ['tt', 'i', 'b', 'u', 's', 'strike', 'big', 'small', 'em', 'strong', 'dfn', 'code', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'a', 'img', 'applet', 'object', 'font', 'basefont', 'br', 'script', 'map', 'q', 'sub', 'sup', 'span', 'bdo', 'iframe', 'input', 'select', 'textarea', 'label', 'button'],
+\ { 'ondblclick': [], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'onmousedown': [], 'onkeypress': [], 'onclick': [], 'title': [], 'class': [], 'dir': ['ltr', 'rtl'], 'style': [], 'onmousemove': [], 'onmouseout': []}
+\ ],
+\ 'u': [
+\ ['tt', 'i', 'b', 'u', 's', 'strike', 'big', 'small', 'em', 'strong', 'dfn', 'code', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'a', 'img', 'applet', 'object', 'font', 'basefont', 'br', 'script', 'map', 'q', 'sub', 'sup', 'span', 'bdo', 'iframe', 'input', 'select', 'textarea', 'label', 'button'],
+\ { 'ondblclick': [], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'onmousedown': [], 'onkeypress': [], 'onclick': [], 'title': [], 'class': [], 'dir': ['ltr', 'rtl'], 'style': [], 'onmousemove': [], 'onmouseout': []}
+\ ],
+\ 'ul': [
+\ ['li'],
+\ { 'ondblclick': [], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'compact': ['BOOL'], 'onmouseover': [], 'lang': [], 'onkeypress': [], 'onmousedown': [], 'type': ['disc', 'square', 'circle'], 'class': [], 'title': [], 'onclick': [], 'dir': ['ltr', 'rtl'], 'onmouseout': [], 'onmousemove': [], 'style': []}
+\ ],
+\ 'var': [
+\ ['tt', 'i', 'b', 'u', 's', 'strike', 'big', 'small', 'em', 'strong', 'dfn', 'code', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'a', 'img', 'applet', 'object', 'font', 'basefont', 'br', 'script', 'map', 'q', 'sub', 'sup', 'span', 'bdo', 'iframe', 'input', 'select', 'textarea', 'label', 'button'],
+\ { 'ondblclick': [], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'onmousedown': [], 'onkeypress': [], 'onclick': [], 'title': [], 'class': [], 'dir': ['ltr', 'rtl'], 'style': [], 'onmousemove': [], 'onmouseout': []}
+\ ],
+\ 'vimxmlattrinfo' : {
+\ 'accept' : ['ContentType', ''],
+\ 'accesskey' : ['Character', ''],
+\ 'action' : ['*URI', ''],
+\ 'align' : ['String', ''],
+\ 'alt' : ['*Text', ''],
+\ 'archive' : ['UriList', ''],
+\ 'axis' : ['CDATA', ''],
+\ 'border' : ['Pixels', ''],
+\ 'cellpadding' : ['Length', ''],
+\ 'cellspacing' : ['Length', ''],
+\ 'char' : ['Character', ''],
+\ 'charoff' : ['Length', ''],
+\ 'charset' : ['LangCode', ''],
+\ 'checked' : ['Bool', ''],
+\ 'class' : ['CDATA', ''],
+\ 'codetype' : ['ContentType', ''],
+\ 'cols' : ['*Number', ''],
+\ 'colspan' : ['Number', ''],
+\ 'content' : ['*CDATA', ''],
+\ 'coords' : ['Coords', ''],
+\ 'data' : ['URI', ''],
+\ 'datetime' : ['DateTime', ''],
+\ 'declare' : ['Bool', ''],
+\ 'defer' : ['Bool', ''],
+\ 'dir' : ['String', ''],
+\ 'disabled' : ['Bool', ''],
+\ 'enctype' : ['ContentType', ''],
+\ 'for' : ['ID', ''],
+\ 'headers' : ['IDREFS', ''],
+\ 'height' : ['Number', ''],
+\ 'href' : ['*URI', ''],
+\ 'hreflang' : ['LangCode', ''],
+\ 'id' : ['ID', ''],
+\ 'ismap' : ['Bool', ''],
+\ 'label' : ['*Text', ''],
+\ 'lang' : ['LangCode', ''],
+\ 'longdesc' : ['URI', ''],
+\ 'maxlength' : ['Number', ''],
+\ 'media' : ['MediaDesc', ''],
+\ 'method' : ['String', ''],
+\ 'multiple' : ['Bool', ''],
+\ 'name' : ['CDATA', ''],
+\ 'nohref' : ['Bool', ''],
+\ 'onblur' : ['Script', ''],
+\ 'onchange' : ['Script', ''],
+\ 'onclick' : ['Script', ''],
+\ 'ondblclick' : ['Script', ''],
+\ 'onfocus' : ['Script', ''],
+\ 'onkeydown' : ['Script', ''],
+\ 'onkeypress' : ['Script', ''],
+\ 'onkeyup' : ['Script', ''],
+\ 'onload' : ['Script', ''],
+\ 'onmousedown' : ['Script', ''],
+\ 'onmousemove' : ['Script', ''],
+\ 'onmouseout' : ['Script', ''],
+\ 'onmouseover' : ['Script', ''],
+\ 'onmouseup' : ['Script', ''],
+\ 'onreset' : ['Script', ''],
+\ 'onselect' : ['Script', ''],
+\ 'onsubmit' : ['Script', ''],
+\ 'onunload' : ['Script', ''],
+\ 'profile' : ['URI', ''],
+\ 'readonly' : ['Bool', ''],
+\ 'rel' : ['LinkTypes', ''],
+\ 'rev' : ['LinkTypes', ''],
+\ 'rows' : ['*Number', ''],
+\ 'rules' : ['String', ''],
+\ 'scheme' : ['CDATA', ''],
+\ 'selected' : ['Bool', ''],
+\ 'shape' : ['Shape', ''],
+\ 'size' : ['CDATA', ''],
+\ 'span' : ['Number', ''],
+\ 'src' : ['*URI', ''],
+\ 'standby' : ['Text', ''],
+\ 'style' : ['StyleSheet', ''],
+\ 'summary' : ['*Text', ''],
+\ 'tabindex' : ['Number', ''],
+\ 'title' : ['Text', ''],
+\ 'type' : ['*ContentType', ''],
+\ 'usemap' : ['URI', ''],
+\ 'valign' : ['String', ''],
+\ 'valuetype' : ['String', ''],
+\ 'width' : ['Number', ''],
+\ 'xmlns' : ['URI', '']
+\ },
+\ 'vimxmltaginfo': {
+\ 'area': ['/>', ''],
+\ 'base': ['/>', ''],
+\ 'basefont': ['/>', ''],
+\ 'br': ['/>', ''],
+\ 'col': ['/>', ''],
+\ 'hr': ['/>', ''],
+\ 'img': ['/>', ''],
+\ 'input': ['/>', ''],
+\ 'isindex': ['/>', ''],
+\ 'link': ['/>', ''],
+\ 'meta': ['/>', ''],
+\ 'param': ['/>', ''],
+\ }
+\ }
+" vim:ft=vim:ff=unix
--- /dev/null
+++ b/lib/vimfiles/autoload/xml/html401s.vim
@@ -1,0 +1,411 @@
+let g:xmldata_html401s = {
+\ 'vimxmlentities': ['AElig', 'Aacute', 'Acirc', 'Agrave', 'Alpha', 'Aring', 'Atilde', 'Auml', 'Beta', 'Ccedil', 'Chi', 'Dagger', 'Delta', 'ETH', 'Eacute', 'Ecirc', 'Egrave', 'Epsilon', 'Eta', 'Euml', 'Gamma', 'Iacute', 'Icirc', 'Igrave', 'Iota', 'Iuml', 'Kappa', 'Lambda', 'Mu', 'Ntilde', 'Nu', 'OElig', 'Oacute', 'Ocirc', 'Ograve', 'Omega', 'Omicron', 'Oslash', 'Otilde', 'Ouml', 'Phi', 'Pi', 'Prime', 'Psi', 'Rho', 'Scaron', 'Sigma', 'THORN', 'Tau', 'Theta', 'Uacute', 'Ucirc', 'Ugrave', 'Upsilon', 'Uuml', 'Xi', 'Yacute', 'Yuml', 'Zeta', 'aacute', 'acirc', 'acute', 'aelig', 'agrave', 'alefsym', 'alpha', 'amp', 'and', 'ang', 'apos', 'aring', 'asymp', 'atilde', 'auml', 'bdquo', 'beta', 'brvbar', 'bull', 'cap', 'ccedil', 'cedil', 'cent', 'chi', 'circ', 'clubs', 'cong', 'copy', 'crarr', 'cup', 'curren', 'dArr', 'dagger', 'darr', 'deg', 'delta', 'diams', 'divide', 'eacute', 'ecirc', 'egrave', 'empty', 'emsp', 'ensp', 'epsilon', 'equiv', 'eta', 'eth', 'euml', 'euro', 'exist', 'fnof', 'forall', 'frac12', 'frac14', 'frac34', 'frasl', 'gamma', 'ge', 'gt', 'hArr', 'harr', 'hearts', 'hellip', 'iacute', 'icirc', 'iexcl', 'igrave', 'image', 'infin', 'int', 'iota', 'iquest', 'isin', 'iuml', 'kappa', 'lArr', 'lambda', 'lang', 'laquo', 'larr', 'lceil', 'ldquo', 'le', 'lfloor', 'lowast', 'loz', 'lrm', 'lsaquo', 'lsquo', 'lt', 'macr', 'mdash', 'micro', 'middot', 'minus', 'mu', 'nabla', 'nbsp', 'ndash', 'ne', 'ni', 'not', 'notin', 'nsub', 'ntilde', 'nu', 'oacute', 'ocirc', 'oelig', 'ograve', 'oline', 'omega', 'omicron', 'oplus', 'or', 'ordf', 'ordm', 'oslash', 'otilde', 'otimes', 'ouml', 'para', 'part', 'permil', 'perp', 'phi', 'pi', 'piv', 'plusmn', 'pound', 'prime', 'prod', 'prop', 'psi', 'quot', 'rArr', 'radic', 'rang', 'raquo', 'rarr', 'rceil', 'rdquo', 'real', 'reg', 'rfloor', 'rho', 'rlm', 'rsaquo', 'rsquo', 'sbquo', 'scaron', 'sdot', 'sect', 'shy', 'sigma', 'sigmaf', 'sim', 'spades', 'sub', 'sube', 'sum', 'sup', 'sup1', 'sup2', 'sup3', 'supe', 'szlig', 'tau', 'there4', 'theta', 'thetasym', 'thinsp', 'thorn', 'tilde', 'times', 'trade', 'uArr', 'uacute', 'uarr', 'ucirc', 'ugrave', 'uml', 'upsih', 'upsilon', 'uuml', 'weierp', 'xi', 'yacute', 'yen', 'yuml', 'zeta', 'zwj', 'zwnj'],
+\ 'vimxmlroot': ['html'],
+\ 'a': [
+\ ['tt', 'i', 'b', 'big', 'small', 'em', 'strong', 'dfn', 'code', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'img', 'object', 'br', 'script', 'map', 'q', 'sub', 'sup', 'span', 'bdo', 'input', 'select', 'textarea', 'label', 'button'],
+\ { 'rel': [], 'accesskey': [], 'coords': [], 'ondblclick': [], 'dir': ['ltr', 'rtl'], 'onblur': [], 'onfocus': [], 'onkeydown': [], 'onkeyup': [], 'href': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'tabindex': [], 'lang': [], 'onmouseout': [], 'onmousemove': [], 'name': [], 'style': [], 'charset': [], 'hreflang': [], 'onkeypress': [], 'onmousedown': [], 'rev': [], 'class': [], 'title': [], 'onclick': [], 'type': [], 'shape': ['rect', 'circle', 'poly', 'default']}
+\ ],
+\ 'abbr': [
+\ ['tt', 'i', 'b', 'big', 'small', 'em', 'strong', 'dfn', 'code', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'a', 'img', 'object', 'br', 'script', 'map', 'q', 'sub', 'sup', 'span', 'bdo', 'input', 'select', 'textarea', 'label', 'button'],
+\ { 'ondblclick': [], 'dir': ['ltr', 'rtl'], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'style': [], 'onmousemove': [], 'onmouseout': [], 'onmousedown': [], 'onkeypress': [], 'onclick': [], 'title': [], 'class': []}
+\ ],
+\ 'acronym': [
+\ ['tt', 'i', 'b', 'big', 'small', 'em', 'strong', 'dfn', 'code', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'a', 'img', 'object', 'br', 'script', 'map', 'q', 'sub', 'sup', 'span', 'bdo', 'input', 'select', 'textarea', 'label', 'button'],
+\ { 'ondblclick': [], 'dir': ['ltr', 'rtl'], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'style': [], 'onmousemove': [], 'onmouseout': [], 'onmousedown': [], 'onkeypress': [], 'onclick': [], 'title': [], 'class': []}
+\ ],
+\ 'address': [
+\ ['tt', 'i', 'b', 'big', 'small', 'em', 'strong', 'dfn', 'code', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'a', 'img', 'object', 'br', 'script', 'map', 'q', 'sub', 'sup', 'span', 'bdo', 'input', 'select', 'textarea', 'label', 'button'],
+\ { 'ondblclick': [], 'dir': ['ltr', 'rtl'], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'style': [], 'onmousemove': [], 'onmouseout': [], 'onmousedown': [], 'onkeypress': [], 'onclick': [], 'title': [], 'class': []}
+\ ],
+\ 'area': [
+\ [],
+\ { 'accesskey': [], 'coords': [], 'ondblclick': [], 'dir': ['ltr', 'rtl'], 'onblur': [], 'onkeydown': [], 'nohref': ['BOOL'], 'onfocus': [], 'onkeyup': [], 'href': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'alt': [], 'tabindex': [], 'onmouseout': [], 'onmousemove': [], 'style': [], 'onkeypress': [], 'onmousedown': [], 'shape': ['rect', 'circle', 'poly', 'default'], 'class': [], 'title': [], 'onclick': []}
+\ ],
+\ 'b': [
+\ ['tt', 'i', 'b', 'big', 'small', 'em', 'strong', 'dfn', 'code', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'a', 'img', 'object', 'br', 'script', 'map', 'q', 'sub', 'sup', 'span', 'bdo', 'input', 'select', 'textarea', 'label', 'button'],
+\ { 'ondblclick': [], 'dir': ['ltr', 'rtl'], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'style': [], 'onmousemove': [], 'onmouseout': [], 'onmousedown': [], 'onkeypress': [], 'onclick': [], 'title': [], 'class': []}
+\ ],
+\ 'base': [
+\ [],
+\ { 'href': []}
+\ ],
+\ 'bdo': [
+\ ['tt', 'i', 'b', 'big', 'small', 'em', 'strong', 'dfn', 'code', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'a', 'img', 'object', 'br', 'script', 'map', 'q', 'sub', 'sup', 'span', 'bdo', 'input', 'select', 'textarea', 'label', 'button'],
+\ { 'dir': ['ltr', 'rtl'], 'id': [], 'lang': [], 'style': [], 'class': [], 'title': []}
+\ ],
+\ 'big': [
+\ ['tt', 'i', 'b', 'big', 'small', 'em', 'strong', 'dfn', 'code', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'a', 'img', 'object', 'br', 'script', 'map', 'q', 'sub', 'sup', 'span', 'bdo', 'input', 'select', 'textarea', 'label', 'button'],
+\ { 'ondblclick': [], 'dir': ['ltr', 'rtl'], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'style': [], 'onmousemove': [], 'onmouseout': [], 'onmousedown': [], 'onkeypress': [], 'onclick': [], 'title': [], 'class': []}
+\ ],
+\ 'blockquote': [
+\ ['p', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'ul', 'ol', 'pre', 'dl', 'div', 'noscript', 'blockquote', 'form', 'hr', 'table', 'fieldset', 'address', 'script'],
+\ { 'ondblclick': [], 'dir': ['ltr', 'rtl'], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'cite': [], 'onmouseover': [], 'lang': [], 'style': [], 'onmousemove': [], 'onmouseout': [], 'onmousedown': [], 'onkeypress': [], 'onclick': [], 'title': [], 'class': []}
+\ ],
+\ 'body': [
+\ ['p', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'ul', 'ol', 'pre', 'dl', 'div', 'noscript', 'blockquote', 'form', 'hr', 'table', 'fieldset', 'address', 'script', 'ins', 'del'],
+\ { 'ondblclick': [], 'dir': ['ltr', 'rtl'], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'onmouseout': [], 'onmousemove': [], 'style': [], 'onunload': [], 'onkeypress': [], 'onmousedown': [], 'onload': [], 'class': [], 'title': [], 'onclick': []}
+\ ],
+\ 'br': [
+\ [],
+\ { 'id': [], 'style': [], 'class': [], 'title': []}
+\ ],
+\ 'button': [
+\ ['p', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'ul', 'ol', 'pre', 'dl', 'div', 'noscript', 'blockquote', 'hr', 'table', 'address', 'tt', 'i', 'b', 'big', 'small', 'em', 'strong', 'dfn', 'code', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'img', 'object', 'br', 'script', 'map', 'q', 'sub', 'sup', 'span', 'bdo'],
+\ { 'accesskey': [], 'disabled': ['BOOL'], 'ondblclick': [], 'dir': ['ltr', 'rtl'], 'onblur': [], 'onkeydown': [], 'onfocus': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'tabindex': [], 'value': [], 'name': [], 'onmouseout': [], 'onmousemove': [], 'style': [], 'onkeypress': [], 'onmousedown': [], 'class': [], 'title': [], 'onclick': [], 'type': ['submit', 'button', 'submit', 'reset']}
+\ ],
+\ 'caption': [
+\ ['tt', 'i', 'b', 'big', 'small', 'em', 'strong', 'dfn', 'code', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'a', 'img', 'object', 'br', 'script', 'map', 'q', 'sub', 'sup', 'span', 'bdo', 'input', 'select', 'textarea', 'label', 'button'],
+\ { 'ondblclick': [], 'dir': ['ltr', 'rtl'], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'style': [], 'onmousemove': [], 'onmouseout': [], 'onmousedown': [], 'onkeypress': [], 'onclick': [], 'title': [], 'class': []}
+\ ],
+\ 'cite': [
+\ ['tt', 'i', 'b', 'big', 'small', 'em', 'strong', 'dfn', 'code', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'a', 'img', 'object', 'br', 'script', 'map', 'q', 'sub', 'sup', 'span', 'bdo', 'input', 'select', 'textarea', 'label', 'button'],
+\ { 'ondblclick': [], 'dir': ['ltr', 'rtl'], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'style': [], 'onmousemove': [], 'onmouseout': [], 'onmousedown': [], 'onkeypress': [], 'onclick': [], 'title': [], 'class': []}
+\ ],
+\ 'code': [
+\ ['tt', 'i', 'b', 'big', 'small', 'em', 'strong', 'dfn', 'code', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'a', 'img', 'object', 'br', 'script', 'map', 'q', 'sub', 'sup', 'span', 'bdo', 'input', 'select', 'textarea', 'label', 'button'],
+\ { 'ondblclick': [], 'dir': ['ltr', 'rtl'], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'style': [], 'onmousemove': [], 'onmouseout': [], 'onmousedown': [], 'onkeypress': [], 'onclick': [], 'title': [], 'class': []}
+\ ],
+\ 'col': [
+\ [],
+\ { 'width': [], 'ondblclick': [], 'dir': ['ltr', 'rtl'], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'charoff': [], 'onmouseover': [], 'lang': [], 'align': ['left', 'center', 'right', 'justify', 'char'], 'valign': ['top', 'middle', 'bottom', 'baseline'], 'onmouseout': [], 'onmousemove': [], 'style': [], 'onkeypress': [], 'onmousedown': [], 'char': [], 'span': ['1'], 'class': [], 'title': [], 'onclick': []}
+\ ],
+\ 'colgroup': [
+\ ['col'],
+\ { 'width': [], 'ondblclick': [], 'dir': ['ltr', 'rtl'], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'charoff': [], 'onmouseover': [], 'lang': [], 'align': ['left', 'center', 'right', 'justify', 'char'], 'valign': ['top', 'middle', 'bottom', 'baseline'], 'onmouseout': [], 'onmousemove': [], 'style': [], 'onkeypress': [], 'onmousedown': [], 'char': [], 'span': ['1'], 'class': [], 'title': [], 'onclick': []}
+\ ],
+\ 'dd': [
+\ ['p', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'ul', 'ol', 'pre', 'dl', 'div', 'noscript', 'blockquote', 'form', 'hr', 'table', 'fieldset', 'address', 'tt', 'i', 'b', 'big', 'small', 'em', 'strong', 'dfn', 'code', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'a', 'img', 'object', 'br', 'script', 'map', 'q', 'sub', 'sup', 'span', 'bdo', 'input', 'select', 'textarea', 'label', 'button'],
+\ { 'ondblclick': [], 'dir': ['ltr', 'rtl'], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'style': [], 'onmousemove': [], 'onmouseout': [], 'onmousedown': [], 'onkeypress': [], 'onclick': [], 'title': [], 'class': []}
+\ ],
+\ 'del': [
+\ ['p', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'ul', 'ol', 'pre', 'dl', 'div', 'noscript', 'blockquote', 'form', 'hr', 'table', 'fieldset', 'address', 'tt', 'i', 'b', 'big', 'small', 'em', 'strong', 'dfn', 'code', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'a', 'img', 'object', 'br', 'script', 'map', 'q', 'sub', 'sup', 'span', 'bdo', 'input', 'select', 'textarea', 'label', 'button'],
+\ { 'ondblclick': [], 'dir': ['ltr', 'rtl'], 'datetime': [], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'cite': [], 'onmouseover': [], 'lang': [], 'onmouseout': [], 'onmousemove': [], 'style': [], 'onkeypress': [], 'onmousedown': [], 'class': [], 'title': [], 'onclick': []}
+\ ],
+\ 'dfn': [
+\ ['tt', 'i', 'b', 'big', 'small', 'em', 'strong', 'dfn', 'code', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'a', 'img', 'object', 'br', 'script', 'map', 'q', 'sub', 'sup', 'span', 'bdo', 'input', 'select', 'textarea', 'label', 'button'],
+\ { 'ondblclick': [], 'dir': ['ltr', 'rtl'], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'style': [], 'onmousemove': [], 'onmouseout': [], 'onmousedown': [], 'onkeypress': [], 'onclick': [], 'title': [], 'class': []}
+\ ],
+\ 'div': [
+\ ['p', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'ul', 'ol', 'pre', 'dl', 'div', 'noscript', 'blockquote', 'form', 'hr', 'table', 'fieldset', 'address', 'tt', 'i', 'b', 'big', 'small', 'em', 'strong', 'dfn', 'code', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'a', 'img', 'object', 'br', 'script', 'map', 'q', 'sub', 'sup', 'span', 'bdo', 'input', 'select', 'textarea', 'label', 'button'],
+\ { 'ondblclick': [], 'dir': ['ltr', 'rtl'], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'style': [], 'onmousemove': [], 'onmouseout': [], 'onmousedown': [], 'onkeypress': [], 'onclick': [], 'title': [], 'class': []}
+\ ],
+\ 'dl': [
+\ ['dt', 'dd'],
+\ { 'ondblclick': [], 'dir': ['ltr', 'rtl'], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'style': [], 'onmousemove': [], 'onmouseout': [], 'onmousedown': [], 'onkeypress': [], 'onclick': [], 'title': [], 'class': []}
+\ ],
+\ 'dt': [
+\ ['tt', 'i', 'b', 'big', 'small', 'em', 'strong', 'dfn', 'code', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'a', 'img', 'object', 'br', 'script', 'map', 'q', 'sub', 'sup', 'span', 'bdo', 'input', 'select', 'textarea', 'label', 'button'],
+\ { 'ondblclick': [], 'dir': ['ltr', 'rtl'], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'style': [], 'onmousemove': [], 'onmouseout': [], 'onmousedown': [], 'onkeypress': [], 'onclick': [], 'title': [], 'class': []}
+\ ],
+\ 'em': [
+\ ['tt', 'i', 'b', 'big', 'small', 'em', 'strong', 'dfn', 'code', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'a', 'img', 'object', 'br', 'script', 'map', 'q', 'sub', 'sup', 'span', 'bdo', 'input', 'select', 'textarea', 'label', 'button'],
+\ { 'ondblclick': [], 'dir': ['ltr', 'rtl'], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'style': [], 'onmousemove': [], 'onmouseout': [], 'onmousedown': [], 'onkeypress': [], 'onclick': [], 'title': [], 'class': []}
+\ ],
+\ 'fieldset': [
+\ ['legend', 'p', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'ul', 'ol', 'pre', 'dl', 'div', 'noscript', 'blockquote', 'form', 'hr', 'table', 'fieldset', 'address', 'tt', 'i', 'b', 'big', 'small', 'em', 'strong', 'dfn', 'code', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'a', 'img', 'object', 'br', 'script', 'map', 'q', 'sub', 'sup', 'span', 'bdo', 'input', 'select', 'textarea', 'label', 'button'],
+\ { 'ondblclick': [], 'dir': ['ltr', 'rtl'], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'style': [], 'onmousemove': [], 'onmouseout': [], 'onmousedown': [], 'onkeypress': [], 'onclick': [], 'title': [], 'class': []}
+\ ],
+\ 'form': [
+\ ['p', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'ul', 'ol', 'pre', 'dl', 'div', 'noscript', 'blockquote', 'hr', 'table', 'fieldset', 'address', 'script'],
+\ { 'enctype': ['application/x-www-form-urlencoded'], 'onsubmit': [], 'ondblclick': [], 'dir': ['ltr', 'rtl'], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'onreset': [], 'id': [], 'method': ['GET', 'POST'], 'onmouseover': [], 'lang': [], 'accept': [], 'onmouseout': [], 'onmousemove': [], 'style': [], 'name': [], 'accept-charset': [], 'onkeypress': [], 'onmousedown': [], 'action': [], 'class': [], 'title': [], 'onclick': []}
+\ ],
+\ 'h1': [
+\ ['tt', 'i', 'b', 'big', 'small', 'em', 'strong', 'dfn', 'code', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'a', 'img', 'object', 'br', 'script', 'map', 'q', 'sub', 'sup', 'span', 'bdo', 'input', 'select', 'textarea', 'label', 'button'],
+\ { 'ondblclick': [], 'dir': ['ltr', 'rtl'], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'style': [], 'onmousemove': [], 'onmouseout': [], 'onmousedown': [], 'onkeypress': [], 'onclick': [], 'title': [], 'class': []}
+\ ],
+\ 'h2': [
+\ ['tt', 'i', 'b', 'big', 'small', 'em', 'strong', 'dfn', 'code', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'a', 'img', 'object', 'br', 'script', 'map', 'q', 'sub', 'sup', 'span', 'bdo', 'input', 'select', 'textarea', 'label', 'button'],
+\ { 'ondblclick': [], 'dir': ['ltr', 'rtl'], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'style': [], 'onmousemove': [], 'onmouseout': [], 'onmousedown': [], 'onkeypress': [], 'onclick': [], 'title': [], 'class': []}
+\ ],
+\ 'h3': [
+\ ['tt', 'i', 'b', 'big', 'small', 'em', 'strong', 'dfn', 'code', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'a', 'img', 'object', 'br', 'script', 'map', 'q', 'sub', 'sup', 'span', 'bdo', 'input', 'select', 'textarea', 'label', 'button'],
+\ { 'ondblclick': [], 'dir': ['ltr', 'rtl'], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'style': [], 'onmousemove': [], 'onmouseout': [], 'onmousedown': [], 'onkeypress': [], 'onclick': [], 'title': [], 'class': []}
+\ ],
+\ 'h4': [
+\ ['tt', 'i', 'b', 'big', 'small', 'em', 'strong', 'dfn', 'code', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'a', 'img', 'object', 'br', 'script', 'map', 'q', 'sub', 'sup', 'span', 'bdo', 'input', 'select', 'textarea', 'label', 'button'],
+\ { 'ondblclick': [], 'dir': ['ltr', 'rtl'], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'style': [], 'onmousemove': [], 'onmouseout': [], 'onmousedown': [], 'onkeypress': [], 'onclick': [], 'title': [], 'class': []}
+\ ],
+\ 'h5': [
+\ ['tt', 'i', 'b', 'big', 'small', 'em', 'strong', 'dfn', 'code', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'a', 'img', 'object', 'br', 'script', 'map', 'q', 'sub', 'sup', 'span', 'bdo', 'input', 'select', 'textarea', 'label', 'button'],
+\ { 'ondblclick': [], 'dir': ['ltr', 'rtl'], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'style': [], 'onmousemove': [], 'onmouseout': [], 'onmousedown': [], 'onkeypress': [], 'onclick': [], 'title': [], 'class': []}
+\ ],
+\ 'h6': [
+\ ['tt', 'i', 'b', 'big', 'small', 'em', 'strong', 'dfn', 'code', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'a', 'img', 'object', 'br', 'script', 'map', 'q', 'sub', 'sup', 'span', 'bdo', 'input', 'select', 'textarea', 'label', 'button'],
+\ { 'ondblclick': [], 'dir': ['ltr', 'rtl'], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'style': [], 'onmousemove': [], 'onmouseout': [], 'onmousedown': [], 'onkeypress': [], 'onclick': [], 'title': [], 'class': []}
+\ ],
+\ 'head': [
+\ ['title', 'base', 'script', 'style', 'meta', 'link', 'object'],
+\ { 'profile': [], 'dir': ['ltr', 'rtl'], 'lang': []}
+\ ],
+\ 'hr': [
+\ [],
+\ { 'ondblclick': [], 'dir': ['ltr', 'rtl'], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'style': [], 'onmousemove': [], 'onmouseout': [], 'onmousedown': [], 'onkeypress': [], 'onclick': [], 'title': [], 'class': []}
+\ ],
+\ 'html': [
+\ ['head', 'body'],
+\ { 'dir': ['ltr', 'rtl'], 'lang': []}
+\ ],
+\ 'i': [
+\ ['tt', 'i', 'b', 'big', 'small', 'em', 'strong', 'dfn', 'code', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'a', 'img', 'object', 'br', 'script', 'map', 'q', 'sub', 'sup', 'span', 'bdo', 'input', 'select', 'textarea', 'label', 'button'],
+\ { 'ondblclick': [], 'dir': ['ltr', 'rtl'], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'style': [], 'onmousemove': [], 'onmouseout': [], 'onmousedown': [], 'onkeypress': [], 'onclick': [], 'title': [], 'class': []}
+\ ],
+\ 'img': [
+\ [],
+\ { 'width': [], 'usemap': [], 'ismap': ['BOOL'], 'ondblclick': [], 'dir': ['ltr', 'rtl'], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'alt': [], 'lang': [], 'src': [], 'longdesc': [], 'onmouseout': [], 'onmousemove': [], 'style': [], 'name': [], 'height': [], 'onkeypress': [], 'onmousedown': [], 'class': [], 'title': [], 'onclick': []}
+\ ],
+\ 'input': [
+\ [],
+\ { 'ondblclick': [], 'onkeydown': [], 'readonly': ['BOOL'], 'onchange': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'value': [], 'src': [], 'name': [], 'checked': ['BOOL'], 'onkeypress': [], 'onmousedown': [], 'type': ['TEXT', 'PASSWORD', 'CHECKBOX', 'RADIO', 'SUBMIT', 'RESET', 'FILE', 'IMAGE', 'BUTTON'], 'class': [], 'title': [], 'onclick': [], 'accesskey': [], 'disabled': ['BOOL'], 'usemap': [], 'ismap': ['BOOL'], 'dir': ['ltr', 'rtl'], 'size': [], 'onblur': [], 'onfocus': [], 'maxlength': [], 'onselect': [], 'accept': [], 'alt': [], 'tabindex': [], 'style': [], 'onmousemove': [], 'onmouseout': []}
+\ ],
+\ 'ins': [
+\ ['p', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'ul', 'ol', 'pre', 'dl', 'div', 'noscript', 'blockquote', 'form', 'hr', 'table', 'fieldset', 'address', 'tt', 'i', 'b', 'big', 'small', 'em', 'strong', 'dfn', 'code', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'a', 'img', 'object', 'br', 'script', 'map', 'q', 'sub', 'sup', 'span', 'bdo', 'input', 'select', 'textarea', 'label', 'button'],
+\ { 'ondblclick': [], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'onkeypress': [], 'onmousedown': [], 'class': [], 'title': [], 'onclick': [], 'dir': ['ltr', 'rtl'], 'datetime': [], 'cite': [], 'onmouseout': [], 'onmousemove': [], 'style': []}
+\ ],
+\ 'kbd': [
+\ ['tt', 'i', 'b', 'big', 'small', 'em', 'strong', 'dfn', 'code', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'a', 'img', 'object', 'br', 'script', 'map', 'q', 'sub', 'sup', 'span', 'bdo', 'input', 'select', 'textarea', 'label', 'button'],
+\ { 'ondblclick': [], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'onmousedown': [], 'onkeypress': [], 'onclick': [], 'title': [], 'class': [], 'dir': ['ltr', 'rtl'], 'style': [], 'onmousemove': [], 'onmouseout': []}
+\ ],
+\ 'label': [
+\ ['tt', 'i', 'b', 'big', 'small', 'em', 'strong', 'dfn', 'code', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'a', 'img', 'object', 'br', 'script', 'map', 'q', 'sub', 'sup', 'span', 'bdo', 'input', 'select', 'textarea', 'button'],
+\ { 'ondblclick': [], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'for': [], 'onkeypress': [], 'onmousedown': [], 'class': [], 'title': [], 'onclick': [], 'accesskey': [], 'dir': ['ltr', 'rtl'], 'onblur': [], 'onfocus': [], 'onmouseout': [], 'onmousemove': [], 'style': []}
+\ ],
+\ 'legend': [
+\ ['tt', 'i', 'b', 'big', 'small', 'em', 'strong', 'dfn', 'code', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'a', 'img', 'object', 'br', 'script', 'map', 'q', 'sub', 'sup', 'span', 'bdo', 'input', 'select', 'textarea', 'label', 'button'],
+\ { 'ondblclick': [], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'onmousedown': [], 'onkeypress': [], 'onclick': [], 'title': [], 'class': [], 'accesskey': [], 'dir': ['ltr', 'rtl'], 'style': [], 'onmousemove': [], 'onmouseout': []}
+\ ],
+\ 'li': [
+\ ['p', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'ul', 'ol', 'pre', 'dl', 'div', 'noscript', 'blockquote', 'form', 'hr', 'table', 'fieldset', 'address', 'tt', 'i', 'b', 'big', 'small', 'em', 'strong', 'dfn', 'code', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'a', 'img', 'object', 'br', 'script', 'map', 'q', 'sub', 'sup', 'span', 'bdo', 'input', 'select', 'textarea', 'label', 'button'],
+\ { 'ondblclick': [], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'onmousedown': [], 'onkeypress': [], 'onclick': [], 'title': [], 'class': [], 'dir': ['ltr', 'rtl'], 'style': [], 'onmousemove': [], 'onmouseout': []}
+\ ],
+\ 'link': [
+\ [],
+\ { 'rel': [], 'ondblclick': [], 'onkeydown': [], 'onkeyup': [], 'href': [], 'media': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'charset': [], 'hreflang': [], 'onkeypress': [], 'onmousedown': [], 'rev': [], 'class': [], 'title': [], 'onclick': [], 'type': [], 'dir': ['ltr', 'rtl'], 'onmouseout': [], 'onmousemove': [], 'style': []}
+\ ],
+\ 'map': [
+\ ['p', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'ul', 'ol', 'pre', 'dl', 'div', 'noscript', 'blockquote', 'form', 'hr', 'table', 'fieldset', 'address', 'area'],
+\ { 'ondblclick': [], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'name': [], 'onkeypress': [], 'onmousedown': [], 'class': [], 'title': [], 'onclick': [], 'dir': ['ltr', 'rtl'], 'onmouseout': [], 'onmousemove': [], 'style': []}
+\ ],
+\ 'meta': [
+\ [],
+\ { 'http-equiv': [], 'content': [], 'lang': [], 'name': [], 'scheme': [], 'dir': ['ltr', 'rtl']}
+\ ],
+\ 'noscript': [
+\ ['p', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'ul', 'ol', 'pre', 'dl', 'div', 'noscript', 'blockquote', 'form', 'hr', 'table', 'fieldset', 'address'],
+\ { 'ondblclick': [], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'onmousedown': [], 'onkeypress': [], 'onclick': [], 'title': [], 'class': [], 'dir': ['ltr', 'rtl'], 'style': [], 'onmousemove': [], 'onmouseout': []}
+\ ],
+\ 'object': [
+\ ['param', 'p', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'ul', 'ol', 'pre', 'dl', 'div', 'noscript', 'blockquote', 'form', 'hr', 'table', 'fieldset', 'address', 'tt', 'i', 'b', 'big', 'small', 'em', 'strong', 'dfn', 'code', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'a', 'img', 'object', 'br', 'script', 'map', 'q', 'sub', 'sup', 'span', 'bdo', 'input', 'select', 'textarea', 'label', 'button'],
+\ { 'ondblclick': [], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'name': [], 'data': [], 'declare': ['BOOL'], 'onkeypress': [], 'onmousedown': [], 'class': [], 'title': [], 'onclick': [], 'type': [], 'width': [], 'usemap': [], 'dir': ['ltr', 'rtl'], 'archive': [], 'standby': [], 'tabindex': [], 'classid': [], 'onmouseout': [], 'onmousemove': [], 'style': [], 'height': [], 'codetype': [], 'codebase': []}
+\ ],
+\ 'ol': [
+\ ['li'],
+\ { 'ondblclick': [], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'onmousedown': [], 'onkeypress': [], 'onclick': [], 'title': [], 'class': [], 'dir': ['ltr', 'rtl'], 'style': [], 'onmousemove': [], 'onmouseout': []}
+\ ],
+\ 'optgroup': [
+\ ['option'],
+\ { 'ondblclick': [], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'onkeypress': [], 'onmousedown': [], 'class': [], 'title': [], 'onclick': [], 'label': [], 'disabled': ['BOOL'], 'dir': ['ltr', 'rtl'], 'onmouseout': [], 'onmousemove': [], 'style': []}
+\ ],
+\ 'option': [
+\ [''],
+\ { 'ondblclick': [], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'value': [], 'onkeypress': [], 'onmousedown': [], 'class': [], 'title': [], 'onclick': [], 'label': [], 'disabled': ['BOOL'], 'dir': ['ltr', 'rtl'], 'onmouseout': [], 'onmousemove': [], 'style': [], 'selected': ['BOOL']}
+\ ],
+\ 'p': [
+\ ['tt', 'i', 'b', 'big', 'small', 'em', 'strong', 'dfn', 'code', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'a', 'img', 'object', 'br', 'script', 'map', 'q', 'sub', 'sup', 'span', 'bdo', 'input', 'select', 'textarea', 'label', 'button'],
+\ { 'ondblclick': [], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'onmousedown': [], 'onkeypress': [], 'onclick': [], 'title': [], 'class': [], 'dir': ['ltr', 'rtl'], 'style': [], 'onmousemove': [], 'onmouseout': []}
+\ ],
+\ 'param': [
+\ [],
+\ { 'id': [], 'value': [], 'name': [], 'type': [], 'valuetype': ['DATA', 'REF', 'OBJECT']}
+\ ],
+\ 'pre': [
+\ ['tt', 'i', 'b', 'em', 'strong', 'dfn', 'code', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'a', 'br', 'script', 'map', 'q', 'span', 'bdo', 'input', 'select', 'textarea', 'label', 'button'],
+\ { 'ondblclick': [], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'onmousedown': [], 'onkeypress': [], 'onclick': [], 'title': [], 'class': [], 'dir': ['ltr', 'rtl'], 'style': [], 'onmousemove': [], 'onmouseout': []}
+\ ],
+\ 'q': [
+\ ['tt', 'i', 'b', 'big', 'small', 'em', 'strong', 'dfn', 'code', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'a', 'img', 'object', 'br', 'script', 'map', 'q', 'sub', 'sup', 'span', 'bdo', 'input', 'select', 'textarea', 'label', 'button'],
+\ { 'ondblclick': [], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'onmousedown': [], 'onkeypress': [], 'onclick': [], 'title': [], 'class': [], 'dir': ['ltr', 'rtl'], 'cite': [], 'style': [], 'onmousemove': [], 'onmouseout': []}
+\ ],
+\ 'samp': [
+\ ['tt', 'i', 'b', 'big', 'small', 'em', 'strong', 'dfn', 'code', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'a', 'img', 'object', 'br', 'script', 'map', 'q', 'sub', 'sup', 'span', 'bdo', 'input', 'select', 'textarea', 'label', 'button'],
+\ { 'ondblclick': [], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'onmousedown': [], 'onkeypress': [], 'onclick': [], 'title': [], 'class': [], 'dir': ['ltr', 'rtl'], 'style': [], 'onmousemove': [], 'onmouseout': []}
+\ ],
+\ 'script': [
+\ [],
+\ { 'src': [], 'for': [], 'charset': [], 'event': [], 'type': [], 'defer': ['BOOL']}
+\ ],
+\ 'select': [
+\ ['optgroup', 'option'],
+\ { 'ondblclick': [], 'onkeydown': [], 'onchange': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'name': [], 'onkeypress': [], 'onmousedown': [], 'class': [], 'title': [], 'onclick': [], 'disabled': ['BOOL'], 'dir': ['ltr', 'rtl'], 'size': [], 'onblur': [], 'onfocus': [], 'tabindex': [], 'onmouseout': [], 'onmousemove': [], 'style': [], 'multiple': ['BOOL']}
+\ ],
+\ 'small': [
+\ ['tt', 'i', 'b', 'big', 'small', 'em', 'strong', 'dfn', 'code', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'a', 'img', 'object', 'br', 'script', 'map', 'q', 'sub', 'sup', 'span', 'bdo', 'input', 'select', 'textarea', 'label', 'button'],
+\ { 'ondblclick': [], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'onmousedown': [], 'onkeypress': [], 'onclick': [], 'title': [], 'class': [], 'dir': ['ltr', 'rtl'], 'style': [], 'onmousemove': [], 'onmouseout': []}
+\ ],
+\ 'span': [
+\ ['tt', 'i', 'b', 'big', 'small', 'em', 'strong', 'dfn', 'code', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'a', 'img', 'object', 'br', 'script', 'map', 'q', 'sub', 'sup', 'span', 'bdo', 'input', 'select', 'textarea', 'label', 'button'],
+\ { 'ondblclick': [], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'onmousedown': [], 'onkeypress': [], 'onclick': [], 'title': [], 'class': [], 'dir': ['ltr', 'rtl'], 'style': [], 'onmousemove': [], 'onmouseout': []}
+\ ],
+\ 'strong': [
+\ ['tt', 'i', 'b', 'big', 'small', 'em', 'strong', 'dfn', 'code', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'a', 'img', 'object', 'br', 'script', 'map', 'q', 'sub', 'sup', 'span', 'bdo', 'input', 'select', 'textarea', 'label', 'button'],
+\ { 'ondblclick': [], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'onmousedown': [], 'onkeypress': [], 'onclick': [], 'title': [], 'class': [], 'dir': ['ltr', 'rtl'], 'style': [], 'onmousemove': [], 'onmouseout': []}
+\ ],
+\ 'style': [
+\ [],
+\ { 'media': [], 'lang': [], 'type': [], 'title': [], 'dir': ['ltr', 'rtl']}
+\ ],
+\ 'sub': [
+\ ['tt', 'i', 'b', 'big', 'small', 'em', 'strong', 'dfn', 'code', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'a', 'img', 'object', 'br', 'script', 'map', 'q', 'sub', 'sup', 'span', 'bdo', 'input', 'select', 'textarea', 'label', 'button'],
+\ { 'ondblclick': [], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'onmousedown': [], 'onkeypress': [], 'onclick': [], 'title': [], 'class': [], 'dir': ['ltr', 'rtl'], 'style': [], 'onmousemove': [], 'onmouseout': []}
+\ ],
+\ 'sup': [
+\ ['tt', 'i', 'b', 'big', 'small', 'em', 'strong', 'dfn', 'code', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'a', 'img', 'object', 'br', 'script', 'map', 'q', 'sub', 'sup', 'span', 'bdo', 'input', 'select', 'textarea', 'label', 'button'],
+\ { 'ondblclick': [], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'onmousedown': [], 'onkeypress': [], 'onclick': [], 'title': [], 'class': [], 'dir': ['ltr', 'rtl'], 'style': [], 'onmousemove': [], 'onmouseout': []}
+\ ],
+\ 'table': [
+\ ['caption', 'col', 'colgroup', 'thead', 'tfoot', 'tbody'],
+\ { 'ondblclick': [], 'onkeydown': [], 'onkeyup': [], 'datapagesize': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'onkeypress': [], 'onmousedown': [], 'class': [], 'title': [], 'onclick': [], 'width': [], 'frame': ['void', 'above', 'below', 'hsides', 'lhs', 'rhs', 'vsides', 'box', 'border'], 'rules': ['none', 'groups', 'rows', 'cols', 'all'], 'dir': ['ltr', 'rtl'], 'summary': [], 'cellspacing': [], 'onmouseout': [], 'onmousemove': [], 'style': [], 'border': [], 'cellpadding': []}
+\ ],
+\ 'tbody': [
+\ ['tr'],
+\ { 'ondblclick': [], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'align': ['left', 'center', 'right', 'justify', 'char'], 'lang': [], 'valign': ['top', 'middle', 'bottom', 'baseline'], 'onkeypress': [], 'onmousedown': [], 'class': [], 'title': [], 'onclick': [], 'dir': ['ltr', 'rtl'], 'charoff': [], 'onmouseout': [], 'onmousemove': [], 'style': [], 'char': []}
+\ ],
+\ 'td': [
+\ ['p', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'ul', 'ol', 'pre', 'dl', 'div', 'noscript', 'blockquote', 'form', 'hr', 'table', 'fieldset', 'address', 'tt', 'i', 'b', 'big', 'small', 'em', 'strong', 'dfn', 'code', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'a', 'img', 'object', 'br', 'script', 'map', 'q', 'sub', 'sup', 'span', 'bdo', 'input', 'select', 'textarea', 'label', 'button'],
+\ { 'ondblclick': [], 'axis': [], 'onkeydown': [], 'abbr': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'scope': ['row', 'col', 'rowgroup', 'colgroup'], 'onmouseover': [], 'lang': [], 'align': ['left', 'center', 'right', 'justify', 'char'], 'valign': ['top', 'middle', 'bottom', 'baseline'], 'onkeypress': [], 'onmousedown': [], 'class': [], 'title': [], 'onclick': [], 'headers': [], 'dir': ['ltr', 'rtl'], 'rowspan': ['1'], 'colspan': ['1'], 'charoff': [], 'onmouseout': [], 'onmousemove': [], 'style': [], 'char': []}
+\ ],
+\ 'textarea': [
+\ [''],
+\ { 'ondblclick': [], 'cols': [], 'onkeydown': [], 'readonly': ['BOOL'], 'onchange': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'name': [], 'onkeypress': [], 'onmousedown': [], 'class': [], 'title': [], 'onclick': [], 'accesskey': [], 'disabled': ['BOOL'], 'rows': [], 'dir': ['ltr', 'rtl'], 'onblur': [], 'onfocus': [], 'onselect': [], 'tabindex': [], 'onmouseout': [], 'onmousemove': [], 'style': []}
+\ ],
+\ 'tfoot': [
+\ ['tr'],
+\ { 'ondblclick': [], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'align': ['left', 'center', 'right', 'justify', 'char'], 'lang': [], 'valign': ['top', 'middle', 'bottom', 'baseline'], 'onkeypress': [], 'onmousedown': [], 'class': [], 'title': [], 'onclick': [], 'dir': ['ltr', 'rtl'], 'charoff': [], 'onmouseout': [], 'onmousemove': [], 'style': [], 'char': []}
+\ ],
+\ 'th': [
+\ ['p', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'ul', 'ol', 'pre', 'dl', 'div', 'noscript', 'blockquote', 'form', 'hr', 'table', 'fieldset', 'address', 'tt', 'i', 'b', 'big', 'small', 'em', 'strong', 'dfn', 'code', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'a', 'img', 'object', 'br', 'script', 'map', 'q', 'sub', 'sup', 'span', 'bdo', 'input', 'select', 'textarea', 'label', 'button'],
+\ { 'ondblclick': [], 'axis': [], 'onkeydown': [], 'abbr': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'scope': ['row', 'col', 'rowgroup', 'colgroup'], 'onmouseover': [], 'lang': [], 'align': ['left', 'center', 'right', 'justify', 'char'], 'valign': ['top', 'middle', 'bottom', 'baseline'], 'onkeypress': [], 'onmousedown': [], 'class': [], 'title': [], 'onclick': [], 'headers': [], 'dir': ['ltr', 'rtl'], 'rowspan': ['1'], 'colspan': ['1'], 'charoff': [], 'onmouseout': [], 'onmousemove': [], 'style': [], 'char': []}
+\ ],
+\ 'thead': [
+\ ['tr'],
+\ { 'ondblclick': [], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'align': ['left', 'center', 'right', 'justify', 'char'], 'lang': [], 'valign': ['top', 'middle', 'bottom', 'baseline'], 'onkeypress': [], 'onmousedown': [], 'class': [], 'title': [], 'onclick': [], 'dir': ['ltr', 'rtl'], 'charoff': [], 'onmouseout': [], 'onmousemove': [], 'style': [], 'char': []}
+\ ],
+\ 'title': [
+\ [''],
+\ { 'lang': [], 'dir': ['ltr', 'rtl']}
+\ ],
+\ 'tr': [
+\ ['th', 'td'],
+\ { 'ondblclick': [], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'align': ['left', 'center', 'right', 'justify', 'char'], 'lang': [], 'valign': ['top', 'middle', 'bottom', 'baseline'], 'onkeypress': [], 'onmousedown': [], 'class': [], 'title': [], 'onclick': [], 'dir': ['ltr', 'rtl'], 'charoff': [], 'onmouseout': [], 'onmousemove': [], 'style': [], 'char': []}
+\ ],
+\ 'tt': [
+\ ['tt', 'i', 'b', 'big', 'small', 'em', 'strong', 'dfn', 'code', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'a', 'img', 'object', 'br', 'script', 'map', 'q', 'sub', 'sup', 'span', 'bdo', 'input', 'select', 'textarea', 'label', 'button'],
+\ { 'ondblclick': [], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'onmousedown': [], 'onkeypress': [], 'onclick': [], 'title': [], 'class': [], 'dir': ['ltr', 'rtl'], 'style': [], 'onmousemove': [], 'onmouseout': []}
+\ ],
+\ 'ul': [
+\ ['li'],
+\ { 'ondblclick': [], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'onmousedown': [], 'onkeypress': [], 'onclick': [], 'title': [], 'class': [], 'dir': ['ltr', 'rtl'], 'style': [], 'onmousemove': [], 'onmouseout': []}
+\ ],
+\ 'var': [
+\ ['tt', 'i', 'b', 'big', 'small', 'em', 'strong', 'dfn', 'code', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'a', 'img', 'object', 'br', 'script', 'map', 'q', 'sub', 'sup', 'span', 'bdo', 'input', 'select', 'textarea', 'label', 'button'],
+\ { 'ondblclick': [], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'onmousedown': [], 'onkeypress': [], 'onclick': [], 'title': [], 'class': [], 'dir': ['ltr', 'rtl'], 'style': [], 'onmousemove': [], 'onmouseout': []}
+\ ],
+\ 'vimxmlattrinfo' : {
+\ 'accept' : ['ContentType', ''],
+\ 'accesskey' : ['Character', ''],
+\ 'action' : ['*URI', ''],
+\ 'align' : ['String', ''],
+\ 'alt' : ['*Text', ''],
+\ 'archive' : ['UriList', ''],
+\ 'axis' : ['CDATA', ''],
+\ 'border' : ['Pixels', ''],
+\ 'cellpadding' : ['Length', ''],
+\ 'cellspacing' : ['Length', ''],
+\ 'char' : ['Character', ''],
+\ 'charoff' : ['Length', ''],
+\ 'charset' : ['LangCode', ''],
+\ 'checked' : ['Bool', ''],
+\ 'class' : ['CDATA', ''],
+\ 'codetype' : ['ContentType', ''],
+\ 'cols' : ['*Number', ''],
+\ 'colspan' : ['Number', ''],
+\ 'content' : ['*CDATA', ''],
+\ 'coords' : ['Coords', ''],
+\ 'data' : ['URI', ''],
+\ 'datetime' : ['DateTime', ''],
+\ 'declare' : ['Bool', ''],
+\ 'defer' : ['Bool', ''],
+\ 'dir' : ['String', ''],
+\ 'disabled' : ['Bool', ''],
+\ 'enctype' : ['ContentType', ''],
+\ 'for' : ['ID', ''],
+\ 'headers' : ['IDREFS', ''],
+\ 'height' : ['Number', ''],
+\ 'href' : ['*URI', ''],
+\ 'hreflang' : ['LangCode', ''],
+\ 'id' : ['ID', ''],
+\ 'ismap' : ['Bool', ''],
+\ 'label' : ['*Text', ''],
+\ 'lang' : ['LangCode', ''],
+\ 'longdesc' : ['URI', ''],
+\ 'maxlength' : ['Number', ''],
+\ 'media' : ['MediaDesc', ''],
+\ 'method' : ['String', ''],
+\ 'multiple' : ['Bool', ''],
+\ 'name' : ['CDATA', ''],
+\ 'nohref' : ['Bool', ''],
+\ 'onblur' : ['Script', ''],
+\ 'onchange' : ['Script', ''],
+\ 'onclick' : ['Script', ''],
+\ 'ondblclick' : ['Script', ''],
+\ 'onfocus' : ['Script', ''],
+\ 'onkeydown' : ['Script', ''],
+\ 'onkeypress' : ['Script', ''],
+\ 'onkeyup' : ['Script', ''],
+\ 'onload' : ['Script', ''],
+\ 'onmousedown' : ['Script', ''],
+\ 'onmousemove' : ['Script', ''],
+\ 'onmouseout' : ['Script', ''],
+\ 'onmouseover' : ['Script', ''],
+\ 'onmouseup' : ['Script', ''],
+\ 'onreset' : ['Script', ''],
+\ 'onselect' : ['Script', ''],
+\ 'onsubmit' : ['Script', ''],
+\ 'onunload' : ['Script', ''],
+\ 'profile' : ['URI', ''],
+\ 'readonly' : ['Bool', ''],
+\ 'rel' : ['LinkTypes', ''],
+\ 'rev' : ['LinkTypes', ''],
+\ 'rows' : ['*Number', ''],
+\ 'rules' : ['String', ''],
+\ 'scheme' : ['CDATA', ''],
+\ 'selected' : ['Bool', ''],
+\ 'shape' : ['Shape', ''],
+\ 'size' : ['CDATA', ''],
+\ 'span' : ['Number', ''],
+\ 'src' : ['*URI', ''],
+\ 'standby' : ['Text', ''],
+\ 'style' : ['StyleSheet', ''],
+\ 'summary' : ['*Text', ''],
+\ 'tabindex' : ['Number', ''],
+\ 'title' : ['Text', ''],
+\ 'type' : ['*ContentType', ''],
+\ 'usemap' : ['URI', ''],
+\ 'valign' : ['String', ''],
+\ 'valuetype' : ['String', ''],
+\ 'width' : ['Number', ''],
+\ 'xmlns' : ['URI', '']
+\ },
+\ 'vimxmltaginfo': {
+\ 'area': ['/>', ''],
+\ 'base': ['/>', ''],
+\ 'br': ['/>', ''],
+\ 'col': ['/>', ''],
+\ 'hr': ['/>', ''],
+\ 'img': ['/>', ''],
+\ 'input': ['/>', ''],
+\ 'link': ['/>', ''],
+\ 'meta': ['/>', ''],
+\ 'param': ['/>', ''],
+\ }
+\ }
+" vim:ft=vim:ff=unix
--- /dev/null
+++ b/lib/vimfiles/autoload/xml/html401t.vim
@@ -1,0 +1,461 @@
+let g:xmldata_html401t = {
+\ 'vimxmlentities': ['AElig', 'Aacute', 'Acirc', 'Agrave', 'Alpha', 'Aring', 'Atilde', 'Auml', 'Beta', 'Ccedil', 'Chi', 'Dagger', 'Delta', 'ETH', 'Eacute', 'Ecirc', 'Egrave', 'Epsilon', 'Eta', 'Euml', 'Gamma', 'Iacute', 'Icirc', 'Igrave', 'Iota', 'Iuml', 'Kappa', 'Lambda', 'Mu', 'Ntilde', 'Nu', 'OElig', 'Oacute', 'Ocirc', 'Ograve', 'Omega', 'Omicron', 'Oslash', 'Otilde', 'Ouml', 'Phi', 'Pi', 'Prime', 'Psi', 'Rho', 'Scaron', 'Sigma', 'THORN', 'Tau', 'Theta', 'Uacute', 'Ucirc', 'Ugrave', 'Upsilon', 'Uuml', 'Xi', 'Yacute', 'Yuml', 'Zeta', 'aacute', 'acirc', 'acute', 'aelig', 'agrave', 'alefsym', 'alpha', 'amp', 'and', 'ang', 'apos', 'aring', 'asymp', 'atilde', 'auml', 'bdquo', 'beta', 'brvbar', 'bull', 'cap', 'ccedil', 'cedil', 'cent', 'chi', 'circ', 'clubs', 'cong', 'copy', 'crarr', 'cup', 'curren', 'dArr', 'dagger', 'darr', 'deg', 'delta', 'diams', 'divide', 'eacute', 'ecirc', 'egrave', 'empty', 'emsp', 'ensp', 'epsilon', 'equiv', 'eta', 'eth', 'euml', 'euro', 'exist', 'fnof', 'forall', 'frac12', 'frac14', 'frac34', 'frasl', 'gamma', 'ge', 'gt', 'hArr', 'harr', 'hearts', 'hellip', 'iacute', 'icirc', 'iexcl', 'igrave', 'image', 'infin', 'int', 'iota', 'iquest', 'isin', 'iuml', 'kappa', 'lArr', 'lambda', 'lang', 'laquo', 'larr', 'lceil', 'ldquo', 'le', 'lfloor', 'lowast', 'loz', 'lrm', 'lsaquo', 'lsquo', 'lt', 'macr', 'mdash', 'micro', 'middot', 'minus', 'mu', 'nabla', 'nbsp', 'ndash', 'ne', 'ni', 'not', 'notin', 'nsub', 'ntilde', 'nu', 'oacute', 'ocirc', 'oelig', 'ograve', 'oline', 'omega', 'omicron', 'oplus', 'or', 'ordf', 'ordm', 'oslash', 'otilde', 'otimes', 'ouml', 'para', 'part', 'permil', 'perp', 'phi', 'pi', 'piv', 'plusmn', 'pound', 'prime', 'prod', 'prop', 'psi', 'quot', 'rArr', 'radic', 'rang', 'raquo', 'rarr', 'rceil', 'rdquo', 'real', 'reg', 'rfloor', 'rho', 'rlm', 'rsaquo', 'rsquo', 'sbquo', 'scaron', 'sdot', 'sect', 'shy', 'sigma', 'sigmaf', 'sim', 'spades', 'sub', 'sube', 'sum', 'sup', 'sup1', 'sup2', 'sup3', 'supe', 'szlig', 'tau', 'there4', 'theta', 'thetasym', 'thinsp', 'thorn', 'tilde', 'times', 'trade', 'uArr', 'uacute', 'uarr', 'ucirc', 'ugrave', 'uml', 'upsih', 'upsilon', 'uuml', 'weierp', 'xi', 'yacute', 'yen', 'yuml', 'zeta', 'zwj', 'zwnj'],
+\ 'vimxmlroot': ['html'],
+\ 'a': [
+\ ['tt', 'i', 'b', 'u', 's', 'strike', 'big', 'small', 'em', 'strong', 'dfn', 'code', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'img', 'applet', 'object', 'font', 'basefont', 'br', 'script', 'map', 'q', 'sub', 'sup', 'span', 'bdo', 'iframe', 'input', 'select', 'textarea', 'label', 'button'],
+\ { 'rel': [], 'accesskey': [], 'coords': [], 'ondblclick': [], 'dir': ['ltr', 'rtl'], 'onblur': [], 'onkeydown': [], 'onfocus': [], 'target': [], 'onkeyup': [], 'href': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'tabindex': [], 'lang': [], 'onmouseout': [], 'onmousemove': [], 'style': [], 'name': [], 'charset': [], 'hreflang': [], 'onkeypress': [], 'onmousedown': [], 'rev': [], 'class': [], 'title': [], 'onclick': [], 'type': [], 'shape': ['rect', 'circle', 'poly', 'default']}
+\ ],
+\ 'abbr': [
+\ ['tt', 'i', 'b', 'u', 's', 'strike', 'big', 'small', 'em', 'strong', 'dfn', 'code', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'a', 'img', 'applet', 'object', 'font', 'basefont', 'br', 'script', 'map', 'q', 'sub', 'sup', 'span', 'bdo', 'iframe', 'input', 'select', 'textarea', 'label', 'button'],
+\ { 'ondblclick': [], 'dir': ['ltr', 'rtl'], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'style': [], 'onmousemove': [], 'onmouseout': [], 'onmousedown': [], 'onkeypress': [], 'onclick': [], 'title': [], 'class': []}
+\ ],
+\ 'acronym': [
+\ ['tt', 'i', 'b', 'u', 's', 'strike', 'big', 'small', 'em', 'strong', 'dfn', 'code', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'a', 'img', 'applet', 'object', 'font', 'basefont', 'br', 'script', 'map', 'q', 'sub', 'sup', 'span', 'bdo', 'iframe', 'input', 'select', 'textarea', 'label', 'button'],
+\ { 'ondblclick': [], 'dir': ['ltr', 'rtl'], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'style': [], 'onmousemove': [], 'onmouseout': [], 'onmousedown': [], 'onkeypress': [], 'onclick': [], 'title': [], 'class': []}
+\ ],
+\ 'address': [
+\ ['tt', 'i', 'b', 'u', 's', 'strike', 'big', 'small', 'em', 'strong', 'dfn', 'code', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'a', 'img', 'applet', 'object', 'font', 'basefont', 'br', 'script', 'map', 'q', 'sub', 'sup', 'span', 'bdo', 'iframe', 'input', 'select', 'textarea', 'label', 'button', 'p'],
+\ { 'ondblclick': [], 'dir': ['ltr', 'rtl'], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'style': [], 'onmousemove': [], 'onmouseout': [], 'onmousedown': [], 'onkeypress': [], 'onclick': [], 'title': [], 'class': []}
+\ ],
+\ 'applet': [
+\ ['param', 'p', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'ul', 'ol', 'dir', 'menu', 'pre', 'dl', 'div', 'center', 'noscript', 'noframes', 'blockquote', 'form', 'isindex', 'hr', 'table', 'fieldset', 'address', 'tt', 'i', 'b', 'u', 's', 'strike', 'big', 'small', 'em', 'strong', 'dfn', 'code', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'a', 'img', 'applet', 'object', 'font', 'basefont', 'br', 'script', 'map', 'q', 'sub', 'sup', 'span', 'bdo', 'iframe', 'input', 'select', 'textarea', 'label', 'button'],
+\ { 'width': [], 'object': [], 'id': [], 'code': [], 'vspace': [], 'archive': [], 'alt': [], 'align': ['top', 'middle', 'bottom', 'left', 'right'], 'style': [], 'name': [], 'height': [], 'hspace': [], 'title': [], 'class': [], 'codebase': []}
+\ ],
+\ 'area': [
+\ [],
+\ { 'accesskey': [], 'coords': [], 'ondblclick': [], 'dir': ['ltr', 'rtl'], 'onblur': [], 'onkeydown': [], 'target': [], 'nohref': ['BOOL'], 'onfocus': [], 'onkeyup': [], 'href': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'alt': [], 'tabindex': [], 'onmouseout': [], 'onmousemove': [], 'style': [], 'onkeypress': [], 'onmousedown': [], 'shape': ['rect', 'circle', 'poly', 'default'], 'class': [], 'title': [], 'onclick': []}
+\ ],
+\ 'b': [
+\ ['tt', 'i', 'b', 'u', 's', 'strike', 'big', 'small', 'em', 'strong', 'dfn', 'code', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'a', 'img', 'applet', 'object', 'font', 'basefont', 'br', 'script', 'map', 'q', 'sub', 'sup', 'span', 'bdo', 'iframe', 'input', 'select', 'textarea', 'label', 'button'],
+\ { 'ondblclick': [], 'dir': ['ltr', 'rtl'], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'style': [], 'onmousemove': [], 'onmouseout': [], 'onmousedown': [], 'onkeypress': [], 'onclick': [], 'title': [], 'class': []}
+\ ],
+\ 'base': [
+\ [],
+\ { 'target': [], 'href': []}
+\ ],
+\ 'basefont': [
+\ [],
+\ { 'size': [], 'face': [], 'color': [], 'id': []}
+\ ],
+\ 'bdo': [
+\ ['tt', 'i', 'b', 'u', 's', 'strike', 'big', 'small', 'em', 'strong', 'dfn', 'code', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'a', 'img', 'applet', 'object', 'font', 'basefont', 'br', 'script', 'map', 'q', 'sub', 'sup', 'span', 'bdo', 'iframe', 'input', 'select', 'textarea', 'label', 'button'],
+\ { 'dir': ['ltr', 'rtl'], 'id': [], 'lang': [], 'style': [], 'class': [], 'title': []}
+\ ],
+\ 'big': [
+\ ['tt', 'i', 'b', 'u', 's', 'strike', 'big', 'small', 'em', 'strong', 'dfn', 'code', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'a', 'img', 'applet', 'object', 'font', 'basefont', 'br', 'script', 'map', 'q', 'sub', 'sup', 'span', 'bdo', 'iframe', 'input', 'select', 'textarea', 'label', 'button'],
+\ { 'ondblclick': [], 'dir': ['ltr', 'rtl'], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'style': [], 'onmousemove': [], 'onmouseout': [], 'onmousedown': [], 'onkeypress': [], 'onclick': [], 'title': [], 'class': []}
+\ ],
+\ 'blockquote': [
+\ ['p', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'ul', 'ol', 'dir', 'menu', 'pre', 'dl', 'div', 'center', 'noscript', 'noframes', 'blockquote', 'form', 'isindex', 'hr', 'table', 'fieldset', 'address', 'tt', 'i', 'b', 'u', 's', 'strike', 'big', 'small', 'em', 'strong', 'dfn', 'code', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'a', 'img', 'applet', 'object', 'font', 'basefont', 'br', 'script', 'map', 'q', 'sub', 'sup', 'span', 'bdo', 'iframe', 'input', 'select', 'textarea', 'label', 'button'],
+\ { 'ondblclick': [], 'dir': ['ltr', 'rtl'], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'cite': [], 'onmouseover': [], 'lang': [], 'style': [], 'onmousemove': [], 'onmouseout': [], 'onmousedown': [], 'onkeypress': [], 'onclick': [], 'title': [], 'class': []}
+\ ],
+\ 'body': [
+\ ['p', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'ul', 'ol', 'dir', 'menu', 'pre', 'dl', 'div', 'center', 'noscript', 'noframes', 'blockquote', 'form', 'isindex', 'hr', 'table', 'fieldset', 'address', 'tt', 'i', 'b', 'u', 's', 'strike', 'big', 'small', 'em', 'strong', 'dfn', 'code', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'a', 'img', 'applet', 'object', 'font', 'basefont', 'br', 'script', 'map', 'q', 'sub', 'sup', 'span', 'bdo', 'iframe', 'input', 'select', 'textarea', 'label', 'button', 'ins', 'del'],
+\ { 'vlink': [], 'ondblclick': [], 'dir': ['ltr', 'rtl'], 'onkeydown': [], 'alink': [], 'onkeyup': [], 'bgcolor': [], 'text': [], 'onmouseup': [], 'id': [], 'link': [], 'onmouseover': [], 'lang': [], 'onmouseout': [], 'onmousemove': [], 'style': [], 'background': [], 'onunload': [], 'onkeypress': [], 'onmousedown': [], 'onload': [], 'class': [], 'title': [], 'onclick': []}
+\ ],
+\ 'br': [
+\ [],
+\ { 'clear': ['none', 'left', 'all', 'right', 'none'], 'id': [], 'style': [], 'class': [], 'title': []}
+\ ],
+\ 'button': [
+\ ['p', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'ul', 'ol', 'dir', 'menu', 'pre', 'dl', 'div', 'center', 'noscript', 'noframes', 'blockquote', 'hr', 'table', 'address', 'tt', 'i', 'b', 'u', 's', 'strike', 'big', 'small', 'em', 'strong', 'dfn', 'code', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'img', 'applet', 'object', 'font', 'basefont', 'br', 'script', 'map', 'q', 'sub', 'sup', 'span', 'bdo'],
+\ { 'accesskey': [], 'disabled': ['BOOL'], 'ondblclick': [], 'dir': ['ltr', 'rtl'], 'onblur': [], 'onkeydown': [], 'onfocus': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'tabindex': [], 'value': [], 'name': [], 'onmouseout': [], 'onmousemove': [], 'style': [], 'onkeypress': [], 'onmousedown': [], 'class': [], 'title': [], 'onclick': [], 'type': ['submit', 'button', 'submit', 'reset']}
+\ ],
+\ 'caption': [
+\ ['tt', 'i', 'b', 'u', 's', 'strike', 'big', 'small', 'em', 'strong', 'dfn', 'code', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'a', 'img', 'applet', 'object', 'font', 'basefont', 'br', 'script', 'map', 'q', 'sub', 'sup', 'span', 'bdo', 'iframe', 'input', 'select', 'textarea', 'label', 'button'],
+\ { 'ondblclick': [], 'dir': ['ltr', 'rtl'], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'align': ['top', 'bottom', 'left', 'right'], 'lang': [], 'onmouseout': [], 'onmousemove': [], 'style': [], 'onkeypress': [], 'onmousedown': [], 'class': [], 'title': [], 'onclick': []}
+\ ],
+\ 'center': [
+\ ['p', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'ul', 'ol', 'dir', 'menu', 'pre', 'dl', 'div', 'center', 'noscript', 'noframes', 'blockquote', 'form', 'isindex', 'hr', 'table', 'fieldset', 'address', 'tt', 'i', 'b', 'u', 's', 'strike', 'big', 'small', 'em', 'strong', 'dfn', 'code', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'a', 'img', 'applet', 'object', 'font', 'basefont', 'br', 'script', 'map', 'q', 'sub', 'sup', 'span', 'bdo', 'iframe', 'input', 'select', 'textarea', 'label', 'button'],
+\ { 'ondblclick': [], 'dir': ['ltr', 'rtl'], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'style': [], 'onmousemove': [], 'onmouseout': [], 'onmousedown': [], 'onkeypress': [], 'onclick': [], 'title': [], 'class': []}
+\ ],
+\ 'cite': [
+\ ['tt', 'i', 'b', 'u', 's', 'strike', 'big', 'small', 'em', 'strong', 'dfn', 'code', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'a', 'img', 'applet', 'object', 'font', 'basefont', 'br', 'script', 'map', 'q', 'sub', 'sup', 'span', 'bdo', 'iframe', 'input', 'select', 'textarea', 'label', 'button'],
+\ { 'ondblclick': [], 'dir': ['ltr', 'rtl'], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'style': [], 'onmousemove': [], 'onmouseout': [], 'onmousedown': [], 'onkeypress': [], 'onclick': [], 'title': [], 'class': []}
+\ ],
+\ 'code': [
+\ ['tt', 'i', 'b', 'u', 's', 'strike', 'big', 'small', 'em', 'strong', 'dfn', 'code', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'a', 'img', 'applet', 'object', 'font', 'basefont', 'br', 'script', 'map', 'q', 'sub', 'sup', 'span', 'bdo', 'iframe', 'input', 'select', 'textarea', 'label', 'button'],
+\ { 'ondblclick': [], 'dir': ['ltr', 'rtl'], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'style': [], 'onmousemove': [], 'onmouseout': [], 'onmousedown': [], 'onkeypress': [], 'onclick': [], 'title': [], 'class': []}
+\ ],
+\ 'col': [
+\ [],
+\ { 'width': [], 'ondblclick': [], 'dir': ['ltr', 'rtl'], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'charoff': [], 'onmouseover': [], 'lang': [], 'align': ['left', 'center', 'right', 'justify', 'char'], 'valign': ['top', 'middle', 'bottom', 'baseline'], 'onmouseout': [], 'onmousemove': [], 'style': [], 'onkeypress': [], 'onmousedown': [], 'char': [], 'span': ['1'], 'class': [], 'title': [], 'onclick': []}
+\ ],
+\ 'colgroup': [
+\ ['col'],
+\ { 'width': [], 'ondblclick': [], 'dir': ['ltr', 'rtl'], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'charoff': [], 'onmouseover': [], 'lang': [], 'align': ['left', 'center', 'right', 'justify', 'char'], 'valign': ['top', 'middle', 'bottom', 'baseline'], 'onmouseout': [], 'onmousemove': [], 'style': [], 'onkeypress': [], 'onmousedown': [], 'char': [], 'span': ['1'], 'class': [], 'title': [], 'onclick': []}
+\ ],
+\ 'dd': [
+\ ['p', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'ul', 'ol', 'dir', 'menu', 'pre', 'dl', 'div', 'center', 'noscript', 'noframes', 'blockquote', 'form', 'isindex', 'hr', 'table', 'fieldset', 'address', 'tt', 'i', 'b', 'u', 's', 'strike', 'big', 'small', 'em', 'strong', 'dfn', 'code', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'a', 'img', 'applet', 'object', 'font', 'basefont', 'br', 'script', 'map', 'q', 'sub', 'sup', 'span', 'bdo', 'iframe', 'input', 'select', 'textarea', 'label', 'button'],
+\ { 'ondblclick': [], 'dir': ['ltr', 'rtl'], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'style': [], 'onmousemove': [], 'onmouseout': [], 'onmousedown': [], 'onkeypress': [], 'onclick': [], 'title': [], 'class': []}
+\ ],
+\ 'del': [
+\ ['p', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'ul', 'ol', 'dir', 'menu', 'pre', 'dl', 'div', 'center', 'noscript', 'noframes', 'blockquote', 'form', 'isindex', 'hr', 'table', 'fieldset', 'address', 'tt', 'i', 'b', 'u', 's', 'strike', 'big', 'small', 'em', 'strong', 'dfn', 'code', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'a', 'img', 'applet', 'object', 'font', 'basefont', 'br', 'script', 'map', 'q', 'sub', 'sup', 'span', 'bdo', 'iframe', 'input', 'select', 'textarea', 'label', 'button'],
+\ { 'ondblclick': [], 'dir': ['ltr', 'rtl'], 'datetime': [], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'cite': [], 'onmouseover': [], 'lang': [], 'onmouseout': [], 'onmousemove': [], 'style': [], 'onkeypress': [], 'onmousedown': [], 'class': [], 'title': [], 'onclick': []}
+\ ],
+\ 'dfn': [
+\ ['tt', 'i', 'b', 'u', 's', 'strike', 'big', 'small', 'em', 'strong', 'dfn', 'code', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'a', 'img', 'applet', 'object', 'font', 'basefont', 'br', 'script', 'map', 'q', 'sub', 'sup', 'span', 'bdo', 'iframe', 'input', 'select', 'textarea', 'label', 'button'],
+\ { 'ondblclick': [], 'dir': ['ltr', 'rtl'], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'style': [], 'onmousemove': [], 'onmouseout': [], 'onmousedown': [], 'onkeypress': [], 'onclick': [], 'title': [], 'class': []}
+\ ],
+\ 'dir': [
+\ ['li'],
+\ { 'ondblclick': [], 'dir': ['ltr', 'rtl'], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'compact': ['BOOL'], 'onmouseover': [], 'lang': [], 'style': [], 'onmousemove': [], 'onmouseout': [], 'onmousedown': [], 'onkeypress': [], 'onclick': [], 'title': [], 'class': []}
+\ ],
+\ 'div': [
+\ ['p', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'ul', 'ol', 'dir', 'menu', 'pre', 'dl', 'div', 'center', 'noscript', 'noframes', 'blockquote', 'form', 'isindex', 'hr', 'table', 'fieldset', 'address', 'tt', 'i', 'b', 'u', 's', 'strike', 'big', 'small', 'em', 'strong', 'dfn', 'code', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'a', 'img', 'applet', 'object', 'font', 'basefont', 'br', 'script', 'map', 'q', 'sub', 'sup', 'span', 'bdo', 'iframe', 'input', 'select', 'textarea', 'label', 'button'],
+\ { 'ondblclick': [], 'dir': ['ltr', 'rtl'], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'align': ['left', 'center', 'right', 'justify'], 'lang': [], 'onmouseout': [], 'onmousemove': [], 'style': [], 'onkeypress': [], 'onmousedown': [], 'class': [], 'title': [], 'onclick': []}
+\ ],
+\ 'dl': [
+\ ['dt', 'dd'],
+\ { 'ondblclick': [], 'dir': ['ltr', 'rtl'], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'compact': ['BOOL'], 'onmouseover': [], 'lang': [], 'style': [], 'onmousemove': [], 'onmouseout': [], 'onmousedown': [], 'onkeypress': [], 'onclick': [], 'title': [], 'class': []}
+\ ],
+\ 'dt': [
+\ ['tt', 'i', 'b', 'u', 's', 'strike', 'big', 'small', 'em', 'strong', 'dfn', 'code', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'a', 'img', 'applet', 'object', 'font', 'basefont', 'br', 'script', 'map', 'q', 'sub', 'sup', 'span', 'bdo', 'iframe', 'input', 'select', 'textarea', 'label', 'button'],
+\ { 'ondblclick': [], 'dir': ['ltr', 'rtl'], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'style': [], 'onmousemove': [], 'onmouseout': [], 'onmousedown': [], 'onkeypress': [], 'onclick': [], 'title': [], 'class': []}
+\ ],
+\ 'em': [
+\ ['tt', 'i', 'b', 'u', 's', 'strike', 'big', 'small', 'em', 'strong', 'dfn', 'code', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'a', 'img', 'applet', 'object', 'font', 'basefont', 'br', 'script', 'map', 'q', 'sub', 'sup', 'span', 'bdo', 'iframe', 'input', 'select', 'textarea', 'label', 'button'],
+\ { 'ondblclick': [], 'dir': ['ltr', 'rtl'], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'style': [], 'onmousemove': [], 'onmouseout': [], 'onmousedown': [], 'onkeypress': [], 'onclick': [], 'title': [], 'class': []}
+\ ],
+\ 'fieldset': [
+\ ['legend', 'p', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'ul', 'ol', 'dir', 'menu', 'pre', 'dl', 'div', 'center', 'noscript', 'noframes', 'blockquote', 'form', 'isindex', 'hr', 'table', 'fieldset', 'address', 'tt', 'i', 'b', 'u', 's', 'strike', 'big', 'small', 'em', 'strong', 'dfn', 'code', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'a', 'img', 'applet', 'object', 'font', 'basefont', 'br', 'script', 'map', 'q', 'sub', 'sup', 'span', 'bdo', 'iframe', 'input', 'select', 'textarea', 'label', 'button'],
+\ { 'ondblclick': [], 'dir': ['ltr', 'rtl'], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'style': [], 'onmousemove': [], 'onmouseout': [], 'onmousedown': [], 'onkeypress': [], 'onclick': [], 'title': [], 'class': []}
+\ ],
+\ 'font': [
+\ ['tt', 'i', 'b', 'u', 's', 'strike', 'big', 'small', 'em', 'strong', 'dfn', 'code', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'a', 'img', 'applet', 'object', 'font', 'basefont', 'br', 'script', 'map', 'q', 'sub', 'sup', 'span', 'bdo', 'iframe', 'input', 'select', 'textarea', 'label', 'button'],
+\ { 'dir': ['ltr', 'rtl'], 'size': [], 'face': [], 'color': [], 'id': [], 'lang': [], 'style': [], 'class': [], 'title': []}
+\ ],
+\ 'form': [
+\ ['p', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'ul', 'ol', 'dir', 'menu', 'pre', 'dl', 'div', 'center', 'noscript', 'noframes', 'blockquote', 'isindex', 'hr', 'table', 'fieldset', 'address', 'tt', 'i', 'b', 'u', 's', 'strike', 'big', 'small', 'em', 'strong', 'dfn', 'code', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'a', 'img', 'applet', 'object', 'font', 'basefont', 'br', 'script', 'map', 'q', 'sub', 'sup', 'span', 'bdo', 'iframe', 'input', 'select', 'textarea', 'label', 'button'],
+\ { 'enctype': ['application/x-www-form-urlencoded'], 'onsubmit': [], 'ondblclick': [], 'dir': ['ltr', 'rtl'], 'onkeydown': [], 'target': [], 'onkeyup': [], 'onmouseup': [], 'onreset': [], 'id': [], 'method': ['GET', 'POST'], 'onmouseover': [], 'lang': [], 'accept': [], 'onmouseout': [], 'onmousemove': [], 'style': [], 'name': [], 'accept-charset': [], 'onkeypress': [], 'onmousedown': [], 'action': [], 'class': [], 'title': [], 'onclick': []}
+\ ],
+\ 'h1': [
+\ ['tt', 'i', 'b', 'u', 's', 'strike', 'big', 'small', 'em', 'strong', 'dfn', 'code', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'a', 'img', 'applet', 'object', 'font', 'basefont', 'br', 'script', 'map', 'q', 'sub', 'sup', 'span', 'bdo', 'iframe', 'input', 'select', 'textarea', 'label', 'button'],
+\ { 'ondblclick': [], 'dir': ['ltr', 'rtl'], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'align': ['left', 'center', 'right', 'justify'], 'lang': [], 'onmouseout': [], 'onmousemove': [], 'style': [], 'onkeypress': [], 'onmousedown': [], 'class': [], 'title': [], 'onclick': []}
+\ ],
+\ 'h2': [
+\ ['tt', 'i', 'b', 'u', 's', 'strike', 'big', 'small', 'em', 'strong', 'dfn', 'code', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'a', 'img', 'applet', 'object', 'font', 'basefont', 'br', 'script', 'map', 'q', 'sub', 'sup', 'span', 'bdo', 'iframe', 'input', 'select', 'textarea', 'label', 'button'],
+\ { 'ondblclick': [], 'dir': ['ltr', 'rtl'], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'align': ['left', 'center', 'right', 'justify'], 'lang': [], 'onmouseout': [], 'onmousemove': [], 'style': [], 'onkeypress': [], 'onmousedown': [], 'class': [], 'title': [], 'onclick': []}
+\ ],
+\ 'h3': [
+\ ['tt', 'i', 'b', 'u', 's', 'strike', 'big', 'small', 'em', 'strong', 'dfn', 'code', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'a', 'img', 'applet', 'object', 'font', 'basefont', 'br', 'script', 'map', 'q', 'sub', 'sup', 'span', 'bdo', 'iframe', 'input', 'select', 'textarea', 'label', 'button'],
+\ { 'ondblclick': [], 'dir': ['ltr', 'rtl'], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'align': ['left', 'center', 'right', 'justify'], 'lang': [], 'onmouseout': [], 'onmousemove': [], 'style': [], 'onkeypress': [], 'onmousedown': [], 'class': [], 'title': [], 'onclick': []}
+\ ],
+\ 'h4': [
+\ ['tt', 'i', 'b', 'u', 's', 'strike', 'big', 'small', 'em', 'strong', 'dfn', 'code', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'a', 'img', 'applet', 'object', 'font', 'basefont', 'br', 'script', 'map', 'q', 'sub', 'sup', 'span', 'bdo', 'iframe', 'input', 'select', 'textarea', 'label', 'button'],
+\ { 'ondblclick': [], 'dir': ['ltr', 'rtl'], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'align': ['left', 'center', 'right', 'justify'], 'lang': [], 'onmouseout': [], 'onmousemove': [], 'style': [], 'onkeypress': [], 'onmousedown': [], 'class': [], 'title': [], 'onclick': []}
+\ ],
+\ 'h5': [
+\ ['tt', 'i', 'b', 'u', 's', 'strike', 'big', 'small', 'em', 'strong', 'dfn', 'code', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'a', 'img', 'applet', 'object', 'font', 'basefont', 'br', 'script', 'map', 'q', 'sub', 'sup', 'span', 'bdo', 'iframe', 'input', 'select', 'textarea', 'label', 'button'],
+\ { 'ondblclick': [], 'dir': ['ltr', 'rtl'], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'align': ['left', 'center', 'right', 'justify'], 'lang': [], 'onmouseout': [], 'onmousemove': [], 'style': [], 'onkeypress': [], 'onmousedown': [], 'class': [], 'title': [], 'onclick': []}
+\ ],
+\ 'h6': [
+\ ['tt', 'i', 'b', 'u', 's', 'strike', 'big', 'small', 'em', 'strong', 'dfn', 'code', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'a', 'img', 'applet', 'object', 'font', 'basefont', 'br', 'script', 'map', 'q', 'sub', 'sup', 'span', 'bdo', 'iframe', 'input', 'select', 'textarea', 'label', 'button'],
+\ { 'ondblclick': [], 'dir': ['ltr', 'rtl'], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'align': ['left', 'center', 'right', 'justify'], 'lang': [], 'onmouseout': [], 'onmousemove': [], 'style': [], 'onkeypress': [], 'onmousedown': [], 'class': [], 'title': [], 'onclick': []}
+\ ],
+\ 'head': [
+\ ['title', 'isindex', 'base', 'script', 'style', 'meta', 'link', 'object'],
+\ { 'profile': [], 'dir': ['ltr', 'rtl'], 'lang': []}
+\ ],
+\ 'hr': [
+\ [],
+\ { 'width': [], 'ondblclick': [], 'dir': ['ltr', 'rtl'], 'size': [], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'align': ['left', 'center', 'right'], 'lang': [], 'onmouseout': [], 'onmousemove': [], 'style': [], 'noshade': ['BOOL'], 'onkeypress': [], 'onmousedown': [], 'class': [], 'title': [], 'onclick': []}
+\ ],
+\ 'html': [
+\ ['head', 'body'],
+\ { 'dir': ['ltr', 'rtl'], 'lang': [], 'version': ['-//W3C//DTD HTML 4.01 Transitional//EN']}
+\ ],
+\ 'i': [
+\ ['tt', 'i', 'b', 'u', 's', 'strike', 'big', 'small', 'em', 'strong', 'dfn', 'code', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'a', 'img', 'applet', 'object', 'font', 'basefont', 'br', 'script', 'map', 'q', 'sub', 'sup', 'span', 'bdo', 'iframe', 'input', 'select', 'textarea', 'label', 'button'],
+\ { 'ondblclick': [], 'dir': ['ltr', 'rtl'], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'style': [], 'onmousemove': [], 'onmouseout': [], 'onmousedown': [], 'onkeypress': [], 'onclick': [], 'title': [], 'class': []}
+\ ],
+\ 'iframe': [
+\ ['p', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'ul', 'ol', 'dir', 'menu', 'pre', 'dl', 'div', 'center', 'noscript', 'noframes', 'blockquote', 'form', 'isindex', 'hr', 'table', 'fieldset', 'address', 'tt', 'i', 'b', 'u', 's', 'strike', 'big', 'small', 'em', 'strong', 'dfn', 'code', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'a', 'img', 'applet', 'object', 'font', 'basefont', 'br', 'script', 'map', 'q', 'sub', 'sup', 'span', 'bdo', 'iframe', 'input', 'select', 'textarea', 'label', 'button'],
+\ { 'width': [], 'scrolling': ['auto', 'yes', 'no', 'auto'], 'marginwidth': [], 'id': [], 'marginheight': [], 'align': ['top', 'middle', 'bottom', 'left', 'right'], 'longdesc': [], 'src': [], 'style': [], 'name': [], 'height': [], 'frameborder': ['1', '0'], 'title': [], 'class': []}
+\ ],
+\ 'img': [
+\ [],
+\ { 'width': [], 'usemap': [], 'ismap': ['BOOL'], 'ondblclick': [], 'dir': ['ltr', 'rtl'], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'vspace': [], 'onmouseover': [], 'alt': [], 'lang': [], 'align': ['top', 'middle', 'bottom', 'left', 'right'], 'src': [], 'longdesc': [], 'onmouseout': [], 'onmousemove': [], 'style': [], 'name': [], 'height': [], 'border': [], 'hspace': [], 'onkeypress': [], 'onmousedown': [], 'class': [], 'title': [], 'onclick': []}
+\ ],
+\ 'input': [
+\ [],
+\ { 'ondblclick': [], 'onkeydown': [], 'readonly': ['BOOL'], 'onchange': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'align': ['top', 'middle', 'bottom', 'left', 'right'], 'value': [], 'src': [], 'name': [], 'checked': ['BOOL'], 'onkeypress': [], 'onmousedown': [], 'type': ['TEXT', 'PASSWORD', 'CHECKBOX', 'RADIO', 'SUBMIT', 'RESET', 'FILE', 'IMAGE', 'BUTTON'], 'class': [], 'title': [], 'onclick': [], 'accesskey': [], 'disabled': ['BOOL'], 'usemap': [], 'ismap': ['BOOL'], 'dir': ['ltr', 'rtl'], 'size': [], 'onblur': [], 'onfocus': [], 'maxlength': [], 'onselect': [], 'tabindex': [], 'accept': [], 'alt': [], 'style': [], 'onmousemove': [], 'onmouseout': []}
+\ ],
+\ 'ins': [
+\ ['p', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'ul', 'ol', 'dir', 'menu', 'pre', 'dl', 'div', 'center', 'noscript', 'noframes', 'blockquote', 'form', 'isindex', 'hr', 'table', 'fieldset', 'address', 'tt', 'i', 'b', 'u', 's', 'strike', 'big', 'small', 'em', 'strong', 'dfn', 'code', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'a', 'img', 'applet', 'object', 'font', 'basefont', 'br', 'script', 'map', 'q', 'sub', 'sup', 'span', 'bdo', 'iframe', 'input', 'select', 'textarea', 'label', 'button'],
+\ { 'ondblclick': [], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'onkeypress': [], 'onmousedown': [], 'class': [], 'title': [], 'onclick': [], 'dir': ['ltr', 'rtl'], 'datetime': [], 'cite': [], 'onmouseout': [], 'onmousemove': [], 'style': []}
+\ ],
+\ 'isindex': [
+\ [],
+\ { 'id': [], 'lang': [], 'prompt': [], 'class': [], 'title': [], 'dir': ['ltr', 'rtl'], 'style': []}
+\ ],
+\ 'kbd': [
+\ ['tt', 'i', 'b', 'u', 's', 'strike', 'big', 'small', 'em', 'strong', 'dfn', 'code', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'a', 'img', 'applet', 'object', 'font', 'basefont', 'br', 'script', 'map', 'q', 'sub', 'sup', 'span', 'bdo', 'iframe', 'input', 'select', 'textarea', 'label', 'button'],
+\ { 'ondblclick': [], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'onmousedown': [], 'onkeypress': [], 'onclick': [], 'title': [], 'class': [], 'dir': ['ltr', 'rtl'], 'style': [], 'onmousemove': [], 'onmouseout': []}
+\ ],
+\ 'label': [
+\ ['tt', 'i', 'b', 'u', 's', 'strike', 'big', 'small', 'em', 'strong', 'dfn', 'code', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'a', 'img', 'applet', 'object', 'font', 'basefont', 'br', 'script', 'map', 'q', 'sub', 'sup', 'span', 'bdo', 'iframe', 'input', 'select', 'textarea', 'button'],
+\ { 'ondblclick': [], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'for': [], 'onkeypress': [], 'onmousedown': [], 'class': [], 'title': [], 'onclick': [], 'accesskey': [], 'dir': ['ltr', 'rtl'], 'onblur': [], 'onfocus': [], 'onmouseout': [], 'onmousemove': [], 'style': []}
+\ ],
+\ 'legend': [
+\ ['tt', 'i', 'b', 'u', 's', 'strike', 'big', 'small', 'em', 'strong', 'dfn', 'code', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'a', 'img', 'applet', 'object', 'font', 'basefont', 'br', 'script', 'map', 'q', 'sub', 'sup', 'span', 'bdo', 'iframe', 'input', 'select', 'textarea', 'label', 'button'],
+\ { 'ondblclick': [], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'align': ['top', 'bottom', 'left', 'right'], 'lang': [], 'onkeypress': [], 'onmousedown': [], 'class': [], 'title': [], 'onclick': [], 'accesskey': [], 'dir': ['ltr', 'rtl'], 'onmouseout': [], 'onmousemove': [], 'style': []}
+\ ],
+\ 'li': [
+\ ['p', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'ul', 'ol', 'dir', 'menu', 'pre', 'dl', 'div', 'center', 'noscript', 'noframes', 'blockquote', 'form', 'isindex', 'hr', 'table', 'fieldset', 'address', 'tt', 'i', 'b', 'u', 's', 'strike', 'big', 'small', 'em', 'strong', 'dfn', 'code', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'a', 'img', 'applet', 'object', 'font', 'basefont', 'br', 'script', 'map', 'q', 'sub', 'sup', 'span', 'bdo', 'iframe', 'input', 'select', 'textarea', 'label', 'button'],
+\ { 'ondblclick': [], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'value': [], 'onkeypress': [], 'onmousedown': [], 'type': [], 'class': [], 'title': [], 'onclick': [], 'dir': ['ltr', 'rtl'], 'onmouseout': [], 'onmousemove': [], 'style': []}
+\ ],
+\ 'link': [
+\ [],
+\ { 'rel': [], 'ondblclick': [], 'onkeydown': [], 'target': [], 'onkeyup': [], 'href': [], 'media': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'charset': [], 'hreflang': [], 'onkeypress': [], 'onmousedown': [], 'rev': [], 'class': [], 'title': [], 'onclick': [], 'type': [], 'dir': ['ltr', 'rtl'], 'onmouseout': [], 'onmousemove': [], 'style': []}
+\ ],
+\ 'map': [
+\ ['p', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'ul', 'ol', 'dir', 'menu', 'pre', 'dl', 'div', 'center', 'noscript', 'noframes', 'blockquote', 'form', 'isindex', 'hr', 'table', 'fieldset', 'address', 'area'],
+\ { 'ondblclick': [], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'name': [], 'onkeypress': [], 'onmousedown': [], 'class': [], 'title': [], 'onclick': [], 'dir': ['ltr', 'rtl'], 'onmouseout': [], 'onmousemove': [], 'style': []}
+\ ],
+\ 'menu': [
+\ ['li'],
+\ { 'ondblclick': [], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'compact': ['BOOL'], 'onmouseover': [], 'lang': [], 'onmousedown': [], 'onkeypress': [], 'onclick': [], 'title': [], 'class': [], 'dir': ['ltr', 'rtl'], 'style': [], 'onmousemove': [], 'onmouseout': []}
+\ ],
+\ 'meta': [
+\ [],
+\ { 'http-equiv': [], 'content': [], 'lang': [], 'name': [], 'scheme': [], 'dir': ['ltr', 'rtl']}
+\ ],
+\ 'noframes': [
+\ ['p', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'ul', 'ol', 'dir', 'menu', 'pre', 'dl', 'div', 'center', 'noscript', 'noframes', 'blockquote', 'form', 'isindex', 'hr', 'table', 'fieldset', 'address', 'tt', 'i', 'b', 'u', 's', 'strike', 'big', 'small', 'em', 'strong', 'dfn', 'code', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'a', 'img', 'applet', 'object', 'font', 'basefont', 'br', 'script', 'map', 'q', 'sub', 'sup', 'span', 'bdo', 'iframe', 'input', 'select', 'textarea', 'label', 'button'],
+\ { 'ondblclick': [], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'onmousedown': [], 'onkeypress': [], 'onclick': [], 'title': [], 'class': [], 'dir': ['ltr', 'rtl'], 'style': [], 'onmousemove': [], 'onmouseout': []}
+\ ],
+\ 'noscript': [
+\ ['p', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'ul', 'ol', 'dir', 'menu', 'pre', 'dl', 'div', 'center', 'noscript', 'noframes', 'blockquote', 'form', 'isindex', 'hr', 'table', 'fieldset', 'address', 'tt', 'i', 'b', 'u', 's', 'strike', 'big', 'small', 'em', 'strong', 'dfn', 'code', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'a', 'img', 'applet', 'object', 'font', 'basefont', 'br', 'script', 'map', 'q', 'sub', 'sup', 'span', 'bdo', 'iframe', 'input', 'select', 'textarea', 'label', 'button'],
+\ { 'ondblclick': [], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'onmousedown': [], 'onkeypress': [], 'onclick': [], 'title': [], 'class': [], 'dir': ['ltr', 'rtl'], 'style': [], 'onmousemove': [], 'onmouseout': []}
+\ ],
+\ 'object': [
+\ ['param', 'p', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'ul', 'ol', 'dir', 'menu', 'pre', 'dl', 'div', 'center', 'noscript', 'noframes', 'blockquote', 'form', 'isindex', 'hr', 'table', 'fieldset', 'address', 'tt', 'i', 'b', 'u', 's', 'strike', 'big', 'small', 'em', 'strong', 'dfn', 'code', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'a', 'img', 'applet', 'object', 'font', 'basefont', 'br', 'script', 'map', 'q', 'sub', 'sup', 'span', 'bdo', 'iframe', 'input', 'select', 'textarea', 'label', 'button'],
+\ { 'ondblclick': [], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'align': ['top', 'middle', 'bottom', 'left', 'right'], 'name': [], 'data': [], 'declare': ['BOOL'], 'onkeypress': [], 'onmousedown': [], 'class': [], 'title': [], 'onclick': [], 'type': [], 'width': [], 'usemap': [], 'dir': ['ltr', 'rtl'], 'vspace': [], 'tabindex': [], 'standby': [], 'archive': [], 'classid': [], 'style': [], 'onmousemove': [], 'onmouseout': [], 'height': [], 'border': [], 'codetype': [], 'hspace': [], 'codebase': []}
+\ ],
+\ 'ol': [
+\ ['li'],
+\ { 'ondblclick': [], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'compact': ['BOOL'], 'onmouseover': [], 'lang': [], 'onkeypress': [], 'onmousedown': [], 'type': [], 'class': [], 'title': [], 'onclick': [], 'start': [], 'dir': ['ltr', 'rtl'], 'onmouseout': [], 'onmousemove': [], 'style': []}
+\ ],
+\ 'optgroup': [
+\ ['option'],
+\ { 'ondblclick': [], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'onkeypress': [], 'onmousedown': [], 'class': [], 'title': [], 'onclick': [], 'label': [], 'disabled': ['BOOL'], 'dir': ['ltr', 'rtl'], 'onmouseout': [], 'onmousemove': [], 'style': []}
+\ ],
+\ 'option': [
+\ [''],
+\ { 'ondblclick': [], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'value': [], 'onkeypress': [], 'onmousedown': [], 'class': [], 'title': [], 'onclick': [], 'label': [], 'disabled': ['BOOL'], 'dir': ['ltr', 'rtl'], 'onmouseout': [], 'onmousemove': [], 'style': [], 'selected': ['BOOL']}
+\ ],
+\ 'p': [
+\ ['tt', 'i', 'b', 'u', 's', 'strike', 'big', 'small', 'em', 'strong', 'dfn', 'code', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'a', 'img', 'applet', 'object', 'font', 'basefont', 'br', 'script', 'map', 'q', 'sub', 'sup', 'span', 'bdo', 'iframe', 'input', 'select', 'textarea', 'label', 'button'],
+\ { 'ondblclick': [], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'align': ['left', 'center', 'right', 'justify'], 'lang': [], 'onkeypress': [], 'onmousedown': [], 'class': [], 'title': [], 'onclick': [], 'dir': ['ltr', 'rtl'], 'onmouseout': [], 'onmousemove': [], 'style': []}
+\ ],
+\ 'param': [
+\ [],
+\ { 'id': [], 'value': [], 'name': [], 'type': [], 'valuetype': ['DATA', 'REF', 'OBJECT']}
+\ ],
+\ 'pre': [
+\ ['tt', 'i', 'b', 'u', 's', 'strike', 'em', 'strong', 'dfn', 'code', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'a', 'br', 'script', 'map', 'q', 'span', 'bdo', 'iframe', 'input', 'select', 'textarea', 'label', 'button'],
+\ { 'ondblclick': [], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'onmousedown': [], 'onkeypress': [], 'onclick': [], 'title': [], 'class': [], 'width': [], 'dir': ['ltr', 'rtl'], 'style': [], 'onmousemove': [], 'onmouseout': []}
+\ ],
+\ 'q': [
+\ ['tt', 'i', 'b', 'u', 's', 'strike', 'big', 'small', 'em', 'strong', 'dfn', 'code', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'a', 'img', 'applet', 'object', 'font', 'basefont', 'br', 'script', 'map', 'q', 'sub', 'sup', 'span', 'bdo', 'iframe', 'input', 'select', 'textarea', 'label', 'button'],
+\ { 'ondblclick': [], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'onmousedown': [], 'onkeypress': [], 'onclick': [], 'title': [], 'class': [], 'dir': ['ltr', 'rtl'], 'cite': [], 'style': [], 'onmousemove': [], 'onmouseout': []}
+\ ],
+\ 's': [
+\ ['tt', 'i', 'b', 'u', 's', 'strike', 'big', 'small', 'em', 'strong', 'dfn', 'code', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'a', 'img', 'applet', 'object', 'font', 'basefont', 'br', 'script', 'map', 'q', 'sub', 'sup', 'span', 'bdo', 'iframe', 'input', 'select', 'textarea', 'label', 'button'],
+\ { 'ondblclick': [], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'onmousedown': [], 'onkeypress': [], 'onclick': [], 'title': [], 'class': [], 'dir': ['ltr', 'rtl'], 'style': [], 'onmousemove': [], 'onmouseout': []}
+\ ],
+\ 'samp': [
+\ ['tt', 'i', 'b', 'u', 's', 'strike', 'big', 'small', 'em', 'strong', 'dfn', 'code', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'a', 'img', 'applet', 'object', 'font', 'basefont', 'br', 'script', 'map', 'q', 'sub', 'sup', 'span', 'bdo', 'iframe', 'input', 'select', 'textarea', 'label', 'button'],
+\ { 'ondblclick': [], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'onmousedown': [], 'onkeypress': [], 'onclick': [], 'title': [], 'class': [], 'dir': ['ltr', 'rtl'], 'style': [], 'onmousemove': [], 'onmouseout': []}
+\ ],
+\ 'script': [
+\ [],
+\ { 'src': [], 'for': [], 'charset': [], 'event': [], 'type': [], 'defer': ['BOOL'], 'language': []}
+\ ],
+\ 'select': [
+\ ['optgroup', 'option'],
+\ { 'ondblclick': [], 'onkeydown': [], 'onchange': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'name': [], 'onkeypress': [], 'onmousedown': [], 'class': [], 'title': [], 'onclick': [], 'disabled': ['BOOL'], 'dir': ['ltr', 'rtl'], 'size': [], 'onblur': [], 'onfocus': [], 'tabindex': [], 'onmouseout': [], 'onmousemove': [], 'style': [], 'multiple': ['BOOL']}
+\ ],
+\ 'small': [
+\ ['tt', 'i', 'b', 'u', 's', 'strike', 'big', 'small', 'em', 'strong', 'dfn', 'code', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'a', 'img', 'applet', 'object', 'font', 'basefont', 'br', 'script', 'map', 'q', 'sub', 'sup', 'span', 'bdo', 'iframe', 'input', 'select', 'textarea', 'label', 'button'],
+\ { 'ondblclick': [], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'onmousedown': [], 'onkeypress': [], 'onclick': [], 'title': [], 'class': [], 'dir': ['ltr', 'rtl'], 'style': [], 'onmousemove': [], 'onmouseout': []}
+\ ],
+\ 'span': [
+\ ['tt', 'i', 'b', 'u', 's', 'strike', 'big', 'small', 'em', 'strong', 'dfn', 'code', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'a', 'img', 'applet', 'object', 'font', 'basefont', 'br', 'script', 'map', 'q', 'sub', 'sup', 'span', 'bdo', 'iframe', 'input', 'select', 'textarea', 'label', 'button'],
+\ { 'ondblclick': [], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'onmousedown': [], 'onkeypress': [], 'onclick': [], 'title': [], 'class': [], 'dir': ['ltr', 'rtl'], 'style': [], 'onmousemove': [], 'onmouseout': []}
+\ ],
+\ 'strike': [
+\ ['tt', 'i', 'b', 'u', 's', 'strike', 'big', 'small', 'em', 'strong', 'dfn', 'code', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'a', 'img', 'applet', 'object', 'font', 'basefont', 'br', 'script', 'map', 'q', 'sub', 'sup', 'span', 'bdo', 'iframe', 'input', 'select', 'textarea', 'label', 'button'],
+\ { 'ondblclick': [], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'onmousedown': [], 'onkeypress': [], 'onclick': [], 'title': [], 'class': [], 'dir': ['ltr', 'rtl'], 'style': [], 'onmousemove': [], 'onmouseout': []}
+\ ],
+\ 'strong': [
+\ ['tt', 'i', 'b', 'u', 's', 'strike', 'big', 'small', 'em', 'strong', 'dfn', 'code', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'a', 'img', 'applet', 'object', 'font', 'basefont', 'br', 'script', 'map', 'q', 'sub', 'sup', 'span', 'bdo', 'iframe', 'input', 'select', 'textarea', 'label', 'button'],
+\ { 'ondblclick': [], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'onmousedown': [], 'onkeypress': [], 'onclick': [], 'title': [], 'class': [], 'dir': ['ltr', 'rtl'], 'style': [], 'onmousemove': [], 'onmouseout': []}
+\ ],
+\ 'style': [
+\ [],
+\ { 'media': [], 'lang': [], 'type': [], 'title': [], 'dir': ['ltr', 'rtl']}
+\ ],
+\ 'sub': [
+\ ['tt', 'i', 'b', 'u', 's', 'strike', 'big', 'small', 'em', 'strong', 'dfn', 'code', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'a', 'img', 'applet', 'object', 'font', 'basefont', 'br', 'script', 'map', 'q', 'sub', 'sup', 'span', 'bdo', 'iframe', 'input', 'select', 'textarea', 'label', 'button'],
+\ { 'ondblclick': [], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'onmousedown': [], 'onkeypress': [], 'onclick': [], 'title': [], 'class': [], 'dir': ['ltr', 'rtl'], 'style': [], 'onmousemove': [], 'onmouseout': []}
+\ ],
+\ 'sup': [
+\ ['tt', 'i', 'b', 'u', 's', 'strike', 'big', 'small', 'em', 'strong', 'dfn', 'code', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'a', 'img', 'applet', 'object', 'font', 'basefont', 'br', 'script', 'map', 'q', 'sub', 'sup', 'span', 'bdo', 'iframe', 'input', 'select', 'textarea', 'label', 'button'],
+\ { 'ondblclick': [], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'onmousedown': [], 'onkeypress': [], 'onclick': [], 'title': [], 'class': [], 'dir': ['ltr', 'rtl'], 'style': [], 'onmousemove': [], 'onmouseout': []}
+\ ],
+\ 'table': [
+\ ['caption', 'col', 'colgroup', 'thead', 'tfoot', 'tbody'],
+\ { 'ondblclick': [], 'onkeydown': [], 'onkeyup': [], 'datapagesize': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'align': ['left', 'center', 'right'], 'onkeypress': [], 'onmousedown': [], 'class': [], 'title': [], 'onclick': [], 'width': [], 'frame': ['void', 'above', 'below', 'hsides', 'lhs', 'rhs', 'vsides', 'box', 'border'], 'rules': ['none', 'groups', 'rows', 'cols', 'all'], 'dir': ['ltr', 'rtl'], 'summary': [], 'bgcolor': [], 'cellspacing': [], 'onmouseout': [], 'onmousemove': [], 'style': [], 'border': [], 'cellpadding': []}
+\ ],
+\ 'tbody': [
+\ ['tr'],
+\ { 'ondblclick': [], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'align': ['left', 'center', 'right', 'justify', 'char'], 'lang': [], 'valign': ['top', 'middle', 'bottom', 'baseline'], 'onkeypress': [], 'onmousedown': [], 'class': [], 'title': [], 'onclick': [], 'dir': ['ltr', 'rtl'], 'charoff': [], 'onmouseout': [], 'onmousemove': [], 'style': [], 'char': []}
+\ ],
+\ 'td': [
+\ ['p', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'ul', 'ol', 'dir', 'menu', 'pre', 'dl', 'div', 'center', 'noscript', 'noframes', 'blockquote', 'form', 'isindex', 'hr', 'table', 'fieldset', 'address', 'tt', 'i', 'b', 'u', 's', 'strike', 'big', 'small', 'em', 'strong', 'dfn', 'code', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'a', 'img', 'applet', 'object', 'font', 'basefont', 'br', 'script', 'map', 'q', 'sub', 'sup', 'span', 'bdo', 'iframe', 'input', 'select', 'textarea', 'label', 'button'],
+\ { 'ondblclick': [], 'axis': [], 'onkeydown': [], 'abbr': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'scope': ['row', 'col', 'rowgroup', 'colgroup'], 'onmouseover': [], 'lang': [], 'align': ['left', 'center', 'right', 'justify', 'char'], 'valign': ['top', 'middle', 'bottom', 'baseline'], 'onkeypress': [], 'onmousedown': [], 'class': [], 'title': [], 'onclick': [], 'width': [], 'headers': [], 'nowrap': ['BOOL'], 'dir': ['ltr', 'rtl'], 'rowspan': ['1'], 'colspan': ['1'], 'bgcolor': [], 'charoff': [], 'onmouseout': [], 'onmousemove': [], 'style': [], 'height': [], 'char': []}
+\ ],
+\ 'textarea': [
+\ [''],
+\ { 'ondblclick': [], 'cols': [], 'onkeydown': [], 'readonly': ['BOOL'], 'onchange': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'name': [], 'onkeypress': [], 'onmousedown': [], 'class': [], 'title': [], 'onclick': [], 'accesskey': [], 'disabled': ['BOOL'], 'rows': [], 'dir': ['ltr', 'rtl'], 'onblur': [], 'onfocus': [], 'onselect': [], 'tabindex': [], 'onmouseout': [], 'onmousemove': [], 'style': []}
+\ ],
+\ 'tfoot': [
+\ ['tr'],
+\ { 'ondblclick': [], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'align': ['left', 'center', 'right', 'justify', 'char'], 'lang': [], 'valign': ['top', 'middle', 'bottom', 'baseline'], 'onkeypress': [], 'onmousedown': [], 'class': [], 'title': [], 'onclick': [], 'dir': ['ltr', 'rtl'], 'charoff': [], 'onmouseout': [], 'onmousemove': [], 'style': [], 'char': []}
+\ ],
+\ 'th': [
+\ ['p', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'ul', 'ol', 'dir', 'menu', 'pre', 'dl', 'div', 'center', 'noscript', 'noframes', 'blockquote', 'form', 'isindex', 'hr', 'table', 'fieldset', 'address', 'tt', 'i', 'b', 'u', 's', 'strike', 'big', 'small', 'em', 'strong', 'dfn', 'code', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'a', 'img', 'applet', 'object', 'font', 'basefont', 'br', 'script', 'map', 'q', 'sub', 'sup', 'span', 'bdo', 'iframe', 'input', 'select', 'textarea', 'label', 'button'],
+\ { 'ondblclick': [], 'axis': [], 'onkeydown': [], 'abbr': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'scope': ['row', 'col', 'rowgroup', 'colgroup'], 'onmouseover': [], 'lang': [], 'align': ['left', 'center', 'right', 'justify', 'char'], 'valign': ['top', 'middle', 'bottom', 'baseline'], 'onkeypress': [], 'onmousedown': [], 'class': [], 'title': [], 'onclick': [], 'width': [], 'headers': [], 'nowrap': ['BOOL'], 'dir': ['ltr', 'rtl'], 'rowspan': ['1'], 'colspan': ['1'], 'bgcolor': [], 'charoff': [], 'onmouseout': [], 'onmousemove': [], 'style': [], 'height': [], 'char': []}
+\ ],
+\ 'thead': [
+\ ['tr'],
+\ { 'ondblclick': [], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'align': ['left', 'center', 'right', 'justify', 'char'], 'lang': [], 'valign': ['top', 'middle', 'bottom', 'baseline'], 'onkeypress': [], 'onmousedown': [], 'class': [], 'title': [], 'onclick': [], 'dir': ['ltr', 'rtl'], 'charoff': [], 'onmouseout': [], 'onmousemove': [], 'style': [], 'char': []}
+\ ],
+\ 'title': [
+\ [''],
+\ { 'lang': [], 'dir': ['ltr', 'rtl']}
+\ ],
+\ 'tr': [
+\ ['th', 'td'],
+\ { 'ondblclick': [], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'align': ['left', 'center', 'right', 'justify', 'char'], 'lang': [], 'valign': ['top', 'middle', 'bottom', 'baseline'], 'onkeypress': [], 'onmousedown': [], 'class': [], 'title': [], 'onclick': [], 'dir': ['ltr', 'rtl'], 'bgcolor': [], 'charoff': [], 'onmouseout': [], 'onmousemove': [], 'style': [], 'char': []}
+\ ],
+\ 'tt': [
+\ ['tt', 'i', 'b', 'u', 's', 'strike', 'big', 'small', 'em', 'strong', 'dfn', 'code', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'a', 'img', 'applet', 'object', 'font', 'basefont', 'br', 'script', 'map', 'q', 'sub', 'sup', 'span', 'bdo', 'iframe', 'input', 'select', 'textarea', 'label', 'button'],
+\ { 'ondblclick': [], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'onmousedown': [], 'onkeypress': [], 'onclick': [], 'title': [], 'class': [], 'dir': ['ltr', 'rtl'], 'style': [], 'onmousemove': [], 'onmouseout': []}
+\ ],
+\ 'u': [
+\ ['tt', 'i', 'b', 'u', 's', 'strike', 'big', 'small', 'em', 'strong', 'dfn', 'code', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'a', 'img', 'applet', 'object', 'font', 'basefont', 'br', 'script', 'map', 'q', 'sub', 'sup', 'span', 'bdo', 'iframe', 'input', 'select', 'textarea', 'label', 'button'],
+\ { 'ondblclick': [], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'onmousedown': [], 'onkeypress': [], 'onclick': [], 'title': [], 'class': [], 'dir': ['ltr', 'rtl'], 'style': [], 'onmousemove': [], 'onmouseout': []}
+\ ],
+\ 'ul': [
+\ ['li'],
+\ { 'ondblclick': [], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'compact': ['BOOL'], 'onmouseover': [], 'lang': [], 'onkeypress': [], 'onmousedown': [], 'type': ['disc', 'square', 'circle'], 'class': [], 'title': [], 'onclick': [], 'dir': ['ltr', 'rtl'], 'onmouseout': [], 'onmousemove': [], 'style': []}
+\ ],
+\ 'var': [
+\ ['tt', 'i', 'b', 'u', 's', 'strike', 'big', 'small', 'em', 'strong', 'dfn', 'code', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'a', 'img', 'applet', 'object', 'font', 'basefont', 'br', 'script', 'map', 'q', 'sub', 'sup', 'span', 'bdo', 'iframe', 'input', 'select', 'textarea', 'label', 'button'],
+\ { 'ondblclick': [], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'onmousedown': [], 'onkeypress': [], 'onclick': [], 'title': [], 'class': [], 'dir': ['ltr', 'rtl'], 'style': [], 'onmousemove': [], 'onmouseout': []}
+\ ],
+\ 'vimxmlattrinfo' : {
+\ 'accept' : ['ContentType', ''],
+\ 'accesskey' : ['Character', ''],
+\ 'action' : ['*URI', ''],
+\ 'align' : ['String', ''],
+\ 'alt' : ['*Text', ''],
+\ 'archive' : ['UriList', ''],
+\ 'axis' : ['CDATA', ''],
+\ 'border' : ['Pixels', ''],
+\ 'cellpadding' : ['Length', ''],
+\ 'cellspacing' : ['Length', ''],
+\ 'char' : ['Character', ''],
+\ 'charoff' : ['Length', ''],
+\ 'charset' : ['LangCode', ''],
+\ 'checked' : ['Bool', ''],
+\ 'class' : ['CDATA', ''],
+\ 'codetype' : ['ContentType', ''],
+\ 'cols' : ['*Number', ''],
+\ 'colspan' : ['Number', ''],
+\ 'content' : ['*CDATA', ''],
+\ 'coords' : ['Coords', ''],
+\ 'data' : ['URI', ''],
+\ 'datetime' : ['DateTime', ''],
+\ 'declare' : ['Bool', ''],
+\ 'defer' : ['Bool', ''],
+\ 'dir' : ['String', ''],
+\ 'disabled' : ['Bool', ''],
+\ 'enctype' : ['ContentType', ''],
+\ 'for' : ['ID', ''],
+\ 'headers' : ['IDREFS', ''],
+\ 'height' : ['Number', ''],
+\ 'href' : ['*URI', ''],
+\ 'hreflang' : ['LangCode', ''],
+\ 'id' : ['ID', ''],
+\ 'ismap' : ['Bool', ''],
+\ 'label' : ['*Text', ''],
+\ 'lang' : ['LangCode', ''],
+\ 'longdesc' : ['URI', ''],
+\ 'maxlength' : ['Number', ''],
+\ 'media' : ['MediaDesc', ''],
+\ 'method' : ['String', ''],
+\ 'multiple' : ['Bool', ''],
+\ 'name' : ['CDATA', ''],
+\ 'nohref' : ['Bool', ''],
+\ 'onblur' : ['Script', ''],
+\ 'onchange' : ['Script', ''],
+\ 'onclick' : ['Script', ''],
+\ 'ondblclick' : ['Script', ''],
+\ 'onfocus' : ['Script', ''],
+\ 'onkeydown' : ['Script', ''],
+\ 'onkeypress' : ['Script', ''],
+\ 'onkeyup' : ['Script', ''],
+\ 'onload' : ['Script', ''],
+\ 'onmousedown' : ['Script', ''],
+\ 'onmousemove' : ['Script', ''],
+\ 'onmouseout' : ['Script', ''],
+\ 'onmouseover' : ['Script', ''],
+\ 'onmouseup' : ['Script', ''],
+\ 'onreset' : ['Script', ''],
+\ 'onselect' : ['Script', ''],
+\ 'onsubmit' : ['Script', ''],
+\ 'onunload' : ['Script', ''],
+\ 'profile' : ['URI', ''],
+\ 'readonly' : ['Bool', ''],
+\ 'rel' : ['LinkTypes', ''],
+\ 'rev' : ['LinkTypes', ''],
+\ 'rows' : ['*Number', ''],
+\ 'rules' : ['String', ''],
+\ 'scheme' : ['CDATA', ''],
+\ 'selected' : ['Bool', ''],
+\ 'shape' : ['Shape', ''],
+\ 'size' : ['CDATA', ''],
+\ 'span' : ['Number', ''],
+\ 'src' : ['*URI', ''],
+\ 'standby' : ['Text', ''],
+\ 'style' : ['StyleSheet', ''],
+\ 'summary' : ['*Text', ''],
+\ 'tabindex' : ['Number', ''],
+\ 'title' : ['Text', ''],
+\ 'type' : ['*ContentType', ''],
+\ 'usemap' : ['URI', ''],
+\ 'valign' : ['String', ''],
+\ 'valuetype' : ['String', ''],
+\ 'width' : ['Number', ''],
+\ 'xmlns' : ['URI', '']
+\ },
+\ 'vimxmltaginfo': {
+\ 'area': ['/>', ''],
+\ 'base': ['/>', ''],
+\ 'basefont': ['/>', ''],
+\ 'br': ['/>', ''],
+\ 'col': ['/>', ''],
+\ 'hr': ['/>', ''],
+\ 'img': ['/>', ''],
+\ 'input': ['/>', ''],
+\ 'isindex': ['/>', ''],
+\ 'link': ['/>', ''],
+\ 'meta': ['/>', ''],
+\ 'param': ['/>', ''],
+\ }
+\ }
+" vim:ft=vim:ff=unix
--- /dev/null
+++ b/lib/vimfiles/autoload/xml/html40f.vim
@@ -1,0 +1,469 @@
+let g:xmldata_html40t = {
+\ 'vimxmlentities': ['AElig', 'Aacute', 'Acirc', 'Agrave', 'Alpha', 'Aring', 'Atilde', 'Auml', 'Beta', 'Ccedil', 'Chi', 'Dagger', 'Delta', 'ETH', 'Eacute', 'Ecirc', 'Egrave', 'Epsilon', 'Eta', 'Euml', 'Gamma', 'Iacute', 'Icirc', 'Igrave', 'Iota', 'Iuml', 'Kappa', 'Lambda', 'Mu', 'Ntilde', 'Nu', 'OElig', 'Oacute', 'Ocirc', 'Ograve', 'Omega', 'Omicron', 'Oslash', 'Otilde', 'Ouml', 'Phi', 'Pi', 'Prime', 'Psi', 'Rho', 'Scaron', 'Sigma', 'THORN', 'Tau', 'Theta', 'Uacute', 'Ucirc', 'Ugrave', 'Upsilon', 'Uuml', 'Xi', 'Yacute', 'Yuml', 'Zeta', 'aacute', 'acirc', 'acute', 'aelig', 'agrave', 'alefsym', 'alpha', 'amp', 'and', 'ang', 'apos', 'aring', 'asymp', 'atilde', 'auml', 'bdquo', 'beta', 'brvbar', 'bull', 'cap', 'ccedil', 'cedil', 'cent', 'chi', 'circ', 'clubs', 'cong', 'copy', 'crarr', 'cup', 'curren', 'dArr', 'dagger', 'darr', 'deg', 'delta', 'diams', 'divide', 'eacute', 'ecirc', 'egrave', 'empty', 'emsp', 'ensp', 'epsilon', 'equiv', 'eta', 'eth', 'euml', 'euro', 'exist', 'fnof', 'forall', 'frac12', 'frac14', 'frac34', 'frasl', 'gamma', 'ge', 'gt', 'hArr', 'harr', 'hearts', 'hellip', 'iacute', 'icirc', 'iexcl', 'igrave', 'image', 'infin', 'int', 'iota', 'iquest', 'isin', 'iuml', 'kappa', 'lArr', 'lambda', 'lang', 'laquo', 'larr', 'lceil', 'ldquo', 'le', 'lfloor', 'lowast', 'loz', 'lrm', 'lsaquo', 'lsquo', 'lt', 'macr', 'mdash', 'micro', 'middot', 'minus', 'mu', 'nabla', 'nbsp', 'ndash', 'ne', 'ni', 'not', 'notin', 'nsub', 'ntilde', 'nu', 'oacute', 'ocirc', 'oelig', 'ograve', 'oline', 'omega', 'omicron', 'oplus', 'or', 'ordf', 'ordm', 'oslash', 'otilde', 'otimes', 'ouml', 'para', 'part', 'permil', 'perp', 'phi', 'pi', 'piv', 'plusmn', 'pound', 'prime', 'prod', 'prop', 'psi', 'quot', 'rArr', 'radic', 'rang', 'raquo', 'rarr', 'rceil', 'rdquo', 'real', 'reg', 'rfloor', 'rho', 'rlm', 'rsaquo', 'rsquo', 'sbquo', 'scaron', 'sdot', 'sect', 'shy', 'sigma', 'sigmaf', 'sim', 'spades', 'sub', 'sube', 'sum', 'sup', 'sup1', 'sup2', 'sup3', 'supe', 'szlig', 'tau', 'there4', 'theta', 'thetasym', 'thinsp', 'thorn', 'tilde', 'times', 'trade', 'uArr', 'uacute', 'uarr', 'ucirc', 'ugrave', 'uml', 'upsih', 'upsilon', 'uuml', 'weierp', 'xi', 'yacute', 'yen', 'yuml', 'zeta', 'zwj', 'zwnj'],
+\ 'vimxmlroot': ['html'],
+\ 'a': [
+\ ['tt', 'i', 'b', 'u', 's', 'strike', 'big', 'small', 'em', 'strong', 'dfn', 'code', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'img', 'applet', 'object', 'font', 'basefont', 'br', 'script', 'map', 'q', 'sub', 'sup', 'span', 'bdo', 'iframe', 'input', 'select', 'textarea', 'label', 'button'],
+\ { 'rel': [], 'accesskey': [], 'coords': [], 'ondblclick': [], 'dir': ['ltr', 'rtl'], 'onblur': [], 'onkeydown': [], 'onfocus': [], 'target': [], 'onkeyup': [], 'href': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'tabindex': [], 'lang': [], 'onmouseout': [], 'onmousemove': [], 'style': [], 'name': [], 'charset': [], 'hreflang': [], 'onkeypress': [], 'onmousedown': [], 'rev': [], 'class': [], 'title': [], 'onclick': [], 'type': [], 'shape': ['rect', 'circle', 'poly', 'default']}
+\ ],
+\ 'abbr': [
+\ ['tt', 'i', 'b', 'u', 's', 'strike', 'big', 'small', 'em', 'strong', 'dfn', 'code', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'a', 'img', 'applet', 'object', 'font', 'basefont', 'br', 'script', 'map', 'q', 'sub', 'sup', 'span', 'bdo', 'iframe', 'input', 'select', 'textarea', 'label', 'button'],
+\ { 'ondblclick': [], 'dir': ['ltr', 'rtl'], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'style': [], 'onmousemove': [], 'onmouseout': [], 'onmousedown': [], 'onkeypress': [], 'onclick': [], 'title': [], 'class': []}
+\ ],
+\ 'acronym': [
+\ ['tt', 'i', 'b', 'u', 's', 'strike', 'big', 'small', 'em', 'strong', 'dfn', 'code', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'a', 'img', 'applet', 'object', 'font', 'basefont', 'br', 'script', 'map', 'q', 'sub', 'sup', 'span', 'bdo', 'iframe', 'input', 'select', 'textarea', 'label', 'button'],
+\ { 'ondblclick': [], 'dir': ['ltr', 'rtl'], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'style': [], 'onmousemove': [], 'onmouseout': [], 'onmousedown': [], 'onkeypress': [], 'onclick': [], 'title': [], 'class': []}
+\ ],
+\ 'address': [
+\ ['tt', 'i', 'b', 'u', 's', 'strike', 'big', 'small', 'em', 'strong', 'dfn', 'code', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'a', 'img', 'applet', 'object', 'font', 'basefont', 'br', 'script', 'map', 'q', 'sub', 'sup', 'span', 'bdo', 'iframe', 'input', 'select', 'textarea', 'label', 'button', 'p'],
+\ { 'ondblclick': [], 'dir': ['ltr', 'rtl'], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'style': [], 'onmousemove': [], 'onmouseout': [], 'onmousedown': [], 'onkeypress': [], 'onclick': [], 'title': [], 'class': []}
+\ ],
+\ 'applet': [
+\ ['param', 'p', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'ul', 'ol', 'dir', 'menu', 'pre', 'dl', 'div', 'center', 'noscript', 'noframes', 'blockquote', 'form', 'isindex', 'hr', 'table', 'fieldset', 'address', 'tt', 'i', 'b', 'u', 's', 'strike', 'big', 'small', 'em', 'strong', 'dfn', 'code', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'a', 'img', 'applet', 'object', 'font', 'basefont', 'br', 'script', 'map', 'q', 'sub', 'sup', 'span', 'bdo', 'iframe', 'input', 'select', 'textarea', 'label', 'button'],
+\ { 'width': [], 'object': [], 'id': [], 'code': [], 'vspace': [], 'archive': [], 'alt': [], 'align': ['top', 'middle', 'bottom', 'left', 'right'], 'style': [], 'name': [], 'height': [], 'hspace': [], 'title': [], 'class': [], 'codebase': []}
+\ ],
+\ 'area': [
+\ [],
+\ { 'accesskey': [], 'coords': [], 'ondblclick': [], 'dir': ['ltr', 'rtl'], 'onblur': [], 'onkeydown': [], 'target': [], 'nohref': ['BOOL'], 'onfocus': [], 'onkeyup': [], 'href': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'alt': [], 'tabindex': [], 'onmouseout': [], 'onmousemove': [], 'style': [], 'onkeypress': [], 'onmousedown': [], 'shape': ['rect', 'circle', 'poly', 'default'], 'class': [], 'title': [], 'onclick': []}
+\ ],
+\ 'b': [
+\ ['tt', 'i', 'b', 'u', 's', 'strike', 'big', 'small', 'em', 'strong', 'dfn', 'code', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'a', 'img', 'applet', 'object', 'font', 'basefont', 'br', 'script', 'map', 'q', 'sub', 'sup', 'span', 'bdo', 'iframe', 'input', 'select', 'textarea', 'label', 'button'],
+\ { 'ondblclick': [], 'dir': ['ltr', 'rtl'], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'style': [], 'onmousemove': [], 'onmouseout': [], 'onmousedown': [], 'onkeypress': [], 'onclick': [], 'title': [], 'class': []}
+\ ],
+\ 'base': [
+\ [],
+\ { 'target': [], 'href': []}
+\ ],
+\ 'basefont': [
+\ [],
+\ { 'size': [], 'face': [], 'color': [], 'id': []}
+\ ],
+\ 'bdo': [
+\ ['tt', 'i', 'b', 'u', 's', 'strike', 'big', 'small', 'em', 'strong', 'dfn', 'code', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'a', 'img', 'applet', 'object', 'font', 'basefont', 'br', 'script', 'map', 'q', 'sub', 'sup', 'span', 'bdo', 'iframe', 'input', 'select', 'textarea', 'label', 'button'],
+\ { 'dir': ['ltr', 'rtl'], 'id': [], 'lang': [], 'style': [], 'class': [], 'title': []}
+\ ],
+\ 'big': [
+\ ['tt', 'i', 'b', 'u', 's', 'strike', 'big', 'small', 'em', 'strong', 'dfn', 'code', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'a', 'img', 'applet', 'object', 'font', 'basefont', 'br', 'script', 'map', 'q', 'sub', 'sup', 'span', 'bdo', 'iframe', 'input', 'select', 'textarea', 'label', 'button'],
+\ { 'ondblclick': [], 'dir': ['ltr', 'rtl'], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'style': [], 'onmousemove': [], 'onmouseout': [], 'onmousedown': [], 'onkeypress': [], 'onclick': [], 'title': [], 'class': []}
+\ ],
+\ 'blockquote': [
+\ ['p', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'ul', 'ol', 'dir', 'menu', 'pre', 'dl', 'div', 'center', 'noscript', 'noframes', 'blockquote', 'form', 'isindex', 'hr', 'table', 'fieldset', 'address', 'tt', 'i', 'b', 'u', 's', 'strike', 'big', 'small', 'em', 'strong', 'dfn', 'code', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'a', 'img', 'applet', 'object', 'font', 'basefont', 'br', 'script', 'map', 'q', 'sub', 'sup', 'span', 'bdo', 'iframe', 'input', 'select', 'textarea', 'label', 'button'],
+\ { 'ondblclick': [], 'dir': ['ltr', 'rtl'], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'cite': [], 'onmouseover': [], 'lang': [], 'style': [], 'onmousemove': [], 'onmouseout': [], 'onmousedown': [], 'onkeypress': [], 'onclick': [], 'title': [], 'class': []}
+\ ],
+\ 'body': [
+\ ['p', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'ul', 'ol', 'dir', 'menu', 'pre', 'dl', 'div', 'center', 'noscript', 'noframes', 'blockquote', 'form', 'isindex', 'hr', 'table', 'fieldset', 'address', 'tt', 'i', 'b', 'u', 's', 'strike', 'big', 'small', 'em', 'strong', 'dfn', 'code', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'a', 'img', 'applet', 'object', 'font', 'basefont', 'br', 'script', 'map', 'q', 'sub', 'sup', 'span', 'bdo', 'iframe', 'input', 'select', 'textarea', 'label', 'button', 'ins', 'del'],
+\ { 'vlink': [], 'ondblclick': [], 'dir': ['ltr', 'rtl'], 'onkeydown': [], 'alink': [], 'onkeyup': [], 'bgcolor': [], 'text': [], 'onmouseup': [], 'id': [], 'link': [], 'onmouseover': [], 'lang': [], 'onmouseout': [], 'onmousemove': [], 'style': [], 'background': [], 'onunload': [], 'onkeypress': [], 'onmousedown': [], 'onload': [], 'class': [], 'title': [], 'onclick': []}
+\ ],
+\ 'br': [
+\ [],
+\ { 'clear': ['none', 'left', 'all', 'right', 'none'], 'id': [], 'style': [], 'class': [], 'title': []}
+\ ],
+\ 'button': [
+\ ['p', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'ul', 'ol', 'dir', 'menu', 'pre', 'dl', 'div', 'center', 'noscript', 'noframes', 'blockquote', 'hr', 'table', 'address', 'tt', 'i', 'b', 'u', 's', 'strike', 'big', 'small', 'em', 'strong', 'dfn', 'code', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'img', 'applet', 'object', 'font', 'basefont', 'br', 'script', 'map', 'q', 'sub', 'sup', 'span', 'bdo'],
+\ { 'accesskey': [], 'disabled': ['BOOL'], 'ondblclick': [], 'dir': ['ltr', 'rtl'], 'onblur': [], 'onkeydown': [], 'onfocus': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'tabindex': [], 'value': [], 'name': [], 'onmouseout': [], 'onmousemove': [], 'style': [], 'onkeypress': [], 'onmousedown': [], 'class': [], 'title': [], 'onclick': [], 'type': ['submit', 'button', 'submit', 'reset']}
+\ ],
+\ 'caption': [
+\ ['tt', 'i', 'b', 'u', 's', 'strike', 'big', 'small', 'em', 'strong', 'dfn', 'code', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'a', 'img', 'applet', 'object', 'font', 'basefont', 'br', 'script', 'map', 'q', 'sub', 'sup', 'span', 'bdo', 'iframe', 'input', 'select', 'textarea', 'label', 'button'],
+\ { 'ondblclick': [], 'dir': ['ltr', 'rtl'], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'align': ['top', 'bottom', 'left', 'right'], 'lang': [], 'onmouseout': [], 'onmousemove': [], 'style': [], 'onkeypress': [], 'onmousedown': [], 'class': [], 'title': [], 'onclick': []}
+\ ],
+\ 'center': [
+\ ['p', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'ul', 'ol', 'dir', 'menu', 'pre', 'dl', 'div', 'center', 'noscript', 'noframes', 'blockquote', 'form', 'isindex', 'hr', 'table', 'fieldset', 'address', 'tt', 'i', 'b', 'u', 's', 'strike', 'big', 'small', 'em', 'strong', 'dfn', 'code', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'a', 'img', 'applet', 'object', 'font', 'basefont', 'br', 'script', 'map', 'q', 'sub', 'sup', 'span', 'bdo', 'iframe', 'input', 'select', 'textarea', 'label', 'button'],
+\ { 'ondblclick': [], 'dir': ['ltr', 'rtl'], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'style': [], 'onmousemove': [], 'onmouseout': [], 'onmousedown': [], 'onkeypress': [], 'onclick': [], 'title': [], 'class': []}
+\ ],
+\ 'cite': [
+\ ['tt', 'i', 'b', 'u', 's', 'strike', 'big', 'small', 'em', 'strong', 'dfn', 'code', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'a', 'img', 'applet', 'object', 'font', 'basefont', 'br', 'script', 'map', 'q', 'sub', 'sup', 'span', 'bdo', 'iframe', 'input', 'select', 'textarea', 'label', 'button'],
+\ { 'ondblclick': [], 'dir': ['ltr', 'rtl'], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'style': [], 'onmousemove': [], 'onmouseout': [], 'onmousedown': [], 'onkeypress': [], 'onclick': [], 'title': [], 'class': []}
+\ ],
+\ 'code': [
+\ ['tt', 'i', 'b', 'u', 's', 'strike', 'big', 'small', 'em', 'strong', 'dfn', 'code', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'a', 'img', 'applet', 'object', 'font', 'basefont', 'br', 'script', 'map', 'q', 'sub', 'sup', 'span', 'bdo', 'iframe', 'input', 'select', 'textarea', 'label', 'button'],
+\ { 'ondblclick': [], 'dir': ['ltr', 'rtl'], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'style': [], 'onmousemove': [], 'onmouseout': [], 'onmousedown': [], 'onkeypress': [], 'onclick': [], 'title': [], 'class': []}
+\ ],
+\ 'col': [
+\ [],
+\ { 'width': [], 'ondblclick': [], 'dir': ['ltr', 'rtl'], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'charoff': [], 'onmouseover': [], 'lang': [], 'align': ['left', 'center', 'right', 'justify', 'char'], 'valign': ['top', 'middle', 'bottom', 'baseline'], 'onmouseout': [], 'onmousemove': [], 'style': [], 'onkeypress': [], 'onmousedown': [], 'char': [], 'span': ['1'], 'class': [], 'title': [], 'onclick': []}
+\ ],
+\ 'colgroup': [
+\ ['col'],
+\ { 'width': [], 'ondblclick': [], 'dir': ['ltr', 'rtl'], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'charoff': [], 'onmouseover': [], 'lang': [], 'align': ['left', 'center', 'right', 'justify', 'char'], 'valign': ['top', 'middle', 'bottom', 'baseline'], 'onmouseout': [], 'onmousemove': [], 'style': [], 'onkeypress': [], 'onmousedown': [], 'char': [], 'span': ['1'], 'class': [], 'title': [], 'onclick': []}
+\ ],
+\ 'dd': [
+\ ['p', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'ul', 'ol', 'dir', 'menu', 'pre', 'dl', 'div', 'center', 'noscript', 'noframes', 'blockquote', 'form', 'isindex', 'hr', 'table', 'fieldset', 'address', 'tt', 'i', 'b', 'u', 's', 'strike', 'big', 'small', 'em', 'strong', 'dfn', 'code', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'a', 'img', 'applet', 'object', 'font', 'basefont', 'br', 'script', 'map', 'q', 'sub', 'sup', 'span', 'bdo', 'iframe', 'input', 'select', 'textarea', 'label', 'button'],
+\ { 'ondblclick': [], 'dir': ['ltr', 'rtl'], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'style': [], 'onmousemove': [], 'onmouseout': [], 'onmousedown': [], 'onkeypress': [], 'onclick': [], 'title': [], 'class': []}
+\ ],
+\ 'del': [
+\ ['p', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'ul', 'ol', 'dir', 'menu', 'pre', 'dl', 'div', 'center', 'noscript', 'noframes', 'blockquote', 'form', 'isindex', 'hr', 'table', 'fieldset', 'address', 'tt', 'i', 'b', 'u', 's', 'strike', 'big', 'small', 'em', 'strong', 'dfn', 'code', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'a', 'img', 'applet', 'object', 'font', 'basefont', 'br', 'script', 'map', 'q', 'sub', 'sup', 'span', 'bdo', 'iframe', 'input', 'select', 'textarea', 'label', 'button'],
+\ { 'ondblclick': [], 'dir': ['ltr', 'rtl'], 'datetime': [], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'cite': [], 'onmouseover': [], 'lang': [], 'onmouseout': [], 'onmousemove': [], 'style': [], 'onkeypress': [], 'onmousedown': [], 'class': [], 'title': [], 'onclick': []}
+\ ],
+\ 'dfn': [
+\ ['tt', 'i', 'b', 'u', 's', 'strike', 'big', 'small', 'em', 'strong', 'dfn', 'code', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'a', 'img', 'applet', 'object', 'font', 'basefont', 'br', 'script', 'map', 'q', 'sub', 'sup', 'span', 'bdo', 'iframe', 'input', 'select', 'textarea', 'label', 'button'],
+\ { 'ondblclick': [], 'dir': ['ltr', 'rtl'], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'style': [], 'onmousemove': [], 'onmouseout': [], 'onmousedown': [], 'onkeypress': [], 'onclick': [], 'title': [], 'class': []}
+\ ],
+\ 'dir': [
+\ ['li'],
+\ { 'ondblclick': [], 'dir': ['ltr', 'rtl'], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'compact': ['BOOL'], 'onmouseover': [], 'lang': [], 'style': [], 'onmousemove': [], 'onmouseout': [], 'onmousedown': [], 'onkeypress': [], 'onclick': [], 'title': [], 'class': []}
+\ ],
+\ 'div': [
+\ ['p', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'ul', 'ol', 'dir', 'menu', 'pre', 'dl', 'div', 'center', 'noscript', 'noframes', 'blockquote', 'form', 'isindex', 'hr', 'table', 'fieldset', 'address', 'tt', 'i', 'b', 'u', 's', 'strike', 'big', 'small', 'em', 'strong', 'dfn', 'code', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'a', 'img', 'applet', 'object', 'font', 'basefont', 'br', 'script', 'map', 'q', 'sub', 'sup', 'span', 'bdo', 'iframe', 'input', 'select', 'textarea', 'label', 'button'],
+\ { 'ondblclick': [], 'dir': ['ltr', 'rtl'], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'align': ['left', 'center', 'right', 'justify'], 'lang': [], 'onmouseout': [], 'onmousemove': [], 'style': [], 'onkeypress': [], 'onmousedown': [], 'class': [], 'title': [], 'onclick': []}
+\ ],
+\ 'dl': [
+\ ['dt', 'dd'],
+\ { 'ondblclick': [], 'dir': ['ltr', 'rtl'], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'compact': ['BOOL'], 'onmouseover': [], 'lang': [], 'style': [], 'onmousemove': [], 'onmouseout': [], 'onmousedown': [], 'onkeypress': [], 'onclick': [], 'title': [], 'class': []}
+\ ],
+\ 'dt': [
+\ ['tt', 'i', 'b', 'u', 's', 'strike', 'big', 'small', 'em', 'strong', 'dfn', 'code', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'a', 'img', 'applet', 'object', 'font', 'basefont', 'br', 'script', 'map', 'q', 'sub', 'sup', 'span', 'bdo', 'iframe', 'input', 'select', 'textarea', 'label', 'button'],
+\ { 'ondblclick': [], 'dir': ['ltr', 'rtl'], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'style': [], 'onmousemove': [], 'onmouseout': [], 'onmousedown': [], 'onkeypress': [], 'onclick': [], 'title': [], 'class': []}
+\ ],
+\ 'em': [
+\ ['tt', 'i', 'b', 'u', 's', 'strike', 'big', 'small', 'em', 'strong', 'dfn', 'code', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'a', 'img', 'applet', 'object', 'font', 'basefont', 'br', 'script', 'map', 'q', 'sub', 'sup', 'span', 'bdo', 'iframe', 'input', 'select', 'textarea', 'label', 'button'],
+\ { 'ondblclick': [], 'dir': ['ltr', 'rtl'], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'style': [], 'onmousemove': [], 'onmouseout': [], 'onmousedown': [], 'onkeypress': [], 'onclick': [], 'title': [], 'class': []}
+\ ],
+\ 'fieldset': [
+\ ['legend', 'p', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'ul', 'ol', 'dir', 'menu', 'pre', 'dl', 'div', 'center', 'noscript', 'noframes', 'blockquote', 'form', 'isindex', 'hr', 'table', 'fieldset', 'address', 'tt', 'i', 'b', 'u', 's', 'strike', 'big', 'small', 'em', 'strong', 'dfn', 'code', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'a', 'img', 'applet', 'object', 'font', 'basefont', 'br', 'script', 'map', 'q', 'sub', 'sup', 'span', 'bdo', 'iframe', 'input', 'select', 'textarea', 'label', 'button'],
+\ { 'ondblclick': [], 'dir': ['ltr', 'rtl'], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'style': [], 'onmousemove': [], 'onmouseout': [], 'onmousedown': [], 'onkeypress': [], 'onclick': [], 'title': [], 'class': []}
+\ ],
+\ 'font': [
+\ ['tt', 'i', 'b', 'u', 's', 'strike', 'big', 'small', 'em', 'strong', 'dfn', 'code', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'a', 'img', 'applet', 'object', 'font', 'basefont', 'br', 'script', 'map', 'q', 'sub', 'sup', 'span', 'bdo', 'iframe', 'input', 'select', 'textarea', 'label', 'button'],
+\ { 'dir': ['ltr', 'rtl'], 'size': [], 'face': [], 'color': [], 'id': [], 'lang': [], 'style': [], 'class': [], 'title': []}
+\ ],
+\ 'form': [
+\ ['p', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'ul', 'ol', 'dir', 'menu', 'pre', 'dl', 'div', 'center', 'noscript', 'noframes', 'blockquote', 'isindex', 'hr', 'table', 'fieldset', 'address', 'tt', 'i', 'b', 'u', 's', 'strike', 'big', 'small', 'em', 'strong', 'dfn', 'code', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'a', 'img', 'applet', 'object', 'font', 'basefont', 'br', 'script', 'map', 'q', 'sub', 'sup', 'span', 'bdo', 'iframe', 'input', 'select', 'textarea', 'label', 'button'],
+\ { 'enctype': ['application/x-www-form-urlencoded'], 'onsubmit': [], 'ondblclick': [], 'dir': ['ltr', 'rtl'], 'onkeydown': [], 'target': [], 'onkeyup': [], 'onmouseup': [], 'onreset': [], 'id': [], 'method': ['GET', 'POST'], 'onmouseover': [], 'lang': [], 'onmouseout': [], 'onmousemove': [], 'style': [], 'accept-charset': [], 'onkeypress': [], 'onmousedown': [], 'action': [], 'class': [], 'title': [], 'onclick': []}
+\ ],
+\ 'h1': [
+\ ['tt', 'i', 'b', 'u', 's', 'strike', 'big', 'small', 'em', 'strong', 'dfn', 'code', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'a', 'img', 'applet', 'object', 'font', 'basefont', 'br', 'script', 'map', 'q', 'sub', 'sup', 'span', 'bdo', 'iframe', 'input', 'select', 'textarea', 'label', 'button'],
+\ { 'ondblclick': [], 'dir': ['ltr', 'rtl'], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'align': ['left', 'center', 'right', 'justify'], 'lang': [], 'onmouseout': [], 'onmousemove': [], 'style': [], 'onkeypress': [], 'onmousedown': [], 'class': [], 'title': [], 'onclick': []}
+\ ],
+\ 'h2': [
+\ ['tt', 'i', 'b', 'u', 's', 'strike', 'big', 'small', 'em', 'strong', 'dfn', 'code', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'a', 'img', 'applet', 'object', 'font', 'basefont', 'br', 'script', 'map', 'q', 'sub', 'sup', 'span', 'bdo', 'iframe', 'input', 'select', 'textarea', 'label', 'button'],
+\ { 'ondblclick': [], 'dir': ['ltr', 'rtl'], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'align': ['left', 'center', 'right', 'justify'], 'lang': [], 'onmouseout': [], 'onmousemove': [], 'style': [], 'onkeypress': [], 'onmousedown': [], 'class': [], 'title': [], 'onclick': []}
+\ ],
+\ 'h3': [
+\ ['tt', 'i', 'b', 'u', 's', 'strike', 'big', 'small', 'em', 'strong', 'dfn', 'code', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'a', 'img', 'applet', 'object', 'font', 'basefont', 'br', 'script', 'map', 'q', 'sub', 'sup', 'span', 'bdo', 'iframe', 'input', 'select', 'textarea', 'label', 'button'],
+\ { 'ondblclick': [], 'dir': ['ltr', 'rtl'], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'align': ['left', 'center', 'right', 'justify'], 'lang': [], 'onmouseout': [], 'onmousemove': [], 'style': [], 'onkeypress': [], 'onmousedown': [], 'class': [], 'title': [], 'onclick': []}
+\ ],
+\ 'h4': [
+\ ['tt', 'i', 'b', 'u', 's', 'strike', 'big', 'small', 'em', 'strong', 'dfn', 'code', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'a', 'img', 'applet', 'object', 'font', 'basefont', 'br', 'script', 'map', 'q', 'sub', 'sup', 'span', 'bdo', 'iframe', 'input', 'select', 'textarea', 'label', 'button'],
+\ { 'ondblclick': [], 'dir': ['ltr', 'rtl'], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'align': ['left', 'center', 'right', 'justify'], 'lang': [], 'onmouseout': [], 'onmousemove': [], 'style': [], 'onkeypress': [], 'onmousedown': [], 'class': [], 'title': [], 'onclick': []}
+\ ],
+\ 'h5': [
+\ ['tt', 'i', 'b', 'u', 's', 'strike', 'big', 'small', 'em', 'strong', 'dfn', 'code', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'a', 'img', 'applet', 'object', 'font', 'basefont', 'br', 'script', 'map', 'q', 'sub', 'sup', 'span', 'bdo', 'iframe', 'input', 'select', 'textarea', 'label', 'button'],
+\ { 'ondblclick': [], 'dir': ['ltr', 'rtl'], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'align': ['left', 'center', 'right', 'justify'], 'lang': [], 'onmouseout': [], 'onmousemove': [], 'style': [], 'onkeypress': [], 'onmousedown': [], 'class': [], 'title': [], 'onclick': []}
+\ ],
+\ 'h6': [
+\ ['tt', 'i', 'b', 'u', 's', 'strike', 'big', 'small', 'em', 'strong', 'dfn', 'code', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'a', 'img', 'applet', 'object', 'font', 'basefont', 'br', 'script', 'map', 'q', 'sub', 'sup', 'span', 'bdo', 'iframe', 'input', 'select', 'textarea', 'label', 'button'],
+\ { 'ondblclick': [], 'dir': ['ltr', 'rtl'], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'align': ['left', 'center', 'right', 'justify'], 'lang': [], 'onmouseout': [], 'onmousemove': [], 'style': [], 'onkeypress': [], 'onmousedown': [], 'class': [], 'title': [], 'onclick': []}
+\ ],
+\ 'head': [
+\ ['title', 'isindex', 'base', 'script', 'style', 'meta', 'link', 'object'],
+\ { 'profile': [], 'dir': ['ltr', 'rtl'], 'lang': []}
+\ ],
+\ 'hr': [
+\ [],
+\ { 'width': [], 'ondblclick': [], 'size': [], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'align': ['left', 'center', 'right'], 'style': [], 'onmousemove': [], 'onmouseout': [], 'noshade': ['BOOL'], 'onmousedown': [], 'onkeypress': [], 'onclick': [], 'title': [], 'class': []}
+\ ],
+\ 'html': [
+\ ['head', 'frameset'],
+\ { 'xmlns': ['http://www.w3.org/1999/xhtml'], 'dir': ['ltr', 'rtl'], 'id': [], 'lang': [], 'xml:lang': []}
+\ ],
+\ 'frameset': [
+\ ['frameset', 'frame', 'noframes'],
+\ { 'rows': [], 'cols': [], 'id': [], 'style': [], 'onunload': [], 'onload': [], 'class': [], 'title': []}
+\ ],
+\ 'frame': [
+\ [],
+\ { 'scrolling': ['auto', 'yes', 'no', 'auto'], 'noresize': ['BOOL'], 'marginwidth': [], 'id': [], 'marginheight': [], 'longdesc': [], 'src': [], 'style': [], 'name': [], 'frameborder': ['1', '0'], 'title': [], 'class': []}
+\ ],
+\ 'i': [
+\ ['tt', 'i', 'b', 'u', 's', 'strike', 'big', 'small', 'em', 'strong', 'dfn', 'code', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'a', 'img', 'applet', 'object', 'font', 'basefont', 'br', 'script', 'map', 'q', 'sub', 'sup', 'span', 'bdo', 'iframe', 'input', 'select', 'textarea', 'label', 'button'],
+\ { 'ondblclick': [], 'dir': ['ltr', 'rtl'], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'style': [], 'onmousemove': [], 'onmouseout': [], 'onmousedown': [], 'onkeypress': [], 'onclick': [], 'title': [], 'class': []}
+\ ],
+\ 'iframe': [
+\ ['p', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'ul', 'ol', 'dir', 'menu', 'pre', 'dl', 'div', 'center', 'noscript', 'noframes', 'blockquote', 'form', 'isindex', 'hr', 'table', 'fieldset', 'address', 'tt', 'i', 'b', 'u', 's', 'strike', 'big', 'small', 'em', 'strong', 'dfn', 'code', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'a', 'img', 'applet', 'object', 'font', 'basefont', 'br', 'script', 'map', 'q', 'sub', 'sup', 'span', 'bdo', 'iframe', 'input', 'select', 'textarea', 'label', 'button'],
+\ { 'width': [], 'scrolling': ['auto', 'yes', 'no', 'auto'], 'marginwidth': [], 'id': [], 'marginheight': [], 'align': ['top', 'middle', 'bottom', 'left', 'right'], 'longdesc': [], 'src': [], 'style': [], 'name': [], 'height': [], 'frameborder': ['1', '0'], 'title': [], 'class': []}
+\ ],
+\ 'img': [
+\ [],
+\ { 'width': [], 'usemap': [], 'ismap': ['BOOL'], 'ondblclick': [], 'dir': ['ltr', 'rtl'], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'vspace': [], 'onmouseover': [], 'alt': [], 'lang': [], 'align': ['top', 'middle', 'bottom', 'left', 'right'], 'src': [], 'longdesc': [], 'onmouseout': [], 'onmousemove': [], 'style': [], 'height': [], 'border': [], 'hspace': [], 'onkeypress': [], 'onmousedown': [], 'class': [], 'title': [], 'onclick': []}
+\ ],
+\ 'input': [
+\ [],
+\ { 'ondblclick': [], 'onkeydown': [], 'readonly': ['BOOL'], 'onchange': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'align': ['top', 'middle', 'bottom', 'left', 'right'], 'value': [], 'src': [], 'name': [], 'checked': ['BOOL'], 'onkeypress': [], 'onmousedown': [], 'type': ['TEXT', 'PASSWORD', 'CHECKBOX', 'RADIO', 'SUBMIT', 'RESET', 'FILE', 'IMAGE', 'BUTTON'], 'class': [], 'title': [], 'onclick': [], 'accesskey': [], 'disabled': ['BOOL'], 'usemap': [], 'dir': ['ltr', 'rtl'], 'size': [], 'onblur': [], 'onfocus': [], 'maxlength': [], 'onselect': [], 'accept': [], 'alt': [], 'tabindex': [], 'style': [], 'onmousemove': [], 'onmouseout': []}
+\ ],
+\ 'ins': [
+\ ['p', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'ul', 'ol', 'dir', 'menu', 'pre', 'dl', 'div', 'center', 'noscript', 'noframes', 'blockquote', 'form', 'isindex', 'hr', 'table', 'fieldset', 'address', 'tt', 'i', 'b', 'u', 's', 'strike', 'big', 'small', 'em', 'strong', 'dfn', 'code', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'a', 'img', 'applet', 'object', 'font', 'basefont', 'br', 'script', 'map', 'q', 'sub', 'sup', 'span', 'bdo', 'iframe', 'input', 'select', 'textarea', 'label', 'button'],
+\ { 'ondblclick': [], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'onkeypress': [], 'onmousedown': [], 'class': [], 'title': [], 'onclick': [], 'dir': ['ltr', 'rtl'], 'datetime': [], 'cite': [], 'onmouseout': [], 'onmousemove': [], 'style': []}
+\ ],
+\ 'isindex': [
+\ [],
+\ { 'id': [], 'lang': [], 'prompt': [], 'class': [], 'title': [], 'dir': ['ltr', 'rtl'], 'style': []}
+\ ],
+\ 'kbd': [
+\ ['tt', 'i', 'b', 'u', 's', 'strike', 'big', 'small', 'em', 'strong', 'dfn', 'code', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'a', 'img', 'applet', 'object', 'font', 'basefont', 'br', 'script', 'map', 'q', 'sub', 'sup', 'span', 'bdo', 'iframe', 'input', 'select', 'textarea', 'label', 'button'],
+\ { 'ondblclick': [], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'onmousedown': [], 'onkeypress': [], 'onclick': [], 'title': [], 'class': [], 'dir': ['ltr', 'rtl'], 'style': [], 'onmousemove': [], 'onmouseout': []}
+\ ],
+\ 'label': [
+\ ['tt', 'i', 'b', 'u', 's', 'strike', 'big', 'small', 'em', 'strong', 'dfn', 'code', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'a', 'img', 'applet', 'object', 'font', 'basefont', 'br', 'script', 'map', 'q', 'sub', 'sup', 'span', 'bdo', 'iframe', 'input', 'select', 'textarea', 'button'],
+\ { 'ondblclick': [], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'for': [], 'onkeypress': [], 'onmousedown': [], 'class': [], 'title': [], 'onclick': [], 'accesskey': [], 'dir': ['ltr', 'rtl'], 'onblur': [], 'onfocus': [], 'onmouseout': [], 'onmousemove': [], 'style': []}
+\ ],
+\ 'legend': [
+\ ['tt', 'i', 'b', 'u', 's', 'strike', 'big', 'small', 'em', 'strong', 'dfn', 'code', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'a', 'img', 'applet', 'object', 'font', 'basefont', 'br', 'script', 'map', 'q', 'sub', 'sup', 'span', 'bdo', 'iframe', 'input', 'select', 'textarea', 'label', 'button'],
+\ { 'ondblclick': [], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'align': ['top', 'bottom', 'left', 'right'], 'lang': [], 'onkeypress': [], 'onmousedown': [], 'class': [], 'title': [], 'onclick': [], 'accesskey': [], 'dir': ['ltr', 'rtl'], 'onmouseout': [], 'onmousemove': [], 'style': []}
+\ ],
+\ 'li': [
+\ ['p', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'ul', 'ol', 'dir', 'menu', 'pre', 'dl', 'div', 'center', 'noscript', 'noframes', 'blockquote', 'form', 'isindex', 'hr', 'table', 'fieldset', 'address', 'tt', 'i', 'b', 'u', 's', 'strike', 'big', 'small', 'em', 'strong', 'dfn', 'code', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'a', 'img', 'applet', 'object', 'font', 'basefont', 'br', 'script', 'map', 'q', 'sub', 'sup', 'span', 'bdo', 'iframe', 'input', 'select', 'textarea', 'label', 'button'],
+\ { 'ondblclick': [], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'value': [], 'onkeypress': [], 'onmousedown': [], 'type': [], 'class': [], 'title': [], 'onclick': [], 'dir': ['ltr', 'rtl'], 'onmouseout': [], 'onmousemove': [], 'style': []}
+\ ],
+\ 'link': [
+\ [],
+\ { 'rel': [], 'ondblclick': [], 'onkeydown': [], 'target': [], 'onkeyup': [], 'href': [], 'media': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'charset': [], 'hreflang': [], 'onkeypress': [], 'onmousedown': [], 'rev': [], 'class': [], 'title': [], 'onclick': [], 'type': [], 'dir': ['ltr', 'rtl'], 'onmouseout': [], 'onmousemove': [], 'style': []}
+\ ],
+\ 'map': [
+\ ['p', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'ul', 'ol', 'dir', 'menu', 'pre', 'dl', 'div', 'center', 'noscript', 'noframes', 'blockquote', 'form', 'isindex', 'hr', 'table', 'fieldset', 'address', 'area'],
+\ { 'ondblclick': [], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'name': [], 'onkeypress': [], 'onmousedown': [], 'class': [], 'title': [], 'onclick': [], 'dir': ['ltr', 'rtl'], 'onmouseout': [], 'onmousemove': [], 'style': []}
+\ ],
+\ 'menu': [
+\ ['li'],
+\ { 'ondblclick': [], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'compact': ['BOOL'], 'onmouseover': [], 'lang': [], 'onmousedown': [], 'onkeypress': [], 'onclick': [], 'title': [], 'class': [], 'dir': ['ltr', 'rtl'], 'style': [], 'onmousemove': [], 'onmouseout': []}
+\ ],
+\ 'meta': [
+\ [],
+\ { 'http-equiv': [], 'content': [], 'lang': [], 'name': [], 'scheme': [], 'dir': ['ltr', 'rtl']}
+\ ],
+\ 'noframes': [
+\ ['p', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'ul', 'ol', 'dir', 'menu', 'pre', 'dl', 'div', 'center', 'noscript', 'noframes', 'blockquote', 'form', 'isindex', 'hr', 'table', 'fieldset', 'address', 'tt', 'i', 'b', 'u', 's', 'strike', 'big', 'small', 'em', 'strong', 'dfn', 'code', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'a', 'img', 'applet', 'object', 'font', 'basefont', 'br', 'script', 'map', 'q', 'sub', 'sup', 'span', 'bdo', 'iframe', 'input', 'select', 'textarea', 'label', 'button'],
+\ { 'ondblclick': [], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'onmousedown': [], 'onkeypress': [], 'onclick': [], 'title': [], 'class': [], 'dir': ['ltr', 'rtl'], 'style': [], 'onmousemove': [], 'onmouseout': []}
+\ ],
+\ 'noscript': [
+\ ['p', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'ul', 'ol', 'dir', 'menu', 'pre', 'dl', 'div', 'center', 'noscript', 'noframes', 'blockquote', 'form', 'isindex', 'hr', 'table', 'fieldset', 'address', 'tt', 'i', 'b', 'u', 's', 'strike', 'big', 'small', 'em', 'strong', 'dfn', 'code', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'a', 'img', 'applet', 'object', 'font', 'basefont', 'br', 'script', 'map', 'q', 'sub', 'sup', 'span', 'bdo', 'iframe', 'input', 'select', 'textarea', 'label', 'button'],
+\ { 'ondblclick': [], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'onmousedown': [], 'onkeypress': [], 'onclick': [], 'title': [], 'class': [], 'dir': ['ltr', 'rtl'], 'style': [], 'onmousemove': [], 'onmouseout': []}
+\ ],
+\ 'object': [
+\ ['param', 'p', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'ul', 'ol', 'dir', 'menu', 'pre', 'dl', 'div', 'center', 'noscript', 'noframes', 'blockquote', 'form', 'isindex', 'hr', 'table', 'fieldset', 'address', 'tt', 'i', 'b', 'u', 's', 'strike', 'big', 'small', 'em', 'strong', 'dfn', 'code', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'a', 'img', 'applet', 'object', 'font', 'basefont', 'br', 'script', 'map', 'q', 'sub', 'sup', 'span', 'bdo', 'iframe', 'input', 'select', 'textarea', 'label', 'button'],
+\ { 'ondblclick': [], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'align': ['top', 'middle', 'bottom', 'left', 'right'], 'name': [], 'data': [], 'declare': ['BOOL'], 'onkeypress': [], 'onmousedown': [], 'class': [], 'title': [], 'onclick': [], 'type': [], 'width': [], 'usemap': [], 'dir': ['ltr', 'rtl'], 'vspace': [], 'tabindex': [], 'standby': [], 'archive': [], 'classid': [], 'style': [], 'onmousemove': [], 'onmouseout': [], 'height': [], 'border': [], 'codetype': [], 'hspace': [], 'codebase': []}
+\ ],
+\ 'ol': [
+\ ['li'],
+\ { 'ondblclick': [], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'compact': ['BOOL'], 'onmouseover': [], 'lang': [], 'onkeypress': [], 'onmousedown': [], 'type': [], 'class': [], 'title': [], 'onclick': [], 'start': [], 'dir': ['ltr', 'rtl'], 'onmouseout': [], 'onmousemove': [], 'style': []}
+\ ],
+\ 'optgroup': [
+\ ['option'],
+\ { 'ondblclick': [], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'onkeypress': [], 'onmousedown': [], 'class': [], 'title': [], 'onclick': [], 'label': [], 'disabled': ['BOOL'], 'dir': ['ltr', 'rtl'], 'onmouseout': [], 'onmousemove': [], 'style': []}
+\ ],
+\ 'option': [
+\ [''],
+\ { 'ondblclick': [], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'value': [], 'onkeypress': [], 'onmousedown': [], 'class': [], 'title': [], 'onclick': [], 'label': [], 'disabled': ['BOOL'], 'dir': ['ltr', 'rtl'], 'onmouseout': [], 'onmousemove': [], 'style': [], 'selected': ['BOOL']}
+\ ],
+\ 'p': [
+\ ['tt', 'i', 'b', 'u', 's', 'strike', 'big', 'small', 'em', 'strong', 'dfn', 'code', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'a', 'img', 'applet', 'object', 'font', 'basefont', 'br', 'script', 'map', 'q', 'sub', 'sup', 'span', 'bdo', 'iframe', 'input', 'select', 'textarea', 'label', 'button'],
+\ { 'ondblclick': [], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'align': ['left', 'center', 'right', 'justify'], 'lang': [], 'onkeypress': [], 'onmousedown': [], 'class': [], 'title': [], 'onclick': [], 'dir': ['ltr', 'rtl'], 'onmouseout': [], 'onmousemove': [], 'style': []}
+\ ],
+\ 'param': [
+\ [],
+\ { 'id': [], 'value': [], 'name': [], 'type': [], 'valuetype': ['DATA', 'REF', 'OBJECT']}
+\ ],
+\ 'pre': [
+\ ['tt', 'i', 'b', 'u', 's', 'strike', 'em', 'strong', 'dfn', 'code', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'a', 'br', 'script', 'map', 'q', 'span', 'bdo', 'iframe', 'input', 'select', 'textarea', 'label', 'button'],
+\ { 'ondblclick': [], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'onmousedown': [], 'onkeypress': [], 'onclick': [], 'title': [], 'class': [], 'width': [], 'dir': ['ltr', 'rtl'], 'style': [], 'onmousemove': [], 'onmouseout': []}
+\ ],
+\ 'q': [
+\ ['tt', 'i', 'b', 'u', 's', 'strike', 'big', 'small', 'em', 'strong', 'dfn', 'code', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'a', 'img', 'applet', 'object', 'font', 'basefont', 'br', 'script', 'map', 'q', 'sub', 'sup', 'span', 'bdo', 'iframe', 'input', 'select', 'textarea', 'label', 'button'],
+\ { 'ondblclick': [], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'onmousedown': [], 'onkeypress': [], 'onclick': [], 'title': [], 'class': [], 'dir': ['ltr', 'rtl'], 'cite': [], 'style': [], 'onmousemove': [], 'onmouseout': []}
+\ ],
+\ 's': [
+\ ['tt', 'i', 'b', 'u', 's', 'strike', 'big', 'small', 'em', 'strong', 'dfn', 'code', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'a', 'img', 'applet', 'object', 'font', 'basefont', 'br', 'script', 'map', 'q', 'sub', 'sup', 'span', 'bdo', 'iframe', 'input', 'select', 'textarea', 'label', 'button'],
+\ { 'ondblclick': [], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'onmousedown': [], 'onkeypress': [], 'onclick': [], 'title': [], 'class': [], 'dir': ['ltr', 'rtl'], 'style': [], 'onmousemove': [], 'onmouseout': []}
+\ ],
+\ 'samp': [
+\ ['tt', 'i', 'b', 'u', 's', 'strike', 'big', 'small', 'em', 'strong', 'dfn', 'code', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'a', 'img', 'applet', 'object', 'font', 'basefont', 'br', 'script', 'map', 'q', 'sub', 'sup', 'span', 'bdo', 'iframe', 'input', 'select', 'textarea', 'label', 'button'],
+\ { 'ondblclick': [], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'onmousedown': [], 'onkeypress': [], 'onclick': [], 'title': [], 'class': [], 'dir': ['ltr', 'rtl'], 'style': [], 'onmousemove': [], 'onmouseout': []}
+\ ],
+\ 'script': [
+\ [],
+\ { 'src': [], 'for': [], 'charset': [], 'event': [], 'type': [], 'defer': ['BOOL'], 'language': []}
+\ ],
+\ 'select': [
+\ ['optgroup', 'option'],
+\ { 'ondblclick': [], 'onkeydown': [], 'onchange': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'name': [], 'onkeypress': [], 'onmousedown': [], 'class': [], 'title': [], 'onclick': [], 'disabled': ['BOOL'], 'dir': ['ltr', 'rtl'], 'size': [], 'onblur': [], 'onfocus': [], 'tabindex': [], 'onmouseout': [], 'onmousemove': [], 'style': [], 'multiple': ['BOOL']}
+\ ],
+\ 'small': [
+\ ['tt', 'i', 'b', 'u', 's', 'strike', 'big', 'small', 'em', 'strong', 'dfn', 'code', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'a', 'img', 'applet', 'object', 'font', 'basefont', 'br', 'script', 'map', 'q', 'sub', 'sup', 'span', 'bdo', 'iframe', 'input', 'select', 'textarea', 'label', 'button'],
+\ { 'ondblclick': [], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'onmousedown': [], 'onkeypress': [], 'onclick': [], 'title': [], 'class': [], 'dir': ['ltr', 'rtl'], 'style': [], 'onmousemove': [], 'onmouseout': []}
+\ ],
+\ 'span': [
+\ ['tt', 'i', 'b', 'u', 's', 'strike', 'big', 'small', 'em', 'strong', 'dfn', 'code', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'a', 'img', 'applet', 'object', 'font', 'basefont', 'br', 'script', 'map', 'q', 'sub', 'sup', 'span', 'bdo', 'iframe', 'input', 'select', 'textarea', 'label', 'button'],
+\ { 'ondblclick': [], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'onmousedown': [], 'onkeypress': [], 'onclick': [], 'title': [], 'class': [], 'dir': ['ltr', 'rtl'], 'style': [], 'onmousemove': [], 'onmouseout': []}
+\ ],
+\ 'strike': [
+\ ['tt', 'i', 'b', 'u', 's', 'strike', 'big', 'small', 'em', 'strong', 'dfn', 'code', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'a', 'img', 'applet', 'object', 'font', 'basefont', 'br', 'script', 'map', 'q', 'sub', 'sup', 'span', 'bdo', 'iframe', 'input', 'select', 'textarea', 'label', 'button'],
+\ { 'ondblclick': [], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'onmousedown': [], 'onkeypress': [], 'onclick': [], 'title': [], 'class': [], 'dir': ['ltr', 'rtl'], 'style': [], 'onmousemove': [], 'onmouseout': []}
+\ ],
+\ 'strong': [
+\ ['tt', 'i', 'b', 'u', 's', 'strike', 'big', 'small', 'em', 'strong', 'dfn', 'code', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'a', 'img', 'applet', 'object', 'font', 'basefont', 'br', 'script', 'map', 'q', 'sub', 'sup', 'span', 'bdo', 'iframe', 'input', 'select', 'textarea', 'label', 'button'],
+\ { 'ondblclick': [], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'onmousedown': [], 'onkeypress': [], 'onclick': [], 'title': [], 'class': [], 'dir': ['ltr', 'rtl'], 'style': [], 'onmousemove': [], 'onmouseout': []}
+\ ],
+\ 'style': [
+\ [],
+\ { 'media': [], 'lang': [], 'type': [], 'title': [], 'dir': ['ltr', 'rtl']}
+\ ],
+\ 'sub': [
+\ ['tt', 'i', 'b', 'u', 's', 'strike', 'big', 'small', 'em', 'strong', 'dfn', 'code', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'a', 'img', 'applet', 'object', 'font', 'basefont', 'br', 'script', 'map', 'q', 'sub', 'sup', 'span', 'bdo', 'iframe', 'input', 'select', 'textarea', 'label', 'button'],
+\ { 'ondblclick': [], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'onmousedown': [], 'onkeypress': [], 'onclick': [], 'title': [], 'class': [], 'dir': ['ltr', 'rtl'], 'style': [], 'onmousemove': [], 'onmouseout': []}
+\ ],
+\ 'sup': [
+\ ['tt', 'i', 'b', 'u', 's', 'strike', 'big', 'small', 'em', 'strong', 'dfn', 'code', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'a', 'img', 'applet', 'object', 'font', 'basefont', 'br', 'script', 'map', 'q', 'sub', 'sup', 'span', 'bdo', 'iframe', 'input', 'select', 'textarea', 'label', 'button'],
+\ { 'ondblclick': [], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'onmousedown': [], 'onkeypress': [], 'onclick': [], 'title': [], 'class': [], 'dir': ['ltr', 'rtl'], 'style': [], 'onmousemove': [], 'onmouseout': []}
+\ ],
+\ 'table': [
+\ ['caption', 'col', 'colgroup', 'thead', 'tfoot', 'tbody'],
+\ { 'ondblclick': [], 'onkeydown': [], 'onkeyup': [], 'datapagesize': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'align': ['left', 'center', 'right'], 'onkeypress': [], 'onmousedown': [], 'class': [], 'title': [], 'onclick': [], 'width': [], 'frame': ['void', 'above', 'below', 'hsides', 'lhs', 'rhs', 'vsides', 'box', 'border'], 'rules': ['none', 'groups', 'rows', 'cols', 'all'], 'dir': ['ltr', 'rtl'], 'summary': [], 'bgcolor': [], 'cellspacing': [], 'onmouseout': [], 'onmousemove': [], 'style': [], 'border': [], 'cellpadding': []}
+\ ],
+\ 'tbody': [
+\ ['tr'],
+\ { 'ondblclick': [], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'align': ['left', 'center', 'right', 'justify', 'char'], 'lang': [], 'valign': ['top', 'middle', 'bottom', 'baseline'], 'onkeypress': [], 'onmousedown': [], 'class': [], 'title': [], 'onclick': [], 'dir': ['ltr', 'rtl'], 'charoff': [], 'onmouseout': [], 'onmousemove': [], 'style': [], 'char': []}
+\ ],
+\ 'td': [
+\ ['p', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'ul', 'ol', 'dir', 'menu', 'pre', 'dl', 'div', 'center', 'noscript', 'noframes', 'blockquote', 'form', 'isindex', 'hr', 'table', 'fieldset', 'address', 'tt', 'i', 'b', 'u', 's', 'strike', 'big', 'small', 'em', 'strong', 'dfn', 'code', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'a', 'img', 'applet', 'object', 'font', 'basefont', 'br', 'script', 'map', 'q', 'sub', 'sup', 'span', 'bdo', 'iframe', 'input', 'select', 'textarea', 'label', 'button'],
+\ { 'ondblclick': [], 'axis': [], 'onkeydown': [], 'abbr': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'scope': ['row', 'col', 'rowgroup', 'colgroup'], 'onmouseover': [], 'lang': [], 'align': ['left', 'center', 'right', 'justify', 'char'], 'valign': ['top', 'middle', 'bottom', 'baseline'], 'onkeypress': [], 'onmousedown': [], 'class': [], 'title': [], 'onclick': [], 'width': [], 'headers': [], 'nowrap': ['BOOL'], 'dir': ['ltr', 'rtl'], 'rowspan': ['1'], 'colspan': ['1'], 'bgcolor': [], 'charoff': [], 'onmouseout': [], 'onmousemove': [], 'style': [], 'height': [], 'char': []}
+\ ],
+\ 'textarea': [
+\ [''],
+\ { 'ondblclick': [], 'cols': [], 'onkeydown': [], 'readonly': ['BOOL'], 'onchange': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'name': [], 'onkeypress': [], 'onmousedown': [], 'class': [], 'title': [], 'onclick': [], 'accesskey': [], 'disabled': ['BOOL'], 'rows': [], 'dir': ['ltr', 'rtl'], 'onblur': [], 'onfocus': [], 'onselect': [], 'tabindex': [], 'onmouseout': [], 'onmousemove': [], 'style': []}
+\ ],
+\ 'tfoot': [
+\ ['tr'],
+\ { 'ondblclick': [], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'align': ['left', 'center', 'right', 'justify', 'char'], 'lang': [], 'valign': ['top', 'middle', 'bottom', 'baseline'], 'onkeypress': [], 'onmousedown': [], 'class': [], 'title': [], 'onclick': [], 'dir': ['ltr', 'rtl'], 'charoff': [], 'onmouseout': [], 'onmousemove': [], 'style': [], 'char': []}
+\ ],
+\ 'th': [
+\ ['p', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'ul', 'ol', 'dir', 'menu', 'pre', 'dl', 'div', 'center', 'noscript', 'noframes', 'blockquote', 'form', 'isindex', 'hr', 'table', 'fieldset', 'address', 'tt', 'i', 'b', 'u', 's', 'strike', 'big', 'small', 'em', 'strong', 'dfn', 'code', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'a', 'img', 'applet', 'object', 'font', 'basefont', 'br', 'script', 'map', 'q', 'sub', 'sup', 'span', 'bdo', 'iframe', 'input', 'select', 'textarea', 'label', 'button'],
+\ { 'ondblclick': [], 'axis': [], 'onkeydown': [], 'abbr': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'scope': ['row', 'col', 'rowgroup', 'colgroup'], 'onmouseover': [], 'lang': [], 'align': ['left', 'center', 'right', 'justify', 'char'], 'valign': ['top', 'middle', 'bottom', 'baseline'], 'onkeypress': [], 'onmousedown': [], 'class': [], 'title': [], 'onclick': [], 'width': [], 'headers': [], 'nowrap': ['BOOL'], 'dir': ['ltr', 'rtl'], 'rowspan': ['1'], 'colspan': ['1'], 'bgcolor': [], 'charoff': [], 'onmouseout': [], 'onmousemove': [], 'style': [], 'height': [], 'char': []}
+\ ],
+\ 'thead': [
+\ ['tr'],
+\ { 'ondblclick': [], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'align': ['left', 'center', 'right', 'justify', 'char'], 'lang': [], 'valign': ['top', 'middle', 'bottom', 'baseline'], 'onkeypress': [], 'onmousedown': [], 'class': [], 'title': [], 'onclick': [], 'dir': ['ltr', 'rtl'], 'charoff': [], 'onmouseout': [], 'onmousemove': [], 'style': [], 'char': []}
+\ ],
+\ 'title': [
+\ [''],
+\ { 'lang': [], 'dir': ['ltr', 'rtl']}
+\ ],
+\ 'tr': [
+\ ['th', 'td'],
+\ { 'ondblclick': [], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'align': ['left', 'center', 'right', 'justify', 'char'], 'lang': [], 'valign': ['top', 'middle', 'bottom', 'baseline'], 'onkeypress': [], 'onmousedown': [], 'class': [], 'title': [], 'onclick': [], 'dir': ['ltr', 'rtl'], 'bgcolor': [], 'charoff': [], 'onmouseout': [], 'onmousemove': [], 'style': [], 'char': []}
+\ ],
+\ 'tt': [
+\ ['tt', 'i', 'b', 'u', 's', 'strike', 'big', 'small', 'em', 'strong', 'dfn', 'code', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'a', 'img', 'applet', 'object', 'font', 'basefont', 'br', 'script', 'map', 'q', 'sub', 'sup', 'span', 'bdo', 'iframe', 'input', 'select', 'textarea', 'label', 'button'],
+\ { 'ondblclick': [], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'onmousedown': [], 'onkeypress': [], 'onclick': [], 'title': [], 'class': [], 'dir': ['ltr', 'rtl'], 'style': [], 'onmousemove': [], 'onmouseout': []}
+\ ],
+\ 'u': [
+\ ['tt', 'i', 'b', 'u', 's', 'strike', 'big', 'small', 'em', 'strong', 'dfn', 'code', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'a', 'img', 'applet', 'object', 'font', 'basefont', 'br', 'script', 'map', 'q', 'sub', 'sup', 'span', 'bdo', 'iframe', 'input', 'select', 'textarea', 'label', 'button'],
+\ { 'ondblclick': [], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'onmousedown': [], 'onkeypress': [], 'onclick': [], 'title': [], 'class': [], 'dir': ['ltr', 'rtl'], 'style': [], 'onmousemove': [], 'onmouseout': []}
+\ ],
+\ 'ul': [
+\ ['li'],
+\ { 'ondblclick': [], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'compact': ['BOOL'], 'onmouseover': [], 'lang': [], 'onkeypress': [], 'onmousedown': [], 'type': ['disc', 'square', 'circle'], 'class': [], 'title': [], 'onclick': [], 'dir': ['ltr', 'rtl'], 'onmouseout': [], 'onmousemove': [], 'style': []}
+\ ],
+\ 'var': [
+\ ['tt', 'i', 'b', 'u', 's', 'strike', 'big', 'small', 'em', 'strong', 'dfn', 'code', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'a', 'img', 'applet', 'object', 'font', 'basefont', 'br', 'script', 'map', 'q', 'sub', 'sup', 'span', 'bdo', 'iframe', 'input', 'select', 'textarea', 'label', 'button'],
+\ { 'ondblclick': [], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'onmousedown': [], 'onkeypress': [], 'onclick': [], 'title': [], 'class': [], 'dir': ['ltr', 'rtl'], 'style': [], 'onmousemove': [], 'onmouseout': []}
+\ ],
+\ 'vimxmlattrinfo' : {
+\ 'accept' : ['ContentType', ''],
+\ 'accesskey' : ['Character', ''],
+\ 'action' : ['*URI', ''],
+\ 'align' : ['String', ''],
+\ 'alt' : ['*Text', ''],
+\ 'archive' : ['UriList', ''],
+\ 'axis' : ['CDATA', ''],
+\ 'border' : ['Pixels', ''],
+\ 'cellpadding' : ['Length', ''],
+\ 'cellspacing' : ['Length', ''],
+\ 'char' : ['Character', ''],
+\ 'charoff' : ['Length', ''],
+\ 'charset' : ['LangCode', ''],
+\ 'checked' : ['Bool', ''],
+\ 'class' : ['CDATA', ''],
+\ 'codetype' : ['ContentType', ''],
+\ 'cols' : ['*Number', ''],
+\ 'colspan' : ['Number', ''],
+\ 'content' : ['*CDATA', ''],
+\ 'coords' : ['Coords', ''],
+\ 'data' : ['URI', ''],
+\ 'datetime' : ['DateTime', ''],
+\ 'declare' : ['Bool', ''],
+\ 'defer' : ['Bool', ''],
+\ 'dir' : ['String', ''],
+\ 'disabled' : ['Bool', ''],
+\ 'enctype' : ['ContentType', ''],
+\ 'for' : ['ID', ''],
+\ 'headers' : ['IDREFS', ''],
+\ 'height' : ['Number', ''],
+\ 'href' : ['*URI', ''],
+\ 'hreflang' : ['LangCode', ''],
+\ 'id' : ['ID', ''],
+\ 'ismap' : ['Bool', ''],
+\ 'label' : ['*Text', ''],
+\ 'lang' : ['LangCode', ''],
+\ 'longdesc' : ['URI', ''],
+\ 'maxlength' : ['Number', ''],
+\ 'media' : ['MediaDesc', ''],
+\ 'method' : ['String', ''],
+\ 'multiple' : ['Bool', ''],
+\ 'name' : ['CDATA', ''],
+\ 'nohref' : ['Bool', ''],
+\ 'onblur' : ['Script', ''],
+\ 'onchange' : ['Script', ''],
+\ 'onclick' : ['Script', ''],
+\ 'ondblclick' : ['Script', ''],
+\ 'onfocus' : ['Script', ''],
+\ 'onkeydown' : ['Script', ''],
+\ 'onkeypress' : ['Script', ''],
+\ 'onkeyup' : ['Script', ''],
+\ 'onload' : ['Script', ''],
+\ 'onmousedown' : ['Script', ''],
+\ 'onmousemove' : ['Script', ''],
+\ 'onmouseout' : ['Script', ''],
+\ 'onmouseover' : ['Script', ''],
+\ 'onmouseup' : ['Script', ''],
+\ 'onreset' : ['Script', ''],
+\ 'onselect' : ['Script', ''],
+\ 'onsubmit' : ['Script', ''],
+\ 'onunload' : ['Script', ''],
+\ 'profile' : ['URI', ''],
+\ 'readonly' : ['Bool', ''],
+\ 'rel' : ['LinkTypes', ''],
+\ 'rev' : ['LinkTypes', ''],
+\ 'rows' : ['*Number', ''],
+\ 'rules' : ['String', ''],
+\ 'scheme' : ['CDATA', ''],
+\ 'selected' : ['Bool', ''],
+\ 'shape' : ['Shape', ''],
+\ 'size' : ['CDATA', ''],
+\ 'span' : ['Number', ''],
+\ 'src' : ['*URI', ''],
+\ 'standby' : ['Text', ''],
+\ 'style' : ['StyleSheet', ''],
+\ 'summary' : ['*Text', ''],
+\ 'tabindex' : ['Number', ''],
+\ 'title' : ['Text', ''],
+\ 'type' : ['*ContentType', ''],
+\ 'usemap' : ['URI', ''],
+\ 'valign' : ['String', ''],
+\ 'valuetype' : ['String', ''],
+\ 'width' : ['Number', ''],
+\ 'xmlns' : ['URI', '']
+\ },
+\ 'vimxmltaginfo': {
+\ 'area': ['/>', ''],
+\ 'base': ['/>', ''],
+\ 'basefont': ['/>', ''],
+\ 'br': ['/>', ''],
+\ 'col': ['/>', ''],
+\ 'hr': ['/>', ''],
+\ 'img': ['/>', ''],
+\ 'input': ['/>', ''],
+\ 'isindex': ['/>', ''],
+\ 'link': ['/>', ''],
+\ 'meta': ['/>', ''],
+\ 'param': ['/>', ''],
+\ }
+\ }
+" vim:ft=vim:ff=unix
--- /dev/null
+++ b/lib/vimfiles/autoload/xml/html40s.vim
@@ -1,0 +1,411 @@
+let g:xmldata_html40s = {
+\ 'vimxmlentities': ['AElig', 'Aacute', 'Acirc', 'Agrave', 'Alpha', 'Aring', 'Atilde', 'Auml', 'Beta', 'Ccedil', 'Chi', 'Dagger', 'Delta', 'ETH', 'Eacute', 'Ecirc', 'Egrave', 'Epsilon', 'Eta', 'Euml', 'Gamma', 'Iacute', 'Icirc', 'Igrave', 'Iota', 'Iuml', 'Kappa', 'Lambda', 'Mu', 'Ntilde', 'Nu', 'OElig', 'Oacute', 'Ocirc', 'Ograve', 'Omega', 'Omicron', 'Oslash', 'Otilde', 'Ouml', 'Phi', 'Pi', 'Prime', 'Psi', 'Rho', 'Scaron', 'Sigma', 'THORN', 'Tau', 'Theta', 'Uacute', 'Ucirc', 'Ugrave', 'Upsilon', 'Uuml', 'Xi', 'Yacute', 'Yuml', 'Zeta', 'aacute', 'acirc', 'acute', 'aelig', 'agrave', 'alefsym', 'alpha', 'amp', 'and', 'ang', 'apos', 'aring', 'asymp', 'atilde', 'auml', 'bdquo', 'beta', 'brvbar', 'bull', 'cap', 'ccedil', 'cedil', 'cent', 'chi', 'circ', 'clubs', 'cong', 'copy', 'crarr', 'cup', 'curren', 'dArr', 'dagger', 'darr', 'deg', 'delta', 'diams', 'divide', 'eacute', 'ecirc', 'egrave', 'empty', 'emsp', 'ensp', 'epsilon', 'equiv', 'eta', 'eth', 'euml', 'euro', 'exist', 'fnof', 'forall', 'frac12', 'frac14', 'frac34', 'frasl', 'gamma', 'ge', 'gt', 'hArr', 'harr', 'hearts', 'hellip', 'iacute', 'icirc', 'iexcl', 'igrave', 'image', 'infin', 'int', 'iota', 'iquest', 'isin', 'iuml', 'kappa', 'lArr', 'lambda', 'lang', 'laquo', 'larr', 'lceil', 'ldquo', 'le', 'lfloor', 'lowast', 'loz', 'lrm', 'lsaquo', 'lsquo', 'lt', 'macr', 'mdash', 'micro', 'middot', 'minus', 'mu', 'nabla', 'nbsp', 'ndash', 'ne', 'ni', 'not', 'notin', 'nsub', 'ntilde', 'nu', 'oacute', 'ocirc', 'oelig', 'ograve', 'oline', 'omega', 'omicron', 'oplus', 'or', 'ordf', 'ordm', 'oslash', 'otilde', 'otimes', 'ouml', 'para', 'part', 'permil', 'perp', 'phi', 'pi', 'piv', 'plusmn', 'pound', 'prime', 'prod', 'prop', 'psi', 'quot', 'rArr', 'radic', 'rang', 'raquo', 'rarr', 'rceil', 'rdquo', 'real', 'reg', 'rfloor', 'rho', 'rlm', 'rsaquo', 'rsquo', 'sbquo', 'scaron', 'sdot', 'sect', 'shy', 'sigma', 'sigmaf', 'sim', 'spades', 'sub', 'sube', 'sum', 'sup', 'sup1', 'sup2', 'sup3', 'supe', 'szlig', 'tau', 'there4', 'theta', 'thetasym', 'thinsp', 'thorn', 'tilde', 'times', 'trade', 'uArr', 'uacute', 'uarr', 'ucirc', 'ugrave', 'uml', 'upsih', 'upsilon', 'uuml', 'weierp', 'xi', 'yacute', 'yen', 'yuml', 'zeta', 'zwj', 'zwnj'],
+\ 'vimxmlroot': ['html'],
+\ 'a': [
+\ ['tt', 'i', 'b', 'big', 'small', 'em', 'strong', 'dfn', 'code', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'img', 'object', 'br', 'script', 'map', 'q', 'sub', 'sup', 'span', 'bdo', 'input', 'select', 'textarea', 'label', 'button'],
+\ { 'rel': [], 'accesskey': [], 'coords': [], 'ondblclick': [], 'dir': ['ltr', 'rtl'], 'onblur': [], 'onfocus': [], 'onkeydown': [], 'onkeyup': [], 'href': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'tabindex': [], 'lang': [], 'onmouseout': [], 'onmousemove': [], 'name': [], 'style': [], 'charset': [], 'hreflang': [], 'onkeypress': [], 'onmousedown': [], 'rev': [], 'class': [], 'title': [], 'onclick': [], 'type': [], 'shape': ['rect', 'circle', 'poly', 'default']}
+\ ],
+\ 'abbr': [
+\ ['tt', 'i', 'b', 'big', 'small', 'em', 'strong', 'dfn', 'code', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'a', 'img', 'object', 'br', 'script', 'map', 'q', 'sub', 'sup', 'span', 'bdo', 'input', 'select', 'textarea', 'label', 'button'],
+\ { 'ondblclick': [], 'dir': ['ltr', 'rtl'], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'style': [], 'onmousemove': [], 'onmouseout': [], 'onmousedown': [], 'onkeypress': [], 'onclick': [], 'title': [], 'class': []}
+\ ],
+\ 'acronym': [
+\ ['tt', 'i', 'b', 'big', 'small', 'em', 'strong', 'dfn', 'code', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'a', 'img', 'object', 'br', 'script', 'map', 'q', 'sub', 'sup', 'span', 'bdo', 'input', 'select', 'textarea', 'label', 'button'],
+\ { 'ondblclick': [], 'dir': ['ltr', 'rtl'], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'style': [], 'onmousemove': [], 'onmouseout': [], 'onmousedown': [], 'onkeypress': [], 'onclick': [], 'title': [], 'class': []}
+\ ],
+\ 'address': [
+\ ['tt', 'i', 'b', 'big', 'small', 'em', 'strong', 'dfn', 'code', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'a', 'img', 'object', 'br', 'script', 'map', 'q', 'sub', 'sup', 'span', 'bdo', 'input', 'select', 'textarea', 'label', 'button'],
+\ { 'ondblclick': [], 'dir': ['ltr', 'rtl'], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'style': [], 'onmousemove': [], 'onmouseout': [], 'onmousedown': [], 'onkeypress': [], 'onclick': [], 'title': [], 'class': []}
+\ ],
+\ 'area': [
+\ [],
+\ { 'accesskey': [], 'coords': [], 'ondblclick': [], 'dir': ['ltr', 'rtl'], 'onblur': [], 'onkeydown': [], 'nohref': ['BOOL'], 'onfocus': [], 'onkeyup': [], 'href': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'alt': [], 'tabindex': [], 'onmouseout': [], 'onmousemove': [], 'style': [], 'onkeypress': [], 'onmousedown': [], 'shape': ['rect', 'circle', 'poly', 'default'], 'class': [], 'title': [], 'onclick': []}
+\ ],
+\ 'b': [
+\ ['tt', 'i', 'b', 'big', 'small', 'em', 'strong', 'dfn', 'code', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'a', 'img', 'object', 'br', 'script', 'map', 'q', 'sub', 'sup', 'span', 'bdo', 'input', 'select', 'textarea', 'label', 'button'],
+\ { 'ondblclick': [], 'dir': ['ltr', 'rtl'], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'style': [], 'onmousemove': [], 'onmouseout': [], 'onmousedown': [], 'onkeypress': [], 'onclick': [], 'title': [], 'class': []}
+\ ],
+\ 'base': [
+\ [],
+\ { 'href': []}
+\ ],
+\ 'bdo': [
+\ ['tt', 'i', 'b', 'big', 'small', 'em', 'strong', 'dfn', 'code', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'a', 'img', 'object', 'br', 'script', 'map', 'q', 'sub', 'sup', 'span', 'bdo', 'input', 'select', 'textarea', 'label', 'button'],
+\ { 'dir': ['ltr', 'rtl'], 'id': [], 'lang': [], 'style': [], 'class': [], 'title': []}
+\ ],
+\ 'big': [
+\ ['tt', 'i', 'b', 'big', 'small', 'em', 'strong', 'dfn', 'code', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'a', 'img', 'object', 'br', 'script', 'map', 'q', 'sub', 'sup', 'span', 'bdo', 'input', 'select', 'textarea', 'label', 'button'],
+\ { 'ondblclick': [], 'dir': ['ltr', 'rtl'], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'style': [], 'onmousemove': [], 'onmouseout': [], 'onmousedown': [], 'onkeypress': [], 'onclick': [], 'title': [], 'class': []}
+\ ],
+\ 'blockquote': [
+\ ['p', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'ul', 'ol', 'pre', 'dl', 'div', 'noscript', 'blockquote', 'form', 'hr', 'table', 'fieldset', 'address', 'script'],
+\ { 'ondblclick': [], 'dir': ['ltr', 'rtl'], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'cite': [], 'onmouseover': [], 'lang': [], 'style': [], 'onmousemove': [], 'onmouseout': [], 'onmousedown': [], 'onkeypress': [], 'onclick': [], 'title': [], 'class': []}
+\ ],
+\ 'body': [
+\ ['p', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'ul', 'ol', 'pre', 'dl', 'div', 'noscript', 'blockquote', 'form', 'hr', 'table', 'fieldset', 'address', 'script', 'ins', 'del'],
+\ { 'ondblclick': [], 'dir': ['ltr', 'rtl'], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'onmouseout': [], 'onmousemove': [], 'style': [], 'onunload': [], 'onkeypress': [], 'onmousedown': [], 'onload': [], 'class': [], 'title': [], 'onclick': []}
+\ ],
+\ 'br': [
+\ [],
+\ { 'id': [], 'style': [], 'class': [], 'title': []}
+\ ],
+\ 'button': [
+\ ['p', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'ul', 'ol', 'pre', 'dl', 'div', 'noscript', 'blockquote', 'hr', 'table', 'address', 'tt', 'i', 'b', 'big', 'small', 'em', 'strong', 'dfn', 'code', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'img', 'object', 'br', 'script', 'map', 'q', 'sub', 'sup', 'span', 'bdo'],
+\ { 'accesskey': [], 'disabled': ['BOOL'], 'ondblclick': [], 'dir': ['ltr', 'rtl'], 'onblur': [], 'onkeydown': [], 'onfocus': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'tabindex': [], 'value': [], 'name': [], 'onmouseout': [], 'onmousemove': [], 'style': [], 'onkeypress': [], 'onmousedown': [], 'class': [], 'title': [], 'onclick': [], 'type': ['submit', 'button', 'submit', 'reset']}
+\ ],
+\ 'caption': [
+\ ['tt', 'i', 'b', 'big', 'small', 'em', 'strong', 'dfn', 'code', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'a', 'img', 'object', 'br', 'script', 'map', 'q', 'sub', 'sup', 'span', 'bdo', 'input', 'select', 'textarea', 'label', 'button'],
+\ { 'ondblclick': [], 'dir': ['ltr', 'rtl'], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'style': [], 'onmousemove': [], 'onmouseout': [], 'onmousedown': [], 'onkeypress': [], 'onclick': [], 'title': [], 'class': []}
+\ ],
+\ 'cite': [
+\ ['tt', 'i', 'b', 'big', 'small', 'em', 'strong', 'dfn', 'code', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'a', 'img', 'object', 'br', 'script', 'map', 'q', 'sub', 'sup', 'span', 'bdo', 'input', 'select', 'textarea', 'label', 'button'],
+\ { 'ondblclick': [], 'dir': ['ltr', 'rtl'], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'style': [], 'onmousemove': [], 'onmouseout': [], 'onmousedown': [], 'onkeypress': [], 'onclick': [], 'title': [], 'class': []}
+\ ],
+\ 'code': [
+\ ['tt', 'i', 'b', 'big', 'small', 'em', 'strong', 'dfn', 'code', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'a', 'img', 'object', 'br', 'script', 'map', 'q', 'sub', 'sup', 'span', 'bdo', 'input', 'select', 'textarea', 'label', 'button'],
+\ { 'ondblclick': [], 'dir': ['ltr', 'rtl'], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'style': [], 'onmousemove': [], 'onmouseout': [], 'onmousedown': [], 'onkeypress': [], 'onclick': [], 'title': [], 'class': []}
+\ ],
+\ 'col': [
+\ [],
+\ { 'width': [], 'ondblclick': [], 'dir': ['ltr', 'rtl'], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'charoff': [], 'onmouseover': [], 'lang': [], 'align': ['left', 'center', 'right', 'justify', 'char'], 'valign': ['top', 'middle', 'bottom', 'baseline'], 'onmouseout': [], 'onmousemove': [], 'style': [], 'onkeypress': [], 'onmousedown': [], 'char': [], 'span': ['1'], 'class': [], 'title': [], 'onclick': []}
+\ ],
+\ 'colgroup': [
+\ ['col'],
+\ { 'width': [], 'ondblclick': [], 'dir': ['ltr', 'rtl'], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'charoff': [], 'onmouseover': [], 'lang': [], 'align': ['left', 'center', 'right', 'justify', 'char'], 'valign': ['top', 'middle', 'bottom', 'baseline'], 'onmouseout': [], 'onmousemove': [], 'style': [], 'onkeypress': [], 'onmousedown': [], 'char': [], 'span': ['1'], 'class': [], 'title': [], 'onclick': []}
+\ ],
+\ 'dd': [
+\ ['p', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'ul', 'ol', 'pre', 'dl', 'div', 'noscript', 'blockquote', 'form', 'hr', 'table', 'fieldset', 'address', 'tt', 'i', 'b', 'big', 'small', 'em', 'strong', 'dfn', 'code', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'a', 'img', 'object', 'br', 'script', 'map', 'q', 'sub', 'sup', 'span', 'bdo', 'input', 'select', 'textarea', 'label', 'button'],
+\ { 'ondblclick': [], 'dir': ['ltr', 'rtl'], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'style': [], 'onmousemove': [], 'onmouseout': [], 'onmousedown': [], 'onkeypress': [], 'onclick': [], 'title': [], 'class': []}
+\ ],
+\ 'del': [
+\ ['p', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'ul', 'ol', 'pre', 'dl', 'div', 'noscript', 'blockquote', 'form', 'hr', 'table', 'fieldset', 'address', 'tt', 'i', 'b', 'big', 'small', 'em', 'strong', 'dfn', 'code', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'a', 'img', 'object', 'br', 'script', 'map', 'q', 'sub', 'sup', 'span', 'bdo', 'input', 'select', 'textarea', 'label', 'button'],
+\ { 'ondblclick': [], 'dir': ['ltr', 'rtl'], 'datetime': [], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'cite': [], 'onmouseover': [], 'lang': [], 'onmouseout': [], 'onmousemove': [], 'style': [], 'onkeypress': [], 'onmousedown': [], 'class': [], 'title': [], 'onclick': []}
+\ ],
+\ 'dfn': [
+\ ['tt', 'i', 'b', 'big', 'small', 'em', 'strong', 'dfn', 'code', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'a', 'img', 'object', 'br', 'script', 'map', 'q', 'sub', 'sup', 'span', 'bdo', 'input', 'select', 'textarea', 'label', 'button'],
+\ { 'ondblclick': [], 'dir': ['ltr', 'rtl'], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'style': [], 'onmousemove': [], 'onmouseout': [], 'onmousedown': [], 'onkeypress': [], 'onclick': [], 'title': [], 'class': []}
+\ ],
+\ 'div': [
+\ ['p', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'ul', 'ol', 'pre', 'dl', 'div', 'noscript', 'blockquote', 'form', 'hr', 'table', 'fieldset', 'address', 'tt', 'i', 'b', 'big', 'small', 'em', 'strong', 'dfn', 'code', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'a', 'img', 'object', 'br', 'script', 'map', 'q', 'sub', 'sup', 'span', 'bdo', 'input', 'select', 'textarea', 'label', 'button'],
+\ { 'ondblclick': [], 'dir': ['ltr', 'rtl'], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'style': [], 'onmousemove': [], 'onmouseout': [], 'onmousedown': [], 'onkeypress': [], 'onclick': [], 'title': [], 'class': []}
+\ ],
+\ 'dl': [
+\ ['dt', 'dd'],
+\ { 'ondblclick': [], 'dir': ['ltr', 'rtl'], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'style': [], 'onmousemove': [], 'onmouseout': [], 'onmousedown': [], 'onkeypress': [], 'onclick': [], 'title': [], 'class': []}
+\ ],
+\ 'dt': [
+\ ['tt', 'i', 'b', 'big', 'small', 'em', 'strong', 'dfn', 'code', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'a', 'img', 'object', 'br', 'script', 'map', 'q', 'sub', 'sup', 'span', 'bdo', 'input', 'select', 'textarea', 'label', 'button'],
+\ { 'ondblclick': [], 'dir': ['ltr', 'rtl'], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'style': [], 'onmousemove': [], 'onmouseout': [], 'onmousedown': [], 'onkeypress': [], 'onclick': [], 'title': [], 'class': []}
+\ ],
+\ 'em': [
+\ ['tt', 'i', 'b', 'big', 'small', 'em', 'strong', 'dfn', 'code', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'a', 'img', 'object', 'br', 'script', 'map', 'q', 'sub', 'sup', 'span', 'bdo', 'input', 'select', 'textarea', 'label', 'button'],
+\ { 'ondblclick': [], 'dir': ['ltr', 'rtl'], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'style': [], 'onmousemove': [], 'onmouseout': [], 'onmousedown': [], 'onkeypress': [], 'onclick': [], 'title': [], 'class': []}
+\ ],
+\ 'fieldset': [
+\ ['legend', 'p', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'ul', 'ol', 'pre', 'dl', 'div', 'noscript', 'blockquote', 'form', 'hr', 'table', 'fieldset', 'address', 'tt', 'i', 'b', 'big', 'small', 'em', 'strong', 'dfn', 'code', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'a', 'img', 'object', 'br', 'script', 'map', 'q', 'sub', 'sup', 'span', 'bdo', 'input', 'select', 'textarea', 'label', 'button'],
+\ { 'ondblclick': [], 'dir': ['ltr', 'rtl'], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'style': [], 'onmousemove': [], 'onmouseout': [], 'onmousedown': [], 'onkeypress': [], 'onclick': [], 'title': [], 'class': []}
+\ ],
+\ 'form': [
+\ ['p', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'ul', 'ol', 'pre', 'dl', 'div', 'noscript', 'blockquote', 'hr', 'table', 'fieldset', 'address', 'script'],
+\ { 'enctype': ['application/x-www-form-urlencoded'], 'onsubmit': [], 'ondblclick': [], 'dir': ['ltr', 'rtl'], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'onreset': [], 'id': [], 'method': ['GET', 'POST'], 'onmouseover': [], 'lang': [], 'onmouseout': [], 'onmousemove': [], 'style': [], 'accept-charset': [], 'onkeypress': [], 'onmousedown': [], 'action': [], 'class': [], 'title': [], 'onclick': []}
+\ ],
+\ 'h1': [
+\ ['tt', 'i', 'b', 'big', 'small', 'em', 'strong', 'dfn', 'code', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'a', 'img', 'object', 'br', 'script', 'map', 'q', 'sub', 'sup', 'span', 'bdo', 'input', 'select', 'textarea', 'label', 'button'],
+\ { 'ondblclick': [], 'dir': ['ltr', 'rtl'], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'style': [], 'onmousemove': [], 'onmouseout': [], 'onmousedown': [], 'onkeypress': [], 'onclick': [], 'title': [], 'class': []}
+\ ],
+\ 'h2': [
+\ ['tt', 'i', 'b', 'big', 'small', 'em', 'strong', 'dfn', 'code', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'a', 'img', 'object', 'br', 'script', 'map', 'q', 'sub', 'sup', 'span', 'bdo', 'input', 'select', 'textarea', 'label', 'button'],
+\ { 'ondblclick': [], 'dir': ['ltr', 'rtl'], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'style': [], 'onmousemove': [], 'onmouseout': [], 'onmousedown': [], 'onkeypress': [], 'onclick': [], 'title': [], 'class': []}
+\ ],
+\ 'h3': [
+\ ['tt', 'i', 'b', 'big', 'small', 'em', 'strong', 'dfn', 'code', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'a', 'img', 'object', 'br', 'script', 'map', 'q', 'sub', 'sup', 'span', 'bdo', 'input', 'select', 'textarea', 'label', 'button'],
+\ { 'ondblclick': [], 'dir': ['ltr', 'rtl'], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'style': [], 'onmousemove': [], 'onmouseout': [], 'onmousedown': [], 'onkeypress': [], 'onclick': [], 'title': [], 'class': []}
+\ ],
+\ 'h4': [
+\ ['tt', 'i', 'b', 'big', 'small', 'em', 'strong', 'dfn', 'code', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'a', 'img', 'object', 'br', 'script', 'map', 'q', 'sub', 'sup', 'span', 'bdo', 'input', 'select', 'textarea', 'label', 'button'],
+\ { 'ondblclick': [], 'dir': ['ltr', 'rtl'], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'style': [], 'onmousemove': [], 'onmouseout': [], 'onmousedown': [], 'onkeypress': [], 'onclick': [], 'title': [], 'class': []}
+\ ],
+\ 'h5': [
+\ ['tt', 'i', 'b', 'big', 'small', 'em', 'strong', 'dfn', 'code', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'a', 'img', 'object', 'br', 'script', 'map', 'q', 'sub', 'sup', 'span', 'bdo', 'input', 'select', 'textarea', 'label', 'button'],
+\ { 'ondblclick': [], 'dir': ['ltr', 'rtl'], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'style': [], 'onmousemove': [], 'onmouseout': [], 'onmousedown': [], 'onkeypress': [], 'onclick': [], 'title': [], 'class': []}
+\ ],
+\ 'h6': [
+\ ['tt', 'i', 'b', 'big', 'small', 'em', 'strong', 'dfn', 'code', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'a', 'img', 'object', 'br', 'script', 'map', 'q', 'sub', 'sup', 'span', 'bdo', 'input', 'select', 'textarea', 'label', 'button'],
+\ { 'ondblclick': [], 'dir': ['ltr', 'rtl'], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'style': [], 'onmousemove': [], 'onmouseout': [], 'onmousedown': [], 'onkeypress': [], 'onclick': [], 'title': [], 'class': []}
+\ ],
+\ 'head': [
+\ ['title', 'base', 'script', 'style', 'meta', 'link', 'object'],
+\ { 'profile': [], 'dir': ['ltr', 'rtl'], 'lang': []}
+\ ],
+\ 'hr': [
+\ [],
+\ { 'ondblclick': [], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'style': [], 'onmousemove': [], 'onmouseout': [], 'onmousedown': [], 'onkeypress': [], 'onclick': [], 'title': [], 'class': []}
+\ ],
+\ 'html': [
+\ ['head', 'body'],
+\ { 'dir': ['ltr', 'rtl'], 'lang': []}
+\ ],
+\ 'i': [
+\ ['tt', 'i', 'b', 'big', 'small', 'em', 'strong', 'dfn', 'code', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'a', 'img', 'object', 'br', 'script', 'map', 'q', 'sub', 'sup', 'span', 'bdo', 'input', 'select', 'textarea', 'label', 'button'],
+\ { 'ondblclick': [], 'dir': ['ltr', 'rtl'], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'style': [], 'onmousemove': [], 'onmouseout': [], 'onmousedown': [], 'onkeypress': [], 'onclick': [], 'title': [], 'class': []}
+\ ],
+\ 'img': [
+\ [],
+\ { 'width': [], 'usemap': [], 'ismap': ['BOOL'], 'ondblclick': [], 'dir': ['ltr', 'rtl'], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'alt': [], 'lang': [], 'src': [], 'longdesc': [], 'onmouseout': [], 'onmousemove': [], 'style': [], 'height': [], 'onkeypress': [], 'onmousedown': [], 'class': [], 'title': [], 'onclick': []}
+\ ],
+\ 'input': [
+\ [],
+\ { 'ondblclick': [], 'onkeydown': [], 'readonly': ['BOOL'], 'onchange': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'value': [], 'src': [], 'name': [], 'checked': ['BOOL'], 'onkeypress': [], 'onmousedown': [], 'type': ['TEXT', 'PASSWORD', 'CHECKBOX', 'RADIO', 'SUBMIT', 'RESET', 'FILE', 'IMAGE', 'BUTTON'], 'class': [], 'title': [], 'onclick': [], 'accesskey': [], 'disabled': ['BOOL'], 'usemap': [], 'dir': ['ltr', 'rtl'], 'size': [], 'onblur': [], 'onfocus': [], 'maxlength': [], 'onselect': [], 'accept': [], 'alt': [], 'tabindex': [], 'style': [], 'onmousemove': [], 'onmouseout': []}
+\ ],
+\ 'ins': [
+\ ['p', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'ul', 'ol', 'pre', 'dl', 'div', 'noscript', 'blockquote', 'form', 'hr', 'table', 'fieldset', 'address', 'tt', 'i', 'b', 'big', 'small', 'em', 'strong', 'dfn', 'code', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'a', 'img', 'object', 'br', 'script', 'map', 'q', 'sub', 'sup', 'span', 'bdo', 'input', 'select', 'textarea', 'label', 'button'],
+\ { 'ondblclick': [], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'onkeypress': [], 'onmousedown': [], 'class': [], 'title': [], 'onclick': [], 'dir': ['ltr', 'rtl'], 'datetime': [], 'cite': [], 'onmouseout': [], 'onmousemove': [], 'style': []}
+\ ],
+\ 'kbd': [
+\ ['tt', 'i', 'b', 'big', 'small', 'em', 'strong', 'dfn', 'code', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'a', 'img', 'object', 'br', 'script', 'map', 'q', 'sub', 'sup', 'span', 'bdo', 'input', 'select', 'textarea', 'label', 'button'],
+\ { 'ondblclick': [], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'onmousedown': [], 'onkeypress': [], 'onclick': [], 'title': [], 'class': [], 'dir': ['ltr', 'rtl'], 'style': [], 'onmousemove': [], 'onmouseout': []}
+\ ],
+\ 'label': [
+\ ['tt', 'i', 'b', 'big', 'small', 'em', 'strong', 'dfn', 'code', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'a', 'img', 'object', 'br', 'script', 'map', 'q', 'sub', 'sup', 'span', 'bdo', 'input', 'select', 'textarea', 'button'],
+\ { 'ondblclick': [], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'for': [], 'onkeypress': [], 'onmousedown': [], 'class': [], 'title': [], 'onclick': [], 'accesskey': [], 'dir': ['ltr', 'rtl'], 'onblur': [], 'onfocus': [], 'onmouseout': [], 'onmousemove': [], 'style': []}
+\ ],
+\ 'legend': [
+\ ['tt', 'i', 'b', 'big', 'small', 'em', 'strong', 'dfn', 'code', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'a', 'img', 'object', 'br', 'script', 'map', 'q', 'sub', 'sup', 'span', 'bdo', 'input', 'select', 'textarea', 'label', 'button'],
+\ { 'ondblclick': [], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'onmousedown': [], 'onkeypress': [], 'onclick': [], 'title': [], 'class': [], 'accesskey': [], 'dir': ['ltr', 'rtl'], 'style': [], 'onmousemove': [], 'onmouseout': []}
+\ ],
+\ 'li': [
+\ ['p', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'ul', 'ol', 'pre', 'dl', 'div', 'noscript', 'blockquote', 'form', 'hr', 'table', 'fieldset', 'address', 'tt', 'i', 'b', 'big', 'small', 'em', 'strong', 'dfn', 'code', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'a', 'img', 'object', 'br', 'script', 'map', 'q', 'sub', 'sup', 'span', 'bdo', 'input', 'select', 'textarea', 'label', 'button'],
+\ { 'ondblclick': [], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'onmousedown': [], 'onkeypress': [], 'onclick': [], 'title': [], 'class': [], 'dir': ['ltr', 'rtl'], 'style': [], 'onmousemove': [], 'onmouseout': []}
+\ ],
+\ 'link': [
+\ [],
+\ { 'rel': [], 'ondblclick': [], 'onkeydown': [], 'onkeyup': [], 'href': [], 'media': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'charset': [], 'hreflang': [], 'onkeypress': [], 'onmousedown': [], 'rev': [], 'class': [], 'title': [], 'onclick': [], 'type': [], 'dir': ['ltr', 'rtl'], 'onmouseout': [], 'onmousemove': [], 'style': []}
+\ ],
+\ 'map': [
+\ ['p', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'ul', 'ol', 'pre', 'dl', 'div', 'noscript', 'blockquote', 'form', 'hr', 'table', 'fieldset', 'address', 'area'],
+\ { 'ondblclick': [], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'name': [], 'onkeypress': [], 'onmousedown': [], 'class': [], 'title': [], 'onclick': [], 'dir': ['ltr', 'rtl'], 'onmouseout': [], 'onmousemove': [], 'style': []}
+\ ],
+\ 'meta': [
+\ [],
+\ { 'http-equiv': [], 'content': [], 'lang': [], 'name': [], 'scheme': [], 'dir': ['ltr', 'rtl']}
+\ ],
+\ 'noscript': [
+\ ['p', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'ul', 'ol', 'pre', 'dl', 'div', 'noscript', 'blockquote', 'form', 'hr', 'table', 'fieldset', 'address'],
+\ { 'ondblclick': [], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'onmousedown': [], 'onkeypress': [], 'onclick': [], 'title': [], 'class': [], 'dir': ['ltr', 'rtl'], 'style': [], 'onmousemove': [], 'onmouseout': []}
+\ ],
+\ 'object': [
+\ ['param', 'p', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'ul', 'ol', 'pre', 'dl', 'div', 'noscript', 'blockquote', 'form', 'hr', 'table', 'fieldset', 'address', 'tt', 'i', 'b', 'big', 'small', 'em', 'strong', 'dfn', 'code', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'a', 'img', 'object', 'br', 'script', 'map', 'q', 'sub', 'sup', 'span', 'bdo', 'input', 'select', 'textarea', 'label', 'button'],
+\ { 'ondblclick': [], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'name': [], 'data': [], 'declare': ['BOOL'], 'onkeypress': [], 'onmousedown': [], 'class': [], 'title': [], 'onclick': [], 'type': [], 'width': [], 'usemap': [], 'dir': ['ltr', 'rtl'], 'archive': [], 'standby': [], 'tabindex': [], 'classid': [], 'onmouseout': [], 'onmousemove': [], 'style': [], 'height': [], 'codetype': [], 'codebase': []}
+\ ],
+\ 'ol': [
+\ ['li'],
+\ { 'ondblclick': [], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'onmousedown': [], 'onkeypress': [], 'onclick': [], 'title': [], 'class': [], 'dir': ['ltr', 'rtl'], 'style': [], 'onmousemove': [], 'onmouseout': []}
+\ ],
+\ 'optgroup': [
+\ ['option'],
+\ { 'ondblclick': [], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'onkeypress': [], 'onmousedown': [], 'class': [], 'title': [], 'onclick': [], 'label': [], 'disabled': ['BOOL'], 'dir': ['ltr', 'rtl'], 'onmouseout': [], 'onmousemove': [], 'style': []}
+\ ],
+\ 'option': [
+\ [''],
+\ { 'ondblclick': [], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'value': [], 'onkeypress': [], 'onmousedown': [], 'class': [], 'title': [], 'onclick': [], 'label': [], 'disabled': ['BOOL'], 'dir': ['ltr', 'rtl'], 'onmouseout': [], 'onmousemove': [], 'style': [], 'selected': ['BOOL']}
+\ ],
+\ 'p': [
+\ ['tt', 'i', 'b', 'big', 'small', 'em', 'strong', 'dfn', 'code', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'a', 'img', 'object', 'br', 'script', 'map', 'q', 'sub', 'sup', 'span', 'bdo', 'input', 'select', 'textarea', 'label', 'button'],
+\ { 'ondblclick': [], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'onmousedown': [], 'onkeypress': [], 'onclick': [], 'title': [], 'class': [], 'dir': ['ltr', 'rtl'], 'style': [], 'onmousemove': [], 'onmouseout': []}
+\ ],
+\ 'param': [
+\ [],
+\ { 'id': [], 'value': [], 'name': [], 'type': [], 'valuetype': ['DATA', 'REF', 'OBJECT']}
+\ ],
+\ 'pre': [
+\ ['tt', 'i', 'b', 'em', 'strong', 'dfn', 'code', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'a', 'br', 'script', 'map', 'q', 'span', 'bdo', 'input', 'select', 'textarea', 'label', 'button'],
+\ { 'ondblclick': [], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'onmousedown': [], 'onkeypress': [], 'onclick': [], 'title': [], 'class': [], 'dir': ['ltr', 'rtl'], 'style': [], 'onmousemove': [], 'onmouseout': []}
+\ ],
+\ 'q': [
+\ ['tt', 'i', 'b', 'big', 'small', 'em', 'strong', 'dfn', 'code', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'a', 'img', 'object', 'br', 'script', 'map', 'q', 'sub', 'sup', 'span', 'bdo', 'input', 'select', 'textarea', 'label', 'button'],
+\ { 'ondblclick': [], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'onmousedown': [], 'onkeypress': [], 'onclick': [], 'title': [], 'class': [], 'dir': ['ltr', 'rtl'], 'cite': [], 'style': [], 'onmousemove': [], 'onmouseout': []}
+\ ],
+\ 'samp': [
+\ ['tt', 'i', 'b', 'big', 'small', 'em', 'strong', 'dfn', 'code', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'a', 'img', 'object', 'br', 'script', 'map', 'q', 'sub', 'sup', 'span', 'bdo', 'input', 'select', 'textarea', 'label', 'button'],
+\ { 'ondblclick': [], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'onmousedown': [], 'onkeypress': [], 'onclick': [], 'title': [], 'class': [], 'dir': ['ltr', 'rtl'], 'style': [], 'onmousemove': [], 'onmouseout': []}
+\ ],
+\ 'script': [
+\ [],
+\ { 'src': [], 'for': [], 'charset': [], 'event': [], 'type': [], 'defer': ['BOOL']}
+\ ],
+\ 'select': [
+\ ['optgroup', 'option'],
+\ { 'ondblclick': [], 'onkeydown': [], 'onchange': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'name': [], 'onkeypress': [], 'onmousedown': [], 'class': [], 'title': [], 'onclick': [], 'disabled': ['BOOL'], 'dir': ['ltr', 'rtl'], 'size': [], 'onblur': [], 'onfocus': [], 'tabindex': [], 'onmouseout': [], 'onmousemove': [], 'style': [], 'multiple': ['BOOL']}
+\ ],
+\ 'small': [
+\ ['tt', 'i', 'b', 'big', 'small', 'em', 'strong', 'dfn', 'code', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'a', 'img', 'object', 'br', 'script', 'map', 'q', 'sub', 'sup', 'span', 'bdo', 'input', 'select', 'textarea', 'label', 'button'],
+\ { 'ondblclick': [], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'onmousedown': [], 'onkeypress': [], 'onclick': [], 'title': [], 'class': [], 'dir': ['ltr', 'rtl'], 'style': [], 'onmousemove': [], 'onmouseout': []}
+\ ],
+\ 'span': [
+\ ['tt', 'i', 'b', 'big', 'small', 'em', 'strong', 'dfn', 'code', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'a', 'img', 'object', 'br', 'script', 'map', 'q', 'sub', 'sup', 'span', 'bdo', 'input', 'select', 'textarea', 'label', 'button'],
+\ { 'ondblclick': [], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'onmousedown': [], 'onkeypress': [], 'onclick': [], 'title': [], 'class': [], 'dir': ['ltr', 'rtl'], 'style': [], 'onmousemove': [], 'onmouseout': []}
+\ ],
+\ 'strong': [
+\ ['tt', 'i', 'b', 'big', 'small', 'em', 'strong', 'dfn', 'code', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'a', 'img', 'object', 'br', 'script', 'map', 'q', 'sub', 'sup', 'span', 'bdo', 'input', 'select', 'textarea', 'label', 'button'],
+\ { 'ondblclick': [], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'onmousedown': [], 'onkeypress': [], 'onclick': [], 'title': [], 'class': [], 'dir': ['ltr', 'rtl'], 'style': [], 'onmousemove': [], 'onmouseout': []}
+\ ],
+\ 'style': [
+\ [],
+\ { 'media': [], 'lang': [], 'type': [], 'title': [], 'dir': ['ltr', 'rtl']}
+\ ],
+\ 'sub': [
+\ ['tt', 'i', 'b', 'big', 'small', 'em', 'strong', 'dfn', 'code', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'a', 'img', 'object', 'br', 'script', 'map', 'q', 'sub', 'sup', 'span', 'bdo', 'input', 'select', 'textarea', 'label', 'button'],
+\ { 'ondblclick': [], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'onmousedown': [], 'onkeypress': [], 'onclick': [], 'title': [], 'class': [], 'dir': ['ltr', 'rtl'], 'style': [], 'onmousemove': [], 'onmouseout': []}
+\ ],
+\ 'sup': [
+\ ['tt', 'i', 'b', 'big', 'small', 'em', 'strong', 'dfn', 'code', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'a', 'img', 'object', 'br', 'script', 'map', 'q', 'sub', 'sup', 'span', 'bdo', 'input', 'select', 'textarea', 'label', 'button'],
+\ { 'ondblclick': [], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'onmousedown': [], 'onkeypress': [], 'onclick': [], 'title': [], 'class': [], 'dir': ['ltr', 'rtl'], 'style': [], 'onmousemove': [], 'onmouseout': []}
+\ ],
+\ 'table': [
+\ ['caption', 'col', 'colgroup', 'thead', 'tfoot', 'tbody'],
+\ { 'ondblclick': [], 'onkeydown': [], 'onkeyup': [], 'datapagesize': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'onkeypress': [], 'onmousedown': [], 'class': [], 'title': [], 'onclick': [], 'width': [], 'frame': ['void', 'above', 'below', 'hsides', 'lhs', 'rhs', 'vsides', 'box', 'border'], 'rules': ['none', 'groups', 'rows', 'cols', 'all'], 'dir': ['ltr', 'rtl'], 'summary': [], 'cellspacing': [], 'onmouseout': [], 'onmousemove': [], 'style': [], 'border': [], 'cellpadding': []}
+\ ],
+\ 'tbody': [
+\ ['tr'],
+\ { 'ondblclick': [], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'align': ['left', 'center', 'right', 'justify', 'char'], 'lang': [], 'valign': ['top', 'middle', 'bottom', 'baseline'], 'onkeypress': [], 'onmousedown': [], 'class': [], 'title': [], 'onclick': [], 'dir': ['ltr', 'rtl'], 'charoff': [], 'onmouseout': [], 'onmousemove': [], 'style': [], 'char': []}
+\ ],
+\ 'td': [
+\ ['p', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'ul', 'ol', 'pre', 'dl', 'div', 'noscript', 'blockquote', 'form', 'hr', 'table', 'fieldset', 'address', 'tt', 'i', 'b', 'big', 'small', 'em', 'strong', 'dfn', 'code', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'a', 'img', 'object', 'br', 'script', 'map', 'q', 'sub', 'sup', 'span', 'bdo', 'input', 'select', 'textarea', 'label', 'button'],
+\ { 'ondblclick': [], 'axis': [], 'onkeydown': [], 'abbr': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'scope': ['row', 'col', 'rowgroup', 'colgroup'], 'onmouseover': [], 'lang': [], 'align': ['left', 'center', 'right', 'justify', 'char'], 'valign': ['top', 'middle', 'bottom', 'baseline'], 'onkeypress': [], 'onmousedown': [], 'class': [], 'title': [], 'onclick': [], 'headers': [], 'dir': ['ltr', 'rtl'], 'rowspan': ['1'], 'colspan': ['1'], 'charoff': [], 'onmouseout': [], 'onmousemove': [], 'style': [], 'char': []}
+\ ],
+\ 'textarea': [
+\ [''],
+\ { 'ondblclick': [], 'cols': [], 'onkeydown': [], 'readonly': ['BOOL'], 'onchange': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'name': [], 'onkeypress': [], 'onmousedown': [], 'class': [], 'title': [], 'onclick': [], 'accesskey': [], 'disabled': ['BOOL'], 'rows': [], 'dir': ['ltr', 'rtl'], 'onblur': [], 'onfocus': [], 'onselect': [], 'tabindex': [], 'onmouseout': [], 'onmousemove': [], 'style': []}
+\ ],
+\ 'tfoot': [
+\ ['tr'],
+\ { 'ondblclick': [], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'align': ['left', 'center', 'right', 'justify', 'char'], 'lang': [], 'valign': ['top', 'middle', 'bottom', 'baseline'], 'onkeypress': [], 'onmousedown': [], 'class': [], 'title': [], 'onclick': [], 'dir': ['ltr', 'rtl'], 'charoff': [], 'onmouseout': [], 'onmousemove': [], 'style': [], 'char': []}
+\ ],
+\ 'th': [
+\ ['p', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'ul', 'ol', 'pre', 'dl', 'div', 'noscript', 'blockquote', 'form', 'hr', 'table', 'fieldset', 'address', 'tt', 'i', 'b', 'big', 'small', 'em', 'strong', 'dfn', 'code', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'a', 'img', 'object', 'br', 'script', 'map', 'q', 'sub', 'sup', 'span', 'bdo', 'input', 'select', 'textarea', 'label', 'button'],
+\ { 'ondblclick': [], 'axis': [], 'onkeydown': [], 'abbr': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'scope': ['row', 'col', 'rowgroup', 'colgroup'], 'onmouseover': [], 'lang': [], 'align': ['left', 'center', 'right', 'justify', 'char'], 'valign': ['top', 'middle', 'bottom', 'baseline'], 'onkeypress': [], 'onmousedown': [], 'class': [], 'title': [], 'onclick': [], 'headers': [], 'dir': ['ltr', 'rtl'], 'rowspan': ['1'], 'colspan': ['1'], 'charoff': [], 'onmouseout': [], 'onmousemove': [], 'style': [], 'char': []}
+\ ],
+\ 'thead': [
+\ ['tr'],
+\ { 'ondblclick': [], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'align': ['left', 'center', 'right', 'justify', 'char'], 'lang': [], 'valign': ['top', 'middle', 'bottom', 'baseline'], 'onkeypress': [], 'onmousedown': [], 'class': [], 'title': [], 'onclick': [], 'dir': ['ltr', 'rtl'], 'charoff': [], 'onmouseout': [], 'onmousemove': [], 'style': [], 'char': []}
+\ ],
+\ 'title': [
+\ [''],
+\ { 'lang': [], 'dir': ['ltr', 'rtl']}
+\ ],
+\ 'tr': [
+\ ['th', 'td'],
+\ { 'ondblclick': [], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'align': ['left', 'center', 'right', 'justify', 'char'], 'lang': [], 'valign': ['top', 'middle', 'bottom', 'baseline'], 'onkeypress': [], 'onmousedown': [], 'class': [], 'title': [], 'onclick': [], 'dir': ['ltr', 'rtl'], 'charoff': [], 'onmouseout': [], 'onmousemove': [], 'style': [], 'char': []}
+\ ],
+\ 'tt': [
+\ ['tt', 'i', 'b', 'big', 'small', 'em', 'strong', 'dfn', 'code', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'a', 'img', 'object', 'br', 'script', 'map', 'q', 'sub', 'sup', 'span', 'bdo', 'input', 'select', 'textarea', 'label', 'button'],
+\ { 'ondblclick': [], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'onmousedown': [], 'onkeypress': [], 'onclick': [], 'title': [], 'class': [], 'dir': ['ltr', 'rtl'], 'style': [], 'onmousemove': [], 'onmouseout': []}
+\ ],
+\ 'ul': [
+\ ['li'],
+\ { 'ondblclick': [], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'onmousedown': [], 'onkeypress': [], 'onclick': [], 'title': [], 'class': [], 'dir': ['ltr', 'rtl'], 'style': [], 'onmousemove': [], 'onmouseout': []}
+\ ],
+\ 'var': [
+\ ['tt', 'i', 'b', 'big', 'small', 'em', 'strong', 'dfn', 'code', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'a', 'img', 'object', 'br', 'script', 'map', 'q', 'sub', 'sup', 'span', 'bdo', 'input', 'select', 'textarea', 'label', 'button'],
+\ { 'ondblclick': [], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'onmousedown': [], 'onkeypress': [], 'onclick': [], 'title': [], 'class': [], 'dir': ['ltr', 'rtl'], 'style': [], 'onmousemove': [], 'onmouseout': []}
+\ ],
+\ 'vimxmlattrinfo' : {
+\ 'accept' : ['ContentType', ''],
+\ 'accesskey' : ['Character', ''],
+\ 'action' : ['*URI', ''],
+\ 'align' : ['String', ''],
+\ 'alt' : ['*Text', ''],
+\ 'archive' : ['UriList', ''],
+\ 'axis' : ['CDATA', ''],
+\ 'border' : ['Pixels', ''],
+\ 'cellpadding' : ['Length', ''],
+\ 'cellspacing' : ['Length', ''],
+\ 'char' : ['Character', ''],
+\ 'charoff' : ['Length', ''],
+\ 'charset' : ['LangCode', ''],
+\ 'checked' : ['Bool', ''],
+\ 'class' : ['CDATA', ''],
+\ 'codetype' : ['ContentType', ''],
+\ 'cols' : ['*Number', ''],
+\ 'colspan' : ['Number', ''],
+\ 'content' : ['*CDATA', ''],
+\ 'coords' : ['Coords', ''],
+\ 'data' : ['URI', ''],
+\ 'datetime' : ['DateTime', ''],
+\ 'declare' : ['Bool', ''],
+\ 'defer' : ['Bool', ''],
+\ 'dir' : ['String', ''],
+\ 'disabled' : ['Bool', ''],
+\ 'enctype' : ['ContentType', ''],
+\ 'for' : ['ID', ''],
+\ 'headers' : ['IDREFS', ''],
+\ 'height' : ['Number', ''],
+\ 'href' : ['*URI', ''],
+\ 'hreflang' : ['LangCode', ''],
+\ 'id' : ['ID', ''],
+\ 'ismap' : ['Bool', ''],
+\ 'label' : ['*Text', ''],
+\ 'lang' : ['LangCode', ''],
+\ 'longdesc' : ['URI', ''],
+\ 'maxlength' : ['Number', ''],
+\ 'media' : ['MediaDesc', ''],
+\ 'method' : ['String', ''],
+\ 'multiple' : ['Bool', ''],
+\ 'name' : ['CDATA', ''],
+\ 'nohref' : ['Bool', ''],
+\ 'onblur' : ['Script', ''],
+\ 'onchange' : ['Script', ''],
+\ 'onclick' : ['Script', ''],
+\ 'ondblclick' : ['Script', ''],
+\ 'onfocus' : ['Script', ''],
+\ 'onkeydown' : ['Script', ''],
+\ 'onkeypress' : ['Script', ''],
+\ 'onkeyup' : ['Script', ''],
+\ 'onload' : ['Script', ''],
+\ 'onmousedown' : ['Script', ''],
+\ 'onmousemove' : ['Script', ''],
+\ 'onmouseout' : ['Script', ''],
+\ 'onmouseover' : ['Script', ''],
+\ 'onmouseup' : ['Script', ''],
+\ 'onreset' : ['Script', ''],
+\ 'onselect' : ['Script', ''],
+\ 'onsubmit' : ['Script', ''],
+\ 'onunload' : ['Script', ''],
+\ 'profile' : ['URI', ''],
+\ 'readonly' : ['Bool', ''],
+\ 'rel' : ['LinkTypes', ''],
+\ 'rev' : ['LinkTypes', ''],
+\ 'rows' : ['*Number', ''],
+\ 'rules' : ['String', ''],
+\ 'scheme' : ['CDATA', ''],
+\ 'selected' : ['Bool', ''],
+\ 'shape' : ['Shape', ''],
+\ 'size' : ['CDATA', ''],
+\ 'span' : ['Number', ''],
+\ 'src' : ['*URI', ''],
+\ 'standby' : ['Text', ''],
+\ 'style' : ['StyleSheet', ''],
+\ 'summary' : ['*Text', ''],
+\ 'tabindex' : ['Number', ''],
+\ 'title' : ['Text', ''],
+\ 'type' : ['*ContentType', ''],
+\ 'usemap' : ['URI', ''],
+\ 'valign' : ['String', ''],
+\ 'valuetype' : ['String', ''],
+\ 'width' : ['Number', ''],
+\ 'xmlns' : ['URI', '']
+\ },
+\ 'vimxmltaginfo': {
+\ 'area': ['/>', ''],
+\ 'base': ['/>', ''],
+\ 'br': ['/>', ''],
+\ 'col': ['/>', ''],
+\ 'hr': ['/>', ''],
+\ 'img': ['/>', ''],
+\ 'input': ['/>', ''],
+\ 'link': ['/>', ''],
+\ 'meta': ['/>', ''],
+\ 'param': ['/>', ''],
+\ }
+\ }
+" vim:ft=vim:ff=unix
--- /dev/null
+++ b/lib/vimfiles/autoload/xml/html40t.vim
@@ -1,0 +1,461 @@
+let g:xmldata_html40t = {
+\ 'vimxmlentities': ['AElig', 'Aacute', 'Acirc', 'Agrave', 'Alpha', 'Aring', 'Atilde', 'Auml', 'Beta', 'Ccedil', 'Chi', 'Dagger', 'Delta', 'ETH', 'Eacute', 'Ecirc', 'Egrave', 'Epsilon', 'Eta', 'Euml', 'Gamma', 'Iacute', 'Icirc', 'Igrave', 'Iota', 'Iuml', 'Kappa', 'Lambda', 'Mu', 'Ntilde', 'Nu', 'OElig', 'Oacute', 'Ocirc', 'Ograve', 'Omega', 'Omicron', 'Oslash', 'Otilde', 'Ouml', 'Phi', 'Pi', 'Prime', 'Psi', 'Rho', 'Scaron', 'Sigma', 'THORN', 'Tau', 'Theta', 'Uacute', 'Ucirc', 'Ugrave', 'Upsilon', 'Uuml', 'Xi', 'Yacute', 'Yuml', 'Zeta', 'aacute', 'acirc', 'acute', 'aelig', 'agrave', 'alefsym', 'alpha', 'amp', 'and', 'ang', 'apos', 'aring', 'asymp', 'atilde', 'auml', 'bdquo', 'beta', 'brvbar', 'bull', 'cap', 'ccedil', 'cedil', 'cent', 'chi', 'circ', 'clubs', 'cong', 'copy', 'crarr', 'cup', 'curren', 'dArr', 'dagger', 'darr', 'deg', 'delta', 'diams', 'divide', 'eacute', 'ecirc', 'egrave', 'empty', 'emsp', 'ensp', 'epsilon', 'equiv', 'eta', 'eth', 'euml', 'euro', 'exist', 'fnof', 'forall', 'frac12', 'frac14', 'frac34', 'frasl', 'gamma', 'ge', 'gt', 'hArr', 'harr', 'hearts', 'hellip', 'iacute', 'icirc', 'iexcl', 'igrave', 'image', 'infin', 'int', 'iota', 'iquest', 'isin', 'iuml', 'kappa', 'lArr', 'lambda', 'lang', 'laquo', 'larr', 'lceil', 'ldquo', 'le', 'lfloor', 'lowast', 'loz', 'lrm', 'lsaquo', 'lsquo', 'lt', 'macr', 'mdash', 'micro', 'middot', 'minus', 'mu', 'nabla', 'nbsp', 'ndash', 'ne', 'ni', 'not', 'notin', 'nsub', 'ntilde', 'nu', 'oacute', 'ocirc', 'oelig', 'ograve', 'oline', 'omega', 'omicron', 'oplus', 'or', 'ordf', 'ordm', 'oslash', 'otilde', 'otimes', 'ouml', 'para', 'part', 'permil', 'perp', 'phi', 'pi', 'piv', 'plusmn', 'pound', 'prime', 'prod', 'prop', 'psi', 'quot', 'rArr', 'radic', 'rang', 'raquo', 'rarr', 'rceil', 'rdquo', 'real', 'reg', 'rfloor', 'rho', 'rlm', 'rsaquo', 'rsquo', 'sbquo', 'scaron', 'sdot', 'sect', 'shy', 'sigma', 'sigmaf', 'sim', 'spades', 'sub', 'sube', 'sum', 'sup', 'sup1', 'sup2', 'sup3', 'supe', 'szlig', 'tau', 'there4', 'theta', 'thetasym', 'thinsp', 'thorn', 'tilde', 'times', 'trade', 'uArr', 'uacute', 'uarr', 'ucirc', 'ugrave', 'uml', 'upsih', 'upsilon', 'uuml', 'weierp', 'xi', 'yacute', 'yen', 'yuml', 'zeta', 'zwj', 'zwnj'],
+\ 'vimxmlroot': ['html'],
+\ 'a': [
+\ ['tt', 'i', 'b', 'u', 's', 'strike', 'big', 'small', 'em', 'strong', 'dfn', 'code', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'img', 'applet', 'object', 'font', 'basefont', 'br', 'script', 'map', 'q', 'sub', 'sup', 'span', 'bdo', 'iframe', 'input', 'select', 'textarea', 'label', 'button'],
+\ { 'rel': [], 'accesskey': [], 'coords': [], 'ondblclick': [], 'dir': ['ltr', 'rtl'], 'onblur': [], 'onkeydown': [], 'onfocus': [], 'target': [], 'onkeyup': [], 'href': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'tabindex': [], 'lang': [], 'onmouseout': [], 'onmousemove': [], 'style': [], 'name': [], 'charset': [], 'hreflang': [], 'onkeypress': [], 'onmousedown': [], 'rev': [], 'class': [], 'title': [], 'onclick': [], 'type': [], 'shape': ['rect', 'circle', 'poly', 'default']}
+\ ],
+\ 'abbr': [
+\ ['tt', 'i', 'b', 'u', 's', 'strike', 'big', 'small', 'em', 'strong', 'dfn', 'code', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'a', 'img', 'applet', 'object', 'font', 'basefont', 'br', 'script', 'map', 'q', 'sub', 'sup', 'span', 'bdo', 'iframe', 'input', 'select', 'textarea', 'label', 'button'],
+\ { 'ondblclick': [], 'dir': ['ltr', 'rtl'], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'style': [], 'onmousemove': [], 'onmouseout': [], 'onmousedown': [], 'onkeypress': [], 'onclick': [], 'title': [], 'class': []}
+\ ],
+\ 'acronym': [
+\ ['tt', 'i', 'b', 'u', 's', 'strike', 'big', 'small', 'em', 'strong', 'dfn', 'code', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'a', 'img', 'applet', 'object', 'font', 'basefont', 'br', 'script', 'map', 'q', 'sub', 'sup', 'span', 'bdo', 'iframe', 'input', 'select', 'textarea', 'label', 'button'],
+\ { 'ondblclick': [], 'dir': ['ltr', 'rtl'], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'style': [], 'onmousemove': [], 'onmouseout': [], 'onmousedown': [], 'onkeypress': [], 'onclick': [], 'title': [], 'class': []}
+\ ],
+\ 'address': [
+\ ['tt', 'i', 'b', 'u', 's', 'strike', 'big', 'small', 'em', 'strong', 'dfn', 'code', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'a', 'img', 'applet', 'object', 'font', 'basefont', 'br', 'script', 'map', 'q', 'sub', 'sup', 'span', 'bdo', 'iframe', 'input', 'select', 'textarea', 'label', 'button', 'p'],
+\ { 'ondblclick': [], 'dir': ['ltr', 'rtl'], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'style': [], 'onmousemove': [], 'onmouseout': [], 'onmousedown': [], 'onkeypress': [], 'onclick': [], 'title': [], 'class': []}
+\ ],
+\ 'applet': [
+\ ['param', 'p', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'ul', 'ol', 'dir', 'menu', 'pre', 'dl', 'div', 'center', 'noscript', 'noframes', 'blockquote', 'form', 'isindex', 'hr', 'table', 'fieldset', 'address', 'tt', 'i', 'b', 'u', 's', 'strike', 'big', 'small', 'em', 'strong', 'dfn', 'code', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'a', 'img', 'applet', 'object', 'font', 'basefont', 'br', 'script', 'map', 'q', 'sub', 'sup', 'span', 'bdo', 'iframe', 'input', 'select', 'textarea', 'label', 'button'],
+\ { 'width': [], 'object': [], 'id': [], 'code': [], 'vspace': [], 'archive': [], 'alt': [], 'align': ['top', 'middle', 'bottom', 'left', 'right'], 'style': [], 'name': [], 'height': [], 'hspace': [], 'title': [], 'class': [], 'codebase': []}
+\ ],
+\ 'area': [
+\ [],
+\ { 'accesskey': [], 'coords': [], 'ondblclick': [], 'dir': ['ltr', 'rtl'], 'onblur': [], 'onkeydown': [], 'target': [], 'nohref': ['BOOL'], 'onfocus': [], 'onkeyup': [], 'href': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'alt': [], 'tabindex': [], 'onmouseout': [], 'onmousemove': [], 'style': [], 'onkeypress': [], 'onmousedown': [], 'shape': ['rect', 'circle', 'poly', 'default'], 'class': [], 'title': [], 'onclick': []}
+\ ],
+\ 'b': [
+\ ['tt', 'i', 'b', 'u', 's', 'strike', 'big', 'small', 'em', 'strong', 'dfn', 'code', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'a', 'img', 'applet', 'object', 'font', 'basefont', 'br', 'script', 'map', 'q', 'sub', 'sup', 'span', 'bdo', 'iframe', 'input', 'select', 'textarea', 'label', 'button'],
+\ { 'ondblclick': [], 'dir': ['ltr', 'rtl'], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'style': [], 'onmousemove': [], 'onmouseout': [], 'onmousedown': [], 'onkeypress': [], 'onclick': [], 'title': [], 'class': []}
+\ ],
+\ 'base': [
+\ [],
+\ { 'target': [], 'href': []}
+\ ],
+\ 'basefont': [
+\ [],
+\ { 'size': [], 'face': [], 'color': [], 'id': []}
+\ ],
+\ 'bdo': [
+\ ['tt', 'i', 'b', 'u', 's', 'strike', 'big', 'small', 'em', 'strong', 'dfn', 'code', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'a', 'img', 'applet', 'object', 'font', 'basefont', 'br', 'script', 'map', 'q', 'sub', 'sup', 'span', 'bdo', 'iframe', 'input', 'select', 'textarea', 'label', 'button'],
+\ { 'dir': ['ltr', 'rtl'], 'id': [], 'lang': [], 'style': [], 'class': [], 'title': []}
+\ ],
+\ 'big': [
+\ ['tt', 'i', 'b', 'u', 's', 'strike', 'big', 'small', 'em', 'strong', 'dfn', 'code', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'a', 'img', 'applet', 'object', 'font', 'basefont', 'br', 'script', 'map', 'q', 'sub', 'sup', 'span', 'bdo', 'iframe', 'input', 'select', 'textarea', 'label', 'button'],
+\ { 'ondblclick': [], 'dir': ['ltr', 'rtl'], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'style': [], 'onmousemove': [], 'onmouseout': [], 'onmousedown': [], 'onkeypress': [], 'onclick': [], 'title': [], 'class': []}
+\ ],
+\ 'blockquote': [
+\ ['p', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'ul', 'ol', 'dir', 'menu', 'pre', 'dl', 'div', 'center', 'noscript', 'noframes', 'blockquote', 'form', 'isindex', 'hr', 'table', 'fieldset', 'address', 'tt', 'i', 'b', 'u', 's', 'strike', 'big', 'small', 'em', 'strong', 'dfn', 'code', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'a', 'img', 'applet', 'object', 'font', 'basefont', 'br', 'script', 'map', 'q', 'sub', 'sup', 'span', 'bdo', 'iframe', 'input', 'select', 'textarea', 'label', 'button'],
+\ { 'ondblclick': [], 'dir': ['ltr', 'rtl'], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'cite': [], 'onmouseover': [], 'lang': [], 'style': [], 'onmousemove': [], 'onmouseout': [], 'onmousedown': [], 'onkeypress': [], 'onclick': [], 'title': [], 'class': []}
+\ ],
+\ 'body': [
+\ ['p', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'ul', 'ol', 'dir', 'menu', 'pre', 'dl', 'div', 'center', 'noscript', 'noframes', 'blockquote', 'form', 'isindex', 'hr', 'table', 'fieldset', 'address', 'tt', 'i', 'b', 'u', 's', 'strike', 'big', 'small', 'em', 'strong', 'dfn', 'code', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'a', 'img', 'applet', 'object', 'font', 'basefont', 'br', 'script', 'map', 'q', 'sub', 'sup', 'span', 'bdo', 'iframe', 'input', 'select', 'textarea', 'label', 'button', 'ins', 'del'],
+\ { 'vlink': [], 'ondblclick': [], 'dir': ['ltr', 'rtl'], 'onkeydown': [], 'alink': [], 'onkeyup': [], 'bgcolor': [], 'text': [], 'onmouseup': [], 'id': [], 'link': [], 'onmouseover': [], 'lang': [], 'onmouseout': [], 'onmousemove': [], 'style': [], 'background': [], 'onunload': [], 'onkeypress': [], 'onmousedown': [], 'onload': [], 'class': [], 'title': [], 'onclick': []}
+\ ],
+\ 'br': [
+\ [],
+\ { 'clear': ['none', 'left', 'all', 'right', 'none'], 'id': [], 'style': [], 'class': [], 'title': []}
+\ ],
+\ 'button': [
+\ ['p', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'ul', 'ol', 'dir', 'menu', 'pre', 'dl', 'div', 'center', 'noscript', 'noframes', 'blockquote', 'hr', 'table', 'address', 'tt', 'i', 'b', 'u', 's', 'strike', 'big', 'small', 'em', 'strong', 'dfn', 'code', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'img', 'applet', 'object', 'font', 'basefont', 'br', 'script', 'map', 'q', 'sub', 'sup', 'span', 'bdo'],
+\ { 'accesskey': [], 'disabled': ['BOOL'], 'ondblclick': [], 'dir': ['ltr', 'rtl'], 'onblur': [], 'onkeydown': [], 'onfocus': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'tabindex': [], 'value': [], 'name': [], 'onmouseout': [], 'onmousemove': [], 'style': [], 'onkeypress': [], 'onmousedown': [], 'class': [], 'title': [], 'onclick': [], 'type': ['submit', 'button', 'submit', 'reset']}
+\ ],
+\ 'caption': [
+\ ['tt', 'i', 'b', 'u', 's', 'strike', 'big', 'small', 'em', 'strong', 'dfn', 'code', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'a', 'img', 'applet', 'object', 'font', 'basefont', 'br', 'script', 'map', 'q', 'sub', 'sup', 'span', 'bdo', 'iframe', 'input', 'select', 'textarea', 'label', 'button'],
+\ { 'ondblclick': [], 'dir': ['ltr', 'rtl'], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'align': ['top', 'bottom', 'left', 'right'], 'lang': [], 'onmouseout': [], 'onmousemove': [], 'style': [], 'onkeypress': [], 'onmousedown': [], 'class': [], 'title': [], 'onclick': []}
+\ ],
+\ 'center': [
+\ ['p', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'ul', 'ol', 'dir', 'menu', 'pre', 'dl', 'div', 'center', 'noscript', 'noframes', 'blockquote', 'form', 'isindex', 'hr', 'table', 'fieldset', 'address', 'tt', 'i', 'b', 'u', 's', 'strike', 'big', 'small', 'em', 'strong', 'dfn', 'code', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'a', 'img', 'applet', 'object', 'font', 'basefont', 'br', 'script', 'map', 'q', 'sub', 'sup', 'span', 'bdo', 'iframe', 'input', 'select', 'textarea', 'label', 'button'],
+\ { 'ondblclick': [], 'dir': ['ltr', 'rtl'], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'style': [], 'onmousemove': [], 'onmouseout': [], 'onmousedown': [], 'onkeypress': [], 'onclick': [], 'title': [], 'class': []}
+\ ],
+\ 'cite': [
+\ ['tt', 'i', 'b', 'u', 's', 'strike', 'big', 'small', 'em', 'strong', 'dfn', 'code', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'a', 'img', 'applet', 'object', 'font', 'basefont', 'br', 'script', 'map', 'q', 'sub', 'sup', 'span', 'bdo', 'iframe', 'input', 'select', 'textarea', 'label', 'button'],
+\ { 'ondblclick': [], 'dir': ['ltr', 'rtl'], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'style': [], 'onmousemove': [], 'onmouseout': [], 'onmousedown': [], 'onkeypress': [], 'onclick': [], 'title': [], 'class': []}
+\ ],
+\ 'code': [
+\ ['tt', 'i', 'b', 'u', 's', 'strike', 'big', 'small', 'em', 'strong', 'dfn', 'code', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'a', 'img', 'applet', 'object', 'font', 'basefont', 'br', 'script', 'map', 'q', 'sub', 'sup', 'span', 'bdo', 'iframe', 'input', 'select', 'textarea', 'label', 'button'],
+\ { 'ondblclick': [], 'dir': ['ltr', 'rtl'], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'style': [], 'onmousemove': [], 'onmouseout': [], 'onmousedown': [], 'onkeypress': [], 'onclick': [], 'title': [], 'class': []}
+\ ],
+\ 'col': [
+\ [],
+\ { 'width': [], 'ondblclick': [], 'dir': ['ltr', 'rtl'], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'charoff': [], 'onmouseover': [], 'lang': [], 'align': ['left', 'center', 'right', 'justify', 'char'], 'valign': ['top', 'middle', 'bottom', 'baseline'], 'onmouseout': [], 'onmousemove': [], 'style': [], 'onkeypress': [], 'onmousedown': [], 'char': [], 'span': ['1'], 'class': [], 'title': [], 'onclick': []}
+\ ],
+\ 'colgroup': [
+\ ['col'],
+\ { 'width': [], 'ondblclick': [], 'dir': ['ltr', 'rtl'], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'charoff': [], 'onmouseover': [], 'lang': [], 'align': ['left', 'center', 'right', 'justify', 'char'], 'valign': ['top', 'middle', 'bottom', 'baseline'], 'onmouseout': [], 'onmousemove': [], 'style': [], 'onkeypress': [], 'onmousedown': [], 'char': [], 'span': ['1'], 'class': [], 'title': [], 'onclick': []}
+\ ],
+\ 'dd': [
+\ ['p', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'ul', 'ol', 'dir', 'menu', 'pre', 'dl', 'div', 'center', 'noscript', 'noframes', 'blockquote', 'form', 'isindex', 'hr', 'table', 'fieldset', 'address', 'tt', 'i', 'b', 'u', 's', 'strike', 'big', 'small', 'em', 'strong', 'dfn', 'code', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'a', 'img', 'applet', 'object', 'font', 'basefont', 'br', 'script', 'map', 'q', 'sub', 'sup', 'span', 'bdo', 'iframe', 'input', 'select', 'textarea', 'label', 'button'],
+\ { 'ondblclick': [], 'dir': ['ltr', 'rtl'], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'style': [], 'onmousemove': [], 'onmouseout': [], 'onmousedown': [], 'onkeypress': [], 'onclick': [], 'title': [], 'class': []}
+\ ],
+\ 'del': [
+\ ['p', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'ul', 'ol', 'dir', 'menu', 'pre', 'dl', 'div', 'center', 'noscript', 'noframes', 'blockquote', 'form', 'isindex', 'hr', 'table', 'fieldset', 'address', 'tt', 'i', 'b', 'u', 's', 'strike', 'big', 'small', 'em', 'strong', 'dfn', 'code', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'a', 'img', 'applet', 'object', 'font', 'basefont', 'br', 'script', 'map', 'q', 'sub', 'sup', 'span', 'bdo', 'iframe', 'input', 'select', 'textarea', 'label', 'button'],
+\ { 'ondblclick': [], 'dir': ['ltr', 'rtl'], 'datetime': [], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'cite': [], 'onmouseover': [], 'lang': [], 'onmouseout': [], 'onmousemove': [], 'style': [], 'onkeypress': [], 'onmousedown': [], 'class': [], 'title': [], 'onclick': []}
+\ ],
+\ 'dfn': [
+\ ['tt', 'i', 'b', 'u', 's', 'strike', 'big', 'small', 'em', 'strong', 'dfn', 'code', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'a', 'img', 'applet', 'object', 'font', 'basefont', 'br', 'script', 'map', 'q', 'sub', 'sup', 'span', 'bdo', 'iframe', 'input', 'select', 'textarea', 'label', 'button'],
+\ { 'ondblclick': [], 'dir': ['ltr', 'rtl'], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'style': [], 'onmousemove': [], 'onmouseout': [], 'onmousedown': [], 'onkeypress': [], 'onclick': [], 'title': [], 'class': []}
+\ ],
+\ 'dir': [
+\ ['li'],
+\ { 'ondblclick': [], 'dir': ['ltr', 'rtl'], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'compact': ['BOOL'], 'onmouseover': [], 'lang': [], 'style': [], 'onmousemove': [], 'onmouseout': [], 'onmousedown': [], 'onkeypress': [], 'onclick': [], 'title': [], 'class': []}
+\ ],
+\ 'div': [
+\ ['p', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'ul', 'ol', 'dir', 'menu', 'pre', 'dl', 'div', 'center', 'noscript', 'noframes', 'blockquote', 'form', 'isindex', 'hr', 'table', 'fieldset', 'address', 'tt', 'i', 'b', 'u', 's', 'strike', 'big', 'small', 'em', 'strong', 'dfn', 'code', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'a', 'img', 'applet', 'object', 'font', 'basefont', 'br', 'script', 'map', 'q', 'sub', 'sup', 'span', 'bdo', 'iframe', 'input', 'select', 'textarea', 'label', 'button'],
+\ { 'ondblclick': [], 'dir': ['ltr', 'rtl'], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'align': ['left', 'center', 'right', 'justify'], 'lang': [], 'onmouseout': [], 'onmousemove': [], 'style': [], 'onkeypress': [], 'onmousedown': [], 'class': [], 'title': [], 'onclick': []}
+\ ],
+\ 'dl': [
+\ ['dt', 'dd'],
+\ { 'ondblclick': [], 'dir': ['ltr', 'rtl'], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'compact': ['BOOL'], 'onmouseover': [], 'lang': [], 'style': [], 'onmousemove': [], 'onmouseout': [], 'onmousedown': [], 'onkeypress': [], 'onclick': [], 'title': [], 'class': []}
+\ ],
+\ 'dt': [
+\ ['tt', 'i', 'b', 'u', 's', 'strike', 'big', 'small', 'em', 'strong', 'dfn', 'code', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'a', 'img', 'applet', 'object', 'font', 'basefont', 'br', 'script', 'map', 'q', 'sub', 'sup', 'span', 'bdo', 'iframe', 'input', 'select', 'textarea', 'label', 'button'],
+\ { 'ondblclick': [], 'dir': ['ltr', 'rtl'], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'style': [], 'onmousemove': [], 'onmouseout': [], 'onmousedown': [], 'onkeypress': [], 'onclick': [], 'title': [], 'class': []}
+\ ],
+\ 'em': [
+\ ['tt', 'i', 'b', 'u', 's', 'strike', 'big', 'small', 'em', 'strong', 'dfn', 'code', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'a', 'img', 'applet', 'object', 'font', 'basefont', 'br', 'script', 'map', 'q', 'sub', 'sup', 'span', 'bdo', 'iframe', 'input', 'select', 'textarea', 'label', 'button'],
+\ { 'ondblclick': [], 'dir': ['ltr', 'rtl'], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'style': [], 'onmousemove': [], 'onmouseout': [], 'onmousedown': [], 'onkeypress': [], 'onclick': [], 'title': [], 'class': []}
+\ ],
+\ 'fieldset': [
+\ ['legend', 'p', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'ul', 'ol', 'dir', 'menu', 'pre', 'dl', 'div', 'center', 'noscript', 'noframes', 'blockquote', 'form', 'isindex', 'hr', 'table', 'fieldset', 'address', 'tt', 'i', 'b', 'u', 's', 'strike', 'big', 'small', 'em', 'strong', 'dfn', 'code', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'a', 'img', 'applet', 'object', 'font', 'basefont', 'br', 'script', 'map', 'q', 'sub', 'sup', 'span', 'bdo', 'iframe', 'input', 'select', 'textarea', 'label', 'button'],
+\ { 'ondblclick': [], 'dir': ['ltr', 'rtl'], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'style': [], 'onmousemove': [], 'onmouseout': [], 'onmousedown': [], 'onkeypress': [], 'onclick': [], 'title': [], 'class': []}
+\ ],
+\ 'font': [
+\ ['tt', 'i', 'b', 'u', 's', 'strike', 'big', 'small', 'em', 'strong', 'dfn', 'code', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'a', 'img', 'applet', 'object', 'font', 'basefont', 'br', 'script', 'map', 'q', 'sub', 'sup', 'span', 'bdo', 'iframe', 'input', 'select', 'textarea', 'label', 'button'],
+\ { 'dir': ['ltr', 'rtl'], 'size': [], 'face': [], 'color': [], 'id': [], 'lang': [], 'style': [], 'class': [], 'title': []}
+\ ],
+\ 'form': [
+\ ['p', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'ul', 'ol', 'dir', 'menu', 'pre', 'dl', 'div', 'center', 'noscript', 'noframes', 'blockquote', 'isindex', 'hr', 'table', 'fieldset', 'address', 'tt', 'i', 'b', 'u', 's', 'strike', 'big', 'small', 'em', 'strong', 'dfn', 'code', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'a', 'img', 'applet', 'object', 'font', 'basefont', 'br', 'script', 'map', 'q', 'sub', 'sup', 'span', 'bdo', 'iframe', 'input', 'select', 'textarea', 'label', 'button'],
+\ { 'enctype': ['application/x-www-form-urlencoded'], 'onsubmit': [], 'ondblclick': [], 'dir': ['ltr', 'rtl'], 'onkeydown': [], 'target': [], 'onkeyup': [], 'onmouseup': [], 'onreset': [], 'id': [], 'method': ['GET', 'POST'], 'onmouseover': [], 'lang': [], 'onmouseout': [], 'onmousemove': [], 'style': [], 'accept-charset': [], 'onkeypress': [], 'onmousedown': [], 'action': [], 'class': [], 'title': [], 'onclick': []}
+\ ],
+\ 'h1': [
+\ ['tt', 'i', 'b', 'u', 's', 'strike', 'big', 'small', 'em', 'strong', 'dfn', 'code', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'a', 'img', 'applet', 'object', 'font', 'basefont', 'br', 'script', 'map', 'q', 'sub', 'sup', 'span', 'bdo', 'iframe', 'input', 'select', 'textarea', 'label', 'button'],
+\ { 'ondblclick': [], 'dir': ['ltr', 'rtl'], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'align': ['left', 'center', 'right', 'justify'], 'lang': [], 'onmouseout': [], 'onmousemove': [], 'style': [], 'onkeypress': [], 'onmousedown': [], 'class': [], 'title': [], 'onclick': []}
+\ ],
+\ 'h2': [
+\ ['tt', 'i', 'b', 'u', 's', 'strike', 'big', 'small', 'em', 'strong', 'dfn', 'code', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'a', 'img', 'applet', 'object', 'font', 'basefont', 'br', 'script', 'map', 'q', 'sub', 'sup', 'span', 'bdo', 'iframe', 'input', 'select', 'textarea', 'label', 'button'],
+\ { 'ondblclick': [], 'dir': ['ltr', 'rtl'], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'align': ['left', 'center', 'right', 'justify'], 'lang': [], 'onmouseout': [], 'onmousemove': [], 'style': [], 'onkeypress': [], 'onmousedown': [], 'class': [], 'title': [], 'onclick': []}
+\ ],
+\ 'h3': [
+\ ['tt', 'i', 'b', 'u', 's', 'strike', 'big', 'small', 'em', 'strong', 'dfn', 'code', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'a', 'img', 'applet', 'object', 'font', 'basefont', 'br', 'script', 'map', 'q', 'sub', 'sup', 'span', 'bdo', 'iframe', 'input', 'select', 'textarea', 'label', 'button'],
+\ { 'ondblclick': [], 'dir': ['ltr', 'rtl'], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'align': ['left', 'center', 'right', 'justify'], 'lang': [], 'onmouseout': [], 'onmousemove': [], 'style': [], 'onkeypress': [], 'onmousedown': [], 'class': [], 'title': [], 'onclick': []}
+\ ],
+\ 'h4': [
+\ ['tt', 'i', 'b', 'u', 's', 'strike', 'big', 'small', 'em', 'strong', 'dfn', 'code', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'a', 'img', 'applet', 'object', 'font', 'basefont', 'br', 'script', 'map', 'q', 'sub', 'sup', 'span', 'bdo', 'iframe', 'input', 'select', 'textarea', 'label', 'button'],
+\ { 'ondblclick': [], 'dir': ['ltr', 'rtl'], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'align': ['left', 'center', 'right', 'justify'], 'lang': [], 'onmouseout': [], 'onmousemove': [], 'style': [], 'onkeypress': [], 'onmousedown': [], 'class': [], 'title': [], 'onclick': []}
+\ ],
+\ 'h5': [
+\ ['tt', 'i', 'b', 'u', 's', 'strike', 'big', 'small', 'em', 'strong', 'dfn', 'code', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'a', 'img', 'applet', 'object', 'font', 'basefont', 'br', 'script', 'map', 'q', 'sub', 'sup', 'span', 'bdo', 'iframe', 'input', 'select', 'textarea', 'label', 'button'],
+\ { 'ondblclick': [], 'dir': ['ltr', 'rtl'], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'align': ['left', 'center', 'right', 'justify'], 'lang': [], 'onmouseout': [], 'onmousemove': [], 'style': [], 'onkeypress': [], 'onmousedown': [], 'class': [], 'title': [], 'onclick': []}
+\ ],
+\ 'h6': [
+\ ['tt', 'i', 'b', 'u', 's', 'strike', 'big', 'small', 'em', 'strong', 'dfn', 'code', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'a', 'img', 'applet', 'object', 'font', 'basefont', 'br', 'script', 'map', 'q', 'sub', 'sup', 'span', 'bdo', 'iframe', 'input', 'select', 'textarea', 'label', 'button'],
+\ { 'ondblclick': [], 'dir': ['ltr', 'rtl'], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'align': ['left', 'center', 'right', 'justify'], 'lang': [], 'onmouseout': [], 'onmousemove': [], 'style': [], 'onkeypress': [], 'onmousedown': [], 'class': [], 'title': [], 'onclick': []}
+\ ],
+\ 'head': [
+\ ['title', 'isindex', 'base', 'script', 'style', 'meta', 'link', 'object'],
+\ { 'profile': [], 'dir': ['ltr', 'rtl'], 'lang': []}
+\ ],
+\ 'hr': [
+\ [],
+\ { 'width': [], 'ondblclick': [], 'size': [], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'align': ['left', 'center', 'right'], 'style': [], 'onmousemove': [], 'onmouseout': [], 'noshade': ['BOOL'], 'onmousedown': [], 'onkeypress': [], 'onclick': [], 'title': [], 'class': []}
+\ ],
+\ 'html': [
+\ ['head', 'body'],
+\ { 'dir': ['ltr', 'rtl'], 'lang': [], 'version': ['-//W3C//DTD HTML 4.0 Transitional//EN']}
+\ ],
+\ 'i': [
+\ ['tt', 'i', 'b', 'u', 's', 'strike', 'big', 'small', 'em', 'strong', 'dfn', 'code', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'a', 'img', 'applet', 'object', 'font', 'basefont', 'br', 'script', 'map', 'q', 'sub', 'sup', 'span', 'bdo', 'iframe', 'input', 'select', 'textarea', 'label', 'button'],
+\ { 'ondblclick': [], 'dir': ['ltr', 'rtl'], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'style': [], 'onmousemove': [], 'onmouseout': [], 'onmousedown': [], 'onkeypress': [], 'onclick': [], 'title': [], 'class': []}
+\ ],
+\ 'iframe': [
+\ ['p', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'ul', 'ol', 'dir', 'menu', 'pre', 'dl', 'div', 'center', 'noscript', 'noframes', 'blockquote', 'form', 'isindex', 'hr', 'table', 'fieldset', 'address', 'tt', 'i', 'b', 'u', 's', 'strike', 'big', 'small', 'em', 'strong', 'dfn', 'code', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'a', 'img', 'applet', 'object', 'font', 'basefont', 'br', 'script', 'map', 'q', 'sub', 'sup', 'span', 'bdo', 'iframe', 'input', 'select', 'textarea', 'label', 'button'],
+\ { 'width': [], 'scrolling': ['auto', 'yes', 'no', 'auto'], 'marginwidth': [], 'id': [], 'marginheight': [], 'align': ['top', 'middle', 'bottom', 'left', 'right'], 'longdesc': [], 'src': [], 'style': [], 'name': [], 'height': [], 'frameborder': ['1', '0'], 'title': [], 'class': []}
+\ ],
+\ 'img': [
+\ [],
+\ { 'width': [], 'usemap': [], 'ismap': ['BOOL'], 'ondblclick': [], 'dir': ['ltr', 'rtl'], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'vspace': [], 'onmouseover': [], 'alt': [], 'lang': [], 'align': ['top', 'middle', 'bottom', 'left', 'right'], 'src': [], 'longdesc': [], 'onmouseout': [], 'onmousemove': [], 'style': [], 'height': [], 'border': [], 'hspace': [], 'onkeypress': [], 'onmousedown': [], 'class': [], 'title': [], 'onclick': []}
+\ ],
+\ 'input': [
+\ [],
+\ { 'ondblclick': [], 'onkeydown': [], 'readonly': ['BOOL'], 'onchange': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'align': ['top', 'middle', 'bottom', 'left', 'right'], 'value': [], 'src': [], 'name': [], 'checked': ['BOOL'], 'onkeypress': [], 'onmousedown': [], 'type': ['TEXT', 'PASSWORD', 'CHECKBOX', 'RADIO', 'SUBMIT', 'RESET', 'FILE', 'IMAGE', 'BUTTON'], 'class': [], 'title': [], 'onclick': [], 'accesskey': [], 'disabled': ['BOOL'], 'usemap': [], 'dir': ['ltr', 'rtl'], 'size': [], 'onblur': [], 'onfocus': [], 'maxlength': [], 'onselect': [], 'accept': [], 'alt': [], 'tabindex': [], 'style': [], 'onmousemove': [], 'onmouseout': []}
+\ ],
+\ 'ins': [
+\ ['p', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'ul', 'ol', 'dir', 'menu', 'pre', 'dl', 'div', 'center', 'noscript', 'noframes', 'blockquote', 'form', 'isindex', 'hr', 'table', 'fieldset', 'address', 'tt', 'i', 'b', 'u', 's', 'strike', 'big', 'small', 'em', 'strong', 'dfn', 'code', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'a', 'img', 'applet', 'object', 'font', 'basefont', 'br', 'script', 'map', 'q', 'sub', 'sup', 'span', 'bdo', 'iframe', 'input', 'select', 'textarea', 'label', 'button'],
+\ { 'ondblclick': [], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'onkeypress': [], 'onmousedown': [], 'class': [], 'title': [], 'onclick': [], 'dir': ['ltr', 'rtl'], 'datetime': [], 'cite': [], 'onmouseout': [], 'onmousemove': [], 'style': []}
+\ ],
+\ 'isindex': [
+\ [],
+\ { 'id': [], 'lang': [], 'prompt': [], 'class': [], 'title': [], 'dir': ['ltr', 'rtl'], 'style': []}
+\ ],
+\ 'kbd': [
+\ ['tt', 'i', 'b', 'u', 's', 'strike', 'big', 'small', 'em', 'strong', 'dfn', 'code', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'a', 'img', 'applet', 'object', 'font', 'basefont', 'br', 'script', 'map', 'q', 'sub', 'sup', 'span', 'bdo', 'iframe', 'input', 'select', 'textarea', 'label', 'button'],
+\ { 'ondblclick': [], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'onmousedown': [], 'onkeypress': [], 'onclick': [], 'title': [], 'class': [], 'dir': ['ltr', 'rtl'], 'style': [], 'onmousemove': [], 'onmouseout': []}
+\ ],
+\ 'label': [
+\ ['tt', 'i', 'b', 'u', 's', 'strike', 'big', 'small', 'em', 'strong', 'dfn', 'code', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'a', 'img', 'applet', 'object', 'font', 'basefont', 'br', 'script', 'map', 'q', 'sub', 'sup', 'span', 'bdo', 'iframe', 'input', 'select', 'textarea', 'button'],
+\ { 'ondblclick': [], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'for': [], 'onkeypress': [], 'onmousedown': [], 'class': [], 'title': [], 'onclick': [], 'accesskey': [], 'dir': ['ltr', 'rtl'], 'onblur': [], 'onfocus': [], 'onmouseout': [], 'onmousemove': [], 'style': []}
+\ ],
+\ 'legend': [
+\ ['tt', 'i', 'b', 'u', 's', 'strike', 'big', 'small', 'em', 'strong', 'dfn', 'code', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'a', 'img', 'applet', 'object', 'font', 'basefont', 'br', 'script', 'map', 'q', 'sub', 'sup', 'span', 'bdo', 'iframe', 'input', 'select', 'textarea', 'label', 'button'],
+\ { 'ondblclick': [], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'align': ['top', 'bottom', 'left', 'right'], 'lang': [], 'onkeypress': [], 'onmousedown': [], 'class': [], 'title': [], 'onclick': [], 'accesskey': [], 'dir': ['ltr', 'rtl'], 'onmouseout': [], 'onmousemove': [], 'style': []}
+\ ],
+\ 'li': [
+\ ['p', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'ul', 'ol', 'dir', 'menu', 'pre', 'dl', 'div', 'center', 'noscript', 'noframes', 'blockquote', 'form', 'isindex', 'hr', 'table', 'fieldset', 'address', 'tt', 'i', 'b', 'u', 's', 'strike', 'big', 'small', 'em', 'strong', 'dfn', 'code', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'a', 'img', 'applet', 'object', 'font', 'basefont', 'br', 'script', 'map', 'q', 'sub', 'sup', 'span', 'bdo', 'iframe', 'input', 'select', 'textarea', 'label', 'button'],
+\ { 'ondblclick': [], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'value': [], 'onkeypress': [], 'onmousedown': [], 'type': [], 'class': [], 'title': [], 'onclick': [], 'dir': ['ltr', 'rtl'], 'onmouseout': [], 'onmousemove': [], 'style': []}
+\ ],
+\ 'link': [
+\ [],
+\ { 'rel': [], 'ondblclick': [], 'onkeydown': [], 'target': [], 'onkeyup': [], 'href': [], 'media': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'charset': [], 'hreflang': [], 'onkeypress': [], 'onmousedown': [], 'rev': [], 'class': [], 'title': [], 'onclick': [], 'type': [], 'dir': ['ltr', 'rtl'], 'onmouseout': [], 'onmousemove': [], 'style': []}
+\ ],
+\ 'map': [
+\ ['p', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'ul', 'ol', 'dir', 'menu', 'pre', 'dl', 'div', 'center', 'noscript', 'noframes', 'blockquote', 'form', 'isindex', 'hr', 'table', 'fieldset', 'address', 'area'],
+\ { 'ondblclick': [], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'name': [], 'onkeypress': [], 'onmousedown': [], 'class': [], 'title': [], 'onclick': [], 'dir': ['ltr', 'rtl'], 'onmouseout': [], 'onmousemove': [], 'style': []}
+\ ],
+\ 'menu': [
+\ ['li'],
+\ { 'ondblclick': [], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'compact': ['BOOL'], 'onmouseover': [], 'lang': [], 'onmousedown': [], 'onkeypress': [], 'onclick': [], 'title': [], 'class': [], 'dir': ['ltr', 'rtl'], 'style': [], 'onmousemove': [], 'onmouseout': []}
+\ ],
+\ 'meta': [
+\ [],
+\ { 'http-equiv': [], 'content': [], 'lang': [], 'name': [], 'scheme': [], 'dir': ['ltr', 'rtl']}
+\ ],
+\ 'noframes': [
+\ ['p', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'ul', 'ol', 'dir', 'menu', 'pre', 'dl', 'div', 'center', 'noscript', 'noframes', 'blockquote', 'form', 'isindex', 'hr', 'table', 'fieldset', 'address', 'tt', 'i', 'b', 'u', 's', 'strike', 'big', 'small', 'em', 'strong', 'dfn', 'code', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'a', 'img', 'applet', 'object', 'font', 'basefont', 'br', 'script', 'map', 'q', 'sub', 'sup', 'span', 'bdo', 'iframe', 'input', 'select', 'textarea', 'label', 'button'],
+\ { 'ondblclick': [], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'onmousedown': [], 'onkeypress': [], 'onclick': [], 'title': [], 'class': [], 'dir': ['ltr', 'rtl'], 'style': [], 'onmousemove': [], 'onmouseout': []}
+\ ],
+\ 'noscript': [
+\ ['p', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'ul', 'ol', 'dir', 'menu', 'pre', 'dl', 'div', 'center', 'noscript', 'noframes', 'blockquote', 'form', 'isindex', 'hr', 'table', 'fieldset', 'address', 'tt', 'i', 'b', 'u', 's', 'strike', 'big', 'small', 'em', 'strong', 'dfn', 'code', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'a', 'img', 'applet', 'object', 'font', 'basefont', 'br', 'script', 'map', 'q', 'sub', 'sup', 'span', 'bdo', 'iframe', 'input', 'select', 'textarea', 'label', 'button'],
+\ { 'ondblclick': [], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'onmousedown': [], 'onkeypress': [], 'onclick': [], 'title': [], 'class': [], 'dir': ['ltr', 'rtl'], 'style': [], 'onmousemove': [], 'onmouseout': []}
+\ ],
+\ 'object': [
+\ ['param', 'p', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'ul', 'ol', 'dir', 'menu', 'pre', 'dl', 'div', 'center', 'noscript', 'noframes', 'blockquote', 'form', 'isindex', 'hr', 'table', 'fieldset', 'address', 'tt', 'i', 'b', 'u', 's', 'strike', 'big', 'small', 'em', 'strong', 'dfn', 'code', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'a', 'img', 'applet', 'object', 'font', 'basefont', 'br', 'script', 'map', 'q', 'sub', 'sup', 'span', 'bdo', 'iframe', 'input', 'select', 'textarea', 'label', 'button'],
+\ { 'ondblclick': [], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'align': ['top', 'middle', 'bottom', 'left', 'right'], 'name': [], 'data': [], 'declare': ['BOOL'], 'onkeypress': [], 'onmousedown': [], 'class': [], 'title': [], 'onclick': [], 'type': [], 'width': [], 'usemap': [], 'dir': ['ltr', 'rtl'], 'vspace': [], 'tabindex': [], 'standby': [], 'archive': [], 'classid': [], 'style': [], 'onmousemove': [], 'onmouseout': [], 'height': [], 'border': [], 'codetype': [], 'hspace': [], 'codebase': []}
+\ ],
+\ 'ol': [
+\ ['li'],
+\ { 'ondblclick': [], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'compact': ['BOOL'], 'onmouseover': [], 'lang': [], 'onkeypress': [], 'onmousedown': [], 'type': [], 'class': [], 'title': [], 'onclick': [], 'start': [], 'dir': ['ltr', 'rtl'], 'onmouseout': [], 'onmousemove': [], 'style': []}
+\ ],
+\ 'optgroup': [
+\ ['option'],
+\ { 'ondblclick': [], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'onkeypress': [], 'onmousedown': [], 'class': [], 'title': [], 'onclick': [], 'label': [], 'disabled': ['BOOL'], 'dir': ['ltr', 'rtl'], 'onmouseout': [], 'onmousemove': [], 'style': []}
+\ ],
+\ 'option': [
+\ [''],
+\ { 'ondblclick': [], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'value': [], 'onkeypress': [], 'onmousedown': [], 'class': [], 'title': [], 'onclick': [], 'label': [], 'disabled': ['BOOL'], 'dir': ['ltr', 'rtl'], 'onmouseout': [], 'onmousemove': [], 'style': [], 'selected': ['BOOL']}
+\ ],
+\ 'p': [
+\ ['tt', 'i', 'b', 'u', 's', 'strike', 'big', 'small', 'em', 'strong', 'dfn', 'code', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'a', 'img', 'applet', 'object', 'font', 'basefont', 'br', 'script', 'map', 'q', 'sub', 'sup', 'span', 'bdo', 'iframe', 'input', 'select', 'textarea', 'label', 'button'],
+\ { 'ondblclick': [], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'align': ['left', 'center', 'right', 'justify'], 'lang': [], 'onkeypress': [], 'onmousedown': [], 'class': [], 'title': [], 'onclick': [], 'dir': ['ltr', 'rtl'], 'onmouseout': [], 'onmousemove': [], 'style': []}
+\ ],
+\ 'param': [
+\ [],
+\ { 'id': [], 'value': [], 'name': [], 'type': [], 'valuetype': ['DATA', 'REF', 'OBJECT']}
+\ ],
+\ 'pre': [
+\ ['tt', 'i', 'b', 'u', 's', 'strike', 'em', 'strong', 'dfn', 'code', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'a', 'br', 'script', 'map', 'q', 'span', 'bdo', 'iframe', 'input', 'select', 'textarea', 'label', 'button'],
+\ { 'ondblclick': [], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'onmousedown': [], 'onkeypress': [], 'onclick': [], 'title': [], 'class': [], 'width': [], 'dir': ['ltr', 'rtl'], 'style': [], 'onmousemove': [], 'onmouseout': []}
+\ ],
+\ 'q': [
+\ ['tt', 'i', 'b', 'u', 's', 'strike', 'big', 'small', 'em', 'strong', 'dfn', 'code', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'a', 'img', 'applet', 'object', 'font', 'basefont', 'br', 'script', 'map', 'q', 'sub', 'sup', 'span', 'bdo', 'iframe', 'input', 'select', 'textarea', 'label', 'button'],
+\ { 'ondblclick': [], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'onmousedown': [], 'onkeypress': [], 'onclick': [], 'title': [], 'class': [], 'dir': ['ltr', 'rtl'], 'cite': [], 'style': [], 'onmousemove': [], 'onmouseout': []}
+\ ],
+\ 's': [
+\ ['tt', 'i', 'b', 'u', 's', 'strike', 'big', 'small', 'em', 'strong', 'dfn', 'code', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'a', 'img', 'applet', 'object', 'font', 'basefont', 'br', 'script', 'map', 'q', 'sub', 'sup', 'span', 'bdo', 'iframe', 'input', 'select', 'textarea', 'label', 'button'],
+\ { 'ondblclick': [], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'onmousedown': [], 'onkeypress': [], 'onclick': [], 'title': [], 'class': [], 'dir': ['ltr', 'rtl'], 'style': [], 'onmousemove': [], 'onmouseout': []}
+\ ],
+\ 'samp': [
+\ ['tt', 'i', 'b', 'u', 's', 'strike', 'big', 'small', 'em', 'strong', 'dfn', 'code', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'a', 'img', 'applet', 'object', 'font', 'basefont', 'br', 'script', 'map', 'q', 'sub', 'sup', 'span', 'bdo', 'iframe', 'input', 'select', 'textarea', 'label', 'button'],
+\ { 'ondblclick': [], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'onmousedown': [], 'onkeypress': [], 'onclick': [], 'title': [], 'class': [], 'dir': ['ltr', 'rtl'], 'style': [], 'onmousemove': [], 'onmouseout': []}
+\ ],
+\ 'script': [
+\ [],
+\ { 'src': [], 'for': [], 'charset': [], 'event': [], 'type': [], 'defer': ['BOOL'], 'language': []}
+\ ],
+\ 'select': [
+\ ['optgroup', 'option'],
+\ { 'ondblclick': [], 'onkeydown': [], 'onchange': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'name': [], 'onkeypress': [], 'onmousedown': [], 'class': [], 'title': [], 'onclick': [], 'disabled': ['BOOL'], 'dir': ['ltr', 'rtl'], 'size': [], 'onblur': [], 'onfocus': [], 'tabindex': [], 'onmouseout': [], 'onmousemove': [], 'style': [], 'multiple': ['BOOL']}
+\ ],
+\ 'small': [
+\ ['tt', 'i', 'b', 'u', 's', 'strike', 'big', 'small', 'em', 'strong', 'dfn', 'code', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'a', 'img', 'applet', 'object', 'font', 'basefont', 'br', 'script', 'map', 'q', 'sub', 'sup', 'span', 'bdo', 'iframe', 'input', 'select', 'textarea', 'label', 'button'],
+\ { 'ondblclick': [], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'onmousedown': [], 'onkeypress': [], 'onclick': [], 'title': [], 'class': [], 'dir': ['ltr', 'rtl'], 'style': [], 'onmousemove': [], 'onmouseout': []}
+\ ],
+\ 'span': [
+\ ['tt', 'i', 'b', 'u', 's', 'strike', 'big', 'small', 'em', 'strong', 'dfn', 'code', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'a', 'img', 'applet', 'object', 'font', 'basefont', 'br', 'script', 'map', 'q', 'sub', 'sup', 'span', 'bdo', 'iframe', 'input', 'select', 'textarea', 'label', 'button'],
+\ { 'ondblclick': [], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'onmousedown': [], 'onkeypress': [], 'onclick': [], 'title': [], 'class': [], 'dir': ['ltr', 'rtl'], 'style': [], 'onmousemove': [], 'onmouseout': []}
+\ ],
+\ 'strike': [
+\ ['tt', 'i', 'b', 'u', 's', 'strike', 'big', 'small', 'em', 'strong', 'dfn', 'code', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'a', 'img', 'applet', 'object', 'font', 'basefont', 'br', 'script', 'map', 'q', 'sub', 'sup', 'span', 'bdo', 'iframe', 'input', 'select', 'textarea', 'label', 'button'],
+\ { 'ondblclick': [], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'onmousedown': [], 'onkeypress': [], 'onclick': [], 'title': [], 'class': [], 'dir': ['ltr', 'rtl'], 'style': [], 'onmousemove': [], 'onmouseout': []}
+\ ],
+\ 'strong': [
+\ ['tt', 'i', 'b', 'u', 's', 'strike', 'big', 'small', 'em', 'strong', 'dfn', 'code', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'a', 'img', 'applet', 'object', 'font', 'basefont', 'br', 'script', 'map', 'q', 'sub', 'sup', 'span', 'bdo', 'iframe', 'input', 'select', 'textarea', 'label', 'button'],
+\ { 'ondblclick': [], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'onmousedown': [], 'onkeypress': [], 'onclick': [], 'title': [], 'class': [], 'dir': ['ltr', 'rtl'], 'style': [], 'onmousemove': [], 'onmouseout': []}
+\ ],
+\ 'style': [
+\ [],
+\ { 'media': [], 'lang': [], 'type': [], 'title': [], 'dir': ['ltr', 'rtl']}
+\ ],
+\ 'sub': [
+\ ['tt', 'i', 'b', 'u', 's', 'strike', 'big', 'small', 'em', 'strong', 'dfn', 'code', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'a', 'img', 'applet', 'object', 'font', 'basefont', 'br', 'script', 'map', 'q', 'sub', 'sup', 'span', 'bdo', 'iframe', 'input', 'select', 'textarea', 'label', 'button'],
+\ { 'ondblclick': [], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'onmousedown': [], 'onkeypress': [], 'onclick': [], 'title': [], 'class': [], 'dir': ['ltr', 'rtl'], 'style': [], 'onmousemove': [], 'onmouseout': []}
+\ ],
+\ 'sup': [
+\ ['tt', 'i', 'b', 'u', 's', 'strike', 'big', 'small', 'em', 'strong', 'dfn', 'code', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'a', 'img', 'applet', 'object', 'font', 'basefont', 'br', 'script', 'map', 'q', 'sub', 'sup', 'span', 'bdo', 'iframe', 'input', 'select', 'textarea', 'label', 'button'],
+\ { 'ondblclick': [], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'onmousedown': [], 'onkeypress': [], 'onclick': [], 'title': [], 'class': [], 'dir': ['ltr', 'rtl'], 'style': [], 'onmousemove': [], 'onmouseout': []}
+\ ],
+\ 'table': [
+\ ['caption', 'col', 'colgroup', 'thead', 'tfoot', 'tbody'],
+\ { 'ondblclick': [], 'onkeydown': [], 'onkeyup': [], 'datapagesize': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'align': ['left', 'center', 'right'], 'onkeypress': [], 'onmousedown': [], 'class': [], 'title': [], 'onclick': [], 'width': [], 'frame': ['void', 'above', 'below', 'hsides', 'lhs', 'rhs', 'vsides', 'box', 'border'], 'rules': ['none', 'groups', 'rows', 'cols', 'all'], 'dir': ['ltr', 'rtl'], 'summary': [], 'bgcolor': [], 'cellspacing': [], 'onmouseout': [], 'onmousemove': [], 'style': [], 'border': [], 'cellpadding': []}
+\ ],
+\ 'tbody': [
+\ ['tr'],
+\ { 'ondblclick': [], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'align': ['left', 'center', 'right', 'justify', 'char'], 'lang': [], 'valign': ['top', 'middle', 'bottom', 'baseline'], 'onkeypress': [], 'onmousedown': [], 'class': [], 'title': [], 'onclick': [], 'dir': ['ltr', 'rtl'], 'charoff': [], 'onmouseout': [], 'onmousemove': [], 'style': [], 'char': []}
+\ ],
+\ 'td': [
+\ ['p', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'ul', 'ol', 'dir', 'menu', 'pre', 'dl', 'div', 'center', 'noscript', 'noframes', 'blockquote', 'form', 'isindex', 'hr', 'table', 'fieldset', 'address', 'tt', 'i', 'b', 'u', 's', 'strike', 'big', 'small', 'em', 'strong', 'dfn', 'code', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'a', 'img', 'applet', 'object', 'font', 'basefont', 'br', 'script', 'map', 'q', 'sub', 'sup', 'span', 'bdo', 'iframe', 'input', 'select', 'textarea', 'label', 'button'],
+\ { 'ondblclick': [], 'axis': [], 'onkeydown': [], 'abbr': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'scope': ['row', 'col', 'rowgroup', 'colgroup'], 'onmouseover': [], 'lang': [], 'align': ['left', 'center', 'right', 'justify', 'char'], 'valign': ['top', 'middle', 'bottom', 'baseline'], 'onkeypress': [], 'onmousedown': [], 'class': [], 'title': [], 'onclick': [], 'width': [], 'headers': [], 'nowrap': ['BOOL'], 'dir': ['ltr', 'rtl'], 'rowspan': ['1'], 'colspan': ['1'], 'bgcolor': [], 'charoff': [], 'onmouseout': [], 'onmousemove': [], 'style': [], 'height': [], 'char': []}
+\ ],
+\ 'textarea': [
+\ [''],
+\ { 'ondblclick': [], 'cols': [], 'onkeydown': [], 'readonly': ['BOOL'], 'onchange': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'name': [], 'onkeypress': [], 'onmousedown': [], 'class': [], 'title': [], 'onclick': [], 'accesskey': [], 'disabled': ['BOOL'], 'rows': [], 'dir': ['ltr', 'rtl'], 'onblur': [], 'onfocus': [], 'onselect': [], 'tabindex': [], 'onmouseout': [], 'onmousemove': [], 'style': []}
+\ ],
+\ 'tfoot': [
+\ ['tr'],
+\ { 'ondblclick': [], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'align': ['left', 'center', 'right', 'justify', 'char'], 'lang': [], 'valign': ['top', 'middle', 'bottom', 'baseline'], 'onkeypress': [], 'onmousedown': [], 'class': [], 'title': [], 'onclick': [], 'dir': ['ltr', 'rtl'], 'charoff': [], 'onmouseout': [], 'onmousemove': [], 'style': [], 'char': []}
+\ ],
+\ 'th': [
+\ ['p', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'ul', 'ol', 'dir', 'menu', 'pre', 'dl', 'div', 'center', 'noscript', 'noframes', 'blockquote', 'form', 'isindex', 'hr', 'table', 'fieldset', 'address', 'tt', 'i', 'b', 'u', 's', 'strike', 'big', 'small', 'em', 'strong', 'dfn', 'code', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'a', 'img', 'applet', 'object', 'font', 'basefont', 'br', 'script', 'map', 'q', 'sub', 'sup', 'span', 'bdo', 'iframe', 'input', 'select', 'textarea', 'label', 'button'],
+\ { 'ondblclick': [], 'axis': [], 'onkeydown': [], 'abbr': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'scope': ['row', 'col', 'rowgroup', 'colgroup'], 'onmouseover': [], 'lang': [], 'align': ['left', 'center', 'right', 'justify', 'char'], 'valign': ['top', 'middle', 'bottom', 'baseline'], 'onkeypress': [], 'onmousedown': [], 'class': [], 'title': [], 'onclick': [], 'width': [], 'headers': [], 'nowrap': ['BOOL'], 'dir': ['ltr', 'rtl'], 'rowspan': ['1'], 'colspan': ['1'], 'bgcolor': [], 'charoff': [], 'onmouseout': [], 'onmousemove': [], 'style': [], 'height': [], 'char': []}
+\ ],
+\ 'thead': [
+\ ['tr'],
+\ { 'ondblclick': [], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'align': ['left', 'center', 'right', 'justify', 'char'], 'lang': [], 'valign': ['top', 'middle', 'bottom', 'baseline'], 'onkeypress': [], 'onmousedown': [], 'class': [], 'title': [], 'onclick': [], 'dir': ['ltr', 'rtl'], 'charoff': [], 'onmouseout': [], 'onmousemove': [], 'style': [], 'char': []}
+\ ],
+\ 'title': [
+\ [''],
+\ { 'lang': [], 'dir': ['ltr', 'rtl']}
+\ ],
+\ 'tr': [
+\ ['th', 'td'],
+\ { 'ondblclick': [], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'align': ['left', 'center', 'right', 'justify', 'char'], 'lang': [], 'valign': ['top', 'middle', 'bottom', 'baseline'], 'onkeypress': [], 'onmousedown': [], 'class': [], 'title': [], 'onclick': [], 'dir': ['ltr', 'rtl'], 'bgcolor': [], 'charoff': [], 'onmouseout': [], 'onmousemove': [], 'style': [], 'char': []}
+\ ],
+\ 'tt': [
+\ ['tt', 'i', 'b', 'u', 's', 'strike', 'big', 'small', 'em', 'strong', 'dfn', 'code', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'a', 'img', 'applet', 'object', 'font', 'basefont', 'br', 'script', 'map', 'q', 'sub', 'sup', 'span', 'bdo', 'iframe', 'input', 'select', 'textarea', 'label', 'button'],
+\ { 'ondblclick': [], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'onmousedown': [], 'onkeypress': [], 'onclick': [], 'title': [], 'class': [], 'dir': ['ltr', 'rtl'], 'style': [], 'onmousemove': [], 'onmouseout': []}
+\ ],
+\ 'u': [
+\ ['tt', 'i', 'b', 'u', 's', 'strike', 'big', 'small', 'em', 'strong', 'dfn', 'code', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'a', 'img', 'applet', 'object', 'font', 'basefont', 'br', 'script', 'map', 'q', 'sub', 'sup', 'span', 'bdo', 'iframe', 'input', 'select', 'textarea', 'label', 'button'],
+\ { 'ondblclick': [], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'onmousedown': [], 'onkeypress': [], 'onclick': [], 'title': [], 'class': [], 'dir': ['ltr', 'rtl'], 'style': [], 'onmousemove': [], 'onmouseout': []}
+\ ],
+\ 'ul': [
+\ ['li'],
+\ { 'ondblclick': [], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'compact': ['BOOL'], 'onmouseover': [], 'lang': [], 'onkeypress': [], 'onmousedown': [], 'type': ['disc', 'square', 'circle'], 'class': [], 'title': [], 'onclick': [], 'dir': ['ltr', 'rtl'], 'onmouseout': [], 'onmousemove': [], 'style': []}
+\ ],
+\ 'var': [
+\ ['tt', 'i', 'b', 'u', 's', 'strike', 'big', 'small', 'em', 'strong', 'dfn', 'code', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'a', 'img', 'applet', 'object', 'font', 'basefont', 'br', 'script', 'map', 'q', 'sub', 'sup', 'span', 'bdo', 'iframe', 'input', 'select', 'textarea', 'label', 'button'],
+\ { 'ondblclick': [], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'onmousedown': [], 'onkeypress': [], 'onclick': [], 'title': [], 'class': [], 'dir': ['ltr', 'rtl'], 'style': [], 'onmousemove': [], 'onmouseout': []}
+\ ],
+\ 'vimxmlattrinfo' : {
+\ 'accept' : ['ContentType', ''],
+\ 'accesskey' : ['Character', ''],
+\ 'action' : ['*URI', ''],
+\ 'align' : ['String', ''],
+\ 'alt' : ['*Text', ''],
+\ 'archive' : ['UriList', ''],
+\ 'axis' : ['CDATA', ''],
+\ 'border' : ['Pixels', ''],
+\ 'cellpadding' : ['Length', ''],
+\ 'cellspacing' : ['Length', ''],
+\ 'char' : ['Character', ''],
+\ 'charoff' : ['Length', ''],
+\ 'charset' : ['LangCode', ''],
+\ 'checked' : ['Bool', ''],
+\ 'class' : ['CDATA', ''],
+\ 'codetype' : ['ContentType', ''],
+\ 'cols' : ['*Number', ''],
+\ 'colspan' : ['Number', ''],
+\ 'content' : ['*CDATA', ''],
+\ 'coords' : ['Coords', ''],
+\ 'data' : ['URI', ''],
+\ 'datetime' : ['DateTime', ''],
+\ 'declare' : ['Bool', ''],
+\ 'defer' : ['Bool', ''],
+\ 'dir' : ['String', ''],
+\ 'disabled' : ['Bool', ''],
+\ 'enctype' : ['ContentType', ''],
+\ 'for' : ['ID', ''],
+\ 'headers' : ['IDREFS', ''],
+\ 'height' : ['Number', ''],
+\ 'href' : ['*URI', ''],
+\ 'hreflang' : ['LangCode', ''],
+\ 'id' : ['ID', ''],
+\ 'ismap' : ['Bool', ''],
+\ 'label' : ['*Text', ''],
+\ 'lang' : ['LangCode', ''],
+\ 'longdesc' : ['URI', ''],
+\ 'maxlength' : ['Number', ''],
+\ 'media' : ['MediaDesc', ''],
+\ 'method' : ['String', ''],
+\ 'multiple' : ['Bool', ''],
+\ 'name' : ['CDATA', ''],
+\ 'nohref' : ['Bool', ''],
+\ 'onblur' : ['Script', ''],
+\ 'onchange' : ['Script', ''],
+\ 'onclick' : ['Script', ''],
+\ 'ondblclick' : ['Script', ''],
+\ 'onfocus' : ['Script', ''],
+\ 'onkeydown' : ['Script', ''],
+\ 'onkeypress' : ['Script', ''],
+\ 'onkeyup' : ['Script', ''],
+\ 'onload' : ['Script', ''],
+\ 'onmousedown' : ['Script', ''],
+\ 'onmousemove' : ['Script', ''],
+\ 'onmouseout' : ['Script', ''],
+\ 'onmouseover' : ['Script', ''],
+\ 'onmouseup' : ['Script', ''],
+\ 'onreset' : ['Script', ''],
+\ 'onselect' : ['Script', ''],
+\ 'onsubmit' : ['Script', ''],
+\ 'onunload' : ['Script', ''],
+\ 'profile' : ['URI', ''],
+\ 'readonly' : ['Bool', ''],
+\ 'rel' : ['LinkTypes', ''],
+\ 'rev' : ['LinkTypes', ''],
+\ 'rows' : ['*Number', ''],
+\ 'rules' : ['String', ''],
+\ 'scheme' : ['CDATA', ''],
+\ 'selected' : ['Bool', ''],
+\ 'shape' : ['Shape', ''],
+\ 'size' : ['CDATA', ''],
+\ 'span' : ['Number', ''],
+\ 'src' : ['*URI', ''],
+\ 'standby' : ['Text', ''],
+\ 'style' : ['StyleSheet', ''],
+\ 'summary' : ['*Text', ''],
+\ 'tabindex' : ['Number', ''],
+\ 'title' : ['Text', ''],
+\ 'type' : ['*ContentType', ''],
+\ 'usemap' : ['URI', ''],
+\ 'valign' : ['String', ''],
+\ 'valuetype' : ['String', ''],
+\ 'width' : ['Number', ''],
+\ 'xmlns' : ['URI', '']
+\ },
+\ 'vimxmltaginfo': {
+\ 'area': ['/>', ''],
+\ 'base': ['/>', ''],
+\ 'basefont': ['/>', ''],
+\ 'br': ['/>', ''],
+\ 'col': ['/>', ''],
+\ 'hr': ['/>', ''],
+\ 'img': ['/>', ''],
+\ 'input': ['/>', ''],
+\ 'isindex': ['/>', ''],
+\ 'link': ['/>', ''],
+\ 'meta': ['/>', ''],
+\ 'param': ['/>', ''],
+\ }
+\ }
+" vim:ft=vim:ff=unix
--- /dev/null
+++ b/lib/vimfiles/autoload/xml/xhtml10f.vim
@@ -1,0 +1,470 @@
+let g:xmldata_xhtml10f = {
+\ 'vimxmlentities': ['AElig', 'Aacute', 'Acirc', 'Agrave', 'Alpha', 'Aring', 'Atilde', 'Auml', 'Beta', 'Ccedil', 'Chi', 'Dagger', 'Delta', 'ETH', 'Eacute', 'Ecirc', 'Egrave', 'Epsilon', 'Eta', 'Euml', 'Gamma', 'Iacute', 'Icirc', 'Igrave', 'Iota', 'Iuml', 'Kappa', 'Lambda', 'Mu', 'Ntilde', 'Nu', 'OElig', 'Oacute', 'Ocirc', 'Ograve', 'Omega', 'Omicron', 'Oslash', 'Otilde', 'Ouml', 'Phi', 'Pi', 'Prime', 'Psi', 'Rho', 'Scaron', 'Sigma', 'THORN', 'Tau', 'Theta', 'Uacute', 'Ucirc', 'Ugrave', 'Upsilon', 'Uuml', 'Xi', 'Yacute', 'Yuml', 'Zeta', 'aacute', 'acirc', 'acute', 'aelig', 'agrave', 'alefsym', 'alpha', 'amp', 'and', 'ang', 'apos', 'aring', 'asymp', 'atilde', 'auml', 'bdquo', 'beta', 'brvbar', 'bull', 'cap', 'ccedil', 'cedil', 'cent', 'chi', 'circ', 'clubs', 'cong', 'copy', 'crarr', 'cup', 'curren', 'dArr', 'dagger', 'darr', 'deg', 'delta', 'diams', 'divide', 'eacute', 'ecirc', 'egrave', 'empty', 'emsp', 'ensp', 'epsilon', 'equiv', 'eta', 'eth', 'euml', 'euro', 'exist', 'fnof', 'forall', 'frac12', 'frac14', 'frac34', 'frasl', 'gamma', 'ge', 'gt', 'hArr', 'harr', 'hearts', 'hellip', 'iacute', 'icirc', 'iexcl', 'igrave', 'image', 'infin', 'int', 'iota', 'iquest', 'isin', 'iuml', 'kappa', 'lArr', 'lambda', 'lang', 'laquo', 'larr', 'lceil', 'ldquo', 'le', 'lfloor', 'lowast', 'loz', 'lrm', 'lsaquo', 'lsquo', 'lt', 'macr', 'mdash', 'micro', 'middot', 'minus', 'mu', 'nabla', 'nbsp', 'ndash', 'ne', 'ni', 'not', 'notin', 'nsub', 'ntilde', 'nu', 'oacute', 'ocirc', 'oelig', 'ograve', 'oline', 'omega', 'omicron', 'oplus', 'or', 'ordf', 'ordm', 'oslash', 'otilde', 'otimes', 'ouml', 'para', 'part', 'permil', 'perp', 'phi', 'pi', 'piv', 'plusmn', 'pound', 'prime', 'prod', 'prop', 'psi', 'quot', 'rArr', 'radic', 'rang', 'raquo', 'rarr', 'rceil', 'rdquo', 'real', 'reg', 'rfloor', 'rho', 'rlm', 'rsaquo', 'rsquo', 'sbquo', 'scaron', 'sdot', 'sect', 'shy', 'sigma', 'sigmaf', 'sim', 'spades', 'sub', 'sube', 'sum', 'sup', 'sup1', 'sup2', 'sup3', 'supe', 'szlig', 'tau', 'there4', 'theta', 'thetasym', 'thinsp', 'thorn', 'tilde', 'times', 'trade', 'uArr', 'uacute', 'uarr', 'ucirc', 'ugrave', 'uml', 'upsih', 'upsilon', 'uuml', 'weierp', 'xi', 'yacute', 'yen', 'yuml', 'zeta', 'zwj', 'zwnj'],
+\ 'vimxmlroot': ['html'],
+\ 'a': [
+\ ['br', 'span', 'bdo', 'object', 'applet', 'img', 'map', 'iframe', 'tt', 'i', 'b', 'u', 's', 'strike', 'big', 'small', 'font', 'basefont', 'em', 'strong', 'dfn', 'code', 'q', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'sub', 'sup', 'input', 'select', 'textarea', 'label', 'button', 'ins', 'del', 'script'],
+\ { 'accesskey': [], 'rel': [], 'coords': [], 'ondblclick': [], 'dir': ['ltr', 'rtl'], 'onblur': [], 'onkeydown': [], 'target': [], 'onfocus': [], 'onkeyup': [], 'href': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'tabindex': [], 'onmouseout': [], 'onmousemove': [], 'style': [], 'name': [], 'charset': [], 'xml:lang': [], 'hreflang': [], 'onkeypress': [], 'onmousedown': [], 'rev': [], 'class': [], 'title': [], 'onclick': [], 'type': [], 'shape': ['rect', 'circle', 'poly', 'default']}
+\ ],
+\ 'abbr': [
+\ ['a', 'br', 'span', 'bdo', 'object', 'applet', 'img', 'map', 'iframe', 'tt', 'i', 'b', 'u', 's', 'strike', 'big', 'small', 'font', 'basefont', 'em', 'strong', 'dfn', 'code', 'q', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'sub', 'sup', 'input', 'select', 'textarea', 'label', 'button', 'ins', 'del', 'script'],
+\ { 'ondblclick': [], 'dir': ['ltr', 'rtl'], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'style': [], 'onmousemove': [], 'onmouseout': [], 'xml:lang': [], 'onmousedown': [], 'onkeypress': [], 'onclick': [], 'title': [], 'class': []}
+\ ],
+\ 'acronym': [
+\ ['a', 'br', 'span', 'bdo', 'object', 'applet', 'img', 'map', 'iframe', 'tt', 'i', 'b', 'u', 's', 'strike', 'big', 'small', 'font', 'basefont', 'em', 'strong', 'dfn', 'code', 'q', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'sub', 'sup', 'input', 'select', 'textarea', 'label', 'button', 'ins', 'del', 'script'],
+\ { 'ondblclick': [], 'dir': ['ltr', 'rtl'], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'style': [], 'onmousemove': [], 'onmouseout': [], 'xml:lang': [], 'onmousedown': [], 'onkeypress': [], 'onclick': [], 'title': [], 'class': []}
+\ ],
+\ 'address': [
+\ ['a', 'br', 'span', 'bdo', 'object', 'applet', 'img', 'map', 'iframe', 'tt', 'i', 'b', 'u', 's', 'strike', 'big', 'small', 'font', 'basefont', 'em', 'strong', 'dfn', 'code', 'q', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'sub', 'sup', 'input', 'select', 'textarea', 'label', 'button', 'ins', 'del', 'script', 'p'],
+\ { 'ondblclick': [], 'dir': ['ltr', 'rtl'], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'style': [], 'onmousemove': [], 'onmouseout': [], 'xml:lang': [], 'onmousedown': [], 'onkeypress': [], 'onclick': [], 'title': [], 'class': []}
+\ ],
+\ 'applet': [
+\ ['param', 'p', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'div', 'ul', 'ol', 'dl', 'menu', 'dir', 'pre', 'hr', 'blockquote', 'address', 'center', 'isindex', 'fieldset', 'table', 'form', 'a', 'br', 'span', 'bdo', 'object', 'applet', 'img', 'map', 'iframe', 'tt', 'i', 'b', 'u', 's', 'strike', 'big', 'small', 'font', 'basefont', 'em', 'strong', 'dfn', 'code', 'q', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'sub', 'sup', 'input', 'select', 'textarea', 'label', 'button', 'noscript', 'ins', 'del', 'script'],
+\ { 'width': [], 'object': [], 'id': [], 'code': [], 'vspace': [], 'archive': [], 'alt': [], 'align': ['top', 'middle', 'bottom', 'left', 'right'], 'style': [], 'name': [], 'height': [], 'hspace': [], 'title': [], 'class': [], 'codebase': []}
+\ ],
+\ 'area': [
+\ [],
+\ { 'accesskey': [], 'coords': [], 'ondblclick': [], 'dir': ['ltr', 'rtl'], 'onblur': [], 'onkeydown': [], 'onfocus': [], 'nohref': ['BOOL'], 'target': [], 'onkeyup': [], 'href': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'tabindex': [], 'lang': [], 'alt': [], 'onmouseout': [], 'onmousemove': [], 'style': [], 'xml:lang': [], 'onkeypress': [], 'onmousedown': [], 'class': [], 'title': [], 'onclick': [], 'shape': ['rect', 'circle', 'poly', 'default']}
+\ ],
+\ 'b': [
+\ ['a', 'br', 'span', 'bdo', 'object', 'applet', 'img', 'map', 'iframe', 'tt', 'i', 'b', 'u', 's', 'strike', 'big', 'small', 'font', 'basefont', 'em', 'strong', 'dfn', 'code', 'q', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'sub', 'sup', 'input', 'select', 'textarea', 'label', 'button', 'ins', 'del', 'script'],
+\ { 'ondblclick': [], 'dir': ['ltr', 'rtl'], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'style': [], 'onmousemove': [], 'onmouseout': [], 'xml:lang': [], 'onmousedown': [], 'onkeypress': [], 'onclick': [], 'title': [], 'class': []}
+\ ],
+\ 'base': [
+\ [],
+\ { 'target': [], 'href': [], 'id': []}
+\ ],
+\ 'basefont': [
+\ [],
+\ { 'size': [], 'face': [], 'color': [], 'id': []}
+\ ],
+\ 'bdo': [
+\ ['a', 'br', 'span', 'bdo', 'object', 'applet', 'img', 'map', 'iframe', 'tt', 'i', 'b', 'u', 's', 'strike', 'big', 'small', 'font', 'basefont', 'em', 'strong', 'dfn', 'code', 'q', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'sub', 'sup', 'input', 'select', 'textarea', 'label', 'button', 'ins', 'del', 'script'],
+\ { 'ondblclick': [], 'dir': ['ltr', 'rtl'], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'style': [], 'onmousemove': [], 'onmouseout': [], 'xml:lang': [], 'onmousedown': [], 'onkeypress': [], 'onclick': [], 'title': [], 'class': []}
+\ ],
+\ 'big': [
+\ ['a', 'br', 'span', 'bdo', 'object', 'applet', 'img', 'map', 'iframe', 'tt', 'i', 'b', 'u', 's', 'strike', 'big', 'small', 'font', 'basefont', 'em', 'strong', 'dfn', 'code', 'q', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'sub', 'sup', 'input', 'select', 'textarea', 'label', 'button', 'ins', 'del', 'script'],
+\ { 'ondblclick': [], 'dir': ['ltr', 'rtl'], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'style': [], 'onmousemove': [], 'onmouseout': [], 'xml:lang': [], 'onmousedown': [], 'onkeypress': [], 'onclick': [], 'title': [], 'class': []}
+\ ],
+\ 'blockquote': [
+\ ['p', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'div', 'ul', 'ol', 'dl', 'menu', 'dir', 'pre', 'hr', 'blockquote', 'address', 'center', 'isindex', 'fieldset', 'table', 'form', 'a', 'br', 'span', 'bdo', 'object', 'applet', 'img', 'map', 'iframe', 'tt', 'i', 'b', 'u', 's', 'strike', 'big', 'small', 'font', 'basefont', 'em', 'strong', 'dfn', 'code', 'q', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'sub', 'sup', 'input', 'select', 'textarea', 'label', 'button', 'noscript', 'ins', 'del', 'script'],
+\ { 'ondblclick': [], 'dir': ['ltr', 'rtl'], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'cite': [], 'onmouseover': [], 'lang': [], 'style': [], 'onmousemove': [], 'onmouseout': [], 'xml:lang': [], 'onmousedown': [], 'onkeypress': [], 'onclick': [], 'title': [], 'class': []}
+\ ],
+\ 'body': [
+\ ['p', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'div', 'ul', 'ol', 'dl', 'menu', 'dir', 'pre', 'hr', 'blockquote', 'address', 'center', 'isindex', 'fieldset', 'table', 'form', 'a', 'br', 'span', 'bdo', 'object', 'applet', 'img', 'map', 'iframe', 'tt', 'i', 'b', 'u', 's', 'strike', 'big', 'small', 'font', 'basefont', 'em', 'strong', 'dfn', 'code', 'q', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'sub', 'sup', 'input', 'select', 'textarea', 'label', 'button', 'noscript', 'ins', 'del', 'script'],
+\ { 'vlink': [], 'ondblclick': [], 'dir': ['ltr', 'rtl'], 'onkeydown': [], 'alink': [], 'onkeyup': [], 'bgcolor': [], 'text': [], 'onmouseup': [], 'id': [], 'link': [], 'onmouseover': [], 'lang': [], 'onmouseout': [], 'onmousemove': [], 'style': [], 'background': [], 'xml:lang': [], 'onunload': [], 'onkeypress': [], 'onmousedown': [], 'onload': [], 'class': [], 'title': [], 'onclick': []}
+\ ],
+\ 'br': [
+\ [],
+\ { 'clear': ['none', 'left', 'all', 'right', 'none'], 'id': [], 'style': [], 'class': [], 'title': []}
+\ ],
+\ 'button': [
+\ ['p', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'div', 'ul', 'ol', 'dl', 'menu', 'dir', 'pre', 'hr', 'blockquote', 'address', 'center', 'table', 'br', 'span', 'bdo', 'object', 'applet', 'img', 'map', 'tt', 'i', 'b', 'u', 's', 'strike', 'big', 'small', 'font', 'basefont', 'em', 'strong', 'dfn', 'code', 'q', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'sub', 'sup', 'noscript', 'ins', 'del', 'script'],
+\ { 'accesskey': [], 'disabled': ['BOOL'], 'ondblclick': [], 'dir': ['ltr', 'rtl'], 'onblur': [], 'onkeydown': [], 'onfocus': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'tabindex': [], 'lang': [], 'value': [], 'onmouseout': [], 'onmousemove': [], 'style': [], 'name': [], 'xml:lang': [], 'onkeypress': [], 'onmousedown': [], 'class': [], 'title': [], 'onclick': [], 'type': ['submit', 'button', 'submit', 'reset']}
+\ ],
+\ 'caption': [
+\ ['a', 'br', 'span', 'bdo', 'object', 'applet', 'img', 'map', 'iframe', 'tt', 'i', 'b', 'u', 's', 'strike', 'big', 'small', 'font', 'basefont', 'em', 'strong', 'dfn', 'code', 'q', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'sub', 'sup', 'input', 'select', 'textarea', 'label', 'button', 'ins', 'del', 'script'],
+\ { 'ondblclick': [], 'dir': ['ltr', 'rtl'], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'align': ['top', 'bottom', 'left', 'right'], 'lang': [], 'onmouseout': [], 'onmousemove': [], 'style': [], 'xml:lang': [], 'onkeypress': [], 'onmousedown': [], 'class': [], 'title': [], 'onclick': []}
+\ ],
+\ 'center': [
+\ ['p', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'div', 'ul', 'ol', 'dl', 'menu', 'dir', 'pre', 'hr', 'blockquote', 'address', 'center', 'isindex', 'fieldset', 'table', 'form', 'a', 'br', 'span', 'bdo', 'object', 'applet', 'img', 'map', 'iframe', 'tt', 'i', 'b', 'u', 's', 'strike', 'big', 'small', 'font', 'basefont', 'em', 'strong', 'dfn', 'code', 'q', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'sub', 'sup', 'input', 'select', 'textarea', 'label', 'button', 'noscript', 'ins', 'del', 'script'],
+\ { 'ondblclick': [], 'dir': ['ltr', 'rtl'], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'style': [], 'onmousemove': [], 'onmouseout': [], 'xml:lang': [], 'onmousedown': [], 'onkeypress': [], 'onclick': [], 'title': [], 'class': []}
+\ ],
+\ 'cite': [
+\ ['a', 'br', 'span', 'bdo', 'object', 'applet', 'img', 'map', 'iframe', 'tt', 'i', 'b', 'u', 's', 'strike', 'big', 'small', 'font', 'basefont', 'em', 'strong', 'dfn', 'code', 'q', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'sub', 'sup', 'input', 'select', 'textarea', 'label', 'button', 'ins', 'del', 'script'],
+\ { 'ondblclick': [], 'dir': ['ltr', 'rtl'], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'style': [], 'onmousemove': [], 'onmouseout': [], 'xml:lang': [], 'onmousedown': [], 'onkeypress': [], 'onclick': [], 'title': [], 'class': []}
+\ ],
+\ 'code': [
+\ ['a', 'br', 'span', 'bdo', 'object', 'applet', 'img', 'map', 'iframe', 'tt', 'i', 'b', 'u', 's', 'strike', 'big', 'small', 'font', 'basefont', 'em', 'strong', 'dfn', 'code', 'q', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'sub', 'sup', 'input', 'select', 'textarea', 'label', 'button', 'ins', 'del', 'script'],
+\ { 'ondblclick': [], 'dir': ['ltr', 'rtl'], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'style': [], 'onmousemove': [], 'onmouseout': [], 'xml:lang': [], 'onmousedown': [], 'onkeypress': [], 'onclick': [], 'title': [], 'class': []}
+\ ],
+\ 'col': [
+\ [],
+\ { 'width': [], 'ondblclick': [], 'dir': ['ltr', 'rtl'], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'charoff': [], 'onmouseover': [], 'lang': [], 'align': ['left', 'center', 'right', 'justify', 'char'], 'valign': ['top', 'middle', 'bottom', 'baseline'], 'onmouseout': [], 'onmousemove': [], 'style': [], 'xml:lang': [], 'onkeypress': [], 'onmousedown': [], 'char': [], 'span': ['1'], 'class': [], 'title': [], 'onclick': []}
+\ ],
+\ 'colgroup': [
+\ ['col'],
+\ { 'width': [], 'ondblclick': [], 'dir': ['ltr', 'rtl'], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'charoff': [], 'onmouseover': [], 'lang': [], 'align': ['left', 'center', 'right', 'justify', 'char'], 'valign': ['top', 'middle', 'bottom', 'baseline'], 'onmouseout': [], 'onmousemove': [], 'style': [], 'xml:lang': [], 'onkeypress': [], 'onmousedown': [], 'char': [], 'span': ['1'], 'class': [], 'title': [], 'onclick': []}
+\ ],
+\ 'dd': [
+\ ['p', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'div', 'ul', 'ol', 'dl', 'menu', 'dir', 'pre', 'hr', 'blockquote', 'address', 'center', 'isindex', 'fieldset', 'table', 'form', 'a', 'br', 'span', 'bdo', 'object', 'applet', 'img', 'map', 'iframe', 'tt', 'i', 'b', 'u', 's', 'strike', 'big', 'small', 'font', 'basefont', 'em', 'strong', 'dfn', 'code', 'q', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'sub', 'sup', 'input', 'select', 'textarea', 'label', 'button', 'noscript', 'ins', 'del', 'script'],
+\ { 'ondblclick': [], 'dir': ['ltr', 'rtl'], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'style': [], 'onmousemove': [], 'onmouseout': [], 'xml:lang': [], 'onmousedown': [], 'onkeypress': [], 'onclick': [], 'title': [], 'class': []}
+\ ],
+\ 'del': [
+\ ['p', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'div', 'ul', 'ol', 'dl', 'menu', 'dir', 'pre', 'hr', 'blockquote', 'address', 'center', 'isindex', 'fieldset', 'table', 'form', 'a', 'br', 'span', 'bdo', 'object', 'applet', 'img', 'map', 'iframe', 'tt', 'i', 'b', 'u', 's', 'strike', 'big', 'small', 'font', 'basefont', 'em', 'strong', 'dfn', 'code', 'q', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'sub', 'sup', 'input', 'select', 'textarea', 'label', 'button', 'noscript', 'ins', 'del', 'script'],
+\ { 'ondblclick': [], 'dir': ['ltr', 'rtl'], 'datetime': [], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'cite': [], 'onmouseover': [], 'lang': [], 'onmouseout': [], 'onmousemove': [], 'style': [], 'xml:lang': [], 'onkeypress': [], 'onmousedown': [], 'class': [], 'title': [], 'onclick': []}
+\ ],
+\ 'dfn': [
+\ ['a', 'br', 'span', 'bdo', 'object', 'applet', 'img', 'map', 'iframe', 'tt', 'i', 'b', 'u', 's', 'strike', 'big', 'small', 'font', 'basefont', 'em', 'strong', 'dfn', 'code', 'q', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'sub', 'sup', 'input', 'select', 'textarea', 'label', 'button', 'ins', 'del', 'script'],
+\ { 'ondblclick': [], 'dir': ['ltr', 'rtl'], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'style': [], 'onmousemove': [], 'onmouseout': [], 'xml:lang': [], 'onmousedown': [], 'onkeypress': [], 'onclick': [], 'title': [], 'class': []}
+\ ],
+\ 'dir': [
+\ ['li'],
+\ { 'ondblclick': [], 'dir': ['ltr', 'rtl'], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'compact': ['BOOL'], 'onmouseover': [], 'lang': [], 'style': [], 'onmousemove': [], 'onmouseout': [], 'xml:lang': [], 'onmousedown': [], 'onkeypress': [], 'onclick': [], 'title': [], 'class': []}
+\ ],
+\ 'div': [
+\ ['p', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'div', 'ul', 'ol', 'dl', 'menu', 'dir', 'pre', 'hr', 'blockquote', 'address', 'center', 'isindex', 'fieldset', 'table', 'form', 'a', 'br', 'span', 'bdo', 'object', 'applet', 'img', 'map', 'iframe', 'tt', 'i', 'b', 'u', 's', 'strike', 'big', 'small', 'font', 'basefont', 'em', 'strong', 'dfn', 'code', 'q', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'sub', 'sup', 'input', 'select', 'textarea', 'label', 'button', 'noscript', 'ins', 'del', 'script'],
+\ { 'ondblclick': [], 'dir': ['ltr', 'rtl'], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'align': ['left', 'center', 'right', 'justify'], 'lang': [], 'onmouseout': [], 'onmousemove': [], 'style': [], 'xml:lang': [], 'onkeypress': [], 'onmousedown': [], 'class': [], 'title': [], 'onclick': []}
+\ ],
+\ 'dl': [
+\ ['dt', 'dd'],
+\ { 'ondblclick': [], 'dir': ['ltr', 'rtl'], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'compact': ['BOOL'], 'onmouseover': [], 'lang': [], 'style': [], 'onmousemove': [], 'onmouseout': [], 'xml:lang': [], 'onmousedown': [], 'onkeypress': [], 'onclick': [], 'title': [], 'class': []}
+\ ],
+\ 'dt': [
+\ ['a', 'br', 'span', 'bdo', 'object', 'applet', 'img', 'map', 'iframe', 'tt', 'i', 'b', 'u', 's', 'strike', 'big', 'small', 'font', 'basefont', 'em', 'strong', 'dfn', 'code', 'q', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'sub', 'sup', 'input', 'select', 'textarea', 'label', 'button', 'ins', 'del', 'script'],
+\ { 'ondblclick': [], 'dir': ['ltr', 'rtl'], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'style': [], 'onmousemove': [], 'onmouseout': [], 'xml:lang': [], 'onmousedown': [], 'onkeypress': [], 'onclick': [], 'title': [], 'class': []}
+\ ],
+\ 'em': [
+\ ['a', 'br', 'span', 'bdo', 'object', 'applet', 'img', 'map', 'iframe', 'tt', 'i', 'b', 'u', 's', 'strike', 'big', 'small', 'font', 'basefont', 'em', 'strong', 'dfn', 'code', 'q', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'sub', 'sup', 'input', 'select', 'textarea', 'label', 'button', 'ins', 'del', 'script'],
+\ { 'ondblclick': [], 'dir': ['ltr', 'rtl'], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'style': [], 'onmousemove': [], 'onmouseout': [], 'xml:lang': [], 'onmousedown': [], 'onkeypress': [], 'onclick': [], 'title': [], 'class': []}
+\ ],
+\ 'fieldset': [
+\ ['legend', 'p', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'div', 'ul', 'ol', 'dl', 'menu', 'dir', 'pre', 'hr', 'blockquote', 'address', 'center', 'isindex', 'fieldset', 'table', 'form', 'a', 'br', 'span', 'bdo', 'object', 'applet', 'img', 'map', 'iframe', 'tt', 'i', 'b', 'u', 's', 'strike', 'big', 'small', 'font', 'basefont', 'em', 'strong', 'dfn', 'code', 'q', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'sub', 'sup', 'input', 'select', 'textarea', 'label', 'button', 'noscript', 'ins', 'del', 'script'],
+\ { 'ondblclick': [], 'dir': ['ltr', 'rtl'], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'style': [], 'onmousemove': [], 'onmouseout': [], 'xml:lang': [], 'onmousedown': [], 'onkeypress': [], 'onclick': [], 'title': [], 'class': []}
+\ ],
+\ 'font': [
+\ ['a', 'br', 'span', 'bdo', 'object', 'applet', 'img', 'map', 'iframe', 'tt', 'i', 'b', 'u', 's', 'strike', 'big', 'small', 'font', 'basefont', 'em', 'strong', 'dfn', 'code', 'q', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'sub', 'sup', 'input', 'select', 'textarea', 'label', 'button', 'ins', 'del', 'script'],
+\ { 'dir': ['ltr', 'rtl'], 'size': [], 'face': [], 'color': [], 'id': [], 'lang': [], 'style': [], 'xml:lang': [], 'title': [], 'class': []}
+\ ],
+\ 'form': [
+\ ['p', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'div', 'ul', 'ol', 'dl', 'menu', 'dir', 'pre', 'hr', 'blockquote', 'address', 'center', 'isindex', 'fieldset', 'table', 'a', 'br', 'span', 'bdo', 'object', 'applet', 'img', 'map', 'iframe', 'tt', 'i', 'b', 'u', 's', 'strike', 'big', 'small', 'font', 'basefont', 'em', 'strong', 'dfn', 'code', 'q', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'sub', 'sup', 'input', 'select', 'textarea', 'label', 'button', 'noscript', 'ins', 'del', 'script'],
+\ { 'enctype': ['application/x-www-form-urlencoded'], 'onsubmit': [], 'ondblclick': [], 'dir': ['ltr', 'rtl'], 'onkeydown': [], 'target': [], 'onkeyup': [], 'onmouseup': [], 'onreset': [], 'id': [], 'method': ['get', 'post'], 'onmouseover': [], 'lang': [], 'accept': [], 'onmouseout': [], 'onmousemove': [], 'style': [], 'name': [], 'xml:lang': [], 'accept-charset': [], 'onkeypress': [], 'onmousedown': [], 'action': [], 'class': [], 'title': [], 'onclick': []}
+\ ],
+\ 'frame': [
+\ [],
+\ { 'scrolling': ['auto', 'yes', 'no', 'auto'], 'noresize': ['BOOL'], 'marginwidth': [], 'id': [], 'marginheight': [], 'longdesc': [], 'src': [], 'style': [], 'name': [], 'frameborder': ['1', '0'], 'title': [], 'class': []}
+\ ],
+\ 'frameset': [
+\ ['frameset', 'frame', 'noframes'],
+\ { 'rows': [], 'cols': [], 'id': [], 'style': [], 'onunload': [], 'onload': [], 'class': [], 'title': []}
+\ ],
+\ 'h1': [
+\ ['a', 'br', 'span', 'bdo', 'object', 'applet', 'img', 'map', 'iframe', 'tt', 'i', 'b', 'u', 's', 'strike', 'big', 'small', 'font', 'basefont', 'em', 'strong', 'dfn', 'code', 'q', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'sub', 'sup', 'input', 'select', 'textarea', 'label', 'button', 'ins', 'del', 'script'],
+\ { 'ondblclick': [], 'dir': ['ltr', 'rtl'], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'align': ['left', 'center', 'right', 'justify'], 'lang': [], 'onmouseout': [], 'onmousemove': [], 'style': [], 'xml:lang': [], 'onkeypress': [], 'onmousedown': [], 'class': [], 'title': [], 'onclick': []}
+\ ],
+\ 'h2': [
+\ ['a', 'br', 'span', 'bdo', 'object', 'applet', 'img', 'map', 'iframe', 'tt', 'i', 'b', 'u', 's', 'strike', 'big', 'small', 'font', 'basefont', 'em', 'strong', 'dfn', 'code', 'q', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'sub', 'sup', 'input', 'select', 'textarea', 'label', 'button', 'ins', 'del', 'script'],
+\ { 'ondblclick': [], 'dir': ['ltr', 'rtl'], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'align': ['left', 'center', 'right', 'justify'], 'lang': [], 'onmouseout': [], 'onmousemove': [], 'style': [], 'xml:lang': [], 'onkeypress': [], 'onmousedown': [], 'class': [], 'title': [], 'onclick': []}
+\ ],
+\ 'h3': [
+\ ['a', 'br', 'span', 'bdo', 'object', 'applet', 'img', 'map', 'iframe', 'tt', 'i', 'b', 'u', 's', 'strike', 'big', 'small', 'font', 'basefont', 'em', 'strong', 'dfn', 'code', 'q', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'sub', 'sup', 'input', 'select', 'textarea', 'label', 'button', 'ins', 'del', 'script'],
+\ { 'ondblclick': [], 'dir': ['ltr', 'rtl'], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'align': ['left', 'center', 'right', 'justify'], 'lang': [], 'onmouseout': [], 'onmousemove': [], 'style': [], 'xml:lang': [], 'onkeypress': [], 'onmousedown': [], 'class': [], 'title': [], 'onclick': []}
+\ ],
+\ 'h4': [
+\ ['a', 'br', 'span', 'bdo', 'object', 'applet', 'img', 'map', 'iframe', 'tt', 'i', 'b', 'u', 's', 'strike', 'big', 'small', 'font', 'basefont', 'em', 'strong', 'dfn', 'code', 'q', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'sub', 'sup', 'input', 'select', 'textarea', 'label', 'button', 'ins', 'del', 'script'],
+\ { 'ondblclick': [], 'dir': ['ltr', 'rtl'], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'align': ['left', 'center', 'right', 'justify'], 'lang': [], 'onmouseout': [], 'onmousemove': [], 'style': [], 'xml:lang': [], 'onkeypress': [], 'onmousedown': [], 'class': [], 'title': [], 'onclick': []}
+\ ],
+\ 'h5': [
+\ ['a', 'br', 'span', 'bdo', 'object', 'applet', 'img', 'map', 'iframe', 'tt', 'i', 'b', 'u', 's', 'strike', 'big', 'small', 'font', 'basefont', 'em', 'strong', 'dfn', 'code', 'q', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'sub', 'sup', 'input', 'select', 'textarea', 'label', 'button', 'ins', 'del', 'script'],
+\ { 'ondblclick': [], 'dir': ['ltr', 'rtl'], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'align': ['left', 'center', 'right', 'justify'], 'lang': [], 'onmouseout': [], 'onmousemove': [], 'style': [], 'xml:lang': [], 'onkeypress': [], 'onmousedown': [], 'class': [], 'title': [], 'onclick': []}
+\ ],
+\ 'h6': [
+\ ['a', 'br', 'span', 'bdo', 'object', 'applet', 'img', 'map', 'iframe', 'tt', 'i', 'b', 'u', 's', 'strike', 'big', 'small', 'font', 'basefont', 'em', 'strong', 'dfn', 'code', 'q', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'sub', 'sup', 'input', 'select', 'textarea', 'label', 'button', 'ins', 'del', 'script'],
+\ { 'ondblclick': [], 'dir': ['ltr', 'rtl'], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'align': ['left', 'center', 'right', 'justify'], 'lang': [], 'onmouseout': [], 'onmousemove': [], 'style': [], 'xml:lang': [], 'onkeypress': [], 'onmousedown': [], 'class': [], 'title': [], 'onclick': []}
+\ ],
+\ 'head': [
+\ ['script', 'style', 'meta', 'link', 'object', 'isindex', 'title', 'script', 'style', 'meta', 'link', 'object', 'isindex', 'base', 'script', 'style', 'meta', 'link', 'object', 'isindex', 'base', 'script', 'style', 'meta', 'link', 'object', 'isindex', 'title', 'script', 'style', 'meta', 'link', 'object', 'isindex'],
+\ { 'profile': [], 'dir': ['ltr', 'rtl'], 'id': [], 'lang': [], 'xml:lang': []}
+\ ],
+\ 'hr': [
+\ [],
+\ { 'width': [], 'ondblclick': [], 'dir': ['ltr', 'rtl'], 'size': [], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'align': ['left', 'center', 'right'], 'lang': [], 'onmouseout': [], 'onmousemove': [], 'style': [], 'xml:lang': [], 'noshade': ['BOOL'], 'onkeypress': [], 'onmousedown': [], 'class': [], 'title': [], 'onclick': []}
+\ ],
+\ 'html': [
+\ ['head', 'frameset'],
+\ { 'xmlns': ['http://www.w3.org/1999/xhtml'], 'dir': ['ltr', 'rtl'], 'id': [], 'lang': [], 'xml:lang': []}
+\ ],
+\ 'i': [
+\ ['a', 'br', 'span', 'bdo', 'object', 'applet', 'img', 'map', 'iframe', 'tt', 'i', 'b', 'u', 's', 'strike', 'big', 'small', 'font', 'basefont', 'em', 'strong', 'dfn', 'code', 'q', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'sub', 'sup', 'input', 'select', 'textarea', 'label', 'button', 'ins', 'del', 'script'],
+\ { 'ondblclick': [], 'dir': ['ltr', 'rtl'], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'style': [], 'onmousemove': [], 'onmouseout': [], 'xml:lang': [], 'onmousedown': [], 'onkeypress': [], 'onclick': [], 'title': [], 'class': []}
+\ ],
+\ 'iframe': [
+\ ['p', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'div', 'ul', 'ol', 'dl', 'menu', 'dir', 'pre', 'hr', 'blockquote', 'address', 'center', 'isindex', 'fieldset', 'table', 'form', 'a', 'br', 'span', 'bdo', 'object', 'applet', 'img', 'map', 'iframe', 'tt', 'i', 'b', 'u', 's', 'strike', 'big', 'small', 'font', 'basefont', 'em', 'strong', 'dfn', 'code', 'q', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'sub', 'sup', 'input', 'select', 'textarea', 'label', 'button', 'noscript', 'ins', 'del', 'script'],
+\ { 'width': [], 'scrolling': ['auto', 'yes', 'no', 'auto'], 'marginwidth': [], 'id': [], 'marginheight': [], 'align': ['top', 'middle', 'bottom', 'left', 'right'], 'longdesc': [], 'src': [], 'style': [], 'name': [], 'height': [], 'frameborder': ['1', '0'], 'title': [], 'class': []}
+\ ],
+\ 'img': [
+\ [],
+\ { 'width': [], 'usemap': [], 'ismap': ['BOOL'], 'ondblclick': [], 'dir': ['ltr', 'rtl'], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'vspace': [], 'onmouseover': [], 'alt': [], 'lang': [], 'align': ['top', 'middle', 'bottom', 'left', 'right'], 'src': [], 'longdesc': [], 'onmouseout': [], 'onmousemove': [], 'style': [], 'name': [], 'xml:lang': [], 'height': [], 'border': [], 'hspace': [], 'onkeypress': [], 'onmousedown': [], 'class': [], 'title': [], 'onclick': []}
+\ ],
+\ 'input': [
+\ [],
+\ { 'ondblclick': [], 'onkeydown': [], 'readonly': ['BOOL'], 'onchange': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'align': ['top', 'middle', 'bottom', 'left', 'right'], 'value': [], 'src': [], 'name': [], 'checked': ['BOOL'], 'onkeypress': [], 'onmousedown': [], 'class': [], 'title': [], 'onclick': [], 'type': ['text', 'password', 'checkbox', 'radio', 'submit', 'reset', 'file', 'hidden', 'image', 'button'], 'accesskey': [], 'disabled': ['BOOL'], 'usemap': [], 'dir': ['ltr', 'rtl'], 'onblur': [], 'size': [], 'onfocus': [], 'maxlength': [], 'onselect': [], 'accept': [], 'tabindex': [], 'alt': [], 'style': [], 'onmousemove': [], 'onmouseout': [], 'xml:lang': []}
+\ ],
+\ 'ins': [
+\ ['p', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'div', 'ul', 'ol', 'dl', 'menu', 'dir', 'pre', 'hr', 'blockquote', 'address', 'center', 'isindex', 'fieldset', 'table', 'form', 'a', 'br', 'span', 'bdo', 'object', 'applet', 'img', 'map', 'iframe', 'tt', 'i', 'b', 'u', 's', 'strike', 'big', 'small', 'font', 'basefont', 'em', 'strong', 'dfn', 'code', 'q', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'sub', 'sup', 'input', 'select', 'textarea', 'label', 'button', 'noscript', 'ins', 'del', 'script'],
+\ { 'ondblclick': [], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'onkeypress': [], 'onmousedown': [], 'class': [], 'title': [], 'onclick': [], 'dir': ['ltr', 'rtl'], 'datetime': [], 'cite': [], 'onmouseout': [], 'onmousemove': [], 'style': [], 'xml:lang': []}
+\ ],
+\ 'isindex': [
+\ [],
+\ { 'id': [], 'lang': [], 'prompt': [], 'title': [], 'class': [], 'dir': ['ltr', 'rtl'], 'style': [], 'xml:lang': []}
+\ ],
+\ 'kbd': [
+\ ['a', 'br', 'span', 'bdo', 'object', 'applet', 'img', 'map', 'iframe', 'tt', 'i', 'b', 'u', 's', 'strike', 'big', 'small', 'font', 'basefont', 'em', 'strong', 'dfn', 'code', 'q', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'sub', 'sup', 'input', 'select', 'textarea', 'label', 'button', 'ins', 'del', 'script'],
+\ { 'ondblclick': [], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'onmousedown': [], 'onkeypress': [], 'onclick': [], 'title': [], 'class': [], 'dir': ['ltr', 'rtl'], 'style': [], 'onmousemove': [], 'onmouseout': [], 'xml:lang': []}
+\ ],
+\ 'label': [
+\ ['a', 'br', 'span', 'bdo', 'object', 'applet', 'img', 'map', 'iframe', 'tt', 'i', 'b', 'u', 's', 'strike', 'big', 'small', 'font', 'basefont', 'em', 'strong', 'dfn', 'code', 'q', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'sub', 'sup', 'input', 'select', 'textarea', 'label', 'button', 'ins', 'del', 'script'],
+\ { 'ondblclick': [], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'for': [], 'onkeypress': [], 'onmousedown': [], 'class': [], 'title': [], 'onclick': [], 'accesskey': [], 'dir': ['ltr', 'rtl'], 'onblur': [], 'onfocus': [], 'onmouseout': [], 'onmousemove': [], 'style': [], 'xml:lang': []}
+\ ],
+\ 'legend': [
+\ ['a', 'br', 'span', 'bdo', 'object', 'applet', 'img', 'map', 'iframe', 'tt', 'i', 'b', 'u', 's', 'strike', 'big', 'small', 'font', 'basefont', 'em', 'strong', 'dfn', 'code', 'q', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'sub', 'sup', 'input', 'select', 'textarea', 'label', 'button', 'ins', 'del', 'script'],
+\ { 'ondblclick': [], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'align': ['top', 'bottom', 'left', 'right'], 'lang': [], 'onkeypress': [], 'onmousedown': [], 'class': [], 'title': [], 'onclick': [], 'accesskey': [], 'dir': ['ltr', 'rtl'], 'onmouseout': [], 'onmousemove': [], 'style': [], 'xml:lang': []}
+\ ],
+\ 'li': [
+\ ['p', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'div', 'ul', 'ol', 'dl', 'menu', 'dir', 'pre', 'hr', 'blockquote', 'address', 'center', 'isindex', 'fieldset', 'table', 'form', 'a', 'br', 'span', 'bdo', 'object', 'applet', 'img', 'map', 'iframe', 'tt', 'i', 'b', 'u', 's', 'strike', 'big', 'small', 'font', 'basefont', 'em', 'strong', 'dfn', 'code', 'q', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'sub', 'sup', 'input', 'select', 'textarea', 'label', 'button', 'noscript', 'ins', 'del', 'script'],
+\ { 'ondblclick': [], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'value': [], 'onkeypress': [], 'onmousedown': [], 'type': [], 'class': [], 'title': [], 'onclick': [], 'dir': ['ltr', 'rtl'], 'onmouseout': [], 'onmousemove': [], 'style': [], 'xml:lang': []}
+\ ],
+\ 'link': [
+\ [],
+\ { 'rel': [], 'ondblclick': [], 'onkeydown': [], 'target': [], 'onkeyup': [], 'href': [], 'media': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'charset': [], 'hreflang': [], 'onkeypress': [], 'onmousedown': [], 'rev': [], 'class': [], 'title': [], 'onclick': [], 'type': [], 'dir': ['ltr', 'rtl'], 'onmouseout': [], 'onmousemove': [], 'style': [], 'xml:lang': []}
+\ ],
+\ 'map': [
+\ ['p', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'div', 'ul', 'ol', 'dl', 'menu', 'dir', 'pre', 'hr', 'blockquote', 'address', 'center', 'isindex', 'fieldset', 'table', 'form', 'noscript', 'ins', 'del', 'script', 'area'],
+\ { 'ondblclick': [], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'name': [], 'onkeypress': [], 'onmousedown': [], 'class': [], 'onclick': [], 'title': [], 'dir': ['ltr', 'rtl'], 'style': [], 'onmouseout': [], 'onmousemove': [], 'xml:lang': []}
+\ ],
+\ 'menu': [
+\ ['li'],
+\ { 'ondblclick': [], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'compact': ['BOOL'], 'onmouseover': [], 'lang': [], 'onmousedown': [], 'onkeypress': [], 'onclick': [], 'title': [], 'class': [], 'dir': ['ltr', 'rtl'], 'style': [], 'onmousemove': [], 'onmouseout': [], 'xml:lang': []}
+\ ],
+\ 'meta': [
+\ [],
+\ { 'http-equiv': [], 'content': [], 'id': [], 'lang': [], 'name': [], 'scheme': [], 'dir': ['ltr', 'rtl'], 'xml:lang': []}
+\ ],
+\ 'noframes': [
+\ ['body'],
+\ { 'ondblclick': [], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'onmousedown': [], 'onkeypress': [], 'onclick': [], 'title': [], 'class': [], 'dir': ['ltr', 'rtl'], 'style': [], 'onmousemove': [], 'onmouseout': [], 'xml:lang': []}
+\ ],
+\ 'noscript': [
+\ ['p', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'div', 'ul', 'ol', 'dl', 'menu', 'dir', 'pre', 'hr', 'blockquote', 'address', 'center', 'isindex', 'fieldset', 'table', 'form', 'a', 'br', 'span', 'bdo', 'object', 'applet', 'img', 'map', 'iframe', 'tt', 'i', 'b', 'u', 's', 'strike', 'big', 'small', 'font', 'basefont', 'em', 'strong', 'dfn', 'code', 'q', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'sub', 'sup', 'input', 'select', 'textarea', 'label', 'button', 'noscript', 'ins', 'del', 'script'],
+\ { 'ondblclick': [], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'onmousedown': [], 'onkeypress': [], 'onclick': [], 'title': [], 'class': [], 'dir': ['ltr', 'rtl'], 'style': [], 'onmousemove': [], 'onmouseout': [], 'xml:lang': []}
+\ ],
+\ 'object': [
+\ ['param', 'p', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'div', 'ul', 'ol', 'dl', 'menu', 'dir', 'pre', 'hr', 'blockquote', 'address', 'center', 'isindex', 'fieldset', 'table', 'form', 'a', 'br', 'span', 'bdo', 'object', 'applet', 'img', 'map', 'iframe', 'tt', 'i', 'b', 'u', 's', 'strike', 'big', 'small', 'font', 'basefont', 'em', 'strong', 'dfn', 'code', 'q', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'sub', 'sup', 'input', 'select', 'textarea', 'label', 'button', 'noscript', 'ins', 'del', 'script'],
+\ { 'ondblclick': [], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'align': ['top', 'middle', 'bottom', 'left', 'right'], 'name': [], 'data': [], 'declare': ['BOOL'], 'onkeypress': [], 'onmousedown': [], 'class': [], 'title': [], 'onclick': [], 'type': [], 'width': [], 'usemap': [], 'dir': ['ltr', 'rtl'], 'vspace': [], 'tabindex': [], 'standby': [], 'archive': [], 'classid': [], 'style': [], 'onmousemove': [], 'onmouseout': [], 'height': [], 'xml:lang': [], 'border': [], 'codetype': [], 'hspace': [], 'codebase': []}
+\ ],
+\ 'ol': [
+\ ['li'],
+\ { 'ondblclick': [], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'compact': ['BOOL'], 'onmouseover': [], 'lang': [], 'onkeypress': [], 'onmousedown': [], 'type': [], 'class': [], 'title': [], 'onclick': [], 'start': [], 'dir': ['ltr', 'rtl'], 'onmouseout': [], 'onmousemove': [], 'style': [], 'xml:lang': []}
+\ ],
+\ 'optgroup': [
+\ ['option'],
+\ { 'ondblclick': [], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'onkeypress': [], 'onmousedown': [], 'class': [], 'title': [], 'onclick': [], 'label': [], 'disabled': ['BOOL'], 'dir': ['ltr', 'rtl'], 'onmouseout': [], 'onmousemove': [], 'style': [], 'xml:lang': []}
+\ ],
+\ 'option': [
+\ [''],
+\ { 'ondblclick': [], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'value': [], 'onkeypress': [], 'onmousedown': [], 'class': [], 'title': [], 'onclick': [], 'label': [], 'disabled': ['BOOL'], 'dir': ['ltr', 'rtl'], 'onmouseout': [], 'onmousemove': [], 'style': [], 'xml:lang': [], 'selected': ['BOOL']}
+\ ],
+\ 'p': [
+\ ['a', 'br', 'span', 'bdo', 'object', 'applet', 'img', 'map', 'iframe', 'tt', 'i', 'b', 'u', 's', 'strike', 'big', 'small', 'font', 'basefont', 'em', 'strong', 'dfn', 'code', 'q', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'sub', 'sup', 'input', 'select', 'textarea', 'label', 'button', 'ins', 'del', 'script'],
+\ { 'ondblclick': [], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'align': ['left', 'center', 'right', 'justify'], 'lang': [], 'onkeypress': [], 'onmousedown': [], 'class': [], 'title': [], 'onclick': [], 'dir': ['ltr', 'rtl'], 'onmouseout': [], 'onmousemove': [], 'style': [], 'xml:lang': []}
+\ ],
+\ 'param': [
+\ [],
+\ { 'id': [], 'value': [], 'name': [], 'type': [], 'valuetype': ['data', 'ref', 'object']}
+\ ],
+\ 'pre': [
+\ ['a', 'br', 'span', 'bdo', 'tt', 'i', 'b', 'u', 's', 'strike', 'em', 'strong', 'dfn', 'code', 'q', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'input', 'select', 'textarea', 'label', 'button', 'ins', 'del', 'script'],
+\ { 'ondblclick': [], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'xml:space': ['preserve'], 'onkeypress': [], 'onmousedown': [], 'class': [], 'title': [], 'onclick': [], 'width': [], 'dir': ['ltr', 'rtl'], 'onmouseout': [], 'onmousemove': [], 'style': [], 'xml:lang': []}
+\ ],
+\ 'q': [
+\ ['a', 'br', 'span', 'bdo', 'object', 'applet', 'img', 'map', 'iframe', 'tt', 'i', 'b', 'u', 's', 'strike', 'big', 'small', 'font', 'basefont', 'em', 'strong', 'dfn', 'code', 'q', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'sub', 'sup', 'input', 'select', 'textarea', 'label', 'button', 'ins', 'del', 'script'],
+\ { 'ondblclick': [], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'onmousedown': [], 'onkeypress': [], 'onclick': [], 'title': [], 'class': [], 'dir': ['ltr', 'rtl'], 'cite': [], 'style': [], 'onmousemove': [], 'onmouseout': [], 'xml:lang': []}
+\ ],
+\ 's': [
+\ ['a', 'br', 'span', 'bdo', 'object', 'applet', 'img', 'map', 'iframe', 'tt', 'i', 'b', 'u', 's', 'strike', 'big', 'small', 'font', 'basefont', 'em', 'strong', 'dfn', 'code', 'q', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'sub', 'sup', 'input', 'select', 'textarea', 'label', 'button', 'ins', 'del', 'script'],
+\ { 'ondblclick': [], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'onmousedown': [], 'onkeypress': [], 'onclick': [], 'title': [], 'class': [], 'dir': ['ltr', 'rtl'], 'style': [], 'onmousemove': [], 'onmouseout': [], 'xml:lang': []}
+\ ],
+\ 'samp': [
+\ ['a', 'br', 'span', 'bdo', 'object', 'applet', 'img', 'map', 'iframe', 'tt', 'i', 'b', 'u', 's', 'strike', 'big', 'small', 'font', 'basefont', 'em', 'strong', 'dfn', 'code', 'q', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'sub', 'sup', 'input', 'select', 'textarea', 'label', 'button', 'ins', 'del', 'script'],
+\ { 'ondblclick': [], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'onmousedown': [], 'onkeypress': [], 'onclick': [], 'title': [], 'class': [], 'dir': ['ltr', 'rtl'], 'style': [], 'onmousemove': [], 'onmouseout': [], 'xml:lang': []}
+\ ],
+\ 'script': [
+\ [''],
+\ { 'id': [], 'src': [], 'charset': [], 'xml:space': ['preserve'], 'type': ['text/javascript'], 'defer': ['BOOL'], 'language': []}
+\ ],
+\ 'select': [
+\ ['optgroup', 'option'],
+\ { 'ondblclick': [], 'onkeydown': [], 'onchange': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'name': [], 'onkeypress': [], 'onmousedown': [], 'class': [], 'title': [], 'onclick': [], 'disabled': ['BOOL'], 'dir': ['ltr', 'rtl'], 'size': [], 'onblur': [], 'onfocus': [], 'tabindex': [], 'onmouseout': [], 'onmousemove': [], 'style': [], 'xml:lang': [], 'multiple': ['BOOL']}
+\ ],
+\ 'small': [
+\ ['a', 'br', 'span', 'bdo', 'object', 'applet', 'img', 'map', 'iframe', 'tt', 'i', 'b', 'u', 's', 'strike', 'big', 'small', 'font', 'basefont', 'em', 'strong', 'dfn', 'code', 'q', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'sub', 'sup', 'input', 'select', 'textarea', 'label', 'button', 'ins', 'del', 'script'],
+\ { 'ondblclick': [], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'onmousedown': [], 'onkeypress': [], 'onclick': [], 'title': [], 'class': [], 'dir': ['ltr', 'rtl'], 'style': [], 'onmousemove': [], 'onmouseout': [], 'xml:lang': []}
+\ ],
+\ 'span': [
+\ ['a', 'br', 'span', 'bdo', 'object', 'applet', 'img', 'map', 'iframe', 'tt', 'i', 'b', 'u', 's', 'strike', 'big', 'small', 'font', 'basefont', 'em', 'strong', 'dfn', 'code', 'q', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'sub', 'sup', 'input', 'select', 'textarea', 'label', 'button', 'ins', 'del', 'script'],
+\ { 'ondblclick': [], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'onmousedown': [], 'onkeypress': [], 'onclick': [], 'title': [], 'class': [], 'dir': ['ltr', 'rtl'], 'style': [], 'onmousemove': [], 'onmouseout': [], 'xml:lang': []}
+\ ],
+\ 'strike': [
+\ ['a', 'br', 'span', 'bdo', 'object', 'applet', 'img', 'map', 'iframe', 'tt', 'i', 'b', 'u', 's', 'strike', 'big', 'small', 'font', 'basefont', 'em', 'strong', 'dfn', 'code', 'q', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'sub', 'sup', 'input', 'select', 'textarea', 'label', 'button', 'ins', 'del', 'script'],
+\ { 'ondblclick': [], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'onmousedown': [], 'onkeypress': [], 'onclick': [], 'title': [], 'class': [], 'dir': ['ltr', 'rtl'], 'style': [], 'onmousemove': [], 'onmouseout': [], 'xml:lang': []}
+\ ],
+\ 'strong': [
+\ ['a', 'br', 'span', 'bdo', 'object', 'applet', 'img', 'map', 'iframe', 'tt', 'i', 'b', 'u', 's', 'strike', 'big', 'small', 'font', 'basefont', 'em', 'strong', 'dfn', 'code', 'q', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'sub', 'sup', 'input', 'select', 'textarea', 'label', 'button', 'ins', 'del', 'script'],
+\ { 'ondblclick': [], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'onmousedown': [], 'onkeypress': [], 'onclick': [], 'title': [], 'class': [], 'dir': ['ltr', 'rtl'], 'style': [], 'onmousemove': [], 'onmouseout': [], 'xml:lang': []}
+\ ],
+\ 'style': [
+\ [''],
+\ { 'media': [], 'id': [], 'lang': [], 'xml:space': ['preserve'], 'title': [], 'type': ['text/css'], 'dir': ['ltr', 'rtl'], 'xml:lang': []}
+\ ],
+\ 'sub': [
+\ ['a', 'br', 'span', 'bdo', 'object', 'applet', 'img', 'map', 'iframe', 'tt', 'i', 'b', 'u', 's', 'strike', 'big', 'small', 'font', 'basefont', 'em', 'strong', 'dfn', 'code', 'q', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'sub', 'sup', 'input', 'select', 'textarea', 'label', 'button', 'ins', 'del', 'script'],
+\ { 'ondblclick': [], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'onmousedown': [], 'onkeypress': [], 'onclick': [], 'title': [], 'class': [], 'dir': ['ltr', 'rtl'], 'style': [], 'onmousemove': [], 'onmouseout': [], 'xml:lang': []}
+\ ],
+\ 'sup': [
+\ ['a', 'br', 'span', 'bdo', 'object', 'applet', 'img', 'map', 'iframe', 'tt', 'i', 'b', 'u', 's', 'strike', 'big', 'small', 'font', 'basefont', 'em', 'strong', 'dfn', 'code', 'q', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'sub', 'sup', 'input', 'select', 'textarea', 'label', 'button', 'ins', 'del', 'script'],
+\ { 'ondblclick': [], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'onmousedown': [], 'onkeypress': [], 'onclick': [], 'title': [], 'class': [], 'dir': ['ltr', 'rtl'], 'style': [], 'onmousemove': [], 'onmouseout': [], 'xml:lang': []}
+\ ],
+\ 'table': [
+\ ['caption', 'col', 'colgroup', 'thead', 'tfoot', 'tbody', 'tr'],
+\ { 'ondblclick': [], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'align': ['left', 'center', 'right'], 'onkeypress': [], 'onmousedown': [], 'class': [], 'title': [], 'onclick': [], 'width': [], 'frame': ['void', 'above', 'below', 'hsides', 'lhs', 'rhs', 'vsides', 'box', 'border'], 'rules': ['none', 'groups', 'rows', 'cols', 'all'], 'dir': ['ltr', 'rtl'], 'summary': [], 'bgcolor': [], 'cellspacing': [], 'onmouseout': [], 'onmousemove': [], 'style': [], 'xml:lang': [], 'border': [], 'cellpadding': []}
+\ ],
+\ 'tbody': [
+\ ['tr'],
+\ { 'ondblclick': [], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'align': ['left', 'center', 'right', 'justify', 'char'], 'lang': [], 'valign': ['top', 'middle', 'bottom', 'baseline'], 'onkeypress': [], 'onmousedown': [], 'class': [], 'title': [], 'onclick': [], 'dir': ['ltr', 'rtl'], 'charoff': [], 'onmouseout': [], 'onmousemove': [], 'style': [], 'xml:lang': [], 'char': []}
+\ ],
+\ 'td': [
+\ ['p', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'div', 'ul', 'ol', 'dl', 'menu', 'dir', 'pre', 'hr', 'blockquote', 'address', 'center', 'isindex', 'fieldset', 'table', 'form', 'a', 'br', 'span', 'bdo', 'object', 'applet', 'img', 'map', 'iframe', 'tt', 'i', 'b', 'u', 's', 'strike', 'big', 'small', 'font', 'basefont', 'em', 'strong', 'dfn', 'code', 'q', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'sub', 'sup', 'input', 'select', 'textarea', 'label', 'button', 'noscript', 'ins', 'del', 'script'],
+\ { 'ondblclick': [], 'axis': [], 'onkeydown': [], 'abbr': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'scope': ['row', 'col', 'rowgroup', 'colgroup'], 'onmouseover': [], 'lang': [], 'align': ['left', 'center', 'right', 'justify', 'char'], 'valign': ['top', 'middle', 'bottom', 'baseline'], 'onkeypress': [], 'onmousedown': [], 'class': [], 'title': [], 'onclick': [], 'width': [], 'headers': [], 'nowrap': ['BOOL'], 'dir': ['ltr', 'rtl'], 'rowspan': ['1'], 'colspan': ['1'], 'bgcolor': [], 'charoff': [], 'onmouseout': [], 'onmousemove': [], 'style': [], 'xml:lang': [], 'height': [], 'char': []}
+\ ],
+\ 'textarea': [
+\ [''],
+\ { 'ondblclick': [], 'cols': [], 'onkeydown': [], 'readonly': ['BOOL'], 'onchange': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'name': [], 'onkeypress': [], 'onmousedown': [], 'class': [], 'title': [], 'onclick': [], 'accesskey': [], 'disabled': ['BOOL'], 'rows': [], 'dir': ['ltr', 'rtl'], 'onblur': [], 'onfocus': [], 'onselect': [], 'tabindex': [], 'onmouseout': [], 'onmousemove': [], 'style': [], 'xml:lang': []}
+\ ],
+\ 'tfoot': [
+\ ['tr'],
+\ { 'ondblclick': [], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'align': ['left', 'center', 'right', 'justify', 'char'], 'lang': [], 'valign': ['top', 'middle', 'bottom', 'baseline'], 'onkeypress': [], 'onmousedown': [], 'class': [], 'title': [], 'onclick': [], 'dir': ['ltr', 'rtl'], 'charoff': [], 'onmouseout': [], 'onmousemove': [], 'style': [], 'xml:lang': [], 'char': []}
+\ ],
+\ 'th': [
+\ ['p', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'div', 'ul', 'ol', 'dl', 'menu', 'dir', 'pre', 'hr', 'blockquote', 'address', 'center', 'isindex', 'fieldset', 'table', 'form', 'a', 'br', 'span', 'bdo', 'object', 'applet', 'img', 'map', 'iframe', 'tt', 'i', 'b', 'u', 's', 'strike', 'big', 'small', 'font', 'basefont', 'em', 'strong', 'dfn', 'code', 'q', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'sub', 'sup', 'input', 'select', 'textarea', 'label', 'button', 'noscript', 'ins', 'del', 'script'],
+\ { 'ondblclick': [], 'axis': [], 'onkeydown': [], 'abbr': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'scope': ['row', 'col', 'rowgroup', 'colgroup'], 'onmouseover': [], 'lang': [], 'align': ['left', 'center', 'right', 'justify', 'char'], 'valign': ['top', 'middle', 'bottom', 'baseline'], 'onkeypress': [], 'onmousedown': [], 'class': [], 'title': [], 'onclick': [], 'width': [], 'headers': [], 'nowrap': ['BOOL'], 'dir': ['ltr', 'rtl'], 'rowspan': ['1'], 'colspan': ['1'], 'bgcolor': [], 'charoff': [], 'onmouseout': [], 'onmousemove': [], 'style': [], 'xml:lang': [], 'height': [], 'char': []}
+\ ],
+\ 'thead': [
+\ ['tr'],
+\ { 'ondblclick': [], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'align': ['left', 'center', 'right', 'justify', 'char'], 'lang': [], 'valign': ['top', 'middle', 'bottom', 'baseline'], 'onkeypress': [], 'onmousedown': [], 'class': [], 'title': [], 'onclick': [], 'dir': ['ltr', 'rtl'], 'charoff': [], 'onmouseout': [], 'onmousemove': [], 'style': [], 'xml:lang': [], 'char': []}
+\ ],
+\ 'title': [
+\ [''],
+\ { 'id': [], 'lang': [], 'dir': ['ltr', 'rtl'], 'xml:lang': []}
+\ ],
+\ 'tr': [
+\ ['th', 'td'],
+\ { 'ondblclick': [], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'align': ['left', 'center', 'right', 'justify', 'char'], 'lang': [], 'valign': ['top', 'middle', 'bottom', 'baseline'], 'onkeypress': [], 'onmousedown': [], 'class': [], 'title': [], 'onclick': [], 'dir': ['ltr', 'rtl'], 'bgcolor': [], 'charoff': [], 'onmouseout': [], 'onmousemove': [], 'style': [], 'xml:lang': [], 'char': []}
+\ ],
+\ 'tt': [
+\ ['a', 'br', 'span', 'bdo', 'object', 'applet', 'img', 'map', 'iframe', 'tt', 'i', 'b', 'u', 's', 'strike', 'big', 'small', 'font', 'basefont', 'em', 'strong', 'dfn', 'code', 'q', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'sub', 'sup', 'input', 'select', 'textarea', 'label', 'button', 'ins', 'del', 'script'],
+\ { 'ondblclick': [], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'onmousedown': [], 'onkeypress': [], 'onclick': [], 'title': [], 'class': [], 'dir': ['ltr', 'rtl'], 'style': [], 'onmousemove': [], 'onmouseout': [], 'xml:lang': []}
+\ ],
+\ 'u': [
+\ ['a', 'br', 'span', 'bdo', 'object', 'applet', 'img', 'map', 'iframe', 'tt', 'i', 'b', 'u', 's', 'strike', 'big', 'small', 'font', 'basefont', 'em', 'strong', 'dfn', 'code', 'q', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'sub', 'sup', 'input', 'select', 'textarea', 'label', 'button', 'ins', 'del', 'script'],
+\ { 'ondblclick': [], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'onmousedown': [], 'onkeypress': [], 'onclick': [], 'title': [], 'class': [], 'dir': ['ltr', 'rtl'], 'style': [], 'onmousemove': [], 'onmouseout': [], 'xml:lang': []}
+\ ],
+\ 'ul': [
+\ ['li'],
+\ { 'ondblclick': [], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'compact': ['BOOL'], 'onmouseover': [], 'lang': [], 'onkeypress': [], 'onmousedown': [], 'type': ['disc', 'square', 'circle'], 'class': [], 'title': [], 'onclick': [], 'dir': ['ltr', 'rtl'], 'onmouseout': [], 'onmousemove': [], 'style': [], 'xml:lang': []}
+\ ],
+\ 'var': [
+\ ['a', 'br', 'span', 'bdo', 'object', 'applet', 'img', 'map', 'iframe', 'tt', 'i', 'b', 'u', 's', 'strike', 'big', 'small', 'font', 'basefont', 'em', 'strong', 'dfn', 'code', 'q', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'sub', 'sup', 'input', 'select', 'textarea', 'label', 'button', 'ins', 'del', 'script'],
+\ { 'ondblclick': [], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'onmousedown': [], 'onkeypress': [], 'onclick': [], 'title': [], 'class': [], 'dir': ['ltr', 'rtl'], 'style': [], 'onmousemove': [], 'onmouseout': [], 'xml:lang': []}
+\ ],
+\ 'vimxmlattrinfo' : {
+\ 'accept' : ['ContentType', ''],
+\ 'accesskey' : ['Character', ''],
+\ 'action' : ['*URI', ''],
+\ 'align' : ['String', ''],
+\ 'alt' : ['*Text', ''],
+\ 'archive' : ['UriList', ''],
+\ 'axis' : ['CDATA', ''],
+\ 'border' : ['Pixels', ''],
+\ 'cellpadding' : ['Length', ''],
+\ 'cellspacing' : ['Length', ''],
+\ 'char' : ['Character', ''],
+\ 'charoff' : ['Length', ''],
+\ 'charset' : ['LangCode', ''],
+\ 'checked' : ['Bool', ''],
+\ 'class' : ['CDATA', ''],
+\ 'codetype' : ['ContentType', ''],
+\ 'cols' : ['*Number', ''],
+\ 'colspan' : ['Number', ''],
+\ 'content' : ['*CDATA', ''],
+\ 'coords' : ['Coords', ''],
+\ 'data' : ['URI', ''],
+\ 'datetime' : ['DateTime', ''],
+\ 'declare' : ['Bool', ''],
+\ 'defer' : ['Bool', ''],
+\ 'dir' : ['String', ''],
+\ 'disabled' : ['Bool', ''],
+\ 'enctype' : ['ContentType', ''],
+\ 'for' : ['ID', ''],
+\ 'headers' : ['IDREFS', ''],
+\ 'height' : ['Number', ''],
+\ 'href' : ['*URI', ''],
+\ 'hreflang' : ['LangCode', ''],
+\ 'id' : ['ID', ''],
+\ 'ismap' : ['Bool', ''],
+\ 'label' : ['*Text', ''],
+\ 'lang' : ['LangCode', ''],
+\ 'longdesc' : ['URI', ''],
+\ 'maxlength' : ['Number', ''],
+\ 'media' : ['MediaDesc', ''],
+\ 'method' : ['String', ''],
+\ 'multiple' : ['Bool', ''],
+\ 'name' : ['CDATA', ''],
+\ 'nohref' : ['Bool', ''],
+\ 'onblur' : ['Script', ''],
+\ 'onchange' : ['Script', ''],
+\ 'onclick' : ['Script', ''],
+\ 'ondblclick' : ['Script', ''],
+\ 'onfocus' : ['Script', ''],
+\ 'onkeydown' : ['Script', ''],
+\ 'onkeypress' : ['Script', ''],
+\ 'onkeyup' : ['Script', ''],
+\ 'onload' : ['Script', ''],
+\ 'onmousedown' : ['Script', ''],
+\ 'onmousemove' : ['Script', ''],
+\ 'onmouseout' : ['Script', ''],
+\ 'onmouseover' : ['Script', ''],
+\ 'onmouseup' : ['Script', ''],
+\ 'onreset' : ['Script', ''],
+\ 'onselect' : ['Script', ''],
+\ 'onsubmit' : ['Script', ''],
+\ 'onunload' : ['Script', ''],
+\ 'profile' : ['URI', ''],
+\ 'readonly' : ['Bool', ''],
+\ 'rel' : ['LinkTypes', ''],
+\ 'rev' : ['LinkTypes', ''],
+\ 'rows' : ['*Number', ''],
+\ 'rules' : ['String', ''],
+\ 'scheme' : ['CDATA', ''],
+\ 'selected' : ['Bool', ''],
+\ 'shape' : ['Shape', ''],
+\ 'size' : ['CDATA', ''],
+\ 'span' : ['Number', ''],
+\ 'src' : ['*URI', ''],
+\ 'standby' : ['Text', ''],
+\ 'style' : ['StyleSheet', ''],
+\ 'summary' : ['*Text', ''],
+\ 'tabindex' : ['Number', ''],
+\ 'title' : ['Text', ''],
+\ 'type' : ['*ContentType', ''],
+\ 'usemap' : ['URI', ''],
+\ 'valign' : ['String', ''],
+\ 'valuetype' : ['String', ''],
+\ 'width' : ['Number', ''],
+\ 'xmlns' : ['URI', '']
+\ },
+\ 'vimxmltaginfo': {
+\ 'area': ['/>', ''],
+\ 'base': ['/>', ''],
+\ 'basefont': ['/>', ''],
+\ 'br': ['/>', ''],
+\ 'col': ['/>', ''],
+\ 'frame': ['/>', ''],
+\ 'hr': ['/>', ''],
+\ 'img': ['/>', ''],
+\ 'input': ['/>', ''],
+\ 'isindex': ['/>', ''],
+\ 'link': ['/>', ''],
+\ 'meta': ['/>', ''],
+\ 'param': ['/>', ''],
+\ }
+\ }
+" vim:ft=vim:ff=unix
--- /dev/null
+++ b/lib/vimfiles/autoload/xml/xhtml10s.vim
@@ -1,0 +1,411 @@
+let g:xmldata_xhtml10s = {
+\ 'vimxmlentities': ['AElig', 'Aacute', 'Acirc', 'Agrave', 'Alpha', 'Aring', 'Atilde', 'Auml', 'Beta', 'Ccedil', 'Chi', 'Dagger', 'Delta', 'ETH', 'Eacute', 'Ecirc', 'Egrave', 'Epsilon', 'Eta', 'Euml', 'Gamma', 'Iacute', 'Icirc', 'Igrave', 'Iota', 'Iuml', 'Kappa', 'Lambda', 'Mu', 'Ntilde', 'Nu', 'OElig', 'Oacute', 'Ocirc', 'Ograve', 'Omega', 'Omicron', 'Oslash', 'Otilde', 'Ouml', 'Phi', 'Pi', 'Prime', 'Psi', 'Rho', 'Scaron', 'Sigma', 'THORN', 'Tau', 'Theta', 'Uacute', 'Ucirc', 'Ugrave', 'Upsilon', 'Uuml', 'Xi', 'Yacute', 'Yuml', 'Zeta', 'aacute', 'acirc', 'acute', 'aelig', 'agrave', 'alefsym', 'alpha', 'amp', 'and', 'ang', 'apos', 'aring', 'asymp', 'atilde', 'auml', 'bdquo', 'beta', 'brvbar', 'bull', 'cap', 'ccedil', 'cedil', 'cent', 'chi', 'circ', 'clubs', 'cong', 'copy', 'crarr', 'cup', 'curren', 'dArr', 'dagger', 'darr', 'deg', 'delta', 'diams', 'divide', 'eacute', 'ecirc', 'egrave', 'empty', 'emsp', 'ensp', 'epsilon', 'equiv', 'eta', 'eth', 'euml', 'euro', 'exist', 'fnof', 'forall', 'frac12', 'frac14', 'frac34', 'frasl', 'gamma', 'ge', 'gt', 'hArr', 'harr', 'hearts', 'hellip', 'iacute', 'icirc', 'iexcl', 'igrave', 'image', 'infin', 'int', 'iota', 'iquest', 'isin', 'iuml', 'kappa', 'lArr', 'lambda', 'lang', 'laquo', 'larr', 'lceil', 'ldquo', 'le', 'lfloor', 'lowast', 'loz', 'lrm', 'lsaquo', 'lsquo', 'lt', 'macr', 'mdash', 'micro', 'middot', 'minus', 'mu', 'nabla', 'nbsp', 'ndash', 'ne', 'ni', 'not', 'notin', 'nsub', 'ntilde', 'nu', 'oacute', 'ocirc', 'oelig', 'ograve', 'oline', 'omega', 'omicron', 'oplus', 'or', 'ordf', 'ordm', 'oslash', 'otilde', 'otimes', 'ouml', 'para', 'part', 'permil', 'perp', 'phi', 'pi', 'piv', 'plusmn', 'pound', 'prime', 'prod', 'prop', 'psi', 'quot', 'rArr', 'radic', 'rang', 'raquo', 'rarr', 'rceil', 'rdquo', 'real', 'reg', 'rfloor', 'rho', 'rlm', 'rsaquo', 'rsquo', 'sbquo', 'scaron', 'sdot', 'sect', 'shy', 'sigma', 'sigmaf', 'sim', 'spades', 'sub', 'sube', 'sum', 'sup', 'sup1', 'sup2', 'sup3', 'supe', 'szlig', 'tau', 'there4', 'theta', 'thetasym', 'thinsp', 'thorn', 'tilde', 'times', 'trade', 'uArr', 'uacute', 'uarr', 'ucirc', 'ugrave', 'uml', 'upsih', 'upsilon', 'uuml', 'weierp', 'xi', 'yacute', 'yen', 'yuml', 'zeta', 'zwj', 'zwnj'],
+\ 'vimxmlroot': ['html'],
+\ 'a': [
+\ ['br', 'span', 'bdo', 'map', 'object', 'img', 'tt', 'i', 'b', 'big', 'small', 'em', 'strong', 'dfn', 'code', 'q', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'sub', 'sup', 'input', 'select', 'textarea', 'label', 'button', 'ins', 'del', 'script'],
+\ { 'accesskey': [], 'rel': [], 'coords': [], 'ondblclick': [], 'dir': ['ltr', 'rtl'], 'onblur': [], 'onfocus': [], 'onkeydown': [], 'onkeyup': [], 'href': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'tabindex': [], 'onmouseout': [], 'onmousemove': [], 'name': [], 'style': [], 'charset': [], 'xml:lang': [], 'hreflang': [], 'onkeypress': [], 'onmousedown': [], 'rev': [], 'class': [], 'title': [], 'onclick': [], 'type': [], 'shape': ['rect', 'circle', 'poly', 'default']}
+\ ],
+\ 'abbr': [
+\ ['a', 'br', 'span', 'bdo', 'map', 'object', 'img', 'tt', 'i', 'b', 'big', 'small', 'em', 'strong', 'dfn', 'code', 'q', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'sub', 'sup', 'input', 'select', 'textarea', 'label', 'button', 'ins', 'del', 'script'],
+\ { 'ondblclick': [], 'dir': ['ltr', 'rtl'], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'style': [], 'onmousemove': [], 'onmouseout': [], 'xml:lang': [], 'onmousedown': [], 'onkeypress': [], 'onclick': [], 'title': [], 'class': []}
+\ ],
+\ 'acronym': [
+\ ['a', 'br', 'span', 'bdo', 'map', 'object', 'img', 'tt', 'i', 'b', 'big', 'small', 'em', 'strong', 'dfn', 'code', 'q', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'sub', 'sup', 'input', 'select', 'textarea', 'label', 'button', 'ins', 'del', 'script'],
+\ { 'ondblclick': [], 'dir': ['ltr', 'rtl'], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'style': [], 'onmousemove': [], 'onmouseout': [], 'xml:lang': [], 'onmousedown': [], 'onkeypress': [], 'onclick': [], 'title': [], 'class': []}
+\ ],
+\ 'address': [
+\ ['a', 'br', 'span', 'bdo', 'map', 'object', 'img', 'tt', 'i', 'b', 'big', 'small', 'em', 'strong', 'dfn', 'code', 'q', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'sub', 'sup', 'input', 'select', 'textarea', 'label', 'button', 'ins', 'del', 'script'],
+\ { 'ondblclick': [], 'dir': ['ltr', 'rtl'], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'style': [], 'onmousemove': [], 'onmouseout': [], 'xml:lang': [], 'onmousedown': [], 'onkeypress': [], 'onclick': [], 'title': [], 'class': []}
+\ ],
+\ 'area': [
+\ [],
+\ { 'accesskey': [], 'coords': [], 'ondblclick': [], 'dir': ['ltr', 'rtl'], 'onblur': [], 'onkeydown': [], 'onfocus': [], 'nohref': ['BOOL'], 'onkeyup': [], 'href': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'tabindex': [], 'lang': [], 'alt': [], 'onmouseout': [], 'onmousemove': [], 'style': [], 'xml:lang': [], 'onkeypress': [], 'onmousedown': [], 'class': [], 'title': [], 'onclick': [], 'shape': ['rect', 'circle', 'poly', 'default']}
+\ ],
+\ 'b': [
+\ ['a', 'br', 'span', 'bdo', 'map', 'object', 'img', 'tt', 'i', 'b', 'big', 'small', 'em', 'strong', 'dfn', 'code', 'q', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'sub', 'sup', 'input', 'select', 'textarea', 'label', 'button', 'ins', 'del', 'script'],
+\ { 'ondblclick': [], 'dir': ['ltr', 'rtl'], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'style': [], 'onmousemove': [], 'onmouseout': [], 'xml:lang': [], 'onmousedown': [], 'onkeypress': [], 'onclick': [], 'title': [], 'class': []}
+\ ],
+\ 'base': [
+\ [],
+\ { 'href': [], 'id': []}
+\ ],
+\ 'bdo': [
+\ ['a', 'br', 'span', 'bdo', 'map', 'object', 'img', 'tt', 'i', 'b', 'big', 'small', 'em', 'strong', 'dfn', 'code', 'q', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'sub', 'sup', 'input', 'select', 'textarea', 'label', 'button', 'ins', 'del', 'script'],
+\ { 'ondblclick': [], 'dir': ['ltr', 'rtl'], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'style': [], 'onmousemove': [], 'onmouseout': [], 'xml:lang': [], 'onmousedown': [], 'onkeypress': [], 'onclick': [], 'title': [], 'class': []}
+\ ],
+\ 'big': [
+\ ['a', 'br', 'span', 'bdo', 'map', 'object', 'img', 'tt', 'i', 'b', 'big', 'small', 'em', 'strong', 'dfn', 'code', 'q', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'sub', 'sup', 'input', 'select', 'textarea', 'label', 'button', 'ins', 'del', 'script'],
+\ { 'ondblclick': [], 'dir': ['ltr', 'rtl'], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'style': [], 'onmousemove': [], 'onmouseout': [], 'xml:lang': [], 'onmousedown': [], 'onkeypress': [], 'onclick': [], 'title': [], 'class': []}
+\ ],
+\ 'blockquote': [
+\ ['p', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'div', 'ul', 'ol', 'dl', 'pre', 'hr', 'blockquote', 'address', 'fieldset', 'table', 'form', 'noscript', 'ins', 'del', 'script'],
+\ { 'ondblclick': [], 'dir': ['ltr', 'rtl'], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'cite': [], 'onmouseover': [], 'lang': [], 'style': [], 'onmousemove': [], 'onmouseout': [], 'xml:lang': [], 'onmousedown': [], 'onkeypress': [], 'onclick': [], 'title': [], 'class': []}
+\ ],
+\ 'body': [
+\ ['p', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'div', 'ul', 'ol', 'dl', 'pre', 'hr', 'blockquote', 'address', 'fieldset', 'table', 'form', 'noscript', 'ins', 'del', 'script'],
+\ { 'ondblclick': [], 'dir': ['ltr', 'rtl'], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'onmouseout': [], 'onmousemove': [], 'style': [], 'xml:lang': [], 'onunload': [], 'onkeypress': [], 'onmousedown': [], 'onload': [], 'class': [], 'title': [], 'onclick': []}
+\ ],
+\ 'br': [
+\ [],
+\ { 'id': [], 'style': [], 'class': [], 'title': []}
+\ ],
+\ 'button': [
+\ ['p', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'div', 'ul', 'ol', 'dl', 'pre', 'hr', 'blockquote', 'address', 'table', 'br', 'span', 'bdo', 'map', 'object', 'img', 'tt', 'i', 'b', 'big', 'small', 'em', 'strong', 'dfn', 'code', 'q', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'sub', 'sup', 'noscript', 'ins', 'del', 'script'],
+\ { 'accesskey': [], 'disabled': ['BOOL'], 'ondblclick': [], 'dir': ['ltr', 'rtl'], 'onblur': [], 'onkeydown': [], 'onfocus': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'tabindex': [], 'lang': [], 'value': [], 'onmouseout': [], 'onmousemove': [], 'style': [], 'name': [], 'xml:lang': [], 'onkeypress': [], 'onmousedown': [], 'class': [], 'title': [], 'onclick': [], 'type': ['submit', 'button', 'submit', 'reset']}
+\ ],
+\ 'caption': [
+\ ['a', 'br', 'span', 'bdo', 'map', 'object', 'img', 'tt', 'i', 'b', 'big', 'small', 'em', 'strong', 'dfn', 'code', 'q', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'sub', 'sup', 'input', 'select', 'textarea', 'label', 'button', 'ins', 'del', 'script'],
+\ { 'ondblclick': [], 'dir': ['ltr', 'rtl'], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'style': [], 'onmousemove': [], 'onmouseout': [], 'xml:lang': [], 'onmousedown': [], 'onkeypress': [], 'onclick': [], 'title': [], 'class': []}
+\ ],
+\ 'cite': [
+\ ['a', 'br', 'span', 'bdo', 'map', 'object', 'img', 'tt', 'i', 'b', 'big', 'small', 'em', 'strong', 'dfn', 'code', 'q', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'sub', 'sup', 'input', 'select', 'textarea', 'label', 'button', 'ins', 'del', 'script'],
+\ { 'ondblclick': [], 'dir': ['ltr', 'rtl'], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'style': [], 'onmousemove': [], 'onmouseout': [], 'xml:lang': [], 'onmousedown': [], 'onkeypress': [], 'onclick': [], 'title': [], 'class': []}
+\ ],
+\ 'code': [
+\ ['a', 'br', 'span', 'bdo', 'map', 'object', 'img', 'tt', 'i', 'b', 'big', 'small', 'em', 'strong', 'dfn', 'code', 'q', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'sub', 'sup', 'input', 'select', 'textarea', 'label', 'button', 'ins', 'del', 'script'],
+\ { 'ondblclick': [], 'dir': ['ltr', 'rtl'], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'style': [], 'onmousemove': [], 'onmouseout': [], 'xml:lang': [], 'onmousedown': [], 'onkeypress': [], 'onclick': [], 'title': [], 'class': []}
+\ ],
+\ 'col': [
+\ [],
+\ { 'width': [], 'ondblclick': [], 'dir': ['ltr', 'rtl'], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'charoff': [], 'onmouseover': [], 'lang': [], 'align': ['left', 'center', 'right', 'justify', 'char'], 'valign': ['top', 'middle', 'bottom', 'baseline'], 'onmouseout': [], 'onmousemove': [], 'style': [], 'xml:lang': [], 'onkeypress': [], 'onmousedown': [], 'char': [], 'span': ['1'], 'class': [], 'title': [], 'onclick': []}
+\ ],
+\ 'colgroup': [
+\ ['col'],
+\ { 'width': [], 'ondblclick': [], 'dir': ['ltr', 'rtl'], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'charoff': [], 'onmouseover': [], 'lang': [], 'align': ['left', 'center', 'right', 'justify', 'char'], 'valign': ['top', 'middle', 'bottom', 'baseline'], 'onmouseout': [], 'onmousemove': [], 'style': [], 'xml:lang': [], 'onkeypress': [], 'onmousedown': [], 'char': [], 'span': ['1'], 'class': [], 'title': [], 'onclick': []}
+\ ],
+\ 'dd': [
+\ ['p', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'div', 'ul', 'ol', 'dl', 'pre', 'hr', 'blockquote', 'address', 'fieldset', 'table', 'form', 'a', 'br', 'span', 'bdo', 'map', 'object', 'img', 'tt', 'i', 'b', 'big', 'small', 'em', 'strong', 'dfn', 'code', 'q', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'sub', 'sup', 'input', 'select', 'textarea', 'label', 'button', 'noscript', 'ins', 'del', 'script'],
+\ { 'ondblclick': [], 'dir': ['ltr', 'rtl'], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'style': [], 'onmousemove': [], 'onmouseout': [], 'xml:lang': [], 'onmousedown': [], 'onkeypress': [], 'onclick': [], 'title': [], 'class': []}
+\ ],
+\ 'del': [
+\ ['p', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'div', 'ul', 'ol', 'dl', 'pre', 'hr', 'blockquote', 'address', 'fieldset', 'table', 'form', 'a', 'br', 'span', 'bdo', 'map', 'object', 'img', 'tt', 'i', 'b', 'big', 'small', 'em', 'strong', 'dfn', 'code', 'q', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'sub', 'sup', 'input', 'select', 'textarea', 'label', 'button', 'noscript', 'ins', 'del', 'script'],
+\ { 'ondblclick': [], 'dir': ['ltr', 'rtl'], 'datetime': [], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'cite': [], 'onmouseover': [], 'lang': [], 'onmouseout': [], 'onmousemove': [], 'style': [], 'xml:lang': [], 'onkeypress': [], 'onmousedown': [], 'class': [], 'title': [], 'onclick': []}
+\ ],
+\ 'dfn': [
+\ ['a', 'br', 'span', 'bdo', 'map', 'object', 'img', 'tt', 'i', 'b', 'big', 'small', 'em', 'strong', 'dfn', 'code', 'q', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'sub', 'sup', 'input', 'select', 'textarea', 'label', 'button', 'ins', 'del', 'script'],
+\ { 'ondblclick': [], 'dir': ['ltr', 'rtl'], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'style': [], 'onmousemove': [], 'onmouseout': [], 'xml:lang': [], 'onmousedown': [], 'onkeypress': [], 'onclick': [], 'title': [], 'class': []}
+\ ],
+\ 'div': [
+\ ['p', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'div', 'ul', 'ol', 'dl', 'pre', 'hr', 'blockquote', 'address', 'fieldset', 'table', 'form', 'a', 'br', 'span', 'bdo', 'map', 'object', 'img', 'tt', 'i', 'b', 'big', 'small', 'em', 'strong', 'dfn', 'code', 'q', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'sub', 'sup', 'input', 'select', 'textarea', 'label', 'button', 'noscript', 'ins', 'del', 'script'],
+\ { 'ondblclick': [], 'dir': ['ltr', 'rtl'], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'style': [], 'onmousemove': [], 'onmouseout': [], 'xml:lang': [], 'onmousedown': [], 'onkeypress': [], 'onclick': [], 'title': [], 'class': []}
+\ ],
+\ 'dl': [
+\ ['dt', 'dd'],
+\ { 'ondblclick': [], 'dir': ['ltr', 'rtl'], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'style': [], 'onmousemove': [], 'onmouseout': [], 'xml:lang': [], 'onmousedown': [], 'onkeypress': [], 'onclick': [], 'title': [], 'class': []}
+\ ],
+\ 'dt': [
+\ ['a', 'br', 'span', 'bdo', 'map', 'object', 'img', 'tt', 'i', 'b', 'big', 'small', 'em', 'strong', 'dfn', 'code', 'q', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'sub', 'sup', 'input', 'select', 'textarea', 'label', 'button', 'ins', 'del', 'script'],
+\ { 'ondblclick': [], 'dir': ['ltr', 'rtl'], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'style': [], 'onmousemove': [], 'onmouseout': [], 'xml:lang': [], 'onmousedown': [], 'onkeypress': [], 'onclick': [], 'title': [], 'class': []}
+\ ],
+\ 'em': [
+\ ['a', 'br', 'span', 'bdo', 'map', 'object', 'img', 'tt', 'i', 'b', 'big', 'small', 'em', 'strong', 'dfn', 'code', 'q', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'sub', 'sup', 'input', 'select', 'textarea', 'label', 'button', 'ins', 'del', 'script'],
+\ { 'ondblclick': [], 'dir': ['ltr', 'rtl'], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'style': [], 'onmousemove': [], 'onmouseout': [], 'xml:lang': [], 'onmousedown': [], 'onkeypress': [], 'onclick': [], 'title': [], 'class': []}
+\ ],
+\ 'fieldset': [
+\ ['legend', 'p', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'div', 'ul', 'ol', 'dl', 'pre', 'hr', 'blockquote', 'address', 'fieldset', 'table', 'form', 'a', 'br', 'span', 'bdo', 'map', 'object', 'img', 'tt', 'i', 'b', 'big', 'small', 'em', 'strong', 'dfn', 'code', 'q', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'sub', 'sup', 'input', 'select', 'textarea', 'label', 'button', 'noscript', 'ins', 'del', 'script'],
+\ { 'ondblclick': [], 'dir': ['ltr', 'rtl'], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'style': [], 'onmousemove': [], 'onmouseout': [], 'xml:lang': [], 'onmousedown': [], 'onkeypress': [], 'onclick': [], 'title': [], 'class': []}
+\ ],
+\ 'form': [
+\ ['p', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'div', 'ul', 'ol', 'dl', 'pre', 'hr', 'blockquote', 'address', 'fieldset', 'table', 'noscript', 'ins', 'del', 'script'],
+\ { 'enctype': ['application/x-www-form-urlencoded'], 'onsubmit': [], 'ondblclick': [], 'dir': ['ltr', 'rtl'], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'onreset': [], 'id': [], 'method': ['get', 'post'], 'onmouseover': [], 'lang': [], 'accept': [], 'onmouseout': [], 'onmousemove': [], 'style': [], 'xml:lang': [], 'accept-charset': [], 'onkeypress': [], 'onmousedown': [], 'action': [], 'class': [], 'title': [], 'onclick': []}
+\ ],
+\ 'h1': [
+\ ['a', 'br', 'span', 'bdo', 'map', 'object', 'img', 'tt', 'i', 'b', 'big', 'small', 'em', 'strong', 'dfn', 'code', 'q', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'sub', 'sup', 'input', 'select', 'textarea', 'label', 'button', 'ins', 'del', 'script'],
+\ { 'ondblclick': [], 'dir': ['ltr', 'rtl'], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'style': [], 'onmousemove': [], 'onmouseout': [], 'xml:lang': [], 'onmousedown': [], 'onkeypress': [], 'onclick': [], 'title': [], 'class': []}
+\ ],
+\ 'h2': [
+\ ['a', 'br', 'span', 'bdo', 'map', 'object', 'img', 'tt', 'i', 'b', 'big', 'small', 'em', 'strong', 'dfn', 'code', 'q', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'sub', 'sup', 'input', 'select', 'textarea', 'label', 'button', 'ins', 'del', 'script'],
+\ { 'ondblclick': [], 'dir': ['ltr', 'rtl'], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'style': [], 'onmousemove': [], 'onmouseout': [], 'xml:lang': [], 'onmousedown': [], 'onkeypress': [], 'onclick': [], 'title': [], 'class': []}
+\ ],
+\ 'h3': [
+\ ['a', 'br', 'span', 'bdo', 'map', 'object', 'img', 'tt', 'i', 'b', 'big', 'small', 'em', 'strong', 'dfn', 'code', 'q', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'sub', 'sup', 'input', 'select', 'textarea', 'label', 'button', 'ins', 'del', 'script'],
+\ { 'ondblclick': [], 'dir': ['ltr', 'rtl'], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'style': [], 'onmousemove': [], 'onmouseout': [], 'xml:lang': [], 'onmousedown': [], 'onkeypress': [], 'onclick': [], 'title': [], 'class': []}
+\ ],
+\ 'h4': [
+\ ['a', 'br', 'span', 'bdo', 'map', 'object', 'img', 'tt', 'i', 'b', 'big', 'small', 'em', 'strong', 'dfn', 'code', 'q', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'sub', 'sup', 'input', 'select', 'textarea', 'label', 'button', 'ins', 'del', 'script'],
+\ { 'ondblclick': [], 'dir': ['ltr', 'rtl'], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'style': [], 'onmousemove': [], 'onmouseout': [], 'xml:lang': [], 'onmousedown': [], 'onkeypress': [], 'onclick': [], 'title': [], 'class': []}
+\ ],
+\ 'h5': [
+\ ['a', 'br', 'span', 'bdo', 'map', 'object', 'img', 'tt', 'i', 'b', 'big', 'small', 'em', 'strong', 'dfn', 'code', 'q', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'sub', 'sup', 'input', 'select', 'textarea', 'label', 'button', 'ins', 'del', 'script'],
+\ { 'ondblclick': [], 'dir': ['ltr', 'rtl'], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'style': [], 'onmousemove': [], 'onmouseout': [], 'xml:lang': [], 'onmousedown': [], 'onkeypress': [], 'onclick': [], 'title': [], 'class': []}
+\ ],
+\ 'h6': [
+\ ['a', 'br', 'span', 'bdo', 'map', 'object', 'img', 'tt', 'i', 'b', 'big', 'small', 'em', 'strong', 'dfn', 'code', 'q', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'sub', 'sup', 'input', 'select', 'textarea', 'label', 'button', 'ins', 'del', 'script'],
+\ { 'ondblclick': [], 'dir': ['ltr', 'rtl'], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'style': [], 'onmousemove': [], 'onmouseout': [], 'xml:lang': [], 'onmousedown': [], 'onkeypress': [], 'onclick': [], 'title': [], 'class': []}
+\ ],
+\ 'head': [
+\ ['script', 'style', 'meta', 'link', 'object', 'title', 'script', 'style', 'meta', 'link', 'object', 'base', 'script', 'style', 'meta', 'link', 'object', 'base', 'script', 'style', 'meta', 'link', 'object', 'title', 'script', 'style', 'meta', 'link', 'object'],
+\ { 'profile': [], 'dir': ['ltr', 'rtl'], 'id': [], 'lang': [], 'xml:lang': []}
+\ ],
+\ 'hr': [
+\ [],
+\ { 'ondblclick': [], 'dir': ['ltr', 'rtl'], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'style': [], 'onmousemove': [], 'onmouseout': [], 'xml:lang': [], 'onmousedown': [], 'onkeypress': [], 'onclick': [], 'title': [], 'class': []}
+\ ],
+\ 'html': [
+\ ['head', 'body'],
+\ { 'xmlns': ['http://www.w3.org/1999/xhtml'], 'dir': ['ltr', 'rtl'], 'id': [], 'lang': [], 'xml:lang': []}
+\ ],
+\ 'i': [
+\ ['a', 'br', 'span', 'bdo', 'map', 'object', 'img', 'tt', 'i', 'b', 'big', 'small', 'em', 'strong', 'dfn', 'code', 'q', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'sub', 'sup', 'input', 'select', 'textarea', 'label', 'button', 'ins', 'del', 'script'],
+\ { 'ondblclick': [], 'dir': ['ltr', 'rtl'], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'style': [], 'onmousemove': [], 'onmouseout': [], 'xml:lang': [], 'onmousedown': [], 'onkeypress': [], 'onclick': [], 'title': [], 'class': []}
+\ ],
+\ 'img': [
+\ [],
+\ { 'width': [], 'usemap': [], 'ismap': ['BOOL'], 'ondblclick': [], 'dir': ['ltr', 'rtl'], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'alt': [], 'lang': [], 'src': [], 'longdesc': [], 'onmouseout': [], 'onmousemove': [], 'style': [], 'xml:lang': [], 'height': [], 'onkeypress': [], 'onmousedown': [], 'class': [], 'title': [], 'onclick': []}
+\ ],
+\ 'input': [
+\ [],
+\ { 'ondblclick': [], 'onkeydown': [], 'readonly': ['BOOL'], 'onchange': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'value': [], 'src': [], 'name': [], 'checked': ['BOOL'], 'onkeypress': [], 'onmousedown': [], 'class': [], 'title': [], 'onclick': [], 'type': ['text', 'password', 'checkbox', 'radio', 'submit', 'reset', 'file', 'hidden', 'image', 'button'], 'accesskey': [], 'disabled': ['BOOL'], 'usemap': [], 'dir': ['ltr', 'rtl'], 'onblur': [], 'size': [], 'onfocus': [], 'maxlength': [], 'onselect': [], 'accept': [], 'tabindex': [], 'alt': [], 'style': [], 'onmousemove': [], 'onmouseout': [], 'xml:lang': []}
+\ ],
+\ 'ins': [
+\ ['p', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'div', 'ul', 'ol', 'dl', 'pre', 'hr', 'blockquote', 'address', 'fieldset', 'table', 'form', 'a', 'br', 'span', 'bdo', 'map', 'object', 'img', 'tt', 'i', 'b', 'big', 'small', 'em', 'strong', 'dfn', 'code', 'q', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'sub', 'sup', 'input', 'select', 'textarea', 'label', 'button', 'noscript', 'ins', 'del', 'script'],
+\ { 'ondblclick': [], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'onkeypress': [], 'onmousedown': [], 'class': [], 'title': [], 'onclick': [], 'dir': ['ltr', 'rtl'], 'datetime': [], 'cite': [], 'onmouseout': [], 'onmousemove': [], 'style': [], 'xml:lang': []}
+\ ],
+\ 'kbd': [
+\ ['a', 'br', 'span', 'bdo', 'map', 'object', 'img', 'tt', 'i', 'b', 'big', 'small', 'em', 'strong', 'dfn', 'code', 'q', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'sub', 'sup', 'input', 'select', 'textarea', 'label', 'button', 'ins', 'del', 'script'],
+\ { 'ondblclick': [], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'onmousedown': [], 'onkeypress': [], 'onclick': [], 'title': [], 'class': [], 'dir': ['ltr', 'rtl'], 'style': [], 'onmousemove': [], 'onmouseout': [], 'xml:lang': []}
+\ ],
+\ 'label': [
+\ ['a', 'br', 'span', 'bdo', 'map', 'object', 'img', 'tt', 'i', 'b', 'big', 'small', 'em', 'strong', 'dfn', 'code', 'q', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'sub', 'sup', 'input', 'select', 'textarea', 'label', 'button', 'ins', 'del', 'script'],
+\ { 'ondblclick': [], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'for': [], 'onkeypress': [], 'onmousedown': [], 'class': [], 'title': [], 'onclick': [], 'accesskey': [], 'dir': ['ltr', 'rtl'], 'onblur': [], 'onfocus': [], 'onmouseout': [], 'onmousemove': [], 'style': [], 'xml:lang': []}
+\ ],
+\ 'legend': [
+\ ['a', 'br', 'span', 'bdo', 'map', 'object', 'img', 'tt', 'i', 'b', 'big', 'small', 'em', 'strong', 'dfn', 'code', 'q', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'sub', 'sup', 'input', 'select', 'textarea', 'label', 'button', 'ins', 'del', 'script'],
+\ { 'ondblclick': [], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'onmousedown': [], 'onkeypress': [], 'onclick': [], 'title': [], 'class': [], 'accesskey': [], 'dir': ['ltr', 'rtl'], 'style': [], 'onmousemove': [], 'onmouseout': [], 'xml:lang': []}
+\ ],
+\ 'li': [
+\ ['p', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'div', 'ul', 'ol', 'dl', 'pre', 'hr', 'blockquote', 'address', 'fieldset', 'table', 'form', 'a', 'br', 'span', 'bdo', 'map', 'object', 'img', 'tt', 'i', 'b', 'big', 'small', 'em', 'strong', 'dfn', 'code', 'q', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'sub', 'sup', 'input', 'select', 'textarea', 'label', 'button', 'noscript', 'ins', 'del', 'script'],
+\ { 'ondblclick': [], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'onmousedown': [], 'onkeypress': [], 'onclick': [], 'title': [], 'class': [], 'dir': ['ltr', 'rtl'], 'style': [], 'onmousemove': [], 'onmouseout': [], 'xml:lang': []}
+\ ],
+\ 'link': [
+\ [],
+\ { 'rel': [], 'ondblclick': [], 'onkeydown': [], 'onkeyup': [], 'href': [], 'media': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'charset': [], 'hreflang': [], 'onkeypress': [], 'onmousedown': [], 'rev': [], 'class': [], 'title': [], 'onclick': [], 'type': [], 'dir': ['ltr', 'rtl'], 'onmouseout': [], 'onmousemove': [], 'style': [], 'xml:lang': []}
+\ ],
+\ 'map': [
+\ ['p', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'div', 'ul', 'ol', 'dl', 'pre', 'hr', 'blockquote', 'address', 'fieldset', 'table', 'form', 'noscript', 'ins', 'del', 'script', 'area'],
+\ { 'ondblclick': [], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'name': [], 'onkeypress': [], 'onmousedown': [], 'class': [], 'onclick': [], 'title': [], 'dir': ['ltr', 'rtl'], 'style': [], 'onmouseout': [], 'onmousemove': [], 'xml:lang': []}
+\ ],
+\ 'meta': [
+\ [],
+\ { 'http-equiv': [], 'content': [], 'id': [], 'lang': [], 'name': [], 'scheme': [], 'dir': ['ltr', 'rtl'], 'xml:lang': []}
+\ ],
+\ 'noscript': [
+\ ['p', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'div', 'ul', 'ol', 'dl', 'pre', 'hr', 'blockquote', 'address', 'fieldset', 'table', 'form', 'noscript', 'ins', 'del', 'script'],
+\ { 'ondblclick': [], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'onmousedown': [], 'onkeypress': [], 'onclick': [], 'title': [], 'class': [], 'dir': ['ltr', 'rtl'], 'style': [], 'onmousemove': [], 'onmouseout': [], 'xml:lang': []}
+\ ],
+\ 'object': [
+\ ['param', 'p', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'div', 'ul', 'ol', 'dl', 'pre', 'hr', 'blockquote', 'address', 'fieldset', 'table', 'form', 'a', 'br', 'span', 'bdo', 'map', 'object', 'img', 'tt', 'i', 'b', 'big', 'small', 'em', 'strong', 'dfn', 'code', 'q', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'sub', 'sup', 'input', 'select', 'textarea', 'label', 'button', 'noscript', 'ins', 'del', 'script'],
+\ { 'ondblclick': [], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'name': [], 'data': [], 'declare': ['BOOL'], 'onkeypress': [], 'onmousedown': [], 'class': [], 'title': [], 'onclick': [], 'type': [], 'width': [], 'usemap': [], 'dir': ['ltr', 'rtl'], 'archive': [], 'standby': [], 'tabindex': [], 'classid': [], 'onmouseout': [], 'onmousemove': [], 'style': [], 'xml:lang': [], 'height': [], 'codetype': [], 'codebase': []}
+\ ],
+\ 'ol': [
+\ ['li'],
+\ { 'ondblclick': [], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'onmousedown': [], 'onkeypress': [], 'onclick': [], 'title': [], 'class': [], 'dir': ['ltr', 'rtl'], 'style': [], 'onmousemove': [], 'onmouseout': [], 'xml:lang': []}
+\ ],
+\ 'optgroup': [
+\ ['option'],
+\ { 'ondblclick': [], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'onkeypress': [], 'onmousedown': [], 'class': [], 'title': [], 'onclick': [], 'label': [], 'disabled': ['BOOL'], 'dir': ['ltr', 'rtl'], 'onmouseout': [], 'onmousemove': [], 'style': [], 'xml:lang': []}
+\ ],
+\ 'option': [
+\ [''],
+\ { 'ondblclick': [], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'value': [], 'onkeypress': [], 'onmousedown': [], 'class': [], 'title': [], 'onclick': [], 'label': [], 'disabled': ['BOOL'], 'dir': ['ltr', 'rtl'], 'onmouseout': [], 'onmousemove': [], 'style': [], 'xml:lang': [], 'selected': ['BOOL']}
+\ ],
+\ 'p': [
+\ ['a', 'br', 'span', 'bdo', 'map', 'object', 'img', 'tt', 'i', 'b', 'big', 'small', 'em', 'strong', 'dfn', 'code', 'q', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'sub', 'sup', 'input', 'select', 'textarea', 'label', 'button', 'ins', 'del', 'script'],
+\ { 'ondblclick': [], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'onmousedown': [], 'onkeypress': [], 'onclick': [], 'title': [], 'class': [], 'dir': ['ltr', 'rtl'], 'style': [], 'onmousemove': [], 'onmouseout': [], 'xml:lang': []}
+\ ],
+\ 'param': [
+\ [],
+\ { 'id': [], 'value': [], 'name': [], 'type': [], 'valuetype': ['data', 'ref', 'object']}
+\ ],
+\ 'pre': [
+\ ['a', 'tt', 'i', 'b', 'big', 'small', 'em', 'strong', 'dfn', 'code', 'q', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'sub', 'sup', 'br', 'span', 'bdo', 'map', 'ins', 'del', 'script', 'input', 'select', 'textarea', 'label', 'button'],
+\ { 'ondblclick': [], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'xml:space': ['preserve'], 'onkeypress': [], 'onmousedown': [], 'class': [], 'title': [], 'onclick': [], 'dir': ['ltr', 'rtl'], 'onmouseout': [], 'onmousemove': [], 'style': [], 'xml:lang': []}
+\ ],
+\ 'q': [
+\ ['a', 'br', 'span', 'bdo', 'map', 'object', 'img', 'tt', 'i', 'b', 'big', 'small', 'em', 'strong', 'dfn', 'code', 'q', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'sub', 'sup', 'input', 'select', 'textarea', 'label', 'button', 'ins', 'del', 'script'],
+\ { 'ondblclick': [], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'onmousedown': [], 'onkeypress': [], 'onclick': [], 'title': [], 'class': [], 'dir': ['ltr', 'rtl'], 'cite': [], 'style': [], 'onmousemove': [], 'onmouseout': [], 'xml:lang': []}
+\ ],
+\ 'samp': [
+\ ['a', 'br', 'span', 'bdo', 'map', 'object', 'img', 'tt', 'i', 'b', 'big', 'small', 'em', 'strong', 'dfn', 'code', 'q', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'sub', 'sup', 'input', 'select', 'textarea', 'label', 'button', 'ins', 'del', 'script'],
+\ { 'ondblclick': [], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'onmousedown': [], 'onkeypress': [], 'onclick': [], 'title': [], 'class': [], 'dir': ['ltr', 'rtl'], 'style': [], 'onmousemove': [], 'onmouseout': [], 'xml:lang': []}
+\ ],
+\ 'script': [
+\ [''],
+\ { 'id': [], 'src': [], 'charset': [], 'xml:space': ['preserve'], 'type': ['text/javascript'], 'defer': ['BOOL']}
+\ ],
+\ 'select': [
+\ ['optgroup', 'option'],
+\ { 'ondblclick': [], 'onkeydown': [], 'onchange': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'name': [], 'onkeypress': [], 'onmousedown': [], 'class': [], 'title': [], 'onclick': [], 'disabled': ['BOOL'], 'dir': ['ltr', 'rtl'], 'size': [], 'onblur': [], 'onfocus': [], 'tabindex': [], 'onmouseout': [], 'onmousemove': [], 'style': [], 'xml:lang': [], 'multiple': ['BOOL']}
+\ ],
+\ 'small': [
+\ ['a', 'br', 'span', 'bdo', 'map', 'object', 'img', 'tt', 'i', 'b', 'big', 'small', 'em', 'strong', 'dfn', 'code', 'q', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'sub', 'sup', 'input', 'select', 'textarea', 'label', 'button', 'ins', 'del', 'script'],
+\ { 'ondblclick': [], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'onmousedown': [], 'onkeypress': [], 'onclick': [], 'title': [], 'class': [], 'dir': ['ltr', 'rtl'], 'style': [], 'onmousemove': [], 'onmouseout': [], 'xml:lang': []}
+\ ],
+\ 'span': [
+\ ['a', 'br', 'span', 'bdo', 'map', 'object', 'img', 'tt', 'i', 'b', 'big', 'small', 'em', 'strong', 'dfn', 'code', 'q', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'sub', 'sup', 'input', 'select', 'textarea', 'label', 'button', 'ins', 'del', 'script'],
+\ { 'ondblclick': [], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'onmousedown': [], 'onkeypress': [], 'onclick': [], 'title': [], 'class': [], 'dir': ['ltr', 'rtl'], 'style': [], 'onmousemove': [], 'onmouseout': [], 'xml:lang': []}
+\ ],
+\ 'strong': [
+\ ['a', 'br', 'span', 'bdo', 'map', 'object', 'img', 'tt', 'i', 'b', 'big', 'small', 'em', 'strong', 'dfn', 'code', 'q', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'sub', 'sup', 'input', 'select', 'textarea', 'label', 'button', 'ins', 'del', 'script'],
+\ { 'ondblclick': [], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'onmousedown': [], 'onkeypress': [], 'onclick': [], 'title': [], 'class': [], 'dir': ['ltr', 'rtl'], 'style': [], 'onmousemove': [], 'onmouseout': [], 'xml:lang': []}
+\ ],
+\ 'style': [
+\ [''],
+\ { 'media': [], 'id': [], 'lang': [], 'xml:space': ['preserve'], 'title': [], 'type': ['text/css'], 'dir': ['ltr', 'rtl'], 'xml:lang': []}
+\ ],
+\ 'sub': [
+\ ['a', 'br', 'span', 'bdo', 'map', 'object', 'img', 'tt', 'i', 'b', 'big', 'small', 'em', 'strong', 'dfn', 'code', 'q', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'sub', 'sup', 'input', 'select', 'textarea', 'label', 'button', 'ins', 'del', 'script'],
+\ { 'ondblclick': [], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'onmousedown': [], 'onkeypress': [], 'onclick': [], 'title': [], 'class': [], 'dir': ['ltr', 'rtl'], 'style': [], 'onmousemove': [], 'onmouseout': [], 'xml:lang': []}
+\ ],
+\ 'sup': [
+\ ['a', 'br', 'span', 'bdo', 'map', 'object', 'img', 'tt', 'i', 'b', 'big', 'small', 'em', 'strong', 'dfn', 'code', 'q', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'sub', 'sup', 'input', 'select', 'textarea', 'label', 'button', 'ins', 'del', 'script'],
+\ { 'ondblclick': [], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'onmousedown': [], 'onkeypress': [], 'onclick': [], 'title': [], 'class': [], 'dir': ['ltr', 'rtl'], 'style': [], 'onmousemove': [], 'onmouseout': [], 'xml:lang': []}
+\ ],
+\ 'table': [
+\ ['caption', 'col', 'colgroup', 'thead', 'tfoot', 'tbody', 'tr'],
+\ { 'ondblclick': [], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'onkeypress': [], 'onmousedown': [], 'class': [], 'title': [], 'onclick': [], 'width': [], 'frame': ['void', 'above', 'below', 'hsides', 'lhs', 'rhs', 'vsides', 'box', 'border'], 'rules': ['none', 'groups', 'rows', 'cols', 'all'], 'dir': ['ltr', 'rtl'], 'summary': [], 'cellspacing': [], 'onmouseout': [], 'onmousemove': [], 'style': [], 'xml:lang': [], 'border': [], 'cellpadding': []}
+\ ],
+\ 'tbody': [
+\ ['tr'],
+\ { 'ondblclick': [], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'align': ['left', 'center', 'right', 'justify', 'char'], 'lang': [], 'valign': ['top', 'middle', 'bottom', 'baseline'], 'onkeypress': [], 'onmousedown': [], 'class': [], 'title': [], 'onclick': [], 'dir': ['ltr', 'rtl'], 'charoff': [], 'onmouseout': [], 'onmousemove': [], 'style': [], 'xml:lang': [], 'char': []}
+\ ],
+\ 'td': [
+\ ['p', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'div', 'ul', 'ol', 'dl', 'pre', 'hr', 'blockquote', 'address', 'fieldset', 'table', 'form', 'a', 'br', 'span', 'bdo', 'map', 'object', 'img', 'tt', 'i', 'b', 'big', 'small', 'em', 'strong', 'dfn', 'code', 'q', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'sub', 'sup', 'input', 'select', 'textarea', 'label', 'button', 'noscript', 'ins', 'del', 'script'],
+\ { 'ondblclick': [], 'axis': [], 'onkeydown': [], 'abbr': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'scope': ['row', 'col', 'rowgroup', 'colgroup'], 'onmouseover': [], 'lang': [], 'align': ['left', 'center', 'right', 'justify', 'char'], 'valign': ['top', 'middle', 'bottom', 'baseline'], 'onkeypress': [], 'onmousedown': [], 'class': [], 'title': [], 'onclick': [], 'headers': [], 'dir': ['ltr', 'rtl'], 'rowspan': ['1'], 'colspan': ['1'], 'charoff': [], 'onmouseout': [], 'onmousemove': [], 'style': [], 'xml:lang': [], 'char': []}
+\ ],
+\ 'textarea': [
+\ [''],
+\ { 'ondblclick': [], 'cols': [], 'onkeydown': [], 'readonly': ['BOOL'], 'onchange': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'name': [], 'onkeypress': [], 'onmousedown': [], 'class': [], 'title': [], 'onclick': [], 'accesskey': [], 'disabled': ['BOOL'], 'rows': [], 'dir': ['ltr', 'rtl'], 'onblur': [], 'onfocus': [], 'onselect': [], 'tabindex': [], 'onmouseout': [], 'onmousemove': [], 'style': [], 'xml:lang': []}
+\ ],
+\ 'tfoot': [
+\ ['tr'],
+\ { 'ondblclick': [], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'align': ['left', 'center', 'right', 'justify', 'char'], 'lang': [], 'valign': ['top', 'middle', 'bottom', 'baseline'], 'onkeypress': [], 'onmousedown': [], 'class': [], 'title': [], 'onclick': [], 'dir': ['ltr', 'rtl'], 'charoff': [], 'onmouseout': [], 'onmousemove': [], 'style': [], 'xml:lang': [], 'char': []}
+\ ],
+\ 'th': [
+\ ['p', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'div', 'ul', 'ol', 'dl', 'pre', 'hr', 'blockquote', 'address', 'fieldset', 'table', 'form', 'a', 'br', 'span', 'bdo', 'map', 'object', 'img', 'tt', 'i', 'b', 'big', 'small', 'em', 'strong', 'dfn', 'code', 'q', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'sub', 'sup', 'input', 'select', 'textarea', 'label', 'button', 'noscript', 'ins', 'del', 'script'],
+\ { 'ondblclick': [], 'axis': [], 'onkeydown': [], 'abbr': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'scope': ['row', 'col', 'rowgroup', 'colgroup'], 'onmouseover': [], 'lang': [], 'align': ['left', 'center', 'right', 'justify', 'char'], 'valign': ['top', 'middle', 'bottom', 'baseline'], 'onkeypress': [], 'onmousedown': [], 'class': [], 'title': [], 'onclick': [], 'headers': [], 'dir': ['ltr', 'rtl'], 'rowspan': ['1'], 'colspan': ['1'], 'charoff': [], 'onmouseout': [], 'onmousemove': [], 'style': [], 'xml:lang': [], 'char': []}
+\ ],
+\ 'thead': [
+\ ['tr'],
+\ { 'ondblclick': [], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'align': ['left', 'center', 'right', 'justify', 'char'], 'lang': [], 'valign': ['top', 'middle', 'bottom', 'baseline'], 'onkeypress': [], 'onmousedown': [], 'class': [], 'title': [], 'onclick': [], 'dir': ['ltr', 'rtl'], 'charoff': [], 'onmouseout': [], 'onmousemove': [], 'style': [], 'xml:lang': [], 'char': []}
+\ ],
+\ 'title': [
+\ [''],
+\ { 'id': [], 'lang': [], 'dir': ['ltr', 'rtl'], 'xml:lang': []}
+\ ],
+\ 'tr': [
+\ ['th', 'td'],
+\ { 'ondblclick': [], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'align': ['left', 'center', 'right', 'justify', 'char'], 'lang': [], 'valign': ['top', 'middle', 'bottom', 'baseline'], 'onkeypress': [], 'onmousedown': [], 'class': [], 'title': [], 'onclick': [], 'dir': ['ltr', 'rtl'], 'charoff': [], 'onmouseout': [], 'onmousemove': [], 'style': [], 'xml:lang': [], 'char': []}
+\ ],
+\ 'tt': [
+\ ['a', 'br', 'span', 'bdo', 'map', 'object', 'img', 'tt', 'i', 'b', 'big', 'small', 'em', 'strong', 'dfn', 'code', 'q', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'sub', 'sup', 'input', 'select', 'textarea', 'label', 'button', 'ins', 'del', 'script'],
+\ { 'ondblclick': [], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'onmousedown': [], 'onkeypress': [], 'onclick': [], 'title': [], 'class': [], 'dir': ['ltr', 'rtl'], 'style': [], 'onmousemove': [], 'onmouseout': [], 'xml:lang': []}
+\ ],
+\ 'ul': [
+\ ['li'],
+\ { 'ondblclick': [], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'onmousedown': [], 'onkeypress': [], 'onclick': [], 'title': [], 'class': [], 'dir': ['ltr', 'rtl'], 'style': [], 'onmousemove': [], 'onmouseout': [], 'xml:lang': []}
+\ ],
+\ 'var': [
+\ ['a', 'br', 'span', 'bdo', 'map', 'object', 'img', 'tt', 'i', 'b', 'big', 'small', 'em', 'strong', 'dfn', 'code', 'q', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'sub', 'sup', 'input', 'select', 'textarea', 'label', 'button', 'ins', 'del', 'script'],
+\ { 'ondblclick': [], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'onmousedown': [], 'onkeypress': [], 'onclick': [], 'title': [], 'class': [], 'dir': ['ltr', 'rtl'], 'style': [], 'onmousemove': [], 'onmouseout': [], 'xml:lang': []}
+\ ],
+\ 'vimxmlattrinfo' : {
+\ 'accept' : ['ContentType', ''],
+\ 'accesskey' : ['Character', ''],
+\ 'action' : ['*URI', ''],
+\ 'align' : ['String', ''],
+\ 'alt' : ['*Text', ''],
+\ 'archive' : ['UriList', ''],
+\ 'axis' : ['CDATA', ''],
+\ 'border' : ['Pixels', ''],
+\ 'cellpadding' : ['Length', ''],
+\ 'cellspacing' : ['Length', ''],
+\ 'char' : ['Character', ''],
+\ 'charoff' : ['Length', ''],
+\ 'charset' : ['LangCode', ''],
+\ 'checked' : ['Bool', ''],
+\ 'class' : ['CDATA', ''],
+\ 'codetype' : ['ContentType', ''],
+\ 'cols' : ['*Number', ''],
+\ 'colspan' : ['Number', ''],
+\ 'content' : ['*CDATA', ''],
+\ 'coords' : ['Coords', ''],
+\ 'data' : ['URI', ''],
+\ 'datetime' : ['DateTime', ''],
+\ 'declare' : ['Bool', ''],
+\ 'defer' : ['Bool', ''],
+\ 'dir' : ['String', ''],
+\ 'disabled' : ['Bool', ''],
+\ 'enctype' : ['ContentType', ''],
+\ 'for' : ['ID', ''],
+\ 'headers' : ['IDREFS', ''],
+\ 'height' : ['Number', ''],
+\ 'href' : ['*URI', ''],
+\ 'hreflang' : ['LangCode', ''],
+\ 'id' : ['ID', ''],
+\ 'ismap' : ['Bool', ''],
+\ 'label' : ['*Text', ''],
+\ 'lang' : ['LangCode', ''],
+\ 'longdesc' : ['URI', ''],
+\ 'maxlength' : ['Number', ''],
+\ 'media' : ['MediaDesc', ''],
+\ 'method' : ['String', ''],
+\ 'multiple' : ['Bool', ''],
+\ 'name' : ['CDATA', ''],
+\ 'nohref' : ['Bool', ''],
+\ 'onblur' : ['Script', ''],
+\ 'onchange' : ['Script', ''],
+\ 'onclick' : ['Script', ''],
+\ 'ondblclick' : ['Script', ''],
+\ 'onfocus' : ['Script', ''],
+\ 'onkeydown' : ['Script', ''],
+\ 'onkeypress' : ['Script', ''],
+\ 'onkeyup' : ['Script', ''],
+\ 'onload' : ['Script', ''],
+\ 'onmousedown' : ['Script', ''],
+\ 'onmousemove' : ['Script', ''],
+\ 'onmouseout' : ['Script', ''],
+\ 'onmouseover' : ['Script', ''],
+\ 'onmouseup' : ['Script', ''],
+\ 'onreset' : ['Script', ''],
+\ 'onselect' : ['Script', ''],
+\ 'onsubmit' : ['Script', ''],
+\ 'onunload' : ['Script', ''],
+\ 'profile' : ['URI', ''],
+\ 'readonly' : ['Bool', ''],
+\ 'rel' : ['LinkTypes', ''],
+\ 'rev' : ['LinkTypes', ''],
+\ 'rows' : ['*Number', ''],
+\ 'rules' : ['String', ''],
+\ 'scheme' : ['CDATA', ''],
+\ 'selected' : ['Bool', ''],
+\ 'shape' : ['Shape', ''],
+\ 'size' : ['CDATA', ''],
+\ 'span' : ['Number', ''],
+\ 'src' : ['*URI', ''],
+\ 'standby' : ['Text', ''],
+\ 'style' : ['StyleSheet', ''],
+\ 'summary' : ['*Text', ''],
+\ 'tabindex' : ['Number', ''],
+\ 'title' : ['Text', ''],
+\ 'type' : ['*ContentType', ''],
+\ 'usemap' : ['URI', ''],
+\ 'valign' : ['String', ''],
+\ 'valuetype' : ['String', ''],
+\ 'width' : ['Number', ''],
+\ 'xmlns' : ['URI', '']
+\ },
+\ 'vimxmltaginfo': {
+\ 'area': ['/>', ''],
+\ 'base': ['/>', ''],
+\ 'br': ['/>', ''],
+\ 'col': ['/>', ''],
+\ 'hr': ['/>', ''],
+\ 'img': ['/>', ''],
+\ 'input': ['/>', ''],
+\ 'link': ['/>', ''],
+\ 'meta': ['/>', ''],
+\ 'param': ['/>', ''],
+\ }
+\ }
+" vim:ft=vim:ff=unix
--- /dev/null
+++ b/lib/vimfiles/autoload/xml/xhtml10t.vim
@@ -1,0 +1,461 @@
+let g:xmldata_xhtml10t = {
+\ 'vimxmlentities': ['AElig', 'Aacute', 'Acirc', 'Agrave', 'Alpha', 'Aring', 'Atilde', 'Auml', 'Beta', 'Ccedil', 'Chi', 'Dagger', 'Delta', 'ETH', 'Eacute', 'Ecirc', 'Egrave', 'Epsilon', 'Eta', 'Euml', 'Gamma', 'Iacute', 'Icirc', 'Igrave', 'Iota', 'Iuml', 'Kappa', 'Lambda', 'Mu', 'Ntilde', 'Nu', 'OElig', 'Oacute', 'Ocirc', 'Ograve', 'Omega', 'Omicron', 'Oslash', 'Otilde', 'Ouml', 'Phi', 'Pi', 'Prime', 'Psi', 'Rho', 'Scaron', 'Sigma', 'THORN', 'Tau', 'Theta', 'Uacute', 'Ucirc', 'Ugrave', 'Upsilon', 'Uuml', 'Xi', 'Yacute', 'Yuml', 'Zeta', 'aacute', 'acirc', 'acute', 'aelig', 'agrave', 'alefsym', 'alpha', 'amp', 'and', 'ang', 'apos', 'aring', 'asymp', 'atilde', 'auml', 'bdquo', 'beta', 'brvbar', 'bull', 'cap', 'ccedil', 'cedil', 'cent', 'chi', 'circ', 'clubs', 'cong', 'copy', 'crarr', 'cup', 'curren', 'dArr', 'dagger', 'darr', 'deg', 'delta', 'diams', 'divide', 'eacute', 'ecirc', 'egrave', 'empty', 'emsp', 'ensp', 'epsilon', 'equiv', 'eta', 'eth', 'euml', 'euro', 'exist', 'fnof', 'forall', 'frac12', 'frac14', 'frac34', 'frasl', 'gamma', 'ge', 'gt', 'hArr', 'harr', 'hearts', 'hellip', 'iacute', 'icirc', 'iexcl', 'igrave', 'image', 'infin', 'int', 'iota', 'iquest', 'isin', 'iuml', 'kappa', 'lArr', 'lambda', 'lang', 'laquo', 'larr', 'lceil', 'ldquo', 'le', 'lfloor', 'lowast', 'loz', 'lrm', 'lsaquo', 'lsquo', 'lt', 'macr', 'mdash', 'micro', 'middot', 'minus', 'mu', 'nabla', 'nbsp', 'ndash', 'ne', 'ni', 'not', 'notin', 'nsub', 'ntilde', 'nu', 'oacute', 'ocirc', 'oelig', 'ograve', 'oline', 'omega', 'omicron', 'oplus', 'or', 'ordf', 'ordm', 'oslash', 'otilde', 'otimes', 'ouml', 'para', 'part', 'permil', 'perp', 'phi', 'pi', 'piv', 'plusmn', 'pound', 'prime', 'prod', 'prop', 'psi', 'quot', 'rArr', 'radic', 'rang', 'raquo', 'rarr', 'rceil', 'rdquo', 'real', 'reg', 'rfloor', 'rho', 'rlm', 'rsaquo', 'rsquo', 'sbquo', 'scaron', 'sdot', 'sect', 'shy', 'sigma', 'sigmaf', 'sim', 'spades', 'sub', 'sube', 'sum', 'sup', 'sup1', 'sup2', 'sup3', 'supe', 'szlig', 'tau', 'there4', 'theta', 'thetasym', 'thinsp', 'thorn', 'tilde', 'times', 'trade', 'uArr', 'uacute', 'uarr', 'ucirc', 'ugrave', 'uml', 'upsih', 'upsilon', 'uuml', 'weierp', 'xi', 'yacute', 'yen', 'yuml', 'zeta', 'zwj', 'zwnj'],
+\ 'vimxmlroot': ['html'],
+\ 'a': [
+\ ['br', 'span', 'bdo', 'object', 'applet', 'img', 'map', 'iframe', 'tt', 'i', 'b', 'u', 's', 'strike', 'big', 'small', 'font', 'basefont', 'em', 'strong', 'dfn', 'code', 'q', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'sub', 'sup', 'input', 'select', 'textarea', 'label', 'button', 'ins', 'del', 'script'],
+\ { 'accesskey': [], 'rel': [], 'coords': [], 'ondblclick': [], 'dir': ['ltr', 'rtl'], 'onblur': [], 'onkeydown': [], 'target': [], 'onfocus': [], 'onkeyup': [], 'href': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'tabindex': [], 'onmouseout': [], 'onmousemove': [], 'style': [], 'name': [], 'charset': [], 'xml:lang': [], 'hreflang': [], 'onkeypress': [], 'onmousedown': [], 'rev': [], 'class': [], 'title': [], 'onclick': [], 'type': [], 'shape': ['rect', 'circle', 'poly', 'default']}
+\ ],
+\ 'abbr': [
+\ ['a', 'br', 'span', 'bdo', 'object', 'applet', 'img', 'map', 'iframe', 'tt', 'i', 'b', 'u', 's', 'strike', 'big', 'small', 'font', 'basefont', 'em', 'strong', 'dfn', 'code', 'q', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'sub', 'sup', 'input', 'select', 'textarea', 'label', 'button', 'ins', 'del', 'script'],
+\ { 'ondblclick': [], 'dir': ['ltr', 'rtl'], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'style': [], 'onmousemove': [], 'onmouseout': [], 'xml:lang': [], 'onmousedown': [], 'onkeypress': [], 'onclick': [], 'title': [], 'class': []}
+\ ],
+\ 'acronym': [
+\ ['a', 'br', 'span', 'bdo', 'object', 'applet', 'img', 'map', 'iframe', 'tt', 'i', 'b', 'u', 's', 'strike', 'big', 'small', 'font', 'basefont', 'em', 'strong', 'dfn', 'code', 'q', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'sub', 'sup', 'input', 'select', 'textarea', 'label', 'button', 'ins', 'del', 'script'],
+\ { 'ondblclick': [], 'dir': ['ltr', 'rtl'], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'style': [], 'onmousemove': [], 'onmouseout': [], 'xml:lang': [], 'onmousedown': [], 'onkeypress': [], 'onclick': [], 'title': [], 'class': []}
+\ ],
+\ 'address': [
+\ ['a', 'br', 'span', 'bdo', 'object', 'applet', 'img', 'map', 'iframe', 'tt', 'i', 'b', 'u', 's', 'strike', 'big', 'small', 'font', 'basefont', 'em', 'strong', 'dfn', 'code', 'q', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'sub', 'sup', 'input', 'select', 'textarea', 'label', 'button', 'ins', 'del', 'script', 'p'],
+\ { 'ondblclick': [], 'dir': ['ltr', 'rtl'], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'style': [], 'onmousemove': [], 'onmouseout': [], 'xml:lang': [], 'onmousedown': [], 'onkeypress': [], 'onclick': [], 'title': [], 'class': []}
+\ ],
+\ 'applet': [
+\ ['param', 'p', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'div', 'ul', 'ol', 'dl', 'menu', 'dir', 'pre', 'hr', 'blockquote', 'address', 'center', 'noframes', 'isindex', 'fieldset', 'table', 'form', 'a', 'br', 'span', 'bdo', 'object', 'applet', 'img', 'map', 'iframe', 'tt', 'i', 'b', 'u', 's', 'strike', 'big', 'small', 'font', 'basefont', 'em', 'strong', 'dfn', 'code', 'q', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'sub', 'sup', 'input', 'select', 'textarea', 'label', 'button', 'noscript', 'ins', 'del', 'script'],
+\ { 'width': [], 'object': [], 'id': [], 'code': [], 'vspace': [], 'archive': [], 'alt': [], 'align': ['top', 'middle', 'bottom', 'left', 'right'], 'style': [], 'name': [], 'height': [], 'hspace': [], 'title': [], 'class': [], 'codebase': []}
+\ ],
+\ 'area': [
+\ [],
+\ { 'accesskey': [], 'coords': [], 'ondblclick': [], 'dir': ['ltr', 'rtl'], 'onblur': [], 'onkeydown': [], 'onfocus': [], 'nohref': ['BOOL'], 'target': [], 'onkeyup': [], 'href': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'tabindex': [], 'lang': [], 'alt': [], 'onmouseout': [], 'onmousemove': [], 'style': [], 'xml:lang': [], 'onkeypress': [], 'onmousedown': [], 'class': [], 'title': [], 'onclick': [], 'shape': ['rect', 'circle', 'poly', 'default']}
+\ ],
+\ 'b': [
+\ ['a', 'br', 'span', 'bdo', 'object', 'applet', 'img', 'map', 'iframe', 'tt', 'i', 'b', 'u', 's', 'strike', 'big', 'small', 'font', 'basefont', 'em', 'strong', 'dfn', 'code', 'q', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'sub', 'sup', 'input', 'select', 'textarea', 'label', 'button', 'ins', 'del', 'script'],
+\ { 'ondblclick': [], 'dir': ['ltr', 'rtl'], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'style': [], 'onmousemove': [], 'onmouseout': [], 'xml:lang': [], 'onmousedown': [], 'onkeypress': [], 'onclick': [], 'title': [], 'class': []}
+\ ],
+\ 'base': [
+\ [],
+\ { 'target': [], 'href': [], 'id': []}
+\ ],
+\ 'basefont': [
+\ [],
+\ { 'size': [], 'face': [], 'color': [], 'id': []}
+\ ],
+\ 'bdo': [
+\ ['a', 'br', 'span', 'bdo', 'object', 'applet', 'img', 'map', 'iframe', 'tt', 'i', 'b', 'u', 's', 'strike', 'big', 'small', 'font', 'basefont', 'em', 'strong', 'dfn', 'code', 'q', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'sub', 'sup', 'input', 'select', 'textarea', 'label', 'button', 'ins', 'del', 'script'],
+\ { 'ondblclick': [], 'dir': ['ltr', 'rtl'], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'style': [], 'onmousemove': [], 'onmouseout': [], 'xml:lang': [], 'onmousedown': [], 'onkeypress': [], 'onclick': [], 'title': [], 'class': []}
+\ ],
+\ 'big': [
+\ ['a', 'br', 'span', 'bdo', 'object', 'applet', 'img', 'map', 'iframe', 'tt', 'i', 'b', 'u', 's', 'strike', 'big', 'small', 'font', 'basefont', 'em', 'strong', 'dfn', 'code', 'q', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'sub', 'sup', 'input', 'select', 'textarea', 'label', 'button', 'ins', 'del', 'script'],
+\ { 'ondblclick': [], 'dir': ['ltr', 'rtl'], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'style': [], 'onmousemove': [], 'onmouseout': [], 'xml:lang': [], 'onmousedown': [], 'onkeypress': [], 'onclick': [], 'title': [], 'class': []}
+\ ],
+\ 'blockquote': [
+\ ['p', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'div', 'ul', 'ol', 'dl', 'menu', 'dir', 'pre', 'hr', 'blockquote', 'address', 'center', 'noframes', 'isindex', 'fieldset', 'table', 'form', 'a', 'br', 'span', 'bdo', 'object', 'applet', 'img', 'map', 'iframe', 'tt', 'i', 'b', 'u', 's', 'strike', 'big', 'small', 'font', 'basefont', 'em', 'strong', 'dfn', 'code', 'q', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'sub', 'sup', 'input', 'select', 'textarea', 'label', 'button', 'noscript', 'ins', 'del', 'script'],
+\ { 'ondblclick': [], 'dir': ['ltr', 'rtl'], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'cite': [], 'onmouseover': [], 'lang': [], 'style': [], 'onmousemove': [], 'onmouseout': [], 'xml:lang': [], 'onmousedown': [], 'onkeypress': [], 'onclick': [], 'title': [], 'class': []}
+\ ],
+\ 'body': [
+\ ['p', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'div', 'ul', 'ol', 'dl', 'menu', 'dir', 'pre', 'hr', 'blockquote', 'address', 'center', 'noframes', 'isindex', 'fieldset', 'table', 'form', 'a', 'br', 'span', 'bdo', 'object', 'applet', 'img', 'map', 'iframe', 'tt', 'i', 'b', 'u', 's', 'strike', 'big', 'small', 'font', 'basefont', 'em', 'strong', 'dfn', 'code', 'q', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'sub', 'sup', 'input', 'select', 'textarea', 'label', 'button', 'noscript', 'ins', 'del', 'script'],
+\ { 'vlink': [], 'ondblclick': [], 'dir': ['ltr', 'rtl'], 'onkeydown': [], 'alink': [], 'onkeyup': [], 'bgcolor': [], 'text': [], 'onmouseup': [], 'id': [], 'link': [], 'onmouseover': [], 'lang': [], 'onmouseout': [], 'onmousemove': [], 'style': [], 'background': [], 'xml:lang': [], 'onunload': [], 'onkeypress': [], 'onmousedown': [], 'onload': [], 'class': [], 'title': [], 'onclick': []}
+\ ],
+\ 'br': [
+\ [],
+\ { 'clear': ['none', 'left', 'all', 'right', 'none'], 'id': [], 'style': [], 'class': [], 'title': []}
+\ ],
+\ 'button': [
+\ ['p', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'div', 'ul', 'ol', 'dl', 'menu', 'dir', 'pre', 'hr', 'blockquote', 'address', 'center', 'noframes', 'table', 'br', 'span', 'bdo', 'object', 'applet', 'img', 'map', 'tt', 'i', 'b', 'u', 's', 'strike', 'big', 'small', 'font', 'basefont', 'em', 'strong', 'dfn', 'code', 'q', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'sub', 'sup', 'noscript', 'ins', 'del', 'script'],
+\ { 'accesskey': [], 'disabled': ['BOOL'], 'ondblclick': [], 'dir': ['ltr', 'rtl'], 'onblur': [], 'onkeydown': [], 'onfocus': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'tabindex': [], 'lang': [], 'value': [], 'onmouseout': [], 'onmousemove': [], 'style': [], 'name': [], 'xml:lang': [], 'onkeypress': [], 'onmousedown': [], 'class': [], 'title': [], 'onclick': [], 'type': ['submit', 'button', 'submit', 'reset']}
+\ ],
+\ 'caption': [
+\ ['a', 'br', 'span', 'bdo', 'object', 'applet', 'img', 'map', 'iframe', 'tt', 'i', 'b', 'u', 's', 'strike', 'big', 'small', 'font', 'basefont', 'em', 'strong', 'dfn', 'code', 'q', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'sub', 'sup', 'input', 'select', 'textarea', 'label', 'button', 'ins', 'del', 'script'],
+\ { 'ondblclick': [], 'dir': ['ltr', 'rtl'], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'align': ['top', 'bottom', 'left', 'right'], 'lang': [], 'onmouseout': [], 'onmousemove': [], 'style': [], 'xml:lang': [], 'onkeypress': [], 'onmousedown': [], 'class': [], 'title': [], 'onclick': []}
+\ ],
+\ 'center': [
+\ ['p', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'div', 'ul', 'ol', 'dl', 'menu', 'dir', 'pre', 'hr', 'blockquote', 'address', 'center', 'noframes', 'isindex', 'fieldset', 'table', 'form', 'a', 'br', 'span', 'bdo', 'object', 'applet', 'img', 'map', 'iframe', 'tt', 'i', 'b', 'u', 's', 'strike', 'big', 'small', 'font', 'basefont', 'em', 'strong', 'dfn', 'code', 'q', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'sub', 'sup', 'input', 'select', 'textarea', 'label', 'button', 'noscript', 'ins', 'del', 'script'],
+\ { 'ondblclick': [], 'dir': ['ltr', 'rtl'], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'style': [], 'onmousemove': [], 'onmouseout': [], 'xml:lang': [], 'onmousedown': [], 'onkeypress': [], 'onclick': [], 'title': [], 'class': []}
+\ ],
+\ 'cite': [
+\ ['a', 'br', 'span', 'bdo', 'object', 'applet', 'img', 'map', 'iframe', 'tt', 'i', 'b', 'u', 's', 'strike', 'big', 'small', 'font', 'basefont', 'em', 'strong', 'dfn', 'code', 'q', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'sub', 'sup', 'input', 'select', 'textarea', 'label', 'button', 'ins', 'del', 'script'],
+\ { 'ondblclick': [], 'dir': ['ltr', 'rtl'], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'style': [], 'onmousemove': [], 'onmouseout': [], 'xml:lang': [], 'onmousedown': [], 'onkeypress': [], 'onclick': [], 'title': [], 'class': []}
+\ ],
+\ 'code': [
+\ ['a', 'br', 'span', 'bdo', 'object', 'applet', 'img', 'map', 'iframe', 'tt', 'i', 'b', 'u', 's', 'strike', 'big', 'small', 'font', 'basefont', 'em', 'strong', 'dfn', 'code', 'q', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'sub', 'sup', 'input', 'select', 'textarea', 'label', 'button', 'ins', 'del', 'script'],
+\ { 'ondblclick': [], 'dir': ['ltr', 'rtl'], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'style': [], 'onmousemove': [], 'onmouseout': [], 'xml:lang': [], 'onmousedown': [], 'onkeypress': [], 'onclick': [], 'title': [], 'class': []}
+\ ],
+\ 'col': [
+\ [],
+\ { 'width': [], 'ondblclick': [], 'dir': ['ltr', 'rtl'], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'charoff': [], 'onmouseover': [], 'lang': [], 'align': ['left', 'center', 'right', 'justify', 'char'], 'valign': ['top', 'middle', 'bottom', 'baseline'], 'onmouseout': [], 'onmousemove': [], 'style': [], 'xml:lang': [], 'onkeypress': [], 'onmousedown': [], 'char': [], 'span': ['1'], 'class': [], 'title': [], 'onclick': []}
+\ ],
+\ 'colgroup': [
+\ ['col'],
+\ { 'width': [], 'ondblclick': [], 'dir': ['ltr', 'rtl'], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'charoff': [], 'onmouseover': [], 'lang': [], 'align': ['left', 'center', 'right', 'justify', 'char'], 'valign': ['top', 'middle', 'bottom', 'baseline'], 'onmouseout': [], 'onmousemove': [], 'style': [], 'xml:lang': [], 'onkeypress': [], 'onmousedown': [], 'char': [], 'span': ['1'], 'class': [], 'title': [], 'onclick': []}
+\ ],
+\ 'dd': [
+\ ['p', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'div', 'ul', 'ol', 'dl', 'menu', 'dir', 'pre', 'hr', 'blockquote', 'address', 'center', 'noframes', 'isindex', 'fieldset', 'table', 'form', 'a', 'br', 'span', 'bdo', 'object', 'applet', 'img', 'map', 'iframe', 'tt', 'i', 'b', 'u', 's', 'strike', 'big', 'small', 'font', 'basefont', 'em', 'strong', 'dfn', 'code', 'q', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'sub', 'sup', 'input', 'select', 'textarea', 'label', 'button', 'noscript', 'ins', 'del', 'script'],
+\ { 'ondblclick': [], 'dir': ['ltr', 'rtl'], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'style': [], 'onmousemove': [], 'onmouseout': [], 'xml:lang': [], 'onmousedown': [], 'onkeypress': [], 'onclick': [], 'title': [], 'class': []}
+\ ],
+\ 'del': [
+\ ['p', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'div', 'ul', 'ol', 'dl', 'menu', 'dir', 'pre', 'hr', 'blockquote', 'address', 'center', 'noframes', 'isindex', 'fieldset', 'table', 'form', 'a', 'br', 'span', 'bdo', 'object', 'applet', 'img', 'map', 'iframe', 'tt', 'i', 'b', 'u', 's', 'strike', 'big', 'small', 'font', 'basefont', 'em', 'strong', 'dfn', 'code', 'q', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'sub', 'sup', 'input', 'select', 'textarea', 'label', 'button', 'noscript', 'ins', 'del', 'script'],
+\ { 'ondblclick': [], 'dir': ['ltr', 'rtl'], 'datetime': [], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'cite': [], 'onmouseover': [], 'lang': [], 'onmouseout': [], 'onmousemove': [], 'style': [], 'xml:lang': [], 'onkeypress': [], 'onmousedown': [], 'class': [], 'title': [], 'onclick': []}
+\ ],
+\ 'dfn': [
+\ ['a', 'br', 'span', 'bdo', 'object', 'applet', 'img', 'map', 'iframe', 'tt', 'i', 'b', 'u', 's', 'strike', 'big', 'small', 'font', 'basefont', 'em', 'strong', 'dfn', 'code', 'q', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'sub', 'sup', 'input', 'select', 'textarea', 'label', 'button', 'ins', 'del', 'script'],
+\ { 'ondblclick': [], 'dir': ['ltr', 'rtl'], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'style': [], 'onmousemove': [], 'onmouseout': [], 'xml:lang': [], 'onmousedown': [], 'onkeypress': [], 'onclick': [], 'title': [], 'class': []}
+\ ],
+\ 'dir': [
+\ ['li'],
+\ { 'ondblclick': [], 'dir': ['ltr', 'rtl'], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'compact': ['BOOL'], 'onmouseover': [], 'lang': [], 'style': [], 'onmousemove': [], 'onmouseout': [], 'xml:lang': [], 'onmousedown': [], 'onkeypress': [], 'onclick': [], 'title': [], 'class': []}
+\ ],
+\ 'div': [
+\ ['p', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'div', 'ul', 'ol', 'dl', 'menu', 'dir', 'pre', 'hr', 'blockquote', 'address', 'center', 'noframes', 'isindex', 'fieldset', 'table', 'form', 'a', 'br', 'span', 'bdo', 'object', 'applet', 'img', 'map', 'iframe', 'tt', 'i', 'b', 'u', 's', 'strike', 'big', 'small', 'font', 'basefont', 'em', 'strong', 'dfn', 'code', 'q', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'sub', 'sup', 'input', 'select', 'textarea', 'label', 'button', 'noscript', 'ins', 'del', 'script'],
+\ { 'ondblclick': [], 'dir': ['ltr', 'rtl'], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'align': ['left', 'center', 'right', 'justify'], 'lang': [], 'onmouseout': [], 'onmousemove': [], 'style': [], 'xml:lang': [], 'onkeypress': [], 'onmousedown': [], 'class': [], 'title': [], 'onclick': []}
+\ ],
+\ 'dl': [
+\ ['dt', 'dd'],
+\ { 'ondblclick': [], 'dir': ['ltr', 'rtl'], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'compact': ['BOOL'], 'onmouseover': [], 'lang': [], 'style': [], 'onmousemove': [], 'onmouseout': [], 'xml:lang': [], 'onmousedown': [], 'onkeypress': [], 'onclick': [], 'title': [], 'class': []}
+\ ],
+\ 'dt': [
+\ ['a', 'br', 'span', 'bdo', 'object', 'applet', 'img', 'map', 'iframe', 'tt', 'i', 'b', 'u', 's', 'strike', 'big', 'small', 'font', 'basefont', 'em', 'strong', 'dfn', 'code', 'q', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'sub', 'sup', 'input', 'select', 'textarea', 'label', 'button', 'ins', 'del', 'script'],
+\ { 'ondblclick': [], 'dir': ['ltr', 'rtl'], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'style': [], 'onmousemove': [], 'onmouseout': [], 'xml:lang': [], 'onmousedown': [], 'onkeypress': [], 'onclick': [], 'title': [], 'class': []}
+\ ],
+\ 'em': [
+\ ['a', 'br', 'span', 'bdo', 'object', 'applet', 'img', 'map', 'iframe', 'tt', 'i', 'b', 'u', 's', 'strike', 'big', 'small', 'font', 'basefont', 'em', 'strong', 'dfn', 'code', 'q', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'sub', 'sup', 'input', 'select', 'textarea', 'label', 'button', 'ins', 'del', 'script'],
+\ { 'ondblclick': [], 'dir': ['ltr', 'rtl'], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'style': [], 'onmousemove': [], 'onmouseout': [], 'xml:lang': [], 'onmousedown': [], 'onkeypress': [], 'onclick': [], 'title': [], 'class': []}
+\ ],
+\ 'fieldset': [
+\ ['legend', 'p', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'div', 'ul', 'ol', 'dl', 'menu', 'dir', 'pre', 'hr', 'blockquote', 'address', 'center', 'noframes', 'isindex', 'fieldset', 'table', 'form', 'a', 'br', 'span', 'bdo', 'object', 'applet', 'img', 'map', 'iframe', 'tt', 'i', 'b', 'u', 's', 'strike', 'big', 'small', 'font', 'basefont', 'em', 'strong', 'dfn', 'code', 'q', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'sub', 'sup', 'input', 'select', 'textarea', 'label', 'button', 'noscript', 'ins', 'del', 'script'],
+\ { 'ondblclick': [], 'dir': ['ltr', 'rtl'], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'style': [], 'onmousemove': [], 'onmouseout': [], 'xml:lang': [], 'onmousedown': [], 'onkeypress': [], 'onclick': [], 'title': [], 'class': []}
+\ ],
+\ 'font': [
+\ ['a', 'br', 'span', 'bdo', 'object', 'applet', 'img', 'map', 'iframe', 'tt', 'i', 'b', 'u', 's', 'strike', 'big', 'small', 'font', 'basefont', 'em', 'strong', 'dfn', 'code', 'q', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'sub', 'sup', 'input', 'select', 'textarea', 'label', 'button', 'ins', 'del', 'script'],
+\ { 'dir': ['ltr', 'rtl'], 'size': [], 'face': [], 'color': [], 'id': [], 'lang': [], 'style': [], 'xml:lang': [], 'title': [], 'class': []}
+\ ],
+\ 'form': [
+\ ['p', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'div', 'ul', 'ol', 'dl', 'menu', 'dir', 'pre', 'hr', 'blockquote', 'address', 'center', 'noframes', 'isindex', 'fieldset', 'table', 'a', 'br', 'span', 'bdo', 'object', 'applet', 'img', 'map', 'iframe', 'tt', 'i', 'b', 'u', 's', 'strike', 'big', 'small', 'font', 'basefont', 'em', 'strong', 'dfn', 'code', 'q', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'sub', 'sup', 'input', 'select', 'textarea', 'label', 'button', 'noscript', 'ins', 'del', 'script'],
+\ { 'enctype': ['application/x-www-form-urlencoded'], 'onsubmit': [], 'ondblclick': [], 'dir': ['ltr', 'rtl'], 'onkeydown': [], 'target': [], 'onkeyup': [], 'onmouseup': [], 'onreset': [], 'id': [], 'method': ['get', 'post'], 'onmouseover': [], 'lang': [], 'accept': [], 'onmouseout': [], 'onmousemove': [], 'style': [], 'name': [], 'xml:lang': [], 'accept-charset': [], 'onkeypress': [], 'onmousedown': [], 'action': [], 'class': [], 'title': [], 'onclick': []}
+\ ],
+\ 'h1': [
+\ ['a', 'br', 'span', 'bdo', 'object', 'applet', 'img', 'map', 'iframe', 'tt', 'i', 'b', 'u', 's', 'strike', 'big', 'small', 'font', 'basefont', 'em', 'strong', 'dfn', 'code', 'q', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'sub', 'sup', 'input', 'select', 'textarea', 'label', 'button', 'ins', 'del', 'script'],
+\ { 'ondblclick': [], 'dir': ['ltr', 'rtl'], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'align': ['left', 'center', 'right', 'justify'], 'lang': [], 'onmouseout': [], 'onmousemove': [], 'style': [], 'xml:lang': [], 'onkeypress': [], 'onmousedown': [], 'class': [], 'title': [], 'onclick': []}
+\ ],
+\ 'h2': [
+\ ['a', 'br', 'span', 'bdo', 'object', 'applet', 'img', 'map', 'iframe', 'tt', 'i', 'b', 'u', 's', 'strike', 'big', 'small', 'font', 'basefont', 'em', 'strong', 'dfn', 'code', 'q', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'sub', 'sup', 'input', 'select', 'textarea', 'label', 'button', 'ins', 'del', 'script'],
+\ { 'ondblclick': [], 'dir': ['ltr', 'rtl'], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'align': ['left', 'center', 'right', 'justify'], 'lang': [], 'onmouseout': [], 'onmousemove': [], 'style': [], 'xml:lang': [], 'onkeypress': [], 'onmousedown': [], 'class': [], 'title': [], 'onclick': []}
+\ ],
+\ 'h3': [
+\ ['a', 'br', 'span', 'bdo', 'object', 'applet', 'img', 'map', 'iframe', 'tt', 'i', 'b', 'u', 's', 'strike', 'big', 'small', 'font', 'basefont', 'em', 'strong', 'dfn', 'code', 'q', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'sub', 'sup', 'input', 'select', 'textarea', 'label', 'button', 'ins', 'del', 'script'],
+\ { 'ondblclick': [], 'dir': ['ltr', 'rtl'], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'align': ['left', 'center', 'right', 'justify'], 'lang': [], 'onmouseout': [], 'onmousemove': [], 'style': [], 'xml:lang': [], 'onkeypress': [], 'onmousedown': [], 'class': [], 'title': [], 'onclick': []}
+\ ],
+\ 'h4': [
+\ ['a', 'br', 'span', 'bdo', 'object', 'applet', 'img', 'map', 'iframe', 'tt', 'i', 'b', 'u', 's', 'strike', 'big', 'small', 'font', 'basefont', 'em', 'strong', 'dfn', 'code', 'q', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'sub', 'sup', 'input', 'select', 'textarea', 'label', 'button', 'ins', 'del', 'script'],
+\ { 'ondblclick': [], 'dir': ['ltr', 'rtl'], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'align': ['left', 'center', 'right', 'justify'], 'lang': [], 'onmouseout': [], 'onmousemove': [], 'style': [], 'xml:lang': [], 'onkeypress': [], 'onmousedown': [], 'class': [], 'title': [], 'onclick': []}
+\ ],
+\ 'h5': [
+\ ['a', 'br', 'span', 'bdo', 'object', 'applet', 'img', 'map', 'iframe', 'tt', 'i', 'b', 'u', 's', 'strike', 'big', 'small', 'font', 'basefont', 'em', 'strong', 'dfn', 'code', 'q', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'sub', 'sup', 'input', 'select', 'textarea', 'label', 'button', 'ins', 'del', 'script'],
+\ { 'ondblclick': [], 'dir': ['ltr', 'rtl'], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'align': ['left', 'center', 'right', 'justify'], 'lang': [], 'onmouseout': [], 'onmousemove': [], 'style': [], 'xml:lang': [], 'onkeypress': [], 'onmousedown': [], 'class': [], 'title': [], 'onclick': []}
+\ ],
+\ 'h6': [
+\ ['a', 'br', 'span', 'bdo', 'object', 'applet', 'img', 'map', 'iframe', 'tt', 'i', 'b', 'u', 's', 'strike', 'big', 'small', 'font', 'basefont', 'em', 'strong', 'dfn', 'code', 'q', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'sub', 'sup', 'input', 'select', 'textarea', 'label', 'button', 'ins', 'del', 'script'],
+\ { 'ondblclick': [], 'dir': ['ltr', 'rtl'], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'align': ['left', 'center', 'right', 'justify'], 'lang': [], 'onmouseout': [], 'onmousemove': [], 'style': [], 'xml:lang': [], 'onkeypress': [], 'onmousedown': [], 'class': [], 'title': [], 'onclick': []}
+\ ],
+\ 'head': [
+\ ['script', 'style', 'meta', 'link', 'object', 'isindex', 'title', 'script', 'style', 'meta', 'link', 'object', 'isindex', 'base', 'script', 'style', 'meta', 'link', 'object', 'isindex', 'base', 'script', 'style', 'meta', 'link', 'object', 'isindex', 'title', 'script', 'style', 'meta', 'link', 'object', 'isindex'],
+\ { 'profile': [], 'dir': ['ltr', 'rtl'], 'id': [], 'lang': [], 'xml:lang': []}
+\ ],
+\ 'hr': [
+\ [],
+\ { 'width': [], 'ondblclick': [], 'dir': ['ltr', 'rtl'], 'size': [], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'align': ['left', 'center', 'right'], 'lang': [], 'onmouseout': [], 'onmousemove': [], 'style': [], 'xml:lang': [], 'noshade': ['BOOL'], 'onkeypress': [], 'onmousedown': [], 'class': [], 'title': [], 'onclick': []}
+\ ],
+\ 'html': [
+\ ['head', 'body'],
+\ { 'xmlns': ['http://www.w3.org/1999/xhtml'], 'dir': ['ltr', 'rtl'], 'id': [], 'lang': [], 'xml:lang': []}
+\ ],
+\ 'i': [
+\ ['a', 'br', 'span', 'bdo', 'object', 'applet', 'img', 'map', 'iframe', 'tt', 'i', 'b', 'u', 's', 'strike', 'big', 'small', 'font', 'basefont', 'em', 'strong', 'dfn', 'code', 'q', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'sub', 'sup', 'input', 'select', 'textarea', 'label', 'button', 'ins', 'del', 'script'],
+\ { 'ondblclick': [], 'dir': ['ltr', 'rtl'], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'style': [], 'onmousemove': [], 'onmouseout': [], 'xml:lang': [], 'onmousedown': [], 'onkeypress': [], 'onclick': [], 'title': [], 'class': []}
+\ ],
+\ 'iframe': [
+\ ['p', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'div', 'ul', 'ol', 'dl', 'menu', 'dir', 'pre', 'hr', 'blockquote', 'address', 'center', 'noframes', 'isindex', 'fieldset', 'table', 'form', 'a', 'br', 'span', 'bdo', 'object', 'applet', 'img', 'map', 'iframe', 'tt', 'i', 'b', 'u', 's', 'strike', 'big', 'small', 'font', 'basefont', 'em', 'strong', 'dfn', 'code', 'q', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'sub', 'sup', 'input', 'select', 'textarea', 'label', 'button', 'noscript', 'ins', 'del', 'script'],
+\ { 'width': [], 'scrolling': ['auto', 'yes', 'no', 'auto'], 'marginwidth': [], 'id': [], 'marginheight': [], 'align': ['top', 'middle', 'bottom', 'left', 'right'], 'longdesc': [], 'src': [], 'style': [], 'name': [], 'height': [], 'frameborder': ['1', '0'], 'title': [], 'class': []}
+\ ],
+\ 'img': [
+\ [],
+\ { 'width': [], 'usemap': [], 'ismap': ['BOOL'], 'ondblclick': [], 'dir': ['ltr', 'rtl'], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'vspace': [], 'onmouseover': [], 'alt': [], 'lang': [], 'align': ['top', 'middle', 'bottom', 'left', 'right'], 'src': [], 'longdesc': [], 'onmouseout': [], 'onmousemove': [], 'style': [], 'name': [], 'xml:lang': [], 'height': [], 'border': [], 'hspace': [], 'onkeypress': [], 'onmousedown': [], 'class': [], 'title': [], 'onclick': []}
+\ ],
+\ 'input': [
+\ [],
+\ { 'ondblclick': [], 'onkeydown': [], 'readonly': ['BOOL'], 'onchange': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'align': ['top', 'middle', 'bottom', 'left', 'right'], 'value': [], 'src': [], 'name': [], 'checked': ['BOOL'], 'onkeypress': [], 'onmousedown': [], 'class': [], 'title': [], 'onclick': [], 'type': ['text', 'password', 'checkbox', 'radio', 'submit', 'reset', 'file', 'hidden', 'image', 'button'], 'accesskey': [], 'disabled': ['BOOL'], 'usemap': [], 'dir': ['ltr', 'rtl'], 'onblur': [], 'size': [], 'onfocus': [], 'maxlength': [], 'onselect': [], 'accept': [], 'tabindex': [], 'alt': [], 'style': [], 'onmousemove': [], 'onmouseout': [], 'xml:lang': []}
+\ ],
+\ 'ins': [
+\ ['p', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'div', 'ul', 'ol', 'dl', 'menu', 'dir', 'pre', 'hr', 'blockquote', 'address', 'center', 'noframes', 'isindex', 'fieldset', 'table', 'form', 'a', 'br', 'span', 'bdo', 'object', 'applet', 'img', 'map', 'iframe', 'tt', 'i', 'b', 'u', 's', 'strike', 'big', 'small', 'font', 'basefont', 'em', 'strong', 'dfn', 'code', 'q', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'sub', 'sup', 'input', 'select', 'textarea', 'label', 'button', 'noscript', 'ins', 'del', 'script'],
+\ { 'ondblclick': [], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'onkeypress': [], 'onmousedown': [], 'class': [], 'title': [], 'onclick': [], 'dir': ['ltr', 'rtl'], 'datetime': [], 'cite': [], 'onmouseout': [], 'onmousemove': [], 'style': [], 'xml:lang': []}
+\ ],
+\ 'isindex': [
+\ [],
+\ { 'id': [], 'lang': [], 'prompt': [], 'title': [], 'class': [], 'dir': ['ltr', 'rtl'], 'style': [], 'xml:lang': []}
+\ ],
+\ 'kbd': [
+\ ['a', 'br', 'span', 'bdo', 'object', 'applet', 'img', 'map', 'iframe', 'tt', 'i', 'b', 'u', 's', 'strike', 'big', 'small', 'font', 'basefont', 'em', 'strong', 'dfn', 'code', 'q', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'sub', 'sup', 'input', 'select', 'textarea', 'label', 'button', 'ins', 'del', 'script'],
+\ { 'ondblclick': [], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'onmousedown': [], 'onkeypress': [], 'onclick': [], 'title': [], 'class': [], 'dir': ['ltr', 'rtl'], 'style': [], 'onmousemove': [], 'onmouseout': [], 'xml:lang': []}
+\ ],
+\ 'label': [
+\ ['a', 'br', 'span', 'bdo', 'object', 'applet', 'img', 'map', 'iframe', 'tt', 'i', 'b', 'u', 's', 'strike', 'big', 'small', 'font', 'basefont', 'em', 'strong', 'dfn', 'code', 'q', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'sub', 'sup', 'input', 'select', 'textarea', 'label', 'button', 'ins', 'del', 'script'],
+\ { 'ondblclick': [], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'for': [], 'onkeypress': [], 'onmousedown': [], 'class': [], 'title': [], 'onclick': [], 'accesskey': [], 'dir': ['ltr', 'rtl'], 'onblur': [], 'onfocus': [], 'onmouseout': [], 'onmousemove': [], 'style': [], 'xml:lang': []}
+\ ],
+\ 'legend': [
+\ ['a', 'br', 'span', 'bdo', 'object', 'applet', 'img', 'map', 'iframe', 'tt', 'i', 'b', 'u', 's', 'strike', 'big', 'small', 'font', 'basefont', 'em', 'strong', 'dfn', 'code', 'q', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'sub', 'sup', 'input', 'select', 'textarea', 'label', 'button', 'ins', 'del', 'script'],
+\ { 'ondblclick': [], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'align': ['top', 'bottom', 'left', 'right'], 'lang': [], 'onkeypress': [], 'onmousedown': [], 'class': [], 'title': [], 'onclick': [], 'accesskey': [], 'dir': ['ltr', 'rtl'], 'onmouseout': [], 'onmousemove': [], 'style': [], 'xml:lang': []}
+\ ],
+\ 'li': [
+\ ['p', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'div', 'ul', 'ol', 'dl', 'menu', 'dir', 'pre', 'hr', 'blockquote', 'address', 'center', 'noframes', 'isindex', 'fieldset', 'table', 'form', 'a', 'br', 'span', 'bdo', 'object', 'applet', 'img', 'map', 'iframe', 'tt', 'i', 'b', 'u', 's', 'strike', 'big', 'small', 'font', 'basefont', 'em', 'strong', 'dfn', 'code', 'q', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'sub', 'sup', 'input', 'select', 'textarea', 'label', 'button', 'noscript', 'ins', 'del', 'script'],
+\ { 'ondblclick': [], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'value': [], 'onkeypress': [], 'onmousedown': [], 'type': [], 'class': [], 'title': [], 'onclick': [], 'dir': ['ltr', 'rtl'], 'onmouseout': [], 'onmousemove': [], 'style': [], 'xml:lang': []}
+\ ],
+\ 'link': [
+\ [],
+\ { 'rel': [], 'ondblclick': [], 'onkeydown': [], 'target': [], 'onkeyup': [], 'href': [], 'media': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'charset': [], 'hreflang': [], 'onkeypress': [], 'onmousedown': [], 'rev': [], 'class': [], 'title': [], 'onclick': [], 'type': [], 'dir': ['ltr', 'rtl'], 'onmouseout': [], 'onmousemove': [], 'style': [], 'xml:lang': []}
+\ ],
+\ 'map': [
+\ ['p', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'div', 'ul', 'ol', 'dl', 'menu', 'dir', 'pre', 'hr', 'blockquote', 'address', 'center', 'noframes', 'isindex', 'fieldset', 'table', 'form', 'noscript', 'ins', 'del', 'script', 'area'],
+\ { 'ondblclick': [], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'name': [], 'onkeypress': [], 'onmousedown': [], 'class': [], 'onclick': [], 'title': [], 'dir': ['ltr', 'rtl'], 'style': [], 'onmouseout': [], 'onmousemove': [], 'xml:lang': []}
+\ ],
+\ 'menu': [
+\ ['li'],
+\ { 'ondblclick': [], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'compact': ['BOOL'], 'onmouseover': [], 'lang': [], 'onmousedown': [], 'onkeypress': [], 'onclick': [], 'title': [], 'class': [], 'dir': ['ltr', 'rtl'], 'style': [], 'onmousemove': [], 'onmouseout': [], 'xml:lang': []}
+\ ],
+\ 'meta': [
+\ [],
+\ { 'http-equiv': [], 'content': [], 'id': [], 'lang': [], 'name': [], 'scheme': [], 'dir': ['ltr', 'rtl'], 'xml:lang': []}
+\ ],
+\ 'noframes': [
+\ ['p', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'div', 'ul', 'ol', 'dl', 'menu', 'dir', 'pre', 'hr', 'blockquote', 'address', 'center', 'noframes', 'isindex', 'fieldset', 'table', 'form', 'a', 'br', 'span', 'bdo', 'object', 'applet', 'img', 'map', 'iframe', 'tt', 'i', 'b', 'u', 's', 'strike', 'big', 'small', 'font', 'basefont', 'em', 'strong', 'dfn', 'code', 'q', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'sub', 'sup', 'input', 'select', 'textarea', 'label', 'button', 'noscript', 'ins', 'del', 'script'],
+\ { 'ondblclick': [], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'onmousedown': [], 'onkeypress': [], 'onclick': [], 'title': [], 'class': [], 'dir': ['ltr', 'rtl'], 'style': [], 'onmousemove': [], 'onmouseout': [], 'xml:lang': []}
+\ ],
+\ 'noscript': [
+\ ['p', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'div', 'ul', 'ol', 'dl', 'menu', 'dir', 'pre', 'hr', 'blockquote', 'address', 'center', 'noframes', 'isindex', 'fieldset', 'table', 'form', 'a', 'br', 'span', 'bdo', 'object', 'applet', 'img', 'map', 'iframe', 'tt', 'i', 'b', 'u', 's', 'strike', 'big', 'small', 'font', 'basefont', 'em', 'strong', 'dfn', 'code', 'q', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'sub', 'sup', 'input', 'select', 'textarea', 'label', 'button', 'noscript', 'ins', 'del', 'script'],
+\ { 'ondblclick': [], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'onmousedown': [], 'onkeypress': [], 'onclick': [], 'title': [], 'class': [], 'dir': ['ltr', 'rtl'], 'style': [], 'onmousemove': [], 'onmouseout': [], 'xml:lang': []}
+\ ],
+\ 'object': [
+\ ['param', 'p', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'div', 'ul', 'ol', 'dl', 'menu', 'dir', 'pre', 'hr', 'blockquote', 'address', 'center', 'noframes', 'isindex', 'fieldset', 'table', 'form', 'a', 'br', 'span', 'bdo', 'object', 'applet', 'img', 'map', 'iframe', 'tt', 'i', 'b', 'u', 's', 'strike', 'big', 'small', 'font', 'basefont', 'em', 'strong', 'dfn', 'code', 'q', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'sub', 'sup', 'input', 'select', 'textarea', 'label', 'button', 'noscript', 'ins', 'del', 'script'],
+\ { 'ondblclick': [], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'align': ['top', 'middle', 'bottom', 'left', 'right'], 'name': [], 'data': [], 'declare': ['BOOL'], 'onkeypress': [], 'onmousedown': [], 'class': [], 'title': [], 'onclick': [], 'type': [], 'width': [], 'usemap': [], 'dir': ['ltr', 'rtl'], 'vspace': [], 'tabindex': [], 'standby': [], 'archive': [], 'classid': [], 'style': [], 'onmousemove': [], 'onmouseout': [], 'height': [], 'xml:lang': [], 'border': [], 'codetype': [], 'hspace': [], 'codebase': []}
+\ ],
+\ 'ol': [
+\ ['li'],
+\ { 'ondblclick': [], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'compact': ['BOOL'], 'onmouseover': [], 'lang': [], 'onkeypress': [], 'onmousedown': [], 'type': [], 'class': [], 'title': [], 'onclick': [], 'start': [], 'dir': ['ltr', 'rtl'], 'onmouseout': [], 'onmousemove': [], 'style': [], 'xml:lang': []}
+\ ],
+\ 'optgroup': [
+\ ['option'],
+\ { 'ondblclick': [], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'onkeypress': [], 'onmousedown': [], 'class': [], 'title': [], 'onclick': [], 'label': [], 'disabled': ['BOOL'], 'dir': ['ltr', 'rtl'], 'onmouseout': [], 'onmousemove': [], 'style': [], 'xml:lang': []}
+\ ],
+\ 'option': [
+\ [''],
+\ { 'ondblclick': [], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'value': [], 'onkeypress': [], 'onmousedown': [], 'class': [], 'title': [], 'onclick': [], 'label': [], 'disabled': ['BOOL'], 'dir': ['ltr', 'rtl'], 'onmouseout': [], 'onmousemove': [], 'style': [], 'xml:lang': [], 'selected': ['BOOL']}
+\ ],
+\ 'p': [
+\ ['a', 'br', 'span', 'bdo', 'object', 'applet', 'img', 'map', 'iframe', 'tt', 'i', 'b', 'u', 's', 'strike', 'big', 'small', 'font', 'basefont', 'em', 'strong', 'dfn', 'code', 'q', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'sub', 'sup', 'input', 'select', 'textarea', 'label', 'button', 'ins', 'del', 'script'],
+\ { 'ondblclick': [], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'align': ['left', 'center', 'right', 'justify'], 'lang': [], 'onkeypress': [], 'onmousedown': [], 'class': [], 'title': [], 'onclick': [], 'dir': ['ltr', 'rtl'], 'onmouseout': [], 'onmousemove': [], 'style': [], 'xml:lang': []}
+\ ],
+\ 'param': [
+\ [],
+\ { 'id': [], 'value': [], 'name': [], 'type': [], 'valuetype': ['data', 'ref', 'object']}
+\ ],
+\ 'pre': [
+\ ['a', 'br', 'span', 'bdo', 'tt', 'i', 'b', 'u', 's', 'strike', 'em', 'strong', 'dfn', 'code', 'q', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'input', 'select', 'textarea', 'label', 'button', 'ins', 'del', 'script'],
+\ { 'ondblclick': [], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'xml:space': ['preserve'], 'onkeypress': [], 'onmousedown': [], 'class': [], 'title': [], 'onclick': [], 'width': [], 'dir': ['ltr', 'rtl'], 'onmouseout': [], 'onmousemove': [], 'style': [], 'xml:lang': []}
+\ ],
+\ 'q': [
+\ ['a', 'br', 'span', 'bdo', 'object', 'applet', 'img', 'map', 'iframe', 'tt', 'i', 'b', 'u', 's', 'strike', 'big', 'small', 'font', 'basefont', 'em', 'strong', 'dfn', 'code', 'q', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'sub', 'sup', 'input', 'select', 'textarea', 'label', 'button', 'ins', 'del', 'script'],
+\ { 'ondblclick': [], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'onmousedown': [], 'onkeypress': [], 'onclick': [], 'title': [], 'class': [], 'dir': ['ltr', 'rtl'], 'cite': [], 'style': [], 'onmousemove': [], 'onmouseout': [], 'xml:lang': []}
+\ ],
+\ 's': [
+\ ['a', 'br', 'span', 'bdo', 'object', 'applet', 'img', 'map', 'iframe', 'tt', 'i', 'b', 'u', 's', 'strike', 'big', 'small', 'font', 'basefont', 'em', 'strong', 'dfn', 'code', 'q', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'sub', 'sup', 'input', 'select', 'textarea', 'label', 'button', 'ins', 'del', 'script'],
+\ { 'ondblclick': [], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'onmousedown': [], 'onkeypress': [], 'onclick': [], 'title': [], 'class': [], 'dir': ['ltr', 'rtl'], 'style': [], 'onmousemove': [], 'onmouseout': [], 'xml:lang': []}
+\ ],
+\ 'samp': [
+\ ['a', 'br', 'span', 'bdo', 'object', 'applet', 'img', 'map', 'iframe', 'tt', 'i', 'b', 'u', 's', 'strike', 'big', 'small', 'font', 'basefont', 'em', 'strong', 'dfn', 'code', 'q', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'sub', 'sup', 'input', 'select', 'textarea', 'label', 'button', 'ins', 'del', 'script'],
+\ { 'ondblclick': [], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'onmousedown': [], 'onkeypress': [], 'onclick': [], 'title': [], 'class': [], 'dir': ['ltr', 'rtl'], 'style': [], 'onmousemove': [], 'onmouseout': [], 'xml:lang': []}
+\ ],
+\ 'script': [
+\ [''],
+\ { 'id': [], 'src': [], 'charset': [], 'xml:space': ['preserve'], 'type': ['text/javascript'], 'defer': ['BOOL'], 'language': []}
+\ ],
+\ 'select': [
+\ ['optgroup', 'option'],
+\ { 'ondblclick': [], 'onkeydown': [], 'onchange': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'name': [], 'onkeypress': [], 'onmousedown': [], 'class': [], 'title': [], 'onclick': [], 'disabled': ['BOOL'], 'dir': ['ltr', 'rtl'], 'size': [], 'onblur': [], 'onfocus': [], 'tabindex': [], 'onmouseout': [], 'onmousemove': [], 'style': [], 'xml:lang': [], 'multiple': ['BOOL']}
+\ ],
+\ 'small': [
+\ ['a', 'br', 'span', 'bdo', 'object', 'applet', 'img', 'map', 'iframe', 'tt', 'i', 'b', 'u', 's', 'strike', 'big', 'small', 'font', 'basefont', 'em', 'strong', 'dfn', 'code', 'q', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'sub', 'sup', 'input', 'select', 'textarea', 'label', 'button', 'ins', 'del', 'script'],
+\ { 'ondblclick': [], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'onmousedown': [], 'onkeypress': [], 'onclick': [], 'title': [], 'class': [], 'dir': ['ltr', 'rtl'], 'style': [], 'onmousemove': [], 'onmouseout': [], 'xml:lang': []}
+\ ],
+\ 'span': [
+\ ['a', 'br', 'span', 'bdo', 'object', 'applet', 'img', 'map', 'iframe', 'tt', 'i', 'b', 'u', 's', 'strike', 'big', 'small', 'font', 'basefont', 'em', 'strong', 'dfn', 'code', 'q', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'sub', 'sup', 'input', 'select', 'textarea', 'label', 'button', 'ins', 'del', 'script'],
+\ { 'ondblclick': [], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'onmousedown': [], 'onkeypress': [], 'onclick': [], 'title': [], 'class': [], 'dir': ['ltr', 'rtl'], 'style': [], 'onmousemove': [], 'onmouseout': [], 'xml:lang': []}
+\ ],
+\ 'strike': [
+\ ['a', 'br', 'span', 'bdo', 'object', 'applet', 'img', 'map', 'iframe', 'tt', 'i', 'b', 'u', 's', 'strike', 'big', 'small', 'font', 'basefont', 'em', 'strong', 'dfn', 'code', 'q', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'sub', 'sup', 'input', 'select', 'textarea', 'label', 'button', 'ins', 'del', 'script'],
+\ { 'ondblclick': [], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'onmousedown': [], 'onkeypress': [], 'onclick': [], 'title': [], 'class': [], 'dir': ['ltr', 'rtl'], 'style': [], 'onmousemove': [], 'onmouseout': [], 'xml:lang': []}
+\ ],
+\ 'strong': [
+\ ['a', 'br', 'span', 'bdo', 'object', 'applet', 'img', 'map', 'iframe', 'tt', 'i', 'b', 'u', 's', 'strike', 'big', 'small', 'font', 'basefont', 'em', 'strong', 'dfn', 'code', 'q', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'sub', 'sup', 'input', 'select', 'textarea', 'label', 'button', 'ins', 'del', 'script'],
+\ { 'ondblclick': [], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'onmousedown': [], 'onkeypress': [], 'onclick': [], 'title': [], 'class': [], 'dir': ['ltr', 'rtl'], 'style': [], 'onmousemove': [], 'onmouseout': [], 'xml:lang': []}
+\ ],
+\ 'style': [
+\ [''],
+\ { 'media': [], 'id': [], 'lang': [], 'xml:space': ['preserve'], 'title': [], 'type': ['text/css'], 'dir': ['ltr', 'rtl'], 'xml:lang': []}
+\ ],
+\ 'sub': [
+\ ['a', 'br', 'span', 'bdo', 'object', 'applet', 'img', 'map', 'iframe', 'tt', 'i', 'b', 'u', 's', 'strike', 'big', 'small', 'font', 'basefont', 'em', 'strong', 'dfn', 'code', 'q', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'sub', 'sup', 'input', 'select', 'textarea', 'label', 'button', 'ins', 'del', 'script'],
+\ { 'ondblclick': [], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'onmousedown': [], 'onkeypress': [], 'onclick': [], 'title': [], 'class': [], 'dir': ['ltr', 'rtl'], 'style': [], 'onmousemove': [], 'onmouseout': [], 'xml:lang': []}
+\ ],
+\ 'sup': [
+\ ['a', 'br', 'span', 'bdo', 'object', 'applet', 'img', 'map', 'iframe', 'tt', 'i', 'b', 'u', 's', 'strike', 'big', 'small', 'font', 'basefont', 'em', 'strong', 'dfn', 'code', 'q', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'sub', 'sup', 'input', 'select', 'textarea', 'label', 'button', 'ins', 'del', 'script'],
+\ { 'ondblclick': [], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'onmousedown': [], 'onkeypress': [], 'onclick': [], 'title': [], 'class': [], 'dir': ['ltr', 'rtl'], 'style': [], 'onmousemove': [], 'onmouseout': [], 'xml:lang': []}
+\ ],
+\ 'table': [
+\ ['caption', 'col', 'colgroup', 'thead', 'tfoot', 'tbody', 'tr'],
+\ { 'ondblclick': [], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'align': ['left', 'center', 'right'], 'onkeypress': [], 'onmousedown': [], 'class': [], 'title': [], 'onclick': [], 'width': [], 'frame': ['void', 'above', 'below', 'hsides', 'lhs', 'rhs', 'vsides', 'box', 'border'], 'rules': ['none', 'groups', 'rows', 'cols', 'all'], 'dir': ['ltr', 'rtl'], 'summary': [], 'bgcolor': [], 'cellspacing': [], 'onmouseout': [], 'onmousemove': [], 'style': [], 'xml:lang': [], 'border': [], 'cellpadding': []}
+\ ],
+\ 'tbody': [
+\ ['tr'],
+\ { 'ondblclick': [], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'align': ['left', 'center', 'right', 'justify', 'char'], 'lang': [], 'valign': ['top', 'middle', 'bottom', 'baseline'], 'onkeypress': [], 'onmousedown': [], 'class': [], 'title': [], 'onclick': [], 'dir': ['ltr', 'rtl'], 'charoff': [], 'onmouseout': [], 'onmousemove': [], 'style': [], 'xml:lang': [], 'char': []}
+\ ],
+\ 'td': [
+\ ['p', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'div', 'ul', 'ol', 'dl', 'menu', 'dir', 'pre', 'hr', 'blockquote', 'address', 'center', 'noframes', 'isindex', 'fieldset', 'table', 'form', 'a', 'br', 'span', 'bdo', 'object', 'applet', 'img', 'map', 'iframe', 'tt', 'i', 'b', 'u', 's', 'strike', 'big', 'small', 'font', 'basefont', 'em', 'strong', 'dfn', 'code', 'q', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'sub', 'sup', 'input', 'select', 'textarea', 'label', 'button', 'noscript', 'ins', 'del', 'script'],
+\ { 'ondblclick': [], 'axis': [], 'onkeydown': [], 'abbr': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'scope': ['row', 'col', 'rowgroup', 'colgroup'], 'onmouseover': [], 'lang': [], 'align': ['left', 'center', 'right', 'justify', 'char'], 'valign': ['top', 'middle', 'bottom', 'baseline'], 'onkeypress': [], 'onmousedown': [], 'class': [], 'title': [], 'onclick': [], 'width': [], 'headers': [], 'nowrap': ['BOOL'], 'dir': ['ltr', 'rtl'], 'rowspan': ['1'], 'colspan': ['1'], 'bgcolor': [], 'charoff': [], 'onmouseout': [], 'onmousemove': [], 'style': [], 'xml:lang': [], 'height': [], 'char': []}
+\ ],
+\ 'textarea': [
+\ [''],
+\ { 'ondblclick': [], 'cols': [], 'onkeydown': [], 'readonly': ['BOOL'], 'onchange': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'name': [], 'onkeypress': [], 'onmousedown': [], 'class': [], 'title': [], 'onclick': [], 'accesskey': [], 'disabled': ['BOOL'], 'rows': [], 'dir': ['ltr', 'rtl'], 'onblur': [], 'onfocus': [], 'onselect': [], 'tabindex': [], 'onmouseout': [], 'onmousemove': [], 'style': [], 'xml:lang': []}
+\ ],
+\ 'tfoot': [
+\ ['tr'],
+\ { 'ondblclick': [], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'align': ['left', 'center', 'right', 'justify', 'char'], 'lang': [], 'valign': ['top', 'middle', 'bottom', 'baseline'], 'onkeypress': [], 'onmousedown': [], 'class': [], 'title': [], 'onclick': [], 'dir': ['ltr', 'rtl'], 'charoff': [], 'onmouseout': [], 'onmousemove': [], 'style': [], 'xml:lang': [], 'char': []}
+\ ],
+\ 'th': [
+\ ['p', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'div', 'ul', 'ol', 'dl', 'menu', 'dir', 'pre', 'hr', 'blockquote', 'address', 'center', 'noframes', 'isindex', 'fieldset', 'table', 'form', 'a', 'br', 'span', 'bdo', 'object', 'applet', 'img', 'map', 'iframe', 'tt', 'i', 'b', 'u', 's', 'strike', 'big', 'small', 'font', 'basefont', 'em', 'strong', 'dfn', 'code', 'q', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'sub', 'sup', 'input', 'select', 'textarea', 'label', 'button', 'noscript', 'ins', 'del', 'script'],
+\ { 'ondblclick': [], 'axis': [], 'onkeydown': [], 'abbr': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'scope': ['row', 'col', 'rowgroup', 'colgroup'], 'onmouseover': [], 'lang': [], 'align': ['left', 'center', 'right', 'justify', 'char'], 'valign': ['top', 'middle', 'bottom', 'baseline'], 'onkeypress': [], 'onmousedown': [], 'class': [], 'title': [], 'onclick': [], 'width': [], 'headers': [], 'nowrap': ['BOOL'], 'dir': ['ltr', 'rtl'], 'rowspan': ['1'], 'colspan': ['1'], 'bgcolor': [], 'charoff': [], 'onmouseout': [], 'onmousemove': [], 'style': [], 'xml:lang': [], 'height': [], 'char': []}
+\ ],
+\ 'thead': [
+\ ['tr'],
+\ { 'ondblclick': [], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'align': ['left', 'center', 'right', 'justify', 'char'], 'lang': [], 'valign': ['top', 'middle', 'bottom', 'baseline'], 'onkeypress': [], 'onmousedown': [], 'class': [], 'title': [], 'onclick': [], 'dir': ['ltr', 'rtl'], 'charoff': [], 'onmouseout': [], 'onmousemove': [], 'style': [], 'xml:lang': [], 'char': []}
+\ ],
+\ 'title': [
+\ [''],
+\ { 'id': [], 'lang': [], 'dir': ['ltr', 'rtl'], 'xml:lang': []}
+\ ],
+\ 'tr': [
+\ ['th', 'td'],
+\ { 'ondblclick': [], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'align': ['left', 'center', 'right', 'justify', 'char'], 'lang': [], 'valign': ['top', 'middle', 'bottom', 'baseline'], 'onkeypress': [], 'onmousedown': [], 'class': [], 'title': [], 'onclick': [], 'dir': ['ltr', 'rtl'], 'bgcolor': [], 'charoff': [], 'onmouseout': [], 'onmousemove': [], 'style': [], 'xml:lang': [], 'char': []}
+\ ],
+\ 'tt': [
+\ ['a', 'br', 'span', 'bdo', 'object', 'applet', 'img', 'map', 'iframe', 'tt', 'i', 'b', 'u', 's', 'strike', 'big', 'small', 'font', 'basefont', 'em', 'strong', 'dfn', 'code', 'q', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'sub', 'sup', 'input', 'select', 'textarea', 'label', 'button', 'ins', 'del', 'script'],
+\ { 'ondblclick': [], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'onmousedown': [], 'onkeypress': [], 'onclick': [], 'title': [], 'class': [], 'dir': ['ltr', 'rtl'], 'style': [], 'onmousemove': [], 'onmouseout': [], 'xml:lang': []}
+\ ],
+\ 'u': [
+\ ['a', 'br', 'span', 'bdo', 'object', 'applet', 'img', 'map', 'iframe', 'tt', 'i', 'b', 'u', 's', 'strike', 'big', 'small', 'font', 'basefont', 'em', 'strong', 'dfn', 'code', 'q', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'sub', 'sup', 'input', 'select', 'textarea', 'label', 'button', 'ins', 'del', 'script'],
+\ { 'ondblclick': [], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'onmousedown': [], 'onkeypress': [], 'onclick': [], 'title': [], 'class': [], 'dir': ['ltr', 'rtl'], 'style': [], 'onmousemove': [], 'onmouseout': [], 'xml:lang': []}
+\ ],
+\ 'ul': [
+\ ['li'],
+\ { 'ondblclick': [], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'compact': ['BOOL'], 'onmouseover': [], 'lang': [], 'onkeypress': [], 'onmousedown': [], 'type': ['disc', 'square', 'circle'], 'class': [], 'title': [], 'onclick': [], 'dir': ['ltr', 'rtl'], 'onmouseout': [], 'onmousemove': [], 'style': [], 'xml:lang': []}
+\ ],
+\ 'var': [
+\ ['a', 'br', 'span', 'bdo', 'object', 'applet', 'img', 'map', 'iframe', 'tt', 'i', 'b', 'u', 's', 'strike', 'big', 'small', 'font', 'basefont', 'em', 'strong', 'dfn', 'code', 'q', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'sub', 'sup', 'input', 'select', 'textarea', 'label', 'button', 'ins', 'del', 'script'],
+\ { 'ondblclick': [], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'lang': [], 'onmousedown': [], 'onkeypress': [], 'onclick': [], 'title': [], 'class': [], 'dir': ['ltr', 'rtl'], 'style': [], 'onmousemove': [], 'onmouseout': [], 'xml:lang': []}
+\ ],
+\ 'vimxmlattrinfo' : {
+\ 'accept' : ['ContentType', ''],
+\ 'accesskey' : ['Character', ''],
+\ 'action' : ['*URI', ''],
+\ 'align' : ['String', ''],
+\ 'alt' : ['*Text', ''],
+\ 'archive' : ['UriList', ''],
+\ 'axis' : ['CDATA', ''],
+\ 'border' : ['Pixels', ''],
+\ 'cellpadding' : ['Length', ''],
+\ 'cellspacing' : ['Length', ''],
+\ 'char' : ['Character', ''],
+\ 'charoff' : ['Length', ''],
+\ 'charset' : ['LangCode', ''],
+\ 'checked' : ['Bool', ''],
+\ 'class' : ['CDATA', ''],
+\ 'codetype' : ['ContentType', ''],
+\ 'cols' : ['*Number', ''],
+\ 'colspan' : ['Number', ''],
+\ 'content' : ['*CDATA', ''],
+\ 'coords' : ['Coords', ''],
+\ 'data' : ['URI', ''],
+\ 'datetime' : ['DateTime', ''],
+\ 'declare' : ['Bool', ''],
+\ 'defer' : ['Bool', ''],
+\ 'dir' : ['String', ''],
+\ 'disabled' : ['Bool', ''],
+\ 'enctype' : ['ContentType', ''],
+\ 'for' : ['ID', ''],
+\ 'headers' : ['IDREFS', ''],
+\ 'height' : ['Number', ''],
+\ 'href' : ['*URI', ''],
+\ 'hreflang' : ['LangCode', ''],
+\ 'id' : ['ID', ''],
+\ 'ismap' : ['Bool', ''],
+\ 'label' : ['*Text', ''],
+\ 'lang' : ['LangCode', ''],
+\ 'longdesc' : ['URI', ''],
+\ 'maxlength' : ['Number', ''],
+\ 'media' : ['MediaDesc', ''],
+\ 'method' : ['String', ''],
+\ 'multiple' : ['Bool', ''],
+\ 'name' : ['CDATA', ''],
+\ 'nohref' : ['Bool', ''],
+\ 'onblur' : ['Script', ''],
+\ 'onchange' : ['Script', ''],
+\ 'onclick' : ['Script', ''],
+\ 'ondblclick' : ['Script', ''],
+\ 'onfocus' : ['Script', ''],
+\ 'onkeydown' : ['Script', ''],
+\ 'onkeypress' : ['Script', ''],
+\ 'onkeyup' : ['Script', ''],
+\ 'onload' : ['Script', ''],
+\ 'onmousedown' : ['Script', ''],
+\ 'onmousemove' : ['Script', ''],
+\ 'onmouseout' : ['Script', ''],
+\ 'onmouseover' : ['Script', ''],
+\ 'onmouseup' : ['Script', ''],
+\ 'onreset' : ['Script', ''],
+\ 'onselect' : ['Script', ''],
+\ 'onsubmit' : ['Script', ''],
+\ 'onunload' : ['Script', ''],
+\ 'profile' : ['URI', ''],
+\ 'readonly' : ['Bool', ''],
+\ 'rel' : ['LinkTypes', ''],
+\ 'rev' : ['LinkTypes', ''],
+\ 'rows' : ['*Number', ''],
+\ 'rules' : ['String', ''],
+\ 'scheme' : ['CDATA', ''],
+\ 'selected' : ['Bool', ''],
+\ 'shape' : ['Shape', ''],
+\ 'size' : ['CDATA', ''],
+\ 'span' : ['Number', ''],
+\ 'src' : ['*URI', ''],
+\ 'standby' : ['Text', ''],
+\ 'style' : ['StyleSheet', ''],
+\ 'summary' : ['*Text', ''],
+\ 'tabindex' : ['Number', ''],
+\ 'title' : ['Text', ''],
+\ 'type' : ['*ContentType', ''],
+\ 'usemap' : ['URI', ''],
+\ 'valign' : ['String', ''],
+\ 'valuetype' : ['String', ''],
+\ 'width' : ['Number', ''],
+\ 'xmlns' : ['URI', '']
+\ },
+\ 'vimxmltaginfo': {
+\ 'area': ['/>', ''],
+\ 'base': ['/>', ''],
+\ 'basefont': ['/>', ''],
+\ 'br': ['/>', ''],
+\ 'col': ['/>', ''],
+\ 'hr': ['/>', ''],
+\ 'img': ['/>', ''],
+\ 'input': ['/>', ''],
+\ 'isindex': ['/>', ''],
+\ 'link': ['/>', ''],
+\ 'meta': ['/>', ''],
+\ 'param': ['/>', ''],
+\ }
+\ }
+" vim:ft=vim:ff=unix
--- /dev/null
+++ b/lib/vimfiles/autoload/xml/xhtml11.vim
@@ -1,0 +1,435 @@
+let g:xmldata_xhtml11 = {
+\ 'vimxmlentities': ['AElig', 'Aacute', 'Acirc', 'Agrave', 'Alpha', 'Aring', 'Atilde', 'Auml', 'Beta', 'Ccedil', 'Chi', 'Dagger', 'Delta', 'ETH', 'Eacute', 'Ecirc', 'Egrave', 'Epsilon', 'Eta', 'Euml', 'Gamma', 'Iacute', 'Icirc', 'Igrave', 'Iota', 'Iuml', 'Kappa', 'Lambda', 'Mu', 'Ntilde', 'Nu', 'OElig', 'Oacute', 'Ocirc', 'Ograve', 'Omega', 'Omicron', 'Oslash', 'Otilde', 'Ouml', 'Phi', 'Pi', 'Prime', 'Psi', 'Rho', 'Scaron', 'Sigma', 'THORN', 'Tau', 'Theta', 'Uacute', 'Ucirc', 'Ugrave', 'Upsilon', 'Uuml', 'Xi', 'Yacute', 'Yuml', 'Zeta', 'aacute', 'acirc', 'acute', 'aelig', 'agrave', 'alefsym', 'alpha', 'amp', 'and', 'ang', 'apos', 'aring', 'asymp', 'atilde', 'auml', 'bdquo', 'beta', 'brvbar', 'bull', 'cap', 'ccedil', 'cedil', 'cent', 'chi', 'circ', 'clubs', 'cong', 'copy', 'crarr', 'cup', 'curren', 'dArr', 'dagger', 'darr', 'deg', 'delta', 'diams', 'divide', 'eacute', 'ecirc', 'egrave', 'empty', 'emsp', 'ensp', 'epsilon', 'equiv', 'eta', 'eth', 'euml', 'euro', 'exist', 'fnof', 'forall', 'frac12', 'frac14', 'frac34', 'frasl', 'gamma', 'ge', 'gt', 'hArr', 'harr', 'hearts', 'hellip', 'iacute', 'icirc', 'iexcl', 'igrave', 'image', 'infin', 'int', 'iota', 'iquest', 'isin', 'iuml', 'kappa', 'lArr', 'lambda', 'lang', 'laquo', 'larr', 'lceil', 'ldquo', 'le', 'lfloor', 'lowast', 'loz', 'lrm', 'lsaquo', 'lsquo', 'lt', 'macr', 'mdash', 'micro', 'middot', 'minus', 'mu', 'nabla', 'nbsp', 'ndash', 'ne', 'ni', 'not', 'notin', 'nsub', 'ntilde', 'nu', 'oacute', 'ocirc', 'oelig', 'ograve', 'oline', 'omega', 'omicron', 'oplus', 'or', 'ordf', 'ordm', 'oslash', 'otilde', 'otimes', 'ouml', 'para', 'part', 'permil', 'perp', 'phi', 'pi', 'piv', 'plusmn', 'pound', 'prime', 'prod', 'prop', 'psi', 'quot', 'rArr', 'radic', 'rang', 'raquo', 'rarr', 'rceil', 'rdquo', 'real', 'reg', 'rfloor', 'rho', 'rlm', 'rsaquo', 'rsquo', 'sbquo', 'scaron', 'sdot', 'sect', 'shy', 'sigma', 'sigmaf', 'sim', 'spades', 'sub', 'sube', 'sum', 'sup', 'sup1', 'sup2', 'sup3', 'supe', 'szlig', 'tau', 'there4', 'theta', 'thetasym', 'thinsp', 'thorn', 'tilde', 'times', 'trade', 'uArr', 'uacute', 'uarr', 'ucirc', 'ugrave', 'uml', 'upsih', 'upsilon', 'uuml', 'weierp', 'xi', 'yacute', 'yen', 'yuml', 'zeta', 'zwj', 'zwnj'],
+\ 'vimxmlroot': ['html'],
+\ 'a': [
+\ ['br', 'span', 'em', 'strong', 'dfn', 'code', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'q', 'tt', 'i', 'b', 'big', 'small', 'sub', 'sup', 'bdo', 'img', 'map', 'object', 'input', 'select', 'textarea', 'label', 'button', 'ruby', 'ins', 'del', 'script', 'noscript'],
+\ { 'coords': [], 'shape': ['rect', 'circle', 'poly', 'default']}
+\ ],
+\ 'abbr': [
+\ ['br', 'span', 'em', 'strong', 'dfn', 'code', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'q', 'tt', 'i', 'b', 'big', 'small', 'sub', 'sup', 'bdo', 'a', 'img', 'map', 'object', 'input', 'select', 'textarea', 'label', 'button', 'ruby', 'ins', 'del', 'script', 'noscript'],
+\ { 'xmlns': ['http://www.w3.org/1999/xhtml'], 'ondblclick': [], 'dir': ['ltr', 'rtl'], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'onmouseout': [], 'onmousemove': [], 'style': [], 'xml:lang': [], 'onkeypress': [], 'onmousedown': [], 'onclick': [], 'class': [], 'title': []}
+\ ],
+\ 'acronym': [
+\ ['br', 'span', 'em', 'strong', 'dfn', 'code', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'q', 'tt', 'i', 'b', 'big', 'small', 'sub', 'sup', 'bdo', 'a', 'img', 'map', 'object', 'input', 'select', 'textarea', 'label', 'button', 'ruby', 'ins', 'del', 'script', 'noscript'],
+\ { 'xmlns': ['http://www.w3.org/1999/xhtml'], 'ondblclick': [], 'dir': ['ltr', 'rtl'], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'style': [], 'onmousemove': [], 'onmouseout': [], 'xml:lang': [], 'onmousedown': [], 'onkeypress': [], 'onclick': [], 'title': [], 'class': []}
+\ ],
+\ 'address': [
+\ ['br', 'span', 'em', 'strong', 'dfn', 'code', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'q', 'tt', 'i', 'b', 'big', 'small', 'sub', 'sup', 'bdo', 'a', 'img', 'map', 'object', 'input', 'select', 'textarea', 'label', 'button', 'ruby', 'ins', 'del', 'script', 'noscript'],
+\ { 'xmlns': ['http://www.w3.org/1999/xhtml'], 'ondblclick': [], 'dir': ['ltr', 'rtl'], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'style': [], 'onmousemove': [], 'onmouseout': [], 'xml:lang': [], 'onmousedown': [], 'onkeypress': [], 'onclick': [], 'title': [], 'class': []}
+\ ],
+\ 'area': [
+\ [],
+\ { 'xmlns': ['http://www.w3.org/1999/xhtml'], 'accesskey': [], 'coords': [], 'ondblclick': [], 'dir': ['ltr', 'rtl'], 'onkeydown': [], 'nohref': ['BOOL'], 'onkeyup': [], 'href': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'alt': [], 'tabindex': [], 'onmouseout': [], 'onmousemove': [], 'style': [], 'xml:lang': [], 'onkeypress': [], 'onmousedown': [], 'class': [], 'title': [], 'onclick': [], 'shape': ['rect', 'circle', 'poly', 'default']}
+\ ],
+\ 'b': [
+\ ['br', 'span', 'em', 'strong', 'dfn', 'code', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'q', 'tt', 'i', 'b', 'big', 'small', 'sub', 'sup', 'bdo', 'a', 'img', 'map', 'object', 'input', 'select', 'textarea', 'label', 'button', 'ruby', 'ins', 'del', 'script', 'noscript'],
+\ { 'xmlns': ['http://www.w3.org/1999/xhtml'], 'ondblclick': [], 'dir': ['ltr', 'rtl'], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'style': [], 'onmousemove': [], 'onmouseout': [], 'xml:lang': [], 'onmousedown': [], 'onkeypress': [], 'onclick': [], 'title': [], 'class': []}
+\ ],
+\ 'base': [
+\ [],
+\ { 'xmlns': ['http://www.w3.org/1999/xhtml'], 'href': []}
+\ ],
+\ 'bdo': [
+\ ['br', 'span', 'em', 'strong', 'dfn', 'code', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'q', 'tt', 'i', 'b', 'big', 'small', 'sub', 'sup', 'bdo', 'a', 'img', 'map', 'object', 'input', 'select', 'textarea', 'label', 'button', 'ruby', 'ins', 'del', 'script', 'noscript'],
+\ { 'xmlns': ['http://www.w3.org/1999/xhtml'], 'dir': ['ltr', 'rtl'], 'id': [], 'style': [], 'xml:lang': [], 'class': [], 'title': []}
+\ ],
+\ 'big': [
+\ ['br', 'span', 'em', 'strong', 'dfn', 'code', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'q', 'tt', 'i', 'b', 'big', 'small', 'sub', 'sup', 'bdo', 'a', 'img', 'map', 'object', 'input', 'select', 'textarea', 'label', 'button', 'ruby', 'ins', 'del', 'script', 'noscript'],
+\ { 'xmlns': ['http://www.w3.org/1999/xhtml'], 'ondblclick': [], 'dir': ['ltr', 'rtl'], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'style': [], 'onmousemove': [], 'onmouseout': [], 'xml:lang': [], 'onmousedown': [], 'onkeypress': [], 'onclick': [], 'title': [], 'class': []}
+\ ],
+\ 'blockquote': [
+\ ['h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'ul', 'ol', 'dl', 'p', 'div', 'pre', 'blockquote', 'address', 'hr', 'table', 'form', 'fieldset', 'ins', 'del', 'script', 'noscript'],
+\ { 'xmlns': ['http://www.w3.org/1999/xhtml'], 'ondblclick': [], 'dir': ['ltr', 'rtl'], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'cite': [], 'onmouseover': [], 'style': [], 'onmousemove': [], 'onmouseout': [], 'xml:lang': [], 'onmousedown': [], 'onkeypress': [], 'onclick': [], 'title': [], 'class': []}
+\ ],
+\ 'body': [
+\ ['h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'ul', 'ol', 'dl', 'p', 'div', 'pre', 'blockquote', 'address', 'hr', 'table', 'form', 'fieldset', 'ins', 'del', 'script', 'noscript'],
+\ { 'xmlns': ['http://www.w3.org/1999/xhtml'], 'ondblclick': [], 'dir': ['ltr', 'rtl'], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'style': [], 'onmousemove': [], 'onmouseout': [], 'xml:lang': [], 'onmousedown': [], 'onkeypress': [], 'onclick': [], 'title': [], 'class': []}
+\ ],
+\ 'br': [
+\ [],
+\ { 'xmlns': ['http://www.w3.org/1999/xhtml'], 'id': [], 'style': [], 'class': [], 'title': []}
+\ ],
+\ 'button': [
+\ ['h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'ul', 'ol', 'dl', 'p', 'div', 'pre', 'blockquote', 'address', 'hr', 'table', 'ins', 'del', 'script', 'noscript', 'br', 'span', 'em', 'strong', 'dfn', 'code', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'q', 'tt', 'i', 'b', 'big', 'small', 'sub', 'sup', 'bdo', 'img', 'map', 'object'],
+\ { 'xmlns': ['http://www.w3.org/1999/xhtml'], 'accesskey': [], 'disabled': ['BOOL'], 'ondblclick': [], 'dir': ['ltr', 'rtl'], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'tabindex': [], 'value': [], 'name': [], 'onmouseout': [], 'onmousemove': [], 'style': [], 'xml:lang': [], 'onkeypress': [], 'onmousedown': [], 'class': [], 'title': [], 'onclick': [], 'type': ['submit', 'button', 'submit', 'reset']}
+\ ],
+\ 'caption': [
+\ ['br', 'span', 'em', 'strong', 'dfn', 'code', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'q', 'tt', 'i', 'b', 'big', 'small', 'sub', 'sup', 'bdo', 'a', 'img', 'map', 'object', 'input', 'select', 'textarea', 'label', 'button', 'ruby', 'ins', 'del', 'script', 'noscript'],
+\ { 'xmlns': ['http://www.w3.org/1999/xhtml'], 'ondblclick': [], 'dir': ['ltr', 'rtl'], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'style': [], 'onmousemove': [], 'onmouseout': [], 'xml:lang': [], 'onmousedown': [], 'onkeypress': [], 'onclick': [], 'title': [], 'class': []}
+\ ],
+\ 'cite': [
+\ ['br', 'span', 'em', 'strong', 'dfn', 'code', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'q', 'tt', 'i', 'b', 'big', 'small', 'sub', 'sup', 'bdo', 'a', 'img', 'map', 'object', 'input', 'select', 'textarea', 'label', 'button', 'ruby', 'ins', 'del', 'script', 'noscript'],
+\ { 'xmlns': ['http://www.w3.org/1999/xhtml'], 'ondblclick': [], 'dir': ['ltr', 'rtl'], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'style': [], 'onmousemove': [], 'onmouseout': [], 'xml:lang': [], 'onmousedown': [], 'onkeypress': [], 'onclick': [], 'title': [], 'class': []}
+\ ],
+\ 'code': [
+\ ['br', 'span', 'em', 'strong', 'dfn', 'code', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'q', 'tt', 'i', 'b', 'big', 'small', 'sub', 'sup', 'bdo', 'a', 'img', 'map', 'object', 'input', 'select', 'textarea', 'label', 'button', 'ruby', 'ins', 'del', 'script', 'noscript'],
+\ { 'xmlns': ['http://www.w3.org/1999/xhtml'], 'ondblclick': [], 'dir': ['ltr', 'rtl'], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'style': [], 'onmousemove': [], 'onmouseout': [], 'xml:lang': [], 'onmousedown': [], 'onkeypress': [], 'onclick': [], 'title': [], 'class': []}
+\ ],
+\ 'col': [
+\ [],
+\ { 'xmlns': ['http://www.w3.org/1999/xhtml'], 'width': [], 'ondblclick': [], 'dir': ['ltr', 'rtl'], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'charoff': [], 'onmouseover': [], 'align': ['left', 'center', 'right', 'justify', 'char'], 'valign': ['top', 'middle', 'bottom', 'baseline'], 'onmouseout': [], 'onmousemove': [], 'style': [], 'xml:lang': [], 'onkeypress': [], 'onmousedown': [], 'char': [], 'span': ['1'], 'class': [], 'title': [], 'onclick': []}
+\ ],
+\ 'colgroup': [
+\ ['col'],
+\ { 'xmlns': ['http://www.w3.org/1999/xhtml'], 'width': [], 'ondblclick': [], 'dir': ['ltr', 'rtl'], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'charoff': [], 'onmouseover': [], 'align': ['left', 'center', 'right', 'justify', 'char'], 'valign': ['top', 'middle', 'bottom', 'baseline'], 'onmouseout': [], 'onmousemove': [], 'style': [], 'xml:lang': [], 'onkeypress': [], 'onmousedown': [], 'char': [], 'span': ['1'], 'class': [], 'title': [], 'onclick': []}
+\ ],
+\ 'dd': [
+\ ['h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'ul', 'ol', 'dl', 'p', 'div', 'pre', 'blockquote', 'address', 'hr', 'table', 'form', 'fieldset', 'br', 'span', 'em', 'strong', 'dfn', 'code', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'q', 'tt', 'i', 'b', 'big', 'small', 'sub', 'sup', 'bdo', 'a', 'img', 'map', 'object', 'input', 'select', 'textarea', 'label', 'button', 'ruby', 'ins', 'del', 'script', 'noscript'],
+\ { 'xmlns': ['http://www.w3.org/1999/xhtml'], 'ondblclick': [], 'dir': ['ltr', 'rtl'], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'style': [], 'onmousemove': [], 'onmouseout': [], 'xml:lang': [], 'onmousedown': [], 'onkeypress': [], 'onclick': [], 'title': [], 'class': []}
+\ ],
+\ 'del': [
+\ ['h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'ul', 'ol', 'dl', 'p', 'div', 'pre', 'blockquote', 'address', 'hr', 'table', 'form', 'fieldset', 'br', 'span', 'em', 'strong', 'dfn', 'code', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'q', 'tt', 'i', 'b', 'big', 'small', 'sub', 'sup', 'bdo', 'a', 'img', 'map', 'object', 'input', 'select', 'textarea', 'label', 'button', 'ruby', 'ins', 'del', 'script', 'noscript'],
+\ { 'xmlns': ['http://www.w3.org/1999/xhtml'], 'ondblclick': [], 'dir': ['ltr', 'rtl'], 'datetime': [], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'cite': [], 'onmouseover': [], 'onmouseout': [], 'onmousemove': [], 'style': [], 'xml:lang': [], 'onkeypress': [], 'onmousedown': [], 'class': [], 'title': [], 'onclick': []}
+\ ],
+\ 'dfn': [
+\ ['br', 'span', 'em', 'strong', 'dfn', 'code', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'q', 'tt', 'i', 'b', 'big', 'small', 'sub', 'sup', 'bdo', 'a', 'img', 'map', 'object', 'input', 'select', 'textarea', 'label', 'button', 'ruby', 'ins', 'del', 'script', 'noscript'],
+\ { 'xmlns': ['http://www.w3.org/1999/xhtml'], 'ondblclick': [], 'dir': ['ltr', 'rtl'], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'style': [], 'onmousemove': [], 'onmouseout': [], 'xml:lang': [], 'onmousedown': [], 'onkeypress': [], 'onclick': [], 'title': [], 'class': []}
+\ ],
+\ 'div': [
+\ ['h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'ul', 'ol', 'dl', 'p', 'div', 'pre', 'blockquote', 'address', 'hr', 'table', 'form', 'fieldset', 'br', 'span', 'em', 'strong', 'dfn', 'code', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'q', 'tt', 'i', 'b', 'big', 'small', 'sub', 'sup', 'bdo', 'a', 'img', 'map', 'object', 'input', 'select', 'textarea', 'label', 'button', 'ruby', 'ins', 'del', 'script', 'noscript'],
+\ { 'xmlns': ['http://www.w3.org/1999/xhtml'], 'ondblclick': [], 'dir': ['ltr', 'rtl'], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'style': [], 'onmousemove': [], 'onmouseout': [], 'xml:lang': [], 'onmousedown': [], 'onkeypress': [], 'onclick': [], 'title': [], 'class': []}
+\ ],
+\ 'dl': [
+\ ['dt', 'dd'],
+\ { 'xmlns': ['http://www.w3.org/1999/xhtml'], 'ondblclick': [], 'dir': ['ltr', 'rtl'], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'style': [], 'onmousemove': [], 'onmouseout': [], 'xml:lang': [], 'onmousedown': [], 'onkeypress': [], 'onclick': [], 'title': [], 'class': []}
+\ ],
+\ 'dt': [
+\ ['br', 'span', 'em', 'strong', 'dfn', 'code', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'q', 'tt', 'i', 'b', 'big', 'small', 'sub', 'sup', 'bdo', 'a', 'img', 'map', 'object', 'input', 'select', 'textarea', 'label', 'button', 'ruby', 'ins', 'del', 'script', 'noscript'],
+\ { 'xmlns': ['http://www.w3.org/1999/xhtml'], 'ondblclick': [], 'dir': ['ltr', 'rtl'], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'style': [], 'onmousemove': [], 'onmouseout': [], 'xml:lang': [], 'onmousedown': [], 'onkeypress': [], 'onclick': [], 'title': [], 'class': []}
+\ ],
+\ 'em': [
+\ ['br', 'span', 'em', 'strong', 'dfn', 'code', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'q', 'tt', 'i', 'b', 'big', 'small', 'sub', 'sup', 'bdo', 'a', 'img', 'map', 'object', 'input', 'select', 'textarea', 'label', 'button', 'ruby', 'ins', 'del', 'script', 'noscript'],
+\ { 'xmlns': ['http://www.w3.org/1999/xhtml'], 'ondblclick': [], 'dir': ['ltr', 'rtl'], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'style': [], 'onmousemove': [], 'onmouseout': [], 'xml:lang': [], 'onmousedown': [], 'onkeypress': [], 'onclick': [], 'title': [], 'class': []}
+\ ],
+\ 'fieldset': [
+\ ['legend', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'ul', 'ol', 'dl', 'p', 'div', 'pre', 'blockquote', 'address', 'hr', 'table', 'form', 'fieldset', 'br', 'span', 'em', 'strong', 'dfn', 'code', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'q', 'tt', 'i', 'b', 'big', 'small', 'sub', 'sup', 'bdo', 'a', 'img', 'map', 'object', 'input', 'select', 'textarea', 'label', 'button', 'ruby', 'ins', 'del', 'script', 'noscript'],
+\ { 'xmlns': ['http://www.w3.org/1999/xhtml'], 'ondblclick': [], 'dir': ['ltr', 'rtl'], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'style': [], 'onmousemove': [], 'onmouseout': [], 'xml:lang': [], 'onmousedown': [], 'onkeypress': [], 'onclick': [], 'title': [], 'class': []}
+\ ],
+\ 'form': [
+\ ['h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'ul', 'ol', 'dl', 'p', 'div', 'pre', 'blockquote', 'address', 'hr', 'table', 'ins', 'del', 'script', 'noscript', 'fieldset'],
+\ { 'xmlns': ['http://www.w3.org/1999/xhtml'], 'enctype': ['application/x-www-form-urlencoded'], 'ondblclick': [], 'dir': ['ltr', 'rtl'], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'method': ['get', 'post'], 'onmouseover': [], 'accept': [], 'onmouseout': [], 'onmousemove': [], 'style': [], 'xml:lang': [], 'accept-charset': [], 'onkeypress': [], 'onmousedown': [], 'action': [], 'class': [], 'title': [], 'onclick': []}
+\ ],
+\ 'h1': [
+\ ['br', 'span', 'em', 'strong', 'dfn', 'code', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'q', 'tt', 'i', 'b', 'big', 'small', 'sub', 'sup', 'bdo', 'a', 'img', 'map', 'object', 'input', 'select', 'textarea', 'label', 'button', 'ruby', 'ins', 'del', 'script', 'noscript'],
+\ { 'xmlns': ['http://www.w3.org/1999/xhtml'], 'ondblclick': [], 'dir': ['ltr', 'rtl'], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'style': [], 'onmousemove': [], 'onmouseout': [], 'xml:lang': [], 'onmousedown': [], 'onkeypress': [], 'onclick': [], 'title': [], 'class': []}
+\ ],
+\ 'h2': [
+\ ['br', 'span', 'em', 'strong', 'dfn', 'code', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'q', 'tt', 'i', 'b', 'big', 'small', 'sub', 'sup', 'bdo', 'a', 'img', 'map', 'object', 'input', 'select', 'textarea', 'label', 'button', 'ruby', 'ins', 'del', 'script', 'noscript'],
+\ { 'xmlns': ['http://www.w3.org/1999/xhtml'], 'ondblclick': [], 'dir': ['ltr', 'rtl'], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'style': [], 'onmousemove': [], 'onmouseout': [], 'xml:lang': [], 'onmousedown': [], 'onkeypress': [], 'onclick': [], 'title': [], 'class': []}
+\ ],
+\ 'h3': [
+\ ['br', 'span', 'em', 'strong', 'dfn', 'code', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'q', 'tt', 'i', 'b', 'big', 'small', 'sub', 'sup', 'bdo', 'a', 'img', 'map', 'object', 'input', 'select', 'textarea', 'label', 'button', 'ruby', 'ins', 'del', 'script', 'noscript'],
+\ { 'xmlns': ['http://www.w3.org/1999/xhtml'], 'ondblclick': [], 'dir': ['ltr', 'rtl'], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'style': [], 'onmousemove': [], 'onmouseout': [], 'xml:lang': [], 'onmousedown': [], 'onkeypress': [], 'onclick': [], 'title': [], 'class': []}
+\ ],
+\ 'h4': [
+\ ['br', 'span', 'em', 'strong', 'dfn', 'code', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'q', 'tt', 'i', 'b', 'big', 'small', 'sub', 'sup', 'bdo', 'a', 'img', 'map', 'object', 'input', 'select', 'textarea', 'label', 'button', 'ruby', 'ins', 'del', 'script', 'noscript'],
+\ { 'xmlns': ['http://www.w3.org/1999/xhtml'], 'ondblclick': [], 'dir': ['ltr', 'rtl'], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'style': [], 'onmousemove': [], 'onmouseout': [], 'xml:lang': [], 'onmousedown': [], 'onkeypress': [], 'onclick': [], 'title': [], 'class': []}
+\ ],
+\ 'h5': [
+\ ['br', 'span', 'em', 'strong', 'dfn', 'code', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'q', 'tt', 'i', 'b', 'big', 'small', 'sub', 'sup', 'bdo', 'a', 'img', 'map', 'object', 'input', 'select', 'textarea', 'label', 'button', 'ruby', 'ins', 'del', 'script', 'noscript'],
+\ { 'xmlns': ['http://www.w3.org/1999/xhtml'], 'ondblclick': [], 'dir': ['ltr', 'rtl'], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'style': [], 'onmousemove': [], 'onmouseout': [], 'xml:lang': [], 'onmousedown': [], 'onkeypress': [], 'onclick': [], 'title': [], 'class': []}
+\ ],
+\ 'h6': [
+\ ['br', 'span', 'em', 'strong', 'dfn', 'code', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'q', 'tt', 'i', 'b', 'big', 'small', 'sub', 'sup', 'bdo', 'a', 'img', 'map', 'object', 'input', 'select', 'textarea', 'label', 'button', 'ruby', 'ins', 'del', 'script', 'noscript'],
+\ { 'xmlns': ['http://www.w3.org/1999/xhtml'], 'ondblclick': [], 'dir': ['ltr', 'rtl'], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'style': [], 'onmousemove': [], 'onmouseout': [], 'xml:lang': [], 'onmousedown': [], 'onkeypress': [], 'onclick': [], 'title': [], 'class': []}
+\ ],
+\ 'head': [
+\ ['script', 'style', 'meta', 'link', 'object', 'title', 'script', 'style', 'meta', 'link', 'object', 'base', 'script', 'style', 'meta', 'link', 'object', 'base', 'script', 'style', 'meta', 'link', 'object', 'title', 'script', 'style', 'meta', 'link', 'object'],
+\ { 'xmlns': ['http://www.w3.org/1999/xhtml'], 'profile': [''], 'dir': ['ltr', 'rtl'], 'xml:lang': []}
+\ ],
+\ 'hr': [
+\ [],
+\ { 'xmlns': ['http://www.w3.org/1999/xhtml'], 'ondblclick': [], 'dir': ['ltr', 'rtl'], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'style': [], 'onmousemove': [], 'onmouseout': [], 'xml:lang': [], 'onmousedown': [], 'onkeypress': [], 'onclick': [], 'title': [], 'class': []}
+\ ],
+\ 'html': [
+\ ['head', 'body'],
+\ { 'xmlns': ['http://www.w3.org/1999/xhtml'], 'dir': ['ltr', 'rtl'], 'version': ['-//W3C//DTD XHTML 1.1//EN'], 'xml:lang': []}
+\ ],
+\ 'i': [
+\ ['br', 'span', 'em', 'strong', 'dfn', 'code', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'q', 'tt', 'i', 'b', 'big', 'small', 'sub', 'sup', 'bdo', 'a', 'img', 'map', 'object', 'input', 'select', 'textarea', 'label', 'button', 'ruby', 'ins', 'del', 'script', 'noscript'],
+\ { 'xmlns': ['http://www.w3.org/1999/xhtml'], 'ondblclick': [], 'dir': ['ltr', 'rtl'], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'style': [], 'onmousemove': [], 'onmouseout': [], 'xml:lang': [], 'onmousedown': [], 'onkeypress': [], 'onclick': [], 'title': [], 'class': []}
+\ ],
+\ 'img': [
+\ [],
+\ { 'ismap': ['BOOL']}
+\ ],
+\ 'input': [
+\ [],
+\ { 'xmlns': ['http://www.w3.org/1999/xhtml'], 'accesskey': [], 'disabled': ['BOOL'], 'ondblclick': [], 'dir': ['ltr', 'rtl'], 'size': [], 'onkeydown': [], 'readonly': ['BOOL'], 'onkeyup': [], 'onmouseup': [], 'id': [], 'maxlength': [], 'onmouseover': [], 'alt': [], 'tabindex': [], 'accept': [], 'value': [], 'src': [], 'onmouseout': [], 'onmousemove': [], 'style': [], 'name': [], 'xml:lang': [], 'checked': ['BOOL'], 'onkeypress': [], 'onmousedown': [], 'type': ['text', 'password', 'checkbox', 'radio', 'submit', 'reset', 'file', 'hidden', 'image', 'button'], 'class': [], 'title': [], 'onclick': []}
+\ ],
+\ 'ins': [
+\ ['h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'ul', 'ol', 'dl', 'p', 'div', 'pre', 'blockquote', 'address', 'hr', 'table', 'form', 'fieldset', 'br', 'span', 'em', 'strong', 'dfn', 'code', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'q', 'tt', 'i', 'b', 'big', 'small', 'sub', 'sup', 'bdo', 'a', 'img', 'map', 'object', 'input', 'select', 'textarea', 'label', 'button', 'ruby', 'ins', 'del', 'script', 'noscript'],
+\ { 'xmlns': ['http://www.w3.org/1999/xhtml'], 'ondblclick': [], 'dir': ['ltr', 'rtl'], 'datetime': [], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'cite': [], 'onmouseover': [], 'onmouseout': [], 'onmousemove': [], 'style': [], 'xml:lang': [], 'onkeypress': [], 'onmousedown': [], 'class': [], 'title': [], 'onclick': []}
+\ ],
+\ 'kbd': [
+\ ['br', 'span', 'em', 'strong', 'dfn', 'code', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'q', 'tt', 'i', 'b', 'big', 'small', 'sub', 'sup', 'bdo', 'a', 'img', 'map', 'object', 'input', 'select', 'textarea', 'label', 'button', 'ruby', 'ins', 'del', 'script', 'noscript'],
+\ { 'xmlns': ['http://www.w3.org/1999/xhtml'], 'ondblclick': [], 'dir': ['ltr', 'rtl'], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'style': [], 'onmousemove': [], 'onmouseout': [], 'xml:lang': [], 'onmousedown': [], 'onkeypress': [], 'onclick': [], 'title': [], 'class': []}
+\ ],
+\ 'label': [
+\ ['input', 'select', 'textarea', 'button', 'br', 'span', 'em', 'strong', 'dfn', 'code', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'q', 'bdo', 'tt', 'i', 'b', 'big', 'small', 'sub', 'sup', 'a', 'img', 'map', 'object', 'ins', 'del', 'script', 'noscript'],
+\ { 'xmlns': ['http://www.w3.org/1999/xhtml'], 'accesskey': [], 'ondblclick': [], 'dir': ['ltr', 'rtl'], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'for': [], 'onmouseout': [], 'onmousemove': [], 'style': [], 'xml:lang': [], 'onkeypress': [], 'onmousedown': [], 'class': [], 'title': [], 'onclick': []}
+\ ],
+\ 'legend': [
+\ ['br', 'span', 'em', 'strong', 'dfn', 'code', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'q', 'tt', 'i', 'b', 'big', 'small', 'sub', 'sup', 'bdo', 'a', 'img', 'map', 'object', 'input', 'select', 'textarea', 'label', 'button', 'ruby', 'ins', 'del', 'script', 'noscript'],
+\ { 'xmlns': ['http://www.w3.org/1999/xhtml'], 'accesskey': [], 'ondblclick': [], 'dir': ['ltr', 'rtl'], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'onmouseout': [], 'onmousemove': [], 'style': [], 'xml:lang': [], 'onkeypress': [], 'onmousedown': [], 'class': [], 'title': [], 'onclick': []}
+\ ],
+\ 'li': [
+\ ['h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'ul', 'ol', 'dl', 'p', 'div', 'pre', 'blockquote', 'address', 'hr', 'table', 'form', 'fieldset', 'br', 'span', 'em', 'strong', 'dfn', 'code', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'q', 'tt', 'i', 'b', 'big', 'small', 'sub', 'sup', 'bdo', 'a', 'img', 'map', 'object', 'input', 'select', 'textarea', 'label', 'button', 'ruby', 'ins', 'del', 'script', 'noscript'],
+\ { 'xmlns': ['http://www.w3.org/1999/xhtml'], 'ondblclick': [], 'dir': ['ltr', 'rtl'], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'style': [], 'onmousemove': [], 'onmouseout': [], 'xml:lang': [], 'onmousedown': [], 'onkeypress': [], 'onclick': [], 'title': [], 'class': []}
+\ ],
+\ 'link': [
+\ [],
+\ { 'xmlns': ['http://www.w3.org/1999/xhtml'], 'rel': [], 'ondblclick': [], 'dir': ['ltr', 'rtl'], 'onkeydown': [], 'onkeyup': [], 'href': [], 'media': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'onmouseout': [], 'onmousemove': [], 'style': [], 'charset': [], 'xml:lang': [], 'hreflang': [], 'onkeypress': [], 'onmousedown': [], 'rev': [], 'class': [], 'title': [], 'onclick': [], 'type': []}
+\ ],
+\ 'map': [
+\ ['h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'ul', 'ol', 'dl', 'p', 'div', 'pre', 'blockquote', 'address', 'hr', 'table', 'form', 'fieldset', 'ins', 'del', 'script', 'noscript', 'area'],
+\ { 'xmlns': ['http://www.w3.org/1999/xhtml'], 'ondblclick': [], 'dir': ['ltr', 'rtl'], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'style': [], 'onmousemove': [], 'onmouseout': [], 'xml:lang': [], 'onmousedown': [], 'onkeypress': [], 'onclick': [], 'title': [], 'class': []}
+\ ],
+\ 'meta': [
+\ [],
+\ { 'xmlns': ['http://www.w3.org/1999/xhtml'], 'http-equiv': [], 'content': [], 'dir': ['ltr', 'rtl'], 'name': [], 'scheme': [], 'xml:lang': []}
+\ ],
+\ 'noscript': [
+\ ['h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'ul', 'ol', 'dl', 'p', 'div', 'pre', 'blockquote', 'address', 'hr', 'table', 'form', 'fieldset', 'ins', 'del', 'script', 'noscript'],
+\ { 'xmlns': ['http://www.w3.org/1999/xhtml'], 'ondblclick': [], 'dir': ['ltr', 'rtl'], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'style': [], 'onmousemove': [], 'onmouseout': [], 'xml:lang': [], 'onmousedown': [], 'onkeypress': [], 'onclick': [], 'title': [], 'class': []}
+\ ],
+\ 'object': [
+\ ['h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'ul', 'ol', 'dl', 'p', 'div', 'pre', 'blockquote', 'address', 'hr', 'table', 'form', 'fieldset', 'br', 'span', 'em', 'strong', 'dfn', 'code', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'q', 'tt', 'i', 'b', 'big', 'small', 'sub', 'sup', 'bdo', 'a', 'img', 'map', 'object', 'input', 'select', 'textarea', 'label', 'button', 'ruby', 'ins', 'del', 'script', 'noscript', 'param'],
+\ { 'xmlns': ['http://www.w3.org/1999/xhtml'], 'width': [], 'ondblclick': [], 'dir': ['ltr', 'rtl'], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'archive': [], 'standby': [], 'tabindex': [], 'classid': [], 'onmouseout': [], 'onmousemove': [], 'style': [], 'name': [], 'data': [], 'xml:lang': [], 'height': [], 'codetype': [], 'declare': ['BOOL'], 'onkeypress': [], 'onmousedown': [], 'class': [], 'title': [], 'onclick': [], 'type': [], 'codebase': []}
+\ ],
+\ 'ol': [
+\ ['li'],
+\ { 'xmlns': ['http://www.w3.org/1999/xhtml'], 'ondblclick': [], 'dir': ['ltr', 'rtl'], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'style': [], 'onmousemove': [], 'onmouseout': [], 'xml:lang': [], 'onmousedown': [], 'onkeypress': [], 'onclick': [], 'title': [], 'class': []}
+\ ],
+\ 'optgroup': [
+\ ['option'],
+\ { 'xmlns': ['http://www.w3.org/1999/xhtml'], 'disabled': ['BOOL'], 'ondblclick': [], 'dir': ['ltr', 'rtl'], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'onmouseout': [], 'onmousemove': [], 'style': [], 'xml:lang': [], 'onkeypress': [], 'onmousedown': [], 'class': [], 'title': [], 'onclick': [], 'label': []}
+\ ],
+\ 'option': [
+\ [''],
+\ { 'xmlns': ['http://www.w3.org/1999/xhtml'], 'disabled': ['BOOL'], 'ondblclick': [], 'dir': ['ltr', 'rtl'], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'value': [], 'onmouseout': [], 'onmousemove': [], 'style': [], 'xml:lang': [], 'onkeypress': [], 'onmousedown': [], 'class': [], 'title': [], 'onclick': [], 'label': [], 'selected': ['BOOL']}
+\ ],
+\ 'p': [
+\ ['br', 'span', 'em', 'strong', 'dfn', 'code', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'q', 'tt', 'i', 'b', 'big', 'small', 'sub', 'sup', 'bdo', 'a', 'img', 'map', 'object', 'input', 'select', 'textarea', 'label', 'button', 'ruby', 'ins', 'del', 'script', 'noscript'],
+\ { 'xmlns': ['http://www.w3.org/1999/xhtml'], 'ondblclick': [], 'dir': ['ltr', 'rtl'], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'style': [], 'onmousemove': [], 'onmouseout': [], 'xml:lang': [], 'onmousedown': [], 'onkeypress': [], 'onclick': [], 'title': [], 'class': []}
+\ ],
+\ 'param': [
+\ [],
+\ { 'xmlns': ['http://www.w3.org/1999/xhtml'], 'id': [], 'value': [], 'name': [], 'valuetype': ['data', 'ref', 'object'], 'type': []}
+\ ],
+\ 'pre': [
+\ ['br', 'span', 'em', 'strong', 'dfn', 'code', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'q', 'tt', 'i', 'b', 'bdo', 'a', 'script', 'map'],
+\ { 'xmlns': ['http://www.w3.org/1999/xhtml'], 'ondblclick': [], 'dir': ['ltr', 'rtl'], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'onmouseout': [], 'onmousemove': [], 'style': [], 'xml:space': ['preserve'], 'xml:lang': [], 'onkeypress': [], 'onmousedown': [], 'class': [], 'title': [], 'onclick': []}
+\ ],
+\ 'q': [
+\ ['br', 'span', 'em', 'strong', 'dfn', 'code', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'q', 'tt', 'i', 'b', 'big', 'small', 'sub', 'sup', 'bdo', 'a', 'img', 'map', 'object', 'input', 'select', 'textarea', 'label', 'button', 'ruby', 'ins', 'del', 'script', 'noscript'],
+\ { 'xmlns': ['http://www.w3.org/1999/xhtml'], 'ondblclick': [], 'dir': ['ltr', 'rtl'], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'cite': [], 'onmouseover': [], 'style': [], 'onmousemove': [], 'onmouseout': [], 'xml:lang': [], 'onmousedown': [], 'onkeypress': [], 'onclick': [], 'title': [], 'class': []}
+\ ],
+\ 'rb': [
+\ ['br', 'span', 'em', 'strong', 'dfn', 'code', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'q', 'tt', 'i', 'b', 'big', 'small', 'sub', 'sup', 'bdo', 'a', 'img', 'map', 'object', 'input', 'select', 'textarea', 'label', 'button', 'ins', 'del', 'script', 'noscript'],
+\ { 'xmlns': ['http://www.w3.org/1999/xhtml'], 'ondblclick': [], 'dir': ['ltr', 'rtl'], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'style': [], 'onmousemove': [], 'onmouseout': [], 'xml:lang': [], 'onmousedown': [], 'onkeypress': [], 'onclick': [], 'title': [], 'class': []}
+\ ],
+\ 'rbc': [
+\ ['rb'],
+\ { 'xmlns': ['http://www.w3.org/1999/xhtml'], 'ondblclick': [], 'dir': ['ltr', 'rtl'], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'style': [], 'onmousemove': [], 'onmouseout': [], 'xml:lang': [], 'onmousedown': [], 'onkeypress': [], 'onclick': [], 'title': [], 'class': []}
+\ ],
+\ 'rp': [
+\ [''],
+\ { 'xmlns': ['http://www.w3.org/1999/xhtml'], 'ondblclick': [], 'dir': ['ltr', 'rtl'], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'style': [], 'onmousemove': [], 'onmouseout': [], 'xml:lang': [], 'onmousedown': [], 'onkeypress': [], 'onclick': [], 'title': [], 'class': []}
+\ ],
+\ 'rt': [
+\ ['br', 'span', 'em', 'strong', 'dfn', 'code', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'q', 'tt', 'i', 'b', 'big', 'small', 'sub', 'sup', 'bdo', 'a', 'img', 'map', 'object', 'input', 'select', 'textarea', 'label', 'button', 'ins', 'del', 'script', 'noscript'],
+\ { 'xmlns': ['http://www.w3.org/1999/xhtml'], 'ondblclick': [], 'dir': ['ltr', 'rtl'], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'style': [], 'onmousemove': [], 'onmouseout': [], 'xml:lang': [], 'onmousedown': [], 'onkeypress': [], 'onclick': [], 'title': [], 'class': []}
+\ ],
+\ 'rtc': [
+\ ['rt'],
+\ { 'xmlns': ['http://www.w3.org/1999/xhtml'], 'ondblclick': [], 'dir': ['ltr', 'rtl'], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'style': [], 'onmousemove': [], 'onmouseout': [], 'xml:lang': [], 'onmousedown': [], 'onkeypress': [], 'onclick': [], 'title': [], 'class': []}
+\ ],
+\ 'ruby': [
+\ ['rb', 'rt', 'rp', 'rt', 'rp', 'rbc', 'rtc'],
+\ { 'xmlns': ['http://www.w3.org/1999/xhtml'], 'ondblclick': [], 'dir': ['ltr', 'rtl'], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'style': [], 'onmousemove': [], 'onmouseout': [], 'xml:lang': [], 'onmousedown': [], 'onkeypress': [], 'onclick': [], 'title': [], 'class': []}
+\ ],
+\ 'samp': [
+\ ['br', 'span', 'em', 'strong', 'dfn', 'code', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'q', 'tt', 'i', 'b', 'big', 'small', 'sub', 'sup', 'bdo', 'a', 'img', 'map', 'object', 'input', 'select', 'textarea', 'label', 'button', 'ruby', 'ins', 'del', 'script', 'noscript'],
+\ { 'xmlns': ['http://www.w3.org/1999/xhtml'], 'ondblclick': [], 'dir': ['ltr', 'rtl'], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'style': [], 'onmousemove': [], 'onmouseout': [], 'xml:lang': [], 'onmousedown': [], 'onkeypress': [], 'onclick': [], 'title': [], 'class': []}
+\ ],
+\ 'script': [
+\ [''],
+\ { 'xmlns': ['http://www.w3.org/1999/xhtml'], 'defer': ['BOOL'], 'src': [], 'charset': [], 'xml:space': ['preserve'], 'type': ['text/javascript']}
+\ ],
+\ 'select': [
+\ ['optgroup', 'option'],
+\ { 'xmlns': ['http://www.w3.org/1999/xhtml'], 'disabled': ['BOOL'], 'ondblclick': [], 'dir': ['ltr', 'rtl'], 'size': [], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'tabindex': [], 'name': [], 'onmouseout': [], 'onmousemove': [], 'style': [], 'xml:lang': [], 'onkeypress': [], 'onmousedown': [], 'class': [], 'title': [], 'onclick': [], 'multiple': ['BOOL']}
+\ ],
+\ 'small': [
+\ ['br', 'span', 'em', 'strong', 'dfn', 'code', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'q', 'tt', 'i', 'b', 'big', 'small', 'sub', 'sup', 'bdo', 'a', 'img', 'map', 'object', 'input', 'select', 'textarea', 'label', 'button', 'ruby', 'ins', 'del', 'script', 'noscript'],
+\ { 'xmlns': ['http://www.w3.org/1999/xhtml'], 'ondblclick': [], 'dir': ['ltr', 'rtl'], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'style': [], 'onmousemove': [], 'onmouseout': [], 'xml:lang': [], 'onmousedown': [], 'onkeypress': [], 'onclick': [], 'title': [], 'class': []}
+\ ],
+\ 'span': [
+\ ['br', 'span', 'em', 'strong', 'dfn', 'code', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'q', 'tt', 'i', 'b', 'big', 'small', 'sub', 'sup', 'bdo', 'a', 'img', 'map', 'object', 'input', 'select', 'textarea', 'label', 'button', 'ruby', 'ins', 'del', 'script', 'noscript'],
+\ { 'xmlns': ['http://www.w3.org/1999/xhtml'], 'ondblclick': [], 'dir': ['ltr', 'rtl'], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'style': [], 'onmousemove': [], 'onmouseout': [], 'xml:lang': [], 'onmousedown': [], 'onkeypress': [], 'onclick': [], 'title': [], 'class': []}
+\ ],
+\ 'strong': [
+\ ['br', 'span', 'em', 'strong', 'dfn', 'code', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'q', 'tt', 'i', 'b', 'big', 'small', 'sub', 'sup', 'bdo', 'a', 'img', 'map', 'object', 'input', 'select', 'textarea', 'label', 'button', 'ruby', 'ins', 'del', 'script', 'noscript'],
+\ { 'xmlns': ['http://www.w3.org/1999/xhtml'], 'ondblclick': [], 'dir': ['ltr', 'rtl'], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'style': [], 'onmousemove': [], 'onmouseout': [], 'xml:lang': [], 'onmousedown': [], 'onkeypress': [], 'onclick': [], 'title': [], 'class': []}
+\ ],
+\ 'style': [
+\ [''],
+\ { 'xmlns': ['http://www.w3.org/1999/xhtml'], 'dir': ['ltr', 'rtl'], 'media': [], 'xml:lang': [], 'xml:space': ['preserve'], 'title': [], 'type': ['text/css']}
+\ ],
+\ 'sub': [
+\ ['br', 'span', 'em', 'strong', 'dfn', 'code', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'q', 'tt', 'i', 'b', 'big', 'small', 'sub', 'sup', 'bdo', 'a', 'img', 'map', 'object', 'input', 'select', 'textarea', 'label', 'button', 'ruby', 'ins', 'del', 'script', 'noscript'],
+\ { 'xmlns': ['http://www.w3.org/1999/xhtml'], 'ondblclick': [], 'dir': ['ltr', 'rtl'], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'style': [], 'onmousemove': [], 'onmouseout': [], 'xml:lang': [], 'onmousedown': [], 'onkeypress': [], 'onclick': [], 'title': [], 'class': []}
+\ ],
+\ 'sup': [
+\ ['br', 'span', 'em', 'strong', 'dfn', 'code', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'q', 'tt', 'i', 'b', 'big', 'small', 'sub', 'sup', 'bdo', 'a', 'img', 'map', 'object', 'input', 'select', 'textarea', 'label', 'button', 'ruby', 'ins', 'del', 'script', 'noscript'],
+\ { 'xmlns': ['http://www.w3.org/1999/xhtml'], 'ondblclick': [], 'dir': ['ltr', 'rtl'], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'style': [], 'onmousemove': [], 'onmouseout': [], 'xml:lang': [], 'onmousedown': [], 'onkeypress': [], 'onclick': [], 'title': [], 'class': []}
+\ ],
+\ 'table': [
+\ ['caption', 'col', 'colgroup', 'thead', 'tfoot', 'tbody', 'tr'],
+\ { 'xmlns': ['http://www.w3.org/1999/xhtml'], 'width': [], 'ondblclick': [], 'frame': ['void', 'above', 'below', 'hsides', 'lhs', 'rhs', 'vsides', 'box', 'border'], 'rules': ['none', 'groups', 'rows', 'cols', 'all'], 'dir': ['ltr', 'rtl'], 'onkeydown': [], 'onkeyup': [], 'summary': [], 'onmouseup': [], 'cellspacing': [], 'id': [], 'onmouseover': [], 'onmouseout': [], 'onmousemove': [], 'style': [], 'xml:lang': [], 'border': [], 'onkeypress': [], 'onmousedown': [], 'class': [], 'title': [], 'onclick': [], 'cellpadding': []}
+\ ],
+\ 'tbody': [
+\ ['tr'],
+\ { 'xmlns': ['http://www.w3.org/1999/xhtml'], 'ondblclick': [], 'dir': ['ltr', 'rtl'], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'charoff': [], 'onmouseover': [], 'align': ['left', 'center', 'right', 'justify', 'char'], 'valign': ['top', 'middle', 'bottom', 'baseline'], 'onmouseout': [], 'onmousemove': [], 'style': [], 'xml:lang': [], 'char': [], 'onkeypress': [], 'onmousedown': [], 'class': [], 'title': [], 'onclick': []}
+\ ],
+\ 'td': [
+\ ['h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'ul', 'ol', 'dl', 'p', 'div', 'pre', 'blockquote', 'address', 'hr', 'table', 'form', 'fieldset', 'br', 'span', 'em', 'strong', 'dfn', 'code', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'q', 'tt', 'i', 'b', 'big', 'small', 'sub', 'sup', 'bdo', 'a', 'img', 'map', 'object', 'input', 'select', 'textarea', 'label', 'button', 'ruby', 'ins', 'del', 'script', 'noscript'],
+\ { 'xmlns': ['http://www.w3.org/1999/xhtml'], 'headers': [], 'ondblclick': [], 'axis': [], 'dir': ['ltr', 'rtl'], 'onkeydown': [], 'abbr': [], 'onkeyup': [], 'rowspan': ['1'], 'colspan': ['1'], 'onmouseup': [], 'id': [], 'charoff': [], 'scope': ['row', 'col', 'rowgroup', 'colgroup'], 'onmouseover': [], 'align': ['left', 'center', 'right', 'justify', 'char'], 'valign': ['top', 'middle', 'bottom', 'baseline'], 'onmouseout': [], 'onmousemove': [], 'style': [], 'xml:lang': [], 'onkeypress': [], 'onmousedown': [], 'char': [], 'class': [], 'title': [], 'onclick': []}
+\ ],
+\ 'textarea': [
+\ [''],
+\ { 'xmlns': ['http://www.w3.org/1999/xhtml'], 'accesskey': [], 'disabled': ['BOOL'], 'ondblclick': [], 'rows': [], 'dir': ['ltr', 'rtl'], 'cols': [], 'onkeydown': [], 'readonly': ['BOOL'], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'tabindex': [], 'name': [], 'onmouseout': [], 'onmousemove': [], 'style': [], 'xml:lang': [], 'onkeypress': [], 'onmousedown': [], 'class': [], 'title': [], 'onclick': []}
+\ ],
+\ 'tfoot': [
+\ ['tr'],
+\ { 'xmlns': ['http://www.w3.org/1999/xhtml'], 'ondblclick': [], 'dir': ['ltr', 'rtl'], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'charoff': [], 'onmouseover': [], 'align': ['left', 'center', 'right', 'justify', 'char'], 'valign': ['top', 'middle', 'bottom', 'baseline'], 'onmouseout': [], 'onmousemove': [], 'style': [], 'xml:lang': [], 'char': [], 'onkeypress': [], 'onmousedown': [], 'class': [], 'title': [], 'onclick': []}
+\ ],
+\ 'th': [
+\ ['h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'ul', 'ol', 'dl', 'p', 'div', 'pre', 'blockquote', 'address', 'hr', 'table', 'form', 'fieldset', 'br', 'span', 'em', 'strong', 'dfn', 'code', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'q', 'tt', 'i', 'b', 'big', 'small', 'sub', 'sup', 'bdo', 'a', 'img', 'map', 'object', 'input', 'select', 'textarea', 'label', 'button', 'ruby', 'ins', 'del', 'script', 'noscript'],
+\ { 'xmlns': ['http://www.w3.org/1999/xhtml'], 'headers': [], 'ondblclick': [], 'axis': [], 'dir': ['ltr', 'rtl'], 'onkeydown': [], 'abbr': [], 'onkeyup': [], 'rowspan': ['1'], 'colspan': ['1'], 'onmouseup': [], 'id': [], 'charoff': [], 'scope': ['row', 'col', 'rowgroup', 'colgroup'], 'onmouseover': [], 'align': ['left', 'center', 'right', 'justify', 'char'], 'valign': ['top', 'middle', 'bottom', 'baseline'], 'onmouseout': [], 'onmousemove': [], 'style': [], 'xml:lang': [], 'onkeypress': [], 'onmousedown': [], 'char': [], 'class': [], 'title': [], 'onclick': []}
+\ ],
+\ 'thead': [
+\ ['tr'],
+\ { 'xmlns': ['http://www.w3.org/1999/xhtml'], 'ondblclick': [], 'dir': ['ltr', 'rtl'], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'charoff': [], 'onmouseover': [], 'align': ['left', 'center', 'right', 'justify', 'char'], 'valign': ['top', 'middle', 'bottom', 'baseline'], 'onmouseout': [], 'onmousemove': [], 'style': [], 'xml:lang': [], 'char': [], 'onkeypress': [], 'onmousedown': [], 'class': [], 'title': [], 'onclick': []}
+\ ],
+\ 'title': [
+\ [''],
+\ { 'xmlns': ['http://www.w3.org/1999/xhtml'], 'dir': ['ltr', 'rtl'], 'xml:lang': []}
+\ ],
+\ 'tr': [
+\ ['th', 'td'],
+\ { 'xmlns': ['http://www.w3.org/1999/xhtml'], 'ondblclick': [], 'dir': ['ltr', 'rtl'], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'charoff': [], 'onmouseover': [], 'align': ['left', 'center', 'right', 'justify', 'char'], 'valign': ['top', 'middle', 'bottom', 'baseline'], 'onmouseout': [], 'onmousemove': [], 'style': [], 'xml:lang': [], 'char': [], 'onkeypress': [], 'onmousedown': [], 'class': [], 'title': [], 'onclick': []}
+\ ],
+\ 'tt': [
+\ ['br', 'span', 'em', 'strong', 'dfn', 'code', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'q', 'tt', 'i', 'b', 'big', 'small', 'sub', 'sup', 'bdo', 'a', 'img', 'map', 'object', 'input', 'select', 'textarea', 'label', 'button', 'ruby', 'ins', 'del', 'script', 'noscript'],
+\ { 'xmlns': ['http://www.w3.org/1999/xhtml'], 'ondblclick': [], 'dir': ['ltr', 'rtl'], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'style': [], 'onmousemove': [], 'onmouseout': [], 'xml:lang': [], 'onmousedown': [], 'onkeypress': [], 'onclick': [], 'title': [], 'class': []}
+\ ],
+\ 'ul': [
+\ ['li'],
+\ { 'xmlns': ['http://www.w3.org/1999/xhtml'], 'ondblclick': [], 'dir': ['ltr', 'rtl'], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'style': [], 'onmousemove': [], 'onmouseout': [], 'xml:lang': [], 'onmousedown': [], 'onkeypress': [], 'onclick': [], 'title': [], 'class': []}
+\ ],
+\ 'var': [
+\ ['br', 'span', 'em', 'strong', 'dfn', 'code', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'q', 'tt', 'i', 'b', 'big', 'small', 'sub', 'sup', 'bdo', 'a', 'img', 'map', 'object', 'input', 'select', 'textarea', 'label', 'button', 'ruby', 'ins', 'del', 'script', 'noscript'],
+\ { 'xmlns': ['http://www.w3.org/1999/xhtml'], 'ondblclick': [], 'dir': ['ltr', 'rtl'], 'onkeydown': [], 'onkeyup': [], 'onmouseup': [], 'id': [], 'onmouseover': [], 'style': [], 'onmousemove': [], 'onmouseout': [], 'xml:lang': [], 'onmousedown': [], 'onkeypress': [], 'onclick': [], 'title': [], 'class': []}
+\ ],
+\ 'vimxmlattrinfo' : {
+\ 'accept' : ['ContentType', ''],
+\ 'accesskey' : ['Character', ''],
+\ 'action' : ['*URI', ''],
+\ 'align' : ['String', ''],
+\ 'alt' : ['*Text', ''],
+\ 'archive' : ['UriList', ''],
+\ 'axis' : ['CDATA', ''],
+\ 'border' : ['Pixels', ''],
+\ 'cellpadding' : ['Length', ''],
+\ 'cellspacing' : ['Length', ''],
+\ 'char' : ['Character', ''],
+\ 'charoff' : ['Length', ''],
+\ 'charset' : ['LangCode', ''],
+\ 'checked' : ['Bool', ''],
+\ 'class' : ['CDATA', ''],
+\ 'codetype' : ['ContentType', ''],
+\ 'cols' : ['*Number', ''],
+\ 'colspan' : ['Number', ''],
+\ 'content' : ['*CDATA', ''],
+\ 'coords' : ['Coords', ''],
+\ 'data' : ['URI', ''],
+\ 'datetime' : ['DateTime', ''],
+\ 'declare' : ['Bool', ''],
+\ 'defer' : ['Bool', ''],
+\ 'dir' : ['String', ''],
+\ 'disabled' : ['Bool', ''],
+\ 'enctype' : ['ContentType', ''],
+\ 'for' : ['ID', ''],
+\ 'headers' : ['IDREFS', ''],
+\ 'height' : ['Number', ''],
+\ 'href' : ['*URI', ''],
+\ 'hreflang' : ['LangCode', ''],
+\ 'id' : ['ID', ''],
+\ 'ismap' : ['Bool', ''],
+\ 'label' : ['*Text', ''],
+\ 'lang' : ['LangCode', ''],
+\ 'longdesc' : ['URI', ''],
+\ 'maxlength' : ['Number', ''],
+\ 'media' : ['MediaDesc', ''],
+\ 'method' : ['String', ''],
+\ 'multiple' : ['Bool', ''],
+\ 'name' : ['CDATA', ''],
+\ 'nohref' : ['Bool', ''],
+\ 'onblur' : ['Script', ''],
+\ 'onchange' : ['Script', ''],
+\ 'onclick' : ['Script', ''],
+\ 'ondblclick' : ['Script', ''],
+\ 'onfocus' : ['Script', ''],
+\ 'onkeydown' : ['Script', ''],
+\ 'onkeypress' : ['Script', ''],
+\ 'onkeyup' : ['Script', ''],
+\ 'onload' : ['Script', ''],
+\ 'onmousedown' : ['Script', ''],
+\ 'onmousemove' : ['Script', ''],
+\ 'onmouseout' : ['Script', ''],
+\ 'onmouseover' : ['Script', ''],
+\ 'onmouseup' : ['Script', ''],
+\ 'onreset' : ['Script', ''],
+\ 'onselect' : ['Script', ''],
+\ 'onsubmit' : ['Script', ''],
+\ 'onunload' : ['Script', ''],
+\ 'profile' : ['URI', ''],
+\ 'readonly' : ['Bool', ''],
+\ 'rel' : ['LinkTypes', ''],
+\ 'rev' : ['LinkTypes', ''],
+\ 'rows' : ['*Number', ''],
+\ 'rules' : ['String', ''],
+\ 'scheme' : ['CDATA', ''],
+\ 'selected' : ['Bool', ''],
+\ 'shape' : ['Shape', ''],
+\ 'size' : ['CDATA', ''],
+\ 'span' : ['Number', ''],
+\ 'src' : ['*URI', ''],
+\ 'standby' : ['Text', ''],
+\ 'style' : ['StyleSheet', ''],
+\ 'summary' : ['*Text', ''],
+\ 'tabindex' : ['Number', ''],
+\ 'title' : ['Text', ''],
+\ 'type' : ['*ContentType', ''],
+\ 'usemap' : ['URI', ''],
+\ 'valign' : ['String', ''],
+\ 'valuetype' : ['String', ''],
+\ 'width' : ['Number', ''],
+\ 'xmlns' : ['URI', '']
+\ },
+\ 'vimxmltaginfo': {
+\ 'area': ['/>', ''],
+\ 'base': ['/>', ''],
+\ 'br': ['/>', ''],
+\ 'col': ['/>', ''],
+\ 'hr': ['/>', ''],
+\ 'img': ['/>', ''],
+\ 'input': ['/>', ''],
+\ 'link': ['/>', ''],
+\ 'meta': ['/>', ''],
+\ 'param': ['/>', ''],
+\ }
+\ }
+" vim:ft=vim:ff=unix
--- /dev/null
+++ b/lib/vimfiles/autoload/xml/xsd.vim
@@ -1,0 +1,130 @@
+" Author: Thomas Barthel
+" Last change: 2007 May 8
+let g:xmldata_xsd = {
+	\ 'schema': [
+		\ [ 'include', 'import', 'redefine', 'annotation', 'simpleType', 'complexType', 'element', 'attribute', 'attributeGroup', 'group', 'notation', 'annotation'],
+		\ { 'targetNamespace' : [], 'version' : [], 'xmlns' : [], 'finalDefault' : [], 'blockDefault' : [], 'id' : [], 'elementFormDefault' : [], 'attributeFormDefault' : [], 'xml:lang' : [] }],
+	\ 'redefine' : [
+		\ ['annotation', 'simpleType', 'complexType', 'attributeGroup', 'group'],
+		\ {'schemaLocation' : [], 'id' : []} ],
+	\ 'include' : [
+		\ ['annotation'],
+		\ {'namespace' : [], 'id' : []} ],
+	\ 'import' : [
+		\ ['annotation'],
+		\ {'namespace' : [], 'schemaLocation' : [], 'id' : []} ],
+	\ 'complexType' : [
+		\ ['annotation', 'simpleContent', 'complexContent', 'all', 'choice', 'sequence', 'group', 'attribute', 'attributeGroup', 'anyAttribute'],
+		\ {'name' : [], 'id' : [], 'abstract' : [], 'final' : [], 'block' : [], 'mixed' : []} ],
+	\ 'complexContent' : [
+		\ ['annotation', 'restriction', 'extension'],
+		\ {'mixed' : [], 'id' : [] } ],
+	\ 'simpleType' : [
+		\ ['annotation', 'restriction', 'list', 'union'],
+		\ {'name' : [], 'final' : [], 'id' : []} ],
+	\ 'simpleContent' : [
+		\ ['annotation', 'restriction', 'extension'],
+		\ {'id' : []} ],
+	\ 'element' : [
+		\ ['annotation', 'complexType', 'simpleType', 'unique', 'key', 'keyref'],
+		\ {'name' : [], 'id' : [], 'ref' : [], 'type' : [], 'minOccurs' : [], 'maxOccurs' : [], 'nillable' : [], 'substitutionGroup' : [], 'abstract' : [], 'final' : [], 'block' : [], 'default' : [], 'fixed' : [], 'form' : []} ],
+	\ 'attribute' : [
+		\ ['annotation', 'simpleType'],
+		\ {'name' : [], 'id' : [], 'ref' : [], 'type' : [], 'use' : [], 'default' : [], 'fixed' : [], 'form' : []} ],
+	\ 'group' : [
+		\ ['annotation', 'all', 'choice', 'sequence'],
+		\ {'name' : [], 'ref' : [], 'minOccurs' : [], 'maxOccurs' : [], 'id' : []} ],
+	\ 'choice' : [
+		\ ['annotation', 'element', 'group', 'choice', 'sequence', 'any'],
+		\ {'minOccurs' : [], 'maxOccurs' : [], 'id' : []} ],
+	\ 'sequence' : [
+		\ ['annotation', 'element', 'group', 'choice', 'sequence', 'any'],
+		\ {'minOccurs' : [], 'maxOccurs' : [], 'id' : []} ],
+	\ 'all' : [
+		\ ['annotation', 'element'],
+		\ {'minOccurs' : [], 'maxOccurs' : [], 'id' : []} ],
+	\ 'any' : [
+		\ ['annotation'],
+		\ {'namespace' : [], 'processContents' : [], 'minOccurs' : [], 'maxOccurs' : [], 'id' : []} ],
+	\ 'unique' : [
+		\ ['annotation', 'selector', 'field'],
+		\ {'name' : [],  'id' : []} ],
+	\ 'key' : [
+		\ ['annotation', 'selector', 'field'],
+		\ {'name' : [],  'id' : []} ],
+	\ 'keyref' : [
+		\ ['annotation', 'selector', 'field'],
+		\ {'name' : [], 'refer' : [], 'id' : []} ],
+	\ 'selector' : [
+		\ ['annotation'],
+		\ {'xpath' : [],  'id' : []} ],
+	\ 'field' : [
+		\ ['annotation'],
+		\ {'xpath' : [],  'id' : []} ],
+	\ 'restriction' : [
+		\ ['annotation', 'simpleType', 'minExclusive', 'maxExclusive', 'minInclusive', 'maxInclusive', 'totalDigits', 'fractionDigits', 'length', 'minLength', 'maxLength', 'enumeration', 'whiteSpace', 'pattern'],
+		\ {'base' : [], 'id' : []} ],
+	\ 'minExclusive' : [
+		\ ['annotation'],
+		\ {'value' : [], 'id' : [], 'fixed' : []}],
+	\ 'maxExclusive' : [
+		\ ['annotation'],
+		\ {'value' : [], 'id' : [], 'fixed' : []}],
+	\ 'minInclusive' : [
+		\ ['annotation'],
+		\ {'value' : [], 'id' : [], 'fixed' : []}],
+	\ 'maxInclusive' : [
+		\ ['annotation'],
+		\ {'value' : [], 'id' : [], 'fixed' : []}],
+	\ 'totalDigits' : [		
+	    \ ['annotation'],
+		\ {'value' : [], 'id' : [], 'fixed' : []}],
+	\ 'fractionDigits' : [
+		\ ['annotation'],
+		\ {'value' : [], 'id' : [], 'fixed' : []}],
+     \ 'length' : [
+     	\ ['annotation'],
+     	\ {'value' : [], 'id' : [], 'fixed' : []}],
+     \ 'minLength' : [
+     	\ ['annotation'],
+     	\ {'value' : [], 'id' : [], 'fixed' : []}],
+     \ 'maxLength' : [
+     	\ ['annotation'],
+     	\ {'value' : [], 'id' : [], 'fixed' : []}],
+     \ 'enumeration' : [
+     	\ ['annotation'],
+     	\ {'value' : [], 'id' : []}],
+     \ 'whiteSpace' : [
+     	\ ['annotation'],
+     	\ {'value' : [], 'id' : [], 'fixed' : []}],
+     \ 'pattern' : [
+     	\ ['annotation'],
+     	\ {'value' : [], 'id' : []}],
+     \ 'extension' : [
+     	\ ['annotation', 'all', 'choice', 'sequence', 'group', 'attribute', 'attributeGroup', 'anyAttribute'],
+		\ {'base' : [], 'id' : []} ],
+	 \ 'attributeGroup' : [
+	 	\ ['annotation', 'attribute', 'attributeGroup', 'anyAttribute'],
+	 	\ {'name' : [], 'id' : [], 'ref' : []} ],
+	 \ 'anyAttribute' : [
+	 	\ ['annotation'],
+	 	\ {'namespace' : [], 'processContents' : [], 'id' : []} ],
+	 \ 'list' : [
+		\ ['annotation', 'simpleType'],
+		\ {'itemType' : [], 'id' : []} ],
+	 \ 'union' : [
+	 	\ ['annotation', 'simpleType'],
+	 	\ {'id' : [], 'memberTypes' : []} ],
+	 \ 'notation' : [
+	 	\ ['annotation'],
+	 	\ {'name' : [], 'id' : [], 'public' : [], 'system' : []} ],
+	 \ 'annotation' : [
+	 	\ ['appinfo', 'documentation'],
+	 	\ {} ],
+	 \ 'appinfo' : [
+	 	\ [],
+	 	\ {'source' : [], 'id' : []} ],
+	 \ 'documentation' : [
+		\ [],
+		\ {'source' : [], 'id' : [], 'xml' : []} ]
+	\ }
--- /dev/null
+++ b/lib/vimfiles/autoload/xml/xsl.vim
@@ -1,0 +1,38 @@
+" Author: Mikolaj Machowski, Thomas Bartel
+" Last change: 2007 May 8
+let g:xmldata_xsl = {
+	\ 'apply-imports' : [[], {}],
+    \ 'apply-templates' : [['sort', 'with-param'], {'select' : [], 'mode' : []}],
+    \ 'attribute' : [['apply-imports', 'apply-templates', 'attribute', 'call-template', 'choose', 'comment', 'copy', 'copy-of', 'element', 'fallback', 'for-each', 'if', 'message', 'number', 'processing-instruction', 'text', 'value-of', 'variable'], {'name' : [], 'namespace' : []}],
+    \ 'attribute-set' : [['attribute'], {'name' : [], 'use-attribute-sets' : []}],
+    \ 'call-template' : [['with-param'], {'name' : []}],
+    \ 'choose' : [['when', 'otherwise'], {}],
+    \ 'comment' : [[], {}],
+    \ 'copy' : [[], {'use-attribute-sets' : []}],
+    \ 'copy-of' : [[], {'select' : []}],
+    \ 'decimal-format' : [[], {'name' : [], 'decimal-separator' : [], 'grouping-separator' : [], 'infinity' : [], 'minus-sign' : [], 'NaN' : [], 'percent' : [], 'per-mille' : [], 'zero-digit' : [], 'digit' : [], 'pattern-separator' : []}],
+    \ 'element' : [['apply-imports', 'apply-templates', 'attribute', 'call-template', 'choose', 'comment', 'copy', 'copy-of', 'element', 'fallback', 'for-each', 'if', 'message', 'number', 'processing-instruction', 'text', 'value-of', 'variable'], {'name' : [], 'namespace' : [], 'use-attribute-sets' : []}],
+    \ 'fallback' : [[], {}],
+    \ 'for-each' : [['sort'], {'select' : []}],
+    \ 'if' : [['apply-imports', 'apply-templates', 'attribute', 'call-template', 'choose', 'comment', 'copy', 'copy-of', 'element', 'fallback', 'for-each', 'if', 'message', 'number', 'processing-instruction', 'text', 'value-of', 'variable'], {'test' : []}],
+    \ 'import' : [[], {'href' : []}],
+    \ 'include' : [[], {'href' : []}],
+    \ 'key' : [[], {'name' : [], 'match' : [], 'use' : []}],
+    \ 'message' : [[], {'terminate' : ['yes', 'no']}],
+    \ 'namespace-alias' : [[], {'stylesheet-prefix' : ['#default'], 'result-prefix' : ['#default']}],
+    \ 'number' : [[], {'level' : ['single', 'multiple', 'any'], 'count' : [], 'from' : [], 'value' : [], 'format' : [], 'lang' : [], 'letter-value' : ['alphabetic', 'traditional'], 'grouping-separator' : [], 'grouping-size' : []}],
+    \ 'otherwise' : [[], {}],
+    \ 'output' : [[], {'method' : ['xml', 'html', 'text'], 'version' : [], 'encoding' : [], 'omit-xml-declaration' : ['yes', 'no'], 'standalone' : ['yes', 'no'], 'doctype-public' : [], 'doctype-system' : [], 'cdata-section-elements' : [], 'indent' : ['yes', 'no'], 'media-type' : []}],
+    \ 'param' : [['apply-imports', 'apply-templates', 'attribute', 'call-template', 'choose', 'comment', 'copy', 'copy-of', 'element', 'fallback', 'for-each', 'if', 'message', 'number', 'processing-instruction', 'text', 'value-of', 'variable'], {'name' : [], 'select' : []}],
+    \ 'preserve-space' : [[], {'elements' : []}],
+    \ 'processing-instructionruction' : [[], {'name' : []}],
+    \ 'sort' : [[], {'select' : [], 'lang' : [], 'data-type' : ['text', 'number'], 'order' : ['ascending', 'descending'], 'case-order' : ['upper-first', 'lower-first']}],
+    \ 'strip-space' : [[], {'elements' : []}],
+    \ 'stylesheet' : [['import', 'attribute-set', 'decimal-format', 'include', 'key', 'namespace-alias', 'output', 'param', 'preserve-space', 'strip-space', 'template'], {'id' : [], 'extension-element-prefixes' : [], 'version' : []}],
+    \ 'template' : [['apply-imports', 'apply-templates', 'attribute', 'call-template', 'choose', 'comment', 'copy', 'copy-of', 'element', 'fallback', 'for-each', 'if', 'message', 'number', 'processing-instruction', 'text', 'value-of', 'variable'], {'match' : [], 'name' : [], 'priority' : [], 'mode' : []}],
+    \ 'text' : [[], {'disable-output-escaping' : ['yes', 'no']}],
+    \ 'transform' : [['import', 'attribute-set', 'decimal-format', 'include', 'key', 'namespace-alias', 'output', 'param', 'preserve-space', 'strip-space', 'template'], {'id' : [], 'extension-element-prefixes' : [], 'exclude-result-prefixes' : [], 'version' : []}],
+    \ 'value-of' : [[], {'select' : [], 'disable-output-escaping' : ['yes', 'no']}],
+    \ 'variable' : [['apply-imports', 'apply-templates', 'attribute', 'call-template', 'choose', 'comment', 'copy', 'copy-of', 'element', 'fallback', 'for-each', 'if', 'message', 'number', 'processing-instruction', 'text', 'value-of', 'variable'], {'name' : [], 'select' : []}],
+    \ 'when' : [[], {'test' : []}],
+    \ 'with-param' : [['apply-imports', 'apply-templates', 'attribute', 'call-template', 'choose', 'comment', 'copy', 'copy-of', 'element', 'fallback', 'for-each', 'if', 'message', 'number', 'processing-instruction', 'text', 'value-of', 'variable'], {'name' : [], 'select' : []}]}
--- /dev/null
+++ b/lib/vimfiles/autoload/xmlcomplete.vim
@@ -1,0 +1,537 @@
+" Vim completion script
+" Language:	XML
+" Maintainer:	Mikolaj Machowski ( mikmach AT wp DOT pl )
+" Last Change:	2006 Jul 18
+" Version: 1.8
+"
+" Changelog:
+" 1.8 - 2006 Jul 18
+"       - allow for closing of xml tags even when data file isn't available
+
+" This function will create Dictionary with users namespace strings and values
+" canonical (system) names of data files.  Names should be lowercase,
+" descriptive to avoid any future conflicts. For example 'xhtml10s' should be
+" name for data of XHTML 1.0 Strict and 'xhtml10t' for XHTML 1.0 Transitional
+" User interface will be provided by XMLns command defined in ftplugin/xml.vim
+" Currently supported canonicals are:
+" xhtml10s - XHTML 1.0 Strict
+" xsl      - XSL
+function! xmlcomplete#CreateConnection(canonical, ...) " {{{
+
+	" When only one argument provided treat name as default namespace (without
+	" 'prefix:').
+	if exists("a:1")
+		let users = a:1
+	else
+		let users = 'DEFAULT'
+	endif
+
+	" Source data file. Due to suspected errors in autoload do it with
+	" :runtime.
+	" TODO: make it properly (using autoload, that is) later
+	exe "runtime autoload/xml/".a:canonical.".vim"
+
+	" Remove all traces of unexisting files to return [] when trying
+	" omnicomplete something
+	" TODO: give warning about non-existing canonicals - should it be?
+	if !exists("g:xmldata_".a:canonical)
+		unlet! g:xmldata_connection
+		return 0
+	endif
+
+	" We need to initialize Dictionary to add key-value pair
+	if !exists("g:xmldata_connection")
+		let g:xmldata_connection = {}
+	endif
+
+	let g:xmldata_connection[users] = a:canonical
+
+endfunction
+" }}}
+
+function! xmlcomplete#CreateEntConnection(...) " {{{
+	if a:0 > 0
+		let g:xmldata_entconnect = a:1
+	else
+		let g:xmldata_entconnect = 'DEFAULT'
+	endif
+endfunction
+" }}}
+
+function! xmlcomplete#CompleteTags(findstart, base)
+  if a:findstart
+    " locate the start of the word
+	let curline = line('.')
+    let line = getline('.')
+    let start = col('.') - 1
+	let compl_begin = col('.') - 2
+
+    while start >= 0 && line[start - 1] =~ '\(\k\|[:.-]\)'
+		let start -= 1
+    endwhile
+
+	if start >= 0 && line[start - 1] =~ '&'
+		let b:entitiescompl = 1
+		let b:compl_context = ''
+		return start
+	endif
+
+	let b:compl_context = getline('.')[0:(compl_begin)]
+	if b:compl_context !~ '<[^>]*$'
+		" Look like we may have broken tag. Check previous lines. Up to
+		" 10?
+		let i = 1
+		while 1
+			let context_line = getline(curline-i)
+			if context_line =~ '<[^>]*$'
+				" Yep, this is this line
+				let context_lines = getline(curline-i, curline-1) + [b:compl_context]
+				let b:compl_context = join(context_lines, ' ')
+				break
+			elseif context_line =~ '>[^<]*$' || i == curline
+				" Normal tag line, no need for completion at all
+				" OR reached first line without tag at all
+				let b:compl_context = ''
+				break
+			endif
+			let i += 1
+		endwhile
+		" Make sure we don't have counter
+		unlet! i
+	endif
+	let b:compl_context = matchstr(b:compl_context, '.*\zs<.*')
+
+	" Make sure we will have only current namespace
+	unlet! b:xml_namespace
+	let b:xml_namespace = matchstr(b:compl_context, '^<\zs\k*\ze:')
+	if b:xml_namespace == ''
+		let b:xml_namespace = 'DEFAULT'
+	endif
+
+    return start
+
+  else
+	" Initialize base return lists
+    let res = []
+    let res2 = []
+	" a:base is very short - we need context
+	if len(b:compl_context) == 0  && !exists("b:entitiescompl")
+		return []
+	endif
+	let context = matchstr(b:compl_context, '^<\zs.*')
+	unlet! b:compl_context
+	" There is no connection of namespace and data file.
+	if !exists("g:xmldata_connection") || g:xmldata_connection == {}
+		" There is still possibility we may do something - eg. close tag
+		let b:unaryTagsStack = "base meta link hr br param img area input col"
+		if context =~ '^\/'
+			let opentag = xmlcomplete#GetLastOpenTag("b:unaryTagsStack")
+			return [opentag.">"]
+		else
+			return []
+		endif
+	endif
+
+	" Make entities completion
+	if exists("b:entitiescompl")
+		unlet! b:entitiescompl
+
+		if !exists("g:xmldata_entconnect") || g:xmldata_entconnect == 'DEFAULT'
+			let values =  g:xmldata{'_'.g:xmldata_connection['DEFAULT']}['vimxmlentities']
+		else
+			let values =  g:xmldata{'_'.g:xmldata_entconnect}['vimxmlentities']
+		endif
+
+		" Get only lines with entity declarations but throw out
+		" parameter-entities - they may be completed in future
+		let entdecl = filter(getline(1, "$"), 'v:val =~ "<!ENTITY\\s\\+[^%]"')
+
+		if len(entdecl) > 0
+			let intent = map(copy(entdecl), 'matchstr(v:val, "<!ENTITY\\s\\+\\zs\\(\\k\\|[.-:]\\)\\+\\ze")')
+			let values = intent + values
+		endif
+
+		if len(a:base) == 1
+			for m in values
+				if m =~ '^'.a:base
+					call add(res, m.';')
+				endif
+			endfor
+			return res
+		else
+			for m in values
+				if m =~? '^'.a:base
+					call add(res, m.';')
+				elseif m =~? a:base
+					call add(res2, m.';')
+				endif
+			endfor
+
+			return res + res2
+		endif
+
+	endif
+	if context =~ '>'
+		" Generally if context contains > it means we are outside of tag and
+		" should abandon action
+		return []
+	endif
+
+    " find tags matching with "a:base"
+	" If a:base contains white space it is attribute.
+	" It could be also value of attribute...
+	" We have to get first word to offer
+	" proper completions
+	if context == ''
+		let tag = ''
+	else
+		let tag = split(context)[0]
+	endif
+	" Get rid of namespace
+	let tag = substitute(tag, '^'.b:xml_namespace.':', '', '')
+
+
+	" Get last word, it should be attr name
+	let attr = matchstr(context, '.*\s\zs.*')
+	" Possible situations where any prediction would be difficult:
+	" 1. Events attributes
+	if context =~ '\s'
+
+		" If attr contains =\s*[\"'] we catched value of attribute
+		if attr =~ "=\s*[\"']" || attr =~ "=\s*$"
+			" Let do attribute specific completion
+			let attrname = matchstr(attr, '.*\ze\s*=')
+			let entered_value = matchstr(attr, ".*=\\s*[\"']\\?\\zs.*")
+
+			if tag =~ '^[?!]'
+				" Return nothing if we are inside of ! or ? tag
+				return []
+			else
+				if has_key(g:xmldata{'_'.g:xmldata_connection[b:xml_namespace]}, tag) && has_key(g:xmldata{'_'.g:xmldata_connection[b:xml_namespace]}[tag][1], attrname)
+					let values = g:xmldata{'_'.g:xmldata_connection[b:xml_namespace]}[tag][1][attrname]
+				else
+					return []
+				endif
+			endif
+
+			if len(values) == 0
+				return []
+			endif
+
+			" We need special version of sbase
+			let attrbase = matchstr(context, ".*[\"']")
+			let attrquote = matchstr(attrbase, '.$')
+			if attrquote !~ "['\"]"
+				let attrquoteopen = '"'
+				let attrquote = '"'
+			else
+				let attrquoteopen = ''
+			endif
+
+			for m in values
+				" This if is needed to not offer all completions as-is
+				" alphabetically but sort them. Those beginning with entered
+				" part will be as first choices
+				if m =~ '^'.entered_value
+					call add(res, attrquoteopen . m . attrquote.' ')
+				elseif m =~ entered_value
+					call add(res2, attrquoteopen . m . attrquote.' ')
+				endif
+			endfor
+
+			return res + res2
+
+		endif
+
+		if tag =~ '?xml'
+			" Two possible arguments for <?xml> plus variation
+			let attrs = ['encoding', 'version="1.0"', 'version']
+		elseif tag =~ '^!'
+			" Don't make completion at all
+			"
+			return []
+		else
+            if !has_key(g:xmldata{'_'.g:xmldata_connection[b:xml_namespace]}, tag)
+				" Abandon when data file isn't complete
+ 				return []
+ 			endif
+			let attrs = keys(g:xmldata{'_'.g:xmldata_connection[b:xml_namespace]}[tag][1])
+		endif
+
+		for m in sort(attrs)
+			if m =~ '^'.attr
+				call add(res, m)
+			elseif m =~ attr
+				call add(res2, m)
+			endif
+		endfor
+		let menu = res + res2
+		let final_menu = []
+		if has_key(g:xmldata{'_'.g:xmldata_connection[b:xml_namespace]}, 'vimxmlattrinfo')
+			for i in range(len(menu))
+				let item = menu[i]
+				if has_key(g:xmldata{'_'.g:xmldata_connection[b:xml_namespace]}['vimxmlattrinfo'], item)
+					let m_menu = g:xmldata{'_'.g:xmldata_connection[b:xml_namespace]}['vimxmlattrinfo'][item][0]
+					let m_info = g:xmldata{'_'.g:xmldata_connection[b:xml_namespace]}['vimxmlattrinfo'][item][1]
+				else
+					let m_menu = ''
+					let m_info = ''
+				endif
+				if tag !~ '^[?!]' && len(g:xmldata{'_'.g:xmldata_connection[b:xml_namespace]}[tag][1][item]) > 0 && g:xmldata{'_'.g:xmldata_connection[b:xml_namespace]}[tag][1][item][0] =~ '^\(BOOL\|'.item.'\)$'
+					let item = item
+				else
+					let item .= '="'
+				endif
+				let final_menu += [{'word':item, 'menu':m_menu, 'info':m_info}]
+			endfor
+		else
+			for i in range(len(menu))
+				let item = menu[i]
+				if tag !~ '^[?!]' && len(g:xmldata{'_'.g:xmldata_connection[b:xml_namespace]}[tag][1][item]) > 0 && g:xmldata{'_'.g:xmldata_connection[b:xml_namespace]}[tag][1][item][0] =~ '^\(BOOL\|'.item.'\)$'
+					let item = item
+				else
+					let item .= '="'
+				endif
+				let final_menu += [item]
+			endfor
+		endif
+		return final_menu
+
+	endif
+	" Close tag
+	let b:unaryTagsStack = "base meta link hr br param img area input col"
+	if context =~ '^\/'
+		let opentag = xmlcomplete#GetLastOpenTag("b:unaryTagsStack")
+		return [opentag.">"]
+	endif
+
+	" Complete elements of XML structure
+	" TODO: #REQUIRED, #IMPLIED, #FIXED, #PCDATA - but these should be detected like
+	" entities - in first run
+	" keywords: CDATA, ID, IDREF, IDREFS, ENTITY, ENTITIES, NMTOKEN, NMTOKENS
+	" are hardly recognizable but keep it in reserve
+	" also: EMPTY ANY SYSTEM PUBLIC DATA
+	if context =~ '^!'
+		let tags = ['!ELEMENT', '!DOCTYPE', '!ATTLIST', '!ENTITY', '!NOTATION', '![CDATA[', '![INCLUDE[', '![IGNORE[']
+
+		for m in tags
+			if m =~ '^'.context
+				let m = substitute(m, '^!\[\?', '', '')
+				call add(res, m)
+			elseif m =~ context
+				let m = substitute(m, '^!\[\?', '', '')
+				call add(res2, m)
+			endif
+		endfor
+
+		return res + res2
+
+	endif
+
+	" Complete text declaration
+	if context =~ '^?'
+		let tags = ['?xml']
+
+		for m in tags
+			if m =~ '^'.context
+				call add(res, substitute(m, '^?', '', ''))
+			elseif m =~ context
+				call add(res, substitute(m, '^?', '', ''))
+			endif
+		endfor
+
+		return res + res2
+
+	endif
+
+	" Deal with tag completion.
+	let opentag = xmlcomplete#GetLastOpenTag("b:unaryTagsStack")
+	let opentag = substitute(opentag, '^\k*:', '', '')
+	if opentag == ''
+		"return []
+	    let tags = keys(g:xmldata{'_'.g:xmldata_connection[b:xml_namespace]})
+		call filter(tags, 'v:val !~ "^vimxml"')
+	else
+		if !has_key(g:xmldata{'_'.g:xmldata_connection[b:xml_namespace]}, opentag)
+			" Abandon when data file isn't complete
+			return []
+		endif
+		let tags = g:xmldata{'_'.g:xmldata_connection[b:xml_namespace]}[opentag][0]
+	endif
+
+	let context = substitute(context, '^\k*:', '', '')
+
+	for m in tags
+		if m =~ '^'.context
+			call add(res, m)
+		elseif m =~ context
+			call add(res2, m)
+		endif
+	endfor
+	let menu = res + res2
+	if b:xml_namespace == 'DEFAULT'
+		let xml_namespace = ''
+	else
+		let xml_namespace = b:xml_namespace.':'
+	endif
+	if has_key(g:xmldata{'_'.g:xmldata_connection[b:xml_namespace]}, 'vimxmltaginfo')
+		let final_menu = []
+		for i in range(len(menu))
+			let item = menu[i]
+			if has_key(g:xmldata{'_'.g:xmldata_connection[b:xml_namespace]}['vimxmltaginfo'], item)
+				let m_menu = g:xmldata{'_'.g:xmldata_connection[b:xml_namespace]}['vimxmltaginfo'][item][0]
+				let m_info = g:xmldata{'_'.g:xmldata_connection[b:xml_namespace]}['vimxmltaginfo'][item][1]
+			else
+				let m_menu = ''
+				let m_info = ''
+			endif
+			let final_menu += [{'word':xml_namespace.item, 'menu':m_menu, 'info':m_info}]
+		endfor
+	else
+		let final_menu = map(menu, 'xml_namespace.v:val')
+	endif
+
+	return final_menu
+
+  endif
+endfunction
+
+" MM: This is severely reduced closetag.vim used with kind permission of Steven
+"     Mueller
+"     Changes: strip all comments; delete error messages; add checking for
+"     namespace
+" Author: Steven Mueller <diffusor@ugcs.caltech.edu>
+" Last Modified: Tue May 24 13:29:48 PDT 2005 
+" Version: 0.9.1
+
+function! xmlcomplete#GetLastOpenTag(unaryTagsStack)
+	let linenum=line('.')
+	let lineend=col('.') - 1 " start: cursor position
+	let first=1              " flag for first line searched
+	let b:TagStack=''        " main stack of tags
+	let startInComment=s:InComment()
+
+	if exists("b:xml_namespace")
+		if b:xml_namespace == 'DEFAULT'
+			let tagpat='</\=\(\k\|[.-]\)\+\|/>'
+		else
+			let tagpat='</\='.b:xml_namespace.':\(\k\|[.-]\)\+\|/>'
+		endif
+	else
+		let tagpat='</\=\(\k\|[.-]\)\+\|/>'
+	endif
+	while (linenum>0)
+		let line=getline(linenum)
+		if first
+			let line=strpart(line,0,lineend)
+		else
+			let lineend=strlen(line)
+		endif
+		let b:lineTagStack=''
+		let mpos=0
+		let b:TagCol=0
+		while (mpos > -1)
+			let mpos=matchend(line,tagpat)
+			if mpos > -1
+				let b:TagCol=b:TagCol+mpos
+				let tag=matchstr(line,tagpat)
+
+				if exists('b:closetag_disable_synID') || startInComment==s:InCommentAt(linenum, b:TagCol)
+					let b:TagLine=linenum
+					call s:Push(matchstr(tag,'[^<>]\+'),'b:lineTagStack')
+				endif
+				let lineend=lineend-mpos
+				let line=strpart(line,mpos,lineend)
+			endif
+		endwhile
+		while (!s:EmptystackP('b:lineTagStack'))
+			let tag=s:Pop('b:lineTagStack')
+			if match(tag, '^/') == 0		"found end tag
+				call s:Push(tag,'b:TagStack')
+			elseif s:EmptystackP('b:TagStack') && !s:Instack(tag, a:unaryTagsStack)	"found unclosed tag
+				return tag
+			else
+				let endtag=s:Peekstack('b:TagStack')
+				if endtag == '/'.tag || endtag == '/'
+					call s:Pop('b:TagStack')	"found a open/close tag pair
+				elseif !s:Instack(tag, a:unaryTagsStack) "we have a mismatch error
+					return ''
+				endif
+			endif
+		endwhile
+		let linenum=linenum-1 | let first=0
+	endwhile
+return ''
+endfunction
+
+function! s:InComment()
+	return synIDattr(synID(line('.'), col('.'), 0), 'name') =~ 'Comment\|String'
+endfunction
+
+function! s:InCommentAt(line, col)
+	return synIDattr(synID(a:line, a:col, 0), 'name') =~ 'Comment\|String'
+endfunction
+
+function! s:SetKeywords()
+	let g:IsKeywordBak=&iskeyword
+	let &iskeyword='33-255'
+endfunction
+
+function! s:RestoreKeywords()
+	let &iskeyword=g:IsKeywordBak
+endfunction
+
+function! s:Push(el, sname)
+	if !s:EmptystackP(a:sname)
+		exe 'let '.a:sname."=a:el.' '.".a:sname
+	else
+		exe 'let '.a:sname.'=a:el'
+	endif
+endfunction
+
+function! s:EmptystackP(sname)
+	exe 'let stack='.a:sname
+	if match(stack,'^ *$') == 0
+		return 1
+	else
+		return 0
+	endif
+endfunction
+
+function! s:Instack(el, sname)
+	exe 'let stack='.a:sname
+	call s:SetKeywords()
+	let m=match(stack, '\<'.a:el.'\>')
+	call s:RestoreKeywords()
+	if m < 0
+		return 0
+	else
+		return 1
+	endif
+endfunction
+
+function! s:Peekstack(sname)
+	call s:SetKeywords()
+	exe 'let stack='.a:sname
+	let top=matchstr(stack, '\<.\{-1,}\>')
+	call s:RestoreKeywords()
+	return top
+endfunction
+
+function! s:Pop(sname)
+	if s:EmptystackP(a:sname)
+		return ''
+	endif
+	exe 'let stack='.a:sname
+	call s:SetKeywords()
+	let loc=matchend(stack,'\<.\{-1,}\>')
+	exe 'let '.a:sname.'=strpart(stack, loc+1, strlen(stack))'
+	let top=strpart(stack, match(stack, '\<'), loc)
+	call s:RestoreKeywords()
+	return top
+endfunction
+
+function! s:Clearstack(sname)
+	exe 'let '.a:sname."=''"
+endfunction
+" vim:set foldmethod=marker:
--- /dev/null
+++ b/lib/vimfiles/autoload/zip.vim
@@ -1,0 +1,373 @@
+" zip.vim: Handles browsing zipfiles
+"            AUTOLOAD PORTION
+" Date:		May 08, 2007
+" Version:	14
+" Maintainer:	Charles E Campbell, Jr <NdrOchip@ScampbellPfamily.AbizM-NOSPAM>
+" License:	Vim License  (see vim's :help license)
+" Copyright:    Copyright (C) 2005 Charles E. Campbell, Jr. {{{1
+"               Permission is hereby granted to use and distribute this code,
+"               with or without modifications, provided that this copyright
+"               notice is copied with it. Like anything else that's free,
+"               zipPlugin.vim is provided *as is* and comes with no warranty
+"               of any kind, either expressed or implied. By using this
+"               plugin, you agree that in no event will the copyright
+"               holder be liable for any damages resulting from the use
+"               of this software.
+
+" ---------------------------------------------------------------------
+" Load Once: {{{1
+let s:keepcpo= &cpo
+set cpo&vim
+if &cp || exists("g:loaded_zip") || v:version < 700
+ finish
+endif
+
+let g:loaded_zip     = "v14"
+let s:zipfile_escape = ' ?&;\'
+let s:ERROR          = 2
+let s:WARNING        = 1
+let s:NOTE           = 0
+
+" ---------------------------------------------------------------------
+"  Global Values: {{{1
+if !exists("g:zip_shq")
+ if has("unix")
+  let g:zip_shq= "'"
+ else
+  let g:zip_shq= '"'
+ endif
+endif
+if !exists("g:zip_zipcmd")
+ let g:zip_zipcmd= "zip"
+endif
+if !exists("g:zip_unzipcmd")
+ let g:zip_unzipcmd= "unzip"
+endif
+
+" ----------------
+"  Functions: {{{1
+" ----------------
+
+" ---------------------------------------------------------------------
+" zip#Browse: {{{2
+fun! zip#Browse(zipfile)
+"  call Dfunc("zip#Browse(zipfile<".a:zipfile.">)")
+  let repkeep= &report
+  set report=10
+
+  " sanity checks
+  if !executable(g:zip_unzipcmd)
+   redraw!
+   echohl Error | echo "***error*** (zip#Browse) unzip not available on your system"
+"   call inputsave()|call input("Press <cr> to continue")|call inputrestore()
+   let &report= repkeep
+"   call Dret("zip#Browse")
+   return
+  endif
+  if !filereadable(a:zipfile)
+   if a:zipfile !~# '^\a\+://'
+    " if its an url, don't complain, let url-handlers such as vim do its thing
+    redraw!
+    echohl Error | echo "***error*** (zip#Browse) File not readable<".a:zipfile.">" | echohl None
+"    call inputsave()|call input("Press <cr> to continue")|call inputrestore()
+   endif
+   let &report= repkeep
+"   call Dret("zip#Browse : file<".a:zipfile."> not readable")
+   return
+  endif
+"  call Decho("passed sanity checks")
+  if &ma != 1
+   set ma
+  endif
+  let b:zipfile= a:zipfile
+
+  setlocal noswapfile
+  setlocal buftype=nofile
+  setlocal bufhidden=hide
+  setlocal nobuflisted
+  setlocal nowrap
+  set ft=tar
+
+  " give header
+  exe "$put ='".'\"'." zip.vim version ".g:loaded_zip."'"
+  exe "$put ='".'\"'." Browsing zipfile ".a:zipfile."'"
+  exe "$put ='".'\"'." Select a file with cursor and press ENTER"."'"
+  $put =''
+  0d
+  $
+
+"  call Decho("exe silent r! ".g:zip_unzipcmd." -l ".s:QuoteFileDir(a:zipfile))
+  exe "silent r! ".g:zip_unzipcmd." -l ".s:QuoteFileDir(a:zipfile)
+  if v:shell_error != 0
+   redraw!
+   echohl WarningMsg | echo "***warning*** (zip#Browse) ".a:zipfile." is not a zip file" | echohl None
+"   call inputsave()|call input("Press <cr> to continue")|call inputrestore()
+   silent %d
+   let eikeep= &ei
+   set ei=BufReadCmd,FileReadCmd
+   exe "r ".a:zipfile
+   let &ei= eikeep
+   1d
+"   call Dret("zip#Browse")
+   return
+  endif
+"  call Decho("line 6: ".getline(6))
+  let namecol= stridx(getline(6),'Name') + 1
+"  call Decho("namecol=".namecol)
+  4,$g/^\s*----/d
+  4,$g/^\s*\a/d
+  $d
+  if namecol > 0
+   exe 'silent 4,$s/^.*\%'.namecol.'c//'
+  endif
+
+  setlocal noma nomod ro
+  noremap <silent> <buffer> <cr> :call <SID>ZipBrowseSelect()<cr>
+
+  let &report= repkeep
+"  call Dret("zip#Browse")
+endfun
+
+" ---------------------------------------------------------------------
+" ZipBrowseSelect: {{{2
+fun! s:ZipBrowseSelect()
+"  call Dfunc("ZipBrowseSelect() zipfile<".b:zipfile."> curfile<".expand("%").">")
+  let repkeep= &report
+  set report=10
+  let fname= getline(".")
+
+  " sanity check
+  if fname =~ '^"'
+   let &report= repkeep
+"   call Dret("ZipBrowseSelect")
+   return
+  endif
+  if fname =~ '/$'
+   redraw!
+   echohl Error | echo "***error*** (zip#Browse) Please specify a file, not a directory" | echohl None
+"   call inputsave()|call input("Press <cr> to continue")|call inputrestore()
+   let &report= repkeep
+"   call Dret("ZipBrowseSelect")
+   return
+  endif
+
+"  call Decho("fname<".fname.">")
+
+  " get zipfile to the new-window
+  let zipfile = b:zipfile
+  let curfile= expand("%")
+"  call Decho("zipfile<".zipfile.">")
+"  call Decho("curfile<".curfile.">")
+
+  new
+  wincmd _
+  let s:zipfile_{winnr()}= curfile
+"  call Decho("exe e zipfile:".escape(zipfile,s:zipfile_escape).'::'.escape(fname,s:zipfile_escape))
+  exe "e zipfile:".escape(zipfile,s:zipfile_escape).'::'.escape(fname,s:zipfile_escape)
+  filetype detect
+
+  let &report= repkeep
+"  call Dret("ZipBrowseSelect : s:zipfile_".winnr()."<".s:zipfile_{winnr()}.">")
+endfun
+
+" ---------------------------------------------------------------------
+" zip#Read: {{{2
+fun! zip#Read(fname,mode)
+"  call Dfunc("zip#Read(fname<".a:fname.">,mode=".a:mode.")")
+  let repkeep= &report
+  set report=10
+
+  if has("unix")
+   let zipfile = substitute(a:fname,'zipfile:\(.\{-}\)::[^\\].*$','\1','')
+   let fname   = substitute(a:fname,'zipfile:.\{-}::\([^\\].*\)$','\1','')
+  else
+   let zipfile = substitute(a:fname,'^.\{-}zipfile:\(.\{-}\)::[^\\].*$','\1','')
+   let fname   = substitute(a:fname,'^.\{-}zipfile:.\{-}::\([^\\].*\)$','\1','')
+   let fname = substitute(fname, '[', '[[]', 'g')
+  endif
+"  call Decho("zipfile<".zipfile.">")
+"  call Decho("fname  <".fname.">")
+
+"  call Decho("exe r! ".g:zip_unzipcmd." -p ".s:QuoteFileDir(zipfile)." ".s:QuoteFileDir(fname))
+  exe "silent r! ".g:zip_unzipcmd." -p ".s:QuoteFileDir(zipfile)." ".s:QuoteFileDir(fname)
+
+  " cleanup
+  0d
+  set nomod
+
+  let &report= repkeep
+"  call Dret("zip#Read")
+endfun
+
+" ---------------------------------------------------------------------
+" zip#Write: {{{2
+fun! zip#Write(fname)
+"  call Dfunc("zip#Write(fname<".a:fname.">) zipfile_".winnr()."<".s:zipfile_{winnr()}.">")
+  let repkeep= &report
+  set report=10
+
+  " sanity checks
+  if !executable(g:zip_zipcmd)
+   redraw!
+   echohl Error | echo "***error*** (zip#Write) sorry, your system doesn't appear to have the zip pgm" | echohl None
+"   call inputsave()|call input("Press <cr> to continue")|call inputrestore()
+   let &report= repkeep
+"   call Dret("zip#Write")
+   return
+  endif
+  if !exists("*mkdir")
+   redraw!
+   echohl Error | echo "***error*** (zip#Write) sorry, mkdir() doesn't work on your system" | echohl None
+"   call inputsave()|call input("Press <cr> to continue")|call inputrestore()
+   let &report= repkeep
+"   call Dret("zip#Write")
+   return
+  endif
+
+  let curdir= getcwd()
+  let tmpdir= tempname()
+"  call Decho("orig tempname<".tmpdir.">")
+  if tmpdir =~ '\.'
+   let tmpdir= substitute(tmpdir,'\.[^.]*$','','e')
+  endif
+"  call Decho("tmpdir<".tmpdir.">")
+  call mkdir(tmpdir,"p")
+
+  " attempt to change to the indicated directory
+  if s:ChgDir(tmpdir,s:ERROR,"(zip#Write) cannot cd to temporary directory")
+   let &report= repkeep
+"   call Dret("zip#Write")
+   return
+  endif
+"  call Decho("current directory now: ".getcwd())
+
+  " place temporary files under .../_ZIPVIM_/
+  if isdirectory("_ZIPVIM_")
+   call s:Rmdir("_ZIPVIM_")
+  endif
+  call mkdir("_ZIPVIM_")
+  cd _ZIPVIM_
+"  call Decho("current directory now: ".getcwd())
+
+  if has("unix")
+   let zipfile = substitute(a:fname,'zipfile:\(.\{-}\)::[^\\].*$','\1','')
+   let fname   = substitute(a:fname,'zipfile:.\{-}::\([^\\].*\)$','\1','')
+  else
+   let zipfile = substitute(a:fname,'^.\{-}zipfile:\(.\{-}\)::[^\\].*$','\1','')
+   let fname   = substitute(a:fname,'^.\{-}zipfile:.\{-}::\([^\\].*\)$','\1','')
+  endif
+"  call Decho("zipfile<".zipfile.">")
+"  call Decho("fname  <".fname.">")
+
+  if fname =~ '/'
+   let dirpath = substitute(fname,'/[^/]\+$','','e')
+   if executable("cygpath")
+    let dirpath = substitute(system("cygpath ".dirpath),'\n','','e')
+   endif
+"   call Decho("mkdir(dirpath<".dirpath.">,p)")
+   call mkdir(dirpath,"p")
+  endif
+  if zipfile !~ '/'
+   let zipfile= curdir.'/'.zipfile
+  endif
+"  call Decho("zipfile<".zipfile."> fname<".fname.">")
+
+  exe "w! ".escape(fname,s:zipfile_escape)
+  if executable("cygpath")
+   let zipfile = substitute(system("cygpath ".zipfile),'\n','','e')
+  endif
+
+  if (has("win32") || has("win95") || has("win64") || has("win16")) && &shell !~? 'sh$'
+    let fname = substitute(fname, '[', '[[]', 'g')
+  endif
+
+"  call Decho(g:zip_zipcmd." -u ".s:QuoteFileDir(zipfile)." ".s:QuoteFileDir(fname))
+  call system(g:zip_zipcmd." -u ".s:QuoteFileDir(zipfile)." ".s:QuoteFileDir(fname))
+  if v:shell_error != 0
+   redraw!
+   echohl Error | echo "***error*** (zip#Write) sorry, unable to update ".zipfile." with ".fname | echohl None
+"   call inputsave()|call input("Press <cr> to continue")|call inputrestore()
+
+  elseif s:zipfile_{winnr()} =~ '^\a\+://'
+   " support writing zipfiles across a network
+   let netzipfile= s:zipfile_{winnr()}
+"   call Decho("handle writing <".zipfile."> across network as <".netzipfile.">")
+   1split|enew
+   let binkeep= &binary
+   let eikeep = &ei
+   set binary ei=all
+   exe "e! ".zipfile
+   call netrw#NetWrite(netzipfile)
+   let &ei     = eikeep
+   let &binary = binkeep
+   q!
+   unlet s:zipfile_{winnr()}
+  endif
+  
+  " cleanup and restore current directory
+  cd ..
+  call s:Rmdir("_ZIPVIM_")
+  call s:ChgDir(curdir,s:WARNING,"(zip#Write) unable to return to ".curdir."!")
+  call s:Rmdir(tmpdir)
+  setlocal nomod
+
+  let &report= repkeep
+"  call Dret("zip#Write")
+endfun
+
+" ---------------------------------------------------------------------
+" QuoteFileDir: {{{2
+fun! s:QuoteFileDir(fname)
+"  call Dfunc("QuoteFileDir(fname<".a:fname.">)")
+"  call Dret("QuoteFileDir")
+  return g:zip_shq.a:fname.g:zip_shq
+endfun
+
+" ---------------------------------------------------------------------
+" ChgDir: {{{2
+fun! s:ChgDir(newdir,errlvl,errmsg)
+"  call Dfunc("ChgDir(newdir<".a:newdir."> errlvl=".a:errlvl."  errmsg<".a:errmsg.">)")
+
+  if (has("win32") || has("win95") || has("win64") || has("win16")) && &shell !~? 'sh$'
+   let newdir= escape(a:newdir,' ')
+  else
+   let newdir= escape(a:newdir,'\ ')
+  endif
+
+  try
+   exe "cd ".newdir
+  catch /^Vim\%((\a\+)\)\=:E344/
+   redraw!
+   if a:errlvl == s:NOTE
+    echo "***note*** ".a:errmsg
+   elseif a:errlvl == s:WARNING
+    echohl WarningMsg | echo "***warning*** ".a:errmsg | echohl NONE
+   elseif a:errlvl == s:ERROR
+    echohl Error | echo "***error*** ".a:errmsg | echohl NONE
+   endif
+"   call inputsave()|call input("Press <cr> to continue")|call inputrestore()
+"   call Dret("ChgDir 1")
+   return 1
+  endtry
+
+"  call Dret("ChgDir 0")
+  return 0
+endfun
+
+" ---------------------------------------------------------------------
+" Rmdir: {{{2
+fun! s:Rmdir(fname)
+"  call Dfunc("Rmdir(fname<".a:fname.">)")
+  if (has("win32") || has("win95") || has("win64") || has("win16")) && &shell !~? 'sh$'
+   call system("rmdir /S/Q ".s:QuoteFileDir(a:fname))
+  else
+   call system("/bin/rm -rf ".s:QuoteFileDir(a:fname))
+  endif
+"  call Dret("Rmdir")
+endfun
+
+" ------------------------------------------------------------------------
+" Modelines And Restoration: {{{1
+let &cpo= s:keepcpo
+unlet s:keepcpo
+" vim:ts=8 fdm=marker
--- /dev/null
+++ b/lib/vimfiles/bugreport.vim
@@ -1,0 +1,88 @@
+:" Use this script to create the file "bugreport.txt", which contains
+:" information about the environment of a possible bug in Vim.
+:"
+:" Maintainer:	Bram Moolenaar <Bram@vim.org>
+:" Last change:	2005 Jun 12
+:"
+:" To use inside Vim:
+:"	:so $VIMRUNTIME/bugreport.vim
+:" Or, from the command line:
+:"	vim -s $VIMRUNTIME/bugreport.vim
+:"
+:" The "if 1" lines are to avoid error messages when expression evaluation is
+:" not compiled in.
+:"
+:if 1
+:  let more_save = &more
+:endif
+:set nomore
+:if has("unix")
+:  !echo "uname -a" >bugreport.txt
+:  !uname -a >>bugreport.txt
+:endif
+:redir >>bugreport.txt
+:version
+:if 1
+:  func <SID>CheckDir(n)
+:    if isdirectory(a:n)
+:      echo 'directory "' . a:n . '" exists'
+:    else
+:      echo 'directory "' . a:n . '" does NOT exist'
+:    endif
+:  endfun
+:  func <SID>CheckFile(n)
+:    if filereadable(a:n)
+:      echo '"' . a:n . '" is readable'
+:    else
+:      echo '"' . a:n . '" is NOT readable'
+:    endif
+:  endfun
+:  echo "--- Directories and Files ---"
+:  echo '$VIM = "' . $VIM . '"'
+:  call <SID>CheckDir($VIM)
+:  echo '$VIMRUNTIME = "' . $VIMRUNTIME . '"'
+:  call <SID>CheckDir($VIMRUNTIME)
+:  call <SID>CheckFile(&helpfile)
+:  call <SID>CheckFile(fnamemodify(&helpfile, ":h") . "/tags")
+:  call <SID>CheckFile($VIMRUNTIME . "/menu.vim")
+:  call <SID>CheckFile($VIMRUNTIME . "/filetype.vim")
+:  call <SID>CheckFile($VIMRUNTIME . "/syntax/synload.vim")
+:  delfun <SID>CheckDir
+:  delfun <SID>CheckFile
+:  echo "--- Scripts sourced ---"
+:  scriptnames
+:endif
+:set all
+:set termcap
+:if has("autocmd")
+:  au
+:endif
+:if 1
+:  echo "--- Normal/Visual mode mappings ---"
+:endif
+:map
+:if 1
+:  echo "--- Insert/Command-line mode mappings ---"
+:endif
+:map!
+:if 1
+:  echo "--- Abbreviations ---"
+:endif
+:ab
+:if 1
+:  echo "--- Highlighting ---"
+:endif
+:highlight
+:if 1
+:  echo "--- Variables ---"
+:endif
+:if 1
+:  let
+:endif
+:redir END
+:set more&
+:if 1
+:  let &more = more_save
+:  unlet more_save
+:endif
+:e bugreport.txt
--- /dev/null
+++ b/lib/vimfiles/colors/README.txt
@@ -1,0 +1,61 @@
+README.txt for color scheme files
+
+These files are used for the ":colorscheme" command.  They appear in the
+Edit/Color Scheme menu in the GUI.
+
+
+Hints for writing a color scheme file:
+
+There are two basic ways to define a color scheme:
+
+1. Define a new Normal color and set the 'background' option accordingly.
+	set background={light or dark}
+	highlight clear
+	highlight Normal ...
+	...
+
+2. Use the default Normal color and automatically adjust to the value of
+   'background'.
+	highlight clear Normal
+	set background&
+	highlight clear
+	if &background == "light"
+	  highlight Error ...
+	  ...
+	else
+	  highlight Error ...
+	  ...
+	endif
+
+You can use ":highlight clear" to reset everything to the defaults, and then
+change the groups that you want differently.  This also will work for groups
+that are added in later versions of Vim.
+Note that ":highlight clear" uses the value of 'background', thus set it
+before this command.
+Some attributes (e.g., bold) might be set in the defaults that you want
+removed in your color scheme.  Use something like "gui=NONE" to remove the
+attributes.
+
+To see which highlight group is used where, find the help for
+"highlight-groups" and "group-name".
+
+You can use ":highlight" to find out the current colors.  Exception: the
+ctermfg and ctermbg values are numbers, which are only valid for the current
+terminal.  Use the color names instead.  See ":help cterm-colors".
+
+The default color settings can be found in the source file src/syntax.c.
+Search for "highlight_init".
+
+If you think you have a color scheme that is good enough to be used by others,
+please check the following items:
+
+- Does it work in a color terminal as well as in the GUI?
+- Is 'background' either used or appropriately set to "light" or "dark"?
+- Try setting 'hlsearch' and searching for a pattern, is the match easy to
+  spot?
+- Split a window with ":split" and ":vsplit".  Are the status lines and
+  vertical separators clearly visible?
+- In the GUI, is it easy to find the cursor, also in a file with lots of
+  syntax highlighting?
+- Do not use hard coded escape sequences, these will not work in other
+  terminals.  Always use color names or #RRGGBB for the GUI.
--- /dev/null
+++ b/lib/vimfiles/colors/blue.vim
@@ -1,0 +1,55 @@
+" local syntax file - set colors on a per-machine basis:
+" vim: tw=0 ts=4 sw=4
+" Vim color file
+" Maintainer:	Steven Vertigan <steven@vertigan.wattle.id.au>
+" Last Change:	2006 Sep 23
+" Revision #5: Switch main text from white to yellow for easier contrast,
+" fixed some problems with terminal backgrounds.
+
+set background=dark
+hi clear
+if exists("syntax_on")
+  syntax reset
+endif
+let g:colors_name = "blue"
+hi Normal		guifg=yellow	guibg=darkBlue	ctermfg=yellow	ctermbg=darkBlue
+hi NonText		guifg=magenta	ctermfg=lightMagenta
+hi comment		guifg=gray		ctermfg=gray	ctermbg=darkBlue	gui=bold 
+hi constant		guifg=cyan		ctermfg=cyan
+hi identifier	guifg=gray		ctermfg=red
+hi statement	guifg=white		ctermfg=white	ctermbg=darkBlue	gui=none
+hi preproc		guifg=green		ctermfg=green
+hi type			guifg=orange	ctermfg=lightRed	ctermbg=darkBlue
+hi special		guifg=magenta	ctermfg=lightMagenta	ctermbg=darkBlue
+hi Underlined	guifg=cyan		ctermfg=cyan	gui=underline	cterm=underline
+hi label		guifg=yellow	ctermfg=yellow
+hi operator		guifg=orange	gui=bold	ctermfg=lightRed	ctermbg=darkBlue
+
+hi ErrorMsg		guifg=orange	guibg=darkBlue	ctermfg=lightRed
+hi WarningMsg	guifg=cyan		guibg=darkBlue	ctermfg=cyan	gui=bold
+hi ModeMsg		guifg=yellow	gui=NONE	ctermfg=yellow
+hi MoreMsg		guifg=yellow	gui=NONE	ctermfg=yellow
+hi Error		guifg=red		guibg=darkBlue	gui=underline	ctermfg=red
+
+hi Todo			guifg=black		guibg=orange	ctermfg=black	ctermbg=darkYellow
+hi Cursor		guifg=black		guibg=white		ctermfg=black	ctermbg=white
+hi Search		guifg=black		guibg=orange	ctermfg=black	ctermbg=darkYellow
+hi IncSearch	guifg=black		guibg=yellow	ctermfg=black	ctermbg=darkYellow
+hi LineNr		guifg=cyan		ctermfg=cyan
+hi title		guifg=white	gui=bold	cterm=bold
+
+hi StatusLineNC	gui=NONE	guifg=black guibg=blue	ctermfg=black  ctermbg=blue
+hi StatusLine	gui=bold	guifg=cyan	guibg=blue	ctermfg=cyan   ctermbg=blue
+hi VertSplit	gui=none	guifg=blue	guibg=blue	ctermfg=blue	ctermbg=blue
+
+hi Visual		term=reverse		ctermfg=black	ctermbg=darkCyan	guifg=black		guibg=darkCyan
+
+hi DiffChange	guibg=darkGreen		guifg=black	ctermbg=darkGreen	ctermfg=black
+hi DiffText		guibg=olivedrab		guifg=black		ctermbg=lightGreen	ctermfg=black
+hi DiffAdd		guibg=slateblue		guifg=black		ctermbg=blue		ctermfg=black
+hi DiffDelete   guibg=coral			guifg=black	ctermbg=cyan		ctermfg=black
+
+hi Folded		guibg=orange		guifg=black		ctermbg=yellow		ctermfg=black
+hi FoldColumn	guibg=gray30		guifg=black	ctermbg=gray		ctermfg=black
+hi cIf0			guifg=gray			ctermfg=gray
+
--- /dev/null
+++ b/lib/vimfiles/colors/darkblue.vim
@@ -1,0 +1,60 @@
+" Vim color file
+" Maintainer:	Bohdan Vlasyuk <bohdan@vstu.edu.ua>
+" Last Change:	2006 Apr 30
+
+" darkblue -- for those who prefer dark background
+" [note: looks bit uglier with come terminal palettes,
+" but is fine on default linux console palette.]
+
+set bg=dark
+hi clear
+if exists("syntax_on")
+	syntax reset
+endif
+
+let colors_name = "darkblue"
+
+hi Normal		guifg=#c0c0c0 guibg=#000040						ctermfg=gray ctermbg=black
+hi ErrorMsg		guifg=#ffffff guibg=#287eff						ctermfg=white ctermbg=lightblue
+hi Visual		guifg=#8080ff guibg=fg		gui=reverse				ctermfg=lightblue ctermbg=fg cterm=reverse
+hi VisualNOS	guifg=#8080ff guibg=fg		gui=reverse,underline	ctermfg=lightblue ctermbg=fg cterm=reverse,underline
+hi Todo			guifg=#d14a14 guibg=#1248d1						ctermfg=red	ctermbg=darkblue
+hi Search		guifg=#90fff0 guibg=#2050d0						ctermfg=white ctermbg=darkblue cterm=underline term=underline
+hi IncSearch	guifg=#b0ffff guibg=#2050d0							ctermfg=darkblue ctermbg=gray
+
+hi SpecialKey		guifg=cyan			ctermfg=darkcyan
+hi Directory		guifg=cyan			ctermfg=cyan
+hi Title			guifg=magenta gui=none ctermfg=magenta cterm=bold
+hi WarningMsg		guifg=red			ctermfg=red
+hi WildMenu			guifg=yellow guibg=black ctermfg=yellow ctermbg=black cterm=none term=none
+hi ModeMsg			guifg=#22cce2		ctermfg=lightblue
+hi MoreMsg			ctermfg=darkgreen	ctermfg=darkgreen
+hi Question			guifg=green gui=none ctermfg=green cterm=none
+hi NonText			guifg=#0030ff		ctermfg=darkblue
+
+hi StatusLine	guifg=blue guibg=darkgray gui=none		ctermfg=blue ctermbg=gray term=none cterm=none
+hi StatusLineNC	guifg=black guibg=darkgray gui=none		ctermfg=black ctermbg=gray term=none cterm=none
+hi VertSplit	guifg=black guibg=darkgray gui=none		ctermfg=black ctermbg=gray term=none cterm=none
+
+hi Folded	guifg=#808080 guibg=#000040			ctermfg=darkgrey ctermbg=black cterm=bold term=bold
+hi FoldColumn	guifg=#808080 guibg=#000040			ctermfg=darkgrey ctermbg=black cterm=bold term=bold
+hi LineNr	guifg=#90f020			ctermfg=green cterm=none
+
+hi DiffAdd	guibg=darkblue	ctermbg=darkblue term=none cterm=none
+hi DiffChange	guibg=darkmagenta ctermbg=magenta cterm=none
+hi DiffDelete	ctermfg=blue ctermbg=cyan gui=bold guifg=Blue guibg=DarkCyan
+hi DiffText	cterm=bold ctermbg=red gui=bold guibg=Red
+
+hi Cursor	guifg=black guibg=yellow ctermfg=black ctermbg=yellow
+hi lCursor	guifg=black guibg=white ctermfg=black ctermbg=white
+
+
+hi Comment	guifg=#80a0ff ctermfg=darkred
+hi Constant	ctermfg=magenta guifg=#ffa0a0 cterm=none
+hi Special	ctermfg=brown guifg=Orange cterm=none gui=none
+hi Identifier	ctermfg=cyan guifg=#40ffff cterm=none
+hi Statement	ctermfg=yellow cterm=none guifg=#ffff60 gui=none
+hi PreProc	ctermfg=magenta guifg=#ff80ff gui=none cterm=none
+hi type		ctermfg=green guifg=#60ff60 gui=none cterm=none
+hi Underlined	cterm=underline term=underline
+hi Ignore	guifg=bg ctermfg=bg
--- /dev/null
+++ b/lib/vimfiles/colors/default.vim
@@ -1,0 +1,23 @@
+" Vim color file
+" Maintainer:	Bram Moolenaar <Bram@vim.org>
+" Last Change:	2001 Jul 23
+
+" This is the default color scheme.  It doesn't define the Normal
+" highlighting, it uses whatever the colors used to be.
+
+" Set 'background' back to the default.  The value can't always be estimated
+" and is then guessed.
+hi clear Normal
+set bg&
+
+" Remove all existing highlighting and set the defaults.
+hi clear
+
+" Load the syntax highlighting defaults, if it's enabled.
+if exists("syntax_on")
+  syntax reset
+endif
+
+let colors_name = "default"
+
+" vim: sw=2
--- /dev/null
+++ b/lib/vimfiles/colors/delek.vim
@@ -1,0 +1,51 @@
+" Vim color file
+" Maintainer:	David Schweikert <dws@ee.ethz.ch>
+" Last Change:	2006 Apr 30
+
+hi clear
+
+let colors_name = "delek"
+
+" Normal should come first
+hi Normal     guifg=Black  guibg=White
+hi Cursor     guifg=bg     guibg=fg
+hi lCursor    guifg=NONE   guibg=Cyan
+
+" Note: we never set 'term' because the defaults for B&W terminals are OK
+hi DiffAdd    ctermbg=LightBlue    guibg=LightBlue
+hi DiffChange ctermbg=LightMagenta guibg=LightMagenta
+hi DiffDelete ctermfg=Blue	   ctermbg=LightCyan gui=bold guifg=Blue guibg=LightCyan
+hi DiffText   ctermbg=Red	   cterm=bold gui=bold guibg=Red
+hi Directory  ctermfg=DarkBlue	   guifg=Blue
+hi ErrorMsg   ctermfg=White	   ctermbg=DarkRed  guibg=Red	    guifg=White
+hi FoldColumn ctermfg=DarkBlue	   ctermbg=Grey     guibg=Grey	    guifg=DarkBlue
+hi Folded     ctermbg=Grey	   ctermfg=DarkBlue guibg=LightGrey guifg=DarkBlue
+hi IncSearch  cterm=reverse	   gui=reverse
+hi LineNr     ctermfg=Brown	   guifg=Brown
+hi ModeMsg    cterm=bold	   gui=bold
+hi MoreMsg    ctermfg=DarkGreen    gui=bold guifg=SeaGreen
+hi NonText    ctermfg=Blue	   gui=bold guifg=gray guibg=white
+hi Pmenu      guibg=LightBlue
+hi PmenuSel   ctermfg=White	   ctermbg=DarkBlue  guifg=White  guibg=DarkBlue
+hi Question   ctermfg=DarkGreen    gui=bold guifg=SeaGreen
+hi Search     ctermfg=NONE	   ctermbg=Yellow guibg=Yellow guifg=NONE
+hi SpecialKey ctermfg=DarkBlue	   guifg=Blue
+hi StatusLine cterm=bold	   ctermbg=blue ctermfg=yellow guibg=gold guifg=blue
+hi StatusLineNC	cterm=bold	   ctermbg=blue ctermfg=black  guibg=gold guifg=blue
+hi Title      ctermfg=DarkMagenta  gui=bold guifg=Magenta
+hi VertSplit  cterm=reverse	   gui=reverse
+hi Visual     ctermbg=NONE	   cterm=reverse gui=reverse guifg=Grey guibg=fg
+hi VisualNOS  cterm=underline,bold gui=underline,bold
+hi WarningMsg ctermfg=DarkRed	   guifg=Red
+hi WildMenu   ctermfg=Black	   ctermbg=Yellow    guibg=Yellow guifg=Black
+
+" syntax highlighting
+hi Comment    cterm=NONE ctermfg=DarkRed     gui=NONE guifg=red2
+hi Constant   cterm=NONE ctermfg=DarkGreen   gui=NONE guifg=green3
+hi Identifier cterm=NONE ctermfg=DarkCyan    gui=NONE guifg=cyan4
+hi PreProc    cterm=NONE ctermfg=DarkMagenta gui=NONE guifg=magenta3
+hi Special    cterm=NONE ctermfg=LightRed    gui=NONE guifg=deeppink
+hi Statement  cterm=bold ctermfg=Blue	     gui=bold guifg=blue
+hi Type	      cterm=NONE ctermfg=Blue	     gui=bold guifg=blue
+
+" vim: sw=2
--- /dev/null
+++ b/lib/vimfiles/colors/desert.vim
@@ -1,0 +1,108 @@
+" Vim color file
+" Maintainer:	Hans Fugal <hans@fugal.net>
+" Last Change:	$Date: 2004/06/13 19:30:30 $
+" Last Change:	$Date: 2004/06/13 19:30:30 $
+" URL:		http://hans.fugal.net/vim/colors/desert.vim
+" Version:	$Id: desert.vim,v 1.1 2004/06/13 19:30:30 vimboss Exp $
+
+" cool help screens
+" :he group-name
+" :he highlight-groups
+" :he cterm-colors
+
+set background=dark
+if version > 580
+    " no guarantees for version 5.8 and below, but this makes it stop
+    " complaining
+    hi clear
+    if exists("syntax_on")
+	syntax reset
+    endif
+endif
+let g:colors_name="desert"
+
+hi Normal	guifg=White guibg=grey20
+
+" highlight groups
+hi Cursor	guibg=khaki guifg=slategrey
+"hi CursorIM
+"hi Directory
+"hi DiffAdd
+"hi DiffChange
+"hi DiffDelete
+"hi DiffText
+"hi ErrorMsg
+hi VertSplit	guibg=#c2bfa5 guifg=grey50 gui=none
+hi Folded	guibg=grey30 guifg=gold
+hi FoldColumn	guibg=grey30 guifg=tan
+hi IncSearch	guifg=slategrey guibg=khaki
+"hi LineNr
+hi ModeMsg	guifg=goldenrod
+hi MoreMsg	guifg=SeaGreen
+hi NonText	guifg=LightBlue guibg=grey30
+hi Question	guifg=springgreen
+hi Search	guibg=peru guifg=wheat
+hi SpecialKey	guifg=yellowgreen
+hi StatusLine	guibg=#c2bfa5 guifg=black gui=none
+hi StatusLineNC	guibg=#c2bfa5 guifg=grey50 gui=none
+hi Title	guifg=indianred
+hi Visual	gui=none guifg=khaki guibg=olivedrab
+"hi VisualNOS
+hi WarningMsg	guifg=salmon
+"hi WildMenu
+"hi Menu
+"hi Scrollbar
+"hi Tooltip
+
+" syntax highlighting groups
+hi Comment	guifg=SkyBlue
+hi Constant	guifg=#ffa0a0
+hi Identifier	guifg=palegreen
+hi Statement	guifg=khaki
+hi PreProc	guifg=indianred
+hi Type		guifg=darkkhaki
+hi Special	guifg=navajowhite
+"hi Underlined
+hi Ignore	guifg=grey40
+"hi Error
+hi Todo		guifg=orangered guibg=yellow2
+
+" color terminal definitions
+hi SpecialKey	ctermfg=darkgreen
+hi NonText	cterm=bold ctermfg=darkblue
+hi Directory	ctermfg=darkcyan
+hi ErrorMsg	cterm=bold ctermfg=7 ctermbg=1
+hi IncSearch	cterm=NONE ctermfg=yellow ctermbg=green
+hi Search	cterm=NONE ctermfg=grey ctermbg=blue
+hi MoreMsg	ctermfg=darkgreen
+hi ModeMsg	cterm=NONE ctermfg=brown
+hi LineNr	ctermfg=3
+hi Question	ctermfg=green
+hi StatusLine	cterm=bold,reverse
+hi StatusLineNC cterm=reverse
+hi VertSplit	cterm=reverse
+hi Title	ctermfg=5
+hi Visual	cterm=reverse
+hi VisualNOS	cterm=bold,underline
+hi WarningMsg	ctermfg=1
+hi WildMenu	ctermfg=0 ctermbg=3
+hi Folded	ctermfg=darkgrey ctermbg=NONE
+hi FoldColumn	ctermfg=darkgrey ctermbg=NONE
+hi DiffAdd	ctermbg=4
+hi DiffChange	ctermbg=5
+hi DiffDelete	cterm=bold ctermfg=4 ctermbg=6
+hi DiffText	cterm=bold ctermbg=1
+hi Comment	ctermfg=darkcyan
+hi Constant	ctermfg=brown
+hi Special	ctermfg=5
+hi Identifier	ctermfg=6
+hi Statement	ctermfg=3
+hi PreProc	ctermfg=5
+hi Type		ctermfg=2
+hi Underlined	cterm=underline ctermfg=5
+hi Ignore	cterm=bold ctermfg=7
+hi Ignore	ctermfg=darkgrey
+hi Error	cterm=bold ctermfg=7 ctermbg=1
+
+
+"vim: sw=4
--- /dev/null
+++ b/lib/vimfiles/colors/elflord.vim
@@ -1,0 +1,50 @@
+" local syntax file - set colors on a per-machine basis:
+" vim: tw=0 ts=4 sw=4
+" Vim color file
+" Maintainer:	Ron Aaron <ron@ronware.org>
+" Last Change:	2003 May 02
+
+set background=dark
+hi clear
+if exists("syntax_on")
+  syntax reset
+endif
+let g:colors_name = "elflord"
+hi Normal		guifg=cyan			guibg=black
+hi Comment	term=bold		ctermfg=DarkCyan		guifg=#80a0ff
+hi Constant	term=underline	ctermfg=Magenta		guifg=Magenta
+hi Special	term=bold		ctermfg=DarkMagenta	guifg=Red
+hi Identifier term=underline	cterm=bold			ctermfg=Cyan guifg=#40ffff
+hi Statement term=bold		ctermfg=Yellow gui=bold	guifg=#aa4444
+hi PreProc	term=underline	ctermfg=LightBlue	guifg=#ff80ff
+hi Type	term=underline		ctermfg=LightGreen	guifg=#60ff60 gui=bold
+hi Function	term=bold		ctermfg=White guifg=White
+hi Repeat	term=underline	ctermfg=White		guifg=white
+hi Operator				ctermfg=Red			guifg=Red
+hi Ignore				ctermfg=black		guifg=bg
+hi Error	term=reverse ctermbg=Red ctermfg=White guibg=Red guifg=White
+hi Todo	term=standout ctermbg=Yellow ctermfg=Black guifg=Blue guibg=Yellow
+
+" Common groups that link to default highlighting.
+" You can specify other highlighting easily.
+hi link String	Constant
+hi link Character	Constant
+hi link Number	Constant
+hi link Boolean	Constant
+hi link Float		Number
+hi link Conditional	Repeat
+hi link Label		Statement
+hi link Keyword	Statement
+hi link Exception	Statement
+hi link Include	PreProc
+hi link Define	PreProc
+hi link Macro		PreProc
+hi link PreCondit	PreProc
+hi link StorageClass	Type
+hi link Structure	Type
+hi link Typedef	Type
+hi link Tag		Special
+hi link SpecialChar	Special
+hi link Delimiter	Special
+hi link SpecialComment Special
+hi link Debug		Special
--- /dev/null
+++ b/lib/vimfiles/colors/evening.vim
@@ -1,0 +1,56 @@
+" Vim color file
+" Maintainer:	Bram Moolenaar <Bram@vim.org>
+" Last Change:	2006 Apr 14
+
+" This color scheme uses a dark grey background.
+
+" First remove all existing highlighting.
+set background=dark
+hi clear
+if exists("syntax_on")
+  syntax reset
+endif
+
+let colors_name = "evening"
+
+hi Normal ctermbg=DarkGrey ctermfg=White guifg=White guibg=grey20
+
+" Groups used in the 'highlight' and 'guicursor' options default value.
+hi ErrorMsg term=standout ctermbg=DarkRed ctermfg=White guibg=Red guifg=White
+hi IncSearch term=reverse cterm=reverse gui=reverse
+hi ModeMsg term=bold cterm=bold gui=bold
+hi StatusLine term=reverse,bold cterm=reverse,bold gui=reverse,bold
+hi StatusLineNC term=reverse cterm=reverse gui=reverse
+hi VertSplit term=reverse cterm=reverse gui=reverse
+hi Visual term=reverse ctermbg=black guibg=grey60
+hi VisualNOS term=underline,bold cterm=underline,bold gui=underline,bold
+hi DiffText term=reverse cterm=bold ctermbg=Red gui=bold guibg=Red
+hi Cursor guibg=Green guifg=Black
+hi lCursor guibg=Cyan guifg=Black
+hi Directory term=bold ctermfg=LightCyan guifg=Cyan
+hi LineNr term=underline ctermfg=Yellow guifg=Yellow
+hi MoreMsg term=bold ctermfg=LightGreen gui=bold guifg=SeaGreen
+hi NonText term=bold ctermfg=LightBlue gui=bold guifg=LightBlue guibg=grey30
+hi Question term=standout ctermfg=LightGreen gui=bold guifg=Green
+hi Search term=reverse ctermbg=Yellow ctermfg=Black guibg=Yellow guifg=Black
+hi SpecialKey term=bold ctermfg=LightBlue guifg=Cyan
+hi Title term=bold ctermfg=LightMagenta gui=bold guifg=Magenta
+hi WarningMsg term=standout ctermfg=LightRed guifg=Red
+hi WildMenu term=standout ctermbg=Yellow ctermfg=Black guibg=Yellow guifg=Black
+hi Folded term=standout ctermbg=LightGrey ctermfg=DarkBlue guibg=LightGrey guifg=DarkBlue
+hi FoldColumn term=standout ctermbg=LightGrey ctermfg=DarkBlue guibg=Grey guifg=DarkBlue
+hi DiffAdd term=bold ctermbg=DarkBlue guibg=DarkBlue
+hi DiffChange term=bold ctermbg=DarkMagenta guibg=DarkMagenta
+hi DiffDelete term=bold ctermfg=Blue ctermbg=DarkCyan gui=bold guifg=Blue guibg=DarkCyan
+hi CursorColumn term=reverse ctermbg=Black guibg=grey40
+hi CursorLine term=underline cterm=underline guibg=grey40
+
+" Groups for syntax highlighting
+hi Constant term=underline ctermfg=Magenta guifg=#ffa0a0 guibg=grey5
+hi Special term=bold ctermfg=LightRed guifg=Orange guibg=grey5
+if &t_Co > 8
+  hi Statement term=bold cterm=bold ctermfg=Yellow guifg=#ffff60 gui=bold
+endif
+hi Ignore ctermfg=DarkGrey guifg=grey20
+
+" vim: sw=2
--- /dev/null
+++ b/lib/vimfiles/colors/koehler.vim
@@ -1,0 +1,70 @@
+" local syntax file - set colors on a per-machine basis:
+" vim: tw=0 ts=4 sw=4
+" Vim color file
+" Maintainer:	Ron Aaron <ron@ronware.org>
+" Last Change:	2006 Dec 10
+
+hi clear
+set background=dark
+if exists("syntax_on")
+  syntax reset
+endif
+let g:colors_name = "koehler"
+hi Normal		  guifg=white  guibg=black
+hi Scrollbar	  guifg=darkcyan guibg=cyan
+hi Menu			  guifg=black guibg=cyan
+hi SpecialKey	  term=bold  cterm=bold  ctermfg=darkred  guifg=#cc0000
+hi NonText		  term=bold  cterm=bold  ctermfg=darkred  gui=bold      guifg=#cc0000
+hi Directory	  term=bold  cterm=bold  ctermfg=brown  guifg=#cc8000
+hi ErrorMsg		  term=standout  cterm=bold  ctermfg=grey  ctermbg=red  guifg=White  guibg=Red
+hi Search		  term=reverse  ctermfg=white  ctermbg=red      guifg=white  guibg=Red
+hi MoreMsg		  term=bold  cterm=bold  ctermfg=darkgreen	gui=bold  guifg=SeaGreen
+hi ModeMsg		  term=bold  cterm=bold  gui=bold  guifg=White	guibg=Blue
+hi LineNr		  term=underline  cterm=bold  ctermfg=darkcyan	guifg=Yellow
+hi Question		  term=standout  cterm=bold  ctermfg=darkgreen	gui=bold  guifg=Green
+hi StatusLine	  term=bold,reverse  cterm=bold ctermfg=lightblue ctermbg=white gui=bold guifg=blue guibg=white
+hi StatusLineNC   term=reverse	ctermfg=white ctermbg=lightblue guifg=white guibg=blue
+hi Title		  term=bold  cterm=bold  ctermfg=darkmagenta  gui=bold	guifg=Magenta
+hi Visual		  term=reverse	cterm=reverse  gui=reverse
+hi WarningMsg	  term=standout  cterm=bold  ctermfg=darkred guifg=Red
+hi Cursor		  guifg=bg	guibg=Green
+hi Comment		  term=bold  cterm=bold ctermfg=cyan  guifg=#80a0ff
+hi Constant		  term=underline  cterm=bold ctermfg=magenta  guifg=#ffa0a0
+hi Special		  term=bold  cterm=bold ctermfg=red  guifg=Orange
+hi Identifier	  term=underline   ctermfg=brown  guifg=#40ffff
+hi Statement	  term=bold  cterm=bold ctermfg=yellow	gui=bold  guifg=#ffff60
+hi PreProc		  term=underline  ctermfg=darkmagenta   guifg=#ff80ff
+hi Type			  term=underline  cterm=bold ctermfg=lightgreen  gui=bold  guifg=#60ff60
+hi Error		  term=reverse	ctermfg=darkcyan  ctermbg=black  guifg=Red	guibg=Black
+hi Todo			  term=standout  ctermfg=black	ctermbg=darkcyan  guifg=Blue  guibg=Yellow
+hi CursorLine	  term=underline  guibg=#555555 cterm=underline
+hi CursorColumn	  term=underline  guibg=#555555 cterm=underline
+hi MatchParen	  term=reverse  ctermfg=blue guibg=Blue
+hi TabLine		  term=bold,reverse  cterm=bold ctermfg=lightblue ctermbg=white gui=bold guifg=blue guibg=white
+hi TabLineFill	  term=bold,reverse  cterm=bold ctermfg=lightblue ctermbg=white gui=bold guifg=blue guibg=white
+hi TabLineSel	  term=reverse	ctermfg=white ctermbg=lightblue guifg=white guibg=blue
+hi link IncSearch		Visual
+hi link String			Constant
+hi link Character		Constant
+hi link Number			Constant
+hi link Boolean			Constant
+hi link Float			Number
+hi link Function		Identifier
+hi link Conditional		Statement
+hi link Repeat			Statement
+hi link Label			Statement
+hi link Operator		Statement
+hi link Keyword			Statement
+hi link Exception		Statement
+hi link Include			PreProc
+hi link Define			PreProc
+hi link Macro			PreProc
+hi link PreCondit		PreProc
+hi link StorageClass	Type
+hi link Structure		Type
+hi link Typedef			Type
+hi link Tag				Special
+hi link SpecialChar		Special
+hi link Delimiter		Special
+hi link SpecialComment	Special
+hi link Debug			Special
--- /dev/null
+++ b/lib/vimfiles/colors/morning.vim
@@ -1,0 +1,56 @@
+" Vim color file
+" Maintainer:	Bram Moolenaar <Bram@vim.org>
+" Last Change:	2006 Apr 15
+
+" This color scheme uses a light grey background.
+
+" First remove all existing highlighting.
+set background=light
+hi clear
+if exists("syntax_on")
+  syntax reset
+endif
+
+let colors_name = "morning"
+
+hi Normal ctermfg=Black ctermbg=LightGrey guifg=Black guibg=grey90
+
+" Groups used in the 'highlight' and 'guicursor' options default value.
+hi ErrorMsg term=standout ctermbg=DarkRed ctermfg=White guibg=Red guifg=White
+hi IncSearch term=reverse cterm=reverse gui=reverse
+hi ModeMsg term=bold cterm=bold gui=bold
+hi StatusLine term=reverse,bold cterm=reverse,bold gui=reverse,bold
+hi StatusLineNC term=reverse cterm=reverse gui=reverse
+hi VertSplit term=reverse cterm=reverse gui=reverse
+hi Visual term=reverse ctermbg=grey guibg=grey80
+hi VisualNOS term=underline,bold cterm=underline,bold gui=underline,bold
+hi DiffText term=reverse cterm=bold ctermbg=Red gui=bold guibg=Red
+hi Cursor guibg=Green guifg=NONE
+hi lCursor guibg=Cyan guifg=NONE
+hi Directory term=bold ctermfg=DarkBlue guifg=Blue
+hi LineNr term=underline ctermfg=Brown guifg=Brown
+hi MoreMsg term=bold ctermfg=DarkGreen gui=bold guifg=SeaGreen
+hi NonText term=bold ctermfg=Blue gui=bold guifg=Blue guibg=grey80
+hi Question term=standout ctermfg=DarkGreen gui=bold guifg=SeaGreen
+hi Search term=reverse ctermbg=Yellow ctermfg=NONE guibg=Yellow guifg=NONE
+hi SpecialKey term=bold ctermfg=DarkBlue guifg=Blue
+hi Title term=bold ctermfg=DarkMagenta gui=bold guifg=Magenta
+hi WarningMsg term=standout ctermfg=DarkRed guifg=Red
+hi WildMenu term=standout ctermbg=Yellow ctermfg=Black guibg=Yellow guifg=Black
+hi Folded term=standout ctermbg=Grey ctermfg=DarkBlue guibg=LightGrey guifg=DarkBlue
+hi FoldColumn term=standout ctermbg=Grey ctermfg=DarkBlue guibg=Grey guifg=DarkBlue
+hi DiffAdd term=bold ctermbg=LightBlue guibg=LightBlue
+hi DiffChange term=bold ctermbg=LightMagenta guibg=LightMagenta
+hi DiffDelete term=bold ctermfg=Blue ctermbg=LightCyan gui=bold guifg=Blue guibg=LightCyan
+hi CursorLine term=underline cterm=underline guibg=grey80
+hi CursorColumn term=reverse ctermbg=grey guibg=grey80
+
+" Colors for syntax highlighting
+hi Constant term=underline ctermfg=DarkRed guifg=Magenta guibg=grey95
+hi Special term=bold ctermfg=DarkMagenta guifg=SlateBlue guibg=grey95
+if &t_Co > 8
+  hi Statement term=bold cterm=bold ctermfg=Brown gui=bold guifg=Brown
+endif
+hi Ignore ctermfg=LightGrey guifg=grey90
+
+" vim: sw=2
--- /dev/null
+++ b/lib/vimfiles/colors/murphy.vim
@@ -1,0 +1,41 @@
+" local syntax file - set colors on a per-machine basis:
+" vim: tw=0 ts=4 sw=4
+" Vim color file
+" Maintainer:	Ron Aaron <ron@ronware.org>
+" Last Change:	2003 May 02
+
+hi clear
+set background=dark
+if exists("syntax_on")
+  syntax reset
+endif
+let g:colors_name = "murphy"
+
+hi Normal		ctermbg=Black  ctermfg=lightgreen guibg=Black		 guifg=lightgreen
+hi Comment		term=bold	   ctermfg=LightRed   guifg=Orange
+hi Constant		term=underline ctermfg=LightGreen guifg=White	gui=NONE
+hi Identifier	term=underline ctermfg=LightCyan  guifg=#00ffff
+hi Ignore					   ctermfg=black	  guifg=bg
+hi PreProc		term=underline ctermfg=LightBlue  guifg=Wheat
+hi Search		term=reverse					  guifg=white	guibg=Blue
+hi Special		term=bold	   ctermfg=LightRed   guifg=magenta
+hi Statement	term=bold	   ctermfg=Yellow	  guifg=#ffff00 gui=NONE
+hi Type						   ctermfg=LightGreen guifg=grey	gui=none
+hi Error		term=reverse   ctermbg=Red	  ctermfg=White guibg=Red  guifg=White
+hi Todo			term=standout  ctermbg=Yellow ctermfg=Black guifg=Blue guibg=Yellow
+" From the source:
+hi Cursor										  guifg=Orchid	guibg=fg
+hi Directory	term=bold	   ctermfg=LightCyan  guifg=Cyan
+hi ErrorMsg		term=standout  ctermbg=DarkRed	  ctermfg=White guibg=Red guifg=White
+hi IncSearch	term=reverse   cterm=reverse	  gui=reverse
+hi LineNr		term=underline ctermfg=Yellow					guifg=Yellow
+hi ModeMsg		term=bold	   cterm=bold		  gui=bold
+hi MoreMsg		term=bold	   ctermfg=LightGreen gui=bold		guifg=SeaGreen
+hi NonText		term=bold	   ctermfg=Blue		  gui=bold		guifg=Blue
+hi Question		term=standout  ctermfg=LightGreen gui=bold		guifg=Cyan
+hi SpecialKey	term=bold	   ctermfg=LightBlue  guifg=Cyan
+hi StatusLine	term=reverse,bold cterm=reverse   gui=NONE		guifg=White guibg=darkblue
+hi StatusLineNC term=reverse   cterm=reverse	  gui=NONE		guifg=white guibg=#333333
+hi Title		term=bold	   ctermfg=LightMagenta gui=bold	guifg=Pink
+hi WarningMsg	term=standout  ctermfg=LightRed   guifg=Red
+hi Visual		term=reverse   cterm=reverse	  gui=NONE		guifg=white guibg=darkgreen
--- /dev/null
+++ b/lib/vimfiles/colors/pablo.vim
@@ -1,0 +1,26 @@
+" local syntax file - set colors on a per-machine basis:
+" vim: tw=0 ts=4 sw=4
+" Vim color file
+" Maintainer:	Ron Aaron <ron@ronware.org>
+" Last Change:	2003 May 02
+
+hi clear
+set background=dark
+if exists("syntax_on")
+  syntax reset
+endif
+let g:colors_name = "pablo"
+
+highlight Comment	 ctermfg=8						  guifg=#808080
+highlight Constant	 ctermfg=14			   cterm=none guifg=#00ffff				  gui=none
+highlight Identifier ctermfg=6						  guifg=#00c0c0
+highlight Statement  ctermfg=3			   cterm=bold guifg=#c0c000				  gui=bold
+highlight PreProc	 ctermfg=10						  guifg=#00ff00
+highlight Type		 ctermfg=2						  guifg=#00c000
+highlight Special	 ctermfg=12						  guifg=#0000ff
+highlight Error					ctermbg=9							guibg=#ff0000
+highlight Todo		 ctermfg=4	ctermbg=3			  guifg=#000080 guibg=#c0c000
+highlight Directory  ctermfg=2						  guifg=#00c000
+highlight StatusLine ctermfg=11 ctermbg=12 cterm=none guifg=#ffff00 guibg=#0000ff gui=none
+highlight Normal									  guifg=#ffffff guibg=#000000
+highlight Search				ctermbg=3							guibg=#c0c000
--- /dev/null
+++ b/lib/vimfiles/colors/peachpuff.vim
@@ -1,0 +1,60 @@
+" Vim color file
+" Maintainer: David Ne\v{c}as (Yeti) <yeti@physics.muni.cz>
+" Last Change: 2003-04-23
+" URL: http://trific.ath.cx/Ftp/vim/colors/peachpuff.vim
+
+" This color scheme uses a peachpuff background (what you've expected when it's
+" called peachpuff?).
+"
+" Note: Only GUI colors differ from default, on terminal it's just `light'.
+
+" First remove all existing highlighting.
+set background=light
+hi clear
+if exists("syntax_on")
+  syntax reset
+endif
+
+let colors_name = "peachpuff"
+
+hi Normal guibg=PeachPuff guifg=Black
+
+hi SpecialKey term=bold ctermfg=4 guifg=Blue
+hi NonText term=bold cterm=bold ctermfg=4 gui=bold guifg=Blue
+hi Directory term=bold ctermfg=4 guifg=Blue
+hi ErrorMsg term=standout cterm=bold ctermfg=7 ctermbg=1 gui=bold guifg=White guibg=Red
+hi IncSearch term=reverse cterm=reverse gui=reverse
+hi Search term=reverse ctermbg=3 guibg=Gold2
+hi MoreMsg term=bold ctermfg=2 gui=bold guifg=SeaGreen
+hi ModeMsg term=bold cterm=bold gui=bold
+hi LineNr term=underline ctermfg=3 guifg=Red3
+hi Question term=standout ctermfg=2 gui=bold guifg=SeaGreen
+hi StatusLine term=bold,reverse cterm=bold,reverse gui=bold guifg=White guibg=Black
+hi StatusLineNC term=reverse cterm=reverse gui=bold guifg=PeachPuff guibg=Gray45
+hi VertSplit term=reverse cterm=reverse gui=bold guifg=White guibg=Gray45
+hi Title term=bold ctermfg=5 gui=bold guifg=DeepPink3
+hi Visual term=reverse cterm=reverse gui=reverse guifg=Grey80 guibg=fg
+hi VisualNOS term=bold,underline cterm=bold,underline gui=bold,underline
+hi WarningMsg term=standout ctermfg=1 gui=bold guifg=Red
+hi WildMenu term=standout ctermfg=0 ctermbg=3 guifg=Black guibg=Yellow
+hi Folded term=standout ctermfg=4 ctermbg=7 guifg=Black guibg=#e3c1a5
+hi FoldColumn term=standout ctermfg=4 ctermbg=7 guifg=DarkBlue guibg=Gray80
+hi DiffAdd term=bold ctermbg=4 guibg=White
+hi DiffChange term=bold ctermbg=5 guibg=#edb5cd
+hi DiffDelete term=bold cterm=bold ctermfg=4 ctermbg=6 gui=bold guifg=LightBlue guibg=#f6e8d0
+hi DiffText term=reverse cterm=bold ctermbg=1 gui=bold guibg=#ff8060
+hi Cursor guifg=bg guibg=fg
+hi lCursor guifg=bg guibg=fg
+
+" Colors for syntax highlighting
+hi Comment term=bold ctermfg=4 guifg=#406090
+hi Constant term=underline ctermfg=1 guifg=#c00058
+hi Special term=bold ctermfg=5 guifg=SlateBlue
+hi Identifier term=underline ctermfg=6 guifg=DarkCyan
+hi Statement term=bold ctermfg=3 gui=bold guifg=Brown
+hi PreProc term=underline ctermfg=5 guifg=Magenta3
+hi Type term=underline ctermfg=2 gui=bold guifg=SeaGreen
+hi Ignore cterm=bold ctermfg=7 guifg=bg
+hi Error term=reverse cterm=bold ctermfg=7 ctermbg=1 gui=bold guifg=White guibg=Red
+hi Todo term=standout ctermfg=0 ctermbg=3 guifg=Blue guibg=Yellow
+
--- /dev/null
+++ b/lib/vimfiles/colors/ron.vim
@@ -1,0 +1,43 @@
+" local syntax file - set colors on a per-machine basis:
+" vim: tw=0 ts=4 sw=4
+" Vim color file
+" Maintainer:	Ron Aaron <ron@ronware.org>
+" Last Change:	2003 May 02
+
+set background=dark
+hi clear
+if exists("syntax_on")
+  syntax reset
+endif
+let g:colors_name = "ron"
+hi Normal		guifg=cyan	guibg=black
+hi NonText		guifg=brown
+hi comment		guifg=green
+hi constant		guifg=cyan	gui=bold
+hi identifier	guifg=cyan	gui=NONE
+hi statement	guifg=lightblue	gui=NONE
+hi preproc		guifg=Pink2
+hi type			guifg=seagreen	gui=bold
+hi special		guifg=yellow
+hi ErrorMsg		guifg=Black	guibg=Red
+hi WarningMsg	guifg=Black	guibg=Green
+hi Error		guibg=Red
+hi Todo			guifg=Black	guibg=orange
+hi Cursor		guibg=#60a060 guifg=#00ff00
+hi Search		guibg=lightslateblue
+hi IncSearch	gui=NONE guibg=steelblue
+hi LineNr		guifg=darkgrey
+hi title		guifg=darkgrey
+hi StatusLineNC	gui=NONE guifg=lightblue guibg=darkblue
+hi StatusLine	gui=bold	guifg=cyan	guibg=blue
+hi label		guifg=gold2
+hi operator		guifg=orange
+hi clear Visual
+hi Visual		term=reverse cterm=reverse gui=reverse
+hi DiffChange   guibg=darkgreen
+hi DiffText		guibg=olivedrab
+hi DiffAdd		guibg=slateblue
+hi DiffDelete   guibg=coral
+hi Folded		guibg=gray30
+hi FoldColumn	guibg=gray30 guifg=white
+hi cIf0			guifg=gray
--- /dev/null
+++ b/lib/vimfiles/colors/shine.vim
@@ -1,0 +1,60 @@
+" Vim color file
+" Maintainer:	Yasuhiro Matsumoto <mattn@mail.goo.ne.jp>
+" Last Change:	2001 May 25
+
+" This look like normal text editor.
+" This color scheme uses a light background.
+
+" First remove all existing highlighting.
+set background=light
+hi clear
+if exists("syntax_on")
+  syntax reset
+endif
+
+let colors_name = "shine"
+
+hi Normal ctermbg=White ctermfg=Black guifg=Black guibg=White
+
+" Groups used in the 'highlight' and 'guicursor' options default value.
+hi ErrorMsg term=standout ctermbg=DarkRed ctermfg=White guibg=Red guifg=White
+hi IncSearch term=reverse cterm=reverse gui=reverse
+hi ModeMsg term=bold cterm=bold gui=bold
+hi StatusLine term=reverse,bold cterm=reverse,bold gui=reverse,bold
+hi StatusLineNC term=reverse cterm=reverse gui=reverse
+hi VertSplit term=reverse cterm=reverse gui=reverse
+hi Visual term=reverse cterm=reverse gui=reverse guifg=Grey guibg=fg
+hi VisualNOS term=underline,bold cterm=underline,bold gui=underline,bold
+hi DiffText term=reverse cterm=bold ctermbg=Red gui=bold guibg=Red
+hi Cursor ctermbg=Green guibg=Green guifg=Black
+hi lCursor guibg=Cyan guifg=Black
+hi Directory term=bold ctermfg=LightRed guifg=Red
+hi LineNr term=underline ctermfg=Yellow guifg=Yellow
+hi MoreMsg term=bold ctermfg=LightGreen gui=bold guifg=SeaGreen
+hi NonText term=bold ctermfg=LightBlue gui=bold guifg=LightBlue guibg=grey90
+hi Question term=standout ctermfg=LightGreen gui=bold guifg=Green
+hi Search term=reverse ctermbg=Yellow ctermfg=Black guibg=Yellow guifg=Black
+hi SpecialKey term=bold ctermfg=LightBlue guifg=Blue
+hi Title term=bold ctermfg=LightMagenta gui=bold guifg=Magenta
+hi WarningMsg term=standout ctermfg=LightRed guifg=Red
+hi WildMenu term=standout ctermbg=Yellow ctermfg=Black guibg=Yellow guifg=Black
+hi Folded term=standout ctermbg=LightGrey ctermfg=DarkBlue guibg=LightGrey guifg=DarkBlue
+hi FoldColumn term=standout ctermbg=LightGrey ctermfg=DarkBlue guibg=Grey guifg=DarkBlue
+hi DiffAdd term=bold ctermbg=DarkBlue guibg=DarkBlue
+hi DiffChange term=bold ctermbg=DarkMagenta guibg=DarkMagenta
+hi DiffDelete term=bold ctermfg=Blue ctermbg=DarkCyan gui=bold guifg=Blue guibg=DarkCyan
+
+hi Comment ctermfg=DarkGrey ctermbg=White guifg=DarkGrey gui=bold
+hi SpecialChar ctermfg=DarkGrey ctermbg=White guifg=DarkGrey gui=bold
+hi StorageClass ctermfg=Red ctermbg=White guifg=Red gui=bold
+hi Number ctermfg=LightRed ctermbg=White guifg=LightRed gui=bold
+
+" Groups for syntax highlighting
+hi Constant term=underline ctermfg=Magenta guifg=#a07070 guibg=grey80
+hi Special term=bold ctermfg=LightRed guifg=DarkOrange guibg=grey80
+if &t_Co > 8
+  hi Statement term=bold cterm=bold ctermfg=DarkGreen ctermbg=White guifg=#ffff60 gui=bold
+endif
+hi Ignore ctermfg=LightGrey guifg=grey90
+
+" vim: sw=2
--- /dev/null
+++ b/lib/vimfiles/colors/slate.vim
@@ -1,0 +1,55 @@
+"%% SiSU Vim color file
+" Slate Maintainer: Ralph Amissah <ralph@amissah.com>
+" (originally looked at desert Hans Fugal <hans@fugal.net> http://hans.fugal.net/vim/colors/desert.vim (2003/05/06)
+:set background=dark
+:highlight clear
+if version > 580
+ hi clear
+ if exists("syntax_on")
+ syntax reset
+ endif
+endif
+:hi Normal guifg=White guibg=grey15
+:hi Cursor guibg=khaki guifg=slategrey
+:hi VertSplit guibg=#c2bfa5 guifg=grey40 gui=none cterm=reverse
+:hi Folded guibg=black guifg=grey40 ctermfg=grey ctermbg=darkgrey
+:hi FoldColumn guibg=black guifg=grey20 ctermfg=4 ctermbg=7
+:hi IncSearch guifg=green guibg=black cterm=none ctermfg=yellow ctermbg=green
+:hi ModeMsg guifg=goldenrod cterm=none ctermfg=brown
+:hi MoreMsg guifg=SeaGreen ctermfg=darkgreen
+:hi NonText guifg=RoyalBlue guibg=grey15 cterm=bold ctermfg=blue
+:hi Question guifg=springgreen ctermfg=green
+:hi Search guibg=peru guifg=wheat cterm=none ctermfg=grey ctermbg=blue
+:hi SpecialKey guifg=yellowgreen ctermfg=darkgreen
+:hi StatusLine guibg=#c2bfa5 guifg=black gui=none cterm=bold,reverse
+:hi StatusLineNC guibg=#c2bfa5 guifg=grey40 gui=none cterm=reverse
+:hi Title guifg=gold gui=bold cterm=bold ctermfg=yellow
+:hi Statement guifg=CornflowerBlue ctermfg=lightblue
+:hi Visual gui=none guifg=khaki guibg=olivedrab cterm=reverse
+:hi WarningMsg guifg=salmon ctermfg=1
+:hi String guifg=SkyBlue ctermfg=darkcyan
+:hi Comment term=bold ctermfg=11 guifg=grey40
+:hi Constant guifg=#ffa0a0 ctermfg=brown
+:hi Special guifg=darkkhaki ctermfg=brown
+:hi Identifier guifg=salmon ctermfg=red
+:hi Include guifg=red ctermfg=red
+:hi PreProc guifg=red guibg=white ctermfg=red
+:hi Operator guifg=Red ctermfg=Red
+:hi Define guifg=gold gui=bold ctermfg=yellow
+:hi Type guifg=CornflowerBlue ctermfg=2
+:hi Function guifg=navajowhite ctermfg=brown
+:hi Structure guifg=green ctermfg=green
+:hi LineNr guifg=grey50 ctermfg=3
+:hi Ignore guifg=grey40 cterm=bold ctermfg=7
+:hi Todo guifg=orangered guibg=yellow2
+:hi Directory ctermfg=darkcyan
+:hi ErrorMsg cterm=bold guifg=White guibg=Red cterm=bold ctermfg=7 ctermbg=1
+:hi VisualNOS cterm=bold,underline
+:hi WildMenu ctermfg=0 ctermbg=3
+:hi DiffAdd ctermbg=4
+:hi DiffChange ctermbg=5
+:hi DiffDelete cterm=bold ctermfg=4 ctermbg=6
+:hi DiffText cterm=bold ctermbg=1
+:hi Underlined cterm=underline ctermfg=5
+:hi Error guifg=White guibg=Red cterm=bold ctermfg=7 ctermbg=1
+:hi SpellErrors guifg=White guibg=Red cterm=bold ctermfg=7 ctermbg=1
--- /dev/null
+++ b/lib/vimfiles/colors/torte.vim
@@ -1,0 +1,50 @@
+" Vim color file
+" Maintainer:	Thorsten Maerz <info@netztorte.de>
+" Last Change:	2006 Dec 07
+" grey on black
+" optimized for TFT panels
+
+set background=dark
+hi clear
+if exists("syntax_on")
+  syntax reset
+endif
+"colorscheme default
+let g:colors_name = "torte"
+
+" hardcoded colors :
+" GUI Comment : #80a0ff = Light blue
+
+" GUI
+highlight Normal     guifg=Grey80	guibg=Black
+highlight Search     guifg=Black	guibg=Red	gui=bold
+highlight Visual     guifg=#404040			gui=bold
+highlight Cursor     guifg=Black	guibg=Green	gui=bold
+highlight Special    guifg=Orange
+highlight Comment    guifg=#80a0ff
+highlight StatusLine guifg=blue		guibg=white
+highlight Statement  guifg=Yellow			gui=NONE
+highlight Type						gui=NONE
+
+" Console
+highlight Normal     ctermfg=LightGrey	ctermbg=Black
+highlight Search     ctermfg=Black	ctermbg=Red	cterm=NONE
+highlight Visual					cterm=reverse
+highlight Cursor     ctermfg=Black	ctermbg=Green	cterm=bold
+highlight Special    ctermfg=Brown
+highlight Comment    ctermfg=Blue
+highlight StatusLine ctermfg=blue	ctermbg=white
+highlight Statement  ctermfg=Yellow			cterm=NONE
+highlight Type						cterm=NONE
+
+" only for vim 5
+if has("unix")
+  if v:version<600
+    highlight Normal  ctermfg=Grey	ctermbg=Black	cterm=NONE	guifg=Grey80      guibg=Black	gui=NONE
+    highlight Search  ctermfg=Black	ctermbg=Red	cterm=bold	guifg=Black       guibg=Red	gui=bold
+    highlight Visual  ctermfg=Black	ctermbg=yellow	cterm=bold	guifg=#404040			gui=bold
+    highlight Special ctermfg=LightBlue			cterm=NONE	guifg=LightBlue			gui=NONE
+    highlight Comment ctermfg=Cyan			cterm=NONE	guifg=LightBlue			gui=NONE
+  endif
+endif
+
--- /dev/null
+++ b/lib/vimfiles/colors/zellner.vim
@@ -1,0 +1,54 @@
+" local syntax file - set colors on a per-machine basis:
+" vim: tw=0 ts=4 sw=4
+" Vim color file
+" Maintainer:	Ron Aaron <ron@ronware.org>
+" Last Change:	2003 May 02
+
+set background=light
+hi clear
+if exists("syntax_on")
+  syntax reset
+endif
+let g:colors_name = "zellner"
+
+hi Comment term=bold ctermfg=Red guifg=Red
+hi Normal guifg=black guibg=white
+hi Constant term=underline ctermfg=Magenta guifg=Magenta
+hi Special term=bold ctermfg=Magenta guifg=Magenta
+hi Identifier term=underline ctermfg=Blue guifg=Blue
+hi Statement term=bold ctermfg=DarkRed gui=NONE guifg=Brown
+hi PreProc term=underline ctermfg=Magenta guifg=Purple
+hi Type term=underline ctermfg=Blue gui=NONE guifg=Blue
+hi Visual term=reverse ctermfg=Yellow ctermbg=Red gui=NONE guifg=Black guibg=Yellow
+hi Search term=reverse ctermfg=Black ctermbg=Cyan gui=NONE guifg=Black guibg=Cyan
+hi Tag term=bold ctermfg=DarkGreen guifg=DarkGreen
+hi Error term=reverse ctermfg=15 ctermbg=9 guibg=Red guifg=White
+hi Todo term=standout ctermbg=Yellow ctermfg=Black guifg=Blue guibg=Yellow
+hi  StatusLine term=bold,reverse cterm=NONE ctermfg=Yellow ctermbg=DarkGray gui=NONE guifg=Yellow guibg=DarkGray
+hi! link MoreMsg Comment
+hi! link ErrorMsg Visual
+hi! link WarningMsg ErrorMsg
+hi! link Question Comment
+hi link String	Constant
+hi link Character	Constant
+hi link Number	Constant
+hi link Boolean	Constant
+hi link Float		Number
+hi link Function	Identifier
+hi link Conditional	Statement
+hi link Repeat	Statement
+hi link Label		Statement
+hi link Operator	Statement
+hi link Keyword	Statement
+hi link Exception	Statement
+hi link Include	PreProc
+hi link Define	PreProc
+hi link Macro		PreProc
+hi link PreCondit	PreProc
+hi link StorageClass	Type
+hi link Structure	Type
+hi link Typedef	Type
+hi link SpecialChar	Special
+hi link Delimiter	Special
+hi link SpecialComment Special
+hi link Debug		Special
--- /dev/null
+++ b/lib/vimfiles/compiler/README.txt
@@ -1,0 +1,11 @@
+This directory contains Vim scripts to be used with a specific compiler.
+They are used with the ":compiler" command.
+
+These scripts usually set options, for example 'errorformat'.
+See ":help write-compiler-plugin".
+
+If you want to write your own compiler plugin, have a look at the other files
+for how to do it, the format is simple.
+
+If you think a compiler plugin you have written is useful for others, please
+send it to Bram@vim.org.
--- /dev/null
+++ b/lib/vimfiles/compiler/ant.vim
@@ -1,0 +1,38 @@
+" Vim Compiler File
+" Compiler:	ant
+" Maintainer:	Johannes Zellner <johannes@zellner.org>
+" Last Change:	Mi, 13 Apr 2005 22:50:07 CEST
+
+if exists("current_compiler")
+    finish
+endif
+let current_compiler = "ant"
+
+if exists(":CompilerSet") != 2		" older Vim always used :setlocal
+  command -nargs=* CompilerSet setlocal <args>
+endif
+
+let s:cpo_save = &cpo
+set cpo&vim
+
+CompilerSet makeprg=ant
+
+" first  line:
+"     ant with jikes +E, which assumes  the following
+"     two property lines in your 'build.xml':
+"
+"         <property name = "build.compiler"       value = "jikes"/>
+"         <property name = "build.compiler.emacs" value = "true"/>
+"
+" second line:
+"     ant with javac
+"
+" note that this will work also for tasks like [wtkbuild]
+"
+CompilerSet errorformat=\ %#[%.%#]\ %#%f:%l:%v:%*\\d:%*\\d:\ %t%[%^:]%#:%m,
+    \%A\ %#[%.%#]\ %f:%l:\ %m,%-Z\ %#[%.%#]\ %p^,%C\ %#[%.%#]\ %#%m
+
+" ,%-C%.%#
+
+let &cpo = s:cpo_save
+unlet s:cpo_save
--- /dev/null
+++ b/lib/vimfiles/compiler/bcc.vim
@@ -1,0 +1,19 @@
+" Vim compiler file
+" Compiler:		bcc - Borland C
+" Maintainer:	Emile van Raaij (eraaij@xs4all.nl)
+" Last Change:	2004 Mar 27
+
+if exists("current_compiler")
+  finish
+endif
+let current_compiler = "bcc"
+
+if exists(":CompilerSet") != 2		" older Vim always used :setlocal
+  command -nargs=* CompilerSet setlocal <args>
+endif
+
+" A workable errorformat for Borland C
+CompilerSet errorformat=%*[^0-9]%n\ %f\ %l:\ %m
+
+" default make
+CompilerSet makeprg=make
--- /dev/null
+++ b/lib/vimfiles/compiler/bdf.vim
@@ -1,0 +1,22 @@
+" Vim compiler file
+" Compiler:         BDF to PCF Conversion
+" Maintainer:       Nikolai Weibull <now@bitwi.se>
+" Latest Revision:  2006-04-19
+
+if exists("current_compiler")
+  finish
+endif
+let current_compiler = "bdf"
+
+let s:cpo_save = &cpo
+set cpo-=C
+
+setlocal makeprg=bdftopcf\ $*
+
+setlocal errorformat=%ABDF\ %trror\ on\ line\ %l:\ %m,
+      \%-Z%p^,
+      \%Cbdftopcf:\ bdf\ input\\,\ %f\\,\ corrupt,
+      \%-G%.%#
+
+let &cpo = s:cpo_save
+unlet s:cpo_save
--- /dev/null
+++ b/lib/vimfiles/compiler/checkstyle.vim
@@ -1,0 +1,20 @@
+" Vim compiler file
+" Compiler:	Checkstyle
+" Maintainer:	Doug Kearns <djkea2@gus.gscit.monash.edu.au>
+" URL:		http://gus.gscit.monash.edu.au/~djkea2/vim/compiler/checkstyle.vim
+" Last Change:	2004 Nov 27
+
+if exists("current_compiler")
+  finish
+endif
+let current_compiler = "checkstyle"
+
+if exists(":CompilerSet") != 2		" older Vim always used :setlocal
+  command -nargs=* CompilerSet setlocal <args>
+endif
+
+CompilerSet makeprg=java\ com.puppycrawl.tools.checkstyle.Main\ -f\ plain
+
+" sample error: WebTable.java:282: '+=' is not preceeded with whitespace.
+"		WebTable.java:201:1: '{' should be on the previous line.
+CompilerSet errorformat=%f:%l:\ %m,%f:%l:%v:\ %m,%-G%.%#
--- /dev/null
+++ b/lib/vimfiles/compiler/cs.vim
@@ -1,0 +1,19 @@
+" Vim compiler file
+" Compiler:	ms C#
+" Maintainer:	Joseph H. Yao (hyao@sina.com)
+" Last Change:	2004 Mar 27
+
+if exists("current_compiler")
+  finish
+endif
+let current_compiler = "cs"
+
+if exists(":CompilerSet") != 2		" older Vim always used :setlocal
+  command -nargs=* CompilerSet setlocal <args>
+endif
+
+" default errorformat
+CompilerSet errorformat&
+
+" default make
+CompilerSet makeprg=csc\ %
--- /dev/null
+++ b/lib/vimfiles/compiler/decada.vim
@@ -1,0 +1,54 @@
+"------------------------------------------------------------------------------
+"  Description: Vim Ada/Dec Ada compiler file
+"     Language: Ada (Dec Ada)
+"          $Id: decada.vim,v 1.1 2007/05/05 18:09:54 vimboss Exp $
+"    Copyright: Copyright (C) 2006 Martin Krischik
+"   Maintainer:	Martin Krischik
+"      $Author: vimboss $
+"        $Date: 2007/05/05 18:09:54 $
+"      Version: 4.2
+"    $Revision: 1.1 $
+"     $HeadURL: https://svn.sourceforge.net/svnroot/gnuada/trunk/tools/vim/compiler/decada.vim $
+"      History: 21.07.2006 MK New Dec Ada
+"               15.10.2006 MK Bram's suggestion for runtime integration
+"    Help Page: compiler-decada
+"------------------------------------------------------------------------------
+
+if (exists("current_compiler")	    &&
+   \ current_compiler == "decada")  ||
+   \ version < 700
+   finish
+endif
+
+let current_compiler = "decada"
+
+if !exists("g:decada")
+   let g:decada = decada#New ()
+endif
+
+if exists(":CompilerSet") != 2
+   "
+   " plugin loaded by other means then the "compiler" command
+   "
+   command -nargs=* CompilerSet setlocal <args>
+endif
+
+call g:decada.Set_Session ()
+
+execute "CompilerSet makeprg="     . escape (g:decada.Make_Command, ' ')
+execute "CompilerSet errorformat=" . escape (g:decada.Error_Format, ' ')
+
+call ada#Map_Menu (
+  \'Dec Ada.Build',
+  \'<F7>',
+  \'call decada.Make ()')
+
+finish " 1}}}
+
+"------------------------------------------------------------------------------
+"   Copyright (C) 2006  Martin Krischik
+"
+"   Vim is Charityware - see ":help license" or uganda.txt for licence details.
+"------------------------------------------------------------------------------
+" vim: textwidth=78 wrap tabstop=8 shiftwidth=3 softtabstop=3 noexpandtab
+" vim: foldmethod=marker
--- /dev/null
+++ b/lib/vimfiles/compiler/dot.vim
@@ -1,0 +1,15 @@
+" Vim compiler file
+" Compiler:     ATT dot
+" Maintainer:	Marcos Macedo <bar4ka@bol.com.br>
+" Last Change:	2004 May 16
+
+if exists("current_compiler")
+  finish
+endif
+let current_compiler = "dot"
+
+if exists(":CompilerSet") != 2		" older Vim always used :setlocal
+  command -nargs=* CompilerSet setlocal <args>
+endif
+
+CompilerSet makeprg=dot\ -T$*\ \"%:p\"\ -o\ \"%:p:r.$*\"
--- /dev/null
+++ b/lib/vimfiles/compiler/eruby.vim
@@ -1,0 +1,41 @@
+" Vim compiler file
+" Language:		eRuby
+" Maintainer:		Doug Kearns <dougkearns@gmail.com>
+" Info:			$Id: eruby.vim,v 1.4 2006/04/15 20:22:51 vimboss Exp $
+" URL:			http://vim-ruby.rubyforge.org
+" Anon CVS:		See above site
+" Release Coordinator:	Doug Kearns <dougkearns@gmail.com>
+
+if exists("current_compiler")
+  finish
+endif
+let current_compiler = "eruby"
+
+if exists(":CompilerSet") != 2		" older Vim always used :setlocal
+  command -nargs=* CompilerSet setlocal <args>
+endif
+
+let s:cpo_save = &cpo
+set cpo-=C
+
+if exists("eruby_compiler") && eruby_compiler == "eruby"
+  CompilerSet makeprg=eruby
+else
+  CompilerSet makeprg=erb
+endif
+
+CompilerSet errorformat=
+    \eruby:\ %f:%l:%m,
+    \%+E%f:%l:\ parse\ error,
+    \%W%f:%l:\ warning:\ %m,
+    \%E%f:%l:in\ %*[^:]:\ %m,
+    \%E%f:%l:\ %m,
+    \%-C%\tfrom\ %f:%l:in\ %.%#,
+    \%-Z%\tfrom\ %f:%l,
+    \%-Z%p^,
+    \%-G%.%#
+
+let &cpo = s:cpo_save
+unlet s:cpo_save
+
+" vim: nowrap sw=2 sts=2 ts=8 ff=unix:
--- /dev/null
+++ b/lib/vimfiles/compiler/fortran_F.vim
@@ -1,0 +1,27 @@
+" Vim compiler file
+" Compiler:	Fortran Company/NAGWare F compiler
+" URL:		http://www.unb.ca/chem/ajit/compiler/fortran_F.vim
+" Maintainer:	Ajit J. Thakkar (ajit AT unb.ca); <http://www.unb.ca/chem/ajit/>
+" Version:	0.2
+" Last Change: 2004 Mar 27
+
+if exists("current_compiler")
+  finish
+endif
+let current_compiler = "fortran_F"
+
+if exists(":CompilerSet") != 2		" older Vim always used :setlocal
+  command -nargs=* CompilerSet setlocal <args>
+endif
+
+let s:cposet=&cpoptions
+set cpoptions-=C
+
+CompilerSet errorformat=%trror:\ %f\\,\ line\ %l:%m,
+      \%tarning:\ %f\\,\ line\ %l:%m,
+      \%tatal\ Error:\ %f\\,\ line\ %l:%m,
+      \%-G%.%#
+CompilerSet makeprg=F
+
+let &cpoptions=s:cposet
+unlet s:cposet
--- /dev/null
+++ b/lib/vimfiles/compiler/fortran_cv.vim
@@ -1,0 +1,30 @@
+" Vim compiler file
+" Compiler:	Compaq Visual Fortran
+" Maintainer:	Joh.-G. Simon (johann-guenter.simon@linde-le.com)
+" Last Change:	11/05/2002
+
+if exists("current_compiler")
+  finish
+endif
+let current_compiler = "fortran_cv"
+
+if exists(":CompilerSet") != 2		" older Vim always used :setlocal
+  command -nargs=* CompilerSet setlocal <args>
+endif
+
+let s:cposet = &cpoptions
+set cpoptions-=C
+
+" A workable errorformat for Compaq Visual Fortran
+CompilerSet errorformat=
+		\%E%f(%l)\ :\ Error:%m,
+		\%W%f(%l)\ :\ Warning:%m,
+		\%-Z%p%^%.%#,
+		\%-G%.%#,
+" Compiler call
+CompilerSet makeprg=df\ /nologo\ /noobj\ /c\ %
+" Visual fortran defaults to printing output on stderr
+" Adjust option shellpipe accordingly
+
+let &cpoptions = s:cposet
+unlet s:cposet
--- /dev/null
+++ b/lib/vimfiles/compiler/fortran_elf90.vim
@@ -1,0 +1,33 @@
+" Vim compiler file
+" Compiler:	Essential Lahey Fortran 90
+"		Probably also works for Lahey Fortran 90
+" URL:		http://www.unb.ca/chem/ajit/compiler/fortran_elf90.vim
+" Maintainer:	Ajit J. Thakkar (ajit AT unb.ca); <http://www.unb.ca/chem/ajit/>
+" Version:	0.2
+" Last Change: 2004 Mar 27
+
+if exists("current_compiler")
+  finish
+endif
+let current_compiler = "fortran_elf90"
+
+if exists(":CompilerSet") != 2		" older Vim always used :setlocal
+  command -nargs=* CompilerSet setlocal <args>
+endif
+
+let s:cposet=&cpoptions
+set cpoptions-=C
+
+CompilerSet errorformat=\%ALine\ %l\\,\ file\ %f,
+      \%C%tARNING\ --%m,
+      \%C%tATAL\ --%m,
+      \%C%tBORT\ --%m,
+      \%+C%\\l%.%#\.,
+      \%C%p\|,
+      \%C%.%#,
+      \%Z%$,
+      \%-G%.%#
+CompilerSet makeprg=elf90
+
+let &cpoptions=s:cposet
+unlet s:cposet
--- /dev/null
+++ b/lib/vimfiles/compiler/fortran_g77.vim
@@ -1,0 +1,48 @@
+" Vim compiler file
+" Compiler:     g77 (GNU Fortran)
+" Maintainer:   Ralf Wildenhues <Ralf.Wildenhues@gmx.de>
+" Last Change:  $Date: 2004/06/13 18:17:36 $
+" $Revision: 1.1 $
+
+if exists("current_compiler")
+  finish
+endif
+let current_compiler = "fortran_g77"
+
+if exists(":CompilerSet") != 2		" older Vim always used :setlocal
+  command -nargs=* CompilerSet setlocal <args>
+endif
+
+let s:cpo_save = &cpo
+set cpo-=C
+
+" Note: The errorformat assumes GNU make
+
+" sample multiline errors (besides gcc backend one-liners):
+" gev.f:14:
+"	   parameter UPLO = 'Upper-triangle'
+"	   ^
+" Unsupported VXT statement at (^)
+" gev.f:6:
+"	   integer	   desca( * ), descb( * )
+"			   1
+" gev.f:19: (continued):
+"	   end subroutine
+"	   2
+" Invalid declaration of or reference to symbol `desca' at (2) [initially seen at (1)]
+
+CompilerSet errorformat=
+	\%Omake:\ %r,
+	\%f:%l:\ warning:\ %m,
+	\%A%f:%l:\ (continued):,
+	\%W%f:%l:\ warning:,
+	\%A%f:%l:\ ,
+	\%-C\ \ \ %p%*[0123456789^]%.%#,
+	\%-C\ \ \ %.%#,
+	\%D%*\\a[%*\\d]:\ Entering\ directory\ `%f',
+	\%X%*\\a[%*\\d]:\ Leaving\ directory\ `%f',
+	\%DMaking\ %*\\a\ in\ %f,
+	\%Z%m
+
+let &cpo = s:cpo_save
+unlet s:cpo_save
--- /dev/null
+++ b/lib/vimfiles/compiler/fortran_lf95.vim
@@ -1,0 +1,27 @@
+" Vim compiler file
+" Compiler:	Lahey/Fujitsu Fortran 95
+" URL:		http://www.unb.ca/chem/ajit/compiler/fortran_lf95.vim
+" Maintainer:	Ajit J. Thakkar (ajit AT unb.ca); <http://www.unb.ca/chem/ajit/>
+" Version:	0.2
+" Last Change: 2004 Mar 27
+
+if exists("current_compiler")
+  finish
+endif
+let current_compiler = "fortran_lf95"
+
+if exists(":CompilerSet") != 2		" older Vim always used :setlocal
+  command -nargs=* CompilerSet setlocal <args>
+endif
+
+let s:cposet=&cpoptions
+set cpoptions-=C
+
+CompilerSet errorformat=\ %#%n-%t:\ \"%f\"\\,\ line\ %l:%m,
+      \Error\ LINK\.%n:%m,
+      \Warning\ LINK\.%n:%m,
+      \%-G%.%#
+CompilerSet makeprg=lf95
+
+let &cpoptions=s:cposet
+unlet s:cposet
--- /dev/null
+++ b/lib/vimfiles/compiler/fpc.vim
@@ -1,0 +1,17 @@
+" Vim compiler file
+" Compiler:     FPC 2.1
+" Maintainer:   Jaroslaw Blasiok <jaro3000@o2.pl>
+" Last Change:  2005 October 07
+
+if exists("current_compiler")
+  finish
+endif
+let current_compiler = "fpc"
+
+if exists(":CompilerSet") != 2		" older Vim always used :setlocal
+  command -nargs=* CompilerSet setlocal <args>
+endif
+
+" NOTE: compiler must be runned with -vb to write whole source path, not only file
+" name.
+CompilerSet errorformat=%f(%l\\,%c)\ %m
--- /dev/null
+++ b/lib/vimfiles/compiler/gcc.vim
@@ -1,0 +1,32 @@
+" Vim compiler file
+" Compiler:         GNU C Compiler
+" Maintainer:       Nikolai Weibull <now@bitwi.se>
+" Latest Revision:  2006-12-20
+
+if exists("current_compiler")
+  finish
+endif
+let current_compiler = "gcc"
+
+let s:cpo_save = &cpo
+set cpo-=C
+
+setlocal errorformat=
+      \%*[^\"]\"%f\"%*\\D%l:\ %m,
+      \\"%f\"%*\\D%l:\ %m,
+      \%-G%f:%l:\ %trror:\ (Each\ undeclared\ identifier\ is\ reported\ only\ once,
+      \%-G%f:%l:\ %trror:\ for\ each\ function\ it\ appears\ in.),
+      \%f:%l:\ %m,
+      \\"%f\"\\,\ line\ %l%*\\D%c%*[^\ ]\ %m,
+      \%D%*\\a[%*\\d]:\ Entering\ directory\ `%f',
+      \%X%*\\a[%*\\d]:\ Leaving\ directory\ `%f',
+      \%D%*\\a:\ Entering\ directory\ `%f',
+      \%X%*\\a:\ Leaving\ directory\ `%f',
+      \%DMaking\ %*\\a\ in\ %f
+
+if exists('g:compiler_gcc_ignore_unmatched_lines')
+  let &errorformat .= ',%-G%.%#'
+endif
+
+let &cpo = s:cpo_save
+unlet s:cpo_save
--- /dev/null
+++ b/lib/vimfiles/compiler/gnat.vim
@@ -1,0 +1,71 @@
+"------------------------------------------------------------------------------
+"  Description: Vim Ada/GNAT compiler file
+"     Language: Ada (GNAT)
+"          $Id: gnat.vim,v 1.1 2007/05/05 18:04:19 vimboss Exp $
+"    Copyright: Copyright (C) 2006 Martin Krischik
+"   Maintainer:	Martin Krischik
+"      $Author: vimboss $
+"        $Date: 2007/05/05 18:04:19 $
+"      Version: 4.2
+"    $Revision: 1.1 $
+"     $HeadURL: https://svn.sourceforge.net/svnroot/gnuada/trunk/tools/vim/compiler/gnat.vim $
+"      History: 24.05.2006 MK Unified Headers
+"		16.07.2006 MK Ada-Mode as vim-ball
+"               15.10.2006 MK Bram's suggestion for runtime integration
+"    Help Page: compiler-gnat
+"------------------------------------------------------------------------------
+
+if (exists("current_compiler")	    &&
+   \ current_compiler == "gnat")    ||
+   \ version < 700
+   finish
+endif
+
+let current_compiler = "gnat"
+
+if !exists("g:gnat")
+   let g:gnat = gnat#New ()
+
+   call ada#Map_Menu (
+      \ 'GNAT.Build',
+      \ '<F7>',
+      \ 'call gnat.Make ()')
+   call ada#Map_Menu (
+      \ 'GNAT.Pretty Print',
+      \ ':GnatPretty',
+      \ 'call gnat.Pretty ()')
+   call ada#Map_Menu (
+      \ 'GNAT.Tags',
+      \ ':GnatTags',
+      \ 'call gnat.Tags ()')
+   call ada#Map_Menu (
+      \ 'GNAT.Find',
+      \ ':GnatFind',
+      \ 'call gnat.Find ()')
+   call ada#Map_Menu (
+      \ 'GNAT.Set Projectfile\.\.\.',
+      \ ':SetProject',
+      \ 'call gnat.Set_Project_File ()')
+endif
+
+if exists(":CompilerSet") != 2
+   "
+   " plugin loaded by other means then the "compiler" command
+   "
+   command -nargs=* CompilerSet setlocal <args>
+endif
+
+call g:gnat.Set_Session ()
+
+execute "CompilerSet makeprg="     . escape (g:gnat.Get_Command('Make'), ' ')
+execute "CompilerSet errorformat=" . escape (g:gnat.Error_Format, ' ')
+
+finish " 1}}}
+
+"------------------------------------------------------------------------------
+"   Copyright (C) 2006  Martin Krischik
+"
+"   Vim is Charityware - see ":help license" or uganda.txt for licence details.
+"------------------------------------------------------------------------------
+" vim: textwidth=0 wrap tabstop=8 shiftwidth=3 softtabstop=3 noexpandtab
+" vim: foldmethod=marker
--- /dev/null
+++ b/lib/vimfiles/compiler/hp_acc.vim
@@ -1,0 +1,33 @@
+" Vim compiler file
+" Compiler:	HP aCC
+" Maintainer:	Matthias Ulrich <matthias-ulrich@web.de>
+" URL:          http://www.subhome.de/vim/hp_acc.vim
+" Last Change:	2005 Nov 19
+"
+"  aCC --version says: "HP ANSI C++ B3910B A.03.13"
+"  This compiler has been tested on:
+"       hp-ux 10.20, hp-ux 11.0 and hp-ux 11.11 (64bit)
+"
+"  Tim Brown's aCC is: "HP ANSI C++ B3910B A.03.33"
+"  and it also works fine...
+"  
+"  Now suggestions by aCC are supported (compile flag aCC +w).
+"  Thanks to Tim Brown again!!
+"  
+
+if exists("current_compiler")
+  finish
+endif
+let current_compiler = "hp_acc"
+
+if exists(":CompilerSet") != 2		" older Vim always used :setlocal
+  command -nargs=* CompilerSet setlocal <args>
+endif
+
+CompilerSet errorformat=%A%trror\ %n\:\ \"%f\"\\,\ line\ %l\ \#\ %m,
+         \%A%tarning\ (suggestion)\ %n\:\ \"%f\"\\,\ line\ %l\ \#\ %m\ %#,
+         \%A%tarning\ %n\:\ \"%f\"\\,\ line\ %l\ \#\ %m\ %#,
+         \%Z\ \ \ \ %p^%.%#,
+         \%-C%.%#
+
+" vim:ts=8:sw=4:cindent
--- /dev/null
+++ b/lib/vimfiles/compiler/icc.vim
@@ -1,0 +1,18 @@
+" Vim compiler file
+" Compiler:		icc - Intel C++
+" Maintainer: Peter Puck <PtrPck@netscape.net>
+" Last Change: 2004 Mar 27
+
+if exists("current_compiler")
+  finish
+endif
+let current_compiler = "icc"
+
+if exists(":CompilerSet") != 2		" older Vim always used :setlocal
+  command -nargs=* CompilerSet setlocal <args>
+endif
+
+" I think that Intel is calling the compiler icl under Windows
+
+CompilerSet errorformat=%-Z%p^,%f(%l):\ remark\ #%n:%m,%f(%l)\ :\ (col.\ %c)\ remark:\ %m,%E%f(%l):\ error:\ %m,%E%f(%l):\ error:\ #%n:\ %m,%W%f(%l):\ warning\ #%n:\ %m,%W%f(%l):\ warning:\ %m,%-C%.%#
+
--- /dev/null
+++ b/lib/vimfiles/compiler/intel.vim
@@ -1,0 +1,21 @@
+" Vim compiler file
+" Compiler:     Intel C++ 7.1
+" Maintainer:   David Harrison <david_jr@users.sourceforge.net>
+" Last Change:  2004 May 16
+
+if exists("current_compiler")
+  finish
+endif
+let current_compiler = "intel"
+
+if exists(":CompilerSet") != 2		" older Vim always used :setlocal
+  command -nargs=* CompilerSet setlocal <args>
+endif
+
+CompilerSet errorformat=%E%f(%l):\ error:\ %m,
+		    \%W%f(%l):\ warning:\ %m,
+		    \%I%f(%l):\ remark\ #%n:\ %m,
+		    \%+C\ \ %m.,
+		    \%-Z\ \ %p^,
+		    \%-G\\s%#,
+		    \%-G%.%#
--- /dev/null
+++ b/lib/vimfiles/compiler/irix5_c.vim
@@ -1,0 +1,21 @@
+" Vim compiler file
+" Compiler:	SGI IRIX 5.3 cc
+" Maintainer:	David Harrison <david_jr@users.sourceforge.net>
+" Last Change:	2004 Mar 27
+
+if exists("current_compiler")
+  finish
+endif
+let current_compiler = "irix5_c"
+
+if exists(":CompilerSet") != 2		" older Vim always used :setlocal
+  command -nargs=* CompilerSet setlocal <args>
+endif
+
+CompilerSet errorformat=\%Ecfe:\ Error:\ %f\\,\ line\ %l:\ %m,
+		     \%Wcfe:\ Warning:\ %n:\ %f\\,\ line\ %l:\ %m,
+		     \%Wcfe:\ Warning\ %n:\ %f\\,\ line\ %l:\ %m,
+		     \%W(%l)\ \ Warning\ %n:\ %m,
+		     \%-Z\ %p^,
+		     \-G\\s%#,
+		     \%-G%.%#
--- /dev/null
+++ b/lib/vimfiles/compiler/irix5_cpp.vim
@@ -1,0 +1,21 @@
+" Vim compiler file
+" Compiler:	SGI IRIX 5.3 CC or NCC
+" Maintainer:	David Harrison <david_jr@users.sourceforge.net>
+" Last Change:	2004 Mar 27
+
+if exists("current_compiler")
+  finish
+endif
+let current_compiler = "irix5_cpp"
+
+if exists(":CompilerSet") != 2		" older Vim always used :setlocal
+  command -nargs=* CompilerSet setlocal <args>
+endif
+
+CompilerSet errorformat=%E\"%f\"\\,\ line\ %l:\ error(%n):\ ,
+		    \%E\"%f\"\\,\ line\ %l:\ error(%n):\ %m,
+		    \%W\"%f\"\\,\ line\ %l:\ warning(%n):\ %m,
+		    \%+IC++\ prelinker:\ %m,
+		      \%-Z\ \ %p%^,
+		      \%+C\ %\\{10}%.%#,
+		      \%-G%.%#
--- /dev/null
+++ b/lib/vimfiles/compiler/javac.vim
@@ -1,0 +1,18 @@
+" Vim compiler file
+" Compiler:     javac
+" Maintainer:   Doug Kearns <djkea2@gus.gscit.monash.edu.au>
+" URL:		http://gus.gscit.monash.edu.au/~djkea2/vim/compiler/javac.vim
+" Last Change:  2004 Nov 27
+
+if exists("current_compiler")
+  finish
+endif
+let current_compiler = "javac"
+
+if exists(":CompilerSet") != 2		" older Vim always used :setlocal
+  command -nargs=* CompilerSet setlocal <args>
+endif
+
+CompilerSet makeprg=javac
+
+CompilerSet errorformat=%E%f:%l:\ %m,%-Z%p^,%-C%.%#,%-G%.%#
--- /dev/null
+++ b/lib/vimfiles/compiler/jikes.vim
@@ -1,0 +1,18 @@
+" Vim Compiler File
+" Compiler:	Jikes
+" Maintainer:	Dan Sharp <dwsharp at hotmail dot com>
+" Last Change:	2004 Mar 27
+" URL:		http://mywebpage.netscape.com/sharppeople/vim/compiler
+
+if exists("current_compiler")
+  finish
+endif
+let current_compiler = "jikes"
+
+if exists(":CompilerSet") != 2		" older Vim always used :setlocal
+  command -nargs=* CompilerSet setlocal <args>
+endif
+
+" Jikes defaults to printing output on stderr
+CompilerSet makeprg=jikes\ -Xstdout\ +E\ \"%\"
+CompilerSet errorformat=%f:%l:%v:%*\\d:%*\\d:%*\\s%m
--- /dev/null
+++ b/lib/vimfiles/compiler/mcs.vim
@@ -1,0 +1,24 @@
+" Vim compiler file
+" Compiler:    Mono C# Compiler
+" Maintainer:  Jarek Sobiecki <harijari@go2.pl>
+" Latest Revision: 2006-06-18
+
+if exists("current_compiler")
+  finish
+endif
+let current_compiler = "mcs"
+
+let s:cpo_save = &cpo
+set cpo-=C
+
+setlocal errorformat=
+         \%E%f(%l\\,%c):\ error\ CS%n:%m,
+         \%W%f(%l\\,%c):\ warning\ CS%n:%m,
+         \%E%>syntax\ error\\,%m,%Z%f(%l\\,%c):\ error\ CS%n:%m,
+         \%D%*\\a[%*\\d]:\ Entering\ directory\ `%f',
+         \%X%*\\a[%*\\d]:\ Leaving\ directory\ `%f',
+         \%DMaking\ %*\\a\ in\ %f,
+         \%G-%.%#
+
+let &cpo = s:cpo_save
+unlet s:cpo_save
--- /dev/null
+++ b/lib/vimfiles/compiler/mips_c.vim
@@ -1,0 +1,21 @@
+" Vim compiler file
+" Compiler:	SGI IRIX 6.5 MIPS C (cc)
+" Maintainer:	David Harrison <david_jr@users.sourceforge.net>
+" Last Change:	2004 Mar 27
+
+if exists("current_compiler")
+  finish
+endif
+let current_compiler = "mips_c"
+
+if exists(":CompilerSet") != 2		" older Vim always used :setlocal
+  command -nargs=* CompilerSet setlocal <args>
+endif
+
+CompilerSet errorformat=%Ecc\-%n\ %.%#:\ ERROR\ File\ =\ %f\%\\,\ Line\ =\ %l,
+		    \%Wcc\-%n\ %.%#:\ WARNING\ File\ =\ %f\%\\,\ Line\ =\ %l,
+		    \%Icc\-%n\ %.%#:\ REMARK\ File\ =\ %f\%\\,\ Line\ =\ %l,
+		    \%+C\ \ %m.,
+		    \%-Z\ \ %p^,
+		    \%-G\\s%#,
+		    \%-G%.%#
--- /dev/null
+++ b/lib/vimfiles/compiler/mipspro_c89.vim
@@ -1,0 +1,22 @@
+" Vim compiler file
+" Compiler:	SGI IRIX 6.5 MIPSPro C (c89)
+" Maintainer:	David Harrison <david_jr@users.sourceforge.net>
+" Last Change:	2004 Mar 27
+
+if exists("current_compiler")
+  finish
+endif
+let current_compiler = "mipspro_c89"
+
+if exists(":CompilerSet") != 2		" older Vim always used :setlocal
+  command -nargs=* CompilerSet setlocal <args>
+endif
+
+CompilerSet errorformat=%Ecc\-%n\ %.%#:\ ERROR\ File\ =\ %f\%\\,\ Line\ =\ %l,
+		    \%Wcc\-%n\ %.%#:\ WARNING\ File\ =\ %f\%\\,\ Line\ =\ %l,
+		    \%Icc\-%n\ %.%#:\ REMARK\ File\ =\ %f\%\\,\ Line\ =\ %l,
+		    \%-Z%p%^,
+		    \%+C\ %\\{10}%m%.,
+		    \%+C\ \ %m,
+		    \%-G\\s%#,
+		    \%-G%.%#
--- /dev/null
+++ b/lib/vimfiles/compiler/mipspro_cpp.vim
@@ -1,0 +1,21 @@
+" Vim compiler file
+" Compiler:	SGI IRIX 6.5 MIPSPro C++ (CC)
+" Maintainer:	David Harrison <david_jr@users.sourceforge.net>
+" Last Change:	2004 Mar 27
+
+if exists("current_compiler")
+  finish
+endif
+let current_compiler = "mipspro_cpp"
+
+if exists(":CompilerSet") != 2		" older Vim always used :setlocal
+  command -nargs=* CompilerSet setlocal <args>
+endif
+
+CompilerSet errorformat=%Ecc\-%n\ %.%#:\ ERROR\ File\ =\ %f\%\\,\ Line\ =\ %l,
+		    \%Wcc\-%n\ %.%#:\ WARNING\ File\ =\ %f\%\\,\ Line\ =\ %l,
+		    \%Icc\-%n\ %.%#:\ REMARK\ File\ =\ %f\%\\,\ Line\ =\ %l,
+		    \%+C\ \ %m.,
+		    \%-Z\ \ %p^,
+		    \%-G\\s%#,
+		    \%-G%.%#
--- /dev/null
+++ b/lib/vimfiles/compiler/modelsim_vcom.vim
@@ -1,0 +1,20 @@
+" Vim Compiler File
+" Compiler:	Modelsim Vcom
+" Maintainer:	Paul Baleme <pbaleme@mail.com>
+" Last Change:	September 8, 2003
+" Thanks to:    allanherriman@hotmail.com
+
+if exists("current_compiler")
+  finish
+endif
+let current_compiler = "modelsim_vcom"
+
+if exists(":CompilerSet") != 2		" older Vim always used :setlocal
+  command -nargs=* CompilerSet setlocal <args>
+endif
+
+"setlocal errorformat=\*\*\ %tRROR:\ %f(%l):\ %m,%tRROR:\ %f(%l):\ %m,%tARNING\[%*[0-9]\]:\ %f(%l):\ %m,\*\*\ %tRROR:\ %m,%tRROR:\ %m,%tARNING\[%*[0-9]\]:\ %m
+
+"setlocal errorformat=%tRROR:\ %f(%l):\ %m,%tARNING\[%*[0-9]\]:\ %m
+CompilerSet errorformat=\*\*\ %tRROR:\ %f(%l):\ %m,\*\*\ %tRROR:\ %m,\*\*\ %tARNING:\ %m,\*\*\ %tOTE:\ %m,%tRROR:\ %f(%l):\ %m,%tARNING\[%*[0-9]\]:\ %f(%l):\ %m,%tRROR:\ %m,%tARNING\[%*[0-9]\]:\ %m
+
--- /dev/null
+++ b/lib/vimfiles/compiler/msvc.vim
@@ -1,0 +1,13 @@
+" Vim compiler file
+" Compiler:	Miscrosoft Visual C
+" Maintainer:	Bram Moolenaar <Bram@vim.org>
+" Last Change:	2005 Nov 30
+
+if exists("current_compiler")
+  finish
+endif
+let current_compiler = "msvc"
+
+" The errorformat for MSVC is the default.
+CompilerSet errorformat&
+CompilerSet makeprg=nmake
--- /dev/null
+++ b/lib/vimfiles/compiler/neato.vim
@@ -1,0 +1,15 @@
+" Vim compiler file
+" Compiler:     ATT neato
+" Maintainer:	Marcos Macedo <bar4ka@bol.com.br>
+" Last Change:	2004 May 16
+
+if exists("current_compiler")
+  finish
+endif
+let current_compiler = "neato"
+
+if exists(":CompilerSet") != 2		" older Vim always used :setlocal
+  command -nargs=* CompilerSet setlocal <args>
+endif
+
+CompilerSet makeprg=neato\ -T$*\ \"%:p\"\ -o\ \"%:p:r.$*\"
--- /dev/null
+++ b/lib/vimfiles/compiler/onsgmls.vim
@@ -1,0 +1,24 @@
+" Vim compiler file
+" Compiler:	onsgmls
+" Maintainer:	Robert Rowsome <rowsome@wam.umd.edu>
+" Last Change:	2004 Mar 27
+
+if exists("current_compiler")
+  finish
+endif
+let current_compiler = "onsgmls"
+
+if exists(":CompilerSet") != 2		" older Vim always used :setlocal
+  command -nargs=* CompilerSet setlocal <args>
+endif
+
+let s:cpo_save = &cpo
+set cpo-=C
+
+CompilerSet makeprg=onsgmls\ -s\ %
+
+CompilerSet errorformat=onsgmls:%f:%l:%c:%t:%m,
+		    \onsgmls:%f:%l:%c:%m
+
+let &cpo = s:cpo_save
+unlet s:cpo_save
--- /dev/null
+++ b/lib/vimfiles/compiler/pbx.vim
@@ -1,0 +1,20 @@
+" Vim compiler file
+" Compiler:	Apple Project Builder
+" Maintainer:	Alexander von Below (public@vonBelow.Com)
+" Last Change:	2004 Mar 27
+
+if exists("current_compiler")
+   finish
+endif
+let current_compiler = "pbx"
+
+if exists(":CompilerSet") != 2		" older Vim always used :setlocal
+  command -nargs=* CompilerSet setlocal <args>
+endif
+
+" The compiler actually is gcc, so the errorformat is unchanged
+CompilerSet errorformat&
+
+" default make
+CompilerSet makeprg=pbxbuild
+
--- /dev/null
+++ b/lib/vimfiles/compiler/perl.vim
@@ -1,0 +1,39 @@
+" Vim Compiler File
+" Compiler:     Perl syntax checks (perl -Wc)
+" Maintainer:   Christian J. Robinson <infynity@onewest.net>
+" Last Change:  2004 Mar 27
+
+if exists("current_compiler")
+  finish
+endif
+let current_compiler = "perl"
+
+if exists(":CompilerSet") != 2		" older Vim always used :setlocal
+  command -nargs=* CompilerSet setlocal <args>
+endif
+
+let s:savecpo = &cpo
+set cpo&vim
+
+if getline(1) =~# '-[^ ]*T'
+	CompilerSet makeprg=perl\ -WTc\ %
+else
+	CompilerSet makeprg=perl\ -Wc\ %
+endif
+
+CompilerSet errorformat=
+	\%-G%.%#had\ compilation\ errors.,
+	\%-G%.%#syntax\ OK,
+	\%m\ at\ %f\ line\ %l.,
+	\%+A%.%#\ at\ %f\ line\ %l\\,%.%#,
+	\%+C%.%#
+
+" Explanation:
+" %-G%.%#had\ compilation\ errors.,  - Ignore the obvious.
+" %-G%.%#syntax\ OK,                 - Don't include the 'a-okay' message.
+" %m\ at\ %f\ line\ %l.,             - Most errors...
+" %+A%.%#\ at\ %f\ line\ %l\\,%.%#,  - As above, including ', near ...'
+" %+C%.%#                            -   ... Which can be multi-line.
+
+let &cpo = s:savecpo
+unlet s:savecpo
--- /dev/null
+++ b/lib/vimfiles/compiler/php.vim
@@ -1,0 +1,28 @@
+" Vim compiler file
+" Compiler:	PHP
+" Maintainer:	Doug Kearns <djkea2@gus.gscit.monash.edu.au>
+" URL:		http://gus.gscit.monash.edu.au/~djkea2/vim/compiler/php.vim
+" Last Change:	2004 Nov 27
+
+if exists("current_compiler")
+  finish
+endif
+let current_compiler = "php"
+
+if exists(":CompilerSet") != 2		" older Vim always used :setlocal
+  command -nargs=* CompilerSet setlocal <args>
+endif
+
+let s:cpo_save = &cpo
+set cpo-=C
+
+CompilerSet makeprg=php\ -lq
+
+CompilerSet errorformat=%E<b>Parse\ error</b>:\ %m\ in\ <b>%f</b>\ on\ line\ <b>%l</b><br\ />,
+		       \%W<b>Notice</b>:\ %m\ in\ <b>%f</b>\ on\ line\ <b>%l</b><br\ />,
+		       \%EParse\ error:\ %m\ in\ %f\ on\ line\ %l,
+		       \%WNotice:\ %m\ in\ %f</b>\ on\ line\ %l,
+		       \%-G%.%#
+
+let &cpo = s:cpo_save
+unlet s:cpo_save
--- /dev/null
+++ b/lib/vimfiles/compiler/pyunit.vim
@@ -1,0 +1,16 @@
+" Vim compiler file
+" Compiler:	Unit testing tool for Python
+" Maintainer:	Max Ischenko <mfi@ukr.net>
+" Last Change: 2004 Mar 27
+
+if exists("current_compiler")
+  finish
+endif
+let current_compiler = "pyunit"
+
+if exists(":CompilerSet") != 2		" older Vim always used :setlocal
+  command -nargs=* CompilerSet setlocal <args>
+endif
+
+CompilerSet efm=%C\ %.%#,%A\ \ File\ \"%f\"\\,\ line\ %l%.%#,%Z%[%^\ ]%\\@=%m
+
--- /dev/null
+++ b/lib/vimfiles/compiler/rst.vim
@@ -1,0 +1,25 @@
+" Vim compiler file
+" Compiler:         reStructuredText Documentation Format
+" Maintainer:       Nikolai Weibull <now@bitwi.se>
+" Latest Revision:  2006-04-19
+
+if exists("current_compiler")
+  finish
+endif
+let current_compiler = "rst"
+
+let s:cpo_save = &cpo
+set cpo-=C
+
+setlocal errorformat=
+      \%f:%l:\ (%tEBUG/0)\ %m,
+      \%f:%l:\ (%tNFO/1)\ %m,
+      \%f:%l:\ (%tARNING/2)\ %m,
+      \%f:%l:\ (%tRROR/3)\ %m,
+      \%f:%l:\ (%tEVERE/3)\ %m,
+      \%D%*\\a[%*\\d]:\ Entering\ directory\ `%f',
+      \%X%*\\a[%*\\d]:\ Leaving\ directory\ `%f',
+      \%DMaking\ %*\\a\ in\ %f
+
+let &cpo = s:cpo_save
+unlet s:cpo_save
--- /dev/null
+++ b/lib/vimfiles/compiler/ruby.vim
@@ -1,0 +1,68 @@
+" Vim compiler file
+" Language:		Ruby
+" Function:		Syntax check and/or error reporting
+" Maintainer:		Tim Hammerquist <timh at rubyforge.org>
+" Info:			$Id: ruby.vim,v 1.6 2006/04/15 20:18:31 vimboss Exp $
+" URL:			http://vim-ruby.rubyforge.org
+" Anon CVS:		See above site
+" Release Coordinator:	Doug Kearns <dougkearns@gmail.com>
+" ----------------------------------------------------------------------------
+"
+" Changelog:
+" 0.2:	script saves and restores 'cpoptions' value to prevent problems with
+"	line continuations
+" 0.1:	initial release
+"
+" Contributors:
+"   Hugh Sasse <hgs@dmu.ac.uk>
+"   Doug Kearns <djkea2@gus.gscit.monash.edu.au>
+"
+" Todo:
+"   match error type %m
+"
+" Comments:
+"   I know this file isn't perfect.  If you have any questions, suggestions,
+"   patches, etc., please don't hesitate to let me know.
+"
+"   This is my first experience with 'errorformat' and compiler plugins and
+"   I welcome any input from more experienced (or clearer-thinking)
+"   individuals.
+" ----------------------------------------------------------------------------
+
+if exists("current_compiler")
+  finish
+endif
+let current_compiler = "ruby"
+
+if exists(":CompilerSet") != 2		" older Vim always used :setlocal
+  command -nargs=* CompilerSet setlocal <args>
+endif
+
+let s:cpo_save = &cpo
+set cpo-=C
+
+" default settings runs script normally
+" add '-c' switch to run syntax check only:
+"
+"   CompilerSet makeprg=ruby\ -wc\ $*
+"
+" or add '-c' at :make command line:
+"
+"   :make -c %<CR>
+"
+CompilerSet makeprg=ruby\ -w\ $*
+
+CompilerSet errorformat=
+    \%+E%f:%l:\ parse\ error,
+    \%W%f:%l:\ warning:\ %m,
+    \%E%f:%l:in\ %*[^:]:\ %m,
+    \%E%f:%l:\ %m,
+    \%-C%\tfrom\ %f:%l:in\ %.%#,
+    \%-Z%\tfrom\ %f:%l,
+    \%-Z%p^,
+    \%-G%.%#
+
+let &cpo = s:cpo_save
+unlet s:cpo_save
+
+" vim: nowrap sw=2 sts=2 ts=8 ff=unix:
--- /dev/null
+++ b/lib/vimfiles/compiler/rubyunit.vim
@@ -1,0 +1,35 @@
+" Vim compiler file
+" Language:		Test::Unit - Ruby Unit Testing Framework
+" Maintainer:		Doug Kearns <dougkearns@gmail.com>
+" Info:			$Id: rubyunit.vim,v 1.4 2006/04/15 20:28:37 vimboss Exp $
+" URL:			http://vim-ruby.rubyforge.org
+" Anon CVS:		See above site
+" Release Coordinator:	Doug Kearns <dougkearns@gmail.com>
+
+if exists("current_compiler")
+  finish
+endif
+let current_compiler = "rubyunit"
+
+if exists(":CompilerSet") != 2		" older Vim always used :setlocal
+  command -nargs=* CompilerSet setlocal <args>
+endif
+
+let s:cpo_save = &cpo
+set cpo-=C
+
+CompilerSet makeprg=testrb
+
+CompilerSet errorformat=\%W\ %\\+%\\d%\\+)\ Failure:,
+			\%C%m\ [%f:%l]:,
+			\%E\ %\\+%\\d%\\+)\ Error:,
+			\%C%m:,
+			\%C\ \ \ \ %f:%l:%.%#,
+			\%C%m,
+			\%Z\ %#,
+			\%-G%.%#
+
+let &cpo = s:cpo_save
+unlet s:cpo_save
+
+" vim: nowrap sw=2 sts=2 ts=8 ff=unix:
--- /dev/null
+++ b/lib/vimfiles/compiler/se.vim
@@ -1,0 +1,28 @@
+" Vim compiler file
+" Compiler:	se (SmartEiffel Compiler)
+" Maintainer:	Doug Kearns <djkea2@gus.gscit.monash.edu.au>
+" URL:		http://gus.gscit.monash.edu.au/~djkea2/vim/compiler/se.vim
+" Last Change:	2004 Nov 27
+
+if exists("current_compiler")
+  finish
+endif
+let current_compiler = "se"
+
+if exists(":CompilerSet") != 2		" older Vim always used :setlocal
+  command -nargs=* CompilerSet setlocal <args>
+endif
+
+let s:cpo_save = &cpo
+set cpo-=C
+
+CompilerSet makeprg=compile\ %
+
+CompilerSet errorformat=%W******\ Warning:\ %m,
+		    \%E******\ Fatal\ Error:\ %m,
+		    \%E******\ Error:\ %m,
+		    \%CLine\ %l\ column\ %c\ in\ %\\w%\\+\ (%f)\ :,
+		    \%-G%.%#
+
+let &cpo = s:cpo_save
+unlet s:cpo_save
--- /dev/null
+++ b/lib/vimfiles/compiler/splint.vim
@@ -1,0 +1,71 @@
+" Vim compiler file
+" Compiler:     splint/lclint (C source code checker)
+" Maintainer:   Ralf Wildenhues <Ralf.Wildenhues@gmx.de>
+" Splint Home:	http://www.splint.org/
+" Last Change:  2005 Apr 21
+" $Revision: 1.3 $
+
+if exists("current_compiler")
+  finish
+endif
+let current_compiler = "splint"
+
+if exists(":CompilerSet") != 2		" older Vim always used :setlocal
+  command -nargs=* CompilerSet setlocal <args>
+endif
+
+let s:cpo_save = &cpo
+set cpo-=C
+
+" adapt this if you want to check more than one file at a time.
+" put command line options in .splintrc or ~/.splintrc
+CompilerSet makeprg=splint\ %
+
+" Note: when using the new array bounds checking flags:  Each warning
+" usually has several lines and several references to source code mostly
+" within one or two lines (see sample warning below).  The easiest way
+" not to mess up file name detection and not to jump to all positions is
+" to add something like
+"	-linelen 500 +boundscompacterrormessages
+" to your .splintrc and 'set cmdheight=4' or more.
+" TODO: reliable way to distinguish file names and constraints.
+"
+" sample warning (generic):
+"
+"foo.c:1006:12: Clauses exit with var referencing local storage in one
+"		       case, fresh storage in other case
+"   foo.c:1003:2: Fresh storage var allocated
+"
+" sample warning (bounds checking):
+"
+"bounds.c: (in function updateEnv)
+"bounds.c:10:5: Possible out-of-bounds store:
+"    strcpy(str, tmp)
+"    Unable to resolve constraint:
+"    requires maxSet(str @ bounds.c:10:13) >= maxRead(getenv("MYENV") @
+"    bounds.c:6:9)
+"     needed to satisfy precondition:
+"    requires maxSet(str @ bounds.c:10:13) >= maxRead(tmp @ bounds.c:10:18)
+"     derived from strcpy precondition: requires maxSet(<parameter 1>) >=
+"    maxRead(<parameter 2>)
+"  A memory write may write to an address beyond the allocated buffer. (Use
+"  -boundswrite to inhibit warning)
+
+CompilerSet errorformat=%OLCLint*m,
+	\%OSplint*m,
+	\%f(%l\\,%c):\ %m,
+	\%*[\ ]%f:%l:%c:\ %m,
+	\%*[\ ]%f:%l:\ %m,
+	\%*[^\"]\"%f\"%*\\D%l:\ %m,
+	\\"%f\"%*\\D%l:\ %m,
+	\%A%f:%l:%c:\ %m,
+	\%A%f:%l:%m,
+	\\"%f\"\\,
+	\\ line\ %l%*\\D%c%*[^\ ]\ %m,
+	\%D%*\\a[%*\\d]:\ Entering\ directory\ `%f',
+	\%X%*\\a[%*\\d]:\ Leaving\ directory\ `%f',
+	\%DMaking\ %*\\a\ in\ %f,
+	\%C\ %#%m
+
+let &cpo = s:cpo_save
+unlet s:cpo_save
--- /dev/null
+++ b/lib/vimfiles/compiler/tcl.vim
@@ -1,0 +1,18 @@
+" Vim compiler file
+" Compiler:	tcl
+" Maintainer:	Doug Kearns <djkea2@gus.gscit.monash.edu.au>
+" URL:		http://gus.gscit.monash.edu.au/~djkea2/vim/compiler/tcl.vim
+" Last Change:	2004 Nov 27
+
+if exists("current_compiler")
+  finish
+endif
+let current_compiler = "tcl"
+
+if exists(":CompilerSet") != 2		" older Vim always used :setlocal
+  command -nargs=* CompilerSet setlocal <args>
+endif
+
+CompilerSet makeprg=tcl
+
+CompilerSet errorformat=%EError:\ %m,%+Z\ %\\{4}(file\ \"%f\"\ line\ %l),%-G%.%#
--- /dev/null
+++ b/lib/vimfiles/compiler/tex.vim
@@ -1,0 +1,68 @@
+" Vim compiler file
+" Compiler:     TeX
+" Maintainer:   Artem Chuprina <ran@ran.pp.ru>
+" Last Change:  2004 Mar 27
+
+if exists("current_compiler")
+	finish
+endif
+
+if exists(":CompilerSet") != 2		" older Vim always used :setlocal
+  command -nargs=* CompilerSet setlocal <args>
+endif
+
+" If makefile exists and we are not asked to ignore it, we use standard make
+" (do not redefine makeprg)
+if exists('b:tex_ignore_makefile') || exists('g:tex_ignore_makefile') ||
+			\(!filereadable('Makefile') && !filereadable('makefile'))
+	" If buffer-local variable 'tex_flavor' exists, it defines TeX flavor,
+	" otherwize the same for global variable with same name, else it will be
+	" LaTeX
+	if exists("b:tex_flavor")
+		let current_compiler = b:tex_flavor
+	elseif exists("g:tex_flavor")
+		let current_compiler = g:tex_flavor
+	else
+		let current_compiler = "latex"
+	endif
+	let &l:makeprg=current_compiler.' -interaction=nonstopmode'
+else
+	let current_compiler = 'make'
+endif
+
+let s:cpo_save = &cpo
+set cpo-=C
+
+" Value errorformat are taken from vim help, see :help errorformat-LaTeX, with
+" addition from Srinath Avadhanula <srinath@fastmail.fm>
+CompilerSet errorformat=%E!\ LaTeX\ %trror:\ %m,
+	\%E!\ %m,
+	\%+WLaTeX\ %.%#Warning:\ %.%#line\ %l%.%#,
+	\%+W%.%#\ at\ lines\ %l--%*\\d,
+	\%WLaTeX\ %.%#Warning:\ %m,
+	\%Cl.%l\ %m,
+	\%+C\ \ %m.,
+	\%+C%.%#-%.%#,
+	\%+C%.%#[]%.%#,
+	\%+C[]%.%#,
+	\%+C%.%#%[{}\\]%.%#,
+	\%+C<%.%#>%.%#,
+	\%C\ \ %m,
+	\%-GSee\ the\ LaTeX%m,
+	\%-GType\ \ H\ <return>%m,
+	\%-G\ ...%.%#,
+	\%-G%.%#\ (C)\ %.%#,
+	\%-G(see\ the\ transcript%.%#),
+	\%-G\\s%#,
+	\%+O(%*[^()])%r,
+	\%+O%*[^()](%*[^()])%r,
+	\%+P(%f%r,
+	\%+P\ %\\=(%f%r,
+	\%+P%*[^()](%f%r,
+	\%+P[%\\d%[^()]%#(%f%r,
+	\%+Q)%r,
+	\%+Q%*[^()])%r,
+	\%+Q[%\\d%*[^()])%r
+
+let &cpo = s:cpo_save
+unlet s:cpo_save
--- /dev/null
+++ b/lib/vimfiles/compiler/tidy.vim
@@ -1,0 +1,29 @@
+" Vim compiler file
+" Compiler:	HTML Tidy
+" Maintainer:	Doug Kearns <djkea2@gus.gscit.monash.edu.au>
+" URL:		http://gus.gscit.monash.edu.au/~djkea2/vim/compiler/tidy.vim
+" Last Change:	2004 Nov 27
+
+" NOTE: set 'tidy_compiler_040800' if you are using the 4th August 2000 release
+"       of HTML Tidy.
+
+if exists("current_compiler")
+  finish
+endif
+let current_compiler = "tidy"
+
+if exists(":CompilerSet") != 2		" older Vim always used :setlocal
+  command -nargs=* CompilerSet setlocal <args>
+endif
+
+" this is needed to work around a bug in the 04/08/00 release of tidy which
+" failed to set the filename if the -quiet option was used
+if exists("tidy_compiler_040800")
+  CompilerSet makeprg=tidy\ -errors\ --gnu-emacs\ yes\ %
+else
+  CompilerSet makeprg=tidy\ -quiet\ -errors\ --gnu-emacs\ yes\ %
+endif
+
+" sample warning: foo.html:8:1: Warning: inserting missing 'foobar' element
+" sample error:   foo.html:9:2: Error: <foobar> is not recognized!
+CompilerSet errorformat=%f:%l:%c:\ Error:%m,%f:%l:%c:\ Warning:%m,%-G%.%#
--- /dev/null
+++ b/lib/vimfiles/compiler/xmllint.vim
@@ -1,0 +1,29 @@
+" Vim compiler file
+" Compiler:	xmllint
+" Maintainer:	Doug Kearns <djkea2@gus.gscit.monash.edu.au>
+" URL:		http://gus.gscit.monash.edu.au/~djkea2/vim/compiler/xmllint.vim
+" Last Change:	2004 Nov 27
+
+if exists("current_compiler")
+  finish
+endif
+let current_compiler = "xmllint"
+
+if exists(":CompilerSet") != 2		" older Vim always used :setlocal
+  command -nargs=* CompilerSet setlocal <args>
+endif
+
+let s:cpo_save = &cpo
+set cpo-=C
+
+CompilerSet makeprg=xmllint\ --valid\ --noout\ 
+
+CompilerSet errorformat=%E%f:%l:\ error:\ %m,
+		    \%W%f:%l:\ warning:\ %m,
+		    \%E%f:%l:\ validity\ error:\ %m,
+		    \%W%f:%l:\ validity\ warning:\ %m,
+		    \%-Z%p^,
+		    \%-G%.%#
+
+let &cpo = s:cpo_save
+unlet s:cpo_save
--- /dev/null
+++ b/lib/vimfiles/compiler/xmlwf.vim
@@ -1,0 +1,23 @@
+" Vim Compiler File
+" Compiler:	xmlwf
+" Maintainer:	Robert Rowsome <rowsome@wam.umd.edu>
+" Last Change:	2004 Mar 27
+
+if exists("current_compiler")
+  finish
+endif
+let current_compiler = "xmlwf"
+
+let s:cpo_save = &cpo
+set cpo&vim
+
+if exists(":CompilerSet") != 2		" older Vim always used :setlocal
+  command -nargs=* CompilerSet setlocal <args>
+endif
+
+CompilerSet makeprg=xmlwf\ %
+
+CompilerSet errorformat=%f:%l%c:%m
+
+let &cpo = s:cpo_save
+unlet s:cpo_save
--- /dev/null
+++ b/lib/vimfiles/delmenu.vim
@@ -1,0 +1,25 @@
+" This Vim script deletes all the menus, so that they can be redefined.
+" Warning: This also deletes all menus defined by the user!
+"
+" Maintainer:	Bram Moolenaar <Bram@vim.org>
+" Last Change:	2001 May 27
+
+aunmenu *
+
+silent! unlet did_install_default_menus
+silent! unlet did_install_syntax_menu
+if exists("did_menu_trans")
+  menutrans clear
+  unlet did_menu_trans
+endif
+
+silent! unlet find_help_dialog
+
+silent! unlet menutrans_help_dialog
+silent! unlet menutrans_path_dialog
+silent! unlet menutrans_tags_dialog
+silent! unlet menutrans_textwidth_dialog
+silent! unlet menutrans_fileformat_dialog
+silent! unlet menutrans_no_file
+
+" vim: set sw=2 :
--- /dev/null
+++ b/lib/vimfiles/doc/Makefile
@@ -1,0 +1,461 @@
+#
+# Makefile for the Vim documentation on Unix
+#
+# If you get "don't know how to make scratch", first run make in the source
+# directory.  Or remove the include below.
+
+AWK = awk
+
+# Set to $(VIMTARGET) when executed from src/Makefile.
+VIMEXE = vim
+
+# include the config.mk from the source directory.  It's only needed to set
+# AWK, used for "make html".  Comment this out if the include gives problems.
+include ../../src/auto/config.mk
+
+DOCS = \
+	ada.txt \
+	arabic.txt \
+	autocmd.txt \
+	change.txt \
+	cmdline.txt \
+	debugger.txt \
+	debug.txt \
+	develop.txt \
+	diff.txt \
+	digraph.txt \
+	editing.txt \
+	eval.txt \
+	farsi.txt \
+	filetype.txt \
+	fold.txt \
+	gui.txt \
+	gui_w16.txt \
+	gui_w32.txt \
+	gui_x11.txt \
+	hangulin.txt \
+	hebrew.txt \
+	help.txt \
+	howto.txt \
+	if_cscop.txt \
+	if_mzsch.txt \
+	if_ole.txt \
+	if_perl.txt \
+	if_pyth.txt \
+	if_ruby.txt \
+	if_sniff.txt \
+	if_tcl.txt \
+	indent.txt \
+	index.txt \
+	insert.txt \
+	intro.txt \
+	map.txt \
+	message.txt \
+	motion.txt \
+	mbyte.txt \
+	mlang.txt \
+	netbeans.txt \
+	options.txt \
+	os_390.txt \
+	os_amiga.txt \
+	os_beos.txt \
+	os_dos.txt \
+	os_mac.txt \
+	os_mint.txt \
+	os_msdos.txt \
+	os_os2.txt \
+	os_qnx.txt \
+	os_risc.txt \
+	os_unix.txt \
+	os_vms.txt \
+	os_win32.txt \
+	pattern.txt \
+	pi_getscript.txt \
+	pi_gzip.txt \
+	pi_netrw.txt \
+	pi_paren.txt \
+	pi_spec.txt \
+	pi_tar.txt \
+	pi_vimball.txt \
+	pi_zip.txt \
+	print.txt \
+	quickfix.txt \
+	quickref.txt \
+	quotes.txt \
+	recover.txt \
+	remote.txt \
+	repeat.txt \
+	rileft.txt \
+	russian.txt \
+	scroll.txt \
+	sign.txt \
+	sponsor.txt \
+	starting.txt \
+	spell.txt \
+	sql.txt \
+	syntax.txt \
+	tabpage.txt \
+	tagsrch.txt \
+	term.txt \
+	tips.txt \
+	todo.txt \
+	uganda.txt \
+	undo.txt \
+	usr_01.txt \
+	usr_02.txt \
+	usr_03.txt \
+	usr_04.txt \
+	usr_05.txt \
+	usr_06.txt \
+	usr_07.txt \
+	usr_08.txt \
+	usr_09.txt \
+	usr_10.txt \
+	usr_11.txt \
+	usr_12.txt \
+	usr_20.txt \
+	usr_21.txt \
+	usr_22.txt \
+	usr_23.txt \
+	usr_24.txt \
+	usr_25.txt \
+	usr_26.txt \
+	usr_27.txt \
+	usr_28.txt \
+	usr_29.txt \
+	usr_30.txt \
+	usr_31.txt \
+	usr_32.txt \
+	usr_40.txt \
+	usr_41.txt \
+	usr_42.txt \
+	usr_43.txt \
+	usr_44.txt \
+	usr_45.txt \
+	usr_90.txt \
+	usr_toc.txt \
+	various.txt \
+	version4.txt \
+	version5.txt \
+	version6.txt \
+	version7.txt \
+	vi_diff.txt \
+	visual.txt \
+	windows.txt \
+	workshop.txt
+
+HTMLS = \
+	ada.html \
+	arabic.html \
+	autocmd.html \
+	change.html \
+	cmdline.html \
+	debug.html \
+	debugger.html \
+	develop.html \
+	diff.html \
+	digraph.html \
+	editing.html \
+	eval.html \
+	farsi.html \
+	filetype.html \
+	fold.html \
+	gui.html \
+	gui_w16.html \
+	gui_w32.html \
+	gui_x11.html \
+	hangulin.html \
+	hebrew.html \
+	howto.html \
+	if_cscop.html \
+	if_mzsch.html \
+	if_ole.html \
+	if_perl.html \
+	if_pyth.html \
+	if_ruby.html \
+	if_sniff.html \
+	if_tcl.html \
+	indent.html \
+	index.html \
+	vimindex.html \
+	insert.html \
+	intro.html \
+	map.html \
+	message.html \
+	motion.html \
+	mbyte.html \
+	mlang.html \
+	netbeans.html \
+	options.html \
+	os_390.html \
+	os_amiga.html \
+	os_beos.html \
+	os_dos.html \
+	os_mac.html \
+	os_mint.html \
+	os_msdos.html \
+	os_os2.html \
+	os_qnx.html \
+	os_risc.html \
+	os_unix.html \
+	os_vms.html \
+	os_win32.html \
+	pattern.html \
+	pi_getscript.html \
+	pi_gzip.html \
+	pi_netrw.html \
+	pi_paren.html \
+	pi_spec.html \
+	pi_tar.html \
+	pi_vimball.html \
+	pi_zip.html \
+	print.html \
+	quickfix.html \
+	quickref.html \
+	quotes.html \
+	recover.html \
+	remote.html \
+	repeat.html \
+	rileft.html \
+	russian.html \
+	scroll.html \
+	sign.html \
+	sponsor.html \
+	starting.html \
+	spell.html \
+	sql.html \
+	syntax.html \
+	tabpage.html \
+	tags.html \
+	tagsrch.html \
+	term.html \
+	tips.html \
+	todo.html \
+	uganda.html \
+	undo.html \
+	usr_01.html \
+	usr_02.html \
+	usr_03.html \
+	usr_04.html \
+	usr_05.html \
+	usr_06.html \
+	usr_07.html \
+	usr_08.html \
+	usr_09.html \
+	usr_10.html \
+	usr_11.html \
+	usr_12.html \
+	usr_20.html \
+	usr_21.html \
+	usr_22.html \
+	usr_23.html \
+	usr_24.html \
+	usr_25.html \
+	usr_26.html \
+	usr_27.html \
+	usr_28.html \
+	usr_29.html \
+	usr_30.html \
+	usr_31.html \
+	usr_32.html \
+	usr_40.html \
+	usr_41.html \
+	usr_42.html \
+	usr_43.html \
+	usr_44.html \
+	usr_45.html \
+	usr_90.html \
+	usr_toc.html \
+	various.html \
+	version4.html \
+	version5.html \
+	version6.html \
+	version7.html \
+	vi_diff.html \
+	visual.html \
+	windows.html \
+	workshop.html
+
+CONVERTED = \
+	vim-fr.UTF-8.1 \
+	evim-fr.UTF-8.1 \
+	vimdiff-fr.UTF-8.1 \
+	vimtutor-fr.UTF-8.1 \
+	xxd-fr.UTF-8.1 \
+	vim-it.UTF-8.1 \
+	evim-it.UTF-8.1 \
+	vimdiff-it.UTF-8.1 \
+	vimtutor-it.UTF-8.1 \
+	xxd-it.UTF-8.1 \
+	vim-ru.UTF-8.1 \
+	evim-ru.UTF-8.1 \
+	vimdiff-ru.UTF-8.1 \
+	vimtutor-ru.UTF-8.1 \
+	xxd-ru.UTF-8.1 \
+
+.SUFFIXES:
+.SUFFIXES: .c .o .txt .html
+
+all: tags vim.man vimdiff.man vimtutor.man xxd.man $(CONVERTED)
+
+# Use Vim to generate the tags file.  Can only be used when Vim has been
+# compiled and installed.  Supports multiple languages.
+vimtags: $(DOCS)
+	$(VIMEXE) -u NONE -esX -c "helptags ." -c quit
+
+# Use "doctags" to generate the tags file.  Only works for English!
+tags: doctags $(DOCS)
+	./doctags $(DOCS) | LANG=C LC_ALL=C sort >tags
+	uniq -d -2 tags
+
+doctags: doctags.c
+	$(CC) doctags.c -o doctags
+
+vim.man: vim.1
+	nroff -man vim.1 | sed -e s/.//g > vim.man
+
+vimdiff.man: vimdiff.1
+	nroff -man vimdiff.1 | sed -e s/.//g > vimdiff.man
+
+vimtutor.man: vimtutor.1
+	nroff -man vimtutor.1 | sed -e s/.//g > vimtutor.man
+
+xxd.man: xxd.1
+	nroff -man xxd.1 | sed -e s/.//g > xxd.man
+
+uganda.nsis.txt: uganda.txt
+	sed -e 's/[ 	]*\*[-a-zA-Z0-9.]*\*//g' -e 's/vim:tw=78://' \
+		uganda.txt | uniq >uganda.nsis.txt
+
+# Awk version of .txt to .html conversion.
+html: noerrors tags tags.ref $(HTMLS)
+	@if test -f errors.log; then more errors.log; fi
+
+noerrors:
+	-rm -f errors.log
+
+.txt.html:
+	$(AWK) -f makehtml.awk $< >$@
+
+# index.html is the starting point for HTML, but for the help files it is
+# help.txt.  Therefore use vimindex.html for index.txt.
+index.html: help.txt
+	$(AWK) -f makehtml.awk help.txt >index.html
+
+vimindex.html: index.txt
+	$(AWK) -f makehtml.awk index.txt >vimindex.html
+
+tags.ref tags.html: tags
+	$(AWK) -f maketags.awk tags >tags.html
+
+# Perl version of .txt to .html conversion.
+# There can't be two rules to produce a .html from a .txt file.
+# Just run over all .txt files each time one changes.  It's fast anyway.
+perlhtml: tags $(DOCS)
+	./vim2html.pl tags $(DOCS)
+
+clean:
+	-rm doctags *.html tags.ref
+
+# These files are in the extra archive, skip if not present
+
+arabic.txt:
+	touch arabic.txt
+
+farsi.txt:
+	touch farsi.txt
+
+hebrew.txt:
+	touch hebrew.txt
+
+russian.txt:
+	touch russian.txt
+
+gui_w16.txt:
+	touch gui_w16.txt
+
+gui_w32.txt:
+	touch gui_w32.txt
+
+if_ole.txt:
+	touch if_ole.txt
+
+os_390.txt:
+	touch os_390.txt
+
+os_amiga.txt:
+	touch os_amiga.txt
+
+os_beos.txt:
+	touch os_beos.txt
+
+os_dos.txt:
+	touch os_dos.txt
+
+os_mac.txt:
+	touch os_mac.txt
+
+os_mint.txt:
+	touch os_mint.txt
+
+os_msdos.txt:
+	touch os_msdos.txt
+
+os_os2.txt:
+	touch os_os2.txt
+
+os_qnx.txt:
+	touch os_qnx.txt
+
+os_risc.txt:
+	touch os_risc.txt
+
+os_win32.txt:
+	touch os_win32.txt
+
+# Note that $< works with GNU make while $> works for BSD make.
+# Is there a solution that works for both??
+vim-fr.UTF-8.1: vim-fr.1
+	iconv -f latin1 -t utf-8 $< >$@
+
+evim-fr.UTF-8.1: evim-fr.1
+	iconv -f latin1 -t utf-8 $< >$@
+
+vimdiff-fr.UTF-8.1: vimdiff-fr.1
+	iconv -f latin1 -t utf-8 $< >$@
+
+vimtutor-fr.UTF-8.1: vimtutor-fr.1
+	iconv -f latin1 -t utf-8 $< >$@
+
+xxd-fr.UTF-8.1: xxd-fr.1
+	iconv -f latin1 -t utf-8 $< >$@
+
+vim-it.UTF-8.1: vim-it.1
+	iconv -f latin1 -t utf-8 $< >$@
+
+evim-it.UTF-8.1: evim-it.1
+	iconv -f latin1 -t utf-8 $< >$@
+
+vimdiff-it.UTF-8.1: vimdiff-it.1
+	iconv -f latin1 -t utf-8 $< >$@
+
+vimtutor-it.UTF-8.1: vimtutor-it.1
+	iconv -f latin1 -t utf-8 $< >$@
+
+xxd-it.UTF-8.1: xxd-it.1
+	iconv -f latin1 -t utf-8 $< >$@
+
+vim-ru.UTF-8.1: vim-ru.1
+	iconv -f KOI8-R -t utf-8 $< >$@
+
+evim-ru.UTF-8.1: evim-ru.1
+	iconv -f KOI8-R -t utf-8 $< >$@
+
+vimdiff-ru.UTF-8.1: vimdiff-ru.1
+	iconv -f KOI8-R -t utf-8 $< >$@
+
+vimtutor-ru.UTF-8.1: vimtutor-ru.1
+	iconv -f KOI8-R -t utf-8 $< >$@
+
+xxd-ru.UTF-8.1: xxd-ru.1
+	iconv -f KOI8-R -t utf-8 $< >$@
--- /dev/null
+++ b/lib/vimfiles/doc/ada.txt
@@ -1,0 +1,515 @@
+*ada.txt*	For Vim version 7.1.  Last change: 2007 May 08
+
+
+		    ADA FILE TYPE PLUG-INS REFERENCE MANUAL~
+
+ADA								      *ada.vim*
+
+1.  Syntax Highlighting			    |ft-ada-syntax|
+2.  Plug-in				    |ft-ada-plugin|
+3.  Omni Completion			    |ft-ada-omni|
+    3.1 Omni Completion with "gnat xref"	|gnat-xref|
+    3.2 Omni Completion with "ctags"		|ada-ctags|
+4.  Compiler Support			    |ada-compiler|
+    4.1 GNAT					|compiler-gnat|
+    4.1 Dec Ada					|compiler-decada|
+5.  References				    |ada-reference|
+    5.1 Options					|ft-ada-options|
+    5.2 Functions				|ft-ada-functions|
+    5.3 Commands				|ft-ada-commands|
+    5.4 Variables				|ft-ada-variables|
+    5.5 Constants				|ft-ada-constants|
+8.  Extra Plug-ins			    |ada-extra-plugins|
+
+==============================================================================
+1. Syntax Highlighting ~
+							       *ft-ada-syntax*
+
+This mode is designed for the 2005 edition of Ada ("Ada 2005"), which includes
+support for objected-programming, protected types, and so on.  It handles code
+written for the original Ada language ("Ada83", "Ada87", "Ada95") as well,
+though code which uses Ada 2005-only keywords will be wrongly colored (such
+code should be fixed anyway).  For more information about Ada, see
+http://www.adapower.com.
+
+The Ada mode handles a number of situations cleanly.
+
+For example, it knows that the "-" in "-5" is a number, but the same character
+in "A-5" is an operator.  Normally, a "with" or "use" clause referencing
+another compilation unit is coloured the same way as C's "#include" is coloured.
+If you have "Conditional" or "Repeat" groups coloured differently, then "end
+if" and "end loop" will be coloured as part of those respective groups.
+
+You can set these to different colours using vim's "highlight" command (e.g.,
+to change how loops are displayed, enter the command ":hi Repeat" followed by
+the colour specification; on simple terminals the colour specification
+ctermfg=White often shows well).
+
+There are several options you can select in this Ada mode. See|ft-ada-options|
+for a complete list.
+
+To enable them, assign a value to the option.  For example, to turn one on:
+ >
+    > let g:ada_standard_types = 1
+>
+To disable them use ":unlet".  Example:
+>
+    > unlet g:ada_standard_types
+
+You can just use ":" and type these into the command line to set these
+temporarily before loading an Ada file.  You can make these option settings
+permanent by adding the "let" command(s), without a colon, to your "~/.vimrc"
+file.
+
+Even on a slow (90Mhz) PC this mode works quickly, but if you find the
+performance unacceptable, turn on |g:ada_withuse_ordinary|.
+
+Syntax folding instructions (|fold-syntax|) are added when |g:ada_folding| is
+set.
+
+==============================================================================
+2. File type Plug-in ~
+					       *ft-ada-indent* *ft-ada-plugin*
+
+The Ada plug-in provides support for:
+
+ - auto indenting	(|indent.txt|)
+ - insert completion	(|i_CTRL-N|)
+ - user completion	(|i_CTRL-X_CTRL-U|)
+ - tag searches		(|tagsrch.txt|)
+ - Quick Fix		(|quickfix.txt|)
+ - backspace handling	(|'backspace'|)
+ - comment handling	(|'comments'|, |'commentstring'|)
+
+The plug-in only activates the features of the Ada mode whenever an Ada
+files is opened and add adds Ada related entries to the main and pop-up menu.
+
+==============================================================================
+3. Omni Completion ~
+								 *ft-ada-omni*
+
+The Ada omni-completions (|i_CTRL-X_CTRL-O|) uses tags database created either
+by "gnat xref -v" or the "exuberant Ctags (http://ctags.sourceforge.net).  The
+complete function will automatically detect which tool was used to create the
+tags file.
+
+------------------------------------------------------------------------------
+3.1 Omni Completion with "gnat xref" ~
+								   *gnat-xref*
+
+GNAT XREF uses the compiler internal informations (ali-files) to produce the
+tags file. This has the advantage to be 100% correct and the option of deep
+nested analysis. However the code must compile, the generator is quite
+slow and the created tags file contains only the basic Ctags informations for
+each entry - not enough for some of the more advanced Vim code browser
+plug-ins.
+
+NOTE: "gnat xref -v" is very tricky to use as it has almost no diagnostic
+       output - If nothing is printed then usually the parameters are wrong.
+       Here some important tips:
+
+1)  You need to compile your code first and use the "-aO" option to point to
+    your .ali files.
+2)  "gnat xref -v ../Include/adacl.ads" won't work - use  the "gnat xref -v
+    -aI../Include adacl.ads" instead.
+3)  "gnat xref -v -aI../Include *.ad?" won't work - use "cd ../Include" and
+    then "gnat xref -v *.ad?"
+4)  Project manager support is completely broken - don't even try "gnat xref
+    -Padacl.gpr".
+5)  VIM is faster when the tags file is sorted - use "sort --unique
+    --ignore-case --output=tags tags" .
+6)  Remember to insert "!_TAG_FILE_SORTED 2 %sort ui" as first line to mark
+    the file assorted.
+
+------------------------------------------------------------------------------
+3.2 Omni Completion with "ctags"~
+								   *ada-ctags*
+
+Exuberant Ctags uses its own multi-language code parser. The parser is quite
+fast, produces a lot of extra informations (hence the name "Exuberant Ctags")
+and can run on files which currently do not compile.
+
+There are also lots of other Vim-tools which use exuberant Ctags.
+
+You will need to install a version of the Exuberant Ctags which has Ada
+support patched in. Such a version is available from the GNU Ada Project
+(http://gnuada.sourceforge.net).
+
+The Ada parser for Exuberant Ctags is fairly new - don't expect complete
+support yet.
+
+==============================================================================
+4.  Compiler Support ~
+								*ada-compiler*
+
+The Ada mode supports more then one Ada compiler and will automatically load the
+compiler set in|g:ada_default_compiler|whenever an Ada source is opened. The
+provided compiler plug-ins are split into the actual compiler plug-in and a
+collection of support functions and variables. This allows the easy
+development of specialized compiler plug-ins fine tuned to your development
+environment.
+
+------------------------------------------------------------------------------
+4.1 GNAT ~
+							       *compiler-gnat*
+
+GNAT is the only free (beer and speech) Ada compiler available. There are
+several version available which differentiate in the licence terms used.
+
+The GNAT compiler plug-in will perform a compile on pressing <F7> and then
+immediately shows the result. You can set the project file to be used by
+setting:
+ >
+ > call g:gnat.Set_Project_File ('my_project.gpr')
+
+Setting a project file will also create a Vim session (|views-sessions|) so -
+like with the GPS - opened files, window positions etc. will remembered
+separately for all projects.
+
+								*gnat_members*
+GNAT OBJECT ~
+
+							       *g:gnat.Make()*
+g:gnat.Make()
+		Calls|g:gnat.Make_Command|and displays the result inside a
+               |quickfix| window.
+
+							     *g:gnat.Pretty()*
+g:gnat.Pretty()
+		Calls|g:gnat.Pretty_Command|
+
+							       *g:gnat.Find()*
+g:gnat.Find()
+		Calls|g:gnat.Find_Command|
+
+							       *g:gnat.Tags()*
+g:gnat.Tags()
+		Calls|g:gnat.Tags_Command|
+
+						   *g:gnat.Set_Project_File()*
+g:gnat.Set_Project_File([{file}])
+		Set gnat project file and load associated session.  An open
+		project will be closed and the session written.  If called
+		without file name the file selector opens for selection of a
+		project file. If called with an empty string then the project
+		and associated session are closed.
+
+							 *g:gnat.Project_File*
+g:gnat.Project_File	string
+		Current project file.
+
+							 *g:gnat.Make_Command*
+g:gnat.Make_Command	string
+		External command used for|g:gnat.Make()| (|'makeprg'|).
+
+						       *g:gnat.Pretty_Program*
+g:gnat.Pretty_Program	string
+		External command used for|g:gnat.Pretty()|
+
+							 *g:gnat.Find_Program*
+g:gnat.Find_Program	string
+		External command used for|g:gnat.Find()|
+
+							 *g:gnat.Tags_Command*
+g:gnat.Tags_Command	string
+		External command used for|g:gnat.Tags()|
+
+							 *g:gnat.Error_Format*
+g:gnat.Error_Format	string
+		Error format (|'errorformat'|)
+
+------------------------------------------------------------------------------
+4.2 Dec Ada ~
+					    *compiler-hpada* *compiler-decada*
+					*compiler-vaxada* *compiler-compaqada*
+
+Dec Ada (also known by - in chronological order - VAX Ada, Dec Ada, Compaq Ada
+and HP Ada) is a fairly dated Ada 83 compiler. Support is basic: <F7> will
+compile the current unit.
+
+The Dec Ada compiler expects the package name and not the file name to be
+passed a parameter. The compiler plug-in supports the usual file name
+convention to convert the file into a unit name. For separates both '-' and
+'__' are allowed.
+
+							      *decada_members*
+DEC ADA OBJECT ~
+
+							     *g:decada.Make()*
+g:decada.Make()		function
+		Calls|g:decada.Make_Command|and displays the result inside a
+               |quickfix| window.
+
+							*g:decada.Unit_Name()*
+g:decada.Unit_Name()	function
+		Get the Unit name for the current file.
+
+						       *g:decada.Make_Command*
+g:decada.Make_Command	string
+		External command used for|g:decadat.Make()| (|'makeprg'|).
+
+						       *g:decada.Error_Format*
+g:decada.Error_Format|	string
+		Error format (|'errorformat'|).
+
+==============================================================================
+5. References ~
+							       *ada-reference*
+
+------------------------------------------------------------------------------
+5.1 Options ~
+							      *ft-ada-options*
+
+							*g:ada_standard_types*
+g:ada_standard_types	bool (true when exists)
+		Highlight types in package Standard (e.g., "Float")
+
+							  *g:ada_space_errors*
+						  *g:ada_no_trail_space_error*
+						    *g:ada_no_tab_space_error*
+							 *g:ada_all_tab_usage*
+g:ada_space_errors	 bool (true when exists)
+		Highlight extraneous errors in spaces ...
+		g:ada_no_trail_space_error
+		    - but ignore trailing spaces at the end of a line
+		g:ada_no_tab_space_error
+		    - but ignore tabs after spaces
+		g:ada_all_tab_usage
+		    - highlight all tab use
+
+							   *g:ada_line_errors*
+g:ada_line_errors	  bool (true when exists)
+		Highlight lines which are to long. Note: This highlighting
+		option is quite CPU intensive.
+
+							 *g:ada_rainbow_color*
+g:ada_rainbow_color	  bool (true when exists)
+		Use rainbow colours for '(' and ')'. You need the
+		rainbow_parenthesis for this to work
+
+							       *g:ada_folding*
+g:ada_folding		  set ('sigpft')
+		Use folding for Ada sources.
+		    's':    activate syntax folding on load
+			'p':    fold packages
+			'f':    fold functions and procedures
+			't':    fold types
+			'c':    fold conditionals
+		    'g':    activate gnat pretty print folding on load
+			'i':    lone 'is' folded with line above
+			'b':	lone 'begin' folded with line above
+			'p':	lone 'private' folded with line above
+			'x':	lone 'exception' folded with line above
+		    'i':    activate indent folding on load
+
+		Note: Syntax folding is in an early (unusable) stage and
+		      indent or gnat pretty folding is suggested.
+
+		For gnat pretty folding to work the following settings are
+		suggested: -cl3 -M79 -c2 -c3 -c4 -A1 -A2 -A3 -A4 -A5
+
+		For indent folding to work the following settings are
+		suggested: shiftwidth=3 softtabstop=3
+
+								*g:ada_abbrev*
+g:ada_abbrev		  bool (true when exists)
+		Add some abbreviations. This feature more or less superseded
+		by the various completion methods.
+
+						      *g:ada_withuse_ordinary*
+g:ada_withuse_ordinary	  bool (true when exists)
+		Show "with" and "use" as ordinary keywords (when used to
+		reference other compilation units they're normally highlighted
+		specially).
+
+							 *g:ada_begin_preproc*
+g:ada_begin_preproc	  bool (true when exists)
+		Show all begin-like keywords using the colouring of C
+		preprocessor commands.
+
+						    *g:ada_omni_with_keywords*
+g:ada_omni_with_keywords
+		Add Keywords, Pragmas, Attributes to omni-completions
+		(|compl-omni|). Note: You can always complete then with user
+		completion (|i_CTRL-X_CTRL-U|).
+
+						      *g:ada_extended_tagging*
+g:ada_extended_tagging	  enum ('jump', 'list')
+		use extended tagging, two options are available
+		    'jump': use tjump to jump.
+		    'list': add tags quick fix list.
+		Normal tagging does not support function or operator
+		overloading as these features are not available in C and
+		tagging was originally developed for C.
+
+						   *g:ada_extended_completion*
+g:ada_extended_completion
+		Uses extended completion for <C-N> and <C-R> completions
+		(|i_CTRL-N|). In this mode the '.' is used as part of the
+		identifier so that 'Object.Method' or 'Package.Procedure' are
+		completed together.
+
+						       *g:ada_gnat_extensions*
+g:ada_gnat_extensions	  bool (true when exists)
+		 Support GNAT extensions.
+
+					       *g:ada_with_gnat_project_files*
+g:ada_with_gnat_project_files	 bool (true when exists)
+		 Add gnat project file keywords and Attributes.
+
+						      *g:ada_default_compiler*
+g:ada_default_compiler	  string
+		set default compiler. Currently supported is 'gnat' and
+		'decada'.
+
+An "exists" type is a boolean is considered true when the variable is defined
+and false when the variable is undefined. The value which the variable is
+set makes no difference.
+
+------------------------------------------------------------------------------
+5.3 Commands ~
+							     *ft-ada-commands*
+
+:AdaRainbow							 *:AdaRainbow*
+		Toggles rainbow colour (|g:ada_rainbow_color|) mode for
+		'(' and ')'
+
+:AdaLines							   *:AdaLines*
+		Toggles line error (|g:ada_line_errors|) display
+
+:AdaSpaces							  *:AdaSpaces*
+		Toggles space error (|g:ada_space_errors|) display.
+
+:AdaTagDir							  *:AdaTagDir*
+		Creates tags file for the directory of the current file.
+
+:AdaTagFile							 *:AdaTagFile*
+		Creates tags file for the current file.
+
+:AdaTypes							   *:AdaTypes*
+		Toggles standard types (|g:ada_standard_types|) colour.
+
+:GnatFind							   *:GnatFind*
+		Calls |g:gnat.Find()|
+
+:GnatPretty							 *:GnatPretty*
+		Calls |g:gnat.Pretty()|
+
+:GnatTags							   *:GnatTags*
+		Calls |g:gnat.Tags()|
+
+------------------------------------------------------------------------------
+5.3 Variables ~
+							    *ft-ada-variables*
+
+								      *g:gnat*
+g:gnat			    object
+		Control object which manages GNAT compiles.  The object
+		is created when the first Ada source code is loaded provided
+		that |g:ada_default_compiler|is set to 'gnat'. See|gnat_members|
+		for details.
+
+								    *g:decada*
+g:decada		      object
+		Control object which manages Dec Ada compiles.	The object
+		is created when the first Ada source code is loaded provided
+		that |g:ada_default_compiler|is set to 'decada'. See
+	       |decada_members|for details.
+
+------------------------------------------------------------------------------
+5.4 Constants ~
+							    *ft-ada-constants*
+
+All constants are locked. See |:lockvar| for details.
+
+							     *g:ada#WordRegex*
+g:ada#WordRegex		string
+		Regular expression to search for Ada words
+
+							  *g:ada#DotWordRegex*
+g:ada#DotWordRegex	string
+		Regular expression to search for Ada words separated by dots.
+
+							       *g:ada#Comment*
+g:ada#Comment		string
+		Regular expression to search for Ada comments
+
+							      *g:ada#Keywords*
+g:ada#Keywords		list of dictionaries
+		List of keywords, attributes etc. pp. in the format used by
+		omni completion. See |complete-items| for details.
+
+							   *g:ada#Ctags_Kinds*
+g:ada#Ctags_Kinds	dictionary of lists
+		Dictionary of the various kinds of items which the Ada support
+		for Ctags generates.
+
+------------------------------------------------------------------------------
+5.2 Functions ~
+							    *ft-ada-functions*
+
+ada#Word([{line}, {col}])					  *ada#Word()*
+		Return full name of Ada entity under the cursor (or at given
+		line/column), stripping white space/newlines as necessary.
+
+ada#List_Tag([{line}, {col}])				      *ada#Listtags()*
+		List all occurrences of the Ada entity under the cursor (or at
+		given line/column) inside the quick-fix window
+
+ada#Jump_Tag ({ident}, {mode})				      *ada#Jump_Tag()*
+		List all occurrences of the Ada entity under the cursor (or at
+		given line/column) in the tag jump list. Mode can either be
+		'tjump' or 'stjump'.
+
+ada#Create_Tags ({option})				   *ada#Create_Tags()*
+		Creates tag file using Ctags. The option can either be 'file'
+		for the current file, 'dir' for the directory of the current
+		file or a file name.
+
+gnat#Insert_Tags_Header()			   *gnat#Insert_Tags_Header()*
+		Adds the tag file header (!_TAG_) informations to the current
+		file which are missing from the GNAT XREF output.
+
+ada#Switch_Syntax_Option ({option})		  *ada#Switch_Syntax_Option()*
+		Toggles highlighting options on or off. Used for the Ada menu.
+
+								  *gnat#New()*
+gnat#New ()
+		Create a new gnat object. See |g:gnat| for details.
+
+
+==============================================================================
+8. Extra Plugins ~
+							   *ada-extra-plugins*
+
+You can optionally install the following extra plug-in. They work well with Ada
+and enhance the ability of the Ada mode.:
+
+backup.vim
+	http://www.vim.org/scripts/script.php?script_id=1537
+	Keeps as many backups as you like so you don't have to.
+
+rainbow_parenthsis.vim
+	http://www.vim.org/scripts/script.php?script_id=1561
+	Very helpful since Ada uses only '(' and ')'.
+
+nerd_comments.vim
+	http://www.vim.org/scripts/script.php?script_id=1218
+	Excellent commenting and uncommenting support for almost any
+	programming language.
+
+matchit.vim
+	http://www.vim.org/scripts/script.php?script_id=39
+	'%' jumping for any language. The normal '%' jump only works for '{}'
+	style languages. The Ada mode will set the needed search patters.
+
+taglist.vim
+	http://www.vim.org/scripts/script.php?script_id=273
+	Source code explorer sidebar. There is a patch for Ada available.
+
+The GNU Ada Project distribution (http://gnuada.sourceforge.net) of Vim
+contains all of the above.
+
+==============================================================================
+vim: textwidth=78 nowrap tabstop=8 shiftwidth=4 softtabstop=4 noexpandtab
+vim: filetype=help encoding=latin1
--- /dev/null
+++ b/lib/vimfiles/doc/arabic.txt
@@ -1,0 +1,322 @@
+*arabic.txt*	For Vim version 7.1.  Last change: 2005 Mar 29
+
+
+		  VIM REFERENCE MANUAL	  by Nadim Shaikli
+
+
+Arabic Language support (options & mappings) for Vim		*Arabic*
+
+{Vi does not have any of these commands}
+
+								*E800*
+In order to use right-to-left and Arabic mapping support, it is
+necessary to compile VIM with the |+arabic| feature.
+
+These functions have been created by Nadim Shaikli <nadim-at-arabeyes.org>
+
+It is best to view this file with these settings within VIM's GUI: >
+
+	:set encoding=utf-8
+	:set arabicshape
+
+
+Introduction
+------------
+Arabic is a rather demanding language in which a number of special
+features are required.	Characters are right-to-left oriented and
+ought to appear as such on the screen (i.e. from right to left).
+Arabic also requires shaping of its characters, meaning the same
+character has a different visual form based on its relative location
+within a word (initial, medial, final or stand-alone).	Arabic also
+requires two different forms of combining and the ability, in
+certain instances, to either superimpose up to two characters on top
+of another (composing) or the actual substitution of two characters
+into one (combining).  Lastly, to display Arabic properly one will
+require not only ISO-8859-6 (U+0600-U+06FF) fonts, but will also
+require Presentation Form-B (U+FE70-U+FEFF) fonts both of which are
+subsets within a so-called ISO-10646-1 font.
+
+The commands, prompts and help files are not in Arabic, therefore
+the user interface remains the standard Vi interface.
+
+
+Highlights
+----------
+o  Editing left-to-right files as in the original VIM hasn't changed.
+
+o  Viewing and editing files in right-to-left windows.	 File
+   orientation is per window, so it is possible to view the same
+   file in right-to-left and left-to-right modes, simultaneously.
+
+o  No special terminal with right-to-left capabilities is required.
+   The right-to-left changes are completely hardware independent.
+   Only Arabic fonts are necessary.
+
+o  Compatible with the original VIM.   Almost all features work in
+   right-to-left mode (there are liable to be bugs).
+
+o  Changing keyboard mapping and reverse insert modes using a single
+   command.
+
+o  Toggling complete Arabic support via a single command.
+
+o  While in Arabic mode, numbers are entered from left to right.  Upon
+   entering a none number character, that character will be inserted
+   just into the left of the last number.
+
+o  Arabic keymapping on the command line in reverse insert mode.
+
+o  Proper Bidirectional functionality is possible given VIM is
+   started within a Bidi capable terminal emulator.
+
+
+Arabic Fonts						*arabicfonts*
+------------
+
+VIM requires monospaced fonts of which there are many out there.
+Arabic requires ISO-8859-6 as well as Presentation Form-B fonts
+(without Form-B, Arabic will _NOT_ be usable).	It is highly
+recommended that users search for so-called 'ISO-10646-1' fonts.
+Do an Internet search or check www.arabeyes.org for further
+info on where to attain the necessary Arabic fonts.
+
+
+Font Installation
+-----------------
+
+o  Installation of fonts for X Window systems (Unix/Linux)
+
+   Depending on your system, copy your_ARABIC_FONT file into a
+   directory of your choice.  Change to the directory containing
+   the Arabic fonts and execute the following commands:
+
+     %	mkfontdir
+     %	xset +fp path_name_of_arabic_fonts_directory
+
+
+Usage
+-----
+Prior to the actual usage of Arabic within VIM, a number of settings
+need to be accounted for and invoked.
+
+o  Setting the Arabic fonts
+
+   +  For VIM GUI set the 'guifont' to your_ARABIC_FONT.  This is done
+      by entering the following command in the VIM window.
+>
+		:set guifont=your_ARABIC_FONT
+<
+      NOTE: the string 'your_ARABIC_FONT' is used to denote a complete
+	    font name akin to that used in Linux/Unix systems.
+	    (e.g. -misc-fixed-medium-r-normal--20-200-75-75-c-100-iso10646-1)
+
+      You can append the 'guifont' set command to your .vimrc file
+      in order to get the same above noted results.  In other words,
+      you can include ':set guifont=your_ARABIC_FONT' to your .vimrc
+      file.
+
+   +  Under the X Window environment, you can also start VIM with
+      '-fn your_ARABIC_FONT' option.
+
+o  Setting the appropriate character Encoding
+   To enable the correct Arabic encoding the following command needs
+   to be appended,
+>
+		:set encoding=utf-8
+<
+   to your .vimrc file (entering the command manually into you VIM
+   window is highly discouraged).  In short, include ':set
+   encoding=utf-8' to your .vimrc file.
+
+   Attempts to use Arabic without UTF-8 will result the following
+   warning message,
+
+								*W17*  >
+     Arabic requires UTF-8, do ':set encoding=utf-8'
+
+o  Enable Arabic settings [short-cut]
+
+   In order to simplify and streamline things, you can either invoke
+   VIM with the command-line option,
+
+     % vim -A my_utf8_arabic_file ...
+
+   or enable 'arabic' via the following command within VIM
+>
+		:set arabic
+<
+   The two above noted possible invocations are the preferred manner
+   in which users are instructed to proceed.  Baring an enabled 'termbidi'
+   setting, both command options:
+
+     1. set the appropriate keymap
+     2. enable the deletion of a single combined pair character
+     3. enable rightleft    mode
+     4. enable rightleftcmd mode (affecting the command-line)
+     5. enable arabicshape  mode (do visual character alterations)
+
+   You may also append the command to your .vimrc file and simply
+   include ':set arabic' to it.
+
+   You are also capable of disabling Arabic support via
+>
+		:set noarabic
+<
+   which resets everything that the command had enabled without touching
+   the global settings as they could affect other possible open buffers.
+   In short the 'noarabic' command,
+
+     1. resets to the alternate keymap
+     2. disables the deletion of a single combined pair character
+     3. disables rightleft mode
+
+   NOTE: the 'arabic' command takes into consideration 'termbidi' for
+	 possible external bi-directional (bidi) support from the
+	 terminal ("mlterm" for instance offers such support).
+	 'termbidi', if available, is superior to rightleft support
+	 and its support is preferred due to its level of offerings.
+	 'arabic' when 'termbidi' is enabled only sets the keymap.
+
+   If, on the other hand, you'd like to be verbose and explicit and
+   are opting not to use the 'arabic' short-cut command, here's what
+   is needed (i.e. if you use ':set arabic' you can skip this section) -
+
+   +  Arabic Keymapping Activation
+
+      To activate the Arabic keymap (i.e. to remap your English/Latin
+      keyboard to look-n-feel like a standard Arabic one), set the
+      'keymap' command to "arabic".  This is done by entering
+>
+		:set keymap=arabic
+<
+      in your VIM window.  You can also append the 'keymap' set command to
+      your .vimrc file.  In other words, you can include ':set keymap=arabic'
+      to your .vimrc file.
+
+      To turn toggle (or switch) your keymapping between Arabic and the
+      default mapping (English), it is advised that users use the 'CTRL-^'
+      key press while in insert (or add/replace) mode.	The command-line
+      will display your current mapping by displaying an "Arabic" string
+      next to your insertion mode (e.g. -- INSERT Arabic --) indicating
+      your current keymap.
+
+   +  Arabic deletion of a combined pair character
+
+      By default VIM has the 'delcombine' option disabled.  This option
+      allows the deletion of ALEF in a LAM_ALEF (LAA) combined character
+      and still retain the LAM (i.e. it reverts to treating the combined
+      character as its natural two characters form -- this also pertains
+      to harakat and their combined forms).  You can enable this option
+      by entering
+>
+		:set delcombine
+<
+      in our VIM window.  You can also append the 'delcombine' set command
+      to your .vimrc file.  In other words, you can include ':set delcombine'
+      to your .vimrc file.
+
+   +  Arabic right-to-left Mode
+
+      By default VIM starts in Left-to-right mode.  'rightleft' is the
+      command that allows one to alter a window's orientation - that can
+      be accomplished via,
+
+      - Toggling between left-to-right and right-to-left modes is
+	accomplished through ':set rightleft' and ':set norightleft'.
+
+      - While in Left-to-right mode, enter ':set rl' in the command line
+	('rl' is the abbreviation for rightleft).
+
+      - Put the ':set rl' line in your '.vimrc' file to start Vim in
+	right-to-left mode permanently.
+
+   +  Arabic right-to-left command-line Mode
+
+      For certain commands the editing can be done in right-to-left mode.
+      Currently this is only applicable to search commands.
+
+      This is controlled with the 'rightleftcmd' option.  The default is
+      "search", which means that windows in which 'rightleft' is set will
+      edit search commands in right-left mode.	To disable this behavior,
+>
+		:set rightleftcmd=
+<
+      To enable right-left editing of search commands again,
+>
+		:set rightleftcmd&
+<
+   +  Arabic Shaping Mode
+
+      To activate the required visual characters alterations (shaping,
+      composing, combining) which the Arabic language requires, enable
+      the 'arabicshape' command.  This is done by entering
+>
+		:set arabicshape
+<
+      in our VIM window.  You can also append the 'arabicshape' set
+      command to your .vimrc file.  In other words, you can include
+      ':set arabicshape' to your .vimrc file.
+
+
+Keymap/Keyboard						*arabickeymap*
+---------------
+
+The character/letter encoding used in VIM is the standard UTF-8.
+It is widely discouraged that any other encoding be used or even
+attempted.
+
+Note: UTF-8 is an all encompassing encoding and as such is
+      the only supported (and encouraged) encoding with
+      regard to Arabic (all other proprietary encodings
+      should be discouraged and frowned upon).
+
+o  Keyboard
+
+   +  CTRL-^ in insert/replace mode toggles between Arabic/Latin mode
+
+   +  Keyboard mapping is based on the Microsoft's Arabic keymap (the
+      defacto standard in the Arab world):
+
+  +---------------------------------------------------------------------+
+  |!   |@   |#   |$   |%   |^   |&   |*   |(   |)   |_   |+   ||   |~  ّ |
+  |1 ١ |2 ٢ |3 ٣ |4 ٤ |5 ٥ |6 ٦ |7 ٧ |8 ٨ |9 ٩ |0 ٠ |-   |=   |\   |` ذ |
+  +---------------------------------------------------------------------+
+       |Q  َ |W  ً |E  ُ |R  ٌ |T لإ |Y إ |U ` |I ÷ |O x |P ؛ |{ < |} > |
+       |q ض |w ص |e ث |r ق |t ف |y غ |u ع |i ه |o خ |p ح |[ ج |] د |
+       +-----------------------------------------------------------+
+	 |A  ِ |S  ٍ |D [ |F ] |G لأ |H أ |J ـ |K ، |L / |:   |"   |
+	 |a ش |s س |d ي |f ب |g ل |h ا |j ت |k ن |l م |; ك |' ط |
+	 +------------------------------------------------------+
+	   |Z ~ |X  ْ |C { |V } |B لآ |N آ |M ' |< , |> . |? ؟ |
+	   |z ئ |x ء |c ؤ |v ر |b لا |n ى |m ة |, و |. ز |/ ظ |
+	   +-------------------------------------------------+
+
+Restrictions
+------------
+
+o  VIM in its GUI form does not currently support Bi-directionality
+   (i.e. the ability to see both Arabic and Latin intermixed within
+   the same line).
+
+
+Known Bugs
+----------
+
+There is one known minor bug,
+
+ 1. If you insert a haraka (e.g. Fatha (U+064E)) after a LAM (U+0644)
+    and then insert an ALEF (U+0627), the appropriate combining will
+    not happen due to the sandwiched haraka resulting in something
+    that will NOT be displayed correctly.
+
+    WORK-AROUND: Don't include harakats between LAM and ALEF combos.
+		 In general, don't anticipate to see correct visual
+		 representation with regard to harakats and LAM+ALEF
+		 combined characters (even those entered after both
+		 characters).  The problem noted is strictly a visual
+		 one, meaning saving such a file will contain all the
+		 appropriate info/encodings - nothing is lost.
+
+No other bugs are known to exist.
+
+ vim:tw=78:ts=8:ft=help:norl:
--- /dev/null
+++ b/lib/vimfiles/doc/autocmd.txt
@@ -1,0 +1,1280 @@
+*autocmd.txt*   For Vim version 7.1.  Last change: 2007 Mar 27
+
+
+		  VIM REFERENCE MANUAL    by Bram Moolenaar
+
+
+Automatic commands					*autocommand*
+
+For a basic explanation, see section |40.3| in the user manual.
+
+1.  Introduction		|autocmd-intro|
+2.  Defining autocommands	|autocmd-define|
+3.  Removing autocommands	|autocmd-remove|
+4.  Listing autocommands	|autocmd-list|
+5.  Events			|autocmd-events|
+6.  Patterns			|autocmd-patterns|
+7.  Buffer-local autocommands	|autocmd-buflocal|
+8.  Groups			|autocmd-groups|
+9.  Executing autocommands	|autocmd-execute|
+10. Using autocommands		|autocmd-use|
+11. Disabling autocommands	|autocmd-disable|
+
+{Vi does not have any of these commands}
+{only when the |+autocmd| feature has not been disabled at compile time}
+
+==============================================================================
+1. Introduction						*autocmd-intro*
+
+You can specify commands to be executed automatically when reading or writing
+a file, when entering or leaving a buffer or window, and when exiting Vim.
+For example, you can create an autocommand to set the 'cindent' option for
+files matching *.c.  You can also use autocommands to implement advanced
+features, such as editing compressed files (see |gzip-example|).  The usual
+place to put autocommands is in your .vimrc or .exrc file.
+
+							*E203* *E204* *E143*
+WARNING: Using autocommands is very powerful, and may lead to unexpected side
+effects.  Be careful not to destroy your text.
+- It's a good idea to do some testing on an expendable copy of a file first.
+  For example: If you use autocommands to decompress a file when starting to
+  edit it, make sure that the autocommands for compressing when writing work
+  correctly.
+- Be prepared for an error halfway through (e.g., disk full).  Vim will mostly
+  be able to undo the changes to the buffer, but you may have to clean up the
+  changes to other files by hand (e.g., compress a file that has been
+  decompressed).
+- If the BufRead* events allow you to edit a compressed file, the FileRead*
+  events should do the same (this makes recovery possible in some rare cases).
+  It's a good idea to use the same autocommands for the File* and Buf* events
+  when possible.
+
+==============================================================================
+2. Defining autocommands				*autocmd-define*
+
+Note: The ":autocmd" command cannot be followed by another command, since any
+'|' is considered part of the command.
+
+							*:au* *:autocmd*
+:au[tocmd] [group] {event} {pat} [nested] {cmd}
+			Add {cmd} to the list of commands that Vim will
+			execute automatically on {event} for a file matching
+			{pat}.  Vim always adds the {cmd} after existing
+			autocommands, so that the autocommands execute in the
+			order in which they were given.  See |autocmd-nested|
+			for [nested].
+
+The special pattern <buffer> or <buffer=N> defines a buffer-local autocommand.
+See |autocmd-buflocal|.
+
+Note that special characters (e.g., "%", "<cword>") in the ":autocmd"
+arguments are not expanded when the autocommand is defined.  These will be
+expanded when the Event is recognized, and the {cmd} is executed.  The only
+exception is that "<sfile>" is expanded when the autocmd is defined.  Example:
+>
+	:au BufNewFile,BufRead *.html so <sfile>:h/html.vim
+
+Here Vim expands <sfile> to the name of the file containing this line.
+
+When your .vimrc file is sourced twice, the autocommands will appear twice.
+To avoid this, put this command in your .vimrc file, before defining
+autocommands: >
+
+	:autocmd!	" Remove ALL autocommands for the current group.
+
+If you don't want to remove all autocommands, you can instead use a variable
+to ensure that Vim includes the autocommands only once: >
+
+	:if !exists("autocommands_loaded")
+	:  let autocommands_loaded = 1
+	:  au ...
+	:endif
+
+When the [group] argument is not given, Vim uses the current group (as defined
+with ":augroup"); otherwise, Vim uses the group defined with [group].  Note
+that [group] must have been defined before.  You cannot define a new group
+with ":au group ..."; use ":augroup" for that.
+
+While testing autocommands, you might find the 'verbose' option to be useful: >
+	:set verbose=9
+This setting makes Vim echo the autocommands as it executes them.
+
+When defining an autocommand in a script, it will be able to call functions
+local to the script and use mappings local to the script.  When the event is
+triggered and the command executed, it will run in the context of the script
+it was defined in.  This matters if |<SID>| is used in a command.
+
+When executing the commands, the messages from one command overwrites a
+previous message.  This is different from when executing the commands
+manually.  Mostly the screen will not scroll up, thus there is no hit-enter
+prompt.  When one command outputs two messages this can happen anyway.
+
+==============================================================================
+3. Removing autocommands				*autocmd-remove*
+
+:au[tocmd]! [group] {event} {pat} [nested] {cmd}
+			Remove all autocommands associated with {event} and
+			{pat}, and add the command {cmd}.  See
+			|autocmd-nested| for [nested].
+
+:au[tocmd]! [group] {event} {pat}
+			Remove all autocommands associated with {event} and
+			{pat}.
+
+:au[tocmd]! [group] * {pat}
+			Remove all autocommands associated with {pat} for all
+			events.
+
+:au[tocmd]! [group] {event}
+			Remove ALL autocommands for {event}.
+
+:au[tocmd]! [group]	Remove ALL autocommands.
+
+When the [group] argument is not given, Vim uses the current group (as defined
+with ":augroup"); otherwise, Vim uses the group defined with [group].
+
+==============================================================================
+4. Listing autocommands					*autocmd-list*
+
+:au[tocmd] [group] {event} {pat}
+			Show the autocommands associated with {event} and
+			{pat}.
+
+:au[tocmd] [group] * {pat}
+			Show the autocommands associated with {pat} for all
+			events.
+
+:au[tocmd] [group] {event}
+			Show all autocommands for {event}.
+
+:au[tocmd] [group]	Show all autocommands.
+
+If you provide the [group] argument, Vim lists only the autocommands for
+[group]; otherwise, Vim lists the autocommands for ALL groups.  Note that this
+argument behavior differs from that for defining and removing autocommands.
+
+In order to list buffer-local autocommands, use a pattern in the form <buffer>
+or <buffer=N>.  See |autocmd-buflocal|.
+
+							*:autocmd-verbose*
+When 'verbose' is non-zero, listing an autocommand will also display where it
+was last defined. Example: >
+
+    :verbose autocmd BufEnter
+    FileExplorer  BufEnter
+	*	  call s:LocalBrowse(expand("<amatch>"))
+	    Last set from /usr/share/vim/vim-7.0/plugin/NetrwPlugin.vim
+<
+See |:verbose-cmd| for more information.
+
+==============================================================================
+5. Events					*autocmd-events* *E215* *E216*
+
+You can specify a comma-separated list of event names.  No white space can be
+used in this list.  The command applies to all the events in the list.
+
+For READING FILES there are four kinds of events possible:
+	BufNewFile			starting to edit a non-existent file
+	BufReadPre	BufReadPost	starting to edit an existing file
+	FilterReadPre	FilterReadPost	read the temp file with filter output
+	FileReadPre	FileReadPost	any other file read
+Vim uses only one of these four kinds when reading a file.  The "Pre" and
+"Post" events are both triggered, before and after reading the file.
+
+Note that the autocommands for the *ReadPre events and all the Filter events
+are not allowed to change the current buffer (you will get an error message if
+this happens).  This is to prevent the file to be read into the wrong buffer.
+
+Note that the 'modified' flag is reset AFTER executing the BufReadPost
+and BufNewFile autocommands.  But when the 'modified' option was set by the
+autocommands, this doesn't happen.
+
+You can use the 'eventignore' option to ignore a number of events or all
+events.
+					*autocommand-events* *{event}*
+Vim recognizes the following events.  Vim ignores the case of event names
+(e.g., you can use "BUFread" or "bufread" instead of "BufRead").
+
+First an overview by function with a short explanation.  Then the list
+alphabetically with full explanations |autocmd-events-abc|.
+
+Name			triggered by ~
+
+	Reading
+|BufNewFile|		starting to edit a file that doesn't exist
+|BufReadPre|		starting to edit a new buffer, before reading the file
+|BufRead|		starting to edit a new buffer, after reading the file
+|BufReadPost|		starting to edit a new buffer, after reading the file
+|BufReadCmd|		before starting to edit a new buffer |Cmd-event|
+
+|FileReadPre|		before reading a file with a ":read" command
+|FileReadPost|		after reading a file with a ":read" command
+|FileReadCmd|		before reading a file with a ":read" command |Cmd-event|
+
+|FilterReadPre|		before reading a file from a filter command
+|FilterReadPost|	after reading a file from a filter command
+
+|StdinReadPre|		before reading from stdin into the buffer
+|StdinReadPost|		After reading from the stdin into the buffer
+
+	Writing
+|BufWrite|		starting to write the whole buffer to a file
+|BufWritePre|		starting to write the whole buffer to a file
+|BufWritePost|		after writing the whole buffer to a file
+|BufWriteCmd|		before writing the whole buffer to a file |Cmd-event|
+
+|FileWritePre|		starting to write part of a buffer to a file
+|FileWritePost|		after writing part of a buffer to a file
+|FileWriteCmd|		before writing part of a buffer to a file |Cmd-event|
+
+|FileAppendPre|		starting to append to a file
+|FileAppendPost|	after appending to a file
+|FileAppendCmd|		before appending to a file |Cmd-event|
+
+|FilterWritePre|	starting to write a file for a filter command or diff
+|FilterWritePost|	after writing a file for a filter command or diff
+
+	Buffers
+|BufAdd|		just after adding a buffer to the buffer list
+|BufCreate|		just after adding a buffer to the buffer list
+|BufDelete|		before deleting a buffer from the buffer list
+|BufWipeout|		before completely deleting a buffer
+
+|BufFilePre|		before changing the name of the current buffer
+|BufFilePost|		after changing the name of the current buffer
+
+|BufEnter|		after entering a buffer
+|BufLeave|		before leaving to another buffer
+|BufWinEnter|		after a buffer is displayed in a window
+|BufWinLeave|		before a buffer is removed from a window
+
+|BufUnload|		before unloading a buffer
+|BufHidden|		just after a buffer has become hidden
+|BufNew|		just after creating a new buffer
+
+|SwapExists|		detected an existing swap file
+
+	Options
+|FileType|		when the 'filetype' option has been set
+|Syntax|		when the 'syntax' option has been set
+|EncodingChanged|	after the 'encoding' option has been changed
+|TermChanged|		after the value of 'term' has changed
+
+	Startup and exit
+|VimEnter|		after doing all the startup stuff
+|GUIEnter|		after starting the GUI successfully
+|TermResponse|		after the terminal response to |t_RV| is received
+
+|VimLeavePre|		before exiting Vim, before writing the viminfo file
+|VimLeave|		before exiting Vim, after writing the viminfo file
+
+	Various
+|FileChangedShell|	Vim notices that a file changed since editing started
+|FileChangedShellPost|	After handling a file changed since editing started
+|FileChangedRO|		before making the first change to a read-only file
+
+|ShellCmdPost|		after executing a shell command
+|ShellFilterPost|	after filtering with a shell command
+
+|FuncUndefined|		a user function is used but it isn't defined
+|SpellFileMissing|	a spell file is used but it can't be found
+|SourcePre|		before sourcing a Vim script
+|SourceCmd|		before sourcing a Vim script |Cmd-event|
+
+|VimResized|		after the Vim window size changed
+|FocusGained|		Vim got input focus
+|FocusLost|		Vim lost input focus
+|CursorHold|		the user doesn't press a key for a while
+|CursorHoldI|		the user doesn't press a key for a while in Insert mode
+|CursorMoved|		the cursor was moved in Normal mode
+|CursorMovedI|		the cursor was moved in Insert mode
+
+|WinEnter|		after entering another window
+|WinLeave|		before leaving a window
+|TabEnter|		after entering another tab page
+|TabLeave|		before leaving a tab page
+|CmdwinEnter|		after entering the command-line window
+|CmdwinLeave|		before leaving the command-line window
+
+|InsertEnter|		starting Insert mode
+|InsertChange|		when typing <Insert> while in Insert or Replace mode
+|InsertLeave|		when leaving Insert mode
+
+|ColorScheme|		after loading a color scheme
+
+|RemoteReply|		a reply from a server Vim was received
+
+|QuickFixCmdPre|	before a quickfix command is run
+|QuickFixCmdPost|	after a quickfix command is run
+
+|SessionLoadPost|	after loading a session file
+
+|MenuPopup|		just before showing the popup menu
+
+|User|			to be used in combination with ":doautocmd"
+
+
+The alphabetical list of autocommand events:		*autocmd-events-abc*
+
+							*BufCreate* *BufAdd*
+BufAdd or BufCreate		Just after creating a new buffer which is
+				added to the buffer list, or adding a buffer
+				to the buffer list.
+				Also used just after a buffer in the buffer
+				list has been renamed.
+				The BufCreate event is for historic reasons.
+				NOTE: When this autocommand is executed, the
+				current buffer "%" may be different from the
+				buffer being created "<afile>".
+							*BufDelete*
+BufDelete			Before deleting a buffer from the buffer list.
+				The BufUnload may be called first (if the
+				buffer was loaded).
+				Also used just before a buffer in the buffer
+				list is renamed.
+				NOTE: When this autocommand is executed, the
+				current buffer "%" may be different from the
+				buffer being deleted "<afile>".
+							*BufEnter*
+BufEnter			After entering a buffer.  Useful for setting
+				options for a file type.  Also executed when
+				starting to edit a buffer, after the
+				BufReadPost autocommands.
+							*BufFilePost*
+BufFilePost			After changing the name of the current buffer
+				with the ":file" or ":saveas" command.
+							*BufFilePre*
+BufFilePre			Before changing the name of the current buffer
+				with the ":file" or ":saveas" command.
+							*BufHidden*
+BufHidden			Just after a buffer has become hidden.  That
+				is, when there are no longer windows that show
+				the buffer, but the buffer is not unloaded or
+				deleted.  Not used for ":qa" or ":q" when
+				exiting Vim.
+				NOTE: When this autocommand is executed, the
+				current buffer "%" may be different from the
+				buffer being unloaded "<afile>".
+							*BufLeave*
+BufLeave			Before leaving to another buffer.  Also when
+				leaving or closing the current window and the
+				new current window is not for the same buffer.
+				Not used for ":qa" or ":q" when exiting Vim.
+							*BufNew*
+BufNew				Just after creating a new buffer.  Also used
+				just after a buffer has been renamed.  When
+				the buffer is added to the buffer list BufAdd
+				will be triggered too.
+				NOTE: When this autocommand is executed, the
+				current buffer "%" may be different from the
+				buffer being created "<afile>".
+							*BufNewFile*
+BufNewFile			When starting to edit a file that doesn't
+				exist.  Can be used to read in a skeleton
+				file.
+						*BufRead* *BufReadPost*
+BufRead or BufReadPost		When starting to edit a new buffer, after
+				reading the file into the buffer, before
+				executing the modelines.  See |BufWinEnter|
+				for when you need to do something after
+				processing the modelines.
+				This does NOT work for ":r file".  Not used
+				when the file doesn't exist.  Also used after
+				successfully recovering a file.
+							*BufReadCmd*
+BufReadCmd			Before starting to edit a new buffer.  Should
+				read the file into the buffer. |Cmd-event|
+						*BufReadPre* *E200* *E201*
+BufReadPre			When starting to edit a new buffer, before
+				reading the file into the buffer.  Not used
+				if the file doesn't exist.
+							*BufUnload*
+BufUnload			Before unloading a buffer.  This is when the
+				text in the buffer is going to be freed.  This
+				may be after a BufWritePost and before a
+				BufDelete.  Also used for all buffers that are
+				loaded when Vim is going to exit.
+				NOTE: When this autocommand is executed, the
+				current buffer "%" may be different from the
+				buffer being unloaded "<afile>".
+							*BufWinEnter*
+BufWinEnter			After a buffer is displayed in a window.  This
+				can be when the buffer is loaded (after
+				processing the modelines), when a hidden
+				buffer is displayed in a window (and is no
+				longer hidden) or a buffer already visible in
+				a window is also displayed in another window.
+							*BufWinLeave*
+BufWinLeave			Before a buffer is removed from a window.
+				Not when it's still visible in another window.
+				Also triggered when exiting.  It's triggered
+				before BufUnload or BufHidden.
+				NOTE: When this autocommand is executed, the
+				current buffer "%" may be different from the
+				buffer being unloaded "<afile>".
+							*BufWipeout*
+BufWipeout			Before completely deleting a buffer.  The
+				BufUnload and BufDelete events may be called
+				first (if the buffer was loaded and was in the
+				buffer list).  Also used just before a buffer
+				is renamed (also when it's not in the buffer
+				list).
+				NOTE: When this autocommand is executed, the
+				current buffer "%" may be different from the
+				buffer being deleted "<afile>".
+						*BufWrite* *BufWritePre*
+BufWrite or BufWritePre		Before writing the whole buffer to a file.
+							*BufWriteCmd*
+BufWriteCmd			Before writing the whole buffer to a file.
+				Should do the writing of the file and reset
+				'modified' if successful, unless '+' is in
+				'cpo' and writing to another file |cpo-+|.
+				The buffer contents should not be changed.
+				|Cmd-event|
+							*BufWritePost*
+BufWritePost			After writing the whole buffer to a file
+				(should undo the commands for BufWritePre).
+							*CmdwinEnter*
+CmdwinEnter			After entering the command-line window.
+				Useful for setting options specifically for
+				this special type of window.  This is
+				triggered _instead_ of BufEnter and WinEnter.
+				<afile> is set to a single character,
+				indicating the type of command-line.
+				|cmdwin-char|
+							*CmdwinLeave*
+CmdwinLeave			Before leaving the command-line window.
+				Useful to clean up any global setting done
+				with CmdwinEnter.  This is triggered _instead_
+				of BufLeave and WinLeave.
+				<afile> is set to a single character,
+				indicating the type of command-line.
+				|cmdwin-char|
+							*ColorScheme*
+ColorScheme			After loading a color scheme. |:colorscheme|
+
+							*CursorHold*
+CursorHold			When the user doesn't press a key for the time
+				specified with 'updatetime'.  Not re-triggered
+				until the user has pressed a key (i.e. doesn't
+				fire every 'updatetime' ms if you leave Vim to
+				make some coffee. :)  See |CursorHold-example|
+				for previewing tags.
+				This event is only triggered in Normal mode.
+				It is not triggered when waiting for a command
+				argument to be typed, or a movement after an
+				operator.
+				While recording the CursorHold event is not
+				triggered. |q|
+				Note: Interactive commands cannot be used for
+				this event.  There is no hit-enter prompt,
+				the screen is updated directly (when needed).
+				Note: In the future there will probably be
+				another option to set the time.
+				Hint: to force an update of the status lines
+				use: >
+					:let &ro = &ro
+<				{only on Amiga, Unix, Win32, MSDOS and all GUI
+				versions}
+							*CursorHoldI*
+CursorHoldI			Just like CursorHold, but in Insert mode.
+
+							*CursorMoved*
+CursorMoved			After the cursor was moved in Normal mode.
+				Also when the text of the cursor line has been
+				changed, e.g., with "x", "rx" or "p".
+				Not triggered when there is typeahead or when
+				an operator is pending.
+				For an example see |match-parens|.
+				Careful: Don't do anything that the user does
+				not expect or that is slow.
+							*CursorMovedI*
+CursorMovedI			After the cursor was moved in Insert mode.
+				Otherwise the same as CursorMoved.
+							*EncodingChanged*
+EncodingChanged			Fires off after the 'encoding' option has been
+				changed.  Useful to set up fonts, for example.
+							*FileAppendCmd*
+FileAppendCmd			Before appending to a file.  Should do the
+				appending to the file.  Use the '[ and ']
+				marks for the range of lines.|Cmd-event|
+							*FileAppendPost*
+FileAppendPost			After appending to a file.
+							*FileAppendPre*
+FileAppendPre			Before appending to a file.  Use the '[ and ']
+				marks for the range of lines.
+							*FileChangedRO*
+FileChangedRO			Before making the first change to a read-only
+				file.  Can be used to check-out the file from
+				a source control system.  Not triggered when
+				the change was caused by an autocommand.
+				This event is triggered when making the first
+				change in a buffer or the first change after
+				'readonly' was set, just before the change is
+				applied to the text.
+				WARNING: If the autocommand moves the cursor
+				the effect of the change is undefined.
+							*E788*
+				It is not allowed to change to another buffer
+				here.  You can reload the buffer but not edit
+				another one.
+							*FileChangedShell*
+FileChangedShell		When Vim notices that the modification time of
+				a file has changed since editing started.
+				Also when the file attributes of the file
+				change. |timestamp|
+				Mostly triggered after executing a shell
+				command, but also with a |:checktime| command
+				or when Gvim regains input focus.
+				This autocommand is triggered for each changed
+				file.  It is not used when 'autoread' is set
+				and the buffer was not changed.  If a
+				FileChangedShell autocommand is present the
+				warning message and prompt is not given.
+				The |v:fcs_reason| variable is set to indicate
+				what happened and |v:fcs_choice| can be used
+				to tell Vim what to do next.
+				NOTE: When this autocommand is executed, the
+				current buffer "%" may be different from the
+				buffer that was changed "<afile>".
+				NOTE: The commands must not change the current
+				buffer, jump to another buffer or delete a
+				buffer.  *E246*
+				NOTE: This event never nests, to avoid an
+				endless loop.  This means that while executing
+				commands for the FileChangedShell event no
+				other FileChangedShell event will be
+				triggered.
+							*FileChangedShellPost*
+FileChangedShellPost		After handling a file that was changed outside
+				of Vim.  Can be used to update the statusline.
+							*FileEncoding*
+FileEncoding			Obsolete.  It still works and is equivalent
+				to |EncodingChanged|.
+							*FileReadCmd*
+FileReadCmd			Before reading a file with a ":read" command.
+				Should do the reading of the file. |Cmd-event|
+							*FileReadPost*
+FileReadPost			After reading a file with a ":read" command.
+				Note that Vim sets the '[ and '] marks to the
+				first and last line of the read.  This can be
+				used to operate on the lines just read.
+							*FileReadPre*
+FileReadPre			Before reading a file with a ":read" command.
+							*FileType*
+FileType			When the 'filetype' option has been set.  The
+				pattern is matched against the filetype.
+				<afile> can be used for the name of the file
+				where this option was set, and <amatch> for
+				the new value of 'filetype'.
+				See |filetypes|.
+							*FileWriteCmd*
+FileWriteCmd			Before writing to a file, when not writing the
+				whole buffer.  Should do the writing to the
+				file.  Should not change the buffer.  Use the
+				'[ and '] marks for the range of lines.
+				|Cmd-event|
+							*FileWritePost*
+FileWritePost			After writing to a file, when not writing the
+				whole buffer.
+							*FileWritePre*
+FileWritePre			Before writing to a file, when not writing the
+				whole buffer.  Use the '[ and '] marks for the
+				range of lines.
+							*FilterReadPost*
+FilterReadPost			After reading a file from a filter command.
+				Vim checks the pattern against the name of
+				the current buffer as with FilterReadPre.
+				Not triggered when 'shelltemp' is off.
+							*FilterReadPre* *E135*
+FilterReadPre			Before reading a file from a filter command.
+				Vim checks the pattern against the name of
+				the current buffer, not the name of the
+				temporary file that is the output of the
+				filter command.
+				Not triggered when 'shelltemp' is off.
+							*FilterWritePost*
+FilterWritePost			After writing a file for a filter command or
+				making a diff.
+				Vim checks the pattern against the name of
+				the current buffer as with FilterWritePre.
+				Not triggered when 'shelltemp' is off.
+							*FilterWritePre*
+FilterWritePre			Before writing a file for a filter command or
+				making a diff.
+				Vim checks the pattern against the name of
+				the current buffer, not the name of the
+				temporary file that is the output of the
+				filter command.
+				Not triggered when 'shelltemp' is off.
+							*FocusGained*
+FocusGained			When Vim got input focus.  Only for the GUI
+				version and a few console versions where this
+				can be detected.
+							*FocusLost*
+FocusLost			When Vim lost input focus.  Only for the GUI
+				version and a few console versions where this
+				can be detected.  May also happen when a
+				dialog pops up.
+							*FuncUndefined*
+FuncUndefined			When a user function is used but it isn't
+				defined.  Useful for defining a function only
+				when it's used.  The pattern is matched
+				against the function name.  Both <amatch> and
+				<afile> are set to the name of the function.
+				See |autoload-functions|.
+							*GUIEnter*
+GUIEnter			After starting the GUI successfully, and after
+				opening the window.  It is triggered before
+				VimEnter when using gvim.  Can be used to
+				position the window from a .gvimrc file: >
+	:autocmd GUIEnter * winpos 100 50
+<							*GUIFailed*
+GUIFailed			After starting the GUI failed.  Vim may
+				continue to run in the terminal, if possible
+				(only on Unix and alikes, when connecting the
+				X server fails).  You may want to quit Vim: >
+	:autocmd GUIFailed * qall
+<							*InsertChange*
+InsertChange			When typing <Insert> while in Insert or
+				Replace mode.  The |v:insertmode| variable
+				indicates the new mode.
+				Be careful not to move the cursor or do
+				anything else that the user does not expect.
+							*InsertEnter*
+InsertEnter			Just before starting Insert mode.  Also for
+				Replace mode and Virtual Replace mode.  The
+				|v:insertmode| variable indicates the mode.
+				Be careful not to move the cursor or do
+				anything else that the user does not expect.
+							*InsertLeave*
+InsertLeave			When leaving Insert mode.  Also when using
+				CTRL-O |i_CTRL-O|.  But not for |i_CTRL-C|.
+							*MenuPopup*
+MenuPopup			Just before showing the popup menu (under the
+				right mouse button).  Useful for adjusting the
+				menu for what is under the cursor or mouse
+				pointer.
+				The pattern is matched against a single
+				character representing the mode:
+					n	Normal
+					v	Visual
+					o	Operator-pending
+					i	Insert
+					c	Command line
+							*QuickFixCmdPre*
+QuickFixCmdPre			Before a quickfix command is run (|:make|,
+				|:lmake|, |:grep|, |:lgrep|, |:grepadd|,
+				|:lgrepadd|, |:vimgrep|, |:lvimgrep|,
+				|:vimgrepadd|, |:lvimgrepadd|). The pattern is
+				matched against the command being run.  When
+				|:grep| is used but 'grepprg' is set to
+				"internal" it still matches "grep".
+				This command cannot be used to set the
+				'makeprg' and 'grepprg' variables.
+				If this command causes an error, the quickfix
+				command is not executed.
+							*QuickFixCmdPost*
+QuickFixCmdPost			Like QuickFixCmdPre, but after a quickfix
+				command is run, before jumping to the first
+				location.
+							*RemoteReply*
+RemoteReply			When a reply from a Vim that functions as
+				server was received |server2client()|.  The
+				pattern is matched against the {serverid}.
+				<amatch> is equal to the {serverid} from which
+				the reply was sent, and <afile> is the actual
+				reply string.
+				Note that even if an autocommand is defined,
+				the reply should be read with |remote_read()|
+				to consume it.
+							*SessionLoadPost*
+SessionLoadPost			After loading the session file created using
+				the |:mksession| command.
+							*ShellCmdPost*
+ShellCmdPost			After executing a shell command with |:!cmd|,
+				|:shell|, |:make| and |:grep|.  Can be used to
+				check for any changed files.
+							*ShellFilterPost*
+ShellFilterPost			After executing a shell command with
+				":{range}!cmd", ":w !cmd" or ":r !cmd".
+				Can be used to check for any changed files.
+							*SourcePre*
+SourcePre			Before sourcing a Vim script. |:source|
+				<afile> is the name of the file being sourced.
+							*SourceCmd*
+SourceCmd			When sourcing a Vim script. |:source|
+				<afile> is the name of the file being sourced.
+				The autocommand must source this file.
+				|Cmd-event|
+							*SpellFileMissing*
+SpellFileMissing		When trying to load a spell checking file and
+				it can't be found.  The pattern is matched
+				against the language.  <amatch> is the
+				language, 'encoding' also matters.  See
+				|spell-SpellFileMissing|.
+							*StdinReadPost*
+StdinReadPost			After reading from the stdin into the buffer,
+				before executing the modelines.  Only used
+				when the "-" argument was used when Vim was
+				started |--|.
+							*StdinReadPre*
+StdinReadPre			Before reading from stdin into the buffer.
+				Only used when the "-" argument was used when
+				Vim was started |--|.
+							*SwapExists*
+SwapExists			Detected an existing swap file when starting
+				to edit a file.  Only when it is possible to
+				select a way to handle the situation, when Vim
+				would ask the user what to do.
+				The |v:swapname| variable holds the name of
+				the swap file found, <afile> the file being
+				edited.  |v:swapcommand| may contain a command
+				to be executed in the opened file.
+				The commands should set the |v:swapchoice|
+				variable to a string with one character to
+				tell Vim what should be done next:
+					'o'	open read-only
+					'e'	edit the file anyway
+					'r'	recover
+					'd'	delete the swap file
+					'q'	quit, don't edit the file
+					'a'	abort, like hitting CTRL-C
+				When set to an empty string the user will be
+				asked, as if there was no SwapExists autocmd.
+				Note: Do not try to change the buffer, the
+				results are unpredictable.
+							*Syntax*
+Syntax				When the 'syntax' option has been set.  The
+				pattern is matched against the syntax name.
+				<afile> can be used for the name of the file
+				where this option was set, and <amatch> for
+				the new value of 'syntax'.
+				See |:syn-on|.
+							*TabEnter*
+TabEnter			Just after entering a tab page. |tab-page|
+				After triggering the WinEnter and before
+				triggering the BufEnter event.
+							*TabLeave*
+TabLeave			Just before leaving a tab page. |tab-page|
+				A WinLeave event will have been triggered
+				first.
+							*TermChanged*
+TermChanged			After the value of 'term' has changed.  Useful
+				for re-loading the syntax file to update the
+				colors, fonts and other terminal-dependent
+				settings.  Executed for all loaded buffers.
+							*TermResponse*
+TermResponse			After the response to |t_RV| is received from
+				the terminal.  The value of |v:termresponse|
+				can be used to do things depending on the
+				terminal version.
+							*User*
+User				Never executed automatically.  To be used for
+				autocommands that are only executed with
+				":doautocmd".
+							*UserGettingBored*
+UserGettingBored		When the user hits CTRL-C.  Just kidding! :-)
+							*VimEnter*
+VimEnter			After doing all the startup stuff, including
+				loading .vimrc files, executing the "-c cmd"
+				arguments, creating all windows and loading
+				the buffers in them.
+							*VimLeave*
+VimLeave			Before exiting Vim, just after writing the
+				.viminfo file.  Executed only once, like
+				VimLeavePre.
+				To detect an abnormal exit use |v:dying|.
+							*VimLeavePre*
+VimLeavePre			Before exiting Vim, just before writing the
+				.viminfo file.  This is executed only once,
+				if there is a match with the name of what
+				happens to be the current buffer when exiting.
+				Mostly useful with a "*" pattern. >
+	:autocmd VimLeavePre * call CleanupStuff()
+<				To detect an abnormal exit use |v:dying|.
+							*VimResized*
+VimResized			After the Vim window was resized, thus 'lines'
+				and/or 'columns' changed.  Not when starting
+				up though.
+							*WinEnter*
+WinEnter			After entering another window.  Not done for
+				the first window, when Vim has just started.
+				Useful for setting the window height.
+				If the window is for another buffer, Vim
+				executes the BufEnter autocommands after the
+				WinEnter autocommands.
+				Note: When using ":split fname" the WinEnter
+				event is triggered after the split but before
+				the file "fname" is loaded.
+							*WinLeave*
+WinLeave			Before leaving a window.  If the window to be
+				entered next is for a different buffer, Vim
+				executes the BufLeave autocommands before the
+				WinLeave autocommands (but not for ":new").
+				Not used for ":qa" or ":q" when exiting Vim.
+
+==============================================================================
+6. Patterns					*autocmd-patterns* *{pat}*
+
+The file pattern {pat} is tested for a match against the file name in one of
+two ways:
+1. When there is no '/' in the pattern, Vim checks for a match against only
+   the tail part of the file name (without its leading directory path).
+2. When there is a '/' in the pattern,  Vim checks for a match against the
+   both short file name (as you typed it) and the full file name (after
+   expanding it to a full path and resolving symbolic links).
+
+The special pattern <buffer> or <buffer=N> is used for buffer-local
+autocommands |autocmd-buflocal|.  This pattern is not matched against the name
+of a buffer.
+
+Examples: >
+	:autocmd BufRead *.txt		set et
+Set the 'et' option for all text files. >
+
+	:autocmd BufRead /vim/src/*.c	set cindent
+Set the 'cindent' option for C files in the /vim/src directory. >
+
+	:autocmd BufRead /tmp/*.c	set ts=5
+If you have a link from "/tmp/test.c" to "/home/nobody/vim/src/test.c", and
+you start editing "/tmp/test.c", this autocommand will match.
+
+Note:  To match part of a path, but not from the root directory, use a '*' as
+the first character.  Example: >
+	:autocmd BufRead */doc/*.txt	set tw=78
+This autocommand will for example be executed for "/tmp/doc/xx.txt" and
+"/usr/home/piet/doc/yy.txt".  The number of directories does not matter here.
+
+
+The file name that the pattern is matched against is after expanding
+wildcards.  Thus is you issue this command: >
+	:e $ROOTDIR/main.$EXT
+The argument is first expanded to: >
+	/usr/root/main.py
+Before it's matched with the pattern of the autocommand.  Careful with this
+when using events like FileReadCmd, the value of <amatch> may not be what you
+expect.
+
+
+Environment variables can be used in a pattern: >
+	:autocmd BufRead $VIMRUNTIME/doc/*.txt  set expandtab
+And ~ can be used for the home directory (if $HOME is defined): >
+	:autocmd BufWritePost ~/.vimrc   so ~/.vimrc
+	:autocmd BufRead ~archive/*      set readonly
+The environment variable is expanded when the autocommand is defined, not when
+the autocommand is executed.  This is different from the command!
+
+							*file-pattern*
+The pattern is interpreted like mostly used in file names:
+	*	matches any sequence of characters
+	?	matches any single character
+	\?	matches a '?'
+	.	matches a '.'
+	~	matches a '~'
+	,	separates patterns
+	\,	matches a ','
+	{ }	like \( \) in a |pattern|
+	,	inside { }: like \| in a |pattern|
+	\	special meaning like in a |pattern|
+	[ch]	matches 'c' or 'h'
+	[^ch]   match any character but 'c' and 'h'
+
+Note that for all systems the '/' character is used for path separator (even
+MS-DOS and OS/2).  This was done because the backslash is difficult to use
+in a pattern and to make the autocommands portable across different systems.
+
+							*autocmd-changes*
+Matching with the pattern is done when an event is triggered.  Changing the
+buffer name in one of the autocommands, or even deleting the buffer, does not
+change which autocommands will be executed.  Example: >
+
+	au BufEnter *.foo  bdel
+	au BufEnter *.foo  set modified
+
+This will delete the current buffer and then set 'modified' in what has become
+the current buffer instead.  Vim doesn't take into account that "*.foo"
+doesn't match with that buffer name.  It matches "*.foo" with the name of the
+buffer at the moment the event was triggered.
+
+However, buffer-local autocommands will not be executed for a buffer that has
+been wiped out with |:bwipe|.  After deleting the buffer with |:bdel| the
+buffer actually still exists (it becomes unlisted), thus the autocommands are
+still executed.
+
+==============================================================================
+7. Buffer-local autocommands	*autocmd-buflocal* *autocmd-buffer-local*
+					*<buffer=N>* *<buffer=abuf>* *E680*
+
+Buffer-local autocommands are attached to a specific buffer.  They are useful
+if the buffer does not have a name and when the name does not match a specific
+pattern.  But it also means they must be explicitly added to each buffer.
+
+Instead of a pattern buffer-local autocommands use one of these forms:
+	<buffer>	current buffer
+	<buffer=99>	buffer number 99
+	<buffer=abuf>	using <abuf> (only when executing autocommands)
+			|<abuf>|
+
+Examples: >
+    :au CursorHold <buffer>  echo 'hold'
+    :au CursorHold <buffer=33>  echo 'hold'
+    :au CursorHold <buffer=abuf>  echo 'hold'
+
+All the commands for autocommands also work with buffer-local autocommands,
+simply use the special string instead of the pattern.  Examples: >
+    :au! * <buffer>		     " remove buffer-local autocommands for
+				     " current buffer
+    :au! * <buffer=33>		     " remove buffer-local autocommands for
+				     " buffer #33
+    :dobuf :au! CursorHold <buffer>  " remove autocmd for given event for all
+				     " buffers
+    :au * <buffer>		     " list buffer-local autocommands for
+				     " current buffer
+
+Note that when an autocommand is defined for the current buffer, it is stored
+with the buffer number.  Thus it uses the form "<buffer=12>", where 12 is the
+number of the current buffer.  You will see this when listing autocommands,
+for example.
+
+To test for presence of buffer-local autocommands use the |exists()| function
+as follows: >
+    :if exists("#CursorHold#<buffer=12>") | ... | endif
+    :if exists("#CursorHold#<buffer>") | ... | endif    " for current buffer
+
+When a buffer is wiped out its buffer-local autocommands are also gone, of
+course.  Note that when deleting a buffer, e.g., with ":bdel", it is only
+unlisted, the autocommands are still present.  In order to see the removal of
+buffer-local autocommands: >
+    :set verbose=6
+
+It is not possible to define buffer-local autocommands for a non-existent
+buffer.
+
+==============================================================================
+8. Groups						*autocmd-groups*
+
+Autocommands can be put together in a group.  This is useful for removing or
+executing a group of autocommands.  For example, all the autocommands for
+syntax highlighting are put in the "highlight" group, to be able to execute
+":doautoall highlight BufRead" when the GUI starts.
+
+When no specific group is selected, Vim uses the default group.  The default
+group does not have a name.  You cannot execute the autocommands from the
+default group separately; you can execute them only by executing autocommands
+for all groups.
+
+Normally, when executing autocommands automatically, Vim uses the autocommands
+for all groups.  The group only matters when executing autocommands with
+":doautocmd" or ":doautoall", or when defining or deleting autocommands.
+
+The group name can contain any characters except white space.  The group name
+"end" is reserved (also in uppercase).
+
+The group name is case sensitive.  Note that this is different from the event
+name!
+
+							*:aug* *:augroup*
+:aug[roup] {name}		Define the autocmd group name for the
+				following ":autocmd" commands.  The name "end"
+				or "END" selects the default group.
+
+						*:augroup-delete* *E367*
+:aug[roup]! {name}		Delete the autocmd group {name}.  Don't use
+				this if there is still an autocommand using
+				this group!  This is not checked.
+
+To enter autocommands for a specific group, use this method:
+1. Select the group with ":augroup {name}".
+2. Delete any old autocommands with ":au!".
+3. Define the autocommands.
+4. Go back to the default group with "augroup END".
+
+Example: >
+	:augroup uncompress
+	:  au!
+	:  au BufEnter *.gz	%!gunzip
+	:augroup END
+
+This prevents having the autocommands defined twice (e.g., after sourcing the
+.vimrc file again).
+
+==============================================================================
+9. Executing autocommands				*autocmd-execute*
+
+Vim can also execute Autocommands non-automatically.  This is useful if you
+have changed autocommands, or when Vim has executed the wrong autocommands
+(e.g., the file pattern match was wrong).
+
+Note that the 'eventignore' option applies here too.  Events listed in this
+option will not cause any commands to be executed.
+
+					*:do* *:doau* *:doautocmd* *E217*
+:do[autocmd] [group] {event} [fname]
+			Apply the autocommands matching [fname] (default:
+			current file name) for {event} to the current buffer.
+			You can use this when the current file name does not
+			match the right pattern, after changing settings, or
+			to execute autocommands for a certain event.
+			It's possible to use this inside an autocommand too,
+			so you can base the autocommands for one extension on
+			another extension.  Example: >
+				:au Bufenter *.cpp so ~/.vimrc_cpp
+				:au Bufenter *.cpp doau BufEnter x.c
+<			Be careful to avoid endless loops.  See
+			|autocmd-nested|.
+
+			When the [group] argument is not given, Vim executes
+			the autocommands for all groups.  When the [group]
+			argument is included, Vim executes only the matching
+			autocommands for that group.  Note: if you use an
+			undefined group name, Vim gives you an error message.
+
+			After applying the autocommands the modelines are
+			processed, so that their overrule the settings from
+			autocommands, like what happens when editing a file.
+
+						*:doautoa* *:doautoall*
+:doautoa[ll] [group] {event} [fname]
+			Like ":doautocmd", but apply the autocommands to each
+			loaded buffer.  Note that {fname} is used to select
+			the autocommands, not the buffers to which they are
+			applied.
+			Careful: Don't use this for autocommands that delete a
+			buffer, change to another buffer or change the
+			contents of a buffer; the result is unpredictable.
+			This command is intended for autocommands that set
+			options, change highlighting, and things like that.
+
+==============================================================================
+10. Using autocommands					*autocmd-use*
+
+For WRITING FILES there are four possible sets of events.  Vim uses only one
+of these sets for a write command:
+
+BufWriteCmd	BufWritePre	BufWritePost	writing the whole buffer
+		FilterWritePre	FilterWritePost	writing to filter temp file
+FileAppendCmd	FileAppendPre	FileAppendPost	appending to a file
+FileWriteCmd	FileWritePre	FileWritePost	any other file write
+
+When there is a matching "*Cmd" autocommand, it is assumed it will do the
+writing.  No further writing is done and the other events are not triggered.
+|Cmd-event|
+
+Note that the *WritePost commands should undo any changes to the buffer that
+were caused by the *WritePre commands; otherwise, writing the file will have
+the side effect of changing the buffer.
+
+Before executing the autocommands, the buffer from which the lines are to be
+written temporarily becomes the current buffer.  Unless the autocommands
+change the current buffer or delete the previously current buffer, the
+previously current buffer is made the current buffer again.
+
+The *WritePre and *AppendPre autocommands must not delete the buffer from
+which the lines are to be written.
+
+The '[ and '] marks have a special position:
+- Before the *ReadPre event the '[ mark is set to the line just above where
+  the new lines will be inserted.
+- Before the *ReadPost event the '[ mark is set to the first line that was
+  just read, the '] mark to the last line.
+- Before executing the *WriteCmd, *WritePre and *AppendPre autocommands the '[
+  mark is set to the first line that will be written, the '] mark to the last
+  line.
+Careful: '[ and '] change when using commands that change the buffer.
+
+In commands which expect a file name, you can use "<afile>" for the file name
+that is being read |:<afile>| (you can also use "%" for the current file
+name).  "<abuf>" can be used for the buffer number of the currently effective
+buffer.  This also works for buffers that doesn't have a name.  But it doesn't
+work for files without a buffer (e.g., with ":r file").
+
+							*gzip-example*
+Examples for reading and writing compressed files: >
+  :augroup gzip
+  :  autocmd!
+  :  autocmd BufReadPre,FileReadPre	*.gz set bin
+  :  autocmd BufReadPost,FileReadPost	*.gz '[,']!gunzip
+  :  autocmd BufReadPost,FileReadPost	*.gz set nobin
+  :  autocmd BufReadPost,FileReadPost	*.gz execute ":doautocmd BufReadPost " . expand("%:r")
+  :  autocmd BufWritePost,FileWritePost	*.gz !mv <afile> <afile>:r
+  :  autocmd BufWritePost,FileWritePost	*.gz !gzip <afile>:r
+
+  :  autocmd FileAppendPre		*.gz !gunzip <afile>
+  :  autocmd FileAppendPre		*.gz !mv <afile>:r <afile>
+  :  autocmd FileAppendPost		*.gz !mv <afile> <afile>:r
+  :  autocmd FileAppendPost		*.gz !gzip <afile>:r
+  :augroup END
+
+The "gzip" group is used to be able to delete any existing autocommands with
+":autocmd!", for when the file is sourced twice.
+
+("<afile>:r" is the file name without the extension, see |:_%:|)
+
+The commands executed for the BufNewFile, BufRead/BufReadPost, BufWritePost,
+FileAppendPost and VimLeave events do not set or reset the changed flag of the
+buffer.  When you decompress the buffer with the BufReadPost autocommands, you
+can still exit with ":q".  When you use ":undo" in BufWritePost to undo the
+changes made by BufWritePre commands, you can still do ":q" (this also makes
+"ZZ" work).  If you do want the buffer to be marked as modified, set the
+'modified' option.
+
+To execute Normal mode commands from an autocommand, use the ":normal"
+command.  Use with care!  If the Normal mode command is not finished, the user
+needs to type characters (e.g., after ":normal m" you need to type a mark
+name).
+
+If you want the buffer to be unmodified after changing it, reset the
+'modified' option.  This makes it possible to exit the buffer with ":q"
+instead of ":q!".
+
+							*autocmd-nested* *E218*
+By default, autocommands do not nest.  If you use ":e" or ":w" in an
+autocommand, Vim does not execute the BufRead and BufWrite autocommands for
+those commands.  If you do want this, use the "nested" flag for those commands
+in which you want nesting.  For example: >
+  :autocmd FileChangedShell *.c nested e!
+The nesting is limited to 10 levels to get out of recursive loops.
+
+It's possible to use the ":au" command in an autocommand.  This can be a
+self-modifying command!  This can be useful for an autocommand that should
+execute only once.
+
+If you want to skip autocommands for one command, use the |:noautocmd| command
+modifier or the 'eventignore' option.
+
+Note: When reading a file (with ":read file" or with a filter command) and the
+last line in the file does not have an <EOL>, Vim remembers this.  At the next
+write (with ":write file" or with a filter command), if the same line is
+written again as the last line in a file AND 'binary' is set, Vim does not
+supply an <EOL>.  This makes a filter command on the just read lines write the
+same file as was read, and makes a write command on just filtered lines write
+the same file as was read from the filter.  For example, another way to write
+a compressed file: >
+
+  :autocmd FileWritePre *.gz   set bin|'[,']!gzip
+  :autocmd FileWritePost *.gz  undo|set nobin
+<
+							*autocommand-pattern*
+You can specify multiple patterns, separated by commas.  Here are some
+examples: >
+
+  :autocmd BufRead   *		set tw=79 nocin ic infercase fo=2croq
+  :autocmd BufRead   .letter	set tw=72 fo=2tcrq
+  :autocmd BufEnter  .letter	set dict=/usr/lib/dict/words
+  :autocmd BufLeave  .letter	set dict=
+  :autocmd BufRead,BufNewFile   *.c,*.h	set tw=0 cin noic
+  :autocmd BufEnter  *.c,*.h	abbr FOR for (i = 0; i < 3; ++i)<CR>{<CR>}<Esc>O
+  :autocmd BufLeave  *.c,*.h	unabbr FOR
+
+For makefiles (makefile, Makefile, imakefile, makefile.unix, etc.): >
+
+  :autocmd BufEnter  ?akefile*	set include=^s\=include
+  :autocmd BufLeave  ?akefile*	set include&
+
+To always start editing C files at the first function: >
+
+  :autocmd BufRead   *.c,*.h	1;/^{
+
+Without the "1;" above, the search would start from wherever the file was
+entered, rather than from the start of the file.
+
+						*skeleton* *template*
+To read a skeleton (template) file when opening a new file: >
+
+  :autocmd BufNewFile  *.c	0r ~/vim/skeleton.c
+  :autocmd BufNewFile  *.h	0r ~/vim/skeleton.h
+  :autocmd BufNewFile  *.java	0r ~/vim/skeleton.java
+
+To insert the current date and time in a *.html file when writing it: >
+
+  :autocmd BufWritePre,FileWritePre *.html   ks|call LastMod()|'s
+  :fun LastMod()
+  :  if line("$") > 20
+  :    let l = 20
+  :  else
+  :    let l = line("$")
+  :  endif
+  :  exe "1," . l . "g/Last modified: /s/Last modified: .*/Last modified: " .
+  :  \ strftime("%Y %b %d")
+  :endfun
+
+You need to have a line "Last modified: <date time>" in the first 20 lines
+of the file for this to work.  Vim replaces <date time> (and anything in the
+same line after it) with the current date and time.  Explanation:
+	ks		mark current position with mark 's'
+	call LastMod()  call the LastMod() function to do the work
+	's		return the cursor to the old position
+The LastMod() function checks if the file is shorter than 20 lines, and then
+uses the ":g" command to find lines that contain "Last modified: ".  For those
+lines the ":s" command is executed to replace the existing date with the
+current one.  The ":execute" command is used to be able to use an expression
+for the ":g" and ":s" commands.  The date is obtained with the strftime()
+function.  You can change its argument to get another date string.
+
+When entering :autocmd on the command-line, completion of events and command
+names may be done (with <Tab>, CTRL-D, etc.) where appropriate.
+
+Vim executes all matching autocommands in the order that you specify them.
+It is recommended that your first autocommand be used for all files by using
+"*" as the file pattern.  This means that you can define defaults you like
+here for any settings, and if there is another matching autocommand it will
+override these.  But if there is no other matching autocommand, then at least
+your default settings are recovered (if entering this file from another for
+which autocommands did match).  Note that "*" will also match files starting
+with ".", unlike Unix shells.
+
+						    *autocmd-searchpat*
+Autocommands do not change the current search patterns.  Vim saves the current
+search patterns before executing autocommands then restores them after the
+autocommands finish.  This means that autocommands do not affect the strings
+highlighted with the 'hlsearch' option.  Within autocommands, you can still
+use search patterns normally, e.g., with the "n" command.
+If you want an autocommand to set the search pattern, such that it is used
+after the autocommand finishes, use the ":let @/ =" command.
+The search-highlighting cannot be switched off with ":nohlsearch" in an
+autocommand.  Use the 'h' flag in the 'viminfo' option to disable search-
+highlighting when starting Vim.
+
+							*Cmd-event*
+When using one of the "*Cmd" events, the matching autocommands are expected to
+do the file reading, writing or sourcing.  This can be used when working with
+a special kind of file, for example on a remote system.
+CAREFUL: If you use these events in a wrong way, it may have the effect of
+making it impossible to read or write the matching files!  Make sure you test
+your autocommands properly.  Best is to use a pattern that will never match a
+normal file name, for example "ftp://*".
+
+When defining a BufReadCmd it will be difficult for Vim to recover a crashed
+editing session.  When recovering from the original file, Vim reads only those
+parts of a file that are not found in the swap file.  Since that is not
+possible with a BufReadCmd, use the |:preserve| command to make sure the
+original file isn't needed for recovery.  You might want to do this only when
+you expect the file to be modified.
+
+For file read and write commands the |v:cmdarg| variable holds the "++enc="
+and "++ff=" argument that are effective.  These should be used for the command
+that reads/writes the file.  The |v:cmdbang| variable is one when "!" was
+used, zero otherwise.
+
+See the $VIMRUNTIME/plugin/netrw.vim for examples.
+
+==============================================================================
+11. Disabling autocommands				*autocmd-disable*
+
+To disable autocommands for some time use the 'eventignore' option.  Note that
+this may cause unexpected behavior, make sure you restore 'eventignore'
+afterwards, using a |:try| block with |:finally|.
+
+							*:noautocmd* *:noa*
+To disable autocommands for just one command use the ":noautocmd" command
+modifier.  This will set 'eventignore' to "all" for the duration of the
+following command.  Example: >
+
+	:noautocmd w fname.gz
+
+This will write the file without triggering the autocommands defined by the
+gzip plugin.
+
+
+ vim:tw=78:ts=8:ft=help:norl:
--- /dev/null
+++ b/lib/vimfiles/doc/change.txt
@@ -1,0 +1,1585 @@
+*change.txt*    For Vim version 7.1.  Last change: 2007 Jan 07
+
+
+		  VIM REFERENCE MANUAL    by Bram Moolenaar
+
+
+This file describes commands that delete or change text.  In this context,
+changing text means deleting the text and replacing it with other text using
+one command.  You can undo all of these commands.  You can repeat the non-Ex
+commands with the "." command.
+
+1. Deleting text		|deleting|
+2. Delete and insert		|delete-insert|
+3. Simple changes		|simple-change|		*changing*
+4. Complex changes		|complex-change|
+   4.1 Filter commands		   |filter|
+   4.2 Substitute		   |:substitute|
+   4.3 Search and replace	   |search-replace|
+   4.4 Changing tabs		   |change-tabs|
+5. Copying and moving text	|copy-move|
+6. Formatting text		|formatting|
+7. Sorting text			|sorting|
+
+For inserting text see |insert.txt|.
+
+==============================================================================
+1. Deleting text					*deleting* *E470*
+
+["x]<Del>	or					*<Del>* *x* *dl*
+["x]x			Delete [count] characters under and after the cursor
+			[into register x] (not |linewise|).  Does the same as
+			"dl".
+			The <Del> key does not take a [count].  Instead, it
+			deletes the last character of the count.
+			See |:fixdel| if the <Del> key does not do what you
+			want.  See |'whichwrap'| for deleting a line break
+			(join lines).  {Vi does not support <Del>}
+
+							*X* *dh*
+["x]X			Delete [count] characters before the cursor [into
+			register x] (not |linewise|).  Does the same as "dh".
+			Also see |'whichwrap'|.
+
+							*d*
+["x]d{motion}		Delete text that {motion} moves over [into register
+			x].  See below for exceptions.
+
+							*dd*
+["x]dd			Delete [count] lines [into register x] |linewise|.
+
+							*D*
+["x]D			Delete the characters under the cursor until the end
+			of the line and [count]-1 more lines [into register
+			x]; synonym for "d$".
+			(not |linewise|)
+			When the '#' flag is in 'cpoptions' the count is
+			ignored.
+
+{Visual}["x]x	or					*v_x* *v_d* *v_<Del>*
+{Visual}["x]d   or
+{Visual}["x]<Del>	Delete the highlighted text [into register x] (for
+			{Visual} see |Visual-mode|).  {not in Vi}
+
+{Visual}["x]CTRL-H   or					*v_CTRL-H* *v_<BS>*
+{Visual}["x]<BS>	When in Select mode: Delete the highlighted text [into
+			register x].
+
+{Visual}["x]X	or					*v_X* *v_D* *v_b_D*
+{Visual}["x]D		Delete the highlighted lines [into register x] (for
+			{Visual} see |Visual-mode|).  In Visual block mode,
+			"D" deletes the highlighted text plus all text until
+			the end of the line.  {not in Vi}
+
+						*:d* *:de* *:del* *:delete*
+:[range]d[elete] [x]	Delete [range] lines (default: current line) [into
+			register x].
+
+:[range]d[elete] [x] {count}
+			Delete {count} lines, starting with [range]
+			(default: current line |cmdline-ranges|) [into
+			register x].
+
+These commands delete text.  You can repeat them with the "." command
+(except ":d") and undo them.  Use Visual mode to delete blocks of text.  See
+|registers| for an explanation of registers.
+
+An exception for the d{motion} command: If the motion is not linewise, the
+start and end of the motion are not in the same line, and there are only
+blanks before the start and after the end of the motion, the delete becomes
+linewise.  This means that the delete also removes the line of blanks that you
+might expect to remain.
+
+Trying to delete an empty region of text (e.g., "d0" in the first column)
+is an error when 'cpoptions' includes the 'E' flag.
+
+							*J*
+J			Join [count] lines, with a minimum of two lines.
+			Remove the indent and insert up to two spaces (see
+			below).
+
+							*v_J*
+{Visual}J		Join the highlighted lines, with a minimum of two
+			lines.  Remove the indent and insert up to two spaces
+			(see below).  {not in Vi}
+
+							*gJ*
+gJ			Join [count] lines, with a minimum of two lines.
+			Don't insert or remove any spaces.  {not in Vi}
+
+							*v_gJ*
+{Visual}gJ		Join the highlighted lines, with a minimum of two
+			lines.  Don't insert or remove any spaces.  {not in
+			Vi}
+
+							*:j* *:join*
+:[range]j[oin][!] [flags]
+			Join [range] lines.  Same as "J", except with [!]
+			the join does not insert or delete any spaces.
+			If a [range] has equal start and end values, this
+			command does nothing.  The default behavior is to
+			join the current line with the line below it.
+			{not in Vi: !}
+			See |ex-flags| for [flags].
+
+:[range]j[oin][!] {count} [flags]
+			Join {count} lines, starting with [range] (default:
+			current line |cmdline-ranges|).  Same as "J", except
+			with [!] the join does not insert or delete any
+			spaces.
+			{not in Vi: !}
+			See |ex-flags| for [flags].
+
+These commands delete the <EOL> between lines.  This has the effect of joining
+multiple lines into one line.  You can repeat these commands (except ":j") and
+undo them.
+
+These commands, except "gJ", insert one space in place of the <EOL> unless
+there is trailing white space or the next line starts with a ')'.  These
+commands, except "gJ", delete any leading white space on the next line.  If
+the 'joinspaces' option is on, these commands insert two spaces after a '.',
+'!' or '?' (but if 'cpoptions' includes the 'j' flag, they insert two spaces
+only after a '.').
+The 'B' and 'M' flags in 'formatoptions' change the behavior for inserting
+spaces before and after a multi-byte character |fo-table|.
+
+
+==============================================================================
+2. Delete and insert				*delete-insert* *replacing*
+
+							*R*
+R			Enter Replace mode: Each character you type replaces
+			an existing character, starting with the character
+			under the cursor.  Repeat the entered text [count]-1
+			times.  See |Replace-mode| for more details.
+
+							*gR*
+gR			Enter Virtual Replace mode: Each character you type
+			replaces existing characters in screen space.  So a
+			<Tab> may replace several characters at once.
+			Repeat the entered text [count]-1 times.  See
+			|Virtual-Replace-mode| for more details.
+			{not available when compiled without the +vreplace
+			feature}
+
+							*c*
+["x]c{motion}		Delete {motion} text [into register x] and start
+			insert.  When  'cpoptions' includes the 'E' flag and
+			there is no text to delete (e.g., with "cTx" when the
+			cursor is just after an 'x'), an error occurs and
+			insert mode does not start (this is Vi compatible).
+			When  'cpoptions' does not include the 'E' flag, the
+			"c" command always starts insert mode, even if there
+			is no text to delete.
+
+							*cc*
+["x]cc			Delete [count] lines [into register x] and start
+			insert |linewise|.  If 'autoindent' is on, preserve
+			the indent of the first line.
+
+							*C*
+["x]C			Delete from the cursor position to the end of the
+			line and [count]-1 more lines [into register x], and
+			start insert.  Synonym for c$ (not |linewise|).
+
+							*s*
+["x]s			Delete [count] characters [into register x] and start
+			insert (s stands for Substitute).  Synonym for "cl"
+			(not |linewise|).
+
+							*S*
+["x]S			Delete [count] lines [into register x] and start
+			insert.  Synonym for "cc" |linewise|.
+
+{Visual}["x]c	or					*v_c* *v_s*
+{Visual}["x]s		Delete the highlighted text [into register x] and
+			start insert (for {Visual} see |Visual-mode|).  {not
+			in Vi}
+
+							*v_r*
+{Visual}["x]r{char}	Replace all selected characters by {char}.
+
+							*v_C*
+{Visual}["x]C		Delete the highlighted lines [into register x] and
+			start insert.  In Visual block mode it works
+			differently |v_b_C|.  {not in Vi}
+							*v_S*
+{Visual}["x]S		Delete the highlighted lines [into register x] and
+			start insert (for {Visual} see |Visual-mode|).  {not
+			in Vi}
+							*v_R*
+{Visual}["x]R		Currently just like {Visual}["x]S.  In a next version
+			it might work differently. {not in Vi}
+
+Notes:
+- You can end Insert and Replace mode with <Esc>.
+- See the section "Insert and Replace mode" |mode-ins-repl| for the other
+  special characters in these modes.
+- The effect of [count] takes place after Vim exits Insert or Replace mode.
+- When the 'cpoptions' option contains '$' and the change is within one line,
+  Vim continues to show the text to be deleted and puts a '$' at the last
+  deleted character.
+
+See |registers| for an explanation of registers.
+
+Replace mode is just like Insert mode, except that every character you enter
+deletes one character.  If you reach the end of a line, Vim appends any
+further characters (just like Insert mode).  In Replace mode, the backspace
+key restores the original text (if there was any).  (See section "Insert and
+Replace mode" |mode-ins-repl|).
+
+						*cw* *cW*
+Special case: "cw" and "cW" work the same as "ce" and "cE" if the cursor is
+on a non-blank.  This is because Vim interprets "cw" as change-word, and a
+word does not include the following white space.  {Vi: "cw" when on a blank
+followed by other blanks changes only the first blank; this is probably a
+bug, because "dw" deletes all the blanks; use the 'w' flag in 'cpoptions' to
+make it work like Vi anyway}
+
+If you prefer "cw" to include the space after a word, use this mapping: >
+	:map cw dwi
+<
+							*:c* *:ch* *:change*
+:{range}c[hange][!]	Replace lines of text with some different text.
+			Type a line containing only "." to stop replacing.
+			Without {range}, this command changes only the current
+			line.
+			Adding [!] toggles 'autoindent' for the time this
+			command is executed.
+
+==============================================================================
+3. Simple changes					*simple-change*
+
+							*r*
+r{char}			Replace the character under the cursor with {char}.
+			If {char} is a <CR> or <NL>, a line break replaces the
+			character.  To replace with a real <CR>, use CTRL-V
+			<CR>.  CTRL-V <NL> replaces with a <Nul>.
+			{Vi: CTRL-V <CR> still replaces with a line break,
+			cannot replace something with a <CR>}
+			If you give a [count], Vim replaces [count] characters
+			with [count] {char}s.  When {char} is a <CR> or <NL>,
+			however, Vim inserts only one <CR>: "5r<CR>" replaces
+			five characters with a single line break.
+			When {char} is a <CR> or <NL>, Vim performs
+			autoindenting.  This works just like deleting the
+			characters that are replaced and then doing
+			"i<CR><Esc>".
+			{char} can be entered as a digraph |digraph-arg|.
+			|:lmap| mappings apply to {char}.  The CTRL-^ command
+			in Insert mode can be used to switch this on/off
+			|i_CTRL-^|.  See |utf-8-char-arg| about using
+			composing characters when 'encoding' is Unicode.
+
+							*gr*
+gr{char}		Replace the virtual characters under the cursor with
+			{char}.  This replaces in screen space, not file
+			space.  See |gR| and |Virtual-Replace-mode| for more
+			details.  As with |r| a count may be given.
+			{char} can be entered like with |r|.
+			{not available when compiled without the +vreplace
+			feature}
+
+						*digraph-arg*
+The argument for Normal mode commands like |r| and |t| is a single character.
+When 'cpo' doesn't contain the 'D' flag, this character can also be entered
+like |digraphs|.  First type CTRL-K and then the two digraph characters.
+{not available when compiled without the |+digraphs| feature}
+
+						*case*
+The following commands change the case of letters.  The currently active
+|locale| is used.  See |:language|.  The LC_CTYPE value matters here.
+
+							*~*
+~			'notildeop' option: Switch case of the character
+			under the cursor and move the cursor to the right.
+			If a [count] is given, do that many characters. {Vi:
+			no count}
+
+~{motion}		'tildeop' option: switch case of {motion} text. {Vi:
+			tilde cannot be used as an operator}
+
+							*g~*
+g~{motion}		Switch case of {motion} text. {not in Vi}
+
+g~g~							*g~g~* *g~~*
+g~~			Switch case of current line. {not in Vi}.
+
+							*v_~*
+{Visual}~		Switch case of highlighted text (for {Visual} see
+			|Visual-mode|). {not in Vi}
+
+							*v_U*
+{Visual}U		Make highlighted text uppercase (for {Visual} see
+			|Visual-mode|). {not in Vi}
+
+							*gU* *uppercase*
+gU{motion}		Make {motion} text uppercase. {not in Vi}
+			Example: >
+				:map! <C-F> <Esc>gUiw`]a
+<			This works in Insert mode: press CTRL-F to make the
+			word before the cursor uppercase.  Handy to type
+			words in lowercase and then make them uppercase.
+
+
+gUgU							*gUgU* *gUU*
+gUU			Make current line uppercase. {not in Vi}.
+
+							*v_u*
+{Visual}u		Make highlighted text lowercase (for {Visual} see
+			|Visual-mode|).  {not in Vi}
+
+							*gu* *lowercase*
+gu{motion}		Make {motion} text lowercase. {not in Vi}
+
+gugu							*gugu* *guu*
+guu			Make current line lowercase. {not in Vi}.
+
+							*g?* *rot13*
+g?{motion}		Rot13 encode {motion} text. {not in Vi}
+
+							*v_g?*
+{Visual}g?		Rot13 encode the highlighted text (for {Visual} see
+			|Visual-mode|).  {not in Vi}
+
+g?g?							*g?g?* *g??*
+g??			Rot13 encode current line. {not in Vi}.
+
+
+Adding and subtracting ~
+							*CTRL-A*
+CTRL-A			Add [count] to the number or alphabetic character at
+			or after the cursor.  {not in Vi}
+
+							*CTRL-X*
+CTRL-X			Subtract [count] from the number or alphabetic
+			character at or after the cursor.  {not in Vi}
+
+The CTRL-A and CTRL-X commands work for (signed) decimal numbers, unsigned
+octal and hexadecimal numbers and alphabetic characters.  This depends on the
+'nrformats' option.
+- When 'nrformats' includes "octal", Vim considers numbers starting with a '0'
+  to be octal, unless the number includes a '8' or '9'.  Other numbers are
+  decimal and may have a preceding minus sign.
+  If the cursor is on a number, the commands apply to that number; otherwise
+  Vim uses the number to the right of the cursor.
+- When 'nrformats' includes "hex", Vim assumes numbers starting with '0x' or
+  '0X' are hexadecimal.  The case of the rightmost letter in the number
+  determines the case of the resulting hexadecimal number.  If there is no
+  letter in the current number, Vim uses the previously detected case.
+- When 'nrformats' includes "alpha", Vim will change the alphabetic character
+  under or after the cursor.  This is useful to make lists with an alphabetic
+  index.
+
+For numbers with leading zeros (including all octal and hexadecimal numbers),
+Vim preserves the number of characters in the number when possible.  CTRL-A on
+"0077" results in "0100", CTRL-X on "0x100" results in "0x0ff".
+There is one exception: When a number that starts with a zero is found not to
+be octal (it contains a '8' or '9'), but 'nrformats' does include "octal",
+leading zeros are removed to avoid that the result may be recognized as an
+octal number.
+
+Note that when 'nrformats' includes "octal", decimal numbers with leading
+zeros cause mistakes, because they can be confused with octal numbers.
+
+The CTRL-A command is very useful in a macro.  Example: Use the following
+steps to make a numbered list.
+
+1. Create the first list entry, make sure it starts with a number.
+2. qa	     - start recording into register 'a'
+3. Y	     - yank the entry
+4. p	     - put a copy of the entry below the first one
+5. CTRL-A    - increment the number
+6. q	     - stop recording
+7. <count>@a - repeat the yank, put and increment <count> times
+
+
+SHIFTING LINES LEFT OR RIGHT				*shift-left-right*
+
+							*<*
+<{motion}		Shift {motion} lines one 'shiftwidth' leftwards.
+
+							*<<*
+<<			Shift [count] lines one 'shiftwidth' leftwards.
+
+							*v_<*
+{Visual}[count]<	Shift the highlighted lines [count] 'shiftwidth'
+			leftwards (for {Visual} see |Visual-mode|).  {not in
+			Vi}
+
+							*>*
+ >{motion}		Shift {motion} lines one 'shiftwidth' rightwards.
+
+							*>>*
+ >>			Shift [count] lines one 'shiftwidth' rightwards.
+
+							*v_>*
+{Visual}[count]>	Shift the highlighted lines [count] 'shiftwidth'
+			rightwards (for {Visual} see |Visual-mode|).  {not in
+			Vi}
+
+							*:<*
+:[range]<		Shift [range] lines one 'shiftwidth' left.  Repeat '<'
+			for shifting multiple 'shiftwidth's.
+
+:[range]< {count}	Shift {count} lines one 'shiftwidth' left, starting
+			with [range] (default current line |cmdline-ranges|).
+			Repeat '<' for shifting multiple 'shiftwidth's.
+
+:[range]le[ft] [indent]	left align lines in [range].  Sets the indent in the
+			lines to [indent] (default 0).  {not in Vi}
+
+							*:>*
+:[range]> [flags]	Shift {count} [range] lines one 'shiftwidth' right.
+			Repeat '>' for shifting multiple 'shiftwidth's.
+			See |ex-flags| for [flags].
+
+:[range]> {count} [flags]
+			Shift {count} lines one 'shiftwidth' right, starting
+			with [range] (default current line |cmdline-ranges|).
+			Repeat '>' for shifting multiple 'shiftwidth's.
+			See |ex-flags| for [flags].
+
+The ">" and "<" commands are handy for changing the indentation within
+programs.  Use the 'shiftwidth' option to set the size of the white space
+which these commands insert or delete.  Normally the 'shiftwidth' option is 8,
+but you can set it to, say, 3 to make smaller indents.  The shift leftwards
+stops when there is no indent.  The shift right does not affect empty lines.
+
+If the 'shiftround' option is on, the indent is rounded to a multiple of
+'shiftwidth'.
+
+If the 'smartindent' option is on, or 'cindent' is on and 'cinkeys' contains
+'#', shift right does not affect lines starting with '#' (these are supposed
+to be C preprocessor lines that must stay in column 1).
+
+When the 'expandtab' option is off (this is the default) Vim uses <Tab>s as
+much as possible to make the indent.  You can use ">><<" to replace an indent
+made out of spaces with the same indent made out of <Tab>s (and a few spaces
+if necessary).  If the 'expandtab' option is on, Vim uses only spaces.  Then
+you can use ">><<" to replace <Tab>s in the indent by spaces (or use
+":retab!").
+
+To move a line several 'shiftwidth's, use Visual mode or the ":" commands.
+For example: >
+	Vjj4>		move three lines 4 indents to the right
+	:<<<		move current line 3 indents to the left
+	:>> 5		move 5 lines 2 indents to the right
+	:5>>		move line 5 2 indents to the right
+
+==============================================================================
+4. Complex changes					*complex-change*
+
+4.1 Filter commands					*filter*
+
+A filter is a program that accepts text at standard input, changes it in some
+way, and sends it to standard output.  You can use the commands below to send
+some text through a filter, so that it is replace by the filter output.
+Examples of filters are "sort", which sorts lines alphabetically, and
+"indent", which formats C program files (you need a version of indent that
+works like a filter; not all versions do).  The 'shell' option specifies the
+shell Vim uses to execute the filter command (See also the 'shelltype'
+option).  You can repeat filter commands with ".".  Vim does not recognize a
+comment (starting with '"') after the ":!" command.
+
+							*!*
+!{motion}{filter}	Filter {motion} text lines through the external
+			program {filter}.
+
+							*!!*
+!!{filter}		Filter [count] lines through the external program
+			{filter}.
+
+							*v_!*
+{Visual}!{filter}	Filter the highlighted lines through the external
+			program {filter} (for {Visual} see |Visual-mode|).
+			{not in Vi}
+
+:{range}![!]{filter} [!][arg]				*:range!*
+			Filter {range} lines through the external program
+			{filter}.  Vim replaces the optional bangs with the
+			latest given command and appends the optional [arg].
+			Vim saves the output of the filter command in a
+			temporary file and then reads the file into the
+			buffer.  Vim uses the 'shellredir' option to redirect
+			the filter output to the temporary file.
+			However, if the 'shelltemp' option is off then pipes
+			are used when possible (on Unix).
+			When the 'R' flag is included in 'cpoptions' marks in
+			the filtered lines are deleted, unless the
+			|:keepmarks| command is used.  Example: >
+				:keepmarks '<,'>!sort
+<			When the number of lines after filtering is less than
+			before, marks in the missing lines are deleted anyway.
+
+							*=*
+={motion}		Filter {motion} lines through the external program
+			given with the 'equalprg' option.  When the 'equalprg'
+			option is empty (this is the default), use the
+			internal formatting function |C-indenting|.  But when
+			'indentexpr' is not empty, it will be used instead
+			|indent-expression|.
+
+							*==*
+==			Filter [count] lines like with ={motion}.
+
+							*v_=*
+{Visual}=		Filter the highlighted lines like with ={motion}.
+			{not in Vi}
+
+
+4.2 Substitute						*:substitute*
+							*:s* *:su*
+:[range]s[ubstitute]/{pattern}/{string}/[flags] [count]
+			For each line in [range] replace a match of {pattern}
+			with {string}.
+			For the {pattern} see |pattern|.
+			{string} can be a literal string, or something
+			special; see |sub-replace-special|.
+			When [range] and [count] are omitted, replace in the
+			current line only.
+			When [count] is given, replace in [count] lines,
+			starting with the last line in [range].  When [range]
+			is omitted start in the current line.
+			Also see |cmdline-ranges|.
+			See |:s_flags| for [flags].
+
+:[range]s[ubstitute] [flags] [count]
+:[range]&[&][flags] [count]					*:&*
+			Repeat last :substitute with same search pattern and
+			substitute string, but without the same flags.  You
+			may add [flags], see |:s_flags|.
+			Note that after ":substitute" the '&' flag can't be
+			used, it's recognized as a pattern separator.
+			The space between ":substitute" and the 'c', 'g' and
+			'r' flags isn't required, but in scripts it's a good
+			idea to keep it to avoid confusion.
+
+:[range]~[&][flags] [count]					*:~*
+			Repeat last substitute with same substitute string
+			but with last used search pattern.  This is like
+			":&r".  See |:s_flags| for [flags].
+
+								*&*
+&			Synonym for ":s//~/" (repeat last substitute).  Note
+			that the flags are not remembered, thus it might
+			actually work differently.  You can use ":&&" to keep
+			the flags.
+
+								*g&*
+g&			Synonym for ":%s//~/&" (repeat last substitute on all
+			lines with the same flags).
+			Mnemonic: global substitute. {not in Vi}
+
+						*:snomagic* *:sno*
+:[range]sno[magic] ...	Same as ":substitute", but always use 'nomagic'.
+			{not in Vi}
+
+						*:smagic* *:sm*
+:[range]sm[agic] ...	Same as ":substitute", but always use 'magic'.
+			{not in Vi}
+
+							*:s_flags*
+The flags that you can use for the substitute commands:
+
+[&]	Must be the first one: Keep the flags from the previous substitute
+	command.  Examples: >
+		:&&
+		:s/this/that/&
+<	Note that ":s" and ":&" don't keep the flags.
+	{not in Vi}
+
+[c]	Confirm each substitution.  Vim highlights the matching string (with
+	|hl-IncSearch|).  You can type:				*:s_c*
+	    'y'	    to substitute this match
+	    'l'	    to substitute this match and then quit ("last")
+	    'n'	    to skip this match
+	    <Esc>   to quit substituting
+	    'a'	    to substitute this and all remaining matches {not in Vi}
+	    'q'	    to quit substituting {not in Vi}
+	    CTRL-E  to scroll the screen up {not in Vi, not available when
+			compiled without the +insert_expand feature}
+	    CTRL-Y  to scroll the screen down {not in Vi, not available when
+			compiled without the +insert_expand feature}
+	If the 'edcompatible' option is on, Vim remembers the [c] flag and
+	toggles it each time you use it, but resets it when you give a new
+	search pattern.
+	{not in Vi: highlighting of the match, other responses than 'y' or 'n'}
+
+[e]     When the search pattern fails, do not issue an error message and, in
+	particular, continue in maps as if no error occurred.  This is most
+	useful to prevent the "No match" error from breaking a mapping.  Vim
+	does not suppress the following error messages, however:
+		Regular expressions can't be delimited by letters
+		\ should be followed by /, ? or &
+		No previous substitute regular expression
+		Trailing characters
+		Interrupted
+	{not in Vi}
+
+[g]	Replace all occurrences in the line.  Without this argument,
+	replacement occurs only for the first occurrence in each line.  If
+	the 'edcompatible' option is on, Vim remembers this flag and toggles
+	it each time you use it, but resets it when you give a new search
+	pattern.  If the 'gdefault' option is on, this flag is on by default
+	and the [g] argument switches it off.
+
+[i]	Ignore case for the pattern.  The 'ignorecase' and 'smartcase' options
+	are not used.
+	{not in Vi}
+
+[I]	Don't ignore case for the pattern.  The 'ignorecase' and 'smartcase'
+	options are not used.
+	{not in Vi}
+
+[n]	Report the number of matches, do not actually substitute.  The [c]
+	flag is ignored.  The matches are reported as if 'report' is zero.
+	Useful to |count-items|.
+
+[p]	Print the line containing the last substitute.
+
+[#]	Like [p] and prepend the line number.
+
+[l]	Like [p] but print the text like |:list|.
+
+[r]	Only useful in combination with ":&" or ":s" without arguments.  ":&r"
+	works the same way as ":~":  When the search pattern is empty, use the
+	previously used search pattern instead of the search pattern from the
+	last substitute or ":global".  If the last command that did a search
+	was a substitute or ":global", there is no effect.  If the last
+	command was a search command such as "/", use the pattern from that
+	command.
+	For ":s" with an argument this already happens: >
+		:s/blue/red/
+		/green
+		:s//red/   or  :~   or  :&r
+<	The last commands will replace "green" with "red". >
+		:s/blue/red/
+		/green
+		:&
+<	The last command will replace "blue" with "red".
+	{not in Vi}
+
+Note that there is no flag to change the "magicness" of the pattern.  A
+different command is used instead.  The reason is that the flags can only be
+found by skipping the pattern, and in order to skip the pattern the
+"magicness" must be known.  Catch 22!
+
+If the {pattern} for the substitute command is empty, the command uses the
+pattern from the last substitute or ":global" command.  With the [r] flag, the
+command uses the pattern from the last substitute, ":global", or search
+command.
+
+If the {string} is omitted the substitute is done as if it's empty.  Thus the
+matched pattern is deleted.  The separator after {pattern} can also be left
+out then.  Example: >
+	:%s/TESTING
+This deletes "TESTING" from all lines, but only one per line.
+
+For compatibility with Vi these two exceptions are allowed:
+"\/{string}/" and "\?{string}?" do the same as "//{string}/r".
+"\&{string}&" does the same as "//{string}/".
+							*E146*
+Instead of the '/' which surrounds the pattern and replacement string, you
+can use any other single-byte character, but not an alphanumeric character,
+'\', '"' or '|'.  This is useful if you want to include a '/' in the search
+pattern or replacement string.  Example: >
+	:s+/+//+
+
+For the definition of a pattern, see |pattern|.
+
+					*sub-replace-special* *:s\=*
+When the {string} starts with "\=" it is evaluated as an expression, see
+|sub-replace-expression|.  You can use that for any special characters.
+Otherwise these characters in {string} have a special meaning:
+								*:s%*
+When {string} is equal to "%" and '/' is included with the 'cpoptions' option,
+then the {string} of the previous substitute command is used. |cpo-/|
+
+magic	nomagic	  action    ~
+  &	  \&	  replaced with the whole matched pattern	     *s/\&*
+ \&	   &	  replaced with &
+      \0	  replaced with the whole matched pattern	   *\0* *s/\0*
+      \1	  replaced with the matched pattern in the first
+		  pair of ()					     *s/\1*
+      \2	  replaced with the matched pattern in the second
+		  pair of ()					     *s/\2*
+      ..	  ..						     *s/\3*
+      \9	  replaced with the matched pattern in the ninth
+		  pair of ()					     *s/\9*
+  ~	  \~	  replaced with the {string} of the previous
+		  substitute					     *s~*
+ \~	   ~	  replaced with ~				     *s/\~*
+      \u	  next character made uppercase			     *s/\u*
+      \U	  following characters made uppercase, until \E      *s/\U*
+      \l	  next character made lowercase			     *s/\l*
+      \L	  following characters made lowercase, until \E      *s/\L*
+      \e	  end of \u, \U, \l and \L (NOTE: not <Esc>!)	     *s/\e*
+      \E	  end of \u, \U, \l and \L			     *s/\E*
+      <CR>	  split line in two at this point
+		  (Type the <CR> as CTRL-V <Enter>)		     *s<CR>*
+      \r	  idem						     *s/\r*
+      \<CR>	  insert a carriage-return (CTRL-M)
+		  (Type the <CR> as CTRL-V <Enter>)		     *s/\<CR>*
+      \n	  insert a <NL> (<NUL> in the file)
+		  (does NOT break the line)			     *s/\n*
+      \b	  insert a <BS>					     *s/\b*
+      \t	  insert a <Tab>				     *s/\t*
+      \\	  insert a single backslash			     *s/\\*
+      \x	  where x is any character not mentioned above:
+		  Reserved for future expansion
+
+Examples: >
+  :s/a\|b/xxx\0xxx/g		 modifies "a b"	     to "xxxaxxx xxxbxxx"
+  :s/\([abc]\)\([efg]\)/\2\1/g	 modifies "af fa bg" to "fa fa gb"
+  :s/abcde/abc^Mde/		 modifies "abcde"    to "abc", "de" (two lines)
+  :s/$/\^M/			 modifies "abcde"    to "abcde^M"
+  :s/\w\+/\u\0/g		 modifies "bla bla"  to "Bla Bla"
+
+Note: In previous versions CTRL-V was handled in a special way.  Since this is
+not Vi compatible, this was removed.  Use a backslash instead.
+
+command		text	result ~
+:s/aa/a^Ma/	aa	a<line-break>a
+:s/aa/a\^Ma/	aa	a^Ma
+:s/aa/a\\^Ma/	aa	a\<line-break>a
+
+(you need to type CTRL-V <CR> to get a ^M here)
+
+The numbering of "\1", "\2" etc. is done based on which "\(" comes first in
+the pattern (going left to right).  When a parentheses group matches several
+times, the last one will be used for "\1", "\2", etc.  Example: >
+  :s/\(\(a[a-d] \)*\)/\2/      modifies "aa ab x" to "ab x"
+
+When using parentheses in combination with '|', like in \([ab]\)\|\([cd]\),
+either the first or second pattern in parentheses did not match, so either
+\1 or \2 is empty.  Example: >
+  :s/\([ab]\)\|\([cd]\)/\1x/g   modifies "a b c d"  to "ax bx x x"
+<
+
+Substitute with an expression			*sub-replace-expression*
+						*sub-replace-\=*
+When the substitute string starts with "\=" the remainder is interpreted as an
+expression.  This does not work recursively: a substitute() function inside
+the expression cannot use "\=" for the substitute string.
+
+The special meaning for characters as mentioned at |sub-replace-special| does
+not apply except "<CR>", "\<CR>" and "\\".  Thus in the result of the
+expression you need to use two backslashes get one, put a backslash before a
+<CR> you want to insert and use a <CR> without a backslash where you want to
+break the line.
+
+For convenience a <NL> character is also used as a line break.  Prepend a
+backslash to get a real <NL> character (which will be a NUL in the file).
+
+When the result is a |List| then the items are joined with separating line
+breaks.  Thus each item becomes a line, except that they can contain line
+breaks themselves.
+
+The whole matched text can be accessed with "submatch(0)".  The text matched
+with the first pair of () with "submatch(1)".  Likewise for further
+sub-matches in ().
+
+Be careful: The separation character must not appear in the expression!
+Consider using a character like "@" or ":".  There is no problem if the result
+of the expression contains the separation character.
+
+Examples: >
+	:s@\n@\="\r" . expand("$HOME") . "\r"@
+This replaces an end-of-line with a new line containing the value of $HOME. >
+
+	s/E/\="\<Char-0x20ac>"/g
+This replaces 'E' characters with an euro sign. Read more in |<Char->|.
+
+
+4.3 Search and replace					*search-replace*
+
+							*:pro* *:promptfind*
+:promptf[ind] [string]
+			Put up a Search dialog.  When [string] is given, it is
+			used as the initial search string.
+			{only for Win32, Motif and GTK GUI}
+
+						*:promptr* *:promptrepl*
+:promptr[epl] [string]
+			Put up a Search/Replace dialog.  When [string] is
+			given, it is used as the initial search string.
+			{only for Win32, Motif and GTK GUI}
+
+
+4.4 Changing tabs					*change-tabs*
+							*:ret* *:retab*
+:[range]ret[ab][!] [new_tabstop]
+			Replace all sequences of white-space containing a
+			<Tab> with new strings of white-space using the new
+			tabstop value given.  If you do not specify a new
+			tabstop size or it is zero, Vim uses the current value
+			of 'tabstop'.
+			The current value of 'tabstop' is always used to
+			compute the width of existing tabs.
+			With !, Vim also replaces strings of only normal
+			spaces with tabs where appropriate.
+			With 'expandtab' on, Vim replaces all tabs with the
+			appropriate number of spaces.
+			This command sets 'tabstop' to the new value given,
+			and if performed on the whole file, which is default,
+			should not make any visible change.
+			Careful: This command modifies any <Tab> characters
+			inside of strings in a C program.  Use "\t" to avoid
+			this (that's a good habit anyway).
+			":retab!" may also change a sequence of spaces by
+			<Tab> characters, which can mess up a printf().
+			{not in Vi}
+			Not available when |+ex_extra| feature was disabled at
+			compile time.
+
+							*retab-example*
+Example for using autocommands and ":retab" to edit a file which is stored
+with tabstops at 8 but edited with tabstops set at 4.  Warning: white space
+inside of strings can change!  Also see 'softtabstop' option. >
+
+  :auto BufReadPost	*.xx	retab! 4
+  :auto BufWritePre	*.xx	retab! 8
+  :auto BufWritePost	*.xx	retab! 4
+  :auto BufNewFile	*.xx	set ts=4
+
+==============================================================================
+5. Copying and moving text				*copy-move*
+
+							*quote*
+"{a-zA-Z0-9.%#:-"}	Use register {a-zA-Z0-9.%#:-"} for next delete, yank
+			or put (use uppercase character to append with
+			delete and yank) ({.%#:} only work with put).
+
+							*:reg* *:registers*
+:reg[isters]		Display the contents of all numbered and named
+			registers.  {not in Vi}
+
+:reg[isters] {arg}	Display the contents of the numbered and named
+			registers that are mentioned in {arg}.  For example: >
+				:dis 1a
+<			to display registers '1' and 'a'.  Spaces are allowed
+			in {arg}.  {not in Vi}
+
+							*:di* *:display*
+:di[splay] [arg]	Same as :registers.  {not in Vi}
+
+							*y* *yank*
+["x]y{motion}		Yank {motion} text [into register x].  When no
+			characters are to be yanked (e.g., "y0" in column 1),
+			this is an error when 'cpoptions' includes the 'E'
+			flag.
+
+							*yy*
+["x]yy			Yank [count] lines [into register x] |linewise|.
+
+							*Y*
+["x]Y			yank [count] lines [into register x] (synonym for
+			yy, |linewise|).  If you like "Y" to work from the
+			cursor to the end of line (which is more logical,
+			but not Vi-compatible) use ":map Y y$".
+
+							*v_y*
+{Visual}["x]y		Yank the highlighted text [into register x] (for
+			{Visual} see |Visual-mode|).  {not in Vi}
+
+							*v_Y*
+{Visual}["x]Y		Yank the highlighted lines [into register x] (for
+			{Visual} see |Visual-mode|).  {not in Vi}
+
+							*:y* *:yank*
+:[range]y[ank] [x]	Yank [range] lines [into register x].
+
+:[range]y[ank] [x] {count}
+			Yank {count} lines, starting with last line number
+			in [range] (default: current line |cmdline-ranges|),
+			[into register x].
+
+							*p* *put* *E353*
+["x]p			Put the text [from register x] after the cursor
+			[count] times.  {Vi: no count}
+
+							*P*
+["x]P			Put the text [from register x] before the cursor
+			[count] times.  {Vi: no count}
+
+							*<MiddleMouse>*
+["x]<MiddleMouse>	Put the text from a register before the cursor [count]
+			times.  Uses the "* register, unless another is
+			specified.
+			Leaves the cursor at the end of the new text.
+			Using the mouse only works when 'mouse' contains 'n'
+			or 'a'.
+			{not in Vi}
+			If you have a scrollwheel and often accidentally paste
+			text, you can use these mappings to disable the
+			pasting with the middle mouse button: >
+				:map <MiddleMouse> <Nop>
+				:imap <MiddleMouse> <Nop>
+<			You might want to disable the multi-click versions
+			too, see |double-click|.
+
+							*gp*
+["x]gp			Just like "p", but leave the cursor just after the new
+			text.  {not in Vi}
+
+							*gP*
+["x]gP			Just like "P", but leave the cursor just after the new
+			text.  {not in Vi}
+
+							*:pu* *:put*
+:[line]pu[t] [x]	Put the text [from register x] after [line] (default
+			current line).  This always works |linewise|, thus
+			this command can be used to put a yanked block as new
+			lines.
+			The cursor is left on the first non-blank in the last
+			new line.
+			The register can also be '=' followed by an optional
+			expression.  The expression continues until the end of
+			the command.  You need to escape the '|' and '"'
+			characters to prevent them from terminating the
+			command.  Example: >
+				:put ='path' . \",/test\"
+<			If there is no expression after '=', Vim uses the
+			previous expression.  You can see it with ":dis =".
+
+:[line]pu[t]! [x]	Put the text [from register x] before [line] (default
+			current line).
+
+["x]]p		    or					*]p* *]<MiddleMouse>*
+["x]]<MiddleMouse>	Like "p", but adjust the indent to the current line.
+			Using the mouse only works when 'mouse' contains 'n'
+			or 'a'.  {not in Vi}
+
+["x][P		    or					*[P*
+["x]]P		    or					*]P*
+["x][p		    or					*[p* *[<MiddleMouse>*
+["x][<MiddleMouse>	Like "P", but adjust the indent to the current line.
+			Using the mouse only works when 'mouse' contains 'n'
+			or 'a'.  {not in Vi}
+
+You can use these commands to copy text from one place to another.  Do this
+by first getting the text into a register with a yank, delete or change
+command, then inserting the register contents with a put command.  You can
+also use these commands to move text from one file to another, because Vim
+preserves all registers when changing buffers (the CTRL-^ command is a quick
+way to toggle between two files).
+
+				*linewise-register* *characterwise-register*
+You can repeat the put commands with "." (except for :put) and undo them.  If
+the command that was used to get the text into the register was |linewise|,
+Vim inserts the text below ("p") or above ("P") the line where the cursor is.
+Otherwise Vim inserts the text after ("p") or before ("P") the cursor.  With
+the ":put" command, Vim always inserts the text in the next line.  You can
+exchange two characters with the command sequence "xp".  You can exchange two
+lines with the command sequence "ddp".  You can exchange two words with the
+command sequence "deep" (start with the cursor in the blank space before the
+first word).  You can use the "']" or "`]" command after the put command to
+move the cursor to the end of the inserted text, or use "'[" or "`[" to move
+the cursor to the start.
+
+						*put-Visual-mode* *v_p* *v_P*
+When using a put command like |p| or |P| in Visual mode, Vim will try to
+replace the selected text with the contents of the register.  Whether this
+works well depends on the type of selection and the type of the text in the
+register.  With blockwise selection it also depends on the size of the block
+and whether the corners are on an existing character.  (Implementation detail:
+it actually works by first putting the register after the selection and then
+deleting the selection.)
+
+							*blockwise-register*
+If you use a blockwise Visual mode command to get the text into the register,
+the block of text will be inserted before ("P") or after ("p") the cursor
+column in the current and next lines.  Vim makes the whole block of text start
+in the same column.  Thus the inserted text looks the same as when it was
+yanked or deleted.  Vim may replace some <Tab> characters with spaces to make
+this happen.  However, if the width of the block is not a multiple of a <Tab>
+width and the text after the inserted block contains <Tab>s, that text may be
+misaligned.
+
+Note that after a characterwise yank command, Vim leaves the cursor on the
+first yanked character that is closest to the start of the buffer.  This means
+that "yl" doesn't move the cursor, but "yh" moves the cursor one character
+left.
+Rationale:	In Vi the "y" command followed by a backwards motion would
+		sometimes not move the cursor to the first yanked character,
+		because redisplaying was skipped.  In Vim it always moves to
+		the first character, as specified by Posix.
+With a linewise yank command the cursor is put in the first line, but the
+column is unmodified, thus it may not be on the first yanked character.
+
+There are nine types of registers:			*registers* *E354*
+1. The unnamed register ""
+2. 10 numbered registers "0 to "9
+3. The small delete register "-
+4. 26 named registers "a to "z or "A to "Z
+5. four read-only registers ":, "., "% and "#
+6. the expression register "=
+7. The selection and drop registers "*, "+ and "~ 
+8. The black hole register "_
+9. Last search pattern register "/
+
+1. Unnamed register ""				*quote_quote* *quotequote*
+Vim fills this register with text deleted with the "d", "c", "s", "x" commands
+or copied with the yank "y" command, regardless of whether or not a specific
+register was used (e.g.  "xdd).  This is like the unnamed register is pointing
+to the last used register.  An exception is the '_' register: "_dd does not
+store the deleted text in any register.
+Vim uses the contents of the unnamed register for any put command (p or P)
+which does not specify a register.  Additionally you can access it with the
+name '"'.  This means you have to type two double quotes.  Writing to the ""
+register writes to register "0.
+{Vi: register contents are lost when changing files, no '"'}
+
+2. Numbered registers "0 to "9		*quote_number* *quote0*	*quote1*
+					*quote2* *quote3* *quote4* *quote9*
+Vim fills these registers with text from yank and delete commands.
+   Numbered register 0 contains the text from the most recent yank command,
+unless the command specified another register with ["x].
+   Numbered register 1 contains the text deleted by the most recent delete or
+change command, unless the command specified another register or the text is
+less than one line (the small delete register is used then).  An exception is
+made for the delete operator with these movement commands: |%|, |(|, |)|, |`|,
+|/|, |?|, |n|, |N|, |{| and |}|.  Register "1 is always used then (this is Vi
+compatible).  The "- register is used as well if the delete is within a line.
+   With each successive deletion or change, Vim shifts the previous contents
+of register 1 into register 2, 2 into 3, and so forth, losing the previous
+contents of register 9.
+{Vi: numbered register contents are lost when changing files; register 0 does
+not exist}
+
+3. Small delete register "-				*quote_-* *quote-*
+This register contains text from commands that delete less than one line,
+except when the command specifies a register with ["x].
+{not in Vi}
+
+4. Named registers "a to "z or "A to "Z			*quote_alpha* *quotea*
+Vim fills these registers only when you say so.  Specify them as lowercase
+letters to replace their previous contents or as uppercase letters to append
+to their previous contents.  When the '>' flag is present in 'cpoptions' then
+a line break is inserted before the appended text.
+
+5. Read-only registers ":, "., "% and "#
+These are '%', '#', ':' and '.'.  You can use them only with the "p", "P",
+and ":put" commands and with CTRL-R.  {not in Vi}
+						*quote_.* *quote.* *E29*
+	".	Contains the last inserted text (the same as what is inserted
+		with the insert mode commands CTRL-A and CTRL-@).  Note: this
+		doesn't work with CTRL-R on the command-line.  It works a bit
+		differently, like inserting the text instead of putting it
+		('textwidth' and other options affect what is inserted).
+							*quote_%* *quote%*
+	"%	Contains the name of the current file.
+							*quote_#* *quote#*
+	"#	Contains the name of the alternate file.
+						*quote_:* *quote:* *E30*
+	":	Contains the most recent executed command-line.  Example: Use
+		"@:" to repeat the previous command-line command.
+		The command-line is only stored in this register when at least
+		one character of it was typed.  Thus it remains unchanged if
+		the command was completely from a mapping.
+		{not available when compiled without the |+cmdline_hist|
+		feature}
+
+6. Expression register "=			*quote_=* *quote=* *@=*
+This is not really a register that stores text, but is a way to use an
+expression in commands which use a register.  The expression register is
+read-only; you cannot put text into it.  After the '=', the cursor moves to
+the command-line, where you can enter any expression (see |expression|).  All
+normal command-line editing commands are available, including a special
+history for expressions.  When you end the command-line by typing <CR>, Vim
+computes the result of the expression.  If you end it with <Esc>, Vim abandons
+the expression.  If you do not enter an expression, Vim uses the previous
+expression (like with the "/" command).  The expression must evaluate to a
+string.  If the result is a number it's turned into a string.  A List,
+Dictionary or FuncRef results in an error message (use string() to convert).
+If the "= register is used for the "p" command, the string is split up at <NL>
+characters.  If the string ends in a <NL>, it is regarded as a linewise
+register.  {not in Vi}
+
+7. Selection and drop registers "*, "+ and "~ 
+Use these register for storing and retrieving the selected text for the GUI.
+See |quotestar| and |quoteplus|.  When the clipboard is not available or not
+working, the unnamed register is used instead.  For Unix systems the clipboard
+is only available when the |+xterm_clipboard| feature is present.  {not in Vi}
+
+Note that there is only a distinction between "* and "+ for X11 systems.  For
+an explanation of the difference, see |x11-selection|.  Under MS-Windows, use
+of "* and "+ is actually synonymous and refers to the |gui-clipboard|.
+
+						*quote_~* *quote~* *<Drop>*
+The read-only "~ register stores the dropped text from the last drag'n'drop
+operation.  When something has been dropped onto Vim, the "~ register is
+filled in and the <Drop> pseudo key is sent for notification.  You can remap
+this key if you want; the default action (for all modes) is to insert the
+contents of the "~ register at the cursor position.  {not in Vi}
+{only available when compiled with the |+dnd| feature, currently only with the
+GTK GUI}
+
+Note: The "~ register is only used when dropping plain text onto Vim.
+Drag'n'drop of URI lists is handled internally.
+
+8. Black hole register "_				*quote_*
+When writing to this register, nothing happens.  This can be used to delete
+text without affecting the normal registers.  When reading from this register,
+nothing is returned.  {not in Vi}
+
+9. Last search pattern register	"/			*quote_/* *quote/*
+Contains the most recent search-pattern.  This is used for "n" and 'hlsearch'.
+It is writable with ":let", you can change it to have 'hlsearch' highlight
+other matches without actually searching.  You can't yank or delete into this
+register.  {not in Vi}
+
+							*@/*
+You can write to a register with a ":let" command |:let-@|.  Example: >
+	:let @/ = "the"
+
+If you use a put command without specifying a register, Vim uses the register
+that was last filled (this is also the contents of the unnamed register).  If
+you are confused, use the ":dis" command to find out what Vim will put (this
+command displays all named and numbered registers; the unnamed register is
+labelled '"').
+
+The next three commands always work on whole lines.
+
+:[range]co[py] {address}				*:co* *:copy*
+			Copy the lines given by [range] to below the line
+			given by {address}.
+
+							*:t*
+:t			Synonym for copy.
+
+:[range]m[ove] {address}			*:m* *:mo* *:move* *E134*
+			Move the lines given by [range] to below the line
+			given by {address}.
+
+==============================================================================
+6. Formatting text					*formatting*
+
+:[range]ce[nter] [width]				*:ce* *:center*
+			Center lines in [range] between [width] columns
+			(default 'textwidth' or 80 when 'textwidth' is 0).
+			{not in Vi}
+			Not available when |+ex_extra| feature was disabled at
+			compile time.
+
+:[range]ri[ght] [width]					*:ri* *:right*
+			Right-align lines in [range] at [width] columns
+			(default 'textwidth' or 80 when 'textwidth' is 0).
+			{not in Vi}
+			Not available when |+ex_extra| feature was disabled at
+			compile time.
+
+							*:le* *:left*
+:[range]le[ft] [indent]
+			Left-align lines in [range].  Sets the indent in the
+			lines to [indent] (default 0).  {not in Vi}
+			Not available when |+ex_extra| feature was disabled at
+			compile time.
+
+							*gq*
+gq{motion}		Format the lines that {motion} moves over.
+			Formatting is done with one of three methods:
+			1. If 'formatexpr' is not empty the expression is
+			   evaluated.  This can differ for each buffer.
+			2. If 'formatprg' is not empty an external program
+			   is used.
+			3. Otherwise formatting is done internally.
+
+			In the third case the 'textwidth' option controls the
+			length of each formatted line (see below).
+			If the 'textwidth' option is 0, the formatted line
+			length is the screen width (with a maximum width of
+			79).
+			The 'formatoptions' option controls the type of
+			formatting |fo-table|.
+			The cursor is left on the first non-blank of the last
+			formatted line.
+			NOTE: The "Q" command formerly performed this
+			function.  If you still want to use "Q" for
+			formatting, use this mapping: >
+				:nnoremap Q gq
+
+gqgq							*gqgq* *gqq*
+gqq			Format the current line.  {not in Vi}
+
+							*v_gq*
+{Visual}gq		Format the highlighted text.  (for {Visual} see
+			|Visual-mode|).  {not in Vi}
+
+							*gw*
+gw{motion}		Format the lines that {motion} moves over.  Similar to
+			|gq| but puts the cursor back at the same position in
+			the text.  However, 'formatprg' and 'formatexpr' are
+			not used.  {not in Vi}
+
+gwgw							*gwgw* *gww*
+gww			Format the current line as with "gw".  {not in Vi}
+
+							*v_gw*
+{Visual}gw		Format the highlighted text as with "gw".  (for
+			{Visual} see |Visual-mode|).  {not in Vi}
+
+Example: To format the current paragraph use:			*gqap*  >
+	gqap
+
+The "gq" command leaves the cursor in the line where the motion command takes
+the cursor.  This allows you to repeat formatting repeated with ".".  This
+works well with "gqj" (format current and next line) and "gq}" (format until
+end of paragraph).  Note: When 'formatprg' is set, "gq" leaves the cursor on
+the first formatted line (as with using a filter command).
+
+If you want to format the current paragraph and continue where you were, use: >
+	gwap
+If you always want to keep paragraphs formatted you may want to add the 'a'
+flag to 'formatoptions'.  See |auto-format|.
+
+If the 'autoindent' option is on, Vim uses the indent of the first line for
+the following lines.
+
+Formatting does not change empty lines (but it does change lines with only
+white space!).
+
+The 'joinspaces' option is used when lines are joined together.
+
+You can set the 'formatexpr' option to an expression or the 'formatprg' option
+to the name of an external program for Vim to use for text formatting.  The
+'textwidth' and other options have no effect on formatting by an external
+program.
+
+							*right-justify*
+There is no command in Vim to right justify text.  You can do it with
+an external command, like "par" (e.g.: "!}par" to format until the end of the
+paragraph) or set 'formatprg' to "par".
+
+							*format-comments*
+Vim can format comments in a special way.  Vim recognizes a comment by a
+specific string at the start of the line (ignoring white space).  Three types
+of comments can be used:
+
+- A comment string that repeats at the start of each line.  An example is the
+  type of comment used in shell scripts, starting with "#".
+- A comment string that occurs only in the first line, not in the following
+  lines.  An example is this list with dashes.
+- Three-piece comments that have a start string, an end string, and optional
+  lines in between.  The strings for the start, middle and end are different.
+  An example is the C-style comment:
+	/*
+	 * this is a C comment
+	 */
+
+The 'comments' option is a comma-separated list of parts.  Each part defines a
+type of comment string.  A part consists of:
+	{flags}:{string}
+
+{string} is the literal text that must appear.
+
+{flags}:
+  n	Nested comment.  Nesting with mixed parts is allowed.  If 'comments'
+	is "n:),n:>" a line starting with "> ) >" is a comment.
+
+  b	Blank (<Space>, <Tab> or <EOL>) required after {string}.
+
+  f	Only the first line has the comment string.  Do not repeat comment on
+	the next line, but preserve indentation (e.g., a bullet-list).
+
+  s	Start of three-piece comment
+
+  m	Middle of a three-piece comment
+
+  e	End of a three-piece comment
+
+  l	Left adjust middle with start or end (default).  Only recognized when
+	used together with 's' or 'e'.
+
+  r	Right adjust middle with start or end.  Only recognized when used
+	together with 's' or 'e'.
+
+  O	Don't use this one for the "O" command.
+
+  x	Allows three-piece comments to be ended by just typing the last
+	character of the end-comment string as the first character on a new
+	line, when the middle-comment string has already been inserted
+	automatically.  See below for more details.
+
+  {digits}
+	When together with 's' or 'e': add extra indent for the middle part.
+	This can be used to left-align the middle part with the start or end
+	and then add an offset.
+
+  -{digits}
+	Like {digits} but reduce the indent.  This only works when there is
+	some indent for the start or end part that can be removed.
+
+When a string has none of the 'f', 's', 'm' or 'e' flags, Vim assumes the
+comment string repeats at the start of each line.  The flags field may be
+empty.
+
+Any blank space in the text before and after the {string} is part of the
+{string}, so do not include leading or trailing blanks unless the blanks are a
+required part of the comment string.
+
+When one comment leader is part of another, specify the part after the whole.
+For example, to include both "-" and "->", use >
+	:set comments=f:->,f:-
+
+A three-piece comment must always be given as start,middle,end, with no other
+parts in between.  An example of a three-piece comment is >
+	sr:/*,mb:*,ex:*/
+for C-comments.  To avoid recognizing "*ptr" as a comment, the middle string
+includes the 'b' flag.  For three-piece comments, Vim checks the text after
+the start and middle strings for the end string.  If Vim finds the end string,
+the comment does not continue on the next line.  Three-piece comments must
+have a middle string because otherwise Vim can't recognize the middle lines.
+
+Notice the use of the "x" flag in the above three-piece comment definition.
+When you hit Return in a C-comment, Vim will insert the middle comment leader
+for the new line, e.g. " * ".  To close this comment you just have to type "/"
+before typing anything else on the new line.  This will replace the
+middle-comment leader with the end-comment leader, leaving just " */".  There
+is no need to hit BackSpace first.
+
+Examples: >
+   "b:*"	Includes lines starting with "*", but not if the "*" is
+		followed by a non-blank.  This avoids a pointer dereference
+		like "*str" to be recognized as a comment.
+   "n:>"	Includes a line starting with ">", ">>", ">>>", etc.
+   "fb:-"	Format a list that starts with "- ".
+
+By default, "b:#" is included.  This means that a line that starts with
+"#include" is not recognized as a comment line.  But a line that starts with
+"# define" is recognized.  This is a compromise.
+
+Often the alignment can be changed from right alignment to a left alignment
+with an additional space.  For example, for Javadoc comments, this can be
+used (insert a backslash before the space when using ":set"): >
+	s1:/*,mb:*,ex:*/
+Note that an offset is included with start, so that the middle part is left
+aligned with the start and then an offset of one character added.  This makes
+it possible to left align the start and middle for this construction: >
+	/**
+	 * comment
+	 */
+
+{not available when compiled without the |+comments| feature}
+
+							*fo-table*
+You can use the 'formatoptions' option  to influence how Vim formats text.
+'formatoptions' is a string that can contain any of the letters below.  The
+default setting is "tcq".  You can separate the option letters with commas for
+readability.
+
+letter	 meaning when present in 'formatoptions'    ~
+
+t	Auto-wrap text using textwidth
+c	Auto-wrap comments using textwidth, inserting the current comment
+	leader automatically.
+r	Automatically insert the current comment leader after hitting
+	<Enter> in Insert mode.
+o	Automatically insert the current comment leader after hitting 'o' or
+	'O' in Normal mode.
+q	Allow formatting of comments with "gq".
+	Note that formatting will not change blank lines or lines containing
+	only the comment leader.  A new paragraph starts after such a line,
+	or when the comment leader changes.
+w	Trailing white space indicates a paragraph continues in the next line.
+	A line that ends in a non-white character ends a paragraph.
+a	Automatic formatting of paragraphs.  Every time text is inserted or
+	deleted the paragraph will be reformatted.  See |auto-format|.
+	When the 'c' flag is present this only happens for recognized
+	comments.
+n	When formatting text, recognize numbered lists.  This actually uses
+	the 'formatlistpat' option, thus any kind of list can be used.  The
+	indent of the text after the number is used for the next line.  The
+	default is to find a number, optionally be followed by '.', ':', ')',
+	']' or '}'.  Note that 'autoindent' must be set too.  Doesn't work
+	well together with "2".
+	Example: >
+		1. the first item
+		   wraps
+		2. the second item
+2	When formatting text, use the indent of the second line of a paragraph
+	for the rest of the paragraph, instead of the indent of the first
+	line.  This supports paragraphs in which the first line has a
+	different indent than the rest.  Note that 'autoindent' must be set
+	too.  Example: >
+			first line of a paragraph
+		second line of the same paragraph
+		third line.
+v	Vi-compatible auto-wrapping in insert mode: Only break a line at a
+	blank that you have entered during the current insert command.  (Note:
+	this is not 100% Vi compatible.  Vi has some "unexpected features" or
+	bugs in this area.  It uses the screen column instead of the line
+	column.)
+b	Like 'v', but only auto-wrap if you enter a blank at or before
+	the wrap margin.  If the line was longer than 'textwidth' when you
+	started the insert, or you do not enter a blank in the insert before
+	reaching 'textwidth', Vim does not perform auto-wrapping.
+l	Long lines are not broken in insert mode: When a line was longer than
+	'textwidth' when the insert command started, Vim does not
+	automatically format it.
+m	Also break at a multi-byte character above 255.  This is useful for
+	Asian text where every character is a word on its own.
+M	When joining lines, don't insert a space before or after a multi-byte
+	character.  Overrules the 'B' flag.
+B	When joining lines, don't insert a space between two multi-byte
+	characters.  Overruled by the 'M' flag.
+1	Don't break a line after a one-letter word.  It's broken before it
+	instead (if possible).
+
+
+With 't' and 'c' you can specify when Vim performs auto-wrapping:
+value	action	~
+""	no automatic formatting (you can use "gq" for manual formatting)
+"t"	automatic formatting of text, but not comments
+"c"	automatic formatting for comments, but not text (good for C code)
+"tc"	automatic formatting for text and comments
+
+Note that when 'textwidth' is 0, Vim does no automatic formatting anyway (but
+does insert comment leaders according to the 'comments' option).  An exception
+is when the 'a' flag is present. |auto-format|
+
+Note that when 'paste' is on, Vim does no formatting at all.
+
+Note that 'textwidth' can be non-zero even if Vim never performs auto-wrapping;
+'textwidth' is still useful for formatting with "gq".
+
+If the 'comments' option includes "/*", "*" and/or "*/", then Vim has some
+built in stuff to treat these types of comments a bit more cleverly.
+Opening a new line before or after "/*" or "*/" (with 'r' or 'o' present in
+'formatoptions') gives the correct start of the line automatically.  The same
+happens with formatting and auto-wrapping.  Opening a line after a line
+starting with "/*" or "*" and containing "*/", will cause no comment leader to
+be inserted, and the indent of the new line is taken from the line containing
+the start of the comment.
+E.g.:
+    /* ~
+     * Your typical comment. ~
+     */ ~
+    The indent on this line is the same as the start of the above
+    comment.
+
+All of this should be really cool, especially in conjunction with the new
+:autocmd command to prepare different settings for different types of file.
+
+Some examples:
+  for C code (only format comments): >
+	:set fo=croq
+< for Mail/news	(format all, don't start comment with "o" command): >
+	:set fo=tcrq
+<
+
+Automatic formatting					*auto-format*
+
+When the 'a' flag is present in 'formatoptions' text is formatted
+automatically when inserting text or deleting text.  This works nice for
+editing text paragraphs.  A few hints on how to use this:
+
+- You need to properly define paragraphs.  The simplest is paragraphs that are
+  separated by a blank line.  When there is no separating blank line, consider
+  using the 'w' flag and adding a space at the end of each line in the
+  paragraphs except the last one.
+
+- You can set the 'formatoptions' based on the type of file |filetype| or
+  specifically for one file with a |modeline|.
+
+- Set 'formatoptions' to "aw2tq" to make text with indents like this:
+
+	    bla bla foobar bla 
+	bla foobar bla foobar bla
+	    bla bla foobar bla 
+	bla foobar bla bla foobar
+
+- Add the 'c' flag to only auto-format comments.  Useful in source code.
+
+- Set 'textwidth' to the desired width.  If it is zero then 79 is used, or the
+  width of the screen if this is smaller.
+
+And a few warnings:
+
+- When part of the text is not properly separated in paragraphs, making
+  changes in this text will cause it to be formatted anyway.  Consider doing >
+
+	:set fo-=a
+
+- When using the 'w' flag (trailing space means paragraph continues) and
+  deleting the last line of a paragraph with |dd|, the paragraph will be
+  joined with the next one.
+
+- Changed text is saved for undo.  Formatting is also a change.  Thus each
+  format action saves text for undo.  This may consume quite a lot of memory.
+
+- Formatting a long paragraph and/or with complicated indenting may be slow.
+
+==============================================================================
+7. Sorting text						*sorting*
+
+Vim has a sorting function and a sorting command.  The sorting function can be
+found here: |sort()|.
+
+							*:sor* *:sort*
+:[range]sor[t][!] [i][u][r][n][x][o] [/{pattern}/]
+			Sort lines in [range].  When no range is given all
+			lines are sorted.
+
+			With [!] the order is reversed.
+
+			With [i] case is ignored.
+
+			With [n] sorting is done on the first decimal number
+			in the line (after or inside a {pattern} match).
+
+			With [x] sorting is done on the first hexadecimal
+			number in the line (after or inside a {pattern}
+			match).  A leading "0x" or "0X" is ignored.
+
+			With [o] sorting is done on the first octal number in
+			the line (after or inside a {pattern} match).
+
+			With [u] only keep the first of a sequence of
+			identical lines (ignoring case when [i] is used).
+			Without this flag, a sequence of identical lines
+			will be kept in their original order.
+			Note that leading and trailing white space may cause
+			lines to be different.
+
+			When /{pattern}/ is specified and there is no [r] flag
+			the text matched with {pattern} is skipped, so that
+			you sort on what comes after the match.
+			Instead of the slash any non-letter can be used.
+			For example, to sort on the second comma-separated
+			field: >
+				:sort /[^,]*,/
+<			To sort on the text at virtual column 10 (thus
+			ignoring the difference between tabs and spaces): >
+				:sort /.*\%10v/
+<			To sort on the first number in the line, no matter
+			what is in front of it: >
+				:sort /.*\ze\d/
+
+<			With [r] sorting is done on the matching {pattern}
+			instead of skipping past it as described above.
+			For example, to sort on only the first three letters
+			of each line: >
+				:sort /\a\a\a/ r
+
+<			If a {pattern} is used, any lines which don't have a
+			match for {pattern} are kept in their current order,
+			but separate from the lines which do match {pattern}.
+			If you sorted in reverse, they will be in reverse
+			order after the sorted lines, otherwise they will be
+			in their original order, right before the sorted
+			lines.
+
+Note that using ":sort" with ":global" doesn't sort the matching lines, it's
+quite useless.
+
+The details about sorting depend on the library function used.  There is no
+guarantee that sorting is "stable" or obeys the current locale.  You will have
+to try it out.
+
+The sorting can be interrupted, but if you interrupt it too late in the
+process you may end up with duplicated lines.  This also depends on the system
+library function used.
+
+ vim:tw=78:ts=8:ft=help:norl:
--- /dev/null
+++ b/lib/vimfiles/doc/cmdline.txt
@@ -1,0 +1,1052 @@
+*cmdline.txt*   For Vim version 7.1.  Last change: 2006 Jul 18
+
+
+		  VIM REFERENCE MANUAL    by Bram Moolenaar
+
+
+				*Cmdline-mode* *Command-line-mode*
+Command-line mode		*Cmdline* *Command-line* *mode-cmdline* *:*
+
+Command-line mode is used to enter Ex commands (":"), search patterns
+("/" and "?"), and filter commands ("!").
+
+Basic command line editing is explained in chapter 20 of the user manual
+|usr_20.txt|.
+
+1. Command-line editing		|cmdline-editing|
+2. Command-line completion	|cmdline-completion|
+3. Ex command-lines		|cmdline-lines|
+4. Ex command-line ranges	|cmdline-ranges|
+5. Ex command-line flags	|ex-flags|
+6. Ex special characters	|cmdline-special|
+7. Command-line window		|cmdline-window|
+
+==============================================================================
+1. Command-line editing					*cmdline-editing*
+
+Normally characters are inserted in front of the cursor position.  You can
+move around in the command-line with the left and right cursor keys.  With the
+<Insert> key, you can toggle between inserting and overstriking characters.
+{Vi: can only alter the last character in the line}
+
+Note that if your keyboard does not have working cursor keys or any of the
+other special keys, you can use ":cnoremap" to define another key for them.
+For example, to define tcsh style editing keys:		*tcsh-style*  >
+	:cnoremap <C-A> <Home>
+	:cnoremap <C-F> <Right>
+	:cnoremap <C-B> <Left>
+	:cnoremap <Esc>b <S-Left>
+	:cnoremap <Esc>f <S-Right>
+(<> notation |<>|; type all this literally)
+
+							*cmdline-too-long*
+When the command line is getting longer than what fits on the screen, only the
+part that fits will be shown.  The cursor can only move in this visible part,
+thus you cannot edit beyond that.
+
+						*cmdline-history* *history*
+The command-lines that you enter are remembered in a history table.  You can
+recall them with the up and down cursor keys.  There are actually five
+history tables:
+- one for ':' commands
+- one for search strings
+- one for expressions
+- one for input lines, typed for the |input()| function.
+- one for debug mode commands
+These are completely separate.  Each history can only be accessed when
+entering the same type of line.
+Use the 'history' option to set the number of lines that are remembered
+(default: 20).
+Notes:
+- When you enter a command-line that is exactly the same as an older one, the
+  old one is removed (to avoid repeated commands moving older commands out of
+  the history).
+- Only commands that are typed are remembered.  Ones that completely come from
+  mappings are not put in the history
+- All searches are put in the search history, including the ones that come
+  from commands like "*" and "#".  But for a mapping, only the last search is
+  remembered (to avoid that long mappings trash the history).
+{Vi: no history}
+{not available when compiled without the |+cmdline_hist| feature}
+
+There is an automatic completion of names on the command-line; see
+|cmdline-completion|.
+
+							*c_CTRL-V*
+CTRL-V		Insert next non-digit literally.  Up to three digits form the
+		decimal value of a single byte.  The non-digit and the three
+		digits are not considered for mapping.  This works the same
+		way as in Insert mode (see above, |i_CTRL-V|).
+		Note: Under Windows CTRL-V is often mapped to paste text.
+		Use CTRL-Q instead then.
+							*c_CTRL-Q*
+CTRL-Q		Same as CTRL-V.  But with some terminals it is used for
+		control flow, it doesn't work then.
+
+							*c_<Left>*
+<Left>		cursor left
+							*c_<Right>*
+<Right>		cursor right
+							*c_<S-Left>*
+<S-Left> or <C-Left>					*c_<C-Left>*
+		cursor one WORD left
+							*c_<S-Right>*
+<S-Right> or <C-Right>					*c_<C-Right>*
+		cursor one WORD right
+CTRL-B or <Home>					*c_CTRL-B* *c_<Home>*
+		cursor to beginning of command-line
+CTRL-E or <End>						*c_CTRL-E* *c_<End>*
+		cursor to end of command-line
+
+							*c_<LeftMouse>*
+<LeftMouse>	cursor to position of mouse click.
+
+CTRL-H							*c_<BS>* *c_CTRL-H*
+<BS>		delete the character in front of the cursor (see |:fixdel| if
+		your <BS> key does not do what you want).
+							*c_<Del>*
+<Del>		delete the character under the cursor (at end of line:
+		character before the cursor) (see |:fixdel| if your <Del>
+		key does not do what you want).
+							*c_CTRL-W*
+CTRL-W		delete the word before the cursor
+							*c_CTRL-U*
+CTRL-U		remove all characters between the cursor position and
+		the beginning of the line.  Previous versions of vim
+		deleted all characters on the line.  If that is the
+		preferred behavior, add the following to your .vimrc: >
+			:cnoremap <C-U> <C-E><C-U>
+<
+		Note: if the command-line becomes empty with one of the
+		delete commands, Command-line mode is quit.
+							*c_<Insert>*
+<Insert>	Toggle between insert and overstrike.  {not in Vi}
+
+{char1} <BS> {char2}	or				*c_digraph*
+CTRL-K {char1} {char2}					*c_CTRL-K*
+		enter digraph (see |digraphs|).  When {char1} is a special
+		key, the code for that key is inserted in <> form.  {not in Vi}
+
+CTRL-R {0-9a-z"%#:-=.}					*c_CTRL-R* *c_<C-R>*
+		Insert the contents of a numbered or named register.  Between
+		typing CTRL-R and the second character '"' will be displayed
+		to indicate that you are expected to enter the name of a
+		register.
+		The text is inserted as if you typed it, but mappings and
+		abbreviations are not used.  Command-line completion through
+		'wildchar' is not triggered though.  And characters that end
+		the command line are inserted literally (<Esc>, <CR>, <NL>,
+		<C-C>).  A <BS> or CTRL-W could still end the command line
+		though, and remaining characters will then be interpreted in
+		another mode, which might not be what you intended.
+		Special registers:
+			'"'	the unnamed register, containing the text of
+				the last delete or yank
+			'%'	the current file name
+			'#'	the alternate file name
+			'*'	the clipboard contents (X11: primary selection)
+			'+'	the clipboard contents
+			'/'	the last search pattern
+			':'	the last command-line
+			'-'	the last small (less than a line) delete
+			'.'	the last inserted text
+							*c_CTRL-R_=*
+			'='	the expression register: you are prompted to
+				enter an expression (see |expression|)
+				(doesn't work at the expression prompt; some
+				things such as changing the buffer or current
+				window are not allowed to avoid side effects)
+		See |registers| about registers.  {not in Vi}
+		Implementation detail: When using the |expression| register
+		and invoking setcmdpos(), this sets the position before
+		inserting the resulting string.  Use CTRL-R CTRL-R to set the
+		position afterwards.
+
+CTRL-R CTRL-F				*c_CTRL-R_CTRL-F* *c_<C-R>_<C-F>*
+CTRL-R CTRL-P				*c_CTRL-R_CTRL-P* *c_<C-R>_<C-P>*
+CTRL-R CTRL-W				*c_CTRL-R_CTRL-W* *c_<C-R>_<C-W>*
+CTRL-R CTRL-A				*c_CTRL-R_CTRL-A* *c_<C-R>_<C-A>*
+		Insert the object under the cursor:
+			CTRL-F	the Filename under the cursor
+			CTRL-P	the Filename under the cursor, expanded with
+				'path' as in |gf|
+			CTRL-W	the Word under the cursor
+			CTRL-A	the WORD under the cursor; see |WORD|
+
+		When 'incsearch' is set the cursor position at the end of the
+		currently displayed match is used.  With CTRL-W the part of
+		the word that was already typed is not inserted again.
+
+		{not in Vi}
+		CTRL-F and CTRL-P: {only when +file_in_path feature is
+		included}
+
+					*c_CTRL-R_CTRL-R* *c_<C-R>_<C-R>*
+					*c_CTRL-R_CTRL-O* *c_<C-R>_<C-O>*
+CTRL-R CTRL-R {0-9a-z"%#:-=. CTRL-F CTRL-P CTRL-W CTRL-A}
+CTRL-R CTRL-O {0-9a-z"%#:-=. CTRL-F CTRL-P CTRL-W CTRL-A}
+		Insert register or object under the cursor.  Works like
+		|c_CTRL-R| but inserts the text literally.  For example, if
+		register a contains "xy^Hz" (where ^H is a backspace),
+		"CTRL-R a" will insert "xz" while "CTRL-R CTRL-R a" will
+		insert "xy^Hz".
+
+CTRL-\ e {expr}						*c_CTRL-\_e*
+		Evaluate {expr} and replace the whole command line with the
+		result.  You will be prompted for the expression, type <Enter>
+		to finish it.  It's most useful in mappings though.  See
+		|expression|.
+		See |c_CTRL-R_=| for inserting the result of an expression.
+		Useful functions are |getcmdtype()|, |getcmdline()| and
+		|getcmdpos()|.
+		The cursor position is unchanged, except when the cursor was
+		at the end of the line, then it stays at the end.
+		|setcmdpos()| can be used to set the cursor position.
+		The |sandbox| is used for evaluating the expression to avoid
+		nasty side effects.
+		Example: >
+			:cmap <F7> <C-\>eAppendSome()<CR>
+			:func AppendSome()
+			   :let cmd = getcmdline() . " Some()"
+			   :" place the cursor on the )
+			   :call setcmdpos(strlen(cmd))
+			   :return cmd
+			:endfunc
+<		This doesn't work recursively, thus not when already editing
+		an expression.
+
+							*c_CTRL-Y*
+CTRL-Y		When there is a modeless selection, copy the selection into
+		the clipboard. |modeless-selection|
+		If there is no selection CTRL-Y is inserted as a character.
+
+CTRL-J						*c_CTRL-J* *c_<NL>* *c_<CR>*
+<CR> or <NL>	start entered command
+							*c_<Esc>*
+<Esc>		When typed and 'x' not present in 'cpoptions', quit
+		Command-line mode without executing.  In macros or when 'x'
+		present in 'cpoptions', start entered command.
+							*c_CTRL-C*
+CTRL-C		quit command-line without executing
+
+							*c_<Up>*
+<Up>		recall older command-line from history, whose beginning
+		matches the current command-line (see below).
+		{not available when compiled without the |+cmdline_hist|
+		feature}
+							*c_<Down>*
+<Down>		recall more recent command-line from history, whose beginning
+		matches the current command-line (see below).
+		{not available when compiled without the |+cmdline_hist|
+		feature}
+
+							*c_<S-Up>* *c_<PageUp>*
+<S-Up> or <PageUp>
+		recall older command-line from history
+		{not available when compiled without the |+cmdline_hist|
+		feature}
+						*c_<S-Down>* *c_<PageDown>*
+<S-Down> or <PageDown>
+		recall more recent command-line from history
+		{not available when compiled without the |+cmdline_hist|
+		feature}
+
+CTRL-D		command-line completion (see |cmdline-completion|)
+'wildchar' option
+		command-line completion (see |cmdline-completion|)
+CTRL-N		command-line completion (see |cmdline-completion|)
+CTRL-P		command-line completion (see |cmdline-completion|)
+CTRL-A		command-line completion (see |cmdline-completion|)
+CTRL-L		command-line completion (see |cmdline-completion|)
+
+							*c_CTRL-_*
+CTRL-_		a - switch between Hebrew and English keyboard mode, which is
+		private to the command-line and not related to hkmap.
+		This is useful when Hebrew text entry is required in the
+		command-line, searches, abbreviations, etc.  Applies only if
+		Vim is compiled with the |+rightleft| feature and the
+		'allowrevins' option is set.
+		See |rileft.txt|.
+
+		b - switch between Farsi and English keyboard mode, which is
+		private to the command-line and not related to fkmap.  In
+		Farsi keyboard mode the characters are inserted in reverse
+		insert manner.  This is useful when Farsi text entry is
+		required in the command-line, searches, abbreviations, etc.
+		Applies only if Vim is compiled with the |+farsi| feature.
+		See |farsi.txt|.
+
+							*c_CTRL-^*
+CTRL-^		Toggle the use of language |:lmap| mappings and/or Input
+		Method.
+		When typing a pattern for a search command and 'imsearch' is
+		not -1, VAL is the value of 'imsearch', otherwise VAL is the
+		value of 'iminsert'.
+		When language mappings are defined:
+		- If VAL is 1 (langmap mappings used) it becomes 0 (no langmap
+		  mappings used).
+		- If VAL was not 1 it becomes 1, thus langmap mappings are
+		  enabled.
+		When no language mappings are defined:
+		- If VAL is 2 (Input Method is used) it becomes 0 (no input
+		  method used)
+		- If VAL has another value it becomes 2, thus the Input Method
+		  is enabled.
+		These language mappings are normally used to type characters
+		that are different from what the keyboard produces.  The
+		'keymap' option can be used to install a whole number of them.
+		When entering a command line, langmap mappings are switched
+		off, since you are expected to type a command.  After
+		switching it on with CTRL-^, the new state is not used again
+		for the next command or Search pattern.
+		{not in Vi}
+
+						*c_CTRL-]*
+CTRL-]		Trigger abbreviation, without inserting a character.  {not in
+		Vi}
+
+For Emacs-style editing on the command-line see |emacs-keys|.
+
+The <Up> and <Down> keys take the current command-line as a search string.
+The beginning of the next/previous command-lines are compared with this
+string.  The first line that matches is the new command-line.  When typing
+these two keys repeatedly, the same string is used again.  For example, this
+can be used to find the previous substitute command: Type ":s" and then <Up>.
+The same could be done by typing <S-Up> a number of times until the desired
+command-line is shown.  (Note: the shifted arrow keys do not work on all
+terminals)
+
+							*his* *:history*
+:his[tory]	Print the history of last entered commands.
+		{not in Vi}
+		{not available when compiled without the |+cmdline_hist|
+		feature}
+
+:his[tory] [{name}] [{first}][, [{last}]]
+		List the contents of history {name} which can be:
+		c[md]	 or :	command-line history
+		s[earch] or /	search string history
+		e[xpr]	 or =	expression register history
+		i[nput]	 or @	input line history
+		d[ebug]	 or >	debug command history
+		a[ll]		all of the above
+		{not in Vi}
+
+		If the numbers {first} and/or {last} are given, the respective
+		range of entries from a history is listed.  These numbers can
+		be specified in the following form:
+							*:history-indexing*
+		A positive number represents the absolute index of an entry
+		as it is given in the first column of a :history listing.
+		This number remains fixed even if other entries are deleted.
+
+		A negative number means the relative position of an entry,
+		counted from the newest entry (which has index -1) backwards.
+
+		Examples:
+		List entries 6 to 12 from the search history: >
+			:history / 6,12
+<
+		List the recent five entries from all histories: >
+			:history all -5,
+
+==============================================================================
+2. Command-line completion				*cmdline-completion*
+
+When editing the command-line, a few commands can be used to complete the
+word before the cursor.  This is available for:
+
+- Command names: At the start of the command-line.
+- Tags: Only after the ":tag" command.
+- File names: Only after a command that accepts a file name or a setting for
+  an option that can be set to a file name.  This is called file name
+  completion.
+- Shell command names: After ":!cmd", ":r !cmd" and ":w !cmd".  $PATH is used.
+- Options: Only after the ":set" command.
+- Mappings: Only after a ":map" or similar command.
+- Variable and function names: Only after a ":if", ":call" or similar command.
+
+When Vim was compiled with the |+cmdline_compl| feature disabled, only file
+names, directories and help items can be completed.
+
+These are the commands that can be used:
+
+							*c_CTRL-D*
+CTRL-D		List names that match the pattern in front of the cursor.
+		When showing file names, directories are highlighted (see
+		'highlight' option).  Names where 'suffixes' matches are moved
+		to the end.
+		The 'wildoptions' option can be set to "tagfile" to list the
+		file of matching tags.
+					*c_CTRL-I* *c_wildchar* *c_<Tab>*
+'wildchar' option
+		A match is done on the pattern in front of the cursor.  The
+		match (if there are several, the first match) is inserted
+		in place of the pattern.  (Note: does not work inside a
+		macro, because <Tab> or <Esc> are mostly used as 'wildchar',
+		and these have a special meaning in some macros.) When typed
+		again and there were multiple matches, the next
+		match is inserted.  After the last match, the first is used
+		again (wrap around).
+		The behavior can be changed with the 'wildmode' option.
+							*c_CTRL-N*
+CTRL-N		After using 'wildchar' which got multiple matches, go to next
+		match.  Otherwise recall more recent command-line from history.
+<S-Tab>							*c_CTRL-P* *c_<S-Tab>*
+CTRL-P		After using 'wildchar' which got multiple matches, go to
+		previous match.  Otherwise recall older command-line from
+		history.  <S-Tab> only works with the GUI, on the Amiga and
+		with MS-DOS.
+							*c_CTRL-A*
+CTRL-A		All names that match the pattern in front of the cursor are
+		inserted.
+							*c_CTRL-L*
+CTRL-L		A match is done on the pattern in front of the cursor.  If
+		there is one match, it is inserted in place of the pattern.
+		If there are multiple matches the longest common part is
+		inserted in place of the pattern.  If the result is shorter
+		than the pattern, no completion is done.
+		When 'incsearch' is set, entering a search pattern for "/" or
+		"?" and the current match is displayed then CTRL-L will add
+		one character from the end of the current match.
+
+The 'wildchar' option defaults to <Tab> (CTRL-E when in Vi compatible mode; in
+a previous version <Esc> was used).  In the pattern standard wildcards '*' and
+'?' are accepted.  '*' matches any string, '?' matches exactly one character.
+
+If you like tcsh's autolist completion, you can use this mapping:
+	:cnoremap X <C-L><C-D>
+(Where X is the command key to use, <C-L> is CTRL-L and <C-D> is CTRL-D)
+This will find the longest match and then list all matching files.
+
+If you like tcsh's autolist completion, you can use the 'wildmode' option to
+emulate it.  For example, this mimics autolist=ambiguous:
+	:set wildmode=longest,list
+This will find the longest match with the first 'wildchar', then list all
+matching files with the next.
+
+							*suffixes*
+For file name completion you can use the 'suffixes' option to set a priority
+between files with almost the same name.  If there are multiple matches,
+those files with an extension that is in the 'suffixes' option are ignored.
+The default is ".bak,~,.o,.h,.info,.swp,.obj", which means that files ending
+in ".bak", "~", ".o", ".h", ".info", ".swp" and ".obj" are sometimes ignored.
+It is impossible to ignore suffixes with two dots.  Examples:
+
+  pattern:	files:				match:	~
+   test*	test.c test.h test.o		test.c
+   test*	test.h test.o			test.h and test.o
+   test*	test.i test.h test.c		test.i and test.c
+
+If there is more than one matching file (after ignoring the ones matching
+the 'suffixes' option) the first file name is inserted.  You can see that
+there is only one match when you type 'wildchar' twice and the completed
+match stays the same.  You can get to the other matches by entering
+'wildchar', CTRL-N or CTRL-P.  All files are included, also the ones with
+extensions matching the 'suffixes' option.
+
+To completely ignore files with some extension use 'wildignore'.
+
+The old value of an option can be obtained by hitting 'wildchar' just after
+the '='.  For example, typing 'wildchar' after ":set dir=" will insert the
+current value of 'dir'.  This overrules file name completion for the options
+that take a file name.
+
+If you would like using <S-Tab> for CTRL-P in an xterm, put this command in
+your .cshrc: >
+	xmodmap -e "keysym Tab = Tab Find"
+And this in your .vimrc: >
+	:cmap <Esc>[1~ <C-P>
+
+==============================================================================
+3. Ex command-lines					*cmdline-lines*
+
+The Ex commands have a few specialties:
+
+							*:quote*
+'"' at the start of a line causes the whole line to be ignored.  '"'
+after a command causes the rest of the line to be ignored.  This can be used
+to add comments.  Example: >
+	:set ai		"set 'autoindent' option
+It is not possible to add a comment to a shell command ":!cmd" or to the
+":map" command and friends, because they see the '"' as part of their
+argument.
+
+							*:bar* *:\bar*
+'|' can be used to separate commands, so you can give multiple commands in one
+line.  If you want to use '|' in an argument, precede it with '\'.
+
+These commands see the '|' as their argument, and can therefore not be
+followed by another command:
+    :argdo
+    :autocmd
+    :bufdo
+    :command
+    :cscope
+    :debug
+    :folddoopen
+    :folddoclosed
+    :function
+    :global
+    :help
+    :helpfind
+    :lcscope
+    :make
+    :normal
+    :perl
+    :perldo
+    :promptfind
+    :promptrepl
+    :pyfile
+    :python
+    :registers
+    :read !
+    :scscope
+    :tcl
+    :tcldo
+    :tclfile
+    :vglobal
+    :windo
+    :write !
+    :[range]!
+    a user defined command without the "-bar" argument |:command|
+
+Note that this is confusing (inherited from Vi): With ":g" the '|' is included
+in the command, with ":s" it is not.
+
+To be able to use another command anyway, use the ":execute" command.
+Example (append the output of "ls" and jump to the first line): >
+	:execute 'r !ls' | '[
+
+There is one exception: When the 'b' flag is present in 'cpoptions', with the
+":map" and ":abbr" commands and friends CTRL-V needs to be used instead of
+'\'.  You can also use "<Bar>" instead.  See also |map_bar|.
+
+Examples: >
+	:!ls | wc		view the output of two commands
+	:r !ls | wc		insert the same output in the text
+	:%g/foo/p|>		moves all matching lines one shiftwidth
+	:%s/foo/bar/|>		moves one line one shiftwidth
+	:map q 10^V|		map "q" to "10|"
+	:map q 10\| map \ l	map "q" to "10\" and map "\" to "l"
+					(when 'b' is present in 'cpoptions')
+
+You can also use <NL> to separate commands in the same way as with '|'.  To
+insert a <NL> use CTRL-V CTRL-J.  "^@" will be shown.  Using '|' is the
+preferred method.  But for external commands a <NL> must be used, because a
+'|' is included in the external command.  To avoid the special meaning of <NL>
+it must be preceded with a backslash.  Example: >
+	:r !date<NL>-join
+This reads the current date into the file and joins it with the previous line.
+
+Note that when the command before the '|' generates an error, the following
+commands will not be executed.
+
+
+Because of Vi compatibility the following strange commands are supported: >
+	:|			print current line (like ":p")
+	:3|			print line 3 (like ":3p")
+	:3			goto line 3
+
+A colon is allowed between the range and the command name.  It is ignored
+(this is Vi compatible).  For example: >
+	:1,$:s/pat/string
+
+When the character '%' or '#' is used where a file name is expected, they are
+expanded to the current and alternate file name (see the chapter "editing
+files" |:_%| |:_#|).
+
+Embedded spaces in file names are allowed on the Amiga if one file name is
+expected as argument.  Trailing spaces will be ignored, unless escaped with a
+backslash or CTRL-V.  Note that the ":next" command uses spaces to separate
+file names.  Escape the spaces to include them in a file name.  Example: >
+	:next foo\ bar goes\ to school\
+starts editing the three files "foo bar", "goes to" and "school ".
+
+When you want to use the special characters '"' or '|' in a command, or want
+to use '%' or '#' in a file name, precede them with a backslash.  The
+backslash is not required in a range and in the ":substitute" command.
+
+							*:_!*
+The '!' (bang) character after an Ex command makes the command behave in a
+different way.  The '!' should be placed immediately after the command, without
+any blanks in between.  If you insert blanks the '!' will be seen as an
+argument for the command, which has a different meaning.  For example:
+	:w! name	write the current buffer to file "name", overwriting
+			any existing file
+	:w !name	send the current buffer as standard input to command
+			"name"
+
+==============================================================================
+4. Ex command-line ranges	*cmdline-ranges* *[range]* *E16*
+
+Some Ex commands accept a line range in front of them.  This is noted as
+[range].  It consists of one or more line specifiers, separated with ',' or
+';'.
+
+The basics are explained in section |10.3| of the user manual.
+
+						*:,* *:;*
+When separated with ';' the cursor position will be set to that line
+before interpreting the next line specifier.  This doesn't happen for ','.
+Examples: >
+   4,/this line/
+<	from line 4 till match with "this line" after the cursor line. >
+   5;/that line/
+<	from line 5 till match with "that line" after line 5.
+
+The default line specifier for most commands is the cursor position, but the
+commands ":write" and ":global" have the whole file (1,$) as default.
+
+If more line specifiers are given than required for the command, the first
+one(s) will be ignored.
+
+Line numbers may be specified with:		*:range* *E14* *{address}*
+	{number}	an absolute line number
+	.		the current line			  *:.*
+	$		the last line in the file		  *:$*
+	%		equal to 1,$ (the entire file)		  *:%*
+	't		position of mark t (lowercase)		  *:'*
+	'T		position of mark T (uppercase); when the mark is in
+			another file it cannot be used in a range
+	/{pattern}[/]	the next line where {pattern} matches	  *:/*
+	?{pattern}[?]	the previous line where {pattern} matches *:?*
+	\/		the next line where the previously used search
+			pattern matches
+	\?		the previous line where the previously used search
+			pattern matches
+	\&		the next line where the previously used substitute
+			pattern matches
+
+Each may be followed (several times) by '+' or '-' and an optional number.
+This number is added or subtracted from the preceding line number.  If the
+number is omitted, 1 is used.
+
+The "/" and "?" after {pattern} are required to separate the pattern from
+anything that follows.
+
+The "/" and "?" may be preceded with another address.  The search starts from
+there.  The difference from using ';' is that the cursor isn't moved.
+Examples: >
+	/pat1//pat2/	Find line containing "pat2" after line containing
+			"pat1", without moving the cursor.
+	7;/pat2/	Find line containing "pat2", after line 7, leaving
+			the cursor in line 7.
+
+The {number} must be between 0 and the number of lines in the file.  When
+using a 0 (zero) this is interpreted as a 1 by most commands.  Commands that
+use it as a count do use it as a zero (|:tag|, |:pop|, etc).  Some commands
+interpret the zero as "before the first line" (|:read|, search pattern, etc).
+
+Examples: >
+	.+3		three lines below the cursor
+	/that/+1	the line below the next line containing "that"
+	.,$		from current line until end of file
+	0;/that		the first line containing "that", also matches in the
+			first line.
+	1;/that		the first line after line 1 containing "that"
+
+Some commands allow for a count after the command.  This count is used as the
+number of lines to be used, starting with the line given in the last line
+specifier (the default is the cursor line).  The commands that accept a count
+are the ones that use a range but do not have a file name argument (because
+a file name can also be a number).
+
+Examples: >
+	:s/x/X/g 5	substitute 'x' by 'X' in the current line and four
+			following lines
+	:23d 4		delete lines 23, 24, 25 and 26
+
+
+Folds and Range
+
+When folds are active the line numbers are rounded off to include the whole
+closed fold.  See |fold-behavior|.
+
+
+Reverse Range						*E493*
+
+A range should have the lower line number first.  If this is not the case, Vim
+will ask you if it should swap the line numbers.
+	Backwards range given, OK to swap ~
+This is not done within the global command ":g".
+
+You can use ":silent" before a command to avoid the question, the range will
+always be swapped then.
+
+
+Count and Range						*N:*
+
+When giving a count before entering ":", this is translated into:
+		:.,.+(count - 1)
+In words: The 'count' lines at and after the cursor.  Example: To delete
+three lines: >
+		3:d<CR>		is translated into: .,.+2d<CR>
+<
+
+Visual Mode and Range					*v_:*
+
+{Visual}:	Starts a command-line with the Visual selected lines as a
+		range.  The code ":'<,'>" is used for this range, which makes
+		it possible to select a similar line from the command-line
+		history for repeating a command on different Visually selected
+		lines.
+
+==============================================================================
+5. Ex command-line flags				*ex-flags*
+
+These flags are supported by a selection of Ex commands.  They print the line
+that the cursor ends up after executing the command:
+
+	l	output like for |:list|
+	#	add line number
+	p	output like for |:print|
+
+The flags can be combined, thus "l#" uses both a line number and |:list| style
+output.
+
+==============================================================================
+6. Ex special characters				*cmdline-special*
+
+Note: These are special characters in the executed command line.  If you want
+to insert special things while typing you can use the CTRL-R command.  For
+example, "%" stands for the current file name, while CTRL-R % inserts the
+current file name right away.  See |c_CTRL-R|.
+
+
+In Ex commands, at places where a file name can be used, the following
+characters have a special meaning.  These can also be used in the expression
+function expand() |expand()|.
+	%	is replaced with the current file name			*:_%*
+	#	is replaced with the alternate file name		*:_#*
+	#n	(where n is a number) is replaced with the file name of
+		buffer n.  "#0" is the same as "#"
+	##	is replaced with all names in the argument list		*:_##*
+		concatenated, separated by spaces.  Each space in a name
+		is preceded with a backslash.
+Note that these give the file name as it was typed.  If an absolute path is
+needed (when using the file name from a different directory), you need to add
+":p".  See |filename-modifiers|.
+Note that backslashes are inserted before spaces, so that the command will
+correctly interpret the file name.  But this doesn't happen for shell
+commands.  For those you probably have to use quotes: >
+	:!ls "%"
+	:r !spell "%"
+
+To avoid the special meaning of '%' and '#' insert a backslash before it.
+Detail: The special meaning is always escaped when there is a backslash before
+it, no matter how many backslashes.
+	you type:		result	~
+	   #			alternate.file
+	   \#			#
+	   \\#			\#
+
+			       *:<cword>* *:<cWORD>* *:<cfile>* *<cfile>*
+			       *:<sfile>* *<sfile>* *:<afile>* *<afile>*
+			       *:<abuf>* *<abuf>* *:<amatch>* *<amatch>*
+			       *E495* *E496* *E497* *E498* *E499* *E500*
+Note: these are typed literally, they are not special keys!
+	<cword>    is replaced with the word under the cursor (like |star|)
+	<cWORD>    is replaced with the WORD under the cursor (see |WORD|)
+	<cfile>    is replaced with the path name under the cursor (like what
+		   |gf| uses)
+	<afile>    when executing autocommands, is replaced with the file name
+		   for a file read or write
+	<abuf>     when executing autocommands, is replaced with the currently
+		   effective buffer number (for ":r file" and ":so file" it is
+		   the current buffer, the file being read/sourced is not in a
+		   buffer).
+	<amatch>   when executing autocommands, is replaced with the match for
+		   which this autocommand was executed.  It differs from
+		   <afile> only when the file name isn't used to match with
+		   (for FileType, Syntax and SpellFileMissing events).
+	<sfile>    when executing a ":source" command, is replaced with the
+		   file name of the sourced file;
+		   when executing a function, is replaced with
+		   "function {function-name}"; function call nesting is
+		   indicated like this:
+		   "function {function-name1}..{function-name2}".  Note that
+		   filename-modifiers are useless when <sfile> is used inside
+		   a function.
+
+							 *filename-modifiers*
+	 *:_%:* *::8* *::p* *::.* *::~* *::h* *::t* *::r* *::e* *::s* *::gs*
+The file name modifiers can be used after "%", "#", "#n", "<cfile>", "<sfile>",
+"<afile>" or "<abuf>".  They are also used with the |fnamemodify()| function.
+These are not available when Vim has been compiled without the |+modify_fname|
+feature.
+These modifiers can be given, in this order:
+	:p	Make file name a full path.  Must be the first modifier.  Also
+		changes "~/" (and "~user/" for Unix and VMS) to the path for
+		the home directory.  If the name is a directory a path
+		separator is added at the end.  For a file name that does not
+		exist and does not have an absolute path the result is
+		unpredictable.
+	:8	Converts the path to 8.3 short format (currently only on
+		win32).  Will act on as much of a path that is an existing
+		path.
+	:~	Reduce file name to be relative to the home directory, if
+		possible.  File name is unmodified if it is not below the home
+		directory.
+	:.	Reduce file name to be relative to current directory, if
+		possible.  File name is unmodified if it is not below the
+		current directory.
+		For maximum shortness, use ":~:.".
+	:h	Head of the file name (the last component and any separators
+		removed).  Cannot be used with :e, :r or :t.
+		Can be repeated to remove several components at the end.
+		When the file name ends in a path separator, only the path
+		separator is removed.  Thus ":p:h" on a directory name results
+		on the directory name itself (without trailing slash).
+		When the file name is an absolute path (starts with "/" for
+		Unix; "x:\" for MS-DOS, WIN32, OS/2; "drive:" for Amiga), that
+		part is not removed.  When there is no head (path is relative
+		to current directory) the result is empty.
+	:t	Tail of the file name (last component of the name).  Must
+		precede any :r or :e.
+	:r	Root of the file name (the last extension removed).  When
+		there is only an extension (file name that starts with '.',
+		e.g., ".vimrc"), it is not removed.  Can be repeated to remove
+		several extensions (last one first).
+	:e	Extension of the file name.  Only makes sense when used alone.
+		When there is no extension the result is empty.
+		When there is only an extension (file name that starts with
+		'.'), the result is empty.  Can be repeated to include more
+		extensions.  If there are not enough extensions (but at least
+		one) as much as possible are included.
+	:s?pat?sub?
+		Substitute the first occurrence of "pat" with "sub".  This
+		works like the |:s| command.  "pat" is a regular expression.
+		Any character can be used for '?', but it must not occur in
+		"pat" or "sub".
+		After this, the previous modifiers can be used again.  For
+		example ":p", to make a full path after the substitution.
+	:gs?pat?sub?
+		Substitute all occurrences of "path" with "sub".  Otherwise
+		this works like ":s".
+
+Examples, when the file name is "src/version.c", current dir
+"/home/mool/vim": >
+  :p			/home/mool/vim/src/version.c
+  :p:.				       src/version.c
+  :p:~				 ~/vim/src/version.c
+  :h				       src
+  :p:h			/home/mool/vim/src
+  :p:h:h		/home/mool/vim
+  :t					   version.c
+  :p:t					   version.c
+  :r				       src/version
+  :p:r			/home/mool/vim/src/version
+  :t:r					   version
+  :e						   c
+  :s?version?main?		       src/main.c
+  :s?version?main?:p	/home/mool/vim/src/main.c
+  :p:gs?/?\\?		\home\mool\vim\src\version.c
+
+Examples, when the file name is "src/version.c.gz": >
+  :p			/home/mool/vim/src/version.c.gz
+  :e						     gz
+  :e:e						   c.gz
+  :e:e:e					   c.gz
+  :e:e:r					   c
+  :r				       src/version.c
+  :r:e						   c
+  :r:r				       src/version
+  :r:r:r			       src/version
+<
+					*extension-removal* *:_%<*
+If a "<" is appended to "%", "#", "#n" or "CTRL-V p" the extension of the file
+name is removed (everything after and including the last '.' in the file
+name).  This is included for backwards compatibility with version 3.0, the
+":r" form is preferred.  Examples: >
+
+	%		current file name
+	%<		current file name without extension
+	#		alternate file name for current window
+	#<		idem, without extension
+	#31		alternate file number 31
+	#31<		idem, without extension
+	<cword>		word under the cursor
+	<cWORD>		WORD under the cursor (see |WORD|)
+	<cfile>		path name under the cursor
+	<cfile><	idem, without extension
+
+Note: Where a file name is expected wildcards expansion is done.  On Unix the
+shell is used for this, unless it can be done internally (for speed).
+Backticks also work, like in >
+	:n `echo *.c`
+(backtick expansion is not possible in |restricted-mode|)
+But expansion is only done if there are any wildcards before expanding the
+'%', '#', etc..  This avoids expanding wildcards inside a file name.  If you
+want to expand the result of <cfile>, add a wildcard character to it.
+Examples: (alternate file name is "?readme?")
+	command		expands to  ~
+	:e #		:e ?readme?
+	:e `ls #`	:e {files matching "?readme?"}
+	:e #.*		:e {files matching "?readme?.*"}
+	:cd <cfile>	:cd {file name under cursor}
+	:cd <cfile>*	:cd {file name under cursor plus "*" and then expanded}
+
+When the expanded argument contains a "!" and it is used for a shell command
+(":!cmd", ":r !cmd" or ":w !cmd"), it is escaped with a backslash to avoid it
+being expanded into a previously used command.  When the 'shell' option
+contains "sh", this is done twice, to avoid the shell trying to expand the
+"!".
+
+							*filename-backslash*
+For filesystems that use a backslash as directory separator (MS-DOS, Windows,
+OS/2), it's a bit difficult to recognize a backslash that is used to escape
+the special meaning of the next character.  The general rule is: If the
+backslash is followed by a normal file name character, it does not have a
+special meaning.  Therefore "\file\foo" is a valid file name, you don't have
+to type the backslash twice.
+
+An exception is the '$' sign.  It is a valid character in a file name.  But
+to avoid a file name like "$home" to be interpreted as an environment variable,
+it needs to be preceded by a backslash.  Therefore you need to use "/\$home"
+for the file "$home" in the root directory.  A few examples:
+
+	FILE NAME	INTERPRETED AS	~
+	$home		expanded to value of environment var $home
+	\$home		file "$home" in current directory
+	/\$home		file "$home" in root directory
+	\\$home		file "\\", followed by expanded $home
+
+==============================================================================
+6. Command-line window				*cmdline-window* *cmdwin*
+
+In the command-line window the command line can be edited just like editing
+text in any window.  It is a special kind of window, because you cannot leave
+it in a normal way.
+{not available when compiled without the |+cmdline_hist| or |+vertsplit|
+feature}
+
+
+OPEN
+
+There are two ways to open the command-line window:
+1. From Command-line mode, use the key specified with the 'cedit' option.
+   The default is CTRL-F when 'compatible' is not set.
+2. From Normal mode, use the "q:", "q/" or "q?" command.  *q:* *q/* *q?*
+   This starts editing an Ex command-line ("q:") or search string ("q/" or
+   "q?").  Note that this is not possible while recording is in progress (the
+   "q" stops recording then).
+
+When the window opens it is filled with the command-line history.  The last
+line contains the command as typed so far.  The left column will show a
+character that indicates the type of command-line being edited, see
+|cmdwin-char|.
+
+Vim will be in Normal mode when the editor is opened, except when 'insertmode'
+is set.
+
+The height of the window is specified with 'cmdwinheight' (or smaller if there
+is no room).  The window is always full width and is positioned just above the
+command-line.
+
+
+EDIT
+
+You can now use commands to move around and edit the text in the window.  Both
+in Normal mode and Insert mode.
+
+It is possible to use ":", "/" and other commands that use the command-line,
+but it's not possible to open another command-line window then.  There is no
+nesting.
+							*E11*
+The command-line window is not a normal window.  It is not possible to move to
+another window or edit another buffer.  All commands that would do this are
+disabled in the command-line window.  Of course it _is_ possible to execute
+any command that you entered in the command-line window.
+
+
+CLOSE							*E199*
+
+There are several ways to leave the command-line window:
+
+<CR>		Execute the command-line under the cursor.  Works both in
+		Insert and in Normal mode.
+CTRL-C		Continue in Command-line mode.  The command-line under the
+		cursor is used as the command-line.  Works both in Insert and
+		in Normal mode.  ":close" also works.  There is no redraw,
+		thus the window will remain visible.
+:quit		Discard the command line and go back to Normal mode.
+		":exit", ":xit" and CTRL-\ CTRL-N also work.
+:qall		Quit Vim, unless there are changes in some buffer.
+:qall!		Quit Vim, discarding changes to any buffer.
+
+Once the command-line window is closed the old window sizes are restored.  The
+executed command applies to the window and buffer where the command-line was
+started from.  This works as if the command-line window was not there, except
+that there will be an extra screen redraw.
+The buffer used for the command-line window is deleted.  Any changes to lines
+other than the one that is executed with <CR> are lost.
+
+If you would like to execute the command under the cursor and then have the
+command-line window open again, you may find this mapping useful: >
+
+	:map <F5> <CR>q:
+
+
+VARIOUS
+
+The command-line window cannot be used:
+- when there already is a command-line window (no nesting)
+- for entering a encryption key or when using inputsecret()
+- when Vim was not compiled with the +vertsplit feature
+
+Some options are set when the command-line window is opened:
+'filetype'	"vim", when editing an Ex command-line; this starts Vim syntax
+		highlighting if it was enabled
+'rightleft'	off
+'modifiable'	on
+'buftype'	"nofile"
+'swapfile'	off
+
+It is allowed to write the buffer contents to a file.  This is an easy way to
+save the command-line history and read it back later.
+
+If the 'wildchar' option is set to <Tab>, and the command-line window is used
+for an Ex command, then two mappings will be added to use <Tab> for completion
+in the command-line window, like this: >
+	:imap <buffer> <Tab> <C-X><C-V>
+	:nmap <buffer> <Tab> a<C-X><C-V>
+Note that hitting <Tab> in Normal mode will do completion on the next
+character.  That way it works at the end of the line.
+If you don't want these mappings, disable them with: >
+	au CmdwinEnter [:>] iunmap <Tab>
+	au CmdwinEnter [:>] nunmap <Tab>
+You could put these lines in your vimrc file.
+
+While in the command-line window you cannot use the mouse to put the cursor in
+another window, or drag statuslines of other windows.  You can drag the
+statusline of the command-line window itself and the statusline above it.
+Thus you can resize the command-line window, but not others.
+
+
+AUTOCOMMANDS
+
+Two autocommand events are used: |CmdwinEnter| and |CmdwinLeave|.  Since this
+window is of a special type, the WinEnter, WinLeave, BufEnter and BufLeave
+events are not triggered.  You can use the Cmdwin events to do settings
+specifically for the command-line window.  Be careful not to cause side
+effects!
+Example: >
+	:au CmdwinEnter :  let b:cpt_save = &cpt | set cpt=v
+	:au CmdwinLeave :  let &cpt = b:cpt_save
+This sets 'complete' to use command-line completion in Insert mode for CTRL-N.
+Another example: >
+	:au CmdwinEnter [/?]  startinsert
+This will make Vim start in Insert mode in the command-line window.
+
+						*cmdwin-char*
+The character used for the pattern indicates the type of command-line:
+	:	normal Ex command
+	>	debug mode command |debug-mode|
+	/	forward search string
+	?	backward search string
+	=	expression for "= |expr-register|
+	@	string for |input()|
+	-	text for |:insert| or |:append|
+
+ vim:tw=78:ts=8:ft=help:norl:
--- /dev/null
+++ b/lib/vimfiles/doc/debug.txt
@@ -1,0 +1,151 @@
+*debug.txt*     For Vim version 7.1.  Last change: 2006 May 01
+
+
+		  VIM REFERENCE MANUAL    by Bram Moolenaar
+
+
+Debugging Vim						*debug-vim*
+
+This is for debugging Vim itself, when it doesn't work properly.
+For debugging Vim scripts, functions, etc. see |debug-scripts|
+
+1. Location of a crash, using gcc and gdb	|debug-gcc|
+2. Windows Bug Reporting			|debug-win32|
+
+==============================================================================
+
+1. Location of a crash, using gcc and gdb		*debug-gcc*
+
+When Vim crashes in one of the test files, and you are using gcc for
+compilation, here is what you can do to find out exactly where Vim crashes.
+This also applies when using the MingW tools.
+
+1. Compile Vim with the "-g" option (there is a line in the Makefile for this,
+   which you can uncomment).
+
+2. Execute these commands (replace "11" with the test that fails): >
+	cd testdir
+	gdb ../vim
+	run -u unix.vim -U NONE -s dotest.in test11.in
+
+3. Check where Vim crashes, gdb should give a message for this.
+
+4. Get a stack trace from gdb with this command: >
+	where
+<  You can check out different places in the stack trace with: >
+	frame 3
+<  Replace "3" with one of the numbers in the stack trace.
+
+==============================================================================
+
+2. Windows Bug Reporting				*debug-win32*
+
+If the Windows version of Vim crashes in a reproducible manner, you can take
+some steps to provide a useful bug report.
+
+
+GENERIC ~
+
+You must obtain the debugger symbols (PDB) file for your executable: gvim.pdb
+for gvim.exe, or vim.pdb for vim.exe. The PDB should be available from the
+same place that you obtained the executable. Be sure to use the PDB that
+matches the EXE (same date).
+
+If you built the executable yourself with the Microsoft Visual C++ compiler,
+then the PDB was built with the EXE.
+
+Alternatively, if you have the source files, you can import Make_ivc.mak into
+Visual Studio as a workspace.  Then select a debug configuration, build and
+you can do all kinds of debugging (set breakpoints, watch variables, etc.).
+
+If you have Visual Studio, use that instead of the VC Toolkit and WinDbg.
+
+For other compilers, you should always use the corresponding debugger: TD for
+a Vim executable compiled with the Borland compiler; gdb (see above
+|debug-gcc|) for the Cygwin and MinGW compilers.
+
+
+								*debug-vs2005*
+2.2 Debugging Vim crashes with Visual Studio 2005/Visual C++ 2005 Express ~
+
+First launch vim.exe or gvim.exe and then launch Visual Studio.  (If you don't
+have Visual Studio, follow the instructions at |get-ms-debuggers| to obtain a
+free copy of Visual C++ 2005 Express Edition.)
+
+On the Tools menu, click Attach to Process.  Choose the Vim process.
+
+In Vim, reproduce the crash.  A dialog will appear in Visual Studio, telling
+you about the unhandled exception in the Vim process.  Click Break to break
+into the process.
+
+Visual Studio will pop up another dialog, telling you that no symbols are
+loaded and that the source code cannot be displayed.  Click OK.
+
+Several windows will open.  Right-click in the Call Stack window.  Choose Load
+Symbols.  The Find Symbols dialog will open, looking for (g)vim.pdb.  Navigate
+to the directory where you have the PDB file and click Open.
+
+At this point, you should have a full call stack with vim function names and
+line numbers.  Double-click one of the lines and the Find Source dialog will
+appear.  Navigate to the directory where the Vim source is (if you have it.)
+
+If you don't know how to debug this any further, follow the instructions
+at ":help bug-reports".  Paste the call stack into the bug report.
+
+If you have a non-free version of Visual Studio, you can save a minidump via
+the Debug menu and send it with the bug report.  A minidump is a small file
+(<100KB), which contains information about the state of your process.
+Visual C++ 2005 Express Edition cannot save minidumps and it cannot be
+installed as a just-in-time debugger. Use WinDbg, |debug-windbg|, if you
+need to save minidumps or you want a just-in-time (postmortem) debugger.
+
+								*debug-windbg*
+2.3 Debugging Vim crashes with WinDbg ~
+
+See |get-ms-debuggers| to obtain a copy of WinDbg.
+
+As with the Visual Studio IDE, you can attach WinDbg to a running Vim process.
+You can also have your system automatically invoke WinDbg as a postmortem
+debugger. To set WinDbg as your postmortem debugger, run "windbg -I".
+
+To attach WinDbg to a running Vim process, launch WinDbg. On the File menu,
+choose Attach to a Process. Select the Vim process and click OK.
+
+At this point, choose Symbol File Path on the File menu, and add the folder
+containing your Vim PDB to the sympath. If you have Vim source available,
+use Source File Path on the File menu. You can now open source files in WinDbg
+and set breakpoints, if you like. Reproduce your crash. WinDbg should open the
+source file at the point of the crash. Using the View menu, you can examine
+the call stack, local variables, watch windows, and so on.
+
+If WinDbg is your postmortem debugger, you do not need to attach WinDbg to
+your Vim process. Simply reproduce the crash and WinDbg will launch
+automatically. As above, set the Symbol File Path and the Source File Path.
+
+To save a minidump, type the following at the WinDbg command line: >
+        .dump vim.dmp
+<
+							*debug-minidump*
+2.4 Opening a Minidump ~
+
+If you have a minidump file, you can open it in Visual Studio or in WinDbg.
+
+In Visual Studio 2005: on the File menu, choose Open, then Project/Solution.
+Navigate to the .dmp file and open it. Now press F5 to invoke the debugger.
+Follow the instructions in |debug-vs2005| to set the Symbol File Path.
+
+In WinDbg: choose Open Crash Dump on the File menu. Follow the instructions in
+|debug-windbg| to set the Symbol File Path.
+
+							*get-ms-debuggers*
+2.5 Obtaining Microsoft Debugging Tools ~
+
+The Debugging Tools for Windows (including WinDbg) can be downloaded from
+    http://www.microsoft.com/whdc/devtools/debugging/default.mspx
+This includes the WinDbg debugger.
+
+Visual C++ 2005 Express Edition can be downloaded for free from:
+    http://msdn.microsoft.com/vstudio/express/visualC/default.aspx
+
+=========================================================================
+ vim:tw=78:ts=8:ft=help:norl:
--- /dev/null
+++ b/lib/vimfiles/doc/debugger.txt
@@ -1,0 +1,140 @@
+*debugger.txt*  For Vim version 7.1.  Last change: 2005 Mar 29
+
+
+		  VIM REFERENCE MANUAL    by Gordon Prieur
+
+
+Debugger Support Features				*debugger-support*
+
+1. Debugger Features		|debugger-features|
+2. Vim Compile Options		|debugger-compilation|
+3. Integrated Debuggers		|debugger-integration|
+
+{Vi does not have any of these features}
+
+==============================================================================
+1. Debugger Features					*debugger-features*
+
+The following features are available for an integration with a debugger or
+an Integrated Programming Environment (IPE) or Integrated Development
+Environment (IDE):
+
+	Alternate Command Input				|alt-input|
+	Debug Signs					|debug-signs|
+	Debug Source Highlight				|debug-highlight|
+	Message Footer					|gui-footer|
+	Balloon Evaluation				|balloon-eval|
+
+These features were added specifically for use in the Motif version of gvim.
+However, the |alt-input| and |debug-highlight| were written to be usable in
+both vim and gvim.  Some of the other features could be used in the non-GUI
+vim with slight modifications.  However, I did not do this nor did I test the
+reliability of building for vim or non Motif GUI versions.
+
+
+1.1 Alternate Command Input				*alt-input*
+
+For Vim to work with a debugger there must be at least an input connection
+with a debugger or external tool.  In many cases there will also be an output
+connection but this isn't absolutely necessary.
+
+The purpose of the input connection is to let the external debugger send
+commands to Vim.  The commands sent by the debugger should give the debugger
+enough control to display the current debug environment and state.
+
+The current implementation is based on the X Toolkit dispatch loop and the
+XtAddInput() function call.
+
+
+1.2 Debug Signs						*debug-signs*
+
+Many debuggers mark specific lines by placing a small sign or color highlight
+on the line.  The |:sign| command lets the debugger set this graphic mark.  Some
+examples where this feature would be used would be a debugger showing an arrow
+representing the Program Counter (PC) of the program being debugged.  Another
+example would be a small stop sign for a line with a breakpoint.  These visible
+highlights let the user keep track of certain parts of the state of the
+debugger.
+
+This feature can be used with more than debuggers, too.  An IPE can use a sign
+to highlight build errors, searched text, or other things.  The sign feature
+can also work together with the |debug-highlight| to ensure the mark is
+highly visible.
+
+Debug signs are defined and placed using the |:sign| command.
+
+
+1.3 Debug Source Highlight				*debug-highlight*
+
+This feature allows a line to have a predominant highlight.  The highlight is
+intended to make a specific line stand out.  The highlight could be made to
+work for both vim and gvim, whereas the debug sign is, in most cases, limited
+to gvim.  The one exception to this is Sun Microsystem's dtterm.  The dtterm
+from Sun has a "sign gutter" for showing signs.
+
+
+1.4 Message Footer					*gui-footer*
+
+The message footer can be used to display messages from a debugger or IPE.  It
+can also be used to display menu and toolbar tips.  The footer area is at the
+bottom of the GUI window, below the line used to display colon commands.
+
+The display of the footer is controlled by the 'guioptions' letter 'F'.
+
+
+1.5 Balloon Evaluation					*balloon-eval*
+
+This feature allows a debugger, or other external tool, to display dynamic
+information based on where the mouse is pointing.  The purpose of this feature
+was to allow Sun's Visual WorkShop debugger to display expression evaluations.
+However, the feature was implemented in as general a manner as possible and
+could be used for displaying other information as well.
+
+The Balloon Evaluation has some settable parameters too.  For Motif the font
+list and colors can be set via X resources (XmNballoonEvalFontList,
+XmNballoonEvalBackground, and XmNballoonEvalForeground).
+The 'balloondelay' option sets the delay before an attempt is made to show a
+balloon.
+The 'ballooneval' option needs to be set to switch it on.
+
+Balloon evaluation is only available when compiled with the |+balloon_eval|
+feature.
+
+The Balloon evaluation functions are also used to show a tooltip for the
+toolbar.  The 'ballooneval' option does not need to be set for this.  But the
+other settings apply.
+
+Another way to use the balloon is with the 'balloonexpr' option.  This is
+completely user definable.
+
+==============================================================================
+2. Vim Compile Options					*debugger-compilation*
+
+The debugger features were added explicitly for use with Sun's Visual
+WorkShop Integrated Programming Environment (ipe).  However, they were done
+in as generic a manner as possible so that integration with other debuggers
+could also use some or all of the tools used with Sun's ipe.
+
+The following compile time preprocessor variables control the features:
+
+    Alternate Command Input			ALT_X_INPUT
+    Debug Glyphs				FEAT_SIGNS
+    Debug Highlights				FEAT_SIGNS
+    Message Footer				FEAT_FOOTER
+    Balloon Evaluation				FEAT_BEVAL
+
+The first integration with a full IPE/IDE was with Sun Visual WorkShop.  To
+compile a gvim which interfaces with VWS set the following flag, which sets
+all the above flags:
+
+    Sun Visual WorkShop				FEAT_SUN_WORKSHOP
+
+==============================================================================
+3. Integrated Debuggers					*debugger-integration*
+
+One fully integrated debugger/IPE/IDE is Sun's Visual WorkShop Integrated
+Programming Environment.
+
+For Sun NetBeans support see |netbeans|.
+
+ vim:tw=78:sw=4:ts=8:ft=help:norl:
--- /dev/null
+++ b/lib/vimfiles/doc/develop.txt
@@ -1,0 +1,490 @@
+*develop.txt*   For Vim version 7.1.  Last change: 2007 May 11
+
+
+		  VIM REFERENCE MANUAL    by Bram Moolenaar
+
+
+Development of Vim.					*development*
+
+This text is important for those who want to be involved in further developing
+Vim.
+
+1. Design goals		|design-goals|
+2. Coding style		|coding-style|
+3. Design decisions	|design-decisions|
+4. Assumptions		|design-assumptions|
+
+See the file README.txt in the "src" directory for an overview of the source
+code.
+
+Vim is open source software.  Everybody is encouraged to contribute to help
+improving Vim.  For sending patches a context diff "diff -c" is preferred.
+Also see http://www.vim.org/tips/tip.php?tip_id=618.
+
+==============================================================================
+1. Design goals						*design-goals*
+
+Most important things come first (roughly).
+
+Note that quite a few items are contradicting.  This is intentional.  A
+balance must be found between them.
+
+
+VIM IS... VI COMPATIBLE					*design-compatible*
+
+First of all, it should be possible to use Vim as a drop-in replacement for
+Vi.  When the user wants to, he can use Vim in compatible mode and hardly
+notice any difference with the original Vi.
+
+Exceptions:
+- We don't reproduce obvious Vi bugs in Vim.
+- There are different versions of Vi.  I am using Version 3.7 (6/7/85) as a
+  reference.  But support for other versions is also included when possible.
+  The Vi part of POSIX is not considered a definitive source.
+- Vim adds new commands, you cannot rely on some command to fail because it
+  didn't exist in Vi.
+- Vim will have a lot of features that Vi doesn't have.  Going back from Vim
+  to Vi will be a problem, this cannot be avoided.
+- Some things are hardly ever used (open mode, sending an e-mail when
+  crashing, etc.).  Those will only be included when someone has a good reason
+  why it should be included and it's not too much work.
+- For some items it is debatable whether Vi compatibility should be
+  maintained.  There will be an option flag for these.
+
+
+VIM IS... IMPROVED					*design-improved*
+
+The IMproved bits of Vim should make it a better Vi, without becoming a
+completely different editor.  Extensions are done with a "Vi spirit".
+- Use the keyboard as much as feasible.  The mouse requires a third hand,
+  which we don't have.  Many terminals don't have a mouse.
+- When the mouse is used anyway, avoid the need to switch back to the
+  keyboard.  Avoid mixing mouse and keyboard handling.
+- Add commands and options in a consistent way.  Otherwise people will have a
+  hard time finding and remembering them.  Keep in mind that more commands and
+  options will be added later.
+- A feature that people do not know about is a useless feature.  Don't add
+  obscure features, or at least add hints in documentation that they exists.
+- Minimize using CTRL and other modifiers, they are more difficult to type.
+- There are many first-time and inexperienced Vim users.  Make it easy for
+  them to start using Vim and learn more over time.
+- There is no limit to the features that can be added.  Selecting new features
+  is one based on (1) what users ask for, (2) how much effort it takes to
+  implement and (3) someone actually implementing it.
+
+
+VIM IS... MULTI PLATFORM				*design-multi-platform*
+
+Vim tries to help as many users on as many platforms as possible.
+- Support many kinds of terminals.  The minimal demands are cursor positioning
+  and clear-screen.  Commands should only use key strokes that most keyboards
+  have.  Support all the keys on the keyboard for mapping.
+- Support many platforms.  A condition is that there is someone willing to do
+  Vim development on that platform, and it doesn't mean messing up the code.
+- Support many compilers and libraries.  Not everybody is able or allowed to
+  install another compiler or GUI library.
+- People switch from one platform to another, and from GUI to terminal
+  version.  Features should be present in all versions, or at least in as many
+  as possible with a reasonable effort.  Try to avoid that users must switch
+  between platforms to accomplish their work efficiently.
+- That a feature is not possible on some platforms, or only possible on one
+  platform, does not mean it cannot be implemented.  [This intentionally
+  contradicts the previous item, these two must be balanced.]
+
+
+VIM IS... WELL DOCUMENTED				*design-documented*
+
+- A feature that isn't documented is a useless feature.  A patch for a new
+  feature must include the documentation.
+- Documentation should be comprehensive and understandable.  Using examples is
+  recommended.
+- Don't make the text unnecessarily long.  Less documentation means that an
+  item is easier to find.
+
+
+VIM IS... HIGH SPEED AND SMALL IN SIZE			*design-speed-size*
+
+Using Vim must not be a big attack on system resources.  Keep it small and
+fast.
+- Computers are becoming faster and bigger each year.  Vim can grow too, but
+  no faster than computers are growing.  Keep Vim usable on older systems.
+- Many users start Vim from a shell very often.  Startup time must be short.
+- Commands must work efficiently.  The time they consume must be as small as
+  possible.  Useful commands may take longer.
+- Don't forget that some people use Vim over a slow connection.  Minimize the
+  communication overhead.
+- Items that add considerably to the size and are not used by many people
+  should be a feature that can be disabled.
+- Vim is a component among other components.  Don't turn it into a massive
+  application, but have it work well together with other programs.
+
+
+VIM IS... MAINTAINABLE					*design-maintain*
+
+- The source code should not become a mess.  It should be reliable code.
+- Use the same layout in all files to make it easy to read |coding-style|.
+- Use comments in a useful way!  Quoting the function name and argument names
+  is NOT useful.  Do explain what they are for.
+- Porting to another platform should be made easy, without having to change
+  too much platform-independent code.
+- Use the object-oriented spirit: Put data and code together.  Minimize the
+  knowledge spread to other parts of the code.
+
+
+VIM IS... FLEXIBLE					*design-flexible*
+
+Vim should make it easy for users to work in their preferred styles rather
+than coercing its users into particular patterns of work.  This can be for
+items with a large impact (e.g., the 'compatible' option) or for details.  The
+defaults are carefully chosen such that most users will enjoy using Vim as it
+is.  Commands and options can be used to adjust Vim to the desire of the user
+and its environment.
+
+
+VIM IS... NOT						*design-not*
+
+- Vim is not a shell or an Operating System.  You will not be able to run a
+  shell inside Vim or use it to control a debugger.  This should work the
+  other way around: Use Vim as a component from a shell or in an IDE.
+  A satirical way to say this: "Unlike Emacs, Vim does not attempt to include
+  everything but the kitchen sink, but some people say that you can clean one
+  with it.  ;-)"
+  To use Vim with gdb see: http://www.agide.org and http://clewn.sf.net.
+- Vim is not a fancy GUI editor that tries to look nice at the cost of
+  being less consistent over all platforms.  But functional GUI features are
+  welcomed.
+
+==============================================================================
+2. Coding style						*coding-style*
+
+These are the rules to use when making changes to the Vim source code.  Please
+stick to these rules, to keep the sources readable and maintainable.
+
+This list is not complete.  Look in the source code for more examples.
+
+
+MAKING CHANGES						*style-changes*
+
+The basic steps to make changes to the code:
+1. Adjust the documentation.  Doing this first gives you an impression of how
+   your changes affect the user.
+2. Make the source code changes.
+3. Check ../doc/todo.txt if the change affects any listed item.
+4. Make a patch with "diff -c" against the unmodified code and docs.
+5. Make a note about what changed and include it with the patch.
+
+
+USE OF COMMON FUNCTIONS					*style-functions*
+
+Some functions that are common to use, have a special Vim version.  Always
+consider using the Vim version, because they were introduced with a reason.
+
+NORMAL NAME	VIM NAME	DIFFERENCE OF VIM VERSION
+free()		vim_free()	Checks for freeing NULL
+malloc()	alloc()		Checks for out of memory situation
+malloc()	lalloc()	Like alloc(), but has long argument
+strcpy()	STRCPY()	Includes cast to (char *), for char_u * args
+strchr()	vim_strchr()	Accepts special characters
+strrchr()	vim_strrchr()	Accepts special characters
+isspace()	vim_isspace()	Can handle characters > 128
+iswhite()	vim_iswhite()	Only TRUE for tab and space
+memcpy()	mch_memmove()	Handles overlapped copies
+bcopy()		mch_memmove()	Handles overlapped copies
+memset()	vim_memset()	Uniform for all systems
+
+
+NAMES							*style-names*
+
+Function names can not be more than 31 characters long (because of VMS).
+
+Don't use "delete" as a variable name, C++ doesn't like it.
+
+Because of the requirement that Vim runs on as many systems as possible, we
+need to avoid using names that are already defined by the system.  This is a
+list of names that are known to cause trouble.  The name is given as a regexp
+pattern.
+
+is.*()		POSIX, ctype.h
+to.*()		POSIX, ctype.h
+
+d_.*		POSIX, dirent.h
+l_.*		POSIX, fcntl.h
+gr_.*		POSIX, grp.h
+pw_.*		POSIX, pwd.h
+sa_.*		POSIX, signal.h
+mem.*		POSIX, string.h
+str.*		POSIX, string.h
+wcs.*		POSIX, string.h
+st_.*		POSIX, stat.h
+tms_.*		POSIX, times.h
+tm_.*		POSIX, time.h
+c_.*		POSIX, termios.h
+MAX.*		POSIX, limits.h
+__.*		POSIX, system
+_[A-Z].*	POSIX, system
+E[A-Z0-9]*	POSIX, errno.h
+
+.*_t		POSIX, for typedefs.  Use .*_T instead.
+
+wait		don't use as argument to a function, conflicts with types.h
+index		shadows global declaration
+time		shadows global declaration
+new		C++ reserved keyword
+try		Borland C++ doesn't like it to be used as a variable.
+
+basename()	GNU string function
+dirname()	GNU string function
+get_env_value()	Linux system function
+
+
+VARIOUS							*style-various*
+
+Typedef'ed names should end in "_T": >
+    typedef int some_T;
+Define'ed names should be uppercase: >
+    #define SOME_THING
+Features always start with "FEAT_": >
+    #define FEAT_FOO
+
+Don't use '\"', some compilers can't handle it.  '"' works fine.
+
+Don't use:
+    #if HAVE_SOME
+Some compilers can't handle that and complain that "HAVE_SOME" is not defined.
+Use
+    #ifdef HAVE_SOME
+or
+    #if defined(HAVE_SOME)
+
+
+STYLE							*style-examples*
+
+General rule: One statement per line.
+
+Wrong:	    if (cond) a = 1;
+
+OK:	    if (cond)
+		a = 1;
+
+Wrong:	    while (cond);
+
+OK:	    while (cond)
+		;
+
+Wrong:	    do a = 1; while (cond);
+
+OK:	    do
+		a = 1;
+	    while (cond);
+
+
+Functions start with:
+
+Wrong:	int function_name(int arg1, int arg2)
+
+OK:	/*
+	 * Explanation of what this function is used for.
+	 *
+	 * Return value explanation.
+	 */
+	    int
+	function_name(arg1, arg2)
+	    int		arg1;		/* short comment about arg1 */
+	    int		arg2;		/* short comment about arg2 */
+	{
+	    int		local;		/* comment about local */
+
+	    local = arg1 * arg2;
+
+NOTE: Don't use ANSI style function declarations.  A few people still have to
+use a compiler that doesn't support it.
+
+
+SPACES AND PUNCTUATION					*style-spaces*
+
+No space between a function name and the bracket:
+
+Wrong:  func (arg);
+OK:	func(arg);
+
+Do use a space after if, while, switch, etc.
+
+Wrong:	if(arg)		for(;;)
+OK:	if (arg)	for (;;)
+
+Use a space after a comma and semicolon:
+
+Wrong:  func(arg1,arg2);	for (i = 0;i < 2;++i)
+OK:	func(arg1, arg2);	for (i = 0; i < 2; ++i)
+
+Use a space before and after '=', '+', '/', etc.
+
+Wrong:	var=a*5;
+OK:	var = a * 5;
+
+In general: Use empty lines to group lines of code together.  Put a comment
+just above the group of lines.  This makes it more easy to quickly see what is
+being done.
+
+OK:	/* Prepare for building the table. */
+	get_first_item();
+	table_idx = 0;
+
+	/* Build the table */
+	while (has_item())
+	    table[table_idx++] = next_item();
+
+	/* Finish up. */
+	cleanup_items();
+	generate_hash(table);
+
+==============================================================================
+3. Design decisions					*design-decisions*
+
+Folding
+
+Several forms of folding should be possible for the same buffer.  For example,
+have one window that shows the text with function bodies folded, another
+window that shows a function body.
+
+Folding is a way to display the text.  It should not change the text itself.
+Therefore the folding has been implemented as a filter between the text stored
+in a buffer (buffer lines) and the text displayed in a window (logical lines).
+
+
+Naming the window
+
+The word "window" is commonly used for several things: A window on the screen,
+the xterm window, a window inside Vim to view a buffer.
+To avoid confusion, other items that are sometimes called window have been
+given another name.  Here is an overview of the related items:
+
+screen		The whole display.  For the GUI it's something like 1024x768
+		pixels.  The Vim shell can use the whole screen or part of it.
+shell		The Vim application.  This can cover the whole screen (e.g.,
+		when running in a console) or part of it (xterm or GUI).
+window		View on a buffer.  There can be several windows in Vim,
+		together with the command line, menubar, toolbar, etc. they
+		fit in the shell.
+
+
+Spell checking						*develop-spell*
+
+When spell checking was going to be added to Vim a survey was done over the
+available spell checking libraries and programs.  Unfortunately, the result
+was that none of them provided sufficient capabilities to be used as the spell
+checking engine in Vim, for various reasons:
+
+- Missing support for multi-byte encodings.  At least UTF-8 must be supported,
+  so that more than one language can be used in the same file.
+  Doing on-the-fly conversion is not always possible (would require iconv
+  support).
+- For the programs and libraries: Using them as-is would require installing
+  them separately from Vim.  That's mostly not impossible, but a drawback.
+- Performance: A few tests showed that it's possible to check spelling on the
+  fly (while redrawing), just like syntax highlighting.  But the mechanisms
+  used by other code are much slower.  Myspell uses a hashtable, for example.
+  The affix compression that most spell checkers use makes it slower too.
+- For using an external program like aspell a communication mechanism would
+  have to be setup.  That's complicated to do in a portable way (Unix-only
+  would be relatively simple, but that's not good enough).  And performance
+  will become a problem (lots of process switching involved).
+- Missing support for words with non-word characters, such as "Etten-Leur" and
+  "et al.", would require marking the pieces of them OK, lowering the
+  reliability.
+- Missing support for regions or dialects.  Makes it difficult to accept
+  all English words and highlight non-Canadian words differently.
+- Missing support for rare words.  Many words are correct but hardly ever used
+  and could be a misspelled often-used word.
+- For making suggestions the speed is less important and requiring to install
+  another program or library would be acceptable.  But the word lists probably
+  differ, the suggestions may be wrong words.
+
+
+Spelling suggestions				*develop-spell-suggestions*
+
+For making suggestions there are two basic mechanisms:
+1. Try changing the bad word a little bit and check for a match with a good
+   word.  Or go through the list of good words, change them a little bit and
+   check for a match with the bad word.  The changes are deleting a character,
+   inserting a character, swapping two characters, etc.
+2. Perform soundfolding on both the bad word and the good words and then find
+   matches, possibly with a few changes like with the first mechanism.
+
+The first is good for finding typing mistakes.  After experimenting with
+hashtables and looking at solutions from other spell checkers the conclusion
+was that a trie (a kind of tree structure) is ideal for this.  Both for
+reducing memory use and being able to try sensible changes.  For example, when
+inserting a character only characters that lead to good words need to be
+tried.  Other mechanisms (with hashtables) need to try all possible letters at
+every position in the word.  Also, a hashtable has the requirement that word
+boundaries are identified separately, while a trie does not require this.
+That makes the mechanism a lot simpler.
+
+Soundfolding is useful when someone knows how the words sounds but doesn't
+know how it is spelled.  For example, the word "dictionary" might be written
+as "daktonerie".  The number of changes that the first method would need to
+try is very big, it's hard to find the good word that way.  After soundfolding
+the words become "tktnr" and "tkxnry", these differ by only two letters.
+
+To find words by their soundfolded equivalent (soundalike word) we need a list
+of all soundfolded words.  A few experiments have been done to find out what
+the best method is.  Alternatives:
+1. Do the sound folding on the fly when looking for suggestions.  This means
+   walking through the trie of good words, soundfolding each word and
+   checking how different it is from the bad word.  This is very efficient for
+   memory use, but takes a long time.  On a fast PC it takes a couple of
+   seconds for English, which can be acceptable for interactive use.  But for
+   some languages it takes more than ten seconds (e.g., German, Catalan),
+   which is unacceptable slow.  For batch processing (automatic corrections)
+   it's too slow for all languages.
+2. Use a trie for the soundfolded words, so that searching can be done just
+   like how it works without soundfolding.  This requires remembering a list
+   of good words for each soundfolded word.  This makes finding matches very
+   fast but requires quite a lot of memory, in the order of 1 to 10 Mbyte.
+   For some languages more than the original word list.
+3. Like the second alternative, but reduce the amount of memory by using affix
+   compression and store only the soundfolded basic word.  This is what Aspell
+   does.  Disadvantage is that affixes need to be stripped from the bad word
+   before soundfolding it, which means that mistakes at the start and/or end
+   of the word will cause the mechanism to fail.  Also, this becomes slow when
+   the bad word is quite different from the good word.
+
+The choice made is to use the second mechanism and use a separate file.  This
+way a user with sufficient memory can get very good suggestions while a user
+who is short of memory or just wants the spell checking and no suggestions
+doesn't use so much memory.
+
+
+Word frequency
+
+For sorting suggestions it helps to know which words are common.  In theory we
+could store a word frequency with the word in the dictionary.  However, this
+requires storing a count per word.  That degrades word tree compression a lot.
+And maintaining the word frequency for all languages will be a heavy task.
+Also, it would be nice to prefer words that are already in the text.  This way
+the words that appear in the specific text are preferred for suggestions.
+
+What has been implemented is to count words that have been seen during
+displaying.  A hashtable is used to quickly find the word count.  The count is
+initialized from words listed in COMMON items in the affix file, so that it
+also works when starting a new file.
+
+This isn't ideal, because the longer Vim is running the higher the counts
+become.  But in practice it is a noticeable improvement over not using the word
+count.
+
+==============================================================================
+4. Assumptions						*design-assumptions*
+
+Size of variables:
+char	    8 bit signed
+char_u	    8 bit unsigned
+int	    32 or 64 bit signed (16 might be possible with limited features)
+unsigned    32 or 64 bit unsigned (16 as with ints)
+long	    32 or 64 bit signed, can hold a pointer
+
+Note that some compilers cannot handle long lines or strings.  The C89
+standard specifies a limit of 509 characters.
+
+ vim:tw=78:ts=8:ft=help:norl:
--- /dev/null
+++ b/lib/vimfiles/doc/diff.txt
@@ -1,0 +1,407 @@
+*diff.txt*      For Vim version 7.1.  Last change: 2006 Oct 02
+
+
+		  VIM REFERENCE MANUAL    by Bram Moolenaar
+
+
+				*diff* *vimdiff* *gvimdiff* *diff-mode*
+This file describes the +diff feature: Showing differences between two or
+three versions of the same file.
+
+The basics are explained in section |08.7| of the user manual.
+
+1. Starting diff mode		|vimdiff|
+2. Viewing diffs		|view-diffs|
+3. Jumping to diffs		|jumpto-diffs|
+4. Copying diffs		|copy-diffs|
+5. Diff options			|diff-options|
+
+{not in Vi}
+
+==============================================================================
+1. Starting diff mode
+
+The easiest way to start editing in diff mode is with the "vimdiff" command.
+This starts Vim as usual, and additionally sets up for viewing the differences
+between the arguments. >
+
+	vimdiff file1 file2 [file3 [file4]]
+
+This is equivalent to: >
+
+	vim -d file1 file2 [file3 [file4]]
+
+You may also use "gvimdiff" or "vim -d -g".  The GUI is started then.
+You may also use "viewdiff" or "gviewdiff".  Vim starts in readonly mode then.
+"r" may be prepended for restricted mode (see |-Z|).
+
+The second and following arguments may also be a directory name.  Vim will
+then append the file name of the first argument to the directory name to find
+the file.
+
+This only works when a standard "diff" command is available.  See 'diffexpr'.
+
+Diffs are local to the current tab page |tab-page|.  You can't see diffs with
+a window in another tab page.  This does make it possible to have several
+diffs at the same time, each in their own tab page.
+
+What happens is that Vim opens a window for each of the files.  This is like
+using the |-O| argument.  This uses vertical splits.  If you prefer horizontal
+splits add the |-o| argument: >
+
+	vimdiff -o file1 file2 [file3]
+
+If you always prefer horizontal splits include "horizontal" in 'diffopt'.
+
+In each of the edited files these options are set:
+
+	'diff'		on
+	'scrollbind'	on
+	'scrollopt'	includes "hor"
+	'wrap'		off
+	'foldmethod'	"diff"
+	'foldcolumn'	value from 'diffopt', default is 2
+
+These options are set local to the window.  When editing another file they are
+reset to the global value.
+
+The differences shown are actually the differences in the buffer.  Thus if you
+make changes after loading a file, these will be included in the displayed
+diffs.  You might have to do ":diffupdate" now and then, not all changes are
+immediately taken into account.
+
+In your .vimrc file you could do something special when Vim was started in
+diff mode.  You could use a construct like this: >
+
+	if &diff
+	   setup for diff mode
+	else
+	   setup for non-diff mode
+	endif
+
+While already in Vim you can start diff mode in three ways.
+
+							*E98*
+:diffsplit {filename}					*:diffs* *:diffsplit*
+		Open a new window on the file {filename}.  The options are set
+		as for "vimdiff" for the current and the newly opened window.
+		Also see 'diffexpr'.
+
+							*:difft* *:diffthis*
+:diffthis	Make the current window part of the diff windows.  This sets
+		the options like for "vimdiff".
+
+:diffpatch {patchfile}					*:diffp* *:diffpatch*
+		Use the current buffer, patch it with the diff found in
+		{patchfile} and open a buffer on the result.  The options are
+		set as for "vimdiff".
+		{patchfile} can be in any format that the "patch" program
+		understands or 'patchexpr' can handle.
+		Note that {patchfile} should only contain a diff for one file,
+		the current file.  If {patchfile} contains diffs for other
+		files as well, the results are unpredictable.  Vim changes
+		directory to /tmp to avoid files in the current directory
+		accidentally being patched.  But it may still result in
+		various ".rej" files to be created.  And when absolute path
+		names are present these files may get patched anyway.
+
+To make these commands use a vertical split, prepend |:vertical|.  Examples: >
+
+	:vert diffsplit main.c~
+	:vert diffpatch /tmp/diff
+
+If you always prefer a vertical split include "vertical" in 'diffopt'.
+
+							*E96*
+There can be up to four buffers with 'diff' set.
+
+Since the option values are remembered with the buffer, you can edit another
+file for a moment and come back to the same file and be in diff mode again.
+
+							*:diffo* *:diffoff*
+:diffoff	Switch off diff mode for the current window.
+
+:diffoff!	Switch off diff mode for all windows in the current tab page.
+
+The ":diffoff" command resets the relevant options to their default value.
+This may be different from what the values were before diff mode was started,
+the old values are not remembered.
+
+	'diff'		off
+	'scrollbind'	off
+	'scrollopt'	without "hor"
+	'wrap'		on
+	'foldmethod'	"manual"
+	'foldcolumn'	0
+
+==============================================================================
+2. Viewing diffs						*view-diffs*
+
+The effect is that the diff windows show the same text, with the differences
+highlighted.  When scrolling the text, the 'scrollbind' option will make the
+text in other windows to be scrolled as well.  With vertical splits the text
+should be aligned properly.
+
+The alignment of text will go wrong when:
+- 'wrap' is on, some lines will be wrapped and occupy two or more screen
+  lines
+- folds are open in one window but not another
+- 'scrollbind' is off
+- changes have been made to the text
+- "filler" is not present in 'diffopt', deleted/inserted lines makes the
+  alignment go wrong
+
+All the buffers edited in a window where the 'diff' option is set will join in
+the diff.  This is also possible for hidden buffers.  They must have been
+edited in a window first for this to be possible.
+
+					*:DiffOrig* *diff-original-file*
+Since 'diff' is a window-local option, it's possible to view the same buffer
+in diff mode in one window and "normal" in another window.  It is also
+possible to view the changes you have made to a buffer since the file was
+loaded.  Since Vim doesn't allow having two buffers for the same file, you
+need another buffer.  This command is useful: >
+	 command DiffOrig vert new | set bt=nofile | r # | 0d_ | diffthis
+	 	\ | wincmd p | diffthis
+(this is in |vimrc_example.vim|).  Use ":DiffOrig" to see the differences
+between the current buffer and the file it was loaded from.
+
+A buffer that is unloaded cannot be used for the diff.  But it does work for
+hidden buffers.  You can use ":hide" to close a window without unloading the
+buffer.  If you don't want a buffer to remain used for the diff do ":set
+nodiff" before hiding it.
+
+							*:diffu* *:diffupdate*
+:diffu[pdate]			Update the diff highlighting and folds.
+
+Vim attempts to keep the differences updated when you make changes to the
+text.  This mostly takes care of inserted and deleted lines.  Changes within a
+line and more complicated changes do not cause the differences to be updated.
+To force the differences to be updated use: >
+
+	:diffupdate
+
+
+Vim will show filler lines for lines that are missing in one window but are
+present in another.  These lines were inserted in another file or deleted in
+this file.  Removing "filler" from the 'diffopt' option will make Vim not
+display these filler lines.
+
+
+Folds are used to hide the text that wasn't changed.  See |folding| for all
+the commands that can be used with folds.
+
+The context of lines above a difference that are not included in the fold can
+be set with the 'diffopt' option.  For example, to set the context to three
+lines: >
+
+	:set diffopt=filler,context:3
+
+
+The diffs are highlighted with these groups:
+
+|hl-DiffAdd|	DiffAdd		Added (inserted) lines.  These lines exist in
+				this buffer but not in another.
+|hl-DiffChange|	DiffChange	Changed lines.
+|hl-DiffText|	DiffText	Changed text inside a Changed line.  Vim
+				finds the first character that is different,
+				and the last character that is different
+				(searching from the end of the line).  The
+				text in between is highlighted.  This means
+				that parts in the middle that are still the
+				same are highlighted anyway.  Only "iwhite" of
+				'diffopt' is used here.
+|hl-DiffDelete| DiffDelete	Deleted lines.  Also called filler lines,
+				because they don't really exist in this
+				buffer.
+
+==============================================================================
+3. Jumping to diffs					*jumpto-diffs*
+
+Two commands can be used to jump to diffs:
+								*[c*
+	[c		Jump backwards to the previous start of a change.
+			When a count is used, do it that many times.
+								*]c*
+	]c		Jump forwards to the next start of a change.
+			When a count is used, do it that many times.
+
+It is an error if there is no change for the cursor to move to.
+
+==============================================================================
+4. Diff copying			*copy-diffs* *E99* *E100* *E101* *E102* *E103*
+								*merge*
+There are two commands to copy text from one buffer to another.  The result is
+that the buffers will be equal within the specified range.
+
+							*:diffg* *:diffget*
+:[range]diffg[et] [bufspec]
+		Modify the current buffer to undo difference with another
+		buffer.  If [bufspec] is given, that buffer is used.
+		Otherwise this only works if there is one other buffer in diff
+		mode.
+		See below for [range].
+
+						*:diffpu* *:diffput* *E793*
+:[range]diffpu[t] [bufspec]
+		Modify another buffer to undo difference with the current
+		buffer.  Just like ":diffget" but the other buffer is modified
+		instead of the current one.
+		When [bufspec] is omitted and there is more than one other
+		buffer in diff mode where 'modifiable' is set this fails.
+		See below for [range].
+
+							*do*
+do		Same as ":diffget" without argument or range.  The "o" stands
+		for "obtain" ("dg" can't be used, it could be the start of
+		"dgg"!).
+
+							*dp*
+dp		Same as ":diffput" without argument or range.
+
+When no [range] is given, the diff at the cursor position or just above it is
+affected.  When [range] is used, Vim tries to only put or get the specified
+lines.  When there are deleted lines, this may not always be possible.
+
+There can be deleted lines below the last line of the buffer.  When the cursor
+is on the last line in the buffer and there is no diff above this line, the
+":diffget" and "do" commands will obtain lines from the other buffer.
+
+To be able to get those lines from another buffer in a [range] it's allowed to
+use the last line number plus one.  This command gets all diffs from the other
+buffer: >
+
+	:1,$+1diffget
+
+Note that deleted lines are displayed, but not counted as text lines.  You
+can't move the cursor into them.  To fill the deleted lines with the lines
+from another buffer use ":diffget" on the line below them.
+								*E787*
+When the buffer that is about to be modified is read-only and the autocommand
+that is triggered by |FileChangedRO| changes buffers the command will fail.
+The autocommand must not change buffers.
+
+The [bufspec] argument above can be a buffer number, a pattern for a buffer
+name or a part of a buffer name.  Examples:
+
+	:diffget		Use the other buffer which is in diff mode
+	:diffget 3		Use buffer 3
+	:diffget v2		Use the buffer which matches "v2" and is in
+				diff mode (e.g., "file.c.v2")
+
+==============================================================================
+5. Diff options						*diff-options*
+
+Also see |'diffopt'| and the "diff" item of |'fillchars'|.
+
+
+FINDING THE DIFFERENCES					*diff-diffexpr*
+
+The 'diffexpr' option can be set to use something else than the standard
+"diff" program to compare two files and find the differences.
+
+When 'diffexpr' is empty, Vim uses this command to find the differences
+between file1 and file2: >
+
+	diff file1 file2 > outfile
+
+The ">" is replaced with the value of 'shellredir'.
+
+The output of "diff" must be a normal "ed" style diff.  Do NOT use a context
+diff.  This example explains the format that Vim expects: >
+
+	1a2
+	> bbb
+	4d4
+	< 111
+	7c7
+	< GGG
+	---
+	> ggg
+
+The "1a2" item appends the line "bbb".
+The "4d4" item deletes the line "111".
+The '7c7" item replaces the line "GGG" with "ggg".
+
+When 'diffexpr' is not empty, Vim evaluates to obtain a diff file in the
+format mentioned.  These variables are set to the file names used:
+
+	v:fname_in		original file
+	v:fname_new		new version of the same file
+	v:fname_out		resulting diff file
+
+Additionally, 'diffexpr' should take care of "icase" and "iwhite" in the
+'diffopt' option.  'diffexpr' cannot change the value of 'lines' and
+'columns'.
+
+Example (this does almost the same as 'diffexpr' being empty): >
+
+	set diffexpr=MyDiff()
+	function MyDiff()
+	   let opt = ""
+	   if &diffopt =~ "icase"
+	     let opt = opt . "-i "
+	   endif
+	   if &diffopt =~ "iwhite"
+	     let opt = opt . "-b "
+	   endif
+	   silent execute "!diff -a --binary " . opt . v:fname_in . " " . v:fname_new .
+		\  " > " . v:fname_out
+	endfunction
+
+The "-a" argument is used to force comparing the files as text, comparing as
+binaries isn't useful.  The "--binary" argument makes the files read in binary
+mode, so that a CTRL-Z doesn't end the text on DOS.
+
+						*E97*
+Vim will do a test if the diff output looks alright.  If it doesn't, you will
+get an error message.  Possible causes:
+-  The "diff" program cannot be executed.
+-  The "diff" program doesn't produce normal "ed" style diffs (see above).
+-  The 'shell' and associated options are not set correctly.  Try if filtering
+   works with a command like ":!sort".
+-  You are using 'diffexpr' and it doesn't work.
+If it's not clear what the problem is set the 'verbose' option to one or more
+to see more messages.
+
+The self-installing Vim includes a diff program.  If you don't have it you
+might want to download a diff.exe.  For example from
+http://jlb.twu.net/code/unixkit.php.
+
+
+USING PATCHES					*diff-patchexpr*
+
+The 'patchexpr' option can be set to use something else than the standard
+"patch" program.
+
+When 'patchexpr' is empty, Vim will call the "patch" program like this: >
+
+	patch -o outfile origfile < patchfile
+
+This should work fine with most versions of the "patch" program.  Note that a
+CR in the middle of a line may cause problems, it is seen as a line break.
+
+If the default doesn't work for you, set the 'patchexpr' to an expression that
+will have the same effect.  These variables are set to the file names used:
+
+	v:fname_in		original file
+	v:fname_diff		patch file
+	v:fname_out		resulting patched file
+
+Example (this does the same as 'patchexpr' being empty): >
+
+	set patchexpr=MyPatch()
+	function MyPatch()
+	   :call system("patch -o " . v:fname_out . " " . v:fname_in .
+	   \  " < " . v:fname_diff)
+	endfunction
+
+Make sure that using the "patch" program doesn't have unwanted side effects.
+For example, watch out for additionally generated files, which should be
+deleted.  It should just patch the file and nothing else.
+   Vim will change directory to "/tmp" or another temp directory before
+evaluating 'patchexpr'.  This hopefully avoids that files in the current
+directory are accidentally patched.  Vim will also delete files starting with
+v:fname_in and ending in ".rej" and ".orig".
+
+ vim:tw=78:ts=8:ft=help:norl:
--- /dev/null
+++ b/lib/vimfiles/doc/digraph.txt
@@ -1,0 +1,348 @@
+*digraph.txt*   For Vim version 7.1.  Last change: 2006 Jul 18
+
+
+		  VIM REFERENCE MANUAL    by Bram Moolenaar
+
+
+Digraphs						*digraphs* *Digraphs*
+
+Digraphs are used to enter characters that normally cannot be entered by
+an ordinary keyboard.  These are mostly accented characters which have the
+eighth bit set.  The digraphs are easier to remember than the decimal number
+that can be entered with CTRL-V (see |i_CTRL-V|).
+
+There is a brief introduction on digraphs in the user manual: |24.9|
+An alternative is using the 'keymap' option.
+
+1. Defining digraphs	|digraphs-define|
+2. Using digraphs	|digraphs-use|
+3. Default digraphs	|digraphs-default|
+
+{Vi does not have any of these commands}
+
+==============================================================================
+1. Defining digraphs					*digraphs-define*
+
+						*:dig* *:digraphs*
+:dig[raphs]		show currently defined digraphs.
+							*E104* *E39*
+:dig[raphs] {char1}{char2} {number} ...
+			Add digraph {char1}{char2} to the list.  {number} is
+			the decimal representation of the character.  Normally
+			it is the Unicode character, see |digraph-encoding|.
+			Example: >
+	:digr e: 235 a: 228
+<			Avoid defining a digraph with '_' (underscore) as the
+			first character, it has a special meaning in the
+			future.
+
+Vim is normally compiled with the |+digraphs| feature.  If the feature is
+disabled, the ":digraph" command will display an error message.
+
+Example of the output of ":digraphs": >
+ TH �  222  ss �  223  a! �  224  a' �  225  a> �  226  a? �  227  a: �  228
+
+The first two characters in each column are the characters you have to type to
+enter the digraph.
+
+In the middle of each column is the resulting character.  This may be mangled
+if you look at it on a system that does not support digraphs or if you print
+this file.
+
+							*digraph-encoding*
+The decimal number normally is the Unicode number of the character.  Note that
+the meaning doesn't change when 'encoding' changes.  The character will be
+converted from Unicode to 'encoding' when needed.  This does require the
+conversion to be available, it might fail.
+
+When Vim was compiled without the +multi_byte feature, you need to specify the
+character in the encoding given with 'encoding'.  You might want to use
+something like this: >
+
+	if has("multi_byte")
+		digraph oe 339
+	elseif &encoding == "iso-8859-15"
+		digraph oe 189
+	endif
+
+This defines the "oe" digraph for a character that is number 339 in Unicode
+and 189 in latin9 (iso-8859-15).
+
+==============================================================================
+2. Using digraphs					*digraphs-use*
+
+There are two methods to enter digraphs:			*i_digraph*
+	CTRL-K {char1} {char2}		or
+	{char1} <BS> {char2}
+The first is always available; the second only when the 'digraph' option is
+set.
+
+If a digraph with {char1}{char2} does not exist, Vim searches for a digraph
+{char2}{char1}.  This helps when you don't remember which character comes
+first.
+
+Note that when you enter CTRL-K {char1}, where {char1} is a special key, Vim
+enters the code for that special key.  This is not a digraph.
+
+Once you have entered the digraph, Vim treats the character like a normal
+character that occupies only one character in the file and on the screen.
+Example: >
+	'B' <BS> 'B'	will enter the broken '|' character (166)
+	'a' <BS> '>'	will enter an 'a' with a circumflex (226)
+	CTRL-K '-' '-'	will enter a soft hyphen (173)
+
+The current digraphs are listed with the ":digraphs" command.  Some of the
+default ones are listed below |digraph-table|.
+
+For CTRL-K, there is one general digraph: CTRL-K <Space> {char} will enter
+{char} with the highest bit set.  You can use this to enter meta-characters.
+
+The <Esc> character cannot be part of a digraph.  When hitting <Esc>, Vim
+stops digraph entry and ends Insert mode or Command-line mode, just like
+hitting an <Esc> out of digraph context.  Use CTRL-V 155 to enter meta-ESC
+(CSI).
+
+If you accidentally typed an 'a' that should be an 'e', you will type 'a' <BS>
+'e'.  But that is a digraph, so you will not get what you want.  To correct
+this, you will have to type <BS> e again.  To avoid this don't set the
+'digraph' option and use CTRL-K to enter digraphs.
+
+You may have problems using Vim with characters which have a value above 128.
+For example: You insert ue (u-umlaut) and the editor echoes \334 in Insert
+mode.  After leaving the Insert mode everything is fine.  Note that fmt
+removes all characters with a value above 128 from the text being formatted.
+On some Unix systems this means you have to define the environment-variable
+LC_CTYPE.  If you are using csh, then put the following line in your .cshrc: >
+	setenv LC_CTYPE iso_8859_1
+
+==============================================================================
+3. Default digraphs					*digraphs-default*
+
+Vim comes with a set of default digraphs.  Check the output of ":digraphs" to
+see them.
+
+On most systems Vim uses the same digraphs.  They work for the Unicode and
+ISO-8859-1 character sets.  These default digraphs are taken from the RFC1345
+mnemonics.  To make it easy to remember the mnemonic, the second character has
+a standard meaning:
+
+	char name		char	meaning ~
+	Exclamation mark	!	Grave
+	Apostrophe		'	Acute accent
+	Greater-Than sign	>	Circumflex accent
+	Question Mark		?	tilde
+	Hyphen-Minus		-	Macron
+	Left parenthesis	(	Breve
+	Full Stop		.	Dot Above
+	Colon			:	Diaeresis
+	Comma			,	Cedilla
+	Underline		_	Underline
+	Solidus			/	Stroke
+	Quotation mark		"	Double acute accent
+	Semicolon		;	Ogonek
+	Less-Than sign		<	Caron
+	Zero			0	Ring above
+	Two			2	Hook
+	Nine			9	Horn
+
+	Equals			=	Cyrillic
+	Asterisk		*	Greek
+	Percent sign		%	Greek/Cyrillic special
+	Plus			+	smalls: Arabic, capitals: Hebrew
+	Three			3	some Latin/Greek/Cyrillic letters
+	Four			4	Bopomofo
+	Five			5	Hiragana
+	Six			6	Katakana
+
+Example: a: is �  and o: is +
+These are the RFC1345 digraphs for the one-byte characters.  See the output of
+":digraphs" for the others.  The characters above 255 are only available when
+Vim was compiled with the |+multi_byte| feature.
+
+EURO
+
+Exception: RFC1345 doesn't specify the euro sign.  In Vim the digraph =e was
+added for this.  Note the difference between latin1, where the digraph Cu is
+used for the currency sign, and latin9 (iso-8859-15), where the digraph =e is
+used for the euro sign, while both of them are the character 164, 0xa4.  For
+compatibility with zsh Eu can also be used for the euro sign.
+
+							*digraph-table*
+char  digraph	hex	dec	official name ~
+^@	NU	0x00	  0	NULL (NUL)
+^A	SH	0x01	  1	START OF HEADING (SOH)
+^B	SX	0x02	  2	START OF TEXT (STX)
+^C	EX	0x03	  3	END OF TEXT (ETX)
+^D	ET	0x04	  4	END OF TRANSMISSION (EOT)
+^E	EQ	0x05	  5	ENQUIRY (ENQ)
+^F	AK	0x06	  6	ACKNOWLEDGE (ACK)
+^G	BL	0x07	  7	BELL (BEL)
+^H	BS	0x08	  8	BACKSPACE (BS)
+^I	HT	0x09	  9	CHARACTER TABULATION (HT)
+^@	LF	0x0a	 10	LINE FEED (LF)
+^K	VT	0x0b	 11	LINE TABULATION (VT)
+^L	FF	0x0c	 12	FORM FEED (FF)
+^M	CR	0x0d	 13	CARRIAGE RETURN (CR)
+^N	SO	0x0e	 14	SHIFT OUT (SO)
+^O	SI	0x0f	 15	SHIFT IN (SI)
+^P	DL	0x10	 16	DATALINK ESCAPE (DLE)
+^Q	D1	0x11	 17	DEVICE CONTROL ONE (DC1)
+^R	D2	0x12	 18	DEVICE CONTROL TWO (DC2)
+^S	D3	0x13	 19	DEVICE CONTROL THREE (DC3)
+^T	D4	0x14	 20	DEVICE CONTROL FOUR (DC4)
+^U	NK	0x15	 21	NEGATIVE ACKNOWLEDGE (NAK)
+^V	SY	0x16	 22	SYNCHRONOUS IDLE (SYN)
+^W	EB	0x17	 23	END OF TRANSMISSION BLOCK (ETB)
+^X	CN	0x18	 24	CANCEL (CAN)
+^Y	EM	0x19	 25	END OF MEDIUM (EM)
+^Z	SB	0x1a	 26	SUBSTITUTE (SUB)
+^[	EC	0x1b	 27	ESCAPE (ESC)
+^\	FS	0x1c	 28	FILE SEPARATOR (IS4)
+^]	GS	0x1d	 29	GROUP SEPARATOR (IS3)
+^^	RS	0x1e	 30	RECORD SEPARATOR (IS2)
+^_	US	0x1f	 31	UNIT SEPARATOR (IS1)
+	SP	0x20	 32	SPACE
+#	Nb	0x23	 35	NUMBER SIGN
+$	DO	0x24	 36	DOLLAR SIGN
+@	At	0x40	 64	COMMERCIAL AT
+[	<(	0x5b	 91	LEFT SQUARE BRACKET
+\	//	0x5c	 92	REVERSE SOLIDUS
+]	)>	0x5d	 93	RIGHT SQUARE BRACKET
+^	'>	0x5e	 94	CIRCUMFLEX ACCENT
+`	'!	0x60	 96	GRAVE ACCENT
+{	(!	0x7b	123	LEFT CURLY BRACKET
+|	!!	0x7c	124	VERTICAL LINE
+}	!)	0x7d	125	RIGHT CURLY BRACKET
+~	'?	0x7e	126	TILDE
+^?	DT	0x7f	127	DELETE (DEL)
+~@	PA	0x80	128	PADDING CHARACTER (PAD)
+~A	HO	0x81	129	HIGH OCTET PRESET (HOP)
+~B	BH	0x82	130	BREAK PERMITTED HERE (BPH)
+~C	NH	0x83	131	NO BREAK HERE (NBH)
+~D	IN	0x84	132	INDEX (IND)
+~E	NL	0x85	133	NEXT LINE (NEL)
+~F	SA	0x86	134	START OF SELECTED AREA (SSA)
+~G	ES	0x87	135	END OF SELECTED AREA (ESA)
+~H	HS	0x88	136	CHARACTER TABULATION SET (HTS)
+~I	HJ	0x89	137	CHARACTER TABULATION WITH JUSTIFICATION (HTJ)
+~J	VS	0x8a	138	LINE TABULATION SET (VTS)
+~K	PD	0x8b	139	PARTIAL LINE FORWARD (PLD)
+~L	PU	0x8c	140	PARTIAL LINE BACKWARD (PLU)
+~M	RI	0x8d	141	REVERSE LINE FEED (RI)
+~N	S2	0x8e	142	SINGLE-SHIFT TWO (SS2)
+~O	S3	0x8f	143	SINGLE-SHIFT THREE (SS3)
+~P	DC	0x90	144	DEVICE CONTROL STRING (DCS)
+~Q	P1	0x91	145	PRIVATE USE ONE (PU1)
+~R	P2	0x92	146	PRIVATE USE TWO (PU2)
+~S	TS	0x93	147	SET TRANSMIT STATE (STS)
+~T	CC	0x94	148	CANCEL CHARACTER (CCH)
+~U	MW	0x95	149	MESSAGE WAITING (MW)
+~V	SG	0x96	150	START OF GUARDED AREA (SPA)
+~W	EG	0x97	151	END OF GUARDED AREA (EPA)
+~X	SS	0x98	152	START OF STRING (SOS)
+~Y	GC	0x99	153	SINGLE GRAPHIC CHARACTER INTRODUCER (SGCI)
+~Z	SC	0x9a	154	SINGLE CHARACTER INTRODUCER (SCI)
+~[	CI	0x9b	155	CONTROL SEQUENCE INTRODUCER (CSI)
+~\	ST	0x9c	156	STRING TERMINATOR (ST)
+~]	OC	0x9d	157	OPERATING SYSTEM COMMAND (OSC)
+~^	PM	0x9e	158	PRIVACY MESSAGE (PM)
+~_	AC	0x9f	159	APPLICATION PROGRAM COMMAND (APC)
+|	NS	0xa0	160	NO-BREAK SPACE
+�	!I	0xa1	161	INVERTED EXCLAMATION MARK
+�	Ct	0xa2	162	CENT SIGN
+�	Pd	0xa3	163	POUND SIGN
+�	Cu	0xa4	164	CURRENCY SIGN
+�	Ye	0xa5	165	YEN SIGN
+�	BB	0xa6	166	BROKEN BAR
+�	SE	0xa7	167	SECTION SIGN
+�	':	0xa8	168	DIAERESIS
+�	Co	0xa9	169	COPYRIGHT SIGN
+�	-a	0xaa	170	FEMININE ORDINAL INDICATOR
+�	<<	0xab	171	LEFT-POINTING DOUBLE ANGLE QUOTATION MARK
+�	NO	0xac	172	NOT SIGN
+�	--	0xad	173	SOFT HYPHEN
+�	Rg	0xae	174	REGISTERED SIGN
+�	'm	0xaf	175	MACRON
+�	DG	0xb0	176	DEGREE SIGN
+�	+-	0xb1	177	PLUS-MINUS SIGN
+�	2S	0xb2	178	SUPERSCRIPT TWO
+�	3S	0xb3	179	SUPERSCRIPT THREE
+�	''	0xb4	180	ACUTE ACCENT
+�	My	0xb5	181	MICRO SIGN
+�	PI	0xb6	182	PILCROW SIGN
+�	.M	0xb7	183	MIDDLE DOT
+�	',	0xb8	184	CEDILLA
+�	1S	0xb9	185	SUPERSCRIPT ONE
+�	-o	0xba	186	MASCULINE ORDINAL INDICATOR
+�	>>	0xbb	187	RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK
+�	14	0xbc	188	VULGAR FRACTION ONE QUARTER
+�	12	0xbd	189	VULGAR FRACTION ONE HALF
+�	34	0xbe	190	VULGAR FRACTION THREE QUARTERS
+�	?I	0xbf	191	INVERTED QUESTION MARK
+�	A!	0xc0	192	LATIN CAPITAL LETTER A WITH GRAVE
+�	A'	0xc1	193	LATIN CAPITAL LETTER A WITH ACUTE
+�	A>	0xc2	194	LATIN CAPITAL LETTER A WITH CIRCUMFLEX
+�	A?	0xc3	195	LATIN CAPITAL LETTER A WITH TILDE
+�	A:	0xc4	196	LATIN CAPITAL LETTER A WITH DIAERESIS
+�	AA	0xc5	197	LATIN CAPITAL LETTER A WITH RING ABOVE
+�	AE	0xc6	198	LATIN CAPITAL LETTER AE
+�	C,	0xc7	199	LATIN CAPITAL LETTER C WITH CEDILLA
+�	E!	0xc8	200	LATIN CAPITAL LETTER E WITH GRAVE
+�	E'	0xc9	201	LATIN CAPITAL LETTER E WITH ACUTE
+�	E>	0xca	202	LATIN CAPITAL LETTER E WITH CIRCUMFLEX
+�	E:	0xcb	203	LATIN CAPITAL LETTER E WITH DIAERESIS
+�	I!	0xcc	204	LATIN CAPITAL LETTER I WITH GRAVE
+�	I'	0xcd	205	LATIN CAPITAL LETTER I WITH ACUTE
+�	I>	0xce	206	LATIN CAPITAL LETTER I WITH CIRCUMFLEX
+�	I:	0xcf	207	LATIN CAPITAL LETTER I WITH DIAERESIS
+�	D-	0xd0	208	LATIN CAPITAL LETTER ETH (Icelandic)
+�	N?	0xd1	209	LATIN CAPITAL LETTER N WITH TILDE
+�	O!	0xd2	210	LATIN CAPITAL LETTER O WITH GRAVE
+�	O'	0xd3	211	LATIN CAPITAL LETTER O WITH ACUTE
+�	O>	0xd4	212	LATIN CAPITAL LETTER O WITH CIRCUMFLEX
+�	O?	0xd5	213	LATIN CAPITAL LETTER O WITH TILDE
+�	O:	0xd6	214	LATIN CAPITAL LETTER O WITH DIAERESIS
+�	*X	0xd7	215	MULTIPLICATION SIGN
+�	O/	0xd8	216	LATIN CAPITAL LETTER O WITH STROKE
+�	U!	0xd9	217	LATIN CAPITAL LETTER U WITH GRAVE
+�	U'	0xda	218	LATIN CAPITAL LETTER U WITH ACUTE
+�	U>	0xdb	219	LATIN CAPITAL LETTER U WITH CIRCUMFLEX
+�	U:	0xdc	220	LATIN CAPITAL LETTER U WITH DIAERESIS
+�	Y'	0xdd	221	LATIN CAPITAL LETTER Y WITH ACUTE
+�	TH	0xde	222	LATIN CAPITAL LETTER THORN (Icelandic)
+�	ss	0xdf	223	LATIN SMALL LETTER SHARP S (German)
+�	a!	0xe0	224	LATIN SMALL LETTER A WITH GRAVE
+�	a'	0xe1	225	LATIN SMALL LETTER A WITH ACUTE
+�	a>	0xe2	226	LATIN SMALL LETTER A WITH CIRCUMFLEX
+�	a?	0xe3	227	LATIN SMALL LETTER A WITH TILDE
+�	a:	0xe4	228	LATIN SMALL LETTER A WITH DIAERESIS
+�	aa	0xe5	229	LATIN SMALL LETTER A WITH RING ABOVE
+�	ae	0xe6	230	LATIN SMALL LETTER AE
+�	c,	0xe7	231	LATIN SMALL LETTER C WITH CEDILLA
+�	e!	0xe8	232	LATIN SMALL LETTER E WITH GRAVE
+�	e'	0xe9	233	LATIN SMALL LETTER E WITH ACUTE
+�	e>	0xea	234	LATIN SMALL LETTER E WITH CIRCUMFLEX
+�	e:	0xeb	235	LATIN SMALL LETTER E WITH DIAERESIS
+�	i!	0xec	236	LATIN SMALL LETTER I WITH GRAVE
+�	i'	0xed	237	LATIN SMALL LETTER I WITH ACUTE
+�	i>	0xee	238	LATIN SMALL LETTER I WITH CIRCUMFLEX
+�	i:	0xef	239	LATIN SMALL LETTER I WITH DIAERESIS
+�	d-	0xf0	240	LATIN SMALL LETTER ETH (Icelandic)
+�	n?	0xf1	241	LATIN SMALL LETTER N WITH TILDE
+�	o!	0xf2	242	LATIN SMALL LETTER O WITH GRAVE
+�	o'	0xf3	243	LATIN SMALL LETTER O WITH ACUTE
+�	o>	0xf4	244	LATIN SMALL LETTER O WITH CIRCUMFLEX
+�	o?	0xf5	245	LATIN SMALL LETTER O WITH TILDE
+�	o:	0xf6	246	LATIN SMALL LETTER O WITH DIAERESIS
+�	-:	0xf7	247	DIVISION SIGN
+�	o/	0xf8	248	LATIN SMALL LETTER O WITH STROKE
+�	u!	0xf9	249	LATIN SMALL LETTER U WITH GRAVE
+�	u'	0xfa	250	LATIN SMALL LETTER U WITH ACUTE
+�	u>	0xfb	251	LATIN SMALL LETTER U WITH CIRCUMFLEX
+�	u:	0xfc	252	LATIN SMALL LETTER U WITH DIAERESIS
+�	y'	0xfd	253	LATIN SMALL LETTER Y WITH ACUTE
+�	th	0xfe	254	LATIN SMALL LETTER THORN (Icelandic)
+�	y:	0xff	255	LATIN SMALL LETTER Y WITH DIAERESIS
+
+ vim:tw=78:ts=8:ft=help:norl:
--- /dev/null
+++ b/lib/vimfiles/doc/doctags.c
@@ -1,0 +1,83 @@
+/* vim:set ts=4 sw=4:
+ * this program makes a tags file for vim_ref.txt
+ *
+ * Usage: doctags vim_ref.txt vim_win.txt ... >tags
+ *
+ * A tag in this context is an identifier between stars, e.g. *c_files*
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <ctype.h>
+#include <stdlib.h>
+
+#define LINELEN 200
+
+	int
+main(argc, argv)
+	int		argc;
+	char	**argv;
+{
+	char	line[LINELEN];
+	char	*p1, *p2;
+	char	*p;
+	FILE	*fd;
+
+	if (argc <= 1)
+	{
+		fprintf(stderr, "Usage: doctags docfile ... >tags\n");
+		exit(1);
+	}
+	printf("help-tags\ttags\t1\n");
+	while (--argc > 0)
+	{
+		++argv;
+		fd = fopen(argv[0], "r");
+		if (fd == NULL)
+		{
+			fprintf(stderr, "Unable to open %s for reading\n", argv[0]);
+			continue;
+		}
+		while (fgets(line, LINELEN, fd) != NULL)
+		{
+			p1 = strchr(line, '*');				/* find first '*' */
+			while (p1 != NULL)
+			{
+				p2 = strchr(p1 + 1, '*');		/* find second '*' */
+				if (p2 != NULL && p2 > p1 + 1)	/* skip "*" and "**" */
+				{
+					for (p = p1 + 1; p < p2; ++p)
+						if (*p == ' ' || *p == '\t' || *p == '|')
+							break;
+					/*
+					 * Only accept a *tag* when it consists of valid
+					 * characters, there is white space before it and is
+					 * followed by a white character or end-of-line.
+					 */
+					if (p == p2
+							&& (p1 == line || p1[-1] == ' ' || p1[-1] == '\t')
+								&& (strchr(" \t\n\r", p[1]) != NULL
+									|| p[1] == '\0'))
+					{
+						*p2 = '\0';
+						++p1;
+						printf("%s\t%s\t/*", p1, argv[0]);
+						while (*p1)
+						{
+							/* insert backslash before '\\' and '/' */
+							if (*p1 == '\\' || *p1 == '/')
+								putchar('\\');
+							putchar(*p1);
+							++p1;
+						}
+						printf("*\n");
+						p2 = strchr(p2 + 1, '*');		/* find next '*' */
+					}
+				}
+				p1 = p2;
+			}
+		}
+		fclose(fd);
+	}
+	return 0;
+}
--- /dev/null
+++ b/lib/vimfiles/doc/editing.txt
@@ -1,0 +1,1555 @@
+*editing.txt*   For Vim version 7.1.  Last change: 2007 May 11
+
+
+		  VIM REFERENCE MANUAL    by Bram Moolenaar
+
+
+Editing files						*edit-files*
+
+1.  Introduction		|edit-intro|
+2.  Editing a file		|edit-a-file|
+3.  The argument list		|argument-list|
+4.  Writing			|writing|
+5.  Writing and quitting	|write-quit|
+6.  Dialogs			|edit-dialogs|
+7.  The current directory	|current-directory|
+8.  Editing binary files	|edit-binary|
+9.  Encryption			|encryption|
+10. Timestamps			|timestamps|
+11. File Searching		|file-searching|
+
+==============================================================================
+1. Introduction						*edit-intro*
+
+Editing a file with Vim means:
+
+1. reading the file into a buffer
+2. changing the buffer with editor commands
+3. writing the buffer into a file
+
+							*current-file*
+As long as you don't write the buffer, the original file remains unchanged.
+If you start editing a file (read a file into the buffer), the file name is
+remembered as the "current file name".  This is also known as the name of the
+current buffer.  It can be used with "%" on the command line |:_%|.
+
+							*alternate-file*
+If there already was a current file name, then that one becomes the alternate
+file name.  It can be used with "#" on the command line |:_#| and you can use
+the |CTRL-^| command to toggle between the current and the alternate file.
+However, the alternate file name is not changed when |:keepalt| is used.
+
+							*:keepalt* *:keepa*
+:keepalt {cmd}		Execute {cmd} while keeping the current alternate file
+			name.  Note that commands invoked indirectly (e.g.,
+			with a function) may still set the alternate file
+			name.  {not in Vi}
+
+All file names are remembered in the buffer list.  When you enter a file name,
+for editing (e.g., with ":e filename") or writing (e.g., with ":w filename"),
+the file name is added to the list.  You can use the buffer list to remember
+which files you edited and to quickly switch from one file to another (e.g.,
+to copy text) with the |CTRL-^| command.  First type the number of the file
+and then hit CTRL-^.  {Vi: only one alternate file name is remembered}
+
+
+CTRL-G		or				*CTRL-G* *:f* *:fi* *:file*
+:f[ile]			Prints the current file name (as typed, unless ":cd"
+			was used), the cursor position (unless the 'ruler'
+			option is set), and the file status (readonly,
+			modified, read errors, new file).  See the 'shortmess'
+			option about how to make this message shorter.
+			{Vi does not include column number}
+
+:f[ile]!		like |:file|, but don't truncate the name even when
+			'shortmess' indicates this.
+
+{count}CTRL-G		Like CTRL-G, but prints the current file name with
+			full path.  If the count is higher than 1 the current
+			buffer number is also given.  {not in Vi}
+
+					*g_CTRL-G* *word-count* *byte-count*
+g CTRL-G		Prints the current position of the cursor in five
+			ways: Column, Line, Word, Character and Byte.  If the
+			number of Characters and Bytes is the same then the
+			Character position is omitted.
+			If there are characters in the line that take more
+			than one position on the screen (<Tab> or special
+			character), both the "real" column and the screen
+			column are shown, separated with a dash.
+			See also 'ruler' option.  {not in Vi}
+
+							*v_g_CTRL-G*
+{Visual}g CTRL-G	Similar to "g CTRL-G", but Word, Character, Line, and
+			Byte counts for the visually selected region are
+			displayed.
+			In Blockwise mode, Column count is also shown.  (For
+			{Visual} see |Visual-mode|.)
+			{not in VI}
+
+							*:file_f*
+:f[ile][!] {name}	Sets the current file name to {name}.  The optional !
+			avoids truncating the message, as with |:file|.
+			If the buffer did have a name, that name becomes the
+			|alternate-file| name.  An unlisted buffer is created
+			to hold the old name.
+							*:0file*
+:0f[ile][!]		Remove the name of the current buffer.  The optional !
+			avoids truncating the message, as with |:file|.  {not
+			in Vi}
+
+:buffers
+:files
+:ls			List all the currently known file names.  See
+			'windows.txt' |:files| |:buffers| |:ls|.  {not in
+			Vi}
+
+Vim will remember the full path name of a file name that you enter.  In most
+cases when the file name is displayed only the name you typed is shown, but
+the full path name is being used if you used the ":cd" command |:cd|.
+
+							*home-replace*
+If the environment variable $HOME is set, and the file name starts with that
+string, it is often displayed with HOME replaced with "~".  This was done to
+keep file names short.  When reading or writing files the full name is still
+used, the "~" is only used when displaying file names.  When replacing the
+file name would result in just "~", "~/" is used instead (to avoid confusion
+between options set to $HOME with 'backupext' set to "~").
+
+When writing the buffer, the default is to use the current file name.  Thus
+when you give the "ZZ" or ":wq" command, the original file will be
+overwritten.  If you do not want this, the buffer can be written into another
+file by giving a file name argument to the ":write" command.  For example: >
+
+	vim testfile
+	[change the buffer with editor commands]
+	:w newfile
+	:q
+
+This will create a file "newfile", that is a modified copy of "testfile".
+The file "testfile" will remain unchanged.  Anyway, if the 'backup' option is
+set, Vim renames or copies the original file before it will be overwritten.
+You can use this file if you discover that you need the original file.  See
+also the 'patchmode' option.  The name of the backup file is normally the same
+as the original file with 'backupext' appended.  The default "~" is a bit
+strange to avoid accidentally overwriting existing files.  If you prefer ".bak"
+change the 'backupext' option.  Extra dots are replaced with '_' on MS-DOS
+machines, when Vim has detected that an MS-DOS-like filesystem is being used
+(e.g., messydos or crossdos) or when the 'shortname' option is on.  The
+backup file can be placed in another directory by setting 'backupdir'.
+
+							*auto-shortname*
+Technical: On the Amiga you can use 30 characters for a file name.  But on an
+	   MS-DOS-compatible filesystem only 8 plus 3 characters are
+	   available.  Vim tries to detect the type of filesystem when it is
+	   creating the .swp file.  If an MS-DOS-like filesystem is suspected,
+	   a flag is set that has the same effect as setting the 'shortname'
+	   option.  This flag will be reset as soon as you start editing a
+	   new file.  The flag will be used when making the file name for the
+	   ".swp" and ".~" files for the current file.  But when you are
+	   editing a file in a normal filesystem and write to an MS-DOS-like
+	   filesystem the flag will not have been set.  In that case the
+	   creation of the ".~" file may fail and you will get an error
+	   message.  Use the 'shortname' option in this case.
+
+When you started editing without giving a file name, "No File" is displayed in
+messages.  If the ":write" command is used with a file name argument, the file
+name for the current file is set to that file name.  This only happens when
+the 'F' flag is included in 'cpoptions' (by default it is included) |cpo-F|.
+This is useful when entering text in an empty buffer and then writing it to a
+file.  If 'cpoptions' contains the 'f' flag (by default it is NOT included)
+|cpo-f| the file name is set for the ":read file" command.  This is useful
+when starting Vim without an argument and then doing ":read file" to start
+editing a file.
+When the file name was set and 'filetype' is empty the filetype detection
+autocommands will be triggered.
+							*not-edited*
+Because the file name was set without really starting to edit that file, you
+are protected from overwriting that file.  This is done by setting the
+"notedited" flag.  You can see if this flag is set with the CTRL-G or ":file"
+command.  It will include "[Not edited]" when the "notedited" flag is set.
+When writing the buffer to the current file name (with ":w!"), the "notedited"
+flag is reset.
+
+							*abandon*
+Vim remembers whether you have changed the buffer.  You are protected from
+losing the changes you made.  If you try to quit without writing, or want to
+start editing another file, Vim will refuse this.  In order to overrule this
+protection, add a '!' to the command.  The changes will then be lost.  For
+example: ":q" will not work if the buffer was changed, but ":q!" will.  To see
+whether the buffer was changed use the "CTRL-G" command.  The message includes
+the string "[Modified]" if the buffer has been changed.
+
+If you want to automatically save the changes without asking, switch on the
+'autowriteall' option.  'autowrite' is the associated Vi-compatible option
+that does not work for all commands.
+
+If you want to keep the changed buffer without saving it, switch on the
+'hidden' option.  See |hidden-buffer|.
+
+==============================================================================
+2. Editing a file					*edit-a-file*
+
+							*:e* *:edit*
+:e[dit] [++opt] [+cmd]	Edit the current file.  This is useful to re-edit the
+			current file, when it has been changed outside of Vim.
+			This fails when changes have been made to the current
+			buffer and 'autowriteall' isn't set or the file can't
+			be written.
+			Also see |++opt| and |+cmd|.
+			{Vi: no ++opt}
+
+							*:edit!*
+:e[dit]! [++opt] [+cmd]
+			Edit the current file always.  Discard any changes to
+			the current buffer.  This is useful if you want to
+			start all over again.
+			Also see |++opt| and |+cmd|.
+			{Vi: no ++opt}
+
+							*:edit_f*
+:e[dit] [++opt] [+cmd] {file}
+			Edit {file}.
+			This fails when changes have been made to the current
+			buffer, unless 'hidden' is set or 'autowriteall' is
+			set and the file can be written.
+			Also see |++opt| and |+cmd|.
+			{Vi: no ++opt}
+
+							*:edit!_f*
+:e[dit]! [++opt] [+cmd] {file}
+			Edit {file} always.  Discard any changes to the
+			current buffer.
+			Also see |++opt| and |+cmd|.
+			{Vi: no ++opt}
+
+:e[dit] [++opt] [+cmd] #[count]
+			Edit the [count]th buffer (as shown by |:files|).
+			This command does the same as [count] CTRL-^.  But ":e
+			#" doesn't work if the alternate buffer doesn't have a
+			file name, while CTRL-^ still works then.
+			Also see |++opt| and |+cmd|.
+			{Vi: no ++opt}
+
+							*:ene* *:enew*
+:ene[w]			Edit a new, unnamed buffer.  This fails when changes
+			have been made to the current buffer, unless 'hidden'
+			is set or 'autowriteall' is set and the file can be
+			written.
+			If 'fileformats' is not empty, the first format given
+			will be used for the new buffer.  If 'fileformats' is
+			empty, the 'fileformat' of the current buffer is used.
+			{not in Vi}
+
+							*:ene!* *:enew!*
+:ene[w]!		Edit a new, unnamed buffer.  Discard any changes to
+			the current buffer.
+			Set 'fileformat' like |:enew|.
+			{not in Vi}
+
+							*:fin* *:find*
+:fin[d][!] [++opt] [+cmd] {file}
+			Find {file} in 'path' and then |:edit| it.
+			{not in Vi} {not available when the |+file_in_path|
+			feature was disabled at compile time}
+
+:{count}fin[d][!] [++opt] [+cmd] {file}
+			Just like ":find", but use the {count} match in
+			'path'.  Thus ":2find file" will find the second
+			"file" found in 'path'.  When there are fewer matches
+			for the file in 'path' than asked for, you get an
+			error message.
+
+							*:ex*
+:ex [++opt] [+cmd] [file]
+			Same as |:edit|.
+
+							*:vi* *:visual*
+:vi[sual][!] [++opt] [+cmd] [file]
+			When used in Ex mode: Leave |Ex-mode|, go back to
+			Normal mode.  Otherwise same as |:edit|.
+
+							*:vie* *:view*
+:vie[w] [++opt] [+cmd] file
+			When used in Ex mode: Leave |Ex mode|, go back to
+			Normal mode.  Otherwise same as |:edit|, but set
+			'readonly' option for this buffer.  {not in Vi}
+
+							*CTRL-^* *CTRL-6*
+CTRL-^			Edit the alternate file (equivalent to ":e #").
+			Mostly the alternate file is the previously edited
+			file.  This is a quick way to toggle between two
+			files.
+			If the 'autowrite' or 'autowriteall' option is on and
+			the buffer was changed, write it.
+			Mostly the ^ character is positioned on the 6 key,
+			pressing CTRL and 6 then gets you what we call CTRL-^.
+			But on some non-US keyboards CTRL-^ is produced in
+			another way.
+
+{count}CTRL-^		Edit [count]th file in the buffer list (equivalent to
+			":e #[count]").  This is a quick way to switch between
+			files.
+			See |CTRL-^| above for further details.
+			{not in Vi}
+
+[count]]f						*]f* *[f*
+[count][f		Same as "gf".  Deprecated.
+
+							*gf* *E446* *E447*
+[count]gf		Edit the file whose name is under or after the cursor.
+			Mnemonic: "goto file".
+			Uses the 'isfname' option to find out which characters
+			are supposed to be in a file name.  Trailing
+			punctuation characters ".,:;!" are ignored.
+			Uses the 'path' option as a list of directory names
+			to look for the file.  Also looks for the file
+			relative to the current file.
+			Uses the 'suffixesadd' option to check for file names
+			with a suffix added.
+			If the file can't be found, 'includeexpr' is used to
+			modify the name and another attempt is done.
+			If a [count] is given, the count'th file that is found
+			in the 'path' is edited.
+			This command fails if Vim refuses to |abandon| the
+			current file.
+			If you want to edit the file in a new window use
+			|CTRL-W_CTRL-F|.
+			If you do want to edit a new file, use: >
+				:e <cfile>
+<			To make gf always work like that: >
+				:map gf :e <cfile><CR>
+<			If the name is a hypertext link, that looks like
+			"type://machine/path", you need the |netrw| plugin.
+			For Unix the '~' character is expanded, like in
+			"~user/file".  Environment variables are expanded too
+			|expand-env|.
+			{not in Vi}
+			{not available when the |+file_in_path| feature was
+			disabled at compile time}
+
+							*v_gf*
+{Visual}[count]gf	Same as "gf", but the highlighted text is used as the
+			name of the file to edit.  'isfname' is ignored.
+			Leading blanks are skipped, otherwise all blanks and
+			special characters are included in the file name.
+			(For {Visual} see |Visual-mode|.)
+			{not in VI}
+
+							*gF*
+[count]gF		Same as "gf", except if a number follows the file
+			name, then the cursor is positioned on that line in
+			the file. The file name and the number must be
+			separated by a non-filename (see 'isfname') and
+			non-numeric character. White space between the
+			filename, the separator and the number are ignored.
+			Examples:
+				eval.c:10 ~
+				eval.c @ 20 ~
+				eval.c (30) ~
+				eval.c 40 ~
+
+							*v_gF*
+{Visual}[count]gF	Same as "v_gf".
+
+These commands are used to start editing a single file.  This means that the
+file is read into the buffer and the current file name is set.  The file that
+is opened depends on the current directory, see |:cd|.
+
+See |read-messages| for an explanation of the message that is given after the
+file has been read.
+
+You can use the ":e!" command if you messed up the buffer and want to start
+all over again.  The ":e" command is only useful if you have changed the
+current file name.
+
+							*:filename* *{file}*
+Note for systems other than Unix and MS-DOS: When using a command that
+accepts a single file name (like ":edit file") spaces in the file name are
+allowed, but trailing spaces are ignored.  This is useful on systems that
+allow file names with embedded spaces (like MS-Windows and the Amiga).
+Example: The command ":e   Long File Name " will edit the file "Long File
+Name".  When using a command that accepts more than one file name (like ":next
+file1 file2") embedded spaces must be escaped with a backslash.
+
+						*wildcard* *wildcards*
+Wildcards in {file} are expanded.  Which wildcards are supported depends on
+the system.  These are the common ones:
+	?	matches one character
+	*	matches anything, including nothing
+	**	matches anything, including nothing, recurses into directories
+	[abc]	match 'a', 'b' or 'c'
+
+To avoid the special meaning of the wildcards prepend a backslash.  However,
+on MS-Windows the backslash is a path separator and "path\[abc]" is still seen
+as a wildcard when "[" is in the 'isfname' option.  A simple way to avoid this
+is to use "path\[[]abc]".  Then the file "path[abc]" literally.
+
+					*starstar-wildcard*
+Expanding "**" is possible on Unix, Win32, Mac OS/X and a few other systems.
+This allows searching a directory tree.  This goes up to 100 directories deep.
+Example: >
+	:n **/*.txt
+Finds files:
+	ttt.txt
+	subdir/ttt.txt
+	a/b/c/d/ttt.txt
+When non-wildcard characters are used these are only matched in the first
+directory.  Example: >
+	:n /usr/inc**/*.h
+Finds files:
+	/usr/include/types.h
+	/usr/include/sys/types.h
+	/usr/inc_old/types.h
+					*backtick-expansion* *`-expansion*
+On Unix and a few other systems you can also use backticks in the file name,
+for example: >
+	:e `find . -name ver\\*.c -print`
+The backslashes before the star are required to prevent "ver*.c" to be
+expanded by the shell before executing the find program.
+This also works for most other systems, with the restriction that the
+backticks must be around the whole item.  It is not possible to have text
+directly before the first or just after the last backtick.
+
+							*`=*
+You can have the backticks expanded as a Vim expression, instead of an
+external command, by using the syntax `={expr}` e.g.: >
+	:e `=tempname()`
+The expression can contain just about anything, thus this can also be used to
+avoid the special meaning of '"', '|', '%' and '#'.  Names are to be separated
+with line breaks.  When the result is a |List| then each item is used as a
+name.  Line breaks also separate names.
+
+							*++opt* *[++opt]*
+The [++opt] argument can be used to force the value of 'fileformat',
+'fileencoding' or 'binary' to a value for one command, and to specify the
+behavior for bad characters.  The form is: >
+	++{optname}
+Or: >
+	++{optname}={value}
+
+Where {optname} is one of:	    *++ff* *++enc* *++bin* *++nobin* *++edit*
+    ff     or  fileformat   overrides 'fileformat'
+    enc    or  encoding	    overrides 'fileencoding'
+    bin    or  binary	    sets 'binary'
+    nobin  or  nobinary	    resets 'binary'
+    bad			    specifies behavior for bad characters
+    edit		    for |:read| only: keep option values as if editing
+			    a file
+
+{value} cannot contain white space.  It can be any valid value for these
+options.  Examples: >
+	:e ++ff=unix
+This edits the same file again with 'fileformat' set to "unix". >
+
+	:w ++enc=latin1 newfile
+This writes the current buffer to "newfile" in latin1 format.
+
+There may be several ++opt arguments, separated by white space.  They must all
+appear before any |+cmd| argument.
+
+								*++bad*
+The argument of "++bad=" specifies what happens with characters that can't be
+converted and illegal bytes.  It can be one of three things:
+    ++bad=X      A single-byte character that replaces each bad character.
+    ++bad=keep   Keep bad characters without conversion.  Note that this may
+		 result in illegal bytes in your text!
+    ++bad=drop   Remove the bad characters.
+
+The default is like "++bad=?": Replace each bad character with a question
+mark.
+
+Note that when reading, the 'fileformat' and 'fileencoding' options will be
+set to the used format.  When writing this doesn't happen, thus a next write
+will use the old value of the option.  Same for the 'binary' option.
+
+
+							*+cmd* *[+cmd]*
+The [+cmd] argument can be used to position the cursor in the newly opened
+file, or execute any other command:
+	+		Start at the last line.
+	+{num}		Start at line {num}.
+	+/{pat}		Start at first line containing {pat}.
+	+{command}	Execute {command} after opening the new file.
+			{command} is any Ex command.
+To include a white space in the {pat} or {command}, precede it with a
+backslash.  Double the number of backslashes. >
+	:edit  +/The\ book	     file
+	:edit  +/dir\ dirname\\      file
+	:edit  +set\ dir=c:\\\\temp  file
+Note that in the last example the number of backslashes is halved twice: Once
+for the "+cmd" argument and once for the ":set" command.
+
+							*file-formats*
+The 'fileformat' option sets the <EOL> style for a file:
+'fileformat'    characters	   name				~
+  "dos"		<CR><NL> or <NL>   DOS format		*DOS-format*
+  "unix"	<NL>		   Unix format		*Unix-format*
+  "mac"		<CR>		   Mac format		*Mac-format*
+Previously 'textmode' was used.  It is obsolete now.
+
+When reading a file, the mentioned characters are interpreted as the <EOL>.
+In DOS format (default for MS-DOS, OS/2 and Win32), <CR><NL> and <NL> are both
+interpreted as the <EOL>.  Note that when writing the file in DOS format,
+<CR> characters will be added for each single <NL>.  Also see |file-read|.
+
+When writing a file, the mentioned characters are used for <EOL>.  For DOS
+format <CR><NL> is used.  Also see |DOS-format-write|.
+
+You can read a file in DOS format and write it in Unix format.  This will
+replace all <CR><NL> pairs by <NL> (assuming 'fileformats' includes "dos"): >
+	:e file
+	:set fileformat=unix
+	:w
+If you read a file in Unix format and write with DOS format, all <NL>
+characters will be replaced with <CR><NL> (assuming 'fileformats' includes
+"unix"): >
+	:e file
+	:set fileformat=dos
+	:w
+
+If you start editing a new file and the 'fileformats' option is not empty
+(which is the default), Vim will try to detect whether the lines in the file
+are separated by the specified formats.  When set to "unix,dos", Vim will
+check for lines with a single <NL> (as used on Unix and Amiga) or by a <CR>
+<NL> pair (MS-DOS).  Only when ALL lines end in <CR><NL>, 'fileformat' is set
+to "dos", otherwise it is set to "unix".  When 'fileformats' includes "mac",
+and no <NL> characters are found in the file, 'fileformat' is set to "mac".
+
+If the 'fileformat' option is set to "dos" on non-MS-DOS systems the message
+"[dos format]" is shown to remind you that something unusual is happening.  On
+MS-DOS systems you get the message "[unix format]" if 'fileformat' is set to
+"unix".  On all systems but the Macintosh you get the message "[mac format]"
+if 'fileformat' is set to "mac".
+
+If the 'fileformats' option is empty and DOS format is used, but while reading
+a file some lines did not end in <CR><NL>, "[CR missing]" will be included in
+the file message.
+If the 'fileformats' option is empty and Mac format is used, but while reading
+a file a <NL> was found, "[NL missing]" will be included in the file message.
+
+If the new file does not exist, the 'fileformat' of the current buffer is used
+when 'fileformats' is empty.  Otherwise the first format from 'fileformats' is
+used for the new file.
+
+Before editing binary, executable or Vim script files you should set the
+'binary' option.  A simple way to do this is by starting Vim with the "-b"
+option.  This will avoid the use of 'fileformat'.  Without this you risk that
+single <NL> characters are unexpectedly replaced with <CR><NL>.
+
+You can encrypt files that are written by setting the 'key' option.  This
+provides some security against others reading your files. |encryption|
+
+
+==============================================================================
+3. The argument list				*argument-list* *arglist*
+
+If you give more than one file name when starting Vim, this list is remembered
+as the argument list.  You can jump to each file in this list.
+
+Do not confuse this with the buffer list, which you can see with the
+|:buffers| command.  The argument list was already present in Vi, the buffer
+list is new in Vim.  Every file name in the argument list will also be present
+in the buffer list (unless it was deleted with |:bdel| or |:bwipe|).  But it's
+common that names in the buffer list are not in the argument list.
+
+This subject is introduced in section |07.2| of the user manual.
+
+There is one global argument list, which is used for all windows by default.
+It is possible to create a new argument list local to a window, see
+|:arglocal|.
+
+You can use the argument list with the following commands, and with the
+expression functions |argc()| and |argv()|.  These all work on the argument
+list of the current window.
+
+							*:ar* *:args*
+:ar[gs]			Print the argument list, with the current file in
+			square brackets.
+
+:ar[gs] [++opt] [+cmd] {arglist}			*:args_f*
+			Define {arglist} as the new argument list and edit
+			the first one.  This fails when changes have been made
+			and Vim does not want to |abandon| the current buffer.
+			Also see |++opt| and |+cmd|.
+			{Vi: no ++opt}
+
+:ar[gs]! [++opt] [+cmd] {arglist}			*:args_f!*
+			Define {arglist} as the new argument list and edit
+			the first one.  Discard any changes to the current
+			buffer.
+			Also see |++opt| and |+cmd|.
+			{Vi: no ++opt}
+
+:[count]arge[dit][!] [++opt] [+cmd] {name}		*:arge* *:argedit*
+			Add {name} to the argument list and edit it.
+			When {name} already exists in the argument list, this
+			entry is edited.
+			This is like using |:argadd| and then |:edit|.
+			Note that only one file name is allowed, and spaces
+			inside the file name are allowed, like with |:edit|.
+			[count] is used like with |:argadd|.
+			[!] is required if the current file cannot be
+			|abandon|ed.
+			Also see |++opt| and |+cmd|.
+			{not in Vi}
+
+:[count]arga[dd] {name} ..			*:arga* *:argadd* *E479*
+			Add the {name}s to the argument list.
+			If [count] is omitted, the {name}s are added just
+			after the current entry in the argument list.
+			Otherwise they are added after the [count]'th file.
+			If the argument list is "a b c", and "b" is the
+			current argument, then these commands result in:
+				command		new argument list ~
+				:argadd x	a b x c
+				:0argadd x	x a b c
+				:1argadd x	a x b c
+				:99argadd x	a b c x
+			There is no check for duplicates, it is possible to
+			add a file to the argument list twice.
+			The currently edited file is not changed.
+			{not in Vi} {not available when compiled without the
+			|+listcmds| feature}
+			Note: you can also use this method: >
+				:args ## x
+<			This will add the "x" item and sort the new list.
+
+:argd[elete] {pattern} ..			*:argd* *:argdelete* *E480*
+			Delete files from the argument list that match the
+			{pattern}s.  {pattern} is used like a file pattern,
+			see |file-pattern|.  "%" can be used to delete the
+			current entry.
+			This command keeps the currently edited file, also
+			when it's deleted from the argument list.
+			Example: >
+				:argdel *.obj
+<			{not in Vi} {not available when compiled without the
+			|+listcmds| feature}
+
+:{range}argd[elete]	Delete the {range} files from the argument list.
+			When the last number in the range is too high, up to
+			the last argument is deleted.  Example: >
+				:10,1000argdel
+<			Deletes arguments 10 and further, keeping 1-9.
+			{not in Vi} {not available when compiled without the
+			|+listcmds| feature}
+
+							*:argu* *:argument*
+:[count]argu[ment] [count] [++opt] [+cmd]
+			Edit file [count] in the argument list.  When [count]
+			is omitted the current entry is used.  This fails
+			when changes have been made and Vim does not want to
+			|abandon| the current buffer.
+			Also see |++opt| and |+cmd|.
+			{not in Vi} {not available when compiled without the
+			|+listcmds| feature}
+
+:[count]argu[ment]! [count] [++opt] [+cmd]
+			Edit file [count] in the argument list, discard any
+			changes to the current buffer.  When [count] is
+			omitted the current entry is used.
+			Also see |++opt| and |+cmd|.
+			{not in Vi} {not available when compiled without the
+			|+listcmds| feature}
+
+:[count]n[ext] [++opt] [+cmd]			*:n* *:ne* *:next* *E165* *E163*
+			Edit [count] next file.  This fails when changes have
+			been made and Vim does not want to |abandon| the
+			current buffer.  Also see |++opt| and |+cmd|.  {Vi: no
+			count or ++opt}.
+
+:[count]n[ext]! [++opt] [+cmd]
+			Edit [count] next file, discard any changes to the
+			buffer.  Also see |++opt| and |+cmd|.  {Vi: no count
+			or ++opt}.
+
+:n[ext] [++opt] [+cmd] {arglist}			*:next_f*
+			Same as |:args_f|.
+
+:n[ext]! [++opt] [+cmd] {arglist}
+			Same as |:args_f!|.
+
+:[count]N[ext] [count] [++opt] [+cmd]			*:Next* *:N* *E164*
+			Edit [count] previous file in argument list.  This
+			fails when changes have been made and Vim does not
+			want to |abandon| the current buffer.
+			Also see |++opt| and |+cmd|.  {Vi: no count or ++opt}.
+
+:[count]N[ext]! [count] [++opt] [+cmd]
+			Edit [count] previous file in argument list.  Discard
+			any changes to the buffer.  Also see |++opt| and
+			|+cmd|.  {Vi: no count or ++opt}.
+
+:[count]prev[ious] [count] [++opt] [+cmd]		*:prev* *:previous*
+			Same as :Next.  Also see |++opt| and |+cmd|.  {Vi:
+			only in some versions}
+
+							*:rew* *:rewind*
+:rew[ind] [++opt] [+cmd]
+			Start editing the first file in the argument list.
+			This fails when changes have been made and Vim does
+			not want to |abandon| the current buffer.
+			Also see |++opt| and |+cmd|. {Vi: no ++opt}
+
+:rew[ind]! [++opt] [+cmd]
+			Start editing the first file in the argument list.
+			Discard any changes to the buffer.  Also see |++opt|
+			and |+cmd|. {Vi: no ++opt}
+
+							*:fir* *:first*
+:fir[st][!] [++opt] [+cmd]
+			Other name for ":rewind". {not in Vi}
+
+							*:la* *:last*
+:la[st] [++opt] [+cmd]
+			Start editing the last file in the argument list.
+			This fails when changes have been made and Vim does
+			not want to |abandon| the current buffer.
+			Also see |++opt| and |+cmd|.  {not in Vi}
+
+:la[st]! [++opt] [+cmd]
+			Start editing the last file in the argument list.
+			Discard any changes to the buffer.  Also see |++opt|
+			and |+cmd|.  {not in Vi}
+
+							*:wn* *:wnext*
+:[count]wn[ext] [++opt] [+cmd]
+			Write current file and start editing the [count]
+			next file.  Also see |++opt| and |+cmd|.  {not in Vi}
+
+:[count]wn[ext] [++opt] [+cmd] {file}
+			Write current file to {file} and start editing the
+			[count] next file, unless {file} already exists and
+			the 'writeany' option is off.  Also see |++opt| and
+			|+cmd|.  {not in Vi}
+
+:[count]wn[ext]! [++opt] [+cmd] {file}
+			Write current file to {file} and start editing the
+			[count] next file.  Also see |++opt| and |+cmd|.  {not
+			in Vi}
+
+:[count]wN[ext][!] [++opt] [+cmd] [file]		*:wN* *:wNext*
+:[count]wp[revious][!] [++opt] [+cmd] [file]		*:wp* *:wprevious*
+			Same as :wnext, but go to previous file instead of
+			next.  {not in Vi}
+
+The [count] in the commands above defaults to one.  For some commands it is
+possible to use two counts.  The last one (rightmost one) is used.
+
+If no [+cmd] argument is present, the cursor is positioned at the last known
+cursor position for the file.  If 'startofline' is set, the cursor will be
+positioned at the first non-blank in the line, otherwise the last know column
+is used.  If there is no last known cursor position the cursor will be in the
+first line (the last line in Ex mode).
+
+							*{arglist}*
+The wildcards in the argument list are expanded and the file names are sorted.
+Thus you can use the command "vim *.c" to edit all the C files.  From within
+Vim the command ":n *.c" does the same.
+
+White space is used to separate file names.  Put a backslash before a space or
+tab to include it in a file name.  E.g., to edit the single file "foo bar": >
+	:next foo\ bar
+
+On Unix and a few other systems you can also use backticks, for example: >
+	:next `find . -name \\*.c -print`
+The backslashes before the star are required to prevent "*.c" to be expanded
+by the shell before executing the find program.
+
+							*arglist-position*
+When there is an argument list you can see which file you are editing in the
+title of the window (if there is one and 'title' is on) and with the file
+message you get with the "CTRL-G" command.  You will see something like
+	(file 4 of 11)
+If 'shortmess' contains 'f' it will be
+	(4 of 11)
+If you are not really editing the file at the current position in the argument
+list it will be
+	(file (4) of 11)
+This means that you are position 4 in the argument list, but not editing the
+fourth file in the argument list.  This happens when you do ":e file".
+
+
+LOCAL ARGUMENT LIST
+
+{not in Vi}
+{not available when compiled without the |+windows| or |+listcmds| feature}
+
+							*:arglocal*
+:argl[ocal]		Make a local copy of the global argument list.
+			Doesn't start editing another file.
+
+:argl[ocal][!] [++opt] [+cmd] {arglist}
+			Define a new argument list, which is local to the
+			current window.  Works like |:args_f| otherwise.
+
+							*:argglobal*
+:argg[lobal]		Use the global argument list for the current window.
+			Doesn't start editing another file.
+
+:argg[lobal][!] [++opt] [+cmd] {arglist}
+			Use the global argument list for the current window.
+			Define a new global argument list like |:args_f|.
+			All windows using the global argument list will see
+			this new list.
+
+There can be several argument lists.  They can be shared between windows.
+When they are shared, changing the argument list in one window will also
+change it in the other window.
+
+When a window is split the new window inherits the argument list from the
+current window.  The two windows then share this list, until one of them uses
+|:arglocal| or |:argglobal| to use another argument list.
+
+
+USING THE ARGUMENT LIST
+
+						*:argdo*
+:argdo[!] {cmd}		Execute {cmd} for each file in the argument list.
+			It works like doing this: >
+				:rewind
+				:{cmd}
+				:next
+				:{cmd}
+				etc.
+<			When the current file can't be |abandon|ed and the [!]
+			is not present, the command fails.
+			When an error is detected on one file, further files
+			in the argument list will not be visited.
+			The last file in the argument list (or where an error
+			occurred) becomes the current file.
+			{cmd} can contain '|' to concatenate several commands.
+			{cmd} must not change the argument list.
+			Note: While this command is executing, the Syntax
+			autocommand event is disabled by adding it to
+			'eventignore'.  This considerably speeds up editing
+			each file.
+			{not in Vi} {not available when compiled without the
+			|+listcmds| feature}
+			Also see |:windo|, |:tabdo| and |:bufdo|.
+
+Example: >
+	:args *.c
+	:argdo set ff=unix | update
+This sets the 'fileformat' option to "unix" and writes the file if is now
+changed.  This is done for all *.c files.
+
+Example: >
+	:args *.[ch]
+	:argdo %s/\<my_foo\>/My_Foo/ge | update
+This changes the word "my_foo" to "My_Foo" in all *.c and *.h files.  The "e"
+flag is used for the ":substitute" command to avoid an error for files where
+"my_foo" isn't used.  ":update" writes the file only if changes were made.
+
+==============================================================================
+4. Writing					*writing* *save-file*
+
+Note: When the 'write' option is off, you are not able to write any file.
+
+							*:w* *:write*
+						*E502* *E503* *E504* *E505*
+						*E512* *E514* *E667* *E796*
+:w[rite]		Write the whole buffer to the current file.  This is
+			the normal way to save changes to a file.  It fails
+			when the 'readonly' option is set or when there is
+			another reason why the file can't be written.
+
+:w[rite]!		Like ":write", but forcefully write when 'readonly' is
+			set or there is another reason why writing was
+			refused.
+			Note: This may change the permission and ownership of
+			the file and break (symbolic) links.  Add the 'W' flag
+			to 'cpoptions' to avoid this.
+
+:[range]w[rite][!]	Write the specified lines to the current file.  This
+			is unusual, because the file will not contain all
+			lines in the buffer.
+
+							*:w_f* *:write_f*
+:[range]w[rite]	{file}	Write the specified lines to {file}, unless it
+			already exists and the 'writeany' option is off.
+
+							*:w!*
+:[range]w[rite]! {file}	Write the specified lines to {file}.  Overwrite an
+			existing file.
+
+						*:w_a* *:write_a* *E494*
+:[range]w[rite][!] >>	Append the specified lines to the current file.
+
+:[range]w[rite][!] >> {file}
+			Append the specified lines to {file}.  '!' forces the
+			write even if file does not exist.
+
+							*:w_c* *:write_c*
+:[range]w[rite] !{cmd}	Execute {cmd} with [range] lines as standard input
+			(note the space in front of the '!').  {cmd} is
+			executed like with ":!{cmd}", any '!' is replaced with
+			the previous command |:!|.
+
+The default [range] for the ":w" command is the whole buffer (1,$).  If you
+write the whole buffer, it is no longer considered changed.  Also when you
+write it to a different file with ":w somefile"!
+
+If a file name is given with ":w" it becomes the alternate file.  This can be
+used, for example, when the write fails and you want to try again later with
+":w #".  This can be switched off by removing the 'A' flag from the
+'cpoptions' option.
+
+							*:sav* *:saveas*
+:sav[eas][!] {file}	Save the current buffer under the name {file} and set
+			the filename of the current buffer to {file}.  The
+			previous name is used for the alternate file name.
+			The [!] is needed to overwrite an existing file.
+			When 'filetype' is empty filetype detection is done
+			with the new name, before the file is written.
+			When the write was successful 'readonly' is reset.
+			{not in Vi}
+
+							*:up* *:update*
+:[range]up[date][!] [>>] [file]
+			Like ":write", but only write when the buffer has been
+			modified.  {not in Vi}
+
+
+WRITING WITH MULTIPLE BUFFERS				*buffer-write*
+
+							*:wa* *:wall*
+:wa[ll]			Write all changed buffers.  Buffers without a file
+			name or which are readonly are not written. {not in
+			Vi}
+
+:wa[ll]!		Write all changed buffers, even the ones that are
+			readonly.  Buffers without a file name are not
+			written. {not in Vi}
+
+
+Vim will warn you if you try to overwrite a file that has been changed
+elsewhere.  See |timestamp|.
+
+			    *backup* *E207* *E506* *E507* *E508* *E509* *E510*
+If you write to an existing file (but do not append) while the 'backup',
+'writebackup' or 'patchmode' option is on, a backup of the original file is
+made.  The file is either copied or renamed (see 'backupcopy').  After the
+file has been successfully written and when the 'writebackup' option is on and
+the 'backup' option is off, the backup file is deleted.  When the 'patchmode'
+option is on the backup file may be renamed.
+
+							*backup-table*
+'backup' 'writebackup'	action	~
+   off	     off	no backup made
+   off	     on		backup current file, deleted afterwards (default)
+   on	     off	delete old backup, backup current file
+   on	     on		delete old backup, backup current file
+
+When the 'backupskip' pattern matches with the name of the file which is
+written, no backup file is made.  The values of 'backup' and 'writebackup' are
+ignored then.
+
+When the 'backup' option is on, an old backup file (with the same name as the
+new backup file) will be deleted.  If 'backup' is not set, but 'writebackup'
+is set, an existing backup file will not be deleted.  The backup file that is
+made while the file is being written will have a different name.
+
+On some filesystems it's possible that in a crash you lose both the backup and
+the newly written file (it might be there but contain bogus data).  In that
+case try recovery, because the swap file is synced to disk and might still be
+there. |:recover|
+
+The directories given with the 'backupdir' option is used to put the backup
+file in.  (default: same directory as the written file).
+
+Whether the backup is a new file, which is a copy of the original file, or the
+original file renamed depends on the 'backupcopy' option.  See there for an
+explanation of when the copy is made and when the file is renamed.
+
+If the creation of a backup file fails, the write is not done.  If you want
+to write anyway add a '!' to the command.
+
+							*write-readonly*
+When the 'cpoptions' option contains 'W', Vim will refuse to overwrite a
+readonly file.  When 'W' is not present, ":w!" will overwrite a readonly file,
+if the system allows it (the directory must be writable).
+
+							*write-fail*
+If the writing of the new file fails, you have to be careful not to lose
+your changes AND the original file.  If there is no backup file and writing
+the new file failed, you have already lost the original file!  DON'T EXIT VIM
+UNTIL YOU WRITE OUT THE FILE!  If a backup was made, it is put back in place
+of the original file (if possible).  If you exit Vim, and lose the changes
+you made, the original file will mostly still be there.  If putting back the
+original file fails, there will be an error message telling you that you
+lost the original file.
+
+						*DOS-format-write*
+If the 'fileformat' is "dos", <CR> <NL> is used for <EOL>.  This is default
+for MS-DOS, Win32 and OS/2.  On other systems the message "[dos format]" is
+shown to remind you that an unusual <EOL> was used.
+						*Unix-format-write*
+If the 'fileformat' is "unix", <NL> is used for <EOL>.  On MS-DOS, Win32 and
+OS/2 the message "[unix format]" is shown.
+						*Mac-format-write*
+If the 'fileformat' is "mac", <CR> is used for <EOL>.  On non-Mac systems the
+message "[mac format]" is shown.
+
+See also |file-formats| and the 'fileformat' and 'fileformats' options.
+
+						*ACL*
+ACL stands for Access Control List.  It is an advanced way to control access
+rights for a file.  It is used on new MS-Windows and Unix systems, but only
+when the filesystem supports it.
+   Vim attempts to preserve the ACL info when writing a file.  The backup file
+will get the ACL info of the original file.
+   The ACL info is also used to check if a file is read-only (when opening the
+file).
+
+						*read-only-share*
+When MS-Windows shares a drive on the network it can be marked as read-only.
+This means that even if the file read-only attribute is absent, and the ACL
+settings on NT network shared drives allow writing to the file, you can still
+not write to the file.  Vim on Win32 platforms will detect read-only network
+drives and will mark the file as read-only.  You will not be able to override
+it with |:write|.
+
+						*write-device*
+When the file name is actually a device name, Vim will not make a backup (that
+would be impossible).  You need to use "!", since the device already exists.
+Example for Unix: >
+	:w! /dev/lpt0
+and for MS-DOS or MS-Windows: >
+	:w! lpt0
+For Unix a device is detected when the name doesn't refer to a normal file or
+a directory.  A fifo or named pipe also looks like a device to Vim.
+For MS-DOS and MS-Windows the device is detected by its name:
+	AUX
+	CON
+	CLOCK$
+	NUL
+	PRN
+	COMn	n=1,2,3... etc
+	LPTn	n=1,2,3... etc
+The names can be in upper- or lowercase.
+
+==============================================================================
+5. Writing and quitting					*write-quit*
+
+							*:q* *:quit*
+:q[uit]			Quit the current window.  Quit Vim if this is the last
+			window.  This fails when changes have been made and
+			Vim refuses to |abandon| the current buffer, and when
+			the last file in the argument list has not been
+			edited.
+			If there are other tab pages and quitting the last
+			window in the current tab page the current tab page is
+			closed |tab-page|.
+
+:conf[irm] q[uit]	Quit, but give prompt when changes have been made, or
+			the last file in the argument list has not been
+			edited.  See |:confirm| and 'confirm'.  {not in Vi}
+
+:q[uit]!		Quit without writing, also when visible buffers have
+			changes.  Does not exit when there are changed hidden
+			buffers.  Use ":qall!" to exit always.
+
+:cq[uit]		Quit always, without writing, and return an error
+			code.  See |:cq|.  Used for Manx's QuickFix mode (see
+			|quickfix|).  {not in Vi}
+
+							*:wq*
+:wq			Write the current file and quit.  Writing fails when
+			the file is read-only or the buffer does not have a
+			name.  Quitting fails when the last file in the
+			argument list has not been edited.
+
+:wq!			Write the current file and quit.  Writing fails when
+			the current buffer does not have a name.
+
+:wq {file}		Write to {file} and quit.  Quitting fails when the
+			last file in the argument list has not been edited.
+
+:wq! {file}		Write to {file} and quit.
+
+:[range]wq[!] [file]	Same as above, but only write the lines in [range].
+
+							*:x* *:xit*
+:[range]x[it][!] [file]
+			Like ":wq", but write only when changes have been
+			made.
+			When 'hidden' is set and there are more windows, the
+			current buffer becomes hidden, after writing the file.
+
+							*:exi* *:exit*
+:[range]exi[t][!] [file]
+			Same as :xit.
+
+							*ZZ*
+ZZ			Write current file, if modified, and quit (same as
+			":x").  (Note: If there are several windows for the
+			current file, the file is written if it was modified
+			and the window is closed).
+
+							*ZQ*
+ZQ			Quit without checking for changes (same as ":q!").
+			{not in Vi}
+
+MULTIPLE WINDOWS AND BUFFERS				*window-exit*
+
+							*:qa* *:qall*
+:qa[ll]		Exit Vim, unless there are some buffers which have been
+		changed.  (Use ":bmod" to go to the next modified buffer).
+		When 'autowriteall' is set all changed buffers will be
+		written, like |:wqall|. {not in Vi}
+
+:conf[irm] qa[ll]
+		Exit Vim.  Bring up a prompt when some buffers have been
+		changed.  See |:confirm|. {not in Vi}
+
+:qa[ll]!	Exit Vim.  Any changes to buffers are lost. {not in Vi}
+
+							*:quita* *:quitall*
+:quita[ll][!]	Same as ":qall". {not in Vi}
+
+:wqa[ll]					*:wqa* *:wqall* *:xa* *:xall*
+:xa[ll]		Write all changed buffers and exit Vim.  If there are buffers
+		without a file name, which are readonly or which cannot be
+		written for another reason, Vim will not quit. {not in Vi}
+
+:conf[irm] wqa[ll]
+:conf[irm] xa[ll]
+		Write all changed buffers and exit Vim.  Bring up a prompt
+		when some buffers are readonly or cannot be written for
+		another reason.  See |:confirm|. {not in Vi}
+
+:wqa[ll]!
+:xa[ll]!	Write all changed buffers, even the ones that are readonly,
+		and exit Vim.  If there are buffers without a file name or
+		which cannot be written for another reason, Vim will not quit.
+		{not in Vi}
+
+==============================================================================
+6. Dialogs						*edit-dialogs*
+
+							*:confirm* *:conf*
+:conf[irm] {command}	Execute {command}, and use a dialog when an
+			operation has to be confirmed.  Can be used on the
+			":q", ":qa" and ":w" commands (the latter to over-ride
+			a read-only setting).
+
+Examples: >
+  :confirm w foo
+<	Will ask for confirmation when "foo" already exists. >
+  :confirm q
+<	Will ask for confirmation when there are changes. >
+  :confirm qa
+<	If any modified, unsaved buffers exist, you will be prompted to save
+	or abandon each one.  There are also choices to "save all" or "abandon
+	all".
+
+If you want to always use ":confirm", set the 'confirm' option.
+
+			*:browse* *:bro* *E338* *E614* *E615* *E616* *E578*
+:bro[wse] {command}	Open a file selection dialog for an argument to
+			{command}.  At present this works for |:e|, |:w|,
+			|:r|, |:saveas|, |:sp|, |:mkexrc|, |:mkvimrc|,
+			|:mksession|, |:split|, |:vsplit|, and |:tabe|.
+			{only in Win32, Athena, Motif, GTK and Mac GUI}
+			When ":browse" is not possible you get an error
+			message.  If the |+browse| feature is missing or the
+			{command} doesn't support browsing, the {command} is
+			executed without a dialog.
+			":browse set" works like |:options|.
+
+The syntax is best shown via some examples: >
+	:browse e $vim/foo
+<		Open the browser in the $vim/foo directory, and edit the
+		file chosen. >
+	:browse e
+<		Open the browser in the directory specified with 'browsedir',
+		and edit the file chosen. >
+	:browse w
+<		Open the browser in the directory of the current buffer,
+		with the current buffer filename as default, and save the
+		buffer under the filename chosen. >
+	:browse w C:/bar
+<		Open the browser in the C:/bar directory, with the current
+		buffer filename as default, and save the buffer under the
+		filename chosen.
+Also see the |'browsedir'| option.
+For versions of Vim where browsing is not supported, the command is executed
+unmodified.
+
+							*browsefilter*
+For MS Windows, you can modify the filters that are used in the browse dialog.
+By setting the g:browsefilter or b:browsefilter variables, you can change the
+filters globally or locally to the buffer.  The variable is set to a string in
+the format "{filter label}\t{pattern};{pattern}\n" where {filter label} is the
+text that appears in the "Files of Type" comboBox, and {pattern} is the
+pattern which filters the filenames.  Several patterns can be given, separated
+by ';'.
+
+For Motif the same format is used, but only the very first pattern is actually
+used (Motif only offers one pattern, but you can edit it).
+
+For example, to have only Vim files in the dialog, you could use the following
+command: >
+
+     let g:browsefilter="Vim Scripts\t*.vim\nVim Startup Files\t*vimrc\n"
+
+You can override the filter setting on a per-buffer basis by setting the
+b:browsefilter variable.  You would most likely set b:browsefilter in a
+filetype plugin, so that the browse dialog would contain entries related to
+the type of file you are currently editing.  Disadvantage: This makes it
+difficult to start editing a file of a different type.  To overcome this, you
+may want to add "All Files\t*.*\n" as the final filter, so that the user can
+still access any desired file.
+
+==============================================================================
+7. The current directory				*current-directory*
+
+You may use the |:cd| and |:lcd| commands to change to another directory, so
+you will not have to type that directory name in front of the file names.  It
+also makes a difference for executing external commands, e.g. ":!ls".
+
+Changing directory fails when the current buffer is modified, the '.' flag is
+present in 'cpoptions' and "!" is not used in the command.
+
+							*:cd* *E747* *E472*
+:cd[!]			On non-Unix systems: Print the current directory
+			name.  On Unix systems: Change the current directory
+			to the home directory.  Use |:pwd| to print the
+			current directory on all systems.
+
+:cd[!] {path}		Change the current directory to {path}.
+			If {path} is relative, it is searched for in the
+			directories listed in |'cdpath'|.
+			Does not change the meaning of an already opened file,
+			because its full path name is remembered.  Files from
+			the |arglist| may change though!
+			On MS-DOS this also changes the active drive.
+			To change to the directory of the current file: >
+				:cd %:h
+<
+							*:cd-* *E186*
+:cd[!] -		Change to the previous current directory (before the
+			previous ":cd {path}" command). {not in Vi}
+
+							*:chd* *:chdir*
+:chd[ir][!] [path]	Same as |:cd|.
+
+							*:lc* *:lcd*
+:lc[d][!] {path}	Like |:cd|, but only set the current directory for the
+			current window.  The current directory for other
+			windows is not changed. {not in Vi}
+
+							*:lch* *:lchdir*
+:lch[dir][!]		Same as |:lcd|. {not in Vi}
+
+							*:pw* *:pwd* *E187*
+:pw[d]			Print the current directory name.  {Vi: no pwd}
+			Also see |getcwd()|.
+
+So long as no |:lcd| command has been used, all windows share the same current
+directory.  Using a command to jump to another window doesn't change anything
+for the current directory.
+When a |:lcd| command has been used for a window, the specified directory
+becomes the current directory for that window.  Windows where the |:lcd|
+command has not been used stick to the global current directory.  When jumping
+to another window the current directory will become the last specified local
+current directory.  If none was specified, the global current directory is
+used.
+When a |:cd| command is used, the current window will lose his local current
+directory and will use the global current directory from now on.
+
+After using |:cd| the full path name will be used for reading and writing
+files.  On some networked file systems this may cause problems.  The result of
+using the full path name is that the file names currently in use will remain
+referring to the same file.  Example: If you have a file a:test and a
+directory a:vim the commands ":e test" ":cd vim" ":w" will overwrite the file
+a:test and not write a:vim/test.  But if you do ":w test" the file a:vim/test
+will be written, because you gave a new file name and did not refer to a
+filename before the ":cd".
+
+==============================================================================
+8. Editing binary files					*edit-binary*
+
+Although Vim was made to edit text files, it is possible to edit binary
+files.  The |-b| Vim argument (b for binary) makes Vim do file I/O in binary
+mode, and sets some options for editing binary files ('binary' on, 'textwidth'
+to 0, 'modeline' off, 'expandtab' off).  Setting the 'binary' option has the
+same effect.  Don't forget to do this before reading the file.
+
+There are a few things to remember when editing binary files:
+- When editing executable files the number of characters must not change.
+  Use only the "R" or "r" command to change text.  Do not delete characters
+  with "x" or by backspacing.
+- Set the 'textwidth' option to 0.  Otherwise lines will unexpectedly be
+  split in two.
+- When there are not many <EOL>s, the lines will become very long.  If you
+  want to edit a line that does not fit on the screen reset the 'wrap' option.
+  Horizontal scrolling is used then.  If a line becomes too long (more than
+  about 32767 characters on the Amiga, much more on 32-bit systems, see
+  |limits|) you cannot edit that line.  The line will be split when reading
+  the file.  It is also possible that you get an "out of memory" error when
+  reading the file.
+- Make sure the 'binary' option is set BEFORE loading the
+  file.  Otherwise both <CR> <NL> and <NL> are considered to end a line
+  and when the file is written the <NL> will be replaced with <CR> <NL>.
+- <Nul> characters are shown on the screen as ^@.  You can enter them with
+  "CTRL-V CTRL-@" or "CTRL-V 000" {Vi cannot handle <Nul> characters in the
+  file}
+- To insert a <NL> character in the file split up a line.  When writing the
+  buffer to a file a <NL> will be written for the <EOL>.
+- Vim normally appends an <EOL> at the end of the file if there is none.
+  Setting the 'binary' option prevents this.  If you want to add the final
+  <EOL>, set the 'endofline' option.  You can also read the value of this
+  option to see if there was an <EOL> for the last line (you cannot see this
+  in the text).
+
+==============================================================================
+9. Encryption						*encryption*
+
+Vim is able to write files encrypted, and read them back.  The encrypted text
+cannot be read without the right key.
+
+Note: The swapfile and text in memory is not encrypted.  A system
+administrator will be able to see your text while you are editing it.
+When filtering text with ":!filter" or using ":w !command" the text is not
+encrypted, this may reveal it to others.
+
+WARNING: If you make a typo when entering the key and then write the file and
+exit, the text will be lost!
+
+The normal way to work with encryption, is to use the ":X" command, which will
+ask you to enter a key.  A following write command will use that key to
+encrypt the file.  If you later edit the same file, Vim will ask you to enter
+a key.  If you type the same key as that was used for writing, the text will
+be readable again.  If you use a wrong key, it will be a mess.
+
+							*:X*
+:X	Prompt for an encryption key.  The typing is done without showing the
+	actual text, so that someone looking at the display won't see it.
+	The typed key is stored in the 'key' option, which is used to encrypt
+	the file when it is written.  The file will remain unchanged until you
+	write it.  See also |-x|.
+
+The value of the 'key' options is used when text is written.  When the option
+is not empty, the written file will be encrypted, using the value as the
+encryption key.  A magic number is prepended, so that Vim can recognize that
+the file is encrypted.
+
+To disable the encryption, reset the 'key' option to an empty value: >
+	:set key=
+
+When reading a file that has been encrypted and this option is not empty, it
+will be used for decryption.  If the value is empty, you will be prompted to
+enter the key.  If you don't enter a key, the file is edited without being
+decrypted.
+
+If want to start reading a file that uses a different key, set the 'key'
+option to an empty string, so that Vim will prompt for a new one.  Don't use
+the ":set" command to enter the value, other people can read the command over
+your shoulder.
+
+Since the value of the 'key' option is supposed to be a secret, its value can
+never be viewed.  You should not set this option in a vimrc file.
+
+An encrypted file can be recognized by the "file" command, if you add this
+line to "/etc/magic", "/usr/share/misc/magic" or wherever your system has the
+"magic" file: >
+     0	string	VimCrypt~	Vim encrypted file
+
+Notes:
+- Encryption is not possible when doing conversion with 'charconvert'.
+- Text you copy or delete goes to the numbered registers.  The registers can
+  be saved in the .viminfo file, where they could be read.  Change your
+  'viminfo' option to be safe.
+- Someone can type commands in Vim when you walk away for a moment, he should
+  not be able to get the key.
+- If you make a typing mistake when entering the key, you might not be able to
+  get your text back!
+- If you type the key with a ":set key=value" command, it can be kept in the
+  history, showing the 'key' value in a viminfo file.
+- There is never 100% safety.  The encryption in Vim has not been tested for
+  robustness.
+- The algorithm used is breakable.  A 4 character key in about one hour, a 6
+  character key in one day (on a Pentium 133 PC).  This requires that you know
+  some text that must appear in the file.  An expert can break it for any key.
+  When the text has been decrypted, this also means that the key can be
+  revealed, and other files encrypted with the same key can be decrypted.
+- Pkzip uses the same encryption, and US Govt has no objection to its export.
+  Pkzip's public file APPNOTE.TXT describes this algorithm in detail.
+- Vim originates from the Netherlands.  That is where the sources come from.
+  Thus the encryption code is not exported from the USA.
+
+==============================================================================
+10. Timestamps					*timestamp* *timestamps*
+
+Vim remembers the modification timestamp of a file when you begin editing it.
+This is used to avoid that you have two different versions of the same file
+(without you knowing this).
+
+After a shell command is run (|:!cmd| |suspend| |:read!| |K|) timestamps are
+compared for all buffers in a window.   Vim will run any associated
+|FileChangedShell| autocommands or display a warning for any files that have
+changed.  In the GUI this happens when Vim regains input focus.
+
+							*E321* *E462*
+If you want to automatically reload a file when it has been changed outside of
+Vim, set the 'autoread' option.  This doesn't work at the moment you write the
+file though, only when the file wasn't changed inside of Vim.
+
+Note that if a FileChangedShell autocommand is defined you will not get a
+warning message or prompt.  The autocommand is expected to handle this.
+
+There is no warning for a directory (e.g., with |netrw-browse|).  But you do
+get warned if you started editing a new file and it was created as a directory
+later.
+
+When Vim notices the timestamp of a file has changed, and the file is being
+edited in a buffer but has not changed, Vim checks if the contents of the file
+is equal.  This is done by reading the file again (into a hidden buffer, which
+is immediately deleted again) and comparing the text.  If the text is equal,
+you will get no warning.
+
+If you don't get warned often enough you can use the following command.
+
+							*:checkt* *:checktime*
+:checkt[ime]		Check if any buffers were changed outside of Vim.
+			This checks and warns you if you would end up with two
+			versions of a file.
+			If this is called from an autocommand, a ":global"
+			command or is not typed the actual check is postponed
+			until a moment the side effects (reloading the file)
+			would be harmless.
+			Each loaded buffer is checked for its associated file
+			being changed.  If the file was changed Vim will take
+			action.  If there are no changes in the buffer and
+			'autoread' is set, the buffer is reloaded.  Otherwise,
+			you are offered the choice of reloading the file.  If
+			the file was deleted you get an error message.
+			If the file previously didn't exist you get a warning
+			if it exists now.
+			Once a file has been checked the timestamp is reset,
+			you will not be warned again.
+
+:[N]checkt[ime] {filename}
+:[N]checkt[ime] [N]
+			Check the timestamp of a specific buffer.  The buffer
+			may be specified by name, number or with a pattern.
+
+
+Before writing a file the timestamp is checked.  If it has changed, Vim will
+ask if you really want to overwrite the file:
+
+	WARNING: The file has been changed since reading it!!!
+	Do you really want to write to it (y/n)?
+
+If you hit 'y' Vim will continue writing the file.  If you hit 'n' the write is
+aborted.  If you used ":wq" or "ZZ" Vim will not exit, you will get another
+chance to write the file.
+
+The message would normally mean that somebody has written to the file after
+the edit session started.  This could be another person, in which case you
+probably want to check if your changes to the file and the changes from the
+other person should be merged.  Write the file under another name and check for
+differences (the "diff" program can be used for this).
+
+It is also possible that you modified the file yourself, from another edit
+session or with another command (e.g., a filter command).  Then you will know
+which version of the file you want to keep.
+
+There is one situation where you get the message while there is nothing wrong:
+On a Win32 system on the day daylight saving time starts.  There is something
+in the Win32 libraries that confuses Vim about the hour time difference.  The
+problem goes away the next day.
+
+==============================================================================
+11. File Searching					*file-searching*
+
+{not available when compiled without the |+path_extra| feature}
+
+The file searching is currently used for the 'path', 'cdpath' and 'tags'
+options, for |finddir()| and |findfile()|.
+
+There are three different types of searching:
+
+1) Downward search:					*starstar*
+   Downward search uses the wildcards '*', '**' and possibly others
+   supported by your operating system.  '*' and '**' are handled inside Vim, so
+   they work on all operating systems.
+
+   The usage of '*' is quite simple: It matches 0 or more characters.
+
+   '**' is more sophisticated:
+      - It ONLY matches directories.
+      - It matches up to 30 directories deep, so you can use it to search an
+	entire directory tree
+      - The maximum number of levels matched can be given by appending a number
+	to '**'.
+	Thus '/usr/**2' can match: >
+		/usr
+		/usr/include
+		/usr/include/sys
+		/usr/include/g++
+		/usr/lib
+		/usr/lib/X11
+		....
+<	It does NOT match '/usr/include/g++/std' as this would be three
+	levels.
+	The allowed number range is 0 ('**0' is removed) to 255.
+	If the given number is smaller than 0 it defaults to 30, if it's
+	bigger than 255 it defaults to 255.
+      - '**' can only be at the end of the path or be followed by a path
+	separator or by a number and a path separator.
+
+   You can combine '*' and '**' in any order: >
+	/usr/**/sys/*
+	/usr/*/sys/**
+	/usr/**2/sys/*
+
+2) Upward search:
+   Here you can give a directory and then search the directory tree upward for
+   a file.  You could give stop-directories to limit the upward search.  The
+   stop-directories are appended to the path (for the 'path' option) or to
+   the filename (for the 'tags' option) with a ';'.  If you want several
+   stop-directories separate them with ';'.  If you want no stop-directory
+   ("search upward till the root directory) just use ';'. >
+	/usr/include/sys;/usr
+<   will search in: >
+	   /usr/include/sys
+	   /usr/include
+	   /usr
+<
+   If you use a relative path the upward search is started in Vim's current
+   directory or in the directory of the current file (if the relative path
+   starts with './' and 'd' is not included in 'cpoptions').
+
+   If Vim's current path is /u/user_x/work/release and you do >
+	:set path=include;/u/user_x
+<  and then search for a file with |gf| the file is searched in: >
+	/u/user_x/work/release/include
+	/u/user_x/work/include
+	/u/user_x/include
+
+3) Combined up/downward search:
+   If Vim's current path is /u/user_x/work/release and you do >
+	set path=**;/u/user_x
+<  and then search for a file with |gf| the file is searched in: >
+	/u/user_x/work/release/**
+	/u/user_x/work/**
+	/u/user_x/**
+<
+   BE CAREFUL!  This might consume a lot of time, as the search of
+   '/u/user_x/**' includes '/u/user_x/work/**' and
+   '/u/user_x/work/release/**'.  So '/u/user_x/work/release/**' is searched
+   three times and '/u/user_x/work/**' is searched twice.
+
+   In the above example you might want to set path to: >
+	:set path=**,/u/user_x/**
+<   This searches: >
+	/u/user_x/work/release/**
+	/u/user_x/**
+<   This searches the same directories, but in a different order.
+
+
+ vim:tw=78:ts=8:ft=help:norl:
--- /dev/null
+++ b/lib/vimfiles/doc/eval.txt
@@ -1,0 +1,7414 @@
+*eval.txt*      For Vim version 7.1.  Last change: 2007 May 11
+
+
+		  VIM REFERENCE MANUAL    by Bram Moolenaar
+
+
+Expression evaluation			*expression* *expr* *E15* *eval*
+
+Using expressions is introduced in chapter 41 of the user manual |usr_41.txt|.
+
+Note: Expression evaluation can be disabled at compile time.  If this has been
+done, the features in this document are not available.  See |+eval| and
+|no-eval-feature|.
+
+1.  Variables			|variables|
+    1.1 Variable types
+    1.2 Function references		|Funcref|
+    1.3 Lists				|Lists|
+    1.4 Dictionaries			|Dictionaries|
+    1.5 More about variables		|more-variables|
+2.  Expression syntax		|expression-syntax|
+3.  Internal variable		|internal-variables|
+4.  Builtin Functions		|functions|
+5.  Defining functions		|user-functions|
+6.  Curly braces names		|curly-braces-names|
+7.  Commands			|expression-commands|
+8.  Exception handling		|exception-handling|
+9.  Examples			|eval-examples|
+10. No +eval feature		|no-eval-feature|
+11. The sandbox			|eval-sandbox|
+12. Textlock			|textlock|
+
+{Vi does not have any of these commands}
+
+==============================================================================
+1. Variables						*variables*
+
+1.1 Variable types ~
+							*E712*
+There are five types of variables:
+
+Number		A 32 bit signed number.
+		Examples:  -123  0x10  0177
+
+String		A NUL terminated string of 8-bit unsigned characters (bytes).
+		Examples: "ab\txx\"--"  'x-z''a,c'
+
+Funcref		A reference to a function |Funcref|.
+		Example: function("strlen")
+
+List		An ordered sequence of items |List|.
+		Example: [1, 2, ['a', 'b']]
+
+Dictionary	An associative, unordered array: Each entry has a key and a
+		value. |Dictionary|
+		Example: {'blue': "#0000ff", 'red': "#ff0000"}
+
+The Number and String types are converted automatically, depending on how they
+are used.
+
+Conversion from a Number to a String is by making the ASCII representation of
+the Number.  Examples: >
+	Number 123	-->	String "123"
+	Number 0	-->	String "0"
+	Number -1	-->	String "-1"
+
+Conversion from a String to a Number is done by converting the first digits
+to a number.  Hexadecimal "0xf9" and Octal "017" numbers are recognized.  If
+the String doesn't start with digits, the result is zero.  Examples: >
+	String "456"	-->	Number 456
+	String "6bar"	-->	Number 6
+	String "foo"	-->	Number 0
+	String "0xf1"	-->	Number 241
+	String "0100"	-->	Number 64
+	String "-8"	-->	Number -8
+	String "+8"	-->	Number 0
+
+To force conversion from String to Number, add zero to it: >
+	:echo "0100" + 0
+<	64 ~
+
+To avoid a leading zero to cause octal conversion, or for using a different
+base, use |str2nr()|.
+
+For boolean operators Numbers are used.  Zero is FALSE, non-zero is TRUE.
+
+Note that in the command >
+	:if "foo"
+"foo" is converted to 0, which means FALSE.  To test for a non-empty string,
+use strlen(): >
+	:if strlen("foo")
+<				*E745* *E728* *E703* *E729* *E730* *E731*
+List, Dictionary and Funcref types are not automatically converted.
+
+								*E706*
+You will get an error if you try to change the type of a variable.  You need
+to |:unlet| it first to avoid this error.  String and Number are considered
+equivalent though.  Consider this sequence of commands: >
+	:let l = "string"
+	:let l = 44		" changes type from String to Number
+	:let l = [1, 2, 3]	" error!
+
+
+1.2 Function references ~
+					*Funcref* *E695* *E718*
+A Funcref variable is obtained with the |function()| function.  It can be used
+in an expression in the place of a function name, before the parenthesis
+around the arguments, to invoke the function it refers to.  Example: >
+
+	:let Fn = function("MyFunc")
+	:echo Fn()
+<							*E704* *E705* *E707*
+A Funcref variable must start with a capital, "s:", "w:", "t:" or "b:".  You
+cannot have both a Funcref variable and a function with the same name.
+
+A special case is defining a function and directly assigning its Funcref to a
+Dictionary entry.  Example: >
+	:function dict.init() dict
+	:   let self.val = 0
+	:endfunction
+
+The key of the Dictionary can start with a lower case letter.  The actual
+function name is not used here.  Also see |numbered-function|.
+
+A Funcref can also be used with the |:call| command: >
+	:call Fn()
+	:call dict.init()
+
+The name of the referenced function can be obtained with |string()|. >
+	:let func = string(Fn)
+
+You can use |call()| to invoke a Funcref and use a list variable for the
+arguments: >
+	:let r = call(Fn, mylist)
+
+
+1.3 Lists ~
+							*List* *Lists* *E686*
+A List is an ordered sequence of items.  An item can be of any type.  Items
+can be accessed by their index number.  Items can be added and removed at any
+position in the sequence.
+
+
+List creation ~
+							*E696* *E697*
+A List is created with a comma separated list of items in square brackets.
+Examples: >
+	:let mylist = [1, two, 3, "four"]
+	:let emptylist = []
+
+An item can be any expression.  Using a List for an item creates a
+List of Lists: >
+	:let nestlist = [[11, 12], [21, 22], [31, 32]]
+
+An extra comma after the last item is ignored.
+
+
+List index ~
+							*list-index* *E684*
+An item in the List can be accessed by putting the index in square brackets
+after the List.  Indexes are zero-based, thus the first item has index zero. >
+	:let item = mylist[0]		" get the first item: 1
+	:let item = mylist[2]		" get the third item: 3
+
+When the resulting item is a list this can be repeated: >
+	:let item = nestlist[0][1]	" get the first list, second item: 12
+<
+A negative index is counted from the end.  Index -1 refers to the last item in
+the List, -2 to the last but one item, etc. >
+	:let last = mylist[-1]		" get the last item: "four"
+
+To avoid an error for an invalid index use the |get()| function.  When an item
+is not available it returns zero or the default value you specify: >
+	:echo get(mylist, idx)
+	:echo get(mylist, idx, "NONE")
+
+
+List concatenation ~
+
+Two lists can be concatenated with the "+" operator: >
+	:let longlist = mylist + [5, 6]
+	:let mylist += [7, 8]
+
+To prepend or append an item turn the item into a list by putting [] around
+it.  To change a list in-place see |list-modification| below.
+
+
+Sublist ~
+
+A part of the List can be obtained by specifying the first and last index,
+separated by a colon in square brackets: >
+	:let shortlist = mylist[2:-1]	" get List [3, "four"]
+
+Omitting the first index is similar to zero.  Omitting the last index is
+similar to -1. >
+	:let endlist = mylist[2:]	" from item 2 to the end: [3, "four"]
+	:let shortlist = mylist[2:2]	" List with one item: [3]
+	:let otherlist = mylist[:]	" make a copy of the List
+
+If the first index is beyond the last item of the List or the second item is
+before the first item, the result is an empty list.  There is no error
+message.
+
+If the second index is equal to or greater than the length of the list the
+length minus one is used: >
+	:let mylist = [0, 1, 2, 3]
+	:echo mylist[2:8]		" result: [2, 3]
+
+NOTE: mylist[s:e] means using the variable "s:e" as index.  Watch out for
+using a single letter variable before the ":".  Insert a space when needed:
+mylist[s : e].
+
+
+List identity ~
+							*list-identity*
+When variable "aa" is a list and you assign it to another variable "bb", both
+variables refer to the same list.  Thus changing the list "aa" will also
+change "bb": >
+	:let aa = [1, 2, 3]
+	:let bb = aa
+	:call add(aa, 4)
+	:echo bb
+<	[1, 2, 3, 4]
+
+Making a copy of a list is done with the |copy()| function.  Using [:] also
+works, as explained above.  This creates a shallow copy of the list: Changing
+a list item in the list will also change the item in the copied list: >
+	:let aa = [[1, 'a'], 2, 3]
+	:let bb = copy(aa)
+	:call add(aa, 4)
+	:let aa[0][1] = 'aaa'
+	:echo aa
+<	[[1, aaa], 2, 3, 4] >
+	:echo bb
+<	[[1, aaa], 2, 3]
+
+To make a completely independent list use |deepcopy()|.  This also makes a
+copy of the values in the list, recursively.  Up to a hundred levels deep.
+
+The operator "is" can be used to check if two variables refer to the same
+List.  "isnot" does the opposite.  In contrast "==" compares if two lists have
+the same value. >
+	:let alist = [1, 2, 3]
+	:let blist = [1, 2, 3]
+	:echo alist is blist
+<	0 >
+	:echo alist == blist
+<	1
+
+Note about comparing lists: Two lists are considered equal if they have the
+same length and all items compare equal, as with using "==".  There is one
+exception: When comparing a number with a string they are considered
+different.  There is no automatic type conversion, as with using "==" on
+variables.  Example: >
+	echo 4 == "4"
+<	1 >
+	echo [4] == ["4"]
+<	0
+
+Thus comparing Lists is more strict than comparing numbers and strings.  You
+can compare simple values this way too by putting them in a string: >
+
+	:let a = 5
+	:let b = "5"
+	echo a == b
+<	1 >
+	echo [a] == [b]
+<	0
+
+
+List unpack ~
+
+To unpack the items in a list to individual variables, put the variables in
+square brackets, like list items: >
+	:let [var1, var2] = mylist
+
+When the number of variables does not match the number of items in the list
+this produces an error.  To handle any extra items from the list append ";"
+and a variable name: >
+	:let [var1, var2; rest] = mylist
+
+This works like: >
+	:let var1 = mylist[0]
+	:let var2 = mylist[1]
+	:let rest = mylist[2:]
+
+Except that there is no error if there are only two items.  "rest" will be an
+empty list then.
+
+
+List modification ~
+							*list-modification*
+To change a specific item of a list use |:let| this way: >
+	:let list[4] = "four"
+	:let listlist[0][3] = item
+
+To change part of a list you can specify the first and last item to be
+modified.  The value must at least have the number of items in the range: >
+	:let list[3:5] = [3, 4, 5]
+
+Adding and removing items from a list is done with functions.  Here are a few
+examples: >
+	:call insert(list, 'a')		" prepend item 'a'
+	:call insert(list, 'a', 3)	" insert item 'a' before list[3]
+	:call add(list, "new")		" append String item
+	:call add(list, [1, 2])		" append a List as one new item
+	:call extend(list, [1, 2])	" extend the list with two more items
+	:let i = remove(list, 3)	" remove item 3
+	:unlet list[3]			" idem
+	:let l = remove(list, 3, -1)	" remove items 3 to last item
+	:unlet list[3 : ]		" idem
+	:call filter(list, 'v:val !~ "x"')  " remove items with an 'x'
+
+Changing the order of items in a list: >
+	:call sort(list)		" sort a list alphabetically
+	:call reverse(list)		" reverse the order of items
+
+
+For loop ~
+
+The |:for| loop executes commands for each item in a list.  A variable is set
+to each item in the list in sequence.  Example: >
+	:for item in mylist
+	:   call Doit(item)
+	:endfor
+
+This works like: >
+	:let index = 0
+	:while index < len(mylist)
+	:   let item = mylist[index]
+	:   :call Doit(item)
+	:   let index = index + 1
+	:endwhile
+
+Note that all items in the list should be of the same type, otherwise this
+results in error |E706|.  To avoid this |:unlet| the variable at the end of
+the loop.
+
+If all you want to do is modify each item in the list then the |map()|
+function will be a simpler method than a for loop.
+
+Just like the |:let| command, |:for| also accepts a list of variables.  This
+requires the argument to be a list of lists. >
+	:for [lnum, col] in [[1, 3], [2, 8], [3, 0]]
+	:   call Doit(lnum, col)
+	:endfor
+
+This works like a |:let| command is done for each list item.  Again, the types
+must remain the same to avoid an error.
+
+It is also possible to put remaining items in a List variable: >
+	:for [i, j; rest] in listlist
+	:   call Doit(i, j)
+	:   if !empty(rest)
+	:      echo "remainder: " . string(rest)
+	:   endif
+	:endfor
+
+
+List functions ~
+						*E714*
+Functions that are useful with a List: >
+	:let r = call(funcname, list)	" call a function with an argument list
+	:if empty(list)			" check if list is empty
+	:let l = len(list)		" number of items in list
+	:let big = max(list)		" maximum value in list
+	:let small = min(list)		" minimum value in list
+	:let xs = count(list, 'x')	" count nr of times 'x' appears in list
+	:let i = index(list, 'x')	" index of first 'x' in list
+	:let lines = getline(1, 10)	" get ten text lines from buffer
+	:call append('$', lines)	" append text lines in buffer
+	:let list = split("a b c")	" create list from items in a string
+	:let string = join(list, ', ')	" create string from list items
+	:let s = string(list)		" String representation of list
+	:call map(list, '">> " . v:val')  " prepend ">> " to each item
+
+Don't forget that a combination of features can make things simple.  For
+example, to add up all the numbers in a list: >
+	:exe 'let sum = ' . join(nrlist, '+')
+
+
+1.4 Dictionaries ~
+						*Dictionaries* *Dictionary*
+A Dictionary is an associative array: Each entry has a key and a value.  The
+entry can be located with the key.  The entries are stored without a specific
+ordering.
+
+
+Dictionary creation ~
+						*E720* *E721* *E722* *E723*
+A Dictionary is created with a comma separated list of entries in curly
+braces.  Each entry has a key and a value, separated by a colon.  Each key can
+only appear once.  Examples: >
+	:let mydict = {1: 'one', 2: 'two', 3: 'three'}
+	:let emptydict = {}
+<							*E713* *E716* *E717*
+A key is always a String.  You can use a Number, it will be converted to a
+String automatically.  Thus the String '4' and the number 4 will find the same
+entry.  Note that the String '04' and the Number 04 are different, since the
+Number will be converted to the String '4'.
+
+A value can be any expression.  Using a Dictionary for a value creates a
+nested Dictionary: >
+	:let nestdict = {1: {11: 'a', 12: 'b'}, 2: {21: 'c'}}
+
+An extra comma after the last entry is ignored.
+
+
+Accessing entries ~
+
+The normal way to access an entry is by putting the key in square brackets: >
+	:let val = mydict["one"]
+	:let mydict["four"] = 4
+
+You can add new entries to an existing Dictionary this way, unlike Lists.
+
+For keys that consist entirely of letters, digits and underscore the following
+form can be used |expr-entry|: >
+	:let val = mydict.one
+	:let mydict.four = 4
+
+Since an entry can be any type, also a List and a Dictionary, the indexing and
+key lookup can be repeated: >
+	:echo dict.key[idx].key
+
+
+Dictionary to List conversion ~
+
+You may want to loop over the entries in a dictionary.  For this you need to
+turn the Dictionary into a List and pass it to |:for|.
+
+Most often you want to loop over the keys, using the |keys()| function: >
+	:for key in keys(mydict)
+	:   echo key . ': ' . mydict[key]
+	:endfor
+
+The List of keys is unsorted.  You may want to sort them first: >
+	:for key in sort(keys(mydict))
+
+To loop over the values use the |values()| function:  >
+	:for v in values(mydict)
+	:   echo "value: " . v
+	:endfor
+
+If you want both the key and the value use the |items()| function.  It returns
+a List in which each item is a  List with two items, the key and the value: >
+	:for [key, value] in items(mydict)
+	:   echo key . ': ' . value
+	:endfor
+
+
+Dictionary identity ~
+							*dict-identity*
+Just like Lists you need to use |copy()| and |deepcopy()| to make a copy of a
+Dictionary.  Otherwise, assignment results in referring to the same
+Dictionary: >
+	:let onedict = {'a': 1, 'b': 2}
+	:let adict = onedict
+	:let adict['a'] = 11
+	:echo onedict['a']
+	11
+
+Two Dictionaries compare equal if all the key-value pairs compare equal.  For
+more info see |list-identity|.
+
+
+Dictionary modification ~
+							*dict-modification*
+To change an already existing entry of a Dictionary, or to add a new entry,
+use |:let| this way: >
+	:let dict[4] = "four"
+	:let dict['one'] = item
+
+Removing an entry from a Dictionary is done with |remove()| or |:unlet|.
+Three ways to remove the entry with key "aaa" from dict: >
+	:let i = remove(dict, 'aaa')
+	:unlet dict.aaa
+	:unlet dict['aaa']
+
+Merging a Dictionary with another is done with |extend()|: >
+	:call extend(adict, bdict)
+This extends adict with all entries from bdict.  Duplicate keys cause entries
+in adict to be overwritten.  An optional third argument can change this.
+Note that the order of entries in a Dictionary is irrelevant, thus don't
+expect ":echo adict" to show the items from bdict after the older entries in
+adict.
+
+Weeding out entries from a Dictionary can be done with |filter()|: >
+	:call filter(dict, 'v:val =~ "x"')
+This removes all entries from "dict" with a value not matching 'x'.
+
+
+Dictionary function ~
+					*Dictionary-function* *self* *E725*
+When a function is defined with the "dict" attribute it can be used in a
+special way with a dictionary.  Example: >
+	:function Mylen() dict
+	:   return len(self.data)
+	:endfunction
+	:let mydict = {'data': [0, 1, 2, 3], 'len': function("Mylen")}
+	:echo mydict.len()
+
+This is like a method in object oriented programming.  The entry in the
+Dictionary is a |Funcref|.  The local variable "self" refers to the dictionary
+the function was invoked from.
+
+It is also possible to add a function without the "dict" attribute as a
+Funcref to a Dictionary, but the "self" variable is not available then.
+
+				*numbered-function* *anonymous-function*
+To avoid the extra name for the function it can be defined and directly
+assigned to a Dictionary in this way: >
+	:let mydict = {'data': [0, 1, 2, 3]}
+	:function mydict.len() dict
+	:   return len(self.data)
+	:endfunction
+	:echo mydict.len()
+
+The function will then get a number and the value of dict.len is a |Funcref|
+that references this function.  The function can only be used through a
+|Funcref|.  It will automatically be deleted when there is no |Funcref|
+remaining that refers to it.
+
+It is not necessary to use the "dict" attribute for a numbered function.
+
+
+Functions for Dictionaries ~
+							*E715*
+Functions that can be used with a Dictionary: >
+	:if has_key(dict, 'foo')	" TRUE if dict has entry with key "foo"
+	:if empty(dict)			" TRUE if dict is empty
+	:let l = len(dict)		" number of items in dict
+	:let big = max(dict)		" maximum value in dict
+	:let small = min(dict)		" minimum value in dict
+	:let xs = count(dict, 'x')	" count nr of times 'x' appears in dict
+	:let s = string(dict)		" String representation of dict
+	:call map(dict, '">> " . v:val')  " prepend ">> " to each item
+
+
+1.5 More about variables ~
+							*more-variables*
+If you need to know the type of a variable or expression, use the |type()|
+function.
+
+When the '!' flag is included in the 'viminfo' option, global variables that
+start with an uppercase letter, and don't contain a lowercase letter, are
+stored in the viminfo file |viminfo-file|.
+
+When the 'sessionoptions' option contains "global", global variables that
+start with an uppercase letter and contain at least one lowercase letter are
+stored in the session file |session-file|.
+
+variable name		can be stored where ~
+my_var_6		not
+My_Var_6		session file
+MY_VAR_6		viminfo file
+
+
+It's possible to form a variable name with curly braces, see
+|curly-braces-names|.
+
+==============================================================================
+2. Expression syntax					*expression-syntax*
+
+Expression syntax summary, from least to most significant:
+
+|expr1| expr2 ? expr1 : expr1	if-then-else
+
+|expr2|	expr3 || expr3 ..	logical OR
+
+|expr3|	expr4 && expr4 ..	logical AND
+
+|expr4|	expr5 == expr5		equal
+	expr5 != expr5		not equal
+	expr5 >	 expr5		greater than
+	expr5 >= expr5		greater than or equal
+	expr5 <	 expr5		smaller than
+	expr5 <= expr5		smaller than or equal
+	expr5 =~ expr5		regexp matches
+	expr5 !~ expr5		regexp doesn't match
+
+	expr5 ==? expr5		equal, ignoring case
+	expr5 ==# expr5		equal, match case
+	etc.			As above, append ? for ignoring case, # for
+				matching case
+
+	expr5 is expr5		same |List| instance
+	expr5 isnot expr5	different |List| instance
+
+|expr5|	expr6 +	 expr6 ..	number addition or list concatenation
+	expr6 -	 expr6 ..	number subtraction
+	expr6 .	 expr6 ..	string concatenation
+
+|expr6|	expr7 *	 expr7 ..	number multiplication
+	expr7 /	 expr7 ..	number division
+	expr7 %	 expr7 ..	number modulo
+
+|expr7|	! expr7			logical NOT
+	- expr7			unary minus
+	+ expr7			unary plus
+
+
+|expr8|	expr8[expr1]		byte of a String or item of a |List|
+	expr8[expr1 : expr1]	substring of a String or sublist of a |List|
+	expr8.name		entry in a |Dictionary|
+	expr8(expr1, ...)	function call with |Funcref| variable
+
+|expr9| number			number constant
+	"string"		string constant, backslash is special
+	'string'		string constant, ' is doubled
+	[expr1, ...]		|List|
+	{expr1: expr1, ...}	|Dictionary|
+	&option			option value
+	(expr1)			nested expression
+	variable		internal variable
+	va{ria}ble		internal variable with curly braces
+	$VAR			environment variable
+	@r			contents of register 'r'
+	function(expr1, ...)	function call
+	func{ti}on(expr1, ...)	function call with curly braces
+
+
+".." indicates that the operations in this level can be concatenated.
+Example: >
+	&nu || &list && &shell == "csh"
+
+All expressions within one level are parsed from left to right.
+
+
+expr1							*expr1* *E109*
+-----
+
+expr2 ? expr1 : expr1
+
+The expression before the '?' is evaluated to a number.  If it evaluates to
+non-zero, the result is the value of the expression between the '?' and ':',
+otherwise the result is the value of the expression after the ':'.
+Example: >
+	:echo lnum == 1 ? "top" : lnum
+
+Since the first expression is an "expr2", it cannot contain another ?:.  The
+other two expressions can, thus allow for recursive use of ?:.
+Example: >
+	:echo lnum == 1 ? "top" : lnum == 1000 ? "last" : lnum
+
+To keep this readable, using |line-continuation| is suggested: >
+	:echo lnum == 1
+	:\	? "top"
+	:\	: lnum == 1000
+	:\		? "last"
+	:\		: lnum
+
+You should always put a space before the ':', otherwise it can be mistaken for
+use in a variable such as "a:1".
+
+
+expr2 and expr3						*expr2* *expr3*
+---------------
+
+					*expr-barbar* *expr-&&*
+The "||" and "&&" operators take one argument on each side.  The arguments
+are (converted to) Numbers.  The result is:
+
+	 input				 output ~
+n1		n2		n1 || n2	n1 && n2 ~
+zero		zero		zero		zero
+zero		non-zero	non-zero	zero
+non-zero	zero		non-zero	zero
+non-zero	non-zero	non-zero	non-zero
+
+The operators can be concatenated, for example: >
+
+	&nu || &list && &shell == "csh"
+
+Note that "&&" takes precedence over "||", so this has the meaning of: >
+
+	&nu || (&list && &shell == "csh")
+
+Once the result is known, the expression "short-circuits", that is, further
+arguments are not evaluated.  This is like what happens in C.  For example: >
+
+	let a = 1
+	echo a || b
+
+This is valid even if there is no variable called "b" because "a" is non-zero,
+so the result must be non-zero.  Similarly below: >
+
+	echo exists("b") && b == "yes"
+
+This is valid whether "b" has been defined or not.  The second clause will
+only be evaluated if "b" has been defined.
+
+
+expr4							*expr4*
+-----
+
+expr5 {cmp} expr5
+
+Compare two expr5 expressions, resulting in a 0 if it evaluates to false, or 1
+if it evaluates to true.
+
+			*expr-==*  *expr-!=*  *expr->*   *expr->=*
+			*expr-<*   *expr-<=*  *expr-=~*  *expr-!~*
+			*expr-==#* *expr-!=#* *expr->#*  *expr->=#*
+			*expr-<#*  *expr-<=#* *expr-=~#* *expr-!~#*
+			*expr-==?* *expr-!=?* *expr->?*  *expr->=?*
+			*expr-<?*  *expr-<=?* *expr-=~?* *expr-!~?*
+			*expr-is*
+		use 'ignorecase'    match case	   ignore case ~
+equal			==		==#		==?
+not equal		!=		!=#		!=?
+greater than		>		>#		>?
+greater than or equal	>=		>=#		>=?
+smaller than		<		<#		<?
+smaller than or equal	<=		<=#		<=?
+regexp matches		=~		=~#		=~?
+regexp doesn't match	!~		!~#		!~?
+same instance		is
+different instance	isnot
+
+Examples:
+"abc" ==# "Abc"	  evaluates to 0
+"abc" ==? "Abc"	  evaluates to 1
+"abc" == "Abc"	  evaluates to 1 if 'ignorecase' is set, 0 otherwise
+
+							*E691* *E692*
+A |List| can only be compared with a |List| and only "equal", "not equal" and
+"is" can be used.  This compares the values of the list, recursively.
+Ignoring case means case is ignored when comparing item values.
+
+							*E735* *E736*
+A |Dictionary| can only be compared with a |Dictionary| and only "equal", "not
+equal" and "is" can be used.  This compares the key/values of the |Dictionary|
+recursively.  Ignoring case means case is ignored when comparing item values.
+
+							*E693* *E694*
+A |Funcref| can only be compared with a |Funcref| and only "equal" and "not
+equal" can be used.  Case is never ignored.
+
+When using "is" or "isnot" with a |List| this checks if the expressions are
+referring to the same |List| instance.  A copy of a |List| is different from
+the original |List|.  When using "is" without a |List| it is equivalent to
+using "equal", using "isnot" equivalent to using "not equal".  Except that a
+different type means the values are different.  "4 == '4'" is true, "4 is '4'"
+is false.
+
+When comparing a String with a Number, the String is converted to a Number,
+and the comparison is done on Numbers.  This means that "0 == 'x'" is TRUE,
+because 'x' converted to a Number is zero.
+
+When comparing two Strings, this is done with strcmp() or stricmp().  This
+results in the mathematical difference (comparing byte values), not
+necessarily the alphabetical difference in the local language.
+
+When using the operators with a trailing '#", or the short version and
+'ignorecase' is off, the comparing is done with strcmp(): case matters.
+
+When using the operators with a trailing '?', or the short version and
+'ignorecase' is set, the comparing is done with stricmp(): case is ignored.
+
+'smartcase' is not used.
+
+The "=~" and "!~" operators match the lefthand argument with the righthand
+argument, which is used as a pattern.  See |pattern| for what a pattern is.
+This matching is always done like 'magic' was set and 'cpoptions' is empty, no
+matter what the actual value of 'magic' or 'cpoptions' is.  This makes scripts
+portable.  To avoid backslashes in the regexp pattern to be doubled, use a
+single-quote string, see |literal-string|.
+Since a string is considered to be a single line, a multi-line pattern
+(containing \n, backslash-n) will not match.  However, a literal NL character
+can be matched like an ordinary character.  Examples:
+	"foo\nbar" =~ "\n"	evaluates to 1
+	"foo\nbar" =~ "\\n"	evaluates to 0
+
+
+expr5 and expr6						*expr5* *expr6*
+---------------
+expr6 +	 expr6 ..	Number addition or |List| concatenation	*expr-+*
+expr6 -	 expr6 ..	Number subtraction			*expr--*
+expr6 .	 expr6 ..	String concatenation			*expr-.*
+
+For |Lists| only "+" is possible and then both expr6 must be a list.  The
+result is a new list with the two lists Concatenated.
+
+expr7 *	 expr7 ..	number multiplication			*expr-star*
+expr7 /	 expr7 ..	number division				*expr-/*
+expr7 %	 expr7 ..	number modulo				*expr-%*
+
+For all, except ".", Strings are converted to Numbers.
+
+Note the difference between "+" and ".":
+	"123" + "456" = 579
+	"123" . "456" = "123456"
+
+When the righthand side of '/' is zero, the result is 0x7fffffff.
+When the righthand side of '%' is zero, the result is 0.
+
+None of these work for |Funcref|s.
+
+
+expr7							*expr7*
+-----
+! expr7			logical NOT		*expr-!*
+- expr7			unary minus		*expr-unary--*
++ expr7			unary plus		*expr-unary-+*
+
+For '!' non-zero becomes zero, zero becomes one.
+For '-' the sign of the number is changed.
+For '+' the number is unchanged.
+
+A String will be converted to a Number first.
+
+These three can be repeated and mixed.  Examples:
+	!-1	    == 0
+	!!8	    == 1
+	--9	    == 9
+
+
+expr8							*expr8*
+-----
+expr8[expr1]		item of String or |List|	*expr-[]* *E111*
+
+If expr8 is a Number or String this results in a String that contains the
+expr1'th single byte from expr8.  expr8 is used as a String, expr1 as a
+Number.  Note that this doesn't recognize multi-byte encodings.
+
+Index zero gives the first character.  This is like it works in C.  Careful:
+text column numbers start with one!  Example, to get the character under the
+cursor: >
+	:let c = getline(".")[col(".") - 1]
+
+If the length of the String is less than the index, the result is an empty
+String.  A negative index always results in an empty string (reason: backwards
+compatibility).  Use [-1:] to get the last byte.
+
+If expr8 is a |List| then it results the item at index expr1.  See |list-index|
+for possible index values.  If the index is out of range this results in an
+error.  Example: >
+	:let item = mylist[-1]		" get last item
+
+Generally, if a |List| index is equal to or higher than the length of the
+|List|, or more negative than the length of the |List|, this results in an
+error.
+
+
+expr8[expr1a : expr1b]	substring or sublist		*expr-[:]*
+
+If expr8 is a Number or String this results in the substring with the bytes
+from expr1a to and including expr1b.  expr8 is used as a String, expr1a and
+expr1b are used as a Number.  Note that this doesn't recognize multi-byte
+encodings.
+
+If expr1a is omitted zero is used.  If expr1b is omitted the length of the
+string minus one is used.
+
+A negative number can be used to measure from the end of the string.  -1 is
+the last character, -2 the last but one, etc.
+
+If an index goes out of range for the string characters are omitted.  If
+expr1b is smaller than expr1a the result is an empty string.
+
+Examples: >
+	:let c = name[-1:]		" last byte of a string
+	:let c = name[-2:-2]		" last but one byte of a string
+	:let s = line(".")[4:]		" from the fifth byte to the end
+	:let s = s[:-3]			" remove last two bytes
+
+If expr8 is a |List| this results in a new |List| with the items indicated by
+the indexes expr1a and expr1b.  This works like with a String, as explained
+just above, except that indexes out of range cause an error.  Examples: >
+	:let l = mylist[:3]		" first four items
+	:let l = mylist[4:4]		" List with one item
+	:let l = mylist[:]		" shallow copy of a List
+
+Using expr8[expr1] or expr8[expr1a : expr1b] on a |Funcref| results in an
+error.
+
+
+expr8.name		entry in a |Dictionary|		*expr-entry*
+
+If expr8 is a |Dictionary| and it is followed by a dot, then the following
+name will be used as a key in the |Dictionary|.  This is just like:
+expr8[name].
+
+The name must consist of alphanumeric characters, just like a variable name,
+but it may start with a number.  Curly braces cannot be used.
+
+There must not be white space before or after the dot.
+
+Examples: >
+	:let dict = {"one": 1, 2: "two"}
+	:echo dict.one
+	:echo dict .2
+
+Note that the dot is also used for String concatenation.  To avoid confusion
+always put spaces around the dot for String concatenation.
+
+
+expr8(expr1, ...)	|Funcref| function call
+
+When expr8 is a |Funcref| type variable, invoke the function it refers to.
+
+
+
+							*expr9*
+number
+------
+number			number constant		*expr-number*
+
+Decimal, Hexadecimal (starting with 0x or 0X), or Octal (starting with 0).
+
+
+string							*expr-string* *E114*
+------
+"string"		string constant		*expr-quote*
+
+Note that double quotes are used.
+
+A string constant accepts these special characters:
+\...	three-digit octal number (e.g., "\316")
+\..	two-digit octal number (must be followed by non-digit)
+\.	one-digit octal number (must be followed by non-digit)
+\x..	byte specified with two hex numbers (e.g., "\x1f")
+\x.	byte specified with one hex number (must be followed by non-hex char)
+\X..	same as \x..
+\X.	same as \x.
+\u....  character specified with up to 4 hex numbers, stored according to the
+	current value of 'encoding' (e.g., "\u02a4")
+\U....	same as \u....
+\b	backspace <BS>
+\e	escape <Esc>
+\f	formfeed <FF>
+\n	newline <NL>
+\r	return <CR>
+\t	tab <Tab>
+\\	backslash
+\"	double quote
+\<xxx>	Special key named "xxx".  e.g. "\<C-W>" for CTRL-W.
+
+Note that "\xff" is stored as the byte 255, which may be invalid in some
+encodings.  Use "\u00ff" to store character 255 according to the current value
+of 'encoding'.
+
+Note that "\000" and "\x00" force the end of the string.
+
+
+literal-string						*literal-string* *E115*
+---------------
+'string'		string constant			*expr-'*
+
+Note that single quotes are used.
+
+This string is taken as it is.  No backslashes are removed or have a special
+meaning.  The only exception is that two quotes stand for one quote.
+
+Single quoted strings are useful for patterns, so that backslashes do not need
+to be doubled.  These two commands are equivalent: >
+	if a =~ "\\s*"
+	if a =~ '\s*'
+
+
+option						*expr-option* *E112* *E113*
+------
+&option			option value, local value if possible
+&g:option		global option value
+&l:option		local option value
+
+Examples: >
+	echo "tabstop is " . &tabstop
+	if &insertmode
+
+Any option name can be used here.  See |options|.  When using the local value
+and there is no buffer-local or window-local value, the global value is used
+anyway.
+
+
+register						*expr-register* *@r*
+--------
+@r			contents of register 'r'
+
+The result is the contents of the named register, as a single string.
+Newlines are inserted where required.  To get the contents of the unnamed
+register use @" or @@.  See |registers| for an explanation of the available
+registers.
+
+When using the '=' register you get the expression itself, not what it
+evaluates to.  Use |eval()| to evaluate it.
+
+
+nesting							*expr-nesting* *E110*
+-------
+(expr1)			nested expression
+
+
+environment variable					*expr-env*
+--------------------
+$VAR			environment variable
+
+The String value of any environment variable.  When it is not defined, the
+result is an empty string.
+						*expr-env-expand*
+Note that there is a difference between using $VAR directly and using
+expand("$VAR").  Using it directly will only expand environment variables that
+are known inside the current Vim session.  Using expand() will first try using
+the environment variables known inside the current Vim session.  If that
+fails, a shell will be used to expand the variable.  This can be slow, but it
+does expand all variables that the shell knows about.  Example: >
+	:echo $version
+	:echo expand("$version")
+The first one probably doesn't echo anything, the second echoes the $version
+variable (if your shell supports it).
+
+
+internal variable					*expr-variable*
+-----------------
+variable		internal variable
+See below |internal-variables|.
+
+
+function call		*expr-function* *E116* *E118* *E119* *E120*
+-------------
+function(expr1, ...)	function call
+See below |functions|.
+
+
+==============================================================================
+3. Internal variable				*internal-variables* *E121*
+									*E461*
+An internal variable name can be made up of letters, digits and '_'.  But it
+cannot start with a digit.  It's also possible to use curly braces, see
+|curly-braces-names|.
+
+An internal variable is created with the ":let" command |:let|.
+An internal variable is explicitly destroyed with the ":unlet" command
+|:unlet|.
+Using a name that is not an internal variable or refers to a variable that has
+been destroyed results in an error.
+
+There are several name spaces for variables.  Which one is to be used is
+specified by what is prepended:
+
+		(nothing) In a function: local to a function; otherwise: global
+|buffer-variable|    b:	  Local to the current buffer.
+|window-variable|    w:	  Local to the current window.
+|tabpage-variable|   t:	  Local to the current tab page.
+|global-variable|    g:	  Global.
+|local-variable|     l:	  Local to a function.
+|script-variable|    s:	  Local to a |:source|'ed Vim script.
+|function-argument|  a:	  Function argument (only inside a function).
+|vim-variable|       v:	  Global, predefined by Vim.
+
+The scope name by itself can be used as a |Dictionary|.  For example, to
+delete all script-local variables: >
+	:for k in keys(s:)
+	:    unlet s:[k]
+	:endfor
+<
+						*buffer-variable* *b:var*
+A variable name that is preceded with "b:" is local to the current buffer.
+Thus you can have several "b:foo" variables, one for each buffer.
+This kind of variable is deleted when the buffer is wiped out or deleted with
+|:bdelete|.
+
+One local buffer variable is predefined:
+					*b:changedtick-variable* *changetick*
+b:changedtick	The total number of changes to the current buffer.  It is
+		incremented for each change.  An undo command is also a change
+		in this case.  This can be used to perform an action only when
+		the buffer has changed.  Example: >
+		    :if my_changedtick != b:changedtick
+		    :   let my_changedtick = b:changedtick
+		    :   call My_Update()
+		    :endif
+<
+						*window-variable* *w:var*
+A variable name that is preceded with "w:" is local to the current window.  It
+is deleted when the window is closed.
+
+						*tabpage-variable* *t:var*
+A variable name that is preceded with "t:" is local to the current tab page,
+It is deleted when the tab page is closed. {not available when compiled
+without the +windows feature}
+
+						*global-variable* *g:var*
+Inside functions global variables are accessed with "g:".  Omitting this will
+access a variable local to a function.  But "g:" can also be used in any other
+place if you like.
+
+						*local-variable* *l:var*
+Inside functions local variables are accessed without prepending anything.
+But you can also prepend "l:" if you like.  However, without prepending "l:"
+you may run into reserved variable names.  For example "count".  By itself it
+refers to "v:count".  Using "l:count" you can have a local variable with the
+same name.
+
+						*script-variable* *s:var*
+In a Vim script variables starting with "s:" can be used.  They cannot be
+accessed from outside of the scripts, thus are local to the script.
+
+They can be used in:
+- commands executed while the script is sourced
+- functions defined in the script
+- autocommands defined in the script
+- functions and autocommands defined in functions and autocommands which were
+  defined in the script (recursively)
+- user defined commands defined in the script
+Thus not in:
+- other scripts sourced from this one
+- mappings
+- etc.
+
+Script variables can be used to avoid conflicts with global variable names.
+Take this example: >
+
+	let s:counter = 0
+	function MyCounter()
+	  let s:counter = s:counter + 1
+	  echo s:counter
+	endfunction
+	command Tick call MyCounter()
+
+You can now invoke "Tick" from any script, and the "s:counter" variable in
+that script will not be changed, only the "s:counter" in the script where
+"Tick" was defined is used.
+
+Another example that does the same: >
+
+	let s:counter = 0
+	command Tick let s:counter = s:counter + 1 | echo s:counter
+
+When calling a function and invoking a user-defined command, the context for
+script variables is set to the script where the function or command was
+defined.
+
+The script variables are also available when a function is defined inside a
+function that is defined in a script.  Example: >
+
+	let s:counter = 0
+	function StartCounting(incr)
+	  if a:incr
+	    function MyCounter()
+	      let s:counter = s:counter + 1
+	    endfunction
+	  else
+	    function MyCounter()
+	      let s:counter = s:counter - 1
+	    endfunction
+	  endif
+	endfunction
+
+This defines the MyCounter() function either for counting up or counting down
+when calling StartCounting().  It doesn't matter from where StartCounting() is
+called, the s:counter variable will be accessible in MyCounter().
+
+When the same script is sourced again it will use the same script variables.
+They will remain valid as long as Vim is running.  This can be used to
+maintain a counter: >
+
+	if !exists("s:counter")
+	  let s:counter = 1
+	  echo "script executed for the first time"
+	else
+	  let s:counter = s:counter + 1
+	  echo "script executed " . s:counter . " times now"
+	endif
+
+Note that this means that filetype plugins don't get a different set of script
+variables for each buffer.  Use local buffer variables instead |b:var|.
+
+
+Predefined Vim variables:			*vim-variable* *v:var*
+
+					*v:beval_col* *beval_col-variable*
+v:beval_col	The number of the column, over which the mouse pointer is.
+		This is the byte index in the |v:beval_lnum| line.
+		Only valid while evaluating the 'balloonexpr' option.
+
+					*v:beval_bufnr* *beval_bufnr-variable*
+v:beval_bufnr	The number of the buffer, over which the mouse pointer is. Only
+		valid while evaluating the 'balloonexpr' option.
+
+					*v:beval_lnum* *beval_lnum-variable*
+v:beval_lnum	The number of the line, over which the mouse pointer is. Only
+		valid while evaluating the 'balloonexpr' option.
+
+					*v:beval_text* *beval_text-variable*
+v:beval_text	The text under or after the mouse pointer.  Usually a word as
+		it is useful for debugging a C program.  'iskeyword' applies,
+		but a dot and "->" before the position is included.  When on a
+		']' the text before it is used, including the matching '[' and
+		word before it.  When on a Visual area within one line the
+		highlighted text is used.
+		Only valid while evaluating the 'balloonexpr' option.
+
+					*v:beval_winnr* *beval_winnr-variable*
+v:beval_winnr	The number of the window, over which the mouse pointer is. Only
+		valid while evaluating the 'balloonexpr' option.
+
+					*v:char* *char-variable*
+v:char		Argument for evaluating 'formatexpr'.
+
+			*v:charconvert_from* *charconvert_from-variable*
+v:charconvert_from
+		The name of the character encoding of a file to be converted.
+		Only valid while evaluating the 'charconvert' option.
+
+			*v:charconvert_to* *charconvert_to-variable*
+v:charconvert_to
+		The name of the character encoding of a file after conversion.
+		Only valid while evaluating the 'charconvert' option.
+
+					*v:cmdarg* *cmdarg-variable*
+v:cmdarg	This variable is used for two purposes:
+		1. The extra arguments given to a file read/write command.
+		   Currently these are "++enc=" and "++ff=".  This variable is
+		   set before an autocommand event for a file read/write
+		   command is triggered.  There is a leading space to make it
+		   possible to append this variable directly after the
+		   read/write command.  Note: The "+cmd" argument isn't
+		   included here, because it will be executed anyway.
+		2. When printing a PostScript file with ":hardcopy" this is
+		   the argument for the ":hardcopy" command.  This can be used
+		   in 'printexpr'.
+
+					*v:cmdbang* *cmdbang-variable*
+v:cmdbang	Set like v:cmdarg for a file read/write command.  When a "!"
+		was used the value is 1, otherwise it is 0.  Note that this
+		can only be used in autocommands.  For user commands |<bang>|
+		can be used.
+
+					*v:count* *count-variable*
+v:count		The count given for the last Normal mode command.  Can be used
+		to get the count before a mapping.  Read-only.  Example: >
+	:map _x :<C-U>echo "the count is " . v:count<CR>
+<		Note: The <C-U> is required to remove the line range that you
+		get when typing ':' after a count.
+		Also used for evaluating the 'formatexpr' option.
+		"count" also works, for backwards compatibility.
+
+					*v:count1* *count1-variable*
+v:count1	Just like "v:count", but defaults to one when no count is
+		used.
+
+						*v:ctype* *ctype-variable*
+v:ctype		The current locale setting for characters of the runtime
+		environment.  This allows Vim scripts to be aware of the
+		current locale encoding.  Technical: it's the value of
+		LC_CTYPE.  When not using a locale the value is "C".
+		This variable can not be set directly, use the |:language|
+		command.
+		See |multi-lang|.
+
+					*v:dying* *dying-variable*
+v:dying		Normally zero.  When a deadly signal is caught it's set to
+		one.  When multiple signals are caught the number increases.
+		Can be used in an autocommand to check if Vim didn't
+		terminate normally. {only works on Unix}
+		Example: >
+	:au VimLeave * if v:dying | echo "\nAAAAaaaarrrggghhhh!!!\n" | endif
+<
+					*v:errmsg* *errmsg-variable*
+v:errmsg	Last given error message.  It's allowed to set this variable.
+		Example: >
+	:let v:errmsg = ""
+	:silent! next
+	:if v:errmsg != ""
+	:  ... handle error
+<		"errmsg" also works, for backwards compatibility.
+
+					*v:exception* *exception-variable*
+v:exception	The value of the exception most recently caught and not
+		finished.  See also |v:throwpoint| and |throw-variables|.
+		Example: >
+	:try
+	:  throw "oops"
+	:catch /.*/
+	:  echo "caught" v:exception
+	:endtry
+<		Output: "caught oops".
+
+					*v:fcs_reason* *fcs_reason-variable*
+v:fcs_reason	The reason why the |FileChangedShell| event was triggered.
+		Can be used in an autocommand to decide what to do and/or what
+		to set v:fcs_choice to.  Possible values:
+			deleted		file no longer exists
+			conflict	file contents, mode or timestamp was
+					changed and buffer is modified
+			changed		file contents has changed
+			mode		mode of file changed
+			time		only file timestamp changed
+
+					*v:fcs_choice* *fcs_choice-variable*
+v:fcs_choice	What should happen after a |FileChangedShell| event was
+		triggered.  Can be used in an autocommand to tell Vim what to
+		do with the affected buffer:
+			reload		Reload the buffer (does not work if
+					the file was deleted).
+			ask		Ask the user what to do, as if there
+					was no autocommand.  Except that when
+					only the timestamp changed nothing
+					will happen.
+			<empty>		Nothing, the autocommand should do
+					everything that needs to be done.
+		The default is empty.  If another (invalid) value is used then
+		Vim behaves like it is empty, there is no warning message.
+
+					*v:fname_in* *fname_in-variable*
+v:fname_in	The name of the input file.  Valid while evaluating:
+			option		used for ~
+			'charconvert'	file to be converted
+			'diffexpr'	original file
+			'patchexpr'	original file
+			'printexpr'	file to be printed
+		And set to the swap file name for |SwapExists|.
+
+					*v:fname_out* *fname_out-variable*
+v:fname_out	The name of the output file.  Only valid while
+		evaluating:
+			option		used for ~
+			'charconvert'	resulting converted file (*)
+			'diffexpr'	output of diff
+			'patchexpr'	resulting patched file
+		(*) When doing conversion for a write command (e.g., ":w
+		file") it will be equal to v:fname_in.  When doing conversion
+		for a read command (e.g., ":e file") it will be a temporary
+		file and different from v:fname_in.
+
+					*v:fname_new* *fname_new-variable*
+v:fname_new	The name of the new version of the file.  Only valid while
+		evaluating 'diffexpr'.
+
+					*v:fname_diff* *fname_diff-variable*
+v:fname_diff	The name of the diff (patch) file.  Only valid while
+		evaluating 'patchexpr'.
+
+					*v:folddashes* *folddashes-variable*
+v:folddashes	Used for 'foldtext': dashes representing foldlevel of a closed
+		fold.
+		Read-only in the |sandbox|. |fold-foldtext|
+
+					*v:foldlevel* *foldlevel-variable*
+v:foldlevel	Used for 'foldtext': foldlevel of closed fold.
+		Read-only in the |sandbox|. |fold-foldtext|
+
+					*v:foldend* *foldend-variable*
+v:foldend	Used for 'foldtext': last line of closed fold.
+		Read-only in the |sandbox|. |fold-foldtext|
+
+					*v:foldstart* *foldstart-variable*
+v:foldstart	Used for 'foldtext': first line of closed fold.
+		Read-only in the |sandbox|. |fold-foldtext|
+
+					*v:insertmode* *insertmode-variable*
+v:insertmode	Used for the |InsertEnter| and |InsertChange| autocommand
+		events.  Values:
+			i	Insert mode
+			r	Replace mode
+			v	Virtual Replace mode
+
+						*v:key* *key-variable*
+v:key		Key of the current item of a |Dictionary|.  Only valid while
+		evaluating the expression used with |map()| and |filter()|.
+		Read-only.
+
+						*v:lang* *lang-variable*
+v:lang		The current locale setting for messages of the runtime
+		environment.  This allows Vim scripts to be aware of the
+		current language.  Technical: it's the value of LC_MESSAGES.
+		The value is system dependent.
+		This variable can not be set directly, use the |:language|
+		command.
+		It can be different from |v:ctype| when messages are desired
+		in a different language than what is used for character
+		encoding.  See |multi-lang|.
+
+						*v:lc_time* *lc_time-variable*
+v:lc_time	The current locale setting for time messages of the runtime
+		environment.  This allows Vim scripts to be aware of the
+		current language.  Technical: it's the value of LC_TIME.
+		This variable can not be set directly, use the |:language|
+		command.  See |multi-lang|.
+
+						*v:lnum* *lnum-variable*
+v:lnum		Line number for the 'foldexpr' |fold-expr| and 'indentexpr'
+		expressions, tab page number for 'guitablabel' and
+		'guitabtooltip'.  Only valid while one of these expressions is
+		being evaluated.  Read-only when in the |sandbox|.
+
+					*v:mouse_win* *mouse_win-variable*
+v:mouse_win	Window number for a mouse click obtained with |getchar()|.
+		First window has number 1, like with |winnr()|.  The value is
+		zero when there was no mouse button click.
+
+					*v:mouse_lnum* *mouse_lnum-variable*
+v:mouse_lnum	Line number for a mouse click obtained with |getchar()|.
+		This is the text line number, not the screen line number.  The
+		value is zero when there was no mouse button click.
+
+					*v:mouse_col* *mouse_col-variable*
+v:mouse_col	Column number for a mouse click obtained with |getchar()|.
+		This is the screen column number, like with |virtcol()|.  The
+		value is zero when there was no mouse button click.
+
+					*v:prevcount* *prevcount-variable*
+v:prevcount	The count given for the last but one Normal mode command.
+		This is the v:count value of the previous command.  Useful if
+		you want to cancel Visual mode and then use the count. >
+			:vmap % <Esc>:call MyFilter(v:prevcount)<CR>
+<		Read-only.
+
+					*v:profiling* *profiling-variable*
+v:profiling	Normally zero.  Set to one after using ":profile start".
+		See |profiling|.
+
+					*v:progname* *progname-variable*
+v:progname	Contains the name (with path removed) with which Vim was
+		invoked.  Allows you to do special initialisations for "view",
+		"evim" etc., or any other name you might symlink to Vim.
+		Read-only.
+
+					*v:register* *register-variable*
+v:register	The name of the register supplied to the last normal mode
+		command.  Empty if none were supplied. |getreg()| |setreg()|
+
+					*v:scrollstart* *scrollstart-variable*
+v:scrollstart	String describing the script or function that caused the
+		screen to scroll up.  It's only set when it is empty, thus the
+		first reason is remembered.  It is set to "Unknown" for a
+		typed command.
+		This can be used to find out why your script causes the
+		hit-enter prompt.
+
+					*v:servername* *servername-variable*
+v:servername	The resulting registered |x11-clientserver| name if any.
+		Read-only.
+
+					*v:shell_error* *shell_error-variable*
+v:shell_error	Result of the last shell command.  When non-zero, the last
+		shell command had an error.  When zero, there was no problem.
+		This only works when the shell returns the error code to Vim.
+		The value -1 is often used when the command could not be
+		executed.  Read-only.
+		Example: >
+	:!mv foo bar
+	:if v:shell_error
+	:  echo 'could not rename "foo" to "bar"!'
+	:endif
+<		"shell_error" also works, for backwards compatibility.
+
+					*v:statusmsg* *statusmsg-variable*
+v:statusmsg	Last given status message.  It's allowed to set this variable.
+
+					*v:swapname* *swapname-variable*
+v:swapname	Only valid when executing |SwapExists| autocommands: Name of
+		the swap file found.  Read-only.
+
+					*v:swapchoice* *swapchoice-variable*
+v:swapchoice	|SwapExists| autocommands can set this to the selected choice
+		for handling an existing swap file:
+			'o'	Open read-only
+			'e'	Edit anyway
+			'r'	Recover
+			'd'	Delete swapfile
+			'q'	Quit
+			'a'	Abort
+		The value should be a single-character string.  An empty value
+		results in the user being asked, as would happen when there is
+		no SwapExists autocommand.  The default is empty.
+
+					*v:swapcommand* *swapcommand-variable*
+v:swapcommand	Normal mode command to be executed after a file has been
+		opened.  Can be used for a |SwapExists| autocommand to have
+		another Vim open the file and jump to the right place.  For
+		example, when jumping to a tag the value is ":tag tagname\r".
+		For ":edit +cmd file" the value is ":cmd\r".
+
+				*v:termresponse* *termresponse-variable*
+v:termresponse	The escape sequence returned by the terminal for the |t_RV|
+		termcap entry.  It is set when Vim receives an escape sequence
+		that starts with ESC [ or CSI and ends in a 'c', with only
+		digits, ';' and '.' in between.
+		When this option is set, the TermResponse autocommand event is
+		fired, so that you can react to the response from the
+		terminal.
+		The response from a new xterm is: "<Esc>[ Pp ; Pv ; Pc c".  Pp
+		is the terminal type: 0 for vt100 and 1 for vt220.  Pv is the
+		patch level (since this was introduced in patch 95, it's
+		always 95 or bigger).  Pc is always zero.
+		{only when compiled with |+termresponse| feature}
+
+				*v:this_session* *this_session-variable*
+v:this_session	Full filename of the last loaded or saved session file.  See
+		|:mksession|.  It is allowed to set this variable.  When no
+		session file has been saved, this variable is empty.
+		"this_session" also works, for backwards compatibility.
+
+					*v:throwpoint* *throwpoint-variable*
+v:throwpoint	The point where the exception most recently caught and not
+		finished was thrown.  Not set when commands are typed.  See
+		also |v:exception| and |throw-variables|.
+		Example: >
+	:try
+	:  throw "oops"
+	:catch /.*/
+	:  echo "Exception from" v:throwpoint
+	:endtry
+<		Output: "Exception from test.vim, line 2"
+
+						*v:val* *val-variable*
+v:val		Value of the current item of a |List| or |Dictionary|.  Only
+		valid while evaluating the expression used with |map()| and
+		|filter()|.  Read-only.
+
+					*v:version* *version-variable*
+v:version	Version number of Vim: Major version number times 100 plus
+		minor version number.  Version 5.0 is 500.  Version 5.1 (5.01)
+		is 501.  Read-only.  "version" also works, for backwards
+		compatibility.
+		Use |has()| to check if a certain patch was included, e.g.: >
+			if has("patch123")
+<		Note that patch numbers are specific to the version, thus both
+		version 5.0 and 5.1 may have a patch 123, but these are
+		completely different.
+
+					*v:warningmsg* *warningmsg-variable*
+v:warningmsg	Last given warning message.  It's allowed to set this variable.
+
+==============================================================================
+4. Builtin Functions					*functions*
+
+See |function-list| for a list grouped by what the function is used for.
+
+(Use CTRL-] on the function name to jump to the full explanation.)
+
+USAGE				RESULT	DESCRIPTION	~
+
+add( {list}, {item})		List	append {item} to |List| {list}
+append( {lnum}, {string})	Number	append {string} below line {lnum}
+append( {lnum}, {list})		Number	append lines {list} below line {lnum}
+argc()				Number	number of files in the argument list
+argidx()			Number	current index in the argument list
+argv( {nr})			String	{nr} entry of the argument list
+argv( )				List	the argument list
+browse( {save}, {title}, {initdir}, {default})
+				String	put up a file requester
+browsedir( {title}, {initdir})  String	put up a directory requester
+bufexists( {expr})		Number	TRUE if buffer {expr} exists
+buflisted( {expr})		Number	TRUE if buffer {expr} is listed
+bufloaded( {expr})		Number	TRUE if buffer {expr} is loaded
+bufname( {expr})		String	Name of the buffer {expr}
+bufnr( {expr})			Number	Number of the buffer {expr}
+bufwinnr( {expr})		Number	window number of buffer {expr}
+byte2line( {byte})		Number	line number at byte count {byte}
+byteidx( {expr}, {nr})		Number	byte index of {nr}'th char in {expr}
+call( {func}, {arglist} [, {dict}])
+				any	call {func} with arguments {arglist}
+changenr()			Number  current change number
+char2nr( {expr})		Number	ASCII value of first char in {expr}
+cindent( {lnum})		Number	C indent for line {lnum}
+col( {expr})			Number	column nr of cursor or mark
+complete({startcol}, {matches})	String  set Insert mode completion
+complete_add( {expr})		Number	add completion match
+complete_check()		Number  check for key typed during completion
+confirm( {msg} [, {choices} [, {default} [, {type}]]])
+				Number	number of choice picked by user
+copy( {expr})			any	make a shallow copy of {expr}
+count( {list}, {expr} [, {start} [, {ic}]])
+				Number	 count how many {expr} are in {list}
+cscope_connection( [{num} , {dbpath} [, {prepend}]])
+				Number	checks existence of cscope connection
+cursor( {lnum}, {col} [, {coladd}])
+				Number	move cursor to {lnum}, {col}, {coladd}
+cursor( {list})			Number	move cursor to position in {list}
+deepcopy( {expr})		any	make a full copy of {expr}
+delete( {fname})		Number	delete file {fname}
+did_filetype()			Number	TRUE if FileType autocommand event used
+diff_filler( {lnum})		Number	diff filler lines about {lnum}
+diff_hlID( {lnum}, {col})	Number	diff highlighting at {lnum}/{col}
+empty( {expr})			Number	TRUE if {expr} is empty
+escape( {string}, {chars})	String	escape {chars} in {string} with '\'
+eval( {string})			any	evaluate {string} into its value
+eventhandler( )			Number	TRUE if inside an event handler
+executable( {expr})		Number	1 if executable {expr} exists
+exists( {expr})			Number	TRUE if {expr} exists
+extend({expr1}, {expr2} [, {expr3}])
+				List/Dict insert items of {expr2} into {expr1}
+expand( {expr})			String	expand special keywords in {expr}
+feedkeys( {string} [, {mode}])	Number  add key sequence to typeahead buffer
+filereadable( {file})		Number	TRUE if {file} is a readable file
+filewritable( {file})		Number	TRUE if {file} is a writable file
+filter( {expr}, {string})	List/Dict  remove items from {expr} where
+					{string} is 0
+finddir( {name}[, {path}[, {count}]])
+				String	find directory {name} in {path}
+findfile( {name}[, {path}[, {count}]])
+				String	find file {name} in {path}
+fnamemodify( {fname}, {mods})	String	modify file name
+foldclosed( {lnum})		Number	first line of fold at {lnum} if closed
+foldclosedend( {lnum})		Number	last line of fold at {lnum} if closed
+foldlevel( {lnum})		Number	fold level at {lnum}
+foldtext( )			String	line displayed for closed fold
+foldtextresult( {lnum})		String	text for closed fold at {lnum}
+foreground( )			Number	bring the Vim window to the foreground
+function( {name})		Funcref reference to function {name}
+garbagecollect()		none	free memory, breaking cyclic references
+get( {list}, {idx} [, {def}])	any	get item {idx} from {list} or {def}
+get( {dict}, {key} [, {def}])	any	get item {key} from {dict} or {def}
+getbufline( {expr}, {lnum} [, {end}])
+				List	lines {lnum} to {end} of buffer {expr}
+getbufvar( {expr}, {varname})	any	variable {varname} in buffer {expr}
+getchar( [expr])		Number	get one character from the user
+getcharmod( )			Number	modifiers for the last typed character
+getcmdline()			String	return the current command-line
+getcmdpos()			Number	return cursor position in command-line
+getcmdtype()			String	return the current command-line type
+getcwd()			String	the current working directory
+getfperm( {fname})		String	file permissions of file {fname}
+getfsize( {fname})		Number	size in bytes of file {fname}
+getfontname( [{name}])		String	name of font being used
+getftime( {fname})		Number	last modification time of file
+getftype( {fname})		String	description of type of file {fname}
+getline( {lnum})		String	line {lnum} of current buffer
+getline( {lnum}, {end})		List	lines {lnum} to {end} of current buffer
+getloclist({nr})		List	list of location list items
+getpos( {expr})			List	position of cursor, mark, etc.
+getqflist()			List	list of quickfix items
+getreg( [{regname} [, 1]])	String	contents of register
+getregtype( [{regname}])	String	type of register
+gettabwinvar( {tabnr}, {winnr}, {name})
+				any	{name} in {winnr} in tab page {tabnr}
+getwinposx()			Number	X coord in pixels of GUI Vim window
+getwinposy()			Number	Y coord in pixels of GUI Vim window
+getwinvar( {nr}, {varname})	any	variable {varname} in window {nr}
+glob( {expr})			String	expand file wildcards in {expr}
+globpath( {path}, {expr})	String	do glob({expr}) for all dirs in {path}
+has( {feature})			Number	TRUE if feature {feature} supported
+has_key( {dict}, {key})		Number	TRUE if {dict} has entry {key}
+haslocaldir()			Number	TRUE if current window executed |:lcd|
+hasmapto( {what} [, {mode} [, {abbr}]])
+				Number	TRUE if mapping to {what} exists
+histadd( {history},{item})	String	add an item to a history
+histdel( {history} [, {item}])	String	remove an item from a history
+histget( {history} [, {index}])	String	get the item {index} from a history
+histnr( {history})		Number	highest index of a history
+hlexists( {name})		Number	TRUE if highlight group {name} exists
+hlID( {name})			Number	syntax ID of highlight group {name}
+hostname()			String	name of the machine Vim is running on
+iconv( {expr}, {from}, {to})	String	convert encoding of {expr}
+indent( {lnum})			Number	indent of line {lnum}
+index( {list}, {expr} [, {start} [, {ic}]])
+				Number	index in {list} where {expr} appears
+input( {prompt} [, {text} [, {completion}]])
+				String	get input from the user
+inputdialog( {p} [, {t} [, {c}]]) String  like input() but in a GUI dialog
+inputlist( {textlist})		Number	let the user pick from a choice list
+inputrestore()			Number	restore typeahead
+inputsave()			Number	save and clear typeahead
+inputsecret( {prompt} [, {text}]) String  like input() but hiding the text
+insert( {list}, {item} [, {idx}]) List	insert {item} in {list} [before {idx}]
+isdirectory( {directory})	Number	TRUE if {directory} is a directory
+islocked( {expr})		Number	TRUE if {expr} is locked
+items( {dict})			List	key-value pairs in {dict}
+join( {list} [, {sep}])		String	join {list} items into one String
+keys( {dict})			List	keys in {dict}
+len( {expr})			Number	the length of {expr}
+libcall( {lib}, {func}, {arg})	String	call {func} in library {lib} with {arg}
+libcallnr( {lib}, {func}, {arg})  Number  idem, but return a Number
+line( {expr})			Number	line nr of cursor, last line or mark
+line2byte( {lnum})		Number	byte count of line {lnum}
+lispindent( {lnum})		Number	Lisp indent for line {lnum}
+localtime()			Number	current time
+map( {expr}, {string})		List/Dict  change each item in {expr} to {expr}
+maparg( {name}[, {mode} [, {abbr}]])
+				String	rhs of mapping {name} in mode {mode}
+mapcheck( {name}[, {mode} [, {abbr}]])
+				String	check for mappings matching {name}
+match( {expr}, {pat}[, {start}[, {count}]])
+				Number	position where {pat} matches in {expr}
+matcharg( {nr})			List	arguments of |:match|
+matchend( {expr}, {pat}[, {start}[, {count}]])
+				Number	position where {pat} ends in {expr}
+matchlist( {expr}, {pat}[, {start}[, {count}]])
+				List	match and submatches of {pat} in {expr}
+matchstr( {expr}, {pat}[, {start}[, {count}]])
+				String	{count}'th match of {pat} in {expr}
+max({list})			Number	maximum value of items in {list}
+min({list})			Number	minimum value of items in {list}
+mkdir({name} [, {path} [, {prot}]])
+				Number	create directory {name}
+mode()				String	current editing mode
+nextnonblank( {lnum})		Number	line nr of non-blank line >= {lnum}
+nr2char( {expr})		String	single char with ASCII value {expr}
+pathshorten( {expr})		String	shorten directory names in a path
+prevnonblank( {lnum})		Number	line nr of non-blank line <= {lnum}
+printf( {fmt}, {expr1}...)	String  format text
+pumvisible()			Number  whether popup menu is visible
+range( {expr} [, {max} [, {stride}]])
+				List	items from {expr} to {max}
+readfile({fname} [, {binary} [, {max}]])
+				List	get list of lines from file {fname}
+reltime( [{start} [, {end}]])	List	get time value
+reltimestr( {time})		String	turn time value into a String
+remote_expr( {server}, {string} [, {idvar}])
+				String	send expression
+remote_foreground( {server})	Number	bring Vim server to the foreground
+remote_peek( {serverid} [, {retvar}])
+				Number	check for reply string
+remote_read( {serverid})	String	read reply string
+remote_send( {server}, {string} [, {idvar}])
+				String	send key sequence
+remove( {list}, {idx} [, {end}])  any	remove items {idx}-{end} from {list}
+remove( {dict}, {key})		any	remove entry {key} from {dict}
+rename( {from}, {to})		Number	rename (move) file from {from} to {to}
+repeat( {expr}, {count})	String	repeat {expr} {count} times
+resolve( {filename})		String	get filename a shortcut points to
+reverse( {list})		List	reverse {list} in-place
+search( {pattern} [, {flags}])	Number	search for {pattern}
+searchdecl({name} [, {global} [, {thisblock}]])
+				Number  search for variable declaration
+searchpair( {start}, {middle}, {end} [, {flags} [, {skip} [, {stopline}]]])
+				Number	search for other end of start/end pair
+searchpairpos( {start}, {middle}, {end} [, {flags} [, {skip} [, {stopline}]]])
+				List	search for other end of start/end pair
+searchpos( {pattern} [, {flags} [, {stopline}]])
+				List	search for {pattern}
+server2client( {clientid}, {string})
+				Number	send reply string
+serverlist()			String	get a list of available servers
+setbufvar( {expr}, {varname}, {val})	set {varname} in buffer {expr} to {val}
+setcmdpos( {pos})		Number	set cursor position in command-line
+setline( {lnum}, {line})	Number	set line {lnum} to {line}
+setloclist( {nr}, {list}[, {action}])
+				Number	modify location list using {list}
+setpos( {expr}, {list})		none	set the {expr} position to {list}
+setqflist( {list}[, {action}])	Number	modify quickfix list using {list}
+setreg( {n}, {v}[, {opt}])	Number	set register to value and type
+settabwinvar( {tabnr}, {winnr}, {varname}, {val})    set {varname} in window
+					{winnr} in tab page {tabnr} to {val}
+setwinvar( {nr}, {varname}, {val})	set {varname} in window {nr} to {val}
+shellescape( {string})		String	escape {string} for use as shell
+					command argument
+simplify( {filename})		String	simplify filename as much as possible
+sort( {list} [, {func}])	List	sort {list}, using {func} to compare
+soundfold( {word})		String	sound-fold {word}
+spellbadword()			String	badly spelled word at cursor
+spellsuggest( {word} [, {max} [, {capital}]])
+				List	spelling suggestions
+split( {expr} [, {pat} [, {keepempty}]])
+				List	make |List| from {pat} separated {expr}
+str2nr( {expr} [, {base}])	Number	convert string to number
+strftime( {format}[, {time}])	String	time in specified format
+stridx( {haystack}, {needle}[, {start}])
+				Number	index of {needle} in {haystack}
+string( {expr})			String	String representation of {expr} value
+strlen( {expr})			Number	length of the String {expr}
+strpart( {src}, {start}[, {len}])
+				String	{len} characters of {src} at {start}
+strridx( {haystack}, {needle} [, {start}])
+				Number	last index of {needle} in {haystack}
+strtrans( {expr})		String	translate string to make it printable
+submatch( {nr})			String	specific match in ":substitute"
+substitute( {expr}, {pat}, {sub}, {flags})
+				String	all {pat} in {expr} replaced with {sub}
+synID( {lnum}, {col}, {trans})	Number	syntax ID at {lnum} and {col}
+synIDattr( {synID}, {what} [, {mode}])
+				String	attribute {what} of syntax ID {synID}
+synIDtrans( {synID})		Number	translated syntax ID of {synID}
+system( {expr} [, {input}])	String	output of shell command/filter {expr}
+tabpagebuflist( [{arg}])	List	list of buffer numbers in tab page
+tabpagenr( [{arg}])		Number	number of current or last tab page
+tabpagewinnr( {tabarg}[, {arg}])
+				Number	number of current window in tab page
+taglist( {expr})		List	list of tags matching {expr}
+tagfiles()			List    tags files used
+tempname()			String	name for a temporary file
+tolower( {expr})		String	the String {expr} switched to lowercase
+toupper( {expr})		String	the String {expr} switched to uppercase
+tr( {src}, {fromstr}, {tostr})	String	translate chars of {src} in {fromstr}
+					to chars in {tostr}
+type( {name})			Number	type of variable {name}
+values( {dict})			List	values in {dict}
+virtcol( {expr})		Number	screen column of cursor or mark
+visualmode( [expr])		String	last visual mode used
+winbufnr( {nr})			Number	buffer number of window {nr}
+wincol()			Number	window column of the cursor
+winheight( {nr})		Number	height of window {nr}
+winline()			Number	window line of the cursor
+winnr( [{expr}])		Number	number of current window
+winrestcmd()			String	returns command to restore window sizes
+winrestview({dict})		None	restore view of current window
+winsaveview()			Dict	save view of current window
+winwidth( {nr})			Number	width of window {nr}
+writefile({list}, {fname} [, {binary}])
+				Number	write list of lines to file {fname}
+
+add({list}, {expr})					*add()*
+		Append the item {expr} to |List| {list}.  Returns the
+		resulting |List|.  Examples: >
+			:let alist = add([1, 2, 3], item)
+			:call add(mylist, "woodstock")
+<		Note that when {expr} is a |List| it is appended as a single
+		item.  Use |extend()| to concatenate |Lists|.
+		Use |insert()| to add an item at another position.
+
+
+append({lnum}, {expr})					*append()*
+		When {expr} is a |List|: Append each item of the |List| as a
+		text line below line {lnum} in the current buffer.
+		Otherwise append {expr} as one text line below line {lnum} in
+		the current buffer.
+		{lnum} can be zero to insert a line before the first one.
+		Returns 1 for failure ({lnum} out of range or out of memory),
+		0 for success.  Example: >
+			:let failed = append(line('$'), "# THE END")
+			:let failed = append(0, ["Chapter 1", "the beginning"])
+<
+							*argc()*
+argc()		The result is the number of files in the argument list of the
+		current window.  See |arglist|.
+
+							*argidx()*
+argidx()	The result is the current index in the argument list.  0 is
+		the first file.  argc() - 1 is the last one.  See |arglist|.
+
+							*argv()*
+argv([{nr}])	The result is the {nr}th file in the argument list of the
+		current window.  See |arglist|.  "argv(0)" is the first one.
+		Example: >
+	:let i = 0
+	:while i < argc()
+	:  let f = escape(argv(i), '. ')
+	:  exe 'amenu Arg.' . f . ' :e ' . f . '<CR>'
+	:  let i = i + 1
+	:endwhile
+<		Without the {nr} argument a |List| with the whole |arglist| is
+		returned.
+
+							*browse()*
+browse({save}, {title}, {initdir}, {default})
+		Put up a file requester.  This only works when "has("browse")"
+		returns non-zero (only in some GUI versions).
+		The input fields are:
+		    {save}	when non-zero, select file to write
+		    {title}	title for the requester
+		    {initdir}	directory to start browsing in
+		    {default}	default file name
+		When the "Cancel" button is hit, something went wrong, or
+		browsing is not possible, an empty string is returned.
+
+							*browsedir()*
+browsedir({title}, {initdir})
+		Put up a directory requester.  This only works when
+		"has("browse")" returns non-zero (only in some GUI versions).
+		On systems where a directory browser is not supported a file
+		browser is used.  In that case: select a file in the directory
+		to be used.
+		The input fields are:
+		    {title}	title for the requester
+		    {initdir}	directory to start browsing in
+		When the "Cancel" button is hit, something went wrong, or
+		browsing is not possible, an empty string is returned.
+
+bufexists({expr})					*bufexists()*
+		The result is a Number, which is non-zero if a buffer called
+		{expr} exists.
+		If the {expr} argument is a number, buffer numbers are used.
+		If the {expr} argument is a string it must match a buffer name
+		exactly.  The name can be:
+		- Relative to the current directory.
+		- A full path.
+		- The name of a buffer with 'filetype' set to "nofile".
+		- A URL name.
+		Unlisted buffers will be found.
+		Note that help files are listed by their short name in the
+		output of |:buffers|, but bufexists() requires using their
+		long name to be able to find them.
+		Use "bufexists(0)" to test for the existence of an alternate
+		file name.
+							*buffer_exists()*
+		Obsolete name: buffer_exists().
+
+buflisted({expr})					*buflisted()*
+		The result is a Number, which is non-zero if a buffer called
+		{expr} exists and is listed (has the 'buflisted' option set).
+		The {expr} argument is used like with |bufexists()|.
+
+bufloaded({expr})					*bufloaded()*
+		The result is a Number, which is non-zero if a buffer called
+		{expr} exists and is loaded (shown in a window or hidden).
+		The {expr} argument is used like with |bufexists()|.
+
+bufname({expr})						*bufname()*
+		The result is the name of a buffer, as it is displayed by the
+		":ls" command.
+		If {expr} is a Number, that buffer number's name is given.
+		Number zero is the alternate buffer for the current window.
+		If {expr} is a String, it is used as a |file-pattern| to match
+		with the buffer names.  This is always done like 'magic' is
+		set and 'cpoptions' is empty.  When there is more than one
+		match an empty string is returned.
+		"" or "%" can be used for the current buffer, "#" for the
+		alternate buffer.
+		A full match is preferred, otherwise a match at the start, end
+		or middle of the buffer name is accepted.  If you only want a
+		full match then put "^" at the start and "$" at the end of the
+		pattern.
+		Listed buffers are found first.  If there is a single match
+		with a listed buffer, that one is returned.  Next unlisted
+		buffers are searched for.
+		If the {expr} is a String, but you want to use it as a buffer
+		number, force it to be a Number by adding zero to it: >
+			:echo bufname("3" + 0)
+<		If the buffer doesn't exist, or doesn't have a name, an empty
+		string is returned. >
+	bufname("#")		alternate buffer name
+	bufname(3)		name of buffer 3
+	bufname("%")		name of current buffer
+	bufname("file2")	name of buffer where "file2" matches.
+<							*buffer_name()*
+		Obsolete name: buffer_name().
+
+							*bufnr()*
+bufnr({expr} [, {create}])
+		The result is the number of a buffer, as it is displayed by
+		the ":ls" command.  For the use of {expr}, see |bufname()|
+		above.
+		If the buffer doesn't exist, -1 is returned.  Or, if the
+		{create} argument is present and not zero, a new, unlisted,
+		buffer is created and its number is returned.
+		bufnr("$") is the last buffer: >
+	:let last_buffer = bufnr("$")
+<		The result is a Number, which is the highest buffer number
+		of existing buffers.  Note that not all buffers with a smaller
+		number necessarily exist, because ":bwipeout" may have removed
+		them.  Use bufexists() to test for the existence of a buffer.
+							*buffer_number()*
+		Obsolete name: buffer_number().
+							*last_buffer_nr()*
+		Obsolete name for bufnr("$"): last_buffer_nr().
+
+bufwinnr({expr})					*bufwinnr()*
+		The result is a Number, which is the number of the first
+		window associated with buffer {expr}.  For the use of {expr},
+		see |bufname()| above.  If buffer {expr} doesn't exist or
+		there is no such window, -1 is returned.  Example: >
+
+	echo "A window containing buffer 1 is " . (bufwinnr(1))
+
+<		The number can be used with |CTRL-W_w| and ":wincmd w"
+		|:wincmd|.
+		Only deals with the current tab page.
+
+
+byte2line({byte})					*byte2line()*
+		Return the line number that contains the character at byte
+		count {byte} in the current buffer.  This includes the
+		end-of-line character, depending on the 'fileformat' option
+		for the current buffer.  The first character has byte count
+		one.
+		Also see |line2byte()|, |go| and |:goto|.
+		{not available when compiled without the |+byte_offset|
+		feature}
+
+byteidx({expr}, {nr})					*byteidx()*
+		Return byte index of the {nr}'th character in the string
+		{expr}.  Use zero for the first character, it returns zero.
+		This function is only useful when there are multibyte
+		characters, otherwise the returned value is equal to {nr}.
+		Composing characters are counted as a separate character.
+		Example : >
+			echo matchstr(str, ".", byteidx(str, 3))
+<		will display the fourth character.  Another way to do the
+		same: >
+			let s = strpart(str, byteidx(str, 3))
+			echo strpart(s, 0, byteidx(s, 1))
+<		If there are less than {nr} characters -1 is returned.
+		If there are exactly {nr} characters the length of the string
+		is returned.
+
+call({func}, {arglist} [, {dict}])			*call()* *E699*
+		Call function {func} with the items in |List| {arglist} as
+		arguments.
+		{func} can either be a |Funcref| or the name of a function.
+		a:firstline and a:lastline are set to the cursor line.
+		Returns the return value of the called function.
+		{dict} is for functions with the "dict" attribute.  It will be
+		used to set the local variable "self". |Dictionary-function|
+
+changenr()						*changenr()*
+		Return the number of the most recent change.  This is the same
+		number as what is displayed with |:undolist| and can be used
+		with the |:undo| command.
+		When a change was made it is the number of that change.  After
+		redo it is the number of the redone change.  After undo it is
+		one less than the number of the undone change.
+
+char2nr({expr})						*char2nr()*
+		Return number value of the first char in {expr}.  Examples: >
+			char2nr(" ")		returns 32
+			char2nr("ABC")		returns 65
+<		The current 'encoding' is used.  Example for "utf-8": >
+			char2nr("�")		returns 225
+			char2nr("�"[0])		returns 195
+<		nr2char() does the opposite.
+
+cindent({lnum})						*cindent()*
+		Get the amount of indent for line {lnum} according the C
+		indenting rules, as with 'cindent'.
+		The indent is counted in spaces, the value of 'tabstop' is
+		relevant.  {lnum} is used just like in |getline()|.
+		When {lnum} is invalid or Vim was not compiled the |+cindent|
+		feature, -1 is returned.
+		See |C-indenting|.
+
+							*col()*
+col({expr})	The result is a Number, which is the byte index of the column
+		position given with {expr}.  The accepted positions are:
+		    .	    the cursor position
+		    $	    the end of the cursor line (the result is the
+			    number of characters in the cursor line plus one)
+		    'x	    position of mark x (if the mark is not set, 0 is
+			    returned)
+		To get the line number use |line()|.  To get both use
+		|getpos()|.
+		For the screen column position use |virtcol()|.
+		Note that only marks in the current file can be used.
+		Examples: >
+			col(".")		column of cursor
+			col("$")		length of cursor line plus one
+			col("'t")		column of mark t
+			col("'" . markname)	column of mark markname
+<		The first column is 1.  0 is returned for an error.
+		For an uppercase mark the column may actually be in another
+		buffer.
+		For the cursor position, when 'virtualedit' is active, the
+		column is one higher if the cursor is after the end of the
+		line.  This can be used to obtain the column in Insert mode: >
+			:imap <F2> <C-O>:let save_ve = &ve<CR>
+				\<C-O>:set ve=all<CR>
+				\<C-O>:echo col(".") . "\n" <Bar>
+				\let &ve = save_ve<CR>
+<
+
+complete({startcol}, {matches})			*complete()* *E785*
+		Set the matches for Insert mode completion.
+		Can only be used in Insert mode.  You need to use a mapping
+		with CTRL-R = |i_CTRL-R|.  It does not work after CTRL-O or
+		with an expression mapping.
+		{startcol} is the byte offset in the line where the completed
+		text start.  The text up to the cursor is the original text
+		that will be replaced by the matches.  Use col('.') for an
+		empty string.  "col('.') - 1" will replace one character by a
+		match.
+		{matches} must be a |List|.  Each |List| item is one match.
+		See |complete-items| for the kind of items that are possible.
+		Note that the after calling this function you need to avoid
+		inserting anything that would completion to stop.
+		The match can be selected with CTRL-N and CTRL-P as usual with
+		Insert mode completion.  The popup menu will appear if
+		specified, see |ins-completion-menu|.
+		Example: >
+	inoremap <F5> <C-R>=ListMonths()<CR>
+
+	func! ListMonths()
+	  call complete(col('.'), ['January', 'February', 'March',
+		\ 'April', 'May', 'June', 'July', 'August', 'September',
+		\ 'October', 'November', 'December'])
+	  return ''
+	endfunc
+<		This isn't very useful, but it shows how it works.  Note that
+		an empty string is returned to avoid a zero being inserted.
+
+complete_add({expr})				*complete_add()*
+		Add {expr} to the list of matches.  Only to be used by the
+		function specified with the 'completefunc' option.
+		Returns 0 for failure (empty string or out of memory),
+		1 when the match was added, 2 when the match was already in
+		the list.
+		See |complete-functions| for an explanation of {expr}.  It is
+		the same as one item in the list that 'omnifunc' would return.
+
+complete_check()				*complete_check()*
+		Check for a key typed while looking for completion matches.
+		This is to be used when looking for matches takes some time.
+		Returns non-zero when searching for matches is to be aborted,
+		zero otherwise.
+		Only to be used by the function specified with the
+		'completefunc' option.
+
+						*confirm()*
+confirm({msg} [, {choices} [, {default} [, {type}]]])
+		Confirm() offers the user a dialog, from which a choice can be
+		made.  It returns the number of the choice.  For the first
+		choice this is 1.
+		Note: confirm() is only supported when compiled with dialog
+		support, see |+dialog_con| and |+dialog_gui|.
+		{msg} is displayed in a |dialog| with {choices} as the
+		alternatives.  When {choices} is missing or empty, "&OK" is
+		used (and translated).
+		{msg} is a String, use '\n' to include a newline.  Only on
+		some systems the string is wrapped when it doesn't fit.
+		{choices} is a String, with the individual choices separated
+		by '\n', e.g. >
+			confirm("Save changes?", "&Yes\n&No\n&Cancel")
+<		The letter after the '&' is the shortcut key for that choice.
+		Thus you can type 'c' to select "Cancel".  The shortcut does
+		not need to be the first letter: >
+			confirm("file has been modified", "&Save\nSave &All")
+<		For the console, the first letter of each choice is used as
+		the default shortcut key.
+		The optional {default} argument is the number of the choice
+		that is made if the user hits <CR>.  Use 1 to make the first
+		choice the default one.  Use 0 to not set a default.  If
+		{default} is omitted, 1 is used.
+		The optional {type} argument gives the type of dialog.  This
+		is only used for the icon of the Win32 GUI.  It can be one of
+		these values: "Error", "Question", "Info", "Warning" or
+		"Generic".  Only the first character is relevant.  When {type}
+		is omitted, "Generic" is used.
+		If the user aborts the dialog by pressing <Esc>, CTRL-C,
+		or another valid interrupt key, confirm() returns 0.
+
+		An example: >
+   :let choice = confirm("What do you want?", "&Apples\n&Oranges\n&Bananas", 2)
+   :if choice == 0
+   :	echo "make up your mind!"
+   :elseif choice == 3
+   :	echo "tasteful"
+   :else
+   :	echo "I prefer bananas myself."
+   :endif
+<		In a GUI dialog, buttons are used.  The layout of the buttons
+		depends on the 'v' flag in 'guioptions'.  If it is included,
+		the buttons are always put vertically.  Otherwise,  confirm()
+		tries to put the buttons in one horizontal line.  If they
+		don't fit, a vertical layout is used anyway.  For some systems
+		the horizontal layout is always used.
+
+							*copy()*
+copy({expr})	Make a copy of {expr}.  For Numbers and Strings this isn't
+		different from using {expr} directly.
+		When {expr} is a |List| a shallow copy is created.  This means
+		that the original |List| can be changed without changing the
+		copy, and vise versa.  But the items are identical, thus
+		changing an item changes the contents of both |Lists|.  Also
+		see |deepcopy()|.
+
+count({comp}, {expr} [, {ic} [, {start}]])			*count()*
+		Return the number of times an item with value {expr} appears
+		in |List| or |Dictionary| {comp}.
+		If {start} is given then start with the item with this index.
+		{start} can only be used with a |List|.
+		When {ic} is given and it's non-zero then case is ignored.
+
+
+							*cscope_connection()*
+cscope_connection([{num} , {dbpath} [, {prepend}]])
+		Checks for the existence of a |cscope| connection.  If no
+		parameters are specified, then the function returns:
+			0, if cscope was not available (not compiled in), or
+			   if there are no cscope connections;
+			1, if there is at least one cscope connection.
+
+		If parameters are specified, then the value of {num}
+		determines how existence of a cscope connection is checked:
+
+		{num}	Description of existence check
+		-----	------------------------------
+		0	Same as no parameters (e.g., "cscope_connection()").
+		1	Ignore {prepend}, and use partial string matches for
+			{dbpath}.
+		2	Ignore {prepend}, and use exact string matches for
+			{dbpath}.
+		3	Use {prepend}, use partial string matches for both
+			{dbpath} and {prepend}.
+		4	Use {prepend}, use exact string matches for both
+			{dbpath} and {prepend}.
+
+		Note: All string comparisons are case sensitive!
+
+		Examples.  Suppose we had the following (from ":cs show"): >
+
+  # pid    database name			prepend path
+  0 27664  cscope.out				/usr/local
+<
+		Invocation					Return Val ~
+		----------					---------- >
+		cscope_connection()					1
+		cscope_connection(1, "out")				1
+		cscope_connection(2, "out")				0
+		cscope_connection(3, "out")				0
+		cscope_connection(3, "out", "local")			1
+		cscope_connection(4, "out")				0
+		cscope_connection(4, "out", "local")			0
+		cscope_connection(4, "cscope.out", "/usr/local")	1
+<
+cursor({lnum}, {col} [, {off}])				*cursor()*
+cursor({list})
+		Positions the cursor at the column (byte count) {col} in the
+		line {lnum}.  The first column is one.
+		When there is one argument {list} this is used as a |List|
+		with two or three items {lnum}, {col} and {off}.  This is like
+		the return value of |getpos()|, but without the first item.
+		Does not change the jumplist.
+		If {lnum} is greater than the number of lines in the buffer,
+		the cursor will be positioned at the last line in the buffer.
+		If {lnum} is zero, the cursor will stay in the current line.
+		If {col} is greater than the number of bytes in the line,
+		the cursor will be positioned at the last character in the
+		line.
+		If {col} is zero, the cursor will stay in the current column.
+		When 'virtualedit' is used {off} specifies the offset in
+		screen columns from the start of the character.  E.g., a
+		position within a <Tab> or after the last character.
+
+
+deepcopy({expr}[, {noref}])				*deepcopy()* *E698*
+		Make a copy of {expr}.  For Numbers and Strings this isn't
+		different from using {expr} directly.
+		When {expr} is a |List| a full copy is created.  This means
+		that the original |List| can be changed without changing the
+		copy, and vise versa.  When an item is a |List|, a copy for it
+		is made, recursively.  Thus changing an item in the copy does
+		not change the contents of the original |List|.
+		When {noref} is omitted or zero a contained |List| or
+		|Dictionary| is only copied once.  All references point to
+		this single copy.  With {noref} set to 1 every occurrence of a
+		|List| or |Dictionary| results in a new copy.  This also means
+		that a cyclic reference causes deepcopy() to fail.
+								*E724*
+		Nesting is possible up to 100 levels.  When there is an item
+		that refers back to a higher level making a deep copy with
+		{noref} set to 1 will fail.
+		Also see |copy()|.
+
+delete({fname})							*delete()*
+		Deletes the file by the name {fname}.  The result is a Number,
+		which is 0 if the file was deleted successfully, and non-zero
+		when the deletion failed.
+		Use |remove()| to delete an item from a |List|.
+
+							*did_filetype()*
+did_filetype()	Returns non-zero when autocommands are being executed and the
+		FileType event has been triggered at least once.  Can be used
+		to avoid triggering the FileType event again in the scripts
+		that detect the file type. |FileType|
+		When editing another file, the counter is reset, thus this
+		really checks if the FileType event has been triggered for the
+		current buffer.  This allows an autocommand that starts
+		editing another buffer to set 'filetype' and load a syntax
+		file.
+
+diff_filler({lnum})					*diff_filler()*
+		Returns the number of filler lines above line {lnum}.
+		These are the lines that were inserted at this point in
+		another diff'ed window.  These filler lines are shown in the
+		display but don't exist in the buffer.
+		{lnum} is used like with |getline()|.  Thus "." is the current
+		line, "'m" mark m, etc.
+		Returns 0 if the current window is not in diff mode.
+
+diff_hlID({lnum}, {col})				*diff_hlID()*
+		Returns the highlight ID for diff mode at line {lnum} column
+		{col} (byte index).  When the current line does not have a
+		diff change zero is returned.
+		{lnum} is used like with |getline()|.  Thus "." is the current
+		line, "'m" mark m, etc.
+		{col} is 1 for the leftmost column, {lnum} is 1 for the first
+		line.
+		The highlight ID can be used with |synIDattr()| to obtain
+		syntax information about the highlighting.
+
+empty({expr})						*empty()*
+		Return the Number 1 if {expr} is empty, zero otherwise.
+		A |List| or |Dictionary| is empty when it does not have any
+		items.  A Number is empty when its value is zero.
+		For a long |List| this is much faster then comparing the
+		length with zero.
+
+escape({string}, {chars})				*escape()*
+		Escape the characters in {chars} that occur in {string} with a
+		backslash.  Example: >
+			:echo escape('c:\program files\vim', ' \')
+<		results in: >
+			c:\\program\ files\\vim
+
+<							*eval()*
+eval({string})	Evaluate {string} and return the result.  Especially useful to
+		turn the result of |string()| back into the original value.
+		This works for Numbers, Strings and composites of them.
+		Also works for |Funcref|s that refer to existing functions.
+
+eventhandler()						*eventhandler()*
+		Returns 1 when inside an event handler.  That is that Vim got
+		interrupted while waiting for the user to type a character,
+		e.g., when dropping a file on Vim.  This means interactive
+		commands cannot be used.  Otherwise zero is returned.
+
+executable({expr})					*executable()*
+		This function checks if an executable with the name {expr}
+		exists.  {expr} must be the name of the program without any
+		arguments.
+		executable() uses the value of $PATH and/or the normal
+		searchpath for programs.		*PATHEXT*
+		On MS-DOS and MS-Windows the ".exe", ".bat", etc. can
+		optionally be included.  Then the extensions in $PATHEXT are
+		tried.  Thus if "foo.exe" does not exist, "foo.exe.bat" can be
+		found.  If $PATHEXT is not set then ".exe;.com;.bat;.cmd" is
+		used.  A dot by itself can be used in $PATHEXT to try using
+		the name without an extension.  When 'shell' looks like a
+		Unix shell, then the name is also tried without adding an
+		extension.
+		On MS-DOS and MS-Windows it only checks if the file exists and
+		is not a directory, not if it's really executable.
+		On MS-Windows an executable in the same directory as Vim is
+		always found.  Since this directory is added to $PATH it
+		should also work to execute it |win32-PATH|.
+		The result is a Number:
+			1	exists
+			0	does not exist
+			-1	not implemented on this system
+
+							*exists()*
+exists({expr})	The result is a Number, which is non-zero if {expr} is
+		defined, zero otherwise.  The {expr} argument is a string,
+		which contains one of these:
+			&option-name	Vim option (only checks if it exists,
+					not if it really works)
+			+option-name	Vim option that works.
+			$ENVNAME	environment variable (could also be
+					done by comparing with an empty
+					string)
+			*funcname	built-in function (see |functions|)
+					or user defined function (see
+					|user-functions|).
+			varname		internal variable (see
+					|internal-variables|).  Also works
+					for |curly-braces-names|, |Dictionary|
+					entries, |List| items, etc.  Beware
+					that this may cause functions to be
+					invoked cause an error message for an
+					invalid expression.
+			:cmdname	Ex command: built-in command, user
+					command or command modifier |:command|.
+					Returns:
+					1  for match with start of a command
+					2  full match with a command
+					3  matches several user commands
+					To check for a supported command
+					always check the return value to be 2.
+			:2match		The |:2match| command.
+			:3match		The |:3match| command.
+			#event		autocommand defined for this event
+			#event#pattern	autocommand defined for this event and
+					pattern (the pattern is taken
+					literally and compared to the
+					autocommand patterns character by
+					character)
+			#group		autocommand group exists
+			#group#event	autocommand defined for this group and
+					event.
+			#group#event#pattern
+					autocommand defined for this group,
+					event and pattern.
+			##event		autocommand for this event is
+					supported.
+		For checking for a supported feature use |has()|.
+
+		Examples: >
+			exists("&shortname")
+			exists("$HOSTNAME")
+			exists("*strftime")
+			exists("*s:MyFunc")
+			exists("bufcount")
+			exists(":Make")
+			exists("#CursorHold")
+			exists("#BufReadPre#*.gz")
+			exists("#filetypeindent")
+			exists("#filetypeindent#FileType")
+			exists("#filetypeindent#FileType#*")
+			exists("##ColorScheme")
+<		There must be no space between the symbol (&/$/*/#) and the
+		name.
+		There must be no extra characters after the name, although in
+		a few cases this is ignored.  That may become more strict in
+		the future, thus don't count on it!
+		Working example: >
+			exists(":make")
+<		NOT working example: >
+			exists(":make install")
+
+<		Note that the argument must be a string, not the name of the
+		variable itself.  For example: >
+			exists(bufcount)
+<		This doesn't check for existence of the "bufcount" variable,
+		but gets the value of "bufcount", and checks if that exists.
+
+expand({expr} [, {flag}])				*expand()*
+		Expand wildcards and the following special keywords in {expr}.
+		The result is a String.
+
+		When there are several matches, they are separated by <NL>
+		characters.  [Note: in version 5.0 a space was used, which
+		caused problems when a file name contains a space]
+
+		If the expansion fails, the result is an empty string.  A name
+		for a non-existing file is not included.
+
+		When {expr} starts with '%', '#' or '<', the expansion is done
+		like for the |cmdline-special| variables with their associated
+		modifiers.  Here is a short overview:
+
+			%		current file name
+			#		alternate file name
+			#n		alternate file name n
+			<cfile>		file name under the cursor
+			<afile>		autocmd file name
+			<abuf>		autocmd buffer number (as a String!)
+			<amatch>	autocmd matched name
+			<sfile>		sourced script file name
+			<cword>		word under the cursor
+			<cWORD>		WORD under the cursor
+			<client>	the {clientid} of the last received
+					message |server2client()|
+		Modifiers:
+			:p		expand to full path
+			:h		head (last path component removed)
+			:t		tail (last path component only)
+			:r		root (one extension removed)
+			:e		extension only
+
+		Example: >
+			:let &tags = expand("%:p:h") . "/tags"
+<		Note that when expanding a string that starts with '%', '#' or
+		'<', any following text is ignored.  This does NOT work: >
+			:let doesntwork = expand("%:h.bak")
+<		Use this: >
+			:let doeswork = expand("%:h") . ".bak"
+<		Also note that expanding "<cfile>" and others only returns the
+		referenced file name without further expansion.  If "<cfile>"
+		is "~/.cshrc", you need to do another expand() to have the
+		"~/" expanded into the path of the home directory: >
+			:echo expand(expand("<cfile>"))
+<
+		There cannot be white space between the variables and the
+		following modifier.  The |fnamemodify()| function can be used
+		to modify normal file names.
+
+		When using '%' or '#', and the current or alternate file name
+		is not defined, an empty string is used.  Using "%:p" in a
+		buffer with no name, results in the current directory, with a
+		'/' added.
+
+		When {expr} does not start with '%', '#' or '<', it is
+		expanded like a file name is expanded on the command line.
+		'suffixes' and 'wildignore' are used, unless the optional
+		{flag} argument is given and it is non-zero.  Names for
+		non-existing files are included.  The "**" item can be used to
+		search in a directory tree.  For example, to find all "README"
+		files in the current directory and below: >
+			:echo expand("**/README")
+<
+		Expand() can also be used to expand variables and environment
+		variables that are only known in a shell.  But this can be
+		slow, because a shell must be started.  See |expr-env-expand|.
+		The expanded variable is still handled like a list of file
+		names.  When an environment variable cannot be expanded, it is
+		left unchanged.  Thus ":echo expand('$FOOBAR')" results in
+		"$FOOBAR".
+
+		See |glob()| for finding existing files.  See |system()| for
+		getting the raw output of an external command.
+
+extend({expr1}, {expr2} [, {expr3}])			*extend()*
+		{expr1} and {expr2} must be both |Lists| or both
+		|Dictionaries|.
+
+		If they are |Lists|: Append {expr2} to {expr1}.
+		If {expr3} is given insert the items of {expr2} before item
+		{expr3} in {expr1}.  When {expr3} is zero insert before the
+		first item.  When {expr3} is equal to len({expr1}) then
+		{expr2} is appended.
+		Examples: >
+			:echo sort(extend(mylist, [7, 5]))
+			:call extend(mylist, [2, 3], 1)
+<		Use |add()| to concatenate one item to a list.  To concatenate
+		two lists into a new list use the + operator: >
+			:let newlist = [1, 2, 3] + [4, 5]
+<
+		If they are |Dictionaries|:
+		Add all entries from {expr2} to {expr1}.
+		If a key exists in both {expr1} and {expr2} then {expr3} is
+		used to decide what to do:
+		{expr3} = "keep": keep the value of {expr1}
+		{expr3} = "force": use the value of {expr2}
+		{expr3} = "error": give an error message		*E737*
+		When {expr3} is omitted then "force" is assumed.
+
+		{expr1} is changed when {expr2} is not empty.  If necessary
+		make a copy of {expr1} first.
+		{expr2} remains unchanged.
+		Returns {expr1}.
+
+
+feedkeys({string} [, {mode}])				*feedkeys()*
+		Characters in {string} are queued for processing as if they
+		come from a mapping or were typed by the user.  They are added
+		to the end of the typeahead buffer, thus if a mapping is still
+		being executed these characters come after them.
+		The function does not wait for processing of keys contained in
+		{string}.
+		To include special keys into {string}, use double-quotes
+		and "\..." notation |expr-quote|. For example,
+		feedkeys("\<CR>") simulates pressing of the <Enter> key. But
+		feedkeys('\<CR>') pushes 5 characters.
+		If {mode} is absent, keys are remapped.
+		{mode} is a String, which can contain these character flags:
+		'm'	Remap keys. This is default.
+		'n'	Do not remap keys.
+		't'	Handle keys as if typed; otherwise they are handled as
+			if coming from a mapping.  This matters for undo,
+			opening folds, etc.
+		Return value is always 0.
+
+filereadable({file})					*filereadable()*
+		The result is a Number, which is TRUE when a file with the
+		name {file} exists, and can be read.  If {file} doesn't exist,
+		or is a directory, the result is FALSE.  {file} is any
+		expression, which is used as a String.
+		If you don't care about the file being readable you can use
+		|glob()|.
+							*file_readable()*
+		Obsolete name: file_readable().
+
+
+filewritable({file})					*filewritable()*
+		The result is a Number, which is 1 when a file with the
+		name {file} exists, and can be written.  If {file} doesn't
+		exist, or is not writable, the result is 0.  If (file) is a
+		directory, and we can write to it, the result is 2.
+
+
+filter({expr}, {string})					*filter()*
+		{expr} must be a |List| or a |Dictionary|.
+		For each item in {expr} evaluate {string} and when the result
+		is zero remove the item from the |List| or |Dictionary|.
+		Inside {string} |v:val| has the value of the current item.
+		For a |Dictionary| |v:key| has the key of the current item.
+		Examples: >
+			:call filter(mylist, 'v:val !~ "OLD"')
+<		Removes the items where "OLD" appears. >
+			:call filter(mydict, 'v:key >= 8')
+<		Removes the items with a key below 8. >
+			:call filter(var, 0)
+<		Removes all the items, thus clears the |List| or |Dictionary|.
+
+		Note that {string} is the result of expression and is then
+		used as an expression again.  Often it is good to use a
+		|literal-string| to avoid having to double backslashes.
+
+		The operation is done in-place.  If you want a |List| or
+		|Dictionary| to remain unmodified make a copy first: >
+			:let l = filter(copy(mylist), 'v:val =~ "KEEP"')
+
+<		Returns {expr}, the |List| or |Dictionary| that was filtered.
+		When an error is encountered while evaluating {string} no
+		further items in {expr} are processed.
+
+
+finddir({name}[, {path}[, {count}]])				*finddir()*
+		Find directory {name} in {path}.  Supports both downwards and
+		upwards recursive directory searches.  See |file-searching|
+		for the syntax of {path}.
+		Returns the path of the first found match.  When the found
+		directory is below the current directory a relative path is
+		returned.  Otherwise a full path is returned.
+		If {path} is omitted or empty then 'path' is used.
+		If the optional {count} is given, find {count}'s occurrence of
+		{name} in {path} instead of the first one.
+		When {count} is negative return all the matches in a |List|.
+		This is quite similar to the ex-command |:find|.
+		{only available when compiled with the +file_in_path feature}
+
+findfile({name}[, {path}[, {count}]])				*findfile()*
+		Just like |finddir()|, but find a file instead of a directory.
+		Uses 'suffixesadd'.
+		Example: >
+			:echo findfile("tags.vim", ".;")
+<		Searches from the directory of the current file upwards until
+		it finds the file "tags.vim".
+
+fnamemodify({fname}, {mods})				*fnamemodify()*
+		Modify file name {fname} according to {mods}.  {mods} is a
+		string of characters like it is used for file names on the
+		command line.  See |filename-modifiers|.
+		Example: >
+			:echo fnamemodify("main.c", ":p:h")
+<		results in: >
+			/home/mool/vim/vim/src
+<		Note: Environment variables and "~" don't work in {fname}, use
+		|expand()| first then.
+
+foldclosed({lnum})					*foldclosed()*
+		The result is a Number.  If the line {lnum} is in a closed
+		fold, the result is the number of the first line in that fold.
+		If the line {lnum} is not in a closed fold, -1 is returned.
+
+foldclosedend({lnum})					*foldclosedend()*
+		The result is a Number.  If the line {lnum} is in a closed
+		fold, the result is the number of the last line in that fold.
+		If the line {lnum} is not in a closed fold, -1 is returned.
+
+foldlevel({lnum})					*foldlevel()*
+		The result is a Number, which is the foldlevel of line {lnum}
+		in the current buffer.  For nested folds the deepest level is
+		returned.  If there is no fold at line {lnum}, zero is
+		returned.  It doesn't matter if the folds are open or closed.
+		When used while updating folds (from 'foldexpr') -1 is
+		returned for lines where folds are still to be updated and the
+		foldlevel is unknown.  As a special case the level of the
+		previous line is usually available.
+
+							*foldtext()*
+foldtext()	Returns a String, to be displayed for a closed fold.  This is
+		the default function used for the 'foldtext' option and should
+		only be called from evaluating 'foldtext'.  It uses the
+		|v:foldstart|, |v:foldend| and |v:folddashes| variables.
+		The returned string looks like this: >
+			+-- 45 lines: abcdef
+<		The number of dashes depends on the foldlevel.  The "45" is
+		the number of lines in the fold.  "abcdef" is the text in the
+		first non-blank line of the fold.  Leading white space, "//"
+		or "/*" and the text from the 'foldmarker' and 'commentstring'
+		options is removed.
+		{not available when compiled without the |+folding| feature}
+
+foldtextresult({lnum})					*foldtextresult()*
+		Returns the text that is displayed for the closed fold at line
+		{lnum}.  Evaluates 'foldtext' in the appropriate context.
+		When there is no closed fold at {lnum} an empty string is
+		returned.
+		{lnum} is used like with |getline()|.  Thus "." is the current
+		line, "'m" mark m, etc.
+		Useful when exporting folded text, e.g., to HTML.
+		{not available when compiled without the |+folding| feature}
+
+							*foreground()*
+foreground()	Move the Vim window to the foreground.  Useful when sent from
+		a client to a Vim server. |remote_send()|
+		On Win32 systems this might not work, the OS does not always
+		allow a window to bring itself to the foreground.  Use
+		|remote_foreground()| instead.
+		{only in the Win32, Athena, Motif and GTK GUI versions and the
+		Win32 console version}
+
+
+function({name})					*function()* *E700*
+		Return a |Funcref| variable that refers to function {name}.
+		{name} can be a user defined function or an internal function.
+
+
+garbagecollect()					*garbagecollect()*
+		Cleanup unused |Lists| and |Dictionaries| that have circular
+		references.  There is hardly ever a need to invoke this
+		function, as it is automatically done when Vim runs out of
+		memory or is waiting for the user to press a key after
+		'updatetime'.  Items without circular references are always
+		freed when they become unused.
+		This is useful if you have deleted a very big |List| and/or
+		|Dictionary| with circular references in a script that runs
+		for a long time.
+
+get({list}, {idx} [, {default}])			*get()*
+		Get item {idx} from |List| {list}.  When this item is not
+		available return {default}.  Return zero when {default} is
+		omitted.
+get({dict}, {key} [, {default}])
+		Get item with key {key} from |Dictionary| {dict}.  When this
+		item is not available return {default}.  Return zero when
+		{default} is omitted.
+
+							*getbufline()*
+getbufline({expr}, {lnum} [, {end}])
+		Return a |List| with the lines starting from {lnum} to {end}
+		(inclusive) in the buffer {expr}.  If {end} is omitted, a
+		|List| with only the line {lnum} is returned.
+
+		For the use of {expr}, see |bufname()| above.
+
+		For {lnum} and {end} "$" can be used for the last line of the
+		buffer.  Otherwise a number must be used.
+
+		When {lnum} is smaller than 1 or bigger than the number of
+		lines in the buffer, an empty |List| is returned.
+
+		When {end} is greater than the number of lines in the buffer,
+		it is treated as {end} is set to the number of lines in the
+		buffer.  When {end} is before {lnum} an empty |List| is
+		returned.
+
+		This function works only for loaded buffers.  For unloaded and
+		non-existing buffers, an empty |List| is returned.
+
+		Example: >
+			:let lines = getbufline(bufnr("myfile"), 1, "$")
+
+getbufvar({expr}, {varname})				*getbufvar()*
+		The result is the value of option or local buffer variable
+		{varname} in buffer {expr}.  Note that the name without "b:"
+		must be used.
+		This also works for a global or buffer-local option, but it
+		doesn't work for a global variable, window-local variable or
+		window-local option.
+		For the use of {expr}, see |bufname()| above.
+		When the buffer or variable doesn't exist an empty string is
+		returned, there is no error message.
+		Examples: >
+			:let bufmodified = getbufvar(1, "&mod")
+			:echo "todo myvar = " . getbufvar("todo", "myvar")
+<
+getchar([expr])						*getchar()*
+		Get a single character from the user or input stream.
+		If [expr] is omitted, wait until a character is available.
+		If [expr] is 0, only get a character when one is available.
+			Return zero otherwise.
+		If [expr] is 1, only check if a character is available, it is
+			not consumed.  Return zero if no character available.
+
+		Without {expr} and when {expr} is 0 a whole character or
+		special key is returned.  If it is an 8-bit character, the
+		result is a number.  Use nr2char() to convert it to a String.
+		Otherwise a String is returned with the encoded character.
+		For a special key it's a sequence of bytes starting with 0x80
+		(decimal: 128).  This is the same value as the string
+		"\<Key>", e.g., "\<Left>".  The returned value is also a
+		String when a modifier (shift, control, alt) was used that is
+		not included in the character.
+
+		When {expr} is 1 only the first byte is returned.  For a
+		one-byte character it is the character itself as a number.
+		Use nr2char() to convert it to a String.
+
+		When the user clicks a mouse button, the mouse event will be
+		returned.  The position can then be found in |v:mouse_col|,
+		|v:mouse_lnum| and |v:mouse_win|.  This example positions the
+		mouse as it would normally happen: >
+			let c = getchar()
+		  	if c == "\<LeftMouse>" && v:mouse_win > 0
+			  exe v:mouse_win . "wincmd w"
+			  exe v:mouse_lnum
+			  exe "normal " . v:mouse_col . "|"
+			endif
+<
+		There is no prompt, you will somehow have to make clear to the
+		user that a character has to be typed.
+		There is no mapping for the character.
+		Key codes are replaced, thus when the user presses the <Del>
+		key you get the code for the <Del> key, not the raw character
+		sequence.  Examples: >
+			getchar() == "\<Del>"
+			getchar() == "\<S-Left>"
+<		This example redefines "f" to ignore case: >
+			:nmap f :call FindChar()<CR>
+			:function FindChar()
+			:  let c = nr2char(getchar())
+			:  while col('.') < col('$') - 1
+			:    normal l
+			:    if getline('.')[col('.') - 1] ==? c
+			:      break
+			:    endif
+			:  endwhile
+			:endfunction
+
+getcharmod()						*getcharmod()*
+		The result is a Number which is the state of the modifiers for
+		the last obtained character with getchar() or in another way.
+		These values are added together:
+			2	shift
+			4	control
+			8	alt (meta)
+			16	mouse double click
+			32	mouse triple click
+			64	mouse quadruple click
+			128	Macintosh only: command
+		Only the modifiers that have not been included in the
+		character itself are obtained.  Thus Shift-a results in "A"
+		with no modifier.
+
+getcmdline()						*getcmdline()*
+		Return the current command-line.  Only works when the command
+		line is being edited, thus requires use of |c_CTRL-\_e| or
+		|c_CTRL-R_=|.
+		Example: >
+			:cmap <F7> <C-\>eescape(getcmdline(), ' \')<CR>
+<		Also see |getcmdtype()|, |getcmdpos()| and |setcmdpos()|.
+
+getcmdpos()						*getcmdpos()*
+		Return the position of the cursor in the command line as a
+		byte count.  The first column is 1.
+		Only works when editing the command line, thus requires use of
+		|c_CTRL-\_e| or |c_CTRL-R_=|.  Returns 0 otherwise.
+		Also see |getcmdtype()|, |setcmdpos()| and |getcmdline()|.
+
+getcmdtype()						*getcmdtype()*
+		Return the current command-line type. Possible return values
+		are:
+		    :	normal Ex command
+		    >	debug mode command |debug-mode|
+		    /	forward search command
+		    ?	backward search command
+		    @	|input()| command
+		    -	|:insert| or |:append| command
+		Only works when editing the command line, thus requires use of
+		|c_CTRL-\_e| or |c_CTRL-R_=|.  Returns an empty string
+		otherwise.
+		Also see |getcmdpos()|, |setcmdpos()| and |getcmdline()|.
+
+							*getcwd()*
+getcwd()	The result is a String, which is the name of the current
+		working directory.
+
+getfsize({fname})					*getfsize()*
+		The result is a Number, which is the size in bytes of the
+		given file {fname}.
+		If {fname} is a directory, 0 is returned.
+		If the file {fname} can't be found, -1 is returned.
+
+getfontname([{name}])					*getfontname()*
+		Without an argument returns the name of the normal font being
+		used.  Like what is used for the Normal highlight group
+		|hl-Normal|.
+		With an argument a check is done whether {name} is a valid
+		font name.  If not then an empty string is returned.
+		Otherwise the actual font name is returned, or {name} if the
+		GUI does not support obtaining the real name.
+		Only works when the GUI is running, thus not in your vimrc or
+		gvimrc file.  Use the |GUIEnter| autocommand to use this
+		function just after the GUI has started.
+		Note that the GTK 2 GUI accepts any font name, thus checking
+		for a valid name does not work.
+
+getfperm({fname})					*getfperm()*
+		The result is a String, which is the read, write, and execute
+		permissions of the given file {fname}.
+		If {fname} does not exist or its directory cannot be read, an
+		empty string is returned.
+		The result is of the form "rwxrwxrwx", where each group of
+		"rwx" flags represent, in turn, the permissions of the owner
+		of the file, the group the file belongs to, and other users.
+		If a user does not have a given permission the flag for this
+		is replaced with the string "-".  Example: >
+			:echo getfperm("/etc/passwd")
+<		This will hopefully (from a security point of view) display
+		the string "rw-r--r--" or even "rw-------".
+
+getftime({fname})					*getftime()*
+		The result is a Number, which is the last modification time of
+		the given file {fname}.  The value is measured as seconds
+		since 1st Jan 1970, and may be passed to strftime().  See also
+		|localtime()| and |strftime()|.
+		If the file {fname} can't be found -1 is returned.
+
+getftype({fname})					*getftype()*
+		The result is a String, which is a description of the kind of
+		file of the given file {fname}.
+		If {fname} does not exist an empty string is returned.
+		Here is a table over different kinds of files and their
+		results:
+			Normal file		"file"
+			Directory		"dir"
+			Symbolic link		"link"
+			Block device		"bdev"
+			Character device	"cdev"
+			Socket			"socket"
+			FIFO			"fifo"
+			All other		"other"
+		Example: >
+			getftype("/home")
+<		Note that a type such as "link" will only be returned on
+		systems that support it.  On some systems only "dir" and
+		"file" are returned.
+
+							*getline()*
+getline({lnum} [, {end}])
+		Without {end} the result is a String, which is line {lnum}
+		from the current buffer.  Example: >
+			getline(1)
+<		When {lnum} is a String that doesn't start with a
+		digit, line() is called to translate the String into a Number.
+		To get the line under the cursor: >
+			getline(".")
+<		When {lnum} is smaller than 1 or bigger than the number of
+		lines in the buffer, an empty string is returned.
+
+		When {end} is given the result is a |List| where each item is
+		a line from the current buffer in the range {lnum} to {end},
+		including line {end}.
+		{end} is used in the same way as {lnum}.
+		Non-existing lines are silently omitted.
+		When {end} is before {lnum} an empty |List| is returned.
+		Example: >
+			:let start = line('.')
+			:let end = search("^$") - 1
+			:let lines = getline(start, end)
+
+<		To get lines from another buffer see |getbufline()|
+
+getloclist({nr})					*getloclist()*
+		Returns a list with all the entries in the location list for
+		window {nr}. When {nr} is zero the current window is used.
+		For a location list window, the displayed location list is
+		returned.  For an invalid window number {nr}, an empty list is
+		returned. Otherwise, same as getqflist().
+
+getqflist()						*getqflist()*
+		Returns a list with all the current quickfix errors.  Each
+		list item is a dictionary with these entries:
+			bufnr	number of buffer that has the file name, use
+				bufname() to get the name
+			lnum	line number in the buffer (first line is 1)
+			col	column number (first column is 1)
+			vcol	non-zero: "col" is visual column
+				zero: "col" is byte index
+			nr	error number
+			pattern	search pattern used to locate the error
+			text	description of the error
+			type	type of the error, 'E', '1', etc.
+			valid	non-zero: recognized error message
+
+		When there is no error list or it's empty an empty list is
+		returned. Quickfix list entries with non-existing buffer
+		number are returned with "bufnr" set to zero.
+
+		Useful application: Find pattern matches in multiple files and
+		do something with them: >
+			:vimgrep /theword/jg *.c
+			:for d in getqflist()
+			:   echo bufname(d.bufnr) ':' d.lnum '=' d.text
+			:endfor
+
+
+getreg([{regname} [, 1]])				*getreg()*
+		The result is a String, which is the contents of register
+		{regname}.  Example: >
+			:let cliptext = getreg('*')
+<		getreg('=') returns the last evaluated value of the expression
+		register.  (For use in maps.)
+		getreg('=', 1) returns the expression itself, so that it can
+		be restored with |setreg()|.  For other registers the extra
+		argument is ignored, thus you can always give it.
+		If {regname} is not specified, |v:register| is used.
+
+
+getregtype([{regname}])					*getregtype()*
+		The result is a String, which is type of register {regname}.
+		The value will be one of:
+		    "v"			for |characterwise| text
+		    "V"			for |linewise| text
+		    "<CTRL-V>{width}"	for |blockwise-visual| text
+		    0			for an empty or unknown register
+		<CTRL-V> is one character with value 0x16.
+		If {regname} is not specified, |v:register| is used.
+
+gettabwinvar({tabnr}, {winnr}, {varname})		*gettabwinvar()*
+		Get the value of window-local variable {varname} in window
+		{winnr} in tab page {tabnr}.
+		When {varname} starts with "&" get the value of a window-local
+		option.
+		Tabs are numbered starting with one.  For the current tabpage
+		use |getwinvar()|.
+		When {winnr} is zero the current window is used.
+		This also works for a global option, buffer-local option and
+		window-local option, but it doesn't work for a global variable
+		or buffer-local variable.
+		When {varname} is empty a dictionary with all window-local
+		variables is returned.
+		Note that {varname} must be the name without "w:".
+		Examples: >
+			:let list_is_on = gettabwinvar(1, 2, '&list')
+			:echo "myvar = " . gettabwinvar(3, 1, 'myvar')
+<
+							*getwinposx()*
+getwinposx()	The result is a Number, which is the X coordinate in pixels of
+		the left hand side of the GUI Vim window.  The result will be
+		-1 if the information is not available.
+
+							*getwinposy()*
+getwinposy()	The result is a Number, which is the Y coordinate in pixels of
+		the top of the GUI Vim window.  The result will be -1 if the
+		information is not available.
+
+getwinvar({winnr}, {varname})				*getwinvar()*
+		Like |gettabwinvar()| for the current tabpage.
+		Examples: >
+			:let list_is_on = getwinvar(2, '&list')
+			:echo "myvar = " . getwinvar(1, 'myvar')
+<
+							*glob()*
+glob({expr})	Expand the file wildcards in {expr}.  See |wildcards| for the
+		use of special characters.
+		The result is a String.
+		When there are several matches, they are separated by <NL>
+		characters.
+		If the expansion fails, the result is an empty string.
+		A name for a non-existing file is not included.
+
+		For most systems backticks can be used to get files names from
+		any external command.  Example: >
+			:let tagfiles = glob("`find . -name tags -print`")
+			:let &tags = substitute(tagfiles, "\n", ",", "g")
+<		The result of the program inside the backticks should be one
+		item per line.  Spaces inside an item are allowed.
+
+		See |expand()| for expanding special Vim variables.  See
+		|system()| for getting the raw output of an external command.
+
+globpath({path}, {expr})				*globpath()*
+		Perform glob() on all directories in {path} and concatenate
+		the results.  Example: >
+			:echo globpath(&rtp, "syntax/c.vim")
+<		{path} is a comma-separated list of directory names.  Each
+		directory name is prepended to {expr} and expanded like with
+		glob().  A path separator is inserted when needed.
+		To add a comma inside a directory name escape it with a
+		backslash.  Note that on MS-Windows a directory may have a
+		trailing backslash, remove it if you put a comma after it.
+		If the expansion fails for one of the directories, there is no
+		error message.
+		The 'wildignore' option applies: Names matching one of the
+		patterns in 'wildignore' will be skipped.
+
+		The "**" item can be used to search in a directory tree.
+		For example, to find all "README.txt" files in the directories
+		in 'runtimepath' and below: >
+			:echo globpath(&rtp, "**/README.txt")
+<
+							*has()*
+has({feature})	The result is a Number, which is 1 if the feature {feature} is
+		supported, zero otherwise.  The {feature} argument is a
+		string.  See |feature-list| below.
+		Also see |exists()|.
+
+
+has_key({dict}, {key})					*has_key()*
+		The result is a Number, which is 1 if |Dictionary| {dict} has
+		an entry with key {key}.  Zero otherwise.
+
+haslocaldir()						*haslocaldir()*
+		The result is a Number, which is 1 when the current
+                window has set a local path via |:lcd|, and 0 otherwise.
+
+hasmapto({what} [, {mode} [, {abbr}]])			*hasmapto()*
+		The result is a Number, which is 1 if there is a mapping that
+		contains {what} in somewhere in the rhs (what it is mapped to)
+		and this mapping exists in one of the modes indicated by
+		{mode}.
+		When {abbr} is there and it is non-zero use abbreviations
+		instead of mappings.  Don't forget to specify Insert and/or
+		Command-line mode.
+		Both the global mappings and the mappings local to the current
+		buffer are checked for a match.
+		If no matching mapping is found 0 is returned.
+		The following characters are recognized in {mode}:
+			n	Normal mode
+			v	Visual mode
+			o	Operator-pending mode
+			i	Insert mode
+			l	Language-Argument ("r", "f", "t", etc.)
+			c	Command-line mode
+		When {mode} is omitted, "nvo" is used.
+
+		This function is useful to check if a mapping already exists
+		to a function in a Vim script.  Example: >
+			:if !hasmapto('\ABCdoit')
+			:   map <Leader>d \ABCdoit
+			:endif
+<		This installs the mapping to "\ABCdoit" only if there isn't
+		already a mapping to "\ABCdoit".
+
+histadd({history}, {item})				*histadd()*
+		Add the String {item} to the history {history} which can be
+		one of:					*hist-names*
+			"cmd"	 or ":"	  command line history
+			"search" or "/"   search pattern history
+			"expr"   or "="   typed expression history
+			"input"  or "@"	  input line history
+		If {item} does already exist in the history, it will be
+		shifted to become the newest entry.
+		The result is a Number: 1 if the operation was successful,
+		otherwise 0 is returned.
+
+		Example: >
+			:call histadd("input", strftime("%Y %b %d"))
+			:let date=input("Enter date: ")
+<		This function is not available in the |sandbox|.
+
+histdel({history} [, {item}])				*histdel()*
+		Clear {history}, i.e. delete all its entries.  See |hist-names|
+		for the possible values of {history}.
+
+		If the parameter {item} is given as String, this is seen
+		as regular expression.  All entries matching that expression
+		will be removed from the history (if there are any).
+		Upper/lowercase must match, unless "\c" is used |/\c|.
+		If {item} is a Number, it will be interpreted as index, see
+		|:history-indexing|.  The respective entry will be removed
+		if it exists.
+
+		The result is a Number: 1 for a successful operation,
+		otherwise 0 is returned.
+
+		Examples:
+		Clear expression register history: >
+			:call histdel("expr")
+<
+		Remove all entries starting with "*" from the search history: >
+			:call histdel("/", '^\*')
+<
+		The following three are equivalent: >
+			:call histdel("search", histnr("search"))
+			:call histdel("search", -1)
+			:call histdel("search", '^'.histget("search", -1).'$')
+<
+		To delete the last search pattern and use the last-but-one for
+		the "n" command and 'hlsearch': >
+			:call histdel("search", -1)
+			:let @/ = histget("search", -1)
+
+histget({history} [, {index}])				*histget()*
+		The result is a String, the entry with Number {index} from
+		{history}.  See |hist-names| for the possible values of
+		{history}, and |:history-indexing| for {index}.  If there is
+		no such entry, an empty String is returned.  When {index} is
+		omitted, the most recent item from the history is used.
+
+		Examples:
+		Redo the second last search from history. >
+			:execute '/' . histget("search", -2)
+
+<		Define an Ex command ":H {num}" that supports re-execution of
+		the {num}th entry from the output of |:history|. >
+			:command -nargs=1 H execute histget("cmd", 0+<args>)
+<
+histnr({history})					*histnr()*
+		The result is the Number of the current entry in {history}.
+		See |hist-names| for the possible values of {history}.
+		If an error occurred, -1 is returned.
+
+		Example: >
+			:let inp_index = histnr("expr")
+<
+hlexists({name})					*hlexists()*
+		The result is a Number, which is non-zero if a highlight group
+		called {name} exists.  This is when the group has been
+		defined in some way.  Not necessarily when highlighting has
+		been defined for it, it may also have been used for a syntax
+		item.
+							*highlight_exists()*
+		Obsolete name: highlight_exists().
+
+							*hlID()*
+hlID({name})	The result is a Number, which is the ID of the highlight group
+		with name {name}.  When the highlight group doesn't exist,
+		zero is returned.
+		This can be used to retrieve information about the highlight
+		group.  For example, to get the background color of the
+		"Comment" group: >
+	:echo synIDattr(synIDtrans(hlID("Comment")), "bg")
+<							*highlightID()*
+		Obsolete name: highlightID().
+
+hostname()						*hostname()*
+		The result is a String, which is the name of the machine on
+		which Vim is currently running.  Machine names greater than
+		256 characters long are truncated.
+
+iconv({expr}, {from}, {to})				*iconv()*
+		The result is a String, which is the text {expr} converted
+		from encoding {from} to encoding {to}.
+		When the conversion fails an empty string is returned.
+		The encoding names are whatever the iconv() library function
+		can accept, see ":!man 3 iconv".
+		Most conversions require Vim to be compiled with the |+iconv|
+		feature.  Otherwise only UTF-8 to latin1 conversion and back
+		can be done.
+		This can be used to display messages with special characters,
+		no matter what 'encoding' is set to.  Write the message in
+		UTF-8 and use: >
+			echo iconv(utf8_str, "utf-8", &enc)
+<		Note that Vim uses UTF-8 for all Unicode encodings, conversion
+		from/to UCS-2 is automatically changed to use UTF-8.  You
+		cannot use UCS-2 in a string anyway, because of the NUL bytes.
+		{only available when compiled with the +multi_byte feature}
+
+							*indent()*
+indent({lnum})	The result is a Number, which is indent of line {lnum} in the
+		current buffer.  The indent is counted in spaces, the value
+		of 'tabstop' is relevant.  {lnum} is used just like in
+		|getline()|.
+		When {lnum} is invalid -1 is returned.
+
+
+index({list}, {expr} [, {start} [, {ic}]])			*index()*
+		Return the lowest index in |List| {list} where the item has a
+		value equal to {expr}.
+		If {start} is given then start looking at the item with index
+		{start} (may be negative for an item relative to the end).
+		When {ic} is given and it is non-zero, ignore case.  Otherwise
+		case must match.
+		-1 is returned when {expr} is not found in {list}.
+		Example: >
+			:let idx = index(words, "the")
+			:if index(numbers, 123) >= 0
+
+
+input({prompt} [, {text} [, {completion}]])		*input()*
+		The result is a String, which is whatever the user typed on
+		the command-line.  The parameter is either a prompt string, or
+		a blank string (for no prompt).  A '\n' can be used in the
+		prompt to start a new line.
+		The highlighting set with |:echohl| is used for the prompt.
+		The input is entered just like a command-line, with the same
+		editing commands and mappings.  There is a separate history
+		for lines typed for input().
+		Example: >
+			:if input("Coffee or beer? ") == "beer"
+			:  echo "Cheers!"
+			:endif
+<
+		If the optional {text} is present and not empty, this is used
+		for the default reply, as if the user typed this.  Example: >
+			:let color = input("Color? ", "white")
+
+<		The optional {completion} argument specifies the type of
+		completion supported for the input.  Without it completion is
+		not performed.  The supported completion types are the same as
+		that can be supplied to a user-defined command using the
+		"-complete=" argument.  Refer to |:command-completion| for
+		more information.  Example: >
+			let fname = input("File: ", "", "file")
+<
+		NOTE: This function must not be used in a startup file, for
+		the versions that only run in GUI mode (e.g., the Win32 GUI).
+		Note: When input() is called from within a mapping it will
+		consume remaining characters from that mapping, because a
+		mapping is handled like the characters were typed.
+		Use |inputsave()| before input() and |inputrestore()|
+		after input() to avoid that.  Another solution is to avoid
+		that further characters follow in the mapping, e.g., by using
+		|:execute| or |:normal|.
+
+		Example with a mapping: >
+			:nmap \x :call GetFoo()<CR>:exe "/" . Foo<CR>
+			:function GetFoo()
+			:  call inputsave()
+			:  let g:Foo = input("enter search pattern: ")
+			:  call inputrestore()
+			:endfunction
+
+inputdialog({prompt} [, {text} [, {cancelreturn}]])		*inputdialog()*
+		Like input(), but when the GUI is running and text dialogs are
+		supported, a dialog window pops up to input the text.
+		Example: >
+			:let n = inputdialog("value for shiftwidth", &sw)
+			:if n != ""
+			:  let &sw = n
+			:endif
+<		When the dialog is cancelled {cancelreturn} is returned.  When
+		omitted an empty string is returned.
+		Hitting <Enter> works like pressing the OK button.  Hitting
+		<Esc> works like pressing the Cancel button.
+		NOTE: Command-line completion is not supported.
+
+inputlist({textlist})					*inputlist()*
+		{textlist} must be a |List| of strings.  This |List| is
+		displayed, one string per line.  The user will be prompted to
+		enter a number, which is returned.
+		The user can also select an item by clicking on it with the
+		mouse.  For the first string 0 is returned.  When clicking
+		above the first item a negative number is returned.  When
+		clicking on the prompt one more than the length of {textlist}
+		is returned.
+		Make sure {textlist} has less then 'lines' entries, otherwise
+		it won't work.  It's a good idea to put the entry number at
+		the start of the string.  And put a prompt in the first item.
+		Example: >
+			let color = inputlist(['Select color:', '1. red',
+				\ '2. green', '3. blue'])
+
+inputrestore()						*inputrestore()*
+		Restore typeahead that was saved with a previous inputsave().
+		Should be called the same number of times inputsave() is
+		called.  Calling it more often is harmless though.
+		Returns 1 when there is nothing to restore, 0 otherwise.
+
+inputsave()						*inputsave()*
+		Preserve typeahead (also from mappings) and clear it, so that
+		a following prompt gets input from the user.  Should be
+		followed by a matching inputrestore() after the prompt.  Can
+		be used several times, in which case there must be just as
+		many inputrestore() calls.
+		Returns 1 when out of memory, 0 otherwise.
+
+inputsecret({prompt} [, {text}])			*inputsecret()*
+		This function acts much like the |input()| function with but
+		two exceptions:
+		a) the user's response will be displayed as a sequence of
+		asterisks ("*") thereby keeping the entry secret, and
+		b) the user's response will not be recorded on the input
+		|history| stack.
+		The result is a String, which is whatever the user actually
+		typed on the command-line in response to the issued prompt.
+		NOTE: Command-line completion is not supported.
+
+insert({list}, {item} [, {idx}])			*insert()*
+		Insert {item} at the start of |List| {list}.
+		If {idx} is specified insert {item} before the item with index
+		{idx}.  If {idx} is zero it goes before the first item, just
+		like omitting {idx}.  A negative {idx} is also possible, see
+		|list-index|.  -1 inserts just before the last item.
+		Returns the resulting |List|.  Examples: >
+			:let mylist = insert([2, 3, 5], 1)
+			:call insert(mylist, 4, -1)
+			:call insert(mylist, 6, len(mylist))
+<		The last example can be done simpler with |add()|.
+		Note that when {item} is a |List| it is inserted as a single
+		item.  Use |extend()| to concatenate |Lists|.
+
+isdirectory({directory})				*isdirectory()*
+		The result is a Number, which is non-zero when a directory
+		with the name {directory} exists.  If {directory} doesn't
+		exist, or isn't a directory, the result is FALSE.  {directory}
+		is any expression, which is used as a String.
+
+islocked({expr})					*islocked()* *E786*
+		The result is a Number, which is non-zero when {expr} is the
+		name of a locked variable.
+		{expr} must be the name of a variable, |List| item or
+		|Dictionary| entry, not the variable itself!  Example: >
+			:let alist = [0, ['a', 'b'], 2, 3]
+			:lockvar 1 alist
+			:echo islocked('alist')		" 1
+			:echo islocked('alist[1]')	" 0
+
+<		When {expr} is a variable that does not exist you get an error
+		message.  Use |exists()| to check for existence.
+
+items({dict})						*items()*
+		Return a |List| with all the key-value pairs of {dict}.  Each
+		|List| item is a list with two items: the key of a {dict}
+		entry and the value of this entry.  The |List| is in arbitrary
+		order.
+
+
+join({list} [, {sep}])					*join()*
+		Join the items in {list} together into one String.
+		When {sep} is specified it is put in between the items.  If
+		{sep} is omitted a single space is used.
+		Note that {sep} is not added at the end.  You might want to
+		add it there too: >
+			let lines = join(mylist, "\n") . "\n"
+<		String items are used as-is.  |Lists| and |Dictionaries| are
+		converted into a string like with |string()|.
+		The opposite function is |split()|.
+
+keys({dict})						*keys()*
+		Return a |List| with all the keys of {dict}.  The |List| is in
+		arbitrary order.
+
+							*len()* *E701*
+len({expr})	The result is a Number, which is the length of the argument.
+		When {expr} is a String or a Number the length in bytes is
+		used, as with |strlen()|.
+		When {expr} is a |List| the number of items in the |List| is
+		returned.
+		When {expr} is a |Dictionary| the number of entries in the
+		|Dictionary| is returned.
+		Otherwise an error is given.
+
+						*libcall()* *E364* *E368*
+libcall({libname}, {funcname}, {argument})
+		Call function {funcname} in the run-time library {libname}
+		with single argument {argument}.
+		This is useful to call functions in a library that you
+		especially made to be used with Vim.  Since only one argument
+		is possible, calling standard library functions is rather
+		limited.
+		The result is the String returned by the function.  If the
+		function returns NULL, this will appear as an empty string ""
+		to Vim.
+		If the function returns a number, use libcallnr()!
+		If {argument} is a number, it is passed to the function as an
+		int; if {argument} is a string, it is passed as a
+		null-terminated string.
+		This function will fail in |restricted-mode|.
+
+		libcall() allows you to write your own 'plug-in' extensions to
+		Vim without having to recompile the program.  It is NOT a
+		means to call system functions!  If you try to do so Vim will
+		very probably crash.
+
+		For Win32, the functions you write must be placed in a DLL
+		and use the normal C calling convention (NOT Pascal which is
+		used in Windows System DLLs).  The function must take exactly
+		one parameter, either a character pointer or a long integer,
+		and must return a character pointer or NULL.  The character
+		pointer returned must point to memory that will remain valid
+		after the function has returned (e.g. in static data in the
+		DLL).  If it points to allocated memory, that memory will
+		leak away.  Using a static buffer in the function should work,
+		it's then freed when the DLL is unloaded.
+
+		WARNING: If the function returns a non-valid pointer, Vim may
+		crash!  This also happens if the function returns a number,
+		because Vim thinks it's a pointer.
+		For Win32 systems, {libname} should be the filename of the DLL
+		without the ".DLL" suffix.  A full path is only required if
+		the DLL is not in the usual places.
+		For Unix: When compiling your own plugins, remember that the
+		object code must be compiled as position-independent ('PIC').
+		{only in Win32 on some Unix versions, when the |+libcall|
+		feature is present}
+		Examples: >
+			:echo libcall("libc.so", "getenv", "HOME")
+			:echo libcallnr("/usr/lib/libc.so", "getpid", "")
+<
+							*libcallnr()*
+libcallnr({libname}, {funcname}, {argument})
+		Just like libcall(), but used for a function that returns an
+		int instead of a string.
+		{only in Win32 on some Unix versions, when the |+libcall|
+		feature is present}
+		Example (not very useful...): >
+			:call libcallnr("libc.so", "printf", "Hello World!\n")
+			:call libcallnr("libc.so", "sleep", 10)
+<
+							*line()*
+line({expr})	The result is a Number, which is the line number of the file
+		position given with {expr}.  The accepted positions are:
+		    .	    the cursor position
+		    $	    the last line in the current buffer
+		    'x	    position of mark x (if the mark is not set, 0 is
+			    returned)
+		    w0	    first line visible in current window
+		    w$	    last line visible in current window
+		Note that a mark in another file can be used.  The line number
+		then applies to another buffer.
+		To get the column number use |col()|.  To get both use
+		|getpos()|.
+		Examples: >
+			line(".")		line number of the cursor
+			line("'t")		line number of mark t
+			line("'" . marker)	line number of mark marker
+<							*last-position-jump*
+		This autocommand jumps to the last known position in a file
+		just after opening it, if the '" mark is set: >
+	:au BufReadPost * if line("'\"") > 0 && line("'\"") <= line("$") | exe "normal g'\"" | endif
+
+line2byte({lnum})					*line2byte()*
+		Return the byte count from the start of the buffer for line
+		{lnum}.  This includes the end-of-line character, depending on
+		the 'fileformat' option for the current buffer.  The first
+		line returns 1.
+		This can also be used to get the byte count for the line just
+		below the last line: >
+			line2byte(line("$") + 1)
+<		This is the file size plus one.
+		When {lnum} is invalid, or the |+byte_offset| feature has been
+		disabled at compile time, -1 is returned.
+		Also see |byte2line()|, |go| and |:goto|.
+
+lispindent({lnum})					*lispindent()*
+		Get the amount of indent for line {lnum} according the lisp
+		indenting rules, as with 'lisp'.
+		The indent is counted in spaces, the value of 'tabstop' is
+		relevant.  {lnum} is used just like in |getline()|.
+		When {lnum} is invalid or Vim was not compiled the
+		|+lispindent| feature, -1 is returned.
+
+localtime()						*localtime()*
+		Return the current time, measured as seconds since 1st Jan
+		1970.  See also |strftime()| and |getftime()|.
+
+
+map({expr}, {string})					*map()*
+		{expr} must be a |List| or a |Dictionary|.
+		Replace each item in {expr} with the result of evaluating
+		{string}.
+		Inside {string} |v:val| has the value of the current item.
+		For a |Dictionary| |v:key| has the key of the current item.
+		Example: >
+			:call map(mylist, '"> " . v:val . " <"')
+<		This puts "> " before and " <" after each item in "mylist".
+
+		Note that {string} is the result of an expression and is then
+		used as an expression again.  Often it is good to use a
+		|literal-string| to avoid having to double backslashes.  You
+		still have to double ' quotes
+
+		The operation is done in-place.  If you want a |List| or
+		|Dictionary| to remain unmodified make a copy first: >
+			:let tlist = map(copy(mylist), ' & . "\t"')
+
+<		Returns {expr}, the |List| or |Dictionary| that was filtered.
+		When an error is encountered while evaluating {string} no
+		further items in {expr} are processed.
+
+
+maparg({name}[, {mode} [, {abbr}]])			*maparg()*
+		Return the rhs of mapping {name} in mode {mode}.  When there
+		is no mapping for {name}, an empty String is returned.
+		{mode} can be one of these strings:
+			"n"	Normal
+			"v"	Visual
+			"o"	Operator-pending
+			"i"	Insert
+			"c"	Cmd-line
+			"l"	langmap |language-mapping|
+			""	Normal, Visual and Operator-pending
+		When {mode} is omitted, the modes for "" are used.
+		When {abbr} is there and it is non-zero use abbreviations
+		instead of mappings.
+		The {name} can have special key names, like in the ":map"
+		command.  The returned String has special characters
+		translated like in the output of the ":map" command listing.
+		The mappings local to the current buffer are checked first,
+		then the global mappings.
+		This function can be used to map a key even when it's already
+		mapped, and have it do the original mapping too.  Sketch: >
+			exe 'nnoremap <Tab> ==' . maparg('<Tab>', 'n')
+
+
+mapcheck({name}[, {mode} [, {abbr}]])			*mapcheck()*
+		Check if there is a mapping that matches with {name} in mode
+		{mode}.  See |maparg()| for {mode} and special names in
+		{name}.
+		When {abbr} is there and it is non-zero use abbreviations
+		instead of mappings.
+		A match happens with a mapping that starts with {name} and
+		with a mapping which is equal to the start of {name}.
+
+			matches mapping "a"     "ab"    "abc" ~
+		   mapcheck("a")	yes	yes	 yes
+		   mapcheck("abc")	yes	yes	 yes
+		   mapcheck("ax")	yes	no	 no
+		   mapcheck("b")	no	no	 no
+
+		The difference with maparg() is that mapcheck() finds a
+		mapping that matches with {name}, while maparg() only finds a
+		mapping for {name} exactly.
+		When there is no mapping that starts with {name}, an empty
+		String is returned.  If there is one, the rhs of that mapping
+		is returned.  If there are several mappings that start with
+		{name}, the rhs of one of them is returned.
+		The mappings local to the current buffer are checked first,
+		then the global mappings.
+		This function can be used to check if a mapping can be added
+		without being ambiguous.  Example: >
+	:if mapcheck("_vv") == ""
+	:   map _vv :set guifont=7x13<CR>
+	:endif
+<		This avoids adding the "_vv" mapping when there already is a
+		mapping for "_v" or for "_vvv".
+
+match({expr}, {pat}[, {start}[, {count}]])			*match()*
+		When {expr} is a |List| then this returns the index of the
+		first item where {pat} matches.  Each item is used as a
+		String, |Lists| and |Dictionaries| are used as echoed.
+		Otherwise, {expr} is used as a String.  The result is a
+		Number, which gives the index (byte offset) in {expr} where
+		{pat} matches.
+		A match at the first character or |List| item returns zero.
+		If there is no match -1 is returned.
+		Example: >
+			:echo match("testing", "ing")	" results in 4
+			:echo match([1, 'x'], '\a')	" results in 1
+<		See |string-match| for how {pat} is used.
+								*strpbrk()*
+		Vim doesn't have a strpbrk() function.  But you can do: >
+			:let sepidx = match(line, '[.,;: \t]')
+<								*strcasestr()*
+		Vim doesn't have a strcasestr() function.  But you can add
+		"\c" to the pattern to ignore case: >
+			:let idx = match(haystack, '\cneedle')
+<
+		If {start} is given, the search starts from byte index
+		{start} in a String or item {start} in a |List|.
+		The result, however, is still the index counted from the
+		first character/item.  Example: >
+			:echo match("testing", "ing", 2)
+<		result is again "4". >
+			:echo match("testing", "ing", 4)
+<		result is again "4". >
+			:echo match("testing", "t", 2)
+<		result is "3".
+		For a String, if {start} > 0 then it is like the string starts
+		{start} bytes later, thus "^" will match at {start}.  Except
+		when {count} is given, then it's like matches before the
+		{start} byte are ignored (this is a bit complicated to keep it
+		backwards compatible).
+		For a String, if {start} < 0, it will be set to 0.  For a list
+		the index is counted from the end.
+		If {start} is out of range ({start} > strlen({expr}) for a
+		String or {start} > len({expr}) for a |List|) -1 is returned.
+
+		When {count} is given use the {count}'th match.  When a match
+		is found in a String the search for the next one starts one
+		character further.  Thus this example results in 1: >
+			echo match("testing", "..", 0, 2)
+<		In a |List| the search continues in the next item.
+		Note that when {count} is added the way {start} works changes,
+		see above.
+
+		See |pattern| for the patterns that are accepted.
+		The 'ignorecase' option is used to set the ignore-caseness of
+		the pattern.  'smartcase' is NOT used.  The matching is always
+		done like 'magic' is set and 'cpoptions' is empty.
+
+
+matcharg({nr})							*matcharg()*
+		Selects the {nr} match item, as set with a |:match|,
+		|:2match| or |:3match| command.
+		Return a |List| with two elements:
+			The name of the highlight group used
+			The pattern used.
+		When {nr} is not 1, 2 or 3 returns an empty |List|.
+		When there is no match item set returns ['', ''].
+		This is usef to save and restore a |:match|.
+
+
+matchend({expr}, {pat}[, {start}[, {count}]])			*matchend()*
+		Same as match(), but return the index of first character after
+		the match.  Example: >
+			:echo matchend("testing", "ing")
+<		results in "7".
+							*strspn()* *strcspn()*
+		Vim doesn't have a strspn() or strcspn() function, but you can
+		do it with matchend(): >
+			:let span = matchend(line, '[a-zA-Z]')
+			:let span = matchend(line, '[^a-zA-Z]')
+<		Except that -1 is returned when there are no matches.
+
+		The {start}, if given, has the same meaning as for match(). >
+			:echo matchend("testing", "ing", 2)
+<		results in "7". >
+			:echo matchend("testing", "ing", 5)
+<		result is "-1".
+		When {expr} is a |List| the result is equal to match().
+
+matchlist({expr}, {pat}[, {start}[, {count}]])			*matchlist()*
+		Same as match(), but return a |List|.  The first item in the
+		list is the matched string, same as what matchstr() would
+		return.  Following items are submatches, like "\1", "\2", etc.
+		in |:substitute|.  When an optional submatch didn't match an
+		empty string is used.  Example: >
+			echo matchlist('acd', '\(a\)\?\(b\)\?\(c\)\?\(.*\)')
+<		Results in: ['acd', 'a', '', 'c', 'd', '', '', '', '', '']
+		When there is no match an empty list is returned.
+
+matchstr({expr}, {pat}[, {start}[, {count}]])			*matchstr()*
+		Same as match(), but return the matched string.  Example: >
+			:echo matchstr("testing", "ing")
+<		results in "ing".
+		When there is no match "" is returned.
+		The {start}, if given, has the same meaning as for match(). >
+			:echo matchstr("testing", "ing", 2)
+<		results in "ing". >
+			:echo matchstr("testing", "ing", 5)
+<		result is "".
+		When {expr} is a |List| then the matching item is returned.
+		The type isn't changed, it's not necessarily a String.
+
+							*max()*
+max({list})	Return the maximum value of all items in {list}.
+		If {list} is not a list or one of the items in {list} cannot
+		be used as a Number this results in an error.
+		An empty |List| results in zero.
+
+							*min()*
+min({list})	Return the minimum value of all items in {list}.
+		If {list} is not a list or one of the items in {list} cannot
+		be used as a Number this results in an error.
+		An empty |List| results in zero.
+
+							*mkdir()* *E739*
+mkdir({name} [, {path} [, {prot}]])
+		Create directory {name}.
+		If {path} is "p" then intermediate directories are created as
+		necessary.  Otherwise it must be "".
+		If {prot} is given it is used to set the protection bits of
+		the new directory.  The default is 0755 (rwxr-xr-x: r/w for
+		the user readable for others).  Use 0700 to make it unreadable
+		for others.
+		This function is not available in the |sandbox|.
+		Not available on all systems.  To check use: >
+			:if exists("*mkdir")
+<
+							*mode()*
+mode()		Return a string that indicates the current mode:
+			n	Normal
+			v	Visual by character
+			V	Visual by line
+			CTRL-V	Visual blockwise
+			s	Select by character
+			S	Select by line
+			CTRL-S	Select blockwise
+			i	Insert
+			R	Replace
+			c	Command-line
+			r	Hit-enter prompt
+		This is useful in the 'statusline' option.  In most other
+		places it always returns "c" or "n".
+
+nextnonblank({lnum})					*nextnonblank()*
+		Return the line number of the first line at or below {lnum}
+		that is not blank.  Example: >
+			if getline(nextnonblank(1)) =~ "Java"
+<		When {lnum} is invalid or there is no non-blank line at or
+		below it, zero is returned.
+		See also |prevnonblank()|.
+
+nr2char({expr})						*nr2char()*
+		Return a string with a single character, which has the number
+		value {expr}.  Examples: >
+			nr2char(64)		returns "@"
+			nr2char(32)		returns " "
+<		The current 'encoding' is used.  Example for "utf-8": >
+			nr2char(300)		returns I with bow character
+<		Note that a NUL character in the file is specified with
+		nr2char(10), because NULs are represented with newline
+		characters.  nr2char(0) is a real NUL and terminates the
+		string, thus results in an empty string.
+
+							*getpos()*
+getpos({expr})	Get the position for {expr}.  For possible values of {expr}
+		see |line()|.
+		The result is a |List| with four numbers:
+		    [bufnum, lnum, col, off]
+		"bufnum" is zero, unless a mark like '0 or 'A is used, then it
+		is the buffer number of the mark.
+		"lnum" and "col" are the position in the buffer.  The first
+		column is 1.
+		The "off" number is zero, unless 'virtualedit' is used.  Then
+		it is the offset in screen columns from the start of the
+		character.  E.g., a position within a <Tab> or after the last
+		character.
+		This can be used to save and restore the cursor position: >
+			let save_cursor = getpos(".")
+			MoveTheCursorAround
+			call setpos('.', save_cursor)
+<		Also see |setpos()|.
+
+pathshorten({expr})					*pathshorten()*
+		Shorten directory names in the path {expr} and return the
+		result.  The tail, the file name, is kept as-is.  The other
+		components in the path are reduced to single letters.  Leading
+		'~' and '.' characters are kept.  Example: >
+			:echo pathshorten('~/.vim/autoload/myfile.vim')
+<			~/.v/a/myfile.vim ~
+		It doesn't matter if the path exists or not.
+
+prevnonblank({lnum})					*prevnonblank()*
+		Return the line number of the first line at or above {lnum}
+		that is not blank.  Example: >
+			let ind = indent(prevnonblank(v:lnum - 1))
+<		When {lnum} is invalid or there is no non-blank line at or
+		above it, zero is returned.
+		Also see |nextnonblank()|.
+
+
+printf({fmt}, {expr1} ...)				*printf()*
+		Return a String with {fmt}, where "%" items are replaced by
+		the formatted form of their respective arguments.  Example: >
+			printf("%4d: E%d %.30s", lnum, errno, msg)
+<		May result in:
+			"  99: E42 asdfasdfasdfasdfasdfasdfasdfas" ~
+
+		Often used items are:
+		  %s	string
+		  %6s	string right-aligned in 6 bytes
+		  %.9s  string truncated to 9 bytes
+		  %c    single byte
+		  %d    decimal number
+		  %5d   decimal number padded with spaces to 5 characters
+		  %x    hex number
+		  %04x  hex number padded with zeros to at least 4 characters
+		  %X    hex number using upper case letters
+		  %o    octal number
+		  %%    the % character itself
+
+		Conversion specifications start with '%' and end with the
+		conversion type.  All other characters are copied unchanged to
+		the result.
+
+		The "%" starts a conversion specification.  The following
+		arguments appear in sequence:
+
+			%  [flags]  [field-width]  [.precision]  type
+
+		flags
+			Zero or more of the following flags:
+
+		    #	      The value should be converted to an "alternate
+			      form".  For c, d, and s conversions, this option
+			      has no effect.  For o conversions, the precision
+			      of the number is increased to force the first
+			      character of the output string to a zero (except
+			      if a zero value is printed with an explicit
+			      precision of zero).
+			      For x and X conversions, a non-zero result has
+			      the string "0x" (or "0X" for X conversions)
+			      prepended to it.
+
+		    0 (zero)  Zero padding.  For all conversions the converted
+			      value is padded on the left with zeros rather
+			      than blanks.  If a precision is given with a
+			      numeric conversion (d, o, x, and X), the 0 flag
+			      is ignored.
+
+		    -	      A negative field width flag; the converted value
+			      is to be left adjusted on the field boundary.
+			      The converted value is padded on the right with
+			      blanks, rather than on the left with blanks or
+			      zeros.  A - overrides a 0 if both are given.
+
+		    ' ' (space)  A blank should be left before a positive
+			      number produced by a signed conversion (d).
+
+		    +	      A sign must always be placed before a number
+			      produced by a signed conversion.  A + overrides
+			      a space if both are used.
+
+		field-width
+			An optional decimal digit string specifying a minimum
+			field width.  If the converted value has fewer bytes
+			than the field width, it will be padded with spaces on
+			the left (or right, if the left-adjustment flag has
+			been given) to fill out the field width.
+
+		.precision
+			An optional precision, in the form of a period '.'
+			followed by an optional digit string.  If the digit
+			string is omitted, the precision is taken as zero.
+			This gives the minimum number of digits to appear for
+			d, o, x, and X conversions, or the maximum number of
+			bytes to be printed from a string for s conversions.
+
+		type
+			A character that specifies the type of conversion to
+			be applied, see below.
+
+		A field width or precision, or both, may be indicated by an
+		asterisk '*' instead of a digit string.  In this case, a
+		Number argument supplies the field width or precision.  A
+		negative field width is treated as a left adjustment flag
+		followed by a positive field width; a negative precision is
+		treated as though it were missing.  Example: >
+			:echo printf("%d: %.*s", nr, width, line)
+<		This limits the length of the text used from "line" to
+		"width" bytes.
+
+		The conversion specifiers and their meanings are:
+
+		doxX    The Number argument is converted to signed decimal
+			(d), unsigned octal (o), or unsigned hexadecimal (x
+			and X) notation.  The letters "abcdef" are used for
+			x conversions; the letters "ABCDEF" are used for X
+			conversions.
+			The precision, if any, gives the minimum number of
+			digits that must appear; if the converted value
+			requires fewer digits, it is padded on the left with
+			zeros.
+			In no case does a non-existent or small field width
+			cause truncation of a numeric field; if the result of
+			a conversion is wider than the field width, the field
+			is expanded to contain the conversion result.
+
+		c	The Number argument is converted to a byte, and the
+			resulting character is written.
+
+		s	The text of the String argument is used.  If a
+			precision is specified, no more bytes than the number
+			specified are used.
+
+		%	A '%' is written.  No argument is converted.  The
+			complete conversion specification is "%%".
+
+		Each argument can be Number or String and is converted
+		automatically to fit the conversion specifier.  Any other
+		argument type results in an error message.
+
+							*E766* *E767*
+		The number of {exprN} arguments must exactly match the number
+		of "%" items.  If there are not sufficient or too many
+		arguments an error is given.  Up to 18 arguments can be used.
+
+
+pumvisible()						*pumvisible()*
+		Returns non-zero when the popup menu is visible, zero
+		otherwise.  See |ins-completion-menu|.
+		This can be used to avoid some things that would remove the
+		popup menu.
+
+							*E726* *E727*
+range({expr} [, {max} [, {stride}]])				*range()*
+		Returns a |List| with Numbers:
+		- If only {expr} is specified: [0, 1, ..., {expr} - 1]
+		- If {max} is specified: [{expr}, {expr} + 1, ..., {max}]
+		- If {stride} is specified: [{expr}, {expr} + {stride}, ...,
+		  {max}] (increasing {expr} with {stride} each time, not
+		  producing a value past {max}).
+		When the maximum is one before the start the result is an
+		empty list.  When the maximum is more than one before the
+		start this is an error.
+		Examples: >
+			range(4)		" [0, 1, 2, 3]
+			range(2, 4)		" [2, 3, 4]
+			range(2, 9, 3)		" [2, 5, 8]
+			range(2, -2, -1)	" [2, 1, 0, -1, -2]
+			range(0)		" []
+			range(2, 0)		" error!
+<
+							*readfile()*
+readfile({fname} [, {binary} [, {max}]])
+		Read file {fname} and return a |List|, each line of the file
+		as an item.  Lines broken at NL characters.  Macintosh files
+		separated with CR will result in a single long line (unless a
+		NL appears somewhere).
+		When {binary} is equal to "b" binary mode is used:
+		- When the last line ends in a NL an extra empty list item is
+		  added.
+		- No CR characters are removed.
+		Otherwise:
+		- CR characters that appear before a NL are removed.
+		- Whether the last line ends in a NL or not does not matter.
+		All NUL characters are replaced with a NL character.
+		When {max} is given this specifies the maximum number of lines
+		to be read.  Useful if you only want to check the first ten
+		lines of a file: >
+			:for line in readfile(fname, '', 10)
+			:  if line =~ 'Date' | echo line | endif
+			:endfor
+<		When {max} is negative -{max} lines from the end of the file
+		are returned, or as many as there are.
+		When {max} is zero the result is an empty list.
+		Note that without {max} the whole file is read into memory.
+		Also note that there is no recognition of encoding.  Read a
+		file into a buffer if you need to.
+		When the file can't be opened an error message is given and
+		the result is an empty list.
+		Also see |writefile()|.
+
+reltime([{start} [, {end}]])				*reltime()*
+		Return an item that represents a time value.  The format of
+		the item depends on the system.  It can be passed to
+		|reltimestr()| to convert it to a string.
+		Without an argument it returns the current time.
+		With one argument is returns the time passed since the time
+		specified in the argument.
+		With two arguments it returns the time passed between {start}
+		and {end}.
+		The {start} and {end} arguments must be values returned by
+		reltime().
+		{only available when compiled with the +reltime feature}
+
+reltimestr({time})				*reltimestr()*
+		Return a String that represents the time value of {time}.
+		This is the number of seconds, a dot and the number of
+		microseconds.  Example: >
+			let start = reltime()
+			call MyFunction()
+			echo reltimestr(reltime(start))
+<		Note that overhead for the commands will be added to the time.
+		The accuracy depends on the system.
+		Leading spaces are used to make the string align nicely.  You
+		can use split() to remove it. >
+			echo split(reltimestr(reltime(start)))[0]
+<		Also see |profiling|.
+		{only available when compiled with the +reltime feature}
+
+							*remote_expr()* *E449*
+remote_expr({server}, {string} [, {idvar}])
+		Send the {string} to {server}.  The string is sent as an
+		expression and the result is returned after evaluation.
+		The result must be a String or a |List|.  A |List| is turned
+		into a String by joining the items with a line break in
+		between (not at the end), like with join(expr, "\n").
+		If {idvar} is present, it is taken as the name of a
+		variable and a {serverid} for later use with
+		remote_read() is stored there.
+		See also |clientserver| |RemoteReply|.
+		This function is not available in the |sandbox|.
+		{only available when compiled with the |+clientserver| feature}
+		Note: Any errors will cause a local error message to be issued
+		and the result will be the empty string.
+		Examples: >
+			:echo remote_expr("gvim", "2+2")
+			:echo remote_expr("gvim1", "b:current_syntax")
+<
+
+remote_foreground({server})				*remote_foreground()*
+		Move the Vim server with the name {server} to the foreground.
+		This works like: >
+			remote_expr({server}, "foreground()")
+<		Except that on Win32 systems the client does the work, to work
+		around the problem that the OS doesn't always allow the server
+		to bring itself to the foreground.
+		Note: This does not restore the window if it was minimized,
+		like foreground() does.
+		This function is not available in the |sandbox|.
+		{only in the Win32, Athena, Motif and GTK GUI versions and the
+		Win32 console version}
+
+
+remote_peek({serverid} [, {retvar}])		*remote_peek()*
+		Returns a positive number if there are available strings
+		from {serverid}.  Copies any reply string into the variable
+		{retvar} if specified.  {retvar} must be a string with the
+		name of a variable.
+		Returns zero if none are available.
+		Returns -1 if something is wrong.
+		See also |clientserver|.
+		This function is not available in the |sandbox|.
+		{only available when compiled with the |+clientserver| feature}
+		Examples: >
+			:let repl = ""
+			:echo "PEEK: ".remote_peek(id, "repl").": ".repl
+
+remote_read({serverid})				*remote_read()*
+		Return the oldest available reply from {serverid} and consume
+		it.  It blocks until a reply is available.
+		See also |clientserver|.
+		This function is not available in the |sandbox|.
+		{only available when compiled with the |+clientserver| feature}
+		Example: >
+			:echo remote_read(id)
+<
+							*remote_send()* *E241*
+remote_send({server}, {string} [, {idvar}])
+		Send the {string} to {server}.  The string is sent as input
+		keys and the function returns immediately.  At the Vim server
+		the keys are not mapped |:map|.
+		If {idvar} is present, it is taken as the name of a variable
+		and a {serverid} for later use with remote_read() is stored
+		there.
+		See also |clientserver| |RemoteReply|.
+		This function is not available in the |sandbox|.
+		{only available when compiled with the |+clientserver| feature}
+		Note: Any errors will be reported in the server and may mess
+		up the display.
+		Examples: >
+		:echo remote_send("gvim", ":DropAndReply ".file, "serverid").
+		 \ remote_read(serverid)
+
+		:autocmd NONE RemoteReply *
+		 \ echo remote_read(expand("<amatch>"))
+		:echo remote_send("gvim", ":sleep 10 | echo ".
+		 \ 'server2client(expand("<client>"), "HELLO")<CR>')
+<
+remove({list}, {idx} [, {end}])				*remove()*
+		Without {end}: Remove the item at {idx} from |List| {list} and
+		return it.
+		With {end}: Remove items from {idx} to {end} (inclusive) and
+		return a list with these items.  When {idx} points to the same
+		item as {end} a list with one item is returned.  When {end}
+		points to an item before {idx} this is an error.
+		See |list-index| for possible values of {idx} and {end}.
+		Example: >
+			:echo "last item: " . remove(mylist, -1)
+			:call remove(mylist, 0, 9)
+remove({dict}, {key})
+		Remove the entry from {dict} with key {key}.  Example: >
+			:echo "removed " . remove(dict, "one")
+<		If there is no {key} in {dict} this is an error.
+
+		Use |delete()| to remove a file.
+
+rename({from}, {to})					*rename()*
+		Rename the file by the name {from} to the name {to}.  This
+		should also work to move files across file systems.  The
+		result is a Number, which is 0 if the file was renamed
+		successfully, and non-zero when the renaming failed.
+		This function is not available in the |sandbox|.
+
+repeat({expr}, {count})					*repeat()*
+		Repeat {expr} {count} times and return the concatenated
+		result.  Example: >
+			:let separator = repeat('-', 80)
+<		When {count} is zero or negative the result is empty.
+		When {expr} is a |List| the result is {expr} concatenated
+		{count} times.  Example: >
+			:let longlist = repeat(['a', 'b'], 3)
+<		Results in ['a', 'b', 'a', 'b', 'a', 'b'].
+
+
+resolve({filename})					*resolve()* *E655*
+		On MS-Windows, when {filename} is a shortcut (a .lnk file),
+		returns the path the shortcut points to in a simplified form.
+		On Unix, repeat resolving symbolic links in all path
+		components of {filename} and return the simplified result.
+		To cope with link cycles, resolving of symbolic links is
+		stopped after 100 iterations.
+		On other systems, return the simplified {filename}.
+		The simplification step is done as by |simplify()|.
+		resolve() keeps a leading path component specifying the
+		current directory (provided the result is still a relative
+		path name) and also keeps a trailing path separator.
+
+							*reverse()*
+reverse({list})	Reverse the order of items in {list} in-place.  Returns
+		{list}.
+		If you want a list to remain unmodified make a copy first: >
+			:let revlist = reverse(copy(mylist))
+
+search({pattern} [, {flags} [, {stopline}]])			*search()*
+		Search for regexp pattern {pattern}.  The search starts at the
+		cursor position (you can use |cursor()| to set it).
+
+		{flags} is a String, which can contain these character flags:
+		'b'	search backward instead of forward
+		'c'     accept a match at the cursor position
+		'e'	move to the End of the match
+		'n'	do Not move the cursor
+		'p'	return number of matching sub-pattern (see below)
+		's'	set the ' mark at the previous location of the cursor
+		'w'	wrap around the end of the file
+		'W'	don't wrap around the end of the file
+		If neither 'w' or 'W' is given, the 'wrapscan' option applies.
+
+		If the 's' flag is supplied, the ' mark is set, only if the
+		cursor is moved. The 's' flag cannot be combined with the 'n'
+		flag.
+
+		'ignorecase', 'smartcase' and 'magic' are used.
+
+		When the {stopline} argument is given then the search stops
+		after searching this line.  This is useful to restrict the
+		search to a range of lines.  Examples: >
+			let match = search('(', 'b', line("w0"))
+			let end = search('END', '', line("w$"))
+<		When {stopline} is used and it is not zero this also implies
+		that the search does not wrap around the end of the file.
+
+		If there is no match a 0 is returned and the cursor doesn't
+		move.  No error message is given.
+		When a match has been found its line number is returned.
+							*search()-sub-match*
+		With the 'p' flag the returned value is one more than the
+		first sub-match in \(\).  One if none of them matched but the
+		whole pattern did match.
+		To get the column number too use |searchpos()|.
+
+		The cursor will be positioned at the match, unless the 'n'
+		flag is used.
+
+		Example (goes over all files in the argument list): >
+		    :let n = 1
+		    :while n <= argc()	    " loop over all files in arglist
+		    :  exe "argument " . n
+		    :  " start at the last char in the file and wrap for the
+		    :  " first search to find match at start of file
+		    :  normal G$
+		    :  let flags = "w"
+		    :  while search("foo", flags) > 0
+		    :    s/foo/bar/g
+		    :	 let flags = "W"
+		    :  endwhile
+		    :  update		    " write the file if modified
+		    :  let n = n + 1
+		    :endwhile
+<
+		Example for using some flags: >
+		    :echo search('\<if\|\(else\)\|\(endif\)', 'ncpe')
+<		This will search for the keywords "if", "else", and "endif"
+		under or after the cursor.  Because of the 'p' flag, it
+		returns 1, 2, or 3 depending on which keyword is found, or 0
+		if the search fails.  With the cursor on the first word of the
+		line:
+		    if (foo == 0) | let foo = foo + 1 | endif ~
+		the function returns 1.  Without the 'c' flag, the function
+		finds the "endif" and returns 3.  The same thing happens
+		without the 'e' flag if the cursor is on the "f" of "if".
+		The 'n' flag tells the function not to move the cursor.
+
+
+searchdecl({name} [, {global} [, {thisblock}]])			*searchdecl()*
+		Search for the declaration of {name}.
+
+		With a non-zero {global} argument it works like |gD|, find
+		first match in the file.  Otherwise it works like |gd|, find
+		first match in the function.
+
+		With a non-zero {thisblock} argument matches in a {} block
+		that ends before the cursor position are ignored.  Avoids
+		finding variable declarations only valid in another scope.
+
+		Moves the cursor to the found match.
+		Returns zero for success, non-zero for failure.
+		Example: >
+			if searchdecl('myvar') == 0
+			   echo getline('.')
+			endif
+<
+							*searchpair()*
+searchpair({start}, {middle}, {end} [, {flags} [, {skip} [, {stopline}]]])
+		Search for the match of a nested start-end pair.  This can be
+		used to find the "endif" that matches an "if", while other
+		if/endif pairs in between are ignored.
+		The search starts at the cursor.  The default is to search
+		forward, include 'b' in {flags} to search backward.
+		If a match is found, the cursor is positioned at it and the
+		line number is returned.  If no match is found 0 or -1 is
+		returned and the cursor doesn't move.  No error message is
+		given.
+
+		{start}, {middle} and {end} are patterns, see |pattern|.  They
+		must not contain \( \) pairs.  Use of \%( \) is allowed.  When
+		{middle} is not empty, it is found when searching from either
+		direction, but only when not in a nested start-end pair.  A
+		typical use is: >
+			searchpair('\<if\>', '\<else\>', '\<endif\>')
+<		By leaving {middle} empty the "else" is skipped.
+
+		{flags} 'b', 'c', 'n', 's', 'w' and 'W' are used like with
+		|search()|.  Additionally:
+		'r'	Repeat until no more matches found; will find the
+			outer pair
+		'm'	return number of Matches instead of line number with
+			the match; will be > 1 when 'r' is used.
+
+		When a match for {start}, {middle} or {end} is found, the
+		{skip} expression is evaluated with the cursor positioned on
+		the start of the match.  It should return non-zero if this
+		match is to be skipped.  E.g., because it is inside a comment
+		or a string.
+		When {skip} is omitted or empty, every match is accepted.
+		When evaluating {skip} causes an error the search is aborted
+		and -1 returned.
+
+		For {stopline} see |search()|.
+
+		The value of 'ignorecase' is used.  'magic' is ignored, the
+		patterns are used like it's on.
+
+		The search starts exactly at the cursor.  A match with
+		{start}, {middle} or {end} at the next character, in the
+		direction of searching, is the first one found.  Example: >
+			if 1
+			  if 2
+			  endif 2
+			endif 1
+<		When starting at the "if 2", with the cursor on the "i", and
+		searching forwards, the "endif 2" is found.  When starting on
+		the character just before the "if 2", the "endif 1" will be
+		found.  That's because the "if 2" will be found first, and
+		then this is considered to be a nested if/endif from "if 2" to
+		"endif 2".
+		When searching backwards and {end} is more than one character,
+		it may be useful to put "\zs" at the end of the pattern, so
+		that when the cursor is inside a match with the end it finds
+		the matching start.
+
+		Example, to find the "endif" command in a Vim script: >
+
+	:echo searchpair('\<if\>', '\<el\%[seif]\>', '\<en\%[dif]\>', 'W',
+			\ 'getline(".") =~ "^\\s*\""')
+
+<		The cursor must be at or after the "if" for which a match is
+		to be found.  Note that single-quote strings are used to avoid
+		having to double the backslashes.  The skip expression only
+		catches comments at the start of a line, not after a command.
+		Also, a word "en" or "if" halfway a line is considered a
+		match.
+		Another example, to search for the matching "{" of a "}": >
+
+	:echo searchpair('{', '', '}', 'bW')
+
+<		This works when the cursor is at or before the "}" for which a
+		match is to be found.  To reject matches that syntax
+		highlighting recognized as strings: >
+
+	:echo searchpair('{', '', '}', 'bW',
+	     \ 'synIDattr(synID(line("."), col("."), 0), "name") =~? "string"')
+<
+							*searchpairpos()*
+searchpairpos({start}, {middle}, {end} [, {flags} [, {skip} [, {stopline}]]])
+		Same as searchpair(), but returns a |List| with the line and
+		column position of the match. The first element of the |List|
+		is the line number and the second element is the byte index of
+		the column position of the match.  If no match is found,
+		returns [0, 0].
+>
+			:let [lnum,col] = searchpairpos('{', '', '}', 'n')
+<
+		See |match-parens| for a bigger and more useful example.
+
+searchpos({pattern} [, {flags} [, {stopline}]])		*searchpos()*
+		Same as |search()|, but returns a |List| with the line and
+		column position of the match. The first element of the |List|
+		is the line number and the second element is the byte index of
+		the column position of the match. If no match is found,
+		returns [0, 0].
+		Example: >
+	:let [lnum, col] = searchpos('mypattern', 'n')
+
+<		When the 'p' flag is given then there is an extra item with
+		the sub-pattern match number |search()-sub-match|.  Example: >
+	:let [lnum, col, submatch] = searchpos('\(\l\)\|\(\u\)', 'np')
+<		In this example "submatch" is 2 when a lowercase letter is
+		found |/\l|, 3 when an uppercase letter is found |/\u|.
+
+server2client( {clientid}, {string})			*server2client()*
+		Send a reply string to {clientid}.  The most recent {clientid}
+		that sent a string can be retrieved with expand("<client>").
+		{only available when compiled with the |+clientserver| feature}
+		Note:
+		This id has to be stored before the next command can be
+		received.  I.e. before returning from the received command and
+		before calling any commands that waits for input.
+		See also |clientserver|.
+		Example: >
+			:echo server2client(expand("<client>"), "HELLO")
+<
+serverlist()					*serverlist()*
+		Return a list of available server names, one per line.
+		When there are no servers or the information is not available
+		an empty string is returned.  See also |clientserver|.
+		{only available when compiled with the |+clientserver| feature}
+		Example: >
+			:echo serverlist()
+<
+setbufvar({expr}, {varname}, {val})			*setbufvar()*
+		Set option or local variable {varname} in buffer {expr} to
+		{val}.
+		This also works for a global or local window option, but it
+		doesn't work for a global or local window variable.
+		For a local window option the global value is unchanged.
+		For the use of {expr}, see |bufname()| above.
+		Note that the variable name without "b:" must be used.
+		Examples: >
+			:call setbufvar(1, "&mod", 1)
+			:call setbufvar("todo", "myvar", "foobar")
+<		This function is not available in the |sandbox|.
+
+setcmdpos({pos})					*setcmdpos()*
+		Set the cursor position in the command line to byte position
+		{pos}.  The first position is 1.
+		Use |getcmdpos()| to obtain the current position.
+		Only works while editing the command line, thus you must use
+		|c_CTRL-\_e|, |c_CTRL-R_=| or |c_CTRL-R_CTRL-R| with '='.  For
+		|c_CTRL-\_e| and |c_CTRL-R_CTRL-R| with '=' the position is
+		set after the command line is set to the expression.  For
+		|c_CTRL-R_=| it is set after evaluating the expression but
+		before inserting the resulting text.
+		When the number is too big the cursor is put at the end of the
+		line.  A number smaller than one has undefined results.
+		Returns 0 when successful, 1 when not editing the command
+		line.
+
+setline({lnum}, {line})					*setline()*
+		Set line {lnum} of the current buffer to {line}.
+		{lnum} is used like with |getline()|.
+		When {lnum} is just below the last line the {line} will be
+		added as a new line.
+		If this succeeds, 0 is returned.  If this fails (most likely
+		because {lnum} is invalid) 1 is returned.  Example: >
+			:call setline(5, strftime("%c"))
+<		When {line} is a |List| then line {lnum} and following lines
+		will be set to the items in the list.  Example: >
+			:call setline(5, ['aaa', 'bbb', 'ccc'])
+<		This is equivalent to: >
+			:for [n, l] in [[5, 6, 7], ['aaa', 'bbb', 'ccc']]
+			:  call setline(n, l)
+			:endfor
+<		Note: The '[ and '] marks are not set.
+
+setloclist({nr}, {list} [, {action}])			*setloclist()*
+		Create or replace or add to the location list for window {nr}.
+		When {nr} is zero the current window is used. For a location
+		list window, the displayed location list is modified.  For an
+		invalid window number {nr}, -1 is returned.
+		Otherwise, same as setqflist().
+
+							*setpos()*
+setpos({expr}, {list})
+		Set the position for {expr}.  Possible values:
+			.	the cursor
+			'x	mark x
+
+		{list} must be a |List| with four numbers:
+		    [bufnum, lnum, col, off]
+
+		"bufnum" is the buffer number.  Zero can be used for the
+		current buffer.  Setting the cursor is only possible for
+		the current buffer.  To set a mark in another buffer you can
+		use the |bufnr()| function to turn a file name into a buffer
+		number.
+		Does not change the jumplist.
+
+		"lnum" and "col" are the position in the buffer.  The first
+		column is 1.  Use a zero "lnum" to delete a mark.
+
+		The "off" number is only used when 'virtualedit' is set. Then
+		it is the offset in screen columns from the start of the
+		character.  E.g., a position within a <Tab> or after the last
+		character.
+
+		Also see |getpos()|
+
+		This does not restore the preferred column for moving
+		vertically.  See |winrestview()| for that.
+
+
+setqflist({list} [, {action}])				*setqflist()*
+		Create or replace or add to the quickfix list using the items
+		in {list}.  Each item in {list} is a dictionary.
+		Non-dictionary items in {list} are ignored.  Each dictionary
+		item can contain the following entries:
+
+		    bufnr	buffer number; must be the number of a valid
+		    		buffer
+		    filename	name of a file; only used when "bufnr" is not
+		    		present or it is invalid.
+		    lnum	line number in the file
+		    pattern	search pattern used to locate the error
+		    col		column number
+		    vcol	when non-zero: "col" is visual column
+				when zero: "col" is byte index
+		    nr		error number
+		    text	description of the error
+		    type	single-character error type, 'E', 'W', etc.
+
+		The "col", "vcol", "nr", "type" and "text" entries are
+		optional.  Either "lnum" or "pattern" entry can be used to
+		locate a matching error line.
+		If the "filename" and "bufnr" entries are not present or
+		neither the "lnum" or "pattern" entries are present, then the
+		item will not be handled as an error line.
+		If both "pattern" and "lnum" are present then "pattern" will
+		be used.
+		Note that the list is not exactly the same as what
+		|getqflist()| returns.
+
+		If {action} is set to 'a', then the items from {list} are
+		added to the existing quickfix list. If there is no existing
+		list, then a new list is created. If {action} is set to 'r',
+		then the items from the current quickfix list are replaced
+		with the items from {list}. If {action} is not present or is
+		set to ' ', then a new list is created.
+
+		Returns zero for success, -1 for failure.
+
+		This function can be used to create a quickfix list
+		independent of the 'errorformat' setting.  Use a command like
+		":cc 1" to jump to the first position.
+
+
+							*setreg()*
+setreg({regname}, {value} [,{options}])
+		Set the register {regname} to {value}.
+		If {options} contains "a" or {regname} is upper case,
+		then the value is appended.
+		{options} can also contains a register type specification:
+		    "c" or "v"	      |characterwise| mode
+		    "l" or "V"	      |linewise| mode
+		    "b" or "<CTRL-V>" |blockwise-visual| mode
+		If a number immediately follows "b" or "<CTRL-V>" then this is
+		used as the width of the selection - if it is not specified
+		then the width of the block is set to the number of characters
+		in the longest line (counting a <Tab> as 1 character).
+
+		If {options} contains no register settings, then the default
+		is to use character mode unless {value} ends in a <NL>.
+		Setting the '=' register is not possible.
+		Returns zero for success, non-zero for failure.
+
+		Examples: >
+			:call setreg(v:register, @*)
+			:call setreg('*', @%, 'ac')
+			:call setreg('a', "1\n2\n3", 'b5')
+
+<		This example shows using the functions to save and restore a
+		register. >
+			:let var_a = getreg('a', 1)
+			:let var_amode = getregtype('a')
+			    ....
+			:call setreg('a', var_a, var_amode)
+
+<		You can also change the type of a register by appending
+		nothing: >
+			:call setreg('a', '', 'al')
+
+settabwinvar({tabnr}, {winnr}, {varname}, {val})	*settabwinvar()*
+		Set option or local variable {varname} in window {winnr} to
+		{val}.
+		Tabs are numbered starting with one.  For the current tabpage
+		use |setwinvar()|.
+		When {winnr} is zero the current window is used.
+		This also works for a global or local buffer option, but it
+		doesn't work for a global or local buffer variable.
+		For a local buffer option the global value is unchanged.
+		Note that the variable name without "w:" must be used.
+		Vim briefly goes to the tab page {tabnr}, this may trigger
+		TabLeave and TabEnter autocommands.
+		Examples: >
+			:call settabwinvar(1, 1, "&list", 0)
+			:call settabwinvar(3, 2, "myvar", "foobar")
+<		This function is not available in the |sandbox|.
+
+setwinvar({nr}, {varname}, {val})			*setwinvar()*
+		Like |settabwinvar()| for the current tab page.
+		Examples: >
+			:call setwinvar(1, "&list", 0)
+			:call setwinvar(2, "myvar", "foobar")
+
+shellescape({string})					*shellescape()*
+		Escape {string} for use as shell command argument.
+		On MS-Windows and MS-DOS, when 'shellslash' is not set, it
+		will enclose {string} double quotes and double all double
+		quotes within {string}.
+		For other systems, it will enclose {string} in single quotes
+		and replace all "'" with "'\''".
+		Example: >
+			:echo shellescape('c:\program files\vim')
+<		results in:
+			"c:\program files\vim" ~
+		Example usage: >
+			:call system("chmod +x -- " . shellescape(expand("%")))
+
+
+simplify({filename})					*simplify()*
+		Simplify the file name as much as possible without changing
+		the meaning.  Shortcuts (on MS-Windows) or symbolic links (on
+		Unix) are not resolved.  If the first path component in
+		{filename} designates the current directory, this will be
+		valid for the result as well.  A trailing path separator is
+		not removed either.
+		Example: >
+			simplify("./dir/.././/file/") == "./file/"
+<		Note: The combination "dir/.." is only removed if "dir" is
+		a searchable directory or does not exist.  On Unix, it is also
+		removed when "dir" is a symbolic link within the same
+		directory.  In order to resolve all the involved symbolic
+		links before simplifying the path name, use |resolve()|.
+
+
+sort({list} [, {func}])					*sort()* *E702*
+		Sort the items in {list} in-place.  Returns {list}.  If you
+		want a list to remain unmodified make a copy first: >
+			:let sortedlist = sort(copy(mylist))
+<		Uses the string representation of each item to sort on.
+		Numbers sort after Strings, |Lists| after Numbers.
+		For sorting text in the current buffer use |:sort|.
+		When {func} is given and it is one then case is ignored.
+		When {func} is a |Funcref| or a function name, this function
+		is called to compare items.  The function is invoked with two
+		items as argument and must return zero if they are equal, 1 if
+		the first one sorts after the second one, -1 if the first one
+		sorts before the second one.  Example: >
+			func MyCompare(i1, i2)
+			   return a:i1 == a:i2 ? 0 : a:i1 > a:i2 ? 1 : -1
+			endfunc
+			let sortedlist = sort(mylist, "MyCompare")
+<
+
+							*soundfold()*
+soundfold({word})
+		Return the sound-folded equivalent of {word}.  Uses the first
+		language in 'spellang' for the current window that supports
+		soundfolding.  'spell' must be set.  When no sound folding is
+		possible the {word} is returned unmodified.
+		This can be used for making spelling suggestions.  Note that
+		the method can be quite slow.
+
+							*spellbadword()*
+spellbadword([{sentence}])
+		Without argument: The result is the badly spelled word under
+		or after the cursor.  The cursor is moved to the start of the
+		bad word.  When no bad word is found in the cursor line the
+		result is an empty string and the cursor doesn't move.
+
+		With argument: The result is the first word in {sentence} that
+		is badly spelled.  If there are no spelling mistakes the
+		result is an empty string.
+
+		The return value is a list with two items:
+		- The badly spelled word or an empty string.
+		- The type of the spelling error:
+			"bad"		spelling mistake
+			"rare"		rare word
+			"local"		word only valid in another region
+			"caps"		word should start with Capital
+		Example: >
+			echo spellbadword("the quik brown fox")
+<			['quik', 'bad'] ~
+
+		The spelling information for the current window is used.  The
+		'spell' option must be set and the value of 'spelllang' is
+		used.
+
+							*spellsuggest()*
+spellsuggest({word} [, {max} [, {capital}]])
+		Return a |List| with spelling suggestions to replace {word}.
+		When {max} is given up to this number of suggestions are
+		returned.  Otherwise up to 25 suggestions are returned.
+
+		When the {capital} argument is given and it's non-zero only
+		suggestions with a leading capital will be given.  Use this
+		after a match with 'spellcapcheck'.
+
+		{word} can be a badly spelled word followed by other text.
+		This allows for joining two words that were split.  The
+		suggestions also include the following text, thus you can
+		replace a line.
+
+		{word} may also be a good word.  Similar words will then be
+		returned.  {word} itself is not included in the suggestions,
+		although it may appear capitalized.
+
+		The spelling information for the current window is used.  The
+		'spell' option must be set and the values of 'spelllang' and
+		'spellsuggest' are used.
+
+
+split({expr} [, {pattern} [, {keepempty}]])			*split()*
+		Make a |List| out of {expr}.  When {pattern} is omitted or
+		empty each white-separated sequence of characters becomes an
+		item.
+		Otherwise the string is split where {pattern} matches,
+		removing the matched characters.
+		When the first or last item is empty it is omitted, unless the
+		{keepempty} argument is given and it's non-zero.
+		Other empty items are kept when {pattern} matches at least one
+		character or when {keepempty} is non-zero.
+		Example: >
+			:let words = split(getline('.'), '\W\+')
+<		To split a string in individual characters: >
+			:for c in split(mystring, '\zs')
+<		If you want to keep the separator you can also use '\zs': >
+			:echo split('abc:def:ghi', ':\zs')
+<			['abc:', 'def:', 'ghi'] ~
+		Splitting a table where the first element can be empty: >
+			:let items = split(line, ':', 1)
+<		The opposite function is |join()|.
+
+
+str2nr( {expr} [, {base}])				*str2nr()*
+		Convert string {expr} to a number.
+		{base} is the conversion base, it can be 8, 10 or 16.
+		When {base} is omitted base 10 is used.  This also means that
+		a leading zero doesn't cause octal conversion to be used, as
+		with the default String to Number conversion.
+		When {base} is 16 a leading "0x" or "0X" is ignored.  With a
+		different base the result will be zero.
+		Text after the number is silently ignored.
+
+
+strftime({format} [, {time}])				*strftime()*
+		The result is a String, which is a formatted date and time, as
+		specified by the {format} string.  The given {time} is used,
+		or the current time if no time is given.  The accepted
+		{format} depends on your system, thus this is not portable!
+		See the manual page of the C function strftime() for the
+		format.  The maximum length of the result is 80 characters.
+		See also |localtime()| and |getftime()|.
+		The language can be changed with the |:language| command.
+		Examples: >
+		  :echo strftime("%c")		   Sun Apr 27 11:49:23 1997
+		  :echo strftime("%Y %b %d %X")	   1997 Apr 27 11:53:25
+		  :echo strftime("%y%m%d %T")	   970427 11:53:55
+		  :echo strftime("%H:%M")	   11:55
+		  :echo strftime("%c", getftime("file.c"))
+						   Show mod time of file.c.
+<		Not available on all systems.  To check use: >
+			:if exists("*strftime")
+
+stridx({haystack}, {needle} [, {start}])		*stridx()*
+		The result is a Number, which gives the byte index in
+		{haystack} of the first occurrence of the String {needle}.
+		If {start} is specified, the search starts at index {start}.
+		This can be used to find a second match: >
+			:let comma1 = stridx(line, ",")
+			:let comma2 = stridx(line, ",", comma1 + 1)
+<		The search is done case-sensitive.
+		For pattern searches use |match()|.
+		-1 is returned if the {needle} does not occur in {haystack}.
+		See also |strridx()|.
+		Examples: >
+		  :echo stridx("An Example", "Example")	     3
+		  :echo stridx("Starting point", "Start")    0
+		  :echo stridx("Starting point", "start")   -1
+<						*strstr()* *strchr()*
+		stridx() works similar to the C function strstr().  When used
+		with a single character it works similar to strchr().
+
+							*string()*
+string({expr})	Return {expr} converted to a String.  If {expr} is a Number,
+		String or a composition of them, then the result can be parsed
+		back with |eval()|.
+			{expr} type	result ~
+			String		'string'
+			Number		123
+			Funcref		function('name')
+			List		[item, item]
+			Dictionary	{key: value, key: value}
+		Note that in String values the ' character is doubled.
+		Also see |strtrans()|.
+
+							*strlen()*
+strlen({expr})	The result is a Number, which is the length of the String
+		{expr} in bytes.
+		If you want to count the number of multi-byte characters (not
+		counting composing characters) use something like this: >
+
+			:let len = strlen(substitute(str, ".", "x", "g"))
+<
+		If the argument is a Number it is first converted to a String.
+		For other types an error is given.
+		Also see |len()|.
+
+strpart({src}, {start}[, {len}])			*strpart()*
+		The result is a String, which is part of {src}, starting from
+		byte {start}, with the byte length {len}.
+		When non-existing bytes are included, this doesn't result in
+		an error, the bytes are simply omitted.
+		If {len} is missing, the copy continues from {start} till the
+		end of the {src}. >
+			strpart("abcdefg", 3, 2)    == "de"
+			strpart("abcdefg", -2, 4)   == "ab"
+			strpart("abcdefg", 5, 4)    == "fg"
+			strpart("abcdefg", 3)       == "defg"
+<		Note: To get the first character, {start} must be 0.  For
+		example, to get three bytes under and after the cursor: >
+			strpart(getline("."), col(".") - 1, 3)
+<
+strridx({haystack}, {needle} [, {start}])			*strridx()*
+		The result is a Number, which gives the byte index in
+		{haystack} of the last occurrence of the String {needle}.
+		When {start} is specified, matches beyond this index are
+		ignored.  This can be used to find a match before a previous
+		match: >
+			:let lastcomma = strridx(line, ",")
+			:let comma2 = strridx(line, ",", lastcomma - 1)
+<		The search is done case-sensitive.
+		For pattern searches use |match()|.
+		-1 is returned if the {needle} does not occur in {haystack}.
+		If the {needle} is empty the length of {haystack} is returned.
+		See also |stridx()|.  Examples: >
+		  :echo strridx("an angry armadillo", "an")	     3
+<							*strrchr()*
+		When used with a single character it works similar to the C
+		function strrchr().
+
+strtrans({expr})					*strtrans()*
+		The result is a String, which is {expr} with all unprintable
+		characters translated into printable characters |'isprint'|.
+		Like they are shown in a window.  Example: >
+			echo strtrans(@a)
+<		This displays a newline in register a as "^@" instead of
+		starting a new line.
+
+submatch({nr})						*submatch()*
+		Only for an expression in a |:substitute| command.  Returns
+		the {nr}'th submatch of the matched text.  When {nr} is 0
+		the whole matched text is returned.
+		Example: >
+			:s/\d\+/\=submatch(0) + 1/
+<		This finds the first number in the line and adds one to it.
+		A line break is included as a newline character.
+
+substitute({expr}, {pat}, {sub}, {flags})		*substitute()*
+		The result is a String, which is a copy of {expr}, in which
+		the first match of {pat} is replaced with {sub}.  This works
+		like the ":substitute" command (without any flags).  But the
+		matching with {pat} is always done like the 'magic' option is
+		set and 'cpoptions' is empty (to make scripts portable).
+		'ignorecase' is still relevant.  'smartcase' is not used.
+		See |string-match| for how {pat} is used.
+		And a "~" in {sub} is not replaced with the previous {sub}.
+		Note that some codes in {sub} have a special meaning
+		|sub-replace-special|.  For example, to replace something with
+		"\n" (two characters), use "\\\\n" or '\\n'.
+		When {pat} does not match in {expr}, {expr} is returned
+		unmodified.
+		When {flags} is "g", all matches of {pat} in {expr} are
+		replaced.  Otherwise {flags} should be "".
+		Example: >
+			:let &path = substitute(&path, ",\\=[^,]*$", "", "")
+<		This removes the last component of the 'path' option. >
+			:echo substitute("testing", ".*", "\\U\\0", "")
+<		results in "TESTING".
+
+synID({lnum}, {col}, {trans})				*synID()*
+		The result is a Number, which is the syntax ID at the position
+		{lnum} and {col} in the current window.
+		The syntax ID can be used with |synIDattr()| and
+		|synIDtrans()| to obtain syntax information about text.
+
+		{col} is 1 for the leftmost column, {lnum} is 1 for the first
+		line.  'synmaxcol' applies, in a longer line zero is returned.
+
+		When {trans} is non-zero, transparent items are reduced to the
+		item that they reveal.  This is useful when wanting to know
+		the effective color.  When {trans} is zero, the transparent
+		item is returned.  This is useful when wanting to know which
+		syntax item is effective (e.g. inside parens).
+		Warning: This function can be very slow.  Best speed is
+		obtained by going through the file in forward direction.
+
+		Example (echoes the name of the syntax item under the cursor): >
+			:echo synIDattr(synID(line("."), col("."), 1), "name")
+<
+synIDattr({synID}, {what} [, {mode}])			*synIDattr()*
+		The result is a String, which is the {what} attribute of
+		syntax ID {synID}.  This can be used to obtain information
+		about a syntax item.
+		{mode} can be "gui", "cterm" or "term", to get the attributes
+		for that mode.  When {mode} is omitted, or an invalid value is
+		used, the attributes for the currently active highlighting are
+		used (GUI, cterm or term).
+		Use synIDtrans() to follow linked highlight groups.
+		{what}		result
+		"name"		the name of the syntax item
+		"fg"		foreground color (GUI: color name used to set
+				the color, cterm: color number as a string,
+				term: empty string)
+		"bg"		background color (like "fg")
+		"fg#"		like "fg", but for the GUI and the GUI is
+				running the name in "#RRGGBB" form
+		"bg#"		like "fg#" for "bg"
+		"bold"		"1" if bold
+		"italic"	"1" if italic
+		"reverse"	"1" if reverse
+		"inverse"	"1" if inverse (= reverse)
+		"underline"	"1" if underlined
+		"undercurl"	"1" if undercurled
+
+		Example (echoes the color of the syntax item under the
+		cursor): >
+	:echo synIDattr(synIDtrans(synID(line("."), col("."), 1)), "fg")
+<
+synIDtrans({synID})					*synIDtrans()*
+		The result is a Number, which is the translated syntax ID of
+		{synID}.  This is the syntax group ID of what is being used to
+		highlight the character.  Highlight links given with
+		":highlight link" are followed.
+
+system({expr} [, {input}])				*system()* *E677*
+		Get the output of the shell command {expr}.
+		When {input} is given, this string is written to a file and
+		passed as stdin to the command.  The string is written as-is,
+		you need to take care of using the correct line separators
+		yourself.  Pipes are not used.
+		Note: newlines in {expr} may cause the command to fail.  The
+		characters in 'shellquote' and 'shellxquote' may also cause
+		trouble.
+		This is not to be used for interactive commands.
+		The result is a String.  Example: >
+
+			:let files = system("ls")
+
+<		To make the result more system-independent, the shell output
+		is filtered to replace <CR> with <NL> for Macintosh, and
+		<CR><NL> with <NL> for DOS-like systems.
+		The command executed is constructed using several options:
+	'shell' 'shellcmdflag' 'shellxquote' {expr} 'shellredir' {tmp} 'shellxquote'
+		({tmp} is an automatically generated file name).
+		For Unix and OS/2 braces are put around {expr} to allow for
+		concatenated commands.
+
+		The command will be executed in "cooked" mode, so that a
+		CTRL-C will interrupt the command (on Unix at least).
+
+		The resulting error code can be found in |v:shell_error|.
+		This function will fail in |restricted-mode|.
+
+		Note that any wrong value in the options mentioned above may
+		make the function fail.  It has also been reported to fail
+		when using a security agent application.
+		Unlike ":!cmd" there is no automatic check for changed files.
+		Use |:checktime| to force a check.
+
+
+tabpagebuflist([{arg}])					*tabpagebuflist()*
+		The result is a |List|, where each item is the number of the
+		buffer associated with each window in the current tab page.
+		{arg} specifies the number of tab page to be used.  When
+		omitted the current tab page is used.
+		When {arg} is invalid the number zero is returned.
+		To get a list of all buffers in all tabs use this: >
+			tablist = []
+			for i in range(tabpagenr('$'))
+			   call extend(tablist, tabpagebuflist(i + 1))
+			endfor
+<		Note that a buffer may appear in more than one window.
+
+
+tabpagenr([{arg}])					*tabpagenr()*
+		The result is a Number, which is the number of the current
+		tab page.  The first tab page has number 1.
+		When the optional argument is "$", the number of the last tab
+		page is returned (the tab page count).
+		The number can be used with the |:tab| command.
+
+
+tabpagewinnr({tabarg}, [{arg}])				*tabpagewinnr()*
+		Like |winnr()| but for tab page {arg}.
+		{tabarg} specifies the number of tab page to be used.
+		{arg} is used like with |winnr()|:
+		- When omitted the current window number is returned.  This is
+		  the window which will be used when going to this tab page.
+		- When "$" the number of windows is returned.
+		- When "#" the previous window nr is returned.
+		Useful examples: >
+		    tabpagewinnr(1)	    " current window of tab page 1
+		    tabpagewinnr(4, '$')    " number of windows in tab page 4
+<		When {tabarg} is invalid zero is returned.
+
+							*tagfiles()*
+tagfiles()	Returns a |List| with the file names used to search for tags
+		for the current buffer.  This is the 'tags' option expanded.
+
+
+taglist({expr})							*taglist()*
+		Returns a list of tags matching the regular expression {expr}.
+		Each list item is a dictionary with at least the following
+		entries:
+			name		Name of the tag.
+			filename	Name of the file where the tag is
+					defined.  It is either relative to the
+					current directory or a full path.
+			cmd		Ex command used to locate the tag in
+					the file.
+			kind		Type of the tag.  The value for this
+					entry depends on the language specific
+					kind values.  Only available when
+					using a tags file generated by
+					Exuberant ctags or hdrtag.
+			static		A file specific tag.  Refer to
+					|static-tag| for more information.
+		More entries may be present, depending on the content of the
+		tags file: access, implementation, inherits and signature.
+		Refer to the ctags documentation for information about these
+		fields.  For C code the fields "struct", "class" and "enum"
+		may appear, they give the name of the entity the tag is
+		contained in.
+
+		The ex-command 'cmd' can be either an ex search pattern, a
+		line number or a line number followed by a byte number.
+
+		If there are no matching tags, then an empty list is returned.
+
+		To get an exact tag match, the anchors '^' and '$' should be
+		used in {expr}.  Refer to |tag-regexp| for more information
+		about the tag search regular expression pattern.
+
+		Refer to |'tags'| for information about how the tags file is
+		located by Vim. Refer to |tags-file-format| for the format of
+		the tags file generated by the different ctags tools.
+
+tempname()					*tempname()* *temp-file-name*
+		The result is a String, which is the name of a file that
+		doesn't exist.  It can be used for a temporary file.  The name
+		is different for at least 26 consecutive calls.  Example: >
+			:let tmpfile = tempname()
+			:exe "redir > " . tmpfile
+<		For Unix, the file will be in a private directory (only
+		accessible by the current user) to avoid security problems
+		(e.g., a symlink attack or other people reading your file).
+		When Vim exits the directory and all files in it are deleted.
+		For MS-Windows forward slashes are used when the 'shellslash'
+		option is set or when 'shellcmdflag' starts with '-'.
+
+tolower({expr})						*tolower()*
+		The result is a copy of the String given, with all uppercase
+		characters turned into lowercase (just like applying |gu| to
+		the string).
+
+toupper({expr})						*toupper()*
+		The result is a copy of the String given, with all lowercase
+		characters turned into uppercase (just like applying |gU| to
+		the string).
+
+tr({src}, {fromstr}, {tostr})				*tr()*
+		The result is a copy of the {src} string with all characters
+		which appear in {fromstr} replaced by the character in that
+		position in the {tostr} string.  Thus the first character in
+		{fromstr} is translated into the first character in {tostr}
+		and so on.  Exactly like the unix "tr" command.
+		This code also deals with multibyte characters properly.
+
+		Examples: >
+			echo tr("hello there", "ht", "HT")
+<		returns "Hello THere" >
+			echo tr("<blob>", "<>", "{}")
+<		returns "{blob}"
+
+							*type()*
+type({expr})	The result is a Number, depending on the type of {expr}:
+			Number:	    0
+			String:	    1
+			Funcref:    2
+			List:	    3
+			Dictionary: 4
+		To avoid the magic numbers it should be used this way: >
+			:if type(myvar) == type(0)
+			:if type(myvar) == type("")
+			:if type(myvar) == type(function("tr"))
+			:if type(myvar) == type([])
+			:if type(myvar) == type({})
+
+values({dict})						*values()*
+		Return a |List| with all the values of {dict}.  The |List| is
+		in arbitrary order.
+
+
+virtcol({expr})						*virtcol()*
+		The result is a Number, which is the screen column of the file
+		position given with {expr}.  That is, the last screen position
+		occupied by the character at that position, when the screen
+		would be of unlimited width.  When there is a <Tab> at the
+		position, the returned Number will be the column at the end of
+		the <Tab>.  For example, for a <Tab> in column 1, with 'ts'
+		set to 8, it returns 8.
+		For the use of {expr} see |col()|.  Additionally you can use
+		[lnum, col]: a |List| with the line and column number.  When
+		"lnum" or "col" is out of range then virtcol() returns zero.
+		When 'virtualedit' is used it can be [lnum, col, off], where
+		"off" is the offset in screen columns from the start of the
+		character.  E.g., a position within a <Tab> or after the last
+		character.
+		For the byte position use |col()|.
+		When Virtual editing is active in the current mode, a position
+		beyond the end of the line can be returned. |'virtualedit'|
+		The accepted positions are:
+		    .	    the cursor position
+		    $	    the end of the cursor line (the result is the
+			    number of displayed characters in the cursor line
+			    plus one)
+		    'x	    position of mark x (if the mark is not set, 0 is
+			    returned)
+		Note that only marks in the current file can be used.
+		Examples: >
+  virtcol(".")	   with text "foo^Lbar", with cursor on the "^L", returns 5
+  virtcol("$")	   with text "foo^Lbar", returns 9
+  virtcol("'t")    with text "    there", with 't at 'h', returns 6
+<		The first column is 1.  0 is returned for an error.
+		A more advanced example that echoes the maximum length of
+		all lines: >
+		    echo max(map(range(1, line('$')), "virtcol([v:val, '$'])"))
+
+
+visualmode([expr])						*visualmode()*
+		The result is a String, which describes the last Visual mode
+		used in the current buffer.  Initially it returns an empty
+		string, but once Visual mode has been used, it returns "v",
+		"V", or "<CTRL-V>" (a single CTRL-V character) for
+		character-wise, line-wise, or block-wise Visual mode
+		respectively.
+		Example: >
+			:exe "normal " . visualmode()
+<		This enters the same Visual mode as before.  It is also useful
+		in scripts if you wish to act differently depending on the
+		Visual mode that was used.
+
+		If an expression is supplied that results in a non-zero number
+		or a non-empty string, then the Visual mode will be cleared
+		and the old value is returned.  Note that " " and "0" are also
+		non-empty strings, thus cause the mode to be cleared.
+
+							*winbufnr()*
+winbufnr({nr})	The result is a Number, which is the number of the buffer
+		associated with window {nr}.  When {nr} is zero, the number of
+		the buffer in the current window is returned.  When window
+		{nr} doesn't exist, -1 is returned.
+		Example: >
+  :echo "The file in the current window is " . bufname(winbufnr(0))
+<
+							*wincol()*
+wincol()	The result is a Number, which is the virtual column of the
+		cursor in the window.  This is counting screen cells from the
+		left side of the window.  The leftmost column is one.
+
+winheight({nr})						*winheight()*
+		The result is a Number, which is the height of window {nr}.
+		When {nr} is zero, the height of the current window is
+		returned.  When window {nr} doesn't exist, -1 is returned.
+		An existing window always has a height of zero or more.
+		Examples: >
+  :echo "The current window has " . winheight(0) . " lines."
+<
+							*winline()*
+winline()	The result is a Number, which is the screen line of the cursor
+		in the window.  This is counting screen lines from the top of
+		the window.  The first line is one.
+		If the cursor was moved the view on the file will be updated
+		first, this may cause a scroll.
+
+							*winnr()*
+winnr([{arg}])	The result is a Number, which is the number of the current
+		window.  The top window has number 1.
+		When the optional argument is "$", the number of the
+		last window is returned (the window count).
+		When the optional argument is "#", the number of the last
+		accessed window is returned (where |CTRL-W_p| goes to).
+		If there is no previous window or it is in another tab page 0
+		is returned.
+		The number can be used with |CTRL-W_w| and ":wincmd w"
+		|:wincmd|.
+		Also see |tabpagewinnr()|.
+
+							*winrestcmd()*
+winrestcmd()	Returns a sequence of |:resize| commands that should restore
+		the current window sizes.  Only works properly when no windows
+		are opened or closed and the current window and tab page is
+		unchanged.
+		Example: >
+			:let cmd = winrestcmd()
+			:call MessWithWindowSizes()
+			:exe cmd
+<
+							*winrestview()*
+winrestview({dict})
+		Uses the |Dictionary| returned by |winsaveview()| to restore
+		the view of the current window.
+		If you have changed the values the result is unpredictable.
+		If the window size changed the result won't be the same.
+
+							*winsaveview()*
+winsaveview()	Returns a |Dictionary| that contains information to restore
+		the view of the current window.  Use |winrestview()| to
+		restore the view.
+		This is useful if you have a mapping that jumps around in the
+		buffer and you want to go back to the original view.
+		This does not save fold information.  Use the 'foldenable'
+		option to temporarily switch off folding, so that folds are
+		not opened when moving around.
+		The return value includes:
+			lnum		cursor line number
+			col		cursor column
+			coladd		cursor column offset for 'virtualedit'
+			curswant	column for vertical movement
+			topline		first line in the window
+			topfill		filler lines, only in diff mode
+			leftcol		first column displayed
+			skipcol		columns skipped
+		Note that no option values are saved.
+
+
+winwidth({nr})						*winwidth()*
+		The result is a Number, which is the width of window {nr}.
+		When {nr} is zero, the width of the current window is
+		returned.  When window {nr} doesn't exist, -1 is returned.
+		An existing window always has a width of zero or more.
+		Examples: >
+  :echo "The current window has " . winwidth(0) . " columns."
+  :if winwidth(0) <= 50
+  :  exe "normal 50\<C-W>|"
+  :endif
+<
+							*writefile()*
+writefile({list}, {fname} [, {binary}])
+		Write |List| {list} to file {fname}.  Each list item is
+		separated with a NL.  Each list item must be a String or
+		Number.
+		When {binary} is equal to "b" binary mode is used: There will
+		not be a NL after the last list item.  An empty item at the
+		end does cause the last line in the file to end in a NL.
+		All NL characters are replaced with a NUL character.
+		Inserting CR characters needs to be done before passing {list}
+		to writefile().
+		An existing file is overwritten, if possible.
+		When the write fails -1 is returned, otherwise 0.  There is an
+		error message if the file can't be created or when writing
+		fails.
+		Also see |readfile()|.
+		To copy a file byte for byte: >
+			:let fl = readfile("foo", "b")
+			:call writefile(fl, "foocopy", "b")
+<
+
+							*feature-list*
+There are three types of features:
+1.  Features that are only supported when they have been enabled when Vim
+    was compiled |+feature-list|.  Example: >
+	:if has("cindent")
+2.  Features that are only supported when certain conditions have been met.
+    Example: >
+	:if has("gui_running")
+<							*has-patch*
+3.  Included patches.  First check |v:version| for the version of Vim.
+    Then the "patch123" feature means that patch 123 has been included for
+    this version.  Example (checking version 6.2.148 or later): >
+	:if v:version > 602 || v:version == 602 && has("patch148")
+<   Note that it's possible for patch 147 to be omitted even though 148 is
+    included.
+
+all_builtin_terms	Compiled with all builtin terminals enabled.
+amiga			Amiga version of Vim.
+arabic			Compiled with Arabic support |Arabic|.
+arp			Compiled with ARP support (Amiga).
+autocmd			Compiled with autocommand support. |autocommand|
+balloon_eval		Compiled with |balloon-eval| support.
+balloon_multiline	GUI supports multiline balloons.
+beos			BeOS version of Vim.
+browse			Compiled with |:browse| support, and browse() will
+			work.
+builtin_terms		Compiled with some builtin terminals.
+byte_offset		Compiled with support for 'o' in 'statusline'
+cindent			Compiled with 'cindent' support.
+clientserver		Compiled with remote invocation support |clientserver|.
+clipboard		Compiled with 'clipboard' support.
+cmdline_compl		Compiled with |cmdline-completion| support.
+cmdline_hist		Compiled with |cmdline-history| support.
+cmdline_info		Compiled with 'showcmd' and 'ruler' support.
+comments		Compiled with |'comments'| support.
+cryptv			Compiled with encryption support |encryption|.
+cscope			Compiled with |cscope| support.
+compatible		Compiled to be very Vi compatible.
+debug			Compiled with "DEBUG" defined.
+dialog_con		Compiled with console dialog support.
+dialog_gui		Compiled with GUI dialog support.
+diff			Compiled with |vimdiff| and 'diff' support.
+digraphs		Compiled with support for digraphs.
+dnd			Compiled with support for the "~ register |quote_~|.
+dos32			32 bits DOS (DJGPP) version of Vim.
+dos16			16 bits DOS version of Vim.
+ebcdic			Compiled on a machine with ebcdic character set.
+emacs_tags		Compiled with support for Emacs tags.
+eval			Compiled with expression evaluation support.  Always
+			true, of course!
+ex_extra		Compiled with extra Ex commands |+ex_extra|.
+extra_search		Compiled with support for |'incsearch'| and
+			|'hlsearch'|
+farsi			Compiled with Farsi support |farsi|.
+file_in_path		Compiled with support for |gf| and |<cfile>|
+filterpipe		When 'shelltemp' is off pipes are used for shell
+			read/write/filter commands
+find_in_path		Compiled with support for include file searches
+			|+find_in_path|.
+fname_case		Case in file names matters (for Amiga, MS-DOS, and
+			Windows this is not present).
+folding			Compiled with |folding| support.
+footer			Compiled with GUI footer support. |gui-footer|
+fork			Compiled to use fork()/exec() instead of system().
+gettext			Compiled with message translation |multi-lang|
+gui			Compiled with GUI enabled.
+gui_athena		Compiled with Athena GUI.
+gui_gtk			Compiled with GTK+ GUI (any version).
+gui_gtk2		Compiled with GTK+ 2 GUI (gui_gtk is also defined).
+gui_mac			Compiled with Macintosh GUI.
+gui_motif		Compiled with Motif GUI.
+gui_photon		Compiled with Photon GUI.
+gui_win32		Compiled with MS Windows Win32 GUI.
+gui_win32s		idem, and Win32s system being used (Windows 3.1)
+gui_running		Vim is running in the GUI, or it will start soon.
+hangul_input		Compiled with Hangul input support. |hangul|
+iconv			Can use iconv() for conversion.
+insert_expand		Compiled with support for CTRL-X expansion commands in
+			Insert mode.
+jumplist		Compiled with |jumplist| support.
+keymap			Compiled with 'keymap' support.
+langmap			Compiled with 'langmap' support.
+libcall			Compiled with |libcall()| support.
+linebreak		Compiled with 'linebreak', 'breakat' and 'showbreak'
+			support.
+lispindent		Compiled with support for lisp indenting.
+listcmds		Compiled with commands for the buffer list |:files|
+			and the argument list |arglist|.
+localmap		Compiled with local mappings and abbr. |:map-local|
+mac			Macintosh version of Vim.
+macunix			Macintosh version of Vim, using Unix files (OS-X).
+menu			Compiled with support for |:menu|.
+mksession		Compiled with support for |:mksession|.
+modify_fname		Compiled with file name modifiers. |filename-modifiers|
+mouse			Compiled with support mouse.
+mouseshape		Compiled with support for 'mouseshape'.
+mouse_dec		Compiled with support for Dec terminal mouse.
+mouse_gpm		Compiled with support for gpm (Linux console mouse)
+mouse_netterm		Compiled with support for netterm mouse.
+mouse_pterm		Compiled with support for qnx pterm mouse.
+mouse_xterm		Compiled with support for xterm mouse.
+multi_byte		Compiled with support for editing Korean et al.
+multi_byte_ime		Compiled with support for IME input method.
+multi_lang		Compiled with support for multiple languages.
+mzscheme		Compiled with MzScheme interface |mzscheme|.
+netbeans_intg		Compiled with support for |netbeans|.
+netbeans_enabled	Compiled with support for |netbeans| and it's used.
+ole			Compiled with OLE automation support for Win32.
+os2			OS/2 version of Vim.
+osfiletype		Compiled with support for osfiletypes |+osfiletype|
+path_extra		Compiled with up/downwards search in 'path' and 'tags'
+perl			Compiled with Perl interface.
+postscript		Compiled with PostScript file printing.
+printer			Compiled with |:hardcopy| support.
+profile			Compiled with |:profile| support.
+python			Compiled with Python interface.
+qnx			QNX version of Vim.
+quickfix		Compiled with |quickfix| support.
+reltime			Compiled with |reltime()| support.
+rightleft		Compiled with 'rightleft' support.
+ruby			Compiled with Ruby interface |ruby|.
+scrollbind		Compiled with 'scrollbind' support.
+showcmd			Compiled with 'showcmd' support.
+signs			Compiled with |:sign| support.
+smartindent		Compiled with 'smartindent' support.
+sniff			Compiled with SNiFF interface support.
+statusline		Compiled with support for 'statusline', 'rulerformat'
+			and special formats of 'titlestring' and 'iconstring'.
+sun_workshop		Compiled with support for Sun |workshop|.
+spell			Compiled with spell checking support |spell|.
+syntax			Compiled with syntax highlighting support |syntax|.
+syntax_items		There are active syntax highlighting items for the
+			current buffer.
+system			Compiled to use system() instead of fork()/exec().
+tag_binary		Compiled with binary searching in tags files
+			|tag-binary-search|.
+tag_old_static		Compiled with support for old static tags
+			|tag-old-static|.
+tag_any_white		Compiled with support for any white characters in tags
+			files |tag-any-white|.
+tcl			Compiled with Tcl interface.
+terminfo		Compiled with terminfo instead of termcap.
+termresponse		Compiled with support for |t_RV| and |v:termresponse|.
+textobjects		Compiled with support for |text-objects|.
+tgetent			Compiled with tgetent support, able to use a termcap
+			or terminfo file.
+title			Compiled with window title support |'title'|.
+toolbar			Compiled with support for |gui-toolbar|.
+unix			Unix version of Vim.
+user_commands		User-defined commands.
+viminfo			Compiled with viminfo support.
+vim_starting		True while initial source'ing takes place.
+vertsplit		Compiled with vertically split windows |:vsplit|.
+virtualedit		Compiled with 'virtualedit' option.
+visual			Compiled with Visual mode.
+visualextra		Compiled with extra Visual mode commands.
+			|blockwise-operators|.
+vms			VMS version of Vim.
+vreplace		Compiled with |gR| and |gr| commands.
+wildignore		Compiled with 'wildignore' option.
+wildmenu		Compiled with 'wildmenu' option.
+windows			Compiled with support for more than one window.
+winaltkeys		Compiled with 'winaltkeys' option.
+win16			Win16 version of Vim (MS-Windows 3.1).
+win32			Win32 version of Vim (MS-Windows 95/98/ME/NT/2000/XP).
+win64			Win64 version of Vim (MS-Windows 64 bit).
+win32unix		Win32 version of Vim, using Unix files (Cygwin)
+win95			Win32 version for MS-Windows 95/98/ME.
+writebackup		Compiled with 'writebackup' default on.
+xfontset		Compiled with X fontset support |xfontset|.
+xim			Compiled with X input method support |xim|.
+xsmp			Compiled with X session management support.
+xsmp_interact		Compiled with interactive X session management support.
+xterm_clipboard		Compiled with support for xterm clipboard.
+xterm_save		Compiled with support for saving and restoring the
+			xterm screen.
+x11			Compiled with X11 support.
+
+							*string-match*
+Matching a pattern in a String
+
+A regexp pattern as explained at |pattern| is normally used to find a match in
+the buffer lines.  When a pattern is used to find a match in a String, almost
+everything works in the same way.  The difference is that a String is handled
+like it is one line.  When it contains a "\n" character, this is not seen as a
+line break for the pattern.  It can be matched with a "\n" in the pattern, or
+with ".".  Example: >
+	:let a = "aaaa\nxxxx"
+	:echo matchstr(a, "..\n..")
+	aa
+	xx
+	:echo matchstr(a, "a.x")
+	a
+	x
+
+Don't forget that "^" will only match at the first character of the String and
+"$" at the last character of the string.  They don't match after or before a
+"\n".
+
+==============================================================================
+5. Defining functions					*user-functions*
+
+New functions can be defined.  These can be called just like builtin
+functions.  The function executes a sequence of Ex commands.  Normal mode
+commands can be executed with the |:normal| command.
+
+The function name must start with an uppercase letter, to avoid confusion with
+builtin functions.  To prevent from using the same name in different scripts
+avoid obvious, short names.  A good habit is to start the function name with
+the name of the script, e.g., "HTMLcolor()".
+
+It's also possible to use curly braces, see |curly-braces-names|.  And the
+|autoload| facility is useful to define a function only when it's called.
+
+							*local-function*
+A function local to a script must start with "s:".  A local script function
+can only be called from within the script and from functions, user commands
+and autocommands defined in the script.  It is also possible to call the
+function from a mappings defined in the script, but then |<SID>| must be used
+instead of "s:" when the mapping is expanded outside of the script.
+
+					*:fu* *:function* *E128* *E129* *E123*
+:fu[nction]		List all functions and their arguments.
+
+:fu[nction] {name}	List function {name}.
+			{name} can also be a |Dictionary| entry that is a
+			|Funcref|: >
+				:function dict.init
+
+:fu[nction] /{pattern}	List functions with a name matching {pattern}.
+			Example that lists all functions ending with "File": >
+				:function /File$
+<
+							*:function-verbose*
+When 'verbose' is non-zero, listing a function will also display where it was
+last defined. Example: >
+
+    :verbose function SetFileTypeSH
+	function SetFileTypeSH(name)
+	    Last set from /usr/share/vim/vim-7.0/filetype.vim
+<
+See |:verbose-cmd| for more information.
+
+							*E124* *E125*
+:fu[nction][!] {name}([arguments]) [range] [abort] [dict]
+			Define a new function by the name {name}.  The name
+			must be made of alphanumeric characters and '_', and
+			must start with a capital or "s:" (see above).
+
+			{name} can also be a |Dictionary| entry that is a
+			|Funcref|: >
+				:function dict.init(arg)
+<			"dict" must be an existing dictionary.  The entry
+			"init" is added if it didn't exist yet.  Otherwise [!]
+			is required to overwrite an existing function.  The
+			result is a |Funcref| to a numbered function.  The
+			function can only be used with a |Funcref| and will be
+			deleted if there are no more references to it.
+								*E127* *E122*
+			When a function by this name already exists and [!] is
+			not used an error message is given.  When [!] is used,
+			an existing function is silently replaced.  Unless it
+			is currently being executed, that is an error.
+
+			For the {arguments} see |function-argument|.
+
+						*a:firstline* *a:lastline*
+			When the [range] argument is added, the function is
+			expected to take care of a range itself.  The range is
+			passed as "a:firstline" and "a:lastline".  If [range]
+			is excluded, ":{range}call" will call the function for
+			each line in the range, with the cursor on the start
+			of each line.  See |function-range-example|.
+
+			When the [abort] argument is added, the function will
+			abort as soon as an error is detected.
+
+			When the [dict] argument is added, the function must
+			be invoked through an entry in a |Dictionary|.  The
+			local variable "self" will then be set to the
+			dictionary.  See |Dictionary-function|.
+
+			The last used search pattern and the redo command "."
+			will not be changed by the function.
+
+					*:endf* *:endfunction* *E126* *E193*
+:endf[unction]		The end of a function definition.  Must be on a line
+			by its own, without other commands.
+
+					*:delf* *:delfunction* *E130* *E131*
+:delf[unction] {name}	Delete function {name}.
+			{name} can also be a |Dictionary| entry that is a
+			|Funcref|: >
+				:delfunc dict.init
+<			This will remove the "init" entry from "dict".  The
+			function is deleted if there are no more references to
+			it.
+							*:retu* *:return* *E133*
+:retu[rn] [expr]	Return from a function.  When "[expr]" is given, it is
+			evaluated and returned as the result of the function.
+			If "[expr]" is not given, the number 0 is returned.
+			When a function ends without an explicit ":return",
+			the number 0 is returned.
+			Note that there is no check for unreachable lines,
+			thus there is no warning if commands follow ":return".
+
+			If the ":return" is used after a |:try| but before the
+			matching |:finally| (if present), the commands
+			following the ":finally" up to the matching |:endtry|
+			are executed first.  This process applies to all
+			nested ":try"s inside the function.  The function
+			returns at the outermost ":endtry".
+
+						*function-argument* *a:var*
+An argument can be defined by giving its name.  In the function this can then
+be used as "a:name" ("a:" for argument).
+					*a:0* *a:1* *a:000* *E740* *...*
+Up to 20 arguments can be given, separated by commas.  After the named
+arguments an argument "..." can be specified, which means that more arguments
+may optionally be following.  In the function the extra arguments can be used
+as "a:1", "a:2", etc.  "a:0" is set to the number of extra arguments (which
+can be 0).  "a:000" is set to a |List| that contains these arguments.  Note
+that "a:1" is the same as "a:000[0]".
+								*E742*
+The a: scope and the variables in it cannot be changed, they are fixed.
+However, if a |List| or |Dictionary| is used, you can changes their contents.
+Thus you can pass a |List| to a function and have the function add an item to
+it.  If you want to make sure the function cannot change a |List| or
+|Dictionary| use |:lockvar|.
+
+When not using "...", the number of arguments in a function call must be equal
+to the number of named arguments.  When using "...", the number of arguments
+may be larger.
+
+It is also possible to define a function without any arguments.  You must
+still supply the () then.  The body of the function follows in the next lines,
+until the matching |:endfunction|.  It is allowed to define another function
+inside a function body.
+
+							*local-variables*
+Inside a function variables can be used.  These are local variables, which
+will disappear when the function returns.  Global variables need to be
+accessed with "g:".
+
+Example: >
+  :function Table(title, ...)
+  :  echohl Title
+  :  echo a:title
+  :  echohl None
+  :  echo a:0 . " items:"
+  :  for s in a:000
+  :    echon ' ' . s
+  :  endfor
+  :endfunction
+
+This function can then be called with: >
+  call Table("Table", "line1", "line2")
+  call Table("Empty Table")
+
+To return more than one value, return a |List|: >
+  :function Compute(n1, n2)
+  :  if a:n2 == 0
+  :    return ["fail", 0]
+  :  endif
+  :  return ["ok", a:n1 / a:n2]
+  :endfunction
+
+This function can then be called with: >
+  :let [success, div] = Compute(102, 6)
+  :if success == "ok"
+  :  echo div
+  :endif
+<
+						*:cal* *:call* *E107* *E117*
+:[range]cal[l] {name}([arguments])
+		Call a function.  The name of the function and its arguments
+		are as specified with |:function|.  Up to 20 arguments can be
+		used.  The returned value is discarded.
+		Without a range and for functions that accept a range, the
+		function is called once.  When a range is given the cursor is
+		positioned at the start of the first line before executing the
+		function.
+		When a range is given and the function doesn't handle it
+		itself, the function is executed for each line in the range,
+		with the cursor in the first column of that line.  The cursor
+		is left at the last line (possibly moved by the last function
+		call).  The arguments are re-evaluated for each line.  Thus
+		this works:
+						*function-range-example*  >
+	:function Mynumber(arg)
+	:  echo line(".") . " " . a:arg
+	:endfunction
+	:1,5call Mynumber(getline("."))
+<
+		The "a:firstline" and "a:lastline" are defined anyway, they
+		can be used to do something different at the start or end of
+		the range.
+
+		Example of a function that handles the range itself: >
+
+	:function Cont() range
+	:  execute (a:firstline + 1) . "," . a:lastline . 's/^/\t\\ '
+	:endfunction
+	:4,8call Cont()
+<
+		This function inserts the continuation character "\" in front
+		of all the lines in the range, except the first one.
+
+		When the function returns a composite value it can be further
+		dereferenced, but the range will not be used then.  Example: >
+	:4,8call GetDict().method()
+<		Here GetDict() gets the range but method() does not.
+
+								*E132*
+The recursiveness of user functions is restricted with the |'maxfuncdepth'|
+option.
+
+
+AUTOMATICALLY LOADING FUNCTIONS ~
+							*autoload-functions*
+When using many or large functions, it's possible to automatically define them
+only when they are used.  There are two methods: with an autocommand and with
+the "autoload" directory in 'runtimepath'.
+
+
+Using an autocommand ~
+
+This is introduced in the user manual, section |41.14|.
+
+The autocommand is useful if you have a plugin that is a long Vim script file.
+You can define the autocommand and quickly quit the script with |:finish|.
+That makes Vim startup faster.  The autocommand should then load the same file
+again, setting a variable to skip the |:finish| command.
+
+Use the FuncUndefined autocommand event with a pattern that matches the
+function(s) to be defined.  Example: >
+
+	:au FuncUndefined BufNet* source ~/vim/bufnetfuncs.vim
+
+The file "~/vim/bufnetfuncs.vim" should then define functions that start with
+"BufNet".  Also see |FuncUndefined|.
+
+
+Using an autoload script ~
+							*autoload* *E746*
+This is introduced in the user manual, section |41.15|.
+
+Using a script in the "autoload" directory is simpler, but requires using
+exactly the right file name.  A function that can be autoloaded has a name
+like this: >
+
+	:call filename#funcname()
+
+When such a function is called, and it is not defined yet, Vim will search the
+"autoload" directories in 'runtimepath' for a script file called
+"filename.vim".  For example "~/.vim/autoload/filename.vim".  That file should
+then define the function like this: >
+
+	function filename#funcname()
+	   echo "Done!"
+	endfunction
+
+The file name and the name used before the # in the function must match
+exactly, and the defined function must have the name exactly as it will be
+called.
+
+It is possible to use subdirectories.  Every # in the function name works like
+a path separator.  Thus when calling a function: >
+
+	:call foo#bar#func()
+
+Vim will look for the file "autoload/foo/bar.vim" in 'runtimepath'.
+
+This also works when reading a variable that has not been set yet: >
+
+	:let l = foo#bar#lvar
+
+However, when the autoload script was already loaded it won't be loaded again
+for an unknown variable.
+
+When assigning a value to such a variable nothing special happens.  This can
+be used to pass settings to the autoload script before it's loaded: >
+
+	:let foo#bar#toggle = 1
+	:call foo#bar#func()
+
+Note that when you make a mistake and call a function that is supposed to be
+defined in an autoload script, but the script doesn't actually define the
+function, the script will be sourced every time you try to call the function.
+And you will get an error message every time.
+
+Also note that if you have two script files, and one calls a function in the
+other and vise versa, before the used function is defined, it won't work.
+Avoid using the autoload functionality at the toplevel.
+
+Hint: If you distribute a bunch of scripts you can pack them together with the
+|vimball| utility.  Also read the user manual |distribute-script|.
+
+==============================================================================
+6. Curly braces names					*curly-braces-names*
+
+Wherever you can use a variable, you can use a "curly braces name" variable.
+This is a regular variable name with one or more expressions wrapped in braces
+{} like this: >
+	my_{adjective}_variable
+
+When Vim encounters this, it evaluates the expression inside the braces, puts
+that in place of the expression, and re-interprets the whole as a variable
+name.  So in the above example, if the variable "adjective" was set to
+"noisy", then the reference would be to "my_noisy_variable", whereas if
+"adjective" was set to "quiet", then it would be to "my_quiet_variable".
+
+One application for this is to create a set of variables governed by an option
+value.  For example, the statement >
+	echo my_{&background}_message
+
+would output the contents of "my_dark_message" or "my_light_message" depending
+on the current value of 'background'.
+
+You can use multiple brace pairs: >
+	echo my_{adverb}_{adjective}_message
+..or even nest them: >
+	echo my_{ad{end_of_word}}_message
+where "end_of_word" is either "verb" or "jective".
+
+However, the expression inside the braces must evaluate to a valid single
+variable name, e.g. this is invalid: >
+	:let foo='a + b'
+	:echo c{foo}d
+.. since the result of expansion is "ca + bd", which is not a variable name.
+
+						*curly-braces-function-names*
+You can call and define functions by an evaluated name in a similar way.
+Example: >
+	:let func_end='whizz'
+	:call my_func_{func_end}(parameter)
+
+This would call the function "my_func_whizz(parameter)".
+
+==============================================================================
+7. Commands						*expression-commands*
+
+:let {var-name} = {expr1}				*:let* *E18*
+			Set internal variable {var-name} to the result of the
+			expression {expr1}.  The variable will get the type
+			from the {expr}.  If {var-name} didn't exist yet, it
+			is created.
+
+:let {var-name}[{idx}] = {expr1}			*E689*
+			Set a list item to the result of the expression
+			{expr1}.  {var-name} must refer to a list and {idx}
+			must be a valid index in that list.  For nested list
+			the index can be repeated.
+			This cannot be used to add an item to a list.
+
+							*E711* *E719*
+:let {var-name}[{idx1}:{idx2}] = {expr1}		*E708* *E709* *E710*
+			Set a sequence of items in a |List| to the result of
+			the expression {expr1}, which must be a list with the
+			correct number of items.
+			{idx1} can be omitted, zero is used instead.
+			{idx2} can be omitted, meaning the end of the list.
+			When the selected range of items is partly past the
+			end of the list, items will be added.
+
+					*:let+=* *:let-=* *:let.=* *E734*
+:let {var} += {expr1}	Like ":let {var} = {var} + {expr1}".
+:let {var} -= {expr1}	Like ":let {var} = {var} - {expr1}".
+:let {var} .= {expr1}	Like ":let {var} = {var} . {expr1}".
+			These fail if {var} was not set yet and when the type
+			of {var} and {expr1} don't fit the operator.
+
+
+:let ${env-name} = {expr1}			*:let-environment* *:let-$*
+			Set environment variable {env-name} to the result of
+			the expression {expr1}.  The type is always String.
+:let ${env-name} .= {expr1}
+			Append {expr1} to the environment variable {env-name}.
+			If the environment variable didn't exist yet this
+			works like "=".
+
+:let @{reg-name} = {expr1}			*:let-register* *:let-@*
+			Write the result of the expression {expr1} in register
+			{reg-name}.  {reg-name} must be a single letter, and
+			must be the name of a writable register (see
+			|registers|).  "@@" can be used for the unnamed
+			register, "@/" for the search pattern.
+			If the result of {expr1} ends in a <CR> or <NL>, the
+			register will be linewise, otherwise it will be set to
+			characterwise.
+			This can be used to clear the last search pattern: >
+				:let @/ = ""
+<			This is different from searching for an empty string,
+			that would match everywhere.
+
+:let @{reg-name} .= {expr1}
+			Append {expr1} to register {reg-name}.  If the
+			register was empty it's like setting it to {expr1}.
+
+:let &{option-name} = {expr1}			*:let-option* *:let-&*
+			Set option {option-name} to the result of the
+			expression {expr1}.  A String or Number value is
+			always converted to the type of the option.
+			For an option local to a window or buffer the effect
+			is just like using the |:set| command: both the local
+			value and the global value are changed.
+			Example: >
+				:let &path = &path . ',/usr/local/include'
+
+:let &{option-name} .= {expr1}
+			For a string option: Append {expr1} to the value.
+			Does not insert a comma like |:set+=|.
+
+:let &{option-name} += {expr1}
+:let &{option-name} -= {expr1}
+			For a number or boolean option: Add or subtract
+			{expr1}.
+
+:let &l:{option-name} = {expr1}
+:let &l:{option-name} .= {expr1}
+:let &l:{option-name} += {expr1}
+:let &l:{option-name} -= {expr1}
+			Like above, but only set the local value of an option
+			(if there is one).  Works like |:setlocal|.
+
+:let &g:{option-name} = {expr1}
+:let &g:{option-name} .= {expr1}
+:let &g:{option-name} += {expr1}
+:let &g:{option-name} -= {expr1}
+			Like above, but only set the global value of an option
+			(if there is one).  Works like |:setglobal|.
+
+:let [{name1}, {name2}, ...] = {expr1}		*:let-unpack* *E687* *E688*
+			{expr1} must evaluate to a |List|.  The first item in
+			the list is assigned to {name1}, the second item to
+			{name2}, etc.
+			The number of names must match the number of items in
+			the |List|.
+			Each name can be one of the items of the ":let"
+			command as mentioned above.
+			Example: >
+				:let [s, item] = GetItem(s)
+<			Detail: {expr1} is evaluated first, then the
+			assignments are done in sequence.  This matters if
+			{name2} depends on {name1}.  Example: >
+				:let x = [0, 1]
+				:let i = 0
+				:let [i, x[i]] = [1, 2]
+				:echo x
+<			The result is [0, 2].
+
+:let [{name1}, {name2}, ...] .= {expr1}
+:let [{name1}, {name2}, ...] += {expr1}
+:let [{name1}, {name2}, ...] -= {expr1}
+			Like above, but append/add/subtract the value for each
+			|List| item.
+
+:let [{name}, ..., ; {lastname}] = {expr1}
+			Like |:let-unpack| above, but the |List| may have more
+			items than there are names.  A list of the remaining
+			items is assigned to {lastname}.  If there are no
+			remaining items {lastname} is set to an empty list.
+			Example: >
+				:let [a, b; rest] = ["aval", "bval", 3, 4]
+<
+:let [{name}, ..., ; {lastname}] .= {expr1}
+:let [{name}, ..., ; {lastname}] += {expr1}
+:let [{name}, ..., ; {lastname}] -= {expr1}
+			Like above, but append/add/subtract the value for each
+			|List| item.
+							*E106*
+:let {var-name}	..	List the value of variable {var-name}.  Multiple
+			variable names may be given.  Special names recognized
+			here:				*E738*
+			  g:	global variables
+			  b:	local buffer variables
+			  w:	local window variables
+			  t:	local tab page variables
+			  s:	script-local variables
+			  l:	local function variables
+			  v:	Vim variables.
+
+:let			List the values of all variables.  The type of the
+			variable is indicated before the value:
+			    <nothing>	String
+				#	Number
+				*	Funcref
+
+
+:unl[et][!] {name} ...				*:unlet* *:unl* *E108* *E795*
+			Remove the internal variable {name}.  Several variable
+			names can be given, they are all removed.  The name
+			may also be a |List| or |Dictionary| item.
+			With [!] no error message is given for non-existing
+			variables.
+			One or more items from a |List| can be removed: >
+				:unlet list[3]	  " remove fourth item
+				:unlet list[3:]   " remove fourth item to last
+<			One item from a |Dictionary| can be removed at a time: >
+				:unlet dict['two']
+				:unlet dict.two
+
+:lockv[ar][!] [depth] {name} ...			*:lockvar* *:lockv*
+			Lock the internal variable {name}.  Locking means that
+			it can no longer be changed (until it is unlocked).
+			A locked variable can be deleted: >
+				:lockvar v
+				:let v = 'asdf'		" fails!
+				:unlet v
+<							*E741*
+			If you try to change a locked variable you get an
+			error message: "E741: Value of {name} is locked"
+
+			[depth] is relevant when locking a |List| or
+			|Dictionary|.  It specifies how deep the locking goes:
+				1	Lock the |List| or |Dictionary| itself,
+					cannot add or remove items, but can
+					still change their values.
+				2	Also lock the values, cannot change
+					the items.  If an item is a |List| or
+					|Dictionary|, cannot add or remove
+					items, but can still change the
+					values.
+				3	Like 2 but for the |List| /
+					|Dictionary| in the |List| /
+					|Dictionary|, one level deeper.
+			The default [depth] is 2, thus when {name} is a |List|
+			or |Dictionary| the values cannot be changed.
+								*E743*
+			For unlimited depth use [!] and omit [depth].
+			However, there is a maximum depth of 100 to catch
+			loops.
+
+			Note that when two variables refer to the same |List|
+			and you lock one of them, the |List| will also be
+			locked when used through the other variable.
+			Example: >
+				:let l = [0, 1, 2, 3]
+				:let cl = l
+				:lockvar l
+				:let cl[1] = 99		" won't work!
+<			You may want to make a copy of a list to avoid this.
+			See |deepcopy()|.
+
+
+:unlo[ckvar][!] [depth] {name} ...			*:unlockvar* *:unlo*
+			Unlock the internal variable {name}.  Does the
+			opposite of |:lockvar|.
+
+
+:if {expr1}			*:if* *:endif* *:en* *E171* *E579* *E580*
+:en[dif]		Execute the commands until the next matching ":else"
+			or ":endif" if {expr1} evaluates to non-zero.
+
+			From Vim version 4.5 until 5.0, every Ex command in
+			between the ":if" and ":endif" is ignored.  These two
+			commands were just to allow for future expansions in a
+			backwards compatible way.  Nesting was allowed.  Note
+			that any ":else" or ":elseif" was ignored, the "else"
+			part was not executed either.
+
+			You can use this to remain compatible with older
+			versions: >
+				:if version >= 500
+				:  version-5-specific-commands
+				:endif
+<			The commands still need to be parsed to find the
+			"endif".  Sometimes an older Vim has a problem with a
+			new command.  For example, ":silent" is recognized as
+			a ":substitute" command.  In that case ":execute" can
+			avoid problems: >
+				:if version >= 600
+				:  execute "silent 1,$delete"
+				:endif
+<
+			NOTE: The ":append" and ":insert" commands don't work
+			properly in between ":if" and ":endif".
+
+						*:else* *:el* *E581* *E583*
+:el[se]			Execute the commands until the next matching ":else"
+			or ":endif" if they previously were not being
+			executed.
+
+					*:elseif* *:elsei* *E582* *E584*
+:elsei[f] {expr1}	Short for ":else" ":if", with the addition that there
+			is no extra ":endif".
+
+:wh[ile] {expr1}			*:while* *:endwhile* *:wh* *:endw*
+						*E170* *E585* *E588* *E733*
+:endw[hile]		Repeat the commands between ":while" and ":endwhile",
+			as long as {expr1} evaluates to non-zero.
+			When an error is detected from a command inside the
+			loop, execution continues after the "endwhile".
+			Example: >
+				:let lnum = 1
+				:while lnum <= line("$")
+				   :call FixLine(lnum)
+				   :let lnum = lnum + 1
+				:endwhile
+<
+			NOTE: The ":append" and ":insert" commands don't work
+			properly inside a ":while" and ":for" loop.
+
+:for {var} in {list}					*:for* *E690* *E732*
+:endfo[r]						*:endfo* *:endfor*
+			Repeat the commands between ":for" and ":endfor" for
+			each item in {list}.  Variable {var} is set to the
+			value of each item.
+			When an error is detected for a command inside the
+			loop, execution continues after the "endfor".
+			Changing {list} inside the loop affects what items are
+			used.  Make a copy if this is unwanted: >
+				:for item in copy(mylist)
+<			When not making a copy, Vim stores a reference to the
+			next item in the list, before executing the commands
+			with the current item.  Thus the current item can be
+			removed without effect.  Removing any later item means
+			it will not be found.  Thus the following example
+			works (an inefficient way to make a list empty): >
+				:for item in mylist
+				   :call remove(mylist, 0)
+				:endfor
+<			Note that reordering the list (e.g., with sort() or
+			reverse()) may have unexpected effects.
+			Note that the type of each list item should be
+			identical to avoid errors for the type of {var}
+			changing.  Unlet the variable at the end of the loop
+			to allow multiple item types.
+
+:for [{var1}, {var2}, ...] in {listlist}
+:endfo[r]
+			Like ":for" above, but each item in {listlist} must be
+			a list, of which each item is assigned to {var1},
+			{var2}, etc.  Example: >
+				:for [lnum, col] in [[1, 3], [2, 5], [3, 8]]
+				   :echo getline(lnum)[col]
+				:endfor
+<
+						*:continue* *:con* *E586*
+:con[tinue]		When used inside a ":while" or ":for" loop, jumps back
+			to the start of the loop.
+			If it is used after a |:try| inside the loop but
+			before the matching |:finally| (if present), the
+			commands following the ":finally" up to the matching
+			|:endtry| are executed first.  This process applies to
+			all nested ":try"s inside the loop.  The outermost
+			":endtry" then jumps back to the start of the loop.
+
+						*:break* *:brea* *E587*
+:brea[k]		When used inside a ":while" or ":for" loop, skips to
+			the command after the matching ":endwhile" or
+			":endfor".
+			If it is used after a |:try| inside the loop but
+			before the matching |:finally| (if present), the
+			commands following the ":finally" up to the matching
+			|:endtry| are executed first.  This process applies to
+			all nested ":try"s inside the loop.  The outermost
+			":endtry" then jumps to the command after the loop.
+
+:try				*:try* *:endt* *:endtry* *E600* *E601* *E602*
+:endt[ry]		Change the error handling for the commands between
+			":try" and ":endtry" including everything being
+			executed across ":source" commands, function calls,
+			or autocommand invocations.
+
+			When an error or interrupt is detected and there is
+			a |:finally| command following, execution continues
+			after the ":finally".  Otherwise, or when the
+			":endtry" is reached thereafter, the next
+			(dynamically) surrounding ":try" is checked for
+			a corresponding ":finally" etc.  Then the script
+			processing is terminated.  (Whether a function
+			definition has an "abort" argument does not matter.)
+			Example: >
+		:try | edit too much | finally | echo "cleanup" | endtry
+		:echo "impossible"	" not reached, script terminated above
+<
+			Moreover, an error or interrupt (dynamically) inside
+			":try" and ":endtry" is converted to an exception.  It
+			can be caught as if it were thrown by a |:throw|
+			command (see |:catch|).  In this case, the script
+			processing is not terminated.
+
+			The value "Vim:Interrupt" is used for an interrupt
+			exception.  An error in a Vim command is converted
+			to a value of the form "Vim({command}):{errmsg}",
+			other errors are converted to a value of the form
+			"Vim:{errmsg}".  {command} is the full command name,
+			and {errmsg} is the message that is displayed if the
+			error exception is not caught, always beginning with
+			the error number.
+			Examples: >
+		:try | sleep 100 | catch /^Vim:Interrupt$/ | endtry
+		:try | edit | catch /^Vim(edit):E\d\+/ | echo "error" | endtry
+<
+					*:cat* *:catch* *E603* *E604* *E605*
+:cat[ch] /{pattern}/	The following commands until the next ":catch",
+			|:finally|, or |:endtry| that belongs to the same
+			|:try| as the ":catch" are executed when an exception
+			matching {pattern} is being thrown and has not yet
+			been caught by a previous ":catch".  Otherwise, these
+			commands are skipped.
+			When {pattern} is omitted all errors are caught.
+			Examples: >
+		:catch /^Vim:Interrupt$/	" catch interrupts (CTRL-C)
+		:catch /^Vim\%((\a\+)\)\=:E/	" catch all Vim errors
+		:catch /^Vim\%((\a\+)\)\=:/	" catch errors and interrupts
+		:catch /^Vim(write):/		" catch all errors in :write
+		:catch /^Vim\%((\a\+)\)\=:E123/	" catch error E123
+		:catch /my-exception/		" catch user exception
+		:catch /.*/			" catch everything
+		:catch				" same as /.*/
+<
+			Another character can be used instead of / around the
+			{pattern}, so long as it does not have a special
+			meaning (e.g., '|' or '"') and doesn't occur inside
+			{pattern}.
+			NOTE: It is not reliable to ":catch" the TEXT of
+			an error message because it may vary in different
+			locales.
+
+					*:fina* *:finally* *E606* *E607*
+:fina[lly]		The following commands until the matching |:endtry|
+			are executed whenever the part between the matching
+			|:try| and the ":finally" is left:  either by falling
+			through to the ":finally" or by a |:continue|,
+			|:break|, |:finish|, or |:return|, or by an error or
+			interrupt or exception (see |:throw|).
+
+							*:th* *:throw* *E608*
+:th[row] {expr1}	The {expr1} is evaluated and thrown as an exception.
+			If the ":throw" is used after a |:try| but before the
+			first corresponding |:catch|, commands are skipped
+			until the first ":catch" matching {expr1} is reached.
+			If there is no such ":catch" or if the ":throw" is
+			used after a ":catch" but before the |:finally|, the
+			commands following the ":finally" (if present) up to
+			the matching |:endtry| are executed.  If the ":throw"
+			is after the ":finally", commands up to the ":endtry"
+			are skipped.  At the ":endtry", this process applies
+			again for the next dynamically surrounding ":try"
+			(which may be found in a calling function or sourcing
+			script), until a matching ":catch" has been found.
+			If the exception is not caught, the command processing
+			is terminated.
+			Example: >
+		:try | throw "oops" | catch /^oo/ | echo "caught" | endtry
+<
+
+							*:ec* *:echo*
+:ec[ho] {expr1} ..	Echoes each {expr1}, with a space in between.  The
+			first {expr1} starts on a new line.
+			Also see |:comment|.
+			Use "\n" to start a new line.  Use "\r" to move the
+			cursor to the first column.
+			Uses the highlighting set by the |:echohl| command.
+			Cannot be followed by a comment.
+			Example: >
+		:echo "the value of 'shell' is" &shell
+<							*:echo-redraw*
+			A later redraw may make the message disappear again.
+			And since Vim mostly postpones redrawing until it's
+			finished with a sequence of commands this happens
+			quite often.  To avoid that a command from before the
+			":echo" causes a redraw afterwards (redraws are often
+			postponed until you type something), force a redraw
+			with the |:redraw| command.  Example: >
+		:new | redraw | echo "there is a new window"
+<
+							*:echon*
+:echon {expr1} ..	Echoes each {expr1}, without anything added.  Also see
+			|:comment|.
+			Uses the highlighting set by the |:echohl| command.
+			Cannot be followed by a comment.
+			Example: >
+				:echon "the value of 'shell' is " &shell
+<
+			Note the difference between using ":echo", which is a
+			Vim command, and ":!echo", which is an external shell
+			command: >
+		:!echo %		--> filename
+<			The arguments of ":!" are expanded, see |:_%|. >
+		:!echo "%"		--> filename or "filename"
+<			Like the previous example.  Whether you see the double
+			quotes or not depends on your 'shell'. >
+		:echo %			--> nothing
+<			The '%' is an illegal character in an expression. >
+		:echo "%"		--> %
+<			This just echoes the '%' character. >
+		:echo expand("%")	--> filename
+<			This calls the expand() function to expand the '%'.
+
+							*:echoh* *:echohl*
+:echoh[l] {name}	Use the highlight group {name} for the following
+			|:echo|, |:echon| and |:echomsg| commands.  Also used
+			for the |input()| prompt.  Example: >
+		:echohl WarningMsg | echo "Don't panic!" | echohl None
+<			Don't forget to set the group back to "None",
+			otherwise all following echo's will be highlighted.
+
+							*:echom* *:echomsg*
+:echom[sg] {expr1} ..	Echo the expression(s) as a true message, saving the
+			message in the |message-history|.
+			Spaces are placed between the arguments as with the
+			|:echo| command.  But unprintable characters are
+			displayed, not interpreted.
+			The parsing works slightly different from |:echo|,
+			more like |:execute|.  All the expressions are first
+			evaluated and concatenated before echoing anything.
+			The expressions must evaluate to a Number or String, a
+			Dictionary or List causes an error.
+			Uses the highlighting set by the |:echohl| command.
+			Example: >
+		:echomsg "It's a Zizzer Zazzer Zuzz, as you can plainly see."
+<			See |:echo-redraw| to avoid the message disappearing
+			when the screen is redrawn.
+							*:echoe* *:echoerr*
+:echoe[rr] {expr1} ..	Echo the expression(s) as an error message, saving the
+			message in the |message-history|.  When used in a
+			script or function the line number will be added.
+			Spaces are placed between the arguments as with the
+			:echo command.  When used inside a try conditional,
+			the message is raised as an error exception instead
+			(see |try-echoerr|).
+			Example: >
+		:echoerr "This script just failed!"
+<			If you just want a highlighted message use |:echohl|.
+			And to get a beep: >
+		:exe "normal \<Esc>"
+<
+							*:exe* *:execute*
+:exe[cute] {expr1} ..	Executes the string that results from the evaluation
+			of {expr1} as an Ex command.  Multiple arguments are
+			concatenated, with a space in between.  {expr1} is
+			used as the processed command, command line editing
+			keys are not recognized.
+			Cannot be followed by a comment.
+			Examples: >
+		:execute "buffer " nextbuf
+		:execute "normal " count . "w"
+<
+			":execute" can be used to append a command to commands
+			that don't accept a '|'.  Example: >
+		:execute '!ls' | echo "theend"
+
+<			":execute" is also a nice way to avoid having to type
+			control characters in a Vim script for a ":normal"
+			command: >
+		:execute "normal ixxx\<Esc>"
+<			This has an <Esc> character, see |expr-string|.
+
+			Note: The executed string may be any command-line, but
+			you cannot start or end a "while", "for" or "if"
+			command.  Thus this is illegal: >
+		:execute 'while i > 5'
+		:execute 'echo "test" | break'
+<
+			It is allowed to have a "while" or "if" command
+			completely in the executed string: >
+		:execute 'while i < 5 | echo i | let i = i + 1 | endwhile'
+<
+
+							*:comment*
+			":execute", ":echo" and ":echon" cannot be followed by
+			a comment directly, because they see the '"' as the
+			start of a string.  But, you can use '|' followed by a
+			comment.  Example: >
+		:echo "foo" | "this is a comment
+
+==============================================================================
+8. Exception handling					*exception-handling*
+
+The Vim script language comprises an exception handling feature.  This section
+explains how it can be used in a Vim script.
+
+Exceptions may be raised by Vim on an error or on interrupt, see
+|catch-errors| and |catch-interrupt|.  You can also explicitly throw an
+exception by using the ":throw" command, see |throw-catch|.
+
+
+TRY CONDITIONALS					*try-conditionals*
+
+Exceptions can be caught or can cause cleanup code to be executed.  You can
+use a try conditional to specify catch clauses (that catch exceptions) and/or
+a finally clause (to be executed for cleanup).
+   A try conditional begins with a |:try| command and ends at the matching
+|:endtry| command.  In between, you can use a |:catch| command to start
+a catch clause, or a |:finally| command to start a finally clause.  There may
+be none or multiple catch clauses, but there is at most one finally clause,
+which must not be followed by any catch clauses.  The lines before the catch
+clauses and the finally clause is called a try block. >
+
+     :try
+     :  ...
+     :  ...				TRY BLOCK
+     :  ...
+     :catch /{pattern}/
+     :  ...
+     :  ...				CATCH CLAUSE
+     :  ...
+     :catch /{pattern}/
+     :  ...
+     :  ...				CATCH CLAUSE
+     :  ...
+     :finally
+     :  ...
+     :  ...				FINALLY CLAUSE
+     :  ...
+     :endtry
+
+The try conditional allows to watch code for exceptions and to take the
+appropriate actions.  Exceptions from the try block may be caught.  Exceptions
+from the try block and also the catch clauses may cause cleanup actions.
+   When no exception is thrown during execution of the try block, the control
+is transferred to the finally clause, if present.  After its execution, the
+script continues with the line following the ":endtry".
+   When an exception occurs during execution of the try block, the remaining
+lines in the try block are skipped.  The exception is matched against the
+patterns specified as arguments to the ":catch" commands.  The catch clause
+after the first matching ":catch" is taken, other catch clauses are not
+executed.  The catch clause ends when the next ":catch", ":finally", or
+":endtry" command is reached - whatever is first.  Then, the finally clause
+(if present) is executed.  When the ":endtry" is reached, the script execution
+continues in the following line as usual.
+   When an exception that does not match any of the patterns specified by the
+":catch" commands is thrown in the try block, the exception is not caught by
+that try conditional and none of the catch clauses is executed.  Only the
+finally clause, if present, is taken.  The exception pends during execution of
+the finally clause.  It is resumed at the ":endtry", so that commands after
+the ":endtry" are not executed and the exception might be caught elsewhere,
+see |try-nesting|.
+   When during execution of a catch clause another exception is thrown, the
+remaining lines in that catch clause are not executed.  The new exception is
+not matched against the patterns in any of the ":catch" commands of the same
+try conditional and none of its catch clauses is taken.  If there is, however,
+a finally clause, it is executed, and the exception pends during its
+execution.  The commands following the ":endtry" are not executed.  The new
+exception might, however, be caught elsewhere, see |try-nesting|.
+   When during execution of the finally clause (if present) an exception is
+thrown, the remaining lines in the finally clause are skipped.  If the finally
+clause has been taken because of an exception from the try block or one of the
+catch clauses, the original (pending) exception is discarded.  The commands
+following the ":endtry" are not executed, and the exception from the finally
+clause is propagated and can be caught elsewhere, see |try-nesting|.
+
+The finally clause is also executed, when a ":break" or ":continue" for
+a ":while" loop enclosing the complete try conditional is executed from the
+try block or a catch clause.  Or when a ":return" or ":finish" is executed
+from the try block or a catch clause of a try conditional in a function or
+sourced script, respectively.  The ":break", ":continue", ":return", or
+":finish" pends during execution of the finally clause and is resumed when the
+":endtry" is reached.  It is, however, discarded when an exception is thrown
+from the finally clause.
+   When a ":break" or ":continue" for a ":while" loop enclosing the complete
+try conditional or when a ":return" or ":finish" is encountered in the finally
+clause, the rest of the finally clause is skipped, and the ":break",
+":continue", ":return" or ":finish" is executed as usual.  If the finally
+clause has been taken because of an exception or an earlier ":break",
+":continue", ":return", or ":finish" from the try block or a catch clause,
+this pending exception or command is discarded.
+
+For examples see |throw-catch| and |try-finally|.
+
+
+NESTING	OF TRY CONDITIONALS				*try-nesting*
+
+Try conditionals can be nested arbitrarily.  That is, a complete try
+conditional can be put into the try block, a catch clause, or the finally
+clause of another try conditional.  If the inner try conditional does not
+catch an exception thrown in its try block or throws a new exception from one
+of its catch clauses or its finally clause, the outer try conditional is
+checked according to the rules above.  If the inner try conditional is in the
+try block of the outer try conditional, its catch clauses are checked, but
+otherwise only the finally clause is executed.  It does not matter for
+nesting, whether the inner try conditional is directly contained in the outer
+one, or whether the outer one sources a script or calls a function containing
+the inner try conditional.
+
+When none of the active try conditionals catches an exception, just their
+finally clauses are executed.  Thereafter, the script processing terminates.
+An error message is displayed in case of an uncaught exception explicitly
+thrown by a ":throw" command.  For uncaught error and interrupt exceptions
+implicitly raised by Vim, the error message(s) or interrupt message are shown
+as usual.
+
+For examples see |throw-catch|.
+
+
+EXAMINING EXCEPTION HANDLING CODE			*except-examine*
+
+Exception handling code can get tricky.  If you are in doubt what happens, set
+'verbose' to 13 or use the ":13verbose" command modifier when sourcing your
+script file.  Then you see when an exception is thrown, discarded, caught, or
+finished.  When using a verbosity level of at least 14, things pending in
+a finally clause are also shown.  This information is also given in debug mode
+(see |debug-scripts|).
+
+
+THROWING AND CATCHING EXCEPTIONS			*throw-catch*
+
+You can throw any number or string as an exception.  Use the |:throw| command
+and pass the value to be thrown as argument: >
+	:throw 4711
+	:throw "string"
+<							*throw-expression*
+You can also specify an expression argument.  The expression is then evaluated
+first, and the result is thrown: >
+	:throw 4705 + strlen("string")
+	:throw strpart("strings", 0, 6)
+
+An exception might be thrown during evaluation of the argument of the ":throw"
+command.  Unless it is caught there, the expression evaluation is abandoned.
+The ":throw" command then does not throw a new exception.
+   Example: >
+
+	:function! Foo(arg)
+	:  try
+	:    throw a:arg
+	:  catch /foo/
+	:  endtry
+	:  return 1
+	:endfunction
+	:
+	:function! Bar()
+	:  echo "in Bar"
+	:  return 4710
+	:endfunction
+	:
+	:throw Foo("arrgh") + Bar()
+
+This throws "arrgh", and "in Bar" is not displayed since Bar() is not
+executed. >
+	:throw Foo("foo") + Bar()
+however displays "in Bar" and throws 4711.
+
+Any other command that takes an expression as argument might also be
+abandoned by an (uncaught) exception during the expression evaluation.  The
+exception is then propagated to the caller of the command.
+   Example: >
+
+	:if Foo("arrgh")
+	:  echo "then"
+	:else
+	:  echo "else"
+	:endif
+
+Here neither of "then" or "else" is displayed.
+
+							*catch-order*
+Exceptions can be caught by a try conditional with one or more |:catch|
+commands, see |try-conditionals|.   The values to be caught by each ":catch"
+command can be specified as a pattern argument.  The subsequent catch clause
+gets executed when a matching exception is caught.
+   Example: >
+
+	:function! Foo(value)
+	:  try
+	:    throw a:value
+	:  catch /^\d\+$/
+	:    echo "Number thrown"
+	:  catch /.*/
+	:    echo "String thrown"
+	:  endtry
+	:endfunction
+	:
+	:call Foo(0x1267)
+	:call Foo('string')
+
+The first call to Foo() displays "Number thrown", the second "String thrown".
+An exception is matched against the ":catch" commands in the order they are
+specified.  Only the first match counts.  So you should place the more
+specific ":catch" first.  The following order does not make sense: >
+
+	:  catch /.*/
+	:    echo "String thrown"
+	:  catch /^\d\+$/
+	:    echo "Number thrown"
+
+The first ":catch" here matches always, so that the second catch clause is
+never taken.
+
+							*throw-variables*
+If you catch an exception by a general pattern, you may access the exact value
+in the variable |v:exception|: >
+
+	:  catch /^\d\+$/
+	:    echo "Number thrown.  Value is" v:exception
+
+You may also be interested where an exception was thrown.  This is stored in
+|v:throwpoint|.  Note that "v:exception" and "v:throwpoint" are valid for the
+exception most recently caught as long it is not finished.
+   Example: >
+
+	:function! Caught()
+	:  if v:exception != ""
+	:    echo 'Caught "' . v:exception . '" in ' . v:throwpoint
+	:  else
+	:    echo 'Nothing caught'
+	:  endif
+	:endfunction
+	:
+	:function! Foo()
+	:  try
+	:    try
+	:      try
+	:	 throw 4711
+	:      finally
+	:	 call Caught()
+	:      endtry
+	:    catch /.*/
+	:      call Caught()
+	:      throw "oops"
+	:    endtry
+	:  catch /.*/
+	:    call Caught()
+	:  finally
+	:    call Caught()
+	:  endtry
+	:endfunction
+	:
+	:call Foo()
+
+This displays >
+
+	Nothing caught
+	Caught "4711" in function Foo, line 4
+	Caught "oops" in function Foo, line 10
+	Nothing caught
+
+A practical example:  The following command ":LineNumber" displays the line
+number in the script or function where it has been used: >
+
+	:function! LineNumber()
+	:    return substitute(v:throwpoint, '.*\D\(\d\+\).*', '\1', "")
+	:endfunction
+	:command! LineNumber try | throw "" | catch | echo LineNumber() | endtry
+<
+							*try-nested*
+An exception that is not caught by a try conditional can be caught by
+a surrounding try conditional: >
+
+	:try
+	:  try
+	:    throw "foo"
+	:  catch /foobar/
+	:    echo "foobar"
+	:  finally
+	:    echo "inner finally"
+	:  endtry
+	:catch /foo/
+	:  echo "foo"
+	:endtry
+
+The inner try conditional does not catch the exception, just its finally
+clause is executed.  The exception is then caught by the outer try
+conditional.  The example displays "inner finally" and then "foo".
+
+							*throw-from-catch*
+You can catch an exception and throw a new one to be caught elsewhere from the
+catch clause: >
+
+	:function! Foo()
+	:  throw "foo"
+	:endfunction
+	:
+	:function! Bar()
+	:  try
+	:    call Foo()
+	:  catch /foo/
+	:    echo "Caught foo, throw bar"
+	:    throw "bar"
+	:  endtry
+	:endfunction
+	:
+	:try
+	:  call Bar()
+	:catch /.*/
+	:  echo "Caught" v:exception
+	:endtry
+
+This displays "Caught foo, throw bar" and then "Caught bar".
+
+							*rethrow*
+There is no real rethrow in the Vim script language, but you may throw
+"v:exception" instead: >
+
+	:function! Bar()
+	:  try
+	:    call Foo()
+	:  catch /.*/
+	:    echo "Rethrow" v:exception
+	:    throw v:exception
+	:  endtry
+	:endfunction
+<							*try-echoerr*
+Note that this method cannot be used to "rethrow" Vim error or interrupt
+exceptions, because it is not possible to fake Vim internal exceptions.
+Trying so causes an error exception.  You should throw your own exception
+denoting the situation.  If you want to cause a Vim error exception containing
+the original error exception value, you can use the |:echoerr| command: >
+
+	:try
+	:  try
+	:    asdf
+	:  catch /.*/
+	:    echoerr v:exception
+	:  endtry
+	:catch /.*/
+	:  echo v:exception
+	:endtry
+
+This code displays
+
+	Vim(echoerr):Vim:E492: Not an editor command:   asdf ~
+
+
+CLEANUP CODE						*try-finally*
+
+Scripts often change global settings and restore them at their end.  If the
+user however interrupts the script by pressing CTRL-C, the settings remain in
+an inconsistent state.  The same may happen to you in the development phase of
+a script when an error occurs or you explicitly throw an exception without
+catching it.  You can solve these problems by using a try conditional with
+a finally clause for restoring the settings.  Its execution is guaranteed on
+normal control flow, on error, on an explicit ":throw", and on interrupt.
+(Note that errors and interrupts from inside the try conditional are converted
+to exceptions.  When not caught, they terminate the script after the finally
+clause has been executed.)
+Example: >
+
+	:try
+	:  let s:saved_ts = &ts
+	:  set ts=17
+	:
+	:  " Do the hard work here.
+	:
+	:finally
+	:  let &ts = s:saved_ts
+	:  unlet s:saved_ts
+	:endtry
+
+This method should be used locally whenever a function or part of a script
+changes global settings which need to be restored on failure or normal exit of
+that function or script part.
+
+							*break-finally*
+Cleanup code works also when the try block or a catch clause is left by
+a ":continue", ":break", ":return", or ":finish".
+   Example: >
+
+	:let first = 1
+	:while 1
+	:  try
+	:    if first
+	:      echo "first"
+	:      let first = 0
+	:      continue
+	:    else
+	:      throw "second"
+	:    endif
+	:  catch /.*/
+	:    echo v:exception
+	:    break
+	:  finally
+	:    echo "cleanup"
+	:  endtry
+	:  echo "still in while"
+	:endwhile
+	:echo "end"
+
+This displays "first", "cleanup", "second", "cleanup", and "end". >
+
+	:function! Foo()
+	:  try
+	:    return 4711
+	:  finally
+	:    echo "cleanup\n"
+	:  endtry
+	:  echo "Foo still active"
+	:endfunction
+	:
+	:echo Foo() "returned by Foo"
+
+This displays "cleanup" and "4711 returned by Foo".  You don't need to add an
+extra ":return" in the finally clause.  (Above all, this would override the
+return value.)
+
+							*except-from-finally*
+Using either of ":continue", ":break", ":return", ":finish", or ":throw" in
+a finally clause is possible, but not recommended since it abandons the
+cleanup actions for the try conditional.  But, of course, interrupt and error
+exceptions might get raised from a finally clause.
+   Example where an error in the finally clause stops an interrupt from
+working correctly: >
+
+	:try
+	:  try
+	:    echo "Press CTRL-C for interrupt"
+	:    while 1
+	:    endwhile
+	:  finally
+	:    unlet novar
+	:  endtry
+	:catch /novar/
+	:endtry
+	:echo "Script still running"
+	:sleep 1
+
+If you need to put commands that could fail into a finally clause, you should
+think about catching or ignoring the errors in these commands, see
+|catch-errors| and |ignore-errors|.
+
+
+CATCHING ERRORS						*catch-errors*
+
+If you want to catch specific errors, you just have to put the code to be
+watched in a try block and add a catch clause for the error message.  The
+presence of the try conditional causes all errors to be converted to an
+exception.  No message is displayed and |v:errmsg| is not set then.  To find
+the right pattern for the ":catch" command, you have to know how the format of
+the error exception is.
+   Error exceptions have the following format: >
+
+	Vim({cmdname}):{errmsg}
+or >
+	Vim:{errmsg}
+
+{cmdname} is the name of the command that failed; the second form is used when
+the command name is not known.  {errmsg} is the error message usually produced
+when the error occurs outside try conditionals.  It always begins with
+a capital "E", followed by a two or three-digit error number, a colon, and
+a space.
+
+Examples:
+
+The command >
+	:unlet novar
+normally produces the error message >
+	E108: No such variable: "novar"
+which is converted inside try conditionals to an exception >
+	Vim(unlet):E108: No such variable: "novar"
+
+The command >
+	:dwim
+normally produces the error message >
+	E492: Not an editor command: dwim
+which is converted inside try conditionals to an exception >
+	Vim:E492: Not an editor command: dwim
+
+You can catch all ":unlet" errors by a >
+	:catch /^Vim(unlet):/
+or all errors for misspelled command names by a >
+	:catch /^Vim:E492:/
+
+Some error messages may be produced by different commands: >
+	:function nofunc
+and >
+	:delfunction nofunc
+both produce the error message >
+	E128: Function name must start with a capital: nofunc
+which is converted inside try conditionals to an exception >
+	Vim(function):E128: Function name must start with a capital: nofunc
+or >
+	Vim(delfunction):E128: Function name must start with a capital: nofunc
+respectively.  You can catch the error by its number independently on the
+command that caused it if you use the following pattern: >
+	:catch /^Vim(\a\+):E128:/
+
+Some commands like >
+	:let x = novar
+produce multiple error messages, here: >
+	E121: Undefined variable: novar
+	E15: Invalid expression:  novar
+Only the first is used for the exception value, since it is the most specific
+one (see |except-several-errors|).  So you can catch it by >
+	:catch /^Vim(\a\+):E121:/
+
+You can catch all errors related to the name "nofunc" by >
+	:catch /\<nofunc\>/
+
+You can catch all Vim errors in the ":write" and ":read" commands by >
+	:catch /^Vim(\(write\|read\)):E\d\+:/
+
+You can catch all Vim errors by the pattern >
+	:catch /^Vim\((\a\+)\)\=:E\d\+:/
+<
+							*catch-text*
+NOTE: You should never catch the error message text itself: >
+	:catch /No such variable/
+only works in the english locale, but not when the user has selected
+a different language by the |:language| command.  It is however helpful to
+cite the message text in a comment: >
+	:catch /^Vim(\a\+):E108:/   " No such variable
+
+
+IGNORING ERRORS						*ignore-errors*
+
+You can ignore errors in a specific Vim command by catching them locally: >
+
+	:try
+	:  write
+	:catch
+	:endtry
+
+But you are strongly recommended NOT to use this simple form, since it could
+catch more than you want.  With the ":write" command, some autocommands could
+be executed and cause errors not related to writing, for instance: >
+
+	:au BufWritePre * unlet novar
+
+There could even be such errors you are not responsible for as a script
+writer: a user of your script might have defined such autocommands.  You would
+then hide the error from the user.
+   It is much better to use >
+
+	:try
+	:  write
+	:catch /^Vim(write):/
+	:endtry
+
+which only catches real write errors.  So catch only what you'd like to ignore
+intentionally.
+
+For a single command that does not cause execution of autocommands, you could
+even suppress the conversion of errors to exceptions by the ":silent!"
+command: >
+	:silent! nunmap k
+This works also when a try conditional is active.
+
+
+CATCHING INTERRUPTS					*catch-interrupt*
+
+When there are active try conditionals, an interrupt (CTRL-C) is converted to
+the exception "Vim:Interrupt".  You can catch it like every exception.  The
+script is not terminated, then.
+   Example: >
+
+	:function! TASK1()
+	:  sleep 10
+	:endfunction
+
+	:function! TASK2()
+	:  sleep 20
+	:endfunction
+
+	:while 1
+	:  let command = input("Type a command: ")
+	:  try
+	:    if command == ""
+	:      continue
+	:    elseif command == "END"
+	:      break
+	:    elseif command == "TASK1"
+	:      call TASK1()
+	:    elseif command == "TASK2"
+	:      call TASK2()
+	:    else
+	:      echo "\nIllegal command:" command
+	:      continue
+	:    endif
+	:  catch /^Vim:Interrupt$/
+	:    echo "\nCommand interrupted"
+	:    " Caught the interrupt.  Continue with next prompt.
+	:  endtry
+	:endwhile
+
+You can interrupt a task here by pressing CTRL-C; the script then asks for
+a new command.  If you press CTRL-C at the prompt, the script is terminated.
+
+For testing what happens when CTRL-C would be pressed on a specific line in
+your script, use the debug mode and execute the |>quit| or |>interrupt|
+command on that line.  See |debug-scripts|.
+
+
+CATCHING ALL						*catch-all*
+
+The commands >
+
+	:catch /.*/
+	:catch //
+	:catch
+
+catch everything, error exceptions, interrupt exceptions and exceptions
+explicitly thrown by the |:throw| command.  This is useful at the top level of
+a script in order to catch unexpected things.
+   Example: >
+
+	:try
+	:
+	:  " do the hard work here
+	:
+	:catch /MyException/
+	:
+	:  " handle known problem
+	:
+	:catch /^Vim:Interrupt$/
+	:    echo "Script interrupted"
+	:catch /.*/
+	:  echo "Internal error (" . v:exception . ")"
+	:  echo " - occurred at " . v:throwpoint
+	:endtry
+	:" end of script
+
+Note: Catching all might catch more things than you want.  Thus, you are
+strongly encouraged to catch only for problems that you can really handle by
+specifying a pattern argument to the ":catch".
+   Example: Catching all could make it nearly impossible to interrupt a script
+by pressing CTRL-C: >
+
+	:while 1
+	:  try
+	:    sleep 1
+	:  catch
+	:  endtry
+	:endwhile
+
+
+EXCEPTIONS AND AUTOCOMMANDS				*except-autocmd*
+
+Exceptions may be used during execution of autocommands.  Example: >
+
+	:autocmd User x try
+	:autocmd User x   throw "Oops!"
+	:autocmd User x catch
+	:autocmd User x   echo v:exception
+	:autocmd User x endtry
+	:autocmd User x throw "Arrgh!"
+	:autocmd User x echo "Should not be displayed"
+	:
+	:try
+	:  doautocmd User x
+	:catch
+	:  echo v:exception
+	:endtry
+
+This displays "Oops!" and "Arrgh!".
+
+							*except-autocmd-Pre*
+For some commands, autocommands get executed before the main action of the
+command takes place.  If an exception is thrown and not caught in the sequence
+of autocommands, the sequence and the command that caused its execution are
+abandoned and the exception is propagated to the caller of the command.
+   Example: >
+
+	:autocmd BufWritePre * throw "FAIL"
+	:autocmd BufWritePre * echo "Should not be displayed"
+	:
+	:try
+	:  write
+	:catch
+	:  echo "Caught:" v:exception "from" v:throwpoint
+	:endtry
+
+Here, the ":write" command does not write the file currently being edited (as
+you can see by checking 'modified'), since the exception from the BufWritePre
+autocommand abandons the ":write".  The exception is then caught and the
+script displays: >
+
+	Caught: FAIL from BufWrite Auto commands for "*"
+<
+							*except-autocmd-Post*
+For some commands, autocommands get executed after the main action of the
+command has taken place.  If this main action fails and the command is inside
+an active try conditional, the autocommands are skipped and an error exception
+is thrown that can be caught by the caller of the command.
+   Example: >
+
+	:autocmd BufWritePost * echo "File successfully written!"
+	:
+	:try
+	:  write /i/m/p/o/s/s/i/b/l/e
+	:catch
+	:  echo v:exception
+	:endtry
+
+This just displays: >
+
+	Vim(write):E212: Can't open file for writing (/i/m/p/o/s/s/i/b/l/e)
+
+If you really need to execute the autocommands even when the main action
+fails, trigger the event from the catch clause.
+   Example: >
+
+	:autocmd BufWritePre  * set noreadonly
+	:autocmd BufWritePost * set readonly
+	:
+	:try
+	:  write /i/m/p/o/s/s/i/b/l/e
+	:catch
+	:  doautocmd BufWritePost /i/m/p/o/s/s/i/b/l/e
+	:endtry
+<
+You can also use ":silent!": >
+
+	:let x = "ok"
+	:let v:errmsg = ""
+	:autocmd BufWritePost * if v:errmsg != ""
+	:autocmd BufWritePost *   let x = "after fail"
+	:autocmd BufWritePost * endif
+	:try
+	:  silent! write /i/m/p/o/s/s/i/b/l/e
+	:catch
+	:endtry
+	:echo x
+
+This displays "after fail".
+
+If the main action of the command does not fail, exceptions from the
+autocommands will be catchable by the caller of the command:  >
+
+	:autocmd BufWritePost * throw ":-("
+	:autocmd BufWritePost * echo "Should not be displayed"
+	:
+	:try
+	:  write
+	:catch
+	:  echo v:exception
+	:endtry
+<
+							*except-autocmd-Cmd*
+For some commands, the normal action can be replaced by a sequence of
+autocommands.  Exceptions from that sequence will be catchable by the caller
+of the command.
+   Example:  For the ":write" command, the caller cannot know whether the file
+had actually been written when the exception occurred.  You need to tell it in
+some way. >
+
+	:if !exists("cnt")
+	:  let cnt = 0
+	:
+	:  autocmd BufWriteCmd * if &modified
+	:  autocmd BufWriteCmd *   let cnt = cnt + 1
+	:  autocmd BufWriteCmd *   if cnt % 3 == 2
+	:  autocmd BufWriteCmd *     throw "BufWriteCmdError"
+	:  autocmd BufWriteCmd *   endif
+	:  autocmd BufWriteCmd *   write | set nomodified
+	:  autocmd BufWriteCmd *   if cnt % 3 == 0
+	:  autocmd BufWriteCmd *     throw "BufWriteCmdError"
+	:  autocmd BufWriteCmd *   endif
+	:  autocmd BufWriteCmd *   echo "File successfully written!"
+	:  autocmd BufWriteCmd * endif
+	:endif
+	:
+	:try
+	:	write
+	:catch /^BufWriteCmdError$/
+	:  if &modified
+	:    echo "Error on writing (file contents not changed)"
+	:  else
+	:    echo "Error after writing"
+	:  endif
+	:catch /^Vim(write):/
+	:    echo "Error on writing"
+	:endtry
+
+When this script is sourced several times after making changes, it displays
+first >
+	File successfully written!
+then >
+	Error on writing (file contents not changed)
+then >
+	Error after writing
+etc.
+
+							*except-autocmd-ill*
+You cannot spread a try conditional over autocommands for different events.
+The following code is ill-formed: >
+
+	:autocmd BufWritePre  * try
+	:
+	:autocmd BufWritePost * catch
+	:autocmd BufWritePost *   echo v:exception
+	:autocmd BufWritePost * endtry
+	:
+	:write
+
+
+EXCEPTION HIERARCHIES AND PARAMETERIZED EXCEPTIONS	*except-hier-param*
+
+Some programming languages allow to use hierarchies of exception classes or to
+pass additional information with the object of an exception class.  You can do
+similar things in Vim.
+   In order to throw an exception from a hierarchy, just throw the complete
+class name with the components separated by a colon, for instance throw the
+string "EXCEPT:MATHERR:OVERFLOW" for an overflow in a mathematical library.
+   When you want to pass additional information with your exception class, add
+it in parentheses, for instance throw the string "EXCEPT:IO:WRITEERR(myfile)"
+for an error when writing "myfile".
+   With the appropriate patterns in the ":catch" command, you can catch for
+base classes or derived classes of your hierarchy.  Additional information in
+parentheses can be cut out from |v:exception| with the ":substitute" command.
+   Example: >
+
+	:function! CheckRange(a, func)
+	:  if a:a < 0
+	:    throw "EXCEPT:MATHERR:RANGE(" . a:func . ")"
+	:  endif
+	:endfunction
+	:
+	:function! Add(a, b)
+	:  call CheckRange(a:a, "Add")
+	:  call CheckRange(a:b, "Add")
+	:  let c = a:a + a:b
+	:  if c < 0
+	:    throw "EXCEPT:MATHERR:OVERFLOW"
+	:  endif
+	:  return c
+	:endfunction
+	:
+	:function! Div(a, b)
+	:  call CheckRange(a:a, "Div")
+	:  call CheckRange(a:b, "Div")
+	:  if (a:b == 0)
+	:    throw "EXCEPT:MATHERR:ZERODIV"
+	:  endif
+	:  return a:a / a:b
+	:endfunction
+	:
+	:function! Write(file)
+	:  try
+	:    execute "write" a:file
+	:  catch /^Vim(write):/
+	:    throw "EXCEPT:IO(" . getcwd() . ", " . a:file . "):WRITEERR"
+	:  endtry
+	:endfunction
+	:
+	:try
+	:
+	:  " something with arithmetics and I/O
+	:
+	:catch /^EXCEPT:MATHERR:RANGE/
+	:  let function = substitute(v:exception, '.*(\(\a\+\)).*', '\1', "")
+	:  echo "Range error in" function
+	:
+	:catch /^EXCEPT:MATHERR/	" catches OVERFLOW and ZERODIV
+	:  echo "Math error"
+	:
+	:catch /^EXCEPT:IO/
+	:  let dir = substitute(v:exception, '.*(\(.\+\),\s*.\+).*', '\1', "")
+	:  let file = substitute(v:exception, '.*(.\+,\s*\(.\+\)).*', '\1', "")
+	:  if file !~ '^/'
+	:    let file = dir . "/" . file
+	:  endif
+	:  echo 'I/O error for "' . file . '"'
+	:
+	:catch /^EXCEPT/
+	:  echo "Unspecified error"
+	:
+	:endtry
+
+The exceptions raised by Vim itself (on error or when pressing CTRL-C) use
+a flat hierarchy:  they are all in the "Vim" class.  You cannot throw yourself
+exceptions with the "Vim" prefix; they are reserved for Vim.
+   Vim error exceptions are parameterized with the name of the command that
+failed, if known.  See |catch-errors|.
+
+
+PECULIARITIES
+							*except-compat*
+The exception handling concept requires that the command sequence causing the
+exception is aborted immediately and control is transferred to finally clauses
+and/or a catch clause.
+
+In the Vim script language there are cases where scripts and functions
+continue after an error: in functions without the "abort" flag or in a command
+after ":silent!", control flow goes to the following line, and outside
+functions, control flow goes to the line following the outermost ":endwhile"
+or ":endif".  On the other hand, errors should be catchable as exceptions
+(thus, requiring the immediate abortion).
+
+This problem has been solved by converting errors to exceptions and using
+immediate abortion (if not suppressed by ":silent!") only when a try
+conditional is active.  This is no restriction since an (error) exception can
+be caught only from an active try conditional.  If you want an immediate
+termination without catching the error, just use a try conditional without
+catch clause.  (You can cause cleanup code being executed before termination
+by specifying a finally clause.)
+
+When no try conditional is active, the usual abortion and continuation
+behavior is used instead of immediate abortion.  This ensures compatibility of
+scripts written for Vim 6.1 and earlier.
+
+However, when sourcing an existing script that does not use exception handling
+commands (or when calling one of its functions) from inside an active try
+conditional of a new script, you might change the control flow of the existing
+script on error.  You get the immediate abortion on error and can catch the
+error in the new script.  If however the sourced script suppresses error
+messages by using the ":silent!" command (checking for errors by testing
+|v:errmsg| if appropriate), its execution path is not changed.  The error is
+not converted to an exception.  (See |:silent|.)  So the only remaining cause
+where this happens is for scripts that don't care about errors and produce
+error messages.  You probably won't want to use such code from your new
+scripts.
+
+							*except-syntax-err*
+Syntax errors in the exception handling commands are never caught by any of
+the ":catch" commands of the try conditional they belong to.  Its finally
+clauses, however, is executed.
+   Example: >
+
+	:try
+	:  try
+	:    throw 4711
+	:  catch /\(/
+	:    echo "in catch with syntax error"
+	:  catch
+	:    echo "inner catch-all"
+	:  finally
+	:    echo "inner finally"
+	:  endtry
+	:catch
+	:  echo 'outer catch-all caught "' . v:exception . '"'
+	:  finally
+	:    echo "outer finally"
+	:endtry
+
+This displays: >
+    inner finally
+    outer catch-all caught "Vim(catch):E54: Unmatched \("
+    outer finally
+The original exception is discarded and an error exception is raised, instead.
+
+							*except-single-line*
+The ":try", ":catch", ":finally", and ":endtry" commands can be put on
+a single line, but then syntax errors may make it difficult to recognize the
+"catch" line, thus you better avoid this.
+   Example: >
+	:try | unlet! foo # | catch | endtry
+raises an error exception for the trailing characters after the ":unlet!"
+argument, but does not see the ":catch" and ":endtry" commands, so that the
+error exception is discarded and the "E488: Trailing characters" message gets
+displayed.
+
+							*except-several-errors*
+When several errors appear in a single command, the first error message is
+usually the most specific one and therefor converted to the error exception.
+   Example: >
+	echo novar
+causes >
+	E121: Undefined variable: novar
+	E15: Invalid expression: novar
+The value of the error exception inside try conditionals is: >
+	Vim(echo):E121: Undefined variable: novar
+<							*except-syntax-error*
+But when a syntax error is detected after a normal error in the same command,
+the syntax error is used for the exception being thrown.
+   Example: >
+	unlet novar #
+causes >
+	E108: No such variable: "novar"
+	E488: Trailing characters
+The value of the error exception inside try conditionals is: >
+	Vim(unlet):E488: Trailing characters
+This is done because the syntax error might change the execution path in a way
+not intended by the user.  Example: >
+	try
+	    try | unlet novar # | catch | echo v:exception | endtry
+	catch /.*/
+	    echo "outer catch:" v:exception
+	endtry
+This displays "outer catch: Vim(unlet):E488: Trailing characters", and then
+a "E600: Missing :endtry" error message is given, see |except-single-line|.
+
+==============================================================================
+9. Examples						*eval-examples*
+
+Printing in Binary ~
+>
+  :" The function Nr2Bin() returns the Hex string of a number.
+  :func Nr2Bin(nr)
+  :  let n = a:nr
+  :  let r = ""
+  :  while n
+  :    let r = '01'[n % 2] . r
+  :    let n = n / 2
+  :  endwhile
+  :  return r
+  :endfunc
+
+  :" The function String2Bin() converts each character in a string to a
+  :" binary string, separated with dashes.
+  :func String2Bin(str)
+  :  let out = ''
+  :  for ix in range(strlen(a:str))
+  :    let out = out . '-' . Nr2Bin(char2nr(a:str[ix]))
+  :  endfor
+  :  return out[1:]
+  :endfunc
+
+Example of its use: >
+  :echo Nr2Bin(32)
+result: "100000" >
+  :echo String2Bin("32")
+result: "110011-110010"
+
+
+Sorting lines ~
+
+This example sorts lines with a specific compare function. >
+
+  :func SortBuffer()
+  :  let lines = getline(1, '$')
+  :  call sort(lines, function("Strcmp"))
+  :  call setline(1, lines)
+  :endfunction
+
+As a one-liner: >
+  :call setline(1, sort(getline(1, '$'), function("Strcmp")))
+
+
+scanf() replacement ~
+							*sscanf*
+There is no sscanf() function in Vim.  If you need to extract parts from a
+line, you can use matchstr() and substitute() to do it.  This example shows
+how to get the file name, line number and column number out of a line like
+"foobar.txt, 123, 45". >
+   :" Set up the match bit
+   :let mx='\(\f\+\),\s*\(\d\+\),\s*\(\d\+\)'
+   :"get the part matching the whole expression
+   :let l = matchstr(line, mx)
+   :"get each item out of the match
+   :let file = substitute(l, mx, '\1', '')
+   :let lnum = substitute(l, mx, '\2', '')
+   :let col = substitute(l, mx, '\3', '')
+
+The input is in the variable "line", the results in the variables "file",
+"lnum" and "col". (idea from Michael Geddes)
+
+
+getting the scriptnames in a Dictionary ~
+						*scriptnames-dictionary*
+The |:scriptnames| command can be used to get a list of all script files that
+have been sourced.  There is no equivalent function or variable for this
+(because it's rarely needed).  In case you need to manipulate the list this
+code can be used: >
+    " Get the output of ":scriptnames" in the scriptnames_output variable.
+    let scriptnames_output = ''
+    redir => scriptnames_output
+    silent scriptnames
+    redir END
+    
+    " Split the output into lines and parse each line.  Add an entry to the
+    " "scripts" dictionary.
+    let scripts = {}
+    for line in split(scriptnames_output, "\n")
+      " Only do non-blank lines.
+      if line =~ '\S'
+	" Get the first number in the line.
+        let nr = matchstr(line, '\d\+')
+	" Get the file name, remove the script number " 123: ".
+        let name = substitute(line, '.\+:\s*', '', '')
+	" Add an item to the Dictionary
+        let scripts[nr] = name
+      endif
+    endfor
+    unlet scriptnames_output
+
+==============================================================================
+10. No +eval feature				*no-eval-feature*
+
+When the |+eval| feature was disabled at compile time, none of the expression
+evaluation commands are available.  To prevent this from causing Vim scripts
+to generate all kinds of errors, the ":if" and ":endif" commands are still
+recognized, though the argument of the ":if" and everything between the ":if"
+and the matching ":endif" is ignored.  Nesting of ":if" blocks is allowed, but
+only if the commands are at the start of the line.  The ":else" command is not
+recognized.
+
+Example of how to avoid executing commands when the |+eval| feature is
+missing: >
+
+	:if 1
+	:  echo "Expression evaluation is compiled in"
+	:else
+	:  echo "You will _never_ see this message"
+	:endif
+
+==============================================================================
+11. The sandbox					*eval-sandbox* *sandbox* *E48*
+
+The 'foldexpr', 'includeexpr', 'indentexpr', 'statusline' and 'foldtext'
+options are evaluated in a sandbox.  This means that you are protected from
+these expressions having nasty side effects.  This gives some safety for when
+these options are set from a modeline.  It is also used when the command from
+a tags file is executed and for CTRL-R = in the command line.
+The sandbox is also used for the |:sandbox| command.
+
+These items are not allowed in the sandbox:
+	- changing the buffer text
+	- defining or changing mapping, autocommands, functions, user commands
+	- setting certain options (see |option-summary|)
+	- setting certain v: variables (see |v:var|)  *E794*
+	- executing a shell command
+	- reading or writing a file
+	- jumping to another buffer or editing a file
+	- executing Python, Perl, etc. commands
+This is not guaranteed 100% secure, but it should block most attacks.
+
+							*:san* *:sandbox*
+:san[dbox] {cmd}	Execute {cmd} in the sandbox.  Useful to evaluate an
+			option that may have been set from a modeline, e.g.
+			'foldexpr'.
+
+							*sandbox-option*
+A few options contain an expression.  When this expression is evaluated it may
+have to be done in the sandbox to avoid a security risk.  But the sandbox is
+restrictive, thus this only happens when the option was set from an insecure
+location.  Insecure in this context are:
+- sourcing a .vimrc or .exrc in the current directory
+- while executing in the sandbox
+- value coming from a modeline
+
+Note that when in the sandbox and saving an option value and restoring it, the
+option will still be marked as it was set in the sandbox.
+
+==============================================================================
+12. Textlock							*textlock*
+
+In a few situations it is not allowed to change the text in the buffer, jump
+to another window and some other things that might confuse or break what Vim
+is currently doing.  This mostly applies to things that happen when Vim is
+actually doing something else.  For example, evaluating the 'balloonexpr' may
+happen any moment the mouse cursor is resting at some position.
+
+This is not allowed when the textlock is active:
+	- changing the buffer text
+	- jumping to another buffer or window
+	- editing another file
+	- closing a window or quitting Vim
+	- etc.
+
+
+ vim:tw=78:ts=8:ft=help:norl:
--- /dev/null
+++ b/lib/vimfiles/doc/evim.1
@@ -1,0 +1,49 @@
+.TH EVIM 1 "2002 February 16"
+.SH NAME
+evim \- easy Vim, edit a file with Vim and setup for modeless editing
+.SH SYNOPSIS
+.br
+.B evim
+[options] [file ..]
+.br
+.B eview
+.SH DESCRIPTION
+.B eVim
+starts
+.B Vim
+and sets options to make it behave like a modeless editor.
+This is still Vim but used as a point-and-click editor.
+This feels a lot like using Notepad on MS-Windows.
+.B eVim
+will always run in the GUI, to enable the use of menus and toolbar.
+.PP
+Only to be used for people who really can't work with Vim in the normal way.
+Editing will be much less efficient.
+.PP
+.B eview
+is the same, but starts in read-only mode.  It works just like evim \-R.
+.PP
+See vim(1) for details about Vim, options, etc.
+.PP
+The 'insertmode' option is set to be able to type text directly.
+.br
+Mappings are setup to make Copy and Paste work with the MS-Windows keys.
+CTRL-X cuts text, CTRL-C copies text and CTRL-V pastes text.
+Use CTRL-Q to obtain the original meaning of CTRL-V.
+.SH OPTIONS
+See vim(1).
+.SH FILES
+.TP 15
+/usr/local/lib/vim/evim.vim
+The script loaded to initialize eVim.
+.SH AKA
+Also Known As "Vim for gumbies".
+When using evim you are expected to take a handkerchief,
+make a knot in each corner and wear it on your head.
+.SH SEE ALSO
+vim(1)
+.SH AUTHOR
+Most of
+.B Vim
+was made by Bram Moolenaar, with a lot of help from others.
+See the Help/Credits menu.
--- /dev/null
+++ b/lib/vimfiles/doc/farsi.txt
@@ -1,0 +1,269 @@
+*farsi.txt*     For Vim version 7.1.  Last change: 2005 Mar 29
+
+
+		  VIM REFERENCE MANUAL    by Mortaza Ghassab Shiran
+
+
+Right to Left and Farsi Mapping for Vim		*farsi* *Farsi*
+
+{Vi does not have any of these commands}
+
+						*E27*
+In order to use right-to-left and Farsi mapping support, it is necessary to
+compile Vim with the |+farsi| feature.
+
+These functions have been made by Mortaza G. Shiran <shiran@jps.net>
+
+
+Introduction
+------------
+In right-to-left oriented files the characters appear on the screen from right
+to left.  This kind of file is most useful when writing Farsi documents,
+composing faxes or writing Farsi memos.
+
+The commands, prompts and help files are not in Farsi, therefore the user
+interface remains the standard Vi interface.
+
+
+Highlights
+----------
+o  Editing left-to-right files as in the original Vim, no change.
+
+o  Viewing and editing files in right-to-left windows.   File orientation is
+   per window, so it is possible to view the same file in right-to-left and
+   left-to-right modes, simultaneously.
+
+o  Compatibility to the original Vim.   Almost all features work in
+   right-to-left mode (see bugs below).
+
+o  Changing keyboard mapping and reverse insert modes using a single
+   command.
+
+o  Backing from reverse insert mode to the correct place in the file
+   (if possible).
+
+o  While in Farsi mode, numbers are entered from left to right.  Upon entering
+   a none number character, that character will be inserted just into the
+   left of the last number.
+
+o  No special terminal with right-to-left capabilities is required.  The
+   right-to-left changes are completely hardware independent.  Only
+   Farsi font is necessary.
+
+o  Farsi keymapping on the command line in reverse insert mode.
+
+o  Toggling between left-to-right and right-to-left via F8 function key.
+
+o  Toggling between Farsi ISIR-3342 standard encoding and Vim Farsi via F9
+   function key.  Since this makes sense only for the text written in
+   right-to-left mode, this function is also supported only in right-to-left
+   mode.
+
+Farsi Fonts					*farsi fonts*
+-----------
+
+If the "extra" archive has been unpacked, the following files are found in the
+subdirectories of the '$VIM/farsi' directory:
+
+   +  far-a01.pcf    X Windows fonts for Unix including Linux systems
+   +  far-a01.bf     X Windows fonts for SunOS
+   +  far-a01.f16    a screen fonts for Unix including Linux systems
+   +  far-a01.fon    a monospaced fonts for Windows NT/95/98
+   +  far-a01.com    a screen fonts for DOS
+
+
+Font Installation
+-----------------
+
+o  Installation of fonts for MS Window systems (NT/95/98)
+
+   From 'Control Panel' folder, start the 'Fonts' program.  Then from 'file'
+   menu item select 'Install New Fonts ...'.  Browse and select the
+   'far-a01.fon', then follow the installation guide.
+   NOTE: several people have reported that this does not work.  The solution
+   is unknown.
+
+o  Installation of fonts for X Window systems (Unix/Linux)
+
+   Depending on your system, copy far-a01.pcf.Z or far-a01.pcf.gz into a
+   directory of your choice.  Change to the directory containing the Farsi
+   fonts and execute the following commands:
+
+   >  mkfontdir
+   >  xset +fp path_name_of_farsi_fonts_directory
+
+o  Installation of fonts for X Window systems (SunOS)
+
+   Copy far-a01.bf font into a directory of your choice.
+   Change to the directory containing the far-a01.fb fonts and
+   execute the following commands:
+
+   >  fldfamily
+   >  xset +fp path_name_of_fonts_directory
+
+o  Installation of ASCII screen fonts (Unix/Linux)
+
+   For Linux system, copy the far-a01.f16 fonts into /usr/lib/kbd/consolefonts
+   directory and execute the setfont program as "setfont far-a01.f16".  For
+   other systems (e.g. SCO Unix), please refer to the fonts installation
+   section of your system administration manuals.
+
+o  Installation of ASCII screen fonts (DOS)
+
+   After system power on, prior to the first use of Vim, upload the Farsi
+   fonts by executing the far-a01.com font uploading program.
+
+
+Usage
+-----
+Prior to starting Vim, the environment in which Vim can run in Farsi mode,
+must be set.  In addition to installation of Farsi fonts, following points
+refer to some of the system environments, which you may need to set:
+Key code mapping, loading graphic card in ASCII screen mode, setting the IO
+driver in 8 bit clean mode ... .
+
+o  Setting the Farsi fonts
+
+   +  For Vim GUI set the 'guifont' to far-a01.  This is done by entering
+      ':set guifont=far-a01' in the Vim window.
+
+      You can have 'guifont' set to far-a01 by Vim during the Vim startup
+      by appending the ':set guifont=far-a01' into your .vimrc file
+      (in case of NT/95/98 platforms _vimrc).
+
+      Under the X Window environment, you can also start Vim with the
+      '-fn far-a01' option.
+
+   +  For Vim within a xterm, start a xterm with the Farsi fonts (e.g.
+      kterm -fn far-a01).  Then start Vim inside the kterm.
+
+   +  For Vim under DOS, prior to the first usage of Vim, upload the Farsi
+      fonts by executing the far-a01.com fonts uploading program.
+
+o  Farsi Keymapping Activation
+
+   To activate the Farsi keymapping, set either 'altkeymap' or 'fkmap'.
+   This is done by entering ':set akm' or ':set fk' in the Vim window.
+   You can have 'altkeymap' or 'fkmap' set as default by appending ':set akm'
+   or ':set fk' in your .vimrc file or _vimrc in case of NT/95/98 platforms.
+
+   To turn off the Farsi keymapping as a default second language keymapping,
+   reset the 'altkeymap' by entering ':set noakm'.
+
+o  right-to-left Farsi Mode
+
+   By default Vim starts in Left-to-right mode.  Following are ways to change
+   the window orientation:
+
+   + Start Vim with the -F option (e.g. vim -F ...).
+
+   + Use the F8 function key to toggle between left-to-right and right-to-left.
+
+   + While in Left-to-right mode, enter 'set rl' in the command line ('rl' is
+     the abbreviation for rightleft).
+
+   + Put the 'set rl' line in your '.vimrc' file to start Vim in
+     right-to-left mode permanently.
+
+Encoding
+--------
+
+The letter encoding used is the Vim extended ISIR-3342 standard with a built
+in function to convert between Vim extended ISIR-3342 and ISIR-3342 standard.
+
+For document portability reasons, the letter encoding is kept the same across
+different platforms (i.e. UNIX's, NT/95/98, MS DOS, ...).
+
+
+o  Keyboard
+
+   +  CTRL-_ in insert/replace modes toggles between Farsi(akm)/Latin
+      mode as follows:
+
+   +  CTRL-_ moves the cursor to the end of the typed text in edit mode.
+
+   +  CTRL-_ in command mode only toggles keyboard mapping between Farsi(akm)/
+      Latin.  The Farsi text is then entered in reverse insert mode.
+
+   +  F8 - Toggles between left-to-right and right-to-left.
+
+   +  F9 - Toggles the encoding between ISIR-3342 standard and Vim extended
+      ISIR-3342 (supported only in right-to-left mode).
+
+   +  Keyboard mapping is based on the Iranian ISIRI-2901 standard.
+      Following table shows the keyboard mapping while Farsi(akm) mode set:
+
+	-------------------------------------
+	`  1  2  3  4  5  6  7  8  9  0  -  =
+	�  �  �  �  �  �  �  �  �  �  �  �  �
+	-------------------------------------
+	~  !  @  #  $  %  ^  &  *  (  )  _  +
+	~  �  �  �  �  �  �  �  �  �  �  �  �
+	-------------------------------------
+	q  w  e  r  t  z  u  i  o  p  [  ]
+	�  �  �  �  �  �  �  �  �  �  �  �
+	-------------------------------------
+	Q  W  E  R  T  Z  U  I  O  P  {  }
+	�  �  �  �  �  �  �  �  [  ]  {  }
+	-------------------------------------
+	a  s  d  f  g  h  j  k  l  ;  '  \
+	�  �  �  �  �  �  �  �  �  �  �  +	-------------------------------------
+	A  S  D  F  G  H  J  K  L  :  "  |
+	�  �� �  �  �  �  �  �  �  �  �  +	-------------------------------------
+	<  y  x  c  v  b  n  m  ,  .  /
+	�  �  �  �  �  �  �  �  �  �  �
+	-------------------------------------
+	>  Y  X  C  V  B  N  M  <  >  ?
+	�  �  �  �  �  �  �  �  �  �  �
+	-------------------------------------
+
+Note:
+	�  stands for Farsi PSP (break without space)
+
+	�  stands for Farsi PCN (for HAMZE attribute )
+
+Restrictions
+------------
+
+o  In insert/replace mode and fkmap (Farsi mode) set, CTRL-B is not
+   supported.
+
+o  If you change the character mapping between Latin/Farsi, the redo buffer
+   will be reset (emptied).  That is, redo is valid and will function (using
+   '.') only within the mode you are in.
+
+o  While numbers are entered in Farsi mode, the redo buffer will be reset
+   (emptied).  That is, you cannot redo the last changes (using '.') after
+   entering numbers.
+
+o  While in left-to-right mode and Farsi mode set, CTRL-R is not supported.
+
+o  While in right-to-left mode, the search on 'Latin' pattern does not work,
+   except if you enter the Latin search pattern in reverse.
+
+o  In command mode there is no support for entering numbers from left
+   to right and also for the sake of flexibility the keymapping logic is
+   restricted.
+
+o  Under the X Window environment, if you want to run Vim within a xterm
+   terminal emulator and Farsi mode set, you need to have an ANSI compatible
+   xterm terminal emulator.  This is because the letter codes above 128 decimal
+   have certain meanings in the standard xterm terminal emulator.
+
+   Note: Under X Window environment, Vim GUI works fine in Farsi mode.
+	 This eliminates the need of any xterm terminal emulator.
+
+
+Bugs
+----
+While in insert/replace and Farsi mode set, if you repeatedly change the
+cursor position (via cursor movement) and enter new text and then try to undo
+the last change, the undo will lag one change behind.  But as you continue to
+undo, you will reach the original line of text.  You can also use U to undo all
+changes made in the current line.
+
+For more information about the bugs refer to rileft.txt.
+
+ vim:tw=78:ts=8:ft=help:norl:
--- /dev/null
+++ b/lib/vimfiles/doc/filetype.txt
@@ -1,0 +1,576 @@
+*filetype.txt*  For Vim version 7.1.  Last change: 2007 May 10
+
+
+		  VIM REFERENCE MANUAL    by Bram Moolenaar
+
+
+Filetypes						*filetype* *file-type*
+
+1. Filetypes					|filetypes|
+2. Filetype plugin				|filetype-plugins|
+3. Docs for the default filetype plugins.	|ftplugin-docs|
+
+Also see |autocmd.txt|.
+
+{Vi does not have any of these commands}
+
+==============================================================================
+1. Filetypes					*filetypes* *file-types*
+
+Vim can detect the type of file that is edited.  This is done by checking the
+file name and sometimes by inspecting the contents of the file for specific
+text.
+
+							*:filetype* *:filet*
+To enable file type detection, use this command in your vimrc: >
+	:filetype on
+Each time a new or existing file is edited, Vim will try to recognize the type
+of the file and set the 'filetype' option.  This will trigger the FileType
+event, which can be used to set the syntax highlighting, set options, etc.
+
+NOTE: Filetypes and 'compatible' don't work together well, since being Vi
+compatible means options are global.  Resetting 'compatible' is recommended,
+if you didn't do that already.
+
+Detail: The ":filetype on" command will load one of these files:
+		Amiga	    $VIMRUNTIME/filetype.vim
+		Mac	    $VIMRUNTIME:filetype.vim
+		MS-DOS	    $VIMRUNTIME\filetype.vim
+		RiscOS	    Vim:Filetype
+		Unix	    $VIMRUNTIME/filetype.vim
+		VMS	    $VIMRUNTIME/filetype.vim
+	This file is a Vim script that defines autocommands for the
+	BufNewFile and BufRead events.  If the file type is not found by the
+	name, the file $VIMRUNTIME/scripts.vim is used to detect it from the
+	contents of the file.
+	When the GUI is running or will start soon, the menu.vim script is
+	also sourced.  See |'go-M'| about avoiding that.
+
+To add your own file types, see |new-filetype| below.  To search for help on a
+filetype prepend "ft-" and optionally append "-syntax", "-indent" or
+"-plugin".  For example: >
+	:help ft-vim-indent
+	:help ft-vim-syntax
+	:help ft-man-plugin
+
+If the file type is not detected automatically, or it finds the wrong type,
+you can either set the 'filetype' option manually, or add a modeline to your
+file.  Example, for in an IDL file use the command: >
+	:set filetype=idl
+
+or add this |modeline| to the file:
+	/* vim: set filetype=idl : */ ~
+
+						*:filetype-plugin-on*
+You can enable loading the plugin files for specific file types with: >
+	:filetype plugin on
+If filetype detection was not switched on yet, it will be as well.
+This actually loads the file "ftplugin.vim" in 'runtimepath'.
+The result is that when a file is edited its plugin file is loaded (if there
+is one for the detected filetype). |filetype-plugin|
+
+						*:filetype-plugin-off*
+You can disable it again with: >
+	:filetype plugin off
+The filetype detection is not switched off then.  But if you do switch off
+filetype detection, the plugins will not be loaded either.
+This actually loads the file "ftplugof.vim" in 'runtimepath'.
+
+						*:filetype-indent-on*
+You can enable loading the indent file for specific file types with: >
+	:filetype indent on
+If filetype detection was not switched on yet, it will be as well.
+This actually loads the file "indent.vim" in 'runtimepath'.
+The result is that when a file is edited its indent file is loaded (if there
+is one for the detected filetype). |indent-expression|
+
+						*:filetype-indent-off*
+You can disable it again with: >
+	:filetype indent off
+The filetype detection is not switched off then.  But if you do switch off
+filetype detection, the indent files will not be loaded either.
+This actually loads the file "indoff.vim" in 'runtimepath'.
+This disables auto-indenting for files you will open.  It will keep working in
+already opened files.  Reset 'autoindent', 'cindent', 'smartindent' and/or
+'indentexpr' to disable indenting in an opened file.
+
+						*:filetype-off*
+To disable file type detection, use this command: >
+	:filetype off
+This will keep the flags for "plugin" and "indent", but since no file types
+are being detected, they won't work until the next ":filetype on".
+
+
+Overview:					*:filetype-overview*
+
+command				detection	plugin		indent ~
+:filetype on			on		unchanged	unchanged
+:filetype off			off		unchanged	unchanged
+:filetype plugin on		on		on		unchanged
+:filetype plugin off		unchanged	off		unchanged
+:filetype indent on		on		unchanged	on
+:filetype indent off		unchanged	unchanged	off
+:filetype plugin indent on	on		on		on
+:filetype plugin indent off	unchanged	off		off
+
+To see the current status, type: >
+	:filetype
+The output looks something like this: >
+	filetype detection:ON  plugin:ON  indent:OFF
+
+The file types are also used for syntax highlighting.  If the ":syntax on"
+command is used, the file type detection is installed too.  There is no need
+to do ":filetype on" after ":syntax on".
+
+To disable one of the file types, add a line in the your filetype file, see
+|remove-filetype|.
+
+							*filetype-detect*
+To detect the file type again: >
+	:filetype detect
+Use this if you started with an empty file and typed text that makes it
+possible to detect the file type.  For example, when you entered this in a
+shell script: "#!/bin/csh".
+   When filetype detection was off, it will be enabled first, like the "on"
+argument was used.
+
+							*filetype-overrule*
+When the same extension is used for two filetypes, Vim tries to guess what
+kind of file it is.  This doesn't always work.  A number of global variables
+can be used to overrule the filetype used for certain extensions:
+
+	file name	variable ~
+	*.asa		g:filetype_asa	|ft-aspvbs-syntax| |ft-aspperl-syntax|
+	*.asp		g:filetype_asp	|ft-aspvbs-syntax| |ft-aspperl-syntax|
+	*.asm		g:asmsyntax	|ft-asm-syntax|
+	*.prg		g:filetype_prg
+	*.pl		g:filetype_pl
+	*.inc		g:filetype_inc
+	*.w		g:filetype_w	|ft-cweb-syntax|
+	*.i		g:filetype_i	|ft-progress-syntax|
+	*.p		g:filetype_p	|ft-pascal-syntax|
+	*.sh		g:bash_is_sh	|ft-sh-syntax|
+	*.tex		g:tex_flavor	|ft-tex-plugin|
+
+							*filetype-ignore*
+To avoid that certain files are being inspected, the g:ft_ignore_pat variable
+is used.  The default value is set like this: >
+	:let g:ft_ignore_pat = '\.\(Z\|gz\|bz2\|zip\|tgz\)$'
+This means that the contents of compressed files are not inspected.
+
+							*new-filetype*
+If a file type that you want to use is not detected yet, there are four ways
+to add it.  In any way, it's better not to modify the $VIMRUNTIME/filetype.vim
+file.  It will be overwritten when installing a new version of Vim.
+
+A. If you want to overrule all default file type checks.
+   This works by writing one file for each filetype.  The disadvantage is that
+   means there can be many files.  The advantage is that you can simply drop
+   this file in the right directory to make it work.
+							*ftdetect*
+   1. Create your user runtime directory.  You would normally use the first
+      item of the 'runtimepath' option.  Then create the directory "ftdetect"
+      inside it.  Example for Unix: >
+	:!mkdir ~/.vim
+	:!mkdir ~/.vim/ftdetect
+<
+   2. Create a file that contains an autocommand to detect the file type.
+      Example: >
+	au BufRead,BufNewFile *.mine		set filetype=mine
+<     Note that there is no "augroup" command, this has already been done
+      when sourcing your file.  You could also use the pattern "*" and then
+      check the contents of the file to recognize it.
+      Write this file as "mine.vim" in the "ftdetect" directory in your user
+      runtime directory.  For example, for Unix: >
+	:w ~/.vim/ftdetect/mine.vim
+
+<  3. To use the new filetype detection you must restart Vim.
+
+   The files in the "ftdetect" directory are used after all the default
+   checks, thus they can overrule a previously detected file type.  But you
+   can also use |:setfiletype| to keep a previously detected filetype.
+
+B. If you want to detect your file after the default file type checks.
+
+   This works like A above, but instead of setting 'filetype' unconditionally
+   use ":setfiletype".  This will only set 'filetype' if no file type was
+   detected yet.  Example: >
+	au BufRead,BufNewFile *.txt		setfiletype text
+<
+   You can also use the already detected file type in your command.  For
+   example, to use the file type "mypascal" when "pascal" has been detected: >
+	au BufRead,BufNewFile *		if &ft == 'pascal' | set ft=mypascal
+								       | endif
+
+C. If your file type can be detected by the file name.
+   1. Create your user runtime directory.  You would normally use the first
+      item of the 'runtimepath' option.  Example for Unix: >
+	:!mkdir ~/.vim
+<
+   2. Create a file that contains autocommands to detect the file type.
+      Example: >
+	" my filetype file
+	if exists("did_load_filetypes")
+	  finish
+	endif
+	augroup filetypedetect
+	  au! BufRead,BufNewFile *.mine		setfiletype mine
+	  au! BufRead,BufNewFile *.xyz		setfiletype drawing
+	augroup END
+<     Write this file as "filetype.vim" in your user runtime directory.  For
+      example, for Unix: >
+	:w ~/.vim/filetype.vim
+
+<  3. To use the new filetype detection you must restart Vim.
+
+   Your filetype.vim will be sourced before the default FileType autocommands
+   have been installed.  Your autocommands will match first, and the
+   ":setfiletype" command will make sure that no other autocommands will set
+   'filetype' after this.
+							*new-filetype-scripts*
+D. If your filetype can only be detected by inspecting the contents of the
+   file.
+
+   1. Create your user runtime directory.  You would normally use the first
+      item of the 'runtimepath' option.  Example for Unix: >
+	:!mkdir ~/.vim
+<
+   2. Create a vim script file for doing this.  Example: >
+	if did_filetype()	" filetype already set..
+	  finish		" ..don't do these checks
+	endif
+	if getline(1) =~ '^#!.*\<mine\>'
+	  setfiletype mine
+	elseif getline(1) =~? '\<drawing\>'
+	  setfiletype drawing
+	endif
+<     See $VIMRUNTIME/scripts.vim for more examples.
+      Write this file as "scripts.vim" in your user runtime directory.  For
+      example, for Unix: >
+	:w ~/.vim/scripts.vim
+<
+   3. The detection will work right away, no need to restart Vim.
+
+   Your scripts.vim is loaded before the default checks for file types, which
+   means that your rules override the default rules in
+   $VIMRUNTIME/scripts.vim.
+
+						*remove-filetype*
+If a file type is detected that is wrong for you, install a filetype.vim or
+scripts.vim to catch it (see above).  You can set 'filetype' to a non-existing
+name to avoid that it will be set later anyway: >
+	:set filetype=ignored
+
+If you are setting up a system with many users, and you don't want each user
+to add/remove the same filetypes, consider writing the filetype.vim and
+scripts.vim files in a runtime directory that is used for everybody.  Check
+the 'runtimepath' for a directory to use.  If there isn't one, set
+'runtimepath' in the |system-vimrc|.  Be careful to keep the default
+directories!
+
+
+						*autocmd-osfiletypes*
+On operating systems which support storing a file type with the file, you can
+specify that an autocommand should only be executed if the file is of a
+certain type.
+
+The actual type checking depends on which platform you are running Vim
+on; see your system's documentation for details.
+
+To use osfiletype checking in an autocommand you should put a list of types to
+match in angle brackets in place of a pattern, like this: >
+
+	:au BufRead *.html,<&faf;HTML>  runtime! syntax/html.vim
+
+This will match:
+
+- Any file whose name ends in `.html'
+- Any file whose type is `&faf' or 'HTML', where the meaning of these types
+  depends on which version of Vim you are using.
+  Unknown types are considered NOT to match.
+
+You can also specify a type and a pattern at the same time (in which case they
+must both match): >
+
+	:au BufRead <&fff>diff*
+
+This will match files of type `&fff' whose names start with `diff'.
+
+Note that osfiletype checking is skipped if Vim is compiled without the
+|+osfiletype| feature.
+
+							*plugin-details*
+The "plugin" directory can be in any of the directories in the 'runtimepath'
+option.  All of these directories will be searched for plugins and they are
+all loaded.  For example, if this command: >
+
+	set runtimepath
+
+produces this output:
+
+	runtimepath=/etc/vim,~/.vim,/usr/local/share/vim/vim60 ~
+
+then Vim will load all plugins in these directories and below:
+
+	/etc/vim/plugin/  ~
+	~/.vim/plugin/  ~
+	/usr/local/share/vim/vim60/plugin/  ~
+
+Note that the last one is the value of $VIMRUNTIME which has been expanded.
+
+What if it looks like your plugin is not being loaded?  You can find out what
+happens when Vim starts up by using the |-V| argument: >
+
+	vim -V2
+
+You will see a lot of messages, in between them is a remark about loading the
+plugins.  It starts with:
+
+	Searching for "plugin/**/*.vim" in ~
+
+There you can see where Vim looks for your plugin scripts.
+
+==============================================================================
+2. Filetype plugin					*filetype-plugins*
+
+When loading filetype plugins has been enabled |:filetype-plugin-on|, options
+will be set and mappings defined.  These are all local to the buffer, they
+will not be used for other files.
+
+Defining mappings for a filetype may get in the way of the mappings you
+define yourself.  There are a few ways to avoid this:
+1. Set the "maplocalleader" variable to the key sequence you want the mappings
+   to start with.  Example: >
+	:let maplocalleader = ","
+<  All mappings will then start with a comma instead of the default, which
+   is a backslash.  Also see |<LocalLeader>|.
+
+2. Define your own mapping.  Example: >
+	:map ,p <Plug>MailQuote
+<  You need to check the description of the plugin file below for the
+   functionality it offers and the string to map to.
+   You need to define your own mapping before the plugin is loaded (before
+   editing a file of that type).  The plugin will then skip installing the
+   default mapping.
+
+3. Disable defining mappings for a specific filetype by setting a variable,
+   which contains the name of the filetype.  For the "mail" filetype this
+   would be: >
+	:let no_mail_maps = 1
+
+4. Disable defining mappings for all filetypes by setting a variable: >
+	:let no_plugin_maps = 1
+<
+
+							*ftplugin-overrule*
+If a global filetype plugin does not do exactly what you want, there are three
+ways to change this:
+
+1. Add a few settings.
+   You must create a new filetype plugin in a directory early in
+   'runtimepath'.  For Unix, for example you could use this file: >
+	vim ~/.vim/ftplugin/fortran.vim
+<  You can set those settings and mappings that you would like to add.  Note
+   that the global plugin will be loaded after this, it may overrule the
+   settings that you do here.  If this is the case, you need to use one of the
+   following two methods.
+
+2. Make a copy of the plugin and change it.
+   You must put the copy in a directory early in 'runtimepath'.  For Unix, for
+   example, you could do this: >
+	cp $VIMRUNTIME/ftplugin/fortran.vim ~/.vim/ftplugin/fortran.vim
+<  Then you can edit the copied file to your liking.  Since the b:did_ftplugin
+   variable will be set, the global plugin will not be loaded.
+   A disadvantage of this method is that when the distributed plugin gets
+   improved, you will have to copy and modify it again.
+
+3. Overrule the settings after loading the global plugin.
+   You must create a new filetype plugin in a directory from the end of
+   'runtimepath'.  For Unix, for example, you could use this file: >
+	vim ~/.vim/after/ftplugin/fortran.vim
+<  In this file you can change just those settings that you want to change.
+
+==============================================================================
+3.  Docs for the default filetype plugins.		*ftplugin-docs*
+
+
+CHANGELOG						*ft-changelog-plugin*
+
+Allows for easy entrance of Changelog entries in Changelog files.  There are
+some commands, mappings, and variables worth exploring:
+
+Options:
+'comments'		is made empty to not mess up formatting.
+'textwidth'		is set to 78, which is standard.
+'formatoptions'		the 't' flag is added to wrap when inserting text.
+
+Commands:
+NewChangelogEntry	Adds a new Changelog entry in an intelligent fashion
+			(see below).
+
+Local mappings:
+<Leader>o		Starts a new Changelog entry in an equally intelligent
+			fashion (see below).
+
+Global mappings:
+			NOTE: The global mappings are accessed by sourcing the
+			ftplugin/changelog.vim file first, e.g. with >
+				runtime ftplugin/changelog.vim
+<			in your |.vimrc|.
+<Leader>o		Switches to the ChangeLog buffer opened for the
+			current directory, or opens it in a new buffer if it
+			exists in the current directory.  Then it does the
+			same as the local <Leader>o described above.
+
+Variables:
+g:changelog_timeformat  Deprecated; use g:changelog_dateformat instead.
+g:changelog_dateformat	The date (and time) format used in ChangeLog entries.
+			The format accepted is the same as for the
+			|strftime()| function.
+			The default is "%Y-%m-%d" which is the standard format
+			for many ChangeLog layouts.
+g:changelog_username	The name and email address of the user.
+			The default is deduced from environment variables and
+			system files.  It searches /etc/passwd for the comment
+			part of the current user, which informally contains
+			the real name of the user up to the first separating
+			comma.  then it checks the $NAME environment variable
+			and finally runs `whoami` and `hostname` to build an
+			email address.  The final form is >
+				Full Name  <user@host>
+<
+g:changelog_new_date_format
+			The format to use when creating a new date-entry.
+			The following table describes special tokens in the
+			string:
+				%%	insert a single '%' character
+				%d	insert the date from above
+				%u	insert the user from above
+				%c	where to position cursor when done
+			The default is "%d  %u\n\n\t* %c\n\n", which produces
+			something like (| is where cursor will be, unless at
+			the start of the line where it denotes the beginning
+			of the line) >
+				|2003-01-14  Full Name  <user@host>
+				|
+				|        * |
+<
+g:changelog_new_entry_format
+			The format used when creating a new entry.
+			The following table describes special tokens in the
+			string:
+				%c	where to position cursor when done
+			The default is "\t*%c", which produces something
+			similar to >
+				|        * |
+<
+g:changelog_date_entry_search
+			The search pattern to use when searching for a
+			date-entry.
+			The same tokens that can be used for
+			g:changelog_new_date_format can be used here as well.
+			The default is '^\s*%d\_s*%u' which finds lines
+			matching the form >
+				|2003-01-14  Full Name  <user@host>
+<			and some similar formats.
+
+g:changelog_date_end_entry_search
+			The search pattern to use when searching for the end
+			of a date-entry.
+			The same tokens that can be used for
+			g:changelog_new_date_format can be used here as well.
+			The default is '^\s*$' which finds lines that contain
+			only whitespace or are completely empty.
+
+The Changelog entries are inserted where they add the least amount of text.
+After figuring out the current date and user, the file is searched for an
+entry beginning with the current date and user and if found adds another item
+under it.  If not found, a new entry and item is prepended to the beginning of
+the Changelog.
+
+
+FORTRAN							*ft-fortran-plugin*
+
+Options:
+'expandtab'	is switched on to avoid tabs as required by the Fortran
+		standards unless the user has set fortran_have_tabs in .vimrc.
+'textwidth'	is set to 72 for fixed source format as required by the
+		Fortran standards and to 80 for free source format.
+'formatoptions' is set to break code and comment lines and to preserve long
+		lines.  You can format comments with |gq|.
+For further discussion of fortran_have_tabs and the method used for the
+detection of source format see |ft-fortran-syntax|.
+
+
+MAIL							*ft-mail-plugin*
+
+Options:
+'modeline'	is switched off to avoid the danger of trojan horses, and to
+		avoid that a Subject line with "Vim:" in it will cause an
+		error message.
+'textwidth'	is set to 72.  This is often recommended for e-mail.
+'formatoptions'  is set to break text lines and to repeat the comment leader
+		in new lines, so that a leading ">" for quotes is repeated.
+		You can also format quoted text with |gq|.
+
+Local mappings:
+<LocalLeader>q   or   \\MailQuote
+	Quotes the text selected in Visual mode, or from the cursor position
+	to the end of the file in Normal mode.  This means "> " is inserted in
+	each line.
+
+MAN							*ft-man-plugin* *:Man*
+
+Displays a manual page in a nice way.  Also see the user manual
+|find-manpage|.
+
+To start using the ":Man" command before any manual page was loaded, source
+this script from your startup vimrc file: >
+
+	runtime ftplugin/man.vim
+
+Options:
+'iskeyword'	the '.' character is added to be able to use CTRL-] on the
+		manual page name.
+
+Commands:
+Man {name}	Display the manual page for {name} in a window.
+Man {number} {name}
+		Display the manual page for {name} in a section {number}.
+
+Global mapping:
+<Leader>K	Displays the manual page for the word under the cursor.
+
+Local mappings:
+CTRL-]		Jump to the manual page for the word under the cursor.
+CTRL-T		Jump back to the previous manual page.
+
+
+RPM SPEC						*ft-spec-plugin*
+
+Since the text for this plugin is rather long it has been put in a separate
+file: |pi_spec.txt|.
+
+
+SQL							*ft-sql*
+
+Since the text for this plugin is rather long it has been put in a separate
+file: |sql.txt|.
+
+
+TEX							*ft-tex-plugin*
+
+If the first line of a *.tex file has the form >
+	%&<format>
+then this determined the file type:  plaintex (for plain TeX), context (for
+ConTeXt), or tex (for LaTeX).  Otherwise, the file is searched for keywords to
+choose context or tex.  If no keywords are found, it defaults to plaintex.
+You can change the default by defining the variable g:tex_flavor to the format
+(not the file type) you use most.  Use one of these: >
+	let g:tex_flavor = "plain"
+	let g:tex_flavor = "context"
+	let g:tex_flavor = "latex"
+Currently no other formats are recognized.
+
+
+ vim:tw=78:ts=8:ft=help:norl:
--- /dev/null
+++ b/lib/vimfiles/doc/fold.txt
@@ -1,0 +1,583 @@
+*fold.txt*      For Vim version 7.1.  Last change: 2007 May 11
+
+
+		  VIM REFERENCE MANUAL    by Bram Moolenaar
+
+
+Folding						*Folding* *folding*
+
+You can find an introduction on folding in chapter 28 of the user manual.
+|usr_28.txt|
+
+1. Fold methods		|fold-methods|
+2. Fold commands	|fold-commands|
+3. Fold options		|fold-options|
+4. Behavior of folds	|fold-behavior|
+
+{Vi has no Folding}
+{not available when compiled without the +folding feature}
+
+==============================================================================
+1. Fold methods					*fold-methods*
+
+The folding method can be set with the 'foldmethod' option.
+
+When setting 'foldmethod' to a value other than "manual", all folds are
+deleted and new ones created.  Switching to the "manual" method doesn't remove
+the existing folds.  This can be used to first define the folds automatically
+and then change them manually.
+
+There are six methods to select folds:
+	manual		manually define folds
+	indent		more indent means a higher fold level
+	expr		specify an expression to define folds
+	syntax		folds defined by syntax highlighting
+	diff		folds for unchanged text
+	marker		folds defined by markers in the text
+
+
+MANUAL						*fold-manual*
+
+Use commands to manually define the fold regions.  This can also be used by a
+script that parses text to find folds.
+
+The level of a fold is only defined by its nesting.  To increase the fold
+level of a fold for a range of lines, define a fold inside it that has the
+same lines.
+
+The manual folds are lost when you abandon the file.  To save the folds use
+the |:mkview| command.  The view can be restored later with |:loadview|.
+
+
+INDENT						*fold-indent*
+
+The folds are automatically defined by the indent of the lines.
+
+The foldlevel is computed from the indent of the line, divided by the
+'shiftwidth' (rounded down).  A sequence of lines with the same or higher fold
+level form a fold, with the lines with a higher level forming a nested fold.
+
+The nesting of folds is limited with 'foldnestmax'.
+
+Some lines are ignored and get the fold level of the line above or below it,
+whatever is the lowest.  These are empty or white lines and lines starting
+with a character in 'foldignore'.  White space is skipped before checking for
+characters in 'foldignore'.  For C use "#" to ignore preprocessor lines.
+
+When you want to ignore lines in another way, use the 'expr' method.  The
+|indent()| function can be used in 'foldexpr' to get the indent of a line.
+
+
+EXPR						*fold-expr*
+
+The folds are automatically defined by their foldlevel, like with the "indent"
+method.  The value of the 'foldexpr' option is evaluated to get the foldlevel
+of a line.  Examples:
+This will create a fold for all consecutive lines that start with a tab: >
+	:set foldexpr=getline(v:lnum)[0]==\"\\t\"
+This will call a function to compute the fold level: >
+	:set foldexpr=MyFoldLevel(v:lnum)
+This will make a fold out of paragraphs separated by blank lines: >
+	:set foldexpr=getline(v:lnum)=~'^\\s*$'&&getline(v:lnum+1)=~'\\S'?'<1':1
+this does the same: >
+	:set foldexpr=getline(v:lnum-1)=~'^\\s*$'&&getline(v:lnum)=~'\\S'?'>1':1
+
+Note that backslashes must be used to escape characters that ":set" handles
+differently (space, backslash, double quote, etc., see |option-backslash|).
+
+These are the conditions with which the expression is evaluated:
+- The current buffer and window are set for the line.
+- The variable "v:lnum" is set to the line number.
+- The result is used for the fold level in this way:
+  value			meaning ~
+  0			the line is not in a fold
+  1, 2, ..		the line is in a fold with this level
+  -1			the fold level is undefined, use the fold level of a
+			line before or after this line, whichever is the
+			lowest.
+  "="			use fold level from the previous line
+  "a1", "a2", ..	add one, two, .. to the fold level of the previous
+			line
+  "s1", "s2", ..	subtract one, two, .. from the fold level of the
+			previous line
+  "<1", "<2", ..	a fold with this level ends at this line
+  ">1", ">2", ..	a fold with this level starts at this line
+
+It is not required to mark the start (end) of a fold with ">1" ("<1"), a fold
+will also start (end) when the fold level is higher (lower) than the fold
+level of the previous line.
+
+There must be no side effects from the expression.  The text in the buffer,
+cursor position, the search patterns, options etc. must not be changed.
+You can change and restore them if you are careful.
+
+If there is some error in the expression, or the resulting value isn't
+recognized, there is no error message and the fold level will be zero.
+For debugging the 'debug' option can be set to "msg", the error messages will
+be visible then.
+
+Note: Since the expression has to be evaluated for every line, this fold
+method can be very slow!
+
+Try to avoid the "=", "a" and "s" return values, since Vim often has to search
+backwards for a line for which the fold level is defined.  This can be slow.
+
+|foldlevel()| can be useful to compute a fold level relative to a previous
+fold level.  But note that foldlevel() may return -1 if the level is not known
+yet.  And it returns the level at the start of the line, while a fold might
+end in that line.
+
+
+SYNTAX						*fold-syntax*
+
+A fold is defined by syntax items that have the "fold" argument. |:syn-fold|
+
+The fold level is defined by nesting folds.  The nesting of folds is limited
+with 'foldnestmax'.
+
+Be careful to specify proper syntax syncing.  If this is not done right, folds
+may differ from the displayed highlighting.  This is especially relevant when
+using patterns that match more than one line.  In case of doubt, try using
+brute-force syncing: >
+	:syn sync fromstart
+
+
+DIFF						*fold-diff*
+
+The folds are automatically defined for text that is not part of a change or
+close to a change.
+
+This method only works properly when the 'diff' option is set for the current
+window and changes are being displayed.  Otherwise the whole buffer will be
+one big fold.
+
+The 'diffopt' option can be used to specify the context.  That is, the number
+of lines between the fold and a change that are not included in the fold.  For
+example, to use a context of 8 lines: >
+	:set diffopt=filler,context:8
+The default context is six lines.
+
+When 'scrollbind' is also set, Vim will attempt to keep the same folds open in
+other diff windows, so that the same text is visible.
+
+
+MARKER						*fold-marker*
+
+Markers in the text tell where folds start and end.  This allows you to
+precisely specify the folds.  This will allow deleting and putting a fold,
+without the risk of including the wrong lines.  The 'foldtext' option is
+normally set such that the text before the marker shows up in the folded line.
+This makes it possible to give a name to the fold.
+
+Markers can have a level included, or can use matching pairs.  Including a
+level is easier, you don't have to add end markers and avoid problems with
+non-matching marker pairs.  Example: >
+	/* global variables {{{1 */
+	int varA, varB;
+
+	/* functions {{{1 */
+	/* funcA() {{{2 */
+	void funcA() {}
+
+	/* funcB() {{{2 */
+	void funcB() {}
+
+A fold starts at a "{{{" marker.  The following number specifies the fold
+level.  What happens depends on the difference between the current fold level
+and the level given by the marker:
+1. If a marker with the same fold level is encountered, the previous fold
+   ends and another fold with the same level starts.
+2. If a marker with a higher fold level is found, a nested fold is started.
+3. if a marker with a lower fold level is found, all folds up to and including
+   this level end and a fold with the specified level starts.
+
+The number indicates the fold level.  A zero cannot be used (a marker with
+level zero is ignored).  You can use "}}}" with a digit to indicate the level
+of the fold that ends.  The fold level of the following line will be one less
+than the indicated level.  Note that Vim doesn't look back to the level of the
+matching marker (that would take too much time).  Example: >
+
+	{{{1
+	fold level here is 1
+	{{{3
+	fold level here is 3
+	}}}3
+	fold level here is 2
+
+You can also use matching pairs of "{{{" and "}}}" markers to define folds.
+Each "{{{" increases the fold level by one, each "}}}" decreases the fold
+level by one.  Be careful to keep the markers matching!  Example: >
+
+	{{{
+	fold level here is 1
+	{{{
+	fold level here is 2
+	}}}
+	fold level here is 1
+
+You can mix using markers with a number and without a number.  A useful way of
+doing this is to use numbered markers for large folds, and unnumbered markers
+locally in a function.  For example use level one folds for the sections of
+your file like "structure definitions", "local variables" and "functions".
+Use level 2 markers for each definition and function,  Use unnumbered markers
+inside functions.  When you make changes in a function to split up folds, you
+don't have to renumber the markers.
+
+The markers can be set with the 'foldmarker' option.  It is recommended to
+keep this at the default value of "{{{,}}}", so that files can be exchanged
+between Vim users.  Only change it when it is required for the file (e.g., it
+contains markers from another folding editor, or the default markers cause
+trouble for the language of the file).
+
+							*fold-create-marker*
+"zf" can be used to create a fold defined by markers.  Vim will insert the
+markers for you.  Vim will append the start and end marker, as specified with
+'foldmarker'.  The markers are appended to the end of the line.
+'commentstring' is used if it isn't empty.
+This does not work properly when:
+- The line already contains a marker with a level number.  Vim then doesn't
+  know what to do.
+- Folds nearby use a level number in their marker which gets in the way.
+- The line is inside a comment, 'commentstring' isn't empty and nested
+  comments don't work.  For example with C: adding /* {{{ */ inside a comment
+  will truncate the existing comment.  Either put the marker before or after
+  the comment, or add the marker manually.
+Generally it's not a good idea to let Vim create markers when you already have
+markers with a level number.
+
+							*fold-delete-marker*
+"zd" can be used to delete a fold defined by markers.  Vim will delete the
+markers for you.  Vim will search for the start and end markers, as specified
+with 'foldmarker', at the start and end of the fold.  When the text around the
+marker matches with 'commentstring', that text is deleted as well.
+This does not work properly when:
+- A line contains more than one marker and one of them specifies a level.
+  Only the first one is removed, without checking if this will have the
+  desired effect of deleting the fold.
+- The marker contains a level number and is used to start or end several folds
+  at the same time.
+
+==============================================================================
+2. Fold commands				*fold-commands* *E490*
+
+All folding commands start with "z".  Hint: the "z" looks like a folded piece
+of paper, if you look at it from the side.
+
+
+CREATING AND DELETING FOLDS ~
+							*zf* *E350*
+zf{motion}  or
+{Visual}zf	Operator to create a fold.
+		This only works when 'foldmethod' is "manual" or "marker".
+		The new fold will be closed for the "manual" method.
+		'foldenable' will be set.
+		Also see |fold-create-marker|.
+
+							*zF*
+zF		Create a fold for N lines.  Works like "zf".
+
+:{range}fo[ld]						*:fold* *:fo*
+		Create a fold for the lines in {range}.  Works like "zf".
+
+							*zd* *E351*
+zd		Delete one fold at the cursor.  When the cursor is on a folded
+		line, that fold is deleted.  Nested folds are moved one level
+		up.  In Visual mode all folds (partially) in the selected area
+		are deleted.  Careful: This easily deletes more folds than you
+		expect and there is no undo.
+		This only works when 'foldmethod' is "manual" or "marker".
+		Also see |fold-delete-marker|.
+
+							*zD*
+zD		Delete folds recursively at the cursor.  In Visual mode all
+		folds (partially) in the selected area and all nested folds in
+		them are deleted.
+		This only works when 'foldmethod' is "manual" or "marker".
+		Also see |fold-delete-marker|.
+
+							*zE* *E352*
+zE		Eliminate all folds in the window.
+		This only works when 'foldmethod' is "manual" or "marker".
+		Also see |fold-delete-marker|.
+
+
+OPENING AND CLOSING FOLDS ~
+
+A fold smaller than 'foldminlines' will always be displayed like it was open.
+Therefore the commands below may work differently on small folds.
+
+							*zo*
+zo		Open one fold under the cursor.  When a count is given, that
+		many folds deep will be opened.  In Visual mode one level of
+		folds is opened for all lines in the selected area.
+
+							*zO*
+zO		Open all folds under the cursor recursively.  Folds that don't
+		contain the cursor line are unchanged.
+		In Visual mode it opens all folds that are in the selected
+		area, also those that are only partly selected.
+
+							*zc*
+zc		Close one fold under the cursor.  When a count is given, that
+		many folds deep are closed.  In Visual mode one level of folds
+		is closed for all lines in the selected area.
+		'foldenable' will be set.
+
+							*zC*
+zC		Close all folds under the cursor recursively.  Folds that
+		don't contain the cursor line are unchanged.
+		In Visual mode it closes all folds that are in the selected
+		area, also those that are only partly selected.
+		'foldenable' will be set.
+
+							*za*
+za		When on a closed fold: open it.  When folds are nested, you
+		may have to use "za" several times.  When a count is given,
+		that many closed folds are opened.
+		When on an open fold: close it and set 'foldenable'.  This
+		will only close one level, since using "za" again will open
+		the fold.  When a count is given that many folds will be
+		closed (that's not the same as repeating "za" that many
+		times).
+
+							*zA*
+zA		When on a closed fold: open it recursively.
+		When on an open fold: close it recursively and set
+		'foldenable'.
+
+							*zv*
+zv		View cursor line: Open just enough folds to make the line in
+		which the cursor is located not folded.
+
+							*zx*
+zx		Update folds: Undo manually opened and closed folds: re-apply
+		'foldlevel', then do "zv": View cursor line.
+
+							*zX*
+zX		Undo manually opened and closed folds: re-apply 'foldlevel'.
+
+							*zm*
+zm		Fold more: Subtract one from 'foldlevel'.  If 'foldlevel' was
+		already zero nothing happens.
+		'foldenable' will be set.
+
+							*zM*
+zM		Close all folds: set 'foldlevel' to 0.
+		'foldenable' will be set.
+
+							*zr*
+zr		Reduce folding: Add one to 'foldlevel'.
+
+							*zR*
+zR		Open all folds.  This sets 'foldlevel' to highest fold level.
+
+							*:foldo* *:foldopen*
+:{range}foldo[pen][!]
+		Open folds in {range}.  When [!] is added all folds are
+		opened.  Useful to see all the text in {range}.  Without [!]
+		one level of folds is opened.
+
+							*:foldc* *:foldclose*
+:{range}foldc[lose][!]
+		Close folds in {range}.  When [!] is added all folds are
+		closed.  Useful to hide all the text in {range}.  Without [!]
+		one level of folds is closed.
+
+							*zn*
+zn		Fold none: reset 'foldenable'.  All folds will be open.
+
+							*zN*
+zN		Fold normal: set 'foldenable'.  All folds will be as they
+		were before.
+
+							*zi*
+zi		Invert 'foldenable'.
+
+
+MOVING OVER FOLDS ~
+							*[z*
+[z		Move to the start of the current open fold.  If already at the
+		start, move to the start of the fold that contains it.  If
+		there is no containing fold, the command fails.
+		When a count is used, repeats the command N times.
+
+							*]z*
+]z		Move to the end of the current open fold.  If already at the
+		end, move to the end of the fold that contains it.  If there
+		is no containing fold, the command fails.
+		When a count is used, repeats the command N times.
+
+							*zj*
+zj		Move downwards to the start of the next fold.  A closed fold
+		is counted as one fold.
+		When a count is used, repeats the command N times.
+		This command can be used after an |operator|.
+
+							*zk*
+zk		Move upwards to the end of the previous fold.  A closed fold
+		is counted as one fold.
+		When a count is used, repeats the command N times.
+		This command can be used after an |operator|.
+
+
+EXECUTING COMMANDS ON FOLDS ~
+
+:[range]foldd[oopen] {cmd}			*:foldd* *:folddoopen*
+		Execute {cmd} on all lines that are not in a closed fold.
+		When [range] is given, only these lines are used.
+		Each time {cmd} is executed the cursor is positioned on the
+		line it is executed for.
+		This works like the ":global" command: First all lines that
+		are not in a closed fold are marked.  Then the {cmd} is
+		executed for all marked lines.  Thus when {cmd} changes the
+		folds, this has no influence on where it is executed (except
+		when lines are deleted, of course).
+		Example: >
+			:folddoopen s/end/loop_end/ge
+<		Note the use of the "e" flag to avoid getting an error message
+		where "end" doesn't match.
+
+:[range]folddoc[losed] {cmd}			*:folddoc* *:folddoclosed*
+		Execute {cmd} on all lines that are in a closed fold.
+		Otherwise like ":folddoopen".
+
+==============================================================================
+3. Fold options					*fold-options*
+
+COLORS							*fold-colors*
+
+The colors of a closed fold are set with the Folded group |hl-Folded|.  The
+colors of the fold column are set with the FoldColumn group |hl-FoldColumn|.
+Example to set the colors: >
+
+	:highlight Folded guibg=grey guifg=blue
+	:highlight FoldColumn guibg=darkgrey guifg=white
+
+
+FOLDLEVEL						*fold-foldlevel*
+
+'foldlevel' is a number option: The higher the more folded regions are open.
+When 'foldlevel' is 0, all folds are closed.
+When 'foldlevel' is positive, some folds are closed.
+When 'foldlevel' is very high, all folds are open.
+'foldlevel' is applied when it is changed.  After that manually folds can be
+opened and closed.
+When increased, folds above the new level are opened.  No manually opened
+folds will be closed.
+When decreased, folds above the new level are closed.  No manually closed
+folds will be opened.
+
+
+FOLDTEXT						*fold-foldtext*
+
+'foldtext' is a string option that specifies an expression.  This expression
+is evaluated to obtain the text displayed for a closed fold.  Example: >
+
+    :set foldtext=v:folddashes.substitute(getline(v:foldstart),'/\\*\\\|\\*/\\\|{{{\\d\\=','','g')
+
+This shows the first line of the fold, with "/*", "*/" and "{{{" removed.
+Note the use of backslashes to avoid some characters to be interpreted by the
+":set" command.  It's simpler to define a function and call that: >
+
+    :set foldtext=MyFoldText()
+    :function MyFoldText()
+    :  let line = getline(v:foldstart)
+    :  let sub = substitute(line, '/\*\|\*/\|{{{\d\=', '', 'g')
+    :  return v:folddashes . sub
+    :endfunction
+
+Evaluating 'foldtext' is done in the |sandbox|.  The current window is set to
+the window that displays the line.  Errors are ignored.
+
+The default value is |foldtext()|.  This returns a reasonable text for most
+types of folding.  If you don't like it, you can specify your own 'foldtext'
+expression.  It can use these special Vim variables:
+	v:foldstart	line number of first line in the fold
+	v:foldend	line number of last line in the fold
+	v:folddashes	a string that contains dashes to represent the
+			foldlevel.
+	v:foldlevel	the foldlevel of the fold
+
+In the result a TAB is replaced with a space and unprintable characters are
+made into printable characters.
+
+The resulting line is truncated to fit in the window, it never wraps.
+When there is room after the text, it is filled with the character specified
+by 'fillchars'.
+
+Note that backslashes need to be used for characters that the ":set" command
+handles differently: Space, backslash and double-quote. |option-backslash|
+
+
+FOLDCOLUMN						*fold-foldcolumn*
+
+'foldcolumn' is a number, which sets the width for a column on the side of the
+window to indicate folds.  When it is zero, there is no foldcolumn.  A normal
+value is 4 or 5.  The minimal useful value is 2, although 1 still provides
+some information.  The maximum is 12.
+
+An open fold is indicated with a column that has a '-' at the top and '|'
+characters below it.  This column stops where the open fold stops.  When folds
+nest, the nested fold is one character right of the fold it's contained in.
+
+A closed fold is indicated with a '+'.
+
+Where the fold column is too narrow to display all nested folds, digits are
+shown to indicate the nesting level.
+
+The mouse can also be used to open and close folds by clicking in the
+fold column:
+- Click on a '+' to open the closed fold at this row.
+- Click on any other non-blank character to close the open fold at this row.
+
+
+OTHER OPTIONS
+
+'foldenable'  'fen':	Open all folds while not set.
+'foldexpr'    'fde':	Expression used for "expr" folding.
+'foldignore'  'fdi':	Characters used for "indent" folding.
+'foldmarker'  'fmr':	Defined markers used for "marker" folding.
+'foldmethod'  'fdm':	Name of the current folding method.
+'foldminlines' 'fml':	Minimum number of screen lines for a fold to be
+			displayed closed.
+'foldnestmax' 'fdn':	Maximum nesting for "indent" and "syntax" folding.
+'foldopen'    'fdo':	Which kinds of commands open closed folds.
+'foldclose'   'fcl':	When the folds not under the cursor are closed.
+
+==============================================================================
+4. Behavior of folds					*fold-behavior*
+
+When moving the cursor upwards or downwards and when scrolling, the cursor
+will move to the first line of a sequence of folded lines.  When the cursor is
+already on a folded line, it moves to the next unfolded line or the next
+closed fold.
+
+While the cursor is on folded lines, the cursor is always displayed in the
+first column.  The ruler does show the actual cursor position, but since the
+line is folded, it cannot be displayed there.
+
+Many movement commands handle a sequence of folded lines like an empty line.
+For example, the "w" command stops once in the first column.
+
+When in Insert mode, the cursor line is never folded.  That allows you to see
+what you type!
+
+When using an operator, a closed fold is included as a whole.  Thus "dl"
+deletes the whole closed fold under the cursor.
+
+For Ex commands the range is adjusted to always start at the first line of a
+closed fold and end at the last line of a closed fold.  Thus this command: >
+	:s/foo/bar/g
+when used with the cursor on a closed fold, will replace "foo" with "bar" in
+all lines of the fold.
+This does not happen for |:folddoopen| and |:folddoclosed|.
+
+When editing a buffer that has been edited before, the last used folding
+settings are used again.  For manual folding the defined folds are restored.
+For all folding methods the manually opened and closed folds are restored.
+If this buffer has been edited in this window, the values from back then are
+used.  Otherwise the values from the window where the buffer was edited last
+are used.
+
+==============================================================================
+ vim:tw=78:ts=8:ft=help:norl:
--- /dev/null
+++ b/lib/vimfiles/doc/gui.txt
@@ -1,0 +1,993 @@
+*gui.txt*       For Vim version 7.1.  Last change: 2007 May 11
+
+
+		  VIM REFERENCE MANUAL    by Bram Moolenaar
+
+
+Vim's Graphical User Interface				*gui* *GUI*
+
+1. Starting the GUI		|gui-start|
+2. Scrollbars			|gui-scrollbars|
+3. Mouse Control		|gui-mouse|
+4. Making GUI Selections	|gui-selections|
+5. Menus			|menus|
+6. Extras			|gui-extras|
+7. Shell Commands		|gui-shell|
+
+Other GUI documentation:
+|gui_x11.txt|	For specific items of the X11 GUI.
+|gui_w32.txt|	For specific items of the Win32 GUI.
+
+{Vi does not have any of these commands}
+
+==============================================================================
+1. Starting the GUI				*gui-start* *E229* *E233*
+
+First you must make sure you actually have a version of Vim with the GUI code
+included.  You can check this with the ":version" command, it says "with xxx
+GUI", where "xxx" is X11-Motif, X11-Athena, Photon, GTK, GTK2, etc., or
+"MS-Windows 32 bit GUI version".
+
+How to start the GUI depends on the system used.  Mostly you can run the
+GUI version of Vim with:
+    gvim [options] [files...]
+
+The X11 version of Vim can run both in GUI and in non-GUI mode.  See
+|gui-x11-start|.
+
+					*gui-init* *gvimrc* *.gvimrc* *_gvimrc*
+The gvimrc file is where GUI-specific startup commands should be placed.  It
+is always sourced after the |vimrc| file.  If you have one then the $MYGVIMRC
+environment variable has its name.
+
+When the GUI starts up initializations are carried out, in this order:
+- The 'term' option is set to "builgin_gui" and terminal options are reset to
+  their default value for the GUI |terminal-options|.
+- If the system menu file exists, it is sourced.  The name of this file is
+  normally "$VIMRUNTIME/menu.vim".  You can check this with ":version".  Also
+  see |$VIMRUNTIME|.  To skip loading the system menu include 'M' in
+  'guioptions'.				*buffers-menu* *no_buffers_menu*
+  The system menu file includes a "Buffers" menu.  If you don't want this, set
+  the "no_buffers_menu" variable in your .vimrc (not .gvimrc!): >
+	:let no_buffers_menu = 1
+< NOTE: Switching on syntax highlighting also loads the menu file, thus
+  disabling the Buffers menu must be done before ":syntax on".
+  The path names are truncated to 35 characters.  You can truncate them at a
+  different length, for example 50, like this: >
+	:let bmenu_max_pathlen = 50
+- If the "-U {gvimrc}" command-line option has been used when starting Vim,
+  the {gvimrc} file will be read for initializations.  The following
+  initializations are skipped.  When {gvimrc} is "NONE" no file will be read
+  for initializations.
+- For Unix and MS-Windows, if the system gvimrc exists, it is sourced.  The
+  name of this file is normally "$VIM/gvimrc".  You can check this with
+  ":version".  Also see |$VIM|.
+- The following are tried, and only the first one that exists is used:
+  - If the GVIMINIT environment variable exists and is not empty, it is
+    executed as an Ex command.
+  - If the user gvimrc file exists, it is sourced.  The name of this file is
+    normally "$HOME/.gvimrc".  You can check this with ":version".
+  - For Win32, when $HOME is not set, "$VIM\_gvimrc" is used.
+  - When a "_gvimrc" file is not found, ".gvimrc" is tried too.  And vice
+    versa.
+  The name of the first file found is stored in $MYGVIMRC, unless it was
+  already set.
+- If the 'exrc' option is set (which is NOT the default) the file ./.gvimrc
+  is sourced, if it exists and isn't the same file as the system or user
+  gvimrc file.  If this file is not owned by you, some security restrictions
+  apply.  When ".gvimrc" is not found, "_gvimrc" is tried too.  For Macintosh
+  and DOS/Win32 "_gvimrc" is tried first.
+
+NOTE: All but the first one are not carried out if Vim was started with
+"-u NONE" and no "-U" argument was given, or when started with "-U NONE".
+
+All this happens AFTER the normal Vim initializations, like reading your
+.vimrc file.  See |initialization|.
+But the GUI window is only opened after all the initializations have been
+carried out.  If you want some commands to be executed just after opening the
+GUI window, use the |GUIEnter| autocommand event.  Example: >
+	:autocmd GUIEnter * winpos 100 50
+
+You can use the gvimrc files to set up your own customized menus (see |:menu|)
+and initialize other things that you may want to set up differently from the
+terminal version.
+
+Recommended place for your personal GUI initializations:
+	Unix		    $HOME/.gvimrc
+	OS/2		    $HOME/.gvimrc or $VIM/.gvimrc
+	MS-DOS and Win32    $HOME/_gvimrc or $VIM/_gvimrc
+	Amiga		    s:.gvimrc or $VIM/.gvimrc
+
+There are a number of options which only have meaning in the GUI version of
+Vim.  These are 'guicursor', 'guifont', 'guipty' and 'guioptions'.  They are
+documented in |options.txt| with all the other options.
+
+If using the Motif or Athena version of the GUI (but not for the GTK+ or
+Win32 version), a number of X resources are available.  See |gui-resources|.
+
+Another way to set the colors for different occasions is with highlight
+groups.  The "Normal" group is used to set the background and foreground
+colors.  Example (which looks nice): >
+
+	:highlight Normal guibg=grey90
+
+The "guibg" and "guifg" settings override the normal background and
+foreground settings.  The other settings for the Normal highlight group are
+not used.  Use the 'guifont' option to set the font.
+
+Also check out the 'guicursor' option, to set the colors for the cursor in
+various modes.
+
+Vim tries to make the window fit on the screen when it starts up.  This avoids
+that you can't see part of it.  On the X Window System this requires a bit of
+guesswork.  You can change the height that is used for the window title and a
+task bar with the 'guiheadroom' option.
+
+						*:winp* *:winpos* *E188*
+:winp[os]
+		Display current position of the top left corner of the GUI vim
+		window in pixels.  Does not work in all versions.
+
+:winp[os] {X} {Y}							*E466*
+		Put the GUI vim window at the given {X} and {Y} coordinates.
+		The coordinates should specify the position in pixels of the
+		top left corner of the window.  Does not work in all versions.
+		Does work in an (new) xterm |xterm-color|.
+		When the GUI window has not been opened yet, the values are
+		remembered until the window is opened.  The position is
+		adjusted to make the window fit on the screen (if possible).
+
+						    *:win* *:winsize* *E465*
+:win[size] {width} {height}
+		Set the window height to {width} by {height} characters.
+		Obsolete, use ":set lines=11 columns=22".
+		If you get less lines than expected, check the 'guiheadroom'
+		option.
+
+If you are running the X Window System, you can get information about the
+window Vim is running in with this command: >
+	:!xwininfo -id $WINDOWID
+
+==============================================================================
+2. Scrollbars						*gui-scrollbars*
+
+There are vertical scrollbars and a horizontal scrollbar.  You may
+configure which ones appear with the 'guioptions' option.
+
+The interface looks like this (with ":set guioptions=mlrb"):
+
+		       +------------------------------+
+		       | File  Edit		 Help | <- Menu bar (m)
+		       +-+--------------------------+-+
+		       |^|			    |^|
+		       |#| Text area.		    |#|
+		       | |			    | |
+		       |v|__________________________|v|
+ Normal status line -> |-+ File.c	       5,2  +-|
+ between Vim windows   |^|""""""""""""""""""""""""""|^|
+		       | |			    | |
+		       | | Another file buffer.     | |
+		       | |			    | |
+		       |#|			    |#|
+ Left scrollbar (l) -> |#|			    |#| <- Right
+		       |#|			    |#|    scrollbar (r)
+		       | |			    | |
+		       |v|			    |v|
+		       +-+--------------------------+-+
+		       | |< ####		   >| | <- Bottom
+		       +-+--------------------------+-+    scrollbar (b)
+
+Any of the scrollbar or menu components may be turned off by not putting the
+appropriate letter in the 'guioptions' string.  The bottom scrollbar is
+only useful when 'nowrap' is set.
+
+
+VERTICAL SCROLLBARS					*gui-vert-scroll*
+
+Each Vim window has a scrollbar next to it which may be scrolled up and down
+to move through the text in that buffer.  The size of the scrollbar-thumb
+indicates the fraction of the buffer which can be seen in the window.
+When the scrollbar is dragged all the way down, the last line of the file
+will appear in the top of the window.
+
+If a window is shrunk to zero height (by the growth of another window) its
+scrollbar disappears.  It reappears when the window is restored.
+
+If a window is vertically split, it will get a scrollbar when it is the
+current window and when, taking the middle of the current window and drawing a
+vertical line, this line goes through the window.
+When there are scrollbars on both sides, and the middle of the current window
+is on the left half, the right scrollbar column will contain scrollbars for
+the rightmost windows.  The same happens on the other side.
+
+
+HORIZONTAL SCROLLBARS					*gui-horiz-scroll*
+
+The horizontal scrollbar (at the bottom of the Vim GUI) may be used to
+scroll text sideways when the 'wrap' option is turned off.  The
+scrollbar-thumb size is such that the text of the longest visible line may be
+scrolled as far as possible left and right.  The cursor is moved when
+necessary, it must remain on a visible character (unless 'virtualedit' is
+set).
+
+Computing the length of the longest visible line takes quite a bit of
+computation, and it has to be done every time something changes.  If this
+takes too much time or you don't like the cursor jumping to another line,
+include the 'h' flag in 'guioptions'.  Then the scrolling is limited by the
+text of the current cursor line.
+
+							*athena-intellimouse*
+If you have an Intellimouse and an X server that supports using the wheel,
+then you can use the wheel to scroll the text up and down in gvim.  This works
+with XFree86 4.0 and later, and with some older versions when you add patches.
+See |scroll-mouse-wheel|.
+
+For older versions of XFree86 you must patch your X server.  The following
+page has a bit of information about using the Intellimouse on Linux as well as
+links to the patches and X server binaries (may not have the one you need
+though):
+    http://www.inria.fr/koala/colas/mouse-wheel-scroll/
+
+==============================================================================
+3. Mouse Control					*gui-mouse*
+
+The mouse only works if the appropriate flag in the 'mouse' option is set.
+When the GUI is switched on, and 'mouse' wasn't set yet, the 'mouse' option is
+automatically set to "a", enabling it for all modes except for the
+|hit-enter| prompt.  If you don't want this, a good place to change the
+'mouse' option is the "gvimrc" file.
+
+Other options that are relevant:
+'mousefocus'	window focus follows mouse pointer |gui-mouse-focus|
+'mousemodel'	what mouse button does which action
+'mousehide'	hide mouse pointer while typing text
+'selectmode'	whether to start Select mode or Visual mode
+
+A quick way to set these is with the ":behave" command.
+							*:behave* *:be*
+:be[have] {model}	Set behavior for mouse and selection.  Valid
+			arguments are:
+			   mswin	MS-Windows behavior
+			   xterm	Xterm behavior
+
+			Using ":behave" changes these options:
+			option		mswin			xterm	~
+			'selectmode'	"mouse,key"		""
+			'mousemodel'	"popup"			"extend"
+			'keymodel'	"startsel,stopsel"	""
+			'selection'	"exclusive"		"inclusive"
+
+In the $VIMRUNTIME directory, there is a script called |mswin.vim|, which will
+also map a few keys to the MS-Windows cut/copy/paste commands.  This is NOT
+compatible, since it uses the CTRL-V, CTRL-X and CTRL-C keys.  If you don't
+mind, use this command: >
+	:so $VIMRUNTIME/mswin.vim
+
+For scrolling with a wheel on a mouse, see |scroll-mouse-wheel|.
+
+
+3.1 Moving Cursor with Mouse				*gui-mouse-move*
+
+Click the left mouse button somewhere in a text buffer where you want the
+cursor to go, and it does!
+This works in	    when 'mouse' contains ~
+Normal mode	    'n' or 'a'
+Visual mode	    'v' or 'a'
+Insert mode	    'i' or 'a'
+
+Select mode is handled like Visual mode.
+
+You may use this with an operator such as 'd' to delete text from the current
+cursor position to the position you point to with the mouse.  That is, you hit
+'d' and then click the mouse somewhere.
+
+							*gui-mouse-focus*
+The 'mousefocus' option can be set to make the keyboard focus follow the
+mouse pointer.  This means that the window where the mouse pointer is, is the
+active window.  Warning: this doesn't work very well when using a menu,
+because the menu command will always be applied to the top window.
+
+If you are on the ':' line (or '/' or '?'), then clicking the left or right
+mouse button will position the cursor on the ':' line (if 'mouse' contains
+'c', 'a' or 'A').
+
+In any situation the middle mouse button may be clicked to paste the current
+selection.
+
+
+3.2 Selection with Mouse				*gui-mouse-select*
+
+The mouse can be used to start a selection.  How depends on the 'mousemodel'
+option:
+'mousemodel' is "extend": use the right mouse button
+'mousemodel' is "popup":  use the left mouse button, while keeping the Shift
+key pressed.
+
+If there was no selection yet, this starts a selection from the old cursor
+position to the position pointed to with the mouse.  If there already is a
+selection then the closest end will be extended.
+
+If 'selectmode' contains "mouse", then the selection will be in Select mode.
+This means that typing normal text will replace the selection.  See
+|Select-mode|.  Otherwise, the selection will be in Visual mode.
+
+Double clicking may be done to make the selection word-wise, triple clicking
+makes it line-wise, and quadruple clicking makes it rectangular block-wise.
+
+See |gui-selections| on how the selection is used.
+
+
+3.3 Other Text Selection with Mouse		*gui-mouse-modeless*
+						*modeless-selection*
+A different kind of selection is used when:
+- in Command-line mode
+- in the Command-line window and pointing in another window
+- at the |hit-enter| prompt
+- whenever the current mode is not in the 'mouse' option
+- when holding the CTRL and SHIFT keys in the GUI
+Since Vim continues like the selection isn't there, and there is no mode
+associated with the selection, this is called modeless selection.  Any text in
+the Vim window can be selected.  Select the text by pressing the left mouse
+button at the start, drag to the end and release.  To extend the selection,
+use the right mouse button when 'mousemodel' is "extend", or the left mouse
+button with the shift key pressed when 'mousemodel' is "popup".
+The middle mouse button pastes the text.
+The selection is removed when the selected text is scrolled or changed.
+On the command line CTRL-Y can be used to copy the selection into the
+clipboard.  To do this from Insert mode, use CTRL-O : CTRL-Y <CR>.
+
+
+3.4 Using Mouse on Status Lines				*gui-mouse-status*
+
+Clicking the left or right mouse button on the status line below a Vim
+window makes that window the current window.  This actually happens on button
+release (to be able to distinguish a click from a drag action).
+
+With the left mouse button a status line can be dragged up and down, thus
+resizing the windows above and below it.  This does not change window focus.
+
+The same can be used on the vertical separator: click to give the window left
+of it focus, drag left and right to make windows wider and narrower.
+
+
+3.5 Various Mouse Clicks				*gui-mouse-various*
+
+    <S-LeftMouse>	Search forward for the word under the mouse click.
+			When 'mousemodel' is "popup" this starts or extends a
+			selection.
+    <S-RightMouse>	Search backward for the word under the mouse click.
+    <C-LeftMouse>	Jump to the tag name under the mouse click.
+    <C-RightMouse>	Jump back to position before the previous tag jump
+			(same as "CTRL-T")
+
+
+3.6 Mouse Mappings					*gui-mouse-mapping*
+
+The mouse events, complete with modifiers, may be mapped.  Eg: >
+   :map <S-LeftMouse>     <RightMouse>
+   :map <S-LeftDrag>      <RightDrag>
+   :map <S-LeftRelease>   <RightRelease>
+   :map <2-S-LeftMouse>   <2-RightMouse>
+   :map <2-S-LeftDrag>    <2-RightDrag>
+   :map <2-S-LeftRelease> <2-RightRelease>
+   :map <3-S-LeftMouse>   <3-RightMouse>
+   :map <3-S-LeftDrag>    <3-RightDrag>
+   :map <3-S-LeftRelease> <3-RightRelease>
+   :map <4-S-LeftMouse>   <4-RightMouse>
+   :map <4-S-LeftDrag>    <4-RightDrag>
+   :map <4-S-LeftRelease> <4-RightRelease>
+These mappings make selection work the way it probably should in a Motif
+application, with shift-left mouse allowing for extending the visual area
+rather than the right mouse button.
+
+Mouse mapping with modifiers does not work for modeless selection.
+
+
+3.7 Drag and drop						*drag-n-drop*
+
+You can drag and drop one or more files into the Vim window, where they will
+be opened as if a |:drop| command was used.
+
+If you hold down Shift while doing this, Vim changes to the first dropped
+file's directory.  If you hold Ctrl Vim will always split a new window for the
+file.  Otherwise it's only done if the current buffer has been changed.
+
+You can also drop a directory on Vim.  This starts the explorer plugin for
+that directory (assuming it was enabled, otherwise you'll get an error
+message).  Keep Shift pressed to change to the directory instead.
+
+If Vim happens to be editing a command line, the names of the dropped files
+and directories will be inserted at the cursor.  This allows you to use these
+names with any Ex command.  Special characters (space, tab, double quote and
+'|'; backslash on non-MS-Windows systems) will be escaped.
+
+==============================================================================
+4. Making GUI Selections				*gui-selections*
+
+							*quotestar*
+You may make selections with the mouse (see |gui-mouse-select|), or by using
+Vim's Visual mode (see |v|).  If 'a' is present in 'guioptions', then
+whenever a selection is started (Visual or Select mode), or when the selection
+is changed, Vim becomes the owner of the windowing system's primary selection
+(on MS-Windows the |gui-clipboard| is used; under X11, the |x11-selection| is
+used - you should read whichever of these is appropriate now).
+
+							*clipboard*
+There is a special register for storing this selection, it is the "*
+register.  Nothing is put in here unless the information about what text is
+selected is about to change (e.g. with a left mouse click somewhere), or when
+another application wants to paste the selected text.  Then the text is put
+in the "* register.  For example, to cut a line and make it the current
+selection/put it on the clipboard: >
+
+	"*dd
+
+Similarly, when you want to paste a selection from another application, e.g.,
+by clicking the middle mouse button, the selection is put in the "* register
+first, and then 'put' like any other register.  For example, to put the
+selection (contents of the clipboard): >
+
+	"*p
+
+When using this register under X11, also see |x11-selection|.  This also
+explains the related "+ register.
+
+Note that when pasting text from one Vim into another separate Vim, the type
+of selection (character, line, or block) will also be copied.  For other
+applications the type is always character.  However, if the text gets
+transferred via the |x11-cut-buffer|, the selection type is ALWAYS lost.
+
+When the "unnamed" string is included in the 'clipboard' option, the unnamed
+register is the same as the "* register.  Thus you can yank to and paste the
+selection without prepending "* to commands.
+
+==============================================================================
+5. Menus						*menus*
+
+For an introduction see |usr_42.txt| in the user manual.
+
+
+5.1 Using Menus						*using-menus*
+
+Basically, menus can be used just like mappings.  You can define your own
+menus, as many as you like.
+Long-time Vim users won't use menus much.  But the power is in adding your own
+menus and menu items.  They are most useful for things that you can't remember
+what the key sequence was.
+
+For creating menus in a different language, see |:menutrans|.
+
+							*menu.vim*
+The default menus are read from the file "$VIMRUNTIME/menu.vim".  See
+|$VIMRUNTIME| for where the path comes from.  You can set up your own menus.
+Starting off with the default set is a good idea.  You can add more items, or,
+if you don't like the defaults at all, start with removing all menus
+|:unmenu-all|.  You can also avoid the default menus being loaded by adding
+this line to your .vimrc file (NOT your .gvimrc file!): >
+	:let did_install_default_menus = 1
+If you also want to avoid the Syntax menu: >
+	:let did_install_syntax_menu = 1
+If you do want the Syntax menu but not all the entries for each available
+syntax file (which take quite a bit of time to load): >
+	:let skip_syntax_sel_menu = 1
+<
+							*console-menus*
+Although this documentation is in the GUI section, you can actually use menus
+in console mode too.  You will have to load |menu.vim| explicitly then, it is
+not done by default.  You can use the |:emenu| command and command-line
+completion with 'wildmenu' to access the menu entries almost like a real menu
+system.  To do this, put these commands in your .vimrc file: >
+	:source $VIMRUNTIME/menu.vim
+	:set wildmenu
+	:set cpo-=<
+	:set wcm=<C-Z>
+	:map <F4> :emenu <C-Z>
+Pressing <F4> will start the menu.  You can now use the cursor keys to select
+a menu entry.  Hit <Enter> to execute it.  Hit <Esc> if you want to cancel.
+This does require the |+menu| feature enabled at compile time.
+
+							*tear-off-menus*
+GTK+ and Motif support Tear-off menus.  These are sort of sticky menus or
+pop-up menus that are present all the time.  If the resizing does not work
+correctly, this may be caused by using something like "Vim*geometry" in the
+defaults.  Use "Vim.geometry" instead.
+
+The Win32 GUI version emulates Motif's tear-off menus.  Actually, a Motif user
+will spot the differences easily, but hopefully they're just as useful.  You
+can also use the |:tearoff| command together with |hidden-menus| to create
+floating menus that do not appear on the main menu bar.
+
+
+5.2 Creating New Menus					*creating-menus*
+
+				*:me*  *:menu*  *:noreme*  *:noremenu*
+				*:am*  *:amenu* *:an*      *:anoremenu*
+				*:nme* *:nmenu* *:nnoreme* *:nnoremenu*
+				*:ome* *:omenu* *:onoreme* *:onoremenu*
+				*:vme* *:vmenu* *:vnoreme* *:vnoremenu*
+				*:xme* *:xmenu* *:xnoreme* *:xnoremenu*
+				*:sme* *:smenu* *:snoreme* *:snoremenu*
+				*:ime* *:imenu* *:inoreme* *:inoremenu*
+				*:cme* *:cmenu* *:cnoreme* *:cnoremenu*
+				*E330* *E327* *E331* *E336* *E333*
+				*E328* *E329* *E337* *E792*
+To create a new menu item, use the ":menu" commands.  They are mostly like
+the ":map" set of commands but the first argument is a menu item name, given
+as a path of menus and submenus with a '.' between them, e.g.: >
+
+   :menu File.Save  :w<CR>
+   :inoremenu File.Save  <C-O>:w<CR>
+   :menu Edit.Big\ Changes.Delete\ All\ Spaces  :%s/[ ^I]//g<CR>
+
+This last one will create a new item in the menu bar called "Edit", holding
+the mouse button down on this will pop up a menu containing the item
+"Big Changes", which is a sub-menu containing the item "Delete All Spaces",
+which when selected, performs the operation.
+
+Special characters in a menu name:
+
+	&	The next character is the shortcut key.  Make sure each
+		shortcut key is only used once in a (sub)menu.  If you want to
+		insert a literal "&" in the menu name use "&&".
+	<Tab>	Separates the menu name from right-aligned text.  This can be
+		used to show the equivalent typed command.  The text "<Tab>"
+		can be used here for convenience.  If you are using a real
+		tab, don't forget to put a backslash before it!
+Example: >
+
+   :amenu &File.&Open<Tab>:e  :browse e<CR>
+
+[typed literally]
+With the shortcut "F" (while keeping the <Alt> key pressed), and then "O",
+this menu can be used.  The second part is shown as "Open     :e".  The ":e"
+is right aligned, and the "O" is underlined, to indicate it is the shortcut.
+
+The ":amenu" command can be used to define menu entries for all modes at once.
+To make the command work correctly, a character is automatically inserted for
+some modes:
+	mode		inserted	appended	~
+	Normal		nothing		nothing
+	Visual		<C-C>		<C-\><C-G>
+	Insert		<C-O>
+	Cmdline		<C-C>		<C-\><C-G>
+	Op-pending	<C-C>		<C-\><C-G>
+
+Appending CTRL-\ CTRL-G is for going back to insert mode when 'insertmode' is
+set. |CTRL-\_CTRL-G|
+
+Example: >
+
+   :amenu File.Next	:next^M
+
+is equal to: >
+
+   :nmenu File.Next	:next^M
+   :vmenu File.Next	^C:next^M^\^G
+   :imenu File.Next	^O:next^M
+   :cmenu File.Next	^C:next^M^\^G
+   :omenu File.Next	^C:next^M^\^G
+
+Careful: In Insert mode this only works for a SINGLE Normal mode command,
+because of the CTRL-O.  If you have two or more commands, you will need to use
+the ":imenu" command.  For inserting text in any mode, you can use the
+expression register: >
+
+   :amenu Insert.foobar   "='foobar'<CR>P
+
+Note that the '<' and 'k' flags in 'cpoptions' also apply here (when
+included they make the <> form and raw key codes not being recognized).
+
+Note that <Esc> in Cmdline mode executes the command, like in a mapping.  This
+is Vi compatible.  Use CTRL-C to quit Cmdline mode.
+
+						*:menu-<silent>* *:menu-silent*
+To define a menu which will not be echoed on the command line, add
+"<silent>" as the first argument.  Example: >
+	:menu <silent> Settings.Ignore\ case  :set ic<CR>
+The ":set ic" will not be echoed when using this menu.  Messages from the
+executed command are still given though.  To shut them up too, add a ":silent"
+in the executed command: >
+	:menu <silent> Search.Header :exe ":silent normal /Header\r"<CR>
+"<silent>" may also appear just after "<special>" or "<script>".
+
+					*:menu-<special>* *:menu-special*
+Define a menu with <> notation for special keys, even though the "<" flag
+may appear in 'cpoptions'.  This is useful if the side effect of setting
+'cpoptions' is not desired.  Example: >
+	:menu <special> Search.Header /Header<CR>
+"<special>" must appear as the very first argument to the ":menu" command or
+just after "<silent>" or "<script>".
+
+						*:menu-<script>* *:menu-script*
+The "to" part of the menu will be inspected for mappings.  If you don't want
+this, use the ":noremenu" command (or the similar one for a specific mode).
+If you do want to use script-local mappings, add "<script>" as the very first
+argument to the ":menu" command or just after "<silent>" or "<special>".
+
+							*menu-priority*
+You can give a priority to a menu.  Menus with a higher priority go more to
+the right.  The priority is given as a number before the ":menu" command.
+Example: >
+	:80menu Buffer.next :bn<CR>
+
+The default menus have these priorities:
+	File		10
+	Edit		20
+	Tools		40
+	Syntax		50
+	Buffers		60
+	Window		70
+	Help		9999
+
+When no or zero priority is given, 500 is used.
+The priority for the PopUp menu is not used.
+
+The Help menu will be placed on the far right side of the menu bar on systems
+which support this (Motif and GTK+).  For GTK+ 2, this is not done anymore
+because right-aligning the Help menu is now discouraged UI design.
+
+You can use a priority higher than 9999, to make it go after the Help menu,
+but that is non-standard and is discouraged.  The highest possible priority is
+about 32000.  The lowest is 1.
+
+							*sub-menu-priority*
+The same mechanism can be used to position a sub-menu.  The priority is then
+given as a dot-separated list of priorities, before the menu name: >
+	:menu 80.500 Buffer.next :bn<CR>
+Giving the sub-menu priority is only needed when the item is not to be put
+in a normal position.  For example, to put a sub-menu before the other items: >
+	:menu 80.100 Buffer.first :brew<CR>
+Or to put a sub-menu after the other items, and further items with default
+priority will be put before it: >
+	:menu 80.900 Buffer.last :blast<CR>
+When a number is missing, the default value 500 will be used: >
+	:menu .900 myMenu.test :echo "text"<CR>
+The menu priority is only used when creating a new menu.  When it already
+existed, e.g., in another mode, the priority will not change.  Thus, the
+priority only needs to be given the first time a menu is used.
+An exception is the PopUp menu.  There is a separate menu for each mode
+(Normal, Op-pending, Visual, Insert, Cmdline).  The order in each of these
+menus can be different.  This is different from menu-bar menus, which have
+the same order for all modes.
+NOTE: sub-menu priorities currently don't work for all versions of the GUI.
+
+							*menu-separator* *E332*
+Menu items can be separated by a special item that inserts some space between
+items.  Depending on the system this is displayed as a line or a dotted line.
+These items must start with a '-' and end in a '-'.  The part in between is
+used to give it a unique name.  Priorities can be used as with normal items.
+Example: >
+	:menu Example.item1	:do something
+	:menu Example.-Sep-	:
+	:menu Example.item2	:do something different
+Note that the separator also requires a rhs.  It doesn't matter what it is,
+because the item will never be selected.  Use a single colon to keep it
+simple.
+
+							*gui-toolbar*
+The toolbar is currently available in the Win32, Athena, Motif, GTK+ (X11),
+and Photon GUI.  It should turn up in other GUIs in due course.  The
+default toolbar is setup in menu.vim.
+The display of the toolbar is controlled by the 'guioptions' letter 'T'.  You
+can thus have menu & toolbar together, or either on its own, or neither.
+The appearance is controlled by the 'toolbar' option.  You can chose between
+an image, text or both.
+
+							*toolbar-icon*
+The toolbar is defined as a special menu called ToolBar, which only has one
+level.  Vim interprets the items in this menu as follows:
+1)  If an "icon=" argument was specified, the file with this name is used.
+    The file can either be specified with the full path or with the base name.
+    In the last case it is searched for in the "bitmaps" directory in
+    'runtimepath', like in point 3.  Examples: >
+	:amenu icon=/usr/local/pixmaps/foo_icon.xpm ToolBar.Foo :echo "Foo"<CR>
+	:amenu icon=FooIcon ToolBar.Foo :echo "Foo"<CR>
+<   Note that in the first case the extension is included, while in the second
+    case it is omitted.
+    If the file cannot be opened the next points are tried.
+    A space in the file name must be escaped with a backslash.
+    A menu priority must come _after_ the icon argument: >
+	:amenu icon=foo 1.42 ToolBar.Foo :echo "42!"<CR>
+2)  An item called 'BuiltIn##', where ## is a number, is taken as number ## of
+    the built-in bitmaps available in Vim.  Currently there are 31 numbered
+    from 0 to 30 which cover most common editing operations |builtin-tools|. >
+	:amenu ToolBar.BuiltIn22 :call SearchNext("back")<CR>
+3)  An item with another name is first searched for in the directory
+    "bitmaps" in 'runtimepath'.  If found, the bitmap file is used as the
+    toolbar button image.  Note that the exact filename is OS-specific: For
+    example, under Win32 the command >
+	:amenu ToolBar.Hello :echo "hello"<CR>
+<   would find the file 'hello.bmp'.  Under GTK+/X11 it is 'Hello.xpm'.  With
+    GTK+ 2 the files 'Hello.png', 'Hello.xpm' and 'Hello.bmp' are checked for
+    existence, and the first one found would be used.
+    For MS-Windows and GTK+ 2 the bitmap is scaled to fit the button.  For
+    MS-Windows a size of 18 by 18 pixels works best.
+    For MS-Windows the bitmap should have 16 colors with the standard palette.
+    The light grey pixels will be changed to the Window frame color and the
+    dark grey pixels to the window shadow color.  More colors might also work,
+    depending on your system.
+4)  If the bitmap is still not found, Vim checks for a match against its list
+    of built-in names.  Each built-in button image has a name.
+    So the command >
+	:amenu ToolBar.Open :e
+<   will show the built-in "open a file" button image if no open.bmp exists.
+    All the built-in names can be seen used in menu.vim.
+5)  If all else fails, a blank, but functioning, button is displayed.
+
+							*builtin-tools*
+nr  Name		Normal action  ~
+00  New			open new window
+01  Open		browse for file to open in current window
+02  Save		write buffer to file
+03  Undo		undo last change
+04  Redo		redo last undone change
+05  Cut			delete selected text to clipboard
+06  Copy		copy selected text to clipboard
+07  Paste		paste text from clipboard
+08  Print		print current buffer
+09  Help		open a buffer on Vim's builtin help
+10  Find		start a search command
+11  SaveAll		write all modified buffers to file
+12  SaveSesn		write session file for current situation
+13  NewSesn		write new session file
+14  LoadSesn		load session file
+15  RunScript		browse for file to run as a Vim script
+16  Replace		prompt for substitute command
+17  WinClose		close current window
+18  WinMax		make current window use many lines
+19  WinMin		make current window use few lines
+20  WinSplit		split current window
+21  Shell		start a shell
+22  FindPrev		search again, backward
+23  FindNext		search again, forward
+24  FindHelp		prompt for word to search help for
+25  Make		run make and jump to first error
+26  TagJump		jump to tag under the cursor
+27  RunCtags		build tags for files in current directory
+28  WinVSplit		split current window vertically
+29  WinMaxWidth		make current window use many columns
+30  WinMinWidth		make current window use few columns
+
+					*hidden-menus* *win32-hidden-menus*
+In the Win32 and GTK+ GUI, starting a menu name with ']' excludes that menu
+from the main menu bar.  You must then use the |:popup| or |:tearoff| command
+to display it.
+
+							*popup-menu*
+In the Win32, GTK+, Motif, Athena and Photon GUI, you can define the
+special menu "PopUp".  This is the menu that is displayed when the right mouse
+button is pressed, if 'mousemodel' is set to popup or popup_setpos.
+
+
+5.3 Showing What Menus Are Mapped To			*showing-menus*
+
+To see what an existing menu is mapped to, use just one argument after the
+menu commands (just like you would with the ":map" commands).  If the menu
+specified is a submenu, then all menus under that hierarchy will be shown.
+If no argument is given after :menu at all, then ALL menu items are shown
+for the appropriate mode (e.g., Command-line mode for :cmenu).
+
+Special characters in the list, just before the rhs:
+*	The menu was defined with "nore" to disallow remapping.
+&	The menu was defined with "<script>" to allow remapping script-local
+	mappings only.
+-	The menu was disabled.
+
+Note that hitting <Tab> while entering a menu name after a menu command may
+be used to complete the name of the menu item.
+
+
+5.4 Executing Menus					*execute-menus*
+
+						*:em*  *:emenu* *E334* *E335*
+:[range]em[enu] {menu}		Execute {menu} from the command line.
+				The default is to execute the Normal mode
+				menu.  If a range is specified, it executes
+				the Visual mode menu.
+				If used from <c-o>, it executes the
+				insert-mode menu Eg: >
+	:emenu File.Exit
+
+If the console-mode vim has been compiled with WANT_MENU defined, you can
+use :emenu to access useful menu items you may have got used to from GUI
+mode.  See 'wildmenu' for an option that works well with this.  See
+|console-menus| for an example.
+
+When using a range, if the lines match with '<,'>, then the menu is executed
+using the last visual selection.
+
+
+5.5 Deleting Menus					*delete-menus*
+
+						*:unme*  *:unmenu*
+						*:aun*   *:aunmenu*
+						*:nunme* *:nunmenu*
+						*:ounme* *:ounmenu*
+						*:vunme* *:vunmenu*
+						*:xunme* *:xunmenu*
+						*:sunme* *:sunmenu*
+						*:iunme* *:iunmenu*
+						*:cunme* *:cunmenu*
+To delete a menu item or a whole submenu, use the unmenu commands, which are
+analogous to the unmap commands.  Eg: >
+    :unmenu! Edit.Paste
+
+This will remove the Paste item from the Edit menu for Insert and
+Command-line modes.
+
+Note that hitting <Tab> while entering a menu name after an umenu command
+may be used to complete the name of the menu item for the appropriate mode.
+
+To remove all menus use:			*:unmenu-all*  >
+	:unmenu *	" remove all menus in Normal and visual mode
+	:unmenu! *	" remove all menus in Insert and Command-line mode
+	:aunmenu *	" remove all menus in all modes
+
+If you want to get rid of the menu bar: >
+	:set guioptions-=m
+
+
+5.6 Disabling Menus					*disable-menus*
+
+						*:menu-disable* *:menu-enable*
+If you do not want to remove a menu, but disable it for a moment, this can be
+done by adding the "enable" or "disable" keyword to a ":menu" command.
+Examples: >
+	:menu disable &File.&Open\.\.\.
+	:amenu enable *
+	:amenu disable &Tools.*
+
+The command applies to the modes as used with all menu commands.  Note that
+characters like "&" need to be included for translated names to be found.
+When the argument is "*", all menus are affected.  Otherwise the given menu
+name and all existing submenus below it are affected.
+
+
+5.7 Examples for Menus					*menu-examples*
+
+Here is an example on how to add menu items with menu's!  You can add a menu
+item for the keyword under the cursor.  The register "z" is used. >
+
+  :nmenu Words.Add\ Var		wb"zye:menu! Words.<C-R>z <C-R>z<CR>
+  :nmenu Words.Remove\ Var	wb"zye:unmenu! Words.<C-R>z<CR>
+  :vmenu Words.Add\ Var		"zy:menu! Words.<C-R>z <C-R>z <CR>
+  :vmenu Words.Remove\ Var	"zy:unmenu! Words.<C-R>z<CR>
+  :imenu Words.Add\ Var		<Esc>wb"zye:menu! Words.<C-R>z <C-R>z<CR>a
+  :imenu Words.Remove\ Var	<Esc>wb"zye:unmenu! Words.<C-R>z<CR>a
+
+(the rhs is in <> notation, you can copy/paste this text to try out the
+mappings, or put these lines in your gvimrc; "<C-R>" is CTRL-R, "<CR>" is
+the <CR> key.  |<>|)
+
+
+5.8 Tooltips & Menu tips
+
+See section |42.4| in the user manual.
+
+							*:tmenu* *:tm*
+:tm[enu] {menupath} {rhs}	Define a tip for a menu or tool.  {only in
+				X11 and Win32 GUI}
+
+:tm[enu] [menupath]		List menu tips. {only in X11 and Win32 GUI}
+
+							*:tunmenu* *:tu*
+:tu[nmenu] {menupath}		Remove a tip for a menu or tool.
+				{only in X11 and Win32 GUI}
+
+When a tip is defined for a menu item, it appears in the command-line area
+when the mouse is over that item, much like a standard Windows menu hint in
+the status bar.  (Except when Vim is in Command-line mode, when of course
+nothing is displayed.)
+When a tip is defined for a ToolBar item, it appears as a tooltip when the
+mouse pauses over that button, in the usual fashion.  Use the |hl-Tooltip|
+highlight group to change its colors.
+
+A "tip" can be defined for each menu item.  For example, when defining a menu
+item like this: >
+	:amenu MyMenu.Hello :echo "Hello"<CR>
+The tip is defined like this: >
+	:tmenu MyMenu.Hello Displays a greeting.
+And delete it with: >
+	:tunmenu MyMenu.Hello
+
+Tooltips are currently only supported for the X11 and Win32 GUI.  However, they
+should appear for the other gui platforms in the not too distant future.
+
+The ":tmenu" command works just like other menu commands, it uses the same
+arguments.  ":tunmenu" deletes an existing menu tip, in the same way as the
+other unmenu commands.
+
+If a menu item becomes invalid (i.e. its actions in all modes are deleted) Vim
+deletes the menu tip (and the item) for you.  This means that :aunmenu deletes
+a menu item - you don't need to do a :tunmenu as well.
+
+
+5.9 Popup Menus
+
+In the Win32 and GTK+ GUI, you can cause a menu to popup at the cursor.
+This behaves similarly to the PopUp menus except that any menu tree can
+be popped up.
+
+This command is for backwards compatibility, using it is discouraged, because
+it behaves in a strange way.
+
+							*:popup* *:popu*
+:popu[p] {name}			Popup the menu {name}.  The menu named must
+				have at least one subentry, but need not
+				appear on the menu-bar (see |hidden-menus|).
+				{only available for Win32 and GTK GUI}
+
+:popu[p]! {name}		Like above, but use the position of the mouse
+				pointer instead of the cursor.
+
+Example: >
+	:popup File
+will make the "File" menu (if there is one) appear at the text cursor (mouse
+pointer if ! was used). >
+
+	:amenu ]Toolbar.Make	:make<CR>
+	:popup ]Toolbar
+This creates a popup menu that doesn't exist on the main menu-bar.
+
+Note that a menu that starts with ']' will not be displayed.
+
+==============================================================================
+6. Extras						*gui-extras*
+
+This section describes other features which are related to the GUI.
+
+- With the GUI, there is no wait for one second after hitting escape, because
+  the key codes don't start with <Esc>.
+
+- Typing ^V followed by a special key in the GUI will insert "<Key>", since
+  the internal string used is meaningless.  Modifiers may also be held down to
+  get "<Modifiers-Key>".
+
+- In the GUI, the modifiers SHIFT, CTRL, and ALT (or META) may be used within
+  mappings of special keys and mouse events.  E.g.: :map <M-LeftDrag> <LeftDrag>
+
+- In the GUI, several normal keys may have modifiers in mappings etc, these
+  are <Space>, <Tab>, <NL>, <CR>, <Esc>.
+
+- To check in a Vim script if the GUI is being used, you can use something
+  like this: >
+
+	if has("gui_running")
+	   echo "yes, we have a GUI"
+	else
+	   echo "Boring old console"
+	endif
+<							*setting-guifont*
+- When you use the same vimrc file on various systems, you can use something
+  like this to set options specifically for each type of GUI: >
+
+	if has("gui_running")
+	    if has("gui_gtk2")
+		:set guifont=Luxi\ Mono\ 12
+	    elseif has("x11")
+		" Also for GTK 1
+		:set guifont=*-lucidatypewriter-medium-r-normal-*-*-180-*-*-m-*-*
+	    elseif has("gui_win32")
+		:set guifont=Luxi_Mono:h12:cANSI
+	    endif
+	endif
+
+A recommended Japanese font is MS Mincho.  You can find info here:
+http://www.lexikan.com/mincho.htm
+
+==============================================================================
+7. Shell Commands					*gui-shell*
+
+For the X11 GUI the external commands are executed inside the gvim window.
+See |gui-pty|.
+
+WARNING: Executing an external command from the X11 GUI will not always
+work.  "normal" commands like "ls", "grep" and "make" mostly work fine.
+Commands that require an intelligent terminal like "less" and "ispell" won't
+work.  Some may even hang and need to be killed from another terminal.  So be
+careful!
+
+For the Win32 GUI the external commands are executed in a separate window.
+See |gui-shell-win32|.
+
+ vim:tw=78:sw=4:ts=8:ft=help:norl:
--- /dev/null
+++ b/lib/vimfiles/doc/gui_w16.txt
@@ -1,0 +1,186 @@
+*gui_w16.txt*   For Vim version 7.1.  Last change: 2005 Mar 29
+
+
+		  VIM REFERENCE MANUAL    by Bram Moolenaar
+
+
+Vim's Graphical User Interface				*gui-w16* *win16-gui*
+
+1. Starting the GUI		|win16-start|
+2. Vim as default editor	|win16-default-editor|
+3. Using the clipboard		|win16-clipboard|
+4. Shell Commands		|win16-shell|
+5. Special colors		|win16-colors|
+6. Windows dialogs & browsers	|win16-dialogs|
+7. Various			|win16-various|
+
+Other relevant documentation:
+|gui.txt|	For generic items of the GUI.
+|os_msdos.txt|  For items common to DOS and Windows.
+|gui_w32.txt|	Some items here are also applicable to the Win16 version.
+
+{Vi does not have a Windows GUI}
+
+The Win16 version of Vim will run on Windows 3.1 or later.  It has not been
+tested on 3.0, it probably won't work without being recompiled and
+modified.  (But you really should upgrade to 3.11 anyway. :)
+
+In most respects it behaves identically to the Win32 GUI version, including
+having a flat-style toolbar(!).  The chief differences:
+
+1) Bold/Italic text is not available, to speed up repaint/reduce resource
+   usage.  (You can re-instate this by undefining MSWIN16_FASTTEXT.)
+2) No tearoff menu emulation.
+3) No OLE interface.
+4) No long filename support (of course).
+5) No tooltips on toolbar buttons - instead they produce command-line tips
+   like menu items do.
+6) Line length limited to 32767 characters (like 16-bit DOS version).
+
+
+==============================================================================
+1. Starting the GUI					*win16-start*
+
+The Win16 GUI version of Vim will always start the GUI, no matter how you
+start it or what it's called.  There is no 'console' version as such, but you
+can use one of the DOS versions in a DOS box.
+
+The Win16 GUI has an extra menu item:  "Window/Select Font".  It brings up the
+standard Windows font selector.  Note that bold and italic fonts are not
+supported in an attempt to maximize GDI drawing speed.
+
+Setting the menu height doesn't work for the Win16 GUI.
+
+							*win16-maximized*
+If you want Vim to start with a maximized window, add this command to your
+vimrc or gvimrc file: >
+	au GUIEnter * simalt ~x
+<
+
+There is a specific version of gvim.exe that runs under the Win32s subsystem
+of Windows 3.1 or 3.11.  See |win32s|.
+
+==============================================================================
+2. Vim as default editor				*win16-default-editor*
+
+To set Vim as the default editor for a file type you can use File Manager's
+"Associate" feature.
+
+When you open a file in Vim by double clicking it, Vim changes to that
+file's directory.
+
+See also |notepad|.
+
+==============================================================================
+3. Using the clipboard					*win16-clipboard*
+
+Windows has a clipboard, where you can copy text to, and paste text from.  Vim
+supports this in several ways.
+The clipboard works in the same way as the Win32 version: see |gui-clipboard|.
+
+==============================================================================
+4. Shell Commands					*win16-shell*
+
+Vim spawns a DOS window for external commands, to make it possible to run any
+DOS command.  The window uses the _default.pif settings.
+
+							*win16-!start*
+Normally, Vim waits for a command to complete before continuing (this makes
+sense for most shell commands which produce output for Vim to use).  If you
+want Vim to start a program and return immediately, you can use the following
+syntax:
+	:!start {command}
+This may only work for a Windows program though.
+Don't forget that you must tell Windows 3.1x to keep executing a DOS command
+in the background while you switch back to Vim.
+
+==============================================================================
+5. Special colors					*win16-colors*
+
+On Win16, the normal DOS colors can be used.  See |dos-colors|.
+
+Additionally the system configured colors can also be used.  These are known
+by the names Sys_XXX, where XXX is the appropriate system color name, from the
+following list (see the Win32 documentation for full descriptions).  Case is
+ignored.
+
+Sys_BTNFace		Sys_BTNShadow			Sys_ActiveBorder
+Sys_ActiveCaption	Sys_AppWorkspace		Sys_Background
+Sys_BTNText		Sys_CaptionText			Sys_GrayText
+Sys_Highlight		Sys_HighlightText		Sys_InactiveBorder
+Sys_InactiveCaption	Sys_InactiveCaptionText		Sys_Menu
+Sys_MenuText		Sys_ScrollBar			Sys_Window
+Sys_WindowFrame		Sys_WindowText
+
+Probably the most useful values are
+	Sys_Window	    Normal window background
+	Sys_WindowText      Normal window text
+	Sys_Highlight       Highlighted background
+	Sys_HighlightText   Highlighted text
+
+These extra colors are also available:
+Gray, Grey, LightYellow, SeaGreen, Orange, Purple, SlateBlue, Violet,
+
+
+See also |rgb.txt|.
+
+==============================================================================
+						*win16-dialogs*
+6. Windows dialogs & browsers
+
+The Win16 GUI can use familiar Windows components for some operations, as well
+as the traditional interface shared with the console version.
+
+
+6.1 Dialogs
+
+The dialogs displayed by the "confirm" family (i.e. the 'confirm' option,
+|:confirm| command and |confirm()| function) are GUI-based rather than the
+console-based ones used by other versions.  There is no option to change this.
+
+
+6.2 File Browsers
+
+When prepending ":browse" before file editing commands, a file requester is
+used to allow you to select an existing file.  See |:browse|.
+
+
+==============================================================================
+7. Various						*win16-various*
+
+							*win16-printing*
+The "File/Print" menu uses Notepad to print the current buffer.  This is a bit
+clumsy, but it's portable.  If you want something else, you can define your
+own print command.  For example, you could look for the 16-bit version of
+PrintFile.  See $VIMRUNTIME/menu.vim for how it works by default.
+
+Using this should also work: >
+	:w >>prn
+
+Vim supports a number of standard MS Windows features.  Some of these are
+detailed elsewhere: see |'mouse'|, |win32-hidden-menus|.
+Also see |:simalt|
+
+							*win16-drag-n-drop*
+You can drag and drop one or more files into the vim window, where they will
+be opened as normal.  If you hold down Shift while doing this, Vim changes to
+the (first) dropped file's directory.  If you hold Ctrl, Vim will always split
+a new window for the file.  Otherwise it's only done if the current buffer has
+been changed.
+You can also drop a directory's icon, but rather than open all files in the
+directory (which wouldn't usually be what you want) Vim instead changes to
+that directory and begins a new file.
+If Vim happens to be editing a command line, the names of the dropped files
+and directories will be inserted at the cursor.  This allows you to use these
+names with any Ex command.
+
+							*win16-truetype*
+It is recommended that you use a raster font and not a TrueType
+fixed-pitch font.  E.g. use Courier, not Courier New.  This is not just
+to use less resources but because there are subtle bugs in the
+handling of fixed-pitch TrueType in Win3.1x.  In particular, when you move
+a block cursor over a pipe character '|', the cursor is drawn in the wrong
+size and bits get left behind.  This is a bug in the Win3.1x GDI, it doesn't
+happen if you run the exe under 95/NT.
+
+ vim:tw=78:sw=4:ts=8:ft=help:norl:
--- /dev/null
+++ b/lib/vimfiles/doc/gui_w32.txt
@@ -1,0 +1,477 @@
+*gui_w32.txt*   For Vim version 7.1.  Last change: 2007 May 03
+
+
+		  VIM REFERENCE MANUAL    by Bram Moolenaar
+
+
+Vim's Win32 Graphical User Interface			*gui-w32* *win32-gui*
+
+1. Starting the GUI		|gui-w32-start|
+2. Vim as default editor	|vim-default-editor|
+3. Using the clipboard		|gui-clipboard|
+4. Shell Commands		|gui-shell-win32|
+5. Special colors		|win32-colors|
+6. Windows dialogs & browsers	|gui-w32-dialogs|
+7. Command line arguments	|gui-w32-cmdargs|
+8. Various			|gui-w32-various|
+
+Other relevant documentation:
+|gui.txt|	For generic items of the GUI.
+|os_win32.txt|  For Win32 specific items.
+
+{Vi does not have a Windows GUI}
+
+==============================================================================
+1. Starting the GUI					*gui-w32-start*
+
+The Win32 GUI version of Vim will always start the GUI, no matter how you
+start it or what it's called.
+
+The GUI will always run in the Windows subsystem.  Mostly shells automatically
+return with a command prompt after starting gvim.  If not, you should use the
+"start" command: >
+	start gvim [options] file ..
+
+Note: All fonts (bold, italic) must be of the same size!!!  If you don't do
+this, text will disappear or mess up the display.  Vim does not check the font
+sizes.  It's the size in screen pixels that must be the same.  Note that some
+fonts that have the same point size don't have the same pixel size!
+Additionally, the positioning of the fonts must be the same (ascent and
+descent).
+
+The Win32 GUI has an extra menu item:  "Edit/Select Font".  It brings up the
+standard Windows font selector.
+
+Setting the menu height doesn't work for the Win32 GUI.
+
+							*gui-win32-maximized*
+If you want Vim to start with a maximized window, add this command to your
+vimrc or gvimrc file: >
+	au GUIEnter * simalt ~x
+<
+								*gui-w32s*
+There is a specific version of gvim.exe that runs under the Win32s subsystem
+of Windows 3.1 or 3.11.  See |win32s|.
+
+==============================================================================
+2. Vim as default editor				*vim-default-editor*
+
+To set Vim as the default editor for a file type:
+1. Start a Windows Explorer
+2. Choose View/Options -> File Types
+3. Select the path to gvim for every file type that you want to use it for.
+   (you can also use three spaces in the file type field, for files without an
+   extension).
+   In the "open" action, use: >
+	gvim "%1"
+<  The quotes are required for using file names with embedded spaces.
+   You can also use this: >
+	gvim "%L"
+<  This should avoid short (8.3 character) file names in some situations.  But
+   I'm not sure if this works everywhere.
+
+When you open a file in Vim by double clicking it, Vim changes to that
+file's directory.
+
+If you want Vim to start full-screen, use this for the Open action: >
+	gvim -c "simalt ~x" "%1"
+
+Another method, which also works when you put Vim in another directory (e.g.,
+when you have got a new version):
+1. select a file you want to use Vim with
+2. <Shift-F10>
+3. select "Open With..." menu entry
+4. click "Other..."
+5. browse to the (new) location of Vim and click "Open"
+6. make "Always Use this program..." checked
+7. <OK>
+
+						*send-to-menu* *sendto*
+You can also install Vim in the "Send To" menu:
+1. Start a Windows Explorer
+2. Navigate to your sendto directory:
+   Windows 95: %windir%\sendto (e.g. "c:\windows\sendto")
+   Windows NT: %windir%\profiles\%user%\sendto (e.g.
+	       "c:\winnt\profiles\mattha\sendto").
+3. Right-click in the file pane and select New->Shortcut
+4. Follow the shortcut wizard, using the full path to VIM/GVIM.
+
+When you 'send a file to Vim', Vim changes to that file's directory.  Note,
+however, that any long directory names will appear in their short (MS-DOS)
+form.  This is a limitation of the Windows "Send To" mechanism.
+
+						*notepad*
+You could replace notepad.exe with gvim.exe, but that has a few side effects.
+Some programs rely on notepad arguments, which are not recognized by Vim.  For
+example "notepad -p" is used by some applications to print a file.  It's
+better to leave notepad where it is and use another way to start Vim.
+
+						*win32-popup-menu*
+A more drastic approach is to install an "Edit with Vim" entry in the popup
+menu for the right mouse button.  With this you can edit any file with Vim.
+
+This can co-exist with the file associations mentioned above.  The difference
+is that the file associations will make starting Vim the default action.  With
+the "Edit with Vim" menu entry you can keep the existing file association for
+double clicking on the file, and edit the file with Vim when you want.  For
+example, you can associate "*.mak" with your make program.  You can execute
+the makefile by double clicking it and use the "Edit with Vim" entry to edit
+the makefile.
+
+You can select any files and right-click to see a menu option called "Edit
+with gvim".  Chosing this menu option will invoke gvim with the file you have
+selected.  If you select multiple files, you will find two gvim-related menu
+options:
+"Edit with multiple gvims"  -- one gvim for each file in the selection
+"Edit with single gvim"     -- one gvim for all the files in the selection
+And if there already is a gvim running:
+"Edit with existing gvim"   -- edit the file with the running gvim
+
+						*install-registry*
+You can add the "Edit with Vim" menu entry in an easy way by using the
+"install.exe" program.  It will add several registry entries for you.
+
+You can also do this by hand.  This is complicated!  Use the install.exe if
+you can.
+
+1. Start the registry editor with "regedit".
+2. Add these keys:
+   key		value name		    value ~
+   HKEY_CLASSES_ROOT\CLSID\{51EEE242-AD87-11d3-9C1E-0090278BBD99}
+		{default}		    Vim Shell Extension
+   HKEY_CLASSES_ROOT\CLSID\{51EEE242-AD87-11d3-9C1E-0090278BBD99}\InProcServer32
+		{default}		    {path}\gvimext.dll
+		ThreadingModel		    Apartment
+   HKEY_CLASSES_ROOT\*\shellex\ContextMenuHandlers\gvim
+		{default}		    {51EEE242-AD87-11d3-9C1E-0090278BBD99}
+   HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Shell Extensions\Approved
+		{51EEE242-AD87-11d3-9C1E-0090278BBD99}
+					    Vim Shell Extension
+   HKEY_LOCAL_MACHINE\Software\Vim\Gvim
+		path			    {path}\gvim.exe
+   HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Uninstall\vim 5.6
+		DisplayName		    Vim 5.6: Edit with Vim popup menu entry
+		UninstallString		    {path}\uninstal.exe
+
+   Replace {path} with the path that leads to the executable.
+   Don't type {default}, this is the value for the key itself.
+
+To remove "Edit with Vim" from the popup menu, just remove the registry
+entries mentioned above.  The "uninstal.exe" program can do this for you.  You
+can also use the entry in the Windows standard "Add/Remove Programs" list.
+
+If you notice that this entry overrules other file type associations, set
+those associations again by hand (using Windows Explorer, see above).  This
+only seems to happen on some Windows NT versions (Windows bug?).  Procedure:
+1. Find the name of the file type.  This can be done by starting the registry
+   editor, and searching for the extension in \\HKEY_CLASSES_ROOT
+2. In a Windows Explorer, use View/Options/File Types.  Search for the file
+   type in the list and click "Edit".  In the actions list, you can select on
+   to be used as the default (normally the "open" action) and click on the
+   "Set Default" button.
+
+
+Vim in the "Open With..." context menu			*win32-open-with-menu*
+
+If you use the Vim install program you have the choice to add Vim to the "Open
+With..." menu.  This means you can use Vim to edit many files.  Not every file
+(for unclear reasons...), thus the "Edit with Vim" menu entry is still useful.
+
+One reason to add this is to be able to edit HTML files directly from Internet
+Explorer.  To enable this use the "Tools" menu, "Internet Options..." entry.
+In the dialog select the "Programs" tab and select Vim in the "HTML editor"
+choice.  If it's not there than installing didn't work properly.
+
+Doing this manually can be done with this script:
+
+----------------------------------------------------------
+REGEDIT4
+
+[HKEY_CLASSES_ROOT\Applications\gvim.exe]
+
+[HKEY_CLASSES_ROOT\Applications\gvim.exe\shell]
+
+[HKEY_CLASSES_ROOT\Applications\gvim.exe\shell\edit]
+
+[HKEY_CLASSES_ROOT\Applications\gvim.exe\shell\edit\command]
+@="c:\\vim\\vim62\\gvim.exe \"%1\""
+
+[HKEY_CLASSES_ROOT\.htm\OpenWithList\gvim.exe]
+
+[HKEY_CLASSES_ROOT\*\OpenWithList\gvim.exe]
+
+----------------------------------------------------------
+
+Change the "c:\\vim\\vim62" bit to where gvim.exe is actually located.
+
+To uninstall this run the Vim uninstall program or manually delete the
+registry entries with "regedit".
+
+==============================================================================
+3. Using the clipboard					*gui-clipboard*
+
+Windows has a clipboard, where you can copy text to, and paste text from.  Vim
+supports this in several ways.  For other systems see |gui-selections|.
+
+The "* register reflects the contents of the clipboard.  |quotestar|
+
+When the "unnamed" string is included in the 'clipboard' option, the unnamed
+register is the same.  Thus you can yank to and paste from the clipboard
+without prepending "* to commands.
+
+The 'a' flag in 'guioptions' is not included by default.  This means that text
+is only put on the clipboard when an operation is performed on it.  Just
+Visually selecting text doesn't put it on the clipboard.  When the 'a' flag is
+included, the text is copied to the clipboard even when it is not operated
+upon.
+
+							*mswin.vim*
+To use the standard MS-Windows way of CTRL-X, CTRL-C and CTRL-V, use the
+$VIMRUNTIME/mswin.vim script.  You could add this line to your _vimrc file: >
+	source $VIMRUNTIME/mswin.vim
+
+Since CTRL-C is used to copy the text to the clipboard, it can't be used to
+cancel an operation.  Use CTRL-Break for that.
+
+CTRL-Z is used for undo.  This means you can't suspend Vim with this key, use
+|:suspend| instead (if it's supported at all).
+
+						*CTRL-V-alternative* *CTRL-Q*
+Since CTRL-V is used to paste, you can't use it to start a blockwise Visual
+selection.  You can use CTRL-Q instead.  You can also use CTRL-Q in Insert
+mode and Command-line mode to get the old meaning of CTRL-V.  But CTRL-Q
+doesn't work for terminals when it's used for control flow.
+
+NOTE: The clipboard support still has a number of bugs.  See |todo|.
+
+==============================================================================
+4. Shell Commands					*gui-shell-win32*
+
+Vim uses another window for external commands, to make it possible to run any
+command.  The external command gets its own environment for running, just like
+it was started from a DOS prompt.
+
+							*win32-vimrun*
+Executing an external command is done indirectly by the "vimrun" command.  The
+"vimrun.exe" must be in the path for this to work.  Or it must be in the same
+directory as the Vim executable.  If "vimrun" cannot be found, the command is
+executed directly, but then the DOS window closes immediately after the
+external command has finished.
+WARNING: If you close this window with the "X" button, and confirm the
+question if you really want to kill the application, Vim may be killed too!
+(This does not apply to commands run asynchronously with ":!start".)
+
+In Windows 95, the window in which the commands are executed is always 25x80
+characters, to be as DOS compatible as possible (this matters!).  The default
+system font is used.  On NT, the window will be the default you have set up for
+"Console" in Control Panel.  On Win32s, the properties of the DOS box are
+determined by _default.pif in the windows directory.
+
+							*msdos-mode*
+If you get a dialog that says "This program is set to run in MS-DOS mode..."
+when you run an external program, you can solve this by changing the
+properties of the associated shortcut:
+- Use a Windows Explorer to find the command.com that is used.  It can be
+  c:\command.com, c:\dos\command.com, c:\windows\command.com, etc.
+- With the right mouse button, select properties of this command.com.
+- In the Program tab select "Advanced".
+- Unselect "MS-DOS mode".
+- Click "OK" twice.
+
+							*win32-!start*
+Normally, Vim waits for a command to complete before continuing (this makes
+sense for most shell commands which produce output for Vim to use).  If you
+want Vim to start a program and return immediately, you can use the following
+syntax on W95 & NT: >
+	:!start {command}
+On Win32s, you will have to go to another window instead.  Don't forget that
+you must tell Windows 3.1x to keep executing a DOS command in the background
+while you switch back to Vim.
+
+==============================================================================
+5. Special colors					*win32-colors*
+
+On Win32, the normal DOS colors can be used.  See |dos-colors|.
+
+Additionally the system configured colors can also be used.  These are known
+by the names Sys_XXX, where XXX is the appropriate system color name, from the
+following list (see the Win32 documentation for full descriptions).  Case is
+ignored.  Note: On Win32s not all of these colors are supported.
+
+Sys_3DDKShadow		Sys_3DFace			Sys_BTNFace
+Sys_3DHilight		Sys_3DHighlight			Sys_BTNHilight
+Sys_BTNHighlight	Sys_3DLight			Sys_3DShadow
+Sys_BTNShadow		Sys_ActiveBorder		Sys_ActiveCaption
+Sys_AppWorkspace	Sys_Background			Sys_Desktop
+Sys_BTNText		Sys_CaptionText			Sys_GrayText
+Sys_Highlight		Sys_HighlightText		Sys_InactiveBorder
+Sys_InactiveCaption	Sys_InactiveCaptionText		Sys_InfoBK
+Sys_InfoText		Sys_Menu			Sys_MenuText
+Sys_ScrollBar		Sys_Window			Sys_WindowFrame
+Sys_WindowText
+
+Probably the most useful values are
+	Sys_Window	    Normal window background
+	Sys_WindowText      Normal window text
+	Sys_Highlight       Highlighted background
+	Sys_HighlightText   Highlighted text
+
+These extra colors are also available:
+Gray, Grey, LightYellow, SeaGreen, Orange, Purple, SlateBlue, Violet,
+
+								*rgb.txt*
+Additionally, colors defined by a "rgb.txt" file can be used.  This file is
+well known from X11.  A few lines from it: >
+
+  255 218 185		   peach puff
+  205 133  63		   peru
+  255 181 197		   pink
+
+This shows the layout of the file:  First the R, G and B value as a decimal
+number, followed by the name of the color.  The four fields are separated by
+spaces.
+
+You can get an rgb.txt file from any X11 distribution.  It is located in a
+directory like "/usr/X11R6/lib/X11/".  For Vim it must be located in the
+$VIMRUNTIME directory.  Thus the file can be found with "$VIMRUNTIME/rgb.txt".
+
+==============================================================================
+						*gui-w32-dialogs* *dialog*
+6. Windows dialogs & browsers
+
+The Win32 GUI can use familiar Windows components for some operations, as well
+as the traditional interface shared with the console version.
+
+
+6.1 Dialogs
+
+The dialogs displayed by the "confirm" family (i.e. the 'confirm' option,
+|:confirm| command and |confirm()| function) are GUI-based rather than the
+console-based ones used by other versions.  The 'c' flag in 'guioptions'
+changes this.
+
+
+6.2 File Browsers
+
+When prepending ":browse" before file editing commands, a file requester is
+used to allow you to select an existing file.  See |:browse|.
+
+
+6.3 Tearoff Menus
+
+The Win32 GUI emulates Motif's tear-off menus.  At the top of each menu you
+will see a small graphic "rip here" sign.  Selecting it will cause a floating
+window to be created with the same menu entries on it.  The floating menu can
+then be accessed just as if it was the original (including sub-menus), but
+without having to go to the menu bar each time.
+This is most useful if you find yourself using a command buried in a sub-menu
+over and over again.
+The tearoff menus can be positioned where you like, and always stay just above
+the Main Vim window.  You can get rid of them by closing them as usual; they
+also of course close when you exit Vim.
+
+							*:tearoff* *:te*
+:te[aroff] {name}	Tear-off the menu {name}.  The menu named must have at
+			least one subentry, but need not appear on the
+			menu-bar (see |win32-hidden-menus|).
+
+Example: >
+	:tearoff File
+will make the "File" menu (if there is one) appear as a tearoff menu. >
+
+	:amenu ]Toolbar.Make	:make<CR>
+	:tearoff ]Toolbar
+This creates a floating menu that doesn't exist on the main menu-bar.
+
+Note that a menu that starts with ']' will not be displayed.
+
+==============================================================================
+7. Command line arguments				*gui-w32-cmdargs*
+
+Analysis of a command line into parameters is not standardised in MS Windows.
+Gvim has to provide logic to analyse a command line.  This logic is likely to
+be different from the default logic provided by a compilation system used to
+build vim.  The differences relate to unusual double quote (") usage.
+The arguments "C:\My Music\freude.txt" and "+/Sch\"iller" are handled in the
+same way.  The argument "+/Sch""iller" may be handled different by gvim and
+vim, depending what it was compiled with.
+
+The rules are:
+      a) A parameter is a sequence of graphic characters.
+      b) Parameters are separated by white space.
+      c) A parameter can be enclosed in double quotes to include white space.
+      d) A sequence of zero or more backslashes (\) and a double quote (")
+	is special.  The effective number of backslashes is halved, rounded
+	down.  An even number of backslashes reverses the acceptability of
+	spaces and tabs, an odd number of backslashes produces a literal
+	double quote.
+
+So:
+	"	is a special double quote
+	\"	is a literal double quote
+	\\"	is a literal backslash and a special double quote
+	\\\"	is a literal backslash and a literal double quote
+	\\\\"	is 2 literal backslashes and a special double quote
+	\\\\\"	is 2 literal backslashes and a literal double quote
+	etc.
+
+Example: >
+	gvim "C:\My Music\freude" +"set ignorecase" +/"\"foo\\" +\"bar\\\"
+
+opens "C:\My Music\freude" and executes the line mode commands: >
+	set ignorecase; /"foo\ and /bar\"
+
+==============================================================================
+8. Various						*gui-w32-various*
+
+							*gui-w32-printing*
+The "File/Print" menu prints the text with syntax highlighting, see
+|:hardcopy|.  If you just want to print the raw text and have a default
+printer installed this should also work: >
+	:w >>prn
+
+Vim supports a number of standard MS Windows features.  Some of these are
+detailed elsewhere: see |'mouse'|, |win32-hidden-menus|.
+
+							*drag-n-drop-win32*
+You can drag and drop one or more files into the Vim window, where they will
+be opened as normal.  See |drag-n-drop|.
+
+							*:simalt* *:si*
+:sim[alt] {key}		simulate pressing {key} while holding Alt pressed.
+			{not in Vi} {only for Win32 versions}
+
+Normally, Vim takes control of all Alt-<Key> combinations, to increase the
+number of possible mappings.  This clashes with the standard use of Alt as the
+key for accessing menus.
+The quick way of getting standard behavior is to set the 'winaltkeys' option
+to "yes".  This however prevents you from mapping Alt keys at all.
+Another way is to set 'winaltkeys' to "menu".  Menu shortcut keys are then
+handled by windows, other ALT keys can be mapped.  This doesn't allow a
+dependency on the current state though.
+To get round this, the :simalt command allows Vim (when 'winaltkeys' is not
+"yes") to fake a Windows-style Alt keypress.  You can use this to map Alt key
+combinations (or anything else for that matter) to produce standard Windows
+actions.  Here are some examples: >
+
+	:map <M-f> :simalt f<CR>
+This makes Alt-F pop down the 'File' menu (with the stock Menu.vim) by
+simulating the keystrokes Alt, F. >
+	:map <M-Space> :simalt ~<CR>
+This maps Alt-Space to pop down the system menu for the Vim window.  Note that
+~ is used by simalt to represent the <Space> character. >
+	:map <C-n> :simalt ~n<CR>
+Maps Control-N to produce the keys Alt-Space followed by N.  This minimizes the
+Vim window via the system menu.
+
+Note that the key changes depending on the language you are using.
+
+						*intellimouse-wheel-problems*
+When using the Intellimouse mouse wheel causes Vim to stop accepting input, go
+to:
+	ControlPanel - Mouse - Wheel - UniversalScrolling - Exceptions
+
+And add gvim to the list of applications.  This problem only appears to happen
+with the Intellimouse driver 2.2 and when "Universal Scrolling" is turned on.
+
+ vim:tw=78:sw=4:ts=8:ft=help:norl:
--- /dev/null
+++ b/lib/vimfiles/doc/gui_x11.txt
@@ -1,0 +1,585 @@
+*gui_x11.txt*   For Vim version 7.1.  Last change: 2006 Jul 12
+
+
+		  VIM REFERENCE MANUAL    by Bram Moolenaar
+
+
+Vim's Graphical User Interface				*gui-x11* *GUI-X11*
+							*Athena* *Motif*
+1. Starting the X11 GUI		|gui-x11-start|
+2. GUI Resources		|gui-resources|
+3. Shell Commands		|gui-pty|
+4. Various			|gui-x11-various|
+5. GTK version			|gui-gtk|
+6. GNOME version		|gui-gnome|
+7. KDE version			|gui-kde|
+8. Compiling			|gui-x11-compiling|
+9. X11 selection mechanism	|x11-selection|
+
+Other relevant documentation:
+|gui.txt|	For generic items of the GUI.
+
+{Vi does not have any of these commands}
+
+==============================================================================
+1. Starting the X11 GUI					*gui-x11-start* *E665*
+
+Then you can run the GUI version of Vim in either of these ways:
+    gvim [options] [files...]
+    vim -g [options] [files...]
+
+So if you call the executable "gvim", or make "gvim" a link to the executable,
+then the GUI version will automatically be used.  Additional characters may be
+added after "gvim", for example "gvim-5".
+
+You may also start up the GUI from within the terminal version by using one of
+these commands:
+	:gui [++opt] [+cmd] [-f|-b] [files...]			*:gu* *:gui*
+	:gvim [++opt] [+cmd] [-f|-b] [files...]			*:gv* *:gvim*
+The "-f" option runs Vim in the foreground.
+The "-b" option runs Vim in the background (this is the default).
+Also see |++opt| and |+cmd|.
+
+							*gui-fork*
+When the GUI is started, it does a fork() and exits the current process.
+When gvim was started from a shell this makes the shell accept further
+commands.  If you don't want this (e.g. when using gvim for a mail program
+that waits for gvim to exit), start gvim with "gvim -f", "vim -gf" or use
+":gui -f".  Don't use "vim -fg", because "-fg" specifies the foreground
+color.
+
+When using "gvim -f" and then ":gui", Vim will run in the foreground.  The
+"-f" argument will be remembered.  To force running Vim in the background use
+":gui -b".
+
+"gvim --nofork" does the same as "gvim -f".
+
+If you want the GUI to run in the foreground always, include the 'f'
+flag in 'guioptions'.  |-f|.
+
+==============================================================================
+2. GUI Resources			*gui-resources* *.Xdefaults*
+
+If using the Motif or Athena version of the GUI (not for the KDE, GTK+ or Win32
+version), a number of X resources are available.  You should use Vim's class
+"Vim" when setting these.  They are as follows:
+
+    Resource name	Meaning		~
+
+    reverseVideo	Boolean: should reverse video be used?
+    background		Color of background.
+    foreground		Color of normal text.
+    scrollBackground	Color of trough portion of scrollbars.
+    scrollForeground	Color of slider and arrow portions of scrollbars.
+    menuBackground	Color of menu backgrounds.
+    menuForeground	Color of menu foregrounds.
+    tooltipForeground	Color of tooltip and balloon foreground.
+    tooltipBackground	Color of tooltip and balloon background.
+
+    font		Name of font used for normal text.
+    boldFont		Name of font used for bold text.
+    italicFont		Name of font used for italic text.
+    boldItalicFont	Name of font used for bold, italic text.
+    menuFont		Name of font used for the menus, used when compiled
+			without the |+xfontset| feature
+    menuFontSet		Name of fontset used for the menus, used when compiled
+			with the |+xfontset| feature
+    tooltipFont		Name of the font used for the tooltip and balloons.
+			When compiled with the |+xfontset| feature this is a
+			fontset name.
+
+    geometry		Initial geometry to use for gvim's window (default
+			is same size as terminal that started it).
+    scrollbarWidth	Thickness of scrollbars.
+    borderWidth		Thickness of border around text area.
+    menuHeight		Height of the menu bar (only for Athena).
+
+A special font for italic, bold, and italic-bold text will only be used if
+the user has specified one via a resource.  No attempt is made to guess what
+fonts should be used for these based on the normal text font.
+
+Note that the colors can also be set with the ":highlight" command, using the
+"Normal", "Menu", "Tooltip", and "Scrollbar" groups.  Example: >
+	:highlight Menu guibg=lightblue
+	:highlight Tooltip guibg=yellow
+	:highlight Scrollbar guibg=lightblue guifg=blue
+	:highlight Normal guibg=grey90
+<
+							*font-sizes*
+Note: All fonts (except for the menu and tooltip) must be of the same size!!!
+If you don't do this, text will disappear or mess up the display.  Vim does
+not check the font sizes.  It's the size in screen pixels that must be the
+same.  Note that some fonts that have the same point size don't have the same
+pixel size!  Additionally, the positioning of the fonts must be the same
+(ascent and descent).  You can check this with "xlsfonts -l {fontname}".
+
+If any of these things are also set with Vim commands, e.g. with
+":set guifont=Screen15", then this will override the X resources (currently
+'guifont' is the only option that is supported).
+
+Here is an example of what you might put in your ~/.Xdefaults file: >
+
+	Vim*useSchemes:			all
+	Vim*sgiMode:			true
+	Vim*useEnhancedFSB:		true
+	Vim.foreground:			Black
+	Vim.background:			Wheat
+	Vim*fontList:			7x13
+
+The first three of these are standard resources on Silicon Graphics machines
+which make Motif applications look even better, highly recommended!
+
+The "Vim*fontList" is to set the menu font for Motif.  Example: >
+	Vim*menuBar*fontList:	     -*-courier-medium-r-*-*-10-*-*-*-*-*-*-*
+With Athena: >
+	Vim*menuBar*SmeBSB*font:     -*-courier-medium-r-*-*-10-*-*-*-*-*-*-*
+	Vim*menuBar*MenuButton*font: -*-courier-medium-r-*-*-10-*-*-*-*-*-*-*
+
+NOTE: A more portable, and indeed more correct, way to specify the menu font
+in either Motif or Athena is through the resource: >
+	Vim.menuFont:	     -*-courier-medium-r-*-*-10-*-*-*-*-*-*-*
+Or, when compiled with the |+xfontset| feature: >
+	Vim.menuFontSet:     -*-courier-medium-r-*-*-10-*-*-*-*-*-*-*
+
+Don't use "Vim*geometry" in the defaults.  This will break the menus.  Use
+"Vim.geometry" instead.
+
+If you get an error message "Cannot allocate colormap entry for "gray60",
+try adding this to your Vim resources (change the colors to your liking): >
+
+	Vim*scrollBackground:		Black
+	Vim*scrollForeground:		Blue
+
+The resources can also be set with arguments to Vim:
+
+    argument		meaning	~
+							*-gui*
+   -display {display}	Run vim on {display}		*-display*
+   -iconic		Start vim iconified		*-iconic*
+   -background {color}	Use {color} for the background	*-background*
+   -bg {color}		idem				*-bg*
+   -foreground {color}	Use {color} for normal text	*-foreground*
+   -fg {color}		idem				*-fg*
+   -ul {color}		idem				*-ul*
+   -font {font}		Use {font} for normal text	*-font*
+   -fn {font}		idem				*-fn*
+   -boldfont {font}	Use {font} for bold text	*-boldfont*
+   -italicfont {font}	Use {font} for italic text	*-italicfont*
+   -menufont {font}	Use {font} for menu items	*-menufont*
+   -menufontset {fontset} Use {fontset} for menu items	*-menufontset*
+   -mf {font}		idem				*-mf*
+   -geometry {geom}	Use {geom} for initial geometry	*-geometry*
+   -geom {geom}		idem, see |-geometry-example|	*-geom*
+   -borderwidth {width}	Use a border width of {width}	*-borderwidth*
+   -bw {width}		idem				*-bw*
+							*-scrollbarwidth*
+   -scrollbarwidth {width}	Use a scrollbar width of {width}
+   -sw {width}		idem				*-sw*
+   -menuheight {height}	Use a menu bar height of {height} *-menuheight*
+   -mh {height}		idem				*-mh*
+			NOTE: On Motif the value is ignored, the menu height
+			is computed to fit the menus.
+   -reverse		Use reverse video		*-reverse*
+   -rv			idem				*-rv*
+   +reverse		Don't use reverse video		*-+reverse*
+   +rv			idem				*-+rv*
+   -xrm {resource}	Set the specified resource	*-xrm*
+
+Note about reverse video: Vim checks that the result is actually a light text
+on a dark background.  The reason is that some X11 versions swap the colors,
+and some don't.  These two examples will both give yellow text on a blue
+background:
+    gvim -fg Yellow -bg Blue -reverse
+    gvim -bg Yellow -fg Blue -reverse
+
+							*-geometry-example*
+An example for the geometry argument: >
+	gvim -geometry 80x63+8+100
+This creates a window with 80 columns and 63 lines at position 8 pixels from
+the left and 100 pixels from the top of the screen.
+
+==============================================================================
+3. Shell Commands					*gui-pty*
+
+WARNING: Executing an external command from the GUI will not always work.
+"normal" commands like "ls", "grep" and "make" mostly work fine.  Commands
+that require an intelligent terminal like "less" and "ispell" won't work.
+Some may even hang and need to be killed from another terminal.  So be
+careful!
+
+There are two ways to do the I/O with a shell command: Pipes and a pseudo-tty.
+The default is to use a pseudo-tty.  This should work best on most systems.
+
+Unfortunately, the implementation of the pseudo-tty is different on every Unix
+system.  And some systems require root permission.  To avoid running into
+problems with a pseudo-tty when you least expect it, test it when not editing
+a file.  Be prepared to "kill" the started command or Vim.  Commands like
+":r !cat" may hang!
+
+If using a pseudo-tty does not work for you, reset the 'guipty' option: >
+
+	:set noguipty
+
+Using a pipe should work on any Unix system, but there are disadvantages:
+- Some shell commands will notice that a pipe is being used and behave
+  differently.  E.g., ":!ls" will list the files in one column.
+- The ":sh" command won't show a prompt, although it will sort of work.
+- When using ":make" it's not possible to interrupt with a CTRL-C.
+
+Typeahead while the external command is running is often lost.  This happens
+both with a pipe and a pseudo-tty.  This is a known problem, but it seems it
+can't be fixed (or at least, it's very difficult).
+
+							*gui-pty-erase*
+When your erase character is wrong for an external command, you should fix
+this in your "~/.cshrc" file, or whatever file your shell uses for
+initializations.  For example, when you want to use backspace to delete
+characters, but hitting backspaces produces "^H" instead, try adding this to
+your "~/.cshrc": >
+	stty erase ^H
+The ^H is a real CTRL-H, type it as CTRL-V CTRL-H.
+
+==============================================================================
+4. Various						*gui-x11-various*
+
+							*gui-x11-printing*
+The "File/Print" menu simply sends the current buffer to "lpr".  No options or
+whatever.  If you want something else, you can define your own print command.
+For example: >
+
+  :10amenu File.Print :w !lpr -Php3
+  :10vmenu File.Print :w !lpr -Php3
+<
+							*X11-icon*
+Vim uses a black&white icon by default when compiled with Motif or Athena.  A
+colored Vim icon is included as $VIMRUNTIME/vim32x32.xpm.  For GTK+, this is
+the builtin icon used.  Unfortunately, how you should install it depends on
+your window manager.  When you use this, remove the 'i' flag from
+'guioptions', to remove the black&white icon: >
+  :set guioptions-=i
+
+If you use one of the fvwm* family of window managers simply add this line to
+your .fvwm2rc configuration file: >
+
+  Style "vim"		Icon vim32x32.xpm
+
+Make sure the icon file's location is consistent with the window manager's
+ImagePath statement.  Either modify the ImagePath from within your .fvwm2rc or
+drop the icon into one the pre-defined directories: >
+
+  ImagePath /usr/X11R6/include/X11/pixmaps:/usr/X11R6/include/X11/bitmaps
+
+Note: older versions of fvwm use "IconPath" instead of "ImagePath".
+
+For CDE "dtwm" (a derivative of Motif) add this line in the .Xdefaults: >
+   Dtwm*Vim*iconImage: /usr/local/share/vim/vim32x32.xpm
+
+For "mwm" (Motif window manager) the line would be: >
+   Mwm*Vim*iconImage: /usr/local/share/vim/vim32x32.xpm
+
+Mouse Pointers Available in X11				*X11_mouse_shapes*
+
+By using the |'mouseshape'| option, the mouse pointer can be automatically
+changed whenever Vim enters one of its various modes (e.g., Insert or
+Command).  Currently, the available pointers are:
+
+	arrow			an arrow pointing northwest
+	beam			a I-like vertical bar
+	size			an arrow pointing up and down
+	busy			a wristwatch
+	blank			an invisible pointer
+	crosshair		a thin "+" sign
+	hand1			a dark hand pointing northeast
+	hand2			a light hand pointing northwest
+	pencil			a pencil pointing southeast
+	question		question_arrow
+	right_arrow		an arrow pointing northeast
+	up_arrow		an arrow pointing upwards
+
+Additionally, any of the mouse pointers that are built into X11 may be
+used by specifying an integer from the X11/cursorfont.h include file.
+
+If a name is used that exists on other systems, but not in X11, the default
+"arrow" pointer is used.
+
+==============================================================================
+5. GTK version						*gui-gtk* *GTK+* *GTK*
+
+The GTK version of the GUI works a little bit different.
+
+GTK does _not_ use the traditional X resource settings.  Thus items in your
+~/.Xdefaults or app-defaults files are not used.
+Many of the traditional X command line arguments are not supported.  (e.g.,
+stuff like -bg, -fg, etc).  The ones that are supported are:
+
+    command line argument   resource name	meaning ~
+    -fn  or  -font	    .font		font name for the text
+    -geom  or  -geometry    .geometry		size of the gvim window
+    -rv  or  -reverse	    *reverseVideo	white text on black background
+    -display					display to be used
+    -fg -foreground {color}			foreground color
+    -bg -background {color}			background color
+
+To set the font, see |'guifont'|.  For GTK, there's also a menu option that
+does this.
+
+Additionally, there are these command line arguments, which are handled by GTK
+internally.  Look in the GTK documentation for how they are used:
+	--sync
+	--gdk-debug
+	--gdk-no-debug
+	--no-xshm	(not in GTK+ 2)
+	--xim-preedit	(not in GTK+ 2)
+	--xim-status	(not in GTK+ 2)
+	--gtk-debug
+	--gtk-no-debug
+	--g-fatal-warnings
+	--gtk-module
+	--display	(GTK+ counterpart of -display; works the same way.)
+	--screen	(The screen number; for GTK+ 2.2 multihead support.)
+
+These arguments are ignored when the |+netbeans_intg| feature is used:
+	-xrm
+	-mf
+
+As for colors, Vim's color settings (for syntax highlighting) is still
+done the traditional Vim way.  See |:highlight| for more help.
+
+If you want to set the colors of remaining gui components (e.g., the
+menubar, scrollbar, whatever), those are GTK specific settings and you
+need to set those up in some sort of gtkrc file.  You'll have to refer
+to the GTK documentation, however little there is, on how to do this.
+See http://developer.gnome.org/doc/API/2.0/gtk/gtk-Resource-Files.html
+for more information.
+
+						*gtk-tooltip-colors*
+Example, which sets the tooltip colors to black on light-yellow: >
+
+	style "tooltips"
+	{
+		bg[NORMAL] = "#ffffcc"
+		fg[NORMAL] = "#000000"
+	}
+
+	widget "gtk-tooltips*"		style "tooltips"
+
+Write this in the file ~/.gtkrc and it will be used by GTK+.  For GTK+ 2
+you might have to use the file ~/.gtkrc-2.0 instead, depending on your
+distribution.
+
+Using Vim as a GTK+ plugin				*gui-gtk-socketid*
+
+When the GTK+ version of Vim starts up normally, it creates its own top level
+window (technically, a 'GtkWindow').  GTK+ provides an embedding facility with
+its GtkSocket and GtkPlug widgets.  If one GTK+ application creates a
+GtkSocket widget in one of its windows, an entirely different GTK+ application
+may embed itself into the first application by creating a top-level GtkPlug
+widget using the socket's ID.
+
+If you pass Vim the command-line option '--socketid' with a decimal or
+hexadecimal value, Vim will create a GtkPlug widget using that value instead
+of the normal GtkWindow.  This enables Vim to act as a GTK+ plugin.
+
+This really is a programmer's interface, and is of no use without a supporting
+application to spawn the Vim correctly.  For more details on GTK+ sockets, see
+http://www.gtk.org/api/
+
+Note that this feature requires the latest GTK version.  GTK 1.2.10 still has
+a small problem.  The socket feature has not yet been tested with GTK+ 2 --
+feel free to volunteer.
+
+==============================================================================
+6. GNOME version				*gui-gnome* *Gnome* *GNOME*
+
+The GNOME GUI works just like the GTK+ version.  See |GTK+| above for how it
+works.  It looks a bit different though, and implements one important feature
+that's not available in the plain GTK+ GUI:  Interaction with the session
+manager. |gui-gnome-session|
+
+These are the different looks:
+- Uses GNOME dialogs (GNOME 1 only).  The GNOME 2 GUI uses the same nice
+  dialogs as the GTK+ 2 version.
+- Uses the GNOME dock, so that the toolbar and menubar can be moved to
+  different locations other than the top (e.g., the toolbar can be placed on
+  the left, right, top, or bottom).  The placement of the menubar and
+  toolbar is only saved in the GNOME 2 version.
+- That means the menubar and toolbar handles are back!  Yeah!  And the
+  resizing grid still works too.
+
+GNOME is compiled with if it was found by configure and the
+--enable-gnome-check argument was used.
+
+
+GNOME session support			*gui-gnome-session* *gnome-session*
+
+On logout, Vim shows the well-known exit confirmation dialog if any buffers
+are modified.  Clicking [Cancel] will stop the logout process.  Otherwise the
+current session is stored to disk by using the |:mksession| command, and
+restored the next time you log in.
+
+The GNOME session support should also work with the KDE session manager.
+If you are experiencing any problems please report them as bugs.
+
+Note: The automatic session save works entirely transparent, in order to
+avoid conflicts with your own session files, scripts and autocommands.  That
+means in detail:
+- The session file is stored to a separate directory (usually $HOME/.gnome2).
+- 'sessionoptions' is ignored, and a hardcoded set of appropriate flags is
+  used instead: >
+	blank,curdir,folds,globals,help,options,winsize
+- The internal variable |v:this_session| is not changed when storing the
+  session.  Also, it is restored to its old value when logging in again.
+
+The position and size of the GUI window is not saved by Vim since doing so
+is the window manager's job.  But if compiled with GTK+ 2 support, Vim helps
+the WM to identify the window by restoring the window role (using the |--role|
+command line argument).
+
+==============================================================================
+7. KDE version					*gui-kde* *kde* *KDE* *KVim*
+							*gui-x11-kde*
+There is no KDE version of Vim.  There has been some work on a port using the
+Qt toolkit, but it never worked properly and it has been abandoned.  Work
+continues on Yzis: www.yzis.org.
+
+==============================================================================
+8. Compiling						*gui-x11-compiling*
+
+If using X11, Vim's Makefile will by default first try to find the necessary
+GTK+ files on your system.  If the GTK+ files cannot be found, then the Motif
+files will be searched for.  Finally, if this fails, the Athena files will be
+searched for.  If all three fail, the GUI will be disabled.
+
+For GTK+, Vim's configuration process requires that GTK+ be properly
+installed.  That is, the shell script 'gtk-config' must be in your PATH, and
+you can already successful compile, build, and execute a GTK+ program.  The
+reason for this is because the compiler flags (CFLAGS) and link flags
+(LDFLAGS) are obtained through the 'gtk-config' shell script.
+
+If you want to build with GTK+ 2 support pass the --enable-gtk2-check argument
+to ./configure.  Optionally, support for GNOME 2 will be compiled if the
+--enable-gnome-check option is also given.  Note that the support for GTK+ 2
+is still experimental.  However, many people have reported that it works just
+fine for them.
+
+Otherwise, if you are using Motif or Athena, when you have the Motif or Athena
+files in a directory where configure doesn't look, edit the Makefile to enter
+the names of the directories.  Search for "GUI_INC_LOC" for an example to set
+the Motif directories, "CONF_OPT_X" for Athena.
+
+							*gui-x11-gtk*
+At the time of this writing, you may use either GTK+ version 1.0.6 or 1.2.  It
+is suggested that you use v1.2 since not all of Vim's GUI features are present
+if using v1.0.6.  For instance, there are no tearoff menus present in v1.0.6.
+Using a version from GTK+'s CVS tree may or may not work, and is therefore not
+supported and not recommended.
+
+For the experimental GTK+ 2 GUI, using the latest release of the GTK+ 2.0 or
+GTK+ 2.2 series is recommended.  CVS HEAD seems to work fine most of time as
+well.
+
+Lastly, although GTK+ has supposedly been ported to the Win32 platform, this
+has not been tested with Vim and is also unsupported.  Also, it's unlikely to
+even compile since GTK+ GUI uses parts of the generic X11 code.  This might
+change in distant future; particularly because getting rid of the X11 centric
+code parts is also required for GTK+ framebuffer support.
+
+							*gui-x11-motif*
+For Motif, you need at least Motif version 1.2 and/or X11R5.  Motif 2.0 and
+X11R6 are OK.  Motif 1.1 and X11R4 might work, no guarantee (there may be a
+few problems, but you might make it compile and run with a bit of work, please
+send me the patches if you do).  The newest releases of LessTif have been
+reported to work fine too.
+
+							*gui-x11-athena*
+The Athena version uses the Xaw widget set by default.  If you have the 3D
+version, you might want to link with Xaw3d instead.  This will make the
+menus look a bit better.  Edit the Makefile and look for "XAW_LIB".  The
+scrollbars will remain the same, because Vim has its own, which are already
+3D (in fact, they look more like Motif).
+
+							*gui-x11-neXtaw*
+The neXtaw version is mostly like Athena, but uses different widgets.
+
+							*gui-x11-misc*
+In general, do not try to mix files from different GTK+, Motif, Athena and X11
+versions.  This will cause problems.  For example, using header files for
+X11R5 with a library for X11R6 probably doesn't work (although the linking
+won't give an error message, Vim will crash later).
+
+==============================================================================
+9. X11 selection mechanism				*x11-selection*
+
+If using X11, in either the GUI or an xterm with an X11-aware Vim, then Vim
+provides varied access to the X11 selection and clipboard.  These are accessed
+by using the two selection registers "* and "+.
+
+X11 provides two basic types of global store, selections and cut-buffers,
+which differ in one important aspect: selections are "owned" by an
+application, and disappear when that application (e.g., Vim) exits, thus
+losing the data, whereas cut-buffers, are stored within the X-server itself
+and remain until written over or the X-server exits (e.g., upon logging out).
+
+The contents of selections are held by the originating application (e.g., upon
+a copy), and only passed on to another application when that other application
+asks for them (e.g., upon a paste).
+
+The contents of cut-buffers are immediately written to, and are then
+accessible directly from the X-server, without contacting the originating
+application.
+
+							*quoteplus* *quote+*
+There are three documented X selections: PRIMARY (which is expected to
+represent the current visual selection - as in Vim's Visual mode), SECONDARY
+(which is ill-defined) and CLIPBOARD (which is expected to be used for
+cut, copy and paste operations).
+
+Of these three, Vim uses PRIMARY when reading and writing the "* register
+(hence when the X11 selections are available, Vim sets a default value for
+|'clipboard'| of "autoselect"), and CLIPBOARD when reading and writing the "+
+register.  Vim does not access the SECONDARY selection.
+
+Examples: (assuming the default option values)
+- Select an URL in Visual mode in Vim.  Go to a text field in Netscape and
+  click the middle mouse button.  The selected text will be inserted
+  (hopefully!).
+- Select some text in Netscape by dragging with the mouse.  Go to Vim and
+  press the middle mouse button: The selected text is inserted.
+- Select some text in Vim and do "+y.  Go to Netscape, select some text in a
+  textfield by dragging with the mouse.  Now use the right mouse button and
+  select "Paste" from the popup menu.  The selected text is overwritten by the
+  text from Vim.
+Note that the text in the "+ register remains available when making a Visual
+selection, which makes other text available in the "* register.  That allows
+overwriting selected text.
+							*x11-cut-buffer*
+There are, by default, 8 cut-buffers: CUT_BUFFER0 to CUT_BUFFER7.  Vim only
+uses CUT_BUFFER0, which is the one that xterm uses by default.
+
+Whenever Vim is about to become unavailable (either via exiting or becoming
+suspended), and thus unable to respond to another application's selection
+request, it writes the contents of any owned selection to CUT_BUFFER0.  If the
+"+ CLIPBOARD selection is owned by Vim, then this is written in preference,
+otherwise if the "* PRIMARY selection is owned by Vim, then that is written.
+
+Similarly, when Vim tries to paste from "* or "+ (either explicitly, or, in
+the case of the "* register, when the middle mouse button is clicked), if the
+requested X selection is empty or unavailable, Vim reverts to reading the
+current value of the CUT_BUFFER0.
+
+Note that when text is copied to CUT_BUFFER0 in this way, the type of
+selection (character, line or block) is always lost, even if it is a Vim which
+later pastes it.
+
+Xterm, by default, always writes visible selections to both PRIMARY and
+CUT_BUFFER0.  When it pastes, it uses PRIMARY if this is available, or else
+falls back upon CUT_BUFFER0.  For this reason, when cutting and pasting
+between Vim and an xterm, you should use the "* register.  Xterm doesn't use
+CLIPBOARD, thus the "+ doesn't work with xterm.
+
+Most newer applications will provide their current selection via PRIMARY ("*)
+and use CLIPBOARD ("+) for cut/copy/paste operations.  You thus have access to
+both by choosing to use either of the "* or "+ registers.
+
+
+ vim:tw=78:sw=4:ts=8:ft=help:norl:
--- /dev/null
+++ b/lib/vimfiles/doc/hangulin.txt
@@ -1,0 +1,101 @@
+*hangulin.txt*  For Vim version 7.1.  Last change: 2006 Apr 02
+
+
+		  VIM REFERENCE MANUAL    by Chi-Deok Hwang and Sung-Hyun Nam
+
+Introduction					*hangul*
+------------
+It is to input hangul, the Korean language, with VIM GUI version.
+If you have a XIM program, you can use another |+xim| feature.
+Basically, it is for anybody who has no XIM program.
+
+Compile
+-------
+Next is a basic option.  You can add any other configure option. >
+
+   ./configure --with-x --enable-multibyte --enable-fontset --enable-hangulinput
+
+And you should check feature.h.  If |+hangul_input| feature is enabled
+by configure, you can select more options such as keyboard type, 2 bulsik
+or 3 bulsik.  You can find keywords like next in there. >
+
+	#define HANGUL_DEFAULT_KEYBOARD 2
+	#define ESC_CHG_TO_ENG_MODE
+	/* #define X_LOCALE */
+	/* #define SLOW_XSERVER */
+
+Environment variables
+---------------------
+You should set LANG variable to Korean locale such as ko or ko_KR.euc.
+If you set LC_ALL variable, it should be set to Korean locale also.
+
+VIM resource
+------------
+You should add nexts to your global vimrc ($HOME/.vimrc). >
+
+	:set fileencoding=korea
+
+Keyboard
+--------
+You can change keyboard type (2 bulsik or 3 bulsik) using VIM_KEYBOARD
+or HANGUL_KEYBOARD_TYPE environment variables.  For sh, just do (2 bulsik): >
+
+    export VIM_KEYBOARD="2"
+or >
+    export HANGUL_KEYBOARD_TYPE="2"
+
+If both are set, VIM_KEYBOARD has higher priority.
+
+Hangul Fonts
+------------
+You can set text font using $HOME/.Xdefaults or in your gvimrc file.
+But to use Hangul, you should set 'guifontset' in your vimrc.
+
+$HOME/.Xdefaults: >
+    Vim.font: english_font
+
+    ! Nexts are for hangul menu with Athena
+    *international: True
+    Vim*fontSet: english_font,hangul_font
+
+    ! Nexts are for hangul menu with Motif
+    *international: True
+    Vim*fontList: english_font;hangul_font:
+
+$HOME/.gvimrc: >
+    set guifontset=english_font,hangul_font
+
+attention! the , (comma) or ; (semicolon)
+
+And there should be no ':set guifont'.  If it exists, then Gvim ignores
+':set guifontset'.  It means VIM runs without fontset supporting.
+So, you can see only English.  Hangul does not be correctly displayed.
+
+After 'fontset' feature is enabled, VIM does not allow using 'font'.
+For example, if you use >
+   :set guifontset=eng_font,your_font
+in your .gvimrc, then you should do for syntax >
+   :hi Comment guifg=Cyan font=another_eng_font,another_your_font
+If you just do >
+   :hi Comment font=another_eng_font
+then you can see a GOOD error message.  Be careful!
+
+hangul_font width should be twice than english_font width.
+
+Unsupported Feature
+-------------------
+Johab font not yet supported.  And I don't have any plan.
+If you really want to use johab font, you can use the
+hanguldraw.c in gau package.
+
+Hanja input not yet supported.  And I don't have any plan.
+If you really want to input hanja, just use VIM with hanterm.
+
+Bug or Comment
+--------------
+Send comments, patches and suggestions to:
+
+				    Chi-Deok Hwang <hwang@mizi.co.kr>
+				    Nam SungHyun <namsh@kldp.org>
+
+ vim:tw=78:ts=8:ft=help:norl:
--- /dev/null
+++ b/lib/vimfiles/doc/hebrew.txt
@@ -1,0 +1,145 @@
+*hebrew.txt*    For Vim version 7.1.  Last change: 2003 May 11
+
+
+	   VIM REFERENCE MANUAL    by Ron Aaron (and Avner Lottem)
+
+
+Hebrew Language support (options & mapping) for Vim		*hebrew*
+
+The supporting 'rightleft' functionality was originally created by Avner
+Lottem:
+   E-mail: alottem@iil.intel.com
+   Phone:  +972-4-8307322
+
+Ron Aaron <ron@ronware.org> is currently helping support these features.
+
+{Vi does not have any of these commands}
+
+All this is only available when the |+rightleft| feature was enabled at
+compile time.
+
+
+Introduction
+------------
+Hebrew-specific options are 'hkmap', 'hkmapp' 'keymap'=hebrew and 'aleph'.
+Hebrew-useful options are 'delcombine', 'allowrevins', 'revins', 'rightleft'
+and 'rightleftcmd'.
+
+The 'rightleft' mode reverses the display order, so characters are displayed
+from right to left instead of the usual left to right.  This is useful
+primarily when editing Hebrew or other Middle-Eastern languages.
+See |rileft.txt| for further details.
+
+Details
+--------------
++  Options:
+   +  'rightleft' ('rl') sets window orientation to right-to-left.  This means
+      that the logical text 'ABC' will be displayed as 'CBA', and will start
+      drawing at the right edge of the window, not the left edge.
+   +  'hkmap' ('hk') sets keyboard mapping to Hebrew, in insert/replace modes.
+   +  'aleph' ('al'), numeric, holds the decimal code of Aleph, for keyboard
+      mapping.
+   +  'hkmapp' ('hkp') sets keyboard mapping to 'phonetic hebrew'
+
+   NOTE: these three ('hkmap', 'hkmapp' and 'aleph') are obsolete.  You should
+	 use ":set keymap=hebrewp" instead.
+
+   +  'delcombine' ('deco'), boolean, if editing UTF-8 encoded Hebrew, allows
+      one to remove the niqud or te`amim by pressing 'x' on a character (with
+      associated niqud).
+
+   +  'rightleftcmd' ('rlc') makes the command-prompt for searches show up on
+      the right side.  It only takes effect if the window is 'rightleft'.
+
++  Encoding:
+   +  Under Unix, ISO 8859-8 encoding (Hebrew letters codes: 224-250).
+   +  Under MS DOS, PC encoding (Hebrew letters codes: 128-154).
+      These are defaults, that can be overridden using the 'aleph' option.
+   +  You should prefer using UTF8, as it supports the combining-characters
+      ('deco' does nothing if UTF8 encoding is not active).
+
++  Vim arguments:
+   +  'vim -H file' starts editing a Hebrew file, i.e. 'rightleft' and 'hkmap'
+      are set.
+
++  Keyboard:
+   +  The 'allowrevins' option enables the CTRL-_ command in Insert mode and
+      in Command-line mode.
+
+   +  CTRL-_ in insert/replace modes toggles 'revins' and 'hkmap' as follows:
+
+      When in rightleft window, 'revins' and 'nohkmap' are toggled, since
+      English will likely be inserted in this case.
+
+      When in norightleft window, 'revins' 'hkmap' are toggled, since Hebrew
+      will likely be inserted in this case.
+
+      CTRL-_ moves the cursor to the end of the typed text.
+
+   +  CTRL-_ in command mode only toggles keyboard mapping (see Bugs below).
+      This setting is independent of 'hkmap' option, which only applies to
+      insert/replace mode.
+
+      Note: On some keyboards, CTRL-_ is mapped to CTRL-?.
+
+   +  Keyboard mapping while 'hkmap' is set (standard Israeli keyboard):
+
+	q w e r t y u i o p
+	/ ' ק ר א ט ו ן ם פ
+
+	 a s d f g h j k l ; '
+	 ש ד ג כ ע י ח ל ך ף ,
+
+	  z x c v b n m , . /
+	  ז ס ב ה נ מ צ ת ץ .
+
+      This is also the keymap when 'keymap=hebrew' is set.  The advantage of
+      'keymap' is that it works properly when using UTF8, e.g. it inserts the
+      correct characters; 'hkmap' does not.  The 'keymap' keyboard can also
+      insert niqud and te`amim.  To see what those mappings are,look at the
+      keymap file 'hebrew.vim' etc.
+
+
+Typing backwards
+
+If the 'revins' (reverse insert) option is set, inserting happens backwards.
+This can be used to type Hebrew.  When inserting characters the cursor is not
+moved and the text moves rightwards.  A <BS> deletes the character under the
+cursor.  CTRL-W and CTRL-U also work in the opposite direction.  <BS>, CTRL-W
+and CTRL-U do not stop at the start of insert or end of line, no matter how
+the 'backspace' option is set.
+
+There is no reverse replace mode (yet).
+
+If the 'showmode' option is set, "-- REVERSE INSERT --" will be shown in the
+status line when reverse Insert mode is active.
+
+When the 'allowrevins' option is set, reverse Insert mode can be also entered
+via CTRL-_, which has some extra functionality: First, keyboard mapping is
+changed according to the window orientation -- if in a left-to-right window,
+'revins' is used to enter Hebrew text, so the keyboard changes to Hebrew
+('hkmap' is set); if in a right-to-left window, 'revins' is used to enter
+English text, so the keyboard changes to English ('hkmap' is reset).  Second,
+when exiting 'revins' via CTRL-_, the cursor moves to the end of the typed
+text (if possible).
+
+
+Pasting when in a rightleft window
+----------------------------------
+When cutting text with the mouse and pasting it in a rightleft window
+the text will be reversed, because the characters come from the cut buffer
+from the left to the right, while inserted in the file from the right to
+the left.   In order to avoid it, toggle 'revins' (by typing CTRL-? or CTRL-_)
+before pasting.
+
+
+Hebrew characters and the 'isprint' variable
+--------------------------------------------
+Sometimes Hebrew character codes are in the non-printable range defined by
+the 'isprint' variable.  For example in the Linux console, the Hebrew font
+encoding starts from 128, while the default 'isprint' variable is @,161-255.
+The result is that all Hebrew characters are displayed as ~x.  To solve this
+problem, set isprint=@,128-255.
+
+
+ vim:tw=78:ts=8:ft=help:norl:
--- /dev/null
+++ b/lib/vimfiles/doc/help.txt
@@ -1,0 +1,216 @@
+*help.txt*	For Vim version 7.1.  Last change: 2006 Nov 07
+
+			VIM - main help file
+									 k
+      Move around:  Use the cursor keys, or "h" to go left,	       h   l
+		    "j" to go down, "k" to go up, "l" to go right.	 j
+Close this window:  Use ":q<Enter>".
+   Get out of Vim:  Use ":qa!<Enter>" (careful, all changes are lost!).
+
+Jump to a subject:  Position the cursor on a tag (e.g. |bars|) and hit CTRL-].
+   With the mouse:  ":set mouse=a" to enable the mouse (in xterm or GUI).
+		    Double-click the left mouse button on a tag, e.g. |bars|.
+	Jump back:  Type CTRL-T or CTRL-O (repeat to go further back).
+
+Get specific help:  It is possible to go directly to whatever you want help
+		    on, by giving an argument to the |:help| command.
+		    It is possible to further specify the context:
+							*help-context*
+			  WHAT			PREPEND    EXAMPLE	~
+		      Normal mode command      (nothing)   :help x
+		      Visual mode command	  v_	   :help v_u
+		      Insert mode command	  i_	   :help i_<Esc>
+		      Command-line command	  :	   :help :quit
+		      Command-line editing	  c_	   :help c_<Del>
+		      Vim command argument	  -	   :help -r
+		      Option			  '	   :help 'textwidth'
+  Search for help:  Type ":help word", then hit CTRL-D to see matching
+		    help entries for "word".
+
+VIM stands for Vi IMproved.  Most of VIM was made by Bram Moolenaar, but only
+through the help of many others.  See |credits|.
+------------------------------------------------------------------------------
+						*doc-file-list* *Q_ct*
+BASIC:
+|quickref|	Overview of the most common commands you will use
+|tutor|		30 minutes training course for beginners
+|copying|	About copyrights
+|iccf|		Helping poor children in Uganda
+|sponsor|	Sponsor Vim development, become a registered Vim user
+|www|		Vim on the World Wide Web
+|bugs|		Where to send bug reports
+
+USER MANUAL: These files explain how to accomplish an editing task.
+
+|usr_toc.txt|	Table Of Contents
+
+Getting Started ~
+|usr_01.txt|  About the manuals
+|usr_02.txt|  The first steps in Vim
+|usr_03.txt|  Moving around
+|usr_04.txt|  Making small changes
+|usr_05.txt|  Set your settings
+|usr_06.txt|  Using syntax highlighting
+|usr_07.txt|  Editing more than one file
+|usr_08.txt|  Splitting windows
+|usr_09.txt|  Using the GUI
+|usr_10.txt|  Making big changes
+|usr_11.txt|  Recovering from a crash
+|usr_12.txt|  Clever tricks
+
+Editing Effectively ~
+|usr_20.txt|  Typing command-line commands quickly
+|usr_21.txt|  Go away and come back
+|usr_22.txt|  Finding the file to edit
+|usr_23.txt|  Editing other files
+|usr_24.txt|  Inserting quickly
+|usr_25.txt|  Editing formatted text
+|usr_26.txt|  Repeating
+|usr_27.txt|  Search commands and patterns
+|usr_28.txt|  Folding
+|usr_29.txt|  Moving through programs
+|usr_30.txt|  Editing programs
+|usr_31.txt|  Exploiting the GUI
+|usr_32.txt|  The undo tree
+
+Tuning Vim ~
+|usr_40.txt|  Make new commands
+|usr_41.txt|  Write a Vim script
+|usr_42.txt|  Add new menus
+|usr_43.txt|  Using filetypes
+|usr_44.txt|  Your own syntax highlighted
+|usr_45.txt|  Select your language
+
+Making Vim Run ~
+|usr_90.txt|  Installing Vim
+
+
+REFERENCE MANUAL: These files explain every detail of Vim.	*reference_toc*
+
+General subjects ~
+|intro.txt|	general introduction to Vim; notation used in help files
+|help.txt|	overview and quick reference (this file)
+|index.txt|	alphabetical index of all commands
+|help-tags|	all the tags you can jump to (index of tags)
+|howto.txt|	how to do the most common editing tasks
+|tips.txt|	various tips on using Vim
+|message.txt|	(error) messages and explanations
+|quotes.txt|	remarks from users of Vim
+|todo.txt|	known problems and desired extensions
+|develop.txt|	development of Vim
+|debug.txt|	debugging Vim itself
+|uganda.txt|	Vim distribution conditions and what to do with your money
+
+Basic editing ~
+|starting.txt|	starting Vim, Vim command arguments, initialisation
+|editing.txt|	editing and writing files
+|motion.txt|	commands for moving around
+|scroll.txt|	scrolling the text in the window
+|insert.txt|	Insert and Replace mode
+|change.txt|	deleting and replacing text
+|indent.txt|	automatic indenting for C and other languages
+|undo.txt|	Undo and Redo
+|repeat.txt|	repeating commands, Vim scripts and debugging
+|visual.txt|	using the Visual mode (selecting a text area)
+|various.txt|	various remaining commands
+|recover.txt|	recovering from a crash
+
+Advanced editing ~
+|cmdline.txt|	Command-line editing
+|options.txt|	description of all options
+|pattern.txt|	regexp patterns and search commands
+|map.txt|	key mapping and abbreviations
+|tagsrch.txt|	tags and special searches
+|quickfix.txt|	commands for a quick edit-compile-fix cycle
+|windows.txt|	commands for using multiple windows and buffers
+|tabpage.txt|	commands for using multiple tab pages
+|syntax.txt|	syntax highlighting
+|spell.txt|	spell checking
+|diff.txt|	working with two or three versions of the same file
+|autocmd.txt|	automatically executing commands on an event
+|filetype.txt|	settings done specifically for a type of file
+|eval.txt|	expression evaluation, conditional commands
+|fold.txt|	hide (fold) ranges of lines
+
+Special issues ~
+|print.txt|	printing
+|remote.txt|	using Vim as a server or client
+|term.txt|	using different terminals and mice
+|digraph.txt|	list of available digraphs
+|mbyte.txt|	multi-byte text support
+|mlang.txt|	non-English language support
+|arabic.txt|	Arabic language support and editing
+|farsi.txt|	Farsi (Persian) editing
+|hebrew.txt|	Hebrew language support and editing
+|russian.txt|	Russian language support and editing
+|ada.txt|	Ada (the programming language) support
+|hangulin.txt|	Hangul (Korean) input mode
+|rileft.txt|	right-to-left editing mode
+
+GUI ~
+|gui.txt|	Graphical User Interface (GUI)
+|gui_w16.txt|	Windows 3.1 GUI
+|gui_w32.txt|	Win32 GUI
+|gui_x11.txt|	X11 GUI
+
+Interfaces ~
+|if_cscop.txt|	using Cscope with Vim
+|if_mzsch.txt|	MzScheme interface
+|if_perl.txt|	Perl interface
+|if_pyth.txt|	Python interface
+|if_sniff.txt|	SNiFF+ interface
+|if_tcl.txt|	Tcl interface
+|if_ole.txt|	OLE automation interface for Win32
+|if_ruby.txt|	Ruby interface
+|debugger.txt|	Interface with a debugger
+|workshop.txt|	Sun Visual Workshop interface
+|netbeans.txt|	NetBeans External Editor interface
+|sign.txt|	debugging signs
+
+Versions ~
+|vi_diff.txt|	Main differences between Vim and Vi
+|version4.txt|	Differences between Vim version 3.0 and 4.x
+|version5.txt|	Differences between Vim version 4.6 and 5.x
+|version6.txt|	Differences between Vim version 5.7 and 6.x
+|version7.txt|	Differences between Vim version 6.4 and 7.x
+						*sys-file-list*
+Remarks about specific systems ~
+|os_390.txt|	OS/390 Unix
+|os_amiga.txt|	Amiga
+|os_beos.txt|	BeOS and BeBox
+|os_dos.txt|	MS-DOS and MS-Windows NT/95 common items
+|os_mac.txt|	Macintosh
+|os_mint.txt|	Atari MiNT
+|os_msdos.txt|	MS-DOS (plain DOS and DOS box under Windows)
+|os_os2.txt|	OS/2
+|os_qnx.txt|	QNX
+|os_risc.txt|	RISC-OS
+|os_unix.txt|	Unix
+|os_vms.txt|	VMS
+|os_win32.txt|	MS-Windows 95/98/NT
+						*standard-plugin-list*
+Standard plugins ~
+|pi_getscript.txt| Downloading latest version of Vim scripts
+|pi_gzip.txt|	   Reading and writing compressed files
+|pi_netrw.txt|	   Reading and writing files over a network
+|pi_paren.txt|	   Highlight matching parens
+|pi_tar.txt|	   Tar file explorer
+|pi_vimball.txt|   Create a self-installing Vim script
+|pi_zip.txt|	   Zip archive explorer
+
+LOCAL ADDITIONS:				*local-additions*
+
+------------------------------------------------------------------------------
+*bars*		Bars example
+
+Now that you've jumped here with CTRL-] or a double mouse click, you can use
+CTRL-T, CTRL-O, g<RightMouse>, or <C-RightMouse> to go back to where you were.
+
+Note that tags are within | characters, but when highlighting is enabled these
+are hidden.  That makes it easier to read a command.
+
+Anyway, you can use CTRL-] on any word, also when it is not within |, and Vim
+will try to find help for it.
+
+------------------------------------------------------------------------------
+ vim:tw=78:fo=tcq2:isk=!-~,^*,^\|,^\":ts=8:ft=help:norl:
--- /dev/null
+++ b/lib/vimfiles/doc/howto.txt
@@ -1,0 +1,96 @@
+*howto.txt*	For Vim version 7.1.  Last change: 2006 Apr 02
+
+
+		  VIM REFERENCE MANUAL	  by Bram Moolenaar
+
+
+How to ...				*howdoi* *how-do-i* *howto* *how-to*
+
+|tutor|			get started
+|:quit|			exit?  I'm trapped, help me!
+|initialization|	initialize Vim
+|vimrc-intro|		write a Vim script file (vimrc)
+|suspend|		suspend Vim
+|usr_11.txt|		recover after a crash
+|07.4|			keep a backup of my file when writing over it
+
+|usr_07.txt|		edit files
+|23.4|			edit binary files
+|usr_24.txt|		insert text
+|deleting|		delete text
+|usr_04.txt|		change text
+|04.5|			copy and move text
+|usr_25.txt|		format text
+|30.6|			format comments
+|30.2|			indent C programs
+|25.3|			automatically set indent
+
+|usr_26.txt|		repeat commands
+|02.5|			undo and redo
+
+|usr_03.txt|		move around
+|word-motions|		word motions
+|left-right-motions|	left-right motions
+|up-down-motions|	up-down motions
+|object-motions|	text-object motions
+|various-motions|	various motions
+|object-select|		text-object selection
+|'whichwrap'|		move over line breaks
+|'virtualedit'|		move to where there is no text
+|usr_27.txt|		specify pattern for searches
+|tags-and-searches|	do tags and special searches
+|29.4|			search in include'd files used to find
+			variables, functions, or macros
+|K|			look up manual for the keyword under cursor
+
+|03.7|			scroll
+|'sidescroll'|		scroll horizontally/sideways
+|'scrolloff'|		set visible context lines
+
+|mode-switching|	change modes
+|04.4|			use Visual mode
+|'insertmode'|		start Vim in Insert mode
+
+|40.1|			map keys
+|24.7|			create abbreviations
+
+|ins-expandtab|		expand a tab to spaces in Insert mode
+|i_CTRL-R|		insert contents of a register in Insert mode
+|24.3|			complete words in Insert mode
+|25.1|			break a line before it gets too long
+
+|20.1|			do command-line editing
+|20.3|			do command-line completion
+|'cmdheight'|		increase the height of command-line
+|10.3|			specify command-line ranges
+|40.3|			specify commands to be executed automatically
+			before/after reading/writing entering/leaving a
+			buffer/window
+
+|'autowrite'|		write automatically
+|30.1|			speedup edit-compile-edit cycle or compile and fix
+			errors within Vim
+
+|options|		set options
+|auto-setting|		set options automatically
+|term-dependent-settings| set options depending on terminal name
+|save-settings|		save settings
+|:quote|		comment my .vim files
+|'helpheight'|		change the default help height
+|'highlight'|		set various highlighting modes
+|'title'|		set the window title
+|'icon'|		set window icon title
+|'report'|		avoid seeing the change messages on every line
+|'shortmess'|		avoid |hit-enter| prompts
+
+|mouse-using|		use mouse with Vim
+|usr_08.txt|		manage multiple windows and buffers
+|gui.txt|		use the gui
+
+|You can't! (yet)|	do dishes using Vim
+
+|usr_06.txt|		switch on syntax highlighting
+|2html.vim|		convert a colored file to HTML
+|less|			use Vim like less or more with syntax highlighting
+
+ vim:tw=78:ts=8:ft=help:norl:
--- /dev/null
+++ b/lib/vimfiles/doc/if_cscop.txt
@@ -1,0 +1,483 @@
+*if_cscop.txt*  For Vim version 7.1.  Last change: 2005 Mar 29
+
+
+		  VIM REFERENCE MANUAL    by Andy Kahn
+
+							*cscope* *Cscope*
+This document explains how to use Vim's cscope interface.
+
+Cscope is a tool like ctags, but think of it as ctags on steroids since it
+does a lot more than what ctags provides.  In Vim, jumping to a result from
+a cscope query is just like jumping to any tag; it is saved on the tag stack
+so that with the right keyboard mappings, you can jump back and forth between
+functions as you normally would with |tags|.
+
+1. Cscope introduction		|cscope-intro|
+2. Cscope related commands	|cscope-commands|
+3. Cscope options		|cscope-options|
+4. How to use cscope in Vim	|cscope-howtouse|
+5. Limitations			|cscope-limitations|
+6. Suggested usage		|cscope-suggestions|
+7. Availability & Information	|cscope-info|
+
+This is currently for Unix and Win32 only.
+{Vi does not have any of these commands}
+
+==============================================================================
+1. Cscope introduction					*cscope-intro*
+
+The following text is taken from a version of the cscope man page:
+
+				    -----
+
+  Cscope is an interactive screen-oriented tool that helps you:
+
+       Learn how a C program works without endless flipping through a thick
+       listing.
+
+       Locate the section of code to change to fix a bug without having to
+       learn the entire program.
+
+       Examine the effect of a proposed change such as adding a value to an
+       enum variable.
+
+       Verify that a change has been made in all source files such as adding
+       an argument to an existing function.
+
+       Rename a global variable in all source files.
+
+       Change a constant to a preprocessor symbol in selected lines of files.
+
+  It is designed to answer questions like:
+       Where is this symbol used?
+       Where is it defined?
+       Where did this variable get its value?
+       What is this global symbol's definition?
+       Where is this function in the source files?
+       What functions call this function?
+       What functions are called by this function?
+       Where does the message "out of space" come from?
+       Where is this source file in the directory structure?
+       What files include this header file?
+
+  Cscope answers these questions from a symbol database that it builds the
+  first time it is used on the source files.  On a subsequent call, cscope
+  rebuilds the database only if a source file has changed or the list of
+  source files is different.  When the database is rebuilt the data for the
+  unchanged files is copied from the old database, which makes rebuilding
+  much faster than the initial build.
+
+				    -----
+
+When cscope is normally invoked, you will get a full-screen selection
+screen allowing you to make a query for one of the above questions.
+However, once a match is found to your query and you have entered your
+text editor to edit the source file containing match, you cannot simply
+jump from tag to tag as you normally would with vi's Ctrl-] or :tag
+command.
+
+Vim's cscope interface is done by invoking cscope with its line-oriented
+interface, and then parsing the output returned from a query.  The end
+result is that cscope query results become just like regular tags, so
+you can jump to them just like you do with normal tags (Ctrl-] or :tag)
+and then go back by popping off the tagstack with Ctrl-T.  (Please note
+however, that you don't actually jump to a cscope tag simply by doing
+Ctrl-] or :tag without remapping these commands or setting an option.
+See the remaining sections on how the cscope interface works and for
+suggested use.)
+
+
+==============================================================================
+2. Cscope related commands				*cscope-commands*
+
+		*:cscope* *:cs* *:scs* *:scscope* *E259* *E262* *E561* *E560*
+All cscope commands are accessed through suboptions to the main cscope
+command ":cscope".  The shortest abbreviation is ":cs".  The ":scscope"
+command does the same and also splits the window (short: "scs").
+
+The available subcommands are:
+
+			*E563* *E564* *E566* *E568* *E569* *E622* *E623*
+			*E625* *E626* *E609*
+    add   : Add a new cscope database/connection.
+
+	USAGE	:cs add {file|dir} [pre-path] [flags]
+
+	    [pre-path] is the pathname used with the -P command to cscope.
+
+	    [flags] are any additional flags you want to pass to cscope.
+
+	EXAMPLES >
+	    :cscope add /usr/local/cdb/cscope.out
+	    :cscope add /projects/vim/cscope.out /usr/local/vim
+	    :cscope add cscope.out /usr/local/vim -C
+<
+				      *cscope-find* *cs-find*
+						*E565* *E567*
+    find  : Query cscope.  All cscope query options are available
+	    except option #5 ("Change this grep pattern").
+
+	USAGE	:cs find {querytype} {name}
+
+	    {querytype} corresponds to the actual cscope line
+	    interface numbers as well as default nvi commands:
+
+		0 or s: Find this C symbol
+		1 or g: Find this definition
+		2 or d: Find functions called by this function
+		3 or c: Find functions calling this function
+		4 or t: Find this text string
+		6 or e: Find this egrep pattern
+		7 or f: Find this file
+		8 or i: Find files #including this file
+
+	EXAMPLES >
+	    :cscope find c vim_free
+	    :cscope find 3 vim_free
+<
+	    These two examples perform the same query. >
+
+	    :cscope find 0 DEFAULT_TERM
+<
+	    Executing this example on the source code for Vim 5.1 produces the
+	    following output:
+
+	    Cscope tag: DEFAULT_TERM
+	       #   line  filename / context / line
+	       1   1009  vim-5.1-gtk/src/term.c <<GLOBAL>>
+			 #define DEFAULT_TERM (char_u *)"amiga"
+	       2   1013  vim-5.1-gtk/src/term.c <<GLOBAL>>
+			 #define DEFAULT_TERM (char_u *)"win32"
+	       3   1017  vim-5.1-gtk/src/term.c <<GLOBAL>>
+			 #define DEFAULT_TERM (char_u *)"pcterm"
+	       4   1021  vim-5.1-gtk/src/term.c <<GLOBAL>>
+			 #define DEFAULT_TERM (char_u *)"ansi"
+	       5   1025  vim-5.1-gtk/src/term.c <<GLOBAL>>
+			 #define DEFAULT_TERM (char_u *)"vt52"
+	       6   1029  vim-5.1-gtk/src/term.c <<GLOBAL>>
+			 #define DEFAULT_TERM (char_u *)"os2ansi"
+	       7   1033  vim-5.1-gtk/src/term.c <<GLOBAL>>
+			 #define DEFAULT_TERM (char_u *)"ansi"
+	       8   1037  vim-5.1-gtk/src/term.c <<GLOBAL>>
+			 # undef DEFAULT_TERM
+	       9   1038  vim-5.1-gtk/src/term.c <<GLOBAL>>
+			 #define DEFAULT_TERM (char_u *)"beos-ansi"
+	      10   1042  vim-5.1-gtk/src/term.c <<GLOBAL>>
+			 #define DEFAULT_TERM (char_u *)"mac-ansi"
+	      11   1335  vim-5.1-gtk/src/term.c <<set_termname>>
+			 term = DEFAULT_TERM;
+	      12   1459  vim-5.1-gtk/src/term.c <<set_termname>>
+			 if (STRCMP(term, DEFAULT_TERM))
+	      13   1826  vim-5.1-gtk/src/term.c <<termcapinit>>
+			 term = DEFAULT_TERM;
+	      14   1833  vim-5.1-gtk/src/term.c <<termcapinit>>
+			 term = DEFAULT_TERM;
+	      15   3635  vim-5.1-gtk/src/term.c <<update_tcap>>
+			 p = find_builtin_term(DEFAULT_TERM);
+	    Enter nr of choice (<CR> to abort):
+
+	    The output shows several pieces of information:
+	    1. The tag number (there are 15 in this example).
+	    2. The line number where the tag occurs.
+	    3. The filename where the tag occurs.
+	    4. The context of the tag (e.g., global, or the function name).
+	    5. The line from the file itself.
+
+    help  : Show a brief synopsis.
+
+	    USAGE   :cs help
+
+						*E260* *E261*
+    kill  : Kill a cscope connection (or kill all cscope connections).
+
+	    USAGE   :cs kill {num|partial_name}
+
+	    To kill a cscope connection, the connection number or a partial
+	    name must be specified.  The partial name is simply any part of
+	    the pathname of the cscope database.  Kill a cscope connection
+	    using the partial name with caution!
+
+	    If the specified connection number is -1, then _ALL_ cscope
+	    connections will be killed.
+
+    reset : Reinit all cscope connections.
+
+	    USAGE   :cs reset
+
+    show  : Show cscope connections.
+
+	    USAGE   :cs show
+
+							*:lcscope* *:lcs*
+This command is same as the ":cscope" command, except when the
+'cscopequickfix' option is set, the location list for the current window is
+used instead of the quickfix list to show the cscope results.
+
+							*:cstag* *E257* *E562*
+If you use cscope as well as ctags, |:cstag| allows you to search one or
+the other before making a jump.  For example, you can choose to first
+search your cscope database(s) for a match, and if one is not found, then
+your tags file(s) will be searched.  The order in which this happens
+is determined by the value of |csto|.  See |cscope-options| for more
+details.
+
+|:cstag| performs the equivalent of ":cs find g" on the identifier when
+searching through the cscope database(s).
+
+|:cstag| performs the equivalent of |:tjump| on the identifier when searching
+through your tags file(s).
+
+
+==============================================================================
+3. Cscope options					*cscope-options*
+
+Use the |:set| command to set all cscope options.  Ideally, you would do
+this in one of your startup files (e.g., .vimrc).  Some cscope related
+variables are only valid within |.vimrc|.  Setting them after vim has
+started will have no effect!
+
+							*cscopeprg* *csprg*
+'cscopeprg' specifies the command to execute cscope.  The default is
+"cscope".  For example: >
+	:set csprg=/usr/local/bin/cscope
+<
+					    *cscopequickfix* *csqf* *E469*
+{not available when compiled without the |+quickfix| feature}
+'cscopequickfix' specifies whether to use quickfix window to show cscope
+results.  This is a list of comma-separated values. Each item consists of
+|cscope-find| command (s, g, d, c, t, e, f or i) and flag (+, - or 0).
+'+' indicates that results must be appended to quickfix window,
+'-' implies previous results clearance, '0' or command absence - don't use
+quickfix.  Search is performed from start until first command occurrence.
+The default value is "" (don't use quickfix anyway).  The following value
+seems to be useful: >
+	:set cscopequickfix=s-,c-,d-,i-,t-,e-
+<
+							*cscopetag* *cst*
+If 'cscopetag' set, the commands ":tag" and CTRL-] as well as "vim -t" will
+always use |:cstag| instead of the default :tag behavior.  Effectively, by
+setting 'cst', you will always search your cscope databases as well as your
+tag files.  The default is off.  Examples: >
+	:set cst
+	:set nocst
+<
+							*cscopetagorder* *csto*
+The value of 'csto' determines the order in which |:cstag| performs a search.
+If 'csto' is set to zero, cscope database(s) are searched first, followed
+by tag file(s) if cscope did not return any matches.  If 'csto' is set to
+one, tag file(s) are searched before cscope database(s).  The default is zero.
+Examples: >
+	:set csto=0
+	:set csto=1
+<
+						*cscopeverbose* *csverb*
+If 'cscopeverbose' is not set (the default), messages will not be printed
+indicating success or failure when adding a cscope database.  Ideally, you
+should reset this option in your |.vimrc| before adding any cscope databases,
+and after adding them, set it.  From then on, when you add more databases
+within Vim, you will get a (hopefully) useful message should the database fail
+to be added.  Examples: >
+	:set csverb
+	:set nocsverb
+<
+						      *cscopepathcomp* *cspc*
+The value of 'cspc' determines how many components of a file's path to
+display.  With the default value of zero the entire path will be displayed.
+The value one will display only the filename with no path.  Other values
+display that many components.  For example: >
+	:set cspc=3
+will display the last 3 components of the file's path, including the file
+name itself.
+
+==============================================================================
+4. How to use cscope in Vim				*cscope-howtouse*
+
+The first thing you need to do is to build a cscope database for your
+source files.  For the most basic case, simply do "cscope -b".  Please
+refer to the cscope man page for more details.
+
+Assuming you have a cscope database, you need to "add" the database to Vim.
+This establishes a cscope "connection" and makes it available for Vim to use.
+You can do this in your .vimrc file, or you can do it manually after starting
+vim.  For example, to add the cscope database "cscope.out", you would do:
+
+	:cs add cscope.out
+
+You can double-check the result of this by executing ":cs show".  This will
+produce output which looks like this:
+
+ # pid	  database name			      prepend path
+ 0 28806  cscope.out			      <none>
+
+Note:
+Because of the Microsoft RTL limitations, Win32 version shows 0 instead
+of the real pid.
+
+Once a cscope connection is established, you can make queries to cscope and
+the results will be printed to you.  Queries are made using the command
+":cs find".  For example:
+
+	:cs find g ALIGN_SIZE
+
+This can get a little cumbersome since one ends up doing a significant
+amount of typing.  Fortunately, there are ways around this by mapping
+shortcut keys.  See |cscope-suggestions| for suggested usage.
+
+If the results return only one match, you will automatically be taken to it.
+If there is more than one match, you will be given a selection screen to pick
+the match you want to go to.  After you have jumped to the new location,
+simply hit Ctrl-T to get back to the previous one.
+
+
+==============================================================================
+5. Limitations						*cscope-limitations*
+
+Cscope support for Vim is only available on systems that support these four
+system calls: fork(), pipe(), execl(), waitpid().  This means it is mostly
+limited to Unix systems.
+
+Additionally Cscope support works for Win32.  For more information and a
+cscope version for Win32 see:
+
+	http://iamphet.nm.ru/cscope/index.html
+
+The DJGPP-built version from http://cscope.sourceforge.net is known to not
+work with Vim.
+
+There are a couple of hard-coded limitations:
+
+    1. The maximum number of cscope connections allowed is 8.  Do you
+    really need more?
+
+    2. Doing a |:tjump| when |:cstag| searches the tag files is not
+    configurable (e.g., you can't do a tselect instead).
+
+==============================================================================
+6. Suggested usage					*cscope-suggestions*
+
+Put these entries in your .vimrc (adjust the pathname accordingly to your
+setup): >
+
+	if has("cscope")
+		set csprg=/usr/local/bin/cscope
+		set csto=0
+		set cst
+		set nocsverb
+		" add any database in current directory
+		if filereadable("cscope.out")
+		    cs add cscope.out
+		" else add database pointed to by environment
+		elseif $CSCOPE_DB != ""
+		    cs add $CSCOPE_DB
+		endif
+		set csverb
+	endif
+
+By setting 'cscopetag', we have effectively replaced all instances of the :tag
+command with :cstag.  This includes :tag, Ctrl-], and "vim -t".  In doing
+this, the regular tag command not only searches your ctags generated tag
+files, but your cscope databases as well.
+
+Some users may want to keep the regular tag behavior and have a different
+shortcut to access :cstag.  For example, one could map Ctrl-_  (underscore)
+to :cstag with the following command: >
+
+	map <C-_> :cstag <C-R>=expand("<cword>")<CR><CR>
+
+A couple of very commonly used cscope queries (using ":cs find") is to
+find all functions calling a certain function and to find all occurrences
+of a particular C symbol.  To do this, you can use these mappings as an
+example: >
+
+	map g<C-]> :cs find 3 <C-R>=expand("<cword>")<CR><CR>
+	map g<C-\> :cs find 0 <C-R>=expand("<cword>")<CR><CR>
+
+These mappings for Ctrl-] (right bracket) and Ctrl-\ (backslash) allow you to
+place your cursor over the function name or C symbol and quickly query cscope
+for any matches.
+
+Or you may use the following scheme, inspired by Vim/Cscope tutorial from
+Cscope Home Page (http://cscope.sourceforge.net/): >
+
+	nmap <C-_>s :cs find s <C-R>=expand("<cword>")<CR><CR>
+	nmap <C-_>g :cs find g <C-R>=expand("<cword>")<CR><CR>
+	nmap <C-_>c :cs find c <C-R>=expand("<cword>")<CR><CR>
+	nmap <C-_>t :cs find t <C-R>=expand("<cword>")<CR><CR>
+	nmap <C-_>e :cs find e <C-R>=expand("<cword>")<CR><CR>
+	nmap <C-_>f :cs find f <C-R>=expand("<cfile>")<CR><CR>
+	nmap <C-_>i :cs find i ^<C-R>=expand("<cfile>")<CR>$<CR>
+	nmap <C-_>d :cs find d <C-R>=expand("<cword>")<CR><CR>
+
+	" Using 'CTRL-spacebar' then a search type makes the vim window
+	" split horizontally, with search result displayed in
+	" the new window.
+
+	nmap <C-Space>s :scs find s <C-R>=expand("<cword>")<CR><CR>
+	nmap <C-Space>g :scs find g <C-R>=expand("<cword>")<CR><CR>
+	nmap <C-Space>c :scs find c <C-R>=expand("<cword>")<CR><CR>
+	nmap <C-Space>t :scs find t <C-R>=expand("<cword>")<CR><CR>
+	nmap <C-Space>e :scs find e <C-R>=expand("<cword>")<CR><CR>
+	nmap <C-Space>f :scs find f <C-R>=expand("<cfile>")<CR><CR>
+	nmap <C-Space>i :scs find i ^<C-R>=expand("<cfile>")<CR>$<CR>
+	nmap <C-Space>d :scs find d <C-R>=expand("<cword>")<CR><CR>
+
+	" Hitting CTRL-space *twice* before the search type does a vertical
+	" split instead of a horizontal one
+
+	nmap <C-Space><C-Space>s
+		\:vert scs find s <C-R>=expand("<cword>")<CR><CR>
+	nmap <C-Space><C-Space>g
+		\:vert scs find g <C-R>=expand("<cword>")<CR><CR>
+	nmap <C-Space><C-Space>c
+		\:vert scs find c <C-R>=expand("<cword>")<CR><CR>
+	nmap <C-Space><C-Space>t
+		\:vert scs find t <C-R>=expand("<cword>")<CR><CR>
+	nmap <C-Space><C-Space>e
+		\:vert scs find e <C-R>=expand("<cword>")<CR><CR>
+	nmap <C-Space><C-Space>i
+		\:vert scs find i ^<C-R>=expand("<cfile>")<CR>$<CR>
+	nmap <C-Space><C-Space>d
+		\:vert scs find d <C-R>=expand("<cword>")<CR><CR>
+
+==============================================================================
+7. Cscope availability and information			*cscope-info*
+
+If you do not already have cscope (it did not come with your compiler
+license or OS distribution), then you can download it for free from:
+	http://cscope.sourceforge.net/
+This is released by SCO under the BSD license.
+
+If you want a newer version of cscope, you will probably have to buy it.
+According to the (old) nvi documentation:
+
+	You can buy version 13.3 source with an unrestricted license
+	for $400 from AT&T Software Solutions by calling +1-800-462-8146.
+
+Also you can download cscope 13.x and mlcscope 14.x (multi-lingual cscope
+which supports C, C++, Java, lex, yacc, breakpoint listing, Ingres, and SDL)
+from World-Wide Exptools Open Source packages page:
+	http://www.bell-labs.com/project/wwexptools/packages.html
+
+In Solaris 2.x, if you have the C compiler license, you will also have
+cscope.  Both are usually located under /opt/SUNWspro/bin
+
+SGI developers can also get it.  Search for Cscope on this page:
+	http://freeware.sgi.com/index-by-alpha.html
+	https://toolbox.sgi.com/toolbox/utilities/cscope/
+The second one is for those who have a password for the SGI toolbox.
+
+There is source to an older version of a cscope clone (called "cs") available
+on the net.  Due to various reasons, this is not supported with Vim.
+
+The cscope interface/support for Vim was originally written by
+Andy Kahn <ackahn@netapp.com>.  The original structure (as well as a tiny
+bit of code) was adapted from the cscope interface in nvi.  Please report
+any problems, suggestions, patches, et al., you have for the usage of
+cscope within Vim to him.
+							*cscope-win32*
+For a cscope version for Win32 see: http://iamphet.nm.ru/cscope/index.html
+
+Win32 support was added by Sergey Khorev <sergey.khorev@gmail.com>.  Contact
+him if you have Win32-specific issues.
+
+ vim:tw=78:ts=8:ft=help:norl:
--- /dev/null
+++ b/lib/vimfiles/doc/if_mzsch.txt
@@ -1,0 +1,272 @@
+*if_mzsch.txt*  For Vim version 7.1.  Last change: 2007 May 03
+
+
+		  VIM REFERENCE MANUAL    by Sergey Khorev
+
+
+The MzScheme Interface to Vim				*mzscheme* *MzScheme*
+
+1. Commands				|mzscheme-commands|
+2. Examples				|mzscheme-examples|
+3. Threads				|mzscheme-threads|
+4. The Vim access procedures		|mzscheme-vim|
+5. Dynamic loading			|mzscheme-dynamic|
+
+{Vi does not have any of these commands}
+
+The MzScheme interface is available only if Vim was compiled with the
+|+mzscheme| feature.
+
+Based on the work of Brent Fulgham.
+Dynamic loading added by Sergey Khorev
+
+For downloading MzScheme and other info:
+	http://www.plt-scheme.org/software/mzscheme/
+
+Note: On FreeBSD you should use the "drscheme" port.
+
+==============================================================================
+1. Commands						*mzscheme-commands*
+
+							*:mzscheme* *:mz*
+:[range]mz[scheme] {stmt}
+			Execute MzScheme statement {stmt}.  {not in Vi}
+
+:[range]mz[scheme] << {endmarker}
+{script}
+{endmarker}
+			Execute inlined MzScheme script {script}.
+			Note: This command doesn't work if the MzScheme
+			feature wasn't compiled in.  To avoid errors, see
+			|script-here|.
+
+							*:mzfile* *:mzf*
+:[range]mzf[ile] {file}	Execute the MzScheme script in {file}.  {not in Vi}
+			All statements are executed in the namespace of the
+			buffer that was current during :mzfile start.
+			If you want to access other namespaces, use
+			'parameterize'.
+
+All of these commands do essentially the same thing - they execute a piece of
+MzScheme code, with the "current range" set to the given line
+range.
+
+In the case of :mzscheme, the code to execute is in the command-line.
+In the case of :mzfile, the code to execute is the contents of the given file.
+
+Each buffer has its own MzScheme namespace. Global namespace is bound to
+the `global-namespace' value from the 'vimext' module.
+MzScheme interface defines exception exn:vim, derived from exn.
+It is raised for various Vim errors.
+
+During compilation, the MzScheme interface will remember the current MzScheme
+collection path. If you want to specify additional paths use the
+'current-library-collection-paths' parameter. E.g., to cons the user-local
+MzScheme collection path: >
+    :mz << EOF
+    (current-library-collection-paths
+	(cons
+	    (build-path (find-system-path 'addon-dir) (version) "collects")
+	    (current-library-collection-paths)))
+    EOF
+<
+
+All functionality is provided through module vimext.
+
+The exn:vim is available without explicit import.
+
+To avoid clashes with MzScheme, consider using prefix when requiring module,
+e.g.: >
+	:mzscheme (require (prefix vim- vimext))
+<
+All the examples below assume this naming scheme.  Note that you need to do
+this again for every buffer.
+
+The auto-instantiation can be achieved with autocommands, e.g. you can put
+something like this in your .vimrc (EOFs should not have indentation): >
+    function s:MzRequire()
+	if has("mzscheme")
+	    :mz << EOF
+	    (require (prefix vim- vimext))
+	    (let ((buf (vim-get-buff-by-name (vim-eval "expand(\"<afile>\")"))))
+	      (when (and buf (not (eq? buf (vim-curr-buff))))
+		(parameterize ((current-namespace (vim-get-buff-namespace buf)))
+		  (namespace-attach-module vim-global-namespace 'vimext)
+		  (namespace-require '(prefix vim vimext)))))
+    EOF
+	endif
+    endfunction
+
+    function s:MzStartup()
+	if has("mzscheme")
+	    au BufNew,BufNewFile,BufAdd,BufReadPre * :call s:MzRequire()
+	    :mz << EOF
+	    (current-library-collection-paths
+		(cons
+		    (build-path (find-system-path 'addon-dir) (version) "collects")
+		    (current-library-collection-paths)))
+    EOF
+	endif
+    endfunction
+
+    call s:MzStartup()
+<
+
+The global namespace just instantiated this module with the prefix "vimext:".
+							*mzscheme-sandbox*
+When executed in the |sandbox|, access to some filesystem and Vim interface
+procedures is restricted.
+
+==============================================================================
+2. Examples						*mzscheme-examples*
+>
+	:mzscheme (display "Hello")
+	:mzscheme (vim-set-buff-line 10 "This is line #10")
+<
+Inline script usage: >
+	function! <SID>SetFirstLine()
+	    :mz << EOF
+	    (display "!!!")
+	    (vim-set-buff-line 1 "This is line #1")
+	    (vim-beep)
+	    EOF
+	endfunction
+
+	nmap <F9> :call <SID>SetFirstLine() <CR>
+<
+File execution: >
+	:mzfile supascript.scm
+<
+Accessing the current buffer namespace from an MzScheme program running in
+another buffer within |:mzfile|-executed script : >
+	; Move to the window below
+	(vim-command "wincmd j")
+	; execute in the context of buffer, to which window belongs
+	; assume that buffer has 'textstring' defined
+	(parameterize ((current-namespace
+			(vim-get-buff-namespace (vim-curr-buff))))
+	 (eval '(vim-set-buff-line 1 textstring)))
+<
+
+==============================================================================
+3. Threads						*mzscheme-threads*
+
+The MzScheme interface supports threads. They are independent from OS threads,
+thus scheduling is required. The option 'mzquantum' determines how often
+Vim should poll for available MzScheme threads.
+NOTE
+Thread scheduling in the console version of Vim is less reliable than in the
+GUI version.
+
+==============================================================================
+5. VIM Functions					*mzscheme-vim*
+
+							*mzscheme-vimext*
+The 'vimext' module provides access to procedures defined in the MzScheme
+interface.
+
+Common
+------
+    (command {command-string})	    Perform the vim ":Ex" style command.
+    (eval {expr-string})	    Evaluate the vim expression to a string.
+				    A |List| is turned into a string by
+				    joining the items and inserting line
+				    breaks.
+				    NOTE clashes with MzScheme eval
+    (range-start)		    Start/End of the range passed with
+    (range-end)			    the Scheme command.
+    (beep)			    beep
+    (get-option {option-name} [buffer-or-window]) Get Vim option value (either
+				    local or global, see set-option).
+    (set-option {string} [buffer-or-window])
+				    Set a Vim option. String must have option
+				    setting form (like optname=optval, or
+				    optname+=optval, etc.) When called with
+				    {buffer} or {window} the local option will
+				    be set. The symbol 'global can be passed
+				    as {buffer-or-window}. Then |:setglobal|
+				    will be used.
+    global-namespace		    The MzScheme main namespace.
+
+Buffers							 *mzscheme-buffer*
+-------
+    (buff? {object})		    Is object a buffer?
+    (buff-valid? {object})	    Is object a valid buffer? (i.e.
+				    corresponds to the real Vim buffer)
+    (get-buff-line {linenr} [buffer])
+				    Get line from a buffer.
+    (set-buff-line {linenr} {string} [buffer])
+				    Set a line in a buffer. If {string} is #f,
+				    the line gets deleted.  The [buffer]
+				    argument is optional. If omitted, the
+				    current buffer will be used.
+    (get-buff-line-list {start} {end} [buffer])
+				    Get a list of lines in a buffer. {Start}
+				    and {end} are 1-based. {Start} is
+				    inclusive, {end} - exclusive.
+    (set-buff-line-list {start} {end} {string-list} [buffer])
+				    Set a list of lines in a buffer. If
+				    string-list is #f or null, the lines get
+				    deleted. If a list is shorter than
+				    {end}-{start} the remaining lines will
+				    be deleted.
+    (get-buff-name [buffer])	    Get a buffer's text name.
+    (get-buff-num [buffer])	    Get a buffer's number.
+    (get-buff-size [buffer])	    Get buffer line count.
+    (insert-buff-line-list {linenr} {string/string-list} [buffer])
+				    Insert a list of lines into a buffer after
+				    {linenr}. If {linenr} is 0, lines will be
+				    inserted at start.
+    (curr-buff)			    Get the current buffer. Use procedures
+				    from `vimcmd' module to change it.
+    (buff-count)		    Get count of total buffers in the editor.
+    (get-next-buff [buffer])	    Get next buffer.
+    (get-prev-buff [buffer])	    Get previous buffer. Return #f when there
+				    are no more buffers.
+    (open-buff {filename})	    Open a new buffer (for file "name")
+    (get-buff-by-name {buffername}) Get a buffer by its filename or #f
+					if there is no such buffer.
+    (get-buff-by-num {buffernum})   Get a buffer by its number (return #f if
+				    there is no buffer with this number).
+    (get-buff-namespace [buffer])   Get buffer namespace.
+
+Windows							    *mzscheme-window*
+------
+    (win? {object})		    Is object a window?
+    (win-valid? {object})	    Is object a valid window (i.e. corresponds
+				    to the real Vim window)?
+    (curr-win)			    Get the current window.
+    (win-count)			    Get count of windows.
+    (get-win-num [window])	    Get window number.
+    (get-win-by-num {windownum})    Get window by its number.
+    (get-win-buffer	[window])   Get the buffer for a given window.
+    (get-win-height [window])
+    (set-win-height {height} [window])  Get/Set height of window.
+    (get-win-width [window])
+    (set-win-width {width} [window])Get/Set width of window.
+    (get-win-list [buffer])	    Get list of windows for a buffer.
+    (get-cursor [window])	    Get cursor position in a window as
+				    a pair (linenr . column).
+    (set-cursor (line . col) [window])  Set cursor position.
+
+==============================================================================
+5. Dynamic loading					*mzscheme-dynamic*
+
+On MS-Windows the MzScheme libraries can be loaded dynamically. The |:version|
+output then includes |+mzscheme/dyn|.
+
+This means that Vim will search for the MzScheme DLL files only when needed.
+When you don't use the MzScheme interface you don't need them, thus you can
+use Vim without these DLL files.
+
+To use the MzScheme interface the MzScheme DLLs must be in your search path.
+In a console window type "path" to see what directories are used.
+
+The names of the DLLs must match the MzScheme version Vim was compiled with.
+For MzScheme version 209 they will be "libmzsch209_000.dll" and
+"libmzgc209_000.dll". To know for sure look at the output of the ":version"
+command, look for -DDYNAMIC_MZSCH_DLL="something" and
+-DDYNAMIC_MZGC_DLL="something" in the "Compilation" info.
+
+======================================================================
+  vim:tw=78:ts=8:sts=4:ft=help:norl:
--- /dev/null
+++ b/lib/vimfiles/doc/if_ole.txt
@@ -1,0 +1,205 @@
+*if_ole.txt*    For Vim version 7.1.  Last change: 2007 May 10
+
+
+		  VIM REFERENCE MANUAL    by Paul Moore
+
+
+The OLE Interface to Vim				*ole-interface*
+
+1. Activation			|ole-activation|
+2. Methods			|ole-methods|
+3. The "normal" command		|ole-normal|
+4. Registration			|ole-registration|
+5. MS Visual Studio integration	|MSVisualStudio|
+
+{Vi does not have any of these commands}
+
+OLE is only available when compiled with the |+ole| feature.  See
+src/if_ole.INSTALL.
+An alternative is using the client-server communication |clientserver|.
+
+==============================================================================
+1. Activation						*ole-activation*
+
+Vim acts as an OLE automation server, accessible from any automation client,
+for example, Visual Basic, Python, or Perl.  The Vim application "name" (its
+"ProgID", in OLE terminology) is "Vim.Application".
+
+Hence, in order to start a Vim instance (or connect to an already running
+instance), code similar to the following should be used:
+
+[Visual Basic] >
+	Dim Vim As Object
+	Set Vim = CreateObject("Vim.Application")
+
+[Python] >
+	from win32com.client.dynamic import Dispatch
+	vim = Dispatch('Vim.Application')
+
+[Perl] >
+	use Win32::OLE;
+	$vim = new Win32::OLE 'Vim.Application';
+
+[C#] >
+        // Add a reference to VIM in your project. 
+        // Choose the COM tab.
+        // Select "VIM Ole Interface 1.1 Type Library"
+	Vim.Vim vimobj = new Vim.Vim();
+
+Vim does not support acting as a "hidden" OLE server, like some other OLE
+Automation servers.  When a client starts up an instance of Vim, that instance
+is immediately visible.  Simply closing the OLE connection to the Vim instance
+is not enough to shut down the Vim instance - it is necessary to explicitly
+execute a quit command (for example, :qa!, :wqa).
+
+==============================================================================
+2. Methods						*ole-methods*
+
+Vim exposes four methods for use by clients.
+
+							*ole-sendkeys*
+SendKeys(keys)		Execute a series of keys.
+
+This method takes a single parameter, which is a string of keystrokes.  These
+keystrokes are executed exactly as if they had been types in at the keyboard.
+Special keys can be given using their <..> names, as for the right hand side
+of a mapping.  Note: Execution of the Ex "normal" command is not supported -
+see below |ole-normal|.
+
+Examples (Visual Basic syntax) >
+	Vim.SendKeys "ihello<Esc>"
+	Vim.SendKeys "ma1GV4jy`a"
+
+These examples assume that Vim starts in Normal mode.  To force Normal mode,
+start the key sequence with CTRL-\ CTRL-N as in >
+
+	Vim.SendKeys "<C-\><C-N>ihello<Esc>"
+
+CTRL-\ CTRL-N returns Vim to Normal mode, when in Insert or Command-line mode.
+Note that this doesn't work halfway a Vim command
+
+							*ole-eval*
+Eval(expr)		Evaluate an expression.
+
+This method takes a single parameter, which is an expression in Vim's normal
+format (see |expression|).  It returns a string, which is the result of
+evaluating the expression.  A |List| is turned into a string by joining the
+items and inserting line breaks.
+
+Examples (Visual Basic syntax) >
+	Line20 = Vim.Eval("getline(20)")
+	Twelve = Vim.Eval("6 + 6")		' Note this is a STRING
+	Font = Vim.Eval("&guifont")
+<
+							*ole-setforeground*
+SetForeground()		Make the Vim window come to the foreground
+
+This method takes no arguments.  No value is returned.
+
+Example (Visual Basic syntax) >
+	Vim.SetForeground
+<
+
+							*ole-gethwnd*
+GetHwnd()		Return the handle of the Vim window.
+
+This method takes no arguments.  It returns the hwnd of the main Vimwindow.
+You can use this if you are writing something which needs to manipulate the
+Vim window, or to track it in the z-order, etc.
+
+Example (Visual Basic syntax) >
+	Vim_Hwnd = Vim.GetHwnd
+<
+
+==============================================================================
+3. The "normal" command					*ole-normal*
+
+Due to the way Vim processes OLE Automation commands, combined with the method
+of implementation of the ex command :normal, it is not possible to execute the
+:normal command via OLE automation.  Any attempt to do so will fail, probably
+harmlessly, although possibly in unpredictable ways.
+
+There is currently no practical way to trap this situation, and users must
+simply be aware of the limitation.
+==============================================================================
+4. Registration					*ole-registration* *E243*
+
+Before Vim will act as an OLE server, it must be registered in the system
+registry.  In order to do this, Vim should be run with a single parameter of
+"-register".
+							*-register*  >
+	gvim -register
+
+If gvim with OLE support is run and notices that no Vim OLE server has been
+registered, it will present a dialog and offers you the choice to register by
+clicking "Yes".
+
+In some situations registering is not possible.  This happens when the
+registry is not writable.  If you run into this problem you need to run gvim
+as "Administrator".
+
+Once vim is registered, the application path is stored in the registry.
+Before moving, deleting, or upgrading Vim, the registry entries should be
+removed using the "-unregister" switch.
+							*-unregister*  >
+	gvim -unregister
+
+The OLE mechanism will use the first registered Vim it finds.  If a Vim is
+already running, this one will be used.  If you want to have (several) Vim
+sessions open that should not react to OLE commands, use the non-OLE version,
+and put it in a different directory.  The OLE version should then be put in a
+directory that is not in your normal path, so that typing "gvim" will start
+the non-OLE version.
+
+							*-silent*
+To avoid the message box that pops up to report the result, prepend "-silent":
+>
+	gvim -silent -register
+	gvim -silent -unregister
+
+==============================================================================
+5. MS Visual Studio integration			*MSVisualStudio* *VisVim*
+
+The OLE version can be used to run Vim as the editor in Microsoft Visual
+Studio.  This is called "VisVim".  It is included in the archive that contains
+the OLE version.  The documentation can be found in the runtime directory, the
+README_VisVim.txt file.
+
+
+Using Vim with Visual Studio .Net~
+
+With .Net you no longer really need VisVim, since .Net studio has support for
+external editors.  Follow these directions:
+
+In .Net Studio choose from the menu Tools->External Tools...
+Add
+     Title     - Vim
+     Command   - c:\vim\vim63\gvim.exe
+     Arguments - --servername VS_NET --remote-silent "+call cursor($(CurLine), $(CurCol))" $(ItemPath)
+     Init Dir  - Empty
+
+Now, when you open a file in .Net, you can choose from the .Net menu:
+Tools->Vim
+
+That will open the file in Vim.
+You can then add this external command as an icon and place it anywhere you
+like.  You might also be able to set this as your default editor.
+
+If you refine this further, please post back to the Vim maillist so we have a
+record of it.
+
+--servername VS_NET
+This will create a new instance of vim called VS_NET.  So if you open multiple
+files from VS, they will use the same instance of Vim.  This allows you to
+have multiple copies of Vim running, but you can control which one has VS
+files in it.
+
+--remote-silent "+call cursor(10, 27)"
+	      - Places the cursor on line 10 column 27
+In Vim >
+   :h --remote-silent for mor details
+
+[.Net remarks provided by Dave Fishburn and Brian Sturk]
+
+==============================================================================
+ vim:tw=78:ts=8:ft=help:norl:
--- /dev/null
+++ b/lib/vimfiles/doc/if_perl.txt
@@ -1,0 +1,283 @@
+*if_perl.txt*   For Vim version 7.1.  Last change: 2006 Mar 06
+
+
+		  VIM REFERENCE MANUAL    by Sven Verdoolaege
+					 and Matt Gerassimof
+
+Perl and Vim				*perl* *Perl*
+
+1. Editing Perl files			|perl-editing|
+2. Compiling VIM with Perl interface	|perl-compiling|
+3. Using the Perl interface		|perl-using|
+4. Dynamic loading			|perl-dynamic|
+
+{Vi does not have any of these commands}
+
+The Perl interface only works when Vim was compiled with the |+perl| feature.
+
+==============================================================================
+1. Editing Perl files					*perl-editing*
+
+Vim syntax highlighting supports Perl and POD files.  Vim assumes a file is
+Perl code if the filename has a .pl or .pm suffix.  Vim also examines the first
+line of a file, regardless of the filename suffix, to check if a file is a
+Perl script (see scripts.vim in Vim's syntax directory).  Vim assumes a file
+is POD text if the filename has a .POD suffix.
+
+To use tags with Perl, you need a recent version of Exuberant ctags.  Look
+here:
+	http://ctags.sourceforge.net
+
+Alternatively, you can use the Perl script pltags.pl, which is shipped with
+Vim in the $VIMRUNTIME/tools directory.  This script has currently more
+features than Exuberant ctags' Perl support.
+
+==============================================================================
+2. Compiling VIM with Perl interface			*perl-compiling*
+
+To compile Vim with Perl interface, you need Perl 5.004 (or later).  Perl must
+be installed before you compile Vim.  Vim's Perl interface does NOT work with
+the 5.003 version that has been officially released!  It will probably work
+with Perl 5.003_05 and later.
+
+The Perl patches for Vim were made by:
+	Sven Verdoolaege <skimo@breughel.ufsia.ac.be>
+	Matt Gerassimof
+
+Perl for MS-Windows can be found at:
+http://www.perl.com/CPAN/ports/nt/Standard/x86/
+
+==============================================================================
+3. Using the Perl interface				*perl-using*
+
+							*:perl* *:pe*
+:pe[rl] {cmd}		Execute Perl command {cmd}.  The current package
+			is "main".
+
+:pe[rl] << {endpattern}
+{script}
+{endpattern}
+			Execute Perl script {script}.
+			{endpattern} must NOT be preceded by any white space.
+			If {endpattern} is omitted, it defaults to a dot '.'
+			like for the |:append| and |:insert| commands.  Using
+			'.' helps when inside a function, because "$i;" looks
+			like the start of an |:insert| command to Vim.
+			This form of the |:perl| command is mainly useful for
+			including perl code in vim scripts.
+			Note: This command doesn't work when the Perl feature
+			wasn't compiled in.  To avoid errors, see
+			|script-here|.
+
+
+Example vim script: >
+
+	function! WhitePearl()
+	perl << EOF
+		VIM::Msg("pearls are nice for necklaces");
+		VIM::Msg("rubys for rings");
+		VIM::Msg("pythons for bags");
+		VIM::Msg("tcls????");
+	EOF
+	endfunction
+<
+
+							*:perldo* *:perld*
+:[range]perld[o] {cmd}	Execute Perl command {cmd} for each line in the
+			[range], with $_ being set to the text of each line in
+			turn, without a trailing <EOL>.  Setting $_ will change
+			the text, but note that it is not possible to add or
+			delete lines using this command.
+			The default for [range] is the whole file: "1,$".
+
+Here are some things you can try: >
+
+  :perl $a=1
+  :perldo $_ = reverse($_);1
+  :perl VIM::Msg("hello")
+  :perl $line = $curbuf->Get(42)
+<
+							*E299*
+Executing Perl commands in the |sandbox| is limited.  ":perldo" will not be
+possible at all.  ":perl" will be evaluated in the Safe environment, if
+possible.
+
+
+							*perl-overview*
+Here is an overview of the functions that are available to Perl: >
+
+  :perl VIM::Msg("Text")		# displays a message
+  :perl VIM::Msg("Error", "ErrorMsg")	# displays an error message
+  :perl VIM::Msg("remark", "Comment")	# displays a highlighted message
+  :perl VIM::SetOption("ai")		# sets a vim option
+  :perl $nbuf = VIM::Buffers()		# returns the number of buffers
+  :perl @buflist = VIM::Buffers()	# returns array of all buffers
+  :perl $mybuf = (VIM::Buffers('qq.c'))[0] # returns buffer object for 'qq.c'
+  :perl @winlist = VIM::Windows()	# returns array of all windows
+  :perl $nwin = VIM::Windows()		# returns the number of windows
+  :perl ($success, $v) = VIM::Eval('&path') # $v: option 'path', $success: 1
+  :perl ($success, $v) = VIM::Eval('&xyz')  # $v: '' and $success: 0
+  :perl $v = VIM::Eval('expand("<cfile>")') # expands <cfile>
+  :perl $curwin->SetHeight(10)		# sets the window height
+  :perl @pos = $curwin->Cursor()	# returns (row, col) array
+  :perl @pos = (10, 10)
+  :perl $curwin->Cursor(@pos)		# sets cursor to @pos
+  :perl $curwin->Cursor(10,10)		# sets cursor to row 10 col 10
+  :perl $mybuf = $curwin->Buffer()	# returns the buffer object for window
+  :perl $curbuf->Name()			# returns buffer name
+  :perl $curbuf->Number()		# returns buffer number
+  :perl $curbuf->Count()		# returns the number of lines
+  :perl $l = $curbuf->Get(10)		# returns line 10
+  :perl @l = $curbuf->Get(1 .. 5)	# returns lines 1 through 5
+  :perl $curbuf->Delete(10)		# deletes line 10
+  :perl $curbuf->Delete(10, 20)		# delete lines 10 through 20
+  :perl $curbuf->Append(10, "Line")	# appends a line
+  :perl $curbuf->Append(10, "Line1", "Line2", "Line3") # appends 3 lines
+  :perl @l = ("L1", "L2", "L3")
+  :perl $curbuf->Append(10, @l)		# appends L1, L2 and L3
+  :perl $curbuf->Set(10, "Line")	# replaces line 10
+  :perl $curbuf->Set(10, "Line1", "Line2")	# replaces lines 10 and 11
+  :perl $curbuf->Set(10, @l)		# replaces 3 lines
+<
+							*perl-Msg*
+VIM::Msg({msg}, {group}?)
+			Displays the message {msg}.  The optional {group}
+			argument specifies a highlight group for Vim to use
+			for the message.
+
+							*perl-SetOption*
+VIM::SetOption({arg})	Sets a vim option.  {arg} can be any argument that the
+			":set" command accepts.  Note that this means that no
+			spaces are allowed in the argument!  See |:set|.
+
+							*perl-Buffers*
+VIM::Buffers([{bn}...])	With no arguments, returns a list of all the buffers
+			in an array context or returns the number of buffers
+			in a scalar context.  For a list of buffer names or
+			numbers {bn}, returns a list of the buffers matching
+			{bn}, using the same rules as Vim's internal
+			|bufname()| function.
+			WARNING: the list becomes invalid when |:bwipe| is
+			used.  Using it anyway may crash Vim.
+
+							*perl-Windows*
+VIM::Windows([{wn}...])	With no arguments, returns a list of all the windows
+			in an array context or returns the number of windows
+			in a scalar context.  For a list of window numbers
+			{wn}, returns a list of the windows with those
+			numbers.
+			WARNING: the list becomes invalid when a window is
+			closed.  Using it anyway may crash Vim.
+
+							*perl-DoCommand*
+VIM::DoCommand({cmd})	Executes Ex command {cmd}.
+
+							*perl-Eval*
+VIM::Eval({expr})	Evaluates {expr} and returns (success, val).
+			success=1 indicates that val contains the value of
+			{expr}; success=0 indicates a failure to evaluate
+			the expression.  '@x' returns the contents of register
+			x, '&x' returns the value of option x, 'x' returns the
+			value of internal |variables| x, and '$x' is equivalent
+			to perl's $ENV{x}.  All |functions| accessible from
+			the command-line are valid for {expr}.
+			A |List| is turned into a string by joining the items
+			and inserting line breaks.
+
+							*perl-SetHeight*
+Window->SetHeight({height})
+			Sets the Window height to {height}, within screen
+			limits.
+
+							*perl-GetCursor*
+Window->Cursor({row}?, {col}?)
+			With no arguments, returns a (row, col) array for the
+			current cursor position in the Window.  With {row} and
+			{col} arguments, sets the Window's cursor position to
+			{row} and {col}.  Note that {col} is numbered from 0,
+			Perl-fashion, and thus is one less than the value in
+			Vim's ruler.
+
+Window->Buffer()					*perl-Buffer*
+			Returns the Buffer object corresponding to the given
+			Window.
+
+							*perl-Name*
+Buffer->Name()		Returns the filename for the Buffer.
+
+							*perl-Number*
+Buffer->Number()	Returns the number of the Buffer.
+
+							*perl-Count*
+Buffer->Count()		Returns the number of lines in the Buffer.
+
+							*perl-Get*
+Buffer->Get({lnum}, {lnum}?, ...)
+			Returns a text string of line {lnum} in the Buffer
+			for each {lnum} specified.  An array can be passed
+			with a list of {lnum}'s specified.
+
+							*perl-Delete*
+Buffer->Delete({lnum}, {lnum}?)
+			Deletes line {lnum} in the Buffer.  With the second
+			{lnum}, deletes the range of lines from the first
+			{lnum} to the second {lnum}.
+
+							*perl-Append*
+Buffer->Append({lnum}, {line}, {line}?, ...)
+			Appends each {line} string after Buffer line {lnum}.
+			The list of {line}s can be an array.
+
+							*perl-Set*
+Buffer->Set({lnum}, {line}, {line}?, ...)
+			Replaces one or more Buffer lines with specified
+			{lines}s, starting at Buffer line {lnum}.  The list of
+			{line}s can be an array.  If the arguments are
+			invalid, replacement does not occur.
+
+$main::curwin
+			The current window object.
+
+$main::curbuf
+			The current buffer object.
+
+
+							*script-here*
+When using a script language in-line, you might want to skip this when the
+language isn't supported.  But this mechanism doesn't work: >
+   if has('perl')
+     perl << EOF
+       this will NOT work!
+   EOF
+   endif
+Instead, put the Perl/Python/Ruby/etc. command in a function and call that
+function: >
+    if has('perl')
+      function DefPerl()
+	perl << EOF
+	  this works
+    EOF
+      endfunction
+      call DefPerl()
+    endif
+Note that "EOF" must be at the start of the line.
+
+==============================================================================
+4. Dynamic loading					*perl-dynamic*
+
+On MS-Windows the Perl library can be loaded dynamically.  The |:version|
+output then includes |+perl/dyn|.
+
+This means that Vim will search for the Perl DLL file only when needed.  When
+you don't use the Perl interface you don't need it, thus you can use Vim
+without this DLL file.
+
+To use the Perl interface the Perl DLL must be in your search path.  In a
+console window type "path" to see what directories are used.
+
+The name of the DLL must match the Perl version Vim was compiled with.
+Currently the name is "perl58.dll".  That is for Perl 5.8.  To know for
+sure edit "gvim.exe" and search for "perl\d*.dll\c".
+
+==============================================================================
+ vim:tw=78:ts=8:ft=help:norl:
--- /dev/null
+++ b/lib/vimfiles/doc/if_pyth.txt
@@ -1,0 +1,331 @@
+*if_pyth.txt*   For Vim version 7.1.  Last change: 2006 Apr 30
+
+
+		  VIM REFERENCE MANUAL    by Paul Moore
+
+
+The Python Interface to Vim				*python* *Python*
+
+1. Commands			|python-commands|
+2. The vim module		|python-vim|
+3. Buffer objects		|python-buffer|
+4. Range objects		|python-range|
+5. Window objects		|python-window|
+6. Dynamic loading		|python-dynamic|
+
+{Vi does not have any of these commands}
+
+The Python interface is available only when Vim was compiled with the
+|+python| feature.
+
+==============================================================================
+1. Commands						*python-commands*
+
+					*:python* *:py* *E205* *E263* *E264*
+:[range]py[thon] {stmt}
+			Execute Python statement {stmt}.
+
+:[range]py[thon] << {endmarker}
+{script}
+{endmarker}
+			Execute Python script {script}.
+			Note: This command doesn't work when the Python
+			feature wasn't compiled in.  To avoid errors, see
+			|script-here|.
+
+{endmarker} must NOT be preceded by any white space.  If {endmarker} is
+omitted from after the "<<", a dot '.' must be used after {script}, like
+for the |:append| and |:insert| commands.
+This form of the |:python| command is mainly useful for including python code
+in Vim scripts.
+
+Example: >
+	function! IcecreamInitialize()
+	python << EOF
+	class StrawberryIcecream:
+		def __call__(self):
+			print 'EAT ME'
+	EOF
+	endfunction
+<
+Note: Python is very sensitive to the indenting.  Also make sure the "class"
+line and "EOF" do not have any indent.
+
+							*:pyfile* *:pyf*
+:[range]pyf[ile] {file}
+			Execute the Python script in {file}.  The whole
+			argument is used as a single file name.  {not in Vi}
+
+Both of these commands do essentially the same thing - they execute a piece of
+Python code, with the "current range" |python-range| set to the given line
+range.
+
+In the case of :python, the code to execute is in the command-line.
+In the case of :pyfile, the code to execute is the contents of the given file.
+
+Python commands cannot be used in the |sandbox|.
+
+To pass arguments you need to set sys.argv[] explicitly.  Example: >
+
+	:python import sys
+	:python sys.argv = ["foo", "bar"]
+	:pyfile myscript.py
+
+Here are some examples					*python-examples*  >
+
+	:python from vim import *
+	:python from string import upper
+	:python current.line = upper(current.line)
+	:python print "Hello"
+	:python str = current.buffer[42]
+
+(Note that changes - like the imports - persist from one command to the next,
+just like in the Python interpreter.)
+
+==============================================================================
+2. The vim module					*python-vim*
+
+Python code gets all of its access to vim (with one exception - see
+|python-output| below) via the "vim" module.  The vim module implements two
+methods, three constants, and one error object.  You need to import the vim
+module before using it: >
+	:python import vim
+
+Overview >
+	:py print "Hello"		# displays a message
+	:py vim.command(cmd)		# execute an ex command
+	:py w = vim.windows[n]		# gets window "n"
+	:py cw = vim.current.window	# gets the current window
+	:py b = vim.buffers[n]		# gets buffer "n"
+	:py cb = vim.current.buffer	# gets the current buffer
+	:py w.height = lines		# sets the window height
+	:py w.cursor = (row, col)	# sets the window cursor position
+	:py pos = w.cursor		# gets a tuple (row, col)
+	:py name = b.name		# gets the buffer file name
+	:py line = b[n]			# gets a line from the buffer
+	:py lines = b[n:m]		# gets a list of lines
+	:py num = len(b)		# gets the number of lines
+	:py b[n] = str			# sets a line in the buffer
+	:py b[n:m] = [str1, str2, str3]	# sets a number of lines at once
+	:py del b[n]			# deletes a line
+	:py del b[n:m]			# deletes a number of lines
+
+
+Methods of the "vim" module
+
+vim.command(str)					*python-command*
+	Executes the vim (ex-mode) command str.  Returns None.
+	Examples: >
+	    :py vim.command("set tw=72")
+	    :py vim.command("%s/aaa/bbb/g")
+<	The following definition executes Normal mode commands: >
+		def normal(str):
+			vim.command("normal "+str)
+		# Note the use of single quotes to delimit a string containing
+		# double quotes
+		normal('"a2dd"aP')
+<								*E659*
+	The ":python" command cannot be used recursively with Python 2.2 and
+	older.  This only works with Python 2.3 and later: >
+	    :py vim.command("python print 'Hello again Python'")
+
+vim.eval(str)						*python-eval*
+	Evaluates the expression str using the vim internal expression
+	evaluator (see |expression|).  Returns the expression result as:
+	- a string if the Vim expression evaluates to a string or number
+	- a list if the Vim expression evaluates to a Vim list
+	- a dictionary if the Vim expression evaluates to a Vim dictionary
+	Dictionaries and lists are recursively expanded.
+	Examples: >
+	    :py text_width = vim.eval("&tw")
+	    :py str = vim.eval("12+12")		# NB result is a string! Use
+						# string.atoi() to convert to
+						# a number.
+
+	    :py tagList = vim.eval('taglist("eval_expr")')
+<	The latter will return a python list of python dicts, for instance:
+	[{'cmd': '/^eval_expr(arg, nextcmd)$/', 'static': 0, 'name':
+	'eval_expr', 'kind': 'f', 'filename': './src/eval.c'}]
+
+
+
+Error object of the "vim" module
+
+vim.error						*python-error*
+	Upon encountering a Vim error, Python raises an exception of type
+	vim.error.
+	Example: >
+		try:
+			vim.command("put a")
+		except vim.error:
+			# nothing in register a
+
+Constants of the "vim" module
+
+	Note that these are not actually constants - you could reassign them.
+	But this is silly, as you would then lose access to the vim objects
+	to which the variables referred.
+
+vim.buffers						*python-buffers*
+	A sequence object providing access to the list of vim buffers.  The
+	object supports the following operations: >
+	    :py b = vim.buffers[i]	# Indexing (read-only)
+	    :py b in vim.buffers	# Membership test
+	    :py n = len(vim.buffers)	# Number of elements
+	    :py for b in vim.buffers:	# Sequential access
+<
+vim.windows						*python-windows*
+	A sequence object providing access to the list of vim windows.  The
+	object supports the following operations: >
+	    :py w = vim.windows[i]	# Indexing (read-only)
+	    :py w in vim.windows	# Membership test
+	    :py n = len(vim.windows)	# Number of elements
+	    :py for w in vim.windows:	# Sequential access
+<
+vim.current						*python-current*
+	An object providing access (via specific attributes) to various
+	"current" objects available in vim:
+		vim.current.line	The current line (RW)		String
+		vim.current.buffer	The current buffer (RO)		Buffer
+		vim.current.window	The current window (RO)		Window
+		vim.current.range	The current line range (RO)	Range
+
+	The last case deserves a little explanation.  When the :python or
+	:pyfile command specifies a range, this range of lines becomes the
+	"current range".  A range is a bit like a buffer, but with all access
+	restricted to a subset of lines.  See |python-range| for more details.
+
+
+Output from Python					*python-output*
+	Vim displays all Python code output in the Vim message area.  Normal
+	output appears as information messages, and error output appears as
+	error messages.
+
+	In implementation terms, this means that all output to sys.stdout
+	(including the output from print statements) appears as information
+	messages, and all output to sys.stderr (including error tracebacks)
+	appears as error messages.
+
+							*python-input*
+	Input (via sys.stdin, including input() and raw_input()) is not
+	supported, and may cause the program to crash.  This should probably be
+	fixed.
+
+==============================================================================
+3. Buffer objects					*python-buffer*
+
+Buffer objects represent vim buffers.  You can obtain them in a number of ways:
+	- via vim.current.buffer (|python-current|)
+	- from indexing vim.buffers (|python-buffers|)
+	- from the "buffer" attribute of a window (|python-window|)
+
+Buffer objects have one read-only attribute - name - the full file name for
+the buffer.  They also have three methods (append, mark, and range; see below).
+
+You can also treat buffer objects as sequence objects.  In this context, they
+act as if they were lists (yes, they are mutable) of strings, with each
+element being a line of the buffer.  All of the usual sequence operations,
+including indexing, index assignment, slicing and slice assignment, work as
+you would expect.  Note that the result of indexing (slicing) a buffer is a
+string (list of strings).  This has one unusual consequence - b[:] is different
+from b.  In particular, "b[:] = None" deletes the whole of the buffer, whereas
+"b = None" merely updates the variable b, with no effect on the buffer.
+
+Buffer indexes start at zero, as is normal in Python.  This differs from vim
+line numbers, which start from 1.  This is particularly relevant when dealing
+with marks (see below) which use vim line numbers.
+
+The buffer object methods are:
+	b.append(str)	Append a line to the buffer
+	b.append(list)	Append a list of lines to the buffer
+			Note that the option of supplying a list of strings to
+			the append method differs from the equivalent method
+			for Python's built-in list objects.
+	b.mark(name)	Return a tuple (row,col) representing the position
+			of the named mark (can also get the []"<> marks)
+	b.range(s,e)	Return a range object (see |python-range|) which
+			represents the part of the given buffer between line
+			numbers s and e |inclusive|.
+
+Note that when adding a line it must not contain a line break character '\n'.
+A trailing '\n' is allowed and ignored, so that you can do: >
+	:py b.append(f.readlines())
+
+Examples (assume b is the current buffer) >
+	:py print b.name		# write the buffer file name
+	:py b[0] = "hello!!!"		# replace the top line
+	:py b[:] = None			# delete the whole buffer
+	:py del b[:]			# delete the whole buffer
+	:py b[0:0] = [ "a line" ]	# add a line at the top
+	:py del b[2]			# delete a line (the third)
+	:py b.append("bottom")		# add a line at the bottom
+	:py n = len(b)			# number of lines
+	:py (row,col) = b.mark('a')	# named mark
+	:py r = b.range(1,5)		# a sub-range of the buffer
+
+==============================================================================
+4. Range objects					*python-range*
+
+Range objects represent a part of a vim buffer.  You can obtain them in a
+number of ways:
+	- via vim.current.range (|python-current|)
+	- from a buffer's range() method (|python-buffer|)
+
+A range object is almost identical in operation to a buffer object.  However,
+all operations are restricted to the lines within the range (this line range
+can, of course, change as a result of slice assignments, line deletions, or
+the range.append() method).
+
+The range object attributes are:
+	r.start		Index of first line into the buffer
+	r.end		Index of last line into the buffer
+
+The range object methods are:
+	r.append(str)	Append a line to the range
+	r.append(list)	Append a list of lines to the range
+			Note that the option of supplying a list of strings to
+			the append method differs from the equivalent method
+			for Python's built-in list objects.
+
+Example (assume r is the current range):
+	# Send all lines in a range to the default printer
+	vim.command("%d,%dhardcopy!" % (r.start+1,r.end+1))
+
+==============================================================================
+5. Window objects					*python-window*
+
+Window objects represent vim windows.  You can obtain them in a number of ways:
+	- via vim.current.window (|python-current|)
+	- from indexing vim.windows (|python-windows|)
+
+You can manipulate window objects only through their attributes.  They have no
+methods, and no sequence or other interface.
+
+Window attributes are:
+	buffer (read-only)	The buffer displayed in this window
+	cursor (read-write)	The current cursor position in the window
+				This is a tuple, (row,col).
+	height (read-write)	The window height, in rows
+	width (read-write)	The window width, in columns
+The height attribute is writable only if the screen is split horizontally.
+The width attribute is writable only if the screen is split vertically.
+
+==============================================================================
+6. Dynamic loading					*python-dynamic*
+
+On MS-Windows the Python library can be loaded dynamically.  The |:version|
+output then includes |+python/dyn|.
+
+This means that Vim will search for the Python DLL file only when needed.
+When you don't use the Python interface you don't need it, thus you can use
+Vim without this DLL file.
+
+To use the Python interface the Python DLL must be in your search path.  In a
+console window type "path" to see what directories are used.
+
+The name of the DLL must match the Python version Vim was compiled with.
+Currently the name is "python24.dll".  That is for Python 2.4.  To know for
+sure edit "gvim.exe" and search for "python\d*.dll\c".
+
+==============================================================================
+ vim:tw=78:ts=8:ft=help:norl:
--- /dev/null
+++ b/lib/vimfiles/doc/if_ruby.txt
@@ -1,0 +1,205 @@
+*if_ruby.txt*   For Vim version 7.1.  Last change: 2006 Apr 30
+
+
+		  VIM REFERENCE MANUAL    by Shugo Maeda
+
+The Ruby Interface to Vim				*ruby* *Ruby*
+
+
+1. Commands			|ruby-commands|
+2. The VIM module		|ruby-vim|
+3. VIM::Buffer objects		|ruby-buffer|
+4. VIM::Window objects		|ruby-window|
+5. Global variables		|ruby-globals|
+6. Dynamic loading		|ruby-dynamic|
+
+{Vi does not have any of these commands}
+			*E266* *E267* *E268* *E269* *E270* *E271* *E272* *E273*
+
+The Ruby interface only works when Vim was compiled with the |+ruby| feature.
+
+The home page for ruby is http://www.ruby-lang.org/.  You can find links for
+downloading Ruby there.
+
+==============================================================================
+1. Commands						*ruby-commands*
+
+							*:ruby* *:rub*
+:rub[y] {cmd}		Execute Ruby command {cmd}.
+
+:rub[y] << {endpattern}
+{script}
+{endpattern}
+			Execute Ruby script {script}.
+			{endpattern} must NOT be preceded by any white space.
+			If {endpattern} is omitted, it defaults to a dot '.'
+			like for the |:append| and |:insert| commands.  This
+			form of the |:ruby| command is mainly useful for
+			including ruby code in vim scripts.
+			Note: This command doesn't work when the Ruby feature
+			wasn't compiled in.  To avoid errors, see
+			|script-here|.
+
+Example Vim script: >
+
+	function! RedGem()
+	ruby << EOF
+	class Garnet
+		def initialize(s)
+			@buffer = VIM::Buffer.current
+			vimputs(s)
+		end
+		def vimputs(s)
+			@buffer.append(@buffer.count,s)
+		end
+	end
+	gem = Garnet.new("pretty")
+	EOF
+	endfunction
+<
+
+						*:rubydo* *:rubyd* *E265*
+:[range]rubyd[o] {cmd}	Evaluate Ruby command {cmd} for each line in the
+			[range], with $_ being set to the text of each line in
+			turn, without a trailing <EOL>.  Setting $_ will change
+			the text, but note that it is not possible to add or
+			delete lines using this command.
+			The default for [range] is the whole file: "1,$".
+
+							*:rubyfile* *:rubyf*
+:rubyf[ile] {file}	Execute the Ruby script in {file}.  This is the same as
+			":ruby load 'file'", but allows file name completion.
+
+Executing Ruby commands is not possible in the |sandbox|.
+
+==============================================================================
+2. The VIM module					*ruby-vim*
+
+Ruby code gets all of its access to vim via the "VIM" module.
+
+Overview >
+	print "Hello"			      # displays a message
+	VIM.command(cmd)		      # execute an ex command
+	num = VIM::Window.count		      # gets the number of windows
+	w = VIM::Window[n]		      # gets window "n"
+	cw = VIM::Window.current	      # gets the current window
+	num = VIM::Buffer.count		      # gets the number of buffers
+	b = VIM::Buffer[n]		      # gets buffer "n"
+	cb = VIM::Buffer.current	      # gets the current buffer
+	w.height = lines		      # sets the window height
+	w.cursor = [row, col]		      # sets the window cursor position
+	pos = w.cursor			      # gets an array [row, col]
+	name = b.name			      # gets the buffer file name
+	line = b[n]			      # gets a line from the buffer
+	num = b.count			      # gets the number of lines
+	b[n] = str			      # sets a line in the buffer
+	b.delete(n)			      # deletes a line
+	b.append(n, str)		      # appends a line after n
+	line = VIM::Buffer.current.line       # gets the current line
+	num = VIM::Buffer.current.line_number # gets the current line number
+	VIM::Buffer.current.line = "test"     # sets the current line number
+<
+
+Module Functions:
+
+							*ruby-message*
+VIM::message({msg})
+	Displays the message {msg}.
+
+							*ruby-set_option*
+VIM::set_option({arg})
+	Sets a vim option.  {arg} can be any argument that the ":set" command
+	accepts.  Note that this means that no spaces are allowed in the
+	argument!  See |:set|.
+
+							*ruby-command*
+VIM::command({cmd})
+	Executes Ex command {cmd}.
+
+							*ruby-evaluate*
+VIM::evaluate({expr})
+	Evaluates {expr} using the vim internal expression evaluator (see
+	|expression|).  Returns the expression result as a string.
+	A |List| is turned into a string by joining the items and inserting
+	line breaks.
+
+==============================================================================
+3. VIM::Buffer objects					*ruby-buffer*
+
+VIM::Buffer objects represent vim buffers.
+
+Class Methods:
+
+current		Returns the current buffer object.
+count		Returns the number of buffers.
+self[{n}]	Returns the buffer object for the number {n}.  The first number
+		is 0.
+
+Methods:
+
+name		Returns the name of the buffer.
+number		Returns the number of the buffer.
+count		Returns the number of lines.
+length		Returns the number of lines.
+self[{n}]	Returns a line from the buffer. {n} is the line number.
+self[{n}] = {str}
+		Sets a line in the buffer. {n} is the line number.
+delete({n})	Deletes a line from the buffer. {n} is the line number.
+append({n}, {str})
+		Appends a line after the line {n}.
+line		Returns the current line of the buffer if the buffer is
+		active.
+line = {str}    Sets the current line of the buffer if the buffer is active.
+line_number     Returns the number of the current line if the buffer is
+		active.
+
+==============================================================================
+4. VIM::Window objects					*ruby-window*
+
+VIM::Window objects represent vim windows.
+
+Class Methods:
+
+current		Returns the current window object.
+count		Returns the number of windows.
+self[{n}]	Returns the window object for the number {n}.  The first number
+		is 0.
+
+Methods:
+
+buffer		Returns the buffer displayed in the window.
+height		Returns the height of the window.
+height = {n}	Sets the window height to {n}.
+width		Returns the width of the window.
+width = {n}	Sets the window width to {n}.
+cursor		Returns a [row, col] array for the cursor position.
+cursor = [{row}, {col}]
+		Sets the cursor position to {row} and {col}.
+
+==============================================================================
+5. Global variables					*ruby-globals*
+
+There are two global variables.
+
+$curwin		The current window object.
+$curbuf		The current buffer object.
+
+==============================================================================
+6. Dynamic loading					*ruby-dynamic*
+
+On MS-Windows the Ruby library can be loaded dynamically.  The |:version|
+output then includes |+ruby/dyn|.
+
+This means that Vim will search for the Ruby DLL file only when needed.  When
+you don't use the Ruby interface you don't need it, thus you can use Vim
+without this DLL file.
+
+To use the Ruby interface the Ruby DLL must be in your search path.  In a
+console window type "path" to see what directories are used.
+
+The name of the DLL must match the Ruby version Vim was compiled with.
+Currently the name is "ruby18.dll".  That is for Ruby 1.8.  To know for sure
+edit "gvim.exe" and search for "ruby\d*.dll\c".
+
+==============================================================================
+ vim:tw=78:ts=8:ft=help:norl:
--- /dev/null
+++ b/lib/vimfiles/doc/if_sniff.txt
@@ -1,0 +1,95 @@
+*if_sniff.txt*	For Vim version 7.1.  Last change: 2005 Mar 29
+
+
+		  VIM REFERENCE MANUAL
+		by Anton Leherbauer (toni@takefive.co.at)
+
+
+SNiFF+ and Vim				    *sniff*
+
+1. Introduction				    |sniff-intro|
+2. Commands				    |sniff-commands|
+3. Compiling Vim with SNiFF+ interface	    |sniff-compiling|
+
+{Vi does not have any of these commands}  *E275* *E274* *E276* *E278* *E279*
+
+The SNiFF+ interface only works, when Vim was compiled with the |+sniff|
+feature.
+
+==============================================================================
+1. Introduction					*sniff-intro*
+
+The following features for the use with SNiFF+ are available:
+
+   * Vim can be used for all editing requests
+   * SNiFF+ recognizes and updates all browsers when a file is saved in Vim
+   * SNiFF+ commands can be issued directly from Vim
+
+How to use Vim with SNiFF+
+   1. Make sure SNiFF+ is running.
+   2. In the Editor view of the Preferences dialog set the Field named
+      'External Editor' to 'Emacs/Vim'.
+   4. Start Vim
+   5. Connect to SNiFF+ (:sniff connect)
+
+Once a connection is established, SNiFF+ uses Vim for all requests to show or
+edit source code.  On the other hand, you can send queries to SNiFF+ with the
+:sniff command.
+
+==============================================================================
+2. Commands				    *sniff-commands*
+
+			    *:sniff* *:sni*
+:sni[ff] request [symbol]   Send request to sniff with optional symbol.
+			    {not in Vi}
+:sni[ff]		    Display all possible requests and the connection
+			    status
+
+Most requests require a symbol (identifier) as parameter.  If it is omitted,
+Vim will use the current word under the cursor.
+The available requests are listed below:
+
+request		      mapping	description
+-------------------------------------------------------------------------------
+connect			sc	Establish connection with SNiFF+.
+				Make sure SNiFF+ is prepared for this in the
+				Preferences
+disconnect		sq	Disconnect from SNiFF+.  You can reconnect any
+				time with :sniff connect (or 'sc')
+toggle			st	Toggle between implementation
+				and definition file
+find-symbol		sf	Load the symbol into a Symbol Browser
+browse-class		sb	Loads the class into a Class Browser
+superclass		ss	Edit superclass of symbol
+overridden		so	Edit overridden method of symbol
+retrieve-file		srf	Retrieve symbol in current file
+retrieve-project	srp	Retrieve symbol in current project
+retrieve-all-projects	srP	Retrieve symbol in all projects
+retrieve-next		sR	Retrieve symbol using current Retriever
+				settings
+goto-symbol		sg	Goto definition or implementation of symbol
+hierarchy		sh	Load symbol into the Hierarchy Browser
+restr-hier		sH	same as above but show only related classes
+xref-to			sxt	Start a refers-to query on symbol and
+				load the results into the Cross Referencer
+xref-by			sxb	Start a referred-by query on symbol
+xref-has		sxh	Start a refers-to components query on symbol
+xref-used-by		sxu	Start a referred-by as component query on
+				symbol
+show-docu		sd	Show documentation of symbol
+gen-docu		sD	Generate documentation of symbol
+
+The mappings are defined in a file 'sniff.vim', which is part of every SNiFF+
+product ($SNIFF_DIR/config/sniff.vim).  This file is sourced whenever Vim
+connects to SNiFF+.
+
+==============================================================================
+3. Compiling Vim with SNiFF+ interface		*sniff-compiling*
+
+To compile Vim with SNiFF+ support, you need two source files of the extra
+archive: if_sniff.c and if_sniff.h.
+On Unix: Edit the Makefile and uncomment the line "--enable-sniff".  Or run
+configure manually with this argument.
+On NT: Specify SNIFF=yes with your make command.
+
+ vim:tw=78:ts=8:ft=help:norl:
--- /dev/null
+++ b/lib/vimfiles/doc/if_tcl.txt
@@ -1,0 +1,531 @@
+*if_tcl.txt*    For Vim version 7.1.  Last change: 2006 Mar 06
+
+
+		  VIM REFERENCE MANUAL    by Ingo Wilken
+
+
+The Tcl Interface to Vim				*tcl* *Tcl* *TCL*
+
+1. Commands				|tcl-ex-commands|
+2. Tcl commands				|tcl-commands|
+3. Tcl variables			|tcl-variables|
+4. Tcl window commands			|tcl-window-cmds|
+5. Tcl buffer commands			|tcl-buffer-cmds|
+6. Miscellaneous; Output from Tcl	|tcl-misc| |tcl-output|
+7. Known bugs & problems		|tcl-bugs|
+8. Examples				|tcl-examples|
+9. Dynamic loading			|tcl-dynamic|
+
+{Vi does not have any of these commands} *E280* *E281*
+
+The Tcl interface only works when Vim was compiled with the |+tcl| feature.
+
+WARNING: There are probably still some bugs.  Please send bug reports,
+comments, ideas etc to <Ingo.Wilken@informatik.uni-oldenburg.de>
+
+==============================================================================
+1. Commands				*tcl-ex-commands* *E571* *E572*
+
+							*:tcl* *:tc*
+:tc[l] {cmd}		Execute Tcl command {cmd}.
+
+:[range]tc[l] << {endmarker}
+{script}
+{endmarker}
+			Execute Tcl script {script}.
+			Note: This command doesn't work when the Tcl feature
+			wasn't compiled in.  To avoid errors, see
+			|script-here|.
+
+{endmarker} must NOT be preceded by any white space.  If {endmarker} is
+omitted from after the "<<", a dot '.' must be used after {script}, like for
+the |:append| and |:insert| commands.
+This form of the |:tcl| command is mainly useful for including tcl code in Vim
+scripts.
+
+Example: >
+	function! DefineDate()
+	    tcl << EOF
+	    proc date {} {
+		return [clock format [clock seconds]]
+	    }
+	EOF
+	endfunction
+<
+
+							*:tcldo* *:tcld*
+:[range]tcld[o] {cmd}	Execute Tcl command {cmd} for each line in [range]
+			with the variable "line" being set to the text of each
+			line in turn, and "lnum" to the line number.  Setting
+			"line" will change the text, but note that it is not
+			possible to add or delete lines using this command.
+			If {cmd} returns an error, the command is interrupted.
+			The default for [range] is the whole file: "1,$".
+			See |tcl-var-line| and |tcl-var-lnum|.  {not in Vi}
+
+							*:tclfile* *:tclf*
+:tclf[ile] {file}	Execute the Tcl script in {file}.  This is the same as
+			":tcl source {file}", but allows file name completion.
+			{not in Vi}
+
+
+Note that Tcl objects (like variables) persist from one command to the next,
+just as in the Tcl shell.
+
+Executing Tcl commands is not possible in the |sandbox|.
+
+==============================================================================
+2. Tcl commands						*tcl-commands*
+
+Tcl code gets all of its access to vim via commands in the "::vim" namespace.
+The following commands are implemented: >
+
+	::vim::beep			# Guess.
+	::vim::buffer {n}		# Create Tcl command for one buffer.
+	::vim::buffer list		# Create Tcl commands for all buffers.
+	::vim::command [-quiet] {cmd}	# Execute an ex command.
+	::vim::expr {expr}		# Use Vim's expression evaluator.
+	::vim::option {opt}		# Get vim option.
+	::vim::option {opt} {val}	# Set vim option.
+	::vim::window list		# Create Tcl commands for all windows.
+
+Commands:
+	::vim::beep					*tcl-beep*
+	Honk.  Does not return a result.
+
+	::vim::buffer {n}				*tcl-buffer*
+	::vim::buffer exists {n}
+	::vim::buffer list
+	Provides access to vim buffers.  With an integer argument, creates a
+	buffer command (see |tcl-buffer-cmds|) for the buffer with that
+	number, and returns its name as the result.  Invalid buffer numbers
+	result in a standard Tcl error.  To test for valid buffer numbers,
+	vim's internal functions can be used: >
+		set nbufs [::vim::expr bufnr("$")]
+		set isvalid [::vim::expr "bufexists($n)"]
+<	The "list" option creates a buffer command for each valid buffer, and
+	returns a list of the command names as the result.
+	Example: >
+		set bufs [::vim::buffer list]
+		foreach b $bufs { $b append end "The End!" }
+<	The "exists" option checks if a buffer with the given number exists.
+	Example: >
+		if { [::vim::buffer exists $n] } { ::vim::command ":e #$n" }
+<	This command might be replaced by a variable in future versions.
+	See also |tcl-var-current| for the current buffer.
+
+	::vim::command {cmd}				*tcl-command*
+	::vim::command -quiet {cmd}
+	Execute the vim (ex-mode) command {cmd}.  Any ex command that affects
+	a buffer or window uses the current buffer/current window.  Does not
+	return a result other than a standard Tcl error code.  After this
+	command is completed, the "::vim::current" variable is updated.
+	The "-quiet" flag suppresses any error messages from vim.
+	Examples: >
+		::vim::command "set ts=8"
+		::vim::command "%s/foo/bar/g"
+<	To execute normal-mode commands, use "normal" (see |:normal|): >
+		set cmd "jj"
+		::vim::command "normal $cmd"
+<	See also |tcl-window-command| and |tcl-buffer-command|.
+
+	::vim::expr {expr}				*tcl-expr*
+	Evaluates the expression {expr} using vim's internal expression
+	evaluator (see |expression|).   Any expression that queries a buffer
+	or window property uses the current buffer/current window.  Returns
+	the result as a string.  A |List| is turned into a string by joining
+	the items and inserting line breaks.
+	Examples: >
+		set perl_available [::vim::expr has("perl")]
+<	See also |tcl-window-expr| and |tcl-buffer-expr|.
+
+	::vim::option {opt}				*tcl-option*
+	::vim::option {opt} {value}
+	Without second argument, queries the value of a vim option.  With this
+	argument, sets the vim option to {value}, and returns the previous
+	value as the result.  Any options that are marked as 'local to buffer'
+	or 'local to window' affect the current buffer/current window.  The
+	global value is not changed, use the ":set" command for that.  For
+	boolean options, {value} should be "0" or "1", or any of the keywords
+	"on", "off" or "toggle".  See |option-summary| for a list of options.
+	Example: >
+		::vim::option ts 8
+<	See also |tcl-window-option| and |tcl-buffer-option|.
+
+	::vim::window {option}				*tcl-window*
+	Provides access to vim windows.  Currently only the "list" option is
+	implemented.  This creates a window command (see |tcl-window-cmds|) for
+	each window, and returns a list of the command names as the result.
+	Example: >
+		set wins [::vim::window list]
+		foreach w $wins { $w height 4 }
+<	This command might be replaced by a variable in future versions.
+	See also |tcl-var-current| for the current window.
+
+==============================================================================
+3. Tcl variables					*tcl-variables*
+
+The ::vim namespace contains a few variables.  These are created when the Tcl
+interpreter is called from vim and set to current values. >
+
+	::vim::current		# array containing "current" objects
+	::vim::lbase		# number of first line
+	::vim::range		# array containing current range numbers
+	line			# current line as a string (:tcldo only)
+	lnum			# current line number (:tcldo only)
+
+Variables:
+	::vim::current					*tcl-var-current*
+	This is an array providing access to various "current" objects
+	available in vim.  The contents of this array are updated after
+	"::vim::command" is called, as this might change vim's current
+	settings (e.g., by deleting the current buffer).
+	The "buffer" element contains the name of the buffer command for the
+	current buffer.  This can be used directly to invoke buffer commands
+	(see |tcl-buffer-cmds|).  This element is read-only.
+	Example: >
+		$::vim::current(buffer) insert begin "Hello world"
+<	The "window" element contains the name of the window command for the
+	current window.  This can be used directly to invoke window commands
+	(see |tcl-window-cmds|).  This element is read-only.
+	Example: >
+		$::vim::current(window) height 10
+<
+	::vim::lbase					*tcl-var-lbase*
+	This variable controls how Tcl treats line numbers.  If it is set to
+	'1', then lines and columns start at 1.  This way, line numbers from
+	Tcl commands and vim expressions are compatible.  If this variable is
+	set to '0', then line numbers and columns start at 0 in Tcl.  This is
+	useful if you want to treat a buffer as a Tcl list or a line as a Tcl
+	string and use standard Tcl commands that return an index ("lsort" or
+	"string first", for example).  The default value is '1'.  Currently,
+	any non-zero values is treated as '1', but your scripts should not
+	rely on this.  See also |tcl-linenumbers|.
+
+	::vim::range					*tcl-var-range*
+	This is an array with three elements, "start", "begin" and "end".  It
+	contains the line numbers of the start and end row of the current
+	range.  "begin" is the same as "start".  This variable is read-only.
+	See |tcl-examples|.
+
+	line						*tcl-var-line*
+	lnum						*tcl-var-lnum*
+	These global variables are only available if the ":tcldo" ex command
+	is being executed.  They contain the text and line number of the
+	current line.  When the Tcl command invoked by ":tcldo" is completed,
+	the current line is set to the contents of the "line" variable, unless
+	the variable was unset by the Tcl command.  The "lnum" variable is
+	read-only.  These variables are not in the "::vim" namespace so they
+	can be used in ":tcldo" without much typing (this might be changed in
+	future versions).  See also |tcl-linenumbers|.
+
+==============================================================================
+4. Tcl window commands					*tcl-window-cmds*
+
+Window commands represent vim windows.  They are created by several commands:
+	::vim::window list			|tcl-window|
+	"windows" option of a buffer command	|tcl-buffer-windows|
+The ::vim::current(window) variable contains the name of the window command
+for the current window.  A window command is automatically deleted when the
+corresponding vim window is closed.
+
+Let's assume the name of the window command is stored in the Tcl variable "win",
+i.e. "$win" calls the command.  The following options are available: >
+
+	$win buffer		# Create Tcl command for window's buffer.
+	$win command {cmd}	# Execute ex command in windows context.
+	$win cursor		# Get current cursor position.
+	$win cursor {var}	# Set cursor position from array variable.
+	$win cursor {row} {col}	# Set cursor position.
+	$win delcmd {cmd}	# Call Tcl command when window is closed.
+	$win expr {expr}	# Evaluate vim expression in windows context.
+	$win height		# Report the window's height.
+	$win height {n}		# Set the window's height.
+	$win option {opt} [val]	# Get/Set vim option in windows context.
+
+Options:
+	$win buffer					*tcl-window-buffer*
+	Creates a Tcl command for the window's buffer, and returns its name as
+	the result.  The name should be stored in a variable: >
+		set buf [$win buffer]
+<	$buf is now a valid Tcl command.  See |tcl-buffer-cmds| for the
+	available options.
+
+	$win cursor					*tcl-window-cursor*
+	$win cursor {var}
+	$win cursor {row} {col}
+	Without argument, reports the current cursor position as a string.
+	This can be converted to a Tcl array variable: >
+		array set here [$win cursor]
+<	"here(row)" and "here(column)" now contain the cursor position.
+	With a single argument, the argument is interpreted as the name of a
+	Tcl array variable, which must contain two elements "row" and "column".
+	These are used to set the cursor to the new position: >
+		$win cursor here	;# not $here !
+<	With two arguments, sets the cursor to the specified row and column: >
+		$win cursor $here(row) $here(column)
+<	Invalid positions result in a standard Tcl error, which can be caught
+	with "catch".  The row and column values depend on the "::vim::lbase"
+	variable.  See |tcl-var-lbase|.
+
+	$win delcmd {cmd}				*tcl-window-delcmd*
+	Registers the Tcl command {cmd} as a deletion callback for the window.
+	This command is executed (in the global scope) just before the window
+	is closed.  Complex commands should be build with "list": >
+		$win delcmd [list puts vimerr "window deleted"]
+<	See also |tcl-buffer-delcmd|.
+
+	$win height					*tcl-window-height*
+	$win height {n}
+	Without argument, reports the window's current height.  With an
+	argument, tries to set the window's height to {n}, then reports the
+	new height (which might be different from {n}).
+
+	$win command [-quiet] {cmd}			*tcl-window-command*
+	$win expr {expr}				*tcl-window-expr*
+	$win option {opt} [val]				*tcl-window-option*
+	These are similar to "::vim::command" etc., except that everything is
+	done in the context of the window represented by $win, instead of the
+	current window.  For example, setting an option that is marked 'local
+	to window' affects the window $win.  Anything that affects or queries
+	a buffer uses the buffer displayed in this window (i.e. the buffer
+	that is represented by "$win buffer").  See |tcl-command|, |tcl-expr|
+	and |tcl-option| for more information.
+	Example: >
+		$win option number on
+
+==============================================================================
+5. Tcl buffer commands					*tcl-buffer-cmds*
+
+Buffer commands represent vim buffers.  They are created by several commands:
+	::vim::buffer {N}			|tcl-buffer|
+	::vim::buffer list			|tcl-buffer|
+	"buffer" option of a window command	|tcl-window-buffer|
+The ::vim::current(buffer) variable contains the name of the buffer command
+for the current buffer.  A buffer command is automatically deleted when the
+corresponding vim buffer is destroyed.  Whenever the buffer's contents are
+changed, all marks in the buffer are automatically adjusted.  Any changes to
+the buffer's contents made by Tcl commands can be undone with the "undo" vim
+command (see |undo|).
+
+Let's assume the name of the buffer command is stored in the Tcl variable "buf",
+i.e. "$buf" calls the command.  The following options are available: >
+
+	$buf append {n} {str}	# Append a line to buffer, after line {n}.
+	$buf command {cmd}	# Execute ex command in buffers context.
+	$buf count		# Report number of lines in buffer.
+	$buf delcmd {cmd}	# Call Tcl command when buffer is deleted.
+	$buf delete {n}		# Delete a single line.
+	$buf delete {n} {m}	# Delete several lines.
+	$buf expr {expr}	# Evaluate vim expression in buffers context.
+	$buf get {n}		# Get a single line as a string.
+	$buf get {n} {m}	# Get several lines as a list.
+	$buf insert {n} {str}	# Insert a line in buffer, as line {n}.
+	$buf last		# Report line number of last line in buffer.
+	$buf mark {mark}	# Report position of buffer mark.
+	$buf name		# Report name of file in buffer.
+	$buf number		# Report number of this buffer.
+	$buf option {opt} [val]	# Get/Set vim option in buffers context.
+	$buf set {n} {text}	# Replace a single line.
+	$buf set {n} {m} {list}	# Replace several lines.
+	$buf windows		# Create Tcl commands for buffer's windows.
+<
+							*tcl-linenumbers*
+Most buffer commands take line numbers as arguments.  How Tcl treats these
+numbers depends on the "::vim::lbase" variable (see |tcl-var-lbase|).  Instead
+of line numbers, several keywords can be also used: "top", "start", "begin",
+"first", "bottom", "end" and "last".
+
+Options:
+	$buf append {n} {str}				*tcl-buffer-append*
+	$buf insert {n} {str}				*tcl-buffer-insert*
+	Add a line to the buffer.  With the "insert" option, the string
+	becomes the new line {n}, with "append" it is inserted after line {n}.
+	Example: >
+		$buf insert top "This is the beginning."
+		$buf append end "This is the end."
+<	To add a list of lines to the buffer, use a loop: >
+		foreach line $list { $buf append $num $line ; incr num }
+<
+	$buf count					*tcl-buffer-count*
+	Reports the total number of lines in the buffer.
+
+	$buf delcmd {cmd}				*tcl-buffer-delcmd*
+	Registers the Tcl command {cmd} as a deletion callback for the buffer.
+	This command is executed (in the global scope) just before the buffer
+	is deleted.  Complex commands should be build with "list": >
+		$buf delcmd [list puts vimerr "buffer [$buf number] gone"]
+<	See also |tcl-window-delcmd|.
+
+	$buf delete {n}					*tcl-buffer-delete*
+	$buf delete {n} {m}
+	Deletes line {n} or lines {n} through {m} from the buffer.
+	This example deletes everything except the last line: >
+		$buf delete first [expr [$buf last] - 1]
+<
+	$buf get {n}					*tcl-buffer-get*
+	$buf get {n} {m}
+	Gets one or more lines from the buffer.  For a single line, the result
+	is a string; for several lines, a list of strings.
+	Example: >
+		set topline [$buf get top]
+<
+	$buf last					*tcl-buffer-last*
+	Reports the line number of the last line.  This value depends on the
+	"::vim::lbase" variable.  See |tcl-var-lbase|.
+
+	$buf mark {mark}				*tcl-buffer-mark*
+	Reports the position of the named mark as a string, similar to the
+	cursor position of the "cursor" option of a window command (see
+	|tcl-window-cursor|).  This can be converted to a Tcl array variable: >
+		array set mpos [$buf mark "a"]
+<	"mpos(column)" and "mpos(row)" now contain the position of the mark.
+	If the mark is not set, a standard Tcl error results.
+
+	$buf name
+	Reports the name of the file in the buffer.  For a buffer without a
+	file, this is an empty string.
+
+	$buf number
+	Reports the number of this buffer.  See |:buffers|.
+	This example deletes a buffer from vim: >
+		::vim::command "bdelete [$buf number]"
+<
+	$buf set {n} {string}				*tcl-buffer-set*
+	$buf set {n} {m} {list}
+	Replace one or several lines in the buffer.  If the list contains more
+	elements than there are lines to replace, they are inserted into the
+	buffer.  If the list contains fewer elements, any unreplaced line is
+	deleted from the buffer.
+
+	$buf windows					*tcl-buffer-windows*
+	Creates a window command for each window that displays this buffer, and
+	returns a list of the command names as the result.
+	Example: >
+		set winlist [$buf windows]
+		foreach win $winlist { $win height 4 }
+<	See |tcl-window-cmds| for the available options.
+
+	$buf command [-quiet] {cmd}			*tcl-buffer-command*
+	$buf expr {exr}					*tcl-buffer-expr*
+	$buf option {opt} [val]				*tcl-buffer-option*
+	These are similar to "::vim::command" etc., except that everything is
+	done in the context of the buffer represented by $buf, instead of the
+	current buffer.  For example, setting an option that is marked 'local
+	to buffer' affects the buffer $buf.  Anything that affects or queries
+	a window uses the first window in vim's window list that displays this
+	buffer (i.e. the first entry in the list returned by "$buf windows").
+	See |tcl-command|, |tcl-expr| and |tcl-option| for more information.
+	Example: >
+		if { [$buf option modified] } { $buf command "w" }
+
+==============================================================================
+6. Miscellaneous; Output from Tcl		*tcl-misc* *tcl-output*
+
+The standard Tcl commands "exit" and "catch" are replaced by custom versions.
+"exit" terminates the current Tcl script and returns to vim, which deletes the
+Tcl interpreter.  Another call to ":tcl" then creates a new Tcl interpreter.
+"exit" does NOT terminate vim!  "catch" works as before, except that it does
+not prevent script termination from "exit".  An exit code != 0 causes the ex
+command that invoked the Tcl script to return an error.
+
+Two new I/O streams are available in Tcl, "vimout" and "vimerr".  All output
+directed to them is displayed in the vim message area, as information messages
+and error messages, respectively.  The standard Tcl output streams stdout and
+stderr are mapped to vimout and vimerr, so that a normal "puts" command can be
+used to display messages in vim.
+
+==============================================================================
+7. Known bugs & problems				*tcl-bugs*
+
+Calling one of the Tcl ex commands from inside Tcl (via "::vim::command") may
+have unexpected side effects.  The command creates a new interpreter, which
+has the same abilities as the standard interpreter - making "::vim::command"
+available in a safe child interpreter therefore makes the child unsafe.  (It
+would be trivial to block nested :tcl* calls or ensure that such calls from a
+safe interpreter create only new safe interpreters, but quite pointless -
+depending on vim's configuration, "::vim::command" may execute arbitrary code
+in any number of other scripting languages.)  A call to "exit" within this new
+interpreter does not affect the old interpreter; it only terminates the new
+interpreter, then script processing continues normally in the old interpreter.
+
+Input from stdin is currently not supported.
+
+==============================================================================
+8. Examples:						*tcl-examples*
+
+Here are a few small (and maybe useful) Tcl scripts.
+
+This script sorts the lines of the entire buffer (assume it contains a list
+of names or something similar):
+	set buf $::vim::current(buffer)
+	set lines [$buf get top bottom]
+	set lines [lsort -dictionary $lines]
+	$buf set top bottom $lines
+
+This script reverses the lines in the buffer.  Note the use of "::vim::lbase"
+and "$buf last" to work with any line number setting.
+	set buf $::vim::current(buffer)
+	set t $::vim::lbase
+	set b [$buf last]
+	while { $t < $b } {
+		set tl [$buf get $t]
+		set bl [$buf get $b]
+		$buf set $t $bl
+		$buf set $b $tl
+		incr t
+		incr b -1
+	}
+
+This script adds a consecutive number to each line in the current range:
+	set buf $::vim::current(buffer)
+	set i $::vim::range(start)
+	set n 1
+	while { $i <= $::vim::range(end) } {
+		set line [$buf get $i]
+		$buf set $i "$n\t$line"
+		incr i ; incr n
+	}
+
+The same can also be done quickly with two ex commands, using ":tcldo":
+	:tcl set n 1
+	:[range]tcldo set line "$n\t$line" ; incr n
+
+This procedure runs an ex command on each buffer (idea stolen from Ron Aaron):
+	proc eachbuf { cmd } {
+		foreach b [::vim::buffer list] {
+			$b command $cmd
+		}
+	}
+Use it like this:
+	:tcl eachbuf %s/foo/bar/g
+Be careful with Tcl's string and backslash substitution, tough.  If in doubt,
+surround the ex command with curly braces.
+
+
+If you want to add some Tcl procedures permanently to vim, just place them in
+a file (e.g. "~/.vimrc.tcl" on Unix machines), and add these lines to your
+startup file (usually "~/.vimrc" on Unix):
+	if has("tcl")
+		tclfile ~/.vimrc.tcl
+	endif
+
+==============================================================================
+9. Dynamic loading					*tcl-dynamic*
+
+On MS-Windows the Tcl library can be loaded dynamically.  The |:version|
+output then includes |+tcl/dyn|.
+
+This means that Vim will search for the Tcl DLL file only when needed.  When
+you don't use the Tcl interface you don't need it, thus you can use Vim
+without this DLL file.
+
+To use the Tcl interface the Tcl DLL must be in your search path.  In a
+console window type "path" to see what directories are used.
+
+The name of the DLL must match the Tcl version Vim was compiled with.
+Currently the name is "tcl83.dll".  That is for Tcl 8.3.  To know for sure
+edit "gvim.exe" and search for "tcl\d*.dll\c".
+
+==============================================================================
+ vim:tw=78:ts=8:ft=help:norl:
--- /dev/null
+++ b/lib/vimfiles/doc/indent.txt
@@ -1,0 +1,585 @@
+*indent.txt*    For Vim version 7.1.  Last change: 2007 May 11
+
+
+		  VIM REFERENCE MANUAL    by Bram Moolenaar
+
+
+This file is about indenting C programs and other files.
+
+1. Indenting C programs		|C-indenting|
+2. Indenting by expression	|indent-expression|
+
+==============================================================================
+1. Indenting C programs					*C-indenting*
+
+The basics for C indenting are explained in section |30.2| of the user manual.
+
+Vim has options for automatically indenting C program files.  These options
+affect only the indent and do not perform other formatting.  For comment
+formatting, see |format-comments|.
+
+Note that this will not work when the |+smartindent| or |+cindent| features
+have been disabled at compile time.
+
+There are in fact four methods available for indentation:
+'autoindent'	uses the indent from the previous line.
+'smartindent'	is like 'autoindent' but also recognizes some C syntax to
+		increase/reduce the indent where appropriate.
+'cindent'	Works more cleverly than the other two and is configurable to
+		different indenting styles.
+'indentexpr'	The most flexible of all: Evaluates an expression to compute
+		the indent of a line.  When non-empty this method overrides
+		the other ones.  See |indent-expression|.
+The rest of this section describes the 'cindent' option.
+
+Note that 'cindent' indenting does not work for every code scenario.  Vim
+is not a C compiler: it does not recognize all syntax.  One requirement is
+that toplevel functions have a '{' in the first column.  Otherwise they are
+easily confused with declarations.
+
+These four options control C program indenting:
+'cindent'	Enables Vim to perform C program indenting automatically.
+'cinkeys'	Specifies which keys trigger reindenting in insert mode.
+'cinoptions'	Sets your preferred indent style.
+'cinwords'	Defines keywords that start an extra indent in the next line.
+
+If 'lisp' is not on and 'equalprg' is empty, the "=" operator indents using
+Vim's built-in algorithm rather than calling an external program.
+
+See |autocommand| for how to set the 'cindent' option automatically for C code
+files and reset it for others.
+
+					*cinkeys-format* *indentkeys-format*
+The 'cinkeys' option is a string that controls Vim's indenting in response to
+typing certain characters or commands in certain contexts.  Note that this not
+only triggers C-indenting.  When 'indentexpr' is not empty 'indentkeys' is
+used instead.  The format of 'cinkeys' and 'indentkeys' is equal.
+
+The default is "0{,0},0),:,0#,!^F,o,O,e" which specifies that indenting occurs
+as follows:
+
+	"0{"	if you type '{' as the first character in a line
+	"0}"	if you type '}' as the first character in a line
+	"0)"	if you type ')' as the first character in a line
+	":"	if you type ':' after a label or case statement
+	"0#"	if you type '#' as the first character in a line
+	"!^F"	if you type CTRL-F (which is not inserted)
+	"o"	if you type a <CR> anywhere or use the "o" command (not in
+		insert mode!)
+	"O"	if you use the "O" command (not in insert mode!)
+	"e"	if you type the second 'e' for an "else" at the start of a
+		line
+
+Characters that can precede each key:				*i_CTRL-F*
+!	When a '!' precedes the key, Vim will not insert the key but will
+	instead reindent the current line.  This allows you to define a
+	command key for reindenting the current line.  CTRL-F is the default
+	key for this.  Be careful if you define CTRL-I for this because CTRL-I
+	is the ASCII code for <Tab>.
+*	When a '*' precedes the key, Vim will reindent the line before
+	inserting the key.  If 'cinkeys' contains "*<Return>", Vim reindents
+	the current line before opening a new line.
+0	When a zero precedes the key (but appears after '!' or '*') Vim will
+	reindent the line only if the key is the first character you type in
+	the line.  When used before "=" Vim will only reindent the line if
+	there is only white space before the word.
+
+When neither '!' nor '*' precedes the key, Vim reindents the line after you
+type the key.  So ';' sets the indentation of a line which includes the ';'.
+
+Special key names:
+<>	Angle brackets mean spelled-out names of keys.  For example: "<Up>",
+	"<Ins>" (see |key-notation|).
+^	Letters preceded by a caret (^) are control characters.  For example:
+	"^F" is CTRL-F.
+o	Reindent a line when you use the "o" command or when Vim opens a new
+	line below the current one (e.g., when you type <Enter> in insert
+	mode).
+O	Reindent a line when you use the "O" command.
+e	Reindent a line that starts with "else" when you type the second 'e'.
+:	Reindent a line when a ':' is typed which is after a label or case
+	statement.  Don't reindent for a ":" in "class::method" for C++.  To
+	Reindent for any ":", use "<:>".
+=word	Reindent when typing the last character of "word".  "word" may
+	actually be part of another word.  Thus "=end" would cause reindenting
+	when typing the "d" in "endif" or "endwhile".  But not when typing
+	"bend".  Also reindent when completion produces a word that starts
+	with "word".  "0=word" reindents when there is only white space before
+	the word.
+=~word	Like =word, but ignore case.
+
+If you really want to reindent when you type 'o', 'O', 'e', '0', '<', '>',
+'*', ':' or '!', use "<o>", "<O>", "<e>", "<0>", "<<>", "<>>", "<*>", "<:>" or
+"<!>", respectively, for those keys.
+
+For an emacs-style indent mode where lines aren't indented every time you
+press <Enter> but only if you press <Tab>, I suggest:
+	:set cinkeys=0{,0},:,0#,!<Tab>,!^F
+You might also want to switch off 'autoindent' then.
+
+Note: If you change the current line's indentation manually, Vim ignores the
+cindent settings for that line.  This prevents vim from reindenting after you
+have changed the indent by typing <BS>, <Tab>, or <Space> in the indent or
+used CTRL-T or CTRL-D.
+
+						*cinoptions-values*
+The 'cinoptions' option sets how Vim performs indentation.  In the list below,
+"N" represents a number of your choice (the number can be negative).  When
+there is an 's' after the number, Vim multiplies the number by 'shiftwidth':
+"1s" is 'shiftwidth', "2s" is two times 'shiftwidth', etc.  You can use a
+decimal point, too: "-0.5s" is minus half a 'shiftwidth'.  The examples below
+assume a 'shiftwidth' of 4.
+
+	>N    Amount added for "normal" indent.  Used after a line that should
+	      increase the indent (lines starting with "if", an opening brace,
+	      etc.).  (default 'shiftwidth').
+
+		cino=		    cino=>2		cino=>2s >
+		  if (cond)	      if (cond)		  if (cond)
+		  {		      {			  {
+		      foo;		foo;			  foo;
+		  }		      }			  }
+<
+	eN    Add N to the prevailing indent inside a set of braces if the
+	      opening brace at the End of the line (more precise: is not the
+	      first character in a line).  This is useful if you want a
+	      different indent when the '{' is at the start of the line from
+	      when '{' is at the end of the line.  (default 0).
+
+		cino=		    cino=e2		cino=e-2 >
+		  if (cond) {	      if (cond) {	  if (cond) {
+		      foo;		    foo;	    foo;
+		  }		      }			  }
+		  else		      else		  else
+		  {		      {			  {
+		      bar;		  bar;		      bar;
+		  }		      }			  }
+<
+	nN    Add N to the prevailing indent for a statement after an "if",
+	      "while", etc., if it is NOT inside a set of braces.  This is
+	      useful if you want a different indent when there is no '{'
+	      before the statement from when there is a '{' before it.
+	      (default 0).
+
+		cino=		    cino=n2		cino=n-2 >
+		  if (cond)	      if (cond)		  if (cond)
+		      foo;		    foo;	    foo;
+		  else		      else		  else
+		  {		      {			  {
+		      bar;		  bar;		      bar;
+		  }		      }			  }
+<
+	fN    Place the first opening brace of a function or other block in
+	      column N.  This applies only for an opening brace that is not
+	      inside other braces and is at the start of the line.  What comes
+	      after the brace is put relative to this brace.  (default 0).
+
+		cino=		    cino=f.5s		cino=f1s >
+		  func()	      func()		  func()
+		  {			{		      {
+		      int foo;		    int foo;		  int foo;
+<
+	{N    Place opening braces N characters from the prevailing indent.
+	      This applies only for opening braces that are inside other
+	      braces.  (default 0).
+
+		cino=		    cino={.5s		cino={1s >
+		  if (cond)	      if (cond)		  if (cond)
+		  {			{		      {
+		      foo;		  foo;		      foo;
+<
+	}N    Place closing braces N characters from the matching opening
+	      brace.  (default 0).
+
+		cino=		    cino={2,}-0.5s	cino=}2 >
+		  if (cond)	      if (cond)		  if (cond)
+		  {			{		  {
+		      foo;		  foo;		      foo;
+		  }		      }			    }
+<
+	^N    Add N to the prevailing indent inside a set of braces if the
+	      opening brace is in column 0.  This can specify a different
+	      indent for whole of a function (some may like to set it to a
+	      negative number).  (default 0).
+
+		cino=		    cino=^-2		cino=^-s >
+		  func()	      func()		  func()
+		  {		      {			  {
+		      if (cond)		if (cond)	  if (cond)
+		      {			{		  {
+			  a = b;	    a = b;	      a = b;
+		      }			}		  }
+		  }		      }			  }
+<
+	:N    Place case labels N characters from the indent of the switch().
+	      (default 'shiftwidth').
+
+		cino=		    cino=:0 >
+		  switch (x)	      switch(x)
+		  {		      {
+		      case 1:	      case 1:
+			  a = b;	  a = b;
+		      default:	      default:
+		  }		      }
+<
+	=N    Place statements occurring after a case label N characters from
+	      the indent of the label.  (default 'shiftwidth').
+
+		cino=		    cino==10 >
+		   case 11:		case 11:  a = a + 1;
+		       a = a + 1;		  b = b + 1;
+<
+	lN    If N != 0 Vim will align with a case label instead of the
+	      statement after it in the same line.
+
+		cino=			    cino=l1 >
+		    switch (a) {	      switch (a) {
+			case 1: {		  case 1: {
+				    break;	      break;
+				}		  }
+<
+	bN    If N != 0 Vim will align a final "break" with the case label,
+	      so that case..break looks like a sort of block.  (default: 0).
+
+		cino=		    cino=b1 >
+		  switch (x)	      switch(x)
+		  {		      {
+		      case 1:		  case 1:
+			  a = b;	      a = b;
+			  break;	  break;
+
+		      default:		  default:
+			  a = 0;	      a = 0;
+			  break;	  break;
+		  }		      }
+<
+	gN    Place C++ scope declarations N characters from the indent of the
+	      block they are in.  (default 'shiftwidth').  A scope declaration
+	      can be "public:", "protected:" or "private:".
+
+		cino=		    cino=g0 >
+		  {		      {
+		      public:	      public:
+			  a = b;	  a = b;
+		      private:	      private:
+		  }		      }
+<
+	hN    Place statements occurring after a C++ scope declaration N
+	      characters from the indent of the label.  (default
+	      'shiftwidth').
+
+		cino=		    cino=h10 >
+		   public:		public:   a = a + 1;
+		       a = a + 1;		  b = b + 1;
+<
+	pN    Parameter declarations for K&R-style function declarations will
+	      be indented N characters from the margin.  (default
+	      'shiftwidth').
+
+		cino=		    cino=p0		cino=p2s >
+		  func(a, b)	      func(a, b)	  func(a, b)
+		      int a;	      int a;			  int a;
+		      char b;	      char b;			  char b;
+<
+	tN    Indent a function return type declaration N characters from the
+	      margin.  (default 'shiftwidth').
+
+		cino=		    cino=t0		cino=t7 >
+		      int	      int			 int
+		  func()	      func()		  func()
+<
+	iN    Indent C++ base class declarations and constructor
+	      initializations, if they start in a new line (otherwise they
+	      are aligned at the right side of the ':').
+	      (default 'shiftwidth').
+
+		cino=			  cino=i0 >
+		  class MyClass :	    class MyClass :
+		      public BaseClass      public BaseClass
+		  {}			    {}
+		  MyClass::MyClass() :	    MyClass::MyClass() :
+		      BaseClass(3)	    BaseClass(3)
+		  {}			    {}
+<
+	+N    Indent a continuation line (a line that spills onto the next) N
+	      additional characters.  (default 'shiftwidth').
+
+		cino=			  cino=+10 >
+		  a = b + 9 *		    a = b + 9 *
+		      c;			      c;
+<
+	cN    Indent comment lines after the comment opener, when there is no
+	      other text with which to align, N characters from the comment
+	      opener.  (default 3).  See also |format-comments|.
+
+		cino=			  cino=c5 >
+		  /*			    /*
+		     text.			 text.
+		   */			     */
+<
+	CN    When N is non-zero, indent comment lines by the amount specified
+	      with the c flag above even if there is other text behind the
+	      comment opener.  (default 0).
+
+		cino=c0			  cino=c0,C1 >
+		  /********		    /********
+		    text.		    text.
+		  ********/		    ********/
+<	      (Example uses ":set comments& comments-=s1:/* comments^=s0:/*")
+
+	/N    Indent comment lines N characters extra.  (default 0).
+		cino=			  cino=/4 >
+		  a = b;		    a = b;
+		  /* comment */			/* comment */
+		  c = d;		    c = d;
+<
+	(N    When in unclosed parentheses, indent N characters from the line
+	      with the unclosed parentheses.  Add a 'shiftwidth' for every
+	      unclosed parentheses.  When N is 0 or the unclosed parentheses
+	      is the first non-white character in its line, line up with the
+	      next non-white character after the unclosed parentheses.
+	      (default 'shiftwidth' * 2).
+
+		cino=			  cino=(0 >
+		  if (c1 && (c2 ||	    if (c1 && (c2 ||
+			      c3))		       c3))
+		      foo;			foo;
+		  if (c1 &&		    if (c1 &&
+			  (c2 || c3))		(c2 || c3))
+		     {			       {
+<
+	uN    Same as (N, but for one level deeper.  (default 'shiftwidth').
+
+		cino=			  cino=u2 >
+		  if (c123456789	    if (c123456789
+			  && (c22345		    && (c22345
+			      || c3))		      || c3))
+<
+	UN    When N is non-zero, do not ignore the indenting specified by
+	      ( or u in case that the unclosed parentheses is the first
+	      non-white character in its line.  (default 0).
+
+		cino= or cino=(s	  cino=(s,U1 >
+		  c = c1 &&		    c = c1 &&
+		      (				(
+		       c2 ||			    c2 ||
+		       c3			    c3
+		      ) && c4;			) && c4;
+<
+	wN    When in unclosed parentheses and N is non-zero and either
+	      using "(0" or "u0", respectively, or using "U0" and the unclosed
+	      parentheses is the first non-white character in its line, line
+	      up with the character immediately after the unclosed parentheses
+	      rather than the first non-white character.  (default 0).
+
+		cino=(0			  cino=(0,w1 >
+		  if (   c1		    if (   c1
+			 && (   c2		&& (   c2
+				|| c3))		    || c3))
+		      foo;			foo;
+<
+	WN    When in unclosed parentheses and N is non-zero and either
+	      using "(0" or "u0", respectively and the unclosed parentheses is
+	      the last non-white character in its line and it is not the
+	      closing parentheses, indent the following line N characters
+	      relative to the outer context (i.e. start of the line or the
+	      next unclosed parentheses).  (default: 0).
+
+		cino=(0			   cino=(0,W4 >
+		  a_long_line(		    a_long_line(
+			      argument,		argument,
+			      argument);	argument);
+		  a_short_line(argument,    a_short_line(argument,
+			       argument);		 argument);
+<
+	mN    When N is non-zero, line up a line starting with a closing
+	      parentheses with the first character of the line with the
+	      matching opening parentheses.  (default 0).
+
+		cino=(s			  cino=(s,m1 >
+		  c = c1 && (		    c = c1 && (
+		      c2 ||			c2 ||
+		      c3			c3
+		      ) && c4;		    ) && c4;
+		  if (			    if (
+		      c1 && c2			c1 && c2
+		     )			    )
+		      foo;			foo;
+<
+	MN    When N is non-zero, line up a line starting with a closing
+	      parentheses with the first character of the previous line.
+	      (default 0).
+
+		cino=			  cino=M1 >
+		  if (cond1 &&		    if (cond1 &&
+			 cond2			   cond2
+		     )				   )
+<
+					*java-cinoptions* *java-indenting*
+	jN    Indent java anonymous classes correctly.  The value 'N' is
+	      currently unused but must be non-zero (e.g. 'j1').  'j1' will
+	      indent for example the following code snippet correctly: >
+
+		object.add(new ChangeListener() {
+		    public void stateChanged(ChangeEvent e) {
+			do_something();
+		    }
+		});
+<
+	)N    Vim searches for unclosed parentheses at most N lines away.
+	      This limits the time needed to search for parentheses.  (default
+	      20 lines).
+
+	*N    Vim searches for unclosed comments at most N lines away.  This
+	      limits the time needed to search for the start of a comment.
+	      (default 30 lines).
+
+	#N    When N is non-zero recognize shell/Perl comments, starting with
+	      '#'.  Default N is zero: don't recognizes '#' comments.  Note
+	      that lines starting with # will still be seen as preprocessor
+	      lines.
+
+
+The defaults, spelled out in full, are:
+	cinoptions=>s,e0,n0,f0,{0,}0,^0,:s,=s,l0,b0,gs,hs,ps,ts,is,+s,c3,C0,
+		   /0,(2s,us,U0,w0,W0,m0,j0,)20,*30,#0
+
+Vim puts a line in column 1 if:
+- It starts with '#' (preprocessor directives), if 'cinkeys' contains '#'.
+- It starts with a label (a keyword followed by ':', other than "case" and
+  "default").
+- Any combination of indentations causes the line to have less than 0
+  indentation.
+
+==============================================================================
+2. Indenting by expression				*indent-expression*
+
+The basics for using flexible indenting are explained in section |30.3| of the
+user manual.
+
+If you want to write your own indent file, it must set the 'indentexpr'
+option.  Setting the 'indentkeys' option is often useful.  See the
+$VIMRUNTIME/indent directory for examples.
+
+
+REMARKS ABOUT SPECIFIC INDENT FILES ~
+
+
+FORTRAN							*ft-fortran-indent*
+
+Block if, select case, and where constructs are indented.  Comments, labelled
+statements and continuation lines are indented if the Fortran is in free
+source form, whereas they are not indented if the Fortran is in fixed source
+form because of the left margin requirements.  Hence manual indent corrections
+will be necessary for labelled statements and continuation lines when fixed
+source form is being used.  For further discussion of the method used for the
+detection of source format see |ft-fortran-syntax|.
+
+Do loops ~
+All do loops are left unindented by default.  Do loops can be unstructured in
+Fortran with (possibly multiple) loops ending on a labelled executable
+statement of almost arbitrary type.  Correct indentation requires
+compiler-quality parsing.  Old code with do loops ending on labelled statements
+of arbitrary type can be indented with elaborate programs such as Tidy
+(http://www.unb.ca/chem/ajit/f_tidy.htm).  Structured do/continue loops are
+also left unindented because continue statements are also used for purposes
+other than ending a do loop.  Programs such as Tidy can convert structured
+do/continue loops to the do/enddo form.  Do loops of the do/enddo variety can
+be indented.  If you use only structured loops of the do/enddo form, you should
+declare this by setting the fortran_do_enddo variable in your .vimrc as
+follows >
+
+   let fortran_do_enddo=1
+
+in which case do loops will be indented.  If all your loops are of do/enddo
+type only in, say, .f90 files, then you should set a buffer flag with an
+autocommand such as >
+
+  au! BufRead,BufNewFile *.f90 let b:fortran_do_enddo=1
+
+to get do loops indented in .f90 files and left alone in Fortran files with
+other extensions such as .for.
+
+
+PYTHON							*ft-python-indent*
+
+The amount of indent can be set for the following situations.  The examples
+given are de the defaults.  Note that the variables are set to an expression,
+so that you can change the value of 'shiftwidth' later.
+
+Indent after an open paren: >
+	let g:pyindent_open_paren = '&sw * 2'
+Indent after a nested paren: >
+	let g:pyindent_nested_paren = '&sw'
+Indent for a continuation line: >
+	let g:pyindent_continue = '&sw * 2'
+
+
+SHELL							*ft-sh-indent*
+
+The amount of indent applied under various circumstances in a shell file can
+be configured by setting the following keys in the |Dictionary|
+b:sh_indent_defaults to a specific amount or to a |Funcref| that references a
+function that will return the amount desired:
+
+b:sh_indent_options['default']	Default amount of indent.
+
+b:sh_indent_options['continuation-line']
+				Amount of indent to add to a continued line.
+
+b:sh_indent_options['case-labels']
+				Amount of indent to add for case labels.
+
+b:sh_indent_options['case-statement']
+				Amount of indent to add for case statements.
+
+b:sh_indent_options['case-breaks']
+				Amount of indent to add (or more likely
+				remove) for case breaks.
+
+VERILOG							*ft-verilog-indent*
+
+General block statements such as if, for, case, always, initial, function,
+specify and begin, etc., are indented.  The module block statements (first
+level blocks) are not indented by default.  you can turn on the indent with
+setting a variable in the .vimrc as follows: >
+
+  let b:verilog_indent_modules = 1
+
+then the module blocks will be indented.  To stop this, remove the variable: >
+
+  :unlet b:verilog_indent_modules
+
+To set the variable only for Verilog file.  The following statements can be
+used: >
+
+  au BufReadPost * if exists("b:current_syntax")
+  au BufReadPost *   if b:current_syntax == "verilog"
+  au BufReadPost *     let b:verilog_indent_modules = 1
+  au BufReadPost *   endif
+  au BufReadPost * endif
+
+Furthermore, setting the variable b:verilog_indent_width to change the
+indenting width (default is 'shiftwidth'): >
+
+  let b:verilog_indent_width = 4
+  let b:verilog_indent_width = &sw * 2
+
+In addition, you can turn the verbose mode for debug issue: >
+
+  let b:verilog_indent_verbose = 1
+
+Make sure to do ":set cmdheight=2" first to allow the display of the message.
+
+
+VIM							*ft-vim-indent*
+
+For indenting Vim scripts there is one variable that specifies the amount of
+indent for a continuation line, a line that starts with a backslash: >
+
+	:let g:vim_indent_cont = &sw * 3
+
+Three times shiftwidth is the default value.
+
+
+ vim:tw=78:ts=8:ft=help:norl:
--- /dev/null
+++ b/lib/vimfiles/doc/index.txt
@@ -1,0 +1,1564 @@
+*index.txt*     For Vim version 7.1.  Last change: 2007 May 05
+
+
+		  VIM REFERENCE MANUAL    by Bram Moolenaar
+
+								*index*
+This file contains a list of all commands for each mode, with a tag and a
+short description.  The lists are sorted on ASCII value.
+
+Tip: When looking for certain functionality, use a search command.  E.g.,
+to look for deleting something, use: "/delete".
+
+1. Insert mode				|insert-index|
+2. Normal mode				|normal-index|
+   2.1. Text objects			|objects|
+   2.2. Window commands			|CTRL-W|
+   2.3. Square bracket commands		|[|
+   2.4. Commands starting with 'g'	|g|
+   2.5. Commands starting with 'z'	|z|
+3. Visual mode				|visual-index|
+4. Command-line editing			|ex-edit-index|
+5. EX commands				|ex-cmd-index|
+
+For an overview of options see help.txt |option-list|.
+For an overview of built-in functions see |functions|.
+For a list of Vim variables see |vim-variable|.
+For a complete listing of all help items see |help-tags|.
+
+==============================================================================
+1. Insert mode						*insert-index*
+
+tag		char		action	~
+-----------------------------------------------------------------------
+|i_CTRL-@|	CTRL-@		insert previously inserted text and stop
+				insert
+|i_CTRL-A|	CTRL-A		insert previously inserted text
+		CTRL-B		not used |i_CTRL-B-gone|
+|i_CTRL-C|	CTRL-C		quit insert mode, without checking for
+				abbreviation, unless 'insertmode' set.
+|i_CTRL-D|	CTRL-D		delete one shiftwidth of indent in the current
+				line
+|i_CTRL-E|	CTRL-E		insert the character which is below the cursor
+		CTRL-F		not used (but by default it's in 'cinkeys' to
+				re-indent the current line)
+|i_CTRL-G_j|	CTRL-G CTRL-J	line down, to column where inserting started
+|i_CTRL-G_j|	CTRL-G j	line down, to column where inserting started
+|i_CTRL-G_j|	CTRL-G <Down>	line down, to column where inserting started
+|i_CTRL-G_k|	CTRL-G CTRL-K	line up, to column where inserting started
+|i_CTRL-G_k|	CTRL-G k	line up, to column where inserting started
+|i_CTRL-G_k|	CTRL-G <Up>	line up, to column where inserting started
+|i_CTRL-G_u|	CTRL-G u	start new undoable edit
+|i_<BS>|	<BS>		delete character before the cursor
+|i_digraph|	{char1}<BS>{char2}
+				enter digraph (only when 'digraph' option set)
+|i_CTRL-H|	CTRL-H		same as <BS>
+|i_<Tab>|	<Tab>		insert a <Tab> character
+|i_CTRL-I|	CTRL-I		same as <Tab>
+|i_<NL>|	<NL>		same as <CR>
+|i_CTRL-J|	CTRL-J		same as <CR>
+|i_CTRL-K|	CTRL-K {char1} {char2}
+				enter digraph
+|i_CTRL-L|	CTRL-L		when 'insertmode' set: Leave Insert mode
+|i_<CR>|	<CR>		begin new line
+|i_CTRL-M|	CTRL-M		same as <CR>
+|i_CTRL-N|	CTRL-N		find next match for keyword in front of the
+				cursor
+|i_CTRL-O|	CTRL-O		execute a single command and return to insert
+				mode
+|i_CTRL-P|	CTRL-P		find previous match for keyword in front of
+				the cursor
+|i_CTRL-Q|	CTRL-Q		same as CTRL-V, unless used for terminal
+				control flow
+|i_CTRL-R|	CTRL-R {0-9a-z"%#*:=}
+				insert the contents of a register
+|i_CTRL-R_CTRL-R| CTRL-R CTRL-R {0-9a-z"%#*:=}
+				insert the contents of a register literally
+|i_CTRL-R_CTRL-O| CTRL-R CTRL-O {0-9a-z"%#*:=}
+				insert the contents of a register literally
+				and don't auto-indent
+|i_CTRL-R_CTRL-P| CTRL-R CTRL-P {0-9a-z"%#*:=}
+				insert the contents of a register literally
+				and fix indent.
+		CTRL-S		(used for terminal control flow)
+|i_CTRL-T|	CTRL-T		insert one shiftwidth of indent in current
+				line
+|i_CTRL-U|	CTRL-U		delete all entered characters in the current
+				line
+|i_CTRL-V|	CTRL-V {char}	insert next non-digit literally
+|i_CTRL-V_digit| CTRL-V {number} insert three digit decimal number as a single
+				byte.
+|i_CTRL-W|	CTRL-W		delete word before the cursor
+|i_CTRL-X|	CTRL-X {mode}	enter CTRL-X sub mode, see |i_CTRL-X_index|
+|i_CTRL-Y|	CTRL-Y		insert the character which is above the cursor
+|i_CTRL-Z|	CTRL-Z		when 'insertmode' set: suspend Vim
+|i_<Esc>|	<Esc>		end insert mode (unless 'insertmode' set)
+|i_CTRL-[|	CTRL-[		same as <Esc>
+|i_CTRL-\_CTRL-N| CTRL-\ CTRL-N	 go to Normal mode
+|i_CTRL-\_CTRL-G| CTRL-\ CTRL-G	 go to mode specified with 'insertmode'
+		CTRL-\ a - z	reserved for extensions
+		CTRL-\ others	not used
+|i_CTRL-]|	CTRL-]		trigger abbreviation
+|i_CTRL-^|	CTRL-^		toggle use of |:lmap| mappings
+|i_CTRL-_|	CTRL-_		When 'allowrevins' set: change language
+				(Hebrew, Farsi) {only when compiled with
+				+rightleft feature}
+
+		<Space> to '~'	not used, except '0' and '^' followed by
+				CTRL-D
+
+|i_0_CTRL-D|	0 CTRL-D	delete all indent in the current line
+|i_^_CTRL-D|	^ CTRL-D	delete all indent in the current line, restore
+				it in the next line
+
+|i_<Del>|	<Del>		delete character under the cursor
+
+		Meta characters (0x80 to 0xff, 128 to 255)
+				not used
+
+|i_<Left>|	<Left>		cursor one character left
+|i_<S-Left>|	<S-Left>	cursor one word left
+|i_<C-Left>|	<C-Left>	cursor one word left
+|i_<Right>|	<Right>		cursor one character right
+|i_<S-Right>|	<S-Right>	cursor one word right
+|i_<C-Right>|	<C-Right>	cursor one word right
+|i_<Up>|	<Up>		cursor one line up
+|i_<S-Up>|	<S-Up>		same as <PageUp>
+|i_<Down>|	<Down>		cursor one line down
+|i_<S-Down>|	<S-Down>	same as <PageDown>
+|i_<Home>|	<Home>		cursor to start of line
+|i_<C-Home>|	<C-Home>	cursor to start of file
+|i_<End>|	<End>		cursor past end of line
+|i_<C-End>|	<C-End>		cursor past end of file
+|i_<PageUp>|	<PageUp>	one screenful backward
+|i_<PageDown>|	<PageDown>	one screenful forward
+|i_<F1>|	<F1>		same as <Help>
+|i_<Help>|	<Help>		stop insert mode and display help window
+|i_<Insert>|	<Insert>	toggle Insert/Replace mode
+|i_<LeftMouse>|	<LeftMouse>	cursor at mouse click
+|i_<MouseDown>|	<MouseDown>	scroll three lines downwards
+|i_<S-MouseDown>| <S-MouseDown>	scroll a full page downwards
+|i_<MouseUp>|	<MouseUp>	scroll three lines upwards
+|i_<S-MouseUp>|	<S-MouseUp>	scroll a full page upwards
+
+commands in CTRL-X submode				*i_CTRL-X_index*
+
+|i_CTRL-X_CTRL-D|	CTRL-X CTRL-D	complete defined identifiers
+|i_CTRL-X_CTRL-E|	CTRL-X CTRL-E	scroll up
+|i_CTRL-X_CTRL-F|	CTRL-X CTRL-F	complete file names
+|i_CTRL-X_CTRL-I|	CTRL-X CTRL-I	complete identifiers
+|i_CTRL-X_CTRL-K|	CTRL-X CTRL-K	complete identifiers from dictionary
+|i_CTRL-X_CTRL-L|	CTRL-X CTRL-L	complete whole lines
+|i_CTRL-X_CTRL-N|	CTRL-X CTRL-N	next completion
+|i_CTRL-X_CTRL-O|	CTRL-X CTRL-O	omni completion
+|i_CTRL-X_CTRL-P|	CTRL-X CTRL-P	previous completion
+|i_CTRL-X_CTRL-S|	CTRL-X CTRL-S	spelling suggestions
+|i_CTRL-X_CTRL-T|	CTRL-X CTRL-T	complete identifiers from thesaurus
+|i_CTRL-X_CTRL-Y|	CTRL-X CTRL-Y	scroll down
+|i_CTRL-X_CTRL-U|	CTRL-X CTRL-U	complete with 'completefunc'
+|i_CTRL-X_CTRL-V|	CTRL-X CTRL-V	complete like in : command line
+|i_CTRL-X_CTRL-]|	CTRL-X CTRL-]	complete tags
+|i_CTRL-X_s|		CTRL-X s	spelling suggestions
+{not available when compiled without the +insert_expand feature}
+
+==============================================================================
+2. Normal mode						*normal-index*
+
+CHAR	 any non-blank character
+WORD	 a sequence of non-blank characters
+N	 a number entered before the command
+{motion} a cursor movement command
+Nmove	 the text that is moved over with a {motion}
+SECTION	 a section that possibly starts with '}' instead of '{'
+
+note: 1 = cursor movement command; 2 = can be undone/redone
+
+tag		char	      note action in Normal mode	~
+------------------------------------------------------------------------------
+		CTRL-@		   not used
+|CTRL-A|	CTRL-A		2  add N to number at/after cursor
+|CTRL-B|	CTRL-B		1  scroll N screens Backwards
+|CTRL-C|	CTRL-C		   interrupt current (search) command
+|CTRL-D|	CTRL-D		   scroll Down N lines (default: half a screen)
+|CTRL-E|	CTRL-E		   scroll N lines upwards (N lines Extra)
+|CTRL-F|	CTRL-F		1  scroll N screens Forward
+|CTRL-G|	CTRL-G		   display current file name and position
+|<BS>|		<BS>		1  same as "h"
+|CTRL-H|	CTRL-H		1  same as "h"
+|<Tab>|		<Tab>		1  go to N newer entry in jump list
+|CTRL-I|	CTRL-I		1  same as <Tab>
+|<NL>|		<NL>		1  same as "j"
+|CTRL-J|	CTRL-J		1  same as "j"
+		CTRL-K		   not used
+|CTRL-L|	CTRL-L		   redraw screen
+|<CR>|		<CR>		1  cursor to the first CHAR N lines lower
+|CTRL-M|	CTRL-M		1  same as <CR>
+|CTRL-N|	CTRL-N		1  same as "j"
+|CTRL-O|	CTRL-O		1  go to N older entry in jump list
+|CTRL-P|	CTRL-P		1  same as "k"
+		CTRL-Q		   (used for terminal control flow)
+|CTRL-R|	CTRL-R		2  redo changes which were undone with 'u'
+		CTRL-S		   (used for terminal control flow)
+|CTRL-T|	CTRL-T		   jump to N older Tag in tag list
+|CTRL-U|	CTRL-U		   scroll N lines Upwards (default: half a
+				   screen)
+|CTRL-V|	CTRL-V		   start blockwise Visual mode
+|CTRL-W|	CTRL-W {char}	   window commands, see |CTRL-W|
+|CTRL-X|	CTRL-X		2  subtract N from number at/after cursor
+|CTRL-Y|	CTRL-Y		   scroll N lines downwards
+|CTRL-Z|	CTRL-Z		   suspend program (or start new shell)
+		CTRL-[ <Esc>	   not used
+|CTRL-\_CTRL-N| CTRL-\ CTRL-N	   go to Normal mode (no-op)
+|CTRL-\_CTRL-G| CTRL-\ CTRL-G	   go to mode specified with 'insertmode'
+		CTRL-\ a - z	   reserved for extensions
+		CTRL-\ others      not used
+|CTRL-]|	CTRL-]		   :ta to ident under cursor
+|CTRL-^|	CTRL-^		   edit Nth alternate file (equivalent to
+				   ":e #N")
+		CTRL-_		   not used
+
+|<Space>|	<Space>		1  same as "l"
+|!|		!{motion}{filter}
+				2  filter Nmove text through the {filter}
+				   command
+|!!|		!!{filter}	2  filter N lines through the {filter} command
+|quote|		"{a-zA-Z0-9.%#:-"}  use register {a-zA-Z0-9.%#:-"} for next
+				   delete, yank or put (uppercase to append)
+				   ({.%#:} only work with put)
+|#|		#		1  search backward for the Nth occurrence of
+				   the ident under the cursor
+|$|		$		1  cursor to the end of Nth next line
+|%|		%		1  find the next (curly/square) bracket on
+				   this line and go to its match, or go to
+				   matching comment bracket, or go to matching
+				   preprocessor directive.
+|N%|		{count}%	1  go to N percentage in the file
+|&|		&		2  repeat last :s
+|'|		'{a-zA-Z0-9}	1  cursor to the first CHAR on the line with
+				   mark {a-zA-Z0-9}
+|''|		''		1  cursor to the first CHAR of the line where
+				   the cursor was before the latest jump.
+|'(|		'(		1  cursor to the first CHAR on the line of the
+				   start of the current sentence
+|')|		')		1  cursor to the first CHAR on the line of the
+				   end of the current sentence
+|'<|		'<		1  cursor to the first CHAR of the line where
+				   highlighted area starts/started in the
+				   current buffer.
+|'>|		'>		1  cursor to the first CHAR of the line where
+				   highlighted area ends/ended in the current
+				   buffer.
+|'[|		'[		1  cursor to the first CHAR on the line of the
+				   start of last operated text or start of put
+				   text
+|']|		']		1  cursor to the first CHAR on the line of the
+				   end of last operated text or end of put
+				   text
+|'{|		'{		1  cursor to the first CHAR on the line of the
+				   start of the current paragraph
+|'}|		'}		1  cursor to the first CHAR on the line of the
+				   end of the current paragraph
+|(|		(		1  cursor N sentences backward
+|)|		)		1  cursor N sentences forward
+|star|		*		1  search forward for the Nth occurrence of
+				   the ident under the cursor
+|+|		+		1  same as <CR>
+|,|		,		1  repeat latest f, t, F or T in opposite
+				   direction N times
+|-|		-		1  cursor to the first CHAR N lines higher
+|.|		.		2  repeat last change with count replaced with
+				   N
+|/|		/{pattern}<CR>	1  search forward for the Nth occurrence of
+				   {pattern}
+|/<CR>|		/<CR>		1  search forward for {pattern} of last search
+|count|		0		1  cursor to the first char of the line
+|count|		1		   prepend to command to give a count
+|count|		2			"
+|count|		3			"
+|count|		4			"
+|count|		5			"
+|count|		6			"
+|count|		7			"
+|count|		8			"
+|count|		9			"
+|:|		:		1  start entering an Ex command
+|N:|		{count}:	   start entering an Ex command with range
+				   from current line to N-1 lines down
+|;|		;		1  repeat latest f, t, F or T N times
+|<|		<{motion}	2  shift Nmove lines one 'shiftwidth'
+				   leftwards
+|<<|		<<		2  shift N lines one 'shiftwidth' leftwards
+|=|		={motion}	2  filter Nmove lines through "indent"
+|==|		==		2  filter N lines through "indent"
+|>|		>{motion}	2  shift Nmove lines one 'shiftwidth'
+				   rightwards
+|>>|		>>		2  shift N lines one 'shiftwidth' rightwards
+|?|		?{pattern}<CR>	1  search backward for the Nth previous
+				   occurrence of {pattern}
+|?<CR>|		?<CR>		1  search backward for {pattern} of last search
+|@|		@{a-z}		2  execute the contents of register {a-z}
+				   N times
+|@:|		@:		   repeat the previous ":" command N times
+|@@|		@@		2  repeat the previous @{a-z} N times
+|A|		A		2  append text after the end of the line N times
+|B|		B		1  cursor N WORDS backward
+|C|		["x]C		2  change from the cursor position to the end
+				   of the line, and N-1 more lines [into
+				   buffer x]; synonym for "c$"
+|D|		["x]D		2  delete the characters under the cursor
+				   until the end of the line and N-1 more
+				   lines [into buffer x]; synonym for "d$"
+|E|		E		1  cursor forward to the end of WORD N
+|F|		F{char}		1  cursor to the Nth occurrence of {char} to
+				   the left
+|G|		G		1  cursor to line N, default last line
+|H|		H		1  cursor to line N from top of screen
+|I|		I		2  insert text before the first CHAR on the
+				   line N times
+|J|		J		2  Join N lines; default is 2
+|K|		K		   lookup Keyword under the cursor with
+				   'keywordprg'
+|L|		L		1  cursor to line N from bottom of screen
+|M|		M		1  cursor to middle line of screen
+|N|		N		1  repeat the latest '/' or '?' N times in
+				   opposite direction
+|O|		O		2  begin a new line above the cursor and
+				   insert text, repeat N times
+|P|		["x]P		2  put the text [from buffer x] before the
+				   cursor N times
+|Q|		Q		   switch to "Ex" mode
+|R|		R		2  enter replace mode: overtype existing
+				   characters, repeat the entered text N-1
+				   times
+|S|		["x]S		2  delete N lines [into buffer x] and start
+				   insert; synonym for "cc".
+|T|		T{char}		1  cursor till after Nth occurrence of {char}
+				   to the left
+|U|		U		2  undo all latest changes on one line
+|V|		V		   start linewise Visual mode
+|W|		W		1  cursor N WORDS forward
+|X|		["x]X		2  delete N characters before the cursor [into
+				   buffer x]
+|Y|		["x]Y		   yank N lines [into buffer x]; synonym for
+				   "yy"
+|ZZ|		ZZ		   store current file if modified, and exit
+|ZQ|		ZQ		   exit current file always
+|[|		[{char}		   square bracket command (see |[| below)
+		\		   not used
+|]|		]{char}		   square bracket command (see |]| below)
+|^|		^		1  cursor to the first CHAR of the line
+|_|		_		1  cursor to the first CHAR N - 1 lines lower
+|`|		`{a-zA-Z0-9}	1  cursor to the mark {a-zA-Z0-9}
+|`(|		`(		1  cursor to the start of the current sentence
+|`)|		`)		1  cursor to the end of the current sentence
+|`<|		`<		1  cursor to the start of the highlighted area
+|`>|		`>		1  cursor to the end of the highlighted area
+|`[|		`[		1  cursor to the start of last operated text
+				   or start of putted text
+|`]|		`]		1  cursor to the end of last operated text or
+				   end of putted text
+|``|		``		1  cursor to the position before latest jump
+|`{|		`{		1  cursor to the start of the current paragraph
+|`}|		`}		1  cursor to the end of the current paragraph
+|a|		a		2  append text after the cursor N times
+|b|		b		1  cursor N words backward
+|c|		["x]c{motion}	2  delete Nmove text [into buffer x] and start
+				   insert
+|cc|		["x]cc		2  delete N lines [into buffer x] and start
+				   insert
+|d|		["x]d{motion}	2  delete Nmove text [into buffer x]
+|dd|		["x]dd		2  delete N lines [into buffer x]
+|do|		do		2  same as ":diffget"
+|dp|		dp		2  same as ":diffput"
+|e|		e		1  cursor forward to the end of word N
+|f|		f{char}		1  cursor to Nth occurrence of {char} to the
+				   right
+|g|		g{char}		   extended commands, see |g| below
+|h|		h		1  cursor N chars to the left
+|i|		i		2  insert text before the cursor N times
+|j|		j		1  cursor N lines downward
+|k|		k		1  cursor N lines upward
+|l|		l		1  cursor N chars to the right
+|m|		m{A-Za-z}	   set mark {A-Za-z} at cursor position
+|n|		n		1  repeat the latest '/' or '?' N times
+|o|		o		2  begin a new line below the cursor and
+				   insert text, repeat N times
+|p|		["x]p		2  put the text [from register x] after the
+				   cursor N times
+|q|		q{0-9a-zA-Z"}	   record typed characters into named register
+				   {0-9a-zA-Z"} (uppercase to append)
+|q|		q		   (while recording) stops recording
+|q:|		q:		   edit : command-line in command-line window
+|q/|		q/		   edit / command-line in command-line window
+|q?|		q?		   edit ? command-line in command-line window
+|r|		r{char}		2  replace N chars with {char}
+|s|		["x]s		2  (substitute) delete N characters [into
+				   buffer x] and start insert
+|t|		t{char}		1  cursor till before Nth occurrence of {char}
+				   to the right
+|u|		u		2  undo changes
+|v|		v		   start characterwise Visual mode
+|w|		w		1  cursor N words forward
+|x|		["x]x		2  delete N characters under and after the
+				   cursor [into buffer x]
+|y|		["x]y{motion}	   yank Nmove text [into buffer x]
+|yy|		["x]yy		   yank N lines [into buffer x]
+|z|		z{char}		   commands starting with 'z', see |z| below
+|{|		{		1  cursor N paragraphs backward
+|bar|		|		1  cursor to column N
+|}|		}		1  cursor N paragraphs forward
+|~|		~		2  'tildeop' off: switch case of N characters
+				   under cursor and move the cursor N
+				   characters to the right
+|~|		~{motion}	   'tildeop' on: switch case of Nmove text
+|<C-End>|	<C-End>		1  same as "G"
+|<C-Home>|	<C-Home>	1  same as "gg"
+|<C-Left>|	<C-Left>	1  same as "b"
+|<C-LeftMouse>|	<C-LeftMouse>	   ":ta" to the keyword at the mouse click
+|<C-Right>|	<C-Right>	1  same as "w"
+|<C-RightMouse>| <C-RightMouse>	   same as "CTRL-T"
+|<Del>|		["x]<Del>	2  same as "x"
+|N<Del>|	{count}<Del>	   remove the last digit from {count}
+|<Down>|	<Down>		1  same as "j"
+|<End>|		<End>		1  same as "$"
+|<F1>|		<F1>		   same as <Help>
+|<Help>|	<Help>		   open a help window
+|<Home>|	<Home>		1  same as "0"
+|<Insert>|	<Insert>	2  same as "i"
+|<Left>|	<Left>		1  same as "h"
+|<LeftMouse>|	<LeftMouse>	1  move cursor to the mouse click position
+|<MiddleMouse>| <MiddleMouse>	2  same as "gP" at the mouse click position
+|<PageDown>|	<PageDown>	   same as CTRL-F
+|<PageUp>|	<PageUp>	   same as CTRL-B
+|<Right>|	<Right>		1  same as "l"
+|<RightMouse>|	<RightMouse>	   start Visual mode, move cursor to the mouse
+				   click position
+|<S-Down>|	<S-Down>	1  same as CTRL-F
+|<S-Left>|	<S-Left>	1  same as "b"
+|<S-LeftMouse>|	<S-LeftMouse>	   same as "*" at the mouse click position
+|<S-Right>|	<S-Right>	1  same as "w"
+|<S-RightMouse>| <S-RightMouse>	   same as "#" at the mouse click position
+|<S-Up>|	<S-Up>		1  same as CTRL-B
+|<Undo>|	<Undo>		2  same as "u"
+|<Up>|		<Up>		1  same as "k"
+|<MouseDown>|	<MouseDown>	   scroll three lines downwards
+|<S-MouseDown>|	<S-MouseDown>	   scroll a full page downwards
+|<MouseUp>|	<MouseUp>	   scroll three lines upwards
+|<S-MouseUp>|	<S-MouseUp>	   scroll a full page upwards
+
+==============================================================================
+2.1 Text objects						*objects*
+
+These can be used after an operator or in Visual mode to select an object.
+
+tag		command		   action in Normal mode	~
+------------------------------------------------------------------------------
+|v_aquote|	a"		   double quoted string
+|v_a'|		a'		   single quoted string
+|v_a(|		a(		   same as ab
+|v_a)|		a)		   same as ab
+|v_a<|		a<		   "a <>" from '<' to the matching '>'
+|v_a>|		a>		   same as a<
+|v_aB|		aB		   "a Block" from "[{" to "]}" (with brackets)
+|v_aW|		aW		   "a WORD" (with white space)
+|v_a[|		a[		   "a []" from '[' to the matching ']'
+|v_a]|		a]		   same as a[
+|v_a`|		a`		   string in backticks
+|v_ab|		ab		   "a block" from "[(" to "])" (with braces)
+|v_ap|		ap		   "a paragraph" (with white space)
+|v_as|		as		   "a sentence" (with white space)
+|v_aw|		aw		   "a word" (with white space)
+|v_a{|		a{		   same as aB
+|v_a}|		a}		   same as aB
+|v_iquote|	i"		   double quoted string without the quotes
+|v_i'|		i'		   single quoted string without the quotes
+|v_i(|		i(		   same as ib
+|v_i)|		i)		   same as ib
+|v_i<|		i<		   "inner <>" from '<' to the matching '>'
+|v_i>|		i>		   same as i<
+|v_iB|		iB		   "inner Block" from "[{" and "]}"
+|v_iW|		iW		   "inner WORD"
+|v_i[|		i[		   "inner []" from '[' to the matching ']'
+|v_i]|		i]		   same as i[
+|v_i`|		i`		   string in backticks without the backticks
+|v_ib|		ib		   "inner block" from "[(" to "])"
+|v_ip|		ip		   "inner paragraph"
+|v_is|		is		   "inner sentence"
+|v_iw|		iw		   "inner word"
+|v_i{|		i{		   same as iB
+|v_i}|		i}		   same as iB
+
+==============================================================================
+2.2 Window commands						*CTRL-W*
+
+tag		command		   action in Normal mode	~
+------------------------------------------------------------------------------
+|CTRL-W_CTRL-B|	CTRL-W CTRL-B	   same as "CTRL-W b"
+|CTRL-W_CTRL-C|	CTRL-W CTRL-C	   same as "CTRL-W c"
+|CTRL-W_CTRL-D|	CTRL-W CTRL-D	   same as "CTRL-W d"
+|CTRL-W_CTRL-F|	CTRL-W CTRL-F	   same as "CTRL-W f"
+		CTRL-W CTRL-G	   same as "CTRL-W g .."
+|CTRL-W_CTRL-H|	CTRL-W CTRL-H	   same as "CTRL-W h"
+|CTRL-W_CTRL-I|	CTRL-W CTRL-I	   same as "CTRL-W i"
+|CTRL-W_CTRL-J|	CTRL-W CTRL-J	   same as "CTRL-W j"
+|CTRL-W_CTRL-K|	CTRL-W CTRL-K	   same as "CTRL-W k"
+|CTRL-W_CTRL-L|	CTRL-W CTRL-L	   same as "CTRL-W l"
+|CTRL-W_CTRL-N|	CTRL-W CTRL-N	   same as "CTRL-W n"
+|CTRL-W_CTRL-O|	CTRL-W CTRL-O	   same as "CTRL-W o"
+|CTRL-W_CTRL-P|	CTRL-W CTRL-P	   same as "CTRL-W p"
+|CTRL-W_CTRL-Q|	CTRL-W CTRL-Q	   same as "CTRL-W q"
+|CTRL-W_CTRL-R|	CTRL-W CTRL-R	   same as "CTRL-W r"
+|CTRL-W_CTRL-S|	CTRL-W CTRL-S	   same as "CTRL-W s"
+|CTRL-W_CTRL-T|	CTRL-W CTRL-T	   same as "CTRL-W t"
+|CTRL-W_CTRL-V|	CTRL-W CTRL-V	   same as "CTRL-W v"
+|CTRL-W_CTRL-W|	CTRL-W CTRL-W	   same as "CTRL-W w"
+|CTRL-W_CTRL-X|	CTRL-W CTRL-X	   same as "CTRL-W x"
+|CTRL-W_CTRL-Z|	CTRL-W CTRL-Z	   same as "CTRL-W z"
+|CTRL-W_CTRL-]|	CTRL-W CTRL-]	   same as "CTRL-W ]"
+|CTRL-W_CTRL-^|	CTRL-W CTRL-^	   same as "CTRL-W ^"
+|CTRL-W_CTRL-_|	CTRL-W CTRL-_	   same as "CTRL-W _"
+|CTRL-W_+|	CTRL-W +	   increase current window height N lines
+|CTRL-W_-|	CTRL-W -	   decrease current window height N lines
+|CTRL-W_<|	CTRL-W <	   decrease current window width N columns
+|CTRL-W_=|	CTRL-W =	   make all windows the same height
+|CTRL-W_>|	CTRL-W >	   increase current window width N columns
+|CTRL-W_H|	CTRL-W H	   move current window to the far left
+|CTRL-W_J|	CTRL-W J	   move current window to the very bottom
+|CTRL-W_K|	CTRL-W K	   move current window to the very top
+|CTRL-W_L|	CTRL-W L	   move current window to the far right
+|CTRL-W_P|	CTRL-W P	   go to preview window
+|CTRL-W_R|	CTRL-W R	   rotate windows upwards N times
+|CTRL-W_S|	CTRL-W S	   same as "CTRL-W s"
+|CTRL-W_T|	CTRL-W T	   move current window to a new tab page
+|CTRL-W_W|	CTRL-W W	   go to N previous window (wrap around)
+|CTRL-W_]|	CTRL-W ]	   split window and jump to tag under cursor
+|CTRL-W_^|	CTRL-W ^	   split current window and edit alternate
+				   file N
+|CTRL-W__|	CTRL-W _	   set current window height to N (default:
+				   very high)
+|CTRL-W_b|	CTRL-W b	   go to bottom window
+|CTRL-W_c|	CTRL-W c	   close current window (like |:close|)
+|CTRL-W_d|	CTRL-W d	   split window and jump to definition under
+				   the cursor
+|CTRL-W_f|	CTRL-W f	   split window and edit file name under the
+				   cursor
+|CTRL-W_F|	CTRL-W F	   split window and edit file name under the
+				   cursor and jump to the line number
+				   following the file name.
+|CTRL-W_g_CTRL-]| CTRL-W g CTRL-]  split window and do |:tjump| to tag under
+				   cursor
+|CTRL-W_g]|	CTRL-W g ]	   split window and do |:tselect| for tag
+				   under cursor
+|CTRL-W_g}|	CTRL-W g }	   do a |:ptjump| to the tag under the cursor
+|CTRL-W_gf|	CTRL-W g f	   edit file name under the cursor in a new
+				   tab page
+|CTRL-W_gF|	CTRL-W g F	   edit file name under the cursor in a new
+				   tab page and jump to the line number
+				   following the file name.
+|CTRL-W_h|	CTRL-W h	   go to Nth left window (stop at first window)
+|CTRL-W_i|	CTRL-W i	   split window and jump to declaration of
+				   identifier under the cursor
+|CTRL-W_j|	CTRL-W j	   go N windows down (stop at last window)
+|CTRL-W_k|	CTRL-W k	   go N windows up (stop at first window)
+|CTRL-W_l|	CTRL-W l	   go to Nth right window (stop at last window)
+|CTRL-W_n|	CTRL-W n	   open new window, N lines high
+|CTRL-W_o|	CTRL-W o	   close all but current window (like |:only|)
+|CTRL-W_p|	CTRL-W p	   go to previous (last accessed) window
+|CTRL-W_q|	CTRL-W q	   quit current window (like |:quit|)
+|CTRL-W_r|	CTRL-W r	   rotate windows downwards N times
+|CTRL-W_s|	CTRL-W s	   split current window in two parts, new
+				   window N lines high
+|CTRL-W_t|	CTRL-W t	   go to top window
+|CTRL-W_v|	CTRL-W v	   split current window vertically, new window
+				   N lines wide
+|CTRL-W_w|	CTRL-W w	   go to N next window (wrap around)
+|CTRL-W_x|	CTRL-W x	   exchange current window with window N
+				   (default: next window)
+|CTRL-W_z|	CTRL-W z	   close preview window
+|CTRL-W_bar|	CTRL-W |	   set window width to N columns
+|CTRL-W_}|	CTRL-W }	   show tag under cursor in preview window
+|CTRL-W_<Down>|	CTRL-W <Down>	   same as "CTRL-W j"
+|CTRL-W_<Up>|	CTRL-W <Up>	   same as "CTRL-W k"
+|CTRL-W_<Left>|	CTRL-W <Left>	   same as "CTRL-W h"
+|CTRL-W_<Right>| CTRL-W <Right>	   same as "CTRL-W l"
+
+==============================================================================
+2.3 Square bracket commands					*[* *]*
+
+tag		char	      note action in Normal mode	~
+------------------------------------------------------------------------------
+|[_CTRL-D|	[ CTRL-D	   jump to first #define found in current and
+				   included files matching the word under the
+				   cursor, start searching at beginning of
+				   current file
+|[_CTRL-I|	[ CTRL-I	   jump to first line in current and included
+				   files that contains the word under the
+				   cursor, start searching at beginning of
+				   current file
+|[#|		[#		1  cursor to N previous unmatched #if, #else
+				   or #ifdef
+|['|		['		1  cursor to previous lowercase mark, on first
+				   non-blank
+|[(|		[(		1  cursor N times back to unmatched '('
+|[star|		[*		1  same as "[/"
+|[`|		[`		1  cursor to previous lowercase mark
+|[/|		[/		1  cursor to N previous start of a C comment
+|[D|		[D		   list all defines found in current and
+				   included files matching the word under the
+				   cursor, start searching at beginning of
+				   current file
+|[I|		[I		   list all lines found in current and
+				   included files that contain the word under
+				   the cursor, start searching at beginning of
+				   current file
+|[P|		[P		2  same as "[p"
+|[[|		[[		1  cursor N sections backward
+|[]|		[]		1  cursor N SECTIONS backward
+|[c|		[c		1  cursor N times backwards to start of change
+|[d|		[d		   show first #define found in current and
+				   included files matching the word under the
+				   cursor, start searching at beginning of
+				   current file
+|[f|		[f		   same as "gf"
+|[i|		[i		   show first line found in current and
+				   included files that contains the word under
+				   the cursor, start searching at beginning of
+				   current file
+|[m|		[m		1  cursor N times back to start of member
+				   function
+|[p|		[p		2  like "P", but adjust indent to current line
+|[s|		[s		1  move to the previous misspelled word
+|[z|		[z		1  move to start of open fold
+|[{|		[{		1  cursor N times back to unmatched '{'
+|[<MiddleMouse> [<MiddleMouse>	2  same as "[p"
+
+|]_CTRL-D|	] CTRL-D	   jump to first #define found in current and
+				   included files matching the word under the
+				   cursor, start searching at cursor position
+|]_CTRL-I|	] CTRL-I	   jump to first line in current and included
+				   files that contains the word under the
+				   cursor, start searching at cursor position
+|]#|		]#		1  cursor to N next unmatched #endif or #else
+|]'|		]'		1  cursor to next lowercase mark, on first
+				   non-blank
+|])|		])		1  cursor N times forward to unmatched ')'
+|]star|		]*		1  same as "]/"
+|]`|		]`		1  cursor to next lowercase mark
+|]/|		]/		1  cursor to N next end of a C comment
+|]D|		]D		   list all #defines found in current and
+				   included files matching the word under the
+				   cursor, start searching at cursor position
+|]I|		]I		   list all lines found in current and
+				   included files that contain the word under
+				   the cursor, start searching at cursor
+				   position
+|]P|		]P		2  same as "[p"
+|][|		][		1  cursor N SECTIONS forward
+|]]|		]]		1  cursor N sections forward
+|]c|		]c		1  cursor N times forward to start of change
+|]d|		]d		   show first #define found in current and
+				   included files matching the word under the
+				   cursor, start searching at cursor position
+|]f|		]f		   same as "gf"
+|]i|		]i		   show first line found in current and
+				   included files that contains the word under
+				   the cursor, start searching at cursor
+				   position
+|]m|		]m		1  cursor N times forward to end of member
+				   function
+|]p|		]p		2  like "p", but adjust indent to current line
+|]s|		]s		1  move to next misspelled word
+|]z|		]z		1  move to end of open fold
+|]}|		]}		1  cursor N times forward to unmatched '}'
+|]<MiddleMouse> ]<MiddleMouse>	2  same as "]p"
+
+==============================================================================
+2.4 Commands starting with 'g'						*g*
+
+tag		char	      note action in Normal mode	~
+------------------------------------------------------------------------------
+|g_CTRL-A|	g CTRL-A	   only when compiled with MEM_PROFILE
+				   defined: dump a memory profile
+|g_CTRL-G|	g CTRL-G	   show information about current cursor
+				   position
+|g_CTRL-H|	g CTRL-H	   start Select block mode
+|g_CTRL-]|	g CTRL-]	   |:tjump| to the tag under the cursor
+|g#|		g#		1  like "#", but without using "\<" and "\>"
+|g$|		g$		1  when 'wrap' off go to rightmost character of
+				   the current line that is on the screen;
+				   when 'wrap' on go to the rightmost character
+				   of the current screen line
+|g&|		g&		2  repeat last ":s" on all lines
+|g'|		g'{mark}	1  like |'| but without changing the jumplist
+|g`|		g`{mark}	1  like |`| but without changing the jumplist
+|gstar|		g*		1  like "*", but without using "\<" and "\>"
+|g0|		g0		1  when 'wrap' off go to leftmost character of
+				   the current line that is on the screen;
+				   when 'wrap' on go to the leftmost character
+				   of the current screen line
+|g8|		g8		   print hex value of bytes used in UTF-8
+				   character under the cursor
+|g<|		g<		   display previous command output
+|g?|		g?		2  Rot13 encoding operator
+|g?g?|		g??		2  Rot13 encode current line
+|g?g?|		g?g?		2  Rot13 encode current line
+|gD|		gD		1  go to definition of word under the cursor
+				   in current file
+|gE|		gE		1  go backwards to the end of the previous
+				   WORD
+|gH|		gH		   start Select line mode
+|gI|		gI		2  like "I", but always start in column 1
+|gJ|		gJ		2  join lines without inserting space
+|gP|		["x]gP		2  put the text [from register x] before the
+				   cursor N times, leave the cursor after it
+|gR|		gR		2  enter Virtual Replace mode
+|gU|		gU{motion}	2  make Nmove text uppercase
+|gV|		gV		   don't reselect the previous Visual area
+				   when executing a mapping or menu in Select
+				   mode
+|g]|		g]		   :tselect on the tag under the cursor
+|g^|		g^		1  when 'wrap' off go to leftmost non-white
+				   character of the current line that is on
+				   the screen; when 'wrap' on go to the
+				   leftmost non-white character of the current
+				   screen line
+|ga|		ga		   print ascii value of character under the
+				   cursor
+|gd|		gd		1  go to definition of word under the cursor
+				   in current function
+|ge|		ge		1  go backwards to the end of the previous
+				   word
+|gf|		gf		   start editing the file whose name is under
+				   the cursor
+|gF|		gF		   start editing the file whose name is under
+				   the cursor and jump to the line number
+				   following the filename.
+|gg|		gg		1  cursor to line N, default first line
+|gh|		gh		   start Select mode
+|gi|		gi		2  like "i", but first move to the |'^| mark
+|gj|		gj		1  like "j", but when 'wrap' on go N screen
+				   lines down
+|gk|		gk		1  like "k", but when 'wrap' on go N screen
+				   lines up
+|gm|		gm		1  go to character at middle of the screenline
+|go|		go		1  cursor to byte N in the buffer
+|gp|		["x]gp		2  put the text [from register x] after the
+				   cursor N times, leave the cursor after it
+|gq|		gq{motion}	2  format Nmove text
+|gr|		gr{char}	2  virtual replace N chars with {char}
+|gs|		gs		   go to sleep for N seconds (default 1)
+|gu|		gu{motion}	2  make Nmove text lowercase
+|gv|		gv		   reselect the previous Visual area
+|gw|		gw{motion}	2  format Nmove text and keep cursor
+|netrw-gx|	gx		   execute application for file name under the
+				   cursor (only with |netrw| plugin)
+|g@|		g@{motion}	   call 'operatorfunc'
+|g~|		g~{motion}	2  swap case for Nmove text
+|g<Down>|	g<Down>		1  same as "gj"
+|g<End>|	g<End>		1  same as "g$"
+|g<Home>|	g<Home>		1  same as "g0"
+|g<LeftMouse>|	g<LeftMouse>	   same as <C-LeftMouse>
+		g<MiddleMouse>	   same as <C-MiddleMouse>
+|g<RightMouse>|	g<RightMouse>	   same as <C-RightMouse>
+|g<Up>|		g<Up>		1  same as "gk"
+
+==============================================================================
+2.5 Commands starting with 'z'						*z*
+
+tag		char	      note action in Normal mode	~
+------------------------------------------------------------------------------
+|z<CR>|		z<CR>		   redraw, cursor line to top of window,
+				   cursor on first non-blank
+|zN<CR>|	z{height}<CR>	   redraw, make window {height} lines high
+|z+|		z+		   cursor on line N (default line below
+				   window), otherwise like "z<CR>"
+|z-|		z-		   redraw, cursor line at bottom of window,
+				   cursor on first non-blank
+|z.|		z.		   redraw, cursor line to center of window,
+				   cursor on first non-blank
+|z=|		z=		   give spelling suggestions
+|zA|		zA		   open a closed fold or close an open fold
+				   recursively
+|zC|		zC		   close folds recursively
+|zD|		zD		   delete folds recursively
+|zE|		zE		   eliminate all folds
+|zF|		zF		   create a fold for N lines
+|zG|		zG		   mark word as good spelled word
+|zM|		zM		   set 'foldlevel' to zero
+|zN|		zN		   set 'foldenable'
+|zO|		zO		   open folds recursively
+|zR|		zR		   set 'foldlevel' to the deepest fold
+|zW|		zW		   mark word as wrong (bad) spelled word
+|zX|		zX		   re-apply 'foldlevel'
+|z^|		z^		   cursor on line N (default line above
+				   window), otherwise like "z-"
+|za|		za		   open a closed fold, close an open fold
+|zb|		zb		   redraw, cursor line at bottom of window
+|zc|		zc		   close a fold
+|zd|		zd		   delete a fold
+|ze|		ze		   when 'wrap' off scroll horizontally to
+				   position the cursor at the end (right side)
+				   of the screen
+|zf|		zf{motion}	   create a fold for Nmove text
+|zg|		zg		   mark word as good spelled word
+|zh|		zh		   when 'wrap' off scroll screen N characters
+				   to the right
+|zi|		zi		   toggle 'foldenable'
+|zj|		zj		1  move to the start of the next fold
+|zk|		zk		1  move to the end of the previous fold
+|zl|		zl		   when 'wrap' off scroll screen N characters
+				   to the left
+|zm|		zm		   subtract one from 'foldlevel'
+|zn|		zn		   reset 'foldenable'
+|zo|		zo		   open fold
+|zr|		zr		   add one to 'foldlevel'
+|zs|		zs		   when 'wrap' off scroll horizontally to
+				   position the cursor at the start (left
+				   side) of the screen
+|zt|		zt		   redraw, cursor line at top of window
+|zv|		zv		   open enough folds to view the cursor line
+|zw|		zw		   mark word as wrong (bad) spelled word
+|zx|		zx		   re-apply 'foldlevel' and do "zv"
+|zz|		zz		   redraw, cursor line at center of window
+|z<Left>|	z<Left>		   same as "zh"
+|z<Right>|	z<Right>	   same as "zl"
+
+==============================================================================
+3. Visual mode						*visual-index*
+
+Most commands in Visual mode are the same as in Normal mode.  The ones listed
+here are those that are different.
+
+tag		command	      note action in Visual mode	~
+------------------------------------------------------------------------------
+|v_CTRL-\_CTRL-N| CTRL-\ CTRL-N	   stop Visual mode
+|v_CTRL-\_CTRL-G| CTRL-\ CTRL-G	   go to mode specified with 'insertmode'
+|v_CTRL-C|	CTRL-C		   stop Visual mode
+|v_CTRL-G|	CTRL-G		   toggle between Visual mode and Select mode
+|v_<BS>|	<BS>		2  Select mode: delete highlighted area
+|v_CTRL-H|	CTRL-H		2  same as <BS>
+|v_CTRL-O|	CTRL-O		   switch from Select to Visual mode for one
+				   command
+|v_CTRL-V|	CTRL-V		   make Visual mode blockwise or stop Visual
+				   mode
+|v_<Esc>|	<Esc>		   stop Visual mode
+|v_CTRL-]|	CTRL-]		   jump to highlighted tag
+|v_!|		!{filter}	2  filter the highlighted lines through the
+				   external command {filter}
+|v_:|		:		   start a command-line with the highlighted
+				   lines as a range
+|v_<|		<		2  shift the highlighted lines one
+				   'shiftwidth' left
+|v_=|		=		2  filter the highlighted lines through the
+				   external program given with the 'equalprg'
+				   option
+|v_>|		>		2  shift the highlighted lines one
+				   'shiftwidth' right
+|v_b_A|		A		2  block mode: append same text in all lines,
+				   after the highlighted area
+|v_C|		C		2  delete the highlighted lines and start
+				   insert
+|v_D|		D		2  delete the highlighted lines
+|v_b_I|		I		2  block mode: insert same text in all lines,
+				   before the highlighted area
+|v_J|		J		2  join the highlighted lines
+|v_K|		K		   run 'keywordprg' on the highlighted area
+|v_O|		O		   Move horizontally to other corner of area.
+		Q		   does not start Ex mode
+|v_R|		R		2  delete the highlighted lines and start
+				   insert
+|v_S|		S		2  delete the highlighted lines and start
+				   insert
+|v_U|		U		2  make highlighted area uppercase
+|v_V|		V		   make Visual mode linewise or stop Visual
+				   mode
+|v_X|		X		2  delete the highlighted lines
+|v_Y|		Y		   yank the highlighted lines
+|v_a(|		a(		   same as ab
+|v_a)|		a)		   same as ab
+|v_a<|		a<		   extend highlighted area with a <> block
+|v_a>|		a>		   same as a<
+|v_aB|		aB		   extend highlighted area with a {} block
+|v_aW|		aW		   extend highlighted area with "a WORD"
+|v_a[|		a[		   extend highlighted area with a [] block
+|v_a]|		a]		   same as a[
+|v_ab|		ab		   extend highlighted area with a () block
+|v_ap|		ap		   extend highlighted area with a paragraph
+|v_as|		as		   extend highlighted area with a sentence
+|v_aw|		aw		   extend highlighted area with "a word"
+|v_a{|		a{		   same as aB
+|v_a}|		a}		   same as aB
+|v_c|		c		2  delete highlighted area and start insert
+|v_d|		d		2  delete highlighted area
+|v_gJ|		gJ		2  join the highlighted lines without
+				   inserting spaces
+|v_gq|		gq		2  format the highlighted lines
+|v_gv|		gv		   exchange current and previous highlighted
+				   area
+|v_i(|		i(		   same as ib
+|v_i)|		i)		   same as ib
+|v_i<|		i<		   extend highlighted area with inner <> block
+|v_i>|		i>		   same as i<
+|v_iB|		iB		   extend highlighted area with inner {} block
+|v_iW|		iW		   extend highlighted area with "inner WORD"
+|v_i[|		i[		   extend highlighted area with inner [] block
+|v_i]|		i]		   same as i[
+|v_ib|		ib		   extend highlighted area with inner () block
+|v_ip|		ip		   extend highlighted area with inner paragraph
+|v_is|		is		   extend highlighted area with inner sentence
+|v_iw|		iw		   extend highlighted area with "inner word"
+|v_i{|		i{		   same as iB
+|v_i}|		i}		   same as iB
+|v_o|		o		   move cursor to other corner of area
+|v_r|		r		2  delete highlighted area and start insert
+|v_s|		s		2  delete highlighted area and start insert
+|v_u|		u		2  make highlighted area lowercase
+|v_v|		v		   make Visual mode characterwise or stop
+				   Visual mode
+|v_x|		x		2  delete the highlighted area
+|v_y|		y		   yank the highlighted area
+|v_~|		~		2  swap case for the highlighted area
+
+==============================================================================
+4. Command-line editing					*ex-edit-index*
+
+Get to the command-line with the ':', '!', '/' or '?' commands.
+Normal characters are inserted at the current cursor position.
+"Completion" below refers to context-sensitive completion.  It will complete
+file names, tags, commands etc. as appropriate.
+
+		CTRL-@		not used
+|c_CTRL-A|	CTRL-A		do completion on the pattern in front of the
+				cursor and insert all matches
+|c_CTRL-B|	CTRL-B		cursor to begin of command-line
+|c_CTRL-C|	CTRL-C		same as <ESC>
+|c_CTRL-D|	CTRL-D		list completions that match the pattern in
+				front of the cursor
+|c_CTRL-E|	CTRL-E		cursor to end of command-line
+|'cedit'|	CTRL-F		default value for 'cedit': opens the
+				command-line window; otherwise not used
+		CTRL-G		not used
+|c_<BS>|	<BS>		delete the character in front of the cursor
+|c_digraph|	{char1} <BS> {char2}
+				enter digraph when 'digraph' is on
+|c_CTRL-H|	CTRL-H		same as <BS>
+|c_<Tab>|	<Tab>		if 'wildchar' is <Tab>: Do completion on
+				the pattern in front of the cursor
+|c_<S-Tab>|	<S-Tab>		same as CTRL-P
+|c_wildchar|	'wildchar'	Do completion on the pattern in front of the
+				cursor (default: <Tab>)
+|c_CTRL-I|	CTRL-I		same as <Tab>
+|c_<NL>|	<NL>		same as <CR>
+|c_CTRL-J|	CTRL-J		same as <CR>
+|c_CTRL-K|	CTRL-K {char1} {char2}
+				enter digraph
+|c_CTRL-L|	CTRL-L		do completion on the pattern in front of the
+				cursor and insert the longest common part
+|c_<CR>|	<CR>		execute entered command
+|c_<CR>|	CTRL-M		same as <CR>
+|c_CTRL-N|	CTRL-N		after using 'wildchar' with multiple matches:
+				go to next match, otherwise: same as <Down>
+		CTRL-O		not used
+|c_CTRL-P|	CTRL-P		after using 'wildchar' with multiple matches:
+				go to previous match, otherwise: same as <Up>
+|c_CTRL-Q|	CTRL-Q		same as CTRL-V, unless it's used for terminal
+				control flow
+|c_CTRL-R|	CTRL-R {0-9a-z"%#*:= CTRL-F CTRL-P CTRL-W CTRL-A}
+				insert the contents of a register or object
+				under the cursor as if typed
+|c_CTRL-R_CTRL-R| CTRL-R CTRL-R {0-9a-z"%#*:= CTRL-F CTRL-P CTRL-W CTRL-A}
+				insert the contents of a register or object
+				under the cursor literally
+		CTRL-S		(used for terminal control flow)
+		CTRL-T		not used
+|c_CTRL-U|	CTRL-U		remove all characters
+|c_CTRL-V|	CTRL-V		insert next non-digit literally, insert three
+				digit decimal number as a single byte.
+|c_CTRL-W|	CTRL-W		delete the word in front of the cursor
+		CTRL-X		not used (reserved for completion)
+		CTRL-Y		copy (yank) modeless selection
+		CTRL-Z		not used (reserved for suspend)
+|c_<Esc>|	<Esc>		abandon command-line without executing it
+|c_<Esc>|	CTRL-[		same as <Esc>
+|c_CTRL-\_CTRL-N| CTRL-\ CTRL-N	 go to Normal mode, abandon command-line
+|c_CTRL-\_CTRL-G| CTRL-\ CTRL-G	 go to mode specified with 'insertmode',
+				abandon command-line
+		CTRL-\ a - d	reserved for extensions
+|c_CTRL-\_e|	CTRL-\ e {expr} replace the command line with the result of
+				{expr}
+		CTRL-\ f - z	reserved for extensions
+		CTRL-\ others	not used
+|c_CTRL-]|	CTRL-]		trigger abbreviation
+|c_CTRL-^|	CTRL-^		toggle use of |:lmap| mappings
+|c_CTRL-_|	CTRL-_		when 'allowrevins' set: change language
+				(Hebrew, Farsi)
+|c_<Del>|	<Del>		delete the character under the cursor
+
+|c_<Left>|	<Left>		cursor left
+|c_<S-Left>|	<S-Left>	cursor one word left
+|c_<C-Left>|	<C-Left>	cursor one word left
+|c_<Right>|	<Right>		cursor right
+|c_<S-Right>|	<S-Right>	cursor one word right
+|c_<C-Right>|	<C-Right>	cursor one word right
+|c_<Up>|	<Up>		recall previous command-line from history that
+				matches pattern in front of the cursor
+|c_<S-Up>|	<S-Up>		recall previous command-line from history
+|c_<Down>|	<Down>		recall next command-line from history that
+				matches pattern in front of the cursor
+|c_<S-Down>|	<S-Down>	recall next command-line from history
+|c_<Home>|	<Home>		cursor to start of command-line
+|c_<End>|	<End>		cursor to end of command-line
+|c_<PageDown>|	<PageDown>	same as <S-Down>
+|c_<PageUp>|	<PageUp>	same as <S-Up>
+|c_<Insert>|	<Insert>	toggle insert/overstrike mode
+|c_<LeftMouse>|	<LeftMouse>	cursor at mouse click
+
+You found it, Arthur!				*holy-grail*
+
+==============================================================================
+5. EX commands					*ex-cmd-index* *:index*
+
+This is a brief but complete listing of all the ":" commands, without
+mentioning any arguments.  The optional part of the command name is inside [].
+The commands are sorted on the non-optional part of their name.
+
+|:!|		:!		filter lines or execute an external command
+|:!!|		:!!		repeat last ":!" command
+|:#|		:#		same as ":number"
+|:&|		:&		repeat last ":substitute"
+|:star|		:*		execute contents of a register
+|:<|		:<		shift lines one 'shiftwidth' left
+|:=|		:=		print the cursor line number
+|:>|		:>		shift lines one 'shiftwidth' right
+|:@|		:@		execute contents of a register
+|:@@|		:@@		repeat the previous ":@"
+|:Next|		:N[ext]		go to previous file in the argument list
+|:Print|	:P[rint]	print lines
+|:X|		:X		ask for encryption key
+|:append|	:a[ppend]	append text
+|:abbreviate|	:ab[breviate]	enter abbreviation
+|:abclear|	:abc[lear]	remove all abbreviations
+|:aboveleft|	:abo[veleft]	make split window appear left or above
+|:all|		:al[l]		open a window for each file in the argument
+				list
+|:amenu|	:am[enu]	enter new menu item for all modes
+|:anoremenu|	:an[oremenu]	enter a new menu for all modes that will not
+				be remapped
+|:args|		:ar[gs]		print the argument list
+|:argadd|	:arga[dd]	add items to the argument list
+|:argdelete|	:argd[elete]	delete items from the argument list
+|:argedit|	:arge[dit]	add item to the argument list and edit it
+|:argdo|	:argdo		do a command on all items in the argument list
+|:argglobal|	:argg[lobal]	define the global argument list
+|:arglocal|	:argl[ocal]	define a local argument list
+|:argument|	:argu[ment]	go to specific file in the argument list
+|:ascii|	:as[cii]	print ascii value of character under the cursor
+|:autocmd|	:au[tocmd]	enter or show autocommands
+|:augroup|	:aug[roup]	select the autocommand group to use
+|:aunmenu|	:aun[menu]	remove menu for all modes
+|:buffer|	:b[uffer]	go to specific buffer in the buffer list
+|:bNext|	:bN[ext]	go to previous buffer in the buffer list
+|:ball|		:ba[ll]		open a window for each buffer in the buffer list
+|:badd|		:bad[d]		add buffer to the buffer list
+|:bdelete|	:bd[elete]	remove a buffer from the buffer list
+|:behave|	:be[have]	set mouse and selection behavior
+|:belowright|	:bel[owright]	make split window appear right or below
+|:bfirst|	:bf[irst]	go to first buffer in the buffer list
+|:blast|	:bl[ast]	go to last buffer in the buffer list
+|:bmodified|	:bm[odified]	go to next buffer in the buffer list that has
+				been modified
+|:bnext|	:bn[ext]	go to next buffer in the buffer list
+|:botright|	:bo[tright]	make split window appear at bottom or far right
+|:bprevious|	:bp[revious]	go to previous buffer in the buffer list
+|:brewind|	:br[ewind]	go to first buffer in the buffer list
+|:break|	:brea[k]	break out of while loop
+|:breakadd|	:breaka[dd]	add a debugger breakpoint
+|:breakdel|	:breakd[el]	delete a debugger breakpoint
+|:breaklist|	:breakl[ist]	list debugger breakpoints
+|:browse|	:bro[wse]	use file selection dialog
+|:bufdo|	:bufdo		execute command in each listed buffer
+|:buffers|	:buffers	list all files in the buffer list
+|:bunload|	:bun[load]	unload a specific buffer
+|:bwipeout|	:bw[ipeout]	really delete a buffer
+|:change|	:c[hange]	replace a line or series of lines
+|:cNext|	:cN[ext]	go to previous error
+|:cNfile|	:cNf[ile]	go to last error in previous file
+|:cabbrev|	:ca[bbrev]	like ":abbreviate" but for Command-line mode
+|:cabclear|	:cabc[lear]	clear all abbreviations for Command-line mode
+|:caddbuffer|	:caddb[uffer]	add errors from buffer
+|:caddexpr|	:cad[dexpr]	add errors from expr
+|:caddfile|	:caddf[ile]	add error message to current quickfix list
+|:call|		:cal[l]		call a function
+|:catch|	:cat[ch]	part of a :try command
+|:cbuffer|	:cb[uffer]	parse error messages and jump to first error
+|:cc|		:cc		go to specific error
+|:cclose|	:ccl[ose]	close quickfix window
+|:cd|		:cd		change directory
+|:center|	:ce[nter]	format lines at the center
+|:cexpr|	:cex[pr]	read errors from expr and jump to first
+|:cfile|	:cf[ile]	read file with error messages and jump to first
+|:cfirst|	:cfir[st]	go to the specified error, default first one
+|:cgetbuffer|	:cgetb[uffer]	get errors from buffer
+|:cgetexpr|	:cgete[xpr]	get errors from expr
+|:cgetfile|	:cg[etfile]	read file with error messages
+|:changes|	:cha[nges]	print the change list
+|:chdir|	:chd[ir]	change directory
+|:checkpath|	:che[ckpath]	list included files
+|:checktime|	:checkt[ime]	check timestamp of loaded buffers
+|:clist|	:cl[ist]	list all errors
+|:clast|	:cla[st]	go to the specified error, default last one
+|:close|	:clo[se]	close current window
+|:cmap|		:cm[ap]		like ":map" but for Command-line mode
+|:cmapclear|	:cmapc[lear]	clear all mappings for Command-line mode
+|:cmenu|	:cme[nu]	add menu for Command-line mode
+|:cnext|	:cn[ext]	go to next error
+|:cnewer|	:cnew[er]	go to newer error list
+|:cnfile|	:cnf[ile]	go to first error in next file
+|:cnoremap|	:cno[remap]	like ":noremap" but for Command-line mode
+|:cnoreabbrev|	:cnorea[bbrev]	like ":noreabbrev" but for Command-line mode
+|:cnoremenu|	:cnoreme[nu]	like ":noremenu" but for Command-line mode
+|:copy|		:co[py]		copy lines
+|:colder|	:col[der]	go to older error list
+|:colorscheme|	:colo[rscheme]	load a specific color scheme
+|:command|	:com[mand]	create user-defined command
+|:comclear|	:comc[lear]	clear all user-defined commands
+|:compiler|	:comp[iler]	do settings for a specific compiler
+|:continue|	:con[tinue]	go back to :while
+|:confirm|	:conf[irm]	prompt user when confirmation required
+|:copen|	:cope[n]	open quickfix window
+|:cprevious|	:cp[revious]	go to previous error
+|:cpfile|	:cpf[ile]	go to last error in previous file
+|:cquit|	:cq[uit]	quit Vim with an error code
+|:crewind|	:cr[ewind]	go to the specified error, default first one
+|:cscope|	:cs[cope]       execute cscope command
+|:cstag|	:cst[ag]	use cscope to jump to a tag
+|:cunmap|	:cu[nmap]	like ":unmap" but for Command-line mode
+|:cunabbrev|	:cuna[bbrev]	like ":unabbrev" but for Command-line mode
+|:cunmenu|	:cunme[nu]	remove menu for Command-line mode
+|:cwindow|	:cw[indow]	open or close quickfix window
+|:delete|	:d[elete]	delete lines
+|:delmarks|	:delm[arks]	delete marks
+|:debug|	:deb[ug]	run a command in debugging mode
+|:debuggreedy|	:debugg[reedy]	read debug mode commands from normal input
+|:delcommand|	:delc[ommand]	delete user-defined command
+|:delfunction|	:delf[unction]	delete a user function
+|:diffupdate|	:dif[fupdate]	update 'diff' buffers
+|:diffget|	:diffg[et]	remove differences in current buffer
+|:diffoff|	:diffo[ff]	switch off diff mode
+|:diffpatch|	:diffp[atch]	apply a patch and show differences
+|:diffput|	:diffpu[t]	remove differences in other buffer
+|:diffsplit|	:diffs[plit]	show differences with another file
+|:diffthis|	:diffthis	make current window a diff window
+|:digraphs|	:dig[raphs]	show or enter digraphs
+|:display|	:di[splay]	display registers
+|:djump|	:dj[ump]	jump to #define
+|:dlist|	:dl[ist]	list #defines
+|:doautocmd|	:do[autocmd]	apply autocommands to current buffer
+|:doautoall|	:doautoa[ll]	apply autocommands for all loaded buffers
+|:drop|		:dr[op]		jump to window editing file or edit file in
+				current window
+|:dsearch|	:ds[earch]	list one #define
+|:dsplit|	:dsp[lit]	split window and jump to #define
+|:edit|		:e[dit]		edit a file
+|:earlier|	:ea[rlier]	go to older change, undo
+|:echo|		:ec[ho]		echoes the result of expressions
+|:echoerr|	:echoe[rr]	like :echo, show like an error and use history
+|:echohl|	:echoh[l]	set highlighting for echo commands
+|:echomsg|	:echom[sg]	same as :echo, put message in history
+|:echon|	:echon		same as :echo, but without <EOL>
+|:else|		:el[se]		part of an :if command
+|:elseif|	:elsei[f]	part of an :if command
+|:emenu|	:em[enu]	execute a menu by name
+|:endif|	:en[dif]	end previous :if
+|:endfor|	:endfo[r]	end previous :for
+|:endfunction|	:endf[unction]	end of a user function
+|:endtry|	:endt[ry]	end previous :try
+|:endwhile|	:endw[hile]	end previous :while
+|:enew|		:ene[w]		edit a new, unnamed buffer
+|:ex|		:ex		same as ":edit"
+|:execute|	:exe[cute]	execute result of expressions
+|:exit|		:exi[t]		same as ":xit"
+|:exusage|	:exu[sage]	overview of Ex commands
+|:file|		:f[ile]		show or set the current file name
+|:files|	:files		list all files in the buffer list
+|:filetype|	:filet[ype]	switch file type detection on/off
+|:find|		:fin[d]		find file in 'path' and edit it
+|:finally|	:fina[lly]	part of a :try command
+|:finish|	:fini[sh]	quit sourcing a Vim script
+|:first|	:fir[st]	go to the first file in the argument list
+|:fixdel|	:fix[del]	set key code of <Del>
+|:fold|		:fo[ld]		create a fold
+|:foldclose|	:foldc[lose]	close folds
+|:folddoopen|	:foldd[oopen]	execute command on lines not in a closed fold
+|:folddoclosed|	:folddoc[losed]	execute command on lines in a closed fold
+|:foldopen|	:foldo[pen]	open folds
+|:for|		:for		for loop
+|:function|	:fu[nction]	define a user function
+|:global|	:g[lobal]	execute commands for matching lines
+|:goto|		:go[to]		go to byte in the buffer
+|:grep|		:gr[ep]		run 'grepprg' and jump to first match
+|:grepadd|	:grepa[dd]	like :grep, but append to current list
+|:gui|		:gu[i]		start the GUI
+|:gvim|		:gv[im]		start the GUI
+|:hardcopy|	:ha[rdcopy]	send text to the printer
+|:help|		:h[elp]		open a help window
+|:helpfind|	:helpf[ind]	dialog to open a help window
+|:helpgrep|	:helpg[rep]	like ":grep" but searches help files
+|:helptags|	:helpt[ags]	generate help tags for a directory
+|:highlight|	:hi[ghlight]	specify highlighting methods
+|:hide|		:hid[e]		hide current buffer for a command
+|:history|	:his[tory]	print a history list
+|:insert|	:i[nsert]	insert text
+|:iabbrev|	:ia[bbrev]	like ":abbrev" but for Insert mode
+|:iabclear|	:iabc[lear]	like ":abclear" but for Insert mode
+|:if|		:if		execute commands when condition met
+|:ijump|	:ij[ump]	jump to definition of identifier
+|:ilist|	:il[ist]	list lines where identifier matches
+|:imap|		:im[ap]		like ":map" but for Insert mode
+|:imapclear|	:imapc[lear]	like ":mapclear" but for Insert mode
+|:imenu|	:ime[nu]	add menu for Insert mode
+|:inoremap|	:ino[remap]	like ":noremap" but for Insert mode
+|:inoreabbrev|	:inorea[bbrev]	like ":noreabbrev" but for Insert mode
+|:inoremenu|	:inoreme[nu]	like ":noremenu" but for Insert mode
+|:intro|	:int[ro]	print the introductory message
+|:isearch|	:is[earch]	list one line where identifier matches
+|:isplit|	:isp[lit]	split window and jump to definition of
+				identifier
+|:iunmap|	:iu[nmap]	like ":unmap" but for Insert mode
+|:iunabbrev|	:iuna[bbrev]	like ":unabbrev" but for Insert mode
+|:iunmenu|	:iunme[nu]	remove menu for Insert mode
+|:join|		:j[oin]		join lines
+|:jumps|	:ju[mps]	print the jump list
+|:k|		:k		set a mark
+|:keepalt|	:keepa[lt]	following command keeps the alternate file
+|:keepmarks|	:kee[pmarks]	following command keeps marks where they are
+|:keepjumps|	:keepj[jumps]	following command keeps jumplist and marks
+|:lNext|	:lN[ext]	go to previous entry in location list
+|:lNfile|	:lNf[ile]	go to last entry in previous file
+|:list|		:l[ist]		print lines
+|:laddexpr|	:lad[dexpr]	add locations from expr
+|:laddbuffer|	:laddb[uffer]	add locations from buffer
+|:laddfile|	:laddf[ile]	add locations to current location list
+|:last|		:la[st]		go to the last file in the argument list
+|:language|	:lan[guage]	set the language (locale)
+|:later|	:lat[er]	go to newer change, redo
+|:lbuffer|	:lb[uffer]	parse locations and jump to first location
+|:lcd|		:lc[d]		change directory locally
+|:lchdir|	:lch[dir]	change directory locally
+|:lclose|	:lcl[ose]	close location window
+|:lcscope|	:lcs[cope]      like ":cscope" but uses location list
+|:left|		:le[ft]		left align lines
+|:leftabove|	:lefta[bove]	make split window appear left or above
+|:let|		:let		assign a value to a variable or option
+|:lexpr|	:lex[pr]	read locations from expr and jump to first
+|:lfile|	:lf[ile]	read file with locations and jump to first
+|:lfirst|	:lfir[st]	go to the specified location, default first one
+|:lgetbuffer|	:lgetb[uffer]	get locations from buffer
+|:lgetexpr|	:lgete[xpr]	get locations from expr
+|:lgetfile|	:lg[etfile]	read file with locations
+|:lgrep|	:lgr[ep]	run 'grepprg' and jump to first match
+|:lgrepadd|	:lgrepa[dd]	like :grep, but append to current list
+|:lhelpgrep|	:lh[elpgrep]	like ":helpgrep" but uses location list
+|:ll|		:ll		go to specific location
+|:llast|	:lla[st]	go to the specified location, default last one
+|:llist|	:lli[st]	list all locations
+|:lmake|	:lmak[e]	execute external command 'makeprg' and parse
+				error messages
+|:lmap|		:lm[ap]		like ":map!" but includes Lang-Arg mode
+|:lmapclear|	:lmapc[lear]	like ":mapclear!" but includes Lang-Arg mode
+|:lnext|	:lne[xt]	go to next location
+|:lnewer|	:lnew[er]	go to newer location list
+|:lnfile|	:lnf[ile]	go to first location in next file
+|:lnoremap|	:ln[oremap]	like ":noremap!" but includes Lang-Arg mode
+|:loadkeymap|	:loadk[eymap]	load the following keymaps until EOF
+|:loadview|	:lo[adview]	load view for current window from a file
+|:lockmarks|	:loc[kmarks]	following command keeps marks where they are
+|:lockvar|	:lockv[ar]	lock variables
+|:lolder|	:lol[der]	go to older location list
+|:lopen|	:lope[n]	open location window
+|:lprevious|	:lp[revious]	go to previous location
+|:lpfile|	:lpf[ile]	go to last location in previous file
+|:lrewind|	:lr[ewind]	go to the specified location, default first one
+|:ls|		:ls		list all buffers
+|:ltag|		:lt[ag]		jump to tag and add matching tags to the
+				location list
+|:lunmap|	:lu[nmap]	like ":unmap!" but includes Lang-Arg mode
+|:lvimgrep|	:lv[imgrep]	search for pattern in files
+|:lvimgrepadd|	:lvimgrepa[dd]	like :vimgrep, but append to current list
+|:lwindow|	:lw[indow]	open or close location window
+|:move|		:m[ove]		move lines
+|:mark|		:ma[rk]		set a mark
+|:make|		:mak[e]		execute external command 'makeprg' and parse
+				error messages
+|:map|		:map		show or enter a mapping
+|:mapclear|	:mapc[lear]	clear all mappings for Normal and Visual mode
+|:marks|	:marks		list all marks
+|:match|	:mat[ch]	define a match to highlight
+|:menu|		:me[nu]		enter a new menu item
+|:menutranslate| :menut[ranslate] add a menu translation item
+|:messages|	:mes[sages]	view previously displayed messages
+|:mkexrc|	:mk[exrc]	write current mappings and settings to a file
+|:mksession|	:mks[ession]	write session info to a file
+|:mkspell|	:mksp[ell]	produce .spl spell file
+|:mkvimrc|	:mkv[imrc]	write current mappings and settings to a file
+|:mkview|	:mkvie[w]	write view of current window to a file
+|:mode|		:mod[e]		show or change the screen mode
+|:mzscheme|	:mz[scheme]	execute MzScheme command
+|:mzfile|	:mzf[ile]	execute MzScheme script file
+|:nbkey|	:nb[key]	pass a key to Netbeans
+|:next|		:n[ext]		go to next file in the argument list
+|:new|		:new		create a new empty window
+|:nmap|		:nm[ap]		like ":map" but for Normal mode
+|:nmapclear|	:nmapc[lear]	clear all mappings for Normal mode
+|:nmenu|	:nme[nu]	add menu for Normal mode
+|:nnoremap|	:nn[oremap]	like ":noremap" but for Normal mode
+|:nnoremenu|	:nnoreme[nu]	like ":noremenu" but for Normal mode
+|:noautocmd|	:noa[utocmd]	following command don't trigger autocommands
+|:noremap|	:no[remap]	enter a mapping that will not be remapped
+|:nohlsearch|	:noh[lsearch]	suspend 'hlsearch' highlighting
+|:noreabbrev|	:norea[bbrev]	enter an abbreviation that will not be
+				remapped
+|:noremenu|	:noreme[nu]	enter a menu that will not be remapped
+|:normal|	:norm[al]	execute Normal mode commands
+|:number|	:nu[mber]	print lines with line number
+|:nunmap|	:nun[map]	like ":unmap" but for Normal mode
+|:nunmenu|	:nunme[nu]	remove menu for Normal mode
+|:open|		:o[pen]		start open mode (not implemented)
+|:omap|		:om[ap]		like ":map" but for Operator-pending mode
+|:omapclear|	:omapc[lear]	remove all mappings for Operator-pending mode
+|:omenu|	:ome[nu]	add menu for Operator-pending mode
+|:only|		:on[ly]		close all windows except the current one
+|:onoremap|	:ono[remap]	like ":noremap" but for Operator-pending mode
+|:onoremenu|	:onoreme[nu]	like ":noremenu" but for Operator-pending mode
+|:options|	:opt[ions]	open the options-window
+|:ounmap|	:ou[nmap]	like ":unmap" but for Operator-pending mode
+|:ounmenu|	:ounme[nu]	remove menu for Operator-pending mode
+|:pclose|	:pc[lose]	close preview window
+|:pedit|	:ped[it]	edit file in the preview window
+|:perl|		:pe[rl]		execute Perl command
+|:print|	:p[rint]	print lines
+|:profdel|	:profd[el]	stop profiling a function or script
+|:profile|	:prof[ile]	profiling functions and scripts
+|:promptfind|	:pro[mtfind]	open GUI dialog for searching
+|:promptrepl|	:promtr[epl]	open GUI dialog for search/replace
+|:perldo|	:perld[o]	execute Perl command for each line
+|:pop|		:po[p]		jump to older entry in tag stack
+|:popup|	:pop[up]	popup a menu by name
+|:ppop|		:pp[op]		":pop" in preview window
+|:preserve|	:pre[serve]	write all text to swap file
+|:previous|	:prev[ious]	go to previous file in argument list
+|:promptfind|	:pro[mptfind]	Search dialog
+|:promptrepl|	:promptr[epl]	Search/Replace dialog
+|:psearch|	:ps[earch]	like ":ijump" but shows match in preview window
+|:ptag|		:pt[ag]		show tag in preview window
+|:ptNext|	:ptN[ext]	|:tNext| in preview window
+|:ptfirst|	:ptf[irst]	|:trewind| in preview window
+|:ptjump|	:ptj[ump]	|:tjump| and show tag in preview window
+|:ptlast|	:ptl[ast]	|:tlast| in preview window
+|:ptnext|	:ptn[ext]	|:tnext| in preview window
+|:ptprevious|	:ptp[revious]	|:tprevious| in preview window
+|:ptrewind|	:ptr[ewind]	|:trewind| in preview window
+|:ptselect|	:pts[elect]	|:tselect| and show tag in preview window
+|:put|		:pu[t]		insert contents of register in the text
+|:pwd|		:pw[d]		print current directory
+|:python|	:py[thon]	execute Python command
+|:pyfile|	:pyf[ile]	execute Python script file
+|:quit|		:q[uit]		quit current window (when one window quit Vim)
+|:quitall|	:quita[ll]	quit Vim
+|:qall|		:qa[ll]		quit Vim
+|:read|		:r[ead]		read file into the text
+|:recover|	:rec[over]	recover a file from a swap file
+|:redo|		:red[o]		redo one undone change
+|:redir|	:redi[r]	redirect messages to a file or register
+|:redraw|	:redr[aw]	force a redraw of the display
+|:redrawstatus|	:redraws[tatus]	force a redraw of the status line(s)
+|:registers|	:reg[isters]	display the contents of registers
+|:resize|	:res[ize]	change current window height
+|:retab|	:ret[ab]	change tab size
+|:return|	:retu[rn]	return from a user function
+|:rewind|	:rew[ind]	go to the first file in the argument list
+|:right|	:ri[ght]	right align text
+|:rightbelow|	:rightb[elow]	make split window appear right or below
+|:ruby|		:rub[y]		execute Ruby command
+|:rubydo|	:rubyd[o]	execute Ruby command for each line
+|:rubyfile|	:rubyf[ile]	execute Ruby script file
+|:runtime|	:ru[ntime]	source vim scripts in 'runtimepath'
+|:rviminfo|	:rv[iminfo]	read from viminfo file
+|:substitute|	:s[ubstitute]	find and replace text
+|:sNext|	:sN[ext]	split window and go to previous file in
+				argument list
+|:sandbox|	:san[dbox]	execute a command in the sandbox
+|:sargument|	:sa[rgument]	split window and go to specific file in
+				argument list
+|:sall|		:sal[l]		open a window for each file in argument list
+|:saveas|	:sav[eas]	save file under another name.
+|:sbuffer|	:sb[uffer]	split window and go to specific file in the
+				buffer list
+|:sbNext|	:sbN[ext]	split window and go to previous file in the
+				buffer list
+|:sball|	:sba[ll]	open a window for each file in the buffer list
+|:sbfirst|	:sbf[irst]	split window and go to first file in the
+				buffer list
+|:sblast|	:sbl[ast]	split window and go to last file in buffer
+				list
+|:sbmodified|	:sbm[odified]	split window and go to modified file in the
+				buffer list
+|:sbnext|	:sbn[ext]	split window and go to next file in the buffer
+				list
+|:sbprevious|	:sbp[revious]	split window and go to previous file in the
+				buffer list
+|:sbrewind|	:sbr[ewind]	split window and go to first file in the
+				buffer list
+|:scriptnames|	:scrip[tnames]	list names of all sourced Vim scripts
+|:scriptencoding| :scripte[ncoding]	encoding used in sourced Vim script
+|:scscope|	:scs[cope]	split window and execute cscope command
+|:set|		:se[t]		show or set options
+|:setfiletype|	:setf[iletype]	set 'filetype', unless it was set already
+|:setglobal|	:setg[lobal]	show global values of options
+|:setlocal|	:setl[ocal]	show or set options locally
+|:sfind|	:sf[ind]	split current window and edit file in 'path'
+|:sfirst|	:sfir[st]	split window and go to first file in the
+				argument list
+|:shell|	:sh[ell]	escape to a shell
+|:simalt|	:sim[alt]	Win32 GUI: simulate Windows ALT key
+|:sign|		:sig[n]		manipulate signs
+|:silent|	:sil[ent]	Run a command silently
+|:sleep|	:sl[eep]	do nothing for a few seconds
+|:slast|	:sla[st]	split window and go to last file in the
+				argument list
+|:smagic|	:sm[agic]	:substitute with 'magic'
+|:smap|		:sma[p]		like ":map" but for Select mode
+|:smapclear|	:smapc[lear]	remove all mappings for Select mode
+|:smenu|	:sme[nu]	add menu for Select mode
+|:snext|	:sn[ext]	split window and go to next file in the
+				argument list
+|:sniff|	:sni[ff]	send request to sniff
+|:snomagic|	:sno[magic]	:substitute with 'nomagic'
+|:snoremap|	:snor[emap]	like ":noremap" but for Select mode
+|:snoremenu|	:snoreme[nu]	like ":noremenu" but for Select mode
+|:sort|		:sor[t]		sort lines
+|:source|	:so[urce]	read Vim or Ex commands from a file
+|:spelldump|	:spelld[ump]	split window and fill with all correct words
+|:spellgood|	:spe[llgood]	add good word for spelling
+|:spellinfo|	:spelli[nfo]	show info about loaded spell files
+|:spellrepall|	:spellr[epall]	replace all bad words like last |z=|
+|:spellundo|	:spellu[ndo]	remove good or bad word
+|:spellwrong|	:spellw[rong]	add spelling mistake
+|:split|	:sp[lit]	split current window
+|:sprevious|	:spr[evious]	split window and go to previous file in the
+				argument list
+|:srewind|	:sre[wind]	split window and go to first file in the
+				argument list
+|:stop|		:st[op]		suspend the editor or escape to a shell
+|:stag|		:sta[g]		split window and jump to a tag
+|:startinsert|	:star[tinsert]	start Insert mode
+|:startgreplace| :startg[replace] start Virtual Replace mode
+|:startreplace|	:startr[eplace]	start Replace mode
+|:stopinsert||	:stopi[nsert]	stop Insert mode
+|:stjump|	:stj[ump]	do ":tjump" and split window
+|:stselect|	:sts[elect]	do ":tselect" and split window
+|:sunhide|	:sun[hide]	same as ":unhide"
+|:sunmap|	:sunm[ap]	like ":unmap" but for Select mode
+|:sunmenu|	:sunme[nu]	remove menu for Select mode
+|:suspend|	:sus[pend]	same as ":stop"
+|:sview|	:sv[iew]	split window and edit file read-only
+|:swapname|	:sw[apname]	show the name of the current swap file
+|:syntax|	:sy[ntax]	syntax highlighting
+|:syncbind|	:sync[bind]	sync scroll binding
+|:t|		:t		same as ":copy"
+|:tNext|	:tN[ext]	jump to previous matching tag
+|:tabNext|	:tabN[ext]	go to previous tab page
+|:tabclose|	:tabc[lose]	close current tab page
+|:tabdo|	:tabdo		execute command in each tab page
+|:tabedit|	:tabe[dit]	edit a file in a new tab page
+|:tabfind|	:tabf[ind]	find file in 'path', edit it in a new tab page
+|:tabfirst|	:tabfir[st]	got to first tab page
+|:tablast|	:tabl[ast]	got to last tab page
+|:tabmove|	:tabm[ove]	move tab page to other position
+|:tabnew|	:tabnew		edit a file in a new tab page
+|:tabnext|	:tabn[ext]	go to next tab page
+|:tabonly|	:tabo[nly]	close all tab pages except the current one
+|:tabprevious|	:tabp[revious]	go to previous tab page
+|:tabrewind|	:tabr[ewind]	got to first tab page
+|:tabs|		:tabs		list the tab pages and what they contain
+|:tab|		:tab		create new tab when opening new window
+|:tag|		:ta[g]		jump to tag
+|:tags|		:tags		show the contents of the tag stack
+|:tcl|		:tc[l]		execute Tcl command
+|:tcldo|	:tcld[o]	execute Tcl command for each line
+|:tclfile|	:tclf[ile]	execute Tcl script file
+|:tearoff|	:te[aroff]	tear-off a menu
+|:tfirst|	:tf[irst]	jump to first matching tag
+|:throw|	:th[row]	throw an exception
+|:tjump|	:tj[ump]	like ":tselect", but jump directly when there
+				is only one match
+|:tlast|	:tl[ast]	jump to last matching tag
+|:tmenu|	:tm[enu]	define menu tooltip
+|:tnext|	:tn[ext]	jump to next matching tag
+|:topleft|	:to[pleft]	make split window appear at top or far left
+|:tprevious|	:tp[revious]	jump to previous matching tag
+|:trewind|	:tr[ewind]	jump to first matching tag
+|:try|		:try		execute commands, abort on error or exception
+|:tselect|	:ts[elect]	list matching tags and select one
+|:tunmenu|	:tu[nmenu]	remove menu tooltip
+|:undo|		:u[ndo]		undo last change(s)
+|:undojoin|	:undoj[oin]	join next change with previous undo block
+|:undolist|	:undol[ist]	list leafs of the undo tree
+|:unabbreviate|	:una[bbreviate]	remove abbreviation
+|:unhide|	:unh[ide]	open a window for each loaded file in the
+				buffer list
+|:unlet|	:unl[et]	delete variable
+|:unlockvar|	:unlo[ckvar]	unlock variables
+|:unmap|	:unm[ap]	remove mapping
+|:unmenu|	:unme[nu]	remove menu
+|:update|	:up[date]	write buffer if modified
+|:vglobal|	:v[global]	execute commands for not matching lines
+|:version|	:ve[rsion]	print version number and other info
+|:verbose|	:verb[ose]	execute command with 'verbose' set
+|:vertical|	:vert[ical]	make following command split vertically
+|:vimgrep|	:vim[grep]	search for pattern in files
+|:vimgrepadd|	:vimgrepa[dd]	like :vimgrep, but append to current list
+|:visual|	:vi[sual]	same as ":edit", but turns off "Ex" mode
+|:viusage|	:viu[sage]	overview of Normal mode commands
+|:view|		:vie[w]		edit a file read-only
+|:vmap|		:vm[ap]		like ":map" but for Visual+Select mode
+|:vmapclear|	:vmapc[lear]	remove all mappings for Visual+Select mode
+|:vmenu|	:vme[nu]	add menu for Visual+Select mode
+|:vnew|		:vne[w]		create a new empty window, vertically split
+|:vnoremap|	:vn[oremap]	like ":noremap" but for Visual+Select mode
+|:vnoremenu|	:vnoreme[nu]	like ":noremenu" but for Visual+Select mode
+|:vsplit|	:vs[plit]	split current window vertically
+|:vunmap|	:vu[nmap]	like ":unmap" but for Visual+Select mode
+|:vunmenu|	:vunme[nu]	remove menu for Visual+Select mode
+|:windo|	:windo		execute command in each window
+|:write|	:w[rite]	write to a file
+|:wNext|	:wN[ext]	write to a file and go to previous file in
+				argument list
+|:wall|		:wa[ll]		write all (changed) buffers
+|:while|	:wh[ile]	execute loop for as long as condition met
+|:winsize|	:wi[nsize]	get or set window size (obsolete)
+|:wincmd|	:winc[md]	execute a Window (CTRL-W) command
+|:winpos|	:winp[os]	get or set window position
+|:wnext|	:wn[ext]	write to a file and go to next file in
+				argument list
+|:wprevious|	:wp[revious]	write to a file and go to previous file in
+				argument list
+|:wq|		:wq		write to a file and quit window or Vim
+|:wqall|	:wqa[ll]	write all changed buffers and quit Vim
+|:wsverb|	:ws[verb]	pass the verb to workshop over IPC
+|:wviminfo|	:wv[iminfo]	write to viminfo file
+|:xit|		:x[it]		write if buffer changed and quit window or Vim
+|:xall|		:xa[ll]		same as ":wqall"
+|:xmapclear|	:xmapc[lear]	remove all mappings for Visual mode
+|:xmap|		:xm[ap]		like ":map" but for Visual mode
+|:xmenu|	:xme[nu]	add menu for Visual mode
+|:xnoremap|	:xn[oremap]	like ":noremap" but for Visual mode
+|:xnoremenu|	:xnoreme[nu]	like ":noremenu" but for Visual mode
+|:xunmap|	:xu[nmap]	like ":unmap" but for Visual mode
+|:xunmenu|	:xunme[nu]	remove menu for Visual mode
+|:yank|		:y[ank]		yank lines into a register
+|:z|		:z		print some lines
+|:~|		:~		repeat last ":substitute"
+
+
+ vim:tw=78:ts=8:ft=help:norl:
--- /dev/null
+++ b/lib/vimfiles/doc/insert.txt
@@ -1,0 +1,1880 @@
+*insert.txt*    For Vim version 7.1.  Last change: 2007 May 07
+
+
+		  VIM REFERENCE MANUAL    by Bram Moolenaar
+
+
+						*Insert* *Insert-mode*
+Inserting and replacing text				*mode-ins-repl*
+
+Most of this file is about Insert and Replace mode.  At the end are a few
+commands for inserting text in other ways.
+
+An overview of the most often used commands can be found in chapter 24 of the
+user manual |usr_24.txt|.
+
+1. Special keys						|ins-special-keys|
+2. Special special keys					|ins-special-special|
+3. 'textwidth' and 'wrapmargin' options			|ins-textwidth|
+4. 'expandtab', 'smarttab' and 'softtabstop'  options	|ins-expandtab|
+5. Replace mode						|Replace-mode|
+6. Virtual Replace mode					|Virtual-Replace-mode|
+7. Insert mode completion				|ins-completion|
+8. Insert mode commands					|inserting|
+9. Ex insert commands					|inserting-ex|
+10. Inserting a file					|inserting-file|
+
+Also see 'virtualedit', for moving the cursor to positions where there is no
+character.  Useful for editing a table.
+
+==============================================================================
+1. Special keys						*ins-special-keys*
+
+In Insert and Replace mode, the following characters have a special meaning;
+other characters are inserted directly.  To insert one of these special
+characters into the buffer, precede it with CTRL-V.  To insert a <Nul>
+character use "CTRL-V CTRL-@" or "CTRL-V 000".  On some systems, you have to
+use "CTRL-V 003" to insert a CTRL-C.  Note: When CTRL-V is mapped you can
+often use CTRL-Q instead |i_CTRL-Q|.
+
+If you are working in a special language mode when inserting text, see the
+'langmap' option, |'langmap'|, on how to avoid switching this mode on and off
+all the time.
+
+If you have 'insertmode' set, <Esc> and a few other keys get another meaning.
+See |'insertmode'|.
+
+char		action	~
+-----------------------------------------------------------------------
+						*i_CTRL-[* *i_<Esc>*
+<Esc> or CTRL-[	End insert or Replace mode, go back to Normal mode.  Finish
+		abbreviation.
+		Note: If your <Esc> key is hard to hit on your keyboard, train
+		yourself to use CTRL-[.
+						*i_CTRL-C*
+CTRL-C		Quit insert mode, go back to Normal mode.  Do not check for
+		abbreviations.  Does not trigger the |InsertLeave| autocommand
+		event.
+
+						*i_CTRL-@*
+CTRL-@		Insert previously inserted text and stop insert.  {Vi: only
+		when typed as first char, only up to 128 chars}
+						*i_CTRL-A*
+CTRL-A		Insert previously inserted text.  {not in Vi}
+
+						*i_CTRL-H* *i_<BS>* *i_BS*
+<BS> or CTRL-H	Delete the character before the cursor (see |i_backspacing|
+		about joining lines).
+		See |:fixdel| if your <BS> key does not do what you want.
+		{Vi: does not delete autoindents}
+						*i_<Del>* *i_DEL*
+<Del>		Delete the character under the cursor.  If the cursor is at
+		the end of the line, and the 'backspace' option includes
+		"eol", delete the <EOL>; the next line is appended after the
+		current one.
+		See |:fixdel| if your <Del> key does not do what you want.
+		{not in Vi}
+						*i_CTRL-W*
+CTRL-W		Delete the word before the cursor (see |i_backspacing| about
+		joining lines).  See the section "word motions",
+		|word-motions|, for the definition of a word.
+						*i_CTRL-U*
+CTRL-U		Delete all entered characters in the current line (see
+		|i_backspacing| about joining lines).
+
+						*i_CTRL-I* *i_<Tab>* *i_Tab*
+<Tab> or CTRL-I Insert a tab.  If the 'expandtab' option is on, the
+		equivalent number of spaces is inserted (use CTRL-V <Tab> to
+		avoid the expansion; use CTRL-Q <Tab> if CTRL-V is mapped
+		|i_CTRL-Q|).  See also the 'smarttab' option and
+		|ins-expandtab|.
+						*i_CTRL-J* *i_<NL>*
+<NL> or CTRL-J	Begin new line.
+						*i_CTRL-M* *i_<CR>*
+<CR> or CTRL-M	Begin new line.
+						*i_CTRL-K*
+CTRL-K {char1} [char2]
+		Enter digraph (see |digraphs|).  When {char1} is a special
+		key, the code for that key is inserted in <> form.  For
+		example, the string "<S-Space>" can be entered by typing
+		<C-K><S-Space> (two keys).  Neither char is considered for
+		mapping.  {not in Vi}
+
+CTRL-N		Find next keyword (see |i_CTRL-N|).  {not in Vi}
+CTRL-P		Find previous keyword (see |i_CTRL-P|).  {not in Vi}
+
+CTRL-R {0-9a-z"%#*+:.-=}					*i_CTRL-R*
+		Insert the contents of a register.  Between typing CTRL-R and
+		the second character, '"' will be displayed to indicate that
+		you are expected to enter the name of a register.
+		The text is inserted as if you typed it, but mappings and
+		abbreviations are not used.  If you have options like
+		'textwidth', 'formatoptions', or 'autoindent' set, this will
+		influence what will be inserted.  This is different from what
+		happens with the "p" command and pasting with the mouse.
+		Special registers:
+			'"'	the unnamed register, containing the text of
+				the last delete or yank
+			'%'	the current file name
+			'#'	the alternate file name
+			'*'	the clipboard contents (X11: primary selection)
+			'+'	the clipboard contents
+			'/'	the last search pattern
+			':'	the last command-line
+			'.'	the last inserted text
+			'-'	the last small (less than a line) delete
+			'='	the expression register: you are prompted to
+				enter an expression (see |expression|)
+				Note that 0x80 (128 decimal) is used for
+				special keys.  E.g., you can use this to move
+				the cursor up:
+					CTRL-R ="\<Up>"
+				Use CTRL-R CTRL-R to insert text literally.
+				When the result is a |List| the items are used
+				as lines.  They can have line breaks inside
+				too.
+		See |registers| about registers.  {not in Vi}
+
+CTRL-R CTRL-R {0-9a-z"%#*+/:.-=}			*i_CTRL-R_CTRL-R*
+		Insert the contents of a register.  Works like using a single
+		CTRL-R, but the text is inserted literally, not as if typed.
+		This differs when the register contains characters like <BS>.
+		Example, where register a contains "ab^Hc": >
+	CTRL-R a		results in "ac".
+	CTRL-R CTRL-R a		results in "ab^Hc".
+<		Options 'textwidth', 'formatoptions', etc. still apply.  If
+		you also want to avoid these, use "<C-R><C-O>r", see below.
+		The '.' register (last inserted text) is still inserted as
+		typed.  {not in Vi}
+
+CTRL-R CTRL-O {0-9a-z"%#*+/:.-=}			*i_CTRL-R_CTRL-O*
+		Insert the contents of a register literally and don't
+		auto-indent.  Does the same as pasting with the mouse
+		|<MiddleMouse>|.
+		Does not replace characters!
+		The '.' register (last inserted text) is still inserted as
+		typed.  {not in Vi}
+
+CTRL-R CTRL-P {0-9a-z"%#*+/:.-=}			*i_CTRL-R_CTRL-P*
+		Insert the contents of a register literally and fix the
+		indent, like |[<MiddleMouse>|.
+		Does not replace characters!
+		The '.' register (last inserted text) is still inserted as
+		typed.  {not in Vi}
+
+						*i_CTRL-T*
+CTRL-T		Insert one shiftwidth of indent at the start of the current
+		line.  The indent is always rounded to a 'shiftwidth' (this is
+		vi compatible).  {Vi: only when in indent}
+						*i_CTRL-D*
+CTRL-D		Delete one shiftwidth of indent at the start of the current
+		line.  The indent is always rounded to a 'shiftwidth' (this is
+		vi compatible).  {Vi: CTRL-D works only when used after
+		autoindent}
+						*i_0_CTRL-D*
+0 CTRL-D	Delete all indent in the current line.  {Vi: CTRL-D works
+		only when used after autoindent}
+						*i_^_CTRL-D*
+^ CTRL-D	Delete all indent in the current line.  The indent is
+		restored in the next line.  This is useful when inserting a
+		label.  {Vi: CTRL-D works only when used after autoindent}
+
+						*i_CTRL-V*
+CTRL-V		Insert next non-digit literally.  For special keys, the
+		terminal code is inserted.  It's also possible to enter the
+		decimal, octal or hexadecimal value of a character
+		|i_CTRL-V_digit|.
+		The characters typed right after CTRL-V are not considered for
+		mapping.  {Vi: no decimal byte entry}
+		Note: When CTRL-V is mapped (e.g., to paste text) you can
+		often use CTRL-Q instead |i_CTRL-Q|.
+
+						*i_CTRL-Q*
+CTRL-Q		Same as CTRL-V.
+		Note: Some terminal connections may eat CTRL-Q, it doesn't
+		work then.  It does work in the GUI.
+
+CTRL-X		Enter CTRL-X mode.  This is a sub-mode where commands can
+		be given to complete words or scroll the window.  See
+		|i_CTRL-X| and |ins-completion|. {not in Vi}
+
+						*i_CTRL-E*
+CTRL-E		Insert the character which is below the cursor.  {not in Vi}
+						*i_CTRL-Y*
+CTRL-Y		Insert the character which is above the cursor.  {not in Vi}
+		Note that for CTRL-E and CTRL-Y 'textwidth' is not used, to be
+		able to copy characters from a long line.
+
+						*i_CTRL-_*
+CTRL-_		Switch between languages, as follows:
+		-  When in a rightleft window, revins and nohkmap are toggled,
+		   since English will likely be inserted in this case.
+		-  When in a norightleft window, revins and hkmap are toggled,
+		   since Hebrew will likely be inserted in this case.
+
+		CTRL-_ moves the cursor to the end of the typed text.
+
+		This command is only available when the 'allowrevins' option
+		is set.
+		Please refer to |rileft.txt| for more information about
+		right-to-left mode.
+		{not in Vi}
+		Only if compiled with the |+rightleft| feature.
+
+						*i_CTRL-^*
+CTRL-^		Toggle the use of typing language characters.
+		When language |:lmap| mappings are defined:
+		- If 'iminsert' is 1 (langmap mappings used) it becomes 0 (no
+		  langmap mappings used).
+		- If 'iminsert' has another value it becomes 1, thus langmap
+		  mappings are enabled.
+		When no language mappings are defined:
+		- If 'iminsert' is 2 (Input Method used) it becomes 0 (no
+		  Input Method used).
+		- If 'iminsert' has another value it becomes 2, thus the Input
+		  Method is enabled.
+		When set to 1, the value of the "b:keymap_name" variable, the
+		'keymap' option or "<lang>" appears in the status line.
+		The language mappings are normally used to type characters
+		that are different from what the keyboard produces.  The
+		'keymap' option can be used to install a whole number of them.
+		{not in Vi}
+
+						*i_CTRL-]*
+CTRL-]		Trigger abbreviation, without inserting a character.  {not in
+		Vi}
+
+						*i_<Insert>*
+<Insert>	Toggle between Insert and Replace mode.  {not in Vi}
+-----------------------------------------------------------------------
+
+						*i_backspacing*
+The effect of the <BS>, CTRL-W, and CTRL-U depend on the 'backspace' option
+(unless 'revins' is set).  This is a comma separated list of items:
+
+item	    action ~
+indent	    allow backspacing over autoindent
+eol	    allow backspacing over end-of-line (join lines)
+start	    allow backspacing over the start position of insert; CTRL-W and
+	    CTRL-U stop once at the start position
+
+When 'backspace' is empty, Vi compatible backspacing is used.  You cannot
+backspace over autoindent, before column 1 or before where insert started.
+
+For backwards compatibility the values "0", "1" and "2" are also allowed, see
+|'backspace'|.
+
+If the 'backspace' option does contain "eol" and the cursor is in column 1
+when one of the three keys is used, the current line is joined with the
+previous line.  This effectively deletes the <EOL> in front of the cursor.
+{Vi: does not cross lines, does not delete past start position of insert}
+
+						*i_CTRL-V_digit*
+With CTRL-V the decimal, octal or hexadecimal value of a character can be
+entered directly.  This way you can enter any character, except a line break
+(<NL>, value 10).  There are five ways to enter the character value:
+
+first char	mode	     max nr of chars   max value ~
+(none)		decimal		   3		255
+o or O		octal		   3		377	 (255)
+x or X		hexadecimal	   2		ff	 (255)
+u		hexadecimal	   4		ffff	 (65535)
+U		hexadecimal	   8		7fffffff (2147483647)
+
+Normally you would type the maximum number of characters.  Thus to enter a
+space (value 32) you would type <C-V>032.  You can omit the leading zero, in
+which case the character typed after the number must be a non-digit.  This
+happens for the other modes as well: As soon as you type a character that is
+invalid for the mode, the value before it will be used and the "invalid"
+character is dealt with in the normal way.
+
+If you enter a value of 10, it will end up in the file as a 0.  The 10 is a
+<NL>, which is used internally to represent the <Nul> character.  When writing
+the buffer to a file, the <NL> character is translated into <Nul>.  The <NL>
+character is written at the end of each line.  Thus if you want to insert a
+<NL> character in a file you will have to make a line break.
+
+						*i_CTRL-X* *insert_expand*
+CTRL-X enters a sub-mode where several commands can be used.  Most of these
+commands do keyword completion; see |ins-completion|.  These are not available
+when Vim was compiled without the |+insert_expand| feature.
+
+Two commands can be used to scroll the window up or down, without exiting
+insert mode:
+
+						*i_CTRL-X_CTRL-E*
+CTRL-X CTRL-E		scroll window one line up.
+			When doing completion look here: |complete_CTRL-E|
+
+						*i_CTRL-X_CTRL-Y*
+CTRL-X CTRL-Y		scroll window one line down.
+			When doing completion look here: |complete_CTRL-Y|
+
+After CTRL-X is pressed, each CTRL-E (CTRL-Y) scrolls the window up (down) by
+one line unless that would cause the cursor to move from its current position
+in the file.  As soon as another key is pressed, CTRL-X mode is exited and
+that key is interpreted as in Insert mode.
+
+
+==============================================================================
+2. Special special keys				*ins-special-special*
+
+The following keys are special.  They stop the current insert, do something,
+and then restart insertion.  This means you can do something without getting
+out of Insert mode.  This is very handy if you prefer to use the Insert mode
+all the time, just like editors that don't have a separate Normal mode.  You
+may also want to set the 'backspace' option to "indent,eol,start" and set the
+'insertmode' option.  You can use CTRL-O if you want to map a function key to
+a command.
+
+The changes (inserted or deleted characters) before and after these keys can
+be undone separately.  Only the last change can be redone and always behaves
+like an "i" command.
+
+char		action	~
+-----------------------------------------------------------------------
+<Up>		cursor one line up			     *i_<Up>*
+<Down>		cursor one line down			     *i_<Down>*
+CTRL-G <Up>	cursor one line up, insert start column	     *i_CTRL-G_<Up>*
+CTRL-G k	cursor one line up, insert start column	     *i_CTRL-G_k*
+CTRL-G CTRL-K	cursor one line up, insert start column	     *i_CTRL-G_CTRL-K*
+CTRL-G <Down>	cursor one line down, insert start column    *i_CTRL-G_<Down>*
+CTRL-G j	cursor one line down, insert start column    *i_CTRL-G_j*
+CTRL-G CTRL-J	cursor one line down, insert start column    *i_CTRL-G_CTRL-J*
+<Left>		cursor one character left		     *i_<Left>*
+<Right>		cursor one character right		     *i_<Right>*
+<S-Left>	cursor one word back (like "b" command)	     *i_<S-Left>*
+<C-Left>	cursor one word back (like "b" command)	     *i_<C-Left>*
+<S-Right>	cursor one word forward (like "w" command)   *i_<S-Right>*
+<C-Right>	cursor one word forward (like "w" command)   *i_<C-Right>*
+<Home>		cursor to first char in the line	     *i_<Home>*
+<End>		cursor to after last char in the line	     *i_<End>*
+<C-Home>	cursor to first char in the file	     *i_<C-Home>*
+<C-End>		cursor to after last char in the file	     *i_<C-End>*
+<LeftMouse>	cursor to position of mouse click	     *i_<LeftMouse>*
+<S-Up>		move window one page up			     *i_<S-Up>*
+<PageUp>	move window one page up			     *i_<PageUp>*
+<S-Down>	move window one page down		     *i_<S-Down>*
+<PageDown>	move window one page down		     *i_<PageDown>*
+<MouseDown>	scroll three lines down			     *i_<MouseDown>*
+<S-MouseDown>	scroll a full page down			     *i_<S-MouseDown>*
+<MouseUp>	scroll three lines up			     *i_<MouseUp>*
+<S-MouseUp>	scroll a full page up			     *i_<S-MouseUp>*
+CTRL-O		execute one command, return to Insert mode   *i_CTRL-O*
+CTRL-\ CTRL-O	like CTRL-O but don't move the cursor	     *i_CTRL-\_CTRL-O*
+CTRL-L		when 'insertmode' is set: go to Normal mode  *i_CTRL-L*
+CTRL-G u	break undo sequence, start new change	     *i_CTRL-G_u*
+-----------------------------------------------------------------------
+
+Note: If the cursor keys take you out of Insert mode, check the 'noesckeys'
+option.
+
+The CTRL-O command sometimes has a side effect: If the cursor was beyond the
+end of the line, it will be put on the last character in the line.  In
+mappings it's often better to use <Esc> (first put an "x" in the text, <Esc>
+will then always put the cursor on it).  Or use CTRL-\ CTRL-O, but then
+beware of the cursor possibly being beyond the end of the line.
+
+The shifted cursor keys are not available on all terminals.
+
+Another side effect is that a count specified before the "i" or "a" command is
+ignored.  That is because repeating the effect of the command after CTRL-O is
+too complicated.
+
+An example for using CTRL-G u: >
+
+	:inoremap <C-H> <C-G>u<C-H>
+
+This redefines the backspace key to start a new undo sequence.  You can now
+undo the effect of the backspace key, without changing what you typed before
+that, with CTRL-O u.
+
+Using CTRL-O splits undo: the text typed before and after it is undone
+separately.  If you want to avoid this (e.g., in a mapping) you might be able
+to use CTRL-R = |i_CTRL-R|.  E.g., to call a function: >
+	:imap <F2> <C-R>=MyFunc()<CR>
+
+When the 'whichwrap' option is set appropriately, the <Left> and <Right>
+keys on the first/last character in the line make the cursor wrap to the
+previous/next line.
+
+The CTRL-G j and CTRL-G k commands can be used to insert text in front of a
+column.  Example: >
+   int i;
+   int j;
+Position the cursor on the first "int", type "istatic <C-G>j       ".  The
+result is: >
+   static int i;
+	  int j;
+When inserting the same text in front of the column in every line, use the
+Visual blockwise command "I" |v_b_I|.
+
+==============================================================================
+3. 'textwidth' and 'wrapmargin' options			*ins-textwidth*
+
+The 'textwidth' option can be used to automatically break a line before it
+gets too long.  Set the 'textwidth' option to the desired maximum line
+length.  If you then type more characters (not spaces or tabs), the
+last word will be put on a new line (unless it is the only word on the
+line).  If you set 'textwidth' to 0, this feature is disabled.
+
+The 'wrapmargin' option does almost the same.  The difference is that
+'textwidth' has a fixed width while 'wrapmargin' depends on the width of the
+screen.  When using 'wrapmargin' this is equal to using 'textwidth' with a
+value equal to (columns - 'wrapmargin'), where columns is the width of the
+screen.
+
+When 'textwidth' and 'wrapmargin' are both set, 'textwidth' is used.
+
+If you don't really want to break the line, but view the line wrapped at a
+convenient place, see the 'linebreak' option.
+
+The line is only broken automatically when using Insert mode, or when
+appending to a line.  When in replace mode and the line length is not
+changed, the line will not be broken.
+
+Long lines are broken if you enter a non-white character after the margin.
+The situations where a line will be broken can be restricted by adding
+characters to the 'formatoptions' option:
+"l"  Only break a line if it was not longer than 'textwidth' when the insert
+     started.
+"v"  Only break at a white character that has been entered during the
+     current insert command.  This is mostly Vi-compatible.
+"lv" Only break if the line was not longer than 'textwidth' when the insert
+     started and only at a white character that has been entered during the
+     current insert command.  Only differs from "l" when entering non-white
+     characters while crossing the 'textwidth' boundary.
+
+Normally an internal function will be used to decide where to break the line.
+If you want to do it in a different way set the 'formatexpr' option to an
+expression that will take care of the line break.
+
+If you want to format a block of text, you can use the "gq" operator.  Type
+"gq" and a movement command to move the cursor to the end of the block.  In
+many cases, the command "gq}" will do what you want (format until the end of
+paragraph).  Alternatively, you can use "gqap", which will format the whole
+paragraph, no matter where the cursor currently is.  Or you can use Visual
+mode: hit "v", move to the end of the block, and type "gq".  See also |gq|.
+
+==============================================================================
+4. 'expandtab', 'smarttab' and 'softtabstop' options	*ins-expandtab*
+
+If the 'expandtab' option is on, spaces will be used to fill the amount of
+whitespace of the tab.  If you want to enter a real <Tab>, type CTRL-V first
+(use CTRL-Q when CTRL-V is mapped |i_CTRL-Q|).
+The 'expandtab' option is off by default.  Note that in Replace mode, a single
+character is replaced with several spaces.  The result of this is that the
+number of characters in the line increases.  Backspacing will delete one
+space at a time.  The original character will be put back for only one space
+that you backspace over (the last one).  {Vi does not have the 'expandtab'
+option}
+
+							*ins-smarttab*
+When the 'smarttab' option is on, a <Tab> inserts 'shiftwidth' positions at
+the beginning of a line and 'tabstop' positions in other places.  This means
+that often spaces instead of a <Tab> character are inserted.  When 'smarttab
+is off, a <Tab> always inserts 'tabstop' positions, and 'shiftwidth' is only
+used for ">>" and the like.  {not in Vi}
+
+							*ins-softtabstop*
+When the 'softtabstop' option is non-zero, a <Tab> inserts 'softtabstop'
+positions, and a <BS> used to delete white space, will delete 'softtabstop'
+positions.  This feels like 'tabstop' was set to 'softtabstop', but a real
+<Tab> character still takes 'tabstop' positions, so your file will still look
+correct when used by other applications.
+
+If 'softtabstop' is non-zero, a <BS> will try to delete as much white space to
+move to the previous 'softtabstop' position, except when the previously
+inserted character is a space, then it will only delete the character before
+the cursor.  Otherwise you cannot always delete a single character before the
+cursor.  You will have to delete 'softtabstop' characters first, and then type
+extra spaces to get where you want to be.
+
+==============================================================================
+5. Replace mode				*Replace* *Replace-mode* *mode-replace*
+
+Enter Replace mode with the "R" command in normal mode.
+
+In Replace mode, one character in the line is deleted for every character you
+type.  If there is no character to delete (at the end of the line), the
+typed character is appended (as in Insert mode).  Thus the number of
+characters in a line stays the same until you get to the end of the line.
+If a <NL> is typed, a line break is inserted and no character is deleted.
+
+Be careful with <Tab> characters.  If you type a normal printing character in
+its place, the number of characters is still the same, but the number of
+columns will become smaller.
+
+If you delete characters in Replace mode (with <BS>, CTRL-W, or CTRL-U), what
+happens is that you delete the changes.  The characters that were replaced
+are restored.  If you had typed past the existing text, the characters you
+added are deleted.  This is effectively a character-at-a-time undo.
+
+If the 'expandtab' option is on, a <Tab> will replace one character with
+several spaces.  The result of this is that the number of characters in the
+line increases.  Backspacing will delete one space at a time.  The original
+character will be put back for only one space that you backspace over (the
+last one).  {Vi does not have the 'expandtab' option}
+
+==============================================================================
+6. Virtual Replace mode		*vreplace-mode* *Virtual-Replace-mode*
+
+Enter Virtual Replace mode with the "gR" command in normal mode.
+{not available when compiled without the +vreplace feature}
+{Vi does not have Virtual Replace mode}
+
+Virtual Replace mode is similar to Replace mode, but instead of replacing
+actual characters in the file, you are replacing screen real estate, so that
+characters further on in the file never appear to move.
+
+So if you type a <Tab> it may replace several normal characters, and if you
+type a letter on top of a <Tab> it may not replace anything at all, since the
+<Tab> will still line up to the same place as before.
+
+Typing a <NL> still doesn't cause characters later in the file to appear to
+move.  The rest of the current line will be replaced by the <NL> (that is,
+they are deleted), and replacing continues on the next line.  A new line is
+NOT inserted unless you go past the end of the file.
+
+Interesting effects are seen when using CTRL-T and CTRL-D.  The characters
+before the cursor are shifted sideways as normal, but characters later in the
+line still remain still.  CTRL-T will hide some of the old line under the
+shifted characters, but CTRL-D will reveal them again.
+
+As with Replace mode, using <BS> etc will bring back the characters that were
+replaced.  This still works in conjunction with 'smartindent', CTRL-T and
+CTRL-D, 'expandtab', 'smarttab', 'softtabstop', etc.
+
+In 'list' mode, Virtual Replace mode acts as if it was not in 'list' mode,
+unless "L" is in 'cpoptions'.
+
+Note that the only times characters beyond the cursor should appear to move
+are in 'list' mode, and occasionally when 'wrap' is set (and the line changes
+length to become shorter or wider than the width of the screen), or
+momentarily when typing over a CTRL character.  A CTRL character takes up two
+screen spaces.  When replacing it with two normal characters, the first will
+be inserted and the second will replace the CTRL character.
+
+This mode is very useful for editing <Tab> separated columns in tables, for
+entering new data while keeping all the columns aligned.
+
+==============================================================================
+7. Insert mode completion				*ins-completion*
+
+In Insert and Replace mode, there are several commands to complete part of a
+keyword or line that has been typed.  This is useful if you are using
+complicated keywords (e.g., function names with capitals and underscores).
+
+These commands are not available when the |+insert_expand| feature was
+disabled at compile time.
+
+Completion can be done for:
+
+1. Whole lines						|i_CTRL-X_CTRL-L|
+2. keywords in the current file				|i_CTRL-X_CTRL-N|
+3. keywords in 'dictionary'				|i_CTRL-X_CTRL-K|
+4. keywords in 'thesaurus', thesaurus-style		|i_CTRL-X_CTRL-T|
+5. keywords in the current and included files		|i_CTRL-X_CTRL-I|
+6. tags							|i_CTRL-X_CTRL-]|
+7. file names						|i_CTRL-X_CTRL-F|
+8. definitions or macros				|i_CTRL-X_CTRL-D|
+9. Vim command-line					|i_CTRL-X_CTRL-V|
+10. User defined completion				|i_CTRL-X_CTRL-U|
+11. omni completion					|i_CTRL-X_CTRL-O|
+12. Spelling suggestions				|i_CTRL-X_s|
+13. keywords in 'complete'				|i_CTRL-N|
+
+All these (except 2) are done in CTRL-X mode.  This is a sub-mode of Insert
+and Replace modes.  You enter CTRL-X mode by typing CTRL-X and one of the
+CTRL-X commands.  You exit CTRL-X mode by typing a key that is not a valid
+CTRL-X mode command.  Valid keys are the CTRL-X command itself, CTRL-N (next),
+and CTRL-P (previous).
+
+Also see the 'infercase' option if you want to adjust the case of the match.
+
+							*complete_CTRL-E*
+When completion is active you can use CTRL-E to stop it and go back to the
+originally typed text.  The CTRL-E will not be inserted.
+
+							*complete_CTRL-Y*
+When the popup menu is displayed you can use CTRL-Y to stop completion and
+accept the currently selected entry.  The CTRL-Y is not inserted.  Typing a
+space, Enter, or some other unprintable character will leave completion mode
+and insert that typed character.
+
+When the popup menu is displayed there are a few more special keys, see
+|popupmenu-keys|.
+
+Note: The keys that are valid in CTRL-X mode are not mapped.  This allows for
+":map ^F ^X^F" to work (where ^F is CTRL-F and ^X is CTRL-X).  The key that
+ends CTRL-X mode (any key that is not a valid CTRL-X mode command) is mapped.
+Also, when doing completion with 'complete' mappings apply as usual.
+
+Note: While completion is active Insert mode can't be used recursively.
+Mappings that somehow invoke ":normal i.." will generate an E523 error.
+
+The following mappings are suggested to make typing the completion commands
+a bit easier (although they will hide other commands): >
+    :inoremap ^] ^X^]
+    :inoremap ^F ^X^F
+    :inoremap ^D ^X^D
+    :inoremap ^L ^X^L
+
+As a special case, typing CTRL-R to perform register insertion (see
+|i_CTRL-R|) will not exit CTRL-X mode.  This is primarily to allow the use of
+the '=' register to call some function to determine the next operation.  If
+the contents of the register (or result of the '=' register evaluation) are
+not valid CTRL-X mode keys, then CTRL-X mode will be exited as if those keys
+had been typed.
+
+For example, the following will map <Tab> to either actually insert a <Tab> if
+the current line is currently only whitespace, or start/continue a CTRL-N
+completion operation: >
+
+	function! CleverTab()
+	   if strpart( getline('.'), 0, col('.')-1 ) =~ '^\s*$'
+	      return "\<Tab>"
+	   else
+	      return "\<C-N>"
+	endfunction
+	inoremap <Tab> <C-R>=CleverTab()<CR>
+
+
+
+Completing whole lines					*compl-whole-line*
+
+							*i_CTRL-X_CTRL-L*
+CTRL-X CTRL-L		Search backwards for a line that starts with the
+			same characters as those in the current line before
+			the cursor.  Indent is ignored.  The matching line is
+			inserted in front of the cursor.
+			The 'complete' option is used to decide which buffers
+			are searched for a match.  Both loaded and unloaded
+			buffers are used.
+	CTRL-L	or
+	CTRL-P		Search backwards for next matching line.  This line
+			replaces the previous matching line.
+
+	CTRL-N		Search forward for next matching line.  This line
+			replaces the previous matching line.
+
+	CTRL-X CTRL-L	After expanding a line you can additionally get the
+			line next to it by typing CTRL-X CTRL-L again, unless
+			a double CTRL-X is used.
+
+Completing keywords in current file			*compl-current*
+
+							*i_CTRL-X_CTRL-P*
+							*i_CTRL-X_CTRL-N*
+CTRL-X CTRL-N		Search forwards for words that start with the keyword
+			in front of the cursor.  The found keyword is inserted
+			in front of the cursor.
+
+CTRL-X CTRL-P		Search backwards for words that start with the keyword
+			in front of the cursor.  The found keyword is inserted
+			in front of the cursor.
+
+	CTRL-N		Search forward for next matching keyword.  This
+			keyword replaces the previous matching keyword.
+
+	CTRL-P		Search backwards for next matching keyword.  This
+			keyword replaces the previous matching keyword.
+
+	CTRL-X CTRL-N or
+	CTRL-X CTRL-P	Further use of CTRL-X CTRL-N or CTRL-X CTRL-P will
+			copy the words following the previous expansion in
+			other contexts unless a double CTRL-X is used.
+
+If there is a keyword in front of the cursor (a name made out of alphabetic
+characters and characters in 'iskeyword'), it is used as the search pattern,
+with "\<" prepended (meaning: start of a word).  Otherwise "\<\k\k" is used
+as search pattern (start of any keyword of at least two characters).
+
+In Replace mode, the number of characters that are replaced depends on the
+length of the matched string.  This works like typing the characters of the
+matched string in Replace mode.
+
+If there is not a valid keyword character before the cursor, any keyword of
+at least two characters is matched.
+	e.g., to get:
+	    printf("(%g, %g, %g)", vector[0], vector[1], vector[2]);
+	just type:
+	    printf("(%g, %g, %g)", vector[0], ^P[1], ^P[2]);
+
+The search wraps around the end of the file, the value of 'wrapscan' is not
+used here.
+
+Multiple repeats of the same completion are skipped; thus a different match
+will be inserted at each CTRL-N and CTRL-P (unless there is only one
+matching keyword).
+
+Single character matches are never included, as they usually just get in
+the way of what you were really after.
+	e.g., to get:
+		printf("name = %s\n", name);
+	just type:
+		printf("name = %s\n", n^P);
+	or even:
+		printf("name = %s\n", ^P);
+The 'n' in '\n' is skipped.
+
+After expanding a word, you can use CTRL-X CTRL-P or CTRL-X CTRL-N to get the
+word following the expansion in other contexts.  These sequences search for
+the text just expanded and further expand by getting an extra word.  This is
+useful if you need to repeat a sequence of complicated words.  Although CTRL-P
+and CTRL-N look just for strings of at least two characters, CTRL-X CTRL-P and
+CTRL-X CTRL-N can be used to expand words of just one character.
+	e.g., to get:
+		M&eacute;xico
+	you can type:
+		M^N^P^X^P^X^P
+CTRL-N starts the expansion and then CTRL-P takes back the single character
+"M", the next two CTRL-X CTRL-P's get the words "&eacute" and ";xico".
+
+If the previous expansion was split, because it got longer than 'textwidth',
+then just the text in the current line will be used.
+
+If the match found is at the end of a line, then the first word in the next
+line will be inserted and the message "word from next line" displayed, if
+this word is accepted the next CTRL-X CTRL-P or CTRL-X CTRL-N will search
+for those lines starting with this word.
+
+
+Completing keywords in 'dictionary'			*compl-dictionary*
+
+							*i_CTRL-X_CTRL-K*
+CTRL-X CTRL-K		Search the files given with the 'dictionary' option
+			for words that start with the keyword in front of the
+			cursor.  This is like CTRL-N, but only the dictionary
+			files are searched, not the current file.  The found
+			keyword is inserted in front of the cursor.  This
+			could potentially be pretty slow, since all matches
+			are found before the first match is used.  By default,
+			the 'dictionary' option is empty.
+			For suggestions where to find a list of words, see the
+			'dictionary' option.
+
+	CTRL-K	or
+	CTRL-N		Search forward for next matching keyword.  This
+			keyword replaces the previous matching keyword.
+
+	CTRL-P		Search backwards for next matching keyword.  This
+			keyword replaces the previous matching keyword.
+
+							*i_CTRL-X_CTRL-T*
+CTRL-X CTRL-T		Works as CTRL-X CTRL-K, but in a special way.  It uses
+			the 'thesaurus' option instead of 'dictionary'.  If a
+			match is found in the thesaurus file, all the
+			remaining words on the same line are included as
+			matches, even though they don't complete the word.
+			Thus a word can be completely replaced.
+
+			For an example, imagine the 'thesaurus' file has a
+			line like this: >
+				angry furious mad enraged
+<			Placing the cursor after the letters "ang" and typing
+			CTRL-X CTRL-T would complete the word "angry";
+			subsequent presses would change the word to "furious",
+			"mad" etc.
+			Other uses include translation between two languages,
+			or grouping API functions by keyword.
+
+	CTRL-T	or
+	CTRL-N		Search forward for next matching keyword.  This
+			keyword replaces the previous matching keyword.
+
+	CTRL-P		Search backwards for next matching keyword.  This
+			keyword replaces the previous matching keyword.
+
+
+Completing keywords in the current and included files	*compl-keyword*
+
+The 'include' option is used to specify a line that contains an include file
+name.  The 'path' option is used to search for include files.
+
+							*i_CTRL-X_CTRL-I*
+CTRL-X CTRL-I		Search for the first keyword in the current and
+			included files that starts with the same characters
+			as those before the cursor.  The matched keyword is
+			inserted in front of the cursor.
+
+	CTRL-N		Search forwards for next matching keyword.  This
+			keyword replaces the previous matching keyword.
+			Note: CTRL-I is the same as <Tab>, which is likely to
+			be typed after a successful completion, therefore
+			CTRL-I is not used for searching for the next match.
+
+	CTRL-P		Search backward for previous matching keyword.  This
+			keyword replaces the previous matching keyword.
+
+	CTRL-X CTRL-I	Further use of CTRL-X CTRL-I will copy the words
+			following the previous expansion in other contexts
+			unless a double CTRL-X is used.
+
+Completing tags						*compl-tag*
+							*i_CTRL-X_CTRL-]*
+CTRL-X CTRL-]		Search for the first tag that starts with the same
+			characters as before the cursor.  The matching tag is
+			inserted in front of the cursor.  Alphabetic
+			characters and characters in 'iskeyword' are used
+			to decide which characters are included in the tag
+			name (same as for a keyword).  See also |CTRL-]|.
+			The 'showfulltag' option can be used to add context
+			from around the tag definition.
+	CTRL-]	or
+	CTRL-N		Search forwards for next matching tag.  This tag
+			replaces the previous matching tag.
+
+	CTRL-P		Search backward for previous matching tag.  This tag
+			replaces the previous matching tag.
+
+
+Completing file names					*compl-filename*
+							*i_CTRL-X_CTRL-F*
+CTRL-X CTRL-F		Search for the first file name that starts with the
+			same characters as before the cursor.  The matching
+			file name is inserted in front of the cursor.
+			Alphabetic characters and characters in 'isfname'
+			are used to decide which characters are included in
+			the file name.  Note: the 'path' option is not used
+			here (yet).
+	CTRL-F	or
+	CTRL-N		Search forwards for next matching file name.  This
+			file name replaces the previous matching file name.
+
+	CTRL-P		Search backward for previous matching file name.
+			This file name replaces the previous matching file
+			name.
+
+
+Completing definitions or macros			*compl-define*
+
+The 'define' option is used to specify a line that contains a definition.
+The 'include' option is used to specify a line that contains an include file
+name.  The 'path' option is used to search for include files.
+
+							*i_CTRL-X_CTRL-D*
+CTRL-X CTRL-D		Search in the current and included files for the
+			first definition (or macro) name that starts with
+			the same characters as before the cursor.  The found
+			definition name is inserted in front of the cursor.
+	CTRL-D	or
+	CTRL-N		Search forwards for next matching macro name.  This
+			macro name replaces the previous matching macro
+			name.
+
+	CTRL-P		Search backward for previous matching macro name.
+			This macro name replaces the previous matching macro
+			name.
+
+	CTRL-X CTRL-D	Further use of CTRL-X CTRL-D will copy the words
+			following the previous expansion in other contexts
+			unless a double CTRL-X is used.
+
+
+Completing Vim commands					*compl-vim*
+
+Completion is context-sensitive.  It works like on the Command-line.  It
+completes an Ex command as well as its arguments.  This is useful when writing
+a Vim script.
+
+							*i_CTRL-X_CTRL-V*
+CTRL-X CTRL-V		Guess what kind of item is in front of the cursor and
+			find the first match for it.
+			Note: When CTRL-V is mapped you can often use CTRL-Q
+			instead |i_CTRL-Q|.
+	CTRL-V	or
+	CTRL-N		Search forwards for next match.  This match replaces
+			the previous one.
+
+	CTRL-P		Search backward for previous match.  This match
+			replaces the previous one.
+
+	CTRL-X CTRL-V	Further use of CTRL-X CTRL-V will do the same as
+			CTRL-V.  This allows mapping a key to do Vim command
+			completion, for example: >
+				:imap <Tab> <C-X><C-V>
+
+User defined completion					*compl-function*
+
+Completion is done by a function that can be defined by the user with the
+'completefunc' option.  See below for how the function is called and an
+example |complete-functions|.
+
+							*i_CTRL-X_CTRL-U*
+CTRL-X CTRL-U		Guess what kind of item is in front of the cursor and
+			find the first match for it.
+	CTRL-U	or
+	CTRL-N		Use the next match.  This match replaces the previous
+			one.
+
+	CTRL-P		Use the previous match.  This match replaces the
+			previous one.
+
+
+Omni completion						*compl-omni*
+
+Completion is done by a function that can be defined by the user with the
+'omnifunc' option.  This is to be used for filetype-specific completion.
+
+See below for how the function is called and an example |complete-functions|.
+For remarks about specific filetypes see |compl-omni-filetypes|.
+More completion scripts will appear, check www.vim.org.  Currently there is a
+first version for C++.
+
+							*i_CTRL-X_CTRL-O*
+CTRL-X CTRL-O		Guess what kind of item is in front of the cursor and
+			find the first match for it.
+	CTRL-O	or
+	CTRL-N		Use the next match.  This match replaces the previous
+			one.
+
+	CTRL-P		Use the previous match.  This match replaces the
+			previous one.
+
+
+Spelling suggestions					*compl-spelling*
+
+A word before or at the cursor is located and correctly spelled words are
+suggested to replace it.  If there is a badly spelled word in the line, before
+or under the cursor, the cursor is moved to after it.  Otherwise the word just
+before the cursor is used for suggestions, even though it isn't badly spelled.
+
+NOTE: CTRL-S suspends display in many Unix terminals.  Use 's' instead.  Type
+CTRL-Q to resume displaying.
+
+						*i_CTRL-X_CTRL-S* *i_CTRL-X_s*
+CTRL-X CTRL-S   or
+CTRL-X s		Locate the word in front of the cursor and find the
+			first spell suggestion for it.
+	CTRL-S	or
+	CTRL-N		Use the next suggestion.  This replaces the previous
+			one.  Note that you can't use 's' here.
+
+	CTRL-P		Use the previous suggestion.  This replaces the
+			previous one.
+
+
+Completing keywords from different sources		*compl-generic*
+
+							*i_CTRL-N*
+CTRL-N			Find next match for words that start with the
+			keyword in front of the cursor, looking in places
+			specified with the 'complete' option.  The found
+			keyword is inserted in front of the cursor.
+
+							*i_CTRL-P*
+CTRL-P			Find previous match for words that start with the
+			keyword in front of the cursor, looking in places
+			specified with the 'complete' option.  The found
+			keyword is inserted in front of the cursor.
+
+	CTRL-N		Search forward for next matching keyword.  This
+			keyword replaces the previous matching keyword.
+
+	CTRL-P		Search backwards for next matching keyword.  This
+			keyword replaces the previous matching keyword.
+
+	CTRL-X CTRL-N or
+	CTRL-X CTRL-P	Further use of CTRL-X CTRL-N or CTRL-X CTRL-P will
+			copy the words following the previous expansion in
+			other contexts unless a double CTRL-X is used.
+
+
+FUNCTIONS FOR FINDING COMPLETIONS			*complete-functions*
+
+This applies to 'completefunc' and 'omnifunc'.
+
+The function is called in two different ways:
+- First the function is called to find the start of the text to be completed.
+- Later the function is called to actually find the matches.
+
+On the first invocation the arguments are:
+   a:findstart  1
+   a:base	empty
+
+The function must return the column where the completion starts.  It must be a
+number between zero and the cursor column "col('.')".  This involves looking
+at the characters just before the cursor and including those characters that
+could be part of the completed item.  The text between this column and the
+cursor column will be replaced with the matches.  Return -1 if no completion
+can be done.
+
+On the second invocation the arguments are:
+   a:findstart  0
+   a:base	the text with which matches should match; the text that was
+		located in the first call (can be empty)
+
+The function must return a List with the matching words.  These matches
+usually include the "a:base" text.  When there are no matches return an empty
+List.
+						*complete-items*
+Each list item can either be a string or a Dictionary.  When it is a string it
+is used as the completion.  When it is a Dictionary it can contain these
+items:
+	word		the text that will be inserted, mandatory
+	abbr		abbreviation of "word"; when not empty it is used in
+			the menu instead of "word"
+	menu		extra text for the popup menu, displayed after "word"
+			or "abbr"
+	info		more information about the item, can be displayed in a
+			preview window
+	kind		single letter indicating the type of completion
+	icase		when non-zero case is to be ignored when comparing
+			items to be equal; when omitted zero is used, thus
+			items that only differ in case are added
+	dup		when non-zero this match will be added even when an
+			item with the same word is already present.
+
+All of these except 'icase' must be a string.  If an item does not meet these
+requirements then an error message is given and further items in the list are
+not used.  You can mix string and Dictionary items in the returned list.
+
+The "menu" item is used in the popup menu and may be truncated, thus it should
+be relatively short.  The "info" item can be longer, it will  be displayed in
+the preview window when "preview" appears in 'completeopt'.  The "info" item
+will also remain displayed after the popup menu has been removed.  This is
+useful for function arguments.  Use a single space for "info" to remove
+existing text in the preview window.
+
+The "kind" item uses a single letter to indicate the kind of completion.  This
+may be used to show the completion differently (different color or icon).
+Currently these types can be used:
+	v	variable
+	f	function or method
+	m	member of a struct or class
+	t	typedef
+	d	#define or macro
+
+When searching for matches takes some time call |complete_add()| to add each
+match to the total list.  These matches should then not appear in the returned
+list!  Call |complete_check()| now and then to allow the user to press a key
+while still searching for matches.  Stop searching when it returns non-zero.
+
+The function is allowed to move the cursor, it is restored afterwards.  This
+option cannot be set from a |modeline| or in the |sandbox|, for security
+reasons.
+
+An example that completes the names of the months: >
+	fun! CompleteMonths(findstart, base)
+	  if a:findstart
+	    " locate the start of the word
+	    let line = getline('.')
+	    let start = col('.') - 1
+	    while start > 0 && line[start - 1] =~ '\a'
+	      let start -= 1
+	    endwhile
+	    return start
+	  else
+	    " find months matching with "a:base"
+	    let res = []
+	    for m in split("Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec")
+	      if m =~ '^' . a:base
+		call add(res, m)
+	      endif
+	    endfor
+	    return res
+	  endif
+	endfun
+	set completefunc=CompleteMonths
+<
+The same, but now pretending searching for matches is slow: >
+	fun! CompleteMonths(findstart, base)
+	  if a:findstart
+	    " locate the start of the word
+	    let line = getline('.')
+	    let start = col('.') - 1
+	    while start > 0 && line[start - 1] =~ '\a'
+	      let start -= 1
+	    endwhile
+	    return start
+	  else
+	    " find months matching with "a:base"
+	    for m in split("Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec")
+	      if m =~ '^' . a:base
+		call complete_add(m)
+	      endif
+	      sleep 300m	" simulate searching for next match
+	      if complete_check()
+		break
+	      endif
+	    endfor
+	    return []
+	  endif
+	endfun
+	set completefunc=CompleteMonths
+<
+
+INSERT COMPLETION POPUP MENU				*ins-completion-menu*
+							*popupmenu-completion*
+Vim can display the matches in a simplistic popup menu.
+
+The menu is used when:
+- The 'completeopt' option contains "menu" or "menuone".
+- The terminal supports at least 8 colors.
+- There are at least two matches.  One if "menuone" is used.
+
+The 'pumheight' option can be used to set a maximum height.  The default is to
+use all space available.
+
+There are three states:
+1. A complete match has been inserted, e.g., after using CTRL-N or CTRL-P.
+2. A cursor key has been used to select another match.  The match was not
+   inserted then, only the entry in the popup menu is highlighted.
+3. Only part of a match has been inserted and characters were typed or the
+   backspace key was used.  The list of matches was then adjusted for what is
+   in front of the cursor.
+
+You normally start in the first state, with the first match being inserted.
+When "longest" is in 'completeopt' and there is more than one match you start
+in the third state.
+
+If you select another match, e.g., with CTRL-N or CTRL-P, you go to the first
+state.  This doesn't change the list of matches.
+
+When you are back at the original text then you are in the third state.  To
+get there right away you can use a mapping that uses CTRL-P right after
+starting the completion: >
+	:imap <F7> <C-N><C-P>
+<
+						*popupmenu-keys*
+In the first state these keys have a special meaning:
+<BS> and CTRL-H   Delete one character, find the matches for the word before
+		  the cursor.  This reduces the list of matches, often to one
+		  entry, and switches to the second state.
+Any non-special character:
+		  Stop completion without changing the match and insert the
+		  typed character.
+
+In the second and third state these keys have a special meaning:
+<BS> and CTRL-H   Delete one character, find the matches for the shorter word
+		  before the cursor.  This may find more matches.
+CTRL-L		  Add one character from the current match, may reduce the
+		  number of matches.
+any printable, non-white character:
+		  Add this character and reduce the number of matches.
+
+In all three states these can be used:
+CTRL-Y		  Yes: Accept the currently selected match and stop completion.
+CTRL-E		  End completion, go back to what was there before selecting a
+		  match (what was typed or longest common string).
+<PageUp>	  Select a match several entries back, but don't insert it.
+<PageDown>	  Select a match several entries further, but don't insert it.
+<Up>		  Select the previous match, as if CTRL-P was used, but don't
+		  insert it.
+<Down>		  Select the next match, as if CTRL-N was used, but don't
+		  insert it.
+<Space> or <Tab>  Stop completion without changing the match and insert the
+		  typed character.
+
+The behavior of the <Enter> key depends on the state you are in:
+first state:	  Use the text as it is and insert a line break.
+second state:	  Insert the currently selected match.
+third state:	  Use the text as it is and insert a line break.
+
+In other words: If you used the cursor keys to select another entry in the
+list of matches then the <Enter> key inserts that match.  If you typed
+something else then <Enter> inserts a line break.
+
+
+The colors of the menu can be changed with these highlight groups:
+Pmenu		normal item  |hl-Pmenu|
+PmenuSel	selected item  |hl-PmenuSel|
+PmenuSbar	scrollbar  |hl-PmenuSbar|
+PmenuThumb	thumb of the scrollbar  |hl-PmenuThumb|
+
+There are no special mappings for when the popup menu is visible.  However,
+you can use an Insert mode mapping that checks the |pumvisible()| function to
+do something different.  Example: >
+	:inoremap <Down> <C-R>=pumvisible() ? "\<lt>C-N>" : "\<lt>Down>"<CR>
+
+You can use of <expr> in mapping to have the popup menu used when typing a
+character and some condition is met.  For example, for typing a dot: >
+	inoremap <expr> . MayComplete()
+	func MayComplete()
+	    if (can complete)
+	      return ".\<C-X>\<C-O>"
+	    endif
+	    return '.'
+	endfunc
+
+See |:map-<expr>| for more info.
+
+
+FILETYPE-SPECIFIC REMARKS FOR OMNI COMPLETION	    *compl-omni-filetypes*
+
+The file used for {filetype} should be autoload/{filetype}complete.vim
+in 'runtimepath'.  Thus for "java" it is autoload/javacomplete.vim.
+
+
+C							*ft-c-omni*
+
+Completion of C code requires a tags file.  You should use Exuberant ctags,
+because it adds extra information that is needed for completion.  You can find
+it here: http://ctags.sourceforge.net/  Version 5.6 or later is recommended.
+
+For version 5.5.4 you should add a patch that adds the "typename:" field:
+	ftp://ftp.vim.org/pub/vim/unstable/patches/ctags-5.5.4.patch
+A compiled .exe for MS-Windows can be found at:
+	http://georgevreilly.com/vim/ctags.html
+
+If you want to complete system functions you can do something like this.  Use
+ctags to generate a tags file for all the system header files: >
+	% ctags -R -f ~/.vim/systags /usr/include /usr/local/include
+In your vimrc file add this tags file to the 'tags' option: >
+	set tags+=~/.vim/systags
+
+When using CTRL-X CTRL-O after a name without any "." or "->" it is completed
+from the tags file directly.  This works for any identifier, also function
+names.  If you want to complete a local variable name, which does not appear
+in the tags file, use CTRL-P instead.
+
+When using CTRL-X CTRL-O after something that has "." or "->" Vim will attempt
+to recognize the type of the variable and figure out what members it has.
+This means only members valid for the variable will be listed.
+
+When a member name already was complete, CTRL-X CTRL-O will add a "." or
+"->" for composite types.
+
+Vim doesn't include a C compiler, only the most obviously formatted
+declarations are recognized.  Preprocessor stuff may cause confusion.
+When the same structure name appears in multiple places all possible members
+are included.
+
+
+CSS							*ft-css-omni*
+
+Complete properties and their appropriate values according to CSS 2.1
+specification.
+
+
+HTML							*ft-html-omni*
+XHTML							*ft-xhtml-omni*
+
+CTRL-X CTRL-O provides completion of various elements of (X)HTML files.  It is
+designed to support writing of XHTML 1.0 Strict files but will also works for
+other versions of HTML. Features:
+
+- after "<" complete tag name depending on context (no div suggestion inside
+  of an a tag); '/>' indicates empty tags
+- inside of tag complete proper attributes (no width attribute for an a tag);
+  show also type of attribute; '*' indicates required attributes
+- when attribute has limited number of possible values help to complete them
+- complete names of entities
+- complete values of "class" and "id" attributes with data obtained from
+  <style> tag and included CSS files
+- when completing value of "style" attribute or working inside of "style" tag
+  switch to |ft-css-omni| completion
+- when completing values of events attributes or working inside of "script"
+  tag switch to |ft-javascript-omni| completion
+- when used after "</" CTRL-X CTRL-O will close the last opened tag
+
+Note: When used first time completion menu will be shown with little delay
+- this is time needed for loading of data file.
+Note: Completion may fail in badly formatted documents. In such case try to
+run |:make| command to detect formatting problems.
+
+
+HTML flavor						*html-flavor*
+
+The default HTML completion depends on the filetype.  For HTML files it is
+HTML 4.01 Transitional ('filetype' is "html"), for XHTML it is XHTML 1.0
+Strict ('filetype' is "xhtml").
+
+When doing completion outside of any other tag you will have possibility to
+choose DOCTYPE and the appropriate data file will be loaded and used for all
+next completions.
+
+More about format of data file in |xml-omni-datafile|. Some of the data files
+may be found on the Vim website (|www|).
+
+Note that b:html_omni_flavor may point to a file with any XML data.  This
+makes possible to mix PHP (|ft-php-omni|) completion with any XML dialect
+(assuming you have data file for it).  Without setting that variable XHTML 1.0
+Strict will be used.
+
+
+JAVASCRIPT					       *ft-javascript-omni*
+
+Completion of most elements of JavaScript language and DOM elements.
+
+Complete:
+
+- variables
+- function name; show function arguments
+- function arguments
+- properties of variables trying to detect type of variable
+- complete DOM objects and properties depending on context
+- keywords of language
+
+Completion works in separate JavaScript files (&ft==javascript), inside of
+<script> tag of (X)HTML and in values of event attributes (including scanning
+of external files.
+
+DOM compatibility
+
+At the moment (beginning of 2006) there are two main browsers - MS Internet
+Explorer and Mozilla Firefox. These two applications are covering over 90% of
+market. Theoretically standards are created by W3C organisation
+(http://www.w3c.org) but they are not always followed/implemented.
+
+		IE	FF	W3C  Omni completion ~
+		+/-	+/-	+    +		     ~
+		+	+	-    +		     ~
+		+	-	-    -		     ~
+		-	+	-    -		     ~
+
+Regardless from state of implementation in browsers but if element is defined
+in standards, completion plugin will place element in suggestion list. When
+both major engines implemented element, even if this is not in standards it
+will be suggested. All other elements are not placed in suggestion list.
+
+
+PHP							*ft-php-omni*
+
+Completion of PHP code requires a tags file for completion of data from
+external files and for class aware completion. You should use Exuberant ctags
+version 5.5.4 or newer. You can find it here: http://ctags.sourceforge.net/
+
+Script completes:
+
+- after $ variables name
+  - if variable was declared as object add "->", if tags file is available show
+    name of class
+  - after "->" complete only function and variable names specific for given
+    class. To find class location and contents tags file is required. Because
+    PHP isn't strongly typed language user can use @var tag to declare class: >
+
+	/* @var $myVar myClass */
+	$myVar->
+<
+    Still, to find myClass contents tags file is required.
+
+- function names with additional info:
+  - in case of built-in functions list of possible arguments and after | type
+    data returned by function
+  - in case of user function arguments and name of file were function was
+    defined (if it is not current file)
+
+- constants names
+- class names after "new" declaration
+
+
+Note: when doing completion first time Vim will load all necessary data into
+memory. It may take several seconds. After next use of completion delay
+should not be noticeable.
+
+Script detects if cursor is inside <?php ?> tags. If it is outside it will
+automatically switch to HTML/CSS/JavaScript completion. Note: contrary to
+original HTML files completion of tags (and only tags) isn't context aware.
+
+
+RUBY							*ft-ruby-omni*
+
+Completion of Ruby code requires that vim be built with |+ruby|.
+
+Ruby completion will parse your buffer on demand in order to provide a list of
+completions.  These completions will be drawn from modules loaded by 'require'
+and modules defined in the current buffer.
+
+The completions provided by CTRL-X CTRL-O are sensitive to the context:
+
+	  CONTEXT			   COMPLETIONS PROVIDED ~
+
+ 1. Not inside a class definition    Classes, constants and globals
+
+ 2. Inside a class definition	     Methods or constants defined in the class
+
+ 3. After '.', '::' or ':'	     Methods applicable to the object being
+				       dereferenced
+
+ 4. After ':' or ':foo'		     Symbol name (beginning with 'foo')
+
+Notes:
+ - Vim will load/evaluate code in order to provide completions.  This may
+   cause some code execution, which may be a concern. This is no longer 
+   enabled by default, to enable this feature add >
+     let g:rubycomplete_buffer_loading = 1
+<- In context 1 above, Vim can parse the entire buffer to add a list of
+   classes to the completion results. This feature is turned off by default,
+   to enable it add >
+     let g:rubycomplete_classes_in_global = 1
+<  to your vimrc
+ - In context 2 above, anonymous classes are not supported.
+ - In context 3 above, Vim will attempt to determine the methods supported by
+   the object.
+ - Vim can detect and load the Rails environment for files within a rails
+   project. The feature is disabled by default, to enable it add >
+     let g:rubycomplete_rails = 1
+<  to your vimrc
+
+
+SYNTAX							*ft-syntax-omni*
+
+Vim has the ability to color syntax highlight nearly 500 languages.  Part of
+this highlighting includes knowing what keywords are part of a language.  Many
+filetypes already have custom completion scripts written for them, the
+syntaxcomplete plugin provides basic completion for all other filetypes.  It
+does this by populating the omni completion list with the text Vim already
+knows how to color highlight.  It can be used for any filetype and provides a
+minimal language-sensitive completion.
+
+To enable syntax code completion you can run: >
+	setlocal omnifunc=syntaxcomplete#Complete
+
+You can automate this by placing the following in your vimrc (after any
+":filetype" command): >
+    if has("autocmd") && exists("+omnifunc")
+	autocmd Filetype *
+		    \	if &omnifunc == "" |
+		    \		setlocal omnifunc=syntaxcomplete#Complete |
+		    \	endif
+    endif
+
+The above will set completion to this script only if a specific plugin does
+not already exist for that filetype.
+
+Each filetype can have a wide range of syntax items.  The plugin allows you to
+customize which syntax groups to include or exclude from the list.  Let's have
+a look at the PHP filetype to see how this works.
+
+If you edit a file called, index.php, run the following command: >
+	:syntax list
+
+First thing you will notice is there are many different syntax groups.  The
+PHP language can include elements from different languages like HTML,
+JavaScript and many more.  The syntax plugin will only include syntax groups
+that begin with the filetype, "php", in this case.  For example these syntax
+groups are included by default with the PHP: phpEnvVar, phpIntVar,
+phpFunctions.
+
+The PHP language has an enormous number of items which it knows how to syntax
+highlight.  This means these items will be available within the omni
+completion list.  Some people may find this list unwieldy or are only
+interested in certain items.
+
+There are two ways to prune this list (if necessary).  If you find certain
+syntax groups you do not wish displayed you can add the following to your
+vimrc: >
+	let g:omni_syntax_group_exclude_php = 'phpCoreConstant,phpConstant'
+
+Add as many syntax groups to this list by comma separating them.  The basic
+form of this variable is: >
+	let g:omni_syntax_group_exclude_{filetype} = 'comma,separated,list'
+
+For completeness the opposite is also true.  Creating this variable in your
+vimrc will only include the items in the phpFunctions and phpMethods syntax
+groups: >
+	let g:omni_syntax_group_include_php = 'phpFunctions,phpMethods'
+
+You can create as many of these variables as you need, varying only the
+filetype at the end of the variable name.
+
+The plugin uses the isKeyword option to determine where word boundaries are
+for the syntax items.  For example, in the Scheme language completion should
+include the "-", call-with-output-file.  Depending on your filetype, this may
+not provide the words you are expecting.  Setting the
+g:omni_syntax_use_iskeyword option to 0 will force the syntax plugin to break
+on word characters.   This can be controlled adding the following to your
+vimrc: >
+    let g:omni_syntax_use_iskeyword = 0
+
+
+SQL							*ft-sql-omni*
+
+Completion for the SQL language includes statements, functions, keywords.
+It will also dynamically complete tables, procedures, views and column lists
+with data pulled directly from within a database.  For detailed instructions
+and a tutorial see |omni-sql-completion|.
+
+The SQL completion plugin can be used in conjunction with other completion
+plugins.  For example, the PHP filetype has it's own completion plugin.
+Since PHP is often used to generate dynamic website by accessing a database,
+the SQL completion plugin can also be enabled.  This allows you to complete
+PHP code and SQL code at the same time.
+
+
+XML							*ft-xml-omni*
+
+Vim 7 provides a mechanism for context aware completion of XML files.  It
+depends on a special |xml-omni-datafile| and two commands: |:XMLns| and
+|:XMLent|.  Features are:
+
+- after "<" complete the tag name, depending on context
+- inside of a tag complete proper attributes
+- when an attribute has a limited number of possible values help to complete
+  them
+- complete names of entities (defined in |xml-omni-datafile| and in the
+  current file with "<!ENTITY" declarations)
+- when used after "</" CTRL-X CTRL-O will close the last opened tag
+
+Format of XML data file					*xml-omni-datafile*
+
+XML data files are stored in the "autoload/xml" directory in 'runtimepath'.
+Vim distribution provides examples of data files in the
+"$VIMRUNTIME/autoload/xml" directory.  They have a meaningful name which will
+be used in commands.  It should be a unique name which will not create
+conflicts.  For example, the name xhtml10s.vim means it is the data file for
+XHTML 1.0 Strict.
+
+Each file contains a variable with a name like g:xmldata_xhtml10s . It is
+a compound from two parts:
+
+1. "g:xmldata_"  general prefix, constant for all data files
+2. "xhtml10s"    the name of the file and the name of the described XML
+		 dialect; it will be used as an argument for the |:XMLns|
+		 command
+
+Part two must be exactly the same as name of file.
+
+The variable is a |Dictionary|.  Keys are tag names and each value is a two
+element |List|.  The first element of the List is also a List with the names
+of possible children.  The second element is a |Dictionary| with the names of
+attributes as keys and the possible values of attributes as values.  Example: >
+
+    let g:xmldata_crippled = {
+    \ "vimxmlentities": ["amp", "lt", "gt", "apos", "quot"],
+    \ 'vimxmlroot': ['tag1'],
+    \ 'tag1':
+    \ [ ['childoftag1a', 'childoftag1b'], {'attroftag1a': [],
+    \ 'attroftag1b': ['valueofattr1', 'valueofattr2']}],
+    \ 'childoftag1a':
+    \ [ [], {'attrofchild': ['attrofchild']}],
+    \ 'childoftag1b':
+    \ [ ['childoftag1a'], {'attrofchild': []}],
+    \ "vimxmltaginfo": {
+    \ 'tag1': ['Menu info', 'Long information visible in preview window']},
+    \ 'vimxmlattrinfo': {
+    \ 'attrofchild': ['Menu info', 'Long information visible in preview window']}}
+
+This example would be put in the "autoload/xml/crippled.vim" file and could
+help to write this file: >
+
+    <tag1 attroftag1b="valueofattr1">
+        <childoftag1a attrofchild>
+                &amp; &lt;
+        </childoftag1a>
+        <childoftag1b attrofchild="5">
+            <childoftag1a>
+                &gt; &apos; &quot;
+            </childoftag1a>
+        </childoftag1b>
+    </tag1>
+
+In the example four special elements are visible:
+
+1. "vimxmlentities" - a special key with List containing entities of this XML
+   dialect.
+2. If the list containing possible values of attributes has one element and
+   this element is equal to the name of the attribute this attribute will be
+   treated as boolean and inserted as 'attrname' and not as 'attrname="'
+3. "vimxmltaginfo" - a special key with a Dictionary containing tag
+   names as keys and two element List as values, for additional menu info and
+   the long description.
+4. "vimxmlattrinfo" - special key with Dictionary containing attribute names
+   as keys and two element List as values, for additional menu info and long
+   description.
+
+Note: Tag names in the data file MUST not contain a namespace description.
+Check xsl.vim for an example.
+Note: All data and functions are publicly available as global
+variables/functions and can be used for personal editing functions.
+
+
+DTD -> Vim							*dtd2vim*
+
+On |www| is the script |dtd2vim| which parses DTD and creates an XML data file
+for Vim XML omni completion.
+
+    dtd2vim: http://www.vim.org/scripts/script.php?script_id=1462
+
+Check the beginning of that file for usage details.
+The script requires perl and:
+
+    perlSGML: http://savannah.nongnu.org/projects/perlsgml
+
+
+Commands
+
+:XMLns {name} [{namespace}]					*:XMLns*
+
+Vim has to know which data file should be used and with which namespace.  For
+loading of the data file and connecting data with the proper namespace use
+|:XMLns| command.  The first (obligatory) argument is the name of the data
+(xhtml10s, xsl).  The second argument is the code of namespace (h, xsl).  When
+used without a second argument the dialect will be used as default - without
+namespace declaration.  For example to use XML completion in .xsl files: >
+
+	:XMLns xhtml10s
+	:XMLns xsl xsl
+
+
+:XMLent {name}							*:XMLent*
+
+By default entities will be completed from the data file of the default
+namespace.  The XMLent command should be used in case when there is no default
+namespace: >
+
+	:XMLent xhtml10s
+
+Usage
+
+While used in this situation (after declarations from previous part, | is
+cursor position): >
+
+	<|
+
+Will complete to an appropriate XHTML tag, and in this situation: >
+
+	<xsl:|
+
+Will complete to an appropriate XSL tag.
+
+
+The script xmlcomplete.vim, provided through the |autoload| mechanism,
+has the xmlcomplete#GetLastOpenTag() function which can be used in XML files
+to get the name of the last open tag (b:unaryTagsStack has to be defined): >
+
+	:echo xmlcomplete#GetLastOpenTag("b:unaryTagsStack")
+
+
+
+==============================================================================
+8. Insert mode commands					*inserting*
+
+The following commands can be used to insert new text into the buffer.  They
+can all be undone and repeated with the "." command.
+
+							*a*
+a			Append text after the cursor [count] times.  If the
+			cursor is in the first column of an empty line Insert
+			starts there.  But not when 'virtualedit' is set!
+
+							*A*
+A			Append text at the end of the line [count] times.
+
+<insert>	or				*i* *insert* *<Insert>*
+i			Insert text before the cursor [count] times.
+			When using CTRL-O in Insert mode |i_CTRL-O| the count
+			is not supported.
+
+							*I*
+I			Insert text before the first non-blank in the line
+			[count] times.
+			When the 'H' flag is present in 'cpoptions' and the
+			line only contains blanks, insert start just before
+			the last blank.
+
+							*gI*
+gI			Insert text in column 1 [count] times.  {not in Vi}
+
+							*gi*
+gi			Insert text in the same position as where Insert mode
+			was stopped last time in the current buffer.
+			This uses the |'^| mark.  It's different from "`^i"
+			when the mark is past the end of the line.
+			The position is corrected for inserted/deleted lines,
+			but NOT for inserted/deleted characters.
+			When the |:keepjumps| command modifier is used the |'^|
+			mark won't be changed.
+			{not in Vi}
+
+							*o*
+o			Begin a new line below the cursor and insert text,
+			repeat [count] times.  {Vi: blank [count] screen
+			lines}
+			When the '#' flag is in 'cpoptions' the count is
+			ignored.
+
+							*O*
+O			Begin a new line above the cursor and insert text,
+			repeat [count] times.  {Vi: blank [count] screen
+			lines}
+			When the '#' flag is in 'cpoptions' the count is
+			ignored.
+
+These commands are used to start inserting text.  You can end insert mode with
+<Esc>.  See |mode-ins-repl| for the other special characters in Insert mode.
+The effect of [count] takes place after Insert mode is exited.
+
+When 'autoindent' is on, the indent for a new line is obtained from the
+previous line.  When 'smartindent' or 'cindent' is on, the indent for a line
+is automatically adjusted for C programs.
+
+'textwidth' can be set to the maximum width for a line.  When a line becomes
+too long when appending characters a line break is automatically inserted.
+
+
+==============================================================================
+9. Ex insert commands					*inserting-ex*
+
+							*:a* *:append*
+:{range}a[ppend][!]	Insert several lines of text below the specified
+			line.  If the {range} is missing, the text will be
+			inserted after the current line.
+			Adding [!] toggles 'autoindent' for the time this
+			command is executed.
+
+							*:i* *:in* *:insert*
+:{range}i[nsert][!]	Insert several lines of text above the specified
+			line.  If the {range} is missing, the text will be
+			inserted before the current line.
+			Adding [!] toggles 'autoindent' for the time this
+			command is executed.
+
+These two commands will keep on asking for lines, until you type a line
+containing only a ".".  Watch out for lines starting with a backslash, see
+|line-continuation|.
+When these commands are used with |:global| or |:vglobal| then the lines are
+obtained from the text following the command.  Separate lines with a NL
+escaped with a backslash: >
+	:global/abc/insert\
+	one line\
+	another line
+The final "." is not needed then.
+NOTE: ":append" and ":insert" don't work properly in between ":if" and
+":endif", ":for" and ":endfor", ":while" and ":endwhile".
+
+							*:start* *:startinsert*
+:star[tinsert][!]	Start Insert mode just after executing this command.
+			Works like typing "i" in Normal mode.  When the ! is
+			included it works like "A", append to the line.
+			Otherwise insertion starts at the cursor position.
+			Note that when using this command in a function or
+			script, the insertion only starts after the function
+			or script is finished.
+			This command does not work from |:normal|.
+			{not in Vi}
+			{not available when compiled without the +ex_extra
+			feature}
+
+							*:stopi* *:stopinsert*
+:stopi[nsert]		Stop Insert mode as soon as possible.  Works like
+			typing <Esc> in Insert mode.
+			Can be used in an autocommand, example: >
+				:au BufEnter scratch stopinsert
+<
+					*replacing-ex* *:startreplace*
+:startr[eplace][!]	Start Replace mode just after executing this command.
+			Works just like typing "R" in Normal mode.  When the
+			! is included it acts just like "$R" had been typed
+			(ie. begin replace mode at the end-of-line).  Other-
+			wise replacement begins at the cursor position.
+			Note that when using this command in a function or
+			script that the replacement will only start after
+			the function or script is finished.
+			{not in Vi}
+			{not available when compiled without the +ex_extra
+			feature}
+
+							*:startgreplace*
+:startg[replace][!]	Just like |:startreplace|, but use Virtual Replace
+			mode, like with |gR|.
+			{not in Vi}
+			{not available when compiled without the +ex_extra
+			feature}
+
+==============================================================================
+10. Inserting a file					*inserting-file*
+
+							*:r* *:re* *:read*
+:r[ead] [++opt] [name]
+			Insert the file [name] (default: current file) below
+			the cursor.
+			See |++opt| for the possible values of [++opt].
+
+:{range}r[ead] [++opt] [name]
+			Insert the file [name] (default: current file) below
+			the specified line.
+			See |++opt| for the possible values of [++opt].
+
+							*:r!* *:read!*
+:[range]r[ead] !{cmd}	Execute {cmd} and insert its standard output below
+			the cursor or the specified line.  A temporary file is
+			used to store the output of the command which is then
+			read into the buffer.  'shellredir' is used to save
+			the output of the command, which can be set to include
+			stderr or not.  {cmd} is executed like with ":!{cmd}",
+			any '!' is replaced with the previous command |:!|.
+
+These commands insert the contents of a file, or the output of a command,
+into the buffer.  They can be undone.  They cannot be repeated with the "."
+command.  They work on a line basis, insertion starts below the line in which
+the cursor is, or below the specified line.  To insert text above the first
+line use the command ":0r {name}".
+
+After the ":read" command, the cursor is left on the first non-blank in the
+first new line.  Unless in Ex mode, then the cursor is left on the last new
+line (sorry, this is Vi compatible).
+
+If a file name is given with ":r", it becomes the alternate file.  This can be
+used, for example, when you want to edit that file instead: ":e! #".  This can
+be switched off by removing the 'a' flag from the 'cpoptions' option.
+
+Of the [++opt] arguments one is specifically for ":read", the ++edit argument.
+This is useful when the ":read" command is actually used to read a file into
+the buffer as if editing that file.  Use this command in an empty buffer: >
+	:read ++edit filename
+The effect is that the 'fileformat', 'fileencoding', 'bomb', etc. options are
+set to what has been detected for "filename".  Note that a single empty line
+remains, you may want to delete it.
+
+							*file-read*
+The 'fileformat' option sets the <EOL> style for a file:
+'fileformat'    characters	   name				~
+  "dos"		<CR><NL> or <NL>   DOS format
+  "unix"	<NL>		   Unix format
+  "mac"		<CR>		   Mac format
+Previously 'textmode' was used.  It is obsolete now.
+
+If 'fileformat' is "dos", a <CR> in front of an <NL> is ignored and a CTRL-Z
+at the end of the file is ignored.
+
+If 'fileformat' is "mac", a <NL> in the file is internally represented by a
+<CR>.  This is to avoid confusion with a <NL> which is used to represent a
+<NUL>.  See |CR-used-for-NL|.
+
+If the 'fileformats' option is not empty Vim tries to recognize the type of
+<EOL> (see |file-formats|).  However, the 'fileformat' option will not be
+changed, the detected format is only used while reading the file.
+A similar thing happens with 'fileencodings'.
+
+On non-MS-DOS, Win32, and OS/2 systems the message "[dos format]" is shown if
+a file is read in DOS format, to remind you that something unusual is done.
+On Macintosh, MS-DOS, Win32, and OS/2 the message "[unix format]" is shown if
+a file is read in Unix format.
+On non-Macintosh systems, the message "[Mac format]" is shown if a file is
+read in Mac format.
+
+An example on how to use ":r !": >
+	:r !uuencode binfile binfile
+This command reads "binfile", uuencodes it and reads it into the current
+buffer.  Useful when you are editing e-mail and want to include a binary
+file.
+
+							*read-messages*
+When reading a file Vim will display a message with information about the read
+file.  In the table is an explanation for some of the items.  The others are
+self explanatory.  Using the long or the short version depends on the
+'shortmess' option.
+
+	long		short		meaning ~
+	[readonly]	{RO}		the file is write protected
+	[fifo/socket]			using a stream
+	[fifo]				using a fifo stream
+	[socket]			using a socket stream
+	[CR missing]			reading with "dos" 'fileformat' and a
+					NL without a preceding CR was found.
+	[NL found]			reading with "mac" 'fileformat' and a
+					NL was found (could be "unix" format)
+	[long lines split]		at least one line was split in two
+	[NOT converted]			conversion from 'fileencoding' to
+					'encoding' was desired but not
+					possible
+	[converted]			conversion from 'fileencoding' to
+					'encoding' done
+	[crypted]			file was decrypted
+	[READ ERRORS]			not all of the file could be read
+
+
+ vim:tw=78:ts=8:ft=help:norl:
--- /dev/null
+++ b/lib/vimfiles/doc/intro.txt
@@ -1,0 +1,881 @@
+*intro.txt*     For Vim version 7.1.  Last change: 2007 May 07
+
+
+		  VIM REFERENCE MANUAL    by Bram Moolenaar
+
+
+Introduction to Vim					*ref* *reference*
+
+1. Introduction			|intro|
+2. Vim on the internet		|internet|
+3. Credits			|credits|
+4. Notation			|notation|
+5. Modes, introduction		|vim-modes-intro|
+6. Switching from mode to mode	|mode-switching|
+7. The window contents		|window-contents|
+8. Definitions			|definitions|
+
+==============================================================================
+1. Introduction						*intro*
+
+Vim stands for Vi IMproved.  It used to be Vi IMitation, but there are so many
+improvements that a name change was appropriate.  Vim is a text editor which
+includes almost all the commands from the Unix program "Vi" and a lot of new
+ones.  It is very useful for editing programs and other plain text.
+   All commands are given with the keyboard.  This has the advantage that you
+can keep your fingers on the keyboard and your eyes on the screen.  For those
+who want it, there is mouse support and a GUI version with scrollbars and
+menus (see |gui.txt|).
+
+An overview of this manual can be found in the file "help.txt", |help.txt|.
+It can be accessed from within Vim with the <Help> or <F1> key and with the
+|:help| command (just type ":help", without the bars or quotes).
+   The 'helpfile' option can be set to the name of the help file, in case it
+is not located in the default place.  You can jump to subjects like with tags:
+Use CTRL-] to jump to a subject under the cursor, use CTRL-T to jump back.
+
+Throughout this manual the differences between Vi and Vim are mentioned in
+curly braces, like this: {Vi does not have on-line help}.  See |vi_diff.txt|
+for a summary of the differences between Vim and Vi.
+
+This manual refers to Vim on various machines.  There may be small differences
+between different computers and terminals.  Besides the remarks given in this
+document, there is a separate document for each supported system, see
+|sys-file-list|.
+
+This manual is a reference for all the Vim commands and options.  This is not
+an introduction to the use of Vi or Vim, it gets a bit complicated here and
+there.  For beginners, there is a hands-on |tutor|.  To learn using Vim, read
+the user manual |usr_toc.txt|.
+
+							*book*
+There are many books on Vi that contain a section for beginners.  There are
+two books I can recommend:
+
+	"Vim - Vi Improved" by Steve Oualline
+
+This is the very first book completely dedicated to Vim.  It is very good for
+beginners.  The most often used commands are explained with pictures and
+examples.  The less often used commands are also explained, the more advanced
+features are summarized.  There is a comprehensive index and a quick
+reference.  Parts of this book have been included in the user manual
+|frombook|.
+Published by New Riders Publishing.  ISBN: 0735710015
+For more information try one of these:
+	http://iccf-holland.org/click5.html
+	http://www.vim.org/iccf/click5.html
+
+	"Learning the Vi editor" by Linda Lamb and Arnold Robbins
+
+This is a book about Vi that includes a chapter on Vim (in the sixth edition).
+The first steps in Vi are explained very well.  The commands that Vim adds are
+only briefly mentioned.  There is also a German translation.
+Published by O'Reilly.  ISBN: 1-56592-426-6.
+
+==============================================================================
+2. Vim on the internet					*internet*
+
+			*www* *WWW*  *faq* *FAQ* *distribution* *download*
+The Vim pages contain the most recent information about Vim.  They also
+contain links to the most recent version of Vim.  The FAQ is a list of
+Frequently Asked Questions.  Read this if you have problems.
+
+	VIM home page:	  http://www.vim.org/
+	VIM FAQ:	  http://vimdoc.sf.net/
+	Downloading:	  ftp://ftp.vim.org/pub/vim/MIRRORS
+
+
+Usenet News group where Vim is discussed:		*news* *usenet*
+	comp.editors
+This group is also for other editors.  If you write about Vim, don't forget to
+mention that.
+
+						*mail-list* *maillist*
+There are several mailing lists for Vim:
+<vim@vim.org>
+	For discussions about using existing versions of Vim: Useful mappings,
+	questions, answers, where to get a specific version, etc.  There are
+	quite a few people watching this list and answering questions, also
+	for beginners.  Don't hesitate to ask your question here.
+<vim-dev@vim.org>				*vim-dev* *vimdev*
+	For discussions about changing Vim: New features, porting, patches,
+	beta-test versions, etc.
+<vim-announce@vim.org>				*vim-announce*
+	Announcements about new versions of Vim; also for beta-test versions
+	and ports to different systems.  This is a read-only list.
+<vim-multibyte@vim.org>				*vim-multibyte*
+	For discussions about using and improving the multi-byte aspects of
+	Vim.
+<vim-mac@vim.org>				*vim-mac*
+	For discussions about using and improving the Macintosh version of
+	Vim.
+
+See http://www.vim.org/maillist.php for the latest information.
+
+NOTE:
+- You can only send messages to these lists if you have subscribed!
+- You need to send the messages from the same location as where you subscribed
+  from (to avoid spam mail).
+- Maximum message size is 40000 characters.
+
+						*subscribe-maillist*
+If you want to join, send a message to
+	<vim-help@vim.org>
+Make sure that your "From:" address is correct.  Then the list server will
+give you help on how to subscribe.
+
+You can retrieve old messages from the maillist software, and an index of
+messages.  Ask vim-help for instructions.
+
+Archives are kept at:				*maillist-archive*
+http://groups.yahoo.com/group/vim
+http://groups.yahoo.com/group/vimdev
+http://groups.yahoo.com/group/vimannounce
+http://groups.yahoo.com/group/vim-multibyte
+http://groups.yahoo.com/group/vim-mac
+
+
+Additional maillists:
+
+<vim-fr@club.voila.fr>				*french-maillist*
+	Vim list in the French language.  Subscribe by sending a message to
+		<vim-fr-subscribe@club.voila.fr>
+	Or go to http://groups.yahoo.com/group/vim-fr.
+
+
+Bug reports:				*bugs* *bug-reports* *bugreport.vim*
+
+Send bug reports to: Vim bugs <bugs@vim.org>
+This is not a maillist but the message is redirected to the Vim maintainer.
+Please be brief; all the time that is spent on answering mail is subtracted
+from the time that is spent on improving Vim!  Always give a reproducible
+example and try to find out which settings or other things influence the
+appearance of the bug.  Try different machines, if possible.  Send me patches
+if you can!
+
+It will help to include information about the version of Vim you are using and
+your setup.  You can get the information with this command: >
+   :so $VIMRUNTIME/bugreport.vim
+This will create a file "bugreport.txt" in the current directory, with a lot
+of information of your environment.  Before sending this out, check if it
+doesn't contain any confidential information!
+
+If Vim crashes, please try to find out where.  You can find help on this here:
+|debug.txt|.
+
+In case of doubt or when you wonder if the problem has already been fixed but
+you can't find a fix for it, become a member of the vim-dev maillist and ask
+your question there. |maillist|
+
+							*year-2000* *Y2K*
+Since Vim internally doesn't use dates for editing, there is no year 2000
+problem to worry about.  Vim does use the time in the form of seconds since
+January 1st 1970.  It is used for a time-stamp check of the edited file and
+the swap file, which is not critical and should only cause warning messages.
+
+There might be a year 2038 problem, when the seconds don't fit in a 32 bit int
+anymore.  This depends on the compiler, libraries and operating system.
+Specifically, time_t and the ctime() function are used.  And the time_t is
+stored in four bytes in the swap file.  But that's only used for printing a
+file date/time for recovery, it will never affect normal editing.
+
+The Vim strftime() function directly uses the strftime() system function.
+localtime() uses the time() system function.  getftime() uses the time
+returned by the stat() system function.  If your system libraries are year
+2000 compliant, Vim is too.
+
+The user may create scripts for Vim that use external commands.  These might
+introduce Y2K problems, but those are not really part of Vim itself.
+
+==============================================================================
+3. Credits				*credits* *author* *Bram* *Moolenaar*
+
+Most of Vim was written by Bram Moolenaar <Bram@vim.org>.
+
+Parts of the documentation come from several Vi manuals, written by:
+	W.N. Joy
+	Alan P.W. Hewett
+	Mark Horton
+
+The Vim editor is based on Stevie and includes (ideas from) other software,
+worked on by the people mentioned here.  Other people helped by sending me
+patches, suggestions and giving feedback about what is good and bad in Vim.
+
+Vim would never have become what it is now, without the help of these people!
+
+	Ron Aaron		Win32 GUI changes
+	Zoltan Arpadffy		work on VMS port
+	Tony Andrews		Stevie
+	Gert van Antwerpen	changes for DJGPP on MS-DOS
+	Berkeley DB(3)		ideas for swap file implementation
+	Keith Bostic		Nvi
+	Walter Briscoe		Makefile updates, various patches
+	Ralf Brown		SPAWNO library for MS-DOS
+	Robert Colon		many useful remarks
+	Marcin Dalecki		GTK+ GUI port, toolbar icons, gettext()
+	Kayhan Demirel		sent me news in Uganda
+	Chris & John Downey	xvi (ideas for multi-windows version)
+	Henk Elbers		first VMS port
+	Daniel Elstner		GTK+ 2 port
+	Eric Fischer		Mac port, 'cindent', and other improvements
+	Benji Fisher		Answering lots of user questions
+	Bill Foster		Athena GUI port
+	Loic Grenie		xvim (ideas for multi windows version)
+	Sven Guckes		Vim promotor and previous WWW page maintainer
+	Darren Hiebert		Exuberant ctags
+	Jason Hildebrand	GTK+ 2 port
+	Bruce Hunsaker		improvements for VMS port
+	Andy Kahn		Cscope support, GTK+ GUI port
+	Oezguer Kesim		Maintainer of Vim Mailing Lists
+	Axel Kielhorn		work on the Macintosh port
+	Steve Kirkendall	Elvis
+	Roger Knobbe		original port to Windows NT
+	Sergey Laskavy		Vim's help from Moscow
+	Felix von Leitner	Maintainer of Vim Mailing Lists
+	David Leonard		Port of Python extensions to Unix
+	Avner Lottem		Edit in right-to-left windows
+	Flemming Madsen		X11 client-server, various features and patches
+	Microsoft		Gave me a copy of DevStudio to compile Vim with
+	Paul Moore		Python interface extensions, many patches
+	Katsuhito Nagano	Work on multi-byte versions
+	Sung-Hyun Nam		Work on multi-byte versions
+	Vince Negri		Win32 GUI and generic console enhancements
+	Steve Oualline		Author of the first Vim book |frombook|
+	George V. Reilly	Win32 port, Win32 GUI start-off
+	Stephen Riehm		bug collector
+	Stefan Roemer		various patches and help to users
+	Ralf Schandl		IBM OS/390 port
+	Olaf Seibert		DICE and BeBox version, regexp improvements
+	Mortaza Shiran		Farsi patches
+	Peter da Silva		termlib
+	Paul Slootman		OS/2 port
+	Henry Spencer		regular expressions
+	Dany St-Amant		Macintosh port
+	Tim Thompson		Stevie
+	G. R. (Fred) Walter	Stevie
+	Sven Verdoolaege	Perl interface
+	Robert Webb		Command-line completion, GUI versions, and
+				lots of patches
+	Ingo Wilken		Tcl interface
+	Mike Williams		PostScript printing
+	Juergen Weigert		Lattice version, AUX improvements, UNIX and
+				MS-DOS ports, autoconf
+	Stefan 'Sec' Zehl	Maintainer of vim.org
+
+I wish to thank all the people that sent me bug reports and suggestions.  The
+list is too long to mention them all here.  Vim would not be the same without
+the ideas from all these people: They keep Vim alive!
+
+
+In this documentation there are several references to other versions of Vi:
+							*Vi* *vi*
+Vi	"the original".  Without further remarks this is the version
+	of Vi that appeared in Sun OS 4.x.  ":version" returns
+	"Version 3.7, 6/7/85".  Sometimes other versions are referred
+	to.  Only runs under Unix.  Source code only available with a
+	license.  More information on Vi can be found through:
+		http://vi-editor.org	[doesn't currently work...]
+							*Posix*
+Posix	From the IEEE standard 1003.2, Part 2: Shell and utilities.
+	Generally known as "Posix".  This is a textual description of
+	how Vi is supposed to work.
+	See |posix-compliance|.
+							*Nvi*
+Nvi	The "New" Vi.  The version of Vi that comes with BSD 4.4 and FreeBSD.
+	Very good compatibility with the original Vi, with a few extensions.
+	The version used is 1.79.  ":version" returns "Version 1.79
+	(10/23/96)".  There has been no release the last few years, although
+	there is a development version 1.81.
+	Source code is freely available.
+							*Elvis*
+Elvis	Another Vi clone, made by Steve Kirkendall.  Very compact but isn't
+	as flexible as Vim.
+	The version used is 2.1.  It is still being developed.  Source code is
+	freely available.
+
+==============================================================================
+4. Notation						*notation*
+
+When syntax highlighting is used to read this, text that is not typed
+literally is often highlighted with the Special group.  These are items in [],
+{} and <>, and CTRL-X.
+
+Note that Vim uses all possible characters in commands.  Sometimes the [], {}
+and <> are part of what you type, the context should make this clear.
+
+
+[]		Characters in square brackets are optional.
+
+						    *count* *[count]* *E489*
+[count]		An optional number that may precede the command to multiply
+		or iterate the command.  If no number is given, a count of one
+		is used, unless otherwise noted.  Note that in this manual the
+		[count] is not mentioned in the description of the command,
+		but only in the explanation.  This was done to make the
+		commands easier to look up.  If the 'showcmd' option is on,
+		the (partially) entered count is shown at the bottom of the
+		window.  You can use <Del> to erase the last digit (|N<Del>|).
+
+							*[quotex]*
+["x]		An optional register designation where text can be stored.
+		See |registers|.  The x is a single character between 'a' and
+		'z' or 'A' and 'Z' or '"', and in some cases (with the put
+		command) between '0' and '9', '%', '#', or others.  The
+		uppercase and lowercase letter designate the same register,
+		but the lowercase letter is used to overwrite the previous
+		register contents, while the uppercase letter is used to
+		append to the previous register contents.  Without the ""x" or
+		with """" the stored text is put into the unnamed register.
+
+							*{}*
+{}		Curly braces denote parts of the command which must appear,
+		but which can take a number of different values.  The
+		differences between Vim and Vi are also given in curly braces
+		(this will be clear from the context).
+
+							*{char1-char2}*
+{char1-char2}	A single character from the range char1 to char2.  For
+		example: {a-z} is a lowercase letter.  Multiple ranges may be
+		concatenated.  For example, {a-zA-Z0-9} is any alphanumeric
+		character.
+
+						*{motion}* *movement*
+{motion}	A command that moves the cursor.  These are explained in
+		|motion.txt|.  Examples:
+			w		to start of next word
+			b		to begin of current word
+			4j		four lines down
+			/The<CR>	to next occurrence of "The"
+		This is used after an |operator| command to move over the text
+		that is to be operated upon.
+		- If the motion includes a count and the operator also has a
+		  count, the two counts are multiplied.  For example: "2d3w"
+		  deletes six words.
+		- The motion can be backwards, e.g. "db" to delete to the
+		  start of the word.
+		- The motion can also be a mouse click.  The mouse is not
+		  supported in every terminal though.
+		- The ":omap" command can be used to map characters while an
+		  operator is pending.
+		- Ex commands can be used to move the cursor.  This can be
+		  used to call a function that does some complicated motion.
+		  The motion is always characterwise exclusive, no matter
+		  what ":" command is used.  This means it's impossible to
+		  include the last character of a line without the line break
+		  (unless 'virtualedit' is set).
+		  If the Ex command changes the text before where the operator
+		  starts or jumps to another buffer the result is
+		  unpredictable.  It is possible to change the text further
+		  down.  Jumping to another buffer is possible if the current
+		  buffer is not unloaded.
+
+							*{Visual}*
+{Visual}	A selected text area.  It is started with the "v", "V", or
+		CTRL-V command, then any cursor movement command can be used
+		to change the end of the selected text.
+		This is used before an |operator| command to highlight the
+		text that is to be operated upon.
+		See |Visual-mode|.
+
+							*<character>*
+<character>	A special character from the table below, optionally with
+		modifiers, or a single ASCII character with modifiers.
+
+							*'character'*
+'c'		A single ASCII character.
+
+							*CTRL-{char}*
+CTRL-{char}	{char} typed as a control character; that is, typing {char}
+		while holding the CTRL key down.  The case of {char} does not
+		matter; thus CTRL-A and CTRL-a are equivalent.  But on some
+		terminals, using the SHIFT key will produce another code,
+		don't use it then.
+
+							*'option'*
+'option'	An option, or parameter, that can be set to a value, is
+		enclosed in single quotes.  See |options|.
+
+							*quotecommandquote*
+"command"	A reference to a command that you can type is enclosed in
+		double quotes.
+
+					*key-notation* *key-codes* *keycodes*
+These names for keys are used in the documentation.  They can also be used
+with the ":map" command (insert the key name by pressing CTRL-K and then the
+key you want the name for).
+
+notation	meaning		    equivalent	decimal value(s)	~
+-----------------------------------------------------------------------
+<Nul>		zero			CTRL-@	  0 (stored as 10) *<Nul>*
+<BS>		backspace		CTRL-H	  8	*backspace*
+<Tab>		tab			CTRL-I	  9	*tab* *Tab*
+							*linefeed*
+<NL>		linefeed		CTRL-J	 10 (used for <Nul>)
+<FF>		formfeed		CTRL-L	 12	*formfeed*
+<CR>		carriage return		CTRL-M	 13	*carriage-return*
+<Return>	same as <CR>				*<Return>*
+<Enter>		same as <CR>				*<Enter>*
+<Esc>		escape			CTRL-[	 27	*escape* *<Esc>*
+<Space>		space				 32	*space*
+<lt>		less-than		<	 60	*<lt>*
+<Bslash>	backslash		\	 92	*backslash* *<Bslash>*
+<Bar>		vertical bar		|	124	*<Bar>*
+<Del>		delete				127
+<CSI>		command sequence intro  ALT-Esc 155	*<CSI>*
+<xCSI>		CSI when typed in the GUI		*<xCSI>*
+
+<EOL>		end-of-line (can be <CR>, <LF> or <CR><LF>,
+		depends on system and 'fileformat')	*<EOL>*
+
+<Up>		cursor-up			*cursor-up* *cursor_up*
+<Down>		cursor-down			*cursor-down* *cursor_down*
+<Left>		cursor-left			*cursor-left* *cursor_left*
+<Right>		cursor-right			*cursor-right* *cursor_right*
+<S-Up>		shift-cursor-up
+<S-Down>	shift-cursor-down
+<S-Left>	shift-cursor-left
+<S-Right>	shift-cursor-right
+<C-Left>	control-cursor-left
+<C-Right>	control-cursor-right
+<F1> - <F12>	function keys 1 to 12		*function_key* *function-key*
+<S-F1> - <S-F12> shift-function keys 1 to 12	*<S-F1>*
+<Help>		help key
+<Undo>		undo key
+<Insert>	insert key
+<Home>		home				*home*
+<End>		end				*end*
+<PageUp>	page-up				*page_up* *page-up*
+<PageDown>	page-down			*page_down* *page-down*
+<kHome>		keypad home (upper left)	*keypad-home*
+<kEnd>		keypad end (lower left)		*keypad-end*
+<kPageUp>	keypad page-up (upper right)	*keypad-page-up*
+<kPageDown>	keypad page-down (lower right)	*keypad-page-down*
+<kPlus>		keypad +			*keypad-plus*
+<kMinus>	keypad -			*keypad-minus*
+<kMultiply>	keypad *			*keypad-multiply*
+<kDivide>	keypad /			*keypad-divide*
+<kEnter>	keypad Enter			*keypad-enter*
+<kPoint>	keypad Decimal point		*keypad-point*
+<k0> - <k9>	keypad 0 to 9			*keypad-0* *keypad-9*
+<S-...>		shift-key			*shift* *<S-*
+<C-...>		control-key			*control* *ctrl* *<C-*
+<M-...>		alt-key or meta-key		*meta* *alt* *<M-*
+<A-...>		same as <M-...>			*<A-*
+<D-...>		command-key (Macintosh only)	*<D-*
+<t_xx>		key with "xx" entry in termcap
+-----------------------------------------------------------------------
+
+Note: The shifted cursor keys, the help key, and the undo key are only
+available on a few terminals.  On the Amiga, shifted function key 10 produces
+a code (CSI) that is also used by key sequences.  It will be recognized only
+after typing another key.
+
+Note: There are two codes for the delete key.  127 is the decimal ASCII value
+for the delete key, which is always recognized.  Some delete keys send another
+value, in which case this value is obtained from the termcap entry "kD".  Both
+values have the same effect.  Also see |:fixdel|.
+
+Note: The keypad keys are used in the same way as the corresponding "normal"
+keys.  For example, <kHome> has the same effect as <Home>.  If a keypad key
+sends the same raw key code as its non-keypad equivalent, it will be
+recognized as the non-keypad code.  For example, when <kHome> sends the same
+code as <Home>, when pressing <kHome> Vim will think <Home> was pressed.
+Mapping <kHome> will not work then.
+
+								*<>*
+Examples are often given in the <> notation.  Sometimes this is just to make
+clear what you need to type, but often it can be typed literally, e.g., with
+the ":map" command.  The rules are:
+ 1.  Any printable characters are typed directly, except backslash and '<'
+ 2.  A backslash is represented with "\\", double backslash, or "<Bslash>".
+ 3.  A real '<' is represented with "\<" or "<lt>".  When there is no
+     confusion possible, a '<' can be used directly.
+ 4.  "<key>" means the special key typed.  This is the notation explained in
+     the table above.  A few examples:
+	   <Esc>		Escape key
+	   <C-G>		CTRL-G
+	   <Up>			cursor up key
+	   <C-LeftMouse>	Control- left mouse click
+	   <S-F11>		Shifted function key 11
+	   <M-a>		Meta- a  ('a' with bit 8 set)
+	   <M-A>		Meta- A  ('A' with bit 8 set)
+	   <t_kd>		"kd" termcap entry (cursor down key)
+
+If you want to use the full <> notation in Vim, you have to make sure the '<'
+flag is excluded from 'cpoptions' (when 'compatible' is not set, it already is
+by default). >
+	:set cpo-=<
+The <> notation uses <lt> to escape the special meaning of key names.  Using a
+backslash also works, but only when 'cpoptions' does not include the 'B' flag.
+
+Examples for mapping CTRL-H to the six characters "<Home>": >
+	:imap <C-H> \<Home>
+	:imap <C-H> <lt>Home>
+The first one only works when the 'B' flag is not in 'cpoptions'.  The second
+one always works.
+To get a literal "<lt>" in a mapping: >
+	:map <C-L> <lt>lt>
+
+For mapping, abbreviation and menu commands you can then copy-paste the
+examples and use them directly.  Or type them literally, including the '<' and
+'>' characters.  This does NOT work for other commands, like ":set" and
+":autocmd"!
+
+==============================================================================
+5. Modes, introduction				*vim-modes-intro* *vim-modes*
+
+Vim has six BASIC modes:
+
+					*Normal* *Normal-mode* *command-mode*
+Normal mode		In Normal mode you can enter all the normal editor
+			commands.  If you start the editor you are in this
+			mode (unless you have set the 'insertmode' option,
+			see below).  This is also known as command mode.
+
+Visual mode		This is like Normal mode, but the movement commands
+			extend a highlighted area.  When a non-movement
+			command is used, it is executed for the highlighted
+			area.  See |Visual-mode|.
+			If the 'showmode' option is on "-- VISUAL --" is shown
+			at the bottom of the window.
+
+Select mode		This looks most like the MS-Windows selection mode.
+			Typing a printable character deletes the selection
+			and starts Insert mode.  See |Select-mode|.
+			If the 'showmode' option is on "-- SELECT --" is shown
+			at the bottom of the window.
+
+Insert mode		In Insert mode the text you type is inserted into the
+			buffer.  See |Insert-mode|.
+			If the 'showmode' option is on "-- INSERT --" is shown
+			at the bottom of the window.
+
+Command-line mode	In Command-line mode (also called Cmdline mode) you
+Cmdline mode		can enter one line of text at the bottom of the
+			window.  This is for the Ex commands, ":", the pattern
+			search commands, "?" and "/", and the filter command,
+			"!".  |Cmdline-mode|
+
+Ex mode			Like Command-line mode, but after entering a command
+			you remain in Ex mode.  Very limited editing of the
+			command line.  |Ex-mode|
+
+There are five ADDITIONAL modes.  These are variants of the BASIC modes:
+
+				*Operator-pending* *Operator-pending-mode*
+Operator-pending mode	This is like Normal mode, but after an operator
+			command has started, and Vim is waiting for a {motion}
+			to specify the text that the operator will work on.
+
+Replace mode		Replace mode is a special case of Insert mode.  You
+			can do the same things as in Insert mode, but for
+			each character you enter, one character of the existing
+			text is deleted.  See |Replace-mode|.
+			If the 'showmode' option is on "-- REPLACE --" is
+			shown at the bottom of the window.
+
+Insert Normal mode	Entered when CTRL-O given in Insert mode.  This is
+			like Normal mode, but after executing one command Vim
+			returns to Insert mode.
+			If the 'showmode' option is on "-- (insert) --" is
+			shown at the bottom of the window.
+
+Insert Visual mode	Entered when starting a Visual selection from Insert
+			mode, e.g., by using CTRL-O and then "v", "V" or
+			CTRL-V.  When the Visual selection ends, Vim returns
+			to Insert mode.
+			If the 'showmode' option is on "-- (insert) VISUAL --"
+			is shown at the bottom of the window.
+
+Insert Select mode	Entered when starting Select mode from Insert mode.
+			E.g., by dragging the mouse or <S-Right>.
+			When the Select mode ends, Vim returns to Insert mode.
+			If the 'showmode' option is on "-- (insert) SELECT --"
+			is shown at the bottom of the window.
+
+==============================================================================
+6. Switching from mode to mode				*mode-switching*
+
+If for any reason you do not know which mode you are in, you can always get
+back to Normal mode by typing <Esc> twice.  This doesn't work for Ex mode
+though, use ":visual".
+You will know you are back in Normal mode when you see the screen flash or
+hear the bell after you type <Esc>.  However, when pressing <Esc> after using
+CTRL-O in Insert mode you get a beep but you are still in Insert mode, type
+<Esc> again.
+
+							*i_esc*
+		TO mode						    ~
+		Normal	Visual	Select	Insert	  Replace   Cmd-line  Ex ~
+FROM mode								 ~
+Normal			v V ^V	  *4	 *1	    R	    : / ? !   Q
+Visual		 *2		  ^G	 c C	    --	      :       --
+Select		 *5	^O ^G		 *6	    --	      --      --
+Insert		 <Esc>	  --	  --		  <Insert>    --      --
+Replace		 <Esc>	  --	  --	<Insert>	      --      --
+Command-line	 *3	  --	  --	 :start	    --		      --
+Ex		 :vi	  --	  --	 --	    --	      --
+
+-  NA
+-- not possible
+
+*1 Go from Normal mode to Insert mode by giving the command "i", "I", "a",
+   "A", "o", "O", "c", "C", "s" or S".
+*2 Go from Visual mode to Normal mode by giving a non-movement command, which
+   causes the command to be executed, or by hitting <Esc> "v", "V" or "CTRL-V"
+   (see |v_v|), which just stops Visual mode without side effects.
+*3 Go from Command-line mode to Normal mode by:
+   - Hitting <CR> or <NL>, which causes the entered command to be executed.
+   - Deleting the complete line (e.g., with CTRL-U) and giving a final <BS>.
+   - Hitting CTRL-C or <Esc>, which quits the command-line without executing
+     the command.
+   In the last case <Esc> may be the character defined with the 'wildchar'
+   option, in which case it will start command-line completion.  You can
+   ignore that and type <Esc> again.  {Vi: when hitting <Esc> the command-line
+   is executed.  This is unexpected for most people; therefore it was changed
+   in Vim.  But when the <Esc> is part of a mapping, the command-line is
+   executed.  If you want the Vi behaviour also when typing <Esc>, use ":cmap
+   ^V<Esc> ^V^M"}
+*4 Go from Normal to Select mode by:
+   - use the mouse to select text while 'selectmode' contains "mouse"
+   - use a non-printable command to move the cursor while keeping the Shift
+     key pressed, and the 'selectmode' option contains "key"
+   - use "v", "V" or "CTRL-V" while 'selectmode' contains "cmd"
+   - use "gh", "gH" or "g CTRL-H"  |g_CTRL-H|
+*5 Go from Select mode to Normal mode by using a non-printable command to move
+   the cursor, without keeping the Shift key pressed.
+*6 Go from Select mode to Insert mode by typing a printable character.  The
+   selection is deleted and the character is inserted.
+
+If the 'insertmode' option is on, editing a file will start in Insert mode.
+
+	*CTRL-\_CTRL-N* *i_CTRL-\_CTRL-N* *c_CTRL-\_CTRL-N* *v_CTRL-\_CTRL-N*
+Additionally the command CTRL-\ CTRL-N or <C-\><C-N> can be used to go to
+Normal mode from any other mode.  This can be used to make sure Vim is in
+Normal mode, without causing a beep like <Esc> would.  However, this does not
+work in Ex mode.  When used after a command that takes an argument, such as
+|f| or |m|, the timeout set with 'ttimeoutlen' applies.
+
+	*CTRL-\_CTRL-G* *i_CTRL-\_CTRL-G* *c_CTRL-\_CTRL-G* *v_CTRL-\_CTRL-G*
+The command CTRL-\ CTRL-G or <C-\><C-G> can be used to go to Insert mode when
+'insertmode' is set.  Otherwise it goes to Normal mode.  This can be used to
+make sure Vim is in the mode indicated by 'insertmode', without knowing in
+what mode Vim currently is.
+
+				    *Q* *mode-Ex* *Ex-mode* *Ex* *EX* *E501*
+Q			Switch to "Ex" mode.  This is a bit like typing ":"
+			commands one after another, except:
+			- You don't have to keep pressing ":".
+			- The screen doesn't get updated after each command.
+			- There is no normal command-line editing.
+			- Mappings and abbreviations are not used.
+			In fact, you are editing the lines with the "standard"
+			line-input editing commands (<Del> or <BS> to erase,
+			CTRL-U to kill the whole line).
+			Vim will enter this mode by default if it's invoked as
+			"ex" on the command-line.
+			Use the ":vi" command |:visual| to exit "Ex" mode.
+			Note: In older versions of Vim "Q" formatted text,
+			that is now done with |gq|.  But if you use the
+			|vimrc_example.vim| script "Q" works like "gq".
+
+					*gQ*
+gQ			Switch to "Ex" mode like with "Q", but really behave
+			like typing ":" commands after another.  All command
+			line editing, completion etc. is available.
+			Use the ":vi" command |:visual| to exit "Ex" mode.
+			{not in Vi}
+
+==============================================================================
+7. The window contents					*window-contents*
+
+In Normal mode and Insert/Replace mode the screen window will show the current
+contents of the buffer: What You See Is What You Get.  There are two
+exceptions:
+- When the 'cpoptions' option contains '$', and the change is within one line,
+  the text is not directly deleted, but a '$' is put at the last deleted
+  character.
+- When inserting text in one window, other windows on the same text are not
+  updated until the insert is finished.
+{Vi: The screen is not always updated on slow terminals}
+
+Lines longer than the window width will wrap, unless the 'wrap' option is off
+(see below).  The 'linebreak' option can be set to wrap at a blank character.
+
+If the window has room after the last line of the buffer, Vim will show '~' in
+the first column of the last lines in the window, like this: >
+
+	+-----------------------+
+	|some line		|
+	|last line		|
+	|~			|
+	|~			|
+	+-----------------------+
+
+Thus the '~' lines indicate that the end of the buffer was reached.
+
+If the last line in a window doesn't fit, Vim will indicate this with a '@' in
+the first column of the last lines in the window, like this: >
+
+	+-----------------------+
+	|first line		|
+	|second line		|
+	|@			|
+	|@			|
+	+-----------------------+
+
+Thus the '@' lines indicate that there is a line that doesn't fit in the
+window.
+
+When the "lastline" flag is present in the 'display' option, you will not see
+'@' characters at the left side of window.  If the last line doesn't fit
+completely, only the part that fits is shown, and the last three characters of
+the last line are replaced with "@@@", like this: >
+
+	+-----------------------+
+	|first line		|
+	|second line		|
+	|a very long line that d|
+	|oesn't fit in the wi@@@|
+	+-----------------------+
+
+If there is a single line that is too long to fit in the window, this is a
+special situation.  Vim will show only part of the line, around where the
+cursor is.  There are no special characters shown, so that you can edit all
+parts of this line.
+{Vi: gives an "internal error" on lines that do not fit in the window}
+
+The '@' occasion in the 'highlight' option can be used to set special
+highlighting for the '@' and '~' characters.  This makes it possible to
+distinguish them from real characters in the buffer.
+
+The 'showbreak' option contains the string to put in front of wrapped lines.
+
+							*wrap-off*
+If the 'wrap' option is off, long lines will not wrap.  Only the part that
+fits on the screen is shown.  If the cursor is moved to a part of the line
+that is not shown, the screen is scrolled horizontally.  The advantage of
+this method is that columns are shown as they are and lines that cannot fit
+on the screen can be edited.  The disadvantage is that you cannot see all the
+characters of a line at once.  The 'sidescroll' option can be set to the
+minimal number of columns to scroll.  {Vi: has no 'wrap' option}
+
+All normal ASCII characters are displayed directly on the screen.  The <Tab>
+is replaced with the number of spaces that it represents.  Other non-printing
+characters are replaced with "^{char}", where {char} is the non-printing
+character with 64 added.  Thus character 7 (bell) will be shown as "^G".
+Characters between 127 and 160 are replaced with "~{char}", where {char} is
+the character with 64 subtracted.  These characters occupy more than one
+position on the screen.  The cursor can only be positioned on the first one.
+
+If you set the 'number' option, all lines will be preceded with their
+number.  Tip: If you don't like wrapping lines to mix with the line numbers,
+set the 'showbreak' option to eight spaces:
+	":set showbreak=\ \ \ \ \ \ \ \ "
+
+If you set the 'list' option, <Tab> characters will not be shown as several
+spaces, but as "^I".  A '$' will be placed at the end of the line, so you can
+find trailing blanks.
+
+In Command-line mode only the command-line itself is shown correctly.  The
+display of the buffer contents is updated as soon as you go back to Command
+mode.
+
+The last line of the window is used for status and other messages.  The
+status messages will only be used if an option is on:
+
+status message			option	     default	Unix default	~
+current mode			'showmode'	on	    on
+command characters		'showcmd'	on	    off
+cursor position			'ruler'		off	    off
+
+The current mode is "-- INSERT --" or "-- REPLACE --", see |'showmode'|.  The
+command characters are those that you typed but were not used yet.  {Vi: does
+not show the characters you typed or the cursor position}
+
+If you have a slow terminal you can switch off the status messages to speed
+up editing:
+	:set nosc noru nosm
+
+If there is an error, an error message will be shown for at least one second
+(in reverse video).  {Vi: error messages may be overwritten with other
+messages before you have a chance to read them}
+
+Some commands show how many lines were affected.  Above which threshold this
+happens can be controlled with the 'report' option (default 2).
+
+On the Amiga Vim will run in a CLI window.  The name Vim and the full name of
+the current file name will be shown in the title bar.  When the window is
+resized, Vim will automatically redraw the window.  You may make the window as
+small as you like, but if it gets too small not a single line will fit in it.
+Make it at least 40 characters wide to be able to read most messages on the
+last line.
+
+On most Unix systems, resizing the window is recognized and handled correctly
+by Vim.  {Vi: not ok}
+
+==============================================================================
+8. Definitions						*definitions*
+
+  screen		The whole area that Vim uses to work in.  This can be
+			a terminal emulator window.  Also called "the Vim
+			window".
+  window		A view on a buffer.
+
+A screen contains one or more windows, separated by status lines and with the
+command line at the bottom.
+
+	+-------------------------------+
+screen	| window 1	| window 2	|
+	|		|		|
+	|		|		|
+	|= status line =|= status line =|
+	| window 3			|
+	|				|
+	|				|
+	|==== status line ==============|
+	|command line			|
+	+-------------------------------+
+
+The command line is also used for messages.  It scrolls up the screen when
+there is not enough room in the command line.
+
+A difference is made between four types of lines:
+
+  buffer lines		The lines in the buffer.  This is the same as the
+			lines as they are read from/written to a file.  They
+			can be thousands of characters long.
+  logical lines		The buffer lines with folding applied.  Buffer lines
+			in a closed fold are changed to a single logical line:
+			"+-- 99 lines folded".  They can be thousands of
+			characters long.
+  window lines		The lines displayed in a window: A range of logical
+			lines with wrapping, line breaks, etc.  applied.  They
+			can only be as long as the width of the window allows,
+			longer lines are wrapped or truncated.
+  screen lines		The lines of the screen that Vim uses.  Consists of
+			the window lines of all windows, with status lines
+			and the command line added.  They can only be as long
+			as the width of the screen allows.  When the command
+			line gets longer it wraps and lines are scrolled to
+			make room.
+
+buffer lines	logical lines	window lines	screen lines ~
+
+1. one		1. one		1. +-- folded   1.  +-- folded
+2. two		2. +-- folded	2. five		2.  five
+3. three	3. five		3. six		3.  six
+4. four		4. six		4. seven	4.  seven
+5. five		5. seven			5.  === status line ===
+6. six						6.  aaa
+7. seven					7.  bbb
+						8.  ccc ccc c
+1. aaa		1. aaa		1. aaa		9.  cc
+2. bbb		2. bbb		2. bbb		10. ddd
+3. ccc ccc ccc	3. ccc ccc ccc	3. ccc ccc c	11. ~ 
+4. ddd		4. ddd		4. cc		12. === status line ===
+				5. ddd		13. (command line)
+				6. ~ 
+
+==============================================================================
+ vim:tw=78:ts=8:ft=help:norl:
--- /dev/null
+++ b/lib/vimfiles/doc/makehtml.awk
@@ -1,0 +1,787 @@
+BEGIN   {
+	# some initialization variables
+	asciiart="no";
+	wasset="no";
+	lineset=0;
+	sample="no";
+	while ( getline ti <"tags.ref" > 0 ) {
+		nf=split(ti,tag,"	");
+		tagkey[tag[1]]="yes";tagref[tag[1]]=tag[2];
+	}
+	skip_word["and"]="yes";
+	skip_word["backspace"]="yes";
+	skip_word["beep"]="yes";
+	skip_word["bugs"]="yes";
+	skip_word["da"]="yes";
+	skip_word["end"]="yes";
+	skip_word["ftp"]="yes";
+	skip_word["go"]="yes";
+	skip_word["help"]="yes";
+	skip_word["home"]="yes";
+	skip_word["news"]="yes";
+	skip_word["index"]="yes";
+	skip_word["insert"]="yes";
+	skip_word["into"]="yes";
+	skip_word["put"]="yes";
+	skip_word["reference"]="yes";
+	skip_word["section"]="yes";
+	skip_word["space"]="yes";
+	skip_word["starting"]="yes";
+	skip_word["toggle"]="yes";
+	skip_word["various"]="yes";
+	skip_word["version"]="yes";
+	skip_word["is"]="yes";
+}
+#
+# protect special chars
+#
+/[><&�]/ {gsub(/&/,"\\&amp;");gsub(/>/,"\\&gt;");gsub(/</,"\\&lt;");gsub("�","\\&aacute;");}
+#
+# end of sample lines by non-blank in first column
+#
+sample == "yes" && substr($0,1,4) == "&lt;" { sample = "no"; gsub(/^&lt;/, " "); }
+sample == "yes" && substr($0,1,1) != " " && substr($0,1,1) != "	" && length($0) > 0 { sample = "no" }
+#
+# sample lines printed bold unless empty...
+#
+sample == "yes" && $0 =="" { print ""; next; }
+sample == "yes" && $0 !="" { print "<B>" $0 "</B>"; next; }
+#
+# start of sample lines in next line
+#
+$0 == "&gt;" { sample = "yes"; print ""; next; }
+substr($0,length($0)-4,5) == " &gt;" { sample = "yes"; gsub(/ &gt;$/, ""); }
+#
+# header lines printed bold, colored
+#
+substr($0,length($0),1) == "~" { print "<B><FONT COLOR=\"PURPLE\">" substr($0,1,length($0)-1) "</FONT></B>"; next; }
+#
+#ad hoc code
+#
+/^"\|\& / {gsub(/\|/,"\\&#124;"); }
+/ = b / {gsub(/ b /," \\&#98; "); }
+#
+# one letter tag
+#
+/[ 	]\*.\*[ 	]/ {gsub(/\*/,"ZWWZ"); }
+#
+# isolated "*"
+#
+/[ 	]\*[ 	]/ {gsub(/ \* /," \\&#42; ");
+		    gsub(/ \*	/," \\&#42;	");
+		    gsub(/	\* /,"	\\&#42; ");
+		    gsub(/	\*	/,"	\\&#42;	"); }
+#
+# tag start
+#
+/[ 	]\*[^ 	]/	{gsub(/ \*/," ZWWZ");gsub(/	\*/,"	ZWWZ");}
+/^\*[^ 	]/ 	 {gsub(/^\*/,"ZWWZ");}
+#
+# tag end
+#
+/[^ 	]\*$/ 	 {gsub(/\*$/,"ZWWZ");}
+/[^ \/	]\*[ 	]/  {gsub(/\*/,"ZWWZ");}
+#
+# isolated "|"
+#
+/[ 	]\|[ 	]/ {gsub(/ \| /," \\&#124; ");
+		    gsub(/ \|	/," \\&#124;	");
+		    gsub(/	\| /,"	\\&#124; ");
+		    gsub(/	\|	/,"	\\&#124;	"); }
+/'\|'/ { gsub(/'\|'/,"'\\&#124;'"); }
+/\^V\|/ {gsub(/\^V\|/,"^V\\&#124;");}
+/ \\\|	/ {gsub(/\|/,"\\&#124;");}
+#
+# one letter pipes and "||" false pipe (digraphs)
+#
+/[ 	]\|.\|[ 	]/ && asciiart == "no" {gsub(/\|/,"YXXY"); }
+/^\|.\|[ 	]/ {gsub(/\|/,"YXXY"); }
+/\|\|/ {gsub(/\|\|/,"\\&#124;\\&#124;"); }
+/^shellpipe/ {gsub(/\|/,"\\&#124;"); }
+#
+# pipe start
+#
+/[ 	]\|[^ 	]/ && asciiart == "no"	{gsub(/ \|/," YXXY");
+			gsub(/	\|/,"	YXXY");}
+/^\|[^ 	]/ 	 {gsub(/^\|/,"YXXY");}
+#
+# pipe end
+#
+/[^ 	]\|$/ && asciiart == "no" {gsub(/\|$/,"YXXY");}
+/[^ 	]\|[s ,.);	]/ && asciiart == "no" {gsub(/\|/,"YXXY");}
+/[^ 	]\|]/ && asciiart == "no" {gsub(/\|/,"YXXY");}
+#
+# various
+#
+/'"/ 	{gsub(/'"/,"\\&#39;\\&#34;'");}
+/"/	{gsub(/"/,"\\&quot;");}
+/%/	{gsub(/%/,"\\&#37;");}
+
+NR == 1 { nf=split(FILENAME,f,".")
+	print "<HTML>";
+
+	print "<HEAD>"
+	if ( FILENAME == "mbyte.txt" ) {
+	    # needs utf-8 as uses many languages
+	    print "<META HTTP-EQUIV=\"Content-type\" content=\"text/html; charset=UTF-8\">";
+	} else {
+	    # common case - Latin1
+	    print "<META HTTP-EQUIV=\"Content-type\" content=\"text/html; charset=ISO-8859-1\">";
+	}
+	print "<TITLE>Vim documentation: " f[1] "</TITLE>";
+	print "</HEAD>";
+
+	print "<BODY BGCOLOR=\"#ffffff\">";
+	print "<H1>Vim documentation: " f[1] "</H1>";
+	print "<A NAME=\"top\"></A>";
+	if ( FILENAME != "help.txt" ) {
+	  print "<A HREF=\"index.html\">main help file</A>\n";
+	}
+	print "<HR>";
+	print "<PRE>";
+	filename=f[1]".html";
+}
+
+# set to a low value to test for few lines of text
+# NR == 99999 { exit; }
+
+# ignore underlines and tags
+substr($0,1,5) == " vim:" { next; }
+substr($0,1,4) == "vim:" { next; }
+# keep just whole lines of "-", "="
+substr($0,1,3) == "===" && substr($0,75,1) != "=" { next; }
+substr($0,1,3) == "---" && substr($0,75,1) != "-" { next; }
+
+{
+	nstar = split($0,s,"ZWWZ");
+	for ( i=2 ; i <= nstar ; i=i+2 ) {
+		nbla=split(s[i],blata,"[ 	]");
+		if ( nbla > 1 ) {
+			gsub("ZWWZ","*");
+			nstar = split($0,s,"ZWWZ");
+		}
+	}
+	npipe = split($0,p,"YXXY");
+	for ( i=2 ; i <= npipe ; i=i+2 ) {
+		nbla=split(p[i],blata,"[ 	]");
+		if ( nbla > 1 ) {
+			gsub("YXXY","|");
+			ntabs = split($0,p,"YXXY");
+		}
+	}
+}
+
+
+FILENAME == "gui.txt" && asciiart == "no"  \
+	  && $0 ~ /\+----/ && $0 ~ /----\+/ {
+	asciiart= "yes";
+	asciicnt=0;
+	}
+
+FILENAME == "quotes.txt" && asciiart == "no" \
+	  && $0 ~ /In summary:/ {
+	asciiart= "yes";
+	asciicnt=0;
+	}
+
+FILENAME == "usr_20.txt" && asciiart == "no" \
+	  && $0 ~ /an empty line at the end:/ {
+	asciiart= "yes";
+	asciicnt=0;
+	}
+
+asciiart == "yes" && $0=="" { asciicnt++; }
+
+asciiart == "yes" && asciicnt == 2 { asciiart = "no"; }
+
+asciiart == "yes" { npipe = 1; }
+#	{ print NR " <=> " asciiart; }
+
+#
+# line contains  "*"
+#
+nstar > 2 && npipe < 3 {
+	printf("\n");
+	for ( i=1; i <= nstar ; i=i+2 ) {
+		this=s[i];
+		put_this();
+		ii=i+1;
+		nbla = split(s[ii],blata," ");
+		if ( ii <= nstar ) {
+			if ( nbla == 1 && substr(s[ii],length(s[ii]),1) != " " ) {
+			printf("*<A NAME=\"%s\"></A>",s[ii]);
+				printf("<B>%s</B>*",s[ii]);
+			} else {
+			printf("*%s*",s[ii]);
+			}
+		}
+	}
+	printf("\n");
+	next;
+	}
+#
+# line contains "|"
+#
+npipe > 2 && nstar < 3 {
+	if  ( npipe%2 == 0 ) {
+		for ( i=1; i < npipe ; i++ ) {
+			gsub("ZWWZ","*",p[i]);
+			printf("%s|",p[i]);
+		}
+		printf("%s\n",p[npipe]);
+		next;
+		}
+	for ( i=1; i <= npipe ; i++ )
+		{
+		if ( i % 2 == 1 ) {
+			gsub("ZWWZ","*",p[i]);
+			this=p[i];
+			put_this();
+			}
+			else {
+			nfn=split(p[i],f,".");
+			if ( nfn == 1 || f[2] == "" || f[1] == "" || length(f[2]) < 3 ) {
+				find_tag1();
+				}
+				else {
+					if ( f[1] == "index" ) {
+		printf "|<A HREF=\"vimindex.html\">" p[i] "</A>|";
+					} else {
+						if ( f[1] == "help" ) {
+		printf "|<A HREF=\"index.html\">" p[i] "</A>|";
+						} else {
+		printf "|<A HREF=\"" f[1] ".html\">" p[i] "</A>|";
+						}
+					}
+				}
+			}
+		}
+		printf("\n");
+		next;
+	}
+#
+# line contains both "|" and "*"
+#
+npipe > 2 && nstar > 2 {
+	printf("\n");
+	for ( j=1; j <= nstar ; j=j+2 ) {
+		npipe = split(s[j],p,"YXXY");
+		if ( npipe > 1 ) {
+			for ( np=1; np<=npipe; np=np+2 ) {
+				this=p[np];
+				put_this();
+				i=np+1;find_tag1();
+			}
+		} else {
+			this=s[j];
+			put_this();
+		}
+		jj=j+1;
+		nbla = split(s[jj],blata," ");
+		if ( jj <= nstar && nbla == 1 && s[jj] != "" ) {
+		printf("*<A NAME=\"%s\"></A>",s[jj]);
+			printf("<B>%s</B>*",s[jj]);
+		} else {
+			if ( s[jj] != "" ) {
+			printf("*%s*",s[jj]);
+			}
+		}
+	}
+	printf("\n");
+	next;
+	}
+#
+# line contains e-mail address john.doe@some.place.edu
+#
+$0 ~ /@/ && $0 ~ /[a-zA-Z0-9]@[a-z]/ \
+	{
+	nemail=split($0,em," ");
+	if ( substr($0,1,1) == "	" ) { printf("	"); }
+	for ( i=1; i <= nemail; i++ ) {
+		if ( em[i] ~ /@/ ) {
+			if ( substr(em[i],2,3) == "lt;" && substr(em[i],length(em[i])-2,3) == "gt;" ) {
+				mailaddr=substr(em[i],5,length(em[i])-8);
+				printf("<A HREF=\"mailto:%s\">&lt;%s&gt;</A> ",mailaddr,mailaddr);
+			} else {
+				if ( substr(em[i],2,3) == "lt;" && substr(em[i],length(em[i])-3,3) == "gt;" ) {
+					mailaddr=substr(em[i],5,length(em[i])-9);
+					printf("<A HREF=\"mailto:%s\">&lt;%s&gt;</A>%s ",mailaddr,mailaddr,substr(em[i],length(em[i]),1));
+				} else {
+					printf("<A HREF=\"mailto:%s\">%s</A> ",em[i],em[i]);
+				}
+			}
+		} else {
+				printf("%s ",em[i]);
+		}
+	}
+	#print "*** " NR " " FILENAME " - possible mail ref";
+	printf("\n");
+	next;
+	}
+#
+# line contains http / ftp reference
+#
+$0 ~ /http:\/\// || $0 ~ /ftp:\/\// {
+	gsub("URL:","");
+	gsub("&lt;","");
+	gsub("&gt;","");
+	gsub("\\(","");
+	gsub("\\)","");
+	nemail=split($0,em," ");
+	for ( i=1; i <= nemail; i++ ) {
+		if ( substr(em[i],1,5) == "http:" ||
+	     	substr(em[i],1,4) == "ftp:" ) {
+			if ( substr(em[i],length(em[i]),1) != "." ) {
+				printf("	<A HREF=\"%s\">%s</A>",em[i],em[i]);
+			} else {
+				em[i]=substr(em[i],1,length(em[i])-1);
+				printf("	<A HREF=\"%s\">%s</A>.",em[i],em[i]);
+			}
+		} else {
+		printf(" %s",em[i]);
+		}
+	}
+	#print "*** " NR " " FILENAME " - possible http ref";
+	printf("\n");
+	next;
+	}
+#
+# some lines contains just one "almost regular" "*"...
+#
+nstar == 2  {
+	this=s[1];
+	put_this();
+	printf("*");
+	this=s[2];
+	put_this();
+	printf("\n");
+	next;
+	}
+#
+# regular line
+#
+	{ ntabs = split($0,tb,"	");
+	for ( i=1; i < ntabs ; i++) {
+		this=tb[i];
+		put_this();
+		printf("	");
+		}
+	this=tb[ntabs];
+	put_this();
+	printf("\n");
+	}
+
+
+asciiart == "yes"  && $0 ~ /\+-\+--/  \
+	&& $0 ~ "scrollbar" { asciiart = "no"; }
+
+END {
+	topback();
+	print "</PRE>\n</BODY>\n\n\n</HTML>"; }
+
+#
+# as main we keep index.txt (by default)
+#
+function topback () {
+	if ( FILENAME != "tags" ) {
+	if ( FILENAME != "help.txt" ) {
+	printf("<A HREF=\"#top\">top</A> - ");
+	printf("<A HREF=\"index.html\">main help file</A>\n");
+	} else {
+	printf("<A HREF=\"#top\">top</A>\n");
+	}
+	}
+}
+
+function find_tag1() {
+	if ( p[i] == "" ) { return; }
+	if ( tagkey[p[i]] == "yes" ) {
+		which=tagref[p[i]];
+		put_href();
+		return;
+	}
+	# if not found, then we have a problem
+	print "============================================"  >>"errors.log";
+	print FILENAME ", line " NR ", pointer: >>" p[i] "<<" >>"errors.log";
+	print $0 >>"errors.log";
+	which="intro.html";
+	put_href();
+}
+
+function see_tag() {
+# ad-hoc code:
+if ( atag == "\"--" || atag == "--\"" ) { return; }
+if_already();
+if ( already == "yes" ) {
+	printf("%s",aword);
+	return;
+	}
+allow_one_char="no";
+find_tag2();
+if ( done == "yes" ) { return; }
+rightchar=substr(atag,length(atag),1);
+if (    rightchar == "." \
+     || rightchar == "," \
+     || rightchar == ":" \
+     || rightchar == ";" \
+     || rightchar == "!" \
+     || rightchar == "?" \
+     || rightchar == ")" ) {
+	atag=substr(atag,1,length(atag)-1);
+	if_already();
+	if ( already == "yes" ) {
+		printf("%s",aword);
+		return;
+	}
+	find_tag2();
+	if ( done == "yes" ) { printf("%s",rightchar);return; }
+	leftchar=substr(atag,1,1);
+	lastbut1=substr(atag,length(atag),1);
+	if (    leftchar == "'" && lastbut1 == "'"  ) {
+		allow_one_char="yes";
+		atag=substr(atag,2,length(atag)-2);
+		if_already();
+		if ( already == "yes" ) {
+			printf("%s",aword);
+			return;
+		}
+		printf("%s",leftchar);
+		aword=substr(atag,1,length(atag))""lastbut1""rightchar;
+		find_tag2();
+		if ( done == "yes" ) { printf("%s%s",lastbut1,rightchar);return; }
+		}
+	}
+atag=aword;
+leftchar=substr(atag,1,1);
+if (    leftchar == "'" && rightchar == "'"  ) {
+	allow_one_char="yes";
+	atag=substr(atag,2,length(atag)-2);
+	if  ( atag == "<" ) { printf(" |%s|%s| ",atag,p[2]); }
+	if_already();
+	if ( already == "yes" ) {
+		printf("%s",aword);
+		return;
+		}
+	printf("%s",leftchar);
+	find_tag2();
+	if ( done == "yes" ) { printf("%s",rightchar);return; }
+	printf("%s%s",atag,rightchar);
+	return;
+	}
+last2=substr(atag,length(atag)-1,2);
+first2=substr(atag,1,2);
+if (    first2 == "('" && last2 == "')"  ) {
+	allow_one_char="yes";
+	atag=substr(atag,3,length(atag)-4);
+	if_already();
+	if ( already == "yes" ) {
+		printf("%s",aword);
+		return;
+		}
+	printf("%s",first2);
+	find_tag2();
+	if ( done == "yes" ) { printf("%s",last2);return; }
+	printf("%s%s",atag,last2);
+	return;
+	}
+if ( last2 == ".)" ) {
+	atag=substr(atag,1,length(atag)-2);
+	if_already();
+	if ( already == "yes" ) {
+		printf("%s",aword);
+		return;
+		}
+	find_tag2();
+	if ( done == "yes" ) { printf("%s",last2);return; }
+	printf("%s%s",atag,last2);
+	return;
+	}
+if ( last2 == ")." ) {
+	atag=substr(atag,1,length(atag)-2);
+	find_tag2();
+	if_already();
+	if ( already == "yes" ) {
+		printf("%s",aword);
+		return;
+		}
+	if ( done == "yes" ) { printf("%s",last2);return; }
+	printf("%s%s",atag,last2);
+	return;
+	}
+first6=substr(atag,1,6);
+last6=substr(atag,length(atag)-5,6);
+if ( last6 == atag ) {
+	printf("%s",aword);
+	return;
+	}
+last6of7=substr(atag,length(atag)-6,6);
+if ( first6 == "&quot;" && last6of7 == "&quot;" && length(atag) > 12 ) {
+	allow_one_char="yes";
+	atag=substr(atag,7,length(atag)-13);
+	if_already();
+	if ( already == "yes" ) {
+		printf("%s",aword);
+		return;
+		}
+	printf("%s",first6);
+	find_tag2();
+	if ( done == "yes" ) { printf("&quot;%s",rightchar); return; }
+	printf("%s&quot;%s",atag,rightchar);
+	return;
+	}
+if ( first6 == "&quot;" && last6 != "&quot;" ) {
+	allow_one_char="yes";
+	atag=substr(atag,7,length(atag)-6);
+	if ( atag == "[" ) { printf("&quot;%s",atag); return; }
+	if ( atag == "." ) { printf("&quot;%s",atag); return; }
+	if ( atag == ":" ) { printf("&quot;%s",atag); return; }
+	if ( atag == "a" ) { printf("&quot;%s",atag); return; }
+	if ( atag == "A" ) { printf("&quot;%s",atag); return; }
+	if ( atag == "g" ) { printf("&quot;%s",atag); return; }
+	if_already();
+	if ( already == "yes" ) {
+		printf("&quot;%s",atag);
+		return;
+		}
+	printf("%s",first6);
+	find_tag2();
+	if ( done == "yes" ) { return; }
+	printf("%s",atag);
+	return;
+	}
+if ( last6 == "&quot;" && first6 == "&quot;" ) {
+	allow_one_char="yes";
+	atag=substr(atag,7,length(atag)-12);
+	if_already();
+	if ( already == "yes" ) {
+		printf("%s",aword);
+		return;
+		}
+	printf("%s",first6);
+	find_tag2();
+	if ( done == "yes" ) { printf("%s",last6);return; }
+	printf("%s%s",atag,last6);
+	return;
+	}
+last6of7=substr(atag,length(atag)-6,6);
+if ( last6of7 == "&quot;" && first6 == "&quot;" ) {
+	allow_one_char="yes";
+	atag=substr(atag,7,length(atag)-13);
+	#printf("\natag=%s,aword=%s\n",atag,aword);
+	if_already();
+	if ( already == "yes" ) {
+		printf("%s",aword);
+		return;
+		}
+	printf("%s",first6);
+	find_tag2();
+	if ( done == "yes" ) { printf("%s%s",last6of7,rightchar);return; }
+	printf("%s%s%s",atag,last6of7,rightchar);
+	return;
+	}
+printf("%s",aword);
+}
+
+function find_tag2() {
+	done="no";
+	# no blanks present in a tag...
+	ntags=split(atag,blata,"[ 	]");
+	if ( ntags > 1 ) { return; }
+	if 	( ( allow_one_char == "no" ) && \
+		  ( index("!#$%&'()+,-./0:;=?@ACINX\\[\\]^_`at\\{\\}~",atag) !=0 ) ) {
+		return;
+	}
+	if ( skip_word[atag] == "yes" ) { return; }
+	if ( wasset == "yes" && lineset == NR ) {
+	wasset="no";
+	see_opt();
+	if ( done_opt == "yes" ) {return;}
+	}
+	if ( wasset == "yes" && lineset != NR ) {
+	wasset="no";
+	}
+	if ( atag == ":set" ) {
+	wasset="yes";
+	lineset=NR;
+	}
+	if ( tagkey[atag] == "yes" ) {
+		which=tagref[atag];
+		put_href2();
+		done="yes";
+	}
+}
+
+function find_tag3() {
+	done="no";
+	# no blanks present in a tag...
+	ntags=split(btag,blata,"[ 	]");
+	if ( ntags > 1 ) { return; }
+	if 	( ( allow_one_char == "no" ) && \
+		  ( index("!#$%&'()+,-./0:;=?@ACINX\\[\\]^_`at\\{\\}~",btag) !=0 ) ) {
+	  	return;
+	}
+	if ( skip_word[btag] == "yes" ) { return; }
+	if ( tagkey[btag] == "yes" ) {
+		which=tagref[btag];
+		put_href3();
+		done="yes";
+	}
+}
+
+function put_href() {
+	if ( p[i] == "" ) { return; }
+	if ( which == FILENAME ) {
+		printf("|<A HREF=\"#%s\">%s</A>|",p[i],p[i]);
+		}
+		else {
+		nz=split(which,zz,".");
+		if ( zz[2] == "txt" || zz[1] == "tags" ) {
+		printf("|<A HREF=\"%s.html#%s\">%s</A>|",zz[1],p[i],p[i]);
+		}
+		else {
+		printf("|<A HREF=\"intro.html#%s\">%s</A>|",p[i],p[i]);
+		}
+	}
+}
+
+function put_href2() {
+	if ( atag == "" ) { return; }
+	if ( which == FILENAME ) {
+		printf("<A HREF=\"#%s\">%s</A>",atag,atag);
+		}
+		else {
+		nz=split(which,zz,".");
+		if ( zz[2] == "txt" || zz[1] == "tags" ) {
+		printf("<A HREF=\"%s.html#%s\">%s</A>",zz[1],atag,atag);
+		}
+		else {
+		printf("<A HREF=\"intro.html#%s\">%s</A>",atag,atag);
+		}
+	}
+}
+
+function put_href3() {
+	if ( btag == "" ) { return; }
+	if ( which == FILENAME ) {
+		printf("<A HREF=\"#%s\">%s</A>",btag,btag2);
+		}
+		else {
+		nz=split(which,zz,".");
+		if ( zz[2] == "txt" || zz[1] == "tags" ) {
+		printf("<A HREF=\"%s.html#%s\">%s</A>",zz[1],btag,btag2);
+		}
+		else {
+		printf("<A HREF=\"intro.html#%s\">%s</A>",btag,btag2);
+		}
+	}
+}
+
+function put_this() {
+	ntab=split(this,ta,"	");
+	for ( nta=1 ; nta <= ntab ; nta++ ) {
+		ata=ta[nta];
+		lata=length(ata);
+		aword="";
+		for ( iata=1 ; iata <=lata ; iata++ ) {
+			achar=substr(ata,iata,1);
+			if ( achar != " " ) { aword=aword""achar; }
+			else {
+				if ( aword != "" ) { atag=aword;
+					see_tag();
+					aword="";
+					printf(" "); }
+				else	{
+					printf(" ");
+					}
+			}
+		}
+		if ( aword != "" ) { atag=aword;
+					see_tag();
+					}
+		if ( nta != ntab ) { printf("	"); }
+	}
+}
+
+function if_already() {
+	already="no";
+	if  ( npipe < 2 ) { return; }
+	if  ( atag == ":au" && p[2] == ":autocmd" ) { already="yes";return; }
+	for ( npp=2 ; npp <= npipe ; npp=npp+2 ) {
+		if 	(  (  (index(p[npp],atag)) != 0 \
+			      && length(p[npp]) > length(atag) \
+			      && length(atag) >= 1  \
+			    ) \
+			    || (p[npp] == atag) \
+			) {
+		# printf("p=|%s|,tag=|%s| ",p[npp],atag);
+		already="yes"; return; }
+	}
+}
+
+function see_opt() {
+	done_opt="no";
+	stag=atag;
+	nfields = split(atag,tae,"=");
+	if ( nfields > 1 )  {
+		btag="'"tae[1]"'";
+		btag2=tae[1];
+	    find_tag3();
+		if (done == "yes") {
+			for ( ntae=2 ; ntae <= nfields ; ntae++ ) {
+				printf("=%s",tae[ntae]);
+			}
+			atag=stag;
+			done_opt="yes";
+			return;
+		}
+		btag=tae[1];
+		btag2=tae[1];
+	    find_tag3();
+		if ( done=="yes" ) {
+			for ( ntae=2 ; ntae <= nfields ; ntae++ ) {
+				printf("=%s",tae[ntae]);
+			}
+			atag=stag;
+			done_opt="yes";
+			return;
+		}
+	}
+	nfields = split(atag,tae,"&quot;");
+	if ( nfields > 1 )  {
+		btag="'"tae[1]"'";
+		btag2=tae[1];
+	   	find_tag3();
+		if (done == "yes") {
+			printf("&quot;");
+			atag=stag;
+			done_opt="yes";
+			return;
+		}
+		btag=tae[1];
+		btag2=tae[1];
+	    find_tag3();
+		if (done == "yes") {
+			printf("&quot;");
+			atag=stag;
+			done_opt="yes";
+			return;
+		}
+	}
+	btag="'"tae[1]"'";
+	btag2=tae[1];
+	find_tag3();
+	if (done == "yes") {
+		atag=stag;
+		done_opt="yes";
+		return;
+	}
+	btag=tae[1];
+	btag2=tae[1];
+	find_tag3();
+	if (done == "yes") {
+		atag=stag;
+		done_opt="yes";
+		return;
+	}
+	atag=stag;
+}
--- /dev/null
+++ b/lib/vimfiles/doc/maketags.awk
@@ -1,0 +1,42 @@
+BEGIN   { FS="	"; }
+
+NR == 1 { nf=split(FILENAME,f,".")
+	print "<HTML>";
+	print "<HEAD><TITLE>" f[1] "</TITLE></HEAD>";
+	print "<BODY BGCOLOR=\"#ffffff\">";
+	print "<H1>Vim Documentation: " f[1] "</H1>";
+	print "<A NAME=\"top\"></A>";
+	print "<HR>";
+	print "<PRE>";
+}
+
+{
+	#
+	# protect special chars
+	#
+	gsub(/&/,"\\&amp;");
+	gsub(/>/,"\\&gt;");
+	gsub(/</,"\\&lt;");
+	gsub(/"/,"\\&quot;");
+	gsub(/%/,"\\&#37;");
+
+	nf=split($0,tag,"	");
+	tagkey[t]=tag[1];tagref[t]=tag[2];tagnum[t]=NR;
+	print $1 "	" $2 "	line " NR >"tags.ref"
+	n=split($2,w,".");
+	printf ("|<A HREF=\"%s.html#%s\">%s</A>|	%s\n",w[1],$1,$1,$2);
+}
+
+END     {
+	topback();
+	print "</PRE>\n</BODY>\n\n\n</HTML>";
+	}
+
+#
+# as main we keep index.txt (by default)
+# other candidate, help.txt
+#
+function topback () {
+	printf("<A HREF=\"#top\">top</A> - ");
+	printf("<A HREF=\"help.html\">back to help</A>\n");
+}
--- /dev/null
+++ b/lib/vimfiles/doc/map.txt
@@ -1,0 +1,1396 @@
+*map.txt*       For Vim version 7.1.  Last change: 2007 May 11
+
+
+		  VIM REFERENCE MANUAL    by Bram Moolenaar
+
+
+Key mapping, abbreviations and user-defined commands.
+
+This subject is introduced in sections |05.3|, |24.7| and |40.1| of the user
+manual.
+
+1. Key mapping			|key-mapping|
+   1.1 MAP COMMANDS			|:map-commands|
+   1.2 Special arguments		|:map-arguments|
+   1.3 Mapping and modes		|:map-modes|
+   1.4 Listing mappings			|map-listing|
+   1.5 Mapping special keys		|:map-special-keys|
+   1.6 Special characters		|:map-special-chars|
+   1.7 What keys to map			|map-which-keys|
+   1.8 Examples				|map-examples|
+   1.9 Using mappings			|map-typing|
+   1.10 Mapping alt-keys		|:map-alt-keys|
+   1.11 Mapping an operator		|:map-operator|
+2. Abbreviations		|abbreviations|
+3. Local mappings and functions	|script-local|
+4. User-defined commands	|user-commands|
+
+==============================================================================
+1. Key mapping				*key-mapping* *mapping* *macro*
+
+Key mapping is used to change the meaning of typed keys.  The most common use
+is to define a sequence commands for a function key.  Example: >
+
+	:map <F2> a<C-R>=strftime("%c")<CR><Esc>
+
+This appends the current date and time after the cursor (in <> notation |<>|).
+
+
+1.1 MAP COMMANDS					*:map-commands*
+
+There are commands to enter new mappings, remove mappings and list mappings.
+See |map-overview| for the various forms of "map" and their relationships with
+modes.
+
+{lhs}	means left-hand-side	*{lhs}*
+{rhs}	means right-hand-side	*{rhs}*
+
+:map	{lhs} {rhs}		|mapmode-nvo|		*:map*
+:nm[ap]	{lhs} {rhs}		|mapmode-n|		*:nm* *:nmap*
+:vm[ap]	{lhs} {rhs}		|mapmode-v|		*:vm* *:vmap*
+:xm[ap]	{lhs} {rhs}		|mapmode-x|		*:xm* *:xmap*
+:smap	{lhs} {rhs}		|mapmode-s|		      *:smap*
+:om[ap]	{lhs} {rhs}		|mapmode-o|		*:om* *:omap*
+:map!	{lhs} {rhs}		|mapmode-ic|		*:map!*
+:im[ap]	{lhs} {rhs}		|mapmode-i|		*:im* *:imap*
+:lm[ap]	{lhs} {rhs}		|mapmode-l|		*:lm* *:lmap*
+:cm[ap]	{lhs} {rhs}		|mapmode-c|		*:cm* *:cmap*
+			Map the key sequence {lhs} to {rhs} for the modes
+			where the map command applies.  The result, including
+			{rhs}, is then further scanned for mappings.  This
+			allows for nested and recursive use of mappings.
+
+
+:no[remap]  {lhs} {rhs}		|mapmode-nvo|		*:no*  *:noremap*
+:nn[oremap] {lhs} {rhs}		|mapmode-n|		*:nn*  *:nnoremap*
+:vn[oremap] {lhs} {rhs}		|mapmode-v|		*:vn*  *:vnoremap*
+:xn[oremap] {lhs} {rhs}		|mapmode-x|		*:xn*  *:xnoremap*
+:snor[emap] {lhs} {rhs}		|mapmode-s|		*:snor* *:snoremap*
+:ono[remap] {lhs} {rhs}		|mapmode-o|		*:ono* *:onoremap*
+:no[remap]! {lhs} {rhs}		|mapmode-ic|		*:no!* *:noremap!*
+:ino[remap] {lhs} {rhs}		|mapmode-i|		*:ino* *:inoremap*
+:ln[oremap] {lhs} {rhs}		|mapmode-l|		*:ln*  *:lnoremap*
+:cno[remap] {lhs} {rhs}		|mapmode-c|		*:cno* *:cnoremap*
+			Map the key sequence {lhs} to {rhs} for the modes
+			where the map command applies.  Disallow mapping of
+			{rhs}, to avoid nested and recursive mappings.  Often
+			used to redefine a command.  {not in Vi}
+
+
+:unm[ap]  {lhs}			|mapmode-nvo|		*:unm*  *:unmap*
+:nun[map] {lhs}			|mapmode-n|		*:nun*  *:nunmap*
+:vu[nmap] {lhs}			|mapmode-v|		*:vu*   *:vunmap*
+:xu[nmap] {lhs}			|mapmode-x|		*:xu*   *:xunmap*
+:sunm[ap] {lhs}			|mapmode-s|		*:sunm* *:sunmap*
+:ou[nmap] {lhs}			|mapmode-o|		*:ou*   *:ounmap*
+:unm[ap]! {lhs}			|mapmode-ic|		*:unm!* *:unmap!*
+:iu[nmap] {lhs}			|mapmode-i|		*:iu*   *:iunmap*
+:lu[nmap] {lhs}			|mapmode-l|		*:lu*   *:lunmap*
+:cu[nmap] {lhs}			|mapmode-c|		*:cu*   *:cunmap*
+			Remove the mapping of {lhs} for the modes where the
+			map command applies.  The mapping may remain defined
+			for other modes where it applies.
+			Note: Trailing spaces are included in the {lhs}.  This
+			unmap does NOT work: >
+				:map @@ foo
+				:unmap @@ | print
+
+:mapc[lear]			|mapmode-nvo|		*:mapc*   *:mapclear*
+:nmapc[lear]			|mapmode-n|		*:nmapc*  *:nmapclear*
+:vmapc[lear]			|mapmode-v|		*:vmapc*  *:vmapclear*
+:xmapc[lear]			|mapmode-x|		*:xmapc*  *:xmapclear*
+:smapc[lear]			|mapmode-s|		*:smapc*  *:smapclear*
+:omapc[lear]			|mapmode-o|		*:omapc*  *:omapclear*
+:mapc[lear]!			|mapmode-ic|		*:mapc!*  *:mapclear!*
+:imapc[lear]			|mapmode-i|		*:imapc*  *:imapclear*
+:lmapc[lear]			|mapmode-l|		*:lmapc*  *:lmapclear*
+:cmapc[lear]			|mapmode-c|		*:cmapc*  *:cmapclear*
+			Remove ALL mappings for the modes where the map
+			command applies.  {not in Vi}
+			Warning: This also removes the default mappings.
+
+:map				|mapmode-nvo|
+:nm[ap]				|mapmode-n|
+:vm[ap]				|mapmode-v|
+:xm[ap]				|mapmode-x|
+:sm[ap]				|mapmode-s|
+:om[ap]				|mapmode-o|
+:map!				|mapmode-ic|
+:im[ap]				|mapmode-i|
+:lm[ap]				|mapmode-l|
+:cm[ap]				|mapmode-c|
+			List all key mappings for the modes where the map
+			command applies.  Note that ":map" and ":map!" are
+			used most often, because they include the other modes.
+
+:map    {lhs}			|mapmode-nvo|		*:map_l*
+:nm[ap] {lhs}			|mapmode-n|		*:nmap_l*
+:vm[ap] {lhs}			|mapmode-v|		*:vmap_l*
+:xm[ap] {lhs}			|mapmode-x|		*:xmap_l*
+:sm[ap] {lhs}			|mapmode-s|		*:smap_l*
+:om[ap] {lhs}			|mapmode-o|		*:omap_l*
+:map!   {lhs}			|mapmode-ic|		*:map_l!*
+:im[ap] {lhs}			|mapmode-i|		*:imap_l*
+:lm[ap] {lhs}			|mapmode-l|		*:lmap_l*
+:cm[ap] {lhs}			|mapmode-c|		*:cmap_l*
+			List the key mappings for the key sequences starting
+			with {lhs} in the modes where the map command applies.
+			{not in Vi}
+
+These commands are used to map a key or key sequence to a string of
+characters.  You can use this to put command sequences under function keys,
+translate one key into another, etc.  See |:mkexrc| for how to save and
+restore the current mappings.
+
+							*map-ambiguous*
+When two mappings start with the same sequence of characters, they are
+ambiguous.  Example: >
+	:imap aa foo
+	:imap aaa bar
+When Vim has read "aa", it will need to get another character to be able to
+decide if "aa" or "aaa" should be mapped.  This means that after typing "aa"
+that mapping won't get expanded yet, Vim is waiting for another character.
+If you type a space, then "foo" will get inserted, plus the space.  If you
+type "a", then "bar" will get inserted.
+{Vi does not allow ambiguous mappings}
+
+
+1.2 SPECIAL ARGUMENTS					*:map-arguments*
+
+"<buffer>", "<silent>", "<special>", "<script>", "<expr>" and "<unique>" can
+be used in any order.  They must appear right after the command, before any
+other arguments.
+
+				*:map-local* *:map-<buffer>* *E224* *E225*
+If the first argument to one of these commands is "<buffer>" it will apply to
+mappings locally to the current buffer only.  Example: >
+	:map <buffer>  ,w  /[.,;]<CR>
+Then you can map ",w" to something else in another buffer: >
+	:map <buffer>  ,w  /[#&!]<CR>
+The local buffer mappings are used before the global ones.
+The "<buffer>" argument can also be used to clear mappings: >
+	:unmap <buffer> ,w
+	:mapclear <buffer>
+Local mappings are also cleared when a buffer is deleted, but not when it is
+unloaded.  Just like local option values.
+
+						*:map-<silent>* *:map-silent*
+To define a mapping which will not be echoed on the command line, add
+"<silent>" as the first argument.  Example: >
+	:map <silent> ,h /Header<CR>
+The search string will not be echoed when using this mapping.  Messages from
+the executed command are still given though.  To shut them up too, add a
+":silent" in the executed command: >
+	:map <silent> ,h :exe ":silent normal /Header\r"<CR>
+Prompts will still be given, e.g., for inputdialog().
+Using "<silent>" for an abbreviation is possible, but will cause redrawing of
+the command line to fail.
+
+						*:map-<special>* *:map-special*
+Define a mapping with <> notation for special keys, even though the "<" flag
+may appear in 'cpoptions'.  This is useful if the side effect of setting
+'cpoptions' is not desired.  Example: >
+	:map <special> <F12> /Header<CR>
+<
+						*:map-<script>* *:map-script*
+If the first argument to one of these commands is "<script>" and it is used to
+define a new mapping or abbreviation, the mapping will only remap characters
+in the {rhs} using mappings that were defined local to a script, starting with
+"<SID>".  This can be used to avoid that mappings from outside a script
+interfere (e.g., when CTRL-V is remapped in mswin.vim), but do use other
+mappings defined in the script.
+Note: ":map <script>" and ":noremap <script>" do the same thing.  The
+"<script>" overrules the command name.  Using ":noremap <script>" is
+preferred, because it's clearer that remapping is (mostly) disabled.
+
+						*:map-<unique>* *E226* *E227*
+If the first argument to one of these commands is "<unique>" and it is used to
+define a new mapping or abbreviation, the command will fail if the mapping or
+abbreviation already exists.  Example: >
+	:map <unique> ,w  /[#&!]<CR>
+When defining a local mapping, there will also be a check if a global map
+already exists which is equal.
+Example of what will fail: >
+	:map ,w  /[#&!]<CR>
+	:map <buffer> <unique> ,w  /[.,;]<CR>
+If you want to map a key and then have it do what it was originally mapped to,
+have a look at |maparg()|.
+
+						*:map-<expr>* *:map-expression*
+If the first argument to one of these commands is "<expr>" and it is used to
+define a new mapping or abbreviation, the argument is an expression.  The
+expression is evaluated to obtain the {rhs} that is used.  Example: >
+	:inoremap <expr> . InsertDot()
+The result of the InsertDot() function will be inserted.  It could check the
+text before the cursor and start omni completion when some condition is met.
+
+Be very careful about side effects!  The expression is evaluated while
+obtaining characters, you may very well make the command dysfunctional.
+For this reason the following is blocked:
+- Changing the buffer text |textlock|.
+- Editing another buffer.
+- The |:normal| command.
+- Moving the cursor is allowed, but it is restored afterwards.
+- You can use getchar(), but the existing typeahead isn't seen and new
+  typeahead is discarded.
+If you want the mapping to do any of these let the returned characters do
+that.
+
+Here is an example that inserts a list number that increases: >
+	let counter = 0
+	inoremap <expr> <C-L> ListItem()
+	inoremap <expr> <C-R> ListReset()
+
+	func ListItem()
+	  let g:counter += 1
+	  return g:counter . '. '
+	endfunc
+
+	func ListReset()
+	  let g:counter = 0
+	  return ''
+	endfunc
+
+CTRL-L inserts the next number, CTRL-R resets the count.  CTRL-R returns an
+empty string, so that nothing is inserted.
+
+Note that there are some tricks to make special keys work and escape CSI bytes
+in the text.  The |:map| command also does this, thus you must avoid that it
+is done twice.  This does not work: >
+	:imap <expr> <F3> "<Char-0x611B>"
+Because the <Char- sequence is escaped for being a |:imap| argument and then
+again for using <expr>.  This does work: >
+	:imap <expr> <F3> "\u611B"
+Using 0x80 as a single byte before other text does not work, it will be seen
+as a special key.
+
+
+1.3 MAPPING AND MODES					*:map-modes*
+
+There are five sets of mappings
+- For Normal mode: When typing commands.
+- For Visual mode: When typing commands while the Visual area is highlighted.
+- For Operator-pending mode: When an operator is pending (after "d", "y", "c",
+  etc.).  Example: ":omap { w" makes "y{" work like "yw" and "d{" like "dw".
+- For Insert mode.  These are also used in Replace mode.
+- For Command-line mode: When entering a ":" or "/" command.
+
+Special case: While typing a count for a command in Normal mode, mapping zero
+is disabled.  This makes it possible to map zero without making it impossible
+to type a count with a zero.
+
+						*map-overview* *map-modes*
+Overview of which map command works in which mode:
+
+			*mapmode-nvo* *mapmode-n* *mapmode-v* *mapmode-o*
+    commands:				      modes: ~
+				       Normal  Visual+Select  Operator-pending ~
+:map   :noremap   :unmap   :mapclear	 yes	    yes		   yes
+:nmap  :nnoremap  :nunmap  :nmapclear	 yes	     -		    -
+:vmap  :vnoremap  :vunmap  :vmapclear	  -	    yes		    -
+:omap  :onoremap  :ounmap  :omapclear	  -	     -		   yes
+
+:nunmap can also be used outside of a monastery.
+						*mapmode-x* *mapmode-s*
+Some commands work both in Visual and Select mode, some in only one.  Note
+that quite often "Visual" is mentioned where both Visual and Select mode
+apply. |Select-mode-mapping|
+
+    commands:				      modes: ~
+					  Visual    Select ~
+:vmap  :vnoremap  :vunmap  :vmapclear	    yes      yes
+:xmap  :xnoremap  :xunmap  :xmapclear	    yes       -
+:smap  :snoremap  :sunmap  :smapclear	    -	     yes
+
+			*mapmode-ic* *mapmode-i* *mapmode-c* *mapmode-l*
+Some commands work both in Insert mode and Command-line mode, some not:
+
+    commands:				      modes: ~
+					  Insert  Command-line	Lang-Arg ~
+:map!  :noremap!  :unmap!  :mapclear!	    yes	       yes	   -
+:imap  :inoremap  :iunmap  :imapclear	    yes		-	   -
+:cmap  :cnoremap  :cunmap  :cmapclear	     -	       yes	   -
+:lmap  :lnoremap  :lunmap  :lmapclear	    yes*       yes*	  yes*
+
+The original Vi did not have separate mappings for
+Normal/Visual/Operator-pending mode and for Insert/Command-line mode.
+Therefore the ":map" and ":map!" commands enter and display mappings for
+several modes.  In Vim you can use the ":nmap", ":vmap", ":omap", ":cmap" and
+":imap" commands to enter mappings for each mode separately.
+
+To enter a mapping for Normal and Visual mode, but not Operator-pending mode,
+first define it for all three modes, then unmap it for Operator-pending mode:
+	:map    xx something-difficult
+	:ounmap xx
+Likewise for a mapping for Visual and Operator-pending mode or Normal and
+Operator-pending mode.
+
+						*language-mapping*
+":lmap" defines a mapping that applies to:
+- Insert mode
+- Command-line mode
+- when entering a search pattern
+- the argument of the commands that accept a text character, such as "r" and
+  "f"
+- for the input() line
+Generally: Whenever a character is to be typed that is part of the text in the
+buffer, not a Vim command character.  "Lang-Arg" isn't really another mode,
+it's just used here for this situation.
+   The simplest way to load a set of related language mappings is by using the
+'keymap' option.  See |45.5|.
+   In Insert mode and in Command-line mode the mappings can be disabled with
+the CTRL-^ command |i_CTRL-^| |c_CTRL-^|.  When starting to enter a normal
+command line (not a search pattern) the mappings are disabled until a CTRL-^
+is typed.  The state last used is remembered for Insert mode and Search
+patterns separately.  The state for Insert mode is also used when typing a
+character as an argument to command like "f" or "t".
+   Language mappings will never be applied to already mapped characters.  They
+are only used for typed characters.  This assumes that the language mapping
+was already done when typing the mapping.
+
+
+1.4 LISTING MAPPINGS					*map-listing*
+
+When listing mappings the characters in the first two columns are:
+
+      CHAR	MODE	~
+     <Space>	Normal, Visual, Select and Operator-pending
+	n	Normal
+	v	Visual and Select
+	s	Select
+	x	Visual
+	o	Operator-pending
+	!	Insert and Command-line
+	i	Insert
+	l	":lmap" mappings for Insert, Command-line and Lang-Arg
+	c	Command-line
+
+Just before the {rhs} a special character can appear:
+	*	indicates that it is not remappable
+	&	indicates that only script-local mappings are remappable
+	@	indicates a buffer-local mapping
+
+Everything from the first non-blank after {lhs} up to the end of the line
+(or '|') is considered to be part of {rhs}.  This allows the {rhs} to end
+with a space.
+
+Note: When using mappings for Visual mode, you can use the "'<" mark, which
+is the start of the last selected Visual area in the current buffer |'<|.
+
+							*:map-verbose*
+When 'verbose' is non-zero, listing a key map will also display where it was
+last defined.  Example: >
+
+	:verbose map <C-W>*
+	n  <C-W>*      * <C-W><C-S>*
+		Last set from /home/abcd/.vimrc
+
+See |:verbose-cmd| for more information.
+
+
+1.5 MAPPING SPECIAL KEYS				*:map-special-keys*
+
+There are three ways to map a special key:
+1. The Vi-compatible method: Map the key code.  Often this is a sequence that
+   starts with <Esc>.  To enter a mapping like this you type ":map " and then
+   you have to type CTRL-V before hitting the function key.  Note that when
+   the key code for the key is in the termcap (the t_ options), it will
+   automatically be translated into the internal code and become the second
+   way of mapping (unless the 'k' flag is included in 'cpoptions').
+2. The second method is to use the internal code for the function key.  To
+   enter such a mapping type CTRL-K and then hit the function key, or use
+   the form "#1", "#2", .. "#9", "#0", "<Up>", "<S-Down>", "<S-F7>", etc.
+   (see table of keys |key-notation|, all keys from <Up> can be used).  The
+   first ten function keys can be defined in two ways: Just the number, like
+   "#2", and with "<F>", like "<F2>".  Both stand for function key 2.  "#0"
+   refers to function key 10, defined with option 't_f10', which may be
+   function key zero on some keyboards.  The <> form cannot be used when
+   'cpoptions' includes the '<' flag.
+3. Use the termcap entry, with the form <t_xx>, where "xx" is the name of the
+   termcap entry.  Any string entry can be used.  For example: >
+     :map <t_F3> G
+<  Maps function key 13 to "G".  This does not work if 'cpoptions' includes
+   the '<' flag.
+
+The advantage of the second and third method is that the mapping will work on
+different terminals without modification (the function key will be
+translated into the same internal code or the actual key code, no matter what
+terminal you are using.  The termcap must be correct for this to work, and you
+must use the same mappings).
+
+DETAIL: Vim first checks if a sequence from the keyboard is mapped.  If it
+isn't the terminal key codes are tried (see |terminal-options|).  If a
+terminal code is found it is replaced with the internal code.  Then the check
+for a mapping is done again (so you can map an internal code to something
+else).  What is written into the script file depends on what is recognized.
+If the terminal key code was recognized as a mapping the key code itself is
+written to the script file.  If it was recognized as a terminal code the
+internal code is written to the script file.
+
+
+1.6 SPECIAL CHARACTERS					*:map-special-chars*
+							*map_backslash*
+Note that only CTRL-V is mentioned here as a special character for mappings
+and abbreviations.  When 'cpoptions' does not contain 'B', a backslash can
+also be used like CTRL-V.  The <> notation can be fully used then |<>|.  But
+you cannot use "<C-V>" like CTRL-V to escape the special meaning of what
+follows.
+
+To map a backslash, or use a backslash literally in the {rhs}, the special
+sequence "<Bslash>" can be used.  This avoids the need to double backslashes
+when using nested mappings.
+
+							*map_CTRL-C*
+Using CTRL-C in the {lhs} is possible, but it will only work when Vim is
+waiting for a key, not when Vim is busy with something.  When Vim is busy
+CTRL-C interrupts/breaks the command.
+When using the GUI version on MS-Windows CTRL-C can be mapped to allow a Copy
+command to the clipboard.  Use CTRL-Break to interrupt Vim.
+
+							*map_space_in_lhs*
+To include a space in {lhs} precede it with a CTRL-V (type two CTRL-Vs for
+each space).
+							*map_space_in_rhs*
+If you want a {rhs} that starts with a space, use "<Space>".  To be fully Vi
+compatible (but unreadable) don't use the |<>| notation, precede {rhs} with a
+single CTRL-V (you have to type CTRL-V two times).
+							*map_empty_rhs*
+You can create an empty {rhs} by typing nothing after a single CTRL-V (you
+have to type CTRL-V two times).  Unfortunately, you cannot do this in a vimrc
+file.
+							*<Nop>*
+A easier way to get a mapping that doesn't produce anything, is to use "<Nop>"
+for the {rhs}.  This only works when the |<>| notation is enabled.  For
+example, to make sure that function key 8 does nothing at all: >
+	:map  <F8>  <Nop>
+	:map! <F8>  <Nop>
+<
+							*map-multibyte*
+It is possible to map multibyte characters, but only the whole character.  You
+cannot map the first byte only.  This was done to prevent problems in this
+scenario: >
+	:set encoding=latin1
+	:imap <M-C> foo
+	:set encoding=utf-8
+The mapping for <M-C> is defined with the latin1 encoding, resulting in a 0xc3
+byte.  If you type the character � (0xea <M-a>) in UTF-8 encoding this is the
+two bytes 0xc3 0xa1.  You don't want the 0xc3 byte to be mapped then,
+otherwise it would be impossible to type the � character.
+
+					*<Leader>* *mapleader*
+To define a mapping which uses the "mapleader" variable, the special string
+"<Leader>" can be used.  It is replaced with the string value of "mapleader".
+If "mapleader" is not set or empty, a backslash is used instead.  Example: >
+	:map <Leader>A  oanother line<Esc>
+Works like: >
+	:map \A  oanother line<Esc>
+But after: >
+	:let mapleader = ","
+It works like: >
+	:map ,A  oanother line<Esc>
+
+Note that the value of "mapleader" is used at the moment the mapping is
+defined.  Changing "mapleader" after that has no effect for already defined
+mappings.
+
+					*<LocalLeader>* *maplocalleader*
+Just like <Leader>, except that it uses "maplocalleader" instead of
+"mapleader".  <LocalLeader> is to be used for mappings which are local to a
+buffer.  Example: >
+      :map <LocalLeader>q  \DoItNow
+<
+In a global plugin <Leader> should be used and in a filetype plugin
+<LocalLeader>.  "mapleader" and "maplocalleader" can be equal.  Although, if
+you make them different, there is a smaller chance of mappings from global
+plugins to clash with mappings for filetype plugins.  For example, you could
+keep "mapleader" at the default backslash, and set "maplocalleader" to an
+underscore.
+
+							*map-<SID>*
+In a script the special key name "<SID>" can be used to define a mapping
+that's local to the script.  See |<SID>| for details.
+
+							*<Plug>*
+The special key name "<Plug>" can be used for an internal mapping, which is
+not to be matched with any key sequence.  This is useful in plugins
+|using-<Plug>|.
+
+							*<Char>* *<Char->*
+To map a character by its decimal, octal or hexadecimal number the <Char>
+construct can be used:
+	<Char-123>	character 123
+	<Char-033>	character 27
+	<Char-0x7f>	character 127
+This is useful to specify a (multi-byte) character in a 'keymap' file.
+Upper and lowercase differences are ignored.
+
+							*map-comments*
+It is not possible to put a comment after these commands, because the '"'
+character is considered to be part of the {lhs} or {rhs}.
+
+							*map_bar*
+Since the '|' character is used to separate a map command from the next
+command, you will have to do something special to include  a '|' in {rhs}.
+There are three methods:
+   use	     works when			   example	~
+   <Bar>     '<' is not in 'cpoptions'	   :map _l :!ls <Bar> more^M
+   \|	     'b' is not in 'cpoptions'	   :map _l :!ls \| more^M
+   ^V|	     always, in Vim and Vi	   :map _l :!ls ^V| more^M
+
+(here ^V stands for CTRL-V; to get one CTRL-V you have to type it twice; you
+cannot use the <> notation "<C-V>" here).
+
+All three work when you use the default setting for 'cpoptions'.
+
+When 'b' is present in 'cpoptions', "\|" will be recognized as a mapping
+ending in a '\' and then another command.  This is Vi compatible, but
+illogical when compared to other commands.
+
+							*map_return*
+When you have a mapping that contains an Ex command, you need to put a line
+terminator after it to have it executed.  The use of <CR> is recommended for
+this (see |<>|).  Example: >
+   :map  _ls  :!ls -l %<CR>:echo "the end"<CR>
+
+To avoid mapping of the characters you type in insert or Command-line mode,
+type a CTRL-V first.  The mapping in Insert mode is disabled if the 'paste'
+option is on.
+
+Note that when an error is encountered (that causes an error message or beep)
+the rest of the mapping is not executed.  This is Vi-compatible.
+
+Note that the second character (argument) of the commands @zZtTfF[]rm'`"v
+and CTRL-X is not mapped.  This was done to be able to use all the named
+registers and marks, even when the command with the same name has been
+mapped.
+
+
+1.7 WHAT KEYS TO MAP					*map-which-keys*
+
+If you are going to map something, you will need to choose which key(s) to use
+for the {lhs}.  You will have to avoid keys that are used for Vim commands,
+otherwise you would not be able to use those commands anymore.  Here are a few
+suggestions:
+- Function keys <F2>, <F3>, etc..  Also the shifted function keys <S-F1>,
+  <S-F2>, etc.  Note that <F1> is already used for the help command.
+- Meta-keys (with the ALT key pressed). |:map-alt-keys|
+- Use the '_' or ',' character and then any other character.  The "_" and ","
+  commands do exist in Vim (see |_| and |,|), but you probably never use them.
+- Use a key that is a synonym for another command.  For example: CTRL-P and
+  CTRL-N.  Use an extra character to allow more mappings.
+
+See the file "index" for keys that are not used and thus can be mapped without
+losing any builtin function.  You can also use ":help {key}^D" to find out if
+a key is used for some command.  ({key} is the specific key you want to find
+out about, ^D is CTRL-D).
+
+
+1.8 EXAMPLES						*map-examples*
+
+A few examples (given as you type them, for "<CR>" you type four characters;
+the '<' flag must not be present in 'cpoptions' for this to work). >
+
+   :map <F3>  o#include
+   :map <M-g> /foo<CR>cwbar<Esc>
+   :map _x    d/END/e<CR>
+   :map! qq   quadrillion questions
+
+
+Multiplying a count
+
+When you type a count before triggering a mapping, it's like the count was
+typed before the {lhs}.  For example, with this mapping: >
+   :map <F4>  3w
+Typing 2<F4> will result in "23w". Thus not moving 2 * 3 words but 23 words.
+If you want to multiply counts use the expression register: >
+   :map <F4>  @='3w'<CR>
+The part between quotes is the expression being executed. |@=|
+
+
+1.9 USING MAPPINGS					*map-typing*
+
+Vim will compare what you type with the start of a mapped sequence.  If there
+is an incomplete match, it will get more characters until there either is a
+complete match or until there is no match at all.  Example: If you map! "qq",
+the first 'q' will not appear on the screen until you type another
+character.  This is because Vim cannot know if the next character will be a
+'q' or not.  If the 'timeout' option is on (which is the default) Vim will
+only wait for one second (or as long as specified with the 'timeoutlen'
+option).  After that it assumes that the 'q' is to be interpreted as such.  If
+you type slowly, or your system is slow, reset the 'timeout' option.  Then you
+might want to set the 'ttimeout' option.
+
+							*map-keys-fails*
+There are situations where key codes might not be recognized:
+- Vim can only read part of the key code.  Mostly this is only the first
+  character.  This happens on some Unix versions in an xterm.
+- The key code is after character(s) that are mapped.  E.g., "<F1><F1>" or
+  "g<F1>".
+
+The result is that the key code is not recognized in this situation, and the
+mapping fails.  There are two actions needed to avoid this problem:
+
+- Remove the 'K' flag from 'cpoptions'.  This will make Vim wait for the rest
+  of the characters of the function key.
+- When using <F1> to <F4> the actual key code generated may correspond to
+  <xF1> to <xF4>.  There are mappings from <xF1> to <F1>, <xF2> to <F2>, etc.,
+  but these are not recognized after another half a mapping.  Make sure the
+  key codes for <F1> to <F4> are correct: >
+	:set <F1>=<type CTRL-V><type F1>
+< Type the <F1> as four characters.  The part after the "=" must be done with
+  the actual keys, not the literal text.
+Another solution is to use the actual key code in the mapping for the second
+special key: >
+	:map <F1><Esc>OP :echo "yes"<CR>
+Don't type a real <Esc>, Vim will recognize the key code and replace it with
+<F1> anyway.
+
+Another problem may be that when keeping ALT or Meta pressed the terminal
+prepends ESC instead of setting the 8th bit.  See |:map-alt-keys|.
+
+						*recursive_mapping*
+If you include the {lhs} in the {rhs} you have a recursive mapping.  When
+{lhs} is typed, it will be replaced with {rhs}.  When the {lhs} which is
+included in {rhs} is encountered it will be replaced with {rhs}, and so on.
+This makes it possible to repeat a command an infinite number of times.  The
+only problem is that the only way to stop this is by causing an error.  The
+macros to solve a maze uses this, look there for an example.  There is one
+exception: If the {rhs} starts with {lhs}, the first character is not mapped
+again (this is Vi compatible).
+For example: >
+   :map ab abcd
+will execute the "a" command and insert "bcd" in the text.  The "ab" in the
+{rhs} will not be mapped again.
+
+If you want to exchange the meaning of two keys you should use the :noremap
+command.  For example: >
+   :noremap k j
+   :noremap j k
+This will exchange the cursor up and down commands.
+
+With the normal :map command, when the 'remap' option is on, mapping takes
+place until the text is found not to be a part of a {lhs}.  For example, if
+you use: >
+   :map x y
+   :map y x
+Vim will replace x with y, and then y with x, etc.  When this has happened
+'maxmapdepth' times (default 1000), Vim will give the error message
+"recursive mapping".
+
+							*:map-undo*
+If you include an undo command inside a mapped sequence, this will bring the
+text back in the state before executing the macro.  This is compatible with
+the original Vi, as long as there is only one undo command in the mapped
+sequence (having two undo commands in a mapped sequence did not make sense
+in the original Vi, you would get back the text before the first undo).
+
+
+1.10 MAPPING ALT-KEYS					*:map-alt-keys*
+
+In the GUI Vim handles the Alt key itself, thus mapping keys with ALT should
+always work.  But in a terminal Vim gets a sequence of bytes and has to figure
+out whether ALT was pressed or not.
+
+By default Vim assumes that pressing the ALT key sets the 8th bit of a typed
+character.  Most decent terminals can work that way, such as xterm, aterm and
+rxvt.  If your <A-k> mappings don't work it might be that the terminal is
+prefixing the character with an ESC character.  But you can just as well type
+ESC before a character, thus Vim doesn't know what happened (except for
+checking the delay between characters, which is not reliable).
+
+As of this writing, some mainstream terminals like gnome-terminal and konsole
+use the ESC prefix.  There doesn't appear a way to have them use the 8th bit
+instead.  Xterm should work well by default.  Aterm and rxvt should work well
+when started with the "--meta8" argument.  You can also tweak resources like
+"metaSendsEscape", "eightBitInput" and "eightBitOutput".
+
+On the Linux console, this behavior can be toggled with the "setmetamode"
+command.  Bear in mind that not using an ESC prefix could get you in trouble
+with other programs.  You should make sure that bash has the "convert-meta"
+option set to "on" in order for your Meta keybindings to still work on it
+(it's the default readline behavior, unless changed by specific system
+configuration).  For that, you can add the line: >
+
+	set convert-meta on
+
+to your ~/.inputrc file. If you're creating the file, you might want to use: >
+
+	$include /etc/inputrc
+
+as the first line, if that file exists on your system, to keep global options.
+This may cause a problem for entering special characters, such as the umlaut.
+Then you should use CTRL-V before that character.
+
+Bear in mind that convert-meta has been reported to have troubles when used in
+UTF-8 locales.  On terminals like xterm, the "metaSendsEscape" resource can be
+toggled on the fly through the "Main Options" menu, by pressing Ctrl-LeftClick
+on the terminal; that's a good last resource in case you want to send ESC when
+using other applications but not when inside VIM.
+
+
+1.11 MAPPING AN OPERATOR				*:map-operator*
+
+An operator is used before a {motion} command.  To define your own operator
+you must create mapping that first sets the 'operatorfunc' option and then
+invoke the |g@| operator.  After the user types the {motion} command the
+specified function will be called.
+
+							*g@* *E774* *E775*
+g@{motion}		Call the function set by the 'operatorfunc' option.
+			The '[ mark is positioned at the start of the text
+			moved over by {motion}, the '] mark on the last
+			character of the text.
+			The function is called with one String argument:
+			    "line"	{motion} was |linewise|
+			    "char"	{motion} was |characterwise|
+			    "block"	{motion} was |blockwise-visual||
+			Although "block" would rarely appear, since it can
+			only result from Visual mode where "g@" is not useful.
+			{not available when compiled without the +eval
+			feature}
+
+Here is an example that counts the number of spaces with <F4>: >
+
+	nmap <silent> <F4> :set opfunc=CountSpaces<CR>g@
+	vmap <silent> <F4> :<C-U>call CountSpaces(visualmode(), 1)<CR>
+
+	function! CountSpaces(type, ...)
+	  let sel_save = &selection
+	  let &selection = "inclusive"
+	  let reg_save = @@
+
+	  if a:0  " Invoked from Visual mode, use '< and '> marks.
+	    silent exe "normal! `<" . a:type . "`>y"
+	  elseif a:type == 'line'
+	    silent exe "normal! '[V']y"
+	  elseif a:type == 'block'
+	    silent exe "normal! `[\<C-V>`]y"
+	  else
+	    silent exe "normal! `[v`]y"
+	  endif
+
+	  echomsg strlen(substitute(@@, '[^ ]', '', 'g'))
+
+	  let &selection = sel_save
+	  let @@ = reg_save
+	endfunction
+
+Note that the 'selection' option is temporarily set to "inclusive" to be able
+to yank exactly the right text by using Visual mode from the '[ to the ']
+mark.
+
+Also note that there is a separate mapping for Visual mode.  It removes the
+"'<,'>" range that ":" inserts in Visual mode and invokes the function with
+visualmode() and an extra argument.
+
+==============================================================================
+2. Abbreviations			*abbreviations* *Abbreviations*
+
+Abbreviations are used in Insert mode, Replace mode and Command-line mode.
+If you enter a word that is an abbreviation, it is replaced with the word it
+stands for.  This can be used to save typing for often used long words.  And
+you can use it to automatically correct obvious spelling errors.
+Examples:
+
+	:iab ms Microsoft
+	:iab tihs this
+
+There are three types of abbreviations:
+
+full-id	  The "full-id" type consists entirely of keyword characters (letters
+	  and characters from 'iskeyword' option).  This is the most common
+	  abbreviation.
+
+	  Examples: "foo", "g3", "-1"
+
+end-id	  The "end-id" type ends in a keyword character, but all the other
+	  characters are not keyword characters.
+
+	  Examples: "#i", "..f", "$/7"
+
+non-id	  The "non-id" type ends in a non-keyword character, the other
+	  characters may be of any type, excluding space and tab.  {this type
+	  is not supported by Vi}
+
+	  Examples: "def#", "4/7$"
+
+Examples of strings that cannot be abbreviations: "a.b", "#def", "a b", "_$r"
+
+An abbreviation is only recognized when you type a non-keyword character.
+This can also be the <Esc> that ends insert mode or the <CR> that ends a
+command.  The non-keyword character which ends the abbreviation is inserted
+after the expanded abbreviation.  An exception to this is the character <C-]>,
+which is used to expand an abbreviation without inserting any extra
+characters.
+
+Example: >
+   :ab hh	hello
+<	    "hh<Space>" is expanded to "hello<Space>"
+	    "hh<C-]>" is expanded to "hello"
+
+The characters before the cursor must match the abbreviation.  Each type has
+an additional rule:
+
+full-id	  In front of the match is a non-keyword character, or this is where
+	  the line or insertion starts.  Exception: When the abbreviation is
+	  only one character, it is not recognized if there is a non-keyword
+	  character in front of it, other than a space or a tab.
+
+end-id	  In front of the match is a keyword character, or a space or a tab,
+	  or this is where the line or insertion starts.
+
+non-id	  In front of the match is a space, tab or the start of the line or
+	  the insertion.
+
+Examples: ({CURSOR} is where you type a non-keyword character) >
+   :ab foo   four old otters
+<		" foo{CURSOR}"	  is expanded to " four old otters"
+		" foobar{CURSOR}" is not expanded
+		"barfoo{CURSOR}"  is not expanded
+>
+   :ab #i #include
+<		"#i{CURSOR}"	  is expanded to "#include"
+		">#i{CURSOR}"	  is not expanded
+>
+   :ab ;; <endofline>
+<		"test;;"	  is not expanded
+		"test ;;"	  is expanded to "test <endofline>"
+
+To avoid the abbreviation in insert mode: Type part of the abbreviation, exit
+insert mode with <Esc>, re-enter insert mode with "a" and type the rest.  Or
+type CTRL-V before the character after the abbreviation.
+To avoid the abbreviation in Command-line mode: Type CTRL-V twice somewhere in
+the abbreviation to avoid it to be replaced.  A CTRL-V in front of a normal
+character is mostly ignored otherwise.
+
+It is possible to move the cursor after an abbreviation: >
+   :iab if if ()<Left>
+This does not work if 'cpoptions' includes the '<' flag. |<>|
+
+You can even do more complicated things.  For example, to consume the space
+typed after an abbreviation: >
+   func Eatchar(pat)
+      let c = nr2char(getchar(0))
+      return (c =~ a:pat) ? '' : c
+   endfunc
+   iabbr <silent> if if ()<Left><C-R>=Eatchar('\s')<CR>
+
+There are no default abbreviations.
+
+Abbreviations are never recursive.  You can use ":ab f f-o-o" without any
+problem.  But abbreviations can be mapped.  {some versions of Vi support
+recursive abbreviations, for no apparent reason}
+
+Abbreviations are disabled if the 'paste' option is on.
+
+				*:abbreviate-local* *:abbreviate-<buffer>*
+Just like mappings, abbreviations can be local to a buffer.  This is mostly
+used in a |filetype-plugin| file.  Example for a C plugin file: >
+	:abb <buffer> FF  for (i = 0; i < ; ++i)
+<
+						*:ab* *:abbreviate*
+:ab[breviate]		list all abbreviations.  The character in the first
+			column indicates the mode where the abbreviation is
+			used: 'i' for insert mode, 'c' for Command-line
+			mode, '!' for both.  These are the same as for
+			mappings, see |map-listing|.
+
+						*:abbreviate-verbose*
+When 'verbose' is non-zero, listing an abbreviation will also display where it
+was last defined.  Example: >
+
+	:verbose abbreviate
+	!  teh		 the
+		Last set from /home/abcd/vim/abbr.vim
+
+See |:verbose-cmd| for more information.
+
+:ab[breviate] {lhs}	list the abbreviations that start with {lhs}
+			You may need to insert a CTRL-V (type it twice) to
+			avoid that a typed {lhs} is expanded, since
+			command-line abbreviations apply here.
+
+:ab[breviate] [<expr>] {lhs} {rhs}
+			add abbreviation for {lhs} to {rhs}.  If {lhs} already
+			existed it is replaced with the new {rhs}.  {rhs} may
+			contain spaces.
+			See |:map-<expr>| for the optional <expr> argument.
+
+						*:una* *:unabbreviate*
+:una[bbreviate] {lhs}	Remove abbreviation for {lhs} from the list.  If none
+			is found, remove abbreviations in which {lhs} matches
+			with the {rhs}.  This is done so that you can even
+			remove abbreviations after expansion.  To avoid
+			expansion insert a CTRL-V (type it twice).
+
+						*:norea* *:noreabbrev*
+:norea[bbrev] [<expr>] [lhs] [rhs]
+			same as ":ab", but no remapping for this {rhs} {not
+			in Vi}
+
+						*:ca* *:cabbrev*
+:ca[bbrev] [<expr>] [lhs] [rhs]
+			same as ":ab", but for Command-line mode only.  {not
+			in Vi}
+
+						*:cuna* *:cunabbrev*
+:cuna[bbrev] {lhs}	same as ":una", but for Command-line mode only.  {not
+			in Vi}
+
+						*:cnorea* *:cnoreabbrev*
+:cnorea[bbrev] [<expr>] [lhs] [rhs]
+			same as ":ab", but for Command-line mode only and no
+			remapping for this {rhs} {not in Vi}
+
+						*:ia* *:iabbrev*
+:ia[bbrev] [<expr>] [lhs] [rhs]
+			same as ":ab", but for Insert mode only.  {not in Vi}
+
+						*:iuna* *:iunabbrev*
+:iuna[bbrev] {lhs}	same as ":una", but for insert mode only.  {not in
+			Vi}
+
+						*:inorea* *:inoreabbrev*
+:inorea[bbrev] [<expr>] [lhs] [rhs]
+			same as ":ab", but for Insert mode only and no
+			remapping for this {rhs} {not in Vi}
+
+							*:abc* *:abclear*
+:abc[lear]		Remove all abbreviations.  {not in Vi}
+
+							*:iabc* *:iabclear*
+:iabc[lear]		Remove all abbreviations for Insert mode.  {not in Vi}
+
+							*:cabc* *:cabclear*
+:cabc[lear]		Remove all abbreviations for Command-line mode.  {not
+			in Vi}
+
+							*using_CTRL-V*
+It is possible to use special characters in the rhs of an abbreviation.
+CTRL-V has to be used to avoid the special meaning of most non printable
+characters.  How many CTRL-Vs need to be typed depends on how you enter the
+abbreviation.  This also applies to mappings.  Let's use an example here.
+
+Suppose you want to abbreviate "esc" to enter an <Esc> character.  When you
+type the ":ab" command in Vim, you have to enter this: (here ^V is a CTRL-V
+and ^[ is <Esc>)
+
+You type:   ab esc ^V^V^V^V^V^[
+
+	All keyboard input is subjected to ^V quote interpretation, so
+	the first, third, and fifth ^V  characters simply allow the second,
+	and fourth ^Vs, and the ^[, to be entered into the command-line.
+
+You see:    ab esc ^V^V^[
+
+	The command-line contains two actual ^Vs before the ^[.  This is
+	how it should appear in your .exrc file, if you choose to go that
+	route.  The first ^V is there to quote the second ^V; the :ab
+	command uses ^V as its own quote character, so you can include quoted
+	whitespace or the | character in the abbreviation.  The :ab command
+	doesn't do anything special with the ^[ character, so it doesn't need
+	to be quoted.  (Although quoting isn't harmful; that's why typing 7
+	[but not 8!] ^Vs works.)
+
+Stored as:  esc     ^V^[
+
+	After parsing, the abbreviation's short form ("esc") and long form
+	(the two characters "^V^[") are stored in the abbreviation table.
+	If you give the :ab command with no arguments, this is how the
+	abbreviation will be displayed.
+
+	Later, when the abbreviation is expanded because the user typed in
+	the word "esc", the long form is subjected to the same type of
+	^V interpretation as keyboard input.  So the ^V protects the ^[
+	character from being interpreted as the "exit Insert mode" character.
+	Instead, the ^[ is inserted into the text.
+
+Expands to: ^[
+
+[example given by Steve Kirkendall]
+
+==============================================================================
+3. Local mappings and functions				*script-local*
+
+When using several Vim script files, there is the danger that mappings and
+functions used in one script use the same name as in other scripts.  To avoid
+this, they can be made local to the script.
+
+						*<SID>* *<SNR>* *E81*
+The string "<SID>" can be used in a mapping or menu.  This requires that the
+'<' flag is not present in 'cpoptions'.
+   When executing the map command, Vim will replace "<SID>" with the special
+key code <SNR>, followed by a number that's unique for the script, and an
+underscore.  Example: >
+	:map <SID>Add
+could define a mapping "<SNR>23_Add".
+
+When defining a function in a script, "s:" can be prepended to the name to
+make it local to the script.  But when a mapping is executed from outside of
+the script, it doesn't know in which script the function was defined.  To
+avoid this problem, use "<SID>" instead of "s:".  The same translation is done
+as for mappings.  This makes it possible to define a call to the function in
+a mapping.
+
+When a local function is executed, it runs in the context of the script it was
+defined in.  This means that new functions and mappings it defines can also
+use "s:" or "<SID>" and it will use the same unique number as when the
+function itself was defined.  Also, the "s:var" local script variables can be
+used.
+
+When executing an autocommand or a user command, it will run in the context of
+the script it was defined in.  This makes it possible that the command calls a
+local function or uses a local mapping.
+
+Otherwise, using "<SID>" outside of a script context is an error.
+
+If you need to get the script number to use in a complicated script, you can
+use this function: >
+	function s:SID()
+	  return matchstr(expand('<sfile>'), '<SNR>\zs\d\+\ze_SID$')
+	endfun
+
+The "<SNR>" will be shown when listing functions and mappings.  This is useful
+to find out what they are defined to.
+
+The |:scriptnames| command can be used to see which scripts have been sourced
+and what their <SNR> number is.
+
+This is all {not in Vi} and {not available when compiled without the +eval
+feature}.
+
+==============================================================================
+4. User-defined commands				*user-commands*
+
+It is possible to define your own Ex commands.  A user-defined command can act
+just like a built-in command (it can have a range or arguments, arguments can
+be completed as filenames or buffer names, etc), except that when the command
+is executed, it is transformed into a normal ex command and then executed.
+
+For starters: See section |40.2| in the user manual.
+
+						*E183* *user-cmd-ambiguous*
+All user defined commands must start with an uppercase letter, to avoid
+confusion with builtin commands.  (There are a few builtin commands, notably
+:Next, :Print and :X, which do start with an uppercase letter.  The builtin
+will always take precedence in these cases).  The other characters of the user
+command can be uppercase letters, lowercase letters or digits.  When using
+digits, note that other commands that take a numeric argument may become
+ambiguous.  For example, the command ":Cc2" could be the user command ":Cc2"
+without an argument, or the command ":Cc" with argument "2".  It is advised to
+put a space between the command name and the argument to avoid these problems.
+
+When using a user-defined command, the command can be abbreviated.  However, if
+an abbreviation is not unique, an error will be issued.  Furthermore, a
+built-in command will always take precedence.
+
+Example: >
+	:command Rename ...
+	:command Renumber ...
+	:Rena				" Means "Rename"
+	:Renu				" Means "Renumber"
+	:Ren				" Error - ambiguous
+	:command Paste ...
+	:P				" The built-in :Print
+
+It is recommended that full names for user-defined commands are used in
+scripts.
+
+:com[mand]						*:com* *:command*
+			List all user-defined commands.  When listing commands,
+			the characters in the first two columns are
+			    !	Command has the -bang attribute
+			    "	Command has the -register attribute
+			    b	Command is local to current buffer
+			(see below for details on attributes)
+
+:com[mand] {cmd}	List the user-defined commands that start with {cmd}
+
+							*:command-verbose*
+When 'verbose' is non-zero, listing a command will also display where it was
+last defined. Example: >
+
+    :verbose command TOhtml
+<	Name	    Args Range Complete  Definition ~
+	TOhtml	    0	 %		 :call Convert2HTML(<line1>, <line2>) ~
+	    Last set from /usr/share/vim/vim-7.0/plugin/tohtml.vim ~
+
+See |:verbose-cmd| for more information.
+
+							*E174* *E182*
+:com[mand][!] [{attr}...] {cmd} {rep}
+			Define a user command.  The name of the command is
+			{cmd} and its replacement text is {rep}.  The command's
+			attributes (see below) are {attr}.  If the command
+			already exists, an error is reported, unless a ! is
+			specified, in which case the command is redefined.
+
+:delc[ommand] {cmd}				*:delc* *:delcommand* *E184*
+			Delete the user-defined command {cmd}.
+
+:comc[lear]						*:comc* *:comclear*
+			Delete all user-defined commands.
+
+Command attributes
+
+User-defined commands are treated by Vim just like any other ex commands.  They
+can have arguments, or have a range specified.  Arguments are subject to
+completion as filenames, buffers, etc.  Exactly how this works depends upon the
+command's attributes, which are specified when the command is defined.
+
+There are a number of attributes, split into four categories: argument
+handling, completion behavior, range handling, and special cases.  The
+attributes are described below, by category.
+
+Argument handling				*E175* *E176* *:command-nargs*
+
+By default, a user defined command will take no arguments (and an error is
+reported if any are supplied).  However, it is possible to specify that the
+command can take arguments, using the -nargs attribute.  Valid cases are:
+
+	-nargs=0    No arguments are allowed (the default)
+	-nargs=1    Exactly one argument is required
+	-nargs=*    Any number of arguments are allowed (0, 1, or many)
+	-nargs=?    0 or 1 arguments are allowed
+	-nargs=+    Arguments must be supplied, but any number are allowed
+
+Arguments are considered to be separated by (unescaped) spaces or tabs in this
+context.
+
+Note that arguments are used as text, not as expressions.  Specifically,
+"s:var" will use the script-local variable in the script where the command was
+defined, not where it is invoked!  Example:
+    script1.vim: >
+	:let s:error = "None"
+	:command -nargs=1 Error echoerr <args>
+<   script2.vim: >
+	:source script1.vim
+	:let s:error = "Wrong!"
+	:Error s:error
+Executing script2.vim will result in "None" to be echoed.  Not what you
+intended!  Calling a function may be an alternative.
+
+Completion behavior				*:command-completion* *E179*
+					*E180* *E181* *:command-complete*
+By default, the arguments of user defined commands do not undergo completion.
+However, by specifying one or the other of the following attributes, argument
+completion can be enabled:
+
+	-complete=augroup	autocmd groups
+	-complete=buffer	buffer names
+	-complete=command	Ex command (and arguments)
+	-complete=dir		directory names
+	-complete=environment	environment variable names
+	-complete=event		autocommand events
+	-complete=expression	Vim expression
+	-complete=file		file and directory names
+	-complete=shellcmd	Shell command
+	-complete=function	function name
+	-complete=help		help subjects
+	-complete=highlight	highlight groups
+	-complete=mapping	mapping name
+	-complete=menu		menus
+	-complete=option	options
+	-complete=tag		tags
+	-complete=tag_listfiles	tags, file names are shown when CTRL-D is hit
+	-complete=var		user variables
+	-complete=custom,{func} custom completion, defined via {func}
+	-complete=customlist,{func} custom completion, defined via {func}
+
+
+Custom completion			*:command-completion-custom*
+					*:command-completion-customlist*
+					*E467* *E468*
+It is possible to define customized completion schemes via the "custom,{func}"
+or the "customlist,{func}" completion argument.  The {func} part should be a
+function with the following prototype >
+
+	:function {func}(ArgLead, CmdLine, CursorPos)
+
+The function need not use all these arguments. The function should provide the
+completion candidates as the return value.
+
+For the "custom" argument, the function should return the completion
+candidates one per line in a newline separated string.
+
+For the "customlist" argument, the function should return the completion
+candidates as a Vim List.  Non-string items in the list are ignored.
+
+The function arguments are:
+	ArgLead		the leading portion of the argument currently being
+			completed on
+	CmdLine		the entire command line
+	CursorPos	the cursor position in it (byte index)
+The function may use these for determining context.  For the "custom"
+argument, it is not necessary to filter candidates against the (implicit
+pattern in) ArgLead.  Vim will do filter the candidates with its regexp engine
+after function return, and this is probably more efficient in most cases. For
+the "customlist" argument, Vim will not filter the returned completion
+candidates and the user supplied function should filter the candidates.
+
+The following example lists user names to a Finger command >
+    :com -complete=custom,ListUsers -nargs=1 Finger !finger <args>
+    :fun ListUsers(A,L,P)
+    :    return system("cut -d: -f1 /etc/passwd")
+    :endfun
+
+The following example completes filenames from the directories specified in
+the 'path' option: >
+    :com -nargs=1 -bang -complete=customlist,EditFileComplete
+			\ EditFile edit<bang> <args>
+    :fun EditFileComplete(A,L,P)
+    :    return split(globpath(&path, a:ArgLead), "\n")
+    :endfun
+<
+
+Range handling				*E177* *E178* *:command-range*
+							*:command-count*
+By default, user-defined commands do not accept a line number range.  However,
+it is possible to specify that the command does take a range (the -range
+attribute), or that it takes an arbitrary count value, either in the line
+number position (-range=N, like the |:split| command) or as a "count"
+argument (-count=N, like the |:Next| command).  The count will then be
+available in the argument with |<count>|.
+
+Possible attributes are:
+
+	-range	    Range allowed, default is current line
+	-range=%    Range allowed, default is whole file (1,$)
+	-range=N    A count (default N) which is specified in the line
+		    number position (like |:split|)
+	-count=N    A count (default N) which is specified either in the line
+		    number position, or as an initial argument (like |:Next|).
+		    Specifying -count (without a default) acts like -count=0
+
+Note that -range=N and -count=N are mutually exclusive - only one should be
+specified.
+
+Special cases				*:command-bang* *:command-bar*
+					*:command-register* *:command-buffer*
+There are some special cases as well:
+
+	-bang	    The command can take a ! modifier (like :q or :w)
+	-bar	    The command can be followed by a "|" and another command.
+		    A "|" inside the command argument is not allowed then.
+		    Also checks for a " to start a comment.
+	-register   The first argument to the command can be an optional
+		    register name (like :del, :put, :yank).
+	-buffer	    The command will only be available in the current buffer.
+
+In the cases of the -count and -register attributes, if the optional argument
+is supplied, it is removed from the argument list and is available to the
+replacement text separately.
+
+Replacement text
+
+The replacement text for a user defined command is scanned for special escape
+sequences, using <...> notation.  Escape sequences are replaced with values
+from the entered command line, and all other text is copied unchanged.  The
+resulting string is executed as an Ex command.  To avoid the replacement use
+<lt> in plade of the initial <.  Thus to include "<bang>" literally use
+"<lt>bang>".
+
+The valid escape sequences are
+
+						*<line1>*
+	<line1>	The starting line of the command range.
+						*<line2>*
+	<line2>	The final line of the command range.
+						*<count>*
+	<count>	Any count supplied (as described for the '-range'
+		and '-count' attributes).
+						*<bang>*
+	<bang>	(See the '-bang' attribute) Expands to a ! if the
+		command was executed with a ! modifier, otherwise
+		expands to nothing.
+						*<reg>* *<register>*
+	<reg>	(See the '-register' attribute) The optional register,
+		if specified.  Otherwise, expands to nothing.  <register>
+		is a synonym for this.
+						*<args>*
+	<args>	The command arguments, exactly as supplied (but as
+		noted above, any count or register can consume some
+		of the arguments, which are then not part of <args>).
+	<lt>	A single '<' (Less-Than) character.  This is needed if you
+		want to get a literal copy of one of these escape sequences
+		into the expansion - for example, to get <bang>, use
+		<lt>bang>.
+
+							*<q-args>*
+If the first two characters of an escape sequence are "q-" (for example,
+<q-args>) then the value is quoted in such a way as to make it a valid value
+for use in an expression.  This uses the argument as one single value.
+When there is no argument <q-args> is an empty string.
+							*<f-args>*
+To allow commands to pass their arguments on to a user-defined function, there
+is a special form <f-args> ("function args").  This splits the command
+arguments at spaces and tabs, quotes each argument individually, and the
+<f-args> sequence is replaced by the comma-separated list of quoted arguments.
+See the Mycmd example below.  If no arguments are given <f-args> is removed.
+   To embed whitespace into an argument of <f-args>, prepend a backslash.
+<f-args> replaces every pair of backslashes (\\) with one backslash.  A
+backslash followed by a character other than white space or a backslash
+remains unmodified.  Overview:
+
+	command		   <f-args> ~
+	XX ab		   'ab'
+	XX a\b		   'a\b'
+	XX a\ b		   'a b'
+	XX a\  b	   'a ', 'b'
+	XX a\\b		   'a\b'
+	XX a\\ b	   'a\', 'b'
+	XX a\\\b	   'a\\b'
+	XX a\\\ b	   'a\ b'
+	XX a\\\\b	   'a\\b'
+	XX a\\\\ b	   'a\\', 'b'
+
+Examples >
+
+   " Delete everything after here to the end
+   :com Ddel +,$d
+
+   " Rename the current buffer
+   :com -nargs=1 -bang -complete=file Ren f <args>|w<bang>
+
+   " Replace a range with the contents of a file
+   " (Enter this all as one line)
+   :com -range -nargs=1 -complete=file
+	 Replace <line1>-pu_|<line1>,<line2>d|r <args>|<line1>d
+
+   " Count the number of lines in the range
+   :com! -range -nargs=0 Lines  echo <line2> - <line1> + 1 "lines"
+
+   " Call a user function (example of <f-args>)
+   :com -nargs=* Mycmd call Myfunc(<f-args>)
+
+When executed as: >
+	:Mycmd arg1 arg2
+This will invoke: >
+	:call Myfunc("arg1","arg2")
+
+   :" A more substantial example
+   :function Allargs(command)
+   :	let i = 0
+   :	while i < argc()
+   :	   if filereadable(argv(i))
+   :	    execute "e " . argv(i)
+   :	     execute a:command
+   :      endif
+   :      let i = i + 1
+   :   endwhile
+   :endfunction
+   :command -nargs=+ -complete=command Allargs call Allargs(<q-args>)
+
+The command Allargs takes any Vim command(s) as argument and executes it on all
+files in the argument list.  Usage example (note use of the "e" flag to ignore
+errors and the "update" command to write modified buffers): >
+	:Allargs %s/foo/bar/ge|update
+This will invoke: >
+	:call Allargs("%s/foo/bar/ge|update")
+<
+When defining an user command in a script, it will be able to call functions
+local to the script and use mappings local to the script.  When the user
+invokes the user command, it will run in the context of the script it was
+defined in.  This matters if |<SID>| is used in a command.
+
+ vim:tw=78:ts=8:ft=help:norl:
--- /dev/null
+++ b/lib/vimfiles/doc/mbyte.txt
@@ -1,0 +1,1408 @@
+*mbyte.txt*     For Vim version 7.1.  Last change: 2006 Aug 11
+
+
+		  VIM REFERENCE MANUAL	  by Bram Moolenaar et al.
+
+
+Multi-byte support				*multibyte* *multi-byte*
+						*Chinese* *Japanese* *Korean*
+This is about editing text in languages which have many characters that can
+not be represented using one byte (one octet).  Examples are Chinese, Japanese
+and Korean.  Unicode is also covered here.
+
+For an introduction to the most common features, see |usr_45.txt| in the user
+manual.
+For changing the language of messages and menus see |mlang.txt|.
+
+{not available when compiled without the +multi_byte feature}
+
+
+1.  Getting started			|mbyte-first|
+2.  Locale				|mbyte-locale|
+3.  Encoding				|mbyte-encoding|
+4.  Using a terminal			|mbyte-terminal|
+5.  Fonts on X11			|mbyte-fonts-X11|
+6.  Fonts on MS-Windows			|mbyte-fonts-MSwin|
+7.  Input on X11			|mbyte-XIM|
+8.  Input on MS-Windows			|mbyte-IME|
+9.  Input with a keymap			|mbyte-keymap|
+10. Using UTF-8				|mbyte-utf8|
+11. Overview of options			|mbyte-options|
+
+NOTE: This file contains UTF-8 characters.  These may show up as strange
+characters or boxes when using another encoding.
+
+==============================================================================
+1. Getting started					*mbyte-first*
+
+This is a summary of the multibyte features in Vim.  If you are lucky it works
+as described and you can start using Vim without much trouble.  If something
+doesn't work you will have to read the rest.  Don't be surprised if it takes
+quite a bit of work and experimenting to make Vim use all the multi-byte
+features.  Unfortunately, every system has its own way to deal with multibyte
+languages and it is quite complicated.
+
+
+COMPILING
+
+If you already have a compiled Vim program, check if the |+multi_byte| feature
+is included.  The |:version| command can be used for this.
+
+If +multi_byte is not included, you should compile Vim with "big" features.
+You can further tune what features are included.  See the INSTALL files in the
+source directory.
+
+
+LOCALE
+
+First of all, you must make sure your current locale is set correctly.  If
+your system has been installed to use the language, it probably works right
+away.  If not, you can often make it work by setting the $LANG environment
+variable in your shell: >
+
+	setenv LANG ja_JP.EUC
+
+Unfortunately, the name of the locale depends on your system.  Japanese might
+also be called "ja_JP.EUCjp" or just "ja".  To see what is currently used: >
+
+	:language
+
+To change the locale inside Vim use: >
+
+	:language ja_JP.EUC
+
+Vim will give an error message if this doesn't work.  This is a good way to
+experiment and find the locale name you want to use.  But it's always better
+to set the locale in the shell, so that it is used right from the start.
+
+See |mbyte-locale| for details.
+
+
+ENCODING
+
+If your locale works properly, Vim will try to set the 'encoding' option
+accordingly.  If this doesn't work you can overrule its value: >
+
+	:set encoding=utf-8
+
+See |encoding-values| for a list of acceptable values.
+
+The result is that all the text that is used inside Vim will be in this
+encoding.  Not only the text in the buffers, but also in registers, variables,
+etc.  This also means that changing the value of 'encoding' makes the existing
+text invalid!  The text doesn't change, but it will be displayed wrong.
+
+You can edit files in another encoding than what 'encoding' is set to.  Vim
+will convert the file when you read it and convert it back when you write it.
+See 'fileencoding', 'fileencodings' and |++enc|.
+
+
+DISPLAY AND FONTS
+
+If you are working in a terminal (emulator) you must make sure it accepts the
+same encoding as which Vim is working with.  If this is not the case, you can
+use the 'termencoding' option to make Vim convert text automatically.
+
+For the GUI you must select fonts that work with the current 'encoding'.  This
+is the difficult part.  It depends on the system you are using, the locale and
+a few other things.  See the chapters on fonts: |mbyte-fonts-X11| for
+X-Windows and |mbyte-fonts-MSwin| for MS-Windows.
+
+For GTK+ 2, you can skip most of this section.  The option 'guifontset' does
+no longer exist.  You only need to set 'guifont' and everything should "just
+work".  If your system comes with Xft2 and fontconfig and the current font
+does not contain a certain glyph, a different font will be used automatically
+if available.  The 'guifontwide' option is still supported but usually you do
+not need to set it.  It is only necessary if the automatic font selection does
+not suit your needs.
+
+For X11 you can set the 'guifontset' option to a list of fonts that together
+cover the characters that are used.  Example for Korean: >
+
+	:set guifontset=k12,r12
+
+Alternatively, you can set 'guifont' and 'guifontwide'.  'guifont' is used for
+the single-width characters, 'guifontwide' for the double-width characters.
+Thus the 'guifontwide' font must be exactly twice as wide as 'guifont'.
+Example for UTF-8: >
+
+	:set guifont=-misc-fixed-medium-r-normal-*-18-120-100-100-c-90-iso10646-1
+	:set guifontwide=-misc-fixed-medium-r-normal-*-18-120-100-100-c-180-iso10646-1
+
+You can also set 'guifont' alone, Vim will try to find a matching
+'guifontwide' for you.
+
+
+INPUT
+
+There are several ways to enter multi-byte characters:
+- For X11 XIM can be used.  See |XIM|.
+- For MS-Windows IME can be used.  See |IME|.
+- For all systems keymaps can be used.  See |mbyte-keymap|.
+
+The options 'iminsert', 'imsearch' and 'imcmdline' can be used to chose
+the different input methods or disable them temporarily.
+
+==============================================================================
+2.  Locale						*mbyte-locale*
+
+The easiest setup is when your whole system uses the locale you want to work
+in.  But it's also possible to set the locale for one shell you are working
+in, or just use a certain locale inside Vim.
+
+
+WHAT IS A LOCALE?					*locale*
+
+There are many of languages in the world.  And there are different cultures
+and environments at least as much as the number of languages.	A linguistic
+environment corresponding to an area is called "locale".  This includes
+information about the used language, the charset, collating order for sorting,
+date format, currency format and so on.  For Vim only the language and charset
+really matter.
+
+You can only use a locale if your system has support for it.  Some systems
+have only a few locales, especially in the USA.  The language which you want
+to use may not be on your system.  In that case you might be able to install
+it as an extra package.  Check your system documentation for how to do that.
+
+The location in which the locales are installed varies from system to system.
+For example, "/usr/share/locale" or "/usr/lib/locale".  See your system's
+setlocale() man page.
+
+Looking in these directories will show you the exact name of each locale.
+Mostly upper/lowercase matters, thus "ja_JP.EUC" and "ja_jp.euc" are
+different.  Some systems have a locale.alias file, which allows translation
+from a short name like "nl" to the full name "nl_NL.ISO_8859-1".
+
+Note that X-windows has its own locale stuff.  And unfortunately uses locale
+names different from what is used elsewhere.  This is confusing!  For Vim it
+matters what the setlocale() function uses, which is generally NOT the
+X-windows stuff.  You might have to do some experiments to find out what
+really works.
+
+							*locale-name*
+The (simplified) format of |locale| name is:
+
+	language
+or	language_territory
+or	language_territory.codeset
+
+Territory means the country (or part of it), codeset means the |charset|.  For
+example, the locale name "ja_JP.eucJP" means:
+	ja	the language is Japanese
+	JP	the country is Japan
+	eucJP	the codeset is EUC-JP
+But it also could be "ja", "ja_JP.EUC", "ja_JP.ujis", etc.  And unfortunately,
+the locale name for a specific language, territory and codeset is not unified
+and depends on your system.
+
+Examples of locale name:
+    charset	    language		  locale name ~
+    GB2312	    Chinese (simplified)  zh_CN.EUC, zh_CN.GB2312
+    Big5	    Chinese (traditional) zh_TW.BIG5, zh_TW.Big5
+    CNS-11643	    Chinese (traditional) zh_TW
+    EUC-JP	    Japanese		  ja, ja_JP.EUC, ja_JP.ujis, ja_JP.eucJP
+    Shift_JIS	    Japanese		  ja_JP.SJIS, ja_JP.Shift_JIS
+    EUC-KR	    Korean		  ko, ko_KR.EUC
+
+
+USING A LOCALE
+
+To start using a locale for the whole system, see the documentation of your
+system.  Mostly you need to set it in a configuration file in "/etc".
+
+To use a locale in a shell, set the $LANG environment value.  When you want to
+use Korean and the |locale| name is "ko", do this:
+
+    sh:    export LANG=ko
+    csh:   setenv LANG ko
+
+You can put this in your ~/.profile or ~/.cshrc file to always use it.
+
+To use a locale in Vim only, use the |:language| command: >
+
+	:language ko
+
+Put this in your ~/.vimrc file to use it always.
+
+Or specify $LANG when starting Vim:
+
+   sh:    LANG=ko vim {vim-arguments}
+   csh:	  env LANG=ko vim {vim-arguments}
+
+You could make a small shell script for this.
+
+==============================================================================
+3.  Encoding				*mbyte-encoding*
+
+Vim uses the 'encoding' option to specify how characters identified and
+encoded when they are used inside Vim.  This applies to all the places where
+text is used, including buffers (files loaded into memory), registers and
+variables.
+
+							*charset* *codeset*
+Charset is another name for encoding.  There are subtle differences, but these
+don't matter when using Vim.  "codeset" is another similar name.
+
+Each character is encoded as one or more bytes.  When all characters are
+encoded with one byte, we call this a single-byte encoding.  The most often
+used one is called "latin1".  This limits the number of characters to 256.
+Some of these are control characters, thus even fewer can be used for text.
+
+When some characters use two or more bytes, we call this a multi-byte
+encoding.  This allows using much more than 256 characters, which is required
+for most East Asian languages.
+
+Most multi-byte encodings use one byte for the first 127 characters.  These
+are equal to ASCII, which makes it easy to exchange plain-ASCII text, no
+matter what language is used.  Thus you might see the right text even when the
+encoding was set wrong.
+
+							*encoding-names*
+Vim can use many different character encodings.  There are three major groups:
+
+1   8bit	Single-byte encodings, 256 different characters.  Mostly used
+		in USA and Europe.  Example: ISO-8859-1 (Latin1).  All
+		characters occupy one screen cell only.
+
+2   2byte	Double-byte encodings, over 10000 different characters.
+		Mostly used in Asian countries.  Example: euc-kr (Korean)
+		The number of screen cells is equal to the number of bytes
+		(except for euc-jp when the first byte is 0x8e).
+
+u   Unicode	Universal encoding, can replace all others.  ISO 10646.
+		Millions of different characters.  Example: UTF-8.  The
+		relation between bytes and screen cells is complex.
+
+Other encodings cannot be used by Vim internally.  But files in other
+encodings can be edited by using conversion, see 'fileencoding'.
+Note that all encodings must use ASCII for the characters up to 128 (except
+when compiled for EBCDIC).
+
+Supported 'encoding' values are:			*encoding-values*
+1   latin1	8-bit characters (ISO 8859-1)
+1   iso-8859-n	ISO_8859 variant (n = 2 to 15)
+1   koi8-r	Russian
+1   koi8-u	Ukrainian
+1   macroman    MacRoman (Macintosh encoding)
+1   8bit-{name} any 8-bit encoding (Vim specific name)
+1   cp437	similar to iso-8859-1
+1   cp737	similar to iso-8859-7
+1   cp775	Baltic
+1   cp850	similar to iso-8859-4
+1   cp852	similar to iso-8859-1
+1   cp855	similar to iso-8859-2
+1   cp857	similar to iso-8859-5
+1   cp860	similar to iso-8859-9
+1   cp861	similar to iso-8859-1
+1   cp862	similar to iso-8859-1
+1   cp863	similar to iso-8859-8
+1   cp865	similar to iso-8859-1
+1   cp866	similar to iso-8859-5
+1   cp869	similar to iso-8859-7
+1   cp874	Thai
+1   cp1250	Czech, Polish, etc.
+1   cp1251	Cyrillic
+1   cp1253	Greek
+1   cp1254	Turkish
+1   cp1255	Hebrew
+1   cp1256	Arabic
+1   cp1257	Baltic
+1   cp1258	Vietnamese
+1   cp{number}	MS-Windows: any installed single-byte codepage
+2   cp932	Japanese (Windows only)
+2   euc-jp	Japanese (Unix only)
+2   sjis	Japanese (Unix only)
+2   cp949	Korean (Unix and Windows)
+2   euc-kr	Korean (Unix only)
+2   cp936	simplified Chinese (Windows only)
+2   euc-cn	simplified Chinese (Unix only)
+2   cp950	traditional Chinese (on Unix alias for big5)
+2   big5	traditional Chinese (on Windows alias for cp950)
+2   euc-tw	traditional Chinese (Unix only)
+2   2byte-{name} Unix: any double-byte encoding (Vim specific name)
+2   cp{number}	MS-Windows: any installed double-byte codepage
+u   utf-8	32 bit UTF-8 encoded Unicode (ISO/IEC 10646-1)
+u   ucs-2	16 bit UCS-2 encoded Unicode (ISO/IEC 10646-1)
+u   ucs-2le	like ucs-2, little endian
+u   utf-16	ucs-2 extended with double-words for more characters
+u   utf-16le	like utf-16, little endian
+u   ucs-4	32 bit UCS-4 encoded Unicode (ISO/IEC 10646-1)
+u   ucs-4le	like ucs-4, little endian
+
+The {name} can be any encoding name that your system supports.  It is passed
+to iconv() to convert between the encoding of the file and the current locale.
+For MS-Windows "cp{number}" means using codepage {number}.
+Examples: >
+		:set encoding=8bit-cp1252
+		:set encoding=2byte-cp932
+<
+Several aliases can be used, they are translated to one of the names above.
+An incomplete list:
+
+1   ansi	same as latin1 (obsolete, for backward compatibility)
+2   japan	Japanese: on Unix "euc-jp", on MS-Windows cp932
+2   korea	Korean: on Unix "euc-kr", on MS-Windows cp949
+2   prc		simplified Chinese: on Unix "euc-cn", on MS-Windows cp936
+2   chinese     same as "prc"
+2   taiwan	traditional Chinese: on Unix "euc-tw", on MS-Windows cp950
+u   utf8	same as utf-8
+u   unicode	same as ucs-2
+u   ucs2be	same as ucs-2 (big endian)
+u   ucs-2be	same as ucs-2 (big endian)
+u   ucs-4be	same as ucs-4 (big endian)
+    default     stands for the default value of 'encoding', depends on the
+		environment
+
+For the UCS codes the byte order matters.  This is tricky, use UTF-8 whenever
+you can.  The default is to use big-endian (most significant byte comes
+first):
+	    name	bytes		char ~
+	    ucs-2	      11 22	    1122
+	    ucs-2le	      22 11	    1122
+	    ucs-4	11 22 33 44	11223344
+	    ucs-4le	44 33 22 11	11223344
+
+On MS-Windows systems you often want to use "ucs-2le", because it uses little
+endian UCS-2.
+
+There are a few encodings which are similar, but not exactly the same.  Vim
+treats them as if they were different encodings, so that conversion will be
+done when needed.  You might want to use the similar name to avoid conversion
+or when conversion is not possible:
+
+	cp932, shift-jis, sjis
+	cp936, euc-cn
+
+							*encoding-table*
+Normally 'encoding' is equal to your current locale and 'termencoding' is
+empty.  This means that your keyboard and display work with characters encoded
+in your current locale, and Vim uses the same characters internally.
+
+You can make Vim use characters in a different encoding by setting the
+'encoding' option to a different value.  Since the keyboard and display still
+use the current locale, conversion needs to be done.  The 'termencoding' then
+takes over the value of the current locale, so Vim converts between 'encoding'
+and 'termencoding'.  Example: >
+	:let &termencoding = &encoding
+	:set encoding=utf-8
+
+However, not all combinations of values are possible.  The table below tells
+you how each of the nine combinations works.  This is further restricted by
+not all conversions being possible, iconv() being present, etc.  Since this
+depends on the system used, no detailed list can be given.
+
+('tenc' is the short name for 'termencoding' and 'enc' short for 'encoding')
+
+'tenc'	    'enc'	remark ~
+
+ 8bit	    8bit	Works.  When 'termencoding' is different from
+			'encoding' typing and displaying may be wrong for some
+			characters, Vim does NOT perform conversion (set
+			'encoding' to "utf-8" to get this).
+ 8bit      2byte	MS-Windows: works for all codepages installed on your
+			system; you can only type 8bit characters;
+			Other systems: does NOT work.
+ 8bit	   Unicode	Works, but only 8bit characters can be typed directly
+			(others through digraphs, keymaps, etc.); in a
+			terminal you can only see 8bit characters; the GUI can
+			show all characters that the 'guifont' supports.
+
+ 2byte	    8bit	Works, but typing non-ASCII characters might
+			be a problem.
+ 2byte	   2byte	MS-Windows: works for all codepages installed on your
+			system; typing characters might be a problem when
+			locale is different from 'encoding'.
+			Other systems: Only works when 'termencoding' is equal
+			to 'encoding', you might as well leave it empty.
+ 2byte	   Unicode	works, Vim will translate typed characters.
+
+ Unicode    8bit	works (unusual)
+ Unicode    2byte	does NOT work
+ Unicode   Unicode	works very well (leaving 'termencoding' empty works
+			the same way, because all Unicode is handled
+			internally as UTF-8)
+
+CONVERSION						*charset-conversion*
+
+Vim will automatically convert from one to another encoding in several places:
+- When reading a file and 'fileencoding' is different from 'encoding'
+- When writing a file and 'fileencoding' is different from 'encoding'
+- When displaying characters and 'termencoding' is different from 'encoding'
+- When reading input and 'termencoding' is different from 'encoding'
+- When displaying messages and the encoding used for LC_MESSAGES differs from
+  'encoding' (requires a gettext version that supports this).
+- When reading a Vim script where |:scriptencoding| is different from
+  'encoding'.
+- When reading or writing a |viminfo| file.
+Most of these require the |+iconv| feature.  Conversion for reading and
+writing files may also be specified with the 'charconvert' option.
+
+Useful utilities for converting the charset:
+    All:	    iconv
+	GNU iconv can convert most encodings.  Unicode is used as the
+	intermediate encoding, which allows conversion from and to all other
+	encodings.  See http://www.gnu.org/directory/libiconv.html.
+
+    Japanese:	    nkf
+	Nkf is "Network Kanji code conversion Filter".  One of the most unique
+	facility of nkf is the guess of the input Kanji code.  So, you don't
+	need to know what the inputting file's |charset| is.  When convert to
+	EUC-JP from ISO-2022-JP or Shift_JIS, simply do the following command
+	in Vim:
+	    :%!nkf -e
+	Nkf can be found at:
+	http://www.sfc.wide.ad.jp/~max/FreeBSD/ports/distfiles/nkf-1.62.tar.gz
+
+    Chinese:	    hc
+	Hc is "Hanzi Converter".  Hc convert a GB file to a Big5 file, or Big5
+	file to GB file.  Hc can be found at:
+	ftp://ftp.cuhk.hk/pub/chinese/ifcss/software/unix/convert/hc-30.tar.gz
+
+    Korean:	    hmconv
+	Hmconv is Korean code conversion utility especially for E-mail.  It can
+	convert between EUC-KR and ISO-2022-KR.  Hmconv can be found at:
+	ftp://ftp.kaist.ac.kr/pub/hangul/code/hmconv/
+
+    Multilingual:   lv
+	Lv is a Powerful Multilingual File Viewer.  And it can be worked as
+	|charset| converter.  Supported |charset|: ISO-2022-CN, ISO-2022-JP,
+	ISO-2022-KR, EUC-CN, EUC-JP, EUC-KR, EUC-TW, UTF-7, UTF-8, ISO-8859
+	series, Shift_JIS, Big5 and HZ.  Lv can be found at:
+	http://www.ff.iij4u.or.jp/~nrt/freeware/lv4495.tar.gz
+
+
+							*mbyte-conversion*
+When reading and writing files in an encoding different from 'encoding',
+conversion needs to be done.  These conversions are supported:
+- All conversions between Latin-1 (ISO-8859-1), UTF-8, UCS-2 and UCS-4 are
+  handled internally.
+- For MS-Windows, when 'encoding' is a Unicode encoding, conversion from and
+  to any codepage should work.
+- Conversion specified with 'charconvert'
+- Conversion with the iconv library, if it is available.
+	Old versions of GNU iconv() may cause the conversion to fail (they
+	request a very large buffer, more than Vim is willing to provide).
+	Try getting another iconv() implementation.
+
+							*iconv-dynamic*
+On MS-Windows Vim can be compiled with the |+iconv/dyn| feature.  This means
+Vim will search for the "iconv.dll" and "libiconv.dll" libraries.  When
+neither of them can be found Vim will still work but some conversions won't be
+possible.
+
+==============================================================================
+4. Using a terminal					*mbyte-terminal*
+
+The GUI fully supports multi-byte characters.  It is also possible in a
+terminal, if the terminal supports the same encoding that Vim uses.  Thus this
+is less flexible.
+
+For example, you can run Vim in a xterm with added multi-byte support and/or
+|XIM|.  Examples are kterm (Kanji term) and hanterm (for Korean), Eterm
+(Enlightened terminal) and rxvt.
+
+If your terminal does not support the right encoding, you can set the
+'termencoding' option.  Vim will then convert the typed characters from
+'termencoding' to 'encoding'.  And displayed text will be converted from
+'encoding' to 'termencoding'.  If the encoding supported by the terminal
+doesn't include all the characters that Vim uses, this leads to lost
+characters.  This may mess up the display.  If you use a terminal that
+supports Unicode, such as the xterm mentioned below, it should work just fine,
+since nearly every character set can be converted to Unicode without loss of
+information.
+
+
+UTF-8 IN XFREE86 XTERM					*UTF8-xterm*
+
+This is a short explanation of how to use UTF-8 character encoding in the
+xterm that comes with XFree86 by Thomas Dickey (text by Markus Kuhn).
+
+Get the latest xterm version which has now UTF-8 support:
+
+	http://invisible-island.net/xterm/xterm.html
+
+Compile it with "./configure --enable-wide-chars ; make"
+
+Also get the ISO 10646-1 version of various fonts, which is available on
+
+	http://www.cl.cam.ac.uk/~mgk25/download/ucs-fonts.tar.gz
+
+and install the font as described in the README file.
+
+Now start xterm with >
+
+  xterm -u8 -fn -misc-fixed-medium-r-semicondensed--13-120-75-75-c-60-iso10646-1
+or, for bigger character: >
+  xterm -u8 -fn -misc-fixed-medium-r-normal--15-140-75-75-c-90-iso10646-1
+
+and you will have a working UTF-8 terminal emulator.  Try both >
+
+   cat utf-8-demo.txt
+   vim utf-8-demo.txt
+
+with the demo text that comes with ucs-fonts.tar.gz in order to see
+whether there are any problems with UTF-8 in your xterm.
+
+For Vim you may need to set 'encoding' to "utf-8".
+
+==============================================================================
+5.  Fonts on X11					*mbyte-fonts-X11*
+
+Unfortunately, using fonts in X11 is complicated.  The name of a single-byte
+font is a long string.  For multi-byte fonts we need several of these...
+
+Note: Most of this is no longer relevant for GTK+ 2.  Selecting a font via
+its XLFD is not supported anymore; see 'guifont' for an example of how to
+set the font.  Do yourself a favor and ignore the |XLFD| and |xfontset|
+sections below.
+
+First of all, Vim only accepts fixed-width fonts for displaying text.  You
+cannot use proportionally spaced fonts.  This excludes many of the available
+(and nicer looking) fonts.  However, for menus and tooltips any font can be
+used.
+
+Note that Display and Input are independent.  It is possible to see your
+language even though you have no input method for it.
+
+You should get a default font for menus and tooltips that works, but it might
+be ugly.  Read the following to find out how to select a better font.
+
+
+X LOGICAL FONT DESCRIPTION (XLFD)
+							*XLFD*
+XLFD is the X font name and contains the information about the font size,
+charset, etc.  The name is in this format:
+
+FOUNDRY-FAMILY-WEIGHT-SLANT-WIDTH-STYLE-PIXEL-POINT-X-Y-SPACE-AVE-CR-CE
+
+Each field means:
+
+- FOUNDRY:  FOUNDRY field.  The company that created the font.
+- FAMILY:   FAMILY_NAME field.  Basic font family name.  (helvetica, gothic,
+	    times, etc)
+- WEIGHT:   WEIGHT_NAME field.  How thick the letters are.  (light, medium,
+	    bold, etc)
+- SLANT:    SLANT field.
+		r:  Roman (no slant)
+		i:  Italic
+		o:  Oblique
+		ri: Reverse Italic
+		ro: Reverse Oblique
+		ot: Other
+		number:	Scaled font
+- WIDTH:    SETWIDTH_NAME field.  Width of characters.  (normal, condensed,
+	    narrow, double wide)
+- STYLE:    ADD_STYLE_NAME field.  Extra info to describe font.  (Serif, Sans
+	    Serif, Informal, Decorated, etc)
+- PIXEL:    PIXEL_SIZE field.  Height, in pixels, of characters.
+- POINT:    POINT_SIZE field.  Ten times height of characters in points.
+- X:	    RESOLUTION_X field.  X resolution (dots per inch).
+- Y:	    RESOLUTION_Y field.  Y resolution (dots per inch).
+- SPACE:    SPACING field.
+		p:  Proportional
+		m:  Monospaced
+		c:  CharCell
+- AVE:	    AVERAGE_WIDTH field.  Ten times average width in pixels.
+- CR:	    CHARSET_REGISTRY field.  The name of the charset group.
+- CE:	    CHARSET_ENCODING field.  The rest of the charset name.  For some
+	    charsets, such as JIS X 0208, if this field is 0, code points has
+	    the same value as GL, and GR if 1.
+
+For example, in case of a 14 dots font corresponding to JIS X 0208, it is
+written like:
+    -misc-fixed-medium-r-normal--16-110-100-100-c-160-jisx0208.1990-0
+
+
+X FONTSET
+						*fontset* *xfontset*
+A single-byte charset is typically associated with one font.  For multi-byte
+charsets a combination of fonts is often used.  This means that one group of
+characters are used from one font and another group from another font (which
+might be double wide).  This collection of fonts is called a fontset.
+
+Which fonts are required in a fontset depends on the current locale.  X
+windows maintains a table of which groups of characters are required for a
+locale.  You have to specify all the fonts that a locale requires in the
+'guifontset' option.
+
+NOTE: The fontset always uses the current locale, even though 'encoding' may
+be set to use a different charset.  In that situation you might want to use
+'guifont' and 'guifontwide' instead of 'guifontset'.
+
+Example:
+    |charset| language		    "groups of characters" ~
+    GB2312    Chinese (simplified)  ISO-8859-1 and GB 2312
+    Big5      Chinese (traditional) ISO-8859-1 and Big5
+    CNS-11643 Chinese (traditional) ISO-8859-1, CNS 11643-1 and CNS 11643-2
+    EUC-JP    Japanese		    JIS X 0201 and JIS X 0208
+    EUC-KR    Korean		    ISO-8859-1 and KS C 5601 (KS X 1001)
+
+You can search for fonts using the xlsfonts command.  For example, when you're
+searching for a font for KS C 5601: >
+    xlsfonts | grep ksc5601
+
+This is complicated and confusing.  You might want to consult the X-Windows
+documentation if there is something you don't understand.
+
+						*base_font_name_list*
+When you have found the names of the fonts you want to use, you need to set
+the 'guifontset' option.  You specify the list by concatenating the font names
+and putting a comma in between them.
+
+For example, when you use the ja_JP.eucJP locale, this requires JIS X 0201
+and JIS X 0208.  You could supply a list of fonts that explicitly specifies
+the charsets, like: >
+
+ :set guifontset=-misc-fixed-medium-r-normal--14-130-75-75-c-140-jisx0208.1983-0,
+	\-misc-fixed-medium-r-normal--14-130-75-75-c-70-jisx0201.1976-0
+
+Alternatively, you can supply a base font name list that omits the charset
+name, letting X-Windows select font characters required for the locale.  For
+example: >
+
+ :set guifontset=-misc-fixed-medium-r-normal--14-130-75-75-c-140,
+	\-misc-fixed-medium-r-normal--14-130-75-75-c-70
+
+Alternatively, you can supply a single base font name that allows X-Windows to
+select from all available fonts.  For example: >
+
+ :set guifontset=-misc-fixed-medium-r-normal--14-*
+
+Alternatively, you can specify alias names.  See the fonts.alias file in the
+fonts directory (e.g., /usr/X11R6/lib/X11/fonts/).  For example: >
+
+ :set guifontset=k14,r14
+<
+							*E253*
+Note that in East Asian fonts, the standard character cell is square.  When
+mixing a Latin font and an East Asian font, the East Asian font width should
+be twice the Latin font width.
+
+If 'guifontset' is not empty, the "font" argument of the |:highlight| command
+is also interpreted as a fontset.  For example, you should use for
+highlighting: >
+	:hi Comment font=english_font,your_font
+If you use a wrong "font" argument you will get an error message.
+Also make sure that you set 'guifontset' before setting fonts for highlight
+groups.
+
+
+USING RESOURCE FILES
+
+Instead of specifying 'guifontset', you can set X11 resources and Vim will
+pick them up.  This is only for people who know how X resource files work.
+
+For Motif and Athena insert these three lines in your $HOME/.Xdefaults file:
+
+	Vim.font: |base_font_name_list|
+	Vim*fontSet: |base_font_name_list|
+	Vim*fontList: your_language_font
+
+Note: Vim.font is for text area.
+      Vim*fontSet is for menu.
+      Vim*fontList is for menu (for Motif GUI)
+
+For example, when you are using Japanese and a 14 dots font, >
+
+	Vim.font: -misc-fixed-medium-r-normal--14-*
+	Vim*fontSet: -misc-fixed-medium-r-normal--14-*
+	Vim*fontList: -misc-fixed-medium-r-normal--14-*
+<
+or: >
+
+	Vim*font: k14,r14
+	Vim*fontSet: k14,r14
+	Vim*fontList: k14,r14
+<
+To have them take effect immediately you will have to do >
+
+	xrdb -merge ~/.Xdefaults
+
+Otherwise you will have to stop and restart the X server before the changes
+take effect.
+
+
+The GTK+ version of GUI Vim does not use .Xdefaults, use ~/.gtkrc instead.
+The default mostly works OK.  But for the menus you might have to change
+it.  Example: >
+
+	style "default"
+	{
+		fontset="-*-*-medium-r-normal--14-*-*-*-c-*-*-*"
+	}
+	widget_class "*" style "default"
+
+==============================================================================
+6.  Fonts on MS-Windows				*mbyte-fonts-MSwin*
+
+The simplest is to use the font dialog to select fonts and try them out.  You
+can find this at the "Edit/Select Font..." menu.  Once you find a font name
+that works well you can use this command to see its name: >
+
+	:set guifont
+
+Then add a command to your |gvimrc| file to set 'guifont': >
+
+	:set guifont=courier_new:h12
+
+==============================================================================
+7.  Input on X11				*mbyte-XIM*
+
+X INPUT METHOD (XIM) BACKGROUND			*XIM* *xim* *x-input-method*
+
+XIM is an international input module for X.  There are two kind of structures,
+Xlib unit type and |IM-server| (Input-Method server) type.  |IM-server| type
+is suitable for complex input, such as CJK.
+
+- IM-server
+							*IM-server*
+  In |IM-server| type input structures, the input event is handled by either
+  of the two ways: FrontEnd system and BackEnd system.  In the FrontEnd
+  system, input events are snatched by the |IM-server| first, then |IM-server|
+  give the application the result of input.  On the other hand, the BackEnd
+  system works reverse order.  MS Windows adopt BackEnd system.  In X, most of
+  |IM-server|s adopt FrontEnd system.  The demerit of BackEnd system is the
+  large overhead in communication, but it provides safe synchronization with
+  no restrictions on applications.
+
+  For example, there are xwnmo and kinput2 Japanese |IM-server|, both are
+  FrontEnd system.  Xwnmo is distributed with Wnn (see below), kinput2 can be
+  found at: ftp://ftp.sra.co.jp/pub/x11/kinput2/
+
+  For Chinese, there's a great XIM server named "xcin", you can input both
+  Traditional and Simplified Chinese characters.  And it can accept other
+  locale if you make a correct input table.  Xcin can be found at:
+  http://xcin.linux.org.tw/
+  Others are scim: http://scim.freedesktop.org/ and fcitx:
+  http://www.fcitx.org/
+
+- Conversion Server
+							*conversion-server*
+  Some system needs additional server: conversion server.  Most of Japanese
+  |IM-server|s need it, Kana-Kanji conversion server.  For Chinese inputting,
+  it depends on the method of inputting, in some methods, PinYin or ZhuYin to
+  HanZi conversion server is needed.  For Korean inputting, if you want to
+  input Hanja, Hangul-Hanja conversion server is needed.
+
+  For example, the Japanese inputting process is divided into 2 steps.  First
+  we pre-input Hira-gana, second Kana-Kanji conversion.  There are so many
+  Kanji characters (6349 Kanji characters are defined in JIS X 0208) and the
+  number of Hira-gana characters are 76.  So, first, we pre-input text as
+  pronounced in Hira-gana, second, we convert Hira-gana to Kanji or Kata-Kana,
+  if needed.  There are some Kana-Kanji conversion server: jserver
+  (distributed with Wnn, see below) and canna.  Canna could be found at:
+  ftp://ftp.nec.co.jp/pub/Canna/ (no longer works).
+
+There is a good input system: Wnn4.2.  Wnn 4.2 contains,
+    xwnmo (|IM-server|)
+    jserver (Japanese Kana-Kanji conversion server)
+    cserver (Chinese PinYin or ZhuYin to simplified HanZi conversion server)
+    tserver (Chinese PinYin or ZhuYin to traditional HanZi conversion server)
+    kserver (Hangul-Hanja conversion server)
+Wnn 4.2 for several systems can be found at various places on the internet.
+Use the RPM or port for your system.
+
+
+- Input Style
+							*xim-input-style*
+  When inputting CJK, there are four areas:
+      1. The area to display of the input while it is being composed
+      2. The area to display the currently active input mode.
+      3. The area to display the next candidate for the selection.
+      4. The area to display other tools.
+
+  The third area is needed when converting.  For example, in Japanese
+  inputting, multiple Kanji characters could have the same pronunciation, so
+  a sequence of Hira-gana characters could map to a distinct sequence of Kanji
+  characters.
+
+  The first and second areas are defined in international input of X with the
+  names of "Preedit Area", "Status Area" respectively.  The third and fourth
+  areas are not defined and are left to be managed by the |IM-server|.  In the
+  international input, four input styles have been defined using combinations
+  of Preedit Area and Status Area: |OnTheSpot|, |OffTheSpot|, |OverTheSpot|
+  and |Root|.
+
+  Currently, GUI Vim support three style, |OverTheSpot|, |OffTheSpot| and
+  |Root|.
+
+*.  on-the-spot						*OnTheSpot*
+    Preedit Area and Status Area are performed by the client application in
+    the area of application.  The client application is directed by the
+    |IM-server| to display all pre-edit data at the location of text
+    insertion.  The client registers callbacks invoked by the input method
+    during pre-editing.
+*.  over-the-spot					*OverTheSpot*
+    Status Area is created in a fixed position within the area of application,
+    in case of Vim, the position is the additional status line.  Preedit Area
+    is made at present input position of application.  The input method
+    displays pre-edit data in a window which it brings up directly over the
+    text insertion position.
+*.  off-the-spot					*OffTheSpot*
+    Preedit Area and Status Area are performed in the area of application, in
+    case of Vim, the area is additional status line.  The client application
+    provides display windows for the pre-edit data to the input method which
+    displays into them directly.
+*.  root-window						*Root*
+    Preedit Area and Status Area are outside of the application.  The input
+    method displays all pre-edit data in a separate area of the screen in a
+    window specific to the input method.
+
+
+USING XIM			*multibyte-input* *E284* *E286* *E287* *E288*
+				*E285* *E291* *E292* *E290* *E289*
+
+Note that Display and Input are independent.  It is possible to see your
+language even though you have no input method for it.  But when your Display
+method doesn't match your Input method, the text will be displayed wrong.
+
+	Note: You can not use IM unless you specify 'guifontset'.
+	      Therefore, Latin users, you have to also use 'guifontset'
+	      if you use IM.
+
+To input your language you should run the |IM-server| which supports your
+language and |conversion-server| if needed.
+
+The next 3 lines should be put in your ~/.Xdefaults file.  They are common for
+all X applications which uses |XIM|.  If you already use |XIM|, you can skip
+this. >
+
+	*international: True
+	*.inputMethod: your_input_server_name
+	*.preeditType: your_input_style
+<
+input_server_name	is your |IM-server| name (check your |IM-server|
+			manual).
+your_input_style	is one of |OverTheSpot|, |OffTheSpot|, |Root|.  See
+			also |xim-input-style|.
+
+*international may not necessary if you use X11R6.
+*.inputMethod and *.preeditType are optional if you use X11R6.
+
+For example, when you are using kinput2 as |IM-server|, >
+
+	*international: True
+	*.inputMethod: kinput2
+	*.preeditType: OverTheSpot
+<
+When using |OverTheSpot|, GUI Vim always connects to the IM Server even in
+Normal mode, so you can input your language with commands like "f" and "r".
+But when using one of the other two methods, GUI Vim connects to the IM Server
+only if it is not in Normal mode.
+
+If your IM Server does not support |OverTheSpot|, and if you want to use your
+language with some Normal mode command like "f" or "r", then you should use a
+localized xterm  or an xterm which supports |XIM|
+
+If needed, you can set the XMODIFIERS environment variable:
+
+	sh:  export XMODIFIERS="@im=input_server_name"
+	csh: setenv XMODIFIERS "@im=input_server_name"
+
+For example, when you are using kinput2 as |IM-server| and sh, >
+
+	export XMODIFIERS="@im=kinput2"
+<
+
+FULLY CONTROLLED XIM
+
+You can fully control XIM, like with IME of MS-Windows (see |multibyte-ime|).
+This is currently only available for the GTK GUI.
+
+Before using fully controlled XIM, one setting is required.  Set the
+'imactivatekey' option to the key that is used for the activation of the input
+method.  For example, when you are using kinput2 + canna as IM Server, the
+activation key is probably Shift+Space: >
+
+	:set imactivatekey=S-space
+
+See 'imactivatekey' for the format.
+
+==============================================================================
+8.  Input on MS-Windows					*mbyte-IME*
+
+(Windows IME support)				*multibyte-ime* *IME*
+
+{only works Windows GUI and compiled with the |+multi_byte_ime| feature}
+
+To input multibyte characters on Windows, you have to use Input Method Editor
+(IME).  In process of your editing text, you must switch status (on/off) of
+IME many many many times.  Because IME with status on is hooking all of your
+key inputs, you cannot input 'j', 'k', or almost all of keys to Vim directly.
+
+This |+multi_byte_ime| feature help this.  It reduce times of switch status of
+IME manually.  In normal mode, there are almost no need working IME, even
+editing multibyte text.  So exiting insert mode with ESC, Vim memorize last
+status of IME and force turn off IME.  When re-enter insert mode, Vim revert
+IME status to that memorized automatically.
+
+This works on not only insert-normal mode, but also search-command input and
+replace mode.
+The options 'iminsert', 'imsearch' and 'imcmdline' can be used to chose
+the different input methods or disable them temporarily.
+
+WHAT IS IME
+    IME is a part of East asian version Windows.  That helps you to input
+    multibyte character.  English and other language version Windows does not
+    have any IME.  (Also there are no need usually.) But there is one that
+    called Microsoft Global IME.  Global IME is a part of Internet Explorer
+    4.0 or above.  You can get more information about Global IME, at below
+    URL.
+
+WHAT IS GLOBAL IME					*global-ime*
+    Global IME makes capability to input Chinese, Japanese, and Korean text
+    into Vim buffer on any language version of Windows 98, Windows 95, and
+    Windows NT 4.0.
+    On Windows 2000 and XP it should work as well (without downloading).  On
+    Windows 2000 Professional, Global IME is built in, and the Input Locales
+    can be added through Control Panel/Regional Options/Input Locales.
+    Please see below URL for detail of Global IME.  You can also find various
+    language version of Global IME at same place.
+
+    - Global IME detailed information.
+	http://www.microsoft.com/windows/ie/features/ime.asp
+
+    - Active Input Method Manager (Global IME)
+	http://msdn.microsoft.com/workshop/misc/AIMM/aimm.asp
+
+    Support Global IME is a experimental feature.
+
+NOTE: For IME to work you must make sure the input locales of your language
+are added to your system.  The exact location of this depends on the version
+of Windows you use.  For example, on my W2P box:
+1. Control Panel
+2. Regional Options
+3. Input Locales Tab
+4. Add Installed input locales -> Chinese(PRC)
+   The default is still English (United Stated)
+
+
+Cursor color when IME or XIM is on				*CursorIM*
+    There is a little cute feature for IME.  Cursor can indicate status of IME
+    by changing its color.  Usually status of IME was indicated by little icon
+    at a corner of desktop (or taskbar).  It is not easy to verify status of
+    IME.  But this feature help this.
+    This works in the same way when using XIM.
+
+    You can select cursor color when status is on by using highlight group
+    CursorIM.  For example, add these lines to your |gvimrc|: >
+
+	if has('multi_byte_ime')
+	    highlight Cursor guifg=NONE guibg=Green
+	    highlight CursorIM guifg=NONE guibg=Purple
+	endif
+<
+    Cursor color with off IME is green.  And purple cursor indicates that
+    status is on.
+
+==============================================================================
+9. Input with a keymap					*mbyte-keymap*
+
+When the keyboard doesn't produce the characters you want to enter in your
+text, you can use the 'keymap' option.  This will translate one or more
+(English) characters to another (non-English) character.  This only happens
+when typing text, not when typing Vim commands.  This avoids having to switch
+between two keyboard settings.
+
+The value of the 'keymap' option specifies a keymap file to use.  The name of
+this file is one of these two:
+
+	keymap/{keymap}_{encoding}.vim
+	keymap/{keymap}.vim
+
+Here {keymap} is the value of the 'keymap' option and {encoding} of the
+'encoding' option.  The file name with the {encoding} included is tried first.
+
+'runtimepath' is used to find these files.  To see an overview of all
+available keymap files, use this: >
+	:echo globpath(&rtp, "keymap/*.vim")
+
+In Insert and Command-line mode you can use CTRL-^ to toggle between using the
+keyboard map or not. |i_CTRL-^| |c_CTRL-^|
+This flag is remembered for Insert mode with the 'iminsert' option.  When
+leaving and entering Insert mode the previous value is used.  The same value
+is also used for commands that take a single character argument, like |f| and
+|r|.
+For Command-line mode the flag is NOT remembered.  You are expected to type an
+Ex command first, which is ASCII.
+For typing search patterns the 'imsearch' option is used.  It can be set to
+use the same value as for 'iminsert'.
+
+It is possible to give the GUI cursor another color when the language mappings
+are being used.  This is disabled by default, to avoid that the cursor becomes
+invisible when you use a non-standard background color.  Here is an example to
+use a brightly colored cursor: >
+	:highlight Cursor guifg=NONE guibg=Green
+	:highlight lCursor guifg=NONE guibg=Cyan
+<
+		*keymap-file-format* *:loadk* *:loadkeymap* *E105* *E791*
+The keymap file looks something like this: >
+
+	" Maintainer:	name <email@address>
+	" Last Changed:	2001 Jan 1
+
+	let b:keymap_name = "short"
+
+	loadkeymap
+	a	A
+	b	B	comment
+
+The lines starting with a " are comments and will be ignored.  Blank lines are
+also ignored.  The lines with the mappings may have a comment after the useful
+text.
+
+The "b:keymap_name" can be set to a short name, which will be shown in the
+status line.  The idea is that this takes less room than the value of
+'keymap', which might be long to distinguish between different languages,
+keyboards and encodings.
+
+The actual mappings are in the lines below "loadkeymap".  In the example "a"
+is mapped to "A" and "b" to "B".  Thus the first item is mapped to the second
+item.  This is done for each line, until the end of the file.
+These items are exactly the same as what can be used in a |:lnoremap| command,
+using "<buffer>" to make the mappings local to the buffer..
+You can check the result with this command: >
+	:lmap
+The two items must be separated by white space.  You cannot include white
+space inside an item, use the special names "<Tab>" and "<Space>" instead.
+The length of the two items together must not exceed 200 bytes.
+
+It's possible to have more than one character in the first column.  This works
+like a dead key.  Example: >
+	'a	á
+Since Vim doesn't know if the next character after a quote is really an "a",
+it will wait for the next character.  To be able to insert a single quote,
+also add this line: >
+	''	'
+Since the mapping is defined with |:lnoremap| the resulting quote will not be
+used for the start of another character.
+The "accents" keymap uses this.				*keymap-accents*
+
+Although it's possible to have more than one character in the second column,
+this is unusual.  But you can use various ways to specify the character: >
+	A	a		literal character
+	A	<char-97>	decimal value
+	A	<char-0x61>	hexadecimal value
+	A	<char-0141>	octal value
+	x	<Space>		special key name
+
+The characters are assumed to be encoded for the current value of 'encoding'.
+It's possible to use ":scriptencoding" when all characters are given
+literally.  That doesn't work when using the <char-> construct, because the
+conversion is done on the keymap file, not on the resulting character.
+
+The lines after "loadkeymap" are interpreted with 'cpoptions' set to "C".
+This means that continuation lines are not used and a backslash has a special
+meaning in the mappings.  Examples: >
+
+	" a comment line
+	\"	x	maps " to x
+	\\	y	maps \ to y
+
+If you write a keymap file that will be useful for others, consider submitting
+it to the Vim maintainer for inclusion in the distribution:
+<maintainer@vim.org>
+
+
+HEBREW KEYMAP						*keymap-hebrew*
+
+This file explains what characters are available in UTF-8 and CP1255 encodings,
+and what the keymaps are to get those characters:
+
+glyph   encoding	   keymap ~
+Char   utf-8 cp1255  hebrew  hebrewp  name ~
+א    0x5d0  0xe0     t	      a     'alef
+ב    0x5d1  0xe1     c	      b     bet
+ג    0x5d2  0xe2     d	      g     gimel
+ד    0x5d3  0xe3     s	      d     dalet
+ה    0x5d4  0xe4     v	      h     he
+ו    0x5d5  0xe5     u	      v     vav
+ז    0x5d6  0xe6     z	      z     zayin
+ח    0x5d7  0xe7     j	      j     het
+ט    0x5d8  0xe8     y	      T     tet
+י    0x5d9  0xe9     h	      y     yod
+ך    0x5da  0xea     l	      K     kaf sofit
+כ    0x5db  0xeb     f	      k     kaf
+ל    0x5dc  0xec     k	      l     lamed
+ם    0x5dd  0xed     o	      M     mem sofit
+מ    0x5de  0xee     n	      m     mem
+ן    0x5df  0xef     i	      N     nun sofit
+נ    0x5e0  0xf0     b	      n     nun
+ס    0x5e1  0xf1     x	      s     samech
+ע    0x5e2  0xf2     g	      u     `ayin
+ף    0x5e3  0xf3     ;	      P     pe sofit
+פ    0x5e4  0xf4     p	      p     pe
+ץ    0x5e5  0xf5     .	      X     tsadi sofit
+צ    0x5e6  0xf6     m	      x     tsadi
+ק    0x5e7  0xf7     e	      q     qof
+ר    0x5e8  0xf8     r	      r     resh
+ש    0x5e9  0xf9     a	      w     shin
+ת    0x5ea  0xfa     ,	      t     tav
+
+Vowel marks and special punctuation:
+הְ    0x5b0  0xc0     A:      A:   sheva
+הֱ    0x5b1  0xc1     HE      HE   hataf segol
+הֲ    0x5b2  0xc2     HA      HA   hataf patah
+הֳ    0x5b3  0xc3     HO      HO   hataf qamats
+הִ    0x5b4  0xc4     I       I    hiriq
+הֵ    0x5b5  0xc5     AY      AY   tsere
+הֶ    0x5b6  0xc6     E       E    segol
+הַ    0x5b7  0xc7     AA      AA   patah
+הָ    0x5b8  0xc8     AO      AO   qamats
+הֹ    0x5b9  0xc9     O       O    holam
+הֻ    0x5bb  0xcb     U       U    qubuts
+כּ    0x5bc  0xcc     D       D    dagesh
+הֽ    0x5bd  0xcd     ]T      ]T   meteg
+ה־   0x5be  0xce     ]Q      ]Q   maqaf
+בֿ    0x5bf  0xcf     ]R      ]R   rafe
+ב׀   0x5c0  0xd0     ]p      ]p   paseq
+שׁ    0x5c1  0xd1     SR      SR   shin-dot
+שׂ    0x5c2  0xd2     SL      SL   sin-dot
+׃    0x5c3  0xd3     ]P      ]P   sof-pasuq
+װ    0x5f0  0xd4     VV      VV   double-vav
+ױ    0x5f1  0xd5     VY      VY   vav-yod
+ײ    0x5f2  0xd6     YY      YY   yod-yod
+
+The following are only available in utf-8
+
+Cantillation marks:
+glyph
+Char utf-8 hebrew name
+ב֑    0x591   C:   etnahta
+ב֒    0x592   Cs   segol
+ב֓    0x593   CS   shalshelet
+ב֔    0x594   Cz   zaqef qatan
+ב֕    0x595   CZ   zaqef gadol
+ב֖    0x596   Ct   tipeha
+ב֗    0x597   Cr   revia
+ב֘    0x598   Cq   zarqa
+ב֙    0x599   Cp   pashta
+ב֚    0x59a   C!   yetiv
+ב֛    0x59b   Cv   tevir
+ב֜    0x59c   Cg   geresh
+ב֝    0x59d   C*   geresh qadim
+ב֞    0x59e   CG   gershayim
+ב֟    0x59f   CP   qarnei-parah
+ב֪    0x5aa   Cy   yerach-ben-yomo
+ב֫    0x5ab   Co   ole
+ב֬    0x5ac   Ci   iluy
+ב֭    0x5ad   Cd   dehi
+ב֮    0x5ae   Cn   zinor
+ב֯    0x5af   CC   masora circle
+
+Combining forms:
+ﬠ    0xfb20  X`   Alternative `ayin
+ﬡ    0xfb21  X'   Alternative 'alef
+ﬢ    0xfb22  X-d  Alternative dalet
+ﬣ    0xfb23  X-h  Alternative he
+ﬤ    0xfb24  X-k  Alternative kaf
+ﬥ    0xfb25  X-l  Alternative lamed
+ﬦ    0xfb26  X-m  Alternative mem-sofit
+ﬧ    0xfb27  X-r  Alternative resh
+ﬨ    0xfb28  X-t  Alternative tav
+﬩    0xfb29  X-+  Alternative plus
+שׁ    0xfb2a  XW   shin+shin-dot
+שׂ    0xfb2b  Xw   shin+sin-dot
+שּׁ    0xfb2c  X..W  shin+shin-dot+dagesh
+שּׂ    0xfb2d  X..w  shin+sin-dot+dagesh
+אַ    0xfb2e  XA   alef+patah
+אָ    0xfb2f  XO   alef+qamats
+אּ    0xfb30  XI   alef+hiriq (mapiq)
+בּ    0xfb31  X.b  bet+dagesh
+גּ    0xfb32  X.g  gimel+dagesh
+דּ    0xfb33  X.d  dalet+dagesh
+הּ    0xfb34  X.h  he+dagesh
+וּ    0xfb35  Xu  vav+dagesh
+זּ    0xfb36  X.z  zayin+dagesh
+טּ    0xfb38  X.T  tet+dagesh
+יּ    0xfb39  X.y  yud+dagesh
+ךּ    0xfb3a  X.K  kaf sofit+dagesh
+כּ    0xfb3b  X.k  kaf+dagesh
+לּ    0xfb3c  X.l  lamed+dagesh
+מּ    0xfb3e  X.m  mem+dagesh
+נּ    0xfb40  X.n  nun+dagesh
+סּ    0xfb41  X.s  samech+dagesh
+ףּ    0xfb43  X.P  pe sofit+dagesh
+פּ    0xfb44  X.p  pe+dagesh
+צּ    0xfb46  X.x  tsadi+dagesh
+קּ    0xfb47  X.q  qof+dagesh
+רּ    0xfb48  X.r  resh+dagesh
+שּ    0xfb49  X.w  shin+dagesh
+תּ    0xfb4a  X.t  tav+dagesh
+וֹ    0xfb4b  Xo   vav+holam
+בֿ    0xfb4c  XRb  bet+rafe
+כֿ    0xfb4d  XRk  kaf+rafe
+פֿ    0xfb4e  XRp  pe+rafe
+ﭏ    0xfb4f  Xal  alef-lamed
+
+==============================================================================
+10. Using UTF-8				*mbyte-utf8* *UTF-8* *utf-8* *utf8*
+							*Unicode* *unicode*
+The Unicode character set was designed to include all characters from other
+character sets.  Therefore it is possible to write text in any language using
+Unicode (with a few rarely used languages excluded).  And it's mostly possible
+to mix these languages in one file, which is impossible with other encodings.
+
+Unicode can be encoded in several ways.  The two most popular ones are UCS-2,
+which uses 16-bit words and UTF-8, which uses one or more bytes for each
+character.  Vim can support all of these encodings, but always uses UTF-8
+internally.
+
+Vim has comprehensive UTF-8 support.  It appears to work in:
+- xterm with utf-8 support enabled
+- Athena, Motif and GTK GUI
+- MS-Windows GUI
+
+Double-width characters are supported.  This works best with 'guifontwide' or
+'guifontset'.  When using only 'guifont' the wide characters are drawn in the
+normal width and a space to fill the gap.  Note that the 'guifontset' option
+is no longer relevant in the GTK+ 2 GUI.
+
+					*mbyte-combining* *mbyte-composing*
+A composing or combining character is used to change the meaning of the
+character before it.  The combining characters are drawn on top of the
+preceding character.
+Up to two combining characters can be used by default.  This can be changed
+with the 'maxcombine' option.
+When editing text a composing character is mostly considered part of the
+preceding character.  For example "x" will delete a character and its
+following composing characters by default.
+If the 'delcombine' option is on, then pressing 'x' will delete the combining
+characters, one at a time, then the base character.  But when inserting, you
+type the first character and the following composing characters separately,
+after which they will be joined.  The "r" command will not allow you to type a
+combining character, because it doesn't know one is coming.  Use "R" instead.
+
+Bytes which are not part of a valid UTF-8 byte sequence are handled like a
+single character and displayed as <xx>, where "xx" is the hex value of the
+byte.
+
+Overlong sequences are not handled specially and displayed like a valid
+character.  However, search patterns may not match on an overlong sequence.
+(an overlong sequence is where more bytes are used than required for the
+character.)  An exception is NUL (zero) which is displayed as "<00>".
+
+In the file and buffer the full range of Unicode characters can be used (31
+bits).  However, displaying only works for 16 bit characters, and only for the
+characters present in the selected font.
+
+Useful commands:
+- "ga" shows the decimal, hexadecimal and octal value of the character under
+  the cursor.  If there are composing characters these are shown too.  (If the
+  message is truncated, use ":messages").
+- "g8" shows the bytes used in a UTF-8 character, also the composing
+  characters, as hex numbers.
+- ":set encoding=utf-8 fileencodings=" forces using UTF-8 for all files.  The
+  default is to use the current locale for 'encoding' and set 'fileencodings'
+  to automatically the encoding of a file.
+
+
+STARTING VIM
+
+If your current locale is in an utf-8 encoding, Vim will automatically start
+in utf-8 mode.
+
+If you are using another locale: >
+
+	set encoding=utf-8
+
+You might also want to select the font used for the menus.  Unfortunately this
+doesn't always work.  See the system specific remarks below, and 'langmenu'.
+
+
+USING UTF-8 IN X-Windows				*utf-8-in-xwindows*
+
+Note: This section does not apply to the GTK+ 2 GUI.
+
+You need to specify a font to be used.  For double-wide characters another
+font is required, which is exactly twice as wide.  There are three ways to do
+this:
+
+1. Set 'guifont' and let Vim find a matching 'guifontwide'
+2. Set 'guifont' and 'guifontwide'
+3. Set 'guifontset'
+
+See the documentation for each option for details.  Example: >
+
+   :set guifont=-misc-fixed-medium-r-normal--15-140-75-75-c-90-iso10646-1
+
+You might also want to set the font used for the menus.  This only works for
+Motif.  Use the ":hi Menu font={fontname}" command for this. |:highlight|
+
+
+TYPING UTF-8						*utf-8-typing*
+
+If you are using X-Windows, you should find an input method that supports
+utf-8.
+
+If your system does not provide support for typing utf-8, you can use the
+'keymap' feature.  This allows writing a keymap file, which defines a utf-8
+character as a sequence of ASCII characters.  See |mbyte-keymap|.
+
+Another method is to set the current locale to the language you want to use
+and for which you have a XIM available.  Then set 'termencoding' to that
+language and Vim will convert the typed characters to 'encoding' for you.
+
+If everything else fails, you can type any character as four hex bytes: >
+
+	CTRL-V u 1234
+
+"1234" is interpreted as a hex number.  You must type four characters, prepend
+a zero if necessary.
+
+
+COMMAND ARGUMENTS					*utf-8-char-arg*
+
+Commands like |f|, |F|, |t| and |r| take an argument of one character.  For
+UTF-8 this argument may include one or two composing characters.  These need
+to be produced together with the base character, Vim doesn't wait for the next
+character to be typed to find out if it is a composing character or not.
+Using 'keymap' or |:lmap| is a nice way to type these characters.
+
+The commands that search for a character in a line handle composing characters
+as follows.  When searching for a character without a composing character,
+this will find matches in the text with or without composing characters.  When
+searching for a character with a composing character, this will only find
+matches with that composing character.  It was implemented this way, because
+not everybody is able to type a composing character.
+
+
+==============================================================================
+11. Overview of options					*mbyte-options*
+
+These options are relevant for editing multi-byte files.  Check the help in
+options.txt for detailed information.
+
+'encoding'	Encoding used for the keyboard and display.  It is also the
+		default encoding for files.
+
+'fileencoding'	Encoding of a file.  When it's different from 'encoding'
+		conversion is done when reading or writing the file.
+
+'fileencodings'	List of possible encodings of a file.  When opening a file
+		these will be tried and the first one that doesn't cause an
+		error is used for 'fileencoding'.
+
+'charconvert'	Expression used to convert files from one encoding to another.
+
+'formatoptions' The 'm' flag can be included to have formatting break a line
+		at a multibyte character of 256 or higher.  Thus is useful for
+		languages where a sequence of characters can be broken
+		anywhere.
+
+'guifontset'	The list of font names used for a multi-byte encoding.  When
+		this option is not empty, it replaces 'guifont'.
+
+'keymap'	Specify the name of a keyboard mapping.
+
+==============================================================================
+
+Contributions specifically for the multi-byte features by:
+	Chi-Deok Hwang <hwang@mizi.co.kr>
+	Nam SungHyun <namsh@kldp.org>
+	K.Nagano <nagano@atese.advantest.co.jp>
+	Taro Muraoka  <koron@tka.att.ne.jp>
+	Yasuhiro Matsumoto <mattn@mail.goo.ne.jp>
+
+ vim:tw=78:ts=8:ft=help:norl:
--- /dev/null
+++ b/lib/vimfiles/doc/message.txt
@@ -1,0 +1,832 @@
+*message.txt*   For Vim version 7.1.  Last change: 2007 Mar 20
+
+
+		  VIM REFERENCE MANUAL    by Bram Moolenaar
+
+
+This file contains an alphabetical list of messages and error messages that
+Vim produces.  You can use this if you don't understand what the message
+means.  It is not complete though.
+
+1. Old messages		|:messages|
+2. Error messages	|error-messages|
+3. Messages		|messages|
+
+==============================================================================
+1. Old messages			*:messages* *:mes* *message-history*
+
+The ":messages" command can be used to view previously given messages.  This
+is especially useful when messages have been overwritten or truncated.  This
+depends on the 'shortmess' option.
+
+The number of remembered messages is fixed at 20 for the tiny version and 100
+for other versions.
+
+								*g<*
+The "g<" command can be used to see the last page of previous command output.
+This is especially useful if you accidentally typed <Space> at the hit-enter
+prompt.  You are then back at the hit-enter prompt and can then scroll further
+back.
+Note: when you stopped the output with "q" at the more prompt only up to that
+point will be displayed.
+The previous command output is cleared when another command produces output.
+
+If you are using translated messages, the first printed line tells who
+maintains the messages or the translations.  You can use this to contact the
+maintainer when you spot a mistake.
+
+If you want to find help on a specific (error) message, use the ID at the
+start of the message.  For example, to get help on the message: >
+
+	E72: Close error on swap file
+
+or (translated): >
+
+	E72: Errore durante chiusura swap file
+
+Use: >
+
+	:help E72
+
+If you are lazy, it also works without the shift key: >
+
+	:help e72
+
+==============================================================================
+2. Error messages					*error-messages*
+
+When an error message is displayed, but it is removed before you could read
+it, you can see it again with: >
+  :echo errmsg
+or view a list of recent messages with: >
+  :messages
+
+
+LIST OF MESSAGES
+			*E222* *E228* *E232* *E256* *E293* *E298* *E304* *E317*
+			*E318* *E356* *E438* *E439* *E440* *E316* *E320* *E322*
+			*E323* *E341* *E473* *E570* *E685* >
+  Add to read buffer
+  makemap: Illegal mode
+  Cannot create BalloonEval with both message and callback
+  Hangul automata ERROR
+  block was not locked
+  Didn't get block nr {N}?
+  ml_timestamp: Didn't get block 0??
+  pointer block id wrong {N}
+  Updated too many blocks?
+  get_varp ERROR
+  u_undo: line numbers wrong
+  undo list corrupt
+  undo line missing
+  ml_get: cannot find line {N}
+  cannot find line {N}
+  line number out of range: {N} past the end
+  line count wrong in block {N}
+  Internal error
+  Internal error: {function}
+  fatal error in cs_manage_matches
+
+This is an internal error.  If you can reproduce it, please send in a bug
+report. |bugs|
+
+>
+  ATTENTION
+  Found a swap file by the name ...
+
+See |ATTENTION|.
+
+							*E92*  >
+  Buffer {N} not found
+
+The buffer you requested does not exist.  This can also happen when you have
+wiped out a buffer which contains a mark or is referenced in another way.
+|:bwipeout|
+
+							*E95*  >
+  Buffer with this name already exists
+
+You cannot have two buffers with the same name.
+
+							*E72*  >
+  Close error on swap file
+
+The |swap-file|, that is used to keep a copy of the edited text, could not be
+closed properly.  Mostly harmless.
+
+							*E169*  >
+  Command too recursive
+
+This happens when an Ex command executes an Ex command that executes an Ex
+command, etc.  This is only allowed 200 times.  When it's more there probably
+is an endless loop.  Probably a |:execute| or |:source| command is involved.
+
+							*E254*  >
+  Cannot allocate color {name}
+
+The color name {name} is unknown.  See |gui-colors| for a list of colors that
+are available on most systems.
+
+							*E458*  >
+  Cannot allocate colormap entry for "xxxx"
+  Cannot allocate colormap entry, some colors may be incorrect
+
+This means that there are not enough colors available for Vim.  It will still
+run, but some of the colors will not appear in the specified color.  Try
+stopping other applications that use many colors, or start them after starting
+gvim.
+Netscape is known to consume a lot of colors.  You can avoid this by telling
+it to use its own colormap: >
+	netscape -install
+Or tell it to limit to a certain number of colors (64 should work well): >
+	netscape -ncols 64
+This can also be done with a line in your Xdefaults file: >
+	Netscape*installColormap: Yes
+or >
+	Netscape*maxImageColors:  64
+<
+							*E79*  >
+  Cannot expand wildcards
+
+A filename contains a strange combination of characters, which causes Vim to
+attempt expanding wildcards but this fails.  This does NOT mean that no
+matching file names could be found, but that the pattern was illegal.
+
+							*E459*  >
+  Cannot go back to previous directory
+
+While expanding a file name, Vim failed to go back to the previously used
+directory.  All file names being used may be invalid now!  You need to have
+execute permission on the current directory.
+
+							*E190* *E212*  >
+  Cannot open "{filename}" for writing
+  Can't open file for writing
+
+For some reason the file you are writing to cannot be created or overwritten.
+The reason could be that you do not have permission to write in the directory
+or the file name is not valid.
+
+							*E166*  >
+  Can't open linked file for writing
+
+You are trying to write to a file which can't be overwritten, and the file is
+a link (either a hard link or a symbolic link).  Writing might still be
+possible if the directory that contains the link or the file is writable, but
+Vim now doesn't know if you want to delete the link and write the file in its
+place, or if you want to delete the file itself and write the new file in its
+place.  If you really want to write the file under this name, you have to
+manually delete the link or the file, or change the permissions so that Vim
+can overwrite.
+
+							*E46*  >
+  Cannot set read-only variable "{name}"
+
+You are trying to assign a value to an argument of a function |a:var| or a Vim
+internal variable |v:var| which is read-only.
+
+							*E90*  >
+  Cannot unload last buffer
+
+Vim always requires one buffer to be loaded, otherwise there would be nothing
+to display in the window.
+
+							*E40*  >
+  Can't open errorfile <filename>
+
+When using the ":make" or ":grep" commands: The file used to save the error
+messages or grep output cannot be opened.  This can have several causes:
+- 'shellredir' has a wrong value.
+- The shell changes directory, causing the error file to be written in another
+  directory.  This could be fixed by changing 'makeef', but then the make
+  command is still executed in the wrong directory.
+- 'makeef' has a wrong value.
+- The 'grepprg' or 'makeprg' could not be executed.  This cannot always be
+  detected (especially on MS-Windows).  Check your $PATH.
+
+ >
+  Can't open file C:\TEMP\VIoD243.TMP
+
+On MS-Windows, this message appears when the output of an external command was
+to be read, but the command didn't run successfully.  This can be caused by
+many things.  Check the 'shell', 'shellquote', 'shellxquote', 'shellslash' and
+related options.  It might also be that the external command was not found,
+there is no different error message for that.
+
+							*E12*  >
+  Command not allowed from exrc/vimrc in current dir or tag search
+
+Some commands are not allowed for security reasons.  These commands mostly
+come from a .exrc or .vimrc file in the current directory, or from a tags
+file.  Also see 'secure'.
+
+							*E74*  >
+  Command too complex
+
+A mapping resulted in a very long command string.  Could be caused by a
+mapping that indirectly calls itself.
+
+>
+  CONVERSION ERROR
+
+When writing a file and the text "CONVERSION ERROR" appears, this means that
+some bits were lost when converting text from the internally used UTF-8 to the
+format of the file.  The file will not be marked unmodified.  If you care
+about the loss of information, set the 'fileencoding' option to another value
+that can handle the characters in the buffer and write again.  If you don't
+care, you can abandon the buffer or reset the 'modified' option.
+
+							*E302*  >
+  Could not rename swap file
+
+When the file name changes, Vim tries to rename the |swap-file| as well.
+This failed and the old swap file is now still used.  Mostly harmless.
+
+							*E43* *E44*  >
+  Damaged match string
+  Corrupted regexp program
+
+Something inside Vim went wrong and resulted in a corrupted regexp.  If you
+know how to reproduce this problem, please report it. |bugs|
+
+							*E208* *E209* *E210*  >
+  Error writing to "{filename}"
+  Error closing "{filename}"
+  Error reading "{filename}"
+
+This occurs when Vim is trying to rename a file, but a simple change of file
+name doesn't work.  Then the file will be copied, but somehow this failed.
+The result may be that both the original file and the destination file exist
+and the destination file may be incomplete.
+
+>
+  Vim: Error reading input, exiting...
+
+This occurs when Vim cannot read typed characters while input is required.
+Vim got stuck, the only thing it can do is exit.  This can happen when both
+stdin and stderr are redirected and executing a script that doesn't exit Vim.
+
+							*E47*  >
+  Error while reading errorfile
+
+Reading the error file was not possible.  This is NOT caused by an error
+message that was not recognized.
+
+							*E80*  >
+  Error while writing
+
+Writing a file was not completed successfully.  The file is probably
+incomplete.
+
+							*E13* *E189*  >
+  File exists (use ! to override)
+  "{filename}" exists (use ! to override)
+
+You are protected from accidentally overwriting a file.  When you want to
+write anyway, use the same command, but add a "!" just after the command.
+Example: >
+	:w /tmp/test
+changes to: >
+	:w! /tmp/test
+<
+							*E768*  >
+  Swap file exists: {filename} (:silent! overrides)
+
+You are protected from overwriting a file that is being edited by Vim.  This
+happens when you use ":w! filename" and a swapfile is found.
+- If the swapfile was left over from an old crashed edit session you may want
+  to delete the swapfile.  Edit {filename} to find out information about the
+  swapfile.
+- If you want to write anyway prepend ":silent!" to the command.  For example: >
+	:silent! w! /tmp/test
+< The special command is needed, since you already added the ! for overwriting
+  an existing file.
+
+							*E139*  >
+  File is loaded in another buffer
+
+You are trying to write a file under a name which is also used in another
+buffer.  This would result in two versions of the same file.
+
+							*E142*  >
+  File not written: Writing is disabled by 'write' option
+
+The 'write' option is off.  This makes all commands that try to write a file
+generate this message.  This could be caused by a |-m| commandline argument.
+You can switch the 'write' option on with ":set write".
+
+							*E25*  >
+  GUI cannot be used: Not enabled at compile time
+
+You are running a version of Vim that doesn't include the GUI code.  Therefore
+"gvim" and ":gui" don't work.
+
+							*E49*  >
+  Invalid scroll size
+
+This is caused by setting an invalid value for the 'scroll', 'scrolljump' or
+'scrolloff' options.
+
+							*E17*  >
+  "{filename}" is a directory
+
+You tried to write a file with the name of a directory.  This is not possible.
+You probably need to append a file name.
+
+							*E19*  >
+  Mark has invalid line number
+
+You are using a mark that has a line number that doesn't exist.  This can
+happen when you have a mark in another file, and some other program has
+deleted lines from it.
+
+							*E219* *E220*  >
+  Missing {.
+  Missing }.
+
+Using a {} construct in a file name, but there is a { without a matching } or
+the other way around.  It should be used like this: {foo,bar}.  This matches
+"foo" and "bar".
+
+							*E315*  >
+  ml_get: invalid lnum:
+
+This is an internal Vim error.  Please try to find out how it can be
+reproduced, and submit a bug report |bugreport.vim|.
+
+							*E173*  >
+  {number} more files to edit
+
+You are trying to exit, while the last item in the argument list has not been
+edited.  This protects you from accidentally exiting when you still have more
+files to work on.  See |argument-list|.  If you do want to exit, just do it
+again and it will work.
+
+							*E23* *E194*  >
+  No alternate file
+  No alternate file name to substitute for '#'
+
+The alternate file is not defined yet.  See |alternate-file|.
+
+							*E32*  >
+  No file name
+
+The current buffer has no name.  To write it, use ":w fname".  Or give the
+buffer a name with ":file fname".
+
+							*E141*  >
+  No file name for buffer {number}
+
+One of the buffers that was changed does not have a file name.  Therefore it
+cannot be written.  You need to give the buffer a file name: >
+	:buffer {number}
+	:file {filename}
+<
+							*E33*  >
+  No previous substitute regular expression
+
+When using the '~' character in a pattern, it is replaced with the previously
+used pattern in a ":substitute" command.  This fails when no such command has
+been used yet.  See |/~|.  This also happens when using ":s/pat/%/", where the
+"%" stands for the previous substitute string.
+
+							*E35*  >
+  No previous regular expression
+
+When using an empty search pattern, the previous search pattern is used.  But
+that is not possible if there was no previous search.
+
+							*E24*  >
+  No such abbreviation
+
+You have used an ":unabbreviate" command with an argument which is not an
+existing abbreviation.  All variations of this command give the same message:
+":cunabbrev", ":iunabbrev", etc.  Check for trailing white space.
+
+>
+  /dev/dsp: No such file or directory
+
+Only given for GTK GUI with Gnome support.  Gnome tries to use the audio
+device and it isn't present.  You can ignore this error.
+
+							*E31*  >
+  No such mapping
+
+You have used an ":unmap" command with an argument which is not an existing
+mapping.  All variations of this command give the same message: ":cunmap",
+":unmap!", etc.  A few hints:
+- Check for trailing white space.
+- If the mapping is buffer-local you need to use ":unmap <buffer>".
+  |:map-<buffer>|
+
+							*E37* *E89*  >
+  No write since last change (use ! to override)
+  No write since last change for buffer {N} (use ! to override)
+
+You are trying to |abandon| a file that has changes.  Vim protects you from
+losing your work.  You can either write the changed file with ":w", or, if you
+are sure, |abandon| it anyway, and lose all the changes.  This can be done by
+adding a '!' character just after the command you used.  Example: >
+	:e other_file
+changes to: >
+	:e! other_file
+<
+							*E162*  >
+  No write since last change for buffer "{name}"
+
+This appears when you try to exit Vim while some buffers are changed.  You
+will either have to write the changed buffer (with |:w|), or use a command to
+abandon the buffer forcefully, e.g., with ":qa!".  Careful, make sure you
+don't throw away changes you really want to keep.  You might have forgotten
+about a buffer, especially when 'hidden' is set.
+
+>
+  [No write since last change]
+
+This appears when executing a shell command while at least one buffer was
+changed.  To avoid the message reset the 'warn' option.
+
+							*E38*  >
+  Null argument
+
+Something inside Vim went wrong and resulted in a NULL pointer.  If you know
+how to reproduce this problem, please report it. |bugs|
+
+							*E172*  >
+  Only one file name allowed
+
+The ":edit" command only accepts one file name.  When you want to specify
+several files for editing use ":next" |:next|.
+
+						*E41* *E82* *E83* *E342*  >
+  Out of memory!
+  Out of memory!  (allocating {number} bytes)
+  Cannot allocate any buffer, exiting...
+  Cannot allocate buffer, using other one...
+
+Oh, oh.  You must have been doing something complicated, or some other program
+is consuming your memory.  Be careful!  Vim is not completely prepared for an
+out-of-memory situation.  First make sure that any changes are saved.  Then
+try to solve the memory shortage.  To stay on the safe side, exit Vim and
+start again.  Also see |msdos-limitations|.
+
+							*E339*  >
+  Pattern too long
+
+This only happens on systems with 16 bit ints: The compiled regexp pattern is
+longer than about 65000 characters.  Try using a shorter pattern.
+
+							*E45*  >
+  'readonly' option is set (use ! to override)
+
+You are trying to write a file that was marked as read-only.  To write the
+file anyway, either reset the 'readonly' option, or add a '!' character just
+after the command you used.  Example: >
+	:w
+changes to: >
+	:w!
+<
+							*E294* *E295* *E301*  >
+  Read error in swap file
+  Seek error in swap file read
+  Oops, lost the swap file!!!
+
+Vim tried to read text from the |swap-file|, but something went wrong.  The
+text in the related buffer may now be corrupted!  Check carefully before you
+write a buffer.  You may want to write it in another file and check for
+differences.
+
+							*E192*  >
+  Recursive use of :normal too deep
+
+You are using a ":normal" command, whose argument again uses a ":normal"
+command in a recursive way.  This is restricted to 'maxmapdepth' levels.  This
+example illustrates how to get this message: >
+	:map gq :normal gq<CR>
+If you type "gq", it will execute this mapping, which will call "gq" again.
+
+							*E22*  >
+  Scripts nested too deep
+
+Scripts can be read with the "-s" command-line argument and with the ":source"
+command.  The script can then again read another script.  This can continue
+for about 14 levels.  When more nesting is done, Vim assumes that there is a
+recursive loop somewhere and stops with this error message.
+
+							*E319*  >
+  Sorry, the command is not available in this version
+
+You have used a command that is not present in the version of Vim you are
+using.  When compiling Vim, many different features can be enabled or
+disabled.  This depends on how big Vim has chosen to be and the operating
+system.  See |+feature-list| for when which feature is available.  The
+|:version| command shows which feature Vim was compiled with.
+
+							*E300*  >
+  Swap file already exists (symlink attack?)
+
+This message appears when Vim is trying to open a swap file and finds it
+already exists or finds a symbolic link in its place.  This shouldn't happen,
+because Vim already checked that the file doesn't exist.  Either someone else
+opened the same file at exactly the same moment (very unlikely) or someone is
+attempting a symlink attack (could happen when editing a file in /tmp or when
+'directory' starts with "/tmp", which is a bad choice).
+
+							*E432*  >
+  Tags file not sorted: {file name}
+
+Vim (and Vi) expect tags files to be sorted in ASCII order.  Binary searching
+can then be used, which is a lot faster than a linear search.  If your tags
+files are not properly sorted, reset the |'tagbsearch'| option.
+This message is only given when Vim detects a problem when searching for a
+tag.  Sometimes this message is not given, even thought the tags file is not
+properly sorted.
+
+							*E460*  >
+  The resource fork would be lost (add ! to override)
+
+On the Macintosh (classic), when writing a file, Vim attempts to preserve all
+info about a file, including its resource fork.  If this is not possible you
+get this error message.  Append "!" to the command name to write anyway (and
+lose the info).
+
+							*E424*  >
+  Too many different highlighting attributes in use
+
+Vim can only handle about 223 different kinds of highlighting.  If you run
+into this limit, you have used too many |:highlight| commands with different
+arguments.  A ":highlight link" is not counted.
+
+							*E77*  >
+  Too many file names
+
+When expanding file names, more than one match was found.  Only one match is
+allowed for the command that was used.
+
+							*E303*  >
+  Unable to open swap file for "{filename}", recovery impossible
+
+Vim was not able to create a swap file.  You can still edit the file, but if
+Vim unexpected exits the changes will be lost.  And Vim may consume a lot of
+memory when editing a big file.  You may want to change the 'directory' option
+to avoid this error.  See |swap-file|.
+
+							*E140*  >
+  Use ! to write partial buffer
+
+When using a range to write part of a buffer, it is unusual to overwrite the
+original file.  It is probably a mistake (e.g., when Visual mode was active
+when using ":w"), therefore Vim requires using a !  after the command, e.g.:
+":3,10w!".
+>
+
+  Warning: Cannot convert string "<Key>Escape,_Key_Cancel" to type
+  VirtualBinding
+
+Messages like this appear when starting up.  This is not a Vim problem, your
+X11 configuration is wrong.  You can find a hint on how to solve this here:
+http://groups.yahoo.com/group/solarisonintel/message/12179.
+
+							*W10*  >
+  Warning: Changing a readonly file
+
+The file is read-only and you are making a change to it anyway.  You can use
+the |FileChangedRO| autocommand event to avoid this message (the autocommand
+must reset the 'readonly' option).  See 'modifiable' to completely disallow
+making changes to a file.
+This message is only given for the first change after 'readonly' has been set.
+
+							*W13*  >
+  Warning: File "{filename}" has been created after editing started
+
+You are editing a file in Vim when it didn't exist, but it does exist now.
+You will have to decide if you want to keep the version in Vim or the newly
+created file.  This message is not given when 'buftype' is not empty.
+
+							*W11*  >
+  Warning: File "{filename}" has changed since editing started
+
+The file which you have started editing has got another timestamp and the
+contents changed (more precisely: When reading the file again with the current
+option settings and autocommands you would end up with different text).  This
+probably means that some other program changed the file.  You will have to
+find out what happened, and decide which version of the file you want to keep.
+Set the 'autoread' option if you want to do this automatically.
+This message is not given when 'buftype' is not empty.
+
+There is one situation where you get this message even though there is nothing
+wrong: If you save a file in Windows on the day the daylight saving time
+starts.  It can be fixed in one of these ways:
+- Add this line in your autoexec.bat: >
+	   SET TZ=-1
+< Adjust the "-1" for your time zone.
+- Disable "automatically adjust clock for daylight saving changes".
+- Just write the file again the next day.  Or set your clock to the next day,
+  write the file twice and set the clock back.
+
+							*W12*  >
+  Warning: File "{filename}" has changed and the buffer was changed in Vim as well
+
+Like the above, and the buffer for the file was changed in this Vim as well.
+You will have to decide if you want to keep the version in this Vim or the one
+on disk.  This message is not given when 'buftype' is not empty.
+
+							*W16*  >
+  Warning: Mode of file "{filename}" has changed since editing started
+
+When the timestamp for a buffer was changed and the contents are still the
+same but the mode (permissions) have changed.  This usually occurs when
+checking out a file from a version control system, which causes the read-only
+bit to be reset.  It should be safe to reload the file.  Set 'autoread' to
+automatically reload the file.
+
+							*E211*  >
+  Warning: File "{filename}" no longer available
+
+The file which you have started editing has disappeared, or is no longer
+accessible.  Make sure you write the buffer somewhere to avoid losing
+changes.  This message is not given when 'buftype' is not empty.
+
+							*W14*  >
+  Warning: List of file names overflow
+
+You must be using an awful lot of buffers.  It's now possible that two buffers
+have the same number, which causes various problems.  You might want to exit
+Vim and restart it.
+
+							*E296* *E297*  >
+  Seek error in swap file write
+  Write error in swap file
+
+This mostly happens when the disk is full.  Vim could not write text into the
+|swap-file|.  It's not directly harmful, but when Vim unexpectedly exits some
+text may be lost without recovery being possible.  Vim might run out of memory
+when this problem persists.
+
+						*connection-refused*  >
+  Xlib: connection to "<machine-name:0.0" refused by server
+
+This happens when Vim tries to connect to the X server, but the X server does
+not allow a connection.  The connection to the X server is needed to be able
+to restore the title and for the xterm clipboard support.  Unfortunately this
+error message cannot be avoided, except by disabling the |+xterm_clipboard|
+and |+X11| features.
+
+							*E10*  >
+  \\ should be followed by /, ? or &
+
+A command line started with a backslash or the range of a command contained a
+backslash in a wrong place.  This is often caused by command-line continuation
+being disabled.  Remove the 'C' flag from the 'cpoptions' option to enable it.
+Or use ":set nocp".
+
+							*E471*  >
+  Argument required
+
+This happens when an Ex command with mandatory argument(s) was executed, but
+no argument has been specified.
+
+							*E474* *E475*  >
+  Invalid argument
+
+An Ex command has been executed, but an invalid argument has been specified.
+
+							*E488*  >
+  Trailing characters
+
+An argument has been added to an Ex command that does not permit one.
+
+							*E477* *E478*  >
+  No ! allowed
+  Don't panic!
+
+You have added a "!" after an Ex command that doesn't permit one.
+
+							*E481*  >
+  No range allowed
+
+A range was specified for an Ex command that doesn't permit one.  See
+|cmdline-ranges|.
+
+							*E482* *E483*  >
+  Can't create file {filename}
+  Can't get temp file name
+
+Vim cannot create a temporary file.
+
+							*E484* *E485*  >
+  Can't open file %s"
+  Can't read file %s"
+
+Vim cannot read a temporary file.
+
+							*E464*  >
+  Ambiguous use of user-defined command
+
+There are two user-defined commands with a common name prefix, and you used
+Command-line completion to execute one of them. |user-cmd-ambiguous|
+Example: >
+	:command MyCommand1 echo "one"
+	:command MyCommand2 echo "two"
+	:MyCommand
+<
+							*E492*  >
+  Not an editor command
+
+You tried to execute a command that is neither an Ex command nor
+a user-defined command.
+
+==============================================================================
+3. Messages						*messages*
+
+This is an (incomplete) overview of various messages that Vim gives:
+
+			*hit-enter* *press-enter* *hit-return*
+			*press-return* *hit-enter-prompt*
+
+  Press ENTER or type command to continue
+
+This message is given when there is something on the screen for you to read,
+and the screen is about to be redrawn:
+- After executing an external command (e.g., ":!ls" and "=").
+- Something is displayed on the status line that is longer than the width of
+  the window, or runs into the 'showcmd' or 'ruler' output.
+
+-> Press <Enter> or <Space> to redraw the screen and continue, without that
+   key being used otherwise.
+-> Press ':' or any other Normal mode command character to start that command.
+-> Press 'k', <Up>, 'u', 'b' or 'g' to scroll back in the messages.  This
+   works the same way as at the |more-prompt|.  Only works when 'compatible'
+   is off and 'more' is on.
+-> Pressing 'j', 'd' or <Down> is ignored when messages scrolled off the top
+   of the screen, 'compatible' is off and 'more' is on, to avoid that typing
+   one 'j' too many causes the messages to disappear.
+-> Press <C-Y> to copy (yank) a modeless selection to the clipboard register.
+-> Use a menu.  The characters defined for Cmdline-mode are used.
+-> When 'mouse' contains the 'r' flag, clicking the left mouse button works
+   like pressing <Space>.  This makes it impossible to select text though.
+-> For the GUI clicking the left mouse button in the last line works like
+   pressing <Space>.
+{Vi: only ":" commands are interpreted}
+
+If you accidentally hit <Enter> or <Space> and you want to see the displayed
+text then use |g<|.  This only works when 'more' is set.
+
+To reduce the number of hit-enter prompts:
+- Set 'cmdheight' to 2 or higher.
+- Add flags to 'shortmess'.
+- Reset 'showcmd' and/or 'ruler'.
+
+If your script causes the hit-enter prompt and you don't know why, you may
+find the |v:scrollstart| variable useful.
+
+Also see 'mouse'.  The hit-enter message is highlighted with the |hl-Question|
+group.
+
+
+						*more-prompt* *pager*  >
+  -- More --
+  -- More -- SPACE/d/j: screen/page/line down, b/u/k: up, q: quit
+
+This message is given when the screen is filled with messages.  It is only
+given when the 'more' option is on.  It is highlighted with the |hl-MoreMsg|
+group.
+
+Type					effect ~
+     <CR> or <NL> or j or <Down>	one more line
+     d					down a page (half a screen)
+     <Space> or <PageDown>		down a screen
+     G					down all the way, until the hit-enter
+					prompt
+
+     <BS> or k or <Up>			one line back (*)
+     u					up a page (half a screen) (*)
+     b or <PageUp>			back a screen (*)
+     g					back to the start (*)
+
+     q, <Esc> or CTRL-C			stop the listing
+     :					stop the listing and enter a
+					     command-line
+    <C-Y>				yank (copy) a modeless selection to
+					the clipboard ("* and "+ registers)
+    {menu-entry}			what the menu is defined to in
+					Cmdline-mode.
+    <LeftMouse> (**)			next page
+
+Any other key causes the meaning of the keys to be displayed.
+
+(*)  backwards scrolling is {not in Vi}.  Only scrolls back to where messages
+     started to scroll.
+(**) Clicking the left mouse button only works:
+     - For the GUI: in the last line of the screen.
+     - When 'r' is included in 'mouse' (but then selecting text won't work).
+
+
+Note: The typed key is directly obtained from the terminal, it is not mapped
+and typeahead is ignored.
+
+The |g<| command can be used to see the last page of previous command output.
+This is especially useful if you accidentally typed <Space> at the hit-enter
+prompt.
+
+ vim:tw=78:ts=8:ft=help:norl:
--- /dev/null
+++ b/lib/vimfiles/doc/mlang.txt
@@ -1,0 +1,205 @@
+*mlang.txt*     For Vim version 7.1.  Last change: 2006 Jul 12
+
+
+		  VIM REFERENCE MANUAL    by Bram Moolenaar
+
+
+Multi-language features				*multilang* *multi-lang*
+
+This is about using messages and menus in various languages.  For editing
+multi-byte text see |multibyte|.
+
+The basics are explained in the user manual: |usr_45.txt|.
+
+1. Messages			|multilang-messages|
+2. Menus			|multilang-menus|
+3. Scripts			|multilang-scripts|
+
+Also see |help-translated| for multi-language help.
+
+{Vi does not have any of these features}
+{not available when compiled without the |+multi_lang| feature}
+
+==============================================================================
+1. Messages						*multilang-messages*
+
+Vim picks up the locale from the environment.  In most cases this means Vim
+will use the language that you prefer, unless it's not available.
+
+To see a list of supported locale names on your system, look in one of these
+directories (for Unix):
+	/usr/lib/locale ~
+	/usr/share/locale ~
+Unfortunately, upper/lowercase differences matter.  Also watch out for the
+use of "-" and "_".
+
+					    *:lan* *:lang* *:language* *E197*
+:lan[guage]
+:lan[guage] mes[sages]
+:lan[guage] cty[pe]
+:lan[guage] tim[e]
+			Print the current language (aka locale).
+			With the "messages" argument the language used for
+			messages is printed.  Technical: LC_MESSAGES.
+			With the "ctype" argument the language used for
+			character encoding is printed.  Technical: LC_CTYPE.
+			With the "time" argument the language used for
+			strftime() is printed.  Technical: LC_TIME.
+			Without argument all parts of the locale are printed
+			(this is system dependent).
+			The current language can also be obtained with the
+			|v:lang|, |v:ctype| and |v:lc_time| variables.
+
+:lan[guage] {name}
+:lan[guage] mes[sages] {name}
+:lan[guage] cty[pe] {name}
+:lan[guage] tim[e] {name}
+			Set the current language (aka locale) to {name}.
+			The locale {name} must be a valid locale on your
+			system.  Some systems accept aliases like "en" or
+			"en_US", but some only accept the full specification
+			like "en_US.ISO_8859-1".
+			With the "messages" argument the language used for
+			messages is set.  This can be different when you want,
+			for example, English messages while editing Japanese
+			text.  This sets $LC_MESSAGES.
+			With the "ctype" argument the language used for
+			character encoding is set.  This affects the libraries
+			that Vim was linked with.  It's unusual to set this to
+			a different value from 'encoding'.  This sets
+			$LC_CTYPE.
+			With the "time" argument the language used for time
+			and date messages is set.  This affects strftime().
+			This sets $LC_TIME.
+			Without an argument both are set, and additionally
+			$LANG is set.
+			This will make a difference for items that depend on
+			the language (some messages, time and date format).
+			Not fully supported on all systems
+			If this fails there will be an error message.  If it
+			succeeds there is no message.  Example: >
+				:language
+				Current language: C
+				:language de_DE.ISO_8859-1
+				:language mes
+				Current messages language: de_DE.ISO_8859-1
+				:lang mes en
+<
+
+MS-WINDOWS MESSAGE TRANSLATIONS				*win32-gettext*
+
+If you used the self-installing .exe file, message translations should work
+already.  Otherwise get the libintl.dll file if you don't have it yet:
+
+	http://sourceforge.net/projects/gettext
+
+This also contains tools xgettext, msgformat and others.
+
+libintl.dll should be placed in same directory with (g)vim.exe, or some
+place where PATH environment value describe.  Message files (vim.mo)
+have to be placed in "$VIMRUNTIME/lang/xx/LC_MESSAGES", where "xx" is the
+abbreviation of the language (mostly two letters).
+
+If you write your own translations you need to generate the .po file and
+convert it to a .mo file.  You need to get the source distribution and read
+the file "src/po/README.txt".
+
+To overrule the automatic choice of the language, set the $LANG variable to
+the language of your choice.  use "en" to disable translations. >
+
+  :let $LANG = 'ja'
+
+(text for Windows by Muraoka Taro)
+
+==============================================================================
+2. Menus						*multilang-menus*
+
+See |45.2| for the basics, esp. using 'langmenu'.
+
+Note that if changes have been made to the menus after the translation was
+done, some of the menus may be shown in English.  Please try contacting the
+maintainer of the translation and ask him to update it.  You can find the
+name and e-mail address of the translator in
+"$VIMRUNTIME/lang/menu_<lang>.vim".
+
+To set the font (or fontset) to use for the menus, use the |:highlight|
+command.  Example: >
+
+	:highlight Menu font=k12,r12
+
+
+ALIAS LOCALE NAMES
+
+Unfortunately, the locale names are different on various systems, even though
+they are for the same language and encoding.  If you do not get the menu
+translations you expected, check the output of this command: >
+
+	echo v:lang
+
+Now check the "$VIMRUNTIME/lang" directory for menu translation files that use
+a similar language.  A difference in a "-" being a "_" already causes a file
+not to be found!  Another common difference to watch out for is "iso8859-1"
+versus "iso_8859-1".  Fortunately Vim makes all names lowercase, thus you
+don't have to worry about case differences.  Spaces are changed to
+underscores, to avoid having to escape them.
+
+If you find a menu translation file for your language with a different name,
+create a file in your own runtime directory to load that one.  The name of
+that file could be: >
+
+	~/.vim/lang/menu_<v:lang>.vim
+
+Check the 'runtimepath' option for directories which are searched.  In that
+file put a command to load the menu file with the other name: >
+
+	runtime lang/menu_<other_lang>.vim
+
+
+TRANSLATING MENUS
+
+If you want to do your own translations, you can use the |:menutrans| command,
+explained below.  It is recommended to put the translations for one language
+in a Vim script.  For a language that has no translation yet, please consider
+becoming the maintainer and make your translations available to all Vim users.
+Send an e-mail to the Vim maintainer <maintainer@vim.org>.
+
+					*:menut* *:menutrans* *:menutranslate*
+:menut[ranslate] clear
+			Clear all menu translations.
+
+:menut[ranslate] {english} {mylang}
+			Translate menu name {english} to {mylang}.  All
+			special characters like "&" and "<Tab>" need to be
+			included.  Spaces and dots need to be escaped with a
+			backslash, just like in other |:menu| commands.
+
+See the $VIMRUNTIME/lang directory for examples.
+
+To try out your translations you first have to remove all menus.  This is how
+you can do it without restarting Vim: >
+	:source $VIMRUNTIME/delmenu.vim
+	:source <your-new-menu-file>
+	:source $VIMRUNTIME/menu.vim
+
+Each part of a menu path is translated separately.  The result is that when
+"Help" is translated to "Hilfe" and "Overview" to "�berblick" then
+"Help.Overview" will be translated to "Hilfe.�berblick".
+
+==============================================================================
+3. Scripts						*multilang-scripts*
+
+In Vim scripts you can use the |v:lang| variable to get the current language
+(locale).  The default value is "C" or comes from the $LANG environment
+variable.
+
+The following example shows how this variable is used in a simple way, to make
+a message adapt to language preferences of the user, >
+
+	:if v:lang =~ "de_DE"
+	:  echo "Guten Morgen"
+	:else
+	:  echo "Good morning"
+	:endif
+<
+
+ vim:tw=78:sw=4:ts=8:ft=help:norl:
--- /dev/null
+++ b/lib/vimfiles/doc/motion.txt
@@ -1,0 +1,1303 @@
+*motion.txt*    For Vim version 7.1.  Last change: 2006 Dec 07
+
+
+		  VIM REFERENCE MANUAL    by Bram Moolenaar
+
+
+Cursor motions					*cursor-motions* *navigation*
+
+These commands move the cursor position.  If the new position is off of the
+screen, the screen is scrolled to show the cursor (see also 'scrolljump' and
+'scrolloff' options).
+
+1. Motions and operators	|operator|
+2. Left-right motions		|left-right-motions|
+3. Up-down motions		|up-down-motions|
+4. Word motions			|word-motions|
+5. Text object motions		|object-motions|
+6. Text object selection	|object-select|
+7. Marks			|mark-motions|
+8. Jumps			|jump-motions|
+9. Various motions		|various-motions|
+
+General remarks:
+
+If you want to know where you are in the file use the "CTRL-G" command
+|CTRL-G| or the "g CTRL-G" command |g_CTRL-G|.  If you set the 'ruler' option,
+the cursor position is continuously shown in the status line (which slows down
+Vim a little).
+
+Experienced users prefer the hjkl keys because they are always right under
+their fingers.  Beginners often prefer the arrow keys, because they do not
+know what the hjkl keys do.  The mnemonic value of hjkl is clear from looking
+at the keyboard.  Think of j as an arrow pointing downwards.
+
+The 'virtualedit' option can be set to make it possible to move the cursor to
+positions where there is no character or halfway a character.
+
+==============================================================================
+1. Motions and operators				*operator*
+
+The motion commands can be used after an operator command, to have the command
+operate on the text that was moved over.  That is the text between the cursor
+position before and after the motion.  Operators are generally used to delete
+or change text.  The following operators are available:
+
+	|c|	c	change
+	|d|	d	delete
+	|y|	y	yank into register (does not change the text)
+	|~|	~	swap case (only if 'tildeop' is set)
+	|g~|	g~	swap case
+	|gu|	gu	make lowercase
+	|gU|	gU	make uppercase
+	|!|	!	filter through an external program
+	|=|	=	filter through 'equalprg' or C-indenting if empty
+	|gq|	gq	text formatting
+	|g?|	g?	ROT13 encoding
+	|>|	>	shift right
+	|<|	<	shift left
+	|zf|	zf	define a fold
+	|g@|    g@      call function set with the 'operatorfunc' option
+
+If the motion includes a count and the operator also had a count before it,
+the two counts are multiplied.  For example: "2d3w" deletes six words.
+
+After applying the operator the cursor is mostly left at the start of the text
+that was operated upon.  For example, "yfe" doesn't move the cursor, but "yFe"
+moves the cursor leftwards to the "e" where the yank started.
+
+						*linewise* *characterwise*
+The operator either affects whole lines, or the characters between the start
+and end position.  Generally, motions that move between lines affect lines
+(are linewise), and motions that move within a line affect characters (are
+characterwise).  However, there are some exceptions.
+
+						*exclusive* *inclusive*
+A character motion is either inclusive or exclusive.  When inclusive, the
+start and end position of the motion are included in the operation.  When
+exclusive, the last character towards the end of the buffer is not included.
+Linewise motions always include the start and end position.
+
+Which motions are linewise, inclusive or exclusive is mentioned with the
+command.  There are however, two general exceptions:
+1. If the motion is exclusive and the end of the motion is in column 1, the
+   end of the motion is moved to the end of the previous line and the motion
+   becomes inclusive.  Example: "}" moves to the first line after a paragraph,
+   but "d}" will not include that line.
+						*exclusive-linewise*
+2. If the motion is exclusive, the end of the motion is in column 1 and the
+   start of the motion was at or before the first non-blank in the line, the
+   motion becomes linewise.  Example: If a paragraph begins with some blanks
+   and you do "d}" while standing on the first non-blank, all the lines of
+   the paragraph are deleted, including the blanks.  If you do a put now, the
+   deleted lines will be inserted below the cursor position.
+
+Note that when the operator is pending (the operator command is typed, but the
+motion isn't yet), a special set of mappings can be used.  See |:omap|.
+
+Instead of first giving the operator and then a motion you can use Visual
+mode: mark the start of the text with "v", move the cursor to the end of the
+text that is to be affected and then hit the operator.  The text between the
+start and the cursor position is highlighted, so you can see what text will
+be operated upon.  This allows much more freedom, but requires more key
+strokes and has limited redo functionality.  See the chapter on Visual mode
+|Visual-mode|.
+
+You can use a ":" command for a motion.  For example "d:call FindEnd()".
+But this can't be redone with "." if the command is more than one line.
+This can be repeated: >
+	d:call search("f")<CR>
+This cannot be repeated: >
+	d:if 1<CR>
+	   call search("f")<CR>
+	endif<CR>
+
+
+FORCING A MOTION TO BE LINEWISE, CHARACTERWISE OR BLOCKWISE
+
+When a motion is not of the type you would like to use, you can force another
+type by using "v", "V" or CTRL-V just after the operator.
+Example: >
+	dj
+deletes two lines >
+	dvj
+deletes from the cursor position until the character below the cursor >
+	d<C-V>j
+deletes the character under the cursor and the character below the cursor. >
+
+Be careful with forcing a linewise movement to be used characterwise or
+blockwise, the column may not always be defined.
+
+							*o_v*
+v		When used after an operator, before the motion command: Force
+		the operator to work characterwise, also when the motion is
+		linewise.  If the motion was linewise, it will become
+		|exclusive|.
+		If the motion already was characterwise, toggle
+		inclusive/exclusive.  This can be used to make an exclusive
+		motion inclusive and an inclusive motion exclusive.
+
+							*o_V*
+V		When used after an operator, before the motion command: Force
+		the operator to work linewise, also when the motion is
+		characterwise.
+
+							*o_CTRL-V*
+CTRL-V		When used after an operator, before the motion command: Force
+		the operator to work blockwise.  This works like Visual block
+		mode selection, with the corners defined by the cursor
+		position before and after the motion.
+
+==============================================================================
+2. Left-right motions					*left-right-motions*
+
+h		or					*h*
+<Left>		or					*<Left>*
+CTRL-H		or					*CTRL-H* *<BS>*
+<BS>			[count] characters to the left.  |exclusive| motion.
+			Note: If you prefer <BS> to delete a character, use
+			the mapping:
+				:map CTRL-V<BS>		X
+			(to enter "CTRL-V<BS>" type the CTRL-V key, followed
+			by the <BS> key)
+			See |:fixdel| if the <BS> key does not do what you
+			want.
+
+l		or					*l*
+<Right>		or					*<Right>* *<Space>*
+<Space>			[count] characters to the right.  |exclusive| motion.
+
+							*0*
+0			To the first character of the line.  |exclusive|
+			motion.
+
+							*<Home>* *<kHome>*
+<Home>			To the first character of the line.  |exclusive|
+			motion.  When moving up or down next, stay in same
+			TEXT column (if possible).  Most other commands stay
+			in the same SCREEN column.  <Home> works like "1|",
+			which differs from "0" when the line starts with a
+			<Tab>.  {not in Vi}
+
+							*^*
+^			To the first non-blank character of the line.
+			|exclusive| motion.
+
+							*$* *<End>* *<kEnd>*
+$  or <End>		To the end of the line.  When a count is given also go
+			[count - 1] lines downward |inclusive|.
+			In Visual mode the cursor goes to just after the last
+			character in the line.
+			When 'virtualedit' is active, "$" may move the cursor
+			back from past the end of the line to the last
+			character in the line.
+
+							*g_*
+g_			To the last non-blank character of the line and
+			[count - 1] lines downward |inclusive|. {not in Vi}
+
+							*g0* *g<Home>*
+g0 or g<Home>		When lines wrap ('wrap' on): To the first character of
+			the screen line.  |exclusive| motion.  Differs from
+			"0" when a line is wider than the screen.
+			When lines don't wrap ('wrap' off): To the leftmost
+			character of the current line that is on the screen.
+			Differs from "0" when the first character of the line
+			is not on the screen.  {not in Vi}
+
+							*g^*
+g^			When lines wrap ('wrap' on): To the first non-blank
+			character of the screen line.  |exclusive| motion.
+			Differs from "^" when a line is wider than the screen.
+			When lines don't wrap ('wrap' off): To the leftmost
+			non-blank character of the current line that is on the
+			screen.  Differs from "^" when the first non-blank
+			character of the line is not on the screen.  {not in
+			Vi}
+
+							*gm*
+gm			Like "g0", but half a screenwidth to the right (or as
+			much as possible). {not in Vi}
+
+							*g$* *g<End>*
+g$ or g<End>		When lines wrap ('wrap' on): To the last character of
+			the screen line and [count - 1] screen lines downward
+			|inclusive|.  Differs from "$" when a line is wider
+			than the screen.
+			When lines don't wrap ('wrap' off): To the rightmost
+			character of the current line that is visible on the
+			screen.  Differs from "$" when the last character of
+			the line is not on the screen or when a count is used.
+			Additionally, vertical movements keep the column,
+			instead of going to the end of the line.
+			{not in Vi}
+
+							*bar*
+|			To screen column [count] in the current line.
+			|exclusive| motion.
+
+							*f*
+f{char}			To [count]'th occurrence of {char} to the right.  The
+			cursor is placed on {char} |inclusive|.
+			{char} can be entered as a digraph |digraph-arg|.
+			When 'encoding' is set to Unicode, composing
+			characters may be used, see |utf-8-char-arg|.
+			|:lmap| mappings apply to {char}.  The CTRL-^ command
+			in Insert mode can be used to switch this on/off
+			|i_CTRL-^|.
+
+							*F*
+F{char}			To the [count]'th occurrence of {char} to the left.
+			The cursor is placed on {char} |exclusive|.
+			{char} can be entered like with the |f| command.
+
+							*t*
+t{char}			Till before [count]'th occurrence of {char} to the
+			right.  The cursor is placed on the character left of
+			{char} |inclusive|.
+			{char} can be entered like with the |f| command.
+
+							*T*
+T{char}			Till after [count]'th occurrence of {char} to the
+			left.  The cursor is placed on the character right of
+			{char} |exclusive|.
+			{char} can be entered like with the |f| command.
+
+							*;*
+;			Repeat latest f, t, F or T [count] times.
+
+							*,*
+,			Repeat latest f, t, F or T in opposite direction
+			[count] times.
+
+These commands move the cursor to the specified column in the current line.
+They stop at the first column and at the end of the line, except "$", which
+may move to one of the next lines.  See 'whichwrap' option to make some of the
+commands move across line boundaries.
+
+==============================================================================
+3. Up-down motions					*up-down-motions*
+
+k		or					*k*
+<Up>		or					*<Up>* *CTRL-P*
+CTRL-P			[count] lines upward |linewise|.
+
+j		or					*j*
+<Down>		or					*<Down>*
+CTRL-J		or					*CTRL-J*
+<NL>		or					*<NL>* *CTRL-N*
+CTRL-N			[count] lines downward |linewise|.
+
+gk		or					*gk* *g<Up>*
+g<Up>			[count] display lines upward.  |exclusive| motion.
+			Differs from 'k' when lines wrap, and when used with
+			an operator, because it's not linewise.  {not in Vi}
+
+gj		or					*gj* *g<Down>*
+g<Down>			[count] display lines downward.  |exclusive| motion.
+			Differs from 'j' when lines wrap, and when used with
+			an operator, because it's not linewise.  {not in Vi}
+
+							*-*
+-  <minus>		[count] lines upward, on the first non-blank
+			character |linewise|.
+
++		or					*+*
+CTRL-M		or					*CTRL-M* *<CR>*
+<CR>			[count] lines downward, on the first non-blank
+			character |linewise|.
+
+							*_*
+_  <underscore>		[count] - 1 lines downward, on the first non-blank
+			character |linewise|.
+
+							*G*
+G			Goto line [count], default last line, on the first
+			non-blank character |linewise|.  If 'startofline' not
+			set, keep the same column.
+
+							*<C-End>*
+<C-End>			Goto line [count], default last line, on the last
+			character |inclusive|. {not in Vi}
+
+<C-Home>	or					*gg* *<C-Home>*
+gg			Goto line [count], default first line, on the first
+			non-blank character |linewise|.  If 'startofline' not
+			set, keep the same column.
+
+:[range]		Set the cursor on the specified line number.  If
+			there are several numbers, the last one is used.
+
+							*N%*
+{count}%		Go to {count} percentage in the file, on the first
+			non-blank in the line |linewise|.  To compute the new
+			line number this formula is used:
+			    ({count} * number-of-lines + 99) / 100
+			See also 'startofline' option.  {not in Vi}
+
+:[range]go[to] [count]					*:go* *:goto* *go*
+[count]go		Go to {count} byte in the buffer.  Default [count] is
+			one, start of the file.  When giving [range], the
+			last number in it used as the byte count.  End-of-line
+			characters are counted depending on the current
+			'fileformat' setting.
+			{not in Vi}
+			{not available when compiled without the
+			|+byte_offset| feature}
+
+These commands move to the specified line.  They stop when reaching the first
+or the last line.  The first two commands put the cursor in the same column
+(if possible) as it was after the last command that changed the column,
+except after the "$" command, then the cursor will be put on the last
+character of the line.
+
+If "k", "-" or CTRL-P is used with a [count] and there are less than [count]
+lines above the cursor and the 'cpo' option includes the "-" flag it is an
+error. |cpo--|.
+
+==============================================================================
+4. Word motions						*word-motions*
+
+<S-Right>	or					*<S-Right>* *w*
+w			[count] words forward.  |exclusive| motion.
+
+<C-Right>	or					*<C-Right>* *W*
+W			[count] WORDS forward.  |exclusive| motion.
+
+							*e*
+e			Forward to the end of word [count] |inclusive|.
+
+							*E*
+E			Forward to the end of WORD [count] |inclusive|.
+
+<S-Left>	or					*<S-Left>* *b*
+b			[count] words backward.  |exclusive| motion.
+
+<C-Left>	or					*<C-Left>* *B*
+B			[count] WORDS backward.  |exclusive| motion.
+
+							*ge*
+ge			Backward to the end of word [count] |inclusive|.
+
+							*gE*
+gE			Backward to the end of WORD [count] |inclusive|.
+
+These commands move over words or WORDS.
+							*word*
+A word consists of a sequence of letters, digits and underscores, or a
+sequence of other non-blank characters, separated with white space (spaces,
+tabs, <EOL>).  This can be changed with the 'iskeyword' option.  An empty line
+is also considered to be a word.
+							*WORD*
+A WORD consists of a sequence of non-blank characters, separated with white
+space.  An empty line is also considered to be a WORD.
+
+A sequence of folded lines is counted for one word of a single character.
+"w" and "W", "e" and "E" move to the start/end of the first word or WORD after
+a range of folded lines.  "b" and "B" move to the start of the first word or
+WORD before the fold.
+
+Special case: "cw" and "cW" are treated like "ce" and "cE" if the cursor is
+on a non-blank.  This is because "cw" is interpreted as change-word, and a
+word does not include the following white space.  {Vi: "cw" when on a blank
+followed by other blanks changes only the first blank; this is probably a
+bug, because "dw" deletes all the blanks}
+
+Another special case: When using the "w" motion in combination with an
+operator and the last word moved over is at the end of a line, the end of
+that word becomes the end of the operated text, not the first word in the
+next line.
+
+The original Vi implementation of "e" is buggy.  For example, the "e" command
+will stop on the first character of a line if the previous line was empty.
+But when you use "2e" this does not happen.  In Vim "ee" and "2e" are the
+same, which is more logical.  However, this causes a small incompatibility
+between Vi and Vim.
+
+==============================================================================
+5. Text object motions					*object-motions*
+
+							*(*
+(			[count] sentences backward.  |exclusive| motion.
+
+							*)*
+)			[count] sentences forward.  |exclusive| motion.
+
+							*{*
+{			[count] paragraphs backward.  |exclusive| motion.
+
+							*}*
+}			[count] paragraphs forward.  |exclusive| motion.
+
+							*]]*
+]]			[count] sections forward or to the next '{' in the
+			first column.  When used after an operator, then also
+			stops below a '}' in the first column.  |exclusive|
+			Note that |exclusive-linewise| often applies.
+
+							*][*
+][			[count] sections forward or to the next '}' in the
+			first column.  |exclusive|
+			Note that |exclusive-linewise| often applies.
+
+							*[[*
+[[			[count] sections backward or to the previous '{' in
+			the first column.  |exclusive|
+			Note that |exclusive-linewise| often applies.
+
+							*[]*
+[]			[count] sections backward or to the previous '}' in
+			the first column.  |exclusive|
+			Note that |exclusive-linewise| often applies.
+
+These commands move over three kinds of text objects.
+
+							*sentence*
+A sentence is defined as ending at a '.', '!' or '?' followed by either the
+end of a line, or by a space or tab.  Any number of closing ')', ']', '"'
+and ''' characters may appear after the '.', '!' or '?' before the spaces,
+tabs or end of line.  A paragraph and section boundary is also a sentence
+boundary.
+If the 'J' flag is present in 'cpoptions', at least two spaces have to
+follow the punctuation mark; <Tab>s are not recognized as white space.
+The definition of a sentence cannot be changed.
+
+							*paragraph*
+A paragraph begins after each empty line, and also at each of a set of
+paragraph macros, specified by the pairs of characters in the 'paragraphs'
+option.  The default is "IPLPPPQPP LIpplpipbp", which corresponds to the
+macros ".IP", ".LP", etc.  (These are nroff macros, so the dot must be in the
+first column).  A section boundary is also a paragraph boundary.
+Note that a blank line (only containing white space) is NOT a paragraph
+boundary.
+Also note that this does not include a '{' or '}' in the first column.  When
+the '{' flag is in 'cpoptions' then '{' in the first column is used as a
+paragraph boundary |posix|.
+
+							*section*
+A section begins after a form-feed (<C-L>) in the first column and at each of
+a set of section macros, specified by the pairs of characters in the
+'sections' option.  The default is "SHNHH HUnhsh", which defines a section to
+start at the nroff macros ".SH", ".NH", ".H", ".HU", ".nh" and ".sh".
+
+The "]" and "[" commands stop at the '{' or '}' in the first column.  This is
+useful to find the start or end of a function in a C program.  Note that the
+first character of the command determines the search direction and the
+second character the type of brace found.
+
+If your '{' or '}' are not in the first column, and you would like to use "[["
+and "]]" anyway, try these mappings: >
+   :map [[ ?{<CR>w99[{
+   :map ][ /}<CR>b99]}
+   :map ]] j0[[%/{<CR>
+   :map [] k$][%?}<CR>
+[type these literally, see |<>|]
+
+==============================================================================
+6. Text object selection			*object-select* *text-objects*
+						*v_a* *v_i*
+
+This is a series of commands that can only be used while in Visual mode or
+after an operator.  The commands that start with "a" select "a"n object
+including white space, the commands starting with "i" select an "inner" object
+without white space, or just the white space.  Thus the "inner" commands
+always select less text than the "a" commands.
+
+These commands are {not in Vi}.
+These commands are not available when the |+textobjects| feature has been
+disabled at compile time.
+							*v_aw* *aw*
+aw			"a word", select [count] words (see |word|).
+			Leading or trailing white space is included, but not
+			counted.
+			When used in Visual linewise mode "aw" switches to
+			Visual characterwise mode.
+
+							*v_iw* *iw*
+iw			"inner word", select [count] words (see |word|).
+			White space between words is counted too.
+			When used in Visual linewise mode "iw" switches to
+			Visual characterwise mode.
+
+							*v_aW* *aW*
+aW			"a WORD", select [count] WORDs (see |WORD|).
+			Leading or trailing white space is included, but not
+			counted.
+			When used in Visual linewise mode "aW" switches to
+			Visual characterwise mode.
+
+							*v_iW* *iW*
+iW			"inner WORD", select [count] WORDs (see |WORD|).
+			White space between words is counted too.
+			When used in Visual linewise mode "iW" switches to
+			Visual characterwise mode.
+
+							*v_as* *as*
+as			"a sentence", select [count] sentences (see
+			|sentence|).
+			When used in Visual mode it is made characterwise.
+
+							*v_is* *is*
+is			"inner sentence", select [count] sentences (see
+			|sentence|).
+			When used in Visual mode it is made characterwise.
+
+							*v_ap* *ap*
+ap			"a paragraph", select [count] paragraphs (see
+			|paragraph|).
+			Exception: a blank line (only containing white space)
+			is also a paragraph boundary.
+			When used in Visual mode it is made linewise.
+
+							*v_ip* *ip*
+ip			"inner paragraph", select [count] paragraphs (see
+			|paragraph|).
+			Exception: a blank line (only containing white space)
+			is also a paragraph boundary.
+			When used in Visual mode it is made linewise.
+
+a]						*v_a]* *v_a[* *a]* *a[*
+a[			"a [] block", select [count] '[' ']' blocks.  This
+			goes backwards to the [count] unclosed '[', and finds
+			the matching ']'.  The enclosed text is selected,
+			including the '[' and ']'.
+			When used in Visual mode it is made characterwise.
+
+i]						*v_i]* *v_i[* *i]* *i[*
+i[			"inner [] block", select [count] '[' ']' blocks.  This
+			goes backwards to the [count] unclosed '[', and finds
+			the matching ']'.  The enclosed text is selected,
+			excluding the '[' and ']'.
+			When used in Visual mode it is made characterwise.
+
+a)							*v_a)* *a)* *a(*
+a(							*v_ab* *v_a(* *ab*
+ab			"a block", select [count] blocks, from "[count] [(" to
+			the matching ')', including the '(' and ')' (see
+			|[(|).  Does not include white space outside of the
+			parenthesis.
+			When used in Visual mode it is made characterwise.
+
+i)							*v_i)* *i)* *i(*
+i(							*v_ib* *v_i(* *ib*
+ib			"inner block", select [count] blocks, from "[count] [("
+			to the matching ')', excluding the '(' and ')' (see
+			|[(|).
+			When used in Visual mode it is made characterwise.
+
+a>						*v_a>* *v_a<* *a>* *a<*
+a<			"a <> block", select [count] <> blocks, from the
+			[count]'th unmatched '<' backwards to the matching
+			'>', including the '<' and '>'.
+			When used in Visual mode it is made characterwise.
+
+i>						*v_i>* *v_i<* *i>* *i<*
+i<			"inner <> block", select [count] <> blocks, from
+			the [count]'th unmatched '<' backwards to the matching
+			'>', excluding the '<' and '>'.
+			When used in Visual mode it is made characterwise.
+
+						*v_at* *at*
+at			"a tag block", select [count] tag blocks, from the
+			[count]'th unmatched "<aaa>" backwards to the matching
+			"</aaa>", including the "<aaa>" and "</aaa>".
+			See |tag-blocks| about the details.
+			When used in Visual mode it is made characterwise.
+
+						*v_it* *it*
+it			"inner tag block", select [count] tag blocks, from the
+			[count]'th unmatched "<aaa>" backwards to the matching
+			"</aaa>", excluding the "<aaa>" and "</aaa>".
+			See |tag-blocks| about the details.
+			When used in Visual mode it is made characterwise.
+
+a}							*v_a}* *a}* *a{*
+a{							*v_aB* *v_a{* *aB*
+aB			"a Block", select [count] Blocks, from "[count] [{" to
+			the matching '}', including the '{' and '}' (see
+			|[{|).
+			When used in Visual mode it is made characterwise.
+
+i}							*v_i}* *i}* *i{*
+i{							*v_iB* *v_i{* *iB*
+iB			"inner Block", select [count] Blocks, from "[count] [{"
+			to the matching '}', excluding the '{' and '}' (see
+			|[{|).
+			When used in Visual mode it is made characterwise.
+
+a"							*v_aquote* *aquote*
+a'							*v_a'* *a'*
+a`							*v_a`* *a`*
+			"a quoted string".  Selects the text from the previous
+			quote until the next quote.  The 'quoteescape' option
+			is used to skip escaped quotes.
+			Only works within one line.
+			When the cursor starts on a quote, Vim will figure out
+			which quote pairs form a string by searching from the
+			start of the line.
+			Any trailing or leading white space is included.
+			When used in Visual mode it is made characterwise.
+			Repeating this object in Visual mode another string is
+			included.  A count is currently not used.
+
+i"							*v_iquote* *iquote*
+i'							*v_i'* *i'*
+i`							*v_i`* *i`*
+			Like a", a' and a`, but exclude the quotes and
+			repeating won't extend the Visual selection.
+			Special case: With a count of 2 the quotes are
+			included, but no extra white space as with a"/a'/a`.
+
+When used after an operator:
+For non-block objects:
+	For the "a" commands: The operator applies to the object and the white
+	space after the object.  If there is no white space after the object
+	or when the cursor was in the white space before the object, the white
+	space before the object is included.
+	For the "inner" commands: If the cursor was on the object, the
+	operator applies to the object.  If the cursor was on white space, the
+	operator applies to the white space.
+For a block object:
+	The operator applies to the block where the cursor is in, or the block
+	on which the cursor is on one of the braces.  For the "inner" commands
+	the surrounding braces are excluded.  For the "a" commands, the braces
+	are included.
+
+When used in Visual mode:
+When start and end of the Visual area are the same (just after typing "v"):
+	One object is selected, the same as for using an operator.
+When start and end of the Visual area are not the same:
+	For non-block objects the area is extended by one object or the white
+	space up to the next object, or both for the "a" objects.  The
+	direction in which this happens depends on which side of the Visual
+	area the cursor is.  For the block objects the block is extended one
+	level outwards.
+
+For illustration, here is a list of delete commands, grouped from small to big
+objects.  Note that for a single character and a whole line the existing vi
+movement commands are used.
+	"dl"	delete character (alias: "x")		|dl|
+	"diw"	delete inner word			*diw*
+	"daw"	delete a word				*daw*
+	"diW"	delete inner WORD (see |WORD|)		*diW*
+	"daW"	delete a WORD (see |WORD|)		*daW*
+	"dd"	delete one line				|dd|
+	"dis"	delete inner sentence			*dis*
+	"das"	delete a sentence			*das*
+	"dib"	delete inner '(' ')' block		*dib*
+	"dab"	delete a '(' ')' block			*dab*
+	"dip"	delete inner paragraph			*dip*
+	"dap"	delete a paragraph			*dap*
+	"diB"	delete inner '{' '}' block		*diB*
+	"daB"	delete a '{' '}' block			*daB*
+
+Note the difference between using a movement command and an object.  The
+movement command operates from here (cursor position) to where the movement
+takes us.  When using an object the whole object is operated upon, no matter
+where on the object the cursor is.  For example, compare "dw" and "daw": "dw"
+deletes from the cursor position to the start of the next word, "daw" deletes
+the word under the cursor and the space after or before it.
+
+
+Tag blocks						*tag-blocks*
+
+For the "it" and "at" text objects an attempt is done to select blocks between
+matching tags for HTML and XML.  But since these are not completely compatible
+there are a few restrictions.
+
+The normal method is to select a <tag> until the matching </tag>.  For "at"
+the tags are included, for "it" they are excluded.  But when "it" is repeated
+the tags will be included (otherwise nothing would change).  Also, "it" used
+on a tag block with no contents will select the leading tag.
+
+"<aaa/>" items are skipped.  Case is ignored, also for XML where case does
+matter.
+
+In HTML it is possible to have a tag like <br> or <meta ...> without a
+matching end tag.  These are ignored.
+
+The text objects are tolerant about mistakes.  Stray end tags are ignored.
+
+==============================================================================
+7. Marks					*mark-motions* *E20* *E78*
+
+Jumping to a mark can be done in two ways:
+1. With ` (backtick):	  The cursor is positioned at the specified location
+			  and the motion is |exclusive|.
+2. With ' (single quote): The cursor is positioned on the first non-blank
+			  character in the line of the specified location and
+			  the motion is linewise.
+
+						*m* *mark* *Mark*
+m{a-zA-Z}		Set mark {a-zA-Z} at cursor position (does not move
+			the cursor, this is not a motion command).
+
+						*m'* *m`*
+m'  or  m`		Set the previous context mark.  This can be jumped to
+			with the "''" or "``" command (does not move the
+			cursor, this is not a motion command).
+
+						*m[* *m]*
+m[  or  m]		Set the |'[| or |']| mark.  Useful when an operator is
+			to be simulated by multiple commands.  (does not move
+			the cursor, this is not a motion command).
+
+						*:ma* *:mark* *E191*
+:[range]ma[rk] {a-zA-Z'}
+			Set mark {a-zA-Z'} at last line number in [range],
+			column 0.  Default is cursor line.
+
+						*:k*
+:[range]k{a-zA-Z'}	Same as :mark, but the space before the mark name can
+			be omitted.
+
+						*'* *'a* *`* *`a*
+'{a-z}  `{a-z}		Jump to the mark {a-z} in the current buffer.
+
+						*'A* *'0* *`A* *`0*
+'{A-Z0-9}  `{A-Z0-9}	To the mark {A-Z0-9} in the file where it was set (not
+			a motion command when in another file).  {not in Vi}
+
+						*g'* *g'a* *g`* *g`a*
+g'{mark}  g`{mark}
+			Jump to the {mark}, but don't change the jumplist when
+			jumping within the current buffer.  Example: >
+				g`"
+<			jumps to the last known position in a file.  See
+			$VIMRUNTIME/vimrc_example.vim.
+			Also see |:keepjumps|.
+			{not in Vi}
+
+						*:marks*
+:marks			List all the current marks (not a motion command).
+			The |'(|, |')|, |'{| and |'}| marks are not listed.
+			The first column has number zero.
+			{not in Vi}
+						*E283*
+:marks {arg}		List the marks that are mentioned in {arg} (not a
+			motion command).  For example: >
+				:marks aB
+<			to list marks 'a' and 'B'.  {not in Vi}
+
+							*:delm* *:delmarks*
+:delm[arks] {marks}	Delete the specified marks.  Marks that can be deleted
+			include A-Z and 0-9.  You cannot delete the ' mark.
+			They can be specified by giving the list of mark
+			names, or with a range, separated with a dash.  Spaces
+			are ignored.  Examples: >
+			   :delmarks a	      deletes mark a
+			   :delmarks a b 1    deletes marks a, b and 1
+			   :delmarks Aa       deletes marks A and a
+			   :delmarks p-z      deletes marks in the range p to z
+			   :delmarks ^.[]     deletes marks ^ . [ ]
+			   :delmarks \"	      deletes mark "
+<			{not in Vi}
+
+:delm[arks]!		Delete all marks for the current buffer, but not marks
+			A-Z or 0-9.
+			{not in Vi}
+
+A mark is not visible in any way.  It is just a position in the file that is
+remembered.  Do not confuse marks with named registers, they are totally
+unrelated.
+
+'a - 'z		lowercase marks, valid within one file
+'A - 'Z		uppercase marks, also called file marks, valid between files
+'0 - '9		numbered marks, set from .viminfo file
+
+Lowercase marks 'a to 'z are remembered as long as the file remains in the
+buffer list.  If you remove the file from the buffer list, all its marks are
+lost.  If you delete a line that contains a mark, that mark is erased.
+
+To delete a mark: Create a new line, position the mark there, delete the line.
+E.g.: "o<Esc>mxdd".  This does change the file though.  Using "u" won't work,
+it also restores marks.
+
+Lowercase marks can be used in combination with operators.  For example: "d't"
+deletes the lines from the cursor position to mark 't'.  Hint: Use mark 't' for
+Top, 'b' for Bottom, etc..  Lowercase marks are restored when using undo and
+redo.
+
+Uppercase marks 'A to 'Z include the file name.  {Vi: no uppercase marks} You
+can use them to jump from file to file.  You can only use an uppercase mark
+with an operator if the mark is in the current file.  The line number of the
+mark remains correct, even if you insert/delete lines or edit another file for
+a moment.  When the 'viminfo' option is not empty, uppercase marks are kept in
+the .viminfo file.  See |viminfo-file-marks|.
+
+Numbered marks '0 to '9 are quite different.  They can not be set directly.
+They are only present when using a viminfo file |viminfo-file|.  Basically '0
+is the location of the cursor when you last exited Vim, '1 the last but one
+time, etc.  Use the "r" flag in 'viminfo' to specify files for which no
+Numbered mark should be stored.  See |viminfo-file-marks|.
+
+
+							*'[* *`[*
+'[  `[			To the first character of the previously changed
+			or yanked text.  {not in Vi}
+
+							*']* *`]*
+']  `]			To the last character of the previously changed or
+			yanked text.  {not in Vi}
+
+After executing an operator the Cursor is put at the beginning of the text
+that was operated upon.  After a put command ("p" or "P") the cursor is
+sometimes placed at the first inserted line and sometimes on the last inserted
+character.  The four commands above put the cursor at either end.  Example:
+After yanking 10 lines you want to go to the last one of them: "10Y']".  After
+inserting several lines with the "p" command you want to jump to the lowest
+inserted line: "p']".  This also works for text that has been inserted.
+
+Note: After deleting text, the start and end positions are the same, except
+when using blockwise Visual mode.  These commands do not work when no change
+was made yet in the current file.
+
+							*'<* *`<*
+'<  `<			To the first character of the last selected Visual
+			area in the current buffer.  For block mode it may
+			also be the last character in the first line (to be
+			able to define the block).  {not in Vi}.
+
+							*'>* *`>*
+'>  `>			To the last character of the last selected Visual
+			area in the current buffer.  For block mode it may
+			also be the first character of the last line (to be
+			able to define the block).  Note that 'selection'
+			applies, the position may be just after the Visual
+			area.  {not in Vi}.
+
+							*''* *``*
+''  ``			To the position before the latest jump, or where the
+			last "m'" or "m`" command was given.  Not set when the
+			|:keepjumps| command modifier was used.
+			Also see |restore-position|.
+
+							*'quote* *`quote*
+'"  `"			To the cursor position when last exiting the current
+			buffer.  Defaults to the first character of the first
+			line.  See |last-position-jump| for how to use this
+			for each opened file.
+			Only one position is remembered per buffer, not one
+			for each window.  As long as the buffer is visible in
+			a window the position won't be changed.
+			{not in Vi}.
+
+							*'^* *`^*
+'^  `^			To the position where the cursor was the last time
+			when Insert mode was stopped.  This is used by the
+			|gi| command.  Not set when the |:keepjumps| command
+			modifier was used.  {not in Vi}
+
+							*'.* *`.*
+'.  `.			To the position where the last change was made.  The
+			position is at or near where the change started.
+			Sometimes a command is executed as several changes,
+			then the position can be near the end of what the
+			command changed.  For example when inserting a word,
+			the position will be on the last character.
+			{not in Vi}
+
+							*'(* *`(*
+'(  `(			To the start of the current sentence, like the |(|
+			command.  {not in Vi}
+
+							*')* *`)*
+')  `)			To the end of the current sentence, like the |)|
+			command.  {not in Vi}
+
+							*'{* *`{*
+'{  `{			To the start of the current paragraph, like the |{|
+			command.  {not in Vi}
+
+							*'}* *`}*
+'}  `}			To the end of the current paragraph, like the |}|
+			command.  {not in Vi}
+
+These commands are not marks themselves, but jump to a mark:
+
+							*]'*
+]'			[count] times to next line with a lowercase mark below
+			the cursor, on the first non-blank character in the
+			line. {not in Vi}
+
+							*]`*
+]`			[count] times to lowercase mark after the cursor. {not
+			in Vi}
+
+							*['*
+['			[count] times to previous line with a lowercase mark
+			before the cursor, on the first non-blank character in
+			the line. {not in Vi}
+
+							*[`*
+[`			[count] times to lowercase mark before the cursor.
+			{not in Vi}
+
+
+:loc[kmarks] {command}					*:loc* *:lockmarks*
+			Execute {command} without adjusting marks.  This is
+			useful when changing text in a way that the line count
+			will be the same when the change has completed.
+			WARNING: When the line count does change, marks below
+			the change will keep their line number, thus move to
+			another text line.
+			These items will not be adjusted for deleted/inserted
+			lines:
+			- lower case letter marks 'a - 'z
+			- upper case letter marks 'A - 'Z
+			- numbered marks '0 - '9
+			- last insert position '^
+			- last change position '.
+			- the Visual area '< and '>
+			- line numbers in placed signs
+			- line numbers in quickfix positions
+			- positions in the |jumplist|
+			- positions in the |tagstack|
+			These items will still be adjusted:
+			- previous context mark ''
+			- the cursor position
+			- the view of a window on a buffer
+			- folds
+			- diffs
+
+:kee[pmarks] {command}					*:kee* *:keepmarks*
+			Currently only has effect for the filter command
+			|:range!|:
+			- When the number of lines after filtering is equal to
+			  or larger than before, all marks are kept at the
+			  same line number.
+			- When the number of lines decreases, the marks in the
+			  lines that disappeared are deleted.
+			In any case the marks below the filtered text have
+			their line numbers adjusted, thus stick to the text,
+			as usual.
+			When the 'R' flag is missing from 'cpoptions' this has
+			the same effect as using ":keepmarks".
+
+							*:keepj* *:keepjumps*
+:keepj[umps] {command}
+			Moving around in {command} does not change the |''|,
+			|'.| and |'^| marks, the |jumplist| or the
+			|changelist|.
+			Useful when making a change or inserting text
+			automatically and the user doesn't want to go to this
+			position.  E.g., when updating a "Last change"
+			timestamp in the first line: >
+
+				:let lnum = line(".")
+				:keepjumps normal gg
+				:call SetLastChange()
+				:keepjumps exe "normal " . lnum . "G"
+<
+			Note that ":keepjumps" must be used for every command.
+			When invoking a function the commands in that function
+			can still change the jumplist.  Also, for
+			":keepjumps exe 'command '" the "command" won't keep
+			jumps.  Instead use: ":exe 'keepjumps command'"
+
+==============================================================================
+8. Jumps					*jump-motions*
+
+A "jump" is one of the following commands: "'", "`", "G", "/", "?", "n",
+"N", "%", "(", ")", "[[", "]]", "{", "}", ":s", ":tag", "L", "M", "H" and
+the commands that start editing a new file.  If you make the cursor "jump"
+with one of these commands, the position of the cursor before the jump is
+remembered.  You can return to that position with the "''" and "``" command,
+unless the line containing that position was changed or deleted.
+
+							*CTRL-O*
+CTRL-O			Go to [count] Older cursor position in jump list
+			(not a motion command).  {not in Vi}
+			{not available without the +jumplist feature}
+
+<Tab>		or					*CTRL-I* *<Tab>*
+CTRL-I			Go to [count] newer cursor position in jump list
+			(not a motion command).
+			In a |quickfix-window| it takes you to the position of
+			the error under the cursor.
+			{not in Vi}
+			{not available without the +jumplist feature}
+
+							*:ju* *:jumps*
+:ju[mps]		Print the jump list (not a motion command).  {not in
+			Vi} {not available without the +jumplist feature}
+
+							*jumplist*
+Jumps are remembered in a jump list.  With the CTRL-O and CTRL-I command you
+can go to cursor positions before older jumps, and back again.  Thus you can
+move up and down the list.  There is a separate jump list for each window.
+The maximum number of entries is fixed at 100.
+{not available without the +jumplist feature}
+
+For example, after three jump commands you have this jump list:
+
+  jump line  col file/line ~
+    3	  1    0 some text ~
+    2	 70    0 another line ~
+    1  1154   23 end. ~
+ > ~
+
+The "file/line" column shows the file name, or the text at the jump if it is
+in the current file (an indent is removed and a long line is truncated to fit
+in the window).
+
+You are currently in line 1167.  If you then use the CTRL-O command, the
+cursor is put in line 1154.  This results in:
+
+  jump line  col file/line ~
+    2	  1    0 some text ~
+    1	 70    0 another line ~
+ >  0  1154   23 end. ~
+    1  1167    0 foo bar ~
+
+The pointer will be set at the last used jump position.  The next CTRL-O
+command will use the entry above it, the next CTRL-I command will use the
+entry below it.  If the pointer is below the last entry, this indicates that
+you did not use a CTRL-I or CTRL-O before.  In this case the CTRL-O command
+will cause the cursor position to be added to the jump list, so you can get
+back to the position before the CTRL-O.  In this case this is line 1167.
+
+With more CTRL-O commands you will go to lines 70 and 1.  If you use CTRL-I
+you can go back to 1154 and 1167 again.  Note that the number in the "jump"
+column indicates the count for the CTRL-O or CTRL-I command that takes you to
+this position.
+
+If you use a jump command, the current line number is inserted at the end of
+the jump list.  If the same line was already in the jump list, it is removed.
+The result is that when repeating CTRL-O you will get back to old positions
+only once.
+
+When the |:keepjumps| command modifier is used, jumps are not stored in the
+jumplist.  Jumps are also not stored in other cases, e.g., in a |:global|
+command.  You can explicitly add a jump by setting the ' mark.
+
+After the CTRL-O command that got you into line 1154 you could give another
+jump command (e.g., "G").  The jump list would then become:
+
+  jump line  col file/line ~
+    4	  1    0 some text ~
+    3	 70    0 another line ~
+    2  1167    0 foo bar ~
+    1  1154   23 end. ~
+ > ~
+
+The line numbers will be adjusted for deleted and inserted lines.  This fails
+if you stop editing a file without writing, like with ":n!".
+
+When you split a window, the jumplist will be copied to the new window.
+
+If you have included the ' item in the 'viminfo' option the jumplist will be
+stored in the viminfo file and restored when starting Vim.
+
+
+CHANGE LIST JUMPS			*changelist* *change-list-jumps* *E664*
+
+When making a change the cursor position is remembered.  One position is
+remembered for every change that can be undone, unless it is close to a
+previous change.  Two commands can be used to jump to positions of changes,
+also those that have been undone:
+
+							*g;* *E662*
+g;			Go to [count] older position in change list.
+			If [count] is larger than the number of older change
+			positions go to the oldest change.
+			If there is no older change an error message is given.
+			(not a motion command)
+			{not in Vi}
+			{not available without the +jumplist feature}
+
+							*g,* *E663*
+g,			Go to [count] newer cursor position in change list.
+			Just like |g;| but in the opposite direction.
+			(not a motion command)
+			{not in Vi}
+			{not available without the +jumplist feature}
+
+When using a count you jump as far back or forward as possible.  Thus you can
+use "999g;" to go to the first change for which the position is still
+remembered.  The number of entries in the change list is fixed and is the same
+as for the |jumplist|.
+
+When two undo-able changes are in the same line and at a column position less
+than 'textwidth' apart only the last one is remembered.  This avoids that a
+sequence of small changes in a line, for example "xxxxx", adds many positions
+to the change list.  When 'textwidth' is zero 'wrapmargin' is used.  When that
+also isn't set a fixed number of 79 is used.  Detail: For the computations
+bytes are used, not characters, to avoid a speed penalty (this only matters
+for multi-byte encodings).
+
+Note that when text has been inserted or deleted the cursor position might be
+a bit different from the position of the change.  Especially when lines have
+been deleted.
+
+When the |:keepjumps| command modifier is used the position of a change is not
+remembered.
+
+							*:changes*
+:changes		Print the change list.  A ">" character indicates the
+			current position.  Just after a change it is below the
+			newest entry, indicating that "g;" takes you to the
+			newest entry position.  The first column indicates the
+			count needed to take you to this position.  Example:
+
+				change line  col text ~
+				    3     9    8 bla bla bla
+				    2    11   57 foo is a bar
+				    1    14   54 the latest changed line
+				>
+
+			The "3g;" command takes you to line 9.  Then the
+			output of ":changes is:
+
+				change line  col text ~
+				>   0     9    8 bla bla bla
+				    1    11   57 foo is a bar
+				    2    14   54 the latest changed line
+
+			Now you can use "g," to go to line 11 and "2g," to go
+			to line 14.
+
+==============================================================================
+9. Various motions				*various-motions*
+
+							*%*
+%			Find the next item in this line after or under the
+			cursor and jump to its match. |inclusive| motion.
+			Items can be:
+			([{}])		parenthesis or (curly/square) brackets
+					(this can be changed with the
+					'matchpairs' option)
+			/* */		start or end of C-style comment
+			#if, #ifdef, #else, #elif, #endif
+					C preprocessor conditionals (when the
+					cursor is on the # or no ([{
+					following)
+			For other items the matchit plugin can be used, see
+			|matchit-install|.
+
+			When 'cpoptions' contains "M" |cpo-M| backslashes
+			before parens and braces are ignored.  Without "M" the
+			number of backslashes matters: an even number doesn't
+			match with an odd number.  Thus in "( \) )" and "\( (
+			\)" the first and last parenthesis match.
+			When the '%' character is not present in 'cpoptions'
+			|cpo-%|, parens and braces inside double quotes are
+			ignored, unless the number of parens/braces in a line
+			is uneven and this line and the previous one does not
+			end in a backslash.  '(', '{', '[', ']', '}' and ')'
+			are also ignored (parens and braces inside single
+			quotes).  Note that this works fine for C, but not for
+			Perl, where single quotes are used for strings.
+			No count is allowed ({count}% jumps to a line {count}
+			percentage down the file |N%|).  Using '%' on
+			#if/#else/#endif makes the movement linewise.
+
+						*[(*
+[(			go to [count] previous unmatched '('.
+			|exclusive| motion. {not in Vi}
+
+						*[{*
+[{			go to [count] previous unmatched '{'.
+			|exclusive| motion. {not in Vi}
+
+						*])*
+])			go to [count] next unmatched ')'.
+			|exclusive| motion. {not in Vi}
+
+						*]}*
+]}			go to [count] next unmatched '}'.
+			|exclusive| motion. {not in Vi}
+
+The above four commands can be used to go to the start or end of the current
+code block.  It is like doing "%" on the '(', ')', '{' or '}' at the other
+end of the code block, but you can do this from anywhere in the code block.
+Very useful for C programs.  Example: When standing on "case x:", "[{" will
+bring you back to the switch statement.
+
+						*]m*
+]m			Go to [count] next start of a method (for Java or
+			similar structured language).  When not before the
+			start of a method, jump to the start or end of the
+			class.  When no '{' is found after the cursor, this is
+			an error.  |exclusive| motion. {not in Vi}
+						*]M*
+]M			Go to [count] next end of a method (for Java or
+			similar structured language).  When not before the end
+			of a method, jump to the start or end of the class.
+			When no '}' is found after the cursor, this is an
+			error. |exclusive| motion. {not in Vi}
+						*[m*
+[m			Go to [count] previous start of a method (for Java or
+			similar structured language).  When not after the
+			start of a method, jump to the start or end of the
+			class.  When no '{' is found before the cursor this is
+			an error. |exclusive| motion. {not in Vi}
+						*[M*
+[M			Go to [count] previous end of a method (for Java or
+			similar structured language).  When not after the
+			end of a method, jump to the start or end of the
+			class.  When no '}' is found before the cursor this is
+			an error. |exclusive| motion. {not in Vi}
+
+The above two commands assume that the file contains a class with methods.
+The class definition is surrounded in '{' and '}'.  Each method in the class
+is also surrounded with '{' and '}'.  This applies to the Java language.  The
+file looks like this: >
+
+	// comment
+	class foo {
+		int method_one() {
+			body_one();
+		}
+		int method_two() {
+			body_two();
+		}
+	}
+Starting with the cursor on "body_two()", using "[m" will jump to the '{' at
+the start of "method_two()" (obviously this is much more useful when the
+method is long!).  Using "2[m" will jump to the start of "method_one()".
+Using "3[m" will jump to the start of the class.
+
+						*[#*
+[#			go to [count] previous unmatched "#if" or "#else".
+			|exclusive| motion. {not in Vi}
+
+						*]#*
+]#			go to [count] next unmatched "#else" or "#endif".
+			|exclusive| motion. {not in Vi}
+
+These two commands work in C programs that contain #if/#else/#endif
+constructs.  It brings you to the start or end of the #if/#else/#endif where
+the current line is included.  You can then use "%" to go to the matching line.
+
+						*[star* *[/*
+[*  or  [/		go to [count] previous start of a C comment "/*".
+			|exclusive| motion. {not in Vi}
+
+						*]star* *]/*
+]*  or  ]/		go to [count] next end of a C comment "*/".
+			|exclusive| motion. {not in Vi}
+
+
+						*H*
+H			To line [count] from top (Home) of window (default:
+			first line on the window) on the first non-blank
+			character |linewise|.  See also 'startofline' option.
+			Cursor is adjusted for 'scrolloff' option.
+
+						*M*
+M			To Middle line of window, on the first non-blank
+			character |linewise|.  See also 'startofline' option.
+
+						*L*
+L			To line [count] from bottom of window (default: Last
+			line on the window) on the first non-blank character
+			|linewise|.  See also 'startofline' option.
+			Cursor is adjusted for 'scrolloff' option.
+
+<LeftMouse>		Moves to the position on the screen where the mouse
+			click is |exclusive|.  See also |<LeftMouse>|.  If the
+			position is in a status line, that window is made the
+			active window and the cursor is not moved.  {not in Vi}
+
+ vim:tw=78:ts=8:ft=help:norl:
--- /dev/null
+++ b/lib/vimfiles/doc/netbeans.txt
@@ -1,0 +1,822 @@
+*netbeans.txt*  For Vim version 7.1.  Last change: 2006 Nov 14
+
+
+		  VIM REFERENCE MANUAL    by Gordon Prieur
+
+
+NetBeans ExternalEditor Integration Features		*netbeans*
+							*netbeans-support*
+1.  Introduction				|netbeans-intro|
+2.  NetBeans Key Bindings			|netbeans-keybindings|
+3.  Configuring Vim for NetBeans		|netbeans-configure|
+4.  Downloading NetBeans			|netbeans-download|
+5.  Preparing NetBeans for Vim			|netbeans-preparation|
+6.  Obtaining the External Editor Module	|obtaining-exted|
+7.  Setting up NetBeans to run with Vim		|netbeans-setup|
+8.  Messages					|netbeans-messages|
+9.  Running Vim from NetBeans			|netbeans-run|
+10. NetBeans protocol				|netbeans-protocol|
+11. NetBeans commands				|netbeans-commands|
+12. Known problems				|netbeans-problems|
+
+{Vi does not have any of these features}
+{only available when compiled with the |+netbeans_intg| feature}
+
+==============================================================================
+1. Introduction						*netbeans-intro*
+
+NetBeans is an open source Integrated Development Environment developed
+jointly by Sun Microsystems, Inc. and the netbeans.org developer community.
+Initially just a Java IDE, NetBeans has had C, C++, and Fortran support added
+in recent releases.
+
+For more information visit the main NetBeans web site http://www.netbeans.org
+or the NetBeans External Editor site at http://externaleditor.netbeans.org.
+
+Sun Microsystems, Inc. also ships NetBeans under the name Sun ONE Studio.
+Visit http://www.sun.com for more information regarding the Sun ONE Studio
+product line.
+
+Current releases of NetBeans provide full support for Java and limited support
+for C, C++, and Fortran.  Current releases of Sun ONE Studio provide full
+support for Java, C, C++, and Fortran.
+
+The interface to NetBeans is also supported by Agide, the A-A-P GUI IDE.
+Agide is very different from NetBeans:
+- Based on Python instead of Java, much smaller footprint and fast startup.
+- Agide is a framework in which many different tools can work together.
+See the A-A-P website for information: http://www.A-A-P.org.
+
+==============================================================================
+2. NetBeans Key Bindings				*netbeans-keybindings*
+
+Vim understands a number of key bindings that execute NetBeans commands.
+These are typically all the Function key combinations.  To execute a NetBeans
+command, the user must press the Pause key followed by a NetBeans key binding.
+For example, in order to compile a Java file, the NetBeans key binding is
+"F9".  So, while in vim, press "Pause F9" to compile a java file.  To toggle a
+breakpoint at the current line, press "Pause Shift F8".
+
+The Pause key is Function key 21.  If you don't have a working Pause key and
+want to use F8 instead, use: >
+
+	:map <F8> <F21>
+
+The External Editor module dynamically reads the NetBeans key bindings so vim
+should always have the latest key bindings, even when NetBeans changes them.
+
+==============================================================================
+3. Configuring Vim for NetBeans			*netbeans-configure*
+
+For more help installing vim, please read |usr_90.txt| in the Vim User Manual.
+
+
+On Unix
+
+When running configure without arguments the NetBeans interface should be
+included.  That is, if the configure check to find out if your system supports
+the required features succeeds.
+
+In case you do not want the NetBeans interface you can disable it by
+uncommenting a line with "--disable-netbeans" in the Makefile.
+
+Currently, only gvim is supported in this integration as NetBeans does not
+have means to supply a terminal emulator for the vim command.  Furthermore,
+there is only GUI support for GTK, GNOME, and Motif.
+
+If Motif support is required the user must supply XPM libraries.  See
+|workshop-xpm| for details on obtaining the latest version of XPM.
+
+
+On MS-Windows
+
+The Win32 support is now in beta stage.
+
+To use XPM signs on Win32 (e.g. when using with NetBeans) you can compile
+XPM by yourself or use precompiled libraries from http://iamphet.nm.ru/misc/
+(for MS Visual C++) or http://gnuwin32.sourceforge.net (for MinGW).
+
+==============================================================================
+4. Downloading NetBeans					*netbeans-download*
+
+The NetBeans IDE is available for download from netbeans.org.  You can download
+a released version, download sources, or use CVS to download the current
+source tree.  If you choose to download sources, follow directions from
+netbeans.org on building NetBeans.
+
+Depending on the version of NetBeans you download, you may need to do further
+work to get the required External Editor module.  This is the module which lets
+NetBeans work with gvim (or xemacs :-).  See http://externaleditor.netbeans.org
+for details on downloading this module if your NetBeans release does not have
+it.
+
+For C, C++, and Fortran support you will also need the cpp module.  See
+http://cpp.netbeans.org for information regarding this module.
+
+You can also download Sun ONE Studio from Sun Microsystems, Inc for a 30 day
+free trial.  See http://www.sun.com for further details.
+
+==============================================================================
+5. Preparing NetBeans for Vim				*netbeans-preparation*
+
+In order for NetBeans to work with vim, the NetBeans External Editor module
+must be loaded and enabled.  If you have a Sun ONE Studio Enterprise Edition
+then this module should be loaded and enabled.  If you have a NetBeans release
+you may need to find another way of obtaining this open source module.
+
+You can check if you have this module by opening the Tools->Options dialog
+and drilling down to the "Modules" list (IDE Configuration->System->Modules).
+If your Modules list has an entry for "External Editor" you must make sure
+it is enabled (the "Enabled" property should have the value "True").  If your
+Modules list has no External Editor see the next section on |obtaining-exted|.
+
+==============================================================================
+6. Obtaining the External Editor Module			    *obtaining-exted*
+
+There are 2 ways of obtaining the External Editor module.  The easiest way
+is to use the NetBeans Update Center to download and install the module.
+Unfortunately, some versions do not have this module in their update
+center.  If you cannot download via the update center you will need to
+download sources and build the module.  I will try and get the module
+available from the NetBeans Update Center so building will be unnecessary.
+Also check http://externaleditor.netbeans.org for other availability options.
+
+To download the External Editor sources via CVS and build your own module,
+see http://externaleditor.netbeans.org and http://www.netbeans.org.
+Unfortunately, this is not a trivial procedure.
+
+==============================================================================
+7. Setting up NetBeans to run with Vim			    *netbeans-setup*
+
+Assuming you have loaded and enabled the NetBeans External Editor module
+as described in |netbeans-preparation| all you need to do is verify that
+the gvim command line is properly configured for your environment.
+
+Open the Tools->Options dialog and open the Editing category.  Select the
+External Editor.  The right hand pane should contain a Properties tab and
+an Expert tab.  In the Properties tab make sure the "Editor Type" is set
+to "Vim".  In the Expert tab make sure the "Vim Command" is correct.
+
+You should be careful if you change the "Vim Command".  There are command
+line options there which must be there for the connection to be properly
+set up.  You can change the command name but that's about it.  If your gvim
+can be found by your $PATH then the VIM Command can start with "gvim".  If
+you don't want gvim searched from your $PATH then hard code in the full
+Unix path name.  At this point you should get a gvim for any source file
+you open in NetBeans.
+
+If some files come up in gvim and others (with different file suffixes) come
+up in the default NetBeans editor you should verify the MIME type in the
+Expert tab MIME Type property.  NetBeans is MIME oriented and the External
+Editor will only open MIME types specified in this property.
+
+==============================================================================
+8. Messages						*netbeans-messages*
+
+These messages are specific for NetBeans:
+
+							*E463*
+Region is guarded, cannot modify
+		NetBeans defines guarded areas in the text, which you cannot
+		change.
+		Also sets the current buffer, if necessary.
+
+							*E656*
+NetBeans disallows writes of unmodified buffers
+		NetBeans does not support writes of unmodified buffers that
+		were opened from NetBeans.
+
+							*E657*
+Partial writes disallowed for NetBeans buffers
+		NetBeans does not support partial writes for buffers that were
+		opened from NetBeans.
+
+							*E658*
+NetBeans connection lost for this buffer
+		NetBeans has become confused about the state of this file.
+		Rather than risk data corruption, NetBeans has severed the
+		connection for this file.  Vim will take over responsibility
+		for saving changes to this file and NetBeans will no longer
+		know of these changes.
+
+							*E744*
+NetBeans does not allow changes in read-only files
+		Vim normally allows changes to a read-only file and only
+		enforces the read-only rule if you try to write the file.
+		However, NetBeans does not let you make changes to a file
+		which is read-only and becomes confused if vim does this.
+		So vim does not allow modifications to files when run with
+		NetBeans.
+==============================================================================
+9. Running Vim from NetBeans				*netbeans-run*
+
+NetBeans starts Vim with the |-nb| argument.  Three forms can be used, that
+differ in the way the information for the connection is specified:
+
+	-nb={fname}				from a file
+	-nb:{hostname}:{addr}:{password}	directly
+	-nb					from a file or environment
+
+							*E660* *E668*
+For security reasons, the best method is to write the information in a file
+readable only by the user.  The name of the file can be passed with the
+"-nb={fname}" argument or, when "-nb" is used without a parameter, the
+environment variable "__NETBEANS_CONINFO".  The file must contain these three
+lines, in any order:
+
+	host={hostname}
+	port={addr}
+	auth={password}
+
+Other lines are ignored.  The caller of Vim is responsible for deleting the
+file afterwards.
+
+{hostname} is the name of the machine where NetBeans is running.  When omitted
+the environment variable "__NETBEANS_HOST" is used or the default "localhost".
+
+{addr} is the port number for NetBeans.  When omitted the environment variable
+"__NETBEANS_SOCKET" is used or the default 3219.
+
+{password} is the password for connecting to NetBeans.  When omitted the
+environment variable "__NETBEANS_VIM_PASSWORD" is used or "changeme".
+
+==============================================================================
+10. NetBeans protocol					*netbeans-protocol*
+
+The communication between NetBeans and Vim uses plain text messages.  This
+protocol was first designed to work with the external editor module of
+NetBeans (see http://externaleditor.netbeans.org).  Later it was extended to
+work with Agide (A-A-P GUI IDE, see http://www.a-a-p.org).  The extensions are
+marked with "version 2.1".
+
+Version 2.2 of the protocol has several minor changes which should only affect
+NetBeans users (ie, not Agide users).  However, a bug was fixed which could
+cause confusion.  The netbeans_saved() function sent a "save" protocol
+command.  In protocol version 2.1 and earlier this was incorrectly interpreted
+as a notification that a write had taken place.  In reality, it told NetBeans
+to save the file so multiple writes were being done.  This caused various
+problems and has been fixed in 2.2.  To decrease the likelihood of this
+confusion happening again, netbeans_saved() has been renamed to
+netbeans_save_buffer().
+
+We are now at version 2.4.  For the differences between 2.3 and 2.4 search for
+"2.4" below.
+
+The messages are currently sent over a socket.  Since the messages are in
+plain UTF-8 text this protocol could also be used with any other communication
+mechanism.
+
+To see an example implementation look at the gvim tool in Agide.  Currently
+found here:
+	http://cvs.sf.net/viewcvs.py/a-a-p/Agide/Tools/GvimTool.py?view=markup
+
+
+
+10.1 Kinds of messages		|nb-messages|
+10.2 Terms			|nb-terms|
+10.3 Commands			|nb-commands|
+10.4 Functions and Replies	|nb-functions|
+10.5 Events			|nb-events|
+10.6 Special messages		|nb-special|
+
+*E627* *E628* *E629* *E630* *E631* *E632* *E633* *E634* *E635* *E636*
+*E637* *E638* *E639* *E640* *E641* *E642* *E643* *E644* *E645* *E646*
+*E647* *E648* *E649* *E650* *E651* *E652* *E653* *E654*
+These errors occur when a message violates the protocol.
+
+
+10.1 Kinds of messages					*nb-messages*
+
+There are four kinds of messages:
+
+kind		direction	comment ~
+Command		IDE -> editor	no reply necessary
+Function	IDE -> editor	editor must send back a reply
+Reply		editor -> IDE	only in response to a Function
+Event		editor -> IDE	no reply necessary
+
+The messages are sent as a single line with a terminating newline character.
+Arguments are separated by a single space.  The first item of the message
+depends on the kind of message:
+
+kind		first item		example ~
+Command		bufID:name!seqno	11:showBalloon!123 "text"
+Function	bufID:name/seqno	11:getLength/123
+Reply		seqno			123 5000
+Event		bufID:name=123		11:keyCommand=123 "S-F2"
+
+
+10.2 Terms						*nb-terms*
+
+bufID		Buffer number.  A message may be either for a specific buffer
+		or generic.  Generic messages use a bufID of zero.  NOTE: this
+		buffer ID is assigned by the IDE, it is not Vim's buffer
+		number.  The bufID must be a sequentially rising number,
+		starting at one.
+
+seqno		The IDE uses a sequence number for Commands and Functions.  A
+		Reply must use the sequence number of the Function that it is
+		associated with.  A zero sequence number can be used for
+		Events (the seqno of the last received Command or Function can
+		also be used).
+
+string		Argument in double quotes.  Text is in UTF-8 encoding.  This
+		means ASCII is passed as-is.  Special characters are
+		represented with a backslash:
+			\"	double quote
+			\n	newline
+			\r	carriage-return
+			\t	tab (optional, also works literally)
+			\\	backslash
+		NUL bytes are not allowed!
+
+boolean		Argument with two possible values:
+			T	true
+			F	false
+
+number		Argument with a decimal number.
+
+optnum		Argument with either a decimal number or "none" (without the
+		quotes).
+
+offset		A number argument that indicates a byte position in a buffer.
+		The first byte has offset zero.  Line breaks are counted for
+		how they appear in the file (CR/LF counts for two bytes).
+		Note that a multi-byte character is counted for the number of
+		bytes it takes.
+
+lnum/col	Argument with a line number and column number position.  The
+		line number starts with one, the column is the byte position,
+		starting with zero.  Note that a multi-byte character counts
+		for several columns.
+
+pathname	String argument: file name with full path.
+
+
+10.3 Commands						*nb-commands*
+
+actionMenuItem	Not implemented.
+
+actionSensitivity
+		Not implemented.
+
+addAnno serNum typeNum off len
+		Place an annotation in this buffer.
+		Arguments:
+		   serNum	number	serial number of this placed
+					annotation, used to be able to remove
+					it
+		   typeNum	number	sequence number of the annotation
+					defined with defineAnnoType for this
+					buffer
+		   off		number	offset where annotation is to be placed
+		   len		number	not used
+		In version 2.1 "lnum/col" can be used instead of "off".
+
+balloonResult text
+		Not implemented.
+
+close		Close the buffer.  This leaves us without current buffer, very
+		dangerous to use!
+
+create		Creates a buffer without a name.  Replaces the current buffer
+		(it's hidden when it was changed).
+		NetBeans uses this as the first command for a file that is
+		being opened.  The sequence of commands could be:
+			create
+			setCaretListener	(ignored)
+			setModified		(no effect)
+			setContentType		(ignored)
+			startDocumentListen
+			setTitle
+			setFullName
+
+defineAnnoType typeNum typeName tooltip glyphFile fg bg
+		Define a type of annotation for this buffer.
+		Arguments:
+		   typeNum	number	sequence number (not really used)
+		   typeName	string	name that identifies this annotation
+		   tooltip	string	not used
+		   glyphFile	string	name of icon file
+		   fg		optnum	foreground color for line highlighting
+		   bg		optnum	background color for line highlighting
+		Vim will define a sign for the annotation.
+		When both "fg" and "bg" are "none" no line highlighting is
+		used (new in version 2.1).
+		When "glyphFile" is empty, no text sign is used (new in
+		version 2.1).
+		When "glyphFile" is one or two characters long, a text sign is
+		defined (new in version 2.1).
+		Note: the annotations will be defined in sequence, and the
+		sequence number is later used with addAnno.
+
+editFile pathname
+		Set the name for the buffer and edit the file "pathname", a
+		string argument.
+		Normal way for the IDE to tell the editor to edit a file.  If
+		the IDE is going to pass the file text to the editor use these
+		commands instead:
+			setFullName
+			insert
+			initDone
+		New in version 2.1.
+
+enableBalloonEval
+		Not implemented.
+
+endAtomic	End an atomic operation.  The changes between "startAtomic"
+		and "endAtomic" can be undone as one operation.  But it's not
+		implemented yet.  Redraw when necessary.
+
+guard off len
+		Mark an area in the buffer as guarded.  This means it cannot
+		be edited.  "off" and "len" are numbers and specify the text
+		to be guarded.
+
+initDone	Mark the buffer as ready for use.  Implicitly makes the buffer
+		the current buffer.  Fires the BufReadPost autocommand event.
+
+insertDone
+		Sent by NetBeans to tell vim an initial file insert is done.
+		This triggers a read message being printed.  Prior to version
+		2.3, no read messages were displayed after opening a file.
+		New in version 2.3.
+
+moveAnnoToFront serNum
+		Not implemented.
+
+netbeansBuffer isNetbeansBuffer
+		If "isNetbeansBuffer" is "T" then this buffer is ``owned'' by
+		NetBeans.
+		New in version 2.2.
+
+putBufferNumber pathname
+		Associate a buffer number with the Vim buffer by the name
+		"pathname", a string argument.  To be used when the editor
+		reported editing another file to the IDE and the IDE needs to
+		tell the editor what buffer number it will use for this file.
+		Also marks the buffer as initialized.
+		New in version 2.1.
+
+raise		Bring the editor to the foreground.
+		New in version 2.1.
+
+removeAnno serNum
+		Remove a previously place annotation for this buffer.
+		"serNum" is the same number used in addAnno.
+
+save		Save the buffer when it was modified.  The other side of the
+		interface is expected to write the buffer and invoke
+		"setModified" to reset the "changed" flag of the buffer.
+		The writing is skipped when one of these conditions is true:
+		- 'write' is not set
+		- the buffer is read-only
+		- the buffer does not have a file name
+		- 'buftype' disallows writing
+		New in version 2.2.
+
+saveDone
+		Sent by NetBeans to tell vim a save is done.  This triggers
+		a save message being printed.  Prior to version 2.3, no save
+		messages were displayed after a save.
+		New in version 2.3.
+
+setAsUser	Not implemented.
+
+setBufferNumber pathname
+		Associate a buffer number with Vim buffer by the name
+		"pathname".  To be used when the editor reported editing
+		another file to the IDE and the IDE needs to tell the editor
+		what buffer number it will use for this file.
+		Has the side effect of making the buffer the current buffer.
+		See "putBufferNumber" for a more useful command.
+
+setContentType
+		Not implemented.
+
+setDot off	Make the buffer the current buffer and set the cursor at the
+		specified position.  If the buffer is open in another window
+		than make that window the current window.
+		If there are folds they are opened to make the cursor line
+		visible.
+		In version 2.1 "lnum/col" can be used instead of "off".
+
+setExitDelay seconds
+		Set the delay for exiting to "seconds", a number.
+		This delay is used to give the IDE a chance to handle things
+		before really exiting.  The default delay is two seconds.
+		New in version 2.1.
+		Obsolete in version 2.3.
+
+setFullName pathname
+		Set the file name to be used for a buffer to "pathname", a
+		string argument.
+		Used when the IDE wants to edit a file under control of the
+		IDE.  This makes the buffer the current buffer, but does not
+		read the file.  "insert" commands will be used next to set the
+		contents.
+
+setLocAndSize	Not implemented.
+
+setMark		Not implemented.
+
+setModified modified
+		When the boolean argument "modified" is "T" mark the buffer as
+		modified, when it is "F" mark it as unmodified.
+
+setModtime time
+		Update a buffers modification time after NetBeans saves the
+		file.
+		New in version 2.3.
+
+setReadOnly
+		Passed by NetBeans to tell vim a file is readonly.
+		Implemented in verion 2.3.
+
+setStyle	Not implemented.
+
+setTitle name
+		Set the title for the buffer to "name", a string argument.
+		The title is only used for NetBeans functions, not by Vim.
+
+setVisible visible
+		When the boolean argument "visible" is "T", goto the buffer.
+		The "F" argument does nothing.
+
+showBalloon text
+		Show a balloon (popup window) at the mouse pointer position,
+		containing "text", a string argument.  The balloon should
+		disappear when the mouse is moved more than a few pixels.
+		New in version 2.1.
+
+specialKeys
+		Map a set of keys (mostly function keys) to be passed back
+		to NetBeans for processing.  This lets NetBeans hotkeys be
+		used from vim.
+		Implemented in version 2.3.
+
+startAtomic	Begin an atomic operation.  The screen will not be updated
+		until "endAtomic" is given.
+
+startCaretListen
+		Not implemented.
+
+startDocumentListen
+		Mark the buffer to report changes to the IDE with the
+		"insert" and "remove" events.  The default is to report
+		changes.
+
+stopCaretListen
+		Not implemented.
+
+stopDocumentListen
+		Mark the buffer to stop reporting changes to the IDE.
+		Opposite of startDocumentListen.
+		NOTE: if "netbeansBuffer" was used to mark this buffer as a
+		NetBeans buffer, then the buffer is deleted in Vim.  This is
+		for compatibility with Sun Studio 10.
+
+unguard off len
+		Opposite of "guard", remove guarding for a text area.
+		Also sets the current buffer, if necessary.
+
+version		Not implemented.
+
+
+10.4 Functions and Replies				*nb-functions*
+
+getDot		Not implemented.
+
+getCursor	Return the current buffer and cursor position.
+		The reply is:
+			seqno bufID lnum col off
+		seqno = sequence number of the function
+		bufID = buffer ID of the current buffer (if this is unknown -1
+			is used)
+		lnum  = line number of the cursor (first line is one)
+		col   = column number of the cursor (in bytes, zero based)
+		off   = offset of the cursor in the buffer (in bytes)
+		New in version 2.1.
+
+getLength	Return the length of the buffer in bytes.
+		Reply example for a buffer with 5000 bytes:
+			123 5000
+		TODO: explain use of partial line.
+
+getMark		Not implemented.
+
+getAnno serNum
+		Return the line number of the annotation in the buffer.
+		Argument:
+			serNum		serial number of this placed annotation
+		The reply is:
+			123 lnum	line number of the annotation
+			123 0		invalid annotation serial number
+		New in version 2.4.
+
+getModified	When a buffer is specified: Return zero if the buffer does not
+		have changes, one if it does have changes.
+		When no buffer is specified (buffer number zero): Return the
+		number of buffers with changes.  When the result is zero it's
+		safe to tell Vim to exit.
+		New in version 2.1.
+
+getText		Return the contents of the buffer as a string.
+		Reply example for a buffer with two lines
+			123 "first line\nsecond line\n"
+		NOTE: docs indicate an offset and length argument, but this is
+		not implemented.
+
+insert off text
+		Insert "text" before position "off".  "text" is a string
+		argument, "off" a number.
+		"off" should have a "\n" (newline) at the end of each line.
+		Or "\r\n" when 'fileformat' is "dos".  When using "insert" in
+		an empty buffer Vim will set 'fileformat' accordingly.
+		When "off" points to the start of a line the text is inserted
+		above this line.  Thus when "off" is zero lines are inserted
+		before the first line.
+		When "off" points after the start of a line, possibly on the
+		NUL at the end of a line, the first line of text is appended
+		to this line.  Further lines come below it.
+		Possible replies:
+			123		no problem
+			123 !message	failed
+		Note that the message in the reply is not quoted.
+		Also sets the current buffer, if necessary.
+		Does not move the cursor to the changed text.
+		Resets undo information.
+
+remove off length
+		Delete "length" bytes of text at position "off".  Both
+		arguments are numbers.
+		Possible replies:
+			123		no problem
+			123 !message	failed
+		Note that the message in the reply is not quoted.
+		Also sets the current buffer, if necessary.
+
+saveAndExit	Perform the equivalent of closing Vim: ":confirm qall".
+		If there are no changed files or the user does not cancel the
+		operation Vim exits and no result is sent back.  The IDE can
+		consider closing the connection as a successful result.
+		If the user cancels the operation the number of modified
+		buffers that remains is returned and Vim does not exit.
+		New in version 2.1.
+
+
+10.5 Events						*nb-events*
+
+balloonEval off len type
+		The mouse pointer rests on text for a short while.  When "len"
+		is zero, there is no selection and the pointer is at position
+		"off".  When "len" is non-zero the text from position "off" to
+		"off" + "len" is selected.
+		Only sent after "enableBalloonEval" was used for this buffer.
+		"type" is not yet defined.
+		Not implemented yet.
+
+balloonText text
+		Used when 'ballooneval' is set and the mouse pointer rests on
+		some text for a moment.  "text" is a string, the text under
+		the mouse pointer.
+		New in version 2.1.
+
+buttonRelease button lnum col
+		Report which button was pressed and the location of the cursor
+		at the time of the release.  Only for buffers that are owned
+		by NetBeans.  This event is not sent if the button was
+		released while the mouse was in the status line or in a
+		separator line.  If col is less than 1 the button release was
+		in the sign area.
+		New in version 2.2.
+
+disconnect
+		Tell NetBeans that vim is exiting and not to try and read or
+		write more commands.
+		New in version 2.3.
+
+fileClosed	Not implemented.
+
+fileModified	Not implemented.
+
+fileOpened pathname open modified
+		A file was opened by the user.
+		Arguments:
+		   pathname	string	  name of the file
+		   open		boolean   always "T"
+		   modified	boolean   always "F"
+
+geometry cols rows x y
+		Report the size and position of the editor window.
+		Arguments:
+		   cols		number	  number of text columns
+		   rows		number	  number of text rows
+		   x		number	  pixel position on screen
+		   y		number	  pixel position on screen
+		Only works for Motif.
+
+insert off text
+		Text "text" has been inserted in Vim at position "off".
+		Only fired when enabled, see "startDocumentListen".
+
+invokeAction	Not implemented.
+
+keyCommand keyName
+		Reports a special key being pressed with name "keyName", which
+		is a string.
+		Supported key names:
+			F1		function key 1
+			F2		function key 2
+			...
+			F12		function key 12
+
+			' '		space (without the quotes)
+			!		exclamation mark
+			...		any other ASCII printable character
+			~		tilde
+
+			X		any unrecognized key
+
+		The key may be prepended by "C", "S" and/or "M" for Control,
+		Shift and Meta (Alt) modifiers.  If there is a modifier a dash
+		is used to separate it from the key name.  For example:
+		"C-F2".
+		ASCII characters are new in version 2.1.
+
+keyAtPos keyName lnum/col
+		Like "keyCommand" and also report the line number and column
+		of the cursor.
+		New in version 2.1.
+
+killed		A file was closed by the user.  Only for files that have been
+		assigned a number by the IDE.
+
+newDotAndMark off off
+		Reports the position of the cursor being at "off" bytes into
+		the buffer.  Only sent just before a "keyCommand" event.
+
+quit		Not implemented.
+
+remove off len
+		Text was deleted in Vim at position "off" with byte length
+		"len".
+		Only fired when enabled, see "startDocumentListen".
+
+revert		Not implemented.
+
+save		The buffer has been saved and is now unmodified.
+		Only fired when enabled, see "startDocumentListen".
+
+startupDone	The editor has finished its startup work and is ready for
+		editing files.
+		New in version 2.1.
+
+unmodified	The buffer is now unmodified.
+		Only fired when enabled, see "startDocumentListen".
+
+version vers	Report the version of the interface implementation.  Vim
+		reports "2.2" (including the quotes).
+
+
+10.6 Special messages					*nb-special*
+
+These messages do not follow the style of the messages above.  They are
+terminated by a newline character.
+
+ACCEPT		Not used.
+
+AUTH password	editor -> IDE: First message that the editor sends to the IDE.
+		Must contain the password for the socket server, as specified
+		with the |-nb| argument.  No quotes are used!
+
+DISCONNECT	IDE -> editor: break the connection.  The editor will exit.
+		The IDE must only send this message when there are no unsaved
+		changes!
+
+DETACH		IDE -> editor: break the connection without exiting the
+		editor.  Used when the IDE exits without bringing down the
+		editor as well.
+		New in version 2.1.
+
+REJECT		Not used.
+
+==============================================================================
+11. NetBeans Commands					*netbeans-commands*
+
+							*:nbkey*
+:nbkey key			Pass the key to NetBeans for processing
+
+Pass the key to NetBeans for hot-key processing.  You should not need to use
+this command directly.  However, NetBeans passes a list of hot-keys to Vim at
+startup and when one of these keys is pressed, this command is generated to
+send the key press back to NetBeans.
+
+==============================================================================
+12. Known problems					*netbeans-problems*
+
+NUL bytes are not possible.  For editor -> IDE they will appear as NL
+characters.  For IDE -> editor they cannot be inserted.
+
+
+ vim:tw=78:ts=8:ft=help:norl:
--- /dev/null
+++ b/lib/vimfiles/doc/options.txt
@@ -1,0 +1,7735 @@
+*options.txt*	For Vim version 7.1.  Last change: 2007 May 11
+
+
+		  VIM REFERENCE MANUAL	  by Bram Moolenaar
+
+
+Options							*options*
+
+1. Setting options			|set-option|
+2. Automatically setting options	|auto-setting|
+3. Options summary			|option-summary|
+
+For an overview of options see help.txt |option-list|.
+
+Vim has a number of internal variables and switches which can be set to
+achieve special effects.  These options come in three forms:
+	boolean		can only be on or off		*boolean* *toggle*
+	number		has a numeric value
+	string		has a string value
+
+==============================================================================
+1. Setting options					*set-option* *E764*
+
+							*:se* *:set*
+:se[t]			Show all options that differ from their default value.
+
+:se[t] all		Show all but terminal options.
+
+:se[t] termcap		Show all terminal options.  Note that in the GUI the
+			key codes are not shown, because they are generated
+			internally and can't be changed.  Changing the terminal
+			codes in the GUI is not useful either...
+
+								*E518* *E519*
+:se[t] {option}?	Show value of {option}.
+
+:se[t] {option}		Toggle option: set, switch it on.
+			Number option: show value.
+			String option: show value.
+
+:se[t] no{option}	Toggle option: Reset, switch it off.
+
+:se[t] {option}!   or
+:se[t] inv{option}	Toggle option: Invert value. {not in Vi}
+
+				*:set-default* *:set-&* *:set-&vi* *:set-&vim*
+:se[t] {option}&	Reset option to its default value.  May depend on the
+			current value of 'compatible'. {not in Vi}
+:se[t] {option}&vi	Reset option to its Vi default value. {not in Vi}
+:se[t] {option}&vim	Reset option to its Vim default value. {not in Vi}
+
+:se[t] all&		Set all options, except terminal options, to their
+			default value.  The values of 'term', 'lines' and
+			'columns' are not changed. {not in Vi}
+
+						*:set-args* *E487* *E521*
+:se[t] {option}={value}		or
+:se[t] {option}:{value}
+			Set string or number option to {value}.
+			For numeric options the value can be given in decimal,
+			hex (preceded with 0x) or octal (preceded with '0')
+			(hex and octal are only available for machines which
+			have the strtol() function).
+			The old value can be inserted by typing 'wildchar' (by
+			default this is a <Tab> or CTRL-E if 'compatible' is
+			set).  See |cmdline-completion|.
+			White space between {option} and '=' is allowed and
+			will be ignored.  White space between '=' and {value}
+			is not allowed.
+			See |option-backslash| for using white space and
+			backslashes in {value}.
+
+:se[t] {option}+={value}				*:set+=*
+			Add the {value} to a number option, or append the
+			{value} to a string option.  When the option is a
+			comma separated list, a comma is added, unless the
+			value was empty.
+			If the option is a list of flags, superfluous flags
+			are removed.  When adding a flag that was already
+			present the option value doesn't change.
+			Also see |:set-args| above.
+			{not in Vi}
+
+:se[t] {option}^={value}				*:set^=*
+			Multiply the {value} to a number option, or prepend
+			the {value} to a string option.  When the option is a
+			comma separated list, a comma is added, unless the
+			value was empty.
+			Also see |:set-args| above.
+			{not in Vi}
+
+:se[t] {option}-={value}				*:set-=*
+			Subtract the {value} from a number option, or remove
+			the {value} from a string option, if it is there.
+			If the {value} is not found in a string option, there
+			is no error or warning.  When the option is a comma
+			separated list, a comma is deleted, unless the option
+			becomes empty.
+			When the option is a list of flags, {value} must be
+			exactly as they appear in the option.  Remove flags
+			one by one to avoid problems.
+			Also see |:set-args| above.
+			{not in Vi}
+
+The {option} arguments to ":set" may be repeated.  For example: >
+	:set ai nosi sw=3 ts=3
+If you make an error in one of the arguments, an error message will be given
+and the following arguments will be ignored.
+
+							*:set-verbose*
+When 'verbose' is non-zero, displaying an option value will also tell where it
+was last set.  Example: >
+	:verbose set shiftwidth cindent?
+	  shiftwidth=4
+		  Last set from modeline
+	  cindent
+		  Last set from /usr/local/share/vim/vim60/ftplugin/c.vim
+This is only done when specific option values are requested, not for ":set
+all" or ":set" without an argument.
+When the option was set by hand there is no "Last set" message.  There is only
+one value for all local options with the same name.  Thus the message applies
+to the option name, not necessarily its value.
+When the option was set while executing a function, user command or
+autocommand, the script in which it was defined is reported.
+Note that an option may also have been set as a side effect of setting
+'compatible'.
+{not available when compiled without the +eval feature}
+
+							*:set-termcap* *E522*
+For {option} the form "t_xx" may be used to set a terminal option.  This will
+override the value from the termcap.  You can then use it in a mapping.  If
+the "xx" part contains special characters, use the <t_xx> form: >
+	:set <t_#4>=^[Ot
+This can also be used to translate a special code for a normal key.  For
+example, if Alt-b produces <Esc>b, use this: >
+	:set <M-b>=^[b
+(the ^[ is a real <Esc> here, use CTRL-V <Esc> to enter it)
+The advantage over a mapping is that it works in all situations.
+
+The t_xx options cannot be set from a |modeline| or in the |sandbox|, for
+security reasons.
+
+The listing from ":set" looks different from Vi.  Long string options are put
+at the end of the list.  The number of options is quite large.  The output of
+"set all" probably does not fit on the screen, causing Vim to give the
+|more-prompt|.
+
+							*option-backslash*
+To include white space in a string option value it has to be preceded with a
+backslash.  To include a backslash you have to use two.  Effectively this
+means that the number of backslashes in an option value is halved (rounded
+down).
+A few examples: >
+   :set tags=tags\ /usr/tags	    results in "tags /usr/tags"
+   :set tags=tags\\,file	    results in "tags\,file"
+   :set tags=tags\\\ file	    results in "tags\ file"
+
+The "|" character separates a ":set" command from a following command.  To
+include the "|" in the option value, use "\|" instead.  This example sets the
+'titlestring' option to "hi|there": >
+   :set titlestring=hi\|there
+This sets the 'titlestring' option to "hi" and 'iconstring' to "there": >
+   :set titlestring=hi|set iconstring=there
+
+Similarly, the double quote character starts a comment.  To include the '"' in
+the option value, use '\"' instead.  This example sets the 'titlestring'
+option to 'hi "there"': >
+   :set titlestring=hi\ \"there\"
+
+For MS-DOS and WIN32 backslashes in file names are mostly not removed.  More
+precise: For options that expect a file name (those where environment
+variables are expanded) a backslash before a normal file name character is not
+removed.  But a backslash before a special character (space, backslash, comma,
+etc.) is used like explained above.
+There is one special situation, when the value starts with "\\": >
+   :set dir=\\machine\path	    results in "\\machine\path"
+   :set dir=\\\\machine\\path	    results in "\\machine\path"
+   :set dir=\\path\\file	    results in "\\path\file" (wrong!)
+For the first one the start is kept, but for the second one the backslashes
+are halved.  This makes sure it works both when you expect backslashes to be
+halved and when you expect the backslashes to be kept.  The third gives a
+result which is probably not what you want.  Avoid it.
+
+				*add-option-flags* *remove-option-flags*
+				*E539* *E550* *E551* *E552*
+Some options are a list of flags.  When you want to add a flag to such an
+option, without changing the existing ones, you can do it like this: >
+   :set guioptions+=a
+Remove a flag from an option like this: >
+   :set guioptions-=a
+This removes the 'a' flag from 'guioptions'.
+Note that you should add or remove one flag at a time.  If 'guioptions' has
+the value "ab", using "set guioptions-=ba" won't work, because the string "ba"
+doesn't appear.
+
+			   *:set_env* *expand-env* *expand-environment-var*
+Environment variables in specific string options will be expanded.  If the
+environment variable exists the '$' and the following environment variable
+name is replaced with its value.  If it does not exist the '$' and the name
+are not modified.  Any non-id character (not a letter, digit or '_') may
+follow the environment variable name.  That character and what follows is
+appended to the value of the environment variable.  Examples: >
+   :set term=$TERM.new
+   :set path=/usr/$INCLUDE,$HOME/include,.
+When adding or removing a string from an option with ":set opt-=val" or ":set
+opt+=val" the expansion is done before the adding or removing.
+
+
+Handling of local options			*local-options*
+
+Some of the options only apply to a window or buffer.  Each window or buffer
+has its own copy of this option, thus can each have their own value.  This
+allows you to set 'list' in one window but not in another.  And set
+'shiftwidth' to 3 in one buffer and 4 in another.
+
+The following explains what happens to these local options in specific
+situations.  You don't really need to know all of this, since Vim mostly uses
+the option values you would expect.  Unfortunately, doing what the user
+expects is a bit complicated...
+
+When splitting a window, the local options are copied to the new window.  Thus
+right after the split the contents of the two windows look the same.
+
+When editing a new buffer, its local option values must be initialized.  Since
+the local options of the current buffer might be specifically for that buffer,
+these are not used.  Instead, for each buffer-local option there also is a
+global value, which is used for new buffers.  With ":set" both the local and
+global value is changed.  With "setlocal" only the local value is changed,
+thus this value is not used when editing a new buffer.
+
+When editing a buffer that has been edited before, the last used window
+options are used again.  If this buffer has been edited in this window, the
+values from back then are used.  Otherwise the values from the window where
+the buffer was edited last are used.
+
+It's possible to set a local window option specifically for a type of buffer.
+When you edit another buffer in the same window, you don't want to keep
+using these local window options.  Therefore Vim keeps a global value of the
+local window options, which is used when editing another buffer.  Each window
+has its own copy of these values.  Thus these are local to the window, but
+global to all buffers in the window.  With this you can do: >
+	:e one
+	:set list
+	:e two
+Now the 'list' option will also be set in "two", since with the ":set list"
+command you have also set the global value. >
+	:set nolist
+	:e one
+	:setlocal list
+	:e two
+Now the 'list' option is not set, because ":set nolist" resets the global
+value, ":setlocal list" only changes the local value and ":e two" gets the
+global value.  Note that if you do this next: >
+	:e one
+You will not get back the 'list' value as it was the last time you edited
+"one".  The options local to a window are not remembered for each buffer.
+
+							*:setl* *:setlocal*
+:setl[ocal] ...		Like ":set" but set only the value local to the
+			current buffer or window.  Not all options have a
+			local value.  If the option does not have a local
+			value the global value is set.
+			With the "all" argument: display all local option's
+			local values.
+			Without argument: Display all local option's local
+			values which are different from the default.
+			When displaying a specific local option, show the
+			local value.  For a global option the global value is
+			shown (but that might change in the future).
+			{not in Vi}
+
+:setl[ocal] {option}<	Set the local value of {option} to its global value by
+			copying the value.
+			{not in Vi}
+
+:se[t] {option}<	Set the local value of {option} to its global value by
+			making it empty.  Only makes sense for |global-local|
+			options.
+			{not in Vi}
+
+							*:setg* *:setglobal*
+:setg[lobal] ...	Like ":set" but set only the global value for a local
+			option without changing the local value.
+			When displaying an option, the global value is shown.
+			With the "all" argument: display all local option's
+			global values.
+			Without argument: display all local option's global
+			values which are different from the default.
+			{not in Vi}
+
+For buffer-local and window-local options:
+	Command		 global value	    local value ~
+      :set option=value	     set		set
+ :setlocal option=value	      -			set
+:setglobal option=value	     set		 -
+      :set option?	      -		       display
+ :setlocal option?	      -		       display
+:setglobal option?	    display		 -
+
+
+Global options with a local value			*global-local*
+
+Options are global when you mostly use one value for all buffers and windows.
+For some global options it's useful to sometimes have a different local value.
+You can set the local value with ":setlocal".  That buffer or window will then
+use the local value, while other buffers and windows continue using the global
+value.
+
+For example, you have two windows, both on C source code.  They use the global
+'makeprg' option.  If you do this in one of the two windows: >
+	:set makeprg=gmake
+then the other window will switch to the same value.  There is no need to set
+the 'makeprg' option in the other C source window too.
+However, if you start editing a Perl file in a new window, you want to use
+another 'makeprg' for it, without changing the value used for the C source
+files.  You use this command: >
+	:setlocal makeprg=perlmake
+You can switch back to using the global value by making the local value empty: >
+	:setlocal makeprg=
+This only works for a string option.  For a boolean option you need to use the
+"<" flag, like this: >
+	:setlocal autoread<
+Note that for non-boolean options using "<" copies the global value to the
+local value, it doesn't switch back to using the global value (that matters
+when the global value changes later).  You can also use: >
+	:set path<
+This will make the local value of 'path' empty, so that the global value is
+used.  Thus it does the same as: >
+	:setlocal path=
+Note: In the future more global options can be made global-local.  Using
+":setlocal" on a global option might work differently then.
+
+
+Setting the filetype
+
+:setf[iletype] {filetype}			*:setf* *:setfiletype*
+			Set the 'filetype' option to {filetype}, but only if
+			not done yet in a sequence of (nested) autocommands.
+			This is short for: >
+				:if !did_filetype()
+				:  setlocal filetype={filetype}
+				:endif
+<			This command is used in a filetype.vim file to avoid
+			setting the 'filetype' option twice, causing different
+			settings and syntax files to be loaded.
+			{not in Vi}
+
+:bro[wse] se[t]			*:set-browse* *:browse-set* *:opt* *:options*
+:opt[ions]		Open a window for viewing and setting all options.
+			Options are grouped by function.
+			Offers short help for each option.  Hit <CR> on the
+			short help to open a help window with more help for
+			the option.
+			Modify the value of the option and hit <CR> on the
+			"set" line to set the new value.  For window and
+			buffer specific options, the last accessed window is
+			used to set the option value in, unless this is a help
+			window, in which case the window below help window is
+			used (skipping the option-window).
+			{not available when compiled without the |+eval| or
+			|+autocmd| features}
+
+								*$HOME*
+Using "~" is like using "$HOME", but it is only recognized at the start of an
+option and after a space or comma.
+
+On Unix systems "~user" can be used too.  It is replaced by the home directory
+of user "user".  Example: >
+    :set path=~mool/include,/usr/include,.
+
+On Unix systems the form "${HOME}" can be used too.  The name between {} can
+contain non-id characters then.  Note that if you want to use this for the
+"gf" command, you need to add the '{' and '}' characters to 'isfname'.
+
+NOTE: expanding environment variables and "~/" is only done with the ":set"
+command, not when assigning a value to an option with ":let".
+
+
+Note the maximum length of an expanded option is limited.  How much depends on
+the system, mostly it is something like 256 or 1024 characters.
+
+							*:fix* *:fixdel*
+:fix[del]		Set the value of 't_kD':
+				't_kb' is     't_kD' becomes	~
+				  CTRL-?	CTRL-H
+				not CTRL-?	CTRL-?
+
+			(CTRL-? is 0177 octal, 0x7f hex) {not in Vi}
+
+			If your delete key terminal code is wrong, but the
+			code for backspace is alright, you can put this in
+			your .vimrc: >
+				:fixdel
+<			This works no matter what the actual code for
+			backspace is.
+
+			If the backspace key terminal code is wrong you can
+			use this: >
+				:if &term == "termname"
+				:  set t_kb=^V<BS>
+				:  fixdel
+				:endif
+<			Where "^V" is CTRL-V and "<BS>" is the backspace key
+			(don't type four characters!).  Replace "termname"
+			with your terminal name.
+
+			If your <Delete> key sends a strange key sequence (not
+			CTRL-? or CTRL-H) you cannot use ":fixdel".  Then use: >
+				:if &term == "termname"
+				:  set t_kD=^V<Delete>
+				:endif
+<			Where "^V" is CTRL-V and "<Delete>" is the delete key
+			(don't type eight characters!).  Replace "termname"
+			with your terminal name.
+
+							*Linux-backspace*
+			Note about Linux: By default the backspace key
+			produces CTRL-?, which is wrong.  You can fix it by
+			putting this line in your rc.local: >
+				echo "keycode 14 = BackSpace" | loadkeys
+<
+							*NetBSD-backspace*
+			Note about NetBSD: If your backspace doesn't produce
+			the right code, try this: >
+				xmodmap -e "keycode 22 = BackSpace"
+<			If this works, add this in your .Xmodmap file: >
+				keysym 22 = BackSpace
+<			You need to restart for this to take effect.
+
+==============================================================================
+2. Automatically setting options			*auto-setting*
+
+Besides changing options with the ":set" command, there are three alternatives
+to set options automatically for one or more files:
+
+1. When starting Vim initializations are read from various places.  See
+   |initialization|.  Most of them are performed for all editing sessions,
+   and some of them depend on the directory where Vim is started.
+   You can create an initialization file with |:mkvimrc|, |:mkview| and
+   |:mksession|.
+2. If you start editing a new file, the automatic commands are executed.
+   This can be used to set options for files matching a particular pattern and
+   many other things.  See |autocommand|.
+3. If you start editing a new file, and the 'modeline' option is on, a
+   number of lines at the beginning and end of the file are checked for
+   modelines.  This is explained here.
+
+					*modeline* *vim:* *vi:* *ex:* *E520*
+There are two forms of modelines.  The first form:
+	[text]{white}{vi:|vim:|ex:}[white]{options}
+
+[text]		any text or empty
+{white}		at least one blank character (<Space> or <Tab>)
+{vi:|vim:|ex:}	the string "vi:", "vim:" or "ex:"
+[white]		optional white space
+{options}	a list of option settings, separated with white space or ':',
+		where each part between ':' is the argument for a ":set"
+		command (can be empty)
+
+Example:
+   vi:noai:sw=3 ts=6 ~
+
+The second form (this is compatible with some versions of Vi):
+
+	[text]{white}{vi:|vim:|ex:}[white]se[t] {options}:[text]
+
+[text]		any text or empty
+{white}		at least one blank character (<Space> or <Tab>)
+{vi:|vim:|ex:}	the string "vi:", "vim:" or "ex:"
+[white]		optional white space
+se[t]		the string "set " or "se " (note the space)
+{options}	a list of options, separated with white space, which is the
+		argument for a ":set" command
+:		a colon
+[text]		any text or empty
+
+Example:
+   /* vim: set ai tw=75: */ ~
+
+The white space before {vi:|vim:|ex:} is required.  This minimizes the chance
+that a normal word like "lex:" is caught.  There is one exception: "vi:" and
+"vim:" can also be at the start of the line (for compatibility with version
+3.0).  Using "ex:" at the start of the line will be ignored (this could be
+short for "example:").
+
+							*modeline-local*
+The options are set like with ":setlocal": The new value only applies to the
+buffer and window that contain the file.  Although it's possible to set global
+options from a modeline, this is unusual.  If you have two windows open and
+the files in it set the same global option to a different value, the result
+depends on which one was opened last.
+
+When editing a file that was already loaded, only the window-local options
+from the modeline are used.  Thus if you manually changed a buffer-local
+option after opening the file, it won't be changed if you edit the same buffer
+in another window.  But window-local options will be set.
+
+							*modeline-version*
+If the modeline is only to be used for some versions of Vim, the version
+number can be specified where "vim:" is used:
+	vim{vers}:	version {vers} or later
+	vim<{vers}:	version before {vers}
+	vim={vers}:	version {vers}
+	vim>{vers}:	version after {vers}
+{vers} is 600 for Vim 6.0 (hundred times the major version plus minor).
+For example, to use a modeline only for Vim 6.0 and later:
+	/* vim600: set foldmethod=marker: */ ~
+To use a modeline for Vim before version 5.7:
+	/* vim<570: set sw=4: */ ~
+There can be no blanks between "vim" and the ":".
+
+
+The number of lines that are checked can be set with the 'modelines' option.
+If 'modeline' is off or 'modelines' is 0 no lines are checked.
+
+Note that for the first form all of the rest of the line is used, thus a line
+like:
+   /* vi:ts=4: */ ~
+will give an error message for the trailing "*/".  This line is OK:
+   /* vi:set ts=4: */ ~
+
+If an error is detected the rest of the line is skipped.
+
+If you want to include a ':' in a set command precede it with a '\'.  The
+backslash in front of the ':' will be removed.  Example:
+   /* vi:set dir=c\:\tmp: */ ~
+This sets the 'dir' option to "c:\tmp".  Only a single backslash before the
+':' is removed.  Thus to include "\:" you have to specify "\\:".
+
+No other commands than "set" are supported, for security reasons (somebody
+might create a Trojan horse text file with modelines).  And not all options
+can be set.  For some options a flag is set, so that when it's used the
+|sandbox| is effective.  Still, there is always a small risk that a modeline
+causes trouble.  E.g., when some joker sets 'textwidth' to 5 all your lines
+are wrapped unexpectedly.  So disable modelines before editing untrusted text.
+The mail ftplugin does this, for example.
+
+Hint: If you would like to do something else than setting an option, you could
+define an autocommand that checks the file for a specific string.  For
+example: >
+	au BufReadPost * if getline(1) =~ "VAR" | call SetVar() | endif
+And define a function SetVar() that does something with the line containing
+"VAR".
+
+==============================================================================
+3. Options summary					*option-summary*
+
+In the list below all the options are mentioned with their full name and with
+an abbreviation if there is one.  Both forms may be used.
+
+In this document when a boolean option is "set" that means that ":set option"
+is entered.  When an option is "reset", ":set nooption" is used.
+
+For some options there are two default values: The "Vim default", which is
+used when 'compatible' is not set, and the "Vi default", which is used when
+'compatible' is set.
+
+Most options are the same in all windows and buffers.  There are a few that
+are specific to how the text is presented in a window.  These can be set to a
+different value in each window.  For example the 'list' option can be set in
+one window and reset in another for the same text, giving both types of view
+at the same time.  There are a few options that are specific to a certain
+file.  These can have a different value for each file or buffer.  For example
+the 'textwidth' option can be 78 for a normal text file and 0 for a C
+program.
+
+	global			one option for all buffers and windows
+	local to window		each window has its own copy of this option
+	local to buffer		each buffer has its own copy of this option
+
+When creating a new window the option values from the currently active window
+are used as a default value for the window-specific options.  For the
+buffer-specific options this depends on the 's' and 'S' flags in the
+'cpoptions' option.  If 's' is included (which is the default) the values for
+buffer options are copied from the currently active buffer when a buffer is
+first entered.  If 'S' is present the options are copied each time the buffer
+is entered, this is almost like having global options.  If 's' and 'S' are not
+present, the options are copied from the currently active buffer when the
+buffer is created.
+
+Hidden options						*hidden-options*
+
+Not all options are supported in all versions.  This depends on the supported
+features and sometimes on the system.  A remark about this is in curly braces
+below.  When an option is not supported it may still be set without getting an
+error, this is called a hidden option.  You can't get the value of a hidden
+option though, it is not stored.
+
+To test if option "foo" can be used with ":set" use something like this: >
+	if exists('&foo')
+This also returns true for a hidden option.  To test if option "foo" is really
+supported use something like this: >
+	if exists('+foo')
+<
+							*E355*
+A jump table for the options with a short description can be found at |Q_op|.
+
+					*'aleph'* *'al'* *aleph* *Aleph*
+'aleph' 'al'		number	(default 128 for MS-DOS, 224 otherwise)
+			global
+			{not in Vi}
+			{only available when compiled with the |+rightleft|
+			feature}
+	The ASCII code for the first letter of the Hebrew alphabet.  The
+	routine that maps the keyboard in Hebrew mode, both in Insert mode
+	(when hkmap is set) and on the command-line (when hitting CTRL-_)
+	outputs the Hebrew characters in the range [aleph..aleph+26].
+	aleph=128 applies to PC code, and aleph=224 applies to ISO 8859-8.
+	See |rileft.txt|.
+
+			*'allowrevins'* *'ari'* *'noallowrevins'* *'noari'*
+'allowrevins' 'ari'	boolean	(default off)
+			global
+			{not in Vi}
+			{only available when compiled with the |+rightleft|
+			feature}
+	Allow CTRL-_ in Insert and Command-line mode.  This is default off, to
+	avoid that users that accidentally type CTRL-_ instead of SHIFT-_ get
+	into reverse Insert mode, and don't know how to get out.  See
+	'revins'.
+	NOTE: This option is reset when 'compatible' is set.
+
+			 *'altkeymap'* *'akm'* *'noaltkeymap'* *'noakm'*
+'altkeymap' 'akm'	boolean (default off)
+			global
+			{not in Vi}
+			{only available when compiled with the |+farsi|
+			feature}
+	When on, the second language is Farsi.  In editing mode CTRL-_ toggles
+	the keyboard map between Farsi and English, when 'allowrevins' set.
+
+	When off, the keyboard map toggles between Hebrew and English.  This
+	is useful to start the Vim in native mode i.e. English (left-to-right
+	mode) and have default second language Farsi or Hebrew (right-to-left
+	mode).  See |farsi.txt|.
+
+						*'ambiwidth'* *'ambw'*
+'ambiwidth' 'ambw'	string (default: "single")
+			global
+			{not in Vi}
+			{only available when compiled with the |+multi_byte|
+			feature}
+	Only effective when 'encoding' is "utf-8" or another Unicode encoding.
+	Tells Vim what to do with characters with East Asian Width Class
+	Ambiguous (such as Euro, Registered Sign, Copyright Sign, Greek
+	letters, Cyrillic letters).
+
+	There are currently two possible values:
+	"single":	Use the same width as characters in US-ASCII.  This is
+			expected by most users.
+	"double":	Use twice the width of ASCII characters.
+
+	There are a number of CJK fonts for which the width of glyphs for
+	those characters are solely based on how many octets they take in
+	legacy/traditional CJK encodings.  In those encodings, Euro,
+	Registered sign, Greek/Cyrillic letters are represented by two octets,
+	therefore those fonts have "wide" glyphs for them.  This is also
+	true of some line drawing characters used to make tables in text
+	file.  Therefore, when a CJK font is used for GUI Vim or
+	Vim is running inside a terminal (emulators) that uses a CJK font
+	(or Vim is run inside an xterm invoked with "-cjkwidth" option.),
+	this option should be set to "double" to match the width perceived
+	by Vim with the width of glyphs in the font.  Perhaps it also has
+	to be set to "double" under CJK Windows 9x/ME or Windows 2k/XP
+	when the system locale is set to one of CJK locales.  See Unicode
+	Standard Annex #11 (http://www.unicode.org/reports/tr11).
+
+			*'antialias'* *'anti'* *'noantialias'* *'noanti'*
+'antialias' 'anti'	boolean (default: off)
+			global
+			{not in Vi}
+			{only available when compiled with GUI enabled
+			on Mac OS X}
+	This option only has an effect in the GUI version of Vim on Mac OS X
+	v10.2 or later.  When on, Vim will use smooth ("antialiased") fonts,
+	which can be easier to read at certain sizes on certain displays.
+	Setting this option can sometimes cause problems if 'guifont' is set
+	to its default (empty string).
+
+			*'autochdir'* *'acd'* *'noautochdir'* *'noacd'*
+'autochdir' 'acd'	boolean (default off)
+			global
+			{not in Vi}
+			{only available when compiled with the
+			|+netbeans_intg| or |+sun_workshop| feature}
+	When on, Vim will change the current working directory whenever you
+	open a file, switch buffers, delete a buffer or open/close a window.
+	It will change to the directory containing the file which was opened
+	or selected.
+	This option is provided for backward compatibility with the Vim
+	released with Sun ONE Studio 4 Enterprise Edition.
+	Note: When this option is on some plugins may not work.
+
+				*'arabic'* *'arab'* *'noarabic'* *'noarab'*
+'arabic' 'arab'		boolean (default off)
+			local to window
+			{not in Vi}
+			{only available when compiled with the |+arabic|
+			feature}
+	This option can be set to start editing Arabic text.
+	Setting this option will:
+	- Set the 'rightleft' option, unless 'termbidi' is set.
+	- Set the 'arabicshape' option, unless 'termbidi' is set.
+	- Set the 'keymap' option to "arabic"; in Insert mode CTRL-^ toggles
+	  between typing English and Arabic key mapping.
+	- Set the 'delcombine' option
+	Note that 'encoding' must be "utf-8" for working with Arabic text.
+
+	Resetting this option will:
+	- Reset the 'rightleft' option.
+	- Disable the use of 'keymap' (without changing its value).
+	Note that 'arabicshape' and 'delcombine' are not reset (it is a global
+	option.
+	Also see |arabic.txt|.
+
+					*'arabicshape'* *'arshape'*
+					*'noarabicshape'* *'noarshape'*
+'arabicshape' 'arshape'	boolean (default on)
+			global
+			{not in Vi}
+			{only available when compiled with the |+arabic|
+			feature}
+	When on and 'termbidi' is off, the required visual character
+	corrections that need to take place for displaying the Arabic language
+	take affect.  Shaping, in essence, gets enabled; the term is a broad
+	one which encompasses:
+	  a) the changing/morphing of characters based on their location
+	     within a word (initial, medial, final and stand-alone).
+	  b) the enabling of the ability to compose characters
+	  c) the enabling of the required combining of some characters
+	When disabled the character display reverts back to each character's
+	true stand-alone form.
+	Arabic is a complex language which requires other settings, for
+	further details see |arabic.txt|.
+
+			*'autoindent'* *'ai'* *'noautoindent'* *'noai'*
+'autoindent' 'ai'	boolean	(default off)
+			local to buffer
+	Copy indent from current line when starting a new line (typing <CR>
+	in Insert mode or when using the "o" or "O" command).  If you do not
+	type anything on the new line except <BS> or CTRL-D and then type
+	<Esc>, CTRL-O or <CR>, the indent is deleted again.  Moving the cursor
+	to another line has the same effect, unless the 'I' flag is included
+	in 'cpoptions'.
+	When autoindent is on, formatting (with the "gq" command or when you
+	reach 'textwidth' in Insert mode) uses the indentation of the first
+	line.
+	When 'smartindent' or 'cindent' is on the indent is changed in
+	a different way.
+	The 'autoindent' option is reset when the 'paste' option is set.
+	{small difference from Vi: After the indent is deleted when typing
+	<Esc> or <CR>, the cursor position when moving up or down is after the
+	deleted indent; Vi puts the cursor somewhere in the deleted indent}.
+
+				 *'autoread'* *'ar'* *'noautoread'* *'noar'*
+'autoread' 'ar'		boolean	(default off)
+			global or local to buffer |global-local|
+			{not in Vi}
+	When a file has been detected to have been changed outside of Vim and
+	it has not been changed inside of Vim, automatically read it again.
+	When the file has been deleted this is not done.  |timestamp|
+	If this option has a local value, use this command to switch back to
+	using the global value: >
+		:set autoread<
+<
+				 *'autowrite'* *'aw'* *'noautowrite'* *'noaw'*
+'autowrite' 'aw'	boolean	(default off)
+			global
+	Write the contents of the file, if it has been modified, on each
+	:next, :rewind, :last, :first, :previous, :stop, :suspend, :tag, :!,
+	:make, CTRL-] and CTRL-^ command; and when a :buffer, CTRL-O, CTRL-I,
+	'{A-Z0-9}, or `{A-Z0-9} command takes one to another file.
+	Note that for some commands the 'autowrite' option is not used, see
+	'autowriteall' for that.
+
+			 *'autowriteall'* *'awa'* *'noautowriteall'* *'noawa'*
+'autowriteall' 'awa'	boolean	(default off)
+			global
+			{not in Vi}
+	Like 'autowrite', but also used for commands ":edit", ":enew", ":quit",
+	":qall", ":exit", ":xit", ":recover" and closing the Vim window.
+	Setting this option also implies that Vim behaves like 'autowrite' has
+	been set.
+
+							*'background'* *'bg'*
+'background' 'bg'	string	(default "dark" or "light")
+			global
+			{not in Vi}
+	When set to "dark", Vim will try to use colors that look good on a
+	dark background.  When set to "light", Vim will try to use colors that
+	look good on a light background.  Any other value is illegal.
+	Vim tries to set the default value according to the terminal used.
+	This will not always be correct.
+	Setting this option does not change the background color, it tells Vim
+	what the background color looks like.  For changing the background
+	color, see |:hi-normal|.
+
+	When 'background' is set Vim will adjust the default color groups for
+	the new value.  But the colors used for syntax highlighting will not
+	change.
+	When a color scheme is loaded (the "colors_name" variable is set)
+	setting 'background' will cause the color scheme to be reloaded.  If
+	the color scheme adjusts to the value of 'background' this will work.
+	However, if the color scheme sets 'background' itself the effect may
+	be undone.  First delete the "colors_name" variable when needed.
+
+	When setting 'background' to the default value with: >
+		:set background&
+<	Vim will guess the value.  In the GUI this should work correctly,
+	in other cases Vim might not be able to guess the right value.
+
+	When starting the GUI, the default value for 'background' will be
+	"light".  When the value is not set in the .gvimrc, and Vim detects
+	that the background is actually quite dark, 'background' is set to
+	"dark".  But this happens only AFTER the .gvimrc file has been read
+	(because the window needs to be opened to find the actual background
+	color).  To get around this, force the GUI window to be opened by
+	putting a ":gui" command in the .gvimrc file, before where the value
+	of 'background' is used (e.g., before ":syntax on").
+	Normally this option would be set in the .vimrc file.  Possibly
+	depending on the terminal name.  Example: >
+		:if &term == "pcterm"
+		:  set background=dark
+		:endif
+<	When this option is set, the default settings for the highlight groups
+	will change.  To use other settings, place ":highlight" commands AFTER
+	the setting of the 'background' option.
+	This option is also used in the "$VIMRUNTIME/syntax/syntax.vim" file
+	to select the colors for syntax highlighting.  After changing this
+	option, you must load syntax.vim again to see the result.  This can be
+	done with ":syntax on".
+
+							*'backspace'* *'bs'*
+'backspace' 'bs'	string	(default "")
+			global
+			{not in Vi}
+	Influences the working of <BS>, <Del>, CTRL-W and CTRL-U in Insert
+	mode.  This is a list of items, separated by commas.  Each item allows
+	a way to backspace over something:
+	value	effect	~
+	indent	allow backspacing over autoindent
+	eol	allow backspacing over line breaks (join lines)
+	start	allow backspacing over the start of insert; CTRL-W and CTRL-U
+		stop once at the start of insert.
+
+	When the value is empty, Vi compatible backspacing is used.
+
+	For backwards compatibility with version 5.4 and earlier:
+	value	effect	~
+	  0	same as ":set backspace=" (Vi compatible)
+	  1	same as ":set backspace=indent,eol"
+	  2	same as ":set backspace=indent,eol,start"
+
+	See |:fixdel| if your <BS> or <Del> key does not do what you want.
+	NOTE: This option is set to "" when 'compatible' is set.
+
+				*'backup'* *'bk'* *'nobackup'* *'nobk'*
+'backup' 'bk'		boolean	(default off)
+			global
+			{not in Vi}
+	Make a backup before overwriting a file.  Leave it around after the
+	file has been successfully written.  If you do not want to keep the
+	backup file, but you do want a backup while the file is being
+	written, reset this option and set the 'writebackup' option (this is
+	the default).  If you do not want a backup file at all reset both
+	options (use this if your file system is almost full).  See the
+	|backup-table| for more explanations.
+	When the 'backupskip' pattern matches, a backup is not made anyway.
+	When 'patchmode' is set, the backup may be renamed to become the
+	oldest version of a file.
+	NOTE: This option is reset when 'compatible' is set.
+
+						*'backupcopy'* *'bkc'*
+'backupcopy' 'bkc'	string	(Vi default for Unix: "yes", otherwise: "auto")
+			global
+			{not in Vi}
+	When writing a file and a backup is made, this option tells how it's
+	done.  This is a comma separated list of words.
+
+	The main values are:
+	"yes"	make a copy of the file and overwrite the original one
+	"no"	rename the file and write a new one
+	"auto"	one of the previous, what works best
+
+	Extra values that can be combined with the ones above are:
+	"breaksymlink"	always break symlinks when writing
+	"breakhardlink"	always break hardlinks when writing
+
+	Making a copy and overwriting the original file:
+	- Takes extra time to copy the file.
+	+ When the file has special attributes, is a (hard/symbolic) link or
+	  has a resource fork, all this is preserved.
+	- When the file is a link the backup will have the name of the link,
+	  not of the real file.
+
+	Renaming the file and writing a new one:
+	+ It's fast.
+	- Sometimes not all attributes of the file can be copied to the new
+	  file.
+	- When the file is a link the new file will not be a link.
+
+	The "auto" value is the middle way: When Vim sees that renaming file
+	is possible without side effects (the attributes can be passed on and
+	the file is not a link) that is used.  When problems are expected, a
+	copy will be made.
+
+	The "breaksymlink" and "breakhardlink" values can be used in
+	combination with any of "yes", "no" and "auto".  When included, they
+	force Vim to always break either symbolic or hard links by doing
+	exactly what the "no" option does, renaming the original file to
+	become the backup and writing a new file in its place.  This can be
+	useful for example in source trees where all the files are symbolic or
+	hard links and any changes should stay in the local source tree, not
+	be propagated back to the original source.
+							*crontab*
+	One situation where "no" and "auto" will cause problems: A program
+	that opens a file, invokes Vim to edit that file, and then tests if
+	the open file was changed (through the file descriptor) will check the
+	backup file instead of the newly created file.  "crontab -e" is an
+	example.
+
+	When a copy is made, the original file is truncated and then filled
+	with the new text.  This means that protection bits, owner and
+	symbolic links of the original file are unmodified.  The backup file
+	however, is a new file, owned by the user who edited the file.  The
+	group of the backup is set to the group of the original file.  If this
+	fails, the protection bits for the group are made the same as for
+	others.
+
+	When the file is renamed this is the other way around: The backup has
+	the same attributes of the original file, and the newly written file
+	is owned by the current user.  When the file was a (hard/symbolic)
+	link, the new file will not!  That's why the "auto" value doesn't
+	rename when the file is a link.  The owner and group of the newly
+	written file will be set to the same ones as the original file, but
+	the system may refuse to do this.  In that case the "auto" value will
+	again not rename the file.
+
+						*'backupdir'* *'bdir'*
+'backupdir' 'bdir'	string	(default for Amiga: ".,t:",
+				 for MS-DOS and Win32: ".,c:/tmp,c:/temp"
+				 for Unix: ".,~/tmp,~/")
+			global
+			{not in Vi}
+	List of directories for the backup file, separated with commas.
+	- The backup file will be created in the first directory in the list
+	  where this is possible.
+	- Empty means that no backup file will be created ('patchmode' is
+	  impossible!).  Writing may fail because of this.
+	- A directory "." means to put the backup file in the same directory
+	  as the edited file.
+	- A directory starting with "./" (or ".\" for MS-DOS et al.) means to
+	  put the backup file relative to where the edited file is.  The
+	  leading "." is replaced with the path name of the edited file.
+	  ("." inside a directory name has no special meaning).
+	- Spaces after the comma are ignored, other spaces are considered part
+	  of the directory name.  To have a space at the start of a directory
+	  name, precede it with a backslash.
+	- To include a comma in a directory name precede it with a backslash.
+	- A directory name may end in an '/'.
+	- Environment variables are expanded |:set_env|.
+	- Careful with '\' characters, type one before a space, type two to
+	  get one in the option (see |option-backslash|), for example: >
+	    :set bdir=c:\\tmp,\ dir\\,with\\,commas,\\\ dir\ with\ spaces
+<	- For backwards compatibility with Vim version 3.0 a '>' at the start
+	  of the option is removed.
+	See also 'backup' and 'writebackup' options.
+	If you want to hide your backup files on Unix, consider this value: >
+		:set backupdir=./.backup,~/.backup,.,/tmp
+<	You must create a ".backup" directory in each directory and in your
+	home directory for this to work properly.
+	The use of |:set+=| and |:set-=| is preferred when adding or removing
+	directories from the list.  This avoids problems when a future version
+	uses another default.
+	This option cannot be set from a |modeline| or in the |sandbox|, for
+	security reasons.
+
+						*'backupext'* *'bex'* *E589*
+'backupext' 'bex'	string	(default "~", for VMS: "_")
+			global
+			{not in Vi}
+	String which is appended to a file name to make the name of the
+	backup file.  The default is quite unusual, because this avoids
+	accidentally overwriting existing files with a backup file.  You might
+	prefer using ".bak", but make sure that you don't have files with
+	".bak" that you want to keep.
+	Only normal file name characters can be used, "/\*?[|<>" are illegal.
+
+	If you like to keep a lot of backups, you could use a BufWritePre
+	autocommand to change 'backupext' just before writing the file to
+	include a timestamp. >
+		:au BufWritePre * let &bex = '-' . strftime("%Y%b%d%X") . '~'
+<	Use 'backupdir' to put the backup in a different directory.
+
+						*'backupskip'* *'bsk'*
+'backupskip' 'bsk'	string	(default: "/tmp/*,$TMPDIR/*,$TMP/*,$TEMP/*")
+			global
+			{not in Vi}
+			{not available when compiled without the |+wildignore|
+			feature}
+	A list of file patterns.  When one of the patterns matches with the
+	name of the file which is written, no backup file is created.  Both
+	the specified file name and the full path name of the file are used.
+	The pattern is used like with |:autocmd|, see |autocmd-patterns|.
+	Watch out for special characters, see |option-backslash|.
+	When $TMPDIR, $TMP or $TEMP is not defined, it is not used for the
+	default value.  "/tmp/*" is only used for Unix.
+
+	Note that environment variables are not expanded.  If you want to use
+	$HOME you must expand it explicitly, e.g.: >
+		:let backupskip = escape(expand('$HOME'), '\') . '/tmp/*'
+
+<	Note that the default also makes sure that "crontab -e" works (when a
+	backup would be made by renaming the original file crontab won't see
+	the newly created file).  Also see 'backupcopy' and |crontab|.
+
+						*'balloondelay'* *'bdlay'*
+'balloondelay' 'bdlay'	number	(default: 600)
+			global
+			{not in Vi}
+			{only available when compiled with the |+balloon_eval|
+			feature}
+	Delay in milliseconds before a balloon may pop up.  See |balloon-eval|.
+
+		       *'ballooneval'* *'beval'* *'noballooneval'* *'nobeval'*
+'ballooneval' 'beval'	boolean	(default off)
+			global
+			{not in Vi}
+			{only available when compiled with the |+balloon_eval|
+			feature}
+	Switch on the |balloon-eval| functionality.
+
+						     *'balloonexpr'* *'bexpr'*
+'balloonexpr' 'bexpr'	string	(default "")
+			global or local to buffer |global-local|
+			{not in Vi}
+			{only available when compiled with the |+balloon_eval|
+			feature}
+	Expression for text to show in evaluation balloon.  It is only used
+	when 'ballooneval' is on.  These variables can be used:
+
+	v:beval_bufnr	number of the buffer in which balloon is going to show
+	v:beval_winnr	number of the window
+	v:beval_lnum	line number
+	v:beval_col	column number (byte index)
+	v:beval_text	word under or after the mouse pointer
+
+	The evaluation of the expression must not have side effects!
+	Example: >
+    function! MyBalloonExpr()
+	return 'Cursor is at line ' . v:beval_lnum .
+		\', column ' . v:beval_col .
+		\ ' of file ' .  bufname(v:beval_bufnr) .
+		\ ' on word "' . v:beval_text . '"'
+    endfunction
+    set bexpr=MyBalloonExpr()
+    set ballooneval
+<
+	NOTE: The balloon is displayed only if the cursor is on a text
+	character.  If the result of evaluating 'balloonexpr' is not empty,
+	Vim does not try to send a message to an external debugger (Netbeans
+	or Sun Workshop).
+
+	The expression may be evaluated in the |sandbox|, see
+	|sandbox-option|.
+
+	It is not allowed to change text or jump to another window while
+	evaluating 'balloonexpr' |textlock|.
+
+	To check whether line breaks in the balloon text work use this check: >
+		if has("balloon_multiline")
+<	When they are supported "\n" characters will start a new line.  If the
+	expression evaluates to a |List| this is equal to using each List item
+	as a string and putting "\n" in between them.
+
+				     *'binary'* *'bin'* *'nobinary'* *'nobin'*
+'binary' 'bin'		boolean	(default off)
+			local to buffer
+			{not in Vi}
+	This option should be set before editing a binary file.  You can also
+	use the |-b| Vim argument.  When this option is switched on a few
+	options will be changed (also when it already was on):
+		'textwidth'  will be set to 0
+		'wrapmargin' will be set to 0
+		'modeline'   will be off
+		'expandtab'  will be off
+	Also, 'fileformat' and 'fileformats' options will not be used, the
+	file is read and written like 'fileformat' was "unix" (a single <NL>
+	separates lines).
+	The 'fileencoding' and 'fileencodings' options will not be used, the
+	file is read without conversion.
+	NOTE: When you start editing a(nother) file while the 'bin' option is
+	on, settings from autocommands may change the settings again (e.g.,
+	'textwidth'), causing trouble when editing.  You might want to set
+	'bin' again when the file has been loaded.
+	The previous values of these options are remembered and restored when
+	'bin' is switched from on to off.  Each buffer has its own set of
+	saved option values.
+	To edit a file with 'binary' set you can use the |++bin| argument.
+	This avoids you have to do ":set bin", which would have effect for all
+	files you edit.
+	When writing a file the <EOL> for the last line is only written if
+	there was one in the original file (normally Vim appends an <EOL> to
+	the last line if there is none; this would make the file longer).  See
+	the 'endofline' option.
+
+			*'bioskey'* *'biosk'* *'nobioskey'* *'nobiosk'*
+'bioskey' 'biosk'	boolean	(default on)
+			global
+			{not in Vi}  {only for MS-DOS}
+	When on the BIOS is called to obtain a keyboard character.  This works
+	better to detect CTRL-C, but only works for the console.  When using a
+	terminal over a serial port reset this option.
+	Also see |'conskey'|.
+
+							*'bomb'* *'nobomb'*
+'bomb'			boolean	(default off)
+			local to buffer
+			{not in Vi}
+			{only available when compiled with the |+multi_byte|
+			feature}
+	When writing a file and the following conditions are met, a BOM (Byte
+	Order Mark) is prepended to the file:
+	- this option is on
+	- the 'binary' option is off
+	- 'fileencoding' is "utf-8", "ucs-2", "ucs-4" or one of the little/big
+	  endian variants.
+	Some applications use the BOM to recognize the encoding of the file.
+	Often used for UCS-2 files on MS-Windows.  For other applications it
+	causes trouble, for example: "cat file1 file2" makes the BOM of file2
+	appear halfway the resulting file.
+	When Vim reads a file and 'fileencodings' starts with "ucs-bom", a
+	check for the presence of the BOM is done and 'bomb' set accordingly.
+	Unless 'binary' is set, it is removed from the first line, so that you
+	don't see it when editing.  When you don't change the options, the BOM
+	will be restored when writing the file.
+
+						*'breakat'* *'brk'*
+'breakat' 'brk'		string	(default " ^I!@*-+;:,./?")
+			global
+			{not in Vi}
+			{not available when compiled without the  |+linebreak|
+			feature}
+	This option lets you choose which characters might cause a line
+	break if 'linebreak' is on.  Only works for ASCII and also for 8-bit
+	characters when 'encoding' is an 8-bit encoding.
+
+						*'browsedir'* *'bsdir'*
+'browsedir' 'bsdir'	string	(default: "last")
+			global
+			{not in Vi} {only for Motif and Win32 GUI}
+	Which directory to use for the file browser:
+	   last		Use same directory as with last file browser.
+	   buffer	Use the directory of the related buffer.
+	   current	Use the current directory.
+	   {path}	Use the specified directory
+
+						*'bufhidden'* *'bh'*
+'bufhidden' 'bh'	string (default: "")
+			local to buffer
+			{not in Vi}
+			{not available when compiled without the |+quickfix|
+			feature}
+	This option specifies what happens when a buffer is no longer
+	displayed in a window:
+	  <empty>	follow the global 'hidden' option
+	  hide		hide the buffer (don't unload it), also when 'hidden'
+			is not set
+	  unload	unload the buffer, also when 'hidden' is set or using
+			|:hide|
+	  delete	delete the buffer from the buffer list, also when
+			'hidden' is set or using |:hide|, like using
+			|:bdelete|
+	  wipe		wipe out the buffer from the buffer list, also when
+			'hidden' is set or using |:hide|, like using
+			|:bwipeout|
+
+	CAREFUL: when "unload", "delete" or "wipe" is used changes in a buffer
+	are lost without a warning.
+	This option is used together with 'buftype' and 'swapfile' to specify
+	special kinds of buffers.   See |special-buffers|.
+
+			*'buflisted'* *'bl'* *'nobuflisted'* *'nobl'* *E85*
+'buflisted' 'bl'	boolean (default: on)
+			local to buffer
+			{not in Vi}
+	When this option is set, the buffer shows up in the buffer list.  If
+	it is reset it is not used for ":bnext", "ls", the Buffers menu, etc.
+	This option is reset by Vim for buffers that are only used to remember
+	a file name or marks.  Vim sets it when starting to edit a buffer.
+	But not when moving to a buffer with ":buffer".
+
+						*'buftype'* *'bt'* *E382*
+'buftype' 'bt'		string (default: "")
+			local to buffer
+			{not in Vi}
+			{not available when compiled without the |+quickfix|
+			feature}
+	The value of this option specifies the type of a buffer:
+	  <empty>	normal buffer
+	  nofile	buffer which is not related to a file and will not be
+			written
+	  nowrite	buffer which will not be written
+	  acwrite	buffer which will always be written with BufWriteCmd
+			autocommands. {not available when compiled without the
+			|+autocmd| feature}
+	  quickfix	quickfix buffer, contains list of errors |:cwindow|
+			or list of locations |:lwindow|
+	  help		help buffer (you are not supposed to set this
+			manually)
+
+	This option is used together with 'bufhidden' and 'swapfile' to
+	specify special kinds of buffers.   See |special-buffers|.
+
+	Be careful with changing this option, it can have many side effects!
+
+	A "quickfix" buffer is only used for the error list and the location
+	list.  This value is set by the |:cwindow| and |:lwindow| commands and
+	you are not supposed to change it.
+
+	"nofile" and "nowrite" buffers are similar:
+	both:		The buffer is not to be written to disk, ":w" doesn't
+			work (":w filename" does work though).
+	both:		The buffer is never considered to be |'modified'|.
+			There is no warning when the changes will be lost, for
+			example when you quit Vim.
+	both:		A swap file is only created when using too much memory
+			(when 'swapfile' has been reset there is never a swap
+			file).
+	nofile only:	The buffer name is fixed, it is not handled like a
+			file name.  It is not modified in response to a |:cd|
+			command.
+							*E676*
+	"acwrite" implies that the buffer name is not related to a file, like
+	"nofile", but it will be written.  Thus, in contrast to "nofile" and
+	"nowrite", ":w" does work and a modified buffer can't be abandoned
+	without saving.  For writing there must be matching |BufWriteCmd|,
+	|FileWriteCmd| or |FileAppendCmd| autocommands.
+
+						*'casemap'* *'cmp'*
+'casemap' 'cmp'		string	(default: "internal,keepascii")
+			global
+			{not in Vi}
+			{only available when compiled with the |+multi_byte|
+			feature}
+	Specifies details about changing the case of letters.  It may contain
+	these words, separated by a comma:
+	internal	Use internal case mapping functions, the current
+			locale does not change the case mapping.  This only
+			matters when 'encoding' is a Unicode encoding,
+			"latin1" or "iso-8859-15".  When "internal" is
+			omitted, the towupper() and towlower() system library
+			functions are used when available.
+	keepascii	For the ASCII characters (0x00 to 0x7f) use the US
+			case mapping, the current locale is not effective.
+			This probably only matters for Turkish.
+
+						*'cdpath'* *'cd'* *E344* *E346*
+'cdpath' 'cd'		string	(default: equivalent to $CDPATH or ",,")
+			global
+			{not in Vi}
+			{not available when compiled without the
+			|+file_in_path| feature}
+	This is a list of directories which will be searched when using the
+	|:cd| and |:lcd| commands, provided that the directory being searched
+	for has a relative path (not starting with "/", "./" or "../").
+	The 'cdpath' option's value has the same form and semantics as
+	|'path'|.  Also see |file-searching|.
+	The default value is taken from $CDPATH, with a "," prepended to look
+	in the current directory first.
+	If the default value taken from $CDPATH is not what you want, include
+	a modified version of the following command in your vimrc file to
+	override it: >
+	  :let &cdpath = ',' . substitute(substitute($CDPATH, '[, ]', '\\\0', 'g'), ':', ',', 'g')
+<	This option cannot be set from a |modeline| or in the |sandbox|, for
+	security reasons.
+	(parts of 'cdpath' can be passed to the shell to expand file names).
+
+						*'cedit'*
+'cedit'			string	(Vi default: "", Vim default: CTRL-F)
+			global
+			{not in Vi}
+			{not available when compiled without the |+vertsplit|
+			feature}
+	The key used in Command-line Mode to open the command-line window.
+	The default is CTRL-F when 'compatible' is off.
+	Only non-printable keys are allowed.
+	The key can be specified as a single character, but it is difficult to
+	type.  The preferred way is to use the <> notation.  Examples: >
+		:set cedit=<C-Y>
+		:set cedit=<Esc>
+<	|Nvi| also has this option, but it only uses the first character.
+	See |cmdwin|.
+
+				*'charconvert'* *'ccv'* *E202* *E214* *E513*
+'charconvert' 'ccv'	string (default "")
+			global
+			{only available when compiled with the |+multi_byte|
+			feature and the |+eval| feature}
+			{not in Vi}
+	An expression that is used for character encoding conversion.  It is
+	evaluated when a file that is to be read or has been written has a
+	different encoding from what is desired.
+	'charconvert' is not used when the internal iconv() function is
+	supported and is able to do the conversion.  Using iconv() is
+	preferred, because it is much faster.
+	'charconvert' is not used when reading stdin |--|, because there is no
+	file to convert from.  You will have to save the text in a file first.
+	The expression must return zero or an empty string for success,
+	non-zero for failure.
+	The possible encoding names encountered are in 'encoding'.
+	Additionally, names given in 'fileencodings' and 'fileencoding' are
+	used.
+	Conversion between "latin1", "unicode", "ucs-2", "ucs-4" and "utf-8"
+	is done internally by Vim, 'charconvert' is not used for this.
+	'charconvert' is also used to convert the viminfo file, if the 'c'
+	flag is present in 'viminfo'.  Also used for Unicode conversion.
+	Example: >
+		set charconvert=CharConvert()
+		fun CharConvert()
+		  system("recode "
+			\ . v:charconvert_from . ".." . v:charconvert_to
+			\ . " <" . v:fname_in . " >" v:fname_out)
+		  return v:shell_error
+		endfun
+<	The related Vim variables are:
+		v:charconvert_from	name of the current encoding
+		v:charconvert_to	name of the desired encoding
+		v:fname_in		name of the input file
+		v:fname_out		name of the output file
+	Note that v:fname_in and v:fname_out will never be the same.
+	Note that v:charconvert_from and v:charconvert_to may be different
+	from 'encoding'.  Vim internally uses UTF-8 instead of UCS-2 or UCS-4.
+	Encryption is not done by Vim when using 'charconvert'.  If you want
+	to encrypt the file after conversion, 'charconvert' should take care
+	of this.
+	This option cannot be set from a |modeline| or in the |sandbox|, for
+	security reasons.
+
+				   *'cindent'* *'cin'* *'nocindent'* *'nocin'*
+'cindent' 'cin'		boolean	(default off)
+			local to buffer
+			{not in Vi}
+			{not available when compiled without the |+cindent|
+			feature}
+	Enables automatic C program indenting  See 'cinkeys' to set the keys
+	that trigger reindenting in insert mode and 'cinoptions' to set your
+	preferred indent style.
+	If 'indentexpr' is not empty, it overrules 'cindent'.
+	If 'lisp' is not on and both 'indentexpr' and 'equalprg' are empty,
+	the "=" operator indents using this algorithm rather than calling an
+	external program.
+	See |C-indenting|.
+	When you don't like the way 'cindent' works, try the 'smartindent'
+	option or 'indentexpr'.
+	This option is not used when 'paste' is set.
+	NOTE: This option is reset when 'compatible' is set.
+
+							*'cinkeys'* *'cink'*
+'cinkeys' 'cink'	string	(default "0{,0},0),:,0#,!^F,o,O,e")
+			local to buffer
+			{not in Vi}
+			{not available when compiled without the |+cindent|
+			feature}
+	A list of keys that, when typed in Insert mode, cause reindenting of
+	the current line.  Only used if 'cindent' is on and 'indentexpr' is
+	empty.
+	For the format of this option see |cinkeys-format|.
+	See |C-indenting|.
+
+						*'cinoptions'* *'cino'*
+'cinoptions' 'cino'	string	(default "")
+			local to buffer
+			{not in Vi}
+			{not available when compiled without the |+cindent|
+			feature}
+	The 'cinoptions' affect the way 'cindent' reindents lines in a C
+	program.  See |cinoptions-values| for the values of this option, and
+	|C-indenting| for info on C indenting in general.
+
+
+						*'cinwords'* *'cinw'*
+'cinwords' 'cinw'	string	(default "if,else,while,do,for,switch")
+			local to buffer
+			{not in Vi}
+			{not available when compiled without both the
+			|+cindent| and the |+smartindent| features}
+	These keywords start an extra indent in the next line when
+	'smartindent' or 'cindent' is set.  For 'cindent' this is only done at
+	an appropriate place (inside {}).
+	Note that 'ignorecase' isn't used for 'cinwords'.  If case doesn't
+	matter, include the keyword both the uppercase and lowercase:
+	"if,If,IF".
+
+						*'clipboard'* *'cb'*
+'clipboard' 'cb'	string	(default "autoselect,exclude:cons\|linux"
+						  for X-windows, "" otherwise)
+			global
+			{not in Vi}
+			{only in GUI versions or when the |+xterm_clipboard|
+			feature is included}
+	This option is a list of comma separated names.
+	These names are recognized:
+
+	unnamed		When included, Vim will use the clipboard register '*'
+			for all yank, delete, change and put operations which
+			would normally go to the unnamed register.  When a
+			register is explicitly specified, it will always be
+			used regardless of whether "unnamed" is in 'clipboard'
+			or not.  The clipboard register can always be
+			explicitly accessed using the "* notation.  Also see
+			|gui-clipboard|.
+
+	autoselect	Works like the 'a' flag in 'guioptions': If present,
+			then whenever Visual mode is started, or the Visual
+			area extended, Vim tries to become the owner of the
+			windowing system's global selection or put the
+			selected text on the clipboard used by the selection
+			register "*.  See |guioptions_a| and |quotestar| for
+			details.  When the GUI is active, the 'a' flag in
+			'guioptions' is used, when the GUI is not active, this
+			"autoselect" flag is used.
+			Also applies to the modeless selection.
+
+	autoselectml	Like "autoselect", but for the modeless selection
+			only.  Compare to the 'A' flag in 'guioptions'.
+
+	exclude:{pattern}
+			Defines a pattern that is matched against the name of
+			the terminal 'term'.  If there is a match, no
+			connection will be made to the X server.  This is
+			useful in this situation:
+			- Running Vim in a console.
+			- $DISPLAY is set to start applications on another
+			  display.
+			- You do not want to connect to the X server in the
+			  console, but do want this in a terminal emulator.
+			To never connect to the X server use: >
+				exclude:.*
+<			This has the same effect as using the |-X| argument.
+			Note that when there is no connection to the X server
+			the window title won't be restored and the clipboard
+			cannot be accessed.
+			The value of 'magic' is ignored, {pattern} is
+			interpreted as if 'magic' was on.
+			The rest of the option value will be used for
+			{pattern}, this must be the last entry.
+
+						*'cmdheight'* *'ch'*
+'cmdheight' 'ch'	number	(default 1)
+			global
+			{not in Vi}
+	Number of screen lines to use for the command-line.  Helps avoiding
+	|hit-enter| prompts.
+	The value of this option is stored with the tab page, so that each tab
+	page can have a different value.
+
+						*'cmdwinheight'* *'cwh'*
+'cmdwinheight' 'cwh'	number	(default 7)
+			global
+			{not in Vi}
+			{not available when compiled without the |+vertsplit|
+			feature}
+	Number of screen lines to use for the command-line window. |cmdwin|
+
+						*'columns'* *'co'* *E594*
+'columns' 'co'		number	(default 80 or terminal width)
+			global
+			{not in Vi}
+	Number of columns of the screen.  Normally this is set by the terminal
+	initialization and does not have to be set by hand.  Also see
+	|posix-screen-size|.
+	When Vim is running in the GUI or in a resizable window, setting this
+	option will cause the window size to be changed.  When you only want
+	to use the size for the GUI, put the command in your |gvimrc| file.
+	When you set this option and Vim is unable to change the physical
+	number of columns of the display, the display may be messed up.  For
+	the GUI it is always possible and Vim limits the number of columns to
+	what fits on the screen.  You can use this command to get the widest
+	window possible: >
+		:set columns=9999
+<	Minimum value is 12, maximum value is 10000.
+
+					*'comments'* *'com'* *E524* *E525*
+'comments' 'com'	string	(default
+				"s1:/*,mb:*,ex:*/,://,b:#,:%,:XCOMM,n:>,fb:-")
+			local to buffer
+			{not in Vi}
+			{not available when compiled without the |+comments|
+			feature}
+	A comma separated list of strings that can start a comment line.  See
+	|format-comments|.  See |option-backslash| about using backslashes to
+	insert a space.
+
+					*'commentstring'* *'cms'* *E537*
+'commentstring' 'cms'	string	(default "/*%s*/")
+			local to buffer
+			{not in Vi}
+			{not available when compiled without the |+folding|
+			feature}
+	A template for a comment.  The "%s" in the value is replaced with the
+	comment text.  Currently only used to add markers for folding, see
+	|fold-marker|.
+
+			*'compatible'* *'cp'* *'nocompatible'* *'nocp'*
+'compatible' 'cp'	boolean	(default on, off when a |vimrc| or |gvimrc|
+								file is found)
+			global
+			{not in Vi}
+	This option has the effect of making Vim either more Vi-compatible, or
+	make Vim behave in a more useful way.
+	This is a special kind of option, because when it's set or reset,
+	other options are also changed as a side effect.  CAREFUL: Setting or
+	resetting this option can have a lot of unexpected effects: Mappings
+	are interpreted in another way, undo behaves differently, etc.  If you
+	set this option in your vimrc file, you should probably put it at the
+	very start.
+	By default this option is on and the Vi defaults are used for the
+	options.  This default was chosen for those people who want to use Vim
+	just like Vi, and don't even (want to) know about the 'compatible'
+	option.
+	When a |vimrc| or |gvimrc| file is found while Vim is starting up,
+	this option is switched off, and all options that have not been
+	modified will be set to the Vim defaults.  Effectively, this means
+	that when a |vimrc| or |gvimrc| file exists, Vim will use the Vim
+	defaults, otherwise it will use the Vi defaults.  (Note: This doesn't
+	happen for the system-wide vimrc or gvimrc file, nor for a file given
+	with the |-u| argument).  Also see |compatible-default| and
+	|posix-compliance|.
+	You can also set this option with the "-C" argument, and reset it with
+	"-N".  See |-C| and |-N|.
+	Switching this option off makes the Vim defaults be used for options
+	that have a different Vi and Vim default value.  See the options
+	marked with a '+' below.  Other options are not modified.
+	At the moment this option is set, several other options will be set
+	or reset to make Vim as Vi-compatible as possible.  See the table
+	below.  This can be used if you want to revert to Vi compatible
+	editing.
+	See also 'cpoptions'.
+
+	option		+ set value	effect	~
+
+	'allowrevins'	  off		no CTRL-_ command
+	'backupcopy'	  Unix: "yes"	  backup file is a copy
+			  others: "auto"  copy or rename backup file
+	'backspace'	  ""		normal backspace
+	'backup'	  off		no backup file
+	'cindent'	  off		no C code indentation
+	'cedit'		+ ""		no key to open the |cmdwin|
+	'cpoptions'	+ (all flags)	Vi-compatible flags
+	'cscopetag'	  off		don't use cscope for ":tag"
+	'cscopetagorder'  0		see |cscopetagorder|
+	'cscopeverbose'	  off		see |cscopeverbose|
+	'digraph'	  off		no digraphs
+	'esckeys'	+ off		no <Esc>-keys in Insert mode
+	'expandtab'	  off		tabs not expanded to spaces
+	'fileformats'	+ ""		no automatic file format detection,
+			  "dos,unix"	except for DOS, Windows and OS/2
+	'formatoptions'	+ "vt"		Vi compatible formatting
+	'gdefault'	  off		no default 'g' flag for ":s"
+	'history'	+ 0		no commandline history
+	'hkmap'		  off		no Hebrew keyboard mapping
+	'hkmapp'	  off		no phonetic Hebrew keyboard mapping
+	'hlsearch'	  off		no highlighting of search matches
+	'incsearch'	  off		no incremental searching
+	'indentexpr'	  ""		no indenting by expression
+	'insertmode'	  off		do not start in Insert mode
+	'iskeyword'	+ "@,48-57,_"	keywords contain alphanumeric
+						characters and '_'
+	'joinspaces'	  on		insert 2 spaces after period
+	'modeline'	+ off		no modelines
+	'more'		+ off		no pauses in listings
+	'revins'	  off		no reverse insert
+	'ruler'		  off		no ruler
+	'scrolljump'	  1		no jump scroll
+	'scrolloff'	  0		no scroll offset
+	'shiftround'	  off		indent not rounded to shiftwidth
+	'shortmess'	+ ""		no shortening of messages
+	'showcmd'	+ off		command characters not shown
+	'showmode'	+ off		current mode not shown
+	'smartcase'	  off		no automatic ignore case switch
+	'smartindent'	  off		no smart indentation
+	'smarttab'	  off		no smart tab size
+	'softtabstop'	  0		tabs are always 'tabstop' positions
+	'startofline'	  on		goto startofline with some commands
+	'tagrelative'	+ off		tag file names are not relative
+	'textauto'	+ off		no automatic textmode detection
+	'textwidth'	  0		no automatic line wrap
+	'tildeop'	  off		tilde is not an operator
+	'ttimeout'	  off		no terminal timeout
+	'whichwrap'	+ ""		left-right movements don't wrap
+	'wildchar'	+ CTRL-E	only when the current value is <Tab>
+					use CTRL-E for cmdline completion
+	'writebackup'	  on or off	depends on +writebackup feature
+
+						*'complete'* *'cpt'* *E535*
+'complete' 'cpt'	string	(default: ".,w,b,u,t,i")
+			local to buffer
+			{not in Vi}
+	This option specifies how keyword completion |ins-completion| works
+	when CTRL-P or CTRL-N are used.  It is also used for whole-line
+	completion |i_CTRL-X_CTRL-L|.  It indicates the type of completion
+	and the places to scan.  It is a comma separated list of flags:
+	.	scan the current buffer ('wrapscan' is ignored)
+	w	scan buffers from other windows
+	b	scan other loaded buffers that are in the buffer list
+	u	scan the unloaded buffers that are in the buffer list
+	U	scan the buffers that are not in the buffer list
+	k	scan the files given with the 'dictionary' option
+	kspell  use the currently active spell checking |spell|
+	k{dict}	scan the file {dict}.  Several "k" flags can be given,
+		patterns are valid too.  For example: >
+			:set cpt=k/usr/dict/*,k~/spanish
+<	s	scan the files given with the 'thesaurus' option
+	s{tsr}	scan the file {tsr}.  Several "s" flags can be given, patterns
+		are valid too.
+	i	scan current and included files
+	d	scan current and included files for defined name or macro
+		|i_CTRL-X_CTRL-D|
+	]	tag completion
+	t	same as "]"
+
+	Unloaded buffers are not loaded, thus their autocmds |:autocmd| are
+	not executed, this may lead to unexpected completions from some files
+	(gzipped files for example).  Unloaded buffers are not scanned for
+	whole-line completion.
+
+	The default is ".,w,b,u,t,i", which means to scan:
+	   1. the current buffer
+	   2. buffers in other windows
+	   3. other loaded buffers
+	   4. unloaded buffers
+	   5. tags
+	   6. included files
+
+	As you can see, CTRL-N and CTRL-P can be used to do any 'iskeyword'-
+	based expansion (e.g., dictionary |i_CTRL-X_CTRL-K|, included patterns
+	|i_CTRL-X_CTRL-I|, tags |i_CTRL-X_CTRL-]| and normal expansions).
+
+						*'completefunc'* *'cfu'*
+'completefunc' 'cfu'	string	(default: empty)
+			local to buffer
+			{not in Vi}
+			{not available when compiled without the +eval
+			or +insert_expand feature}
+	This option specifies a function to be used for Insert mode completion
+	with CTRL-X CTRL-U. |i_CTRL-X_CTRL-U|
+	See |complete-functions| for an explanation of how the function is
+	invoked and what it should return.
+
+
+						*'completeopt'* *'cot'*
+'completeopt' 'cot'	string	(default: "menu,preview")
+			global
+			{not available when compiled without the
+			|+insert_expand| feature}
+			{not in Vi}
+	A comma separated list of options for Insert mode completion
+	|ins-completion|.  The supported values are:
+
+	   menu	    Use a popup menu to show the possible completions.  The
+		    menu is only shown when there is more than one match and
+		    sufficient colors are available.  |ins-completion-menu|
+
+	   menuone  Use the popup menu also when there is only one match.
+		    Useful when there is additional information about the
+		    match, e.g., what file it comes from.
+
+	   longest  Only insert the longest common text of the matches.  If
+		    the menu is displayed you can use CTRL-L to add more
+		    characters.  Whether case is ignored depends on the kind
+		    of completion.  For buffer text the 'ignorecase' option is
+		    used.
+
+	   preview  Show extra information about the currently selected
+		    completion in the preview window.  Only works in
+		    combination with "menu" or "menuone".
+
+
+				*'confirm'* *'cf'* *'noconfirm'* *'nocf'*
+'confirm' 'cf'		boolean (default off)
+			global
+			{not in Vi}
+	When 'confirm' is on, certain operations that would normally
+	fail because of unsaved changes to a buffer, e.g. ":q" and ":e",
+	instead raise a |dialog| asking if you wish to save the current
+	file(s).  You can still use a ! to unconditionally |abandon| a buffer.
+	If 'confirm' is off you can still activate confirmation for one
+	command only (this is most useful in mappings) with the |:confirm|
+	command.
+	Also see the |confirm()| function and the 'v' flag in 'guioptions'.
+
+			*'conskey'* *'consk'* *'noconskey'* *'noconsk'*
+'conskey' 'consk'	boolean	(default off)
+			global
+			{not in Vi}  {only for MS-DOS}
+	When on direct console I/O is used to obtain a keyboard character.
+	This should work in most cases.  Also see |'bioskey'|.  Together,
+	three methods of console input are available:
+	'conskey'   'bioskey'	    action ~
+	   on	     on or off	    direct console input
+	   off		on	    BIOS
+	   off		off	    STDIN
+
+			*'copyindent'* *'ci'* *'nocopyindent'* *'noci'*
+'copyindent' 'ci'	boolean	(default off)
+			local to buffer
+			{not in Vi}
+	Copy the structure of the existing lines indent when autoindenting a
+	new line.  Normally the new indent is reconstructed by a series of
+	tabs followed by spaces as required (unless |'expandtab'| is enabled,
+	in which case only spaces are used).  Enabling this option makes the
+	new line copy whatever characters were used for indenting on the
+	existing line.  If the new indent is greater than on the existing
+	line, the remaining space is filled in the normal manner.
+	NOTE: 'copyindent' is reset when 'compatible' is set.
+	Also see 'preserveindent'.
+
+						*'cpoptions'* *'cpo'*
+'cpoptions' 'cpo'	string	(Vim default: "aABceFs",
+				 Vi default:  all flags)
+			global
+			{not in Vi}
+	A sequence of single character flags.  When a character is present
+	this indicates vi-compatible behavior.  This is used for things where
+	not being vi-compatible is mostly or sometimes preferred.
+	'cpoptions' stands for "compatible-options".
+	Commas can be added for readability.
+	To avoid problems with flags that are added in the future, use the
+	"+=" and "-=" feature of ":set" |add-option-flags|.
+	NOTE: This option is set to the Vi default value when 'compatible' is
+	set and to the Vim default value when 'compatible' is reset.
+	NOTE: This option is set to the POSIX default value at startup when
+	the Vi default value would be used and the $VIM_POSIX environment
+	variable exists |posix|.  This means tries to behave like the POSIX
+	specification.
+
+	    contains	behavior	~
+								*cpo-a*
+		a	When included, a ":read" command with a file name
+			argument will set the alternate file name for the
+			current window.
+								*cpo-A*
+		A	When included, a ":write" command with a file name
+			argument will set the alternate file name for the
+			current window.
+								*cpo-b*
+		b	"\|" in a ":map" command is recognized as the end of
+			the map command.  The '\' is included in the mapping,
+			the text after the '|' is interpreted as the next
+			command.  Use a CTRL-V instead of a backslash to
+			include the '|' in the mapping.  Applies to all
+			mapping, abbreviation, menu and autocmd commands.
+			See also |map_bar|.
+								*cpo-B*
+		B	A backslash has no special meaning in mappings,
+			abbreviations and the "to" part of the menu commands.
+			Remove this flag to be able to use a backslash like a
+			CTRL-V.  For example, the command ":map X \<Esc>"
+			results in X being mapped to:
+				'B' included:	"\^["	 (^[ is a real <Esc>)
+				'B' excluded:	"<Esc>"  (5 characters)
+				('<' excluded in both cases)
+								*cpo-c*
+		c	Searching continues at the end of any match at the
+			cursor position, but not further than the start of the
+			next line.  When not present searching continues
+			one character from the cursor position.  With 'c'
+			"abababababab" only gets three matches when repeating
+			"/abab", without 'c' there are five matches.
+								*cpo-C*
+		C	Do not concatenate sourced lines that start with a
+			backslash.  See |line-continuation|.
+								*cpo-d*
+		d	Using "./" in the 'tags' option doesn't mean to use
+			the tags file relative to the current file, but the
+			tags file in the current directory.
+								*cpo-D*
+		D	Can't use CTRL-K to enter a digraph after Normal mode
+			commands with a character argument, like |r|, |f| and
+			|t|.
+								*cpo-e*
+		e	When executing a register with ":@r", always add a
+			<CR> to the last line, also when the register is not
+			linewise.  If this flag is not present, the register
+			is not linewise and the last line does not end in a
+			<CR>, then the last line is put on the command-line
+			and can be edited before hitting <CR>.
+								*cpo-E*
+		E	It is an error when using "y", "d", "c", "g~", "gu" or
+			"gU" on an Empty region.  The operators only work when
+			at least one character is to be operate on.  Example:
+			This makes "y0" fail in the first column.
+								*cpo-f*
+		f	When included, a ":read" command with a file name
+			argument will set the file name for the current buffer,
+			if the current buffer doesn't have a file name yet.
+								*cpo-F*
+		F	When included, a ":write" command with a file name
+			argument will set the file name for the current
+			buffer, if the current buffer doesn't have a file name
+			yet.  Also see |cpo-P|.
+								*cpo-g*
+		g	Goto line 1 when using ":edit" without argument.
+								*cpo-H*
+		H	When using "I" on a line with only blanks, insert
+			before the last blank.  Without this flag insert after
+			the last blank.
+								*cpo-i*
+		i	When included, interrupting the reading of a file will
+			leave it modified.
+								*cpo-I*
+		I	When moving the cursor up or down just after inserting
+			indent for 'autoindent', do not delete the indent.
+								*cpo-j*
+		j	When joining lines, only add two spaces after a '.',
+			not after '!' or '?'.  Also see 'joinspaces'.
+								*cpo-J*
+		J	A |sentence| has to be followed by two spaces after
+			the '.', '!' or '?'.  A <Tab> is not recognized as
+			white space.
+								*cpo-k*
+		k	Disable the recognition of raw key codes in
+			mappings, abbreviations, and the "to" part of menu
+			commands.  For example, if <Key> sends ^[OA (where ^[
+			is <Esc>), the command ":map X ^[OA" results in X
+			being mapped to:
+				'k' included:	"^[OA"	 (3 characters)
+				'k' excluded:	"<Key>"  (one key code)
+			Also see the '<' flag below.
+								*cpo-K*
+		K	Don't wait for a key code to complete when it is
+			halfway a mapping.  This breaks mapping <F1><F1> when
+			only part of the second <F1> has been read.  It
+			enables cancelling the mapping by typing <F1><Esc>.
+								*cpo-l*
+		l	Backslash in a [] range in a search pattern is taken
+			literally, only "\]", "\^", "\-" and "\\" are special.
+			See |/[]|
+			   'l' included: "/[ \t]"  finds <Space>, '\' and 't'
+			   'l' excluded: "/[ \t]"  finds <Space> and <Tab>
+			Also see |cpo-\|.
+								*cpo-L*
+		L	When the 'list' option is set, 'wrapmargin',
+			'textwidth', 'softtabstop' and Virtual Replace mode
+			(see |gR|) count a <Tab> as two characters, instead of
+			the normal behavior of a <Tab>.
+								*cpo-m*
+		m	When included, a showmatch will always wait half a
+			second.  When not included, a showmatch will wait half
+			a second or until a character is typed.  |'showmatch'|
+								*cpo-M*
+		M	When excluded, "%" matching will take backslashes into
+			account.  Thus in "( \( )" and "\( ( \)" the outer
+			parenthesis match.  When included "%" ignores
+			backslashes, which is Vi compatible.
+								*cpo-n*
+		n	When included, the column used for 'number' will also
+			be used for text of wrapped lines.
+								*cpo-o*
+		o	Line offset to search command is not remembered for
+			next search.
+								*cpo-O*
+		O	Don't complain if a file is being overwritten, even
+			when it didn't exist when editing it.  This is a
+			protection against a file unexpectedly created by
+			someone else.  Vi didn't complain about this.
+								*cpo-p*
+		p	Vi compatible Lisp indenting.  When not present, a
+			slightly better algorithm is used.
+								*cpo-P*
+		P	When included, a ":write" command that appends to a
+			file will set the file name for the current buffer, if
+			the current buffer doesn't have a file name yet and
+			the 'F' flag is also included |cpo-F|.
+								*cpo-q*
+		q	When joining multiple lines leave the cursor at the
+			position where it would be when joining two lines.
+								*cpo-r*
+		r	Redo ("." command) uses "/" to repeat a search
+			command, instead of the actually used search string.
+								*cpo-R*
+		R	Remove marks from filtered lines.  Without this flag
+			marks are kept like |:keepmarks| was used.
+								*cpo-s*
+		s	Set buffer options when entering the buffer for the
+			first time.  This is like it is in Vim version 3.0.
+			And it is the default.  If not present the options are
+			set when the buffer is created.
+								*cpo-S*
+		S	Set buffer options always when entering a buffer
+			(except 'readonly', 'fileformat', 'filetype' and
+			'syntax').  This is the (most) Vi compatible setting.
+			The options are set to the values in the current
+			buffer.  When you change an option and go to another
+			buffer, the value is copied.  Effectively makes the
+			buffer options global to all buffers.
+
+			's'    'S'     copy buffer options
+			no     no      when buffer created
+			yes    no      when buffer first entered (default)
+			 X     yes     each time when buffer entered (vi comp.)
+								*cpo-t*
+		t	Search pattern for the tag command is remembered for
+			"n" command.  Otherwise Vim only puts the pattern in
+			the history for search pattern, but doesn't change the
+			last used search pattern.
+								*cpo-u*
+		u	Undo is Vi compatible.  See |undo-two-ways|.
+								*cpo-v*
+		v	Backspaced characters remain visible on the screen in
+			Insert mode.  Without this flag the characters are
+			erased from the screen right away.  With this flag the
+			screen newly typed text overwrites backspaced
+			characters.
+								*cpo-w*
+		w	When using "cw" on a blank character, only change one
+			character and not all blanks until the start of the
+			next word.
+								*cpo-W*
+		W	Don't overwrite a readonly file.  When omitted, ":w!"
+			overwrites a readonly file, if possible.
+								*cpo-x*
+		x	<Esc> on the command-line executes the command-line.
+			The default in Vim is to abandon the command-line,
+			because <Esc> normally aborts a command.  |c_<Esc>|
+								*cpo-X*
+		X	When using a count with "R" the replaced text is
+			deleted only once.  Also when repeating "R" with "."
+			and a count.
+								*cpo-y*
+		y	A yank command can be redone with ".".
+								*cpo-Z*
+		Z	When using "w!" while the 'readonly' option is set,
+			don't reset 'readonly'.
+								*cpo-!*
+		!	When redoing a filter command, use the last used
+			external command, whatever it was.  Otherwise the last
+			used -filter- command is used.
+								*cpo-$*
+		$	When making a change to one line, don't redisplay the
+			line, but put a '$' at the end of the changed text.
+			The changed text will be overwritten when you type the
+			new text.  The line is redisplayed if you type any
+			command that moves the cursor from the insertion
+			point.
+								*cpo-%*
+		%	Vi-compatible matching is done for the "%" command.
+			Does not recognize "#if", "#endif", etc.
+			Does not recognize "/*" and "*/".
+			Parens inside single and double quotes are also
+			counted, causing a string that contains a paren to
+			disturb the matching.  For example, in a line like
+			"if (strcmp("foo(", s))" the first paren does not
+			match the last one.  When this flag is not included,
+			parens inside single and double quotes are treated
+			specially.  When matching a paren outside of quotes,
+			everything inside quotes is ignored.  When matching a
+			paren inside quotes, it will find the matching one (if
+			there is one).  This works very well for C programs.
+			This flag is also used for other features, such as
+			C-indenting.
+								*cpo--*
+		-	When included, a vertical movement command fails when
+			it would go above the first line or below the last
+			line.  Without it the cursor moves to the first or
+			last line, unless it already was in that line.
+			Applies to the commands "-", "k", CTRL-P, "+", "j",
+			CTRL-N, CTRL-J and ":1234".
+								*cpo-+*
+		+	When included, a ":write file" command will reset the
+			'modified' flag of the buffer, even though the buffer
+			itself may still be different from its file.
+								*cpo-star*
+		*	Use ":*" in the same way as ":@".  When not included,
+			":*" is an alias for ":'<,'>", select the Visual area.
+								*cpo-<*
+		<	Disable the recognition of special key codes in |<>|
+			form in mappings, abbreviations, and the "to" part of
+			menu commands.  For example, the command
+			":map X <Tab>" results in X being mapped to:
+				'<' included:	"<Tab>"  (5 characters)
+				'<' excluded:	"^I"	 (^I is a real <Tab>)
+			Also see the 'k' flag above.
+								*cpo->*
+		>	When appending to a register, put a line break before
+			the appended text.
+
+	POSIX flags.  These are not included in the Vi default value, except
+	when $VIM_POSIX was set on startup. |posix|
+
+	    contains	behavior	~
+								*cpo-#*
+		#	A count before "D", "o" and "O" has no effect.
+								*cpo-&*
+		&	When ":preserve" was used keep the swap file when
+			exiting normally while this buffer is still loaded.
+			This flag is tested when exiting.
+								*cpo-\*
+		\	Backslash in a [] range in a search pattern is taken
+			literally, only "\]" is special  See |/[]|
+			   '\' included: "/[ \-]"  finds <Space>, '\' and '-'
+			   '\' excluded: "/[ \-]"  finds <Space> and '-'
+			Also see |cpo-l|.
+								*cpo-/*
+		/	When "%" is used as the replacement string in a |:s|
+			command, use the previous replacement string. |:s%|
+								*cpo-{*
+		{	The |{| and |}| commands also stop at a "{" character
+			at the start of a line.
+								*cpo-.*
+		.	The ":chdir" and ":cd" commands fail if the current
+			buffer is modified, unless ! is used.  Vim doesn't
+			need this, since it remembers the full path of an
+			opened file.
+								*cpo-bar*
+		|	The value of the $LINES and $COLUMNS environment
+			variables overrule the terminal size values obtained
+			with system specific functions.
+
+
+						*'cscopepathcomp'* *'cspc'*
+'cscopepathcomp' 'cspc'	number	(default 0)
+			global
+			{not available when compiled without the |+cscope|
+			feature}
+			{not in Vi}
+	Determines how many components of the path to show in a list of tags.
+	See |cscopepathcomp|.
+
+						*'cscopeprg'* *'csprg'*
+'cscopeprg' 'csprg'	string	(default "cscope")
+			global
+			{not available when compiled without the |+cscope|
+			feature}
+			{not in Vi}
+	Specifies the command to execute cscope.  See |cscopeprg|.
+	This option cannot be set from a |modeline| or in the |sandbox|, for
+	security reasons.
+
+						*'cscopequickfix'* *'csqf'*
+'cscopequickfix' 'csqf' string	(default "")
+			global
+			{not available when compiled without the |+cscope|
+			or |+quickfix| features}
+			{not in Vi}
+	Specifies whether to use quickfix window to show cscope results.
+	See |cscopequickfix|.
+
+				*'cscopetag'* *'cst'* *'nocscopetag'* *'nocst'*
+'cscopetag' 'cst'	boolean (default off)
+			global
+			{not available when compiled without the |+cscope|
+			feature}
+			{not in Vi}
+	Use cscope for tag commands.  See |cscope-options|.
+	NOTE: This option is reset when 'compatible' is set.
+
+						*'cscopetagorder'* *'csto'*
+'cscopetagorder' 'csto'	number	(default 0)
+			global
+			{not available when compiled without the |+cscope|
+			feature}
+			{not in Vi}
+	Determines the order in which ":cstag" performs a search.  See
+	|cscopetagorder|.
+	NOTE: This option is set to 0 when 'compatible' is set.
+
+					*'cscopeverbose'* *'csverb'*
+					*'nocscopeverbose'* *'nocsverb'*
+'cscopeverbose' 'csverb' boolean (default off)
+			global
+			{not available when compiled without the |+cscope|
+			feature}
+			{not in Vi}
+	Give messages when adding a cscope database.  See |cscopeverbose|.
+	NOTE: This option is reset when 'compatible' is set.
+
+
+			*'cursorcolumn'* *'cuc'* *'nocursorcolumn'* *'nocuc'*
+'cursorcolumn' 'cuc'	boolean	(default off)
+			local to window
+			{not in Vi}
+			{not available when compiled without the  |+syntax|
+			feature}
+	Highlight the screen column of the cursor with CursorColumn
+	|hl-CursorColumn|.  Useful to align text.  Will make screen redrawing
+	slower.
+	If you only want the highlighting in the current window you can use
+	these autocommands: >
+		au WinLeave * set nocursorline nocursorcolumn
+		au WinEnter * set cursorline cursorcolumn
+<
+
+			*'cursorline'* *'cul'* *'nocursorline'* *'nocul'*
+'cursorline' 'cul'	boolean	(default off)
+			local to window
+			{not in Vi}
+			{not available when compiled without the  |+syntax|
+			feature}
+	Highlight the screen line of the cursor with CursorLine
+	|hl-CursorLine|.  Useful to easily spot the cursor.  Will make screen
+	redrawing slower.
+	When Visual mode is active the highlighting isn't used to make it
+	easier to see the selected text.
+
+
+						*'debug'*
+'debug'			string	(default "")
+			global
+			{not in Vi}
+	These values can be used:
+	msg	Error messages that would otherwise be omitted will be given
+		anyway.
+	throw	Error messages that would otherwise be omitted will be given
+		anyway and also throw an exception and set |v:errmsg|.
+	beep	A message will be given when otherwise only a beep would be
+		produced.
+	The values can be combined, separated by a comma.
+	"msg" and "throw" are useful for debugging 'foldexpr', 'formatexpr' or
+	'indentexpr'.
+
+						*'define'* *'def'*
+'define' 'def'		string	(default "^\s*#\s*define")
+			global or local to buffer |global-local|
+			{not in Vi}
+	Pattern to be used to find a macro definition.  It is a search
+	pattern, just like for the "/" command.  This option is used for the
+	commands like "[i" and "[d" |include-search|.  The 'isident' option is
+	used to recognize the defined name after the match:
+		{match with 'define'}{non-ID chars}{defined name}{non-ID char}
+	See |option-backslash| about inserting backslashes to include a space
+	or backslash.
+	The default value is for C programs.  For C++ this value would be
+	useful, to include const type declarations: >
+		^\(#\s*define\|[a-z]*\s*const\s*[a-z]*\)
+<	When using the ":set" command, you need to double the backslashes!
+
+			*'delcombine'* *'deco'* *'nodelcombine'* *'nodeco'*
+'delcombine' 'deco'	boolean (default off)
+			global
+			{not in Vi}
+			{only available when compiled with the |+multi_byte|
+			feature}
+	If editing Unicode and this option is set, backspace and Normal mode
+	"x" delete each combining character on its own.  When it is off (the
+	default) the character along with its combining characters are
+	deleted.
+	Note: When 'delcombine' is set "xx" may work different from "2x"!
+
+	This is useful for Arabic, Hebrew and many other languages where one
+	may have combining characters overtop of base characters, and want
+	to remove only the combining ones.
+
+						*'dictionary'* *'dict'*
+'dictionary' 'dict'	string	(default "")
+			global or local to buffer |global-local|
+			{not in Vi}
+	List of file names, separated by commas, that are used to lookup words
+	for keyword completion commands |i_CTRL-X_CTRL-K|.  Each file should
+	contain a list of words.  This can be one word per line, or several
+	words per line, separated by non-keyword characters (white space is
+	preferred).  Maximum line length is 510 bytes.
+	When this option is empty, or an entry "spell" is present, spell
+	checking is enabled the currently active spelling is used. |spell|
+	To include a comma in a file name precede it with a backslash.  Spaces
+	after a comma are ignored, otherwise spaces are included in the file
+	name.  See |option-backslash| about using backslashes.
+	This has nothing to do with the |Dictionary| variable type.
+	Where to find a list of words?
+	- On FreeBSD, there is the file "/usr/share/dict/words".
+	- In the Simtel archive, look in the "msdos/linguist" directory.
+	- In "miscfiles" of the GNU collection.
+	The use of |:set+=| and |:set-=| is preferred when adding or removing
+	directories from the list.  This avoids problems when a future version
+	uses another default.
+	Backticks cannot be used in this option for security reasons.
+
+							*'diff'* *'nodiff'*
+'diff'			boolean	(default off)
+			local to window
+			{not in Vi}
+			{not available when compiled without the |+diff|
+			feature}
+	Join the current window in the group of windows that shows differences
+	between files.  See |vimdiff|.
+
+						*'dex'* *'diffexpr'*
+'diffexpr' 'dex'	string	(default "")
+			global
+			{not in Vi}
+			{not available when compiled without the |+diff|
+			feature}
+	Expression which is evaluated to obtain an ed-style diff file from two
+	versions of a file.  See |diff-diffexpr|.
+	This option cannot be set from a |modeline| or in the |sandbox|, for
+	security reasons.
+
+						*'dip'* *'diffopt'*
+'diffopt' 'dip'		string	(default "filler")
+			global
+			{not in Vi}
+			{not available when compiled without the |+diff|
+			feature}
+	Option settings for diff mode.  It can consist of the following items.
+	All are optional.  Items must be separated by a comma.
+
+		filler		Show filler lines, to keep the text
+				synchronized with a window that has inserted
+				lines at the same position.  Mostly useful
+				when windows are side-by-side and 'scrollbind'
+				is set.
+
+		context:{n}	Use a context of {n} lines between a change
+				and a fold that contains unchanged lines.
+				When omitted a context of six lines is used.
+				See |fold-diff|.
+
+		icase		Ignore changes in case of text.  "a" and "A"
+				are considered the same.  Adds the "-i" flag
+				to the "diff" command if 'diffexpr' is empty.
+
+		iwhite		Ignore changes in amount of white space.  Adds
+				the "-b" flag to the "diff" command if
+				'diffexpr' is empty.  Check the documentation
+				of the "diff" command for what this does
+				exactly.  It should ignore adding trailing
+				white space, but not leading white space.
+
+		horizontal	Start diff mode with horizontal splits (unless
+				explicitly specified otherwise).
+
+		vertical	Start diff mode with vertical splits (unless
+				explicitly specified otherwise).
+
+		foldcolumn:{n}	Set the 'foldcolumn' option to {n} when
+				starting diff mode.  Without this 2 is used.
+
+	Examples: >
+
+		:set diffopt=filler,context:4
+		:set diffopt=
+		:set diffopt=filler,foldcolumn:3
+<
+				     *'digraph'* *'dg'* *'nodigraph'* *'nodg'*
+'digraph' 'dg'		boolean	(default off)
+			global
+			{not in Vi}
+			{not available when compiled without the |+digraphs|
+			feature}
+	Enable the entering of digraphs in Insert mode with {char1} <BS>
+	{char2}.  See |digraphs|.
+	NOTE: This option is reset when 'compatible' is set.
+
+						*'directory'* *'dir'*
+'directory' 'dir'	string	(default for Amiga: ".,t:",
+				 for MS-DOS and Win32: ".,c:\tmp,c:\temp"
+				 for Unix: ".,~/tmp,/var/tmp,/tmp")
+			global
+	List of directory names for the swap file, separated with commas.
+	- The swap file will be created in the first directory where this is
+	  possible.
+	- Empty means that no swap file will be used (recovery is
+	  impossible!).
+	- A directory "." means to put the swap file in the same directory as
+	  the edited file.  On Unix, a dot is prepended to the file name, so
+	  it doesn't show in a directory listing.  On MS-Windows the "hidden"
+	  attribute is set and a dot prepended if possible.
+	- A directory starting with "./" (or ".\" for MS-DOS et al.) means to
+	  put the swap file relative to where the edited file is.  The leading
+	  "." is replaced with the path name of the edited file.
+	- For Unix and Win32, if a directory ends in two path separators "//"
+	  or "\\", the swap file name will be built from the complete path to
+	  the file with all path separators substituted to percent '%' signs.
+	  This will ensure file name uniqueness in the preserve directory.
+	- Spaces after the comma are ignored, other spaces are considered part
+	  of the directory name.  To have a space at the start of a directory
+	  name, precede it with a backslash.
+	- To include a comma in a directory name precede it with a backslash.
+	- A directory name may end in an ':' or '/'.
+	- Environment variables are expanded |:set_env|.
+	- Careful with '\' characters, type one before a space, type two to
+	  get one in the option (see |option-backslash|), for example: >
+	    :set dir=c:\\tmp,\ dir\\,with\\,commas,\\\ dir\ with\ spaces
+<	- For backwards compatibility with Vim version 3.0 a '>' at the start
+	  of the option is removed.
+	Using "." first in the list is recommended.  This means that editing
+	the same file twice will result in a warning.  Using "/tmp" on Unix is
+	discouraged: When the system crashes you lose the swap file.
+	"/var/tmp" is often not cleared when rebooting, thus is a better
+	choice than "/tmp".  But it can contain a lot of files, your swap
+	files get lost in the crowd.  That is why a "tmp" directory in your
+	home directory is tried first.
+	The use of |:set+=| and |:set-=| is preferred when adding or removing
+	directories from the list.  This avoids problems when a future version
+	uses another default.
+	This option cannot be set from a |modeline| or in the |sandbox|, for
+	security reasons.
+	{Vi: directory to put temp file in, defaults to "/tmp"}
+
+					*'display'* *'dy'*
+'display' 'dy'		string	(default "")
+			global
+			{not in Vi}
+	Change the way text is displayed.  This is comma separated list of
+	flags:
+	lastline	When included, as much as possible of the last line
+			in a window will be displayed.  When not included, a
+			last line that doesn't fit is replaced with "@" lines.
+	uhex		Show unprintable characters hexadecimal as <xx>
+			instead of using ^C and ~C.
+
+						*'eadirection'* *'ead'*
+'eadirection' 'ead'	string	(default "both")
+			global
+			{not in Vi}
+			{not available when compiled without the +vertsplit
+			feature}
+	Tells when the 'equalalways' option applies:
+		ver	vertically, width of windows is not affected
+		hor	horizontally, height of windows is not affected
+		both	width and height of windows is affected
+
+			   *'ed'* *'edcompatible'* *'noed'* *'noedcompatible'*
+'edcompatible' 'ed'	boolean	(default off)
+			global
+	Makes the 'g' and 'c' flags of the ":substitute" command to be
+	toggled each time the flag is given.  See |complex-change|.  See
+	also 'gdefault' option.
+	Switching this option on is discouraged!
+
+					*'encoding'* *'enc'* *E543*
+'encoding' 'enc'	string (default: "latin1" or value from $LANG)
+			global
+			{only available when compiled with the |+multi_byte|
+			feature}
+			{not in Vi}
+	Sets the character encoding used inside Vim.  It applies to text in
+	the buffers, registers, Strings in expressions, text stored in the
+	viminfo file, etc.  It sets the kind of characters which Vim can work
+	with.  See |encoding-names| for the possible values.
+
+	NOTE: Changing this option will not change the encoding of the
+	existing text in Vim.  It may cause non-ASCII text to become invalid.
+	It should normally be kept at its default value, or set when Vim
+	starts up.  See |multibyte|.  To reload the menus see |:menutrans|.
+
+	NOTE: For GTK+ 2 it is highly recommended to set 'encoding' to
+	"utf-8".  Although care has been taken to allow different values of
+	'encoding', "utf-8" is the natural choice for the environment and
+	avoids unnecessary conversion overhead.  "utf-8" has not been made
+	the default to prevent different behavior of the GUI and terminal
+	versions, and to avoid changing the encoding of newly created files
+	without your knowledge (in case 'fileencodings' is empty).
+
+	The character encoding of files can be different from 'encoding'.
+	This is specified with 'fileencoding'.  The conversion is done with
+	iconv() or as specified with 'charconvert'.
+
+	Normally 'encoding' will be equal to your current locale.  This will
+	be the default if Vim recognizes your environment settings.  If
+	'encoding' is not set to the current locale, 'termencoding' must be
+	set to convert typed and displayed text.  See |encoding-table|.
+
+	When you set this option, it fires the |EncodingChanged| autocommand
+	event so that you can set up fonts if necessary.
+
+	When the option is set, the value is converted to lowercase.  Thus
+	you can set it with uppercase values too.  Underscores are translated
+	to '-' signs.
+	When the encoding is recognized, it is changed to the standard name.
+	For example "Latin-1" becomes "latin1", "ISO_88592" becomes
+	"iso-8859-2" and "utf8" becomes "utf-8".
+
+	Note: "latin1" is also used when the encoding could not be detected.
+	This only works when editing files in the same encoding!  When the
+	actual character set is not latin1, make sure 'fileencoding' and
+	'fileencodings' are empty.  When conversion is needed, switch to using
+	utf-8.
+
+	When "unicode", "ucs-2" or "ucs-4" is used, Vim internally uses utf-8.
+	You don't notice this while editing, but it does matter for the
+	|viminfo-file|.  And Vim expects the terminal to use utf-8 too.  Thus
+	setting 'encoding' to one of these values instead of utf-8 only has
+	effect for encoding used for files when 'fileencoding' is empty.
+
+	When 'encoding' is set to a Unicode encoding, and 'fileencodings' was
+	not set yet, the default for 'fileencodings' is changed.
+
+			*'endofline'* *'eol'* *'noendofline'* *'noeol'*
+'endofline' 'eol'	boolean	(default on)
+			local to buffer
+			{not in Vi}
+	When writing a file and this option is off and the 'binary' option
+	is on, no <EOL> will be written for the last line in the file.  This
+	option is automatically set when starting to edit a new file, unless
+	the file does not have an <EOL> for the last line in the file, in
+	which case it is reset.  Normally you don't have to set or reset this
+	option.  When 'binary' is off the value is not used when writing the
+	file.  When 'binary' is on it is used to remember the presence of a
+	<EOL> for the last line in the file, so that when you write the file
+	the situation from the original file can be kept.  But you can change
+	it if you want to.
+
+			     *'equalalways'* *'ea'* *'noequalalways'* *'noea'*
+'equalalways' 'ea'	boolean	(default on)
+			global
+			{not in Vi}
+	When on, all the windows are automatically made the same size after
+	splitting or closing a window.  This also happens the moment the
+	option is switched on.  When off, splitting a window will reduce the
+	size of the current window and leave the other windows the same.  When
+	closing a window the extra lines are given to the window next to it
+	(depending on 'splitbelow' and 'splitright').
+	When mixing vertically and horizontally split windows, a minimal size
+	is computed and some windows may be larger if there is room.  The
+	'eadirection' option tells in which direction the size is affected.
+	Changing the height of a window can be avoided by setting
+	'winfixheight'.
+
+						*'equalprg'* *'ep'*
+'equalprg' 'ep'		string	(default "")
+			global or local to buffer |global-local|
+			{not in Vi}
+	External program to use for "=" command.  When this option is empty
+	the internal formatting functions are used ('lisp', 'cindent' or
+	'indentexpr').
+	Environment variables are expanded |:set_env|.  See |option-backslash|
+	about including spaces and backslashes.
+	This option cannot be set from a |modeline| or in the |sandbox|, for
+	security reasons.
+
+			*'errorbells'* *'eb'* *'noerrorbells'* *'noeb'*
+'errorbells' 'eb'	boolean	(default off)
+			global
+	Ring the bell (beep or screen flash) for error messages.  This only
+	makes a difference for error messages, the bell will be used always
+	for a lot of errors without a message (e.g., hitting <Esc> in Normal
+	mode).  See 'visualbell' on how to make the bell behave like a beep,
+	screen flash or do nothing.
+
+						*'errorfile'* *'ef'*
+'errorfile' 'ef'	string	(Amiga default: "AztecC.Err",
+					others: "errors.err")
+			global
+			{not in Vi}
+			{not available when compiled without the |+quickfix|
+			feature}
+	Name of the errorfile for the QuickFix mode (see |:cf|).
+	When the "-q" command-line argument is used, 'errorfile' is set to the
+	following argument.  See |-q|.
+	NOT used for the ":make" command.  See 'makeef' for that.
+	Environment variables are expanded |:set_env|.
+	See |option-backslash| about including spaces and backslashes.
+	This option cannot be set from a |modeline| or in the |sandbox|, for
+	security reasons.
+
+						*'errorformat'* *'efm'*
+'errorformat' 'efm'	string	(default is very long)
+			global or local to buffer |global-local|
+			{not in Vi}
+			{not available when compiled without the |+quickfix|
+			feature}
+	Scanf-like description of the format for the lines in the error file
+	(see |errorformat|).
+
+				     *'esckeys'* *'ek'* *'noesckeys'* *'noek'*
+'esckeys' 'ek'		boolean	(Vim default: on, Vi default: off)
+			global
+			{not in Vi}
+	Function keys that start with an <Esc> are recognized in Insert
+	mode.  When this option is off, the cursor and function keys cannot be
+	used in Insert mode if they start with an <Esc>.  The advantage of
+	this is that the single <Esc> is recognized immediately, instead of
+	after one second.  Instead of resetting this option, you might want to
+	try changing the values for 'timeoutlen' and 'ttimeoutlen'.  Note that
+	when 'esckeys' is off, you can still map anything, but the cursor keys
+	won't work by default.
+	NOTE: This option is set to the Vi default value when 'compatible' is
+	set and to the Vim default value when 'compatible' is reset.
+
+						*'eventignore'* *'ei'*
+'eventignore' 'ei'	string	(default "")
+			global
+			{not in Vi}
+			{not available when compiled without the |+autocmd|
+			feature}
+	A list of autocommand event names, which are to be ignored.
+	When set to "all" or when "all" is one of the items, all autocommand
+	events are ignored, autocommands will not be executed.
+	Otherwise this is a comma separated list of event names.  Example: >
+	    :set ei=WinEnter,WinLeave
+<
+				 *'expandtab'* *'et'* *'noexpandtab'* *'noet'*
+'expandtab' 'et'	boolean	(default off)
+			local to buffer
+			{not in Vi}
+	In Insert mode: Use the appropriate number of spaces to insert a
+	<Tab>.  Spaces are used in indents with the '>' and '<' commands and
+	when 'autoindent' is on.  To insert a real tab when 'expandtab' is
+	on, use CTRL-V<Tab>.  See also |:retab| and |ins-expandtab|.
+	NOTE: This option is reset when 'compatible' is set.
+
+					*'exrc'* *'ex'* *'noexrc'* *'noex'*
+'exrc' 'ex'		boolean (default off)
+			global
+			{not in Vi}
+	Enables the reading of .vimrc, .exrc and .gvimrc in the current
+	directory.  If you switch this option on you should also consider
+	setting the 'secure' option (see |initialization|).  Using a local
+	.exrc, .vimrc or .gvimrc is a potential security leak, use with care!
+	also see |.vimrc| and |gui-init|.
+	This option cannot be set from a |modeline| or in the |sandbox|, for
+	security reasons.
+
+				*'fileencoding'* *'fenc'* *E213*
+'fileencoding' 'fenc'	string (default: "")
+			local to buffer
+			{only available when compiled with the |+multi_byte|
+			feature}
+			{not in Vi}
+	Sets the character encoding for the file of this buffer.
+	When 'fileencoding' is different from 'encoding', conversion will be
+	done when reading and writing the file.
+	When 'fileencoding' is empty, the same value as 'encoding' will be
+	used (no conversion when reading or writing a file).
+		WARNING: Conversion can cause loss of information!  When
+		'encoding' is "utf-8" conversion is most likely done in a way
+		that the reverse conversion results in the same text.  When
+		'encoding' is not "utf-8" some characters may be lost!
+	See 'encoding' for the possible values.  Additionally, values may be
+	specified that can be handled by the converter, see
+	|mbyte-conversion|.
+	When reading a file 'fileencoding' will be set from 'fileencodings'.
+	To read a file in a certain encoding it won't work by setting
+	'fileencoding', use the |++enc| argument.  One exception: when
+	'fileencodings' is empty the value of 'fileencoding' is used.
+	For a new file the global value of 'fileencoding' is used.
+	Prepending "8bit-" and "2byte-" has no meaning here, they are ignored.
+	When the option is set, the value is converted to lowercase.  Thus
+	you can set it with uppercase values too.  '_' characters are
+	replaced with '-'.  If a name is recognized from the list for
+	'encoding', it is replaced by the standard name.  For example
+	"ISO8859-2" becomes "iso-8859-2".
+	When this option is set, after starting to edit a file, the 'modified'
+	option is set, because the file would be different when written.
+	If you do this in a modeline, you might want to set 'nomodified' to
+	avoid this.
+	This option can not be changed when 'modifiable' is off.
+
+							*'fe'*
+	NOTE: Before version 6.0 this option specified the encoding for the
+	whole of Vim, this was a mistake.  Now use 'encoding' instead.  The
+	old short name was 'fe', which is no longer used.
+
+					*'fileencodings'* *'fencs'*
+'fileencodings' 'fencs'	string (default: "ucs-bom",
+				    "ucs-bom,utf-8,default,latin1" when
+				    'encoding' is set to a Unicode value)
+			global
+			{only available when compiled with the |+multi_byte|
+			feature}
+			{not in Vi}
+	This is a list of character encodings considered when starting to edit
+	an existing file.  When a file is read, Vim tries to use the first
+	mentioned character encoding.  If an error is detected, the next one
+	in the list is tried.  When an encoding is found that works,
+	'fileencoding' is set to it.  If all fail, 'fileencoding' is set to
+	an empty string, which means the value of 'encoding' is used.
+		WARNING: Conversion can cause loss of information!  When
+		'encoding' is "utf-8" (or one of the other Unicode variants)
+		conversion is most likely done in a way that the reverse
+		conversion results in the same text.  When 'encoding' is not
+		"utf-8" some non-ASCII characters may be lost!  You can use
+		the |++bad| argument to specify what is done with characters
+		that can't be converted.
+	For an empty file or a file with only ASCII characters most encodings
+	will work and the first entry of 'fileencodings' will be used (except
+	"ucs-bom", which requires the BOM to be present).  If you prefer
+	another encoding use an BufReadPost autocommand event to test if your
+	preferred encoding is to be used.  Example: >
+		au BufReadPost * if search('\S', 'w') == 0 |
+			\ set fenc=iso-2022-jp | endif
+<	This sets 'fileencoding' to "iso-2022-jp" if the file does not contain
+	non-blank characters.
+	When the |++enc| argument is used then the value of 'fileencodings' is
+	not used.
+	Note that 'fileencodings' is not used for a new file, the global value
+	of 'fileencoding' is used instead.  You can set it with: >
+		:setglobal fenc=iso-8859-2
+<	This means that a non-existing file may get a different encoding than
+	an empty file.
+	The special value "ucs-bom" can be used to check for a Unicode BOM
+	(Byte Order Mark) at the start of the file.  It must not be preceded
+	by "utf-8" or another Unicode encoding for this to work properly.
+	An entry for an 8-bit encoding (e.g., "latin1") should be the last,
+	because Vim cannot detect an error, thus the encoding is always
+	accepted.
+	The special value "default" can be used for the encoding from the
+	environment.  This is the default value for 'encoding'.  It is useful
+	when 'encoding' is set to "utf-8" and your environment uses a
+	non-latin1 encoding, such as Russian.
+	When 'encoding' is "utf-8" and a file contains an illegal byte
+	sequence it won't be recognized as UTF-8.  You can use the |8g8|
+	command to find the illegal byte sequence.
+	WRONG VALUES:			WHAT'S WRONG:
+		latin1,utf-8		"latin1" will always be used
+		utf-8,ucs-bom,latin1	BOM won't be recognized in an utf-8
+					file
+		cp1250,latin1		"cp1250" will always be used
+	If 'fileencodings' is empty, 'fileencoding' is not modified.
+	See 'fileencoding' for the possible values.
+	Setting this option does not have an effect until the next time a file
+	is read.
+
+					*'fileformat'* *'ff'*
+'fileformat' 'ff'	string (MS-DOS, MS-Windows, OS/2 default: "dos",
+				Unix default: "unix",
+				Macintosh default: "mac")
+			local to buffer
+			{not in Vi}
+	This gives the <EOL> of the current buffer, which is used for
+	reading/writing the buffer from/to a file:
+	    dos	    <CR> <NL>
+	    unix    <NL>
+	    mac	    <CR>
+	When "dos" is used, CTRL-Z at the end of a file is ignored.
+	See |file-formats| and |file-read|.
+	For the character encoding of the file see 'fileencoding'.
+	When 'binary' is set, the value of 'fileformat' is ignored, file I/O
+	works like it was set to "unix'.
+	This option is set automatically when starting to edit a file and
+	'fileformats' is not empty and 'binary' is off.
+	When this option is set, after starting to edit a file, the 'modified'
+	option is set, because the file would be different when written.
+	This option can not be changed when 'modifiable' is off.
+	For backwards compatibility: When this option is set to "dos",
+	'textmode' is set, otherwise 'textmode' is reset.
+
+					*'fileformats'* *'ffs'*
+'fileformats' 'ffs'	string (default:
+				Vim+Vi	MS-DOS, MS-Windows OS/2: "dos,unix",
+				Vim	Unix: "unix,dos",
+				Vim	Mac: "mac,unix,dos",
+				Vi	Cygwin: "unix,dos",
+				Vi	others: "")
+			global
+			{not in Vi}
+	This gives the end-of-line (<EOL>) formats that will be tried when
+	starting to edit a new buffer and when reading a file into an existing
+	buffer:
+	- When empty, the format defined with 'fileformat' will be used
+	  always.  It is not set automatically.
+	- When set to one name, that format will be used whenever a new buffer
+	  is opened.  'fileformat' is set accordingly for that buffer.  The
+	  'fileformats' name will be used when a file is read into an existing
+	  buffer, no matter what 'fileformat' for that buffer is set to.
+	- When more than one name is present, separated by commas, automatic
+	  <EOL> detection will be done when reading a file.  When starting to
+	  edit a file, a check is done for the <EOL>:
+	  1. If all lines end in <CR><NL>, and 'fileformats' includes "dos",
+	     'fileformat' is set to "dos".
+	  2. If a <NL> is found and 'fileformats' includes "unix", 'fileformat'
+	     is set to "unix".  Note that when a <NL> is found without a
+	     preceding <CR>, "unix" is preferred over "dos".
+	  3. If 'fileformats' includes "mac", 'fileformat' is set to "mac".
+	     This means that "mac" is only chosen when "unix" is not present,
+	     or when no <NL> is found in the file, and when "dos" is not
+	     present, or no <CR><NL> is present in the file.
+	     Also if "unix" was first chosen, but the first <CR> is before
+	     the first <NL> and there appears to be more <CR>'s than <NL>'s in
+	     the file, then 'fileformat' is set to "mac".
+	  4. If 'fileformat' is still not set, the first name from
+	     'fileformats' is used.
+	  When reading a file into an existing buffer, the same is done, but
+	  this happens like 'fileformat' has been set appropriately for that
+	  file only, the option is not changed.
+	When 'binary' is set, the value of 'fileformats' is not used.
+
+	For systems with a Dos-like <EOL> (<CR><NL>), when reading files that
+	are ":source"ed and for vimrc files, automatic <EOL> detection may be
+	done:
+	- When 'fileformats' is empty, there is no automatic detection.  Dos
+	  format will be used.
+	- When 'fileformats' is set to one or more names, automatic detection
+	  is done.  This is based on the first <NL> in the file: If there is a
+	  <CR> in front of it, Dos format is used, otherwise Unix format is
+	  used.
+	Also see |file-formats|.
+	For backwards compatibility: When this option is set to an empty
+	string or one format (no comma is included), 'textauto' is reset,
+	otherwise 'textauto' is set.
+	NOTE: This option is set to the Vi default value when 'compatible' is
+	set and to the Vim default value when 'compatible' is reset.
+
+					*'filetype'* *'ft'*
+'filetype' 'ft'		string (default: "")
+			local to buffer
+			{not in Vi}
+			{not available when compiled without the |+autocmd|
+			feature}
+	When this option is set, the FileType autocommand event is triggered.
+	All autocommands that match with the value of this option will be
+	executed.  Thus the value of 'filetype' is used in place of the file
+	name.
+	Otherwise this option does not always reflect the current file type.
+	This option is normally set when the file type is detected.  To enable
+	this use the ":filetype on" command. |:filetype|
+	Setting this option to a different value is most useful in a modeline,
+	for a file for which the file type is not automatically recognized.
+	Example, for in an IDL file:
+		/* vim: set filetype=idl : */ ~
+	|FileType| |filetypes|
+	When a dot appears in the value then this separates two filetype
+	names.  Example:
+		/* vim: set filetype=c.doxygen : */ ~
+	This will use the "c" filetype first, then the "doxygen" filetype.
+	This works both for filetype plugins and for syntax files.  More than
+	one dot may appear.
+	Do not confuse this option with 'osfiletype', which is for the file
+	type that is actually stored with the file.
+	This option is not copied to another buffer, independent of the 's' or
+	'S' flag in 'cpoptions'.
+	Only normal file name characters can be used, "/\*?[|<>" are illegal.
+
+						*'fillchars'* *'fcs'*
+'fillchars' 'fcs'	string	(default "vert:|,fold:-")
+			global
+			{not in Vi}
+			{not available when compiled without the |+windows|
+			and |+folding| features}
+	Characters to fill the statuslines and vertical separators.
+	It is a comma separated list of items:
+
+	  item		default		Used for ~
+	  stl:c		' ' or '^'	statusline of the current window
+	  stlnc:c	' ' or '-'	statusline of the non-current windows
+	  vert:c	'|'		vertical separators |:vsplit|
+	  fold:c	'-'		filling 'foldtext'
+	  diff:c	'-'		deleted lines of the 'diff' option
+
+	Any one that is omitted will fall back to the default.  For "stl" and
+	"stlnc" the space will be used when there is highlighting, '^' or '-'
+	otherwise.
+
+	Example: >
+	    :set fillchars=stl:^,stlnc:-,vert:\|,fold:-,diff:-
+<	This is similar to the default, except that these characters will also
+	be used when there is highlighting.
+
+	for "stl" and "stlnc" only single-byte values are supported.
+
+	The highlighting used for these items:
+	  item		highlight group ~
+	  stl:c		StatusLine		|hl-StatusLine|
+	  stlnc:c	StatusLineNC		|hl-StatusLineNC|
+	  vert:c	VertSplit		|hl-VertSplit|
+	  fold:c	Folded			|hl-Folded|
+	  diff:c	DiffDelete		|hl-DiffDelete|
+
+					*'fkmap'* *'fk'* *'nofkmap'* *'nofk'*
+'fkmap' 'fk'		boolean (default off)			*E198*
+			global
+			{not in Vi}
+			{only available when compiled with the |+rightleft|
+			feature}
+	When on, the keyboard is mapped for the Farsi character set.
+	Normally you would set 'allowrevins' and use CTRL-_ in insert mode to
+	toggle this option |i_CTRL-_|.  See |farsi.txt|.
+
+						*'foldclose'* *'fcl'*
+'foldclose' 'fcl'	string (default "")
+			global
+			{not in Vi}
+			{not available when compiled without the |+folding|
+			feature}
+	When set to "all", a fold is closed when the cursor isn't in it and
+	its level is higher than 'foldlevel'.  Useful if you want folds to
+	automatically close when moving out of them.
+
+						*'foldcolumn'* *'fdc'*
+'foldcolumn' 'fdc'	number (default 0)
+			local to window
+			{not in Vi}
+			{not available when compiled without the |+folding|
+			feature}
+	When non-zero, a column with the specified width is shown at the side
+	of the window which indicates open and closed folds.  The maximum
+	value is 12.
+	See |folding|.
+
+			*'foldenable'* *'fen'* *'nofoldenable'* *'nofen'*
+'foldenable' 'fen'	boolean (default on)
+			local to window
+			{not in Vi}
+			{not available when compiled without the |+folding|
+			feature}
+	When off, all folds are open.  This option can be used to quickly
+	switch between showing all text unfolded and viewing the text with
+	folds (including manually opened or closed folds).  It can be toggled
+	with the |zi| command.  The 'foldcolumn' will remain blank when
+	'foldenable' is off.
+	This option is set by commands that create a new fold or close a fold.
+	See |folding|.
+
+						*'foldexpr'* *'fde'*
+'foldexpr' 'fde'	string (default: "0")
+			local to window
+			{not in Vi}
+			{not available when compiled without the |+folding|
+			or |+eval| feature}
+	The expression used for when 'foldmethod' is "expr".  It is evaluated
+	for each line to obtain its fold level.  See |fold-expr|.
+
+	The expression may be evaluated in the |sandbox|, see
+	|sandbox-option|.
+
+	It is not allowed to change text or jump to another window while
+	evaluating 'foldexpr' |textlock|.
+
+						*'foldignore'* *'fdi'*
+'foldignore' 'fdi'	string (default: "#")
+			local to window
+			{not in Vi}
+			{not available when compiled without the |+folding|
+			feature}
+	Used only when 'foldmethod' is "indent".  Lines starting with
+	characters in 'foldignore' will get their fold level from surrounding
+	lines.  White space is skipped before checking for this character.
+	The default "#" works well for C programs.  See |fold-indent|.
+
+						*'foldlevel'* *'fdl'*
+'foldlevel' 'fdl'	number (default: 0)
+			local to window
+			{not in Vi}
+			{not available when compiled without the |+folding|
+			feature}
+	Sets the fold level: Folds with a higher level will be closed.
+	Setting this option to zero will close all folds.  Higher numbers will
+	close fewer folds.
+	This option is set by commands like |zm|, |zM| and |zR|.
+	See |fold-foldlevel|.
+
+						*'foldlevelstart'* *'fdls'*
+'foldlevelstart' 'fdls'	number (default: -1)
+			global
+			{not in Vi}
+			{not available when compiled without the |+folding|
+			feature}
+	Sets 'foldlevel' when starting to edit another buffer in a window.
+	Useful to always start editing with all folds closed (value zero),
+	some folds closed (one) or no folds closed (99).
+	This is done before reading any modeline, thus a setting in a modeline
+	overrules this option.  Starting to edit a file for |diff-mode| also
+	ignores this option and closes all folds.
+	It is also done before BufReadPre autocommands, to allow an autocmd to
+	overrule the 'foldlevel' value for specific files.
+	When the value is negative, it is not used.
+
+						*'foldmarker'* *'fmr'* *E536*
+'foldmarker' 'fmr'	string (default: "{{{,}}}")
+			local to window
+			{not in Vi}
+			{not available when compiled without the |+folding|
+			feature}
+	The start and end marker used when 'foldmethod' is "marker".  There
+	must be one comma, which separates the start and end marker.  The
+	marker is a literal string (a regular expression would be too slow).
+	See |fold-marker|.
+
+						*'foldmethod'* *'fdm'*
+'foldmethod' 'fdm'	string (default: "manual")
+			local to window
+			{not in Vi}
+			{not available when compiled without the |+folding|
+			feature}
+	The kind of folding used for the current window.  Possible values:
+	|fold-manual|	manual	    Folds are created manually.
+	|fold-indent|	indent	    Lines with equal indent form a fold.
+	|fold-expr|	expr	    'foldexpr' gives the fold level of a line.
+	|fold-marker|	marker	    Markers are used to specify folds.
+	|fold-syntax|	syntax	    Syntax highlighting items specify folds.
+	|fold-diff|	diff	    Fold text that is not changed.
+
+						*'foldminlines'* *'fml'*
+'foldminlines' 'fml'	number (default: 1)
+			local to window
+			{not in Vi}
+			{not available when compiled without the |+folding|
+			feature}
+	Sets the minimum number of screen lines for a fold to be displayed
+	closed.  Also for manually closed folds.
+	Note that this only has an effect of what is displayed.  After using
+	"zc" to close a fold, which is displayed open because it's smaller
+	than 'foldminlines', a following "zc" may close a containing fold.
+
+						*'foldnestmax'* *'fdn'*
+'foldnestmax' 'fdn'	number (default: 20)
+			local to window
+			{not in Vi}
+			{not available when compiled without the |+folding|
+			feature}
+	Sets the maximum nesting of folds for the "indent" and "syntax"
+	methods.  This avoids that too many folds will be created.  Using more
+	than 20 doesn't work, because the internal limit is 20.
+
+						*'foldopen'* *'fdo'*
+'foldopen' 'fdo'	string (default: "block,hor,mark,percent,quickfix,
+							     search,tag,undo")
+			global
+			{not in Vi}
+			{not available when compiled without the |+folding|
+			feature}
+	Specifies for which type of commands folds will be opened, if the
+	command moves the cursor into a closed fold.  It is a comma separated
+	list of items.
+		item		commands ~
+		all		any
+		block		"(", "{", "[[", "[{", etc.
+		hor		horizontal movements: "l", "w", "fx", etc.
+		insert		any command in Insert mode
+		jump		far jumps: "G", "gg", etc.
+		mark		jumping to a mark: "'m", CTRL-O, etc.
+		percent		"%"
+		quickfix	":cn", ":crew", ":make", etc.
+		search		search for a pattern: "/", "n", "*", "gd", etc.
+				(not for a search pattern in a ":" command)
+				Also for |[s| and |]s|.
+		tag		jumping to a tag: ":ta", CTRL-T, etc.
+		undo		undo or redo: "u" and CTRL-R
+	When the command is part of a mapping this option is not used.  Add
+	the |zv| command to the mapping to get the same effect.
+	When a movement command is used for an operator (e.g., "dl" or "y%")
+	this option is not used.  This means the operator will include the
+	whole closed fold.
+	Note that vertical movements are not here, because it would make it
+	very difficult to move onto a closed fold.
+	In insert mode the folds containing the cursor will always be open
+	when text is inserted.
+	To close folds you can re-apply 'foldlevel' with the |zx| command or
+	set the 'foldclose' option to "all".
+
+						*'foldtext'* *'fdt'*
+'foldtext' 'fdt'	string (default: "foldtext()")
+			local to window
+			{not in Vi}
+			{not available when compiled without the |+folding|
+			feature}
+	An expression which is used to specify the text displayed for a closed
+	fold.  See |fold-foldtext|.
+
+	The expression may be evaluated in the |sandbox|, see
+	|sandbox-option|.
+
+	It is not allowed to change text or jump to another window while
+	evaluating 'foldtext' |textlock|.
+
+					*'formatoptions'* *'fo'*
+'formatoptions' 'fo'	string (Vim default: "tcq", Vi default: "vt")
+			local to buffer
+			{not in Vi}
+	This is a sequence of letters which describes how automatic
+	formatting is to be done.  See |fo-table|.  When the 'paste' option is
+	on, no formatting is done (like 'formatoptions' is empty).  Commas can
+	be inserted for readability.
+	To avoid problems with flags that are added in the future, use the
+	"+=" and "-=" feature of ":set" |add-option-flags|.
+	NOTE: This option is set to the Vi default value when 'compatible' is
+	set and to the Vim default value when 'compatible' is reset.
+
+					*'formatlistpat'* *'flp'*
+'formatlistpat' 'flp'	string (default: "^\s*\d\+[\]:.)}\t ]\s*")
+			local to buffer
+			{not in Vi}
+	A pattern that is used to recognize a list header.  This is used for
+	the "n" flag in 'formatoptions'.
+	The pattern must match exactly the text that will be the indent for
+	the line below it.  You can use |/\ze| to mark the end of the match
+	while still checking more characters.  There must be a character
+	following the pattern, when it matches the whole line it is handled
+	like there is no match.
+	The default recognizes a number, followed by an optional punctuation
+	character and white space.
+
+						*'formatprg'* *'fp'*
+'formatprg' 'fp'	string (default "")
+			global
+			{not in Vi}
+	The name of an external program that will be used to format the lines
+	selected with the |gq| operator.  The program must take the input on
+	stdin and produce the output on stdout.  The Unix program "fmt" is
+	such a program.
+	If the 'formatexpr' option is not empty it will be used instead.
+	Otherwise, if 'formatprg' option is an empty string, the internal
+	format function will be used |C-indenting|.
+	Environment variables are expanded |:set_env|.  See |option-backslash|
+	about including spaces and backslashes.
+	The expression may be evaluated in the |sandbox|, see
+	|sandbox-option|.
+
+						*'formatexpr'* *'fex'*
+'formatexpr' 'fex'	string (default "")
+			local to buffer
+			{not in Vi}
+			{not available when compiled without the |+eval|
+			feature}
+	Expression which is evaluated to format a range of lines for the |gq|
+	operator.  When this option is empty 'formatprg' is used.
+
+	The |v:lnum|  variable holds the first line to be formatted.
+	The |v:count| variable holds the number of lines to be formatted.
+	The |v:char|  variable holds the character that is going to be
+		      inserted.  This can be empty.  Don't insert it yet!
+
+	Example: >
+		:set formatexpr=mylang#Format()
+<	This will invoke the mylang#Format() function in the
+	autoload/mylang.vim file in 'runtimepath'. |autoload|
+
+	The expression is also evaluated when 'textwidth' is set and adding
+	text beyond that limit.  This happens under the same conditions as
+	when internal formatting is used.  Make sure the cursor is kept in the
+	same spot relative to the text then!  The |mode()| function will
+	return "i" or "R" in this situation.  When the function returns
+	non-zero Vim will fall back to using the internal format mechanism.
+
+	The expression may be evaluated in the |sandbox|, see
+	|sandbox-option|.
+
+						*'fsync'* *'fs'*
+'fsync' 'fs'		boolean	(default on)
+			global
+			{not in Vi}
+	When on, the library function fsync() will be called after writing a
+	file.  This will flush a file to disk, ensuring that it is safely
+	written even on filesystems which do metadata-only journaling.  This
+	will force the harddrive to spin up on Linux systems running in laptop
+	mode, so it may be undesirable in some situations.  Be warned that
+	turning this off increases the chances of data loss after a crash.  On
+	systems without an fsync() implementation, this variable is always
+	off.
+	Also see 'swapsync' for controlling fsync() on swap files.
+
+				   *'gdefault'* *'gd'* *'nogdefault'* *'nogd'*
+'gdefault' 'gd'		boolean	(default off)
+			global
+			{not in Vi}
+	When on, the ":substitute" flag 'g' is default on.  This means that
+	all matches in a line are substituted instead of one.  When a 'g' flag
+	is given to a ":substitute" command, this will toggle the substitution
+	of all or one match.  See |complex-change|.
+
+		command		'gdefault' on	'gdefault' off	~
+		:s///		  subst. all	  subst. one
+		:s///g		  subst. one	  subst. all
+		:s///gg		  subst. all	  subst. one
+
+	NOTE: This option is reset when 'compatible' is set.
+
+						*'grepformat'* *'gfm'*
+'grepformat' 'gfm'	string	(default "%f:%l%m,%f  %l%m")
+			global
+			{not in Vi}
+	Format to recognize for the ":grep" command output.
+	This is a scanf-like string that uses the same format as the
+	'errorformat' option: see |errorformat|.
+
+						*'grepprg'* *'gp'*
+'grepprg' 'gp'		string	(default "grep -n ",
+					Unix: "grep -n $* /dev/null",
+					Win32: "findstr /n" or "grep -n",
+						      VMS: "SEARCH/NUMBERS ")
+			global or local to buffer |global-local|
+			{not in Vi}
+	Program to use for the |:grep| command.  This option may contain '%'
+	and '#' characters, which are expanded like when used in a command-
+	line.  The placeholder "$*" is allowed to specify where the arguments
+	will be included.  Environment variables are expanded |:set_env|.  See
+	|option-backslash| about including spaces and backslashes.
+	When your "grep" accepts the "-H" argument, use this to make ":grep"
+	also work well with a single file: >
+		:set grepprg=grep\ -nH
+<	Special value: When 'grepprg' is set to "internal" the |:grep| command
+	works like |:vimgrep|, |:lgrep| like |:lvimgrep|, |:grepadd| like
+	|:vimgrepadd| and |:lgrepadd| like |:lvimgrepadd|.
+	See also the section |:make_makeprg|, since most of the comments there
+	apply equally to 'grepprg'.
+	For Win32, the default is "findstr /n" if "findstr.exe" can be found,
+	otherwise it's "grep -n".
+	This option cannot be set from a |modeline| or in the |sandbox|, for
+	security reasons.
+
+			*'guicursor'* *'gcr'* *E545* *E546* *E548* *E549*
+'guicursor' 'gcr'	string	(default "n-v-c:block-Cursor/lCursor,
+					ve:ver35-Cursor,
+					o:hor50-Cursor,
+					i-ci:ver25-Cursor/lCursor,
+					r-cr:hor20-Cursor/lCursor,
+					sm:block-Cursor
+					-blinkwait175-blinkoff150-blinkon175",
+				for MS-DOS and Win32 console:
+					"n-v-c:block,o:hor50,i-ci:hor15,
+					r-cr:hor30,sm:block")
+			global
+			{not in Vi}
+			{only available when compiled with GUI enabled, and
+			for MS-DOS and Win32 console}
+	This option tells Vim what the cursor should look like in different
+	modes.  It fully works in the GUI.  In an MSDOS or Win32 console, only
+	the height of the cursor can be changed.  This can be done by
+	specifying a block cursor, or a percentage for a vertical or
+	horizontal cursor.
+	For a console the 't_SI' and 't_EI' escape sequences are used.
+
+	The option is a comma separated list of parts.  Each part consist of a
+	mode-list and an argument-list:
+		mode-list:argument-list,mode-list:argument-list,..
+	The mode-list is a dash separated list of these modes:
+		n	Normal mode
+		v	Visual mode
+		ve	Visual mode with 'selection' "exclusive" (same as 'v',
+			if not specified)
+		o	Operator-pending mode
+		i	Insert mode
+		r	Replace mode
+		c	Command-line Normal (append) mode
+		ci	Command-line Insert mode
+		cr	Command-line Replace mode
+		sm	showmatch in Insert mode
+		a	all modes
+	The argument-list is a dash separated list of these arguments:
+		hor{N}	horizontal bar, {N} percent of the character height
+		ver{N}	vertical bar, {N} percent of the character width
+		block	block cursor, fills the whole character
+			[only one of the above three should be present]
+		blinkwait{N}				*cursor-blinking*
+		blinkon{N}
+		blinkoff{N}
+			blink times for cursor: blinkwait is the delay before
+			the cursor starts blinking, blinkon is the time that
+			the cursor is shown and blinkoff is the time that the
+			cursor is not shown.  The times are in msec.  When one
+			of the numbers is zero, there is no blinking.  The
+			default is: "blinkwait700-blinkon400-blinkoff250".
+			These numbers are used for a missing entry.  This
+			means that blinking is enabled by default.  To switch
+			blinking off you can use "blinkon0".  The cursor only
+			blinks when Vim is waiting for input, not while
+			executing a command.
+			To make the cursor blink in an xterm, see
+			|xterm-blink|.
+		{group-name}
+			a highlight group name, that sets the color and font
+			for the cursor
+		{group-name}/{group-name}
+			Two highlight group names, the first is used when
+			no language mappings are used, the other when they
+			are. |language-mapping|
+
+	Examples of parts:
+	   n-c-v:block-nCursor	in Normal, Command-line and Visual mode, use a
+				block cursor with colors from the "nCursor"
+				highlight group
+	   i-ci:ver30-iCursor-blinkwait300-blinkon200-blinkoff150
+				In Insert and Command-line Insert mode, use a
+				30% vertical bar cursor with colors from the
+				"iCursor" highlight group.  Blink a bit
+				faster.
+
+	The 'a' mode is different.  It will set the given argument-list for
+	all modes.  It does not reset anything to defaults.  This can be used
+	to do a common setting for all modes.  For example, to switch off
+	blinking: "a:blinkon0"
+
+	Examples of cursor highlighting: >
+	    :highlight Cursor gui=reverse guifg=NONE guibg=NONE
+	    :highlight Cursor gui=NONE guifg=bg guibg=fg
+<
+					*'guifont'* *'gfn'*
+						   *E235* *E596* *E610* *E611*
+'guifont' 'gfn'		string	(default "")
+			global
+			{not in Vi}
+			{only available when compiled with GUI enabled}
+	This is a list of fonts which will be used for the GUI version of Vim.
+	In its simplest form the value is just one font name.  When
+	the font cannot be found you will get an error message.  To try other
+	font names a list can be specified, font names separated with commas.
+	The first valid font is used.
+
+	On systems where 'guifontset' is supported (X11) and 'guifontset' is
+	not empty, then 'guifont' is not used.
+
+	Spaces after a comma are ignored.  To include a comma in a font name
+	precede it with a backslash.  Setting an option requires an extra
+	backslash before a space and a backslash.  See also
+	|option-backslash|.  For example: >
+	    :set guifont=Screen15,\ 7x13,font\\,with\\,commas
+<	will make Vim try to use the font "Screen15" first, and if it fails it
+	will try to use "7x13" and then "font,with,commas" instead.
+
+	If none of the fonts can be loaded, Vim will keep the current setting.
+	If an empty font list is given, Vim will try using other resource
+	settings (for X, it will use the Vim.font resource), and finally it
+	will try some builtin default which should always be there ("7x13" in
+	the case of X).  The font names given should be "normal" fonts.  Vim
+	will try to find the related bold and italic fonts.
+
+	For Win32, GTK, Mac OS and Photon: >
+	    :set guifont=*
+<	will bring up a font requester, where you can pick the font you want.
+
+	The font name depends on the GUI used.  See |setting-guifont| for a
+	way to set 'guifont' for various systems.
+
+	For the GTK+ 2 GUI the font name looks like this: >
+	    :set guifont=Andale\ Mono\ 11
+<	That's all.  XLFDs are no longer accepted.
+
+	For Mac OSX you can use something like this: >
+	    :set guifont=Monaco:h10
+<	Also see 'macatsui', it can help fix display problems.
+								*E236*
+	Note that the fonts must be mono-spaced (all characters have the same
+	width).  An exception is GTK 2: all fonts are accepted, but
+	mono-spaced fonts look best.
+
+	To preview a font on X11, you might be able to use the "xfontsel"
+	program.  The "xlsfonts" program gives a list of all available fonts.
+
+	For the Win32 GUI					*E244* *E245*
+	- takes these options in the font name:
+		hXX - height is XX (points, can be floating-point)
+		wXX - width is XX (points, can be floating-point)
+		b   - bold
+		i   - italic
+		u   - underline
+		s   - strikeout
+		cXX - character set XX.  Valid charsets are: ANSI, ARABIC,
+		      BALTIC, CHINESEBIG5, DEFAULT, EASTEUROPE, GB2312, GREEK,
+		      HANGEUL, HEBREW, JOHAB, MAC, OEM, RUSSIAN, SHIFTJIS,
+		      SYMBOL, THAI, TURKISH, VIETNAMESE ANSI and BALTIC.
+		      Normally you would use "cDEFAULT".
+
+	  Use a ':' to separate the options.
+	- A '_' can be used in the place of a space, so you don't need to use
+	  backslashes to escape the spaces.
+	- Examples: >
+	    :set guifont=courier_new:h12:w5:b:cRUSSIAN
+	    :set guifont=Andale_Mono:h7.5:w4.5
+<	See also |font-sizes|.
+
+					*'guifontset'* *'gfs'*
+					*E250* *E252* *E234* *E597* *E598*
+'guifontset' 'gfs'	string	(default "")
+			global
+			{not in Vi}
+			{only available when compiled with GUI enabled and
+			with the |+xfontset| feature}
+			{not available in the GTK+ 2 GUI}
+	When not empty, specifies two (or more) fonts to be used.  The first
+	one for normal English, the second one for your special language.  See
+	|xfontset|.
+	Setting this option also means that all font names will be handled as
+	a fontset name.  Also the ones used for the "font" argument of the
+	|:highlight| command.
+	The fonts must match with the current locale.  If fonts for the
+	character sets that the current locale uses are not included, setting
+	'guifontset' will fail.
+	Note the difference between 'guifont' and 'guifontset': In 'guifont'
+	the comma-separated names are alternative names, one of which will be
+	used.  In 'guifontset' the whole string is one fontset name,
+	including the commas.  It is not possible to specify alternative
+	fontset names.
+	This example works on many X11 systems: >
+		:set guifontset=-*-*-medium-r-normal--16-*-*-*-c-*-*-*
+<
+				*'guifontwide'* *'gfw'* *E231* *E533* *E534*
+'guifontwide' 'gfw'	string	(default "")
+			global
+			{not in Vi}
+			{only available when compiled with GUI enabled}
+	When not empty, specifies a comma-separated list of fonts to be used
+	for double-width characters.  The first font that can be loaded is
+	used.
+	Note: The size of these fonts must be exactly twice as wide as the one
+	specified with 'guifont' and the same height.
+
+	All GUI versions but GTK+ 2:
+
+	'guifontwide' is only used when 'encoding' is set to "utf-8" and
+	'guifontset' is empty or invalid.
+	When 'guifont' is set and a valid font is found in it and
+	'guifontwide' is empty Vim will attempt to find a matching
+	double-width font and set 'guifontwide' to it.
+
+	GTK+ 2 GUI only:			*guifontwide_gtk2*
+
+	If set and valid, 'guifontwide' is always used for double width
+	characters, even if 'encoding' is not set to "utf-8".
+	Vim does not attempt to find an appropriate value for 'guifontwide'
+	automatically.  If 'guifontwide' is empty Pango/Xft will choose the
+	font for characters not available in 'guifont'.  Thus you do not need
+	to set 'guifontwide' at all unless you want to override the choice
+	made by Pango/Xft.
+
+						*'guiheadroom'* *'ghr'*
+'guiheadroom' 'ghr'	number	(default 50)
+			global
+			{not in Vi} {only for GTK and X11 GUI}
+	The number of pixels subtracted from the screen height when fitting
+	the GUI window on the screen.  Set this before the GUI is started,
+	e.g., in your |gvimrc| file.  When zero, the whole screen height will
+	be used by the window.  When positive, the specified number of pixel
+	lines will be left for window decorations and other items on the
+	screen.  Set it to a negative value to allow windows taller than the
+	screen.
+
+						*'guioptions'* *'go'*
+'guioptions' 'go'	string	(default "gmrLtT"   (MS-Windows),
+					 "agimrLtT" (GTK, Motif and Athena))
+			global
+			{not in Vi}
+			{only available when compiled with GUI enabled}
+	This option only has an effect in the GUI version of Vim.  It is a
+	sequence of letters which describes what components and options of the
+	GUI should be used.
+	To avoid problems with flags that are added in the future, use the
+	"+=" and "-=" feature of ":set" |add-option-flags|.
+
+	Valid letters are as follows:
+							*guioptions_a* *'go-a'*
+	  'a'	Autoselect:  If present, then whenever VISUAL mode is started,
+		or the Visual area extended, Vim tries to become the owner of
+		the windowing system's global selection.  This means that the
+		Visually highlighted text is available for pasting into other
+		applications as well as into Vim itself.  When the Visual mode
+		ends, possibly due to an operation on the text, or when an
+		application wants to paste the selection, the highlighted text
+		is automatically yanked into the "* selection register.
+		Thus the selection is still available for pasting into other
+		applications after the VISUAL mode has ended.
+		    If not present, then Vim won't become the owner of the
+		windowing system's global selection unless explicitly told to
+		by a yank or delete operation for the "* register.
+		The same applies to the modeless selection.
+								*'go-A'*
+	  'A'	Autoselect for the modeless selection.  Like 'a', but only
+		applies to the modeless selection.
+
+		    'guioptions'   autoselect Visual  autoselect modeless ~
+			 ""		 -			 -
+			 "a"		yes			yes
+			 "A"		 -			yes
+			 "aA"		yes			yes
+
+								*'go-c'*
+	  'c'	Use console dialogs instead of popup dialogs for simple
+		choices.
+								*'go-e'*
+	  'e'	Add tab pages when indicated with 'showtabline'.
+		'guitablabel' can be used to change the text in the labels.
+		When 'e' is missing a non-GUI tab pages line may be used.
+		The GUI tabs are only supported on some systems, currently
+		GTK, Motif and MS-Windows.
+								*'go-f'*
+	  'f'	Foreground: Don't use fork() to detach the GUI from the shell
+		where it was started.  Use this for programs that wait for the
+		editor to finish (e.g., an e-mail program).  Alternatively you
+		can use "gvim -f" or ":gui -f" to start the GUI in the
+		foreground.  |gui-fork|
+		Note: Set this option in the vimrc file.  The forking may have
+		happened already when the |gvimrc| file is read.
+								*'go-i'*
+	  'i'	Use a Vim icon.  For GTK with KDE it is used in the left-upper
+		corner of the window.  It's black&white on non-GTK, because of
+		limitations of X11.  For a color icon, see |X11-icon|.
+	  							*'go-m'*
+	  'm'	Menu bar is present.
+	  							*'go-M'*
+	  'M'	The system menu "$VIMRUNTIME/menu.vim" is not sourced.  Note
+		that this flag must be added in the .vimrc file, before
+		switching on syntax or filetype recognition (when the |gvimrc|
+		file is sourced the system menu has already been loaded; the
+		":syntax on" and ":filetype on" commands load the menu too).
+	  							*'go-g'*
+	  'g'	Grey menu items: Make menu items that are not active grey.  If
+		'g' is not included inactive menu items are not shown at all.
+		Exception: Athena will always use grey menu items.
+								*'go-t'*
+	  't'	Include tearoff menu items.  Currently only works for Win32,
+		GTK+, and Motif 1.2 GUI.
+								*'go-T'*
+	  'T'	Include Toolbar.  Currently only in Win32, GTK+, Motif, Photon
+		and Athena GUIs.
+								*'go-r'*
+	  'r'	Right-hand scrollbar is always present.
+	  							*'go-R'*
+	  'R'	Right-hand scrollbar is present when there is a vertically
+		split window.
+	  							*'go-l'*
+	  'l'	Left-hand scrollbar is always present.
+	  							*'go-L'*
+	  'L'	Left-hand scrollbar is present when there is a vertically
+		split window.
+								*'go-b'*
+	  'b'	Bottom (horizontal) scrollbar is present.  Its size depends on
+		the longest visible line, or on the cursor line if the 'h'
+		flag is included. |gui-horiz-scroll|
+	  							*'go-h'*
+	  'h'	Limit horizontal scrollbar size to the length of the cursor
+		line.  Reduces computations. |gui-horiz-scroll|
+
+	And yes, you may even have scrollbars on the left AND the right if
+	you really want to :-).  See |gui-scrollbars| for more information.
+
+	  							*'go-v'*
+	  'v'	Use a vertical button layout for dialogs.  When not included,
+		a horizontal layout is preferred, but when it doesn't fit a
+		vertical layout is used anyway.
+	  							*'go-p'*
+	  'p'	Use Pointer callbacks for X11 GUI.  This is required for some
+		window managers.  If the cursor is not blinking or hollow at
+		the right moment, try adding this flag.  This must be done
+		before starting the GUI.  Set it in your |gvimrc|.  Adding or
+		removing it after the GUI has started has no effect.
+	  							*'go-F'*
+	  'F'	Add a footer.  Only for Motif.  See |gui-footer|.
+
+
+						*'guipty'* *'noguipty'*
+'guipty'		boolean	(default on)
+			global
+			{not in Vi}
+			{only available when compiled with GUI enabled}
+	Only in the GUI: If on, an attempt is made to open a pseudo-tty for
+	I/O to/from shell commands.  See |gui-pty|.
+
+						*'guitablabel'* *'gtl'*
+'guitablabel' 'gtl'	string	(default empty)
+			global
+			{not in Vi}
+			{only available when compiled with GUI enabled and
+			with the +windows feature}
+	When nonempty describes the text to use in a label of the GUI tab
+	pages line.  When empty and when the result is empty Vim will use a
+	default label.  See |setting-guitablabel| for more info.
+
+	The format of this option is like that of 'statusline'.
+	'guitabtooltip' is used for the tooltip, see below.
+
+	Only used when the GUI tab pages line is displayed.  'e' must be
+	present in 'guioptions'.  For the non-GUI tab pages line 'tabline' is
+	used.
+
+						*'guitabtooltip'* *'gtt'*
+'guitabtooltip' 'gtt'	string	(default empty)
+			global
+			{not in Vi}
+			{only available when compiled with GUI enabled and
+			with the +windows feature}
+	When nonempty describes the text to use in a tooltip for the GUI tab
+	pages line.  When empty Vim will use a default tooltip.
+	This option is otherwise just like 'guitablabel' above.
+
+
+						*'helpfile'* *'hf'*
+'helpfile' 'hf'		string	(default (MSDOS)  "$VIMRUNTIME\doc\help.txt"
+					 (others) "$VIMRUNTIME/doc/help.txt")
+			global
+			{not in Vi}
+	Name of the main help file.  All distributed help files should be
+	placed together in one directory.  Additionally, all "doc" directories
+	in 'runtimepath' will be used.
+	Environment variables are expanded |:set_env|.  For example:
+	"$VIMRUNTIME/doc/help.txt".  If $VIMRUNTIME is not set, $VIM is also
+	tried.  Also see |$VIMRUNTIME| and |option-backslash| about including
+	spaces and backslashes.
+	This option cannot be set from a |modeline| or in the |sandbox|, for
+	security reasons.
+
+						*'helpheight'* *'hh'*
+'helpheight' 'hh'	number	(default 20)
+			global
+			{not in Vi}
+			{not available when compiled without the +windows
+			feature}
+	Minimal initial height of the help window when it is opened with the
+	":help" command.  The initial height of the help window is half of the
+	current window, or (when the 'ea' option is on) the same as other
+	windows.  When the height is less than 'helpheight', the height is
+	set to 'helpheight'.  Set to zero to disable.
+
+						*'helplang'* *'hlg'*
+'helplang' 'hlg'	string	(default: messages language or empty)
+			global
+			{only available when compiled with the |+multi_lang|
+			feature}
+			{not in Vi}
+	Comma separated list of languages.  Vim will use the first language
+	for which the desired help can be found.  The English help will always
+	be used as a last resort.  You can add "en" to prefer English over
+	another language, but that will only find tags that exist in that
+	language and not in the English help.
+	Example: >
+		:set helplang=de,it
+<	This will first search German, then Italian and finally English help
+	files.
+	When using |CTRL-]| and ":help!" in a non-English help file Vim will
+	try to find the tag in the current language before using this option.
+	See |help-translated|.
+
+				     *'hidden'* *'hid'* *'nohidden'* *'nohid'*
+'hidden' 'hid'		boolean	(default off)
+			global
+			{not in Vi}
+	When off a buffer is unloaded when it is |abandon|ed.  When on a
+	buffer becomes hidden when it is |abandon|ed.  If the buffer is still
+	displayed in another window, it does not become hidden, of course.
+	The commands that move through the buffer list sometimes make a buffer
+	hidden although the 'hidden' option is off: When the buffer is
+	modified, 'autowrite' is off or writing is not possible, and the '!'
+	flag was used.  See also |windows.txt|.
+	To only make one buffer hidden use the 'bufhidden' option.
+	This option is set for one command with ":hide {command}" |:hide|.
+	WARNING: It's easy to forget that you have changes in hidden buffers.
+	Think twice when using ":q!" or ":qa!".
+
+						*'highlight'* *'hl'*
+'highlight' 'hl'	string	(default (as a single string):
+				     "8:SpecialKey,@:NonText,d:Directory,
+				     e:ErrorMsg,i:IncSearch,l:Search,m:MoreMsg,
+				     M:ModeMsg,n:LineNr,r:Question,
+				     s:StatusLine,S:StatusLineNC,c:VertSplit,
+				     t:Title,v:Visual,w:WarningMsg,W:WildMenu,
+				     f:Folded,F:FoldColumn,A:DiffAdd,
+				     C:DiffChange,D:DiffDelete,T:DiffText,
+				     >:SignColumn,B:SpellBad,P:SpellCap,
+				     R:SpellRare,L:SpellLocal,
+				     +:Pmenu,=:PmenuSel,
+				     x:PmenuSbar,X:PmenuThumb")
+			global
+			{not in Vi}
+	This option can be used to set highlighting mode for various
+	occasions.  It is a comma separated list of character pairs.  The
+	first character in a pair gives the occasion, the second the mode to
+	use for that occasion.  The occasions are:
+	|hl-SpecialKey|	 8  Meta and special keys listed with ":map"
+	|hl-NonText|	 @  '~' and '@' at the end of the window and
+			    characters from 'showbreak'
+	|hl-Directory|	 d  directories in CTRL-D listing and other special
+			    things in listings
+	|hl-ErrorMsg|	 e  error messages
+			 h  (obsolete, ignored)
+	|hl-IncSearch|	 i  'incsearch' highlighting
+	|hl-Search|	 l  last search pattern highlighting (see 'hlsearch')
+	|hl-MoreMsg|	 m  |more-prompt|
+	|hl-ModeMsg|	 M  Mode (e.g., "-- INSERT --")
+	|hl-LineNr|	 n  line number for ":number" and ":#" commands
+	|hl-Question|	 r  |hit-enter| prompt and yes/no questions
+	|hl-StatusLine|	 s  status line of current window |status-line|
+	|hl-StatusLineNC| S  status lines of not-current windows
+	|hl-Title|	 t  Titles for output from ":set all", ":autocmd" etc.
+	|hl-VertSplit|	 c  column used to separate vertically split windows
+	|hl-Visual|	 v  Visual mode
+	|hl-VisualNOS|	 V  Visual mode when Vim does is "Not Owning the
+			    Selection" Only X11 Gui's |gui-x11| and
+			    |xterm-clipboard|.
+	|hl-WarningMsg|	 w  warning messages
+	|hl-WildMenu|	 W  wildcard matches displayed for 'wildmenu'
+	|hl-Folded|	 f  line used for closed folds
+	|hl-FoldColumn|	 F  'foldcolumn'
+	|hl-DiffAdd|	 A  added line in diff mode
+	|hl-DiffChange|	 C  changed line in diff mode
+	|hl-DiffDelete|	 D  deleted line in diff mode
+	|hl-DiffText|	 T  inserted text in diff mode
+	|hl-SignColumn|	 >  column used for |signs|
+	|hl-SpellBad|	 B  misspelled word |spell|
+	|hl-SpellCap|	 P  word that should start with capital|spell|
+	|hl-SpellRare|	 R  rare word |spell|
+	|hl-SpellLocal|	 L  word from other region |spell|
+	|hl-Pmenu|       +  popup menu normal line
+	|hl-PmenuSel|    =  popup menu normal line
+	|hl-PmenuSbar|   x  popup menu scrollbar
+	|hl-PmenuThumb|  X  popup menu scrollbar thumb
+
+	The display modes are:
+		r	reverse		(termcap entry "mr" and "me")
+		i	italic		(termcap entry "ZH" and "ZR")
+		b	bold		(termcap entry "md" and "me")
+		s	standout	(termcap entry "so" and "se")
+		u	underline	(termcap entry "us" and "ue")
+		c	undercurl	(termcap entry "Cs" and "Ce")
+		n	no highlighting
+		-	no highlighting
+		:	use a highlight group
+	The default is used for occasions that are not included.
+	If you want to change what the display modes do, see |dos-colors|
+	for an example.
+	When using the ':' display mode, this must be followed by the name of
+	a highlight group.  A highlight group can be used to define any type
+	of highlighting, including using color.  See |:highlight| on how to
+	define one.  The default uses a different group for each occasion.
+	See |highlight-default| for the default highlight groups.
+
+				 *'hlsearch'* *'hls'* *'nohlsearch'* *'nohls'*
+'hlsearch' 'hls'	boolean	(default off)
+			global
+			{not in Vi}
+			{not available when compiled without the
+			|+extra_search| feature}
+	When there is a previous search pattern, highlight all its matches.
+	The type of highlighting used can be set with the 'l' occasion in the
+	'highlight' option.  This uses the "Search" highlight group by
+	default.  Note that only the matching text is highlighted, any offsets
+	are not applied.
+	See also: 'incsearch' and |:match|.
+	When you get bored looking at the highlighted matches, you can turn it
+	off with |:nohlsearch|.  As soon as you use a search command, the
+	highlighting comes back.
+	When the search pattern can match an end-of-line, Vim will try to
+	highlight all of the matched text.  However, this depends on where the
+	search starts.  This will be the first line in the window or the first
+	line below a closed fold.  A match in a previous line which is not
+	drawn may not continue in a newly drawn line.
+	NOTE: This option is reset when 'compatible' is set.
+
+						*'history'* *'hi'*
+'history' 'hi'		number	(Vim default: 20, Vi default: 0)
+			global
+			{not in Vi}
+	A history of ":" commands, and a history of previous search patterns
+	are remembered.  This option decides how many entries may be stored in
+	each of these histories (see |cmdline-editing|).
+	NOTE: This option is set to the Vi default value when 'compatible' is
+	set and to the Vim default value when 'compatible' is reset.
+
+					 *'hkmap'* *'hk'* *'nohkmap'* *'nohk'*
+'hkmap' 'hk'		boolean (default off)
+			global
+			{not in Vi}
+			{only available when compiled with the |+rightleft|
+			feature}
+	When on, the keyboard is mapped for the Hebrew character set.
+	Normally you would set 'allowrevins' and use CTRL-_ in insert mode to
+	toggle this option.  See |rileft.txt|.
+	NOTE: This option is reset when 'compatible' is set.
+
+				 *'hkmapp'* *'hkp'* *'nohkmapp'* *'nohkp'*
+'hkmapp' 'hkp'		boolean (default off)
+			global
+			{not in Vi}
+			{only available when compiled with the |+rightleft|
+			feature}
+	When on, phonetic keyboard mapping is used.  'hkmap' must also be on.
+	This is useful if you have a non-Hebrew keyboard.
+	See |rileft.txt|.
+	NOTE: This option is reset when 'compatible' is set.
+
+						*'icon'* *'noicon'*
+'icon'			boolean	(default off, on when title can be restored)
+			global
+			{not in Vi}
+			{not available when compiled without the |+title|
+			feature}
+	When on, the icon text of the window will be set to the value of
+	'iconstring' (if it is not empty), or to the name of the file
+	currently being edited.  Only the last part of the name is used.
+	Overridden by the 'iconstring' option.
+	Only works if the terminal supports setting window icons (currently
+	only X11 GUI and terminals with a non-empty 't_IS' option - these are
+	Unix xterm and iris-ansi by default, where 't_IS' is taken from the
+	builtin termcap).
+	When Vim was compiled with HAVE_X11 defined, the original icon will be
+	restored if possible |X11|.  See |X11-icon| for changing the icon on
+	X11.
+
+						*'iconstring'*
+'iconstring'		string	(default "")
+			global
+			{not in Vi}
+			{not available when compiled without the |+title|
+			feature}
+	When this option is not empty, it will be used for the icon text of
+	the window.  This happens only when the 'icon' option is on.
+	Only works if the terminal supports setting window icon text
+	(currently only X11 GUI and terminals with a non-empty 't_IS' option).
+	Does not work for MS Windows.
+	When Vim was compiled with HAVE_X11 defined, the original icon will be
+	restored if possible |X11|.
+	When this option contains printf-style '%' items, they will be
+	expanded according to the rules used for 'statusline'.  See
+	'titlestring' for example settings.
+	{not available when compiled without the |+statusline| feature}
+
+			*'ignorecase'* *'ic'* *'noignorecase'* *'noic'*
+'ignorecase' 'ic'	boolean	(default off)
+			global
+	Ignore case in search patterns.  Also used when searching in the tags
+	file.
+	Also see 'smartcase'.
+	Can be overruled by using "\c" or "\C" in the pattern, see
+	|/ignorecase|.
+
+						*'imactivatekey'* *'imak'*
+'imactivatekey' 'imak'	string (default "")
+			global
+			{not in Vi}
+			{only available when compiled with |+xim| and
+			|+GUI_GTK|}
+	Specifies the key that your Input Method in X-Windows uses for
+	activation.  When this is specified correctly, vim can fully control
+	IM with 'imcmdline', 'iminsert' and 'imsearch'.
+	You can't use this option to change the activation key, the option
+	tells Vim what the key is.
+	Format:
+		[MODIFIER_FLAG-]KEY_STRING
+
+	These characters can be used for MODIFIER_FLAG (case is ignored):
+		S	    Shift key
+		L	    Lock key
+		C	    Control key
+		1	    Mod1 key
+		2	    Mod2 key
+		3	    Mod3 key
+		4	    Mod4 key
+		5	    Mod5 key
+	Combinations are allowed, for example "S-C-space" or "SC-space" are
+	both shift+ctrl+space.
+	See <X11/keysymdef.h> and XStringToKeysym for KEY_STRING.
+
+	Example: >
+		:set imactivatekey=S-space
+<	"S-space" means shift+space.  This is the activation key for kinput2 +
+	canna (Japanese), and ami (Korean).
+
+				*'imcmdline'* *'imc'* *'noimcmdline'* *'noimc'*
+'imcmdline' 'imc'	boolean (default off)
+			global
+			{not in Vi}
+			{only available when compiled with the |+xim|
+			|+multi_byte_ime| or |global-ime| feature}
+	When set the Input Method is always on when starting to edit a command
+	line, unless entering a search pattern (see 'imsearch' for that).
+	Setting this option is useful when your input method allows entering
+	English characters directly, e.g., when it's used to type accented
+	characters with dead keys.
+
+				*'imdisable'* *'imd'* *'nodisable'* *'noimd'*
+'imdisable' 'imd'	boolean (default off, on for some systems (SGI))
+			global
+			{not in Vi}
+			{only available when compiled with the |+xim|
+			|+multi_byte_ime| or |global-ime| feature}
+	When set the Input Method is never used.  This is useful to disable
+	the IM when it doesn't work properly.
+	Currently this option is on by default for SGI/IRIX machines.  This
+	may change in later releases.
+
+						*'iminsert'* *'imi'*
+'iminsert' 'imi'	number (default 0, 2 when an input method is supported)
+			local to buffer
+			{not in Vi}
+	Specifies whether :lmap or an Input Method (IM) is to be used in
+	Insert mode.  Valid values:
+		0	:lmap is off and IM is off
+		1	:lmap is ON and IM is off
+		2	:lmap is off and IM is ON
+	2 is available only when compiled with the |+multi_byte_ime|, |+xim|
+	or |global-ime|.
+	To always reset the option to zero when leaving Insert mode with <Esc>
+	this can be used: >
+		:inoremap <ESC> <ESC>:set iminsert=0<CR>
+<	This makes :lmap and IM turn off automatically when leaving Insert
+	mode.
+	Note that this option changes when using CTRL-^ in Insert mode
+	|i_CTRL-^|.
+	The value is set to 1 when setting 'keymap' to a valid keymap name.
+	It is also used for the argument of commands like "r" and "f".
+	The value 0 may not work correctly with Athena and Motif with some XIM
+	methods.  Use 'imdisable' to disable XIM then.
+
+						*'imsearch'* *'ims'*
+'imsearch' 'ims'	number (default 0, 2 when an input method is supported)
+			local to buffer
+			{not in Vi}
+	Specifies whether :lmap or an Input Method (IM) is to be used when
+	entering a search pattern.  Valid values:
+		-1	the value of 'iminsert' is used, makes it look like
+			'iminsert' is also used when typing a search pattern
+		0	:lmap is off and IM is off
+		1	:lmap is ON and IM is off
+		2	:lmap is off and IM is ON
+	Note that this option changes when using CTRL-^ in Command-line mode
+	|c_CTRL-^|.
+	The value is set to 1 when it is not -1 and setting the 'keymap'
+	option to a valid keymap name.
+	The value 0 may not work correctly with Athena and Motif with some XIM
+	methods.  Use 'imdisable' to disable XIM then.
+
+						*'include'* *'inc'*
+'include' 'inc'		string	(default "^\s*#\s*include")
+			global or local to buffer |global-local|
+			{not in Vi}
+			{not available when compiled without the
+			|+find_in_path| feature}
+	Pattern to be used to find an include command.  It is a search
+	pattern, just like for the "/" command (See |pattern|).  The default
+	value is for C programs.  This option is used for the commands "[i",
+	"]I", "[d", etc.
+	Normally the 'isfname' option is used to recognize the file name that
+	comes after the matched pattern.  But if "\zs" appears in the pattern
+	then the text matched from "\zs" to the end, or until "\ze" if it
+	appears, is used as the file name.  Use this to include characters
+	that are not in 'isfname', such as a space.  You can then use
+	'includeexpr' to process the matched text.
+	See |option-backslash| about including spaces and backslashes.
+
+						*'includeexpr'* *'inex'*
+'includeexpr' 'inex'	string	(default "")
+			local to buffer
+			{not in Vi}
+			{not available when compiled without the
+			|+find_in_path| or |+eval| feature}
+	Expression to be used to transform the string found with the 'include'
+	option to a file name.  Mostly useful to change "." to "/" for Java: >
+		:set includeexpr=substitute(v:fname,'\\.','/','g')
+<	The "v:fname" variable will be set to the file name that was detected.
+
+	Also used for the |gf| command if an unmodified file name can't be
+	found.  Allows doing "gf" on the name after an 'include' statement.
+	Also used for |<cfile>|.
+
+	The expression may be evaluated in the |sandbox|, see
+	|sandbox-option|.
+
+	It is not allowed to change text or jump to another window while
+	evaluating 'includeexpr' |textlock|.
+
+				 *'incsearch'* *'is'* *'noincsearch'* *'nois'*
+'incsearch' 'is'	boolean	(default off)
+			global
+			{not in Vi}
+			{not available when compiled without the
+			|+extra_search| feature}
+	While typing a search command, show where the pattern, as it was typed
+	so far, matches.  The matched string is highlighted.  If the pattern
+	is invalid or not found, nothing is shown.  The screen will be updated
+	often, this is only useful on fast terminals.
+	Note that the match will be shown, but the cursor will return to its
+	original position when no match is found and when pressing <Esc>.  You
+	still need to finish the search command with <Enter> to move the
+	cursor to the match.
+	The highlighting can be set with the 'i' flag in 'highlight'.
+	See also: 'hlsearch'.
+	CTRL-L can be used to add one character from after the current match
+	to the command line.
+	CTRL-R CTRL-W can be used to add the word at the end of the current
+	match, excluding the characters that were already typed.
+	NOTE: This option is reset when 'compatible' is set.
+
+						*'indentexpr'* *'inde'*
+'indentexpr' 'inde'	string	(default "")
+			local to buffer
+			{not in Vi}
+			{not available when compiled without the |+cindent|
+			or |+eval| features}
+	Expression which is evaluated to obtain the proper indent for a line.
+	It is used when a new line is created, for the |=| operator and
+	in Insert mode as specified with the 'indentkeys' option.
+	When this option is not empty, it overrules the 'cindent' and
+	'smartindent' indenting.
+	When 'paste' is set this option is not used for indenting.
+	The expression is evaluated with |v:lnum| set to the line number for
+	which the indent is to be computed.  The cursor is also in this line
+	when the expression is evaluated (but it may be moved around).
+	The expression must return the number of spaces worth of indent.  It
+	can return "-1" to keep the current indent (this means 'autoindent' is
+	used for the indent).
+	Functions useful for computing the indent are |indent()|, |cindent()|
+	and |lispindent()|.
+	The evaluation of the expression must not have side effects!  It must
+	not change the text, jump to another window, etc.  Afterwards the
+	cursor position is always restored, thus the cursor may be moved.
+	Normally this option would be set to call a function: >
+		:set indentexpr=GetMyIndent()
+<	Error messages will be suppressed, unless the 'debug' option contains
+	"msg".
+	See |indent-expression|.
+	NOTE: This option is made empty when 'compatible' is set.
+
+	The expression may be evaluated in the |sandbox|, see
+	|sandbox-option|.
+
+	It is not allowed to change text or jump to another window while
+	evaluating 'indentexpr' |textlock|.
+
+
+						*'indentkeys'* *'indk'*
+'indentkeys' 'indk'	string	(default "0{,0},:,0#,!^F,o,O,e")
+			local to buffer
+			{not in Vi}
+			{not available when compiled without the |+cindent|
+			feature}
+	A list of keys that, when typed in Insert mode, cause reindenting of
+	the current line.  Only happens if 'indentexpr' isn't empty.
+	The format is identical to 'cinkeys', see |indentkeys-format|.
+	See |C-indenting| and |indent-expression|.
+
+			*'infercase'* *'inf'* *'noinfercase'* *'noinf'*
+'infercase' 'inf'	boolean	(default off)
+			local to buffer
+			{not in Vi}
+	When doing keyword completion in insert mode |ins-completion|, and
+	'ignorecase' is also on, the case of the match is adjusted.  If the
+	typed text contains a lowercase letter where the match has an upper
+	case letter, the completed part is made lowercase.  If the typed text
+	has no lowercase letters and the match has a lowercase letter where
+	the typed text has an uppercase letter, and there is a letter before
+	it, the completed part is made uppercase.
+
+			*'insertmode'* *'im'* *'noinsertmode'* *'noim'*
+'insertmode' 'im'	boolean	(default off)
+			global
+			{not in Vi}
+	Makes Vim work in a way that Insert mode is the default mode.  Useful
+	if you want to use Vim as a modeless editor.  Used for |evim|.
+	These Insert mode commands will be useful:
+	- Use the cursor keys to move around.
+	- Use CTRL-O to execute one Normal mode command |i_CTRL-O|).  When
+	  this is a mapping, it is executed as if 'insertmode' was off.
+	  Normal mode remains active until the mapping is finished.
+	- Use CTRL-L to execute a number of Normal mode commands, then use
+	  <Esc> to get back to Insert mode.  Note that CTRL-L moves the cursor
+	  left, like <Esc> does when 'insertmode' isn't set.  |i_CTRL-L|
+
+	These items change when 'insertmode' is set:
+	- when starting to edit of a file, Vim goes to Insert mode.
+	- <Esc> in Insert mode is a no-op and beeps.
+	- <Esc> in Normal mode makes Vim go to Insert mode.
+	- CTRL-L in Insert mode is a command, it is not inserted.
+	- CTRL-Z in Insert mode suspends Vim, see |CTRL-Z|.	*i_CTRL-Z*
+	However, when <Esc> is used inside a mapping, it behaves like
+	'insertmode' was not set.  This was done to be able to use the same
+	mappings with 'insertmode' set or not set.
+	When executing commands with |:normal| 'insertmode' is not used.
+
+	NOTE: This option is reset when 'compatible' is set.
+
+						*'isfname'* *'isf'*
+'isfname' 'isf'		string	(default for MS-DOS, Win32 and OS/2:
+			     "@,48-57,/,\,.,-,_,+,,,#,$,%,{,},[,],:,@-@,!,~,="
+			    for AMIGA: "@,48-57,/,.,-,_,+,,,$,:"
+			    for VMS: "@,48-57,/,.,-,_,+,,,#,$,%,<,>,[,],:,;,~"
+			    for OS/390: "@,240-249,/,.,-,_,+,,,#,$,%,~,="
+			    otherwise: "@,48-57,/,.,-,_,+,,,#,$,%,~,=")
+			global
+			{not in Vi}
+	The characters specified by this option are included in file names and
+	path names.  Filenames are used for commands like "gf", "[i" and in
+	the tags file.  It is also used for "\f" in a |pattern|.
+	Multi-byte characters 256 and above are always included, only the
+	characters up to 255 are specified with this option.
+	For UTF-8 the characters 0xa0 to 0xff are included as well.
+
+	Note that on systems using a backslash as path separator, Vim tries to
+	do its best to make it work as you would expect.  That is a bit
+	tricky, since Vi originally used the backslash to escape special
+	characters.  Vim will not remove a backslash in front of a normal file
+	name character on these systems, but it will on Unix and alikes.  The
+	'&' and '^' are not included by default, because these are special for
+	cmd.exe.
+
+	The format of this option is a list of parts, separated with commas.
+	Each part can be a single character number or a range.  A range is two
+	character numbers with '-' in between.  A character number can be a
+	decimal number between 0 and 255 or the ASCII character itself (does
+	not work for digits).  Example:
+		"_,-,128-140,#-43"	(include '_' and '-' and the range
+					128 to 140 and '#' to 43)
+	If a part starts with '^', the following character number or range
+	will be excluded from the option.  The option is interpreted from left
+	to right.  Put the excluded character after the range where it is
+	included.  To include '^' itself use it as the last character of the
+	option or the end of a range.  Example:
+		"^a-z,#,^"	(exclude 'a' to 'z', include '#' and '^')
+	If the character is '@', all characters where isalpha() returns TRUE
+	are included.  Normally these are the characters a to z and A to Z,
+	plus accented characters.  To include '@' itself use "@-@".  Examples:
+		"@,^a-z"	All alphabetic characters, excluding lower
+				case letters.
+		"a-z,A-Z,@-@"	All letters plus the '@' character.
+	A comma can be included by using it where a character number is
+	expected.  Example:
+		"48-57,,,_"	Digits, comma and underscore.
+	A comma can be excluded by prepending a '^'.  Example:
+		" -~,^,,9"	All characters from space to '~', excluding
+				comma, plus <Tab>.
+	See |option-backslash| about including spaces and backslashes.
+
+						*'isident'* *'isi'*
+'isident' 'isi'		string	(default for MS-DOS, Win32 and OS/2:
+					   "@,48-57,_,128-167,224-235"
+				otherwise: "@,48-57,_,192-255")
+			global
+			{not in Vi}
+	The characters given by this option are included in identifiers.
+	Identifiers are used in recognizing environment variables and after a
+	match of the 'define' option.  It is also used for "\i" in a
+	|pattern|.  See 'isfname' for a description of the format of this
+	option.
+	Careful: If you change this option, it might break expanding
+	environment variables.  E.g., when '/' is included and Vim tries to
+	expand "$HOME/.viminfo".  Maybe you should change 'iskeyword' instead.
+
+						*'iskeyword'* *'isk'*
+'iskeyword' 'isk'	string (Vim default for MS-DOS and Win32:
+					    "@,48-57,_,128-167,224-235"
+				   otherwise:  "@,48-57,_,192-255"
+				Vi default: "@,48-57,_")
+			local to buffer
+			{not in Vi}
+	Keywords are used in searching and recognizing with many commands:
+	"w", "*", "[i", etc.  It is also used for "\k" in a |pattern|.  See
+	'isfname' for a description of the format of this option.  For C
+	programs you could use "a-z,A-Z,48-57,_,.,-,>".
+	For a help file it is set to all non-blank printable characters except
+	'*', '"' and '|' (so that CTRL-] on a command finds the help for that
+	command).
+	When the 'lisp' option is on the '-' character is always included.
+	NOTE: This option is set to the Vi default value when 'compatible' is
+	set and to the Vim default value when 'compatible' is reset.
+
+						*'isprint'* *'isp'*
+'isprint' 'isp'	string	(default for MS-DOS, Win32, OS/2 and Macintosh:
+				"@,~-255"; otherwise: "@,161-255")
+			global
+			{not in Vi}
+	The characters given by this option are displayed directly on the
+	screen.  It is also used for "\p" in a |pattern|.  The characters from
+	space (ASCII 32) to '~' (ASCII 126) are always displayed directly,
+	even when they are not included in 'isprint' or excluded.  See
+	'isfname' for a description of the format of this option.
+
+	Non-printable characters are displayed with two characters:
+		  0 -  31	"^@" - "^_"
+		 32 - 126	always single characters
+		   127		"^?"
+		128 - 159	"~@" - "~_"
+		160 - 254	"| " - "|~"
+		   255		"~?"
+	When 'encoding' is a Unicode one, illegal bytes from 128 to 255 are
+	displayed as <xx>, with the hexadecimal value of the byte.
+	When 'display' contains "uhex" all unprintable characters are
+	displayed as <xx>.
+	The NonText highlighting will be used for unprintable characters.
+	|hl-NonText|
+
+	Multi-byte characters 256 and above are always included, only the
+	characters up to 255 are specified with this option.  When a character
+	is printable but it is not available in the current font, a
+	replacement character will be shown.
+	Unprintable and zero-width Unicode characters are displayed as <xxxx>.
+	There is no option to specify these characters.
+
+			*'joinspaces'* *'js'* *'nojoinspaces'* *'nojs'*
+'joinspaces' 'js'	boolean	(default on)
+			global
+			{not in Vi}
+	Insert two spaces after a '.', '?' and '!' with a join command.
+	When 'cpoptions' includes the 'j' flag, only do this after a '.'.
+	Otherwise only one space is inserted.
+	NOTE: This option is set when 'compatible' is set.
+
+							*'key'*
+'key'			string	(default "")
+			local to buffer
+			{not in Vi}
+	The key that is used for encrypting and decrypting the current buffer.
+	See |encryption|.
+	Careful: Do not set the key value by hand, someone might see the typed
+	key.  Use the |:X| command.  But you can make 'key' empty: >
+		:set key=
+<	It is not possible to get the value of this option with ":set key" or
+	"echo &key".  This is to avoid showing it to someone who shouldn't
+	know.  It also means you cannot see it yourself once you have set it,
+	be careful not to make a typing error!
+
+					*'keymap'* *'kmp'* *E544*
+'keymap' 'kmp'		string	(default "")
+			local to buffer
+			{not in Vi}
+			{only available when compiled with the |+keymap|
+			feature}
+	Name of a keyboard mapping.  See |mbyte-keymap|.
+	Setting this option to a valid keymap name has the side effect of
+	setting 'iminsert' to one, so that the keymap becomes effective.
+	'imsearch' is also set to one, unless it was -1
+	Only normal file name characters can be used, "/\*?[|<>" are illegal.
+
+					*'keymodel'* *'km'*
+'keymodel' 'km'		string	(default "")
+			global
+			{not in Vi}
+	List of comma separated words, which enable special things that keys
+	can do.  These values can be used:
+	   startsel	Using a shifted special key starts selection (either
+			Select mode or Visual mode, depending on "key" being
+			present in 'selectmode').
+	   stopsel	Using a not-shifted special key stops selection.
+	Special keys in this context are the cursor keys, <End>, <Home>,
+	<PageUp> and <PageDown>.
+	The 'keymodel' option is set by the |:behave| command.
+
+					*'keywordprg'* *'kp'*
+'keywordprg' 'kp'	string	(default "man" or "man -s",  DOS: ":help",
+						OS/2: "view /", VMS: "help")
+			global or local to buffer |global-local|
+			{not in Vi}
+	Program to use for the |K| command.  Environment variables are
+	expanded |:set_env|.  ":help" may be used to access the Vim internal
+	help.  (Note that previously setting the global option to the empty
+	value did this, which is now deprecated.)
+	When "man" is used, Vim will automatically translate a count for the
+	"K" command to a section number.  Also for "man -s", in which case the
+	"-s" is removed when there is no count.
+	See |option-backslash| about including spaces and backslashes.
+	Example: >
+		:set keywordprg=man\ -s
+<	This option cannot be set from a |modeline| or in the |sandbox|, for
+	security reasons.
+
+					*'langmap'* *'lmap'* *E357* *E358*
+'langmap' 'lmap'	string	(default "")
+			global
+			{not in Vi}
+			{only available when compiled with the |+langmap|
+			feature}
+	This option allows switching your keyboard into a special language
+	mode.  When you are typing text in Insert mode the characters are
+	inserted directly.  When in command mode the 'langmap' option takes
+	care of translating these special characters to the original meaning
+	of the key.  This means you don't have to change the keyboard mode to
+	be able to execute Normal mode commands.
+	This is the opposite of the 'keymap' option, where characters are
+	mapped in Insert mode.
+	This only works for 8-bit characters.  The value of 'langmap' may be
+	specified with multi-byte characters (e.g., UTF-8), but only the lower
+	8 bits of each character will be used.
+
+	Example (for Greek, in UTF-8):				*greek*  >
+	    :set langmap=ΑA,ΒB,ΨC,ΔD,ΕE,ΦF,ΓG,ΗH,ΙI,ΞJ,ΚK,ΛL,ΜM,ΝN,ΟO,ΠP,QQ,ΡR,ΣS,ΤT,ΘU,ΩV,WW,ΧX,ΥY,ΖZ,αa,βb,ψc,δd,εe,φf,γg,ηh,ιi,ξj,κk,λl,μm,νn,οo,πp,qq,ρr,σs,τt,θu,ωv,ςw,χx,υy,ζz
+<	Example (exchanges meaning of z and y for commands): >
+	    :set langmap=zy,yz,ZY,YZ
+<
+	The 'langmap' option is a list of parts, separated with commas.  Each
+	part can be in one of two forms:
+	1.  A list of pairs.  Each pair is a "from" character immediately
+	    followed by the "to" character.  Examples: "aA", "aAbBcC".
+	2.  A list of "from" characters, a semi-colon and a list of "to"
+	    characters.  Example: "abc;ABC"
+	Example: "aA,fgh;FGH,cCdDeE"
+	Special characters need to be preceded with a backslash.  These are
+	";", ',' and backslash itself.
+
+	This will allow you to activate vim actions without having to switch
+	back and forth between the languages.  Your language characters will
+	be understood as normal vim English characters (according to the
+	langmap mappings) in the following cases:
+	 o Normal/Visual mode (commands, buffer/register names, user mappings)
+	 o Insert/Replace Mode: Register names after CTRL-R
+	 o Insert/Replace Mode: Mappings
+	Characters entered in Command-line mode will NOT be affected by
+	this option.   Note that this option can be changed at any time
+	allowing to switch between mappings for different languages/encodings.
+	Use a mapping to avoid having to type it each time!
+
+					*'langmenu'* *'lm'*
+'langmenu' 'lm'		string	(default "")
+			global
+			{not in Vi}
+			{only available when compiled with the |+menu| and
+			|+multi_lang| features}
+	Language to use for menu translation.  Tells which file is loaded
+	from the "lang" directory in 'runtimepath': >
+		"lang/menu_" . &langmenu . ".vim"
+<	(without the spaces).  For example, to always use the Dutch menus, no
+	matter what $LANG is set to: >
+		:set langmenu=nl_NL.ISO_8859-1
+<	When 'langmenu' is empty, |v:lang| is used.
+	Only normal file name characters can be used, "/\*?[|<>" are illegal.
+	If your $LANG is set to a non-English language but you do want to use
+	the English menus: >
+		:set langmenu=none
+<	This option must be set before loading menus, switching on filetype
+	detection or syntax highlighting.  Once the menus are defined setting
+	this option has no effect.  But you could do this: >
+		:source $VIMRUNTIME/delmenu.vim
+		:set langmenu=de_DE.ISO_8859-1
+		:source $VIMRUNTIME/menu.vim
+<	Warning: This deletes all menus that you defined yourself!
+
+					*'laststatus'* *'ls'*
+'laststatus' 'ls'	number	(default 1)
+			global
+			{not in Vi}
+	The value of this option influences when the last window will have a
+	status line:
+		0: never
+		1: only if there are at least two windows
+		2: always
+	The screen looks nicer with a status line if you have several
+	windows, but it takes another screen line. |status-line|
+
+			*'lazyredraw'* *'lz'* *'nolazyredraw'* *'nolz'*
+'lazyredraw' 'lz'	boolean	(default off)
+			global
+			{not in Vi}
+	When this option is set, the screen will not be redrawn while
+	executing macros, registers and other commands that have not been
+	typed.  Also, updating the window title is postponed.  To force an
+	update use |:redraw|.
+
+			*'linebreak'* *'lbr'* *'nolinebreak'* *'nolbr'*
+'linebreak' 'lbr'	boolean	(default off)
+			local to window
+			{not in Vi}
+			{not available when compiled without the  |+linebreak|
+			feature}
+	If on Vim will wrap long lines at a character in 'breakat' rather
+	than at the last character that fits on the screen.  Unlike
+	'wrapmargin' and 'textwidth', this does not insert <EOL>s in the file,
+	it only affects the way the file is displayed, not its contents.  The
+	value of 'showbreak' is used to put in front of wrapped lines.
+	This option is not used when the 'wrap' option is off or 'list' is on.
+	Note that <Tab> characters after an <EOL> are mostly not displayed
+	with the right amount of white space.
+
+						*'lines'* *E593*
+'lines'			number	(default 24 or terminal height)
+			global
+	Number of lines of the Vim window.
+	Normally you don't need to set this.  It is done automatically by the
+	terminal initialization code.  Also see |posix-screen-size|.
+	When Vim is running in the GUI or in a resizable window, setting this
+	option will cause the window size to be changed.  When you only want
+	to use the size for the GUI, put the command in your |gvimrc| file.
+	Vim limits the number of lines to what fits on the screen.  You can
+	use this command to get the tallest window possible: >
+		:set lines=999
+<	Minimum value is 2, maximum value is 1000.
+	If you get less lines than expected, check the 'guiheadroom' option.
+	When you set this option and Vim is unable to change the physical
+	number of lines of the display, the display may be messed up.
+
+						*'linespace'* *'lsp'*
+'linespace' 'lsp'	number	(default 0, 1 for Win32 GUI)
+			global
+			{not in Vi}
+			{only in the GUI}
+	Number of pixel lines inserted between characters.  Useful if the font
+	uses the full character cell height, making lines touch each other.
+	When non-zero there is room for underlining.
+	With some fonts there can be too much room between lines (to have
+	space for ascents and descents).  Then it makes sense to set
+	'linespace' to a negative value.  This may cause display problems
+	though!
+
+						*'lisp'* *'nolisp'*
+'lisp'			boolean	(default off)
+			local to buffer
+			{not available when compiled without the |+lispindent|
+			feature}
+	Lisp mode: When <Enter> is typed in insert mode set the indent for
+	the next line to Lisp standards (well, sort of).  Also happens with
+	"cc" or "S".  'autoindent' must also be on for this to work.  The 'p'
+	flag in 'cpoptions' changes the method of indenting: Vi compatible or
+	better.  Also see 'lispwords'.
+	The '-' character is included in keyword characters.  Redefines the
+	"=" operator to use this same indentation algorithm rather than
+	calling an external program if 'equalprg' is empty.
+	This option is not used when 'paste' is set.
+	{Vi: Does it a little bit differently}
+
+						*'lispwords'* *'lw'*
+'lispwords' 'lw'	string	(default is very long)
+			global
+			{not in Vi}
+			{not available when compiled without the |+lispindent|
+			feature}
+	Comma separated list of words that influence the Lisp indenting.
+	|'lisp'|
+
+						*'list'* *'nolist'*
+'list'			boolean	(default off)
+			local to window
+	List mode: Show tabs as CTRL-I, show end of line with $.  Useful to
+	see the difference between tabs and spaces and for trailing blanks.
+	Note that this will also affect formatting (set with 'textwidth' or
+	'wrapmargin') when 'cpoptions' includes 'L'.  See 'listchars' for
+	changing the way tabs are displayed.
+
+						*'listchars'* *'lcs'*
+'listchars' 'lcs'	string	(default "eol:$")
+			global
+			{not in Vi}
+	Strings to use in 'list' mode.  It is a comma separated list of string
+	settings.
+	  eol:c		Character to show at the end of each line.  When
+			omitted, there is no extra character at the end of the
+			line.
+	  tab:xy	Two characters to be used to show a tab.  The first
+			char is used once.  The second char is repeated to
+			fill the space that the tab normally occupies.
+			"tab:>-" will show a tab that takes four spaces as
+			">---".  When omitted, a tab is show as ^I.
+	  trail:c	Character to show for trailing spaces.  When omitted,
+			trailing spaces are blank.
+	  extends:c	Character to show in the last column, when 'wrap' is
+			off and the line continues beyond the right of the
+			screen.
+	  precedes:c	Character to show in the first column, when 'wrap'
+			is off and there is text preceding the character
+			visible in the first column.
+	  nbsp:c	Character to show for a non-breakable space (character
+			0xA0, 160).  Left blank when omitted.
+
+	The characters ':' and ',' should not be used.  UTF-8 characters can
+	be used when 'encoding' is "utf-8", otherwise only printable
+	characters are allowed.  All characters must be single width.
+
+	Examples: >
+	    :set lcs=tab:>-,trail:-
+	    :set lcs=tab:>-,eol:<,nbsp:%
+	    :set lcs=extends:>,precedes:<
+<	The "NonText" highlighting will be used for "eol", "extends" and
+	"precedes".  "SpecialKey" for "nbsp", "tab" and "trail".
+	|hl-NonText| |hl-SpecialKey|
+
+			*'lpl'* *'nolpl'* *'loadplugins'* *'noloadplugins'*
+'loadplugins' 'lpl'	boolean	(default on)
+			global
+			{not in Vi}
+	When on the plugin scripts are loaded when starting up |load-plugins|.
+	This option can be reset in your |vimrc| file to disable the loading
+	of plugins.
+	Note that using the "-u NONE" and "--noplugin" command line arguments
+	reset this option. |-u| |--noplugin|
+
+						*'macatsui'* *'nomacatsui'*
+'macatsui'		boolean	(default on)
+			global
+			{only available in Mac GUI version}
+	This is a workaround for when drawing doesn't work properly.  When set
+	and compiled with multi-byte support ATSUI text drawing is used.  When
+	not set ATSUI text drawing is not used.  Switch this option off when
+	you experience drawing problems.  In a future version the problems may
+	be solved and this option becomes obsolete.  Therefore use this method
+	to unset it: >
+		if exists('&macatsui')
+		   set nomacatsui
+		endif
+<	Another option to check if you have drawing problems is
+	'termencoding'.
+
+						*'magic'* *'nomagic'*
+'magic'			boolean	(default on)
+			global
+	Changes the special characters that can be used in search patterns.
+	See |pattern|.
+	NOTE: To avoid portability problems with using patterns, always keep
+	this option at the default "on".  Only switch it off when working with
+	old Vi scripts.  In any other situation write patterns that work when
+	'magic' is on.  Include "\M" when you want to |/\M|.
+
+						*'makeef'* *'mef'*
+'makeef' 'mef'		string	(default: "")
+			global
+			{not in Vi}
+			{not available when compiled without the |+quickfix|
+			feature}
+	Name of the errorfile for the |:make| command (see |:make_makeprg|)
+	and the |:grep| command.
+	When it is empty, an internally generated temp file will be used.
+	When "##" is included, it is replaced by a number to make the name
+	unique.  This makes sure that the ":make" command doesn't overwrite an
+	existing file.
+	NOT used for the ":cf" command.  See 'errorfile' for that.
+	Environment variables are expanded |:set_env|.
+	See |option-backslash| about including spaces and backslashes.
+	This option cannot be set from a |modeline| or in the |sandbox|, for
+	security reasons.
+
+						*'makeprg'* *'mp'*
+'makeprg' 'mp'		string	(default "make", VMS: "MMS")
+			global or local to buffer |global-local|
+			{not in Vi}
+	Program to use for the ":make" command.  See |:make_makeprg|.
+	This option may contain '%' and '#' characters, which are expanded to
+	the current and alternate file name. |:_%| |:_#|
+	Environment variables are expanded |:set_env|.  See |option-backslash|
+	about including spaces and backslashes.
+	Note that a '|' must be escaped twice: once for ":set" and once for
+	the interpretation of a command.  When you use a filter called
+	"myfilter" do it like this: >
+	    :set makeprg=gmake\ \\\|\ myfilter
+<	The placeholder "$*" can be given (even multiple times) to specify
+	where the arguments will be included, for example: >
+	    :set makeprg=latex\ \\\\nonstopmode\ \\\\input\\{$*}
+<	This option cannot be set from a |modeline| or in the |sandbox|, for
+	security reasons.
+
+						*'matchpairs'* *'mps'*
+'matchpairs' 'mps'	string	(default "(:),{:},[:]")
+			local to buffer
+			{not in Vi}
+	Characters that form pairs.  The |%| command jumps from one to the
+	other.  Currently only single byte character pairs are allowed, and
+	they must be different.  The characters must be separated by a colon.
+	The pairs must be separated by a comma.  Example for including '<' and
+	'>' (HTML): >
+		:set mps+=<:>
+
+<	A more exotic example, to jump between the '=' and ';' in an
+	assignment, useful for languages like C and Java: >
+		:au FileType c,cpp,java set mps+==:;
+
+<	For a more advanced way of using "%", see the matchit.vim plugin in
+	the $VIMRUNTIME/macros directory. |add-local-help|
+
+						*'matchtime'* *'mat'*
+'matchtime' 'mat'	number	(default 5)
+			global
+			{not in Vi}{in Nvi}
+	Tenths of a second to show the matching paren, when 'showmatch' is
+	set.  Note that this is not in milliseconds, like other options that
+	set a time.  This is to be compatible with Nvi.
+
+						*'maxcombine'* *'mco'*
+'maxcombine' 'mco'	number (default 2)
+			global
+			{not in Vi}
+			{only available when compiled with the |+multi_byte|
+			feature}
+	The maximum number of combining characters supported for displaying.
+	Only used when 'encoding' is "utf-8".
+	The default is OK for most languages.  Hebrew may require 4.
+	Maximum value is 6.
+	Even when this option is set to 2 you can still edit text with more
+	combining characters, you just can't see them.  Use |g8| or |ga|.
+	See |mbyte-combining|.
+
+						*'maxfuncdepth'* *'mfd'*
+'maxfuncdepth' 'mfd'	number	(default 100)
+			global
+			{not in Vi}
+			{not available when compiled without the +eval
+			feature}
+	Maximum depth of function calls for user functions.  This normally
+	catches endless recursion.  When using a recursive function with
+	more depth, set 'maxfuncdepth' to a bigger number.  But this will use
+	more memory, there is the danger of failing when memory is exhausted.
+	See also |:function|.
+
+						*'maxmapdepth'* *'mmd'* *E223*
+'maxmapdepth' 'mmd'	number	(default 1000)
+			global
+			{not in Vi}
+	Maximum number of times a mapping is done without resulting in a
+	character to be used.  This normally catches endless mappings, like
+	":map x y" with ":map y x".  It still does not catch ":map g wg",
+	because the 'w' is used before the next mapping is done.  See also
+	|key-mapping|.
+
+						*'maxmem'* *'mm'*
+'maxmem' 'mm'		number	(default between 256 to 5120 (system
+				 dependent) or half the amount of memory
+				 available)
+			global
+			{not in Vi}
+	Maximum amount of memory (in Kbyte) to use for one buffer.  When this
+	limit is reached allocating extra memory for a buffer will cause
+	other memory to be freed.  Maximum value 2000000.  Use this to work
+	without a limit.  Also see 'maxmemtot'.
+
+						*'maxmempattern'* *'mmp'*
+'maxmempattern' 'mmp'	number	(default 1000)
+			global
+			{not in Vi}
+	Maximum amount of memory (in Kbyte) to use for pattern matching.
+	Maximum value 2000000.  Use this to work without a limit.
+							*E363*
+	When Vim runs into the limit it gives an error message and mostly
+	behaves like CTRL-C was typed.
+	Running into the limit often means that the pattern is very
+	inefficient or too complex.  This may already happen with the pattern
+	"\(.\)*" on a very long line.  ".*" works much better.
+	Vim may run out of memory before hitting the 'maxmempattern' limit.
+
+						*'maxmemtot'* *'mmt'*
+'maxmemtot' 'mmt'	number	(default between 2048 and 10240 (system
+				 dependent) or half the amount of memory
+				 available)
+			global
+			{not in Vi}
+	Maximum amount of memory (in Kbyte) to use for all buffers together.
+	Maximum value 2000000.  Use this to work without a limit.  Also see
+	'maxmem'.
+
+						*'menuitems'* *'mis'*
+'menuitems' 'mis'	number	(default 25)
+			global
+			{not in Vi}
+			{not available when compiled without the |+menu|
+			feature}
+	Maximum number of items to use in a menu.  Used for menus that are
+	generated from a list of items, e.g., the Buffers menu.  Changing this
+	option has no direct effect, the menu must be refreshed first.
+
+						*'mkspellmem'* *'msm'*
+'mkspellmem' 'msm'	string	(default "460000,2000,500")
+			global
+			{not in Vi}
+			{not available when compiled without the |+syntax|
+			feature}
+	Parameters for |:mkspell|.  This tunes when to start compressing the
+	word tree.  Compression can be slow when there are many words, but
+	it's needed to avoid running out of memory.  The amount of memory used
+	per word depends very much on how similar the words are, that's why
+	this tuning is complicated.
+
+	There are three numbers, separated by commas:
+		{start},{inc},{added}
+
+	For most languages the uncompressed word tree fits in memory.  {start}
+	gives the amount of memory in Kbyte that can be used before any
+	compression is done.  It should be a bit smaller than the amount of
+	memory that is available to Vim.
+
+	When going over the {start} limit the {inc} number specifies the
+	amount of memory in Kbyte that can be allocated before another
+	compression is done.  A low number means compression is done after
+	less words are added, which is slow.  A high number means more memory
+	will be allocated.
+
+	After doing compression, {added} times 1024 words can be added before
+	the {inc} limit is ignored and compression is done when any extra
+	amount of memory is needed.  A low number means there is a smaller
+	chance of hitting the {inc} limit, less memory is used but it's
+	slower.
+
+	The languages for which these numbers are important are Italian and
+	Hungarian.  The default works for when you have about 512 Mbyte.  If
+	you have 1 Gbyte you could use: >
+		:set mkspellmem=900000,3000,800
+<	If you have less than 512 Mbyte |:mkspell| may fail for some
+	languages, no matter what you set 'mkspellmem' to.
+
+				   *'modeline'* *'ml'* *'nomodeline'* *'noml'*
+'modeline' 'ml'		boolean	(Vim default: on (off for root),
+				 Vi default: off)
+			local to buffer
+						*'modelines'* *'mls'*
+'modelines' 'mls'	number	(default 5)
+			global
+			{not in Vi}
+	If 'modeline' is on 'modelines' gives the number of lines that is
+	checked for set commands.  If 'modeline' is off or 'modelines' is zero
+	no lines are checked.  See |modeline|.
+	NOTE: 'modeline' is set to the Vi default value when 'compatible' is
+	set and to the Vim default value when 'compatible' is reset.
+
+				*'modifiable'* *'ma'* *'nomodifiable'* *'noma'*
+'modifiable' 'ma'	boolean	(default on)
+			local to buffer
+			{not in Vi}		*E21*
+	When off the buffer contents cannot be changed.  The 'fileformat' and
+	'fileencoding' options also can't be changed.
+	Can be reset with the |-M| command line argument.
+
+				*'modified'* *'mod'* *'nomodified'* *'nomod'*
+'modified' 'mod'	boolean	(default off)
+			local to buffer
+			{not in Vi}
+	When on, the buffer is considered to be modified.  This option is set
+	when:
+	1. A change was made to the text since it was last written.  Using the
+	   |undo| command to go back to the original text will reset the
+	   option.  But undoing changes that were made before writing the
+	   buffer will set the option again, since the text is different from
+	   when it was written.
+	2. 'fileformat' or 'fileencoding' is different from its original
+	   value.  The original value is set when the buffer is read or
+	   written.  A ":set nomodified" command also resets the original
+	   values to the current values and the 'modified' option will be
+	   reset.
+	When 'buftype' is "nowrite" or "nofile" this option may be set, but
+	will be ignored.
+
+						*'more'* *'nomore'*
+'more'			boolean	(Vim default: on, Vi default: off)
+			global
+			{not in Vi}
+	When on, listings pause when the whole screen is filled.  You will get
+	the |more-prompt|.  When this option is off there are no pauses, the
+	listing continues until finished.
+	NOTE: This option is set to the Vi default value when 'compatible' is
+	set and to the Vim default value when 'compatible' is reset.
+
+						*'mouse'* *E538*
+'mouse'			string	(default "", "a" for GUI, MS-DOS and Win32)
+			global
+			{not in Vi}
+	Enable the use of the mouse.  Only works for certain terminals
+	(xterm, MS-DOS, Win32 |win32-mouse|, QNX pterm, and Linux console
+	with gpm).  For using the mouse in the GUI, see |gui-mouse|.
+	The mouse can be enabled for different modes:
+		n	Normal mode
+		v	Visual mode
+		i	Insert mode
+		c	Command-line mode
+		h	all previous modes when editing a help file
+		a	all previous modes
+		r	for |hit-enter| and |more-prompt| prompt
+	Normally you would enable the mouse in all four modes with: >
+		:set mouse=a
+<	When the mouse is not enabled, the GUI will still use the mouse for
+	modeless selection.  This doesn't move the text cursor.
+
+	See |mouse-using|.  Also see |'clipboard'|.
+
+	Note: When enabling the mouse in a terminal, copy/paste will use the
+	"* register if there is access to an X-server.  The xterm handling of
+	the mouse buttons can still be used by keeping the shift key pressed.
+	Also see the 'clipboard' option.
+
+			*'mousefocus'* *'mousef'* *'nomousefocus'* *'nomousef'*
+'mousefocus' 'mousef'	boolean	(default off)
+			global
+			{not in Vi}
+			{only works in the GUI}
+	The window that the mouse pointer is on is automatically activated.
+	When changing the window layout or window focus in another way, the
+	mouse pointer is moved to the window with keyboard focus.  Off is the
+	default because it makes using the pull down menus a little goofy, as
+	a pointer transit may activate a window unintentionally.
+
+			*'mousehide'* *'mh'* *'nomousehide'* *'nomh'*
+'mousehide' 'mh'	boolean	(default on)
+			global
+			{not in Vi}
+			{only works in the GUI}
+	When on, the mouse pointer is hidden when characters are typed.
+	The mouse pointer is restored when the mouse is moved.
+
+						*'mousemodel'* *'mousem'*
+'mousemodel' 'mousem'	string	(default "extend", "popup" for MS-DOS and Win32)
+			global
+			{not in Vi}
+	Sets the model to use for the mouse.  The name mostly specifies what
+	the right mouse button is used for:
+	   extend	Right mouse button extends a selection.  This works
+			like in an xterm.
+	   popup	Right mouse button pops up a menu.  The shifted left
+			mouse button extends a selection.  This works like
+			with Microsoft Windows.
+	   popup_setpos Like "popup", but the cursor will be moved to the
+			position where the mouse was clicked, and thus the
+			selected operation will act upon the clicked object.
+			If clicking inside a selection, that selection will
+			be acted upon, i.e. no cursor move.  This implies of
+			course, that right clicking outside a selection will
+			end Visual mode.
+	Overview of what button does what for each model:
+	mouse		    extend		popup(_setpos) ~
+	left click	    place cursor	place cursor
+	left drag	    start selection	start selection
+	shift-left	    search word		extend selection
+	right click	    extend selection	popup menu (place cursor)
+	right drag	    extend selection	-
+	middle click	    paste		paste
+
+	In the "popup" model the right mouse button produces a pop-up menu.
+	You need to define this first, see |popup-menu|.
+
+	Note that you can further refine the meaning of buttons with mappings.
+	See |gui-mouse-mapping|.  But mappings are NOT used for modeless
+	selection (because that's handled in the GUI code directly).
+
+	The 'mousemodel' option is set by the |:behave| command.
+
+					*'mouseshape'* *'mouses'* *E547*
+'mouseshape' 'mouses'	string	(default "i:beam,r:beam,s:updown,sd:cross,
+					m:no,ml:up-arrow,v:rightup-arrow")
+			global
+			{not in Vi}
+			{only available when compiled with the |+mouseshape|
+			feature}
+	This option tells Vim what the mouse pointer should look like in
+	different modes.  The option is a comma separated list of parts, much
+	like used for 'guicursor'.  Each part consist of a mode/location-list
+	and an argument-list:
+		mode-list:shape,mode-list:shape,..
+	The mode-list is a dash separated list of these modes/locations:
+			In a normal window: ~
+		n	Normal mode
+		v	Visual mode
+		ve	Visual mode with 'selection' "exclusive" (same as 'v',
+			if not specified)
+		o	Operator-pending mode
+		i	Insert mode
+		r	Replace mode
+
+			Others: ~
+		c	appending to the command-line
+		ci	inserting in the command-line
+		cr	replacing in the command-line
+		m	at the 'Hit ENTER' or 'More' prompts
+		ml	idem, but cursor in the last line
+		e	any mode, pointer below last window
+		s	any mode, pointer on a status line
+		sd	any mode, while dragging a status line
+		vs	any mode, pointer on a vertical separator line
+		vd	any mode, while dragging a vertical separator line
+		a	everywhere
+
+	The shape is one of the following:
+	avail	name		looks like ~
+	w x	arrow		Normal mouse pointer
+	w x	blank		no pointer at all (use with care!)
+	w x	beam		I-beam
+	w x	updown		up-down sizing arrows
+	w x	leftright	left-right sizing arrows
+	w x	busy		The system's usual busy pointer
+	w x	no		The system's usual 'no input' pointer
+	  x	udsizing	indicates up-down resizing
+	  x	lrsizing	indicates left-right resizing
+	  x	crosshair	like a big thin +
+	  x	hand1		black hand
+	  x	hand2		white hand
+	  x	pencil		what you write with
+	  x	question	big ?
+	  x	rightup-arrow	arrow pointing right-up
+	w x	up-arrow	arrow pointing up
+	  x	<number>	any X11 pointer number (see X11/cursorfont.h)
+
+	The "avail" column contains a 'w' if the shape is available for Win32,
+	x for X11.
+	Any modes not specified or shapes not available use the normal mouse
+	pointer.
+
+	Example: >
+		:set mouseshape=s:udsizing,m:no
+<	will make the mouse turn to a sizing arrow over the status lines and
+	indicate no input when the hit-enter prompt is displayed (since
+	clicking the mouse has no effect in this state.)
+
+						*'mousetime'* *'mouset'*
+'mousetime' 'mouset'	number	(default 500)
+			global
+			{not in Vi}
+	Only for GUI, MS-DOS, Win32 and Unix with xterm.  Defines the maximum
+	time in msec between two mouse clicks for the second click to be
+	recognized as a multi click.
+
+						    *'mzquantum'* *'mzq'*
+'mzquantum' 'mzq'	number	(default 100)
+			global
+			{not in Vi}
+			{not available when compiled without the |+mzscheme|
+			feature}
+	The number of milliseconds between polls for MzScheme threads.
+	Negative or zero value means no thread scheduling.
+
+							*'nrformats'* *'nf'*
+'nrformats' 'nf'	string	(default "octal,hex")
+			local to buffer
+			{not in Vi}
+	This defines what bases Vim will consider for numbers when using the
+	CTRL-A and CTRL-X commands for adding to and subtracting from a number
+	respectively; see |CTRL-A| for more info on these commands.
+	alpha	If included, single alphabetical characters will be
+		incremented or decremented.  This is useful for a list with a
+		letter index a), b), etc.
+	octal	If included, numbers that start with a zero will be considered
+		to be octal.  Example: Using CTRL-A on "007" results in "010".
+	hex	If included, numbers starting with "0x" or "0X" will be
+		considered to be hexadecimal.  Example: Using CTRL-X on
+		"0x100" results in "0x0ff".
+	Numbers which simply begin with a digit in the range 1-9 are always
+	considered decimal.  This also happens for numbers that are not
+	recognized as octal or hex.
+
+				*'number'* *'nu'* *'nonumber'* *'nonu'*
+'number' 'nu'		boolean	(default off)
+			local to window
+	Print the line number in front of each line.  When the 'n' option is
+	excluded from 'cpoptions' a wrapped line will not use the column of
+	line numbers (this is the default when 'compatible' isn't set).
+	The 'numberwidth' option can be used to set the room used for the line
+	number.
+	When a long, wrapped line doesn't start with the first character, '-'
+	characters are put before the number.
+	See |hl-LineNr| for the highlighting used for the number.
+
+						*'numberwidth'* *'nuw'*
+'numberwidth' 'nuw'	number	(Vim default: 4  Vi default: 8)
+			local to window
+			{not in Vi}
+			{only available when compiled with the |+linebreak|
+			feature}
+	Minimal number of columns to use for the line number.  Only relevant
+	when the 'number' option is set or printing lines with a line number.
+	Since one space is always between the number and the text, there is
+	one less character for the number itself.
+	The value is the minimum width.  A bigger width is used when needed to
+	fit the highest line number in the buffer.  Thus with the Vim default
+	of 4 there is room for a line number up to 999.  When the buffer has
+	1000 lines five columns will be used.
+	The minimum value is 1, the maximum value is 10.
+	NOTE: 'numberwidth' is reset to 8 when 'compatible' is set.
+
+						*'omnifunc'* *'ofu'*
+'omnifunc' 'ofu'	string	(default: empty)
+			local to buffer
+			{not in Vi}
+			{not available when compiled without the +eval
+			or +insert_expand feature}
+	This option specifies a function to be used for Insert mode omni
+	completion with CTRL-X CTRL-O. |i_CTRL-X_CTRL-O|
+	See |complete-functions| for an explanation of how the function is
+	invoked and what it should return.
+	This option is usually set by a filetype plugin:
+	|:filetype-plugin-on|
+
+
+			    *'opendevice'* *'odev'* *'noopendevice'* *'noodev'*
+'opendevice' 'odev'	boolean	(default off)
+			global
+			{not in Vi}
+			{only for MS-DOS, MS-Windows and OS/2}
+	Enable reading and writing from devices.  This may get Vim stuck on a
+	device that can be opened but doesn't actually do the I/O.  Therefore
+	it is off by default.
+	Note that on MS-Windows editing "aux.h", "lpt1.txt" and the like also
+	result in editing a device.
+
+
+						*'operatorfunc'* *'opfunc'*
+'operatorfunc' 'opfunc'	string	(default: empty)
+			global
+			{not in Vi}
+	This option specifies a function to be called by the |g@| operator.
+	See |:map-operator| for more info and an example.
+
+	This option cannot be set from a |modeline| or in the |sandbox|, for
+	security reasons.
+
+
+					*'osfiletype'* *'oft'* *E366*
+'osfiletype' 'oft'	string (RISC-OS default: "Text",
+				others default: "")
+			local to buffer
+			{not in Vi}
+			{only available when compiled with the |+osfiletype|
+			feature}
+	Some operating systems store extra information about files besides
+	name, datestamp and permissions.  This option contains the extra
+	information, the nature of which will vary between systems.
+	The value of this option is usually set when the file is loaded, and
+	use to set the file type when file is written.
+	It can affect the pattern matching of the automatic commands.
+	|autocmd-osfiletypes|
+
+						*'paragraphs'* *'para'*
+'paragraphs' 'para'	string	(default "IPLPPPQPP LIpplpipbp")
+			global
+	Specifies the nroff macros that separate paragraphs.  These are pairs
+	of two letters (see |object-motions|).
+
+						*'paste'* *'nopaste'*
+'paste'			boolean	(default off)
+			global
+			{not in Vi}
+	Put Vim in Paste mode.  This is useful if you want to cut or copy
+	some text from one window and paste it in Vim.  This will avoid
+	unexpected effects.
+	Setting this option is useful when using Vim in a terminal, where Vim
+	cannot distinguish between typed text and pasted text.  In the GUI, Vim
+	knows about pasting and will mostly do the right thing without 'paste'
+	being set.  The same is true for a terminal where Vim handles the
+	mouse clicks itself.
+	This option is reset when starting the GUI.  Thus if you set it in
+	your .vimrc it will work in a terminal, but not in the GUI.  Setting
+	'paste' in the GUI has side effects: e.g., the Paste toolbar button
+	will no longer work in Insert mode, because it uses a mapping.
+	When the 'paste' option is switched on (also when it was already on):
+		- mapping in Insert mode and Command-line mode is disabled
+		- abbreviations are disabled
+		- 'textwidth' is set to 0
+		- 'wrapmargin' is set to 0
+		- 'autoindent' is reset
+		- 'smartindent' is reset
+		- 'softtabstop' is set to 0
+		- 'revins' is reset
+		- 'ruler' is reset
+		- 'showmatch' is reset
+		- 'formatoptions' is used like it is empty
+	These options keep their value, but their effect is disabled:
+		- 'lisp'
+		- 'indentexpr'
+		- 'cindent'
+	NOTE: When you start editing another file while the 'paste' option is
+	on, settings from the modelines or autocommands may change the
+	settings again, causing trouble when pasting text.  You might want to
+	set the 'paste' option again.
+	When the 'paste' option is reset the mentioned options are restored to
+	the value before the moment 'paste' was switched from off to on.
+	Resetting 'paste' before ever setting it does not have any effect.
+	Since mapping doesn't work while 'paste' is active, you need to use
+	the 'pastetoggle' option to toggle the 'paste' option with some key.
+
+						*'pastetoggle'* *'pt'*
+'pastetoggle' 'pt'	string	(default "")
+			global
+			{not in Vi}
+	When non-empty, specifies the key sequence that toggles the 'paste'
+	option.  This is like specifying a mapping: >
+	    :map {keys} :set invpaste<CR>
+<	Where {keys} is the value of 'pastetoggle'.
+	The difference is that it will work even when 'paste' is set.
+	'pastetoggle' works in Insert mode and Normal mode, but not in
+	Command-line mode.
+	Mappings are checked first, thus overrule 'pastetoggle'.  However,
+	when 'paste' is on mappings are ignored in Insert mode, thus you can do
+	this: >
+	    :map <F10> :set paste<CR>
+	    :map <F11> :set nopaste<CR>
+	    :imap <F10> <C-O>:set paste<CR>
+	    :imap <F11> <nop>
+	    :set pastetoggle=<F11>
+<	This will make <F10> start paste mode and <F11> stop paste mode.
+	Note that typing <F10> in paste mode inserts "<F10>", since in paste
+	mode everything is inserted literally, except the 'pastetoggle' key
+	sequence.
+
+						*'pex'* *'patchexpr'*
+'patchexpr' 'pex'	string	(default "")
+			global
+			{not in Vi}
+			{not available when compiled without the |+diff|
+			feature}
+	Expression which is evaluated to apply a patch to a file and generate
+	the resulting new version of the file.  See |diff-patchexpr|.
+
+						*'patchmode'* *'pm'* *E206*
+'patchmode' 'pm'	string	(default "")
+			global
+			{not in Vi}
+	When non-empty the oldest version of a file is kept.  This can be used
+	to keep the original version of a file if you are changing files in a
+	source distribution.  Only the first time that a file is written a
+	copy of the original file will be kept.  The name of the copy is the
+	name of the original file with the string in the 'patchmode' option
+	appended.  This option should start with a dot.  Use a string like
+	".org".  'backupdir' must not be empty for this to work (Detail: The
+	backup file is renamed to the patchmode file after the new file has
+	been successfully written, that's why it must be possible to write a
+	backup file).  If there was no file to be backed up, an empty file is
+	created.
+	When the 'backupskip' pattern matches, a patchmode file is not made.
+	Using 'patchmode' for compressed files appends the extension at the
+	end (e.g., "file.gz.orig"), thus the resulting name isn't always
+	recognized as a compressed file.
+	Only normal file name characters can be used, "/\*?[|<>" are illegal.
+
+					*'path'* *'pa'* *E343* *E345* *E347*
+'path' 'pa'		string	(default on Unix: ".,/usr/include,,"
+				   on OS/2:	  ".,/emx/include,,"
+				   other systems: ".,,")
+			global or local to buffer |global-local|
+			{not in Vi}
+	This is a list of directories which will be searched when using the
+	|gf|, [f, ]f, ^Wf, |:find| and other commands, provided that the file
+	being searched for has a relative path (not starting with '/').  The
+	directories in the 'path' option may be relative or absolute.
+	- Use commas to separate directory names: >
+		:set path=.,/usr/local/include,/usr/include
+<	- Spaces can also be used to separate directory names (for backwards
+	  compatibility with version 3.0).  To have a space in a directory
+	  name, precede it with an extra backslash, and escape the space: >
+		:set path=.,/dir/with\\\ space
+<	- To include a comma in a directory name precede it with an extra
+	  backslash: >
+		:set path=.,/dir/with\\,comma
+<	- To search relative to the directory of the current file, use: >
+		:set path=.
+<	- To search in the current directory use an empty string between two
+	  commas: >
+		:set path=,,
+<	- A directory name may end in a ':' or '/'.
+	- Environment variables are expanded |:set_env|.
+	- When using |netrw.vim| URLs can be used.  For example, adding
+	  "http://www.vim.org" will make ":find index.html" work.
+	- Search upwards and downwards in a directory tree:
+	  1) "*" matches a sequence of characters, e.g.: >
+		:set path=/usr/include/*
+<	     means all subdirectories in /usr/include (but not /usr/include
+	     itself). >
+		:set path=/usr/*c
+<	     matches /usr/doc and /usr/src.
+	  2) "**" matches a subtree, up to 100 directories deep.  Example: >
+		:set path=/home/user_x/src/**
+<	     means search in the whole subtree under "/home/usr_x/src".
+	  3) If the path ends with a ';', this path is the startpoint
+	     for upward search.
+	  See |file-searching| for more info and exact syntax.
+	  {not available when compiled without the |+path_extra| feature}
+	- Careful with '\' characters, type two to get one in the option: >
+		:set path=.,c:\\include
+<	  Or just use '/' instead: >
+		:set path=.,c:/include
+<	Don't forget "." or files won't even be found in the same directory as
+	the file!
+	The maximum length is limited.  How much depends on the system, mostly
+	it is something like 256 or 1024 characters.
+	You can check if all the include files are found, using the value of
+	'path', see |:checkpath|.
+	The use of |:set+=| and |:set-=| is preferred when adding or removing
+	directories from the list.  This avoids problems when a future version
+	uses another default.  To remove the current directory use: >
+		:set path-=
+<	To add the current directory use: >
+		:set path+=
+<	To use an environment variable, you probably need to replace the
+	separator.  Here is an example to append $INCL, in which directory
+	names are separated with a semi-colon: >
+		:let &path = &path . "," . substitute($INCL, ';', ',', 'g')
+<	Replace the ';' with a ':' or whatever separator is used.  Note that
+	this doesn't work when $INCL contains a comma or white space.
+
+			*'preserveindent'* *'pi'* *'nopreserveindent'* *'nopi'*
+'preserveindent' 'pi'	boolean	(default off)
+			local to buffer
+			{not in Vi}
+	When changing the indent of the current line, preserve as much of the
+	indent structure as possible.  Normally the indent is replaced by a
+	series of tabs followed by spaces as required (unless |'expandtab'| is
+	enabled, in which case only spaces are used).  Enabling this option
+	means the indent will preserve as many existing characters as possible
+	for indenting, and only add additional tabs or spaces as required.
+	NOTE: When using ">>" multiple times the resulting indent is a mix of
+	tabs and spaces.  You might not like this.
+	NOTE: 'preserveindent' is reset when 'compatible' is set.
+	Also see 'copyindent'.
+	Use |:retab| to clean up white space.
+
+					*'previewheight'* *'pvh'*
+'previewheight' 'pvh'	number (default 12)
+			global
+			{not in Vi}
+			{not available when compiled without the |+windows| or
+			|+quickfix| feature}
+	Default height for a preview window.  Used for |:ptag| and associated
+	commands.  Used for |CTRL-W_}| when no count is given.
+
+					*'previewwindow'* *'nopreviewwindow'*
+					*'pvw'* *'nopvw'* *E590*
+'previewwindow' 'pvw'	boolean (default off)
+			local to window
+			{not in Vi}
+			{not available when compiled without the |+windows| or
+			|+quickfix| feature}
+	Identifies the preview window.  Only one window can have this option
+	set.  It's normally not set directly, but by using one of the commands
+	|:ptag|, |:pedit|, etc.
+
+						*'printdevice'* *'pdev'*
+'printdevice' 'pdev'	string	(default empty)
+			global
+			{not in Vi}
+			{only available when compiled with the |+printer|
+			feature}
+	The name of the printer to be used for |:hardcopy|.
+	See |pdev-option|.
+	This option cannot be set from a |modeline| or in the |sandbox|, for
+	security reasons.
+
+						*'printencoding'* *'penc'*
+'printencoding' 'penc'	String	(default empty, except for some systems)
+			global
+			{not in Vi}
+			{only available when compiled with the |+printer|
+			and |+postscript| features}
+	Sets the character encoding used when printing.
+	See |penc-option|.
+
+						*'printexpr'* *'pexpr'*
+'printexpr' 'pexpr'	String	(default: see below)
+			global
+			{not in Vi}
+			{only available when compiled with the |+printer|
+			and |+postscript| features}
+	Expression used to print the PostScript produced with |:hardcopy|.
+	See |pexpr-option|.
+
+						*'printfont'* *'pfn'*
+'printfont' 'pfn'	string	(default "courier")
+			global
+			{not in Vi}
+			{only available when compiled with the |+printer|
+			feature}
+	The name of the font that will be used for |:hardcopy|.
+	See |pfn-option|.
+
+						*'printheader'* *'pheader'*
+'printheader' 'pheader'  string  (default "%<%f%h%m%=Page %N")
+			global
+			{not in Vi}
+			{only available when compiled with the |+printer|
+			feature}
+	The format of the header produced in |:hardcopy| output.
+	See |pheader-option|.
+
+						*'printmbcharset'* *'pmbcs'*
+'printmbcharset' 'pmbcs'  string (default "")
+			global
+			{not in Vi}
+			{only available when compiled with the |+printer|,
+			|+postscript| and |+multi_byte| features}
+	The CJK character set to be used for CJK output from |:hardcopy|.
+	See |pmbcs-option|.
+
+						*'printmbfont'* *'pmbfn'*
+'printmbfont' 'pmbfn'	string (default "")
+			global
+			{not in Vi}
+			{only available when compiled with the |+printer|,
+			|+postscript| and |+multi_byte| features}
+	List of font names to be used for CJK output from |:hardcopy|.
+	See |pmbfn-option|.
+
+						*'printoptions'* *'popt'*
+'printoptions' 'popt' string (default "")
+			global
+			{not in Vi}
+			{only available when compiled with |+printer| feature}
+	List of items that control the format of the output of |:hardcopy|.
+	See |popt-option|.
+
+						*'prompt'* *'noprompt'*
+'prompt'		boolean	(default on)
+			global
+	When on a ":" prompt is used in Ex mode.
+
+						*'pumheight'* *'ph'*
+'pumheight' 'ph'	number	(default 0)
+			global
+			{not available when compiled without the
+			|+insert_expand| feature}
+			{not in Vi}
+	Determines the maximum number of items to show in the popup menu for
+	Insert mode completion.  When zero as much space as available is used.
+	|ins-completion-menu|.
+
+
+						*'quoteescape'* *'qe'*
+'quoteescape' 'qe'	string	(default "\")
+			local to buffer
+			{not in Vi}
+	The characters that are used to escape quotes in a string.  Used for
+	objects like a', a" and a` |a'|.
+	When one of the characters in this option is found inside a string,
+	the following character will be skipped.  The default value makes the
+	text "foo\"bar\\" considered to be one string.
+
+				   *'readonly'* *'ro'* *'noreadonly'* *'noro'*
+'readonly' 'ro'		boolean	(default off)
+			local to buffer
+	If on, writes fail unless you use a '!'.  Protects you from
+	accidentally overwriting a file.  Default on when Vim is started
+	in read-only mode ("vim -R") or when the executable is called "view".
+	When using ":w!" the 'readonly' option is reset for the current
+	buffer, unless the 'Z' flag is in 'cpoptions'.
+	{not in Vi:}  When using the ":view" command the 'readonly' option is
+	set for the newly edited buffer.
+
+						*'remap'* *'noremap'*
+'remap'			boolean	(default on)
+			global
+	Allows for mappings to work recursively.  If you do not want this for
+	a single entry, use the :noremap[!] command.
+	NOTE: To avoid portability problems with Vim scripts, always keep
+	this option at the default "on".  Only switch it off when working with
+	old Vi scripts.
+
+						*'report'*
+'report'		number	(default 2)
+			global
+	Threshold for reporting number of lines changed.  When the number of
+	changed lines is more than 'report' a message will be given for most
+	":" commands.  If you want it always, set 'report' to 0.
+	For the ":substitute" command the number of substitutions is used
+	instead of the number of lines.
+
+			 *'restorescreen'* *'rs'* *'norestorescreen'* *'nors'*
+'restorescreen' 'rs'	boolean	(default on)
+			global
+			{not in Vi}  {only in Windows 95/NT console version}
+	When set, the screen contents is restored when exiting Vim.  This also
+	happens when executing external commands.
+
+	For non-Windows Vim: You can set or reset the 't_ti' and 't_te'
+	options in your .vimrc.  To disable restoring:
+		set t_ti= t_te=
+	To enable restoring (for an xterm):
+		set t_ti=^[7^[[r^[[?47h t_te=^[[?47l^[8
+	(Where ^[ is an <Esc>, type CTRL-V <Esc> to insert it)
+
+				*'revins'* *'ri'* *'norevins'* *'nori'*
+'revins' 'ri'		boolean	(default off)
+			global
+			{not in Vi}
+			{only available when compiled with the |+rightleft|
+			feature}
+	Inserting characters in Insert mode will work backwards.  See "typing
+	backwards" |ins-reverse|.  This option can be toggled with the CTRL-_
+	command in Insert mode, when 'allowrevins' is set.
+	NOTE: This option is reset when 'compatible' or 'paste' is set.
+
+				 *'rightleft'* *'rl'* *'norightleft'* *'norl'*
+'rightleft' 'rl'	boolean	(default off)
+			local to window
+			{not in Vi}
+			{only available when compiled with the |+rightleft|
+			feature}
+	When on, display orientation becomes right-to-left, i.e., characters
+	that are stored in the file appear from the right to the left.
+	Using this option, it is possible to edit files for languages that
+	are written from the right to the left such as Hebrew and Arabic.
+	This option is per window, so it is possible to edit mixed files
+	simultaneously, or to view the same file in both ways (this is
+	useful whenever you have a mixed text file with both right-to-left
+	and left-to-right strings so that both sets are displayed properly
+	in different windows).  Also see |rileft.txt|.
+
+			*'rightleftcmd'* *'rlc'* *'norightleftcmd'* *'norlc'*
+'rightleftcmd' 'rlc'	string	(default "search")
+			local to window
+			{not in Vi}
+			{only available when compiled with the |+rightleft|
+			feature}
+	Each word in this option enables the command line editing to work in
+	right-to-left mode for a group of commands:
+
+		search		"/" and "?" commands
+
+	This is useful for languages such as Hebrew, Arabic and Farsi.
+	The 'rightleft' option must be set for 'rightleftcmd' to take effect.
+
+					 *'ruler'* *'ru'* *'noruler'* *'noru'*
+'ruler' 'ru'		boolean	(default off)
+			global
+			{not in Vi}
+			{not available when compiled without the
+			|+cmdline_info| feature}
+	Show the line and column number of the cursor position, separated by a
+	comma.  When there is room, the relative position of the displayed
+	text in the file is shown on the far right:
+		Top	first line is visible
+		Bot	last line is visible
+		All	first and last line are visible
+		45%	relative position in the file
+	If 'rulerformat' is set, it will determine the contents of the ruler.
+	Each window has its own ruler.  If a window has a status line, the
+	ruler is shown there.  Otherwise it is shown in the last line of the
+	screen.  If the statusline is given by 'statusline' (i.e. not empty),
+	this option takes precedence over 'ruler' and 'rulerformat'
+	If the number of characters displayed is different from the number of
+	bytes in the text (e.g., for a TAB or a multi-byte character), both
+	the text column (byte number) and the screen column are shown,
+	separated with a dash.
+	For an empty line "0-1" is shown.
+	For an empty buffer the line number will also be zero: "0,0-1".
+	This option is reset when the 'paste' option is set.
+	If you don't want to see the ruler all the time but want to know where
+	you are, use "g CTRL-G" |g_CTRL-G|.
+	NOTE: This option is reset when 'compatible' is set.
+
+						*'rulerformat'* *'ruf'*
+'rulerformat' 'ruf'	string	(default empty)
+			global
+			{not in Vi}
+			{not available when compiled without the |+statusline|
+			feature}
+	When this option is not empty, it determines the content of the ruler
+	string, as displayed for the 'ruler' option.
+	The format of this option is like that of 'statusline'.
+	The default ruler width is 17 characters.  To make the ruler 15
+	characters wide, put "%15(" at the start and "%)" at the end.
+	Example: >
+		:set rulerformat=%15(%c%V\ %p%%%)
+<
+				*'runtimepath'* *'rtp'* *vimfiles*
+'runtimepath' 'rtp'	string	(default:
+					Unix: "$HOME/.vim,
+						$VIM/vimfiles,
+						$VIMRUNTIME,
+						$VIM/vimfiles/after,
+						$HOME/.vim/after"
+					Amiga: "home:vimfiles,
+						$VIM/vimfiles,
+						$VIMRUNTIME,
+						$VIM/vimfiles/after,
+						home:vimfiles/after"
+					PC, OS/2: "$HOME/vimfiles,
+						$VIM/vimfiles,
+						$VIMRUNTIME,
+						$VIM/vimfiles/after,
+						$HOME/vimfiles/after"
+					Macintosh: "$VIM:vimfiles,
+						$VIMRUNTIME,
+						$VIM:vimfiles:after"
+					RISC-OS: "Choices:vimfiles,
+						$VIMRUNTIME,
+						Choices:vimfiles/after"
+					VMS: "sys$login:vimfiles,
+						$VIM/vimfiles,
+						$VIMRUNTIME,
+						$VIM/vimfiles/after,
+						sys$login:vimfiles/after")
+			global
+			{not in Vi}
+	This is a list of directories which will be searched for runtime
+	files:
+	  filetype.vim	filetypes by file name |new-filetype|
+	  scripts.vim	filetypes by file contents |new-filetype-scripts|
+	  autoload/	automatically loaded scripts |autoload-functions|
+	  colors/	color scheme files |:colorscheme|
+	  compiler/	compiler files |:compiler|
+	  doc/		documentation |write-local-help|
+	  ftplugin/	filetype plugins |write-filetype-plugin|
+	  indent/	indent scripts |indent-expression|
+	  keymap/	key mapping files |mbyte-keymap|
+	  lang/		menu translations |:menutrans|
+	  menu.vim	GUI menus |menu.vim|
+	  plugin/	plugin scripts |write-plugin|
+	  print/	files for printing |postscript-print-encoding|
+	  spell/	spell checking files |spell|
+	  syntax/	syntax files |mysyntaxfile|
+	  tutor/	files for vimtutor |tutor|
+
+	And any other file searched for with the |:runtime| command.
+
+	The defaults for most systems are setup to search five locations:
+	1. In your home directory, for your personal preferences.
+	2. In a system-wide Vim directory, for preferences from the system
+	   administrator.
+	3. In $VIMRUNTIME, for files distributed with Vim.
+							*after-directory*
+	4. In the "after" directory in the system-wide Vim directory.  This is
+	   for the system administrator to overrule or add to the distributed
+	   defaults (rarely needed)
+	5. In the "after" directory in your home directory.  This is for
+	   personal preferences to overrule or add to the distributed defaults
+	   or system-wide settings (rarely needed).
+
+	Note that, unlike 'path', no wildcards like "**" are allowed.  Normal
+	wildcards are allowed, but can significantly slow down searching for
+	runtime files.  For speed, use as few items as possible and avoid
+	wildcards.
+	See |:runtime|.
+	Example: >
+		:set runtimepath=~/vimruntime,/mygroup/vim,$VIMRUNTIME
+<	This will use the directory "~/vimruntime" first (containing your
+	personal Vim runtime files), then "/mygroup/vim" (shared between a
+	group of people) and finally "$VIMRUNTIME" (the distributed runtime
+	files).
+	You probably should always include $VIMRUNTIME somewhere, to use the
+	distributed runtime files.  You can put a directory before $VIMRUNTIME
+	to find files which replace a distributed runtime files.  You can put
+	a directory after $VIMRUNTIME to find files which add to distributed
+	runtime files.
+	This option cannot be set from a |modeline| or in the |sandbox|, for
+	security reasons.
+
+						*'scroll'* *'scr'*
+'scroll' 'scr'		number	(default: half the window height)
+			local to window
+	Number of lines to scroll with CTRL-U and CTRL-D commands.  Will be
+	set to half the number of lines in the window when the window size
+	changes.  If you give a count to the CTRL-U or CTRL-D command it will
+	be used as the new value for 'scroll'.  Reset to half the window
+	height with ":set scroll=0".   {Vi is a bit different: 'scroll' gives
+	the number of screen lines instead of file lines, makes a difference
+	when lines wrap}
+
+			*'scrollbind'* *'scb'* *'noscrollbind'* *'noscb'*
+'scrollbind' 'scb'	boolean  (default off)
+			local to window
+			{not in Vi}
+			{not available when compiled without the |+scrollbind|
+			feature}
+	See also |scroll-binding|.  When this option is set, the current
+	window scrolls as other scrollbind windows (windows that also have
+	this option set) scroll.  This option is useful for viewing the
+	differences between two versions of a file, see 'diff'.
+	See |'scrollopt'| for options that determine how this option should be
+	interpreted.
+	This option is mostly reset when splitting a window to edit another
+	file.  This means that ":split | edit file" results in two windows
+	with scroll-binding, but ":split file" does not.
+
+						*'scrolljump'* *'sj'*
+'scrolljump' 'sj'	number	(default 1)
+			global
+			{not in Vi}
+	Minimal number of lines to scroll when the cursor gets off the
+	screen (e.g., with "j").  Not used for scroll commands (e.g., CTRL-E,
+	CTRL-D).  Useful if your terminal scrolls very slowly.
+	When set to a negative number from -1 to -100 this is used as the
+	percentage of the window height.  Thus -50 scrolls half the window
+	height.
+	NOTE: This option is set to 1 when 'compatible' is set.
+
+						*'scrolloff'* *'so'*
+'scrolloff' 'so'	number	(default 0)
+			global
+			{not in Vi}
+	Minimal number of screen lines to keep above and below the cursor.
+	This will make some context visible around where you are working.  If
+	you set it to a very large value (999) the cursor line will always be
+	in the middle of the window (except at the start or end of the file or
+	when long lines wrap).
+	For scrolling horizontally see 'sidescrolloff'.
+	NOTE: This option is set to 0 when 'compatible' is set.
+
+						*'scrollopt'* *'sbo'*
+'scrollopt' 'sbo'	string	(default "ver,jump")
+			global
+			{not available when compiled without the |+scrollbind|
+			feature}
+			{not in Vi}
+	This is a comma-separated list of words that specifies how
+	'scrollbind' windows should behave.  'sbo' stands for ScrollBind
+	Options.
+	The following words are available:
+	    ver		Bind vertical scrolling for 'scrollbind' windows
+	    hor		Bind horizontal scrolling for 'scrollbind' windows
+	    jump	Applies to the offset between two windows for vertical
+			scrolling.  This offset is the difference in the first
+			displayed line of the bound windows.  When moving
+			around in a window, another 'scrollbind' window may
+			reach a position before the start or after the end of
+			the buffer.  The offset is not changed though, when
+			moving back the 'scrollbind' window will try to scroll
+			to the desired position when possible.
+			When now making that window the current one, two
+			things can be done with the relative offset:
+			1. When "jump" is not included, the relative offset is
+			   adjusted for the scroll position in the new current
+			   window.  When going back to the other window, the
+			   new relative offset will be used.
+			2. When "jump" is included, the other windows are
+			   scrolled to keep the same relative offset.  When
+			   going back to the other window, it still uses the
+			   same relative offset.
+	Also see |scroll-binding|.
+	When 'diff' mode is active there always is vertical scroll binding,
+	even when "ver" isn't there.
+
+						*'sections'* *'sect'*
+'sections' 'sect'	string	(default "SHNHH HUnhsh")
+			global
+	Specifies the nroff macros that separate sections.  These are pairs of
+	two letters (See |object-motions|).  The default makes a section start
+	at the nroff macros ".SH", ".NH", ".H", ".HU", ".nh" and ".sh".
+
+						*'secure'* *'nosecure'* *E523*
+'secure'		boolean	(default off)
+			global
+			{not in Vi}
+	When on, ":autocmd", shell and write commands are not allowed in
+	".vimrc" and ".exrc" in the current directory and map commands are
+	displayed.  Switch it off only if you know that you will not run into
+	problems, or when the 'exrc' option is off.  On Unix this option is
+	only used if the ".vimrc" or ".exrc" is not owned by you.  This can be
+	dangerous if the systems allows users to do a "chown".  You better set
+	'secure' at the end of your ~/.vimrc then.
+	This option cannot be set from a |modeline| or in the |sandbox|, for
+	security reasons.
+
+						*'selection'* *'sel'*
+'selection' 'sel'	string	(default "inclusive")
+			global
+			{not in Vi}
+	This option defines the behavior of the selection.  It is only used
+	in Visual and Select mode.
+	Possible values:
+	   value	past line     inclusive ~
+	   old		   no		yes
+	   inclusive	   yes		yes
+	   exclusive	   yes		no
+	"past line" means that the cursor is allowed to be positioned one
+	character past the line.
+	"inclusive" means that the last character of the selection is included
+	in an operation.  For example, when "x" is used to delete the
+	selection.
+	Note that when "exclusive" is used and selecting from the end
+	backwards, you cannot include the last character of a line, when
+	starting in Normal mode and 'virtualedit' empty.
+
+	The 'selection' option is set by the |:behave| command.
+
+						*'selectmode'* *'slm'*
+'selectmode' 'slm'	string	(default "")
+			global
+			{not in Vi}
+	This is a comma separated list of words, which specifies when to start
+	Select mode instead of Visual mode, when a selection is started.
+	Possible values:
+	   mouse	when using the mouse
+	   key		when using shifted special keys
+	   cmd		when using "v", "V" or CTRL-V
+	See |Select-mode|.
+	The 'selectmode' option is set by the |:behave| command.
+
+						*'sessionoptions'* *'ssop'*
+'sessionoptions' 'ssop'	string	(default: "blank,buffers,curdir,folds,
+					       help,options,tabpages,winsize")
+			global
+			{not in Vi}
+			{not available when compiled without the +mksession
+			feature}
+	Changes the effect of the |:mksession| command.  It is a comma
+	separated list of words.  Each word enables saving and restoring
+	something:
+	   word		save and restore ~
+	   blank	empty windows
+	   buffers	hidden and unloaded buffers, not just those in windows
+	   curdir	the current directory
+	   folds	manually created folds, opened/closed folds and local
+			fold options
+	   globals	global variables that start with an uppercase letter
+			and contain at least one lowercase letter.  Only
+			String and Number types are stored.
+	   help		the help window
+	   localoptions	options and mappings local to a window or buffer (not
+			global values for local options)
+	   options	all options and mappings (also global values for local
+			options)
+	   resize	size of the Vim window: 'lines' and 'columns'
+	   sesdir	the directory in which the session file is located
+			will become the current directory (useful with
+			projects accessed over a network from different
+			systems)
+	   slash	backslashes in file names replaced with forward
+			slashes
+	   tabpages	all tab pages; without this only the current tab page
+			is restored, so that you can make a session for each
+			tab page separately
+	   unix		with Unix end-of-line format (single <NL>), even when
+			on Windows or DOS
+	   winpos	position of the whole Vim window
+	   winsize	window sizes
+
+	Don't include both "curdir" and "sesdir".
+	When "curdir" nor "sesdir" is included, file names are stored with
+	absolute paths.
+	"slash" and "unix" are useful on Windows when sharing session files
+	with Unix.  The Unix version of Vim cannot source dos format scripts,
+	but the Windows version of Vim can source unix format scripts.
+
+						*'shell'* *'sh'* *E91*
+'shell' 'sh'		string	(default $SHELL or "sh",
+					MS-DOS and Win32: "command.com" or
+					"cmd.exe", OS/2: "cmd")
+			global
+	Name of the shell to use for ! and :! commands.  When changing the
+	value also check these options: 'shelltype', 'shellpipe', 'shellslash'
+	'shellredir', 'shellquote', 'shellxquote' and 'shellcmdflag'.
+	It is allowed to give an argument to the command, e.g.  "csh -f".
+	See |option-backslash| about including spaces and backslashes.
+	Environment variables are expanded |:set_env|.
+	If the name of the shell contains a space, you might need to enclose
+	it in quotes.  Example: >
+		:set shell=\"c:\program\ files\unix\sh.exe\"\ -f
+<	Note the backslash before each quote (to avoid starting a comment) and
+	each space (to avoid ending the option value).  Also note that the
+	"-f" is not inside the quotes, because it is not part of the command
+	name.  And Vim automagically recognizes the backslashes that are path
+	separators.
+	For Dos 32 bits (DJGPP), you can set the $DJSYSFLAGS environment
+	variable to change the way external commands are executed.  See the
+	libc.inf file of DJGPP.
+	Under MS-Windows, when the executable ends in ".com" it must be
+	included.  Thus setting the shell to "command.com" or "4dos.com"
+	works, but "command" and "4dos" do not work for all commands (e.g.,
+	filtering).
+	For unknown reasons, when using "4dos.com" the current directory is
+	changed to "C:\".  To avoid this set 'shell' like this: >
+		:set shell=command.com\ /c\ 4dos
+<	This option cannot be set from a |modeline| or in the |sandbox|, for
+	security reasons.
+
+						*'shellcmdflag'* *'shcf'*
+'shellcmdflag' 'shcf'	string	(default: "-c", MS-DOS and Win32, when 'shell'
+					does not contain "sh" somewhere: "/c")
+			global
+			{not in Vi}
+	Flag passed to the shell to execute "!" and ":!" commands; e.g.,
+	"bash.exe -c ls" or "command.com /c dir".  For the MS-DOS-like
+	systems, the default is set according to the value of 'shell', to
+	reduce the need to set this option by the user.  It's not used for
+	OS/2 (EMX figures this out itself).  See |option-backslash| about
+	including spaces and backslashes.  See |dos-shell|.
+	This option cannot be set from a |modeline| or in the |sandbox|, for
+	security reasons.
+
+						*'shellpipe'* *'sp'*
+'shellpipe' 'sp'	string	(default ">", "| tee", "|& tee" or "2>&1| tee")
+			global
+			{not in Vi}
+			{not available when compiled without the |+quickfix|
+			feature}
+	String to be used to put the output of the ":make" command in the
+	error file.  See also |:make_makeprg|.  See |option-backslash| about
+	including spaces and backslashes.
+	The name of the temporary file can be represented by "%s" if necessary
+	(the file name is appended automatically if no %s appears in the value
+	of this option).
+	For the Amiga and MS-DOS the default is ">".  The output is directly
+	saved in a file and not echoed to the screen.
+	For Unix the default it "| tee".  The stdout of the compiler is saved
+	in a file and echoed to the screen.  If the 'shell' option is "csh" or
+	"tcsh" after initializations, the default becomes "|& tee".  If the
+	'shell' option is "sh", "ksh", "zsh" or "bash" the default becomes
+	"2>&1| tee".  This means that stderr is also included.
+	The initialization of this option is done after reading the ".vimrc"
+	and the other initializations, so that when the 'shell' option is set
+	there, the 'shellpipe' option changes automatically, unless it was
+	explicitly set before.
+	When 'shellpipe' is set to an empty string, no redirection of the
+	":make" output will be done.  This is useful if you use a 'makeprg'
+	that writes to 'makeef' by itself.  If you want no piping, but do
+	want to include the 'makeef', set 'shellpipe' to a single space.
+	Don't forget to precede the space with a backslash: ":set sp=\ ".
+	In the future pipes may be used for filtering and this option will
+	become obsolete (at least for Unix).
+	This option cannot be set from a |modeline| or in the |sandbox|, for
+	security reasons.
+
+						*'shellquote'* *'shq'*
+'shellquote' 'shq'	string	(default: ""; MS-DOS and Win32, when 'shell'
+					contains "sh" somewhere: "\"")
+			global
+			{not in Vi}
+	Quoting character(s), put around the command passed to the shell, for
+	the "!" and ":!" commands.  The redirection is kept outside of the
+	quoting.  See 'shellxquote' to include the redirection.  It's
+	probably not useful to set both options.
+	This is an empty string by default.  Only known to be useful for
+	third-party shells on MS-DOS-like systems, such as the MKS Korn Shell
+	or bash, where it should be "\"".  The default is adjusted according
+	the value of 'shell', to reduce the need to set this option by the
+	user.  See |dos-shell|.
+	This option cannot be set from a |modeline| or in the |sandbox|, for
+	security reasons.
+
+						*'shellredir'* *'srr'*
+'shellredir' 'srr'	string	(default ">", ">&" or ">%s 2>&1")
+			global
+			{not in Vi}
+	String to be used to put the output of a filter command in a temporary
+	file.  See also |:!|.  See |option-backslash| about including spaces
+	and backslashes.
+	The name of the temporary file can be represented by "%s" if necessary
+	(the file name is appended automatically if no %s appears in the value
+	of this option).
+	The default is ">".  For Unix, if the 'shell' option is "csh", "tcsh"
+	or "zsh" during initializations, the default becomes ">&".  If the
+	'shell' option is "sh", "ksh" or "bash" the default becomes
+	">%s 2>&1".  This means that stderr is also included.
+	For Win32, the Unix checks are done and additionally "cmd" is checked
+	for, which makes the default ">%s 2>&1".  Also, the same names with
+	".exe" appended are checked for.
+	The initialization of this option is done after reading the ".vimrc"
+	and the other initializations, so that when the 'shell' option is set
+	there, the 'shellredir' option changes automatically unless it was
+	explicitly set before.
+	In the future pipes may be used for filtering and this option will
+	become obsolete (at least for Unix).
+	This option cannot be set from a |modeline| or in the |sandbox|, for
+	security reasons.
+
+			*'shellslash'* *'ssl'* *'noshellslash'* *'nossl'*
+'shellslash' 'ssl'	boolean	(default off)
+			global
+			{not in Vi} {only for MSDOS, MS-Windows and OS/2}
+	When set, a forward slash is used when expanding file names.  This is
+	useful when a Unix-like shell is used instead of command.com or
+	cmd.exe.  Backward slashes can still be typed, but they are changed to
+	forward slashes by Vim.
+	Note that setting or resetting this option has no effect for some
+	existing file names, thus this option needs to be set before opening
+	any file for best results.  This might change in the future.
+	'shellslash' only works when a backslash can be used as a path
+	separator.  To test if this is so use: >
+		if exists('+shellslash')
+<
+			*'shelltemp'* *'stmp'* *'noshelltemp'* *'nostmp'*
+'shelltemp' 'stmp'	boolean	(Vi default off, Vim default on)
+			global
+			{not in Vi}
+	When on, use temp files for shell commands.  When off use a pipe.
+	When using a pipe is not possible temp files are used anyway.
+	Currently a pipe is only supported on Unix.  You can check it with: >
+		:if has("filterpipe")
+<	The advantage of using a pipe is that nobody can read the temp file
+	and the 'shell' command does not need to support redirection.
+	The advantage of using a temp file is that the file type and encoding
+	can be detected.
+	The |FilterReadPre|, |FilterReadPost| and |FilterWritePre|,
+	|FilterWritePost| autocommands event are not triggered when
+	'shelltemp' is off.
+
+						*'shelltype'* *'st'*
+'shelltype' 'st'	number	(default 0)
+			global
+			{not in Vi} {only for the Amiga}
+	On the Amiga this option influences the way how the commands work
+	which use a shell.
+	0 and 1: always use the shell
+	2 and 3: use the shell only to filter lines
+	4 and 5: use shell only for ':sh' command
+	When not using the shell, the command is executed directly.
+
+	0 and 2: use "shell 'shellcmdflag' cmd" to start external commands
+	1 and 3: use "shell cmd" to start external commands
+
+						*'shellxquote'* *'sxq'*
+'shellxquote' 'sxq'	string	(default: "";
+					for Win32, when 'shell' contains "sh"
+					somewhere: "\""
+					for Unix, when using system(): "\"")
+			global
+			{not in Vi}
+	Quoting character(s), put around the command passed to the shell, for
+	the "!" and ":!" commands.  Includes the redirection.  See
+	'shellquote' to exclude the redirection.  It's probably not useful
+	to set both options.
+	This is an empty string by default.  Known to be useful for
+	third-party shells when using the Win32 version, such as the MKS Korn
+	Shell or bash, where it should be "\"".  The default is adjusted
+	according the value of 'shell', to reduce the need to set this option
+	by the user.  See |dos-shell|.
+	This option cannot be set from a |modeline| or in the |sandbox|, for
+	security reasons.
+
+			*'shiftround'* *'sr'* *'noshiftround'* *'nosr'*
+'shiftround' 'sr'	boolean	(default off)
+			global
+			{not in Vi}
+	Round indent to multiple of 'shiftwidth'.  Applies to > and <
+	commands.  CTRL-T and CTRL-D in Insert mode always round the indent to
+	a multiple of 'shiftwidth' (this is Vi compatible).
+	NOTE: This option is reset when 'compatible' is set.
+
+						*'shiftwidth'* *'sw'*
+'shiftwidth' 'sw'	number	(default 8)
+			local to buffer
+	Number of spaces to use for each step of (auto)indent.  Used for
+	|'cindent'|, |>>|, |<<|, etc.
+
+						*'shortmess'* *'shm'*
+'shortmess' 'shm'	string	(Vim default "filnxtToO", Vi default: "",
+							POSIX default: "A")
+			global
+			{not in Vi}
+	This option helps to avoid all the |hit-enter| prompts caused by file
+	messages, for example  with CTRL-G, and to avoid some other messages.
+	It is a list of flags:
+	 flag	meaning when present	~
+	  f	use "(3 of 5)" instead of "(file 3 of 5)"
+	  i	use "[noeol]" instead of "[Incomplete last line]"
+	  l	use "999L, 888C" instead of "999 lines, 888 characters"
+	  m	use "[+]" instead of "[Modified]"
+	  n	use "[New]" instead of "[New File]"
+	  r	use "[RO]" instead of "[readonly]"
+	  w	use "[w]" instead of "written" for file write message
+		and "[a]" instead of "appended" for ':w >> file' command
+	  x	use "[dos]" instead of "[dos format]", "[unix]" instead of
+		"[unix format]" and "[mac]" instead of "[mac format]".
+	  a	all of the above abbreviations
+
+	  o	overwrite message for writing a file with subsequent message
+		for reading a file (useful for ":wn" or when 'autowrite' on)
+	  O	message for reading a file overwrites any previous message.
+		Also for quickfix message (e.g., ":cn").
+	  s	don't give "search hit BOTTOM, continuing at TOP" or "search
+		hit TOP, continuing at BOTTOM" messages
+	  t	truncate file message at the start if it is too long to fit
+		on the command-line, "<" will appear in the left most column.
+		Ignored in Ex mode.
+	  T	truncate other messages in the middle if they are too long to
+		fit on the command line.  "..." will appear in the middle.
+		Ignored in Ex mode.
+	  W	don't give "written" or "[w]" when writing a file
+	  A	don't give the "ATTENTION" message when an existing swap file
+		is found.
+	  I	don't give the intro message when starting Vim |:intro|.
+
+	This gives you the opportunity to avoid that a change between buffers
+	requires you to hit <Enter>, but still gives as useful a message as
+	possible for the space available.  To get the whole message that you
+	would have got with 'shm' empty, use ":file!"
+	Useful values:
+	    shm=	No abbreviation of message.
+	    shm=a	Abbreviation, but no loss of information.
+	    shm=at	Abbreviation, and truncate message when necessary.
+
+	NOTE: This option is set to the Vi default value when 'compatible' is
+	set and to the Vim default value when 'compatible' is reset.
+
+				 *'shortname'* *'sn'* *'noshortname'* *'nosn'*
+'shortname' 'sn'	boolean	(default off)
+			local to buffer
+			{not in Vi, not in MS-DOS versions}
+	Filenames are assumed to be 8 characters plus one extension of 3
+	characters.  Multiple dots in file names are not allowed.  When this
+	option is on, dots in file names are replaced with underscores when
+	adding an extension (".~" or ".swp").  This option is not available
+	for MS-DOS, because then it would always be on.  This option is useful
+	when editing files on an MS-DOS compatible filesystem, e.g., messydos
+	or crossdos.  When running the Win32 GUI version under Win32s, this
+	option is always on by default.
+
+						*'showbreak'* *'sbr'* *E595*
+'showbreak' 'sbr'	string	(default "")
+			global
+			{not in Vi}
+			{not available when compiled without the  |+linebreak|
+			feature}
+	String to put at the start of lines that have been wrapped.  Useful
+	values are "> " or "+++ ".
+	Only printable single-cell characters are allowed, excluding <Tab> and
+	comma (in a future version the comma might be used to separate the
+	part that is shown at the end and at the start of a line).
+	The characters are highlighted according to the '@' flag in
+	'highlight'.
+	Note that tabs after the showbreak will be displayed differently.
+	If you want the 'showbreak' to appear in between line numbers, add the
+	"n" flag to 'cpoptions'.
+
+				     *'showcmd'* *'sc'* *'noshowcmd'* *'nosc'*
+'showcmd' 'sc'		boolean	(Vim default: on, off for Unix, Vi default:
+				 off)
+			global
+			{not in Vi}
+			{not available when compiled without the
+			|+cmdline_info| feature}
+	Show (partial) command in the last line of the screen.  Set this
+	option off if your terminal is slow.
+	In Visual mode the size of the selected area is shown:
+	- When selecting characters within a line, the number of characters.
+	- When selecting more than one line, the number of lines.
+	- When selecting a block, the size in screen characters: linesxcolumns.
+	NOTE: This option is set to the Vi default value when 'compatible' is
+	set and to the Vim default value when 'compatible' is reset.
+
+			*'showfulltag'* *'sft'* *'noshowfulltag'* *'nosft'*
+'showfulltag' 'sft'	boolean (default off)
+			global
+			{not in Vi}
+	When completing a word in insert mode (see |ins-completion|) from the
+	tags file, show both the tag name and a tidied-up form of the search
+	pattern (if there is one) as possible matches.  Thus, if you have
+	matched a C function, you can see a template for what arguments are
+	required (coding style permitting).
+
+				 *'showmatch'* *'sm'* *'noshowmatch'* *'nosm'*
+'showmatch' 'sm'	boolean	(default off)
+			global
+	When a bracket is inserted, briefly jump to the matching one.  The
+	jump is only done if the match can be seen on the screen.  The time to
+	show the match can be set with 'matchtime'.
+	A Beep is given if there is no match (no matter if the match can be
+	seen or not).  This option is reset when the 'paste' option is set.
+	When the 'm' flag is not included in 'cpoptions', typing a character
+	will immediately move the cursor back to where it belongs.
+	See the "sm" field in 'guicursor' for setting the cursor shape and
+	blinking when showing the match.
+	The 'matchpairs' option can be used to specify the characters to show
+	matches for.  'rightleft' and 'revins' are used to look for opposite
+	matches.
+	Also see the matchparen plugin for highlighting the match when moving
+	around |pi_paren.txt|.
+	Note: Use of the short form is rated PG.
+
+				 *'showmode'* *'smd'* *'noshowmode'* *'nosmd'*
+'showmode' 'smd'	boolean	(Vim default: on, Vi default: off)
+			global
+	If in Insert, Replace or Visual mode put a message on the last line.
+	Use the 'M' flag in 'highlight' to set the type of highlighting for
+	this message.
+	When |XIM| may be used the message will include "XIM".  But this
+	doesn't mean XIM is really active, especially when 'imactivatekey' is
+	not set.
+	NOTE: This option is set to the Vi default value when 'compatible' is
+	set and to the Vim default value when 'compatible' is reset.
+
+						*'showtabline'* *'stal'*
+'showtabline' 'stal'	number	(default 1)
+			global
+			{not in Vi}
+			{not available when compiled without the +windows
+			feature}
+	The value of this option specifies when the line with tab page labels
+	will be displayed:
+		0: never
+		1: only if there are at least two tab pages
+		2: always
+	This is both for the GUI and non-GUI implementation of the tab pages
+	line.
+	See |tab-page| for more information about tab pages.
+
+						*'sidescroll'* *'ss'*
+'sidescroll' 'ss'	number	(default 0)
+			global
+			{not in Vi}
+	The minimal number of columns to scroll horizontally.  Used only when
+	the 'wrap' option is off and the cursor is moved off of the screen.
+	When it is zero the cursor will be put in the middle of the screen.
+	When using a slow terminal set it to a large number or 0.  When using
+	a fast terminal use a small number or 1.  Not used for "zh" and "zl"
+	commands.
+
+						*'sidescrolloff'* *'siso'*
+'sidescrolloff' 'siso'	number (default 0)
+			global
+			{not in Vi}
+	The minimal number of screen columns to keep to the left and to the
+	right of the cursor if 'nowrap' is set.  Setting this option to a
+	value greater than 0 while having |'sidescroll'| also at a non-zero
+	value makes some context visible in the line you are scrolling in
+	horizontally (except at beginning of the line).  Setting this option
+	to a large value (like 999) has the effect of keeping the cursor
+	horizontally centered in the window, as long as one does not come too
+	close to the beginning of the line.
+	NOTE: This option is set to 0 when 'compatible' is set.
+
+	Example: Try this together with 'sidescroll' and 'listchars' as
+		 in the following example to never allow the cursor to move
+		 onto the "extends" character:
+
+		 :set nowrap sidescroll=1 listchars=extends:>,precedes:<
+		 :set sidescrolloff=1
+
+
+			*'smartcase'* *'scs'* *'nosmartcase'* *'noscs'*
+'smartcase' 'scs'	boolean	(default off)
+			global
+			{not in Vi}
+	Override the 'ignorecase' option if the search pattern contains upper
+	case characters.  Only used when the search pattern is typed and
+	'ignorecase' option is on.  Used for the commands "/", "?", "n", "N",
+	":g" and ":s".  Not used for "*", "#", "gd", tag search, etc..  After
+	"*" and "#" you can make 'smartcase' used by doing a "/" command,
+	recalling the search pattern from history and hitting <Enter>.
+	NOTE: This option is reset when 'compatible' is set.
+
+			     *'smartindent'* *'si'* *'nosmartindent'* *'nosi'*
+'smartindent' 'si'	boolean	(default off)
+			local to buffer
+			{not in Vi}
+			{not available when compiled without the
+			|+smartindent| feature}
+	Do smart autoindenting when starting a new line.  Works for C-like
+	programs, but can also be used for other languages.  'cindent' does
+	something like this, works better in most cases, but is more strict,
+	see |C-indenting|.  When 'cindent' is on, setting 'si' has no effect.
+	'indentexpr' is a more advanced alternative.
+	Normally 'autoindent' should also be on when using 'smartindent'.
+	An indent is automatically inserted:
+	- After a line ending in '{'.
+	- After a line starting with a keyword from 'cinwords'.
+	- Before a line starting with '}' (only with the "O" command).
+	When typing '}' as the first character in a new line, that line is
+	given the same indent as the matching '{'.
+	When typing '#' as the first character in a new line, the indent for
+	that line is removed, the '#' is put in the first column.  The indent
+	is restored for the next line.  If you don't want this, use this
+	mapping: ":inoremap # X^H#", where ^H is entered with CTRL-V CTRL-H.
+	When using the ">>" command, lines starting with '#' are not shifted
+	right.
+	NOTE: 'smartindent' is reset when 'compatible' is set.  When 'paste'
+	is set smart indenting is disabled.
+
+				 *'smarttab'* *'sta'* *'nosmarttab'* *'nosta'*
+'smarttab' 'sta'	boolean	(default off)
+			global
+			{not in Vi}
+	When on, a <Tab> in front of a line inserts blanks according to
+	'shiftwidth'.  'tabstop' or 'softtabstop' is used in other places.  A
+	<BS> will delete a 'shiftwidth' worth of space at the start of the
+	line.
+	When off, a <Tab> always inserts blanks according to 'tabstop' or
+	'softtabstop'.  'shiftwidth' is only used for shifting text left or
+	right |shift-left-right|.
+	What gets inserted (a <Tab> or spaces) depends on the 'expandtab'
+	option.  Also see |ins-expandtab|.  When 'expandtab' is not set, the
+	number of spaces is minimized by using <Tab>s.
+	NOTE: This option is reset when 'compatible' is set.
+
+					*'softtabstop'* *'sts'*
+'softtabstop' 'sts'	number	(default 0)
+			local to buffer
+			{not in Vi}
+	Number of spaces that a <Tab> counts for while performing editing
+	operations, like inserting a <Tab> or using <BS>.  It "feels" like
+	<Tab>s are being inserted, while in fact a mix of spaces and <Tab>s is
+	used.  This is useful to keep the 'ts' setting at its standard value
+	of 8, while being able to edit like it is set to 'sts'.  However,
+	commands like "x" still work on the actual characters.
+	When 'sts' is zero, this feature is off.
+	'softtabstop' is set to 0 when the 'paste' option is set.
+	See also |ins-expandtab|.  When 'expandtab' is not set, the number of
+	spaces is minimized by using <Tab>s.
+	The 'L' flag in 'cpoptions' changes how tabs are used when 'list' is
+	set.
+	NOTE: This option is set to 0 when 'compatible' is set.
+
+						*'spell'* *'nospell'*
+'spell'			boolean	(default off)
+			local to window
+			{not in Vi}
+			{not available when compiled without the |+syntax|
+			feature}
+	When on spell checking will be done.  See |spell|.
+	The languages are specified with 'spelllang'.
+
+						*'spellcapcheck'* *'spc'*
+'spellcapcheck' 'spc'	string	(default "[.?!]\_[\])'" \t]\+")
+			local to buffer
+			{not in Vi}
+			{not available when compiled without the |+syntax|
+			feature}
+	Pattern to locate the end of a sentence.  The following word will be
+	checked to start with a capital letter.  If not then it is highlighted
+	with SpellCap |hl-SpellCap| (unless the word is also badly spelled).
+	When this check is not wanted make this option empty.
+	Only used when 'spell' is set.
+	Be careful with special characters, see |option-backslash| about
+	including spaces and backslashes.
+	To set this option automatically depending on the language, see
+	|set-spc-auto|.
+
+						*'spellfile'* *'spf'*
+'spellfile' 'spf'	string	(default empty)
+			local to buffer
+			{not in Vi}
+			{not available when compiled without the |+syntax|
+			feature}
+	Name of the word list file where words are added for the |zg| and |zw|
+	commands.  It must end in ".{encoding}.add".  You need to include the
+	path, otherwise the file is placed in the current directory.
+								*E765*
+	It may also be a comma separated list of names.  A count before the
+	|zg| and |zw| commands can be used to access each.  This allows using
+	a personal word list file and a project word list file.
+	When a word is added while this option is empty Vim will set it for
+	you: Using the first directory in 'runtimepath' that is writable.  If
+	there is no "spell" directory yet it will be created.  For the file
+	name the first language name that appears in 'spelllang' is used,
+	ignoring the region.
+	The resulting ".spl" file will be used for spell checking, it does not
+	have to appear in 'spelllang'.
+	Normally one file is used for all regions, but you can add the region
+	name if you want to.  However, it will then only be used when
+	'spellfile' is set to it, for entries in 'spelllang' only files
+	without region name will be found.
+	This option cannot be set from a |modeline| or in the |sandbox|, for
+	security reasons.
+
+						*'spelllang'* *'spl'*
+'spelllang' 'spl'	string	(default "en")
+			local to buffer
+			{not in Vi}
+			{not available when compiled without the |+syntax|
+			feature}
+	A comma separated list of word list names.  When the 'spell' option is
+	on spellchecking will be done for these languages.  Example: >
+		set spelllang=en_us,nl,medical
+<	This means US English, Dutch and medical words are recognized.  Words
+	that are not recognized will be highlighted.
+	The word list name must not include a comma or dot.  Using a dash is
+	recommended to separate the two letter language name from a
+	specification.  Thus "en-rare" is used for rare English words.
+	A region name must come last and have the form "_xx", where "xx" is
+	the two-letter, lower case region name.  You can use more than one
+	region by listing them: "en_us,en_ca" supports both US and Canadian
+	English, but not words specific for Australia, New Zealand or Great
+	Britain.
+							*E757*
+	As a special case the name of a .spl file can be given as-is.  The
+	first "_xx" in the name is removed and used as the region name
+	(_xx is an underscore, two letters and followed by a non-letter).
+	This is mainly for testing purposes.  You must make sure the correct
+	encoding is used, Vim doesn't check it.
+	When 'encoding' is set the word lists are reloaded.  Thus it's a good
+	idea to set 'spelllang' after setting 'encoding' to avoid loading the
+	files twice.
+	How the related spell files are found is explained here: |spell-load|.
+
+	If the |spellfile.vim| plugin is active and you use a language name
+	for which Vim cannot find the .spl file in 'runtimepath' the plugin
+	will ask you if you want to download the file.
+
+	After this option has been set successfully, Vim will source the files
+	"spell/LANG.vim" in 'runtimepath'.  "LANG" is the value of 'spelllang'
+	up to the first comma, dot or underscore.
+	Also see |set-spc-auto|.
+
+
+						*'spellsuggest'* *'sps'*
+'spellsuggest' 'sps'	string	(default "best")
+			global
+			{not in Vi}
+			{not available when compiled without the |+syntax|
+			feature}
+	Methods used for spelling suggestions.  Both for the |z=| command and
+	the |spellsuggest()| function.  This is a comma-separated list of
+	items:
+
+	best		Internal method that works best for English.  Finds
+			changes like "fast" and uses a bit of sound-a-like
+			scoring to improve the ordering.
+
+	double		Internal method that uses two methods and mixes the
+			results.  The first method is "fast", the other method
+			computes how much the suggestion sounds like the bad
+			word.  That only works when the language specifies
+			sound folding.  Can be slow and doesn't always give
+			better results.
+
+	fast		Internal method that only checks for simple changes:
+			character inserts/deletes/swaps.  Works well for
+			simple typing mistakes.
+
+	{number}	The maximum number of suggestions listed for |z=|.
+			Not used for |spellsuggest()|.  The number of
+			suggestions is never more than the value of 'lines'
+			minus two.
+
+	file:{filename} Read file {filename}, which must have two columns,
+			separated by a slash.  The first column contains the
+			bad word, the second column the suggested good word.
+			Example:
+				theribal/terrible ~
+			Use this for common mistakes that do not appear at the
+			top of the suggestion list with the internal methods.
+			Lines without a slash are ignored, use this for
+			comments.
+			The file is used for all languages.
+
+	expr:{expr}	Evaluate expression {expr}.  Use a function to avoid
+			trouble with spaces.  |v:val| holds the badly spelled
+			word.  The expression must evaluate to a List of
+			Lists, each with a suggestion and a score.
+			Example:
+				[['the', 33], ['that', 44]]
+			Set 'verbose' and use |z=| to see the scores that the
+			internal methods use.  A lower score is better.
+			This may invoke |spellsuggest()| if you temporarily
+			set 'spellsuggest' to exclude the "expr:" part.
+			Errors are silently ignored, unless you set the
+			'verbose' option to a non-zero value.
+
+	Only one of "best", "double" or "fast" may be used.  The others may
+	appear several times in any order.  Example: >
+		:set sps=file:~/.vim/sugg,best,expr:MySuggest()
+<
+	This option cannot be set from a |modeline| or in the |sandbox|, for
+	security reasons.
+
+
+			*'splitbelow'* *'sb'* *'nosplitbelow'* *'nosb'*
+'splitbelow' 'sb'	boolean	(default off)
+			global
+			{not in Vi}
+			{not available when compiled without the +windows
+			feature}
+	When on, splitting a window will put the new window below the current
+	one. |:split|
+
+			*'splitright'* *'spr'* *'nosplitright'* *'nospr'*
+'splitright' 'spr'	boolean	(default off)
+			global
+			{not in Vi}
+			{not available when compiled without the +vertsplit
+			feature}
+	When on, splitting a window will put the new window right of the
+	current one. |:vsplit|
+
+			   *'startofline'* *'sol'* *'nostartofline'* *'nosol'*
+'startofline' 'sol'	boolean	(default on)
+			global
+			{not in Vi}
+	When "on" the commands listed below move the cursor to the first
+	non-blank of the line.  When off the cursor is kept in the same column
+	(if possible).  This applies to the commands: CTRL-D, CTRL-U, CTRL-B,
+	CTRL-F, "G", "H", "M", "L", gg, and to the commands "d", "<<" and ">>"
+	with a linewise operator, with "%" with a count and to buffer changing
+	commands (CTRL-^, :bnext, :bNext, etc.).  Also for an Ex command that
+	only has a line number, e.g., ":25" or ":+".
+	In case of buffer changing commands the cursor is placed at the column
+	where it was the last time the buffer was edited.
+	NOTE: This option is set when 'compatible' is set.
+
+			   *'statusline'* *'stl'* *E540* *E541* *E542*
+'statusline' 'stl'	string	(default empty)
+			global or local to window |global-local|
+			{not in Vi}
+			{not available when compiled without the |+statusline|
+			feature}
+	When nonempty, this option determines the content of the status line.
+	Also see |status-line|.
+
+	The option consists of printf style '%' items interspersed with
+	normal text.  Each status line item is of the form:
+	  %-0{minwid}.{maxwid}{item}
+	All fields except the {item} is optional.  A single percent sign can
+	be given as "%%".  Up to 80 items can be specified.
+
+	When the option starts with "%!" then it is used as an expression,
+	evaluated and the result is used as the option value.  Example: >
+		:set statusline=%!MyStatusLine()
+<	The result can contain %{} items that will be evaluated too.
+
+	When there is error while evaluating the option then it will be made
+	empty to avoid further errors.  Otherwise screen updating would loop.
+
+	Note that the only effect of 'ruler' when this option is set (and
+	'laststatus' is 2) is controlling the output of |CTRL-G|.
+
+	field	    meaning ~
+	-	    Left justify the item.  The default is right justified
+		    when minwid is larger than the length of the item.
+	0	    Leading zeroes in numeric items.  Overridden by '-'.
+	minwid	    Minimum width of the item, padding as set by '-' & '0'.
+		    Value must be 50 or less.
+	maxwid	    Maximum width of the item.  Truncation occurs with a '<'
+		    on the left for text items.  Numeric items will be
+		    shifted down to maxwid-2 digits followed by '>'number
+		    where number is the amount of missing digits, much like
+		    an exponential notation.
+	item	    A one letter code as described below.
+
+	Following is a description of the possible statusline items.  The
+	second character in "item" is the type:
+		N for number
+		S for string
+		F for flags as described below
+		- not applicable
+
+	item  meaning ~
+	f S   Path to the file in the buffer, as typed or relative to current
+	      directory.
+	F S   Full path to the file in the buffer.
+	t S   File name (tail) of file in the buffer.
+	m F   Modified flag, text is " [+]"; " [-]" if 'modifiable' is off.
+	M F   Modified flag, text is ",+" or ",-".
+	r F   Readonly flag, text is " [RO]".
+	R F   Readonly flag, text is ",RO".
+	h F   Help buffer flag, text is " [help]".
+	H F   Help buffer flag, text is ",HLP".
+	w F   Preview window flag, text is " [Preview]".
+	W F   Preview window flag, text is ",PRV".
+	y F   Type of file in the buffer, e.g., " [vim]".  See 'filetype'.
+	Y F   Type of file in the buffer, e.g., ",VIM".  See 'filetype'.
+	      {not available when compiled without |+autocmd| feature}
+	k S   Value of "b:keymap_name" or 'keymap' when |:lmap| mappings are
+	      being used: "<keymap>"
+	n N   Buffer number.
+	b N   Value of byte under cursor.
+	B N   As above, in hexadecimal.
+	o N   Byte number in file of byte under cursor, first byte is 1.
+	      Mnemonic: Offset from start of file (with one added)
+	      {not available when compiled without |+byte_offset| feature}
+	O N   As above, in hexadecimal.
+	N N   Printer page number.  (Only works in the 'printheader' option.)
+	l N   Line number.
+	L N   Number of lines in buffer.
+	c N   Column number.
+	v N   Virtual column number.
+	V N   Virtual column number as -{num}.  Not displayed if equal to 'c'.
+	p N   Percentage through file in lines as in |CTRL-G|.
+	P S   Percentage through file of displayed window.  This is like the
+	      percentage described for 'ruler'.  Always 3 in length.
+	a S   Argument list status as in default title.  ({current} of {max})
+	      Empty if the argument file count is zero or one.
+	{ NF  Evaluate expression between '%{' and '}' and substitute result.
+	      Note that there is no '%' before the closing '}'.
+	( -   Start of item group.  Can be used for setting the width and
+	      alignment of a section.  Must be followed by %) somewhere.
+	) -   End of item group.  No width fields allowed.
+	T N   For 'tabline': start of tab page N label.  Use %T after the last
+	      label.  This information is used for mouse clicks.
+	X N   For 'tabline': start of close tab N label.  Use %X after the
+	      label, e.g.: %3Xclose%X.  Use %999X for a "close current tab"
+	      mark.  This information is used for mouse clicks.
+	< -   Where to truncate line if too long.  Default is at the start.
+	      No width fields allowed.
+	= -   Separation point between left and right aligned items.
+	      No width fields allowed.
+	# -   Set highlight group.  The name must follow and then a # again.
+	      Thus use %#HLname# for highlight group HLname.  The same
+	      highlighting is used, also for the statusline of non-current
+	      windows.
+	* -   Set highlight group to User{N}, where {N} is taken from the
+	      minwid field, e.g. %1*.  Restore normal highlight with %* or %0*.
+	      The difference between User{N} and StatusLine  will be applied
+	      to StatusLineNC for the statusline of non-current windows.
+	      The number N must be between 1 and 9.  See |hl-User1..9|
+
+	Display of flags are controlled by the following heuristic:
+	If a flag text starts with comma it is assumed that it wants to
+	separate itself from anything but preceding plaintext.  If it starts
+	with a space it is assumed that it wants to separate itself from
+	anything but other flags.  That is: A leading comma is removed if the
+	preceding character stems from plaintext.  A leading space is removed
+	if the preceding character stems from another active flag.  This will
+	make a nice display when flags are used like in the examples below.
+
+	When all items in a group becomes an empty string (i.e. flags that are
+	not set) and a minwid is not set for the group, the whole group will
+	become empty.  This will make a group like the following disappear
+	completely from the statusline when none of the flags are set. >
+		:set statusline=...%(\ [%M%R%H]%)...
+<
+	Beware that an expression is evaluated each and every time the status
+	line is displayed.  The current buffer and current window will be set
+	temporarily to that of the window (and buffer) whose statusline is
+	currently being drawn.  The expression will evaluate in this context.
+	The variable "actual_curbuf" is set to the 'bufnr()' number of the
+	real current buffer.
+
+	The 'statusline' option may be evaluated in the |sandbox|, see
+	|sandbox-option|.
+
+	It is not allowed to change text or jump to another window while
+	evaluating 'statusline' |textlock|.
+
+	If the statusline is not updated when you want it (e.g., after setting
+	a variable that's used in an expression), you can force an update by
+	setting an option without changing its value.  Example: >
+		:let &ro = &ro
+
+<	A result of all digits is regarded a number for display purposes.
+	Otherwise the result is taken as flag text and applied to the rules
+	described above.
+
+	Watch out for errors in expressions.  They may render Vim unusable!
+	If you are stuck, hold down ':' or 'Q' to get a prompt, then quit and
+	edit your .vimrc or whatever with "vim -u NONE" to get it right.
+
+	Examples:
+	Emulate standard status line with 'ruler' set >
+	  :set statusline=%<%f\ %h%m%r%=%-14.(%l,%c%V%)\ %P
+<	Similar, but add ASCII value of char under the cursor (like "ga") >
+	  :set statusline=%<%f%h%m%r%=%b\ 0x%B\ \ %l,%c%V\ %P
+<	Display byte count and byte value, modified flag in red. >
+	  :set statusline=%<%f%=\ [%1*%M%*%n%R%H]\ %-19(%3l,%02c%03V%)%O'%02b'
+	  :hi User1 term=inverse,bold cterm=inverse,bold ctermfg=red
+<	Display a ,GZ flag if a compressed file is loaded >
+	  :set statusline=...%r%{VarExists('b:gzflag','\ [GZ]')}%h...
+<	In the |:autocmd|'s: >
+	  :let b:gzflag = 1
+<	And: >
+	  :unlet b:gzflag
+<	And define this function: >
+	  :function VarExists(var, val)
+	  :    if exists(a:var) | return a:val | else | return '' | endif
+	  :endfunction
+<
+						*'suffixes'* *'su'*
+'suffixes' 'su'		string	(default ".bak,~,.o,.h,.info,.swp,.obj")
+			global
+			{not in Vi}
+	Files with these suffixes get a lower priority when multiple files
+	match a wildcard.  See |suffixes|.  Commas can be used to separate the
+	suffixes.  Spaces after the comma are ignored.  A dot is also seen as
+	the start of a suffix.  To avoid a dot or comma being recognized as a
+	separator, precede it with a backslash (see |option-backslash| about
+	including spaces and backslashes).
+	See 'wildignore' for completely ignoring files.
+	The use of |:set+=| and |:set-=| is preferred when adding or removing
+	suffixes from the list.  This avoids problems when a future version
+	uses another default.
+
+						*'suffixesadd'* *'sua'*
+'suffixesadd' 'sua'	string	(default "")
+			local to buffer
+			{not in Vi}
+			{not available when compiled without the
+			|+file_in_path| feature}
+	Comma separated list of suffixes, which are used when searching for a
+	file for the "gf", "[I", etc. commands.  Example: >
+		:set suffixesadd=.java
+<
+				*'swapfile'* *'swf'* *'noswapfile'* *'noswf'*
+'swapfile' 'swf'	boolean (default on)
+			local to buffer
+			{not in Vi}
+	Use a swapfile for the buffer.  This option can be reset when a
+	swapfile is not wanted for a specific buffer.  For example, with
+	confidential information that even root must not be able to access.
+	Careful: All text will be in memory:
+		- Don't use this for big files.
+		- Recovery will be impossible!
+	A swapfile will only be present when |'updatecount'| is non-zero and
+	'swapfile' is set.
+	When 'swapfile' is reset, the swap file for the current buffer is
+	immediately deleted.  When 'swapfile' is set, and 'updatecount' is
+	non-zero, a swap file is immediately created.
+	Also see |swap-file| and |'swapsync'|.
+
+	This option is used together with 'bufhidden' and 'buftype' to
+	specify special kinds of buffers.   See |special-buffers|.
+
+						*'swapsync'* *'sws'*
+'swapsync' 'sws'	string	(default "fsync")
+			global
+			{not in Vi}
+	When this option is not empty a swap file is synced to disk after
+	writing to it.  This takes some time, especially on busy unix systems.
+	When this option is empty parts of the swap file may be in memory and
+	not written to disk.  When the system crashes you may lose more work.
+	On Unix the system does a sync now and then without Vim asking for it,
+	so the disadvantage of setting this option off is small.  On some
+	systems the swap file will not be written at all.  For a unix system
+	setting it to "sync" will use the sync() call instead of the default
+	fsync(), which may work better on some systems.
+	The 'fsync' option is used for the actual file.
+
+						*'switchbuf'* *'swb'*
+'switchbuf' 'swb'	string	(default "")
+			global
+			{not in Vi}
+	This option controls the behavior when switching between buffers.
+	Possible values (comma separated list):
+	   useopen	If included, jump to the first open window that
+			contains the specified buffer (if there is one).
+			Otherwise: Do not examine other windows.
+			This setting is checked with |quickfix| commands, when
+			jumping to errors (":cc", ":cn", "cp", etc.).  It is
+			also used in all buffer related split commands, for
+			example ":sbuffer", ":sbnext", or ":sbrewind".
+	   usetab	Like "useopen", but also consider windows in other tab
+			pages.
+	   split	If included, split the current window before loading
+			a buffer.  Otherwise: do not split, use current window.
+			Supported in |quickfix| commands that display errors.
+
+						*'synmaxcol'* *'smc'*
+'synmaxcol' 'smc'	number	(default 3000)
+			local to buffer
+			{not in Vi}
+			{not available when compiled without the |+syntax|
+			feature}
+	Maximum column in which to search for syntax items.  In long lines the
+	text after this column is not highlighted and following lines may not
+	be highlighted correctly, because the syntax state is cleared.
+	This helps to avoid very slow redrawing for an XML file that is one
+	long line.
+	Set to zero to remove the limit.
+
+						*'syntax'* *'syn'*
+'syntax' 'syn'		string	(default empty)
+			local to buffer
+			{not in Vi}
+			{not available when compiled without the |+syntax|
+			feature}
+	When this option is set, the syntax with this name is loaded, unless
+	syntax highlighting has been switched off with ":syntax off".
+	Otherwise this option does not always reflect the current syntax (the
+	b:current_syntax variable does).
+	This option is most useful in a modeline, for a file which syntax is
+	not automatically recognized.  Example, in an IDL file:
+		/* vim: set syntax=idl : */ ~
+	When a dot appears in the value then this separates two filetype
+	names.  Example:
+		/* vim: set syntax=c.doxygen : */ ~
+	This will use the "c" syntax first, then the "doxygen" syntax.
+	Note that the second one must be prepared to be loaded as an addition,
+	otherwise it will be skipped.  More than one dot may appear.
+	To switch off syntax highlighting for the current file, use: >
+		:set syntax=OFF
+<	To switch syntax highlighting on according to the current value of the
+	'filetype' option: >
+		:set syntax=ON
+<	What actually happens when setting the 'syntax' option is that the
+	Syntax autocommand event is triggered with the value as argument.
+	This option is not copied to another buffer, independent of the 's' or
+	'S' flag in 'cpoptions'.
+	Only normal file name characters can be used, "/\*?[|<>" are illegal.
+
+						*'tabline'* *'tal'*
+'tabline' 'tal'		string	(default empty)
+			global
+			{not in Vi}
+			{not available when compiled without the +windows
+			feature}
+	When nonempty, this option determines the content of the tab pages
+	line at the top of the Vim window.  When empty Vim will use a default
+	tab pages line.  See |setting-tabline| for more info.
+
+	The tab pages line only appears as specified with the 'showtabline'
+	option and only when there is no GUI tab line.  When 'e' is in
+	'guioptions' and the GUI supports a tab line 'guitablabel' is used
+	instead.
+
+	The value is evaluated like with 'statusline'.  You can use
+	|tabpagenr()|, |tabpagewinnr()| and |tabpagebuflist()| to figure out
+	the text to be displayed.  Use "%1T" for the first label, "%2T" for
+	the second one, etc.  Use "%X" items for closing labels.
+
+	Keep in mind that only one of the tab pages is the current one, others
+	are invisible and you can't jump to their windows.
+
+
+						*'tabpagemax'* *'tpm'*
+'tabpagemax' 'tpm'	number	(default 10)
+			global
+			{not in Vi}
+			{not available when compiled without the +windows
+			feature}
+	Maximum number of tab pages to be opened by the |-p| command line
+	argument or the ":tab all" command. |tabpage|
+
+
+						*'tabstop'* *'ts'*
+'tabstop' 'ts'		number	(default 8)
+			local to buffer
+	Number of spaces that a <Tab> in the file counts for.  Also see
+	|:retab| command, and 'softtabstop' option.
+
+	Note: Setting 'tabstop' to any other value than 8 can make your file
+	appear wrong in many places (e.g., when printing it).
+
+	There are four main ways to use tabs in Vim:
+	1. Always keep 'tabstop' at 8, set 'softtabstop' and 'shiftwidth' to 4
+	   (or 3 or whatever you prefer) and use 'noexpandtab'.  Then Vim
+	   will use a mix of tabs and spaces, but typing <Tab> and <BS> will
+	   behave like a tab appears every 4 (or 3) characters.
+	2. Set 'tabstop' and 'shiftwidth' to whatever you prefer and use
+	   'expandtab'.  This way you will always insert spaces.  The
+	   formatting will never be messed up when 'tabstop' is changed.
+	3. Set 'tabstop' and 'shiftwidth' to whatever you prefer and use a
+	   |modeline| to set these values when editing the file again.  Only
+	   works when using Vim to edit the file.
+	4. Always set 'tabstop' and 'shiftwidth' to the same value, and
+	   'noexpandtab'.  This should then work (for initial indents only)
+	   for any tabstop setting that people use.  It might be nice to have
+	   tabs after the first non-blank inserted as spaces if you do this
+	   though.  Otherwise aligned comments will be wrong when 'tabstop' is
+	   changed.
+
+			*'tagbsearch'* *'tbs'* *'notagbsearch'* *'notbs'*
+'tagbsearch' 'tbs'	boolean	(default on)
+			global
+			{not in Vi}
+	When searching for a tag (e.g., for the |:ta| command), Vim can either
+	use a binary search or a linear search in a tags file.  Binary
+	searching makes searching for a tag a LOT faster, but a linear search
+	will find more tags if the tags file wasn't properly sorted.
+	Vim normally assumes that your tags files are sorted, or indicate that
+	they are not sorted.  Only when this is not the case does the
+	'tagbsearch' option need to be switched off.
+
+	When 'tagbsearch' is on, binary searching is first used in the tags
+	files.  In certain situations, Vim will do a linear search instead for
+	certain files, or retry all files with a linear search.  When
+	'tagbsearch' is off, only a linear search is done.
+
+	Linear searching is done anyway, for one file, when Vim finds a line
+	at the start of the file indicating that it's not sorted: >
+   !_TAG_FILE_SORTED	0	/some command/
+<	[The whitespace before and after the '0' must be a single <Tab>]
+
+	When a binary search was done and no match was found in any of the
+	files listed in 'tags', and 'ignorecase' is set or a pattern is used
+	instead of a normal tag name, a retry is done with a linear search.
+	Tags in unsorted tags files, and matches with different case will only
+	be found in the retry.
+
+	If a tag file indicates that it is case-fold sorted, the second,
+	linear search can be avoided for the 'ignorecase' case.  Use a value
+	of '2' in the "!_TAG_FILE_SORTED" line for this.  A tag file can be
+	case-fold sorted with the -f switch to "sort" in most unices, as in
+	the command: "sort -f -o tags tags".  For "Exuberant ctags" version
+	5.3 or higher the -f or --fold-case-sort switch can be used for this
+	as well.  Note that case must be folded to uppercase for this to work.
+
+	When 'tagbsearch' is off, tags searching is slower when a full match
+	exists, but faster when no full match exists.  Tags in unsorted tags
+	files may only be found with 'tagbsearch' off.
+	When the tags file is not sorted, or sorted in a wrong way (not on
+	ASCII byte value), 'tagbsearch' should be off, or the line given above
+	must be included in the tags file.
+	This option doesn't affect commands that find all matching tags (e.g.,
+	command-line completion and ":help").
+	{Vi: always uses binary search in some versions}
+
+						*'taglength'* *'tl'*
+'taglength' 'tl'	number	(default 0)
+			global
+	If non-zero, tags are significant up to this number of characters.
+
+			*'tagrelative'* *'tr'* *'notagrelative'* *'notr'*
+'tagrelative' 'tr'	boolean	(Vim default: on, Vi default: off)
+			global
+			{not in Vi}
+	If on and using a tags file in another directory, file names in that
+	tags file are relative to the directory where the tags file is.
+	NOTE: This option is set to the Vi default value when 'compatible' is
+	set and to the Vim default value when 'compatible' is reset.
+
+						*'tags'* *'tag'* *E433*
+'tags' 'tag'		string	(default "./tags,tags", when compiled with
+				|+emacs_tags|: "./tags,./TAGS,tags,TAGS")
+			global or local to buffer |global-local|
+	Filenames for the tag command, separated by spaces or commas.  To
+	include a space or comma in a file name, precede it with a backslash
+	(see |option-backslash| about including spaces and backslashes).
+	When a file name starts with "./", the '.' is replaced with the path
+	of the current file.  But only when the 'd' flag is not included in
+	'cpoptions'.  Environment variables are expanded |:set_env|.  Also see
+	|tags-option|.
+	"*", "**" and other wildcards can be used to search for tags files in
+	a directory tree.  See |file-searching|.  {not available when compiled
+	without the |+path_extra| feature}
+	The |tagfiles()| function can be used to get a list of the file names
+	actually used.
+	If Vim was compiled with the |+emacs_tags| feature, Emacs-style tag
+	files are also supported.  They are automatically recognized.  The
+	default value becomes "./tags,./TAGS,tags,TAGS", unless case
+	differences are ignored (MS-Windows).  |emacs-tags|
+	The use of |:set+=| and |:set-=| is preferred when adding or removing
+	file names from the list.  This avoids problems when a future version
+	uses another default.
+	{Vi: default is "tags /usr/lib/tags"}
+
+				*'tagstack'* *'tgst'* *'notagstack'* *'notgst'*
+'tagstack' 'tgst'	boolean	(default on)
+			global
+			{not in all versions of Vi}
+	When on, the |tagstack| is used normally.  When off, a ":tag" or
+	":tselect" command with an argument will not push the tag onto the
+	tagstack.  A following ":tag" without an argument, a ":pop" command or
+	any other command that uses the tagstack will use the unmodified
+	tagstack, but does change the pointer to the active entry.
+	Resetting this option is useful when using a ":tag" command in a
+	mapping which should not change the tagstack.
+
+						*'term'* *E529* *E530* *E531*
+'term'			string	(default is $TERM, if that fails:
+				      in the GUI: "builtin_gui"
+					on Amiga: "amiga"
+					 on BeOS: "beos-ansi"
+					  on Mac: "mac-ansi"
+					 on MiNT: "vt52"
+				       on MS-DOS: "pcterm"
+					 on OS/2: "os2ansi"
+					 on Unix: "ansi"
+					  on VMS: "ansi"
+				       on Win 32: "win32")
+			global
+	Name of the terminal.  Used for choosing the terminal control
+	characters.  Environment variables are expanded |:set_env|.
+	For example: >
+		:set term=$TERM
+<	See |termcap|.
+
+						*'termbidi'* *'tbidi'*
+						*'notermbidi'* *'notbidi'*
+'termbidi' 'tbidi'	boolean (default off, on for "mlterm")
+			global
+			{not in Vi}
+			{only available when compiled with the |+arabic|
+			feature}
+	The terminal is in charge of Bi-directionality of text (as specified
+	by Unicode).  The terminal is also expected to do the required shaping
+	that some languages (such as Arabic) require.
+	Setting this option implies that 'rightleft' will not be set when
+	'arabic' is set and the value of 'arabicshape' will be ignored.
+	Note that setting 'termbidi' has the immediate effect that
+	'arabicshape' is ignored, but 'rightleft' isn't changed automatically.
+	This option is reset when the GUI is started.
+	For further details see |arabic.txt|.
+
+					*'termencoding'* *'tenc'*
+'termencoding' 'tenc'	string	(default ""; with GTK+ 2 GUI: "utf-8"; with
+						    Macintosh GUI: "macroman")
+			global
+			{only available when compiled with the |+multi_byte|
+			feature}
+			{not in Vi}
+	Encoding used for the terminal.  This specifies what character
+	encoding the keyboard produces and the display will understand.  For
+	the GUI it only applies to the keyboard ('encoding' is used for the
+	display).  Except for the Mac when 'macatsui' is off, then
+	'termencoding' should be "macroman".
+	In the Win32 console version the default value is the console codepage
+	when it differs from the ANSI codepage.
+								*E617*
+	Note: This does not apply to the GTK+ 2 GUI.  After the GUI has been
+	successfully initialized, 'termencoding' is forcibly set to "utf-8".
+	Any attempts to set a different value will be rejected, and an error
+	message is shown.
+	For the Win32 GUI 'termencoding' is not used for typed characters,
+	because the Win32 system always passes Unicode characters.
+	When empty, the same encoding is used as for the 'encoding' option.
+	This is the normal value.
+	Not all combinations for 'termencoding' and 'encoding' are valid.  See
+	|encoding-table|.
+	The value for this option must be supported by internal conversions or
+	iconv().  When this is not possible no conversion will be done and you
+	will probably experience problems with non-ASCII characters.
+	Example: You are working with the locale set to euc-jp (Japanese) and
+	want to edit a UTF-8 file: >
+		:let &termencoding = &encoding
+		:set encoding=utf-8
+<	You need to do this when your system has no locale support for UTF-8.
+
+						*'terse'* *'noterse'*
+'terse'			boolean	(default off)
+			global
+	When set: Add 's' flag to 'shortmess' option (this makes the message
+	for a search that hits the start or end of the file not being
+	displayed).  When reset: Remove 's' flag from 'shortmess' option.  {Vi
+	shortens a lot of messages}
+
+				   *'textauto'* *'ta'* *'notextauto'* *'nota'*
+'textauto' 'ta'		boolean	(Vim default: on, Vi default: off)
+			global
+			{not in Vi}
+	This option is obsolete.  Use 'fileformats'.
+	For backwards compatibility, when 'textauto' is set, 'fileformats' is
+	set to the default value for the current system.  When 'textauto' is
+	reset, 'fileformats' is made empty.
+	NOTE: This option is set to the Vi default value when 'compatible' is
+	set and to the Vim default value when 'compatible' is reset.
+
+				   *'textmode'* *'tx'* *'notextmode'* *'notx'*
+'textmode' 'tx'		boolean	(MS-DOS, Win32 and OS/2: default on,
+				 others: default off)
+			local to buffer
+			{not in Vi}
+	This option is obsolete.  Use 'fileformat'.
+	For backwards compatibility, when 'textmode' is set, 'fileformat' is
+	set to "dos".  When 'textmode' is reset, 'fileformat' is set to
+	"unix".
+
+						*'textwidth'* *'tw'*
+'textwidth' 'tw'	number	(default 0)
+			local to buffer
+			{not in Vi}
+	Maximum width of text that is being inserted.  A longer line will be
+	broken after white space to get this width.  A zero value disables
+	this.  'textwidth' is set to 0 when the 'paste' option is set.  When
+	'textwidth' is zero, 'wrapmargin' may be used.  See also
+	'formatoptions' and |ins-textwidth|.
+	When 'formatexpr' is set it will be used to break the line.
+	NOTE: This option is set to 0 when 'compatible' is set.
+
+						*'thesaurus'* *'tsr'*
+'thesaurus' 'tsr'	string	(default "")
+			global or local to buffer |global-local|
+			{not in Vi}
+	List of file names, separated by commas, that are used to lookup words
+	for thesaurus completion commands |i_CTRL-X_CTRL-T|.  Each line in
+	the file should contain words with similar meaning, separated by
+	non-keyword characters (white space is preferred).  Maximum line
+	length is 510 bytes.
+	To obtain a file to be used here, check out the wordlist FAQ at
+	http://www.hyphenologist.co.uk .
+	To include a comma in a file name precede it with a backslash.  Spaces
+	after a comma are ignored, otherwise spaces are included in the file
+	name.  See |option-backslash| about using backslashes.
+	The use of |:set+=| and |:set-=| is preferred when adding or removing
+	directories from the list.  This avoids problems when a future version
+	uses another default.
+	Backticks cannot be used in this option for security reasons.
+
+			     *'tildeop'* *'top'* *'notildeop'* *'notop'*
+'tildeop' 'top'		boolean	(default off)
+			global
+			{not in Vi}
+	When on: The tilde command "~" behaves like an operator.
+	NOTE: This option is reset when 'compatible' is set.
+
+				*'timeout'* *'to'* *'notimeout'* *'noto'*
+'timeout' 'to'		boolean (default on)
+			global
+						*'ttimeout'* *'nottimeout'*
+'ttimeout'		boolean (default off)
+			global
+			{not in Vi}
+	These two options together determine the behavior when part of a
+	mapped key sequence or keyboard code has been received:
+
+	'timeout'    'ttimeout'		action	~
+	   off		off		do not time out
+	   on		on or off	time out on :mappings and key codes
+	   off		on		time out on key codes
+
+	If both options are off, Vim will wait until either the complete
+	mapping or key sequence has been received, or it is clear that there
+	is no mapping or key sequence for the received characters.  For
+	example: if you have mapped "vl" and Vim has received 'v', the next
+	character is needed to see if the 'v' is followed by an 'l'.
+	When one of the options is on, Vim will wait for about 1 second for
+	the next character to arrive.  After that the already received
+	characters are interpreted as single characters.  The waiting time can
+	be changed with the 'timeoutlen' option.
+	On slow terminals or very busy systems timing out may cause
+	malfunctioning cursor keys.  If both options are off, Vim waits
+	forever after an entered <Esc> if there are key codes that start
+	with <Esc>.  You will have to type <Esc> twice.  If you do not have
+	problems with key codes, but would like to have :mapped key
+	sequences not timing out in 1 second, set the 'ttimeout' option and
+	reset the 'timeout' option.
+
+	NOTE: 'ttimeout' is reset when 'compatible' is set.
+
+						*'timeoutlen'* *'tm'*
+'timeoutlen' 'tm'	number	(default 1000)
+			global
+			{not in all versions of Vi}
+						*'ttimeoutlen'* *'ttm'*
+'ttimeoutlen' 'ttm'	number	(default -1)
+			global
+			{not in Vi}
+	The time in milliseconds that is waited for a key code or mapped key
+	sequence to complete.  Also used for CTRL-\ CTRL-N and CTRL-\ CTRL-G
+	when part of a command has been typed.
+	Normally only 'timeoutlen' is used and 'ttimeoutlen' is -1.  When a
+	different timeout value for key codes is desired set 'ttimeoutlen' to
+	a non-negative number.
+
+		ttimeoutlen	mapping delay	   key code delay	~
+		   < 0		'timeoutlen'	   'timeoutlen'
+		  >= 0		'timeoutlen'	   'ttimeoutlen'
+
+	The timeout only happens when the 'timeout' and 'ttimeout' options
+	tell so.  A useful setting would be >
+		:set timeout timeoutlen=3000 ttimeoutlen=100
+<	(time out on mapping after three seconds, time out on key codes after
+	a tenth of a second).
+
+						*'title'* *'notitle'*
+'title'			boolean	(default off, on when title can be restored)
+			global
+			{not in Vi}
+			{not available when compiled without the |+title|
+			feature}
+	When on, the title of the window will be set to the value of
+	'titlestring' (if it is not empty), or to:
+		filename [+=-] (path) - VIM
+	Where:
+		filename	the name of the file being edited
+		-		indicates the file cannot be modified, 'ma' off
+		+		indicates the file was modified
+		=		indicates the file is read-only
+		=+		indicates the file is read-only and modified
+		(path)		is the path of the file being edited
+		- VIM		the server name |v:servername| or "VIM"
+	Only works if the terminal supports setting window titles
+	(currently Amiga console, Win32 console, all GUI versions and
+	terminals with a non- empty 't_ts' option - these are Unix xterm and
+	iris-ansi by default, where 't_ts' is taken from the builtin termcap).
+								*X11*
+	When Vim was compiled with HAVE_X11 defined, the original title will
+	be restored if possible.  The output of ":version" will include "+X11"
+	when HAVE_X11 was defined, otherwise it will be "-X11".  This also
+	works for the icon name |'icon'|.
+	But: When Vim was started with the |-X| argument, restoring the title
+	will not work (except in the GUI).
+	If the title cannot be restored, it is set to the value of 'titleold'.
+	You might want to restore the title outside of Vim then.
+	When using an xterm from a remote machine you can use this command:
+	    rsh machine_name xterm -display $DISPLAY &
+	then the WINDOWID environment variable should be inherited and the
+	title of the window should change back to what it should be after
+	exiting Vim.
+
+								*'titlelen'*
+'titlelen'		number	(default 85)
+			global
+			{not in Vi}
+			{not available when compiled without the |+title|
+			feature}
+	Gives the percentage of 'columns' to use for the length of the window
+	title.  When the title is longer, only the end of the path name is
+	shown.  A '<' character before the path name is used to indicate this.
+	Using a percentage makes this adapt to the width of the window.  But
+	it won't work perfectly, because the actual number of characters
+	available also depends on the font used and other things in the title
+	bar.  When 'titlelen' is zero the full path is used.  Otherwise,
+	values from 1 to 30000 percent can be used.
+	'titlelen' is also used for the 'titlestring' option.
+
+						*'titleold'*
+'titleold'		string	(default "Thanks for flying Vim")
+			global
+			{not in Vi}
+			{only available when compiled with the |+title|
+			feature}
+	This option will be used for the window title when exiting Vim if the
+	original title cannot be restored.  Only happens if 'title' is on or
+	'titlestring' is not empty.
+	This option cannot be set from a |modeline| or in the |sandbox|, for
+	security reasons.
+						*'titlestring'*
+'titlestring'		string	(default "")
+			global
+			{not in Vi}
+			{not available when compiled without the |+title|
+			feature}
+	When this option is not empty, it will be used for the title of the
+	window.  This happens only when the 'title' option is on.
+	Only works if the terminal supports setting window titles (currently
+	Amiga console, Win32 console, all GUI versions and terminals with a
+	non-empty 't_ts' option).
+	When Vim was compiled with HAVE_X11 defined, the original title will
+	be restored if possible |X11|.
+	When this option contains printf-style '%' items, they will be
+	expanded according to the rules used for 'statusline'.
+	Example: >
+    :auto BufEnter * let &titlestring = hostname() . "/" . expand("%:p")
+    :set title titlestring=%<%F%=%l/%L-%P titlelen=70
+<	The value of 'titlelen' is used to align items in the middle or right
+	of the available space.
+	Some people prefer to have the file name first: >
+    :set titlestring=%t%(\ %M%)%(\ (%{expand(\"%:~:.:h\")})%)%(\ %a%)
+<	Note the use of "%{ }" and an expression to get the path of the file,
+	without the file name.  The "%( %)" constructs are used to add a
+	separating space only when needed.
+	NOTE: Use of special characters in 'titlestring' may cause the display
+	to be garbled (e.g., when it contains a CR or NL character).
+	{not available when compiled without the |+statusline| feature}
+
+				*'toolbar'* *'tb'*
+'toolbar' 'tb'		string	(default "icons,tooltips")
+			global
+			{only for |+GUI_GTK|, |+GUI_Athena|, |+GUI_Motif| and
+			|+GUI_Photon|}
+	The contents of this option controls various toolbar settings.  The
+	possible values are:
+		icons		Toolbar buttons are shown with icons.
+		text		Toolbar buttons shown with text.
+		horiz		Icon and text of a toolbar button are
+				horizontally arranged.  {only in GTK+ 2 GUI}
+		tooltips	Tooltips are active for toolbar buttons.
+	Tooltips refer to the popup help text which appears after the mouse
+	cursor is placed over a toolbar button for a brief moment.
+
+	If you want the toolbar to be shown with icons as well as text, do the
+	following: >
+		:set tb=icons,text
+<	Motif and Athena cannot display icons and text at the same time.  They
+	will show icons if both are requested.
+
+	If none of the strings specified in 'toolbar' are valid or if
+	'toolbar' is empty, this option is ignored.  If you want to disable
+	the toolbar, you need to set the 'guioptions' option.  For example: >
+		:set guioptions-=T
+<	Also see |gui-toolbar|.
+
+						*'toolbariconsize'* *'tbis'*
+'toolbariconsize' 'tbis'	string	(default "small")
+				global
+				{not in Vi}
+				{only in the GTK+ 2 GUI}
+	Controls the size of toolbar icons.  The possible values are:
+		tiny		Use tiny toolbar icons.
+		small		Use small toolbar icons (default).
+		medium		Use medium-sized toolbar icons.
+		large		Use large toolbar icons.
+	The exact dimensions in pixels of the various icon sizes depend on
+	the current theme.  Common dimensions are large=32x32, medium=24x24,
+	small=20x20 and tiny=16x16.
+
+	If 'toolbariconsize' is empty, the global default size as determined
+	by user preferences or the current theme is used.
+
+			     *'ttybuiltin'* *'tbi'* *'nottybuiltin'* *'notbi'*
+'ttybuiltin' 'tbi'	boolean	(default on)
+			global
+			{not in Vi}
+	When on, the builtin termcaps are searched before the external ones.
+	When off the builtin termcaps are searched after the external ones.
+	When this option is changed, you should set the 'term' option next for
+	the change to take effect, for example: >
+		:set notbi term=$TERM
+<	See also |termcap|.
+	Rationale: The default for this option is "on", because the builtin
+	termcap entries are generally better (many systems contain faulty
+	xterm entries...).
+
+				     *'ttyfast'* *'tf'* *'nottyfast'* *'notf'*
+'ttyfast' 'tf'		boolean	(default off, on when 'term' is xterm, hpterm,
+					sun-cmd, screen, rxvt, dtterm or
+					iris-ansi; also on when running Vim in
+					a DOS console)
+			global
+			{not in Vi}
+	Indicates a fast terminal connection.  More characters will be sent to
+	the screen for redrawing, instead of using insert/delete line
+	commands.  Improves smoothness of redrawing when there are multiple
+	windows and the terminal does not support a scrolling region.
+	Also enables the extra writing of characters at the end of each screen
+	line for lines that wrap.  This helps when using copy/paste with the
+	mouse in an xterm and other terminals.
+
+						*'ttymouse'* *'ttym'*
+'ttymouse' 'ttym'	string	(default depends on 'term')
+			global
+			{not in Vi}
+			{only in Unix and VMS, doesn't work in the GUI; not
+			available when compiled without |+mouse|}
+	Name of the terminal type for which mouse codes are to be recognized.
+	Currently these strings are valid:
+							*xterm-mouse*
+	   xterm	xterm-like mouse handling.  The mouse generates
+			"<Esc>[Mscr", where "scr" is three bytes:
+				"s"  = button state
+				"c"  = column plus 33
+				"r"  = row plus 33
+			This only works up to 223 columns!  See "dec" for a
+			solution.
+	   xterm2	Works like "xterm", but with the xterm reporting the
+			mouse position while the mouse is dragged.  This works
+			much faster and more precise.  Your xterm must at
+			least at patchlevel 88 / XFree 3.3.3 for this to
+			work.  See below for how Vim detects this
+			automatically.
+							*netterm-mouse*
+	   netterm	NetTerm mouse handling.  The mouse generates
+			"<Esc>}r,c<CR>", where "r,c" are two decimal numbers
+			for the row and column.
+							*dec-mouse*
+	   dec		DEC terminal mouse handling.  The mouse generates a
+			rather complex sequence, starting with "<Esc>[".
+			This is also available for an Xterm, if it was
+			configured with "--enable-dec-locator".
+							*jsbterm-mouse*
+	   jsbterm	JSB term mouse handling.
+							*pterm-mouse*
+	   pterm	QNX pterm mouse handling.
+
+	The mouse handling must be enabled at compile time |+mouse_xterm|
+	|+mouse_dec| |+mouse_netterm|.
+	Only "xterm"(2) is really recognized.  NetTerm mouse codes are always
+	recognized, if enabled at compile time.  DEC terminal mouse codes
+	are recognized if enabled at compile time, and 'ttymouse' is not
+	"xterm" (because the xterm and dec mouse codes conflict).
+	This option is automatically set to "xterm", when the 'term' option is
+	set to a name that starts with "xterm", and 'ttymouse' is not "xterm"
+	or "xterm2" already.  The main use of this option is to set it to
+	"xterm", when the terminal name doesn't start with "xterm", but it can
+	handle xterm mouse codes.
+	The "xterm2" value will be set if the xterm version is reported to be
+	95 of higher.  This only works when compiled with the |+termresponse|
+	feature and if |t_RV| is set to the escape sequence to request the
+	xterm version number.  Otherwise "xterm2" must be set explicitly.
+	If you do not want 'ttymouse' to be set to "xterm2" automatically, set
+	t_RV to an empty string: >
+		:set t_RV=
+<
+						*'ttyscroll'* *'tsl'*
+'ttyscroll' 'tsl'	number	(default 999)
+			global
+	Maximum number of lines to scroll the screen.  If there are more lines
+	to scroll the window is redrawn.  For terminals where scrolling is
+	very slow and redrawing is not slow this can be set to a small number,
+	e.g., 3, to speed up displaying.
+
+						*'ttytype'* *'tty'*
+'ttytype' 'tty'		string	(default from $TERM)
+			global
+	Alias for 'term', see above.
+
+						*'undolevels'* *'ul'*
+'undolevels' 'ul'	number	(default 100, 1000 for Unix, VMS,
+						Win32 and OS/2)
+			global
+			{not in Vi}
+	Maximum number of changes that can be undone.  Since undo information
+	is kept in memory, higher numbers will cause more memory to be used
+	(nevertheless, a single change can use an unlimited amount of memory).
+	Set to 0 for Vi compatibility: One level of undo and "u" undoes
+	itself: >
+		set ul=0
+<	But you can also get Vi compatibility by including the 'u' flag in
+	'cpoptions', and still be able to use CTRL-R to repeat undo.
+	Set to a negative number for no undo at all: >
+		set ul=-1
+<	This helps when you run out of memory for a single change.
+	Also see |undo-two-ways|.
+
+						*'updatecount'* *'uc'*
+'updatecount' 'uc'	number	(default: 200)
+			global
+			{not in Vi}
+	After typing this many characters the swap file will be written to
+	disk.  When zero, no swap file will be created at all (see chapter on
+	recovery |crash-recovery|).  'updatecount' is set to zero by starting
+	Vim with the "-n" option, see |startup|.  When editing in readonly
+	mode this option will be initialized to 10000.
+	The swapfile can be disabled per buffer with |'swapfile'|.
+	When 'updatecount' is set from zero to non-zero, swap files are
+	created for all buffers that have 'swapfile' set.  When 'updatecount'
+	is set to zero, existing swap files are not deleted.
+	Also see |'swapsync'|.
+	This option has no meaning in buffers where |'buftype'| is "nofile"
+	or "nowrite".
+
+						*'updatetime'* *'ut'*
+'updatetime' 'ut'	number	(default 4000)
+			global
+			{not in Vi}
+	If this many milliseconds nothing is typed the swap file will be
+	written to disk (see |crash-recovery|).  Also used for the
+	|CursorHold| autocommand event.
+
+						*'verbose'* *'vbs'*
+'verbose' 'vbs'		number	(default 0)
+			global
+			{not in Vi, although some versions have a boolean
+			verbose option}
+	When bigger than zero, Vim will give messages about what it is doing.
+	Currently, these messages are given:
+	>= 1	When the viminfo file is read or written.
+	>= 2	When a file is ":source"'ed.
+	>= 5	Every searched tags file and include file.
+	>= 8	Files for which a group of autocommands is executed.
+	>= 9	Every executed autocommand.
+	>= 12	Every executed function.
+	>= 13	When an exception is thrown, caught, finished, or discarded.
+	>= 14	Anything pending in a ":finally" clause.
+	>= 15	Every executed Ex command (truncated at 200 characters).
+
+	This option can also be set with the "-V" argument.  See |-V|.
+	This option is also set by the |:verbose| command.
+
+	When the 'verbosefile' option is set then the verbose messages are not
+	displayed.
+
+						*'verbosefile'* *'vfile'*
+'verbosefile' 'vfile'	string	(default empty)
+			global
+			{not in Vi}
+	When not empty all messages are written in a file with this name.
+	When the file exists messages are appended.
+	Writing to the file ends when Vim exits or when 'verbosefile' is made
+	empty.
+	Setting 'verbosefile' to a new value is like making it empty first.
+	The difference with |:redir| is that verbose messages are not
+	displayed when 'verbosefile' is set.
+
+						*'viewdir'* *'vdir'*
+'viewdir' 'vdir'	string	(default for Amiga, MS-DOS, OS/2 and Win32:
+							 "$VIM/vimfiles/view",
+				 for Unix: "~/.vim/view",
+				 for Macintosh: "$VIM:vimfiles:view"
+				 for VMS: "sys$login:vimfiles/view"
+				 for RiscOS: "Choices:vimfiles/view")
+			global
+			{not in Vi}
+			{not available when compiled without the +mksession
+			feature}
+	Name of the directory where to store files for |:mkview|.
+	This option cannot be set from a |modeline| or in the |sandbox|, for
+	security reasons.
+
+						*'viewoptions'* *'vop'*
+'viewoptions' 'vop'	string	(default: "folds,options,cursor")
+			global
+			{not in Vi}
+			{not available when compiled without the +mksession
+			feature}
+	Changes the effect of the |:mkview| command.  It is a comma separated
+	list of words.  Each word enables saving and restoring something:
+	   word		save and restore ~
+	   cursor	cursor position in file and in window
+	   folds	manually created folds, opened/closed folds and local
+			fold options
+	   options	options and mappings local to a window or buffer (not
+			global values for local options)
+	   slash	backslashes in file names replaced with forward
+			slashes
+	   unix		with Unix end-of-line format (single <NL>), even when
+			on Windows or DOS
+
+	"slash" and "unix" are useful on Windows when sharing view files
+	with Unix.  The Unix version of Vim cannot source dos format scripts,
+	but the Windows version of Vim can source unix format scripts.
+
+				*'viminfo'* *'vi'* *E526* *E527* *E528*
+'viminfo' 'vi'		string	(Vi default: "", Vim default for MS-DOS,
+				   Windows and OS/2: '20,<50,s10,h,rA:,rB:,
+				   for Amiga: '20,<50,s10,h,rdf0:,rdf1:,rdf2:
+				   for others: '20,<50,s10,h)
+			global
+			{not in Vi}
+			{not available when compiled without the  |+viminfo|
+			feature}
+	When non-empty, the viminfo file is read upon startup and written
+	when exiting Vim (see |viminfo-file|).  The string should be a comma
+	separated list of parameters, each consisting of a single character
+	identifying the particular parameter, followed by a number or string
+	which specifies the value of that parameter.  If a particular
+	character is left out, then the default value is used for that
+	parameter.  The following is a list of the identifying characters and
+	the effect of their value.
+	CHAR	VALUE	~
+	!	When included, save and restore global variables that start
+		with an uppercase letter, and don't contain a lowercase
+		letter.  Thus "KEEPTHIS and "K_L_M" are stored, but "KeepThis"
+		and "_K_L_M" are not.  Only String and Number types are
+		stored.
+	"	Maximum number of lines saved for each register.  Old name of
+		the '<' item, with the disadvantage that you need to put a
+		backslash before the ", otherwise it will be recognized as the
+		start of a comment!
+	%	When included, save and restore the buffer list.  If Vim is
+		started with a file name argument, the buffer list is not
+		restored.  If Vim is started without a file name argument, the
+		buffer list is restored from the viminfo file.  Buffers
+		without a file name and buffers for help files are not written
+		to the viminfo file.
+		When followed by a number, the number specifies the maximum
+		number of buffers that are stored.  Without a number all
+		buffers are stored.
+	'	Maximum number of previously edited files for which the marks
+		are remembered.  This parameter must always be included when
+		'viminfo' is non-empty.
+		Including this item also means that the |jumplist| and the
+		|changelist| are stored in the viminfo file.
+	/	Maximum number of items in the search pattern history to be
+		saved.  If non-zero, then the previous search and substitute
+		patterns are also saved.  When not included, the value of
+		'history' is used.
+	:	Maximum number of items in the command-line history to be
+		saved.  When not included, the value of 'history' is used.
+	<	Maximum number of lines saved for each register.  If zero then
+		registers are not saved.  When not included, all lines are
+		saved.  '"' is the old name for this item.
+		Also see the 's' item below: limit specified in Kbyte.
+	@	Maximum number of items in the input-line history to be
+		saved.  When not included, the value of 'history' is used.
+	c	When included, convert the text in the viminfo file from the
+		'encoding' used when writing the file to the current
+		'encoding'.  See |viminfo-encoding|.
+	f	Whether file marks need to be stored.  If zero, file marks ('0
+		to '9, 'A to 'Z) are not stored.  When not present or when
+		non-zero, they are all stored.  '0 is used for the current
+		cursor position (when exiting or when doing ":wviminfo").
+	h	Disable the effect of 'hlsearch' when loading the viminfo
+		file.  When not included, it depends on whether ":nohlsearch"
+		has been used since the last search command.
+	n	Name of the viminfo file.  The name must immediately follow
+		the 'n'.  Must be the last one!  If the "-i" argument was
+		given when starting Vim, that file name overrides the one
+		given here with 'viminfo'.  Environment variables are expanded
+		when opening the file, not when setting the option.
+	r	Removable media.  The argument is a string (up to the next
+		',').  This parameter can be given several times.  Each
+		specifies the start of a path for which no marks will be
+		stored.  This is to avoid removable media.  For MS-DOS you
+		could use "ra:,rb:", for Amiga "rdf0:,rdf1:,rdf2:".  You can
+		also use it for temp files, e.g., for Unix: "r/tmp".  Case is
+		ignored.  Maximum length of each 'r' argument is 50
+		characters.
+	s	Maximum size of an item in Kbyte.  If zero then registers are
+		not saved.  Currently only applies to registers.  The default
+		"s10" will exclude registers with more than 10 Kbyte of text.
+		Also see the '<' item above: line count limit.
+
+	Example: >
+	    :set viminfo='50,<1000,s100,:0,n~/vim/viminfo
+<
+	'50		Marks will be remembered for the last 50 files you
+			edited.
+	<1000		Contents of registers (up to 1000 lines each) will be
+			remembered.
+	s100		Registers with more than 100 Kbyte text are skipped.
+	:0		Command-line history will not be saved.
+	n~/vim/viminfo	The name of the file to use is "~/vim/viminfo".
+	no /		Since '/' is not specified, the default will be used,
+			that is, save all of the search history, and also the
+			previous search and substitute patterns.
+	no %		The buffer list will not be saved nor read back.
+	no h		'hlsearch' highlighting will be restored.
+
+	When setting 'viminfo' from an empty value you can use |:rviminfo| to
+	load the contents of the file, this is not done automatically.
+
+	This option cannot be set from a |modeline| or in the |sandbox|, for
+	security reasons.
+
+					    *'virtualedit'* *'ve'*
+'virtualedit' 've'	string	(default "")
+			global
+			{not in Vi}
+			{not available when compiled without the
+			|+virtualedit| feature}
+	A comma separated list of these words:
+	    block	Allow virtual editing in Visual block mode.
+	    insert	Allow virtual editing in Insert mode.
+	    all		Allow virtual editing in all modes.
+	    onemore	Allow the cursor to move just past the end of the line
+
+	Virtual editing means that the cursor can be positioned where there is
+	no actual character.  This can be halfway into a tab or beyond the end
+	of the line.  Useful for selecting a rectangle in Visual mode and
+	editing a table.
+	"onemore" is not the same, it will only allow moving the cursor just
+	after the last character of the line.  This makes some commands more
+	consistent.  Previously the cursor was always past the end of the line
+	if the line was empty.  But it is far from Vi compatible.  It may also
+	break some plugins or Vim scripts.  For example because |l| can move
+	the cursor after the last character.  Use with care!
+	Using the |$| command will move to the last character in the line, not
+	past it.  This may actually move the cursor to the left!
+	It doesn't make sense to combine "all" with "onemore", but you will
+	not get a warning for it.
+
+			*'visualbell'* *'vb'* *'novisualbell'* *'novb'* *beep*
+'visualbell' 'vb'	boolean	(default off)
+			global
+			{not in Vi}
+	Use visual bell instead of beeping.  The terminal code to display the
+	visual bell is given with 't_vb'.  When no beep or flash is wanted,
+	use ":set vb t_vb=".
+	Note: When the GUI starts, 't_vb' is reset to its default value.  You
+	might want to set it again in your |gvimrc|.
+	In the GUI, 't_vb' defaults to "<Esc>|f", which inverts the display
+	for 20 msec.  If you want to use a different time, use "<Esc>|40f",
+	where 40 is the time in msec.
+	Does not work on the Amiga, you always get a screen flash.
+	Also see 'errorbells'.
+
+						*'warn'* *'nowarn'*
+'warn'			boolean	(default on)
+			global
+	Give a warning message when a shell command is used while the buffer
+	has been changed.
+
+		     *'weirdinvert'* *'wiv'* *'noweirdinvert'* *'nowiv'*
+'weirdinvert' 'wiv'	boolean	(default off)
+			global
+			{not in Vi}
+	This option has the same effect as the 't_xs' terminal option.
+	It is provided for backwards compatibility with version 4.x.
+	Setting 'weirdinvert' has the effect of making 't_xs' non-empty, and
+	vice versa.  Has no effect when the GUI is running.
+
+						*'whichwrap'* *'ww'*
+'whichwrap' 'ww'	string	(Vim default: "b,s", Vi default: "")
+			global
+			{not in Vi}
+	Allow specified keys that move the cursor left/right to move to the
+	previous/next line when the cursor is on the first/last character in
+	the line.  Concatenate characters to allow this for these keys:
+		char   key	  mode	~
+		 b    <BS>	 Normal and Visual
+		 s    <Space>	 Normal and Visual
+		 h    "h"	 Normal and Visual (not recommended)
+		 l    "l"	 Normal and Visual (not recommended)
+		 <    <Left>	 Normal and Visual
+		 >    <Right>	 Normal and Visual
+		 ~    "~"	 Normal
+		 [    <Left>	 Insert and Replace
+		 ]    <Right>	 Insert and Replace
+	For example: >
+		:set ww=<,>,[,]
+<	allows wrap only when cursor keys are used.
+	When the movement keys are used in combination with a delete or change
+	operator, the <EOL> also counts for a character.  This makes "3h"
+	different from "3dh" when the cursor crosses the end of a line.  This
+	is also true for "x" and "X", because they do the same as "dl" and
+	"dh".  If you use this, you may also want to use the mapping
+	":map <BS> X" to make backspace delete the character in front of the
+	cursor.
+	When 'l' is included and it is used after an operator at the end of a
+	line then it will not move to the next line.  This makes "dl", "cl",
+	"yl" etc. work normally.
+	NOTE: This option is set to the Vi default value when 'compatible' is
+	set and to the Vim default value when 'compatible' is reset.
+
+						*'wildchar'* *'wc'*
+'wildchar' 'wc'		number	(Vim default: <Tab>, Vi default: CTRL-E)
+			global
+			{not in Vi}
+	Character you have to type to start wildcard expansion in the
+	command-line, as specified with 'wildmode'.
+	The character is not recognized when used inside a macro.  See
+	'wildcharm' for that.
+	Although 'wc' is a number option, you can set it to a special key: >
+		:set wc=<Esc>
+<	NOTE: This option is set to the Vi default value when 'compatible' is
+	set and to the Vim default value when 'compatible' is reset.
+
+						*'wildcharm'* *'wcm'*
+'wildcharm' 'wcm'	number	(default: none (0))
+			global
+			{not in Vi}
+	'wildcharm' works exactly like 'wildchar', except that it is
+	recognized when used inside a macro.  You can find "spare" command-line
+	keys suitable for this option by looking at |ex-edit-index|.  Normally
+	you'll never actually type 'wildcharm', just use it in mappings that
+	automatically invoke completion mode, e.g.: >
+		:set wcm=<C-Z>
+		:cmap ss so $vim/sessions/*.vim<C-Z>
+<	Then after typing :ss you can use CTRL-P & CTRL-N.
+
+						*'wildignore'* *'wig'*
+'wildignore' 'wig'	string	(default "")
+			global
+			{not in Vi}
+			{not available when compiled without the |+wildignore|
+			feature}
+	A list of file patterns.  A file that matches with one of these
+	patterns is ignored when completing file or directory names.
+	The pattern is used like with |:autocmd|, see |autocmd-patterns|.
+	Also see 'suffixes'.
+	Example: >
+		:set wildignore=*.o,*.obj
+<	The use of |:set+=| and |:set-=| is preferred when adding or removing
+	a pattern from the list.  This avoids problems when a future version
+	uses another default.
+
+				*'wildmenu'* *'wmnu'* *'nowildmenu'* *'nowmnu'*
+'wildmenu' 'wmnu'	boolean	(default off)
+			global
+			{not in Vi}
+			{not available if compiled without the |+wildmenu|
+			feature}
+	When 'wildmenu' is on, command-line completion operates in an enhanced
+	mode.  On pressing 'wildchar' (usually <Tab>) to invoke completion,
+	the possible matches are shown just above the command line, with the
+	first match highlighted (overwriting the status line, if there is
+	one).  Keys that show the previous/next match, such as <Tab> or
+	CTRL-P/CTRL-N, cause the highlight to move to the appropriate match.
+	When 'wildmode' is used, "wildmenu" mode is used where "full" is
+	specified.  "longest" and "list" do not start "wildmenu" mode.
+	If there are more matches than can fit in the line, a ">" is shown on
+	the right and/or a "<" is shown on the left.  The status line scrolls
+	as needed.
+	The "wildmenu" mode is abandoned when a key is hit that is not used
+	for selecting a completion.
+	While the "wildmenu" is active the following keys have special
+	meanings:
+
+	<Left> <Right>	- select previous/next match (like CTRL-P/CTRL-N)
+	<Down>		- in filename/menu name completion: move into a
+			  subdirectory or submenu.
+	<CR>		- in menu completion, when the cursor is just after a
+			  dot: move into a submenu.
+	<Up>		- in filename/menu name completion: move up into
+			  parent directory or parent menu.
+
+	This makes the menus accessible from the console |console-menus|.
+
+	If you prefer the <Left> and <Right> keys to move the cursor instead
+	of selecting a different match, use this: >
+		:cnoremap <Left> <Space><BS><Left>
+		:cnoremap <Right> <Space><BS><Right>
+<
+	The "WildMenu" highlighting is used for displaying the current match
+	|hl-WildMenu|.
+
+						*'wildmode'* *'wim'*
+'wildmode' 'wim'	string	(Vim default: "full")
+			global
+			{not in Vi}
+	Completion mode that is used for the character specified with
+	'wildchar'.  It is a comma separated list of up to four parts.  Each
+	part specifies what to do for each consecutive use of 'wildchar'.  The
+	first part specifies the behavior for the first use of 'wildchar',
+	The second part for the second use, etc.
+	These are the possible values for each part:
+	""		Complete only the first match.
+	"full"		Complete the next full match.  After the last match,
+			the original string is used and then the first match
+			again.
+	"longest"	Complete till longest common string.  If this doesn't
+			result in a longer string, use the next part.
+	"longest:full"	Like "longest", but also start 'wildmenu' if it is
+			enabled.
+	"list"		When more than one match, list all matches.
+	"list:full"	When more than one match, list all matches and
+			complete first match.
+	"list:longest"	When more than one match, list all matches and
+			complete till longest common string.
+	When there is only a single match, it is fully completed in all cases.
+
+	Examples: >
+		:set wildmode=full
+<	Complete first full match, next match, etc.  (the default) >
+		:set wildmode=longest,full
+<	Complete longest common string, then each full match >
+		:set wildmode=list:full
+<	List all matches and complete each full match >
+		:set wildmode=list,full
+<	List all matches without completing, then each full match >
+		:set wildmode=longest,list
+<	Complete longest common string, then list alternatives.
+
+						*'wildoptions'* *'wop'*
+'wildoptions' 'wop'	string	(default "")
+			global
+			{not in Vi}
+			{not available when compiled without the |+wildignore|
+			feature}
+	A list of words that change how command line completion is done.
+	Currently only one word is allowed:
+	  tagfile	When using CTRL-D to list matching tags, the kind of
+			tag and the file of the tag is listed.	Only one match
+			is displayed per line.  Often used tag kinds are:
+				d	#define
+				f	function
+	Also see |cmdline-completion|.
+
+						*'winaltkeys'* *'wak'*
+'winaltkeys' 'wak'	string	(default "menu")
+			global
+			{not in Vi}
+			{only used in Win32, Motif, GTK and Photon GUI}
+	Some GUI versions allow the access to menu entries by using the ALT
+	key in combination with a character that appears underlined in the
+	menu.  This conflicts with the use of the ALT key for mappings and
+	entering special characters.  This option tells what to do:
+	  no	Don't use ALT keys for menus.  ALT key combinations can be
+		mapped, but there is no automatic handling.  This can then be
+		done with the |:simalt| command.
+	  yes	ALT key handling is done by the windowing system.  ALT key
+		combinations cannot be mapped.
+	  menu	Using ALT in combination with a character that is a menu
+		shortcut key, will be handled by the windowing system.  Other
+		keys can be mapped.
+	If the menu is disabled by excluding 'm' from 'guioptions', the ALT
+	key is never used for the menu.
+	This option is not used for <F10>; on Win32 and with GTK <F10> will
+	select the menu, unless it has been mapped.
+
+						*'window'* *'wi'*
+'window' 'wi'		number  (default screen height - 1)
+			global
+	Window height.  Do not confuse this with the height of the Vim window,
+	use 'lines' for that.
+	Used for |CTRL-F| and |CTRL-B| when there is only one window and the
+	value is smaller than 'lines' minus one.  The screen will scroll
+	'window' minus two lines, with a minimum of one.
+	When 'window' is equal to 'lines' minus one CTRL-F and CTRL-B scroll
+	in a much smarter way, taking care of wrapping lines.
+	When resizing the Vim window, the value is smaller than 1 or more than
+	or equal to 'lines' it will be set to 'lines' minus 1.
+	{Vi also uses the option to specify the number of displayed lines}
+
+						*'winheight'* *'wh'* *E591*
+'winheight' 'wh'	number	(default 1)
+			global
+			{not in Vi}
+			{not available when compiled without the +windows
+			feature}
+	Minimal number of lines for the current window.  This is not a hard
+	minimum, Vim will use fewer lines if there is not enough room.  If the
+	current window is smaller, its size is increased, at the cost of the
+	height of other windows.  Set it to 999 to make the current window
+	always fill the screen (although this has the drawback that ":all"
+	will create only two windows).  Set it to a small number for normal
+	editing.
+	Minimum value is 1.
+	The height is not adjusted after one of the commands to change the
+	height of the current window.
+	'winheight' applies to the current window.  Use 'winminheight' to set
+	the minimal height for other windows.
+
+			*'winfixheight'* *'wfh'* *'nowinfixheight'* *'nowfh'*
+'winfixheight' 'wfh'	boolean	(default off)
+			local to window
+			{not in Vi}
+			{not available when compiled without the +windows
+			feature}
+	Keep the window height when windows are opened or closed and
+	'equalalways' is set.  Also for |CTRL-W_=|.  Set by default for the
+	|preview-window| and |quickfix-window|.
+	The height may be changed anyway when running out of room.
+
+			*'winfixwidth'* *'wfw'* *'nowinfixwidth'* *'nowfw'*
+'winfixwidth' 'wfw'	boolean	(default off)
+			local to window
+			{not in Vi}
+			{not available when compiled without the +windows
+			feature}
+	Keep the window width when windows are opened or closed and
+	'equalalways' is set.  Also for |CTRL-W_=|.
+	The width may be changed anyway when running out of room.
+
+						*'winminheight'* *'wmh'*
+'winminheight' 'wmh'	number	(default 1)
+			global
+			{not in Vi}
+			{not available when compiled without the +windows
+			feature}
+	The minimal height of a window, when it's not the current window.
+	This is a hard minimum, windows will never become smaller.
+	When set to zero, windows may be "squashed" to zero lines (i.e. just a
+	status bar) if necessary.  They will return to at least one line when
+	they become active (since the cursor has to have somewhere to go.)
+	Use 'winheight' to set the minimal height of the current window.
+	This option is only checked when making a window smaller.  Don't use a
+	large number, it will cause errors when opening more than a few
+	windows.  A value of 0 to 3 is reasonable.
+
+						*'winminwidth'* *'wmw'*
+'winminwidth' 'wmw'	number	(default 1)
+			global
+			{not in Vi}
+			{not available when compiled without the +vertsplit
+			feature}
+	The minimal width of a window, when it's not the current window.
+	This is a hard minimum, windows will never become smaller.
+	When set to zero, windows may be "squashed" to zero columns (i.e. just
+	a vertical separator) if necessary.  They will return to at least one
+	line when they become active (since the cursor has to have somewhere
+	to go.)
+	Use 'winwidth' to set the minimal width of the current window.
+	This option is only checked when making a window smaller.  Don't use a
+	large number, it will cause errors when opening more than a few
+	windows.  A value of 0 to 12 is reasonable.
+
+						*'winwidth'* *'wiw'* *E592*
+'winwidth' 'wiw'	number	(default 20)
+			global
+			{not in Vi}
+			{not available when compiled without the +vertsplit
+			feature}
+	Minimal number of columns for the current window.  This is not a hard
+	minimum, Vim will use fewer columns if there is not enough room.  If
+	the current window is smaller, its size is increased, at the cost of
+	the width of other windows.  Set it to 999 to make the current window
+	always fill the screen.  Set it to a small number for normal editing.
+	The width is not adjusted after one of the commands to change the
+	width of the current window.
+	'winwidth' applies to the current window.  Use 'winminwidth' to set
+	the minimal width for other windows.
+
+						*'wrap'* *'nowrap'*
+'wrap'			boolean	(default on)
+			local to window
+			{not in Vi}
+	This option changes how text is displayed.  It doesn't change the text
+	in the buffer, see 'textwidth' for that.
+	When on, lines longer than the width of the window will wrap and
+	displaying continues on the next line.  When off lines will not wrap
+	and only part of long lines will be displayed.  When the cursor is
+	moved to a part that is not shown, the screen will scroll
+	horizontally.
+	The line will be broken in the middle of a word if necessary.  See
+	'linebreak' to get the break at a word boundary.
+	To make scrolling horizontally a bit more useful, try this: >
+		:set sidescroll=5
+		:set listchars+=precedes:<,extends:>
+<	See 'sidescroll', 'listchars' and |wrap-off|.
+
+						*'wrapmargin'* *'wm'*
+'wrapmargin' 'wm'	number	(default 0)
+			local to buffer
+	Number of characters from the right window border where wrapping
+	starts.  When typing text beyond this limit, an <EOL> will be inserted
+	and inserting continues on the next line.
+	Options that add a margin, such as 'number' and 'foldcolumn', cause
+	the text width to be further reduced.  This is Vi compatible.
+	When 'textwidth' is non-zero, this option is not used.
+	See also 'formatoptions' and |ins-textwidth|.  {Vi: works differently
+	and less usefully}
+
+				   *'wrapscan'* *'ws'* *'nowrapscan'* *'nows'*
+'wrapscan' 'ws'		boolean	(default on)			*E384* *E385*
+			global
+	Searches wrap around the end of the file.  Also applies to |]s| and
+	|[s|, searching for spelling mistakes.
+
+						   *'write'* *'nowrite'*
+'write'			boolean	(default on)
+			global
+			{not in Vi}
+	Allows writing files.  When not set, writing a file is not allowed.
+	Can be used for a view-only mode, where modifications to the text are
+	still allowed.  Can be reset with the |-m| or |-M| command line
+	argument.  Filtering text is still possible, even though this requires
+	writing a temporary file.
+
+				   *'writeany'* *'wa'* *'nowriteany'* *'nowa'*
+'writeany' 'wa'		boolean	(default off)
+			global
+	Allows writing to any file with no need for "!" override.
+
+			     *'writebackup'* *'wb'* *'nowritebackup'* *'nowb'*
+'writebackup' 'wb'	boolean	(default on with |+writebackup| feature, off
+					otherwise)
+			global
+			{not in Vi}
+	Make a backup before overwriting a file.  The backup is removed after
+	the file was successfully written, unless the 'backup' option is
+	also on.  Reset this option if your file system is almost full.  See
+	|backup-table| for another explanation.
+	When the 'backupskip' pattern matches, a backup is not made anyway.
+	NOTE: This option is set to the default value when 'compatible' is
+	set.
+
+						*'writedelay'* *'wd'*
+'writedelay' 'wd'	number	(default 0)
+			global
+			{not in Vi}
+	The number of microseconds to wait for each character sent to the
+	screen.  When non-zero, characters are sent to the terminal one by
+	one.  For MS-DOS pcterm this does not work.  For debugging purposes.
+
+ vim:tw=78:ts=8:ft=help:norl:
--- /dev/null
+++ b/lib/vimfiles/doc/os_390.txt
@@ -1,0 +1,340 @@
+*os_390.txt*    For Vim version 7.1.  Last change: 2005 Mar 29
+
+
+		  VIM REFERENCE MANUAL	  by Ralf Schandl
+
+					*zOS* *z/OS* *OS390* *os390* *MVS*
+This file contains the particulars for the z/OS UNIX version of Vim.
+
+1. Open source on z/OS UNIX		|zOS-open-source|
+2. Your feedback is needed		|zOS-feedback|
+3. Building VIM for z/OS UNIX		|zOS-building|
+4. ASCII/EBCDIC dependent scripts	|zOS-has-ebcdic|
+5. XTerm Problems			|zOS-xterm|
+6. Motif Problems			|zOS-Motif|
+7. Bugs					|zOS-Bugs|
+8. Known weaknesses			|zOS-weaknesses|
+9. Changes				|zOS-changes|
+
+DISCLAIMER: ~
+We are IBM employees, but IBM is not responsible for this port.  This is our
+private fun, and is provided in the hopes that it may be useful to others.
+
+Please note that this software has NOT been submitted to any formal IBM
+testing and is published AS IS.  Please do not contact IBM for support for this
+software, as it is not an official component of any IBM product.  IT IS NOT
+SUPPORTED, GUARANTEED, OR RELATED WHATSOEVER TO IBM.
+
+Contributors: ~
+The port to z/OS UNIX was done by Ralf Schandl for the Redbook mentioned
+below.
+
+Changes, bug-reports, or both by:
+
+	David Moore
+	Anthony Giorgio <agiorgio@fastmail.fm>
+	and others
+
+This document was written by Ralf Schandl and revised by Anthony Giorgio.
+
+==============================================================================
+1. Open source on z/OS UNIX		*OS390-open-source* *zOS-open-source*
+
+If you are interested in other Open Source Software on z/OS UNIX, have a
+look at the following Redbook:
+
+    Mike MacIsaac et al
+    "Open Source Software for z/OS and OS/390 UNIX"
+    IBM Form Number: SG24-5944-01
+    ISBN: 0738424633
+
+You can find out more information, order a hard copy, or download a PDF
+version of these Redbooks at:
+
+	    http://www.redbooks.ibm.com
+
+==============================================================================
+2. Your feedback is needed		*OS390-feedback* *zOS-feedback*
+
+Vim should compile, link, and run right out of the box on a standard IBM z/OS
+UNIX mainframe.  I've personally run it on z/OS V1R2 and V1R3 machines without
+problems.
+
+Many changes had to be done to the code to port Vim to z/OS UNIX.  As like
+most UNIX programs, Vim contained heavy ASCII dependencies.  I might have
+missed an ASCII dependency, or it is possible that a new one has been added
+with a feature or bug fix.  Most programmers are simply not aware of possible
+ASCII/EBCDIC conversion issues.  If you hit a problem that seems related to
+this, feel free to contact us at the email addresses above.
+
+One indication of ASCII/EBCDIC conversion problems is screen corruption with
+"unprintable" characters.  For example, at one point the errorbell was broken
+in Vim.  Any time Vim tried to ring the terminal bell an ASCII character 0x07
+would be printed.  This works fine on most terminals, but is broken on an
+EBCDIC one.  The correct solution was to define a different value for the bell
+character on EBCDIC systems.
+
+Remember, it's only possible to fix a bug if the community knows about it.
+Don't rely on someone else to report it!  See the section |bug-reports|.
+
+==============================================================================
+3. Building VIM for z/OS UNIX		*OS390-building* *zOS-building*
+
+A word on debugging code first: ~
+
+The normal run of configure adds the flag '-g' to the compiler options,
+to include debugging information into the executable.  This information
+are normally removed from the executable with the strip command during
+installation.  On z/OS UNIX, it is not possible to remove this from
+the executable.  The strip command exists on z/OS UNIX and is called
+during the installation, but it does nothing.  It is equivalent to the
+'touch' command.  This is due to the way debug symbols are stored in the
+objects generated by the compiler.
+
+If you want to build Vim without debugging code, export the environment
+variable CFLAGS set to an empty string before you call the configure script.
+>
+	export CFLAGS=""
+
+
+Building without X11: ~
+
+Note: Use cc to build Vim.  The c89 compiler has stricter syntax checking
+and will not compile Vim cleanly.
+
+If you build VIM without X11 support, compiling and building is
+straightforward.  Don't forget to export _CC_CCMODE=1 before calling
+configure and make.
+>
+    $ export _CC_CCMODE=1
+    $./configure --with-features=big --without-x --enable-gui=no
+    $ make
+    $ make test
+<
+	Test notes:
+	Test 11 will fail if you do not have gzip installed.
+	Test 42 will fail, as VIM on z/OS UNIX doesn't support the multibyte
+	feature.  (David Moore: "Doesn't work _yet_!  :-)  I'll see what I
+	can do.")
+>
+
+    $ make install
+
+
+Building with X11: ~
+
+There are two ways for building Vim with X11 support.  You can link it
+statically with the X11 libraries or can bind it with the X11 DLLs.  The
+statically linked version results in a huge executable (~13MB), while the
+dynamically linked executable is much smaller (~4.5MB).
+
+Here is what you do, if you want Motif:
+
+  a) Static link >
+	$ configure --with-features=big --enable-gui=motif
+	$ make
+<
+     VIM is now linked statically with the X11 libraries.
+
+  b) Dynamic link:
+     Make VIM as described for the static link.  Then change the contents of
+     the 'auto/link.sed' file by appending: >
+	s%-lXm  *%/usr/lib/Xm.x %g
+	s%-lX11  *%/usr/lib/X11.x %g
+	s%-lSM  *%/usr/lib/SM.x %g
+	s%-lICE  *%/usr/lib/ICE.x %g
+<
+     Then do: >
+	$ rm vim
+	$ make
+<
+     Now Vim is linked with the X11-DLLs.
+
+See the Makefile and the file link.sh on how link.sed is used.
+
+==============================================================================
+4. ASCII/EBCDIC dependent scripts	*OS390-has-ebcdic* *zOS-has-ebcdic*
+
+For the internal script language the feature "ebcdic" was added.  With this
+you can fix ASCII dependent scripts like this:
+>
+    if has("ebcdic")
+	let space = 64
+    else
+	let space = 32
+    endif
+<
+==============================================================================
+5. XTerm problems			*OS390-xterm* *zOS-xterm*
+
+Note: This problem was resolved in version 6.1b. ~
+
+I saw one problem with XTerm on z/OS UNIX.  The terminal code for moving the
+cursor to the left is wrong in the termlib database.  Perhaps not wrong, but
+it didn't work with VIM syntax highlighting and command line cursor movement.
+
+If the highlighting is messed up while you type, but is okay after you refreshed
+the screen with <C-L> or if you can't move to the left with the cursor key on
+the command line, try adding >
+	:set t_le=^H
+<
+to your .vimrc.  Note: '^H' is one character, hit <C-V><C-H> to get it.
+
+==============================================================================
+6. Motif Problems			*OS390-Motif* *zOS-Motif*
+
+It seems that in porting the Motif library to z/OS, a translation from EBCDIC
+to ASCII for the accelerator characters of the pull-down menus was forgotten.
+Even after I tried to hand convert the menus, the accelerator keys continued
+to only work for the opening of menus (like <Alt-F> to open the file menu).
+They still do not work for the menu items themselves (like <Alt-F>O to open
+the file browser).
+
+There is no solution for this as of yet.
+
+==============================================================================
+7. Bugs					*OS390-bugs* *zOS-Bugs*
+
+- Vim will consistently hang when a large amount of text is selected in
+  visual block mode.  This may be due to a memory corruption issue.  Note that
+  this occurs in both the terminal and gui versions.
+
+==============================================================================
+8. Known weaknesses			*OS390-weaknesses* *zOS-weaknesses*
+
+- No binary search in tag files.
+  The program /bin/sort sorts by ASCII value by default.  This program is
+  normally used by ctags to sort the tags.  There might be a version of
+  ctags out there, that does it right, but we can't be sure.  So this seems to
+  be a permanent restriction.
+
+- Multibyte support (utf-8) doesn't work, it's disabled at compile time.
+  (|multibyte|)
+
+- The cscope interface (|cscope|) doesn't work for the version of cscope
+  that we use on our mainframe.  We have a copy of version 15.0b12, and it
+  causes Vim to hang when using the "cscope add" command.  I'm guessing that
+  the binary format of the cscope database isn't quite what Vim is expecting.
+  I've tried to port the current version of cscope (15.3) to z/OS, without
+  much success.  If anyone is interested in trying, drop me a line if you
+  make any progress.
+
+- No glib/gtk support.  I have not been able to successfully compile glib on
+  z/OS UNIX.  This means you'll have to live without the pretty gtk toolbar.
+
+Never tested:
+    - Perl interface		(|perl|)
+    - Hangul input		(|hangul|)
+    - Encryption support	(|encryption|)
+    - Langmap			(|'langmap'|)
+    - Python support		(|Python|)
+    - Right-to-left mode	(|'rightleft'|)
+    - SNiFF+ interface		(|sniff|)
+    - TCL interface		(|tcl|)
+    ...
+
+If you try any of these features and they work, drop us a note!
+
+==============================================================================
+9. Changes				*OS390-changes*	*zOS-changes*
+
+This is a small reference of the changes made to the z/OS port of Vim.  It is
+not an exhaustive summary of all the modifications made to the code base.
+
+6.1b (beta):
+  Changed KS_LE in term.c to be "\b" instead of "\010"  This fixed the
+  screen corruption problems in gVim reported by Anthony Giorgio.
+
+  Anthony Giorgio updated this document:
+	- Changed OS/390 to z/OS where appropriate.  IBM decided to rename
+		all of its servers and operating systems.  z/OS and OS/390
+		are the same product, but the version numbering system was
+		reset for the name change (e.g. OS/390 V2R11 == z/OS V1R1).
+	- Added information about second edition of the Open Source Redbook.
+	- Moved Redbook information to a separate section.
+	- Various tweaks and changes.
+	- Updated testing section.
+
+6.0au:
+  Changed configure.in
+  Changed documentation.
+  Anthony Giorgio fixed the errorbell.
+
+  David Moore found some problems, which were fixed by Bram and/or David for
+  6.0au.
+
+6.0q (alpha):
+  Minor changes for nrformats=alpha (see |'nrformats'|).
+  Problem with hard-coded keycode for the English pound sign.  Added a define in
+  ascii.h
+  Disabled multibyte for EBCDIC in feature.h
+
+6.0f (alpha):
+  First compile of Vim 6 on z/OS UNIX.  Some minor changes were needed.
+
+  Finally found the reason why make from the top level didn't work (I must have
+  been blind before!).  The Makefile contained a list of targets in one target
+  line.  On all other UNIX's the macro $@ evaluates to the first target in this
+  list, only on z/OS UNIX it evaluates to the last one :-(.
+
+5.6-390d:
+  Cleaned up some hacks.
+
+5.6-390c:
+  I grepped through the source and examined every spot with a character
+  involved in a operation (+-).  I hope I now found all EBCDIC/ASCII
+  stuff, but ....
+
+  Fixed:
+    - fixed warning message in do_fixdel()
+    - fixed translation from Ctrl-Char to symbolic name (like ^h to CTRL-H)
+	    for :help
+    - fixed yank/delete/... into register
+    - fixed :register command
+    - fixed viminfo register storing
+    - fixed quick-access table in findoptions()
+    - fixed 'g^H' select mode
+    - fixed tgetstr() 'get terminal capability string', ESC and
+	    Ctrl chars where wrong.  (Not used on OS/390 UNIX)
+
+
+  ctags:
+    - added trigraphs support (used in prolog of system header files)
+	    (get.c)
+    - fixed sorting order with LC_COLLATE=S390 to force EBCDIC sorting.
+	    (sort.c)
+
+5.6-390b:
+  Changed:
+    - configure.in:
+	- added test for OS/390 UNIX
+	- added special compiler and linker options if building with X11
+    - configure:
+	- after created via autoconf hand-edited it to make the test for
+	  ICEConnectionNumber work.  This is a autoconf problem.  OS/390 UNIX
+	  needs -lX11 for this.
+    - Makefile
+	- Don't include the lib directories ('-L...') into the variable
+	  ALL_LIBS.  Use own variable ALL_LIB_DIRS instead.  A fully POSIX
+	  compliant compiler must not accept objects/libraries and options
+	  mixed.  Now we can call the linker like this:
+
+	    $(CC) $(LDFLAGS) $(ALL_LIB_DIRS) $(OBJ) $(ALL_LIBS)
+
+  Fixed:
+    - Double quote couldn't be entered
+      Missed ASCII dependencies while setting up terminal
+      In ASCII 127 is the delete char, in EBCDIC codepage 1047 the value 127
+      is the double quote.
+    - fixed ':fixdel'
+
+5.6-390a:
+  first alpha release for OS/390 UNIX.
+
+  Addition:
+    - For the internal script language I added the feature "ebcdic".
+      This can be queried with the has()-function of the internal
+      script language.
+
+------------------------------------------------------------------------------
+ vim:tw=78:fo=tcq2:ts=8:ft=help:norl:
--- /dev/null
+++ b/lib/vimfiles/doc/os_amiga.txt
@@ -1,0 +1,145 @@
+*os_amiga.txt*  For Vim version 7.1.  Last change: 2005 Mar 29
+
+
+		  VIM REFERENCE MANUAL    by Bram Moolenaar
+
+
+							*Amiga*
+This file contains the particularities for the Amiga version of Vim.
+There is also a section specifically for |MorphOS| below.
+
+Installation on the Amiga:
+- Assign "VIM:" to the directory where the Vim "doc" directory is.  Vim will
+  look for the file "VIM:doc/help.txt" (for the help command).
+  Setting the environment variable $VIM also works.  And the other way around:
+  when $VIM used and it is not defined, "VIM:" is used.
+- With DOS 1.3 or earlier: Put "arp.library" in "libs:".  Vim must have been
+  compiled with the |+ARP| feature enabled.  Make sure that newcli and run are
+  in "C:" (for executing external commands).
+- Put a shell that accepts a command with "-c" (e.g. "Csh" from Fish disk
+  624) in "c:" or in any other directory that is in your search path (for
+  executing external commands).
+
+If you have sufficient memory you can avoid startup delays by making Vim and
+csh resident with the command "rez csh vim".  You will have to put
+"rezlib.library" in your "libs:" directory.  Under 2.0 you will need rez
+version 0.5.
+
+If you do not use digraphs, you can save some memory by recompiling without
+the |+digraphs| feature.  If you want to use Vim with other terminals you can
+recompile with the TERMCAP option.  Vim compiles with Manx 5.x and SAS 6.x.
+See the makefiles and feature.h.
+
+If you notice Vim crashes on some files when syntax highlighting is on, or
+when using a search pattern with nested wildcards, it might be that the stack
+is too small.  Try increasing the stack size.  In a shell use the Stack
+command before launching Vim.  On the Workbench, select the Vim icon, use the
+workbench "Info" menu and change the Stack field in the form.
+
+If you want to use different colors set the termcap codes:
+	t_mr (for inverted text)
+	t_md (for bold text)
+	t_me (for normal text after t_mr and t_md)
+	t_so (for standout mode)
+	t_se (for normal text after t_so)
+	t_us (for underlined text)
+	t_ue (for normal text after t_us)
+	t_ZH (for italic text)
+	t_ZR (for normal text after t_ZH)
+
+Standard ANSI escape sequences are used.  The codes are:
+30 grey char   40 grey cell   >0 grey background    0 all attributes off
+31 black char  41 black cell  >1 black background   1 boldface
+32 white char  42 white cell  >2 white background   2 faint
+33 blue char   43 blue cell   >3 blue background    3 italic
+34 grey char   44 grey cell   >4 grey background    4 underscore
+35 black char  45 black cell  >5 black background   7 reverse video
+36 white char  46 white cell  >6 white background   8 invisible
+37 blue char   47 blue cell   >7 blue background
+
+The codes with '>' must be the last.  The cell and background color should be
+the same.  The codes can be combined by separating them with a semicolon.  For
+example to get white text on a blue background: >
+  :set t_me=^V<Esc>[0;32;43;>3m
+  :set t_se=^V<Esc>[0;32;43;>3m
+  :set t_ue=^V<Esc>[0;32;43;>3m
+  :set t_ZR=^V<Esc>[0;32;43;>3m
+  :set t_md=^V<Esc>[1;32;43;>3m
+  :set t_mr=^V<Esc>[7;32;43;>3m
+  :set t_so=^V<Esc>[0;31;43;>3m
+  :set t_us=^V<Esc>[4;32;43;>3m
+  :set t_ZH=^V<Esc>[3;32;43;>3m
+
+When using multiple commands with a filter command, e.g. >
+  :r! echo this; echo that
+Only the output of the last command is used.  To fix this you have to group the
+commands.  This depends on the shell you use (that is why it is not done
+automatically in Vim).  Examples: >
+  :r! (echo this; echo that)
+  :r! {echo this; echo that}
+
+Commands that accept a single file name allow for embedded spaces in the file
+name.  However, when using commands that accept several file names, embedded
+spaces need to be escaped with a backslash.
+
+------------------------------------------------------------------------------
+Vim for MorphOS							*MorphOS*
+
+[this section mostly by Ali Akcaagac]
+
+For the latest info about the MorphOS version:
+	http://www.akcaagac.com/index_vim.html
+
+
+Problems ~
+
+There are a couple of problems which are not MorphOS related but more Vim and
+UN*X related.  When starting up Vim in ram: it complains with a nag requester
+from MorphOS please simply ignore it.  Another problem is when running Vim as
+is some plugins will cause a few problems which you can ignore as well.
+Hopefully someone will be fixing it over the time.
+
+To pass all these problems for now you can either run:
+
+	vim <file to be edited>
+
+or if you want to run Vim plain and enjoy the motion of Helpfiles etc. it then
+would be better to enter:
+
+	vim --noplugins <of course you can add a file>
+
+
+Installation ~
+
+1) Please copy the binary 'VIM' file to c:
+2) Get the Vim runtime package from:
+
+	ftp://ftp.vim.org/pub/vim/amiga/vim62rt.tgz
+
+   and unpack it in your 'Apps' directory of the MorphOS installation.  For me
+   this would create following directory hierarchy:
+
+	MorphOS:Apps/Vim/Vim62/...
+
+3) Add the following lines to your s:shell-startup (Important!).
+
+	;Begin VIM
+	Set VIM=MorphOS:Apps/Vim/Vim62
+	Assign HOME: ""
+	;End VIM
+
+4) Copy the '.vimrc' file to s:
+
+5) There is also a file named 'color-sequence' included in this archive.  This
+   will set the MorphOS Shell to show ANSI colors.  Please copy the file to s:
+   and change the s:shell-startup to:
+
+	;Begin VIM
+	Set VIM=MorphOS:Apps/Vim/Vim62
+	Assign HOME: ""
+	Execute S:Color-Sequence
+	Cls
+	;End VIM
+
+
+ vim:tw=78:ts=8:ft=help:norl:
--- /dev/null
+++ b/lib/vimfiles/doc/os_beos.txt
@@ -1,0 +1,348 @@
+*os_beos.txt*	For Vim version 7.1.  Last change: 2005 Mar 29
+
+
+		  VIM REFERENCE MANUAL    by Bram Moolenaar
+
+
+							*BeOS* *BeBox*
+This is a port of Vim 5.1 to the BeOS Preview Release 2 (also known as PR2)
+or later.
+
+This file contains the particularities for the BeBox/BeOS version of Vim.  For
+matters not discussed in this file, Vim behaves very much like the Unix
+|os_unix.txt| version.
+
+ 1. General			|beos-general|
+ 2. Compiling Vim		|beos-compiling|
+ 3. Timeout in the Terminal	|beos-timeout|
+ 4. Unicode vs. Latin1		|beos-unicode|
+ 5. The BeOS GUI		|beos-gui|
+ 6. The $VIM directory		|beos-vimdir|
+ 7. Drag & Drop			|beos-dragndrop|
+ 8. Single Launch vs. Multiple
+    Launch			|beos-launch|
+ 9. Fonts			|beos-fonts|
+10. The meta key modifier	|beos-meta|
+11. Mouse key mappings		|beos-mouse|
+12. Color names			|beos-colors|
+13. Compiling with Perl		|beos-perl|
+
+
+1. General						*beos-general*
+
+The default syntax highlighting mostly works with different foreground colors
+to highlight items.  This works best if you set your Terminal window to a
+darkish background and light letters.  Some middle-grey background (for
+instance (r,g,b)=(168,168,168)) with black letters also works nicely.  If you
+use the default light background and dark letters, it may look better to
+simply reverse the notion of foreground and background color settings.  To do
+this, add this to your .vimrc file (where <Esc> may need to be replaced with
+the escape character): >
+
+  :if &term == "beos-ansi"
+  :    set t_AB=<Esc>[3%dm
+  :    set t_AF=<Esc>[4%dm
+  :endif
+
+
+2. Compiling Vim					*beos-compiling*
+
+From the Advanced Access Preview Release (AAPR) on, Vim can be configured with
+the standard configure script.  To get the compiler and its flags right, use
+the following command-line in the shell (you can cut and paste it in one go):
+
+CC=$BE_C_COMPILER CFLAGS="$BE_DEFAULT_C_FLAGS -O7" \
+    ./configure --prefix=/boot/home/config
+
+$BE_C_COMPILER is usually "mwcc", $BE_DEFAULT_C_FLAGS is usually "-I- -I."
+
+When configure has run, and you wish to enable GUI support, you must edit the
+config.mk file so that the lines with GUI_xxx refer to $(BEOSGUI_xxx) instead
+of $(NONE_xxx).
+Alternatively you can make this change in the Makefile; it will have a
+more permanent effect.  Search for "NONE_".
+
+After compilation you need to add the resources to the binary.  Add the
+following few lines near the end (before the line with "exit $exit_value") of
+the link.sh script to do this automatically.
+
+    rmattr BEOS:TYPE vim
+    copyres os_beos.rsrc vim
+    mimeset vim
+
+Also, create a dummy file "strip":
+
+    #!/bin/sh
+    mimeset $1
+    exit 0
+
+You will need it when using "make install" to install Vim.
+
+Now type "make" to compile Vim, then "make install" to install it.
+
+If you want to install Vim by hand, you must copy Vim to $HOME/config/bin, and
+create a bunch of symlinks to it ({g,r,rg}{vim,ex,view}).  Furthermore you must
+copy Vim's configuration files to $HOME/config/share/vim:
+vim-5.0s/{*.vim,doc,syntax}.  For completeness, you should also copy the nroff
+manual pages to $HOME/config/man/man1.  Don't forget ctags/ctags and xxd/xxd!
+
+Obviously, you need the unlimited linker to actually link Vim.  See
+http://www.metrowerks.com for purchasing the CodeWarrior compiler for BeOS.
+There are currently no other linkers that can do the job.
+
+This won't be able to include the Perl or Python interfaces even if
+you have the appropriate files installed. |beos-perl|
+
+
+3. Timeout in the Terminal				*beos-timeout*
+
+Because some POSIX/UNIX features are still missing[1], there is no direct OS
+support for read-with-timeout in the Terminal.  This would mean that you cannot
+use :mappings of more than one character, unless you also :set notimeout.
+|'timeout'|
+
+To circumvent this problem, I added a workaround to provide the necessary
+input with timeout by using an extra thread which reads ahead one character.
+As a side effect, it also makes Vim recognize when the Terminal window
+resizes.
+
+Function keys are not supported in the Terminal since they produce very
+indistinctive character sequences.
+
+These problems do not exist in the GUI.
+
+[1]: there is no select() on file descriptors; also the termios VMIN and VTIME
+settings do not seem to work properly.  This has been the case since DR7 at
+least and still has not been fixed as of PR2.
+
+							*beos-unicode*
+4. Unicode vs. Latin1					*beos-utf8*
+
+BeOS uses Unicode and UTF-8 for text strings (16-bit characters encoded to
+8-bit characters).  Vim assumes ISO-Latin1 or other 8-bit character codes.
+This does not produce the desired results for non-ASCII characters.  Try the
+command :digraphs to see.  If they look messed up, use :set isprint=@ to
+(slightly) improve the display of ISO-Latin1 characters 128-255.  This works
+better in the GUI, depending on which font you use (below).
+
+You may also use the /boot/bin/xtou command to convert UTF-8 files from (xtou
+-f iso1 filename) or to (xtou -t iso1 filename) ISO-Latin1 characters.
+
+
+5. The BeOS GUI						*beos-gui*
+
+Normally Vim starts with the GUI if you start it as gvim or vim -g.  The BeOS
+version tries to determine if it was started from the Tracker instead of the
+Terminal, and if so, use the GUI anyway.  However, the current detection scheme
+is fooled if you use the command "vim - </dev/null" or "vim filename &".  The
+latter can be called a feature but probably only works because there is no
+BSD-style job control.
+
+Stuff that does not work yet:
+
+- Running external commands from the GUI does not work 100% (again due to lack
+  of support for select()).  There was a choice between seeing the command's
+  output, or being able to interrupt it.  I chose for seeing the output.  Even
+  now the command sometimes crashes mysteriously, apparently in Be's
+  malloc_internal() called from the putenv() function, after fork()ing.  (data
+  access exception occurred, ec01b0ec:  90e80000 *stw r7, 0x0000 (r8)).  (:!ls
+  works usually, :r !ls usually doesn't).  This has been reported as bug
+  # 971215-083826.
+- The window title.
+- Starting the GUI from the Terminal version with :gui always acts as if
+  :gui -f were used.  There is no way to fix this that I can see.
+- There are some small display glitches here and there that I hope to clean up
+  later.  Most of them occur when the window is partially obscured.  Some of
+  them seem to be bugs in BeOS, because the Terminal has similar glitches.
+- Mouse up events are not generated when outside the window.  This is a bug in
+  BeOS.  You can notice this when selecting text and moving the cursor outside
+  the window, then letting go of the mouse button.  Another way is when you
+  drag the scrollbar and do the same thing.  Because Vim still thinks you are
+  still playing with the scrollbar it won't change it itself.  I provided a
+  workaround which kicks in when the window is activated or deactivated (so it
+  works best with focus- follows-mouse (/boot/bin/ffm) turned on).
+- The cursor does not flash (very low priority; I'm not sure I even like it
+  when it flashes)
+
+
+6. The $VIM directory					*beos-vimdir*
+
+$VIM is the symbolic name for the place where Vims support files are stored.
+The default value for $VIM is set at compile time and can be determined with >
+
+  :version
+
+The normal value is /boot/home/config/share/vim.  If you don't like it you can
+set the VIM environment variable to override this, or set 'helpfile' in your
+.vimrc: >
+
+  :if version >= 500
+  :    set helpfile=~/vim/vim54/doc/help.txt
+  :    syntax on
+  :endif
+
+
+7. Drag & Drop						*beos-dragndrop*
+
+You can drop files and directories on either the Vim icon (starts a new Vim
+session, unless you use the File Types application to set Vim to be "Single
+Launch") or on the Vim window (starts editing the files).  Dropping a folder
+sets Vim's current working directory. |:cd| |:pwd| If you drop files or
+folders with either SHIFT key pressed, Vim changes directory to the folder
+that contains the first item dropped.  When starting Vim, there is no need to
+press shift: Vim behaves as if you do.
+
+Files dropped set the current argument list. |argument-list|
+
+
+8. Single Launch vs. Multiple Launch			*beos-launch*
+
+As distributed Vim's Application Flags (as seen in the FileTypes preference)
+are set to Multiple Launch.  If you prefer, you can set them to Single Launch
+instead.  Attempts to start a second copy of Vim will cause the first Vim to
+open the files instead.  This works from the Tracker but also from the command
+line.  In the latter case, non-file (option) arguments are not supported.
+
+NB: Only the GUI version has a BApplication (and hence Application Flags).
+This section does not apply to the GUI-less version, should you compile one.
+
+
+9. Fonts						*beos-fonts*
+
+Set fonts with >
+
+  :set guifont=Courier10_BT/Roman/10
+
+where the first part is the font family, the second part the style, and the
+third part the size.  You can use underscores instead of spaces in family and
+style.
+
+Best results are obtained with monospaced fonts (such as Courier).  Vim
+attempts to use all fonts in B_FIXED_SPACING mode but apparently this does not
+work for proportional fonts (despite what the BeBook says).
+
+Vim also tries to use the B_ISO8859_1 encoding, also known as ISO Latin 1.
+This also does not work for all fonts.  It does work for Courier, but not for
+ProFontISOLatin1/Regular (strangely enough).  You can verify this by giving the >
+
+  :digraphs
+
+command, which lists a bunch of characters with their ISO Latin 1 encoding.
+If, for instance, there are "box" characters among them, or the last character
+isn't a dotted-y, then for this font the encoding does not work.
+
+If the font you specify is unavailable, you get the system fixed font.
+
+Standard fixed-width system fonts are:
+
+	      ProFontISOLatin1/Regular
+		  Courier10_BT/Roman
+		  Courier10_BT/Italic
+		  Courier10_BT/Bold
+		  Courier10_BT/Bold_Italic
+
+Standard proportional system fonts are:
+
+		    Swis721_BT/Roman
+		    Swis721_BT/Italic
+		    Swis721_BT/Bold
+		    Swis721_BT/Bold_Italic
+		Dutch801_Rm_BT/Roman
+		Dutch801_Rm_BT/Italic
+		Dutch801_Rm_BT/Bold
+		Dutch801_Rm_BT/Bold_Italic
+		   Baskerville/Roman
+		   Baskerville/Italic
+		   Baskerville/Bold
+		   Baskerville/Bold_Italic
+		 SymbolProp_BT/Regular
+
+Try some of them, just for fun.
+
+
+10. The meta key modifier				*beos-meta*
+
+The META key modifier is obtained by the left or right OPTION keys.  This is
+because the ALT (aka COMMAND) keys are not passed to applications.
+
+
+11. Mouse key mappings					*beos-mouse*
+
+Vim calls the various mouse buttons LeftMouse, MiddleMouse and RightMouse.  If
+you use the default Mouse preference settings these names indeed correspond to
+reality.  Vim uses this mapping:
+
+    Button 1 -> LeftMouse,
+    Button 2 -> RightMouse,
+    Button 3 -> MiddleMouse.
+
+If your mouse has fewer than 3 buttons you can provide your own mapping from
+mouse clicks with modifier(s) to other mouse buttons.  See the file
+vim-5.x/macros/swapmous.vim for an example.		|gui-mouse-mapping|
+
+
+12. Color names						*beos-colors*
+
+Vim has a number of color names built-in.  Additional names are read from the
+file $VIMRUNTIME/rgb.txt, if present.  This file is basically the color
+database from X.  Names used from this file are cached for efficiency.
+
+
+13. Compiling with Perl					*beos-perl*
+
+Compiling with Perl support enabled is slightly tricky.  The Metrowerks
+compiler has some strange ideas where to search for include files.  Since
+several include files with Perl have the same names as some Vim header
+files, the wrong ones get included.  To fix this, run the following Perl
+script while in the vim-5.0/src directory: >
+
+   preproc.pl > perl.h
+
+    #!/bin/env perl
+    # Simple #include expander, just good enough for the Perl header files.
+
+    use strict;
+    use IO::File;
+    use Config;
+
+    sub doinclude
+    {
+	my $filename = $_[0];
+	my $fh = new IO::File($filename, "r");
+	if (defined $fh) {
+	    print "/* Start of $filename */\n";
+
+	    while (<$fh>) {
+		if (/^#include "(.*)"/) {
+		    doinclude($1);
+		    print "/* Back in $filename */\n";
+		} else {
+		    print $_;
+		}
+	    }
+	    print "/* End of $filename */\n";
+
+	    undef $fh;
+	} else {
+	    print "/* Cannot open $filename */\n";
+	    print "#include \"$filename\"\n";
+	}
+    }
+
+    chdir     $Config{installarchlib}."/CORE";
+    doinclude "perl.h";
+
+It expands the "perl.h" header file, using only other Perl header files.
+
+Now you can configure & make Vim with the --enable-perlinterp option.
+Be warned though that this adds about 616 kilobytes to the size of Vim!
+Without Perl, Vim with default features and GUI is about 575K, with Perl
+it is about 1191K.
+
+-Olaf Seibert
+
+[Note: these addresses no longer work:]
+<rhialto@polder.ubc.kun.nl>
+http://polder.ubc.kun.nl/~rhialto/be
+
+ vim:tw=78:ts=8:ft=help:norl:
--- /dev/null
+++ b/lib/vimfiles/doc/os_dos.txt
@@ -1,0 +1,296 @@
+*os_dos.txt*    For Vim version 7.1.  Last change: 2006 Mar 30
+
+
+		  VIM REFERENCE MANUAL    by Bram Moolenaar
+
+
+							*dos* *DOS*
+This file documents the common particularities of the MS-DOS and Win32
+versions of Vim.  Also see |os_win32.txt| and |os_msdos.txt|.
+
+1. File locations		|dos-locations|
+2. Using backslashes		|dos-backslash|
+3. Standard mappings		|dos-standard-mappings|
+4. Screen output and colors	|dos-colors|
+5. File formats			|dos-file-formats|
+6. :cd command			|dos-:cd|
+7. Interrupting			|dos-CTRL-Break|
+8. Temp files			|dos-temp-files|
+9. Shell option default		|dos-shell|
+
+==============================================================================
+1. File locations					*dos-locations*
+
+If you keep the Vim executable in the directory that contains the help and
+syntax subdirectories, there is no need to do anything special for Vim to
+work.  No registry entries or environment variables need to be set.  Just make
+sure that the directory is in your search path, or use a shortcut on the
+desktop.
+
+Your vimrc files ("_vimrc" and "_gvimrc") are normally located one directory
+up from the runtime files.  If you want to put them somewhere else, set the
+environment variable $VIM to the directory where you keep them.  Example: >
+	set VIM=C:\user\piet
+Will find "c:\user\piet\_vimrc".
+Note: This would only be needed when the computer is used by several people.
+Otherwise it's simpler to keep your _vimrc file in the default place.
+
+If you move the executable to another location, you also need to set the $VIM
+environment variable.  The runtime files will be found in "$VIM/vim{version}".
+Example: >
+	set VIM=E:\vim
+Will find the version 5.4 runtime files in "e:\vim\vim54".
+Note: This is _not_ recommended.  The preferred way is to keep the executable
+in the runtime directory.
+
+If you move your executable AND want to put your "_vimrc" and "_gvimrc" files
+somewhere else, you must set $VIM to where you vimrc files are, and set
+$VIMRUNTIME to the runtime files.  Example: >
+	set VIM=C:\usr\piet
+	set VIMRUNTIME=E:\vim\vim54
+Will find "c:\user\piet\_vimrc" and the runtime files in "e:\vim\vim54".
+
+See |$VIM| and |$VIMRUNTIME| for more information.
+
+Under Windows 95, you can set $VIM in your C:\autoexec.bat file.  For
+example: >
+  set VIM=D:\vim
+Under Windows NT, you can set environment variables for each user separately
+under "Start/Settings/Control Panel->System", or through the properties in the
+menu of "My Computer", under the Environment Tab.
+
+==============================================================================
+2. Using backslashes					*dos-backslash*
+
+Using backslashes in file names can be a problem.  Vi halves the number of
+backslashes for some commands.  Vim is a bit more tolerant and does not remove
+backslashes from a file name, so ":e c:\foo\bar" works as expected.  But when
+a backslash occurs before a special character (space, comma, backslash, etc.),
+Vim removes the backslash.  Use slashes to avoid problems: ":e c:/foo/bar"
+works fine.  Vim replaces the slashes with backslashes internally to avoid
+problems with some MS-DOS programs and Win32 programs.
+
+When you prefer to use forward slashes, set the 'shellslash' option.  Vim will
+then replace backslashes with forward slashes when expanding file names.  This
+is especially useful when using a Unix-like 'shell'.
+
+==============================================================================
+3. Standard mappings				*dos-standard-mappings*
+
+The mappings for CTRL-PageUp and CTRL-PageDown have been removed, they now
+jump to the next or previous tab page |<C-PageUp>| |<C-PageDown>|
+
+If you want them to move to the first and last screen line you can use these
+mappings:
+
+key		key code     Normal/Visual mode	    Insert mode ~
+CTRL-PageUp	<M-N><M-C-D>	    H		    <C-O>H
+CTRL-PageDown	<M-N>v		    L$		    <C-O>L<C-O>$
+
+Additionally, these keys are available for copy/cut/paste.  In the Win32
+and DJGPP versions, they also use the clipboard.
+
+Shift-Insert	paste text (from clipboard)			*<S-Insert>*
+CTRL-Insert	copy Visual text (to clipboard)			*<C-Insert>*
+CTRL-Del	cut Visual text (to clipboard)			*<C-Del>*
+Shift-Del	cut Visual text (to clipboard)			*<S-Del>*
+
+These mappings accomplish this (Win32 and DJGPP versions of Vim):
+
+key		key code     Normal	Visual	    Insert ~
+Shift-Insert	<M-N><M-T>   "*P	"-d"*P      <C-R><C-O>*
+CTRL-Insert	<M-N><M-U>		"*y
+Shift-Del	<M-N><M-W>		"*d
+CTRL-Del	<M-N><M-X>		"*d
+
+Or these mappings (non-Win32 version of Vim):
+
+key		key code     Normal	Visual	    Insert ~
+Shift-Insert	<M-N><M-T>   P		"-dP	    <C-R><C-O>"
+CTRL-Insert	<M-N><M-U>		y
+Shift-Del	<M-N><M-W>		d
+CTRL-Del	<M-N><M-X>		d
+
+When the clipboard is supported, the "* register is used.
+
+==============================================================================
+4. Screen output and colors				*dos-colors*
+
+The default output method for the screen is to use bios calls.  This works
+right away on most systems.  You do not need ansi.sys.  You can use ":mode" to
+set the current screen mode.  See |:mode|.
+
+To change the screen colors that Vim uses, you can use the |:highlight|
+command.  The Normal highlight group specifies the colors Vim uses for normal
+text.  For example, to get grey text on a blue background: >
+	:hi Normal ctermbg=Blue ctermfg=grey
+See |highlight-groups| for other groups that are available.
+
+A DOS console does not support attributes like bold and underlining.  You can
+set the color used in five modes with nine terminal options.  Note that this
+is not necessary since you can set the color directly with the ":highlight"
+command; these options are for backward compatibility with older Vim versions.
+The |'highlight'| option specifies which of the five modes is used for which
+action. >
+
+	:set t_mr=^V^[\|xxm		start of invert mode
+	:set t_md=^V^[\|xxm		start of bold mode
+	:set t_me=^V^[\|xxm		back to normal text
+
+	:set t_so=^V^[\|xxm		start of standout mode
+	:set t_se=^V^[\|xxm		back to normal text
+
+	:set t_us=^V^[\|xxm		start of underline mode
+	:set t_ue=^V^[\|xxm		back to normal text
+
+	:set t_ZH=^V^[\|xxm		start of italics mode
+	:set t_ZR=^V^[\|xxm		back to normal text
+
+^V is CTRL-V
+^[ is <Esc>
+You must replace xx with a decimal code, which is the foreground color number
+and background color number added together:
+
+COLOR			FOREGROUND	BACKGROUND	~
+Black			    0		    0
+DarkBlue		    1		   16
+DarkGreen		    2		   32
+DarkCyan		    3		   48
+DarkRed			    4		   64
+DarkMagenta		    5		   80
+Brown, DarkYellow	    6		   96
+LightGray		    7		  112
+DarkGray		    8		  128 *
+Blue, LightBlue		    9		  144 *
+Green, LightGreen	   10		  160 *
+Cyan, LightCyan		   11		  176 *
+Red, LightRed		   12		  192 *
+Magenta, LightMagenta	   13		  208 *
+Yellow, LightYellow	   14		  224 *
+White			   15		  240 *
+
+* Depending on the display mode, the color codes above 128 may not be
+  available, and code 128 will make the text blink.
+
+When you use 0, the color is reset to the one used when you started Vim
+(usually 7, lightgray on black, but you can override this.  If you have
+overridden the default colors in a command prompt, you may need to adjust
+some of the highlight colors in your vimrc---see below).
+This is the default for t_me.
+
+The defaults for the various highlight modes are:
+	t_mr	112	 reverse mode: Black text (0) on LightGray (112)
+	t_md	 15	 bold mode: White text (15) on Black (0)
+	t_me	  0	 normal mode (revert to default)
+
+	t_so	 31	 standout mode: White (15) text on DarkBlue (16)
+	t_se	  0	 standout mode end (revert to default)
+
+	t_czh	225	 italic mode: DarkBlue text (1) on Yellow (224)
+	t_czr	  0	 italic mode end (revert to default)
+
+	t_us	 67	 underline mode: DarkCyan text (3) on DarkRed (64)
+	t_ue	  0	 underline mode end (revert to default)
+
+These colors were chosen because they also look good when using an inverted
+display, but you can change them to your liking.
+
+Example: >
+  :set t_mr=^V^[\|97m	" start of invert mode: DarkBlue (1) on Brown (96)
+  :set t_md=^V^[\|67m	" start of bold mode: DarkCyan (3) on DarkRed (64)
+  :set t_me=^V^[\|112m	" back to normal mode: Black (0) on LightGray (112)
+
+  :set t_so=^V^[\|37m	" start of standout mode: DarkMagenta (5) on DarkGreen
+									(32)
+  :set t_se=^V^[\|112m	" back to normal mode: Black (0) on LightGray (112)
+
+==============================================================================
+5. File formats						*dos-file-formats*
+
+If the 'fileformat' option is set to "dos" (which is the default), Vim accepts
+a single <NL> or a <CR><NL> pair for end-of-line (<EOL>).  When writing a
+file, Vim uses <CR><NL>.  Thus, if you edit a file and write it, Vim replaces
+<NL> with <CR><NL>.
+
+If the 'fileformat' option is set to "unix", Vim uses a single <NL> for <EOL>
+and shows <CR> as ^M.
+
+You can use Vim to replace <NL> with <CR><NL> by reading in any mode and
+writing in Dos mode (":se ff=dos").
+You can use Vim to replace <CR><NL> with <NL> by reading in Dos mode and
+writing in Unix mode (":se ff=unix").
+
+Vim sets 'fileformat' automatically when 'fileformats' is not empty (which is
+the default), so you don't really have to worry about what you are doing.
+					|'fileformat'| |'fileformats'|
+
+If you want to edit a script file or a binary file, you should set the
+'binary' option before loading the file.  Script files and binary files may
+contain single <NL> characters which Vim would replace with <CR><NL>.  You can
+set 'binary' automatically by starting Vim with the "-b" (binary) option.
+
+==============================================================================
+6. :cd command						*dos-:cd*
+
+The ":cd" command recognizes the drive specifier and changes the current
+drive.  Use ":cd c:" to make drive C the active drive.  Use ":cd d:\foo" to go
+to the directory "foo" in the root of drive D.  Vim also recognizes UNC names
+if the system supports them; e.g., ":cd \\server\share\dir".  |:cd|
+
+==============================================================================
+7. Interrupting						*dos-CTRL-Break*
+
+Use CTRL-Break instead of CTRL-C to interrupt searches.  Vim does not detect
+the CTRL-C until it tries to read a key.
+
+==============================================================================
+8. Temp files						*dos-temp-files*
+
+Only for the 16 bit and 32 bit DOS version:
+Vim puts temporary files (for filtering) in the first of these directories
+that exists and in which Vim can create a file:
+	$TMP
+	$TEMP
+	C:\TMP
+	C:\TEMP
+	current directory
+
+For the Win32 version (both console and GUI):
+Vim uses standard Windows functions to obtain a temporary file name (for
+filtering).  The first of these directories that exists and in which Vim can
+create a file is used:
+	$TMP
+	$TEMP
+	current directory
+
+==============================================================================
+9. Shell option default					*dos-shell*
+
+The default for the 'sh' ('shell') option is "command.com" on Windows 95 and
+"cmd.exe" on Windows NT.  If SHELL is defined, Vim uses SHELL instead, and if
+SHELL is not defined but COMSPEC is, Vim uses COMSPEC.  Vim starts external
+commands with "<shell> /c <command_name>".  Typing CTRL-Z starts a new command
+subshell.  Return to Vim with "exit".	|'shell'| |CTRL-Z|
+
+If you are running a third-party shell, you may need to set the
+|'shellcmdflag'| ('shcf') and |'shellquote'| ('shq') or |'shellxquote'|
+('sxq') options.  Unfortunately, this also depends on the version of Vim used.
+For example, with the MKS Korn shell or with bash, the values of the options
+should be:
+
+		DOS 16 bit	    DOS 32 bit		Win32  ~
+'shellcmdflag'	   -c			-c		 -c
+'shellquote'	   "
+'shellxquote'						 "
+
+For Dos 16 bit this starts the shell as:
+	<shell> -c "command name" >file
+For Win32 as:
+	<shell> -c "command name >file"
+For DOS 32 bit, DJGPP does this internally somehow.
+
+When starting up, Vim checks for the presence of "sh" anywhere in the 'shell'
+option.  If it is present, Vim sets the 'shellcmdflag' and 'shellquote' or
+'shellxquote' options will be set as described above.
+
+ vim:tw=78:ts=8:ft=help:norl:
--- /dev/null
+++ b/lib/vimfiles/doc/os_mac.txt
@@ -1,0 +1,118 @@
+*os_mac.txt*    For Vim version 7.1.  Last change: 2006 Apr 30
+
+
+		  VIM REFERENCE MANUAL    by Bram Moolenaar et al.
+
+
+					*mac* *Mac* *macintosh* *Macintosh*
+
+This file documents the particularities of the Macintosh version of Vim.
+
+NOTE: This file is a bit outdated.  You might find more useful info here:
+	http://macvim.org/
+
+1. Filename Convention		|mac-filename|
+2. .vimrc an .vim files		|mac-vimfile|
+3. FAQ				|mac-faq|
+4. Known Lack			|mac-lack|
+5. Mac Bug Report		|mac-bug|
+6. Compiling Vim		|mac-compile|
+
+There was a Mac port for version 3.0 of Vim.  Here are the first few lines
+from the old file:
+
+VIM Release Notes
+Initial Macintosh release, VIM version 3.0
+19 October 1994
+
+Eric Fischer
+<enf1@midway.uchicago.edu>, <eric@jcp.uchicago.edu>, <etaoin@uchicago.edu>
+5759 N. Guilford Ave
+Indianapolis IN 46220 USA
+
+==============================================================================
+1. Filename Convention					*mac-filename*
+
+Starting with Vim version 7 you can just use the unix path separators with
+Vim. In order to determine if the specified filename is relative to the
+current folder or absolute (i.e. relative to the "Desktop"), the following
+algorithm is used:
+
+	If the path start by a "/", the path is absolute
+	If the path start by a ":", the path is relative
+	If the path doesn't start by neither a "/" nor ":",
+	  and a ":" is found before a "/" then the path is absolute
+>
+		:e /HD/text
+		:e HD:text
+<	Edit the file "text" of the disk "HD" >
+		:e :src:main.c
+		:e src/main.c
+<	Edit the file "main.c" in the folder "src" in the current folder >
+		:e os_mac.c
+<	Edit the file "os_mac.c" in the current folder.
+
+You can use the |$VIM| and |$VIMRUNTIME|  variable. >
+
+		:so $VIMRUNTIME:syntax:syntax.vim
+
+==============================================================================
+2. .vimrc and .vim files				*mac-vimfile*
+
+It is recommended to use Unix style line separators for Vim scripts, thus a
+single newline character.
+
+When starting up Vim will load the $VIMRUNTIME/macmap.vim script to define
+default command-key mappings.
+
+On older systems files starting with a dot "." are discouraged, thus the rc
+files are named "vimrc" or "_vimrc" and "gvimrc" or "_gvimrc".  These files
+can be in any format (mac, dos or unix).  Vim can handle any file format when
+the |'nocompatible'| option is set, otherwise it will only handle mac format
+files.
+
+==============================================================================
+3. Mac FAQ						*mac-faq*
+
+On the internet:  http://macvim.org/OSX/index.php#FAQ
+
+Q: I can't enter non-ASCII character in Apple Terminal.
+A: Under Window Settings, Emulation, make sure that "Escape non-ASCII
+   characters" is not checked.
+
+Q: How do I start the GUI from the command line?
+A: Assuming that Vim.app is located in /Applications:
+	open /Applications/Vim.app
+   Or:
+	/Applications/Vim.app/Contents/MacOS/Vim -g  {arguments}
+
+Q: How can I set $PATH to something reasonable when I start Vim.app from the
+   GUI or with open?
+A: The following trick works with most shells.  Put it in your vimrc file.
+   This is included in the system vimrc file included with the binaries
+   distributed at macvim.org . >
+	let s:path = system("echo echo VIMPATH'${PATH}' | $SHELL -l")
+	let $PATH = matchstr(s:path, 'VIMPATH\zs.\{-}\ze\n')
+
+==============================================================================
+4. Mac Lack						*mac-lack*
+
+In a terminal CTRL-^ needs to be entered as Shift-Control-6.  CTRL-@ as
+Shift-Control-2.
+
+==============================================================================
+5. Mac Bug Report					*mac-bug*
+
+When reporting any Mac specific bug or feature change, please use the vim-mac
+maillist |vim-mac|.  However, you need to be subscribed.  An alternative is to
+send a message to the current MacVim maintainers:
+
+	mac@vim.org
+
+==============================================================================
+6. Compiling Vim					*mac-compile*
+
+See the file "src/INSTALLmac.txt" that comes with the source files.
+
+
+ vim:tw=78:ts=8:ft=help:norl:
--- /dev/null
+++ b/lib/vimfiles/doc/os_mint.txt
@@ -1,0 +1,39 @@
+*os_mint.txt*   For Vim version 7.1.  Last change: 2005 Mar 29
+
+
+		  VIM REFERENCE MANUAL    by Jens M. Felderhoff
+
+
+							*MiNT* *Atari*
+This file contains the particularities for the Atari MiNT version of Vim.
+
+For compiling Vim on the Atari running MiNT see "INSTALL" and "Makefile"
+in the src directory.
+
+Vim for MiNT behaves almost exactly like the Unix version.
+The Unix behavior described in the documentation also refers to the
+MiNT version of Vim unless explicitly stated otherwise.
+
+For wildcard expansion of <~> (home directory) you need a shell that
+expands the tilde.  The vanilla Bourne shell doesn't recognize it.
+With csh and ksh it should work OK.
+
+The MiNT version of vim needs the termcap file /etc/termcap with the
+terminal capabilities of your terminal.  Builtin termcaps are
+supported for the vt52 terminal.  Termcap entries for the TOSWIN window
+manager and the virtual console terminals have been appended to the
+termcap file that comes with the Vim distribution.
+
+If you should encounter problems with swapped <BS> and <Del> keys, see
+|:fixdel|.
+
+Because terminal updating under MiNT is often slow (e.g. serial line
+terminal), the 'showcmd' and 'ruler' options are default off.
+If you have a fast terminal, try setting them on.  You might
+also want to set 'ttyfast'.
+
+Send bug reports to
+
+	Jens M. Felderhoff, e-mail: <jmf@infko.uni-koblenz.de>
+
+ vim:tw=78:ts=8:ft=help:norl:
--- /dev/null
+++ b/lib/vimfiles/doc/os_msdos.txt
@@ -1,0 +1,276 @@
+*os_msdos.txt*  For Vim version 7.1.  Last change: 2005 Mar 29
+
+
+		  VIM REFERENCE MANUAL    by Bram Moolenaar
+
+
+					*msdos* *ms-dos* *MSDOS* *MS-DOS*
+This file contains the particularities for the MS-DOS version of Vim.
+
+1. Two versions for MS-DOS	|msdos-versions|
+2. Known problems		|msdos-problems|
+3. Long file names		|msdos-longfname|
+4. Termcap codes		|msdos-termcap|
+5. Shifted arrow keys		|msdos-arrows|
+6. Filename extensions		|msdos-fname-extensions|
+7. Memory usage and limitations	|msdos-limitations|
+8. Symbolically linked files	|msdos-linked-files|
+9. Copy/paste in a dos box	|msdos-copy-paste|
+
+Additionally, there are a number of common Win32 and DOS items:
+File locations			|dos-locations|
+Using backslashes		|dos-backslash|
+Standard mappings		|dos-standard-mappings|
+Screen output and colors	|dos-colors|
+File formats			|dos-file-formats|
+:cd command			|dos-:cd|
+Interrupting			|dos-CTRL-Break|
+Temp files			|dos-temp-files|
+Shell option default		|dos-shell|
+
+For compiling Vim see src/INSTALL.pc.			*msdos-compiling*
+
+==============================================================================
+1. Two versions for MS-DOS				*msdos-versions*
+
+There are two versions of Vim that can be used with MS-DOS machines:
+
+							*dos16*
+Dos16 version	Can be used on any MS-DOS system, only uses up to 640 Kbyte of
+		memory.  Also runs on OS/2, Windows 95, and NT.  Excludes some
+		Vim-specific features (autocommands, syntax highlighting,
+		etc.).  Recommended for use on pre-386 machines.
+							*dos32*
+Dos32 version	Requires 386 processor and a |DPMI| driver, uses all
+		available memory.  Supports long file names and the Windows
+		clipboard, but NOT on Windows NT.  Recommended for MS-DOS,
+		Windows 3.1 and Windows 95.
+
+There are also two versions that run under Windows:
+Win32 version   Requires Windows 95 or Windows NT, uses all available
+		memory, supports long file names, etc.  Has some problems on
+		Windows 95.  Recommended for Windows NT.  See |os_win32.txt|
+Win32 GUI	Requirements like the Win32 version, but runs in its own
+		window, instead of a console.  Has scrollbars, menu, etc.
+		Recommended for Windows 95 and Windows NT.  See |gui-w32|.
+
+It is recommended to use the Dos32 or Win32 version.  Although the Dos16
+version is able to edit very big files, it quickly runs out of memory when
+making big changes.  Disabling undo helps: ":set ul=-1".  The screen updating
+of the Dos16 version is the fastest of the three on DOS or Windows 95; on
+Windows NT, the Win32 version is just as fast.
+
+								*DPMI*
+For the Dos32 version, you may need a DPMI driver when running in MS-DOS.  If
+you are running Windows or installed a clever memory manager, it will probably
+work already.  If you get the message "No DPMI", you need to install a DPMI
+driver.  Such a driver is included with the executable in CSDPMI4B.ZIP.  Run
+"cwsdpmi" just before starting Vim each time.  Or you might want to include
+"cwsdpmi -p" in your autoexec.bat to make it resident.  The latest version of
+"CSDPMI*.ZIP" can be obtained from: "ftp.neosoft.com:pub/users/s/sandmann".
+
+							*minimal-features*
+The 16 bit DOS version has been compiled with minimal features.  Check the
+|+feature-list| which ones are included (marked with a "T").
+You can include more features by editing feature.h and recompiling.
+
+==============================================================================
+2. Known problems					*msdos-problems*
+
+When using smartdrive (MS-DOS 6.x) with write-behind caching, it is possible
+that Vim will try to create a swap file on a read-only file system (e.g.
+write protected floppy).  You will then be given the message >
+	A serious disk error has occurred .., Retry (r)?
+There is nothing you can do but unprotect the floppy or switch off the
+computer.  Even CTRL-ALT-DEL will not get you out of this.  This is really a
+problem of smartdrive, not Vim.  Smartdrive works fine otherwise.  If this
+bothers you, don't use the write-behind caching.
+
+Vim can't read swap files that have been opened already, unless the "share"
+command has been used.  If you see stray warnings for existing swap files,
+include the "share" command in your config.sys or autoexec.bat (see your MSDOS
+documentation).
+
+The Dos16 version can only have about 10 files open (in a window or hidden) at
+one time.  With more files you will get error messages when trying to read or
+write a file, and for filter commands.  Or Vim runs out of memory, and random
+problems may result.
+
+The Dos32 version cannot have an unlimited number of files open at any one
+time.  The limit depends on the setting of FILES in your CONFIG.SYS.  This
+defaults to 15; if you need to edit a lot of files, you should increase this.
+If you do not set FILES high enough, you can get strange errors, and shell
+commands may cause a crash!
+
+The Dos32 version can work with long file names.  When doing file name
+completion, matches for the short file name will also be found.  But this will
+result in the corresponding long file name.  For example, if you have the long
+file name "this_is_a_test" with the short file name "this_i~1", the command
+":e *1" will start editing "this_is_a_test".
+
+When using the Dos32 version and you run into problems with DPMI support,
+check if there is a program in your config.sys that eats resources.  One
+program known to cause this problem is "netx", which says "NetWare v. 3.26
+Workstation shell".  Replace it with version 3.32 to fix the problem.
+
+The Dos32 version will parse its arguments to handle quotation.  This is good
+to edit a file with spaces in its name, for example: >
+	vim "program files\accessories\ppp.scp"
+A side effect is that single quotes are removed.  Insert a backslash to avoid
+that.  For example, to edit the file "fi'le.txt": >
+	vim fi\'le.txt
+
+==============================================================================
+3. Long file names					*msdos-longfname*
+
+If the Dos32 version is run on Windows 95, it can use long file names.  It
+will work by default.  If you want to disable this, use this setting:
+	set LFN=N
+You can put this in your autoexec.bat file.
+
+Note: If you have installed DJGPP on your machine, you probably have a
+"djgpp.env" file, which contains "LFN=n".  You need to use "LFN=Y" to switch
+on using long file names then.
+
+==============================================================================
+4. Termcap codes					*msdos-termcap*
+
+If you want to use another output method (e.g., when using a terminal on a COM
+port), set the terminal name to "pcansi".  You can change the termcap options
+when needed (see |terminal-options|).  Note that the
+normal IBM ansi.sys does not support all the codes of the builtin pcansi
+terminal.  If you use ansi.sys, you will need to delete the termcap entries
+t_al and t_dl with >
+   :set t_al= t_dl=
+Otherwise, the screen will not be updated correctly.  It is better to use
+nansi.sys, nnansi.sys, or the like instead of ansi.sys.
+
+If you want to use Vim on a terminal connected to a COM: port, reset the
+'bioskey' option.  Otherwise the commands will be read from the PC keyboard.
+CTRL-C and CTRL-P may not work correctly with 'bioskey' reset.
+
+==============================================================================
+5. Shifted arrow keys					*msdos-arrows*
+
+Use CTRL-arrow-left and CTRL-arrow-right instead of SHIFT-arrow-left and
+SHIFT-arrow-right.  The arrow-up and arrow-down cannot be used with SHIFT or
+CTRL.
+
+==============================================================================
+6. Filename extensions				*msdos-fname-extensions*
+
+MS-DOS allows for only one file name extension.  Therefore, when appending an
+extension, the '.' in the original file name is replaced with a '_', the name
+is truncated to 8 characters, and the new extension (e.g., ".swp") is
+appended.  Two examples: "test.c" becomes "test_c.bak", "thisisat.est"
+becomes "thisisat.bak".  To reduce these problems, the default for
+'backupext' is "~" instead of ".bak".  The backup file for "thisisat.est"
+then becomes "thisisat.es~".  The 'shortname' option is not available,
+because it would always be set.
+
+==============================================================================
+7. Memory usage and limitations			*msdos-limitations*
+
+A swap file is used to store most of the text.  You should be able to edit
+very large files.  However, memory is used for undo and other things.  If you
+delete a lot of text, you can still run out of memory in the Dos16 version.
+
+If Vim gives an "Out of memory" warning, you should stop editing.  The result
+of further editing actions is unpredictable.  Setting 'undolevels' to 0 saves
+some memory.  Running the maze macros on a big maze is guaranteed to run out
+of memory, because each change is remembered for undo.  In this case set
+'undolevels' to a negative number.  This will switch off undo completely.
+
+						*msdos-clipboard-limits*
+In the Dos32 version, extended memory is used to avoid these problems.
+However, if you are using the clipboard, you can still run into memory
+limitations because the Windows clipboard can only communicate with Vim using
+Dos memory.  This means that the largest amount of text that can be sent to
+or received from the Windows clipboard is limited by how much free Dos memory
+is available on your system.
+
+You can usually maximize the amount of available Dos memory by adding the
+following lines to Dos's "config.sys" file: >
+
+	DOS=HIGH,UMB
+	DEVICE=C:\WINDOWS\himem.sys
+	DEVICE=C:\WINDOWS\emm386.exe RAM
+
+Modifying config.sys in this way will also help to make more memory available
+for the Dos16 version, if you are using that.
+
+In the Dos16 version the line length is limited to about 32000 characters.
+When reading a file the lines are automatically split.  But editing a line
+in such a way that it becomes too long may give unexpected results.
+
+==============================================================================
+8. Symbolically linked files			*msdos-linked-files*
+
+When using Vim to edit a symbolically linked file on a unix NFS file server,
+you may run into problems.  When writing the file, Vim does not "write
+through" the symlink.  Instead, it deletes the symbolic link and creates a new
+file in its place.
+
+On Unix, Vim is prepared for links (symbolic or hard).  A backup copy of the
+original file is made and then the original file is overwritten.  This assures
+that all properties of the file remain the same.  On non-Unix systems, the
+original file is renamed and a new file is written.  Only the protection bits
+are set like the original file.  However, this doesn't work properly when
+working on an NFS-mounted file system where links and other things exist.  The
+only way to fix this in the current version is not making a backup file, by
+":set nobackup nowritebackup"	|'writebackup'|
+
+A similar problem occurs when mounting a Unix filesystem through Samba or a
+similar system.  When Vim creates a new file it will get the default user ID
+for the mounted file system.  This may be different from the original user ID.
+To avoid this set the 'backupcopy' option to "yes".
+
+==============================================================================
+9. Copy/paste in a dos box			*msdos-copy-paste*
+
+					*E450* *E451* *E452* *E453* *E454*
+The 32 bit version can copy/paste from/to the Windows clipboard directly.  Use
+the "* register.  Large amounts of text can be copied this way, but it must be
+possible to allocate memory for it, see |msdos-clipboard-limits|.  When moving
+text from one Vim to another, the type of the selection
+(characterwise/linewise/blockwise) is passed on.
+
+In other versions, the following can be used.
+
+(posted to comp.editors by John Velman <velman@igate1.hac.com>)
+
+How to copy/paste text from/to vim in a dos box:
+
+1) To get VIM to run in a window, instead of full screen, press alt+enter.
+   This toggles back and forth between full screen and a dos window.
+   NOTE: In Windows 95 you must have the property "Fast Pasting" unchecked!
+   In the properties dialog box for the MS-DOS window, go to "MS-DOS
+   Prompt/Misc/Fast pasting" and make sure that it is NOT checked.
+   To make this permanent, change the properties for
+   "\windows\system\conagent.exe" (from Philip Nelson, unverified).
+
+2) To paste something _into_ Vim, put Vim in insert mode.
+
+3) Put the text you want to paste on the windows clipboard.
+
+4) Click the control box in the upper left of the Vim window.  (This looks
+   like a big minus sign.)  If you don't want to use the mouse, you can get
+   this with alt+spacebar.
+5) On the resulting dropdown menu choose "Edit".
+6) On the child dropdown menu choose "Paste".
+
+To copy something from the Vim window to the clipboard,
+
+1) Select the control box to get the control drop down menu.
+2) Select "Edit".
+3) Select "Mark".
+4) Using either the keys or the mouse, select the part of the Vim window that
+   you want to copy.  To use the keys, use the arrow keys, and hold down shift
+   to extend the selection.
+5) When you've completed your selection, press 'enter'.  The selection
+   is now in the windows clipboard.  By the way, this can be any
+   rectangular selection, for example columns 4-25 in rows 7-10.  It can
+   include anything in the VIM window: the output of a :!dir, for
+   example.
+
+ vim:tw=78:ts=8:ft=help:norl:
--- /dev/null
+++ b/lib/vimfiles/doc/os_os2.txt
@@ -1,0 +1,220 @@
+*os_os2.txt*    For Vim version 7.1.  Last change: 2007 Apr 22
+
+
+		  VIM REFERENCE MANUAL    by Paul Slootman
+
+
+							*os2* *OS2* *OS/2*
+This file contains the particularities for the OS/2 version of Vim.
+
+At present there is no native PM version of the GUI version of Vim: The OS/2
+version is a console application.  However, there is now a Win32s-compatible
+GUI version, which should be usable by owners of Warp 4 (which supports
+Win32s) in a Win-OS/2 session.  The notes in this file refer to the native
+console version.
+
+
+NOTE
+
+This OS/2 port works well for me and a couple of other OS/2 users; however,
+since I haven't had much feedback, that either means no (OS/2-specific) bugs
+exist (besides the ones mentioned below), or no one has yet created a
+situation in which any bugs are apparent.  File I/O in Dos and Unix mode,
+binary mode, and FAT handling all seem to work well, which would seem to be
+the most likely places for trouble.
+
+A known problem is that files opened by Vim are inherited by other programs
+that are started via a shell escape from within Vim.  This specifically means
+that Vim won't be able to remove the swap file(s) associated with buffers open
+at the time the other program was started, until the other program is stopped.
+At that time, the swap file may be removed, but if Vim could not do that the
+first time, it won't be removed at all.  You'll get warnings that some other
+Vim session may be editing the file when you start Vim up again on that file.
+This can be reproduced with ":!start epm".  Now quit Vim, and start Vim again
+with the file that was in the buffer at the time epm was started.  I'm working
+on this!
+
+A second problem is that Vim doesn't understand the situation when using it
+when accessing the OS/2 system via the network, e.g. using telnet from a Unix
+system, and then starting Vim.  The problem seems to be that OS/2 =sometimes=
+recognizes function / cursor keys, and tries to convert those to the
+corresponding OS/2 codes generated by the "normal" PC keyboard.  I've been
+testing a workaround (mapping the OS/2 codes to the correct functions), but so
+far I can't say anything conclusive (this is on Warp 3, by the way).  In the
+meantime any help will be appreciated.
+
+
+PREREQUISITES
+
+To run Vim, you need the emx runtime environment (at least rev. 0.9b).  This
+is generally available as (ask Archie about it):
+
+    emxrt.zip     emx runtime package
+
+I've included a copy of emx.dll, which should be copied to one of the
+directories listed in your LIBPATH.  Emx is GPL'ed, but the emx.dll library is
+not (read COPYING.EMX to find out what that means to you).
+
+This emx.dll is from the emxfix04.zip package, which unfortunately has a bug,
+eh, I mean a POSIX feature, in select().  Versions of Vim before 3.27 will
+appear to hang when starting (actually, while processing vimrc).  Hit <Enter> a
+couple of times until Vim starts working if this happens.  Next, get an up to
+date version of Vim!
+
+
+HELP AND VIMRC FILE
+
+If you unpack the archive that Vim came in and run Vim directly from where it
+was unpacked, Vim should be able to find the runtime files and your .vimrc
+without any settings.
+
+If you put the runtime files separately from the binary, the VIM environment
+variable is used to find the location of the help files and the system .vimrc.
+Place an entry such as this in CONFIG.SYS: >
+
+  SET VIM=c:/local/lib/vim
+
+Put your .vimrc and your other Vim files in this directory.  Copy the runtime
+directory to this directory.  Each version of Vim has its own runtime
+directory.  It will be called something like "c:/local/lib/vim/vim54".  Thus
+you get a tree of Vim files like this:
+	c:/local/lib/vim/.vimrc
+	c:/local/lib/vim/vim54/filetype.vim
+	c:/local/lib/vim/vim54/doc/help.txt
+	etc.
+
+Note: .vimrc may also be called _vimrc to accommodate those who have chosen to
+install OS/2 on a FAT file system.  Vim first tries to find .vimrc and if that
+fails, looks for _vimrc in the same place.  The existence of a .vimrc or
+_vimrc file influences the 'compatible' options, which can have unexpected side
+effects.  See |'compatible'|.
+
+If you're using network drives with OS/2, then you can install Vim on a
+network drive (including .vimrc; this is then called the "system" vimrc file),
+and then use a personal copy of .vimrc (the "user" vimrc file).  This should be
+located in a directory indicated by the HOME environment variable.
+
+
+ENVIRONMENT VARIABLES IN FILE NAMES
+
+This HOME environment variable is also used when using ~ in file names, so
+":e ~/textfile" will edit the file "textfile" in the directory referred to by
+HOME.  Additionally you can use other environment variables in file names, as
+in ":n $SRC/*.c".
+
+The HOME environment variable is also used to locate the .viminfo file
+(see |viminfo-file|).  There is no support yet for .viminfo on FAT file
+systems yet, sorry.  You could try the -i startup flag (as in "vim -i
+$HOME/_viminfo") however.
+
+If the HOME environment variable is not set, the value "C:/" is used as a
+default.
+
+
+BACKSLASHES
+
+Using slashes ('/') and backslashes ('\') can be a bit of a problem (see
+|dos-backslash| for more explanation), but in almost all cases Vim does "The
+Right Thing".  Vim itself uses backslashes in file names, but will happily
+accept forward slashes if they are entered (in fact, sometimes that works
+better!).
+
+
+TEMP FILES
+
+Temporary files (for filtering) are put in the first directory in the next
+list that exists and where a file can be created:
+	$TMP
+	$TEMP
+	C:\TMP
+	C:\TEMP
+	current directory
+
+
+TERMINAL SETTING
+
+							*os2ansi*
+Use "os2ansi" as the TERM environment variable (or don't set it at all, as the
+default is the correct value).  You can set term to os2ansi in the .vimrc, in
+case you need TERM to be a different value for other applications.  The
+problem is that OS/2 ANSI emulation is quite limited (it doesn't have insert /
+delete line, for example).
+
+If you want to use a different value for TERM (because of other programs, for
+example), make sure that the termcap entry for that TERM value has the
+appropriate key mappings.  The termcap.dat distributed with emx does not always
+have them.  Here are some suitable values to add to the termcap entry of your
+choice; these allow the cursor keys and the named function keys (such as
+pagedown) to work.
+
+	:ku=\316H:kd=\316P:kl=\316K:kr=\316M:%i=\316t:#4=\316s:\
+	:kD=\316S:kI=\316R:kN=\316Q:kP=\316I:kh=\316G:@7=\316O:\
+	:k1=\316;:k2=\316<:k3=\316=:k4=\316>:k5=\316?:k6=\316@:\
+	:k7=\316A:k8=\316B:k9=\316C:k;=\316D:
+
+
+Paul Slootman
+
+
+43 LINE WINDOW
+
+A suggestion from Steven Tryon, on how to run Vim in a bigger window:
+
+When I call Vim from an OS/2 WPS application such as PMMail it comes up
+in the default 25-line mode.  To get a more useful window size I make
+my external editor "vimbig.cmd" which in turn calls "vimbig2.cmd".
+Brute force and awkwardness, perhaps, but it works.
+
+vimbig.cmd: >
+   @echo off
+   start "Vi Improved" /f vimbig2.cmd %1 %2 %3 %4
+
+vimbig2.cmd: >
+   @echo off
+   mode 80,43
+   vim.exe %1 %2 %3 %4
+   exit
+<
+
+CLIPBOARD ACCESS (provided by Alexander Wagner)
+
+Vim for OS/2 has no direct access to the system clipboard.  To enable access
+anyway you need an additional tool which gives you access to the clipboard
+from within a vio application.  The freeware package clipbrd.zip by Stefan
+Gruendel can be used for this purpose.  You might download the package
+including precompiled binaries and all sources from:
+	http://www.stellarcom.org/vim/index.html
+
+Installation of this package is straight forward: just put the two executables
+that come with this package into a directory within your PATH for Vim should
+be able to call them from whatever directory you are working.
+
+To copy text from the clipboard to your Vim session you can use the :r
+command.  Simply call clipbrd.exe from within Vim in the following way: >
+
+	:r !clipbrd -r
+
+To copy text from Vim to the system clipboard just mark the text in the usual
+vim-manner and call: >
+
+	:!clipbrd -w
+
+which will write your selection right into OS/2's clipboard.
+
+For ease of use you might want to add some maps for this commands.  E.g. to
+use F11 to paste the clipboard into Vim and F12 to copy selected text to the
+clipboard you would use: >
+
+	if has("os2")
+	  imap <F11>     <ESC>:r !clipbrd -r<CR>i
+	  vmap <F12>     :!clipbrd -w<cr>
+	else
+	  imap <F11>     <ESC>"*p<CR>i
+	  vmap <F12>     "*y
+	endif
+
+This will ensure that only on OS/2 clipbrd is called whereas on other
+platforms vims build in mechanism is used.  (To enable this functions on every
+load of Vim place the above lines in your .vimrc.)
+
+ vim:tw=78:ts=8:ft=help:norl:
--- /dev/null
+++ b/lib/vimfiles/doc/os_qnx.txt
@@ -1,0 +1,138 @@
+*os_qnx.txt*    For Vim version 7.1.  Last change: 2005 Mar 29
+
+
+		  VIM REFERENCE MANUAL    by Julian Kinraid
+
+
+							*QNX* *qnx*
+
+1. General			|qnx-general|
+2. Compiling Vim		|qnx-compiling|
+3. Terminal support		|qnx-terminal|
+4. Photon GUI			|photon-gui|
+5. Photon fonts			|photon-fonts|
+6. Bugs & things To Do
+
+==============================================================================
+
+1. General						*qnx-general*
+
+Vim on QNX behaves much like other unix versions. |os_unix.txt|
+
+
+2. Compiling Vim					*qnx-compiling*
+
+Vim can be compiled using the standard configure/make approach.  If you want to
+compile for X11, pass the --with-x option to configure.  Otherwise, running
+./configure without any arguments or passing --enable-gui=photon, will compile
+vim with the Photon gui support.  Run ./configure --help , to find out other
+features you can enable/disable.
+
+
+3. Terminal support					*qnx-terminal*
+
+Vim has support for the mouse and clipboard in a pterm, if those options
+are compiled in, which they are normally.
+
+The options that affect mouse support are |'mouse'| and |'ttymouse'|.  When
+using the mouse, only simple left and right mouse clicking/dragging is
+supported.  If you hold down shift, ctrl, or alt while using the mouse, pterm
+will handle the mouse itself.  It will make a selection, separate from what
+vim's doing.
+
+When the mouse is in use, you can press Alt-RightMouse to open the pterm menu.
+To turn the mouse off in vim, set the mouse option to nothing, set mouse=
+
+
+4. Photon GUI						*photon-gui*
+
+To start the gui for vim, you need to run either gvim or vim -g, otherwise
+the terminal version will run.  For more info - |gui-x11-start|
+
+Supported features:
+	:browse command					|:browse|
+	:confirm command				|:confirm|
+	Cursor blinking					|'guicursor'|
+	Menus, popup menus and menu priorities		|:menu|
+							|popup-menu|
+							|menu-priority|
+	Toolbar						|gui-toolbar|
+							|'toolbar'|
+	Font selector (:set guifont=*)			|photon-fonts|
+	Mouse focus					|'mousefocus'|
+	Mouse hide					|'mousehide'|
+	Mouse cursor shapes				|'mouseshape'|
+	Clipboard					|gui-clipboard|
+
+Unfinished features:
+	Various international support, such as Farsi & Hebrew support,
+	different encodings, etc.
+
+	This help file
+
+Unsupported features:
+	Find & Replace window				|:promptfind|
+	Tearoff menus
+
+	Other things which I can't think of so I can't list them
+
+
+5. Fonts						*photon-fonts*
+
+You set fonts in the gui with the guifont option >
+	:set guifont=Lucida\ Terminal
+<
+The font must be a monospace font, and any spaces in the font name must be
+escaped with a '\'.  The default font used is PC Terminal, size 8.  Using
+'*' as the font name will open a standard Photon font selector where you can
+select a font.
+
+Following the name, you can include optional settings to control the size and
+style of the font, each setting separated by a ':'.  Not all fonts support the
+various styles.
+
+The options are,
+    s{size}	Set the size of the font to {size}
+    b		Bold style
+    a		Use antialiasing
+    i		Italic style
+
+Examples:
+
+Set the font to monospace size 10 with antialiasing >
+	:set guifont=monospace:s10:a
+<
+Set the font to Courier size 12, with bold and italics >
+	:set guifont=Courier:s12:b:i
+<
+Select a font with the requester >
+	:set guifont=*
+<
+
+
+6. Bugs & things To Do
+
+Known problems:
+	- Vim hangs sometimes when running an external program.  Workaround:
+	  put this line in your |vimrc| file: >
+		set noguipty
+
+Bugs:
+	- Still a slight problem with menu highlighting.
+	- When using phditto/phinows/etc., if you are using a font that
+	  doesn't support the bold attribute, when vim attempts to draw
+	  bold text it will be all messed up.
+	- The cursor can sometimes be hard to see.
+	- A number of minor problems that can fixed. :)
+
+Todo:
+	- Improve multi-language support.
+	- Options for setting the fonts used in the menu and toolbar.
+	- Find & Replace dialog.
+	- The clientserver features.
+	- Maybe tearoff menus.
+
+	- Replace usage of fork() with spawn() when launching external
+	  programs.
+
+ vim:tw=78:sw=4:ts=8:ts=8:ft=help:norl:
--- /dev/null
+++ b/lib/vimfiles/doc/os_risc.txt
@@ -1,0 +1,323 @@
+*os_risc.txt*   For Vim version 7.1.  Last change: 2005 Mar 29
+
+
+		  VIM REFERENCE MANUAL    by Thomas Leonard
+
+
+						*riscos* *RISCOS* *RISC-OS*
+This file contains the particularities for the RISC OS version of Vim.
+
+The RISC OS port is a completely new port and is not based on the old `archi'
+port.
+
+1.  File locations		|riscos-locations|
+2.  Filename munging		|riscos-munging|
+3.  Command-line use		|riscos-commandline|
+4.  Desktop (GUI) use		|riscos-gui|
+5.  Remote use (telnet)		|riscos-remote|
+6.  Temporary files		|riscos-temp-files|
+7.  Interrupting		|riscos-interrupt|
+8.  Memory usage		|riscos-memory|
+9.  Filetypes			|riscos-filetypes|
+10. The shell			|riscos-shell|
+11. Porting new releases	|riscos-porting|
+
+If I've missed anything, email me and I'll try to fix it.  In fact, even if I
+haven't missed anything then email me anyway to give me some confidence that it
+actually works!
+
+Thomas Leonard <tal197@ecs.soton.ac.uk>
+
+	[these URLs no longer work...]
+ Port homepage:	http://www.ecs.soton.ac.uk/~tal197/
+	or try:	http://www.soton.ac.uk/~tal197/
+
+==============================================================================
+							*riscos-locations*
+1. File locations
+
+The Vim executable and shared resource files are all stored inside the !Vim
+application directory.
+
+When !Vim is first seen by the filer, it aliases the *vi and *ex commands to
+run the command-line versions of Vim (see |riscos-commandline|).
+
+!Vim.Resources and !Vim.Resources2 contain the files from the standard Vim
+distribution, but modified slightly to work within the limits of ADFS, plus
+some extra files such as the window templates.
+
+User choices are read from `Choices:*' and are saved to `<Choices$Write>.*'.
+If you have the new !Boot structure then these should be set up already.  If
+not, set Choices$Path to a list of directories to search when looking for
+user configuration files.  Set Choices$Write to the directory you want files
+to be saved into (so your search patterns and marks can be remembered between
+sessions).
+
+==============================================================================
+							*riscos-munging*
+2. Filename munging
+
+All pathname munging is disabled by default, so Vim should behave like a
+normal RISC OS application now.  So, if you want to edit `doc/html' then you
+actually type `*vi doc/html'.
+
+The only times munging is done is when:
+
+- Searching included files from C programs, since these are always munged.
+  See |[I|.
+  Note: make sure you are in the right directory when you use this
+	command (i.e. the one with subdirectories 'c' and 'h').
+
+- Sourcing files using |:so|.
+  Paths starting `$VIM/' are munged like this:
+
+  $VIM/syntax/help.vim  ->  Vim:syntax.help
+
+  Also, files ending in `.vim' have their extensions removed, and slashes
+  replaced with dots.
+
+Some tag files and script files may have to be edited to work under this port.
+
+==============================================================================
+							*riscos-commandline*
+3. Command-line use
+
+To use Vim from the command-line use the `*vi' command (or '*ex' for
+|Ex-mode|).
+
+Type `*vi -h' for a list of options.
+
+Running the command-line version of Vim in a large high-color mode may cause
+the scrolling to be very slow.  Either change to a mode with fewer colors or
+use the GUI version.
+
+Also, holding down Ctrl will slow it down even more, and Ctrl-Shift will
+freeze it, as usual for text programs.
+
+==============================================================================
+							*riscos-gui*
+4. Desktop use
+
+Limitations:
+
+- Left scrollbars don't work properly (right and bottom are fine).
+- Doesn't increase scroll speed if it gets behind.
+
+You can resize the window by dragging the lower-right corner, even though
+there is no icon shown there.
+
+You can use the --rows and --columns arguments to specify the initial size of
+the Vim window, like this: >
+
+  *Vi -g --rows 20 --columns 80
+
+The global clipboard is supported, so you can select some text and then
+paste it directly into another application (provided it supports the
+clipboard too).
+
+Clicking Menu now opens a menu like a normal RISC OS program.  Hold down Shift
+when clicking Menu to paste (from the global clipboard).
+
+Dragging a file to the window replaces the CURRENT buffer (the one with the
+cursor, NOT the one you dragged to) with the file.
+
+Dragging with Ctrl held down causes a new Vim window to be opened for the
+file (see |:sp|).
+
+Dragging a file in with Shift held down in insert mode inserts the pathname of
+the file.
+
+:browse :w opens a standard RISC OS save box.
+:browse :e opens a directory viewer.
+
+For fonts, you have the choice of the system font, an outline font, the system
+font via ZapRedraw and any of the Zap fonts via ZapRedraw: >
+
+  :set guifont=
+<			To use the system font via the VDU drivers.  Supports
+			bold and underline.
+>
+  :set guifont=Corpus.Medium
+<			Use the named outline font.  You can use any font, but
+			only monospaced ones like Corpus look right.
+>
+  :set guifont=Corpus.Medium:w8:h12:b:i
+<			As before, but with size of 8 point by 12 point, and
+			in bold italic.
+			If only one of width and height is given then that
+			value is used for both.  If neither is given then 10
+			point is used.
+
+Thanks to John Kortink, Vim can use the ZapRedraw module.  Start the font name
+with '!' (or '!!' for double height), like this: >
+
+  :set guifont=!!
+<			Use the system font, but via ZapRedraw.  This gives a
+			faster redraw on StrongARM processors, but you can't
+			get bold or italic text.  Double height.
+>
+  :set guifont=!script
+<			Uses the named Zap font (a directory in VimFont$Path).
+			The redraw is the same speed as for '!!', but you get
+			a nicer looking font.
+			Only the "man+" and "script" fonts are supplied
+			currently, but you can use any of the Zap fonts if
+			they are in VimFont$Path.
+			Vim will try to load font files '0', 'B', 'I' and 'IB'
+			from the named directory.  Only '0' (normal style) MUST
+			be present.  Link files are not currently supported.
+
+Note that when using ZapRedraw the edit bar is drawn in front of the character
+you are on rather than behind it.  Also redraw is incorrect for screen modes
+with eigen values of 0.  If the font includes control characters then you can
+get Vim to display them by changing the 'isprint' option.
+
+If you find the scrolling is too slow on your machine, try experimenting
+with the 'scrolljump' and 'ttyscroll' options.
+
+In particular, StrongARM users may find that: >
+
+  :set ttyscroll=0
+
+makes scrolling faster in high-color modes.
+
+=============================================================================
+							*riscos-remote*
+5. Remote use (telnet)
+
+I have included a built-in termcap entry, but you can edit the termcap file to
+allow other codes to be used if you want to use Vim from a remote terminal.
+
+Although I do not have an internet connection to my Acorn, I have managed to
+run Vim in a FreeTerm window using the loopback connection.
+
+It seems to work pretty well now, using '*vi -T ansi'.
+
+==============================================================================
+							*riscos-temp-files*
+6. Temporary files
+
+If Vim crashes then the swap and backup files (if any) will be in the
+directories set with the 'directory' and 'bdir' options.  By default the swap
+files are in <Wimp$ScrapDir> (i.e. inside !Scrap) and backups are in the
+directory you were saving to.  Vim will allow you to try and recover the file
+when you next try to edit it.
+
+To see a list of swap files, press <F12> and type `*vi -r'.
+
+Vim no longer brings up ATTENTION warnings if you try to edit two files with
+the same name in different directories.
+
+However, it also no longer warns if you try to edit the same file twice (with
+two copies of Vim), though you will still be warned when you save that the
+datestamp has changed.
+
+==============================================================================
+							*riscos-interrupt*
+7. Interrupting
+
+To break out of a looping macro, or similar, hold down Escape in the
+command-line version, or press CTRL-C in the GUI version.
+
+==============================================================================
+							*riscos-memory*
+8. Memory usage
+
+Vim will use dynamic areas on RISC OS 3.5 or later.  If you can use them on
+older machines then edit the !RunTxt and GVim files.  I don't know what UnixLib
+does by default on these machines so I'm playing safe.
+
+It doesn't work at all well without dynamic areas, since it can't change its
+memory allocation once running.  Hence you should edit `!Vim.GVim' and
+`!Vim.!RunTxt' to choose the best size for you.  You probably need at least
+about 1400K.
+
+==============================================================================
+							*riscos-filetypes*
+9. Filetypes
+
+You can now specify that autocommands are only executed for files of certain
+types.  The filetype is given in the form &xxx, when xxx is the filetype.
+
+Filetypes must be specified by number (e.g. &fff for Text).
+
+The system has changed from version 5.3.  The new sequence of events is:
+
+- A file is loaded. |'osfiletype'| is set to the RISC OS filetype.
+- Based on the filetype and pathname, Vim will try to set |'filetype'| to the
+  Vim-type of the file.
+- Setting this option may load syntax files and perform other actions.
+- Saving the file will give it a filetype of |'osfiletype'|.
+
+Some examples may make this clearer:
+
+  Kind of file loaded	osfiletype	filetype ~
+  C code 'c.hellow'	Text (&fff)	C
+  LaTeX document	LaTeX (&2a8)	TeX
+  Draw document		DrawFile (&aff)	(not changed)
+
+==============================================================================
+							*riscos-shell*
+10. The shell
+
+- Bangs (!s) are only replaced if they are followed by a space or end-of-line,
+  since many pathnames contain them.
+
+- You can prefix the command with '~', which stops any output from being
+  displayed.  This also means that you don't have to press <Enter> afterwards,
+  and stops the screen from being redrawn. {only in the GUI version}
+
+==============================================================================
+							*riscos-porting*
+11. Porting new releases to RISC OS
+
+Downloading everything you need:
+
+- Get the latest source distribution (see www.vim.org)
+- Get the runtime environment files (e.g. these help files)
+- Get the `extra' archive (contains the RISC OS specific bits)
+- Get the RISC OS binary distribution (if possible)
+
+
+Unarchiving:
+
+- Create a raFS disk and put the archives on it
+- Un-gzip them
+- Un-tar them   (*tar xELf 50 archive/tar)
+
+
+Recompiling the sources:
+
+- Create c, s, and h directories.
+- Put all the header files in 'h'.	     \
+- Put all the C files in `c'.		     | And lose the extensions
+- Put the assembler file (`swis/s') in 's'.  /
+- Rename all the files in `proto' to `h', like this:
+    raFS::VimSrc.source.proto.file/pro
+	  becomes
+    raFS::VimSrc.source.h.file_pro
+- In the files `h.proto' and `c.termlib', search and replace
+    .pro"
+       with
+    _pro.h"
+- Create a simple Makefile if desired and do '*make -k'.
+  Use 'CC = gcc -DRISCOS -DUSE_GUI -O2 -x c' in the Makefile.
+- Save the binary as !Vim.Vim in the binary distribution.
+
+
+Updating the run-time environment:
+
+- Replace old or missing files inside !Vim.Resources with the
+  new files.
+- Remove files in `doc' not ending in `/txt', except for `tags'.
+- Lose the extensions from the files in `doc'.
+- Edit the `doc.tags' file.  Remove extensions from the second column: >
+	:%s/^\(.[^\t]*\t.*\)\.txt\t/\1\t/
+- Remove extensions from the syntax files.  Split them into two directories
+  to avoid the 77 entry limit on old ADFS filesystems.
+- Edit `Vim:FileType' to match `*.c.*' as well as `*/c' and so on.
+  Add filetype checking too.
+- Edit `Vim:Menu' and remove all the keys from the menus: >
+	:%s/<Tab>[^ \t]*//
+<
+ vim:tw=78:ts=8:ft=help:norl:
--- /dev/null
+++ b/lib/vimfiles/doc/os_unix.txt
@@ -1,0 +1,60 @@
+*os_unix.txt*   For Vim version 7.1.  Last change: 2005 Mar 29
+
+
+		  VIM REFERENCE MANUAL    by Bram Moolenaar
+
+
+							*unix* *Unix*
+This file contains the particularities for the Unix version of Vim.
+
+For compiling Vim on Unix see "INSTALL" and "Makefile" in the src directory.
+
+The default help file name is "/usr/local/lib/vim/help.txt"
+The files "$HOME/.vimrc" and "$HOME/.exrc" are used instead of "s:.vimrc" and
+"s:.exrc".  Additionally "/usr/local/etc/vimrc" is used first.
+If "/usr/local/share" exists it is used instead of "/usr/local/lib".
+
+Temporary files (for filtering) are put in "/tmp".  If you want to place them
+somewhere else, set the environment variable $TMPDIR to the directory you
+prefer.
+
+With wildcard expansion you can use '~' (home directory) and '$'
+(environment variable).
+
+							*fork* *spoon*
+For executing external commands fork()/exec() is used when possible, otherwise
+system() is used, which is a bit slower.  The output of ":version" includes
+|+fork| when fork()/exec() is used, |+system()| when system() is used.  This
+can be changed at compile time.
+(For forking of the GUI version see |gui-fork|.)
+
+Because terminal updating under Unix is often slow (e.g. serial line
+terminal, shell window in suntools), the 'showcmd' and 'ruler' options
+are default off.  If you have a fast terminal, try setting them on.  You might
+also want to set 'ttyfast'.
+
+When using Vim in an xterm the mouse clicks can be used by Vim by setting
+'mouse' to "a".  If there is access to an X-server gui style copy/paste will
+be used and visual feedback will be provided while dragging with the mouse.
+If you then still want the xterm copy/paste with the mouse, press the shift
+key when using the mouse.  See |mouse-using|.  Visual feedback while dragging
+can also be achieved via the 'ttymouse' option if your xterm is new enough.
+
+							*terminal-colors*
+To use colors in Vim you can use the following example (if your terminal
+supports colors, but "T_Co" is empty or zero): >
+   :set t_me=^[[0;1;36m     " normal mode (undoes t_mr and t_md)
+   :set t_mr=^[[0;1;33;44m  " reverse (invert) mode
+   :set t_md=^[[1;33;41m    " bold mode
+   :set t_se=^[[1;36;40m    " standout end
+   :set t_so=^[[1;32;45m    " standout mode
+   :set t_ue=^[[0;1;36m     " underline end
+   :set t_us=^[[1;32m       " underline mode start
+[the ^[ is an <Esc>, type CTRL-V <Esc> to enter it]
+
+For real color terminals the ":highlight" command can be used.
+
+The file "tools/vim132" is a shell script that can be used to put Vim in 132
+column mode on a vt100 and lookalikes.
+
+ vim:tw=78:ts=8:ft=help:norl:
--- /dev/null
+++ b/lib/vimfiles/doc/os_vms.txt
@@ -1,0 +1,816 @@
+*os_vms.txt*    For Vim version 7.1.  Last change: 2006 Nov 18
+
+
+		  VIM REFERENCE MANUAL
+
+
+							*VMS* *vms*
+This file contains the particularities for the VMS version of Vim.
+You can reach this information file by typing :help VMS in Vim command
+prompt.
+
+ 1. Getting started	|vms-started|
+ 2. Download files	|vms-download|
+ 3. Compiling		|vms-compiling|
+ 4. Problems		|vms-problems|
+ 5. Deploy		|vms-deploy|
+ 6. Practical usage	|vms-usage|
+ 7. GUI mode questions	|vms-gui|
+ 8. Useful notes	|vms-notes|
+ 9. VMS related changes	|vms-changes|
+10. Authors		|vms-authors|
+
+==============================================================================
+
+1. Getting started					*vms-started*
+
+Vim (Vi IMproved) is a vi-compatible text editor that runs on nearly every
+operating system known to humanity.  Now use Vim on OpenVMS too, in character
+or X/Motif environment.  It is fully featured and absolutely compatible with
+Vim on other operating systems.
+
+==============================================================================
+
+2. Download files					*vms-download*
+
+You can download the Vim source code by ftp from the official Vim site:
+	ftp://ftp.vim.org/pub/vim/
+Or use one of the mirrors:
+	ftp://ftp.vim.org/pub/vim/MIRRORS
+
+You will need both the Unix and Extra archives to build vim.exe for VMS.
+For using Vim's full power you will need the runtime files as well.
+
+You can download precompiled executables from:
+	http://www.polarhome.com/vim/
+	ftp://ftp.polarhome.com/pub/vim/
+
+To use the precompiled binary version, you need one of these archives:
+
+  vim-XX-exe-ia64-gui.zip       IA64 GUI/Motif executables
+  vim-XX-exe-ia64-gtk.zip       IA64 GUI/GTK executables
+  vim-XX-exe-ia64-term.zip      IA64 console executables
+  vim-XX-exe-axp-gui.zip	Alpha GUI/Motif executables
+  vim-XX-exe-axp-gtk.zip	Alpha GUI/GTK executables
+  vim-XX-exe-axp-term.zip       Alpha console executables
+  vim-XX-exe-vax-gui.zip	VAX GUI executables
+  vim-XX-exe-vax-term.zip       VAX console executables
+
+and of course (optional)
+  vim-XX-runtime.zip		runtime files
+
+The binary archives contain: vim.exe, ctags.exe, xxd.exe files.
+
+For GTK executables you will need GTKLIB that is available for
+Alpha and IA64 platform.
+
+==============================================================================
+
+3. Compiling						*vms-compiling*
+
+See the file [.SRC]INSTALLVMS.TXT.
+
+==============================================================================
+
+4. Problems						*vms-problems*
+
+The code has been tested under Open VMS 6.2 - 8.2 on Alpha, VAX and IA64
+platforms with the DEC C compiler.  It should work without bigger problems.
+If your system does not have some include libraries you can tune up in
+OS_VMS_CONF.H file.
+
+If you decided to build Vim with +perl, +python, etc. options, first you need
+to download OpenVMS distributions of Perl and Python.  Build and deploy the
+libraries and change adequate lines in MAKE_VMS.MMS file.  There should not be
+a problem from Vim side.
+
+Also GTK, XPM library paths should be configured in MAKE_VMS.MMS
+
+Note: Under VAX it should work with the DEC C compiler without problems.  The
+VAX C compiler is not fully ANSI C compatible in pre-processor directives
+semantics, therefore you have to use a converter program what will do the lion
+part of the job.  For detailed instructions read file INSTALLvms.txt
+
+MMS_VIM.EXE is build together with VIM.EXE, but for XD.EXE you should
+change to subdirectory and build it separately.
+
+CTAGS is not part of the Vim source distribution anymore, however the OpenVMS
+specific source might contain CTAGS source files as described above.
+You can find more information about CTAGS on VMS at
+http://www.polarhome.com/ctags/
+
+Advanced users may try some acrobatics in FEATURE.H file also.
+
+It is possible to compile with +xfontset +xim options too, but then you have
+to set up GUI fonts etc. correctly.  See :help xim from Vim command prompt.
+
+You may want to use GUI with GTK icons, then you have to download and install
+GTK for OpenVMS or at least runtime shareable images - LIBGTK from
+polarhome.com
+
+For more advanced questions, please send your problem to Vim on VMS mailing
+list <vim-vms@polarhome.com>
+More about the vim-vms list can be found at:
+http://www.polarhome.com/mailman/listinfo/vim-vms
+
+==============================================================================
+
+5. Deploy						*vms-deploy*
+
+Vim uses a special directory structure to hold the document and runtime files:
+
+   vim (or wherever)
+    |- tmp
+    |- vim57
+    |----- doc
+    |----- syntax
+    |- vim62
+    |----- doc
+    |----- syntax
+    |- vim64
+    |----- doc
+    |----- syntax
+    vimrc    (system rc files)
+    gvimrc
+
+Use: >
+
+	define/nolog VIM	device:[path.vim]
+	define/nolog VIMRUNTIME device:[path.vim.vim60]
+	define/nolog TMP	device:[path.tmp]
+
+to get vim.exe to find its document, filetype, and syntax files, and to
+specify a directory where temporary files will be located.  Copy the "runtime"
+subdirectory of the vim distribution to vimruntime.
+
+Logicals $VIMRUNTIME and $TMP are optional.
+
+If $VIMRUNTIME is not set, Vim will guess and try to set up automatically.
+Read more about it at :help runtime
+
+If $TMP is not set, you will not be able to use some functions as CTAGS,
+XXD, printing etc. that use temporary directory for normal operation.
+The $TMP directory should be readable and writable by the user(s).
+The easiest way to set up $TMP is to define a logical: >
+
+	define/nolog TMP SYS$SCRATCH
+or as: >
+	define/nolog TMP SYS$LOGIN
+
+==============================================================================
+
+6. Practical usage					*vms-usage*
+
+Usually, you want to run just one version of Vim on your system, therefore
+it is enough to dedicate one directory for Vim.
+Copy the whole Vim runtime directory structure to the deployment position.
+Add the following lines to your LOGIN.COM (in SYS$LOGIN directory).
+Set up the logical $VIM as: >
+
+	$ define VIM device:<path>
+
+Set up some symbols: >
+
+	$ ! vi starts Vim in chr. mode.
+	$ vi*m  :== mcr VIM:VIM.EXE
+
+	$ !gvi starts Vim in GUI mode.
+	$ gv*im :== spawn/nowait mcr VIM:VIM.EXE -g
+
+Please, check the notes for customization and configuration of symbols.
+
+You may want to create .vimrc and .gvimrc files in your home directory
+(SYS$LOGIN) to overwrite default settings.
+
+The easiest way is just rename example files.  You may leave the menu file
+(MENU.VIM) and files vimrc and gvimrc in the original $VIM directory.  It will
+be default setup for all users, and for users it is enough just to have their
+own additions or resetting in their home directory in files .vimrc and .gvimrc.
+It should work without problems.
+
+Note: Remember, system rc files (default for all users) don't have a leading
+".".  So, system rc files are: >
+
+	$VIM:vimrc
+	$VIM:gvimrc
+	$VIM:menu.vim
+
+and user customized rc files are: >
+
+	sys$login:.vimrc
+	sys$login:.gvimrc
+
+You can check that everything is on the right place with the :version command.
+
+Example LOGIN.COM: >
+
+	$ define/nolog VIM RF10:[UTIL.VIM]
+	$ vi*m :== mcr VIM:VIM.EXE
+	$ gv*im:== spawn/nowait/input=NLA0 mcr VIM:VIM.EXE -g -GEOMETRY 80x40
+	$ set disp/create/node=192.168.5.223/trans=tcpip
+
+Note: This set-up should be enough, if you are working on standalone server or
+clustered environment, but if you want to use Vim as internode editor in
+DECNET environment, it will satisfy as well.
+You just have to define the "whole" path: >
+
+	$ define VIM "<server_name>[""user password""]::device:<path>"
+	$ vi*m :== "mcr VIM:VIM.EXE"
+
+as for example: >
+
+	$ define VIM "PLUTO::RF10:[UTIL.VIM]"
+	$ define VIM "PLUTO""ZAY mypass""::RF10:[UTIL.VIM]" ! if passwd required
+
+You can also use the $VIMRUNTIME logical to point to the proper version of Vim
+if you have installed more versions at the same time.  If $VIMRUNTIME is not
+defined Vim will borrow its value from the $VIM logical.  You can find more
+information about the $VIMRUNTIME logical by typing :help runtime as a Vim
+command.
+
+System administrators might want to set up a system wide Vim installation,
+then add to the SYS$STARTUP:SYLOGICALS.COM >
+
+	$ define/nolog/sys VIM device:<path>
+	$ define/nolog/sys TMP SYS$SCRATCH
+
+and to the SYS$STARTUP:SYLOGIN.COM >
+
+	$ vi*m :== mcr VIM:VIM.EXE
+	$ gv*im:== spawn/nowait/input=NLA0 mcr VIM:VIM.EXE -g -GEOMETRY 80x40
+
+
+It will set up a normal Vim work environment for every user on the system.
+
+IMPORTANT: Vim on OpenVMS (and on other case insensitive system) command line
+parameters are assumed to be lowercase. In order to indicate that a command
+line parameter is uppercase "/" sign must be used.
+
+Examples:
+  >
+	vim -R  filename  ! means: -r List swap files and exit
+	vim -/r filename  ! means: -R Readonly mode (like "view")
+	vim -u	<vimrc>   ! means: -u Use <vimrc> instead of any .vimrc
+	vim -/u <gvimrc>  ! means: -U Use <gvimrc> instead of any .gvimrc
+
+==============================================================================
+
+7. GUI mode questions					*vms-gui*
+
+OpenVMS is a real mainframe OS, therefore even if it has a GUI console, most
+of the users do not use a native X/Window environment during normal operation.
+It is not possible to start Vim in GUI mode "just like that".  But anyhow it
+is not too complicated either.
+
+First of all: you will need an executable that is built with the GUI enabled.
+
+Second: you need to have installed DECW/Motif on your VMS server, otherwise
+you will get errors that some shareable libraries are missing.
+
+Third: If you choose to run Vim with extra features such as GUI/GTK then you
+need a GTK installation too or at least a GTK runtime environment (LIBGTK
+can be downloaded from http://www.polarhome.com/vim/).
+
+1) If you are working on the VMS X/Motif console:
+   Start Vim with the command: >
+
+	$ mc device:<path>VIM.EXE -g
+<
+   or type :gui as a command to the Vim command prompt.  For more info :help
+   gui
+
+2) If you are working on some other X/Window environment like Unix or a remote
+   X VMS console.  Set up display to your host with: >
+
+	$ set disp/create/node=<your IP address>/trans=<transport-name>
+<
+   and start Vim as in point 1.  You can find more help in VMS documentation or
+   type: help set disp in VMS prompt.
+   Examples: >
+
+	$ set disp/create/node=192.168.5.159		 ! default trans is DECnet
+	$ set disp/create/node=192.168.5.159/trans=tcpip ! TCP/IP network
+	$ set disp/create/node=192.168.5.159/trans=local ! display on the same node
+
+Note: you should define just one of these.
+For more information type $help set disp in VMS prompt.
+
+3) Another elegant solution is XDM if you have installed on OpenVMS box.
+   It is possible to work from XDM client as from GUI console.
+
+4) If you are working on MS-Windows or some other non X/Window environment
+   you need to set up one X server and run Vim as in point 2.
+   For MS-Windows there are available free X servers as MIX , Omni X etc.,
+   as well as excellent commercial products as eXcursion or ReflectionX with
+   built-in DEC support.
+
+Please note, that executables without GUI are slightly faster during startup
+then with enabled GUI in character mode. Therefore, if you do not use GUI
+features, it is worth to choose non GUI executables.
+
+==============================================================================
+
+8. Useful notes						*vms-notes*
+
+8.1 backspace/delete
+8.2 Filters
+8.3 VMS file version numbers
+8.4 Directory conversion
+8.5 Remote host invocation
+8.6 Terminal problems
+8.7 Hex-editing and other external tools
+8.8 Sourcing vimrc and gvimrc
+8.9 Printing from Vim
+8.10 Setting up the symbols
+8.11 diff and other GNU programs
+8.12 diff-mode
+8.13 Allow '$' in C keywords
+8.14 VIMTUTOR for beginners
+
+8.1 backspace/delete
+
+There are backspace/delete key inconsistencies with VMS.
+:fixdel doesn't do the trick, but the solution is: >
+
+	:inoremap ^? ^H		" for terminal mode
+	:inoremap <Del> ^H	" for gui mode
+
+Read more in ch: 8.6 (Terminal problems).
+(Bruce Hunsaker <BNHunsaker@chq.byu.edu> Vim 5.3)
+
+
+8.2 Filters
+
+Vim supports filters, i.e., if you have a sort program that can handle
+input/output redirection like Unix (<infile >outfile), you could use >
+
+	:map \s 0!'aqsort<CR>
+
+(Charles E. Campbell, Jr. <cec@gryphon.gsfc.nasa.gov> Vim 5.4)
+
+
+8.3 VMS file version numbers
+
+Vim is saving files into a new file with the next higher file version
+number, try these settings. >
+
+	:set nobackup	     " does not create *.*_ backup files
+	:set nowritebackup   " does not have any purpose on VMS.  It's the
+			     " default.
+
+Recovery is working perfect as well from the default swap file.
+Read more with :help swapfile
+
+(Claude Marinier <ClaudeMarinier@xwavesolutions.com> Vim 5.5, Zoltan Arpadffy
+Vim 5.6)
+
+
+8.4 Directory conversion
+
+Vim will internally convert any unix-style paths and even mixed unix/VMS
+paths into VMS style paths.  Some typical conversions resemble:
+
+	/abc/def/ghi		-> abc:[def]ghi.
+	/abc/def/ghi.j		-> abc:[def]ghi.j
+	/abc/def/ghi.j;2	-> abc:[def]ghi.j;2
+	/abc/def/ghi/jkl/mno	-> abc:[def.ghi.jkl]mno.
+	abc:[def.ghi]jkl/mno	-> abc:[def.ghi.jkl]mno.
+	  ./			-> current directory
+	  ../			-> relative parent directory
+	  [.def.ghi]		-> relative child directory
+	   ./def/ghi		-> relative child directory
+
+Note: You may use <,> brackets as well (device:<path>file.ext;version) as
+rf10:<user.zay.work>test.c;1
+
+(David Elins <delins@foliage.com>, Jerome Lauret
+<JLAURET@mail.chem.sunysb.edu> Vim 5.6 )
+
+
+8.5 Remote host invocation
+
+It is possible to use Vim as an internode editor.
+1. Edit some file from remote node: >
+
+	vi "<server>""username passwd""::<device>:<path><filename>;<version>"
+
+example: >
+	vi "pluto""zay passwd""::RF10:<USER.ZAY.WORK>TEST.C;1"
+
+Note: syntax is very important, otherwise VMS will recognize more parameters
+instead of one (resulting with: file not found)
+
+2.  Set up Vim as your internode editor.  If Vim is not installed on your
+host, just set up your IP address, the full Vim path including the server name
+and run the command procedure below: >
+
+	$ if (p1 .eqs. "") .OR. (p2 .eqs. "") then goto usage
+	$ set disp/create/node=<your_IP_here>/trans=tcpip
+	$ define "VIM "<vim_server>""''p1' ''p2'""::<device>:<vim_path>"
+	$  vi*m :== "mcr VIM:VIM.EXE"
+	$ gv*im :== "spawn/nowait mcr VIM:VIM.EXE -g"
+	$ goto end
+	$ usage:
+	$ write sys$output " Please enter username and password as a parameter."
+	$ write sys$output " Example: @SETVIM.COM username passwd"
+	$ end:
+
+Note: Never use it in a clustered environment (you do not need it), loading
+could be very-very slow, but even faster then a local Emacs. :-)
+
+(Zoltan Arpadffy, Vim 5.6)
+
+
+8.6 Terminal problems
+
+If your terminal name is not known to Vim and it is trying to find the default
+one you will get the following message during start-up:
+---
+Terminal entry not found in termcap
+'unknown-terminal' not known.  Available built-in terminals are:
+    builtin_gui
+    builtin_riscos
+    builtin_amiga
+    builtin_beos-ansi
+    builtin_ansi
+    builtin_vt320
+    builtin_vt52
+    builtin_pcansi
+    builtin_win32
+    builtin_xterm
+    builtin_iris-ansi
+    builtin_debug
+    builtin_dumb
+defaulting to 'vt320'
+---
+The solution is to define default terminal name: >
+
+	$ ! unknown terminal name.  Let us use vt320 or ansi instead.
+	$ ! Note: it's case sensitive
+	$ define term "vt320"
+
+Terminals from VT100 to VT320 (as V300, VT220, VT200 ) do not need any extra
+keyboard mappings.  They should work perfect as they are, including arrows,
+Ins, Del buttons etc., except Backspace in GUI mode.  To solve it, add to
+.gvimrc: >
+
+	inoremap <Del> <BS>
+
+Vim will also recognize that they are fast terminals.
+
+If you have some annoying line jumping on the screen between windows add to
+your .vimrc file: >
+
+	set ttyfast	" set fast terminal
+
+Note: if you're using Vim on remote host or through very slow connection, it's
+recommended to avoid fast terminal option with: >
+
+	set nottyfast   " set terminal to slow mode
+
+(Zoltan Arpadffy, Vim 5.6)
+
+
+8.7 Hex-editing and other external tools
+
+A very important difference between OpenVMS and other systems is that VMS uses
+special commands to execute executables: >
+
+	RUN <path>filename
+	MCR <path>filename <parameters>
+
+OpenVMS users always have to be aware that the Vim command :! "just" drop them
+to DCL prompt.  This feature is possible to use without any problem with all
+DCL commands, but if we want to execute some program as XXD, CTAGS, JTAGS etc.
+we're running into trouble if we follow the Vim documentation (see: help
+xxd).
+
+Solution: Execute with the MC command and add the full path to the executable.
+Example: Instead of :%!xxd command use: >
+
+	:%!mc vim:xxd
+
+... or in general: >
+	:!mc <path>filename <parameters>
+
+Note: You can use XXD and CTAGS from GUI menu.
+
+To customize ctags it is possible to define the logical $CTAGS with standard
+parameters as: >
+
+	define/nolog CTAGS "--totals -o sys$login:tags"
+
+For additional information, please read :help tagsearch and CTAGS
+documentation at http://ctags.sourceforge.net/ctags.html.
+
+(Zoltan Arpadffy, Vim 5.6-70)
+
+
+8.8 Sourcing vimrc and gvimrc
+
+If you want to use your .vimrc and .gvimrc from other platforms (e.g. Windows)
+you can get in trouble if you ftp that file(s): VMS has different end-of-line
+indication.
+The symptom is that Vim is not sourcing your .vimrc/.gvimrc, even if you say:
+>
+	:so sys$login:.vimrc
+
+One trick is to compress (e.g. zip) the files on the other platform and
+uncompress it on VMS; if you have the same symptom, try to create the files
+with copy-paste (for this you need both op. systems reachable from one
+machine, e.g. an Xterm on Windows or telnet to Windows from VMS).
+
+(Sandor Kopanyi, <sandor.kopanyi@mailbox.hu> Vim 6.0a)
+
+
+8.9 Printing from Vim
+
+To be able to print from Vim (running in GUI mode) under VMS you have to set
+up $TMP logical which should point to some temporary directory and logical
+SYS$PRINT to your default print queue.
+Example: >
+
+	$define SYS$PRINT HP5ANSI
+
+You can print out whole buffer or just the marked area.
+More info under :help hardcopy
+
+(Zoltan Arpadffy, Vim 6.0c)
+
+
+8.10 Setting up the symbols
+
+When I use GVIM this way and press CTRL-Y in the parent terminal, gvim exits.
+I now use a different symbol that seems to work OK and fixes the problem.
+I suggest this instead: >
+
+	$ GV*IM:==SPAWN/NOWAIT/INPUT=NLA0: MCR VIM:VIM.EXE -G -GEOMETRY 80X40
+
+The /INPUT=NLA0: separates the standard input of the gvim process from the
+parent terminal, to block signals from the parent window.
+Without the -GEOMETRY, the GVIM window size will be minimal and the menu
+will be confused after a window-resize.
+
+(Carlo Mekenkamp, Coen Engelbarts, Vim 6.0ac)
+
+
+8.11 diff and other GNU programs
+
+From 6.0 diff functionality has been implemented, but OpenVMS does not use
+GNU/Unix like diff therefore built in diff does not work.
+There is a simple solution to solve this anomaly.  Install a Unix like diff
+and Vim will work perfect in diff mode too.  You just have to redefine your
+diff program as: >
+
+	define /nolog diff <GNU_PATH>diff.exe
+
+Another, more sophisticated solution is described below (8.12 diff-mode)
+There are some other programs as patch, make etc that may cause same problems.
+At www.polarhome.com is possible to download an GNU package for Alpha and VAX
+boxes that is meant to solve GNU problems on OpenVMS.
+( Zoltan Arpadffy, Vim 6.1)
+
+
+8.12 diff-mode
+
+Vim 6.0 and higher supports vim diff-mode (See |new-diff-mode|, |diff-mode|
+and |08.7|).  This uses the external program 'diff' and expects a Unix-like
+output format from diff.  The standard VMS diff has a different output
+format.  To use vim on VMS in diff-mode, you need to:
+    1 Install a Unix-like diff program, e.g. GNU diff
+    2 Tell vim to use the Unix-like diff for diff-mode.
+
+You can download GNU diff from the VIM-VMS website, it is one of the GNU
+tools in http://www.polarhome.com/vim/files/gnu_tools.zip.  I suggest to
+unpack it in a separate directory "GNU" and create a logical GNU: that
+points to that directory, e.g: >
+
+   DEFINE GNU    <DISK>:[<DIRECTORY>.BIN.GNU]
+
+You may also want to define a symbol GDIFF, to use the GNU diff from the DCL
+prompt: >
+
+   GDIFF :==     $GNU:DIFF.EXE
+
+Now you need to tell vim to use the new diff program.  Take the example
+settings from |diff-diffexpr| and change the call to the external diff
+program to the new diff on VMS.  Add this to your .vimrc file: >
+
+     " Set up vimdiff options
+       if v:version >= 600
+	" Use GNU diff on VMS
+	set diffexpr=MyDiff()
+	function MyDiff()
+	   let opt = ""
+	   if &diffopt =~ "icase"
+	     let opt = opt . "-i "
+	   endif
+	   if &diffopt =~ "iwhite"
+	     let opt = opt . "-b "
+	   endif
+	   silent execute "!mc GNU:diff.exe -a " . opt . v:fname_in . " " .  v:fname_new .
+		\  " > " . v:fname_out
+	endfunction
+      endif
+
+You can now use vim in diff-mode, e.g. to compare two files in read-only
+mode: >
+
+    $ VIM -D/R <FILE1> <FILE2>
+
+You can also define new symbols for vimdiff, e.g.: >
+
+    $ VIMDIFF     :== 'VIM' -D/R
+    $ GVIMDIFF    :== 'GVIM' -D/R
+
+You can now compare files in 4 ways: >
+
+    1. VMS  diff:  $ DIFF     <FILE1> <FILE2>
+    2. GNU  diff:  $ GDIFF    <FILE1> <FILE2>
+    3. VIM  diff:  $ VIMDIFF  <FILE1> <FILE2>
+    4. GVIM diff:  $ GVIMDIFF <FILE1> <FILE2>
+
+( Coen Engelbarts, Vim 6.1)
+
+
+8.13 Allow '$' in C keywords
+
+DEC C uses many identifiers with '$' in them.  This is not allowed in ANSI C,
+and vim recognises the '$' as the end of the identifier.  You can change this
+with the |iskeyword|command.
+Add this command to your .vimrc file: >
+
+    autocmd FileType c,cpp,cs  set iskeyword+=$
+
+You can also create the file(s) $VIM/FTPLUGIN/C.VIM (and/or CPP.VIM and
+CS.VIM) and add this command: >
+
+	set iskeyword+=$
+
+Now word-based commands, e.g. the '*'-search-command and the CTRL-]
+tag-lookup, work on the whole identifier.  (Ctags on VMS also supports '$' in
+C keywords since ctags version 5.1.)
+
+( Coen Engelbarts, Vim 6.1)
+
+8.14 VIMTUTOR for beginners
+
+It exits VIMTUTOR.COM DCL script that can help Vim beginners to learn/make
+first steps with Vim on OpenVMS.  Depending of binary distribution you may
+start it with: >
+
+	@vim:vimtutor
+
+(Thomas.R.Wyant III, Vim 6.1)
+
+==============================================================================
+
+9. VMS related changes					*vms-changes*
+
+Version 7
+- Improved low level char input (affects just console mode)
+
+Version 6.4 (2005 Oct 15)
+- GTKLIB and Vim build on IA64
+- colors in terminal mode
+- syntax highlighting in terminal mode
+- write problem fixed (extra CR)
+- ESC and ESC sequence recognition in terminal mode
+- make file changed to support new MMS version
+- env variable expansion in path corrected
+- printing problems corrected
+- help text added for case insensitive arguments
+
+Version 6.3 (2004 May 10)
+- Improved vms_read function
+- CTAGS v5.5.4 included
+- Documentation corrected and updated
+
+Version 6.2 (2003 May 7)
+- Corrected VMS system call results
+- Low level character input is rewritten
+- Correction in tag and quickfix handling
+- First GTK build
+- Make file changes
+    - GTK feature added
+    - Define for OLD_VMS
+    - OpenVMS version 6.2 or older
+- Documentation updated with GTK features
+- CTAGS v5.5 included
+- VMS VIM tutor created
+
+Version 6.1 (2002 Mar 25)
+- TCL init_tcl() problem fixed
+- CTAGS v5.4 included
+- GNU tools binaries for OpenVMS
+- Make file changes
+    - PERL, PYTHON and TCL support improved
+    - InstallVMS.txt has a detailed description HOWTO build
+- VMS/Unix file handling rewritten
+- Minor casting and bug fixes
+
+Version 6.0 (2001 Sep 28)
+- Unix and VMS code has been merged
+	- separated "really" VMS related code
+	- included all possible Unix functionality
+	- simplified or deleted the configuration files
+	- makefile MAKE_VMS.MMS reviewed
+- menu changes (fixed printing, CTAGS and XXD usage)
+- fixed variable RMS record format handling anomaly
+- corrected syntax, ftplugin etc files load
+- changed expand_wildcards and expandpath functions to work more general
+- created OS_VMS_FILTER.COM - DECC->VAXC pre-processor directive convert
+  script.
+- Improved code's VAXC and new DECC compilers compatibility
+- changed quickfix parameters:
+	- errormessage format to suite DECC
+	- search, make and other commands to suite VMS system
+- updated and renamed MMS make files for Vim and CTAGS.
+- CTAGS has been removed from source distribution of Vim but it will remain
+  in OpenVMS binary distributions.
+- simplified build/configuration procedure
+- created INSTALLvms.txt - detailed compiling instructions under VMS.
+- updated test scripts.
+
+Version 5.8 (2001 Jun 1)
+- OS_VMS.TXT updated with new features.
+- other minor fixes.
+- documentation updated
+- this version had been tested much more than any other OpenVMS version
+  earlier
+
+Version 5.7 (2000 Jun 24)
+- New CTAGS v5.0 in distribution
+- Documentation updated
+
+Version 5.6 (2000 Jan 17)
+- VMS filename related changes:
+	- version handling (open everything, save to new version)
+	- correct file extension matching for syntax (version problem)
+	- handle <,> characters and passwords in directory definition
+	- handle internode/remote invocation and editing with passwords
+	- OpenVMS files will be treated case insensitive from now
+	- corrected response of expand("%:.") etc path related functions
+	(in one word: VMS directory handling internally)
+- version command
+	- corrected (+,-) information data
+	- added compiler and OS version
+	- added user and host information
+	- resolving $VIM and $VIMRUNTIME logicals
+- VMS port is in MAX_FEAT (maximum features) club with Unix, Win32 and OS/2.
+	- enabled farsi, rightleft etc. features
+	- undo level raised up to 1000
+- Updated OS_VMS.MMS file.
+	- maximum features ON is default
+	- Vim is compilable with +perl, +python and +tcl features.
+	- improved MMK compatibility
+- Created MAKEFILE_VMS.MMS, makefile for testing Vim during development.
+- Defined DEC terminal VT320
+	- compatibility for VT3*0, VT2*0 and VT1*0 - ANSI terminals
+	  backwards, but not VT340 and newer with colour capability.
+	- VT320 is default terminal for OpenVMS
+	- these new terminals are also fast ttys (default for OpenVMS).
+	- allowed dec_mouse ttym
+- Updated files vimrc and gvimrc with VMS specific suggestions.
+- OS_VMS.TXT updated with new features.
+
+Version 5.5 (1999 Dec 3)
+- Popup menu line crash corrected.
+- Handle full file names with version numbers.
+- Directory handling (CD command etc.)
+- Corrected file name conversion VMS to Unix and v.v.
+- Correct response of expand wildcards
+- Recovery is working from this version under VMS as well.
+- Improved terminal and signal handing.
+- Improved OS_VMS.TXT
+
+Version 5.4 (1999 Sep 9)
+- Cut and paste mismatch corrected.
+- Motif directories during open and save are corrected.
+
+Version 5.3 (1998 Oct 12)
+- Minor changes in the code
+- Standard distribution with +GUI option
+
+Version 5.1 (1998 Apr 21)
+- Syntax and DEC C changes in the code
+- Fixing problems with the /doc subdirectory
+- Improve OS_VMS.MMS
+
+Version 4.5 (1996 Dec 16)
+- First VMS port by Henk Elbers <henk@xs4all.nl>
+
+==============================================================================
+
+10. Authors						*vms-authors*
+
+OpenVMS documentation and executables are maintained by:
+Zoltan Arpadffy <arpadffy@polarhome.com>
+
+This document uses parts and remarks from earlier authors and contributors
+of OS_VMS.TXT:
+	Charles E. Campbell, Jr. <cec@gryphon.gsfc.nasa.gov>
+	Bruce Hunsaker <BNHunsaker@chq.byu.edu>
+	Sandor Kopanyi <sandor.kopanyi@mailbox.hu>
+
+ vim:tw=78:ts=8:ft=help:norl:
--- /dev/null
+++ b/lib/vimfiles/doc/os_win32.txt
@@ -1,0 +1,336 @@
+*os_win32.txt*  For Vim version 7.1.  Last change: 2007 Apr 22
+
+
+		  VIM REFERENCE MANUAL    by George Reilly
+
+
+						*win32* *Win32* *MS-Windows*
+This file documents the idiosyncrasies of the Win32 version of Vim.
+
+The Win32 version of Vim works on both Windows NT and Windows 95.  There are
+both console and GUI versions.  There is GUI version for use in the Win32s
+subsystem in Windows 3.1[1].  You can also use the 32-bit DOS version of Vim
+instead.  See |os_msdos.txt|.
+
+1. Known problems		|win32-problems|
+2. Startup			|win32-startup|
+3. Restore screen contents	|win32-restore|
+4. Using the mouse		|win32-mouse|
+5. Running under Windows 3.1	|win32-win3.1|
+6. Win32 mini FAQ		|win32-faq|
+
+Additionally, there are a number of common Win32 and DOS items:
+File locations			|dos-locations|
+Using backslashes		|dos-backslash|
+Standard mappings		|dos-standard-mappings|
+Screen output and colors	|dos-colors|
+File formats			|dos-file-formats|
+:cd command			|dos-:cd|
+Interrupting			|dos-CTRL-Break|
+Temp files			|dos-temp-files|
+Shell option default		|dos-shell|
+
+Win32 GUI			|gui-w32|
+
+Credits:
+The Win32 version was written by George V. Reilly <george@reilly.org>.
+The original Windows NT port was done by Roger Knobbe <RogerK@wonderware.com>.
+The GUI version was made by George V. Reilly and Robert Webb.
+
+For compiling see "src/INSTALL.pc".			*win32-compiling*
+
+==============================================================================
+1. Known problems				*windows95* *win32-problems*
+
+There are a few known problems with running in a console on Windows 95.  As
+far as we know, this is the same in Windows 98 and Windows ME.
+
+Comments from somebody working at Microsoft: "Win95 console support has always
+been and will always be flaky".
+1.  Dead key support doesn't work.
+2.  Resizing the window with ":set columns=nn lines=nn" works, but executing
+    external commands MAY CAUSE THE SYSTEM TO HANG OR CRASH.
+3.  Screen updating is slow, unless you change 'columns' or 'lines' to a
+    non-DOS value.  But then the second problem applies!
+
+If this bothers you, use the 32 bit MS-DOS version or the Win32 GUI version.
+
+When doing file name completion, Vim also finds matches for the short file
+name.  But Vim will still find and use the corresponding long file name.  For
+example, if you have the long file name "this_is_a_test" with the short file
+name "this_i~1", the command ":e *1" will start editing "this_is_a_test".
+
+==============================================================================
+2. Startup						*win32-startup*
+
+Current directory					*win32-curdir*
+
+If Vim is started with a single file name argument, and it has a full path
+(starts with "x:\"), Vim assumes it was started from the file explorer and
+will set the current directory to where that file is.  To avoid this when
+typing a command to start Vim, use a forward slash instead of a backslash.
+Example: >
+
+	vim c:\text\files\foo.txt
+
+Will change to the "C:\text\files" directory. >
+
+	vim c:/text\files\foo.txt
+
+Will use the current directory.
+
+
+Term option						*win32-term*
+
+The only kind of terminal type that the Win32 version of Vim understands is
+"win32", which is built-in.  If you set 'term' to anything else, you will
+probably get very strange behavior from Vim.  Therefore Vim does not obtain
+the default value of 'term' from the environment variable "TERM".
+
+$PATH							*win32-PATH*
+
+The directory of the Vim executable is appended to $PATH.  This is mostly to
+make "!xxd' work, as it is in the Tools menu.  And it also means that when
+executable() returns 1 the executable can actually be executed.
+
+==============================================================================
+3. Restore screen contents				*win32-restore*
+
+When 'restorescreen' is set (which is the default), Vim will restore the
+original contents of the console when exiting or when executing external
+commands.  If you don't want this, use ":set nors".	|'restorescreen'|
+
+==============================================================================
+4. Using the mouse					*win32-mouse*
+
+The Win32 version of Vim supports using the mouse.  If you have a two-button
+mouse, the middle button can be emulated by pressing both left and right
+buttons simultaneously - but note that in the Win32 GUI, if you have the right
+mouse button pop-up menu enabled (see 'mouse'), you should err on the side of
+pressing the left button first.				|mouse-using|
+
+When the mouse doesn't work, try disabling the "Quick Edit Mode" feature of
+the console.
+
+==============================================================================
+5. Running under Windows 3.1				*win32-win3.1*
+
+						*win32s* *windows-3.1*
+There is a special version of Gvim that runs under Windows 3.1 and 3.11.  You
+need the gvim.exe that was compiled with Visual C++ 4.1.
+
+To run the Win32 version under Windows 3.1, you need to install Win32s.  You
+might have it already from another Win32 application which you have installed.
+If Vim doesn't seem to be running properly, get the latest version: 1.30c.
+You can find it at:
+
+	http://support.microsoft.com/download/support/mslfiles/pw1118.exe
+
+(Microsoft moved it again, we don't know where it is now :-( ).
+
+The reason for having two versions of gvim.exe is that the Win32s version was
+compiled with VC++ 4.1.  This is the last version of VC++ that supports Win32s
+programs.  VC++ 5.0 is better, so that one was used for the Win32 version.
+Apart from that, there is no difference between the programs.  If you are in a
+mixed environment, you can use the gvim.exe for Win32s on both.
+
+The Win32s version works the same way as the Win32 version under 95/NT.  When
+running under Win32s the following differences apply:
+- You cannot use long file names, because Windows 3.1 doesn't support them!
+- When executing an external command, it doesn't return an exit code.  After
+  doing ":make" you have to do ":cn" yourself.
+
+==============================================================================
+6. Win32 mini FAQ					*win32-faq*
+
+Q. Why does the Win32 version of Vim update the screen so slowly on Windows 95?
+A. The support for Win32 console mode applications is very buggy in Win95.
+   For some unknown reason, the screen updates very slowly when Vim is run at
+   one of the standard resolutions (80x25, 80x43, or 80x50) and the 16-bit DOS
+   version updates the screen much more quickly than the Win32 version.
+   However, if the screen is set to some other resolution, such as by ":set
+   columns=100" or ":set lines=40", screen updating becomes about as fast as
+   it is with the 16-bit version.
+
+   WARNING: Changing 'columns' may make Windows 95 crash while updating the
+   window (complaints --> Microsoft).  Since this mostly works, this has not
+   been disabled, but be careful with changing 'columns'.
+
+   Changing the screen resolution makes updates faster, but it brings
+   additional problems.  External commands (e.g., ":!dir") can cause Vim to
+   freeze when the screen is set to a non-standard resolution, particularly
+   when 'columns' is not equal to 80.  It is not possible for Vim to reliably
+   set the screen resolution back to the value it had upon startup before
+   running external commands, so if you change the number of 'lines' or
+   'columns', be very, very careful.  In fact, Vim will not allow you to
+   execute external commands when 'columns' is not equal to 80, because it is
+   so likely to freeze up afterwards.
+
+   None of the above applies on Windows NT.  Screen updates are fast, no
+   matter how many 'lines' or 'columns' the window has, and external commands
+   do not cause Vim to freeze.
+
+Q. So if the Win32 version updates the screen so slowly on Windows 95 and the
+   16-bit DOS version updates the screen quickly, why would I want to run the
+   Win32 version?
+A. Firstly, the Win32 version isn't that slow, especially when the screen is
+   set to some non-standard number of 'lines' or 'columns'.  Secondly, the
+   16-bit DOS version has some severe limitations: It can't do big changes and
+   it doesn't know about long file names.  The Win32 version doesn't have these
+   limitations and it's faster overall (the same is true for the 32-bit DJGPP
+   DOS version of Vim).  The Win32 version is smarter about handling the
+   screen, the mouse, and the keyboard than the DJGPP version is.
+
+Q. And what about the 16-bit DOS version versus the Win32 version on NT?
+A. There are no good reasons to run the 16-bit DOS version on NT.  The Win32
+   version updates the screen just as fast as the 16-bit version does when
+   running on NT.  All of the above disadvantages apply.  Finally, DOS
+   applications can take a long time to start up and will run more slowly.  On
+   non-Intel NT platforms, the DOS version is almost unusably slow, because it
+   runs on top of an 80x86 emulator.
+
+Q. How do I change the font?
+A. In the GUI version, you can use the 'guifont' option.  Example: >
+	:set guifont=Lucida_Console:h15:cDEFAULT
+<  In the console version, you need to set the font of the console itself.
+   You cannot do this from within Vim.
+
+Q. When I change the size of the console window with ':set lines=xx' or
+   similar, the font changes! (Win95)
+A. You have the console font set to 'Auto' in Vim's (or your MS-DOS prompt's)
+   properties.  This makes W95 guess (badly!) what font is best.  Set an explicit
+   font instead.
+
+Q. Why can't I paste into Vim when running Windows 95?
+A. In the properties dialog box for the MS-DOS window, go to "MS-DOS
+   Prompt/Misc/Fast pasting" and make sure that it is NOT checked.  You should
+   also do ":set paste" in Vim to avoid unexpected effects.	|'paste'|
+
+Q. How do I type dead keys on Windows 95, in the console version?
+   (A dead key is an accent key, such as acute, grave, or umlaut, that doesn't
+   produce a character by itself, but when followed by another key, produces
+   an accented character, such as a-acute, e-grave, u-umlaut, n-tilde, and so
+   on.  Very useful for most European languages.  English-language keyboard
+   layouts don't use dead keys, as far as we know.)
+A. You don't.  The console mode input routines simply do not work correctly in
+   Windows 95, and I have not been able to work around them.  In the words
+   of a senior developer at Microsoft:
+	Win95 console support has always been and will always be flaky.
+
+	The flakiness is unavoidable because we are stuck between the world of
+	MS-DOS keyboard TSRs like KEYB (which wants to cook the data;
+	important for international) and the world of Win32.
+
+	So keys that don't "exist" in MS-DOS land (like dead keys) have a
+	very tenuous existence in Win32 console land.  Keys that act
+	differently between MS-DOS land and Win32 console land (like
+	capslock) will act flaky.
+
+	Don't even _mention_ the problems with multiple language keyboard
+	layouts...
+
+   You may be able to fashion some sort of workaround with the digraphs
+   mechanism.							|digraphs|
+
+   The best solution is to use the Win32 GUI version gvim.exe.  Alternatively,
+   you can try one of the DOS versions of Vim where dead keys reportedly do
+   work.
+
+Q. How do I type dead keys on Windows NT?
+A. Dead keys work on NT 3.51.  Just type them as you would in any other
+   application.
+   On NT 4.0, you need to make sure that the default locale (set in the
+   Keyboard part of the Control Panel) is the same as the currently active
+   locale.  Otherwise the NT code will get confused and crash!  This is a NT
+   4.0 problem, not really a Vim problem.
+
+Q. I'm using Vim to edit a symbolically linked file on a Unix NFS file server.
+   When I write the file, Vim does not "write through" the symlink.  Instead,
+   it deletes the symbolic link and creates a new file in its place.  Why?
+A. On Unix, Vim is prepared for links (symbolic or hard).  A backup copy of
+   the original file is made and then the original file is overwritten.  This
+   assures that all properties of the file remain the same.  On non-Unix
+   systems, the original file is renamed and a new file is written.  Only the
+   protection bits are set like the original file.  However, this doesn't work
+   properly when working on an NFS-mounted file system where links and other
+   things exist.  The only way to fix this in the current version is not
+   making a backup file, by ":set nobackup nowritebackup"     |'writebackup'|
+
+Q. I'm using Vim to edit a file on a Unix file server through Samba.  When I
+   write the file, the owner of the file is changed.  Why?
+A. When writing a file Vim renames the original file, this is a backup (in
+   case writing the file fails halfway).  Then the file is written as a new
+   file.  Samba then gives it the default owner for the file system, which may
+   differ from the original owner.
+   To avoid this set the 'backupcopy' option to "yes".  Vim will then make a
+   copy of the file for the backup, and overwrite the original file.  The
+   owner isn't changed then.
+
+Q. How do I get to see the output of ":make" while it's running?
+A. Basically what you need is to put a tee program that will copy its input
+   (the output from make) to both stdout and to the errorfile.  You can find a
+   copy of tee (and a number of other GNU tools) at
+   http://gnuwin32.sourceforge.net or http://unxutils.sourceforge.net
+   Alternatively, try the more recent Cygnus version of the GNU tools at
+   http://www.cygwin.com  Other Unix-style tools for Win32 are listed at
+   http://directory.google.com/Top/Computers/Software/Operating_Systems/Unix/Win32/
+   When you do get a copy of tee, you'll need to add >
+	:set shellpipe=\|\ tee
+<  to your _vimrc.
+
+Q. I'm storing files on a remote machine that works with VisionFS, and files
+   disappear!
+A. VisionFS can't handle certain dot (.) three letter extension file names.
+   SCO declares this behavior required for backwards compatibility with 16bit
+   DOS/Windows environments.  The two commands below demonstrate the behavior:
+>
+	echo Hello > file.bat~ 
+	dir > file.bat
+<
+   The result is that the "dir" command updates the "file.bat~" file, instead
+   of creating a new "file.bat" file.  This same behavior is exhibited in Vim
+   when editing an existing file named "foo.bat" because the default behavior
+   of Vim is to create a temporary file with a '~' character appended to the
+   name.  When the file is written, it winds up being deleted.
+
+   Solution: Add this command to your _vimrc file: >
+	:set backupext=.temporary
+
+Q. How do I change the blink rate of the cursor?
+A. You can't!  This is a limitation of the NT console.  NT 5.0 is reported to
+   be able to set the blink rate for all console windows at the same time.
+
+							*:!start*
+Q. How can I run an external command or program asynchronously?
+A. When using :! to run an external command, you can run it with "start": >
+	:!start winfile.exe<CR>
+<  Using "start" stops Vim switching to another screen, opening a new console,
+   or waiting for the program to complete; it indicates that you are running a
+   program that does not effect the files you are editing.  Programs begun
+   with :!start do not get passed Vim's open file handles, which means they do
+   not have to be closed before Vim.
+   To avoid this special treatment, use ":! start".
+
+Q. I'm using Win32s, and when I try to run an external command like "make",
+   Vim doesn't wait for it to finish!  Help!
+A. The problem is that a 32-bit application (Vim) can't get notification from
+   Windows that a 16-bit application (your DOS session) has finished.  Vim
+   includes a work-around for this, but you must set up your DOS commands to
+   run in a window, not full-screen.  Unfortunately the default when you
+   install Windows is full-screen.  To change this:
+   1) Start PIF editor (in the Main program group).
+   2) Open the file "_DEFAULT.PIF" in your Windows directory.
+   3) Changes the display option from "Full Screen" to "Windowed".
+   4) Save and exit.
+
+   To test, start Vim and type >
+	:!dir C:\<CR>".
+<  You should see a DOS box window appear briefly with the directory listing.
+
+Q. I use Vim under Win32s and NT.  In NT, I can define the console to default to
+   50 lines, so that I get a 80x50 shell when I ':sh'.  Can I do the same in
+   W3.1x, or am I stuck with 80x25?
+A. Edit SYSTEM.INI and add 'ScreenLines=50' to the [NonWindowsApp] section.  DOS
+   prompts and external DOS commands will now run in a 50-line window.
+
+ vim:tw=78:fo=tcq2:ts=8:ft=help:norl:
--- /dev/null
+++ b/lib/vimfiles/doc/pattern.txt
@@ -1,0 +1,1262 @@
+*pattern.txt*   For Vim version 7.1.  Last change: 2007 May 11
+
+
+		  VIM REFERENCE MANUAL    by Bram Moolenaar
+
+
+Patterns and search commands				*pattern-searches*
+
+The very basics can be found in section |03.9| of the user manual.  A few more
+explanations are in chapter 27 |usr_27.txt|.
+
+1. Search commands		|search-commands|
+2. The definition of a pattern	|search-pattern|
+3. Magic			|/magic|
+4. Overview of pattern items	|pattern-overview|
+5. Multi items			|pattern-multi-items|
+6. Ordinary atoms		|pattern-atoms|
+7. Ignoring case in a pattern	|/ignorecase|
+8. Composing characters		|patterns-composing|
+9. Compare with Perl patterns	|perl-patterns|
+10. Highlighting matches	|match-highlight|
+
+==============================================================================
+1. Search commands				*search-commands* *E486*
+
+							*/*
+/{pattern}[/]<CR>	Search forward for the [count]'th occurrence of
+			{pattern} |exclusive|.
+
+/{pattern}/{offset}<CR>	Search forward for the [count]'th occurrence of
+			{pattern} and go |{offset}| lines up or down.
+			|linewise|.
+
+							*/<CR>*
+/<CR>			Search forward for the [count]'th latest used
+			pattern |last-pattern| with latest used |{offset}|.
+
+//{offset}<CR>		Search forward for the [count]'th latest used
+			pattern |last-pattern| with new |{offset}|.  If
+			{offset} is empty no offset is used.
+
+							*?*
+?{pattern}[?]<CR>	Search backward for the [count]'th previous
+			occurrence of {pattern} |exclusive|.
+
+?{pattern}?{offset}<CR>	Search backward for the [count]'th previous
+			occurrence of {pattern} and go |{offset}| lines up or
+			down |linewise|.
+
+							*?<CR>*
+?<CR>			Search backward for the [count]'th latest used
+			pattern |last-pattern| with latest used |{offset}|.
+
+??{offset}<CR>		Search backward for the [count]'th latest used
+			pattern |last-pattern| with new |{offset}|.  If
+			{offset} is empty no offset is used.
+
+							*n*
+n			Repeat the latest "/" or "?" [count] times.
+			|last-pattern| {Vi: no count}
+
+							*N*
+N			Repeat the latest "/" or "?" [count] times in
+			opposite direction. |last-pattern| {Vi: no count}
+
+							*star* *E348* *E349*
+*			Search forward for the [count]'th occurrence of the
+			word nearest to the cursor.  The word used for the
+			search is the first of:
+				1. the keyword under the cursor |'iskeyword'|
+				2. the first keyword after the cursor, in the
+				   current line
+				3. the non-blank word under the cursor
+				4. the first non-blank word after the cursor,
+				   in the current line
+			Only whole keywords are searched for, like with the
+			command "/\<keyword\>".  |exclusive|  {not in Vi}
+			'ignorecase' is used, 'smartcase' is not.
+
+							*#*
+#			Same as "*", but search backward.  The pound sign
+			(character 163) also works.  If the "#" key works as
+			backspace, try using "stty erase <BS>" before starting
+			Vim (<BS> is CTRL-H or a real backspace).  {not in Vi}
+
+							*gstar*
+g*			Like "*", but don't put "\<" and "\>" around the word.
+			This makes the search also find matches that are not a
+			whole word.  {not in Vi}
+
+							*g#*
+g#			Like "#", but don't put "\<" and "\>" around the word.
+			This makes the search also find matches that are not a
+			whole word.  {not in Vi}
+
+							*gd*
+gd			Goto local Declaration.  When the cursor is on a local
+			variable, this command will jump to its declaration.
+			First Vim searches for the start of the current
+			function, just like "[[".  If it is not found the
+			search stops in line 1.  If it is found, Vim goes back
+			until a blank line is found.  From this position Vim
+			searches for the keyword under the cursor, like with
+			"*", but lines that look like a comment are ignored
+			(see 'comments' option).
+			Note that this is not guaranteed to work, Vim does not
+			really check the syntax, it only searches for a match
+			with the keyword.  If included files also need to be
+			searched use the commands listed in |include-search|.
+			After this command |n| searches forward for the next
+			match (not backward).
+			{not in Vi}
+
+							*gD*
+gD			Goto global Declaration.  When the cursor is on a
+			global variable that is defined in the file, this
+			command will jump to its declaration.  This works just
+			like "gd", except that the search for the keyword
+			always starts in line 1.  {not in Vi}
+
+							*1gd*
+1gd			Like "gd", but ignore matches inside a {} block that
+			ends before the cursor position. {not in Vi}
+
+							*1gD*
+1gD			Like "gD", but ignore matches inside a {} block that
+			ends before the cursor position. {not in Vi}
+
+							*CTRL-C*
+CTRL-C			Interrupt current (search) command.  Use CTRL-Break on
+			MS-DOS |dos-CTRL-Break|.
+			In Normal mode, any pending command is aborted.
+
+							*:noh* *:nohlsearch*
+:noh[lsearch]		Stop the highlighting for the 'hlsearch' option.  It
+			is automatically turned back on when using a search
+			command, or setting the 'hlsearch' option.
+			This command doesn't work in an autocommand, because
+			the highlighting state is saved and restored when
+			executing autocommands |autocmd-searchpat|.
+
+While typing the search pattern the current match will be shown if the
+'incsearch' option is on.  Remember that you still have to finish the search
+command with <CR> to actually position the cursor at the displayed match.  Or
+use <Esc> to abandon the search.
+
+All matches for the last used search pattern will be highlighted if you set
+the 'hlsearch' option.  This can be suspended with the |:nohlsearch| command.
+
+					*search-offset* *{offset}*
+These commands search for the specified pattern.  With "/" and "?" an
+additional offset may be given.  There are two types of offsets: line offsets
+and character offsets.  {the character offsets are not in Vi}
+
+The offset gives the cursor position relative to the found match:
+    [num]	[num] lines downwards, in column 1
+    +[num]	[num] lines downwards, in column 1
+    -[num]	[num] lines upwards, in column 1
+    e[+num]	[num] characters to the right of the end of the match
+    e[-num]	[num] characters to the left of the end of the match
+    s[+num]	[num] characters to the right of the start of the match
+    s[-num]	[num] characters to the left of the start of the match
+    b[+num]	[num] identical to s[+num] above (mnemonic: begin)
+    b[-num]	[num] identical to s[-num] above (mnemonic: begin)
+    ;{pattern}  perform another search, see |//;|
+
+If a '-' or '+' is given but [num] is omitted, a count of one will be used.
+When including an offset with 'e', the search becomes inclusive (the
+character the cursor lands on is included in operations).
+
+Examples:
+
+pattern			cursor position	~
+/test/+1		one line below "test", in column 1
+/test/e			on the last t of "test"
+/test/s+2		on the 's' of "test"
+/test/b-3		three characters before "test"
+
+If one of these commands is used after an operator, the characters between
+the cursor position before and after the search is affected.  However, if a
+line offset is given, the whole lines between the two cursor positions are
+affected.
+
+An example of how to search for matches with a pattern and change the match
+with another word: >
+	/foo<CR>	find "foo"
+	c//e		change until end of match
+	bar<Esc>	type replacement
+	//<CR>		go to start of next match
+	c//e		change until end of match
+	beep<Esc>	type another replacement
+			etc.
+<
+							*//;* *E386*
+A very special offset is ';' followed by another search command.  For example: >
+
+   /test 1/;/test
+   /test.*/+1;?ing?
+
+The first one first finds the next occurrence of "test 1", and then the first
+occurrence of "test" after that.
+
+This is like executing two search commands after each other, except that:
+- It can be used as a single motion command after an operator.
+- The direction for a following "n" or "N" command comes from the first
+  search command.
+- When an error occurs the cursor is not moved at all.
+
+							*last-pattern*
+The last used pattern and offset are remembered.  They can be used to repeat
+the search, possibly in another direction or with another count.  Note that
+two patterns are remembered: One for 'normal' search commands and one for the
+substitute command ":s".  Each time an empty pattern is given, the previously
+used pattern is used.
+
+The 'magic' option sticks with the last used pattern.  If you change 'magic',
+this will not change how the last used pattern will be interpreted.
+The 'ignorecase' option does not do this.  When 'ignorecase' is changed, it
+will result in the pattern to match other text.
+
+All matches for the last used search pattern will be highlighted if you set
+the 'hlsearch' option.
+
+To clear the last used search pattern: >
+	:let @/ = ""
+This will not set the pattern to an empty string, because that would match
+everywhere.  The pattern is really cleared, like when starting Vim.
+
+The search usually skips matches that don't move the cursor.  Whether the next
+match is found at the next character or after the skipped match depends on the
+'c' flag in 'cpoptions'.  See |cpo-c|.
+	   with 'c' flag:   "/..." advances 1 to 3 characters
+	without 'c' flag:   "/..." advances 1 character
+The unpredictability with the 'c' flag is caused by starting the search in the
+first column, skipping matches until one is found past the cursor position.
+
+When searching backwards, searching starts at the start of the line, using the
+'c' flag in 'cpoptions' as described above.  Then the last match before the
+cursor position is used.
+
+In Vi the ":tag" command sets the last search pattern when the tag is searched
+for.  In Vim this is not done, the previous search pattern is still remembered,
+unless the 't' flag is present in 'cpoptions'.  The search pattern is always
+put in the search history.
+
+If the 'wrapscan' option is on (which is the default), searches wrap around
+the end of the buffer.  If 'wrapscan' is not set, the backward search stops
+at the beginning and the forward search stops at the end of the buffer.  If
+'wrapscan' is set and the pattern was not found the error message "pattern
+not found" is given, and the cursor will not be moved.  If 'wrapscan' is not
+set the message becomes "search hit BOTTOM without match" when searching
+forward, or "search hit TOP without match" when searching backward.  If
+wrapscan is set and the search wraps around the end of the file the message
+"search hit TOP, continuing at BOTTOM" or "search hit BOTTOM, continuing at
+TOP" is given when searching backwards or forwards respectively.  This can be
+switched off by setting the 's' flag in the 'shortmess' option.  The highlight
+method 'w' is used for this message (default: standout).
+
+							*search-range*
+You can limit the search command "/" to a certain range of lines by including
+\%>l items.  For example, to match the word "limit" below line 199 and above
+line 300: >
+	/\%>199l\%<300llimit
+Also see |/\%>l|.
+
+Another way is to use the ":substitute" command with the 'c' flag.  Example: >
+   :.,300s/Pattern//gc
+This command will search from the cursor position until line 300 for
+"Pattern".  At the match, you will be asked to type a character.  Type 'q' to
+stop at this match, type 'n' to find the next match.
+
+The "*", "#", "g*" and "g#" commands look for a word near the cursor in this
+order, the first one that is found is used:
+- The keyword currently under the cursor.
+- The first keyword to the right of the cursor, in the same line.
+- The WORD currently under the cursor.
+- The first WORD to the right of the cursor, in the same line.
+The keyword may only contain letters and characters in 'iskeyword'.
+The WORD may contain any non-blanks (<Tab>s and/or <Space>s).
+Note that if you type with ten fingers, the characters are easy to remember:
+the "#" is under your left hand middle finger (search to the left and up) and
+the "*" is under your right hand middle finger (search to the right and down).
+(this depends on your keyboard layout though).
+
+==============================================================================
+2. The definition of a pattern		*search-pattern* *pattern* *[pattern]*
+					*regular-expression* *regexp* *Pattern*
+					*E76* *E383* *E476*
+
+For starters, read chapter 27 of the user manual |usr_27.txt|.
+
+						*/bar* */\bar* */pattern*
+1. A pattern is one or more branches, separated by "\|".  It matches anything
+   that matches one of the branches.  Example: "foo\|beep" matches "foo" and
+   matches "beep".  If more than one branch matches, the first one is used.
+
+   pattern ::=	    branch
+		or  branch \| branch
+		or  branch \| branch \| branch
+		etc.
+
+						*/branch* */\&*
+2. A branch is one or more concats, separated by "\&".  It matches the last
+   concat, but only if all the preceding concats also match at the same
+   position.  Examples:
+	"foobeep\&..." matches "foo" in "foobeep".
+	".*Peter\&.*Bob" matches in a line containing both "Peter" and "Bob"
+
+   branch ::=	    concat
+		or  concat \& concat
+		or  concat \& concat \& concat
+		etc.
+
+						*/concat*
+3. A concat is one or more pieces, concatenated.  It matches a match for the
+   first piece, followed by a match for the second piece, etc.  Example:
+   "f[0-9]b", first matches "f", then a digit and then "b".
+
+   concat  ::=	    piece
+		or  piece piece
+		or  piece piece piece
+		etc.
+
+						*/piece*
+4. A piece is an atom, possibly followed by a multi, an indication of how many
+   times the atom can be matched.  Example: "a*" matches any sequence of "a"
+   characters: "", "a", "aa", etc.  See |/multi|.
+
+   piece   ::=	    atom
+		or  atom  multi
+
+						*/atom*
+5. An atom can be one of a long list of items.  Many atoms match one character
+   in the text.  It is often an ordinary character or a character class.
+   Braces can be used to make a pattern into an atom.  The "\z(\)" construct
+   is only for syntax highlighting.
+
+   atom    ::=	    ordinary-atom		|/ordinary-atom|
+		or  \( pattern \)		|/\(|
+		or  \%( pattern \)		|/\%(|
+		or  \z( pattern \)		|/\z(|
+
+
+==============================================================================
+3. Magic							*/magic*
+
+Some characters in the pattern are taken literally.  They match with the same
+character in the text.  When preceded with a backslash however, these
+characters get a special meaning.
+
+Other characters have a special meaning without a backslash.  They need to be
+preceded with a backslash to match literally.
+
+If a character is taken literally or not depends on the 'magic' option and the
+items mentioned next.
+							*/\m* */\M*
+Use of "\m" makes the pattern after it be interpreted as if 'magic' is set,
+ignoring the actual value of the 'magic' option.
+Use of "\M" makes the pattern after it be interpreted as if 'nomagic' is used.
+							*/\v* */\V*
+Use of "\v" means that in the pattern after it all ASCII characters except
+'0'-'9', 'a'-'z', 'A'-'Z' and '_' have a special meaning.  "very magic"
+
+Use of "\V" means that in the pattern after it only the backslash has a
+special meaning.  "very nomagic"
+
+Examples:
+after:	  \v	   \m	    \M	     \V		matches ~
+		'magic' 'nomagic'
+	  $	   $	    $	     \$		matches end-of-line
+	  .	   .	    \.	     \.		matches any character
+	  *	   *	    \*	     \*		any number of the previous atom
+	  ()	   \(\)     \(\)     \(\)	grouping into an atom
+	  |	   \|	    \|	     \|		separating alternatives
+	  \a	   \a	    \a	     \a		alphabetic character
+	  \\	   \\	    \\	     \\		literal backslash
+	  \.	   \.	    .	     .		literal dot
+	  \{	   {	    {	     {		literal '{'
+	  a	   a	    a	     a		literal 'a'
+
+{only Vim supports \m, \M, \v and \V}
+
+It is recommended to always keep the 'magic' option at the default setting,
+which is 'magic'.  This avoids portability problems.  To make a pattern immune
+to the 'magic' option being set or not, put "\m" or "\M" at the start of the
+pattern.
+
+==============================================================================
+4. Overview of pattern items				*pattern-overview*
+
+Overview of multi items.				*/multi* *E61* *E62*
+More explanation and examples below, follow the links.			*E64*
+
+	  multi ~
+     'magic' 'nomagic'	matches of the preceding atom ~
+|/star|	*	\*	0 or more	as many as possible
+|/\+|	\+	\+	1 or more	as many as possible (*)
+|/\=|	\=	\=	0 or 1		as many as possible (*)
+|/\?|	\?	\?	0 or 1		as many as possible (*)
+
+|/\{|	\{n,m}	\{n,m}	n to m		as many as possible (*)
+	\{n}	\{n}	n		exactly (*)
+	\{n,}	\{n,}	at least n	as many as possible (*)
+	\{,m}	\{,m}	0 to m		as many as possible (*)
+	\{}	\{}	0 or more	as many as possible (same as *) (*)
+
+|/\{-|	\{-n,m}	\{-n,m}	n to m		as few as possible (*)
+	\{-n}	\{-n}	n		exactly (*)
+	\{-n,}	\{-n,}	at least n	as few as possible (*)
+	\{-,m}	\{-,m}	0 to m		as few as possible (*)
+	\{-}	\{-}	0 or more	as few as possible (*)
+
+							*E59*
+|/\@>|	\@>	\@>	1, like matching a whole pattern (*)
+|/\@=|	\@=	\@=	nothing, requires a match |/zero-width| (*)
+|/\@!|	\@!	\@!	nothing, requires NO match |/zero-width| (*)
+|/\@<=|	\@<=	\@<=	nothing, requires a match behind |/zero-width| (*)
+|/\@<!|	\@<!	\@<!	nothing, requires NO match behind |/zero-width| (*)
+
+(*) {not in Vi}
+
+
+Overview of ordinary atoms.				*/ordinary-atom*
+More explanation and examples below, follow the links.
+
+      ordinary atom ~
+      magic   nomagic	matches ~
+|/^|	^	^	start-of-line (at start of pattern) |/zero-width|
+|/\^|	\^	\^	literal '^'
+|/\_^|	\_^	\_^	start-of-line (used anywhere) |/zero-width|
+|/$|	$	$	end-of-line (at end of pattern) |/zero-width|
+|/\$|	\$	\$	literal '$'
+|/\_$|	\_$	\_$	end-of-line (used anywhere) |/zero-width|
+|/.|	.	\.	any single character (not an end-of-line)
+|/\_.|	\_.	\_.	any single character or end-of-line
+|/\<|	\<	\<	beginning of a word |/zero-width|
+|/\>|	\>	\>	end of a word |/zero-width|
+|/\zs|	\zs	\zs	anything, sets start of match
+|/\ze|	\ze	\ze	anything, sets end of match
+|/\%^|	\%^	\%^	beginning of file |/zero-width|		*E71*
+|/\%$|	\%$	\%$	end of file |/zero-width|
+|/\%V|	\%V	\%V	inside Visual area |/zero-width|
+|/\%#|	\%#	\%#	cursor position |/zero-width|
+|/\%'m|	\%'m	\%'m	mark m position |/zero-width|
+|/\%l|	\%23l	\%23l	in line 23 |/zero-width|
+|/\%c|	\%23c	\%23c	in column 23 |/zero-width|
+|/\%v|	\%23v	\%23v	in virtual column 23 |/zero-width|
+
+Character classes {not in Vi}:				*/character-classes*
+|/\i|	\i	\i	identifier character (see 'isident' option)
+|/\I|	\I	\I	like "\i", but excluding digits
+|/\k|	\k	\k	keyword character (see 'iskeyword' option)
+|/\K|	\K	\K	like "\k", but excluding digits
+|/\f|	\f	\f	file name character (see 'isfname' option)
+|/\F|	\F	\F	like "\f", but excluding digits
+|/\p|	\p	\p	printable character (see 'isprint' option)
+|/\P|	\P	\P	like "\p", but excluding digits
+|/\s|	\s	\s	whitespace character: <Space> and <Tab>
+|/\S|	\S	\S	non-whitespace character; opposite of \s
+|/\d|	\d	\d	digit:				[0-9]
+|/\D|	\D	\D	non-digit:			[^0-9]
+|/\x|	\x	\x	hex digit:			[0-9A-Fa-f]
+|/\X|	\X	\X	non-hex digit:			[^0-9A-Fa-f]
+|/\o|	\o	\o	octal digit:			[0-7]
+|/\O|	\O	\O	non-octal digit:		[^0-7]
+|/\w|	\w	\w	word character:			[0-9A-Za-z_]
+|/\W|	\W	\W	non-word character:		[^0-9A-Za-z_]
+|/\h|	\h	\h	head of word character:		[A-Za-z_]
+|/\H|	\H	\H	non-head of word character:	[^A-Za-z_]
+|/\a|	\a	\a	alphabetic character:		[A-Za-z]
+|/\A|	\A	\A	non-alphabetic character:	[^A-Za-z]
+|/\l|	\l	\l	lowercase character:		[a-z]
+|/\L|	\L	\L	non-lowercase character:	[^a-z]
+|/\u|	\u	\u	uppercase character:		[A-Z]
+|/\U|	\U	\U	non-uppercase character		[^A-Z]
+|/\_|	\_x	\_x	where x is any of the characters above: character
+			class with end-of-line included
+(end of character classes)
+
+|/\e|	\e	\e	<Esc>
+|/\t|	\t	\t	<Tab>
+|/\r|	\r	\r	<CR>
+|/\b|	\b	\b	<BS>
+|/\n|	\n	\n	end-of-line
+|/~|	~	\~	last given substitute string
+|/\1|	\1	\1	same string as matched by first \(\) {not in Vi}
+|/\2|	\2	\2	Like "\1", but uses second \(\)
+	   ...
+|/\9|	\9	\9	Like "\1", but uses ninth \(\)
+								*E68*
+|/\z1|	\z1	\z1	only for syntax highlighting, see |:syn-ext-match|
+	   ...
+|/\z1|	\z9	\z9	only for syntax highlighting, see |:syn-ext-match|
+
+	x	x	a character with no special meaning matches itself
+
+|/[]|	[]	\[]	any character specified inside the []
+|/\%[]| \%[]	\%[]	a sequence of optionally matched atoms
+
+|/\c|	\c	\c	ignore case
+|/\C|	\C	\C	match case
+|/\m|	\m	\m	'magic' on for the following chars in the pattern
+|/\M|	\M	\M	'magic' off for the following chars in the pattern
+|/\v|	\v	\v	the following chars in the pattern are "very magic"
+|/\V|	\V	\V	the following chars in the pattern are "very nomagic"
+|/\Z|	\Z	\Z	ignore differences in Unicode "combining characters".
+			Useful when searching voweled Hebrew or Arabic text.
+
+|/\%d|	\%d	\%d	match specified decimal character (eg \%d123
+|/\%x|	\%x	\%x	match specified hex character (eg \%x2a)
+|/\%o|	\%o	\%o	match specified octal character (eg \%o040)
+|/\%u|	\%u	\%u	match specified multibyte character (eg \%u20ac)
+|/\%U|	\%U	\%U	match specified large multibyte character (eg
+			\%U12345678)
+
+Example			matches ~
+\<\I\i*		or
+\<\h\w*
+\<[a-zA-Z_][a-zA-Z0-9_]*
+			An identifier (e.g., in a C program).
+
+\(\.$\|\. \)		A period followed by <EOL> or a space.
+
+[.!?][])"']*\($\|[ ]\)	A search pattern that finds the end of a sentence,
+			with almost the same definition as the ")" command.
+
+cat\Z			Both "cat" and "càt" ("a" followed by 0x0300)
+			Does not match "càt" (character 0x00e0), even
+			though it may look the same.
+
+
+==============================================================================
+5. Multi items						*pattern-multi-items*
+
+An atom can be followed by an indication of how many times the atom can be
+matched and in what way.  This is called a multi.  See |/multi| for an
+overview.
+
+						*/star* */\star* *E56*
+*	(use \* when 'magic' is not set)
+	Matches 0 or more of the preceding atom, as many as possible.
+	Example  'nomagic'	matches ~
+	a*	   a\*		"", "a", "aa", "aaa", etc.
+	.*	   \.\*		anything, also an empty string, no end-of-line
+	\_.*	   \_.\*	everything up to the end of the buffer
+	\_.*END	   \_.\*END	everything up to and including the last "END"
+				in the buffer
+
+	Exception: When "*" is used at the start of the pattern or just after
+	"^" it matches the star character.
+
+	Be aware that repeating "\_." can match a lot of text and take a long
+	time.  For example, "\_.*END" matches all text from the current
+	position to the last occurrence of "END" in the file.  Since the "*"
+	will match as many as possible, this first skips over all lines until
+	the end of the file and then tries matching "END", backing up one
+	character at a time.
+
+							*/\+* *E57*
+\+	Matches 1 or more of the preceding atom, as many as possible. {not in
+	Vi}
+	Example		matches ~
+	^.\+$		any non-empty line
+	\s\+		white space of at least one character
+
+							*/\=*
+\=	Matches 0 or 1 of the preceding atom, as many as possible. {not in Vi}
+	Example		matches ~
+	foo\=		"fo" and "foo"
+
+							*/\?*
+\?	Just like \=.  Cannot be used when searching backwards with the "?"
+	command. {not in Vi}
+
+						*/\{* *E58* *E60* *E554*
+\{n,m}	Matches n to m of the preceding atom, as many as possible
+\{n}	Matches n of the preceding atom
+\{n,}	Matches at least n of the preceding atom, as many as possible
+\{,m}	Matches 0 to m of the preceding atom, as many as possible
+\{}	Matches 0 or more of the preceding atom, as many as possible (like *)
+							*/\{-*
+\{-n,m}	matches n to m of the preceding atom, as few as possible
+\{-n}	matches n of the preceding atom
+\{-n,}	matches at least n of the preceding atom, as few as possible
+\{-,m}	matches 0 to m of the preceding atom, as few as possible
+\{-}	matches 0 or more of the preceding atom, as few as possible
+	{Vi does not have any of these}
+
+	n and m are positive decimal numbers or zero
+								*non-greedy*
+	If a "-" appears immediately after the "{", then a shortest match
+	first algorithm is used (see example below).  In particular, "\{-}" is
+	the same as "*" but uses the shortest match first algorithm.  BUT: A
+	match that starts earlier is preferred over a shorter match: "a\{-}b"
+	matches "aaab" in "xaaab".
+
+	Example			matches ~
+	ab\{2,3}c		"abbc" or "abbbc"
+	a\{5}			"aaaaa".
+	ab\{2,}c		"abbc", "abbbc", "abbbbc", etc
+	ab\{,3}c		"ac", "abc", "abbc" or "abbbc".
+	a[bc]\{3}d		"abbbd", "abbcd", "acbcd", "acccd", etc.
+	a\(bc\)\{1,2}d		"abcd" or "abcbcd"
+	a[bc]\{-}[cd]		"abc" in "abcd"
+	a[bc]*[cd]		"abcd" in "abcd"
+
+	The } may optionally be preceded with a backslash: \{n,m\}.
+
+							*/\@=*
+\@=	Matches the preceding atom with zero width. {not in Vi}
+	Like "(?=pattern)" in Perl.
+	Example			matches ~
+	foo\(bar\)\@=		"foo" in "foobar"
+	foo\(bar\)\@=foo	nothing
+							*/zero-width*
+	When using "\@=" (or "^", "$", "\<", "\>") no characters are included
+	in the match.  These items are only used to check if a match can be
+	made.  This can be tricky, because a match with following items will
+	be done in the same position.  The last example above will not match
+	"foobarfoo", because it tries match "foo" in the same position where
+	"bar" matched.
+
+	Note that using "\&" works the same as using "\@=": "foo\&.." is the
+	same as "\(foo\)\@=..".  But using "\&" is easier, you don't need the
+	braces.
+
+
+							*/\@!*
+\@!	Matches with zero width if the preceding atom does NOT match at the
+	current position. |/zero-width| {not in Vi}
+	Like '(?!pattern)" in Perl.
+	Example			matches ~
+	foo\(bar\)\@!		any "foo" not followed by "bar"
+	a.\{-}p\@!		"a", "ap", "app", etc. not followed by a "p"
+	if \(\(then\)\@!.\)*$	"if " not followed by "then"
+
+	Using "\@!" is tricky, because there are many places where a pattern
+	does not match.  "a.*p\@!" will match from an "a" to the end of the
+	line, because ".*" can match all characters in the line and the "p"
+	doesn't match at the end of the line.  "a.\{-}p\@!" will match any
+	"a", "ap", "aap", etc. that isn't followed by a "p", because the "."
+	can match a "p" and "p\@!" doesn't match after that.
+
+	You can't use "\@!" to look for a non-match before the matching
+	position: "\(foo\)\@!bar" will match "bar" in "foobar", because at the
+	position where "bar" matches, "foo" does not match.  To avoid matching
+	"foobar" you could use "\(foo\)\@!...bar", but that doesn't match a
+	bar at the start of a line.  Use "\(foo\)\@<!bar".
+
+							*/\@<=*
+\@<=	Matches with zero width if the preceding atom matches just before what
+	follows. |/zero-width| {not in Vi}
+	Like '(?<=pattern)" in Perl, but Vim allows non-fixed-width patterns.
+	Example			matches ~
+	\(an\_s\+\)\@<=file	"file" after "an" and white space or an
+				end-of-line
+	For speed it's often much better to avoid this multi.  Try using "\zs"
+	instead |/\zs|.  To match the same as the above example:
+		an\_s\+\zsfile
+
+	"\@<=" and "\@<!" check for matches just before what follows.
+	Theoretically these matches could start anywhere before this position.
+	But to limit the time needed, only the line where what follows matches
+	is searched, and one line before that (if there is one).  This should
+	be sufficient to match most things and not be too slow.
+	The part of the pattern after "\@<=" and "\@<!" are checked for a
+	match first, thus things like "\1" don't work to reference \(\) inside
+	the preceding atom.  It does work the other way around:
+	Example			matches ~
+	\1\@<=,\([a-z]\+\)	",abc" in "abc,abc"
+
+							*/\@<!*
+\@<!	Matches with zero width if the preceding atom does NOT match just
+	before what follows.  Thus this matches if there is no position in the
+	current or previous line where the atom matches such that it ends just
+	before what follows.  |/zero-width| {not in Vi}
+	Like '(?<!pattern)" in Perl, but Vim allows non-fixed-width patterns.
+	The match with the preceding atom is made to end just before the match
+	with what follows, thus an atom that ends in ".*" will work.
+	Warning: This can be slow (because many positions need to be checked
+	for a match).
+	Example			matches ~
+	\(foo\)\@<!bar		any "bar" that's not in "foobar"
+	\(\/\/.*\)\@\<!in	"in" which is not after "//"
+
+							*/\@>*
+\@>	Matches the preceding atom like matching a whole pattern. {not in Vi}
+	Like '(?>pattern)" in Perl.
+	Example		matches ~
+	\(a*\)\@>a	nothing (the "a*" takes all the "a"'s, there can't be
+			another one following)
+
+	This matches the preceding atom as if it was a pattern by itself.  If
+	it doesn't match, there is no retry with shorter sub-matches or
+	anything.  Observe this difference: "a*b" and "a*ab" both match
+	"aaab", but in the second case the "a*" matches only the first two
+	"a"s.  "\(a*\)\@>ab" will not match "aaab", because the "a*" matches
+	the "aaa" (as many "a"s as possible), thus the "ab" can't match.
+
+
+==============================================================================
+6.  Ordinary atoms					*pattern-atoms*
+
+An ordinary atom can be:
+
+							*/^*
+^	At beginning of pattern or after "\|", "\(", "\%(" or "\n": matches
+	start-of-line; at other positions, matches literal '^'. |/zero-width|
+	Example		matches ~
+	^beep(		the start of the C function "beep" (probably).
+
+							*/\^*
+\^	Matches literal '^'.  Can be used at any position in the pattern.
+
+							*/\_^*
+\_^	Matches start-of-line. |/zero-width|  Can be used at any position in
+	the pattern.
+	Example		matches ~
+	\_s*\_^foo	white space and blank lines and then "foo" at
+			start-of-line
+
+							*/$*
+$	At end of pattern or in front of "\|" or "\)" ("|" or ")" after "\v"):
+	matches end-of-line <EOL>; at other positions, matches literal '$'.
+	|/zero-width|
+
+							*/\$*
+\$	Matches literal '$'.  Can be used at any position in the pattern.
+
+							*/\_$*
+\_$	Matches end-of-line. |/zero-width|  Can be used at any position in the
+	pattern.  Note that "a\_$b" never matches, since "b" cannot match an
+	end-of-line.  Use "a\nb" instead |/\n|.
+	Example		matches ~
+	foo\_$\_s*	"foo" at end-of-line and following white space and
+			blank lines
+
+.	(with 'nomagic': \.)				*/.* */\.*
+	Matches any single character, but not an end-of-line.
+
+							*/\_.*
+\_.	Matches any single character or end-of-line.
+	Careful: "\_.*" matches all text to the end of the buffer!
+
+							*/\<*
+\<	Matches the beginning of a word: The next char is the first char of a
+	word.  The 'iskeyword' option specifies what is a word character.
+	|/zero-width|
+
+							*/\>*
+\>	Matches the end of a word: The previous char is the last char of a
+	word.  The 'iskeyword' option specifies what is a word character.
+	|/zero-width|
+
+							*/\zs*
+\zs	Matches at any position, and sets the start of the match there: The
+	next char is the first char of the whole match. |/zero-width|
+	Example: >
+		/^\s*\zsif
+<	matches an "if" at the start of a line, ignoring white space.
+	Can be used multiple times, the last one encountered in a matching
+	branch is used.  Example: >
+		/\(.\{-}\zsFab\)\{3}
+<	Finds the third occurrence of "Fab".
+	{not in Vi} {not available when compiled without the +syntax feature}
+							*/\ze*
+\ze	Matches at any position, and sets the end of the match there: The
+	previous char is the last char of the whole match. |/zero-width|
+	Can be used multiple times, the last one encountered in a matching
+	branch is used.
+	Example: "end\ze\(if\|for\)" matches the "end" in "endif" and
+	"endfor".
+	{not in Vi} {not available when compiled without the +syntax feature}
+
+						*/\%^* *start-of-file*
+\%^	Matches start of the file.  When matching with a string, matches the
+	start of the string. {not in Vi}
+	For example, to find the first "VIM" in a file: >
+		/\%^\_.\{-}\zsVIM
+<
+						*/\%$* *end-of-file*
+\%$	Matches end of the file.  When matching with a string, matches the
+	end of the string. {not in Vi}
+	Note that this does NOT find the last "VIM" in a file: >
+		/VIM\_.\{-}\%$
+<	It will find the next VIM, because the part after it will always
+	match.  This one will find the last "VIM" in the file: >
+		/VIM\ze\(\(VIM\)\@!\_.\)*\%$
+<	This uses |/\@!| to ascertain that "VIM" does NOT match in any
+	position after the first "VIM".
+	Searching from the end of the file backwards is easier!
+
+						*/\%V*
+\%V	Match inside the Visual area.  When Visual mode has already been
+	stopped match in the area that |gv| would reselect.
+	Only works for the current buffer.
+
+						*/\%#* *cursor-position*
+\%#	Matches with the cursor position.  Only works when matching in a
+	buffer displayed in a window. {not in Vi}
+	WARNING: When the cursor is moved after the pattern was used, the
+	result becomes invalid.  Vim doesn't automatically update the matches.
+	This is especially relevant for syntax highlighting and 'hlsearch'.
+	In other words: When the cursor moves the display isn't updated for
+	this change.  An update is done for lines which are changed (the whole
+	line is updated) or when using the |CTRL-L| command (the whole screen
+	is updated).  Example, to highlight the word under the cursor: >
+		/\k*\%#\k*
+<	When 'hlsearch' is set and you move the cursor around and make changes
+	this will clearly show when the match is updated or not.
+
+						*/\%'m* */\%<'m* */\%>'m*
+\%'m	Matches with the position of mark m.
+\%<'m	Matches before the position of mark m.
+\%>'m	Matches after the position of mark m.
+	Example, to highlight the text from mark 's to 'e: >
+		/.\%>'s.*\%<'e..
+<	Note that two dots are required to include mark 'e in the match.  That
+	is because "\%<'e" matches at the character before the 'e mark, and
+	since it's a |/zero-width| match it doesn't include that character.
+	{not in Vi}
+	WARNING: When the mark is moved after the pattern was used, the result
+	becomes invalid.  Vim doesn't automatically update the matches.
+	Similar to moving the cursor for "\%#" |/\%#|.
+
+						*/\%l* */\%>l* */\%<l*
+\%23l	Matches in a specific line.
+\%<23l	Matches above a specific line (lower line number).
+\%>23l	Matches below a specific line (higher line number).
+	These three can be used to match specific lines in a buffer.  The "23"
+	can be any line number.  The first line is 1. {not in Vi}
+	WARNING: When inserting or deleting lines Vim does not automatically
+	update the matches.  This means Syntax highlighting quickly becomes
+	wrong.
+	Example, to highlight the line where the cursor currently is: >
+		:exe '/\%' . line(".") . 'l.*'
+<	When 'hlsearch' is set and you move the cursor around and make changes
+	this will clearly show when the match is updated or not.
+
+						*/\%c* */\%>c* */\%<c*
+\%23c	Matches in a specific column.
+\%<23c	Matches before a specific column.
+\%>23c	Matches after a specific column.
+	These three can be used to match specific columns in a buffer or
+	string.  The "23" can be any column number.  The first column is 1.
+	Actually, the column is the byte number (thus it's not exactly right
+	for multi-byte characters).  {not in Vi}
+	WARNING: When inserting or deleting text Vim does not automatically
+	update the matches.  This means Syntax highlighting quickly becomes
+	wrong.
+	Example, to highlight the column where the cursor currently is: >
+		:exe '/\%' . col(".") . 'c'
+<	When 'hlsearch' is set and you move the cursor around and make changes
+	this will clearly show when the match is updated or not.
+	Example for matching a single byte in column 44: >
+		/\%>43c.\%<46c
+<	Note that "\%<46c" matches in column 45 when the "." matches a byte in
+	column 44.
+						*/\%v* */\%>v* */\%<v*
+\%23v	Matches in a specific virtual column.
+\%<23v	Matches before a specific virtual column.
+\%>23v	Matches after a specific virtual column.
+	These three can be used to match specific virtual columns in a buffer
+	or string.  When not matching with a buffer in a window, the option
+	values of the current window are used (e.g., 'tabstop').
+	The "23" can be any column number.  The first column is 1.
+	Note that some virtual column positions will never match, because they
+	are halfway through a tab or other character that occupies more than
+	one screen character.  {not in Vi}
+	WARNING: When inserting or deleting text Vim does not automatically
+	update highlighted matches.  This means Syntax highlighting quickly
+	becomes wrong.
+	Example, to highlight the all characters after virtual column 72: >
+		/\%>72v.*
+<	When 'hlsearch' is set and you move the cursor around and make changes
+	this will clearly show when the match is updated or not.
+	To match the text up to column 17: >
+		/.*\%17v
+<	Column 17 is not included, because that's where the "\%17v" matches,
+	and since this is a |/zero-width| match, column 17 isn't included in
+	the match.  This does the same: >
+		/.*\%<18v
+<
+
+Character classes: {not in Vi}
+\i	identifier character (see 'isident' option)	*/\i*
+\I	like "\i", but excluding digits			*/\I*
+\k	keyword character (see 'iskeyword' option)	*/\k*
+\K	like "\k", but excluding digits			*/\K*
+\f	file name character (see 'isfname' option)	*/\f*
+\F	like "\f", but excluding digits			*/\F*
+\p	printable character (see 'isprint' option)	*/\p*
+\P	like "\p", but excluding digits			*/\P*
+
+NOTE: the above also work for multi-byte characters.  The ones below only
+match ASCII characters, as indicated by the range.
+
+						*whitespace* *white-space*
+\s	whitespace character: <Space> and <Tab>		*/\s*
+\S	non-whitespace character; opposite of \s	*/\S*
+\d	digit:				[0-9]		*/\d*
+\D	non-digit:			[^0-9]		*/\D*
+\x	hex digit:			[0-9A-Fa-f]	*/\x*
+\X	non-hex digit:			[^0-9A-Fa-f]	*/\X*
+\o	octal digit:			[0-7]		*/\o*
+\O	non-octal digit:		[^0-7]		*/\O*
+\w	word character:			[0-9A-Za-z_]	*/\w*
+\W	non-word character:		[^0-9A-Za-z_]	*/\W*
+\h	head of word character:		[A-Za-z_]	*/\h*
+\H	non-head of word character:	[^A-Za-z_]	*/\H*
+\a	alphabetic character:		[A-Za-z]	*/\a*
+\A	non-alphabetic character:	[^A-Za-z]	*/\A*
+\l	lowercase character:		[a-z]		*/\l*
+\L	non-lowercase character:	[^a-z]		*/\L*
+\u	uppercase character:		[A-Z]		*/\u*
+\U	non-uppercase character		[^A-Z]		*/\U*
+
+	NOTE: Using the atom is faster than the [] form.
+
+	NOTE: 'ignorecase', "\c" and "\C" are not used by character classes.
+
+			*/\_* *E63* */\_i* */\_I* */\_k* */\_K* */\_f* */\_F*
+			*/\_p* */\_P* */\_s* */\_S* */\_d* */\_D* */\_x* */\_X*
+			*/\_o* */\_O* */\_w* */\_W* */\_h* */\_H* */\_a* */\_A*
+			*/\_l* */\_L* */\_u* */\_U*
+\_x	Where "x" is any of the characters above: The character class with
+	end-of-line added
+(end of character classes)
+
+\e	matches <Esc>					*/\e*
+\t	matches <Tab>					*/\t*
+\r	matches <CR>					*/\r*
+\b	matches <BS>					*/\b*
+\n	matches an end-of-line				*/\n*
+	When matching in a string instead of buffer text a literal newline
+	character is matched.
+
+~	matches the last given substitute string	*/~* */\~*
+
+\(\)	A pattern enclosed by escaped parentheses.	*/\(* */\(\)* */\)*
+	E.g., "\(^a\)" matches 'a' at the start of a line.  *E51* *E54* *E55*
+
+\1      Matches the same string that was matched by	*/\1* *E65*
+	the first sub-expression in \( and \). {not in Vi}
+	Example: "\([a-z]\).\1" matches "ata", "ehe", "tot", etc.
+\2      Like "\1", but uses second sub-expression,	*/\2*
+   ...							*/\3*
+\9      Like "\1", but uses ninth sub-expression.	*/\9*
+	Note: The numbering of groups is done based on which "\(" comes first
+	in the pattern (going left to right), NOT based on what is matched
+	first.
+
+\%(\)	A pattern enclosed by escaped parentheses.	*/\%(\)* */\%(* *E53*
+	Just like \(\), but without counting it as a sub-expression.  This
+	allows using more groups and it's a little bit faster.
+	{not in Vi}
+
+x	A single character, with no special meaning, matches itself
+
+							*/\* */\\*
+\x	A backslash followed by a single character, with no special meaning,
+	is reserved for future expansions
+
+[]	(with 'nomagic': \[])		*/[]* */\[]* */\_[]* */collection*
+\_[]
+	A collection.  This is a sequence of characters enclosed in brackets.
+	It matches any single character in the collection.
+	Example		matches ~
+	[xyz]		any 'x', 'y' or 'z'
+	[a-zA-Z]$	any alphabetic character at the end of a line
+	\c[a-z]$	same
+								*/[\n]*
+	With "\_" prepended the collection also includes the end-of-line.
+	The same can be done by including "\n" in the collection.  The
+	end-of-line is also matched when the collection starts with "^"!  Thus
+	"\_[^ab]" matches the end-of-line and any character but "a" and "b".
+	This makes it Vi compatible: Without the "\_" or "\n" the collection
+	does not match an end-of-line.
+								*E769*
+	When the ']' is not there Vim will not give an error message but
+	assume no collection is used.  Useful to search for '['.  However, you
+	do get E769 for internal searching.
+
+	If the sequence begins with "^", it matches any single character NOT
+	in the collection: "[^xyz]" matches anything but 'x', 'y' and 'z'.
+	- If two characters in the sequence are separated by '-', this is
+	  shorthand for the full list of ASCII characters between them.  E.g.,
+	  "[0-9]" matches any decimal digit.
+	- A character class expression is evaluated to the set of characters
+	  belonging to that character class.  The following character classes
+	  are supported:
+			  Name		Contents ~
+*[:alnum:]*		  [:alnum:]     letters and digits
+*[:alpha:]*		  [:alpha:]     letters
+*[:blank:]*		  [:blank:]     space and tab characters
+*[:cntrl:]*		  [:cntrl:]     control characters
+*[:digit:]*		  [:digit:]     decimal digits
+*[:graph:]*		  [:graph:]     printable characters excluding space
+*[:lower:]*		  [:lower:]     lowercase letters (all letters when
+					'ignorecase' is used)
+*[:print:]*		  [:print:]     printable characters including space
+*[:punct:]*		  [:punct:]     punctuation characters
+*[:space:]*		  [:space:]     whitespace characters
+*[:upper:]*		  [:upper:]     uppercase letters (all letters when
+					'ignorecase' is used)
+*[:xdigit:]*		  [:xdigit:]    hexadecimal digits
+*[:return:]*		  [:return:]	the <CR> character
+*[:tab:]*		  [:tab:]	the <Tab> character
+*[:escape:]*		  [:escape:]	the <Esc> character
+*[:backspace:]*		  [:backspace:]	the <BS> character
+	  The brackets in character class expressions are additional to the
+	  brackets delimiting a collection.  For example, the following is a
+	  plausible pattern for a UNIX filename: "[-./[:alnum:]_~]\+" That is,
+	  a list of at least one character, each of which is either '-', '.',
+	  '/', alphabetic, numeric, '_' or '~'.
+	  These items only work for 8-bit characters.
+							*/[[=* *[==]*
+	- An equivalence class.  This means that characters are matched that
+	  have almost the same meaning, e.g., when ignoring accents.  The form
+	  is:
+		[=a=]
+	  Currently this is only implemented for latin1.  Also works for the
+	  latin1 characters in utf-8 and latin9.
+							*/[[.* *[..]*
+	- A collation element.  This currently simply accepts a single
+	  character in the form:
+		[.a.]
+							  */\]*
+	- To include a literal ']', '^', '-' or '\' in the collection, put a
+	  backslash before it: "[xyz\]]", "[\^xyz]", "[xy\-z]" and "[xyz\\]".
+	  (Note: POSIX does not support the use of a backslash this way).  For
+	  ']' you can also make it the first character (following a possible
+	  "^"):  "[]xyz]" or "[^]xyz]" {not in Vi}.
+	  For '-' you can also make it the first or last character: "[-xyz]",
+	  "[^-xyz]" or "[xyz-]".  For '\' you can also let it be followed by
+	  any character that's not in "^]-\bertn".  "[\xyz]" matches '\', 'x',
+	  'y' and 'z'.  It's better to use "\\" though, future expansions may
+	  use other characters after '\'.
+	- The following translations are accepted when the 'l' flag is not
+	  included in 'cpoptions' {not in Vi}:
+		\e	<Esc>
+		\t	<Tab>
+		\r	<CR>	(NOT end-of-line!)
+		\b	<BS>
+		\n	line break, see above |/[\n]|
+		\d123	decimal number of character
+		\o40	octal number of character up to 0377
+		\x20	hexadecimal number of character up to 0xff
+		\u20AC	hex. number of multibyte character up to 0xffff
+		\U1234	hex. number of multibyte character up to 0xffffffff
+	  NOTE: The other backslash codes mentioned above do not work inside
+	  []!
+	- Matching with a collection can be slow, because each character in
+	  the text has to be compared with each character in the collection.
+	  Use one of the other atoms above when possible.  Example: "\d" is
+	  much faster than "[0-9]" and matches the same characters.
+
+						*/\%[]* *E69* *E70* *E369*
+\%[]	A sequence of optionally matched atoms.  This always matches.
+	It matches as much of the list of atoms it contains as possible.  Thus
+	it stops at the first atom that doesn't match.  For example: >
+		/r\%[ead]
+<	matches "r", "re", "rea" or "read".  The longest that matches is used.
+	To match the Ex command "function", where "fu" is required and
+	"nction" is optional, this would work: >
+		/\<fu\%[nction]\>
+<	The end-of-word atom "\>" is used to avoid matching "fu" in "full".
+	It gets more complicated when the atoms are not ordinary characters.
+	You don't often have to use it, but it is possible.  Example: >
+		/\<r\%[[eo]ad]\>
+<	Matches the words "r", "re", "ro", "rea", "roa", "read" and "road".
+	There can be no \(\), \%(\) or \z(\) items inside the [] and \%[] does
+	not nest.
+	{not available when compiled without the +syntax feature}
+
+				*/\%d* */\%x* */\%o* */\%u* */\%U* *E678*
+
+\%d123	Matches the character specified with a decimal number.  Must be
+	followed by a non-digit.
+\%o40	Matches the character specified with an octal number up to 0377.
+	Numbers below 040 must be followed by a non-octal digit or a non-digit.
+\%x2a	Matches the character specified with up to two hexadecimal characters.
+\%u20AC	Matches the character specified with up to four hexadecimal
+	characters.
+\%U1234abcd	Matches the character specified with up to eight hexadecimal
+	characters.
+
+==============================================================================
+7. Ignoring case in a pattern					*/ignorecase*
+
+If the 'ignorecase' option is on, the case of normal letters is ignored.
+'smartcase' can be set to ignore case when the pattern contains lowercase
+letters only.
+							*/\c* */\C*
+When "\c" appears anywhere in the pattern, the whole pattern is handled like
+'ignorecase' is on.  The actual value of 'ignorecase' and 'smartcase' is
+ignored.  "\C" does the opposite: Force matching case for the whole pattern.
+{only Vim supports \c and \C}
+Note that 'ignorecase', "\c" and "\C" are not used for the character classes.
+
+Examples:
+      pattern	'ignorecase'  'smartcase'	matches ~
+	foo	  off		-		foo
+	foo	  on		-		foo Foo FOO
+	Foo	  on		off		foo Foo FOO
+	Foo	  on		on		    Foo
+	\cfoo	  -		-		foo Foo FOO
+	foo\C	  -		-		foo
+
+Technical detail:				*NL-used-for-Nul*
+<Nul> characters in the file are stored as <NL> in memory.  In the display
+they are shown as "^@".  The translation is done when reading and writing
+files.  To match a <Nul> with a search pattern you can just enter CTRL-@ or
+"CTRL-V 000".  This is probably just what you expect.  Internally the
+character is replaced with a <NL> in the search pattern.  What is unusual is
+that typing CTRL-V CTRL-J also inserts a <NL>, thus also searches for a <Nul>
+in the file.  {Vi cannot handle <Nul> characters in the file at all}
+
+						*CR-used-for-NL*
+When 'fileformat' is "mac", <NL> characters in the file are stored as <CR>
+characters internally.  In the display they are shown as "^M".  Otherwise this
+works similar to the usage of <NL> for a <Nul>.
+
+When working with expression evaluation, a <NL> character in the pattern
+matches a <NL> in the string.  The use of "\n" (backslash n) to match a <NL>
+doesn't work there, it only works to match text in the buffer.
+
+						*pattern-multi-byte*
+Patterns will also work with multi-byte characters, mostly as you would
+expect.  But invalid bytes may cause trouble, a pattern with an invalid byte
+will probably never match.
+
+==============================================================================
+8. Composing characters					*patterns-composing*
+
+							*/\Z*
+When "\Z" appears anywhere in the pattern, composing characters are ignored.
+Thus only the base characters need to match, the composing characters may be
+different and the number of composing characters may differ.  Only relevant
+when 'encoding' is "utf-8".
+
+When a composing character appears at the start of the pattern of after an
+item that doesn't include the composing character, a match is found at any
+character that includes this composing character.
+
+When using a dot and a composing character, this works the same as the
+composing character by itself, except that it doesn't matter what comes before
+this.
+
+The order of composing characters matters, even though changing the order
+doesn't change what a character looks like.  This may change in the future.
+
+==============================================================================
+9. Compare with Perl patterns				*perl-patterns*
+
+Vim's regexes are most similar to Perl's, in terms of what you can do.  The
+difference between them is mostly just notation;  here's a summary of where
+they differ:
+
+Capability			in Vimspeak	in Perlspeak ~
+----------------------------------------------------------------
+force case insensitivity	\c		(?i)
+force case sensitivity		\C		(?-i)
+backref-less grouping		\%(atom\)	(?:atom)
+conservative quantifiers	\{-n,m}		*?, +?, ??, {}?
+0-width match			atom\@=		(?=atom)
+0-width non-match		atom\@!		(?!atom)
+0-width preceding match		atom\@<=	(?<=atom)
+0-width preceding non-match	atom\@<!	(?<!atom)
+match without retry		atom\@>		(?>atom)
+
+Vim and Perl handle newline characters inside a string a bit differently:
+
+In Perl, ^ and $ only match at the very beginning and end of the text,
+by default, but you can set the 'm' flag, which lets them match at
+embedded newlines as well.  You can also set the 's' flag, which causes
+a . to match newlines as well.  (Both these flags can be changed inside
+a pattern using the same syntax used for the i flag above, BTW.)
+
+On the other hand, Vim's ^ and $ always match at embedded newlines, and
+you get two separate atoms, \%^ and \%$, which only match at the very
+start and end of the text, respectively.  Vim solves the second problem
+by giving you the \_ "modifier":  put it in front of a . or a character
+class, and they will match newlines as well.
+
+Finally, these constructs are unique to Perl:
+- execution of arbitrary code in the regex:  (?{perl code})
+- conditional expressions:  (?(condition)true-expr|false-expr)
+
+...and these are unique to Vim:
+- changing the magic-ness of a pattern:  \v \V \m \M
+   (very useful for avoiding backslashitis)
+- sequence of optionally matching atoms:  \%[atoms]
+- \& (which is to \| what "and" is to "or";  it forces several branches
+   to match at one spot)
+- matching lines/columns by number:  \%5l \%5c \%5v
+- setting the start and end of the match:  \zs \ze
+
+==============================================================================
+10. Highlighting matches				*match-highlight*
+
+							*:mat* *:match*
+:mat[ch] {group} /{pattern}/
+		Define a pattern to highlight in the current window.  It will
+		be highlighted with {group}.  Example: >
+			:highlight MyGroup ctermbg=green guibg=green
+			:match MyGroup /TODO/
+<		Instead of // any character can be used to mark the start and
+		end of the {pattern}.  Watch out for using special characters,
+		such as '"' and '|'.
+
+		{group} must exist at the moment this command is executed.
+
+		The {group} highlighting still applies when a character is
+		to be highlighted for 'hlsearch'.
+
+		Note that highlighting the last used search pattern with
+		'hlsearch' is used in all windows, while the pattern defined
+		with ":match" only exists in the current window.  It is kept
+		when switching to another buffer.
+
+		'ignorecase' does not apply, use |/\c| in the pattern to
+		ignore case.  Otherwise case is not ignored.
+
+		When matching end-of-line and Vim redraws only part of the
+		display you may get unexpected results.  That is because Vim
+		looks for a match in the line where redrawing starts.
+
+		Also see |matcharg()|, it returns the highlight group and
+		pattern of a previous :match command.
+
+		Another example, which highlights all characters in virtual
+		column 72 and more: >
+			:highlight rightMargin term=bold ctermfg=blue guifg=blue
+			:match rightMargin /.\%>72v/
+<		To highlight all character that are in virtual column 7: >
+			:highlight col8 ctermbg=grey guibg=grey
+			:match col8 /\%<8v.\%>7v/
+<		Note the use of two items to also match a character that
+		occupies more than one virtual column, such as a TAB.
+
+:mat[ch]
+:mat[ch] none
+		Clear a previously defined match pattern.
+
+
+:2mat[ch] {group} /{pattern}/					*:2match*
+:2mat[ch]
+:2mat[ch] none
+:3mat[ch] {group} /{pattern}/					*:3match*
+:3mat[ch]
+:3mat[ch] none
+		Just like |:match| above, but set a separate match.  Thus
+		there can be three matches active at the same time.  The match
+		with the lowest number has priority if several match at the
+		same position.
+		The ":3match" command is used by the |matchparen| plugin.  You
+		are suggested to use ":match" for manual matching and
+		":2match" for another plugin.
+
+
+ vim:tw=78:ts=8:ft=help:norl:
--- /dev/null
+++ b/lib/vimfiles/doc/pi_getscript.txt
@@ -1,0 +1,408 @@
+*pi_getscript.txt*  For Vim version 7.1.  Last change: 2007 May 08
+>
+		GETSCRIPT REFERENCE MANUAL  by Charles E. Campbell, Jr.
+<
+Authors:  Charles E. Campbell, Jr.  <NdrOchip@ScampbellPfamilyA.Mbiz>
+	  (remove NOSPAM from the email address)
+						*GetLatestVimScripts-copyright*
+Copyright: (c) 2004-2006 by Charles E. Campbell, Jr.	*glvs-copyright*
+           The VIM LICENSE applies to getscript.vim and
+           pi_getscript.txt (see |copyright|) except use
+           "getscript" instead of "Vim".  No warranty, express or implied.
+	   Use At-Your-Own-Risk.
+
+Getscript is a plugin that simplifies retrieval of the latest versions of the
+scripts that you yourself use!  Typing |:GLVS| will invoke getscript; it will
+then use the <GetLatestVimScripts.dat> (see |GetLatestVimScripts_dat|) file to
+get the latest versions of scripts listed therein from http://vim.sf.net/.
+
+==============================================================================
+1. Contents				*glvs-contents* *glvs* *getscript*
+   					*GetLatestVimScripts*
+
+	1. Contents........................................: |glvs-contents|
+	2. GetLatestVimScripts -- Getting Started..........: |glvs-install|
+	3. GetLatestVimScripts Usage.......................: |glvs-usage|
+	4. GetLatestVimScripts Data File...................: |glvs-data|
+	5. GetLatestVimScripts Friendly Plugins............: |glvs-plugins|
+	6. GetLatestVimScripts AutoInstall.................: |glvs-autoinstall|
+	7. GetLatestViMScripts Options.....................: |glvs-options|
+	8. GetLatestVimScripts Algorithm...................: |glvs-alg|
+	9. GetLatestVimScripts History.....................: |glvs-hist|
+
+
+==============================================================================
+2. GetLatestVimScripts -- Getting Started		*getscript-start*
+						*getlatestvimscripts-install*
+
+	VERSION FROM VIM DISTRIBUTION			*glvs-dist-install*
+
+Vim 7.0 does not include the GetLatestVimScripts.dist file which
+serves as an example and a template.  So, you'll need to create
+your own!  See |GetLatestVimScripts_dat|.
+
+	VERSION FROM VIM SF NET				*glvs-install*
+
+NOTE: The last step, that of renaming/moving the GetLatestVimScripts.dist
+file, is for those who have just downloaded GetLatestVimScripts.tar.bz2 for
+the first time.
+
+The GetLatestVimScripts.dist file serves as an example and a template for your
+own personal list.  Feel free to remove all the scripts mentioned within it;
+the "important" part of it is the first two lines.
+
+Your computer needs to have wget for GetLatestVimScripts to do its work.
+
+	1. if compressed:  gunzip getscript.vba.gz
+	2. Unix:
+		vim getscript.vba
+		:so %
+		:q
+		cd ~/.vim/GetLatest
+		mv GetLatestVimScripts.dist GetLatestVimScripts.dat
+		(edit GetLatestVimScripts.dat to install your own personal
+		list of desired plugins -- see |GetLatestVimScripts_dat|)
+	
+	3. Windows:
+		vim getscript.vba
+		:so %
+		:q
+		cd **path-to-vimfiles**/GetLatest
+		mv GetLatestVimScripts.dist GetLatestVimScripts.dat
+		(edit GetLatestVimScripts.dat to install your own personal
+		list of desired plugins -- see |GetLatestVimScripts_dat|)
+
+
+==============================================================================
+3. GetLatestVimScripts Usage				*glvs-usage* *:GLVS*
+
+Unless its been defined elsewhere, >
+	:GLVS
+will invoke GetLatestVimScripts().  If some other plugin has defined that
+command, then you may type
+>
+	:GetLatestVimScripts
+<
+The script will attempt to update and, if permitted, will automatically
+install scripts from http://vim.sourceforge.net/.  To do so it will peruse a
+file,
+>
+	.vim/GetLatest/GetLatestVimScripts.dat                    (unix)
+<
+or >
+	..wherever..\vimfiles\GetLatest\GetLatestVimScripts.dat   (windows)
+(see |glvs-data|), and examine plugins in your [.vim|vimfiles]/plugin
+directory (see |glvs-plugins|).
+
+Scripts which have been downloaded will appear in the
+~/.vim/GetLatest (unix) or ..wherever..\vimfiles\GetLatest (windows)
+subdirectory.  GetLatestVimScripts will attempt to automatically
+install them if you have the following line in your <.vimrc>: >
+
+	let g:GetLatestVimScripts_allowautoinstall=1
+
+The <GetLatestVimScripts.dat> file will be automatically be updated to
+reflect the latest version of script(s) so downloaded.
+(also see |glvs-options|)
+
+
+==============================================================================
+4. GetLatestVimScripts Data File		*getscript-data* *glvs-data*
+ 						*:GetLatestVimScripts_dat*
+The data file <GetLatestVimScripts.dat> must have for its first two lines
+the following text:
+>
+	ScriptID SourceID Filename
+	--------------------------
+<
+Following those two lines are three columns; the first two are numeric
+followed by a text column.  The GetLatest/GetLatestVimScripts.dist file
+contains an example of such a data file.  Anything following a #... is
+ignored, so you may embed comments in the file.
+
+The first number on each line gives the script's ScriptID.  When you're about
+to use a web browser to look at scripts on http://vim.sf.net/, just before you
+click on the script's link, you'll see a line resembling
+
+	http://vim.sourceforge.net/scripts/script.php?script_id=40
+
+The "40" happens to be a ScriptID that GetLatestVimScripts needs to
+download the associated page.
+
+The second number on each line gives the script's SourceID.  The SourceID
+records the count of uploaded scripts as determined by vim.sf.net; hence it
+serves to indicate "when" a script was uploaded.  Setting the SourceID to 1
+insures that GetLatestVimScripts will assume that the script it has is
+out-of-date.
+
+The SourceID is extracted by GetLatestVimScripts from the script's page on
+vim.sf.net; whenever it's greater than the one stored in the
+GetLatestVimScripts.dat file, the script will be downloaded
+(see |GetLatestVimScripts_dat|).
+
+If your script's author has included a special comment line in his/her plugin,
+the plugin itself will be used by GetLatestVimScripts to build your
+<GetLatestVimScripts.dat> file, including any dependencies on other scripts it
+may have.  As an example, consider: >
+
+	" GetLatestVimScripts: 884  1 :AutoInstall: AutoAlign.vim
+
+This comment line tells getscript.vim to check vimscript #884 and that the
+script is automatically installable.  Getscript will also use this line to
+help build the GetLatestVimScripts.dat file, by including a line such as: >
+
+	884 1 AutoAlign.vim
+<
+in it an AutoAlign.vim line isn't already in GetLatestVimScripts.dat file.
+See |glvs-plugins| for more.  Thus, GetLatestVimScripts thus provides a
+comprehensive ability to keep your plugins up-to-date!
+
+						*GetLatestVimScripts_dat*
+As an example of a <GetLatestVimScripts.dat> file:
+>
+    ScriptID SourceID Filename
+    --------------------------
+    294 1 Align.vim
+    120 2 decho.vim
+     40 3 DrawIt.tar.gz
+    451 4 EasyAccents.vim
+    195 5 engspchk.vim
+    642 6 GetLatestVimScripts.vim
+    489 7 Manpageview.vim
+<
+Note: the first two lines are required, but essentially act as comments.
+
+
+==============================================================================
+5. GetLatestVimScripts Friendly Plugins	*getscript-plugins* *glvs-plugins*
+
+If a plugin author includes the following comment anywhere in their plugin,
+GetLatestVimScripts will find it and use it to automatically build the user's
+GetLatestVimScripts.dat files:
+>
+	                         src_id
+	                            v
+	" GetLatestVimScripts: ### ### yourscriptname
+	                        ^
+	                    scriptid
+<
+As an author, you should include such a line in to refer to your own script
+plus any additional lines describing any plugin dependencies it may have.
+Same format, of course!
+
+If your command is auto-installable (see |glvs-autoinstall|), and most scripts
+are, then you may include :AutoInstall: at the start of "yourscriptname".
+
+GetLatestVimScripts commands for those scripts are then appended, if not
+already present, to the user's GetLatest/GetLatestVimScripts.dat file.  Its a
+relatively painless way to automate the acquisition of any scripts your
+plugins depend upon.
+
+Now, as an author, you probably don't want GetLatestVimScripts to download
+your own scripts for you yourself, thereby overwriting your not-yet-released
+hard work.  GetLatestVimScripts provides a solution for this:  put
+>
+	0 0 yourscriptname
+<
+into your <GetLatestVimScripts.dat> file and GetLatestVimScripts will skip
+examining the "yourscriptname" scripts for those GetLatestVimScripts comment
+lines.  As a result, those lines won't be inadvertently installed into your
+<GetLatestVimScripts.dat> file and subsequently used to download your own
+scripts.  This is especially important to do if you've included the
+:AutoInstall: option.
+
+Be certain to use the same "yourscriptname" in the "0 0 yourscriptname" line
+as you've used in your GetLatestVimScripts comment!
+
+
+==============================================================================
+6. GetLatestVimScripts AutoInstall			*getscript-autoinstall*
+							*glvs-autoinstall*
+
+GetLatestVimScripts now supports "AutoInstall".  Not all scripts are
+supportive of auto-install, as they may have special things you need to do to
+install them (please refer to the script's "install" directions).  On the
+other hand, most scripts will be auto-installable.
+
+To let GetLatestVimScripts do an autoinstall, the data file's comment field
+should begin with (surrounding blanks are ignored): >
+
+	:AutoInstall:
+<
+Both colons are needed, and it should begin the comment (yourscriptname)
+field.
+
+One may prevent any autoinstalling by putting the following line in your
+<.vimrc>: >
+
+	let g:GetLatestVimScripts_allowautoinstall= 0
+<
+With :AutoInstall: enabled, as it is by default, files which end with
+
+	---.tar.bz2  : decompressed & untarred in .vim/ directory
+	---.vba.bz2  : decompressed in .vim/ directory, then vimball handles it
+	---.vim.bz2  : decompressed & moved into .vim/plugin directory
+	---.tar.gz   : decompressed & untarred in .vim/ directory
+	---.vba.gz   : decompressed in .vim/ directory, then vimball handles it
+	---.vim.gz   : decompressed & moved into .vim/plugin directory
+	---.vba      : unzipped in .vim/ directory
+	---.vim      : moved to .vim/plugin directory
+	---.zip      : unzipped in .vim/ directory
+
+and which merely need to have their components placed by the untar/gunzip or
+move-to-plugin-directory process should be auto-installable.  Vimballs, of
+course, should always be auto-installable.
+
+When is a script not auto-installable?  Let me give an example:
+
+	.vim/after/syntax/blockhl.vim
+
+The <blockhl.vim> script provides block highlighting for C/C++ programs; it is
+available at:
+
+	http://vim.sourceforge.net/scripts/script.php?script_id=104
+
+Currently, vim's after/syntax only supports by-filetype scripts (in
+blockhl.vim's case, that's after/syntax/c.vim).  Hence, auto-install would
+possibly overwrite the current user's after/syntax/c.vim file.
+
+In my own case, I use <aftersyntax.vim> (renamed to after/syntax/c.vim) to
+allow a after/syntax/c/ directory:
+
+	http://vim.sourceforge.net/scripts/script.php?script_id=1023
+
+The script allows multiple syntax files to exist separately in the
+after/syntax/c subdirectory.  I can't bundle aftersyntax.vim in and build an
+appropriate tarball for auto-install because of the potential for the
+after/syntax/c.vim contained in it to overwrite a user's c.vim.
+
+
+==============================================================================
+7. GetLatestVimScripts Options					*glvs-options*
+>
+	g:GetLatestVimScripts_wget
+<	default= "wget"
+		This variable holds the name of the command for obtaining
+		scripts.
+>
+	g:GetLatestVimScripts_options
+<	default= "-q -O"
+		This variable holds the options to be used with the
+		g:GetLatestVimScripts_wget command.
+>
+ 	g:getLatestVimScripts_allowautoinstall
+<	default= 1
+		This variable indicates whether GetLatestVimScripts is allowed
+		to attempt to automatically install scripts.  Note that it
+		doesn't understand vimballs (yet).  Furthermore, the plugin
+		author has to have explicitly indicated that his/her plugin
+		is automatically installable.
+
+
+==============================================================================
+8. GetLatestVimScripts Algorithm		*glvs-algorithm* *glvs-alg*
+
+The Vim sourceforge page dynamically creates a page by keying off of the
+so-called script-id.  Within the webpage of
+
+	http://vim.sourceforge.net/scripts/script.php?script_id=40
+
+is a line specifying the latest source-id (src_id).  The source identifier
+numbers are always increasing, hence if the src_id is greater than the one
+recorded for the script in GetLatestVimScripts then it's time to download a
+newer copy of that script.
+
+GetLatestVimScripts will then download the script and update its internal
+database of script ids, source ids, and scriptnames.
+
+The AutoInstall process will:
+
+	Move the file from GetLatest/ to the following directory
+		Unix   : $HOME/.vim
+		Windows: $HOME\vimfiles
+	if the downloaded file ends with ".bz2"
+		bunzip2 it
+	else if the downloaded file ends with ".gz"
+		gunzip it
+	if the resulting file ends with ".zip"
+		unzip it
+	else if the resulting file ends with ".tar"
+		tar -oxvf it
+	else if the resulting file ends with ".vim"
+		move it to the plugin subdirectory
+
+
+==============================================================================
+9. GetLatestVimScripts History		*getscript-history* *glvs-hist* {{{1
+
+v24 Apr 16, 2007 : * removed save&restore of the fo option during script
+                     loading
+v23 Nov 03, 2006 : * ignores comments (#...)
+                   * handles vimballs
+v22 Oct 13, 2006 : * supports automatic use of curl if wget is not
+                     available
+v21 May 01, 2006 : * now takes advantage of autoloading.
+v20 Dec 23, 2005 : * Eric Haarbauer found&fixed a bug with unzip use;
+                     unzip needs the -o flag to overwrite.
+v19 Nov 28, 2005 : * v18's GetLatestVimScript line accessed the wrong
+                     script! Fixed.
+v18 Mar 21, 2005 : * bugfix to automatic database construction
+                   * bugfix - nowrapscan caused an error
+                     (tnx to David Green for the fix)
+    Apr 01, 2005   * if shell is bash, "mv" instead of "ren" used in
+                     :AutoInstall:s, even though its o/s is windows
+    Apr 01, 2005   * when downloading errors occurred, GLVS was
+                     terminating early.  It now just goes on to trying
+                     the next script (after trying three times to
+                     download a script description page)
+    Apr 20, 2005   * bugfix - when a failure to download occurred,
+                     GetLatestVimScripts would stop early and claim that
+                     everything was current.  Fixed.
+v17 Aug 25, 2004 : * g:GetLatestVimScripts_allowautoinstall, which
+                     defaults to 1, can be used to prevent all
+                     :AutoInstall:
+v16 Aug 25, 2004 : * made execution of bunzip2/gunzip/tar/zip silent
+                   * fixed bug with :AutoInstall: use of helptags
+v15 Aug 24, 2004 : * bugfix: the "0 0 comment" download prevention wasn't
+                     always preventing downloads (just usually).  Fixed.
+v14 Aug 24, 2004 : * bugfix -- helptags was using dotvim, rather than
+                     s:dotvim.  Fixed.
+v13 Aug 23, 2004 : * will skip downloading a file if its scriptid or srcid
+                     is zero.  Useful for script authors; that way their
+                     own GetLatestVimScripts activity won't overwrite
+                     their scripts.
+v12 Aug 23, 2004 : * bugfix - a "return" got left in the distribution that
+                     was intended only for testing.  Removed, now works.
+                   * :AutoInstall: implemented
+v11 Aug 20, 2004 : * GetLatestVimScripts is now a plugin:
+                   * :GetLatestVimScripts command
+                   * (runtimepath)/GetLatest/GetLatestVimScripts.dat
+                     now holds scripts that need updating
+v10 Apr 19, 2004 : * moved history from script to doc
+v9  Jan 23, 2004 :   windows (win32/win16/win95) will use
+                     double quotes ("") whereas other systems will use
+                     single quotes ('') around the urls in calls via wget
+v8  Dec 01, 2003 :   makes three tries at downloading
+v7  Sep 02, 2003 :   added error messages if "Click on..." or "src_id="
+                     not found in downloaded webpage
+                     Uses t_ti, t_te, and rs to make progress visible
+v6  Aug 06, 2003 :   final status messages now display summary of work
+                     ( "Downloaded someqty scripts" or
+                       "Everything was current")
+                     Now GetLatestVimScripts is careful about downloading
+                     GetLatestVimScripts.vim itself!
+                     (goes to <NEW_GetLatestVimScripts.vim>)
+v5  Aug 04, 2003 :   missing an endif near bottom
+v4  Jun 17, 2003 :   redraw! just before each "considering" message
+v3  May 27, 2003 :   Protects downloaded files from errant shell
+                     expansions with single quotes: '...'
+v2  May 14, 2003 :   extracts name of item to be obtained from the
+                     script file.  Uses it instead of comment field
+                     for output filename; comment is used in the
+                     "considering..." line and is now just a comment!
+                   * Fixed a bug: a string-of-numbers is not the
+                     same as a number, so I added zero to them
+                     and they became numbers.  Fixes comparison.
+
+==============================================================================
+vim:tw=78:ts=8:ft=help:fdm=marker
--- /dev/null
+++ b/lib/vimfiles/doc/pi_gzip.txt
@@ -1,0 +1,39 @@
+*pi_gzip.txt*   For Vim version 7.1.  Last change: 2002 Oct 29
+
+
+		  VIM REFERENCE MANUAL    by Bram Moolenaar
+
+
+Editing compressed files with Vim		*gzip* *bzip2* *compress*
+
+1. Autocommands			|gzip-autocmd|
+
+The functionality mentioned here is a |standard-plugin|.
+This plugin is only available if 'compatible' is not set.
+You can avoid loading this plugin by setting the "loaded_gzip" variable: >
+	:let loaded_gzip = 1
+
+{Vi does not have any of this}
+
+==============================================================================
+1. Autocommands						*gzip-autocmd*
+
+The plugin installs autocommands to intercept reading and writing of files
+with these extensions:
+
+	extension	compression ~
+	*.Z		compress (Lempel-Ziv)
+	*.gz		gzip
+	*.bz2		bzip2
+
+That's actually the only thing you need to know.  There are no options.
+
+After decompressing a file, the filetype will be detected again.  This will
+make a file like "foo.c.gz" get the "c" filetype.
+
+If you have 'patchmode' set, it will be appended after the extension for
+compression.  Thus editing the patchmode file will not give you the automatic
+decompression.  You have to rename the file if you want this.
+
+==============================================================================
+ vim:tw=78:ts=8:ft=help:norl:
--- /dev/null
+++ b/lib/vimfiles/doc/pi_netrw.txt
@@ -1,0 +1,2160 @@
+*pi_netrw.txt*  For Vim version 7.1.  Last change: 2007 May 08
+
+	    -----------------------------------------------------
+	    NETRW REFERENCE MANUAL    by Charles E. Campbell, Jr.
+	    -----------------------------------------------------
+
+
+*dav*           *http*          *network*       *Nwrite*   *netrw-file*
+*fetch*         *netrw*         *Nread*         *rcp*      *scp*
+*ftp*           *netrw.vim*     *Nsource*       *rsync*    *sftp*
+
+==============================================================================
+1. Contents						*netrw-contents*
+
+1.  Contents.............................................|netrw-contents|
+2.  Starting With Netrw..................................|netrw-start|
+3.  Netrw Reference......................................|netrw-ref|
+      CONTROLLING EXTERNAL APPLICATIONS..................|netrw-externapp|
+      READING............................................|netrw-read|
+      WRITING............................................|netrw-write|
+      DIRECTORY LISTING..................................|netrw-dirlist|
+      CHANGING THE USERID AND PASSWORD...................|netrw-chgup|
+      VARIABLES..........................................|netrw-variables|
+      PATHS..............................................|netrw-path|
+4.  Network-Oriented File Transfer.......................|netrw-xfer|
+      NETRC..............................................|netrw-netrc|
+      PASSWORD...........................................|netrw-passwd|
+5.  Activation...........................................|netrw-activate|
+6.  Transparent File Transfer............................|netrw-transparent|
+7.  Ex Commands..........................................|netrw-ex|
+8.  Variables and Options................................|netrw-var|
+9.  Directory Browsing...................................|netrw-browse| {{{1
+      Maps...............................................|netrw-maps|
+      Exploring..........................................|netrw-explore-cmds|
+      Quick Reference Commands Table.....................|netrw-browse-cmds|
+      Netrw Browser Variables............................|netrw-browse-var|
+      Introduction To Directory Browsing.................|netrw-browse-intro|
+      Netrw Browsing And Option Incompatibilities........|netrw-incompatible|
+      Directory Exploring Commands.......................|netrw-explore|
+      Refreshing The Listing.............................|netrw-ctrl-l|
+      Going Up...........................................|netrw--|
+      Browsing...........................................|netrw-cr|
+      Obtaining A File...................................|netrw-O|
+      Change Listing Style...............................|netrw-i|
+      Making A New Directory.............................|netrw-d|
+      Deleting Files Or Directories......................|netrw-D|
+      Renaming Files Or Directories......................|netrw-move|
+      Hiding Files Or Directories........................|netrw-a|
+      Edit File Or Directory Hiding List.................|netrw-ctrl-h|
+      Browsing With A Horizontally Split Window..........|netrw-o|
+      Browsing With A Vertically Split Window............|netrw-v|
+      Browsing With A New Tab............................|netrw-t|
+      Preview Window.....................................|netrw-p|
+      Selecting Sorting Style............................|netrw-s|
+      Editing The Sorting Sequence.......................|netrw-S|
+      Reversing Sorting Order............................|netrw-r|
+      Changing To A Predecessor Directory................|netrw-u|
+      Changing To A Successor Directory..................|netrw-U|
+      Customizing Browsing With A User Function..........|netrw-x|
+      Making The Browsing Directory The Current Directory|netrw-c|
+      Bookmarking A Directory............................|netrw-mb|
+      Changing To A Bookmarked Directory.................|netrw-gb|
+      Listing Bookmarks And History......................|netrw-q|
+      Improving Directory Browsing.......................|netrw-listhack| }}}1
+10. Problems and Fixes...................................|netrw-problems|
+11. Debugging............................................|netrw-debug|
+12. History..............................................|netrw-history|
+13. Credits..............................................|netrw-credits|
+
+The Netrw plugin is generally sourced automatically as it is a
+|standard-plugin|.  That said, to make use of netrw, one must
+have plugins available which can be done with the following
+two lines in your <.vimrc>: >
+
+	set nocp                    " 'compatible' is not set
+	filetype plugin on          " plugins are enabled
+<
+You can avoid loading this plugin by setting the "loaded_netrw" variable
+in your <.vimrc> file: >
+
+	:let loaded_netrw = 1
+
+{Vi does not have any of this}
+
+==============================================================================
+2. Starting With Netrw						*netrw-start*
+
+Netrw makes reading, writing, and browsing over a network connection easy!
+First, make sure that you have plugins enabled, so you'll need to have at
+least the following in your <.vimrc>: (or see |netrw-activate|) >
+
+	set nocp                    " 'compatible' is not set
+	filetype plugin on          " plugins are enabled
+<
+(see |'cp'| and |:filetype-plugin-on|)
+
+Netrw supports "transparent" editing of files on other machines using urls
+(see |netrw-transparent|). As an example of this, let's assume you have an
+account on some other machine; try >
+
+	vim scp://hostname/path/to/file
+<
+if you have an ssh connection.  Want to make ssh/scp easier to use? Check
+out |netrw-listhack|!
+
+What if you have ftp, not ssh/scp?  That's easy, too; try >
+
+	vim ftp://hostname/path/to/file
+<
+Want to make ftp simpler to use?  See if your ftp supports a file called
+<.netrc> -- typically it goes in your home directory, has read/write
+permissions for only the user to read (ie. not group, world, other, etc),
+and has lines resembling >
+
+	machine HOSTNAME login USERID password "PASSWORD"
+	machine HOSTNAME login USERID password "PASSWORD"
+	...
+	default          login USERID password "PASSWORD"
+<
+Now about browsing -- ie. when you just want to look around before editing a
+file.  For browsing on your current host, just "edit" a directory: >
+
+	vim .
+	vim /home/userid/path
+<
+For browsing on a remote host, "edit" a directory (but make sure that
+the directory name is followed by a "/"): >
+
+	vim scp://hostname/
+	vim ftp://hostname/path/to/dir/
+<
+See |netrw-browse| for more!
+
+There's more protocols supported than scp and ftp, too: see the next
+section, |netrw-externapp|.
+
+==============================================================================
+3. Netrw Reference						*netrw-ref*
+
+CONTROLLING EXTERNAL APPLICATIONS			*netrw-externapp*
+
+	Protocol  Variable	    Default Value
+	--------  ----------------  -------------
+	   dav:    *g:netrw_dav_cmd*  = "cadaver"
+	 fetch:  *g:netrw_fetch_cmd*  = "fetch -o"    if fetch is available
+	   ftp:    *g:netrw_ftp_cmd*  = "ftp"
+	  http:   *g:netrw_http_cmd*  = "curl -o"     if      curl  is available
+	  http:    g:netrw_http_cmd   = "wget -q -O"  else if wget  is available
+          http:    g:netrw_http_cmd   = "fetch -o"    else if fetch is available
+	   rcp:    *g:netrw_rcp_cmd*  = "rcp"
+	 rsync:  *g:netrw_rsync_cmd*  = "rsync -a"
+	   scp:    *g:netrw_scp_cmd*  = "scp -q"
+	  sftp:   *g:netrw_sftp_cmd*  = "sftp"
+
+READING						*netrw-read* *netrw-nread*
+	:Nread ?					give help
+	:Nread "machine:path"				uses rcp
+	:Nread "machine path"				uses ftp w/ <.netrc>
+	:Nread "machine id password path"		uses ftp
+	:Nread "dav://machine[:port]/path"		uses cadaver
+	:Nread "fetch://[user@]machine/path"		uses fetch
+	:Nread "ftp://[user@]machine[[:#]port]/path"	uses ftp w/ <.netrc>
+	:Nread "http://[user@]machine/path"		uses http  uses wget
+	:Nread "rcp://[user@]machine/path"		uses rcp
+	:Nread "rsync://[user@]machine[:port]/path"	uses rsync
+	:Nread "scp://[user@]machine[[:#]port]/path"	uses scp
+	:Nread "sftp://[user@]machine/path"		uses sftp
+
+WRITING						*netrw-write* *netrw-nwrite*
+	:Nwrite ?					give help
+	:Nwrite "machine:path"				uses rcp
+	:Nwrite "machine path"				uses ftp w/ <.netrc>
+	:Nwrite "machine id password path"		uses ftp
+	:Nwrite "dav://machine[:port]/path"		uses cadaver
+	:Nwrite "ftp://[user@]machine[[:#]port]/path"	uses ftp w/ <.netrc>
+	:Nwrite "rcp://[user@]machine/path"		uses rcp
+	:Nwrite "rsync://[user@]machine[:port]/path"	uses rsync
+	:Nwrite "scp://[user@]machine[[:#]port]/path"	uses scp
+	:Nwrite "sftp://[user@]machine/path"		uses sftp
+	http: not supported!
+
+SOURCING					*netrw-source*
+	:Nsource ?					give help
+	:Nsource "dav://machine[:port]/path"		uses cadaver
+	:Nsource "fetch://[user@]machine/path"		uses fetch
+	:Nsource "ftp://[user@]machine[[:#]port]/path"	uses ftp w/ <.netrc>
+	:Nsource "http://[user@]machine/path"		uses http  uses wget
+	:Nsource "rcp://[user@]machine/path"		uses rcp
+	:Nsource "rsync://[user@]machine[:port]/path"	uses rsync
+	:Nsource "scp://[user@]machine[[:#]port]/path"	uses scp
+	:Nsource "sftp://[user@]machine/path"		uses sftp
+
+DIRECTORY LISTING					*netrw-dirlist*
+	:Nread [protocol]://[user]@hostname/path/
+
+						*netrw-login* *netrw-password*
+ CHANGING USERID AND PASSWORD			*netrw-chgup* *netrw-userpass*
+
+	Attempts to use ftp will prompt you for a user-id and a password.
+	These will be saved in global variables g:netrw_uid and
+	g:netrw_passwd; subsequent uses of ftp will re-use those two items to
+	simplify the further use of ftp.  However, if you need to use a
+	different user id and/or password, you'll want to call NetUserPass()
+	first.  To work around the need to enter passwords, check if your ftp
+	supports a <.netrc> file in your home directory.  Also see
+	|netrw-passwd| (and if you're using ssh/scp hoping to figure out how
+	to not need to use passwords, look at |netrw-listhack|).
+
+	:NetUserPass [uid [password]]		-- prompts as needed
+	:call NetUserPass()			-- prompts for uid and password
+	:call NetUserPass("uid")		-- prompts for password
+	:call NetUserPass("uid","password")	-- sets global uid and password
+
+VARIABLES						*netrw-variables*
+
+(also see: |netrw-browse-var| |netrw-protocol| |netrw-settings| |netrw-var|)
+
+ *b:netrw_lastfile*	last file Network-read/written retained on a per-buffer
+			basis		(supports plain :Nw )
+
+ *g:netrw_ftp*		if it doesn't exist, use default ftp
+			=0 use default ftp		       (uid password)
+			=1 use alternate ftp method	  (user uid password)
+			If you're having trouble with ftp, try changing the
+			value of this variable to see if the alternate ftp
+			method works for your setup.
+
+ *g:netrw_extracmd*	default: doesn't exist
+                        If this variable exists, then any string it contains
+			will be placed into the commands set to your ftp
+			client.  As an example:
+			  ="passive"
+
+ *g:netrw_ftpmode*	="binary"				    (default)
+			="ascii"
+
+ *g:netrw_ignorenetrc*	=0 (default for linux, cygwin)
+			=1 If you have a <.netrc> file but it doesn't work and
+			   you want it ignored, then set this variable as shown.
+			   (default for Windows + cmd.exe)
+
+ *g:netrw_menu*		=0 disable netrw's menu
+			=1 (default) netrw's menu enabled
+
+ *g:netrw_nogx*		if this variable exists, then the "gx" map will not
+			be available (see |netrw-gx|)
+
+ *g:netrw_uid*		(ftp) user-id,      retained on a per-session basis
+ *g:netrw_passwd*	(ftp) password,     retained on a per-session basis
+
+ *g:netrw_shq*		= "'" for Unix/Linux systems (ie. a single quote)
+			= "'" for Windows + cygwin systems (ie. a single quote)
+			= '"' for Windows systems, not using cygwin
+			      (ie. a double quote)
+			Controls the quoting character used during scp and ftp
+			commands.
+
+ *g:netrw_scpport*      = "-P" : option to use to set port for scp
+ *g:netrw_sshport*      = "-p" : option to use to set port for ssh
+
+ *g:netrw_use_errorwindow* =1 : messages from netrw will use a separate one
+                                line window.  This window provides reliable
+				delivery of messages. (default)
+			   =0 : messages from netrw will use echoerr ;
+			        messages don't always seem to show up this
+				way, but one doesn't have to quit the window.
+
+ *g:netrw_win95ftp*	=1 if using Win95, will remove four trailing blank
+			   lines that o/s's ftp "provides" on transfers
+			=0 force normal ftp behavior (no trailing line removal)
+
+ *g:netrw_cygwin*	=1 assume scp under windows is from cygwin. Also
+			   permits network browsing to use ls with time and
+			   size sorting (default if windows)
+			=0 assume Windows' scp accepts windows-style paths
+			   Network browsing uses dir instead of ls
+			This option is ignored if you're using unix
+
+ *g:netrw_use_nt_rcp*	=0 don't use the rcp of WinNT, Win2000 and WinXP
+			=1 use WinNT's rcp in binary mode         (default)
+
+PATHS								*netrw-path*
+
+Paths to files are generally user-directory relative for most protocols.
+It is possible that some protocol will make paths relative to some
+associated directory, however.
+>
+	example:  vim scp://user@host/somefile
+	example:  vim scp://user@host/subdir1/subdir2/somefile
+<
+where "somefile" is the "user"'s home directory.  If you wish to get a
+file using root-relative paths, use the full path:
+>
+	example:  vim scp://user@host//somefile
+	example:  vim scp://user@host//subdir1/subdir2/somefile
+<
+
+==============================================================================
+4. Network-Oriented File Transfer				*netrw-xfer*
+
+Network-oriented file transfer under Vim is implemented by a VimL-based script
+(<netrw.vim>) using plugin techniques.  It currently supports both reading and
+writing across networks using rcp, scp, ftp or ftp+<.netrc>, scp, fetch,
+dav/cadaver, rsync, or sftp.
+
+http is currently supported read-only via use of wget or fetch.
+
+<netrw.vim> is a standard plugin which acts as glue between Vim and the
+various file transfer programs.  It uses autocommand events (BufReadCmd,
+FileReadCmd, BufWriteCmd) to intercept reads/writes with url-like filenames. >
+
+	ex. vim ftp://hostname/path/to/file
+<
+The characters preceding the colon specify the protocol to use; in the
+example, its ftp.  The <netrw.vim> script then formulates a command or a
+series of commands (typically ftp) which it issues to an external program
+(ftp, scp, etc) which does the actual file transfer/protocol.  Files are read
+from/written to a temporary file (under Unix/Linux, /tmp/...) which the
+<netrw.vim> script will clean up.
+
+				*netrw-putty* *netrw-pscp* *netrw-psftp*
+One may modify any protocol's implementing external application by setting a
+variable (ex. scp uses the variable g:netrw_scp_cmd, which is defaulted to
+"scp -q").  As an example, consider using PuTTY: >
+
+	let g:netrw_scp_cmd = '"c:\Program Files\PuTTY\pscp.exe" -q -batch'
+	let g:netrw_sftp_cmd= '"c:\Program Files\PuTTY\psftp.exe"'
+<
+See |netrw-p8| for more about putty, pscp, psftp, etc.
+
+Ftp, an old protocol, seems to be blessed by numerous implementations.
+Unfortunately, some implementations are noisy (ie., add junk to the end of the
+file).  Thus, concerned users may decide to write a NetReadFixup() function
+that will clean up after reading with their ftp.  Some Unix systems (ie.,
+FreeBSD) provide a utility called "fetch" which uses the ftp protocol but is
+not noisy and more convenient, actually, for <netrw.vim> to use.
+Consequently, if "fetch" is executable, it will be used to do reads for
+ftp://... (and http://...) .  See |netrw-var| for more about this.
+
+For rcp, scp, sftp, and http, one may use network-oriented file transfers
+transparently; ie.
+>
+	vim rcp://[user@]machine/path
+	vim scp://[user@]machine/path
+<
+If your ftp supports <.netrc>, then it too can be just as transparently used
+if the needed triad of machine name, user id, and password are present in
+that file.  Your ftp must be able to use the <.netrc> file on its own, however.
+>
+	vim ftp://[user@]machine[[:#]portnumber]/path
+<
+However, ftp will often need to query the user for the userid and password.
+The latter will be done "silently"; ie. asterisks will show up instead of
+the actually-typed-in password.  Netrw will retain the userid and password
+for subsequent read/writes from the most recent transfer so subsequent
+transfers (read/write) to or from that machine will take place without
+additional prompting.
+
+								*netrw-urls*
+  +=================================+============================+============+
+  |  Reading                        | Writing                    |  Uses      |
+  +=================================+============================+============+
+  | DAV:                            |                            |            |
+  |  dav://host/path                |                            | cadaver    |
+  |  :Nread dav://host/path         | :Nwrite dav://host/path    | cadaver    |
+  +---------------------------------+----------------------------+------------+
+  | FETCH:                          |                            |            |
+  |  fetch://[user@]host/path       |                            |            |
+  |  fetch://[user@]host:http/path  |  Not Available             | fetch      |
+  |  :Nread fetch://[user@]host/path|                            |            |
+  +---------------------------------+----------------------------+------------+
+  | FILE:                           |                            |            |
+  |  file:///*                      | file:///*                  |            |
+  |  file://localhost/*             | file://localhost/*         |            |
+  +---------------------------------+----------------------------+------------+
+  | FTP:          (*3)              |              (*3)          |            |
+  |  ftp://[user@]host/path         | ftp://[user@]host/path     | ftp  (*2)  |
+  |  :Nread ftp://host/path         | :Nwrite ftp://host/path    | ftp+.netrc |
+  |  :Nread host path               | :Nwrite host path          | ftp+.netrc |
+  |  :Nread host uid pass path      | :Nwrite host uid pass path | ftp        |
+  +---------------------------------+----------------------------+------------+
+  | HTTP: wget is executable: (*4)  |                            |            |
+  |  http://[user@]host/path        |        Not Available       | wget       |
+  +---------------------------------+----------------------------+------------+
+  | HTTP: fetch is executable (*4)  |                            |            |
+  |  http://[user@]host/path        |        Not Available       | fetch      |
+  +---------------------------------+----------------------------+------------+
+  | RCP:                            |                            |            |
+  |  rcp://[user@]host/path         | rcp://[user@]host/path     | rcp        |
+  +---------------------------------+----------------------------+------------+
+  | RSYNC:                          |                            |            |
+  |  rsync://[user@]host/path       | rsync://[user@]host/path   | rsync      |
+  |  :Nread rsync://host/path       | :Nwrite rsync://host/path  | rsync      |
+  |  :Nread rcp://host/path         | :Nwrite rcp://host/path    | rcp        |
+  +---------------------------------+----------------------------+------------+
+  | SCP:                            |                            |            |
+  |  scp://[user@]host/path         | scp://[user@]host/path     | scp        |
+  |  :Nread scp://host/path         | :Nwrite scp://host/path    | scp  (*1)  |
+  +---------------------------------+----------------------------+------------+
+  | SFTP:                           |                            |            |
+  |  sftp://[user@]host/path        | sftp://[user@]host/path    | sftp       |
+  |  :Nread sftp://host/path        | :Nwrite sftp://host/path   | sftp  (*1) |
+  +=================================+============================+============+
+
+	(*1) For an absolute path use scp://machine//path.
+
+	(*2) if <.netrc> is present, it is assumed that it will
+	work with your ftp client.  Otherwise the script will
+	prompt for user-id and password.
+
+        (*3) for ftp, "machine" may be machine#port or machine:port
+	if a different port is needed than the standard ftp port
+
+	(*4) for http:..., if wget is available it will be used.  Otherwise,
+	if fetch is available it will be used.
+
+Both the :Nread and the :Nwrite ex-commands can accept multiple filenames.
+
+
+NETRC							*netrw-netrc*
+
+The typical syntax for lines in a <.netrc> file is given as shown below.
+Ftp under Unix usually supports <.netrc>; ftp under Windows usually doesn't.
+>
+	machine {full machine name} login {user-id} password "{password}"
+	default login {user-id} password "{password}"
+
+Your ftp client must handle the use of <.netrc> on its own, but if the
+<.netrc> file exists, an ftp transfer will not ask for the user-id or
+password.
+
+	Note:
+	Since this file contains passwords, make very sure nobody else can
+	read this file!  Most programs will refuse to use a .netrc that is
+	readable for others.  Don't forget that the system administrator can
+	still read the file!
+
+
+PASSWORD						*netrw-passwd*
+
+The script attempts to get passwords for ftp invisibly using |inputsecret()|,
+a built-in Vim function.  See |netrw-uidpass| for how to change the password
+after one has set it.
+
+Unfortunately there doesn't appear to be a way for netrw to feed a password to
+scp.  Thus every transfer via scp will require re-entry of the password.
+However, |netrw-listhack| can help with this problem.
+
+
+==============================================================================
+5. Activation						*netrw-activate*
+
+Network-oriented file transfers are available by default whenever Vim's
+|'nocompatible'| mode is enabled.  The <netrw.vim> file resides in your
+system's vim-plugin directory and is sourced automatically whenever you bring
+up vim.  I suggest that, at a minimum, you have at least the following in your
+<.vimrc> customization file: >
+
+	set nocp
+	if version >= 600
+	  filetype plugin indent on
+	endif
+<
+
+==============================================================================
+6. Transparent File Transfer				*netrw-transparent*
+
+Transparent file transfers occur whenever a regular file read or write
+(invoked via an |:autocmd| for |BufReadCmd| or |BufWriteCmd| events) is made.
+Thus one may use files across networks just as simply as if they were local. >
+
+	vim ftp://[user@]machine/path
+	...
+	:wq
+
+See |netrw-activate| for more on how to encourage your vim to use plugins
+such as netrw.
+
+
+==============================================================================
+7. Ex Commands						*netrw-ex*
+
+The usual read/write commands are supported.  There are also a few
+additional commands available.  Often you won't need to use Nw or
+Nread as shown in |netrw-transparent| (ie. simply use >
+  :e url
+  :r url
+  :w url
+instead, as appropriate) -- see |netrw-urls|.  In the explanations
+below, a {netfile} is an url to a remote file.
+
+:[range]Nw	Write the specified lines to the current
+		file as specified in b:netrw_lastfile.
+
+:[range]Nw {netfile} [{netfile}]...
+		Write the specified lines to the {netfile}.
+
+:Nread		Read the specified lines into the current
+		buffer from the file specified in
+		b:netrw_lastfile.
+
+:Nread {netfile} {netfile}...
+		Read the {netfile} after the current line.
+
+:Nsource {netfile}
+		Source the {netfile}.
+		To start up vim using a remote .vimrc, one may use
+		the following (all on one line) (tnx to Antoine Mechelynck) >
+		vim -u NORC -N
+		 --cmd "runtime plugin/netrwPlugin.vim"
+		 --cmd "source scp://HOSTNAME/.vimrc"
+<								*netrw-uidpass*
+:call NetUserPass()
+		If b:netrw_uid and b:netrw_passwd don't exist,
+		this function query the user for them.
+
+:call NetUserPass("userid")
+		This call will set the b:netrw_uid and, if
+		the password doesn't exist, will query the user for it.
+
+:call NetUserPass("userid","passwd")
+		This call will set both the b:netrw_uid and b:netrw_passwd.
+		The user-id and password are used by ftp transfers.  One may
+		effectively remove the user-id and password by using ""
+		strings.
+
+:NetrwSettings  This command is described in |netrw-settings| -- used to
+                display netrw settings and change netrw behavior.
+
+
+==============================================================================
+8. Variables and Options			*netrw-options* *netrw-var*
+
+The <netrw.vim> script provides several variables which act as options to
+ffect <netrw.vim>'s behavior.  These variables typically may be set in the
+user's <.vimrc> file:
+(also see:
+|netrw-settings| |netrw-browse-var| |netrw-protocol| |netrw-settings|) >
+
+                        -------------
+                        Netrw Options
+                        -------------
+	Option			Meaning
+	--------------		-----------------------------------------------
+<
+        b:netrw_col             Holds current cursor position (during NetWrite)
+        g:netrw_cygwin          =1 assume scp under windows is from cygwin
+                                                              (default/windows)
+                                =0 assume scp under windows accepts windows
+                                   style paths                (default/else)
+        g:netrw_ftp             =0 use default ftp            (uid password)
+        g:netrw_ftpmode         ="binary"                     (default)
+                                ="ascii"                      (your choice)
+	g:netrw_ignorenetrc     =1                            (default)
+	                           if you have a <.netrc> file but you don't
+				   want it used, then set this variable.  Its
+				   mere existence is enough to cause <.netrc>
+				   to be ignored.
+        b:netrw_lastfile        Holds latest method/machine/path.
+        b:netrw_line            Holds current line number     (during NetWrite)
+        g:netrw_passwd          Holds current password for ftp.
+	g:netrw_silent          =0 transfers done normally
+	                        =1 transfers done silently
+        g:netrw_uid             Holds current user-id for ftp.
+                                =1 use alternate ftp         (user uid password)
+                                (see |netrw-options|)
+        g:netrw_use_nt_rcp      =0 don't use WinNT/2K/XP's rcp (default)
+                                =1 use WinNT/2K/XP's rcp, binary mode
+        g:netrw_win95ftp        =0 use unix-style ftp even if win95/98/ME/etc
+                                =1 use default method to do ftp >
+	-----------------------------------------------------------------------
+<
+The script will also make use of the following variables internally, albeit
+temporarily.
+>
+			     -------------------
+			     Temporary Variables
+			     -------------------
+	Variable		Meaning
+	--------		------------------------------------
+<
+	g:netrw_method		Index indicating rcp/ftp+.netrc/ftp
+	g:netrw_machine		Holds machine name parsed from input
+	g:netrw_fname		Holds filename being accessed >
+	------------------------------------------------------------
+<
+								*netrw-protocol*
+
+Netrw supports a number of protocols.  These protocols are invoked using the
+variables listed below, and may be modified by the user.
+>
+			   ------------------------
+                           Protocol Control Options
+			   ------------------------
+    Option            Type        Setting         Meaning
+    ---------         --------    --------------  ---------------------------
+<
+    netrw_ftp         variable    =doesn't exist  userid set by "user userid"
+                                  =0              userid set by "user userid"
+                                  =1              userid set by "userid"
+    NetReadFixup      function    =doesn't exist  no change
+                                  =exists         Allows user to have files
+                                                  read via ftp automatically
+                                                  transformed however they wish
+                                                  by NetReadFixup()
+    g:netrw_dav_cmd    variable   ="cadaver"
+    g:netrw_fetch_cmd  variable   ="fetch -o"     if fetch is available
+    g:netrw_ftp_cmd    variable   ="ftp"
+    g:netrw_http_cmd   variable   ="fetch -o"     if      fetch is available
+    g:netrw_http_cmd   variable   ="wget -O"      else if wget  is available
+    g:netrw_list_cmd   variable   ="ssh USEPORT HOSTNAME ls -Fa"
+    g:netrw_rcp_cmd    variable   ="rcp"
+    g:netrw_rsync_cmd  variable   ="rsync -a"
+    g:netrw_scp_cmd    variable   ="scp -q"
+    g:netrw_sftp_cmd   variable   ="sftp" >
+    -------------------------------------------------------------------------
+<
+								*netrw-ftp*
+
+The g:netrw_..._cmd options (|g:netrw_ftp_cmd| and |g:netrw_sftp_cmd|)
+specify the external program to use handle the ftp protocol.  They may
+include command line options (such as -p for passive mode).
+
+Browsing is supported by using the |g:netrw_list_cmd|; the substring
+"HOSTNAME" will be changed via substitution with whatever the current request
+is for a hostname.
+
+Two options (|g:netrw_ftp| and |netrw-fixup|) both help with certain ftp's
+that give trouble .  In order to best understand how to use these options if
+ftp is giving you troubles, a bit of discussion is provided on how netrw does
+ftp reads.
+
+For ftp, netrw typically builds up lines of one of the following formats in a
+temporary file:
+>
+  IF g:netrw_ftp !exists or is not 1     IF g:netrw_ftp exists and is 1
+  ----------------------------------     ------------------------------
+<
+       open machine [port]                    open machine [port]
+       user userid password                   userid password
+       [g:netrw_ftpmode]                      password
+       [g:netrw_extracmd]                     [g:netrw_ftpmode]
+       get filename tempfile                  [g:netrw_extracmd]
+                                              get filename tempfile >
+  ---------------------------------------------------------------------
+<
+The |g:netrw_ftpmode| and |g:netrw_extracmd| are optional.
+
+Netrw then executes the lines above by use of a filter:
+>
+	:%! {g:netrw_ftp_cmd} -i [-n]
+<
+where
+	g:netrw_ftp_cmd is usually "ftp",
+	-i tells ftp not to be interactive
+	-n means don't use netrc and is used for Method #3 (ftp w/o <.netrc>)
+
+If <.netrc> exists it will be used to avoid having to query the user for
+userid and password.  The transferred file is put into a temporary file.
+The temporary file is then read into the main editing session window that
+requested it and the temporary file deleted.
+
+If your ftp doesn't accept the "user" command and immediately just demands a
+userid, then try putting "let netrw_ftp=1" in your <.vimrc>.
+
+								*netrw-cadaver*
+To handle the SSL certificate dialog for untrusted servers, one may pull
+down the certificate and place it into /usr/ssl/cert.pem.  This operation
+renders the server treatment as "trusted".
+
+						*netrw-fixup* *netreadfixup*
+If your ftp for whatever reason generates unwanted lines (such as AUTH
+messages) you may write a NetReadFixup(tmpfile) function:
+>
+    function! NetReadFixup(method,line1,line2)
+      " a:line1: first new line in current file
+      " a:line2: last  new line in current file
+      if     a:method == 1 "rcp
+      elseif a:method == 2 "ftp + <.netrc>
+      elseif a:method == 3 "ftp + machine,uid,password,filename
+      elseif a:method == 4 "scp
+      elseif a:method == 5 "http/wget
+      elseif a:method == 6 "dav/cadaver
+      elseif a:method == 7 "rsync
+      elseif a:method == 8 "fetch
+      elseif a:method == 9 "sftp
+      else               " complain
+      endif
+    endfunction
+>
+The NetReadFixup() function will be called if it exists and thus allows you to
+customize your reading process.  As a further example, <netrw.vim> contains
+just such a function to handle Windows 95 ftp.  For whatever reason, Windows
+95's ftp dumps four blank lines at the end of a transfer, and so it is
+desirable to automate their removal.  Here's some code taken from <netrw.vim>
+itself:
+>
+    if has("win95") && g:netrw_win95ftp
+     fun! NetReadFixup(method, line1, line2)
+       if method == 3   " ftp (no <.netrc>)
+        let fourblanklines= line2 - 3
+        silent fourblanklines.",".line2."g/^\s*/d"
+       endif
+     endfunction
+    endif
+>
+
+==============================================================================
+9. Directory Browsing	*netrw-browse* *netrw-dir* *netrw-list* *netrw-help*
+
+MAPS								*netrw-maps*
+     <F1>.............Help.......................................|netrw-help|
+     <cr>.............Browsing...................................|netrw-cr|
+     <del>............Deleting Files or Directories..............|netrw-delete|
+     -................Going Up...................................|netrw--|
+     a................Hiding Files or Directories................|netrw-a|
+     mb...............Bookmarking a Directory....................|netrw-mb|
+     gb...............Changing to a Bookmarked Directory.........|netrw-gb|
+     c................Make Browsing Directory The Current Dir....|netrw-c|
+     d................Make A New Directory.......................|netrw-d|
+     D................Deleting Files or Directories..............|netrw-D|
+     <c-h>............Edit File/Directory Hiding List............|netrw-ctrl-h|
+     i................Change Listing Style.......................|netrw-i|
+     <c-l>............Refreshing the Listing.....................|netrw-ctrl-l|
+     o................Browsing with a Horizontal Split...........|netrw-o|
+     p................Preview Window.............................|netrw-p|
+     q................Listing Bookmarks and History..............|netrw-q|
+     r................Reversing Sorting Order....................|netrw-r|
+     R................Renaming Files or Directories..............|netrw-R|
+     s................Selecting Sorting Style....................|netrw-s|
+     S................Editing the Sorting Sequence...............|netrw-S|
+     t................Browsing with a new tab....................|netrw-t|
+     u................Changing to a Predecessor Directory........|netrw-u|
+     U................Changing to a Successor Directory..........|netrw-U|
+     v................Browsing with a Vertical Split.............|netrw-v|
+     x................Customizing Browsing.......................|netrw-x|
+
+    COMMANDS						*netrw-explore-cmds*
+     :Explore[!]  [dir] Explore directory of current file........|netrw-explore|
+     :Sexplore[!] [dir] Split & Explore directory ...............|netrw-explore|
+     :Hexplore[!] [dir] Horizontal Split & Explore...............|netrw-explore|
+     :Vexplore[!] [dir] Vertical Split & Explore.................|netrw-explore|
+     :Texplore[!] [dir] Tab & Explore............................|netrw-explore|
+     :Pexplore[!] [dir] Vertical Split & Explore.................|netrw-explore|
+     :Nexplore[!] [dir] Vertical Split & Explore.................|netrw-explore|
+     :NetrwSettings.............................................|netrw-settings|
+
+QUICK REFERENCE COMMANDS TABLE				*netrw-browse-cmds*
+>
+        -------	-----------
+	Command	Explanation
+        -------	-----------
+<	<F1>	Causes Netrw to issue help
+	 <cr>	Netrw will enter the directory or read the file |netrw-cr|
+	 <del>	Netrw will attempt to remove the file/directory |netrw-del|
+	   -	Makes Netrw go up one directory |netrw--|
+	   a	Toggles between normal display, |netrw-a|
+		 hiding (suppress display of files matching g:netrw_list_hide)
+		 showing (display only files which match g:netrw_list_hide)
+	   mb	bookmark current directory
+	   gb	go to previous bookmarked directory
+	   c	Make current browsing directory the current directory |netrw-c|
+	   d	Make a directory |netrw-d|
+	   D	Netrw will attempt to remove the file(s)/directory(ies) |netrw-D|
+	 <c-h>	Edit file hiding list |netrw-ctrl-h|
+	   i	Cycle between thin, long, wide, and tree listings|netrw-i|
+	 <c-l>	Causes Netrw to refresh the directory listing |netrw-ctrl-l|
+	   o	Enter the file/directory under the cursor in a new browser
+		 window.  A horizontal split is used. |netrw-o|
+	   O	Obtain a file specified by cursor |netrw-O|
+	   p	Preview the file |netrw-p|
+	   P	Browse in the previously used window |netrw-P|
+	   q	List bookmarked directories and history |netrw-q|
+	   r	Reverse sorting order |netrw-r|
+	   R	Rename the designed file(s)/directory(ies) |netrw-R|
+	   s	Select sorting style: by name, time, or file size |netrw-s|
+	   S	Specify suffix priority for name-sorting |netrw-S|
+	   t	Enter the file/directory under the cursor in a new tab|netrw-t|
+	   u	Change to recently-visited directory |netrw-u|
+	   U	Change to subsequently-visited directory |netrw-U|
+	   v	Enter the file/directory under the cursor in a new browser
+		 window.  A vertical split is used. |netrw-v|
+	   x	Apply a function to a file. (special browsers) |netrw-x|
+
+NETRW BROWSER VARIABLES					*netrw-browse-var*
+>
+   ---				-----------
+   Var				Explanation
+   ---				-----------
+< *g:netrw_alto*		change from above splitting to below splitting
+				by setting this variable (see |netrw-o|)
+				 default: =&sb           (see |'sb'|)
+
+  *g:netrw_altv*		change from left splitting to right splitting
+				by setting this variable (see |netrw-v|)
+				 default: =&spr          (see |'spr'|)
+
+  *g:netrw_browse_split*	when browsing, <cr> will open the file by:
+				=0: re-using the same window
+				=1: horizontally splitting the window first  
+				=2: vertically   splitting the window first  
+				=3: open file in new tab
+
+  *g:netrw_browsex_viewer*	specify user's preference for a viewer: >
+					"kfmclient exec"
+					"gnome-open"
+<				If >
+					"-"
+<				is used, then netrwFileHandler() will look for
+				a script/function to handle the given
+				extension.  (see |netrw_filehandler|).
+
+  *g:netrw_fastbrowse*		=0: slow speed browsing, never re-use
+				    directory listings; always obtain
+				    directory listings.
+				=1: medium speed browsing, re-use directory
+				    listings only when remote browsing.
+				    (default value)
+				=2: fast browsing, only obtains directory
+				    listings when the directory hasn't been
+				    seen before (or |netrw-ctrl-l| is used).
+				Fast browsing retains old directory listing
+				buffers so that they don't need to be
+				re-acquired.  This feature is especially
+				important for remote browsing.  However, if
+				a file is introduced or deleted into or from
+				such directories, the old directory buffer
+				becomes out-of-date.  One may always refresh
+				such a directory listing with |netrw-ctrl-l|.
+				This option gives the choice of the trade-off
+				between accuracy and speed to the user.
+
+  *g:netrw_ftp_browse_reject*	ftp can produce a number of errors and warnings
+				that can show up as "directories" and "files"
+				in the listing.  This pattern is used to
+				remove such embedded messages.  By default its
+				value is:
+				 '^total\s\+\d\+$\|
+				 ^Trying\s\+\d\+.*$\|
+				 ^KERBEROS_V\d rejected\|
+				 ^Security extensions not\|
+				 No such file\|
+				 : connect to address [0-9a-fA-F:]*
+				 : No route to host$'
+
+  *g:netrw_ftp_list_cmd*	options for passing along to ftp for directory
+				listing.  Defaults:
+				 unix or g:netrw_cygwin set: : "ls -lF"
+				 otherwise                     "dir"
+
+
+  *g:netrw_ftp_sizelist_cmd*	options for passing along to ftp for directory
+				listing, sorted by size of file.
+				Defaults:
+				 unix or g:netrw_cygwin set: : "ls -slF"
+				 otherwise                     "dir"
+
+  *g:netrw_ftp_timelist_cmd*	options for passing along to ftp for directory
+				listing, sorted by time of last modification.
+				Defaults:
+				 unix or g:netrw_cygwin set: : "ls -tlF"
+				 otherwise                     "dir"
+
+  *g:netrw_hide*		if true, the hiding list is used
+				 default: =0
+
+  *g:netrw_keepdir*		=1 (default) keep current directory immune from
+				   the browsing directory.
+				=0 keep the current directory the same as the
+				   browsing directory.
+				The current browsing directory is contained in
+				b:netrw_curdir (also see |netrw-c|)
+
+  *g:netrw_list_cmd*		command for listing remote directories
+				 default: (if ssh is executable)
+				          "ssh HOSTNAME ls -FLa"
+
+  *g:netrw_liststyle*		Set the default listing style:
+                                = 0: thin listing (one file per line)
+                                = 1: long listing (one file per line with time
+				     stamp information and file size)
+				= 2: wide listing (multiple files in columns)
+				= 3: tree style listing
+  *g:netrw_list_hide*		comma separated pattern list for hiding files
+				 default: ""
+
+  *g:netrw_local_mkdir*		command for making a local directory
+				 default: "mkdir"
+
+  *g:netrw_local_rmdir*		remove directory command (rmdir)
+				 default: "rmdir"
+
+  *g:netrw_maxfilenamelen*	=32 by default, selected so as to make long
+				    listings fit on 80 column displays.
+				If your screen is wider, and you have file
+				or directory names longer than 32 bytes,
+				you may set this option to keep listings
+				columnar.
+
+  *g:netrw_mkdir_cmd*		command for making a remote directory
+				 default: "ssh USEPORT HOSTNAME mkdir"
+
+  *g:netrw_rm_cmd*		command for removing files
+				 default: "ssh USEPORT HOSTNAME rm"
+
+  *g:netrw_rmdir_cmd*		command for removing directories
+				 default: "ssh USEPORT HOSTNAME rmdir"
+
+  *g:netrw_rmf_cmd*		 command for removing softlinks
+				 default: "ssh USEPORT HOSTNAME rm -f"
+
+  *g:netrw_sort_by*		sort by "name", "time", or "size"
+				 default: "name"
+
+  *g:netrw_sort_direction*	sorting direction: "normal" or "reverse"
+				 default: "normal"
+
+  *g:netrw_sort_sequence*	when sorting by name, first sort by the
+				comma-separated pattern sequence
+				 default: '[\/]$,*,\.bak$,\.o$,\.h$,
+				           \.info$,\.swp$,\.obj$'
+
+  *g:netrw_ssh_cmd*		One may specify an executable command
+				to use instead of ssh for remote actions
+				such as listing, file removal, etc.
+				 default: ssh
+
+  *g:netrw_ssh_browse_reject*	ssh can sometimes produce unwanted lines,
+				messages, banners, and whatnot that one doesn't
+				want masquerading as "directories" and "files".
+				Use this pattern to remove such embedded
+				messages.  By default its value is:
+					 '^total\s\+\d\+$'
+
+  *g:netrw_use_noswf*		netrw normally avoids writing swapfiles
+  				for browser buffers.  However, under some
+				systems this apparently is causing nasty
+				ml_get errors to appear; if you're getting
+				ml_get errors, try putting
+				  let g:netrw_use_noswf= 0
+				in your .vimrc.
+
+  *g:netrw_timefmt*		specify format string to strftime() (%c)
+				 default: "%c"
+
+  *g:netrw_winsize*		specify initial size of new o/v windows
+				 default: ""
+
+  *g:NetrwTopLvlMenu*		This variable specifies the top level
+				menu name; by default, its "Netrw.".  If
+				you wish to change this, do so in your
+				.vimrc.
+
+INTRODUCTION TO DIRECTORY BROWSING			*netrw-browse-intro*
+
+Netrw supports the browsing of directories on the local system and on remote
+hosts, including listing files and directories, entering directories, editing
+files therein, deleting files/directories, making new directories, and moving
+(renaming) files and directories.  The Netrw browser generally implements the
+previous explorer maps and commands for remote directories, although details
+(such as pertinent global variable names) necessarily differ.
+
+The Netrw remote file and directory browser handles two protocols: ssh and
+ftp.  The protocol in the url, if it is ftp, will cause netrw to use ftp
+in its remote browsing.  Any other protocol will be used for file transfers,
+but otherwise the ssh protocol will be used to do remote directory browsing.
+
+To use Netrw's remote directory browser, simply attempt to read a "file" with a
+trailing slash and it will be interpreted as a request to list a directory:
+
+	vim [protocol]://[user@]hostname/path/
+
+For local directories, the trailing slash is not required.
+
+If you'd like to avoid entering the password in for remote directory listings
+with ssh or scp, see |netrw-listhack|.
+
+
+NETRW BROWSING AND OPTION INCOMPATIBILITIES		*netrw-incompatible*
+
+Netrw will not work properly with >
+
+	:set acd
+	:set fo=...ta...
+<
+If either of these options are present when browsing is attempted, netrw
+will change them by using noacd and removing the ta suboptions from the
+|'formatoptions'|.
+
+			*netrw-explore*  *netrw-pexplore* *netrw-texplore*
+			*netrw-hexplore* *netrw-sexplore* *netrw-nexplore*
+			*netrw-vexplore*
+DIRECTORY EXPLORING COMMANDS 
+
+     :Explore[!]   [dir]... Explore directory of current file       *:Explore*
+     :Sexplore[!]  [dir]... Split&Explore directory of current file *:Sexplore*
+     :Hexplore[!]  [dir]... Horizontal Split & Explore              *:Hexplore*
+     :Vexplore[!]  [dir]... Vertical   Split & Explore              *:Vexplore*
+     :Texplore     [dir]... Tab              & Explore              *:Texplore*
+
+     Used with :Explore **/pattern : (also see |netrw-starstar|)
+     :Nexplore............. go to next matching file                *:Nexplore*
+     :Pexplore............. go to previous matching file            *:Pexplore*
+
+:Explore  will open the local-directory browser on the current file's
+          directory (or on directory [dir] if specified).  The window will be
+	  split only if the file has been modified, otherwise the browsing
+	  window will take over that window.  Normally the splitting is taken
+	  horizontally.
+:Explore! is like :Explore, but will use vertical splitting.
+:Sexplore will always split the window before invoking the local-directory
+          browser.  As with Explore, the splitting is normally done
+	  horizontally.
+:Sexplore! [dir] is like :Sexplore, but the splitting will be done vertically.
+:Hexplore  [dir] does an :Explore with |:belowright| horizontal splitting.
+:Hexplore! [dir] does an :Explore with |:aboveleft|  horizontal splitting.
+:Vexplore  [dir] does an :Explore with |:leftabove|  vertical splitting.
+:Vexplore! [dir] does an :Explore with |:rightbelow| vertical splitting.
+:Texplore  [dir] does a tabnew before generating the browser window
+
+By default, these commands use the current file's directory.  However, one
+may explicitly provide a directory (path) to use.
+
+							*netrw-starstar*
+When Explore, Sexplore, Hexplore, or Vexplore are used with a **/filepat,
+such as:
+>
+	:Explore **/filename_pattern
+<
+netrw will attempt to find a file in the current directory or any subdirectory
+which matches the filename pattern.  Internally, it produces a list of files
+which match the pattern and their paths; to that extent it resembles the Unix
+operation:
+>
+	find $(pwd) -name "$1" -exec "echo" "{}" ";" 2> /dev/null
+<
+The directory display is updated to show the subdirectory containing a
+matching file.  One may then proceed to the next (or previous) matching files'
+directories by using Nexplore or Pexplore, respectively.  If your console or
+gui produces recognizable shift-up or shift-down sequences, then you'll likely
+find using shift-downarrow and shift-uparrow convenient.  They're mapped by
+netrw:
+
+	<s-down>  == Nexplore, and
+	<s-up>    == Pexplore.
+
+As an example, consider
+>
+	:Explore **/*.c
+	:Nexplore
+	:Nexplore
+	:Pexplore
+<
+The status line will show, on the right hand side of the status line, a
+message like "Match 3 of 20".
+
+							*netrw-starpat*
+When Explore, Sexplore, Hexplore, or Vexplore are used with a */pattern,
+such as:
+>
+	:Explore */pattern
+<
+netrw will use |:vimgrep| to find files which contain the given pattern.
+Like what happens with |netrw-starstar|, a list of files which contain
+matches to the given pattern is generated.  The cursor will then jump
+to the first file with the given pattern; |:Nexplore|, |:Pexplore|, and
+the shifted-down and -up arrows work with the list to move to the next
+or previous files in that list.
+
+						*netrw-starstarpat*
+When Explore, Sexplore, Hexplore, or Vexplore are used with a **//pattern,
+such as:
+>
+	:Explore **//pattern
+<
+then Explore will use |:vimgrep| to find files like |netrw-starpat|;
+however, Explore will also search subdirectories as well as the current
+directory.
+
+
+REFRESHING THE LISTING				*netrw-ctrl-l* *netrw-ctrl_l*
+
+To refresh either a local or remote directory listing, press ctrl-l (<c-l>) or
+hit the <cr> when atop the ./ directory entry in the listing.  One may also
+refresh a local directory by using ":e .".
+
+
+GOING UP						*netrw--*
+
+To go up a directory, press "-" or press the <cr> when atop the ../ directory
+entry in the listing.
+
+Netrw will use the command in |g:netrw_list_cmd| to perform the directory
+listing operation after changing HOSTNAME to the host specified by the
+user-provided url.  By default netrw provides the command as:
+
+	ssh HOSTNAME ls -FLa
+
+where the HOSTNAME becomes the [user@]hostname as requested by the attempt to
+read.  Naturally, the user may override this command with whatever is
+preferred.  The NetList function which implements remote directory browsing
+expects that directories will be flagged by a trailing slash.
+
+
+BROWSING							*netrw-cr*
+
+Browsing is simple: move the cursor onto a file or directory of interest.
+Hitting the <cr> (the return key) will select the file or directory.
+Directories will themselves be listed, and files will be opened using the
+protocol given in the original read request.  
+
+  CAVEAT: There are four forms of listing (see |netrw-i|).  Netrw assumes
+  that two or more spaces delimit filenames and directory names for the long
+  and wide listing formats.  Thus, if your filename or directory name has two
+  or more spaces embedded in it, or any trailing spaces, then you'll need to
+  use the "thin" format to select it.
+
+The |g:netrw_browse_split| option, which is zero by default, may be used to
+cause the opening of files to be done in a new window or tab.  When the option
+is one or two, the splitting will be taken horizontally or vertically,
+respectively.  When the option is set to three, a <cr> will cause the file
+to appear in a new tab.
+
+
+OBTAINING A FILE						*netrw-O*
+
+When browsing a remote directory, one may obtain a file under the cursor (ie.
+get a copy on your local machine, but not edit it) by pressing the O key.
+Only ftp and scp are supported for this operation (but since these two are
+available for browsing, that shouldn't be a problem).  The status bar
+will then show, on its right hand side, a message like "Obtaining filename".
+The statusline will be restored after the transfer is complete.
+
+Netrw can also "obtain" a file using the local browser.  Netrw's display
+of a directory is not necessarily the same as Vim's "current directory",
+unless |g:netrw_keepdir| is set to 0 in the user's <.vimrc>.  One may select
+a file using the local browser (by putting the cursor on it) and pressing
+"O" will then "obtain" the file; ie. copy it to Vim's current directory.
+
+Related topics:
+ * To see what the current directory is, use |:pwd|
+ * To make the currently browsed directory the current directory, see |netrw-c|
+ * To automatically make the currently browsed directory the current
+   directory, see |g:netrw_keepdir|.
+
+
+CHANGE LISTING STYLE						*netrw-i*
+
+The "i" map cycles between the thin, long, wide, and tree listing formats.
+
+The short listing format gives just the files' and directories' names.
+
+The long listing is either based on the "ls" command via ssh for remote
+directories or displays the filename, file size (in bytes), and the time and
+date of last modification for local directories.  With the long listing
+format, netrw is not able to recognize filenames which have trailing spaces.
+Use the thin listing format for such files.
+
+The wide listing format uses two or more contiguous spaces to delineate
+filenames; when using that format, netrw won't be able to recognize or use
+filenames which have two or more contiguous spaces embedded in the name or any
+trailing spaces.  The thin listing format will, however, work with such files.
+This listing format is the most compact.
+
+The tree listing format has a top directory followed by files and directories
+preceded by a "|".  One may open and close directories by pressing the <cr>
+key while atop the directory name.  There is only one tree listing buffer;
+hence, using "v" or "o" on a subdirectory will only show the same buffer,
+twice.
+
+
+MAKING A NEW DIRECTORY						*netrw-d*
+
+With the "d" map one may make a new directory either remotely (which depends
+on the global variable g:netrw_mkdir_cmd) or locally (which depends on the
+global variable g:netrw_local_mkdir).  Netrw will issue a request for the new
+directory's name.  A bare <CR> at that point will abort the making of the
+directory.  Attempts to make a local directory that already exists (as either
+a file or a directory) will be detected, reported on, and ignored.
+
+
+DELETING FILES OR DIRECTORIES		*netrw-delete* *netrw-D* *netrw-del*
+
+Deleting/removing files and directories involves moving the cursor to the
+file/directory to be deleted and pressing "D".  Directories must be empty
+first before they can be successfully removed.  If the directory is a softlink
+to a directory, then netrw will make two requests to remove the directory
+before succeeding.  Netrw will ask for confirmation before doing the
+removal(s).  You may select a range of lines with the "V" command (visual
+selection), and then pressing "D".
+
+The g:netrw_rm_cmd, g:netrw_rmf_cmd, and g:netrw_rmdir_cmd variables are used
+to control the attempts to remove files and directories.  The g:netrw_rm_cmd
+is used with files, and its default value is:
+
+	g:netrw_rm_cmd: ssh HOSTNAME rm
+
+The g:netrw_rmdir_cmd variable is used to support the removal of directories.
+Its default value is:
+
+	g:netrw_rmdir_cmd: ssh HOSTNAME rmdir
+
+If removing a directory fails with g:netrw_rmdir_cmd, netrw then will attempt
+to remove it again using the g:netrw_rmf_cmd variable.  Its default value is:
+
+	g:netrw_rmf_cmd: ssh HOSTNAME rm -f
+
+
+RENAMING FILES OR DIRECTORIES		*netrw-move* *netrw-rename* *netrw-R*
+
+Renaming/moving files and directories involves moving the cursor to the
+file/directory to be moved (renamed) and pressing "R".  You will then be
+queried for where you want the file/directory to be moved.  You may select a
+range of lines with the "V" command (visual selection), and then pressing "R".
+
+The g:netrw_rename_cmd variable is used to implement renaming.  By default its
+value is:
+
+	ssh HOSTNAME mv
+
+One may rename a block of files and directories by selecting them with
+the V (|linewise-visual|).
+
+
+HIDING FILES OR DIRECTORIES			*netrw-a* *netrw-hiding*
+
+Netrw's browsing facility allows one to use the hiding list in one of three
+ways: ignore it, hide files which match, and show only those files which
+match.  The "a" map allows the user to cycle about these three ways.
+
+The g:netrw_list_hide variable holds a comma delimited list of patterns (ex.
+\.obj) which specify the hiding list. (also see |netrw-ctrl-h|)  To set the
+hiding list, use the <c-h> map.  As an example, to hide files which begin with
+a ".", one may use the <c-h> map to set the hiding list to '^\..*' (or one may
+put let g:netrw_list_hide= '^\..*' in one's <.vimrc>).  One may then use the
+"a" key to show all files, hide matching files, or to show only the matching
+files.
+
+	Example: ^.*\.[ch]
+		This hiding list command will hide/show all *.c and *.h files.
+
+	Example: ^.*\.c,^.*\.h
+		This hiding list command will also hide/show all *.c and *.h
+		files.
+
+Don't forget to use the "a" map to select the normal/hiding/show mode you want!
+
+						*netrw-ctrl_h*
+EDIT FILE OR DIRECTORY HIDING LIST		*netrw-ctrl-h* *netrw-edithide*
+
+The "<ctrl-h>" map brings up a requestor allowing the user to change the
+file/directory hiding list.  The hiding list consists of one or more patterns
+delimited by commas.  Files and/or directories satisfying these patterns will
+either be hidden (ie. not shown) or be the only ones displayed (see
+|netrw-a|).
+
+
+BROWSING WITH A HORIZONTALLY SPLIT WINDOW		*netrw-o* *netrw-horiz*
+
+Normally one enters a file or directory using the <cr>.  However, the "o" map
+allows one to open a new window to hold the new directory listing or file.  A
+horizontal split is used.  (for vertical splitting, see |netrw-v|)
+
+Normally, the o key splits the window horizontally with the new window and
+cursor at the top.  To change to splitting the window horizontally with the
+new window and cursor at the bottom, have
+
+	let g:netrw_alto = 1
+
+in your <.vimrc>.  (also see |netrw-t| |netrw-v| |g:netrw_alto|)
+
+There is only one tree listing buffer; using "o" on a displayed subdirectory 
+will split the screen, but the same buffer will be shown twice.
+
+
+BROWSING WITH A VERTICALLY SPLIT WINDOW				*netrw-v*
+
+Normally one enters a file or directory using the <cr>.  However, the "v" map
+allows one to open a new window to hold the new directory listing or file.  A
+vertical split is used.  (for horizontal splitting, see |netrw-o|)
+
+Normally, the v key splits the window vertically with the new window and
+cursor at the left.  To change to splitting the window vertically with the new
+window and cursor at the right, have
+
+	let g:netrw_altv = 1
+
+in your <.vimrc>.  (also see: |netrw-o| |netrw-t| |g:netrw_altv|)
+
+There is only one tree listing buffer; using "v" on a displayed subdirectory 
+will split the screen, but the same buffer will be shown twice.
+
+
+BROWSING WITH A NEW TAB					*netrw-t*
+
+Normally one enters a file or directory using the <cr>.  The "t" map
+allows one to open a new window hold the new directory listing or file in a
+new tab. (also see: |netrw-o| |netrw-v|)
+
+
+PREVIEW WINDOW					*netrw-p* *netrw-preview*
+
+One may use a preview window by using the "p" key when the cursor is atop the
+desired filename to be previewed.
+
+
+PREVIOUS WINDOW					*netrw-P* *netrw-prvwin*
+
+To edit a file or directory in the previously used window (see :he |CTRL-W_P|),
+press a "P".  If there's only one window, then the one window will be
+horizontally split (above/below splitting is controlled by |g:netrw_alto|,
+and its initial size is controlled by |g:netrw_winsize|).
+
+If there's more than one window, the previous window will be re-used on
+the selected file/directory.  If the previous window's associated buffer
+has been modified, and there's only one window with that buffer, then
+the user will be asked if s/he wishes to save the buffer first (yes,
+no, or cancel).
+
+
+SELECTING SORTING STYLE				*netrw-s* *netrw-sort*
+
+One may select the sorting style by name, time, or (file) size.  The "s" map
+allows one to circulate amongst the three choices; the directory listing will
+automatically be refreshed to reflect the selected style.
+
+
+EDITING THE SORTING SEQUENCE		*netrw-S* *netrw-sortsequence*
+
+When "Sorted by" is name, one may specify priority via the sorting sequence
+(g:netrw_sort_sequence).  The sorting sequence typically prioritizes the
+name-listing by suffix, although any pattern will do.  Patterns are delimited
+by commas.  The default sorting sequence is:
+>
+	[\/]$,*,\.bak$,\.o$,\.h$,\.info$,\.swp$,\.obj$
+<
+The lone * is where all filenames not covered by one of the other patterns
+will end up.  One may change the sorting sequence by modifying the
+g:netrw_sort_sequence variable (either manually or in your <.vimrc>) or by
+using the "S" map.
+
+
+REVERSING SORTING ORDER			*netrw-r* *netrw-reverse*
+
+One may toggle between normal and reverse sorting order by pressing the
+"r" key.
+
+
+CHANGING TO A PREDECESSOR DIRECTORY		*netrw-u* *netrw-updir*
+
+Every time you change to a new directory (new for the current session),
+netrw will save the directory in a recently-visited directory history
+list (unless g:netrw_dirhistmax is zero; by default, its ten).  With the
+"u" map, one can change to an earlier directory (predecessor).  To do
+the opposite, see |netrw-U|.
+
+
+CHANGING TO A SUCCESSOR DIRECTORY		*netrw-U* *netrw-downdir*
+
+With the "U" map, one can change to a later directory (successor).
+This map is the opposite of the "u" map. (see |netrw-u|)  Use the
+q map to list both the bookmarks and history. (see |netrw-q|)
+
+						*netrw-gx*
+CUSTOMIZING BROWSING WITH A USER FUNCTION	*netrw-x* *netrw-handler*
+						(also see |netrw_filehandler|)
+
+Certain files, such as html, gif, jpeg, (word/office) doc, etc, files, are
+best seen with a special handler (ie. a tool provided with your computer).
+Netrw allows one to invoke such special handlers by: >
+
+	* when Exploring, hit the "x" key
+	* when editing, hit gx with the cursor atop the special filename
+<	  (not available if the |g:netrw_nogx| variable exists)
+
+Netrw determines which special handler by the following method:
+
+  * if |g:netrw_browsex_viewer| exists, then it will be used to attempt to
+    view files.  Examples of useful settings (place into your <.vimrc>): >
+
+	:let g:netrw_browsex_viewer= "kfmclient exec"
+<   or >
+	:let g:netrw_browsex_viewer= "gnome-open"
+<
+    If g:netrw_browsex_viewer == '-', then netrwFileHandler() will be
+    invoked first (see |netrw_filehandler|).
+
+  * for Windows 32 or 64, the url and FileProtocolHandler dlls are used.  
+  * for Gnome (with gnome-open): gnome-open is used.
+  * for KDE (with kfmclient): kfmclient is used.
+  * otherwise the netrwFileHandler plugin is used.
+
+The file's suffix is used by these various approaches to determine an
+appropriate application to use to "handle" these files.  Such things as
+OpenOffice (*.sfx), visualization (*.jpg, *.gif, etc), and PostScript (*.ps,
+*.eps) can be handled.
+
+							*netrw_filehandler*
+
+The "x" map applies a function to a file, based on its extension.  Of course,
+the handler function must exist for it to be called!
+>
+ Ex. mypgm.html   x ->
+                  NFH_html("scp://user@host/some/path/mypgm.html")
+<
+Users may write their own netrw File Handler functions to support more
+suffixes with special handling.  See <plugin/netrwFileHandlers.vim> for
+examples on how to make file handler functions.   As an example: >
+
+	" NFH_suffix(filename)
+	fun! NFH_suffix(filename)
+	..do something special with filename..
+	endfun
+<
+These functions need to be defined in some file in your .vim/plugin
+(vimfiles\plugin) directory.  Vim's function names may not have punctuation
+characters (except for the underscore) in them.  To support suffices that
+contain such characters, netrw will first convert the suffix using the
+following table: >
+
+    @ -> AT       ! -> EXCLAMATION    % -> PERCENT  
+    : -> COLON    = -> EQUAL          ? -> QUESTION 
+    , -> COMMA    - -> MINUS          ; -> SEMICOLON
+    $ -> DOLLAR   + -> PLUS           ~ -> TILDE    
+<    
+So, for example: >
+
+	file.rcs,v  ->  NFH_rcsCOMMAv()
+<
+If more such translations are necessary, please send me email: >
+		NdrOchip at ScampbellPfamily.AbizM - NOSPAM
+with a request.
+
+
+MAKING THE BROWSING DIRECTORY THE CURRENT DIRECTORY	*netrw-c* *netrw-curdir*
+
+By default, |g:netrw_keepdir| is 1.  This setting means that the current
+directory will not track the browsing directory.
+
+Setting g:netrw_keepdir to 0 tells netrw to make vim's current directory to
+track netrw's browsing directory.
+
+However, given the default setting for g:netrw_keepdir of 1 where netrw
+maintains its own separate notion of the current directory, in order to make
+the two directories the same, use the "c" map (just type c).  That map will
+set Vim's notion of the current directory to netrw's current browsing
+directory.
+
+
+BOOKMARKING A DIRECTORY		*netrw-mb* *netrw-bookmark* *netrw-bookmarks*
+One may easily "bookmark" a directory by using >
+
+	{cnt}mb
+<
+Any count may be used.  One may use viminfo's "!" option to retain bookmarks
+between vim sessions.  See |netrw-gb| for how to return to a bookmark and
+|netrw-q| for how to list them.
+
+
+CHANGING TO A BOOKMARKED DIRECTORY			*netrw-gb* 
+
+To change directory back to a bookmarked directory, use
+
+	{cnt}gb
+
+Any count may be used to reference any of the bookmarks.  See |netrw-mb| on
+how to bookmark a directory and |netrw-q| on how to list bookmarks.
+
+
+LISTING BOOKMARKS AND HISTORY			*netrw-q* *netrw-listbookmark*
+
+Pressing "q" will list the bookmarked directories and directory traversal
+history (query). (see |netrw-mb|, |netrw-gb|, |netrw-u|, and |netrw-U|)
+
+
+IMPROVING DIRECTORY BROWSING				*netrw-listhack*
+
+Especially with the remote directory browser, constantly entering the password
+is tedious.
+
+For Linux/Unix systems, the book "Linux Server Hacks - 100 industrial strength
+tips & tools" by Rob Flickenger (O'Reilly, ISBN 0-596-00461-3) gives a tip
+for setting up no-password ssh and scp and discusses associated security
+issues.  It used to be available at http://hacks.oreilly.com/pub/h/66 ,
+but apparently that address is now being redirected to some "hackzine".
+I'll attempt a summary:
+
+	1. Generate a public/private key pair on the ssh server:
+	   ssh-keygen -t rsa
+	   (saving the file in ~/.ssh/id_rsa is ok)
+	2. Just hit the <CR> when asked for passphrase (twice).
+	3. This creates two files:
+	     ~/.ssh/id_rsa
+	     ~/.ssh/id_rsa.pub
+	4. On the client:
+	    cd
+	    mkdir .ssh
+	    chmod 0700 .ssh
+	    scp {serverhostname}:.ssh/id_rsa.pub .
+	    cat id_rsa.pub >> .ssh/authorized_keys2
+
+For Windows, folks on the vim mailing list have mentioned that Pageant helps
+with avoiding the constant need to enter the password.
+
+
+NETRW SETTINGS						*netrw-settings*
+
+With the NetrwSettings.vim plugin, >
+	:NetrwSettings
+will bring up a window with the many variables that netrw uses for its
+settings.  You may change any of their values; when you save the file, the
+settings therein will be used.  One may also press "?" on any of the lines for
+help on what each of the variables do.
+
+(also see: |netrw-browse-var| |netrw-protocol| |netrw-var| |netrw-variables|)
+
+
+==============================================================================
+10. Problems and Fixes						*netrw-problems*
+
+	(This section is likely to grow as I get feedback)
+	(also see |netrw-debug|)
+								*netrw-p1*
+	P1. I use windows 95, and my ftp dumps four blank lines at the
+	    end of every read.
+
+		See |netrw-fixup|, and put the following into your
+		<.vimrc> file:
+
+			let g:netrw_win95ftp= 1
+
+								*netrw-p2*
+	P2. I use Windows, and my network browsing with ftp doesn't sort by
+	    time or size!  -or-  The remote system is a Windows server; why
+	    don't I get sorts by time or size?
+
+		Windows' ftp has a minimal support for ls (ie. it doesn't
+		accept sorting options).  It doesn't support the -F which
+		gives an explanatory character (ABC/ for "ABC is a directory").
+		Netrw then uses "dir" to get both its short and long listings.
+		If you think your ftp does support a full-up ls, put the
+		following into your <.vimrc>: >
+
+			let g:netrw_ftp_list_cmd    = "ls -lF"
+			let g:netrw_ftp_timelist_cmd= "ls -tlF"
+			let g:netrw_ftp_sizelist_cmd= "ls -slF"
+<
+		Alternatively, if you have cygwin on your Windows box, put
+		into your <.vimrc>: >
+
+			let g:netrw_cygwin= 1
+<
+		This problem also occurs when the remote system is Windows.
+		In this situation, the various g:netrw_ftp_[time|size]list_cmds
+		are as shown above, but the remote system will not correctly
+		modify its listing behavior.
+
+
+								*netrw-p3*
+	P3. I tried rcp://user@host/ (or protocol other than ftp) and netrw
+	    used ssh!  That wasn't what I asked for...
+
+		Netrw has two methods for browsing remote directories: ssh
+		and ftp.  Unless you specify ftp specifically, ssh is used.
+		When it comes time to do download a file (not just a directory
+		listing), netrw will use the given protocol to do so.
+
+								*netrw-p4*
+	P4. I would like long listings to be the default.
+
+			let g:netrw_liststyle= 1
+
+		Check out |netrw-browse-var| for more customizations that
+		you can set.
+
+								*netrw-p5*
+	P5. My times come up oddly in local browsing
+
+		Does your system's strftime() accept the "%c" to yield dates
+		such as "Sun Apr 27 11:49:23 1997"?  If not, do a "man strftime"
+		and find out what option should be used.  Then put it into
+		your <.vimrc>:
+			let g:netrw_timefmt= "%X"  (where X is the option)
+
+								*netrw-p6*
+	P6. I want my current directory to track my browsing.
+	    How do I do that?
+
+		let g:netrw_keepdir= 0
+	
+								*netrw-p7*
+	P7. I use Chinese (or other non-ascii) characters in my filenames, and
+	    netrw (Explore, Sexplore, Hexplore, etc) doesn't display them!
+
+		(taken from an answer provided by Wu Yongwei on the vim
+		mailing list)
+		I now see the problem. You code page is not 936, right? Vim
+		seems only able to open files with names that are valid in the
+		current code page, as are many other applications that do not
+		use the Unicode version of Windows APIs. This is an OS-related
+		issue. You should not have such problems when the system
+		locale uses UTF-8, such as modern Linux distros.
+
+		(...it is one more reason to recommend that people use utf-8!)
+
+								*netrw-p8*
+	P8. I'm getting "ssh is not executable on your system" -- what do I
+	    do?
+
+		(Dudley Fox) Most people I know use putty for windows ssh.  It
+		is a free ssh/telnet application. You can read more about it
+		here:
+
+		http://www.chiark.greenend.org.uk/~sgtatham/putty/ Also:
+
+		(Marlin Unruh) This program also works for me. It's a single
+		executable, so he/she can copy it into the Windows\System32
+		folder and create a shortcut to it. 
+
+		(Dudley Fox) You might also wish to consider plink, as it
+		sounds most similar to what you are looking for. plink is an
+		application in the putty suite.
+
+           http://the.earth.li/~sgtatham/putty/0.58/htmldoc/Chapter7.html#plink
+
+	   	(Vissale Neang) Maybe you can try OpenSSH for windows, which
+		can be obtained from:
+
+		http://sshwindows.sourceforge.net/
+
+		It doesn't need the full Cygwin package. 
+
+		(Antoine Mechelynck) For individual Unix-like programs needed
+		for work in a native-Windows environment, I recommend getting
+		them from the GnuWin32 project on sourceforge if it has them:
+
+		    http://gnuwin32.sourceforge.net/
+
+		Unlike Cygwin, which sets up a Unix-like virtual machine on
+		top of Windows, GnuWin32 is a rewrite of Unix utilities with
+		Windows system calls, and its programs works quite well in the
+		cmd.exe "Dos box". 
+
+		(dave) Download WinSCP and use that to connect to the server.
+		In Preferences > Editors, set gvim as your editor:
+
+			- Click "Add..."
+			- Set External Editor (adjust path as needed, include
+			  the quotes and !.! at the end):
+			    "c:\Program Files\Vim\vim70\gvim.exe" !.!
+			- Check that the filetype in the box below is
+			  {asterisk}.{asterisk} (all files), or whatever types
+			  you want (cec: change {asterisk} to * ; I had to
+			  write it that way because otherwise the helptags
+			  system thinks its a tag)
+			- Make sure its at the top of the listbox (click it,
+			  then click "Up" if its not)
+		If using the Norton Commander style, you just have to hit <F4>
+		to edit a file in a local copy of gvim.
+
+		(Vit Gottwald) How to generate public/private key and save
+		public key it on server: >
+  http://www.tartarus.org/~simon/puttydoc/Chapter8.html#pubkey-gettingready
+			8.3 Getting ready for public key authentication
+<
+		How to use private key with 'pscp': >
+			http://www.tartarus.org/~simon/puttydoc/Chapter5.html
+			5.2.4 Using public key authentication with PSCP 
+<
+		(cec) To make proper use of these suggestions above, you will
+		need to modify the following user-settable variables in your
+		.vimrc:
+
+			|g:netrw_ssh_cmd| |g:netrw_list_cmd|  |g:netrw_mkdir_cmd|
+			|g:netrw_rm_cmd|  |g:netrw_rmdir_cmd| |g:netrw_rmf_cmd|
+
+		The first one (|g:netrw_ssh_cmd|) is the most important; most
+		of the others will use the string in g:netrw_ssh_cmd by
+		default.
+						*netrw-p9* *netrw-ml_get*
+	P9. I'm browsing, changing directory, and bang!  ml_get errors
+	    appear and I have to kill vim.  Any way around this?
+
+		Normally netrw attempts to avoid writing swapfiles for
+		its temporary directory buffers.  However, on some systems
+		this attempt appears to be causing ml_get errors to
+		appear.  Please try setting |g:netrw_use_noswf| to 0
+		in your <.vimrc>: >
+			let g:netrw_use_noswf= 0
+<
+
+==============================================================================
+11. Debugging						*netrw-debug*
+
+The <netrw.vim> script is typically available as:
+>
+	/usr/local/share/vim/vim6x/plugin/netrw.vim
+< -or- >
+	/usr/local/share/vim/vim7x/plugin/netrw.vim
+<
+which is loaded automatically at startup (assuming :set nocp).
+
+	1. Get the <Decho.vim> script, available as:
+
+	     http://mysite.verizon.net/astronaut/vim/index.html#vimlinks_scripts
+	     as "Decho, a vimL debugging aid"
+	   or
+	     http://vim.sourceforge.net/scripts/script.php?script_id=120
+
+	   and put it into your local plugin directory.
+
+	2. <Decho.vim> itself needs the <cecutil.vim> script, so you'll need
+	   to put it into your .vim/plugin, too.  You may obtain it from:
+
+		http://mysite.verizon.net/astronaut/vim/index.html#VimFuncs
+		as "DrC's Utilities"
+
+	3. Edit the <netrw.vim> file by typing:
+
+		vim netrw.vim
+		:DechoOn
+		:wq
+
+	   To restore to normal non-debugging behavior, edit <netrw.vim>
+	   by typing
+
+		vim netrw.vim
+		:DechoOff
+		:wq
+
+	   This command, provided by <Decho.vim>, will comment out all
+	   Decho-debugging statements (Dfunc(), Dret(), Decho(), Dredir()).
+
+	4. Then bring up vim and attempt a transfer or do browsing.  A set of
+	   messages should appear concerning the steps that <netrw.vim> took
+	   in attempting to read/write your file over the network.
+
+	   To save the file, use >
+		:wincmd j
+		:set bt=
+		:w! DBG
+<	   Please send that information to <netrw.vim>'s maintainer, >
+		NdrOchip at ScampbellPfamily.AbizM - NOSPAM
+<
+==============================================================================
+12. History						*netrw-history* {{{1
+
+	v109: Mar 26, 2007 * if a directory name includes a "$" character,
+			     Explore() will use expand() in an attempt to
+			     decipher the name.
+	      May 07, 2007 * g:netrw_use_errorwindow now allows one to
+	                     have error messages go to a reliable window
+			     or to use a less reliable but recallable 
+			     echoerr method
+	      May 07, 2007 * g:netrw_scpport and g:netrw_sshport support
+	                     use of -P and -p, respectively, to set port
+			     for scp/ssh.
+	v108: Jan 03, 2007 * included preview map (|netrw-p|), supporting
+			     remote browsing
+			   * netrw can now source remote files
+	      Jan 26, 2007 * Colton Jamieson noted that remote directory
+			     browsing did not support alternate port
+			     selection.  This feature has now been extended
+			     to apply to all remote browsing commands via ssh.
+			     (list, remove/delete, rename)
+	      Jan 31, 2007 * Luis Florit reported that @* was an invalid
+			     register.  The @* register is now only saved and
+			     restored if |'guioptions'| contains "a".
+	      Feb 02, 2007 * Fixed a bug that cropped up when writing files
+			     via scp using cygwin
+	      Feb 08, 2007 * tree listing mode managed to stop working again;
+			     fixed again!
+	      Feb 15, 2007 * Guido Van Hoecke reported that netrw didn't
+			     handle browsing well with M$ ftp servers.  He even
+			     set up a temporary account for me to test with
+			     (thanks!).  Netrw now can browse M$ ftp servers.
+	v107: Oct 12, 2006 * bypassed the autowrite option
+	      Oct 24, 2006 * handles automatic decompression of *.gz and *.bz2
+			     files
+	      Nov 03, 2006 * Explore will highlight matching files when
+			     **/pattern is used (and if the |'hls'| option
+			     is set)
+	      Nov 09, 2006 * a debugging line, when enabled, was inadvertently
+			     bringing up help instead of simply reporting on
+			     list contents
+	      Nov 21, 2006 * tree listing improved (cursor remains put)
+	      Nov 27, 2006 * fixed b:netrw_curdir bug when repeated "i"s were
+			     pressed.
+	      Dec 15, 2006 * considerable qty of changes, mostly to share more
+			     code between local and remote browsing.  Includes
+			     support for tree-style listing for both remote
+			     and local browsing.
+	      Dec 15, 2006 * Included Peter Bengtsson's modifications to
+			     support the Amiga.
+	v106: Sep 21, 2006 * removed old v:version<700 code as netrw now
+			     requires vim 7.0
+			   * worked around a bug where register * was
+			     overwritten during local browsing
+	v104: Sep 05, 2006 * as suggested by Rodolfo Borges, :Explore and
+			     variants will position the cursor on the file
+			     just having been edited
+			   * changed default |g:netrw_sort_sequence| order
+			   * changed b, Nb to simply mb  (see |netrw-mb|)
+			   * changed B, NB to simply gb  (see |netrw-gb|)
+			   * tree listing style (see |g:netrw_liststyle|)
+			   * attempts to retain the alternate file
+	v103: Jul 26, 2006 * used Yakov Lerner's tip#1289 to improve netrw
+			     error message display
+			   * wide listings didn't handle files with backslashes
+			     in their names properly.  A symptom was an
+			     inability to open files.
+	      Aug 09, 2006 * included "t" mapping for opening tabbed windows,
+			    both for remote and local browsing
+			   * changed netrw_longlist to netrw_liststyle
+	      Aug 15, 2006 * fixed one of the NB maps
+	      Aug 22, 2006 * changed *Explore commands to use -nargs=* instead
+			     of -nargs=?.  Allows both -complete=dir _and_ the
+			     starstar arguments to work (-nargs=? seems to
+			     require one or the other).
+	      Aug 23, 2006 * copied all w:.. variables across splits to
+			     new windows
+	      Aug 25, 2006 * when g:netrw_browsex_viewer was '-'
+			     (see |g:netrw_browsex_viewer|) it wasn't causing
+			     netrwFileHandlers#Invoke() to be called as it
+			     was expected to.  (tnx Steve Dugaro)
+	      Aug 29, 2006 * changed NetBrowseX() to use "setlocal ... noswf"
+			     instead of "set ... noswf"  (tnx Benji Fisher)
+	      Aug 31, 2006 * tabs and fastbrowse<=1 didn't work together.
+	v102: Jun 15, 2006 * chgd netrwPlugin to call netrw#LocalBrowseCheck()
+			   * bugfix: g:netrw_keepdir==0 had stopped working
+	      Jul 06, 2006 * bugfix: NetOptionSave/Restore now saves/restores
+			     the unnamed register (|registers|)
+	      Jul 07, 2006 * |g:netrw_menu| support included
+	      Jul 13, 2006 * :Texplore command implemented
+	      Jul 17, 2006 * NetSplit and (Local|Net)BrowseChgDir() were both
+			     splitting windows.  This affected o, v, and
+			     g:netrw_browse_split.
+	      Jul 20, 2006 * works around wildignore setting (was causing
+			     netrw's local browser not to list wildignore'd
+			     files)
+	      Jul 24, 2006 * <leftmouse> acts as a <cr> for selecting a file
+			     <rightmouse> acts as a <del> for deleting a file
+	v100: May 14, 2006 * when using Windows and shell==cmd.exe, the
+			     default for g:netrw_ignorenetrc is now 1
+			   * bugfix: unwanted ^Ms now removed
+			     (affected shell==cmd.exe - Windows)
+			   * added Bookmarks and History to the menu
+			   * an error message about non-existing
+			     w:netrw_longlist was appearing during attempts to
+			     Explore (fixed)
+			   * g:netrw_shq now available to make netrw use
+			     specified style of quotes for commands
+	     May 29, 2006  * user NFH_*() functions were inadvertently being
+			     ignored
+			   * fixed a Windows non-cygwin ftp handling problem.
+			   * hiding pattern candidate separators included some
+			     characters it shouldn't have (tnx to Osei Poku)
+	     Jun 01, 2006  * for browsing, netrw was supposed to use "dir"
+			     instead of "ls -lF" when using
+			     ftp+non-cygwin+windows.  Fixed.
+			   * an inadvertently left-in-place debugging statement
+			     was preventing use of the "x" key with browsing.
+	     Jun 05, 2006  * g:netrw_nogx available to prevent making the gx
+			     map (see |g:netrw_nogx|)
+			   * bugfix, Explore wouldn't change directory
+			     properly (vim ., :Explore subdirname)
+	     Jun 06, 2006  * moved history to 2nd line in Netrw menu
+			   * fixed delete for unix-based systems
+	     Jun 07, 2006  * x key now works for windows-noncygwin-ftp
+	     Jun 08, 2006  * Explore */pat and **//pat now wraps
+	v99: May 09, 2006  * g:netrw_browse_split=3 for opening files in new
+			     tabs implemented.
+	     May 12, 2006  * deletes temporary file at end of NetRead()
+			   * visual mode based Obtain implemented
+			   * added -complete=dir to the various Explore
+			     commands
+	v98: May 02, 2006  * the "p" key didn't work properly when the browsing
+			     directory name had spaces in it.
+	v97: May 01, 2006  * exists("&acd") now used to determine if
+			     the 'acd' option exists
+			   * "obtain" now works again under Windows
+	v96: * bugfix - the |'acd'| option is not always defined but is
+	       now bypassed only when it is
+	v95: * bugfix - Hiding mode worked correctly (don't show any file
+	       matching any of the g:netrw_hide patterns), but
+	       showing mode was showing only those files that didn't
+	       match any of the g:netrw_hide patterns.  Instead, it now
+	       shows all files that match any of the g:netrw_hide patterns
+	       (the difference between a logical and and logical or).
+	v94: * bugfix - a Decho() had a missing quote; only affects things
+	       when debugging was enabled.
+	v93: * bugfix - removed FocusGained event from causing a slow-browser
+	       refresh for Windows
+	v92: * :Explore **//pattern implemented  (**/filepattern already taken)
+	v91: * :Explore */pattern implemented
+	     * |'acd'| option bypassed
+	v90: * mark ', as suggested by Yegappan Lakshmanan, used to help
+	       guarantee entry into the jump list when appropriate.
+	     * <s-down> and <s-up> are no longer defined until a
+	       :Explore **/pattern  is used (if the user already has a map
+	       for them).  They will be defined for new browser windows
+	       from that point forward.
+	v89: * A <s-down>, <s-up>, :Nexplore, or a :Pexplore without having
+	       first done an :Explore **/pattern (see |netrw-starstar|) caused
+	       a lot of unhelpful error messages to appear
+	v88: * moved DrChip.Netrw menu to Netrw.  Now has priority 80 by
+	       default.  g:NetrwTopLvlMenu == "Netrw" and can be changed
+	       by the user to suit.  The priority is g:NetrwMenuPriority.
+	     * Changed filetype for browser displays from netrwlist to netrw.
+	v87: * bug fix -- menus were partially disappearing
+	v85: * bug fix -- missing an endif
+	     * bug fix -- handles spaces in names and directories when using
+	       ftp-based browsing
+	v83: * disabled stop-acd handling; the change in directory handling
+	       may allow acd to be used again.  Awaiting feedback.
+	     * D was refusing to delete remote files/directories in wide
+	       listing mode.
+	v81: * FocusGained also used to refresh/wipe local browser directory
+	       buffers
+	     * (bugfix) netrw was leaving [Scratch] buffers behind when the
+	       user had the "hidden" option set.  The 'hidden' option is
+	       now bypassed.
+	v80: * ShellCmdPost event used in conjunction with g:netrw_fastbrowse
+	       to refresh/wipe local browser directory buffers.
+	v79: * directories are now displayed with nowrap
+	     * (bugfix) if the column width was smaller than the largest
+	       file's name, then netrw would hang when using wide-listing
+	       mode - fixed
+	     * g:netrw_fastbrowse introduced
+	v78: * progress has been made on allowing spaces inside directory
+	       names for remote work (reading, writing, browsing).  (scp)
+	v77: * Mikolaj Machowski fixed a bug in a substitute command
+	     * g:netrw_browsex_viewer implemented
+	     * Mikolaj Machowski pointed out that gnome-open is often
+	       executable under KDE systems, although it is effectively
+	       not functional.  NetBrowseX now looks for "kicker" as 
+	       a running process to determine if KDE is actually the
+	       really running.
+	     * Explorer's O functionality was inadvertently left out.
+	       Netrw now does the same thing, but with the "P" key.
+	     * added g:netrw_browse_split option
+	     * fixed a bug where the directory contained a "." but
+	       the file didn't (was treating the dirname from "."
+	       onwards as a suffix)
+	v76: * "directory is missing" error message now restores echo
+	       highlighting
+	v75: * file://... now conforms to RFC2396 (thanks to S. Zacchiroli)
+	     * if the binary option is set, then NetWrite() will only write
+	       the whole file (line numbers don't make sense with this).
+	       Supports writing of tar and zip files.
+	v74: * bugfix (vim, then :Explore) now works
+	     * ctrl-L keeps cursor at same screen location (both local and
+	       remote browsing)
+	     * netrw now can read remote zip and tar files
+	     * Obtain now uses WinXP ftp+.netrc successfully
+	v73: * bugfix -- scp://host/path/file was getting named incorrectly
+	     * netrw detects use of earlier-than-7.0 version of vim and issues
+	       a pertinent error message.
+	     * netrwSettings.vim is now uses autoloading.  Only
+	       <netrwPlugin.vim> is needed as a pure plugin
+	       (ie. always loaded).
+	v72: * bugfix -- formerly, one could prevent the loading of netrw
+	       by "let g:loaded_netrw=1"; when autoloading became supported,
+	       this feature was lost.  It is now restored.
+	v71: * bugfix -- made some "set nomodifiable"s into setlocal variants
+	       (allows :e somenewfile  to be modifiable as usual)
+	     * NetrwSettings calls a netrw function, thereby assuring that
+	       netrw has loaded.  However, if netrw does not load for whatever
+	       reason, then NetrwSettings will now issue a warning message.
+	     * For what reason I don't recall, when wget and fetch are both
+	       not present, and an attempt to read a http://... url is made,
+	       netrw exited.  It now only returns.
+	     * When ch=1, on the second and subsequent uses of browsing Netrw
+	       would issue a blank line to clear the echo'd messages.  This
+	       caused an annoying "Hit-Enter" prompt; now a blank line message
+	       is echo'd only if &ch>1.
+	v70: * when using |netrw-O|, the "Obtaining filename" message is now
+	       shown using |hl-User9|.  If User9 has not been defined, netrw
+	       will define it.
+	v69: * Bugfix: win95/98 machines were experiencing a
+	       "E121: Undefined variable: g:netrw_win95ftp" message
+	v68: * double-click-leftmouse selects word under mouse
+	v67: * Passwords which contain blanks will now be surrounded by
+	       double-quotes automatically (Yongwei)
+	v66: * Netrw now seems to work with a few more Windows situations
+	     * O now obtains a file: remote browsing file -> local copy,
+	       locally browsing file -> current directory (see :pwd)
+	     * i now cycles between thin, long, and wide listing styles
+	     * NB and Nb are maps that are always available; corresponding
+	       B and b maps are only available when not using wide listing
+	       in order to allow them to be used for motions
+	v65: * Browser functions now use NetOptionSave/Restore; in particular,
+	       netrw now works around the report setting
+	v64: * Bugfix - browsing a "/" directory (Unix) yielded buffers 
+	       named "[Scratch]" instead of "/"
+	     * Bugfix - remote browsing with ftp was omitting the ./ and ../
+	v63: * netrw now takes advantage of autoload (and requires 7.0)
+	     * Bugfix - using r (to reverse sort) working again
+	v62: * Bugfix - spaces allowed again in directory names with
+	       g:netrw_keepdir=0.  In fact, I've tested netrw (again)
+	       with most ANSI punctuation marks for directory names.
+	     * Bugfix - NetrwSettings gave errors when g:netrw_silent
+	       had not be set.
+	v61: * document upgrade -- netrw variable-based settings all should
+	       have tags.  Supports NetrwSettings command.
+	     * several important variables are window-oriented.  Netrw has
+	       to transfer these across a window split.  See s:BufWinVars()
+	       and s:UseBufWinVars().
+	v60: * when using the i map to switch between long and short listings,
+	       netrw will now keep cursor on same line
+	     * "Match # of #" now uses status line
+	     * :Explore **/*.c  will now work from a non-netrw-browser window
+	     * :Explore **/patterns can now be run in separate browser windows
+	     * active banner (hit <cr> will cause various things to happen)
+	v59: * bugfix -- another keepalt work-around installed (for vim6.3)
+	     * "Match # of #" for Explore **/pattern matches
+	v58: * Explore and relatives can now handle **/somefilepattern (v7)
+	     * Nexplore and Pexplore introduced (v7).  shift-down and shift-up
+	       cursor keys will invoke Nexplore and Pexplore, respectively.
+	     * bug fixed with o and v
+	     * autochdir only worked around for vim when it has been
+	       compiled with either |+netbeans_intg| or |+sun_workshop|
+	     * Under Windows, all directories and files were being preceded
+	       with a "/" when local browsing.  Fixed.
+	     * When: syntax highlighting is off, laststatus=2, and remote
+	       browsing is used, sometimes the laststatus highlighting
+	       bleeds into the entire display.  Work around - do an extra
+	       redraw in that case.
+	     * Bugfix: when g:netrw_keepdir=0, due to re-use of buffers,
+	       netrw didn't change the directory when it should've
+	     * Bugfix: D and R commands work again
+	v57: * Explore and relatives can now handle RO files
+	     * reverse sort restored with vim7's sort command
+	     * g:netrw_keepdir now being used to keep the current directory
+	       unchanged as intended (sense change)
+	     * vim 6.3 still supported
+	v56: * LocalBrowse now saves autochdir setting, unsets it, and
+	       restores it before returning.
+	     * using vim's rename() instead of system + local_rename variable
+	     * avoids changing directory when g:netrw_keepdir is false
+	v55: * -bar used with :Explore :Sexplore etc to allow multiple
+	       commands to be separated by |s
+	     * browser listings now use the "nowrap" option
+	     * browser: some unuseful error messages now suppressed
+	v54: * For backwards compatibility, Explore and Sexplore have been
+	       implemented.  In addition, Hexplore and Vexplore commands
+	       are available, too.
+	     * <amatch> used instead of <afile> in the transparency
+	       support (BufReadCmd, FileReadCmd, FileWriteCmd)
+	     * ***netrw*** prepended to various error messages netrw may emit
+	     * g:netrw_port used instead of b:netrw_port for scp
+	     * any leading [:#] is removed from port numbers
+	v53: * backslashes as well as slashes placed in various patterns
+	       (ex. g:netrw_sort_sequence) to better support Windows
+	v52: * nonumber'ing now set for browsing buffers
+	     * when the hiding list hid all files, error messages ensued. Fixed
+	     * when browsing, swf is set, but directory is not set, when netrw
+	       was attempting to restore options, vim wanted to save a swapfile
+	       to a local directory using an url-style path.  Fixed
+	v51: * cygwin detection now automated (using windows and &shell is bash)
+	     * customizable browser "file" rejection patterns
+	     * directory history
+	     * :[range]w url  now supported (ie. netrw has a FileWriteCmd event)
+	     * error messages have a "Press <cr> to continue" to allow them
+	       to be seen
+	     * directory browser displays no longer bother the swapfile
+	     * u/U commands to go up and down the history stack
+	     * history stack may be saved with viminfo with its "!" option
+	     * bugfixes associated with unwanted [No Files] entries
+	v50: * directories now displayed using buftype=nofile; should keep the
+	       directory names as-is
+	     * attempts to remove empty "[No File]" buffers leftover
+	       from :file ..name.. commands
+	     * bugfix: a "caps-lock" editing difficulty left in v49 was fixed
+	     * syntax highlighting for "Showing:" the hiding list included
+	     * bookmarks can now be retained if "!" is in the viminfo option
+	v49: * will use ftp for http://.../ browsing v48:
+	     * One may use ftp to do remote host file browsing
+	     * (windows and !cygwin) remote browsing with ftp can now use
+	       the "dir" command internally to provide listings
+	     * g:netrw_keepdir now allows one to keep the initial current
+	       directory as the current directory (normally the local file
+	       browser makes the currently viewed directory the current
+	       directory)
+	     * g:netrw_alto and g:netrw_altv now support alternate placement
+	       of windows started with o or v
+	     * Nread ? and Nwrite ?  now uses echomsg (instead of echo) so
+	       :messages can repeat showing the help
+	     * bugfix: avoids problems with partial matches of directory names
+	       to prior buffers with longer names
+	     * one can suppress error messages with g:netrw_quiet ctrl-h used
+	     * instead of <Leader>h for editing hiding list one may edit the
+	     * sorting sequence with the S map now allows confirmation of
+	     * deletion with [y(es) n(o) a(ll) q(uit)] the "x" map now handles
+	     * special file viewing with:
+	       (windows) rundll32 url.dll (gnome)   gnome-open (kde)
+	       kfmclient If none of these are on the executable path, then
+	       netrwFileHandlers.vim is used.
+	     * directory bookmarking during both local and remote browsing
+	       implemented
+	     * one may view all, use the hiding list to suppress, or use the
+	       hiding list to show-only remote and local file/directory
+	       listings
+	     * improved unusual file and directory name handling preview
+	     * window support
+	v47: * now handles local directory browsing.
+	v46: * now handles remote directory browsing
+	     * g:netrw_silent (if 1) will cause all transfers to be silent
+	v45: * made the [user@]hostname:path form a bit more restrictive to
+	       better handle errors in using protocols (e.g. scp:usr@host:file
+	       was being recognized as an rcp request) v44: * changed from
+	       "rsync -a" to just "rsync"
+	     * somehow an editing error messed up the test to recognize
+	       use of the fetch method for NetRead.
+	     * more debugging statements included
+	v43: * moved "Explanation" comments to <pi_netrw.txt> help file as
+	       "Network Reference" (|netrw-ref|)
+	     * <netrw.vim> now uses Dfunc() Decho() and Dret() for debugging
+	     * removed superfluous NetRestorePosn() calls
+	v42: * now does BufReadPre and BufReadPost events on file:///* and
+	       file://localhost/* v41: * installed file:///* and
+	       file://localhost/* handling v40: * prevents redraw when a
+	       protocol error occurs so that the user may see it v39: * sftp
+	       support v38: * Now uses NetRestorePosn() calls with
+	       Nread/Nwrite commands
+	     * Temporary files now removed via bwipe! instead of bwipe
+	       (thanks to Dave Roberts) v37: * Claar's modifications which
+	       test if ftp is successful, otherwise give an error message
+	     * After a read, the alternate file was pointing to the temp file.
+	       The temp file buffer is now wiped out.
+	     * removed silent from transfer methods so user can see what's
+	       happening
+
+
+==============================================================================
+12. Credits						*netrw-credits* {{{1
+
+	Vim editor	by Bram Moolenaar (Thanks, Bram!)
+	dav		support by C Campbell
+	fetch		support by Bram Moolenaar and C Campbell
+	ftp		support by C Campbell <NdrOchip@ScampbellPfamily.AbizM>
+	http		support by Bram Moolenaar <bram@moolenaar.net>
+	rcp
+	rsync		support by C Campbell (suggested by Erik Warendorph)
+	scp		support by raf <raf@comdyn.com.au>
+	sftp		support by C Campbell
+
+	inputsecret(), BufReadCmd, BufWriteCmd contributed by C Campbell
+
+	Jérôme Augé		-- also using new buffer method with ftp+.netrc
+	Bram Moolenaar		-- obviously vim itself, :e and v:cmdarg use,
+	                           fetch,...
+	Yasuhiro Matsumoto	-- pointing out undo+0r problem and a solution
+	Erik Warendorph		-- for several suggestions (g:netrw_..._cmd
+				   variables, rsync etc)
+	Doug Claar		-- modifications to test for success with ftp
+	                           operation
+
+==============================================================================
+ vim:tw=78:ts=8:ft=help:norl:fdm=marker
--- /dev/null
+++ b/lib/vimfiles/doc/pi_paren.txt
@@ -1,0 +1,50 @@
+*pi_paren.txt*  For Vim version 7.1.  Last change: 2006 Jun 14
+
+
+		  VIM REFERENCE MANUAL    by Bram Moolenaar
+
+
+Highlighting matching parens			*matchparen*
+
+The functionality mentioned here is a |standard-plugin|.
+This plugin is only available if 'compatible' is not set.
+
+You can avoid loading this plugin by setting the "loaded_matchparen" variable: >
+	:let loaded_matchparen = 1
+
+The plugin installs CursorMoved autocommands to redefine the match
+highlighting.
+
+To disable the plugin after it was loaded use this command: >
+
+	:NoMatchParen
+
+And to enable it again: >
+
+	:DoMatchParen
+
+The highlighting used is MatchParen.  You can specify different colors with
+the ":highlight" command.  Example: >
+
+	:hi MatchParen ctermbg=blue guibg=lightblue
+
+The characters to be matched come from the 'matchpairs' option.  You can
+change the value to highlight different matches.  Note that not everything is
+possible.  For example, you can't highlight single or double quotes, because
+the start and end are equal.
+
+The syntax highlighting attributes are used.  When the cursor currently is not
+in a string or comment syntax item, then matches inside string and comment
+syntax items are ignored.  Any syntax items with "string" or "comment"
+somewhere in their name are considered string or comment items.
+
+The search is limited to avoid a delay when moving the cursor.  The limits
+are:
+- What is visible in the window.
+- 100 lines above or below the cursor to avoid a long delay when there are
+  closed folds.
+- 'synmaxcol' times 2 bytes before or after the cursor to avoid a delay
+  in a long line with syntax highlighting.
+
+==============================================================================
+ vim:tw=78:ts=8:ft=help:norl:
--- /dev/null
+++ b/lib/vimfiles/doc/pi_spec.txt
@@ -1,0 +1,111 @@
+*pi_spec.txt*   For Vim version 7.1.  Last change: 2006 Apr 24
+
+by Gustavo Niemeyer ~
+
+This is a filetype plugin to work with rpm spec files.
+
+Currently, this Vim plugin allows you to easily update the %changelog
+section in RPM spec files.  It will even create a section for you if it
+doesn't exist yet.  If you've already inserted an entry today, it will
+give you the opportunity to just add a new item in today's entry.  If you
+don't provide a format string (|spec_chglog_format|), it'll ask you an
+email address and build a format string by itself.
+
+1. How to use it	|spec-how-to-use-it|
+2. Customizing		|spec-customizing|
+
+==============================================================================
+1. How to use it				*spec-how-to-use-it*
+
+The spec_chglog plugin provides a map like the following:
+
+	:map <buffer> <LocalLeader>c <Plug>SpecChangelog
+
+It means that you may run the plugin inside a spec file by pressing
+your maplocalleader key (default is '\') plus 'c'.  If you do not have
+|spec_chglog_format| set, the plugin will ask you for an email address
+to use in this edit session.
+
+Every time you run the plugin, it will check to see if the last entry in the
+changelog has been written today and by you.  If the entry matches, it will
+just insert a new changelog item, otherwise it will create a new changelog
+entry.  If you are running with |spec_chglog_release_info| enabled, it will
+also check if the name, version and release matches.  The plugin is smart
+enough to ask you if it should update the package release, if you have not
+done so.
+
+Setting a map					*spec-setting-a-map*
+-------------
+
+As you should know, you can easily set a map to access any Vim command (or
+anything, for that matter).  If you don't like the default map of
+<LocalLeader>c, you may just set up your own key.  The following line
+shows you how you could do this in your .vimrc file, mapping the plugin to
+the <F5> key:
+
+	au FileType spec map <buffer> <F5> <Plug>SpecChangelog
+
+Note: the plugin will respect your desire to change the default mapping
+      and won't set it.
+
+This command will add a map only in the spec file buffers.
+
+
+==============================================================================
+2. Customizing					*spec-customizing*
+
+The format string				*spec_chglog_format*
+-----------------
+
+You can easily customize how your spec file entry will look like.  To do
+this just set the variable "spec_chglog_format" in your .vimrc file like
+this: >
+
+	let spec_chglog_format = "%a %b %d %Y My Name <my@email.com>"
+
+Note that "%a %b %d %Y" is the most used time format.  If you don't provide
+a format string, when you run the SpecChangelog command for the first
+time, it will ask you an email address and build the |spec_chglog_format|
+variable for you.  This way, you will only need to provide your email
+address once.
+
+To discover which format options you can use, take a look at the strftime()
+function man page.
+
+Where to insert new items			*spec_chglog_prepend*
+-------------------------
+
+The plugin will usually insert new %changelog entry items (note that it's
+not the entry itself) after the existing ones.  If you set the
+spec_chglog_prepend variable >
+
+	let spec_chglog_prepend = 1
+
+it will insert new items before the existing ones.
+
+Inserting release info				*spec_chglog_release_info*
+----------------------
+
+If you want, the plugin may automatically insert release information
+on each changelog entry.  One advantage of turning this feature on is
+that it may control if the release has been updated after the last
+change in the package or not.  If you have not updated the package
+version or release, it will ask you if it should update the package
+release for you.  To turn this feature on, just insert the following
+code in your .vimrc: >
+
+	let spec_chglog_release_info = 1
+
+Then, the first item in your changelog entry will be something like: >
+
+	+ name-1.0-1cl
+
+If you don't like the release updating feature and don't want to answer
+"No" each time it detects an old release, you may disable it with >
+
+	let spec_chglog_never_increase_release = 1
+
+
+Good luck!!
+
+vim:tw=78:ts=8:ft=help:norl:
--- /dev/null
+++ b/lib/vimfiles/doc/pi_tar.txt
@@ -1,0 +1,68 @@
+*pi_tar.txt*	For Vim version 7.1.  Last change: 2006 Sep 29
+
+       	       	       +====================+
+       	       	       | Tar File Interface |
+       	       	       +====================+
+
+Author:  Charles E. Campbell, Jr.  <NdrOchip@ScampbellPfamily.AbizM>
+	  (remove NOSPAM from Campbell's email first)
+Copyright: The GPL (gnu public license) applies to	*tar-copyright*
+	   tarPlugin.vim, and pi_tar.txt.
+	   No warranty, express or implied.  Use At-Your-Own-Risk.
+
+==============================================================================
+1. Contents					*tar* *tar-contents*
+   1. Contents..................................................|tar-contents|
+   2. Usage.....................................................|tar-usage|
+   3. Options...................................................|tar-options|
+   4. History...................................................|tar-history|
+
+==============================================================================
+2. Usage					*tar-usage* *tar-manual*
+
+   When one edits a *.tar file, this plugin will handle displaying a
+   contents page.  Select a file to edit by moving the cursor atop
+   the desired file, then hit the <return> key.  After editing, one may
+   also write to the file.  Currently, one may not make a new file in
+   tar archives via the plugin.
+
+==============================================================================
+3. Options						*tar-options*
+
+   These options are variables that one may change, typically in one's
+   <.vimrc> file.
+                         Default
+   Variable               Value   Explanation
+   *g:tar_browseoptions*  "Ptf"   used to get a list of contents
+   *g:tar_readoptions*    "OPxf"  used to extract a file from a tarball
+   *g:tar_cmd*            "tar"   the name of the tar program
+   *g:tar_writeoptions*   "uf"    used to update/replace a file
+
+
+==============================================================================
+4. History						*tar-history*
+
+   v10 May 02, 2006 * now using "redraw then echo" to show messages, instead
+                      of "echo and prompt user"
+   v9 May 02, 2006 * improved detection of masquerading as tar file
+   v8 May 02, 2006 * allows editing of files that merely masquerade as tar
+                     files
+   v7 Mar 22, 2006 * work on making tar plugin work across network
+      Mar 27, 2006 * g:tar_cmd now available for users to change the name
+                     of the tar program to be used.  By default, of course,
+		     its "tar".
+   v6 Dec 21, 2005 * writing to files not in directories caused problems -
+                     fixed (pointed out by Christian Robinson)
+   v5 Nov 22, 2005 * report option workaround installed
+   v3 Sep 16, 2005 * handles writing files in an archive back to the
+                     archive
+      Oct 18, 2005 * <amatch> used instead of <afile> in autocmds
+      Oct 18, 2005 * handles writing to compressed archives
+      Nov 03, 2005 * handles writing tarfiles across a network using
+                     netrw#NetWrite()
+   v2              * converted to use Vim7's new autoload feature by
+                     Bram Moolenaar
+   v1 (original)   * Michael Toren (see http://michael.toren.net/code/)
+
+==============================================================================
+vim:tw=78:ts=8:ft=help
--- /dev/null
+++ b/lib/vimfiles/doc/pi_vimball.txt
@@ -1,0 +1,138 @@
+*pi_vimball.txt*	For Vim version 7.1.  Last change: 2007 May 11
+
+			       ----------------
+			       Vimball Archiver
+			       ----------------
+
+Author:  Charles E. Campbell, Jr.  <NdrOchip@ScampbellPfamily.AbizM>
+	  (remove NOSPAM from Campbell's email first)
+Copyright: (c) 2004-2006 by Charles E. Campbell, Jr.	*Vimball-copyright*
+	   The VIM LICENSE applies to Vimball.vim, and Vimball.txt
+	   (see |copyright|) except use "Vimball" instead of "Vim".
+	   No warranty, express or implied.
+	   Use At-Your-Own-Risk!
+
+==============================================================================
+1. Contents				*vba* *vimball* *vimball-contents*
+
+	1. Contents......................................: |vimball-contents|
+	2. Vimball Manual................................: |vimball-manual|
+	   MkVimball.....................................: |:MkVimball|
+	   UseVimball....................................: |:UseVimball|
+	   RmVimball.....................................: |:RmVimball|
+	3. Vimball History...............................: |vimball-history|
+
+
+==============================================================================
+2. Vimball Manual					*vimball-manual*
+
+							*:MkVimball*
+		:[range]MkVimball[!] filename [path]
+
+	The range is composed of lines holding paths to files to be included
+	in your new vimball.  As an example: >
+		plugin/something.vim
+		doc/something.txt
+<	using >
+		:[range]MkVimball filename
+<
+	on this range of lines will create a file called "filename.vba" which
+	can be used by Vimball.vim to re-create these files.  If the
+	"filename.vba" file already exists, then MkVimball will issue a
+	warning and not create the file.  Note that these paths are relative
+	to your .vim (vimfiles) directory, and the files should be in that
+	directory.  The vimball plugin normally uses the first |'runtimepath'|
+	directory that exists as a prefix; don't use absolute paths, unless
+	the user has specified such a path.
+							*g:vimball_home*
+	You may override the use of the |'runtimepath'| by specifying a
+	variable, g:vimball_home.
+
+	If you use the exclamation point (!), then MkVimball will create the
+	"filename.vba" file, overwriting it if it already exists.  This
+	behavior resembles that for |:w|.
+
+							*vimball-extract*
+		vim filename.vba
+
+	Simply editing a Vimball will cause Vimball.vim to tell the user to
+	source the file to extract its contents.
+
+	Extraction will only proceed if the first line of a putative vimball
+	file holds the "Vimball Archiver by Charles E. Campbell, Jr., Ph.D."
+	line.
+
+		:VimballList				*:VimballList*
+
+	This command will tell Vimball to list the files in the archive, along
+	with their lengths in lines.
+
+		:UseVimball [path]			*:UseVimball*
+
+	This command is contained within the vimball itself; it invokes the
+	vimball#Vimball() routine which is responsible for unpacking the
+	vimball.  One may choose to execute it by hand instead of sourcing
+	the vimball; one may also choose to specify a path for the
+	installation, thereby overriding the automatic choice of the first
+	existing directory on the |'runtimepath'|.
+
+		:RmVimball vimballfile [path]		*:RmVimball*
+
+	This command removes all files generated by the specified vimball
+	(but not any directories it may have made).  One may choose a path
+	for de-installation, too (see |'runtimepath'|); otherwise, the
+	default is the first existing directory on the |'runtimepath'|.
+	To implement this, a file (.VimballRecord) is made in that directory
+	containing a record of what files need to be removed for all vimballs
+	used thus far.
+
+
+==============================================================================
+3. Vimball History					*vimball-history* {{{1
+
+	22 : Mar 21, 2007 * uses setlocal instead of set during BufEnter
+	21 : Nov 27, 2006 * (tnx to Bill McCarthy) vimball had a header
+	                    handling problem and it now changes \s to /s
+	20 : Nov 20, 2006 * substitute() calls have all had the 'e' flag
+	                    removed.
+	18 : Aug 01, 2006 * vimballs now use folding to easily display their
+	                    contents.
+			  * if a user has AsNeeded/somefile, then vimball
+			    will extract plugin/somefile to the AsNeeded/
+			    directory
+	17 : Jun 28, 2006 * changes all \s to /s internally for Windows
+	16 : Jun 15, 2006 * A. Mechelynck's idea to allow users to specify
+			    installation root paths implemented for
+			    UseVimball, MkVimball, and RmVimball.
+			  * RmVimball implemented
+	15 : Jun 13, 2006 * bugfix
+	14 : May 26, 2006 * bugfixes
+	13 : May 01, 2006 * exists("&acd") used to determine if the acd
+			    option exists
+	12 : May 01, 2006 * bugfix - the |'acd'| option is not always defined
+	11 : Apr 27, 2006 * VimballList would create missing subdirectories that
+			    the vimball specified were needed.  Fixed.
+	10 : Apr 27, 2006 * moved all setting saving/restoration to a pair of
+			    functions.  Included some more settings in them
+			    which frequently cause trouble.
+	9  : Apr 26, 2006 * various changes to support Windows predilection
+			    for backslashes and spaces in file and directory
+			    names.
+	7  : Apr 25, 2006 * bypasses foldenable
+			  * uses more exe and less norm! (:yank :put etc)
+			  * does better at insuring a "Press ENTER" prompt
+			    appears to keep its messages visible
+	4  : Mar 31, 2006 * BufReadPost seems to fire twice; BufReadEnter
+			    only fires once, so the "Source this file..."
+			    message is now issued only once.
+	3  : Mar 20, 2006 * removed query, now requires sourcing to be
+			    extracted (:so %).  Message to that effect
+			    included.
+			  * :VimballList  now shows files that would be
+			    extracted.
+	2  : Mar 20, 2006 * query, :UseVimball included
+	1  : Mar 20, 2006 * initial release
+
+
+==============================================================================
+vim:tw=78:ts=8:ft=help:fdm=marker
--- /dev/null
+++ b/lib/vimfiles/doc/pi_zip.txt
@@ -1,0 +1,97 @@
+*pi_zip.txt*	For Vim version 7.1.  Last change: 2007 May 11
+
+				+====================+
+				| Zip File Interface |
+				+====================+
+
+Author:  Charles E. Campbell, Jr.  <NdrOchip@ScampbellPfamily.AbizM>
+	  (remove NOSPAM from Campbell's email first)
+Copyright: Copyright (C) 2005,2006 Charles E Campbell, Jr *zip-copyright*
+           Permission is hereby granted to use and distribute this code,
+	   with or without modifications, provided that this copyright
+	   notice is copied with it. Like anything else that's free,
+	   zip.vim, zipPlugin.vim, and pi_zip.txt are provided *as is*
+	   and it comes with no warranty of any kind, either expressed or
+	   implied. By using this plugin, you agree that in no event will
+	   the copyright holder be liable for any damages resulting from
+	   the use of this software.
+
+==============================================================================
+1. Contents					*zip* *zip-contents*
+   1. Contents................................................|zip-contents|
+   2. Usage...................................................|zip-usage|
+   3. Additional Extensions...................................|zip-extension|
+   4. History.................................................|zip-history|
+
+==============================================================================
+2. Usage					*zip-usage* *zip-manual*
+
+   When one edits a *.zip file, this plugin will handle displaying a
+   contents page.  Select a file to edit by moving the cursor atop
+   the desired file, then hit the <return> key.  After editing, one may
+   also write to the file.  Currently, one may not make a new file in
+   zip archives via the plugin.
+
+   OPTIONS
+							*zip_shq*
+   Different operating systems may use one or more shells to execute
+   commands.  Zip will try to guess the correct quoting mechanism to
+   allow spaces and whatnot in filenames; however, if it is incorrectly
+   guessing the quote to use for your setup, you may use >
+	g:zip_shq
+<  which by default is a single quote under Unix (') and a double quote
+   under Windows (").  If you'd rather have no quotes, simply set
+   g:zip_shq to the empty string (let g:zip_shq= "") in your <.vimrc>.
+
+   							*g:zip_unzipcmd*
+   Use this option to specify the program which does the duty of "unzip".
+   Its used during browsing. By default: >
+   	let g:zip_unzipcmd= "unzip"
+<
+							*g:zip_zipcmd*
+   Use this option to specify the program which does the duty of "zip".
+   Its used during the writing (updating) of a file already in a zip
+   file; by default: >
+   	let g:zip_zipcmd= "zip"
+<
+
+==============================================================================
+3. Additional Extensions					*zip-extension*
+
+   Apparently there are a number of archivers who generate zip files that
+   don't use the .zip extension (.jar, .xpi, etc).  To handle such files,
+   place a line in your <.vimrc> file: >
+
+	au BufReadCmd *.jar,*.xpi call zip#Browse(expand("<amatch>"))
+<
+   One can simply extend this line to accommodate additional extensions that
+   are actually zip files.
+
+==============================================================================
+4. History					*zip-history* {{{1
+   v14 May 07, 2007 * using b:zipfile instead of w:zipfile to avoid problem
+                      when editing alternate file to bring up a zipfile
+   v10 May 02, 2006 * now using "redraw then echo" to show messages, instead
+                      of "echo and prompt user"
+		    * g:zip_shq provided to allow for quoting control for the
+		      command being passed via :r! ... commands.
+   v8 Apr 10, 2006 * Bram Moolenaar reported that he received an error message
+                     due to "Pattern not found: ^.*\%0c"; this was caused by
+		     stridx finding a Name... at the beginning of the line;
+		     zip.vim tried 4,$s/^.*\%0c//, but that doesn't work.
+		     Fixed.
+   v7 Mar 22, 2006 * escaped some characters that can cause filename handling
+                     problems.
+   v6 Dec 21, 2005 * writing to files not in directories caused problems -
+                     fixed (pointed out by Christian Robinson)
+   v5 Nov 22, 2005 * report option workaround installed
+   v3 Oct 18, 2005 * <amatch> used instead of <afile> in autocmds
+   v2 Sep 16, 2005 * silenced some commands (avoiding hit-enter prompt)
+                   * began testing under Windows; works thus far
+		   * filetype detection fixed
+      Nov 03, 2005 * handles writing zipfiles across a network using
+                     netrw#NetWrite()
+   v1 Sep 15, 2005 * Initial release, had browsing, reading, and writing
+
+==============================================================================
+vim:tw=78:ts=8:ft=help:fdm=marker
--- /dev/null
+++ b/lib/vimfiles/doc/print.txt
@@ -1,0 +1,751 @@
+*print.txt*     For Vim version 7.1.  Last change: 2007 Apr 22
+
+
+		  VIM REFERENCE MANUAL    by Bram Moolenaar
+
+
+Printing						*printing*
+
+1. Introduction				|print-intro|
+2. Print options			|print-options|
+3. PostScript Printing			|postscript-printing|
+4. PostScript Printing Encoding		|postscript-print-encoding|
+5. PostScript CJK Printing		|postscript-cjk-printing|
+6. PostScript Printing Troubleshooting	|postscript-print-trouble|
+7. PostScript Utilities			|postscript-print-util|
+8. Formfeed Characters			|printing-formfeed|
+
+{Vi has None of this}
+{only available when compiled with the |+printer| feature}
+
+==============================================================================
+1. Introduction						*print-intro*
+
+On MS-Windows Vim can print your text on any installed printer.  On other
+systems a PostScript file is produced.  This can be directly sent to a
+PostScript printer.  For other printers a program like ghostscript needs to be
+used.
+
+					*:ha* *:hardcopy* *E237* *E238* *E324*
+:[range]ha[rdcopy][!] [arguments]
+			Send [range] lines (default whole file) to the
+			printer.
+
+			On MS-Windows a dialog is displayed to allow selection
+			of printer, paper size etc.  To skip the dialog, use
+			the [!].  In this case the printer defined by
+			'printdevice' is used, or, if 'printdevice' is empty,
+			the system default printer.
+
+			For systems other than MS-Windows, PostScript is
+			written in a temp file and 'printexpr' is used to
+			actually print it.  Then [arguments] can be used by
+			'printexpr' through |v:cmdarg|.  Otherwise [arguments]
+			is ignored.  'printoptions' can be used to specify
+			paper size, duplex, etc.
+
+:[range]ha[rdcopy][!] >{filename}
+			As above, but write the resulting PostScript in file
+			{filename}.
+			Things like "%" are expanded |cmdline-special|
+			Careful: An existing file is silently overwritten.
+			{only available when compiled with the |+postscript|
+			feature}
+			On MS-Windows use the "print to file" feature of the
+			printer driver.
+
+Progress is displayed during printing as a page number and a percentage.  To
+abort printing use the interrupt key (CTRL-C or, on MS-systems, CTRL-Break).
+
+Printer output is controlled by the 'printfont' and 'printoptions' options.
+'printheader' specifies the format of a page header.
+
+The printed file is always limited to the selected margins, irrespective of
+the current window's 'wrap' or 'linebreak' settings.  The "wrap" item in
+'printoptions' can be used to switch wrapping off.
+The current highlighting colors are used in the printout, with the following
+considerations:
+1) The normal background is always rendered as white (i.e. blank paper).
+2) White text or the default foreground is rendered as black, so that it shows
+   up!
+3) If 'background' is "dark", then the colours are darkened to compensate for
+   the fact that otherwise they would be too bright to show up clearly on
+   white paper.
+
+==============================================================================
+2. Print options					*print-options*
+
+Here are the details for the options that change the way printing is done.
+For generic info about setting options see |options.txt|.
+
+							*pdev-option*
+'printdevice' 'pdev'	string	(default empty)
+			global
+This defines the name of the printer to be used when the |:hardcopy| command
+is issued with a bang (!) to skip the printer selection dialog.  On Win32, it
+should be the printer name exactly as it appears in the standard printer
+dialog.
+If the option is empty, then vim will use the system default printer for
+":hardcopy!"
+
+							*penc-option* *E620*
+'printencoding' 'penc'	String	(default empty, except for:
+					Windows, OS/2: cp1252,
+					Macintosh: mac-roman,
+					VMS: dec-mcs,
+					HPUX: hp-roman8,
+					EBCDIC: ebcdic-uk)
+			global
+Sets the character encoding used when printing.  This option tells VIM which
+print character encoding file from the "print" directory in 'runtimepath' to
+use.
+
+This option will accept any value from |encoding-names|.  Any recognized names
+are converted to VIM standard names - see 'encoding' for more details.  Names
+not recognized by VIM will just be converted to lower case and underscores
+replaced with '-' signs.
+
+If 'printencoding' is empty or VIM cannot find the file then it will use
+'encoding' (if VIM is compiled with |+multi_byte| and it is set an 8-bit
+encoding) to find the print character encoding file.  If VIM is unable to find
+a character encoding file then it will use the "latin1" print character
+encoding file.
+
+When 'encoding' is set to a multi-byte encoding, VIM will try to convert
+characters to the printing encoding for printing (if 'printencoding' is empty
+then the conversion will be to latin1).  Conversion to a printing encoding
+other than latin1 will require VIM to be compiled with the |+iconv| feature.
+If no conversion is possible then printing will fail.  Any characters that
+cannot be converted will be replaced with upside down question marks.
+
+Four print character encoding files are provided to support default Mac, VMS,
+HPUX, and EBCDIC character encodings and are used by default on these
+platforms.  Code page 1252 print character encoding is used by default on
+Windows and OS/2 platforms.
+
+							*pexpr-option*
+'printexpr' 'pexpr'	String	(default: see below)
+			global
+Expression that is evaluated to print the PostScript produced with
+|:hardcopy|.
+The file name to be printed is in |v:fname_in|.
+The arguments to the ":hardcopy" command are in |v:cmdarg|.
+The expression must take care of deleting the file after printing it.
+When there is an error, the expression must return a non-zero number.
+If there is no error, return zero or an empty string.
+The default for non MS-Windows or VMS systems is to simply use "lpr" to print
+the file: >
+
+    system('lpr' . (&printdevice == '' ? '' : ' -P' . &printdevice)
+	. ' ' . v:fname_in) . delete(v:fname_in) + v:shell_error
+
+On MS-Dos, MS-Windows and OS/2 machines the default is to copy the file to the
+currently specified printdevice: >
+
+    system('copy' . ' ' . v:fname_in . (&printdevice == ''
+		? ' LPT1:' : (' \"' . &printdevice . '\"')))
+		. delete(v:fname_in)
+
+On VMS machines the default is to send the file to either the default or
+currently specified printdevice: >
+
+    system('print' . (&printdevice == '' ? '' : ' /queue=' .
+		&printdevice) . ' ' . v:fname_in) . delete(v:fname_in)
+
+If you change this option, using a function is an easy way to avoid having to
+escape all the spaces.  Example: >
+
+	:set printexpr=PrintFile(v:fname_in)
+	:function PrintFile(fname)
+	:  call system("ghostview " . a:fname)
+	:  call delete(a:fname)
+	:  return v:shell_error
+	:endfunc
+
+Be aware that some print programs return control before they have read the
+file.  If you delete the file too soon it will not be printed.  These programs
+usually offer an option to have them remove the file when printing is done.
+							*E365*
+If evaluating the expression fails or it results in a non-zero number, you get
+an error message.  In that case Vim will delete the file.  In the default
+value for non-MS-Windows a trick is used: Adding "v:shell_error" will result
+in a non-zero number when the system() call fails.
+
+This option cannot be set from a |modeline| or in the |sandbox|, for security
+reasons.
+
+							*pfn-option* *E613*
+'printfont' 'pfn'	string	(default "courier")
+			global
+This is the name of the font that will be used for the |:hardcopy| command's
+output.  It has the same format as the 'guifont' option, except that only one
+font may be named, and the special "guifont=*" syntax is not available.
+
+In the Win32 GUI version this specifies a font name with its extra attributes,
+as with the 'guifont' option.
+
+For other systems, only ":h11" is recognized, where "11" is the point size of
+the font.  When omitted, the point size is 10.
+
+							*pheader-option*
+'printheader' 'pheader'  string  (default "%<%f%h%m%=Page %N")
+			 global
+This defines the format of the header produced in |:hardcopy| output.  The
+option is defined in the same way as the 'statusline' option.  If Vim has not
+been compiled with the |+statusline| feature, this option has no effect and a
+simple default header is used, which shows the page number.
+
+							*pmbcs-option*
+'printmbcharset' 'pmbcs'  string (default "")
+			  global
+Sets the CJK character set to be used when generating CJK output from
+|:hardcopy|.  The following predefined values are currently recognised by VIM:
+
+		Value		Description ~
+  Chinese	GB_2312-80
+  (Simplified)	GBT_12345-90
+		MAC		Apple Mac Simplified Chinese
+		GBT-90_MAC	GB/T 12345-90 Apple Mac Simplified
+				  Chinese
+		GBK		GBK (GB 13000.1-93)
+		ISO10646	ISO 10646-1:1993
+
+  Chinese	CNS_1993	CNS 11643-1993, Planes 1 & 2
+  (Traditional)	BIG5
+		ETEN		Big5 with ETen extensions
+		ISO10646	ISO 10646-1:1993
+
+  Japanese	JIS_C_1978
+		JIS_X_1983
+		JIS_X_1990
+		MSWINDOWS	Win3.1/95J (JIS X 1997 + NEC +
+				  IBM extensions)
+		KANJITALK6	Apple Mac KanjiTalk V6.x
+		KANJITALK7	Apple Mac KanjiTalk V7.x
+
+  Korean	KS_X_1992
+		MAC		Apple Macintosh Korean
+		MSWINDOWS	KS X 1992 with MS extensions
+		ISO10646	ISO 10646-1:1993
+
+Only certain combinations of the above values and 'printencoding' are
+possible.  The following tables show the valid combinations:
+
+				euc-cn	 gbk	ucs-2	utf-8 ~
+  Chinese	GB_2312-80	   x
+  (Simplified)	GBT_12345-90	   x
+		MAC		   x
+		GBT-90_MAC	   x
+		GBK			   x
+		ISO10646			  x	  x
+
+				euc-tw	 big5	ucs-2	utf-8 ~
+  Chinese	CNS_1993	   x
+  (Traditional)	BIG5			   x
+		ETEN			   x
+		ISO10646			  x	  x
+
+				euc-jp	 sjis	ucs-2	utf-8 ~
+  Japanese	JIS_C_1978	   x	   x
+		JIS_X_1983	   x	   x
+		JIS_X_1990	   x		  x	  x
+		MSWINDOWS	   x
+		KANJITALK6	   x
+		KANJITALK7	   x
+
+				euc-kr	 cp949	ucs-2	utf-8 ~
+  Korean	KS_X_1992	   x
+		MAC		   x
+		MSWINDOWS		   x
+		ISO10646			  x	  x
+
+To set up the correct encoding and character set for printing some
+Japanese text you would do the following; >
+	:set printencoding=euc-jp
+	:set printmbcharset=JIS_X_1983
+
+If 'printmbcharset' is not one of the above values then it is assumed to
+specify a custom multi-byte character set and no check will be made that it is
+compatible with the value for 'printencoding'.  VIM will look for a file
+defining the character set in the "print" directory in 'runtimepath'.
+
+							*pmbfn-option*
+'printmbfont' 'pmbfn'	string (default "")
+			global
+This is a comma-separated list of fields for font names to be used when
+generating CJK output from |:hardcopy|.  Each font name has to be preceded
+with a letter indicating the style the font is to be used for as follows:
+
+  r:{font-name}		font to use for normal characters
+  b:{font-name}		font to use for bold characters
+  i:{font-name}		font to use for italic characters
+  o:{font-name}		font to use for bold-italic characters
+
+A field with the r: prefix must be specified when doing CJK printing.  The
+other fontname specifiers are optional.  If a specifier is missing then
+another font will be used as follows:
+
+  if b: is missing, then use r:
+  if i: is missing, then use r:
+  if o: is missing, then use b:
+
+Some CJK fonts do not contain characters for codes in the ASCII code range.
+Also, some characters in the CJK ASCII code ranges differ in a few code points
+from traditional ASCII characters.  There are two additional fields to control
+printing of characters in the ASCII code range.
+
+  c:yes			Use Courier font for characters in the ASCII
+  c:no (default)	code range.
+
+  a:yes			Use ASCII character set for codes in the ASCII
+  a:no (default)	code range.
+
+The following is an example of specifying two multi-byte fonts, one for normal
+and italic printing and one for bold and bold-italic printing, and using
+Courier to print codes in the ASCII code range but using the national
+character set: >
+	:set printmbfont=r:WadaMin-Regular,b:WadaMin-Bold,c:yes
+<
+							*popt-option*
+'printoptions' 'popt'	string (default "")
+			global
+This is a comma-separated list of items that control the format of the output
+of |:hardcopy|:
+
+  left:{spec}		left margin (default: 10pc)
+  right:{spec}		right margin (default: 5pc)
+  top:{spec}		top margin (default: 5pc)
+  bottom:{spec}		bottom margin (default: 5pc)
+			{spec} is a number followed by "in" for inches, "pt"
+			for points (1 point is 1/72 of an inch), "mm" for
+			millimeters or "pc" for a percentage of the media
+			size.
+			Weird example:
+			    left:2in,top:30pt,right:16mm,bottom:3pc
+			If the unit is not recognized there is no error and
+			the default value is used.
+
+  header:{nr}		Number of lines to reserve for the header.
+			Only the first line is actually filled, thus when {nr}
+			is 2 there is one empty line.  The header is formatted
+			according to 'printheader'.
+  header:0		Do not print a header.
+  header:2  (default)	Use two lines for the header
+
+  syntax:n		Do not use syntax highlighting.  This is faster and
+			thus useful when printing large files.
+  syntax:y		Do syntax highlighting.
+  syntax:a  (default)	Use syntax highlighting if the printer appears to be
+			able to print color or grey.
+
+  number:y		Include line numbers in the printed output.
+  number:n  (default)	No line numbers.
+
+  wrap:y    (default)	Wrap long lines.
+  wrap:n		Truncate long lines.
+
+  duplex:off		Print on one side.
+  duplex:long (default)	Print on both sides (when possible), bind on long
+			side.
+  duplex:short		Print on both sides (when possible), bind on short
+			side.
+
+  collate:y  (default)	Collating: 1 2 3, 1 2 3, 1 2 3
+  collate:n		No collating: 1 1 1, 2 2 2, 3 3 3
+
+  jobsplit:n (default)	Do all copies in one print job
+  jobsplit:y		Do each copy as a separate print job.  Useful when
+			doing N-up postprocessing.
+
+  portrait:y (default)	Orientation is portrait.
+  portrait:n		Orientation is landscape.
+						*a4* *letter*
+  paper:A4   (default)	Paper size: A4
+  paper:{name}		Paper size from this table:
+			{name}	    size in cm	     size in inch ~
+			10x14	    25.4  x 35.57    10    x 14
+			A3	    29.7  x 42	     11.69 x 16.54
+			A4	    21	  x 29.7      8.27 x 11.69
+			A5	    14.8  x 21	      5.83 x  8.27
+			B4	    25	  x 35.3     10.12 x 14.33
+			B5	    17.6  x 25	      7.17 x 10.12
+			executive   18.42 x 26.67     7.25 x 10.5
+			folio	    21	  x 33	      8.27 x 13
+			ledger	    43.13 x 27.96    17    x 11
+			legal	    21.59 x 35.57     8.5  x 14
+			letter	    21.59 x 27.96     8.5  x 11
+			quarto	    21.59 x 27.5      8.5  x 10.83
+			statement   13.97 x 21.59     5.5  x  8.5
+			tabloid     27.96 x 43.13    11    x 17
+
+  formfeed:n (default)	Treat form feed characters (0x0c) as a normal print
+			character.
+  formfeed:y		When a form feed character is encountered, continue
+			printing of the current line at the beginning of the
+			first line on a new page.
+
+The item indicated with (default) is used when the item is not present.  The
+values are not always used, especially when using a dialog to select the
+printer and options.
+Example: >
+	:set printoptions=paper:letter,duplex:off
+
+==============================================================================
+3. PostScript Printing					*postscript-printing*
+						*E455* *E456* *E457* *E624*
+Provided you have enough disk space there should be no problems generating a
+PostScript file.  You need to have the runtime files correctly installed (if
+you can find the help files, they probably are).
+
+There are currently a number of limitations with PostScript printing:
+
+- 'printfont' - The font name is ignored (the Courier family is always used -
+  it should be available on all PostScript printers) but the font size is
+  used.
+
+- 'printoptions' - The duplex setting is used when generating PostScript
+  output, but it is up to the printer to take notice of the setting.  If the
+  printer does not support duplex printing then it should be silently ignored.
+  Some printers, however, don't print at all.
+
+- 8-bit support - While a number of 8-bit print character encodings are
+  supported it is possible that some characters will not print.  Whether a
+  character will print depends on the font in the printer knowing the
+  character.  Missing characters will be replaced with an upside down question
+  mark, or a space if that character is also not known by the font.  It may be
+  possible to get all the characters in an encoding to print by installing a
+  new version of the Courier font family.
+
+- Multi-byte support - Currently VIM will try to convert multi-byte characters
+  to the 8-bit encoding specified by 'printencoding' (or latin1 if it is
+  empty).  Any characters that are not successfully converted are shown as
+  unknown characters.  Printing will fail if VIM cannot convert the multi-byte
+  to the 8-bit encoding.
+
+==============================================================================
+4. Custom 8-bit Print Character Encodings	*postscript-print-encoding*
+								*E618* *E619*
+To use your own print character encoding when printing 8-bit character data
+you need to define your own PostScript font encoding vector.  Details on how
+to define a font encoding vector is beyond the scope of this help file, but
+you can find details in the PostScript Language Reference Manual, 3rd Edition,
+published by Addison-Wesley and available in PDF form at
+http://www.adobe.com/.  The following describes what you need to do for VIM to
+locate and use your print character encoding.
+
+i.   Decide on a unique name for your encoding vector, one that does not clash
+     with any of the recognized or standard encoding names that VIM uses (see
+     |encoding-names| for a list), and that no one else is likely to use.
+ii.  Copy $VIMRUNTIME/print/latin1.ps to the print subdirectory in your
+     'runtimepath' and rename it with your unique name.
+iii. Edit your renamed copy of latin1.ps, replacing all occurrences of latin1
+     with your unique name (don't forget the line starting %%Title:), and
+     modify the array of glyph names to define your new encoding vector.  The
+     array must have exactly 256 entries or you will not be able to print!
+iv.  Within VIM, set 'printencoding' to your unique encoding name and then
+     print your file.  VIM will now use your custom print character encoding.
+
+VIM will report an error with the resource file if you change the order or
+content of the first 3 lines, other than the name of the encoding on the line
+starting %%Title: or the version number on the line starting %%Version:.
+
+[Technical explanation for those that know PostScript - VIM looks for a file
+with the same name as the encoding it will use when printing.  The file
+defines a new PostScript Encoding resource called /VIM-name, where name is the
+print character encoding VIM will use.]
+
+==============================================================================
+5. PostScript CJK Printing			*postscript-cjk-printing*
+							*E673* *E674* *E675*
+
+VIM supports printing of Chinese, Japanese, and Korean files.  Setting up VIM
+to correctly print CJK files requires setting up a few more options.
+
+Each of these countries has many standard character sets and encodings which
+require that both be specified when printing.  In addition, CJK fonts normally
+do not have the concept of italic glyphs and use different weight or stroke
+style to achieve emphasis when printing.  This in turn requires a different
+approach to specifying fonts to use when printing.
+
+The encoding and character set are specified with the 'printencoding' and
+'printmbcharset' options.  If 'printencoding' is not specified then 'encoding'
+is used as normal.  If 'printencoding' is specified then characters will be
+translated to this encoding for printing.  You should ensure that the encoding
+is compatible with the character set needed for the file contents or some
+characters may not appear when printed.
+
+The fonts to use for CJK printing are specified with 'printmbfont'.  This
+option allows you to specify different fonts to use when printing characters
+which are syntax highlighted with the font styles normal, italic, bold and
+bold-italic.
+
+No CJK fonts are supplied with VIM.  There are some free Korean, Japanese, and
+Traditional Chinese fonts available at:
+
+  http://examples.oreilly.com/cjkvinfo/adobe/samples/
+
+You can find descriptions of the various fonts in the read me file at
+
+  http://examples.oreilly.com/cjkvinfo/adobe/00README
+
+Please read your printer documentation on how to install new fonts.
+
+CJK fonts can be large containing several thousand glyphs, and it is not
+uncommon to find that they only contain a subset of a national standard.  It
+is not unusual to find the fonts to not include characters for codes in the
+ASCII code range.  If you find half-width Roman characters are not appearing
+in your printout then you should configure VIM to use the Courier font the
+half-width ASCII characters with 'printmbfont'.  If your font does not include
+other characters then you will need to find another font that does.
+
+Another issue with ASCII characters, is that the various national character
+sets specify a couple of different glyphs in the ASCII code range.  If you
+print ASCII text using the national character set you may see some unexpected
+characters.  If you want true ASCII code printing then you need to configure
+VIM to output ASCII characters for the ASCII code range with 'printmbfont'.
+
+It is possible to define your own multi-byte character set although this
+should not be attempted lightly.  A discussion on the process if beyond the
+scope of these help files.  You can find details on CMap (character map) files
+in the document 'Adobe CMap and CIDFont Files Specification, Version 1.0',
+available from http://www.adobe.com as a PDF file.
+
+==============================================================================
+6. PostScript Printing Troubleshooting		*postscript-print-trouble*
+									*E621*
+Usually the only sign of a problem when printing with PostScript is that your
+printout does not appear.  If you are lucky you may get a printed page that
+tells you the PostScript operator that generated the error that prevented the
+print job completing.
+
+There are a number of possible causes as to why the printing may have failed:
+
+- Wrong version of the prolog resource file.  The prolog resource file
+  contains some PostScript that VIM needs to be able to print.  Each version
+  of VIM needs one particular version.  Make sure you have correctly installed
+  the runtime files, and don't have any old versions of a file called prolog
+  in the print directory in your 'runtimepath' directory.
+
+- Paper size.  Some PostScript printers will abort printing a file if they do
+  not support the requested paper size.  By default VIM uses A4 paper.  Find
+  out what size paper your printer normally uses and set the appropriate paper
+  size with 'printoptions'.  If you cannot find the name of the paper used,
+  measure a sheet and compare it with the table of supported paper sizes listed
+  for 'printoptions', using the paper that is closest in both width AND height.
+  Note: The dimensions of actual paper may vary slightly from the ones listed.
+  If there is no paper listed close enough, then you may want to try psresize
+  from PSUtils, discussed below.
+
+- Two-sided printing (duplex).  Normally a PostScript printer that does not
+  support two-sided printing will ignore any request to do it.  However, some
+  printers may abort the job altogether.  Try printing with duplex turned off.
+  Note: Duplex prints can be achieved manually using PS utils - see below.
+
+- Collated printing.  As with Duplex printing, most PostScript printers that
+  do not support collating printouts will ignore a request to do so.  Some may
+  not.  Try printing with collation turned off.
+
+- Syntax highlighting.  Some print management code may prevent the generated
+  PostScript file from being printed on a black and white printer when syntax
+  highlighting is turned on, even if solid black is the only color used.  Try
+  printing with syntax highlighting turned off.
+
+A safe printoptions setting to try is: >
+
+	:set printoptions=paper:A4,duplex:off,collate:n,syntax:n
+
+Replace "A4" with the paper size that best matches your printer paper.
+
+==============================================================================
+7. PostScript Utilities				*postscript-print-util*
+
+7.1 Ghostscript
+
+Ghostscript is a PostScript and PDF interpreter that can be used to display
+and print on non-PostScript printers PostScript and PDF files.  It can also
+generate PDF files from PostScript.
+
+Ghostscript will run on a wide variety of platforms.
+
+There are three available versions:
+
+- AFPL Ghostscript (formerly Aladdin Ghostscript) which is free for
+  non-commercial use.  It can be obtained from:
+
+    http://www.cs.wisc.edu/~ghost/
+
+- GNU Ghostscript which is available under the GNU General Public License.  It
+  can be obtained from:
+
+    ftp://mirror.cs.wisc.edu/pub/mirrors/ghost/gnu/
+
+- A commercial version for inclusion in commercial products.
+
+Additional information on Ghostscript can also be found at:
+
+  http://www.ghostscript.com/
+
+Support for a number of non PostScript printers is provided in the
+distribution as standard, but if you cannot find support for your printer
+check the Ghostscript site for other printers not included by default.
+
+
+7.2 Ghostscript Previewers.
+
+The interface to Ghostscript is very primitive so a number of graphical front
+ends have been created.  These allow easier PostScript file selection,
+previewing at different zoom levels, and printing.  Check supplied
+documentation for full details.
+
+X11
+
+- Ghostview.  Obtainable from:
+
+    http://www.cs.wisc.edu/~ghost/gv/
+
+- gv.  Derived from Ghostview.  Obtainable from:
+
+    http://wwwthep.physik.uni-mainz.de/~plass/gv/
+
+  Copies (possibly not the most recent) can be found at:
+
+    http://www.cs.wisc.edu/~ghost/gv/
+
+OpenVMS
+
+- Is apparently supported in the main code now (untested).  See:
+
+    http://wwwthep.physik.uni-mainz.de/~plass/gv/
+
+Windows and OS/2
+
+- GSview.  Obtainable from:
+
+    http://www.cs.wisc.edu/~ghost/gsview/
+
+DOS
+
+- ps_view.  Obtainable from:
+
+    ftp://ftp.pg.gda.pl/pub/TeX/support/ps_view/
+    ftp://ftp.dante.de/tex-archive/support/ps_view/
+
+Linux
+
+- GSview.  Linux version of the popular Windows and OS/2 previewer.
+  Obtainable from:
+
+    http://www.cs.wisc.edu/~ghost/gsview/
+
+- BMV.  Different from Ghostview and gv in that it doesn't use X but svgalib.
+  Obtainable from:
+
+    ftp://sunsite.unc.edu/pub/Linux/apps/graphics/viewers/svga/bmv-1.2.tgz
+
+
+7.3 PSUtils
+
+PSUtils is a collection of utility programs for manipulating PostScript
+documents.  Binary distributions are available for many platforms, as well as
+the full source.  PSUtils can be found at:
+
+  http://knackered.org/angus/psutils
+
+The utilities of interest include:
+
+- psnup.     Convert PS files for N-up printing.
+- psselect.  Select page range and order of printing.
+- psresize.  Change the page size.
+- psbook.    Reorder and lay out pages ready for making a book.
+
+The output of one program can be used as the input to the next, allowing for
+complex print document creation.
+
+
+N-UP PRINTING
+
+The psnup utility takes an existing PostScript file generated from VIM and
+convert it to an n-up version.  The simplest way to create a 2-up printout is
+to first create a PostScript file with: >
+
+	:hardcopy > test.ps
+
+Then on your command line execute: >
+
+	psnup -n 2 test.ps final.ps
+
+Note: You may get warnings from some Ghostscript previewers for files produced
+by psnup - these may safely be ignored.
+
+Finally print the file final.ps to your PostScript printer with your
+platform's print command.  (You will need to delete the two PostScript files
+afterwards yourself.)  'printexpr' could be modified to perform this extra
+step before printing.
+
+
+ALTERNATE DUPLEX PRINTING
+
+It is possible to achieve a poor man's version of duplex printing using the PS
+utility psselect.  This utility has options -e and -o for printing just the
+even or odd pages of a PS file respectively.
+
+First generate a PS file with the 'hardcopy' command, then generate a new
+files with all the odd and even numbered pages with: >
+
+	psselect -o test.ps odd.ps
+	psselect -e test.ps even.ps
+
+Next print odd.ps with your platform's normal print command.  Then take the
+print output, turn it over and place it back in the paper feeder.  Now print
+even.ps with your platform's print command.  All the even pages should now
+appear on the back of the odd pages.
+
+There a couple of points to bear in mind:
+
+1. Position of the first page.  If the first page is on top of the printout
+   when printing the odd pages then you need to reverse the order that the odd
+   pages are printed.  This can be done with the -r option to psselect.  This
+   will ensure page 2 is printed on the back of page 1.
+   Note: it is better to reverse the odd numbered pages rather than the even
+   numbered in case there are an odd number of pages in the original PS file.
+
+2. Paper flipping.  When turning over the paper with the odd pages printed on
+   them you may have to either flip them horizontally (along the long edge) or
+   vertically (along the short edge), as well as possibly rotating them 180
+   degrees.  All this depends on the printer - it will be more obvious for
+   desktop ink jets than for small office laser printers where the paper path
+   is hidden from view.
+
+
+==============================================================================
+8. Formfeed Characters					*printing-formfeed*
+
+By default VIM does not do any special processing of |formfeed| control
+characters.  Setting the 'printoptions' formfeed item will make VIM recognize
+formfeed characters and continue printing the current line at the beginning
+of the first line on a new page.  The use of formfeed characters provides
+rudimentary print control but there are certain things to be aware of.
+
+VIM will always start printing a line (including a line number if enabled)
+containing a formfeed character, even if it is the first character on the
+line.  This means if a line starting with a formfeed character is the first
+line of a page then VIM will print a blank page.
+
+Since the line number is printed at the start of printing the line containing
+the formfeed character, the remainder of the line printed on the new page
+will not have a line number printed for it (in the same way as the wrapped
+lines of a long line when wrap in 'printoptions' is enabled).
+
+If the formfeed character is the last character on a line, then printing will
+continue on the second line of the new page, not the first.  This is due to
+VIM processing the end of the line after the formfeed character and moving
+down a line to continue printing.
+
+Due to the points made above it is recommended that when formfeed character
+processing is enabled, printing of line numbers is disabled, and that form
+feed characters are not the last character on a line.  Even then you may need
+to adjust the number of lines before a formfeed character to prevent
+accidental blank pages.
+
+==============================================================================
+ vim:tw=78:ts=8:ft=help:norl:
--- /dev/null
+++ b/lib/vimfiles/doc/quickfix.txt
@@ -1,0 +1,1386 @@
+*quickfix.txt*  For Vim version 7.1.  Last change: 2007 May 10
+
+
+		  VIM REFERENCE MANUAL    by Bram Moolenaar
+
+
+This subject is introduced in section |30.1| of the user manual.
+
+1. Using QuickFix commands		|quickfix|
+2. The error window			|quickfix-window|
+3. Using more than one list of errors	|quickfix-error-lists|
+4. Using :make				|:make_makeprg|
+5. Using :grep				|grep|
+6. Selecting a compiler			|compiler-select|
+7. The error format			|error-file-format|
+8. The directory stack			|quickfix-directory-stack|
+9. Specific error file formats		|errorformats|
+
+{Vi does not have any of these commands}
+
+The quickfix commands are not available when the |+quickfix| feature was
+disabled at compile time.
+
+=============================================================================
+1. Using QuickFix commands			*quickfix* *Quickfix* *E42*
+
+Vim has a special mode to speedup the edit-compile-edit cycle.  This is
+inspired by the quickfix option of the Manx's Aztec C compiler on the Amiga.
+The idea is to save the error messages from the compiler in a file and use Vim
+to jump to the errors one by one.  You can examine each problem and fix it,
+without having to remember all the error messages.
+
+In Vim the quickfix commands are used more generally to find a list of
+positions in files.  For example, |:vimgrep| finds pattern matches.  You can
+use the positions in a script with the |getqflist()| function.  Thus you can
+do a lot more than the edit/compile/fix cycle!
+
+If you are using Manx's Aztec C compiler on the Amiga look here for how to use
+it with Vim: |quickfix-manx|.  If you are using another compiler you should
+save the error messages in a file and start Vim with "vim -q filename".  An
+easy way to do this is with the |:make| command (see below).  The
+'errorformat' option should be set to match the error messages from your
+compiler (see |errorformat| below).
+
+						*location-list* *E776*
+A location list is similar to a quickfix list and contains a list of positions
+in files.  A location list is associated with a window and each window can
+have a separate location list.  A location list can be associated with only
+one window.  The location list is independent of the quickfix list.
+
+When a window with a location list is split, the new window gets a copy of the
+location list.  When there are no references to a location list, the location
+list is destroyed.
+
+The following quickfix commands can be used.  The location list commands are
+similar to the quickfix commands, replacing the 'c' prefix in the quickfix
+command with 'l'.
+
+							*:cc*
+:cc[!] [nr]		Display error [nr].  If [nr] is omitted, the same
+			error is displayed again.  Without [!] this doesn't
+			work when jumping to another buffer, the current buffer
+			has been changed, there is the only window for the
+			buffer and both 'hidden' and 'autowrite' are off.
+			When jumping to another buffer with [!] any changes to
+			the current buffer are lost, unless 'hidden' is set or
+			there is another window for this buffer.
+			The 'switchbuf' settings are respected when jumping
+			to a buffer.
+
+							*:ll*
+:ll[!] [nr]		Same as ":cc", except the location list for the
+			current window is used instead of the quickfix list.
+
+							*:cn* *:cnext* *E553*
+:[count]cn[ext][!]	Display the [count] next error in the list that
+			includes a file name.  If there are no file names at
+			all, go to the [count] next error.  See |:cc| for
+			[!] and 'switchbuf'.
+
+							*:lne* *:lnext*
+:[count]lne[xt][!]	Same as ":cnext", except the location list for the
+			current window is used instead of the quickfix list.
+
+:[count]cN[ext][!]			*:cp* *:cprevious* *:cN* *:cNext*
+:[count]cp[revious][!]	Display the [count] previous error in the list that
+			includes a file name.  If there are no file names at
+			all, go to the [count] previous error.  See |:cc| for
+			[!] and 'switchbuf'.
+
+
+:[count]lN[ext][!]			*:lp* *:lprevious* *:lN* *:lNext*
+:[count]lp[revious][!]	Same as ":cNext" and ":cprevious", except the location
+			list for the current window is used instead of the
+			quickfix list.
+
+							*:cnf* *:cnfile*
+:[count]cnf[ile][!]	Display the first error in the [count] next file in
+			the list that includes a file name.  If there are no
+			file names at all or if there is no next file, go to
+			the [count] next error.  See |:cc| for [!] and
+			'switchbuf'.
+
+							*:lnf* *:lnfile*
+:[count]lnf[ile][!]	Same as ":cnfile", except the location list for the
+			current window is used instead of the quickfix list.
+
+:[count]cNf[ile][!]			*:cpf* *:cpfile* *:cNf* *:cNfile*
+:[count]cpf[ile][!]	Display the last error in the [count] previous file in
+			the list that includes a file name.  If there are no
+			file names at all or if there is no next file, go to
+			the [count] previous error.  See |:cc| for [!] and
+			'switchbuf'.
+
+
+:[count]lNf[ile][!]			*:lpf* *:lpfile* *:lNf* *:lNfile*
+:[count]lpf[ile][!]	Same as ":cNfile" and ":cpfile", except the location
+			list for the current window is used instead of the
+			quickfix list.
+
+							*:crewind* *:cr*
+:cr[ewind][!] [nr]	Display error [nr].  If [nr] is omitted, the FIRST
+			error is displayed.  See |:cc|.
+
+							*:lrewind* *:lr*
+:lr[ewind][!] [nr]	Same as ":crewind", except the location list for the
+			current window is used instead of the quickfix list.
+
+							*:cfirst* *:cfir*
+:cfir[st][!] [nr]	Same as ":crewind".
+
+							*:lfirst* *:lfir*
+:lfir[st][!] [nr]	Same as ":lrewind".
+
+							*:clast* *:cla*
+:cla[st][!] [nr]	Display error [nr].  If [nr] is omitted, the LAST
+			error is displayed.  See |:cc|.
+
+							*:llast* *:lla*
+:lla[st][!] [nr]	Same as ":clast", except the location list for the
+			current window is used instead of the quickfix list.
+
+							*:cq* *:cquit*
+:cq[uit]		Quit Vim with an error code, so that the compiler
+			will not compile the same file again.
+
+							*:cf* *:cfile*
+:cf[ile][!] [errorfile]	Read the error file and jump to the first error.
+			This is done automatically when Vim is started with
+			the -q option.  You can use this command when you
+			keep Vim running while compiling.  If you give the
+			name of the errorfile, the 'errorfile' option will
+			be set to [errorfile].  See |:cc| for [!].
+
+							*:lf* *:lfile*
+:lf[ile][!] [errorfile]	Same as ":cfile", except the location list for the
+			current window is used instead of the quickfix list.
+			You can not use the -q command-line option to set
+			the location list.
+
+
+:cg[etfile][!] [errorfile]				*:cg* *:cgetfile*
+			Read the error file.  Just like ":cfile" but don't
+			jump to the first error.
+
+
+:lg[etfile][!] [errorfile]				*:lg* *:lgetfile*
+			Same as ":cgetfile", except the location list for the
+			current window is used instead of the quickfix list.
+
+							*:caddf* *:caddfile*
+:caddf[ile] [errorfile]	Read the error file and add the errors from the
+			errorfile to the current quickfix list. If a quickfix
+			list is not present, then a new list is created.
+
+							*:laddf* *:laddfile*
+:laddf[ile] [errorfile]	Same as ":caddfile", except the location list for the
+			current window is used instead of the quickfix list.
+
+						*:cb* *:cbuffer* *E681*
+:cb[uffer][!] [bufnr]	Read the error list from the current buffer.
+			When [bufnr] is given it must be the number of a
+			loaded buffer.  That buffer will then be used instead
+			of the current buffer.
+			A range can be specified for the lines to be used.
+			Otherwise all lines in the buffer are used.
+			See |:cc| for [!].
+
+						*:lb* *:lbuffer*
+:lb[uffer][!] [bufnr]	Same as ":cbuffer", except the location list for the
+			current window is used instead of the quickfix list.
+
+						*:cgetb* *:cgetbuffer*
+:cgetb[uffer] [bufnr]	Read the error list from the current buffer.  Just
+			like ":cbuffer" but don't jump to the first error.
+
+						*:lgetb* *:lgetbuffer*
+:lgetb[uffer] [bufnr]	Same as ":cgetbuffer", except the location list for
+			the current window is used instead of the quickfix
+			list.
+
+							*:caddb* *:caddbuffer*
+:caddb[uffer] [bufnr]	Read the error list from the current buffer and add
+			the errors to the current quickfix list.  If a
+			quickfix list is not present, then a new list is
+			created. Otherwise, same as ":cbuffer".
+
+							*:laddb* *:laddbuffer*
+:laddb[uffer] [bufnr]	Same as ":caddbuffer", except the location list for
+			the current window is used instead of the quickfix
+			list.
+
+							*:cex* *:cexpr* *E777*
+:cex[pr][!] {expr}	Create a quickfix list using the result of {expr} and
+			jump to the first error.  If {expr} is a String, then
+			each new-line terminated line in the String is
+			processed using 'errorformat' and the result is added
+			to the quickfix list.  If {expr} is a List, then each
+			String item in the list is processed and added to the
+			quickfix list.  Non String items in the List are
+			ignored. See |:cc|
+			for [!].
+			Examples: >
+				:cexpr system('grep -n xyz *')
+				:cexpr getline(1, '$')
+<
+							*:lex* *:lexpr*
+:lex[pr][!] {expr}	Same as ":cexpr", except the location list for the
+			current window is used instead of the quickfix list.
+
+							*:cgete* *:cgetexpr*
+:cgete[xpr][!] {expr}	Create a quickfix list using the result of {expr}.
+			Just like ":cexpr", but don't jump to the first error.
+
+							*:lgete* *:lgetexpr*
+:lgete[xpr][!] {expr}	Same as ":cgetexpr", except the location list for the
+			current window is used instead of the quickfix list.
+
+							*:cad* *:caddexpr*
+:cad[dexpr][!] {expr}	Evaluate {expr} and add the resulting lines to the
+			current quickfix list. If a quickfix list is not
+			present, then a new list is created. The current
+			cursor position will not be changed. See |:cexpr| for
+			more information.
+			Example: >
+    :g/mypattern/caddexpr expand("%") . ":" . line(".") .  ":" . getline(".")
+<
+							*:lad* *:laddexpr*
+:lad[dexpr][!] {expr}	Same as ":caddexpr", except the location list for the
+			current window is used instead of the quickfix list.
+
+							*:cl* *:clist*
+:cl[ist] [from] [, [to]]
+			List all errors that are valid |quickfix-valid|.
+			If numbers [from] and/or [to] are given, the respective
+			range of errors is listed.  A negative number counts
+			from the last error backwards, -1 being the last error.
+			The 'switchbuf' settings are respected when jumping
+			to a buffer.
+
+:cl[ist]! [from] [, [to]]
+			List all errors.
+
+							*:lli* *:llist*
+:lli[st] [from] [, [to]]
+			Same as ":clist", except the location list for the
+			current window is used instead of the quickfix list.
+
+:lli[st]! [from] [, [to]]
+			List all the entries in the location list for the
+			current window.
+
+If you insert or delete lines, mostly the correct error location is still
+found because hidden marks are used.  Sometimes, when the mark has been
+deleted for some reason, the message "line changed" is shown to warn you that
+the error location may not be correct.  If you quit Vim and start again the
+marks are lost and the error locations may not be correct anymore.
+
+If vim is built with |+autocmd| support, two autocommands are available for
+running commands before and after a quickfix command (':make', ':grep' and so
+on) is executed. See |QuickFixCmdPre| and |QuickFixCmdPost| for details.
+
+=============================================================================
+2. The error window					*quickfix-window*
+
+							*:cope* *:copen*
+:cope[n] [height]	Open a window to show the current list of errors.
+			When [height] is given, the window becomes that high
+			(if there is room).  Otherwise the window is made ten
+			lines high.
+			The window will contain a special buffer, with
+			'buftype' equal to "quickfix".  Don't change this!
+			If there already is a quickfix window, it will be made
+			the current window.  It is not possible to open a
+			second quickfix window.
+
+							*:lop* *:lopen*
+:lop[en] [height]	Open a window to show the location list for the
+			current window. Works only when the location list for
+			the current window is present.  You can have more than
+			one location window opened at a time.  Otherwise, it
+			acts the same as ":copen".
+
+							*:ccl* *:cclose*
+:ccl[ose]		Close the quickfix window.
+
+							*:lcl* *:lclose*
+:lcl[ose]		Close the window showing the location list for the
+			current window.
+
+							*:cw* *:cwindow*
+:cw[indow] [height]	Open the quickfix window when there are recognized
+			errors.  If the window is already open and there are
+			no recognized errors, close the window.
+
+							*:lw* *:lwindow*
+:lw[indow] [height]	Same as ":cwindow", except use the window showing the
+			location list for the current window.
+
+Normally the quickfix window is at the bottom of the screen.  If there are
+vertical splits, it's at the bottom of the rightmost column of windows.  To
+make it always occupy the full width: >
+	:botright cwindow
+You can move the window around with |window-moving| commands.
+For example, to move it to the top: CTRL-W K
+The 'winfixheight' option will be set, which means that the window will mostly
+keep its height, ignoring 'winheight' and 'equalalways'.  You can change the
+height manually (e.g., by dragging the status line above it with the mouse).
+
+In the quickfix window, each line is one error.  The line number is equal to
+the error number.  You can use ":.cc" to jump to the error under the cursor.
+Hitting the <Enter> key or double-clicking the mouse on a line has the same
+effect.  The file containing the error is opened in the window above the
+quickfix window.  If there already is a window for that file, it is used
+instead.  If the buffer in the used window has changed, and the error is in
+another file, jumping to the error will fail.  You will first have to make
+sure the window contains a buffer which can be abandoned.
+					*CTRL-W_<Enter>* *CTRL-W_<CR>*
+You can use CTRL-W <Enter> to open a new window and jump to the error there.
+
+When the quickfix window has been filled, two autocommand events are
+triggered.  First the 'filetype' option is set to "qf", which triggers the
+FileType event.  Then the BufReadPost event is triggered, using "quickfix" for
+the buffer name.  This can be used to perform some action on the listed
+errors.  Example: >
+	au BufReadPost quickfix  setlocal modifiable
+		\ | silent exe 'g/^/s//\=line(".")." "/'
+		\ | setlocal nomodifiable
+This prepends the line number to each line.  Note the use of "\=" in the
+substitute string of the ":s" command, which is used to evaluate an
+expression.
+The BufWinEnter event is also triggered, again using "quickfix" for the buffer
+name.
+
+Note: Making changes in the quickfix window has no effect on the list of
+errors.  'modifiable' is off to avoid making changes.  If you delete or insert
+lines anyway, the relation between the text and the error number is messed up.
+If you really want to do this, you could write the contents of the quickfix
+window to a file and use ":cfile" to have it parsed and used as the new error
+list.
+
+						*location-list-window*
+The location list window displays the entries in a location list.  When you
+open a location list window, it is created below the current window and
+displays the location list for the current window.  The location list window
+is similar to the quickfix window, except that you can have more than one
+location list window open at a time. When you use a location list command in
+this window, the displayed location list is used.
+
+When you select a file from the location list window, the following steps are
+used to find a window to edit the file:
+
+1. If a window with the location list displayed in the location list window is
+   present, then the file is opened in that window.
+2. If the above step fails and if the file is already opened in another
+   window, then that window is used.
+3. If the above step fails then an existing window showing a buffer with
+   'buftype' not set is used.
+4. If the above step fails, then the file is edited in a new window.
+
+In all of the above cases, if the location list for the selected window is not
+yet set, then it is set to the location list displayed in the location list
+window.
+
+=============================================================================
+3. Using more than one list of errors			*quickfix-error-lists*
+
+So far has been assumed that there is only one list of errors.  Actually the
+ten last used lists are remembered.  When starting a new list, the previous
+ones are automatically kept.  Two commands can be used to access older error
+lists.  They set one of the existing error lists as the current one.
+
+						*:colder* *:col* *E380*
+:col[der] [count]	Go to older error list.  When [count] is given, do
+			this [count] times.  When already at the oldest error
+			list, an error message is given.
+
+						*:lolder* *:lol*
+:lol[der] [count]	Same as ":colder", except use the location list for
+			the current window instead of the quickfix list.
+
+						*:cnewer* *:cnew* *E381*
+:cnew[er] [count]	Go to newer error list.  When [count] is given, do
+			this [count] times.  When already at the newest error
+			list, an error message is given.
+
+						*:lnewer* *:lnew*
+:lnew[er] [count]	Same as ":cnewer", except use the location list for
+			the current window instead of the quickfix list.
+
+When adding a new error list, it becomes the current list.
+
+When ":colder" has been used and ":make" or ":grep" is used to add a new error
+list, one newer list is overwritten.  This is especially useful if you are
+browsing with ":grep" |grep|.  If you want to keep the more recent error
+lists, use ":cnewer 99" first.
+
+=============================================================================
+4. Using :make						*:make_makeprg*
+
+							*:mak* *:make*
+:mak[e][!] [arguments]	1. If vim was built with |+autocmd|, all relevant
+			   |QuickFixCmdPre| autocommands are executed.
+			2. If the 'autowrite' option is on, write any changed
+			   buffers
+			3. An errorfile name is made from 'makeef'.  If
+			   'makeef' doesn't contain "##", and a file with this
+			   name already exists, it is deleted.
+			4. The program given with the 'makeprg' option is
+			   started (default "make") with the optional
+			   [arguments] and the output is saved in the
+			   errorfile (for Unix it is also echoed on the
+			   screen).
+			5. The errorfile is read using 'errorformat'.
+			6. If vim was built with |+autocmd|, all relevant
+			   |QuickFixCmdPost| autocommands are executed.
+			7. If [!] is not given the first error is jumped to.
+			8. The errorfile is deleted.
+			9. You can now move through the errors with commands
+			   like |:cnext| and |:cprevious|, see above.
+			This command does not accept a comment, any "
+			characters are considered part of the arguments.
+
+							*:lmak* *:lmake*
+:lmak[e][!] [arguments]
+			Same as ":make", except the location list for the
+			current window is used instead of the quickfix list.
+
+The ":make" command executes the command given with the 'makeprg' option.
+This is done by passing the command to the shell given with the 'shell'
+option.  This works almost like typing
+
+	":!{makeprg} [arguments] {shellpipe} {errorfile}".
+
+{makeprg} is the string given with the 'makeprg' option.  Any command can be
+used, not just "make".  Characters '%' and '#' are expanded as usual on a
+command-line.  You can use "%<" to insert the current file name without
+extension, or "#<" to insert the alternate file name without extension, for
+example: >
+   :set makeprg=make\ #<.o
+
+[arguments] is anything that is typed after ":make".
+{shellpipe} is the 'shellpipe' option.
+{errorfile} is the 'makeef' option, with ## replaced to make it unique.
+
+The placeholder "$*" can be used for the argument list in {makeprog} if the
+command needs some additional characters after its arguments.  The $* is
+replaced then by all arguments.  Example: >
+   :set makeprg=latex\ \\\\nonstopmode\ \\\\input\\{$*}
+or simpler >
+   :let &mp = 'latex \\nonstopmode \\input\{$*}'
+"$*" can be given multiple times, for example: >
+   :set makeprg=gcc\ -o\ $*\ $*
+
+The 'shellpipe' option defaults to ">" for the Amiga, MS-DOS and Win32.  This
+means that the output of the compiler is saved in a file and not shown on the
+screen directly.  For Unix "| tee" is used.  The compiler output is shown on
+the screen and saved in a file the same time.  Depending on the shell used
+"|& tee" or "2>&1| tee" is the default, so stderr output will be included.
+
+If 'shellpipe' is empty, the {errorfile} part will be omitted.  This is useful
+for compilers that write to an errorfile themselves (e.g., Manx's Amiga C).
+
+==============================================================================
+5. Using :vimgrep and :grep				*grep* *lid*
+
+Vim has two ways to find matches for a pattern: Internal and external.  The
+advantage of the internal grep is that it works on all systems and uses the
+powerful Vim search patterns.  An external grep program can be used when the
+Vim grep does not do what you want.
+
+The internal method will be slower, because files are read into memory.  The
+advantages are:
+- Line separators and encoding are automatically recognized, as if a file is
+  being edited.
+- Uses Vim search patterns.  Multi-line patterns can be used.
+- When plugins are enabled: compressed and remote files can be searched.
+	|gzip| |netrw|
+
+To be able to do this Vim loads each file as if it is being edited.  When
+there is no match in the file the associated buffer is wiped out again.  The
+'hidden' option is ignored here to avoid running out of memory or file
+descriptors when searching many files.  However, when the |:hide| command
+modifier is used the buffers are kept loaded.  This makes following searches
+in the same files a lot faster.
+
+
+5.1 using Vim's internal grep
+
+					*:vim* *:vimgrep* *E682* *E683*
+:vim[grep][!] /{pattern}/[g][j] {file} ...
+			Search for {pattern} in the files {file} ... and set
+			the error list to the matches.
+			Without the 'g' flag each line is added only once.
+			With 'g' every match is added.
+
+			{pattern} is a Vim search pattern.  Instead of
+			enclosing it in / any non-ID character (see
+			|'isident'|) can be used, so long as it does not
+			appear in {pattern}.
+			'ignorecase' applies.  To overrule it put |/\c| in the
+			pattern to ignore case or |/\C| to match case.
+			'smartcase' is not used.
+
+			When a number is put before the command this is used
+			as the maximum number of matches to find.  Use
+			":1vimgrep pattern file" to find only the first.
+			Useful if you only want to check if there is a match
+			and quit quickly when it's found.
+
+			Without the 'j' flag Vim jumps to the first match.
+			With 'j' only the quickfix list is updated.
+			With the [!] any changes in the current buffer are
+			abandoned.
+
+			Every second or so the searched file name is displayed
+			to give you an idea of the progress made.
+			Examples: >
+				:vimgrep /an error/ *.c
+				:vimgrep /\<FileName\>/ *.h include/*
+				:vimgrep /myfunc/ **/*.c
+<			For the use of "**" see |starstar-wildcard|.
+
+:vim[grep][!] {pattern} {file} ...
+			Like above, but instead of enclosing the pattern in a
+			non-ID character use a white-separated pattern.  The
+			pattern must start with an ID character.
+			Example: >
+				:vimgrep Error *.c
+<
+							*:lv* *:lvimgrep*
+:lv[imgrep][!] /{pattern}/[g][j] {file} ...
+:lv[imgrep][!] {pattern} {file} ...
+			Same as ":vimgrep", except the location list for the
+			current window is used instead of the quickfix list.
+
+						*:vimgrepa* *:vimgrepadd*
+:vimgrepa[dd][!] /{pattern}/[g][j] {file} ...
+:vimgrepa[dd][!] {pattern} {file} ...
+			Just like ":vimgrep", but instead of making a new list
+			of errors the matches are appended to the current
+			list.
+
+						*:lvimgrepa* *:lvimgrepadd*
+:lvimgrepa[dd][!] /{pattern}/[g][j] {file} ...
+:lvimgrepa[dd][!] {pattern} {file} ...
+			Same as ":vimgrepadd", except the location list for
+			the current window is used instead of the quickfix
+			list.
+
+5.2 External grep
+
+Vim can interface with "grep" and grep-like programs (such as the GNU
+id-utils) in a similar way to its compiler integration (see |:make| above).
+
+[Unix trivia: The name for the Unix "grep" command comes from ":g/re/p", where
+"re" stands for Regular Expression.]
+
+							    *:gr* *:grep*
+:gr[ep][!] [arguments]	Just like ":make", but use 'grepprg' instead of
+			'makeprg' and 'grepformat' instead of 'errorformat'.
+			When 'grepprg' is "internal" this works like
+			|:vimgrep|.  Note that the pattern needs to be
+			enclosed in separator characters then.
+
+							    *:lgr* *:lgrep*
+:lgr[ep][!] [arguments]	Same as ":grep", except the location list for the
+			current window is used instead of the quickfix list.
+
+							*:grepa* *:grepadd*
+:grepa[dd][!] [arguments]
+			Just like ":grep", but instead of making a new list of
+			errors the matches are appended to the current list.
+			Example: >
+				:grep nothing %
+				:bufdo grepadd! something %
+<			The first command makes a new error list which is
+			empty.  The second command executes "grepadd" for each
+			listed buffer.  Note the use of ! to avoid that
+			":grepadd" jumps to the first error, which is not
+			allowed with |:bufdo|.
+
+							*:lgrepa* *:lgrepadd*
+:lgrepa[dd][!] [arguments]
+			Same as ":grepadd", except the location list for the
+			current window is used instead of the quickfix list.
+
+5.3 Setting up external grep
+
+If you have a standard "grep" program installed, the :grep command may work
+well with the defaults.  The syntax is very similar to the standard command: >
+
+	:grep foo *.c
+
+Will search all files with the .c extension for the substring "foo".  The
+arguments to :grep are passed straight to the "grep" program, so you can use
+whatever options your "grep" supports.
+
+By default, :grep invokes grep with the -n option (show file and line
+numbers).  You can change this with the 'grepprg' option.  You will need to set
+'grepprg' if:
+
+a)	You are using a program that isn't called "grep"
+b)	You have to call grep with a full path
+c)	You want to pass other options automatically (e.g. case insensitive
+	search.)
+
+Once "grep" has executed, Vim parses the results using the 'grepformat'
+option.  This option works in the same way as the 'errorformat' option - see
+that for details.  You may need to change 'grepformat' from the default if
+your grep outputs in a non-standard format, or you are using some other
+program with a special format.
+
+Once the results are parsed, Vim loads the first file containing a match and
+jumps to the appropriate line, in the same way that it jumps to a compiler
+error in |quickfix| mode.  You can then use the |:cnext|, |:clist|, etc.
+commands to see the other matches.
+
+
+5.4 Using :grep with id-utils
+
+You can set up :grep to work with the GNU id-utils like this: >
+
+	:set grepprg=lid\ -Rgrep\ -s
+	:set grepformat=%f:%l:%m
+
+then >
+	:grep (regexp)
+
+works just as you'd expect.
+(provided you remembered to mkid first :)
+
+
+5.5 Browsing source code with :vimgrep or :grep
+
+Using the stack of error lists that Vim keeps, you can browse your files to
+look for functions and the functions they call.  For example, suppose that you
+have to add an argument to the read_file() function.  You enter this command: >
+
+	:vimgrep /\<read_file\>/ *.c
+
+You use ":cn" to go along the list of matches and add the argument.  At one
+place you have to get the new argument from a higher level function msg(), and
+need to change that one too.  Thus you use: >
+
+	:vimgrep /\<msg\>/ *.c
+
+While changing the msg() functions, you find another function that needs to
+get the argument from a higher level.  You can again use ":vimgrep" to find
+these functions.  Once you are finished with one function, you can use >
+
+	:colder
+
+to go back to the previous one.
+
+This works like browsing a tree: ":vimgrep" goes one level deeper, creating a
+list of branches.  ":colder" goes back to the previous level.  You can mix
+this use of ":vimgrep" and "colder" to browse all the locations in a tree-like
+way.  If you do this consistently, you will find all locations without the
+need to write down a "todo" list.
+
+=============================================================================
+6. Selecting a compiler					*compiler-select*
+
+						*:comp* *:compiler* *E666*
+:comp[iler][!] {name}		Set options to work with compiler {name}.
+				Without the "!" options are set for the
+				current buffer.  With "!" global options are
+				set.
+				If you use ":compiler foo" in "file.foo" and
+				then ":compiler! bar" in another buffer, Vim
+				will keep on using "foo" in "file.foo".
+				{not available when compiled without the
+				|+eval| feature}
+
+
+The Vim plugins in the "compiler" directory will set options to use the
+selected compiler.  For ":compiler" local options are set, for ":compiler!"
+global options.
+							*current_compiler*
+To support older Vim versions, the plugins always use "current_compiler" and
+not "b:current_compiler".  What the command actually does is the following:
+
+- Delete the "current_compiler" and "b:current_compiler" variables.
+- Define the "CompilerSet" user command.  With "!" it does ":set", without "!"
+  it does ":setlocal".
+- Execute ":runtime! compiler/{name}.vim".  The plugins are expected to set
+  options with "CompilerSet" and set the "current_compiler" variable to the
+  name of the compiler.
+- Delete the "CompilerSet" user command.
+- Set "b:current_compiler" to the value of "current_compiler".
+- Without "!" the old value of "current_compiler" is restored.
+
+
+For writing a compiler plugin, see |write-compiler-plugin|.
+
+
+GCC					*quickfix-gcc*	*compiler-gcc*
+
+There's one variable you can set for the GCC compiler:
+
+g:compiler_gcc_ignore_unmatched_lines
+				Ignore lines that don't match any patterns
+				defined for GCC.  Useful if output from
+				commands run from make are generating false
+				positives.
+
+
+MANX AZTEC C				*quickfix-manx* *compiler-manx*
+
+To use Vim with Manx's Aztec C compiler on the Amiga you should do the
+following:
+- Set the CCEDIT environment variable with the command: >
+	mset "CCEDIT=vim -q"
+- Compile with the -qf option.  If the compiler finds any errors, Vim is
+  started and the cursor is positioned on the first error.  The error message
+  will be displayed on the last line.  You can go to other errors with the
+  commands mentioned above.  You can fix the errors and write the file(s).
+- If you exit Vim normally the compiler will re-compile the same file.  If you
+  exit with the :cq command, the compiler will terminate.  Do this if you
+  cannot fix the error, or if another file needs to be compiled first.
+
+There are some restrictions to the Quickfix mode on the Amiga.  The
+compiler only writes the first 25 errors to the errorfile (Manx's
+documentation does not say how to get more).  If you want to find the others,
+you will have to fix a few errors and exit the editor.  After recompiling,
+up to 25 remaining errors will be found.
+
+If Vim was started from the compiler, the :sh and some :!  commands will not
+work, because Vim is then running in the same process as the compiler and
+stdin (standard input) will not be interactive.
+
+
+PYUNIT COMPILER						*compiler-pyunit*
+
+This is not actually a compiler, but a unit testing framework for the
+Python language.  It is included into standard Python distribution
+starting from version 2.0.  For older versions, you can get it from
+http://pyunit.sourceforge.net.
+
+When you run your tests with the help of the framework, possible errors
+are parsed by Vim and presented for you in quick-fix mode.
+
+Unfortunately, there is no standard way to run the tests.
+The alltests.py script seems to be used quite often, that's all.
+Useful values for the 'makeprg' options therefore are:
+ setlocal makeprg=./alltests.py " Run a testsuite
+ setlocal makeprg=python %      " Run a single testcase
+
+Also see http://vim.sourceforge.net/tip_view.php?tip_id=280.
+
+
+TEX COMPILER						*compiler-tex*
+
+Included in the distribution compiler for TeX ($VIMRUNTIME/compiler/tex.vim)
+uses make command if possible.  If the compiler finds a file named "Makefile"
+or "makefile" in the current directory, it supposes that you want to process
+your *TeX files with make, and the makefile does the right work.  In this case
+compiler sets 'errorformat' for *TeX output and leaves 'makeprg' untouched.  If
+neither "Makefile" nor "makefile" is found, the compiler will not use make.
+You can force the compiler to ignore makefiles by defining
+b:tex_ignore_makefile or g:tex_ignore_makefile variable (they are checked for
+existence only).
+
+If the compiler chose not to use make, it need to choose a right program for
+processing your input.  If b:tex_flavor or g:tex_flavor (in this precedence)
+variable exists, it defines TeX flavor for :make (actually, this is the name
+of executed command), and if both variables do not exist, it defaults to
+"latex".  For example, while editing chapter2.tex \input-ed from mypaper.tex
+written in AMS-TeX: >
+
+	:let b:tex_flavor = 'amstex'
+	:compiler tex
+<	[editing...] >
+	:make mypaper
+
+Note that you must specify a name of the file to process as an argument (to
+process the right file when editing \input-ed or \include-ed file; portable
+solution for substituting % for no arguments is welcome).  This is not in the
+semantics of make, where you specify a target, not source, but you may specify
+filename without extension ".tex" and mean this as "make filename.dvi or
+filename.pdf or filename.some_result_extension according to compiler".
+
+Note: tex command line syntax is set to usable both for MikTeX (suggestion
+by Srinath Avadhanula) and teTeX (checked by Artem Chuprina).  Suggestion
+from |errorformat-LaTeX| is too complex to keep it working for different
+shells and OSes and also does not allow to use other available TeX options,
+if any.  If your TeX doesn't support "-interaction=nonstopmode", please
+report it with different means to express \nonstopmode from the command line.
+
+=============================================================================
+7. The error format					*error-file-format*
+
+					*errorformat* *E372* *E373* *E374*
+						*E375* *E376* *E377* *E378*
+The 'errorformat' option specifies a list of formats that are recognized.  The
+first format that matches with an error message is used.  You can add several
+formats for different messages your compiler produces, or even entries for
+multiple compilers.  See |efm-entries|.
+
+Each entry in 'errorformat' is a scanf-like string that describes the format.
+First, you need to know how scanf works.  Look in the documentation of your
+C compiler.  Below you find the % items that Vim understands.  Others are
+invalid.
+
+Special characters in 'errorformat' are comma and backslash.  See
+|efm-entries| for how to deal with them.  Note that a literal "%" is matched
+by "%%", thus it is not escaped with a backslash.
+
+Note: By default the difference between upper and lowercase is ignored.  If
+you want to match case, add "\C" to the pattern |/\C|.
+
+
+Basic items
+
+	%f		file name (finds a string)
+	%l		line number (finds a number)
+	%c		column number (finds a number representing character
+			column of the error, (1 <tab> == 1 character column))
+	%v		virtual column number (finds a number representing
+			screen column of the error (1 <tab> == 8 screen
+			columns))
+	%t		error type (finds a single character)
+	%n		error number (finds a number)
+	%m		error message (finds a string)
+	%r		matches the "rest" of a single-line file message %O/P/Q
+	%p		pointer line (finds a sequence of '-', '.' or ' ' and
+			uses the length for the column number)
+	%*{conv}	any scanf non-assignable conversion
+	%%		the single '%' character
+	%s		search text (finds a string)
+
+The "%f" conversion may depend on the current 'isfname' setting.  "~/" is
+expanded to the home directory and environment variables are expanded.
+
+The "%f" and "%m" conversions have to detect the end of the string.  This
+normally happens by matching following characters and items.  When nothing is
+following the rest of the line is matched.  If "%f" is followed by a '%' or a
+backslash, it will look for a sequence of 'isfname' characters.
+
+On MS-DOS, MS-Windows and OS/2 a leading "C:" will be included in "%f", even
+when using "%f:".  This means that a file name which is a single alphabetical
+letter will not be detected.
+
+The "%p" conversion is normally followed by a "^".  It's used for compilers
+that output a line like: >
+	    ^
+or >
+   ---------^
+to indicate the column of the error.  This is to be used in a multi-line error
+message.  See |errorformat-javac| for a  useful example.
+
+The "%s" conversion specifies the text to search for to locate the error line.
+The text is used as a literal string.  The anchors "^" and "$" are added to
+the text to locate the error line exactly matching the search text and the
+text is prefixed with the "\V" atom to make it "very nomagic".  The "%s"
+conversion can be used to locate lines without a line number in the error
+output.  Like the output of the "grep" shell command.
+When the pattern is present the line number will not be used.
+
+Changing directory
+
+The following uppercase conversion characters specify the type of special
+format strings.  At most one of them may be given as a prefix at the begin
+of a single comma-separated format pattern.
+Some compilers produce messages that consist of directory names that have to
+be prepended to each file name read by %f (example: GNU make).  The following
+codes can be used to scan these directory names; they will be stored in an
+internal directory stack.					*E379*
+	%D		"enter directory" format string; expects a following
+			  %f that finds the directory name
+	%X		"leave directory" format string; expects following %f
+
+When defining an "enter directory" or "leave directory" format, the "%D" or
+"%X" has to be given at the start of that substring.  Vim tracks the directory
+changes and prepends the current directory to each erroneous file found with a
+relative path.  See |quickfix-directory-stack| for details, tips and
+limitations.
+
+
+Multi-line messages				*errorformat-multi-line*
+
+It is possible to read the output of programs that produce multi-line
+messages, i.e. error strings that consume more than one line.  Possible
+prefixes are:
+	%E		start of a multi-line error message
+	%W		start of a multi-line warning message
+	%I		start of a multi-line informational message
+	%A		start of a multi-line message (unspecified type)
+	%>		for next line start with current pattern again |efm-%>|
+	%C		continuation of a multi-line message
+	%Z		end of a multi-line message
+These can be used with '+' and '-', see |efm-ignore| below.
+
+Using "\n" in the pattern won't work to match multi-line messages.
+
+Example: Your compiler happens to write out errors in the following format
+(leading line numbers not being part of the actual output):
+
+     1	Error 275 ~
+     2	line 42 ~
+     3	column 3 ~
+     4	' ' expected after '--' ~
+
+The appropriate error format string has to look like this: >
+   :set efm=%EError\ %n,%Cline\ %l,%Ccolumn\ %c,%Z%m
+
+And the |:clist| error message generated for this error is:
+
+ 1:42 col 3 error 275:  ' ' expected after '--'
+
+Another example: Think of a Python interpreter that produces the following
+error message (line numbers are not part of the actual output):
+
+     1	==============================================================
+     2	FAIL: testGetTypeIdCachesResult (dbfacadeTest.DjsDBFacadeTest)
+     3	--------------------------------------------------------------
+     4	Traceback (most recent call last):
+     5	  File "unittests/dbfacadeTest.py", line 89, in testFoo
+     6	    self.assertEquals(34, dtid)
+     7	  File "/usr/lib/python2.2/unittest.py", line 286, in
+     8	 failUnlessEqual
+     9	    raise self.failureException, \
+    10	AssertionError: 34 != 33
+    11
+    12	--------------------------------------------------------------
+    13	Ran 27 tests in 0.063s
+
+Say you want |:clist| write the relevant information of this message only,
+namely:
+ 5 unittests/dbfacadeTest.py:89:  AssertionError: 34 != 33
+
+Then the error format string could be defined as follows: >
+  :set efm=%C\ %.%#,%A\ \ File\ \"%f\"\\,\ line\ %l%.%#,%Z%[%^\ ]%\\@=%m
+
+Note that the %C string is given before the %A here: since the expression
+' %.%#' (which stands for the regular expression ' .*') matches every line
+starting with a space, followed by any characters to the end of the line,
+it also hides line 7 which would trigger a separate error message otherwise.
+Error format strings are always parsed pattern by pattern until the first
+match occurs.
+							*efm-%>*
+The %> item can be used to avoid trying patterns that appear earlier in
+'errorformat'.  This is useful for patterns that match just about anything.
+For example, if the error looks like this:
+
+	Error in line 123 of foo.c: ~
+	unknown variable "i" ~
+
+This can be found with: >
+	:set efm=xxx,%E%>Error in line %l of %f:,%Z%m
+Where "xxx" has a pattern that would also match the second line.
+
+Important: There is no memory of what part of the errorformat matched before;
+every line in the error file gets a complete new run through the error format
+lines.  For example, if one has: >
+  setlocal efm=aa,bb,cc,dd,ee
+Where aa, bb, etc. are error format strings.  Each line of the error file will
+be matched to the pattern aa, then bb, then cc, etc.  Just because cc matched
+the previous error line does _not_ mean that dd will be tried first on the
+current line, even if cc and dd are multi-line errorformat strings.
+
+
+
+Separate file name			*errorformat-separate-filename*
+
+These prefixes are useful if the file name is given once and multiple messages
+follow that refer to this file name.
+	%O		single-line file message: overread the matched part
+	%P		single-line file message: push file %f onto the stack
+	%Q		single-line file message: pop the last file from stack
+
+Example: Given a compiler that produces the following error logfile (without
+leading line numbers):
+
+     1	[a1.tt]
+     2	(1,17)  error: ';' missing
+     3	(21,2)  warning: variable 'z' not defined
+     4	(67,3)  error: end of file found before string ended
+     5
+     6	[a2.tt]
+     7
+     8	[a3.tt]
+     9	NEW compiler v1.1
+    10	(2,2)   warning: variable 'x' not defined
+    11	(67,3)  warning: 's' already defined
+
+This logfile lists several messages for each file enclosed in [...] which are
+properly parsed by an error format like this: >
+  :set efm=%+P[%f],(%l\\,%c)%*[\ ]%t%*[^:]:\ %m,%-Q
+
+A call of |:clist| writes them accordingly with their correct filenames:
+
+  2 a1.tt:1 col 17 error: ';' missing
+  3 a1.tt:21 col 2 warning: variable 'z' not defined
+  4 a1.tt:67 col 3 error: end of file found before string ended
+  8 a3.tt:2 col 2 warning: variable 'x' not defined
+  9 a3.tt:67 col 3 warning: 's' already defined
+
+Unlike the other prefixes that all match against whole lines, %P, %Q and %O
+can be used to match several patterns in the same line.  Thus it is possible
+to parse even nested files like in the following line:
+  {"file1" {"file2" error1} error2 {"file3" error3 {"file4" error4 error5}}}
+The %O then parses over strings that do not contain any push/pop file name
+information.  See |errorformat-LaTeX| for an extended example.
+
+
+Ignoring and using whole messages			*efm-ignore*
+
+The codes '+' or '-' can be combined with the uppercase codes above; in that
+case they have to precede the letter, e.g. '%+A' or '%-G':
+	%-		do not include the matching multi-line in any output
+	%+		include the whole matching line in the %m error string
+
+One prefix is only useful in combination with '+' or '-', namely %G.  It parses
+over lines containing general information like compiler version strings or
+other headers that can be skipped.
+	%-G		ignore this message
+	%+G		general message
+
+
+Pattern matching
+
+The scanf()-like "%*[]" notation is supported for backward-compatibility
+with previous versions of Vim.  However, it is also possible to specify
+(nearly) any Vim supported regular expression in format strings.
+Since meta characters of the regular expression language can be part of
+ordinary matching strings or file names (and therefore internally have to
+be escaped), meta symbols have to be written with leading '%':
+	%\		The single '\' character.  Note that this has to be
+			escaped ("%\\") in ":set errorformat=" definitions.
+	%.		The single '.' character.
+	%#		The single '*'(!) character.
+	%^		The single '^' character.  Note that this is not
+			useful, the pattern already matches start of line.
+	%$		The single '$' character.  Note that this is not
+			useful, the pattern already matches end of line.
+	%[		The single '[' character for a [] character range.
+	%~		The single '~' character.
+When using character classes in expressions (see |/\i| for an overview),
+terms containing the "\+" quantifier can be written in the scanf() "%*"
+notation.  Example: "%\\d%\\+" ("\d\+", "any number") is equivalent to "%*\\d".
+Important note: The \(...\) grouping of sub-matches can not be used in format
+specifications because it is reserved for internal conversions.
+
+
+Multiple entries in 'errorformat'			*efm-entries*
+
+To be able to detect output from several compilers, several format patterns
+may be put in 'errorformat', separated by commas (note: blanks after the comma
+are ignored).  The first pattern that has a complete match is used.  If no
+match is found, matching parts from the last one will be used, although the
+file name is removed and the error message is set to the whole message.  If
+there is a pattern that may match output from several compilers (but not in a
+right way), put it after one that is more restrictive.
+
+To include a comma in a pattern precede it with a backslash (you have to type
+two in a ":set" command).  To include a backslash itself give two backslashes
+(you have to type four in a ":set" command).  You also need to put a backslash
+before a space for ":set".
+
+
+Valid matches						*quickfix-valid*
+
+If a line does not completely match one of the entries in 'errorformat', the
+whole line is put in the error message and the entry is marked "not valid"
+These lines are skipped with the ":cn" and ":cp" commands (unless there is
+no valid line at all).  You can use ":cl!" to display all the error messages.
+
+If the error format does not contain a file name Vim cannot switch to the
+correct file.  You will have to do this by hand.
+
+
+Examples
+
+The format of the file from the Amiga Aztec compiler is:
+
+	filename>linenumber:columnnumber:errortype:errornumber:errormessage
+
+	filename	name of the file in which the error was detected
+	linenumber	line number where the error was detected
+	columnnumber	column number where the error was detected
+	errortype	type of the error, normally a single 'E' or 'W'
+	errornumber	number of the error (for lookup in the manual)
+	errormessage	description of the error
+
+This can be matched with this 'errorformat' entry:
+	%f>%l:%c:%t:%n:%m
+
+Some examples for C compilers that produce single-line error outputs:
+%f:%l:\ %t%*[^0123456789]%n:\ %m	for Manx/Aztec C error messages
+					(scanf() doesn't understand [0-9])
+%f\ %l\ %t%*[^0-9]%n:\ %m		for SAS C
+\"%f\"\\,%*[^0-9]%l:\ %m		for generic C compilers
+%f:%l:\ %m				for GCC
+%f:%l:\ %m,%Dgmake[%*\\d]:\ Entering\ directory\ `%f',
+%Dgmake[%*\\d]:\ Leaving\ directory\ `%f'
+					for GCC with gmake (concat the lines!)
+%f(%l)\ :\ %*[^:]:\ %m			old SCO C compiler (pre-OS5)
+%f(%l)\ :\ %t%*[^0-9]%n:\ %m		idem, with error type and number
+%f:%l:\ %m,In\ file\ included\ from\ %f:%l:,\^I\^Ifrom\ %f:%l%m
+					for GCC, with some extras
+
+Extended examples for the handling of multi-line messages are given below,
+see |errorformat-Jikes| and |errorformat-LaTeX|.
+
+Note the backslash in front of a space and double quote.  It is required for
+the :set command.  There are two backslashes in front of a comma, one for the
+:set command and one to avoid recognizing the comma as a separator of error
+formats.
+
+
+Filtering messages
+
+If you have a compiler that produces error messages that do not fit in the
+format string, you could write a program that translates the error messages
+into this format.  You can use this program with the ":make" command by
+changing the 'makeprg' option.  For example: >
+   :set mp=make\ \\\|&\ error_filter
+The backslashes before the pipe character are required to avoid it to be
+recognized as a command separator.  The backslash before each space is
+required for the set command.
+
+=============================================================================
+8. The directory stack				*quickfix-directory-stack*
+
+Quickfix maintains a stack for saving all used directories parsed from the
+make output.  For GNU-make this is rather simple, as it always prints the
+absolute path of all directories it enters and leaves.  Regardless if this is
+done via a 'cd' command in the makefile or with the parameter "-C dir" (change
+to directory before reading the makefile).  It may be useful to use the switch
+"-w" to force GNU-make to print out the working directory before and after
+processing.
+
+Maintaining the correct directory is more complicated if you don't use
+GNU-make.  AIX-make for example doesn't print any information about its
+working directory.  Then you need to enhance the makefile.  In the makefile of
+LessTif there is a command which echoes "Making {target} in {dir}".  The
+special problem here is that it doesn't print informations on leaving the
+directory and that it doesn't print the absolute path.
+
+To solve the problem with relative paths and missing "leave directory"
+messages Vim uses following algorithm:
+
+1) Check if the given directory is a subdirectory of the current directory.
+   If this is true, store it as the current directory.
+2) If it is not a subdir of the current directory, try if this is a
+   subdirectory of one of the upper directories.
+3) If the directory still isn't found, it is assumed to be a subdirectory
+   of Vim's current directory.
+
+Additionally it is checked for every file, if it really exists in the
+identified directory.  If not, it is searched in all other directories of the
+directory stack (NOT the directory subtree!).  If it is still not found, it is
+assumed that it is in Vim's current directory.
+
+There are limitation in this algorithm.  This examples assume that make just
+prints information about entering a directory in the form "Making all in dir".
+
+1) Assume you have following directories and files:
+   ./dir1
+   ./dir1/file1.c
+   ./file1.c
+
+   If make processes the directory "./dir1" before the current directory and
+   there is an error in the file "./file1.c", you will end up with the file
+   "./dir1/file.c" loaded by Vim.
+
+   This can only be solved with a "leave directory" message.
+
+2) Assume you have following directories and files:
+   ./dir1
+   ./dir1/dir2
+   ./dir2
+
+   You get the following:
+
+   Make output			  Directory interpreted by Vim
+   ------------------------	  ----------------------------
+   Making all in dir1		  ./dir1
+   Making all in dir2		  ./dir1/dir2
+   Making all in dir2		  ./dir1/dir2
+
+   This can be solved by printing absolute directories in the "enter directory"
+   message or by printing "leave directory" messages..
+
+To avoid this problems, ensure to print absolute directory names and "leave
+directory" messages.
+
+Examples for Makefiles:
+
+Unix:
+    libs:
+	    for dn in $(LIBDIRS); do				\
+		(cd $$dn; echo "Entering dir '$$(pwd)'"; make); \
+		echo "Leaving dir";				\
+	    done
+
+Add
+    %DEntering\ dir\ '%f',%XLeaving\ dir
+to your 'errorformat' to handle the above output.
+
+Note that Vim doesn't check if the directory name in a "leave directory"
+messages is the current directory.  This is why you could just use the message
+"Leaving dir".
+
+=============================================================================
+9. Specific error file formats			*errorformats*
+
+						*errorformat-Jikes*
+Jikes(TM), a source-to-bytecode Java compiler published by IBM Research,
+produces simple multi-line error messages.
+
+An 'errorformat' string matching the produced messages is shown below.
+The following lines can be placed in the user's |vimrc| to overwrite Vim's
+recognized default formats, or see |:set+=| how to install this format
+additionally to the default. >
+
+  :set efm=%A%f:%l:%c:%*\\d:%*\\d:,
+	\%C%*\\s%trror:%m,
+	\%+C%*[^:]%trror:%m,
+	\%C%*\\s%tarning:%m,
+	\%C%m
+<
+Jikes(TM) produces a single-line error message when invoked with the option
+"+E", and can be matched with the following: >
+
+  :setl efm=%f:%l:%v:%*\\d:%*\\d:%*\\s%m
+<
+						*errorformat-javac*
+This 'errorformat' has been reported to work well for javac, which outputs a
+line with "^" to indicate the column of the error: >
+  :setl efm=%A%f:%l:\ %m,%-Z%p^,%-C%.%#
+or: >
+  :setl efm=%A%f:%l:\ %m,%+Z%p^,%+C%.%#,%-G%.%#
+<
+Here is an alternative from Michael F. Lamb for Unix that filters the errors
+first: >
+  :setl errorformat=%Z%f:%l:\ %m,%A%p^,%-G%*[^sl]%.%#
+  :setl makeprg=javac\ %\ 2>&1\ \\\|\ vim-javac-filter
+
+You need to put the following in "vim-javac-filter" somewhere in your path
+(e.g., in ~/bin) and make it executable: >
+   #!/bin/sed -f
+   /\^$/s/\t/\ /g;/:[0-9]\+:/{h;d};/^[ \t]*\^/G;
+
+In English, that sed script:
+- Changes single tabs to single spaces and
+- Moves the line with the filename, line number, error message to just after
+  the pointer line. That way, the unused error text between doesn't break
+  vim's notion of a "multi-line message" and also doesn't force us to include
+  it as a "continuation of a multi-line message."
+
+						*errorformat-ant*
+For ant (http://jakarta.apache.org/) the above errorformat has to be modified
+to honour the leading [javac] in front of each javac output line: >
+  :set efm=%A\ %#[javac]\ %f:%l:\ %m,%-Z\ %#[javac]\ %p^,%-C%.%#
+
+The 'errorformat' can also be configured to handle ant together with either
+javac or jikes.  If you're using jikes, you should tell ant to use jikes' +E
+command line switch which forces jikes to generate one-line error messages.
+This is what the second line (of a build.xml file) below does: >
+  <property name = "build.compiler"       value = "jikes"/>
+  <property name = "build.compiler.emacs" value = "true"/>
+
+The 'errorformat' which handles ant with both javac and jikes is: >
+  :set efm=\ %#[javac]\ %#%f:%l:%c:%*\\d:%*\\d:\ %t%[%^:]%#:%m,
+	   \%A\ %#[javac]\ %f:%l:\ %m,%-Z\ %#[javac]\ %p^,%-C%.%#
+<
+						*errorformat-jade*
+parsing jade (see http://www.jclark.com/) errors is simple: >
+  :set efm=jade:%f:%l:%c:%t:%m
+<
+						*errorformat-LaTeX*
+The following is an example how an 'errorformat' string can be specified
+for the (La)TeX typesetting system which displays error messages over
+multiple lines.  The output of ":clist" and ":cc" etc. commands displays
+multi-lines in a single line, leading white space is removed.
+It should be easy to adopt the above LaTeX errorformat to any compiler output
+consisting of multi-line errors.
+
+The commands can be placed in a |vimrc| file or some other Vim script file,
+e.g. a script containing LaTeX related stuff which is loaded only when editing
+LaTeX sources.
+Make sure to copy all lines of the example (in the given order), afterwards
+remove the comment lines.  For the '\' notation at the start of some lines see
+|line-continuation|.
+
+		First prepare 'makeprg' such that LaTeX will report multiple
+		errors; do not stop when the first error has occurred: >
+ :set makeprg=latex\ \\\\nonstopmode\ \\\\input\\{$*}
+<
+		Start of multi-line error messages: >
+ :set efm=%E!\ LaTeX\ %trror:\ %m,
+	\%E!\ %m,
+<		Start of multi-line warning messages; the first two also
+		include the line number.  Meaning of some regular expressions:
+		  - "%.%#"  (".*")   matches a (possibly empty) string
+		  - "%*\\d" ("\d\+") matches a number >
+	\%+WLaTeX\ %.%#Warning:\ %.%#line\ %l%.%#,
+	\%+W%.%#\ at\ lines\ %l--%*\\d,
+	\%WLaTeX\ %.%#Warning:\ %m,
+<		Possible continuations of error/warning messages; the first
+		one also includes the line number: >
+	\%Cl.%l\ %m,
+	\%+C\ \ %m.,
+	\%+C%.%#-%.%#,
+	\%+C%.%#[]%.%#,
+	\%+C[]%.%#,
+	\%+C%.%#%[{}\\]%.%#,
+	\%+C<%.%#>%.%#,
+	\%C\ \ %m,
+<		Lines that match the following patterns do not contain any
+		important information; do not include them in messages: >
+	\%-GSee\ the\ LaTeX%m,
+	\%-GType\ \ H\ <return>%m,
+	\%-G\ ...%.%#,
+	\%-G%.%#\ (C)\ %.%#,
+	\%-G(see\ the\ transcript%.%#),
+<		Generally exclude any empty or whitespace-only line from
+		being displayed: >
+	\%-G\\s%#,
+<		The LaTeX output log does not specify the names of erroneous
+		source files per line; rather they are given globally,
+		enclosed in parentheses.
+		The following patterns try to match these names and store
+		them in an internal stack.  The patterns possibly scan over
+		the same input line (one after another), the trailing "%r"
+		conversion indicates the "rest" of the line that will be
+		parsed in the next go until the end of line is reached.
+
+		Overread a file name enclosed in '('...')'; do not push it
+		on a stack since the file apparently does not contain any
+		error: >
+	\%+O(%f)%r,
+<		Push a file name onto the stack.  The name is given after '(': >
+	\%+P(%f%r,
+	\%+P\ %\\=(%f%r,
+	\%+P%*[^()](%f%r,
+	\%+P[%\\d%[^()]%#(%f%r,
+<		Pop the last stored file name when a ')' is scanned: >
+	\%+Q)%r,
+	\%+Q%*[^()])%r,
+	\%+Q[%\\d%*[^()])%r
+
+Note that in some cases file names in the LaTeX output log cannot be parsed
+properly.  The parser might have been messed up by unbalanced parentheses
+then.  The above example tries to catch the most relevant cases only.
+You can customize the given setting to suit your own purposes, for example,
+all the annoying "Overfull ..." warnings could be excluded from being
+recognized as an error.
+Alternatively to filtering the LaTeX compiler output, it is also possible
+to directly read the *.log file that is produced by the [La]TeX compiler.
+This contains even more useful information about possible error causes.
+However, to properly parse such a complex file, an external filter should
+be used.  See the description further above how to make such a filter known
+by Vim.
+
+						*errorformat-Perl*
+In $VIMRUNTIME/tools you can find the efm_perl.pl script, which filters Perl
+error messages into a format that quickfix mode will understand.  See the
+start of the file about how to use it.
+
+
+
+ vim:tw=78:ts=8:ft=help:norl:
--- /dev/null
+++ b/lib/vimfiles/doc/quickref.txt
@@ -1,0 +1,1376 @@
+*quickref.txt*  For Vim version 7.1.  Last change: 2007 May 11
+
+
+		  VIM REFERENCE MANUAL    by Bram Moolenaar
+
+			    Quick reference guide
+
+							 *quickref* *Contents*
+ tag	  subject			 tag	  subject	~
+|Q_ct|  list of help files		|Q_re|	Repeating commands
+|Q_lr|	motion: Left-right		|Q_km|	Key mapping
+|Q_ud|	motion: Up-down			|Q_ab|	Abbreviations
+|Q_tm|	motion: Text object		|Q_op|	Options
+|Q_pa|	motion: Pattern searches	|Q_ur|	Undo/Redo commands
+|Q_ma|	motion: Marks			|Q_et|	External commands
+|Q_vm|	motion: Various			|Q_qf|	Quickfix commands
+|Q_ta|	motion: Using tags		|Q_vc|	Various commands
+|Q_sc|	Scrolling			|Q_ce|	Ex: Command-line editing
+|Q_in|	insert: Inserting text		|Q_ra|	Ex: Ranges
+|Q_ai|	insert: Keys			|Q_ex|	Ex: Special characters
+|Q_ss|	insert: Special keys		|Q_st|	Starting VIM
+|Q_di|	insert: Digraphs		|Q_ed|	Editing a file
+|Q_si|	insert: Special inserts		|Q_fl|	Using the argument list
+|Q_de|	change: Deleting text		|Q_wq|	Writing and quitting
+|Q_cm|	change: Copying and moving	|Q_ac|	Automatic commands
+|Q_ch|	change: Changing text		|Q_wi|	Multi-window commands
+|Q_co|	change: Complex			|Q_bu|	Buffer list commands
+|Q_vi|	Visual mode			|Q_sy|	Syntax highlighting
+|Q_to|	Text objects			|Q_gu|	GUI commands
+					|Q_fo|  Folding
+
+------------------------------------------------------------------------------
+N is used to indicate an optional count that can be given before the command.
+------------------------------------------------------------------------------
+*Q_lr*		Left-right motions
+
+|h|	N  h		left (also: CTRL-H, <BS>, or <Left> key)
+|l|	N  l		right (also: <Space> or <Right> key)
+|0|	   0		to first character in the line (also: <Home> key)
+|^|	   ^		to first non-blank character in the line
+|$|	N  $		to the last character in the line (N-1 lines lower)
+			   (also: <End> key)
+|g0|	N  g0		to first character in screen line (differs from "0"
+			   when lines wrap)
+|g^|	N  g^		to first non-blank character in screen line (differs
+			   from "^" when lines wrap)
+|g$|	N  g$		to last character in screen line (differs from "$"
+			   when lines wrap)
+|gm|	N  gm		to middle of the screen line
+|bar|	N  |		to column N (default: 1)
+|f|	N  f{char}	to the Nth occurrence of {char} to the right
+|F|	N  F{char}	to the Nth occurrence of {char} to the left
+|t|	N  t{char}	till before the Nth occurrence of {char} to the right
+|T|	N  T{char}	till before the Nth occurrence of {char} to the left
+|;|	N  ;		repeat the last "f", "F", "t", or "T" N times
+|,|	N  ,		repeat the last "f", "F", "t", or "T" N times in
+			   opposite direction
+------------------------------------------------------------------------------
+*Q_ud*		Up-down motions
+
+|k|	N  k		up N lines (also: CTRL-P and <Up>)
+|j|	N  j		down N lines (also: CTRL-J, CTRL-N, <NL>, and <Down>)
+|-|	N  -		up N lines, on the first non-blank character
+|+|	N  +		down N lines, on the first non-blank character (also:
+			   CTRL-M and <CR>)
+|_|	N  _		down N-1 lines, on the first non-blank character
+|G|	N  G		goto line N (default: last line), on the first
+			   non-blank character
+|gg|	N  gg		goto line N (default: first line), on the first
+			   non-blank character
+|N%|	N  %		goto line N percentage down in the file.  N must be
+			   given, otherwise it is the |%| command.
+|gk|	N  gk		up N screen lines (differs from "k" when line wraps)
+|gj|	N  gj		down N screen lines (differs from "j" when line wraps)
+------------------------------------------------------------------------------
+*Q_tm*		Text object motions
+
+|w|	N  w		N words forward
+|W|	N  W		N blank-separated |WORD|s forward
+|e|	N  e		forward to the end of the Nth word
+|E|	N  E		forward to the end of the Nth blank-separated |WORD|
+|b|	N  b		N words backward
+|B|	N  B		N blank-separated |WORD|s backward
+|ge|	N  ge		backward to the end of the Nth word
+|gE|	N  gE		backward to the end of the Nth blank-separated |WORD|
+
+|)|	N  )		N sentences forward
+|(|	N  (		N sentences backward
+|}|	N  }		N paragraphs forward
+|{|	N  {		N paragraphs backward
+|]]|	N  ]]		N sections forward, at start of section
+|[[|	N  [[		N sections backward, at start of section
+|][|	N  ][		N sections forward, at end of section
+|[]|	N  []		N sections backward, at end of section
+|[(|	N  [(		N times back to unclosed '('
+|[{|	N  [{		N times back to unclosed '{'
+|[m|	N  [m		N times back to start of method (for Java)
+|[M|	N  [M		N times back to end of method (for Java)
+|])|	N  ])		N times forward to unclosed ')'
+|]}|	N  ]}		N times forward to unclosed '}'
+|]m|	N  ]m		N times forward to start of method (for Java)
+|]M|	N  ]M		N times forward to end of method (for Java)
+|[#|	N  [#		N times back to unclosed "#if" or "#else"
+|]#|	N  ]#		N times forward to unclosed "#else" or "#endif"
+|[star|	N  [*		N times back to start of comment "/*"
+|]star|	N  ]*		N times forward to end of comment "*/"
+------------------------------------------------------------------------------
+*Q_pa*		Pattern searches
+
+|/|	N  /{pattern}[/[offset]]<CR>
+			search forward for the Nth occurrence of {pattern}
+|?|	N  ?{pattern}[?[offset]]<CR>
+			search backward for the Nth occurrence of {pattern}
+|/<CR>|	N  /<CR>	repeat last search, in the forward direction
+|?<CR>|	N  ?<CR>	repeat last search, in the backward direction
+|n|	N  n		repeat last search
+|N|	N  N		repeat last search, in opposite direction
+|star|	N  *		search forward for the identifier under the cursor
+|#|	N  #		search backward for the identifier under the cursor
+|gstar|	N  g*		like "*", but also find partial matches
+|g#|	N  g#		like "#", but also find partial matches
+|gd|	   gd		goto local declaration of identifier under the cursor
+|gD|	   gD		goto global declaration of identifier under the cursor
+
+|pattern|		Special characters in search patterns
+
+			meaning		      magic   nomagic	~
+		matches any single character	.	\.
+		       matches start of line	^	^
+			       matches <EOL>	$	$
+		       matches start of word	\<	\<
+			 matches end of word	\>	\>
+	matches a single char from the range	[a-z]	\[a-z]
+      matches a single char not in the range	[^a-z]	\[^a-z]
+		  matches an identifier char	\i	\i
+		   idem but excluding digits	\I	\I
+		 matches a keyword character	\k	\k
+		   idem but excluding digits	\K	\K
+	       matches a file name character	\f	\f
+		   idem but excluding digits	\F	\F
+	       matches a printable character	\p	\p
+		   idem but excluding digits	\P	\P
+	     matches a white space character	\s	\s
+	 matches a non-white space character	\S	\S
+
+			       matches <Esc>	\e	\e
+			       matches <Tab>	\t	\t
+				matches <CR>	\r	\r
+				matches <BS>	\b	\b
+
+     matches 0 or more of the preceding atom	*	\*
+     matches 1 or more of the preceding atom	\+	\+
+	matches 0 or 1 of the preceding atom	\=	\=
+	matches 2 to 5 of the preceding atom	\{2,5}  \{2,5}
+		  separates two alternatives	\|	\|
+		group a pattern into an atom	\(\)	\(\)
+
+|search-offset|		Offsets allowed after search command
+
+    [num]	[num] lines downwards, in column 1
+    +[num]	[num] lines downwards, in column 1
+    -[num]	[num] lines upwards, in column 1
+    e[+num]	[num] characters to the right of the end of the match
+    e[-num]	[num] characters to the left of the end of the match
+    s[+num]	[num] characters to the right of the start of the match
+    s[-num]	[num] characters to the left of the start of the match
+    b[+num]	[num] identical to s[+num] above (mnemonic: begin)
+    b[-num]	[num] identical to s[-num] above (mnemonic: begin)
+    ;{search-command}	execute {search-command} next
+------------------------------------------------------------------------------
+*Q_ma*		Marks and motions
+
+|m|	   m{a-zA-Z}	mark current position with mark {a-zA-Z}
+|`a|	   `{a-z}	go to mark {a-z} within current file
+|`A|	   `{A-Z}	go to mark {A-Z} in any file
+|`0|	   `{0-9}	go to the position where Vim was previously exited
+|``|	   ``		go to the position before the last jump
+|`quote|   `"		go to the position when last editing this file
+|`[|	   `[		go to the start of the previously operated or put text
+|`]|	   `]		go to the end of the previously operated or put text
+|`<|	   `<		go to the start of the (previous) Visual area
+|`>|	   `>		go to the end of the (previous) Visual area
+|`.|	   `.		go to the position of the last change in this file
+|'|	   '{a-zA-Z0-9[]'"<>.}
+			same as `, but on the first non-blank in the line
+|:marks|  :marks	print the active marks
+|CTRL-O|  N  CTRL-O	go to Nth older position in jump list
+|CTRL-I|  N  CTRL-I	go to Nth newer position in jump list
+|:ju|	  :ju[mps]	print the jump list
+------------------------------------------------------------------------------
+*Q_vm*		Various motions
+
+|%|	   %		find the next brace, bracket, comment, or "#if"/
+			   "#else"/"#endif" in this line and go to its match
+|H|	N  H		go to the Nth line in the window, on the first
+			   non-blank
+|M|	   M		go to the middle line in the window, on the first
+			   non-blank
+|L|	N  L		go to the Nth line from the bottom, on the first
+			   non-blank
+
+|go|	N  go			go to Nth byte in the buffer
+|:go|	:[range]go[to] [off]	go to [off] byte in the buffer
+------------------------------------------------------------------------------
+*Q_ta*		Using tags
+
+|:ta|	   :ta[g][!] {tag}	Jump to tag {tag}
+|:ta|	   :[count]ta[g][!]	Jump to [count]'th newer tag in tag list
+|CTRL-]|      CTRL-]		Jump to the tag under cursor, unless changes
+				   have been made
+|:ts|	   :ts[elect][!] [tag]	List matching tags and select one to jump to
+|:tjump|   :tj[ump][!] [tag]	Jump to tag [tag] or select from list when
+				   there are multiple matches
+|:ltag|	   :lt[ag][!] [tag]	Jump to tag [tag] and add matching tags to the
+				   location list.
+
+|:tags|	   :tags		Print tag list
+|CTRL-T|   N  CTRL-T		Jump back from Nth older tag in tag list
+|:po|	   :[count]po[p][!]	Jump back from [count]'th older tag in tag list
+|:tnext|   :[count]tn[ext][!]	Jump to [count]'th next matching tag
+|:tp|      :[count]tp[revious][!] Jump to [count]'th previous matching tag
+|:tr|	   :[count]tr[ewind][!] Jump to [count]'th matching tag
+|:tl|	   :tl[ast][!]		Jump to last matching tag
+
+|:ptag|	   :pt[ag] {tag}	open a preview window to show tag {tag}
+|CTRL-W_}|     CTRL-W }		like CTRL-] but show tag in preview window
+|:pts|     :pts[elect]		like ":tselect" but show tag in preview window
+|:ptjump|  :ptj[ump]		like ":tjump" but show tag in preview window
+|:pclose|  :pc[lose]		close tag preview window
+|CTRL-W_z|     CTRL-W z		close tag preview window
+------------------------------------------------------------------------------
+*Q_sc*		Scrolling
+
+|CTRL-E|	N  CTRL-E	window N lines downwards (default: 1)
+|CTRL-D|	N  CTRL-D	window N lines Downwards (default: 1/2 window)
+|CTRL-F|	N  CTRL-F	window N pages Forwards (downwards)
+|CTRL-Y|	N  CTRL-Y	window N lines upwards (default: 1)
+|CTRL-U|	N  CTRL-U	window N lines Upwards (default: 1/2 window)
+|CTRL-B|	N  CTRL-B	window N pages Backwards (upwards)
+|z<CR>|		   z<CR> or zt	redraw, current line at top of window
+|z.|		   z.	 or zz	redraw, current line at center of window
+|z-|		   z-	 or zb	redraw, current line at bottom of window
+
+These only work when 'wrap' is off:
+|zh|		N  zh		scroll screen N characters to the right
+|zl|		N  zl		scroll screen N characters to the left
+|zH|		N  zH		scroll screen half a screenwidth to the right
+|zL|		N  zL		scroll screen half a screenwidth to the left
+------------------------------------------------------------------------------
+*Q_in*		Inserting text
+
+|a|	N  a	append text after the cursor (N times)
+|A|	N  A	append text at the end of the line (N times)
+|i|	N  i	insert text before the cursor (N times) (also: <Insert>)
+|I|	N  I	insert text before the first non-blank in the line (N times)
+|gI|	N  gI	insert text in column 1 (N times)
+|o|	N  o	open a new line below the current line, append text (N times)
+|O|	N  O	open a new line above the current line, append text (N times)
+|:startinsert|  :star[tinsert][!]  start Insert mode, append when [!] used
+|:startreplace| :startr[eplace][!]  start Replace mode, at EOL when [!] used
+
+in Visual block mode:
+|v_b_I|    I	insert the same text in front of all the selected lines
+|v_b_A|	   A	append the same text after all the selected lines
+------------------------------------------------------------------------------
+*Q_ai*		Insert mode keys
+
+|insert-index|	alphabetical index of Insert mode commands
+
+leaving Insert mode:
+|i_<Esc>|	<Esc>		  end Insert mode, back to Normal mode
+|i_CTRL-C|	CTRL-C		  like <Esc>, but do not use an abbreviation
+|i_CTRL-O|	CTRL-O {command}  execute {command} and return to Insert mode
+
+moving around:
+|i_<Up>|	cursor keys	  move cursor left/right/up/down
+|i_<S-Left>|	shift-left/right  one word left/right
+|i_<S-Up>|	shift-up/down	  one screenful backward/forward
+|i_<End>|	<End>		  cursor after last character in the line
+|i_<Home>|	<Home>		  cursor to first character in the line
+------------------------------------------------------------------------------
+*Q_ss*		Special keys in Insert mode
+
+|i_CTRL-V|	CTRL-V {char}..	  insert character literally, or enter decimal
+				     byte value
+|i_<NL>|	<NL> or <CR> or CTRL-M or CTRL-J
+				  begin new line
+|i_CTRL-E|	CTRL-E		  insert the character from below the cursor
+|i_CTRL-Y|	CTRL-Y		  insert the character from above the cursor
+
+|i_CTRL-A|	CTRL-A		  insert previously inserted text
+|i_CTRL-@|	CTRL-@		  insert previously inserted text and stop
+				     Insert mode
+|i_CTRL-R|	CTRL-R {0-9a-z%#:.-="}  insert the contents of a register
+
+|i_CTRL-N|	CTRL-N		  insert next match of identifier before the
+				     cursor
+|i_CTRL-P|	CTRL-P		  insert previous match of identifier before
+				     the cursor
+|i_CTRL-X|	CTRL-X ...	  complete the word before the cursor in
+				     various ways
+
+|i_<BS>|	<BS> or CTRL-H	  delete the character before the cursor
+|i_<Del>|	<Del>		  delete the character under the cursor
+|i_CTRL-W|	CTRL-W		  delete word before the cursor
+|i_CTRL-U|	CTRL-U		  delete all entered characters in the current
+				     line
+|i_CTRL-T|	CTRL-T		  insert one shiftwidth of indent in front of
+				       the current line
+|i_CTRL-D|	CTRL-D		  delete one shiftwidth of indent in front of
+				     the current line
+|i_0_CTRL-D|	0 CTRL-D	  delete all indent in the current line
+|i_^_CTRL-D|	^ CTRL-D	  delete all indent in the current line,
+				     restore indent in next line
+------------------------------------------------------------------------------
+*Q_di*		Digraphs
+
+|:dig|	   :dig[raphs]		show current list of digraphs
+|:dig|	   :dig[raphs] {char1}{char2} {number} ...
+				add digraph(s) to the list
+
+In Insert or Command-line mode:
+|i_CTRL-K|	CTRL-K {char1} {char2}
+				  enter digraph
+|i_digraph|	{char1} <BS> {char2}
+				  enter digraph if 'digraph' option set
+------------------------------------------------------------------------------
+*Q_si*		Special inserts
+
+|:r|	   :r [file]	   insert the contents of [file] below the cursor
+|:r!|	   :r! {command}   insert the standard output of {command} below the
+			      cursor
+------------------------------------------------------------------------------
+*Q_de*		Deleting text
+
+|x|	N  x		delete N characters under and after the cursor
+|<Del>| N  <Del>	delete N characters under and after the cursor
+|X|	N  X		delete N characters before the cursor
+|d|	N  d{motion}	delete the text that is moved over with {motion}
+|v_d|	{visual}d	delete the highlighted text
+|dd|	N  dd		delete N lines
+|D|	N  D		delete to the end of the line (and N-1 more lines)
+|J|	N  J		join N-1 lines (delete <EOL>s)
+|v_J|	{visual}J	join the highlighted lines
+|gJ|	N  gJ		like "J", but without inserting spaces
+|v_gJ|	{visual}gJ	like "{visual}J", but without inserting spaces
+|:d|	:[range]d [x]	delete [range] lines [into register x]
+------------------------------------------------------------------------------
+*Q_cm*		Copying and moving text
+
+|quote|	  "{char}	use register {char} for the next delete, yank, or put
+|:reg|	  :reg		show the contents of all registers
+|:reg|	  :reg {arg}	show the contents of registers mentioned in {arg}
+|y|	  N  y{motion}	yank the text moved over with {motion} into a register
+|v_y|	     {visual}y	yank the highlighted text into a register
+|yy|	  N  yy		yank N lines into a register
+|Y|	  N  Y		yank N lines into a register
+|p|	  N  p		put a register after the cursor position (N times)
+|P|	  N  P		put a register before the cursor position (N times)
+|]p|	  N  ]p		like p, but adjust indent to current line
+|[p|	  N  [p		like P, but adjust indent to current line
+|gp|	  N  gp		like p, but leave cursor after the new text
+|gP|	  N  gP		like P, but leave cursor after the new text
+------------------------------------------------------------------------------
+*Q_ch*		Changing text
+
+|r|	  N  r{char}	replace N characters with {char}
+|gr|	  N  gr{char}	replace N characters without affecting layout
+|R|	  N  R		enter Replace mode (repeat the entered text N times)
+|gR|	  N  gR		enter virtual Replace mode: Like Replace mode but
+			   without affecting layout
+|v_b_r|	  {visual}r{char}
+			in Visual block mode: Replace each char of the
+			   selected text with {char}
+
+	(change = delete text and enter Insert mode)
+|c|	  N  c{motion}	change the text that is moved over with {motion}
+|v_c|	     {visual}c	change the highlighted text
+|cc|	  N  cc		change N lines
+|S|	  N  S		change N lines
+|C|	  N  C		change to the end of the line (and N-1 more lines)
+|s|	  N  s		change N characters
+|v_b_c|	     {visual}c	in Visual block mode: Change each of the selected
+			   lines with the entered text
+|v_b_C|	     {visual}C	in Visual block mode: Change each of the selected
+			   lines until end-of-line with the entered text
+
+|~|	  N  ~		switch case for N characters and advance cursor
+|v_~|	     {visual}~	switch case for highlighted text
+|v_u|	     {visual}u	make highlighted text lowercase
+|v_U|	     {visual}U	make highlighted text uppercase
+|g~|	     g~{motion} switch case for the text that is moved over with
+			   {motion}
+|gu|	     gu{motion} make the text that is moved over with {motion}
+			   lowercase
+|gU|	     gU{motion} make the text that is moved over with {motion}
+			   uppercase
+|v_g?|	     {visual}g? perform rot13 encoding on highlighted text
+|g?|	     g?{motion} perform rot13 encoding on the text that is moved over
+			   with {motion}
+
+|CTRL-A|  N  CTRL-A	add N to the number at or after the cursor
+|CTRL-X|  N  CTRL-X	subtract N from the number at or after the cursor
+
+|<|	  N  <{motion}	move the lines that are moved over with {motion} one
+			   shiftwidth left
+|<<|	  N  <<		move N lines one shiftwidth left
+|>|	  N  >{motion}	move the lines that are moved over with {motion} one
+			   shiftwidth right
+|>>|	  N  >>		move N lines one shiftwidth right
+|gq|	  N  gq{motion}	format the lines that are moved over with {motion} to
+			   'textwidth' length
+|:ce|	  :[range]ce[nter] [width]
+			center the lines in [range]
+|:le|	  :[range]le[ft] [indent]
+			left-align the lines in [range] (with [indent])
+|:ri|	  :[range]ri[ght] [width]
+			right-align the lines in [range]
+------------------------------------------------------------------------------
+*Q_co*		Complex changes
+
+|!|	   N  !{motion}{command}<CR>
+			filter the lines that are moved over through {command}
+|!!|	   N  !!{command}<CR>
+			filter N lines through {command}
+|v_!|	      {visual}!{command}<CR>
+			filter the highlighted lines through {command}
+|:range!|  :[range]! {command}<CR>
+			filter [range] lines through {command}
+|=|	   N  ={motion}
+			filter the lines that are moved over through 'equalprg'
+|==|	   N  ==	filter N lines through 'equalprg'
+|v_=|	      {visual}=
+			filter the highlighted lines through 'equalprg'
+|:s|	   :[range]s[ubstitute]/{pattern}/{string}/[g][c]
+			substitute {pattern} by {string} in [range] lines;
+			   with [g], replace all occurrences of {pattern};
+			   with [c], confirm each replacement
+|:s|	   :[range]s[ubstitute] [g][c]
+			repeat previous ":s" with new range and options
+|&|	      &		Repeat previous ":s" on current line without options
+|:ret|	   :[range]ret[ab][!] [tabstop]
+			set 'tabstop' to new value and adjust white space
+			   accordingly
+------------------------------------------------------------------------------
+*Q_vi*		Visual mode
+
+|visual-index|	list of Visual mode commands.
+
+|v|	   v		start highlighting characters  }  move cursor and use
+|V|	   V		start highlighting linewise    }  operator to affect
+|CTRL-V|   CTRL-V	start highlighting blockwise   }  highlighted text
+|v_o|	   o		exchange cursor position with start of highlighting
+|gv|	   gv		start highlighting on previous visual area
+|v_v|	   v		highlight characters or stop highlighting
+|v_V|	   V		highlight linewise or stop highlighting
+|v_CTRL-V| CTRL-V	highlight blockwise or stop highlighting
+------------------------------------------------------------------------------
+*Q_to*		Text objects (only in Visual mode or after an operator)
+
+|v_aw|	N  aw		Select "a word"
+|v_iw|	N  iw		Select "inner word"
+|v_aW|	N  aW		Select "a |WORD|"
+|v_iW|	N  iW		Select "inner |WORD|"
+|v_as|	N  as		Select "a sentence"
+|v_is|	N  is		Select "inner sentence"
+|v_ap|	N  ap		Select "a paragraph"
+|v_ip|	N  ip		Select "inner paragraph"
+|v_ab|	N  ab		Select "a block" (from "[(" to "])")
+|v_ib|	N  ib		Select "inner block" (from "[(" to "])")
+|v_aB|	N  aB		Select "a Block" (from "[{" to "]}")
+|v_iB|	N  iB		Select "inner Block" (from "[{" to "]}")
+------------------------------------------------------------------------------
+*Q_re*		Repeating commands
+
+|.|	   N  .		repeat last change (with count replaced with N)
+|q|	      q{a-z}	record typed characters into register {a-z}
+|q|	      q{A-Z}	record typed characters, appended to register {a-z}
+|q|	      q		stop recording
+|@|	   N  @{a-z}	execute the contents of register {a-z} (N times)
+|@@|	   N  @@	   repeat previous @{a-z} (N times)
+|:@|	   :@{a-z}	execute the contents of register {a-z} as an Ex
+			   command
+|:@@|	   :@@		repeat previous :@{a-z}
+|:g|	   :[range]g[lobal]/{pattern}/[cmd]
+			Execute Ex command [cmd] (default: ":p") on the lines
+			   within [range] where {pattern} matches.
+|:g|	   :[range]g[lobal]!/{pattern}/[cmd]
+			Execute Ex command [cmd] (default: ":p") on the lines
+			   within [range] where {pattern} does NOT match.
+|:so|	   :so[urce] {file}
+			Read Ex commands from {file}.
+|:so|	   :so[urce]! {file}
+			Read Vim commands from {file}.
+|:sl|	   :sl[eep] [sec]
+			don't do anything for [sec] seconds
+|gs|	   N  gs	Goto Sleep for N seconds
+------------------------------------------------------------------------------
+*Q_km*		Key mapping
+
+|:map|	     :ma[p] {lhs} {rhs}	  Map {lhs} to {rhs} in Normal and Visual
+				     mode.
+|:map!|	     :ma[p]! {lhs} {rhs}  Map {lhs} to {rhs} in Insert and Command-line
+				     mode.
+|:noremap|   :no[remap][!] {lhs} {rhs}
+				  Same as ":map", no remapping for this {rhs}
+|:unmap|     :unm[ap] {lhs}	  Remove the mapping of {lhs} for Normal and
+				     Visual mode.
+|:unmap!|    :unm[ap]! {lhs}	  Remove the mapping of {lhs} for Insert and
+				     Command-line mode.
+|:map_l|     :ma[p] [lhs]	  List mappings (starting with [lhs]) for
+				     Normal and Visual mode.
+|:map_l!|    :ma[p]! [lhs]	  List mappings (starting with [lhs]) for
+				     Insert and Command-line mode.
+|:cmap|	     :cmap/:cunmap/:cnoremap
+				  like ":map!"/":unmap!"/":noremap!" but for
+				     Command-line mode only
+|:imap|	     :imap/:iunmap/:inoremap
+				  like ":map!"/":unmap!"/":noremap!" but for
+				     Insert mode only
+|:nmap|	     :nmap/:nunmap/:nnoremap
+				  like ":map"/":unmap"/":noremap" but for
+				     Normal mode only
+|:vmap|	     :vmap/:vunmap/:vnoremap
+				  like ":map"/":unmap"/":noremap" but for
+				     Visual mode only
+|:omap|	     :omap/:ounmap/:onoremap
+				  like ":map"/":unmap"/":noremap" but only for
+				     when an operator is pending
+|:mapc|      :mapc[lear]	  remove mappings for Normal and Visual mode
+|:mapc|      :mapc[lear]!	  remove mappings for Insert and Cmdline mode
+|:imapc|     :imapc[lear]	  remove mappings for Insert mode
+|:vmapc|     :vmapc[lear]	  remove mappings for Visual mode
+|:omapc|     :omapc[lear]	  remove mappings for Operator-pending mode
+|:nmapc|     :nmapc[lear]	  remove mappings for Normal mode
+|:cmapc|     :cmapc[lear]	  remove mappings for Cmdline mode
+|:mkexrc|    :mk[exrc][!] [file]  write current mappings, abbreviations, and
+				     settings to [file] (default: ".exrc";
+				     use ! to overwrite)
+|:mkvimrc|   :mkv[imrc][!] [file]
+				  same as ":mkexrc", but with default ".vimrc"
+|:mksession| :mks[ession][!] [file]
+				  like ":mkvimrc", but store current files,
+				     windows, etc. too, to be able to continue
+				     this session later.
+------------------------------------------------------------------------------
+*Q_ab*		Abbreviations
+
+|:abbreviate|	:ab[breviate] {lhs} {rhs}  add abbreviation for {lhs} to {rhs}
+|:abbreviate|	:ab[breviate] {lhs}	   show abbr's that start with {lhs}
+|:abbreviate|	:ab[breviate]		   show all abbreviations
+|:unabbreviate|	:una[bbreviate] {lhs}	   remove abbreviation for {lhs}
+|:noreabbrev|	:norea[bbrev] [lhs] [rhs]  like ":ab", but don't remap [rhs]
+|:iabbrev|	:iab/:iunab/:inoreab	   like ":ab", but only for Insert mode
+|:cabbrev|	:cab/:cunab/:cnoreab	   like ":ab", but only for
+						Command-line mode
+|:abclear|	:abc[lear]		   remove all abbreviations
+|:cabclear|	:cabc[lear]		   remove all abbr's for Cmdline mode
+|:iabclear|	:iabc[lear]		   remove all abbr's for Insert mode
+------------------------------------------------------------------------------
+*Q_op*		Options
+
+|:set|		:se[t]			  Show all modified options.
+|:set|		:se[t] all		  Show all non-termcap options.
+|:set|		:se[t] termcap		  Show all termcap options.
+|:set|		:se[t] {option}		  Set boolean option (switch it on),
+					  show string or number option.
+|:set|		:se[t] no{option}	  Reset boolean option (switch it off).
+|:set|		:se[t] inv{option}	  invert boolean option.
+|:set|		:se[t] {option}={value}	  Set string/number option to {value}.
+|:set|		:se[t] {option}+={value}  append {value} to string option, add
+					  {value} to number option
+|:set|		:se[t] {option}-={value}  remove {value} to string option,
+					  subtract {value} from number option
+|:set|		:se[t] {option}?	  Show value of {option}.
+|:set|		:se[t] {option}&	  Reset {option} to its default value.
+
+|:setlocal|	:setl[ocal]		  like ":set" but set the local value
+					  for options that have one
+|:setglobal|	:setg[lobal]		  like ":set" but set the global value
+					  of a local option
+
+|:fix|		:fix[del]		  Set value of 't_kD' according to
+					  value of 't_kb'.
+|:options|	:opt[ions]		  Open a new window to view and set
+					  options, grouped by functionality,
+					  a one line explanation and links to
+					  the help.
+
+Short explanation of each option:		*option-list*
+'aleph'		  'al'	    ASCII code of the letter Aleph (Hebrew)
+'allowrevins'	  'ari'     allow CTRL-_ in Insert and Command-line mode
+'altkeymap'	  'akm'     for default second language (Farsi/Hebrew)
+'ambiwidth'	  'ambw'    what to do with Unicode chars of ambiguous width
+'antialias'	  'anti'    Mac OS X: use smooth, antialiased fonts
+'autochdir'	  'acd'     change directory to the file in the current window
+'arabic'	  'arab'    for Arabic as a default second language
+'arabicshape'	  'arshape' do shaping for Arabic characters
+'autoindent'	  'ai'	    take indent for new line from previous line
+'autoread'	  'ar'	    autom. read file when changed outside of Vim
+'autowrite'	  'aw'	    automatically write file if changed
+'autowriteall'	  'awa'     as 'autowrite', but works with more commands
+'background'	  'bg'	    "dark" or "light", used for highlight colors
+'backspace'	  'bs'	    how backspace works at start of line
+'backup'	  'bk'	    keep backup file after overwriting a file
+'backupcopy'	  'bkc'     make backup as a copy, don't rename the file
+'backupdir'	  'bdir'    list of directories for the backup file
+'backupext'	  'bex'     extension used for the backup file
+'backupskip'	  'bsk'     no backup for files that match these patterns
+'balloondelay'	  'bdlay'   delay in mS before a balloon may pop up
+'ballooneval'	  'beval'   switch on balloon evaluation
+'balloonexpr'	  'bexpr'   expression to show in balloon
+'binary'	  'bin'     read/write/edit file in binary mode
+'bioskey'	  'biosk'   MS-DOS: use bios calls for input characters
+'bomb'			    prepend a Byte Order Mark to the file
+'breakat'	  'brk'     characters that may cause a line break
+'browsedir'	  'bsdir'   which directory to start browsing in
+'bufhidden'	  'bh'	    what to do when buffer is no longer in window
+'buflisted'	  'bl'	    whether the buffer shows up in the buffer list
+'buftype'	  'bt'	    special type of buffer
+'casemap'	  'cmp'     specifies how case of letters is changed
+'cdpath'	  'cd'	    list of directories searched with ":cd"
+'cedit'			    key used to open the command-line window
+'charconvert'	  'ccv'     expression for character encoding conversion
+'cindent'	  'cin'     do C program indenting
+'cinkeys'	  'cink'    keys that trigger indent when 'cindent' is set
+'cinoptions'	  'cino'    how to do indenting when 'cindent' is set
+'cinwords'	  'cinw'    words where 'si' and 'cin' add an indent
+'clipboard'	  'cb'	    use the clipboard as the unnamed register
+'cmdheight'	  'ch'	    number of lines to use for the command-line
+'cmdwinheight'	  'cwh'     height of the command-line window
+'columns'	  'co'	    number of columns in the display
+'comments'	  'com'     patterns that can start a comment line
+'commentstring'   'cms'     template for comments; used for fold marker
+'compatible'	  'cp'	    behave Vi-compatible as much as possible
+'complete'	  'cpt'     specify how Insert mode completion works
+'completefunc'	  'cfu'     function to be used for Insert mode completion
+'completeopt'	  'cot'     options for Insert mode completion
+'confirm'	  'cf'	    ask what to do about unsaved/read-only files
+'conskey'	  'consk'   get keys directly from console (MS-DOS only)
+'copyindent'	  'ci'	    make 'autoindent' use existing indent structure
+'cpoptions'	  'cpo'     flags for Vi-compatible behavior
+'cscopepathcomp'  'cspc'    how many components of the path to show
+'cscopeprg'       'csprg'   command to execute cscope
+'cscopequickfix'  'csqf'    use quickfix window for cscope results
+'cscopetag'       'cst'     use cscope for tag commands
+'cscopetagorder'  'csto'    determines ":cstag" search order
+'cscopeverbose'   'csverb'  give messages when adding a cscope database
+'cursorcolumn'	  'cuc'	    highlight the screen column of the cursor
+'cursorline'	  'cul'	    highlight the screen line of the cursor
+'debug'			    set to "msg" to see all error messages
+'define'	  'def'     pattern to be used to find a macro definition
+'delcombine'	  'deco'    delete combining characters on their own
+'dictionary'	  'dict'    list of file names used for keyword completion
+'diff'			    use diff mode for the current window
+'diffexpr'	  'dex'     expression used to obtain a diff file
+'diffopt'	  'dip'     options for using diff mode
+'digraph'	  'dg'	    enable the entering of digraphs in Insert mode
+'directory'	  'dir'     list of directory names for the swap file
+'display'	  'dy'	    list of flags for how to display text
+'eadirection'	  'ead'     in which direction 'equalalways' works
+'edcompatible'	  'ed'	    toggle flags of ":substitute" command
+'encoding'	  'enc'     encoding used internally
+'endofline'	  'eol'     write <EOL> for last line in file
+'equalalways'	  'ea'	    windows are automatically made the same size
+'equalprg'	  'ep'	    external program to use for "=" command
+'errorbells'	  'eb'	    ring the bell for error messages
+'errorfile'	  'ef'	    name of the errorfile for the QuickFix mode
+'errorformat'	  'efm'     description of the lines in the error file
+'esckeys'	  'ek'	    recognize function keys in Insert mode
+'eventignore'	  'ei'	    autocommand events that are ignored
+'expandtab'	  'et'	    use spaces when <Tab> is inserted
+'exrc'		  'ex'	    read .vimrc and .exrc in the current directory
+'fileencoding'	  'fenc'    file encoding for multi-byte text
+'fileencodings'   'fencs'   automatically detected character encodings
+'fileformat'	  'ff'	    file format used for file I/O
+'fileformats'	  'ffs'     automatically detected values for 'fileformat'
+'filetype'	  'ft'	    type of file, used for autocommands
+'fillchars'	  'fcs'     characters to use for displaying special items
+'fkmap'		  'fk'	    Farsi keyboard mapping
+'foldclose'	  'fcl'     close a fold when the cursor leaves it
+'foldcolumn'	  'fdc'     width of the column used to indicate folds
+'foldenable'	  'fen'     set to display all folds open
+'foldexpr'	  'fde'     expression used when 'foldmethod' is "expr"
+'foldignore'	  'fdi'     ignore lines when 'foldmethod' is "indent"
+'foldlevel'	  'fdl'     close folds with a level higher than this
+'foldlevelstart'  'fdls'    'foldlevel' when starting to edit a file
+'foldmarker'	  'fmr'     markers used when 'foldmethod' is "marker"
+'foldmethod'	  'fdm'     folding type
+'foldminlines'	  'fml'     minimum number of lines for a fold to be closed
+'foldnestmax'	  'fdn'     maximum fold depth
+'foldopen'	  'fdo'     for which commands a fold will be opened
+'foldtext'	  'fdt'     expression used to display for a closed fold
+'formatlistpat'   'flp'     pattern used to recognize a list header
+'formatoptions'   'fo'	    how automatic formatting is to be done
+'formatprg'	  'fp'	    name of external program used with "gq" command
+'formatexpr'	  'fex'     expression used with "gq" command
+'fsync'		  'fs'	    whether to invoke fsync() after file write
+'gdefault'	  'gd'	    the ":substitute" flag 'g' is default on
+'grepformat'	  'gfm'     format of 'grepprg' output
+'grepprg'	  'gp'	    program to use for ":grep"
+'guicursor'	  'gcr'     GUI: settings for cursor shape and blinking
+'guifont'	  'gfn'     GUI: Name(s) of font(s) to be used
+'guifontset'	  'gfs'     GUI: Names of multi-byte fonts to be used
+'guifontwide'	  'gfw'     list of font names for double-wide characters
+'guiheadroom'	  'ghr'     GUI: pixels room for window decorations
+'guioptions'	  'go'	    GUI: Which components and options are used
+'guipty'		    GUI: try to use a pseudo-tty for ":!" commands
+'guitablabel'	  'gtl'     GUI: custom label for a tab page
+'guitabtooltip'   'gtt'     GUI: custom tooltip for a tab page
+'helpfile'	  'hf'	    full path name of the main help file
+'helpheight'	  'hh'	    minimum height of a new help window
+'helplang'	  'hlg'     preferred help languages
+'hidden'	  'hid'     don't unload buffer when it is |abandon|ed
+'highlight'	  'hl'	    sets highlighting mode for various occasions
+'hlsearch'	  'hls'     highlight matches with last search pattern
+'history'	  'hi'	    number of command-lines that are remembered
+'hkmap'		  'hk'	    Hebrew keyboard mapping
+'hkmapp'	  'hkp'     phonetic Hebrew keyboard mapping
+'icon'			    let Vim set the text of the window icon
+'iconstring'		    string to use for the Vim icon text
+'ignorecase'	  'ic'	    ignore case in search patterns
+'imactivatekey'   'imak'    key that activates the X input method
+'imcmdline'	  'imc'     use IM when starting to edit a command line
+'imdisable'	  'imd'     do not use the IM in any mode
+'iminsert'	  'imi'     use :lmap or IM in Insert mode
+'imsearch'	  'ims'     use :lmap or IM when typing a search pattern
+'include'	  'inc'     pattern to be used to find an include file
+'includeexpr'	  'inex'    expression used to process an include line
+'incsearch'	  'is'	    highlight match while typing search pattern
+'indentexpr'	  'inde'    expression used to obtain the indent of a line
+'indentkeys'	  'indk'    keys that trigger indenting with 'indentexpr'
+'infercase'	  'inf'     adjust case of match for keyword completion
+'insertmode'	  'im'	    start the edit of a file in Insert mode
+'isfname'	  'isf'     characters included in file names and pathnames
+'isident'	  'isi'     characters included in identifiers
+'iskeyword'	  'isk'     characters included in keywords
+'isprint'	  'isp'     printable characters
+'joinspaces'	  'js'	    two spaces after a period with a join command
+'key'			    encryption key
+'keymap'	  'kmp'     name of a keyboard mapping
+'keymodel'	  'km'	    enable starting/stopping selection with keys
+'keywordprg'	  'kp'	    program to use for the "K" command
+'langmap'	  'lmap'    alphabetic characters for other language mode
+'langmenu'	  'lm'	    language to be used for the menus
+'laststatus'	  'ls'	    tells when last window has status lines
+'lazyredraw'	  'lz'	    don't redraw while executing macros
+'linebreak'	  'lbr'     wrap long lines at a blank
+'lines'			    number of lines in the display
+'linespace'	  'lsp'     number of pixel lines to use between characters
+'lisp'			    automatic indenting for Lisp
+'lispwords'	  'lw'	    words that change how lisp indenting works
+'list'			    show <Tab> and <EOL>
+'listchars'	  'lcs'     characters for displaying in list mode
+'loadplugins'	  'lpl'     load plugin scripts when starting up
+'macatsui'		    Mac GUI: use ATSUI text drawing
+'magic'			    changes special characters in search patterns
+'makeef'	  'mef'     name of the errorfile for ":make"
+'makeprg'	  'mp'	    program to use for the ":make" command
+'matchpairs'	  'mps'     pairs of characters that "%" can match
+'matchtime'	  'mat'     tenths of a second to show matching paren
+'maxcombine'	  'mco'     maximum nr of combining characters displayed
+'maxfuncdepth'	  'mfd'     maximum recursive depth for user functions
+'maxmapdepth'	  'mmd'     maximum recursive depth for mapping
+'maxmem'	  'mm'	    maximum memory (in Kbyte) used for one buffer
+'maxmempattern'   'mmp'     maximum memory (in Kbyte) used for pattern search
+'maxmemtot'	  'mmt'     maximum memory (in Kbyte) used for all buffers
+'menuitems'	  'mis'     maximum number of items in a menu
+'mkspellmem'	  'msm'     memory used before |:mkspell| compresses the tree
+'modeline'	  'ml'	    recognize modelines at start or end of file
+'modelines'	  'mls'     number of lines checked for modelines
+'modifiable'	  'ma'	    changes to the text are not possible
+'modified'	  'mod'     buffer has been modified
+'more'			    pause listings when the whole screen is filled
+'mouse'			    enable the use of mouse clicks
+'mousefocus'	  'mousef'  keyboard focus follows the mouse
+'mousehide'	  'mh'	    hide mouse pointer while typing
+'mousemodel'	  'mousem'  changes meaning of mouse buttons
+'mouseshape'	  'mouses'  shape of the mouse pointer in different modes
+'mousetime'	  'mouset'  max time between mouse double-click
+'mzquantum'	  'mzq'     the interval between polls for MzScheme threads
+'nrformats'	  'nf'	    number formats recognized for CTRL-A command
+'number'	  'nu'	    print the line number in front of each line
+'numberwidth'	  'nuw'     number of columns used for the line number
+'omnifunc'	  'ofu'     function for filetype-specific completion
+'opendevice'	  'odev'    allow reading/writing devices on MS-Windows
+'operatorfunc'	  'opfunc'  function to be called for |g@| operator
+'osfiletype'	  'oft'     operating system-specific filetype information
+'paragraphs'	  'para'    nroff macros that separate paragraphs
+'paste'			    allow pasting text
+'pastetoggle'	  'pt'	    key code that causes 'paste' to toggle
+'patchexpr'	  'pex'     expression used to patch a file
+'patchmode'	  'pm'	    keep the oldest version of a file
+'path'		  'pa'	    list of directories searched with "gf" et.al.
+'preserveindent'  'pi'	    preserve the indent structure when reindenting
+'previewheight'   'pvh'     height of the preview window
+'previewwindow'   'pvw'     identifies the preview window
+'printdevice'	  'pdev'    name of the printer to be used for :hardcopy
+'printencoding'   'penc'    encoding to be used for printing
+'printexpr'	  'pexpr'   expression used to print PostScript for :hardcopy
+'printfont'	  'pfn'     name of the font to be used for :hardcopy
+'printheader'	  'pheader' format of the header used for :hardcopy
+'printmbcharset'  'pmbcs'   CJK character set to be used for :hardcopy
+'printmbfont'	  'pmbfn'   font names to be used for CJK output of :hardcopy
+'printoptions'	  'popt'    controls the format of :hardcopy output
+'pumheight'	  'ph'	    maximum height of the popup menu
+'quoteescape'	  'qe'	    escape characters used in a string
+'readonly'	  'ro'	    disallow writing the buffer
+'remap'			    allow mappings to work recursively
+'report'		    threshold for reporting nr. of lines changed
+'restorescreen'   'rs'	    Win32: restore screen when exiting
+'revins'	  'ri'	    inserting characters will work backwards
+'rightleft'	  'rl'	    window is right-to-left oriented
+'rightleftcmd'	  'rlc'     commands for which editing works right-to-left
+'ruler'		  'ru'	    show cursor line and column in the status line
+'rulerformat'	  'ruf'     custom format for the ruler
+'runtimepath'	  'rtp'     list of directories used for runtime files
+'scroll'	  'scr'     lines to scroll with CTRL-U and CTRL-D
+'scrollbind'	  'scb'     scroll in window as other windows scroll
+'scrolljump'	  'sj'	    minimum number of lines to scroll
+'scrolloff'	  'so'	    minimum nr. of lines above and below cursor
+'scrollopt'	  'sbo'     how 'scrollbind' should behave
+'sections'	  'sect'    nroff macros that separate sections
+'secure'		    secure mode for reading .vimrc in current dir
+'selection'	  'sel'     what type of selection to use
+'selectmode'	  'slm'     when to use Select mode instead of Visual mode
+'sessionoptions'  'ssop'    options for |:mksession|
+'shell'		  'sh'	    name of shell to use for external commands
+'shellcmdflag'	  'shcf'    flag to shell to execute one command
+'shellpipe'	  'sp'	    string to put output of ":make" in error file
+'shellquote'	  'shq'     quote character(s) for around shell command
+'shellredir'	  'srr'     string to put output of filter in a temp file
+'shellslash'	  'ssl'     use forward slash for shell file names
+'shelltemp'	  'stmp'    whether to use a temp file for shell commands
+'shelltype'	  'st'	    Amiga: influences how to use a shell
+'shellxquote'	  'sxq'     like 'shellquote', but include redirection
+'shiftround'	  'sr'	    round indent to multiple of shiftwidth
+'shiftwidth'	  'sw'	    number of spaces to use for (auto)indent step
+'shortmess'	  'shm'     list of flags, reduce length of messages
+'shortname'	  'sn'	    non-MS-DOS: Filenames assumed to be 8.3 chars
+'showbreak'	  'sbr'     string to use at the start of wrapped lines
+'showcmd'	  'sc'	    show (partial) command in status line
+'showfulltag'	  'sft'     show full tag pattern when completing tag
+'showmatch'	  'sm'	    briefly jump to matching bracket if insert one
+'showmode'	  'smd'     message on status line to show current mode
+'showtabline'	  'stal'    tells when the tab pages line is displayed
+'sidescroll'	  'ss'	    minimum number of columns to scroll horizontal
+'sidescrolloff'   'siso'    min. nr. of columns to left and right of cursor
+'smartcase'	  'scs'     no ignore case when pattern has uppercase
+'smartindent'	  'si'	    smart autoindenting for C programs
+'smarttab'	  'sta'     use 'shiftwidth' when inserting <Tab>
+'softtabstop'	  'sts'     number of spaces that <Tab> uses while editing
+'spell'			    enable spell checking
+'spellcapcheck'   'spc'     pattern to locate end of a sentence
+'spellfile'	  'spf'     files where |zg| and |zw| store words
+'spelllang'	  'spl'     language(s) to do spell checking for
+'spellsuggest'	  'sps'     method(s) used to suggest spelling corrections
+'splitbelow'	  'sb'	    new window from split is below the current one
+'splitright'	  'spr'     new window is put right of the current one
+'startofline'	  'sol'     commands move cursor to first blank in line
+'statusline'	  'stl'     custom format for the status line
+'suffixes'	  'su'	    suffixes that are ignored with multiple match
+'suffixesadd'	  'sua'     suffixes added when searching for a file
+'swapfile'	  'swf'     whether to use a swapfile for a buffer
+'swapsync'	  'sws'     how to sync the swap file
+'switchbuf'	  'swb'     sets behavior when switching to another buffer
+'synmaxcol'	  'smc'     maximum column to find syntax items
+'syntax'	  'syn'     syntax to be loaded for current buffer
+'tabstop'	  'ts'	    number of spaces that <Tab> in file uses
+'tabline'	  'tal'     custom format for the console tab pages line
+'tabpagemax'	  'tpm'     maximum number of tab pages for |-p| and "tab all"
+'tagbsearch'	  'tbs'     use binary searching in tags files
+'taglength'	  'tl'	    number of significant characters for a tag
+'tagrelative'	  'tr'	    file names in tag file are relative
+'tags'		  'tag'     list of file names used by the tag command
+'tagstack'	  'tgst'    push tags onto the tag stack
+'term'			    name of the terminal
+'termbidi'	  'tbidi'   terminal takes care of bi-directionality
+'termencoding'	  'tenc'    character encoding used by the terminal
+'terse'			    shorten some messages
+'textauto'	  'ta'	    obsolete, use 'fileformats'
+'textmode'	  'tx'	    obsolete, use 'fileformat'
+'textwidth'	  'tw'	    maximum width of text that is being inserted
+'thesaurus'	  'tsr'     list of thesaurus files for keyword completion
+'tildeop'	  'top'     tilde command "~" behaves like an operator
+'timeout'	  'to'	    time out on mappings and key codes
+'timeoutlen'	  'tm'	    time out time in milliseconds
+'title'			    let Vim set the title of the window
+'titlelen'		    percentage of 'columns' used for window title
+'titleold'		    old title, restored when exiting
+'titlestring'		    string to use for the Vim window title
+'toolbar'	  'tb'	    GUI: which items to show in the toolbar
+'toolbariconsize' 'tbis'    size of the toolbar icons (for GTK 2 only)
+'ttimeout'		    time out on mappings
+'ttimeoutlen'	  'ttm'     time out time for key codes in milliseconds
+'ttybuiltin'	  'tbi'     use built-in termcap before external termcap
+'ttyfast'	  'tf'	    indicates a fast terminal connection
+'ttymouse'	  'ttym'    type of mouse codes generated
+'ttyscroll'	  'tsl'     maximum number of lines for a scroll
+'ttytype'	  'tty'     alias for 'term'
+'undolevels'	  'ul'	    maximum number of changes that can be undone
+'updatecount'	  'uc'	    after this many characters flush swap file
+'updatetime'	  'ut'	    after this many milliseconds flush swap file
+'verbose'	  'vbs'     give informative messages
+'verbosefile'	  'vfile'   file to write messages in
+'viewdir'	  'vdir'    directory where to store files with :mkview
+'viewoptions'	  'vop'     specifies what to save for :mkview
+'viminfo'	  'vi'	    use .viminfo file upon startup and exiting
+'virtualedit'	  've'	    when to use virtual editing
+'visualbell'	  'vb'	    use visual bell instead of beeping
+'warn'			    warn for shell command when buffer was changed
+'weirdinvert'	  'wi'	    for terminals that have weird inversion method
+'whichwrap'	  'ww'	    allow specified keys to cross line boundaries
+'wildchar'	  'wc'	    command-line character for wildcard expansion
+'wildcharm'	  'wcm'     like 'wildchar' but also works when mapped
+'wildignore'	  'wig'     files matching these patterns are not completed
+'wildmenu'	  'wmnu'    use menu for command line completion
+'wildmode'	  'wim'     mode for 'wildchar' command-line expansion
+'wildoptions'	  'wop'     specifies how command line completion is done.
+'winaltkeys'	  'wak'     when the windows system handles ALT keys
+'winheight'	  'wh'	    minimum number of lines for the current window
+'winfixheight'	  'wfh'     keep window height when opening/closing windows
+'winfixwidth'	  'wfw'     keep window width when opening/closing windows
+'winminheight'	  'wmh'     minimum number of lines for any window
+'winminwidth'	  'wmw'     minimal number of columns for any window
+'winwidth'	  'wiw'     minimal number of columns for current window
+'wrap'			    long lines wrap and continue on the next line
+'wrapmargin'	  'wm'	    chars from the right where wrapping starts
+'wrapscan'	  'ws'	    searches wrap around the end of the file
+'write'			    writing to a file is allowed
+'writeany'	  'wa'	    write to file with no need for "!" override
+'writebackup'	  'wb'	    make a backup before overwriting a file
+'writedelay'	  'wd'	    delay this many msec for each char (for debug)
+------------------------------------------------------------------------------
+*Q_ur*		Undo/Redo commands
+
+|u|	  N  u		undo last N changes
+|CTRL-R|  N  CTRL-R	redo last N undone changes
+|U|	     U		restore last changed line
+------------------------------------------------------------------------------
+*Q_et*		External commands
+
+|:shell|	:sh[ell]	start a shell
+|:!|		:!{command}	execute {command} with a shell
+|K|		   K		lookup keyword under the cursor with
+				   'keywordprg' program (default: "man")
+------------------------------------------------------------------------------
+*Q_qf*		Quickfix commands
+
+|:cc|		:cc [nr]	display error [nr] (default is the same again)
+|:cnext|	:cn		display the next error
+|:cprevious|	:cp		display the previous error
+|:clist|	:cl		list all errors
+|:cfile|	:cf		read errors from the file 'errorfile'
+|:cgetbuffer|	:cgetb		like :cbuffer but don't jump to the first error
+|:cgetfile|	:cg		like :cfile but don't jump to the first error
+|:cgetexpr|	:cgete		like :cexpr but don't jump to the first error
+|:caddfile|	:caddf		add errors from the error file to the current
+				   quickfix list
+|:caddexpr|	:cad		add errors from an expression to the current
+				   quickfix list
+|:cbuffer|	:cb		read errors from text in a buffer
+|:cexpr|	:cex		read errors from an expression
+|:cquit|	:cq		quit without writing and return error code (to
+				   the compiler)
+|:make|		:make [args]	start make, read errors, and jump to first
+				   error
+|:grep|		:gr[ep] [args]	execute 'grepprg' to find matches and jump to
+				   the first one.
+------------------------------------------------------------------------------
+*Q_vc*		Various commands
+
+|CTRL-L|	   CTRL-L	Clear and redraw the screen.
+|CTRL-G|	   CTRL-G	show current file name (with path) and cursor
+				   position
+|ga|		   ga		show ascii value of character under cursor in
+				   decimal, hex, and octal
+|g8|		   g8		for utf-8 encoding: show byte sequence for
+				   character under cursor in hex.
+|g_CTRL-G|	   g CTRL-G	show cursor column, line, and character
+				   position
+|CTRL-C|	   CTRL-C	during searches: Interrupt the search
+|dos-CTRL-Break|   CTRL-Break	MS-DOS: during searches: Interrupt the search
+|<Del>|		   <Del>	while entering a count: delete last character
+|:version|	:ve[rsion]	show version information
+|:mode|		:mode N		MS-DOS: set screen mode to N (number, C80,
+				   C4350, etc.)
+|:normal|	:norm[al][!] {commands}
+				Execute Normal mode commands.
+|Q|		Q		switch to "Ex" mode
+
+|:redir|	:redir >{file}		redirect messages to {file}
+|:silent|	:silent[!] {command}	execute {command} silently
+|:confirm|	:confirm {command}	quit, write, etc., asking about
+					unsaved changes or read-only files.
+|:browse|	:browse {command}	open/read/write file, using a
+					file selection dialog
+------------------------------------------------------------------------------
+*Q_ce*		Command-line editing
+
+|c_<Esc>|	<Esc>		   abandon command-line (if 'wildchar' is
+				      <Esc>, type it twice)
+
+|c_CTRL-V|	CTRL-V {char}	   insert {char} literally
+|c_CTRL-V|	CTRL-V {number}    enter decimal value of character (up to
+				      three digits)
+|c_CTRL-K|	CTRL-K {char1} {char2}
+				   enter digraph (See |Q_di|)
+|c_CTRL-R|	CTRL-R {0-9a-z"%#:-=}
+				   insert the contents of a register
+
+|c_<Left>|	<Left>/<Right>	   cursor left/right
+|c_<S-Left>|	<S-Left>/<S-Right> cursor one word left/right
+|c_CTRL-B|	CTRL-B/CTRL-E	   cursor to beginning/end of command-line
+
+|c_<BS>|	<BS>		   delete the character in front of the cursor
+|c_<Del>|	<Del>		   delete the character under the cursor
+|c_CTRL-W|	CTRL-W		   delete the word in front of the cursor
+|c_CTRL-U|	CTRL-U		   remove all characters
+
+|c_<Up>|	<Up>/<Down>	   recall older/newer command-line that starts
+				      with current command
+|c_<S-Up>|	<S-Up>/<S-Down>	   recall older/newer command-line from history
+|:history|	:his[tory]	   show older command-lines
+
+Context-sensitive completion on the command-line:
+
+|c_wildchar|	'wildchar'  (default: <Tab>)
+				do completion on the pattern in front of the
+				   cursor.  If there are multiple matches,
+				   beep and show the first one; further
+				   'wildchar' will show the next ones.
+|c_CTRL-D|	CTRL-D		list all names that match the pattern in
+				   front of the cursor
+|c_CTRL-A|	CTRL-A		insert all names that match pattern in front
+				   of cursor
+|c_CTRL-L|	CTRL-L		insert longest common part of names that
+				   match pattern
+|c_CTRL-N|	CTRL-N		after 'wildchar' with multiple matches: go
+				   to next match
+|c_CTRL-P|	CTRL-P		after 'wildchar' with multiple matches: go
+				   to previous match
+------------------------------------------------------------------------------
+*Q_ra*		Ex ranges
+
+|:range|	,		separates two line numbers
+|:range|	;		idem, set cursor to the first line number
+				before interpreting the second one
+
+|:range|	{number}	an absolute line number
+|:range|	.		the current line
+|:range|	$		the last line in the file
+|:range|	%		equal to 1,$ (the entire file)
+|:range|	*		equal to '<,'> (visual area)
+|:range|	't		position of mark t
+|:range|	/{pattern}[/]	the next line where {pattern} matches
+|:range|	?{pattern}[?]	the previous line where {pattern} matches
+
+|:range|	+[num]		add [num] to the preceding line number
+				   (default: 1)
+|:range|	-[num]		subtract [num] from the preceding line
+				   number (default: 1)
+------------------------------------------------------------------------------
+*Q_ex*		Special Ex characters
+
+|:bar|	    |		separates two commands (not for ":global" and ":!")
+|:quote|    "		begins comment
+
+|:_%|	    %		current file name (only where a file name is expected)
+|:_#|	    #[num]	alternate file name [num] (only where a file name is
+			   expected)
+	Note: The next four are typed literally; these are not special keys!
+|:<cword>|  <cword>	word under the cursor (only where a file name is
+			   expected)
+|:<cWORD>|  <cWORD>	WORD under the cursor (only where a file name is
+			   expected) (see |WORD|)
+|:<cfile>|  <cfile>	file name under the cursor (only where a file name is
+			   expected)
+|:<afile>|  <afile>	file name for autocommand (only where a file name is
+			   expected)
+|:<sfile>|  <sfile>	file name of a ":source"d file, within that file (only
+			   where a file name is expected)
+
+		After "%", "#", "<cfile>", "<sfile>" or "<afile>"
+		|::p|	    :p		full path
+		|::h|	    :h		head (file name removed)
+		|::t|	    :t		tail (file name only)
+		|::r|	    :r		root (extension removed)
+		|::e|	    :e		extension
+		|::s|	    :s/{pat}/{repl}/	substitute {pat} with {repl}
+------------------------------------------------------------------------------
+*Q_st*		Starting VIM
+
+|-vim|	   vim [options]		start editing with an empty buffer
+|-file|	   vim [options] {file} ..	start editing one or more files
+|--|	   vim [options] -		read file from stdin
+|-tag|	   vim [options] -t {tag}	edit the file associated with {tag}
+|-qf|	   vim [options] -q [fname]	start editing in QuickFix mode,
+					   display the first error
+
+	Most useful Vim arguments (for full list see |startup-options|)
+
+|-gui|	-g		    start GUI (also allows other options)
+
+|-+|	+[num]		    put the cursor at line [num] (default: last line)
+|-+c|	+{command}	    execute {command} after loading the file
+|-+/|	+/{pat} {file} ..   put the cursor at the first occurrence of {pat}
+|-v|	-v		    Vi mode, start ex in Normal mode
+|-e|	-e		    Ex mode, start vim in Ex mode
+|-R|	-R		    Read-only mode, implies -n
+|-m|	-m		    modifications not allowed (resets 'write' option)
+|-d|	-d		    diff mode |diff|
+|-b|	-b		    binary mode
+|-l|	-l		    lisp mode
+|-A|	-A		    Arabic mode ('arabic' is set)
+|-F|	-F		    Farsi mode ('fkmap' and 'rightleft' are set)
+|-H|	-H		    Hebrew mode ('hkmap' and 'rightleft' are set)
+|-V|	-V		    Verbose, give informative messages
+|-C|	-C		    Compatible, set the 'compatible' option
+|-N|	-N		    Nocompatible, reset the 'compatible' option
+|-r|	-r		    give list of swap files
+|-r|	-r {file} ..	    recover aborted edit session
+|-n|	-n		    do not create a swap file
+|-o|	-o [num]	    open [num] windows (default: one for each file)
+|-f|	-f		    GUI: foreground process, don't fork
+			    Amiga: do not restart VIM to open a window (for
+				e.g., mail)
+|-s|	-s {scriptin}	    first read commands from the file {scriptin}
+|-w|	-w {scriptout}	    write typed chars to file {scriptout} (append)
+|-W|	-W {scriptout}	    write typed chars to file {scriptout} (overwrite)
+|-T|	-T {terminal}	    set terminal name
+|-d|	-d {device}	    Amiga: open {device} to be used as a console
+|-u|	-u {vimrc}	    read inits from {vimrc} instead of other inits
+|-U|	-U {gvimrc}	    idem, for when starting the GUI
+|-i|	-i {viminfo}	    read info from {viminfo} instead of other files
+|---|	--		    end of options, other arguments are file names
+|--help|    --help	    show list of arguments and exit
+|--version| --version	    show version info and exit
+|--|	-		    Read file from stdin.
+------------------------------------------------------------------------------
+*Q_ed*		Editing a file
+
+	   Without !: Fail if changes has been made to the current buffer.
+	      With !: Discard any changes to the current buffer.
+|:edit_f|  :e[dit][!] {file}	Edit {file}.
+|:edit|	   :e[dit][!]		Reload the current file.
+|:enew|	   :ene[w][!]		Edit a new, unnamed buffer.
+|:find|    :fin[d][!] {file}	Find {file} in 'path' and edit it.
+
+|CTRL-^|   N   CTRL-^		Edit alternate file N (equivalent to ":e #N").
+|gf|	       gf  or ]f	Edit the file whose name is under the cursor
+|:pwd|	   :pwd			Print the current directory name.
+|:cd|	   :cd [path]		Change the current directory to [path].
+|:cd-|	   :cd -		Back to previous current directory.
+|:file|	   :f[ile]		Print the current file name and the cursor
+				   position.
+|:file|	   :f[ile] {name}	Set the current file name to {name}.
+|:files|   :files		Show alternate file names.
+------------------------------------------------------------------------------
+*Q_fl*		Using the argument list			|argument-list|
+
+|:args|	   :ar[gs]		Print the argument list, with the current file
+				   in "[]".
+|:all|	   :all  or :sall	Open a window for every file in the arg list.
+|:wn|	   :wn[ext][!]		Write file and edit next file.
+|:wn|	   :wn[ext][!] {file}	Write to {file} and edit next file, unless
+				   {file} exists.  With !, overwrite existing
+				   file.
+|:wN|	   :wN[ext][!] [file]	Write file and edit previous file.
+
+	     in current window    in new window	~
+|:argument|  :argu[ment] N	  :sar[gument] N	Edit file N
+|:next|	     :n[ext]		  :sn[ext]		Edit next file
+|:next_f|    :n[ext] {arglist}	  :sn[ext] {arglist}	define new arg list
+							   and edit first file
+|:Next|	     :N[ext]		  :sN[ext]		Edit previous file
+|:first|     :fir[st]		  :sfir[st]		Edit first file
+|:last|	     :la[st]		  :sla[st]		Edit last file
+------------------------------------------------------------------------------
+*Q_wq*		Writing and quitting
+
+|:w|	  :[range]w[rite][!]		Write to the current file.
+|:w_f|	  :[range]w[rite] {file}	Write to {file}, unless it already
+					   exists.
+|:w_f|	  :[range]w[rite]! {file}	Write to {file}.  Overwrite an existing
+					   file.
+|:w_a|	  :[range]w[rite][!] >>		Append to the current file.
+|:w_a|	  :[range]w[rite][!] >> {file}	Append to {file}.
+|:w_c|	  :[range]w[rite] !{cmd}	Execute {cmd} with [range] lines as
+					   standard input.
+|:up|	  :[range]up[date][!]		write to current file if modified
+|:wall|	  :wa[ll][!]			write all changed buffers
+
+|:q|	  :q[uit]		Quit current buffer, unless changes have been
+				   made.  Exit Vim when there are no other
+				   non-help buffers
+|:q|	  :q[uit]!		Quit current buffer always, discard any
+				   changes.  Exit Vim when there are no other
+				   non-help buffers
+|:qa|	  :qa[ll]		Exit Vim, unless changes have been made.
+|:qa|	  :qa[ll]!		Exit Vim always, discard any changes.
+|:cq|	  :cq			Quit without writing and return error code.
+
+|:wq|	  :wq[!]		Write the current file and exit.
+|:wq|	  :wq[!] {file}		Write to {file} and exit.
+|:xit|	  :x[it][!] [file]	Like ":wq" but write only when changes have
+				   been made
+|ZZ|	     ZZ			Same as ":x".
+|ZQ|	     ZQ			Same as ":q!".
+|:xall|	  :xa[ll][!]  or :wqall[!]
+				Write all changed buffers and exit
+
+|:stop|	  :st[op][!]		Suspend VIM or start new shell.  If 'aw' option
+				   is set and [!] not given write the buffer.
+|CTRL-Z|     CTRL-Z		Same as ":stop"
+------------------------------------------------------------------------------
+*Q_ac*		Automatic Commands
+
+|viminfo-file|	Read registers, marks, history at startup, save when exiting.
+
+|:rviminfo|	:rv[iminfo] [file]	Read info from viminfo file [file]
+|:rviminfo|	:rv[iminfo]! [file]	idem, overwrite existing info
+|:wviminfo|	:wv[iminfo] [file]	Add info to viminfo file [file]
+|:wviminfo|	:wv[iminfo]! [file]	Write info to viminfo file [file]
+
+|modeline|	Automatic option setting when editing a file
+
+|modeline|	vim:{set-arg}: ..	In the first and last lines of the
+					file (see 'ml' option), {set-arg} is
+					given as an argument to ":set"
+
+|autocommand|	Automatic execution of commands on certain events.
+
+|:autocmd|	:au			List all autocommands
+|:autocmd|	:au {event}		List all autocommands for {event}
+|:autocmd|	:au {event} {pat}	List all autocommands for {event} with
+					{pat}
+|:autocmd|	:au {event} {pat} {cmd}	Enter new autocommands for {event}
+					with {pat}
+|:autocmd|	:au!			Remove all autocommands
+|:autocmd|	:au! {event}		Remove all autocommands for {event}
+|:autocmd|	:au! * {pat}		Remove all autocommands for {pat}
+|:autocmd|	:au! {event} {pat}	Remove all autocommands for {event}
+					with {pat}
+|:autocmd|	:au! {event} {pat} {cmd}  Remove all autocommands for {event}
+					with {pat} and enter new one
+------------------------------------------------------------------------------
+*Q_wi*		Multi-window commands
+
+|CTRL-W_s|	CTRL-W s  or  :split	Split window into two parts
+|:split_f|	:split {file}		Split window and edit {file} in one of
+					   them
+|:vsplit|	:vsplit {file}		Same, but split vertically
+|:vertical|	:vertical {cmd}		Make {cmd} split vertically
+
+|:sfind|	:sf[ind] {file}		Split window, find {file} in 'path'
+					   and edit it.
+|CTRL-W_]|	CTRL-W ]		Split window and jump to tag under
+					   cursor
+|CTRL-W_f|	CTRL-W f		Split window and edit file name under
+					   the cursor
+|CTRL-W_^|	CTRL-W ^		Split window and edit alternate file
+|CTRL-W_n|	CTRL-W n  or  :new	Create new empty window
+|CTRL-W_q|	CTRL-W q  or  :q[uit]	Quit editing and close window
+|CTRL-W_c|	CTRL-W c  or  :cl[ose]	Make buffer hidden and close window
+|CTRL-W_o|	CTRL-W o  or  :on[ly]	Make current window only one on the
+					   screen
+
+|CTRL-W_j|	CTRL-W j		Move cursor to window below
+|CTRL-W_k|	CTRL-W k		Move cursor to window above
+|CTRL-W_CTRL-W|	CTRL-W CTRL-W		Move cursor to window below (wrap)
+|CTRL-W_W|	CTRL-W W		Move cursor to window above (wrap)
+|CTRL-W_t|	CTRL-W t		Move cursor to top window
+|CTRL-W_b|	CTRL-W b		Move cursor to bottom window
+|CTRL-W_p|	CTRL-W p		Move cursor to previous active window
+
+|CTRL-W_r|	CTRL-W r		Rotate windows downwards
+|CTRL-W_R|	CTRL-W R		Rotate windows upwards
+|CTRL-W_x|	CTRL-W x		Exchange current window with next one
+
+|CTRL-W_=|	CTRL-W =		Make all windows equal height
+|CTRL-W_-|	CTRL-W -		Decrease current window height
+|CTRL-W_+|	CTRL-W +		Increase current window height
+|CTRL-W__|	CTRL-W _		Set current window height (default:
+					   very high)
+------------------------------------------------------------------------------
+*Q_bu*		Buffer list commands
+
+|:buffers|	:buffers  or  :files	list all known buffer and file names
+
+|:ball|		:ball	  or  :sball	edit all args/buffers
+|:unhide|	:unhide   or  :sunhide	edit all loaded buffers
+
+|:badd|		:badd {fname}		add file name {fname} to the list
+|:bunload|	:bunload[!] [N]		unload buffer [N] from memory
+|:bdelete|	:bdelete[!] [N]		unload buffer [N] and delete it from
+					   the buffer list
+
+	      in current window   in new window	~
+|:buffer|     :[N]buffer [N]	  :[N]sbuffer [N]     to arg/buf N
+|:bnext|      :[N]bnext [N]	  :[N]sbnext [N]      to Nth next arg/buf
+|:bNext|      :[N]bNext [N]	  :[N]sbNext [N]      to Nth previous arg/buf
+|:bprevious|  :[N]bprevious [N]   :[N]sbprevious [N]  to Nth previous arg/buf
+|:bfirst|     :bfirst		  :sbfirst	      to first arg/buf
+|:blast|      :blast		  :sblast	      to last arg/buf
+|:bmodified|  :[N]bmod [N]	  :[N]sbmod [N]	      to Nth modified buf
+------------------------------------------------------------------------------
+*Q_sy*		Syntax Highlighting
+
+|:syn-on|	:syntax on		start using syntax highlighting
+|:syn-off|	:syntax off		stop using syntax highlighting
+
+|:syn-keyword|	:syntax keyword {group-name} {keyword} ..
+					add a syntax keyword item
+|:syn-match|	:syntax match {group-name} {pattern} ...
+					add syntax match item
+|:syn-region|	:syntax region {group-name} {pattern} ...
+					add syntax region item
+|:syn-sync|	:syntax sync [ccomment | lines {N} | ...]
+					tell syntax how to sync
+|:syntax|	:syntax [list]		list current syntax items
+|:syn-clear|	:syntax clear		clear all syntax info
+
+|:highlight|	:highlight clear	clear all highlight info
+|:highlight|	:highlight {group-name} {key}={arg} ..
+					set highlighting for {group-name}
+
+|:filetype|	:filetype on		switch on file type detection, without
+					syntax highlighting
+|:filetype|	:filetype plugin indent on
+					switch on file type detection, with
+					automatic indenting and settings
+------------------------------------------------------------------------------
+*Q_gu*		GUI commands
+
+|:gui|		:gui			UNIX: start the GUI
+|:gui|		:gui {fname} ..		idem, and edit {fname} ..
+
+|:menu|		:menu			list all menus
+|:menu|		:menu {mpath}		list menus starting with {mpath}
+|:menu|		:menu {mpath} {rhs}	add menu {mpath}, giving {lhs}
+|:menu|		:menu {pri} {mpath} {rhs}
+					idem, with priorities {pri}
+|:menu|		:menu ToolBar.{name} {rhs}
+					add toolbar item, giving {lhs}
+|:tmenu|	:tmenu {mpath} {text}	add tooltip to menu {mpath}
+|:unmenu|	:unmenu {mpath}		remove menu {mpath}
+------------------------------------------------------------------------------
+*Q_fo*		Folding
+
+|'foldmethod'|	set foldmethod=manual	manual folding
+		set foldmethod=indent	folding by indent
+		set foldmethod=expr	folding by 'foldexpr'
+		set foldmethod=syntax	folding by syntax regions
+		set foldmethod=marker	folding by 'foldmarkers'
+
+|zf|		zf{motion}		operator: Define a fold manually
+|:fold|		:{range}fold		define a fold for {range} lines
+|zd|		zd			delete one fold under the cursor
+|zD|		zD			delete all folds under the cursor
+
+|zo|		zo			open one fold under the cursor
+|zO|		zO			open all folds under the cursor
+|zc|		zc			close one fold under the cursor
+|zC|		zC			close all folds under the cursor
+
+|zm|		zm			fold more: decrease 'foldlevel'
+|zM|		zM			close all folds: make 'foldlevel' zero
+|zr|		zr			reduce folding: increase 'foldlevel'
+|zR|		zR			open all folds: make 'foldlevel' max.
+
+|zn|		zn			fold none: reset 'foldenable'
+|zN|		zN			fold normal set 'foldenable'
+|zi|		zi			invert 'foldenable'
+
+ vim:tw=78:ts=8:ft=help:norl:
--- /dev/null
+++ b/lib/vimfiles/doc/quotes.txt
@@ -1,0 +1,274 @@
+*quotes.txt*    For Vim version 7.1.  Last change: 2006 Apr 24
+
+
+		  VIM REFERENCE MANUAL    by Bram Moolenaar
+
+
+							*quotes*
+Here are some nice quotes about Vim that I collected from news and mail.
+
+
+vim (vim) noun - Ebullient vitality and energy.  [Latin, accusative of vis,
+strength]  (Dictionary)
+
+Vim is so much better than vi that a great many of my old vi :map's became
+immediately obsolete! (Tony Nugent, Australia)
+
+Coming with a very GUI mindset from Windows, I always thought of people using
+Vi as some kind of outer space alien in human clothes.  Once I tried I really
+got addicted by its power and now I found myself typing Vim keypresses in the
+oddest places! That's why I would like to see Vim embedded in every
+application which deals with text editing.  (Jos� Fonseca)
+
+I was a 12-year emacs user who switched to Vim about a year ago after finally
+giving up on the multiple incompatible versions, flaky contributed packages,
+disorganized keystrokes, etc.  And it was one of the best moves I ever made.
+(Joel Burton)
+
+Although all of the programs were used during the preparation of the new and
+revised material, most of the editing was done with Vim versions 4.5 and 5.0
+under GNU-Linux (Redhat 4.2).  (Arnold Robbins, Israel, author of "Learning
+the Vi editor")
+
+Out of all the open software i've ever seen and used, and i've seen a lot, Vim
+is the best, most useful and highest quality to work with, second only to the
+linux kernel itself.  (Peter Jay Salzman)
+
+It's well worth noting that the _entirety_ of SourceForge was written using
+Vim and its nifty PHP syntax highlighting.  I think the entire SF.net tech
+staff uses Vim and we're all excited to have you aboard! (Tim Perdue)
+
+Vim is one of a select bunch of tools for which I have no substitute.  It is
+a brilliant piece of work! (Biju Chacko)
+
+A previous girlfriend of mine switched to emacs.  Needless to say, the
+relationship went nowhere.  (Geoffrey Mann)
+
+I rarely think about Vim, in the same way that I guess a fish rarely thinks
+about water.  It's the environment in which everything else happens.  I'm a
+fairly busy system administrator working on a lot of different platforms.  Vim
+is the only thing that's consistent across all my systems, and it's just about
+the only thing that doesn't break from time to time.  When a new system comes
+in the door without Vim, I install it right away.  Great to have a tool that's
+the same everywhere, that's completely reliable, so I can ignore it and think
+about other things.  (Pete Schaeffer)
+
+Having recently succeeded in running Vim via telnet through a Nokia
+Communicator, I can now report that it works nicely on a Palm Pilot too.
+(Allan Kelly, Scotland)
+
+You've done a tremendous job with 'VIM', Bram!  The more I use it, the more
+impressed I get (I am an old 'vi' die hard who once started out with early
+versions of 'emacs' in the late 1970's and was relieved by finding 'vi' in the
+first UNIX I came across in 1983).  In my opinion, it's about time 'VIM'
+replace 'emacs' as the standard for top editors.  (Bo Thide', Sweden)
+
+I love and use VIM heavily too.  (Larry Wall)
+
+Vi is like a Ferrari, if you're a beginner, it handles like a bitch, but once
+you get the hang of it, it's small, powerful and FAST! (Unknown)
+VIM is like a new model Ferrari, and sounds like one too - "VIIIIIIMMM!"
+(Stephen Riehm, Germany)
+
+Schon bei Nutzung eines Bruchteils der VIM-Funktionen wird der Benutzer recht
+schnell die Vorzuege dieses Editors kennen- und schaetzenlernen.
+Translated: Even when only using a fraction of VIM-functions, the user will
+quickly get used to and appreciate the advantages of this editor.  (Garry
+Glendown, conclusion of an article on VIM in iX magazine 9/1998)
+
+I've recently acquired the O'Reilly book on VI (it also discusses VIM
+in-depth), and I'm amazed at just how powerful this application is.  (Jeffrey
+Rankin)
+
+This guide was written using the Windows 9.x distribution of GVIM, which is
+quite possibly the greatest thing to come along since God created the naked
+girl.  (Michael DiBernardo)
+
+Boy, I thought I knew almost everything about VIM, but every time I browse the
+online documentation, I hit upon a minor but cool aspect of a VIM feature that
+I didn't know before!  I must say the documentation is one the finest I've
+ever seen in a product -- even better than most commercial products.
+(Gautam Mudunuri)
+
+VIM 4.5 is really a fantastic editor.  It has sooooo many features and more
+importantly, the defaults are so well thought out that you really don't have
+to change anything!!  Words cannot express my amazement and gratitude to the
+creators of VIM.  Keep it up.  (Vikas, USA)
+
+I wonder how long it will be before people will refer to other Vi editors as
+VIM clones?  (Darren Hiebert)
+
+I read about [auto-positioning-in-file-based-on-the-errors-from-make] in one
+of those "Perfect Programmer's Editor" threads and was delighted to discover
+that VIM already supports it.  (Brendan Macmillan, Australia)
+
+I just discovered VIM (5.0) and I'm telling everyone I know about it!
+I tell them VIM stands for VI for the new (M)illenium.  Thanks so much!
+(Matt F. Valentine)
+
+I think from now on "vi" should be called "Vim Imitation", not the other way
+around.  (Rungun Ramanathan)
+
+The Law of VIM:
+For each member b of the possible behaviour space B of program P, there exists
+a finite time t before which at least one user u in the total user space U of
+program P will request b becomes a member of the allowed behaviour space B'
+(B' <= B).
+In other words: Sooner or later everyone wants everything as an option.
+(Negri)
+
+Whenever I move to a new computing platform, the first thing I do is to port
+VIM.  Lately, I am simply stunned by its ease of compilation using the
+configure facility.  (A.M. Sabuncu, Turkey)
+
+The options are really excellent and very powerful.  (Anish Maharaj)
+
+The Spring user-interface designs are in, and word from the boutiques is that
+80x24 text-only mode is back with a *vengeance! Vi editor clone VIM burst onto
+March desk-tops with a dazzling show of pastel syntax highlights for its 5.0
+look.  Strident and customizable, VIM raises eyebrows with its interpretation
+of the classic Vi single-key macro collection.
+http://www.ntk.net/index.cgi?back=archive98/now0327.txt&line=179#l
+
+I just wanted to take this opportunity to let you know that VIM 5 ROCKS!
+Syntax highlighting: how did I survive without it?!  Thank you for creating
+mankind's best editor!  (Mun Johl, USA)
+
+Thanks again for VIM.  I use it every day on Linux.  (Eric Foster-Johnson,
+author of the book "UNIX Programming Tools")
+
+The BEST EDITOR EVER (Stuart Woolford)
+
+I have used most of VIM's fancy features at least once, many frequently, and I
+can honestly say that I couldn't live with anything less anymore.  My
+productivity has easily doubled compared to what it was when I used vi.
+(Sitaram Chamarty)
+
+I luv VIM.  It is incredible.  I'm naming my first-born Vimberly.  (Jose
+Unpingco, USA)
+
+Hint:  "VIM" is "vi improved" - much better! (Sven Guckes, Germany)
+
+I use VIM every day.  I spend more time in VIM than in any other program...
+It's the best vi clone there is.  I think it's great.  (Craig Sanders,
+Australia)
+
+I strongly advise using VIM--its infinite undo/redo saved me much grief.
+(Terry Brown)
+
+Thanks very much for writing what in my opinion is the finest text editor on
+the planet.  If I were to get another cat, I would name it "Vim".
+(Bob Sheehan, USA)
+
+I typed :set all and the screen FILLED up with options.  A whole screen of
+things to be set and unset.  I saw some of my old friends like wrapmargin,
+modelines and showmode, but the screen was FILLED with new friends!   I love
+them all!   I love VIM!   I'm so happy that I've found this editor!  I feel
+like how I once felt when I started using vi after a couple of years of using
+ed.  I never thought I'd forsake my beloved ed, but vi ... oh god, vi was
+great.  And now, VIM.  (Peter Jay Salzman, USA)
+
+I am really happy with such a wonderful software package.  Much better than
+almost any expensive, off the shelf program.  (Jeff Walker)
+
+Whenever I reread the VIM documentation I'm overcome with excitement at the
+power of the editor.  (William Edward Webber, Australia)
+
+Hurrah for VIM!! It is "at your fingertips" like vi, and has the extensions
+that vi sorely needs: highlighting for executing commands on blocks, an easily
+navigable and digestible help screen, and more.  (Paul Pax)
+
+The reason WHY I don't have this amazingly useful macro any more, is that I
+now use VIM - and this is built in!! (Stephen Riehm, Germany)
+
+I am a user of VIM and I love it.  I use it to do all my programming, C,
+C++, HTML what ever.  (Tim Allwine)
+
+I discovered VIM after years of struggling with the original vi, and I just
+can't live without it any more.  (Emmanuel Mogenet, USA)
+
+Emacs has not a bit of chance to survive so long as VIM is around.  Besides,
+it also has the most detailed software documentation I have ever seen---much
+better than most commercial software!  (Leiming Qian)
+
+This version of VIM will just blow people apart when they discover just how
+fantastic it is! (Tony Nugent, Australia)
+
+I took your advice & finally got VIM & I'm really impressed.  Instant convert.
+(Patrick Killelea, USA)
+
+VIM is by far my favorite piece of shareware and I have been particularly
+pleased with version 3.0.  This is really a solid piece of work.  (Robert
+Colon, USA)
+
+VIM is a joy to use, it is so well thought and practical that I wonder why
+anybody would use visual development tools.  VIM is powerful and elegant, it
+looks deceptively simple but is almost as complex as a 747 (especially when I
+look at my growing .vimrc), keep up that wonderful job, VIM is a centerpiece
+of the free software world.  (Louis-David Mitterand, USA)
+
+I cannot believe how great it is to use VIM.  I think the guys at work are
+getting tired of hearing me bragging about it.  Others eyes are lighting up.
+(Rick Croote)
+
+Emacs takes way to much time to start up and run, it is to big and bulky for
+effective use and the interface is more confusing than it is of any help.  VIM
+however is short, it is fast, it is powerful, it has a good interface and it
+is all purpose.  (Paal Ditlefsen Ekran)
+
+From the first time I got VIM3.0, I was very enthusiastic.  It has almost no
+problems.  The swapfile handling and the backup possibilities are robust, also
+the protection against editing one file twice.  It is very compatible to the
+real VI (and that is a MUST, because my brain is trained over years in using
+it).  (Gert van Antwerpen, Holland)
+
+Visual mode in VIM is a very powerful thing! (Tony Nugent, Australia)
+
+I have to say that VIM is =THE= single greatest piece of source code to ever
+come across the net (Jim Battle, USA).
+
+In fact, if you do want to get a new vi I'd suggest VIM-3.0.  This is, by
+far, the best version of vi I've ever seen (Albert W. Schueller).
+
+I should mention that VIM is a very good editor and can compete with anything
+(Ilya Beloozerov).
+
+To tell the truth sometimes I used elvis, vile, xvi, calvin, etc.  And this is
+the reason that I can state that VIM is the best! (Ferenc Deak, Hungary)
+
+VIM is by far the best editor that I have used in a long time, and I have
+looked at just about every thing that is available for every platform that I
+use.  VIM is the best on all of them.  (Guy L. Oliver)
+
+VIM is the greatest editor since the stone chisel.  (Jose Unpingco, USA)
+
+I would like to say that with VIM I am finally making the 'emacs to vi'
+transition - as an Editor it is so much better in many ways: keyboard layout,
+memory usage, text alteration to name 3.  (Mark Adam)
+
+In fact, now if I want to know what a particular setting does in vi, I fire up
+VIM and check out it's help!  (Nikhil Patel, USA)
+
+As a vi user, VIM has made working with text a far more pleasant task than
+before I encountered this program.  (Steinar Knutsen, Norway)
+
+I use VIM since version 3.0.  Since that time, it is the ONLY editor I use,
+with Solaris, Linux and OS/2 Warp.  I suggest all my friends to use VIM, they
+try, and they continue using it.  VIM is really the best software I have ever
+downloaded from the Internet, and the best editor I know of.  (Marco
+Eccettuato, Italy)
+
+
+In summary:
+     __     ___		    _	    _	_  ___ _____
+     \ \   / (_)_ __ ___   (_)___  | | | |/ _ \_   _|
+      \ \ / /| | '_ ` _ \  | / __| | |_| | | | || |
+       \ V / | | | | | | | | \__ \ |  _  | |_| || |
+	\_/  |_|_| |_| |_| |_|___/ |_| |_|\___/ |_|
+	     ____ _____ _   _ _____ _____ _ _
+	    / ___|_   _| | | |	___|  ___| | |
+	    \___ \ | | | | | | |_  | |_  | | |
+	     ___) || | | |_| |	_| |  _| |_|_|
+	    |____/ |_|	\___/|_|   |_|	 (_|_)	      (Tony Nugent, Australia)
+
+ vim:tw=78:ts=8:ft=help:norl:
--- /dev/null
+++ b/lib/vimfiles/doc/recover.txt
@@ -1,0 +1,191 @@
+*recover.txt*   For Vim version 7.1.  Last change: 2006 Apr 24
+
+
+		  VIM REFERENCE MANUAL    by Bram Moolenaar
+
+
+Recovery after a crash					*crash-recovery*
+
+You have spent several hours typing in that text that has to be finished
+next morning, and then disaster strikes: Your computer crashes.
+
+			DON'T PANIC!
+
+You can recover most of your changes from the files that Vim uses to store
+the contents of the file.  Mostly you can recover your work with one command:
+	vim -r filename
+
+1. The swap file	|swap-file|
+2. Recovery		|recovery|
+
+==============================================================================
+1. The swap file					*swap-file*
+
+Vim stores the things you changed in a swap file.  Using the original file
+you started from plus the swap file you can mostly recover your work.
+
+You can see the name of the current swap file being used with the command:
+
+	:sw[apname]					*:sw* *:swapname*
+
+The name of the swap file is normally the same as the file you are editing,
+with the extension ".swp".
+- On Unix, a '.' is prepended to swap file names in the same directory as the
+  edited file.  This avoids that the swap file shows up in a directory
+  listing.
+- On MS-DOS machines and when the 'shortname' option is on, any '.' in the
+  original file name is replaced with '_'.
+- If this file already exists (e.g., when you are recovering from a crash) a
+  warning is given and another extension is used, ".swo", ".swn", etc.
+- An existing file will never be overwritten.
+- The swap file is deleted as soon as Vim stops editing the file.
+
+Technical: The replacement of '.' with '_' is done to avoid problems with
+	   MS-DOS compatible filesystems (e.g., crossdos, multidos).  If Vim
+	   is able to detect that the file is on an MS-DOS-like filesystem, a
+	   flag is set that has the same effect as the 'shortname' option.
+	   This flag is reset when you start editing another file.
+							*E326*
+	   If the ".swp" file name already exists, the last character is
+	   decremented until there is no file with that name or ".saa" is
+	   reached.  In the last case, no swap file is created.
+
+By setting the 'directory' option you can place the swap file in another place
+than where the edited file is.
+Advantages:
+- You will not pollute the directories with ".swp" files.
+- When the 'directory' is on another partition, reduce the risk of damaging
+  the file system where the file is (in a crash).
+Disadvantages:
+- You can get name collisions from files with the same name but in different
+  directories (although Vim tries to avoid that by comparing the path name).
+  This will result in bogus ATTENTION warning messages.
+- When you use your home directory, and somebody else tries to edit the same
+  file, he will not see your swap file and will not get the ATTENTION warning
+  message.
+On the Amiga you can also use a recoverable ram disk, but there is no 100%
+guarantee that this works.  Putting swap files in a normal ram disk (like RAM:
+on the Amiga) or in a place that is cleared when rebooting (like /tmp on Unix)
+makes no sense, you will lose the swap file in a crash.
+
+If you want to put swap files in a fixed place, put a command resembling the
+following ones in your .vimrc:
+	:set dir=dh2:tmp	(for Amiga)
+	:set dir=~/tmp		(for Unix)
+	:set dir=c:\\tmp	(for MS-DOS and Win32)
+This is also very handy when editing files on floppy.  Of course you will have
+to create that "tmp" directory for this to work!
+
+For read-only files, a swap file is not used.  Unless the file is big, causing
+the amount of memory used to be higher than given with 'maxmem' or
+'maxmemtot'.  And when making a change to a read-only file, the swap file is
+created anyway.
+
+The 'swapfile' option can be reset to avoid creating a swapfile.
+
+
+Detecting an existing swap file ~
+
+You can find this in the user manual, section |11.3|.
+
+
+Updating the swapfile ~
+
+The swap file is updated after typing 200 characters or when you have not
+typed anything for four seconds.  This only happens if the buffer was
+changed, not when you only moved around.  The reason why it is not kept up to
+date all the time is that this would slow down normal work too much.  You can
+change the 200 character count with the 'updatecount' option.  You can set
+the time with the 'updatetime' option.  The time is given in milliseconds.
+After writing to the swap file Vim syncs the file to disk.  This takes some
+time, especially on busy Unix systems.  If you don't want this you can set the
+'swapsync' option to an empty string.  The risk of losing work becomes bigger
+though.  On some non-Unix systems (MS-DOS, Amiga) the swap file won't be
+written at all.
+
+If the writing to the swap file is not wanted, it can be switched off by
+setting the 'updatecount' option to 0.  The same is done when starting Vim
+with the "-n" option.  Writing can be switched back on by setting the
+'updatecount' option to non-zero.  Swap files will be created for all buffers
+when doing this.  But when setting 'updatecount' to zero, the existing swap
+files will not be removed, it will only affect files that will be opened
+after this.
+
+If you want to make sure that your changes are in the swap file use this
+command:
+
+					*:pre* *:preserve* *E313* *E314*
+:pre[serve]		Write all text for all buffers into swap file.  The
+			original file is no longer needed for recovery.
+			This sets a flag in the current buffer.  When the '&'
+			flag is present in 'cpoptions' the swap file will not
+			be deleted for this buffer when Vim exits and the
+			buffer is still loaded |cpo-&|.
+			{Vi: might also exit}
+
+A Vim swap file can be recognized by the first six characters: "b0VIM ".
+After that comes the version number, e.g., "3.0".
+
+
+Links and symbolic links ~
+
+On Unix it is possible to have two names for the same file.  This can be done
+with hard links and with symbolic links (symlinks).
+
+For hard links Vim does not know the other name of the file.  Therefore, the
+name of the swapfile will be based on the name you used to edit the file.
+There is no check for editing the same file by the other name too, because Vim
+cannot find the other swapfile (except for searching all of your harddisk,
+which would be very slow).
+
+For symbolic links Vim resolves the links to find the name of the actual file.
+The swap file name is based on that name.  Thus it doesn't matter by what name
+you edit the file, the swap file name will normally be the same.  However,
+there are exceptions:
+- When the directory of the actual file is not writable the swapfile is put
+  elsewhere.
+- When the symbolic links somehow create a loop you get an *E773* error
+  message and the unmodified file name will be used.  You won't be able to
+  save your file normally.
+
+==============================================================================
+2. Recovery					*recovery* *E308* *E311*
+
+Basic file recovery is explained in the user manual: |usr_11.txt|.
+
+Another way to do recovery is to start Vim and use the ":recover" command.
+This is easy when you start Vim to edit a file and you get the "ATTENTION:
+Found a swap file ..." message.  In this case the single command ":recover"
+will do the work.  You can also give the name of the file or the swap file to
+the recover command:
+					*:rec* *:recover* *E305* *E306* *E307*
+:rec[over] [file]	Try to recover [file] from the swap file.  If [file]
+			is not given use the file name for the current
+			buffer.  The current contents of the buffer are lost.
+			This command fails if the buffer was modified.
+
+:rec[over]! [file]	Like ":recover", but any changes in the current
+			buffer are lost.
+
+							*E312* *E309* *E310*
+Vim has some intelligence about what to do if the swap file is corrupt in
+some way.  If Vim has doubt about what it found, it will give an error
+message and insert lines with "???" in the text.  If you see an error message
+while recovering, search in the file for "???" to see what is wrong.  You may
+want to cut and paste to get the text you need.
+
+The most common remark is "???LINES MISSING".  This means that Vim cannot read
+the text from the original file.  This can happen if the system crashed and
+parts of the original file were not written to disk.
+
+Be sure that the recovery was successful before overwriting the original
+file or deleting the swap file.  It is good practice to write the recovered
+file elsewhere and run 'diff' to find out if the changes you want are in the
+recovered file.
+
+Once you are sure the recovery is ok delete the swap file.  Otherwise, you
+will continue to get warning messages that the ".swp" file already exists.
+
+{Vi: recovers in another way and sends mail if there is something to recover}
+
+ vim:tw=78:ts=8:ft=help:norl:
--- /dev/null
+++ b/lib/vimfiles/doc/remote.txt
@@ -1,0 +1,201 @@
+*remote.txt*    For Vim version 7.1.  Last change: 2006 Apr 30
+
+
+		  VIM REFERENCE MANUAL    by Bram Moolenaar
+
+
+Vim client-server communication				*client-server*
+
+1. Common functionality		|clientserver|
+2. X11 specific items		|x11-clientserver|
+3. MS-Windows specific items	|w32-clientserver|
+
+{Vi does not have any of these commands}
+
+==============================================================================
+1. Common functionality					*clientserver*
+
+When compiled with the |+clientserver| option, Vim can act as a command
+server.  It accepts messages from a client and executes them.  At the same
+time, Vim can function as a client and send commands to a Vim server.
+
+The following command line arguments are available:
+
+    argument			meaning	~
+
+   --remote [+{cmd}] {file} ...					*--remote*
+				Open the file list in a remote Vim.  When
+				there is no Vim server, execute locally.
+				There is one optional init command: +{cmd}.
+				This must be an Ex command that can be
+				followed by "|".
+				The rest of the command line is taken as the
+				file list.  Thus any non-file arguments must
+				come before this.
+				You cannot edit stdin this way |--|.
+				The remote Vim is raised.  If you don't want
+				this use >
+				 vim --remote-send "<C-\><C-N>:n filename<CR>"
+<  --remote-silent [+{cmd}] {file} ...			*--remote-silent*
+				As above, but don't complain if there is no
+				server and the file is edited locally.
+   --remote-wait [+{cmd}] {file} ...				*--remote-wait*
+				As --remote, but wait for files to complete
+				(unload) in remote Vim.
+   --remote-wait-silent [+{cmd}] {file} ...		*--remote-wait-silent*
+				As --remote-wait, but don't complain if there
+				is no server.
+							*--remote-tab*
+   --remote-tab			Like --remote but open each file in a new
+				tabpage.
+							*--remote-tab-silent*
+   --remote-tab-silent		Like --remote-silent but open each file in a
+				new tabpage.
+							*--remote-tab-wait*
+   --remote-tab-wait		Like --remote-wait but open each file in a new
+				tabpage.
+
+						*--remote-tab-wait-silent*
+   --remote-tab-wait-silent	Like --remote-wait-silent but open each file
+				in a new tabpage.
+								*--servername*
+   --servername {name}		Become the server {name}.  When used together
+				with one of the --remote commands: connect to
+				server {name} instead of the default (see
+				below).
+								*--remote-send*
+   --remote-send {keys}		Send {keys} to server and exit.
+								*--remote-expr*
+   --remote-expr {expr}		Evaluate {expr} in server and print the result
+				on stdout.
+								*--serverlist*
+   --serverlist			Output a list of server names.
+
+
+Examples ~
+
+Edit "file.txt" in an already running GVIM server: >
+    gvim --remote file.txt
+
+Edit "file.txt" in an already running server called FOOBAR: >
+    gvim --servername FOOBAR --remote file.txt
+
+Edit "file.txt" in server "FILES" if it exists, become server "FILES"
+otherwise: >
+    gvim --servername FILES --remote-silent file.txt
+
+This doesn't work, all arguments after --remote will be used as file names: >
+    gvim --remote --servername FOOBAR file.txt
+
+Edit file "+foo" in a remote server (note the use of "./" to avoid the special
+meaning of the leading plus): >
+    vim --remote ./+foo
+
+Tell the remote server "BLA" to write all files and exit: >
+    vim --servername BLA --remote-send '<C-\><C-N>:wqa<CR>'
+
+
+SERVER NAME
+
+By default Vim will try to register the name under which it was invoked (gvim,
+egvim ...).  This can be overridden with the --servername argument.  If the
+specified name is not available, a postfix is applied until a free name is
+encountered, i.e. "gvim1" for the second invocation of gvim on a particular
+X-server.  The resulting name is available in the servername builtin variable
+|v:servername|.  The case of the server name is ignored, thus "gvim" and
+"GVIM" are considered equal.
+
+When Vim is invoked with --remote, --remote-wait or --remote-send it will try
+to locate the server name determined by the invocation name and --servername
+argument as described above.  If an exact match is not available, the first
+server with the number postfix will be used.  If a name with the number
+postfix is specified with the --servername argument, it must match exactly.
+
+If no server can be located and --remote or --remote-wait was used, Vim will
+start up according to the rest of the command line and do the editing by
+itself.  This way it is not necessary to know whether gvim is already started
+when sending command to it.
+
+The --serverlist argument will cause Vim to print a list of registered command
+servers on the standard output (stdout) and exit.
+
+Win32 Note: Making the Vim server go to the foreground doesn't always work,
+because MS-Windows doesn't allow it.  The client will move the server to the
+foreground when using the --remote or --remote-wait argument and the server
+name starts with "g".
+
+
+REMOTE EDITING
+
+The --remote argument will cause a |:drop| command to be constructed from the
+rest of the command line and sent as described above.
+The --remote-wait argument does the same thing and additionally sets up to
+wait for each of the files to have been edited.  This uses the BufUnload
+event, thus as soon as a file has been unloaded, Vim assumes you are done
+editing it.
+Note that the --remote and --remote-wait arguments will consume the rest of
+the command line.  I.e. all remaining arguments will be regarded as filenames.
+You can not put options there!
+
+
+FUNCTIONS
+								*E240* *E573*
+There are a number of Vim functions for scripting the command server.  See
+the description in |eval.txt| or use CTRL-] on the function name to jump to
+the full explanation.
+
+    synopsis				     explanation ~
+    remote_expr( server, string, idvar)      send expression
+    remote_send( server, string, idvar)      send key sequence
+    serverlist()			     get a list of available servers
+    remote_peek( serverid, retvar)	     check for reply string
+    remote_read( serverid)		     read reply string
+    server2client( serverid, string)	     send reply string
+    remote_foreground( server)		     bring server to the front
+
+See also the explanation of |CTRL-\_CTRL-N|.  Very useful as a leading key
+sequence.
+The {serverid} for server2client() can be obtained with expand("<client>")
+
+==============================================================================
+2. X11 specific items					*x11-clientserver*
+				    *E247* *E248* *E251* *E258* *E277*
+
+The communication between client and server goes through the X server.  The
+display of the Vim server must be specified.  The usual protection of the X
+server is used, you must be able to open a window on the X server for the
+communication to work.  It is possible to communicate between different
+systems.
+
+By default, a GUI Vim will register a name on the X-server by which it can be
+addressed for subsequent execution of injected strings.  Vim can also act as
+a client and send strings to other instances of Vim on the same X11 display.
+
+When an X11 GUI Vim (gvim) is started, it will try to register a send-server
+name on the 'VimRegistry' property on the root window.
+
+A non GUI Vim with access to the X11 display (|xterm-clipboard| enabled), can
+also act as a command server if a server name is explicitly given with the
+--servername argument.
+
+An empty --servername argument will cause the command server to be disabled.
+
+To send commands to a Vim server from another application, read the source
+file src/if_xcmdsrv.c, it contains some hints about the protocol used.
+
+==============================================================================
+3. Win32 specific items					*w32-clientserver*
+
+Every Win32 Vim can work as a server, also in the console.  You do not need a
+version compiled with OLE.  Windows messages are used, this works on any
+version of MS-Windows.  But only communication within one system is possible.
+
+Since MS-Windows messages are used, any other application should be able to
+communicate with a Vim server.  An alternative is using the OLE functionality
+|ole-interface|.
+
+When using gvim, the --remote-wait only works properly this way: >
+
+	start /w gvim --remote-wait file.txt
+<
+ vim:tw=78:sw=4:ts=8:ft=help:norl:
--- /dev/null
+++ b/lib/vimfiles/doc/repeat.txt
@@ -1,0 +1,669 @@
+*repeat.txt*    For Vim version 7.1.  Last change: 2007 Jan 07
+
+
+		  VIM REFERENCE MANUAL    by Bram Moolenaar
+
+
+Repeating commands, Vim scripts and debugging			*repeating*
+
+Chapter 26 of the user manual introduces repeating |usr_26.txt|.
+
+1. Single repeats	|single-repeat|
+2. Multiple repeats	|multi-repeat|
+3. Complex repeats	|complex-repeat|
+4. Using Vim scripts	|using-scripts|
+5. Debugging scripts	|debug-scripts|
+6. Profiling		|profiling|
+
+==============================================================================
+1. Single repeats					*single-repeat*
+
+							*.*
+.			Repeat last change, with count replaced with [count].
+			Also repeat a yank command, when the 'y' flag is
+			included in 'cpoptions'.  Does not repeat a
+			command-line command.
+
+Simple changes can be repeated with the "." command.  Without a count, the
+count of the last change is used.  If you enter a count, it will replace the
+last one.  If the last change included a specification of a numbered register,
+the register number will be incremented.  See |redo-register| for an example
+how to use this.  Note that when repeating a command that used a Visual
+selection, the same SIZE of area is used, see |visual-repeat|.
+
+							*@:*
+@:			Repeat last command-line [count] times.
+			{not available when compiled without the
+			|+cmdline_hist| feature}
+
+
+==============================================================================
+2. Multiple repeats					*multi-repeat*
+
+						*:g* *:global* *E147* *E148*
+:[range]g[lobal]/{pattern}/[cmd]
+			Execute the Ex command [cmd] (default ":p") on the
+			lines within [range] where {pattern} matches.
+
+:[range]g[lobal]!/{pattern}/[cmd]
+			Execute the Ex command [cmd] (default ":p") on the
+			lines within [range] where {pattern} does NOT match.
+
+							*:v* *:vglobal*
+:[range]v[global]/{pattern}/[cmd]
+			Same as :g!.
+
+Instead of the '/' which surrounds the {pattern}, you can use any other
+single byte character, but not an alphanumeric character, '\', '"' or '|'.
+This is useful if you want to include a '/' in the search pattern or
+replacement string.
+
+For the definition of a pattern, see |pattern|.
+
+The global commands work by first scanning through the [range] lines and
+marking each line where a match occurs (for a multi-line pattern, only the
+start of the match matters).
+In a second scan the [cmd] is executed for each marked line with its line
+number prepended.  For ":v" and ":g!" the command is executed for each not
+marked line.  If a line is deleted its mark disappears.
+The default for [range] is the whole buffer (1,$).  Use "CTRL-C" to interrupt
+the command.  If an error message is given for a line, the command for that
+line is aborted and the global command continues with the next marked or
+unmarked line.
+
+To repeat a non-Ex command, you can use the ":normal" command: >
+	:g/pat/normal {commands}
+Make sure that {commands} ends with a whole command, otherwise Vim will wait
+for you to type the rest of the command for each match.  The screen will not
+have been updated, so you don't know what you are doing.  See |:normal|.
+
+The undo/redo command will undo/redo the whole global command at once.
+The previous context mark will only be set once (with "''" you go back to
+where the cursor was before the global command).
+
+The global command sets both the last used search pattern and the last used
+substitute pattern (this is vi compatible).  This makes it easy to globally
+replace a string:
+	:g/pat/s//PAT/g
+This replaces all occurrences of "pat" with "PAT".  The same can be done with:
+	:%s/pat/PAT/g
+Which is two characters shorter!
+
+A special case is using ":visual" as a command.  This will move to a matching
+line, go to Normal mode to let you execute commands there until you use |Q| to
+return to Ex mode.  This will be repeated for each matching line.  While doing
+this you cannot use ":global".
+
+==============================================================================
+3. Complex repeats					*complex-repeat*
+
+							*q* *recording*
+q{0-9a-zA-Z"}		Record typed characters into register {0-9a-zA-Z"}
+			(uppercase to append).  The 'q' command is disabled
+			while executing a register, and it doesn't work inside
+			a mapping.  {Vi: no recording}
+
+q			Stops recording.  (Implementation note: The 'q' that
+			stops recording is not stored in the register, unless
+			it was the result of a mapping)  {Vi: no recording}
+
+							*@*
+@{0-9a-z".=*}		Execute the contents of register {0-9a-z".=*} [count]
+			times.  Note that register '%' (name of the current
+			file) and '#' (name of the alternate file) cannot be
+			used.  For "@=" you are prompted to enter an
+			expression.  The result of the expression is then
+			executed.  See also |@:|.  {Vi: only named registers}
+
+							*@@* *E748*
+@@			Repeat the previous @{0-9a-z":*} [count] times.
+
+:[addr]*{0-9a-z".=}						*:@* *:star*
+:[addr]@{0-9a-z".=*}	Execute the contents of register {0-9a-z".=*} as an Ex
+			command.  First set cursor at line [addr] (default is
+			current line).  When the last line in the register does
+			not have a <CR> it will be added automatically when
+			the 'e' flag is present in 'cpoptions'.
+			Note that the ":*" command is only recognized when the
+			'*' flag is present in 'cpoptions'.  This is NOT the
+			default when 'nocompatible' is used.
+			For ":@=" the last used expression is used.  The
+			result of evaluating the expression is executed as an
+			Ex command.
+			Mappings are not recognized in these commands.
+			{Vi: only in some versions} Future: Will execute the
+			register for each line in the address range.
+
+							*:@:*
+:[addr]@:		Repeat last command-line.  First set cursor at line
+			[addr] (default is current line).  {not in Vi}
+
+							*:@@*
+:[addr]@@		Repeat the previous :@{0-9a-z"}.  First set cursor at
+			line [addr] (default is current line).  {Vi: only in
+			some versions}
+
+==============================================================================
+4. Using Vim scripts					*using-scripts*
+
+For writing a Vim script, see chapter 41 of the user manual |usr_41.txt|.
+
+					*:so* *:source* *load-vim-script*
+:so[urce] {file}	Read Ex commands from {file}.  These are commands that
+			start with a ":".
+			Triggers the |SourcePre| autocommand.
+
+:so[urce]! {file}	Read Vim commands from {file}.  These are commands
+			that are executed from Normal mode, like you type
+			them.
+			When used after |:global|, |:argdo|, |:windo|,
+			|:bufdo|, in a loop or when another command follows
+			the display won't be updated while executing the
+			commands.
+			{not in Vi}
+
+							*:ru* *:runtime*
+:ru[ntime][!] {file} ..
+			Read Ex commands from {file} in each directory given
+			by 'runtimepath'.  There is no error for non-existing
+			files.  Example: >
+				:runtime syntax/c.vim
+
+<			There can be multiple {file} arguments, separated by
+			spaces.  Each {file} is searched for in the first
+			directory from 'runtimepath', then in the second
+			directory, etc.  Use a backslash to include a space
+			inside {file} (although it's better not to use spaces
+			in file names, it causes trouble).
+
+			When [!] is included, all found files are sourced.
+			When it is not included only the first found file is
+			sourced.
+
+			When {file} contains wildcards it is expanded to all
+			matching files.  Example: >
+				:runtime! plugin/*.vim
+<			This is what Vim uses to load the plugin files when
+			starting up.  This similar command: >
+				:runtime plugin/*.vim
+<			would source the first file only.
+
+			When 'verbose' is one or higher, there is a message
+			when no file could be found.
+			When 'verbose' is two or higher, there is a message
+			about each searched file.
+			{not in Vi}
+
+:scripte[ncoding] [encoding]		*:scripte* *:scriptencoding* *E167*
+			Specify the character encoding used in the script.
+			The following lines will be converted from [encoding]
+			to the value of the 'encoding' option, if they are
+			different.  Examples: >
+				scriptencoding iso-8859-5
+				scriptencoding cp932
+<
+			When [encoding] is empty, no conversion is done.  This
+			can be used to restrict conversion to a sequence of
+			lines: >
+				scriptencoding euc-jp
+				... lines to be converted ...
+				scriptencoding
+				... not converted ...
+
+<			When conversion isn't supported by the system, there
+			is no error message and no conversion is done.
+
+			Don't use "ucs-2" or "ucs-4", scripts cannot be in
+			these encodings (they would contain NUL bytes).
+			When a sourced script starts with a BOM (Byte Order
+			Mark) in utf-8 format Vim will recognized it, no need
+			to use ":scriptencoding utf-8" then.
+
+			When compiled without the |+multi_byte| feature this
+			command is ignored.
+			{not in Vi}
+
+						*:scrip* *:scriptnames*
+:scrip[tnames]		List all sourced script names, in the order they were
+			first sourced.  The number is used for the script ID
+			|<SID>|.
+			{not in Vi} {not available when compiled without the
+			|+eval| feature}
+
+						*:fini* *:finish* *E168*
+:fini[sh]		Stop sourcing a script.  Can only be used in a Vim
+			script file.  This is a quick way to skip the rest of
+			the file.  If it is used after a |:try| but before the
+			matching |:finally| (if present), the commands
+			following the ":finally" up to the matching |:endtry|
+			are executed first.  This process applies to all
+			nested ":try"s in the script.  The outermost ":endtry"
+			then stops sourcing the script.  {not in Vi}
+
+All commands and command sequences can be repeated by putting them in a named
+register and then executing it.  There are two ways to get the commands in the
+register:
+- Use the record command "q".  You type the commands once, and while they are
+  being executed they are stored in a register.  Easy, because you can see
+  what you are doing.  If you make a mistake, "p"ut the register into the
+  file, edit the command sequence, and then delete it into the register
+  again.  You can continue recording by appending to the register (use an
+  uppercase letter).
+- Delete or yank the command sequence into the register.
+
+Often used command sequences can be put under a function key with the ':map'
+command.
+
+An alternative is to put the commands in a file, and execute them with the
+':source!' command.  Useful for long command sequences.  Can be combined with
+the ':map' command to put complicated commands under a function key.
+
+The ':source' command reads Ex commands from a file line by line.  You will
+have to type any needed keyboard input.  The ':source!' command reads from a
+script file character by character, interpreting each character as if you
+typed it.
+
+Example: When you give the ":!ls" command you get the |hit-enter| prompt.  If
+you ':source' a file with the line "!ls" in it, you will have to type the
+<Enter> yourself.  But if you ':source!' a file with the line ":!ls" in it,
+the next characters from that file are read until a <CR> is found.  You will
+not have to type <CR> yourself, unless ":!ls" was the last line in the file.
+
+It is possible to put ':source[!]' commands in the script file, so you can
+make a top-down hierarchy of script files.  The ':source' command can be
+nested as deep as the number of files that can be opened at one time (about
+15).  The ':source!' command can be nested up to 15 levels deep.
+
+You can use the "<sfile>" string (literally, this is not a special key) inside
+of the sourced file, in places where a file name is expected.  It will be
+replaced by the file name of the sourced file.  For example, if you have a
+"other.vimrc" file in the same directory as your ".vimrc" file, you can source
+it from your ".vimrc" file with this command: >
+	:source <sfile>:h/other.vimrc
+
+In script files terminal-dependent key codes are represented by
+terminal-independent two character codes.  This means that they can be used
+in the same way on different kinds of terminals.  The first character of a
+key code is 0x80 or 128, shown on the screen as "~@".  The second one can be
+found in the list |key-notation|.  Any of these codes can also be entered
+with CTRL-V followed by the three digit decimal code.  This does NOT work for
+the <t_xx> termcap codes, these can only be used in mappings.
+
+							*:source_crnl* *W15*
+MS-DOS, Win32 and OS/2: Files that are read with ":source" normally have
+<CR><NL> <EOL>s.  These always work.  If you are using a file with <NL> <EOL>s
+(for example, a file made on Unix), this will be recognized if 'fileformats'
+is not empty and the first line does not end in a <CR>.  This fails if the
+first line has something like ":map <F1> :help^M", where "^M" is a <CR>.  If
+the first line ends in a <CR>, but following ones don't, you will get an error
+message, because the <CR> from the first lines will be lost.
+
+Mac Classic: Files that are read with ":source" normally have <CR> <EOL>s.
+These always work.  If you are using a file with <NL> <EOL>s (for example, a
+file made on Unix), this will be recognized if 'fileformats' is not empty and
+the first line does not end in a <CR>.  Be careful not to use a file with <NL>
+linebreaks which has a <CR> in first line.
+
+On other systems, Vim expects ":source"ed files to end in a <NL>.  These
+always work.  If you are using a file with <CR><NL> <EOL>s (for example, a
+file made on MS-DOS), all lines will have a trailing <CR>.  This may cause
+problems for some commands (e.g., mappings).  There is no automatic <EOL>
+detection, because it's common to start with a line that defines a mapping
+that ends in a <CR>, which will confuse the automaton.
+
+							*line-continuation*
+Long lines in a ":source"d Ex command script file can be split by inserting
+a line continuation symbol "\" (backslash) at the start of the next line.
+There can be white space before the backslash, which is ignored.
+
+Example: the lines >
+	:set comments=sr:/*,mb:*,el:*/,
+		     \://,
+		     \b:#,
+		     \:%,
+		     \n:>,
+		     \fb:-
+are interpreted as if they were given in one line:
+	:set comments=sr:/*,mb:*,el:*/,://,b:#,:%,n:>,fb:-
+
+All leading whitespace characters in the line before a backslash are ignored.
+Note however that trailing whitespace in the line before it cannot be
+inserted freely; it depends on the position where a command is split up
+whether additional whitespace is allowed or not.
+
+There is a problem with the ":append" and ":insert" commands: >
+   :1append
+   \asdf
+   .
+The backslash is seen as a line-continuation symbol, thus this results in the
+command: >
+   :1appendasdf
+   .
+To avoid this, add the 'C' flag to the 'cpoptions' option: >
+   :set cpo+=C
+   :1append
+   \asdf
+   .
+   :set cpo-=C
+
+Note that when the commands are inside a function, you need to add the 'C'
+flag when defining the function, it is not relevant when executing it. >
+   :set cpo+=C
+   :function Foo()
+   :1append
+   \asdf
+   .
+   :endfunction
+   :set cpo-=C
+
+Rationale:
+	Most programs work with a trailing backslash to indicate line
+	continuation.  Using this in Vim would cause incompatibility with Vi.
+	For example for this Vi mapping: >
+		:map xx  asdf\
+<	Therefore the unusual leading backslash is used.
+
+==============================================================================
+5. Debugging scripts					*debug-scripts*
+
+Besides the obvious messages that you can add to your scripts to find out what
+they are doing, Vim offers a debug mode.  This allows you to step through a
+sourced file or user function and set breakpoints.
+
+NOTE: The debugging mode is far from perfect.  Debugging will have side
+effects on how Vim works.  You cannot use it to debug everything.  For
+example, the display is messed up by the debugging messages.
+{Vi does not have a debug mode}
+
+An alternative to debug mode is setting the 'verbose' option.  With a bigger
+number it will give more verbose messages about what Vim is doing.
+
+
+STARTING DEBUG MODE						*debug-mode*
+
+To enter debugging mode use one of these methods:
+1. Start Vim with the |-D| argument: >
+	vim -D file.txt
+<  Debugging will start as soon as the first vimrc file is sourced.  This is
+   useful to find out what is happening when Vim is starting up.  A side
+   effect is that Vim will switch the terminal mode before initialisations
+   have finished, with unpredictable results.
+   For a GUI-only version (Windows, Macintosh) the debugging will start as
+   soon as the GUI window has been opened.  To make this happen early, add a
+   ":gui" command in the vimrc file.
+								*:debug*
+2. Run a command with ":debug" prepended.  Debugging will only be done while
+   this command executes.  Useful for debugging a specific script or user
+   function.  And for scripts and functions used by autocommands.  Example: >
+	:debug edit test.txt.gz
+
+3. Set a breakpoint in a sourced file or user function.  You could do this in
+   the command line: >
+	vim -c "breakadd file */explorer.vim" .
+<  This will run Vim and stop in the first line of the "explorer.vim" script.
+   Breakpoints can also be set while in debugging mode.
+
+In debugging mode every executed command is displayed before it is executed.
+Comment lines, empty lines and lines that are not executed are skipped.  When
+a line contains two commands, separated by "|", each command will be displayed
+separately.
+
+
+DEBUG MODE
+
+Once in debugging mode, the usual Ex commands can be used.  For example, to
+inspect the value of a variable: >
+	echo idx
+When inside a user function, this will print the value of the local variable
+"idx".  Prepend "g:" to get the value of a global variable: >
+	echo g:idx
+All commands are executed in the context of the current function or script.
+You can also set options, for example setting or resetting 'verbose' will show
+what happens, but you might want to set it just before executing the lines you
+are interested in: >
+	:set verbose=20
+
+Commands that require updating the screen should be avoided, because their
+effect won't be noticed until after leaving debug mode.  For example: >
+	:help
+won't be very helpful.
+
+There is a separate command-line history for debug mode.
+
+The line number for a function line is relative to the start of the function.
+If you have trouble figuring out where you are, edit the file that defines
+the function in another Vim, search for the start of the function and do
+"99j".  Replace "99" with the line number.
+
+Additionally, these commands can be used:
+							*>cont*
+	cont		Continue execution until the next breakpoint is hit.
+							*>quit*
+	quit		Abort execution.  This is like using CTRL-C, some
+			things might still be executed, doesn't abort
+			everything.  Still stops at the next breakpoint.
+							*>next*
+	next		Execute the command and come back to debug mode when
+			it's finished.  This steps over user function calls
+			and sourced files.
+							*>step*
+	step		Execute the command and come back to debug mode for
+			the next command.  This steps into called user
+			functions and sourced files.
+							*>interrupt*
+	interrupt	This is like using CTRL-C, but unlike ">quit" comes
+			back to debug mode for the next command that is
+			executed.  Useful for testing |:finally| and |:catch|
+			on interrupt exceptions.
+							*>finish*
+	finish		Finish the current script or user function and come
+			back to debug mode for the command after the one that
+			sourced or called it.
+
+About the additional commands in debug mode:
+- There is no command-line completion for them, you get the completion for the
+  normal Ex commands only.
+- You can shorten them, up to a single character: "c", "n", "s" and "f".
+- Hitting <CR> will repeat the previous one.  When doing another command, this
+  is reset (because it's not clear what you want to repeat).
+- When you want to use the Ex command with the same name, prepend a colon:
+  ":cont", ":next", ":finish" (or shorter).
+
+
+DEFINING BREAKPOINTS
+							*:breaka* *:breakadd*
+:breaka[dd] func [lnum] {name}
+		Set a breakpoint in a function.  Example: >
+			:breakadd func Explore
+<		Doesn't check for a valid function name, thus the breakpoint
+		can be set before the function is defined.
+
+:breaka[dd] file [lnum] {name}
+		Set a breakpoint in a sourced file.  Example: >
+			:breakadd file 43 .vimrc
+
+:breaka[dd] here
+		Set a breakpoint in the current line of the current file.
+		Like doing: >
+			:breakadd file <cursor-line> <current-file>
+<		Note that this only works for commands that are executed when
+		sourcing the file, not for a function defined in that file.
+
+The [lnum] is the line number of the breakpoint.  Vim will stop at or after
+this line.  When omitted line 1 is used.
+
+							*:debug-name*
+{name} is a pattern that is matched with the file or function name.  The
+pattern is like what is used for autocommands.  There must be a full match (as
+if the pattern starts with "^" and ends in "$").  A "*" matches any sequence
+of characters.  'ignorecase' is not used, but "\c" can be used in the pattern
+to ignore case |/\c|.  Don't include the () for the function name!
+
+The match for sourced scripts is done against the full file name.  If no path
+is specified the current directory is used.  Examples: >
+	breakadd file explorer.vim
+matches "explorer.vim" in the current directory. >
+	breakadd file *explorer.vim
+matches ".../plugin/explorer.vim", ".../plugin/iexplorer.vim", etc. >
+	breakadd file */explorer.vim
+matches ".../plugin/explorer.vim" and "explorer.vim" in any other directory.
+
+The match for functions is done against the name as it's shown in the output
+of ":function".  For local functions this means that something like "<SNR>99_"
+is prepended.
+
+Note that functions are first loaded and later executed.  When they are loaded
+the "file" breakpoints are checked, when they are executed the "func"
+breakpoints.
+
+
+DELETING BREAKPOINTS
+						*:breakd* *:breakdel* *E161*
+:breakd[el] {nr}
+		Delete breakpoint {nr}.  Use |:breaklist| to see the number of
+		each breakpoint.
+
+:breakd[el] *
+		Delete all breakpoints.
+
+:breakd[el] func [lnum] {name}
+		Delete a breakpoint in a function.
+
+:breakd[el] file [lnum] {name}
+		Delete a breakpoint in a sourced file.
+
+:breakd[el] here
+		Delete a breakpoint at the current line of the current file.
+
+When [lnum] is omitted, the first breakpoint in the function or file is
+deleted.
+The {name} must be exactly the same as what was typed for the ":breakadd"
+command.  "explorer", "*explorer.vim" and "*explorer*" are different.
+
+
+LISTING BREAKPOINTS
+							*:breakl* *:breaklist*
+:breakl[ist]
+		List all breakpoints.
+
+
+OBSCURE
+
+						*:debugg* *:debuggreedy*
+:debugg[reedy]
+		Read debug mode commands from the normal input stream, instead
+		of getting them directly from the user.  Only useful for test
+		scripts.  Example: >
+		  echo 'q^Mq' | vim -e -s -c debuggreedy -c 'breakadd file script.vim' -S script.vim
+
+:0debugg[reedy]
+		Undo ":debuggreedy": get debug mode commands directly from the
+		user, don't use typeahead for debug commands.
+
+==============================================================================
+6. Profiling						*profile* *profiling*
+
+Profiling means that Vim measures the time that is spend on executing
+functions and/or scripts.  The |+profile| feature is required for this.
+It is only included when Vim was compiled with "huge" features.
+{Vi does not have profiling}
+
+You can also use the |reltime()| function to measure time.  This only requires
+the |+reltime| feature, which is present more often.
+
+:prof[ile] start {fname}			*:prof* *:profile* *E750*
+		Start profiling, write the output in {fname} upon exit.
+		If {fname} already exists it will be silently overwritten.
+		The variable |v:profiling| is set to one.
+
+:prof[ile] pause
+		Don't profile until the following ":profile continue".  Can be
+		used when doing something that should not be counted (e.g., an
+		external command).  Does not nest.
+
+:prof[ile] continue
+		Continue profiling after ":profile pause".
+
+:prof[ile] func {pattern}
+		Profile function that matches the pattern {pattern}.
+		See |:debug-name| for how {pattern} is used.
+
+:prof[ile][!] file {pattern}
+		Profile script file that matches the pattern {pattern}.
+		See |:debug-name| for how {pattern} is used.
+		This only profiles the script itself, not the functions
+		defined in it.
+		When the [!] is added then all functions defined in the script
+		will also be profiled.  But only if the script is loaded after
+		this command.
+
+
+:profd[el] ...						*:profd* *:profdel*
+		Stop profiling for the arguments specified. See |:breakdel|
+		for the arguments.
+
+
+You must always start with a ":profile start fname" command.  The resulting
+file is written when Vim exits.  Here is an example of the output, with line
+numbers prepended for the explanation:
+
+  1 FUNCTION  Test2() ~
+  2 Called 1 time ~
+  3 Total time:   0.155251 ~
+  4  Self time:   0.002006 ~
+  5  ~
+  6 count  total (s)   self (s) ~
+  7	9	       0.000096   for i in range(8) ~
+  8	8   0.153655   0.000410     call Test3() ~
+  9	8	       0.000070   endfor ~
+ 10				  " Ask a question ~
+ 11	1	       0.001341   echo input("give me an answer: ") ~
+
+The header (lines 1-4) gives the time for the whole function.  The "Total"
+time is the time passed while the function was executing.  The "Self" time is
+the "Total" time reduced by time spent in:
+- other user defined functions
+- sourced scripts
+- executed autocommands
+- external (shell) commands
+
+Lines 7-11 show the time spent in each executed line.  Lines that are not
+executed do not count.  Thus a comment line is never counted.
+
+The Count column shows how many times a line was executed.  Note that the
+"for" command in line 7 is executed one more time as the following lines.
+That is because the line is also executed to detect the end of the loop.
+
+The time Vim spends waiting for user input isn't counted at all.  Thus how
+long you take to respond to the input() prompt is irrelevant.
+
+Profiling should give a good indication of where time is spent, but keep in
+mind there are various things that may clobber the results:
+
+- The accuracy of the time measured depends on the gettimeofday() system
+  function.  It may only be as accurate as 1/100 second, even though the times
+  are displayed in micro seconds.
+
+- Real elapsed time is measured, if other processes are busy they may cause
+  delays at unpredictable moments.  You may want to run the profiling several
+  times and use the lowest results.
+
+- If you have several commands in one line you only get one time.  Split the
+  line to see the time for the individual commands.
+
+- The time of the lines added up is mostly less than the time of the whole
+  function.  There is some overhead in between.
+
+- Functions that are deleted before Vim exits will not produce profiling
+  information.  You can check the |v:profiling| variable if needed: >
+	:if !v:profiling
+	:   delfunc MyFunc
+	:endif
+<
+- Profiling may give weird results on multi-processor systems, when sleep
+  mode kicks in or the processor frequency is reduced to save power.
+
+- The "self" time is wrong when a function is used recursively.
+
+
+ vim:tw=78:ts=8:ft=help:norl:
--- /dev/null
+++ b/lib/vimfiles/doc/rileft.txt
@@ -1,0 +1,125 @@
+*rileft.txt*    For Vim version 7.1.  Last change: 2006 Apr 24
+
+
+		  VIM REFERENCE MANUAL    by Avner Lottem
+					  updated by Nadim Shaikli
+
+
+Right to Left display mode for Vim				*rileft*
+
+
+These functions were originally created by Avner Lottem:
+   E-mail: alottem@iil.intel.com
+   Phone:  +972-4-8307322
+
+{Vi does not have any of these commands}
+
+								*E26*
+This feature is only available when the |+rightleft| feature was enabled
+at compile time.
+
+
+Introduction
+------------
+Some languages such as Arabic, Farsi, Hebrew (among others) require the
+ability to display their text from right-to-left.  Files in those languages
+are stored conventionally and the right-to-left requirement is only a
+function of the display engine (per the Unicode specification).  In
+right-to-left oriented files the characters appear on the screen from
+right to left.
+
+Bidirectionality (or bidi for short) is what Unicode offers as a full
+solution to these languages.  Bidi offers the user the ability to view
+both right-to-left as well as left-to-right text properly at the same time
+within the same window.  Vim currently, due to simplicity, does not offer
+bidi and is merely opting to present a functional means to display/enter/use
+right-to-left languages.  An older hybrid solution in which direction is
+encoded for every character (or group of characters) are not supported either
+as this kind of support is out of the scope of a simple addition to an
+existing editor (and it's not sanctioned by Unicode either).
+
+
+Highlights
+----------
+o  Editing left-to-right files as in the original Vim, no change.
+
+o  Viewing and editing files in right-to-left windows.  File orientation
+   is per window, so it is possible to view the same file in right-to-left
+   and left-to-right modes, simultaneously.  (Useful for editing mixed files
+   in which both right-to-left and left-to-right text exist).
+
+o  Compatibility to the original Vim.  Almost all features work in
+   right-to-left mode (see Bugs below).
+
+o  Backing from reverse insert mode to the correct place in the file
+   (if possible).
+
+o  No special terminal with right-to-left capabilities is required.  The
+   right-to-left changes are completely hardware independent.
+
+o  Many languages use and require right-to-left support.  These languages
+   can quite easily be supported given the inclusion of their required
+   keyboard mappings and some possible minor code change.  Some of the
+   current supported languages include - |arabic.txt|, |farsi.txt| and
+   |hebrew.txt|.
+
+
+Of Interest...
+--------------
+
+o  Invocations
+   -----------
+   + 'rightleft' ('rl') sets window orientation to right-to-left.
+   + 'delcombine' ('deco'), boolean, if editing UTF-8 encoded languages,
+     allows one to remove a composing character which gets superimposed
+     on those that proceeded them (some languages require this).
+   + 'rightleftcmd' ('rlc') sets the command-line within certain modes
+     (such as search) to be utilized in right-to-left orientation as well.
+
+o  Typing backwards					*ins-reverse*
+   ----------------
+   In lieu of using full-fledged the 'rightleft' option, one can opt for
+   reverse insertion.  When the 'revins' (reverse insert) option is set,
+   inserting happens backwards.  This can be used to type right-to-left
+   text.  When inserting characters the cursor is not moved and the text
+   moves rightwards.  A <BS> deletes the character under the cursor.
+   CTRL-W and CTRL-U also work in the opposite direction.  <BS>, CTRL-W
+   and CTRL-U do not stop at the start of insert or end of line, no matter
+   how the 'backspace' option is set.
+
+   There is no reverse replace mode (yet).
+
+   If the 'showmode' option is set, "-- REVERSE INSERT --" will be shown
+   in the status line when reverse Insert mode is active.
+
+o  Pasting when in a rightleft window
+   ----------------------------------
+   When cutting text with the mouse and pasting it in a rightleft window
+   the text will be reversed, because the characters come from the cut buffer
+   from the left to the right, while inserted in the file from the right to
+   the left.   In order to avoid it, toggle 'revins' before pasting.
+
+
+Bugs
+----
+o  Does not handle CTRL-A and CTRL-X commands (add and subtract) correctly
+   when in rightleft window.
+
+o  Does not support reverse insert and rightleft modes on the command-line.
+   However, functionality of the editor is not reduced, because it is
+   possible to enter mappings, abbreviations and searches typed from the
+   left to the right on the command-line.
+
+o  Somewhat slower in right-to-left mode, because right-to-left motion is
+   emulated inside Vim, not by the controlling terminal.
+
+o  When the Athena GUI is used, the bottom scrollbar works in the wrong
+   direction.  This is difficult to fix.
+
+o  When both 'rightleft' and 'revins' are on: 'textwidth' does not work.
+   Lines do not wrap at all; you just get a single, long line.
+
+o  There is no full bidirectionality (bidi) support.
+
+
+ vim:tw=78:ts=8:ft=help:norl:
--- /dev/null
+++ b/lib/vimfiles/doc/russian.txt
@@ -1,0 +1,74 @@
+*russian.txt*   For Vim version 7.1.  Last change: 2006 Apr 24
+
+
+		  VIM REFERENCE MANUAL    by Vassily Ragosin
+
+
+Russian language localization and support in Vim	   *russian* *Russian*
+
+1. Introduction				  |russian-intro|
+2. Russian keymaps			  |russian-keymap|
+3. Localization				  |russian-l18n|
+4. Known issues				  |russian-issues|
+
+===============================================================================
+1. Introduction							*russian-intro*
+
+Russian language is supported perfectly well in Vim.  You can type and view
+Russian text just as any other, without the need to tweak the settings.
+
+===============================================================================
+2. Russian keymaps					       *russian-keymap*
+
+To switch between languages you can use your system native keyboard switcher,
+or use one of the Russian keymaps, included in the Vim distribution.  For
+example,
+>
+    :set keymap=russian-jcukenwin
+<
+In the latter case, you can switch between languages even if you do not have
+system Russian keyboard or independently from a system-wide keyboard settings.
+See 'keymap'.  You can also map a key to switch between keyboards, if you
+choose the latter option.  See |:map|.
+
+For your convenience, to avoid switching between keyboards, when you need to
+enter Normal mode command, you can also set 'langmap' option:
+>
+    :set langmap=ФИСВУАПРШОЛДЬТЩЗЙКЫЕГМЦЧНЯ;ABCDEFGHIJKLMNOPQRSTUVWXYZ,
+    фисвуапршолдьтщзйкыегмцчня;abcdefghijklmnopqrstuvwxyz
+
+This is in utf-8, you cannot read this if your 'encoding' is not utf-8.
+You have to type this command in one line, it is wrapped for the sake of
+readability.
+
+===============================================================================
+3. Localization							 *russian-l18n*
+
+If you wish to use messages, help files, menus and other items translated to
+Russian, you will need to install the RuVim Language Pack, available in
+different codepages from
+
+    http://www.sourceforge.net/projects/ruvim/
+
+Make sure that your Vim is at least 6.2.506 and use ruvim 0.5 or later for
+automatic installs.  Vim also needs to be compiled with |+gettext| feature for
+user interface items translations to work.
+
+After downloading an archive from RuVim project, unpack it into your
+$VIMRUNTIME directory.  We recommend using UTF-8 archive, if your version of
+Vim is compiled with |+multi_byte| feature enabled.
+
+In order to use the Russian documentation, make sure you have set the
+'helplang' option to "ru".
+
+===============================================================================
+4. Known issues						       *russian-issues*
+
+-- If you are using Russian message translations in Win32 console, then
+   you may see the output produced by "vim --help", "vim --version" commands
+   and Win32 console window title appearing in a wrong codepage.  This problem
+   is related to a bug in GNU gettext library and may be fixed in the future
+   releases of gettext.
+
+===============================================================================
+ vim:tw=78:ts=8:ft=help:norl:
--- /dev/null
+++ b/lib/vimfiles/doc/scroll.txt
@@ -1,0 +1,315 @@
+*scroll.txt*    For Vim version 7.1.  Last change: 2006 Aug 27
+
+
+		  VIM REFERENCE MANUAL    by Bram Moolenaar
+
+
+Scrolling						*scrolling*
+
+These commands move the contents of the window.  If the cursor position is
+moved off of the window, the cursor is moved onto the window (with
+'scrolloff' screen lines around it).  A page is the number of lines in the
+window minus two.  The mnemonics for these commands may be a bit confusing.
+Remember that the commands refer to moving the window (the part of the buffer
+that you see) upwards or downwards in the buffer.  When the window moves
+upwards in the buffer, the text in the window moves downwards on your screen.
+
+See section |03.7| of the user manual for an introduction.
+
+1. Scrolling downwards		|scroll-down|
+2. Scrolling upwards		|scroll-up|
+3. Scrolling relative to cursor	|scroll-cursor|
+4. Scrolling horizontally	|scroll-horizontal|
+5. Scrolling synchronously	|scroll-binding|
+6. Scrolling with a mouse wheel |scroll-mouse-wheel|
+
+==============================================================================
+1. Scrolling downwards					*scroll-down*
+
+The following commands move the edit window (the part of the buffer that you
+see) downwards (this means that more lines downwards in the text buffer can be
+seen):
+
+							*CTRL-E*
+CTRL-E			Scroll window [count] lines downwards in the buffer.
+			Mnemonic: Extra lines.
+
+							*CTRL-D*
+CTRL-D			Scroll window Downwards in the buffer.  The number of
+			lines comes from the 'scroll' option (default: half a
+			screen).  If [count] given, first set 'scroll' option
+			to [count].  The cursor is moved the same number of
+			lines down in the file (if possible; when lines wrap
+			and when hitting the end of the file there may be a
+			difference).  When the cursor is on the last line of
+			the buffer nothing happens and a beep is produced.
+			See also 'startofline' option.
+			{difference from vi: Vim scrolls 'scroll' screen
+			lines, instead of file lines; makes a difference when
+			lines wrap}
+
+<S-Down>	or				*<S-Down>* *<kPageDown>*
+<PageDown>	or				*<PageDown>* *CTRL-F*
+CTRL-F			Scroll window [count] pages Forwards (downwards) in
+			the buffer.  See also 'startofline' option.
+			When there is only one window the 'window' option
+			might be used.
+
+							*z+*
+z+			Without [count]: Redraw with the line just below the
+			window at the top of the window.  Put the cursor in
+			that line, at the first non-blank in the line.
+			With [count]: just like "z<CR>".
+
+==============================================================================
+2. Scrolling upwards					*scroll-up*
+
+The following commands move the edit window (the part of the buffer that you
+see) upwards (this means that more lines upwards in the text buffer can be
+seen):
+
+							*CTRL-Y*
+CTRL-Y			Scroll window [count] lines upwards in the buffer.
+			Note: When using the MS-Windows key bindings CTRL-Y is
+			remapped to redo.
+
+							*CTRL-U*
+CTRL-U			Scroll window Upwards in the buffer.  The number of
+			lines comes from the 'scroll' option (default: half a
+			screen).  If [count] given, first set the 'scroll'
+			option to [count].  The cursor is moved the same
+			number of lines up in the file (if possible; when
+			lines wrap and when hitting the end of the file there
+			may be a difference).  When the cursor is on the first
+			line of the buffer nothing happens and a beep is
+			produced.  See also 'startofline' option.
+			{difference from vi: Vim scrolls 'scroll' screen
+			lines, instead of file lines; makes a difference when
+			lines wrap}
+
+<S-Up>		or					*<S-Up>* *<kPageUp>*
+<PageUp>	or					*<PageUp>* *CTRL-B*
+CTRL-B			Scroll window [count] pages Backwards (upwards) in the
+			buffer.  See also 'startofline' option.
+			When there is only one window the 'window' option
+			might be used.
+
+							*z^*
+z^			Without [count]: Redraw with the line just above the
+			window at the bottom of the window.  Put the cursor in
+			that line, at the first non-blank in the line.
+			With [count]: First scroll the text to put the [count]
+			line at the bottom of the window, then redraw with the
+			line which is now at the top of the window at the
+			bottom of the window.  Put the cursor in that line, at
+			the first non-blank in the line.
+
+==============================================================================
+3. Scrolling relative to cursor				*scroll-cursor*
+
+The following commands reposition the edit window (the part of the buffer that
+you see) while keeping the cursor on the same line:
+
+							*z<CR>*
+z<CR>			Redraw, line [count] at top of window (default
+			cursor line).  Put cursor at first non-blank in the
+			line.
+
+							*zt*
+zt			Like "z<CR>", but leave the cursor in the same
+			column.  {not in Vi}
+
+							*zN<CR>*
+z{height}<CR>		Redraw, make window {height} lines tall.  This is
+			useful to make the number of lines small when screen
+			updating is very slow.  Cannot make the height more
+			than the physical screen height.
+
+							*z.*
+z.			Redraw, line [count] at center of window (default
+			cursor line).  Put cursor at first non-blank in the
+			line.
+
+							*zz*
+zz			Like "z.", but leave the cursor in the same column.
+			Careful: If caps-lock is on, this commands becomes
+			"ZZ": write buffer and exit!  {not in Vi}
+
+							*z-*
+z-			Redraw, line [count] at bottom of window (default
+			cursor line).  Put cursor at first non-blank in the
+			line.
+
+							*zb*
+zb			Like "z-", but leave the cursor in the same column.
+			{not in Vi}
+
+==============================================================================
+4. Scrolling horizontally				*scroll-horizontal*
+
+For the following four commands the cursor follows the screen.  If the
+character that the cursor is on is moved off the screen, the cursor is moved
+to the closest character that is on the screen.  The value of 'sidescroll' is
+not used.
+
+z<Right>    or						*zl* *z<Right>*
+zl			Move the view on the text [count] characters to the
+			right, thus scroll the text [count] characters to the
+			left.  This only works when 'wrap' is off.  {not in
+			Vi}
+
+z<Left>      or						*zh* *z<Left>*
+zh			Move the view on the text [count] characters to the
+			left, thus scroll the text [count] characters to the
+			right.  This only works when 'wrap' is off.  {not in
+			Vi}
+
+							*zL*
+zL			Move the view on the text half a screenwidth to the
+			right, thus scroll the text half a screenwidth to the
+			left.  This only works when 'wrap' is off.  {not in
+			Vi}
+
+							*zH*
+zH			Move the view on the text half a screenwidth to the
+			left, thus scroll the text half a screenwidth to the
+			right.  This only works when 'wrap' is off.  {not in
+			Vi}
+
+For the following two commands the cursor is not moved in the text, only the
+text scrolls on the screen.
+
+							*zs*
+zs			Scroll the text horizontally to position the cursor
+			at the start (left side) of the screen.  This only
+			works when 'wrap' is off.  {not in Vi}
+
+							*ze*
+ze			Scroll the text horizontally to position the cursor
+			at the end (right side) of the screen.  This only
+			works when 'wrap' is off.  {not in Vi}
+
+==============================================================================
+5. Scrolling synchronously				*scroll-binding*
+
+Occasionally, it is desirable to bind two or more windows together such that
+when one window is scrolled, the other windows are scrolled also.  In Vim,
+windows can be given this behavior by setting the (window-specific)
+'scrollbind' option.  When a window that has 'scrollbind' set is scrolled, all
+other 'scrollbind' windows are scrolled the same amount, if possible.  The
+behavior of 'scrollbind' can be modified by the 'scrollopt' option.
+
+When using the scrollbars, the binding only happens when scrolling the window
+with focus (where the cursor is).  You can use this to avoid scroll-binding
+for a moment without resetting options.
+
+When a window also has the 'diff' option set, the scroll-binding uses the
+differences between the two buffers to synchronize the position precisely.
+Otherwise the following method is used.
+
+							*scrollbind-relative*
+Each 'scrollbind' window keeps track of its "relative offset," which can be
+thought of as the difference between the current window's vertical scroll
+position and the other window's vertical scroll position.  When one of the
+'scrollbind' windows is asked to vertically scroll past the beginning or end
+limit of its text, the window no longer scrolls, but remembers how far past
+the limit it wishes to be.  The window keeps this information so that it can
+maintain the same relative offset, regardless of its being asked to scroll
+past its buffer's limits.
+
+However, if a 'scrollbind' window that has a relative offset that is past its
+buffer's limits is given the cursor focus, the other 'scrollbind' windows must
+jump to a location where the current window's relative offset is valid.  This
+behavior can be changed by clearing the 'jump' flag from the 'scrollopt'
+option.
+
+						*syncbind* *:syncbind* *:sync*
+:syncbind		Force all 'scrollbind' windows to have the same
+			relative offset.  I.e., when any of the 'scrollbind'
+			windows is scrolled to the top of its buffer, all of
+			the 'scrollbind' windows will also be at the top of
+			their buffers.
+
+							*scrollbind-quickadj*
+The 'scrollbind' flag is meaningful when using keyboard commands to vertically
+scroll a window, and also meaningful when using the vertical scrollbar of the
+window which has the cursor focus.  However, when using the vertical scrollbar
+of a window which doesn't have the cursor focus, 'scrollbind' is ignored.
+This allows quick adjustment of the relative offset of 'scrollbind' windows.
+
+==============================================================================
+6. Scrolling with a mouse wheel				*scroll-mouse-wheel*
+
+When your mouse has a scroll wheel, it should work with Vim in the GUI.  How
+it works depends on your system.  It might also work in an xterm
+|xterm-mouse-wheel|.
+
+For the Win32 GUI the scroll action is hard coded.  It works just like
+dragging the scrollbar of the current window.  How many lines are scrolled
+depends on your mouse driver.  If the scroll action causes input focus
+problems, see |intellimouse-wheel-problems|.
+
+For the X11 GUIs (Motif, Athena and GTK) scrolling the wheel generates key
+presses <MouseDown> and <MouseUp>.  The default action for these keys are:
+    <MouseDown>		scroll three lines down.	*<MouseDown>*
+    <S-MouseDown>	scroll a full page down.	*<S-MouseDown>*
+    <C-MouseDown>	scroll a full page down.	*<C-MouseDown>*
+    <MouseUp>		scroll three lines up.		*<MouseUp>*
+    <S-MouseUp>		scroll a full page up.		*<S-MouseUp>*
+    <C-MouseUp>		scroll a full page up.		*<C-MouseUp>*
+This should work in all modes, except when editing the command line.
+
+Note that <MouseDown> is used for scrolling the text down, this happens when
+you turn the mouse wheel up!
+
+You can modify this behavior by mapping the keys.  For example, to make the
+scroll wheel move one line or half a page in Normal mode: >
+   :map <MouseDown> <C-Y>
+   :map <S-MouseDown> <C-U>
+   :map <MouseUp> <C-E>
+   :map <S-MouseUp> <C-D>
+You can also use Alt and Ctrl modifiers.
+
+This only works when Vim gets the scroll wheel events, of course.  You can
+check if this works with the "xev" program.
+
+When using XFree86, the /etc/XF86Config file should have the correct entry for
+your mouse.  For FreeBSD, this entry works for a Logitech scrollmouse: >
+    Protocol     "MouseMan"
+    Device       "/dev/psm0"
+    ZAxisMapping 4 5
+See the XFree86 documentation for information.
+
+							*xterm-mouse-wheel*
+To use the mouse wheel in a new xterm you only have to make the scroll wheel
+work in your Xserver, as mentioned above.
+
+To use the mouse wheel in an older xterm you must do this:
+1. Make it work in your Xserver, as mentioned above.
+2. Add translations for the xterm, so that the xterm will pass a scroll event
+   to Vim as an escape sequence.
+3. Add mappings in Vim, to interpret the escape sequences as <MouseUp> or
+   <MouseDown> keys.
+
+You can do the translations by adding this to your ~.Xdefaults file (or other
+file where your X resources are kept): >
+
+  XTerm*VT100.Translations:		#override \n\
+		s<Btn4Down>: string("0x9b") string("[64~") \n\
+		s<Btn5Down>: string("0x9b") string("[65~") \n\
+		<Btn4Down>: string("0x9b") string("[62~") \n\
+		<Btn5Down>: string("0x9b") string("[63~") \n\
+		<Btn4Up>: \n\
+		<Btn5Up>:
+
+Add these mappings to your vimrc file: >
+	:map <M-Esc>[62~ <MouseDown>
+	:map! <M-Esc>[62~ <MouseDown>
+	:map <M-Esc>[63~ <MouseUp>
+	:map! <M-Esc>[63~ <MouseUp>
+	:map <M-Esc>[64~ <S-MouseDown>
+	:map! <M-Esc>[64~ <S-MouseDown>
+	:map <M-Esc>[65~ <S-MouseUp>
+	:map! <M-Esc>[65~ <S-MouseUp>
+<
+ vim:tw=78:ts=8:ft=help:norl:
--- /dev/null
+++ b/lib/vimfiles/doc/sign.txt
@@ -1,0 +1,191 @@
+*sign.txt*      For Vim version 7.1.  Last change: 2006 Apr 24
+
+
+		  VIM REFERENCE MANUAL    by Gordon Prieur
+					  and Bram Moolenaar
+
+
+Sign Support Features				*sign-support*
+
+1. Introduction				|sign-intro|
+2. Commands				|sign-commands|
+
+{Vi does not have any of these features}
+{only available when compiled with the |+signs| feature}
+
+==============================================================================
+1. Introduction					*sign-intro* *signs*
+
+When a debugger or other IDE tool is driving an editor it needs to be able
+to give specific highlights which quickly tell the user useful information
+about the file.  One example of this would be a debugger which had an icon
+in the left-hand column denoting a breakpoint.  Another example might be an
+arrow representing the Program Counter (PC).  The sign features allow both
+placement of a sign, or icon, in the left-hand side of the window and
+definition of a highlight which will be applied to that line.  Displaying the
+sign as an image is most likely only feasible in gvim (although Sun
+Microsystem's dtterm does support this it's the only terminal emulator I know
+of which does).  A text sign and the highlight should be feasible in any color
+terminal emulator.
+
+Signs and highlights are not useful just for debuggers.  Sun's Visual
+WorkShop uses signs and highlights to mark build errors and SourceBrowser
+hits.  Additionally, the debugger supports 8 to 10 different signs and
+highlight colors. |workshop|  Same for Netbeans |netbeans|.
+
+There are two steps in using signs:
+
+1. Define the sign.  This specifies the image, text and highlighting.  For
+   example, you can define a "break" sign with an image of a stop roadsign and
+   text "!!".
+
+2. Place the sign.  This specifies the file and line number where the sign is
+   displayed.  A defined sign can be placed several times in different lines
+   and files.
+
+When signs are defined for a file, Vim will automatically add a column of two
+characters to display them in.  When the last sign is unplaced the column
+disappears again.  The color of the column is set with the SignColumn group
+|hl-SignColumn|.  Example to set the color: >
+
+	:highlight SignColumn guibg=darkgrey
+
+==============================================================================
+2. Commands					*sign-commands* *:sig* *:sign*
+
+Here is an example that places a sign piet, displayed with the text ">>", in
+line 23 of the current file: >
+	:sign define piet text=>> texthl=Search
+	:exe ":sign place 2 line=23 name=piet file=" . expand("%:p")
+
+And here is the command to delete it again: >
+	:sign unplace 2
+
+Note that the ":sign" command cannot be followed by another command or a
+comment.  If you do need that, use the |:execute| command.
+
+
+DEFINING A SIGN.			*:sign-define* *E255* *E160* *E612*
+
+:sign define {name} {argument}...
+		Define a new sign or set attributes for an existing sign.
+		The {name} can either be a number (all digits) or a name
+		starting with a non-digit.
+		About 120 different signs can be defined.
+
+		Accepted arguments:
+
+	icon={pixmap}
+		Define the file name where the bitmap can be found.  Should be
+		a full path.  The bitmap should fit in the place of two
+		characters.  This is not checked.  If the bitmap is too big it
+		will cause redraw problems.  Only GTK 2 can scale the bitmap
+		to fit the space available.
+			toolkit		supports ~
+			GTK 1		pixmap (.xpm)
+			GTK 2		many
+			Motif		pixmap (.xpm)
+
+	linehl={group}
+		Highlighting group used for the whole line the sign is placed
+		in.  Most useful is defining a background color.
+
+	text={text}						*E239*
+		Define the text that is displayed when there is no icon or the
+		GUI is not being used.  Only printable characters are allowed
+		and they must occupy one or two display cells.
+
+	texthl={group}
+		Highlighting group used for the text item.
+
+
+DELETING A SIGN						*:sign-undefine* *E155*
+
+:sign undefine {name}
+		Deletes a previously defined sign.  If signs with this {name}
+		are still placed this will cause trouble.
+
+
+LISTING SIGNS						*:sign-list* *E156*
+
+:sign list	Lists all defined signs and their attributes.
+
+:sign list {name}
+		Lists one defined sign and its attributes.
+
+
+PLACING SIGNS						*:sign-place* *E158*
+
+:sign place {id} line={lnum} name={name} file={fname}
+		Place sign defined as {name} at line {lnum} in file {fname}.
+							*:sign-fname*
+		The file {fname} must already be loaded in a buffer.  The
+		exact file name must be used, wildcards, $ENV and ~ are not
+		expanded, white space must not be escaped.  Trailing white
+		space is ignored.
+
+		The sign is remembered under {id}, this can be used for
+		further manipulation.  {id} must be a number.
+		It's up to the user to make sure the {id} is used only once in
+		each file (if it's used several times unplacing will also have
+		to be done several times and making changes may not work as
+		expected).
+
+:sign place {id} line={lnum} name={name} buffer={nr}
+		Same, but use buffer {nr}.
+
+:sign place {id} name={name} file={fname}
+		Change the placed sign {id} in file {fname} to use the defined
+		sign {name}.  See remark above about {fname} |:sign-fname|.
+		This can be used to change the displayed sign without moving
+		it (e.g., when the debugger has stopped at a breakpoint).
+
+:sign place {id} name={name} buffer={nr}
+		Same, but use buffer {nr}.
+
+
+REMOVING SIGNS						*:sign-unplace* *E159*
+
+:sign unplace {id} file={fname}
+		Remove the previously placed sign {id} from file {fname}.
+		See remark above about {fname} |:sign-fname|.
+
+:sign unplace {id} buffer={nr}
+		Same, but use buffer {nr}.
+
+:sign unplace {id}
+		Remove the previously placed sign {id} from all files it
+		appears in.
+
+:sign unplace *
+		Remove all placed signs.
+
+:sign unplace
+		Remove the placed sign at the cursor position.
+
+
+LISTING PLACED SIGNS
+
+:sign place file={fname}
+		List signs placed in file {fname}.
+		See remark above about {fname} |:sign-fname|.
+
+:sign place buffer={nr}
+		List signs placed in buffer {nr}.
+
+:sign place	List placed signs in all files.
+
+
+JUMPING TO A SIGN					*:sign-jump* *E157*
+
+:sign jump {id} file={fname}
+		Open the file {fname} or jump to the window that contains
+		{fname} and position the cursor at sign {id}.
+		See remark above about {fname} |:sign-fname|.
+		If the file isn't displayed in window and the current file can
+		not be |abandon|ed this fails.
+
+:sign jump {id} buffer={nr}
+		Same, but use buffer {nr}.
+
+ vim:tw=78:ts=8:ft=help:norl:
--- /dev/null
+++ b/lib/vimfiles/doc/spell.txt
@@ -1,0 +1,1579 @@
+*spell.txt*	For Vim version 7.1.  Last change: 2007 May 07
+
+
+		  VIM REFERENCE MANUAL	  by Bram Moolenaar
+
+
+Spell checking						*spell*
+
+1. Quick start			|spell-quickstart|
+2. Remarks on spell checking	|spell-remarks|
+3. Generating a spell file	|spell-mkspell|
+4. Spell file format		|spell-file-format|
+
+{Vi does not have any of these commands}
+
+Spell checking is not available when the |+syntax| feature has been disabled
+at compile time.
+
+Note: There also is a vimspell plugin.  If you have it you can do ":help
+vimspell" to find about it.  But you will probably want to get rid of the
+plugin and use the 'spell' option instead, it works better.
+
+==============================================================================
+1. Quick start						*spell-quickstart*
+
+This command switches on spell checking: >
+
+	:setlocal spell spelllang=en_us
+
+This switches on the 'spell' option and specifies to check for US English.
+
+The words that are not recognized are highlighted with one of these:
+	SpellBad	word not recognized			|hl-SpellBad|
+	SpellCap	word not capitalised			|hl-SpellCap|
+	SpellRare	rare word				|hl-SpellRare|
+	SpellLocal	wrong spelling for selected region	|hl-SpellLocal|
+
+Vim only checks words for spelling, there is no grammar check.
+
+If the 'mousemodel' option is set to "popup" and the cursor is on a badly
+spelled word or it is "popup_setpos" and the mouse pointer is on a badly
+spelled word, then the popup menu will contain a submenu to replace the bad
+word.  Note: this slows down the appearance of the popup menu.  Note for GTK:
+don't release the right mouse button until the menu appears, otherwise it
+won't work.
+
+To search for the next misspelled word:
+
+							*]s* *E756*
+]s			Move to next misspelled word after the cursor.
+			A count before the command can be used to repeat.
+			'wrapscan' applies.
+
+							*[s*
+[s			Like "]s" but search backwards, find the misspelled
+			word before the cursor.  Doesn't recognize words
+			split over two lines, thus may stop at words that are
+			not highlighted as bad.  Does not stop at word with
+			missing capital at the start of a line.
+
+							*]S*
+]S			Like "]s" but only stop at bad words, not at rare
+			words or words for another region.
+
+							*[S*
+[S			Like "]S" but search backwards.
+
+
+To add words to your own word list:
+
+							*zg*
+zg			Add word under the cursor as a good word to the first
+			name in 'spellfile'.  A count may precede the command
+			to indicate the entry in 'spellfile' to be used.  A
+			count of two uses the second entry.
+
+			In Visual mode the selected characters are added as a
+			word (including white space!).
+			When the cursor is on text that is marked as badly
+			spelled then the marked text is used.
+			Otherwise the word under the cursor, separated by
+			non-word characters, is used.
+
+			If the word is explicitly marked as bad word in
+			another spell file the result is unpredictable.
+
+							*zG*
+zG			Like "zg" but add the word to the internal word list
+			|internal-wordlist|.
+
+							*zw*
+zw			Like "zg" but mark the word as a wrong (bad) word.
+			If the word already appears in 'spellfile' it is
+			turned into a comment line.  See |spellfile-cleanup|
+			for getting rid of those.
+
+							*zW*
+zW			Like "zw" but add the word to the internal word list
+			|internal-wordlist|.
+
+zuw							*zug* *zuw*
+zug			Undo |zw| and |zg|, remove the word from the entry in
+			'spellfile'.  Count used as with |zg|.
+
+zuW							*zuG* *zuW*
+zuG			Undo |zW| and |zG|, remove the word from the internal
+			word list.  Count used as with |zg|.
+
+							*:spe* *:spellgood*
+:[count]spe[llgood] {word}
+			Add {word} as a good word to 'spellfile', like with
+			|zg|.  Without count the first name is used, with a
+			count of two the second entry, etc.
+
+:spe[llgood]! {word}	Add {word} as a good word to the internal word list,
+			like with |zG|.
+
+							*:spellw* *:spellwrong*
+:[count]spellw[rong] {word}
+			Add {word} as a wrong (bad) word to 'spellfile', as
+			with |zw|.  Without count the first name is used, with
+			a count of two the second entry, etc.
+
+:spellw[rong]! {word}	Add {word} as a wrong (bad) word to the internal word
+			list, like with |zW|.
+
+:[count]spellu[ndo] {word}				*:spellu* *:spellundo*
+			Like |zuw|.  [count] used as with |:spellgood|.
+
+:spellu[ndo]! {word}	Like |zuW|.  [count] used as with |:spellgood|.
+
+
+After adding a word to 'spellfile' with the above commands its associated
+".spl" file will automatically be updated and reloaded.  If you change
+'spellfile' manually you need to use the |:mkspell| command.  This sequence of
+commands mostly works well: >
+	:edit <file in 'spellfile'>
+<	(make changes to the spell file) >
+	:mkspell! %
+
+More details about the 'spellfile' format below |spell-wordlist-format|.
+
+							*internal-wordlist*
+The internal word list is used for all buffers where 'spell' is set.  It is
+not stored, it is lost when you exit Vim.  It is also cleared when 'encoding'
+is set.
+
+
+Finding suggestions for bad words:
+							*z=*
+z=			For the word under/after the cursor suggest correctly
+			spelled words.  This also works to find alternatives
+			for a word that is not highlighted as a bad word,
+			e.g., when the word after it is bad.
+			In Visual mode the highlighted text is taken as the
+			word to be replaced.
+			The results are sorted on similarity to the word being
+			replaced.
+			This may take a long time.  Hit CTRL-C when you get
+			bored.
+
+			If the command is used without a count the
+			alternatives are listed and you can enter the number
+			of your choice or press <Enter> if you don't want to
+			replace.  You can also use the mouse to click on your
+			choice (only works if the mouse can be used in Normal
+			mode and when there are no line wraps).  Click on the
+			first line (the header) to cancel.
+
+			The suggestions listed normally replace a highlighted
+			bad word.  Sometimes they include other text, in that
+			case the replaced text is also listed after a "<".
+
+			If a count is used that suggestion is used, without
+			prompting.  For example, "1z=" always takes the first
+			suggestion.
+
+			If 'verbose' is non-zero a score will be displayed
+			with the suggestions to indicate the likeliness to the
+			badly spelled word (the higher the score the more
+			different).
+			When a word was replaced the redo command "." will
+			repeat the word replacement.  This works like "ciw",
+			the good word and <Esc>.  This does NOT work for Thai
+			and other languages without spaces between words.
+
+					*:spellr* *:spellrepall* *E752* *E753*
+:spellr[epall]		Repeat the replacement done by |z=| for all matches
+			with the replaced word in the current window.
+
+In Insert mode, when the cursor is after a badly spelled word, you can use
+CTRL-X s to find suggestions.  This works like Insert mode completion.  Use
+CTRL-N to use the next suggestion, CTRL-P to go back. |i_CTRL-X_s|
+
+The 'spellsuggest' option influences how the list of suggestions is generated
+and sorted.  See |'spellsuggest'|.
+
+The 'spellcapcheck' option is used to check the first word of a sentence
+starts with a capital.  This doesn't work for the first word in the file.
+When there is a line break right after a sentence the highlighting of the next
+line may be postponed.  Use |CTRL-L| when needed.  Also see |set-spc-auto| for
+how it can be set automatically when 'spelllang' is set.
+
+Vim counts the number of times a good word is encountered.  This is used to
+sort the suggestions: words that have been seen before get a small bonus,
+words that have been seen often get a bigger bonus.  The COMMON item in the
+affix file can be used to define common words, so that this mechanism also
+works in a new or short file |spell-COMMON|.
+
+==============================================================================
+2. Remarks on spell checking				*spell-remarks*
+
+PERFORMANCE
+
+Vim does on-the-fly spell checking.  To make this work fast the word list is
+loaded in memory.  Thus this uses a lot of memory (1 Mbyte or more).  There
+might also be a noticeable delay when the word list is loaded, which happens
+when 'spell' is set and when 'spelllang' is set while 'spell' was already set.
+To minimize the delay each word list is only loaded once, it is not deleted
+when 'spelllang' is made empty or 'spell' is reset.  When 'encoding' is set
+all the word lists are reloaded, thus you may notice a delay then too.
+
+
+REGIONS
+
+A word may be spelled differently in various regions.  For example, English
+comes in (at least) these variants:
+
+	en		all regions
+	en_au		Australia
+	en_ca		Canada
+	en_gb		Great Britain
+	en_nz		New Zealand
+	en_us		USA
+
+Words that are not used in one region but are used in another region are
+highlighted with SpellLocal |hl-SpellLocal|.
+
+Always use lowercase letters for the language and region names.
+
+When adding a word with |zg| or another command it's always added for all
+regions.  You can change that by manually editing the 'spellfile'.  See
+|spell-wordlist-format|.  Note that the regions as specified in the files in
+'spellfile' are only used when all entries in 'spelllang' specify the same
+region (not counting files specified by their .spl name).
+
+							*spell-german*
+Specific exception: For German these special regions are used:
+	de		all German words accepted
+	de_de		old and new spelling
+	de_19		old spelling
+	de_20		new spelling
+	de_at		Austria
+	de_ch		Switzerland
+
+							*spell-russian*
+Specific exception: For Russian these special regions are used:
+	ru		all Russian words accepted
+	ru_ru		"IE" letter spelling
+	ru_yo		"YO" letter spelling
+
+							*spell-yiddish*
+Yiddish requires using "utf-8" encoding, because of the special characters
+used.  If you are using latin1 Vim will use transliterated (romanized) Yiddish
+instead.  If you want to use transliterated Yiddish with utf-8 use "yi-tr".
+In a table:
+	'encoding'	'spelllang'
+	utf-8		yi		Yiddish
+	latin1		yi		transliterated Yiddish
+	utf-8		yi-tr		transliterated Yiddish
+
+
+SPELL FILES						*spell-load*
+
+Vim searches for spell files in the "spell" subdirectory of the directories in
+'runtimepath'.  The name is: LL.EEE.spl, where:
+	LL	the language name
+	EEE	the value of 'encoding'
+
+The value for "LL" comes from 'spelllang', but excludes the region name.
+Examples:
+	'spelllang'	LL ~
+	en_us		en
+	en-rare		en-rare
+	medical_ca	medical
+
+Only the first file is loaded, the one that is first in 'runtimepath'.  If
+this succeeds then additionally files with the name LL.EEE.add.spl are loaded.
+All the ones that are found are used.
+
+If no spell file is found the |SpellFileMissing| autocommand event is
+triggered.  This may trigger the |spellfile.vim| plugin to offer you
+downloading the spell file.
+
+Additionally, the files related to the names in 'spellfile' are loaded.  These
+are the files that |zg| and |zw| add good and wrong words to.
+
+Exceptions:
+- Vim uses "latin1" when 'encoding' is "iso-8859-15".  The euro sign doesn't
+  matter for spelling.
+- When no spell file for 'encoding' is found "ascii" is tried.  This only
+  works for languages where nearly all words are ASCII, such as English.  It
+  helps when 'encoding' is not "latin1", such as iso-8859-2, and English text
+  is being edited.  For the ".add" files the same name as the found main
+  spell file is used.
+
+For example, with these values:
+	'runtimepath' is "~/.vim,/usr/share/vim70,~/.vim/after"
+	'encoding'    is "iso-8859-2"
+	'spelllang'   is "pl"
+
+Vim will look for:
+1. ~/.vim/spell/pl.iso-8859-2.spl
+2. /usr/share/vim70/spell/pl.iso-8859-2.spl
+3. ~/.vim/spell/pl.iso-8859-2.add.spl
+4. /usr/share/vim70/spell/pl.iso-8859-2.add.spl
+5. ~/.vim/after/spell/pl.iso-8859-2.add.spl
+
+This assumes 1. is not found and 2. is found.
+
+If 'encoding' is "latin1" Vim will look for:
+1. ~/.vim/spell/pl.latin1.spl
+2. /usr/share/vim70/spell/pl.latin1.spl
+3. ~/.vim/after/spell/pl.latin1.spl
+4. ~/.vim/spell/pl.ascii.spl
+5. /usr/share/vim70/spell/pl.ascii.spl
+6. ~/.vim/after/spell/pl.ascii.spl
+
+This assumes none of them are found (Polish doesn't make sense when leaving
+out the non-ASCII characters).
+
+Spelling for EBCDIC is currently not supported.
+
+A spell file might not be available in the current 'encoding'.  See
+|spell-mkspell| about how to create a spell file.  Converting a spell file
+with "iconv" will NOT work!
+
+						    *spell-sug-file* *E781*
+If there is a file with exactly the same name as the ".spl" file but ending in
+".sug", that file will be used for giving better suggestions.  It isn't loaded
+before suggestions are made to reduce memory use.
+
+				    *E758* *E759* *E778* *E779* *E780* *E782*
+When loading a spell file Vim checks that it is properly formatted.  If you
+get an error the file may be truncated, modified or intended for another Vim
+version.
+
+
+SPELLFILE CLEANUP					*spellfile-cleanup*
+
+The |zw| command turns existing entries in 'spellfile' into comment lines.
+This avoids having to write a new file every time, but results in the file
+only getting longer, never shorter.  To clean up the comment lines in all
+".add" spell files do this: >
+	:runtime spell/cleanadd.vim
+
+This deletes all comment lines, except the ones that start with "##".  Use
+"##" lines to add comments that you want to keep.
+
+You can invoke this script as often as you like.  A variable is provided to
+skip updating files that have been changed recently.  Set it to the number of
+seconds that has passed since a file was changed before it will be cleaned.
+For example, to clean only files that were not changed in the last hour: >
+      let g:spell_clean_limit = 60 * 60
+The default is one second.
+
+
+WORDS
+
+Vim uses a fixed method to recognize a word.  This is independent of
+'iskeyword', so that it also works in help files and for languages that
+include characters like '-' in 'iskeyword'.  The word characters do depend on
+'encoding'.
+
+The table with word characters is stored in the main .spl file.  Therefore it
+matters what the current locale is when generating it!  A .add.spl file does
+not contain a word table though.
+
+For a word that starts with a digit the digit is ignored, unless the word as a
+whole is recognized.  Thus if "3D" is a word and "D" is not then "3D" is
+recognized as a word, but if "3D" is not a word then only the "D" is marked as
+bad.  Hex numbers in the form 0x12ab and 0X12AB are recognized.
+
+
+WORD COMBINATIONS
+
+It is possible to spell-check words that include a space.  This is used to
+recognize words that are invalid when used by themselves, e.g. for "et al.".
+It can also be used to recognize "the the" and highlight it.
+
+The number of spaces is irrelevant.  In most cases a line break may also
+appear.  However, this makes it difficult to find out where to start checking
+for spelling mistakes.  When you make a change to one line and only that line
+is redrawn Vim won't look in the previous line, thus when "et" is at the end
+of the previous line "al." will be flagged as an error.  And when you type
+"the<CR>the" the highlighting doesn't appear until the first line is redrawn.
+Use |CTRL-L| to redraw right away.  "[s" will also stop at a word combination
+with a line break.
+
+When encountering a line break Vim skips characters such as '*', '>' and '"',
+so that comments in C, shell and Vim code can be spell checked.
+
+
+SYNTAX HIGHLIGHTING					*spell-syntax*
+
+Files that use syntax highlighting can specify where spell checking should be
+done:
+
+1.  everywhere			   default
+2.  in specific items		   use "contains=@Spell"
+3.  everywhere but specific items  use "contains=@NoSpell"
+
+For the second method adding the @NoSpell cluster will disable spell checking
+again.  This can be used, for example, to add @Spell to the comments of a
+program, and add @NoSpell for items that shouldn't be checked.
+Also see |:syn-spell| for text that is not in a syntax item.
+
+
+VIM SCRIPTS
+
+If you want to write a Vim script that does something with spelling, you may
+find these functions useful:
+
+    spellbadword()	find badly spelled word at the cursor
+    spellsuggest()	get list of spelling suggestions
+    soundfold()		get the sound-a-like version of a word
+
+
+SETTING 'spellcapcheck' AUTOMATICALLY			*set-spc-auto*
+
+After the 'spelllang' option has been set successfully, Vim will source the
+files "spell/LANG.vim" in 'runtimepath'.  "LANG" is the value of 'spelllang'
+up to the first comma, dot or underscore.  This can be used to set options
+specifically for the language, especially 'spellcapcheck'.
+
+The distribution includes a few of these files.  Use this command to see what
+they do: >
+	:next $VIMRUNTIME/spell/*.vim
+
+Note that the default scripts don't set 'spellcapcheck' if it was changed from
+the default value.  This assumes the user prefers another value then.
+
+
+DOUBLE SCORING						*spell-double-scoring*
+
+The 'spellsuggest' option can be used to select "double" scoring.  This
+mechanism is based on the principle that there are two kinds of spelling
+mistakes:
+
+1. You know how to spell the word, but mistype something.  This results in a
+   small editing distance (character swapped/omitted/inserted) and possibly a
+   word that sounds completely different.
+
+2. You don't know how to spell the word and type something that sounds right.
+   The edit distance can be big but the word is similar after sound-folding.
+
+Since scores for these two mistakes will be very different we use a list
+for each and mix them.
+
+The sound-folding is slow and people that know the language won't make the
+second kind of mistakes.  Therefore 'spellsuggest' can be set to select the
+preferred method for scoring the suggestions.
+
+==============================================================================
+3. Generating a spell file				*spell-mkspell*
+
+Vim uses a binary file format for spelling.  This greatly speeds up loading
+the word list and keeps it small.
+						    *.aff* *.dic* *Myspell*
+You can create a Vim spell file from the .aff and .dic files that Myspell
+uses.  Myspell is used by OpenOffice.org and Mozilla.  You should be able to
+find them here:
+	http://wiki.services.openoffice.org/wiki/Dictionaries
+You can also use a plain word list.  The results are the same, the choice
+depends on what word lists you can find.
+
+If you install Aap (from www.a-a-p.org) you can use the recipes in the
+runtime/spell/??/ directories.  Aap will take care of downloading the files,
+apply patches needed for Vim and build the .spl file.
+
+Make sure your current locale is set properly, otherwise Vim doesn't know what
+characters are upper/lower case letters.  If the locale isn't available (e.g.,
+when using an MS-Windows codepage on Unix) add tables to the .aff file
+|spell-affix-chars|.  If the .aff file doesn't define a table then the word
+table of the currently active spelling is used.  If spelling is not active
+then Vim will try to guess.
+
+							*:mksp* *:mkspell*
+:mksp[ell][!] [-ascii] {outname} {inname} ...
+			Generate a Vim spell file from word lists.  Example: >
+		:mkspell /tmp/nl nl_NL.words
+<								*E751*
+			When {outname} ends in ".spl" it is used as the output
+			file name.  Otherwise it should be a language name,
+			such as "en", without the region name.  The file
+			written will be "{outname}.{encoding}.spl", where
+			{encoding} is the value of the 'encoding' option.
+
+			When the output file already exists [!] must be used
+			to overwrite it.
+
+			When the [-ascii] argument is present, words with
+			non-ascii characters are skipped.  The resulting file
+			ends in "ascii.spl".
+
+			The input can be the Myspell format files {inname}.aff
+			and {inname}.dic.  If {inname}.aff does not exist then
+			{inname} is used as the file name of a plain word
+			list.
+
+			Multiple {inname} arguments can be given to combine
+			regions into one Vim spell file.  Example: >
+		:mkspell ~/.vim/spell/en /tmp/en_US /tmp/en_CA /tmp/en_AU
+<			This combines the English word lists for US, CA and AU
+			into one en.spl file.
+			Up to eight regions can be combined. *E754* *E755*
+			The REP and SAL items of the first .aff file where
+			they appear are used. |spell-REP| |spell-SAL|
+
+			This command uses a lot of memory, required to find
+			the optimal word tree (Polish, Italian and Hungarian
+			require several hundred Mbyte).  The final result will
+			be much smaller, because compression is used.  To
+			avoid running out of memory compression will be done
+			now and then.  This can be tuned with the 'mkspellmem'
+			option.
+
+			After the spell file was written and it was being used
+			in a buffer it will be reloaded automatically.
+
+:mksp[ell] [-ascii] {name}.{enc}.add
+			Like ":mkspell" above, using {name}.{enc}.add as the
+			input file and producing an output file in the same
+			directory that has ".spl" appended.
+
+:mksp[ell] [-ascii] {name}
+			Like ":mkspell" above, using {name} as the input file
+			and producing an output file in the same directory
+			that has ".{enc}.spl" appended.
+
+Vim will report the number of duplicate words.  This might be a mistake in the
+list of words.  But sometimes it is used to have different prefixes and
+suffixes for the same basic word to avoid them combining (e.g. Czech uses
+this).  If you want Vim to report all duplicate words set the 'verbose'
+option.
+
+Since you might want to change a Myspell word list for use with Vim the
+following procedure is recommended:
+
+1. Obtain the xx_YY.aff and xx_YY.dic files from Myspell.
+2. Make a copy of these files to xx_YY.orig.aff and xx_YY.orig.dic.
+3. Change the xx_YY.aff and xx_YY.dic files to remove bad words, add missing
+   words, define word characters with FOL/LOW/UPP, etc.  The distributed
+   "*.diff" files can be used.
+4. Start Vim with the right locale and use |:mkspell| to generate the Vim
+   spell file.
+5. Try out the spell file with ":set spell spelllang=xx" if you wrote it in
+   a spell directory in 'runtimepath', or ":set spelllang=xx.enc.spl" if you
+   wrote it somewhere else.
+
+When the Myspell files are updated you can merge the differences:
+1. Obtain the new Myspell files as xx_YY.new.aff and xx_UU.new.dic.
+2. Use Vimdiff to see what changed: >
+	vimdiff xx_YY.orig.dic xx_YY.new.dic
+3. Take over the changes you like in xx_YY.dic.
+   You may also need to change xx_YY.aff.
+4. Rename xx_YY.new.dic to xx_YY.orig.dic and xx_YY.new.aff to xx_YY.new.aff.
+
+
+SPELL FILE VERSIONS					*E770* *E771* *E772*
+
+Spell checking is a relatively new feature in Vim, thus it's possible that the
+.spl file format will be changed to support more languages.  Vim will check
+the validity of the spell file and report anything wrong.
+
+	E771: Old spell file, needs to be updated ~
+This spell file is older than your Vim.  You need to update the .spl file.
+
+	E772: Spell file is for newer version of Vim ~
+This means the spell file was made for a later version of Vim.  You need to
+update Vim.
+
+	E770: Unsupported section in spell file ~
+This means the spell file was made for a later version of Vim and contains a
+section that is required for the spell file to work.  In this case it's
+probably a good idea to upgrade your Vim.
+
+
+SPELL FILE DUMP
+
+If for some reason you want to check what words are supported by the currently
+used spelling files, use this command:
+
+							*:spelldump* *:spelld*
+:spelld[ump]		Open a new window and fill it with all currently valid
+			words.  Compound words are not included.
+			Note: For some languages the result may be enormous,
+			causing Vim to run out of memory.
+
+:spelld[ump]!		Like ":spelldump" and include the word count.  This is
+			the number of times the word was found while
+			updating the screen.  Words that are in COMMON items
+			get a starting count of 10.
+
+The format of the word list is used |spell-wordlist-format|.  You should be
+able to read it with ":mkspell" to generate one .spl file that includes all
+the words.
+
+When all entries to 'spelllang' use the same regions or no regions at all then
+the region information is included in the dumped words.  Otherwise only words
+for the current region are included and no "/regions" line is generated.
+
+Comment lines with the name of the .spl file are used as a header above the
+words that were generated from that .spl file.
+
+
+SPELL FILE MISSING		*spell-SpellFileMissing* *spellfile.vim*
+
+If the spell file for the language you are using is not available, you will
+get an error message.  But if the "spellfile.vim" plugin is active it will
+offer you to download the spell file.  Just follow the instructions, it will
+ask you where to write the file.
+
+The plugin has a default place where to look for spell files, on the Vim ftp
+server.  If you want to use another location or another protocol, set the
+g:spellfile_URL variable to the directory that holds the spell files.  The
+|netrw| plugin is used for getting the file, look there for the specific
+syntax of the URL.  Example: >
+	let g:spellfile_URL = 'http://ftp.vim.org/vim/runtime/spell'
+You may need to escape special characters.
+
+The plugin will only ask about downloading a language once.  If you want to
+try again anyway restart Vim, or set g:spellfile_URL to another value (e.g.,
+prepend a space).
+
+To avoid using the "spellfile.vim" plugin do this in your vimrc file: >
+
+	let loaded_spellfile_plugin = 1
+
+Instead of using the plugin you can define a |SpellFileMissing| autocommand to
+handle the missing file yourself.  You can use it like this: >
+
+	:au SpellFileMissing * call Download_spell_file(expand('<amatch>'))
+
+Thus the <amatch> item contains the name of the language.  Another important
+value is 'encoding', since every encoding has its own spell file.  With two
+exceptions:
+- For ISO-8859-15 (latin9) the name "latin1" is used (the encodings only
+  differ in characters not used in dictionary words).
+- The name "ascii" may also be used for some languages where the words use
+  only ASCII letters for most of the words.
+
+The default "spellfile.vim" plugin uses this autocommand, if you define your
+autocommand afterwards you may want to use ":au! SpellFileMissing" to overrule
+it.  If you define your autocommand before the plugin is loaded it will notice
+this and not do anything.
+							*E797*
+Note that the SpellFileMissing autocommand must not change or destroy the
+buffer the user was editing.
+
+==============================================================================
+4. Spell file format					*spell-file-format*
+
+This is the format of the files that are used by the person who creates and
+maintains a word list.
+
+Note that we avoid the word "dictionary" here.  That is because the goal of
+spell checking differs from writing a dictionary (as in the book).  For
+spelling we need a list of words that are OK, thus should not be highlighted.
+Person and company names will not appear in a dictionary, but do appear in a
+word list.  And some old words are rarely used while they are common
+misspellings.  These do appear in a dictionary but not in a word list.
+
+There are two formats: A straight list of words and a list using affix
+compression.  The files with affix compression are used by Myspell (Mozilla
+and OpenOffice.org).  This requires two files, one with .aff and one with .dic
+extension.
+
+
+FORMAT OF STRAIGHT WORD LIST				*spell-wordlist-format*
+
+The words must appear one per line.  That is all that is required.
+
+Additionally the following items are recognized:
+
+- Empty and blank lines are ignored.
+
+	# comment ~
+- Lines starting with a # are ignored (comment lines).
+
+	/encoding=utf-8 ~
+- A line starting with "/encoding=", before any word, specifies the encoding
+  of the file.  After the second '=' comes an encoding name.  This tells Vim
+  to setup conversion from the specified encoding to 'encoding'.  Thus you can
+  use one word list for several target encodings.
+
+	/regions=usca ~
+- A line starting with "/regions=" specifies the region names that are
+  supported.  Each region name must be two ASCII letters.  The first one is
+  region 1.  Thus "/regions=usca" has region 1 "us" and region 2 "ca".
+  In an addition word list the region names should be equal to the main word
+  list!
+
+- Other lines starting with '/' are reserved for future use.  The ones that
+  are not recognized are ignored.  You do get a warning message, so that you
+  know something won't work.
+
+- A "/" may follow the word with the following items:
+    =		Case must match exactly.
+    ?		Rare word.
+    !		Bad (wrong) word.
+    digit	A region in which the word is valid.  If no regions are
+		specified the word is valid in all regions.
+
+Example:
+
+	# This is an example word list		comment
+	/encoding=latin1			encoding of the file
+	/regions=uscagb				regions "us", "ca" and "gb"
+	example					word for all regions
+	blah/12					word for regions "us" and "ca"
+	vim/!					bad word
+	Campbell/?3				rare word in region 3 "gb"
+	's mornings/=				keep-case word
+
+Note that when "/=" is used the same word with all upper-case letters is not
+accepted.  This is different from a word with mixed case that is automatically
+marked as keep-case, those words may appear in all upper-case letters.
+
+
+FORMAT WITH .AFF AND .DIC FILES				*aff-dic-format*
+
+There are two files: the basic word list and an affix file.  The affix file
+specifies settings for the language and can contain affixes.  The affixes are
+used to modify the basic words to get the full word list.  This significantly
+reduces the number of words, especially for a language like Polish.  This is
+called affix compression.
+
+The basic word list and the affix file are combined with the ":mkspell"
+command and results in a binary spell file.  All the preprocessing has been
+done, thus this file loads fast.  The binary spell file format is described in
+the source code (src/spell.c).  But only developers need to know about it.
+
+The preprocessing also allows us to take the Myspell language files and modify
+them before the Vim word list is made.  The tools for this can be found in the
+"src/spell" directory.
+
+The format for the affix and word list files is based on what Myspell uses
+(the spell checker of Mozilla and OpenOffice.org).  A description can be found
+here:
+	http://lingucomponent.openoffice.org/affix.readme ~
+Note that affixes are case sensitive, this isn't obvious from the description.
+
+Vim supports quite a few extras.  They are described below |spell-affix-vim|.
+Attempts have been made to keep this compatible with other spell checkers, so
+that the same files can often be used.  One other project that offers more
+than Myspell is Hunspell ( http://hunspell.sf.net ).
+
+
+WORD LIST FORMAT				*spell-dic-format*
+
+A short example, with line numbers:
+
+	1	1234 ~
+	2	aan ~
+	3	Als ~
+	4	Etten-Leur ~
+	5	et al. ~
+	6	's-Gravenhage ~
+	7	's-Gravenhaags ~
+	8	# word that differs between regions ~
+	9	kado/1 ~
+	10	cadeau/2 ~
+	11	TCP,IP ~
+	12	/the S affix may add a 's' ~
+	13	bedel/S ~
+
+The first line contains the number of words.  Vim ignores it, but you do get
+an error message if it's not there.  *E760*
+
+What follows is one word per line.  White space at the end of the line is
+ignored, all other white space matters.  The encoding is specified in the
+affix file |spell-SET|.
+
+Comment lines start with '#' or '/'.  See the example lines 8 and 12.  Note
+that putting a comment after a word is NOT allowed:
+
+		someword   # comment that causes an error! ~
+
+After the word there is an optional slash and flags.  Most of these flags are
+letters that indicate the affixes that can be used with this word.  These are
+specified with SFX and PFX lines in the .aff file, see |spell-SFX| and
+|spell-PFX|.  Vim allows using other flag types with the FLAG item in the
+affix file |spell-FLAG|.
+
+When the word only has lower-case letters it will also match with the word
+starting with an upper-case letter.
+
+When the word includes an upper-case letter, this means the upper-case letter
+is required at this position.  The same word with a lower-case letter at this
+position will not match. When some of the other letters are upper-case it will
+not match either.
+
+The word with all upper-case characters will always be OK,
+
+	word list	matches			does not match ~
+	als		als Als ALS		ALs AlS aLs aLS
+	Als		Als  ALS		als ALs AlS aLs aLS
+	ALS		ALS			als Als ALs AlS aLs aLS
+	AlS		AlS ALS			als Als ALs aLs aLS
+
+The KEEPCASE affix ID can be used to specifically match a word with identical
+case only, see below |spell-KEEPCASE|.
+
+Note: in line 5 to 7 non-word characters are used.  You can include any
+character in a word.  When checking the text a word still only matches when it
+appears with a non-word character before and after it.  For Myspell a word
+starting with a non-word character probably won't work.
+
+In line 12 the word "TCP/IP" is defined.  Since the slash has a special
+meaning the comma is used instead.  This is defined with the SLASH item in the
+affix file, see |spell-SLASH|.  Note that without this SLASH item the word
+will be "TCP,IP".
+
+
+AFFIX FILE FORMAT			*spell-aff-format* *spell-affix-vim*
+
+							*spell-affix-comment*
+Comment lines in the .aff file start with a '#':
+
+	# comment line ~
+
+With some items it's also possible to put a comment after it, but this isn't
+supported in general.
+
+
+ENCODING							*spell-SET*
+
+The affix file can be in any encoding that is supported by "iconv".  However,
+in some cases the current locale should also be set properly at the time
+|:mkspell| is invoked.  Adding FOL/LOW/UPP lines removes this requirement
+|spell-FOL|.
+
+The encoding should be specified before anything where the encoding matters.
+The encoding applies both to the affix file and the dictionary file.  It is
+done with a SET line:
+
+	SET utf-8 ~
+
+The encoding can be different from the value of the 'encoding' option at the
+time ":mkspell" is used.  Vim will then convert everything to 'encoding' and
+generate a spell file for 'encoding'.  If some of the used characters to not
+fit in 'encoding' you will get an error message.
+							*spell-affix-mbyte*
+When using a multi-byte encoding it's possible to use more different affix
+flags.  But Myspell doesn't support that, thus you may not want to use it
+anyway.  For compatibility use an 8-bit encoding.
+
+
+INFORMATION
+
+These entries in the affix file can be used to add information to the spell
+file.  There are no restrictions on the format, but they should be in the
+right encoding.
+
+				*spell-NAME* *spell-VERSION* *spell-HOME*
+				*spell-AUTHOR* *spell-EMAIL* *spell-COPYRIGHT*
+	NAME		Name of the language
+	VERSION		1.0.1  with fixes
+	HOME		http://www.myhome.eu
+	AUTHOR		John Doe
+	EMAIL		john AT Doe DOT net
+	COPYRIGHT	LGPL
+
+These fields are put in the .spl file as-is.  The |:spellinfo| command can be
+used to view the info.
+
+							*:spellinfo* *:spelli*
+:spelli[nfo]		Display the information for the spell file(s) used for
+			the current buffer.
+
+
+CHARACTER TABLES
+							*spell-affix-chars*
+When using an 8-bit encoding the affix file should define what characters are
+word characters.  This is because the system where ":mkspell" is used may not
+support a locale with this encoding and isalpha() won't work.  For example
+when using "cp1250" on Unix.
+						*E761* *E762* *spell-FOL*
+						*spell-LOW* *spell-UPP*
+Three lines in the affix file are needed.  Simplistic example:
+
+	FOL  ��� ~
+	LOW  ��� ~
+	UPP  ��� ~
+
+All three lines must have exactly the same number of characters.
+
+The "FOL" line specifies the case-folded characters.  These are used to
+compare words while ignoring case.  For most encodings this is identical to
+the lower case line.
+
+The "LOW" line specifies the characters in lower-case.  Mostly it's equal to
+the "FOL" line.
+
+The "UPP" line specifies the characters with upper-case.  That is, a character
+is upper-case where it's different from the character at the same position in
+"FOL".
+
+An exception is made for the German sharp s �.  The upper-case version is
+"SS".  In the FOL/LOW/UPP lines it should be included, so that it's recognized
+as a word character, but use the � character in all three.
+
+ASCII characters should be omitted, Vim always handles these in the same way.
+When the encoding is UTF-8 no word characters need to be specified.
+
+							*E763*
+Vim allows you to use spell checking for several languages in the same file.
+You can list them in the 'spelllang' option.  As a consequence all spell files
+for the same encoding must use the same word characters, otherwise they can't
+be combined without errors.  If you get a warning that the word tables differ
+you may need to generate the .spl file again with |:mkspell|.  Check the FOL,
+LOW and UPP lines in the used .aff file.
+
+The XX.ascii.spl spell file generated with the "-ascii" argument will not
+contain the table with characters, so that it can be combine with spell files
+for any encoding.  The .add.spl files also do not contain the table.
+
+
+MID-WORD CHARACTERS
+							*spell-midword*
+Some characters are only to be considered word characters if they are used in
+between two ordinary word characters.  An example is the single quote: It is
+often used to put text in quotes, thus it can't be recognized as a word
+character, but when it appears in between word characters it must be part of
+the word.  This is needed to detect a spelling error such as they'are.  That
+should be they're, but since "they" and "are" are words themselves that would
+go unnoticed.
+
+These characters are defined with MIDWORD in the .aff file.  Example:
+
+	MIDWORD	'- ~
+
+
+FLAG TYPES						*spell-FLAG*
+
+Flags are used to specify the affixes that can be used with a word and for
+other properties of the word.  Normally single-character flags are used.  This
+limits the number of possible flags, especially for 8-bit encodings.  The FLAG
+item can be used if more affixes are to be used.  Possible values:
+
+	FLAG long	use two-character flags
+	FLAG num	use numbers, from 1 up to 65000
+	FLAG caplong	use one-character flags without A-Z and two-character
+			flags that start with A-Z
+
+With "FLAG num" the numbers in a list of affixes need to be separated with a
+comma: "234,2143,1435".  This method is inefficient, but useful if the file is
+generated with a program.
+
+When using "caplong" the two-character flags all start with a capital: "Aa",
+"B1", "BB", etc.  This is useful to use one-character flags for the most
+common items and two-character flags for uncommon items.
+
+Note: When using utf-8 only characters up to 65000 may be used for flags.
+
+
+AFFIXES
+					    *spell-PFX* *spell-SFX*
+The usual PFX (prefix) and SFX (suffix) lines are supported (see the Myspell
+documentation or the Aspell manual:
+http://aspell.net/man-html/Affix-Compression.html).
+
+Summary:
+	SFX L Y 2 ~
+	SFX L 0 re [^x] ~
+	SFX L 0 ro x ~
+
+The first line is a header and has four fields:
+	SFX {flag} {combine} {count}
+
+{flag}		The name used for the suffix.  Mostly it's a single letter,
+		but other characters can be used, see |spell-FLAG|.
+
+{combine}	Can be 'Y' or 'N'.  When 'Y' then the word plus suffix can
+		also have a prefix.  When 'N' then a prefix is not allowed.
+
+{count}		The number of lines following.  If this is wrong you will get
+		an error message.
+
+For PFX the fields are exactly the same.
+
+The basic format for the following lines is:
+	SFX {flag} {strip} {add} {condition} {extra}
+
+{flag}		Must be the same as the {flag} used in the first line.
+
+{strip}		Characters removed from the basic word.  There is no check if
+		the characters are actually there, only the length is used (in
+		bytes).  This better match the {condition}, otherwise strange
+		things may happen.  If the {strip} length is equal to or
+		longer than the basic word the suffix won't be used.
+		When {strip} is 0 (zero) then nothing is stripped.
+
+{add}		Characters added to the basic word, after removing {strip}.
+		Optionally there is a '/' followed by flags.  The flags apply
+		to the word plus affix.  See |spell-affix-flags|
+
+{condition}	A simplistic pattern.  Only when this matches with a basic
+		word will the suffix be used for that word.  This is normally
+		for using one suffix letter with different {add} and {strip}
+		fields for words with different endings.
+		When {condition} is a . (dot) there is no condition.
+		The pattern may contain:
+		- Literal characters.
+		- A set of characters in []. [abc] matches a, b and c.
+		  A dash is allowed for a range [a-c], but this is
+		  Vim-specific.
+		- A set of characters that starts with a ^, meaning the
+		  complement of the specified characters. [^abc] matches any
+		  character but a, b and c.
+
+{extra}		Optional extra text:
+		    # comment		Comment is ignored
+		    -			Hunspell uses this, ignored
+
+For PFX the fields are the same, but the {strip}, {add} and {condition} apply
+to the start of the word.
+
+Note: Myspell ignores any extra text after the relevant info.  Vim requires
+this text to start with a "#" so that mistakes don't go unnoticed.  Example:
+
+	SFX F 0 in   [^i]n      # Spion > Spionin  ~
+	SFX F 0 nen  in		# Bauerin > Bauerinnen ~
+
+Apparently Myspell allows an affix name to appear more than once.  Since this
+might also be a mistake, Vim checks for an extra "S".  The affix files for
+Myspell that use this feature apparently have this flag.  Example:
+
+	SFX a Y 1 S ~
+	SFX a 0 an . ~
+
+	SFX a Y 2 S ~
+	SFX a 0 en . ~
+	SFX a 0 on . ~
+
+
+AFFIX FLAGS						*spell-affix-flags*
+
+This is a feature that comes from Hunspell: The affix may specify flags.  This
+works similar to flags specified on a basic word.  The flags apply to the
+basic word plus the affix (but there are restrictions).  Example:
+
+	SFX S Y 1 ~
+	SFX S 0 s . ~
+
+	SFX A Y 1 ~
+	SFX A 0 able/S . ~
+
+When the dictionary file contains "drink/AS" then these words are possible:
+
+	drink
+	drinks		uses S suffix
+	drinkable	uses A suffix
+	drinkables	uses A suffix and then S suffix
+
+Generally the flags of the suffix are added to the flags of the basic word,
+both are used for the word plus suffix.  But the flags of the basic word are
+only used once for affixes, except that both one prefix and one suffix can be
+used when both support combining.
+
+Specifically, the affix flags can be used for:
+- Suffixes on suffixes, as in the example above.  This works once, thus you
+  can have two suffixes on a word (plus one prefix).
+- Making the word with the affix rare, by using the |spell-RARE| flag.
+- Exclude the word with the affix from compounding, by using the
+  |spell-COMPOUNDFORBIDFLAG| flag.
+- Allow the word with the affix to be part of a compound word on the side of
+  the affix with the |spell-COMPOUNDPERMITFLAG|.
+- Use the NEEDCOMPOUND flag: word plus affix can only be used as part of a
+  compound word. |spell-NEEDCOMPOUND|
+- Compound flags: word plus affix can be part of a compound word at the end,
+  middle, start, etc.  The flags are combined with the flags of the basic
+  word.  |spell-compound|
+- NEEDAFFIX: another affix is needed to make a valid word.
+- CIRCUMFIX, as explained just below.
+
+
+CIRCUMFIX						*spell-CIRCUMFIX*
+
+The CIRCUMFIX flag means a prefix and suffix must be added at the same time.
+If a prefix has the CIRCUMFIX flag than only suffixes with the CIRCUMFIX flag
+can be added, and the other way around.
+An alternative is to only specify the suffix, and give the that suffix two
+flags: The required prefix and the NEEDAFFIX flag.  |spell-NEEDAFFIX|
+
+
+PFXPOSTPONE						*spell-PFXPOSTPONE*
+
+When an affix file has very many prefixes that apply to many words it's not
+possible to build the whole word list in memory.  This applies to Hebrew (a
+list with all words is over a Gbyte).  In that case applying prefixes must be
+postponed.  This makes spell checking slower.  It is indicated by this keyword
+in the .aff file:
+
+	PFXPOSTPONE ~
+
+Only prefixes without a chop string and without flags can be postponed.
+Prefixes with a chop string or with flags will still be included in the word
+list.  An exception if the chop string is one character and equal to the last
+character of the added string, but in lower case.  Thus when the chop string
+is used to allow the following word to start with an upper case letter.
+
+
+WORDS WITH A SLASH					*spell-SLASH*
+
+The slash is used in the .dic file to separate the basic word from the affix
+letters and other flags.  Unfortunately, this means you cannot use a slash in
+a word.  Thus "TCP/IP" is not a word but "TCP with the flags "IP".  To include
+a slash in the word put a backslash before it: "TCP\/IP".  In the rare case
+you want to use a backslash inside a word you need to use two backslashes.
+Any other use of the backslash is reserved for future expansion.
+
+
+KEEP-CASE WORDS						*spell-KEEPCASE*
+
+In the affix file a KEEPCASE line can be used to define the affix name used
+for keep-case words.  Example:
+
+	KEEPCASE = ~
+
+This flag is not supported by Myspell.  It has the meaning that case matters.
+This can be used if the word does not have the first letter in upper case at
+the start of a sentence.  Example:
+
+    word list	    matches		    does not match ~
+    's morgens/=    's morgens		    'S morgens 's Morgens 'S MORGENS
+    's Morgens	    's Morgens 'S MORGENS   'S morgens 's morgens
+
+The flag can also be used to avoid that the word matches when it is in all
+upper-case letters.
+
+
+RARE WORDS						*spell-RARE*
+
+In the affix file a RARE line can be used to define the affix name used for
+rare words.  Example:
+
+	RARE ? ~
+
+Rare words are highlighted differently from bad words.  This is to be used for
+words that are correct for the language, but are hardly ever used and could be
+a typing mistake anyway.  When the same word is found as good it won't be
+highlighted as rare.
+
+This flag can also be used on an affix, so that a basic word is not rare but
+the basic word plus affix is rare |spell-affix-flags|.  However, if the word
+also appears as a good word in another way (e.g., in another region) it won't
+be marked as rare.
+
+
+BAD WORDS						*spell-BAD*
+
+In the affix file a BAD line can be used to define the affix name used for
+bad words.  Example:
+
+	BAD ! ~
+
+This can be used to exclude words that would otherwise be good.  For example
+"the the" in the .dic file:
+
+	the the/! ~
+
+Once a word has been marked as bad it won't be undone by encountering the same
+word as good.
+
+The flag also applies to the word with affixes, thus this can be used to mark
+a whole bunch of related words as bad.
+
+							*spell-NEEDAFFIX*
+The NEEDAFFIX flag is used to require that a word is used with an affix.  The
+word itself is not a good word (unless there is an empty affix).  Example:
+
+	NEEDAFFIX + ~
+
+
+COMPOUND WORDS						*spell-compound*
+
+A compound word is a longer word made by concatenating words that appear in
+the .dic file.  To specify which words may be concatenated a character is
+used.  This character is put in the list of affixes after the word.  We will
+call this character a flag here.  Obviously these flags must be different from
+any affix IDs used.
+
+							*spell-COMPOUNDFLAG*
+The Myspell compatible method uses one flag, specified with COMPOUNDFLAG.  All
+words with this flag combine in any order.  This means there is no control
+over which word comes first.  Example:
+	COMPOUNDFLAG c ~
+
+							*spell-COMPOUNDRULE*
+A more advanced method to specify how compound words can be formed uses
+multiple items with multiple flags.  This is not compatible with Myspell 3.0.
+Let's start with an example:
+	COMPOUNDRULE c+ ~
+	COMPOUNDRULE se ~
+
+The first line defines that words with the "c" flag can be concatenated in any
+order.  The second line defines compound words that are made of one word with
+the "s" flag and one word with the "e" flag.  With this dictionary:
+	bork/c ~
+	onion/s ~
+	soup/e ~
+
+You can make these words:
+	bork
+	borkbork
+	borkborkbork
+	(etc.)
+	onion
+	soup
+	onionsoup
+
+The COMPOUNDRULE item may appear multiple times.  The argument is made out of
+one or more groups, where each group can be:
+	one flag			e.g., c
+	alternate flags inside []	e.g., [abc]
+Optionally this may be followed by:
+	*	the group appears zero or more times, e.g., sm*e
+	+	the group appears one or more times, e.g., c+
+
+This is similar to the regexp pattern syntax (but not the same!).  A few
+examples with the sequence of word flags they require:
+    COMPOUNDRULE x+	    x xx xxx etc.
+    COMPOUNDRULE yz	    yz
+    COMPOUNDRULE x+z	    xz xxz xxxz etc.
+    COMPOUNDRULE yx+	    yx yxx yxxx etc.
+
+    COMPOUNDRULE [abc]z    az bz cz
+    COMPOUNDRULE [abc]+z   az aaz abaz bz baz bcbz cz caz cbaz etc.
+    COMPOUNDRULE a[xyz]+   ax axx axyz ay ayx ayzz az azy azxy etc.
+    COMPOUNDRULE sm*e	    se sme smme smmme etc.
+    COMPOUNDRULE s[xyz]*e  se sxe sxye sxyxe sye syze sze szye szyxe  etc.
+
+A specific example: Allow a compound to be made of two words and a dash:
+	In the .aff file:
+	    COMPOUNDRULE sde ~
+	    NEEDAFFIX x ~
+	    COMPOUNDWORDMAX 3 ~
+	    COMPOUNDMIN 1 ~
+	In the .dic file:
+	    start/s ~
+	    end/e ~
+	    -/xd ~
+
+This allows for the word "start-end", but not "startend".
+
+An additional implied rule is that, without further flags, a word with a
+prefix cannot be compounded after another word, and a word with a suffix
+cannot be compounded with a following word.  Thus the affix cannot appear
+on the inside of a compound word.  This can be changed with the
+|spell-COMPOUNDPERMITFLAG|.
+
+							*spell-NEEDCOMPOUND*
+The NEEDCOMPOUND flag is used to require that a word is used as part of a
+compound word.  The word itself is not a good word.  Example:
+
+	NEEDCOMPOUND & ~
+
+							*spell-COMPOUNDMIN*
+The minimal character length of a word used for compounding is specified with
+COMPOUNDMIN.  Example:
+	COMPOUNDMIN 5 ~
+
+When omitted there is no minimal length.  Obviously you could just leave out
+the compound flag from short words instead, this feature is present for
+compatibility with Myspell.
+
+							*spell-COMPOUNDWORDMAX*
+The maximum number of words that can be concatenated into a compound word is
+specified with COMPOUNDWORDMAX.  Example:
+	COMPOUNDWORDMAX 3 ~
+
+When omitted there is no maximum.  It applies to all compound words.
+
+To set a limit for words with specific flags make sure the items in
+COMPOUNDRULE where they appear don't allow too many words.
+
+							*spell-COMPOUNDSYLMAX*
+The maximum number of syllables that a compound word may contain is specified
+with COMPOUNDSYLMAX.  Example:
+	COMPOUNDSYLMAX 6 ~
+
+This has no effect if there is no SYLLABLE item.  Without COMPOUNDSYLMAX there
+is no limit on the number of syllables.
+
+If both COMPOUNDWORDMAX and COMPOUNDSYLMAX are defined, a compound word is
+accepted if it fits one of the criteria, thus is either made from up to
+COMPOUNDWORDMAX words or contains up to COMPOUNDSYLMAX syllables.
+
+						    *spell-COMPOUNDFORBIDFLAG*
+The COMPOUNDFORBIDFLAG specifies a flag that can be used on an affix.  It
+means that the word plus affix cannot be used in a compound word.  Example:
+	affix file:
+		COMPOUNDFLAG c ~
+		COMPOUNDFORBIDFLAG x ~
+		SFX a Y 2 ~
+		SFX a 0 s   . ~
+		SFX a 0 ize/x . ~
+	dictionary:
+		word/c ~
+		util/ac ~
+
+This allows for "wordutil" and "wordutils" but not "wordutilize".
+Note: this doesn't work for postponed prefixes yet.
+
+						    *spell-COMPOUNDPERMITFLAG*
+The COMPOUNDPERMITFLAG specifies a flag that can be used on an affix.  It
+means that the word plus affix can also be used in a compound word in a way
+where the affix ends up halfway the word.  Without this flag that is not
+allowed.
+Note: this doesn't work for postponed prefixes yet.
+
+						    *spell-COMPOUNDROOT*
+The COMPOUNDROOT flag is used for words in the dictionary that are already a
+compound.  This means it counts for two words when checking the compounding
+rules.  Can also be used for an affix to count the affix as a compounding
+word.
+
+							*spell-SYLLABLE*
+The SYLLABLE item defines characters or character sequences that are used to
+count the number of syllables in a word.  Example:
+	SYLLABLE a�e�i�o���u���y/aa/au/ea/ee/ei/ie/oa/oe/oo/ou/uu/ui ~
+
+Before the first slash is the set of characters that are counted for one
+syllable, also when repeated and mixed, until the next character that is not
+in this set.  After the slash come sequences of characters that are counted
+for one syllable.  These are preferred over using characters from the set.
+With the example "ideeen" has three syllables, counted by "i", "ee" and "e".
+
+Only case-folded letters need to be included.
+
+Another way to restrict compounding was mentioned above: Adding the
+|spell-COMPOUNDFORBIDFLAG| flag to an affix causes all words that are made
+with that affix not be be used for compounding.
+
+
+UNLIMITED COMPOUNDING					*spell-NOBREAK*
+
+For some languages, such as Thai, there is no space in between words.  This
+looks like all words are compounded.  To specify this use the NOBREAK item in
+the affix file, without arguments:
+	NOBREAK ~
+
+Vim will try to figure out where one word ends and a next starts.  When there
+are spelling mistakes this may not be quite right.
+
+
+							*spell-COMMON*
+Common words can be specified with the COMMON item.  This will give better
+suggestions when editing a short file.  Example:
+
+	COMMON  the of to and a in is it you that he was for on are ~
+
+The words must be separated by white space, up to 25 per line.
+When multiple regions are specified in a ":mkspell" command the common words
+for all regions are combined and used for all regions.
+
+							*spell-NOSPLITSUGS*
+This item indicates that splitting a word to make suggestions is not a good
+idea.  Split-word suggestions will appear only when there are few similar
+words.
+
+	NOSPLITSUGS ~
+
+							*spell-NOSUGGEST*
+The flag specified with NOSUGGEST can be used for words that will not be
+suggested.  Can be used for obscene words.
+
+	NOSUGGEST % ~
+
+
+REPLACEMENTS						*spell-REP*
+
+In the affix file REP items can be used to define common mistakes.  This is
+used to make spelling suggestions.  The items define the "from" text and the
+"to" replacement.  Example:
+
+	REP 4 ~
+	REP f ph ~
+	REP ph f ~
+	REP k ch ~
+	REP ch k ~
+
+The first line specifies the number of REP lines following.  Vim ignores the
+number, but it must be there (for compatibility with Myspell).
+
+Don't include simple one-character replacements or swaps.  Vim will try these
+anyway.  You can include whole words if you want to, but you might want to use
+the "file:" item in 'spellsuggest' instead.
+
+You can include a space by using an underscore:
+
+	REP the_the the ~
+
+
+SIMILAR CHARACTERS					*spell-MAP* *E783*
+
+In the affix file MAP items can be used to define letters that are very much
+alike.  This is mostly used for a letter with different accents.  This is used
+to prefer suggestions with these letters substituted.  Example:
+
+	MAP 2 ~
+	MAP e���� ~
+	MAP u���� ~
+
+The first line specifies the number of MAP lines following.  Vim ignores the
+number, but the line must be there.
+
+Each letter must appear in only one of the MAP items.  It's a bit more
+efficient if the first letter is ASCII or at least one without accents.
+
+
+.SUG FILE						*spell-NOSUGFILE*
+
+When soundfolding is specified in the affix file then ":mkspell" will normally
+produce a .sug file next to the .spl file.  This file is used to find
+suggestions by their sound-a-like form quickly.  At the cost of a lot of
+memory (the amount depends on the number of words, |:mkspell| will display an
+estimate when it's done).
+
+To avoid producing a .sug file use this item in the affix file:
+
+	NOSUGFILE ~
+
+Users can simply omit the .sug file if they don't want to use it.
+
+
+SOUND-A-LIKE						*spell-SAL*
+
+In the affix file SAL items can be used to define the sounds-a-like mechanism
+to be used.  The main items define the "from" text and the "to" replacement.
+Simplistic example:
+
+	SAL CIA			 X ~
+	SAL CH			 X ~
+	SAL C			 K ~
+	SAL K			 K ~
+
+There are a few rules and this can become quite complicated.  An explanation
+how it works can be found in the Aspell manual:
+http://aspell.net/man-html/Phonetic-Code.html.
+
+There are a few special items:
+
+	SAL followup		true ~
+	SAL collapse_result	true ~
+	SAL remove_accents	true ~
+
+"1" has the same meaning as "true".  Any other value means "false".
+
+
+SIMPLE SOUNDFOLDING				*spell-SOFOFROM* *spell-SOFOTO*
+
+The SAL mechanism is complex and slow.  A simpler mechanism is mapping all
+characters to another character, mapping similar sounding characters to the
+same character.  At the same time this does case folding.  You can not have
+both SAL items and simple soundfolding.
+
+There are two items required: one to specify the characters that are mapped
+and one that specifies the characters they are mapped to.  They must have
+exactly the same number of characters.  Example:
+
+    SOFOFROM abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ ~
+    SOFOTO   ebctefghejklnnepkrstevvkesebctefghejklnnepkrstevvkes ~
+
+In the example all vowels are mapped to the same character 'e'.  Another
+method would be to leave out all vowels.  Some characters that sound nearly
+the same and are often mixed up, such as 'm' and 'n', are mapped to the same
+character.  Don't do this too much, all words will start looking alike.
+
+Characters that do not appear in SOFOFROM will be left out, except that all
+white space is replaced by one space.  Sequences of the same character in
+SOFOFROM are replaced by one.
+
+You can use the |soundfold()| function to try out the results.  Or set the
+'verbose' option to see the score in the output of the |z=| command.
+
+
+UNSUPPORTED ITEMS				*spell-affix-not-supported*
+
+These items appear in the affix file of other spell checkers.  In Vim they are
+ignored, not supported or defined in another way.
+
+ACCENT		(Hunspell)				*spell-ACCENT*
+		Use MAP instead. |spell-MAP|
+
+CHECKCOMPOUNDCASE  (Hunspell)			*spell-CHECKCOMPOUNDCASE*
+		Disallow uppercase letters at compound word boundaries.
+		Not supported.
+
+CHECKCOMPOUNDDUP  (Hunspell)			*spell-CHECKCOMPOUNDDUP*
+		Disallow using the same word twice in a compound.  Not
+		supported.
+
+CHECKCOMPOUNDREP  (Hunspell)			*spell-CHECKCOMPOUNDREP*
+		Something about using REP items and compound words.  Not
+		supported.
+
+CHECKCOMPOUNDTRIPLE  (Hunspell)			*spell-CHECKCOMPOUNDTRIPLE*
+		Forbid three identical characters when compounding.  Not
+		supported.
+
+CHECKCOMPOUNDPATTERN  (Hunspell)		*spell-CHECKCOMPOUNDPATTERN*
+		Forbid compounding when patterns match.  Not supported.
+
+COMPLEXPREFIXES  (Hunspell)				*spell-COMPLEXPREFIXES*
+		Enables using two prefixes.  Not supported.
+
+COMPOUND	(Hunspell)				*spell-COMPOUND*
+		This is one line with the count of COMPOUND items, followed by
+		that many COMPOUND lines with a pattern.
+		Remove the first line with the count and rename the other
+		items to COMPOUNDRULE |spell-COMPOUNDRULE|
+
+COMPOUNDFIRST	(Hunspell)				*spell-COMPOUNDFIRST*
+		Use COMPOUNDRULE instead. |spell-COMPOUNDRULE|
+
+COMPOUNDBEGIN	(Hunspell)				*spell-COMPOUNDBEGIN*
+		Use COMPOUNDRULE instead. |spell-COMPOUNDRULE|
+
+COMPOUNDEND	(Hunspell)				*spell-COMPOUNDEND*
+		Use COMPOUNDRULE instead. |spell-COMPOUNDRULE|
+
+COMPOUNDMIDDLE	(Hunspell)				*spell-COMPOUNDMIDDLE*
+		Use COMPOUNDRULE instead. |spell-COMPOUNDRULE|
+
+COMPOUNDSYLLABLE  (Hunspell)			*spell-COMPOUNDSYLLABLE*
+		Use SYLLABLE and COMPOUNDSYLMAX instead. |spell-SYLLABLE|
+		|spell-COMPOUNDSYLMAX|
+
+FORBIDDENWORD	(Hunspell)				*spell-FORBIDDENWORD*
+		Use BAD instead. |spell-BAD|
+
+LANG		(Hunspell)				*spell-LANG*
+		This specifies language-specific behavior.  This actually
+		moves part of the language knowledge into the program,
+		therefore Vim does not support it.  Each language property
+		must be specified separately.
+
+LEMMA_PRESENT	(Hunspell)				*spell-LEMMA_PRESENT*
+		Only needed for morphological analysis.
+
+MAXNGRAMSUGS	(Hunspell)				*spell-MAXNGRAMSUGS*
+		Not supported.
+
+ONLYINCOMPOUND	(Hunspell)				*spell-ONLYINCOMPOUND*
+		Use NEEDCOMPOUND instead. |spell-NEEDCOMPOUND|
+
+PSEUDOROOT	(Hunspell)				*spell-PSEUDOROOT*
+		Use NEEDAFFIX instead. |spell-NEEDAFFIX|
+
+SUGSWITHDOTS	(Hunspell)				*spell-SUGSWITHDOTS*
+		Adds dots to suggestions.  Vim doesn't need this.
+
+SYLLABLENUM	(Hunspell)				*spell-SYLLABLENUM*
+		Not supported.
+
+TRY		(Myspell, Hunspell, others)		*spell-TRY*
+		Vim does not use the TRY item, it is ignored.  For making
+		suggestions the actual characters in the words are used, that
+		is much more efficient.
+
+WORDCHARS	(Hunspell)				*spell-WORDCHARS*
+		Used to recognize words.  Vim doesn't need it, because there
+		is no need to separate words before checking them (using a
+		trie instead of a hashtable).
+
+ vim:tw=78:sw=4:ts=8:ft=help:norl:
--- /dev/null
+++ b/lib/vimfiles/doc/sponsor.txt
@@ -1,0 +1,216 @@
+*sponsor.txt*   For Vim version 7.1.  Last change: 2007 Jan 05
+
+
+		  VIM REFERENCE MANUAL    by Bram Moolenaar
+
+
+
+SPONSOR VIM DEVELOPMENT						*sponsor*
+
+Fixing bugs and adding new features takes a lot of time and effort.  To show
+your appreciation for the work and motivate Bram and others to continue
+working on Vim please send a donation.
+
+Since Bram is back to a paid job the money will now be used to help children
+in Uganda.  See |uganda|.  But at the same time donations increase Bram's
+motivation to keep working on Vim!
+
+For the most recent information about sponsoring look on the Vim web site:
+
+	http://www.vim.org/sponsor/
+
+More explanations can be found in the |sponsor-faq|.
+
+
+REGISTERED VIM USER						*register*
+
+You can become a registered Vim user by sending at least 10 euro.  This works
+similar to sponsoring Vim, see |sponsor| above.  Registration was made
+possible for the situation where your boss or bookkeeper may be willing to
+register software, but does not like the terms "sponsoring" and "donation".
+
+More explanations can be found in the |register-faq|.
+
+
+VOTE FOR FEATURES					*vote-for-features*
+
+To give registered Vim users and sponsors an advantage over lurkers they can
+vote for the items Bram should work on.  How does this voting work?
+
+1.  You send at least 10 euro.  See below for ways to transfer money
+    |send-money|.
+
+2.  You will be e-mailed a registration key.  Enter this key on your account
+    page on the Vim website.  You can easily create an account if you don't
+    have one yet.
+
+3.  You can enter your votes on the voting page.  There is a link to that page
+    on your account page after entering a registration key.  Your votes will
+    be counted for two years.
+
+4.  The voting results appear on the results page, which is visible for
+    everybody:  http://www.vim.org/sponsor/vote_results.php
+
+Additionally, once you have send 100 euro or more in total, your name appears
+in the "Vim hall of honour":   http://www.vim.org/sponsor/hall_of_honour.php
+But only if you enable this on your account page.
+
+
+HOW TO SEND MONEY						*send-money*
+
+Credit card	Through PayPal, see the PayPal site for information:
+			https://www.paypal.com/en_US/mrb/pal=XAC62PML3GF8Q
+		The e-mail address for sending sponsorship money is:
+			donate@vim.org
+		The e-mail address for Vim registration is:
+			register@vim.org
+		Using Euro is preferred, other currencies are also accepted.
+		In Euro countries a bank transfer is preferred, this has lower
+		costs.
+
+Other methods	See |iccf-donations|.
+		Include "Vim sponsor" or "Vim registration" in the comment of
+		your money transfer.  Send me an e-mail that mentions the
+		amount you transferred if you want to vote for features and
+		show others you are a registered Vim user or sponsor.
+
+Cash		Small amounts can be send with ordinary mail.  Put something
+		around the money, so that it's not noticeable from the
+		outside.  Mention your e-mail address if you want to vote for
+		features and show others you are a registered Vim user or
+		sponsor.
+
+You can use this permanent address:
+			Bram Moolenaar
+			Molenstraat 2
+			2161 HP Lisse
+			The Netherlands
+
+
+
+QUESTIONS AND ANSWERS				*sponsor-faq* *register-faq*
+
+Why should I give money?
+
+If you do not show your appreciation for Vim then Bram will be less motivated
+to fix bugs and add new features.  He will do something else instead.
+
+
+How much money should I send?
+
+That is up to you.  The more you give, the more children will be helped.
+An indication for individuals that use Vim at home: 10 Euro per year.  For
+professional use: 30 Euro per year per person.  Send at least 10 euro to be
+able to vote for features.
+
+
+What do I get in return?
+
+Each registered Vim user and sponsor who donates at least 10 euro will be able
+to vote for new features.  These votes will give priority to the work on Vim.
+The votes are valid for two years.  The more money you send the more your
+votes count |votes-counted|.
+
+If you send 100 Euro or more in total you will be mentioned on the "Vim hall
+of honour" page on the Vim web site.  But only if you enable this on your
+account page.  You can also select whether the amount will be visible.
+
+
+How do I become a Vim sponsor or registered Vim user?
+
+Send money, as explained above |send-money| and include your e-mail address.
+When the money has been received you will receive a unique registration key.
+This key can be used on the Vim website to activate voting on your Vim
+account.  You will then get an extra page where you can vote for features and
+choose whether others will be able to see that you donated.  There is a link
+to this page on your "My Account" page.
+
+
+What is the difference between sponsoring and registering?
+
+It has a different name.  Use the term "registration" if your boss doesn't
+like "sponsoring" or "donation".  The benefits are the same.
+
+
+How can I send money?
+
+See |send-money|.  Check the web site for the most recent information:
+http://www.vim.org/sponsor/
+
+
+Why don't you use the SourceForge donation system?
+
+SourceForge takes 5% of the donations for themselves.  If you want to support
+SourceForge you can send money to them directly.
+
+
+I cannot afford to send money, may I still use Vim?
+
+Yes.
+
+
+I did not register Vim, can I use all available features?
+
+Yes.
+
+
+I noticed a bug, do I need to register before I can report it?
+
+No, suggestions for improving Vim can always be given.  For improvements use
+the developer |maillist|, for reporting bugs see |bugs|.
+
+
+How are my votes counted?				*votes-counted*
+
+You may vote when you send 10 euro or more.  You can enter up to ten votes.
+You can select the same item several times to give it more points.  You can
+also enter three counter votes, these count as negative points.
+
+When you send 30 euro or more the points are doubled.  Above 100 euro they
+count four times, above 300 euro they count six times, above 1000 euro ten
+times.
+
+
+Can I change my votes?
+
+You can change your votes any time you like, up to two years after you
+sent money.  The points will be counted right away.
+
+
+Can I add an item to vote on?
+
+Not directly.  You can suggest items to vote on to Bram.  He will consider
+fitting your item into the list.
+
+
+How about Charityware?
+
+Currently the Vim donations go to |uganda| anyway.  Thus it doesn't matter if
+you sponsor Vim or ICCF.  Except that Vim sponsoring will allow you to vote
+for features.
+
+
+I donated $$$, now please add feature XYZ!
+
+There is no direct relation between your donation and the work Bram does.
+Otherwise you would be paying for work and we would have to pay tax over the
+donation.  If you want to hire Bram for specific work, contact him directly,
+don't use the donation system.
+
+
+Are the donations tax deductible?
+
+That depends on your country.  The donations to help the children in |Uganda|
+are tax deductible in Holland, Germany, Canada and in the USA.  See the ICCF
+website http://iccf-holland.org/donate.html.  You must send an e-mail to Bram
+to let him know that the donation is done because of the use of Vim.
+
+
+Can you send me a bill?
+
+No, because there is no relation between the money you send and the work that
+is done.  But a receipt is possible.
+
+
+
+ vim:tw=78:ts=8:ft=help:norl:
--- /dev/null
+++ b/lib/vimfiles/doc/sql.txt
@@ -1,0 +1,763 @@
+*sql.txt*	For Vim version 7.1.  Last change: Wed Apr 26 2006 3:05:33 PM
+
+by David Fishburn
+
+This is a filetype plugin to work with SQL files.
+
+The Structured Query Language (SQL) is a standard which specifies statements
+that allow a user to interact with a relational database.  Vim includes
+features for navigation, indentation and syntax highlighting.
+
+1. Navigation					|sql-navigation|
+    1.1 Matchit					|sql-matchit|
+    1.2 Text Object Motions			|sql-object-motions|
+    1.3 Predefined Object Motions		|sql-predefined-objects|
+    1.4 Macros					|sql-macros|
+2. SQL Dialects					|sql-dialects|
+    2.1 SQLSetType				|SQLSetType|
+    2.2 SQL Dialect Default			|sql-type-default|
+3. Adding new SQL Dialects			|sql-adding-dialects|
+4. OMNI SQL Completion				|sql-completion|
+    4.1 Static mode				|sql-completion-static|
+    4.2 Dynamic mode				|sql-completion-dynamic|
+    4.3 Tutorial				|sql-completion-tutorial|
+	4.3.1 Complete Tables			|sql-completion-tables|
+	4.3.2 Complete Columns			|sql-completion-columns|
+	4.3.3 Complete Procedures		|sql-completion-procedures|
+	4.3.4 Complete Views			|sql-completion-views|
+    4.4 Completion Customization		|sql-completion-customization|
+    4.5 SQL Maps				|sql-completion-maps|
+    4.6 Using with other filetypes		|sql-completion-filetypes|
+
+==============================================================================
+1. Navigation					*sql-navigation*
+
+The SQL ftplugin provides a number of options to assist with file
+navigation.
+
+
+1.1 Matchit					*sql-matchit*
+-----------
+The matchit plugin (http://www.vim.org/scripts/script.php?script_id=39)
+provides many additional features and can be customized for different
+languages.  The matchit plugin is configured by defining a local
+buffer variable, b:match_words.  Pressing the % key while on various
+keywords will move the cursor to its match.  For example, if the cursor
+is on an "if", pressing % will cycle between the "else", "elseif" and
+"end if" keywords.
+
+The following keywords are supported: >
+    if
+    elseif | elsif
+    else [if]
+    end if
+
+    [while condition] loop
+	leave
+	break
+	continue
+	exit
+    end loop
+
+    for
+	leave
+	break
+	continue
+	exit
+    end loop
+
+    do
+	statements
+    doend
+
+    case
+    when
+    when
+    default
+    end case
+
+    merge
+    when not matched
+    when matched
+
+    create[ or replace] procedure|function|event
+    returns
+
+
+1.2 Text Object Motions				*sql-object-motions*
+-----------------------
+Vim has a number of predefined keys for working with text |object-motions|.
+This filetype plugin attempts to translate these keys to maps which make sense
+for the SQL language.
+
+The following |Normal| mode and |Visual| mode maps exist (when you edit a SQL
+file): >
+    ]]		    move forward to the next 'begin'
+    [[		    move backwards to the previous 'begin'
+    ][		    move forward to the next 'end'
+    []		    move backwards to the previous 'end'
+
+
+1.3 Predefined Object Motions			*sql-predefined-objects*
+-----------------------------
+Most relational databases support various standard features, tables, indices,
+triggers and stored procedures.  Each vendor also has a variety of proprietary
+objects.  The next set of maps have been created to help move between these
+objects.  Depends on which database vendor you are using, the list of objects
+must be configurable.  The filetype plugin attempts to define many of the
+standard objects, plus many additional ones.  In order to make this as
+flexible as possible, you can override the list of objects from within your
+|vimrc| with the following: >
+    let g:ftplugin_sql_objects = 'function,procedure,event,table,trigger' .
+		\ ',schema,service,publication,database,datatype,domain' .
+		\ ',index,subscription,synchronization,view,variable'
+
+The following |Normal| mode and |Visual| mode maps have been created which use
+the above list: >
+    ]}		    move forward to the next 'create <object name>'
+    [{		    move backward to the previous 'create <object name>'
+
+Repeatedly pressing ]} will cycle through each of these create statements: >
+    create table t1 (
+	...
+    );
+
+    create procedure p1
+    begin
+	...
+    end;
+
+    create index i1 on t1 (c1);
+
+The default setting for g:ftplugin_sql_objects is: >
+    let g:ftplugin_sql_objects = 'function,procedure,event,' .
+		\ '\\(existing\\\\|global\\s\\+temporary\\s\\+\\)\\\{,1}' .
+		\ 'table,trigger' .
+		\ ',schema,service,publication,database,datatype,domain' .
+		\ ',index,subscription,synchronization,view,variable'
+
+The above will also handle these cases: >
+    create table t1 (
+	...
+    );
+    create existing table t2 (
+	...
+    );
+    create global temporary table t3 (
+	...
+    );
+
+By default, the ftplugin only searches for CREATE statements.  You can also
+override this via your |vimrc| with the following: >
+    let g:ftplugin_sql_statements = 'create,alter'
+
+The filetype plugin defines three types of comments: >
+    1.  --
+    2.  //
+    3.  /*
+	 *
+	 */
+
+The following |Normal| mode and |Visual| mode maps have been created to work
+with comments: >
+    ]"		    move forward to the beginning of a comment
+    ["		    move forward to the end of a comment
+
+
+
+1.4 Macros					   *sql-macros*
+----------
+Vim's feature to find macro definitions, |'define'|, is supported using this
+regular expression: >
+    \c\<\(VARIABLE\|DECLARE\|IN\|OUT\|INOUT\)\>
+
+This addresses the following code: >
+    CREATE VARIABLE myVar1 INTEGER;
+
+    CREATE PROCEDURE sp_test(
+	IN myVar2 INTEGER,
+	OUT myVar3 CHAR(30),
+	INOUT myVar4 NUMERIC(20,0)
+    )
+    BEGIN
+	DECLARE myVar5 INTEGER;
+
+	SELECT c1, c2, c3
+	  INTO myVar2, myVar3, myVar4
+	  FROM T1
+	 WHERE c4 = myVar1;
+    END;
+
+Place your cursor on "myVar1" on this line: >
+	 WHERE c4 = myVar1;
+		     ^
+
+Press any of the following keys: >
+    [d
+    [D
+    [CTRL-D
+
+
+==============================================================================
+2. SQL Dialects					*sql-dialects* *sql-types*
+						*sybase* *TSQL* *Transact-SQL*
+						*sqlanywhere*
+						*oracle* *plsql* *sqlj*
+						*sqlserver*
+						*mysql* *postgres* *psql*
+						*informix*
+
+All relational databases support SQL.  There is a portion of SQL that is
+portable across vendors (ex. CREATE TABLE, CREATE INDEX), but there is a
+great deal of vendor specific extensions to SQL.  Oracle supports the
+"CREATE OR REPLACE" syntax, column defaults specified in the CREATE TABLE
+statement and the procedural language (for stored procedures and triggers).
+
+The default Vim distribution ships with syntax highlighting based on Oracle's
+PL/SQL.  The default SQL indent script works for Oracle and SQL Anywhere.
+The default filetype plugin works for all vendors and should remain vendor
+neutral, but extendable.
+
+Vim currently has support for a variety of different vendors, currently this
+is via syntax scripts. Unfortunately, to flip between different syntax rules
+you must either create:
+    1.  New filetypes
+    2.  Custom autocmds
+    3.  Manual steps / commands
+
+The majority of people work with only one vendor's database product, it would
+be nice to specify a default in your |vimrc|.
+
+
+2.1 SQLSetType					*sqlsettype* *SQLSetType*
+--------------
+For the people that work with many different databases, it would be nice to be
+able to flip between the various vendors rules (indent, syntax) on a per
+buffer basis, at any time.  The ftplugin/sql.vim file defines this function: >
+    SQLSetType
+
+Executing this function without any parameters will set the indent and syntax
+scripts back to their defaults, see |sql-type-default|.  If you have turned
+off Vi's compatibility mode, |'compatible'|, you can use the <Tab> key to
+complete the optional parameter.
+
+After typing the function name and a space, you can use the completion to
+supply a parameter.  The function takes the name of the Vim script you want to
+source.  Using the |cmdline-completion| feature, the SQLSetType function will
+search the |'runtimepath'| for all Vim scripts with a name containing 'sql'.
+This takes the guess work out of the spelling of the names.  The following are
+examples: >
+    :SQLSetType
+    :SQLSetType sqloracle
+    :SQLSetType sqlanywhere
+    :SQLSetType sqlinformix
+    :SQLSetType mysql
+
+The easiest approach is to the use <Tab> character which will first complete
+the command name (SQLSetType), after a space and another <Tab>, display a list
+of available Vim script names: >
+    :SQL<Tab><space><Tab>
+
+
+2.2 SQL Dialect Default				*sql-type-default*
+-----------------------
+As mentioned earlier, the default syntax rules for Vim is based on Oracle
+(PL/SQL).  You can override this default by placing one of the following in
+your |vimrc|: >
+    let g:sql_type_default = 'sqlanywhere'
+    let g:sql_type_default = 'sqlinformix'
+    let g:sql_type_default = 'mysql'
+
+If you added the following to your |vimrc|: >
+    let g:sql_type_default = 'sqlinformix'
+
+The next time edit a SQL file the following scripts will be automatically
+loaded by Vim: >
+    ftplugin/sql.vim
+    syntax/sqlinformix.vim
+    indent/sql.vim
+>
+Notice indent/sqlinformix.sql was not loaded.  There is no indent file
+for Informix, Vim loads the default files if the specified files does not
+exist.
+
+
+==============================================================================
+3. Adding new SQL Dialects			*sql-adding-dialects*
+
+If you begin working with a SQL dialect which does not have any customizations
+available with the default Vim distribution you can check http://www.vim.org
+to see if any customization currently exist.  If not, you can begin by cloning
+an existing script.  Read |filetype-plugins| for more details.
+
+To help identify these scripts, try to create the files with a "sql" prefix.
+If you decide you wish to create customizations for the SQLite database, you
+can create any of the following: >
+    Unix
+	~/.vim/syntax/sqlite.vim
+	~/.vim/indent/sqlite.vim
+    Windows
+	$VIM/vimfiles/syntax/sqlite.vim
+	$VIM/vimfiles/indent/sqlite.vim
+
+No changes are necessary to the SQLSetType function.  It will automatically
+pickup the new SQL files and load them when you issue the SQLSetType command.
+
+
+==============================================================================
+4. OMNI SQL Completion				*sql-completion*
+						*omni-sql-completion*
+
+Vim 7 includes a code completion interface and functions which allows plugin
+developers to build in code completion for any language.  Vim 7 includes
+code completion for the SQL language.
+
+There are two modes to the SQL completion plugin, static and dynamic.  The
+static mode populates the popups with the data generated from current syntax
+highlight rules.  The dynamic mode populates the popups with data retrieved
+directly from a database.  This includes, table lists, column lists,
+procedures names and more.
+
+4.1 Static Mode					*sql-completion-static*
+---------------
+The static popups created contain items defined by the active syntax rules
+while editing a file with a filetype of SQL.  The plugin defines (by default)
+various maps to help the user refine the list of items to be displayed.
+The defaults static maps are: >
+    imap <buffer> <C-C>a <C-\><C-O>:call sqlcomplete#Map('syntax')<CR><C-X><C-O>
+    imap <buffer> <C-C>k <C-\><C-O>:call sqlcomplete#Map('sqlKeyword')<CR><C-X><C-O>
+    imap <buffer> <C-C>f <C-\><C-O>:call sqlcomplete#Map('sqlFunction')<CR><C-X><C-O>
+    imap <buffer> <C-C>o <C-\><C-O>:call sqlcomplete#Map('sqlOption')<CR><C-X><C-O>
+    imap <buffer> <C-C>T <C-\><C-O>:call sqlcomplete#Map('sqlType')<CR><C-X><C-O>
+    imap <buffer> <C-C>s <C-\><C-O>:call sqlcomplete#Map('sqlStatement')<CR><C-X><C-O>
+
+The static maps (which are based on the syntax highlight groups) follow this
+format: >
+    imap <buffer> <C-C>k <C-\><C-O>:call sqlcomplete#Map('sqlKeyword')<CR><C-X><C-O>
+
+This command breaks down as: >
+    imap		   - Create an insert map
+    <buffer>		   - Only for this buffer
+    <C-C>k		   - Your choice of key map
+    <C-\><C-O>		   - Execute one command, return to Insert mode
+    :call sqlcomplete#Map( - Allows the SQL completion plugin to perform some
+			     housekeeping functions to allow it to be used in
+			     conjunction with other completion plugins.
+			     Indicate which item you want the SQL completion
+			     plugin to complete.
+			     In this case we are asking the plugin to display
+			     items from the syntax highlight group
+			     'sqlKeyword'.
+			     You can view a list of highlight group names to
+			     choose from by executing the
+				 :syntax list
+			     command while editing a SQL file.
+    'sqlKeyword'	   - Display the items for the sqlKeyword highlight
+			     group
+    )<CR>		   - Execute the :let command
+    <C-X><C-O>		   - Trigger the standard omni completion key stroke.
+			     Passing in 'sqlKeyword' instructs the SQL
+			     completion plugin to populate the popup with
+			     items from the sqlKeyword highlight group.  The
+			     plugin will also cache this result until Vim is
+			     restarted.  The syntax list is retrieved using
+			     the syntaxcomplete plugin.
+
+Using the 'syntax' keyword is a special case.  This instructs the
+syntaxcomplete plugin to retrieve all syntax items.  So this will effectively
+work for any of Vim's SQL syntax files.  At the time of writing this includes
+10 different syntax files for the different dialects of SQL (see section 3
+above, |sql-dialects|).
+
+Here are some examples of the entries which are pulled from the syntax files: >
+     All
+	 - Contains the contents of all syntax highlight groups
+     Statements
+	 - Select, Insert, Update, Delete, Create, Alter, ...
+     Functions
+	 - Min, Max, Trim, Round, Date, ...
+     Keywords
+	 - Index, Database, Having, Group, With
+     Options
+	 - Isolation_level, On_error, Qualify_owners, Fire_triggers, ...
+     Types
+	 - Integer, Char, Varchar, Date, DateTime, Timestamp, ...
+
+
+4.2 Dynamic Mode				*sql-completion-dynamic*
+----------------
+Dynamic mode populates the popups with data directly from a database.  In
+order for the dynamic feature to be enabled you must have the dbext.vim
+plugin installed, (http://vim.sourceforge.net/script.php?script_id=356).
+
+Dynamic mode is used by several features of the SQL completion plugin.
+After installing the dbext plugin see the dbext-tutorial for additional
+configuration and usage.  The dbext plugin allows the SQL completion plugin
+to display a list of tables, procedures, views and columns. >
+     Table List
+	 - All tables for all schema owners
+     Procedure List
+	 - All stored procedures for all schema owners
+     View List
+	 - All stored procedures for all schema owners
+     Column List
+	 - For the selected table, the columns that are part of the table
+
+To enable the popup, while in INSERT mode, use the following key combinations
+for each group (where <C-C> means hold the CTRL key down while pressing
+the space bar):
+     Table List		    - <C-C>t
+			    - <C-X><C-O> (the default map assumes tables)
+     Stored Procedure List  - <C-C>p
+     View List		    - <C-C>v
+     Column List	    - <C-C>c
+
+     Windows platform only  - When viewing a popup window displaying the list
+			      of tables, you can press <C-Right>, this will
+			      replace the table currently highlighted with
+			      the column list for that table.
+			    - When viewing a popup window displaying the list
+			      of columns, you can press <C-Left>, this will
+			      replace the column list with the list of tables.
+			    - This allows you to quickly drill down into a
+			      table to view it's columns and back again.
+
+The SQL completion plugin caches various lists that are displayed in
+the popup window.  This makes the re-displaying of these lists very
+fast.  If new tables or columns are added to the database it may become
+necessary to clear the plugins cache.  The default map for this is: >
+    imap <buffer> <C-C>R <C-\><C-O>:call sqlcomplete#Map('ResetCache')<CR><C-X><C-O>
+
+
+4.3 SQL Tutorial				*sql-completion-tutorial*
+----------------
+
+This tutorial is designed to take you through the common features of the SQL
+completion plugin so that: >
+     a) You gain familiarity with the plugin
+     b) You are introduced to some of the more common features
+     c) Show how to customize it to your preferences
+     d) Demonstrate "Best of Use" of the plugin (easiest way to configure).
+
+First, create a new buffer: >
+     :e tutorial.sql
+
+
+Static features
+---------------
+To take you through the various lists, simply enter insert mode, hit:
+    <C-C>s   (show SQL statements)
+At this point, you can page down through the list until you find "select".
+If you are familiar with the item you are looking for, for example you know
+the statement begins with the letter "s".  You can type ahead (without the
+quotes) "se" then press:
+    <C-Space>t
+Assuming "select" is highlighted in the popup list press <Enter> to choose
+the entry.  Now type:
+    * fr<C-C>a (show all syntax items)
+choose "from" from the popup list.
+
+When writing stored procedures using the "type" list is useful.  It contains
+a list of all the database supported types.  This may or may not be true
+depending on the syntax file you are using.  The SQL Anywhere syntax file
+(sqlanywhere.vim) has support for this: >
+     BEGIN
+	DECLARE customer_id <C-C>T <-- Choose a type from the list
+
+
+Dynamic features
+----------------
+To take advantage of the dynamic features you must first install the
+dbext.vim plugin (http://vim.sourceforge.net/script.php?script_id=356).  It
+also comes with a tutorial.  From the SQL completion plugin's perspective,
+the main feature dbext provides is a connection to a database.  dbext
+connection profiles are the most efficient mechanism to define connection
+information.  Once connections have been setup, the SQL completion plugin
+uses the features of dbext in the background to populate the popups.
+
+What follows assumes dbext.vim has been correctly configured, a simple test
+is to run the command, :DBListTable.  If a list of tables is shown, you know
+dbext.vim is working as expected.  If not, please consult the dbext.txt
+documentation.
+
+Assuming you have followed the dbext-tutorial you can press <C-C>t to
+display a list of tables.  There is a delay while dbext is creating the table
+list.  After the list is displayed press <C-W>.  This will remove both the
+popup window and the table name already chosen when the list became active. >
+
+ 4.3.1 Table Completion:			*sql-completion-tables*
+
+Press <C-C>t to display a list of tables from within the database you
+have connected via the dbext plugin.
+NOTE: All of the SQL completion popups support typing a prefix before pressing
+the key map.  This will limit the contents of the popup window to just items
+beginning with those characters.  >
+
+ 4.3.2 Column Completion:			*sql-completion-columns*
+
+The SQL completion plugin can also display a list of columns for particular
+tables.  The column completion is trigger via <C-C>c.
+
+NOTE: The following example uses <C-Right> to trigger a column list while
+the popup window is active.  This map is only available on the Windows
+platforms since *nix does not recognize CTRL and the right arrow held down
+together.  If you wish to enable this functionality on a *nix platform choose
+a key and create one of these mappings (see |sql-completion-maps| for further
+details on where to create this imap): >
+    imap <buffer> <your_keystroke> <C-R>=sqlcomplete#DrillIntoTable()<CR>
+    imap <buffer> <your_keystroke> <C-Y><C-\><C-O>:call sqlcomplete#Map('column')<CR><C-X><C-O>
+
+Example of using column completion:
+     - Press <C-C>t again to display the list of tables.
+     - When the list is displayed in the completion window, press <C-Right>,
+       this will replace the list of tables, with a list of columns for the
+       table highlighted (after the same short delay).
+     - If you press <C-Left>, this will again replace the column list with the
+       list of tables.  This allows you to drill into tables and column lists
+       very quickly.
+     - Press <C-Right> again while the same table is highlighted.  You will
+       notice there is no delay since the column list has been cached.  If you
+       change the schema of a cached table you can press <C-C>R, which
+       clears the SQL completion cache.
+     - NOTE: <C-Right> and <C-Left> have been designed to work while the
+       completion window is active.  If the completion popup window is
+       not active, a normal <C-Right> or <C-Left> will be executed.
+
+Lets look how we can build a SQL statement dynamically.  A select statement
+requires a list of columns.  There are two ways to build a column list using
+the SQL completion plugin. >
+    One column at a time:
+<       1. After typing SELECT press <C-C>t to display a list of tables.
+	2. Choose a table from the list.
+	3. Press <C-Right> to display a list of columns.
+	4. Choose the column from the list and press enter.
+	5. Enter a "," and press <C-C>c.  Generating a column list
+	   generally requires having the cursor on a table name.  The plugin
+	   uses this name to determine what table to retrieve the column list.
+	   In this step, since we are pressing <C-C>c without the cursor
+	   on a table name the column list displayed will be for the previous
+	   table.  Choose a different column and move on.
+	6. Repeat step 5 as often as necessary. >
+    All columns for a table:
+<	1. After typing SELECT press <C-C>t to display a list of tables.
+	2. Highlight the table you need the column list for.
+	3. Press <Enter> to choose the table from the list.
+	4. Press <C-C>l to request a comma separated list of all columns
+	   for this table.
+	5. Based on the table name chosen in step 3, the plugin attempts to
+	   decide on a reasonable table alias.	You are then prompted to
+	   either accept of change the alias.  Press OK.
+	6. The table name is replaced with the column list of the table is
+	   replaced with the comma separate list of columns with the alias
+	   prepended to each of the columns.
+	7. Step 3 and 4 can be replaced by pressing <C-C>L, which has
+	   a <C-Y> embedded in the map to choose the currently highlighted
+	   table in the list.
+
+There is a special provision when writing select statements.  Consider the
+following statement: >
+     select *
+       from customer c,
+	    contact cn,
+	    department as dp,
+	    employee e,
+	    site_options so
+      where c.
+
+In INSERT mode after typing the final "c." which is an alias for the
+"customer" table, you can press either <C-C>c or <C-X><C-O>.  This will
+popup a list of columns for the customer table.  It does this by looking back
+to the beginning of the select statement and finding a list of the tables
+specified in the FROM clause.  In this case it notes that in the string
+"customer c", "c" is an alias for the customer table.  The optional "AS"
+keyword is also supported, "customer AS c". >
+
+
+ 4.3.3 Procedure Completion:			*sql-completion-procedures*
+
+Similar to the table list, <C-C>p, will display a list of stored
+procedures stored within the database. >
+
+ 4.3.4 View Completion:				*sql-completion-views*
+
+Similar to the table list, <C-C>v, will display a list of views in the
+database.
+
+
+4.4 Completion Customization			*sql-completion-customization*
+----------------------------
+
+The SQL completion plugin can be customized through various options set in
+your |vimrc|: >
+    omni_sql_no_default_maps
+<       - Default: This variable is not defined
+	- If this variable is defined, no maps are created for OMNI
+	  completion.  See |sql-completion-maps| for further discussion.
+>
+    omni_sql_use_tbl_alias
+<	- Default: a
+	- This setting is only used when generating a comma separated
+	  column list.	By default the map is <C-C>l.  When generating
+	  a column list, an alias can be prepended to the beginning of each
+	  column, for example:	e.emp_id, e.emp_name.  This option has three
+	  settings: >
+		n - do not use an alias
+		d - use the default (calculated) alias
+		a - ask to confirm the alias name
+<
+	  An alias is determined following a few rules:
+	       1.  If the table name has an '_', then use it as a separator: >
+		   MY_TABLE_NAME --> MTN
+		   my_table_name --> mtn
+		   My_table_NAME --> MtN
+<	       2.  If the table name does NOT contain an '_', but DOES use
+		   mixed case then the case is used as a separator: >
+		   MyTableName --> MTN
+<	       3.  If the table name does NOT contain an '_', and does NOT
+		   use mixed case then the first letter of the table is used: >
+		   mytablename --> m
+		   MYTABLENAME --> M
+
+    omni_sql_ignorecase
+<	- Default: Current setting for|ignorecase|
+	- Valid settings are 0 or 1.
+	- When entering a few letters before initiating completion, the list
+	  will be filtered to display only the entries which begin with the
+	  list of characters.  When this option is set to 0, the list will be
+	  filtered using case sensitivity. >
+
+    omni_sql_include_owner
+<	- Default: 0, unless dbext.vim 3.00 has been installed
+	- Valid settings are 0 or 1.
+	- When completing tables, procedure or views and using dbext.vim 3.00
+	  or higher the list of objects will also include the owner name.
+	  When completing these objects and omni_sql_include_owner is enabled
+	  the owner name will be replaced. >
+
+    omni_sql_precache_syntax_groups
+<	- Default:
+	  ['syntax','sqlKeyword','sqlFunction','sqlOption','sqlType','sqlStatement']
+	- sqlcomplete can be used in conjunction with other completion
+	  plugins.  This is outlined at |sql-completion-filetypes|.  When the
+	  filetype is changed temporarily to SQL, the sqlcompletion plugin
+	  will cache the syntax groups listed in the List specified in this
+	  option.
+>
+
+4.5 SQL Maps					*sql-completion-maps*
+------------
+
+The default SQL maps have been described in other sections of this document in
+greater detail.  Here is a list of the maps with a brief description of each.
+
+Static Maps
+-----------
+These are maps which use populate the completion list using Vim's syntax
+highlighting rules. >
+    <C-C>a
+<       - Displays all SQL syntax items. >
+    <C-C>k
+<       - Displays all SQL syntax items defined as 'sqlKeyword'. >
+    <C-C>f
+<       - Displays all SQL syntax items defined as 'sqlFunction. >
+    <C-C>o
+<       - Displays all SQL syntax items defined as 'sqlOption'. >
+    <C-C>T
+<       - Displays all SQL syntax items defined as 'sqlType'. >
+    <C-C>s
+<       - Displays all SQL syntax items defined as 'sqlStatement'. >
+
+Dynamic Maps
+------------
+These are maps which use populate the completion list using the dbext.vim
+plugin. >
+    <C-C>t
+<       - Displays a list of tables. >
+    <C-C>p
+<       - Displays a list of procedures. >
+    <C-C>v
+<       - Displays a list of views. >
+    <C-C>c
+<       - Displays a list of columns for a specific table. >
+    <C-C>l
+<       - Displays a comma separated list of columns for a specific table. >
+    <C-C>L
+<       - Displays a comma separated list of columns for a specific table.
+	  This should only be used when the completion window is active. >
+    <C-Right>
+<	- Displays a list of columns for the table currently highlighted in
+	  the completion window.  <C-Right> is not recognized on most Unix
+	  systems, so this maps is only created on the Windows platform.
+	  If you would like the same feature on Unix, choose a different key
+	  and make the same map in your vimrc. >
+    <C-Left>
+<	- Displays the list of tables.
+	  <C-Left> is not recognized on most Unix systems, so this maps is
+	  only created on the Windows platform.  If you would like the same
+	  feature on Unix, choose a different key and make the same map in
+	  your vimrc. >
+    <C-C>R
+<	- This maps removes all cached items and forces the SQL completion
+	  to regenerate the list of items.
+
+Customizing Maps
+----------------
+You can create as many additional key maps as you like.  Generally, the maps
+will be specifying different syntax highlight groups.
+
+If you do not wish the default maps created or the key choices do not work on
+your platform (often a case on *nix) you define the following variable in
+your |vimrc|: >
+    let g:omni_sql_no_default_maps = 1
+
+Do no edit ftplugin/sql.vim directly!  If you change this file your changes
+will be over written on future updates.  Vim has a special directory structure
+which allows you to make customizations without changing the files that are
+included with the Vim distribution.  If you wish to customize the maps
+create an after/ftplugin/sql.vim (see |after-directory|) and place the same
+maps from the ftplugin/sql.vim in it using your own key strokes.  <C-C> was
+chosen since it will work on both Windows and *nix platforms.  On the windows
+platform you can also use <C-Space> or ALT keys.
+
+
+4.6 Using with other filetypes			*sql-completion-filetypes*
+------------------------------
+
+Many times SQL can be used with different filetypes.  For example Perl, Java,
+PHP, Javascript can all interact with a database.  Often you need both the SQL
+completion as well as the completion capabilities for the current language you
+are editing.
+
+This can be enabled easily with the following steps (assuming a Perl file): >
+    1.  :e test.pl
+    2.  :set filetype=sql
+    3.  :set ft=perl
+
+Step 1
+------
+Begins by editing a Perl file.  Vim automatically sets the filetype to
+"perl".  By default, Vim runs the appropriate filetype file
+ftplugin/perl.vim.  If you are using the syntax completion plugin by following
+the directions at |ft-syntax-omni| then the |'omnifunc'| option has been set to
+"syntax#Complete".  Pressing <C-X><C-O> will display the omni popup containing
+the syntax items for Perl.
+
+Step 2
+------
+Manually setting the filetype to 'sql' will also fire the appropriate filetype
+files ftplugin/sql.vim.  This file will define a number of buffer specific
+maps for SQL completion, see |sql-completion-maps|.  Now these maps have
+been created and the SQL completion plugin has been initialized.  All SQL
+syntax items have been cached in preparation.  The SQL filetype script detects
+we are attempting to use two different completion plugins.  Since the SQL maps
+begin with <C-C>, the maps will toggle the |'omnifunc'| when in use.  So you
+can use <C-X><C-O> to continue using the completion for Perl (using the syntax
+completion plugin) and <C-C> to use the SQL completion features.
+
+Step 3
+------
+Setting the filetype back to Perl sets all the usual "perl" related items back
+as they were.
+
+
+vim:tw=78:ts=8:ft=help:norl:
--- /dev/null
+++ b/lib/vimfiles/doc/starting.txt
@@ -1,0 +1,1473 @@
+*starting.txt*  For Vim version 7.1.  Last change: 2007 May 12
+
+
+		  VIM REFERENCE MANUAL    by Bram Moolenaar
+
+
+Starting Vim						*starting*
+
+1. Vim arguments		|vim-arguments|
+2. Vim on the Amiga		|starting-amiga|
+3. Running eVim			|evim-keys|
+4. Initialization		|initialization|
+5. $VIM and $VIMRUNTIME		|$VIM|
+6. Suspending			|suspend|
+7. Saving settings		|save-settings|
+8. Views and Sessions		|views-sessions|
+9. The viminfo file		|viminfo-file|
+
+==============================================================================
+1. Vim arguments					*vim-arguments*
+
+Most often, Vim is started to edit a single file with the command
+
+	vim filename					*-vim*
+
+More generally, Vim is started with:
+
+	vim [option | filename] ..
+
+Option arguments and file name arguments can be mixed, and any number of them
+can be given.  However, watch out for options that take an argument.
+
+For compatibility with various Vi versions, see	|cmdline-arguments|.
+
+Exactly one out of the following five items may be used to choose how to
+start editing:
+
+							*-file* *---*
+filename	One or more file names.  The first one will be the current
+		file and read into the buffer.  The cursor will be positioned
+		on the first line of the buffer.
+		To avoid a file name starting with a '-' being interpreted as
+		an option, precede the arglist with "--", e.g.: >
+			vim -- -filename
+<		All arguments after the "--" will be interpreted as file names,
+		no other options or "+command" argument can follow.
+
+							*--*
+-		This argument can mean two things, depending on whether Ex
+		mode is to be used.
+
+		Starting in Normal mode: >
+			vim -
+			ex -v -
+<		Start editing a new buffer, which is filled with text
+		that is read from stdin.  The commands that would normally be
+		read from stdin will now be read from stderr.  Example: >
+			find . -name "*.c" -print | vim -
+<		The buffer will be marked modified, because it contains text
+		that needs to be saved.  Except when in readonly mode, then
+		the buffer is not marked modified.  Example: >
+			ls | view -
+<
+		Starting in Ex mode: >
+			ex -
+			vim -e -
+			exim -
+			vim -E
+<		Start editing in silent mode.  See |-s-ex|.
+
+							*-t* *-tag*
+-t {tag}	A tag.  "tag" is looked up in the tags file, the associated
+		file becomes the current file, and the associated command is
+		executed.  Mostly this is used for C programs, in which case
+		"tag" often is a function name.  The effect is that the file
+		containing that function becomes the current file and the
+		cursor is positioned on the start of the function (see
+		|tags|).
+
+							*-q* *-qf*
+-q [errorfile]	QuickFix mode.  The file with the name [errorfile] is read
+		and the first error is displayed.  See |quickfix|.
+		If [errorfile] is not given, the 'errorfile' option is used
+		for the file name.  See 'errorfile' for the default value.
+		{not in Vi}
+
+(nothing)	Without one of the four items above, Vim will start editing a
+		new buffer.  It's empty and doesn't have a file name.
+
+
+The startup mode can be changed by using another name instead of "vim", which
+is equal to giving options:
+ex	vim -e	    Start in Ex mode (see |Ex-mode|).		    *ex*
+exim	vim -E	    Start in improved Ex mode (see |Ex-mode|).	    *exim*
+			(normally not installed)
+view	vim -R	    Start in read-only mode (see |-R|).		    *view*
+gvim	vim -g	    Start the GUI (see |gui|).			    *gvim*
+gex	vim -eg	    Start the GUI in Ex mode.			    *gex*
+gview	vim -Rg	    Start the GUI in read-only mode.		    *gview*
+rvim	vim -Z	    Like "vim", but in restricted mode (see |-Z|)   *rvim*
+rview	vim -RZ	    Like "view", but in restricted mode.	    *rview*
+rgvim	vim -gZ	    Like "gvim", but in restricted mode.	    *rgvim*
+rgview	vim -RgZ    Like "gview", but in restricted mode.	    *rgview*
+evim    vim -y      Easy Vim: set 'insertmode' (see |-y|)	    *evim*
+eview   vim -yR     Like "evim" in read-only mode		    *eview*
+vimdiff vim -d	    Start in diff mode |diff-mode|
+gvimdiff vim -gd    Start in diff mode |diff-mode|
+
+Additional characters may follow, they are ignored.  For example, you can have
+"gvim-5" to start the GUI.  You must have an executable by that name then, of
+course.
+
+On Unix, you would normally have one executable called Vim, and links from the
+different startup-names to that executable.  If your system does not support
+links and you do not want to have several copies of the executable, you could
+use an alias instead.  For example: >
+	alias view   vim -R
+	alias gvim   vim -g
+<
+							*startup-options*
+The option arguments may be given in any order.  Single-letter options can be
+combined after one dash.  There can be no option arguments after the "--"
+argument.
+
+On VMS all option arguments are assumed to be lowercase, unless preceded with
+a slash.  Thus "-R" means recovery and "-/R" readonly.
+
+--help							*-h* *--help*
+-h		Give usage (help) message and exit.  {not in Vi}
+		See |info-message| about capturing the text.
+
+							*--version*
+--version	Print version information and exit.  Same output as for
+		|:version| command.  {not in Vi}
+		See |info-message| about capturing the text.
+
+							*--noplugin*
+--noplugin	Skip loading plugins.  Resets the 'loadplugins' option.
+		{not in Vi}
+		Note that the |-u| argument may also disable loading plugins:
+			argument	load vimrc files	load plugins ~
+			(nothing)		yes		    yes
+			-u NONE			no		    no
+			-u NORC			no		    yes
+			--noplugin		yes		    no
+
+							*--literal*
+--literal	Take file names literally, don't expand wildcards.  Not needed
+		for Unix, because Vim always takes file names literally (the
+		shell expands wildcards).
+		Applies to all the names, also the ones that come before this
+		argument.
+
+							*-+*
++[num]		The cursor will be positioned on line "num" for the first
+		file being edited.  If "num" is missing, the cursor will be
+		positioned on the last line.
+
+							*-+/*
++/{pat}		The cursor will be positioned on the first line containing
+		"pat" in the first file being edited (see |pattern| for the
+		available search patterns).
+
++{command}						*-+c* *-c*
+-c {command}	{command} will be executed after the first file has been
+		read (and after autocommands and modelines for that file have
+		been processed).  "command" is interpreted as an Ex command.
+		If the "command" contains spaces, it must be enclosed in
+		double quotes (this depends on the shell that is used).
+		Example: >
+			vim  "+set si"  main.c
+			vim  "+find stdio.h"
+			vim  -c "set ff=dos"  -c wq  mine.mak
+<
+		Note: You can use up to 10 "+" or "-c" arguments in a Vim
+		command.  They are executed in the order given.  A "-S"
+		argument counts as a "-c" argument as well.
+		{Vi only allows one command}
+
+--cmd {command}						*--cmd*
+		{command} will be executed before processing any vimrc file.
+		Otherwise it acts like -c {command}.  You can use up to 10 of
+		these commands, independently from "-c" commands.
+		{not in Vi}
+
+							*-S*
+-S {file}	The {file} will be sourced after the first file has been read.
+		This is an easy way to do the equivalent of: >
+			-c "source {file}"
+<		It can be mixed with "-c" arguments and repeated like "-c".
+		The limit of 10 "-c" arguments applies here as well.
+		{file} cannot start with a "-".
+		{not in Vi}
+
+-S		Works like "-S Session.vim".  Only when used as the last
+		argument or when another "-" option follows.
+
+							*-r*
+-r		Recovery mode.  Without a file name argument, a list of
+		existing swap files is given.  With a file name, a swap file
+		is read to recover a crashed editing session.  See
+		|crash-recovery|.
+
+							*-L*
+-L		Same as -r.  {only in some versions of Vi: "List recoverable
+		edit sessions"}
+
+							*-R*
+-R		Readonly mode.  The 'readonly' option will be set for all the
+		files being edited.  You can still edit the buffer, but will
+		be prevented from accidentally overwriting a file.  If you
+		forgot that you are in View mode and did make some changes,
+		you can overwrite a file by adding an exclamation mark to
+		the Ex command, as in ":w!".  The 'readonly' option can be
+		reset with ":set noro" (see the options chapter, |options|).
+		Subsequent edits will not be done in readonly mode.  Calling
+		the executable "view" has the same effect as the -R argument.
+		The 'updatecount' option will be set to 10000, meaning that
+		the swap file will not be updated automatically very often.
+
+							*-m*
+-m		Modifications not allowed to be written.  The 'write' option
+		will be reset, so that writing files is disabled.  However,
+		the 'write' option can be set to enable writing again.
+		{not in Vi}
+
+							*-M*
+-M		Modifications not allowed.  The 'modifiable' option will be
+		reset, so that changes are not allowed.  The 'write' option
+		will be reset, so that writing files is disabled.  However,
+		the 'modifiable' and 'write' options can be set to enable
+		changes and writing.
+		{not in Vi}
+
+						*-Z* *restricted-mode* *E145*
+-Z		Restricted mode.  All commands that make use of an external
+		shell are disabled.  This includes suspending with CTRL-Z,
+		":sh", filtering, the system() function, backtick expansion,
+		etc.
+		{not in Vi}
+
+							*-g*
+-g		Start Vim in GUI mode.  See |gui|.  {not in Vi}
+
+							*-v*
+-v		Start Ex in Vi mode.  Only makes a difference when the
+		executable is called "ex" or "gvim".  For gvim the GUI is not
+		started if possible.
+
+							*-e*
+-e		Start Vim in Ex mode |Q|.  Only makes a difference when the
+		executable is not called "ex".
+
+							*-E*
+-E		Start Vim in improved Ex mode |gQ|.  Only makes a difference
+		when the executable is not called "exim".
+		{not in Vi}
+
+							*-s-ex*
+-s		Silent or batch mode.  Only when Vim was started as "ex" or
+		when preceded with the "-e" argument.  Otherwise see |-s|,
+		which does take an argument while this use of "-s" doesn't.
+		To be used when Vim is used to execute Ex commands from a file
+		instead of a terminal.  Switches off most prompts and
+		informative messages.  Also warnings and error messages.
+		The output of these commands is displayed (to stdout):
+			:print
+			:list
+			:number
+			:set      to display option values.
+		When 'verbose' is non-zero messages are printed (for
+		debugging, to stderr).
+		'term' and $TERM are not used.
+		If Vim appears to be stuck try typing "qa!<Enter>".  You don't
+		get a prompt thus you can't see Vim is waiting for you to type
+		something.
+		Initializations are skipped (except the ones given with the
+		"-u" argument).
+		Example: >
+			vim -e -s  < thefilter  thefile
+<
+							*-b*
+-b		Binary mode.  File I/O will only recognize <NL> to separate
+		lines.  The 'expandtab' option will be reset.  The 'textwidth'
+		option is set to 0.  'modeline' is reset.  The 'binary' option
+		is set.  This is done after reading the vimrc/exrc files but
+		before reading any file in the arglist.  See also
+		|edit-binary|.  {not in Vi}
+
+							*-l*
+-l		Lisp mode.  Sets the 'lisp' and 'showmatch' options on.
+
+							*-A*
+-A		Arabic mode.  Sets the 'arabic' option on.  (Only when
+		compiled with the |+arabic| features (which include
+		|+rightleft|), otherwise Vim gives an error message
+		and exits.)  {not in Vi}
+
+							*-F*
+-F		Farsi mode.  Sets the 'fkmap' and 'rightleft' options on.
+		(Only when compiled with |+rightleft| and |+farsi| features,
+		otherwise Vim gives an error message and exits.)  {not in Vi}
+
+							*-H*
+-H		Hebrew mode.  Sets the 'hkmap' and 'rightleft' options on.
+		(Only when compiled with the |+rightleft| feature, otherwise
+		Vim gives an error message and exits.)  {not in Vi}
+
+							*-V* *verbose*
+-V[N]		Verbose.  Sets the 'verbose' option to [N] (default: 10).
+		Messages will be given for each file that is ":source"d and
+		for reading or writing a viminfo file.  Can be used to find
+		out what is happening upon startup and exit.  {not in Vi}
+		Example: >
+			vim -V8 foobar
+
+-V[N]{filename}
+		Like -V and set 'verbosefile' to {filename}.  The result is
+		that messages are not displayed but written to the file
+		{filename}.  {filename} must not start with a digit.
+		Example: >
+			vim -V20vimlog foobar
+<
+							*-D*
+-D		Debugging.  Go to debugging mode when executing the first
+		command from a script. |debug-mode|
+		{not available when compiled without the |+eval| feature}
+		{not in Vi}
+
+							*-C*
+-C		Compatible mode.  Sets the 'compatible' option.  You can use
+		this to get 'compatible', even though a .vimrc file exists.
+		But the command ":set nocompatible" overrules it anyway.
+		Also see |compatible-default|.  {not in Vi}
+
+							*-N*
+-N		Not compatible mode.  Resets the 'compatible' option.  You can
+		use this to get 'nocompatible', when there is no .vimrc file.
+		Also see |compatible-default|.  {not in Vi}
+
+							*-y* *easy*
+-y		Easy mode.  Implied for |evim| and |eview|.  Starts with
+		'insertmode' set and behaves like a click-and-type editor.
+		This sources the script $VIMRUNTIME/evim.vim.  Mappings are
+		set up to work like most click-and-type editors, see
+		|evim-keys|.  The GUI is started when available.
+		{not in Vi}
+
+							*-n*
+-n		No swap file will be used.  Recovery after a crash will be
+		impossible.  Handy if you want to view or edit a file on a
+		very slow medium (e.g., a floppy).
+		Can also be done with ":set updatecount=0".  You can switch it
+		on again by setting the 'updatecount' option to some value,
+		e.g., ":set uc=100".
+		'updatecount' is set to 0 AFTER executing commands from a
+		vimrc file, but before the GUI initializations.  Thus it
+		overrides a setting for 'updatecount' in a vimrc file, but not
+		in a gvimrc file.  See |startup|.
+		When you want to reduce accesses to the disk (e.g., for a
+		laptop), don't use "-n", but set 'updatetime' and
+		'updatecount' to very big numbers, and type ":preserve" when
+		you want to save your work.  This way you keep the possibility
+		for crash recovery.
+		{not in Vi}
+
+							*-o*
+-o[N]		Open N windows, split horizontally.  If [N] is not given,
+		one window is opened for every file given as argument.  If
+		there is not enough room, only the first few files get a
+		window.  If there are more windows than arguments, the last
+		few windows will be editing an empty file.
+		{not in Vi}
+
+							*-O*
+-O[N]		Open N windows, split vertically.  Otherwise it's like -o.
+		If both the -o and the -O option are given, the last one on
+		the command line determines how the windows will be split.
+		{not in Vi}
+
+							*-p*
+-p[N]		Open N tab pages.  If [N] is not given, one tab page is opened
+		for every file given as argument.  The maximum is set with
+		'tabpagemax' pages (default 10).  If there are more tab pages
+		than arguments, the last few tab pages will be editing an
+		empty file.  Also see |tabpage|.
+		{not in Vi}
+
+							*-T*
+-T {terminal}	Set the terminal type to "terminal".  This influences the
+		codes that Vim will send to your terminal.  This is normally
+		not needed, because Vim will be able to find out what type
+		of terminal you are using.  (See |terminal-info|.)  {not in Vi}
+
+							*-d*
+-d		Start in diff mode, like |vimdiff|.
+		{not in Vi} {not available when compiled without the |+diff|
+		feature}
+
+-d {device}	Only on the Amiga and when not compiled with the |+diff|
+		feature.  Works like "-dev".
+							*-dev*
+-dev {device}	Only on the Amiga: The {device} is opened to be used for
+		editing.
+		Normally you would use this to set the window position and
+		size: "-d con:x/y/width/height", e.g.,
+		"-d con:30/10/600/150".  But you can also use it to start
+		editing on another device, e.g., AUX:.  {not in Vi}
+							*-f*
+-f		Amiga: Do not restart Vim to open a new window.  This
+		option should be used when Vim is started by a program that
+		will wait for the edit session to finish (e.g., mail or
+		readnews).  See |amiga-window|.
+
+		GUI: Do not disconnect from the program that started Vim.
+		'f' stands for "foreground".  If omitted, the GUI forks a new
+		process and exits the current one.  "-f" should be used when
+		gvim is started by a program that will wait for the edit
+		session to finish (e.g., mail or readnews).  If you want gvim
+		never to fork, include 'f' in 'guioptions' in your |gvimrc|.
+		Careful: You can use "-gf" to start the GUI in the foreground,
+		but "-fg" is used to specify the foreground color.  |gui-fork|
+		{not in Vi}
+
+							*--nofork*
+--nofork	GUI: Do not fork.  Same as |-f|.
+							*-u* *E282*
+-u {vimrc}	The file {vimrc} is read for initializations.  Most other
+		initializations are skipped; see |initialization|.  This can
+		be used to start Vim in a special mode, with special
+		mappings and settings.  A shell alias can be used to make
+		this easy to use.  For example: >
+			alias vimc vim -u ~/.c_vimrc !*
+<		Also consider using autocommands; see |autocommand|.
+		When {vimrc} is equal to "NONE" (all uppercase), all
+		initializations from files and environment variables are
+		skipped, including reading the |gvimrc| file when the GUI
+		starts.  Loading plugins is also skipped.
+		When {vimrc} is equal to "NORC" (all uppercase), this has the
+		same effect as "NONE", but loading plugins is not skipped.
+		Using the "-u" argument has the side effect that the
+		'compatible' option will be on by default.  This can have
+		unexpected effects.  See |'compatible'|.
+		{not in Vi}
+
+							*-U* *E230*
+-U {gvimrc}	The file {gvimrc} is read for initializations when the GUI
+		starts.  Other GUI initializations are skipped.  When {gvimrc}
+		is equal to "NONE", no file is read for GUI initializations at
+		all.  |gui-init|
+		Exception: Reading the system-wide menu file is always done.
+		{not in Vi}
+
+							*-i*
+-i {viminfo}	The file "viminfo" is used instead of the default viminfo
+		file.  If the name "NONE" is used (all uppercase), no viminfo
+		file is read or written, even if 'viminfo' is set or when
+		":rv" or ":wv" are used.  See also |viminfo-file|.
+		{not in Vi}
+
+							*-x*
+-x		Use encryption to read/write files.  Will prompt for a key,
+		which is then stored in the 'key' option.  All writes will
+		then use this key to encrypt the text.  The '-x' argument is
+		not needed when reading a file, because there is a check if
+		the file that is being read has been encrypted, and Vim asks
+		for a key automatically. |encryption|
+
+							*-X*
+-X		Do not try connecting to the X server to get the current
+		window title and copy/paste using the X clipboard.  This
+		avoids a long startup time when running Vim in a terminal
+		emulator and the connection to the X server is slow.
+		Only makes a difference on Unix or VMS, when compiled with the
+		|+X11| feature.  Otherwise it's ignored.
+		To disable the connection only for specific terminals, see the
+		'clipboard' option.
+		When the X11 Session Management Protocol (XSMP) handler has
+		been built in, the -X option also disables that connection as
+		it, too, may have undesirable delays.
+		When the connection is desired later anyway (e.g., for
+		client-server messages), call the |serverlist()| function.
+		This does not enable the XSMP handler though.
+		{not in Vi}
+
+							*-s*
+-s {scriptin}	The script file "scriptin" is read.  The characters in the
+		file are interpreted as if you had typed them.  The same can
+		be done with the command ":source! {scriptin}".  If the end
+		of the file is reached before the editor exits, further
+		characters are read from the keyboard.  Only works when not
+		started in Ex mode, see |-s-ex|.  See also |complex-repeat|.
+		{not in Vi}
+
+							*-w_nr*
+-w {number}
+-w{number}	Set the 'window' option to {number}.
+
+							*-w*
+-w {scriptout}	All the characters that you type are recorded in the file
+		"scriptout", until you exit Vim.  This is useful if you want
+		to create a script file to be used with "vim -s" or
+		":source!".  When the "scriptout" file already exists, new
+		characters are appended.  See also |complex-repeat|.
+		{scriptout} cannot start with a digit.
+		{not in Vi}
+
+							*-W*
+-W {scriptout}	Like -w, but do not append, overwrite an existing file.
+		{not in Vi}
+
+--remote [+{cmd}] {file} ...
+		Open the {file} in another Vim that functions as a server.
+		Any non-file arguments must come before this.
+		See |--remote|. {not in Vi}
+
+--remote-silent [+{cmd}] {file} ...
+		Like --remote, but don't complain if there is no server.
+		See |--remote-silent|. {not in Vi}
+
+--remote-wait [+{cmd}] {file} ...
+		Like --remote, but wait for the server to finish editing the
+		file(s).
+		See |--remote-wait|. {not in Vi}
+
+--remote-wait-silent [+{cmd}] {file} ...
+		Like --remote-wait, but don't complain if there is no server.
+		See |--remote-wait-silent|. {not in Vi}
+
+--servername {name}
+		Specify the name of the Vim server to send to or to become.
+		See |--servername|. {not in Vi}
+
+--remote-send {keys}
+		Send {keys} to a Vim server and exit.
+		See |--remote-send|. {not in Vi}
+
+--remote-expr {expr}
+		Evaluate {expr} in another Vim that functions as a server.
+		The result is printed on stdout.
+		See |--remote-expr|. {not in Vi}
+
+--serverlist	Output a list of Vim server names and exit.  See
+		|--serverlist|. {not in Vi}
+
+--socketid {id}						*--socketid*
+		GTK+ GUI Vim only.  Make gvim try to use GtkPlug mechanism, so
+		that it runs inside another window.  See |gui-gtk-socketid|
+		for details. {not in Vi}
+
+--echo-wid						*--echo-wid*
+		GTK+ GUI Vim only.  Make gvim echo the Window ID on stdout,
+		which can be used to run gvim in a kpart widget.  The format
+		of the output is: >
+			WID: 12345\n
+<		{not in Vi}
+
+--role {role}						*--role*
+		GTK+ 2 GUI only.  Set the role of the main window to {role}.
+		The window role can be used by a window manager to uniquely
+		identify a window, in order to restore window placement and
+		such.  The --role argument is passed automatically when
+		restoring the session on login.  See |gui-gnome-session|
+		{not in Vi}
+
+-P {parent-title}				*-P* *MDI* *E671* *E672*
+		Win32 only: Specify the title of the parent application.  When
+		possible, Vim will run in an MDI window inside the
+		application.
+		{parent-title} must appear in the window title of the parent
+		application.  Make sure that it is specific enough.
+		Note that the implementation is still primitive.  It won't
+		work with all applications and the menu doesn't work.
+
+-nb							*-nb*
+-nb={fname}
+-nb:{hostname}:{addr}:{password}
+		Attempt connecting to Netbeans and become an editor server for
+		it.  The second form specifies a file to read connection info
+		from.  The third form specifies the hostname, address and
+		password for connecting to Netbeans. |netbeans-run|
+
+Example for using a script file to change a name in several files:
+	Create a file "subs.vi" containing substitute commands and a :wq
+	command: >
+		:%s/Jones/Smith/g
+		:%s/Allen/Peter/g
+		:wq
+<
+	Execute Vim on all files you want to change: >
+
+		foreach i ( *.let ) vim -s subs.vi $i
+
+If the executable is called "view", Vim will start in Readonly mode.  This is
+useful if you can make a hard or symbolic link from "view" to "vim".
+Starting in Readonly mode can also be done with "vim -R".
+
+If the executable is called "ex", Vim will start in "Ex" mode.  This means it
+will accept only ":" commands.  But when the "-v" argument is given, Vim will
+start in Normal mode anyway.
+
+Additional arguments are available on unix like systems when compiled with
+X11 GUI support.  See |gui-resources|.
+
+==============================================================================
+2. Vim on the Amiga					*starting-amiga*
+
+Starting Vim from the Workbench				*workbench*
+-------------------------------
+
+Vim can be started from the Workbench by clicking on its icon twice.  It will
+then start with an empty buffer.
+
+Vim can be started to edit one or more files by using a "Project" icon.  The
+"Default Tool" of the icon must be the full pathname of the Vim executable.
+The name of the ".info" file must be the same as the name of the text file.
+By clicking on this icon twice, Vim will be started with the file name as
+current file name, which will be read into the buffer (if it exists).  You can
+edit multiple files by pressing the shift key while clicking on icons, and
+clicking twice on the last one.  The "Default Tool" for all these icons must
+be the same.
+
+It is not possible to give arguments to Vim, other than file names, from the
+workbench.
+
+Vim window						*amiga-window*
+----------
+
+Vim will run in the CLI window where it was started.  If Vim was started with
+the "run" or "runback" command, or if Vim was started from the workbench, it
+will open a window of its own.
+
+Technical detail:
+	To open the new window a little trick is used.  As soon as Vim
+	recognizes that it does not run in a normal CLI window, it will
+	create a script file in "t:".  This script file contains the same
+	command as the one Vim was started with, and an "endcli" command.
+	This script file is then executed with a "newcli" command (the "c:run"
+	and "c:newcli" commands are required for this to work).  The script
+	file will hang around until reboot, or until you delete it.  This
+	method is required to get the ":sh" and ":!" commands to work
+	correctly.  But when Vim was started with the -f option (foreground
+	mode), this method is not used.  The reason for this is that
+	when a program starts Vim with the -f option it will wait for Vim to
+	exit.  With the script trick, the calling program does not know when
+	Vim exits.  The -f option can be used when Vim is started by a mail
+	program which also waits for the edit session to finish.  As a
+	consequence, the ":sh" and ":!" commands are not available when the
+	-f option is used.
+
+Vim will automatically recognize the window size and react to window
+resizing.  Under Amiga DOS 1.3, it is advised to use the fastfonts program,
+"FF", to speed up display redrawing.
+
+==============================================================================
+3. Running eVim							*evim-keys*
+
+EVim runs Vim as click-and-type editor.  This is very unlike the original Vi
+idea.  But it helps for people that don't use Vim often enough to learn the
+commands.  Hopefully they will find out that learning to use Normal mode
+commands will make their editing much more effective.
+
+In Evim these options are changed from their default value:
+
+	:set nocompatible	Use Vim improvements
+	:set insertmode		Remain in Insert mode most of the time
+	:set hidden		Keep invisible buffers loaded
+	:set backup		Keep backup files (not for VMS)
+	:set backspace=2	Backspace over everything
+	:set autoindent		auto-indent new lines
+	:set history=50		keep 50 lines of Ex commands
+	:set ruler		show the cursor position
+	:set incsearch		show matches halfway typing a pattern
+	:set mouse=a		use the mouse in all modes
+	:set hlsearch		highlight all matches for a search pattern
+	:set whichwrap+=<,>,[,]  <Left> and <Right> wrap around line breaks
+	:set guioptions-=a	non-Unix only: don't do auto-select
+
+Key mappings:
+	<Down>		moves by screen lines rather than file lines
+	<Up>		idem
+	Q		does "gq", formatting, instead of Ex mode
+	<BS>		in Visual mode: deletes the selection
+	CTRL-X		in Visual mode: Cut to clipboard
+	<S-Del>		idem
+	CTRL-C		in Visual mode: Copy to clipboard
+	<C-Insert>	idem
+	CTRL-V		Pastes from the clipboard (in any mode)
+	<S-Insert>	idem
+	CTRL-Q		do what CTRL-V used to do
+	CTRL-Z		undo
+	CTRL-Y		redo
+	<M-Space>	system menu
+	CTRL-A		select all
+	<C-Tab>		next window, CTRL-W w
+	<C-F4>		close window, CTRL-W c
+
+Additionally:
+- ":behave mswin" is used |:behave|
+- syntax highlighting is enabled
+- filetype detection is enabled, filetype plugins and indenting is enabled
+- in a text file 'textwidth' is set to 78
+
+One hint: If you want to go to Normal mode to be able to type a sequence of
+commands, use CTRL-L. |i_CTRL-L|
+
+==============================================================================
+4. Initialization				*initialization* *startup*
+
+This section is about the non-GUI version of Vim.  See |gui-fork| for
+additional initialization when starting the GUI.
+
+At startup, Vim checks environment variables and files and sets values
+accordingly.  Vim proceeds in this order:
+
+1. Set the 'shell' and 'term' option		*SHELL* *COMSPEC* *TERM*
+	The environment variable SHELL, if it exists, is used to set the
+	'shell' option.  On MS-DOS and Win32, the COMSPEC variable is used
+	if SHELL is not set.
+	The environment variable TERM, if it exists, is used to set the 'term'
+	option.  However, 'term' will change later when starting the GUI (step
+	8 below).
+
+2. Process the arguments
+	The options and file names from the command that start Vim are
+	inspected.  Buffers are created for all files (but not loaded yet).
+	The |-V| argument can be used to display or log what happens next,
+	useful for debugging the initializations.
+
+3. Execute Ex commands, from environment variables and/or files
+	An environment variable is read as one Ex command line, where multiple
+	commands must be separated with '|' or "<NL>".
+								*vimrc* *exrc*
+	A file that contains initialization commands is called a "vimrc" file.
+	Each line in a vimrc file is executed as an Ex command line.  It is
+	sometimes also referred to as "exrc" file.  They are the same type of
+	file, but "exrc" is what Vi always used, "vimrc" is a Vim specific
+	name.  Also see |vimrc-intro|.
+
+	Recommended place for your personal initializations:
+		Unix		    $HOME/.vimrc
+		OS/2		    $HOME/.vimrc or $VIM/.vimrc (or _vimrc)
+		MS-DOS and Win32    $HOME/_vimrc or $VIM/_vimrc
+		Amiga		    s:.vimrc or $VIM/.vimrc
+
+	If Vim was started with "-u filename", the file "filename" is used.
+	All following initializations until 4. are skipped.
+	"vim -u NORC" can be used to skip these initializations without
+	reading a file.  "vim -u NONE" also skips loading plugins.  |-u|
+
+	If Vim was started in Ex mode with the "-s" argument, all following
+	initializations until 4. are skipped.  Only the "-u" option is
+	interpreted.
+							*evim.vim*
+     a. If vim was started as |evim| or |eview| or with the |-y| argument, the
+	script $VIMRUNTIME/evim.vim will be loaded.
+							*system-vimrc*
+     b. For Unix, MS-DOS, MS-Windows, OS/2, VMS, Macintosh, RISC-OS and Amiga
+	the system vimrc file is read for initializations.  The path of this
+	file is shown with the ":version" command.  Mostly it's "$VIM/vimrc".
+	Note that this file is ALWAYS read in 'compatible' mode, since the
+	automatic resetting of 'compatible' is only done later.  Add a ":set
+	nocp" command if you like.
+	For the Macintosh the $VIMRUNTIME/macmap.vim is read.
+
+			  *VIMINIT* *.vimrc* *_vimrc* *EXINIT* *.exrc* *_exrc*
+     c. Four places are searched for initializations.  The first that exists
+	is used, the others are ignored.  The $MYVIMRC environment variable is
+	set to the file that was first found, unless $MYVIMRC was already set.
+	-  The environment variable VIMINIT (see also |compatible-default|) (*)
+	   The value of $VIMINIT is used as an Ex command line.
+	-  The user vimrc file(s):
+		    "$HOME/.vimrc"	(for Unix and OS/2) (*)
+		    "s:.vimrc"		(for Amiga) (*)
+		    "home:.vimrc"	(for Amiga) (*)
+		    "$VIM/.vimrc"	(for OS/2 and Amiga) (*)
+		    "$HOME/_vimrc"	(for MS-DOS and Win32) (*)
+		    "$VIM/_vimrc"	(for MS-DOS and Win32) (*)
+		Note: For Unix, OS/2 and Amiga, when ".vimrc" does not exist,
+		"_vimrc" is also tried, in case an MS-DOS compatible file
+		system is used.  For MS-DOS and Win32 ".vimrc" is checked
+		after "_vimrc", in case long file names are used.
+		Note: For MS-DOS and Win32, "$HOME" is checked first.  If no
+		"_vimrc" or ".vimrc" is found there, "$VIM" is tried.
+		See |$VIM| for when $VIM is not set.
+	-  The environment variable EXINIT.
+	   The value of $EXINIT is used as an Ex command line.
+	-  The user exrc file(s).  Same as for the user vimrc file, but with
+	   "vimrc" replaced by "exrc".  But only one of ".exrc" and "_exrc" is
+	   used, depending on the system.  And without the (*)!
+
+     d. If the 'exrc' option is on (which is not the default), the current
+	directory is searched for three files.  The first that exists is used,
+	the others are ignored.
+	-  The file ".vimrc" (for Unix, Amiga and OS/2) (*)
+		    "_vimrc" (for MS-DOS and Win32) (*)
+	-  The file "_vimrc" (for Unix, Amiga and OS/2) (*)
+		    ".vimrc" (for MS-DOS and Win32) (*)
+	-  The file ".exrc"  (for Unix, Amiga and OS/2)
+		    "_exrc"  (for MS-DOS and Win32)
+
+     (*) Using this file or environment variable will cause 'compatible' to be
+	 off by default.  See |compatible-default|.
+
+4. Load the plugin scripts.					*load-plugins*
+	This does the same as the command: >
+		:runtime! plugin/**/*.vim
+<	The result is that all directories in the 'runtimepath' option will be
+	searched for the "plugin" sub-directory and all files ending in ".vim"
+	will be sourced (in alphabetical order per directory), also in
+	subdirectories.
+	Loading plugins won't be done when:
+	- The 'loadplugins' option was reset in a vimrc file.
+	- The |--noplugin| command line argument is used.
+	- The "-u NONE" command line argument is used |-u|.
+	- When Vim was compiled without the |+eval| feature.
+	Note that using "-c 'set noloadplugins'" doesn't work, because the
+	commands from the command line have not been executed yet.  You can
+	use "--cmd 'set noloadplugins'" |--cmd|.
+
+5. Set 'shellpipe' and 'shellredir'
+	The 'shellpipe' and 'shellredir' options are set according to the
+	value of the 'shell' option, unless they have been set before.
+	This means that Vim will figure out the values of 'shellpipe' and
+	'shellredir' for you, unless you have set them yourself.
+
+6. Set 'updatecount' to zero, if "-n" command argument used
+
+7. Set binary options
+	If the "-b" flag was given to Vim, the options for binary editing will
+	be set now.  See |-b|.
+
+8. Perform GUI initializations
+	Only when starting "gvim", the GUI initializations will be done.  See
+	|gui-init|.
+
+9. Read the viminfo file
+	If the 'viminfo' option is not empty, the viminfo file is read.  See
+	|viminfo-file|.
+
+10. Read the quickfix file
+	If the "-q" flag was given to Vim, the quickfix file is read.  If this
+	fails, Vim exits.
+
+11. Open all windows
+	When the |-o| flag was given, windows will be opened (but not
+	displayed yet).
+	When the |-p| flag was given, tab pages will be created (but not
+	displayed yet).
+	When switching screens, it happens now.  Redrawing starts.
+	If the "-q" flag was given to Vim, the first error is jumped to.
+	Buffers for all windows will be loaded.
+
+12. Execute startup commands
+	If a "-t" flag was given to Vim, the tag is jumped to.
+	The commands given with the |-c| and |+cmd| arguments are executed.
+	If the 'insertmode' option is set, Insert mode is entered.
+	The |VimEnter| autocommands are executed.
+
+Some hints on using initializations:
+
+Standard setup:
+Create a vimrc file to set the default settings and mappings for all your edit
+sessions.  Put it in a place so that it will be found by 3b:
+	~/.vimrc	(Unix and OS/2)
+	s:.vimrc	(Amiga)
+	$VIM\_vimrc	(MS-DOS and Win32)
+Note that creating a vimrc file will cause the 'compatible' option to be off
+by default.  See |compatible-default|.
+
+Local setup:
+Put all commands that you need for editing a specific directory only into a
+vimrc file and place it in that directory under the name ".vimrc" ("_vimrc"
+for MS-DOS and Win32).  NOTE: To make Vim look for these special files you
+have to turn on the option 'exrc'.  See |trojan-horse| too.
+
+System setup:
+This only applies if you are managing a Unix system with several users and
+want to set the defaults for all users.  Create a vimrc file with commands
+for default settings and mappings and put it in the place that is given with
+the ":version" command.
+
+Saving the current state of Vim to a file:
+Whenever you have changed values of options or when you have created a
+mapping, then you may want to save them in a vimrc file for later use.  See
+|save-settings| about saving the current state of settings to a file.
+
+Avoiding setup problems for Vi users:
+Vi uses the variable EXINIT and the file "~/.exrc".  So if you do not want to
+interfere with Vi, then use the variable VIMINIT and the file "vimrc" instead.
+
+Amiga environment variables:
+On the Amiga, two types of environment variables exist.  The ones set with the
+DOS 1.3 (or later) setenv command are recognized.  See the AmigaDos 1.3
+manual.  The environment variables set with the old Manx Set command (before
+version 5.0) are not recognized.
+
+MS-DOS line separators:
+On MS-DOS-like systems (MS-DOS itself, Win32, and OS/2), Vim assumes that all
+the vimrc files have <CR> <NL> pairs as line separators.  This will give
+problems if you have a file with only <NL>s and have a line like
+":map xx yy^M".  The trailing ^M will be ignored.
+
+						     *compatible-default*
+When Vim starts, the 'compatible' option is on.  This will be used when Vim
+starts its initializations.  But as soon as a user vimrc file is found, or a
+vimrc file in the current directory, or the "VIMINIT" environment variable is
+set, it will be set to 'nocompatible'.  This has the side effect of setting or
+resetting other options (see 'compatible').  But only the options that have
+not been set or reset will be changed.  This has the same effect like the
+value of 'compatible' had this value when starting Vim.  Note that this
+doesn't happen for the system-wide vimrc file nor when Vim was started with
+the |-u| command line argument.  It does also happen for gvimrc files.  The
+$MYVIMRC or $MYGVIMRC file will be set to the first found vimrc and/or gvimrc
+file.
+
+But there is a side effect of setting or resetting 'compatible' at the moment
+a .vimrc file is found: Mappings are interpreted the moment they are
+encountered.  This makes a difference when using things like "<CR>".  If the
+mappings depend on a certain value of 'compatible', set or reset it before
+giving the mapping.
+
+The above behavior can be overridden in these ways:
+- If the "-N" command line argument is given, 'nocompatible' will be used,
+  even when no vimrc file exists.
+- If the "-C" command line argument is given, 'compatible' will be used, even
+  when a vimrc file exists.
+- If the "-u {vimrc}" argument is used, 'compatible' will be used.
+- When the name of the executable ends in "ex", then this works like the "-C"
+  argument was given: 'compatible' will be used, even when a vimrc file
+  exists.  This has been done to make Vim behave like "ex", when it is started
+  as "ex".
+
+Avoiding trojan horses:					*trojan-horse*
+While reading the "vimrc" or the "exrc" file in the current directory, some
+commands can be disabled for security reasons by setting the 'secure' option.
+This is always done when executing the command from a tags file.  Otherwise it
+would be possible that you accidentally use a vimrc or tags file that somebody
+else created and contains nasty commands.  The disabled commands are the ones
+that start a shell, the ones that write to a file, and ":autocmd".  The ":map"
+commands are echoed, so you can see which keys are being mapped.
+	If you want Vim to execute all commands in a local vimrc file, you
+can reset the 'secure' option in the EXINIT or VIMINIT environment variable or
+in the global "exrc" or "vimrc" file.  This is not possible in "vimrc" or
+"exrc" in the current directory, for obvious reasons.
+	On Unix systems, this only happens if you are not the owner of the
+vimrc file.  Warning: If you unpack an archive that contains a vimrc or exrc
+file, it will be owned by you.  You won't have the security protection.  Check
+the vimrc file before you start Vim in that directory, or reset the 'exrc'
+option.  Some Unix systems allow a user to do "chown" on a file.  This makes
+it possible for another user to create a nasty vimrc and make you the owner.
+Be careful!
+	When using tag search commands, executing the search command (the last
+part of the line in the tags file) is always done in secure mode.  This works
+just like executing a command from a vimrc/exrc in the current directory.
+
+							*slow-start*
+If Vim takes a long time to start up, there may be a few causes:
+- If the Unix version was compiled with the GUI and/or X11 (check the output
+  of ":version" for "+GUI" and "+X11"), it may need to load shared libraries
+  and connect to the X11 server.  Try compiling a version with GUI and X11
+  disabled.  This also should make the executable smaller.
+  Use the |-X| command line argument to avoid connecting to the X server when
+  running in a terminal.
+- If you have "viminfo" enabled, the loading of the viminfo file may take a
+  while.  You can find out if this is the problem by disabling viminfo for a
+  moment (use the Vim argument "-i NONE", |-i|).  Try reducing the number of
+  lines stored in a register with ":set viminfo='20,<50,s10".  |viminfo-file|.
+
+							*:intro*
+When Vim starts without a file name, an introductory message is displayed (for
+those who don't know what Vim is).  It is removed as soon as the display is
+redrawn in any way.  To see the message again, use the ":intro" command (if
+there is not enough room, you will see only part of it).
+   To avoid the intro message on startup, add the 'I' flag to 'shortmess'.
+
+							*info-message*
+The |--help| and |--version| arguments cause Vim to print a message and then
+exit.  Normally the message is send to stdout, thus can be redirected to a
+file with: >
+
+	vim --help >file
+
+From inside Vim: >
+
+	:read !vim --help
+
+When using gvim, it detects that it might have been started from the desktop,
+without a terminal to show messages on.  This is detected when both stdout and
+stderr are not a tty.  This breaks the ":read" command, as used in the example
+above.  To make it work again, set 'shellredir' to ">" instead of the default
+">&": >
+
+	:set shellredir=>
+	:read !gvim --help
+
+This still won't work for systems where gvim does not use stdout at all
+though.
+
+==============================================================================
+5. $VIM and $VIMRUNTIME
+								*$VIM*
+The environment variable "$VIM" is used to locate various user files for Vim,
+such as the user startup script ".vimrc".  This depends on the system, see
+|startup|.
+
+To avoid the need for every user to set the $VIM environment variable, Vim
+will try to get the value for $VIM in this order:
+1. The value defined by the $VIM environment variable.  You can use this to
+   make Vim look in a specific directory for its support files.  Example: >
+	setenv VIM /home/paul/vim
+2. The path from 'helpfile' is used, unless it contains some environment
+   variable too (the default is "$VIMRUNTIME/doc/help.txt": chicken-egg
+   problem).  The file name ("help.txt" or any other) is removed.  Then
+   trailing directory names are removed, in this order: "doc", "runtime" and
+   "vim{version}" (e.g., "vim54").
+3. For MSDOS, Win32 and OS/2 Vim tries to use the directory name of the
+   executable.  If it ends in "/src", this is removed.  This is useful if you
+   unpacked the .zip file in some directory, and adjusted the search path to
+   find the vim executable.  Trailing directory names are removed, in this
+   order: "runtime" and "vim{version}" (e.g., "vim54").
+4. For Unix the compile-time defined installation directory is used (see the
+   output of ":version").
+
+Once Vim has done this once, it will set the $VIM environment variable.  To
+change it later, use a ":let" command like this: >
+	:let $VIM = "/home/paul/vim/"
+<
+								*$VIMRUNTIME*
+The environment variable "$VIMRUNTIME" is used to locate various support
+files, such as the on-line documentation and files used for syntax
+highlighting.  For example, the main help file is normally
+"$VIMRUNTIME/doc/help.txt".
+You don't normally set $VIMRUNTIME yourself, but let Vim figure it out.  This
+is the order used to find the value of $VIMRUNTIME:
+1. If the environment variable $VIMRUNTIME is set, it is used.  You can use
+   this when the runtime files are in an unusual location.
+2. If "$VIM/vim{version}" exists, it is used.  {version} is the version
+   number of Vim, without any '-' or '.'.  For example: "$VIM/vim54".  This is
+   the normal value for $VIMRUNTIME.
+3. If "$VIM/runtime" exists, it is used.
+4. The value of $VIM is used.  This is for backwards compatibility with older
+   versions.
+5. When the 'helpfile' option is set and doesn't contain a '$', its value is
+   used, with "doc/help.txt" removed from the end.
+
+For Unix, when there is a compiled-in default for $VIMRUNTIME (check the
+output of ":version"), steps 2, 3 and 4 are skipped, and the compiled-in
+default is used after step 5.  This means that the compiled-in default
+overrules the value of $VIM.  This is useful if $VIM is "/etc" and the runtime
+files are in "/usr/share/vim/vim54".
+
+Once Vim has done this once, it will set the $VIMRUNTIME environment variable.
+To change it later, use a ":let" command like this: >
+	:let $VIMRUNTIME = "/home/piet/vim/vim54"
+
+In case you need the value of $VIMRUNTIME in a shell (e.g., for a script that
+greps in the help files) you might be able to use this: >
+
+	VIMRUNTIME=`vim -e -T dumb --cmd 'exe "set t_cm=\<C-M>"|echo $VIMRUNTIME|quit' | tr -d '\015' `
+
+==============================================================================
+6. Suspending						*suspend*
+
+					*iconize* *iconise* *CTRL-Z* *v_CTRL-Z*
+CTRL-Z			Suspend Vim, like ":stop".
+			Works in Normal and in Visual mode.  In Insert and
+			Command-line mode, the CTRL-Z is inserted as a normal
+			character.  In Visual mode Vim goes back to Normal
+			mode.
+			Note: if CTRL-Z undoes a change see |mswin.vim|.
+
+
+:sus[pend][!]	or			*:sus* *:suspend* *:st* *:stop*
+:st[op][!]		Suspend Vim.
+			If the '!' is not given and 'autowrite' is set, every
+			buffer with changes and a file name is written out.
+			If the '!' is given or 'autowrite' is not set, changed
+			buffers are not written, don't forget to bring Vim
+			back to the foreground later!
+
+In the GUI, suspending is implemented as iconising gvim.  In Windows 95/NT,
+gvim is minimized.
+
+On many Unix systems, it is possible to suspend Vim with CTRL-Z.  This is only
+possible in Normal and Visual mode (see next chapter, |vim-modes|).  Vim will
+continue if you make it the foreground job again.  On other systems, CTRL-Z
+will start a new shell.  This is the same as the ":sh" command.  Vim will
+continue if you exit from the shell.
+
+In X-windows the selection is disowned when Vim suspends.  this means you
+can't paste it in another application (since Vim is going to sleep an attempt
+to get the selection would make the program hang).
+
+==============================================================================
+7. Saving settings					*save-settings*
+
+Mostly you will edit your vimrc files manually.  This gives you the greatest
+flexibility.  There are a few commands to generate a vimrc file automatically.
+You can use these files as they are, or copy/paste lines to include in another
+vimrc file.
+
+							*:mk* *:mkexrc*
+:mk[exrc] [file]	Write current key mappings and changed options to
+			[file] (default ".exrc" in the current directory),
+			unless it already exists.  {not in Vi}
+
+:mk[exrc]! [file]	Always write current key mappings and changed
+			options to [file] (default ".exrc" in the current
+			directory).  {not in Vi}
+
+							*:mkv* *:mkvimrc*
+:mkv[imrc][!] [file]	Like ":mkexrc", but the default is ".vimrc" in the
+			current directory.  The ":version" command is also
+			written to the file.  {not in Vi}
+
+These commands will write ":map" and ":set" commands to a file, in such a way
+that when these commands are executed, the current key mappings and options
+will be set to the same values.  The options 'columns', 'endofline',
+'fileformat', 'key', 'lines', 'modified', 'scroll', 'term', 'textmode',
+'ttyfast' and 'ttymouse' are not included, because these are terminal or file
+dependent.  Note that the options 'binary', 'paste' and 'readonly' are
+included, this might not always be what you want.
+
+When special keys are used in mappings, The 'cpoptions' option will be
+temporarily set to its Vim default, to avoid the mappings to be
+misinterpreted.  This makes the file incompatible with Vi, but makes sure it
+can be used with different terminals.
+
+Only global mappings are stored, not mappings local to a buffer.
+
+A common method is to use a default ".vimrc" file, make some modifications
+with ":map" and ":set" commands and write the modified file.  First read the
+default ".vimrc" in with a command like ":source ~piet/.vimrc.Cprogs", change
+the settings and then save them in the current directory with ":mkvimrc!".  If
+you want to make this file your default .vimrc, move it to your home directory
+(on Unix), s: (Amiga) or $VIM directory (MS-DOS).  You could also use
+autocommands |autocommand| and/or modelines |modeline|.
+
+						*vimrc-option-example*
+If you only want to add a single option setting to your vimrc, you can use
+these steps:
+1. Edit your vimrc file with Vim.
+2. Play with the option until it's right.  E.g., try out different values for
+   'guifont'.
+3. Append a line to set the value of the option, using the expression register
+   '=' to enter the value.  E.g., for the 'guifont' option: >
+   o:set guifont=<C-R>=&guifont<CR><Esc>
+<  [<C-R> is a CTRL-R, <CR> is a return, <Esc> is the escape key]
+   You need to escape special characters, esp. spaces.
+
+Note that when you create a .vimrc file, this can influence the 'compatible'
+option, which has several side effects.  See |'compatible'|.
+":mkvimrc", ":mkexrc" and ":mksession" write the command to set or reset the
+'compatible' option to the output file first, because of these side effects.
+
+==============================================================================
+8. Views and Sessions					*views-sessions*
+
+This is introduced in sections |21.4| and |21.5| of the user manual.
+
+						*View* *view-file*
+A View is a collection of settings that apply to one window.  You can save a
+View and when you restore it later, the text is displayed in the same way.
+The options and mappings in this window will also be restored, so that you can
+continue editing like when the View was saved.
+
+						*Session* *session-file*
+A Session keeps the Views for all windows, plus the global settings.  You can
+save a Session and when you restore it later the window layout looks the same.
+You can use a Session to quickly switch between different projects,
+automatically loading the files you were last working on in that project.
+
+Views and Sessions are a nice addition to viminfo-files, which are used to
+remember information for all Views and Sessions together |viminfo-file|.
+
+You can quickly start editing with a previously saved View or Session with the
+|-S| argument: >
+	vim -S Session.vim
+<
+All this is {not in Vi} and {not available when compiled without the
+|+mksession| feature}.
+
+							*:mks* *:mksession*
+:mks[ession][!] [file]	Write a Vim script that restores the current editing
+			session.
+			When [!] is included an existing file is overwritten.
+			When [file] is omitted "Session.vim" is used.
+
+The output of ":mksession" is like ":mkvimrc", but additional commands are
+added to the file.  Which ones depends on the 'sessionoptions' option.  The
+resulting file, when executed with a ":source" command:
+1. Restores global mappings and options, if 'sessionoptions' contains
+   "options".  Script-local mappings will not be written.
+2. Restores global variables that start with an uppercase letter and contain
+   at least one lowercase letter, if 'sessionoptions' contains "globals".
+3. Unloads all currently loaded buffers.
+4. Restores the current directory if 'sessionoptions' contains "curdir", or
+   sets the current directory to where the Session file is if 'sessionoptions'
+   contains "sesdir".
+5. Restores GUI Vim window position, if 'sessionoptions' contains "winpos".
+6. Restores screen size, if 'sessionoptions' contains "resize".
+7. Reloads the buffer list, with the last cursor positions.  If
+   'sessionoptions' contains "buffers" then all buffers are restored,
+   including hidden and unloaded buffers.  Otherwise only buffers in windows
+   are restored.
+8. Restores all windows with the same layout.  If 'sessionoptions' contains
+   "help", help windows are restored.  If 'sessionoptions' contains "blank",
+   windows editing a buffer without a name will be restored.
+   If 'sessionoptions' contains "winsize" and no (help/blank) windows were
+   left out, the window sizes are restored (relative to the screen size).
+   Otherwise, the windows are just given sensible sizes.
+9. Restores the Views for all the windows, as with |:mkview|.  But
+   'sessionoptions' is used instead of 'viewoptions'.
+10. If a file exists with the same name as the Session file, but ending in
+   "x.vim" (for eXtra), executes that as well.  You can use *x.vim files to
+   specify additional settings and actions associated with a given Session,
+   such as creating menu items in the GUI version.
+
+After restoring the Session, the full filename of your current Session is
+available in the internal variable "v:this_session" |this_session-variable|.
+An example mapping: >
+  :nmap <F2> :wa<Bar>exe "mksession! " . v:this_session<CR>:so ~/sessions/
+This saves the current Session, and starts off the command to load another.
+
+A session includes all tab pages, unless "tabpages" was removed from
+'sessionoptions'. |tab-page|
+
+The |SessionLoadPost| autocmd event is triggered after a session file is
+loaded/sourced.
+						*SessionLoad-variable*
+While the session file is loading the SessionLoad global variable is set to 1.
+Plugins can use this to postpone some work until the SessionLoadPost event is
+triggered.
+
+							*:mkvie* *:mkview*
+:mkvie[w][!] [file]	Write a Vim script that restores the contents of the
+			current window.
+			When [!] is included an existing file is overwritten.
+			When [file] is omitted or is a number from 1 to 9, a
+			name is generated and 'viewdir' prepended.  When the
+			last directory name in 'viewdir' does not exist, this
+			directory is created.
+			An existing file is always overwritten then.  Use
+			|:loadview| to load this view again.
+			When [file] is the name of a file ('viewdir' is not
+			used), a command to edit the file is added to the
+			generated file.
+
+The output of ":mkview" contains these items:
+1. The argument list used in the window.  When the global argument list is
+   used it is reset to the global list.
+   The index in the argument list is also restored.
+2. The file being edited in the window.  If there is no file, the window is
+   made empty.
+3. Restore mappings, abbreviations and options local to the window if
+   'viewoptions' contains "options" or "localoptions".  For the options it
+   restores only values that are local to the current buffer and values local
+   to the window.
+   When storing the view as part of a session and "options" is in
+   'sessionoptions', global values for local options will be stored too.
+4. Restore folds when using manual folding and 'viewoptions' contains
+   "folds".  Restore manually opened and closed folds.
+5. The scroll position and the cursor position in the file.  Doesn't work very
+   well when there are closed folds.
+6. The local current directory, if it is different from the global current
+   directory.
+
+Note that Views and Sessions are not perfect:
+- They don't restore everything.  For example, defined functions, autocommands
+  and ":syntax on" are not included.  Things like register contents and
+  command line history are in viminfo, not in Sessions or Views.
+- Global option values are only set when they differ from the default value.
+  When the current value is not the default value, loading a Session will not
+  set it back to the default value.  Local options will be set back to the
+  default value though.
+- Existing mappings will be overwritten without warning.  An existing mapping
+  may cause an error for ambiguity.
+- When storing manual folds and when storing manually opened/closed folds,
+  changes in the file between saving and loading the view will mess it up.
+- The Vim script is not very efficient.  But still faster than typing the
+  commands yourself!
+
+							*:lo* *:loadview*
+:lo[adview] [nr]	Load the view for the current file.  When [nr] is
+			omitted, the view stored with ":mkview" is loaded.
+			When [nr] is specified, the view stored with ":mkview
+			[nr]" is loaded.
+
+The combination of ":mkview" and ":loadview" can be used to store up to ten
+different views of a file.  These are remembered in the directory specified
+with the 'viewdir' option.  The views are stored using the file name.  If a
+file is renamed or accessed through a (symbolic) link the view will not be
+found.
+
+You might want to clean up your 'viewdir' directory now and then.
+
+To automatically save and restore views for *.c files: >
+	au BufWinLeave *.c mkview
+	au BufWinEnter *.c silent loadview
+
+==============================================================================
+9. The viminfo file				*viminfo* *viminfo-file* *E136*
+						*E575* *E576* *E577*
+If you exit Vim and later start it again, you would normally lose a lot of
+information.  The viminfo file can be used to remember that information, which
+enables you to continue where you left off.
+
+This is introduced in section |21.3| of the user manual.
+
+The viminfo file is used to store:
+- The command line history.
+- The search string history.
+- The input-line history.
+- Contents of non-empty registers.
+- Marks for several files.
+- File marks, pointing to locations in files.
+- Last search/substitute pattern (for 'n' and '&').
+- The buffer list.
+- Global variables.
+
+The viminfo file is not supported when the |+viminfo| feature has been
+disabled at compile time.
+
+You could also use a Session file.  The difference is that the viminfo file
+does not depend on what you are working on.  There normally is only one
+viminfo file.  Session files are used to save the state of a specific editing
+Session.  You could have several Session files, one for each project you are
+working on.  Viminfo and Session files together can be used to effectively
+enter Vim and directly start working in your desired setup. |session-file|
+
+							*viminfo-read*
+When Vim is started and the 'viminfo' option is non-empty, the contents of
+the viminfo file are read and the info can be used in the appropriate places.
+The marks are not read in at startup (but file marks are).  See
+|initialization| for how to set the 'viminfo' option upon startup.
+
+							*viminfo-write*
+When Vim exits and 'viminfo' is non-empty, the info is stored in the viminfo
+file (it's actually merged with the existing one, if one exists).  The
+'viminfo' option is a string containing information about what info should be
+stored, and contains limits on how much should be stored (see 'viminfo').
+
+Notes for Unix:
+- The file protection for the viminfo file will be set to prevent other users
+  from being able to read it, because it may contain any text or commands that
+  you have worked with.
+- If you want to share the viminfo file with other users (e.g. when you "su"
+  to another user), you can make the file writable for the group or everybody.
+  Vim will preserve this when writing new viminfo files.  Be careful, don't
+  allow just anybody to read and write your viminfo file!
+- Vim will not overwrite a viminfo file that is not writable by the current
+  "real" user.  This helps for when you did "su" to become root, but your
+  $HOME is still set to a normal user's home directory.  Otherwise Vim would
+  create a viminfo file owned by root that nobody else can read.
+- The viminfo file cannot be a symbolic link.  This is to avoid security
+  issues.
+
+Marks are stored for each file separately.  When a file is read and 'viminfo'
+is non-empty, the marks for that file are read from the viminfo file.  NOTE:
+The marks are only written when exiting Vim, which is fine because marks are
+remembered for all the files you have opened in the current editing session,
+unless ":bdel" is used.  If you want to save the marks for a file that you are
+about to abandon with ":bdel", use ":wv".  The '[' and ']' marks are not
+stored, but the '"' mark is.  The '"' mark is very useful for jumping to the
+cursor position when the file was last exited.  No marks are saved for files
+that start with any string given with the "r" flag in 'viminfo'.  This can be
+used to avoid saving marks for files on removable media (for MS-DOS you would
+use "ra:,rb:", for Amiga "rdf0:,rdf1:,rdf2:").
+
+							*viminfo-file-marks*
+Uppercase marks ('A to 'Z) are stored when writing the viminfo file.  The
+numbered marks ('0 to '9) are a bit special.  When the viminfo file is written
+(when exiting or with the ":wviminfo" command), '0 is set to the current cursor
+position and file.  The old '0 is moved to '1, '1 to '2, etc.  This
+resembles what happens with the "1 to "9 delete registers.  If the current
+cursor position is already present in '0 to '9, it is moved to '0, to avoid
+having the same position twice.  The result is that with "'0", you can jump
+back to the file and line where you exited Vim.  To do that right away, try
+using this command: >
+
+	vim -c "normal '0"
+
+In a shell you could make an alias for it: >
+
+	alias lvim vim -c '"'normal "'"0'"'
+
+Use the "r" flag in 'viminfo' to specify for which files no marks should be
+remembered.
+
+
+VIMINFO FILE NAME					*viminfo-file-name*
+
+- The default name of the viminfo file is "$HOME/.viminfo" for Unix and OS/2,
+  "s:.viminfo" for Amiga, "$HOME\_viminfo" for MS-DOS and Win32.  For the last
+  two, when $HOME is not set, "$VIM\_viminfo" is used.  When $VIM is also not
+  set, "c:\_viminfo" is used.  For OS/2 "$VIM/.viminfo" is used when $HOME is
+  not set and $VIM is set.
+- The 'n' flag in the 'viminfo' option can be used to specify another viminfo
+  file name |'viminfo'|.
+- The "-i" Vim argument can be used to set another file name, |-i|.  When the
+  file name given is "NONE" (all uppercase), no viminfo file is ever read or
+  written.  Also not for the commands below!
+- For the commands below, another file name can be given, overriding the
+  default and the name given with 'viminfo' or "-i" (unless it's NONE).
+
+
+CHARACTER ENCODING					*viminfo-encoding*
+
+The text in the viminfo file is encoded as specified with the 'encoding'
+option.  Normally you will always work with the same 'encoding' value, and
+this works just fine.  However, if you read the viminfo file with another
+value for 'encoding' than what it was written with, some of the text
+(non-ASCII characters) may be invalid.  If this is unacceptable, add the 'c'
+flag to the 'viminfo' option: >
+	:set viminfo+=c
+Vim will then attempt to convert the text in the viminfo file from the
+'encoding' value it was written with to the current 'encoding' value.  This
+requires Vim to be compiled with the |+iconv| feature.  Filenames are not
+converted.
+
+
+MANUALLY READING AND WRITING
+
+Two commands can be used to read and write the viminfo file manually.  This
+can be used to exchange registers between two running Vim programs: First
+type ":wv" in one and then ":rv" in the other.  Note that if the register
+already contained something, then ":rv!" would be required.  Also note
+however that this means everything will be overwritten with information from
+the first Vim, including the command line history, etc.
+
+The viminfo file itself can be edited by hand too, although we suggest you
+start with an existing one to get the format right.  It is reasonably
+self-explanatory once you're in there.  This can be useful in order to
+create a second file, say "~/.my_viminfo" which could contain certain
+settings that you always want when you first start Vim.  For example, you
+can preload registers with particular data, or put certain commands in the
+command line history.  A line in your .vimrc file like >
+	:rviminfo! ~/.my_viminfo
+can be used to load this information.  You could even have different viminfos
+for different types of files (e.g., C code) and load them based on the file
+name, using the ":autocmd" command (see |:autocmd|).
+
+							*viminfo-errors*
+When Vim detects an error while reading a viminfo file, it will not overwrite
+that file.  If there are more than 10 errors, Vim stops reading the viminfo
+file.  This was done to avoid accidentally destroying a file when the file
+name of the viminfo file is wrong.  This could happen when accidentally typing
+"vim -i file" when you wanted "vim -R file" (yes, somebody accidentally did
+that!).  If you want to overwrite a viminfo file with an error in it, you will
+either have to fix the error, or delete the file (while Vim is running, so
+most of the information will be restored).
+
+						   *:rv* *:rviminfo* *E195*
+:rv[iminfo][!] [file]	Read from viminfo file [file] (default: see above).
+			If [!] is given, then any information that is
+			already set (registers, marks, etc.) will be
+			overwritten.  {not in Vi}
+
+					*:wv* *:wviminfo* *E137* *E138* *E574*
+:wv[iminfo][!] [file]	Write to viminfo file [file] (default: see above).
+			The information in the file is first read in to make
+			a merge between old and new info.  When [!] is used,
+			the old information is not read first, only the
+			internal info is written.  If 'viminfo' is empty, marks
+			for up to 100 files will be written.
+			When you get error "E138: Can't write viminfo file"
+			check that no old temp files were left behind (e.g.
+			~/.viminf*) and that you can write in the directory of
+			the .viminfo file.
+			{not in Vi}
+
+ vim:tw=78:ts=8:ft=help:norl:
--- /dev/null
+++ b/lib/vimfiles/doc/syntax.txt
@@ -1,0 +1,4530 @@
+*syntax.txt*	For Vim version 7.1.  Last change: 2007 May 11
+
+
+		  VIM REFERENCE MANUAL	  by Bram Moolenaar
+
+
+Syntax highlighting		*syntax* *syntax-highlighting* *coloring*
+
+Syntax highlighting enables Vim to show parts of the text in another font or
+color.	Those parts can be specific keywords or text matching a pattern.  Vim
+doesn't parse the whole file (to keep it fast), so the highlighting has its
+limitations.  Lexical highlighting might be a better name, but since everybody
+calls it syntax highlighting we'll stick with that.
+
+Vim supports syntax highlighting on all terminals.  But since most ordinary
+terminals have very limited highlighting possibilities, it works best in the
+GUI version, gvim.
+
+In the User Manual:
+|usr_06.txt| introduces syntax highlighting.
+|usr_44.txt| introduces writing a syntax file.
+
+1.  Quick start			|:syn-qstart|
+2.  Syntax files		|:syn-files|
+3.  Syntax loading procedure	|syntax-loading|
+4.  Syntax file remarks		|:syn-file-remarks|
+5.  Defining a syntax		|:syn-define|
+6.  :syntax arguments		|:syn-arguments|
+7.  Syntax patterns		|:syn-pattern|
+8.  Syntax clusters		|:syn-cluster|
+9.  Including syntax files	|:syn-include|
+10. Synchronizing		|:syn-sync|
+11. Listing syntax items	|:syntax|
+12. Highlight command		|:highlight|
+13. Linking groups		|:highlight-link|
+14. Cleaning up			|:syn-clear|
+15. Highlighting tags		|tag-highlight|
+16. Color xterms		|xterm-color|
+
+{Vi does not have any of these commands}
+
+Syntax highlighting is not available when the |+syntax| feature has been
+disabled at compile time.
+
+==============================================================================
+1. Quick start						*:syn-qstart*
+
+						*:syn-enable* *:syntax-enable*
+This command switches on syntax highlighting: >
+
+	:syntax enable
+
+What this command actually does is to execute the command >
+	:source $VIMRUNTIME/syntax/syntax.vim
+
+If the VIM environment variable is not set, Vim will try to find
+the path in another way (see |$VIMRUNTIME|).  Usually this works just
+fine.  If it doesn't, try setting the VIM environment variable to the
+directory where the Vim stuff is located.  For example, if your syntax files
+are in the "/usr/vim/vim50/syntax" directory, set $VIMRUNTIME to
+"/usr/vim/vim50".  You must do this in the shell, before starting Vim.
+
+							*:syn-on* *:syntax-on*
+The ":syntax enable" command will keep your current color settings.  This
+allows using ":highlight" commands to set your preferred colors before or
+after using this command.  If you want Vim to overrule your settings with the
+defaults, use: >
+	:syntax on
+<
+					*:hi-normal* *:highlight-normal*
+If you are running in the GUI, you can get white text on a black background
+with: >
+	:highlight Normal guibg=Black guifg=White
+For a color terminal see |:hi-normal-cterm|.
+For setting up your own colors syntax highlighting see |syncolor|.
+
+NOTE: The syntax files on MS-DOS and Windows have lines that end in <CR><NL>.
+The files for Unix end in <NL>.  This means you should use the right type of
+file for your system.  Although on MS-DOS and Windows the right format is
+automatically selected if the 'fileformats' option is not empty.
+
+NOTE: When using reverse video ("gvim -fg white -bg black"), the default value
+of 'background' will not be set until the GUI window is opened, which is after
+reading the |gvimrc|.  This will cause the wrong default highlighting to be
+used.  To set the default value of 'background' before switching on
+highlighting, include the ":gui" command in the |gvimrc|: >
+
+   :gui		" open window and set default for 'background'
+   :syntax on	" start highlighting, use 'background' to set colors
+
+NOTE: Using ":gui" in the |gvimrc| means that "gvim -f" won't start in the
+foreground!  Use ":gui -f" then.
+
+
+You can toggle the syntax on/off with this command >
+   :if exists("syntax_on") | syntax off | else | syntax enable | endif
+
+To put this into a mapping, you can use: >
+   :map <F7> :if exists("syntax_on") <Bar>
+	\   syntax off <Bar>
+	\ else <Bar>
+	\   syntax enable <Bar>
+	\ endif <CR>
+[using the |<>| notation, type this literally]
+
+Details
+The ":syntax" commands are implemented by sourcing a file.  To see exactly how
+this works, look in the file:
+    command		file ~
+    :syntax enable	$VIMRUNTIME/syntax/syntax.vim
+    :syntax on		$VIMRUNTIME/syntax/syntax.vim
+    :syntax manual	$VIMRUNTIME/syntax/manual.vim
+    :syntax off		$VIMRUNTIME/syntax/nosyntax.vim
+Also see |syntax-loading|.
+
+==============================================================================
+2. Syntax files						*:syn-files*
+
+The syntax and highlighting commands for one language are normally stored in
+a syntax file.	The name convention is: "{name}.vim".  Where {name} is the
+name of the language, or an abbreviation (to fit the name in 8.3 characters,
+a requirement in case the file is used on a DOS filesystem).
+Examples:
+	c.vim		perl.vim	java.vim	html.vim
+	cpp.vim		sh.vim		csh.vim
+
+The syntax file can contain any Ex commands, just like a vimrc file.  But
+the idea is that only commands for a specific language are included.  When a
+language is a superset of another language, it may include the other one,
+for example, the cpp.vim file could include the c.vim file: >
+   :so $VIMRUNTIME/syntax/c.vim
+
+The .vim files are normally loaded with an autocommand.  For example: >
+   :au Syntax c	    runtime! syntax/c.vim
+   :au Syntax cpp   runtime! syntax/cpp.vim
+These commands are normally in the file $VIMRUNTIME/syntax/synload.vim.
+
+
+MAKING YOUR OWN SYNTAX FILES				*mysyntaxfile*
+
+When you create your own syntax files, and you want to have Vim use these
+automatically with ":syntax enable", do this:
+
+1. Create your user runtime directory.	You would normally use the first item
+   of the 'runtimepath' option.  Example for Unix: >
+	mkdir ~/.vim
+
+2. Create a directory in there called "syntax".  For Unix: >
+	mkdir ~/.vim/syntax
+
+3. Write the Vim syntax file.  Or download one from the internet.  Then write
+   it in your syntax directory.  For example, for the "mine" syntax: >
+	:w ~/.vim/syntax/mine.vim
+
+Now you can start using your syntax file manually: >
+	:set syntax=mine
+You don't have to exit Vim to use this.
+
+If you also want Vim to detect the type of file, see |new-filetype|.
+
+If you are setting up a system with many users and you don't want each user
+to add the same syntax file, you can use another directory from 'runtimepath'.
+
+
+ADDING TO AN EXISTING SYNTAX FILE		*mysyntaxfile-add*
+
+If you are mostly satisfied with an existing syntax file, but would like to
+add a few items or change the highlighting, follow these steps:
+
+1. Create your user directory from 'runtimepath', see above.
+
+2. Create a directory in there called "after/syntax".  For Unix: >
+	mkdir ~/.vim/after
+	mkdir ~/.vim/after/syntax
+
+3. Write a Vim script that contains the commands you want to use.  For
+   example, to change the colors for the C syntax: >
+	highlight cComment ctermfg=Green guifg=Green
+
+4. Write that file in the "after/syntax" directory.  Use the name of the
+   syntax, with ".vim" added.  For our C syntax: >
+	:w ~/.vim/after/syntax/c.vim
+
+That's it.  The next time you edit a C file the Comment color will be
+different.  You don't even have to restart Vim.
+
+If you have multiple files, you can use the filetype as the directory name.
+All the "*.vim" files in this directory will be used, for example:
+	~/.vim/after/syntax/c/one.vim
+	~/.vim/after/syntax/c/two.vim
+
+
+REPLACING AN EXISTING SYNTAX FILE			*mysyntaxfile-replace*
+
+If you don't like a distributed syntax file, or you have downloaded a new
+version, follow the same steps as for |mysyntaxfile| above.  Just make sure
+that you write the syntax file in a directory that is early in 'runtimepath'.
+Vim will only load the first syntax file found.
+
+
+NAMING CONVENTIONS
+				    *group-name* *{group-name}* *E669* *W18*
+The name for a highlight or syntax group must consist of ASCII letters, digits
+and the underscore.  As a regexp: "[a-zA-Z0-9_]*"
+
+To be able to allow each user to pick his favorite set of colors, there must
+be preferred names for highlight groups that are common for many languages.
+These are the suggested group names (if syntax highlighting works properly
+you can see the actual color, except for "Ignore"):
+
+	*Comment	any comment
+
+	*Constant	any constant
+	 String		a string constant: "this is a string"
+	 Character	a character constant: 'c', '\n'
+	 Number		a number constant: 234, 0xff
+	 Boolean	a boolean constant: TRUE, false
+	 Float		a floating point constant: 2.3e10
+
+	*Identifier	any variable name
+	 Function	function name (also: methods for classes)
+
+	*Statement	any statement
+	 Conditional	if, then, else, endif, switch, etc.
+	 Repeat		for, do, while, etc.
+	 Label		case, default, etc.
+	 Operator	"sizeof", "+", "*", etc.
+	 Keyword	any other keyword
+	 Exception	try, catch, throw
+
+	*PreProc	generic Preprocessor
+	 Include	preprocessor #include
+	 Define		preprocessor #define
+	 Macro		same as Define
+	 PreCondit	preprocessor #if, #else, #endif, etc.
+
+	*Type		int, long, char, etc.
+	 StorageClass	static, register, volatile, etc.
+	 Structure	struct, union, enum, etc.
+	 Typedef	A typedef
+
+	*Special	any special symbol
+	 SpecialChar	special character in a constant
+	 Tag		you can use CTRL-] on this
+	 Delimiter	character that needs attention
+	 SpecialComment	special things inside a comment
+	 Debug		debugging statements
+
+	*Underlined	text that stands out, HTML links
+
+	*Ignore		left blank, hidden
+
+	*Error		any erroneous construct
+
+	*Todo		anything that needs extra attention; mostly the
+			keywords TODO FIXME and XXX
+
+The names marked with * are the preferred groups; the others are minor groups.
+For the preferred groups, the "syntax.vim" file contains default highlighting.
+The minor groups are linked to the preferred groups, so they get the same
+highlighting.  You can override these defaults by using ":highlight" commands
+after sourcing the "syntax.vim" file.
+
+Note that highlight group names are not case sensitive.  "String" and "string"
+can be used for the same group.
+
+The following names are reserved and cannot be used as a group name:
+	NONE   ALL   ALLBUT   contains	 contained
+
+==============================================================================
+3. Syntax loading procedure				*syntax-loading*
+
+This explains the details that happen when the command ":syntax enable" is
+issued.  When Vim initializes itself, it finds out where the runtime files are
+located.  This is used here as the variable |$VIMRUNTIME|.
+
+":syntax enable" and ":syntax on" do the following:
+
+    Source $VIMRUNTIME/syntax/syntax.vim
+    |
+    +-	Clear out any old syntax by sourcing $VIMRUNTIME/syntax/nosyntax.vim
+    |
+    +-	Source first syntax/synload.vim in 'runtimepath'
+    |	|
+    |	+-  Setup the colors for syntax highlighting.  If a color scheme is
+    |	|   defined it is loaded again with ":colors {name}".  Otherwise
+    |	|   ":runtime! syntax/syncolor.vim" is used.  ":syntax on" overrules
+    |	|   existing colors, ":syntax enable" only sets groups that weren't
+    |	|   set yet.
+    |	|
+    |	+-  Set up syntax autocmds to load the appropriate syntax file when
+    |	|   the 'syntax' option is set. *synload-1*
+    |	|
+    |	+-  Source the user's optional file, from the |mysyntaxfile| variable.
+    |	    This is for backwards compatibility with Vim 5.x only. *synload-2*
+    |
+    +-	Do ":filetype on", which does ":runtime! filetype.vim".  It loads any
+    |	filetype.vim files found.  It should always Source
+    |	$VIMRUNTIME/filetype.vim, which does the following.
+    |	|
+    |	+-  Install autocmds based on suffix to set the 'filetype' option
+    |	|   This is where the connection between file name and file type is
+    |	|   made for known file types. *synload-3*
+    |	|
+    |	+-  Source the user's optional file, from the *myfiletypefile*
+    |	|   variable.  This is for backwards compatibility with Vim 5.x only.
+    |	|   *synload-4*
+    |	|
+    |	+-  Install one autocommand which sources scripts.vim when no file
+    |	|   type was detected yet. *synload-5*
+    |	|
+    |	+-  Source $VIMRUNTIME/menu.vim, to setup the Syntax menu. |menu.vim|
+    |
+    +-	Install a FileType autocommand to set the 'syntax' option when a file
+    |	type has been detected. *synload-6*
+    |
+    +-	Execute syntax autocommands to start syntax highlighting for each
+	already loaded buffer.
+
+
+Upon loading a file, Vim finds the relevant syntax file as follows:
+
+    Loading the file triggers the BufReadPost autocommands.
+    |
+    +-	If there is a match with one of the autocommands from |synload-3|
+    |	(known file types) or |synload-4| (user's file types), the 'filetype'
+    |	option is set to the file type.
+    |
+    +-	The autocommand at |synload-5| is triggered.  If the file type was not
+    |	found yet, then scripts.vim is searched for in 'runtimepath'.  This
+    |	should always load $VIMRUNTIME/scripts.vim, which does the following.
+    |	|
+    |	+-  Source the user's optional file, from the *myscriptsfile*
+    |	|   variable.  This is for backwards compatibility with Vim 5.x only.
+    |	|
+    |	+-  If the file type is still unknown, check the contents of the file,
+    |	    again with checks like "getline(1) =~ pattern" as to whether the
+    |	    file type can be recognized, and set 'filetype'.
+    |
+    +-	When the file type was determined and 'filetype' was set, this
+    |	triggers the FileType autocommand |synload-6| above.  It sets
+    |	'syntax' to the determined file type.
+    |
+    +-	When the 'syntax' option was set above, this triggers an autocommand
+    |	from |synload-1| (and |synload-2|).  This find the main syntax file in
+    |	'runtimepath', with this command:
+    |		runtime! syntax/<name>.vim
+    |
+    +-	Any other user installed FileType or Syntax autocommands are
+	triggered.  This can be used to change the highlighting for a specific
+	syntax.
+
+==============================================================================
+4. Syntax file remarks					*:syn-file-remarks*
+
+						*b:current_syntax-variable*
+Vim stores the name of the syntax that has been loaded in the
+"b:current_syntax" variable.  You can use this if you want to load other
+settings, depending on which syntax is active.	Example: >
+   :au BufReadPost * if b:current_syntax == "csh"
+   :au BufReadPost *   do-some-things
+   :au BufReadPost * endif
+
+
+2HTML						*2html.vim* *convert-to-HTML*
+
+This is not a syntax file itself, but a script that converts the current
+window into HTML.  Vim opens a new window in which it builds the HTML file.
+
+You are not supposed to set the 'filetype' or 'syntax' option to "2html"!
+Source the script to convert the current file: >
+
+	:runtime! syntax/2html.vim
+<
+Warning: This is slow!
+							*:TOhtml*
+Or use the ":TOhtml" user command.  It is defined in a standard plugin.
+":TOhtml" also works with a range and in a Visual area: >
+
+	:10,40TOhtml
+
+After you save the resulting file, you can view it with any HTML viewer, such
+as Netscape.  The colors should be exactly the same as you see them in Vim.
+
+To restrict the conversion to a range of lines set "html_start_line" and
+"html_end_line" to the first and last line to be converted.  Example, using
+the last set Visual area: >
+
+	:let html_start_line = line("'<")
+	:let html_end_line = line("'>")
+
+The lines are numbered according to 'number' option and the Number
+highlighting.  You can force lines to be numbered in the HTML output by
+setting "html_number_lines" to non-zero value: >
+   :let html_number_lines = 1
+Force to omit the line numbers by using a zero value: >
+   :let html_number_lines = 0
+Go back to the default to use 'number' by deleting the variable: >
+   :unlet html_number_lines
+
+Closed folds are put in the HTML as they are displayed.  If you don't want
+this, use the |zR| command before invoking 2html, or use: >
+   :let html_ignore_folding = 1
+
+By default, HTML optimized for old browsers is generated.  If you prefer using
+cascading style sheets (CSS1) for the attributes (resulting in considerably
+shorter and valid HTML 4 file), use: >
+   :let html_use_css = 1
+
+By default "<pre>" and "</pre>" is used around the text.  This makes it show
+up as you see it in Vim, but without wrapping.	If you prefer wrapping, at the
+risk of making some things look a bit different, use: >
+   :let html_no_pre = 1
+This will use <br> at the end of each line and use "&nbsp;" for repeated
+spaces.
+
+The current value of 'encoding' is used to specify the charset of the HTML
+file.  This only works for those values of 'encoding' that have an equivalent
+HTML charset name.  To overrule this set g:html_use_encoding to the name of
+the charset to be used: >
+   :let html_use_encoding = "foobar"
+To omit the line that specifies the charset, set g:html_use_encoding to an
+empty string: >
+   :let html_use_encoding = ""
+To go back to the automatic mechanism, delete the g:html_use_encoding
+variable: >
+   :unlet html_use_encoding
+<
+For diff mode a sequence of more than 3 filler lines is displayed as three
+lines with the middle line mentioning the total number of inserted lines.  If
+you prefer to see all the inserted lines use: >
+    :let html_whole_filler = 1
+And to go back to displaying up to three lines again: >
+    :unlet html_whole_filler
+<
+					    *convert-to-XML* *convert-to-XHTML*
+An alternative is to have the script generate XHTML (XML compliant HTML).  To
+do this set the "use_xhtml" variable: >
+    :let use_xhtml = 1
+To disable it again delete the variable: >
+    :unlet use_xhtml
+The generated XHTML file can be used in DocBook XML documents.  See:
+	http://people.mech.kuleuven.ac.be/~pissaris/howto/src2db.html
+
+Remarks:
+- This only works in a version with GUI support.  If the GUI is not actually
+  running (possible for X11) it still works, but not very well (the colors
+  may be wrong).
+- Older browsers will not show the background colors.
+- From most browsers you can also print the file (in color)!
+
+Here is an example how to run the script over all .c and .h files from a
+Unix shell: >
+   for f in *.[ch]; do gvim -f +"syn on" +"run! syntax/2html.vim" +"wq" +"q" $f; done
+<
+
+ABEL						*abel.vim* *ft-abel-syntax*
+
+ABEL highlighting provides some user-defined options.  To enable them, assign
+any value to the respective variable.  Example: >
+	:let abel_obsolete_ok=1
+To disable them use ":unlet".  Example: >
+	:unlet abel_obsolete_ok
+
+Variable			Highlight ~
+abel_obsolete_ok		obsolete keywords are statements, not errors
+abel_cpp_comments_illegal	do not interpret '//' as inline comment leader
+
+
+ADA
+
+See |ft-ada-syntax|
+
+
+ANT						*ant.vim* *ft-ant-syntax*
+
+The ant syntax file provides syntax highlighting for javascript and python
+by default.  Syntax highlighting for other script languages can be installed
+by the function AntSyntaxScript(), which takes the tag name as first argument
+and the script syntax file name as second argument.  Example: >
+
+	:call AntSyntaxScript('perl', 'perl.vim')
+
+will install syntax perl highlighting for the following ant code >
+
+	<script language = 'perl'><![CDATA[
+	    # everything inside is highlighted as perl
+	]]></script>
+
+See |mysyntaxfile-add| for installing script languages permanently.
+
+
+APACHE						*apache.vim* *ft-apache-syntax*
+
+The apache syntax file provides syntax highlighting depending on Apache HTTP
+server version, by default for 1.3.x.  Set "apache_version" to Apache version
+(as a string) to get highlighting for another version.	Example: >
+
+	:let apache_version = "2.0"
+<
+
+		*asm.vim* *asmh8300.vim* *nasm.vim* *masm.vim* *asm68k*
+ASSEMBLY	*ft-asm-syntax* *ft-asmh8300-syntax* *ft-nasm-syntax*
+		*ft-masm-syntax* *ft-asm68k-syntax* *fasm.vim*
+
+Files matching "*.i" could be Progress or Assembly.  If the automatic detection
+doesn't work for you, or you don't edit Progress at all, use this in your
+startup vimrc: >
+   :let filetype_i = "asm"
+Replace "asm" with the type of assembly you use.
+
+There are many types of assembly languages that all use the same file name
+extensions.  Therefore you will have to select the type yourself, or add a
+line in the assembly file that Vim will recognize.  Currently these syntax
+files are included:
+	asm		GNU assembly (the default)
+	asm68k		Motorola 680x0 assembly
+	asmh8300	Hitachi H-8300 version of GNU assembly
+	ia64		Intel Itanium 64
+	fasm		Flat assembly (http://flatassembler.net)
+	masm		Microsoft assembly (probably works for any 80x86)
+	nasm		Netwide assembly
+	tasm		Turbo Assembly (with opcodes 80x86 up to Pentium, and
+			MMX)
+	pic		PIC assembly (currently for PIC16F84)
+
+The most flexible is to add a line in your assembly file containing: >
+	:asmsyntax=nasm
+Replace "nasm" with the name of the real assembly syntax.  This line must be
+one of the first five lines in the file.
+
+The syntax type can always be overruled for a specific buffer by setting the
+b:asmsyntax variable: >
+	:let b:asmsyntax=nasm
+
+If b:asmsyntax is not set, either automatically or by hand, then the value of
+the global variable asmsyntax is used.	This can be seen as a default assembly
+language: >
+	:let asmsyntax=nasm
+
+As a last resort, if nothing is defined, the "asm" syntax is used.
+
+
+Netwide assembler (nasm.vim) optional highlighting ~
+
+To enable a feature: >
+	:let   {variable}=1|set syntax=nasm
+To disable a feature: >
+	:unlet {variable}  |set syntax=nasm
+
+Variable		Highlight ~
+nasm_loose_syntax	unofficial parser allowed syntax not as Error
+			  (parser dependent; not recommended)
+nasm_ctx_outside_macro	contexts outside macro not as Error
+nasm_no_warn		potentially risky syntax not as ToDo
+
+
+ASPPERL and ASPVBS			*ft-aspperl-syntax* *ft-aspvbs-syntax*
+
+*.asp and *.asa files could be either Perl or Visual Basic script.  Since it's
+hard to detect this you can set two global variables to tell Vim what you are
+using.	For Perl script use: >
+	:let g:filetype_asa = "aspperl"
+	:let g:filetype_asp = "aspperl"
+For Visual Basic use: >
+	:let g:filetype_asa = "aspvbs"
+	:let g:filetype_asp = "aspvbs"
+
+
+BAAN						    *baan.vim* *baan-syntax*
+
+The baan.vim gives syntax support for BaanC of release BaanIV upto SSA ERP LN
+for both 3 GL and 4 GL programming. Large number of standard defines/constants
+are supported.
+
+Some special violation of coding standards will be signalled when one specify
+in ones |.vimrc|: >
+	let baan_code_stds=1
+
+*baan-folding*
+
+Syntax folding can be enabled at various levels through the variables
+mentioned below (Set those in your |.vimrc|). The more complex folding on
+source blocks and SQL can be CPU intensive.
+
+To allow any folding and enable folding at function level use: >
+	let baan_fold=1
+Folding can be enabled at source block level as if, while, for ,... The
+indentation preceding the begin/end keywords has to match (spaces are not
+considered equal to a tab). >
+	let baan_fold_block=1
+Folding can be enabled for embedded SQL blocks as SELECT, SELECTDO,
+SELECTEMPTY, ... The indentation preceding the begin/end keywords has to
+match (spaces are not considered equal to a tab). >
+	let baan_fold_sql=1
+Note: Block folding can result in many small folds. It is suggested to |:set|
+the options 'foldminlines' and 'foldnestmax' in |.vimrc| or use |:setlocal| in
+.../after/syntax/baan.vim (see |after-directory|). Eg: >
+	set foldminlines=5
+	set foldnestmax=6
+
+
+BASIC			*basic.vim* *vb.vim* *ft-basic-syntax* *ft-vb-syntax*
+
+Both Visual Basic and "normal" basic use the extension ".bas".	To detect
+which one should be used, Vim checks for the string "VB_Name" in the first
+five lines of the file.  If it is not found, filetype will be "basic",
+otherwise "vb".  Files with the ".frm" extension will always be seen as Visual
+Basic.
+
+
+C							*c.vim* *ft-c-syntax*
+
+A few things in C highlighting are optional.  To enable them assign any value
+to the respective variable.  Example: >
+	:let c_comment_strings=1
+To disable them use ":unlet".  Example: >
+	:unlet c_comment_strings
+
+Variable		Highlight ~
+c_gnu			GNU gcc specific items
+c_comment_strings	strings and numbers inside a comment
+c_space_errors		trailing white space and spaces before a <Tab>
+c_no_trail_space_error	 ... but no trailing spaces
+c_no_tab_space_error	 ... but no spaces before a <Tab>
+c_no_bracket_error	don't highlight {}; inside [] as errors
+c_no_curly_error	don't highlight {}; inside [] and () as errors;
+				except { and } in first column
+c_no_ansi		don't do standard ANSI types and constants
+c_ansi_typedefs		 ... but do standard ANSI types
+c_ansi_constants	 ... but do standard ANSI constants
+c_no_utf		don't highlight \u and \U in strings
+c_syntax_for_h		use C syntax for *.h files, instead of C++
+c_no_if0		don't highlight "#if 0" blocks as comments
+c_no_cformat		don't highlight %-formats in strings
+c_no_c99		don't highlight C99 standard items
+
+When 'foldmethod' is set to "syntax" then /* */ comments and { } blocks will
+become a fold.  If you don't want comments to become a fold use: >
+	:let c_no_comment_fold = 1
+"#if 0" blocks are also folded, unless: >
+	:let c_no_if0_fold = 1
+
+If you notice highlighting errors while scrolling backwards, which are fixed
+when redrawing with CTRL-L, try setting the "c_minlines" internal variable
+to a larger number: >
+	:let c_minlines = 100
+This will make the syntax synchronization start 100 lines before the first
+displayed line.  The default value is 50 (15 when c_no_if0 is set).  The
+disadvantage of using a larger number is that redrawing can become slow.
+
+When using the "#if 0" / "#endif" comment highlighting, notice that this only
+works when the "#if 0" is within "c_minlines" from the top of the window.  If
+you have a long "#if 0" construct it will not be highlighted correctly.
+
+To match extra items in comments, use the cCommentGroup cluster.
+Example: >
+   :au Syntax c call MyCadd()
+   :function MyCadd()
+   :  syn keyword cMyItem contained Ni
+   :  syn cluster cCommentGroup add=cMyItem
+   :  hi link cMyItem Title
+   :endfun
+
+ANSI constants will be highlighted with the "cConstant" group.	This includes
+"NULL", "SIG_IGN" and others.  But not "TRUE", for example, because this is
+not in the ANSI standard.  If you find this confusing, remove the cConstant
+highlighting: >
+	:hi link cConstant NONE
+
+If you see '{' and '}' highlighted as an error where they are OK, reset the
+highlighting for cErrInParen and cErrInBracket.
+
+If you want to use folding in your C files, you can add these lines in a file
+an the "after" directory in 'runtimepath'.  For Unix this would be
+~/.vim/after/syntax/c.vim. >
+    syn region myFold start="{" end="}" transparent fold
+    syn sync fromstart
+    set foldmethod=syntax
+
+CH						*ch.vim* *ft-ch-syntax*
+
+C/C++ interpreter.  Ch has similar syntax highlighting to C and builds upon
+the C syntax file.  See |c.vim| for all the settings that are available for C.
+
+By setting a variable you can tell Vim to use Ch syntax for *.h files, instead
+of C or C++: >
+	:let ch_syntax_for_h = 1
+
+
+CHILL						*chill.vim* *ft-chill-syntax*
+
+Chill syntax highlighting is similar to C.  See |c.vim| for all the settings
+that are available.  Additionally there is:
+
+chill_space_errors	like c_space_errors
+chill_comment_string	like c_comment_strings
+chill_minlines		like c_minlines
+
+
+CHANGELOG				*changelog.vim* *ft-changelog-syntax*
+
+ChangeLog supports highlighting spaces at the start of a line.
+If you do not like this, add following line to your .vimrc: >
+	let g:changelog_spacing_errors = 0
+This works the next time you edit a changelog file.  You can also use
+"b:changelog_spacing_errors" to set this per buffer (before loading the syntax
+file).
+
+You can change the highlighting used, e.g., to flag the spaces as an error: >
+	:hi link ChangelogError Error
+Or to avoid the highlighting: >
+	:hi link ChangelogError NONE
+This works immediately.
+
+
+COBOL						*cobol.vim* *ft-cobol-syntax*
+
+COBOL highlighting has different needs for legacy code than it does for fresh
+development.  This is due to differences in what is being done (maintenance
+versus development) and other factors.	To enable legacy code highlighting,
+add this line to your .vimrc: >
+	:let cobol_legacy_code = 1
+To disable it again, use this: >
+	:unlet cobol_legacy_code
+
+
+COLD FUSION			*coldfusion.vim* *ft-coldfusion-syntax*
+
+The ColdFusion has its own version of HTML comments.  To turn on ColdFusion
+comment highlighting, add the following line to your startup file: >
+
+	:let html_wrong_comments = 1
+
+The ColdFusion syntax file is based on the HTML syntax file.
+
+
+CSH						*csh.vim* *ft-csh-syntax*
+
+This covers the shell named "csh".  Note that on some systems tcsh is actually
+used.
+
+Detecting whether a file is csh or tcsh is notoriously hard.  Some systems
+symlink /bin/csh to /bin/tcsh, making it almost impossible to distinguish
+between csh and tcsh.  In case VIM guesses wrong you can set the
+"filetype_csh" variable.  For using csh: >
+
+	:let filetype_csh = "csh"
+
+For using tcsh: >
+
+	:let filetype_csh = "tcsh"
+
+Any script with a tcsh extension or a standard tcsh filename (.tcshrc,
+tcsh.tcshrc, tcsh.login) will have filetype tcsh.  All other tcsh/csh scripts
+will be classified as tcsh, UNLESS the "filetype_csh" variable exists.  If the
+"filetype_csh" variable exists, the filetype will be set to the value of the
+variable.
+
+
+CYNLIB						*cynlib.vim* *ft-cynlib-syntax*
+
+Cynlib files are C++ files that use the Cynlib class library to enable
+hardware modelling and simulation using C++.  Typically Cynlib files have a .cc
+or a .cpp extension, which makes it very difficult to distinguish them from a
+normal C++ file.  Thus, to enable Cynlib highlighting for .cc files, add this
+line to your .vimrc file: >
+
+	:let cynlib_cyntax_for_cc=1
+
+Similarly for cpp files (this extension is only usually used in Windows) >
+
+	:let cynlib_cyntax_for_cpp=1
+
+To disable these again, use this: >
+
+	:unlet cynlib_cyntax_for_cc
+	:unlet cynlib_cyntax_for_cpp
+<
+
+CWEB						*cweb.vim* *ft-cweb-syntax*
+
+Files matching "*.w" could be Progress or cweb.  If the automatic detection
+doesn't work for you, or you don't edit Progress at all, use this in your
+startup vimrc: >
+   :let filetype_w = "cweb"
+
+
+DESKTOP					   *desktop.vim* *ft-desktop-syntax*
+
+Primary goal of this syntax file is to highlight .desktop and .directory files
+according to freedesktop.org standard: http://pdx.freedesktop.org/Standards/
+But actually almost none implements this standard fully.  Thus it will
+highlight all Unix ini files.  But you can force strict highlighting according
+to standard by placing this in your vimrc file: >
+	:let enforce_freedesktop_standard = 1
+
+
+DIRCOLORS			       *dircolors.vim* *ft-dircolors-syntax*
+
+The dircolors utility highlighting definition has one option.  It exists to
+provide compatibility with the Slackware GNU/Linux distributions version of
+the command.  It adds a few keywords that are generally ignored by most
+versions.  On Slackware systems, however, the utility accepts the keywords and
+uses them for processing.  To enable the Slackware keywords add the following
+line to your startup file: >
+	let dircolors_is_slackware = 1
+
+
+DOCBOOK					*docbk.vim* *ft-docbk-syntax* *docbook*
+DOCBOOK	XML				*docbkxml.vim* *ft-docbkxml-syntax*
+DOCBOOK	SGML				*docbksgml.vim* *ft-docbksgml-syntax*
+
+There are two types of DocBook files: SGML and XML.  To specify what type you
+are using the "b:docbk_type" variable should be set.  Vim does this for you
+automatically if it can recognize the type.  When Vim can't guess it the type
+defaults to XML.
+You can set the type manually: >
+	:let docbk_type = "sgml"
+or: >
+	:let docbk_type = "xml"
+You need to do this before loading the syntax file, which is complicated.
+Simpler is setting the filetype to "docbkxml" or "docbksgml": >
+	:set filetype=docbksgml
+or: >
+	:set filetype=docbkxml
+
+
+DOSBATCH				*dosbatch.vim* *ft-dosbatch-syntax*
+
+There is one option with highlighting DOS batch files.	This covers new
+extensions to the Command Interpreter introduced with Windows 2000 and
+is controlled by the variable dosbatch_cmdextversion.  For Windows NT
+this should have the value 1, and for Windows 2000 it should be 2.
+Select the version you want with the following line: >
+
+   :let dosbatch_cmdextversion = 1
+
+If this variable is not defined it defaults to a value of 2 to support
+Windows 2000.
+
+A second option covers whether *.btm files should be detected as type
+"dosbatch" (MS-DOS batch files) or type "btm" (4DOS batch files).  The latter
+is used by default.  You may select the former with the following line: >
+
+   :let g:dosbatch_syntax_for_btm = 1
+
+If this variable is undefined or zero, btm syntax is selected.
+
+
+DOXYGEN						*doxygen.vim* *doxygen-syntax*
+
+Doxygen generates code documentation using a special documentation format
+(similar to Javadoc).  This syntax script adds doxygen highlighting to c, cpp
+and idl files, and should also work with java.
+
+There are a few of ways to turn on doxygen formatting. It can be done
+explicitly or in a modeline by appending '.doxygen' to the syntax of the file.
+Example: >
+	:set syntax=c.doxygen
+or >
+	// vim:syntax=c.doxygen
+
+It can also be done automatically for c, cpp and idl files by setting the
+global or buffer-local variable load_doxygen_syntax.  This is done by adding
+the following to your .vimrc. >
+	:let g:load_doxygen_syntax=1
+
+There are a couple of variables that have an affect on syntax highlighting, and
+are to do with non-standard highlighting options.
+
+Variable			Default	Effect ~
+g:doxygen_enhanced_color
+g:doxygen_enhanced_colour	0	Use non-standard highlighting for
+					doxygen comments.
+
+doxygen_my_rendering		0	Disable rendering of HTML bold, italic
+					and html_my_rendering underline.
+
+doxygen_javadoc_autobrief	1	Set to 0 to disable javadoc autobrief
+					colour highlighting.
+
+doxygen_end_punctuation		'[.]'	Set to regexp match for the ending
+					punctuation of brief
+
+There are also some hilight groups worth mentioning as they can be useful in
+configuration.
+
+Highlight			Effect ~
+doxygenErrorComment		The colour of an end-comment when missing
+				punctuation in a code, verbatim or dot section
+doxygenLinkError		The colour of an end-comment when missing the
+				\endlink from a \link section.
+
+
+DTD						*dtd.vim* *ft-dtd-syntax*
+
+The DTD syntax highlighting is case sensitive by default.  To disable
+case-sensitive highlighting, add the following line to your startup file: >
+
+	:let dtd_ignore_case=1
+
+The DTD syntax file will highlight unknown tags as errors.  If
+this is annoying, it can be turned off by setting: >
+
+	:let dtd_no_tag_errors=1
+
+before sourcing the dtd.vim syntax file.
+Parameter entity names are highlighted in the definition using the
+'Type' highlighting group and 'Comment' for punctuation and '%'.
+Parameter entity instances are highlighted using the 'Constant'
+highlighting group and the 'Type' highlighting group for the
+delimiters % and ;.  This can be turned off by setting: >
+
+	:let dtd_no_param_entities=1
+
+The DTD syntax file is also included by xml.vim to highlight included dtd's.
+
+
+EIFFEL					*eiffel.vim* *ft-eiffel-syntax*
+
+While Eiffel is not case-sensitive, its style guidelines are, and the
+syntax highlighting file encourages their use.  This also allows to
+highlight class names differently.  If you want to disable case-sensitive
+highlighting, add the following line to your startup file: >
+
+	:let eiffel_ignore_case=1
+
+Case still matters for class names and TODO marks in comments.
+
+Conversely, for even stricter checks, add one of the following lines: >
+
+	:let eiffel_strict=1
+	:let eiffel_pedantic=1
+
+Setting eiffel_strict will only catch improper capitalization for the
+five predefined words "Current", "Void", "Result", "Precursor", and
+"NONE", to warn against their accidental use as feature or class names.
+
+Setting eiffel_pedantic will enforce adherence to the Eiffel style
+guidelines fairly rigorously (like arbitrary mixes of upper- and
+lowercase letters as well as outdated ways to capitalize keywords).
+
+If you want to use the lower-case version of "Current", "Void",
+"Result", and "Precursor", you can use >
+
+	:let eiffel_lower_case_predef=1
+
+instead of completely turning case-sensitive highlighting off.
+
+Support for ISE's proposed new creation syntax that is already
+experimentally handled by some compilers can be enabled by: >
+
+	:let eiffel_ise=1
+
+Finally, some vendors support hexadecimal constants.  To handle them, add >
+
+	:let eiffel_hex_constants=1
+
+to your startup file.
+
+
+ERLANG						*erlang.vim* *ft-erlang-syntax*
+
+The erlang highlighting supports Erlang (ERicsson LANGuage).
+Erlang is case sensitive and default extension is ".erl".
+
+If you want to disable keywords highlighting, put in your .vimrc: >
+	:let erlang_keywords = 1
+If you want to disable built-in-functions highlighting, put in your
+.vimrc file: >
+	:let erlang_functions = 1
+If you want to disable special characters highlighting, put in
+your .vimrc: >
+	:let erlang_characters = 1
+
+
+FLEXWIKI				*flexwiki.vim* *ft-flexwiki-syntax*
+
+FlexWiki is an ASP.NET-based wiki package available at http://www.flexwiki.com
+
+Syntax highlighting is available for the most common elements of FlexWiki
+syntax. The associated ftplugin script sets some buffer-local options to make
+editing FlexWiki pages more convenient. FlexWiki considers a newline as the
+start of a new paragraph, so the ftplugin sets 'tw'=0 (unlimited line length),
+'wrap' (wrap long lines instead of using horizontal scrolling), 'linebreak'
+(to wrap at a character in 'breakat' instead of at the last char on screen),
+and so on. It also includes some keymaps that are disabled by default.
+
+If you want to enable the keymaps that make "j" and "k" and the cursor keys
+move up and down by display lines, add this to your .vimrc: >
+	:let flexwiki_maps = 1
+
+
+FORM						*form.vim* *ft-form-syntax*
+
+The coloring scheme for syntax elements in the FORM file uses the default
+modes Conditional, Number, Statement, Comment, PreProc, Type, and String,
+following the language specifications in 'Symbolic Manipulation with FORM' by
+J.A.M. Vermaseren, CAN, Netherlands, 1991.
+
+If you want include your own changes to the default colors, you have to
+redefine the following syntax groups:
+
+    - formConditional
+    - formNumber
+    - formStatement
+    - formHeaderStatement
+    - formComment
+    - formPreProc
+    - formDirective
+    - formType
+    - formString
+
+Note that the form.vim syntax file implements FORM preprocessor commands and
+directives per default in the same syntax group.
+
+A predefined enhanced color mode for FORM is available to distinguish between
+header statements and statements in the body of a FORM program.  To activate
+this mode define the following variable in your vimrc file >
+
+	:let form_enhanced_color=1
+
+The enhanced mode also takes advantage of additional color features for a dark
+gvim display.  Here, statements are colored LightYellow instead of Yellow, and
+conditionals are LightBlue for better distinction.
+
+
+FORTRAN					*fortran.vim* *ft-fortran-syntax*
+
+Default highlighting and dialect ~
+Highlighting appropriate for f95 (Fortran 95) is used by default.  This choice
+should be appropriate for most users most of the time because Fortran 95 is a
+superset of Fortran 90 and almost a superset of Fortran 77.
+
+Fortran source code form ~
+Fortran 9x code can be in either fixed or free source form.  Note that the
+syntax highlighting will not be correct if the form is incorrectly set.
+
+When you create a new fortran file, the syntax script assumes fixed source
+form.  If you always use free source form, then >
+    :let fortran_free_source=1
+in your .vimrc prior to the :syntax on command.  If you always use fixed source
+form, then >
+    :let fortran_fixed_source=1
+in your .vimrc prior to the :syntax on command.
+
+If the form of the source code depends upon the file extension, then it is
+most convenient to set fortran_free_source in a ftplugin file.  For more
+information on ftplugin files, see |ftplugin|.  For example, if all your
+fortran files with an .f90 extension are written in free source form and the
+rest in fixed source form, add the following code to your ftplugin file >
+    let s:extfname = expand("%:e")
+    if s:extfname ==? "f90"
+	let fortran_free_source=1
+	unlet! fortran_fixed_source
+    else
+	let fortran_fixed_source=1
+	unlet! fortran_free_source
+    endif
+Note that this will work only if the "filetype plugin indent on" command
+precedes the "syntax on" command in your .vimrc file.
+
+When you edit an existing fortran file, the syntax script will assume free
+source form if the fortran_free_source variable has been set, and assumes
+fixed source form if the fortran_fixed_source variable has been set.  If
+neither of these variables have been set, the syntax script attempts to
+determine which source form has been used by examining the first five columns
+of the first 250 lines of your file.  If no signs of free source form are
+detected, then the file is assumed to be in fixed source form.  The algorithm
+should work in the vast majority of cases.  In some cases, such as a file that
+begins with 250 or more full-line comments, the script may incorrectly decide
+that the fortran code is in fixed form.  If that happens, just add a
+non-comment statement beginning anywhere in the first five columns of the
+first twenty five lines, save (:w) and then reload (:e!) the file.
+
+Tabs in fortran files ~
+Tabs are not recognized by the Fortran standards.  Tabs are not a good idea in
+fixed format fortran source code which requires fixed column boundaries.
+Therefore, tabs are marked as errors.  Nevertheless, some programmers like
+using tabs.  If your fortran files contain tabs, then you should set the
+variable fortran_have_tabs in your .vimrc with a command such as >
+    :let fortran_have_tabs=1
+placed prior to the :syntax on command.  Unfortunately, the use of tabs will
+mean that the syntax file will not be able to detect incorrect margins.
+
+Syntax folding of fortran files ~
+If you wish to use foldmethod=syntax, then you must first set the variable
+fortran_fold with a command such as >
+    :let fortran_fold=1
+to instruct the syntax script to define fold regions for program units, that
+is main programs starting with a program statement, subroutines, function
+subprograms, block data subprograms, interface blocks, and modules.  If you
+also set the variable fortran_fold_conditionals with a command such as >
+    :let fortran_fold_conditionals=1
+then fold regions will also be defined for do loops, if blocks, and select
+case constructs.  If you also set the variable
+fortran_fold_multilinecomments with a command such as >
+    :let fortran_fold_multilinecomments=1
+then fold regions will also be defined for three or more consecutive comment
+lines.  Note that defining fold regions can be slow for large files.
+
+If fortran_fold, and possibly fortran_fold_conditionals and/or
+fortran_fold_multilinecomments, have been set, then vim will fold your file if
+you set foldmethod=syntax.  Comments or blank lines placed between two program
+units are not folded because they are seen as not belonging to any program
+unit.
+
+More precise fortran syntax ~
+If you set the variable fortran_more_precise with a command such as >
+    :let fortran_more_precise=1
+then the syntax coloring will be more precise but slower.  In particular,
+statement labels used in do, goto and arithmetic if statements will be
+recognized, as will construct names at the end of a do, if, select or forall
+construct.
+
+Non-default fortran dialects ~
+The syntax script supports five Fortran dialects: f95, f90, f77, the Lahey
+subset elf90, and the Imagine1 subset F.
+
+If you use f77 with extensions, even common ones like do/enddo loops, do/while
+loops and free source form that are supported by most f77 compilers including
+g77 (GNU Fortran), then you will probably find the default highlighting
+satisfactory.  However, if you use strict f77 with no extensions, not even free
+source form or the MIL STD 1753 extensions, then the advantages of setting the
+dialect to f77 are that names such as SUM are recognized as user variable
+names and not highlighted as f9x intrinsic functions, that obsolete constructs
+such as ASSIGN statements are not highlighted as todo items, and that fixed
+source form will be assumed.
+
+If you use elf90 or F, the advantage of setting the dialect appropriately is
+that f90 features excluded from these dialects will be highlighted as todo
+items and that free source form will be assumed as required for these
+dialects.
+
+The dialect can be selected by setting the variable fortran_dialect.  The
+permissible values of fortran_dialect are case-sensitive and must be "f95",
+"f90", "f77", "elf" or "F".  Invalid values of fortran_dialect are ignored.
+
+If all your fortran files use the same dialect, set fortran_dialect in your
+.vimrc prior to your syntax on statement.  If the dialect depends upon the file
+extension, then it is most convenient to set it in a ftplugin file.  For more
+information on ftplugin files, see |ftplugin|.  For example, if all your
+fortran files with an .f90 extension are written in the elf subset, your
+ftplugin file should contain the code >
+    let s:extfname = expand("%:e")
+    if s:extfname ==? "f90"
+	let fortran_dialect="elf"
+    else
+	unlet! fortran_dialect
+    endif
+Note that this will work only if the "filetype plugin indent on" command
+precedes the "syntax on" command in your .vimrc file.
+
+Finer control is necessary if the file extension does not uniquely identify
+the dialect.  You can override the default dialect, on a file-by-file basis, by
+including a comment with the directive "fortran_dialect=xx" (where xx=f77 or
+elf or F or f90 or f95) in one of the first three lines in your file.  For
+example, your older .f files may be written in extended f77 but your newer
+ones may be F codes, and you would identify the latter by including in the
+first three lines of those files a Fortran comment of the form >
+  ! fortran_dialect=F
+F overrides elf if both directives are present.
+
+Limitations ~
+Parenthesis checking does not catch too few closing parentheses.  Hollerith
+strings are not recognized.  Some keywords may be highlighted incorrectly
+because Fortran90 has no reserved words.
+
+For further information related to fortran, see |ft-fortran-indent| and
+|ft-fortran-plugin|.
+
+
+FVWM CONFIGURATION FILES			*fvwm.vim* *ft-fvwm-syntax*
+
+In order for Vim to recognize Fvwm configuration files that do not match
+the patterns *fvwmrc* or *fvwm2rc* , you must put additional patterns
+appropriate to your system in your myfiletypes.vim file.  For these
+patterns, you must set the variable "b:fvwm_version" to the major version
+number of Fvwm, and the 'filetype' option to fvwm.
+
+For example, to make Vim identify all files in /etc/X11/fvwm2/
+as Fvwm2 configuration files, add the following: >
+
+  :au! BufNewFile,BufRead /etc/X11/fvwm2/*  let b:fvwm_version = 2 |
+					 \ set filetype=fvwm
+
+If you'd like Vim to highlight all valid color names, tell it where to
+find the color database (rgb.txt) on your system.  Do this by setting
+"rgb_file" to its location.  Assuming your color database is located
+in /usr/X11/lib/X11/, you should add the line >
+
+	:let rgb_file = "/usr/X11/lib/X11/rgb.txt"
+
+to your .vimrc file.
+
+
+GSP						*gsp.vim* *ft-gsp-syntax*
+
+The default coloring style for GSP pages is defined by |html.vim|, and
+the coloring for java code (within java tags or inline between backticks)
+is defined by |java.vim|.  The following HTML groups defined in |html.vim|
+are redefined to incorporate and highlight inline java code:
+
+    htmlString
+    htmlValue
+    htmlEndTag
+    htmlTag
+    htmlTagN
+
+Highlighting should look fine most of the places where you'd see inline
+java code, but in some special cases it may not.  To add another HTML
+group where you will have inline java code where it does not highlight
+correctly, just copy the line you want from |html.vim| and add gspJava
+to the contains clause.
+
+The backticks for inline java are highlighted according to the htmlError
+group to make them easier to see.
+
+
+GROFF						*groff.vim* *ft-groff-syntax*
+
+The groff syntax file is a wrapper for |nroff.vim|, see the notes
+under that heading for examples of use and configuration.  The purpose
+of this wrapper is to set up groff syntax extensions by setting the
+filetype from a |modeline| or in a personal filetype definitions file
+(see |filetype.txt|).
+
+
+HASKELL			     *haskell.vim* *lhaskell.vim* *ft-haskell-syntax*
+
+The Haskell syntax files support plain Haskell code as well as literate
+Haskell code, the latter in both Bird style and TeX style.  The Haskell
+syntax highlighting will also highlight C preprocessor directives.
+
+If you want to highlight delimiter characters (useful if you have a
+light-coloured background), add to your .vimrc: >
+	:let hs_highlight_delimiters = 1
+To treat True and False as keywords as opposed to ordinary identifiers,
+add: >
+	:let hs_highlight_boolean = 1
+To also treat the names of primitive types as keywords: >
+	:let hs_highlight_types = 1
+And to treat the names of even more relatively common types as keywords: >
+	:let hs_highlight_more_types = 1
+If you want to highlight the names of debugging functions, put in
+your .vimrc: >
+	:let hs_highlight_debug = 1
+
+The Haskell syntax highlighting also highlights C preprocessor
+directives, and flags lines that start with # but are not valid
+directives as erroneous.  This interferes with Haskell's syntax for
+operators, as they may start with #.  If you want to highlight those
+as operators as opposed to errors, put in your .vimrc: >
+	:let hs_allow_hash_operator = 1
+
+The syntax highlighting for literate Haskell code will try to
+automatically guess whether your literate Haskell code contains
+TeX markup or not, and correspondingly highlight TeX constructs
+or nothing at all.  You can override this globally by putting
+in your .vimrc >
+	:let lhs_markup = none
+for no highlighting at all, or >
+	:let lhs_markup = tex
+to force the highlighting to always try to highlight TeX markup.
+For more flexibility, you may also use buffer local versions of
+this variable, so e.g. >
+	:let b:lhs_markup = tex
+will force TeX highlighting for a particular buffer.  It has to be
+set before turning syntax highlighting on for the buffer or
+loading a file.
+
+
+HTML						*html.vim* *ft-html-syntax*
+
+The coloring scheme for tags in the HTML file works as follows.
+
+The  <> of opening tags are colored differently than the </> of a closing tag.
+This is on purpose! For opening tags the 'Function' color is used, while for
+closing tags the 'Type' color is used (See syntax.vim to check how those are
+defined for you)
+
+Known tag names are colored the same way as statements in C.  Unknown tag
+names are colored with the same color as the <> or </> respectively which
+makes it easy to spot errors
+
+Note that the same is true for argument (or attribute) names.  Known attribute
+names are colored differently than unknown ones.
+
+Some HTML tags are used to change the rendering of text.  The following tags
+are recognized by the html.vim syntax coloring file and change the way normal
+text is shown: <B> <I> <U> <EM> <STRONG> (<EM> is used as an alias for <I>,
+while <STRONG> as an alias for <B>), <H1> - <H6>, <HEAD>, <TITLE> and <A>, but
+only if used as a link (that is, it must include a href as in
+<A href="somefile.html">).
+
+If you want to change how such text is rendered, you must redefine the
+following syntax groups:
+
+    - htmlBold
+    - htmlBoldUnderline
+    - htmlBoldUnderlineItalic
+    - htmlUnderline
+    - htmlUnderlineItalic
+    - htmlItalic
+    - htmlTitle for titles
+    - htmlH1 - htmlH6 for headings
+
+To make this redefinition work you must redefine them all with the exception
+of the last two (htmlTitle and htmlH[1-6], which are optional) and define the
+following variable in your vimrc (this is due to the order in which the files
+are read during initialization) >
+	:let html_my_rendering=1
+
+If you'd like to see an example download mysyntax.vim at
+http://www.fleiner.com/vim/download.html
+
+You can also disable this rendering by adding the following line to your
+vimrc file: >
+	:let html_no_rendering=1
+
+HTML comments are rather special (see an HTML reference document for the
+details), and the syntax coloring scheme will highlight all errors.
+However, if you prefer to use the wrong style (starts with <!-- and
+ends with --!>) you can define >
+	:let html_wrong_comments=1
+
+JavaScript and Visual Basic embedded inside HTML documents are highlighted as
+'Special' with statements, comments, strings and so on colored as in standard
+programming languages.  Note that only JavaScript and Visual Basic are currently
+supported, no other scripting language has been added yet.
+
+Embedded and inlined cascading style sheets (CSS) are highlighted too.
+
+There are several html preprocessor languages out there.  html.vim has been
+written such that it should be trivial to include it.  To do so add the
+following two lines to the syntax coloring file for that language
+(the example comes from the asp.vim file):
+
+    runtime! syntax/html.vim
+    syn cluster htmlPreproc add=asp
+
+Now you just need to make sure that you add all regions that contain
+the preprocessor language to the cluster htmlPreproc.
+
+
+HTML/OS (by Aestiva)				*htmlos.vim* *ft-htmlos-syntax*
+
+The coloring scheme for HTML/OS works as follows:
+
+Functions and variable names are the same color by default, because VIM
+doesn't specify different colors for Functions and Identifiers.  To change
+this (which is recommended if you want function names to be recognizable in a
+different color) you need to add the following line to either your ~/.vimrc: >
+  :hi Function term=underline cterm=bold ctermfg=LightGray
+
+Of course, the ctermfg can be a different color if you choose.
+
+Another issues that HTML/OS runs into is that there is no special filetype to
+signify that it is a file with HTML/OS coding.	You can change this by opening
+a file and turning on HTML/OS syntax by doing the following: >
+  :set syntax=htmlos
+
+Lastly, it should be noted that the opening and closing characters to begin a
+block of HTML/OS code can either be << or [[ and >> or ]], respectively.
+
+
+IA64				*ia64.vim* *intel-itanium* *ft-ia64-syntax*
+
+Highlighting for the Intel Itanium 64 assembly language.  See |asm.vim| for
+how to recognize this filetype.
+
+To have *.inc files be recognized as IA64, add this to your .vimrc file: >
+	:let g:filetype_inc = "ia64"
+
+
+INFORM						*inform.vim* *ft-inform-syntax*
+
+Inform highlighting includes symbols provided by the Inform Library, as
+most programs make extensive use of it.  If do not wish Library symbols
+to be highlighted add this to your vim startup: >
+	:let inform_highlight_simple=1
+
+By default it is assumed that Inform programs are Z-machine targeted,
+and highlights Z-machine assembly language symbols appropriately.  If
+you intend your program to be targeted to a Glulx/Glk environment you
+need to add this to your startup sequence: >
+	:let inform_highlight_glulx=1
+
+This will highlight Glulx opcodes instead, and also adds glk() to the
+set of highlighted system functions.
+
+The Inform compiler will flag certain obsolete keywords as errors when
+it encounters them.  These keywords are normally highlighted as errors
+by Vim.  To prevent such error highlighting, you must add this to your
+startup sequence: >
+	:let inform_suppress_obsolete=1
+
+By default, the language features highlighted conform to Compiler
+version 6.30 and Library version 6.11.  If you are using an older
+Inform development environment, you may with to add this to your
+startup sequence: >
+	:let inform_highlight_old=1
+
+IDL							*idl.vim* *idl-syntax*
+
+IDL (Interface Definition Language) files are used to define RPC calls.  In
+Microsoft land, this is also used for defining COM interfaces and calls.
+
+IDL's structure is simple enough to permit a full grammar based approach to
+rather than using a few heuristics.  The result is large and somewhat
+repetitive but seems to work.
+
+There are some Microsoft extensions to idl files that are here.  Some of them
+are disabled by defining idl_no_ms_extensions.
+
+The more complex of the extensions are disabled by defining idl_no_extensions.
+
+Variable			Effect ~
+
+idl_no_ms_extensions		Disable some of the Microsoft specific
+				extensions
+idl_no_extensions		Disable complex extensions
+idlsyntax_showerror		Show IDL errors (can be rather intrusive, but
+				quite helpful)
+idlsyntax_showerror_soft	Use softer colours by default for errors
+
+
+JAVA						*java.vim* *ft-java-syntax*
+
+The java.vim syntax highlighting file offers several options:
+
+In Java 1.0.2 it was never possible to have braces inside parens, so this was
+flagged as an error.  Since Java 1.1 this is possible (with anonymous
+classes), and therefore is no longer marked as an error.  If you prefer the old
+way, put the following line into your vim startup file: >
+	:let java_mark_braces_in_parens_as_errors=1
+
+All identifiers in java.lang.* are always visible in all classes.  To
+highlight them use: >
+	:let java_highlight_java_lang_ids=1
+
+You can also highlight identifiers of most standard Java packages if you
+download the javaid.vim script at http://www.fleiner.com/vim/download.html.
+If you prefer to only highlight identifiers of a certain package, say java.io
+use the following: >
+	:let java_highlight_java_io=1
+Check the javaid.vim file for a list of all the packages that are supported.
+
+Function names are not highlighted, as the way to find functions depends on
+how you write Java code.  The syntax file knows two possible ways to highlight
+functions:
+
+If you write function declarations that are always indented by either
+a tab, 8 spaces or 2 spaces you may want to set >
+	:let java_highlight_functions="indent"
+However, if you follow the Java guidelines about how functions and classes are
+supposed to be named (with respect to upper and lowercase), use >
+	:let java_highlight_functions="style"
+If both options do not work for you, but you would still want function
+declarations to be highlighted create your own definitions by changing the
+definitions in java.vim or by creating your own java.vim which includes the
+original one and then adds the code to highlight functions.
+
+In Java 1.1 the functions System.out.println() and System.err.println() should
+only be used for debugging.  Therefore it is possible to highlight debugging
+statements differently.  To do this you must add the following definition in
+your startup file: >
+	:let java_highlight_debug=1
+The result will be that those statements are highlighted as 'Special'
+characters.  If you prefer to have them highlighted differently you must define
+new highlightings for the following groups.:
+    Debug, DebugSpecial, DebugString, DebugBoolean, DebugType
+which are used for the statement itself, special characters used in debug
+strings, strings, boolean constants and types (this, super) respectively.  I
+have opted to chose another background for those statements.
+
+In order to help you to write code that can be easily ported between
+Java and C++, all C++ keywords are marked as error in a Java program.
+However, if you use them regularly, you may want to define the following
+variable in your .vimrc file: >
+	:let java_allow_cpp_keywords=1
+
+Javadoc is a program that takes special comments out of Java program files and
+creates HTML pages.  The standard configuration will highlight this HTML code
+similarly to HTML files (see |html.vim|).  You can even add Javascript
+and CSS inside this code (see below).  There are four differences however:
+  1. The title (all characters up to the first '.' which is followed by
+     some white space or up to the first '@') is colored differently (to change
+     the color change the group CommentTitle).
+  2. The text is colored as 'Comment'.
+  3. HTML comments are colored as 'Special'
+  4. The special Javadoc tags (@see, @param, ...) are highlighted as specials
+     and the argument (for @see, @param, @exception) as Function.
+To turn this feature off add the following line to your startup file: >
+	:let java_ignore_javadoc=1
+
+If you use the special Javadoc comment highlighting described above you
+can also turn on special highlighting for Javascript, visual basic
+scripts and embedded CSS (stylesheets).  This makes only sense if you
+actually have Javadoc comments that include either Javascript or embedded
+CSS.  The options to use are >
+	:let java_javascript=1
+	:let java_css=1
+	:let java_vb=1
+
+In order to highlight nested parens with different colors define colors
+for javaParen, javaParen1 and javaParen2, for example with >
+	:hi link javaParen Comment
+or >
+	:hi javaParen ctermfg=blue guifg=#0000ff
+
+If you notice highlighting errors while scrolling backwards, which are fixed
+when redrawing with CTRL-L, try setting the "java_minlines" internal variable
+to a larger number: >
+	:let java_minlines = 50
+This will make the syntax synchronization start 50 lines before the first
+displayed line.  The default value is 10.  The disadvantage of using a larger
+number is that redrawing can become slow.
+
+
+LACE						*lace.vim* *ft-lace-syntax*
+
+Lace (Language for Assembly of Classes in Eiffel) is case insensitive, but the
+style guide lines are not.  If you prefer case insensitive highlighting, just
+define the vim variable 'lace_case_insensitive' in your startup file: >
+	:let lace_case_insensitive=1
+
+
+LEX						*lex.vim* *ft-lex-syntax*
+
+Lex uses brute-force synchronizing as the "^%%$" section delimiter
+gives no clue as to what section follows.  Consequently, the value for >
+	:syn sync minlines=300
+may be changed by the user if s/he is experiencing synchronization
+difficulties (such as may happen with large lex files).
+
+
+LISP						*lisp.vim* *ft-lisp-syntax*
+
+The lisp syntax highlighting provides two options: >
+
+	g:lisp_instring : if it exists, then "(...)" strings are highlighted
+			  as if the contents of the string were lisp.
+			  Useful for AutoLisp.
+	g:lisp_rainbow  : if it exists and is nonzero, then differing levels
+			  of parenthesization will receive different
+			  highlighting.
+<
+The g:lisp_rainbow option provides 10 levels of individual colorization for
+the parentheses and backquoted parentheses.  Because of the quantity of
+colorization levels, unlike non-rainbow highlighting, the rainbow mode
+specifies its highlighting using ctermfg and guifg, thereby bypassing the
+usual colorscheme control using standard highlighting groups.  The actual
+highlighting used depends on the dark/bright setting  (see |'bg'|).
+
+
+LITE						*lite.vim* *ft-lite-syntax*
+
+There are two options for the lite syntax highlighting.
+
+If you like SQL syntax highlighting inside Strings, use this: >
+
+	:let lite_sql_query = 1
+
+For syncing, minlines defaults to 100.	If you prefer another value, you can
+set "lite_minlines" to the value you desire.  Example: >
+
+	:let lite_minlines = 200
+
+
+LPC						*lpc.vim* *ft-lpc-syntax*
+
+LPC stands for a simple, memory-efficient language: Lars Pensj| C.  The
+file name of LPC is usually *.c.  Recognizing these files as LPC would bother
+users writing only C programs.	If you want to use LPC syntax in Vim, you
+should set a variable in your .vimrc file: >
+
+	:let lpc_syntax_for_c = 1
+
+If it doesn't work properly for some particular C or LPC files, use a
+modeline.  For a LPC file:
+
+	// vim:set ft=lpc:
+
+For a C file that is recognized as LPC:
+
+	// vim:set ft=c:
+
+If you don't want to set the variable, use the modeline in EVERY LPC file.
+
+There are several implementations for LPC, we intend to support most widely
+used ones.  Here the default LPC syntax is for MudOS series, for MudOS v22
+and before, you should turn off the sensible modifiers, and this will also
+asserts the new efuns after v22 to be invalid, don't set this variable when
+you are using the latest version of MudOS: >
+
+	:let lpc_pre_v22 = 1
+
+For LpMud 3.2 series of LPC: >
+
+	:let lpc_compat_32 = 1
+
+For LPC4 series of LPC: >
+
+	:let lpc_use_lpc4_syntax = 1
+
+For uLPC series of LPC:
+uLPC has been developed to Pike, so you should use Pike syntax
+instead, and the name of your source file should be *.pike
+
+
+LUA						*lua.vim* *ft-lua-syntax*
+
+This syntax file may be used for Lua 4.0, Lua 5.0 or Lua 5.1 (the latter is
+the default). You can select one of these versions using the global variables
+lua_version and lua_subversion. For example, to activate Lua
+4.0 syntax highlighting, use this command: >
+
+	:let lua_version = 4
+
+If you are using Lua 5.0, use these commands: >
+
+	:let lua_version = 5
+	:let lua_subversion = 0
+
+To restore highlighting for Lua 5.1: >
+
+	:let lua_version = 5
+	:let lua_subversion = 1
+
+
+MAIL						*mail.vim* *ft-mail.vim*
+
+Vim highlights all the standard elements of an email (headers, signatures,
+quoted text and URLs / email addresses).  In keeping with standard conventions,
+signatures begin in a line containing only "--" followed optionally by
+whitespaces and end with a newline.
+
+Vim treats lines beginning with ']', '}', '|', '>' or a word followed by '>'
+as quoted text.  However Vim highlights headers and signatures in quoted text
+only if the text is quoted with '>' (optionally followed by one space).
+
+By default mail.vim synchronises syntax to 100 lines before the first
+displayed line.  If you have a slow machine, and generally deal with emails
+with short headers, you can change this to a smaller value: >
+
+    :let mail_minlines = 30
+
+
+MAKE						*make.vim* *ft-make-syntax*
+
+In makefiles, commands are usually highlighted to make it easy for you to spot
+errors.  However, this may be too much coloring for you.  You can turn this
+feature off by using: >
+
+	:let make_no_commands = 1
+
+
+MAPLE						*maple.vim* *ft-maple-syntax*
+
+Maple V, by Waterloo Maple Inc, supports symbolic algebra.  The language
+supports many packages of functions which are selectively loaded by the user.
+The standard set of packages' functions as supplied in Maple V release 4 may be
+highlighted at the user's discretion.  Users may place in their .vimrc file: >
+
+	:let mvpkg_all= 1
+
+to get all package functions highlighted, or users may select any subset by
+choosing a variable/package from the table below and setting that variable to
+1, also in their .vimrc file (prior to sourcing
+$VIMRUNTIME/syntax/syntax.vim).
+
+	Table of Maple V Package Function Selectors >
+  mv_DEtools	 mv_genfunc	mv_networks	mv_process
+  mv_Galois	 mv_geometry	mv_numapprox	mv_simplex
+  mv_GaussInt	 mv_grobner	mv_numtheory	mv_stats
+  mv_LREtools	 mv_group	mv_orthopoly	mv_student
+  mv_combinat	 mv_inttrans	mv_padic	mv_sumtools
+  mv_combstruct mv_liesymm	mv_plots	mv_tensor
+  mv_difforms	 mv_linalg	mv_plottools	mv_totorder
+  mv_finance	 mv_logic	mv_powseries
+
+
+MATHEMATICA		*mma.vim* *ft-mma-syntax* *ft-mathematica-syntax*
+
+Empty *.m files will automatically be presumed to be Matlab files unless you
+have the following in your .vimrc: >
+
+	let filetype_m = "mma"
+
+
+MOO						*moo.vim* *ft-moo-syntax*
+
+If you use C-style comments inside expressions and find it mangles your
+highlighting, you may want to use extended (slow!) matches for C-style
+comments: >
+
+	:let moo_extended_cstyle_comments = 1
+
+To disable highlighting of pronoun substitution patterns inside strings: >
+
+	:let moo_no_pronoun_sub = 1
+
+To disable highlighting of the regular expression operator '%|', and matching
+'%(' and '%)' inside strings: >
+
+	:let moo_no_regexp = 1
+
+Unmatched double quotes can be recognized and highlighted as errors: >
+
+	:let moo_unmatched_quotes = 1
+
+To highlight builtin properties (.name, .location, .programmer etc.): >
+
+	:let moo_builtin_properties = 1
+
+Unknown builtin functions can be recognized and highlighted as errors.  If you
+use this option, add your own extensions to the mooKnownBuiltinFunction group.
+To enable this option: >
+
+	:let moo_unknown_builtin_functions = 1
+
+An example of adding sprintf() to the list of known builtin functions: >
+
+	:syn keyword mooKnownBuiltinFunction sprintf contained
+
+
+MSQL						*msql.vim* *ft-msql-syntax*
+
+There are two options for the msql syntax highlighting.
+
+If you like SQL syntax highlighting inside Strings, use this: >
+
+	:let msql_sql_query = 1
+
+For syncing, minlines defaults to 100.	If you prefer another value, you can
+set "msql_minlines" to the value you desire.  Example: >
+
+	:let msql_minlines = 200
+
+
+NCF						*ncf.vim* *ft-ncf-syntax*
+
+There is one option for NCF syntax highlighting.
+
+If you want to have unrecognized (by ncf.vim) statements highlighted as
+errors, use this: >
+
+	:let ncf_highlight_unknowns = 1
+
+If you don't want to highlight these errors, leave it unset.
+
+
+NROFF						*nroff.vim* *ft-nroff-syntax*
+
+The nroff syntax file works with AT&T n/troff out of the box.  You need to
+activate the GNU groff extra features included in the syntax file before you
+can use them.
+
+For example, Linux and BSD distributions use groff as their default text
+processing package.  In order to activate the extra syntax highlighting
+features for groff, add the following option to your start-up files: >
+
+  :let b:nroff_is_groff = 1
+
+Groff is different from the old AT&T n/troff that you may still find in
+Solaris.  Groff macro and request names can be longer than 2 characters and
+there are extensions to the language primitives.  For example, in AT&T troff
+you access the year as a 2-digit number with the request \(yr.  In groff you
+can use the same request, recognized for compatibility, or you can use groff's
+native syntax, \[yr].  Furthermore, you can use a 4-digit year directly:
+\[year].  Macro requests can be longer than 2 characters, for example, GNU mm
+accepts the requests ".VERBON" and ".VERBOFF" for creating verbatim
+environments.
+
+In order to obtain the best formatted output g/troff can give you, you should
+follow a few simple rules about spacing and punctuation.
+
+1. Do not leave empty spaces at the end of lines.
+
+2. Leave one space and one space only after an end-of-sentence period,
+   exclamation mark, etc.
+
+3. For reasons stated below, it is best to follow all period marks with a
+   carriage return.
+
+The reason behind these unusual tips is that g/n/troff have a line breaking
+algorithm that can be easily upset if you don't follow the rules given above.
+
+Unlike TeX, troff fills text line-by-line, not paragraph-by-paragraph and,
+furthermore, it does not have a concept of glue or stretch, all horizontal and
+vertical space input will be output as is.
+
+Therefore, you should be careful about not using more space between sentences
+than you intend to have in your final document.  For this reason, the common
+practice is to insert a carriage return immediately after all punctuation
+marks.  If you want to have "even" text in your final processed output, you
+need to maintaining regular spacing in the input text.  To mark both trailing
+spaces and two or more spaces after a punctuation as an error, use: >
+
+  :let nroff_space_errors = 1
+
+Another technique to detect extra spacing and other errors that will interfere
+with the correct typesetting of your file, is to define an eye-catching
+highlighting definition for the syntax groups "nroffDefinition" and
+"nroffDefSpecial" in your configuration files.  For example: >
+
+  hi def nroffDefinition term=italic cterm=italic gui=reverse
+  hi def nroffDefSpecial term=italic,bold cterm=italic,bold
+			 \ gui=reverse,bold
+
+If you want to navigate preprocessor entries in your source file as easily as
+with section markers, you can activate the following option in your .vimrc
+file: >
+
+	let b:preprocs_as_sections = 1
+
+As well, the syntax file adds an extra paragraph marker for the extended
+paragraph macro (.XP) in the ms package.
+
+Finally, there is a |groff.vim| syntax file that can be used for enabling
+groff syntax highlighting either on a file basis or globally by default.
+
+
+OCAML						*ocaml.vim* *ft-ocaml-syntax*
+
+The OCaml syntax file handles files having the following prefixes: .ml,
+.mli, .mll and .mly.  By setting the following variable >
+
+	:let ocaml_revised = 1
+
+you can switch from standard OCaml-syntax to revised syntax as supported
+by the camlp4 preprocessor.  Setting the variable >
+
+	:let ocaml_noend_error = 1
+
+prevents highlighting of "end" as error, which is useful when sources
+contain very long structures that Vim does not synchronize anymore.
+
+
+PAPP						*papp.vim* *ft-papp-syntax*
+
+The PApp syntax file handles .papp files and, to a lesser extend, .pxml
+and .pxsl files which are all a mixture of perl/xml/html/other using xml
+as the top-level file format.  By default everything inside phtml or pxml
+sections is treated as a string with embedded preprocessor commands.  If
+you set the variable: >
+
+	:let papp_include_html=1
+
+in your startup file it will try to syntax-hilight html code inside phtml
+sections, but this is relatively slow and much too colourful to be able to
+edit sensibly. ;)
+
+The newest version of the papp.vim syntax file can usually be found at
+http://papp.plan9.de.
+
+
+PASCAL						*pascal.vim* *ft-pascal-syntax*
+
+Files matching "*.p" could be Progress or Pascal.  If the automatic detection
+doesn't work for you, or you don't edit Progress at all, use this in your
+startup vimrc: >
+
+   :let filetype_p = "pascal"
+
+The Pascal syntax file has been extended to take into account some extensions
+provided by Turbo Pascal, Free Pascal Compiler and GNU Pascal Compiler.
+Delphi keywords are also supported.  By default, Turbo Pascal 7.0 features are
+enabled.  If you prefer to stick with the standard Pascal keywords, add the
+following line to your startup file: >
+
+   :let pascal_traditional=1
+
+To switch on Delphi specific constructions (such as one-line comments,
+keywords, etc): >
+
+   :let pascal_delphi=1
+
+
+The option pascal_symbol_operator controls whether symbol operators such as +,
+*, .., etc. are displayed using the Operator color or not.  To colorize symbol
+operators, add the following line to your startup file: >
+
+   :let pascal_symbol_operator=1
+
+Some functions are highlighted by default.  To switch it off: >
+
+   :let pascal_no_functions=1
+
+Furthermore, there are specific variable for some compiler.  Besides
+pascal_delphi, there are pascal_gpc and pascal_fpc.  Default extensions try to
+match Turbo Pascal. >
+
+   :let pascal_gpc=1
+
+or >
+
+   :let pascal_fpc=1
+
+To ensure that strings are defined on a single line, you can define the
+pascal_one_line_string variable. >
+
+   :let pascal_one_line_string=1
+
+If you dislike <Tab> chars, you can set the pascal_no_tabs variable.  Tabs
+will be highlighted as Error. >
+
+   :let pascal_no_tabs=1
+
+
+
+PERL						*perl.vim* *ft-perl-syntax*
+
+There are a number of possible options to the perl syntax highlighting.
+
+If you use POD files or POD segments, you might: >
+
+	:let perl_include_pod = 1
+
+The reduce the complexity of parsing (and increase performance) you can switch
+off two elements in the parsing of variable names and contents. >
+
+To handle package references in variable and function names not differently
+from the rest of the name (like 'PkgName::' in '$PkgName::VarName'): >
+
+	:let perl_no_scope_in_variables = 1
+
+(In Vim 6.x it was the other way around: "perl_want_scope_in_variables"
+enabled it.)
+
+If you do not want complex things like '@{${"foo"}}' to be parsed: >
+
+	:let perl_no_extended_vars = 1
+
+(In Vim 6.x it was the other way around: "perl_extended_vars" enabled it.)
+
+The coloring strings can be changed.  By default strings and qq friends will be
+highlighted like the first line.  If you set the variable
+perl_string_as_statement, it will be highlighted as in the second line.
+
+   "hello world!"; qq|hello world|;
+   ^^^^^^^^^^^^^^NN^^^^^^^^^^^^^^^N	  (unlet perl_string_as_statement)
+   S^^^^^^^^^^^^SNNSSS^^^^^^^^^^^SN	  (let perl_string_as_statement)
+
+(^ = perlString, S = perlStatement, N = None at all)
+
+The syncing has 3 options.  The first two switch off some triggering of
+synchronization and should only be needed in case it fails to work properly.
+If while scrolling all of a sudden the whole screen changes color completely
+then you should try and switch off one of those.  Let me know if you can figure
+out the line that causes the mistake.
+
+One triggers on "^\s*sub\s*" and the other on "^[$@%]" more or less. >
+
+	:let perl_no_sync_on_sub
+	:let perl_no_sync_on_global_var
+
+Below you can set the maximum distance VIM should look for starting points for
+its attempts in syntax highlighting. >
+
+	:let perl_sync_dist = 100
+
+If you want to use folding with perl, set perl_fold: >
+
+	:let perl_fold = 1
+
+If you want to fold blocks in if statements, etc. as well set the following: >
+
+	:let perl_fold_blocks = 1
+
+To avoid folding packages or subs when perl_fold is let, let the appropriate
+variable(s): >
+
+	:unlet perl_nofold_packages
+	:unlet perl_nofold_subs
+
+
+
+PHP3 and PHP4		*php.vim* *php3.vim* *ft-php-syntax* *ft-php3-syntax*
+
+[note: previously this was called "php3", but since it now also supports php4
+it has been renamed to "php"]
+
+There are the following options for the php syntax highlighting.
+
+If you like SQL syntax highlighting inside Strings: >
+
+  let php_sql_query = 1
+
+For highlighting the Baselib methods: >
+
+  let php_baselib = 1
+
+Enable HTML syntax highlighting inside strings: >
+
+  let php_htmlInStrings = 1
+
+Using the old colorstyle: >
+
+  let php_oldStyle = 1
+
+Enable highlighting ASP-style short tags: >
+
+  let php_asp_tags = 1
+
+Disable short tags: >
+
+  let php_noShortTags = 1
+
+For highlighting parent error ] or ): >
+
+  let php_parent_error_close = 1
+
+For skipping an php end tag, if there exists an open ( or [ without a closing
+one: >
+
+  let php_parent_error_open = 1
+
+Enable folding for classes and functions: >
+
+  let php_folding = 1
+
+Selecting syncing method: >
+
+  let php_sync_method = x
+
+x = -1 to sync by search (default),
+x > 0 to sync at least x lines backwards,
+x = 0 to sync from start.
+
+
+PLAINTEX				*plaintex.vim* *ft-plaintex-syntax*
+
+TeX is a typesetting language, and plaintex is the file type for the "plain"
+variant of TeX.  If you never want your *.tex files recognized as plain TeX,
+see |ft-tex-plugin|.
+
+This syntax file has the option >
+
+	let g:plaintex_delimiters = 1
+
+if you want to highlight brackets "[]" and braces "{}".
+
+
+PPWIZARD					*ppwiz.vim* *ft-ppwiz-syntax*
+
+PPWizard is a preprocessor for HTML and OS/2 INF files
+
+This syntax file has the options:
+
+- ppwiz_highlight_defs : determines highlighting mode for PPWizard's
+  definitions.  Possible values are
+
+  ppwiz_highlight_defs = 1 : PPWizard #define statements retain the
+    colors of their contents (e.g. PPWizard macros and variables)
+
+  ppwiz_highlight_defs = 2 : preprocessor #define and #evaluate
+    statements are shown in a single color with the exception of line
+    continuation symbols
+
+  The default setting for ppwiz_highlight_defs is 1.
+
+- ppwiz_with_html : If the value is 1 (the default), highlight literal
+  HTML code; if 0, treat HTML code like ordinary text.
+
+
+PHTML						*phtml.vim* *ft-phtml-syntax*
+
+There are two options for the phtml syntax highlighting.
+
+If you like SQL syntax highlighting inside Strings, use this: >
+
+	:let phtml_sql_query = 1
+
+For syncing, minlines defaults to 100.	If you prefer another value, you can
+set "phtml_minlines" to the value you desire.  Example: >
+
+	:let phtml_minlines = 200
+
+
+POSTSCRIPT				*postscr.vim* *ft-postscr-syntax*
+
+There are several options when it comes to highlighting PostScript.
+
+First which version of the PostScript language to highlight.  There are
+currently three defined language versions, or levels.  Level 1 is the original
+and base version, and includes all extensions prior to the release of level 2.
+Level 2 is the most common version around, and includes its own set of
+extensions prior to the release of level 3.  Level 3 is currently the highest
+level supported.  You select which level of the PostScript language you want
+highlighted by defining the postscr_level variable as follows: >
+
+	:let postscr_level=2
+
+If this variable is not defined it defaults to 2 (level 2) since this is
+the most prevalent version currently.
+
+Note, not all PS interpreters will support all language features for a
+particular language level.  In particular the %!PS-Adobe-3.0 at the start of
+PS files does NOT mean the PostScript present is level 3 PostScript!
+
+If you are working with Display PostScript, you can include highlighting of
+Display PS language features by defining the postscr_display variable as
+follows: >
+
+	:let postscr_display=1
+
+If you are working with Ghostscript, you can include highlighting of
+Ghostscript specific language features by defining the variable
+postscr_ghostscript as follows: >
+
+	:let postscr_ghostscript=1
+
+PostScript is a large language, with many predefined elements.	While it
+useful to have all these elements highlighted, on slower machines this can
+cause Vim to slow down.  In an attempt to be machine friendly font names and
+character encodings are not highlighted by default.  Unless you are working
+explicitly with either of these this should be ok.  If you want them to be
+highlighted you should set one or both of the following variables: >
+
+	:let postscr_fonts=1
+	:let postscr_encodings=1
+
+There is a stylistic option to the highlighting of and, or, and not.  In
+PostScript the function of these operators depends on the types of their
+operands - if the operands are booleans then they are the logical operators,
+if they are integers then they are binary operators.  As binary and logical
+operators can be highlighted differently they have to be highlighted one way
+or the other.  By default they are treated as logical operators.  They can be
+highlighted as binary operators by defining the variable
+postscr_andornot_binary as follows: >
+
+	:let postscr_andornot_binary=1
+<
+
+			*ptcap.vim* *ft-printcap-syntax*
+PRINTCAP + TERMCAP	*ft-ptcap-syntax* *ft-termcap-syntax*
+
+This syntax file applies to the printcap and termcap databases.
+
+In order for Vim to recognize printcap/termcap files that do not match
+the patterns *printcap*, or *termcap*, you must put additional patterns
+appropriate to your system in your |myfiletypefile| file.  For these
+patterns, you must set the variable "b:ptcap_type" to either "print" or
+"term", and then the 'filetype' option to ptcap.
+
+For example, to make Vim identify all files in /etc/termcaps/ as termcap
+files, add the following: >
+
+   :au BufNewFile,BufRead /etc/termcaps/* let b:ptcap_type = "term" |
+				       \ set filetype=ptcap
+
+If you notice highlighting errors while scrolling backwards, which
+are fixed when redrawing with CTRL-L, try setting the "ptcap_minlines"
+internal variable to a larger number: >
+
+   :let ptcap_minlines = 50
+
+(The default is 20 lines.)
+
+
+PROGRESS				*progress.vim* *ft-progress-syntax*
+
+Files matching "*.w" could be Progress or cweb.  If the automatic detection
+doesn't work for you, or you don't edit cweb at all, use this in your
+startup vimrc: >
+   :let filetype_w = "progress"
+The same happens for "*.i", which could be assembly, and "*.p", which could be
+Pascal.  Use this if you don't use assembly and Pascal: >
+   :let filetype_i = "progress"
+   :let filetype_p = "progress"
+
+
+PYTHON						*python.vim* *ft-python-syntax*
+
+There are four options to control Python syntax highlighting.
+
+For highlighted numbers: >
+	:let python_highlight_numbers = 1
+
+For highlighted builtin functions: >
+	:let python_highlight_builtins = 1
+
+For highlighted standard exceptions: >
+	:let python_highlight_exceptions = 1
+
+For highlighted trailing whitespace and mix of spaces and tabs:
+	:let python_highlight_space_errors = 1
+
+If you want all possible Python highlighting (the same as setting the
+preceding three options): >
+	:let python_highlight_all = 1
+
+
+QUAKE						*quake.vim* *ft-quake-syntax*
+
+The Quake syntax definition should work for most any FPS (First Person
+Shooter) based on one of the Quake engines.  However, the command names vary
+a bit between the three games (Quake, Quake 2, and Quake 3 Arena) so the
+syntax definition checks for the existence of three global variables to allow
+users to specify what commands are legal in their files.  The three variables
+can be set for the following effects:
+
+set to highlight commands only available in Quake: >
+	:let quake_is_quake1 = 1
+
+set to highlight commands only available in Quake 2: >
+	:let quake_is_quake2 = 1
+
+set to highlight commands only available in Quake 3 Arena: >
+	:let quake_is_quake3 = 1
+
+Any combination of these three variables is legal, but might highlight more
+commands than are actually available to you by the game.
+
+
+READLINE				*readline.vim* *ft-readline-syntax*
+
+The readline library is primarily used by the BASH shell, which adds quite a
+few commands and options to the ones already available.  To highlight these
+items as well you can add the following to your |vimrc| or just type it in the
+command line before loading a file with the readline syntax: >
+	let readline_has_bash = 1
+
+This will add highlighting for the commands that BASH (version 2.05a and
+later, and part earlier) adds.
+
+
+REXX						*rexx.vim* *ft-rexx-syntax*
+
+If you notice highlighting errors while scrolling backwards, which are fixed
+when redrawing with CTRL-L, try setting the "rexx_minlines" internal variable
+to a larger number: >
+	:let rexx_minlines = 50
+This will make the syntax synchronization start 50 lines before the first
+displayed line.  The default value is 10.  The disadvantage of using a larger
+number is that redrawing can become slow.
+
+
+RUBY						*ruby.vim* *ft-ruby-syntax*
+
+There are a number of options to the Ruby syntax highlighting.
+
+By default, the "end" keyword is colorized according to the opening statement
+of the block it closes.  While useful, this feature can be expensive; if you
+experience slow redrawing (or you are on a terminal with poor color support)
+you may want to turn it off by defining the "ruby_no_expensive" variable: >
+
+	:let ruby_no_expensive = 1
+<
+In this case the same color will be used for all control keywords.
+
+If you do want this feature enabled, but notice highlighting errors while
+scrolling backwards, which are fixed when redrawing with CTRL-L, try setting
+the "ruby_minlines" variable to a value larger than 50: >
+
+	:let ruby_minlines = 100
+<
+Ideally, this value should be a number of lines large enough to embrace your
+largest class or module.
+
+Highlighting of special identifiers can be disabled by removing the
+rubyIdentifier highlighting: >
+
+	:hi link rubyIdentifier NONE
+<
+This will prevent highlighting of special identifiers like "ConstantName",
+"$global_var", "@@class_var", "@instance_var", "| block_param |", and
+":symbol".
+
+Significant methods of Kernel, Module and Object are highlighted by default.
+This can be disabled by defining "ruby_no_special_methods": >
+
+	:let ruby_no_special_methods = 1
+<
+This will prevent highlighting of important methods such as "require", "attr",
+"private", "raise" and "proc".
+
+Ruby operators can be highlighted. This is enabled by defining
+"ruby_operators": >
+
+	:let ruby_operators = 1
+<
+Whitespace errors can be highlighted by defining "ruby_space_errors": >
+
+	:let ruby_space_errors = 1
+<
+This will highlight trailing whitespace and tabs preceded by a space character
+as errors.  This can be refined by defining "ruby_no_trail_space_error" and
+"ruby_no_tab_space_error" which will ignore trailing whitespace and tabs after
+spaces respectively.
+
+Folding can be enabled by defining "ruby_fold": >
+
+	:let ruby_fold = 1
+<
+This will set the 'foldmethod' option to "syntax" and allow folding of
+classes, modules, methods, code blocks, heredocs and comments.
+
+Folding of multiline comments can be disabled by defining
+"ruby_no_comment_fold": >
+
+	:let ruby_no_comment_fold = 1
+<
+
+SCHEME						*scheme.vim* *ft-scheme-syntax*
+
+By default only R5RS keywords are highlighted and properly indented.
+
+MzScheme-specific stuff will be used if b:is_mzscheme or g:is_mzscheme
+variables are defined.
+
+Also scheme.vim supports keywords of the Chicken Scheme->C compiler.  Define
+b:is_chicken or g:is_chicken, if you need them.
+
+
+SDL						*sdl.vim* *ft-sdl-syntax*
+
+The SDL highlighting probably misses a few keywords, but SDL has so many
+of them it's almost impossibly to cope.
+
+The new standard, SDL-2000, specifies that all identifiers are
+case-sensitive (which was not so before), and that all keywords can be
+used either completely lowercase or completely uppercase.  To have the
+highlighting reflect this, you can set the following variable: >
+	:let sdl_2000=1
+
+This also sets many new keywords.  If you want to disable the old
+keywords, which is probably a good idea, use: >
+	:let SDL_no_96=1
+
+
+The indentation is probably also incomplete, but right now I am very
+satisfied with it for my own projects.
+
+
+SED						*sed.vim* *ft-sed-syntax*
+
+To make tabs stand out from regular blanks (accomplished by using Todo
+highlighting on the tabs), define "highlight_sedtabs" by putting >
+
+	:let highlight_sedtabs = 1
+
+in the vimrc file.  (This special highlighting only applies for tabs
+inside search patterns, replacement texts, addresses or text included
+by an Append/Change/Insert command.)  If you enable this option, it is
+also a good idea to set the tab width to one character; by doing that,
+you can easily count the number of tabs in a string.
+
+Bugs:
+
+  The transform command (y) is treated exactly like the substitute
+  command.  This means that, as far as this syntax file is concerned,
+  transform accepts the same flags as substitute, which is wrong.
+  (Transform accepts no flags.)  I tolerate this bug because the
+  involved commands need very complex treatment (95 patterns, one for
+  each plausible pattern delimiter).
+
+
+SGML						*sgml.vim* *ft-sgml-syntax*
+
+The coloring scheme for tags in the SGML file works as follows.
+
+The <> of opening tags are colored differently than the </> of a closing tag.
+This is on purpose! For opening tags the 'Function' color is used, while for
+closing tags the 'Type' color is used (See syntax.vim to check how those are
+defined for you)
+
+Known tag names are colored the same way as statements in C.  Unknown tag
+names are not colored which makes it easy to spot errors.
+
+Note that the same is true for argument (or attribute) names.  Known attribute
+names are colored differently than unknown ones.
+
+Some SGML tags are used to change the rendering of text.  The following tags
+are recognized by the sgml.vim syntax coloring file and change the way normal
+text is shown: <varname> <emphasis> <command> <function> <literal>
+<replaceable> <ulink> and <link>.
+
+If you want to change how such text is rendered, you must redefine the
+following syntax groups:
+
+    - sgmlBold
+    - sgmlBoldItalic
+    - sgmlUnderline
+    - sgmlItalic
+    - sgmlLink for links
+
+To make this redefinition work you must redefine them all and define the
+following variable in your vimrc (this is due to the order in which the files
+are read during initialization) >
+   let sgml_my_rendering=1
+
+You can also disable this rendering by adding the following line to your
+vimrc file: >
+   let sgml_no_rendering=1
+
+(Adapted from the html.vim help text by Claudio Fleiner <claudio@fleiner.com>)
+
+
+SH		*sh.vim* *ft-sh-syntax* *ft-bash-syntax* *ft-ksh-syntax*
+
+This covers the "normal" Unix (Borne) sh, bash and the Korn shell.
+
+Vim attempts to determine which shell type is in use by specifying that
+various filenames are of specific types: >
+
+    ksh : .kshrc* *.ksh
+    bash: .bashrc* bashrc bash.bashrc .bash_profile* *.bash
+<
+If none of these cases pertain, then the first line of the file is examined
+(ex. /bin/sh  /bin/ksh	/bin/bash).  If the first line specifies a shelltype,
+then that shelltype is used.  However some files (ex. .profile) are known to
+be shell files but the type is not apparent.  Furthermore, on many systems
+sh is symbolically linked to "bash" (Linux, Windows+cygwin) or "ksh" (Posix).
+
+One may specify a global default by instantiating one of the following three
+variables in your <.vimrc>:
+
+    ksh: >
+	let g:is_kornshell = 1
+<   posix: (using this is the same as setting is_kornshell to 1) >
+	let g:is_posix     = 1
+<   bash: >
+	let g:is_bash	   = 1
+<   sh: (default) Borne shell >
+	let g:is_sh	   = 1
+
+If there's no "#! ..." line, and the user hasn't availed himself/herself of a
+default sh.vim syntax setting as just shown, then syntax/sh.vim will assume
+the Borne shell syntax.  No need to quote RFCs or market penetration
+statistics in error reports, please -- just select the default version of
+the sh your system uses in your <.vimrc>.
+
+If, in your <.vimrc>, you set >
+	let g:sh_fold_enabled= 1
+>
+then various syntax items (HereDocuments and function bodies) become
+syntax-foldable (see |:syn-fold|).
+
+If you notice highlighting errors while scrolling backwards, which are fixed
+when redrawing with CTRL-L, try setting the "sh_minlines" internal variable
+to a larger number.  Example: >
+
+	let sh_minlines = 500
+
+This will make syntax synchronization start 500 lines before the first
+displayed line.  The default value is 200.  The disadvantage of using a larger
+number is that redrawing can become slow.
+
+If you don't have much to synchronize on, displaying can be very slow.	To
+reduce this, the "sh_maxlines" internal variable can be set.  Example: >
+
+	let sh_maxlines = 100
+<
+The default is to use the twice sh_minlines.  Set it to a smaller number to
+speed up displaying.  The disadvantage is that highlight errors may appear.
+
+
+SPEEDUP (AspenTech plant simulator)		*spup.vim* *ft-spup-syntax*
+
+The Speedup syntax file has some options:
+
+- strict_subsections : If this variable is defined, only keywords for
+  sections and subsections will be highlighted as statements but not
+  other keywords (like WITHIN in the OPERATION section).
+
+- highlight_types : Definition of this variable causes stream types
+  like temperature or pressure to be highlighted as Type, not as a
+  plain Identifier.  Included are the types that are usually found in
+  the DECLARE section; if you defined own types, you have to include
+  them in the syntax file.
+
+- oneline_comments : this value ranges from 1 to 3 and determines the
+  highlighting of # style comments.
+
+  oneline_comments = 1 : allow normal Speedup code after an even
+  number of #s.
+
+  oneline_comments = 2 : show code starting with the second # as
+  error.  This is the default setting.
+
+  oneline_comments = 3 : show the whole line as error if it contains
+  more than one #.
+
+Since especially OPERATION sections tend to become very large due to
+PRESETting variables, syncing may be critical.  If your computer is
+fast enough, you can increase minlines and/or maxlines near the end of
+the syntax file.
+
+
+SQL						*sql.vim* *ft-sql-syntax*
+				*sqlinformix.vim* *ft-sqlinformix-syntax*
+				*sqlanywhere.vim* *ft-sqlanywhere-syntax*
+
+While there is an ANSI standard for SQL, most database engines add their own
+custom extensions.  Vim currently supports the Oracle and Informix dialects of
+SQL.  Vim assumes "*.sql" files are Oracle SQL by default.
+
+Vim currently has SQL support for a variety of different vendors via syntax
+scripts.  You can change Vim's default from Oracle to any of the current SQL
+supported types.  You can also easily alter the SQL dialect being used on a
+buffer by buffer basis.
+
+For more detailed instructions see |sql.txt|.
+
+
+TCSH						*tcsh.vim* *ft-tcsh-syntax*
+
+This covers the shell named "tcsh".  It is a superset of csh.  See |csh.vim|
+for how the filetype is detected.
+
+Tcsh does not allow \" in strings unless the "backslash_quote" shell variable
+is set.  If you want VIM to assume that no backslash quote constructs exist add
+this line to your .vimrc: >
+
+	:let tcsh_backslash_quote = 0
+
+If you notice highlighting errors while scrolling backwards, which are fixed
+when redrawing with CTRL-L, try setting the "tcsh_minlines" internal variable
+to a larger number: >
+
+	:let tcsh_minlines = 100
+
+This will make the syntax synchronization start 100 lines before the first
+displayed line.  The default value is 15.  The disadvantage of using a larger
+number is that redrawing can become slow.
+
+
+TEX						*tex.vim* *ft-tex-syntax*
+
+*tex-folding*
+Want Syntax Folding? ~
+
+As of version 28 of <syntax/tex.vim>, syntax-based folding of parts, chapters,
+sections, subsections, etc are supported.  Put >
+	let g:tex_fold_enabled=1
+in your <.vimrc>, and :set fdm=syntax.  I suggest doing the latter via a
+modeline at the end of your LaTeX file: >
+	% vim: fdm=syntax
+<
+*tex-runon*
+Run-on Comments/Math? ~
+
+The <syntax/tex.vim> highlighting supports TeX, LaTeX, and some AmsTeX.  The
+highlighting supports three primary zones/regions: normal, texZone, and
+texMathZone.  Although considerable effort has been made to have these zones
+terminate properly, zones delineated by $..$ and $$..$$ cannot be synchronized
+as there's no difference between start and end patterns.  Consequently, a
+special "TeX comment" has been provided >
+	%stopzone
+which will forcibly terminate the highlighting of either a texZone or a
+texMathZone.
+
+*tex-slow*
+Slow Syntax Highlighting? ~
+
+If you have a slow computer, you may wish to reduce the values for >
+	:syn sync maxlines=200
+	:syn sync minlines=50
+(especially the latter).  If your computer is fast, you may wish to
+increase them.	This primarily affects synchronizing (i.e. just what group,
+if any, is the text at the top of the screen supposed to be in?).
+
+*tex-morecommands* *tex-package*
+Wish To Highlight More Commmands? ~
+
+LaTeX is a programmable language, and so there are thousands of packages full
+of specialized LaTeX commands, syntax, and fonts.  If you're using such a
+package you'll often wish that the distributed syntax/tex.vim would support
+it.  However, clearly this is impractical.  So please consider using the
+techniques in |mysyntaxfile-add| to extend or modify the highlighting provided
+by syntax/tex.vim.
+
+*tex-error*
+Excessive Error Highlighting? ~
+
+The <tex.vim> supports lexical error checking of various sorts.  Thus,
+although the error checking is ofttimes very useful, it can indicate
+errors where none actually are.  If this proves to be a problem for you,
+you may put in your <.vimrc> the following statement: >
+	let tex_no_error=1
+and all error checking by <syntax/tex.vim> will be suppressed.
+
+*tex-math*
+Need a new Math Group? ~
+
+If you want to include a new math group in your LaTeX, the following
+code shows you an example as to how you might do so: >
+	call TexNewMathZone(sfx,mathzone,starform)
+You'll want to provide the new math group with a unique suffix
+(currently, A-L and V-Z are taken by <syntax/tex.vim> itself).
+As an example, consider how eqnarray is set up by <syntax/tex.vim>: >
+	call TexNewMathZone("D","eqnarray",1)
+You'll need to change "mathzone" to the name of your new math group,
+and then to the call to it in .vim/after/syntax/tex.vim.
+The "starform" variable, if true, implies that your new math group
+has a starred form (ie. eqnarray*).
+
+*tex-style*
+Starting a New Style? ~
+
+One may use "\makeatletter" in *.tex files, thereby making the use of "@" in
+commands available.  However, since the *.tex file doesn't have one of the
+following suffices: sty cls clo dtx ltx, the syntax highlighting will flag
+such use of @ as an error.  To solve this: >
+
+	:let b:tex_stylish = 1
+	:set ft=tex
+
+Putting "let g:tex_stylish=1" into your <.vimrc> will make <syntax/tex.vim>
+always accept such use of @.
+
+
+TF						*tf.vim* *ft-tf-syntax*
+
+There is one option for the tf syntax highlighting.
+
+For syncing, minlines defaults to 100.	If you prefer another value, you can
+set "tf_minlines" to the value you desire.  Example: >
+
+	:let tf_minlines = your choice
+
+
+VIM						*vim.vim* *ft-vim-syntax*
+
+There is a tradeoff between more accurate syntax highlighting versus
+screen updating speed.  To improve accuracy, you may wish to increase
+the g:vim_minlines variable.  The g:vim_maxlines variable may be used
+to improve screen updating rates (see |:syn-sync| for more on this).
+
+	g:vim_minlines : used to set synchronization minlines
+	g:vim_maxlines : used to set synchronization maxlines
+
+The g:vimembedscript option allows for somewhat faster loading of syntax
+highlighting for vim scripts at the expense of supporting syntax highlighting
+for external scripting languages (currently perl, python, ruby, and tcl).
+
+	g:vimembedscript == 1 (default)  <vim.vim> will allow highlighting
+	g:vimembedscript doesn't exist	 of supported embedded scripting
+					 languages: perl, python, ruby and
+					 tcl.
+
+	g:vimembedscript == 0		 Syntax highlighting for embedded
+					 scripting languages will not be
+					 loaded.
+
+Not all error highlighting that syntax/vim.vim does may be correct; VimL is a
+difficult language to highlight correctly.  A way to suppress error
+highlighting is to put: >
+
+	let g:vimsyntax_noerror = 1
+
+in your |vimrc|.
+
+
+XF86CONFIG				*xf86conf.vim* *ft-xf86conf-syntax*
+
+The syntax of XF86Config file differs in XFree86 v3.x and v4.x.  Both
+variants are supported.  Automatic detection is used, but is far from perfect.
+You may need to specify the version manually.  Set the variable
+xf86conf_xfree86_version to 3 or 4 according to your XFree86 version in
+your .vimrc.  Example: >
+	:let xf86conf_xfree86_version=3
+When using a mix of versions, set the b:xf86conf_xfree86_version variable.
+
+Note that spaces and underscores in option names are not supported.  Use
+"SyncOnGreen" instead of "__s yn con gr_e_e_n" if you want the option name
+highlighted.
+
+
+XML						*xml.vim* *ft-xml-syntax*
+
+Xml namespaces are highlighted by default.  This can be inhibited by
+setting a global variable: >
+
+	:let g:xml_namespace_transparent=1
+<
+							*xml-folding*
+The xml syntax file provides syntax |folding| (see |:syn-fold|) between
+start and end tags.  This can be turned on by >
+
+	:let g:xml_syntax_folding = 1
+	:set foldmethod=syntax
+
+Note: syntax folding might slow down syntax highlighting significantly,
+especially for large files.
+
+
+X Pixmaps (XPM)					*xpm.vim* *ft-xpm-syntax*
+
+xpm.vim creates its syntax items dynamically based upon the contents of the
+XPM file.  Thus if you make changes e.g. in the color specification strings,
+you have to source it again e.g. with ":set syn=xpm".
+
+To copy a pixel with one of the colors, yank a "pixel" with "yl" and insert it
+somewhere else with "P".
+
+Do you want to draw with the mouse?  Try the following: >
+   :function! GetPixel()
+   :   let c = getline(".")[col(".") - 1]
+   :   echo c
+   :   exe "noremap <LeftMouse> <LeftMouse>r".c
+   :   exe "noremap <LeftDrag>	<LeftMouse>r".c
+   :endfunction
+   :noremap <RightMouse> <LeftMouse>:call GetPixel()<CR>
+   :set guicursor=n:hor20	   " to see the color beneath the cursor
+This turns the right button into a pipette and the left button into a pen.
+It will work with XPM files that have one character per pixel only and you
+must not click outside of the pixel strings, but feel free to improve it.
+
+It will look much better with a font in a quadratic cell size, e.g. for X: >
+	:set guifont=-*-clean-medium-r-*-*-8-*-*-*-*-80-*
+
+==============================================================================
+5. Defining a syntax					*:syn-define* *E410*
+
+Vim understands three types of syntax items:
+
+1. Keyword
+   It can only contain keyword characters, according to the 'iskeyword'
+   option.  It cannot contain other syntax items.  It will only match with a
+   complete word (there are no keyword characters before or after the match).
+   The keyword "if" would match in "if(a=b)", but not in "ifdef x", because
+   "(" is not a keyword character and "d" is.
+
+2. Match
+   This is a match with a single regexp pattern.
+
+3. Region
+   This starts at a match of the "start" regexp pattern and ends with a match
+   with the "end" regexp pattern.  Any other text can appear in between.  A
+   "skip" regexp pattern can be used to avoid matching the "end" pattern.
+
+Several syntax ITEMs can be put into one syntax GROUP.	For a syntax group
+you can give highlighting attributes.  For example, you could have an item
+to define a "/* .. */" comment and another one that defines a "// .." comment,
+and put them both in the "Comment" group.  You can then specify that a
+"Comment" will be in bold font and have a blue color.  You are free to make
+one highlight group for one syntax item, or put all items into one group.
+This depends on how you want to specify your highlighting attributes.  Putting
+each item in its own group results in having to specify the highlighting
+for a lot of groups.
+
+Note that a syntax group and a highlight group are similar.  For a highlight
+group you will have given highlight attributes.  These attributes will be used
+for the syntax group with the same name.
+
+In case more than one item matches at the same position, the one that was
+defined LAST wins.  Thus you can override previously defined syntax items by
+using an item that matches the same text.  But a keyword always goes before a
+match or region.  And a keyword with matching case always goes before a
+keyword with ignoring case.
+
+
+PRIORITY						*:syn-priority*
+
+When several syntax items may match, these rules are used:
+
+1. When multiple Match or Region items start in the same position, the item
+   defined last has priority.
+2. A Keyword has priority over Match and Region items.
+3. An item that starts in an earlier position has priority over items that
+   start in later positions.
+
+
+DEFINING CASE						*:syn-case* *E390*
+
+:sy[ntax] case [match | ignore]
+	This defines if the following ":syntax" commands will work with
+	matching case, when using "match", or with ignoring case, when using
+	"ignore".  Note that any items before this are not affected, and all
+	items until the next ":syntax case" command are affected.
+
+
+SPELL CHECKING						*:syn-spell*
+
+:sy[ntax] spell [toplevel | notoplevel | default]
+	This defines where spell checking is to be done for text that is not
+	in a syntax item:
+
+	toplevel:	Text is spell checked.
+	notoplevel:	Text is not spell checked.
+	default:	When there is a @Spell cluster no spell checking.
+
+	For text in syntax items use the @Spell and @NoSpell clusters
+	|spell-syntax|.  When there is no @Spell and no @NoSpell cluster then
+	spell checking is done for "default" and "toplevel".
+
+	To activate spell checking the 'spell' option must be set.
+
+
+DEFINING KEYWORDS					*:syn-keyword*
+
+:sy[ntax] keyword {group-name} [{options}] {keyword} .. [{options}]
+
+	This defines a number of keywords.
+
+	{group-name}	Is a syntax group name such as "Comment".
+	[{options}]	See |:syn-arguments| below.
+	{keyword} ..	Is a list of keywords which are part of this group.
+
+	Example: >
+  :syntax keyword   Type   int long char
+<
+	The {options} can be given anywhere in the line.  They will apply to
+	all keywords given, also for options that come after a keyword.
+	These examples do exactly the same: >
+  :syntax keyword   Type   contained int long char
+  :syntax keyword   Type   int long contained char
+  :syntax keyword   Type   int long char contained
+<								*E789*
+	When you have a keyword with an optional tail, like Ex commands in
+	Vim, you can put the optional characters inside [], to define all the
+	variations at once: >
+  :syntax keyword   vimCommand	 ab[breviate] n[ext]
+<
+	Don't forget that a keyword can only be recognized if all the
+	characters are included in the 'iskeyword' option.  If one character
+	isn't, the keyword will never be recognized.
+	Multi-byte characters can also be used.  These do not have to be in
+	'iskeyword'.
+
+	A keyword always has higher priority than a match or region, the
+	keyword is used if more than one item matches.	Keywords do not nest
+	and a keyword can't contain anything else.
+
+	Note that when you have a keyword that is the same as an option (even
+	one that isn't allowed here), you can not use it.  Use a match
+	instead.
+
+	The maximum length of a keyword is 80 characters.
+
+	The same keyword can be defined multiple times, when its containment
+	differs.  For example, you can define the keyword once not contained
+	and use one highlight group, and once contained, and use a different
+	highlight group.  Example: >
+  :syn keyword vimCommand tag
+  :syn keyword vimSetting contained tag
+<	When finding "tag" outside of any syntax item, the "vimCommand"
+	highlight group is used.  When finding "tag" in a syntax item that
+	contains "vimSetting", the "vimSetting" group is used.
+
+
+DEFINING MATCHES					*:syn-match*
+
+:sy[ntax] match {group-name} [{options}] [excludenl] {pattern} [{options}]
+
+	This defines one match.
+
+	{group-name}		A syntax group name such as "Comment".
+	[{options}]		See |:syn-arguments| below.
+	[excludenl]		Don't make a pattern with the end-of-line "$"
+				extend a containing match or region.  Must be
+				given before the pattern. |:syn-excludenl|
+	{pattern}		The search pattern that defines the match.
+				See |:syn-pattern| below.
+				Note that the pattern may match more than one
+				line, which makes the match depend on where
+				Vim starts searching for the pattern.  You
+				need to make sure syncing takes care of this.
+
+	Example (match a character constant): >
+  :syntax match Character /'.'/hs=s+1,he=e-1
+<
+
+DEFINING REGIONS	*:syn-region* *:syn-start* *:syn-skip* *:syn-end*
+							*E398* *E399*
+:sy[ntax] region {group-name} [{options}]
+		[matchgroup={group-name}]
+		[keepend]
+		[extend]
+		[excludenl]
+		start={start_pattern} ..
+		[skip={skip_pattern}]
+		end={end_pattern} ..
+		[{options}]
+
+	This defines one region.  It may span several lines.
+
+	{group-name}		A syntax group name such as "Comment".
+	[{options}]		See |:syn-arguments| below.
+	[matchgroup={group-name}]  The syntax group to use for the following
+				start or end pattern matches only.  Not used
+				for the text in between the matched start and
+				end patterns.  Use NONE to reset to not using
+				a different group for the start or end match.
+				See |:syn-matchgroup|.
+	keepend			Don't allow contained matches to go past a
+				match with the end pattern.  See
+				|:syn-keepend|.
+	extend			Override a "keepend" for an item this region
+				is contained in.  See |:syn-extend|.
+	excludenl		Don't make a pattern with the end-of-line "$"
+				extend a containing match or item.  Only
+				useful for end patterns.  Must be given before
+				the patterns it applies to. |:syn-excludenl|
+	start={start_pattern}	The search pattern that defines the start of
+				the region.  See |:syn-pattern| below.
+	skip={skip_pattern}	The search pattern that defines text inside
+				the region where not to look for the end
+				pattern.  See |:syn-pattern| below.
+	end={end_pattern}	The search pattern that defines the end of
+				the region.  See |:syn-pattern| below.
+
+	Example: >
+  :syntax region String   start=+"+  skip=+\\"+  end=+"+
+<
+	The start/skip/end patterns and the options can be given in any order.
+	There can be zero or one skip pattern.	There must be one or more
+	start and end patterns.  This means that you can omit the skip
+	pattern, but you must give at least one start and one end pattern.  It
+	is allowed to have white space before and after the equal sign
+	(although it mostly looks better without white space).
+
+	When more than one start pattern is given, a match with one of these
+	is sufficient.	This means there is an OR relation between the start
+	patterns.  The last one that matches is used.  The same is true for
+	the end patterns.
+
+	The search for the end pattern starts right after the start pattern.
+	Offsets are not used for this.	This implies that the match for the
+	end pattern will never overlap with the start pattern.
+
+	The skip and end pattern can match across line breaks, but since the
+	search for the pattern can start in any line it often does not do what
+	you want.  The skip pattern doesn't avoid a match of an end pattern in
+	the next line.	Use single-line patterns to avoid trouble.
+
+	Note: The decision to start a region is only based on a matching start
+	pattern.  There is no check for a matching end pattern.  This does NOT
+	work: >
+		:syn region First  start="("  end=":"
+		:syn region Second start="("  end=";"
+<	The Second always matches before the First (last defined pattern has
+	higher priority).  The Second region then continues until the next
+	';', no matter if there is a ':' before it.  Using a match does work: >
+		:syn match First  "(\_.\{-}:"
+		:syn match Second "(\_.\{-};"
+<	This pattern matches any character or line break with "\_." and
+	repeats that with "\{-}" (repeat as few as possible).
+
+							*:syn-keepend*
+	By default, a contained match can obscure a match for the end pattern.
+	This is useful for nesting.  For example, a region that starts with
+	"{" and ends with "}", can contain another region.  An encountered "}"
+	will then end the contained region, but not the outer region:
+	    {		starts outer "{}" region
+		{	starts contained "{}" region
+		}	ends contained "{}" region
+	    }		ends outer "{} region
+	If you don't want this, the "keepend" argument will make the matching
+	of an end pattern of the outer region also end any contained item.
+	This makes it impossible to nest the same region, but allows for
+	contained items to highlight parts of the end pattern, without causing
+	that to skip the match with the end pattern.  Example: >
+  :syn match  vimComment +"[^"]\+$+
+  :syn region vimCommand start="set" end="$" contains=vimComment keepend
+<	The "keepend" makes the vimCommand always end at the end of the line,
+	even though the contained vimComment includes a match with the <EOL>.
+
+	When "keepend" is not used, a match with an end pattern is retried
+	after each contained match.  When "keepend" is included, the first
+	encountered match with an end pattern is used, truncating any
+	contained matches.
+							*:syn-extend*
+	The "keepend" behavior can be changed by using the "extend" argument.
+	When an item with "extend" is contained in an item that uses
+	"keepend", the "keepend" is ignored and the containing region will be
+	extended.
+	This can be used to have some contained items extend a region while
+	others don't.  Example: >
+
+   :syn region htmlRef start=+<a>+ end=+</a>+ keepend contains=htmlItem,htmlScript
+   :syn match htmlItem +<[^>]*>+ contained
+   :syn region htmlScript start=+<script+ end=+</script[^>]*>+ contained extend
+
+<	Here the htmlItem item does not make the htmlRef item continue
+	further, it is only used to highlight the <> items.  The htmlScript
+	item does extend the htmlRef item.
+
+	Another example: >
+   :syn region xmlFold start="<a>" end="</a>" fold transparent keepend extend
+<	This defines a region with "keepend", so that its end cannot be
+	changed by contained items, like when the "</a>" is matched to
+	highlight it differently.  But when the xmlFold region is nested (it
+	includes itself), the "extend" applies, so that the "</a>" of a nested
+	region only ends that region, and not the one it is contained in.
+
+							*:syn-excludenl*
+	When a pattern for a match or end pattern of a region includes a '$'
+	to match the end-of-line, it will make a region item that it is
+	contained in continue on the next line.  For example, a match with
+	"\\$" (backslash at the end of the line) can make a region continue
+	that would normally stop at the end of the line.  This is the default
+	behavior.  If this is not wanted, there are two ways to avoid it:
+	1. Use "keepend" for the containing item.  This will keep all
+	   contained matches from extending the match or region.  It can be
+	   used when all contained items must not extend the containing item.
+	2. Use "excludenl" in the contained item.  This will keep that match
+	   from extending the containing match or region.  It can be used if
+	   only some contained items must not extend the containing item.
+	   "excludenl" must be given before the pattern it applies to.
+
+							*:syn-matchgroup*
+	"matchgroup" can be used to highlight the start and/or end pattern
+	differently than the body of the region.  Example: >
+  :syntax region String matchgroup=Quote start=+"+  skip=+\\"+	end=+"+
+<	This will highlight the quotes with the "Quote" group, and the text in
+	between with the "String" group.
+	The "matchgroup" is used for all start and end patterns that follow,
+	until the next "matchgroup".  Use "matchgroup=NONE" to go back to not
+	using a matchgroup.
+
+	In a start or end pattern that is highlighted with "matchgroup" the
+	contained items of the region are not used.  This can be used to avoid
+	that a contained item matches in the start or end pattern match.  When
+	using "transparent", this does not apply to a start or end pattern
+	match that is highlighted with "matchgroup".
+
+	Here is an example, which highlights three levels of parentheses in
+	different colors: >
+   :sy region par1 matchgroup=par1 start=/(/ end=/)/ contains=par2
+   :sy region par2 matchgroup=par2 start=/(/ end=/)/ contains=par3 contained
+   :sy region par3 matchgroup=par3 start=/(/ end=/)/ contains=par1 contained
+   :hi par1 ctermfg=red guifg=red
+   :hi par2 ctermfg=blue guifg=blue
+   :hi par3 ctermfg=darkgreen guifg=darkgreen
+
+==============================================================================
+6. :syntax arguments					*:syn-arguments*
+
+The :syntax commands that define syntax items take a number of arguments.
+The common ones are explained here.  The arguments may be given in any order
+and may be mixed with patterns.
+
+Not all commands accept all arguments.	This table shows which arguments
+can not be used for all commands:
+							*E395* *E396*
+		    contains  oneline	fold  display  extend ~
+:syntax keyword		 -	 -	 -	 -	 -
+:syntax match		yes	 -	yes	yes	yes
+:syntax region		yes	yes	yes	yes	yes
+
+These arguments can be used for all three commands:
+	contained
+	containedin
+	nextgroup
+	transparent
+	skipwhite
+	skipnl
+	skipempty
+
+
+contained						*:syn-contained*
+
+When the "contained" argument is given, this item will not be recognized at
+the top level, but only when it is mentioned in the "contains" field of
+another match.	Example: >
+   :syntax keyword Todo    TODO    contained
+   :syntax match   Comment "//.*"  contains=Todo
+
+
+display							*:syn-display*
+
+If the "display" argument is given, this item will be skipped when the
+detected highlighting will not be displayed.  This will speed up highlighting,
+by skipping this item when only finding the syntax state for the text that is
+to be displayed.
+
+Generally, you can use "display" for match and region items that meet these
+conditions:
+- The item does not continue past the end of a line.  Example for C: A region
+  for a "/*" comment can't contain "display", because it continues on the next
+  line.
+- The item does not contain items that continue past the end of the line or
+  make it continue on the next line.
+- The item does not change the size of any item it is contained in.  Example
+  for C: A match with "\\$" in a preprocessor match can't have "display",
+  because it may make that preprocessor match shorter.
+- The item does not allow other items to match that didn't match otherwise,
+  and that item may extend the match too far.  Example for C: A match for a
+  "//" comment can't use "display", because a "/*" inside that comment would
+  match then and start a comment which extends past the end of the line.
+
+Examples, for the C language, where "display" can be used:
+- match with a number
+- match with a label
+
+
+transparent						*:syn-transparent*
+
+If the "transparent" argument is given, this item will not be highlighted
+itself, but will take the highlighting of the item it is contained in.	This
+is useful for syntax items that don't need any highlighting but are used
+only to skip over a part of the text.
+
+The "contains=" argument is also inherited from the item it is contained in,
+unless a "contains" argument is given for the transparent item itself.	To
+avoid that unwanted items are contained, use "contains=NONE".  Example, which
+highlights words in strings, but makes an exception for "vim": >
+	:syn match myString /'[^']*'/ contains=myWord,myVim
+	:syn match myWord   /\<[a-z]*\>/ contained
+	:syn match myVim    /\<vim\>/ transparent contained contains=NONE
+	:hi link myString String
+	:hi link myWord   Comment
+Since the "myVim" match comes after "myWord" it is the preferred match (last
+match in the same position overrules an earlier one).  The "transparent"
+argument makes the "myVim" match use the same highlighting as "myString".  But
+it does not contain anything.  If the "contains=NONE" argument would be left
+out, then "myVim" would use the contains argument from myString and allow
+"myWord" to be contained, which will be highlighted as a Constant.  This
+happens because a contained match doesn't match inside itself in the same
+position, thus the "myVim" match doesn't overrule the "myWord" match here.
+
+When you look at the colored text, it is like looking at layers of contained
+items.	The contained item is on top of the item it is contained in, thus you
+see the contained item.  When a contained item is transparent, you can look
+through, thus you see the item it is contained in.  In a picture:
+
+		look from here
+
+	    |	|   |	|   |	|
+	    V	V   V	V   V	V
+
+	       xxxx	  yyy		more contained items
+	    ....................	contained item (transparent)
+	=============================	first item
+
+The 'x', 'y' and '=' represent a highlighted syntax item.  The '.' represent a
+transparent group.
+
+What you see is:
+
+	=======xxxx=======yyy========
+
+Thus you look through the transparent "....".
+
+
+oneline							*:syn-oneline*
+
+The "oneline" argument indicates that the region does not cross a line
+boundary.  It must match completely in the current line.  However, when the
+region has a contained item that does cross a line boundary, it continues on
+the next line anyway.  A contained item can be used to recognize a line
+continuation pattern.  But the "end" pattern must still match in the first
+line, otherwise the region doesn't even start.
+
+When the start pattern includes a "\n" to match an end-of-line, the end
+pattern must be found in the same line as where the start pattern ends.  The
+end pattern may also include an end-of-line.  Thus the "oneline" argument
+means that the end of the start pattern and the start of the end pattern must
+be within one line.  This can't be changed by a skip pattern that matches a
+line break.
+
+
+fold							*:syn-fold*
+
+The "fold" argument makes the fold level increased by one for this item.
+Example: >
+   :syn region myFold start="{" end="}" transparent fold
+   :syn sync fromstart
+   :set foldmethod=syntax
+This will make each {} block form one fold.
+
+The fold will start on the line where the item starts, and end where the item
+ends.  If the start and end are within the same line, there is no fold.
+The 'foldnestmax' option limits the nesting of syntax folds.
+{not available when Vim was compiled without |+folding| feature}
+
+
+			*:syn-contains* *E405* *E406* *E407* *E408* *E409*
+contains={groupname},..
+
+The "contains" argument is followed by a list of syntax group names.  These
+groups will be allowed to begin inside the item (they may extend past the
+containing group's end).  This allows for recursive nesting of matches and
+regions.  If there is no "contains" argument, no groups will be contained in
+this item.  The group names do not need to be defined before they can be used
+here.
+
+contains=ALL
+		If the only item in the contains list is "ALL", then all
+		groups will be accepted inside the item.
+
+contains=ALLBUT,{group-name},..
+		If the first item in the contains list is "ALLBUT", then all
+		groups will be accepted inside the item, except the ones that
+		are listed.  Example: >
+  :syntax region Block start="{" end="}" ... contains=ALLBUT,Function
+
+contains=TOP
+		If the first item in the contains list is "TOP", then all
+		groups will be accepted that don't have the "contained"
+		argument.
+contains=TOP,{group-name},..
+		Like "TOP", but excluding the groups that are listed.
+
+contains=CONTAINED
+		If the first item in the contains list is "CONTAINED", then
+		all groups will be accepted that have the "contained"
+		argument.
+contains=CONTAINED,{group-name},..
+		Like "CONTAINED", but excluding the groups that are
+		listed.
+
+
+The {group-name} in the "contains" list can be a pattern.  All group names
+that match the pattern will be included (or excluded, if "ALLBUT" is used).
+The pattern cannot contain white space or a ','.  Example: >
+   ... contains=Comment.*,Keyw[0-3]
+The matching will be done at moment the syntax command is executed.  Groups
+that are defined later will not be matched.  Also, if the current syntax
+command defines a new group, it is not matched.  Be careful: When putting
+syntax commands in a file you can't rely on groups NOT being defined, because
+the file may have been sourced before, and ":syn clear" doesn't remove the
+group names.
+
+The contained groups will also match in the start and end patterns of a
+region.  If this is not wanted, the "matchgroup" argument can be used
+|:syn-matchgroup|.  The "ms=" and "me=" offsets can be used to change the
+region where contained items do match.	Note that this may also limit the
+area that is highlighted
+
+
+containedin={groupname}...				*:syn-containedin*
+
+The "containedin" argument is followed by a list of syntax group names.  The
+item will be allowed to begin inside these groups.  This works as if the
+containing item has a "contains=" argument that includes this item.
+
+The {groupname}... can be used just like for "contains", as explained above.
+
+This is useful when adding a syntax item afterwards.  An item can be told to
+be included inside an already existing item, without changing the definition
+of that item.  For example, to highlight a word in a C comment after loading
+the C syntax: >
+	:syn keyword myword HELP containedin=cComment contained
+Note that "contained" is also used, to avoid that the item matches at the top
+level.
+
+Matches for "containedin" are added to the other places where the item can
+appear.  A "contains" argument may also be added as usual.  Don't forget that
+keywords never contain another item, thus adding them to "containedin" won't
+work.
+
+
+nextgroup={groupname},..				*:syn-nextgroup*
+
+The "nextgroup" argument is followed by a list of syntax group names,
+separated by commas (just like with "contains", so you can also use patterns).
+
+If the "nextgroup" argument is given, the mentioned syntax groups will be
+tried for a match, after the match or region ends.  If none of the groups have
+a match, highlighting continues normally.  If there is a match, this group
+will be used, even when it is not mentioned in the "contains" field of the
+current group.	This is like giving the mentioned group priority over all
+other groups.  Example: >
+   :syntax match  ccFoobar  "Foo.\{-}Bar"  contains=ccFoo
+   :syntax match  ccFoo     "Foo"	    contained nextgroup=ccFiller
+   :syntax region ccFiller  start="."  matchgroup=ccBar  end="Bar"  contained
+
+This will highlight "Foo" and "Bar" differently, and only when there is a
+"Bar" after "Foo".  In the text line below, "f" shows where ccFoo is used for
+highlighting, and "bbb" where ccBar is used. >
+
+   Foo asdfasd Bar asdf Foo asdf Bar asdf
+   fff	       bbb	fff	 bbb
+
+Note the use of ".\{-}" to skip as little as possible until the next Bar.
+when ".*" would be used, the "asdf" in between "Bar" and "Foo" would be
+highlighted according to the "ccFoobar" group, because the ccFooBar match
+would include the first "Foo" and the last "Bar" in the line (see |pattern|).
+
+
+skipwhite						*:syn-skipwhite*
+skipnl							*:syn-skipnl*
+skipempty						*:syn-skipempty*
+
+These arguments are only used in combination with "nextgroup".	They can be
+used to allow the next group to match after skipping some text:
+	skipwhite	skip over space and tab characters
+	skipnl		skip over the end of a line
+	skipempty	skip over empty lines (implies a "skipnl")
+
+When "skipwhite" is present, the white space is only skipped if there is no
+next group that matches the white space.
+
+When "skipnl" is present, the match with nextgroup may be found in the next
+line.  This only happens when the current item ends at the end of the current
+line!  When "skipnl" is not present, the nextgroup will only be found after
+the current item in the same line.
+
+When skipping text while looking for a next group, the matches for other
+groups are ignored.  Only when no next group matches, other items are tried
+for a match again.  This means that matching a next group and skipping white
+space and <EOL>s has a higher priority than other items.
+
+Example: >
+  :syn match ifstart "\<if.*"	  nextgroup=ifline skipwhite skipempty
+  :syn match ifline  "[^ \t].*" nextgroup=ifline skipwhite skipempty contained
+  :syn match ifline  "endif"	contained
+Note that the "[^ \t].*" match matches all non-white text.  Thus it would also
+match "endif".	Therefore the "endif" match is put last, so that it takes
+precedence.
+Note that this example doesn't work for nested "if"s.  You need to add
+"contains" arguments to make that work (omitted for simplicity of the
+example).
+
+==============================================================================
+7. Syntax patterns				*:syn-pattern* *E401* *E402*
+
+In the syntax commands, a pattern must be surrounded by two identical
+characters.  This is like it works for the ":s" command.  The most common to
+use is the double quote.  But if the pattern contains a double quote, you can
+use another character that is not used in the pattern.	Examples: >
+  :syntax region Comment  start="/\*"  end="\*/"
+  :syntax region String   start=+"+    end=+"+	 skip=+\\"+
+
+See |pattern| for the explanation of what a pattern is.  Syntax patterns are
+always interpreted like the 'magic' options is set, no matter what the actual
+value of 'magic' is.  And the patterns are interpreted like the 'l' flag is
+not included in 'cpoptions'.  This was done to make syntax files portable and
+independent of 'compatible' and 'magic' settings.
+
+Try to avoid patterns that can match an empty string, such as "[a-z]*".
+This slows down the highlighting a lot, because it matches everywhere.
+
+						*:syn-pattern-offset*
+The pattern can be followed by a character offset.  This can be used to
+change the highlighted part, and to change the text area included in the
+match or region (which only matters when trying to match other items).	Both
+are relative to the matched pattern.  The character offset for a skip
+pattern can be used to tell where to continue looking for an end pattern.
+
+The offset takes the form of "{what}={offset}"
+The {what} can be one of seven strings:
+
+ms	Match Start	offset for the start of the matched text
+me	Match End	offset for the end of the matched text
+hs	Highlight Start	offset for where the highlighting starts
+he	Highlight End	offset for where the highlighting ends
+rs	Region Start	offset for where the body of a region starts
+re	Region End	offset for where the body of a region ends
+lc	Leading Context	offset past "leading context" of pattern
+
+The {offset} can be:
+
+s	start of the matched pattern
+s+{nr}	start of the matched pattern plus {nr} chars to the right
+s-{nr}	start of the matched pattern plus {nr} chars to the left
+e	end of the matched pattern
+e+{nr}	end of the matched pattern plus {nr} chars to the right
+e-{nr}	end of the matched pattern plus {nr} chars to the left
+{nr}	(for "lc" only): start matching {nr} chars to the left
+
+Examples: "ms=s+1", "hs=e-2", "lc=3".
+
+Although all offsets are accepted after any pattern, they are not always
+meaningful.  This table shows which offsets are actually used:
+
+		    ms	 me   hs   he	rs   re	  lc ~
+match item	    yes  yes  yes  yes	-    -	  yes
+region item start   yes  -    yes  -	yes  -	  yes
+region item skip    -	 yes  -    -	-    -	  yes
+region item end     -	 yes  -    yes	-    yes  yes
+
+Offsets can be concatenated, with a ',' in between.  Example: >
+  :syn match String  /"[^"]*"/hs=s+1,he=e-1
+<
+    some "string" text
+	  ^^^^^^		highlighted
+
+Notes:
+- There must be no white space between the pattern and the character
+  offset(s).
+- The highlighted area will never be outside of the matched text.
+- A negative offset for an end pattern may not always work, because the end
+  pattern may be detected when the highlighting should already have stopped.
+- The start of a match cannot be in a line other than where the pattern
+  matched.  This doesn't work: "a\nb"ms=e.  You can make the highlighting
+  start in another line, this does work: "a\nb"hs=e.
+
+Example (match a comment but don't highlight the /* and */): >
+  :syntax region Comment start="/\*"hs=e+1 end="\*/"he=s-1
+<
+	/* this is a comment */
+	  ^^^^^^^^^^^^^^^^^^^	  highlighted
+
+A more complicated Example: >
+  :syn region Exa matchgroup=Foo start="foo"hs=s+2,rs=e+2 matchgroup=Bar end="bar"me=e-1,he=e-1,re=s-1
+<
+	 abcfoostringbarabc
+	    mmmmmmmmmmm	    match
+	      sssrrreee	    highlight start/region/end ("Foo", "Exa" and "Bar")
+
+Leading context			*:syn-lc* *:syn-leading* *:syn-context*
+
+Note: This is an obsolete feature, only included for backwards compatibility
+with previous Vim versions.  It's now recommended to use the |/\@<=| construct
+in the pattern.
+
+The "lc" offset specifies leading context -- a part of the pattern that must
+be present, but is not considered part of the match.  An offset of "lc=n" will
+cause Vim to step back n columns before attempting the pattern match, allowing
+characters which have already been matched in previous patterns to also be
+used as leading context for this match.  This can be used, for instance, to
+specify that an "escaping" character must not precede the match: >
+
+  :syn match ZNoBackslash "[^\\]z"ms=s+1
+  :syn match WNoBackslash "[^\\]w"lc=1
+  :syn match Underline "_\+"
+<
+	  ___zzzz ___wwww
+	  ^^^	  ^^^	  matches Underline
+	      ^ ^	  matches ZNoBackslash
+		     ^^^^ matches WNoBackslash
+
+The "ms" offset is automatically set to the same value as the "lc" offset,
+unless you set "ms" explicitly.
+
+
+Multi-line patterns					*:syn-multi-line*
+
+The patterns can include "\n" to match an end-of-line.	Mostly this works as
+expected, but there are a few exceptions.
+
+When using a start pattern with an offset, the start of the match is not
+allowed to start in a following line.  The highlighting can start in a
+following line though.
+
+The skip pattern can include the "\n", but the search for an end pattern will
+continue in the first character of the next line, also when that character is
+matched by the skip pattern.  This is because redrawing may start in any line
+halfway a region and there is no check if the skip pattern started in a
+previous line.	For example, if the skip pattern is "a\nb" and an end pattern
+is "b", the end pattern does match in the second line of this: >
+	 x x a
+	 b x x
+Generally this means that the skip pattern should not match any characters
+after the "\n".
+
+
+External matches					*:syn-ext-match*
+
+These extra regular expression items are available in region patterns:
+
+						*/\z(* */\z(\)* *E50* *E52*
+    \z(\)	Marks the sub-expression as "external", meaning that it is can
+		be accessed from another pattern match.  Currently only usable
+		in defining a syntax region start pattern.
+
+					*/\z1* */\z2* */\z3* */\z4* */\z5*
+    \z1  ...  \z9			*/\z6* */\z7* */\z8* */\z9* *E66* *E67*
+		Matches the same string that was matched by the corresponding
+		sub-expression in a previous start pattern match.
+
+Sometimes the start and end patterns of a region need to share a common
+sub-expression.  A common example is the "here" document in Perl and many Unix
+shells.  This effect can be achieved with the "\z" special regular expression
+items, which marks a sub-expression as "external", in the sense that it can be
+referenced from outside the pattern in which it is defined.  The here-document
+example, for instance, can be done like this: >
+  :syn region hereDoc start="<<\z(\I\i*\)" end="^\z1$"
+
+As can be seen here, the \z actually does double duty.	In the start pattern,
+it marks the "\(\I\i*\)" sub-expression as external; in the end pattern, it
+changes the \1 back-reference into an external reference referring to the
+first external sub-expression in the start pattern.  External references can
+also be used in skip patterns: >
+  :syn region foo start="start \(\I\i*\)" skip="not end \z1" end="end \z1"
+
+Note that normal and external sub-expressions are completely orthogonal and
+indexed separately; for instance, if the pattern "\z(..\)\(..\)" is applied
+to the string "aabb", then \1 will refer to "bb" and \z1 will refer to "aa".
+Note also that external sub-expressions cannot be accessed as back-references
+within the same pattern like normal sub-expressions.  If you want to use one
+sub-expression as both a normal and an external sub-expression, you can nest
+the two, as in "\(\z(...\)\)".
+
+Note that only matches within a single line can be used.  Multi-line matches
+cannot be referred to.
+
+==============================================================================
+8. Syntax clusters					*:syn-cluster* *E400*
+
+:sy[ntax] cluster {cluster-name} [contains={group-name}..]
+				 [add={group-name}..]
+				 [remove={group-name}..]
+
+This command allows you to cluster a list of syntax groups together under a
+single name.
+
+	contains={group-name}..
+		The cluster is set to the specified list of groups.
+	add={group-name}..
+		The specified groups are added to the cluster.
+	remove={group-name}..
+		The specified groups are removed from the cluster.
+
+A cluster so defined may be referred to in a contains=.., nextgroup=.., add=..
+or remove=.. list with a "@" prefix.  You can also use this notation to
+implicitly declare a cluster before specifying its contents.
+
+Example: >
+   :syntax match Thing "# [^#]\+ #" contains=@ThingMembers
+   :syntax cluster ThingMembers contains=ThingMember1,ThingMember2
+
+As the previous example suggests, modifications to a cluster are effectively
+retroactive; the membership of the cluster is checked at the last minute, so
+to speak: >
+   :syntax keyword A aaa
+   :syntax keyword B bbb
+   :syntax cluster AandB contains=A
+   :syntax match Stuff "( aaa bbb )" contains=@AandB
+   :syntax cluster AandB add=B	  " now both keywords are matched in Stuff
+
+This also has implications for nested clusters: >
+   :syntax keyword A aaa
+   :syntax keyword B bbb
+   :syntax cluster SmallGroup contains=B
+   :syntax cluster BigGroup contains=A,@SmallGroup
+   :syntax match Stuff "( aaa bbb )" contains=@BigGroup
+   :syntax cluster BigGroup remove=B	" no effect, since B isn't in BigGroup
+   :syntax cluster SmallGroup remove=B	" now bbb isn't matched within Stuff
+
+==============================================================================
+9. Including syntax files				*:syn-include* *E397*
+
+It is often useful for one language's syntax file to include a syntax file for
+a related language.  Depending on the exact relationship, this can be done in
+two different ways:
+
+	- If top-level syntax items in the included syntax file are to be
+	  allowed at the top level in the including syntax, you can simply use
+	  the |:runtime| command: >
+
+  " In cpp.vim:
+  :runtime! syntax/c.vim
+  :unlet b:current_syntax
+
+<	- If top-level syntax items in the included syntax file are to be
+	  contained within a region in the including syntax, you can use the
+	  ":syntax include" command:
+
+:sy[ntax] include [@{grouplist-name}] {file-name}
+
+	  All syntax items declared in the included file will have the
+	  "contained" flag added.  In addition, if a group list is specified,
+	  all top-level syntax items in the included file will be added to
+	  that list. >
+
+   " In perl.vim:
+   :syntax include @Pod <sfile>:p:h/pod.vim
+   :syntax region perlPOD start="^=head" end="^=cut" contains=@Pod
+<
+	  When {file-name} is an absolute path (starts with "/", "c:", "$VAR"
+	  or "<sfile>") that file is sourced.  When it is a relative path
+	  (e.g., "syntax/pod.vim") the file is searched for in 'runtimepath'.
+	  All matching files are loaded.  Using a relative path is
+	  recommended, because it allows a user to replace the included file
+	  with his own version, without replacing the file that does the ":syn
+	  include".
+
+==============================================================================
+10. Synchronizing				*:syn-sync* *E403* *E404*
+
+Vim wants to be able to start redrawing in any position in the document.  To
+make this possible it needs to know the syntax state at the position where
+redrawing starts.
+
+:sy[ntax] sync [ccomment [group-name] | minlines={N} | ...]
+
+There are four ways to synchronize:
+1. Always parse from the start of the file.
+   |:syn-sync-first|
+2. Based on C-style comments.  Vim understands how C-comments work and can
+   figure out if the current line starts inside or outside a comment.
+   |:syn-sync-second|
+3. Jumping back a certain number of lines and start parsing there.
+   |:syn-sync-third|
+4. Searching backwards in the text for a pattern to sync on.
+   |:syn-sync-fourth|
+
+				*:syn-sync-maxlines* *:syn-sync-minlines*
+For the last three methods, the line range where the parsing can start is
+limited by "minlines" and "maxlines".
+
+If the "minlines={N}" argument is given, the parsing always starts at least
+that many lines backwards.  This can be used if the parsing may take a few
+lines before it's correct, or when it's not possible to use syncing.
+
+If the "maxlines={N}" argument is given, the number of lines that are searched
+for a comment or syncing pattern is restricted to N lines backwards (after
+adding "minlines").  This is useful if you have few things to sync on and a
+slow machine.  Example: >
+   :syntax sync ccomment maxlines=500
+<
+						*:syn-sync-linebreaks*
+When using a pattern that matches multiple lines, a change in one line may
+cause a pattern to no longer match in a previous line.	This means has to
+start above where the change was made.	How many lines can be specified with
+the "linebreaks" argument.  For example, when a pattern may include one line
+break use this: >
+   :syntax sync linebreaks=1
+The result is that redrawing always starts at least one line before where a
+change was made.  The default value for "linebreaks" is zero.  Usually the
+value for "minlines" is bigger than "linebreaks".
+
+
+First syncing method:			*:syn-sync-first*
+>
+   :syntax sync fromstart
+
+The file will be parsed from the start.  This makes syntax highlighting
+accurate, but can be slow for long files.  Vim caches previously parsed text,
+so that it's only slow when parsing the text for the first time.  However,
+when making changes some part of the next needs to be parsed again (worst
+case: to the end of the file).
+
+Using "fromstart" is equivalent to using "minlines" with a very large number.
+
+
+Second syncing method:			*:syn-sync-second* *:syn-sync-ccomment*
+
+For the second method, only the "ccomment" argument needs to be given.
+Example: >
+   :syntax sync ccomment
+
+When Vim finds that the line where displaying starts is inside a C-style
+comment, the last region syntax item with the group-name "Comment" will be
+used.  This requires that there is a region with the group-name "Comment"!
+An alternate group name can be specified, for example: >
+   :syntax sync ccomment javaComment
+This means that the last item specified with "syn region javaComment" will be
+used for the detected C comment region.  This only works properly if that
+region does have a start pattern "\/*" and an end pattern "*\/".
+
+The "maxlines" argument can be used to restrict the search to a number of
+lines.	The "minlines" argument can be used to at least start a number of
+lines back (e.g., for when there is some construct that only takes a few
+lines, but it hard to sync on).
+
+Note: Syncing on a C comment doesn't work properly when strings are used
+that cross a line and contain a "*/".  Since letting strings cross a line
+is a bad programming habit (many compilers give a warning message), and the
+chance of a "*/" appearing inside a comment is very small, this restriction
+is hardly ever noticed.
+
+
+Third syncing method:				*:syn-sync-third*
+
+For the third method, only the "minlines={N}" argument needs to be given.
+Vim will subtract {N} from the line number and start parsing there.  This
+means {N} extra lines need to be parsed, which makes this method a bit slower.
+Example: >
+   :syntax sync minlines=50
+
+"lines" is equivalent to "minlines" (used by older versions).
+
+
+Fourth syncing method:				*:syn-sync-fourth*
+
+The idea is to synchronize on the end of a few specific regions, called a
+sync pattern.  Only regions can cross lines, so when we find the end of some
+region, we might be able to know in which syntax item we are.  The search
+starts in the line just above the one where redrawing starts.  From there
+the search continues backwards in the file.
+
+This works just like the non-syncing syntax items.  You can use contained
+matches, nextgroup, etc.  But there are a few differences:
+- Keywords cannot be used.
+- The syntax items with the "sync" keyword form a completely separated group
+  of syntax items.  You can't mix syncing groups and non-syncing groups.
+- The matching works backwards in the buffer (line by line), instead of
+  forwards.
+- A line continuation pattern can be given.  It is used to decide which group
+  of lines need to be searched like they were one line.  This means that the
+  search for a match with the specified items starts in the first of the
+  consecutive that contain the continuation pattern.
+- When using "nextgroup" or "contains", this only works within one line (or
+  group of continued lines).
+- When using a region, it must start and end in the same line (or group of
+  continued lines).  Otherwise the end is assumed to be at the end of the
+  line (or group of continued lines).
+- When a match with a sync pattern is found, the rest of the line (or group of
+  continued lines) is searched for another match.  The last match is used.
+  This is used when a line can contain both the start end the end of a region
+  (e.g., in a C-comment like /* this */, the last "*/" is used).
+
+There are two ways how a match with a sync pattern can be used:
+1. Parsing for highlighting starts where redrawing starts (and where the
+   search for the sync pattern started).  The syntax group that is expected
+   to be valid there must be specified.  This works well when the regions
+   that cross lines cannot contain other regions.
+2. Parsing for highlighting continues just after the match.  The syntax group
+   that is expected to be present just after the match must be specified.
+   This can be used when the previous method doesn't work well.  It's much
+   slower, because more text needs to be parsed.
+Both types of sync patterns can be used at the same time.
+
+Besides the sync patterns, other matches and regions can be specified, to
+avoid finding unwanted matches.
+
+[The reason that the sync patterns are given separately, is that mostly the
+search for the sync point can be much simpler than figuring out the
+highlighting.  The reduced number of patterns means it will go (much)
+faster.]
+
+					    *syn-sync-grouphere* *E393* *E394*
+    :syntax sync match {sync-group-name} grouphere {group-name} "pattern" ..
+
+	Define a match that is used for syncing.  {group-name} is the
+	name of a syntax group that follows just after the match.  Parsing
+	of the text for highlighting starts just after the match.  A region
+	must exist for this {group-name}.  The first one defined will be used.
+	"NONE" can be used for when there is no syntax group after the match.
+
+						*syn-sync-groupthere*
+    :syntax sync match {sync-group-name} groupthere {group-name} "pattern" ..
+
+	Like "grouphere", but {group-name} is the name of a syntax group that
+	is to be used at the start of the line where searching for the sync
+	point started.	The text between the match and the start of the sync
+	pattern searching is assumed not to change the syntax highlighting.
+	For example, in C you could search backwards for "/*" and "*/".  If
+	"/*" is found first, you know that you are inside a comment, so the
+	"groupthere" is "cComment".  If "*/" is found first, you know that you
+	are not in a comment, so the "groupthere" is "NONE".  (in practice
+	it's a bit more complicated, because the "/*" and "*/" could appear
+	inside a string.  That's left as an exercise to the reader...).
+
+    :syntax sync match ..
+    :syntax sync region ..
+
+	Without a "groupthere" argument.  Define a region or match that is
+	skipped while searching for a sync point.
+
+						*syn-sync-linecont*
+    :syntax sync linecont {pattern}
+
+	When {pattern} matches in a line, it is considered to continue in
+	the next line.	This means that the search for a sync point will
+	consider the lines to be concatenated.
+
+If the "maxlines={N}" argument is given too, the number of lines that are
+searched for a match is restricted to N.  This is useful if you have very
+few things to sync on and a slow machine.  Example: >
+   :syntax sync maxlines=100
+
+You can clear all sync settings with: >
+   :syntax sync clear
+
+You can clear specific sync patterns with: >
+   :syntax sync clear {sync-group-name} ..
+
+==============================================================================
+11. Listing syntax items		*:syntax* *:sy* *:syn* *:syn-list*
+
+This command lists all the syntax items: >
+
+    :sy[ntax] [list]
+
+To show the syntax items for one syntax group: >
+
+    :sy[ntax] list {group-name}
+
+To list the syntax groups in one cluster:			*E392*	>
+
+    :sy[ntax] list @{cluster-name}
+
+See above for other arguments for the ":syntax" command.
+
+Note that the ":syntax" command can be abbreviated to ":sy", although ":syn"
+is mostly used, because it looks better.
+
+==============================================================================
+12. Highlight command			*:highlight* *:hi* *E28* *E411* *E415*
+
+There are three types of highlight groups:
+- The ones used for specific languages.  For these the name starts with the
+  name of the language.  Many of these don't have any attributes, but are
+  linked to a group of the second type.
+- The ones used for all syntax languages.
+- The ones used for the 'highlight' option.
+							*hitest.vim*
+You can see all the groups currently active with this command: >
+    :so $VIMRUNTIME/syntax/hitest.vim
+This will open a new window containing all highlight group names, displayed
+in their own color.
+
+						*:colo* *:colorscheme* *E185*
+:colo[rscheme] {name}	Load color scheme {name}.  This searches 'runtimepath'
+			for the file "colors/{name}.vim.  The first one that
+			is found is loaded.
+			To see the name of the currently active color scheme
+			(if there is one): >
+				:echo g:colors_name
+<			Doesn't work recursively, thus you can't use
+			":colorscheme" in a color scheme script.
+			After the color scheme has been loaded the
+			|ColorScheme| autocommand event is triggered.
+			For info about writing a colorscheme file: >
+				:edit $VIMRUNTIME/colors/README.txt
+
+:hi[ghlight]		List all the current highlight groups that have
+			attributes set.
+
+:hi[ghlight] {group-name}
+			List one highlight group.
+
+:hi[ghlight] clear	Reset all highlighting to the defaults.  Removes all
+			highlighting for groups added by the user!
+			Uses the current value of 'background' to decide which
+			default colors to use.
+
+:hi[ghlight] clear {group-name}
+:hi[ghlight] {group-name} NONE
+			Disable the highlighting for one highlight group.  It
+			is _not_ set back to the default colors.
+
+:hi[ghlight] [default] {group-name} {key}={arg} ..
+			Add a highlight group, or change the highlighting for
+			an existing group.
+			See |highlight-args| for the {key}={arg} arguments.
+			See |:highlight-default| for the optional [default]
+			argument.
+
+Normally a highlight group is added once when starting up.  This sets the
+default values for the highlighting.  After that, you can use additional
+highlight commands to change the arguments that you want to set to non-default
+values.  The value "NONE" can be used to switch the value off or go back to
+the default value.
+
+A simple way to change colors is with the |:colorscheme| command.  This loads
+a file with ":highlight" commands such as this: >
+
+   :hi Comment	gui=bold
+
+Note that all settings that are not included remain the same, only the
+specified field is used, and settings are merged with previous ones.  So, the
+result is like this single command has been used: >
+   :hi Comment	term=bold ctermfg=Cyan guifg=#80a0ff gui=bold
+<
+							*:highlight-verbose*
+When listing a highlight group and 'verbose' is non-zero, the listing will
+also tell where it was last set.  Example: >
+	:verbose hi Comment
+<	Comment        xxx term=bold ctermfg=4 guifg=Blue ~
+	   Last set from /home/mool/vim/vim7/runtime/syntax/syncolor.vim ~
+
+When ":hi clear" is used then the script where this command is used will be
+mentioned for the default values. See |:verbose-cmd| for more information.
+
+					*highlight-args* *E416* *E417* *E423*
+There are three types of terminals for highlighting:
+term	a normal terminal (vt100, xterm)
+cterm	a color terminal (MS-DOS console, color-xterm, these have the "Co"
+	termcap entry)
+gui	the GUI
+
+For each type the highlighting can be given.  This makes it possible to use
+the same syntax file on all terminals, and use the optimal highlighting.
+
+1. highlight arguments for normal terminals
+
+					*bold* *underline* *undercurl*
+					*inverse* *italic* *standout*
+term={attr-list}			*attr-list* *highlight-term* *E418*
+	attr-list is a comma separated list (without spaces) of the
+	following items (in any order):
+		bold
+		underline
+		undercurl	not always available
+		reverse
+		inverse		same as reverse
+		italic
+		standout
+		NONE		no attributes used (used to reset it)
+
+	Note that "bold" can be used here and by using a bold font.  They
+	have the same effect.
+	"undercurl" is a curly underline.  When "undercurl" is not possible
+	then "underline" is used.  In general "undercurl" is only available in
+	the GUI.  The color is set with |highlight-guisp|.
+
+start={term-list}				*highlight-start* *E422*
+stop={term-list}				*term-list* *highlight-stop*
+	These lists of terminal codes can be used to get
+	non-standard attributes on a terminal.
+
+	The escape sequence specified with the "start" argument
+	is written before the characters in the highlighted
+	area.  It can be anything that you want to send to the
+	terminal to highlight this area.  The escape sequence
+	specified with the "stop" argument is written after the
+	highlighted area.  This should undo the "start" argument.
+	Otherwise the screen will look messed up.
+
+	The {term-list} can have two forms:
+
+	1. A string with escape sequences.
+	   This is any string of characters, except that it can't start with
+	   "t_" and blanks are not allowed.  The <> notation is recognized
+	   here, so you can use things like "<Esc>" and "<Space>".  Example:
+		start=<Esc>[27h;<Esc>[<Space>r;
+
+	2. A list of terminal codes.
+	   Each terminal code has the form "t_xx", where "xx" is the name of
+	   the termcap entry.  The codes have to be separated with commas.
+	   White space is not allowed.	Example:
+		start=t_C1,t_BL
+	   The terminal codes must exist for this to work.
+
+
+2. highlight arguments for color terminals
+
+cterm={attr-list}					*highlight-cterm*
+	See above for the description of {attr-list} |attr-list|.
+	The "cterm" argument is likely to be different from "term", when
+	colors are used.  For example, in a normal terminal comments could
+	be underlined, in a color terminal they can be made Blue.
+	Note: Many terminals (e.g., DOS console) can't mix these attributes
+	with coloring.	Use only one of "cterm=" OR "ctermfg=" OR "ctermbg=".
+
+ctermfg={color-nr}				*highlight-ctermfg* *E421*
+ctermbg={color-nr}				*highlight-ctermbg*
+	The {color-nr} argument is a color number.  Its range is zero to
+	(not including) the number given by the termcap entry "Co".
+	The actual color with this number depends on the type of terminal
+	and its settings.  Sometimes the color also depends on the settings of
+	"cterm".  For example, on some systems "cterm=bold ctermfg=3" gives
+	another color, on others you just get color 3.
+
+	For an xterm this depends on your resources, and is a bit
+	unpredictable.	See your xterm documentation for the defaults.	The
+	colors for a color-xterm can be changed from the .Xdefaults file.
+	Unfortunately this means that it's not possible to get the same colors
+	for each user.	See |xterm-color| for info about color xterms.
+
+	The MSDOS standard colors are fixed (in a console window), so these
+	have been used for the names.  But the meaning of color names in X11
+	are fixed, so these color settings have been used, to make the
+	highlighting settings portable (complicated, isn't it?).  The
+	following names are recognized, with the color number used:
+
+							*cterm-colors*
+	    NR-16   NR-8    COLOR NAME ~
+	    0	    0	    Black
+	    1	    4	    DarkBlue
+	    2	    2	    DarkGreen
+	    3	    6	    DarkCyan
+	    4	    1	    DarkRed
+	    5	    5	    DarkMagenta
+	    6	    3	    Brown, DarkYellow
+	    7	    7	    LightGray, LightGrey, Gray, Grey
+	    8	    0*	    DarkGray, DarkGrey
+	    9	    4*	    Blue, LightBlue
+	    10	    2*	    Green, LightGreen
+	    11	    6*	    Cyan, LightCyan
+	    12	    1*	    Red, LightRed
+	    13	    5*	    Magenta, LightMagenta
+	    14	    3*	    Yellow, LightYellow
+	    15	    7*	    White
+
+	The number under "NR-16" is used for 16-color terminals ('t_Co'
+	greater than or equal to 16).  The number under "NR-8" is used for
+	8-color terminals ('t_Co' less than 16).  The '*' indicates that the
+	bold attribute is set for ctermfg.  In many 8-color terminals (e.g.,
+	"linux"), this causes the bright colors to appear.  This doesn't work
+	for background colors!	Without the '*' the bold attribute is removed.
+	If you want to set the bold attribute in a different way, put a
+	"cterm=" argument AFTER the "ctermfg=" or "ctermbg=" argument.	Or use
+	a number instead of a color name.
+
+	The case of the color names is ignored.
+	Note that for 16 color ansi style terminals (including xterms), the
+	numbers in the NR-8 column is used.  Here '*' means 'add 8' so that Blue
+	is 12, DarkGray is 8 etc.
+
+	Note that for some color terminals these names may result in the wrong
+	colors!
+
+							*:hi-normal-cterm*
+	When setting the "ctermfg" or "ctermbg" colors for the Normal group,
+	these will become the colors used for the non-highlighted text.
+	Example: >
+		:highlight Normal ctermfg=grey ctermbg=darkblue
+<	When setting the "ctermbg" color for the Normal group, the
+	'background' option will be adjusted automatically.  This causes the
+	highlight groups that depend on 'background' to change!  This means
+	you should set the colors for Normal first, before setting other
+	colors.
+	When a colorscheme is being used, changing 'background' causes it to
+	be reloaded, which may reset all colors (including Normal).  First
+	delete the "colors_name" variable when you don't want this.
+
+	When you have set "ctermfg" or "ctermbg" for the Normal group, Vim
+	needs to reset the color when exiting.	This is done with the "op"
+	termcap entry |t_op|.  If this doesn't work correctly, try setting the
+	't_op' option in your .vimrc.
+							*E419* *E420*
+	When Vim knows the normal foreground and background colors, "fg" and
+	"bg" can be used as color names.  This only works after setting the
+	colors for the Normal group and for the MS-DOS console.  Example, for
+	reverse video: >
+	    :highlight Visual ctermfg=bg ctermbg=fg
+<	Note that the colors are used that are valid at the moment this
+	command are given.  If the Normal group colors are changed later, the
+	"fg" and "bg" colors will not be adjusted.
+
+
+3. highlight arguments for the GUI
+
+gui={attr-list}						*highlight-gui*
+	These give the attributes to use in the GUI mode.
+	See |attr-list| for a description.
+	Note that "bold" can be used here and by using a bold font.  They
+	have the same effect.
+	Note that the attributes are ignored for the "Normal" group.
+
+font={font-name}					*highlight-font*
+	font-name is the name of a font, as it is used on the system Vim
+	runs on.  For X11 this is a complicated name, for example: >
+   font=-misc-fixed-bold-r-normal--14-130-75-75-c-70-iso8859-1
+<
+	The font-name "NONE" can be used to revert to the default font.
+	When setting the font for the "Normal" group, this becomes the default
+	font (until the 'guifont' option is changed; the last one set is
+	used).
+	The following only works with Motif and Athena, not with other GUIs:
+	When setting the font for the "Menu" group, the menus will be changed.
+	When setting the font for the "Tooltip" group, the tooltips will be
+	changed.
+	All fonts used, except for Menu and Tooltip, should be of the same
+	character size as the default font!  Otherwise redrawing problems will
+	occur.
+
+guifg={color-name}					*highlight-guifg*
+guibg={color-name}					*highlight-guibg*
+guisp={color-name}					*highlight-guisp*
+	These give the foreground (guifg), background (guibg) and special
+	(guisp) color to use in the GUI.  "guisp" is used for undercurl.
+	There are a few special names:
+		NONE		no color (transparent)
+		bg		use normal background color
+		background	use normal background color
+		fg		use normal foreground color
+		foreground	use normal foreground color
+	To use a color name with an embedded space or other special character,
+	put it in single quotes.  The single quote cannot be used then.
+	Example: >
+	    :hi comment guifg='salmon pink'
+<
+							*gui-colors*
+	Suggested color names (these are available on most systems):
+	    Red		LightRed	DarkRed
+	    Green	LightGreen	DarkGreen	SeaGreen
+	    Blue	LightBlue	DarkBlue	SlateBlue
+	    Cyan	LightCyan	DarkCyan
+	    Magenta	LightMagenta	DarkMagenta
+	    Yellow	LightYellow	Brown		DarkYellow
+	    Gray	LightGray	DarkGray
+	    Black	White
+	    Orange	Purple		Violet
+
+	In the Win32 GUI version, additional system colors are available.  See
+	|win32-colors|.
+
+	You can also specify a color by its Red, Green and Blue values.
+	The format is "#rrggbb", where
+		"rr"	is the Red value
+		"gg"	is the Green value
+		"bb"	is the Blue value
+	All values are hexadecimal, range from "00" to "ff".  Examples: >
+  :highlight Comment guifg=#11f0c3 guibg=#ff00ff
+<
+					*highlight-groups* *highlight-default*
+These are the default highlighting groups.  These groups are used by the
+'highlight' option default.  Note that the highlighting depends on the value
+of 'background'.  You can see the current settings with the ":highlight"
+command.
+							*hl-Cursor*
+Cursor		the character under the cursor
+							*hl-CursorIM*
+CursorIM	like Cursor, but used when in IME mode |CursorIM|
+							*hl-CursorColumn*
+CursorColumn	the screen column that the cursor is in when 'cursorcolumn' is
+		set
+							*hl-CursorLine*
+CursorLine	the screen line that the cursor is in when 'cursorline' is
+		set
+							*hl-Directory*
+Directory	directory names (and other special names in listings)
+							*hl-DiffAdd*
+DiffAdd		diff mode: Added line |diff.txt|
+							*hl-DiffChange*
+DiffChange	diff mode: Changed line |diff.txt|
+							*hl-DiffDelete*
+DiffDelete	diff mode: Deleted line |diff.txt|
+							*hl-DiffText*
+DiffText	diff mode: Changed text within a changed line |diff.txt|
+							*hl-ErrorMsg*
+ErrorMsg	error messages on the command line
+							*hl-VertSplit*
+VertSplit	the column separating vertically split windows
+							*hl-Folded*
+Folded		line used for closed folds
+							*hl-FoldColumn*
+FoldColumn	'foldcolumn'
+							*hl-SignColumn*
+SignColumn	column where |signs| are displayed
+							*hl-IncSearch*
+IncSearch	'incsearch' highlighting; also used for the text replaced with
+		":s///c"
+							*hl-LineNr*
+LineNr		Line number for ":number" and ":#" commands, and when 'number'
+		option is set.
+							*hl-MatchParen*
+MatchParen	The character under the cursor or just before it, if it
+		is a paired bracket, and its match. |pi_paren.txt|
+
+							*hl-ModeMsg*
+ModeMsg		'showmode' message (e.g., "-- INSERT --")
+							*hl-MoreMsg*
+MoreMsg		|more-prompt|
+							*hl-NonText*
+NonText		'~' and '@' at the end of the window, characters from
+		'showbreak' and other characters that do not really exist in
+		the text (e.g., ">" displayed when a double-wide character
+		doesn't fit at the end of the line).
+							*hl-Normal*
+Normal		normal text
+							*hl-Pmenu*
+Pmenu		Popup menu: normal item.
+							*hl-PmenuSel*
+PmenuSel	Popup menu: selected item.
+							*hl-PmenuSbar*
+PmenuSbar	Popup menu: scrollbar.
+							*hl-PmenuThumb*
+PmenuThumb	Popup menu: Thumb of the scrollbar.
+							*hl-Question*
+Question	|hit-enter| prompt and yes/no questions
+							*hl-Search*
+Search		Last search pattern highlighting (see 'hlsearch').
+		Also used for highlighting the current line in the quickfix
+		window and similar items that need to stand out.
+							*hl-SpecialKey*
+SpecialKey	Meta and special keys listed with ":map", also for text used
+		to show unprintable characters in the text, 'listchars'.
+		Generally: text that is displayed differently from what it
+		really is.
+							*hl-SpellBad*
+SpellBad	Word that is not recognized by the spellchecker. |spell|
+		This will be combined with the highlighting used otherwise.
+							*hl-SpellCap*
+SpellCap	Word that should start with a capital. |spell|
+		This will be combined with the highlighting used otherwise.
+							*hl-SpellLocal*
+SpellLocal	Word that is recognized by the spellchecker as one that is
+		used in another region. |spell|
+		This will be combined with the highlighting used otherwise.
+							*hl-SpellRare*
+SpellRare	Word that is recognized by the spellchecker as one that is
+		hardly ever used. |spell|
+		This will be combined with the highlighting used otherwise.
+							*hl-StatusLine*
+StatusLine	status line of current window
+							*hl-StatusLineNC*
+StatusLineNC	status lines of not-current windows
+		Note: if this is equal to "StatusLine" Vim will use "^^^" in
+		the status line of the current window.
+							*hl-TabLine*
+TabLine		tab pages line, not active tab page label
+							*hl-TabLineFill*
+TabLineFill	tab pages line, where there are no labels
+							*hl-TabLineSel*
+TabLineSel	tab pages line, active tab page label
+							*hl-Title*
+Title		titles for output from ":set all", ":autocmd" etc.
+							*hl-Visual*
+Visual		Visual mode selection
+							*hl-VisualNOS*
+VisualNOS	Visual mode selection when vim is "Not Owning the Selection".
+		Only X11 Gui's |gui-x11| and |xterm-clipboard| supports this.
+							*hl-WarningMsg*
+WarningMsg	warning messages
+							*hl-WildMenu*
+WildMenu	current match in 'wildmenu' completion
+
+					*hl-User1* *hl-User1..9* *hl-User9*
+The 'statusline' syntax allows the use of 9 different highlights in the
+statusline and ruler (via 'rulerformat').  The names are User1 to User9.
+
+For the GUI you can use these groups to set the colors for the menu,
+scrollbars and tooltips.  They don't have defaults.  This doesn't work for the
+Win32 GUI.  Only three highlight arguments have any effect here: font, guibg,
+and guifg.
+
+							*hl-Menu*
+Menu		Current font, background and foreground colors of the menus.
+		Also used for the toolbar.
+		Applicable highlight arguments: font, guibg, guifg.
+
+		NOTE: For Motif and Athena the font argument actually
+		specifies a fontset at all times, no matter if 'guifontset' is
+		empty, and as such it is tied to the current |:language| when
+		set.
+
+							*hl-Scrollbar*
+Scrollbar	Current background and foreground of the main window's
+		scrollbars.
+		Applicable highlight arguments: guibg, guifg.
+
+							*hl-Tooltip*
+Tooltip		Current font, background and foreground of the tooltips.
+		Applicable highlight arguments: font, guibg, guifg.
+
+		NOTE: For Motif and Athena the font argument actually
+		specifies a fontset at all times, no matter if 'guifontset' is
+		empty, and as such it is tied to the current |:language| when
+		set.
+
+==============================================================================
+13. Linking groups		*:hi-link* *:highlight-link* *E412* *E413*
+
+When you want to use the same highlighting for several syntax groups, you
+can do this more easily by linking the groups into one common highlight
+group, and give the color attributes only for that group.
+
+To set a link:
+
+    :hi[ghlight][!] [default] link {from-group} {to-group}
+
+To remove a link:
+
+    :hi[ghlight][!] [default] link {from-group} NONE
+
+Notes:							*E414*
+- If the {from-group} and/or {to-group} doesn't exist, it is created.  You
+  don't get an error message for a non-existing group.
+- As soon as you use a ":highlight" command for a linked group, the link is
+  removed.
+- If there are already highlight settings for the {from-group}, the link is
+  not made, unless the '!' is given.  For a ":highlight link" command in a
+  sourced file, you don't get an error message.  This can be used to skip
+  links for groups that already have settings.
+
+					*:hi-default* *:highlight-default*
+The [default] argument is used for setting the default highlighting for a
+group.	If highlighting has already been specified for the group the command
+will be ignored.  Also when there is an existing link.
+
+Using [default] is especially useful to overrule the highlighting of a
+specific syntax file.  For example, the C syntax file contains: >
+	:highlight default link cComment Comment
+If you like Question highlighting for C comments, put this in your vimrc file: >
+	:highlight link cComment Question
+Without the "default" in the C syntax file, the highlighting would be
+overruled when the syntax file is loaded.
+
+==============================================================================
+14. Cleaning up						*:syn-clear* *E391*
+
+If you want to clear the syntax stuff for the current buffer, you can use this
+command: >
+  :syntax clear
+
+This command should be used when you want to switch off syntax highlighting,
+or when you want to switch to using another syntax.  It's normally not needed
+in a syntax file itself, because syntax is cleared by the autocommands that
+load the syntax file.
+The command also deletes the "b:current_syntax" variable, since no syntax is
+loaded after this command.
+
+If you want to disable syntax highlighting for all buffers, you need to remove
+the autocommands that load the syntax files: >
+  :syntax off
+
+What this command actually does, is executing the command >
+  :source $VIMRUNTIME/syntax/nosyntax.vim
+See the "nosyntax.vim" file for details.  Note that for this to work
+$VIMRUNTIME must be valid.  See |$VIMRUNTIME|.
+
+To clean up specific syntax groups for the current buffer: >
+  :syntax clear {group-name} ..
+This removes all patterns and keywords for {group-name}.
+
+To clean up specific syntax group lists for the current buffer: >
+  :syntax clear @{grouplist-name} ..
+This sets {grouplist-name}'s contents to an empty list.
+
+						*:syntax-reset* *:syn-reset*
+If you have changed the colors and messed them up, use this command to get the
+defaults back: >
+
+  :syntax reset
+
+This doesn't change the colors for the 'highlight' option.
+
+Note that the syntax colors that you set in your vimrc file will also be reset
+back to their Vim default.
+Note that if you are using a color scheme, the colors defined by the color
+scheme for syntax highlighting will be lost.
+
+What this actually does is: >
+
+	let g:syntax_cmd = "reset"
+	runtime! syntax/syncolor.vim
+
+Note that this uses the 'runtimepath' option.
+
+							*syncolor*
+If you want to use different colors for syntax highlighting, you can add a Vim
+script file to set these colors.  Put this file in a directory in
+'runtimepath' which comes after $VIMRUNTIME, so that your settings overrule
+the default colors.  This way these colors will be used after the ":syntax
+reset" command.
+
+For Unix you can use the file ~/.vim/after/syntax/syncolor.vim.  Example: >
+
+	if &background == "light"
+	  highlight comment ctermfg=darkgreen guifg=darkgreen
+	else
+	  highlight comment ctermfg=green guifg=green
+	endif
+
+								*E679*
+Do make sure this syncolor.vim script does not use a "syntax on", set the
+'background' option or uses a "colorscheme" command, because it results in an
+endless loop.
+
+Note that when a color scheme is used, there might be some confusion whether
+your defined colors are to be used or the colors from the scheme.  This
+depends on the color scheme file.  See |:colorscheme|.
+
+							*syntax_cmd*
+The "syntax_cmd" variable is set to one of these values when the
+syntax/syncolor.vim files are loaded:
+   "on"		":syntax on" command.  Highlight colors are overruled but
+		links are kept
+   "enable"	":syntax enable" command.  Only define colors for groups that
+		don't have highlighting yet.  Use ":syntax default".
+   "reset"	":syntax reset" command or loading a color scheme.  Define all
+		the colors.
+   "skip"	Don't define colors.  Used to skip the default settings when a
+		syncolor.vim file earlier in 'runtimepath' has already set
+		them.
+
+==============================================================================
+15. Highlighting tags					*tag-highlight*
+
+If you want to highlight all the tags in your file, you can use the following
+mappings.
+
+	<F11>	-- Generate tags.vim file, and highlight tags.
+	<F12>	-- Just highlight tags based on existing tags.vim file.
+>
+  :map <F11>  :sp tags<CR>:%s/^\([^	:]*:\)\=\([^	]*\).*/syntax keyword Tag \2/<CR>:wq! tags.vim<CR>/^<CR><F12>
+  :map <F12>  :so tags.vim<CR>
+
+WARNING: The longer the tags file, the slower this will be, and the more
+memory Vim will consume.
+
+Only highlighting typedefs, unions and structs can be done too.  For this you
+must use Exuberant ctags (found at http://ctags.sf.net).
+
+Put these lines in your Makefile:
+
+# Make a highlight file for types.  Requires Exuberant ctags and awk
+types: types.vim
+types.vim: *.[ch]
+	ctags --c-kinds=gstu -o- *.[ch] |\
+		awk 'BEGIN{printf("syntax keyword Type\t")}\
+			{printf("%s ", $$1)}END{print ""}' > $@
+
+And put these lines in your .vimrc: >
+
+   " load the types.vim highlighting file, if it exists
+   autocmd BufRead,BufNewFile *.[ch] let fname = expand('<afile>:p:h') . '/types.vim'
+   autocmd BufRead,BufNewFile *.[ch] if filereadable(fname)
+   autocmd BufRead,BufNewFile *.[ch]   exe 'so ' . fname
+   autocmd BufRead,BufNewFile *.[ch] endif
+
+==============================================================================
+16. Color xterms				*xterm-color* *color-xterm*
+
+Most color xterms have only eight colors.  If you don't get colors with the
+default setup, it should work with these lines in your .vimrc: >
+   :if &term =~ "xterm"
+   :  if has("terminfo")
+   :	set t_Co=8
+   :	set t_Sf=<Esc>[3%p1%dm
+   :	set t_Sb=<Esc>[4%p1%dm
+   :  else
+   :	set t_Co=8
+   :	set t_Sf=<Esc>[3%dm
+   :	set t_Sb=<Esc>[4%dm
+   :  endif
+   :endif
+<	[<Esc> is a real escape, type CTRL-V <Esc>]
+
+You might want to change the first "if" to match the name of your terminal,
+e.g. "dtterm" instead of "xterm".
+
+Note: Do these settings BEFORE doing ":syntax on".  Otherwise the colors may
+be wrong.
+							*xiterm* *rxvt*
+The above settings have been mentioned to work for xiterm and rxvt too.
+But for using 16 colors in an rxvt these should work with terminfo: >
+	:set t_AB=<Esc>[%?%p1%{8}%<%t25;%p1%{40}%+%e5;%p1%{32}%+%;%dm
+	:set t_AF=<Esc>[%?%p1%{8}%<%t22;%p1%{30}%+%e1;%p1%{22}%+%;%dm
+<
+							*colortest.vim*
+To test your color setup, a file has been included in the Vim distribution.
+To use it, execute this command: >
+   :runtime syntax/colortest.vim
+
+Some versions of xterm (and other terminals, like the Linux console) can
+output lighter foreground colors, even though the number of colors is defined
+at 8.  Therefore Vim sets the "cterm=bold" attribute for light foreground
+colors, when 't_Co' is 8.
+
+							*xfree-xterm*
+To get 16 colors or more, get the newest xterm version (which should be
+included with XFree86 3.3 and later).  You can also find the latest version
+at: >
+	http://invisible-island.net/xterm/xterm.html
+Here is a good way to configure it.  This uses 88 colors and enables the
+termcap-query feature, which allows Vim to ask the xterm how many colors it
+supports. >
+	./configure --disable-bold-color --enable-88-color --enable-tcap-query
+If you only get 8 colors, check the xterm compilation settings.
+(Also see |UTF8-xterm| for using this xterm with UTF-8 character encoding).
+
+This xterm should work with these lines in your .vimrc (for 16 colors): >
+   :if has("terminfo")
+   :  set t_Co=16
+   :  set t_AB=<Esc>[%?%p1%{8}%<%t%p1%{40}%+%e%p1%{92}%+%;%dm
+   :  set t_AF=<Esc>[%?%p1%{8}%<%t%p1%{30}%+%e%p1%{82}%+%;%dm
+   :else
+   :  set t_Co=16
+   :  set t_Sf=<Esc>[3%dm
+   :  set t_Sb=<Esc>[4%dm
+   :endif
+<	[<Esc> is a real escape, type CTRL-V <Esc>]
+
+Without |+terminfo|, Vim will recognize these settings, and automatically
+translate cterm colors of 8 and above to "<Esc>[9%dm" and "<Esc>[10%dm".
+Colors above 16 are also translated automatically.
+
+For 256 colors this has been reported to work: >
+
+   :set t_AB=<Esc>[48;5;%dm
+   :set t_AF=<Esc>[38;5;%dm
+
+Or just set the TERM environment variable to "xterm-color" or "xterm-16color"
+and try if that works.
+
+You probably want to use these X resources (in your ~/.Xdefaults file):
+	XTerm*color0:			#000000
+	XTerm*color1:			#c00000
+	XTerm*color2:			#008000
+	XTerm*color3:			#808000
+	XTerm*color4:			#0000c0
+	XTerm*color5:			#c000c0
+	XTerm*color6:			#008080
+	XTerm*color7:			#c0c0c0
+	XTerm*color8:			#808080
+	XTerm*color9:			#ff6060
+	XTerm*color10:			#00ff00
+	XTerm*color11:			#ffff00
+	XTerm*color12:			#8080ff
+	XTerm*color13:			#ff40ff
+	XTerm*color14:			#00ffff
+	XTerm*color15:			#ffffff
+	Xterm*cursorColor:		Black
+
+[Note: The cursorColor is required to work around a bug, which changes the
+cursor color to the color of the last drawn text.  This has been fixed by a
+newer version of xterm, but not everybody is using it yet.]
+
+To get these right away, reload the .Xdefaults file to the X Option database
+Manager (you only need to do this when you just changed the .Xdefaults file): >
+  xrdb -merge ~/.Xdefaults
+<
+					*xterm-blink* *xterm-blinking-cursor*
+To make the cursor blink in an xterm, see tools/blink.c.  Or use Thomas
+Dickey's xterm above patchlevel 107 (see above for where to get it), with
+these resources:
+	XTerm*cursorBlink:	on
+	XTerm*cursorOnTime:	400
+	XTerm*cursorOffTime:	250
+	XTerm*cursorColor:	White
+
+							*hpterm-color*
+These settings work (more or less) for an hpterm, which only supports 8
+foreground colors: >
+   :if has("terminfo")
+   :  set t_Co=8
+   :  set t_Sf=<Esc>[&v%p1%dS
+   :  set t_Sb=<Esc>[&v7S
+   :else
+   :  set t_Co=8
+   :  set t_Sf=<Esc>[&v%dS
+   :  set t_Sb=<Esc>[&v7S
+   :endif
+<	[<Esc> is a real escape, type CTRL-V <Esc>]
+
+						*Eterm* *enlightened-terminal*
+These settings have been reported to work for the Enlightened terminal
+emulator, or Eterm.  They might work for all xterm-like terminals that use the
+bold attribute to get bright colors.  Add an ":if" like above when needed. >
+       :set t_Co=16
+       :set t_AF=^[[%?%p1%{8}%<%t3%p1%d%e%p1%{22}%+%d;1%;m
+       :set t_AB=^[[%?%p1%{8}%<%t4%p1%d%e%p1%{32}%+%d;1%;m
+<
+						*TTpro-telnet*
+These settings should work for TTpro telnet.  Tera Term Pro is a freeware /
+open-source program for MS-Windows. >
+	set t_Co=16
+	set t_AB=^[[%?%p1%{8}%<%t%p1%{40}%+%e%p1%{32}%+5;%;%dm
+	set t_AF=^[[%?%p1%{8}%<%t%p1%{30}%+%e%p1%{22}%+1;%;%dm
+Also make sure TTpro's Setup / Window / Full Color is enabled, and make sure
+that Setup / Font / Enable Bold is NOT enabled.
+(info provided by John Love-Jensen <eljay@Adobe.COM>)
+
+ vim:tw=78:sw=4:ts=8:ft=help:norl:
--- /dev/null
+++ b/lib/vimfiles/doc/tabpage.txt
@@ -1,0 +1,378 @@
+*tabpage.txt*   For Vim version 7.1.  Last change: 2007 Mar 11
+
+
+		  VIM REFERENCE MANUAL    by Bram Moolenaar
+
+
+Editing with windows in multiple tab pages.		*tab-page* *tabpage*
+
+The commands which have been added to use multiple tab pages are explained
+here.  Additionally, there are explanations for commands that work differently
+when used in combination with more than one tab page.
+
+1. Introduction			|tab-page-intro|
+2. Commands			|tab-page-commands|
+3. Other items			|tab-page-other|
+4. Setting 'tabline'		|setting-tabline|
+5. Setting 'guitablabel'	|setting-guitablabel|
+
+{Vi does not have any of these commands}
+{not able to use multiple tab pages when the |+windows| feature was disabled
+at compile time}
+
+==============================================================================
+1. Introduction						*tab-page-intro*
+
+A tab page holds one or more windows.  You can easily switch between tab
+pages, so that you have several collections of windows to work on different
+things.
+
+Usually you will see a list of labels at the top of the Vim window, one for
+each tab page.  With the mouse you can click on the label to jump to that tab
+page.  There are other ways to move between tab pages, see below.
+
+Most commands work only in the current tab page.  That includes the |CTRL-W|
+commands, |:windo|, |:all| and |:ball| (when not using the |:tab| modifier).
+The commands that are aware of other tab pages than the current one are
+mentioned below.
+
+Tabs are also a nice way to edit a buffer temporarily without changing the
+current window layout.  Open a new tab page, do whatever you want to do and
+close the tab page.
+
+==============================================================================
+2. Commands						*tab-page-commands*
+
+OPENING A NEW TAB PAGE:
+
+When starting Vim "vim -p filename ..." opens each file argument in a separate
+tab page (up to 'tabpagemax'). |-p|
+
+A double click with the mouse in the non-GUI tab pages line opens a new, empty
+tab page.  It is placed left of the position of the click.  The first click
+may select another tab page first, causing an extra screen update.
+
+This also works in a few GUI versions, esp. Win32 and Motif.  But only when
+clicking right of the labels.
+
+In the GUI tab pages line you can use the right mouse button to open menu.
+|tabline-menu|.
+
+:tabe[dit]				*:tabe* *:tabedit* *:tabnew*
+:tabnew		Open a new tab page with an empty window, after the current
+		tab page.
+
+:tabe[dit] [++opt] [+cmd] {file}
+:tabnew [++opt] [+cmd] {file}
+		Open a new tab page and edit {file}, like with |:edit|.
+
+:tabf[ind] [++opt] [+cmd] {file}			*:tabf* *:tabfind*
+		Open a new tab page and edit {file} in 'path', like with
+		|:find|.
+		{not available when the |+file_in_path| feature was disabled
+		at compile time}
+
+:[count]tab {cmd}					*:tab*
+		Execute {cmd} and when it opens a new window open a new tab
+		page instead.  Doesn't work for |:diffsplit|, |:diffpatch|,
+		|:execute| and |:normal|.
+		When [count] is omitted the tab page appears after the current
+		one.  When [count] is specified the new tab page comes after
+		tab page [count].  Use ":0tab cmd" to get the new tab page as
+		the first one.  Examples: >
+			:tab split	" opens current buffer in new tab page
+			:tab help gt	" opens tab page with help for "gt"
+
+CTRL-W gf	Open a new tab page and edit the file name under the cursor.
+		See |CTRL-W_gf|.
+
+CTRL-W gF	Open a new tab page and edit the file name under the cursor
+		and jump to the line number following the file name.
+		See |CTRL-W_gF|.
+
+CLOSING A TAB PAGE:
+
+Closing the last window of a tab page closes the tab page too, unless there is
+only one tab page.
+
+Using the mouse: If the tab page line is displayed you can click in the "X" at
+the top right to close the current tab page.  A custom |'tabline'| may show
+something else.
+
+							*:tabc* *:tabclose*
+:tabc[lose][!]	Close current tab page.
+		This command fails when:
+		- There is only one tab page on the screen.		*E784*
+		- When 'hidden' is not set, [!] is not used, a buffer has
+		  changes, and there is no other window on this buffer.
+		Changes to the buffer are not written and won't get lost, so
+		this is a "safe" command.
+
+:tabc[lose][!] {count}
+		Close tab page {count}.  Fails in the same way as ':tabclose"
+		above.
+
+							*:tabo* *:tabonly*
+:tabo[nly][!]	Close all other tab pages.
+		When the 'hidden' option is set, all buffers in closed windows
+		become hidden.
+		When 'hidden' is not set, and the 'autowrite' option is set,
+		modified buffers are written.  Otherwise, windows that have
+		buffers that are modified are not removed, unless the [!] is
+		given, then they become hidden.  But modified buffers are
+		never abandoned, so changes cannot get lost.
+
+
+SWITCHING TO ANOTHER TAB PAGE:
+
+Using the mouse: If the tab page line is displayed you can click in a tab page
+label to switch to that tab page.  Click where there is no label to go to the
+next tab page.  |'tabline'|
+
+:tabn[ext]				*:tabn* *:tabnext* *gt*
+<C-PageDown>				*CTRL-<PageDown>* *<C-PageDown>*
+gt					*i_CTRL-<PageDown>* *i_<C-PageDown>*
+		Go to the next tab page.  Wraps around from the last to the
+		first one.
+
+:tabn[ext] {count}
+{count}<C-PageDown>
+{count}gt	Go to tab page {count}.  The first tab page has number one.
+
+
+:tabp[revious]				*:tabp* *:tabprevious* *gT* *:tabN*
+:tabN[ext]				*:tabNext* *CTRL-<PageUp>*
+<C-PageUp>			 *<C-PageUp>* *i_CTRL-<PageUp>* *i_<C-PageUp>*
+gT		Go to the previous tab page.  Wraps around from the first one
+		to the last one.
+
+:tabp[revious] {count}
+:tabN[ext] {count}
+{count}<C-PageUp>
+{count}gT	Go {count} tab pages back.  Wraps around from the first one
+		to the last one.
+
+:tabr[ewind]			*:tabfir* *:tabfirst* *:tabr* *:tabrewind*
+:tabfir[st]	Go to the first tab page.
+
+							*:tabl* *:tablast*
+:tabl[ast]	Go to the last tab page.
+
+
+Other commands:
+							*:tabs*
+:tabs		List the tab pages and the windows they contain.
+		Shows a ">" for the current window.
+		Shows a "+" for modified buffers.
+
+
+REORDERING TAB PAGES:
+
+:tabm[ove] [N]						*:tabm* *:tabmove*
+		Move the current tab page to after tab page N.  Use zero to
+		make the current tab page the first one.  Without N the tab
+		page is made the last one.
+
+
+LOOPING OVER TAB PAGES:
+
+							*:tabd* *:tabdo*
+:tabd[o] {cmd}	Execute {cmd} in each tab page.
+		It works like doing this: >
+			:tabfirst
+			:{cmd}
+			:tabnext
+			:{cmd}
+			etc.
+<		This only operates in the current window of each tab page.
+		When an error is detected on one tab page, further tab pages
+		will not be visited.
+		The last tab page (or where an error occurred) becomes the
+		current tab page.
+		{cmd} can contain '|' to concatenate several commands.
+		{cmd} must not open or close tab pages or reorder them.
+		{not in Vi} {not available when compiled without the
+		|+listcmds| feature}
+		Also see |:windo|, |:argdo| and |:bufdo|.
+
+==============================================================================
+3. Other items						*tab-page-other*
+
+							*tabline-menu*
+The GUI tab pages line has a popup menu.  It is accessed with a right click.
+The entries are:
+	Close		Close the tab page under the mouse pointer.  The
+			current one if there is no label under the mouse
+			pointer.
+	New Tab		Open a tab page, editing an empty buffer.  It appears
+			to the left of the mouse pointer.
+	Open Tab...	Like "New Tab" and additionally use a file selector to
+			select a file to edit.
+
+Diff mode works per tab page.  You can see the diffs between several files
+within one tab page.  Other tab pages can show differences between other
+files.
+
+Variables local to a tab page start with "t:". |tabpage-variable|
+
+Currently there is only one option local to a tab page: 'cmdheight'.
+
+The TabLeave and TabEnter autocommand events can be used to do something when
+switching from one tab page to another.  The exact order depends on what you
+are doing.  When creating a new tab page this works as if you create a new
+window on the same buffer and then edit another buffer.  Thus ":tabnew"
+triggers:
+	WinLeave		leave current window
+	TabLeave		leave current tab page
+	TabEnter		enter new tab page
+	WinEnter		enter window in new tab page
+	BufLeave		leave current buffer
+	BufEnter		enter new empty buffer
+
+When switching to another tab page the order is:
+	BufLeave
+	WinLeave
+	TabLeave
+	TabEnter
+	WinEnter
+	BufEnter
+
+==============================================================================
+4. Setting 'tabline'					*setting-tabline*
+
+The 'tabline' option specifies what the line with tab pages labels looks like.
+It is only used when there is no GUI tab line.
+
+You can use the 'showtabline' option to specify when you want the line with
+tab page labels to appear: never, when there is more than one tab page or
+always.
+
+The highlighting of the tab pages line is set with the groups TabLine
+TabLineSel and TabLineFill.  |hl-TabLine| |hl-TabLineSel| |hl-TabLineFill|
+
+A "+" will be shown for a tab page that has a modified window.  The number of
+windows in a tabpage is also shown.  Thus "3+" means three windows and one of
+them has a modified buffer.
+
+The 'tabline' option allows you to define your preferred way to tab pages
+labels.  This isn't easy, thus an example will be given here.
+
+For basics see the 'statusline' option.  The same items can be used in the
+'tabline' option.  Additionally, the |tabpagebuflist()|, |tabpagenr()| and
+|tabpagewinnr()| functions are useful.
+
+Since the number of tab labels will vary, you need to use an expression for
+the whole option.  Something like: >
+	:set tabline=%!MyTabLine()
+
+Then define the MyTabLine() function to list all the tab pages labels.  A
+convenient method is to split it in two parts:  First go over all the tab
+pages and define labels for them.  Then get the label for each tab page. >
+
+	function MyTabLine()
+	  let s = ''
+	  for i in range(tabpagenr('$'))
+	    " select the highlighting
+	    if i + 1 == tabpagenr()
+	      let s .= '%#TabLineSel#'
+	    else
+	      let s .= '%#TabLine#'
+	    endif
+
+	    " set the tab page number (for mouse clicks)
+	    let s .= '%' . (i + 1) . 'T'
+
+	    " the label is made by MyTabLabel()
+	    let s .= ' %{MyTabLabel(' . (i + 1) . ')} '
+	  endfor
+
+	  " after the last tab fill with TabLineFill and reset tab page nr
+	  let s .= '%#TabLineFill#%T'
+
+	  " right-align the label to close the current tab page
+	  if tabpagenr('$') > 1
+	    let s .= '%=%#TabLine#%999Xclose'
+	  endif
+
+	  return s
+	endfunction
+
+Now the MyTabLabel() function is called for each tab page to get its label. >
+
+	function MyTabLabel(n)
+	  let buflist = tabpagebuflist(a:n)
+	  let winnr = tabpagewinnr(a:n)
+	  return bufname(buflist[winnr - 1])
+	endfunction
+
+This is just a simplistic example that results in a tab pages line that
+resembles the default, but without adding a + for a modified buffer or
+truncating the names.  You will want to reduce the width of labels in a
+clever way when there is not enough room.  Check the 'columns' option for the
+space available.
+
+==============================================================================
+5. Setting 'guitablabel'				*setting-guitablabel*
+
+When the GUI tab pages line is displayed, 'guitablabel' can be used to
+specify the label to display for each tab page.  Unlike 'tabline', which
+specifies the whole tab pages line at once, 'guitablabel' is used for each
+label separately.
+
+'guitabtooltip' is very similar and is used for the tooltip of the same label.
+This only appears when the mouse pointer hovers over the label, thus it
+usually is longer.  Only supported on some systems though.
+
+See the 'statusline' option for the format of the value.
+
+The "%N" item can be used for the current tab page number.  The |v:lnum|
+variable is also set to this number when the option is evaluated.
+The items that use a file name refer to the current window of the tab page.
+
+Note that syntax highlighting is not used for the option.  The %T and %X
+items are also ignored.
+
+A simple example that puts the tab page number and the buffer name in the
+label: >
+	:set guitablabel=%N\ %f
+
+An example that resembles the default 'guitablabel': Show the number of
+windows in the tab page and a '+' if there is a modified buffer: >
+
+	function GuiTabLabel()
+	  let label = ''
+	  let bufnrlist = tabpagebuflist(v:lnum)
+
+	  " Add '+' if one of the buffers in the tab page is modified
+	  for bufnr in bufnrlist
+	    if getbufvar(bufnr, "&modified")
+	      let label = '+'
+	      break
+	    endif
+	  endfor
+
+	  " Append the number of windows in the tab page if more than one
+	  let wincount = tabpagewinnr(v:lnum, '$')
+	  if wincount > 1
+	    let label .= wincount
+	  endif
+	  if label != ''
+	    let label .= ' '
+	  endif
+
+	  " Append the buffer name
+	  return label . bufname(bufnrlist[tabpagewinnr(v:lnum) - 1])
+	endfunction
+
+	set guitablabel=%{GuiTabLabel()}
+
+Note that the function must be defined before setting the option, otherwise
+you get an error message for the function not being known.
+
+If you want to fall back to the default label, return an empty string.
+
+If you want to show something specific for a tab page, you might want to use a
+tab page local variable. |t:var|
+
+
+ vim:tw=78:ts=8:ft=help:norl:
--- /dev/null
+++ b/lib/vimfiles/doc/tags
@@ -1,0 +1,8112 @@
+!	change.txt	/*!*
+!!	change.txt	/*!!*
+#	pattern.txt	/*#*
+$	motion.txt	/*$*
+$HOME	options.txt	/*$HOME*
+$HOME-use	version5.txt	/*$HOME-use*
+$VIM	starting.txt	/*$VIM*
+$VIM-use	version5.txt	/*$VIM-use*
+$VIMRUNTIME	starting.txt	/*$VIMRUNTIME*
+%	motion.txt	/*%*
+&	change.txt	/*&*
+'	motion.txt	/*'*
+''	motion.txt	/*''*
+'(	motion.txt	/*'(*
+')	motion.txt	/*')*
+'.	motion.txt	/*'.*
+'0	motion.txt	/*'0*
+'<	motion.txt	/*'<*
+'>	motion.txt	/*'>*
+'A	motion.txt	/*'A*
+'[	motion.txt	/*'[*
+']	motion.txt	/*']*
+'^	motion.txt	/*'^*
+'a	motion.txt	/*'a*
+'acd'	options.txt	/*'acd'*
+'ai'	options.txt	/*'ai'*
+'akm'	options.txt	/*'akm'*
+'al'	options.txt	/*'al'*
+'aleph'	options.txt	/*'aleph'*
+'allowrevins'	options.txt	/*'allowrevins'*
+'altkeymap'	options.txt	/*'altkeymap'*
+'ambiwidth'	options.txt	/*'ambiwidth'*
+'ambw'	options.txt	/*'ambw'*
+'anti'	options.txt	/*'anti'*
+'antialias'	options.txt	/*'antialias'*
+'ap'	vi_diff.txt	/*'ap'*
+'ar'	options.txt	/*'ar'*
+'arab'	options.txt	/*'arab'*
+'arabic'	options.txt	/*'arabic'*
+'arabicshape'	options.txt	/*'arabicshape'*
+'ari'	options.txt	/*'ari'*
+'arshape'	options.txt	/*'arshape'*
+'as'	todo.txt	/*'as'*
+'autochdir'	options.txt	/*'autochdir'*
+'autoindent'	options.txt	/*'autoindent'*
+'autoprint'	vi_diff.txt	/*'autoprint'*
+'autoread'	options.txt	/*'autoread'*
+'autosave'	todo.txt	/*'autosave'*
+'autowrite'	options.txt	/*'autowrite'*
+'autowriteall'	options.txt	/*'autowriteall'*
+'aw'	options.txt	/*'aw'*
+'awa'	options.txt	/*'awa'*
+'background'	options.txt	/*'background'*
+'backspace'	options.txt	/*'backspace'*
+'backup'	options.txt	/*'backup'*
+'backupcopy'	options.txt	/*'backupcopy'*
+'backupdir'	options.txt	/*'backupdir'*
+'backupext'	options.txt	/*'backupext'*
+'backupskip'	options.txt	/*'backupskip'*
+'balloondelay'	options.txt	/*'balloondelay'*
+'ballooneval'	options.txt	/*'ballooneval'*
+'balloonexpr'	options.txt	/*'balloonexpr'*
+'bdir'	options.txt	/*'bdir'*
+'bdlay'	options.txt	/*'bdlay'*
+'beautify'	vi_diff.txt	/*'beautify'*
+'beval'	options.txt	/*'beval'*
+'bex'	options.txt	/*'bex'*
+'bexpr'	options.txt	/*'bexpr'*
+'bf'	vi_diff.txt	/*'bf'*
+'bg'	options.txt	/*'bg'*
+'bh'	options.txt	/*'bh'*
+'bin'	options.txt	/*'bin'*
+'binary'	options.txt	/*'binary'*
+'biosk'	options.txt	/*'biosk'*
+'bioskey'	options.txt	/*'bioskey'*
+'bk'	options.txt	/*'bk'*
+'bkc'	options.txt	/*'bkc'*
+'bl'	options.txt	/*'bl'*
+'bomb'	options.txt	/*'bomb'*
+'breakat'	options.txt	/*'breakat'*
+'brk'	options.txt	/*'brk'*
+'browsedir'	options.txt	/*'browsedir'*
+'bs'	options.txt	/*'bs'*
+'bsdir'	options.txt	/*'bsdir'*
+'bsk'	options.txt	/*'bsk'*
+'bt'	options.txt	/*'bt'*
+'bufhidden'	options.txt	/*'bufhidden'*
+'buflisted'	options.txt	/*'buflisted'*
+'buftype'	options.txt	/*'buftype'*
+'casemap'	options.txt	/*'casemap'*
+'cb'	options.txt	/*'cb'*
+'ccv'	options.txt	/*'ccv'*
+'cd'	options.txt	/*'cd'*
+'cdpath'	options.txt	/*'cdpath'*
+'cedit'	options.txt	/*'cedit'*
+'cf'	options.txt	/*'cf'*
+'cfu'	options.txt	/*'cfu'*
+'ch'	options.txt	/*'ch'*
+'character'	intro.txt	/*'character'*
+'charconvert'	options.txt	/*'charconvert'*
+'ci'	options.txt	/*'ci'*
+'cin'	options.txt	/*'cin'*
+'cindent'	options.txt	/*'cindent'*
+'cink'	options.txt	/*'cink'*
+'cinkeys'	options.txt	/*'cinkeys'*
+'cino'	options.txt	/*'cino'*
+'cinoptions'	options.txt	/*'cinoptions'*
+'cinw'	options.txt	/*'cinw'*
+'cinwords'	options.txt	/*'cinwords'*
+'clipboard'	options.txt	/*'clipboard'*
+'cmdheight'	options.txt	/*'cmdheight'*
+'cmdwinheight'	options.txt	/*'cmdwinheight'*
+'cmp'	options.txt	/*'cmp'*
+'cms'	options.txt	/*'cms'*
+'co'	options.txt	/*'co'*
+'columns'	options.txt	/*'columns'*
+'com'	options.txt	/*'com'*
+'comments'	options.txt	/*'comments'*
+'commentstring'	options.txt	/*'commentstring'*
+'compatible'	options.txt	/*'compatible'*
+'complete'	options.txt	/*'complete'*
+'completefunc'	options.txt	/*'completefunc'*
+'completeopt'	options.txt	/*'completeopt'*
+'confirm'	options.txt	/*'confirm'*
+'consk'	options.txt	/*'consk'*
+'conskey'	options.txt	/*'conskey'*
+'copyindent'	options.txt	/*'copyindent'*
+'cot'	options.txt	/*'cot'*
+'cp'	options.txt	/*'cp'*
+'cpo'	options.txt	/*'cpo'*
+'cpoptions'	options.txt	/*'cpoptions'*
+'cpt'	options.txt	/*'cpt'*
+'cscopepathcomp'	options.txt	/*'cscopepathcomp'*
+'cscopeprg'	options.txt	/*'cscopeprg'*
+'cscopequickfix'	options.txt	/*'cscopequickfix'*
+'cscopetag'	options.txt	/*'cscopetag'*
+'cscopetagorder'	options.txt	/*'cscopetagorder'*
+'cscopeverbose'	options.txt	/*'cscopeverbose'*
+'cspc'	options.txt	/*'cspc'*
+'csprg'	options.txt	/*'csprg'*
+'csqf'	options.txt	/*'csqf'*
+'cst'	options.txt	/*'cst'*
+'csto'	options.txt	/*'csto'*
+'csverb'	options.txt	/*'csverb'*
+'cuc'	options.txt	/*'cuc'*
+'cul'	options.txt	/*'cul'*
+'cursorcolumn'	options.txt	/*'cursorcolumn'*
+'cursorline'	options.txt	/*'cursorline'*
+'cwh'	options.txt	/*'cwh'*
+'debug'	options.txt	/*'debug'*
+'deco'	options.txt	/*'deco'*
+'def'	options.txt	/*'def'*
+'define'	options.txt	/*'define'*
+'delcombine'	options.txt	/*'delcombine'*
+'dex'	options.txt	/*'dex'*
+'dg'	options.txt	/*'dg'*
+'dict'	options.txt	/*'dict'*
+'dictionary'	options.txt	/*'dictionary'*
+'diff'	options.txt	/*'diff'*
+'diffexpr'	options.txt	/*'diffexpr'*
+'diffopt'	options.txt	/*'diffopt'*
+'digraph'	options.txt	/*'digraph'*
+'dip'	options.txt	/*'dip'*
+'dir'	options.txt	/*'dir'*
+'directory'	options.txt	/*'directory'*
+'display'	options.txt	/*'display'*
+'dy'	options.txt	/*'dy'*
+'ea'	options.txt	/*'ea'*
+'ead'	options.txt	/*'ead'*
+'eadirection'	options.txt	/*'eadirection'*
+'eb'	options.txt	/*'eb'*
+'ed'	options.txt	/*'ed'*
+'edcompatible'	options.txt	/*'edcompatible'*
+'ef'	options.txt	/*'ef'*
+'efm'	options.txt	/*'efm'*
+'ei'	options.txt	/*'ei'*
+'ek'	options.txt	/*'ek'*
+'enc'	options.txt	/*'enc'*
+'encoding'	options.txt	/*'encoding'*
+'endofline'	options.txt	/*'endofline'*
+'eol'	options.txt	/*'eol'*
+'ep'	options.txt	/*'ep'*
+'equalalways'	options.txt	/*'equalalways'*
+'equalprg'	options.txt	/*'equalprg'*
+'errorbells'	options.txt	/*'errorbells'*
+'errorfile'	options.txt	/*'errorfile'*
+'errorformat'	options.txt	/*'errorformat'*
+'esckeys'	options.txt	/*'esckeys'*
+'et'	options.txt	/*'et'*
+'eventignore'	options.txt	/*'eventignore'*
+'ex'	options.txt	/*'ex'*
+'expandtab'	options.txt	/*'expandtab'*
+'exrc'	options.txt	/*'exrc'*
+'fcl'	options.txt	/*'fcl'*
+'fcs'	options.txt	/*'fcs'*
+'fdc'	options.txt	/*'fdc'*
+'fde'	options.txt	/*'fde'*
+'fdi'	options.txt	/*'fdi'*
+'fdl'	options.txt	/*'fdl'*
+'fdls'	options.txt	/*'fdls'*
+'fdm'	options.txt	/*'fdm'*
+'fdn'	options.txt	/*'fdn'*
+'fdo'	options.txt	/*'fdo'*
+'fdt'	options.txt	/*'fdt'*
+'fe'	options.txt	/*'fe'*
+'fen'	options.txt	/*'fen'*
+'fenc'	options.txt	/*'fenc'*
+'fencs'	options.txt	/*'fencs'*
+'fex'	options.txt	/*'fex'*
+'ff'	options.txt	/*'ff'*
+'ffs'	options.txt	/*'ffs'*
+'fileencoding'	options.txt	/*'fileencoding'*
+'fileencodings'	options.txt	/*'fileencodings'*
+'fileformat'	options.txt	/*'fileformat'*
+'fileformats'	options.txt	/*'fileformats'*
+'filetype'	options.txt	/*'filetype'*
+'fillchars'	options.txt	/*'fillchars'*
+'fk'	options.txt	/*'fk'*
+'fkmap'	options.txt	/*'fkmap'*
+'fl'	vi_diff.txt	/*'fl'*
+'flash'	vi_diff.txt	/*'flash'*
+'flp'	options.txt	/*'flp'*
+'fml'	options.txt	/*'fml'*
+'fmr'	options.txt	/*'fmr'*
+'fo'	options.txt	/*'fo'*
+'foldclose'	options.txt	/*'foldclose'*
+'foldcolumn'	options.txt	/*'foldcolumn'*
+'foldenable'	options.txt	/*'foldenable'*
+'foldexpr'	options.txt	/*'foldexpr'*
+'foldignore'	options.txt	/*'foldignore'*
+'foldlevel'	options.txt	/*'foldlevel'*
+'foldlevelstart'	options.txt	/*'foldlevelstart'*
+'foldmarker'	options.txt	/*'foldmarker'*
+'foldmethod'	options.txt	/*'foldmethod'*
+'foldminlines'	options.txt	/*'foldminlines'*
+'foldnestmax'	options.txt	/*'foldnestmax'*
+'foldopen'	options.txt	/*'foldopen'*
+'foldtext'	options.txt	/*'foldtext'*
+'formatexpr'	options.txt	/*'formatexpr'*
+'formatlistpat'	options.txt	/*'formatlistpat'*
+'formatoptions'	options.txt	/*'formatoptions'*
+'formatprg'	options.txt	/*'formatprg'*
+'fp'	options.txt	/*'fp'*
+'fs'	options.txt	/*'fs'*
+'fsync'	options.txt	/*'fsync'*
+'ft'	options.txt	/*'ft'*
+'gcr'	options.txt	/*'gcr'*
+'gd'	options.txt	/*'gd'*
+'gdefault'	options.txt	/*'gdefault'*
+'gfm'	options.txt	/*'gfm'*
+'gfn'	options.txt	/*'gfn'*
+'gfs'	options.txt	/*'gfs'*
+'gfw'	options.txt	/*'gfw'*
+'ghr'	options.txt	/*'ghr'*
+'go'	options.txt	/*'go'*
+'go-A'	options.txt	/*'go-A'*
+'go-F'	options.txt	/*'go-F'*
+'go-L'	options.txt	/*'go-L'*
+'go-M'	options.txt	/*'go-M'*
+'go-R'	options.txt	/*'go-R'*
+'go-T'	options.txt	/*'go-T'*
+'go-a'	options.txt	/*'go-a'*
+'go-b'	options.txt	/*'go-b'*
+'go-c'	options.txt	/*'go-c'*
+'go-e'	options.txt	/*'go-e'*
+'go-f'	options.txt	/*'go-f'*
+'go-g'	options.txt	/*'go-g'*
+'go-h'	options.txt	/*'go-h'*
+'go-i'	options.txt	/*'go-i'*
+'go-l'	options.txt	/*'go-l'*
+'go-m'	options.txt	/*'go-m'*
+'go-p'	options.txt	/*'go-p'*
+'go-r'	options.txt	/*'go-r'*
+'go-t'	options.txt	/*'go-t'*
+'go-v'	options.txt	/*'go-v'*
+'gp'	options.txt	/*'gp'*
+'gr'	vi_diff.txt	/*'gr'*
+'graphic'	vi_diff.txt	/*'graphic'*
+'grepformat'	options.txt	/*'grepformat'*
+'grepprg'	options.txt	/*'grepprg'*
+'gtl'	options.txt	/*'gtl'*
+'gtt'	options.txt	/*'gtt'*
+'guicursor'	options.txt	/*'guicursor'*
+'guifont'	options.txt	/*'guifont'*
+'guifontset'	options.txt	/*'guifontset'*
+'guifontwide'	options.txt	/*'guifontwide'*
+'guiheadroom'	options.txt	/*'guiheadroom'*
+'guioptions'	options.txt	/*'guioptions'*
+'guipty'	options.txt	/*'guipty'*
+'guitablabel'	options.txt	/*'guitablabel'*
+'guitabtooltip'	options.txt	/*'guitabtooltip'*
+'hardtabs'	vi_diff.txt	/*'hardtabs'*
+'helpfile'	options.txt	/*'helpfile'*
+'helpheight'	options.txt	/*'helpheight'*
+'helplang'	options.txt	/*'helplang'*
+'hf'	options.txt	/*'hf'*
+'hh'	options.txt	/*'hh'*
+'hi'	options.txt	/*'hi'*
+'hid'	options.txt	/*'hid'*
+'hidden'	options.txt	/*'hidden'*
+'highlight'	options.txt	/*'highlight'*
+'history'	options.txt	/*'history'*
+'hk'	options.txt	/*'hk'*
+'hkmap'	options.txt	/*'hkmap'*
+'hkmapp'	options.txt	/*'hkmapp'*
+'hkp'	options.txt	/*'hkp'*
+'hl'	options.txt	/*'hl'*
+'hlg'	options.txt	/*'hlg'*
+'hls'	options.txt	/*'hls'*
+'hlsearch'	options.txt	/*'hlsearch'*
+'ht'	vi_diff.txt	/*'ht'*
+'ic'	options.txt	/*'ic'*
+'icon'	options.txt	/*'icon'*
+'iconstring'	options.txt	/*'iconstring'*
+'ignorecase'	options.txt	/*'ignorecase'*
+'im'	options.txt	/*'im'*
+'imactivatekey'	options.txt	/*'imactivatekey'*
+'imak'	options.txt	/*'imak'*
+'imc'	options.txt	/*'imc'*
+'imcmdline'	options.txt	/*'imcmdline'*
+'imd'	options.txt	/*'imd'*
+'imdisable'	options.txt	/*'imdisable'*
+'imi'	options.txt	/*'imi'*
+'iminsert'	options.txt	/*'iminsert'*
+'ims'	options.txt	/*'ims'*
+'imsearch'	options.txt	/*'imsearch'*
+'inc'	options.txt	/*'inc'*
+'include'	options.txt	/*'include'*
+'includeexpr'	options.txt	/*'includeexpr'*
+'incsearch'	options.txt	/*'incsearch'*
+'inde'	options.txt	/*'inde'*
+'indentexpr'	options.txt	/*'indentexpr'*
+'indentkeys'	options.txt	/*'indentkeys'*
+'indk'	options.txt	/*'indk'*
+'inex'	options.txt	/*'inex'*
+'inf'	options.txt	/*'inf'*
+'infercase'	options.txt	/*'infercase'*
+'insertmode'	options.txt	/*'insertmode'*
+'is'	options.txt	/*'is'*
+'isf'	options.txt	/*'isf'*
+'isfname'	options.txt	/*'isfname'*
+'isi'	options.txt	/*'isi'*
+'isident'	options.txt	/*'isident'*
+'isk'	options.txt	/*'isk'*
+'iskeyword'	options.txt	/*'iskeyword'*
+'isp'	options.txt	/*'isp'*
+'isprint'	options.txt	/*'isprint'*
+'joinspaces'	options.txt	/*'joinspaces'*
+'js'	options.txt	/*'js'*
+'key'	options.txt	/*'key'*
+'keymap'	options.txt	/*'keymap'*
+'keymodel'	options.txt	/*'keymodel'*
+'keywordprg'	options.txt	/*'keywordprg'*
+'km'	options.txt	/*'km'*
+'kmp'	options.txt	/*'kmp'*
+'kp'	options.txt	/*'kp'*
+'langmap'	options.txt	/*'langmap'*
+'langmenu'	options.txt	/*'langmenu'*
+'laststatus'	options.txt	/*'laststatus'*
+'lazyredraw'	options.txt	/*'lazyredraw'*
+'lbr'	options.txt	/*'lbr'*
+'lcs'	options.txt	/*'lcs'*
+'linebreak'	options.txt	/*'linebreak'*
+'lines'	options.txt	/*'lines'*
+'linespace'	options.txt	/*'linespace'*
+'lisp'	options.txt	/*'lisp'*
+'lispwords'	options.txt	/*'lispwords'*
+'list'	options.txt	/*'list'*
+'listchars'	options.txt	/*'listchars'*
+'lm'	options.txt	/*'lm'*
+'lmap'	options.txt	/*'lmap'*
+'loadplugins'	options.txt	/*'loadplugins'*
+'lpl'	options.txt	/*'lpl'*
+'ls'	options.txt	/*'ls'*
+'lsp'	options.txt	/*'lsp'*
+'lw'	options.txt	/*'lw'*
+'lz'	options.txt	/*'lz'*
+'ma'	options.txt	/*'ma'*
+'macatsui'	options.txt	/*'macatsui'*
+'magic'	options.txt	/*'magic'*
+'makeef'	options.txt	/*'makeef'*
+'makeprg'	options.txt	/*'makeprg'*
+'mat'	options.txt	/*'mat'*
+'matchpairs'	options.txt	/*'matchpairs'*
+'matchtime'	options.txt	/*'matchtime'*
+'maxcombine'	options.txt	/*'maxcombine'*
+'maxfuncdepth'	options.txt	/*'maxfuncdepth'*
+'maxmapdepth'	options.txt	/*'maxmapdepth'*
+'maxmem'	options.txt	/*'maxmem'*
+'maxmempattern'	options.txt	/*'maxmempattern'*
+'maxmemtot'	options.txt	/*'maxmemtot'*
+'mco'	options.txt	/*'mco'*
+'mef'	options.txt	/*'mef'*
+'menuitems'	options.txt	/*'menuitems'*
+'mesg'	vi_diff.txt	/*'mesg'*
+'mfd'	options.txt	/*'mfd'*
+'mh'	options.txt	/*'mh'*
+'mis'	options.txt	/*'mis'*
+'mkspellmem'	options.txt	/*'mkspellmem'*
+'ml'	options.txt	/*'ml'*
+'mls'	options.txt	/*'mls'*
+'mm'	options.txt	/*'mm'*
+'mmd'	options.txt	/*'mmd'*
+'mmp'	options.txt	/*'mmp'*
+'mmt'	options.txt	/*'mmt'*
+'mod'	options.txt	/*'mod'*
+'modeline'	options.txt	/*'modeline'*
+'modelines'	options.txt	/*'modelines'*
+'modifiable'	options.txt	/*'modifiable'*
+'modified'	options.txt	/*'modified'*
+'more'	options.txt	/*'more'*
+'mouse'	options.txt	/*'mouse'*
+'mousef'	options.txt	/*'mousef'*
+'mousefocus'	options.txt	/*'mousefocus'*
+'mousehide'	options.txt	/*'mousehide'*
+'mousem'	options.txt	/*'mousem'*
+'mousemodel'	options.txt	/*'mousemodel'*
+'mouses'	options.txt	/*'mouses'*
+'mouseshape'	options.txt	/*'mouseshape'*
+'mouset'	options.txt	/*'mouset'*
+'mousetime'	options.txt	/*'mousetime'*
+'mp'	options.txt	/*'mp'*
+'mps'	options.txt	/*'mps'*
+'msm'	options.txt	/*'msm'*
+'mzq'	options.txt	/*'mzq'*
+'mzquantum'	options.txt	/*'mzquantum'*
+'nf'	options.txt	/*'nf'*
+'noacd'	options.txt	/*'noacd'*
+'noai'	options.txt	/*'noai'*
+'noakm'	options.txt	/*'noakm'*
+'noallowrevins'	options.txt	/*'noallowrevins'*
+'noaltkeymap'	options.txt	/*'noaltkeymap'*
+'noanti'	options.txt	/*'noanti'*
+'noantialias'	options.txt	/*'noantialias'*
+'noar'	options.txt	/*'noar'*
+'noarab'	options.txt	/*'noarab'*
+'noarabic'	options.txt	/*'noarabic'*
+'noarabicshape'	options.txt	/*'noarabicshape'*
+'noari'	options.txt	/*'noari'*
+'noarshape'	options.txt	/*'noarshape'*
+'noas'	todo.txt	/*'noas'*
+'noautochdir'	options.txt	/*'noautochdir'*
+'noautoindent'	options.txt	/*'noautoindent'*
+'noautoread'	options.txt	/*'noautoread'*
+'noautosave'	todo.txt	/*'noautosave'*
+'noautowrite'	options.txt	/*'noautowrite'*
+'noautowriteall'	options.txt	/*'noautowriteall'*
+'noaw'	options.txt	/*'noaw'*
+'noawa'	options.txt	/*'noawa'*
+'nobackup'	options.txt	/*'nobackup'*
+'noballooneval'	options.txt	/*'noballooneval'*
+'nobeval'	options.txt	/*'nobeval'*
+'nobin'	options.txt	/*'nobin'*
+'nobinary'	options.txt	/*'nobinary'*
+'nobiosk'	options.txt	/*'nobiosk'*
+'nobioskey'	options.txt	/*'nobioskey'*
+'nobk'	options.txt	/*'nobk'*
+'nobl'	options.txt	/*'nobl'*
+'nobomb'	options.txt	/*'nobomb'*
+'nobuflisted'	options.txt	/*'nobuflisted'*
+'nocf'	options.txt	/*'nocf'*
+'noci'	options.txt	/*'noci'*
+'nocin'	options.txt	/*'nocin'*
+'nocindent'	options.txt	/*'nocindent'*
+'nocompatible'	options.txt	/*'nocompatible'*
+'noconfirm'	options.txt	/*'noconfirm'*
+'noconsk'	options.txt	/*'noconsk'*
+'noconskey'	options.txt	/*'noconskey'*
+'nocopyindent'	options.txt	/*'nocopyindent'*
+'nocp'	options.txt	/*'nocp'*
+'nocscopetag'	options.txt	/*'nocscopetag'*
+'nocscopeverbose'	options.txt	/*'nocscopeverbose'*
+'nocst'	options.txt	/*'nocst'*
+'nocsverb'	options.txt	/*'nocsverb'*
+'nocuc'	options.txt	/*'nocuc'*
+'nocul'	options.txt	/*'nocul'*
+'nocursorcolumn'	options.txt	/*'nocursorcolumn'*
+'nocursorline'	options.txt	/*'nocursorline'*
+'nodeco'	options.txt	/*'nodeco'*
+'nodelcombine'	options.txt	/*'nodelcombine'*
+'nodg'	options.txt	/*'nodg'*
+'nodiff'	options.txt	/*'nodiff'*
+'nodigraph'	options.txt	/*'nodigraph'*
+'nodisable'	options.txt	/*'nodisable'*
+'noea'	options.txt	/*'noea'*
+'noeb'	options.txt	/*'noeb'*
+'noed'	options.txt	/*'noed'*
+'noedcompatible'	options.txt	/*'noedcompatible'*
+'noek'	options.txt	/*'noek'*
+'noendofline'	options.txt	/*'noendofline'*
+'noeol'	options.txt	/*'noeol'*
+'noequalalways'	options.txt	/*'noequalalways'*
+'noerrorbells'	options.txt	/*'noerrorbells'*
+'noesckeys'	options.txt	/*'noesckeys'*
+'noet'	options.txt	/*'noet'*
+'noex'	options.txt	/*'noex'*
+'noexpandtab'	options.txt	/*'noexpandtab'*
+'noexrc'	options.txt	/*'noexrc'*
+'nofen'	options.txt	/*'nofen'*
+'nofk'	options.txt	/*'nofk'*
+'nofkmap'	options.txt	/*'nofkmap'*
+'nofoldenable'	options.txt	/*'nofoldenable'*
+'nogd'	options.txt	/*'nogd'*
+'nogdefault'	options.txt	/*'nogdefault'*
+'noguipty'	options.txt	/*'noguipty'*
+'nohid'	options.txt	/*'nohid'*
+'nohidden'	options.txt	/*'nohidden'*
+'nohk'	options.txt	/*'nohk'*
+'nohkmap'	options.txt	/*'nohkmap'*
+'nohkmapp'	options.txt	/*'nohkmapp'*
+'nohkp'	options.txt	/*'nohkp'*
+'nohls'	options.txt	/*'nohls'*
+'nohlsearch'	options.txt	/*'nohlsearch'*
+'noic'	options.txt	/*'noic'*
+'noicon'	options.txt	/*'noicon'*
+'noignorecase'	options.txt	/*'noignorecase'*
+'noim'	options.txt	/*'noim'*
+'noimc'	options.txt	/*'noimc'*
+'noimcmdline'	options.txt	/*'noimcmdline'*
+'noimd'	options.txt	/*'noimd'*
+'noincsearch'	options.txt	/*'noincsearch'*
+'noinf'	options.txt	/*'noinf'*
+'noinfercase'	options.txt	/*'noinfercase'*
+'noinsertmode'	options.txt	/*'noinsertmode'*
+'nois'	options.txt	/*'nois'*
+'nojoinspaces'	options.txt	/*'nojoinspaces'*
+'nojs'	options.txt	/*'nojs'*
+'nolazyredraw'	options.txt	/*'nolazyredraw'*
+'nolbr'	options.txt	/*'nolbr'*
+'nolinebreak'	options.txt	/*'nolinebreak'*
+'nolisp'	options.txt	/*'nolisp'*
+'nolist'	options.txt	/*'nolist'*
+'noloadplugins'	options.txt	/*'noloadplugins'*
+'nolpl'	options.txt	/*'nolpl'*
+'nolz'	options.txt	/*'nolz'*
+'noma'	options.txt	/*'noma'*
+'nomacatsui'	options.txt	/*'nomacatsui'*
+'nomagic'	options.txt	/*'nomagic'*
+'nomh'	options.txt	/*'nomh'*
+'noml'	options.txt	/*'noml'*
+'nomod'	options.txt	/*'nomod'*
+'nomodeline'	options.txt	/*'nomodeline'*
+'nomodifiable'	options.txt	/*'nomodifiable'*
+'nomodified'	options.txt	/*'nomodified'*
+'nomore'	options.txt	/*'nomore'*
+'nomousef'	options.txt	/*'nomousef'*
+'nomousefocus'	options.txt	/*'nomousefocus'*
+'nomousehide'	options.txt	/*'nomousehide'*
+'nonu'	options.txt	/*'nonu'*
+'nonumber'	options.txt	/*'nonumber'*
+'noodev'	options.txt	/*'noodev'*
+'noopendevice'	options.txt	/*'noopendevice'*
+'nopaste'	options.txt	/*'nopaste'*
+'nopi'	options.txt	/*'nopi'*
+'nopreserveindent'	options.txt	/*'nopreserveindent'*
+'nopreviewwindow'	options.txt	/*'nopreviewwindow'*
+'noprompt'	options.txt	/*'noprompt'*
+'nopvw'	options.txt	/*'nopvw'*
+'noreadonly'	options.txt	/*'noreadonly'*
+'noremap'	options.txt	/*'noremap'*
+'norestorescreen'	options.txt	/*'norestorescreen'*
+'norevins'	options.txt	/*'norevins'*
+'nori'	options.txt	/*'nori'*
+'norightleft'	options.txt	/*'norightleft'*
+'norightleftcmd'	options.txt	/*'norightleftcmd'*
+'norl'	options.txt	/*'norl'*
+'norlc'	options.txt	/*'norlc'*
+'noro'	options.txt	/*'noro'*
+'nors'	options.txt	/*'nors'*
+'noru'	options.txt	/*'noru'*
+'noruler'	options.txt	/*'noruler'*
+'nosb'	options.txt	/*'nosb'*
+'nosc'	options.txt	/*'nosc'*
+'noscb'	options.txt	/*'noscb'*
+'noscrollbind'	options.txt	/*'noscrollbind'*
+'noscs'	options.txt	/*'noscs'*
+'nosecure'	options.txt	/*'nosecure'*
+'nosft'	options.txt	/*'nosft'*
+'noshellslash'	options.txt	/*'noshellslash'*
+'noshelltemp'	options.txt	/*'noshelltemp'*
+'noshiftround'	options.txt	/*'noshiftround'*
+'noshortname'	options.txt	/*'noshortname'*
+'noshowcmd'	options.txt	/*'noshowcmd'*
+'noshowfulltag'	options.txt	/*'noshowfulltag'*
+'noshowmatch'	options.txt	/*'noshowmatch'*
+'noshowmode'	options.txt	/*'noshowmode'*
+'nosi'	options.txt	/*'nosi'*
+'nosm'	options.txt	/*'nosm'*
+'nosmartcase'	options.txt	/*'nosmartcase'*
+'nosmartindent'	options.txt	/*'nosmartindent'*
+'nosmarttab'	options.txt	/*'nosmarttab'*
+'nosmd'	options.txt	/*'nosmd'*
+'nosn'	options.txt	/*'nosn'*
+'nosol'	options.txt	/*'nosol'*
+'nospell'	options.txt	/*'nospell'*
+'nosplitbelow'	options.txt	/*'nosplitbelow'*
+'nosplitright'	options.txt	/*'nosplitright'*
+'nospr'	options.txt	/*'nospr'*
+'nosr'	options.txt	/*'nosr'*
+'nossl'	options.txt	/*'nossl'*
+'nosta'	options.txt	/*'nosta'*
+'nostartofline'	options.txt	/*'nostartofline'*
+'nostmp'	options.txt	/*'nostmp'*
+'noswapfile'	options.txt	/*'noswapfile'*
+'noswf'	options.txt	/*'noswf'*
+'nota'	options.txt	/*'nota'*
+'notagbsearch'	options.txt	/*'notagbsearch'*
+'notagrelative'	options.txt	/*'notagrelative'*
+'notagstack'	options.txt	/*'notagstack'*
+'notbi'	options.txt	/*'notbi'*
+'notbidi'	options.txt	/*'notbidi'*
+'notbs'	options.txt	/*'notbs'*
+'notermbidi'	options.txt	/*'notermbidi'*
+'noterse'	options.txt	/*'noterse'*
+'notextauto'	options.txt	/*'notextauto'*
+'notextmode'	options.txt	/*'notextmode'*
+'notf'	options.txt	/*'notf'*
+'notgst'	options.txt	/*'notgst'*
+'notildeop'	options.txt	/*'notildeop'*
+'notimeout'	options.txt	/*'notimeout'*
+'notitle'	options.txt	/*'notitle'*
+'noto'	options.txt	/*'noto'*
+'notop'	options.txt	/*'notop'*
+'notr'	options.txt	/*'notr'*
+'nottimeout'	options.txt	/*'nottimeout'*
+'nottybuiltin'	options.txt	/*'nottybuiltin'*
+'nottyfast'	options.txt	/*'nottyfast'*
+'notx'	options.txt	/*'notx'*
+'novb'	options.txt	/*'novb'*
+'novice'	vi_diff.txt	/*'novice'*
+'novisualbell'	options.txt	/*'novisualbell'*
+'nowa'	options.txt	/*'nowa'*
+'nowarn'	options.txt	/*'nowarn'*
+'nowb'	options.txt	/*'nowb'*
+'noweirdinvert'	options.txt	/*'noweirdinvert'*
+'nowfh'	options.txt	/*'nowfh'*
+'nowfw'	options.txt	/*'nowfw'*
+'nowildmenu'	options.txt	/*'nowildmenu'*
+'nowinfixheight'	options.txt	/*'nowinfixheight'*
+'nowinfixwidth'	options.txt	/*'nowinfixwidth'*
+'nowiv'	options.txt	/*'nowiv'*
+'nowmnu'	options.txt	/*'nowmnu'*
+'nowrap'	options.txt	/*'nowrap'*
+'nowrapscan'	options.txt	/*'nowrapscan'*
+'nowrite'	options.txt	/*'nowrite'*
+'nowriteany'	options.txt	/*'nowriteany'*
+'nowritebackup'	options.txt	/*'nowritebackup'*
+'nows'	options.txt	/*'nows'*
+'nrformats'	options.txt	/*'nrformats'*
+'nu'	options.txt	/*'nu'*
+'number'	options.txt	/*'number'*
+'numberwidth'	options.txt	/*'numberwidth'*
+'nuw'	options.txt	/*'nuw'*
+'odev'	options.txt	/*'odev'*
+'oft'	options.txt	/*'oft'*
+'ofu'	options.txt	/*'ofu'*
+'omnifunc'	options.txt	/*'omnifunc'*
+'op'	vi_diff.txt	/*'op'*
+'open'	vi_diff.txt	/*'open'*
+'opendevice'	options.txt	/*'opendevice'*
+'operatorfunc'	options.txt	/*'operatorfunc'*
+'opfunc'	options.txt	/*'opfunc'*
+'optimize'	vi_diff.txt	/*'optimize'*
+'option'	intro.txt	/*'option'*
+'osfiletype'	options.txt	/*'osfiletype'*
+'pa'	options.txt	/*'pa'*
+'para'	options.txt	/*'para'*
+'paragraphs'	options.txt	/*'paragraphs'*
+'paste'	options.txt	/*'paste'*
+'pastetoggle'	options.txt	/*'pastetoggle'*
+'patchexpr'	options.txt	/*'patchexpr'*
+'patchmode'	options.txt	/*'patchmode'*
+'path'	options.txt	/*'path'*
+'pdev'	options.txt	/*'pdev'*
+'penc'	options.txt	/*'penc'*
+'pex'	options.txt	/*'pex'*
+'pexpr'	options.txt	/*'pexpr'*
+'pfn'	options.txt	/*'pfn'*
+'ph'	options.txt	/*'ph'*
+'pheader'	options.txt	/*'pheader'*
+'pi'	options.txt	/*'pi'*
+'pm'	options.txt	/*'pm'*
+'pmbcs'	options.txt	/*'pmbcs'*
+'pmbfn'	options.txt	/*'pmbfn'*
+'popt'	options.txt	/*'popt'*
+'preserveindent'	options.txt	/*'preserveindent'*
+'previewheight'	options.txt	/*'previewheight'*
+'previewwindow'	options.txt	/*'previewwindow'*
+'printdevice'	options.txt	/*'printdevice'*
+'printencoding'	options.txt	/*'printencoding'*
+'printexpr'	options.txt	/*'printexpr'*
+'printfont'	options.txt	/*'printfont'*
+'printheader'	options.txt	/*'printheader'*
+'printmbcharset'	options.txt	/*'printmbcharset'*
+'printmbfont'	options.txt	/*'printmbfont'*
+'printoptions'	options.txt	/*'printoptions'*
+'prompt'	options.txt	/*'prompt'*
+'pt'	options.txt	/*'pt'*
+'pumheight'	options.txt	/*'pumheight'*
+'pvh'	options.txt	/*'pvh'*
+'pvw'	options.txt	/*'pvw'*
+'qe'	options.txt	/*'qe'*
+'quote	motion.txt	/*'quote*
+'quoteescape'	options.txt	/*'quoteescape'*
+'readonly'	options.txt	/*'readonly'*
+'redraw'	vi_diff.txt	/*'redraw'*
+'remap'	options.txt	/*'remap'*
+'report'	options.txt	/*'report'*
+'restorescreen'	options.txt	/*'restorescreen'*
+'revins'	options.txt	/*'revins'*
+'ri'	options.txt	/*'ri'*
+'rightleft'	options.txt	/*'rightleft'*
+'rightleftcmd'	options.txt	/*'rightleftcmd'*
+'rl'	options.txt	/*'rl'*
+'rlc'	options.txt	/*'rlc'*
+'ro'	options.txt	/*'ro'*
+'rs'	options.txt	/*'rs'*
+'rtp'	options.txt	/*'rtp'*
+'ru'	options.txt	/*'ru'*
+'ruf'	options.txt	/*'ruf'*
+'ruler'	options.txt	/*'ruler'*
+'rulerformat'	options.txt	/*'rulerformat'*
+'runtimepath'	options.txt	/*'runtimepath'*
+'sb'	options.txt	/*'sb'*
+'sbo'	options.txt	/*'sbo'*
+'sbr'	options.txt	/*'sbr'*
+'sc'	options.txt	/*'sc'*
+'scb'	options.txt	/*'scb'*
+'scr'	options.txt	/*'scr'*
+'scroll'	options.txt	/*'scroll'*
+'scrollbind'	options.txt	/*'scrollbind'*
+'scrolljump'	options.txt	/*'scrolljump'*
+'scrolloff'	options.txt	/*'scrolloff'*
+'scrollopt'	options.txt	/*'scrollopt'*
+'scs'	options.txt	/*'scs'*
+'sect'	options.txt	/*'sect'*
+'sections'	options.txt	/*'sections'*
+'secure'	options.txt	/*'secure'*
+'sel'	options.txt	/*'sel'*
+'selection'	options.txt	/*'selection'*
+'selectmode'	options.txt	/*'selectmode'*
+'sessionoptions'	options.txt	/*'sessionoptions'*
+'sft'	options.txt	/*'sft'*
+'sh'	options.txt	/*'sh'*
+'shcf'	options.txt	/*'shcf'*
+'shell'	options.txt	/*'shell'*
+'shellcmdflag'	options.txt	/*'shellcmdflag'*
+'shellpipe'	options.txt	/*'shellpipe'*
+'shellquote'	options.txt	/*'shellquote'*
+'shellredir'	options.txt	/*'shellredir'*
+'shellslash'	options.txt	/*'shellslash'*
+'shelltemp'	options.txt	/*'shelltemp'*
+'shelltype'	options.txt	/*'shelltype'*
+'shellxquote'	options.txt	/*'shellxquote'*
+'shiftround'	options.txt	/*'shiftround'*
+'shiftwidth'	options.txt	/*'shiftwidth'*
+'shm'	options.txt	/*'shm'*
+'shortmess'	options.txt	/*'shortmess'*
+'shortname'	options.txt	/*'shortname'*
+'showbreak'	options.txt	/*'showbreak'*
+'showcmd'	options.txt	/*'showcmd'*
+'showfulltag'	options.txt	/*'showfulltag'*
+'showmatch'	options.txt	/*'showmatch'*
+'showmode'	options.txt	/*'showmode'*
+'showtabline'	options.txt	/*'showtabline'*
+'shq'	options.txt	/*'shq'*
+'si'	options.txt	/*'si'*
+'sidescroll'	options.txt	/*'sidescroll'*
+'sidescrolloff'	options.txt	/*'sidescrolloff'*
+'siso'	options.txt	/*'siso'*
+'sj'	options.txt	/*'sj'*
+'slm'	options.txt	/*'slm'*
+'slow'	vi_diff.txt	/*'slow'*
+'slowopen'	vi_diff.txt	/*'slowopen'*
+'sm'	options.txt	/*'sm'*
+'smartcase'	options.txt	/*'smartcase'*
+'smartindent'	options.txt	/*'smartindent'*
+'smarttab'	options.txt	/*'smarttab'*
+'smc'	options.txt	/*'smc'*
+'smd'	options.txt	/*'smd'*
+'sn'	options.txt	/*'sn'*
+'so'	options.txt	/*'so'*
+'softtabstop'	options.txt	/*'softtabstop'*
+'sol'	options.txt	/*'sol'*
+'sourceany'	vi_diff.txt	/*'sourceany'*
+'sp'	options.txt	/*'sp'*
+'spc'	options.txt	/*'spc'*
+'spell'	options.txt	/*'spell'*
+'spellcapcheck'	options.txt	/*'spellcapcheck'*
+'spellfile'	options.txt	/*'spellfile'*
+'spelllang'	options.txt	/*'spelllang'*
+'spellsuggest'	options.txt	/*'spellsuggest'*
+'spf'	options.txt	/*'spf'*
+'spl'	options.txt	/*'spl'*
+'splitbelow'	options.txt	/*'splitbelow'*
+'splitright'	options.txt	/*'splitright'*
+'spr'	options.txt	/*'spr'*
+'sps'	options.txt	/*'sps'*
+'sr'	options.txt	/*'sr'*
+'srr'	options.txt	/*'srr'*
+'ss'	options.txt	/*'ss'*
+'ssl'	options.txt	/*'ssl'*
+'ssop'	options.txt	/*'ssop'*
+'st'	options.txt	/*'st'*
+'sta'	options.txt	/*'sta'*
+'stal'	options.txt	/*'stal'*
+'startofline'	options.txt	/*'startofline'*
+'statusline'	options.txt	/*'statusline'*
+'stl'	options.txt	/*'stl'*
+'stmp'	options.txt	/*'stmp'*
+'sts'	options.txt	/*'sts'*
+'su'	options.txt	/*'su'*
+'sua'	options.txt	/*'sua'*
+'suffixes'	options.txt	/*'suffixes'*
+'suffixesadd'	options.txt	/*'suffixesadd'*
+'sw'	options.txt	/*'sw'*
+'swapfile'	options.txt	/*'swapfile'*
+'swapsync'	options.txt	/*'swapsync'*
+'swb'	options.txt	/*'swb'*
+'swf'	options.txt	/*'swf'*
+'switchbuf'	options.txt	/*'switchbuf'*
+'sws'	options.txt	/*'sws'*
+'sxq'	options.txt	/*'sxq'*
+'syn'	options.txt	/*'syn'*
+'synmaxcol'	options.txt	/*'synmaxcol'*
+'syntax'	options.txt	/*'syntax'*
+'t_#2'	term.txt	/*'t_#2'*
+'t_#4'	term.txt	/*'t_#4'*
+'t_%1'	term.txt	/*'t_%1'*
+'t_%i'	term.txt	/*'t_%i'*
+'t_&8'	term.txt	/*'t_&8'*
+'t_@7'	term.txt	/*'t_@7'*
+'t_AB'	term.txt	/*'t_AB'*
+'t_AF'	term.txt	/*'t_AF'*
+'t_AL'	term.txt	/*'t_AL'*
+'t_CS'	term.txt	/*'t_CS'*
+'t_CV'	term.txt	/*'t_CV'*
+'t_Ce'	term.txt	/*'t_Ce'*
+'t_Co'	term.txt	/*'t_Co'*
+'t_Cs'	term.txt	/*'t_Cs'*
+'t_DL'	term.txt	/*'t_DL'*
+'t_EI'	term.txt	/*'t_EI'*
+'t_F1'	term.txt	/*'t_F1'*
+'t_F2'	term.txt	/*'t_F2'*
+'t_F3'	term.txt	/*'t_F3'*
+'t_F4'	term.txt	/*'t_F4'*
+'t_F5'	term.txt	/*'t_F5'*
+'t_F6'	term.txt	/*'t_F6'*
+'t_F7'	term.txt	/*'t_F7'*
+'t_F8'	term.txt	/*'t_F8'*
+'t_F9'	term.txt	/*'t_F9'*
+'t_IE'	term.txt	/*'t_IE'*
+'t_IS'	term.txt	/*'t_IS'*
+'t_K1'	term.txt	/*'t_K1'*
+'t_K3'	term.txt	/*'t_K3'*
+'t_K4'	term.txt	/*'t_K4'*
+'t_K5'	term.txt	/*'t_K5'*
+'t_K6'	term.txt	/*'t_K6'*
+'t_K7'	term.txt	/*'t_K7'*
+'t_K8'	term.txt	/*'t_K8'*
+'t_K9'	term.txt	/*'t_K9'*
+'t_KA'	term.txt	/*'t_KA'*
+'t_KB'	term.txt	/*'t_KB'*
+'t_KC'	term.txt	/*'t_KC'*
+'t_KD'	term.txt	/*'t_KD'*
+'t_KE'	term.txt	/*'t_KE'*
+'t_KF'	term.txt	/*'t_KF'*
+'t_KG'	term.txt	/*'t_KG'*
+'t_KH'	term.txt	/*'t_KH'*
+'t_KI'	term.txt	/*'t_KI'*
+'t_KJ'	term.txt	/*'t_KJ'*
+'t_KK'	term.txt	/*'t_KK'*
+'t_KL'	term.txt	/*'t_KL'*
+'t_RI'	term.txt	/*'t_RI'*
+'t_RV'	term.txt	/*'t_RV'*
+'t_SI'	term.txt	/*'t_SI'*
+'t_Sb'	term.txt	/*'t_Sb'*
+'t_Sf'	term.txt	/*'t_Sf'*
+'t_WP'	term.txt	/*'t_WP'*
+'t_WS'	term.txt	/*'t_WS'*
+'t_ZH'	term.txt	/*'t_ZH'*
+'t_ZR'	term.txt	/*'t_ZR'*
+'t_al'	term.txt	/*'t_al'*
+'t_bc'	term.txt	/*'t_bc'*
+'t_cd'	term.txt	/*'t_cd'*
+'t_ce'	term.txt	/*'t_ce'*
+'t_cl'	term.txt	/*'t_cl'*
+'t_cm'	term.txt	/*'t_cm'*
+'t_cs'	term.txt	/*'t_cs'*
+'t_da'	term.txt	/*'t_da'*
+'t_db'	term.txt	/*'t_db'*
+'t_dl'	term.txt	/*'t_dl'*
+'t_fs'	term.txt	/*'t_fs'*
+'t_k1'	term.txt	/*'t_k1'*
+'t_k2'	term.txt	/*'t_k2'*
+'t_k3'	term.txt	/*'t_k3'*
+'t_k4'	term.txt	/*'t_k4'*
+'t_k5'	term.txt	/*'t_k5'*
+'t_k6'	term.txt	/*'t_k6'*
+'t_k7'	term.txt	/*'t_k7'*
+'t_k8'	term.txt	/*'t_k8'*
+'t_k9'	term.txt	/*'t_k9'*
+'t_k;'	term.txt	/*'t_k;'*
+'t_kB'	term.txt	/*'t_kB'*
+'t_kD'	term.txt	/*'t_kD'*
+'t_kI'	term.txt	/*'t_kI'*
+'t_kN'	term.txt	/*'t_kN'*
+'t_kP'	term.txt	/*'t_kP'*
+'t_kb'	term.txt	/*'t_kb'*
+'t_kd'	term.txt	/*'t_kd'*
+'t_ke'	term.txt	/*'t_ke'*
+'t_kh'	term.txt	/*'t_kh'*
+'t_kl'	term.txt	/*'t_kl'*
+'t_kr'	term.txt	/*'t_kr'*
+'t_ks'	term.txt	/*'t_ks'*
+'t_ku'	term.txt	/*'t_ku'*
+'t_le'	term.txt	/*'t_le'*
+'t_mb'	term.txt	/*'t_mb'*
+'t_md'	term.txt	/*'t_md'*
+'t_me'	term.txt	/*'t_me'*
+'t_mr'	term.txt	/*'t_mr'*
+'t_ms'	term.txt	/*'t_ms'*
+'t_nd'	term.txt	/*'t_nd'*
+'t_op'	term.txt	/*'t_op'*
+'t_se'	term.txt	/*'t_se'*
+'t_so'	term.txt	/*'t_so'*
+'t_sr'	term.txt	/*'t_sr'*
+'t_star7'	term.txt	/*'t_star7'*
+'t_te'	term.txt	/*'t_te'*
+'t_ti'	term.txt	/*'t_ti'*
+'t_ts'	term.txt	/*'t_ts'*
+'t_ue'	term.txt	/*'t_ue'*
+'t_us'	term.txt	/*'t_us'*
+'t_ut'	term.txt	/*'t_ut'*
+'t_vb'	term.txt	/*'t_vb'*
+'t_ve'	term.txt	/*'t_ve'*
+'t_vi'	term.txt	/*'t_vi'*
+'t_vs'	term.txt	/*'t_vs'*
+'t_xs'	term.txt	/*'t_xs'*
+'ta'	options.txt	/*'ta'*
+'tabline'	options.txt	/*'tabline'*
+'tabpagemax'	options.txt	/*'tabpagemax'*
+'tabstop'	options.txt	/*'tabstop'*
+'tag'	options.txt	/*'tag'*
+'tagbsearch'	options.txt	/*'tagbsearch'*
+'taglength'	options.txt	/*'taglength'*
+'tagrelative'	options.txt	/*'tagrelative'*
+'tags'	options.txt	/*'tags'*
+'tagstack'	options.txt	/*'tagstack'*
+'tal'	options.txt	/*'tal'*
+'tb'	options.txt	/*'tb'*
+'tbi'	options.txt	/*'tbi'*
+'tbidi'	options.txt	/*'tbidi'*
+'tbis'	options.txt	/*'tbis'*
+'tbs'	options.txt	/*'tbs'*
+'tenc'	options.txt	/*'tenc'*
+'term'	options.txt	/*'term'*
+'termbidi'	options.txt	/*'termbidi'*
+'termencoding'	options.txt	/*'termencoding'*
+'terse'	options.txt	/*'terse'*
+'textauto'	options.txt	/*'textauto'*
+'textmode'	options.txt	/*'textmode'*
+'textwidth'	options.txt	/*'textwidth'*
+'tf'	options.txt	/*'tf'*
+'tgst'	options.txt	/*'tgst'*
+'thesaurus'	options.txt	/*'thesaurus'*
+'tildeop'	options.txt	/*'tildeop'*
+'timeout'	options.txt	/*'timeout'*
+'timeoutlen'	options.txt	/*'timeoutlen'*
+'title'	options.txt	/*'title'*
+'titlelen'	options.txt	/*'titlelen'*
+'titleold'	options.txt	/*'titleold'*
+'titlestring'	options.txt	/*'titlestring'*
+'tl'	options.txt	/*'tl'*
+'tm'	options.txt	/*'tm'*
+'to'	options.txt	/*'to'*
+'toolbar'	options.txt	/*'toolbar'*
+'toolbariconsize'	options.txt	/*'toolbariconsize'*
+'top'	options.txt	/*'top'*
+'tpm'	options.txt	/*'tpm'*
+'tr'	options.txt	/*'tr'*
+'ts'	options.txt	/*'ts'*
+'tsl'	options.txt	/*'tsl'*
+'tsr'	options.txt	/*'tsr'*
+'ttimeout'	options.txt	/*'ttimeout'*
+'ttimeoutlen'	options.txt	/*'ttimeoutlen'*
+'ttm'	options.txt	/*'ttm'*
+'tty'	options.txt	/*'tty'*
+'ttybuiltin'	options.txt	/*'ttybuiltin'*
+'ttyfast'	options.txt	/*'ttyfast'*
+'ttym'	options.txt	/*'ttym'*
+'ttymouse'	options.txt	/*'ttymouse'*
+'ttyscroll'	options.txt	/*'ttyscroll'*
+'ttytype'	options.txt	/*'ttytype'*
+'tw'	options.txt	/*'tw'*
+'tx'	options.txt	/*'tx'*
+'uc'	options.txt	/*'uc'*
+'ul'	options.txt	/*'ul'*
+'undolevels'	options.txt	/*'undolevels'*
+'updatecount'	options.txt	/*'updatecount'*
+'updatetime'	options.txt	/*'updatetime'*
+'ut'	options.txt	/*'ut'*
+'vb'	options.txt	/*'vb'*
+'vbs'	options.txt	/*'vbs'*
+'vdir'	options.txt	/*'vdir'*
+'ve'	options.txt	/*'ve'*
+'verbose'	options.txt	/*'verbose'*
+'verbosefile'	options.txt	/*'verbosefile'*
+'vfile'	options.txt	/*'vfile'*
+'vi'	options.txt	/*'vi'*
+'viewdir'	options.txt	/*'viewdir'*
+'viewoptions'	options.txt	/*'viewoptions'*
+'viminfo'	options.txt	/*'viminfo'*
+'virtualedit'	options.txt	/*'virtualedit'*
+'visualbell'	options.txt	/*'visualbell'*
+'vop'	options.txt	/*'vop'*
+'w1200'	vi_diff.txt	/*'w1200'*
+'w300'	vi_diff.txt	/*'w300'*
+'w9600'	vi_diff.txt	/*'w9600'*
+'wa'	options.txt	/*'wa'*
+'wak'	options.txt	/*'wak'*
+'warn'	options.txt	/*'warn'*
+'wb'	options.txt	/*'wb'*
+'wc'	options.txt	/*'wc'*
+'wcm'	options.txt	/*'wcm'*
+'wd'	options.txt	/*'wd'*
+'weirdinvert'	options.txt	/*'weirdinvert'*
+'wfh'	options.txt	/*'wfh'*
+'wfw'	options.txt	/*'wfw'*
+'wh'	options.txt	/*'wh'*
+'whichwrap'	options.txt	/*'whichwrap'*
+'wi'	options.txt	/*'wi'*
+'wig'	options.txt	/*'wig'*
+'wildchar'	options.txt	/*'wildchar'*
+'wildcharm'	options.txt	/*'wildcharm'*
+'wildignore'	options.txt	/*'wildignore'*
+'wildmenu'	options.txt	/*'wildmenu'*
+'wildmode'	options.txt	/*'wildmode'*
+'wildoptions'	options.txt	/*'wildoptions'*
+'wim'	options.txt	/*'wim'*
+'winaltkeys'	options.txt	/*'winaltkeys'*
+'window'	options.txt	/*'window'*
+'winfixheight'	options.txt	/*'winfixheight'*
+'winfixwidth'	options.txt	/*'winfixwidth'*
+'winheight'	options.txt	/*'winheight'*
+'winminheight'	options.txt	/*'winminheight'*
+'winminwidth'	options.txt	/*'winminwidth'*
+'winwidth'	options.txt	/*'winwidth'*
+'wiv'	options.txt	/*'wiv'*
+'wiw'	options.txt	/*'wiw'*
+'wm'	options.txt	/*'wm'*
+'wmh'	options.txt	/*'wmh'*
+'wmnu'	options.txt	/*'wmnu'*
+'wmw'	options.txt	/*'wmw'*
+'wop'	options.txt	/*'wop'*
+'wrap'	options.txt	/*'wrap'*
+'wrapmargin'	options.txt	/*'wrapmargin'*
+'wrapscan'	options.txt	/*'wrapscan'*
+'write'	options.txt	/*'write'*
+'writeany'	options.txt	/*'writeany'*
+'writebackup'	options.txt	/*'writebackup'*
+'writedelay'	options.txt	/*'writedelay'*
+'ws'	options.txt	/*'ws'*
+'ww'	options.txt	/*'ww'*
+'{	motion.txt	/*'{*
+'}	motion.txt	/*'}*
+(	motion.txt	/*(*
+)	motion.txt	/*)*
++	motion.txt	/*+*
+++bad	editing.txt	/*++bad*
+++bin	editing.txt	/*++bin*
+++builtin_terms	various.txt	/*++builtin_terms*
+++edit	editing.txt	/*++edit*
+++enc	editing.txt	/*++enc*
+++ff	editing.txt	/*++ff*
+++nobin	editing.txt	/*++nobin*
+++opt	editing.txt	/*++opt*
++ARP	various.txt	/*+ARP*
++GUI_Athena	various.txt	/*+GUI_Athena*
++GUI_GTK	various.txt	/*+GUI_GTK*
++GUI_Motif	various.txt	/*+GUI_Motif*
++GUI_Photon	various.txt	/*+GUI_Photon*
++GUI_neXtaw	various.txt	/*+GUI_neXtaw*
++X11	various.txt	/*+X11*
++arabic	various.txt	/*+arabic*
++autocmd	various.txt	/*+autocmd*
++balloon_eval	various.txt	/*+balloon_eval*
++browse	various.txt	/*+browse*
++builtin_terms	various.txt	/*+builtin_terms*
++byte_offset	various.txt	/*+byte_offset*
++cindent	various.txt	/*+cindent*
++clientserver	various.txt	/*+clientserver*
++clipboard	various.txt	/*+clipboard*
++cmd	editing.txt	/*+cmd*
++cmdline_compl	various.txt	/*+cmdline_compl*
++cmdline_hist	various.txt	/*+cmdline_hist*
++cmdline_info	various.txt	/*+cmdline_info*
++comments	various.txt	/*+comments*
++cryptv	various.txt	/*+cryptv*
++cscope	various.txt	/*+cscope*
++cursorshape	various.txt	/*+cursorshape*
++debug	various.txt	/*+debug*
++dialog_con	various.txt	/*+dialog_con*
++dialog_con_gui	various.txt	/*+dialog_con_gui*
++dialog_gui	various.txt	/*+dialog_gui*
++diff	various.txt	/*+diff*
++digraphs	various.txt	/*+digraphs*
++dnd	various.txt	/*+dnd*
++emacs_tags	various.txt	/*+emacs_tags*
++eval	various.txt	/*+eval*
++ex_extra	various.txt	/*+ex_extra*
++extra_search	various.txt	/*+extra_search*
++farsi	various.txt	/*+farsi*
++feature-list	various.txt	/*+feature-list*
++file_in_path	various.txt	/*+file_in_path*
++find_in_path	various.txt	/*+find_in_path*
++folding	various.txt	/*+folding*
++footer	various.txt	/*+footer*
++fork	various.txt	/*+fork*
++gettext	various.txt	/*+gettext*
++hangul_input	various.txt	/*+hangul_input*
++iconv	various.txt	/*+iconv*
++iconv/dyn	various.txt	/*+iconv\/dyn*
++insert_expand	various.txt	/*+insert_expand*
++jumplist	various.txt	/*+jumplist*
++keymap	various.txt	/*+keymap*
++langmap	various.txt	/*+langmap*
++libcall	various.txt	/*+libcall*
++linebreak	various.txt	/*+linebreak*
++lispindent	various.txt	/*+lispindent*
++listcmds	various.txt	/*+listcmds*
++localmap	various.txt	/*+localmap*
++menu	various.txt	/*+menu*
++mksession	various.txt	/*+mksession*
++modify_fname	various.txt	/*+modify_fname*
++mouse	various.txt	/*+mouse*
++mouse_dec	various.txt	/*+mouse_dec*
++mouse_gpm	various.txt	/*+mouse_gpm*
++mouse_netterm	various.txt	/*+mouse_netterm*
++mouse_pterm	various.txt	/*+mouse_pterm*
++mouse_xterm	various.txt	/*+mouse_xterm*
++mouseshape	various.txt	/*+mouseshape*
++multi_byte	various.txt	/*+multi_byte*
++multi_byte_ime	various.txt	/*+multi_byte_ime*
++multi_lang	various.txt	/*+multi_lang*
++mzscheme	various.txt	/*+mzscheme*
++mzscheme/dyn	various.txt	/*+mzscheme\/dyn*
++netbeans_intg	various.txt	/*+netbeans_intg*
++ole	various.txt	/*+ole*
++osfiletype	various.txt	/*+osfiletype*
++path_extra	various.txt	/*+path_extra*
++perl	various.txt	/*+perl*
++perl/dyn	various.txt	/*+perl\/dyn*
++postscript	various.txt	/*+postscript*
++printer	various.txt	/*+printer*
++profile	various.txt	/*+profile*
++python	various.txt	/*+python*
++python/dyn	various.txt	/*+python\/dyn*
++quickfix	various.txt	/*+quickfix*
++reltime	various.txt	/*+reltime*
++rightleft	various.txt	/*+rightleft*
++ruby	various.txt	/*+ruby*
++ruby/dyn	various.txt	/*+ruby\/dyn*
++scrollbind	various.txt	/*+scrollbind*
++signs	various.txt	/*+signs*
++smartindent	various.txt	/*+smartindent*
++sniff	various.txt	/*+sniff*
++statusline	various.txt	/*+statusline*
++sun_workshop	various.txt	/*+sun_workshop*
++syntax	various.txt	/*+syntax*
++system()	various.txt	/*+system()*
++tag_any_white	various.txt	/*+tag_any_white*
++tag_binary	various.txt	/*+tag_binary*
++tag_old_static	various.txt	/*+tag_old_static*
++tcl	various.txt	/*+tcl*
++tcl/dyn	various.txt	/*+tcl\/dyn*
++terminfo	various.txt	/*+terminfo*
++termresponse	various.txt	/*+termresponse*
++textobjects	various.txt	/*+textobjects*
++tgetent	various.txt	/*+tgetent*
++title	various.txt	/*+title*
++toolbar	various.txt	/*+toolbar*
++user_commands	various.txt	/*+user_commands*
++vertsplit	various.txt	/*+vertsplit*
++viminfo	various.txt	/*+viminfo*
++virtualedit	various.txt	/*+virtualedit*
++visual	various.txt	/*+visual*
++visualextra	various.txt	/*+visualextra*
++vreplace	various.txt	/*+vreplace*
++wildignore	various.txt	/*+wildignore*
++wildmenu	various.txt	/*+wildmenu*
++windows	various.txt	/*+windows*
++writebackup	various.txt	/*+writebackup*
++xfontset	various.txt	/*+xfontset*
++xim	various.txt	/*+xim*
++xsmp	various.txt	/*+xsmp*
++xsmp_interact	various.txt	/*+xsmp_interact*
++xterm_clipboard	various.txt	/*+xterm_clipboard*
++xterm_save	various.txt	/*+xterm_save*
+,	motion.txt	/*,*
+-	motion.txt	/*-*
+-+	starting.txt	/*-+*
+-+/	starting.txt	/*-+\/*
+-+c	starting.txt	/*-+c*
+-+reverse	gui_x11.txt	/*-+reverse*
+-+rv	gui_x11.txt	/*-+rv*
+--	starting.txt	/*--*
+---	starting.txt	/*---*
+--cmd	starting.txt	/*--cmd*
+--echo-wid	starting.txt	/*--echo-wid*
+--help	starting.txt	/*--help*
+--literal	starting.txt	/*--literal*
+--nofork	starting.txt	/*--nofork*
+--noplugin	starting.txt	/*--noplugin*
+--remote	remote.txt	/*--remote*
+--remote-expr	remote.txt	/*--remote-expr*
+--remote-send	remote.txt	/*--remote-send*
+--remote-silent	remote.txt	/*--remote-silent*
+--remote-tab	remote.txt	/*--remote-tab*
+--remote-tab-silent	remote.txt	/*--remote-tab-silent*
+--remote-tab-wait	remote.txt	/*--remote-tab-wait*
+--remote-tab-wait-silent	remote.txt	/*--remote-tab-wait-silent*
+--remote-wait	remote.txt	/*--remote-wait*
+--remote-wait-silent	remote.txt	/*--remote-wait-silent*
+--role	starting.txt	/*--role*
+--serverlist	remote.txt	/*--serverlist*
+--servername	remote.txt	/*--servername*
+--socketid	starting.txt	/*--socketid*
+--version	starting.txt	/*--version*
+-A	starting.txt	/*-A*
+-C	starting.txt	/*-C*
+-D	starting.txt	/*-D*
+-E	starting.txt	/*-E*
+-F	starting.txt	/*-F*
+-H	starting.txt	/*-H*
+-L	starting.txt	/*-L*
+-M	starting.txt	/*-M*
+-N	starting.txt	/*-N*
+-O	starting.txt	/*-O*
+-P	starting.txt	/*-P*
+-R	starting.txt	/*-R*
+-S	starting.txt	/*-S*
+-T	starting.txt	/*-T*
+-U	starting.txt	/*-U*
+-V	starting.txt	/*-V*
+-W	starting.txt	/*-W*
+-X	starting.txt	/*-X*
+-Z	starting.txt	/*-Z*
+-b	starting.txt	/*-b*
+-background	gui_x11.txt	/*-background*
+-bg	gui_x11.txt	/*-bg*
+-boldfont	gui_x11.txt	/*-boldfont*
+-borderwidth	gui_x11.txt	/*-borderwidth*
+-bw	gui_x11.txt	/*-bw*
+-c	starting.txt	/*-c*
+-d	starting.txt	/*-d*
+-dev	starting.txt	/*-dev*
+-display	gui_x11.txt	/*-display*
+-e	starting.txt	/*-e*
+-f	starting.txt	/*-f*
+-fg	gui_x11.txt	/*-fg*
+-file	starting.txt	/*-file*
+-fn	gui_x11.txt	/*-fn*
+-font	gui_x11.txt	/*-font*
+-foreground	gui_x11.txt	/*-foreground*
+-g	starting.txt	/*-g*
+-geom	gui_x11.txt	/*-geom*
+-geometry	gui_x11.txt	/*-geometry*
+-geometry-example	gui_x11.txt	/*-geometry-example*
+-gui	gui_x11.txt	/*-gui*
+-h	starting.txt	/*-h*
+-i	starting.txt	/*-i*
+-iconic	gui_x11.txt	/*-iconic*
+-italicfont	gui_x11.txt	/*-italicfont*
+-l	starting.txt	/*-l*
+-m	starting.txt	/*-m*
+-menufont	gui_x11.txt	/*-menufont*
+-menufontset	gui_x11.txt	/*-menufontset*
+-menuheight	gui_x11.txt	/*-menuheight*
+-mf	gui_x11.txt	/*-mf*
+-mh	gui_x11.txt	/*-mh*
+-n	starting.txt	/*-n*
+-nb	starting.txt	/*-nb*
+-o	starting.txt	/*-o*
+-p	starting.txt	/*-p*
+-q	starting.txt	/*-q*
+-qf	starting.txt	/*-qf*
+-r	starting.txt	/*-r*
+-register	if_ole.txt	/*-register*
+-reverse	gui_x11.txt	/*-reverse*
+-rv	gui_x11.txt	/*-rv*
+-s	starting.txt	/*-s*
+-s-ex	starting.txt	/*-s-ex*
+-scrollbarwidth	gui_x11.txt	/*-scrollbarwidth*
+-silent	if_ole.txt	/*-silent*
+-sw	gui_x11.txt	/*-sw*
+-t	starting.txt	/*-t*
+-tag	starting.txt	/*-tag*
+-u	starting.txt	/*-u*
+-ul	gui_x11.txt	/*-ul*
+-unregister	if_ole.txt	/*-unregister*
+-v	starting.txt	/*-v*
+-vim	starting.txt	/*-vim*
+-w	starting.txt	/*-w*
+-w_nr	starting.txt	/*-w_nr*
+-x	starting.txt	/*-x*
+-xrm	gui_x11.txt	/*-xrm*
+-y	starting.txt	/*-y*
+.	repeat.txt	/*.*
+...	eval.txt	/*...*
+.Xdefaults	gui_x11.txt	/*.Xdefaults*
+.aff	spell.txt	/*.aff*
+.dic	spell.txt	/*.dic*
+.exrc	starting.txt	/*.exrc*
+.gvimrc	gui.txt	/*.gvimrc*
+.vimrc	starting.txt	/*.vimrc*
+/	pattern.txt	/*\/*
+/$	pattern.txt	/*\/$*
+/.	pattern.txt	/*\/.*
+//;	pattern.txt	/*\/\/;*
+/<CR>	pattern.txt	/*\/<CR>*
+/[[.	pattern.txt	/*\/[[.*
+/[[=	pattern.txt	/*\/[[=*
+/[\n]	pattern.txt	/*\/[\\n]*
+/[]	pattern.txt	/*\/[]*
+/\	pattern.txt	/*\/\\*
+/\$	pattern.txt	/*\/\\$*
+/\%#	pattern.txt	/*\/\\%#*
+/\%$	pattern.txt	/*\/\\%$*
+/\%'m	pattern.txt	/*\/\\%'m*
+/\%(	pattern.txt	/*\/\\%(*
+/\%(\)	pattern.txt	/*\/\\%(\\)*
+/\%<'m	pattern.txt	/*\/\\%<'m*
+/\%<c	pattern.txt	/*\/\\%<c*
+/\%<l	pattern.txt	/*\/\\%<l*
+/\%<v	pattern.txt	/*\/\\%<v*
+/\%>'m	pattern.txt	/*\/\\%>'m*
+/\%>c	pattern.txt	/*\/\\%>c*
+/\%>l	pattern.txt	/*\/\\%>l*
+/\%>v	pattern.txt	/*\/\\%>v*
+/\%U	pattern.txt	/*\/\\%U*
+/\%V	pattern.txt	/*\/\\%V*
+/\%[]	pattern.txt	/*\/\\%[]*
+/\%^	pattern.txt	/*\/\\%^*
+/\%c	pattern.txt	/*\/\\%c*
+/\%d	pattern.txt	/*\/\\%d*
+/\%l	pattern.txt	/*\/\\%l*
+/\%o	pattern.txt	/*\/\\%o*
+/\%u	pattern.txt	/*\/\\%u*
+/\%v	pattern.txt	/*\/\\%v*
+/\%x	pattern.txt	/*\/\\%x*
+/\&	pattern.txt	/*\/\\&*
+/\(	pattern.txt	/*\/\\(*
+/\(\)	pattern.txt	/*\/\\(\\)*
+/\)	pattern.txt	/*\/\\)*
+/\+	pattern.txt	/*\/\\+*
+/\.	pattern.txt	/*\/\\.*
+/\1	pattern.txt	/*\/\\1*
+/\2	pattern.txt	/*\/\\2*
+/\3	pattern.txt	/*\/\\3*
+/\9	pattern.txt	/*\/\\9*
+/\<	pattern.txt	/*\/\\<*
+/\=	pattern.txt	/*\/\\=*
+/\>	pattern.txt	/*\/\\>*
+/\?	pattern.txt	/*\/\\?*
+/\@!	pattern.txt	/*\/\\@!*
+/\@<!	pattern.txt	/*\/\\@<!*
+/\@<=	pattern.txt	/*\/\\@<=*
+/\@=	pattern.txt	/*\/\\@=*
+/\@>	pattern.txt	/*\/\\@>*
+/\A	pattern.txt	/*\/\\A*
+/\C	pattern.txt	/*\/\\C*
+/\D	pattern.txt	/*\/\\D*
+/\F	pattern.txt	/*\/\\F*
+/\H	pattern.txt	/*\/\\H*
+/\I	pattern.txt	/*\/\\I*
+/\K	pattern.txt	/*\/\\K*
+/\L	pattern.txt	/*\/\\L*
+/\M	pattern.txt	/*\/\\M*
+/\O	pattern.txt	/*\/\\O*
+/\P	pattern.txt	/*\/\\P*
+/\S	pattern.txt	/*\/\\S*
+/\U	pattern.txt	/*\/\\U*
+/\V	pattern.txt	/*\/\\V*
+/\W	pattern.txt	/*\/\\W*
+/\X	pattern.txt	/*\/\\X*
+/\Z	pattern.txt	/*\/\\Z*
+/\[]	pattern.txt	/*\/\\[]*
+/\\	pattern.txt	/*\/\\\\*
+/\]	pattern.txt	/*\/\\]*
+/\^	pattern.txt	/*\/\\^*
+/\_	pattern.txt	/*\/\\_*
+/\_$	pattern.txt	/*\/\\_$*
+/\_.	pattern.txt	/*\/\\_.*
+/\_A	pattern.txt	/*\/\\_A*
+/\_D	pattern.txt	/*\/\\_D*
+/\_F	pattern.txt	/*\/\\_F*
+/\_H	pattern.txt	/*\/\\_H*
+/\_I	pattern.txt	/*\/\\_I*
+/\_K	pattern.txt	/*\/\\_K*
+/\_L	pattern.txt	/*\/\\_L*
+/\_O	pattern.txt	/*\/\\_O*
+/\_P	pattern.txt	/*\/\\_P*
+/\_S	pattern.txt	/*\/\\_S*
+/\_U	pattern.txt	/*\/\\_U*
+/\_W	pattern.txt	/*\/\\_W*
+/\_X	pattern.txt	/*\/\\_X*
+/\_[]	pattern.txt	/*\/\\_[]*
+/\_^	pattern.txt	/*\/\\_^*
+/\_a	pattern.txt	/*\/\\_a*
+/\_d	pattern.txt	/*\/\\_d*
+/\_f	pattern.txt	/*\/\\_f*
+/\_h	pattern.txt	/*\/\\_h*
+/\_i	pattern.txt	/*\/\\_i*
+/\_k	pattern.txt	/*\/\\_k*
+/\_l	pattern.txt	/*\/\\_l*
+/\_o	pattern.txt	/*\/\\_o*
+/\_p	pattern.txt	/*\/\\_p*
+/\_s	pattern.txt	/*\/\\_s*
+/\_u	pattern.txt	/*\/\\_u*
+/\_w	pattern.txt	/*\/\\_w*
+/\_x	pattern.txt	/*\/\\_x*
+/\a	pattern.txt	/*\/\\a*
+/\b	pattern.txt	/*\/\\b*
+/\bar	pattern.txt	/*\/\\bar*
+/\c	pattern.txt	/*\/\\c*
+/\d	pattern.txt	/*\/\\d*
+/\e	pattern.txt	/*\/\\e*
+/\f	pattern.txt	/*\/\\f*
+/\h	pattern.txt	/*\/\\h*
+/\i	pattern.txt	/*\/\\i*
+/\k	pattern.txt	/*\/\\k*
+/\l	pattern.txt	/*\/\\l*
+/\m	pattern.txt	/*\/\\m*
+/\n	pattern.txt	/*\/\\n*
+/\o	pattern.txt	/*\/\\o*
+/\p	pattern.txt	/*\/\\p*
+/\r	pattern.txt	/*\/\\r*
+/\s	pattern.txt	/*\/\\s*
+/\star	pattern.txt	/*\/\\star*
+/\t	pattern.txt	/*\/\\t*
+/\u	pattern.txt	/*\/\\u*
+/\v	pattern.txt	/*\/\\v*
+/\w	pattern.txt	/*\/\\w*
+/\x	pattern.txt	/*\/\\x*
+/\z(	syntax.txt	/*\/\\z(*
+/\z(\)	syntax.txt	/*\/\\z(\\)*
+/\z1	syntax.txt	/*\/\\z1*
+/\z2	syntax.txt	/*\/\\z2*
+/\z3	syntax.txt	/*\/\\z3*
+/\z4	syntax.txt	/*\/\\z4*
+/\z5	syntax.txt	/*\/\\z5*
+/\z6	syntax.txt	/*\/\\z6*
+/\z7	syntax.txt	/*\/\\z7*
+/\z8	syntax.txt	/*\/\\z8*
+/\z9	syntax.txt	/*\/\\z9*
+/\ze	pattern.txt	/*\/\\ze*
+/\zs	pattern.txt	/*\/\\zs*
+/\{	pattern.txt	/*\/\\{*
+/\{-	pattern.txt	/*\/\\{-*
+/\~	pattern.txt	/*\/\\~*
+/^	pattern.txt	/*\/^*
+/atom	pattern.txt	/*\/atom*
+/bar	pattern.txt	/*\/bar*
+/branch	pattern.txt	/*\/branch*
+/character-classes	pattern.txt	/*\/character-classes*
+/collection	pattern.txt	/*\/collection*
+/concat	pattern.txt	/*\/concat*
+/dyn	various.txt	/*\/dyn*
+/ignorecase	pattern.txt	/*\/ignorecase*
+/magic	pattern.txt	/*\/magic*
+/multi	pattern.txt	/*\/multi*
+/ordinary-atom	pattern.txt	/*\/ordinary-atom*
+/pattern	pattern.txt	/*\/pattern*
+/piece	pattern.txt	/*\/piece*
+/star	pattern.txt	/*\/star*
+/zero-width	pattern.txt	/*\/zero-width*
+/~	pattern.txt	/*\/~*
+0	motion.txt	/*0*
+01.1	usr_01.txt	/*01.1*
+01.2	usr_01.txt	/*01.2*
+01.3	usr_01.txt	/*01.3*
+01.4	usr_01.txt	/*01.4*
+02.1	usr_02.txt	/*02.1*
+02.2	usr_02.txt	/*02.2*
+02.3	usr_02.txt	/*02.3*
+02.4	usr_02.txt	/*02.4*
+02.5	usr_02.txt	/*02.5*
+02.6	usr_02.txt	/*02.6*
+02.7	usr_02.txt	/*02.7*
+02.8	usr_02.txt	/*02.8*
+03.1	usr_03.txt	/*03.1*
+03.10	usr_03.txt	/*03.10*
+03.2	usr_03.txt	/*03.2*
+03.3	usr_03.txt	/*03.3*
+03.4	usr_03.txt	/*03.4*
+03.5	usr_03.txt	/*03.5*
+03.6	usr_03.txt	/*03.6*
+03.7	usr_03.txt	/*03.7*
+03.8	usr_03.txt	/*03.8*
+03.9	usr_03.txt	/*03.9*
+04.1	usr_04.txt	/*04.1*
+04.10	usr_04.txt	/*04.10*
+04.2	usr_04.txt	/*04.2*
+04.3	usr_04.txt	/*04.3*
+04.4	usr_04.txt	/*04.4*
+04.5	usr_04.txt	/*04.5*
+04.6	usr_04.txt	/*04.6*
+04.7	usr_04.txt	/*04.7*
+04.8	usr_04.txt	/*04.8*
+04.9	usr_04.txt	/*04.9*
+05.1	usr_05.txt	/*05.1*
+05.2	usr_05.txt	/*05.2*
+05.3	usr_05.txt	/*05.3*
+05.4	usr_05.txt	/*05.4*
+05.5	usr_05.txt	/*05.5*
+05.6	usr_05.txt	/*05.6*
+05.7	usr_05.txt	/*05.7*
+06.1	usr_06.txt	/*06.1*
+06.2	usr_06.txt	/*06.2*
+06.3	usr_06.txt	/*06.3*
+06.4	usr_06.txt	/*06.4*
+06.5	usr_06.txt	/*06.5*
+06.6	usr_06.txt	/*06.6*
+07.1	usr_07.txt	/*07.1*
+07.2	usr_07.txt	/*07.2*
+07.3	usr_07.txt	/*07.3*
+07.4	usr_07.txt	/*07.4*
+07.5	usr_07.txt	/*07.5*
+07.6	usr_07.txt	/*07.6*
+07.7	usr_07.txt	/*07.7*
+08.1	usr_08.txt	/*08.1*
+08.2	usr_08.txt	/*08.2*
+08.3	usr_08.txt	/*08.3*
+08.4	usr_08.txt	/*08.4*
+08.5	usr_08.txt	/*08.5*
+08.6	usr_08.txt	/*08.6*
+08.7	usr_08.txt	/*08.7*
+08.8	usr_08.txt	/*08.8*
+08.9	usr_08.txt	/*08.9*
+09.1	usr_09.txt	/*09.1*
+09.2	usr_09.txt	/*09.2*
+09.3	usr_09.txt	/*09.3*
+09.4	usr_09.txt	/*09.4*
+10.1	usr_10.txt	/*10.1*
+10.2	usr_10.txt	/*10.2*
+10.3	usr_10.txt	/*10.3*
+10.4	usr_10.txt	/*10.4*
+10.5	usr_10.txt	/*10.5*
+10.6	usr_10.txt	/*10.6*
+10.7	usr_10.txt	/*10.7*
+10.8	usr_10.txt	/*10.8*
+10.9	usr_10.txt	/*10.9*
+11.1	usr_11.txt	/*11.1*
+11.2	usr_11.txt	/*11.2*
+11.3	usr_11.txt	/*11.3*
+11.4	usr_11.txt	/*11.4*
+12.1	usr_12.txt	/*12.1*
+12.2	usr_12.txt	/*12.2*
+12.3	usr_12.txt	/*12.3*
+12.4	usr_12.txt	/*12.4*
+12.5	usr_12.txt	/*12.5*
+12.6	usr_12.txt	/*12.6*
+12.7	usr_12.txt	/*12.7*
+12.8	usr_12.txt	/*12.8*
+1gD	pattern.txt	/*1gD*
+1gd	pattern.txt	/*1gd*
+20.1	usr_20.txt	/*20.1*
+20.2	usr_20.txt	/*20.2*
+20.3	usr_20.txt	/*20.3*
+20.4	usr_20.txt	/*20.4*
+20.5	usr_20.txt	/*20.5*
+21.1	usr_21.txt	/*21.1*
+21.2	usr_21.txt	/*21.2*
+21.3	usr_21.txt	/*21.3*
+21.4	usr_21.txt	/*21.4*
+21.5	usr_21.txt	/*21.5*
+21.6	usr_21.txt	/*21.6*
+22.1	usr_22.txt	/*22.1*
+22.2	usr_22.txt	/*22.2*
+22.3	usr_22.txt	/*22.3*
+22.4	usr_22.txt	/*22.4*
+23.1	usr_23.txt	/*23.1*
+23.2	usr_23.txt	/*23.2*
+23.3	usr_23.txt	/*23.3*
+23.4	usr_23.txt	/*23.4*
+23.5	usr_23.txt	/*23.5*
+24.1	usr_24.txt	/*24.1*
+24.10	usr_24.txt	/*24.10*
+24.2	usr_24.txt	/*24.2*
+24.3	usr_24.txt	/*24.3*
+24.4	usr_24.txt	/*24.4*
+24.5	usr_24.txt	/*24.5*
+24.6	usr_24.txt	/*24.6*
+24.7	usr_24.txt	/*24.7*
+24.8	usr_24.txt	/*24.8*
+24.9	usr_24.txt	/*24.9*
+25.1	usr_25.txt	/*25.1*
+25.2	usr_25.txt	/*25.2*
+25.3	usr_25.txt	/*25.3*
+25.4	usr_25.txt	/*25.4*
+25.5	usr_25.txt	/*25.5*
+26.1	usr_26.txt	/*26.1*
+26.2	usr_26.txt	/*26.2*
+26.3	usr_26.txt	/*26.3*
+26.4	usr_26.txt	/*26.4*
+27.1	usr_27.txt	/*27.1*
+27.2	usr_27.txt	/*27.2*
+27.3	usr_27.txt	/*27.3*
+27.4	usr_27.txt	/*27.4*
+27.5	usr_27.txt	/*27.5*
+27.6	usr_27.txt	/*27.6*
+27.7	usr_27.txt	/*27.7*
+27.8	usr_27.txt	/*27.8*
+27.9	usr_27.txt	/*27.9*
+28.1	usr_28.txt	/*28.1*
+28.10	usr_28.txt	/*28.10*
+28.2	usr_28.txt	/*28.2*
+28.3	usr_28.txt	/*28.3*
+28.4	usr_28.txt	/*28.4*
+28.5	usr_28.txt	/*28.5*
+28.6	usr_28.txt	/*28.6*
+28.7	usr_28.txt	/*28.7*
+28.8	usr_28.txt	/*28.8*
+28.9	usr_28.txt	/*28.9*
+29.1	usr_29.txt	/*29.1*
+29.2	usr_29.txt	/*29.2*
+29.3	usr_29.txt	/*29.3*
+29.4	usr_29.txt	/*29.4*
+29.5	usr_29.txt	/*29.5*
+2html.vim	syntax.txt	/*2html.vim*
+30.1	usr_30.txt	/*30.1*
+30.2	usr_30.txt	/*30.2*
+30.3	usr_30.txt	/*30.3*
+30.4	usr_30.txt	/*30.4*
+30.5	usr_30.txt	/*30.5*
+30.6	usr_30.txt	/*30.6*
+31.1	usr_31.txt	/*31.1*
+31.2	usr_31.txt	/*31.2*
+31.3	usr_31.txt	/*31.3*
+31.4	usr_31.txt	/*31.4*
+31.5	usr_31.txt	/*31.5*
+32.1	usr_32.txt	/*32.1*
+32.2	usr_32.txt	/*32.2*
+32.3	usr_32.txt	/*32.3*
+40.1	usr_40.txt	/*40.1*
+40.2	usr_40.txt	/*40.2*
+40.3	usr_40.txt	/*40.3*
+41.1	usr_41.txt	/*41.1*
+41.10	usr_41.txt	/*41.10*
+41.11	usr_41.txt	/*41.11*
+41.12	usr_41.txt	/*41.12*
+41.13	usr_41.txt	/*41.13*
+41.14	usr_41.txt	/*41.14*
+41.15	usr_41.txt	/*41.15*
+41.16	usr_41.txt	/*41.16*
+41.2	usr_41.txt	/*41.2*
+41.3	usr_41.txt	/*41.3*
+41.4	usr_41.txt	/*41.4*
+41.5	usr_41.txt	/*41.5*
+41.6	usr_41.txt	/*41.6*
+41.7	usr_41.txt	/*41.7*
+41.8	usr_41.txt	/*41.8*
+41.9	usr_41.txt	/*41.9*
+42	usr_42.txt	/*42*
+42.1	usr_42.txt	/*42.1*
+42.2	usr_42.txt	/*42.2*
+42.3	usr_42.txt	/*42.3*
+42.4	usr_42.txt	/*42.4*
+43.1	usr_43.txt	/*43.1*
+43.2	usr_43.txt	/*43.2*
+44.1	usr_44.txt	/*44.1*
+44.10	usr_44.txt	/*44.10*
+44.11	usr_44.txt	/*44.11*
+44.12	usr_44.txt	/*44.12*
+44.2	usr_44.txt	/*44.2*
+44.3	usr_44.txt	/*44.3*
+44.4	usr_44.txt	/*44.4*
+44.5	usr_44.txt	/*44.5*
+44.6	usr_44.txt	/*44.6*
+44.7	usr_44.txt	/*44.7*
+44.8	usr_44.txt	/*44.8*
+44.9	usr_44.txt	/*44.9*
+45.1	usr_45.txt	/*45.1*
+45.2	usr_45.txt	/*45.2*
+45.3	usr_45.txt	/*45.3*
+45.4	usr_45.txt	/*45.4*
+45.5	usr_45.txt	/*45.5*
+8g8	various.txt	/*8g8*
+90.1	usr_90.txt	/*90.1*
+90.2	usr_90.txt	/*90.2*
+90.3	usr_90.txt	/*90.3*
+90.4	usr_90.txt	/*90.4*
+90.5	usr_90.txt	/*90.5*
+:	cmdline.txt	/*:*
+:!	various.txt	/*:!*
+:!!	various.txt	/*:!!*
+:!cmd	various.txt	/*:!cmd*
+:!start	os_win32.txt	/*:!start*
+:#	various.txt	/*:#*
+:#!	various.txt	/*:#!*
+:$	cmdline.txt	/*:$*
+:%	cmdline.txt	/*:%*
+:&	change.txt	/*:&*
+:'	cmdline.txt	/*:'*
+:,	cmdline.txt	/*:,*
+:.	cmdline.txt	/*:.*
+:/	cmdline.txt	/*:\/*
+:0file	editing.txt	/*:0file*
+:2match	pattern.txt	/*:2match*
+:3match	pattern.txt	/*:3match*
+::.	cmdline.txt	/*::.*
+::8	cmdline.txt	/*::8*
+::e	cmdline.txt	/*::e*
+::gs	cmdline.txt	/*::gs*
+::h	cmdline.txt	/*::h*
+::p	cmdline.txt	/*::p*
+::r	cmdline.txt	/*::r*
+::s	cmdline.txt	/*::s*
+::t	cmdline.txt	/*::t*
+::~	cmdline.txt	/*::~*
+:;	cmdline.txt	/*:;*
+:<	change.txt	/*:<*
+:<abuf>	cmdline.txt	/*:<abuf>*
+:<afile>	cmdline.txt	/*:<afile>*
+:<amatch>	cmdline.txt	/*:<amatch>*
+:<cWORD>	cmdline.txt	/*:<cWORD>*
+:<cfile>	cmdline.txt	/*:<cfile>*
+:<cword>	cmdline.txt	/*:<cword>*
+:<sfile>	cmdline.txt	/*:<sfile>*
+:=	various.txt	/*:=*
+:>	change.txt	/*:>*
+:?	cmdline.txt	/*:?*
+:@	repeat.txt	/*:@*
+:@:	repeat.txt	/*:@:*
+:@@	repeat.txt	/*:@@*
+:AdaLines	ada.txt	/*:AdaLines*
+:AdaRainbow	ada.txt	/*:AdaRainbow*
+:AdaSpaces	ada.txt	/*:AdaSpaces*
+:AdaTagDir	ada.txt	/*:AdaTagDir*
+:AdaTagFile	ada.txt	/*:AdaTagFile*
+:AdaTypes	ada.txt	/*:AdaTypes*
+:CompilerSet	usr_41.txt	/*:CompilerSet*
+:DiffOrig	diff.txt	/*:DiffOrig*
+:Explore	pi_netrw.txt	/*:Explore*
+:GLVS	pi_getscript.txt	/*:GLVS*
+:GetLatestVimScripts_dat	pi_getscript.txt	/*:GetLatestVimScripts_dat*
+:GnatFind	ada.txt	/*:GnatFind*
+:GnatPretty	ada.txt	/*:GnatPretty*
+:GnatTags	ada.txt	/*:GnatTags*
+:Hexplore	pi_netrw.txt	/*:Hexplore*
+:Man	filetype.txt	/*:Man*
+:MkVimball	pi_vimball.txt	/*:MkVimball*
+:N	editing.txt	/*:N*
+:Nexplore	pi_netrw.txt	/*:Nexplore*
+:Next	editing.txt	/*:Next*
+:P	various.txt	/*:P*
+:Pexplore	pi_netrw.txt	/*:Pexplore*
+:Print	various.txt	/*:Print*
+:RmVimball	pi_vimball.txt	/*:RmVimball*
+:Sexplore	pi_netrw.txt	/*:Sexplore*
+:TOhtml	syntax.txt	/*:TOhtml*
+:Texplore	pi_netrw.txt	/*:Texplore*
+:UseVimball	pi_vimball.txt	/*:UseVimball*
+:Vexplore	pi_netrw.txt	/*:Vexplore*
+:VimballList	pi_vimball.txt	/*:VimballList*
+:X	editing.txt	/*:X*
+:XMLent	insert.txt	/*:XMLent*
+:XMLns	insert.txt	/*:XMLns*
+:\bar	cmdline.txt	/*:\\bar*
+:_!	cmdline.txt	/*:_!*
+:_#	cmdline.txt	/*:_#*
+:_##	cmdline.txt	/*:_##*
+:_%	cmdline.txt	/*:_%*
+:_%:	cmdline.txt	/*:_%:*
+:_%<	cmdline.txt	/*:_%<*
+:a	insert.txt	/*:a*
+:ab	map.txt	/*:ab*
+:abbreviate	map.txt	/*:abbreviate*
+:abbreviate-<buffer>	map.txt	/*:abbreviate-<buffer>*
+:abbreviate-local	map.txt	/*:abbreviate-local*
+:abbreviate-verbose	map.txt	/*:abbreviate-verbose*
+:abc	map.txt	/*:abc*
+:abclear	map.txt	/*:abclear*
+:abo	windows.txt	/*:abo*
+:aboveleft	windows.txt	/*:aboveleft*
+:al	windows.txt	/*:al*
+:all	windows.txt	/*:all*
+:am	gui.txt	/*:am*
+:amenu	gui.txt	/*:amenu*
+:an	gui.txt	/*:an*
+:anoremenu	gui.txt	/*:anoremenu*
+:append	insert.txt	/*:append*
+:ar	editing.txt	/*:ar*
+:arga	editing.txt	/*:arga*
+:argadd	editing.txt	/*:argadd*
+:argd	editing.txt	/*:argd*
+:argdelete	editing.txt	/*:argdelete*
+:argdo	editing.txt	/*:argdo*
+:arge	editing.txt	/*:arge*
+:argedit	editing.txt	/*:argedit*
+:argglobal	editing.txt	/*:argglobal*
+:arglocal	editing.txt	/*:arglocal*
+:args	editing.txt	/*:args*
+:args_f	editing.txt	/*:args_f*
+:args_f!	editing.txt	/*:args_f!*
+:argu	editing.txt	/*:argu*
+:argument	editing.txt	/*:argument*
+:as	various.txt	/*:as*
+:ascii	various.txt	/*:ascii*
+:au	autocmd.txt	/*:au*
+:aug	autocmd.txt	/*:aug*
+:augroup	autocmd.txt	/*:augroup*
+:augroup-delete	autocmd.txt	/*:augroup-delete*
+:aun	gui.txt	/*:aun*
+:aunmenu	gui.txt	/*:aunmenu*
+:autocmd	autocmd.txt	/*:autocmd*
+:autocmd-verbose	autocmd.txt	/*:autocmd-verbose*
+:b	windows.txt	/*:b*
+:bN	windows.txt	/*:bN*
+:bNext	windows.txt	/*:bNext*
+:ba	windows.txt	/*:ba*
+:bad	windows.txt	/*:bad*
+:badd	windows.txt	/*:badd*
+:ball	windows.txt	/*:ball*
+:bar	cmdline.txt	/*:bar*
+:bd	windows.txt	/*:bd*
+:bdel	windows.txt	/*:bdel*
+:bdelete	windows.txt	/*:bdelete*
+:be	gui.txt	/*:be*
+:behave	gui.txt	/*:behave*
+:bel	windows.txt	/*:bel*
+:belowright	windows.txt	/*:belowright*
+:bf	windows.txt	/*:bf*
+:bfirst	windows.txt	/*:bfirst*
+:bl	windows.txt	/*:bl*
+:blast	windows.txt	/*:blast*
+:bm	windows.txt	/*:bm*
+:bmodified	windows.txt	/*:bmodified*
+:bn	windows.txt	/*:bn*
+:bnext	windows.txt	/*:bnext*
+:botright	windows.txt	/*:botright*
+:bp	windows.txt	/*:bp*
+:bprevious	windows.txt	/*:bprevious*
+:br	windows.txt	/*:br*
+:brea	eval.txt	/*:brea*
+:break	eval.txt	/*:break*
+:breaka	repeat.txt	/*:breaka*
+:breakadd	repeat.txt	/*:breakadd*
+:breakd	repeat.txt	/*:breakd*
+:breakdel	repeat.txt	/*:breakdel*
+:breakl	repeat.txt	/*:breakl*
+:breaklist	repeat.txt	/*:breaklist*
+:brewind	windows.txt	/*:brewind*
+:bro	editing.txt	/*:bro*
+:browse	editing.txt	/*:browse*
+:browse-set	options.txt	/*:browse-set*
+:bu	windows.txt	/*:bu*
+:buf	windows.txt	/*:buf*
+:bufdo	windows.txt	/*:bufdo*
+:buffer	windows.txt	/*:buffer*
+:buffer-!	windows.txt	/*:buffer-!*
+:buffers	windows.txt	/*:buffers*
+:bun	windows.txt	/*:bun*
+:bunload	windows.txt	/*:bunload*
+:bw	windows.txt	/*:bw*
+:bwipe	windows.txt	/*:bwipe*
+:bwipeout	windows.txt	/*:bwipeout*
+:c	change.txt	/*:c*
+:cN	quickfix.txt	/*:cN*
+:cNext	quickfix.txt	/*:cNext*
+:cNf	quickfix.txt	/*:cNf*
+:cNfile	quickfix.txt	/*:cNfile*
+:ca	map.txt	/*:ca*
+:cabbrev	map.txt	/*:cabbrev*
+:cabc	map.txt	/*:cabc*
+:cabclear	map.txt	/*:cabclear*
+:cad	quickfix.txt	/*:cad*
+:caddb	quickfix.txt	/*:caddb*
+:caddbuffer	quickfix.txt	/*:caddbuffer*
+:caddexpr	quickfix.txt	/*:caddexpr*
+:caddf	quickfix.txt	/*:caddf*
+:caddfile	quickfix.txt	/*:caddfile*
+:cal	eval.txt	/*:cal*
+:call	eval.txt	/*:call*
+:cat	eval.txt	/*:cat*
+:catch	eval.txt	/*:catch*
+:cb	quickfix.txt	/*:cb*
+:cbuffer	quickfix.txt	/*:cbuffer*
+:cc	quickfix.txt	/*:cc*
+:ccl	quickfix.txt	/*:ccl*
+:cclose	quickfix.txt	/*:cclose*
+:cd	editing.txt	/*:cd*
+:cd-	editing.txt	/*:cd-*
+:ce	change.txt	/*:ce*
+:center	change.txt	/*:center*
+:cex	quickfix.txt	/*:cex*
+:cexpr	quickfix.txt	/*:cexpr*
+:cf	quickfix.txt	/*:cf*
+:cfile	quickfix.txt	/*:cfile*
+:cfir	quickfix.txt	/*:cfir*
+:cfirst	quickfix.txt	/*:cfirst*
+:cg	quickfix.txt	/*:cg*
+:cgetb	quickfix.txt	/*:cgetb*
+:cgetbuffer	quickfix.txt	/*:cgetbuffer*
+:cgete	quickfix.txt	/*:cgete*
+:cgetexpr	quickfix.txt	/*:cgetexpr*
+:cgetfile	quickfix.txt	/*:cgetfile*
+:ch	change.txt	/*:ch*
+:change	change.txt	/*:change*
+:changes	motion.txt	/*:changes*
+:chd	editing.txt	/*:chd*
+:chdir	editing.txt	/*:chdir*
+:che	tagsrch.txt	/*:che*
+:checkpath	tagsrch.txt	/*:checkpath*
+:checkt	editing.txt	/*:checkt*
+:checktime	editing.txt	/*:checktime*
+:cl	quickfix.txt	/*:cl*
+:cla	quickfix.txt	/*:cla*
+:clast	quickfix.txt	/*:clast*
+:clist	quickfix.txt	/*:clist*
+:clo	windows.txt	/*:clo*
+:close	windows.txt	/*:close*
+:cm	map.txt	/*:cm*
+:cmap	map.txt	/*:cmap*
+:cmap_l	map.txt	/*:cmap_l*
+:cmapc	map.txt	/*:cmapc*
+:cmapclear	map.txt	/*:cmapclear*
+:cme	gui.txt	/*:cme*
+:cmenu	gui.txt	/*:cmenu*
+:cn	quickfix.txt	/*:cn*
+:cnew	quickfix.txt	/*:cnew*
+:cnewer	quickfix.txt	/*:cnewer*
+:cnext	quickfix.txt	/*:cnext*
+:cnf	quickfix.txt	/*:cnf*
+:cnfile	quickfix.txt	/*:cnfile*
+:cno	map.txt	/*:cno*
+:cnorea	map.txt	/*:cnorea*
+:cnoreabbrev	map.txt	/*:cnoreabbrev*
+:cnoremap	map.txt	/*:cnoremap*
+:cnoreme	gui.txt	/*:cnoreme*
+:cnoremenu	gui.txt	/*:cnoremenu*
+:co	change.txt	/*:co*
+:col	quickfix.txt	/*:col*
+:colder	quickfix.txt	/*:colder*
+:colo	syntax.txt	/*:colo*
+:colorscheme	syntax.txt	/*:colorscheme*
+:com	map.txt	/*:com*
+:comc	map.txt	/*:comc*
+:comclear	map.txt	/*:comclear*
+:command	map.txt	/*:command*
+:command-bang	map.txt	/*:command-bang*
+:command-bar	map.txt	/*:command-bar*
+:command-buffer	map.txt	/*:command-buffer*
+:command-complete	map.txt	/*:command-complete*
+:command-completion	map.txt	/*:command-completion*
+:command-completion-custom	map.txt	/*:command-completion-custom*
+:command-completion-customlist	map.txt	/*:command-completion-customlist*
+:command-count	map.txt	/*:command-count*
+:command-nargs	map.txt	/*:command-nargs*
+:command-range	map.txt	/*:command-range*
+:command-register	map.txt	/*:command-register*
+:command-verbose	map.txt	/*:command-verbose*
+:comment	eval.txt	/*:comment*
+:comp	quickfix.txt	/*:comp*
+:compiler	quickfix.txt	/*:compiler*
+:con	eval.txt	/*:con*
+:conf	editing.txt	/*:conf*
+:confirm	editing.txt	/*:confirm*
+:continue	eval.txt	/*:continue*
+:cope	quickfix.txt	/*:cope*
+:copen	quickfix.txt	/*:copen*
+:copy	change.txt	/*:copy*
+:cp	quickfix.txt	/*:cp*
+:cpf	quickfix.txt	/*:cpf*
+:cpfile	quickfix.txt	/*:cpfile*
+:cprevious	quickfix.txt	/*:cprevious*
+:cq	quickfix.txt	/*:cq*
+:cquit	quickfix.txt	/*:cquit*
+:cr	quickfix.txt	/*:cr*
+:crewind	quickfix.txt	/*:crewind*
+:cs	if_cscop.txt	/*:cs*
+:cscope	if_cscop.txt	/*:cscope*
+:cstag	if_cscop.txt	/*:cstag*
+:cu	map.txt	/*:cu*
+:cuna	map.txt	/*:cuna*
+:cunabbrev	map.txt	/*:cunabbrev*
+:cunmap	map.txt	/*:cunmap*
+:cunme	gui.txt	/*:cunme*
+:cunmenu	gui.txt	/*:cunmenu*
+:cw	quickfix.txt	/*:cw*
+:cwindow	quickfix.txt	/*:cwindow*
+:d	change.txt	/*:d*
+:de	change.txt	/*:de*
+:debug	repeat.txt	/*:debug*
+:debug-name	repeat.txt	/*:debug-name*
+:debugg	repeat.txt	/*:debugg*
+:debuggreedy	repeat.txt	/*:debuggreedy*
+:del	change.txt	/*:del*
+:delc	map.txt	/*:delc*
+:delcommand	map.txt	/*:delcommand*
+:delcr	todo.txt	/*:delcr*
+:delete	change.txt	/*:delete*
+:delf	eval.txt	/*:delf*
+:delfunction	eval.txt	/*:delfunction*
+:delm	motion.txt	/*:delm*
+:delmarks	motion.txt	/*:delmarks*
+:di	change.txt	/*:di*
+:diffg	diff.txt	/*:diffg*
+:diffget	diff.txt	/*:diffget*
+:diffo	diff.txt	/*:diffo*
+:diffoff	diff.txt	/*:diffoff*
+:diffp	diff.txt	/*:diffp*
+:diffpatch	diff.txt	/*:diffpatch*
+:diffpu	diff.txt	/*:diffpu*
+:diffput	diff.txt	/*:diffput*
+:diffs	diff.txt	/*:diffs*
+:diffsplit	diff.txt	/*:diffsplit*
+:difft	diff.txt	/*:difft*
+:diffthis	diff.txt	/*:diffthis*
+:diffu	diff.txt	/*:diffu*
+:diffupdate	diff.txt	/*:diffupdate*
+:dig	digraph.txt	/*:dig*
+:digraphs	digraph.txt	/*:digraphs*
+:display	change.txt	/*:display*
+:dj	tagsrch.txt	/*:dj*
+:djump	tagsrch.txt	/*:djump*
+:dli	tagsrch.txt	/*:dli*
+:dlist	tagsrch.txt	/*:dlist*
+:do	autocmd.txt	/*:do*
+:doau	autocmd.txt	/*:doau*
+:doautoa	autocmd.txt	/*:doautoa*
+:doautoall	autocmd.txt	/*:doautoall*
+:doautocmd	autocmd.txt	/*:doautocmd*
+:dr	windows.txt	/*:dr*
+:drop	windows.txt	/*:drop*
+:ds	tagsrch.txt	/*:ds*
+:dsearch	tagsrch.txt	/*:dsearch*
+:dsp	tagsrch.txt	/*:dsp*
+:dsplit	tagsrch.txt	/*:dsplit*
+:e	editing.txt	/*:e*
+:ea	undo.txt	/*:ea*
+:earlier	undo.txt	/*:earlier*
+:ec	eval.txt	/*:ec*
+:echo	eval.txt	/*:echo*
+:echo-redraw	eval.txt	/*:echo-redraw*
+:echoe	eval.txt	/*:echoe*
+:echoerr	eval.txt	/*:echoerr*
+:echoh	eval.txt	/*:echoh*
+:echohl	eval.txt	/*:echohl*
+:echom	eval.txt	/*:echom*
+:echomsg	eval.txt	/*:echomsg*
+:echon	eval.txt	/*:echon*
+:edit	editing.txt	/*:edit*
+:edit!	editing.txt	/*:edit!*
+:edit!_f	editing.txt	/*:edit!_f*
+:edit_f	editing.txt	/*:edit_f*
+:el	eval.txt	/*:el*
+:else	eval.txt	/*:else*
+:elsei	eval.txt	/*:elsei*
+:elseif	eval.txt	/*:elseif*
+:em	gui.txt	/*:em*
+:emenu	gui.txt	/*:emenu*
+:en	eval.txt	/*:en*
+:endf	eval.txt	/*:endf*
+:endfo	eval.txt	/*:endfo*
+:endfor	eval.txt	/*:endfor*
+:endfunction	eval.txt	/*:endfunction*
+:endif	eval.txt	/*:endif*
+:endt	eval.txt	/*:endt*
+:endtry	eval.txt	/*:endtry*
+:endw	eval.txt	/*:endw*
+:endwhile	eval.txt	/*:endwhile*
+:ene	editing.txt	/*:ene*
+:ene!	editing.txt	/*:ene!*
+:enew	editing.txt	/*:enew*
+:enew!	editing.txt	/*:enew!*
+:ex	editing.txt	/*:ex*
+:exe	eval.txt	/*:exe*
+:execute	eval.txt	/*:execute*
+:exi	editing.txt	/*:exi*
+:exit	editing.txt	/*:exit*
+:exu	various.txt	/*:exu*
+:exusage	various.txt	/*:exusage*
+:f	editing.txt	/*:f*
+:fi	editing.txt	/*:fi*
+:file	editing.txt	/*:file*
+:file_f	editing.txt	/*:file_f*
+:filename	editing.txt	/*:filename*
+:files	windows.txt	/*:files*
+:filet	filetype.txt	/*:filet*
+:filetype	filetype.txt	/*:filetype*
+:filetype-indent-off	filetype.txt	/*:filetype-indent-off*
+:filetype-indent-on	filetype.txt	/*:filetype-indent-on*
+:filetype-off	filetype.txt	/*:filetype-off*
+:filetype-overview	filetype.txt	/*:filetype-overview*
+:filetype-plugin-off	filetype.txt	/*:filetype-plugin-off*
+:filetype-plugin-on	filetype.txt	/*:filetype-plugin-on*
+:fin	editing.txt	/*:fin*
+:fina	eval.txt	/*:fina*
+:finally	eval.txt	/*:finally*
+:find	editing.txt	/*:find*
+:fini	repeat.txt	/*:fini*
+:finish	repeat.txt	/*:finish*
+:fir	editing.txt	/*:fir*
+:first	editing.txt	/*:first*
+:fix	options.txt	/*:fix*
+:fixdel	options.txt	/*:fixdel*
+:fo	fold.txt	/*:fo*
+:fold	fold.txt	/*:fold*
+:foldc	fold.txt	/*:foldc*
+:foldclose	fold.txt	/*:foldclose*
+:foldd	fold.txt	/*:foldd*
+:folddoc	fold.txt	/*:folddoc*
+:folddoclosed	fold.txt	/*:folddoclosed*
+:folddoopen	fold.txt	/*:folddoopen*
+:foldo	fold.txt	/*:foldo*
+:foldopen	fold.txt	/*:foldopen*
+:for	eval.txt	/*:for*
+:fu	eval.txt	/*:fu*
+:function	eval.txt	/*:function*
+:function-verbose	eval.txt	/*:function-verbose*
+:g	repeat.txt	/*:g*
+:global	repeat.txt	/*:global*
+:go	motion.txt	/*:go*
+:goto	motion.txt	/*:goto*
+:gr	quickfix.txt	/*:gr*
+:grep	quickfix.txt	/*:grep*
+:grepa	quickfix.txt	/*:grepa*
+:grepadd	quickfix.txt	/*:grepadd*
+:gu	gui_x11.txt	/*:gu*
+:gui	gui_x11.txt	/*:gui*
+:gv	gui_x11.txt	/*:gv*
+:gvim	gui_x11.txt	/*:gvim*
+:h	various.txt	/*:h*
+:ha	print.txt	/*:ha*
+:hardcopy	print.txt	/*:hardcopy*
+:help	various.txt	/*:help*
+:helpf	various.txt	/*:helpf*
+:helpfind	various.txt	/*:helpfind*
+:helpg	various.txt	/*:helpg*
+:helpgrep	various.txt	/*:helpgrep*
+:helpt	various.txt	/*:helpt*
+:helptags	various.txt	/*:helptags*
+:hi	syntax.txt	/*:hi*
+:hi-default	syntax.txt	/*:hi-default*
+:hi-link	syntax.txt	/*:hi-link*
+:hi-normal	syntax.txt	/*:hi-normal*
+:hi-normal-cterm	syntax.txt	/*:hi-normal-cterm*
+:hide	windows.txt	/*:hide*
+:highlight	syntax.txt	/*:highlight*
+:highlight-default	syntax.txt	/*:highlight-default*
+:highlight-link	syntax.txt	/*:highlight-link*
+:highlight-normal	syntax.txt	/*:highlight-normal*
+:highlight-verbose	syntax.txt	/*:highlight-verbose*
+:history	cmdline.txt	/*:history*
+:history-indexing	cmdline.txt	/*:history-indexing*
+:i	insert.txt	/*:i*
+:ia	map.txt	/*:ia*
+:iabbrev	map.txt	/*:iabbrev*
+:iabc	map.txt	/*:iabc*
+:iabclear	map.txt	/*:iabclear*
+:if	eval.txt	/*:if*
+:ij	tagsrch.txt	/*:ij*
+:ijump	tagsrch.txt	/*:ijump*
+:il	tagsrch.txt	/*:il*
+:ilist	tagsrch.txt	/*:ilist*
+:im	map.txt	/*:im*
+:imap	map.txt	/*:imap*
+:imap_l	map.txt	/*:imap_l*
+:imapc	map.txt	/*:imapc*
+:imapclear	map.txt	/*:imapclear*
+:ime	gui.txt	/*:ime*
+:imenu	gui.txt	/*:imenu*
+:in	insert.txt	/*:in*
+:index	index.txt	/*:index*
+:ino	map.txt	/*:ino*
+:inorea	map.txt	/*:inorea*
+:inoreabbrev	map.txt	/*:inoreabbrev*
+:inoremap	map.txt	/*:inoremap*
+:inoreme	gui.txt	/*:inoreme*
+:inoremenu	gui.txt	/*:inoremenu*
+:insert	insert.txt	/*:insert*
+:intro	starting.txt	/*:intro*
+:is	tagsrch.txt	/*:is*
+:isearch	tagsrch.txt	/*:isearch*
+:isp	tagsrch.txt	/*:isp*
+:isplit	tagsrch.txt	/*:isplit*
+:iu	map.txt	/*:iu*
+:iuna	map.txt	/*:iuna*
+:iunabbrev	map.txt	/*:iunabbrev*
+:iunmap	map.txt	/*:iunmap*
+:iunme	gui.txt	/*:iunme*
+:iunmenu	gui.txt	/*:iunmenu*
+:j	change.txt	/*:j*
+:join	change.txt	/*:join*
+:ju	motion.txt	/*:ju*
+:jumps	motion.txt	/*:jumps*
+:k	motion.txt	/*:k*
+:kee	motion.txt	/*:kee*
+:keepa	editing.txt	/*:keepa*
+:keepalt	editing.txt	/*:keepalt*
+:keepj	motion.txt	/*:keepj*
+:keepjumps	motion.txt	/*:keepjumps*
+:keepmarks	motion.txt	/*:keepmarks*
+:l	various.txt	/*:l*
+:lN	quickfix.txt	/*:lN*
+:lNext	quickfix.txt	/*:lNext*
+:lNf	quickfix.txt	/*:lNf*
+:lNfile	quickfix.txt	/*:lNfile*
+:la	editing.txt	/*:la*
+:lad	quickfix.txt	/*:lad*
+:laddb	quickfix.txt	/*:laddb*
+:laddbuffer	quickfix.txt	/*:laddbuffer*
+:laddexpr	quickfix.txt	/*:laddexpr*
+:laddf	quickfix.txt	/*:laddf*
+:laddfile	quickfix.txt	/*:laddfile*
+:lan	mlang.txt	/*:lan*
+:lang	mlang.txt	/*:lang*
+:language	mlang.txt	/*:language*
+:last	editing.txt	/*:last*
+:lat	undo.txt	/*:lat*
+:later	undo.txt	/*:later*
+:lb	quickfix.txt	/*:lb*
+:lbuffer	quickfix.txt	/*:lbuffer*
+:lc	editing.txt	/*:lc*
+:lcd	editing.txt	/*:lcd*
+:lch	editing.txt	/*:lch*
+:lchdir	editing.txt	/*:lchdir*
+:lcl	quickfix.txt	/*:lcl*
+:lclose	quickfix.txt	/*:lclose*
+:lcs	if_cscop.txt	/*:lcs*
+:lcscope	if_cscop.txt	/*:lcscope*
+:le	change.txt	/*:le*
+:left	change.txt	/*:left*
+:lefta	windows.txt	/*:lefta*
+:leftabove	windows.txt	/*:leftabove*
+:let	eval.txt	/*:let*
+:let+=	eval.txt	/*:let+=*
+:let-$	eval.txt	/*:let-$*
+:let-&	eval.txt	/*:let-&*
+:let-=	eval.txt	/*:let-=*
+:let-@	eval.txt	/*:let-@*
+:let-environment	eval.txt	/*:let-environment*
+:let-option	eval.txt	/*:let-option*
+:let-register	eval.txt	/*:let-register*
+:let-unpack	eval.txt	/*:let-unpack*
+:let.=	eval.txt	/*:let.=*
+:lex	quickfix.txt	/*:lex*
+:lexpr	quickfix.txt	/*:lexpr*
+:lf	quickfix.txt	/*:lf*
+:lfile	quickfix.txt	/*:lfile*
+:lfir	quickfix.txt	/*:lfir*
+:lfirst	quickfix.txt	/*:lfirst*
+:lg	quickfix.txt	/*:lg*
+:lgetb	quickfix.txt	/*:lgetb*
+:lgetbuffer	quickfix.txt	/*:lgetbuffer*
+:lgete	quickfix.txt	/*:lgete*
+:lgetexpr	quickfix.txt	/*:lgetexpr*
+:lgetfile	quickfix.txt	/*:lgetfile*
+:lgr	quickfix.txt	/*:lgr*
+:lgrep	quickfix.txt	/*:lgrep*
+:lgrepa	quickfix.txt	/*:lgrepa*
+:lgrepadd	quickfix.txt	/*:lgrepadd*
+:lh	various.txt	/*:lh*
+:lhelpgrep	various.txt	/*:lhelpgrep*
+:list	various.txt	/*:list*
+:ll	quickfix.txt	/*:ll*
+:lla	quickfix.txt	/*:lla*
+:llast	quickfix.txt	/*:llast*
+:lli	quickfix.txt	/*:lli*
+:llist	quickfix.txt	/*:llist*
+:lm	map.txt	/*:lm*
+:lmak	quickfix.txt	/*:lmak*
+:lmake	quickfix.txt	/*:lmake*
+:lmap	map.txt	/*:lmap*
+:lmap_l	map.txt	/*:lmap_l*
+:lmapc	map.txt	/*:lmapc*
+:lmapclear	map.txt	/*:lmapclear*
+:ln	map.txt	/*:ln*
+:lne	quickfix.txt	/*:lne*
+:lnew	quickfix.txt	/*:lnew*
+:lnewer	quickfix.txt	/*:lnewer*
+:lnext	quickfix.txt	/*:lnext*
+:lnf	quickfix.txt	/*:lnf*
+:lnfile	quickfix.txt	/*:lnfile*
+:lnoremap	map.txt	/*:lnoremap*
+:lo	starting.txt	/*:lo*
+:loadk	mbyte.txt	/*:loadk*
+:loadkeymap	mbyte.txt	/*:loadkeymap*
+:loadview	starting.txt	/*:loadview*
+:loc	motion.txt	/*:loc*
+:lockmarks	motion.txt	/*:lockmarks*
+:lockv	eval.txt	/*:lockv*
+:lockvar	eval.txt	/*:lockvar*
+:lol	quickfix.txt	/*:lol*
+:lolder	quickfix.txt	/*:lolder*
+:lop	quickfix.txt	/*:lop*
+:lopen	quickfix.txt	/*:lopen*
+:lp	quickfix.txt	/*:lp*
+:lpf	quickfix.txt	/*:lpf*
+:lpfile	quickfix.txt	/*:lpfile*
+:lprevious	quickfix.txt	/*:lprevious*
+:lr	quickfix.txt	/*:lr*
+:lrewind	quickfix.txt	/*:lrewind*
+:ls	windows.txt	/*:ls*
+:lt	tagsrch.txt	/*:lt*
+:ltag	tagsrch.txt	/*:ltag*
+:lu	map.txt	/*:lu*
+:lunmap	map.txt	/*:lunmap*
+:lv	quickfix.txt	/*:lv*
+:lvimgrep	quickfix.txt	/*:lvimgrep*
+:lvimgrepa	quickfix.txt	/*:lvimgrepa*
+:lvimgrepadd	quickfix.txt	/*:lvimgrepadd*
+:lw	quickfix.txt	/*:lw*
+:lwindow	quickfix.txt	/*:lwindow*
+:m	change.txt	/*:m*
+:ma	motion.txt	/*:ma*
+:mak	quickfix.txt	/*:mak*
+:make	quickfix.txt	/*:make*
+:make_makeprg	quickfix.txt	/*:make_makeprg*
+:map	map.txt	/*:map*
+:map!	map.txt	/*:map!*
+:map-<buffer>	map.txt	/*:map-<buffer>*
+:map-<expr>	map.txt	/*:map-<expr>*
+:map-<script>	map.txt	/*:map-<script>*
+:map-<silent>	map.txt	/*:map-<silent>*
+:map-<special>	map.txt	/*:map-<special>*
+:map-<unique>	map.txt	/*:map-<unique>*
+:map-alt-keys	map.txt	/*:map-alt-keys*
+:map-arguments	map.txt	/*:map-arguments*
+:map-commands	map.txt	/*:map-commands*
+:map-expression	map.txt	/*:map-expression*
+:map-local	map.txt	/*:map-local*
+:map-modes	map.txt	/*:map-modes*
+:map-operator	map.txt	/*:map-operator*
+:map-script	map.txt	/*:map-script*
+:map-silent	map.txt	/*:map-silent*
+:map-special	map.txt	/*:map-special*
+:map-special-chars	map.txt	/*:map-special-chars*
+:map-special-keys	map.txt	/*:map-special-keys*
+:map-undo	map.txt	/*:map-undo*
+:map-verbose	map.txt	/*:map-verbose*
+:map_l	map.txt	/*:map_l*
+:map_l!	map.txt	/*:map_l!*
+:mapc	map.txt	/*:mapc*
+:mapc!	map.txt	/*:mapc!*
+:mapclear	map.txt	/*:mapclear*
+:mapclear!	map.txt	/*:mapclear!*
+:mark	motion.txt	/*:mark*
+:marks	motion.txt	/*:marks*
+:mat	pattern.txt	/*:mat*
+:match	pattern.txt	/*:match*
+:me	gui.txt	/*:me*
+:menu	gui.txt	/*:menu*
+:menu-<script>	gui.txt	/*:menu-<script>*
+:menu-<silent>	gui.txt	/*:menu-<silent>*
+:menu-<special>	gui.txt	/*:menu-<special>*
+:menu-disable	gui.txt	/*:menu-disable*
+:menu-enable	gui.txt	/*:menu-enable*
+:menu-script	gui.txt	/*:menu-script*
+:menu-silent	gui.txt	/*:menu-silent*
+:menu-special	gui.txt	/*:menu-special*
+:menut	mlang.txt	/*:menut*
+:menutrans	mlang.txt	/*:menutrans*
+:menutranslate	mlang.txt	/*:menutranslate*
+:mes	message.txt	/*:mes*
+:messages	message.txt	/*:messages*
+:mk	starting.txt	/*:mk*
+:mkexrc	starting.txt	/*:mkexrc*
+:mks	starting.txt	/*:mks*
+:mksession	starting.txt	/*:mksession*
+:mksp	spell.txt	/*:mksp*
+:mkspell	spell.txt	/*:mkspell*
+:mkv	starting.txt	/*:mkv*
+:mkvie	starting.txt	/*:mkvie*
+:mkview	starting.txt	/*:mkview*
+:mkvimrc	starting.txt	/*:mkvimrc*
+:mo	change.txt	/*:mo*
+:mod	term.txt	/*:mod*
+:mode	term.txt	/*:mode*
+:move	change.txt	/*:move*
+:mz	if_mzsch.txt	/*:mz*
+:mzf	if_mzsch.txt	/*:mzf*
+:mzfile	if_mzsch.txt	/*:mzfile*
+:mzscheme	if_mzsch.txt	/*:mzscheme*
+:n	editing.txt	/*:n*
+:nbkey	netbeans.txt	/*:nbkey*
+:ne	editing.txt	/*:ne*
+:new	windows.txt	/*:new*
+:next	editing.txt	/*:next*
+:next_f	editing.txt	/*:next_f*
+:nm	map.txt	/*:nm*
+:nmap	map.txt	/*:nmap*
+:nmap_l	map.txt	/*:nmap_l*
+:nmapc	map.txt	/*:nmapc*
+:nmapclear	map.txt	/*:nmapclear*
+:nme	gui.txt	/*:nme*
+:nmenu	gui.txt	/*:nmenu*
+:nn	map.txt	/*:nn*
+:nnoremap	map.txt	/*:nnoremap*
+:nnoreme	gui.txt	/*:nnoreme*
+:nnoremenu	gui.txt	/*:nnoremenu*
+:no	map.txt	/*:no*
+:no!	map.txt	/*:no!*
+:noa	autocmd.txt	/*:noa*
+:noautocmd	autocmd.txt	/*:noautocmd*
+:noh	pattern.txt	/*:noh*
+:nohlsearch	pattern.txt	/*:nohlsearch*
+:norea	map.txt	/*:norea*
+:noreabbrev	map.txt	/*:noreabbrev*
+:noremap	map.txt	/*:noremap*
+:noremap!	map.txt	/*:noremap!*
+:noreme	gui.txt	/*:noreme*
+:noremenu	gui.txt	/*:noremenu*
+:norm	various.txt	/*:norm*
+:normal	various.txt	/*:normal*
+:normal-range	various.txt	/*:normal-range*
+:nu	various.txt	/*:nu*
+:number	various.txt	/*:number*
+:nun	map.txt	/*:nun*
+:nunmap	map.txt	/*:nunmap*
+:nunme	gui.txt	/*:nunme*
+:nunmenu	gui.txt	/*:nunmenu*
+:o	vi_diff.txt	/*:o*
+:om	map.txt	/*:om*
+:omap	map.txt	/*:omap*
+:omap_l	map.txt	/*:omap_l*
+:omapc	map.txt	/*:omapc*
+:omapclear	map.txt	/*:omapclear*
+:ome	gui.txt	/*:ome*
+:omenu	gui.txt	/*:omenu*
+:on	windows.txt	/*:on*
+:only	windows.txt	/*:only*
+:ono	map.txt	/*:ono*
+:onoremap	map.txt	/*:onoremap*
+:onoreme	gui.txt	/*:onoreme*
+:onoremenu	gui.txt	/*:onoremenu*
+:op	vi_diff.txt	/*:op*
+:open	vi_diff.txt	/*:open*
+:opt	options.txt	/*:opt*
+:options	options.txt	/*:options*
+:ou	map.txt	/*:ou*
+:ounmap	map.txt	/*:ounmap*
+:ounme	gui.txt	/*:ounme*
+:ounmenu	gui.txt	/*:ounmenu*
+:p	various.txt	/*:p*
+:pc	windows.txt	/*:pc*
+:pclose	windows.txt	/*:pclose*
+:pe	if_perl.txt	/*:pe*
+:ped	windows.txt	/*:ped*
+:pedit	windows.txt	/*:pedit*
+:perl	if_perl.txt	/*:perl*
+:perld	if_perl.txt	/*:perld*
+:perldo	if_perl.txt	/*:perldo*
+:po	tagsrch.txt	/*:po*
+:pop	tagsrch.txt	/*:pop*
+:popu	gui.txt	/*:popu*
+:popup	gui.txt	/*:popup*
+:pp	windows.txt	/*:pp*
+:ppop	windows.txt	/*:ppop*
+:pr	various.txt	/*:pr*
+:pre	recover.txt	/*:pre*
+:preserve	recover.txt	/*:preserve*
+:prev	editing.txt	/*:prev*
+:previous	editing.txt	/*:previous*
+:print	various.txt	/*:print*
+:pro	change.txt	/*:pro*
+:prof	repeat.txt	/*:prof*
+:profd	repeat.txt	/*:profd*
+:profdel	repeat.txt	/*:profdel*
+:profile	repeat.txt	/*:profile*
+:promptfind	change.txt	/*:promptfind*
+:promptr	change.txt	/*:promptr*
+:promptrepl	change.txt	/*:promptrepl*
+:ps	windows.txt	/*:ps*
+:psearch	windows.txt	/*:psearch*
+:ptN	tagsrch.txt	/*:ptN*
+:ptNext	tagsrch.txt	/*:ptNext*
+:pta	windows.txt	/*:pta*
+:ptag	windows.txt	/*:ptag*
+:ptf	tagsrch.txt	/*:ptf*
+:ptfirst	tagsrch.txt	/*:ptfirst*
+:ptj	tagsrch.txt	/*:ptj*
+:ptjump	tagsrch.txt	/*:ptjump*
+:ptl	tagsrch.txt	/*:ptl*
+:ptlast	tagsrch.txt	/*:ptlast*
+:ptn	tagsrch.txt	/*:ptn*
+:ptnext	tagsrch.txt	/*:ptnext*
+:ptp	tagsrch.txt	/*:ptp*
+:ptprevious	tagsrch.txt	/*:ptprevious*
+:ptr	tagsrch.txt	/*:ptr*
+:ptrewind	tagsrch.txt	/*:ptrewind*
+:pts	tagsrch.txt	/*:pts*
+:ptselect	tagsrch.txt	/*:ptselect*
+:pu	change.txt	/*:pu*
+:put	change.txt	/*:put*
+:pw	editing.txt	/*:pw*
+:pwd	editing.txt	/*:pwd*
+:py	if_pyth.txt	/*:py*
+:pyf	if_pyth.txt	/*:pyf*
+:pyfile	if_pyth.txt	/*:pyfile*
+:python	if_pyth.txt	/*:python*
+:q	editing.txt	/*:q*
+:qa	editing.txt	/*:qa*
+:qall	editing.txt	/*:qall*
+:quit	editing.txt	/*:quit*
+:quita	editing.txt	/*:quita*
+:quitall	editing.txt	/*:quitall*
+:quote	cmdline.txt	/*:quote*
+:r	insert.txt	/*:r*
+:r!	insert.txt	/*:r!*
+:range	cmdline.txt	/*:range*
+:range!	change.txt	/*:range!*
+:re	insert.txt	/*:re*
+:read	insert.txt	/*:read*
+:read!	insert.txt	/*:read!*
+:rec	recover.txt	/*:rec*
+:recover	recover.txt	/*:recover*
+:red	undo.txt	/*:red*
+:redi	various.txt	/*:redi*
+:redir	various.txt	/*:redir*
+:redo	undo.txt	/*:redo*
+:redr	various.txt	/*:redr*
+:redraw	various.txt	/*:redraw*
+:redraws	various.txt	/*:redraws*
+:redrawstatus	various.txt	/*:redrawstatus*
+:reg	change.txt	/*:reg*
+:registers	change.txt	/*:registers*
+:res	windows.txt	/*:res*
+:resize	windows.txt	/*:resize*
+:ret	change.txt	/*:ret*
+:retab	change.txt	/*:retab*
+:retu	eval.txt	/*:retu*
+:return	eval.txt	/*:return*
+:rew	editing.txt	/*:rew*
+:rewind	editing.txt	/*:rewind*
+:ri	change.txt	/*:ri*
+:right	change.txt	/*:right*
+:rightb	windows.txt	/*:rightb*
+:rightbelow	windows.txt	/*:rightbelow*
+:ru	repeat.txt	/*:ru*
+:rub	if_ruby.txt	/*:rub*
+:ruby	if_ruby.txt	/*:ruby*
+:rubyd	if_ruby.txt	/*:rubyd*
+:rubydo	if_ruby.txt	/*:rubydo*
+:rubyf	if_ruby.txt	/*:rubyf*
+:rubyfile	if_ruby.txt	/*:rubyfile*
+:runtime	repeat.txt	/*:runtime*
+:rv	starting.txt	/*:rv*
+:rviminfo	starting.txt	/*:rviminfo*
+:s	change.txt	/*:s*
+:s%	change.txt	/*:s%*
+:sN	windows.txt	/*:sN*
+:sNext	windows.txt	/*:sNext*
+:s\=	change.txt	/*:s\\=*
+:s_c	change.txt	/*:s_c*
+:s_flags	change.txt	/*:s_flags*
+:sa	windows.txt	/*:sa*
+:sal	windows.txt	/*:sal*
+:sall	windows.txt	/*:sall*
+:san	eval.txt	/*:san*
+:sandbox	eval.txt	/*:sandbox*
+:sargument	windows.txt	/*:sargument*
+:sav	editing.txt	/*:sav*
+:saveas	editing.txt	/*:saveas*
+:sb	windows.txt	/*:sb*
+:sbN	windows.txt	/*:sbN*
+:sbNext	windows.txt	/*:sbNext*
+:sba	windows.txt	/*:sba*
+:sball	windows.txt	/*:sball*
+:sbf	windows.txt	/*:sbf*
+:sbfirst	windows.txt	/*:sbfirst*
+:sbl	windows.txt	/*:sbl*
+:sblast	windows.txt	/*:sblast*
+:sbm	windows.txt	/*:sbm*
+:sbmodified	windows.txt	/*:sbmodified*
+:sbn	windows.txt	/*:sbn*
+:sbnext	windows.txt	/*:sbnext*
+:sbp	windows.txt	/*:sbp*
+:sbprevious	windows.txt	/*:sbprevious*
+:sbr	windows.txt	/*:sbr*
+:sbrewind	windows.txt	/*:sbrewind*
+:sbuffer	windows.txt	/*:sbuffer*
+:scrip	repeat.txt	/*:scrip*
+:scripte	repeat.txt	/*:scripte*
+:scriptencoding	repeat.txt	/*:scriptencoding*
+:scriptnames	repeat.txt	/*:scriptnames*
+:scs	if_cscop.txt	/*:scs*
+:scscope	if_cscop.txt	/*:scscope*
+:se	options.txt	/*:se*
+:search-args	tagsrch.txt	/*:search-args*
+:set	options.txt	/*:set*
+:set+=	options.txt	/*:set+=*
+:set-&	options.txt	/*:set-&*
+:set-&vi	options.txt	/*:set-&vi*
+:set-&vim	options.txt	/*:set-&vim*
+:set-=	options.txt	/*:set-=*
+:set-args	options.txt	/*:set-args*
+:set-browse	options.txt	/*:set-browse*
+:set-default	options.txt	/*:set-default*
+:set-termcap	options.txt	/*:set-termcap*
+:set-verbose	options.txt	/*:set-verbose*
+:set^=	options.txt	/*:set^=*
+:set_env	options.txt	/*:set_env*
+:setf	options.txt	/*:setf*
+:setfiletype	options.txt	/*:setfiletype*
+:setg	options.txt	/*:setg*
+:setglobal	options.txt	/*:setglobal*
+:setl	options.txt	/*:setl*
+:setlocal	options.txt	/*:setlocal*
+:sf	windows.txt	/*:sf*
+:sfind	windows.txt	/*:sfind*
+:sfir	windows.txt	/*:sfir*
+:sfirst	windows.txt	/*:sfirst*
+:sh	various.txt	/*:sh*
+:shell	various.txt	/*:shell*
+:si	gui_w32.txt	/*:si*
+:sig	sign.txt	/*:sig*
+:sign	sign.txt	/*:sign*
+:sign-define	sign.txt	/*:sign-define*
+:sign-fname	sign.txt	/*:sign-fname*
+:sign-jump	sign.txt	/*:sign-jump*
+:sign-list	sign.txt	/*:sign-list*
+:sign-place	sign.txt	/*:sign-place*
+:sign-undefine	sign.txt	/*:sign-undefine*
+:sign-unplace	sign.txt	/*:sign-unplace*
+:sil	various.txt	/*:sil*
+:silent	various.txt	/*:silent*
+:simalt	gui_w32.txt	/*:simalt*
+:sl	various.txt	/*:sl*
+:sla	windows.txt	/*:sla*
+:slast	windows.txt	/*:slast*
+:sleep	various.txt	/*:sleep*
+:sm	change.txt	/*:sm*
+:smagic	change.txt	/*:smagic*
+:smap	map.txt	/*:smap*
+:smap_l	map.txt	/*:smap_l*
+:smapc	map.txt	/*:smapc*
+:smapclear	map.txt	/*:smapclear*
+:sme	gui.txt	/*:sme*
+:smenu	gui.txt	/*:smenu*
+:sn	windows.txt	/*:sn*
+:snext	windows.txt	/*:snext*
+:sni	if_sniff.txt	/*:sni*
+:sniff	if_sniff.txt	/*:sniff*
+:sno	change.txt	/*:sno*
+:snomagic	change.txt	/*:snomagic*
+:snor	map.txt	/*:snor*
+:snoremap	map.txt	/*:snoremap*
+:snoreme	gui.txt	/*:snoreme*
+:snoremenu	gui.txt	/*:snoremenu*
+:so	repeat.txt	/*:so*
+:sor	change.txt	/*:sor*
+:sort	change.txt	/*:sort*
+:source	repeat.txt	/*:source*
+:source_crnl	repeat.txt	/*:source_crnl*
+:sp	windows.txt	/*:sp*
+:spe	spell.txt	/*:spe*
+:spelld	spell.txt	/*:spelld*
+:spelldump	spell.txt	/*:spelldump*
+:spellgood	spell.txt	/*:spellgood*
+:spelli	spell.txt	/*:spelli*
+:spellinfo	spell.txt	/*:spellinfo*
+:spellr	spell.txt	/*:spellr*
+:spellrepall	spell.txt	/*:spellrepall*
+:spellu	spell.txt	/*:spellu*
+:spellundo	spell.txt	/*:spellundo*
+:spellw	spell.txt	/*:spellw*
+:spellwrong	spell.txt	/*:spellwrong*
+:split	windows.txt	/*:split*
+:split_f	windows.txt	/*:split_f*
+:spr	windows.txt	/*:spr*
+:sprevious	windows.txt	/*:sprevious*
+:sre	windows.txt	/*:sre*
+:srewind	windows.txt	/*:srewind*
+:st	starting.txt	/*:st*
+:sta	windows.txt	/*:sta*
+:stag	windows.txt	/*:stag*
+:star	repeat.txt	/*:star*
+:start	insert.txt	/*:start*
+:startgreplace	insert.txt	/*:startgreplace*
+:startinsert	insert.txt	/*:startinsert*
+:startreplace	insert.txt	/*:startreplace*
+:stj	tagsrch.txt	/*:stj*
+:stjump	tagsrch.txt	/*:stjump*
+:stop	starting.txt	/*:stop*
+:stopi	insert.txt	/*:stopi*
+:stopinsert	insert.txt	/*:stopinsert*
+:sts	tagsrch.txt	/*:sts*
+:stselect	tagsrch.txt	/*:stselect*
+:su	change.txt	/*:su*
+:substitute	change.txt	/*:substitute*
+:sun	windows.txt	/*:sun*
+:sunhide	windows.txt	/*:sunhide*
+:sunm	map.txt	/*:sunm*
+:sunmap	map.txt	/*:sunmap*
+:sunme	gui.txt	/*:sunme*
+:sunmenu	gui.txt	/*:sunmenu*
+:sus	starting.txt	/*:sus*
+:suspend	starting.txt	/*:suspend*
+:sv	windows.txt	/*:sv*
+:sview	windows.txt	/*:sview*
+:sw	recover.txt	/*:sw*
+:swapname	recover.txt	/*:swapname*
+:sy	syntax.txt	/*:sy*
+:syn	syntax.txt	/*:syn*
+:syn-arguments	syntax.txt	/*:syn-arguments*
+:syn-case	syntax.txt	/*:syn-case*
+:syn-clear	syntax.txt	/*:syn-clear*
+:syn-cluster	syntax.txt	/*:syn-cluster*
+:syn-contained	syntax.txt	/*:syn-contained*
+:syn-containedin	syntax.txt	/*:syn-containedin*
+:syn-contains	syntax.txt	/*:syn-contains*
+:syn-context	syntax.txt	/*:syn-context*
+:syn-default-override	usr_06.txt	/*:syn-default-override*
+:syn-define	syntax.txt	/*:syn-define*
+:syn-display	syntax.txt	/*:syn-display*
+:syn-enable	syntax.txt	/*:syn-enable*
+:syn-end	syntax.txt	/*:syn-end*
+:syn-excludenl	syntax.txt	/*:syn-excludenl*
+:syn-ext-match	syntax.txt	/*:syn-ext-match*
+:syn-extend	syntax.txt	/*:syn-extend*
+:syn-file-remarks	syntax.txt	/*:syn-file-remarks*
+:syn-files	syntax.txt	/*:syn-files*
+:syn-fold	syntax.txt	/*:syn-fold*
+:syn-include	syntax.txt	/*:syn-include*
+:syn-keepend	syntax.txt	/*:syn-keepend*
+:syn-keyword	syntax.txt	/*:syn-keyword*
+:syn-lc	syntax.txt	/*:syn-lc*
+:syn-leading	syntax.txt	/*:syn-leading*
+:syn-list	syntax.txt	/*:syn-list*
+:syn-manual	usr_06.txt	/*:syn-manual*
+:syn-match	syntax.txt	/*:syn-match*
+:syn-matchgroup	syntax.txt	/*:syn-matchgroup*
+:syn-multi-line	syntax.txt	/*:syn-multi-line*
+:syn-nextgroup	syntax.txt	/*:syn-nextgroup*
+:syn-off	usr_06.txt	/*:syn-off*
+:syn-on	syntax.txt	/*:syn-on*
+:syn-oneline	syntax.txt	/*:syn-oneline*
+:syn-pattern	syntax.txt	/*:syn-pattern*
+:syn-pattern-offset	syntax.txt	/*:syn-pattern-offset*
+:syn-priority	syntax.txt	/*:syn-priority*
+:syn-qstart	syntax.txt	/*:syn-qstart*
+:syn-region	syntax.txt	/*:syn-region*
+:syn-reset	syntax.txt	/*:syn-reset*
+:syn-skip	syntax.txt	/*:syn-skip*
+:syn-skipempty	syntax.txt	/*:syn-skipempty*
+:syn-skipnl	syntax.txt	/*:syn-skipnl*
+:syn-skipwhite	syntax.txt	/*:syn-skipwhite*
+:syn-spell	syntax.txt	/*:syn-spell*
+:syn-start	syntax.txt	/*:syn-start*
+:syn-sync	syntax.txt	/*:syn-sync*
+:syn-sync-ccomment	syntax.txt	/*:syn-sync-ccomment*
+:syn-sync-first	syntax.txt	/*:syn-sync-first*
+:syn-sync-fourth	syntax.txt	/*:syn-sync-fourth*
+:syn-sync-linebreaks	syntax.txt	/*:syn-sync-linebreaks*
+:syn-sync-maxlines	syntax.txt	/*:syn-sync-maxlines*
+:syn-sync-minlines	syntax.txt	/*:syn-sync-minlines*
+:syn-sync-second	syntax.txt	/*:syn-sync-second*
+:syn-sync-third	syntax.txt	/*:syn-sync-third*
+:syn-transparent	syntax.txt	/*:syn-transparent*
+:sync	scroll.txt	/*:sync*
+:syncbind	scroll.txt	/*:syncbind*
+:syntax	syntax.txt	/*:syntax*
+:syntax-enable	syntax.txt	/*:syntax-enable*
+:syntax-on	syntax.txt	/*:syntax-on*
+:syntax-reset	syntax.txt	/*:syntax-reset*
+:t	change.txt	/*:t*
+:tN	tagsrch.txt	/*:tN*
+:tNext	tagsrch.txt	/*:tNext*
+:ta	tagsrch.txt	/*:ta*
+:tab	tabpage.txt	/*:tab*
+:tabN	tabpage.txt	/*:tabN*
+:tabNext	tabpage.txt	/*:tabNext*
+:tabc	tabpage.txt	/*:tabc*
+:tabclose	tabpage.txt	/*:tabclose*
+:tabd	tabpage.txt	/*:tabd*
+:tabdo	tabpage.txt	/*:tabdo*
+:tabe	tabpage.txt	/*:tabe*
+:tabedit	tabpage.txt	/*:tabedit*
+:tabf	tabpage.txt	/*:tabf*
+:tabfind	tabpage.txt	/*:tabfind*
+:tabfir	tabpage.txt	/*:tabfir*
+:tabfirst	tabpage.txt	/*:tabfirst*
+:tabl	tabpage.txt	/*:tabl*
+:tablast	tabpage.txt	/*:tablast*
+:tabm	tabpage.txt	/*:tabm*
+:tabmove	tabpage.txt	/*:tabmove*
+:tabn	tabpage.txt	/*:tabn*
+:tabnew	tabpage.txt	/*:tabnew*
+:tabnext	tabpage.txt	/*:tabnext*
+:tabo	tabpage.txt	/*:tabo*
+:tabonly	tabpage.txt	/*:tabonly*
+:tabp	tabpage.txt	/*:tabp*
+:tabprevious	tabpage.txt	/*:tabprevious*
+:tabr	tabpage.txt	/*:tabr*
+:tabrewind	tabpage.txt	/*:tabrewind*
+:tabs	tabpage.txt	/*:tabs*
+:tag	tagsrch.txt	/*:tag*
+:tags	tagsrch.txt	/*:tags*
+:tc	if_tcl.txt	/*:tc*
+:tcl	if_tcl.txt	/*:tcl*
+:tcld	if_tcl.txt	/*:tcld*
+:tcldo	if_tcl.txt	/*:tcldo*
+:tclf	if_tcl.txt	/*:tclf*
+:tclfile	if_tcl.txt	/*:tclfile*
+:te	gui_w32.txt	/*:te*
+:tearoff	gui_w32.txt	/*:tearoff*
+:tf	tagsrch.txt	/*:tf*
+:tfirst	tagsrch.txt	/*:tfirst*
+:th	eval.txt	/*:th*
+:throw	eval.txt	/*:throw*
+:tj	tagsrch.txt	/*:tj*
+:tjump	tagsrch.txt	/*:tjump*
+:tl	tagsrch.txt	/*:tl*
+:tlast	tagsrch.txt	/*:tlast*
+:tm	gui.txt	/*:tm*
+:tmenu	gui.txt	/*:tmenu*
+:tn	tagsrch.txt	/*:tn*
+:tnext	tagsrch.txt	/*:tnext*
+:topleft	windows.txt	/*:topleft*
+:tp	tagsrch.txt	/*:tp*
+:tprevious	tagsrch.txt	/*:tprevious*
+:tr	tagsrch.txt	/*:tr*
+:trewind	tagsrch.txt	/*:trewind*
+:try	eval.txt	/*:try*
+:ts	tagsrch.txt	/*:ts*
+:tselect	tagsrch.txt	/*:tselect*
+:tu	gui.txt	/*:tu*
+:tunmenu	gui.txt	/*:tunmenu*
+:u	undo.txt	/*:u*
+:un	undo.txt	/*:un*
+:una	map.txt	/*:una*
+:unabbreviate	map.txt	/*:unabbreviate*
+:undo	undo.txt	/*:undo*
+:undoj	undo.txt	/*:undoj*
+:undojoin	undo.txt	/*:undojoin*
+:undol	undo.txt	/*:undol*
+:undolist	undo.txt	/*:undolist*
+:unh	windows.txt	/*:unh*
+:unhide	windows.txt	/*:unhide*
+:unl	eval.txt	/*:unl*
+:unlet	eval.txt	/*:unlet*
+:unlo	eval.txt	/*:unlo*
+:unlockvar	eval.txt	/*:unlockvar*
+:unm	map.txt	/*:unm*
+:unm!	map.txt	/*:unm!*
+:unmap	map.txt	/*:unmap*
+:unmap!	map.txt	/*:unmap!*
+:unme	gui.txt	/*:unme*
+:unmenu	gui.txt	/*:unmenu*
+:unmenu-all	gui.txt	/*:unmenu-all*
+:up	editing.txt	/*:up*
+:update	editing.txt	/*:update*
+:v	repeat.txt	/*:v*
+:ve	various.txt	/*:ve*
+:verb	various.txt	/*:verb*
+:verbose	various.txt	/*:verbose*
+:verbose-cmd	various.txt	/*:verbose-cmd*
+:version	various.txt	/*:version*
+:vert	windows.txt	/*:vert*
+:vertical	windows.txt	/*:vertical*
+:vertical-resize	windows.txt	/*:vertical-resize*
+:vglobal	repeat.txt	/*:vglobal*
+:vi	editing.txt	/*:vi*
+:vie	editing.txt	/*:vie*
+:view	editing.txt	/*:view*
+:vim	quickfix.txt	/*:vim*
+:vimgrep	quickfix.txt	/*:vimgrep*
+:vimgrepa	quickfix.txt	/*:vimgrepa*
+:vimgrepadd	quickfix.txt	/*:vimgrepadd*
+:visual	editing.txt	/*:visual*
+:visual_example	visual.txt	/*:visual_example*
+:viu	various.txt	/*:viu*
+:viusage	various.txt	/*:viusage*
+:vm	map.txt	/*:vm*
+:vmap	map.txt	/*:vmap*
+:vmap_l	map.txt	/*:vmap_l*
+:vmapc	map.txt	/*:vmapc*
+:vmapclear	map.txt	/*:vmapclear*
+:vme	gui.txt	/*:vme*
+:vmenu	gui.txt	/*:vmenu*
+:vn	map.txt	/*:vn*
+:vne	windows.txt	/*:vne*
+:vnew	windows.txt	/*:vnew*
+:vnoremap	map.txt	/*:vnoremap*
+:vnoreme	gui.txt	/*:vnoreme*
+:vnoremenu	gui.txt	/*:vnoremenu*
+:vs	windows.txt	/*:vs*
+:vsplit	windows.txt	/*:vsplit*
+:vu	map.txt	/*:vu*
+:vunmap	map.txt	/*:vunmap*
+:vunme	gui.txt	/*:vunme*
+:vunmenu	gui.txt	/*:vunmenu*
+:w	editing.txt	/*:w*
+:w!	editing.txt	/*:w!*
+:wN	editing.txt	/*:wN*
+:wNext	editing.txt	/*:wNext*
+:w_a	editing.txt	/*:w_a*
+:w_c	editing.txt	/*:w_c*
+:w_f	editing.txt	/*:w_f*
+:wa	editing.txt	/*:wa*
+:wall	editing.txt	/*:wall*
+:wh	eval.txt	/*:wh*
+:while	eval.txt	/*:while*
+:win	gui.txt	/*:win*
+:winc	windows.txt	/*:winc*
+:wincmd	windows.txt	/*:wincmd*
+:windo	windows.txt	/*:windo*
+:winp	gui.txt	/*:winp*
+:winpos	gui.txt	/*:winpos*
+:winsize	gui.txt	/*:winsize*
+:wn	editing.txt	/*:wn*
+:wnext	editing.txt	/*:wnext*
+:wp	editing.txt	/*:wp*
+:wprevious	editing.txt	/*:wprevious*
+:wq	editing.txt	/*:wq*
+:wqa	editing.txt	/*:wqa*
+:wqall	editing.txt	/*:wqall*
+:write	editing.txt	/*:write*
+:write_a	editing.txt	/*:write_a*
+:write_c	editing.txt	/*:write_c*
+:write_f	editing.txt	/*:write_f*
+:ws	workshop.txt	/*:ws*
+:wsverb	workshop.txt	/*:wsverb*
+:wv	starting.txt	/*:wv*
+:wviminfo	starting.txt	/*:wviminfo*
+:x	editing.txt	/*:x*
+:xa	editing.txt	/*:xa*
+:xall	editing.txt	/*:xall*
+:xit	editing.txt	/*:xit*
+:xm	map.txt	/*:xm*
+:xmap	map.txt	/*:xmap*
+:xmap_l	map.txt	/*:xmap_l*
+:xmapc	map.txt	/*:xmapc*
+:xmapclear	map.txt	/*:xmapclear*
+:xme	gui.txt	/*:xme*
+:xmenu	gui.txt	/*:xmenu*
+:xn	map.txt	/*:xn*
+:xnoremap	map.txt	/*:xnoremap*
+:xnoreme	gui.txt	/*:xnoreme*
+:xnoremenu	gui.txt	/*:xnoremenu*
+:xu	map.txt	/*:xu*
+:xunmap	map.txt	/*:xunmap*
+:xunme	gui.txt	/*:xunme*
+:xunmenu	gui.txt	/*:xunmenu*
+:y	change.txt	/*:y*
+:yank	change.txt	/*:yank*
+:z	various.txt	/*:z*
+:z#	various.txt	/*:z#*
+:~	change.txt	/*:~*
+;	motion.txt	/*;*
+<	change.txt	/*<*
+<2-LeftMouse>	term.txt	/*<2-LeftMouse>*
+<3-LeftMouse>	term.txt	/*<3-LeftMouse>*
+<4-LeftMouse>	term.txt	/*<4-LeftMouse>*
+<<	change.txt	/*<<*
+<>	intro.txt	/*<>*
+<A-	intro.txt	/*<A-*
+<A-LeftMouse>	term.txt	/*<A-LeftMouse>*
+<A-RightMouse>	term.txt	/*<A-RightMouse>*
+<BS>	motion.txt	/*<BS>*
+<Bar>	intro.txt	/*<Bar>*
+<Bslash>	intro.txt	/*<Bslash>*
+<C-	intro.txt	/*<C-*
+<C-Del>	os_dos.txt	/*<C-Del>*
+<C-End>	motion.txt	/*<C-End>*
+<C-Home>	motion.txt	/*<C-Home>*
+<C-Insert>	os_dos.txt	/*<C-Insert>*
+<C-Left>	motion.txt	/*<C-Left>*
+<C-LeftMouse>	tagsrch.txt	/*<C-LeftMouse>*
+<C-MouseDown>	scroll.txt	/*<C-MouseDown>*
+<C-MouseUp>	scroll.txt	/*<C-MouseUp>*
+<C-PageDown>	tabpage.txt	/*<C-PageDown>*
+<C-PageUp>	tabpage.txt	/*<C-PageUp>*
+<C-Right>	motion.txt	/*<C-Right>*
+<C-RightMouse>	tagsrch.txt	/*<C-RightMouse>*
+<CR>	motion.txt	/*<CR>*
+<CSI>	intro.txt	/*<CSI>*
+<Char->	map.txt	/*<Char->*
+<Char>	map.txt	/*<Char>*
+<D-	intro.txt	/*<D-*
+<Del>	change.txt	/*<Del>*
+<Down>	motion.txt	/*<Down>*
+<Drop>	change.txt	/*<Drop>*
+<EOL>	intro.txt	/*<EOL>*
+<End>	motion.txt	/*<End>*
+<Enter>	intro.txt	/*<Enter>*
+<Esc>	intro.txt	/*<Esc>*
+<F10>	term.txt	/*<F10>*
+<F11>	term.txt	/*<F11>*
+<F12>	term.txt	/*<F12>*
+<F13>	term.txt	/*<F13>*
+<F14>	term.txt	/*<F14>*
+<F15>	term.txt	/*<F15>*
+<F16>	term.txt	/*<F16>*
+<F17>	term.txt	/*<F17>*
+<F18>	term.txt	/*<F18>*
+<F19>	term.txt	/*<F19>*
+<F1>	various.txt	/*<F1>*
+<F2>	term.txt	/*<F2>*
+<F3>	term.txt	/*<F3>*
+<F4>	term.txt	/*<F4>*
+<F5>	term.txt	/*<F5>*
+<F6>	term.txt	/*<F6>*
+<F7>	term.txt	/*<F7>*
+<F8>	term.txt	/*<F8>*
+<F9>	term.txt	/*<F9>*
+<Help>	various.txt	/*<Help>*
+<Home>	motion.txt	/*<Home>*
+<Insert>	insert.txt	/*<Insert>*
+<Leader>	map.txt	/*<Leader>*
+<Left>	motion.txt	/*<Left>*
+<LeftDrag>	term.txt	/*<LeftDrag>*
+<LeftMouse>	visual.txt	/*<LeftMouse>*
+<LeftRelease>	visual.txt	/*<LeftRelease>*
+<LocalLeader>	map.txt	/*<LocalLeader>*
+<M-	intro.txt	/*<M-*
+<MiddleDrag>	term.txt	/*<MiddleDrag>*
+<MiddleMouse>	change.txt	/*<MiddleMouse>*
+<MiddleRelease>	term.txt	/*<MiddleRelease>*
+<Mouse>	term.txt	/*<Mouse>*
+<MouseDown>	scroll.txt	/*<MouseDown>*
+<MouseUp>	scroll.txt	/*<MouseUp>*
+<NL>	motion.txt	/*<NL>*
+<Nop>	map.txt	/*<Nop>*
+<Nul>	intro.txt	/*<Nul>*
+<PageDown>	scroll.txt	/*<PageDown>*
+<PageUp>	scroll.txt	/*<PageUp>*
+<Plug>	map.txt	/*<Plug>*
+<Return>	intro.txt	/*<Return>*
+<Right>	motion.txt	/*<Right>*
+<RightDrag>	term.txt	/*<RightDrag>*
+<RightMouse>	visual.txt	/*<RightMouse>*
+<RightRelease>	term.txt	/*<RightRelease>*
+<S-	intro.txt	/*<S-*
+<S-Del>	os_dos.txt	/*<S-Del>*
+<S-Down>	scroll.txt	/*<S-Down>*
+<S-End>	term.txt	/*<S-End>*
+<S-F10>	term.txt	/*<S-F10>*
+<S-F11>	term.txt	/*<S-F11>*
+<S-F12>	term.txt	/*<S-F12>*
+<S-F1>	intro.txt	/*<S-F1>*
+<S-F2>	term.txt	/*<S-F2>*
+<S-F3>	term.txt	/*<S-F3>*
+<S-F4>	term.txt	/*<S-F4>*
+<S-F5>	term.txt	/*<S-F5>*
+<S-F6>	term.txt	/*<S-F6>*
+<S-F7>	term.txt	/*<S-F7>*
+<S-F8>	term.txt	/*<S-F8>*
+<S-F9>	term.txt	/*<S-F9>*
+<S-Home>	term.txt	/*<S-Home>*
+<S-Insert>	os_dos.txt	/*<S-Insert>*
+<S-Left>	motion.txt	/*<S-Left>*
+<S-LeftMouse>	term.txt	/*<S-LeftMouse>*
+<S-MouseDown>	scroll.txt	/*<S-MouseDown>*
+<S-MouseUp>	scroll.txt	/*<S-MouseUp>*
+<S-Right>	motion.txt	/*<S-Right>*
+<S-RightMouse>	term.txt	/*<S-RightMouse>*
+<S-Tab>	term.txt	/*<S-Tab>*
+<S-Up>	scroll.txt	/*<S-Up>*
+<S-xF1>	term.txt	/*<S-xF1>*
+<S-xF2>	term.txt	/*<S-xF2>*
+<S-xF3>	term.txt	/*<S-xF3>*
+<S-xF4>	term.txt	/*<S-xF4>*
+<SID>	map.txt	/*<SID>*
+<SNR>	map.txt	/*<SNR>*
+<Space>	motion.txt	/*<Space>*
+<Tab>	motion.txt	/*<Tab>*
+<Undo>	undo.txt	/*<Undo>*
+<Up>	motion.txt	/*<Up>*
+<abuf>	cmdline.txt	/*<abuf>*
+<afile>	cmdline.txt	/*<afile>*
+<amatch>	cmdline.txt	/*<amatch>*
+<args>	map.txt	/*<args>*
+<bang>	map.txt	/*<bang>*
+<buffer=N>	autocmd.txt	/*<buffer=N>*
+<buffer=abuf>	autocmd.txt	/*<buffer=abuf>*
+<cfile>	cmdline.txt	/*<cfile>*
+<character>	intro.txt	/*<character>*
+<count>	map.txt	/*<count>*
+<f-args>	map.txt	/*<f-args>*
+<k0>	term.txt	/*<k0>*
+<k1>	term.txt	/*<k1>*
+<k2>	term.txt	/*<k2>*
+<k3>	term.txt	/*<k3>*
+<k4>	term.txt	/*<k4>*
+<k5>	term.txt	/*<k5>*
+<k6>	term.txt	/*<k6>*
+<k7>	term.txt	/*<k7>*
+<k8>	term.txt	/*<k8>*
+<k9>	term.txt	/*<k9>*
+<kDivide>	term.txt	/*<kDivide>*
+<kEnd>	motion.txt	/*<kEnd>*
+<kEnter>	term.txt	/*<kEnter>*
+<kHome>	motion.txt	/*<kHome>*
+<kMinus>	term.txt	/*<kMinus>*
+<kMultiply>	term.txt	/*<kMultiply>*
+<kPageDown>	scroll.txt	/*<kPageDown>*
+<kPageUp>	scroll.txt	/*<kPageUp>*
+<kPlus>	term.txt	/*<kPlus>*
+<kPoint>	term.txt	/*<kPoint>*
+<line1>	map.txt	/*<line1>*
+<line2>	map.txt	/*<line2>*
+<lt>	intro.txt	/*<lt>*
+<q-args>	map.txt	/*<q-args>*
+<reg>	map.txt	/*<reg>*
+<register>	map.txt	/*<register>*
+<sfile>	cmdline.txt	/*<sfile>*
+<xCSI>	intro.txt	/*<xCSI>*
+<xDown>	term.txt	/*<xDown>*
+<xEnd>	term.txt	/*<xEnd>*
+<xEnd>-xterm	term.txt	/*<xEnd>-xterm*
+<xF1>	term.txt	/*<xF1>*
+<xF1>-xterm	term.txt	/*<xF1>-xterm*
+<xF2>	term.txt	/*<xF2>*
+<xF2>-xterm	term.txt	/*<xF2>-xterm*
+<xF3>	term.txt	/*<xF3>*
+<xF3>-xterm	term.txt	/*<xF3>-xterm*
+<xF4>	term.txt	/*<xF4>*
+<xF4>-xterm	term.txt	/*<xF4>-xterm*
+<xHome>	term.txt	/*<xHome>*
+<xHome>-xterm	term.txt	/*<xHome>-xterm*
+<xLeft>	term.txt	/*<xLeft>*
+<xRight>	term.txt	/*<xRight>*
+<xUp>	term.txt	/*<xUp>*
+=	change.txt	/*=*
+==	change.txt	/*==*
+>	change.txt	/*>*
+>>	change.txt	/*>>*
+>cont	repeat.txt	/*>cont*
+>finish	repeat.txt	/*>finish*
+>interrupt	repeat.txt	/*>interrupt*
+>next	repeat.txt	/*>next*
+>quit	repeat.txt	/*>quit*
+>step	repeat.txt	/*>step*
+?	pattern.txt	/*?*
+?<CR>	pattern.txt	/*?<CR>*
+@	repeat.txt	/*@*
+@/	change.txt	/*@\/*
+@:	repeat.txt	/*@:*
+@=	change.txt	/*@=*
+@@	repeat.txt	/*@@*
+@r	eval.txt	/*@r*
+A	insert.txt	/*A*
+ACL	editing.txt	/*ACL*
+ATTENTION	usr_11.txt	/*ATTENTION*
+Abbreviations	map.txt	/*Abbreviations*
+Aleph	options.txt	/*Aleph*
+Amiga	os_amiga.txt	/*Amiga*
+Arabic	arabic.txt	/*Arabic*
+Atari	os_mint.txt	/*Atari*
+Athena	gui_x11.txt	/*Athena*
+B	motion.txt	/*B*
+BeBox	os_beos.txt	/*BeBox*
+BeOS	os_beos.txt	/*BeOS*
+Bram	intro.txt	/*Bram*
+BufAdd	autocmd.txt	/*BufAdd*
+BufCreate	autocmd.txt	/*BufCreate*
+BufDelete	autocmd.txt	/*BufDelete*
+BufEnter	autocmd.txt	/*BufEnter*
+BufFilePost	autocmd.txt	/*BufFilePost*
+BufFilePre	autocmd.txt	/*BufFilePre*
+BufHidden	autocmd.txt	/*BufHidden*
+BufLeave	autocmd.txt	/*BufLeave*
+BufNew	autocmd.txt	/*BufNew*
+BufNewFile	autocmd.txt	/*BufNewFile*
+BufRead	autocmd.txt	/*BufRead*
+BufReadCmd	autocmd.txt	/*BufReadCmd*
+BufReadPost	autocmd.txt	/*BufReadPost*
+BufReadPre	autocmd.txt	/*BufReadPre*
+BufUnload	autocmd.txt	/*BufUnload*
+BufWinEnter	autocmd.txt	/*BufWinEnter*
+BufWinLeave	autocmd.txt	/*BufWinLeave*
+BufWipeout	autocmd.txt	/*BufWipeout*
+BufWrite	autocmd.txt	/*BufWrite*
+BufWriteCmd	autocmd.txt	/*BufWriteCmd*
+BufWritePost	autocmd.txt	/*BufWritePost*
+BufWritePre	autocmd.txt	/*BufWritePre*
+C	change.txt	/*C*
+C-editing	tips.txt	/*C-editing*
+C-indenting	indent.txt	/*C-indenting*
+COMSPEC	starting.txt	/*COMSPEC*
+CR-used-for-NL	pattern.txt	/*CR-used-for-NL*
+CTRL-6	editing.txt	/*CTRL-6*
+CTRL-<PageDown>	tabpage.txt	/*CTRL-<PageDown>*
+CTRL-<PageUp>	tabpage.txt	/*CTRL-<PageUp>*
+CTRL-A	change.txt	/*CTRL-A*
+CTRL-B	scroll.txt	/*CTRL-B*
+CTRL-C	pattern.txt	/*CTRL-C*
+CTRL-D	scroll.txt	/*CTRL-D*
+CTRL-E	scroll.txt	/*CTRL-E*
+CTRL-F	scroll.txt	/*CTRL-F*
+CTRL-G	editing.txt	/*CTRL-G*
+CTRL-H	motion.txt	/*CTRL-H*
+CTRL-I	motion.txt	/*CTRL-I*
+CTRL-J	motion.txt	/*CTRL-J*
+CTRL-L	various.txt	/*CTRL-L*
+CTRL-M	motion.txt	/*CTRL-M*
+CTRL-N	motion.txt	/*CTRL-N*
+CTRL-O	motion.txt	/*CTRL-O*
+CTRL-P	motion.txt	/*CTRL-P*
+CTRL-Q	gui_w32.txt	/*CTRL-Q*
+CTRL-R	undo.txt	/*CTRL-R*
+CTRL-T	tagsrch.txt	/*CTRL-T*
+CTRL-U	scroll.txt	/*CTRL-U*
+CTRL-U-changed	version6.txt	/*CTRL-U-changed*
+CTRL-V	visual.txt	/*CTRL-V*
+CTRL-V-alternative	gui_w32.txt	/*CTRL-V-alternative*
+CTRL-W	index.txt	/*CTRL-W*
+CTRL-W_+	windows.txt	/*CTRL-W_+*
+CTRL-W_-	windows.txt	/*CTRL-W_-*
+CTRL-W_<	windows.txt	/*CTRL-W_<*
+CTRL-W_<BS>	windows.txt	/*CTRL-W_<BS>*
+CTRL-W_<CR>	quickfix.txt	/*CTRL-W_<CR>*
+CTRL-W_<Down>	windows.txt	/*CTRL-W_<Down>*
+CTRL-W_<Enter>	quickfix.txt	/*CTRL-W_<Enter>*
+CTRL-W_<Left>	windows.txt	/*CTRL-W_<Left>*
+CTRL-W_<Right>	windows.txt	/*CTRL-W_<Right>*
+CTRL-W_<Up>	windows.txt	/*CTRL-W_<Up>*
+CTRL-W_=	windows.txt	/*CTRL-W_=*
+CTRL-W_>	windows.txt	/*CTRL-W_>*
+CTRL-W_CTRL-B	windows.txt	/*CTRL-W_CTRL-B*
+CTRL-W_CTRL-C	windows.txt	/*CTRL-W_CTRL-C*
+CTRL-W_CTRL-D	tagsrch.txt	/*CTRL-W_CTRL-D*
+CTRL-W_CTRL-F	windows.txt	/*CTRL-W_CTRL-F*
+CTRL-W_CTRL-H	windows.txt	/*CTRL-W_CTRL-H*
+CTRL-W_CTRL-I	tagsrch.txt	/*CTRL-W_CTRL-I*
+CTRL-W_CTRL-J	windows.txt	/*CTRL-W_CTRL-J*
+CTRL-W_CTRL-K	windows.txt	/*CTRL-W_CTRL-K*
+CTRL-W_CTRL-L	windows.txt	/*CTRL-W_CTRL-L*
+CTRL-W_CTRL-N	windows.txt	/*CTRL-W_CTRL-N*
+CTRL-W_CTRL-O	windows.txt	/*CTRL-W_CTRL-O*
+CTRL-W_CTRL-P	windows.txt	/*CTRL-W_CTRL-P*
+CTRL-W_CTRL-Q	windows.txt	/*CTRL-W_CTRL-Q*
+CTRL-W_CTRL-R	windows.txt	/*CTRL-W_CTRL-R*
+CTRL-W_CTRL-S	windows.txt	/*CTRL-W_CTRL-S*
+CTRL-W_CTRL-T	windows.txt	/*CTRL-W_CTRL-T*
+CTRL-W_CTRL-V	windows.txt	/*CTRL-W_CTRL-V*
+CTRL-W_CTRL-W	windows.txt	/*CTRL-W_CTRL-W*
+CTRL-W_CTRL-X	windows.txt	/*CTRL-W_CTRL-X*
+CTRL-W_CTRL-Z	windows.txt	/*CTRL-W_CTRL-Z*
+CTRL-W_CTRL-]	windows.txt	/*CTRL-W_CTRL-]*
+CTRL-W_CTRL-^	windows.txt	/*CTRL-W_CTRL-^*
+CTRL-W_CTRL-_	windows.txt	/*CTRL-W_CTRL-_*
+CTRL-W_F	windows.txt	/*CTRL-W_F*
+CTRL-W_H	windows.txt	/*CTRL-W_H*
+CTRL-W_J	windows.txt	/*CTRL-W_J*
+CTRL-W_K	windows.txt	/*CTRL-W_K*
+CTRL-W_L	windows.txt	/*CTRL-W_L*
+CTRL-W_P	windows.txt	/*CTRL-W_P*
+CTRL-W_R	windows.txt	/*CTRL-W_R*
+CTRL-W_S	windows.txt	/*CTRL-W_S*
+CTRL-W_T	windows.txt	/*CTRL-W_T*
+CTRL-W_W	windows.txt	/*CTRL-W_W*
+CTRL-W_]	windows.txt	/*CTRL-W_]*
+CTRL-W_^	windows.txt	/*CTRL-W_^*
+CTRL-W__	windows.txt	/*CTRL-W__*
+CTRL-W_b	windows.txt	/*CTRL-W_b*
+CTRL-W_bar	windows.txt	/*CTRL-W_bar*
+CTRL-W_c	windows.txt	/*CTRL-W_c*
+CTRL-W_d	tagsrch.txt	/*CTRL-W_d*
+CTRL-W_f	windows.txt	/*CTRL-W_f*
+CTRL-W_gF	windows.txt	/*CTRL-W_gF*
+CTRL-W_g]	windows.txt	/*CTRL-W_g]*
+CTRL-W_g_CTRL-]	windows.txt	/*CTRL-W_g_CTRL-]*
+CTRL-W_gf	windows.txt	/*CTRL-W_gf*
+CTRL-W_g}	windows.txt	/*CTRL-W_g}*
+CTRL-W_h	windows.txt	/*CTRL-W_h*
+CTRL-W_i	tagsrch.txt	/*CTRL-W_i*
+CTRL-W_j	windows.txt	/*CTRL-W_j*
+CTRL-W_k	windows.txt	/*CTRL-W_k*
+CTRL-W_l	windows.txt	/*CTRL-W_l*
+CTRL-W_n	windows.txt	/*CTRL-W_n*
+CTRL-W_o	windows.txt	/*CTRL-W_o*
+CTRL-W_p	windows.txt	/*CTRL-W_p*
+CTRL-W_q	windows.txt	/*CTRL-W_q*
+CTRL-W_r	windows.txt	/*CTRL-W_r*
+CTRL-W_s	windows.txt	/*CTRL-W_s*
+CTRL-W_t	windows.txt	/*CTRL-W_t*
+CTRL-W_v	windows.txt	/*CTRL-W_v*
+CTRL-W_w	windows.txt	/*CTRL-W_w*
+CTRL-W_x	windows.txt	/*CTRL-W_x*
+CTRL-W_z	windows.txt	/*CTRL-W_z*
+CTRL-W_}	windows.txt	/*CTRL-W_}*
+CTRL-X	change.txt	/*CTRL-X*
+CTRL-Y	scroll.txt	/*CTRL-Y*
+CTRL-Z	starting.txt	/*CTRL-Z*
+CTRL-\_CTRL-G	intro.txt	/*CTRL-\\_CTRL-G*
+CTRL-\_CTRL-N	intro.txt	/*CTRL-\\_CTRL-N*
+CTRL-]	tagsrch.txt	/*CTRL-]*
+CTRL-^	editing.txt	/*CTRL-^*
+CTRL-{char}	intro.txt	/*CTRL-{char}*
+Chinese	mbyte.txt	/*Chinese*
+Cmd-event	autocmd.txt	/*Cmd-event*
+Cmdline	cmdline.txt	/*Cmdline*
+Cmdline-mode	cmdline.txt	/*Cmdline-mode*
+CmdwinEnter	autocmd.txt	/*CmdwinEnter*
+CmdwinLeave	autocmd.txt	/*CmdwinLeave*
+ColorScheme	autocmd.txt	/*ColorScheme*
+Command-line	cmdline.txt	/*Command-line*
+Command-line-mode	cmdline.txt	/*Command-line-mode*
+Contents	quickref.txt	/*Contents*
+Cscope	if_cscop.txt	/*Cscope*
+CursorHold	autocmd.txt	/*CursorHold*
+CursorHold-example	windows.txt	/*CursorHold-example*
+CursorHoldI	autocmd.txt	/*CursorHoldI*
+CursorIM	mbyte.txt	/*CursorIM*
+CursorMoved	autocmd.txt	/*CursorMoved*
+CursorMovedI	autocmd.txt	/*CursorMovedI*
+D	change.txt	/*D*
+DOS	os_dos.txt	/*DOS*
+DOS-format	editing.txt	/*DOS-format*
+DOS-format-write	editing.txt	/*DOS-format-write*
+DPMI	os_msdos.txt	/*DPMI*
+Dictionaries	eval.txt	/*Dictionaries*
+Dictionary	eval.txt	/*Dictionary*
+Dictionary-function	eval.txt	/*Dictionary-function*
+Digraphs	digraph.txt	/*Digraphs*
+E	motion.txt	/*E*
+E10	message.txt	/*E10*
+E100	diff.txt	/*E100*
+E101	diff.txt	/*E101*
+E102	diff.txt	/*E102*
+E103	diff.txt	/*E103*
+E104	digraph.txt	/*E104*
+E105	mbyte.txt	/*E105*
+E106	eval.txt	/*E106*
+E107	eval.txt	/*E107*
+E108	eval.txt	/*E108*
+E109	eval.txt	/*E109*
+E11	cmdline.txt	/*E11*
+E110	eval.txt	/*E110*
+E111	eval.txt	/*E111*
+E112	eval.txt	/*E112*
+E113	eval.txt	/*E113*
+E114	eval.txt	/*E114*
+E115	eval.txt	/*E115*
+E116	eval.txt	/*E116*
+E117	eval.txt	/*E117*
+E118	eval.txt	/*E118*
+E119	eval.txt	/*E119*
+E12	message.txt	/*E12*
+E120	eval.txt	/*E120*
+E121	eval.txt	/*E121*
+E122	eval.txt	/*E122*
+E123	eval.txt	/*E123*
+E124	eval.txt	/*E124*
+E125	eval.txt	/*E125*
+E126	eval.txt	/*E126*
+E127	eval.txt	/*E127*
+E128	eval.txt	/*E128*
+E129	eval.txt	/*E129*
+E13	message.txt	/*E13*
+E130	eval.txt	/*E130*
+E131	eval.txt	/*E131*
+E132	eval.txt	/*E132*
+E133	eval.txt	/*E133*
+E134	change.txt	/*E134*
+E135	autocmd.txt	/*E135*
+E136	starting.txt	/*E136*
+E137	starting.txt	/*E137*
+E138	starting.txt	/*E138*
+E139	message.txt	/*E139*
+E14	cmdline.txt	/*E14*
+E140	message.txt	/*E140*
+E141	message.txt	/*E141*
+E142	message.txt	/*E142*
+E143	autocmd.txt	/*E143*
+E144	various.txt	/*E144*
+E145	starting.txt	/*E145*
+E146	change.txt	/*E146*
+E147	repeat.txt	/*E147*
+E148	repeat.txt	/*E148*
+E149	various.txt	/*E149*
+E15	eval.txt	/*E15*
+E150	various.txt	/*E150*
+E151	various.txt	/*E151*
+E152	various.txt	/*E152*
+E153	various.txt	/*E153*
+E154	various.txt	/*E154*
+E155	sign.txt	/*E155*
+E156	sign.txt	/*E156*
+E157	sign.txt	/*E157*
+E158	sign.txt	/*E158*
+E159	sign.txt	/*E159*
+E16	cmdline.txt	/*E16*
+E160	sign.txt	/*E160*
+E161	repeat.txt	/*E161*
+E162	message.txt	/*E162*
+E163	editing.txt	/*E163*
+E164	editing.txt	/*E164*
+E165	editing.txt	/*E165*
+E166	message.txt	/*E166*
+E167	repeat.txt	/*E167*
+E168	repeat.txt	/*E168*
+E169	message.txt	/*E169*
+E17	message.txt	/*E17*
+E170	eval.txt	/*E170*
+E171	eval.txt	/*E171*
+E172	message.txt	/*E172*
+E173	message.txt	/*E173*
+E174	map.txt	/*E174*
+E175	map.txt	/*E175*
+E176	map.txt	/*E176*
+E177	map.txt	/*E177*
+E178	map.txt	/*E178*
+E179	map.txt	/*E179*
+E18	eval.txt	/*E18*
+E180	map.txt	/*E180*
+E181	map.txt	/*E181*
+E182	map.txt	/*E182*
+E183	map.txt	/*E183*
+E184	map.txt	/*E184*
+E185	syntax.txt	/*E185*
+E186	editing.txt	/*E186*
+E187	editing.txt	/*E187*
+E188	gui.txt	/*E188*
+E189	message.txt	/*E189*
+E19	message.txt	/*E19*
+E190	message.txt	/*E190*
+E191	motion.txt	/*E191*
+E192	message.txt	/*E192*
+E193	eval.txt	/*E193*
+E194	message.txt	/*E194*
+E195	starting.txt	/*E195*
+E196	various.txt	/*E196*
+E197	mlang.txt	/*E197*
+E198	options.txt	/*E198*
+E199	cmdline.txt	/*E199*
+E20	motion.txt	/*E20*
+E200	autocmd.txt	/*E200*
+E201	autocmd.txt	/*E201*
+E202	options.txt	/*E202*
+E203	autocmd.txt	/*E203*
+E204	autocmd.txt	/*E204*
+E205	if_pyth.txt	/*E205*
+E206	options.txt	/*E206*
+E207	editing.txt	/*E207*
+E208	message.txt	/*E208*
+E209	message.txt	/*E209*
+E21	options.txt	/*E21*
+E210	message.txt	/*E210*
+E211	message.txt	/*E211*
+E212	message.txt	/*E212*
+E213	options.txt	/*E213*
+E214	options.txt	/*E214*
+E215	autocmd.txt	/*E215*
+E216	autocmd.txt	/*E216*
+E217	autocmd.txt	/*E217*
+E218	autocmd.txt	/*E218*
+E219	message.txt	/*E219*
+E22	message.txt	/*E22*
+E220	message.txt	/*E220*
+E222	message.txt	/*E222*
+E223	options.txt	/*E223*
+E224	map.txt	/*E224*
+E225	map.txt	/*E225*
+E226	map.txt	/*E226*
+E227	map.txt	/*E227*
+E228	message.txt	/*E228*
+E229	gui.txt	/*E229*
+E23	message.txt	/*E23*
+E230	starting.txt	/*E230*
+E231	options.txt	/*E231*
+E232	message.txt	/*E232*
+E233	gui.txt	/*E233*
+E234	options.txt	/*E234*
+E235	options.txt	/*E235*
+E236	options.txt	/*E236*
+E237	print.txt	/*E237*
+E238	print.txt	/*E238*
+E239	sign.txt	/*E239*
+E24	message.txt	/*E24*
+E240	remote.txt	/*E240*
+E241	eval.txt	/*E241*
+E243	if_ole.txt	/*E243*
+E244	options.txt	/*E244*
+E245	options.txt	/*E245*
+E246	autocmd.txt	/*E246*
+E247	remote.txt	/*E247*
+E248	remote.txt	/*E248*
+E25	message.txt	/*E25*
+E250	options.txt	/*E250*
+E251	remote.txt	/*E251*
+E252	options.txt	/*E252*
+E253	mbyte.txt	/*E253*
+E254	message.txt	/*E254*
+E255	sign.txt	/*E255*
+E256	message.txt	/*E256*
+E257	if_cscop.txt	/*E257*
+E258	remote.txt	/*E258*
+E259	if_cscop.txt	/*E259*
+E26	rileft.txt	/*E26*
+E260	if_cscop.txt	/*E260*
+E261	if_cscop.txt	/*E261*
+E262	if_cscop.txt	/*E262*
+E263	if_pyth.txt	/*E263*
+E264	if_pyth.txt	/*E264*
+E265	if_ruby.txt	/*E265*
+E266	if_ruby.txt	/*E266*
+E267	if_ruby.txt	/*E267*
+E268	if_ruby.txt	/*E268*
+E269	if_ruby.txt	/*E269*
+E27	farsi.txt	/*E27*
+E270	if_ruby.txt	/*E270*
+E271	if_ruby.txt	/*E271*
+E272	if_ruby.txt	/*E272*
+E273	if_ruby.txt	/*E273*
+E274	if_sniff.txt	/*E274*
+E275	if_sniff.txt	/*E275*
+E276	if_sniff.txt	/*E276*
+E277	remote.txt	/*E277*
+E278	if_sniff.txt	/*E278*
+E279	if_sniff.txt	/*E279*
+E28	syntax.txt	/*E28*
+E280	if_tcl.txt	/*E280*
+E281	if_tcl.txt	/*E281*
+E282	starting.txt	/*E282*
+E283	motion.txt	/*E283*
+E284	mbyte.txt	/*E284*
+E285	mbyte.txt	/*E285*
+E286	mbyte.txt	/*E286*
+E287	mbyte.txt	/*E287*
+E288	mbyte.txt	/*E288*
+E289	mbyte.txt	/*E289*
+E29	change.txt	/*E29*
+E290	mbyte.txt	/*E290*
+E291	mbyte.txt	/*E291*
+E292	mbyte.txt	/*E292*
+E293	message.txt	/*E293*
+E294	message.txt	/*E294*
+E295	message.txt	/*E295*
+E296	message.txt	/*E296*
+E297	message.txt	/*E297*
+E298	message.txt	/*E298*
+E299	if_perl.txt	/*E299*
+E30	change.txt	/*E30*
+E300	message.txt	/*E300*
+E301	message.txt	/*E301*
+E302	message.txt	/*E302*
+E303	message.txt	/*E303*
+E304	message.txt	/*E304*
+E305	recover.txt	/*E305*
+E306	recover.txt	/*E306*
+E307	recover.txt	/*E307*
+E308	recover.txt	/*E308*
+E309	recover.txt	/*E309*
+E31	message.txt	/*E31*
+E310	recover.txt	/*E310*
+E311	recover.txt	/*E311*
+E312	recover.txt	/*E312*
+E313	recover.txt	/*E313*
+E314	recover.txt	/*E314*
+E315	message.txt	/*E315*
+E316	message.txt	/*E316*
+E317	message.txt	/*E317*
+E318	message.txt	/*E318*
+E319	message.txt	/*E319*
+E32	message.txt	/*E32*
+E320	message.txt	/*E320*
+E321	editing.txt	/*E321*
+E322	message.txt	/*E322*
+E323	message.txt	/*E323*
+E324	print.txt	/*E324*
+E325	usr_11.txt	/*E325*
+E326	recover.txt	/*E326*
+E327	gui.txt	/*E327*
+E328	gui.txt	/*E328*
+E329	gui.txt	/*E329*
+E33	message.txt	/*E33*
+E330	gui.txt	/*E330*
+E331	gui.txt	/*E331*
+E332	gui.txt	/*E332*
+E333	gui.txt	/*E333*
+E334	gui.txt	/*E334*
+E335	gui.txt	/*E335*
+E336	gui.txt	/*E336*
+E337	gui.txt	/*E337*
+E338	editing.txt	/*E338*
+E339	message.txt	/*E339*
+E34	various.txt	/*E34*
+E340	vi_diff.txt	/*E340*
+E341	message.txt	/*E341*
+E342	message.txt	/*E342*
+E343	options.txt	/*E343*
+E344	options.txt	/*E344*
+E345	options.txt	/*E345*
+E346	options.txt	/*E346*
+E347	options.txt	/*E347*
+E348	pattern.txt	/*E348*
+E349	pattern.txt	/*E349*
+E35	message.txt	/*E35*
+E350	fold.txt	/*E350*
+E351	fold.txt	/*E351*
+E352	fold.txt	/*E352*
+E353	change.txt	/*E353*
+E354	change.txt	/*E354*
+E355	options.txt	/*E355*
+E356	message.txt	/*E356*
+E357	options.txt	/*E357*
+E358	options.txt	/*E358*
+E359	term.txt	/*E359*
+E36	windows.txt	/*E36*
+E360	various.txt	/*E360*
+E362	term.txt	/*E362*
+E363	options.txt	/*E363*
+E364	eval.txt	/*E364*
+E365	print.txt	/*E365*
+E366	options.txt	/*E366*
+E367	autocmd.txt	/*E367*
+E368	eval.txt	/*E368*
+E369	pattern.txt	/*E369*
+E37	message.txt	/*E37*
+E370	various.txt	/*E370*
+E371	various.txt	/*E371*
+E372	quickfix.txt	/*E372*
+E373	quickfix.txt	/*E373*
+E374	quickfix.txt	/*E374*
+E375	quickfix.txt	/*E375*
+E376	quickfix.txt	/*E376*
+E377	quickfix.txt	/*E377*
+E378	quickfix.txt	/*E378*
+E379	quickfix.txt	/*E379*
+E38	message.txt	/*E38*
+E380	quickfix.txt	/*E380*
+E381	quickfix.txt	/*E381*
+E382	options.txt	/*E382*
+E383	pattern.txt	/*E383*
+E384	options.txt	/*E384*
+E385	options.txt	/*E385*
+E386	pattern.txt	/*E386*
+E387	tagsrch.txt	/*E387*
+E388	tagsrch.txt	/*E388*
+E389	tagsrch.txt	/*E389*
+E39	digraph.txt	/*E39*
+E390	syntax.txt	/*E390*
+E391	syntax.txt	/*E391*
+E392	syntax.txt	/*E392*
+E393	syntax.txt	/*E393*
+E394	syntax.txt	/*E394*
+E395	syntax.txt	/*E395*
+E396	syntax.txt	/*E396*
+E397	syntax.txt	/*E397*
+E398	syntax.txt	/*E398*
+E399	syntax.txt	/*E399*
+E40	message.txt	/*E40*
+E400	syntax.txt	/*E400*
+E401	syntax.txt	/*E401*
+E402	syntax.txt	/*E402*
+E403	syntax.txt	/*E403*
+E404	syntax.txt	/*E404*
+E405	syntax.txt	/*E405*
+E406	syntax.txt	/*E406*
+E407	syntax.txt	/*E407*
+E408	syntax.txt	/*E408*
+E409	syntax.txt	/*E409*
+E41	message.txt	/*E41*
+E410	syntax.txt	/*E410*
+E411	syntax.txt	/*E411*
+E412	syntax.txt	/*E412*
+E413	syntax.txt	/*E413*
+E414	syntax.txt	/*E414*
+E415	syntax.txt	/*E415*
+E416	syntax.txt	/*E416*
+E417	syntax.txt	/*E417*
+E418	syntax.txt	/*E418*
+E419	syntax.txt	/*E419*
+E42	quickfix.txt	/*E42*
+E420	syntax.txt	/*E420*
+E421	syntax.txt	/*E421*
+E422	syntax.txt	/*E422*
+E423	syntax.txt	/*E423*
+E424	message.txt	/*E424*
+E425	tagsrch.txt	/*E425*
+E426	tagsrch.txt	/*E426*
+E427	tagsrch.txt	/*E427*
+E428	tagsrch.txt	/*E428*
+E429	tagsrch.txt	/*E429*
+E43	message.txt	/*E43*
+E430	tagsrch.txt	/*E430*
+E431	tagsrch.txt	/*E431*
+E432	message.txt	/*E432*
+E433	options.txt	/*E433*
+E434	tagsrch.txt	/*E434*
+E435	tagsrch.txt	/*E435*
+E436	term.txt	/*E436*
+E437	term.txt	/*E437*
+E438	message.txt	/*E438*
+E439	message.txt	/*E439*
+E44	message.txt	/*E44*
+E440	message.txt	/*E440*
+E441	windows.txt	/*E441*
+E442	windows.txt	/*E442*
+E443	windows.txt	/*E443*
+E444	windows.txt	/*E444*
+E445	windows.txt	/*E445*
+E446	editing.txt	/*E446*
+E447	editing.txt	/*E447*
+E448	various.txt	/*E448*
+E449	eval.txt	/*E449*
+E45	message.txt	/*E45*
+E450	os_msdos.txt	/*E450*
+E451	os_msdos.txt	/*E451*
+E452	os_msdos.txt	/*E452*
+E453	os_msdos.txt	/*E453*
+E454	os_msdos.txt	/*E454*
+E455	print.txt	/*E455*
+E456	print.txt	/*E456*
+E457	print.txt	/*E457*
+E458	message.txt	/*E458*
+E459	message.txt	/*E459*
+E46	message.txt	/*E46*
+E460	message.txt	/*E460*
+E461	eval.txt	/*E461*
+E462	editing.txt	/*E462*
+E463	netbeans.txt	/*E463*
+E464	message.txt	/*E464*
+E465	gui.txt	/*E465*
+E466	gui.txt	/*E466*
+E467	map.txt	/*E467*
+E468	map.txt	/*E468*
+E469	if_cscop.txt	/*E469*
+E47	message.txt	/*E47*
+E470	change.txt	/*E470*
+E471	message.txt	/*E471*
+E472	editing.txt	/*E472*
+E473	message.txt	/*E473*
+E474	message.txt	/*E474*
+E475	message.txt	/*E475*
+E476	pattern.txt	/*E476*
+E477	message.txt	/*E477*
+E478	message.txt	/*E478*
+E479	editing.txt	/*E479*
+E48	eval.txt	/*E48*
+E480	editing.txt	/*E480*
+E481	message.txt	/*E481*
+E482	message.txt	/*E482*
+E483	message.txt	/*E483*
+E484	message.txt	/*E484*
+E485	message.txt	/*E485*
+E486	pattern.txt	/*E486*
+E487	options.txt	/*E487*
+E488	message.txt	/*E488*
+E489	intro.txt	/*E489*
+E49	message.txt	/*E49*
+E490	fold.txt	/*E490*
+E492	message.txt	/*E492*
+E493	cmdline.txt	/*E493*
+E494	editing.txt	/*E494*
+E495	cmdline.txt	/*E495*
+E496	cmdline.txt	/*E496*
+E497	cmdline.txt	/*E497*
+E498	cmdline.txt	/*E498*
+E499	cmdline.txt	/*E499*
+E50	syntax.txt	/*E50*
+E500	cmdline.txt	/*E500*
+E501	intro.txt	/*E501*
+E502	editing.txt	/*E502*
+E503	editing.txt	/*E503*
+E504	editing.txt	/*E504*
+E505	editing.txt	/*E505*
+E506	editing.txt	/*E506*
+E507	editing.txt	/*E507*
+E508	editing.txt	/*E508*
+E509	editing.txt	/*E509*
+E51	pattern.txt	/*E51*
+E510	editing.txt	/*E510*
+E512	editing.txt	/*E512*
+E513	options.txt	/*E513*
+E514	editing.txt	/*E514*
+E515	windows.txt	/*E515*
+E516	windows.txt	/*E516*
+E517	windows.txt	/*E517*
+E518	options.txt	/*E518*
+E519	options.txt	/*E519*
+E52	syntax.txt	/*E52*
+E520	options.txt	/*E520*
+E521	options.txt	/*E521*
+E522	options.txt	/*E522*
+E523	options.txt	/*E523*
+E524	options.txt	/*E524*
+E525	options.txt	/*E525*
+E526	options.txt	/*E526*
+E527	options.txt	/*E527*
+E528	options.txt	/*E528*
+E529	options.txt	/*E529*
+E53	pattern.txt	/*E53*
+E530	options.txt	/*E530*
+E531	options.txt	/*E531*
+E533	options.txt	/*E533*
+E534	options.txt	/*E534*
+E535	options.txt	/*E535*
+E536	options.txt	/*E536*
+E537	options.txt	/*E537*
+E538	options.txt	/*E538*
+E539	options.txt	/*E539*
+E54	pattern.txt	/*E54*
+E540	options.txt	/*E540*
+E541	options.txt	/*E541*
+E542	options.txt	/*E542*
+E543	options.txt	/*E543*
+E544	options.txt	/*E544*
+E545	options.txt	/*E545*
+E546	options.txt	/*E546*
+E547	options.txt	/*E547*
+E548	options.txt	/*E548*
+E549	options.txt	/*E549*
+E55	pattern.txt	/*E55*
+E550	options.txt	/*E550*
+E551	options.txt	/*E551*
+E552	options.txt	/*E552*
+E553	quickfix.txt	/*E553*
+E554	pattern.txt	/*E554*
+E555	tagsrch.txt	/*E555*
+E556	tagsrch.txt	/*E556*
+E557	term.txt	/*E557*
+E558	term.txt	/*E558*
+E559	term.txt	/*E559*
+E56	pattern.txt	/*E56*
+E560	if_cscop.txt	/*E560*
+E561	if_cscop.txt	/*E561*
+E562	if_cscop.txt	/*E562*
+E563	if_cscop.txt	/*E563*
+E564	if_cscop.txt	/*E564*
+E565	if_cscop.txt	/*E565*
+E566	if_cscop.txt	/*E566*
+E567	if_cscop.txt	/*E567*
+E568	if_cscop.txt	/*E568*
+E569	if_cscop.txt	/*E569*
+E57	pattern.txt	/*E57*
+E570	message.txt	/*E570*
+E571	if_tcl.txt	/*E571*
+E572	if_tcl.txt	/*E572*
+E573	remote.txt	/*E573*
+E574	starting.txt	/*E574*
+E575	starting.txt	/*E575*
+E576	starting.txt	/*E576*
+E577	starting.txt	/*E577*
+E578	editing.txt	/*E578*
+E579	eval.txt	/*E579*
+E58	pattern.txt	/*E58*
+E580	eval.txt	/*E580*
+E581	eval.txt	/*E581*
+E582	eval.txt	/*E582*
+E583	eval.txt	/*E583*
+E584	eval.txt	/*E584*
+E585	eval.txt	/*E585*
+E586	eval.txt	/*E586*
+E587	eval.txt	/*E587*
+E588	eval.txt	/*E588*
+E589	options.txt	/*E589*
+E59	pattern.txt	/*E59*
+E590	options.txt	/*E590*
+E591	options.txt	/*E591*
+E592	options.txt	/*E592*
+E593	options.txt	/*E593*
+E594	options.txt	/*E594*
+E595	options.txt	/*E595*
+E596	options.txt	/*E596*
+E597	options.txt	/*E597*
+E598	options.txt	/*E598*
+E60	pattern.txt	/*E60*
+E600	eval.txt	/*E600*
+E601	eval.txt	/*E601*
+E602	eval.txt	/*E602*
+E603	eval.txt	/*E603*
+E604	eval.txt	/*E604*
+E605	eval.txt	/*E605*
+E606	eval.txt	/*E606*
+E607	eval.txt	/*E607*
+E608	eval.txt	/*E608*
+E609	if_cscop.txt	/*E609*
+E61	pattern.txt	/*E61*
+E610	options.txt	/*E610*
+E611	options.txt	/*E611*
+E612	sign.txt	/*E612*
+E613	print.txt	/*E613*
+E614	editing.txt	/*E614*
+E615	editing.txt	/*E615*
+E616	editing.txt	/*E616*
+E617	options.txt	/*E617*
+E618	print.txt	/*E618*
+E619	print.txt	/*E619*
+E62	pattern.txt	/*E62*
+E620	print.txt	/*E620*
+E621	print.txt	/*E621*
+E622	if_cscop.txt	/*E622*
+E623	if_cscop.txt	/*E623*
+E624	print.txt	/*E624*
+E625	if_cscop.txt	/*E625*
+E626	if_cscop.txt	/*E626*
+E627	netbeans.txt	/*E627*
+E628	netbeans.txt	/*E628*
+E629	netbeans.txt	/*E629*
+E63	pattern.txt	/*E63*
+E630	netbeans.txt	/*E630*
+E631	netbeans.txt	/*E631*
+E632	netbeans.txt	/*E632*
+E633	netbeans.txt	/*E633*
+E634	netbeans.txt	/*E634*
+E635	netbeans.txt	/*E635*
+E636	netbeans.txt	/*E636*
+E637	netbeans.txt	/*E637*
+E638	netbeans.txt	/*E638*
+E639	netbeans.txt	/*E639*
+E64	pattern.txt	/*E64*
+E640	netbeans.txt	/*E640*
+E641	netbeans.txt	/*E641*
+E642	netbeans.txt	/*E642*
+E643	netbeans.txt	/*E643*
+E644	netbeans.txt	/*E644*
+E645	netbeans.txt	/*E645*
+E646	netbeans.txt	/*E646*
+E647	netbeans.txt	/*E647*
+E648	netbeans.txt	/*E648*
+E649	netbeans.txt	/*E649*
+E65	pattern.txt	/*E65*
+E650	netbeans.txt	/*E650*
+E651	netbeans.txt	/*E651*
+E652	netbeans.txt	/*E652*
+E653	netbeans.txt	/*E653*
+E654	netbeans.txt	/*E654*
+E655	eval.txt	/*E655*
+E656	netbeans.txt	/*E656*
+E657	netbeans.txt	/*E657*
+E658	netbeans.txt	/*E658*
+E659	if_pyth.txt	/*E659*
+E66	syntax.txt	/*E66*
+E660	netbeans.txt	/*E660*
+E661	various.txt	/*E661*
+E662	motion.txt	/*E662*
+E663	motion.txt	/*E663*
+E664	motion.txt	/*E664*
+E665	gui_x11.txt	/*E665*
+E666	quickfix.txt	/*E666*
+E667	editing.txt	/*E667*
+E668	netbeans.txt	/*E668*
+E669	syntax.txt	/*E669*
+E67	syntax.txt	/*E67*
+E670	various.txt	/*E670*
+E671	starting.txt	/*E671*
+E672	starting.txt	/*E672*
+E673	print.txt	/*E673*
+E674	print.txt	/*E674*
+E675	print.txt	/*E675*
+E676	options.txt	/*E676*
+E677	eval.txt	/*E677*
+E678	pattern.txt	/*E678*
+E679	syntax.txt	/*E679*
+E68	pattern.txt	/*E68*
+E680	autocmd.txt	/*E680*
+E681	quickfix.txt	/*E681*
+E682	quickfix.txt	/*E682*
+E683	quickfix.txt	/*E683*
+E684	eval.txt	/*E684*
+E685	message.txt	/*E685*
+E686	eval.txt	/*E686*
+E687	eval.txt	/*E687*
+E688	eval.txt	/*E688*
+E689	eval.txt	/*E689*
+E69	pattern.txt	/*E69*
+E690	eval.txt	/*E690*
+E691	eval.txt	/*E691*
+E692	eval.txt	/*E692*
+E693	eval.txt	/*E693*
+E694	eval.txt	/*E694*
+E695	eval.txt	/*E695*
+E696	eval.txt	/*E696*
+E697	eval.txt	/*E697*
+E698	eval.txt	/*E698*
+E699	eval.txt	/*E699*
+E70	pattern.txt	/*E70*
+E700	eval.txt	/*E700*
+E701	eval.txt	/*E701*
+E702	eval.txt	/*E702*
+E703	eval.txt	/*E703*
+E704	eval.txt	/*E704*
+E705	eval.txt	/*E705*
+E706	eval.txt	/*E706*
+E707	eval.txt	/*E707*
+E708	eval.txt	/*E708*
+E709	eval.txt	/*E709*
+E71	pattern.txt	/*E71*
+E710	eval.txt	/*E710*
+E711	eval.txt	/*E711*
+E712	eval.txt	/*E712*
+E713	eval.txt	/*E713*
+E714	eval.txt	/*E714*
+E715	eval.txt	/*E715*
+E716	eval.txt	/*E716*
+E717	eval.txt	/*E717*
+E718	eval.txt	/*E718*
+E719	eval.txt	/*E719*
+E72	message.txt	/*E72*
+E720	eval.txt	/*E720*
+E721	eval.txt	/*E721*
+E722	eval.txt	/*E722*
+E723	eval.txt	/*E723*
+E724	eval.txt	/*E724*
+E725	eval.txt	/*E725*
+E726	eval.txt	/*E726*
+E727	eval.txt	/*E727*
+E728	eval.txt	/*E728*
+E729	eval.txt	/*E729*
+E73	tagsrch.txt	/*E73*
+E730	eval.txt	/*E730*
+E731	eval.txt	/*E731*
+E732	eval.txt	/*E732*
+E733	eval.txt	/*E733*
+E734	eval.txt	/*E734*
+E735	eval.txt	/*E735*
+E736	eval.txt	/*E736*
+E737	eval.txt	/*E737*
+E738	eval.txt	/*E738*
+E739	eval.txt	/*E739*
+E74	message.txt	/*E74*
+E740	eval.txt	/*E740*
+E741	eval.txt	/*E741*
+E742	eval.txt	/*E742*
+E743	eval.txt	/*E743*
+E744	netbeans.txt	/*E744*
+E745	eval.txt	/*E745*
+E746	eval.txt	/*E746*
+E747	editing.txt	/*E747*
+E748	repeat.txt	/*E748*
+E749	various.txt	/*E749*
+E75	vi_diff.txt	/*E75*
+E750	repeat.txt	/*E750*
+E751	spell.txt	/*E751*
+E752	spell.txt	/*E752*
+E753	spell.txt	/*E753*
+E754	spell.txt	/*E754*
+E755	spell.txt	/*E755*
+E756	spell.txt	/*E756*
+E757	options.txt	/*E757*
+E758	spell.txt	/*E758*
+E759	spell.txt	/*E759*
+E76	pattern.txt	/*E76*
+E760	spell.txt	/*E760*
+E761	spell.txt	/*E761*
+E762	spell.txt	/*E762*
+E763	spell.txt	/*E763*
+E764	options.txt	/*E764*
+E765	options.txt	/*E765*
+E766	eval.txt	/*E766*
+E767	eval.txt	/*E767*
+E768	message.txt	/*E768*
+E769	pattern.txt	/*E769*
+E77	message.txt	/*E77*
+E770	spell.txt	/*E770*
+E771	spell.txt	/*E771*
+E772	spell.txt	/*E772*
+E773	recover.txt	/*E773*
+E774	map.txt	/*E774*
+E775	map.txt	/*E775*
+E776	quickfix.txt	/*E776*
+E777	quickfix.txt	/*E777*
+E778	spell.txt	/*E778*
+E779	spell.txt	/*E779*
+E78	motion.txt	/*E78*
+E780	spell.txt	/*E780*
+E781	spell.txt	/*E781*
+E782	spell.txt	/*E782*
+E783	spell.txt	/*E783*
+E784	tabpage.txt	/*E784*
+E785	eval.txt	/*E785*
+E786	eval.txt	/*E786*
+E787	diff.txt	/*E787*
+E788	autocmd.txt	/*E788*
+E789	syntax.txt	/*E789*
+E79	message.txt	/*E79*
+E790	undo.txt	/*E790*
+E791	mbyte.txt	/*E791*
+E792	gui.txt	/*E792*
+E793	diff.txt	/*E793*
+E794	eval.txt	/*E794*
+E795	eval.txt	/*E795*
+E796	editing.txt	/*E796*
+E797	spell.txt	/*E797*
+E80	message.txt	/*E80*
+E800	arabic.txt	/*E800*
+E81	map.txt	/*E81*
+E82	message.txt	/*E82*
+E83	message.txt	/*E83*
+E84	windows.txt	/*E84*
+E85	options.txt	/*E85*
+E86	windows.txt	/*E86*
+E87	windows.txt	/*E87*
+E88	windows.txt	/*E88*
+E89	message.txt	/*E89*
+E90	message.txt	/*E90*
+E91	options.txt	/*E91*
+E92	message.txt	/*E92*
+E93	windows.txt	/*E93*
+E94	windows.txt	/*E94*
+E95	message.txt	/*E95*
+E96	diff.txt	/*E96*
+E97	diff.txt	/*E97*
+E98	diff.txt	/*E98*
+E99	diff.txt	/*E99*
+EX	intro.txt	/*EX*
+EXINIT	starting.txt	/*EXINIT*
+Elvis	intro.txt	/*Elvis*
+EncodingChanged	autocmd.txt	/*EncodingChanged*
+Eterm	syntax.txt	/*Eterm*
+Ex	intro.txt	/*Ex*
+Ex-mode	intro.txt	/*Ex-mode*
+Exuberant_ctags	tagsrch.txt	/*Exuberant_ctags*
+F	motion.txt	/*F*
+FAQ	intro.txt	/*FAQ*
+Farsi	farsi.txt	/*Farsi*
+FileAppendCmd	autocmd.txt	/*FileAppendCmd*
+FileAppendPost	autocmd.txt	/*FileAppendPost*
+FileAppendPre	autocmd.txt	/*FileAppendPre*
+FileChangedRO	autocmd.txt	/*FileChangedRO*
+FileChangedShell	autocmd.txt	/*FileChangedShell*
+FileChangedShellPost	autocmd.txt	/*FileChangedShellPost*
+FileEncoding	autocmd.txt	/*FileEncoding*
+FileReadCmd	autocmd.txt	/*FileReadCmd*
+FileReadPost	autocmd.txt	/*FileReadPost*
+FileReadPre	autocmd.txt	/*FileReadPre*
+FileType	autocmd.txt	/*FileType*
+FileWriteCmd	autocmd.txt	/*FileWriteCmd*
+FileWritePost	autocmd.txt	/*FileWritePost*
+FileWritePre	autocmd.txt	/*FileWritePre*
+FilterReadPost	autocmd.txt	/*FilterReadPost*
+FilterReadPre	autocmd.txt	/*FilterReadPre*
+FilterWritePost	autocmd.txt	/*FilterWritePost*
+FilterWritePre	autocmd.txt	/*FilterWritePre*
+FocusGained	autocmd.txt	/*FocusGained*
+FocusLost	autocmd.txt	/*FocusLost*
+Folding	fold.txt	/*Folding*
+FuncUndefined	autocmd.txt	/*FuncUndefined*
+Funcref	eval.txt	/*Funcref*
+G	motion.txt	/*G*
+GNOME	gui_x11.txt	/*GNOME*
+GTK	gui_x11.txt	/*GTK*
+GTK+	gui_x11.txt	/*GTK+*
+GUI	gui.txt	/*GUI*
+GUI-X11	gui_x11.txt	/*GUI-X11*
+GUIEnter	autocmd.txt	/*GUIEnter*
+GUIFailed	autocmd.txt	/*GUIFailed*
+GetLatestVimScripts	pi_getscript.txt	/*GetLatestVimScripts*
+GetLatestVimScripts-copyright	pi_getscript.txt	/*GetLatestVimScripts-copyright*
+GetLatestVimScripts_dat	pi_getscript.txt	/*GetLatestVimScripts_dat*
+Gnome	gui_x11.txt	/*Gnome*
+H	motion.txt	/*H*
+I	insert.txt	/*I*
+ICCF	uganda.txt	/*ICCF*
+IM-server	mbyte.txt	/*IM-server*
+IME	mbyte.txt	/*IME*
+Insert	insert.txt	/*Insert*
+Insert-mode	insert.txt	/*Insert-mode*
+InsertChange	autocmd.txt	/*InsertChange*
+InsertEnter	autocmd.txt	/*InsertEnter*
+InsertLeave	autocmd.txt	/*InsertLeave*
+J	change.txt	/*J*
+Japanese	mbyte.txt	/*Japanese*
+K	various.txt	/*K*
+KDE	gui_x11.txt	/*KDE*
+KVim	gui_x11.txt	/*KVim*
+Korean	mbyte.txt	/*Korean*
+L	motion.txt	/*L*
+Linux-backspace	options.txt	/*Linux-backspace*
+List	eval.txt	/*List*
+Lists	eval.txt	/*Lists*
+M	motion.txt	/*M*
+MDI	starting.txt	/*MDI*
+MS-DOS	os_msdos.txt	/*MS-DOS*
+MS-Windows	os_win32.txt	/*MS-Windows*
+MSDOS	os_msdos.txt	/*MSDOS*
+MSVisualStudio	if_ole.txt	/*MSVisualStudio*
+MVS	os_390.txt	/*MVS*
+Mac	os_mac.txt	/*Mac*
+Mac-format	editing.txt	/*Mac-format*
+Mac-format-write	editing.txt	/*Mac-format-write*
+Macintosh	os_mac.txt	/*Macintosh*
+Mark	motion.txt	/*Mark*
+MenuPopup	autocmd.txt	/*MenuPopup*
+MiNT	os_mint.txt	/*MiNT*
+Moolenaar	intro.txt	/*Moolenaar*
+MorphOS	os_amiga.txt	/*MorphOS*
+Motif	gui_x11.txt	/*Motif*
+Myspell	spell.txt	/*Myspell*
+MzScheme	if_mzsch.txt	/*MzScheme*
+N	pattern.txt	/*N*
+N%	motion.txt	/*N%*
+N:	cmdline.txt	/*N:*
+N<Del>	various.txt	/*N<Del>*
+NL-used-for-Nul	pattern.txt	/*NL-used-for-Nul*
+NetBSD-backspace	options.txt	/*NetBSD-backspace*
+Normal	intro.txt	/*Normal*
+Normal-mode	intro.txt	/*Normal-mode*
+Nread	pi_netrw.txt	/*Nread*
+Nsource	pi_netrw.txt	/*Nsource*
+Nvi	intro.txt	/*Nvi*
+Nwrite	pi_netrw.txt	/*Nwrite*
+O	insert.txt	/*O*
+OS/2	os_os2.txt	/*OS\/2*
+OS2	os_os2.txt	/*OS2*
+OS390	os_390.txt	/*OS390*
+OS390-Motif	os_390.txt	/*OS390-Motif*
+OS390-bugs	os_390.txt	/*OS390-bugs*
+OS390-building	os_390.txt	/*OS390-building*
+OS390-changes	os_390.txt	/*OS390-changes*
+OS390-feedback	os_390.txt	/*OS390-feedback*
+OS390-has-ebcdic	os_390.txt	/*OS390-has-ebcdic*
+OS390-open-source	os_390.txt	/*OS390-open-source*
+OS390-weaknesses	os_390.txt	/*OS390-weaknesses*
+OS390-xterm	os_390.txt	/*OS390-xterm*
+OffTheSpot	mbyte.txt	/*OffTheSpot*
+OnTheSpot	mbyte.txt	/*OnTheSpot*
+Operator-pending	intro.txt	/*Operator-pending*
+Operator-pending-mode	intro.txt	/*Operator-pending-mode*
+OverTheSpot	mbyte.txt	/*OverTheSpot*
+P	change.txt	/*P*
+PATHEXT	eval.txt	/*PATHEXT*
+Pattern	pattern.txt	/*Pattern*
+Perl	if_perl.txt	/*Perl*
+Posix	intro.txt	/*Posix*
+Python	if_pyth.txt	/*Python*
+Q	intro.txt	/*Q*
+Q-command-changed	version5.txt	/*Q-command-changed*
+QNX	os_qnx.txt	/*QNX*
+Q_ab	quickref.txt	/*Q_ab*
+Q_ac	quickref.txt	/*Q_ac*
+Q_ai	quickref.txt	/*Q_ai*
+Q_bu	quickref.txt	/*Q_bu*
+Q_ce	quickref.txt	/*Q_ce*
+Q_ch	quickref.txt	/*Q_ch*
+Q_cm	quickref.txt	/*Q_cm*
+Q_co	quickref.txt	/*Q_co*
+Q_ct	help.txt	/*Q_ct*
+Q_de	quickref.txt	/*Q_de*
+Q_di	quickref.txt	/*Q_di*
+Q_ed	quickref.txt	/*Q_ed*
+Q_et	quickref.txt	/*Q_et*
+Q_ex	quickref.txt	/*Q_ex*
+Q_fl	quickref.txt	/*Q_fl*
+Q_fo	quickref.txt	/*Q_fo*
+Q_gu	quickref.txt	/*Q_gu*
+Q_in	quickref.txt	/*Q_in*
+Q_km	quickref.txt	/*Q_km*
+Q_lr	quickref.txt	/*Q_lr*
+Q_ma	quickref.txt	/*Q_ma*
+Q_op	quickref.txt	/*Q_op*
+Q_pa	quickref.txt	/*Q_pa*
+Q_qf	quickref.txt	/*Q_qf*
+Q_ra	quickref.txt	/*Q_ra*
+Q_re	quickref.txt	/*Q_re*
+Q_sc	quickref.txt	/*Q_sc*
+Q_si	quickref.txt	/*Q_si*
+Q_ss	quickref.txt	/*Q_ss*
+Q_st	quickref.txt	/*Q_st*
+Q_sy	quickref.txt	/*Q_sy*
+Q_ta	quickref.txt	/*Q_ta*
+Q_tm	quickref.txt	/*Q_tm*
+Q_to	quickref.txt	/*Q_to*
+Q_ud	quickref.txt	/*Q_ud*
+Q_ur	quickref.txt	/*Q_ur*
+Q_vc	quickref.txt	/*Q_vc*
+Q_vi	quickref.txt	/*Q_vi*
+Q_vm	quickref.txt	/*Q_vm*
+Q_wi	quickref.txt	/*Q_wi*
+Q_wq	quickref.txt	/*Q_wq*
+QuickFixCmdPost	autocmd.txt	/*QuickFixCmdPost*
+QuickFixCmdPre	autocmd.txt	/*QuickFixCmdPre*
+Quickfix	quickfix.txt	/*Quickfix*
+R	change.txt	/*R*
+RISC-OS	os_risc.txt	/*RISC-OS*
+RISCOS	os_risc.txt	/*RISCOS*
+RemoteReply	autocmd.txt	/*RemoteReply*
+Replace	insert.txt	/*Replace*
+Replace-mode	insert.txt	/*Replace-mode*
+Root	mbyte.txt	/*Root*
+Ruby	if_ruby.txt	/*Ruby*
+Russian	russian.txt	/*Russian*
+S	change.txt	/*S*
+SHELL	starting.txt	/*SHELL*
+SQLSetType	sql.txt	/*SQLSetType*
+Select	visual.txt	/*Select*
+Select-mode	visual.txt	/*Select-mode*
+Select-mode-mapping	visual.txt	/*Select-mode-mapping*
+Session	starting.txt	/*Session*
+SessionLoad-variable	starting.txt	/*SessionLoad-variable*
+SessionLoadPost	autocmd.txt	/*SessionLoadPost*
+ShellCmdPost	autocmd.txt	/*ShellCmdPost*
+ShellFilterPost	autocmd.txt	/*ShellFilterPost*
+SourceCmd	autocmd.txt	/*SourceCmd*
+SourcePre	autocmd.txt	/*SourcePre*
+SpellFileMissing	autocmd.txt	/*SpellFileMissing*
+StdinReadPost	autocmd.txt	/*StdinReadPost*
+StdinReadPre	autocmd.txt	/*StdinReadPre*
+SwapExists	autocmd.txt	/*SwapExists*
+Syntax	autocmd.txt	/*Syntax*
+T	motion.txt	/*T*
+TCL	if_tcl.txt	/*TCL*
+TERM	starting.txt	/*TERM*
+TSQL	sql.txt	/*TSQL*
+TTpro-telnet	syntax.txt	/*TTpro-telnet*
+Tab	intro.txt	/*Tab*
+TabEnter	autocmd.txt	/*TabEnter*
+TabLeave	autocmd.txt	/*TabLeave*
+Tcl	if_tcl.txt	/*Tcl*
+TermChanged	autocmd.txt	/*TermChanged*
+TermResponse	autocmd.txt	/*TermResponse*
+Transact-SQL	sql.txt	/*Transact-SQL*
+U	undo.txt	/*U*
+UTF-8	mbyte.txt	/*UTF-8*
+UTF8-xterm	mbyte.txt	/*UTF8-xterm*
+Uganda	uganda.txt	/*Uganda*
+Unicode	mbyte.txt	/*Unicode*
+Unix	os_unix.txt	/*Unix*
+Unix-format	editing.txt	/*Unix-format*
+Unix-format-write	editing.txt	/*Unix-format-write*
+User	autocmd.txt	/*User*
+UserGettingBored	autocmd.txt	/*UserGettingBored*
+V	visual.txt	/*V*
+VIMINIT	starting.txt	/*VIMINIT*
+VMS	os_vms.txt	/*VMS*
+Vi	intro.txt	/*Vi*
+View	starting.txt	/*View*
+VimEnter	autocmd.txt	/*VimEnter*
+VimLeave	autocmd.txt	/*VimLeave*
+VimLeavePre	autocmd.txt	/*VimLeavePre*
+VimResized	autocmd.txt	/*VimResized*
+Vimball-copyright	pi_vimball.txt	/*Vimball-copyright*
+Virtual-Replace-mode	insert.txt	/*Virtual-Replace-mode*
+VisVim	if_ole.txt	/*VisVim*
+Visual	visual.txt	/*Visual*
+Visual-mode	visual.txt	/*Visual-mode*
+W	motion.txt	/*W*
+W10	message.txt	/*W10*
+W11	message.txt	/*W11*
+W12	message.txt	/*W12*
+W13	message.txt	/*W13*
+W14	message.txt	/*W14*
+W15	repeat.txt	/*W15*
+W16	message.txt	/*W16*
+W17	arabic.txt	/*W17*
+W18	syntax.txt	/*W18*
+WORD	motion.txt	/*WORD*
+WWW	intro.txt	/*WWW*
+Win32	os_win32.txt	/*Win32*
+WinEnter	autocmd.txt	/*WinEnter*
+WinLeave	autocmd.txt	/*WinLeave*
+X	change.txt	/*X*
+X11	options.txt	/*X11*
+X11-icon	gui_x11.txt	/*X11-icon*
+X11_mouse_shapes	gui_x11.txt	/*X11_mouse_shapes*
+X1Drag	term.txt	/*X1Drag*
+X1Mouse	term.txt	/*X1Mouse*
+X1Release	term.txt	/*X1Release*
+X2Drag	term.txt	/*X2Drag*
+X2Mouse	term.txt	/*X2Mouse*
+X2Release	term.txt	/*X2Release*
+XIM	mbyte.txt	/*XIM*
+XLFD	mbyte.txt	/*XLFD*
+Y	change.txt	/*Y*
+Y2K	intro.txt	/*Y2K*
+ZQ	editing.txt	/*ZQ*
+ZZ	editing.txt	/*ZZ*
+[	index.txt	/*[*
+[#	motion.txt	/*[#*
+['	motion.txt	/*['*
+[(	motion.txt	/*[(*
+[++opt]	editing.txt	/*[++opt]*
+[+cmd]	editing.txt	/*[+cmd]*
+[..]	pattern.txt	/*[..]*
+[/	motion.txt	/*[\/*
+[:alnum:]	pattern.txt	/*[:alnum:]*
+[:alpha:]	pattern.txt	/*[:alpha:]*
+[:backspace:]	pattern.txt	/*[:backspace:]*
+[:blank:]	pattern.txt	/*[:blank:]*
+[:cntrl:]	pattern.txt	/*[:cntrl:]*
+[:digit:]	pattern.txt	/*[:digit:]*
+[:escape:]	pattern.txt	/*[:escape:]*
+[:graph:]	pattern.txt	/*[:graph:]*
+[:lower:]	pattern.txt	/*[:lower:]*
+[:print:]	pattern.txt	/*[:print:]*
+[:punct:]	pattern.txt	/*[:punct:]*
+[:return:]	pattern.txt	/*[:return:]*
+[:space:]	pattern.txt	/*[:space:]*
+[:tab:]	pattern.txt	/*[:tab:]*
+[:upper:]	pattern.txt	/*[:upper:]*
+[:xdigit:]	pattern.txt	/*[:xdigit:]*
+[<MiddleMouse>	change.txt	/*[<MiddleMouse>*
+[==]	pattern.txt	/*[==]*
+[D	tagsrch.txt	/*[D*
+[I	tagsrch.txt	/*[I*
+[M	motion.txt	/*[M*
+[P	change.txt	/*[P*
+[S	spell.txt	/*[S*
+[[	motion.txt	/*[[*
+[]	motion.txt	/*[]*
+[_CTRL-D	tagsrch.txt	/*[_CTRL-D*
+[_CTRL-I	tagsrch.txt	/*[_CTRL-I*
+[`	motion.txt	/*[`*
+[c	diff.txt	/*[c*
+[count]	intro.txt	/*[count]*
+[d	tagsrch.txt	/*[d*
+[f	editing.txt	/*[f*
+[i	tagsrch.txt	/*[i*
+[m	motion.txt	/*[m*
+[p	change.txt	/*[p*
+[pattern]	pattern.txt	/*[pattern]*
+[quotex]	intro.txt	/*[quotex]*
+[range]	cmdline.txt	/*[range]*
+[s	spell.txt	/*[s*
+[star	motion.txt	/*[star*
+[z	fold.txt	/*[z*
+[{	motion.txt	/*[{*
+\0	change.txt	/*\\0*
+]	index.txt	/*]*
+]#	motion.txt	/*]#*
+]'	motion.txt	/*]'*
+])	motion.txt	/*])*
+]/	motion.txt	/*]\/*
+]<MiddleMouse>	change.txt	/*]<MiddleMouse>*
+]D	tagsrch.txt	/*]D*
+]I	tagsrch.txt	/*]I*
+]M	motion.txt	/*]M*
+]P	change.txt	/*]P*
+]S	spell.txt	/*]S*
+][	motion.txt	/*][*
+]]	motion.txt	/*]]*
+]_CTRL-D	tagsrch.txt	/*]_CTRL-D*
+]_CTRL-I	tagsrch.txt	/*]_CTRL-I*
+]`	motion.txt	/*]`*
+]c	diff.txt	/*]c*
+]d	tagsrch.txt	/*]d*
+]f	editing.txt	/*]f*
+]i	tagsrch.txt	/*]i*
+]m	motion.txt	/*]m*
+]p	change.txt	/*]p*
+]s	spell.txt	/*]s*
+]star	motion.txt	/*]star*
+]z	fold.txt	/*]z*
+]}	motion.txt	/*]}*
+^	motion.txt	/*^*
+_	motion.txt	/*_*
+_exrc	starting.txt	/*_exrc*
+_gvimrc	gui.txt	/*_gvimrc*
+_vimrc	starting.txt	/*_vimrc*
+`	motion.txt	/*`*
+`(	motion.txt	/*`(*
+`)	motion.txt	/*`)*
+`-expansion	editing.txt	/*`-expansion*
+`.	motion.txt	/*`.*
+`0	motion.txt	/*`0*
+`<	motion.txt	/*`<*
+`=	editing.txt	/*`=*
+`>	motion.txt	/*`>*
+`A	motion.txt	/*`A*
+`[	motion.txt	/*`[*
+`]	motion.txt	/*`]*
+`^	motion.txt	/*`^*
+``	motion.txt	/*``*
+`a	motion.txt	/*`a*
+`quote	motion.txt	/*`quote*
+`{	motion.txt	/*`{*
+`}	motion.txt	/*`}*
+a	insert.txt	/*a*
+a'	motion.txt	/*a'*
+a(	motion.txt	/*a(*
+a)	motion.txt	/*a)*
+a4	print.txt	/*a4*
+a:0	eval.txt	/*a:0*
+a:000	eval.txt	/*a:000*
+a:1	eval.txt	/*a:1*
+a:firstline	eval.txt	/*a:firstline*
+a:lastline	eval.txt	/*a:lastline*
+a:var	eval.txt	/*a:var*
+a<	motion.txt	/*a<*
+a>	motion.txt	/*a>*
+aB	motion.txt	/*aB*
+aW	motion.txt	/*aW*
+a[	motion.txt	/*a[*
+a]	motion.txt	/*a]*
+a`	motion.txt	/*a`*
+ab	motion.txt	/*ab*
+abandon	editing.txt	/*abandon*
+abbreviations	map.txt	/*abbreviations*
+abel.vim	syntax.txt	/*abel.vim*
+active-buffer	windows.txt	/*active-buffer*
+ada#Create_Tags()	ada.txt	/*ada#Create_Tags()*
+ada#Jump_Tag()	ada.txt	/*ada#Jump_Tag()*
+ada#Listtags()	ada.txt	/*ada#Listtags()*
+ada#Switch_Syntax_Option()	ada.txt	/*ada#Switch_Syntax_Option()*
+ada#Word()	ada.txt	/*ada#Word()*
+ada-compiler	ada.txt	/*ada-compiler*
+ada-ctags	ada.txt	/*ada-ctags*
+ada-extra-plugins	ada.txt	/*ada-extra-plugins*
+ada-reference	ada.txt	/*ada-reference*
+ada.txt	ada.txt	/*ada.txt*
+ada.vim	ada.txt	/*ada.vim*
+add()	eval.txt	/*add()*
+add-filetype-plugin	usr_05.txt	/*add-filetype-plugin*
+add-global-plugin	usr_05.txt	/*add-global-plugin*
+add-local-help	usr_05.txt	/*add-local-help*
+add-option-flags	options.txt	/*add-option-flags*
+add-plugin	usr_05.txt	/*add-plugin*
+added-5.1	version5.txt	/*added-5.1*
+added-5.2	version5.txt	/*added-5.2*
+added-5.3	version5.txt	/*added-5.3*
+added-5.4	version5.txt	/*added-5.4*
+added-5.5	version5.txt	/*added-5.5*
+added-5.6	version5.txt	/*added-5.6*
+added-5.7	version5.txt	/*added-5.7*
+added-5.8	version5.txt	/*added-5.8*
+added-6.1	version6.txt	/*added-6.1*
+added-6.2	version6.txt	/*added-6.2*
+added-6.3	version6.txt	/*added-6.3*
+added-6.4	version6.txt	/*added-6.4*
+added-7.1	version7.txt	/*added-7.1*
+added-BeOS	version5.txt	/*added-BeOS*
+added-Mac	version5.txt	/*added-Mac*
+added-VMS	version5.txt	/*added-VMS*
+added-cmdline-args	version5.txt	/*added-cmdline-args*
+added-options	version5.txt	/*added-options*
+added-regexp	version5.txt	/*added-regexp*
+added-various	version5.txt	/*added-various*
+added-win32-GUI	version5.txt	/*added-win32-GUI*
+aff-dic-format	spell.txt	/*aff-dic-format*
+after-directory	options.txt	/*after-directory*
+aleph	options.txt	/*aleph*
+alt	intro.txt	/*alt*
+alt-input	debugger.txt	/*alt-input*
+alternate-file	editing.txt	/*alternate-file*
+amiga-window	starting.txt	/*amiga-window*
+anonymous-function	eval.txt	/*anonymous-function*
+ant.vim	syntax.txt	/*ant.vim*
+ap	motion.txt	/*ap*
+apache.vim	syntax.txt	/*apache.vim*
+append()	eval.txt	/*append()*
+aquote	motion.txt	/*aquote*
+arabic.txt	arabic.txt	/*arabic.txt*
+arabicfonts	arabic.txt	/*arabicfonts*
+arabickeymap	arabic.txt	/*arabickeymap*
+argc()	eval.txt	/*argc()*
+argidx()	eval.txt	/*argidx()*
+arglist	editing.txt	/*arglist*
+arglist-position	editing.txt	/*arglist-position*
+arglist-quit	usr_07.txt	/*arglist-quit*
+argument-list	editing.txt	/*argument-list*
+argv()	eval.txt	/*argv()*
+as	motion.txt	/*as*
+asm.vim	syntax.txt	/*asm.vim*
+asm68k	syntax.txt	/*asm68k*
+asmh8300.vim	syntax.txt	/*asmh8300.vim*
+at	motion.txt	/*at*
+athena-intellimouse	gui.txt	/*athena-intellimouse*
+attr-list	syntax.txt	/*attr-list*
+author	intro.txt	/*author*
+auto-format	change.txt	/*auto-format*
+auto-setting	options.txt	/*auto-setting*
+auto-shortname	editing.txt	/*auto-shortname*
+autocmd-<>	tips.txt	/*autocmd-<>*
+autocmd-buffer-local	autocmd.txt	/*autocmd-buffer-local*
+autocmd-buflocal	autocmd.txt	/*autocmd-buflocal*
+autocmd-changes	autocmd.txt	/*autocmd-changes*
+autocmd-define	autocmd.txt	/*autocmd-define*
+autocmd-disable	autocmd.txt	/*autocmd-disable*
+autocmd-events	autocmd.txt	/*autocmd-events*
+autocmd-events-abc	autocmd.txt	/*autocmd-events-abc*
+autocmd-execute	autocmd.txt	/*autocmd-execute*
+autocmd-groups	autocmd.txt	/*autocmd-groups*
+autocmd-intro	autocmd.txt	/*autocmd-intro*
+autocmd-list	autocmd.txt	/*autocmd-list*
+autocmd-nested	autocmd.txt	/*autocmd-nested*
+autocmd-osfiletypes	filetype.txt	/*autocmd-osfiletypes*
+autocmd-patterns	autocmd.txt	/*autocmd-patterns*
+autocmd-remove	autocmd.txt	/*autocmd-remove*
+autocmd-searchpat	autocmd.txt	/*autocmd-searchpat*
+autocmd-use	autocmd.txt	/*autocmd-use*
+autocmd.txt	autocmd.txt	/*autocmd.txt*
+autocmds-kept	version5.txt	/*autocmds-kept*
+autocommand	autocmd.txt	/*autocommand*
+autocommand-events	autocmd.txt	/*autocommand-events*
+autocommand-pattern	autocmd.txt	/*autocommand-pattern*
+autoload	eval.txt	/*autoload*
+autoload-functions	eval.txt	/*autoload-functions*
+avoid-hit-enter	version5.txt	/*avoid-hit-enter*
+aw	motion.txt	/*aw*
+a{	motion.txt	/*a{*
+a}	motion.txt	/*a}*
+b	motion.txt	/*b*
+b:changedtick-variable	eval.txt	/*b:changedtick-variable*
+b:current_syntax-variable	syntax.txt	/*b:current_syntax-variable*
+b:netrw_lastfile	pi_netrw.txt	/*b:netrw_lastfile*
+b:var	eval.txt	/*b:var*
+baan-folding	syntax.txt	/*baan-folding*
+baan-syntax	syntax.txt	/*baan-syntax*
+baan.vim	syntax.txt	/*baan.vim*
+backslash	intro.txt	/*backslash*
+backspace	intro.txt	/*backspace*
+backspace-delete	version4.txt	/*backspace-delete*
+backtick-expansion	editing.txt	/*backtick-expansion*
+backup	editing.txt	/*backup*
+backup-changed	version4.txt	/*backup-changed*
+backup-extension	version4.txt	/*backup-extension*
+backup-table	editing.txt	/*backup-table*
+balloon-eval	debugger.txt	/*balloon-eval*
+bar	motion.txt	/*bar*
+bars	help.txt	/*bars*
+base_font_name_list	mbyte.txt	/*base_font_name_list*
+basic.vim	syntax.txt	/*basic.vim*
+beep	options.txt	/*beep*
+beos-colors	os_beos.txt	/*beos-colors*
+beos-compiling	os_beos.txt	/*beos-compiling*
+beos-dragndrop	os_beos.txt	/*beos-dragndrop*
+beos-fonts	os_beos.txt	/*beos-fonts*
+beos-general	os_beos.txt	/*beos-general*
+beos-gui	os_beos.txt	/*beos-gui*
+beos-launch	os_beos.txt	/*beos-launch*
+beos-meta	os_beos.txt	/*beos-meta*
+beos-mouse	os_beos.txt	/*beos-mouse*
+beos-perl	os_beos.txt	/*beos-perl*
+beos-timeout	os_beos.txt	/*beos-timeout*
+beos-unicode	os_beos.txt	/*beos-unicode*
+beos-utf8	os_beos.txt	/*beos-utf8*
+beos-vimdir	os_beos.txt	/*beos-vimdir*
+beval_bufnr-variable	eval.txt	/*beval_bufnr-variable*
+beval_col-variable	eval.txt	/*beval_col-variable*
+beval_lnum-variable	eval.txt	/*beval_lnum-variable*
+beval_text-variable	eval.txt	/*beval_text-variable*
+beval_winnr-variable	eval.txt	/*beval_winnr-variable*
+blockwise-examples	visual.txt	/*blockwise-examples*
+blockwise-operators	visual.txt	/*blockwise-operators*
+blockwise-register	change.txt	/*blockwise-register*
+blockwise-visual	visual.txt	/*blockwise-visual*
+bold	syntax.txt	/*bold*
+book	intro.txt	/*book*
+bookmark	usr_03.txt	/*bookmark*
+boolean	options.txt	/*boolean*
+break-finally	eval.txt	/*break-finally*
+browse()	eval.txt	/*browse()*
+browsedir()	eval.txt	/*browsedir()*
+browsefilter	editing.txt	/*browsefilter*
+bufexists()	eval.txt	/*bufexists()*
+buffer-hidden	windows.txt	/*buffer-hidden*
+buffer-list	windows.txt	/*buffer-list*
+buffer-variable	eval.txt	/*buffer-variable*
+buffer-write	editing.txt	/*buffer-write*
+buffer_exists()	eval.txt	/*buffer_exists()*
+buffer_name()	eval.txt	/*buffer_name()*
+buffer_number()	eval.txt	/*buffer_number()*
+buffers	windows.txt	/*buffers*
+buffers-menu	gui.txt	/*buffers-menu*
+buflisted()	eval.txt	/*buflisted()*
+bufloaded()	eval.txt	/*bufloaded()*
+bufname()	eval.txt	/*bufname()*
+bufnr()	eval.txt	/*bufnr()*
+bufwinnr()	eval.txt	/*bufwinnr()*
+bug-fixes-5	version5.txt	/*bug-fixes-5*
+bug-fixes-6	version6.txt	/*bug-fixes-6*
+bug-fixes-7	version7.txt	/*bug-fixes-7*
+bug-reports	intro.txt	/*bug-reports*
+bugreport.vim	intro.txt	/*bugreport.vim*
+bugs	intro.txt	/*bugs*
+builtin-terms	term.txt	/*builtin-terms*
+builtin-tools	gui.txt	/*builtin-tools*
+builtin_terms	term.txt	/*builtin_terms*
+byte-count	editing.txt	/*byte-count*
+byte2line()	eval.txt	/*byte2line()*
+byteidx()	eval.txt	/*byteidx()*
+bzip2	pi_gzip.txt	/*bzip2*
+c	change.txt	/*c*
+c.vim	syntax.txt	/*c.vim*
+cW	change.txt	/*cW*
+c_<BS>	cmdline.txt	/*c_<BS>*
+c_<C-Left>	cmdline.txt	/*c_<C-Left>*
+c_<C-R>	cmdline.txt	/*c_<C-R>*
+c_<C-R>_<C-A>	cmdline.txt	/*c_<C-R>_<C-A>*
+c_<C-R>_<C-F>	cmdline.txt	/*c_<C-R>_<C-F>*
+c_<C-R>_<C-O>	cmdline.txt	/*c_<C-R>_<C-O>*
+c_<C-R>_<C-P>	cmdline.txt	/*c_<C-R>_<C-P>*
+c_<C-R>_<C-R>	cmdline.txt	/*c_<C-R>_<C-R>*
+c_<C-R>_<C-W>	cmdline.txt	/*c_<C-R>_<C-W>*
+c_<C-Right>	cmdline.txt	/*c_<C-Right>*
+c_<CR>	cmdline.txt	/*c_<CR>*
+c_<Del>	cmdline.txt	/*c_<Del>*
+c_<Down>	cmdline.txt	/*c_<Down>*
+c_<End>	cmdline.txt	/*c_<End>*
+c_<Esc>	cmdline.txt	/*c_<Esc>*
+c_<Home>	cmdline.txt	/*c_<Home>*
+c_<Insert>	cmdline.txt	/*c_<Insert>*
+c_<Left>	cmdline.txt	/*c_<Left>*
+c_<LeftMouse>	cmdline.txt	/*c_<LeftMouse>*
+c_<NL>	cmdline.txt	/*c_<NL>*
+c_<PageDown>	cmdline.txt	/*c_<PageDown>*
+c_<PageUp>	cmdline.txt	/*c_<PageUp>*
+c_<Right>	cmdline.txt	/*c_<Right>*
+c_<S-Down>	cmdline.txt	/*c_<S-Down>*
+c_<S-Left>	cmdline.txt	/*c_<S-Left>*
+c_<S-Right>	cmdline.txt	/*c_<S-Right>*
+c_<S-Tab>	cmdline.txt	/*c_<S-Tab>*
+c_<S-Up>	cmdline.txt	/*c_<S-Up>*
+c_<Tab>	cmdline.txt	/*c_<Tab>*
+c_<Up>	cmdline.txt	/*c_<Up>*
+c_CTRL-A	cmdline.txt	/*c_CTRL-A*
+c_CTRL-B	cmdline.txt	/*c_CTRL-B*
+c_CTRL-C	cmdline.txt	/*c_CTRL-C*
+c_CTRL-D	cmdline.txt	/*c_CTRL-D*
+c_CTRL-E	cmdline.txt	/*c_CTRL-E*
+c_CTRL-H	cmdline.txt	/*c_CTRL-H*
+c_CTRL-I	cmdline.txt	/*c_CTRL-I*
+c_CTRL-J	cmdline.txt	/*c_CTRL-J*
+c_CTRL-K	cmdline.txt	/*c_CTRL-K*
+c_CTRL-L	cmdline.txt	/*c_CTRL-L*
+c_CTRL-N	cmdline.txt	/*c_CTRL-N*
+c_CTRL-P	cmdline.txt	/*c_CTRL-P*
+c_CTRL-Q	cmdline.txt	/*c_CTRL-Q*
+c_CTRL-R	cmdline.txt	/*c_CTRL-R*
+c_CTRL-R_=	cmdline.txt	/*c_CTRL-R_=*
+c_CTRL-R_CTRL-A	cmdline.txt	/*c_CTRL-R_CTRL-A*
+c_CTRL-R_CTRL-F	cmdline.txt	/*c_CTRL-R_CTRL-F*
+c_CTRL-R_CTRL-O	cmdline.txt	/*c_CTRL-R_CTRL-O*
+c_CTRL-R_CTRL-P	cmdline.txt	/*c_CTRL-R_CTRL-P*
+c_CTRL-R_CTRL-R	cmdline.txt	/*c_CTRL-R_CTRL-R*
+c_CTRL-R_CTRL-W	cmdline.txt	/*c_CTRL-R_CTRL-W*
+c_CTRL-U	cmdline.txt	/*c_CTRL-U*
+c_CTRL-V	cmdline.txt	/*c_CTRL-V*
+c_CTRL-W	cmdline.txt	/*c_CTRL-W*
+c_CTRL-Y	cmdline.txt	/*c_CTRL-Y*
+c_CTRL-\_CTRL-G	intro.txt	/*c_CTRL-\\_CTRL-G*
+c_CTRL-\_CTRL-N	intro.txt	/*c_CTRL-\\_CTRL-N*
+c_CTRL-\_e	cmdline.txt	/*c_CTRL-\\_e*
+c_CTRL-]	cmdline.txt	/*c_CTRL-]*
+c_CTRL-^	cmdline.txt	/*c_CTRL-^*
+c_CTRL-_	cmdline.txt	/*c_CTRL-_*
+c_digraph	cmdline.txt	/*c_digraph*
+c_wildchar	cmdline.txt	/*c_wildchar*
+call()	eval.txt	/*call()*
+carriage-return	intro.txt	/*carriage-return*
+case	change.txt	/*case*
+catch-all	eval.txt	/*catch-all*
+catch-errors	eval.txt	/*catch-errors*
+catch-interrupt	eval.txt	/*catch-interrupt*
+catch-order	eval.txt	/*catch-order*
+catch-text	eval.txt	/*catch-text*
+cc	change.txt	/*cc*
+ch.vim	syntax.txt	/*ch.vim*
+change-list-jumps	motion.txt	/*change-list-jumps*
+change-tabs	change.txt	/*change-tabs*
+change.txt	change.txt	/*change.txt*
+changed-5.1	version5.txt	/*changed-5.1*
+changed-5.2	version5.txt	/*changed-5.2*
+changed-5.3	version5.txt	/*changed-5.3*
+changed-5.4	version5.txt	/*changed-5.4*
+changed-5.5	version5.txt	/*changed-5.5*
+changed-5.6	version5.txt	/*changed-5.6*
+changed-5.7	version5.txt	/*changed-5.7*
+changed-5.8	version5.txt	/*changed-5.8*
+changed-6.1	version6.txt	/*changed-6.1*
+changed-6.2	version6.txt	/*changed-6.2*
+changed-6.3	version6.txt	/*changed-6.3*
+changed-6.4	version6.txt	/*changed-6.4*
+changed-7.1	version7.txt	/*changed-7.1*
+changelist	motion.txt	/*changelist*
+changelog.vim	syntax.txt	/*changelog.vim*
+changenr()	eval.txt	/*changenr()*
+changetick	eval.txt	/*changetick*
+changing	change.txt	/*changing*
+char-variable	eval.txt	/*char-variable*
+char2nr()	eval.txt	/*char2nr()*
+characterwise	motion.txt	/*characterwise*
+characterwise-register	change.txt	/*characterwise-register*
+characterwise-visual	visual.txt	/*characterwise-visual*
+charconvert_from-variable	eval.txt	/*charconvert_from-variable*
+charconvert_to-variable	eval.txt	/*charconvert_to-variable*
+charset	mbyte.txt	/*charset*
+charset-conversion	mbyte.txt	/*charset-conversion*
+chill.vim	syntax.txt	/*chill.vim*
+cindent()	eval.txt	/*cindent()*
+cinkeys-format	indent.txt	/*cinkeys-format*
+cinoptions-values	indent.txt	/*cinoptions-values*
+client-server	remote.txt	/*client-server*
+clientserver	remote.txt	/*clientserver*
+clipboard	gui.txt	/*clipboard*
+cmdarg-variable	eval.txt	/*cmdarg-variable*
+cmdbang-variable	eval.txt	/*cmdbang-variable*
+cmdline-arguments	vi_diff.txt	/*cmdline-arguments*
+cmdline-changed	version5.txt	/*cmdline-changed*
+cmdline-completion	cmdline.txt	/*cmdline-completion*
+cmdline-editing	cmdline.txt	/*cmdline-editing*
+cmdline-history	cmdline.txt	/*cmdline-history*
+cmdline-lines	cmdline.txt	/*cmdline-lines*
+cmdline-ranges	cmdline.txt	/*cmdline-ranges*
+cmdline-special	cmdline.txt	/*cmdline-special*
+cmdline-too-long	cmdline.txt	/*cmdline-too-long*
+cmdline-window	cmdline.txt	/*cmdline-window*
+cmdline.txt	cmdline.txt	/*cmdline.txt*
+cmdwin	cmdline.txt	/*cmdwin*
+cmdwin-char	cmdline.txt	/*cmdwin-char*
+cobol.vim	syntax.txt	/*cobol.vim*
+codeset	mbyte.txt	/*codeset*
+coding-style	develop.txt	/*coding-style*
+col()	eval.txt	/*col()*
+coldfusion.vim	syntax.txt	/*coldfusion.vim*
+collapse	tips.txt	/*collapse*
+color-xterm	syntax.txt	/*color-xterm*
+coloring	syntax.txt	/*coloring*
+colortest.vim	syntax.txt	/*colortest.vim*
+command-mode	intro.txt	/*command-mode*
+compatible-default	starting.txt	/*compatible-default*
+compile-changes-5	version5.txt	/*compile-changes-5*
+compile-changes-6	version6.txt	/*compile-changes-6*
+compile-changes-7	version7.txt	/*compile-changes-7*
+compiler-compaqada	ada.txt	/*compiler-compaqada*
+compiler-decada	ada.txt	/*compiler-decada*
+compiler-gcc	quickfix.txt	/*compiler-gcc*
+compiler-gnat	ada.txt	/*compiler-gnat*
+compiler-hpada	ada.txt	/*compiler-hpada*
+compiler-manx	quickfix.txt	/*compiler-manx*
+compiler-pyunit	quickfix.txt	/*compiler-pyunit*
+compiler-select	quickfix.txt	/*compiler-select*
+compiler-tex	quickfix.txt	/*compiler-tex*
+compiler-vaxada	ada.txt	/*compiler-vaxada*
+compl-current	insert.txt	/*compl-current*
+compl-define	insert.txt	/*compl-define*
+compl-dictionary	insert.txt	/*compl-dictionary*
+compl-filename	insert.txt	/*compl-filename*
+compl-function	insert.txt	/*compl-function*
+compl-generic	insert.txt	/*compl-generic*
+compl-keyword	insert.txt	/*compl-keyword*
+compl-omni	insert.txt	/*compl-omni*
+compl-omni-filetypes	insert.txt	/*compl-omni-filetypes*
+compl-spelling	insert.txt	/*compl-spelling*
+compl-tag	insert.txt	/*compl-tag*
+compl-vim	insert.txt	/*compl-vim*
+compl-whole-line	insert.txt	/*compl-whole-line*
+complete()	eval.txt	/*complete()*
+complete-functions	insert.txt	/*complete-functions*
+complete-items	insert.txt	/*complete-items*
+complete_CTRL-E	insert.txt	/*complete_CTRL-E*
+complete_CTRL-Y	insert.txt	/*complete_CTRL-Y*
+complete_add()	eval.txt	/*complete_add()*
+complete_check()	eval.txt	/*complete_check()*
+complex-change	change.txt	/*complex-change*
+complex-repeat	repeat.txt	/*complex-repeat*
+compress	pi_gzip.txt	/*compress*
+confirm()	eval.txt	/*confirm()*
+connection-refused	message.txt	/*connection-refused*
+console-menus	gui.txt	/*console-menus*
+control	intro.txt	/*control*
+conversion-server	mbyte.txt	/*conversion-server*
+convert-to-HTML	syntax.txt	/*convert-to-HTML*
+convert-to-XHTML	syntax.txt	/*convert-to-XHTML*
+convert-to-XML	syntax.txt	/*convert-to-XML*
+copy()	eval.txt	/*copy()*
+copy-diffs	diff.txt	/*copy-diffs*
+copy-move	change.txt	/*copy-move*
+copying	uganda.txt	/*copying*
+copyright	uganda.txt	/*copyright*
+count	intro.txt	/*count*
+count()	eval.txt	/*count()*
+count-bytes	tips.txt	/*count-bytes*
+count-items	tips.txt	/*count-items*
+count-variable	eval.txt	/*count-variable*
+count1-variable	eval.txt	/*count1-variable*
+cp-default	version5.txt	/*cp-default*
+cpo-!	options.txt	/*cpo-!*
+cpo-#	options.txt	/*cpo-#*
+cpo-$	options.txt	/*cpo-$*
+cpo-%	options.txt	/*cpo-%*
+cpo-&	options.txt	/*cpo-&*
+cpo-+	options.txt	/*cpo-+*
+cpo--	options.txt	/*cpo--*
+cpo-.	options.txt	/*cpo-.*
+cpo-/	options.txt	/*cpo-\/*
+cpo-<	options.txt	/*cpo-<*
+cpo->	options.txt	/*cpo->*
+cpo-A	options.txt	/*cpo-A*
+cpo-B	options.txt	/*cpo-B*
+cpo-C	options.txt	/*cpo-C*
+cpo-D	options.txt	/*cpo-D*
+cpo-E	options.txt	/*cpo-E*
+cpo-F	options.txt	/*cpo-F*
+cpo-H	options.txt	/*cpo-H*
+cpo-I	options.txt	/*cpo-I*
+cpo-J	options.txt	/*cpo-J*
+cpo-K	options.txt	/*cpo-K*
+cpo-L	options.txt	/*cpo-L*
+cpo-M	options.txt	/*cpo-M*
+cpo-O	options.txt	/*cpo-O*
+cpo-P	options.txt	/*cpo-P*
+cpo-R	options.txt	/*cpo-R*
+cpo-S	options.txt	/*cpo-S*
+cpo-W	options.txt	/*cpo-W*
+cpo-X	options.txt	/*cpo-X*
+cpo-Z	options.txt	/*cpo-Z*
+cpo-\	options.txt	/*cpo-\\*
+cpo-a	options.txt	/*cpo-a*
+cpo-b	options.txt	/*cpo-b*
+cpo-bar	options.txt	/*cpo-bar*
+cpo-c	options.txt	/*cpo-c*
+cpo-d	options.txt	/*cpo-d*
+cpo-e	options.txt	/*cpo-e*
+cpo-f	options.txt	/*cpo-f*
+cpo-g	options.txt	/*cpo-g*
+cpo-i	options.txt	/*cpo-i*
+cpo-j	options.txt	/*cpo-j*
+cpo-k	options.txt	/*cpo-k*
+cpo-l	options.txt	/*cpo-l*
+cpo-m	options.txt	/*cpo-m*
+cpo-n	options.txt	/*cpo-n*
+cpo-o	options.txt	/*cpo-o*
+cpo-p	options.txt	/*cpo-p*
+cpo-q	options.txt	/*cpo-q*
+cpo-r	options.txt	/*cpo-r*
+cpo-s	options.txt	/*cpo-s*
+cpo-star	options.txt	/*cpo-star*
+cpo-t	options.txt	/*cpo-t*
+cpo-u	options.txt	/*cpo-u*
+cpo-v	options.txt	/*cpo-v*
+cpo-w	options.txt	/*cpo-w*
+cpo-x	options.txt	/*cpo-x*
+cpo-y	options.txt	/*cpo-y*
+cpo-{	options.txt	/*cpo-{*
+crash-recovery	recover.txt	/*crash-recovery*
+creating-menus	gui.txt	/*creating-menus*
+credits	intro.txt	/*credits*
+crontab	options.txt	/*crontab*
+cs-find	if_cscop.txt	/*cs-find*
+cs7-problem	term.txt	/*cs7-problem*
+cscope	if_cscop.txt	/*cscope*
+cscope-commands	if_cscop.txt	/*cscope-commands*
+cscope-find	if_cscop.txt	/*cscope-find*
+cscope-howtouse	if_cscop.txt	/*cscope-howtouse*
+cscope-info	if_cscop.txt	/*cscope-info*
+cscope-intro	if_cscop.txt	/*cscope-intro*
+cscope-limitations	if_cscop.txt	/*cscope-limitations*
+cscope-options	if_cscop.txt	/*cscope-options*
+cscope-suggestions	if_cscop.txt	/*cscope-suggestions*
+cscope-win32	if_cscop.txt	/*cscope-win32*
+cscope_connection()	eval.txt	/*cscope_connection()*
+cscopepathcomp	if_cscop.txt	/*cscopepathcomp*
+cscopeprg	if_cscop.txt	/*cscopeprg*
+cscopequickfix	if_cscop.txt	/*cscopequickfix*
+cscopetag	if_cscop.txt	/*cscopetag*
+cscopetagorder	if_cscop.txt	/*cscopetagorder*
+cscopeverbose	if_cscop.txt	/*cscopeverbose*
+csh.vim	syntax.txt	/*csh.vim*
+cspc	if_cscop.txt	/*cspc*
+csprg	if_cscop.txt	/*csprg*
+csqf	if_cscop.txt	/*csqf*
+cst	if_cscop.txt	/*cst*
+csto	if_cscop.txt	/*csto*
+csverb	if_cscop.txt	/*csverb*
+ctags	tagsrch.txt	/*ctags*
+ctags-gone	version6.txt	/*ctags-gone*
+cterm-colors	syntax.txt	/*cterm-colors*
+ctrl	intro.txt	/*ctrl*
+ctype-variable	eval.txt	/*ctype-variable*
+curly-braces-function-names	eval.txt	/*curly-braces-function-names*
+curly-braces-names	eval.txt	/*curly-braces-names*
+curpos-visual	version6.txt	/*curpos-visual*
+current-directory	editing.txt	/*current-directory*
+current-file	editing.txt	/*current-file*
+current_compiler	quickfix.txt	/*current_compiler*
+cursor()	eval.txt	/*cursor()*
+cursor-blinking	options.txt	/*cursor-blinking*
+cursor-down	intro.txt	/*cursor-down*
+cursor-left	intro.txt	/*cursor-left*
+cursor-motions	motion.txt	/*cursor-motions*
+cursor-position	pattern.txt	/*cursor-position*
+cursor-right	intro.txt	/*cursor-right*
+cursor-up	intro.txt	/*cursor-up*
+cursor_down	intro.txt	/*cursor_down*
+cursor_left	intro.txt	/*cursor_left*
+cursor_right	intro.txt	/*cursor_right*
+cursor_up	intro.txt	/*cursor_up*
+cw	change.txt	/*cw*
+cweb.vim	syntax.txt	/*cweb.vim*
+cynlib.vim	syntax.txt	/*cynlib.vim*
+d	change.txt	/*d*
+daB	motion.txt	/*daB*
+daW	motion.txt	/*daW*
+dab	motion.txt	/*dab*
+dap	motion.txt	/*dap*
+das	motion.txt	/*das*
+dav	pi_netrw.txt	/*dav*
+daw	motion.txt	/*daw*
+dd	change.txt	/*dd*
+debug-gcc	debug.txt	/*debug-gcc*
+debug-highlight	debugger.txt	/*debug-highlight*
+debug-minidump	debug.txt	/*debug-minidump*
+debug-mode	repeat.txt	/*debug-mode*
+debug-scripts	repeat.txt	/*debug-scripts*
+debug-signs	debugger.txt	/*debug-signs*
+debug-vim	debug.txt	/*debug-vim*
+debug-vs2005	debug.txt	/*debug-vs2005*
+debug-win32	debug.txt	/*debug-win32*
+debug-windbg	debug.txt	/*debug-windbg*
+debug.txt	debug.txt	/*debug.txt*
+debugger-compilation	debugger.txt	/*debugger-compilation*
+debugger-features	debugger.txt	/*debugger-features*
+debugger-integration	debugger.txt	/*debugger-integration*
+debugger-support	debugger.txt	/*debugger-support*
+debugger.txt	debugger.txt	/*debugger.txt*
+dec-mouse	options.txt	/*dec-mouse*
+decada_members	ada.txt	/*decada_members*
+deepcopy()	eval.txt	/*deepcopy()*
+definition-search	tagsrch.txt	/*definition-search*
+definitions	intro.txt	/*definitions*
+delete()	eval.txt	/*delete()*
+delete-insert	change.txt	/*delete-insert*
+delete-menus	gui.txt	/*delete-menus*
+deleting	change.txt	/*deleting*
+design-assumptions	develop.txt	/*design-assumptions*
+design-compatible	develop.txt	/*design-compatible*
+design-decisions	develop.txt	/*design-decisions*
+design-documented	develop.txt	/*design-documented*
+design-flexible	develop.txt	/*design-flexible*
+design-goals	develop.txt	/*design-goals*
+design-improved	develop.txt	/*design-improved*
+design-maintain	develop.txt	/*design-maintain*
+design-multi-platform	develop.txt	/*design-multi-platform*
+design-not	develop.txt	/*design-not*
+design-speed-size	develop.txt	/*design-speed-size*
+desktop.vim	syntax.txt	/*desktop.vim*
+develop-spell	develop.txt	/*develop-spell*
+develop-spell-suggestions	develop.txt	/*develop-spell-suggestions*
+develop.txt	develop.txt	/*develop.txt*
+development	develop.txt	/*development*
+dh	change.txt	/*dh*
+diB	motion.txt	/*diB*
+diW	motion.txt	/*diW*
+dialog	gui_w32.txt	/*dialog*
+dialogs-added	version5.txt	/*dialogs-added*
+dib	motion.txt	/*dib*
+dict-identity	eval.txt	/*dict-identity*
+dict-modification	eval.txt	/*dict-modification*
+did_filetype()	eval.txt	/*did_filetype()*
+diff	diff.txt	/*diff*
+diff-diffexpr	diff.txt	/*diff-diffexpr*
+diff-mode	diff.txt	/*diff-mode*
+diff-options	diff.txt	/*diff-options*
+diff-original-file	diff.txt	/*diff-original-file*
+diff-patchexpr	diff.txt	/*diff-patchexpr*
+diff.txt	diff.txt	/*diff.txt*
+diff_filler()	eval.txt	/*diff_filler()*
+diff_hlID()	eval.txt	/*diff_hlID()*
+digraph-arg	change.txt	/*digraph-arg*
+digraph-encoding	digraph.txt	/*digraph-encoding*
+digraph-table	digraph.txt	/*digraph-table*
+digraph.txt	digraph.txt	/*digraph.txt*
+digraphs	digraph.txt	/*digraphs*
+digraphs-changed	version6.txt	/*digraphs-changed*
+digraphs-default	digraph.txt	/*digraphs-default*
+digraphs-define	digraph.txt	/*digraphs-define*
+digraphs-use	digraph.txt	/*digraphs-use*
+dip	motion.txt	/*dip*
+dircolors.vim	syntax.txt	/*dircolors.vim*
+dis	motion.txt	/*dis*
+disable-menus	gui.txt	/*disable-menus*
+distribute-script	usr_41.txt	/*distribute-script*
+distribution	intro.txt	/*distribution*
+diw	motion.txt	/*diw*
+dl	change.txt	/*dl*
+do	diff.txt	/*do*
+doc-file-list	help.txt	/*doc-file-list*
+docbk.vim	syntax.txt	/*docbk.vim*
+docbksgml.vim	syntax.txt	/*docbksgml.vim*
+docbkxml.vim	syntax.txt	/*docbkxml.vim*
+docbook	syntax.txt	/*docbook*
+documentation-6	version6.txt	/*documentation-6*
+donate	uganda.txt	/*donate*
+dos	os_dos.txt	/*dos*
+dos-:cd	os_dos.txt	/*dos-:cd*
+dos-CTRL-Break	os_dos.txt	/*dos-CTRL-Break*
+dos-backslash	os_dos.txt	/*dos-backslash*
+dos-colors	os_dos.txt	/*dos-colors*
+dos-file-formats	os_dos.txt	/*dos-file-formats*
+dos-locations	os_dos.txt	/*dos-locations*
+dos-shell	os_dos.txt	/*dos-shell*
+dos-standard-mappings	os_dos.txt	/*dos-standard-mappings*
+dos-temp-files	os_dos.txt	/*dos-temp-files*
+dos16	os_msdos.txt	/*dos16*
+dos32	os_msdos.txt	/*dos32*
+dosbatch.vim	syntax.txt	/*dosbatch.vim*
+double-click	term.txt	/*double-click*
+download	intro.txt	/*download*
+doxygen-syntax	syntax.txt	/*doxygen-syntax*
+doxygen.vim	syntax.txt	/*doxygen.vim*
+dp	diff.txt	/*dp*
+drag-n-drop	gui.txt	/*drag-n-drop*
+drag-n-drop-win32	gui_w32.txt	/*drag-n-drop-win32*
+drag-status-line	term.txt	/*drag-status-line*
+dtd.vim	syntax.txt	/*dtd.vim*
+dtd2vim	insert.txt	/*dtd2vim*
+dying-variable	eval.txt	/*dying-variable*
+e	motion.txt	/*e*
+easy	starting.txt	/*easy*
+edit-a-file	editing.txt	/*edit-a-file*
+edit-binary	editing.txt	/*edit-binary*
+edit-dialogs	editing.txt	/*edit-dialogs*
+edit-files	editing.txt	/*edit-files*
+edit-intro	editing.txt	/*edit-intro*
+edit-no-break	usr_25.txt	/*edit-no-break*
+editing.txt	editing.txt	/*editing.txt*
+efm-%>	quickfix.txt	/*efm-%>*
+efm-entries	quickfix.txt	/*efm-entries*
+efm-ignore	quickfix.txt	/*efm-ignore*
+eiffel.vim	syntax.txt	/*eiffel.vim*
+emacs-keys	tips.txt	/*emacs-keys*
+emacs-tags	tagsrch.txt	/*emacs-tags*
+emacs_tags	tagsrch.txt	/*emacs_tags*
+empty()	eval.txt	/*empty()*
+encoding-names	mbyte.txt	/*encoding-names*
+encoding-table	mbyte.txt	/*encoding-table*
+encoding-values	mbyte.txt	/*encoding-values*
+encryption	editing.txt	/*encryption*
+end	intro.txt	/*end*
+end-of-file	pattern.txt	/*end-of-file*
+enlightened-terminal	syntax.txt	/*enlightened-terminal*
+erlang.vim	syntax.txt	/*erlang.vim*
+errmsg-variable	eval.txt	/*errmsg-variable*
+error-file-format	quickfix.txt	/*error-file-format*
+error-messages	message.txt	/*error-messages*
+errorformat	quickfix.txt	/*errorformat*
+errorformat-Jikes	quickfix.txt	/*errorformat-Jikes*
+errorformat-LaTeX	quickfix.txt	/*errorformat-LaTeX*
+errorformat-Perl	quickfix.txt	/*errorformat-Perl*
+errorformat-ant	quickfix.txt	/*errorformat-ant*
+errorformat-changed	version4.txt	/*errorformat-changed*
+errorformat-jade	quickfix.txt	/*errorformat-jade*
+errorformat-javac	quickfix.txt	/*errorformat-javac*
+errorformat-multi-line	quickfix.txt	/*errorformat-multi-line*
+errorformat-separate-filename	quickfix.txt	/*errorformat-separate-filename*
+errorformats	quickfix.txt	/*errorformats*
+escape	intro.txt	/*escape*
+escape()	eval.txt	/*escape()*
+escape-bar	version4.txt	/*escape-bar*
+eval	eval.txt	/*eval*
+eval()	eval.txt	/*eval()*
+eval-examples	eval.txt	/*eval-examples*
+eval-sandbox	eval.txt	/*eval-sandbox*
+eval.txt	eval.txt	/*eval.txt*
+eventhandler()	eval.txt	/*eventhandler()*
+eview	starting.txt	/*eview*
+evim	starting.txt	/*evim*
+evim-keys	starting.txt	/*evim-keys*
+evim.vim	starting.txt	/*evim.vim*
+ex	starting.txt	/*ex*
+ex-cmd-index	index.txt	/*ex-cmd-index*
+ex-edit-index	index.txt	/*ex-edit-index*
+ex-flags	cmdline.txt	/*ex-flags*
+ex:	options.txt	/*ex:*
+except-autocmd	eval.txt	/*except-autocmd*
+except-autocmd-Cmd	eval.txt	/*except-autocmd-Cmd*
+except-autocmd-Post	eval.txt	/*except-autocmd-Post*
+except-autocmd-Pre	eval.txt	/*except-autocmd-Pre*
+except-autocmd-ill	eval.txt	/*except-autocmd-ill*
+except-compat	eval.txt	/*except-compat*
+except-examine	eval.txt	/*except-examine*
+except-from-finally	eval.txt	/*except-from-finally*
+except-hier-param	eval.txt	/*except-hier-param*
+except-several-errors	eval.txt	/*except-several-errors*
+except-single-line	eval.txt	/*except-single-line*
+except-syntax-err	eval.txt	/*except-syntax-err*
+except-syntax-error	eval.txt	/*except-syntax-error*
+exception-handling	eval.txt	/*exception-handling*
+exception-variable	eval.txt	/*exception-variable*
+exclusive	motion.txt	/*exclusive*
+exclusive-linewise	motion.txt	/*exclusive-linewise*
+executable()	eval.txt	/*executable()*
+execute-menus	gui.txt	/*execute-menus*
+exim	starting.txt	/*exim*
+exists()	eval.txt	/*exists()*
+expand()	eval.txt	/*expand()*
+expand-env	options.txt	/*expand-env*
+expand-environment-var	options.txt	/*expand-environment-var*
+expr	eval.txt	/*expr*
+expr-!	eval.txt	/*expr-!*
+expr-!=	eval.txt	/*expr-!=*
+expr-!=#	eval.txt	/*expr-!=#*
+expr-!=?	eval.txt	/*expr-!=?*
+expr-!~	eval.txt	/*expr-!~*
+expr-!~#	eval.txt	/*expr-!~#*
+expr-!~?	eval.txt	/*expr-!~?*
+expr-%	eval.txt	/*expr-%*
+expr-&&	eval.txt	/*expr-&&*
+expr-'	eval.txt	/*expr-'*
+expr-+	eval.txt	/*expr-+*
+expr--	eval.txt	/*expr--*
+expr-.	eval.txt	/*expr-.*
+expr-/	eval.txt	/*expr-\/*
+expr-<	eval.txt	/*expr-<*
+expr-<#	eval.txt	/*expr-<#*
+expr-<=	eval.txt	/*expr-<=*
+expr-<=#	eval.txt	/*expr-<=#*
+expr-<=?	eval.txt	/*expr-<=?*
+expr-<?	eval.txt	/*expr-<?*
+expr-==	eval.txt	/*expr-==*
+expr-==#	eval.txt	/*expr-==#*
+expr-==?	eval.txt	/*expr-==?*
+expr-=~	eval.txt	/*expr-=~*
+expr-=~#	eval.txt	/*expr-=~#*
+expr-=~?	eval.txt	/*expr-=~?*
+expr->	eval.txt	/*expr->*
+expr->#	eval.txt	/*expr->#*
+expr->=	eval.txt	/*expr->=*
+expr->=#	eval.txt	/*expr->=#*
+expr->=?	eval.txt	/*expr->=?*
+expr->?	eval.txt	/*expr->?*
+expr-[:]	eval.txt	/*expr-[:]*
+expr-[]	eval.txt	/*expr-[]*
+expr-barbar	eval.txt	/*expr-barbar*
+expr-entry	eval.txt	/*expr-entry*
+expr-env	eval.txt	/*expr-env*
+expr-env-expand	eval.txt	/*expr-env-expand*
+expr-function	eval.txt	/*expr-function*
+expr-is	eval.txt	/*expr-is*
+expr-nesting	eval.txt	/*expr-nesting*
+expr-number	eval.txt	/*expr-number*
+expr-option	eval.txt	/*expr-option*
+expr-quote	eval.txt	/*expr-quote*
+expr-register	eval.txt	/*expr-register*
+expr-star	eval.txt	/*expr-star*
+expr-string	eval.txt	/*expr-string*
+expr-unary-+	eval.txt	/*expr-unary-+*
+expr-unary--	eval.txt	/*expr-unary--*
+expr-variable	eval.txt	/*expr-variable*
+expr1	eval.txt	/*expr1*
+expr2	eval.txt	/*expr2*
+expr3	eval.txt	/*expr3*
+expr4	eval.txt	/*expr4*
+expr5	eval.txt	/*expr5*
+expr6	eval.txt	/*expr6*
+expr7	eval.txt	/*expr7*
+expr8	eval.txt	/*expr8*
+expr9	eval.txt	/*expr9*
+expression	eval.txt	/*expression*
+expression-commands	eval.txt	/*expression-commands*
+expression-syntax	eval.txt	/*expression-syntax*
+exrc	starting.txt	/*exrc*
+extend()	eval.txt	/*extend()*
+extension-removal	cmdline.txt	/*extension-removal*
+extensions-improvements	todo.txt	/*extensions-improvements*
+f	motion.txt	/*f*
+faq	intro.txt	/*faq*
+farsi	farsi.txt	/*farsi*
+farsi.txt	farsi.txt	/*farsi.txt*
+fasm.vim	syntax.txt	/*fasm.vim*
+fcs_choice-variable	eval.txt	/*fcs_choice-variable*
+fcs_reason-variable	eval.txt	/*fcs_reason-variable*
+feature-list	eval.txt	/*feature-list*
+feedkeys()	eval.txt	/*feedkeys()*
+fetch	pi_netrw.txt	/*fetch*
+file-browser-5.2	version5.txt	/*file-browser-5.2*
+file-formats	editing.txt	/*file-formats*
+file-pattern	autocmd.txt	/*file-pattern*
+file-read	insert.txt	/*file-read*
+file-searching	editing.txt	/*file-searching*
+file-type	filetype.txt	/*file-type*
+file-types	filetype.txt	/*file-types*
+file_readable()	eval.txt	/*file_readable()*
+fileencoding-changed	version6.txt	/*fileencoding-changed*
+filename-backslash	cmdline.txt	/*filename-backslash*
+filename-modifiers	cmdline.txt	/*filename-modifiers*
+filereadable()	eval.txt	/*filereadable()*
+filetype	filetype.txt	/*filetype*
+filetype-detect	filetype.txt	/*filetype-detect*
+filetype-ignore	filetype.txt	/*filetype-ignore*
+filetype-overrule	filetype.txt	/*filetype-overrule*
+filetype-plugin	usr_43.txt	/*filetype-plugin*
+filetype-plugins	filetype.txt	/*filetype-plugins*
+filetype.txt	filetype.txt	/*filetype.txt*
+filetypedetect-changed	version6.txt	/*filetypedetect-changed*
+filetypes	filetype.txt	/*filetypes*
+filewritable()	eval.txt	/*filewritable()*
+filter	change.txt	/*filter*
+filter()	eval.txt	/*filter()*
+find-manpage	usr_12.txt	/*find-manpage*
+find-replace	usr_10.txt	/*find-replace*
+finddir()	eval.txt	/*finddir()*
+findfile()	eval.txt	/*findfile()*
+fixed-5.1	version5.txt	/*fixed-5.1*
+fixed-5.2	version5.txt	/*fixed-5.2*
+fixed-5.3	version5.txt	/*fixed-5.3*
+fixed-5.4	version5.txt	/*fixed-5.4*
+fixed-5.5	version5.txt	/*fixed-5.5*
+fixed-5.6	version5.txt	/*fixed-5.6*
+fixed-5.7	version5.txt	/*fixed-5.7*
+fixed-5.8	version5.txt	/*fixed-5.8*
+fixed-6.1	version6.txt	/*fixed-6.1*
+fixed-6.2	version6.txt	/*fixed-6.2*
+fixed-6.3	version6.txt	/*fixed-6.3*
+fixed-6.4	version6.txt	/*fixed-6.4*
+fixed-7.1	version7.txt	/*fixed-7.1*
+flexwiki.vim	syntax.txt	/*flexwiki.vim*
+fname_diff-variable	eval.txt	/*fname_diff-variable*
+fname_in-variable	eval.txt	/*fname_in-variable*
+fname_new-variable	eval.txt	/*fname_new-variable*
+fname_out-variable	eval.txt	/*fname_out-variable*
+fnamemodify()	eval.txt	/*fnamemodify()*
+fo-table	change.txt	/*fo-table*
+fold-behavior	fold.txt	/*fold-behavior*
+fold-colors	fold.txt	/*fold-colors*
+fold-commands	fold.txt	/*fold-commands*
+fold-create-marker	fold.txt	/*fold-create-marker*
+fold-delete-marker	fold.txt	/*fold-delete-marker*
+fold-diff	fold.txt	/*fold-diff*
+fold-expr	fold.txt	/*fold-expr*
+fold-foldcolumn	fold.txt	/*fold-foldcolumn*
+fold-foldlevel	fold.txt	/*fold-foldlevel*
+fold-foldtext	fold.txt	/*fold-foldtext*
+fold-indent	fold.txt	/*fold-indent*
+fold-manual	fold.txt	/*fold-manual*
+fold-marker	fold.txt	/*fold-marker*
+fold-methods	fold.txt	/*fold-methods*
+fold-options	fold.txt	/*fold-options*
+fold-syntax	fold.txt	/*fold-syntax*
+fold.txt	fold.txt	/*fold.txt*
+foldclosed()	eval.txt	/*foldclosed()*
+foldclosedend()	eval.txt	/*foldclosedend()*
+folddashes-variable	eval.txt	/*folddashes-variable*
+foldend-variable	eval.txt	/*foldend-variable*
+folding	fold.txt	/*folding*
+foldlevel()	eval.txt	/*foldlevel()*
+foldlevel-variable	eval.txt	/*foldlevel-variable*
+foldstart-variable	eval.txt	/*foldstart-variable*
+foldtext()	eval.txt	/*foldtext()*
+foldtextresult()	eval.txt	/*foldtextresult()*
+font-sizes	gui_x11.txt	/*font-sizes*
+fontset	mbyte.txt	/*fontset*
+foreground()	eval.txt	/*foreground()*
+fork	os_unix.txt	/*fork*
+form.vim	syntax.txt	/*form.vim*
+format-bullet-list	tips.txt	/*format-bullet-list*
+format-comments	change.txt	/*format-comments*
+formatting	change.txt	/*formatting*
+formfeed	intro.txt	/*formfeed*
+fortran.vim	syntax.txt	/*fortran.vim*
+french-maillist	intro.txt	/*french-maillist*
+frombook	usr_01.txt	/*frombook*
+ft-abel-syntax	syntax.txt	/*ft-abel-syntax*
+ft-ada-commands	ada.txt	/*ft-ada-commands*
+ft-ada-constants	ada.txt	/*ft-ada-constants*
+ft-ada-functions	ada.txt	/*ft-ada-functions*
+ft-ada-indent	ada.txt	/*ft-ada-indent*
+ft-ada-omni	ada.txt	/*ft-ada-omni*
+ft-ada-options	ada.txt	/*ft-ada-options*
+ft-ada-plugin	ada.txt	/*ft-ada-plugin*
+ft-ada-syntax	ada.txt	/*ft-ada-syntax*
+ft-ada-variables	ada.txt	/*ft-ada-variables*
+ft-ant-syntax	syntax.txt	/*ft-ant-syntax*
+ft-apache-syntax	syntax.txt	/*ft-apache-syntax*
+ft-asm-syntax	syntax.txt	/*ft-asm-syntax*
+ft-asm68k-syntax	syntax.txt	/*ft-asm68k-syntax*
+ft-asmh8300-syntax	syntax.txt	/*ft-asmh8300-syntax*
+ft-aspperl-syntax	syntax.txt	/*ft-aspperl-syntax*
+ft-aspvbs-syntax	syntax.txt	/*ft-aspvbs-syntax*
+ft-bash-syntax	syntax.txt	/*ft-bash-syntax*
+ft-basic-syntax	syntax.txt	/*ft-basic-syntax*
+ft-c-omni	insert.txt	/*ft-c-omni*
+ft-c-syntax	syntax.txt	/*ft-c-syntax*
+ft-ch-syntax	syntax.txt	/*ft-ch-syntax*
+ft-changelog-plugin	filetype.txt	/*ft-changelog-plugin*
+ft-changelog-syntax	syntax.txt	/*ft-changelog-syntax*
+ft-chill-syntax	syntax.txt	/*ft-chill-syntax*
+ft-cobol-syntax	syntax.txt	/*ft-cobol-syntax*
+ft-coldfusion-syntax	syntax.txt	/*ft-coldfusion-syntax*
+ft-csh-syntax	syntax.txt	/*ft-csh-syntax*
+ft-css-omni	insert.txt	/*ft-css-omni*
+ft-cweb-syntax	syntax.txt	/*ft-cweb-syntax*
+ft-cynlib-syntax	syntax.txt	/*ft-cynlib-syntax*
+ft-desktop-syntax	syntax.txt	/*ft-desktop-syntax*
+ft-dircolors-syntax	syntax.txt	/*ft-dircolors-syntax*
+ft-docbk-syntax	syntax.txt	/*ft-docbk-syntax*
+ft-docbksgml-syntax	syntax.txt	/*ft-docbksgml-syntax*
+ft-docbkxml-syntax	syntax.txt	/*ft-docbkxml-syntax*
+ft-dosbatch-syntax	syntax.txt	/*ft-dosbatch-syntax*
+ft-dtd-syntax	syntax.txt	/*ft-dtd-syntax*
+ft-eiffel-syntax	syntax.txt	/*ft-eiffel-syntax*
+ft-erlang-syntax	syntax.txt	/*ft-erlang-syntax*
+ft-flexwiki-syntax	syntax.txt	/*ft-flexwiki-syntax*
+ft-form-syntax	syntax.txt	/*ft-form-syntax*
+ft-fortran-indent	indent.txt	/*ft-fortran-indent*
+ft-fortran-plugin	filetype.txt	/*ft-fortran-plugin*
+ft-fortran-syntax	syntax.txt	/*ft-fortran-syntax*
+ft-fvwm-syntax	syntax.txt	/*ft-fvwm-syntax*
+ft-groff-syntax	syntax.txt	/*ft-groff-syntax*
+ft-gsp-syntax	syntax.txt	/*ft-gsp-syntax*
+ft-haskell-syntax	syntax.txt	/*ft-haskell-syntax*
+ft-html-omni	insert.txt	/*ft-html-omni*
+ft-html-syntax	syntax.txt	/*ft-html-syntax*
+ft-htmlos-syntax	syntax.txt	/*ft-htmlos-syntax*
+ft-ia64-syntax	syntax.txt	/*ft-ia64-syntax*
+ft-inform-syntax	syntax.txt	/*ft-inform-syntax*
+ft-java-syntax	syntax.txt	/*ft-java-syntax*
+ft-javascript-omni	insert.txt	/*ft-javascript-omni*
+ft-ksh-syntax	syntax.txt	/*ft-ksh-syntax*
+ft-lace-syntax	syntax.txt	/*ft-lace-syntax*
+ft-lex-syntax	syntax.txt	/*ft-lex-syntax*
+ft-lisp-syntax	syntax.txt	/*ft-lisp-syntax*
+ft-lite-syntax	syntax.txt	/*ft-lite-syntax*
+ft-lpc-syntax	syntax.txt	/*ft-lpc-syntax*
+ft-lua-syntax	syntax.txt	/*ft-lua-syntax*
+ft-mail-plugin	filetype.txt	/*ft-mail-plugin*
+ft-mail.vim	syntax.txt	/*ft-mail.vim*
+ft-make-syntax	syntax.txt	/*ft-make-syntax*
+ft-man-plugin	filetype.txt	/*ft-man-plugin*
+ft-maple-syntax	syntax.txt	/*ft-maple-syntax*
+ft-masm-syntax	syntax.txt	/*ft-masm-syntax*
+ft-mathematica-syntax	syntax.txt	/*ft-mathematica-syntax*
+ft-mma-syntax	syntax.txt	/*ft-mma-syntax*
+ft-moo-syntax	syntax.txt	/*ft-moo-syntax*
+ft-msql-syntax	syntax.txt	/*ft-msql-syntax*
+ft-nasm-syntax	syntax.txt	/*ft-nasm-syntax*
+ft-ncf-syntax	syntax.txt	/*ft-ncf-syntax*
+ft-nroff-syntax	syntax.txt	/*ft-nroff-syntax*
+ft-ocaml-syntax	syntax.txt	/*ft-ocaml-syntax*
+ft-papp-syntax	syntax.txt	/*ft-papp-syntax*
+ft-pascal-syntax	syntax.txt	/*ft-pascal-syntax*
+ft-perl-syntax	syntax.txt	/*ft-perl-syntax*
+ft-php-omni	insert.txt	/*ft-php-omni*
+ft-php-syntax	syntax.txt	/*ft-php-syntax*
+ft-php3-syntax	syntax.txt	/*ft-php3-syntax*
+ft-phtml-syntax	syntax.txt	/*ft-phtml-syntax*
+ft-plaintex-syntax	syntax.txt	/*ft-plaintex-syntax*
+ft-postscr-syntax	syntax.txt	/*ft-postscr-syntax*
+ft-ppwiz-syntax	syntax.txt	/*ft-ppwiz-syntax*
+ft-printcap-syntax	syntax.txt	/*ft-printcap-syntax*
+ft-progress-syntax	syntax.txt	/*ft-progress-syntax*
+ft-ptcap-syntax	syntax.txt	/*ft-ptcap-syntax*
+ft-python-indent	indent.txt	/*ft-python-indent*
+ft-python-syntax	syntax.txt	/*ft-python-syntax*
+ft-quake-syntax	syntax.txt	/*ft-quake-syntax*
+ft-readline-syntax	syntax.txt	/*ft-readline-syntax*
+ft-rexx-syntax	syntax.txt	/*ft-rexx-syntax*
+ft-ruby-omni	insert.txt	/*ft-ruby-omni*
+ft-ruby-syntax	syntax.txt	/*ft-ruby-syntax*
+ft-scheme-syntax	syntax.txt	/*ft-scheme-syntax*
+ft-sdl-syntax	syntax.txt	/*ft-sdl-syntax*
+ft-sed-syntax	syntax.txt	/*ft-sed-syntax*
+ft-sgml-syntax	syntax.txt	/*ft-sgml-syntax*
+ft-sh-indent	indent.txt	/*ft-sh-indent*
+ft-sh-syntax	syntax.txt	/*ft-sh-syntax*
+ft-spec-plugin	filetype.txt	/*ft-spec-plugin*
+ft-spup-syntax	syntax.txt	/*ft-spup-syntax*
+ft-sql	filetype.txt	/*ft-sql*
+ft-sql-omni	insert.txt	/*ft-sql-omni*
+ft-sql-syntax	syntax.txt	/*ft-sql-syntax*
+ft-sqlanywhere-syntax	syntax.txt	/*ft-sqlanywhere-syntax*
+ft-sqlinformix-syntax	syntax.txt	/*ft-sqlinformix-syntax*
+ft-syntax-omni	insert.txt	/*ft-syntax-omni*
+ft-tcsh-syntax	syntax.txt	/*ft-tcsh-syntax*
+ft-termcap-syntax	syntax.txt	/*ft-termcap-syntax*
+ft-tex-plugin	filetype.txt	/*ft-tex-plugin*
+ft-tex-syntax	syntax.txt	/*ft-tex-syntax*
+ft-tf-syntax	syntax.txt	/*ft-tf-syntax*
+ft-vb-syntax	syntax.txt	/*ft-vb-syntax*
+ft-verilog-indent	indent.txt	/*ft-verilog-indent*
+ft-vim-indent	indent.txt	/*ft-vim-indent*
+ft-vim-syntax	syntax.txt	/*ft-vim-syntax*
+ft-xf86conf-syntax	syntax.txt	/*ft-xf86conf-syntax*
+ft-xhtml-omni	insert.txt	/*ft-xhtml-omni*
+ft-xml-omni	insert.txt	/*ft-xml-omni*
+ft-xml-syntax	syntax.txt	/*ft-xml-syntax*
+ft-xpm-syntax	syntax.txt	/*ft-xpm-syntax*
+ftdetect	filetype.txt	/*ftdetect*
+ftp	pi_netrw.txt	/*ftp*
+ftplugin	usr_41.txt	/*ftplugin*
+ftplugin-docs	filetype.txt	/*ftplugin-docs*
+ftplugin-name	usr_05.txt	/*ftplugin-name*
+ftplugin-overrule	filetype.txt	/*ftplugin-overrule*
+ftplugin-special	usr_41.txt	/*ftplugin-special*
+ftplugins	usr_05.txt	/*ftplugins*
+function()	eval.txt	/*function()*
+function-argument	eval.txt	/*function-argument*
+function-key	intro.txt	/*function-key*
+function-list	usr_41.txt	/*function-list*
+function-range-example	eval.txt	/*function-range-example*
+function_key	intro.txt	/*function_key*
+functions	eval.txt	/*functions*
+fvwm.vim	syntax.txt	/*fvwm.vim*
+fvwm2rc	syntax.txt	/*fvwm2rc*
+fvwmrc	syntax.txt	/*fvwmrc*
+g	index.txt	/*g*
+g#	pattern.txt	/*g#*
+g$	motion.txt	/*g$*
+g&	change.txt	/*g&*
+g'	motion.txt	/*g'*
+g'a	motion.txt	/*g'a*
+g+	undo.txt	/*g+*
+g,	motion.txt	/*g,*
+g-	undo.txt	/*g-*
+g0	motion.txt	/*g0*
+g8	various.txt	/*g8*
+g:NetrwTopLvlMenu	pi_netrw.txt	/*g:NetrwTopLvlMenu*
+g:ada#Comment	ada.txt	/*g:ada#Comment*
+g:ada#Ctags_Kinds	ada.txt	/*g:ada#Ctags_Kinds*
+g:ada#DotWordRegex	ada.txt	/*g:ada#DotWordRegex*
+g:ada#Keywords	ada.txt	/*g:ada#Keywords*
+g:ada#WordRegex	ada.txt	/*g:ada#WordRegex*
+g:ada_abbrev	ada.txt	/*g:ada_abbrev*
+g:ada_all_tab_usage	ada.txt	/*g:ada_all_tab_usage*
+g:ada_begin_preproc	ada.txt	/*g:ada_begin_preproc*
+g:ada_default_compiler	ada.txt	/*g:ada_default_compiler*
+g:ada_extended_completion	ada.txt	/*g:ada_extended_completion*
+g:ada_extended_tagging	ada.txt	/*g:ada_extended_tagging*
+g:ada_folding	ada.txt	/*g:ada_folding*
+g:ada_gnat_extensions	ada.txt	/*g:ada_gnat_extensions*
+g:ada_line_errors	ada.txt	/*g:ada_line_errors*
+g:ada_no_tab_space_error	ada.txt	/*g:ada_no_tab_space_error*
+g:ada_no_trail_space_error	ada.txt	/*g:ada_no_trail_space_error*
+g:ada_omni_with_keywords	ada.txt	/*g:ada_omni_with_keywords*
+g:ada_rainbow_color	ada.txt	/*g:ada_rainbow_color*
+g:ada_space_errors	ada.txt	/*g:ada_space_errors*
+g:ada_standard_types	ada.txt	/*g:ada_standard_types*
+g:ada_with_gnat_project_files	ada.txt	/*g:ada_with_gnat_project_files*
+g:ada_withuse_ordinary	ada.txt	/*g:ada_withuse_ordinary*
+g:decada	ada.txt	/*g:decada*
+g:decada.Error_Format	ada.txt	/*g:decada.Error_Format*
+g:decada.Make()	ada.txt	/*g:decada.Make()*
+g:decada.Make_Command	ada.txt	/*g:decada.Make_Command*
+g:decada.Unit_Name()	ada.txt	/*g:decada.Unit_Name()*
+g:gnat	ada.txt	/*g:gnat*
+g:gnat.Error_Format	ada.txt	/*g:gnat.Error_Format*
+g:gnat.Find()	ada.txt	/*g:gnat.Find()*
+g:gnat.Find_Program	ada.txt	/*g:gnat.Find_Program*
+g:gnat.Make()	ada.txt	/*g:gnat.Make()*
+g:gnat.Make_Command	ada.txt	/*g:gnat.Make_Command*
+g:gnat.Pretty()	ada.txt	/*g:gnat.Pretty()*
+g:gnat.Pretty_Program	ada.txt	/*g:gnat.Pretty_Program*
+g:gnat.Project_File	ada.txt	/*g:gnat.Project_File*
+g:gnat.Set_Project_File()	ada.txt	/*g:gnat.Set_Project_File()*
+g:gnat.Tags()	ada.txt	/*g:gnat.Tags()*
+g:gnat.Tags_Command	ada.txt	/*g:gnat.Tags_Command*
+g:netrw_alto	pi_netrw.txt	/*g:netrw_alto*
+g:netrw_altv	pi_netrw.txt	/*g:netrw_altv*
+g:netrw_browse_split	pi_netrw.txt	/*g:netrw_browse_split*
+g:netrw_browsex_viewer	pi_netrw.txt	/*g:netrw_browsex_viewer*
+g:netrw_cygwin	pi_netrw.txt	/*g:netrw_cygwin*
+g:netrw_dav_cmd	pi_netrw.txt	/*g:netrw_dav_cmd*
+g:netrw_extracmd	pi_netrw.txt	/*g:netrw_extracmd*
+g:netrw_fastbrowse	pi_netrw.txt	/*g:netrw_fastbrowse*
+g:netrw_fetch_cmd	pi_netrw.txt	/*g:netrw_fetch_cmd*
+g:netrw_ftp	pi_netrw.txt	/*g:netrw_ftp*
+g:netrw_ftp_browse_reject	pi_netrw.txt	/*g:netrw_ftp_browse_reject*
+g:netrw_ftp_cmd	pi_netrw.txt	/*g:netrw_ftp_cmd*
+g:netrw_ftp_list_cmd	pi_netrw.txt	/*g:netrw_ftp_list_cmd*
+g:netrw_ftp_sizelist_cmd	pi_netrw.txt	/*g:netrw_ftp_sizelist_cmd*
+g:netrw_ftp_timelist_cmd	pi_netrw.txt	/*g:netrw_ftp_timelist_cmd*
+g:netrw_ftpmode	pi_netrw.txt	/*g:netrw_ftpmode*
+g:netrw_hide	pi_netrw.txt	/*g:netrw_hide*
+g:netrw_http_cmd	pi_netrw.txt	/*g:netrw_http_cmd*
+g:netrw_ignorenetrc	pi_netrw.txt	/*g:netrw_ignorenetrc*
+g:netrw_keepdir	pi_netrw.txt	/*g:netrw_keepdir*
+g:netrw_list_cmd	pi_netrw.txt	/*g:netrw_list_cmd*
+g:netrw_list_hide	pi_netrw.txt	/*g:netrw_list_hide*
+g:netrw_liststyle	pi_netrw.txt	/*g:netrw_liststyle*
+g:netrw_local_mkdir	pi_netrw.txt	/*g:netrw_local_mkdir*
+g:netrw_local_rmdir	pi_netrw.txt	/*g:netrw_local_rmdir*
+g:netrw_maxfilenamelen	pi_netrw.txt	/*g:netrw_maxfilenamelen*
+g:netrw_menu	pi_netrw.txt	/*g:netrw_menu*
+g:netrw_mkdir_cmd	pi_netrw.txt	/*g:netrw_mkdir_cmd*
+g:netrw_nogx	pi_netrw.txt	/*g:netrw_nogx*
+g:netrw_passwd	pi_netrw.txt	/*g:netrw_passwd*
+g:netrw_rcp_cmd	pi_netrw.txt	/*g:netrw_rcp_cmd*
+g:netrw_rm_cmd	pi_netrw.txt	/*g:netrw_rm_cmd*
+g:netrw_rmdir_cmd	pi_netrw.txt	/*g:netrw_rmdir_cmd*
+g:netrw_rmf_cmd	pi_netrw.txt	/*g:netrw_rmf_cmd*
+g:netrw_rsync_cmd	pi_netrw.txt	/*g:netrw_rsync_cmd*
+g:netrw_scp_cmd	pi_netrw.txt	/*g:netrw_scp_cmd*
+g:netrw_scpport	pi_netrw.txt	/*g:netrw_scpport*
+g:netrw_sftp_cmd	pi_netrw.txt	/*g:netrw_sftp_cmd*
+g:netrw_shq	pi_netrw.txt	/*g:netrw_shq*
+g:netrw_sort_by	pi_netrw.txt	/*g:netrw_sort_by*
+g:netrw_sort_direction	pi_netrw.txt	/*g:netrw_sort_direction*
+g:netrw_sort_sequence	pi_netrw.txt	/*g:netrw_sort_sequence*
+g:netrw_ssh_browse_reject	pi_netrw.txt	/*g:netrw_ssh_browse_reject*
+g:netrw_ssh_cmd	pi_netrw.txt	/*g:netrw_ssh_cmd*
+g:netrw_sshport	pi_netrw.txt	/*g:netrw_sshport*
+g:netrw_timefmt	pi_netrw.txt	/*g:netrw_timefmt*
+g:netrw_uid	pi_netrw.txt	/*g:netrw_uid*
+g:netrw_use_errorwindow	pi_netrw.txt	/*g:netrw_use_errorwindow*
+g:netrw_use_noswf	pi_netrw.txt	/*g:netrw_use_noswf*
+g:netrw_use_nt_rcp	pi_netrw.txt	/*g:netrw_use_nt_rcp*
+g:netrw_win95ftp	pi_netrw.txt	/*g:netrw_win95ftp*
+g:netrw_winsize	pi_netrw.txt	/*g:netrw_winsize*
+g:tar_browseoptions	pi_tar.txt	/*g:tar_browseoptions*
+g:tar_cmd	pi_tar.txt	/*g:tar_cmd*
+g:tar_readoptions	pi_tar.txt	/*g:tar_readoptions*
+g:tar_writeoptions	pi_tar.txt	/*g:tar_writeoptions*
+g:var	eval.txt	/*g:var*
+g:vimball_home	pi_vimball.txt	/*g:vimball_home*
+g:zip_unzipcmd	pi_zip.txt	/*g:zip_unzipcmd*
+g:zip_zipcmd	pi_zip.txt	/*g:zip_zipcmd*
+g;	motion.txt	/*g;*
+g<	message.txt	/*g<*
+g<Down>	motion.txt	/*g<Down>*
+g<End>	motion.txt	/*g<End>*
+g<Home>	motion.txt	/*g<Home>*
+g<LeftMouse>	tagsrch.txt	/*g<LeftMouse>*
+g<RightMouse>	tagsrch.txt	/*g<RightMouse>*
+g<Up>	motion.txt	/*g<Up>*
+g?	change.txt	/*g?*
+g??	change.txt	/*g??*
+g?g?	change.txt	/*g?g?*
+g@	map.txt	/*g@*
+gD	pattern.txt	/*gD*
+gE	motion.txt	/*gE*
+gF	editing.txt	/*gF*
+gH	visual.txt	/*gH*
+gI	insert.txt	/*gI*
+gJ	change.txt	/*gJ*
+gP	change.txt	/*gP*
+gQ	intro.txt	/*gQ*
+gR	change.txt	/*gR*
+gT	tabpage.txt	/*gT*
+gU	change.txt	/*gU*
+gUU	change.txt	/*gUU*
+gUgU	change.txt	/*gUgU*
+gV	visual.txt	/*gV*
+g]	tagsrch.txt	/*g]*
+g^	motion.txt	/*g^*
+g_	motion.txt	/*g_*
+g_CTRL-A	various.txt	/*g_CTRL-A*
+g_CTRL-G	editing.txt	/*g_CTRL-G*
+g_CTRL-H	visual.txt	/*g_CTRL-H*
+g_CTRL-]	tagsrch.txt	/*g_CTRL-]*
+g`	motion.txt	/*g`*
+g`a	motion.txt	/*g`a*
+ga	various.txt	/*ga*
+garbagecollect()	eval.txt	/*garbagecollect()*
+gd	pattern.txt	/*gd*
+ge	motion.txt	/*ge*
+get()	eval.txt	/*get()*
+get-ms-debuggers	debug.txt	/*get-ms-debuggers*
+getbufline()	eval.txt	/*getbufline()*
+getbufvar()	eval.txt	/*getbufvar()*
+getchar()	eval.txt	/*getchar()*
+getcharmod()	eval.txt	/*getcharmod()*
+getcmdline()	eval.txt	/*getcmdline()*
+getcmdpos()	eval.txt	/*getcmdpos()*
+getcmdtype()	eval.txt	/*getcmdtype()*
+getcwd()	eval.txt	/*getcwd()*
+getfontname()	eval.txt	/*getfontname()*
+getfperm()	eval.txt	/*getfperm()*
+getfsize()	eval.txt	/*getfsize()*
+getftime()	eval.txt	/*getftime()*
+getftype()	eval.txt	/*getftype()*
+getlatestvimscripts-install	pi_getscript.txt	/*getlatestvimscripts-install*
+getline()	eval.txt	/*getline()*
+getloclist()	eval.txt	/*getloclist()*
+getpos()	eval.txt	/*getpos()*
+getqflist()	eval.txt	/*getqflist()*
+getreg()	eval.txt	/*getreg()*
+getregtype()	eval.txt	/*getregtype()*
+getscript	pi_getscript.txt	/*getscript*
+getscript-autoinstall	pi_getscript.txt	/*getscript-autoinstall*
+getscript-data	pi_getscript.txt	/*getscript-data*
+getscript-history	pi_getscript.txt	/*getscript-history*
+getscript-plugins	pi_getscript.txt	/*getscript-plugins*
+getscript-start	pi_getscript.txt	/*getscript-start*
+gettabwinvar()	eval.txt	/*gettabwinvar()*
+getwinposx()	eval.txt	/*getwinposx()*
+getwinposy()	eval.txt	/*getwinposy()*
+getwinvar()	eval.txt	/*getwinvar()*
+gex	starting.txt	/*gex*
+gf	editing.txt	/*gf*
+gg	motion.txt	/*gg*
+gh	visual.txt	/*gh*
+gi	insert.txt	/*gi*
+gj	motion.txt	/*gj*
+gk	motion.txt	/*gk*
+glob()	eval.txt	/*glob()*
+global-ime	mbyte.txt	/*global-ime*
+global-local	options.txt	/*global-local*
+global-variable	eval.txt	/*global-variable*
+globpath()	eval.txt	/*globpath()*
+glvs	pi_getscript.txt	/*glvs*
+glvs-alg	pi_getscript.txt	/*glvs-alg*
+glvs-algorithm	pi_getscript.txt	/*glvs-algorithm*
+glvs-autoinstall	pi_getscript.txt	/*glvs-autoinstall*
+glvs-contents	pi_getscript.txt	/*glvs-contents*
+glvs-copyright	pi_getscript.txt	/*glvs-copyright*
+glvs-data	pi_getscript.txt	/*glvs-data*
+glvs-dist-install	pi_getscript.txt	/*glvs-dist-install*
+glvs-hist	pi_getscript.txt	/*glvs-hist*
+glvs-install	pi_getscript.txt	/*glvs-install*
+glvs-options	pi_getscript.txt	/*glvs-options*
+glvs-plugins	pi_getscript.txt	/*glvs-plugins*
+glvs-usage	pi_getscript.txt	/*glvs-usage*
+gm	motion.txt	/*gm*
+gnat#Insert_Tags_Header()	ada.txt	/*gnat#Insert_Tags_Header()*
+gnat#New()	ada.txt	/*gnat#New()*
+gnat-xref	ada.txt	/*gnat-xref*
+gnat_members	ada.txt	/*gnat_members*
+gnome-session	gui_x11.txt	/*gnome-session*
+go	motion.txt	/*go*
+gp	change.txt	/*gp*
+gpm-mouse	term.txt	/*gpm-mouse*
+gq	change.txt	/*gq*
+gqap	change.txt	/*gqap*
+gqgq	change.txt	/*gqgq*
+gqq	change.txt	/*gqq*
+gr	change.txt	/*gr*
+graphic-option-gone	version4.txt	/*graphic-option-gone*
+greek	options.txt	/*greek*
+grep	quickfix.txt	/*grep*
+groff.vim	syntax.txt	/*groff.vim*
+group-name	syntax.txt	/*group-name*
+gs	various.txt	/*gs*
+gsp.vim	syntax.txt	/*gsp.vim*
+gstar	pattern.txt	/*gstar*
+gt	tabpage.txt	/*gt*
+gtk-tooltip-colors	gui_x11.txt	/*gtk-tooltip-colors*
+gu	change.txt	/*gu*
+gugu	change.txt	/*gugu*
+gui	gui.txt	/*gui*
+gui-clipboard	gui_w32.txt	/*gui-clipboard*
+gui-colors	syntax.txt	/*gui-colors*
+gui-extras	gui.txt	/*gui-extras*
+gui-footer	debugger.txt	/*gui-footer*
+gui-fork	gui_x11.txt	/*gui-fork*
+gui-gnome	gui_x11.txt	/*gui-gnome*
+gui-gnome-session	gui_x11.txt	/*gui-gnome-session*
+gui-gtk	gui_x11.txt	/*gui-gtk*
+gui-gtk-socketid	gui_x11.txt	/*gui-gtk-socketid*
+gui-horiz-scroll	gui.txt	/*gui-horiz-scroll*
+gui-init	gui.txt	/*gui-init*
+gui-kde	gui_x11.txt	/*gui-kde*
+gui-mouse	gui.txt	/*gui-mouse*
+gui-mouse-focus	gui.txt	/*gui-mouse-focus*
+gui-mouse-mapping	gui.txt	/*gui-mouse-mapping*
+gui-mouse-modeless	gui.txt	/*gui-mouse-modeless*
+gui-mouse-move	gui.txt	/*gui-mouse-move*
+gui-mouse-select	gui.txt	/*gui-mouse-select*
+gui-mouse-status	gui.txt	/*gui-mouse-status*
+gui-mouse-various	gui.txt	/*gui-mouse-various*
+gui-pty	gui_x11.txt	/*gui-pty*
+gui-pty-erase	gui_x11.txt	/*gui-pty-erase*
+gui-resources	gui_x11.txt	/*gui-resources*
+gui-scrollbars	gui.txt	/*gui-scrollbars*
+gui-selections	gui.txt	/*gui-selections*
+gui-shell	gui.txt	/*gui-shell*
+gui-shell-win32	gui_w32.txt	/*gui-shell-win32*
+gui-start	gui.txt	/*gui-start*
+gui-toolbar	gui.txt	/*gui-toolbar*
+gui-vert-scroll	gui.txt	/*gui-vert-scroll*
+gui-w16	gui_w16.txt	/*gui-w16*
+gui-w32	gui_w32.txt	/*gui-w32*
+gui-w32-cmdargs	gui_w32.txt	/*gui-w32-cmdargs*
+gui-w32-dialogs	gui_w32.txt	/*gui-w32-dialogs*
+gui-w32-printing	gui_w32.txt	/*gui-w32-printing*
+gui-w32-start	gui_w32.txt	/*gui-w32-start*
+gui-w32-various	gui_w32.txt	/*gui-w32-various*
+gui-w32s	gui_w32.txt	/*gui-w32s*
+gui-win32-maximized	gui_w32.txt	/*gui-win32-maximized*
+gui-x11	gui_x11.txt	/*gui-x11*
+gui-x11-athena	gui_x11.txt	/*gui-x11-athena*
+gui-x11-compiling	gui_x11.txt	/*gui-x11-compiling*
+gui-x11-gtk	gui_x11.txt	/*gui-x11-gtk*
+gui-x11-kde	gui_x11.txt	/*gui-x11-kde*
+gui-x11-misc	gui_x11.txt	/*gui-x11-misc*
+gui-x11-motif	gui_x11.txt	/*gui-x11-motif*
+gui-x11-neXtaw	gui_x11.txt	/*gui-x11-neXtaw*
+gui-x11-printing	gui_x11.txt	/*gui-x11-printing*
+gui-x11-start	gui_x11.txt	/*gui-x11-start*
+gui-x11-various	gui_x11.txt	/*gui-x11-various*
+gui.txt	gui.txt	/*gui.txt*
+gui_w16.txt	gui_w16.txt	/*gui_w16.txt*
+gui_w32.txt	gui_w32.txt	/*gui_w32.txt*
+gui_x11.txt	gui_x11.txt	/*gui_x11.txt*
+guifontwide_gtk2	options.txt	/*guifontwide_gtk2*
+guioptions_a	options.txt	/*guioptions_a*
+guu	change.txt	/*guu*
+gv	visual.txt	/*gv*
+gview	starting.txt	/*gview*
+gvim	starting.txt	/*gvim*
+gvimdiff	diff.txt	/*gvimdiff*
+gvimrc	gui.txt	/*gvimrc*
+gw	change.txt	/*gw*
+gwgw	change.txt	/*gwgw*
+gww	change.txt	/*gww*
+gzip	pi_gzip.txt	/*gzip*
+gzip-autocmd	pi_gzip.txt	/*gzip-autocmd*
+gzip-example	autocmd.txt	/*gzip-example*
+gzip-helpfile	tips.txt	/*gzip-helpfile*
+g~	change.txt	/*g~*
+g~g~	change.txt	/*g~g~*
+g~~	change.txt	/*g~~*
+h	motion.txt	/*h*
+hangul	hangulin.txt	/*hangul*
+hangulin.txt	hangulin.txt	/*hangulin.txt*
+has()	eval.txt	/*has()*
+has-patch	eval.txt	/*has-patch*
+has_key()	eval.txt	/*has_key()*
+haskell.vim	syntax.txt	/*haskell.vim*
+haslocaldir()	eval.txt	/*haslocaldir()*
+hasmapto()	eval.txt	/*hasmapto()*
+hebrew	hebrew.txt	/*hebrew*
+hebrew.txt	hebrew.txt	/*hebrew.txt*
+help	various.txt	/*help*
+help-context	help.txt	/*help-context*
+help-summary	usr_02.txt	/*help-summary*
+help-tags	tags	1
+help-translated	various.txt	/*help-translated*
+help-xterm-window	various.txt	/*help-xterm-window*
+help.txt	help.txt	/*help.txt*
+hex-editing	tips.txt	/*hex-editing*
+hidden-buffer	windows.txt	/*hidden-buffer*
+hidden-changed	version5.txt	/*hidden-changed*
+hidden-menus	gui.txt	/*hidden-menus*
+hidden-options	options.txt	/*hidden-options*
+hidden-quit	windows.txt	/*hidden-quit*
+highlight-args	syntax.txt	/*highlight-args*
+highlight-changed	version4.txt	/*highlight-changed*
+highlight-cterm	syntax.txt	/*highlight-cterm*
+highlight-ctermbg	syntax.txt	/*highlight-ctermbg*
+highlight-ctermfg	syntax.txt	/*highlight-ctermfg*
+highlight-default	syntax.txt	/*highlight-default*
+highlight-font	syntax.txt	/*highlight-font*
+highlight-groups	syntax.txt	/*highlight-groups*
+highlight-gui	syntax.txt	/*highlight-gui*
+highlight-guibg	syntax.txt	/*highlight-guibg*
+highlight-guifg	syntax.txt	/*highlight-guifg*
+highlight-guisp	syntax.txt	/*highlight-guisp*
+highlight-start	syntax.txt	/*highlight-start*
+highlight-stop	syntax.txt	/*highlight-stop*
+highlight-term	syntax.txt	/*highlight-term*
+highlightID()	eval.txt	/*highlightID()*
+highlight_exists()	eval.txt	/*highlight_exists()*
+his	cmdline.txt	/*his*
+hist-names	eval.txt	/*hist-names*
+histadd()	eval.txt	/*histadd()*
+histdel()	eval.txt	/*histdel()*
+histget()	eval.txt	/*histget()*
+histnr()	eval.txt	/*histnr()*
+history	cmdline.txt	/*history*
+hit-enter	message.txt	/*hit-enter*
+hit-enter-prompt	message.txt	/*hit-enter-prompt*
+hit-return	message.txt	/*hit-return*
+hitest.vim	syntax.txt	/*hitest.vim*
+hjkl	usr_02.txt	/*hjkl*
+hl-Cursor	syntax.txt	/*hl-Cursor*
+hl-CursorColumn	syntax.txt	/*hl-CursorColumn*
+hl-CursorIM	syntax.txt	/*hl-CursorIM*
+hl-CursorLine	syntax.txt	/*hl-CursorLine*
+hl-DiffAdd	syntax.txt	/*hl-DiffAdd*
+hl-DiffChange	syntax.txt	/*hl-DiffChange*
+hl-DiffDelete	syntax.txt	/*hl-DiffDelete*
+hl-DiffText	syntax.txt	/*hl-DiffText*
+hl-Directory	syntax.txt	/*hl-Directory*
+hl-ErrorMsg	syntax.txt	/*hl-ErrorMsg*
+hl-FoldColumn	syntax.txt	/*hl-FoldColumn*
+hl-Folded	syntax.txt	/*hl-Folded*
+hl-IncSearch	syntax.txt	/*hl-IncSearch*
+hl-LineNr	syntax.txt	/*hl-LineNr*
+hl-MatchParen	syntax.txt	/*hl-MatchParen*
+hl-Menu	syntax.txt	/*hl-Menu*
+hl-ModeMsg	syntax.txt	/*hl-ModeMsg*
+hl-MoreMsg	syntax.txt	/*hl-MoreMsg*
+hl-NonText	syntax.txt	/*hl-NonText*
+hl-Normal	syntax.txt	/*hl-Normal*
+hl-Pmenu	syntax.txt	/*hl-Pmenu*
+hl-PmenuSbar	syntax.txt	/*hl-PmenuSbar*
+hl-PmenuSel	syntax.txt	/*hl-PmenuSel*
+hl-PmenuThumb	syntax.txt	/*hl-PmenuThumb*
+hl-Question	syntax.txt	/*hl-Question*
+hl-Scrollbar	syntax.txt	/*hl-Scrollbar*
+hl-Search	syntax.txt	/*hl-Search*
+hl-SignColumn	syntax.txt	/*hl-SignColumn*
+hl-SpecialKey	syntax.txt	/*hl-SpecialKey*
+hl-SpellBad	syntax.txt	/*hl-SpellBad*
+hl-SpellCap	syntax.txt	/*hl-SpellCap*
+hl-SpellLocal	syntax.txt	/*hl-SpellLocal*
+hl-SpellRare	syntax.txt	/*hl-SpellRare*
+hl-StatusLine	syntax.txt	/*hl-StatusLine*
+hl-StatusLineNC	syntax.txt	/*hl-StatusLineNC*
+hl-TabLine	syntax.txt	/*hl-TabLine*
+hl-TabLineFill	syntax.txt	/*hl-TabLineFill*
+hl-TabLineSel	syntax.txt	/*hl-TabLineSel*
+hl-Title	syntax.txt	/*hl-Title*
+hl-Tooltip	syntax.txt	/*hl-Tooltip*
+hl-User1	syntax.txt	/*hl-User1*
+hl-User1..9	syntax.txt	/*hl-User1..9*
+hl-User9	syntax.txt	/*hl-User9*
+hl-VertSplit	syntax.txt	/*hl-VertSplit*
+hl-Visual	syntax.txt	/*hl-Visual*
+hl-VisualNOS	syntax.txt	/*hl-VisualNOS*
+hl-WarningMsg	syntax.txt	/*hl-WarningMsg*
+hl-WildMenu	syntax.txt	/*hl-WildMenu*
+hlID()	eval.txt	/*hlID()*
+hlexists()	eval.txt	/*hlexists()*
+holy-grail	index.txt	/*holy-grail*
+home	intro.txt	/*home*
+home-replace	editing.txt	/*home-replace*
+hostname()	eval.txt	/*hostname()*
+how-do-i	howto.txt	/*how-do-i*
+how-to	howto.txt	/*how-to*
+howdoi	howto.txt	/*howdoi*
+howto	howto.txt	/*howto*
+howto.txt	howto.txt	/*howto.txt*
+hpterm	term.txt	/*hpterm*
+hpterm-color	syntax.txt	/*hpterm-color*
+html-flavor	insert.txt	/*html-flavor*
+html.vim	syntax.txt	/*html.vim*
+htmlos.vim	syntax.txt	/*htmlos.vim*
+http	pi_netrw.txt	/*http*
+i	insert.txt	/*i*
+i'	motion.txt	/*i'*
+i(	motion.txt	/*i(*
+i)	motion.txt	/*i)*
+i<	motion.txt	/*i<*
+i>	motion.txt	/*i>*
+iB	motion.txt	/*iB*
+iW	motion.txt	/*iW*
+i[	motion.txt	/*i[*
+i]	motion.txt	/*i]*
+i_0_CTRL-D	insert.txt	/*i_0_CTRL-D*
+i_<BS>	insert.txt	/*i_<BS>*
+i_<C-End>	insert.txt	/*i_<C-End>*
+i_<C-Home>	insert.txt	/*i_<C-Home>*
+i_<C-Left>	insert.txt	/*i_<C-Left>*
+i_<C-PageDown>	tabpage.txt	/*i_<C-PageDown>*
+i_<C-PageUp>	tabpage.txt	/*i_<C-PageUp>*
+i_<C-Right>	insert.txt	/*i_<C-Right>*
+i_<CR>	insert.txt	/*i_<CR>*
+i_<Del>	insert.txt	/*i_<Del>*
+i_<Down>	insert.txt	/*i_<Down>*
+i_<End>	insert.txt	/*i_<End>*
+i_<Esc>	insert.txt	/*i_<Esc>*
+i_<F1>	various.txt	/*i_<F1>*
+i_<Help>	various.txt	/*i_<Help>*
+i_<Home>	insert.txt	/*i_<Home>*
+i_<Insert>	insert.txt	/*i_<Insert>*
+i_<Left>	insert.txt	/*i_<Left>*
+i_<LeftMouse>	insert.txt	/*i_<LeftMouse>*
+i_<MouseDown>	insert.txt	/*i_<MouseDown>*
+i_<MouseUp>	insert.txt	/*i_<MouseUp>*
+i_<NL>	insert.txt	/*i_<NL>*
+i_<PageDown>	insert.txt	/*i_<PageDown>*
+i_<PageUp>	insert.txt	/*i_<PageUp>*
+i_<Right>	insert.txt	/*i_<Right>*
+i_<S-Down>	insert.txt	/*i_<S-Down>*
+i_<S-Left>	insert.txt	/*i_<S-Left>*
+i_<S-MouseDown>	insert.txt	/*i_<S-MouseDown>*
+i_<S-MouseUp>	insert.txt	/*i_<S-MouseUp>*
+i_<S-Right>	insert.txt	/*i_<S-Right>*
+i_<S-Up>	insert.txt	/*i_<S-Up>*
+i_<Tab>	insert.txt	/*i_<Tab>*
+i_<Up>	insert.txt	/*i_<Up>*
+i_BS	insert.txt	/*i_BS*
+i_CTRL-<PageDown>	tabpage.txt	/*i_CTRL-<PageDown>*
+i_CTRL-<PageUp>	tabpage.txt	/*i_CTRL-<PageUp>*
+i_CTRL-@	insert.txt	/*i_CTRL-@*
+i_CTRL-A	insert.txt	/*i_CTRL-A*
+i_CTRL-B-gone	version5.txt	/*i_CTRL-B-gone*
+i_CTRL-C	insert.txt	/*i_CTRL-C*
+i_CTRL-D	insert.txt	/*i_CTRL-D*
+i_CTRL-E	insert.txt	/*i_CTRL-E*
+i_CTRL-F	indent.txt	/*i_CTRL-F*
+i_CTRL-G_<Down>	insert.txt	/*i_CTRL-G_<Down>*
+i_CTRL-G_<Up>	insert.txt	/*i_CTRL-G_<Up>*
+i_CTRL-G_CTRL-J	insert.txt	/*i_CTRL-G_CTRL-J*
+i_CTRL-G_CTRL-K	insert.txt	/*i_CTRL-G_CTRL-K*
+i_CTRL-G_j	insert.txt	/*i_CTRL-G_j*
+i_CTRL-G_k	insert.txt	/*i_CTRL-G_k*
+i_CTRL-G_u	insert.txt	/*i_CTRL-G_u*
+i_CTRL-H	insert.txt	/*i_CTRL-H*
+i_CTRL-I	insert.txt	/*i_CTRL-I*
+i_CTRL-J	insert.txt	/*i_CTRL-J*
+i_CTRL-K	insert.txt	/*i_CTRL-K*
+i_CTRL-L	insert.txt	/*i_CTRL-L*
+i_CTRL-M	insert.txt	/*i_CTRL-M*
+i_CTRL-N	insert.txt	/*i_CTRL-N*
+i_CTRL-O	insert.txt	/*i_CTRL-O*
+i_CTRL-P	insert.txt	/*i_CTRL-P*
+i_CTRL-Q	insert.txt	/*i_CTRL-Q*
+i_CTRL-R	insert.txt	/*i_CTRL-R*
+i_CTRL-R_CTRL-O	insert.txt	/*i_CTRL-R_CTRL-O*
+i_CTRL-R_CTRL-P	insert.txt	/*i_CTRL-R_CTRL-P*
+i_CTRL-R_CTRL-R	insert.txt	/*i_CTRL-R_CTRL-R*
+i_CTRL-T	insert.txt	/*i_CTRL-T*
+i_CTRL-U	insert.txt	/*i_CTRL-U*
+i_CTRL-V	insert.txt	/*i_CTRL-V*
+i_CTRL-V_digit	insert.txt	/*i_CTRL-V_digit*
+i_CTRL-W	insert.txt	/*i_CTRL-W*
+i_CTRL-X	insert.txt	/*i_CTRL-X*
+i_CTRL-X_CTRL-D	insert.txt	/*i_CTRL-X_CTRL-D*
+i_CTRL-X_CTRL-E	insert.txt	/*i_CTRL-X_CTRL-E*
+i_CTRL-X_CTRL-F	insert.txt	/*i_CTRL-X_CTRL-F*
+i_CTRL-X_CTRL-I	insert.txt	/*i_CTRL-X_CTRL-I*
+i_CTRL-X_CTRL-K	insert.txt	/*i_CTRL-X_CTRL-K*
+i_CTRL-X_CTRL-L	insert.txt	/*i_CTRL-X_CTRL-L*
+i_CTRL-X_CTRL-N	insert.txt	/*i_CTRL-X_CTRL-N*
+i_CTRL-X_CTRL-O	insert.txt	/*i_CTRL-X_CTRL-O*
+i_CTRL-X_CTRL-P	insert.txt	/*i_CTRL-X_CTRL-P*
+i_CTRL-X_CTRL-S	insert.txt	/*i_CTRL-X_CTRL-S*
+i_CTRL-X_CTRL-T	insert.txt	/*i_CTRL-X_CTRL-T*
+i_CTRL-X_CTRL-U	insert.txt	/*i_CTRL-X_CTRL-U*
+i_CTRL-X_CTRL-V	insert.txt	/*i_CTRL-X_CTRL-V*
+i_CTRL-X_CTRL-Y	insert.txt	/*i_CTRL-X_CTRL-Y*
+i_CTRL-X_CTRL-]	insert.txt	/*i_CTRL-X_CTRL-]*
+i_CTRL-X_index	index.txt	/*i_CTRL-X_index*
+i_CTRL-X_s	insert.txt	/*i_CTRL-X_s*
+i_CTRL-Y	insert.txt	/*i_CTRL-Y*
+i_CTRL-Z	options.txt	/*i_CTRL-Z*
+i_CTRL-[	insert.txt	/*i_CTRL-[*
+i_CTRL-\_CTRL-G	intro.txt	/*i_CTRL-\\_CTRL-G*
+i_CTRL-\_CTRL-N	intro.txt	/*i_CTRL-\\_CTRL-N*
+i_CTRL-\_CTRL-O	insert.txt	/*i_CTRL-\\_CTRL-O*
+i_CTRL-]	insert.txt	/*i_CTRL-]*
+i_CTRL-^	insert.txt	/*i_CTRL-^*
+i_CTRL-_	insert.txt	/*i_CTRL-_*
+i_DEL	insert.txt	/*i_DEL*
+i_Tab	insert.txt	/*i_Tab*
+i_^_CTRL-D	insert.txt	/*i_^_CTRL-D*
+i_backspacing	insert.txt	/*i_backspacing*
+i_digraph	digraph.txt	/*i_digraph*
+i_esc	intro.txt	/*i_esc*
+i`	motion.txt	/*i`*
+ia64.vim	syntax.txt	/*ia64.vim*
+ib	motion.txt	/*ib*
+iccf	uganda.txt	/*iccf*
+iccf-donations	uganda.txt	/*iccf-donations*
+icon-changed	version4.txt	/*icon-changed*
+iconise	starting.txt	/*iconise*
+iconize	starting.txt	/*iconize*
+iconv()	eval.txt	/*iconv()*
+iconv-dynamic	mbyte.txt	/*iconv-dynamic*
+ident-search	tips.txt	/*ident-search*
+idl-syntax	syntax.txt	/*idl-syntax*
+idl.vim	syntax.txt	/*idl.vim*
+if_cscop.txt	if_cscop.txt	/*if_cscop.txt*
+if_mzsch.txt	if_mzsch.txt	/*if_mzsch.txt*
+if_ole.txt	if_ole.txt	/*if_ole.txt*
+if_perl.txt	if_perl.txt	/*if_perl.txt*
+if_pyth.txt	if_pyth.txt	/*if_pyth.txt*
+if_ruby.txt	if_ruby.txt	/*if_ruby.txt*
+if_sniff.txt	if_sniff.txt	/*if_sniff.txt*
+if_tcl.txt	if_tcl.txt	/*if_tcl.txt*
+ignore-errors	eval.txt	/*ignore-errors*
+improved-autocmds-5.4	version5.txt	/*improved-autocmds-5.4*
+improved-quickfix	version5.txt	/*improved-quickfix*
+improved-sessions	version5.txt	/*improved-sessions*
+improved-viminfo	version5.txt	/*improved-viminfo*
+improvements-5	version5.txt	/*improvements-5*
+improvements-6	version6.txt	/*improvements-6*
+improvements-7	version7.txt	/*improvements-7*
+inactive-buffer	windows.txt	/*inactive-buffer*
+include-search	tagsrch.txt	/*include-search*
+inclusive	motion.txt	/*inclusive*
+incomp-small-6	version6.txt	/*incomp-small-6*
+incompatible-5	version5.txt	/*incompatible-5*
+incompatible-6	version6.txt	/*incompatible-6*
+incompatible-7	version7.txt	/*incompatible-7*
+indent()	eval.txt	/*indent()*
+indent-expression	indent.txt	/*indent-expression*
+indent.txt	indent.txt	/*indent.txt*
+indentkeys-format	indent.txt	/*indentkeys-format*
+index	index.txt	/*index*
+index()	eval.txt	/*index()*
+index.txt	index.txt	/*index.txt*
+info-message	starting.txt	/*info-message*
+inform.vim	syntax.txt	/*inform.vim*
+informix	sql.txt	/*informix*
+initialization	starting.txt	/*initialization*
+input()	eval.txt	/*input()*
+inputdialog()	eval.txt	/*inputdialog()*
+inputlist()	eval.txt	/*inputlist()*
+inputrestore()	eval.txt	/*inputrestore()*
+inputsave()	eval.txt	/*inputsave()*
+inputsecret()	eval.txt	/*inputsecret()*
+ins-completion	insert.txt	/*ins-completion*
+ins-completion-menu	insert.txt	/*ins-completion-menu*
+ins-expandtab	insert.txt	/*ins-expandtab*
+ins-reverse	rileft.txt	/*ins-reverse*
+ins-smarttab	insert.txt	/*ins-smarttab*
+ins-softtabstop	insert.txt	/*ins-softtabstop*
+ins-special-keys	insert.txt	/*ins-special-keys*
+ins-special-special	insert.txt	/*ins-special-special*
+ins-textwidth	insert.txt	/*ins-textwidth*
+insert	insert.txt	/*insert*
+insert()	eval.txt	/*insert()*
+insert-index	index.txt	/*insert-index*
+insert.txt	insert.txt	/*insert.txt*
+insert_expand	insert.txt	/*insert_expand*
+inserting	insert.txt	/*inserting*
+inserting-ex	insert.txt	/*inserting-ex*
+inserting-file	insert.txt	/*inserting-file*
+insertmode-variable	eval.txt	/*insertmode-variable*
+install	usr_90.txt	/*install*
+install-home	usr_90.txt	/*install-home*
+install-registry	gui_w32.txt	/*install-registry*
+intel-itanium	syntax.txt	/*intel-itanium*
+intellimouse-wheel-problems	gui_w32.txt	/*intellimouse-wheel-problems*
+interfaces-5.2	version5.txt	/*interfaces-5.2*
+internal-variables	eval.txt	/*internal-variables*
+internal-wordlist	spell.txt	/*internal-wordlist*
+internet	intro.txt	/*internet*
+intro	intro.txt	/*intro*
+intro.txt	intro.txt	/*intro.txt*
+inverse	syntax.txt	/*inverse*
+ip	motion.txt	/*ip*
+iquote	motion.txt	/*iquote*
+is	motion.txt	/*is*
+isdirectory()	eval.txt	/*isdirectory()*
+islocked()	eval.txt	/*islocked()*
+it	motion.txt	/*it*
+italic	syntax.txt	/*italic*
+items()	eval.txt	/*items()*
+iw	motion.txt	/*iw*
+i{	motion.txt	/*i{*
+i}	motion.txt	/*i}*
+j	motion.txt	/*j*
+java-cinoptions	indent.txt	/*java-cinoptions*
+java-indenting	indent.txt	/*java-indenting*
+java.vim	syntax.txt	/*java.vim*
+join()	eval.txt	/*join()*
+jsbterm-mouse	options.txt	/*jsbterm-mouse*
+jtags	tagsrch.txt	/*jtags*
+jump-motions	motion.txt	/*jump-motions*
+jumplist	motion.txt	/*jumplist*
+jumpto-diffs	diff.txt	/*jumpto-diffs*
+k	motion.txt	/*k*
+kcc	uganda.txt	/*kcc*
+kde	gui_x11.txt	/*kde*
+key-codes	intro.txt	/*key-codes*
+key-codes-changed	version4.txt	/*key-codes-changed*
+key-mapping	map.txt	/*key-mapping*
+key-notation	intro.txt	/*key-notation*
+key-variable	eval.txt	/*key-variable*
+keycodes	intro.txt	/*keycodes*
+keymap-accents	mbyte.txt	/*keymap-accents*
+keymap-file-format	mbyte.txt	/*keymap-file-format*
+keymap-hebrew	mbyte.txt	/*keymap-hebrew*
+keypad-0	intro.txt	/*keypad-0*
+keypad-9	intro.txt	/*keypad-9*
+keypad-comma	term.txt	/*keypad-comma*
+keypad-divide	intro.txt	/*keypad-divide*
+keypad-end	intro.txt	/*keypad-end*
+keypad-enter	intro.txt	/*keypad-enter*
+keypad-home	intro.txt	/*keypad-home*
+keypad-minus	intro.txt	/*keypad-minus*
+keypad-multiply	intro.txt	/*keypad-multiply*
+keypad-page-down	intro.txt	/*keypad-page-down*
+keypad-page-up	intro.txt	/*keypad-page-up*
+keypad-plus	intro.txt	/*keypad-plus*
+keypad-point	intro.txt	/*keypad-point*
+keys()	eval.txt	/*keys()*
+known-bugs	todo.txt	/*known-bugs*
+l	motion.txt	/*l*
+l:var	eval.txt	/*l:var*
+lace.vim	syntax.txt	/*lace.vim*
+lang-variable	eval.txt	/*lang-variable*
+language-mapping	map.txt	/*language-mapping*
+last-pattern	pattern.txt	/*last-pattern*
+last-position-jump	eval.txt	/*last-position-jump*
+last_buffer_nr()	eval.txt	/*last_buffer_nr()*
+lc_time-variable	eval.txt	/*lc_time-variable*
+left-right-motions	motion.txt	/*left-right-motions*
+len()	eval.txt	/*len()*
+less	various.txt	/*less*
+letter	print.txt	/*letter*
+lex.vim	syntax.txt	/*lex.vim*
+lhaskell.vim	syntax.txt	/*lhaskell.vim*
+libcall()	eval.txt	/*libcall()*
+libcallnr()	eval.txt	/*libcallnr()*
+license	uganda.txt	/*license*
+lid	quickfix.txt	/*lid*
+limits	vi_diff.txt	/*limits*
+line()	eval.txt	/*line()*
+line-continuation	repeat.txt	/*line-continuation*
+line2byte()	eval.txt	/*line2byte()*
+linefeed	intro.txt	/*linefeed*
+linewise	motion.txt	/*linewise*
+linewise-register	change.txt	/*linewise-register*
+linewise-visual	visual.txt	/*linewise-visual*
+lisp.vim	syntax.txt	/*lisp.vim*
+lispindent()	eval.txt	/*lispindent()*
+list-identity	eval.txt	/*list-identity*
+list-index	eval.txt	/*list-index*
+list-modification	eval.txt	/*list-modification*
+list-repeat	windows.txt	/*list-repeat*
+lite.vim	syntax.txt	/*lite.vim*
+literal-string	eval.txt	/*literal-string*
+lnum-variable	eval.txt	/*lnum-variable*
+load-plugins	starting.txt	/*load-plugins*
+load-vim-script	repeat.txt	/*load-vim-script*
+local-additions	help.txt	/*local-additions*
+local-function	eval.txt	/*local-function*
+local-options	options.txt	/*local-options*
+local-variable	eval.txt	/*local-variable*
+local-variables	eval.txt	/*local-variables*
+locale	mbyte.txt	/*locale*
+locale-name	mbyte.txt	/*locale-name*
+localtime()	eval.txt	/*localtime()*
+location-list	quickfix.txt	/*location-list*
+location-list-window	quickfix.txt	/*location-list-window*
+long-lines	version5.txt	/*long-lines*
+lowercase	change.txt	/*lowercase*
+lpc.vim	syntax.txt	/*lpc.vim*
+lua.vim	syntax.txt	/*lua.vim*
+m	motion.txt	/*m*
+m'	motion.txt	/*m'*
+m[	motion.txt	/*m[*
+m]	motion.txt	/*m]*
+m`	motion.txt	/*m`*
+mac	os_mac.txt	/*mac*
+mac-bug	os_mac.txt	/*mac-bug*
+mac-compile	os_mac.txt	/*mac-compile*
+mac-faq	os_mac.txt	/*mac-faq*
+mac-filename	os_mac.txt	/*mac-filename*
+mac-lack	os_mac.txt	/*mac-lack*
+mac-vimfile	os_mac.txt	/*mac-vimfile*
+macintosh	os_mac.txt	/*macintosh*
+macro	map.txt	/*macro*
+mail-list	intro.txt	/*mail-list*
+mail.vim	syntax.txt	/*mail.vim*
+maillist	intro.txt	/*maillist*
+maillist-archive	intro.txt	/*maillist-archive*
+make.vim	syntax.txt	/*make.vim*
+manual-copyright	usr_01.txt	/*manual-copyright*
+map()	eval.txt	/*map()*
+map-<SID>	map.txt	/*map-<SID>*
+map-ambiguous	map.txt	/*map-ambiguous*
+map-backtick	tips.txt	/*map-backtick*
+map-comments	map.txt	/*map-comments*
+map-examples	map.txt	/*map-examples*
+map-keys-fails	map.txt	/*map-keys-fails*
+map-listing	map.txt	/*map-listing*
+map-modes	map.txt	/*map-modes*
+map-multibyte	map.txt	/*map-multibyte*
+map-overview	map.txt	/*map-overview*
+map-self-destroy	tips.txt	/*map-self-destroy*
+map-typing	map.txt	/*map-typing*
+map-which-keys	map.txt	/*map-which-keys*
+map.txt	map.txt	/*map.txt*
+map_CTRL-C	map.txt	/*map_CTRL-C*
+map_backslash	map.txt	/*map_backslash*
+map_bar	map.txt	/*map_bar*
+map_empty_rhs	map.txt	/*map_empty_rhs*
+map_return	map.txt	/*map_return*
+map_space_in_lhs	map.txt	/*map_space_in_lhs*
+map_space_in_rhs	map.txt	/*map_space_in_rhs*
+maparg()	eval.txt	/*maparg()*
+mapcheck()	eval.txt	/*mapcheck()*
+maple.vim	syntax.txt	/*maple.vim*
+mapleader	map.txt	/*mapleader*
+maplocalleader	map.txt	/*maplocalleader*
+mapmode-c	map.txt	/*mapmode-c*
+mapmode-i	map.txt	/*mapmode-i*
+mapmode-ic	map.txt	/*mapmode-ic*
+mapmode-l	map.txt	/*mapmode-l*
+mapmode-n	map.txt	/*mapmode-n*
+mapmode-nvo	map.txt	/*mapmode-nvo*
+mapmode-o	map.txt	/*mapmode-o*
+mapmode-s	map.txt	/*mapmode-s*
+mapmode-v	map.txt	/*mapmode-v*
+mapmode-x	map.txt	/*mapmode-x*
+mapping	map.txt	/*mapping*
+mark	motion.txt	/*mark*
+mark-motions	motion.txt	/*mark-motions*
+masm.vim	syntax.txt	/*masm.vim*
+match()	eval.txt	/*match()*
+match-highlight	pattern.txt	/*match-highlight*
+match-parens	tips.txt	/*match-parens*
+matcharg()	eval.txt	/*matcharg()*
+matchend()	eval.txt	/*matchend()*
+matchit-install	usr_05.txt	/*matchit-install*
+matchlist()	eval.txt	/*matchlist()*
+matchparen	pi_paren.txt	/*matchparen*
+matchstr()	eval.txt	/*matchstr()*
+max()	eval.txt	/*max()*
+mbyte-IME	mbyte.txt	/*mbyte-IME*
+mbyte-XIM	mbyte.txt	/*mbyte-XIM*
+mbyte-combining	mbyte.txt	/*mbyte-combining*
+mbyte-composing	mbyte.txt	/*mbyte-composing*
+mbyte-conversion	mbyte.txt	/*mbyte-conversion*
+mbyte-encoding	mbyte.txt	/*mbyte-encoding*
+mbyte-first	mbyte.txt	/*mbyte-first*
+mbyte-fonts-MSwin	mbyte.txt	/*mbyte-fonts-MSwin*
+mbyte-fonts-X11	mbyte.txt	/*mbyte-fonts-X11*
+mbyte-keymap	mbyte.txt	/*mbyte-keymap*
+mbyte-locale	mbyte.txt	/*mbyte-locale*
+mbyte-options	mbyte.txt	/*mbyte-options*
+mbyte-terminal	mbyte.txt	/*mbyte-terminal*
+mbyte-utf8	mbyte.txt	/*mbyte-utf8*
+mbyte.txt	mbyte.txt	/*mbyte.txt*
+menu-changes-5.4	version5.txt	/*menu-changes-5.4*
+menu-examples	gui.txt	/*menu-examples*
+menu-priority	gui.txt	/*menu-priority*
+menu-separator	gui.txt	/*menu-separator*
+menu.vim	gui.txt	/*menu.vim*
+menus	gui.txt	/*menus*
+merge	diff.txt	/*merge*
+message-history	message.txt	/*message-history*
+message.txt	message.txt	/*message.txt*
+messages	message.txt	/*messages*
+meta	intro.txt	/*meta*
+min()	eval.txt	/*min()*
+minimal-features	os_msdos.txt	/*minimal-features*
+missing-options	vi_diff.txt	/*missing-options*
+mkdir()	eval.txt	/*mkdir()*
+mlang.txt	mlang.txt	/*mlang.txt*
+mma.vim	syntax.txt	/*mma.vim*
+mode()	eval.txt	/*mode()*
+mode-Ex	intro.txt	/*mode-Ex*
+mode-cmdline	cmdline.txt	/*mode-cmdline*
+mode-ins-repl	insert.txt	/*mode-ins-repl*
+mode-replace	insert.txt	/*mode-replace*
+mode-switching	intro.txt	/*mode-switching*
+modeless-and-clipboard	version6.txt	/*modeless-and-clipboard*
+modeless-selection	gui.txt	/*modeless-selection*
+modeline	options.txt	/*modeline*
+modeline-local	options.txt	/*modeline-local*
+modeline-version	options.txt	/*modeline-version*
+moo.vim	syntax.txt	/*moo.vim*
+more-compatible	version5.txt	/*more-compatible*
+more-prompt	message.txt	/*more-prompt*
+more-variables	eval.txt	/*more-variables*
+motion.txt	motion.txt	/*motion.txt*
+mouse-mode-table	term.txt	/*mouse-mode-table*
+mouse-overview	term.txt	/*mouse-overview*
+mouse-swap-buttons	term.txt	/*mouse-swap-buttons*
+mouse-using	term.txt	/*mouse-using*
+mouse_col-variable	eval.txt	/*mouse_col-variable*
+mouse_lnum-variable	eval.txt	/*mouse_lnum-variable*
+mouse_win-variable	eval.txt	/*mouse_win-variable*
+movement	intro.txt	/*movement*
+ms-dos	os_msdos.txt	/*ms-dos*
+msdos	os_msdos.txt	/*msdos*
+msdos-arrows	os_msdos.txt	/*msdos-arrows*
+msdos-clipboard-limits	os_msdos.txt	/*msdos-clipboard-limits*
+msdos-compiling	os_msdos.txt	/*msdos-compiling*
+msdos-copy-paste	os_msdos.txt	/*msdos-copy-paste*
+msdos-fname-extensions	os_msdos.txt	/*msdos-fname-extensions*
+msdos-limitations	os_msdos.txt	/*msdos-limitations*
+msdos-linked-files	os_msdos.txt	/*msdos-linked-files*
+msdos-longfname	os_msdos.txt	/*msdos-longfname*
+msdos-mode	gui_w32.txt	/*msdos-mode*
+msdos-problems	os_msdos.txt	/*msdos-problems*
+msdos-termcap	os_msdos.txt	/*msdos-termcap*
+msdos-versions	os_msdos.txt	/*msdos-versions*
+msql.vim	syntax.txt	/*msql.vim*
+mswin.vim	gui_w32.txt	/*mswin.vim*
+multi-byte	mbyte.txt	/*multi-byte*
+multi-lang	mlang.txt	/*multi-lang*
+multi-repeat	repeat.txt	/*multi-repeat*
+multibyte	mbyte.txt	/*multibyte*
+multibyte-ime	mbyte.txt	/*multibyte-ime*
+multibyte-input	mbyte.txt	/*multibyte-input*
+multilang	mlang.txt	/*multilang*
+multilang-menus	mlang.txt	/*multilang-menus*
+multilang-messages	mlang.txt	/*multilang-messages*
+multilang-scripts	mlang.txt	/*multilang-scripts*
+myfiletypefile	syntax.txt	/*myfiletypefile*
+myscriptsfile	syntax.txt	/*myscriptsfile*
+mysql	sql.txt	/*mysql*
+mysyntaxfile	syntax.txt	/*mysyntaxfile*
+mysyntaxfile-add	syntax.txt	/*mysyntaxfile-add*
+mysyntaxfile-replace	syntax.txt	/*mysyntaxfile-replace*
+mzscheme	if_mzsch.txt	/*mzscheme*
+mzscheme-buffer	if_mzsch.txt	/*mzscheme-buffer*
+mzscheme-commands	if_mzsch.txt	/*mzscheme-commands*
+mzscheme-dynamic	if_mzsch.txt	/*mzscheme-dynamic*
+mzscheme-examples	if_mzsch.txt	/*mzscheme-examples*
+mzscheme-sandbox	if_mzsch.txt	/*mzscheme-sandbox*
+mzscheme-threads	if_mzsch.txt	/*mzscheme-threads*
+mzscheme-vim	if_mzsch.txt	/*mzscheme-vim*
+mzscheme-vimext	if_mzsch.txt	/*mzscheme-vimext*
+mzscheme-window	if_mzsch.txt	/*mzscheme-window*
+n	pattern.txt	/*n*
+nasm.vim	syntax.txt	/*nasm.vim*
+navigation	motion.txt	/*navigation*
+nb-commands	netbeans.txt	/*nb-commands*
+nb-events	netbeans.txt	/*nb-events*
+nb-functions	netbeans.txt	/*nb-functions*
+nb-messages	netbeans.txt	/*nb-messages*
+nb-special	netbeans.txt	/*nb-special*
+nb-terms	netbeans.txt	/*nb-terms*
+ncf.vim	syntax.txt	/*ncf.vim*
+netbeans	netbeans.txt	/*netbeans*
+netbeans-commands	netbeans.txt	/*netbeans-commands*
+netbeans-configure	netbeans.txt	/*netbeans-configure*
+netbeans-download	netbeans.txt	/*netbeans-download*
+netbeans-intro	netbeans.txt	/*netbeans-intro*
+netbeans-keybindings	netbeans.txt	/*netbeans-keybindings*
+netbeans-messages	netbeans.txt	/*netbeans-messages*
+netbeans-preparation	netbeans.txt	/*netbeans-preparation*
+netbeans-problems	netbeans.txt	/*netbeans-problems*
+netbeans-protocol	netbeans.txt	/*netbeans-protocol*
+netbeans-run	netbeans.txt	/*netbeans-run*
+netbeans-setup	netbeans.txt	/*netbeans-setup*
+netbeans-support	netbeans.txt	/*netbeans-support*
+netbeans.txt	netbeans.txt	/*netbeans.txt*
+netreadfixup	pi_netrw.txt	/*netreadfixup*
+netrw	pi_netrw.txt	/*netrw*
+netrw--	pi_netrw.txt	/*netrw--*
+netrw-D	pi_netrw.txt	/*netrw-D*
+netrw-O	pi_netrw.txt	/*netrw-O*
+netrw-P	pi_netrw.txt	/*netrw-P*
+netrw-R	pi_netrw.txt	/*netrw-R*
+netrw-S	pi_netrw.txt	/*netrw-S*
+netrw-U	pi_netrw.txt	/*netrw-U*
+netrw-a	pi_netrw.txt	/*netrw-a*
+netrw-activate	pi_netrw.txt	/*netrw-activate*
+netrw-bookmark	pi_netrw.txt	/*netrw-bookmark*
+netrw-bookmarks	pi_netrw.txt	/*netrw-bookmarks*
+netrw-browse	pi_netrw.txt	/*netrw-browse*
+netrw-browse-cmds	pi_netrw.txt	/*netrw-browse-cmds*
+netrw-browse-intro	pi_netrw.txt	/*netrw-browse-intro*
+netrw-browse-var	pi_netrw.txt	/*netrw-browse-var*
+netrw-c	pi_netrw.txt	/*netrw-c*
+netrw-cadaver	pi_netrw.txt	/*netrw-cadaver*
+netrw-chgup	pi_netrw.txt	/*netrw-chgup*
+netrw-contents	pi_netrw.txt	/*netrw-contents*
+netrw-cr	pi_netrw.txt	/*netrw-cr*
+netrw-credits	pi_netrw.txt	/*netrw-credits*
+netrw-ctrl-h	pi_netrw.txt	/*netrw-ctrl-h*
+netrw-ctrl-l	pi_netrw.txt	/*netrw-ctrl-l*
+netrw-ctrl_h	pi_netrw.txt	/*netrw-ctrl_h*
+netrw-ctrl_l	pi_netrw.txt	/*netrw-ctrl_l*
+netrw-curdir	pi_netrw.txt	/*netrw-curdir*
+netrw-d	pi_netrw.txt	/*netrw-d*
+netrw-debug	pi_netrw.txt	/*netrw-debug*
+netrw-del	pi_netrw.txt	/*netrw-del*
+netrw-delete	pi_netrw.txt	/*netrw-delete*
+netrw-dir	pi_netrw.txt	/*netrw-dir*
+netrw-dirlist	pi_netrw.txt	/*netrw-dirlist*
+netrw-downdir	pi_netrw.txt	/*netrw-downdir*
+netrw-edithide	pi_netrw.txt	/*netrw-edithide*
+netrw-ex	pi_netrw.txt	/*netrw-ex*
+netrw-explore	pi_netrw.txt	/*netrw-explore*
+netrw-explore-cmds	pi_netrw.txt	/*netrw-explore-cmds*
+netrw-externapp	pi_netrw.txt	/*netrw-externapp*
+netrw-file	pi_netrw.txt	/*netrw-file*
+netrw-fixup	pi_netrw.txt	/*netrw-fixup*
+netrw-ftp	pi_netrw.txt	/*netrw-ftp*
+netrw-gb	pi_netrw.txt	/*netrw-gb*
+netrw-gx	pi_netrw.txt	/*netrw-gx*
+netrw-handler	pi_netrw.txt	/*netrw-handler*
+netrw-help	pi_netrw.txt	/*netrw-help*
+netrw-hexplore	pi_netrw.txt	/*netrw-hexplore*
+netrw-hiding	pi_netrw.txt	/*netrw-hiding*
+netrw-history	pi_netrw.txt	/*netrw-history*
+netrw-horiz	pi_netrw.txt	/*netrw-horiz*
+netrw-i	pi_netrw.txt	/*netrw-i*
+netrw-incompatible	pi_netrw.txt	/*netrw-incompatible*
+netrw-list	pi_netrw.txt	/*netrw-list*
+netrw-listbookmark	pi_netrw.txt	/*netrw-listbookmark*
+netrw-listhack	pi_netrw.txt	/*netrw-listhack*
+netrw-login	pi_netrw.txt	/*netrw-login*
+netrw-maps	pi_netrw.txt	/*netrw-maps*
+netrw-mb	pi_netrw.txt	/*netrw-mb*
+netrw-ml_get	pi_netrw.txt	/*netrw-ml_get*
+netrw-move	pi_netrw.txt	/*netrw-move*
+netrw-netrc	pi_netrw.txt	/*netrw-netrc*
+netrw-nexplore	pi_netrw.txt	/*netrw-nexplore*
+netrw-nread	pi_netrw.txt	/*netrw-nread*
+netrw-nwrite	pi_netrw.txt	/*netrw-nwrite*
+netrw-o	pi_netrw.txt	/*netrw-o*
+netrw-options	pi_netrw.txt	/*netrw-options*
+netrw-p	pi_netrw.txt	/*netrw-p*
+netrw-p1	pi_netrw.txt	/*netrw-p1*
+netrw-p2	pi_netrw.txt	/*netrw-p2*
+netrw-p3	pi_netrw.txt	/*netrw-p3*
+netrw-p4	pi_netrw.txt	/*netrw-p4*
+netrw-p5	pi_netrw.txt	/*netrw-p5*
+netrw-p6	pi_netrw.txt	/*netrw-p6*
+netrw-p7	pi_netrw.txt	/*netrw-p7*
+netrw-p8	pi_netrw.txt	/*netrw-p8*
+netrw-p9	pi_netrw.txt	/*netrw-p9*
+netrw-passwd	pi_netrw.txt	/*netrw-passwd*
+netrw-password	pi_netrw.txt	/*netrw-password*
+netrw-path	pi_netrw.txt	/*netrw-path*
+netrw-pexplore	pi_netrw.txt	/*netrw-pexplore*
+netrw-preview	pi_netrw.txt	/*netrw-preview*
+netrw-problems	pi_netrw.txt	/*netrw-problems*
+netrw-protocol	pi_netrw.txt	/*netrw-protocol*
+netrw-prvwin	pi_netrw.txt	/*netrw-prvwin*
+netrw-pscp	pi_netrw.txt	/*netrw-pscp*
+netrw-psftp	pi_netrw.txt	/*netrw-psftp*
+netrw-putty	pi_netrw.txt	/*netrw-putty*
+netrw-q	pi_netrw.txt	/*netrw-q*
+netrw-r	pi_netrw.txt	/*netrw-r*
+netrw-read	pi_netrw.txt	/*netrw-read*
+netrw-ref	pi_netrw.txt	/*netrw-ref*
+netrw-rename	pi_netrw.txt	/*netrw-rename*
+netrw-reverse	pi_netrw.txt	/*netrw-reverse*
+netrw-s	pi_netrw.txt	/*netrw-s*
+netrw-settings	pi_netrw.txt	/*netrw-settings*
+netrw-sexplore	pi_netrw.txt	/*netrw-sexplore*
+netrw-sort	pi_netrw.txt	/*netrw-sort*
+netrw-sortsequence	pi_netrw.txt	/*netrw-sortsequence*
+netrw-source	pi_netrw.txt	/*netrw-source*
+netrw-starpat	pi_netrw.txt	/*netrw-starpat*
+netrw-starstar	pi_netrw.txt	/*netrw-starstar*
+netrw-starstarpat	pi_netrw.txt	/*netrw-starstarpat*
+netrw-start	pi_netrw.txt	/*netrw-start*
+netrw-t	pi_netrw.txt	/*netrw-t*
+netrw-texplore	pi_netrw.txt	/*netrw-texplore*
+netrw-transparent	pi_netrw.txt	/*netrw-transparent*
+netrw-u	pi_netrw.txt	/*netrw-u*
+netrw-uidpass	pi_netrw.txt	/*netrw-uidpass*
+netrw-updir	pi_netrw.txt	/*netrw-updir*
+netrw-urls	pi_netrw.txt	/*netrw-urls*
+netrw-userpass	pi_netrw.txt	/*netrw-userpass*
+netrw-v	pi_netrw.txt	/*netrw-v*
+netrw-var	pi_netrw.txt	/*netrw-var*
+netrw-variables	pi_netrw.txt	/*netrw-variables*
+netrw-vexplore	pi_netrw.txt	/*netrw-vexplore*
+netrw-write	pi_netrw.txt	/*netrw-write*
+netrw-x	pi_netrw.txt	/*netrw-x*
+netrw-xfer	pi_netrw.txt	/*netrw-xfer*
+netrw.vim	pi_netrw.txt	/*netrw.vim*
+netrw_filehandler	pi_netrw.txt	/*netrw_filehandler*
+netterm-mouse	options.txt	/*netterm-mouse*
+network	pi_netrw.txt	/*network*
+new-5	version5.txt	/*new-5*
+new-6	version6.txt	/*new-6*
+new-7	version7.txt	/*new-7*
+new-GTK-GUI	version5.txt	/*new-GTK-GUI*
+new-MzScheme	version7.txt	/*new-MzScheme*
+new-Select-mode	version5.txt	/*new-Select-mode*
+new-View	version6.txt	/*new-View*
+new-argument-list	version6.txt	/*new-argument-list*
+new-buftype	version6.txt	/*new-buftype*
+new-cmdwin	version6.txt	/*new-cmdwin*
+new-color-schemes	version6.txt	/*new-color-schemes*
+new-commands	version5.txt	/*new-commands*
+new-commands-5.4	version5.txt	/*new-commands-5.4*
+new-debug-itf	version6.txt	/*new-debug-itf*
+new-debug-mode	version6.txt	/*new-debug-mode*
+new-debug-support	version7.txt	/*new-debug-support*
+new-define-operator	version7.txt	/*new-define-operator*
+new-diff-mode	version6.txt	/*new-diff-mode*
+new-encryption	version5.txt	/*new-encryption*
+new-evim	version6.txt	/*new-evim*
+new-ex-commands-5.2	version5.txt	/*new-ex-commands-5.2*
+new-file-browser	version6.txt	/*new-file-browser*
+new-file-writing	version6.txt	/*new-file-writing*
+new-filetype	filetype.txt	/*new-filetype*
+new-filetype-5.4	version5.txt	/*new-filetype-5.4*
+new-filetype-plugins	version6.txt	/*new-filetype-plugins*
+new-filetype-scripts	filetype.txt	/*new-filetype-scripts*
+new-folding	version6.txt	/*new-folding*
+new-functions-5.2	version5.txt	/*new-functions-5.2*
+new-global-values	version6.txt	/*new-global-values*
+new-highlighting	version5.txt	/*new-highlighting*
+new-indent-flex	version6.txt	/*new-indent-flex*
+new-items-6	version6.txt	/*new-items-6*
+new-items-7	version7.txt	/*new-items-7*
+new-line-continuation	version5.txt	/*new-line-continuation*
+new-location-list	version7.txt	/*new-location-list*
+new-manpage-trans	version7.txt	/*new-manpage-trans*
+new-map-expression	version7.txt	/*new-map-expression*
+new-map-select	version7.txt	/*new-map-select*
+new-more-highlighting	version7.txt	/*new-more-highlighting*
+new-more-unicode	version7.txt	/*new-more-unicode*
+new-multi-byte	version5.txt	/*new-multi-byte*
+new-multi-lang	version6.txt	/*new-multi-lang*
+new-netrw-explore	version7.txt	/*new-netrw-explore*
+new-network-files	version6.txt	/*new-network-files*
+new-omni-completion	version7.txt	/*new-omni-completion*
+new-onemore	version7.txt	/*new-onemore*
+new-operator-mod	version6.txt	/*new-operator-mod*
+new-options-5.2	version5.txt	/*new-options-5.2*
+new-options-5.4	version5.txt	/*new-options-5.4*
+new-perl-python	version5.txt	/*new-perl-python*
+new-plugins	version6.txt	/*new-plugins*
+new-posix	version7.txt	/*new-posix*
+new-print-multi-byte	version7.txt	/*new-print-multi-byte*
+new-printing	version6.txt	/*new-printing*
+new-runtime-dir	version5.txt	/*new-runtime-dir*
+new-script	version5.txt	/*new-script*
+new-script-5.4	version5.txt	/*new-script-5.4*
+new-scroll-back	version7.txt	/*new-scroll-back*
+new-search-path	version6.txt	/*new-search-path*
+new-searchpat	version6.txt	/*new-searchpat*
+new-session-files	version5.txt	/*new-session-files*
+new-spell	version7.txt	/*new-spell*
+new-tab-pages	version7.txt	/*new-tab-pages*
+new-undo-branches	version7.txt	/*new-undo-branches*
+new-unlisted-buffers	version6.txt	/*new-unlisted-buffers*
+new-user-defined	version5.txt	/*new-user-defined*
+new-user-manual	version6.txt	/*new-user-manual*
+new-utf-8	version6.txt	/*new-utf-8*
+new-vertsplit	version6.txt	/*new-vertsplit*
+new-vim-script	version7.txt	/*new-vim-script*
+new-vim-server	version6.txt	/*new-vim-server*
+new-vimgrep	version7.txt	/*new-vimgrep*
+new-virtedit	version6.txt	/*new-virtedit*
+news	intro.txt	/*news*
+nextnonblank()	eval.txt	/*nextnonblank()*
+nice	todo.txt	/*nice*
+no-eval-feature	eval.txt	/*no-eval-feature*
+no_buffers_menu	gui.txt	/*no_buffers_menu*
+non-greedy	pattern.txt	/*non-greedy*
+normal-index	index.txt	/*normal-index*
+not-compatible	usr_01.txt	/*not-compatible*
+not-edited	editing.txt	/*not-edited*
+notation	intro.txt	/*notation*
+notepad	gui_w32.txt	/*notepad*
+nr2char()	eval.txt	/*nr2char()*
+nroff.vim	syntax.txt	/*nroff.vim*
+numbered-function	eval.txt	/*numbered-function*
+o	insert.txt	/*o*
+o_CTRL-V	motion.txt	/*o_CTRL-V*
+o_V	motion.txt	/*o_V*
+o_v	motion.txt	/*o_v*
+object-motions	motion.txt	/*object-motions*
+object-select	motion.txt	/*object-select*
+objects	index.txt	/*objects*
+obtaining-exted	netbeans.txt	/*obtaining-exted*
+ocaml.vim	syntax.txt	/*ocaml.vim*
+ole-activation	if_ole.txt	/*ole-activation*
+ole-eval	if_ole.txt	/*ole-eval*
+ole-gethwnd	if_ole.txt	/*ole-gethwnd*
+ole-interface	if_ole.txt	/*ole-interface*
+ole-methods	if_ole.txt	/*ole-methods*
+ole-normal	if_ole.txt	/*ole-normal*
+ole-registration	if_ole.txt	/*ole-registration*
+ole-sendkeys	if_ole.txt	/*ole-sendkeys*
+ole-setforeground	if_ole.txt	/*ole-setforeground*
+omni-sql-completion	sql.txt	/*omni-sql-completion*
+online-help	various.txt	/*online-help*
+opening-window	windows.txt	/*opening-window*
+operator	motion.txt	/*operator*
+option-backslash	options.txt	/*option-backslash*
+option-list	quickref.txt	/*option-list*
+option-summary	options.txt	/*option-summary*
+options	options.txt	/*options*
+options-changed	version5.txt	/*options-changed*
+options.txt	options.txt	/*options.txt*
+oracle	sql.txt	/*oracle*
+os2	os_os2.txt	/*os2*
+os2ansi	os_os2.txt	/*os2ansi*
+os390	os_390.txt	/*os390*
+os_390.txt	os_390.txt	/*os_390.txt*
+os_amiga.txt	os_amiga.txt	/*os_amiga.txt*
+os_beos.txt	os_beos.txt	/*os_beos.txt*
+os_dos.txt	os_dos.txt	/*os_dos.txt*
+os_mac.txt	os_mac.txt	/*os_mac.txt*
+os_mint.txt	os_mint.txt	/*os_mint.txt*
+os_msdos.txt	os_msdos.txt	/*os_msdos.txt*
+os_os2.txt	os_os2.txt	/*os_os2.txt*
+os_qnx.txt	os_qnx.txt	/*os_qnx.txt*
+os_risc.txt	os_risc.txt	/*os_risc.txt*
+os_unix.txt	os_unix.txt	/*os_unix.txt*
+os_vms.txt	os_vms.txt	/*os_vms.txt*
+os_win32.txt	os_win32.txt	/*os_win32.txt*
+other-features	vi_diff.txt	/*other-features*
+p	change.txt	/*p*
+page-down	intro.txt	/*page-down*
+page-up	intro.txt	/*page-up*
+page_down	intro.txt	/*page_down*
+page_up	intro.txt	/*page_up*
+pager	message.txt	/*pager*
+papp.vim	syntax.txt	/*papp.vim*
+paragraph	motion.txt	/*paragraph*
+pascal.vim	syntax.txt	/*pascal.vim*
+pathshorten()	eval.txt	/*pathshorten()*
+pattern	pattern.txt	/*pattern*
+pattern-atoms	pattern.txt	/*pattern-atoms*
+pattern-multi-byte	pattern.txt	/*pattern-multi-byte*
+pattern-multi-items	pattern.txt	/*pattern-multi-items*
+pattern-overview	pattern.txt	/*pattern-overview*
+pattern-searches	pattern.txt	/*pattern-searches*
+pattern.txt	pattern.txt	/*pattern.txt*
+patterns-composing	pattern.txt	/*patterns-composing*
+pdev-option	print.txt	/*pdev-option*
+penc-option	print.txt	/*penc-option*
+perl	if_perl.txt	/*perl*
+perl-Append	if_perl.txt	/*perl-Append*
+perl-Buffer	if_perl.txt	/*perl-Buffer*
+perl-Buffers	if_perl.txt	/*perl-Buffers*
+perl-Count	if_perl.txt	/*perl-Count*
+perl-Delete	if_perl.txt	/*perl-Delete*
+perl-DoCommand	if_perl.txt	/*perl-DoCommand*
+perl-Eval	if_perl.txt	/*perl-Eval*
+perl-Get	if_perl.txt	/*perl-Get*
+perl-GetCursor	if_perl.txt	/*perl-GetCursor*
+perl-Msg	if_perl.txt	/*perl-Msg*
+perl-Name	if_perl.txt	/*perl-Name*
+perl-Number	if_perl.txt	/*perl-Number*
+perl-Set	if_perl.txt	/*perl-Set*
+perl-SetHeight	if_perl.txt	/*perl-SetHeight*
+perl-SetOption	if_perl.txt	/*perl-SetOption*
+perl-Windows	if_perl.txt	/*perl-Windows*
+perl-compiling	if_perl.txt	/*perl-compiling*
+perl-dynamic	if_perl.txt	/*perl-dynamic*
+perl-editing	if_perl.txt	/*perl-editing*
+perl-overview	if_perl.txt	/*perl-overview*
+perl-patterns	pattern.txt	/*perl-patterns*
+perl-using	if_perl.txt	/*perl-using*
+perl.vim	syntax.txt	/*perl.vim*
+pexpr-option	print.txt	/*pexpr-option*
+pfn-option	print.txt	/*pfn-option*
+pheader-option	print.txt	/*pheader-option*
+photon-fonts	os_qnx.txt	/*photon-fonts*
+photon-gui	os_qnx.txt	/*photon-gui*
+php.vim	syntax.txt	/*php.vim*
+php3.vim	syntax.txt	/*php3.vim*
+phtml.vim	syntax.txt	/*phtml.vim*
+pi_getscript.txt	pi_getscript.txt	/*pi_getscript.txt*
+pi_gzip.txt	pi_gzip.txt	/*pi_gzip.txt*
+pi_netrw.txt	pi_netrw.txt	/*pi_netrw.txt*
+pi_paren.txt	pi_paren.txt	/*pi_paren.txt*
+pi_spec.txt	pi_spec.txt	/*pi_spec.txt*
+pi_tar.txt	pi_tar.txt	/*pi_tar.txt*
+pi_vimball.txt	pi_vimball.txt	/*pi_vimball.txt*
+pi_zip.txt	pi_zip.txt	/*pi_zip.txt*
+plaintex.vim	syntax.txt	/*plaintex.vim*
+plsql	sql.txt	/*plsql*
+plugin	usr_05.txt	/*plugin*
+plugin-details	filetype.txt	/*plugin-details*
+plugin-filetype	usr_41.txt	/*plugin-filetype*
+plugin-special	usr_41.txt	/*plugin-special*
+pmbcs-option	print.txt	/*pmbcs-option*
+pmbfn-option	print.txt	/*pmbfn-option*
+popt-option	print.txt	/*popt-option*
+popup-menu	gui.txt	/*popup-menu*
+popup-menu-added	version5.txt	/*popup-menu-added*
+popupmenu-completion	insert.txt	/*popupmenu-completion*
+popupmenu-keys	insert.txt	/*popupmenu-keys*
+ports-5.2	version5.txt	/*ports-5.2*
+ports-6	version6.txt	/*ports-6*
+posix	vi_diff.txt	/*posix*
+posix-compliance	vi_diff.txt	/*posix-compliance*
+posix-screen-size	vi_diff.txt	/*posix-screen-size*
+postgres	sql.txt	/*postgres*
+postscr.vim	syntax.txt	/*postscr.vim*
+postscript-cjk-printing	print.txt	/*postscript-cjk-printing*
+postscript-print-encoding	print.txt	/*postscript-print-encoding*
+postscript-print-trouble	print.txt	/*postscript-print-trouble*
+postscript-print-util	print.txt	/*postscript-print-util*
+postscript-printing	print.txt	/*postscript-printing*
+ppwiz.vim	syntax.txt	/*ppwiz.vim*
+press-enter	message.txt	/*press-enter*
+press-return	message.txt	/*press-return*
+prevcount-variable	eval.txt	/*prevcount-variable*
+preview-window	windows.txt	/*preview-window*
+prevnonblank()	eval.txt	/*prevnonblank()*
+print-intro	print.txt	/*print-intro*
+print-options	print.txt	/*print-options*
+print.txt	print.txt	/*print.txt*
+printf()	eval.txt	/*printf()*
+printing	print.txt	/*printing*
+printing-formfeed	print.txt	/*printing-formfeed*
+profile	repeat.txt	/*profile*
+profiling	repeat.txt	/*profiling*
+profiling-variable	eval.txt	/*profiling-variable*
+progname-variable	eval.txt	/*progname-variable*
+progress.vim	syntax.txt	/*progress.vim*
+psql	sql.txt	/*psql*
+ptcap.vim	syntax.txt	/*ptcap.vim*
+pterm-mouse	options.txt	/*pterm-mouse*
+pumvisible()	eval.txt	/*pumvisible()*
+put	change.txt	/*put*
+put-Visual-mode	change.txt	/*put-Visual-mode*
+python	if_pyth.txt	/*python*
+python-buffer	if_pyth.txt	/*python-buffer*
+python-buffers	if_pyth.txt	/*python-buffers*
+python-command	if_pyth.txt	/*python-command*
+python-commands	if_pyth.txt	/*python-commands*
+python-current	if_pyth.txt	/*python-current*
+python-dynamic	if_pyth.txt	/*python-dynamic*
+python-error	if_pyth.txt	/*python-error*
+python-eval	if_pyth.txt	/*python-eval*
+python-examples	if_pyth.txt	/*python-examples*
+python-input	if_pyth.txt	/*python-input*
+python-output	if_pyth.txt	/*python-output*
+python-range	if_pyth.txt	/*python-range*
+python-vim	if_pyth.txt	/*python-vim*
+python-window	if_pyth.txt	/*python-window*
+python-windows	if_pyth.txt	/*python-windows*
+python.vim	syntax.txt	/*python.vim*
+q	repeat.txt	/*q*
+q/	cmdline.txt	/*q\/*
+q:	cmdline.txt	/*q:*
+q?	cmdline.txt	/*q?*
+qnx	os_qnx.txt	/*qnx*
+qnx-compiling	os_qnx.txt	/*qnx-compiling*
+qnx-general	os_qnx.txt	/*qnx-general*
+qnx-terminal	os_qnx.txt	/*qnx-terminal*
+quake.vim	syntax.txt	/*quake.vim*
+quickfix	quickfix.txt	/*quickfix*
+quickfix-6	version6.txt	/*quickfix-6*
+quickfix-directory-stack	quickfix.txt	/*quickfix-directory-stack*
+quickfix-error-lists	quickfix.txt	/*quickfix-error-lists*
+quickfix-gcc	quickfix.txt	/*quickfix-gcc*
+quickfix-manx	quickfix.txt	/*quickfix-manx*
+quickfix-valid	quickfix.txt	/*quickfix-valid*
+quickfix-window	quickfix.txt	/*quickfix-window*
+quickfix.txt	quickfix.txt	/*quickfix.txt*
+quickref	quickref.txt	/*quickref*
+quickref.txt	quickref.txt	/*quickref.txt*
+quote	change.txt	/*quote*
+quote#	change.txt	/*quote#*
+quote%	change.txt	/*quote%*
+quote+	gui_x11.txt	/*quote+*
+quote-	change.txt	/*quote-*
+quote.	change.txt	/*quote.*
+quote/	change.txt	/*quote\/*
+quote0	change.txt	/*quote0*
+quote1	change.txt	/*quote1*
+quote2	change.txt	/*quote2*
+quote3	change.txt	/*quote3*
+quote4	change.txt	/*quote4*
+quote9	change.txt	/*quote9*
+quote:	change.txt	/*quote:*
+quote=	change.txt	/*quote=*
+quote_	change.txt	/*quote_*
+quote_#	change.txt	/*quote_#*
+quote_%	change.txt	/*quote_%*
+quote_-	change.txt	/*quote_-*
+quote_.	change.txt	/*quote_.*
+quote_/	change.txt	/*quote_\/*
+quote_:	change.txt	/*quote_:*
+quote_=	change.txt	/*quote_=*
+quote_alpha	change.txt	/*quote_alpha*
+quote_number	change.txt	/*quote_number*
+quote_quote	change.txt	/*quote_quote*
+quote_~	change.txt	/*quote_~*
+quotea	change.txt	/*quotea*
+quotecommandquote	intro.txt	/*quotecommandquote*
+quoteplus	gui_x11.txt	/*quoteplus*
+quotequote	change.txt	/*quotequote*
+quotes	quotes.txt	/*quotes*
+quotes.txt	quotes.txt	/*quotes.txt*
+quotestar	gui.txt	/*quotestar*
+quote~	change.txt	/*quote~*
+r	change.txt	/*r*
+range()	eval.txt	/*range()*
+raw-terminal-mode	term.txt	/*raw-terminal-mode*
+rcp	pi_netrw.txt	/*rcp*
+read-messages	insert.txt	/*read-messages*
+read-only-share	editing.txt	/*read-only-share*
+read-stdin	version5.txt	/*read-stdin*
+readfile()	eval.txt	/*readfile()*
+readline.vim	syntax.txt	/*readline.vim*
+recording	repeat.txt	/*recording*
+recover.txt	recover.txt	/*recover.txt*
+recovery	recover.txt	/*recovery*
+recursive_mapping	map.txt	/*recursive_mapping*
+redo	undo.txt	/*redo*
+redo-register	undo.txt	/*redo-register*
+ref	intro.txt	/*ref*
+reference	intro.txt	/*reference*
+reference_toc	help.txt	/*reference_toc*
+regexp	pattern.txt	/*regexp*
+regexp-changes-5.4	version5.txt	/*regexp-changes-5.4*
+register	sponsor.txt	/*register*
+register-faq	sponsor.txt	/*register-faq*
+register-variable	eval.txt	/*register-variable*
+registers	change.txt	/*registers*
+regular-expression	pattern.txt	/*regular-expression*
+reltime()	eval.txt	/*reltime()*
+reltimestr()	eval.txt	/*reltimestr()*
+remote.txt	remote.txt	/*remote.txt*
+remote_expr()	eval.txt	/*remote_expr()*
+remote_foreground()	eval.txt	/*remote_foreground()*
+remote_peek()	eval.txt	/*remote_peek()*
+remote_read()	eval.txt	/*remote_read()*
+remote_send()	eval.txt	/*remote_send()*
+remove()	eval.txt	/*remove()*
+remove-filetype	filetype.txt	/*remove-filetype*
+remove-option-flags	options.txt	/*remove-option-flags*
+rename()	eval.txt	/*rename()*
+rename-files	tips.txt	/*rename-files*
+repeat()	eval.txt	/*repeat()*
+repeat.txt	repeat.txt	/*repeat.txt*
+repeating	repeat.txt	/*repeating*
+replacing	change.txt	/*replacing*
+replacing-ex	insert.txt	/*replacing-ex*
+reselect-Visual	visual.txt	/*reselect-Visual*
+resolve()	eval.txt	/*resolve()*
+restore-cursor	usr_05.txt	/*restore-cursor*
+restore-position	tips.txt	/*restore-position*
+restricted-mode	starting.txt	/*restricted-mode*
+retab-example	change.txt	/*retab-example*
+rethrow	eval.txt	/*rethrow*
+reverse()	eval.txt	/*reverse()*
+rexx.vim	syntax.txt	/*rexx.vim*
+rgb.txt	gui_w32.txt	/*rgb.txt*
+rgview	starting.txt	/*rgview*
+rgvim	starting.txt	/*rgvim*
+right-justify	change.txt	/*right-justify*
+rileft	rileft.txt	/*rileft*
+rileft.txt	rileft.txt	/*rileft.txt*
+riscos	os_risc.txt	/*riscos*
+riscos-commandline	os_risc.txt	/*riscos-commandline*
+riscos-filetypes	os_risc.txt	/*riscos-filetypes*
+riscos-gui	os_risc.txt	/*riscos-gui*
+riscos-interrupt	os_risc.txt	/*riscos-interrupt*
+riscos-locations	os_risc.txt	/*riscos-locations*
+riscos-memory	os_risc.txt	/*riscos-memory*
+riscos-munging	os_risc.txt	/*riscos-munging*
+riscos-porting	os_risc.txt	/*riscos-porting*
+riscos-remote	os_risc.txt	/*riscos-remote*
+riscos-shell	os_risc.txt	/*riscos-shell*
+riscos-temp-files	os_risc.txt	/*riscos-temp-files*
+rot13	change.txt	/*rot13*
+rsync	pi_netrw.txt	/*rsync*
+ruby	if_ruby.txt	/*ruby*
+ruby-buffer	if_ruby.txt	/*ruby-buffer*
+ruby-command	if_ruby.txt	/*ruby-command*
+ruby-commands	if_ruby.txt	/*ruby-commands*
+ruby-dynamic	if_ruby.txt	/*ruby-dynamic*
+ruby-evaluate	if_ruby.txt	/*ruby-evaluate*
+ruby-globals	if_ruby.txt	/*ruby-globals*
+ruby-message	if_ruby.txt	/*ruby-message*
+ruby-set_option	if_ruby.txt	/*ruby-set_option*
+ruby-vim	if_ruby.txt	/*ruby-vim*
+ruby-window	if_ruby.txt	/*ruby-window*
+ruby.vim	syntax.txt	/*ruby.vim*
+russian	russian.txt	/*russian*
+russian-intro	russian.txt	/*russian-intro*
+russian-issues	russian.txt	/*russian-issues*
+russian-keymap	russian.txt	/*russian-keymap*
+russian-l18n	russian.txt	/*russian-l18n*
+russian.txt	russian.txt	/*russian.txt*
+rview	starting.txt	/*rview*
+rvim	starting.txt	/*rvim*
+rxvt	syntax.txt	/*rxvt*
+s	change.txt	/*s*
+s/\&	change.txt	/*s\/\\&*
+s/\0	change.txt	/*s\/\\0*
+s/\1	change.txt	/*s\/\\1*
+s/\2	change.txt	/*s\/\\2*
+s/\3	change.txt	/*s\/\\3*
+s/\9	change.txt	/*s\/\\9*
+s/\<CR>	change.txt	/*s\/\\<CR>*
+s/\E	change.txt	/*s\/\\E*
+s/\L	change.txt	/*s\/\\L*
+s/\U	change.txt	/*s\/\\U*
+s/\\	change.txt	/*s\/\\\\*
+s/\b	change.txt	/*s\/\\b*
+s/\e	change.txt	/*s\/\\e*
+s/\l	change.txt	/*s\/\\l*
+s/\n	change.txt	/*s\/\\n*
+s/\r	change.txt	/*s\/\\r*
+s/\t	change.txt	/*s\/\\t*
+s/\u	change.txt	/*s\/\\u*
+s/\~	change.txt	/*s\/\\~*
+s:var	eval.txt	/*s:var*
+s<CR>	change.txt	/*s<CR>*
+sandbox	eval.txt	/*sandbox*
+sandbox-option	eval.txt	/*sandbox-option*
+save-file	editing.txt	/*save-file*
+save-settings	starting.txt	/*save-settings*
+scheme.vim	syntax.txt	/*scheme.vim*
+scp	pi_netrw.txt	/*scp*
+script	usr_41.txt	/*script*
+script-here	if_perl.txt	/*script-here*
+script-local	map.txt	/*script-local*
+script-variable	eval.txt	/*script-variable*
+scriptnames-dictionary	eval.txt	/*scriptnames-dictionary*
+scriptout-changed	version4.txt	/*scriptout-changed*
+scroll-binding	scroll.txt	/*scroll-binding*
+scroll-cursor	scroll.txt	/*scroll-cursor*
+scroll-down	scroll.txt	/*scroll-down*
+scroll-horizontal	scroll.txt	/*scroll-horizontal*
+scroll-insert	tips.txt	/*scroll-insert*
+scroll-mouse-wheel	scroll.txt	/*scroll-mouse-wheel*
+scroll-region	term.txt	/*scroll-region*
+scroll-smooth	tips.txt	/*scroll-smooth*
+scroll-up	scroll.txt	/*scroll-up*
+scroll.txt	scroll.txt	/*scroll.txt*
+scrollbind-quickadj	scroll.txt	/*scrollbind-quickadj*
+scrollbind-relative	scroll.txt	/*scrollbind-relative*
+scrolling	scroll.txt	/*scrolling*
+scrollstart-variable	eval.txt	/*scrollstart-variable*
+sdl.vim	syntax.txt	/*sdl.vim*
+search()	eval.txt	/*search()*
+search()-sub-match	eval.txt	/*search()-sub-match*
+search-commands	pattern.txt	/*search-commands*
+search-offset	pattern.txt	/*search-offset*
+search-pattern	pattern.txt	/*search-pattern*
+search-range	pattern.txt	/*search-range*
+search-replace	change.txt	/*search-replace*
+searchdecl()	eval.txt	/*searchdecl()*
+searchpair()	eval.txt	/*searchpair()*
+searchpairpos()	eval.txt	/*searchpairpos()*
+searchpos()	eval.txt	/*searchpos()*
+section	motion.txt	/*section*
+sed.vim	syntax.txt	/*sed.vim*
+self	eval.txt	/*self*
+send-money	sponsor.txt	/*send-money*
+send-to-menu	gui_w32.txt	/*send-to-menu*
+sendto	gui_w32.txt	/*sendto*
+sentence	motion.txt	/*sentence*
+server2client()	eval.txt	/*server2client()*
+serverlist()	eval.txt	/*serverlist()*
+servername-variable	eval.txt	/*servername-variable*
+session-file	starting.txt	/*session-file*
+set-option	options.txt	/*set-option*
+set-spc-auto	spell.txt	/*set-spc-auto*
+setbufvar()	eval.txt	/*setbufvar()*
+setcmdpos()	eval.txt	/*setcmdpos()*
+setline()	eval.txt	/*setline()*
+setloclist()	eval.txt	/*setloclist()*
+setpos()	eval.txt	/*setpos()*
+setqflist()	eval.txt	/*setqflist()*
+setreg()	eval.txt	/*setreg()*
+settabwinvar()	eval.txt	/*settabwinvar()*
+setting-guifont	gui.txt	/*setting-guifont*
+setting-guitablabel	tabpage.txt	/*setting-guitablabel*
+setting-tabline	tabpage.txt	/*setting-tabline*
+setwinvar()	eval.txt	/*setwinvar()*
+sftp	pi_netrw.txt	/*sftp*
+sgml.vim	syntax.txt	/*sgml.vim*
+sh.vim	syntax.txt	/*sh.vim*
+shell-window	tips.txt	/*shell-window*
+shell_error-variable	eval.txt	/*shell_error-variable*
+shellescape()	eval.txt	/*shellescape()*
+shift	intro.txt	/*shift*
+shift-left-right	change.txt	/*shift-left-right*
+short-name-changed	version4.txt	/*short-name-changed*
+showing-menus	gui.txt	/*showing-menus*
+sign-commands	sign.txt	/*sign-commands*
+sign-intro	sign.txt	/*sign-intro*
+sign-support	sign.txt	/*sign-support*
+sign.txt	sign.txt	/*sign.txt*
+signs	sign.txt	/*signs*
+simple-change	change.txt	/*simple-change*
+simplify()	eval.txt	/*simplify()*
+simulated-command	vi_diff.txt	/*simulated-command*
+single-repeat	repeat.txt	/*single-repeat*
+skeleton	autocmd.txt	/*skeleton*
+slow-fast-terminal	term.txt	/*slow-fast-terminal*
+slow-start	starting.txt	/*slow-start*
+slow-terminal	term.txt	/*slow-terminal*
+sniff	if_sniff.txt	/*sniff*
+sniff-commands	if_sniff.txt	/*sniff-commands*
+sniff-compiling	if_sniff.txt	/*sniff-compiling*
+sniff-intro	if_sniff.txt	/*sniff-intro*
+sort()	eval.txt	/*sort()*
+sorting	change.txt	/*sorting*
+soundfold()	eval.txt	/*soundfold()*
+space	intro.txt	/*space*
+spec-customizing	pi_spec.txt	/*spec-customizing*
+spec-how-to-use-it	pi_spec.txt	/*spec-how-to-use-it*
+spec-setting-a-map	pi_spec.txt	/*spec-setting-a-map*
+spec_chglog_format	pi_spec.txt	/*spec_chglog_format*
+spec_chglog_prepend	pi_spec.txt	/*spec_chglog_prepend*
+spec_chglog_release_info	pi_spec.txt	/*spec_chglog_release_info*
+special-buffers	windows.txt	/*special-buffers*
+speed-up	tips.txt	/*speed-up*
+spell	spell.txt	/*spell*
+spell-ACCENT	spell.txt	/*spell-ACCENT*
+spell-AUTHOR	spell.txt	/*spell-AUTHOR*
+spell-BAD	spell.txt	/*spell-BAD*
+spell-CHECKCOMPOUNDCASE	spell.txt	/*spell-CHECKCOMPOUNDCASE*
+spell-CHECKCOMPOUNDDUP	spell.txt	/*spell-CHECKCOMPOUNDDUP*
+spell-CHECKCOMPOUNDPATTERN	spell.txt	/*spell-CHECKCOMPOUNDPATTERN*
+spell-CHECKCOMPOUNDREP	spell.txt	/*spell-CHECKCOMPOUNDREP*
+spell-CHECKCOMPOUNDTRIPLE	spell.txt	/*spell-CHECKCOMPOUNDTRIPLE*
+spell-CIRCUMFIX	spell.txt	/*spell-CIRCUMFIX*
+spell-COMMON	spell.txt	/*spell-COMMON*
+spell-COMPLEXPREFIXES	spell.txt	/*spell-COMPLEXPREFIXES*
+spell-COMPOUND	spell.txt	/*spell-COMPOUND*
+spell-COMPOUNDBEGIN	spell.txt	/*spell-COMPOUNDBEGIN*
+spell-COMPOUNDEND	spell.txt	/*spell-COMPOUNDEND*
+spell-COMPOUNDFIRST	spell.txt	/*spell-COMPOUNDFIRST*
+spell-COMPOUNDFLAG	spell.txt	/*spell-COMPOUNDFLAG*
+spell-COMPOUNDFORBIDFLAG	spell.txt	/*spell-COMPOUNDFORBIDFLAG*
+spell-COMPOUNDMIDDLE	spell.txt	/*spell-COMPOUNDMIDDLE*
+spell-COMPOUNDMIN	spell.txt	/*spell-COMPOUNDMIN*
+spell-COMPOUNDPERMITFLAG	spell.txt	/*spell-COMPOUNDPERMITFLAG*
+spell-COMPOUNDROOT	spell.txt	/*spell-COMPOUNDROOT*
+spell-COMPOUNDRULE	spell.txt	/*spell-COMPOUNDRULE*
+spell-COMPOUNDSYLLABLE	spell.txt	/*spell-COMPOUNDSYLLABLE*
+spell-COMPOUNDSYLMAX	spell.txt	/*spell-COMPOUNDSYLMAX*
+spell-COMPOUNDWORDMAX	spell.txt	/*spell-COMPOUNDWORDMAX*
+spell-COPYRIGHT	spell.txt	/*spell-COPYRIGHT*
+spell-EMAIL	spell.txt	/*spell-EMAIL*
+spell-FLAG	spell.txt	/*spell-FLAG*
+spell-FOL	spell.txt	/*spell-FOL*
+spell-FORBIDDENWORD	spell.txt	/*spell-FORBIDDENWORD*
+spell-HOME	spell.txt	/*spell-HOME*
+spell-KEEPCASE	spell.txt	/*spell-KEEPCASE*
+spell-LANG	spell.txt	/*spell-LANG*
+spell-LEMMA_PRESENT	spell.txt	/*spell-LEMMA_PRESENT*
+spell-LOW	spell.txt	/*spell-LOW*
+spell-MAP	spell.txt	/*spell-MAP*
+spell-MAXNGRAMSUGS	spell.txt	/*spell-MAXNGRAMSUGS*
+spell-NAME	spell.txt	/*spell-NAME*
+spell-NEEDAFFIX	spell.txt	/*spell-NEEDAFFIX*
+spell-NEEDCOMPOUND	spell.txt	/*spell-NEEDCOMPOUND*
+spell-NOBREAK	spell.txt	/*spell-NOBREAK*
+spell-NOSPLITSUGS	spell.txt	/*spell-NOSPLITSUGS*
+spell-NOSUGFILE	spell.txt	/*spell-NOSUGFILE*
+spell-NOSUGGEST	spell.txt	/*spell-NOSUGGEST*
+spell-ONLYINCOMPOUND	spell.txt	/*spell-ONLYINCOMPOUND*
+spell-PFX	spell.txt	/*spell-PFX*
+spell-PFXPOSTPONE	spell.txt	/*spell-PFXPOSTPONE*
+spell-PSEUDOROOT	spell.txt	/*spell-PSEUDOROOT*
+spell-RARE	spell.txt	/*spell-RARE*
+spell-REP	spell.txt	/*spell-REP*
+spell-SAL	spell.txt	/*spell-SAL*
+spell-SET	spell.txt	/*spell-SET*
+spell-SFX	spell.txt	/*spell-SFX*
+spell-SLASH	spell.txt	/*spell-SLASH*
+spell-SOFOFROM	spell.txt	/*spell-SOFOFROM*
+spell-SOFOTO	spell.txt	/*spell-SOFOTO*
+spell-SUGSWITHDOTS	spell.txt	/*spell-SUGSWITHDOTS*
+spell-SYLLABLE	spell.txt	/*spell-SYLLABLE*
+spell-SYLLABLENUM	spell.txt	/*spell-SYLLABLENUM*
+spell-SpellFileMissing	spell.txt	/*spell-SpellFileMissing*
+spell-TRY	spell.txt	/*spell-TRY*
+spell-UPP	spell.txt	/*spell-UPP*
+spell-VERSION	spell.txt	/*spell-VERSION*
+spell-WORDCHARS	spell.txt	/*spell-WORDCHARS*
+spell-aff-format	spell.txt	/*spell-aff-format*
+spell-affix-chars	spell.txt	/*spell-affix-chars*
+spell-affix-comment	spell.txt	/*spell-affix-comment*
+spell-affix-flags	spell.txt	/*spell-affix-flags*
+spell-affix-mbyte	spell.txt	/*spell-affix-mbyte*
+spell-affix-not-supported	spell.txt	/*spell-affix-not-supported*
+spell-affix-vim	spell.txt	/*spell-affix-vim*
+spell-compound	spell.txt	/*spell-compound*
+spell-dic-format	spell.txt	/*spell-dic-format*
+spell-double-scoring	spell.txt	/*spell-double-scoring*
+spell-file-format	spell.txt	/*spell-file-format*
+spell-german	spell.txt	/*spell-german*
+spell-load	spell.txt	/*spell-load*
+spell-midword	spell.txt	/*spell-midword*
+spell-mkspell	spell.txt	/*spell-mkspell*
+spell-quickstart	spell.txt	/*spell-quickstart*
+spell-remarks	spell.txt	/*spell-remarks*
+spell-russian	spell.txt	/*spell-russian*
+spell-sug-file	spell.txt	/*spell-sug-file*
+spell-syntax	spell.txt	/*spell-syntax*
+spell-wordlist-format	spell.txt	/*spell-wordlist-format*
+spell-yiddish	spell.txt	/*spell-yiddish*
+spell.txt	spell.txt	/*spell.txt*
+spellbadword()	eval.txt	/*spellbadword()*
+spellfile-cleanup	spell.txt	/*spellfile-cleanup*
+spellfile.vim	spell.txt	/*spellfile.vim*
+spellsuggest()	eval.txt	/*spellsuggest()*
+split()	eval.txt	/*split()*
+splitfind	windows.txt	/*splitfind*
+splitview	windows.txt	/*splitview*
+sponsor	sponsor.txt	/*sponsor*
+sponsor-faq	sponsor.txt	/*sponsor-faq*
+sponsor.txt	sponsor.txt	/*sponsor.txt*
+spoon	os_unix.txt	/*spoon*
+spup.vim	syntax.txt	/*spup.vim*
+sql-adding-dialects	sql.txt	/*sql-adding-dialects*
+sql-completion	sql.txt	/*sql-completion*
+sql-completion-columns	sql.txt	/*sql-completion-columns*
+sql-completion-customization	sql.txt	/*sql-completion-customization*
+sql-completion-dynamic	sql.txt	/*sql-completion-dynamic*
+sql-completion-filetypes	sql.txt	/*sql-completion-filetypes*
+sql-completion-maps	sql.txt	/*sql-completion-maps*
+sql-completion-procedures	sql.txt	/*sql-completion-procedures*
+sql-completion-static	sql.txt	/*sql-completion-static*
+sql-completion-tables	sql.txt	/*sql-completion-tables*
+sql-completion-tutorial	sql.txt	/*sql-completion-tutorial*
+sql-completion-views	sql.txt	/*sql-completion-views*
+sql-dialects	sql.txt	/*sql-dialects*
+sql-macros	sql.txt	/*sql-macros*
+sql-matchit	sql.txt	/*sql-matchit*
+sql-navigation	sql.txt	/*sql-navigation*
+sql-object-motions	sql.txt	/*sql-object-motions*
+sql-predefined-objects	sql.txt	/*sql-predefined-objects*
+sql-type-default	sql.txt	/*sql-type-default*
+sql-types	sql.txt	/*sql-types*
+sql.txt	sql.txt	/*sql.txt*
+sql.vim	syntax.txt	/*sql.vim*
+sqlanywhere	sql.txt	/*sqlanywhere*
+sqlanywhere.vim	syntax.txt	/*sqlanywhere.vim*
+sqlinformix.vim	syntax.txt	/*sqlinformix.vim*
+sqlj	sql.txt	/*sqlj*
+sqlserver	sql.txt	/*sqlserver*
+sqlsettype	sql.txt	/*sqlsettype*
+sscanf	eval.txt	/*sscanf*
+standard-plugin	usr_05.txt	/*standard-plugin*
+standard-plugin-list	help.txt	/*standard-plugin-list*
+standout	syntax.txt	/*standout*
+star	pattern.txt	/*star*
+starstar	editing.txt	/*starstar*
+starstar-wildcard	editing.txt	/*starstar-wildcard*
+start-of-file	pattern.txt	/*start-of-file*
+starting	starting.txt	/*starting*
+starting-amiga	starting.txt	/*starting-amiga*
+starting.txt	starting.txt	/*starting.txt*
+startup	starting.txt	/*startup*
+startup-options	starting.txt	/*startup-options*
+startup-terminal	term.txt	/*startup-terminal*
+static-tag	tagsrch.txt	/*static-tag*
+status-line	windows.txt	/*status-line*
+statusmsg-variable	eval.txt	/*statusmsg-variable*
+str2nr()	eval.txt	/*str2nr()*
+strcasestr()	eval.txt	/*strcasestr()*
+strchr()	eval.txt	/*strchr()*
+strcspn()	eval.txt	/*strcspn()*
+strftime()	eval.txt	/*strftime()*
+stridx()	eval.txt	/*stridx()*
+string()	eval.txt	/*string()*
+string-match	eval.txt	/*string-match*
+strlen()	eval.txt	/*strlen()*
+strpart()	eval.txt	/*strpart()*
+strpbrk()	eval.txt	/*strpbrk()*
+strrchr()	eval.txt	/*strrchr()*
+strridx()	eval.txt	/*strridx()*
+strspn()	eval.txt	/*strspn()*
+strstr()	eval.txt	/*strstr()*
+strtrans()	eval.txt	/*strtrans()*
+style-changes	develop.txt	/*style-changes*
+style-examples	develop.txt	/*style-examples*
+style-functions	develop.txt	/*style-functions*
+style-names	develop.txt	/*style-names*
+style-spaces	develop.txt	/*style-spaces*
+style-various	develop.txt	/*style-various*
+sub-menu-priority	gui.txt	/*sub-menu-priority*
+sub-replace-\=	change.txt	/*sub-replace-\\=*
+sub-replace-expression	change.txt	/*sub-replace-expression*
+sub-replace-special	change.txt	/*sub-replace-special*
+submatch()	eval.txt	/*submatch()*
+subscribe-maillist	intro.txt	/*subscribe-maillist*
+substitute()	eval.txt	/*substitute()*
+substitute-CR	version6.txt	/*substitute-CR*
+suffixes	cmdline.txt	/*suffixes*
+suspend	starting.txt	/*suspend*
+swap-file	recover.txt	/*swap-file*
+swapchoice-variable	eval.txt	/*swapchoice-variable*
+swapcommand-variable	eval.txt	/*swapcommand-variable*
+swapfile-changed	version4.txt	/*swapfile-changed*
+swapname-variable	eval.txt	/*swapname-variable*
+sybase	sql.txt	/*sybase*
+syn-sync-grouphere	syntax.txt	/*syn-sync-grouphere*
+syn-sync-groupthere	syntax.txt	/*syn-sync-groupthere*
+syn-sync-linecont	syntax.txt	/*syn-sync-linecont*
+synID()	eval.txt	/*synID()*
+synIDattr()	eval.txt	/*synIDattr()*
+synIDtrans()	eval.txt	/*synIDtrans()*
+syncbind	scroll.txt	/*syncbind*
+syncolor	syntax.txt	/*syncolor*
+synload-1	syntax.txt	/*synload-1*
+synload-2	syntax.txt	/*synload-2*
+synload-3	syntax.txt	/*synload-3*
+synload-4	syntax.txt	/*synload-4*
+synload-5	syntax.txt	/*synload-5*
+synload-6	syntax.txt	/*synload-6*
+syntax	syntax.txt	/*syntax*
+syntax-highlighting	syntax.txt	/*syntax-highlighting*
+syntax-loading	syntax.txt	/*syntax-loading*
+syntax-printing	usr_06.txt	/*syntax-printing*
+syntax.txt	syntax.txt	/*syntax.txt*
+syntax_cmd	syntax.txt	/*syntax_cmd*
+sys-file-list	help.txt	/*sys-file-list*
+system()	eval.txt	/*system()*
+system-vimrc	starting.txt	/*system-vimrc*
+s~	change.txt	/*s~*
+t	motion.txt	/*t*
+t:var	eval.txt	/*t:var*
+t_#2	term.txt	/*t_#2*
+t_#4	term.txt	/*t_#4*
+t_%1	term.txt	/*t_%1*
+t_%i	term.txt	/*t_%i*
+t_&8	term.txt	/*t_&8*
+t_@7	term.txt	/*t_@7*
+t_AB	term.txt	/*t_AB*
+t_AF	term.txt	/*t_AF*
+t_AL	term.txt	/*t_AL*
+t_CS	term.txt	/*t_CS*
+t_CV	term.txt	/*t_CV*
+t_Ce	term.txt	/*t_Ce*
+t_Co	term.txt	/*t_Co*
+t_Cs	term.txt	/*t_Cs*
+t_DL	term.txt	/*t_DL*
+t_EI	term.txt	/*t_EI*
+t_F1	term.txt	/*t_F1*
+t_F2	term.txt	/*t_F2*
+t_F3	term.txt	/*t_F3*
+t_F4	term.txt	/*t_F4*
+t_F5	term.txt	/*t_F5*
+t_F6	term.txt	/*t_F6*
+t_F7	term.txt	/*t_F7*
+t_F8	term.txt	/*t_F8*
+t_F9	term.txt	/*t_F9*
+t_IE	term.txt	/*t_IE*
+t_IS	term.txt	/*t_IS*
+t_K1	term.txt	/*t_K1*
+t_K3	term.txt	/*t_K3*
+t_K4	term.txt	/*t_K4*
+t_K5	term.txt	/*t_K5*
+t_K6	term.txt	/*t_K6*
+t_K7	term.txt	/*t_K7*
+t_K8	term.txt	/*t_K8*
+t_K9	term.txt	/*t_K9*
+t_KA	term.txt	/*t_KA*
+t_KB	term.txt	/*t_KB*
+t_KC	term.txt	/*t_KC*
+t_KD	term.txt	/*t_KD*
+t_KE	term.txt	/*t_KE*
+t_KF	term.txt	/*t_KF*
+t_KG	term.txt	/*t_KG*
+t_KH	term.txt	/*t_KH*
+t_KI	term.txt	/*t_KI*
+t_KJ	term.txt	/*t_KJ*
+t_KK	term.txt	/*t_KK*
+t_KL	term.txt	/*t_KL*
+t_RI	term.txt	/*t_RI*
+t_RV	term.txt	/*t_RV*
+t_SI	term.txt	/*t_SI*
+t_Sb	term.txt	/*t_Sb*
+t_Sf	term.txt	/*t_Sf*
+t_WP	term.txt	/*t_WP*
+t_WS	term.txt	/*t_WS*
+t_ZH	term.txt	/*t_ZH*
+t_ZR	term.txt	/*t_ZR*
+t_al	term.txt	/*t_al*
+t_bc	term.txt	/*t_bc*
+t_cd	term.txt	/*t_cd*
+t_cdl	version4.txt	/*t_cdl*
+t_ce	term.txt	/*t_ce*
+t_ci	version4.txt	/*t_ci*
+t_cil	version4.txt	/*t_cil*
+t_cl	term.txt	/*t_cl*
+t_cm	term.txt	/*t_cm*
+t_cri	version4.txt	/*t_cri*
+t_cs	term.txt	/*t_cs*
+t_csc	version4.txt	/*t_csc*
+t_cv	version4.txt	/*t_cv*
+t_cvv	version4.txt	/*t_cvv*
+t_da	term.txt	/*t_da*
+t_db	term.txt	/*t_db*
+t_dl	term.txt	/*t_dl*
+t_ed	version4.txt	/*t_ed*
+t_el	version4.txt	/*t_el*
+t_f1	version4.txt	/*t_f1*
+t_f10	version4.txt	/*t_f10*
+t_f2	version4.txt	/*t_f2*
+t_f3	version4.txt	/*t_f3*
+t_f4	version4.txt	/*t_f4*
+t_f5	version4.txt	/*t_f5*
+t_f6	version4.txt	/*t_f6*
+t_f7	version4.txt	/*t_f7*
+t_f8	version4.txt	/*t_f8*
+t_f9	version4.txt	/*t_f9*
+t_fs	term.txt	/*t_fs*
+t_help	version4.txt	/*t_help*
+t_il	version4.txt	/*t_il*
+t_k1	term.txt	/*t_k1*
+t_k2	term.txt	/*t_k2*
+t_k3	term.txt	/*t_k3*
+t_k4	term.txt	/*t_k4*
+t_k5	term.txt	/*t_k5*
+t_k6	term.txt	/*t_k6*
+t_k7	term.txt	/*t_k7*
+t_k8	term.txt	/*t_k8*
+t_k9	term.txt	/*t_k9*
+t_k;	term.txt	/*t_k;*
+t_kB	term.txt	/*t_kB*
+t_kD	term.txt	/*t_kD*
+t_kI	term.txt	/*t_kI*
+t_kN	term.txt	/*t_kN*
+t_kP	term.txt	/*t_kP*
+t_kb	term.txt	/*t_kb*
+t_kd	term.txt	/*t_kd*
+t_ke	term.txt	/*t_ke*
+t_kh	term.txt	/*t_kh*
+t_kl	term.txt	/*t_kl*
+t_kr	term.txt	/*t_kr*
+t_ks	term.txt	/*t_ks*
+t_ku	term.txt	/*t_ku*
+t_le	term.txt	/*t_le*
+t_mb	term.txt	/*t_mb*
+t_md	term.txt	/*t_md*
+t_me	term.txt	/*t_me*
+t_mr	term.txt	/*t_mr*
+t_ms	term.txt	/*t_ms*
+t_nd	term.txt	/*t_nd*
+t_op	term.txt	/*t_op*
+t_se	term.txt	/*t_se*
+t_sf1	version4.txt	/*t_sf1*
+t_sf10	version4.txt	/*t_sf10*
+t_sf2	version4.txt	/*t_sf2*
+t_sf3	version4.txt	/*t_sf3*
+t_sf4	version4.txt	/*t_sf4*
+t_sf5	version4.txt	/*t_sf5*
+t_sf6	version4.txt	/*t_sf6*
+t_sf7	version4.txt	/*t_sf7*
+t_sf8	version4.txt	/*t_sf8*
+t_sf9	version4.txt	/*t_sf9*
+t_skd	version4.txt	/*t_skd*
+t_skl	version4.txt	/*t_skl*
+t_skr	version4.txt	/*t_skr*
+t_sku	version4.txt	/*t_sku*
+t_so	term.txt	/*t_so*
+t_sr	term.txt	/*t_sr*
+t_star7	term.txt	/*t_star7*
+t_tb	version4.txt	/*t_tb*
+t_te	term.txt	/*t_te*
+t_ti	term.txt	/*t_ti*
+t_tp	version4.txt	/*t_tp*
+t_ts	term.txt	/*t_ts*
+t_ts_old	version4.txt	/*t_ts_old*
+t_ue	term.txt	/*t_ue*
+t_undo	version4.txt	/*t_undo*
+t_us	term.txt	/*t_us*
+t_ut	term.txt	/*t_ut*
+t_vb	term.txt	/*t_vb*
+t_ve	term.txt	/*t_ve*
+t_vi	term.txt	/*t_vi*
+t_vs	term.txt	/*t_vs*
+t_xs	term.txt	/*t_xs*
+tab	intro.txt	/*tab*
+tab-page	tabpage.txt	/*tab-page*
+tab-page-commands	tabpage.txt	/*tab-page-commands*
+tab-page-intro	tabpage.txt	/*tab-page-intro*
+tab-page-other	tabpage.txt	/*tab-page-other*
+tabline-menu	tabpage.txt	/*tabline-menu*
+tabpage	tabpage.txt	/*tabpage*
+tabpage-variable	eval.txt	/*tabpage-variable*
+tabpage.txt	tabpage.txt	/*tabpage.txt*
+tabpagebuflist()	eval.txt	/*tabpagebuflist()*
+tabpagenr()	eval.txt	/*tabpagenr()*
+tabpagewinnr()	eval.txt	/*tabpagewinnr()*
+tag	tagsrch.txt	/*tag*
+tag-!	tagsrch.txt	/*tag-!*
+tag-any-white	tagsrch.txt	/*tag-any-white*
+tag-binary-search	tagsrch.txt	/*tag-binary-search*
+tag-blocks	motion.txt	/*tag-blocks*
+tag-commands	tagsrch.txt	/*tag-commands*
+tag-details	tagsrch.txt	/*tag-details*
+tag-highlight	syntax.txt	/*tag-highlight*
+tag-matchlist	tagsrch.txt	/*tag-matchlist*
+tag-old-static	tagsrch.txt	/*tag-old-static*
+tag-overloaded	version5.txt	/*tag-overloaded*
+tag-preview	tagsrch.txt	/*tag-preview*
+tag-priority	tagsrch.txt	/*tag-priority*
+tag-regexp	tagsrch.txt	/*tag-regexp*
+tag-search	tagsrch.txt	/*tag-search*
+tag-security	tagsrch.txt	/*tag-security*
+tag-skip-file	tagsrch.txt	/*tag-skip-file*
+tag-stack	tagsrch.txt	/*tag-stack*
+tagfiles()	eval.txt	/*tagfiles()*
+taglist()	eval.txt	/*taglist()*
+tags	tagsrch.txt	/*tags*
+tags-and-searches	tagsrch.txt	/*tags-and-searches*
+tags-file-changed	version5.txt	/*tags-file-changed*
+tags-file-format	tagsrch.txt	/*tags-file-format*
+tags-option	tagsrch.txt	/*tags-option*
+tagsrch.txt	tagsrch.txt	/*tagsrch.txt*
+tagstack	tagsrch.txt	/*tagstack*
+tar	pi_tar.txt	/*tar*
+tar-contents	pi_tar.txt	/*tar-contents*
+tar-copyright	pi_tar.txt	/*tar-copyright*
+tar-history	pi_tar.txt	/*tar-history*
+tar-manual	pi_tar.txt	/*tar-manual*
+tar-options	pi_tar.txt	/*tar-options*
+tar-usage	pi_tar.txt	/*tar-usage*
+tcl	if_tcl.txt	/*tcl*
+tcl-beep	if_tcl.txt	/*tcl-beep*
+tcl-buffer	if_tcl.txt	/*tcl-buffer*
+tcl-buffer-append	if_tcl.txt	/*tcl-buffer-append*
+tcl-buffer-cmds	if_tcl.txt	/*tcl-buffer-cmds*
+tcl-buffer-command	if_tcl.txt	/*tcl-buffer-command*
+tcl-buffer-count	if_tcl.txt	/*tcl-buffer-count*
+tcl-buffer-delcmd	if_tcl.txt	/*tcl-buffer-delcmd*
+tcl-buffer-delete	if_tcl.txt	/*tcl-buffer-delete*
+tcl-buffer-expr	if_tcl.txt	/*tcl-buffer-expr*
+tcl-buffer-get	if_tcl.txt	/*tcl-buffer-get*
+tcl-buffer-insert	if_tcl.txt	/*tcl-buffer-insert*
+tcl-buffer-last	if_tcl.txt	/*tcl-buffer-last*
+tcl-buffer-mark	if_tcl.txt	/*tcl-buffer-mark*
+tcl-buffer-option	if_tcl.txt	/*tcl-buffer-option*
+tcl-buffer-set	if_tcl.txt	/*tcl-buffer-set*
+tcl-buffer-windows	if_tcl.txt	/*tcl-buffer-windows*
+tcl-bugs	if_tcl.txt	/*tcl-bugs*
+tcl-command	if_tcl.txt	/*tcl-command*
+tcl-commands	if_tcl.txt	/*tcl-commands*
+tcl-dynamic	if_tcl.txt	/*tcl-dynamic*
+tcl-ex-commands	if_tcl.txt	/*tcl-ex-commands*
+tcl-examples	if_tcl.txt	/*tcl-examples*
+tcl-expr	if_tcl.txt	/*tcl-expr*
+tcl-linenumbers	if_tcl.txt	/*tcl-linenumbers*
+tcl-misc	if_tcl.txt	/*tcl-misc*
+tcl-option	if_tcl.txt	/*tcl-option*
+tcl-output	if_tcl.txt	/*tcl-output*
+tcl-var-current	if_tcl.txt	/*tcl-var-current*
+tcl-var-lbase	if_tcl.txt	/*tcl-var-lbase*
+tcl-var-line	if_tcl.txt	/*tcl-var-line*
+tcl-var-lnum	if_tcl.txt	/*tcl-var-lnum*
+tcl-var-range	if_tcl.txt	/*tcl-var-range*
+tcl-variables	if_tcl.txt	/*tcl-variables*
+tcl-window	if_tcl.txt	/*tcl-window*
+tcl-window-buffer	if_tcl.txt	/*tcl-window-buffer*
+tcl-window-cmds	if_tcl.txt	/*tcl-window-cmds*
+tcl-window-command	if_tcl.txt	/*tcl-window-command*
+tcl-window-cursor	if_tcl.txt	/*tcl-window-cursor*
+tcl-window-delcmd	if_tcl.txt	/*tcl-window-delcmd*
+tcl-window-expr	if_tcl.txt	/*tcl-window-expr*
+tcl-window-height	if_tcl.txt	/*tcl-window-height*
+tcl-window-option	if_tcl.txt	/*tcl-window-option*
+tcsh-style	cmdline.txt	/*tcsh-style*
+tcsh.vim	syntax.txt	/*tcsh.vim*
+tear-off-menus	gui.txt	/*tear-off-menus*
+telnet-CTRL-]	tagsrch.txt	/*telnet-CTRL-]*
+temp-file-name	eval.txt	/*temp-file-name*
+template	autocmd.txt	/*template*
+tempname()	eval.txt	/*tempname()*
+term-dependent-settings	term.txt	/*term-dependent-settings*
+term-list	syntax.txt	/*term-list*
+term.txt	term.txt	/*term.txt*
+termcap	term.txt	/*termcap*
+termcap-changed	version4.txt	/*termcap-changed*
+termcap-colors	term.txt	/*termcap-colors*
+termcap-cursor-color	term.txt	/*termcap-cursor-color*
+termcap-cursor-shape	term.txt	/*termcap-cursor-shape*
+termcap-options	term.txt	/*termcap-options*
+termcap-title	term.txt	/*termcap-title*
+terminal-colors	os_unix.txt	/*terminal-colors*
+terminal-info	term.txt	/*terminal-info*
+terminal-options	term.txt	/*terminal-options*
+terminfo	term.txt	/*terminfo*
+termresponse-variable	eval.txt	/*termresponse-variable*
+tex-error	syntax.txt	/*tex-error*
+tex-folding	syntax.txt	/*tex-folding*
+tex-math	syntax.txt	/*tex-math*
+tex-morecommands	syntax.txt	/*tex-morecommands*
+tex-package	syntax.txt	/*tex-package*
+tex-runon	syntax.txt	/*tex-runon*
+tex-slow	syntax.txt	/*tex-slow*
+tex-style	syntax.txt	/*tex-style*
+tex.vim	syntax.txt	/*tex.vim*
+text-objects	motion.txt	/*text-objects*
+text-objects-changed	version5.txt	/*text-objects-changed*
+textlock	eval.txt	/*textlock*
+tf.vim	syntax.txt	/*tf.vim*
+this_session-variable	eval.txt	/*this_session-variable*
+throw-catch	eval.txt	/*throw-catch*
+throw-expression	eval.txt	/*throw-expression*
+throw-from-catch	eval.txt	/*throw-from-catch*
+throw-variables	eval.txt	/*throw-variables*
+throwpoint-variable	eval.txt	/*throwpoint-variable*
+timestamp	editing.txt	/*timestamp*
+timestamps	editing.txt	/*timestamps*
+tips	tips.txt	/*tips*
+tips.txt	tips.txt	/*tips.txt*
+todo	todo.txt	/*todo*
+todo.txt	todo.txt	/*todo.txt*
+toggle	options.txt	/*toggle*
+toggle-revins	version4.txt	/*toggle-revins*
+tolower()	eval.txt	/*tolower()*
+toolbar-icon	gui.txt	/*toolbar-icon*
+toupper()	eval.txt	/*toupper()*
+tr()	eval.txt	/*tr()*
+trojan-horse	starting.txt	/*trojan-horse*
+try-conditionals	eval.txt	/*try-conditionals*
+try-echoerr	eval.txt	/*try-echoerr*
+try-finally	eval.txt	/*try-finally*
+try-nested	eval.txt	/*try-nested*
+try-nesting	eval.txt	/*try-nesting*
+tutor	usr_01.txt	/*tutor*
+twice	if_cscop.txt	/*twice*
+type()	eval.txt	/*type()*
+type-mistakes	tips.txt	/*type-mistakes*
+typecorr-settings	usr_41.txt	/*typecorr-settings*
+typecorr.txt	usr_41.txt	/*typecorr.txt*
+u	undo.txt	/*u*
+uganda	uganda.txt	/*uganda*
+uganda.txt	uganda.txt	/*uganda.txt*
+undercurl	syntax.txt	/*undercurl*
+underline	syntax.txt	/*underline*
+undo	undo.txt	/*undo*
+undo-blocks	undo.txt	/*undo-blocks*
+undo-branches	undo.txt	/*undo-branches*
+undo-commands	undo.txt	/*undo-commands*
+undo-redo	undo.txt	/*undo-redo*
+undo-remarks	undo.txt	/*undo-remarks*
+undo-tree	undo.txt	/*undo-tree*
+undo-two-ways	undo.txt	/*undo-two-ways*
+undo.txt	undo.txt	/*undo.txt*
+undo_ftplugin	usr_41.txt	/*undo_ftplugin*
+unicode	mbyte.txt	/*unicode*
+unix	os_unix.txt	/*unix*
+unlisted-buffer	windows.txt	/*unlisted-buffer*
+up-down-motions	motion.txt	/*up-down-motions*
+uppercase	change.txt	/*uppercase*
+use-cpo-save	usr_41.txt	/*use-cpo-save*
+use-visual-cmds	version4.txt	/*use-visual-cmds*
+useful-mappings	tips.txt	/*useful-mappings*
+usenet	intro.txt	/*usenet*
+user-cmd-ambiguous	map.txt	/*user-cmd-ambiguous*
+user-commands	map.txt	/*user-commands*
+user-functions	eval.txt	/*user-functions*
+user-manual	usr_toc.txt	/*user-manual*
+using-<Plug>	usr_41.txt	/*using-<Plug>*
+using-menus	gui.txt	/*using-menus*
+using-scripts	repeat.txt	/*using-scripts*
+using-xxd	tips.txt	/*using-xxd*
+using_CTRL-V	map.txt	/*using_CTRL-V*
+usr_01.txt	usr_01.txt	/*usr_01.txt*
+usr_02.txt	usr_02.txt	/*usr_02.txt*
+usr_03.txt	usr_03.txt	/*usr_03.txt*
+usr_04.txt	usr_04.txt	/*usr_04.txt*
+usr_05.txt	usr_05.txt	/*usr_05.txt*
+usr_06.txt	usr_06.txt	/*usr_06.txt*
+usr_07.txt	usr_07.txt	/*usr_07.txt*
+usr_08.txt	usr_08.txt	/*usr_08.txt*
+usr_09.txt	usr_09.txt	/*usr_09.txt*
+usr_10.txt	usr_10.txt	/*usr_10.txt*
+usr_11.txt	usr_11.txt	/*usr_11.txt*
+usr_12.txt	usr_12.txt	/*usr_12.txt*
+usr_20.txt	usr_20.txt	/*usr_20.txt*
+usr_21.txt	usr_21.txt	/*usr_21.txt*
+usr_22.txt	usr_22.txt	/*usr_22.txt*
+usr_23.txt	usr_23.txt	/*usr_23.txt*
+usr_24.txt	usr_24.txt	/*usr_24.txt*
+usr_25.txt	usr_25.txt	/*usr_25.txt*
+usr_26.txt	usr_26.txt	/*usr_26.txt*
+usr_27.txt	usr_27.txt	/*usr_27.txt*
+usr_28.txt	usr_28.txt	/*usr_28.txt*
+usr_29.txt	usr_29.txt	/*usr_29.txt*
+usr_30.txt	usr_30.txt	/*usr_30.txt*
+usr_31.txt	usr_31.txt	/*usr_31.txt*
+usr_32.txt	usr_32.txt	/*usr_32.txt*
+usr_40.txt	usr_40.txt	/*usr_40.txt*
+usr_41.txt	usr_41.txt	/*usr_41.txt*
+usr_42.txt	usr_42.txt	/*usr_42.txt*
+usr_43.txt	usr_43.txt	/*usr_43.txt*
+usr_44.txt	usr_44.txt	/*usr_44.txt*
+usr_45.txt	usr_45.txt	/*usr_45.txt*
+usr_90.txt	usr_90.txt	/*usr_90.txt*
+usr_toc.txt	usr_toc.txt	/*usr_toc.txt*
+utf-8	mbyte.txt	/*utf-8*
+utf-8-char-arg	mbyte.txt	/*utf-8-char-arg*
+utf-8-in-xwindows	mbyte.txt	/*utf-8-in-xwindows*
+utf-8-typing	mbyte.txt	/*utf-8-typing*
+utf8	mbyte.txt	/*utf8*
+v	visual.txt	/*v*
+v:beval_bufnr	eval.txt	/*v:beval_bufnr*
+v:beval_col	eval.txt	/*v:beval_col*
+v:beval_lnum	eval.txt	/*v:beval_lnum*
+v:beval_text	eval.txt	/*v:beval_text*
+v:beval_winnr	eval.txt	/*v:beval_winnr*
+v:char	eval.txt	/*v:char*
+v:charconvert_from	eval.txt	/*v:charconvert_from*
+v:charconvert_to	eval.txt	/*v:charconvert_to*
+v:cmdarg	eval.txt	/*v:cmdarg*
+v:cmdbang	eval.txt	/*v:cmdbang*
+v:count	eval.txt	/*v:count*
+v:count1	eval.txt	/*v:count1*
+v:ctype	eval.txt	/*v:ctype*
+v:dying	eval.txt	/*v:dying*
+v:errmsg	eval.txt	/*v:errmsg*
+v:exception	eval.txt	/*v:exception*
+v:fcs_choice	eval.txt	/*v:fcs_choice*
+v:fcs_reason	eval.txt	/*v:fcs_reason*
+v:fname_diff	eval.txt	/*v:fname_diff*
+v:fname_in	eval.txt	/*v:fname_in*
+v:fname_new	eval.txt	/*v:fname_new*
+v:fname_out	eval.txt	/*v:fname_out*
+v:folddashes	eval.txt	/*v:folddashes*
+v:foldend	eval.txt	/*v:foldend*
+v:foldlevel	eval.txt	/*v:foldlevel*
+v:foldstart	eval.txt	/*v:foldstart*
+v:insertmode	eval.txt	/*v:insertmode*
+v:key	eval.txt	/*v:key*
+v:lang	eval.txt	/*v:lang*
+v:lc_time	eval.txt	/*v:lc_time*
+v:lnum	eval.txt	/*v:lnum*
+v:mouse_col	eval.txt	/*v:mouse_col*
+v:mouse_lnum	eval.txt	/*v:mouse_lnum*
+v:mouse_win	eval.txt	/*v:mouse_win*
+v:prevcount	eval.txt	/*v:prevcount*
+v:profiling	eval.txt	/*v:profiling*
+v:progname	eval.txt	/*v:progname*
+v:register	eval.txt	/*v:register*
+v:scrollstart	eval.txt	/*v:scrollstart*
+v:servername	eval.txt	/*v:servername*
+v:shell_error	eval.txt	/*v:shell_error*
+v:statusmsg	eval.txt	/*v:statusmsg*
+v:swapchoice	eval.txt	/*v:swapchoice*
+v:swapcommand	eval.txt	/*v:swapcommand*
+v:swapname	eval.txt	/*v:swapname*
+v:termresponse	eval.txt	/*v:termresponse*
+v:this_session	eval.txt	/*v:this_session*
+v:throwpoint	eval.txt	/*v:throwpoint*
+v:val	eval.txt	/*v:val*
+v:var	eval.txt	/*v:var*
+v:version	eval.txt	/*v:version*
+v:warningmsg	eval.txt	/*v:warningmsg*
+v_!	change.txt	/*v_!*
+v_$	visual.txt	/*v_$*
+v_:	cmdline.txt	/*v_:*
+v_<	change.txt	/*v_<*
+v_<BS>	change.txt	/*v_<BS>*
+v_<Del>	change.txt	/*v_<Del>*
+v_<Esc>	visual.txt	/*v_<Esc>*
+v_=	change.txt	/*v_=*
+v_>	change.txt	/*v_>*
+v_C	change.txt	/*v_C*
+v_CTRL-C	visual.txt	/*v_CTRL-C*
+v_CTRL-G	visual.txt	/*v_CTRL-G*
+v_CTRL-H	change.txt	/*v_CTRL-H*
+v_CTRL-O	visual.txt	/*v_CTRL-O*
+v_CTRL-V	visual.txt	/*v_CTRL-V*
+v_CTRL-Z	starting.txt	/*v_CTRL-Z*
+v_CTRL-\_CTRL-G	intro.txt	/*v_CTRL-\\_CTRL-G*
+v_CTRL-\_CTRL-N	intro.txt	/*v_CTRL-\\_CTRL-N*
+v_CTRL-]	tagsrch.txt	/*v_CTRL-]*
+v_D	change.txt	/*v_D*
+v_J	change.txt	/*v_J*
+v_K	various.txt	/*v_K*
+v_O	visual.txt	/*v_O*
+v_P	change.txt	/*v_P*
+v_R	change.txt	/*v_R*
+v_S	change.txt	/*v_S*
+v_U	change.txt	/*v_U*
+v_V	visual.txt	/*v_V*
+v_X	change.txt	/*v_X*
+v_Y	change.txt	/*v_Y*
+v_a	motion.txt	/*v_a*
+v_a'	motion.txt	/*v_a'*
+v_a(	motion.txt	/*v_a(*
+v_a)	motion.txt	/*v_a)*
+v_a<	motion.txt	/*v_a<*
+v_a>	motion.txt	/*v_a>*
+v_aB	motion.txt	/*v_aB*
+v_aW	motion.txt	/*v_aW*
+v_a[	motion.txt	/*v_a[*
+v_a]	motion.txt	/*v_a]*
+v_a`	motion.txt	/*v_a`*
+v_ab	motion.txt	/*v_ab*
+v_ap	motion.txt	/*v_ap*
+v_aquote	motion.txt	/*v_aquote*
+v_as	motion.txt	/*v_as*
+v_at	motion.txt	/*v_at*
+v_aw	motion.txt	/*v_aw*
+v_a{	motion.txt	/*v_a{*
+v_a}	motion.txt	/*v_a}*
+v_b_<	visual.txt	/*v_b_<*
+v_b_<_example	visual.txt	/*v_b_<_example*
+v_b_>	visual.txt	/*v_b_>*
+v_b_>_example	visual.txt	/*v_b_>_example*
+v_b_A	visual.txt	/*v_b_A*
+v_b_A_example	visual.txt	/*v_b_A_example*
+v_b_C	visual.txt	/*v_b_C*
+v_b_D	change.txt	/*v_b_D*
+v_b_I	visual.txt	/*v_b_I*
+v_b_I_example	visual.txt	/*v_b_I_example*
+v_b_c	visual.txt	/*v_b_c*
+v_b_r	visual.txt	/*v_b_r*
+v_b_r_example	visual.txt	/*v_b_r_example*
+v_c	change.txt	/*v_c*
+v_d	change.txt	/*v_d*
+v_g?	change.txt	/*v_g?*
+v_gF	editing.txt	/*v_gF*
+v_gJ	change.txt	/*v_gJ*
+v_gV	visual.txt	/*v_gV*
+v_g]	tagsrch.txt	/*v_g]*
+v_g_CTRL-G	editing.txt	/*v_g_CTRL-G*
+v_g_CTRL-]	tagsrch.txt	/*v_g_CTRL-]*
+v_gf	editing.txt	/*v_gf*
+v_gq	change.txt	/*v_gq*
+v_gv	visual.txt	/*v_gv*
+v_gw	change.txt	/*v_gw*
+v_i	motion.txt	/*v_i*
+v_i'	motion.txt	/*v_i'*
+v_i(	motion.txt	/*v_i(*
+v_i)	motion.txt	/*v_i)*
+v_i<	motion.txt	/*v_i<*
+v_i>	motion.txt	/*v_i>*
+v_iB	motion.txt	/*v_iB*
+v_iW	motion.txt	/*v_iW*
+v_i[	motion.txt	/*v_i[*
+v_i]	motion.txt	/*v_i]*
+v_i`	motion.txt	/*v_i`*
+v_ib	motion.txt	/*v_ib*
+v_ip	motion.txt	/*v_ip*
+v_iquote	motion.txt	/*v_iquote*
+v_is	motion.txt	/*v_is*
+v_it	motion.txt	/*v_it*
+v_iw	motion.txt	/*v_iw*
+v_i{	motion.txt	/*v_i{*
+v_i}	motion.txt	/*v_i}*
+v_o	visual.txt	/*v_o*
+v_p	change.txt	/*v_p*
+v_r	change.txt	/*v_r*
+v_s	change.txt	/*v_s*
+v_u	change.txt	/*v_u*
+v_v	visual.txt	/*v_v*
+v_x	change.txt	/*v_x*
+v_y	change.txt	/*v_y*
+v_~	change.txt	/*v_~*
+val-variable	eval.txt	/*val-variable*
+values()	eval.txt	/*values()*
+variables	eval.txt	/*variables*
+various	various.txt	/*various*
+various-cmds	various.txt	/*various-cmds*
+various-motions	motion.txt	/*various-motions*
+various.txt	various.txt	/*various.txt*
+vb.vim	syntax.txt	/*vb.vim*
+vba	pi_vimball.txt	/*vba*
+verbose	starting.txt	/*verbose*
+version-5.1	version5.txt	/*version-5.1*
+version-5.2	version5.txt	/*version-5.2*
+version-5.3	version5.txt	/*version-5.3*
+version-5.4	version5.txt	/*version-5.4*
+version-5.5	version5.txt	/*version-5.5*
+version-5.6	version5.txt	/*version-5.6*
+version-5.7	version5.txt	/*version-5.7*
+version-5.8	version5.txt	/*version-5.8*
+version-6.1	version6.txt	/*version-6.1*
+version-6.2	version6.txt	/*version-6.2*
+version-6.3	version6.txt	/*version-6.3*
+version-6.4	version6.txt	/*version-6.4*
+version-7.1	version7.txt	/*version-7.1*
+version-variable	eval.txt	/*version-variable*
+version4.txt	version4.txt	/*version4.txt*
+version5.txt	version5.txt	/*version5.txt*
+version6.txt	version6.txt	/*version6.txt*
+version7.txt	version7.txt	/*version7.txt*
+vi	intro.txt	/*vi*
+vi-differences	vi_diff.txt	/*vi-differences*
+vi:	options.txt	/*vi:*
+vi_diff.txt	vi_diff.txt	/*vi_diff.txt*
+view	starting.txt	/*view*
+view-diffs	diff.txt	/*view-diffs*
+view-file	starting.txt	/*view-file*
+views-sessions	starting.txt	/*views-sessions*
+vim-additions	vi_diff.txt	/*vim-additions*
+vim-announce	intro.txt	/*vim-announce*
+vim-arguments	starting.txt	/*vim-arguments*
+vim-default-editor	gui_w32.txt	/*vim-default-editor*
+vim-dev	intro.txt	/*vim-dev*
+vim-mac	intro.txt	/*vim-mac*
+vim-modes	intro.txt	/*vim-modes*
+vim-modes-intro	intro.txt	/*vim-modes-intro*
+vim-multibyte	intro.txt	/*vim-multibyte*
+vim-script-intro	usr_41.txt	/*vim-script-intro*
+vim-variable	eval.txt	/*vim-variable*
+vim.vim	syntax.txt	/*vim.vim*
+vim7	version7.txt	/*vim7*
+vim:	options.txt	/*vim:*
+vimball	pi_vimball.txt	/*vimball*
+vimball-contents	pi_vimball.txt	/*vimball-contents*
+vimball-extract	pi_vimball.txt	/*vimball-extract*
+vimball-history	pi_vimball.txt	/*vimball-history*
+vimball-manual	pi_vimball.txt	/*vimball-manual*
+vimdev	intro.txt	/*vimdev*
+vimdiff	diff.txt	/*vimdiff*
+vimfiles	options.txt	/*vimfiles*
+viminfo	starting.txt	/*viminfo*
+viminfo-encoding	starting.txt	/*viminfo-encoding*
+viminfo-errors	starting.txt	/*viminfo-errors*
+viminfo-file	starting.txt	/*viminfo-file*
+viminfo-file-marks	starting.txt	/*viminfo-file-marks*
+viminfo-file-name	starting.txt	/*viminfo-file-name*
+viminfo-read	starting.txt	/*viminfo-read*
+viminfo-write	starting.txt	/*viminfo-write*
+vimrc	starting.txt	/*vimrc*
+vimrc-filetype	usr_05.txt	/*vimrc-filetype*
+vimrc-intro	usr_05.txt	/*vimrc-intro*
+vimrc-option-example	starting.txt	/*vimrc-option-example*
+vimrc_example.vim	usr_05.txt	/*vimrc_example.vim*
+vimtutor	usr_01.txt	/*vimtutor*
+virtcol()	eval.txt	/*virtcol()*
+visual-block	visual.txt	/*visual-block*
+visual-change	visual.txt	/*visual-change*
+visual-examples	visual.txt	/*visual-examples*
+visual-index	index.txt	/*visual-index*
+visual-mode	visual.txt	/*visual-mode*
+visual-operators	visual.txt	/*visual-operators*
+visual-repeat	visual.txt	/*visual-repeat*
+visual-search	visual.txt	/*visual-search*
+visual-start	visual.txt	/*visual-start*
+visual-use	visual.txt	/*visual-use*
+visual.txt	visual.txt	/*visual.txt*
+visualmode()	eval.txt	/*visualmode()*
+vms	os_vms.txt	/*vms*
+vms-authors	os_vms.txt	/*vms-authors*
+vms-changes	os_vms.txt	/*vms-changes*
+vms-compiling	os_vms.txt	/*vms-compiling*
+vms-deploy	os_vms.txt	/*vms-deploy*
+vms-download	os_vms.txt	/*vms-download*
+vms-gui	os_vms.txt	/*vms-gui*
+vms-notes	os_vms.txt	/*vms-notes*
+vms-problems	os_vms.txt	/*vms-problems*
+vms-started	os_vms.txt	/*vms-started*
+vms-usage	os_vms.txt	/*vms-usage*
+vote-for-features	sponsor.txt	/*vote-for-features*
+votes-counted	sponsor.txt	/*votes-counted*
+votes-for-changes	todo.txt	/*votes-for-changes*
+vreplace-mode	insert.txt	/*vreplace-mode*
+vt100-cursor-keys	term.txt	/*vt100-cursor-keys*
+vt100-function-keys	term.txt	/*vt100-function-keys*
+w	motion.txt	/*w*
+w32-clientserver	remote.txt	/*w32-clientserver*
+w:var	eval.txt	/*w:var*
+warningmsg-variable	eval.txt	/*warningmsg-variable*
+white-space	pattern.txt	/*white-space*
+whitespace	pattern.txt	/*whitespace*
+wildcard	editing.txt	/*wildcard*
+wildcards	editing.txt	/*wildcards*
+win16-!start	gui_w16.txt	/*win16-!start*
+win16-clipboard	gui_w16.txt	/*win16-clipboard*
+win16-colors	gui_w16.txt	/*win16-colors*
+win16-default-editor	gui_w16.txt	/*win16-default-editor*
+win16-dialogs	gui_w16.txt	/*win16-dialogs*
+win16-drag-n-drop	gui_w16.txt	/*win16-drag-n-drop*
+win16-gui	gui_w16.txt	/*win16-gui*
+win16-maximized	gui_w16.txt	/*win16-maximized*
+win16-printing	gui_w16.txt	/*win16-printing*
+win16-shell	gui_w16.txt	/*win16-shell*
+win16-start	gui_w16.txt	/*win16-start*
+win16-truetype	gui_w16.txt	/*win16-truetype*
+win16-various	gui_w16.txt	/*win16-various*
+win32	os_win32.txt	/*win32*
+win32-!start	gui_w32.txt	/*win32-!start*
+win32-PATH	os_win32.txt	/*win32-PATH*
+win32-colors	gui_w32.txt	/*win32-colors*
+win32-compiling	os_win32.txt	/*win32-compiling*
+win32-curdir	os_win32.txt	/*win32-curdir*
+win32-faq	os_win32.txt	/*win32-faq*
+win32-gettext	mlang.txt	/*win32-gettext*
+win32-gui	gui_w32.txt	/*win32-gui*
+win32-hidden-menus	gui.txt	/*win32-hidden-menus*
+win32-mouse	os_win32.txt	/*win32-mouse*
+win32-open-with-menu	gui_w32.txt	/*win32-open-with-menu*
+win32-popup-menu	gui_w32.txt	/*win32-popup-menu*
+win32-problems	os_win32.txt	/*win32-problems*
+win32-restore	os_win32.txt	/*win32-restore*
+win32-startup	os_win32.txt	/*win32-startup*
+win32-term	os_win32.txt	/*win32-term*
+win32-vimrun	gui_w32.txt	/*win32-vimrun*
+win32-win3.1	os_win32.txt	/*win32-win3.1*
+win32s	os_win32.txt	/*win32s*
+winbufnr()	eval.txt	/*winbufnr()*
+wincol()	eval.txt	/*wincol()*
+window	windows.txt	/*window*
+window-contents	intro.txt	/*window-contents*
+window-exit	editing.txt	/*window-exit*
+window-move-cursor	windows.txt	/*window-move-cursor*
+window-moving	windows.txt	/*window-moving*
+window-resize	windows.txt	/*window-resize*
+window-size	term.txt	/*window-size*
+window-tag	windows.txt	/*window-tag*
+window-variable	eval.txt	/*window-variable*
+windows	windows.txt	/*windows*
+windows-3.1	os_win32.txt	/*windows-3.1*
+windows-intro	windows.txt	/*windows-intro*
+windows-starting	windows.txt	/*windows-starting*
+windows.txt	windows.txt	/*windows.txt*
+windows95	os_win32.txt	/*windows95*
+winheight()	eval.txt	/*winheight()*
+winline()	eval.txt	/*winline()*
+winnr()	eval.txt	/*winnr()*
+winrestcmd()	eval.txt	/*winrestcmd()*
+winrestview()	eval.txt	/*winrestview()*
+winsaveview()	eval.txt	/*winsaveview()*
+winwidth()	eval.txt	/*winwidth()*
+word	motion.txt	/*word*
+word-count	editing.txt	/*word-count*
+word-motions	motion.txt	/*word-motions*
+workbench	starting.txt	/*workbench*
+workshop	workshop.txt	/*workshop*
+workshop-commands	workshop.txt	/*workshop-commands*
+workshop-compiling	workshop.txt	/*workshop-compiling*
+workshop-configure	workshop.txt	/*workshop-configure*
+workshop-intro	workshop.txt	/*workshop-intro*
+workshop-support	workshop.txt	/*workshop-support*
+workshop-xpm	workshop.txt	/*workshop-xpm*
+workshop.txt	workshop.txt	/*workshop.txt*
+wrap-off	intro.txt	/*wrap-off*
+write-compiler-plugin	usr_41.txt	/*write-compiler-plugin*
+write-device	editing.txt	/*write-device*
+write-fail	editing.txt	/*write-fail*
+write-filetype-plugin	usr_41.txt	/*write-filetype-plugin*
+write-library-script	usr_41.txt	/*write-library-script*
+write-local-help	usr_41.txt	/*write-local-help*
+write-plugin	usr_41.txt	/*write-plugin*
+write-plugin-quickload	usr_41.txt	/*write-plugin-quickload*
+write-quit	editing.txt	/*write-quit*
+write-readonly	editing.txt	/*write-readonly*
+writefile()	eval.txt	/*writefile()*
+writing	editing.txt	/*writing*
+www	intro.txt	/*www*
+x	change.txt	/*x*
+x-input-method	mbyte.txt	/*x-input-method*
+x-resources	version5.txt	/*x-resources*
+x11-clientserver	remote.txt	/*x11-clientserver*
+x11-cut-buffer	gui_x11.txt	/*x11-cut-buffer*
+x11-selection	gui_x11.txt	/*x11-selection*
+xf86conf.vim	syntax.txt	/*xf86conf.vim*
+xfontset	mbyte.txt	/*xfontset*
+xfree-xterm	syntax.txt	/*xfree-xterm*
+xim	mbyte.txt	/*xim*
+xim-input-style	mbyte.txt	/*xim-input-style*
+xiterm	syntax.txt	/*xiterm*
+xml-folding	syntax.txt	/*xml-folding*
+xml-omni-datafile	insert.txt	/*xml-omni-datafile*
+xml.vim	syntax.txt	/*xml.vim*
+xpm.vim	syntax.txt	/*xpm.vim*
+xterm-8-bit	term.txt	/*xterm-8-bit*
+xterm-8bit	term.txt	/*xterm-8bit*
+xterm-blink	syntax.txt	/*xterm-blink*
+xterm-blinking-cursor	syntax.txt	/*xterm-blinking-cursor*
+xterm-clipboard	term.txt	/*xterm-clipboard*
+xterm-codes	term.txt	/*xterm-codes*
+xterm-color	syntax.txt	/*xterm-color*
+xterm-command-server	term.txt	/*xterm-command-server*
+xterm-copy-paste	term.txt	/*xterm-copy-paste*
+xterm-cursor-keys	term.txt	/*xterm-cursor-keys*
+xterm-end-home-keys	term.txt	/*xterm-end-home-keys*
+xterm-function-keys	term.txt	/*xterm-function-keys*
+xterm-modifier-keys	term.txt	/*xterm-modifier-keys*
+xterm-mouse	options.txt	/*xterm-mouse*
+xterm-mouse-wheel	scroll.txt	/*xterm-mouse-wheel*
+xterm-save-screen	tips.txt	/*xterm-save-screen*
+xterm-screens	tips.txt	/*xterm-screens*
+xterm-scroll-region	term.txt	/*xterm-scroll-region*
+xterm-shifted-keys	term.txt	/*xterm-shifted-keys*
+y	change.txt	/*y*
+yank	change.txt	/*yank*
+ye-option-gone	version4.txt	/*ye-option-gone*
+year-2000	intro.txt	/*year-2000*
+your-runtime-dir	usr_43.txt	/*your-runtime-dir*
+yy	change.txt	/*yy*
+z	index.txt	/*z*
+z+	scroll.txt	/*z+*
+z-	scroll.txt	/*z-*
+z.	scroll.txt	/*z.*
+z/OS	os_390.txt	/*z\/OS*
+z<CR>	scroll.txt	/*z<CR>*
+z<Left>	scroll.txt	/*z<Left>*
+z<Right>	scroll.txt	/*z<Right>*
+z=	spell.txt	/*z=*
+zA	fold.txt	/*zA*
+zC	fold.txt	/*zC*
+zD	fold.txt	/*zD*
+zE	fold.txt	/*zE*
+zF	fold.txt	/*zF*
+zG	spell.txt	/*zG*
+zH	scroll.txt	/*zH*
+zL	scroll.txt	/*zL*
+zM	fold.txt	/*zM*
+zN	fold.txt	/*zN*
+zN<CR>	scroll.txt	/*zN<CR>*
+zO	fold.txt	/*zO*
+zOS	os_390.txt	/*zOS*
+zOS-Bugs	os_390.txt	/*zOS-Bugs*
+zOS-Motif	os_390.txt	/*zOS-Motif*
+zOS-building	os_390.txt	/*zOS-building*
+zOS-changes	os_390.txt	/*zOS-changes*
+zOS-feedback	os_390.txt	/*zOS-feedback*
+zOS-has-ebcdic	os_390.txt	/*zOS-has-ebcdic*
+zOS-open-source	os_390.txt	/*zOS-open-source*
+zOS-weaknesses	os_390.txt	/*zOS-weaknesses*
+zOS-xterm	os_390.txt	/*zOS-xterm*
+zR	fold.txt	/*zR*
+zW	spell.txt	/*zW*
+zX	fold.txt	/*zX*
+z^	scroll.txt	/*z^*
+za	fold.txt	/*za*
+zb	scroll.txt	/*zb*
+zc	fold.txt	/*zc*
+zd	fold.txt	/*zd*
+ze	scroll.txt	/*ze*
+zf	fold.txt	/*zf*
+zg	spell.txt	/*zg*
+zh	scroll.txt	/*zh*
+zi	fold.txt	/*zi*
+zip	pi_zip.txt	/*zip*
+zip-contents	pi_zip.txt	/*zip-contents*
+zip-copyright	pi_zip.txt	/*zip-copyright*
+zip-extension	pi_zip.txt	/*zip-extension*
+zip-history	pi_zip.txt	/*zip-history*
+zip-manual	pi_zip.txt	/*zip-manual*
+zip-usage	pi_zip.txt	/*zip-usage*
+zip_shq	pi_zip.txt	/*zip_shq*
+zj	fold.txt	/*zj*
+zk	fold.txt	/*zk*
+zl	scroll.txt	/*zl*
+zm	fold.txt	/*zm*
+zn	fold.txt	/*zn*
+zo	fold.txt	/*zo*
+zr	fold.txt	/*zr*
+zs	scroll.txt	/*zs*
+zt	scroll.txt	/*zt*
+zuG	spell.txt	/*zuG*
+zuW	spell.txt	/*zuW*
+zug	spell.txt	/*zug*
+zuw	spell.txt	/*zuw*
+zv	fold.txt	/*zv*
+zw	spell.txt	/*zw*
+zx	fold.txt	/*zx*
+zz	scroll.txt	/*zz*
+{	motion.txt	/*{*
+{Visual}	intro.txt	/*{Visual}*
+{address}	cmdline.txt	/*{address}*
+{arglist}	editing.txt	/*{arglist}*
+{char1-char2}	intro.txt	/*{char1-char2}*
+{event}	autocmd.txt	/*{event}*
+{file}	editing.txt	/*{file}*
+{group-name}	syntax.txt	/*{group-name}*
+{lhs}	map.txt	/*{lhs}*
+{motion}	intro.txt	/*{motion}*
+{move-around}	visual.txt	/*{move-around}*
+{offset}	pattern.txt	/*{offset}*
+{pat}	autocmd.txt	/*{pat}*
+{rhs}	map.txt	/*{rhs}*
+{subject}	various.txt	/*{subject}*
+{}	intro.txt	/*{}*
+}	motion.txt	/*}*
+~	change.txt	/*~*
--- /dev/null
+++ b/lib/vimfiles/doc/tagsrch.txt
@@ -1,0 +1,833 @@
+*tagsrch.txt*   For Vim version 7.1.  Last change: 2006 Apr 24
+
+
+		  VIM REFERENCE MANUAL    by Bram Moolenaar
+
+
+Tags and special searches				*tags-and-searches*
+
+See section |29.1| of the user manual for an introduction.
+
+1. Jump to a tag		|tag-commands|
+2. Tag stack			|tag-stack|
+3. Tag match list		|tag-matchlist|
+4. Tags details			|tag-details|
+5. Tags file format		|tags-file-format|
+6. Include file searches	|include-search|
+
+==============================================================================
+1. Jump to a tag					*tag-commands*
+
+							*tag* *tags*
+A tag is an identifier that appears in a "tags" file.  It is a sort of label
+that can be jumped to.  For example: In C programs each function name can be
+used as a tag.  The "tags" file has to be generated by a program like ctags,
+before the tag commands can be used.
+
+With the ":tag" command the cursor will be positioned on the tag.  With the
+CTRL-] command, the keyword on which the cursor is standing is used as the
+tag.  If the cursor is not on a keyword, the first keyword to the right of the
+cursor is used.
+
+The ":tag" command works very well for C programs.  If you see a call to a
+function and wonder what that function does, position the cursor inside of the
+function name and hit CTRL-].  This will bring you to the function definition.
+An easy way back is with the CTRL-T command.  Also read about the tag stack
+below.
+
+						*:ta* *:tag* *E426* *E429*
+:[count]ta[g][!] {ident}
+			Jump to the definition of {ident}, using the
+			information in the tags file(s).  Put {ident} in the
+			tag stack.  See |tag-!| for [!].
+			{ident} can be a regexp pattern, see |tag-regexp|.
+			When there are several matching tags for {ident}, jump
+			to the [count] one.  When [count] is omitted the
+			first one is jumped to. See |tag-matchlist| for
+			jumping to other matching tags.
+
+g<LeftMouse>						*g<LeftMouse>*
+<C-LeftMouse>					*<C-LeftMouse>* *CTRL-]*
+CTRL-]			Jump to the definition of the keyword under the
+			cursor.  Same as ":tag {ident}", where {ident} is the
+			keyword under or after cursor.
+			When there are several matching tags for {ident}, jump
+			to the [count] one.  When no [count] is given the
+			first one is jumped to. See |tag-matchlist| for
+			jumping to other matching tags.
+			{Vi: identifier after the cursor}
+
+							*v_CTRL-]*
+{Visual}CTRL-]		Same as ":tag {ident}", where {ident} is the text that
+			is highlighted.  {not in Vi}
+
+							*telnet-CTRL-]*
+CTRL-] is the default telnet escape key.  When you type CTRL-] to jump to a
+tag, you will get the telnet prompt instead.  Most versions of telnet allow
+changing or disabling the default escape key.  See the telnet man page.  You
+can 'telnet -E {Hostname}' to disable the escape character, or 'telnet -e
+{EscapeCharacter} {Hostname}' to specify another escape character.  If
+possible, try to use "ssh" instead of "telnet" to avoid this problem.
+
+							*tag-priority*
+When there are multiple matches for a tag, this priority is used:
+1. "FSC"  A full matching static tag for the current file.
+2. "F C"  A full matching global tag for the current file.
+3. "F  "  A full matching global tag for another file.
+4. "FS "  A full matching static tag for another file.
+5. " SC"  An ignore-case matching static tag for the current file.
+6. "  C"  An ignore-case matching global tag for the current file.
+7. "   "  An ignore-case matching global tag for another file.
+8. " S "  An ignore-case matching static tag for another file.
+
+Note that when the current file changes, the priority list is mostly not
+changed, to avoid confusion when using ":tnext".  It is changed when using
+":tag {ident}".
+
+The ignore-case matches are not found for a ":tag" command when the
+'ignorecase' option is off.  They are found when a pattern is used (starting
+with a "/") and for ":tselect", also when 'ignorecase' is off.  Note that
+using ignore-case tag searching disables binary searching in the tags file,
+which causes a slowdown.  This can be avoided by fold-case sorting the tag
+file.  See the 'tagbsearch' option for an explanation.
+
+==============================================================================
+2. Tag stack				*tag-stack* *tagstack* *E425*
+
+On the tag stack is remembered which tags you jumped to, and from where.
+Tags are only pushed onto the stack when the 'tagstack' option is set.
+
+g<RightMouse>						*g<RightMouse>*
+<C-RightMouse>					*<C-RightMouse>* *CTRL-T*
+CTRL-T			Jump to [count] older entry in the tag stack
+			(default 1).  {not in Vi}
+
+						*:po* *:pop* *E555* *E556*
+:[count]po[p][!]	Jump to [count] older entry in tag stack (default 1).
+			See |tag-!| for [!].  {not in Vi}
+
+:[count]ta[g][!]	Jump to [count] newer entry in tag stack (default 1).
+			See |tag-!| for [!].  {not in Vi}
+
+							*:tags*
+:tags			Show the contents of the tag stack.  The active
+			entry is marked with a '>'.  {not in Vi}
+
+The output of ":tags" looks like this:
+
+   # TO tag      FROM line in file/line
+   1  1 main		 1  harddisk2:text/vim/test
+ > 2  2 FuncA		58  i = FuncA(10);
+   3  1 FuncC	       357  harddisk2:text/vim/src/amiga.c
+
+This list shows the tags that you jumped to and the cursor position before
+that jump.  The older tags are at the top, the newer at the bottom.
+
+The '>' points to the active entry.  This is the tag that will be used by the
+next ":tag" command.  The CTRL-T and ":pop" command will use the position
+above the active entry.
+
+Below the "TO" is the number of the current match in the match list.  Note
+that this doesn't change when using ":pop" or ":tag".
+
+The line number and file name are remembered to be able to get back to where
+you were before the tag command.  The line number will be correct, also when
+deleting/inserting lines, unless this was done by another program (e.g.
+another instance of Vim).
+
+For the current file, the "file/line" column shows the text at the position.
+An indent is removed and a long line is truncated to fit in the window.
+
+You can jump to previously used tags with several commands.  Some examples:
+
+	":pop" or CTRL-T	to position before previous tag
+	{count}CTRL-T		to position before {count} older tag
+	":tag"			to newer tag
+	":0tag"			to last used tag
+
+The most obvious way to use this is while browsing through the call graph of
+a program.  Consider the following call graph:
+
+	main  --->  FuncA  --->  FuncC
+	      --->  FuncB
+
+(Explanation: main calls FuncA and FuncB; FuncA calls FuncC).
+You can get from main to FuncA by using CTRL-] on the call to FuncA.  Then
+you can CTRL-] to get to FuncC.  If you now want to go back to main you can
+use CTRL-T twice.  Then you can CTRL-] to FuncB.
+
+If you issue a ":ta {ident}" or CTRL-] command, this tag is inserted at the
+current position in the stack.  If the stack was full (it can hold up to 20
+entries), the oldest entry is deleted and the older entries shift one
+position up (their index number is decremented by one).  If the last used
+entry was not at the bottom, the entries below the last used one are
+deleted.  This means that an old branch in the call graph is lost.  After the
+commands explained above the tag stack will look like this:
+
+   # TO tag	FROM line in file
+   1 main	       1  harddisk2:text/vim/test
+   2 FuncB	      59  harddisk2:text/vim/src/main.c
+
+							*E73*
+When you try to use the tag stack while it doesn't contain anything you will
+get an error message.
+
+==============================================================================
+3. Tag match list				*tag-matchlist* *E427* *E428*
+
+When there are several matching tags, these commands can be used to jump
+between them.  Note that these command don't change the tag stack, they keep
+the same entry.
+
+							*:ts* *:tselect*
+:ts[elect][!] [ident]	List the tags that match [ident], using the
+			information in the tags file(s).
+			When [ident] is not given, the last tag name from the
+			tag stack is used.
+			With a '>' in the first column is indicated which is
+			the current position in the list (if there is one).
+			[ident] can be a regexp pattern, see |tag-regexp|.
+			See |tag-priority| for the priorities used in the
+			listing.  {not in Vi}
+			Example output:
+
+>
+	 nr pri kind tag		file
+	  1 F	f    mch_delay		os_amiga.c
+			mch_delay(msec, ignoreinput)
+	> 2 F	f    mch_delay		os_msdos.c
+			mch_delay(msec, ignoreinput)
+	  3 F	f    mch_delay		os_unix.c
+			mch_delay(msec, ignoreinput)
+	Enter nr of choice (<CR> to abort):
+<
+			See |tag-priority| for the "pri" column.  Note that
+			this depends on the current file, thus using
+			":tselect xxx" can produce different results.
+			The "kind" column gives the kind of tag, if this was
+			included in the tags file.
+			The "info" column shows information that could be
+			found in the tags file.  It depends on the program
+			that produced the tags file.
+			When the list is long, you may get the |more-prompt|.
+			If you already see the tag you want to use, you can
+			type 'q' and enter the number.
+
+							*:sts* *:stselect*
+:sts[elect][!] [ident]	Does ":tselect[!] [ident]" and splits the window for
+			the selected tag.  {not in Vi}
+
+							*g]*
+g]			Like CTRL-], but use ":tselect" instead of ":tag".
+			{not in Vi}
+
+							*v_g]*
+{Visual}g]		Same as "g]", but use the highlighted text as the
+			identifier.  {not in Vi}
+
+							*:tj* *:tjump*
+:tj[ump][!] [ident]	Like ":tselect", but jump to the tag directly when
+			there is only one match.  {not in Vi}
+
+							*:stj* *:stjump*
+:stj[ump][!] [ident]	Does ":tjump[!] [ident]" and splits the window for the
+			selected tag.  {not in Vi}
+
+							*g_CTRL-]*
+g CTRL-]		Like CTRL-], but use ":tjump" instead of ":tag".
+			{not in Vi}
+
+							*v_g_CTRL-]*
+{Visual}g CTRL-]	Same as "g CTRL-]", but use the highlighted text as
+			the identifier.  {not in Vi}
+
+							*:tn* *:tnext*
+:[count]tn[ext][!]	Jump to [count] next matching tag (default 1).  See
+			|tag-!| for [!].  {not in Vi}
+
+							*:tp* *:tprevious*
+:[count]tp[revious][!]	Jump to [count] previous matching tag (default 1).
+			See |tag-!| for [!].  {not in Vi}
+
+							*:tN* *:tNext*
+:[count]tN[ext][!]	Same as ":tprevious".  {not in Vi}
+
+							*:tr* *:trewind*
+:[count]tr[ewind][!]	Jump to first matching tag.  If [count] is given, jump
+			to [count]th matching tag.  See |tag-!| for [!].  {not
+			in Vi}
+
+							*:tf* *:tfirst*
+:[count]tf[irst][!]	Same as ":trewind".  {not in Vi}
+
+							*:tl* *:tlast*
+:tl[ast][!]		Jump to last matching tag.  See |tag-!| for [!].  {not
+			in Vi}
+
+							*:lt* *:ltag*
+:lt[ag][!] [ident]	Jump to tag [ident] and add the matching tags to a new
+			location list for the current window.  [ident] can be
+			a regexp pattern, see |tag-regexp|.  When [ident] is
+			not given, the last tag name from the tag stack is
+			used.  The search pattern to locate the tag line is
+			prefixed with "\V" to escape all the special
+			characters (very nomagic). The location list showing
+			the matching tags is independent of the tag stack.
+			See |tag-!| for [!].
+			{not in Vi}
+
+When there is no other message, Vim shows which matching tag has been jumped
+to, and the number of matching tags: >
+	tag 1 of 3 or more
+The " or more" is used to indicate that Vim didn't try all the tags files yet.
+When using ":tnext" a few times, or with ":tlast", more matches may be found.
+
+When you didn't see this message because of some other message, or you just
+want to know where you are, this command will show it again (and jump to the
+same tag as last time): >
+	:0tn
+<
+							*tag-skip-file*
+When a matching tag is found for which the file doesn't exist, this match is
+skipped and the next matching tag is used.  Vim reports this, to notify you of
+missing files.  When the end of the list of matches has been reached, an error
+message is given.
+
+							*tag-preview*
+The tag match list can also be used in the preview window.  The commands are
+the same as above, with a "p" prepended.
+{not available when compiled without the |+quickfix| feature}
+
+							*:pts* *:ptselect*
+:pts[elect][!] [ident]	Does ":tselect[!] [ident]" and shows the new tag in a
+			"Preview" window.  See |:ptag| for more info.
+			{not in Vi}
+
+							*:ptj* *:ptjump*
+:ptj[ump][!] [ident]	Does ":tjump[!] [ident]" and shows the new tag in a
+			"Preview" window.  See |:ptag| for more info.
+			{not in Vi}
+
+							*:ptn* *:ptnext*
+:[count]ptn[ext][!]	":tnext" in the preview window.  See |:ptag|.
+			{not in Vi}
+
+							*:ptp* *:ptprevious*
+:[count]ptp[revious][!]	":tprevious" in the preview window.  See |:ptag|.
+			{not in Vi}
+
+							*:ptN* *:ptNext*
+:[count]ptN[ext][!]	Same as ":ptprevious".  {not in Vi}
+
+							*:ptr* *:ptrewind*
+:[count]ptr[ewind][!]	":trewind" in the preview window.  See |:ptag|.
+			{not in Vi}
+
+							*:ptf* *:ptfirst*
+:[count]ptf[irst][!]	Same as ":ptrewind".  {not in Vi}
+
+							*:ptl* *:ptlast*
+:ptl[ast][!]		":tlast" in the preview window.  See |:ptag|.
+			{not in Vi}
+
+==============================================================================
+4. Tags details						*tag-details*
+
+							*static-tag*
+A static tag is a tag that is defined for a specific file.  In a C program
+this could be a static function.
+
+In Vi jumping to a tag sets the current search pattern.  This means that
+the "n" command after jumping to a tag does not search for the same pattern
+that it did before jumping to the tag.  Vim does not do this as we consider it
+to be a bug.  You can still find the tag search pattern in the search history.
+If you really want the old Vi behavior, set the 't' flag in 'cpoptions'.
+
+							*tag-binary-search*
+Vim uses binary searching in the tags file to find the desired tag quickly
+(when enabled at compile time |+tag_binary|).  But this only works if the
+tags file was sorted on ASCII byte value.  Therefore, if no match was found,
+another try is done with a linear search.  If you only want the linear search,
+reset the 'tagbsearch' option.  Or better: Sort the tags file!
+
+Note that the binary searching is disabled when not looking for a tag with a
+specific name.  This happens when ignoring case and when a regular expression
+is used that doesn't start with a fixed string.  Tag searching can be a lot
+slower then.  The former can be avoided by case-fold sorting the tags file.
+See 'tagbsearch' for details.
+
+							*tag-regexp*
+The ":tag" and "tselect" commands accept a regular expression argument.  See
+|pattern| for the special characters that can be used.
+When the argument starts with '/', it is used as a pattern.  If the argument
+does not start with '/', it is taken literally, as a full tag name.
+Examples: >
+    :tag main
+<	jumps to the tag "main" that has the highest priority. >
+    :tag /^get
+<	jumps to the tag that starts with "get" and has the highest priority. >
+    :tag /norm
+<	lists all the tags that contain "norm", including "id_norm".
+When the argument both exists literally, and match when used as a regexp, a
+literal match has a higher priority.  For example, ":tag /open" matches "open"
+before "open_file" and "file_open".
+When using a pattern case is ignored.  If you want to match case use "\C" in
+the pattern.
+
+							*tag-!*
+If the tag is in the current file this will always work.  Otherwise the
+performed actions depend on whether the current file was changed, whether a !
+is added to the command and on the 'autowrite' option:
+
+  tag in       file	   autowrite			~
+current file  changed	!   option	  action	~
+-----------------------------------------------------------------------------
+    yes		 x	x     x	  goto tag
+    no		 no	x     x	  read other file, goto tag
+    no		yes    yes    x   abandon current file, read other file, goto
+				  tag
+    no		yes	no    on  write current file, read other file, goto
+				  tag
+    no		yes	no   off  fail
+-----------------------------------------------------------------------------
+
+- If the tag is in the current file, the command will always work.
+- If the tag is in another file and the current file was not changed, the
+  other file will be made the current file and read into the buffer.
+- If the tag is in another file, the current file was changed and a ! is
+  added to the command, the changes to the current file are lost, the other
+  file will be made the current file and read into the buffer.
+- If the tag is in another file, the current file was changed and the
+  'autowrite' option is on, the current file will be written, the other
+  file will be made the current file and read into the buffer.
+- If the tag is in another file, the current file was changed and the
+  'autowrite' option is off, the command will fail.  If you want to save
+  the changes, use the ":w" command and then use ":tag" without an argument.
+  This works because the tag is put on the stack anyway.  If you want to lose
+  the changes you can use the ":tag!" command.
+
+							*tag-security*
+Note that Vim forbids some commands, for security reasons.  This works like
+using the 'secure' option for exrc/vimrc files in the current directory.  See
+|trojan-horse| and |sandbox|.
+When the {tagaddress} changes a buffer, you will get a warning message:
+	"WARNING: tag command changed a buffer!!!"
+In a future version changing the buffer will be impossible.  All this for
+security reasons: Somebody might hide a nasty command in the tags file, which
+would otherwise go unnoticed.  Example: >
+	:$d|/tag-function-name/
+{this security prevention is not present in Vi}
+
+In Vi the ":tag" command sets the last search pattern when the tag is searched
+for.  In Vim this is not done, the previous search pattern is still remembered,
+unless the 't' flag is present in 'cpoptions'.  The search pattern is always
+put in the search history, so you can modify it if searching fails.
+
+					*emacs-tags* *emacs_tags* *E430*
+Emacs style tag files are only supported if Vim was compiled with the
+|+emacs_tags| feature enabled.  Sorry, there is no explanation about Emacs tag
+files here, it is only supported for backwards compatibility :-).
+
+							*tags-option*
+The 'tags' option is a list of file names.  Each of these files is searched
+for the tag.  This can be used to use a different tags file than the default
+file "tags".  It can also be used to access a common tags file.
+
+The next file in the list is not used when:
+- A matching static tag for the current buffer has been found.
+- A matching global tag has been found.
+This also depends on the 'ignorecase' option.  If it is off, and the tags file
+only has a match without matching case, the next tags file is searched for a
+match with matching case.  If no tag with matching case is found, the first
+match without matching case is used.  If 'ignorecase' is on, and a matching
+global tag with or without matching case is found, this one is used, no
+further tags files are searched.
+
+When a tag file name starts with "./", the '.' is replaced with the path of
+the current file.  This makes it possible to use a tags file in the directory
+where the current file is (no matter what the current directory is).  The idea
+of using "./" is that you can define which tag file is searched first: In the
+current directory ("tags,./tags") or in the directory of the current file
+("./tags,tags").
+
+For example: >
+	:set tags=./tags,tags,/home/user/commontags
+
+In this example the tag will first be searched for in the file "tags" in the
+directory where the current file is.  Next the "tags" file in the current
+directory.  If it is not found there, then the file "/home/user/commontags"
+will be searched for the tag.
+
+This can be switched off by including the 'd' flag in 'cpoptions', to make
+it Vi compatible.  "./tags" will then be the tags file in the current
+directory, instead of the tags file in the directory where the current file
+is.
+
+Instead of the comma a space may be used.  Then a backslash is required for
+the space to be included in the string option: >
+	:set tags=tags\ /home/user/commontags
+
+To include a space in a file name use three backslashes.  To include a comma
+in a file name use two backslashes.  For example, use: >
+	:set tags=tag\\\ file,/home/user/common\\,tags
+
+for the files "tag file" and "/home/user/common,tags".  The 'tags' option will
+have the value "tag\ file,/home/user/common\,tags".
+
+If the 'tagrelative' option is on (which is the default) and using a tag file
+in another directory, file names in that tag file are relative to the
+directory where the tag file is.
+
+==============================================================================
+5. Tags file format				*tags-file-format* *E431*
+
+						*ctags* *jtags*
+A tags file can be created with an external command, for example "ctags".  It
+will contain a tag for each function.  Some versions of "ctags" will also make
+a tag for each "#defined" macro, typedefs, enums, etc.
+
+Some programs that generate tags files:
+ctags			As found on most Unix systems.  Only supports C.  Only
+			does the basic work.
+							*Exuberant_ctags*
+exuberant ctags		This a very good one.  It works for C, C++, Java,
+			Fortran, Eiffel and others.  It can generate tags for
+			many items.  See http://ctags.sourceforge.net.
+etags			Connected to Emacs.  Supports many languages.
+JTags			For Java, in Java.  It can be found at
+			http://www.fleiner.com/jtags/.
+ptags.py		For Python, in Python.  Found in your Python source
+			directory at Tools/scripts/ptags.py.
+ptags			For Perl, in Perl.  It can be found at
+			http://www.eleves.ens.fr:8080/home/nthiery/Tags/.
+gnatxref		For Ada.  See http://www.gnuada.org/.  gnatxref is
+			part of the gnat package.
+
+
+The lines in the tags file must have one of these three formats:
+
+1.  {tagname}		{TAB} {tagfile} {TAB} {tagaddress}
+2.  {tagfile}:{tagname} {TAB} {tagfile} {TAB} {tagaddress}
+3.  {tagname}		{TAB} {tagfile} {TAB} {tagaddress} {term} {field} ..
+
+The first is a normal tag, which is completely compatible with Vi.  It is the
+only format produced by traditional ctags implementations.  This is often used
+for functions that are global, also referenced in other files.
+
+The lines in the tags file can end in <LF> or <CR><LF>.  On the Macintosh <CR>
+also works.  The <CR> and <NL> characters can never appear inside a line.
+
+							*tag-old-static*
+The second format is for a static tag only.  It is obsolete now, replaced by
+the third format.  It is only supported by Elvis 1.x and Vim and a few
+versions of ctags.  A static tag is often used for functions that are local,
+only referenced in the file {tagfile}.  Note that for the static tag, the two
+occurrences of {tagfile} must be exactly the same.  Also see |tags-option|
+below, for how static tags are used.
+
+The third format is new.  It includes additional information in optional
+fields at the end of each line.  It is backwards compatible with Vi.  It is
+only supported by new versions of ctags (such as Exuberant ctags).
+
+{tagname}	The identifier.  Normally the name of a function, but it can
+		be any identifier.  It cannot contain a <Tab>.
+{TAB}		One <Tab> character.  Note: previous versions allowed any
+		white space here.  This has been abandoned to allow spaces in
+		{tagfile}.  It can be re-enabled by including the
+		|+tag_any_white| feature at compile time. *tag-any-white*
+{tagfile}	The file that contains the definition of {tagname}.  It can
+		have an absolute or relative path.  It may contain environment
+		variables and wildcards (although the use of wildcards is
+		doubtful).  It cannot contain a <Tab>.
+{tagaddress}	The Ex command that positions the cursor on the tag.  It can
+		be any Ex command, although restrictions apply (see
+		|tag-security|).  Posix only allows line numbers and search
+		commands, which are mostly used.
+{term}		;" The two characters semicolon and double quote.  This is
+		interpreted by Vi as the start of a comment, which makes the
+		following be ignored.  This is for backwards compatibility
+		with Vi, it ignores the following fields.
+{field} ..	A list of optional fields.  Each field has the form:
+
+			<Tab>{fieldname}:{value}
+
+		The {fieldname} identifies the field, and can only contain
+		alphabetical characters [a-zA-Z].
+		The {value} is any string, but cannot contain a <Tab>.
+		These characters are special:
+			"\t" stands for a <Tab>
+			"\r" stands for a <CR>
+			"\n" stands for a <NL>
+			"\\" stands for a single '\' character
+
+		There is one field that doesn't have a ':'.  This is the kind
+		of the tag.  It is handled like it was preceded with "kind:".
+		See the documentation of ctags for the kinds it produces.
+
+		The only other field currently recognized by Vim is "file:"
+		(with an empty value).  It is used for a static tag.
+
+The first lines in the tags file can contain lines that start with
+	!_TAG_
+These are sorted to the first lines, only rare tags that start with "!" can
+sort to before them.  Vim recognizes two items.  The first one is the line
+that indicates if the file was sorted.  When this line is found, Vim uses
+binary searching for the tags file:
+	!_TAG_FILE_SORTED<Tab>1<Tab>{anything} ~
+
+A tag file may be case-fold sorted to avoid a linear search when 'ignorecase'
+is on.  See 'tagbsearch' for details.  The value '2' should be used then:
+	!_TAG_FILE_SORTED<Tab>2<Tab>{anything} ~
+
+The other tag that Vim recognizes, but only when compiled with the
+|+multi_byte| feature, is the encoding of the tags file:
+	!_TAG_FILE_ENCODING<Tab>utf-8<Tab>{anything} ~
+Here "utf-8" is the encoding used for the tags.  Vim will then convert the tag
+being searched for from 'encoding' to the encoding of the tags file.  And when
+listing tags the reverse happens.  When the conversion fails the unconverted
+tag is used.
+
+							*tag-search*
+The command can be any Ex command, but often it is a search command.
+Examples:
+	tag1	file1	/^main(argc, argv)/ ~
+	tag2	file2	108 ~
+
+The command is always executed with 'magic' not set.  The only special
+characters in a search pattern are "^" (begin-of-line) and "$" (<EOL>).
+See |pattern|.  Note that you must put a backslash before each backslash in
+the search text.  This is for backwards compatibility with Vi.
+
+							*E434* *E435*
+If the command is a normal search command (it starts and ends with "/" or
+"?"), some special handling is done:
+- Searching starts on line 1 of the file.
+  The direction of the search is forward for "/", backward for "?".
+  Note that 'wrapscan' does not matter, the whole file is always searched.  (Vi
+  does use 'wrapscan', which caused tags sometimes not be found.)  {Vi starts
+  searching in line 2 of another file.  It does not find a tag in line 1 of
+  another file when 'wrapscan' is not set}
+- If the search fails, another try is done ignoring case.  If that fails too,
+  a search is done for:
+	"^tagname[ \t]*("
+  (the tag with '^' prepended and "[ \t]*(" appended).  When using function
+  names, this will find the function name when it is in column 0.  This will
+  help when the arguments to the function have changed since the tags file was
+  made.  If this search also fails another search is done with:
+	"^[#a-zA-Z_].*\<tagname[ \t]*("
+  This means: A line starting with '#' or an identifier and containing the tag
+  followed by white space and a '('.  This will find macro names and function
+  names with a type prepended.  {the extra searches are not in Vi}
+
+==============================================================================
+6. Include file searches		*include-search* *definition-search*
+							*E387* *E388* *E389*
+
+These commands look for a string in the current file and in all encountered
+included files (recursively).  This can be used to find the definition of a
+variable, function or macro.  If you only want to search in the current
+buffer, use the commands listed at |pattern-searches|.
+
+These commands are not available when the |+find_in_path| feature was disabled
+at compile time.
+
+When a line is encountered that includes another file, that file is searched
+before continuing in the current buffer.  Files included by included files are
+also searched.  When an include file could not be found it is silently
+ignored.  Use the |:checkpath| command to discover which files could not be
+found, possibly your 'path' option is not set up correctly.  Note: the
+included file is searched, not a buffer that may be editing that file.  Only
+for the current file the lines in the buffer are used.
+
+The string can be any keyword or a defined macro.  For the keyword any match
+will be found.  For defined macros only lines that match with the 'define'
+option will be found.  The default is "^#\s*define", which is for C programs.
+For other languages you probably want to change this.  See 'define' for an
+example for C++.  The string cannot contain an end-of-line, only matches
+within a line are found.
+
+When a match is found for a defined macro, the displaying of lines continues
+with the next line when a line ends in a backslash.
+
+The commands that start with "[" start searching from the start of the current
+file.  The commands that start with "]" start at the current cursor position.
+
+The 'include' option is used to define a line that includes another file.  The
+default is "\^#\s*include", which is for C programs.  Note: Vim does not
+recognize C syntax, if the 'include' option matches a line inside
+"#ifdef/#endif" or inside a comment, it is searched anyway.  The 'isfname'
+option is used to recognize the file name that comes after the matched
+pattern.
+
+The 'path' option is used to find the directory for the include files that
+do not have an absolute path.
+
+The 'comments' option is used for the commands that display a single line or
+jump to a line.  It defines patterns that may start a comment.  Those lines
+are ignored for the search, unless [!] is used.  One exception: When the line
+matches the pattern "^# *define" it is not considered to be a comment.
+
+If you want to list matches, and then select one to jump to, you could use a
+mapping to do that for you.  Here is an example: >
+
+  :map <F4> [I:let nr = input("Which one: ")<Bar>exe "normal " . nr ."[\t"<CR>
+<
+							*[i*
+[i			Display the first line that contains the keyword
+			under the cursor.  The search starts at the beginning
+			of the file.  Lines that look like a comment are
+			ignored (see 'comments' option).  If a count is given,
+			the count'th matching line is displayed, and comment
+			lines are not ignored.  {not in Vi}
+
+							*]i*
+]i			like "[i", but start at the current cursor position.
+			{not in Vi}
+
+							*:is* *:isearch*
+:[range]is[earch][!] [count] [/]pattern[/]
+			Like "[i"  and "]i", but search in [range] lines
+			(default: whole file).
+			See |:search-args| for [/] and [!].  {not in Vi}
+
+							*[I*
+[I			Display all lines that contain the keyword under the
+			cursor.  Filenames and line numbers are displayed
+			for the found lines.  The search starts at the
+			beginning of the file.  {not in Vi}
+
+							*]I*
+]I			like "[I", but start at the current cursor position.
+			{not in Vi}
+
+							*:il* *:ilist*
+:[range]il[ist][!] [/]pattern[/]
+			Like "[I" and "]I", but search in [range] lines
+			(default: whole file).
+			See |:search-args| for [/] and [!].  {not in Vi}
+
+							*[_CTRL-I*
+[ CTRL-I		Jump to the first line that contains the keyword
+			under the cursor.  The search starts at the beginning
+			of the file.  Lines that look like a comment are
+			ignored (see 'comments' option).  If a count is given,
+			the count'th matching line is jumped to, and comment
+			lines are not ignored.  {not in Vi}
+
+							*]_CTRL-I*
+] CTRL-I		like "[ CTRL-I", but start at the current cursor
+			position.  {not in Vi}
+
+							*:ij* *:ijump*
+:[range]ij[ump][!] [count] [/]pattern[/]
+			Like "[ CTRL-I"  and "] CTRL-I", but search in
+			[range] lines (default: whole file).
+			See |:search-args| for [/] and [!].  {not in Vi}
+
+CTRL-W CTRL-I					*CTRL-W_CTRL-I* *CTRL-W_i*
+CTRL-W i		Open a new window, with the cursor on the first line
+			that contains the keyword under the cursor.  The
+			search starts at the beginning of the file.  Lines
+			that look like a comment line are ignored (see
+			'comments' option).  If a count is given, the count'th
+			matching line is jumped to, and comment lines are not
+			ignored.  {not in Vi}
+
+							*:isp* *:isplit*
+:[range]isp[lit][!] [count] [/]pattern[/]
+			Like "CTRL-W i"  and "CTRL-W i", but search in
+			[range] lines (default: whole file).
+			See |:search-args| for [/] and [!].  {not in Vi}
+
+							*[d*
+[d			Display the first macro definition that contains the
+			macro under the cursor.  The search starts from the
+			beginning of the file.  If a count is given, the
+			count'th matching line is displayed.  {not in Vi}
+
+							*]d*
+]d			like "[d", but start at the current cursor position.
+			{not in Vi}
+
+							*:ds* *:dsearch*
+:[range]ds[earch][!] [count] [/]string[/]
+			Like "[d"  and "]d", but search in [range] lines
+			(default: whole file).
+			See |:search-args| for [/] and [!].  {not in Vi}
+
+							*[D*
+[D			Display all macro definitions that contain the macro
+			under the cursor.  Filenames and line numbers are
+			displayed for the found lines.  The search starts
+			from the beginning of the file.  {not in Vi}
+
+							*]D*
+]D			like "[D", but start at the current cursor position.
+			{not in Vi}
+
+							*:dli* *:dlist*
+:[range]dl[ist][!] [/]string[/]
+			Like "[D"  and "]D", but search in [range] lines
+			(default: whole file).
+			See |:search-args| for [/] and [!].  {not in Vi}
+			Note that ":dl" works like ":delete" with the "l"
+			flag.
+
+							*[_CTRL-D*
+[ CTRL-D		Jump to the first macro definition that contains the
+			keyword under the cursor.  The search starts from
+			the beginning of the file.  If a count is given, the
+			count'th matching line is jumped to.  {not in Vi}
+
+							*]_CTRL-D*
+] CTRL-D		like "[ CTRL-D", but start at the current cursor
+			position.  {not in Vi}
+
+							*:dj* *:djump*
+:[range]dj[ump][!] [count] [/]string[/]
+			Like "[ CTRL-D"  and "] CTRL-D", but search  in
+			[range] lines (default: whole file).
+			See |:search-args| for [/] and [!].  {not in Vi}
+
+CTRL-W CTRL-D					*CTRL-W_CTRL-D* *CTRL-W_d*
+CTRL-W d		Open a new window, with the cursor on the first
+			macro definition line that contains the keyword
+			under the cursor.  The search starts from the
+			beginning of the file.  If a count is given, the
+			count'th matching line is jumped to.  {not in Vi}
+
+							*:dsp* *:dsplit*
+:[range]dsp[lit][!] [count] [/]string[/]
+			Like "CTRL-W d", but search in [range] lines
+			(default: whole file).
+			See |:search-args| for [/] and [!].  {not in Vi}
+
+							*:che* *:checkpath*
+:che[ckpath]		List all the included files that could not be found.
+			{not in Vi}
+
+:che[ckpath]!		List all the included files.  {not in Vi}
+
+								*:search-args*
+Common arguments for the commands above:
+[!]   When included, find matches in lines that are recognized as comments.
+      When excluded, a match is ignored when the line is recognized as a
+      comment (according to 'comments'), or the match is in a C comment (after
+      "//" or inside /* */).  Note that a match may be missed if a line is
+      recognized as a comment, but the comment ends halfway the line.
+      And  if the line is a comment, but it is not recognized (according to
+      'comments') a match may be found in it anyway.  Example: >
+		/* comment
+		   foobar */
+<     A match for "foobar" is found, because this line is not recognized as a
+      comment (even though syntax highlighting does recognize it).
+      Note: Since a macro definition mostly doesn't look like a comment, the
+      [!] makes no difference for ":dlist", ":dsearch" and ":djump".
+[/]   A pattern can be surrounded by '/'.  Without '/' only whole words are
+      matched, using the pattern "\<pattern\>".  Only after the second '/' a
+      next command can be appended with '|'.  Example: >
+	:isearch /string/ | echo "the last one"
+<     For a ":djump", ":dsplit", ":dlist" and ":dsearch" command the pattern
+      is used as a literal string, not as a search pattern.
+
+ vim:tw=78:ts=8:ft=help:norl:
--- /dev/null
+++ b/lib/vimfiles/doc/term.txt
@@ -1,0 +1,856 @@
+*term.txt*      For Vim version 7.1.  Last change: 2007 Feb 28
+
+
+		  VIM REFERENCE MANUAL    by Bram Moolenaar
+
+
+Terminal information					*terminal-info*
+
+Vim uses information about the terminal you are using to fill the screen and
+recognize what keys you hit.  If this information is not correct, the screen
+may be messed up or keys may not be recognized.  The actions which have to be
+performed on the screen are accomplished by outputting a string of
+characters.  Special keys produce a string of characters.  These strings are
+stored in the terminal options, see |terminal-options|.
+
+NOTE: Most of this is not used when running the |GUI|.
+
+1. Startup			|startup-terminal|
+2. Terminal options		|terminal-options|
+3. Window size			|window-size|
+4. Slow and fast terminals	|slow-fast-terminal|
+5. Using the mouse		|mouse-using|
+
+==============================================================================
+1. Startup						*startup-terminal*
+
+When Vim is started a default terminal type is assumed.  For the Amiga this is
+a standard CLI window, for MS-DOS the pc terminal, for Unix an ansi terminal.
+A few other terminal types are always available, see below |builtin-terms|.
+
+You can give the terminal name with the '-T' Vim argument.  If it is not given
+Vim will try to get the name from the TERM environment variable.
+
+				*termcap* *terminfo* *E557* *E558* *E559*
+On Unix the terminfo database or termcap file is used.  This is referred to as
+"termcap" in all the documentation.  At compile time, when running configure,
+the choice whether to use terminfo or termcap is done automatically.  When
+running Vim the output of ":version" will show |+terminfo| if terminfo is
+used.  Also see |xterm-screens|.
+
+On non-Unix systems a termcap is only available if Vim was compiled with
+TERMCAP defined.
+
+					*builtin-terms* *builtin_terms*
+Which builtin terminals are available depends on a few defines in feature.h,
+which need to be set at compile time:
+    define		output of ":version"	terminals builtin	~
+NO_BUILTIN_TCAPS	-builtin_terms		none
+SOME_BUILTIN_TCAPS	+builtin_terms		most common ones (default)
+ALL_BUILTIN_TCAPS	++builtin_terms		all available
+
+You can see a list of available builtin terminals with ":set term=xxx" (when
+not running the GUI).  Also see |+builtin_terms|.
+
+If the termcap code is included Vim will try to get the strings for the
+terminal you are using from the termcap file and the builtin termcaps.  Both
+are always used, if an entry for the terminal you are using is present.  Which
+one is used first depends on the 'ttybuiltin' option:
+
+'ttybuiltin' on		1: builtin termcap	2: external termcap
+'ttybuiltin' off	1: external termcap	2: builtin termcap
+
+If an option is missing in one of them, it will be obtained from the other
+one.  If an option is present in both, the one first encountered is used.
+
+Which external termcap file is used varies from system to system and may
+depend on the environment variables "TERMCAP" and "TERMPATH".  See "man
+tgetent".
+
+Settings depending on terminal			*term-dependent-settings*
+
+If you want to set options or mappings, depending on the terminal name, you
+can do this best in your .vimrc.  Example: >
+
+   if &term == "xterm"
+     ... xterm maps and settings ...
+   elseif &term =~ "vt10."
+     ... vt100, vt102 maps and settings ...
+   endif
+<
+						*raw-terminal-mode*
+For normal editing the terminal will be put into "raw" mode.  The strings
+defined with 't_ti' and 't_ks' will be sent to the terminal.  Normally this
+puts the terminal in a state where the termcap codes are valid and activates
+the cursor and function keys.  When Vim exits the terminal will be put back
+into the mode it was before Vim started.  The strings defined with 't_te' and
+'t_ke' will be sent to the terminal.  On the Amiga, with commands that execute
+an external command (e.g., "!!"), the terminal will be put into Normal mode
+for a moment.  This means that you can stop the output to the screen by
+hitting a printing key.  Output resumes when you hit <BS>.
+
+							*cs7-problem*
+Note: If the terminal settings are changed after running Vim, you might have
+an illegal combination of settings.  This has been reported on Solaris 2.5
+with "stty cs8 parenb", which is restored as "stty cs7 parenb".  Use
+"stty cs8 -parenb -istrip" instead, this is restored correctly.
+
+Some termcap entries are wrong in the sense that after sending 't_ks' the
+cursor keys send codes different from the codes defined in the termcap.  To
+avoid this you can set 't_ks' (and 't_ke') to empty strings.  This must be
+done during initialization (see |initialization|), otherwise it's too late.
+
+Some termcap entries assume that the highest bit is always reset.  For
+example: The cursor-up entry for the Amiga could be ":ku=\E[A:".  But the
+Amiga really sends "\233A".  This works fine if the highest bit is reset,
+e.g., when using an Amiga over a serial line.  If the cursor keys don't work,
+try the entry ":ku=\233A:".
+
+Some termcap entries have the entry ":ku=\E[A:".  But the Amiga really sends
+"\233A".  On output "\E[" and "\233" are often equivalent, on input they
+aren't.  You will have to change the termcap entry, or change the key code with
+the :set command to fix this.
+
+Many cursor key codes start with an <Esc>.  Vim must find out if this is a
+single hit of the <Esc> key or the start of a cursor key sequence.  It waits
+for a next character to arrive.  If it does not arrive within one second a
+single <Esc> is assumed.  On very slow systems this may fail, causing cursor
+keys not to work sometimes.  If you discover this problem reset the 'timeout'
+option.  Vim will wait for the next character to arrive after an <Esc>.  If
+you want to enter a single <Esc> you must type it twice.  Resetting the
+'esckeys' option avoids this problem in Insert mode, but you lose the
+possibility to use cursor and function keys in Insert mode.
+
+On the Amiga the recognition of window resizing is activated only when the
+terminal name is "amiga" or "builtin_amiga".
+
+Some terminals have confusing codes for the cursor keys.  The televideo 925 is
+such a terminal.  It sends a CTRL-H for cursor-left.  This would make it
+impossible to distinguish a backspace and cursor-left.  To avoid this problem
+CTRL-H is never recognized as cursor-left.
+
+					*vt100-cursor-keys* *xterm-cursor-keys*
+Other terminals (e.g., vt100 and xterm) have cursor keys that send <Esc>OA,
+<Esc>OB, etc.  Unfortunately these are valid commands in insert mode: Stop
+insert, Open a new line above the new one, start inserting 'A', 'B', etc.
+Instead of performing these commands Vim will erroneously recognize this typed
+key sequence as a cursor key movement.  To avoid this and make Vim do what you
+want in either case you could use these settings: >
+	:set notimeout		" don't timeout on mappings
+	:set ttimeout		" do timeout on terminal key codes
+	:set timeoutlen=100	" timeout after 100 msec
+This requires the key-codes to be sent within 100msec in order to recognize
+them as a cursor key.  When you type you normally are not that fast, so they
+are recognized as individual typed commands, even though Vim receives the same
+sequence of bytes.
+
+				*vt100-function-keys* *xterm-function-keys*
+An xterm can send function keys F1 to F4 in two modes: vt100 compatible or
+not.  Because Vim may not know what the xterm is sending, both types of keys
+are recognized.  The same happens for the <Home> and <End> keys.
+			normal			vt100 ~
+	<F1>	t_k1	<Esc>[11~	<xF1>	<Esc>OP	    *<xF1>-xterm*
+	<F2>	t_k2	<Esc>[12~	<xF2>	<Esc>OQ	    *<xF2>-xterm*
+	<F3>	t_k3	<Esc>[13~	<xF3>	<Esc>OR	    *<xF3>-xterm*
+	<F4>	t_k4	<Esc>[14~	<xF4>	<Esc>OS	    *<xF4>-xterm*
+	<Home>	t_kh	<Esc>[7~	<xHome>	<Esc>OH	    *<xHome>-xterm*
+	<End>	t_@7	<Esc>[4~	<xEnd>	<Esc>OF	    *<xEnd>-xterm*
+
+When Vim starts, <xF1> is mapped to <F1>, <xF2> to <F2> etc.  This means that
+by default both codes do the same thing.  If you make a mapping for <xF2>,
+because your terminal does have two keys, the default mapping is overwritten,
+thus you can use the <F2> and <xF2> keys for something different.
+
+							*xterm-shifted-keys*
+Newer versions of xterm support shifted function keys and special keys.  Vim
+recognizes most of them.  Use ":set termcap" to check which are supported and
+what the codes are.  Mostly these are not in a termcap, they are only
+supported by the builtin_xterm termcap.
+
+							*xterm-modifier-keys*
+Newer versions of xterm support Alt and Ctrl for most function keys.  To avoid
+having to add all combinations of Alt, Ctrl and Shift for every key a special
+sequence is recognized at the end of a termcap entry: ";*X".  The "X" can be
+any character, often '~' is used.  The ";*" stands for an optional modifier
+argument.  ";2" is Shift, ";3" is Alt, ";5" is Ctrl and ";9" is Meta (when
+it's different from Alt).  They can be combined.  Examples: >
+	:set <F8>=^[[19;*~
+	:set <Home>=^[[1;*H
+Another speciality about these codes is that they are not overwritten by
+another code.  That is to avoid that the codes obtained from xterm directly
+|t_RV| overwrite them.
+							*xterm-scroll-region*
+The default termcap entry for xterm on Sun and other platforms does not
+contain the entry for scroll regions.  Add ":cs=\E[%i%d;%dr:" to the xterm
+entry in /etc/termcap and everything should work.
+
+							*xterm-end-home-keys*
+On some systems (at least on FreeBSD with XFree86 3.1.2) the codes that the
+<End> and <Home> keys send contain a <Nul> character.  To make these keys send
+the proper key code, add these lines to your ~/.Xdefaults file:
+
+*VT100.Translations:		#override \n\
+		<Key>Home: string("0x1b") string("[7~") \n\
+		<Key>End: string("0x1b") string("[8~")
+
+						*xterm-8bit* *xterm-8-bit*
+Xterm can be run in a mode where it uses 8-bit escape sequences.  The CSI code
+is used instead of <Esc>[.  The advantage is that an <Esc> can quickly be
+recognized in Insert mode, because it can't be confused with the start of a
+special key.
+For the builtin termcap entries, Vim checks if the 'term' option contains
+"8bit" anywhere.  It then uses 8-bit characters for the termcap entries, the
+mouse and a few other things.  You would normally set $TERM in your shell to
+"xterm-8bit" and Vim picks this up and adjusts to the 8-bit setting
+automatically.
+When Vim receives a response to the |t_RV| (request version) sequence and it
+starts with CSI, it assumes that the terminal is in 8-bit mode and will
+convert all key sequences to their 8-bit variants.
+
+==============================================================================
+2. Terminal options		*terminal-options* *termcap-options* *E436*
+
+The terminal options can be set just like normal options.  But they are not
+shown with the ":set all" command.  Instead use ":set termcap".
+
+It is always possible to change individual strings by setting the
+appropriate option.  For example: >
+	:set t_ce=^V^[[K	(CTRL-V, <Esc>, [, K)
+
+{Vi: no terminal options.  You have to exit Vi, edit the termcap entry and
+try again}
+
+The options are listed below.  The associated termcap code is always equal to
+the last two characters of the option name.  Only one termcap code is
+required: Cursor motion, 't_cm'.
+
+The options 't_da', 't_db', 't_ms', 't_xs' represent flags in the termcap.
+When the termcap flag is present, the option will be set to "y".  But any
+non-empty string means that the flag is set.  An empty string means that the
+flag is not set.  't_CS' works like this too, but it isn't a termcap flag.
+
+OUTPUT CODES
+	option	meaning	~
+
+	t_AB	set background color (ANSI)			*t_AB* *'t_AB'*
+	t_AF	set foreground color (ANSI)			*t_AF* *'t_AF'*
+	t_AL	add number of blank lines			*t_AL* *'t_AL'*
+	t_al	add new blank line				*t_al* *'t_al'*
+	t_bc	backspace character				*t_bc* *'t_bc'*
+	t_cd	clear to end of screen				*t_cd* *'t_cd'*
+	t_ce	clear to end of line				*t_ce* *'t_ce'*
+	t_cl	clear screen					*t_cl* *'t_cl'*
+	t_cm	cursor motion (required!)		  *E437* *t_cm* *'t_cm'*
+	t_Co	number of colors				*t_Co* *'t_Co'*
+	t_CS	if non-empty, cursor relative to scroll region	*t_CS* *'t_CS'*
+	t_cs	define scrolling region				*t_cs* *'t_cs'*
+	t_CV	define vertical scrolling region		*t_CV* *'t_CV'*
+	t_da	if non-empty, lines from above scroll down	*t_da* *'t_da'*
+	t_db	if non-empty, lines from below scroll up	*t_db* *'t_db'*
+	t_DL	delete number of lines				*t_DL* *'t_DL'*
+	t_dl	delete line					*t_dl* *'t_dl'*
+	t_fs	set window title end (from status line)		*t_fs* *'t_fs'*
+	t_ke	exit "keypad transmit" mode			*t_ke* *'t_ke'*
+	t_ks	start "keypad transmit" mode			*t_ks* *'t_ks'*
+	t_le	move cursor one char left			*t_le* *'t_le'*
+	t_mb	blinking mode					*t_mb* *'t_mb'*
+	t_md	bold mode					*t_md* *'t_md'*
+	t_me	Normal mode (undoes t_mr, t_mb, t_md and color)	*t_me* *'t_me'*
+	t_mr	reverse (invert) mode				*t_mr* *'t_mr'*
+								*t_ms* *'t_ms'*
+	t_ms	if non-empty, cursor can be moved in standout/inverse mode
+	t_nd	non destructive space character			*t_nd* *'t_nd'*
+	t_op	reset to original color pair			*t_op* *'t_op'*
+	t_RI	cursor number of chars right			*t_RI* *'t_RI'*
+	t_Sb	set background color				*t_Sb* *'t_Sb'*
+	t_Sf	set foreground color				*t_Sf* *'t_Sf'*
+	t_se	standout end					*t_se* *'t_se'*
+	t_so	standout mode					*t_so* *'t_so'*
+	t_sr	scroll reverse (backward)			*t_sr* *'t_sr'*
+	t_te	out of "termcap" mode				*t_te* *'t_te'*
+	t_ti	put terminal in "termcap" mode			*t_ti* *'t_ti'*
+	t_ts	set window title start (to status line)		*t_ts* *'t_ts'*
+	t_ue	underline end					*t_ue* *'t_ue'*
+	t_us	underline mode					*t_us* *'t_us'*
+	t_Ce	undercurl end					*t_Ce* *'t_Ce'*
+	t_Cs	undercurl mode					*t_Cs* *'t_Cs'*
+	t_ut	clearing uses the current background color	*t_ut* *'t_ut'*
+	t_vb	visual bell					*t_vb* *'t_vb'*
+	t_ve	cursor visible					*t_ve* *'t_ve'*
+	t_vi	cursor invisible				*t_vi* *'t_vi'*
+	t_vs	cursor very visible				*t_vs* *'t_vs'*
+								*t_xs* *'t_xs'*
+	t_xs	if non-empty, standout not erased by overwriting (hpterm)
+	t_ZH	italics mode					*t_ZH* *'t_ZH'*
+	t_ZR	italics end					*t_ZR* *'t_ZR'*
+
+Added by Vim (there are no standard codes for these):
+	t_IS	set icon text start				*t_IS* *'t_IS'*
+	t_IE	set icon text end				*t_IE* *'t_IE'*
+	t_WP	set window position (Y, X) in pixels		*t_WP* *'t_WP'*
+	t_WS	set window size (height, width) in characters	*t_WS* *'t_WS'*
+	t_SI	start insert mode (bar cursor shape)		*t_SI* *'t_SI'*
+	t_EI	end insert mode (block cursor shape)		*t_EI* *'t_EI'*
+		|termcap-cursor-shape|
+	t_RV	request terminal version string (for xterm)	*t_RV* *'t_RV'*
+		|xterm-8bit| |v:termresponse| |'ttymouse'| |xterm-codes|
+
+KEY CODES
+Note: Use the <> form if possible
+
+	option	name		meaning	~
+
+	t_ku	<Up>		arrow up			*t_ku* *'t_ku'*
+	t_kd	<Down>		arrow down			*t_kd* *'t_kd'*
+	t_kr	<Right>		arrow right			*t_kr* *'t_kr'*
+	t_kl	<Left>		arrow left			*t_kl* *'t_kl'*
+		<xUp>		alternate arrow up		*<xUp>*
+		<xDown>		alternate arrow down		*<xDown>*
+		<xRight>	alternate arrow right		*<xRight>*
+		<xLeft>		alternate arrow left		*<xLeft>*
+		<S-Up>		shift arrow up
+		<S-Down>	shift arrow down
+	t_%i	<S-Right>	shift arrow right		*t_%i* *'t_%i'*
+	t_#4	<S-Left>	shift arrow left		*t_#4* *'t_#4'*
+	t_k1	<F1>		function key 1			*t_k1* *'t_k1'*
+		<xF1>		alternate F1			*<xF1>*
+	t_k2	<F2>		function key 2		*<F2>*	*t_k2* *'t_k2'*
+		<xF2>		alternate F2			*<xF2>*
+	t_k3	<F3>		function key 3		*<F3>*	*t_k3* *'t_k3'*
+		<xF3>		alternate F3			*<xF3>*
+	t_k4	<F4>		function key 4		*<F4>*	*t_k4* *'t_k4'*
+		<xF4>		alternate F4			*<xF4>*
+	t_k5	<F5>		function key 5		*<F5>*	*t_k5* *'t_k5'*
+	t_k6	<F6>		function key 6		*<F6>*	*t_k6* *'t_k6'*
+	t_k7	<F7>		function key 7		*<F7>*	*t_k7* *'t_k7'*
+	t_k8	<F8>		function key 8		*<F8>*	*t_k8* *'t_k8'*
+	t_k9	<F9>		function key 9		*<F9>*	*t_k9* *'t_k9'*
+	t_k;	<F10>		function key 10		*<F10>*	*t_k;* *'t_k;'*
+	t_F1	<F11>		function key 11		*<F11>* *t_F1* *'t_F1'*
+	t_F2	<F12>		function key 12		*<F12>*	*t_F2* *'t_F2'*
+	t_F3	<F13>		function key 13		*<F13>*	*t_F3* *'t_F3'*
+	t_F4	<F14>		function key 14		*<F14>*	*t_F4* *'t_F4'*
+	t_F5	<F15>		function key 15		*<F15>*	*t_F5* *'t_F5'*
+	t_F6	<F16>		function key 16		*<F16>*	*t_F6* *'t_F6'*
+	t_F7	<F17>		function key 17		*<F17>*	*t_F7* *'t_F7'*
+	t_F8	<F18>		function key 18		*<F18>*	*t_F8* *'t_F8'*
+	t_F9	<F19>		function key 19		*<F19>*	*t_F9* *'t_F9'*
+		<S-F1>		shifted function key 1
+		<S-xF1>		alternate <S-F1>		*<S-xF1>*
+		<S-F2>		shifted function key 2		*<S-F2>*
+		<S-xF2>		alternate <S-F2>		*<S-xF2>*
+		<S-F3>		shifted function key 3		*<S-F3>*
+		<S-xF3>		alternate <S-F3>		*<S-xF3>*
+		<S-F4>		shifted function key 4		*<S-F4>*
+		<S-xF4>		alternate <S-F4>		*<S-xF4>*
+		<S-F5>		shifted function key 5		*<S-F5>*
+		<S-F6>		shifted function key 6		*<S-F6>*
+		<S-F7>		shifted function key 7		*<S-F7>*
+		<S-F8>		shifted function key 8		*<S-F8>*
+		<S-F9>		shifted function key 9		*<S-F9>*
+		<S-F10>		shifted function key 10		*<S-F10>*
+		<S-F11>		shifted function key 11		*<S-F11>*
+		<S-F12>		shifted function key 12		*<S-F12>*
+	t_%1	<Help>		help key			*t_%1* *'t_%1'*
+	t_&8	<Undo>		undo key			*t_&8* *'t_&8'*
+	t_kI	<Insert>	insert key			*t_kI* *'t_kI'*
+	t_kD	<Del>		delete key			*t_kD* *'t_kD'*
+	t_kb	<BS>		backspace key			*t_kb* *'t_kb'*
+	t_kB	<S-Tab>		back-tab (shift-tab)  *<S-Tab>* *t_kB* *'t_kB'*
+	t_kh	<Home>		home key			*t_kh* *'t_kh'*
+	t_#2	<S-Home>	shifted home key     *<S-Home>* *t_#2* *'t_#2'*
+		<xHome>		alternate home key		*<xHome>*
+	t_@7	<End>		end key				*t_@7* *'t_@7'*
+	t_*7	<S-End>		shifted end key	*<S-End>* *t_star7* *'t_star7'*
+		<xEnd>		alternate end key		*<xEnd>*
+	t_kP	<PageUp>	page-up key			*t_kP* *'t_kP'*
+	t_kN	<PageDown>	page-down key			*t_kN* *'t_kN'*
+	t_K1	<kHome>		keypad home key			*t_K1* *'t_K1'*
+	t_K4	<kEnd>		keypad end key			*t_K4* *'t_K4'*
+	t_K3	<kPageUp>	keypad page-up key		*t_K3* *'t_K3'*
+	t_K5	<kPageDown>	keypad page-down key		*t_K5* *'t_K5'*
+	t_K6	<kPlus>		keypad plus key	      *<kPlus>*	*t_K6* *'t_K6'*
+	t_K7	<kMinus>	keypad minus key     *<kMinus>*	*t_K7* *'t_K7'*
+	t_K8	<kDivide>	keypad divide	    *<kDivide>* *t_K8* *'t_K8'*
+	t_K9	<kMultiply>	keypad multiply   *<kMultiply>* *t_K9* *'t_K9'*
+	t_KA	<kEnter>	keypad enter key     *<kEnter>*	*t_KA* *'t_KA'*
+	t_KB	<kPoint>	keypad decimal point *<kPoint>*	*t_KB* *'t_KB'*
+	t_KC	<k0>		keypad 0		 *<k0>*	*t_KC* *'t_KC'*
+	t_KD	<k1>		keypad 1		 *<k1>*	*t_KD* *'t_KD'*
+	t_KE	<k2>		keypad 2		 *<k2>*	*t_KE* *'t_KE'*
+	t_KF	<k3>		keypad 3		 *<k3>*	*t_KF* *'t_KF'*
+	t_KG	<k4>		keypad 4		 *<k4>*	*t_KG* *'t_KG'*
+	t_KH	<k5>		keypad 5		 *<k5>*	*t_KH* *'t_KH'*
+	t_KI	<k6>		keypad 6		 *<k6>*	*t_KI* *'t_KI'*
+	t_KJ	<k7>		keypad 7		 *<k7>*	*t_KJ* *'t_KJ'*
+	t_KK	<k8>		keypad 8		 *<k8>*	*t_KK* *'t_KK'*
+	t_KL	<k9>		keypad 9		 *<k9>*	*t_KL* *'t_KL'*
+		<Mouse>		leader of mouse code		*<Mouse>*
+
+Note about t_so and t_mr: When the termcap entry "so" is not present the
+entry for "mr" is used.  And vice versa.  The same is done for "se" and "me".
+If your terminal supports both inversion and standout mode, you can see two
+different modes.  If your terminal supports only one of the modes, both will
+look the same.
+
+							*keypad-comma*
+The keypad keys, when they are not mapped, behave like the equivalent normal
+key.  There is one exception: if you have a comma on the keypad instead of a
+decimal point, Vim will use a dot anyway.  Use these mappings to fix that: >
+	:noremap <kPoint> ,
+	:noremap! <kPoint> ,
+<							*xterm-codes*
+There is a special trick to obtain the key codes which currently only works
+for xterm.  When |t_RV| is defined and a response is received which indicates
+an xterm with patchlevel 141 or higher, Vim uses special escape sequences to
+request the key codes directly from the xterm.  The responses are used to
+adjust the various t_ codes.  This avoids the problem that the xterm can
+produce different codes, depending on the mode it is in (8-bit, VT102,
+VT220, etc.).  The result is that codes like <xF1> are no longer needed.
+Note: This is only done on startup.  If the xterm options are changed after
+Vim has started, the escape sequences may not be recognized any more.
+
+							*termcap-colors*
+Note about colors: The 't_Co' option tells Vim the number of colors available.
+When it is non-zero, the 't_AB' and 't_AF' options are used to set the color.
+If one of these is not available, 't_Sb' and 't_Sf' are used.  't_me' is used
+to reset to the default colors.
+
+				*termcap-cursor-shape* *termcap-cursor-color*
+When Vim enters Insert mode the 't_SI' escape sequence is sent.  When leaving
+Insert mode 't_EI' is used.  But only if both are defined.  This can be used
+to change the shape or color of the cursor in Insert mode.  These are not
+standard termcap/terminfo entries, you need to set them yourself.
+Example for an xterm, this changes the color of the cursor: >
+    if &term =~ "xterm"
+	let &t_SI = "\<Esc>]12;purple\x7"
+	let &t_EI = "\<Esc>]12;blue\x7"
+    endif
+NOTE: When Vim exits the shape for Normal mode will remain.  The shape from
+before Vim started will not be restored.
+{not available when compiled without the +cursorshape feature}
+
+							*termcap-title*
+The 't_ts' and 't_fs' options are used to set the window title if the terminal
+allows title setting via sending strings.  They are sent before and after the
+title string, respectively.  Similar 't_IS' and 't_IE'  are used to set the
+icon text.  These are Vim-internal extensions of the Unix termcap, so they
+cannot be obtained from an external termcap.  However, the builtin termcap
+contains suitable entries for xterm and iris-ansi, so you don't need to set
+them here.
+							*hpterm*
+If inversion or other highlighting does not work correctly, try setting the
+'t_xs' option to a non-empty string.  This makes the 't_ce' code be used to
+remove highlighting from a line.  This is required for "hpterm".  Setting the
+'weirdinvert' option has the same effect as making 't_xs' non-empty, and vice
+versa.
+
+							*scroll-region*
+Some termcaps do not include an entry for 'cs' (scroll region), although the
+terminal does support it.  For example: xterm on a Sun.  You can use the
+builtin_xterm or define t_cs yourself.  For example: >
+	:set t_cs=^V^[[%i%d;%dr
+Where ^V is CTRL-V and ^[ is <Esc>.
+
+The vertical scroll region t_CV is not a standard termcap code.  Vim uses it
+internally in the GUI.  But it can also be defined for a terminal, if you can
+find one that supports it.  The two arguments are the left and right column of
+the region which to restrict the scrolling to.  Just like t_cs defines the top
+and bottom lines.  Defining t_CV will make scrolling in vertically split
+windows a lot faster.  Don't set t_CV when t_da or t_db is set (text isn't
+cleared when scrolling).
+
+Unfortunately it is not possible to deduce from the termcap how cursor
+positioning should be done when using a scrolling region: Relative to the
+beginning of the screen or relative to the beginning of the scrolling region.
+Most terminals use the first method.  A known exception is the MS-DOS console
+(pcterm).  The 't_CS' option should be set to any string when cursor
+positioning is relative to the start of the scrolling region.  It should be
+set to an empty string otherwise.  It defaults to "yes" when 'term' is
+"pcterm".
+
+Note for xterm users: The shifted cursor keys normally don't work.  You can
+	make them work with the xmodmap command and some mappings in Vim.
+
+	Give these commands in the xterm:
+		xmodmap -e "keysym Up = Up F13"
+		xmodmap -e "keysym Down = Down F16"
+		xmodmap -e "keysym Left = Left F18"
+		xmodmap -e "keysym Right = Right F19"
+
+	And use these mappings in Vim:
+		:map <t_F3> <S-Up>
+		:map! <t_F3> <S-Up>
+		:map <t_F6> <S-Down>
+		:map! <t_F6> <S-Down>
+		:map <t_F8> <S-Left>
+		:map! <t_F8> <S-Left>
+		:map <t_F9> <S-Right>
+		:map! <t_F9> <S-Right>
+
+Instead of, say, <S-Up> you can use any other command that you want to use the
+shift-cursor-up key for.  (Note: To help people that have a Sun keyboard with
+left side keys F14 is not used because it is confused with the undo key; F15
+is not used, because it does a window-to-front; F17 is not used, because it
+closes the window.  On other systems you can probably use them.)
+
+==============================================================================
+3. Window size						*window-size*
+
+[This is about the size of the whole window Vim is using, not a window that is
+created with the ":split" command.]
+
+If you are running Vim on an Amiga and the terminal name is "amiga" or
+"builtin_amiga", the amiga-specific window resizing will be enabled.  On Unix
+systems three methods are tried to get the window size:
+
+- an ioctl call (TIOCGSIZE or TIOCGWINSZ, depends on your system)
+- the environment variables "LINES" and "COLUMNS"
+- from the termcap entries "li" and "co"
+
+If everything fails a default size of 24 lines and 80 columns is assumed.  If
+a window-resize signal is received the size will be set again.  If the window
+size is wrong you can use the 'lines' and 'columns' options to set the
+correct values.
+
+One command can be used to set the screen size:
+
+						*:mod* *:mode* *E359* *E362*
+:mod[e] [mode]
+
+Without argument this only detects the screen size and redraws the screen.
+With MS-DOS it is possible to switch screen mode.  [mode] can be one of these
+values:
+	"bw40"		40 columns black&white
+	"c40"		40 columns color
+	"bw80"		80 columns black&white
+	"c80"		80 columns color (most people use this)
+	"mono"		80 columns monochrome
+	"c4350"		43 or 50 lines EGA/VGA mode
+	number		mode number to use, depends on your video card
+
+==============================================================================
+4. Slow and fast terminals			*slow-fast-terminal*
+						*slow-terminal*
+
+If you have a fast terminal you may like to set the 'ruler' option.  The
+cursor position is shown in the status line.  If you are using horizontal
+scrolling ('wrap' option off) consider setting 'sidescroll' to a small
+number.
+
+If you have a slow terminal you may want to reset the 'showcmd' option.
+The command characters will not be shown in the status line.  If the terminal
+scrolls very slowly, set the 'scrolljump' to 5 or so.  If the cursor is moved
+off the screen (e.g., with "j") Vim will scroll 5 lines at a time.  Another
+possibility is to reduce the number of lines that Vim uses with the command
+"z{height}<CR>".
+
+If the characters from the terminal are arriving with more than 1 second
+between them you might want to set the 'timeout' and/or 'ttimeout' option.
+See the "Options" chapter |options|.
+
+If your terminal does not support a scrolling region, but it does support
+insert/delete line commands, scrolling with multiple windows may make the
+lines jump up and down.  If you don't want this set the 'ttyfast' option.
+This will redraw the window instead of scroll it.
+
+If your terminal scrolls very slowly, but redrawing is not slow, set the
+'ttyscroll' option to a small number, e.g., 3.  This will make Vim redraw the
+screen instead of scrolling, when there are more than 3 lines to be scrolled.
+
+If you are using a color terminal that is slow, use this command: >
+	hi NonText cterm=NONE ctermfg=NONE
+This avoids that spaces are sent when they have different attributes.  On most
+terminals you can't see this anyway.
+
+If you are using Vim over a slow serial line, you might want to try running
+Vim inside the "screen" program.  Screen will optimize the terminal I/O quite
+a bit.
+
+If you are testing termcap options, but you cannot see what is happening,
+you might want to set the 'writedelay' option.  When non-zero, one character
+is sent to the terminal at a time (does not work for MS-DOS).  This makes the
+screen updating a lot slower, making it possible to see what is happening.
+
+==============================================================================
+5. Using the mouse					*mouse-using*
+
+This section is about using the mouse on a terminal or a terminal window.  How
+to use the mouse in a GUI window is explained in |gui-mouse|.  For scrolling
+with a mouse wheel see |scroll-mouse-wheel|.
+
+Don't forget to enable the mouse with this commands: >
+	:set mouse=a
+Otherwise Vim won't recognize the mouse in all modes (See 'mouse').
+
+Currently the mouse is supported for Unix in an xterm window, in a Linux
+console (with GPM |gpm-mouse|), for MS-DOS and in a Windows console.
+Mouse clicks can be used to position the cursor, select an area and paste.
+
+These characters in the 'mouse' option tell in which situations the mouse will
+be used by Vim:
+		n	Normal mode
+		v	Visual mode
+		i	Insert mode
+		c	Command-line mode
+		h	all previous modes when in a help file
+		a	all previous modes
+		r	for |hit-enter| prompt
+
+The default for 'mouse' is empty, the mouse is not used.  Normally you would
+do: >
+	:set mouse=a
+to start using the mouse (this is equivalent to setting 'mouse' to "nvich").
+If you only want to use the mouse in a few modes or also want to use it for
+the two questions you will have to concatenate the letters for those modes.
+For example: >
+	:set mouse=nv
+Will make the mouse work in Normal mode and Visual mode. >
+	:set mouse=h
+Will make the mouse work in help files only (so you can use "g<LeftMouse>" to
+jump to tags).
+
+Whether the selection that is started with the mouse is in Visual mode or
+Select mode depends on whether "mouse" is included in the 'selectmode'
+option.
+
+In an xterm, with the currently active mode included in the 'mouse' option,
+normal mouse clicks are used by Vim, mouse clicks with the shift or ctrl key
+pressed go to the xterm.  With the currently active mode not included in
+'mouse' all mouse clicks go to the xterm.
+
+							*xterm-clipboard*
+In the Athena and Motif GUI versions, when running in a terminal and there is
+access to the X-server (DISPLAY is set), the copy and paste will behave like
+in the GUI.  If not, the middle mouse button will insert the unnamed register.
+In that case, here is how you copy and paste a piece of text:
+
+Copy/paste with the mouse and Visual mode ('mouse' option must be set, see
+above):
+1. Press left mouse button on first letter of text, move mouse pointer to last
+   letter of the text and release the button.  This will start Visual mode and
+   highlight the selected area.
+2. Press "y" to yank the Visual text in the unnamed register.
+3. Click the left mouse button at the insert position.
+4. Click the middle mouse button.
+
+Shortcut: If the insert position is on the screen at the same time as the
+Visual text, you can do 2, 3 and 4 all in one: Click the middle mouse button
+at the insert position.
+
+Note: When the |-X| command line argument is used, Vim will not connect to the
+X server and copy/paste to the X clipboard (selection) will not work.  Use the
+shift key with the mouse buttons to let the xterm do the selection.
+
+							*xterm-command-server*
+When the X-server clipboard is available, the command server described in
+|x11-clientserver| can be enabled with the --servername command line argument.
+
+							*xterm-copy-paste*
+NOTE: In some (older) xterms, it's not possible to move the cursor past column
+95.  This is an xterm problem, not Vim's.  Get a newer xterm |color-xterm|.
+
+Copy/paste in xterm with (current mode NOT included in 'mouse'):
+1. Press left mouse button on first letter of text, move mouse pointer to last
+   letter of the text and release the button.
+2. Use normal Vim commands to put the cursor at the insert position.
+3. Press "a" to start Insert mode.
+4. Click the middle mouse button.
+5. Press ESC to end Insert mode.
+(The same can be done with anything in 'mouse' if you keep the shift key
+pressed while using the mouse.)
+
+Note: if you lose the 8th bit when pasting (special characters are translated
+into other characters), you may have to do "stty cs8 -istrip -parenb" in your
+shell before starting Vim.
+
+Thus in an xterm the shift and ctrl keys cannot be used with the mouse.  Mouse
+commands requiring the CTRL modifier can be simulated by typing the "g" key
+before using the mouse:
+	"g<LeftMouse>"	is "<C-LeftMouse>	(jump to tag under mouse click)
+	"g<RightMouse>" is "<C-RightMouse>	("CTRL-T")
+
+					*mouse-mode-table* *mouse-overview*
+A short overview of what the mouse buttons do, when 'mousemodel' is "extend":
+
+Normal Mode:
+event	      position	   selection	  change  action	~
+	       cursor			  window		~
+<LeftMouse>     yes	     end	    yes
+<C-LeftMouse>   yes	     end	    yes	   "CTRL-]" (2)
+<S-LeftMouse>   yes	  no change	    yes	   "*" (2)    *<S-LeftMouse>*
+<LeftDrag>      yes	start or extend (1) no		      *<LeftDrag>*
+<LeftRelease>   yes	start or extend (1) no
+<MiddleMouse>   yes	  if not active     no	   put
+<MiddleMouse>   yes	  if active	    no	   yank and put
+<RightMouse>    yes	start or extend     yes
+<A-RightMouse>  yes start or extend blockw. yes		      *<A-RightMouse>*
+<S-RightMouse>  yes	   no change	    yes	   "#" (2)    *<S-RightMouse>*
+<C-RightMouse>  no	   no change	    no	   "CTRL-T"
+<RightDrag>     yes	    extend	    no		      *<RightDrag>*
+<RightRelease>  yes	    extend	    no		      *<RightRelease>*
+
+Insert or Replace Mode:
+event	      position	   selection	  change  action	~
+	       cursor			  window		~
+<LeftMouse>     yes     (cannot be active)  yes
+<C-LeftMouse>   yes     (cannot be active)  yes	   "CTRL-O^]" (2)
+<S-LeftMouse>   yes     (cannot be active)  yes	   "CTRL-O*" (2)
+<LeftDrag>      yes     start or extend (1) no	   like CTRL-O (1)
+<LeftRelease>   yes     start or extend (1) no	   like CTRL-O (1)
+<MiddleMouse>   no      (cannot be active)  no	   put register
+<RightMouse>    yes     start or extend	    yes	   like CTRL-O
+<A-RightMouse>  yes start or extend blockw. yes
+<S-RightMouse>  yes     (cannot be active)  yes	   "CTRL-O#" (2)
+<C-RightMouse>  no	(cannot be active)  no	   "CTRL-O CTRL-T"
+
+In a help window:
+event	      position	   selection	  change  action	~
+	       cursor			  window		~
+<2-LeftMouse>   yes     (cannot be active)  no	   "^]" (jump to help tag)
+
+When 'mousemodel' is "popup", these are different:
+
+Normal Mode:
+event	      position	   selection	  change  action	~
+	       cursor			  window		~
+<S-LeftMouse>	yes	start or extend (1) no
+<A-LeftMouse>   yes start or extend blockw. no		      *<A-LeftMouse>*
+<RightMouse>	no	popup menu	    no
+
+Insert or Replace Mode:
+event	      position	   selection	  change  action	~
+	       cursor			  window		~
+<S-LeftMouse>   yes     start or extend (1) no	   like CTRL-O (1)
+<A-LeftMouse>   yes start or extend blockw. no
+<RightMouse>    no	popup menu	    no
+
+(1) only if mouse pointer moved since press
+(2) only if click is in same buffer
+
+Clicking the left mouse button causes the cursor to be positioned.  If the
+click is in another window that window is made the active window.  When
+editing the command-line the cursor can only be positioned on the
+command-line.  When in Insert mode Vim remains in Insert mode.  If 'scrolloff'
+is set, and the cursor is positioned within 'scrolloff' lines from the window
+border, the text is scrolled.
+
+A selection can be started by pressing the left mouse button on the first
+character, moving the mouse to the last character, then releasing the mouse
+button.  You will not always see the selection until you release the button,
+only in some versions (GUI, MS-DOS, WIN32) will the dragging be shown
+immediately.  Note that you can make the text scroll by moving the mouse at
+least one character in the first/last line in the window when 'scrolloff' is
+non-zero.
+
+In Normal, Visual and Select mode clicking the right mouse button causes the
+Visual area to be extended.  When 'mousemodel' is "popup", the left button has
+to be used while keeping the shift key pressed.  When clicking in a window
+which is editing another buffer, the Visual or Select mode is stopped.
+
+In Normal, Visual and Select mode clicking the right mouse button with the alt
+key pressed causes the Visual area to become blockwise.  When 'mousemodel' is
+"popup" the left button has to be used with the alt key.  Note that this won't
+work on systems where the window manager consumes the mouse events when the
+alt key is pressed (it may move the window).
+
+							*double-click*
+Double, triple and quadruple clicks are supported when the GUI is active,
+for MS-DOS and Win32, and for an xterm (if the gettimeofday() function is
+available).  For selecting text, extra clicks extend the selection:
+	click		select ~
+	double		word or % match		*<2-LeftMouse>*
+	triple		line			*<3-LeftMouse>*
+	quadruple	rectangular block	*<4-LeftMouse>*
+Exception: In a Help window a double click jumps to help for the word that is
+clicked on.
+A double click on a word selects that word.  'iskeyword' is used to specify
+which characters are included in a word.  A double click on a character
+that has a match selects until that match (like using "v%").  If the match is
+an #if/#else/#endif block, the selection becomes linewise.
+For MS-DOS and xterm the time for double clicking can be set with the
+'mousetime' option.  For the other systems this time is defined outside of
+Vim.
+An example, for using a double click to jump to the tag under the cursor: >
+	:map <2-LeftMouse> :exe "tag ". expand("<cword>")<CR>
+
+Dragging the mouse with a double click (button-down, button-up, button-down
+and then drag) will result in whole words to be selected.  This continues
+until the button is released, at which point the selection is per character
+again.
+
+							*gpm-mouse*
+The GPM mouse is only supported when the |+mouse_gpm| feature was enabled at
+compile time.  The GPM mouse driver (Linux console) does not support quadruple
+clicks.
+
+In Insert mode, when a selection is started, Vim goes into Normal mode
+temporarily.  When Visual or Select mode ends, it returns to Insert mode.
+This is like using CTRL-O in Insert mode.  Select mode is used when the
+'selectmode' option contains "mouse".
+
+							*drag-status-line*
+When working with several windows, the size of the windows can be changed by
+dragging the status line with the mouse.  Point the mouse at a status line,
+press the left button, move the mouse to the new position of the status line,
+release the button.  Just clicking the mouse in a status line makes that window
+the current window, without moving the cursor.  If by selecting a window it
+will change position or size, the dragging of the status line will look
+confusing, but it will work (just try it).
+
+					*<MiddleRelease>* *<MiddleDrag>*
+Mouse clicks can be mapped.  The codes for mouse clicks are:
+     code	    mouse button	      normal action	~
+ <LeftMouse>	 left pressed		    set cursor position
+ <LeftDrag>	 left moved while pressed   extend selection
+ <LeftRelease>	 left released		    set selection end
+ <MiddleMouse>	 middle pressed		    paste text at cursor position
+ <MiddleDrag>	 middle moved while pressed -
+ <MiddleRelease> middle released	    -
+ <RightMouse>	 right pressed		    extend selection
+ <RightDrag>	 right moved while pressed  extend selection
+ <RightRelease>  right released		    set selection end
+ <X1Mouse>	 X1 button pressed	    -			*X1Mouse*
+ <X1Drag>	 X1 moved while pressed	    -			*X1Drag*
+ <X1Release>	 X1 button release	    -			*X1Release*
+ <X2Mouse>	 X2 button pressed	    -			*X2Mouse*
+ <X2Drag>	 X2 moved while pressed     -			*X2Drag*
+ <X2Release>	 X2 button release	    -			*X2Release*
+
+The X1 and X2 buttons refer to the extra buttons found on some mice.  The
+'Microsoft Explorer' mouse has these buttons available to the right thumb.
+Currently X1 and X2 only work on Win32 environments.
+
+Examples: >
+	:noremap <MiddleMouse> <LeftMouse><MiddleMouse>
+Paste at the position of the middle mouse button click (otherwise the paste
+would be done at the cursor position). >
+
+	:noremap <LeftRelease> <LeftRelease>y
+Immediately yank the selection, when using Visual mode.
+
+Note the use of ":noremap" instead of "map" to avoid a recursive mapping.
+>
+	:map <X1Mouse> <C-O>
+	:map <X2Mouse> <C-I>
+Map the X1 and X2 buttons to go forwards and backwards in the jump list, see
+|CTRL-O| and |CTRL-I|.
+
+						*mouse-swap-buttons*
+To swap the meaning of the left and right mouse buttons: >
+	:noremap	<LeftMouse>	<RightMouse>
+	:noremap	<LeftDrag>	<RightDrag>
+	:noremap	<LeftRelease>	<RightRelease>
+	:noremap	<RightMouse>	<LeftMouse>
+	:noremap	<RightDrag>	<LeftDrag>
+	:noremap	<RightRelease>	<LeftRelease>
+	:noremap	g<LeftMouse>	<C-RightMouse>
+	:noremap	g<RightMouse>	<C-LeftMouse>
+	:noremap!	<LeftMouse>	<RightMouse>
+	:noremap!	<LeftDrag>	<RightDrag>
+	:noremap!	<LeftRelease>	<RightRelease>
+	:noremap!	<RightMouse>	<LeftMouse>
+	:noremap!	<RightDrag>	<LeftDrag>
+	:noremap!	<RightRelease>	<LeftRelease>
+<
+ vim:tw=78:ts=8:ft=help:norl:
--- /dev/null
+++ b/lib/vimfiles/doc/tips.txt
@@ -1,0 +1,508 @@
+*tips.txt*      For Vim version 7.1.  Last change: 2006 Jul 24
+
+
+		  VIM REFERENCE MANUAL    by Bram Moolenaar
+
+
+Tips and ideas for using Vim				*tips*
+
+Don't forget to browse the user manual, it also contains lots of useful tips
+|usr_toc.txt|.
+
+Editing C programs				|C-editing|
+Finding where identifiers are used		|ident-search|
+Switching screens in an xterm			|xterm-screens|
+Scrolling in Insert mode			|scroll-insert|
+Smooth scrolling				|scroll-smooth|
+Correcting common typing mistakes		|type-mistakes|
+Counting words, lines, etc.			|count-items|
+Restoring the cursor position			|restore-position|
+Renaming files					|rename-files|
+Speeding up external commands			|speed-up|
+Useful mappings					|useful-mappings|
+Compressing the help files			|gzip-helpfile|
+Hex editing					|hex-editing|
+Executing shell commands in a window		|shell-window|
+Using <> notation in autocommands		|autocmd-<>|
+Highlighting matching parens			|match-parens|
+
+==============================================================================
+Editing C programs					*C-editing*
+
+There are quite a few features in Vim to help you edit C program files.  Here
+is an overview with tags to jump to:
+
+|usr_29.txt|		Moving through programs chapter in the user manual.
+|usr_30.txt|		Editing programs chapter in the user manual.
+|C-indenting|		Automatically set the indent of a line while typing
+			text.
+|=|			Re-indent a few lines.
+|format-comments|	Format comments.
+
+|:checkpath|		Show all recursively included files.
+|[i|			Search for identifier under cursor in current and
+			included files.
+|[_CTRL-I|		Jump to match for "[i"
+|[I|			List all lines in current and included files where
+			identifier under the cursor matches.
+|[d|			Search for define under cursor in current and included
+			files.
+
+|CTRL-]|		Jump to tag under cursor (e.g., definition of a
+			function).
+|CTRL-T|		Jump back to before a CTRL-] command.
+|:tselect|		Select one tag out of a list of matching tags.
+
+|gd|			Go to Declaration of local variable under cursor.
+|gD|			Go to Declaration of global variable under cursor.
+
+|gf|			Go to file name under the cursor.
+
+|%|			Go to matching (), {}, [], /* */, #if, #else, #endif.
+|[/|			Go to previous start of comment.
+|]/|			Go to next end of comment.
+|[#|			Go back to unclosed #if, #ifdef, or #else.
+|]#|			Go forward to unclosed #else or #endif.
+|[(|			Go back to unclosed '('
+|])|			Go forward to unclosed ')'
+|[{|			Go back to unclosed '{'
+|]}|			Go forward to unclosed '}'
+
+|v_ab|			Select "a block" from "[(" to "])", including braces
+|v_ib|			Select "inner block" from "[(" to "])"
+|v_aB|			Select "a block" from "[{" to "]}", including brackets
+|v_iB|			Select "inner block" from "[{" to "]}"
+
+==============================================================================
+Finding where identifiers are used			*ident-search*
+
+You probably already know that |tags| can be used to jump to the place where a
+function or variable is defined.  But sometimes you wish you could jump to all
+the places where a function or variable is being used.  This is possible in
+two ways:
+1. Using the |:grep| command.  This should work on most Unix systems,
+   but can be slow (it reads all files) and only searches in one directory.
+2. Using ID utils.  This is fast and works in multiple directories.  It uses a
+   database to store locations.  You will need some additional programs for
+   this to work.  And you need to keep the database up to date.
+
+Using the GNU id-tools:
+
+What you need:
+- The GNU id-tools installed (mkid is needed to create ID and lid is needed to
+  use the macros).
+- An identifier database file called "ID" in the current directory.  You can
+  create it with the shell command "mkid file1 file2 ..".
+
+Put this in your .vimrc: >
+	map _u :call ID_search()<Bar>execute "/\\<" . g:word . "\\>"<CR>
+	map _n :n<Bar>execute "/\\<" . g:word . "\\>"<CR>
+
+	function! ID_search()
+	  let g:word = expand("<cword>")
+	  let x = system("lid --key=none ". g:word)
+	  let x = substitute(x, "\n", " ", "g")
+	  execute "next " . x
+	endfun
+
+To use it, place the cursor on a word, type "_u" and vim will load the file
+that contains the word.  Search for the next occurrence of the word in the
+same file with "n".  Go to the next file with "_n".
+
+This has been tested with id-utils-3.2 (which is the name of the id-tools
+archive file on your closest gnu-ftp-mirror).
+
+[the idea for this comes from Andreas Kutschera]
+
+==============================================================================
+Switching screens in an xterm		*xterm-screens* *xterm-save-screen*
+
+(From comp.editors, by Juergen Weigert, in reply to a question)
+
+:> Another question is that after exiting vim, the screen is left as it
+:> was, i.e. the contents of the file I was viewing (editing) was left on
+:> the screen. The output from my previous like "ls" were lost,
+:> ie. no longer in the scrolling buffer. I know that there is a way to
+:> restore the screen after exiting vim or other vi like editors,
+:> I just don't know how. Helps are appreciated. Thanks.
+:
+:I imagine someone else can answer this.  I assume though that vim and vi do
+:the same thing as each other for a given xterm setup.
+
+They not necessarily do the same thing, as this may be a termcap vs.
+terminfo problem.  You should be aware that there are two databases for
+describing attributes of a particular type of terminal: termcap and
+terminfo.  This can cause differences when the entries differ AND when of
+the programs in question one uses terminfo and the other uses termcap
+(also see |+terminfo|).
+
+In your particular problem, you are looking for the control sequences
+^[[?47h and ^[[?47l.  These switch between xterms alternate and main screen
+buffer.  As a quick workaround a command sequence like >
+	echo -n "^[[?47h"; vim ... ; echo -n "^[[?47l"
+may do what you want.  (My notation ^[ means the ESC character, further down
+you'll see that the databases use \E instead).
+
+On startup, vim echoes the value of the termcap variable ti (terminfo:
+smcup) to the terminal.  When exiting, it echoes te (terminfo: rmcup).  Thus
+these two variables are the correct place where the above mentioned control
+sequences should go.
+
+Compare your xterm termcap entry (found in /etc/termcap) with your xterm
+terminfo entry (retrieved with "infocmp -C xterm").  Both should contain
+entries similar to: >
+	:te=\E[2J\E[?47l\E8:ti=\E7\E[?47h:
+
+PS: If you find any difference, someone (your sysadmin?) should better check
+    the complete termcap and terminfo database for consistency.
+
+NOTE 1: If you recompile Vim with FEAT_XTERM_SAVE defined in feature.h, the
+builtin xterm will include the mentioned "te" and "ti" entries.
+
+NOTE 2: If you want to disable the screen switching, and you don't want to
+change your termcap, you can add these lines to your .vimrc: >
+	:set t_ti= t_te=
+
+==============================================================================
+Scrolling in Insert mode				*scroll-insert*
+
+If you are in insert mode and you want to see something that is just off the
+screen, you can use CTRL-X CTRL-E and CTRL-X CTRL-Y to scroll the screen.
+						|i_CTRL-X_CTRL-E|
+
+To make this easier, you could use these mappings: >
+	:inoremap <C-E> <C-X><C-E>
+	:inoremap <C-Y> <C-X><C-Y>
+(Type this literally, make sure the '<' flag is not in 'cpoptions').
+You then lose the ability to copy text from the line above/below the cursor
+|i_CTRL-E|.
+
+Also consider setting 'scrolloff' to a larger value, so that you can always see
+some context around the cursor.  If 'scrolloff' is bigger than half the window
+height, the cursor will always be in the middle and the text is scrolled when
+the cursor is moved up/down.
+
+==============================================================================
+Smooth scrolling					*scroll-smooth*
+
+If you like the scrolling to go a bit smoother, you can use these mappings: >
+	:map <C-U> <C-Y><C-Y><C-Y><C-Y><C-Y><C-Y><C-Y><C-Y><C-Y><C-Y><C-Y><C-Y><C-Y><C-Y><C-Y><C-Y>
+	:map <C-D> <C-E><C-E><C-E><C-E><C-E><C-E><C-E><C-E><C-E><C-E><C-E><C-E><C-E><C-E><C-E><C-E>
+
+(Type this literally, make sure the '<' flag is not in 'cpoptions').
+
+==============================================================================
+Correcting common typing mistakes			*type-mistakes*
+
+When there are a few words that you keep on typing in the wrong way, make
+abbreviations that correct them.  For example: >
+	:ab teh the
+	:ab fro for
+
+==============================================================================
+Counting words, lines, etc.				*count-items*
+
+To count how often any pattern occurs in the current buffer use the substitute
+command and add the 'n' flag to avoid the substitution.  The reported number
+of substitutions is the number of items.  Examples: >
+
+	:%s/./&/gn		characters
+	:%s/\i\+/&/gn		words
+	:%s/^//n		lines
+	:%s/the/&/gn		"the" anywhere
+	:%s/\<the\>/&/gn	"the" as a word
+
+You might want to reset 'hlsearch' or do ":nohlsearch".
+Add the 'e' flag if you don't want an error when there are no matches.
+
+An alternative is using |v_g_CTRL-G| in Visual mode.
+
+If you want to find matches in multiple files use |:vimgrep|.
+
+							*count-bytes*
+If you want to count bytes, you can use this:
+
+	Visually select the characters (block is also possible)
+	Use "y" to yank the characters
+	Use the strlen() function: >
+		:echo strlen(@")
+A line break is counted for one byte.
+
+==============================================================================
+Restoring the cursor position				*restore-position*
+
+Sometimes you want to write a mapping that makes a change somewhere in the
+file and restores the cursor position, without scrolling the text.  For
+example, to change the date mark in a file: >
+   :map <F2> msHmtgg/Last [cC]hange:\s*/e+1<CR>"_D"=strftime("%Y %b %d")<CR>p'tzt`s
+
+Breaking up saving the position:
+	ms	store cursor position in the 's' mark
+	H	go to the first line in the window
+	mt	store this position in the 't' mark
+
+Breaking up restoring the position:
+	't	go to the line previously at the top of the window
+	zt	scroll to move this line to the top of the window
+	`s	jump to the original position of the cursor
+
+==============================================================================
+Renaming files						*rename-files*
+
+Say I have a directory with the following files in them (directory picked at
+random :-):
+
+buffer.c
+charset.c
+digraph.c
+...
+
+and I want to rename *.c *.bla.  I'd do it like this: >
+
+	$ vim
+	:r !ls *.c
+	:%s/\(.*\).c/mv & \1.bla
+	:w !sh
+	:q!
+
+==============================================================================
+Speeding up external commands				*speed-up*
+
+In some situations, execution of an external command can be very slow.  This
+can also slow down wildcard expansion on Unix.  Here are a few suggestions to
+increase the speed.
+
+If your .cshrc (or other file, depending on the shell used) is very long, you
+should separate it into a section for interactive use and a section for
+non-interactive use (often called secondary shells).  When you execute a
+command from Vim like ":!ls", you do not need the interactive things (for
+example, setting the prompt).  Put the stuff that is not needed after these
+lines: >
+
+	if ($?prompt == 0) then
+		exit 0
+	endif
+
+Another way is to include the "-f" flag in the 'shell' option, e.g.: >
+
+	:set shell=csh\ -f
+
+(the backslash is needed to include the space in the option).
+This will make csh completely skip the use of the .cshrc file.  This may cause
+some things to stop working though.
+
+==============================================================================
+Useful mappings						*useful-mappings*
+
+Here are a few mappings that some people like to use.
+
+							*map-backtick*  >
+	:map ' `
+Make the single quote work like a backtick.  Puts the cursor on the column of
+a mark, instead of going to the first non-blank character in the line.
+
+							*emacs-keys*
+For Emacs-style editing on the command-line: >
+	" start of line
+	:cnoremap <C-A>		<Home>
+	" back one character
+	:cnoremap <C-B>		<Left>
+	" delete character under cursor
+	:cnoremap <C-D>		<Del>
+	" end of line
+	:cnoremap <C-E>		<End>
+	" forward one character
+	:cnoremap <C-F>		<Right>
+	" recall newer command-line
+	:cnoremap <C-N>		<Down>
+	" recall previous (older) command-line
+	:cnoremap <C-P>		<Up>
+	" back one word
+	:cnoremap <Esc><C-B>	<S-Left>
+	" forward one word
+	:cnoremap <Esc><C-F>	<S-Right>
+
+NOTE: This requires that the '<' flag is excluded from 'cpoptions'. |<>|
+
+							*format-bullet-list*
+This mapping will format any bullet list.  It requires that there is an empty
+line above and below each list entry.  The expression commands are used to
+be able to give comments to the parts of the mapping. >
+
+	:let m =     ":map _f  :set ai<CR>"    " need 'autoindent' set
+	:let m = m . "{O<Esc>"		      " add empty line above item
+	:let m = m . "}{)^W"		      " move to text after bullet
+	:let m = m . "i     <CR>     <Esc>"    " add space for indent
+	:let m = m . "gq}"		      " format text after the bullet
+	:let m = m . "{dd"		      " remove the empty line
+	:let m = m . "5lDJ"		      " put text after bullet
+	:execute m			      |" define the mapping
+
+(<> notation |<>|.  Note that this is all typed literally.  ^W is "^" "W", not
+CTRL-W.  You can copy/paste this into Vim if '<' is not included in
+'cpoptions'.)
+
+Note that the last comment starts with |", because the ":execute" command
+doesn't accept a comment directly.
+
+You also need to set 'textwidth' to a non-zero value, e.g., >
+	:set tw=70
+
+A mapping that does about the same, but takes the indent for the list from the
+first line (Note: this mapping is a single long line with a lot of spaces): >
+	:map _f :set ai<CR>}{a                                                          <Esc>WWmmkD`mi<CR><Esc>kkddpJgq}'mJO<Esc>j
+<
+							*collapse*
+These two mappings reduce a sequence of empty (;b) or blank (;n) lines into a
+single line >
+    :map ;b   GoZ<Esc>:g/^$/.,/./-j<CR>Gdd
+    :map ;n   GoZ<Esc>:g/^[ <Tab>]*$/.,/[^ <Tab>]/-j<CR>Gdd
+
+==============================================================================
+Compressing the help files				*gzip-helpfile*
+
+For those of you who are really short on disk space, you can compress the help
+files and still be able to view them with Vim.  This makes accessing the help
+files a bit slower and requires the "gzip" program.
+
+(1) Compress all the help files: "gzip doc/*.txt".
+
+(2) Edit "doc/tags" and change the ".txt" to ".txt.gz": >
+	:%s=\(\t.*\.txt\)\t=\1.gz\t=
+
+(3) Add this line to your vimrc: >
+	set helpfile={dirname}/help.txt.gz
+
+Where {dirname} is the directory where the help files are.  The |gzip| plugin
+will take care of decompressing the files.
+You must make sure that $VIMRUNTIME is set to where the other Vim files are,
+when they are not in the same location as the compressed "doc" directory.  See
+|$VIMRUNTIME|.
+
+==============================================================================
+Executing shell commands in a window			*shell-window*
+
+There have been questions for the possibility to execute a shell in a window
+inside Vim.  The answer: you can't!  Including this would add a lot of code to
+Vim, which is a good reason not to do this.  After all, Vim is an editor, it
+is not supposed to do non-editing tasks.  However, to get something like this,
+you might try splitting your terminal screen or display window with the
+"splitvt" program.  You can probably find it on some ftp server.  The person
+that knows more about this is Sam Lantinga <slouken@cs.ucdavis.edu>.
+An alternative is the "window" command, found on BSD Unix systems, which
+supports multiple overlapped windows.  Or the "screen" program, found at
+www.uni-erlangen.de, which supports a stack of windows.
+
+==============================================================================
+Hex editing					*hex-editing* *using-xxd*
+
+See section |23.4| of the user manual.
+
+If one has a particular extension that one uses for binary files (such as exe,
+bin, etc), you may find it helpful to automate the process with the following
+bit of autocmds for your <.vimrc>.  Change that "*.bin" to whatever
+comma-separated list of extension(s) you find yourself wanting to edit: >
+
+	" vim -b : edit binary using xxd-format!
+	augroup Binary
+	  au!
+	  au BufReadPre  *.bin let &bin=1
+	  au BufReadPost *.bin if &bin | %!xxd
+	  au BufReadPost *.bin set ft=xxd | endif
+	  au BufWritePre *.bin if &bin | %!xxd -r
+	  au BufWritePre *.bin endif
+	  au BufWritePost *.bin if &bin | %!xxd
+	  au BufWritePost *.bin set nomod | endif
+	augroup END
+
+==============================================================================
+Using <> notation in autocommands			*autocmd-<>*
+
+The <> notation is not recognized in the argument of an :autocmd.  To avoid
+having to use special characters, you could use a self-destroying mapping to
+get the <> notation and then call the mapping from the autocmd.  Example:
+
+						*map-self-destroy*  >
+ " This is for automatically adding the name of the file to the menu list.
+ " It uses a self-destroying mapping!
+ " 1. use a line in the buffer to convert the 'dots' in the file name to \.
+ " 2. store that in register '"'
+ " 3. add that name to the Buffers menu list
+ " WARNING: this does have some side effects, like overwriting the
+ " current register contents and removing any mapping for the "i" command.
+ "
+ autocmd BufNewFile,BufReadPre * nmap i :nunmap i<CR>O<C-R>%<Esc>:.g/\./s/\./\\./g<CR>0"9y$u:menu Buffers.<C-R>9 :buffer <C-R>%<C-V><CR><CR>
+ autocmd BufNewFile,BufReadPre * normal i
+
+Another method, perhaps better, is to use the ":execute" command.  In the
+string you can use the <> notation by preceding it with a backslash.  Don't
+forget to double the number of existing backslashes and put a backslash before
+'"'.
+>
+  autocmd BufNewFile,BufReadPre * exe "normal O\<C-R>%\<Esc>:.g/\\./s/\\./\\\\./g\<CR>0\"9y$u:menu Buffers.\<C-R>9 :buffer \<C-R>%\<C-V>\<CR>\<CR>"
+
+For a real buffer menu, user functions should be used (see |:function|), but
+then the <> notation isn't used, which defeats using it as an example here.
+
+==============================================================================
+Highlighting matching parens					*match-parens*
+
+This example shows the use of a few advanced tricks:
+- using the |CursorMoved| autocommand event
+- using |searchpairpos()| to find a matching paren
+- using |synID()| to detect whether the cursor is in a string or comment
+- using |:match| to highlight something
+- using a |pattern| to match a specific position in the file.
+
+This should be put in a Vim script file, since it uses script-local variables.
+It skips matches in strings or comments, unless the cursor started in string
+or comment.  This requires syntax highlighting.
+
+A slightly more advanced version is used in the |matchparen| plugin.
+>
+	let s:paren_hl_on = 0
+	function s:Highlight_Matching_Paren()
+	  if s:paren_hl_on
+	    match none
+	    let s:paren_hl_on = 0
+	  endif
+
+	  let c_lnum = line('.')
+	  let c_col = col('.')
+
+	  let c = getline(c_lnum)[c_col - 1]
+	  let plist = split(&matchpairs, ':\|,')
+	  let i = index(plist, c)
+	  if i < 0
+	    return
+	  endif
+	  if i % 2 == 0
+	    let s_flags = 'nW'
+	    let c2 = plist[i + 1]
+	  else
+	    let s_flags = 'nbW'
+	    let c2 = c
+	    let c = plist[i - 1]
+	  endif
+	  if c == '['
+	    let c = '\['
+	    let c2 = '\]'
+	  endif
+	  let s_skip ='synIDattr(synID(line("."), col("."), 0), "name") ' .
+		\ '=~?	"string\\|comment"'
+	  execute 'if' s_skip '| let s_skip = 0 | endif'
+
+	  let [m_lnum, m_col] = searchpairpos(c, '', c2, s_flags, s_skip)
+
+	  if m_lnum > 0 && m_lnum >= line('w0') && m_lnum <= line('w$')
+	    exe 'match Search /\(\%' . c_lnum . 'l\%' . c_col .
+		  \ 'c\)\|\(\%' . m_lnum . 'l\%' . m_col . 'c\)/'
+	    let s:paren_hl_on = 1
+	  endif
+	endfunction
+
+	autocmd CursorMoved,CursorMovedI * call s:Highlight_Matching_Paren()
+	autocmd InsertEnter * match none
+<
+
+ vim:tw=78:ts=8:ft=help:norl:
--- /dev/null
+++ b/lib/vimfiles/doc/todo.txt
@@ -1,0 +1,4054 @@
+*todo.txt*      For Vim version 7.1.  Last change: 2007 May 12
+
+
+		  VIM REFERENCE MANUAL	  by Bram Moolenaar
+
+
+			      TODO list for Vim		*todo*
+
+This is a veeeery long list of known bugs, current work and desired
+improvements.  To make it a little bit accessible, the items are grouped by
+subject.  In the first column of the line a classification is used to be able
+to look for "the next thing to do":
+
+Priority classification:
+9   next point release
+8   next release
+7   as soon as possible
+6   soon
+5   should be included
+4   nice to have
+3   consider including
+2   maybe not
+1   probably not
+-   unclassified
+
+						    *votes-for-changes*
+See |develop.txt| for development plans.  You can vote for which items should
+be worked on, but only if you sponsor Vim development.  See |sponsor|.
+
+							*known-bugs*
+-------------------- Known bugs and current work -----------------------
+
+Patch to make virtcol([123, '$']) do the right thing. (Michael Schaap)
+
+Insert mode completion: CTRL-N and CTRL-P work differently and they both don't
+work as expected. (Bernhard Walle, 2007 Feb 27)
+
+When 'rightleft' is set the completion menu is positioned wrong. (Baha-Eddine
+MOKADEM)
+
+glob() doesn't work correctly with single quotes and 'shell' set to /bin/sh.
+(Adri Verhoef, Charles Campbell 2007 Mar 26)
+
+Splitting quickfix window messes up window layout. (Marius Gedminas, 2007 Apr
+25)
+
+Replace ccomplete.vim by cppcomplete.vim from www.vim.org?  script 1520
+(Martin Stubenschrott)
+    ctags -R --c++-kinds=+p --fields=+iaS --extra=+q .
+
+Making the German sharp s uppercase doesn't work properly: one character less
+is uppercased in "gUe".
+Also: latin2 has the same character but it isn't uppercased there.
+
+Mac: After a ":vsplit" the left scrollbar doesn't appear until 'columns' is
+changed or the window is resized.
+
+Mac: Patch for Mac GUI tabline. (Nicolas Weber, 2006 Jul 18, Update 2007 Feb)
+    New update v6 ~/tmp/guitab.v6.diff (Kyle Wheeler)
+
+When 'virtualedit' is set a "p" of a block just past the end of the line
+inserts before the cursor. (Engelke)
+
+Using Aap to build Vim: add remarks about how to set personal preferences.
+Example on http://www.calmar.ws/tmp/aap.html
+
+GTK: 'bsdir' doesn't work.  Sometimes get a "gtk critical error".
+Moved some code to append file name to further down in gui_gtk.c
+gui_mch_browse(), but "last" value of 'bsdir' still doesn't work.
+
+C syntax: "#define x {"  The macro should terminate at the end of the line,
+not continue in the next line. (Kelvin Lee, 2006 May 24)
+
+C syntax: {} inside () causes following {} to be highlighted as error.
+(Michalis Giannakidis, 2006 Jun 1)
+
+Gnome improvements: Edward Catmur, 2007 Jan 7
+    Also use Save/Discard for other GUIs
+
+New PHP syntax file, use it? (Peter Hodge)
+
+'foldcolumn' in modeline applied to wrong window when using a session. (Teemu
+Likonen, March 19)
+
+Syntax highlighting wrong for transparent region. (Doug Kearns, 2007 Feb 26)
+
+More AmigaOS4 patches. (Peter Bengtsson, Nov 9)
+
+Add v:searchforward variable.  Patch by Yakov Lerner, 2006 Nov 18.
+
+Redraw problem in loop. (Yakov Lerner, 2006 Sep 7)
+
+Add option settings to help ftplugin. (David Eggum, 2006 Dec 18)
+
+Use new dutch wordlist for spelling?  http://www.opentaal.org/
+See remarks from Adri, 2007 Feb 9.
+
+When opening quickfix window, disable spell checking?
+
+Windows 98: pasting from the clipboard with text from another application has
+a trailing NUL.  (Joachim Hofmann)  Perhaps the length specified for CF_TEXT
+isn't right?
+
+Win32: When 'encoding' is "latin1" 'ignorecase' doesn't work for characters
+with umlaut. (Joachim Hofmann)  toupper_tab[] and tolower_tab[] are not filled
+properly?
+
+Completion: Scanning for tags doesn't check for typed key now and then?
+Hangs for about 5 seconds.  Appears to be caused by finding include files with
+"foo/**" in 'path'.  (Kalisiak, 2006 July 15)
+
+Completion: When 'completeopt' has "longest" and there is one match the
+message is "back at original" and typing a char doesn't leave completion mode.
+(Igor Prischepoff, 2006 Oct 5)
+
+Completion: When using CTRL-X O and there is only "struct." before the cursor,
+typing one char to reduce the matches, then BS completion stops.  Should keep
+completion if still no less than what we started with.
+
+Completion: don't stop completion when typing a space when completing full
+lines?  Also when completing file names?  Only stop completion when there are
+no matches?
+After using BS completion only stops when typing a space.  Many people want to
+stop at non-word characters, e.g., '('.  Add an option for this?  Or check
+vim_iswordc() before calling ins_compl_addleader()?
+
+searchpos() doesn't use match under cursor at start of line. (Viktor
+Kojouharov, 2006 Nov 16)
+
+When FEAT_BYTEOFF is defined but FEAT_NETBEANS_INTG is not compiling fails.
+Add FEAT_BYTEOFF to the check at line 1180 in feature.h
+
+Color for cUserLabel should differ from case label, so that a mistake in a
+switch list is noticed:
+    switch (i)
+    {
+    case 1:
+    foobar:
+    }
+
+":s" command removes combining characters. (Ron Aaron, 2006 May 17, 2006 Dec 7)
+
+Look at http://www.gtk-server.org/ .  It has a Vim script implementation.
+
+Changes for Win32 makefile. (Mike Williams, 2007 Jan 22, Alexei Alexandrov,
+2007 Feb 8)
+
+Patch for Win32 clipboard under Cygwin. (Frodak Baksik, Feb 15)
+    Sutcliffe says it works well.
+
+Win32: Patch for convert_filterW(). (Taro Muraoka, 2007 Mar 2)
+
+Win32: XPM support only works with path without spaces.  Patch by Mathias
+Michaelis, 2006 Jun 9.  Another patch for more path names, 2006 May 31.
+New version: http://members.tcnet.ch/michaelis/vim/patches.zip (also for other
+patches by Mathias, see mail Feb 22)
+
+Win32: compiling with normal features and OLE fails.  Patch by Mathias
+Michaelis, 2006 Jun 4.
+
+Win32: echo doesn't work for gvim.exe.mnf.  Use inline file.  Patch by Mathias
+Michaelis.  http://groups.yahoo.com/group/vimdev/message/43765
+Patch that includes this and does more by George Reilly, 2007 Feb 12
+
+Win16: include patches to make Win16 version work. (Vince Negri, 2006 May 22)
+
+Win32: after "[I" showing matches, scroll wheel messes up screen. (Tsakiridis,
+2007 Feb 18)
+
+Win32: using CTRL-S in Insert mode doesn't remove the "+" from the tab pages
+label.  (Tsakiridis, 2007 Feb 18)
+
+Win32: remote editing doesn't work when the current directory name contains
+"[]". (Ivan Tishchenko, 2007 March 1)
+
+Win64: diff.exe crashes on Win64. (Julianne Bailey, 2006 Dec 12)
+Build another diff.exe somehow?
+
+Win64: Seek error in swap file for a very big file (3 Gbyte).  Check storing
+pointer in long and seek offset in 64 bit var.
+
+When doing "gvim --remote-tab foo" while gvim is minimized the tab pages line
+only shows the current label, not the others.
+
+Problem finding swap file for recovery. (Gautam Iyer, 2006 May 16)
+
+When setting 'keymap' twice the b:keymap_name variable isn't set. (Milan
+Berta, 2007 Mar 9)  Has something to do with 'iminsert'.
+
+Problem with CursorHoldI?  (Max Dyckhoff, 2006 Nov 10)
+
+UTF-8: mapping a multi-byte key where the second byte is 0x80 doesn't appear
+to work. (Tony Mechelynck, 2007 March 2)
+
+The str2special() function doesn't handle multi-byte characters properly.
+Patch from Vladimir Vichniakov, 2007 Apr 24.
+find_special_key() also has this problem.
+
+In debug mode, using CTRL-R = to evaluate a function causes stepping through
+the function. (Hari Krishna Dara, 2006 Jun 28)
+
+":let &shiftwidth = 'asdf'" doesn't produce an error message.
+
+C++ indenting wrong with "=". (James Kanze, 2007 Jan 26)
+
+"zug" reports wrong file. problem with Namebuff? (Lawrence Kesteloot, 2006 Sep
+10)
+
+":lockvar" should use copyID to avoid endless loop.
+
+Patch to use xterm mouse codes for screen. (Micah Cowan, 2007 May 8)
+
+Gvim: dialog for closing Vim should check if Vim is busy writing a file.  Then
+use a different dialog: "busy saving, really quit? yes / no".
+
+Win32: editing remote file d:\a[1]\aa.txt doesn't work. (Liu Yubao, 2006 May
+29)
+
+"zw" doesn't appear to work. (Luis A Florit, 2006 Jun 23, 24)
+
+"dw" in a line with one character deletes the line.  Vi and nvi don't do this.
+Is it intentional or not? (Kjell Arne Rekaa)
+
+Check other interfaces for changing curbuf in a wrong way.  Patch like for
+if_ruby.c.
+
+Spell checking in popup menu: If the only problem is the case of the first
+character, don't offer "ignore" and "add to word list".
+
+":helpgrep" should use the directory from 'helpfile'.
+
+The need_fileinfo flag is messy.  Instead make the message right away and put
+it in keep_msg?
+
+More-prompt is skipped when doing this; (Randall W. Morris, Jun 17)
+    :au
+    <Space>
+    b
+    <Space>
+
+Editing a file remotely that matches 'wildignore' results in a "no match"
+error.  Should only happen when there are wildards, not when giving the file
+name literally, and esp. if there is only one name.
+
+When 'expandtab' is set then a Tab copied for 'copyindent' is expanded to
+spaces, even when 'preserveindent' is set. (Alexei Alexandrov, Mar 7)
+
+Test 61 fails sometimes.  This is a timing problem: "sleep 2" sometimes takes
+longer than 2 seconds.
+
+VMS: while editing a file found in complex, Vim will save file into the first
+directory of the path and not to the original location of the file.
+(Zoltan Arpadffy)
+
+input() completion should not insert a backslash to escape a space in a file
+name?
+
+getpos()/setpos() don't include curswant.  getpos() could return a fifth
+element.  setpos() could accept an optional fifth element.
+
+Ruby completion is insecure.  Can this be fixed?
+
+":confirm w" does give a prompt when 'readonly' is set, but not when the file
+permissions are read-only.  Both can be overruled by ":w!" thus it would be
+logical to get a prompt for both. (Michael Schaap)
+
+When 'backupskip' is set from $TEMP special characters need to be escaped.
+(patch by Grembowietz, 2007 Feb 26, not quite right)
+Another problem is that file_pat_to_reg_pat() doesn't recognize "\\", so "\\(" 
+will be seen as a path separator plus "\(".
+
+":python os.chdir('/tmp')" makes short buffer names invalid. (Xavier de Gaye)
+Check directory and call shorten_fnames()?
+
+aucmd_prepbuf() should also use a window in another tab page.
+
+Substituting an area with a line break with almost the same area does change
+the Visual area.  Can this be fixed? (James Vega, 2006 Sept 15)
+
+Windows installer could add a "open in new tab of existing Vim" menu entry.
+
+:s/e/E/l not only lists but also shows line number.  Is that right?
+(Yakov Lerner, 2006 Jul 27)
+
+GUI: When combining fg en bg make sure they are not equal.
+
+Use different pt_br dictionary for spell checking. (Jackson A. Aquino, 2006
+Jun 5)
+
+Mac: Using gvim: netrw window disappears. (Nick Lo, 2006 Jun 21)
+
+When 'bomb' is set or reset the file should be considered modified. (Tony
+Mechelynck)  Handle like 'endofline'.
+
+Add an option to specify the character to use when a double-width character is
+moved to the next line.  Default '>', set to a space to blank it out.  Check
+that char is single width when it's set (compare with 'listchars').
+
+Update main.aap for installing on the Mac.
+
+The generated vim.bat can avoid the loop for NT. (Carl Zmola, 2006 Sep 3)
+
+Session file creation: 'autochdir' causes trouble.  Keep it off until after
+loading all files.
+
+C completion: doesn't work after aa[0]->, where aa is an array of structures.
+(W. de Hoog, 2006 Aug 12)
+
+The spellfile plugin checks for a writable "spell" directory.  A user may have
+a writable runtime directory without a "spell" directory, it could be created
+then.
+
+These two abbreviations don't give the same result:
+	let asdfasdf = "xyz\<Left>"
+	cabbr XXX <C-R>=asdfasdf<CR>
+	cabbr YYY xyz<Left>
+
+Michael Dietrich: maximized gvim sometimes displays output of external command
+partly. (2006 Dec 7)
+
+In FileChangedShell command it's no longer allowed to switch to another
+buffer.  But the changed buffer may differ from the current buffer, how to
+reload it then?
+
+New syntax files for fstab and resolv from Radu Dineiu, David Necas did
+previous version.
+
+For Aap: include a config.arg.example file with hints how to use config.arg.
+
+Linux distributions:
+- Suggest compiling xterm with --enable-tcap-query, so that nr of colors is
+  known to Vim.  88 colors instead of 16 works better.  See ":help
+  xfree-xterm".
+- Suggest including bare "vi" and "vim" with X11, syntax, etc.
+
+Completion menu: For a wrapping line, completing a long file name, only the
+start of the path is shown in the menu.  Should move the menu to the right to
+show more text of the completions.  Shorten the items that don't fit in the
+middle?
+
+When running inside screen it's possible to kill the X server and restart it
+(using pty's the program can keep on running).  Vim dies because it looses the
+connection to the X server.  Can Vim simply quit using the X server instead of
+dying?  Also relevant when running in a console.
+
+Accessing file#var in a function should not need the g: prepended.
+
+When ":cn" moves to an error in the same line the message isn't shortened.
+Only skip shortening for ":cc"?
+
+Win32: The matchparen plugin doesn't update the match when scrolling with the
+mouse wheel. (Ilya Bobir, 2006 Jun 27)
+
+Write "making vim work better" for the docs (mostly pointers): *nice*
+    - sourcing $VIMRUNTIME/vimrc_example.vim
+    - setting 'mouse' to "a"
+    - getting colors in xterm
+    - compiling Vim with X11, GUI, etc.
+
+Problem with ":call" and dictionary function. Hari Krishna Dara, Charles
+Campbell 2006 Jul 06.
+
+Syntax HL error caused by "containedin". (Peter Hodge, 2006 Oct 6)
+
+GTK: When maximizing Vim the result is slightly smaller, the filler border is
+not there, and the "maximize" button is still there.  Clicking it again does
+give a maximized window. (Darren Hiebert)
+Problem is that gui_mch_set_text_area_pos() is invoked to change the text area
+size, which causes the toplevel window to resize.  When doing this while the
+size is already right the filler remains there.
+Detect using the maximize button (GdkWindowState bit
+GDK_WINDOW_STATE_MAXIMIZED) and set it again?
+
+Another resizing problem when setting 'columns' and 'lines' to a very large
+number. (Tony Mechelynck, 2007 Feb 6)
+
+Problem with using :redir in user command completion function? (Hari Krishna
+Dara, 2006 June 21)
+
+After starting Vim, using '0 to jump somewhere in a file, ":sp" doesn't center
+the cursor line.  It works OK after some other commands.
+
+Screen redrawing when continuously updating the buffer and resizing the
+terminal. (Yakov Lerner, 2006 Sept 7)
+
+Win32: Is it possible to have both postscript and Win32 printing?
+Does multi-byte printing with ":hardcopy" work?  Add remark in documentation
+about this.
+
+'thesaurus' doesn't work when 'infercase' is set. (Mohsin, 2006 May 30)
+
+There should be something about spell checking in the user manual.
+
+Check: Running Vim in a console and still having connect to the X server for
+copy/paste: is stopping the X server handled gracefully?  Should catch the X
+error and stop using the connection to the server.
+
+Problem with 'cdpath' on MS-Windows when a directory is equal to $HOME. (2006
+Jul 26, Gary Johnson)
+
+In the Netbeans interface add a "vimeval" function, so that the other side can
+check the result of has("patch13").
+
+":py" asks for an argument, ":py asd" then gives the error that ":py" isn't
+implemented.  Should already happen for ":py".
+
+Add command modifier that skips wildcard expansion, so that you don't need to
+put backslashes before special chars, only for white space.
+
+Win32 GUI: confirm() with zero default should not have a choice selected.
+
+Win32: When the GUI tab pages line is displayed Vim jumps from the secondary
+to the primary monitor. (Afton Lewis, 2007 Mar 9)  Old resizing problem?
+
+GTK GUI: When the completion popup menu is used scrolling another window by
+the scrollbar is OK, but using the scroll wheel it behaves line <Enter>.
+
+"cit" used on <foo></foo> deletes <foo>.  Should not delete anything and start
+insertion, like "ci'" does on "". (Michal Bozon)
+
+Allow more than 3 ":match" items.
+
+The magic clipboard format "VimClipboard2" appears in several places.  Should
+be only one.
+
+It's difficult to debug numbered functions (function in a Dictionary).  Print
+the function name before resolving it to a number?
+	let d = {}
+	fun! d.foo()
+	  echo "here"
+	endfun
+	call d.foo(9)
+
+Add a mark for the other end of the Visual area (VIsual pos).  '< and '> are
+only set after Visual moded is ended.
+
+Small problem displaying diff filler line when opening windows with a script.
+(David Luyer, 2007 Mar 1 ~/Mail/oldmail/mool/in.15872 )
+
+When pattern for ":sort" is empty, use last search pattern.  Allows trying out
+the pattern first. (Brian McKee)
+
+Is it allowed that 'backupext' is empty?  Problems when backup is in same dir
+as original file?  If it's OK don't compare with 'patchmode'. (Thierry Closen)
+
+Patch for supporting count before CR in quickfix window. (AOYAMA Shotaro, 2007
+Jan 1)
+
+Patch for adding ":lscscope". (Navdeep Parhar, 2007 Apr 26; update Apr 28)
+
+Patch for improving regexp speed by not freeing memory. (Alexei Alexandrov,
+2007 Feb 6)
+
+xterm should be able to pass focus changes to Vim, so that Vim can check for
+buffers that changed.  Perhaps in misc.c, function selectwindow().
+Xterm 224 supports it!
+
+Omni completion takes the wrong structure for variable arguments. (Bill
+McCarthy, 2007 Feb 18)
+
+When completing from another file that uses a different encoding completion
+text has the wrong encoding.  E.g., when 'encoding' is utf-8 and file is
+latin1.  Example from Gombault Damien, 2007 Mar 24.
+
+Completing ":echohl" argument should include "None". (Ori Avtalion)
+
+
+Vim 7.2:
+-   Search offset doesn't work for multibyte character.  Patch from Yukihiro
+    Nakadaira, 2006 Jul 18.
+    Changes the offset from counting bytes to counting characters.
+-   Rename the tutor files from tutor.gr.* to tutor.el.*.  Greece vs Greek.
+    Make all tutor files available in utf-8.
+-   Remove ! for ":cgetfile" and ":lgetfile". (patch from Yegappan Lakshmanan,
+    2007 Mar 9)
+-   Add blowfish encryption.  Openssl has an implementation.  Also by Paul
+    Kocher (LGPL), close to original.  Mohsin also has some ideas.
+    Take four bytes and turn them into unsigned to avoid byte-order problems.
+    Need to buffer up to 7 bytes to align on 8 byte boundaries.
+-   Rename doc/sql.vim doc/ft_sql.vim.
+-   Change "command-line" to "[Command Line]" for the command line buffer
+    name in ex_window().
+-   Move including fcntl.h to vim.h, before O_NOFOLLOW, and remove it from all
+    .c files.
+-   ":{range}source": source the lines from the file.
+	You can already yank lines and use :@" to execute them.
+	Most of do_source() would not be used, need a new function.
+	It's easy when not doing breakpoints or profiling.
+
+
+Patches:
+-   Add 'cscopeignorecase' option. (Liang Wenzhi, 2006 Sept 3)
+-   Argument for feedkeys() to prepend to typeahead (Yakov Lerner, 2006 Oct
+    21)
+-   Load intl.dll too, not only libintl.dll. (Mike Williams, 2006 May 9, docs
+    patch May 10)
+-   Extra argument to strtrans() to translate special keys to their name (Eric
+    Arnold, 2006 May 22)
+-   'threglookexp' option: only match with first word in thesaurus file.
+    (Jakson A. Aquino, 2006 Jun 14)
+-   Mac: indicate whether a buffer was modified. (Nicolas Weber, 2006 Jun 30)
+-   Allow negative 'nrwidth' for left aligning. (Nathan Laredo, 2006 Aug 16)
+-   ml_append_string(): efficiently append to an existing line. (Brad
+    Beveridge, 2006 Aug 26)  Use in some situations, e.g., when pasting a
+    character at a time?
+-   gettabvar() and settabvar() functions. (Yegappan Lakshmanan, 2006 Sep 8)
+-   recognize hex numbers better. (Mark Manning, 2006 Sep 13)
+
+
+Awaiting updated patches:
+9   Mac unicode patch (Da Woon Jung, Eckehard Berns):
+    8   Add patch from Muraoka Taro (Mar 16) to support input method on Mac?
+	New patch 2004 Jun 16
+    - selecting proportional font breaks display
+    - UTF-8 text causes display problems.  Font replacement causes this.
+    - Command-key mappings do not work. (Alan Schmitt)
+    - With 'nopaste' pasting is wrong, with 'paste' Command-V doesn't work.
+      (Alan Schmitt)
+    - remove 'macatsui' option when this has been fixed.
+    - when 'macatsui' is off should we always convert to "macroman" and ignore
+      'termencoding'?
+9   HTML indenting can be slow.  Caused by using searchpair().  Can search()
+    be used instead?
+8   Win32: Add minidump generation. (George Reilly, 2006 Apr 24)
+8   Add ":n" to fnamemodify(): normalize path, remove "../" when possible.
+    Aric Blumer has a patch for this.  He will update the patch for 6.3.
+7   Completion of network shares, patch by Yasuhiro Matsumoto.
+    Update 2004 Sep 6.
+    How does this work?  Missing comments.
+-   Patch for 'breakindent' option: repeat indent for wrapped line. (Vaclav
+    Smilauer, 2004 Sep 13, fix Oct 31)
+    Asked for improvements 2004 Dec 20.
+8   Add a few more command names to the menus.  Patch from Jiri Brezina
+    (28 feb 2002).  Will mess the translations...
+7   ATTENTION dialog choices are more logical when "Delete it' appears
+    before "Quit".  Patch by Robert Webb, 2004 May 3.
+-   Include flipcase patch: ~/vim/patches/wall.flipcase2 ?  Make it work
+    for multi-byte characters.
+-   Win32: add options to print dialog.  Patch from Vipin Aravind.
+-   Patch to add highlighting for whitespace. (Tom Schumm, 2003 Jul 5)
+    use the patch that keeps using HLF_8 if HLF_WS has not
+    been given values.
+    Add section in help files for these highlight groups?
+8   "fg" and "bg" don't work in an xterm.  Get default colors from xterm
+    with an ESC sequence.
+    xterm can send colors for many things.  E.g. for the cursor:
+	<Esc>]12;?<Bel>
+    Can use this to get the background color and restore the colors on exit.
+7   Add "DefaultFG" and "DefaultBG" for the colors of the menu. (Marcin
+    Dalecki has a patch for Motif and Carbon)
+-   Add possibility to highlight specific columns (for Fortran).  Or put a
+    line in between columns (e.g., for 'textwidth').
+    Patch to add 'hlcolumn' from Vit Stradal, 2004 May 20.
+8   Add functions:
+    gettext()		Translate a message.  (Patch from Yasuhiro Matsumoto)
+			Update 2004 Sep 10
+			Another patch from Edward L. Fox (2005 Nov 24)
+			Search in 'runtimepath'?
+			More docs needed about how to use this.
+			How to get the messages into the .po files?
+    confirm()		add "flags" argument, with 'v' for vertical
+			    layout and 'c' for console dialog. (Haegg)
+			    Flemming Madsen has a patch for the 'c' flag
+			    (2003 May 13)
+    raisewin()		raise gvim window (see HierAssist patch for
+			    Tcl implementation ~/vim/HierAssist/ )
+    taglist()		add argument to specify maximum number of matches.
+			useful for interactive things or completion.
+7   Make globpath() also work with upwards search. (Brian Medley)
+7   Add patch from Benoit Cerrina to integrate Vim and Perl functions
+    better.  Now also works for Ruby (2001 Nov 10)
+-   Patch from Herculano de Lima Einloft Neto for better formatting of the
+    quickfix window (2004 dec 2)
+7   When 'rightleft' is set, the search pattern should be displayed right
+    to left as well?  See patch of Dec 26. (Nadim Shaikli)
+8   Option to lock all used memory so that it doesn't get swapped to disk
+    (uncrypted).  Patch by Jason Holt, 2003 May 23.  Uses mlock.
+7   Support a stronger encryption.  Jason Holt implemented AES (May 6 2003).
+7   Add ! register, for shell commands. (patch from Grenie)
+8   In the gzip plugin, also recognize *.gz.orig, *.gz.bak, etc.  Like it's
+    done for filetype detection.  Patch from Walter Briscoe, 2003 Jul 1.
+7   Add a "-@ filelist" argument: read file names from a file. (David
+    Kotchan has a patch for it)
+8   Include a connection to an external program through a pipe?  See
+    patches from Felbinger for a mathematica interface.
+    Or use emacs server kind of thing?
+7   Add ":justify" command.  Patch from Vit Stradal 2002 Nov 25.
+-   findmatch() should be adjusted for Lisp.  See remark at
+    get_lisp_indent().  Esp. \( and \) should be skipped. (Dorai Sitaram,
+    incomplete patch Mar 18)
+-   For GUI Find/Replace dialog support using a regexp.  Patch for Motif
+    and GTK by degreneir (nov 10 and nov 18).
+-   Patch for "paranoid mode" by Kevin Collins, March 7.  Needs much more work.
+
+
+Vi incompatibility:
+-   Try new POSIX tests, made after my comments. (Geoff Clare, 2005 April 7)
+    Version 1.5 is in ~/src/posix/1.5. (Lynne Canal)
+8   With undo/redo only marks in the changed lines should be changed.  Other
+    marks should be kept.  Vi keeps each mark at the same text, even when it
+    is deleted or restored. (Webb)
+    Also: A mark is lost after: make change, undo, redo and undo.
+    Example: "{d''" then "u" then "d''": deletes an extra line, because the ''
+    position is one line down. (Veselinovic)
+8   When stdin is not a tty, and Vim reads commands from it, an error should
+    make Vim exit.
+7   Unix Vim (not gvim): Typing CTRL-C in Ex mode should finish the line
+    (currently you can continue typing, but it's truncated later anyway).
+    Requires a way to make CTRL-C interrupt select() when in cooked input.
+8   When loading a file in the .exrc, Vi loads the argument anyway.  Vim skips
+    loading the argument if there is a file already.  When no file argument
+    given, Vi starts with an empty buffer, Vim keeps the loaded file. (Bearded)
+6   In Insert mode, when using <BS> or <Del>, don't wipe out the text, but
+    only move back the cursor.	Behaves like '$' in 'cpoptions'.  Use a flag
+    in 'cpoptions' to switch this on/off.
+8   When editing a file which is a symbolic link, and then opening another
+    symbolic link on the same file, Vim uses the name of the first one.
+    Adjust the file name in the buffer to the last one used?  Use several file
+    names in one buffer???
+    Also: When first editing file "test", which is symlink to "test2", and
+    then editing "test2", you end up editing buffer "test" again.  It's not
+    logical that the name that was first used sticks with the buffer.
+7   The ":undo" command works differently in Ex mode.  Edit a file, make some
+    changes, "Q", "undo" and _all_ changes are undone, like the ":visual"
+    command was one command.
+    On the other hand, an ":undo" command in an Ex script only undoes the last
+    change (e.g., use two :append commands, then :undo).
+7   The ":map" command output overwrites the command.  Perhaps it should keep
+    the ":map" when it's used without arguments?
+7   CTRL-L is not the end of a section?  It is for Posix!  Make it an option.
+7   Implement 'prompt' option.	Init to off when stdin is not a tty.
+7   CTRL-T in Insert mode inserts 'shiftwidth' of spaces at the cursor.  Add a
+    flag in 'cpoptions' for this.
+7   Add a way to send an email for a crashed edit session.  Create a file when
+    making changes (containing name of the swap file), delete it when writing
+    the file.  Supply a program that can check for crashed sessions (either
+    all, for a system startup, or for one user, for in a .login file).
+7   Vi doesn't do autoindenting when input is not from a tty (in Ex mode).
+7   "z3<CR>" should still use the whole window, but only redisplay 3 lines.
+7   ":tag xx" should move the cursor to the first non-blank.  Or should it go
+    to the match with the tag?	Option?
+7   Implement 'autoprint'/'ap' option.
+7   Add flag in 'cpoptions' that makes <BS> after a count work like <Del>
+    (Sayre).
+7   Add flag in 'cpoptions' that makes operator (yank, filter) not move the
+    cursor, at least when cancelled. (default Vi compatible).
+7   This Vi-trick doesn't work: "Q" to go to Ex mode, then "g/pattern/visual".
+    In Vi you can edit in visual mode, and when doing "Q" you jump to the next
+    match.  Nvi can do it too.
+7   Support '\' for line continuation in Ex mode for these commands: (Luebking)
+	g/./a\		    g/pattern1/ s/pattern2/rep1\\
+	line 1\		    line 2\\
+	line 2\		    line 3\\
+	.		    line4/
+6   ":e /tmp/$tty" doesn't work.  ":e $uid" does.  Is $tty not set because of
+    the way the shell is started?
+6   Vi compatibility (optional): make "ia<CR><ESC>10." do the same strange
+    thing.  (only repeat insert for the first line).
+
+
+GTK+ 1 (OK in GTK 2):
+8   When using "gvim -geom 40x30" or setting 'columns' in .gvimrc or with a
+    GUIEnter autocommand, the width is still set to fit the toolbar.  Also
+    happens when changing the font.  How to avoid that the toolbar specifies
+    the minimal window width?
+8   When using a theme with different scrollbars (gtkstep), the scrollbars can
+    be too narrow. (Drazen Kacar)
+8   Font "7x14" has a bold version "7x14bold".  Try to find the bold font by
+    appending "bold" when there are not 14 dashes.
+
+GTK+ GUI known bugs:
+9   Crash with X command server over ssh. (Ciaran McCreesh, 2006 Feb 6)
+8   GTK 2: Combining UTF-8 characters not displayed properly in menus (Mikolaj
+    Machowski)  They are displayed as separate characters.  Problem in
+    creating a label?
+8   GTK 2: Combining UTF-8 characters are sometimes not drawn properly.
+    Depends on the font size, "monospace 13" has the problem.  Vim seems to do
+    everything right, must be a GTK bug.  Is there a way to work around it?
+9   Can't paste a Visual selection from GTK-gvim to vim in xterm or Motif gvim
+    when it is longer than 4000 characters.  Works OK from gvim to gvim and
+    vim to vim.  Pasting through xterm (using the shift key) also works.
+    It starts working after GTK gvim loses the selection and gains it again.
+-   Gnome2: When moving the toolbar out of the dock, so that it becomes
+    floating, it can no longer be moved.  Therefore making it float has been
+    blocked for now.
+
+
+Win32 GUI known bugs:
+-   Win32: tearoff menu window should have a scrollbar when it's taller than
+    the screen.
+8   non-ASCII font names don't work.  Need to convert from 'encoding' and use
+    the wide functions.
+8   On Windows 98 the unicows library is needed to support functions with UCS2
+    file names.  Can we load unicows.dll dynamically?
+8   When the primary monitor is below or right of the secondary monitor and
+    Vim is on the secondary monitor it will often move to the primary monitor.
+    Window position coordinates can be negative. (James Harvey)
+8   The -P argument doesn't work very well with many MDI applications.
+    The last argument of CreateWindowEx() should be used, see MSDN docs.
+    Tutorial: http://win32assembly.online.fr/tut32.html
+8   In eval.c, io.h is included when MSWIN32 is defined.  Shouldn't this be
+    WIN32?  Or can including io.h be moved to vim.h? (Dan Sharp)
+7   Windows XP: When using "ClearType" for text smoothing, a column of yellow
+    pixels remains when typing spaces in front of a "D" ('guifont' set to
+    "lucida_console:h8").
+6   Win32 GUI: With "-u NONE -U NONE" and doing "CTRL-W v" "CTRL-W o", the ":"
+    of ":only" is highlighted like the cursor.  (Lipelis)
+8   When 'encoding' is "utf-8", should use 'guifont' for both normal and wide
+    characters to make Asian languages work.  Win32 fonts contain both
+    type of characters.
+7   When font smoothing is enabled, redrawing can become very slow.  The reason
+    appears to be drawing with a transparent background.  Would it be possible
+    to use an opaque background in most places?
+8   Use another default for 'termencoding': the active codepage.  Means that
+    when 'encoding' is changed typing characters still works properly.
+    Alternative: use the Unicode functions to obtain typed characters.
+8   Win32: Multi-byte characters are not displayed, even though the same font
+    in Notepad can display them. (Srinath Avadhanula)  Try with the
+    UTF-8-demo.txt page with Andale Mono.
+7   The cursor color indicating IME mode doesn't work properly. (Shizhu Pan,
+    2004 May 9)
+8   Win32: When clicking on the gvim title bar, which gives it focus, produces
+    a file-changed dialog, after clicking on a button in that dialog the gvim
+    window follows the mouse.  The button-up event is lost.  Only with
+    MS-Windows 98?
+    Try this: ":set sw ts", get enter-prompt, then change the file in a
+    console, go back to Vim and click "reload" in the dialog for the changed
+    file: Window moves with the cursor!
+    Put focus event in input buffer and let generic Vim code handle it?
+8   When activating the Vim window with mouse click, don't move cursor to
+    mouse position.  Catch WM_MOUSEACTIVATE. (Luevelsmeyer)
+8   Win32: When mouse is hidden and in the toolbar, moving it won't make it
+    appear. (Sami Salonen)
+8   Win32 GUI: With maximized window, ":set go-=r" doesn't use the space that
+    comes available. (Poucet)  It works OK on Win 98 but doesn't work on Win
+    NT 4.0.  Leaves a grey area where the scrollbar was.  ":set go+=r" also
+    doesn't work properly.
+8   When Vim is minimized and when maximizing it a file-changed dialog pops
+    up, Vim isn't maximized.  It should be done before the dialog, so that it
+    appears in the right position. (Webb)
+9   When selecting at the more-prompt or hit-enter-prompt, the right mouse
+    button doesn't give popup menu.
+    At the hit-enter prompt CTRL-Y doesn't work to copy the modeless
+    selection.
+    On the command line, don't get a popup menu for the right mouse button.
+    Let the middle button paste selected text (not the clipboard but the
+    non-Visual selection)?  Otherwise CTRL-Y has to be used to copy the text.
+8   When 'grepprg' doesn't execute, the error only flashes by, the
+    user can hardly see what is wrong. (Moore)
+    Could use vimrun with an "-nowait" argument to only wait when an error
+    occurs, but "command.com" doesn't return an error code.
+8   When the 'shell' cannot be executed, should give an appropriate error msg.
+    Esp. for a filter command, currently it only complains the file could not
+    be read.
+7   Add an option to add one pixel column to the character width?  Lucida
+    Console italic is wider than the normal font ("d" overlaps with next char).
+    Opposite of 'linespace': 'columnspace'.
+7   At the hit-enter prompt scrolling now no longer works.  Need to use the
+    keyboard to get around this.  Pretend <CR> was hit when the user tries to
+    scroll?
+7   Scrollbar width doesn't change when selecting other windows appearance.
+    Also background color of Toolbar and rectangle below vert. scrollbar.
+7   "!start /min cmd" should run in a minimized window, instead of using
+    "/min" as the command name. (Rogall)
+6   Drawing text transparently doesn't seem to work (when drawing part cursor).
+8   CTRL key doesn't always work in combination with ALT key.  It does work
+    for function keys, not for alphabetic characters.  Perhaps this is because
+    CTRL-ALT is used by Windows as AltGr?
+8   CTRL-- doesn't work for AZERTY, because it's CTRL-[ for QWERTY.  How do we
+    know which keyboard is being used?
+7   When scrolling, and a background color is dithered, the dither pattern
+    doesn't always join correctly between the scrolled area and the new drawn
+    area (Koloseike).
+8   When gui_init_font() is called with "*", p_guifont is freed while it might
+    still be used somewhere.  This is too tricky, do the font selection first,
+    then set the new font by name (requires putting all logfont parameters in
+    the font name).
+
+
+Athena and Motif:
+6   New Motif toolbar button from Marcin Dalecki:
+    - When the mouse pointer is over an Agide button the red becomes black.
+      Something with the way colors are specified in the .xpm file.
+    - The pixmap is two pixels smaller than it should be.  The gap is filled
+      with grey instead of the current toolbar background color.
+9   Can configure be changed to disable netbeans if the Xpm library is
+    required and it's missing?
+8   When using the resource "Vim*borderwidth 2" the widgets are positioned
+    wrong.
+9   XIM is disabled by default for SGI/IRIX.  Fix XIM so that 'imdisable' can
+    be off by default.
+9   XIM doesn't work properly for Athena/Motif. (Yasuhiro Matsumoto)  For now,
+    keep XIM active at all times when the input method has the preediting
+    flag.
+8   X11: A menu that contains an umlaut is truncated at that character.
+    Happens when the locale is "C", which uses ASCII instead of IS0-8859-1.
+    Is there a way to use latin1 by default?  Gnome_init() seems to do this.
+8   Perhaps use fontsets for everything?
+6   When starting in English and switching the language to Japanese, setting
+    the locale with ":lang", 'guifontset' and "hi menu font=", deleting all
+    menus and setting them again, the menus don't use the new font.  Most of
+    the tooltips work though...
+7   Motif: when using a file selection dialog, the specified file name is not
+    always used (when specifying a filter or another directory).
+8   When 'encoding' is different from the current locale (e.g., utf-8) the
+    menu strings don't work.  Requires conversion from 'encoding' to the
+    current locale.  Workaround: set 'langmenu'.
+
+
+Athena GUI:
+9   When dragging the scrollbar thumb very fast, focus is only obtained in
+    the scrollbar itself.  And the thumb is no longer updated when moving
+    through files.
+7   The file selector is not resizable.  With a big font it is difficult to
+    read long file names. (Schroeder)
+4   Re-write the widget attachments and code so that we will not have to go
+    through and calculate the absolute position of every widget every time the
+    window is refreshed/changes size.  This will help the "flashing-widgets"
+    problem during a refresh.
+5   When starting gvim with all the default colors and then typing
+    ":hi Menu guibg=cyan", the menus change color but the background of the
+    pullright pixmap doesn't change colors.
+    If you type ":hi Menu guibg=cyan font=anyfont", then the pixmap changes
+    colors as it should.
+    Allocating a new pixmap and setting the resource doesn't change the
+    pullright pixmap's colors.  Why?  Possible Athena bug?
+
+
+Motif GUI:
+-   gui_mch_browsedir() is missing.
+7   Use XmStringCreateLocalized() instead of XmStringCreateSimple()?
+    David Harrison says it's OK (it exists in Motif 1.2).
+8   Lesstif: When deleting a menu that's torn off, the torn off menu becomes
+    very small instead of disappearing.  When closing it, Vim crashes.
+    (Phillipps)
+
+
+GUI:
+9   On Solaris, creating the popup menu causes the right mouse button no
+    longer to work for extending the selection. (Halevy)
+9   When running an external program, it can't always be killed with CTRL-C.
+    e.g., on Solaris 5.5, when using "K" (Keech).  Other 'guipty' problems on
+    Solaris 2.6. (Marley)
+9   On Solaris: Using a "-geometry" argument, bigger than the window where Vim
+    is started from, causes empty lines below the cmdline. (raf)
+8   X11 GUI: When menu is disabled by excluding 'm' from 'guioptions', ALT key
+    should not be used to trigger a menu (like the Win32 version).
+8   When setting 'langmenu', it should be effective immediately.  Store both
+    the English and the translated text in the menu structure.  Re-generate
+    the translation when 'langmenu' has changed.
+8   Basic flaw in the GUI code: NextScreen is updated before calling
+    gui_write(), but the GUI code relies on NextScreen to represent the state
+    of where it is processing the output.
+    Need better separation of Vim core and GUI code.
+8   When fontset support is enabled, setting 'guifont' to a single font
+    doesn't work.
+8   Menu priority for sub-menus for: Amiga, BeOS.
+8   When translating menus ignore the part after the Tab, the shortcut.  So
+    that the same menu item with a different shortcut (e.g., for the Mac) are
+    still translated.
+8   Add menu separators for Amiga, RISCOS.
+8   Add way to specify the file filter for the browse dialog.  At least for
+    browse().
+8   Add dialog for search/replace to other GUIs?  Tk has something for this,
+    use that code?  Or use console dialog.
+8   When selecting a font with the font dialog and the font is invalid, the
+    error message disappears too quick.
+7   More features in the find/replace dialog:
+    - regexp on/off
+    - search in selection/buffer/all buffers/directory
+       when all buffers/directory is used:
+	- filter for file name
+       when directory is used:
+	- subdirectory on/off
+	- top directory browser
+8   gui_check_colors() is not called at the right moment.  Do it much later,
+    to avoid problems.
+8   gui_update_cursor() is called for a cursor shape change, even when there
+    are mappings to be processed.  Only do something when going to wait for
+    input.  Or maybe every 100 ms?
+8   X11: When the window size is reduced to fit on screen, there are blank
+    lines below the text and bottom scrollbar.  "gvim -geometry 80x78+0+0".
+    When the "+0+0" is omitted it works.
+8   When starting an external command, and 'guipty' set, BS and DEL are mixed
+    up.  Set erase character somehow?
+8   A dead circumflex followed by a space should give the '^' character
+    (Rommel).  Look how xterm does this.
+    Also: Bednar has some code for dead key handling.
+    Also: Nedit 5.0.2 with USE_XMIM does it right. (Gaya)
+8   The compose key doesn't work properly (Cepas).  Both for Win32 and X11.
+7   The cursor in an inactive window should be hollow.  Currently it's not
+    visible.
+7   GUI on Solaris 2.5.1, using /usr/dt/..: When gvim starts, cursor is
+    hollow, after window lowered/raised it's OK. (Godfrey)
+7   When starting GUI with ":gui", and window is made smaller because it
+    doesn't fit on the screen, there is an extra redraw.
+8   When setting font with .Xdefaults, there is an extra empty line at the
+    bottom, which disappears when using ":set guifont=<Tab>". (Chadzelek)
+8   When font shape changes, but not the size, doing ":set font=" does not
+    redraw the screen with the new font.  Also for Win32.
+    When the size changes, on Solaris 2.5 there isn't a redraw for the
+    remaining part of the window (Phillipps).
+-   Flashes really badly in certain cases when running remotely from a Sun.
+4   Re-write the code so that the highlighting isn't changed multiple times
+    when doing a ":hi clear".  The color changes happen three or more times
+    currently.  This is very obvious on a 66Mhz 486.
+
+
+MSDOS/DJGPP:
+9   Pressing CTRL-C often crashes the console Vim runs in. (Ken Liao)
+    When 'bioskey' isn't set it doesn't happen.  Could be a problem with the
+    BIOS emulation of the console.  Version 5.6 already had this problem.
+8   DJGPP: "cd c:" can take us to a directory that no longer exists.
+    change_drive() doesn't check this.  How to check for this error?
+9   The 16 bit version runs out of memory very quickly.  Should find unused
+    code and reduce static data.  Resetting 'writebackup' helps to be able to
+    write a file.
+9   Crash when running on Windows 98 in a console window and pressing CTRL-C.
+    Happens now and then.  When debugging Vim in gdb this also happens.  Since
+    the console crashes, might be a bug in the DOS console.  Resetting
+    'bioskey' avoids it, but then CTRL-C doesn't work.
+9   DOS: Make CTRL-Fx and ALT-Fx work.
+    CTRL-F1 = CE-5E, CTRL-F2 = CE-5F, .., CTRL-F10 = CE-67
+    ALT-F1 = CE-68, ALT-F2 = CE-69, .., ALT-F10 = CE-71
+    Shifted cursor keys produce same codes as unshifted keys.  Use bioskey(2)
+    to get modifier mask for <S-C-M-Fx>.
+    Use K_SPECIAL/KS_MODIFIER codes to insert modifier mask in input stream?
+    Make this work like in Win32 console.
+    Mapping things like <M-A> doesn't work, because it generates an extended
+    key code.  Use a translation table?
+9   Can't read an opened swap file when the "share" command has not been used.
+    At least ignore the swap files that Vim has opened itself.
+8   Use DJGPP 2.03.
+8   The Dos32 version (DJGPP) can't use long file names on Windows NT.
+    Check if new package can be used (v2misc/ntlfn08[bs].zip).
+8   setlocale() is bogus.
+8   Vim busy waits for new characters or mouse clicks.	Should put in some
+    sort of sleep, to avoid eating 50% of the CPU time.  Test on an unpatched
+    Windows 95 system!
+8   DJGPP: when shell is bash, make fails. (Donahoe)
+7   Hitting CTRL-P twice quickly (e.g., in keyword completion) on a 8088
+    machine, starts printer echo! (John Mullin).
+7   MSDOS 16 bit version can't work with COMSPEC that has an argument, e.g.:
+    COMSPEC=C:\WINDOWS\COMMAND.COM /E:4096    (Bradley)
+    Caused by BCC system() function (Borland "make" has the same problem).
+8   Mouse: handle left&right button pressed as middle button pressed.  Add
+    modifier keys shift, ctrl and alt.
+7   When too many files are open (depends on FILES), strange things happen.
+    The Dos16 version runs out of memory, in the Dos32 version "!ls" causes a
+    crash.  Another symptom: .swp files are not deleted, existing files are
+    "[New file]".
+7   DJGPP version doesn't work with graphics display mode.  Switch to a mode
+    that is supported?
+8   DJGPP: ":mode" doesn't work for many modes.  Disable them.
+8   DJGPP: When starting in Ex mode, shouldn't clear the screen. (Walter
+    Briscoe)
+
+
+MSDOS, OS/2 and Win32:
+8   OS/2: Add backtick expansion.  Undefine NO_EXPANDPATH and use
+    gen_expand_wildcards().
+8   OS/2: Add clipboard support?  See example clipbrd.exe from Alexander
+    Wagner.
+8   OS/2: Add Extended Attributes support and define HAVE_ACL.
+8   OS/2: When editing a file name "foo.txt" that is actually called FOO.txt,
+    writing uses "foo.txt".  Should obtain the real file name.
+8   Should $USERPROFILE be preferred above $HOMEDRIVE/$HOMEPATH?  No, but it's
+    a good fallback, thus use:
+	    $HOME
+	    $HOMEDRIVE$HOMEPATH
+	    SHGetSpecialFolderPath(NULL, lpzsPath, CSIDL_APPDATA, FALSE);
+	    $USERPROFILE
+	    SHGetSpecialFolderPath(NULL, lpzsPath, CSIDL_COMMON_APPDATA, FALSE);
+	    $ALLUSERSPROFILE
+	    $SYSTEMDRIVE\
+	    C:\
+8   Win32 console: <M-Up> and <M-Down> don't work. (Geddes)  We don't have
+    special keys for these.  Should use modifier + key.
+8   Win32 console: caps-lock makes non-alpha keys work like with shift.
+    Should work like in the GUI version.
+8   Environment variables in DOS are not case sensitive.  Make a define for
+    STRCMP_ENV(), and use it when comparing environment var names.
+8   Setting 'shellslash' has no immediate effect.  Change all file names when
+    it is set/reset?  Or only use it when actually executing a shell command?
+8   When editing a file on a Samba server, case might matter.  ":e file"
+    followed by ":e FILE" will edit "file" again, even though "FILE" might be
+    another one.  Set last used name in buflist_new()?  Fix do_ecmd(), etc.
+8   When a buffer is editing a file like "ftp://mach/file", which is not going
+    to be used like a normal file name, don't change the slashes to
+    backslashes. (Ronald Hoellwarth)
+
+
+Windows 95:
+8   Editing a file by it's short file name and writing it, makes the long file
+    name disappear.  Setting 'backupcopy' helps.
+    Use FindFirstFile()->cAlternateFileName in fname_case() (George Reilly).
+8   Doing wildcard expansion, will match the short filename, but result in the
+    long filename (both DJGPP and Win32).
+
+
+Win32 console:
+9   When editing a file by its short file name, it should be expanded into its
+    long file name, to avoid problems like these: (Mccollister)
+     1) Create a file called ".bashrc" using some other editor.
+     2) Drag that file onto a shortcut or the actual executable.
+     3) Note that the file name is something like BASHRC~1
+     4) Go to File->Save As menu item and type ".bashrc" as the file name.
+     5) Press "Yes" to indicate that I want to overwrite the file.
+     6) Note that the message "File exists (add ! to override)" is displayed
+	and the file is not saved.
+    Use FindFirstFile() to expand a file name and directory in the path to its
+    long name.
+8   Also implement 'conskey' option for the Win32 console version?  Look at
+    how Xvi does console I/O under Windows NT.
+7   Re-install the use of $TERM and support the use of different terminals,
+    besides the console.
+8   Use of <altgr> modifier doesn't work?  5.3 was OK. (Garcia-Suarez/Guckes)
+9   Mapping <C-S-Tab> doesn't work correctly.  How to see the difference with
+    <C-S-i>?
+9   tmpnam() uses file in root of file system: "\asdf".  That doesn't work on
+    a Netware network drive.  Use same function as for Win32 GUI?
+8   In os_win32.h, HAVE_STRICMP and HAVE_STRNICMP are defined only if __GNUC__
+    is not defined.  Shouldn't that be the other way around?
+7   Use SetConsoleCP() and SetConsoleOutputCP() to implement 'termencoding'?
+    Avoids that input and output work differently.  Need to be restored when
+    exiting.
+
+
+Amiga:
+8   In mch_inchar() should use convert_input_safe() to handle incomplete byte
+    sequences.
+9   In mch_expandpath() a "*" is to be expanded, but "\*" isn't.  Remove
+    backslashes in result.
+8   Executing a shell, only one option for 'shell' is separated.  Should do
+    all options, using white space separation.
+
+
+Macintosh:
+-   GUI: gui_mch_browsedir() is missing.
+7   Patch to add 'transparency' option.  Disadvantage: it's slow. (Eckehard
+    Berns, 2004 May 9) http://ecki.to/vim/TransBack-2004-05-09.diff
+    Needs more work.  Add when someone really wants it.
+7   Loading the Perl library only works on OS/X 10.2 or 10.3, never on both.
+    Load the Perl library dynamically see Python sources file dynload_mac
+    (Jack)
+    dynamic linking: http://developer.apple.com/technotes/tn2002/tn2064.html
+8   Inputting Unicode characters does not work in the terminal.  They appear
+    to arrive as upper and lower bytes. (David Brown, 2004 April 17)
+8   Typing Unicode characters doesn't work at all in the GUI.
+8   inputdialog() doesn't resize when giving more text lines. (David Fishburn,
+    2006 Sept 28)
+9   Problems in Carbon version for OS X: (Benji Fisher)
+    - keyboard shortcuts in the menus get lost.
+8   The Vim/About menu doesn't work.
+8   ":gui" doesn't fork.  Enabling the code in gui.c to fork causes a SEGV.
+8   Define vim_mkdir() for Macintosh.
+8   Define mch_writable() for Macintosh.
+8   Some file systems are case-sensitive, some are not.  Turn
+    CASE_INSENSITIVE_FILENAME into an option, at least for completion.
+9   When DiskLock is running, using a swap file causes a crash.  Appears to be
+    a problem with writing a file that starts with a dot. (Giacalone)
+9   On G3 Mac, OS version 8, control strip causes characters messed up when
+    scrolling (CTRL-L cleans it up). (Benji Fisher)
+9   On G3 Mac, OS version 8, variable-speed scrolling doesn't work, after two
+    seconds of scrolling the screen freezes. (Benji Fisher)
+9   In mac_expandpath() check that handling of backslashes is done properly.
+8   Standard Mac shortcuts are missing.  (Amerige)
+8   Handling of non-fixed width fonts is wrong. (Amerige)
+
+
+"Small" problems:
+-   When using e_secure in do_one_cmd() mention the command being executed,
+    otherwise it's not clear where it comes from.
+8   When disabling FEAT_CMDL_COMPL compilation fails.  Would need to avoid
+    using parse_compl_arg() in eval.c and uc_scan_attr().
+9   For Turkish vim_tolower() and vim_toupper() also need to use utf_
+    functions for characters below 0x80. (Sertacyildiz)
+9   When the last edited file is a help file, using '0 in a new Vim doesn't
+    edit the file as a help file.
+8   When an ":edit" is inside a try command and the ATTENTION prompt is used,
+    the :catch commands are always executed, also when the file is edited
+    normally.  Should reset did_emsg and undo side effects.  Also make sure
+    the ATTENTION message shows up.  Servatius Brandt works on this.
+9   When using ":e ++enc=foo file" and the file is already loaded with
+    'fileencoding' set to "bar", then do_ecmd() uses that buffer, even though
+    the fileencoding differs.  Reload the buffer in this situation?  Need to
+    check for the buffer to be unmodified.
+8   ":g//" gives "Pattern not found error" with E486.  Should not use the
+    error number, it's not a regular error message.
+7   Vimtutor leaves escape sequence in terminal. This is the xterm response to
+    requesting the version number.  (Yasuhiro Matsumoto)
+8   When redirecting and using ":silent" the current column for displaying and
+    redirection can be different.  Use a separate variable to hold the column
+    for redirection.
+7   The messages for "vim --help" and "vim --version" don't use
+    'termencoding'.
+-   Could the hit-enter prompt be avoided when a message only overlaps the
+    'showcmd' area?  Clear that area when the next cmd is typed.
+8   When 'scrollbind' is set, a window won't scroll horizontally if the cursor
+    line is too short.  Add a word in 'scrollopt' to allow moving the cursor
+    to longer line that is visible.  A similar thing is done for the GUI when
+    using the horizontal scrollbar.
+7   VisVim can only open one file.  Hard to solve: each opened file is passed
+    with a separate invocation, would need to use timestamps to know the
+    invocations belong together.
+8   When giving a ":bwipeout" command a file-changed dialog may popup for this
+    buffer, which is pointless.  (Mike Williams)
+8   On MS-Windows ":make" doesn't show output while it is working.  Use the
+    tee.exe from  http://unxutils.sourceforge.net/ ?  About 16 Kbyte in the
+    UnxUtils.zip archive.
+    Alternate one: http://www.pramodx.20m.com/tee_for_win32.htm, but Walter
+    Briscoe says it's not as good.
+8   "stl" and "stlnc" in 'fillchars' don't work for multi-byte characters.
+8   When doing Insert mode completion a mapping cannot recursively call
+    edit(), because the completion information is global.  Put everything in
+    an allocated structure?
+6   Python: ":py raw_input('prompt')" doesn't work. (Manu Hack)
+8   Command line completion: buffers "foo.txt" and "../b/foo.txt", completing
+    ":buf foo<Tab>" doesn't find the second one. (George V. Reilly)
+7   Output for ":scriptnames" and ":breaklist" should shorten the file names:
+    use "~/" when possible.
+7   mb_off2cells() doesn't work correctly on the tail byte of a double-byte
+    character. (Yasuhiro Matsumoto)  It should return 1 when used on a tail
+    byte, like for utf-8.  Store second byte of double-byte in ScreenLines2[]
+    (like for DBCS_JPNU) and put a zero in the second byte (like for UTF-8).
+8   'backupdir' and 'directory' should use $TMPDIR, $TMP and/or $TEMP when
+    defined.
+7   Inside a function with "perl <<EOF" a line with "$i++" is recognized as an
+    ":insert" command, causing the following "endfunction" not to be found.
+    Add skipping this perl construction inside function definitions.
+7   When 'ttimeoutlen' is 10 and 'timeoutlen' is 1000, there is a keycode
+    "<Esc>a" and a mapping <Esc>x", when typing "<Esc>a" with half a second
+    delay should not be interpreted as a keycode. (Hans Ginzel)
+7   ":botright 1 new" twice causes all window heights to be changed.  Make the
+    bottom window only bigger as much as needed.
+7   "[p" doesn't work in Visual mode. (David Brown)
+7   The Cygwin and MingW makefiles define "PC", but it's not used anywhere.
+    Remove? (Dan Sharp)
+9   User commands use the context of the script they were defined in.  This
+    causes a "s:var" argument to unexpectedly use a variable in the defining
+    script, not the calling script.  Add an argument to ":command":
+    "-keepcontext".  Do replace <SID>, so that a function in the defining
+    script can be called.
+8   The Japanese message translations for MS-Windows are called ja.sjis.po,
+    but they use encoding cp932.  Rename the file and check that it still
+    works.
+9   When a syntax region does not use "keepend" and a contained item does use
+    "extend", this makes the outer region stop at the end of the contained
+    region. (Lutz Eymers)  Another example Nov 14 2002.
+8   A very long message in confirm() can't be quit.  Make this possible with
+    CTRL-C.
+7   clip_x11_own_selection() uses CurrentTime, that is not allowed.  VNC X
+    server has a problem with this.  (Mark Waggoner) Remembering the timestamp
+    of events isn't always possible.  We don't get them in an xterm.  GTK
+    doesn't obtain the selection again when the timestamp differs, thus it
+    won't work for GTK anyway.
+8   When the clipboard isn't supported: ":yank*" gives a confusing error
+    message.  Specifically mention that the register name is invalid.
+8   "gf" always excludes trailing punctuation characters.  file_name_in_line()
+    is currently fixed to use ".,:;!".  Add an option to make this
+    configurable?
+8   'hkmap' should probably be global-local.
+9   When "$" is in 'cpoptions' and folding is active, a "C" command changes
+    the folds and resets w_lines_valid.  The display updating doesn't work
+    then. (Pritesh Mistry)
+8   ":s!from!to!" works, but ":smagic!from!to!" doesn't.  It sees the "!" as a
+    flag to to the command.  Same for ":snomagic". (Johan Spetz)
+8   Using ":s" in a function changes the previous replacement string.  Save
+    "old_sub" in save_search_patterns()?
+8   Should allow multi-byte characters for the delimiter: ":s+a+b+" where "+"
+    is a multi-byte character.
+8   When appending to a file and 'patchmode' isn't empty, a backup file is
+    always written, even when the original file already exists.
+7   When using "daw" on the last word in a file and this is a single letter,
+    nothing is deleted.  Should delete the letter and preceding white space.
+9   When getting focus while writing a large file, could warn for this file
+    being changed outside of Vim.  Avoid checking this while the file is being
+    written.
+9   The "Error detected while processing modelines" message should have an
+    error number.
+7   The message in bt_dontwrite_msg() could be clearer.
+8   The script ID that is stored with an option and displayed with ":verbose
+    set" isn't reset when the option is set internally.  For example when
+    'foldlevel' is set from 'foldlevelstart'.
+8   Also store the line number with the script ID and use it for ":verbose",
+    so that "set nocompatible" is found when it changes other option values.
+    When an option is set indirectly mention the command?  E.g. when
+    ":diffsplit" sets 'foldmethod'.
+8   In the fileformat dialog, "Cancel" isn't translated.  Add a global
+    variable for this. (Eduardo Fernandez)
+9   When editing a file with 'readonly' set, there is no check for an existing
+    swap file.  Then using ":write" (without making any changes) doesn't give
+    a warning either.  Should check for an existing swap file without creating
+    one.
+7   When 'showbreak' is set, the amount of space a Tab occupies changes.
+    Should work like 'showbreak' is inserted without changing the Tabs.
+7   When 'mousefocus' is set and switching to another window with a typed
+    command, the mouse pointer may be moved to a part of the window that's
+    covered by another window and we lose focus.  Only move in the y
+    direction, not horizontally?
+8   When using CTRL-D after ":help", restrict the number of matches to a
+    thousand, otherwise using CTRL-D without an argument takes too long.
+8   ":hardcopy":
+    - Using the cterm_color[] table is wrong when t_colors is > 16.
+    - Need to handle unprintable characters.
+    - Win32: On a B&W printer syntax highlighting isn't visible.  Perform
+      dithering to make grey text?
+    - Add a flag in 'printoptions' to add an empty page to make the total
+      number even.  "addempty"? (Mike Williams)
+    - Respect 'linebreak'.  Perhaps also 'showbreak'?
+    - Should interpreted CTRL-L as a page break.
+    - Grey line numbers are not always readable.  Add field in 'printoptions'.
+      Default to black when no syntax highlighting.
+    - Be able to print a window in diff mode.
+    - Be able to specify a colorscheme to use for printing.  And a separate
+      one for B&W printing (if that can be detected).
+8   In Visual block mode with 'lbr' set, a change command doesn't insert the
+    text in following lines where the linebreak changes.
+9   dosinst.c: The DJGPP version can't uninstall the Uninstall registry key on
+    Windows NT.  How to install a .inf file on Windows NT and how to detect
+    that Windows NT is being used?
+8   When 'virtualedit' is "block,insert" and encoding is "utf-8", selecting a
+    block of one double-wide character, then "d" deletes only half of it.
+8   When 'virtualedit' is set, should "I" in blockwise visual mode also insert
+    in lines that don't extend into the block?
+8   With 'virtualedit' set, in Insert mode just after the end of line, CTRL-O
+    yh does not yank the last character of the line. (Pavel Papushev)
+    Doing "hl" first appears to make it work.
+8   With 'virtualedit' set it's possible to move into the blank area from
+    'linebreak'.
+8   With 'virtualedit' set and 'selection' "exclusive", a Visual selection
+    that ends in or after a tab, "d" doesn't delete (part of) the tab.
+    (Helmut Stiegler)
+8   With 'virtualedit' set, a blockwise Visual selection that starts and ends
+    in a tab, "<" shifts too much. (Helmut Stiegler)
+9   When jumping to a tag, the search pattern is put in the history.  When
+    'magic' is on, the pattern may not work.  Translate the pattern depending
+    on p_magic when putting it in the history?  Alternative: Store value of
+    'magic' in history.  (Margo)
+9   optwin.vim: Restoring a mapping for <Space> or <CR> is not correct for
+    ":noremap".  Add "mapcmd({string}, {mode})?  Use code from ":mkexrc".
+9   incsearch is incorrect for "/that/<Return>/this/;//" (last search pattern
+    isn't updated).
+9   term_console is used before it is set (msdos, Amiga).
+9   Get out-of-memory for ":g/^/,$s//@/" on 1000 lines, this is not handled
+    correctly.  Get many error messages while redrawing the screen, which
+    cause another redraw, etc.
+8   [<C-I> doesn't work when '*' is in 'iskeyword'.  find_pattern_in_path()
+    must escape special characters in the pattern.
+8   Vim can overwrite a read-only file with ":w!".  ":w" can't overwrite an
+    existing file, "w!" can, but perhaps not a read-only file?  Then use
+    ":w!!" for that.
+    Or ask for permission to overwrite it (if file can be made writable) and
+    restore file to readonly afterwards.
+    Overwriting a file for which a swap file exists is similar issue.
+7   When compiled with "xterm_clipboard", startup can be slower and might get
+    error message for invalid $DISPLAY.  Try connecting to the X server in the
+    background (forked), so that Vim starts up quicker?  Connect as soon as
+    the clipboard is to be used (Visual select mode starts, paste from
+    clipboard)
+7   X11: Some people prefer to use CLIPBOARD instead of PRIMARY for the normal
+    selection.  Add an "xclipboard" argument to the 'clipboard' option? (Mark
+    Waggoner)
+8   For xterm need to open a connection to the X server to get the window
+    title, which can be slow.  Can also get the title with "<Esc>[21t", no
+    need to use X11 calls.  This returns "<Esc>]l{title}<Esc>\".
+6   When the xterm reports the number of colors, a redraw occurs.  This is
+    annoying on a slow connection.  Wait for the xterm to report the number of
+    colors before drawing the screen.  With a timeout.
+8   When the builtin xterm termcap contains codes that are not wanted, need a
+    way to avoid using the builtin termcap.
+8   Xterm sends ^[[H for <Home> and ^[[F for <End> in some mode.  Also
+    recognize these keys?  Mostly useful for xterm simulators, like gnometerm.
+    See http://dickey.his.com/xterm/xterm.faq.html#xterm_pc_style.
+8   For xterm also recognize keypad up/down/left/right and insert.
+8   '[ and '] should be set to start/end of line when using a linewise operator
+    (e.g., ":w").
+8   CTRL-A can't handle big "long" numbers, they become negative.  Check for
+    "-" character, if not present, use unsigned long.
+8   Make it possible to disable the special meaning of "#" in the first column
+    for ">>".
+8   Add suspending with CTRL-Z at the "more" prompt, and when executing a long
+    script in do_cmdline().
+8   When using 'hidden', many swap files will be open.  When Vim runs into the
+    maximum number of open files, error messages will appear.  Detect that
+    this problem is present, and close any hidden files that don't have
+    changes.
+8   With 'viminfo' set such that the ".viminfo" file is written on a FAT
+    filesystem, an illegal file name may be created: ".vim".
+8   For each buffer that is opened, the viminfo file is opened and read to
+    check for file marks.  This can be slow.
+7   In xterm, recognize both vt100 and vt220 cursor keys.  Change
+    add_termcode() to not remove an existing entry for a name, when it's
+    needed.
+    Need a generic solution to recognize different codes for the same key.
+8   Core dump within signal function: gdb doesn't show stack backtrace!  Option
+    to skip catch_signals()?
+9   Repeating a "cw" with "." doesn't work if the text was pasted from the
+    clipboard. (Thomas Jones)  It's because the menu/toolbar item exits Insert
+    mode and uses "gP".  How to fix this without breaking inserting a block of
+    text?
+8   In Replace mode pasting from the clipboard (using menu or toolbar) inserts
+    all the text.  Add ":rmenu"?
+8   Pasting with the mouse in Replace mode inserts the text, instead of
+    overwriting, when it is more than one line.  Same for using <C-R>.
+9   CTRL-E and CTRL-Y don't work in small window when 'so' is 4 and lines are
+    wrapping (Acevedo/in.226).  E.g., when using CTRL-E, window height 7,
+    window might actually scroll down when last line of buffer is displayed.
+    --> Remember if the previous command was "cursor follows screen" or
+    "screen follow cursor" and use this in cursupdate().
+7   tilde_replace() can only handle "~/", should also do "~user/".
+    Get the list of home directories (from /etc/passwd?  Use getpwent()) and
+    use some clever algorithm to match a path with that.  Find common strings
+    in the list?
+8   When dragging status line with mouse, sometimes a jump when first clicking
+    on the status line (caused by 'winheight').  Select window on button up,
+    instead of on button down.
+8   Dragging the status line doesn't scroll but redraw.
+9   Evaluating 'statusline' in build_stl_str_hl() does not properly check for
+    reaching the end of the available buffer.
+    Patch to dynamically allocate the buffer for % items. (Eric Arnold, 2006
+    May 14)
+8   When performing incremental search, should abort searching as soon as a
+    character is typed.
+8   When the value of $MAKE contains a path, configure can't handle this.
+    It's an autoconf bug.  Remove the path from $MAKE to work around it.
+8   How to set VIMRC_FILE to \"something\" for configure?  Why does this not
+    work: CFLAGS='-DVIMRC_FILE=\"/mydir/myfile\"' ./configure
+8   The temporary file is sometimes not writable.  Check for this, and use an
+    alternate name when it isn't.  Or add the 'temptemplate' option: template
+    for the temp file name ":set temptemplate=/usr/tmp/?????.tmp".
+    Also: Win32 version uses Windows temp directory, which might not work for
+    cygwin bash.
+7   Get error "*, \+ or \( operand could be empty" for pattern "\(.\)\1\{3}".
+    Remember flags for backreferences.
+7   When switching to Daylight Saving Time, Vim complains that a file has been
+    changed since last read.  Can we use a function that uses GMT?
+7   When completing an environment variable after a '$', check for file names
+    that contain a '$' after all have been found.
+8   When "cm" termcap entry is missing, starting gvim shouldn't complain about
+    it. (Lohner)  Try out with "vt100" entry, cm replaced with cX.
+7   When an include file starts with "../", the check for already visiting
+    this file doesn't work.  Need to simplify the file name.
+7   The names and comments for the arguments of do_browse() are confusing.
+    "dflt" isn't the default file name when "initdir" is not NULL and
+    "initdir" is the default path to be used.
+7   When 'scrolloff' is exactly half the window height, "j" causes a scroll of
+    two lines at a time.  "k" doesn't do this. (Cory T. Echols)
+8   When write_viminfo() is used while there are many orphaned viminfo
+    tempfiles writing the viminfo file fails.  Give a clear error message so
+    that the user knows he has to delete the files.
+7   It's possible to redefine a script-local function with ":func
+    <SNR>123_Test()". (Krishna)  Disallow this.
+
+
+I can't reproduce these (if you can, let me know how!):
+9   NT 4.0 on NTFS file system: Editing ".bashrc" (drag and drop), file
+    disappears.  Editing ".xyz" is OK.  Also, drag&drop only works for three
+    files. (McCollister)
+
+
+Problems that will (probably) not be solved:
+-   GTK: when using the popup menu with spelling suggestions and releasing the
+    right mouse button before the menu appears selecting an item with the
+    right mouse button has no effect.  GTK does not produce an event for this.
+-   xterm title: The following scenario may occur (esp. when running the Vim
+    test script): Vim 1 sets the title to "file1", then restores the title to
+    "xterm" with an ESC sequence when exiting.  Vim 2 obtains the old title
+    with an X library call, this may result in "file1", because the window
+    manager hasn't processed the "xterm" title yet.  Can apparently only be
+    worked around with a delay.
+-   In a terminal with 'mouse' set such that the mouse is active when entering
+    a command line, after executing a shell command that scrolls up the
+    display and then pressing ":": Selecting text with the mouse works like
+    the display wasn't scrolled.  Vim doesn't know how much the external
+    command scrolled up the display.  Use Shift to select text.
+-   X windows: When $DISPLAY points to a X server where there is no access
+    permission, trying to connect to the X server causes an error message.
+    XtOpenDisplay() prints this directly, there is no way to avoid it.
+-   X windows: Setting 'guifontset' to an illegal value sometimes crashes Vim.
+    This is caused by a fault in a X library function, can't be solved in Vim.
+-   Win32 tcl: has("tcl") hangs when the tcl84.dll is from cygwin.
+-   Motif: When adding a menu item "Find this &Symbol", the "s" in "this" will
+    be underlined, instead of in "Symbol".  Motif doesn't let us specify which
+    character gets the highlighting.
+-   Moving the cursor removes color in color-xterm.  This is a color-xterm
+    problem!  color-xterm ver. 6.1 beta 3 and later work properly.
+-   In zsh, "gvim&" changes the terminal settings.  This is a zsh problem.
+    (Jennings)
+-   Problem with HPterm under X: old contents of window is lost (Cosentino).
+-   Amiga: When using quickfix with the Manx compiler we only get the first 25
+    errors.  How do we get the rest?
+-   Amiga: The ":cq" command does not always abort the Manx compiler.  Why?
+-   Linux: A file with protection r--rw-rw- is seen readonly for others.  The
+    access() function in GNU libc is probably wrong.
+-   MSDOS: When using smartdrive with write-back buffering, writing to a
+    readonly floppy will cause problems.  How to test for a writable floppy
+    first?
+-   MSDOS: Both 16 and 32 bit versions: File name expansion doesn't work for
+    names that start with a dot.  These used to be illegal file names.
+-   When doing a CTRL-Z and typing a command for the shell, while Vim is busy
+    (e.g. writing a file), the command for the shell is sometimes eaten by Vim,
+    because the terminal mode is changed from RAW to CBREAK.
+-   An old version of GNU tgoto can't handle the terminfo code for "AF".  The
+    "%p1" is interpreted as "%p" and "1", causing color not to be working.
+    Fix: Change the "%p1" in the "AF" and "AB" terminfo entries to "%p".
+    (Benzinger).
+-   When running an external command from the GUI, typeahead is going to that
+    program, not to Vim.  It looks like the shell eats the characters, Vim
+    can't get back what the external command didn't use.
+-   Win32 GUI: Error code from external command not returned in shell_error.
+    It appears that cmd.exe and command.com don't return an error code.
+-   Win32 GUI: The Toolbar is a bit too high when the flat style is being
+    used.  We don't have control over the height of the Toolbar.
+-   Win32: All files created on the day of switching from winter to summer
+    time cause "changed since editing started" messages.  It goes away when
+    the file is written again the next day, or the timezone is adjusted.
+    DJGPP version is OK. (Zaimi)  Looks like a problem with the Win32 library.
+    Rebooting doesn't help.  Time stamps look OK in directory. (Penn)
+    Is this on FAT (stores wall clock time) or NTFS (stores UTS)?
+-   Win32, MS-Windows XP: $HOME uses the wrong drive when the user profiles
+    are not on the boot disk.  This is caused by a wrong value of $HOMEDRIVE.
+    This is a bug in XP, see MSKB article 818134.
+-   SunOS 5.5.1 with Motif: The file open dialog does not have a horizontal
+    scroll bar for the "files" selection.  This is a problem in the Motif
+    libraries, get a patch from Sun.
+-   Solaris 2.6 with GTK and Perl: gvim crashes when started.  Problem with X
+    input method called from GDK code.  Without Perl it doesn't crash.
+-   VMS: Vimdiff doesn't work with the VMS diff, because the output looks
+    different.  This makes test 47 fail.  Install a Unix-compatible diff.
+-   VMS v7.1 and older: Tests 21 and 32 fail.  From VMS v7.1-2 and newer Vim
+    does not have this behavior. (Zoltan Arpadffy)
+-   Win32 GUI: mouse wheel always scrolls rightmost window.  The events arrive
+    in Vim as if the rightmost scrollbar was used.
+-   GTK with Gnome: Produces an error message when starting up:
+	Gdk-WARNING **: locale not supported by C library
+    This is caused by the gnome library gnome_init() setting $LC_CTYPE to
+    "en_US".  Not all systems support this locale name, thus causing the
+    error.  Hopefully a newer version of GTK/Gnome fixes this problem.
+-   GTK 2: With this mapping the hit-enter prompt is _sometimes_ below the
+    screen, at other times there is a grey area below the command line:
+	:nmap <F11> :if &guioptions=~'m' \| set guioptions-=m \| else \| set guioptions+=m \| endif<cr>
+-   GTK: When pasting a selection from Vim to xclipboard gvim crashes with a
+    ABRT signal.  Probably an error in the file gdkselection.c, the assert
+    always fails when XmbTextListToTextProperty() fails. (Tom Allard)
+-   GTK 2: gives an assertion error for every non-builtin icon in the toolbar.
+    This is a GTK 2.4.x bug, fixed in GTK 2.4.2. (Thomas de Grenier de Latour)
+-   When using an xterm that supports the termresponse feature, and the 't_Co'
+    termcap option was wrong when Vim started, it will be corrected when the
+    termresponse is received.  Since the number of colors changes, the
+    highlighting needs to be initialized again.  This may cause colors defined
+    in the vimrc file to be lost.
+-   On Windows NT 4.0 the number of files passed to Vim with drag&drop and
+    "Edit with Vim" is limited.  The maximum command line length is 255 chars.
+
+---------------------  extensions and improvements ----------------------
+						    *extensions-improvements*
+
+Didn't make it into Vim 7.0:
+-   Add COLUMN NUMBERS to ":" commands ":line1,line2[col1,col2]cmd".  Block
+    can be selected with CTRL-V.  Allow '$' (end of line) for col2.
+-   Add DEBUGGER INTERFACE.  Implementation for gdb by Xavier de Gaye.
+    Should work like an IDE.  Try to keep it generic.  Now found here:
+    http://clewn.sf.net.
+    And the idevim plugin/script.
+    To be able to start the debugger from inside Vim: For GUI run a program
+    with a netbeans connection; for console: start a program that splits the
+    terminal, runs the debugger in one window and reconnect Vim I/O to the
+    other window.
+    Wishes for NetBeans commands:
+    - make it possible to have 'defineAnnoType' also handle terminal colors.
+    - send 'balloonText' events for the cursor position (using CursorHold ?)
+      in terminal mode.
+-   ECLIPSE plugin.  Problem is: the interface is very complicated.  Need to
+    implement part in Java and then connect to Vim.  Some hints from Alexandru
+    Roman, 2004 Dec 15.  Should then also work with Oracle Jdeveloper, see JSR
+    198 standard http://www.jcp.org/en/jsr/detail?id=198.
+    Eclim does it: http://eclim.sourceforge.net/  (Eric Van Dewoestine)
+    Plugin that uses a terminal emulator: http://vimplugin.sf.net
+    And another one: http://www.satokar.com/viplugin/index.php
+-   STICKY CURSOR: Add a way of scrolling that leaves the cursor where it is.
+    Especially when using the scrollbar.  Typing a cursor-movement command
+    scrolls back to where the cursor is.
+-   Running a shell command from the GUI still has limitations.  Look into how
+    the terminal emulator of the Vim shell project can help:
+    http://vimshell.wana.at
+-   Add Lua interface? (Wolfgang Oertl)
+8   Add a command to jump to a certain kind of tag.  Allow the user to specify
+    values for the optional fields.  E.g., ":tag size type=m".
+    Also allow specifying the file and command, so that the result of
+    taglist() can be used.
+-   X11: Make it possible to run Vim inside a window of another program.
+    This can be done with XReparentWindow().  But how exactly?
+
+
+Documentation:
+8   List of Vim runtime directories.  dotvim.txt from Charles Campbell, 2007
+    Feb 20.
+8   The GUI help should explain the Find and Find/Replace dialogs.  Add a link
+    to it from ":promptrepl" and ":promptfind".
+8   List of options should mention whether environment variables are expanded
+    or not.
+8   Extend usr_27.txt a bit. (Adam Seyfarth)
+7   Add a section on debugging scripts in the user manual.
+9   Make the Reference Manual more precise.  For each command mention:
+    - change to cursor position and curswant
+    - if it can be undone (u/CTRL-R) and redone (.)
+    - how it works for folded lines
+    - how it works with multi-byte characters
+9   In change.txt, remark about Javadoc isn't right.  Right alignment would
+    work too.
+8   Spread the windows commands over the other files.  For example, ":stag"
+    should be with ":tag".  Cross-link with tags to avoid too much double
+    text.
+8   Add tags for all features, e.g. "gui_running".
+7   MS-Windows: When a wrong command is typed with an ALT key, give a hint to
+    look at the help for 'winaltkeys'.
+7   Add a help.vim plugin that maps <Tab> to jump to the next tag in || and
+    <C-Tab> (and <S-Tab>) to the previous tag.
+-   Check text editor compendium for vi and Vim remarks.
+
+
+Help:
+-   First try using the ":help" argument literally, before using it as a
+    pattern.  And then match it as part of a tag.
+-   When a help item has multiple matches make it possible to use ":tn" to go
+    to the other matches.
+-   Support a way to view (and edit) .info files.
+-   Default mapping for help files: <Tab> to position cursor on next |:tag|.
+-   Implement a "sticky" help window, some help text lines that are always
+    displayed in a window with fixed height. (Guckes)  Use "~/.vimhelp" file,
+    user can edit it to insert his favorite commands, new account can contain a
+    default contents.
+-   Make 'winminheight' a local option, so that the user can set a minimal
+    height for the help window (and other windows).
+-   ":help :s^I" should expand to ":help :substitute".
+-   Make the help key (<F1>) context sensitive?
+-   Learn mode: show short help while typing commands.
+
+
+User Friendlier:
+8   Windows install with NSIS: make it possible to do a silent install, see
+    http://nsis.sourceforge.net/Docs/Chapter4.html#4.12
+8   Windows install with install.exe: Use .exe instead of .bat files for
+    links, so that command line arguments are passed on unmodified? (Walter
+    Briscoe)
+8   Windows install: Be able to associate Vim with a selection of file types?
+8   Windows uninstall: Have uninstal.c delete the vimfiles directories that
+    dosinst.c creates.  List the contents of the directory (recursively) if
+    the user asks for it.  Requires an implementation of "rm -rf".
+8   Remember the name of the vimrc file that was used (~/.vimrc, $VIM/_vimrc,
+    $HOME/_vimrc, etc.) and add "edit vimrc" to the File menu.
+-   Add a way to save local settings and mappings into a new plugin file.
+    ":mkplugin <file>"?
+8   Add ":plugininstall" command.  Can be used to install a plugin file that
+    includes documentation.  Let the user select a directory from
+    'runtimepath'.
+	" Vim plugin
+	<main plugin code>
+	" >>> plugin help start <<<
+	<plugin docs>
+-   Add mappings local to a window: ":map <window> ..."?
+9   Add buffer-local menu.  Should offer a choice between removing the menu or
+    disabling it.  Be careful that tear-offs don't disappear (keep one empty
+    item?).
+    Alternative: use BufEnter and BufLeave autocommands.
+8   make a vimtutor script for Amiga and other systems.
+7   Add the arguments for configure to the ":version" output?
+7   When Vim detects a file is being edited elsewhere and it's a gvim session
+    of the same user it should offer a "Raise" button, so that the other gvim
+    window can be displayed. (Eduard)
+8   Support saving and restoring session for X windows?  It should work to do
+    ":mksession" and use "-S fname" for the restart command.  The
+    gui_x11_wm_protocol_handler() already takes care of the rest.
+    global_event_filter() for GTK.
+
+
+Tab pages:
+9   GUI implementation for the tab pages line for other systems.
+7   GUI: Control over the appearance of the text in the labels (bold, color,
+    font, etc.)
+9   Make it possible to drag a tab page label to another position with the
+    mouse.
+8   Make GUI menu in tab pages line configurable.  Like the popup menu.
+8   balloons for the tab page labels that are shortened to show the full path.
+8   :tabmove +N	 move tab page N pages forward
+8   :tabmove -N	 move tab page N pages backward
+7   :tabdup	 duplicate the tab with all its windows.
+7   Option to put tab line at the left or right?  Need an option to specify
+    its width.  It's like a separate window with ":tabs" output.
+7   Add local variables for each tab page?
+8   Add local options for each tab page?  E.g., 'diffopt' could differ between
+    tab pages.
+7   Add local highlighting for each tab page?
+7   Add local directory for tab pages?  How would this interfere with
+    window-local directories?
+
+
+Spell checking:
+-   Support more regions? Caolan McNamara argues it's needed for es_XX.
+    https://bugzilla.redhat.com/bugzilla/show_bug.cgi?id=219777    
+-   Unicode defines another quote character: 0x2019.  Use it as an equivalent
+    of a single quote, thus use it as a word character like a quote and match
+    with words, replacing the curly quote with a single quote.
+-   Could filter &eacute; things for HTML before doing spell checking.
+    Similarly for TeX.
+-   The Hungarian spell file uses four extra characters in the FOL/UPP/LOW
+    items than other spell files with the ISO-8859-2 encoding, that causes
+    problem when changing 'spelllang'.  There is no obvious way to fix this.
+-   Considering Hunspell 1.1.4:
+    What does MAXNGRAMSUGS do?
+    Is COMPLEXPREFIXES necessary when we have flags for affixes?
+-   There is no Finnish spell checking file.  For openoffic Voikko is now
+    used, which is based on Malaga: http://home.arcor.de/bjoern-beutel/malaga/
+    (Teemu Likonen)
+8   ":mkspell" still takes much too long in Hungarian dictionary from
+    hunspell.  Only solution appears to be to postpone secondary suffixes.
+8   Handle postponed prefix with COMPOUNDPERMITFLAG or COMPOUNDFORBIDFLAG.
+    WFP_COMPPERMIT and WFP_COMPFORBID
+8   implement use of <compoptions> in .spl file:
+    implement CHECKCOMPOUNDREP: when a compound word seems to be OK apply REP
+    items and theck if the result is a valid word.
+    implement CHECKCOMPOUNDDUP
+    implement CHECKCOMPOUNDTRIPLE
+    Add CHECKCOMPOUNDCASE: when compounding make leading capital lower case.
+    How is it supposed to work?
+8   implement using CHECKCOMPOUNDPATTERN: match words with sl_comppat[].
+-   Add a command the repeats ]s and z=, showing the misspelled word in its
+    context.  Thus to spell-check a whole file.
+-   suggestion for "KG" to "kg" when it's keepcase.
+-   For flags on affixes: Use a "AFFCOMPSET" flag; means the compound flags of
+    the word are not used.
+-   Support breakpoint character ? 0xb7 and ignore it?  Makes it possible to
+    use same wordlist for hyphenation.
+-   Compound word is accepted if nr of words is <= COMPOUNDWORDMAX OR nr of
+    syllables <= COMPOUNDSYLMAX.  Specify using AND in the affix file?
+-   NEEDCOMPOUND also used for affix?  Or is this called ONLYINCOMPOUND now?
+    Or is ONLYINCOMPOUND only for inside a compound, not at start or end?
+-   Do we need a flag for the rule that when compounding is done the following
+    word doesn't have a capital after a word character, even for Onecap words?
+-   New hunspell home page: http://hunspell.sourceforge.net/
+    - Version 1.1.0 is out now, look into that.
+    - Lots of code depends on LANG, that isn't right.  Enable each mechanism
+      in the affix file separately.
+    - Example with compounding dash is bad, gets in the way of setting
+      COMPOUNDMIN and COMPOUNDWORDMAX to a reasonable value.
+    - PSEUDOROOT == NEEDAFFIX
+    - COMPOUNDROOT -> COMPOUNDED?  For a word that already is a compound word
+	    Or use COMPOUNDED2, COMPOUNDED3, etc.
+8   Alternate Dutch word list at www.nederlandsewoorden.nl (use script to
+    obtain).  But new Myspell wordlist will come (Hagen)
+-   CIRCUMFIX: when a word uses a prefix marked with the CIRCUMFIX flag, then
+    the word must also have a suffix marked with the CIRCUMFIX flag.  It's a
+    bit primitive, since only one flag is used, which doesn't allow matching
+    specific prefixes with suffixes.
+    Alternative:
+	PSFX {flag} {pchop} {padd} {pcond} {schop} {sadd}[/flags] {scond}
+    We might not need this at all, you can use the NEEDAFFIX flag and the
+    affix which is required.
+-   When a suffix has more than one syllable, it may count as a word for
+    COMPOUNDWORDMAX.
+-   Add flags to count extra syllables in a word.  SYLLABLEADD1 SYLLABLEADD2,
+    etc.?  Or make it possible to specify the syllable count of a word
+    directly, e.g., after another slash: /abc/3
+-   MORPHO item in affix file: ignore TAB and morphological field after
+    word/flags and affix.
+-   Implement multiple flags for compound words and CMP item?
+    Await comments from other spell checking authors.
+-   Also see tklspell: http://tkltrans.sourceforge.net/
+8   Charles Campbell asks for method to add "contained" groups to existing
+    syntax items (to add @Spell).
+    Add ":syntax contains {pattern} add=@Spell" command?  A bit like ":syn
+    cluster" but change the contains list directly for matching syntax items.
+-   References: MySpell library (in OpenOffice.org).
+	http://spellchecker.mozdev.org/source.html
+	http://whiteboard.openoffice.org/source/browse/whiteboard/lingucomponent/source/spellcheck/myspell/
+      author: Kevin Hendricks <kevin.hendricks@sympatico.ca>
+8   Make "en-rare" spell file?  Ask Charles Campbell.
+8   The English dictionaries for different regions are not consistent in their
+    use of words with a dash.
+7   Insert mode completion mechanism that uses the spell word lists.
+8   Add hl groups to 'spelllang'?
+	:set spelllang=en_us,en-rare/SpellRare,en-math/SpellMath
+    More complicated: Regions with different languages?  E.g., comments
+    in English, strings in German (po file).
+
+
+Diff mode:
+8   Use diff mode to show the changes made in a buffer (compared to the file).
+    Use an unnamed buffer, like doing:
+	new | set bt=nofile | r # | 0d_ | diffthis | wincmd p | diffthis
+    Also show difference with the file when editing started?  Should show what
+    can be undone. (Tom Popovich)
+7   Add cursor-binding: when moving the cursor in one diff'ed buffer, also
+    move it in other diff'ed buffers, so that CTRL-W commands go to the same
+    location.
+
+
+Folding:
+    (commands still available: zI zJ zK zp zP zq zQ zV zy zY;
+    secondary: zB zS zT zZ, z=)
+8   Vertical folds: looks like vertically split windows, but the cursor moves
+    through the vertical separator, separator moves when scrolling.
+8   Add "z/" and "z?" for searching in not folded text only.
+9   Add search pattern item to only match in closed or open fold and/or fold
+    with certain level.  Allows doing ":g/pat/cmd" to work on closed folds.
+8   Add different highlighting for a fold line depending on the fold level.
+    (Noel Henson)
+7   Use "++--", "+++--" for different levels instead of "+---" "+----".
+8   When a closed fold is displayed open because of 'foldminlines', the
+    behavior of commands is still like the fold is closed.  How to make the
+    user aware of this?
+8   Add an option 'foldskip' with values like 'foldopen' that specifies which
+    commands skip over a closed fold.
+8   "H" and "L" count buffer lines instead of window lines. (Servatius Brandt)
+8   Add a way to add fold-plugins.  Johannes Zellner has one for VB.
+7   When using manual folding, the undo command should also restore folds.
+-   Allow completely hiding a closed fold.  E.g., by setting 'foldtext' to an
+    empty string.  Require showing a character in 'foldcolumn' to avoid the
+    missing line goes unnoticed.
+    How to implement this?
+-   When pressing the down arrow of a scrollbar, a closed fold doesn't scroll
+    until after a long time.  How to make scrolling with closed folds
+    smoother?
+-   When creating a session, also store folds for buffers in the buffer list,
+    using the wininfo in wi_folds.
+-   When currently editing the first file in the argument list the session
+    file can contain:
+	args version.c main.c
+	edit version.c
+    Can editing version.c twice be avoided?
+-   'foldmethod' "textobject": fold on sections and paragraph text objects.
+-   Add 'hidecomment' option: don't display comments in /* */ and after //.
+    Or is the conceal patch from Vince Negri a more generic solution?
+-   "zuf": undo change in manual fold. "zUf" redo change in manual fold.  How
+    to implement this?
+-   "zJ" command: add the line or fold below the fold in the fold under the
+    cursor.
+-   'foldmethod' "syntax": "fold=3" argument: set fold level for a region or
+    match.
+-   Apply a new foldlevel to a range of lines. (Steve Litt)
+8   Have some way to restrict commands to not folded text.  Also commands like
+    searches.
+
+
+Multi-byte characters:
+-   When editing a file with both utf-8 and latin1 text Vim always falls back
+    to latin1.  Add a command to convert the latin1 characters to utf-8?
+	:unmix utf-8,latin1 filename
+    Would only work when 'encoding' is utf-8.
+9   When the tail byte of a double-byte character is illegal (e.g., a CR), the
+    display is messed up (Yasuhiro Matsumoto).  Should check for illegal
+    double-byte characters and display them differently (display each single
+    byte).
+8   Add an item in 'fileencodings' to check the first lines of a file for
+    the encoding.  See Python PEP: http://www.python.org/peps/pep-0263.html.
+    To avoid getting a wrong encoding only accept something Emacs-like:
+    "-*- coding: enc-na_me.foo -*-" and "-*- coding= enc-na_me.foo -*-"
+    Match with "-\*-\s*coding[:=]\s*\([::word::-_.]\+\)\s*-\*-" and use first
+    item.
+8   Add an item in 'fileencodings' to check the first line of an XML file for
+    the encoding.  <?xml version="1.0" encoding="UTF-8"?>  Or "charset=UTF-8"?
+    For HTML look for "charset=utf-8".
+8   The quickfix file is read without conversion, thus in 'encoding'.  Add an
+    option to specify the encoding of the errorfile and convert it.  Also for
+    ":grep" and ":helpgrep".
+    More generic solution: support a filter (e.g., by calling a function).
+8   When a file was converted from 'fileencoding' to 'encoding', a tag search
+    should also do this on the search pattern. (Andrzej M. Ostruszka)
+7   When converting a file fails, mention which byte could not be converted,
+    so that the user can fix the problem.
+8   Add configure option to be able to disable using the iconv library. (Udo
+    Schweigert)
+9   'aleph' should be set to 1488 for Unicode. (Zvi Har'El)
+8   Should add test for using various commands with multi-byte characters.
+8   'infercase' doesn't work with multi-byte characters.
+8   toupper() function doesn't handle byte count changes.
+7   When searching, should order of composing characters be ignored?
+8   Should implement 'delcombine' for command line editing.
+8   Detect overlong UTF-8 sequences and handle them like illegal bytes.
+8   ":s/x/\u\1/" doesn't work, making uppercase isn't done for multi-byte
+    characters.
+8   UTF-8: "r" in Visual mode doesn't take composing characters.
+8   UTF-8: When there is a precomposed character in the font, use it instead
+    of a character and a composing character.  See xterm for an example.
+7   When a character can't be displayed, display its digraph instead.
+    'display' option to specify this.
+7   Use ideas for nl_langinfo() from Markus Kuhn in enc_default():
+    (www.cl.cam.ac.uk/~mgk25/ucs/langinfo.c)
+-   GTK and Win32: Allow selecting fonts for 'guifontset' with the
+    fontselector somehow.
+-   GTK and Win32: make it possible to set the font for the menu to make it
+    possible to have 'encoding' different from the current locale.
+-   dbcs_class() only works for Japanese and Korean.  Implement this for
+    other encodings.  The "euc-jp" and "euc-kr" choices might be wrong.
+-   Find some way to automatically select the right GUI font or fontset,
+    depending on the default value of 'encoding'.
+    Irrelevant in the GTK+ 2 GUI so long as UTF-8 is used.
+    For Windows, the charset_pairs[] table could be used.  But how do we know
+    if a font exists?
+-   Do keyboard conversion from 'termencoding' to 'encoding' with
+    convert_input() for Mac GUI and RiscOS GUI.
+-   Add mnemonics from RFC1345 longer than two characters.
+    Support CTRL-K _{mnemonic}_
+7   In "-- INSERT (lang) --" show the name of the keymap used instead of
+    "lang". (Ilya Dogolazky)
+-   Make 'langmap' accept multi-byte characters.
+	Patch from Konstantin Korikov, 2006 Oct 15.
+-   Make 'breakat' accept multi-byte characters.  Problem: can't use a lookup
+    table anymore (breakat_flags[]).
+    Simplistic solution: when 'formatoptions' contains "m" also break a line
+    at a multi-byte character >= 0x100.
+-   Do we need the reverse of 'keymap', like 'langmap' but with files and
+    multi-byte characters?  E.g., when using a Russian keyboard.
+-   Add the possibility to enter mappings which are used whenever normal text
+    could be entered.  E.g., for "f" command.  But not in Normal mode.  Sort
+    of opposite of 'langmap'.  Use ":tmap" command?
+-   When breaking a line, take properties of multi-byte characters into
+    account.  The "linebreak" program from Bruno Haible can do it:
+    ftp://ftp.ilog.fr/pub/Users/haible/gnu/linebreak-0.1.tar.gz
+    But it's very complicated...
+
+
+Printing:
+7   Implement "undercurl" for printing.
+-   Add "page width" to wrap long lines.
+-   Win32: use a font dialog for setting 'printfont'.  Can reuse the code for
+    the 'guifont' dialog, put the common code in a separate function.
+-   Add the file timestamp to the page header (with an option). (George
+    Reilly)
+-   Win32: when 'printfont' is empty use 'guifont'.
+-   Unix: Use some dialog box to do the obvious settings (paper size, printer
+    name, portrait/landscape, etc).
+-   PostScript: Only works for text that can be converted to an 8-bit
+    character set.  How to support Unicode fully?
+-   Allow specifying the paper size, instead of using a standard size.  Same
+    units as for the margins.
+-   Support right-to-left text?
+8   Make the foreground color darkening function preserve the hue of the
+    color.
+
+
+Syntax highlighting:
+8   Make ":syn off" use 'runtimepath' instead of $VIMRUNTIME. (Gary Johnson)
+    Should do the same for ":syn on" and ":syn manual".
+8   Support "containedin" argument for ":syn include", so that the defined
+    cluster can be added to existing syntax items.
+8   C syntax: Don't highlight {} as errors inside () when used like this:
+    "({ something })", often used in GCC code.
+7   Add a "startgroup" to a region.  Used like "nextgroup" inside the region,
+    preferred item at the start of the region. (Charles Campbell)
+8   When editing a new file without a name and giving it a name (by writing
+    it) and 'filetype' is not set, detect the filetype.  Avoid doing it for
+    ":wq file".
+7   For "nextgroup" we have skipwhite, skipnl and skipempty.  It would be
+    really nice to be able to skip with a pattern.  Or skip with a syntax
+    group. (Nikolai Weibull, 2007 Feb 27)
+8   Make conversion to HTML faster (Write it in C or pre-compile the script).
+9   There is still a redraw bug somewhere.  Probably because a cached state is
+    used in a wrong way.  I can't reproduce it...
+7   Be able to change only the background highlighting.  Useful for Diff* and
+    Search highlighting.
+7   When 'number' is set highlight the number of the current line.
+    Must be enabled with an option, because it slows down display updating.
+8   Allow the user to add items to the Syntax menu sorted, without having to
+    change this for each release.
+8   Add a "matchcontains" for regions: items contained in the start or end
+    pattern, but not in the body.
+8   Add a "keepend-contained" argument: Don't change the end of an item this
+    one is contained in.  Like "keepend" but specified on the contained item,
+    instead of the containing item.
+8   cpp.vim: In C++ it's allowed to use {} inside ().
+8   Some syntax files set 'iskeyword'.  When switching to another filetype
+    this isn't reset.  Add a special keyword definition for the syntax rules?
+    When this is done, use vim.vim syntax highlighting for help file examples,
+    but without ":" in 'iskeyword' for syntax.
+8   Add specific syntax item to match with parens/braces that don't have a
+    "%" match.  :syntax nomatch cMatchError (,{,[,),},] [contained]
+8   Highlight the text between two matching parens (e.g., with a grey
+    background) when on one of the parens or in between them.
+    Option for the matchparen plugin?
+8   Add a command to jump to the next character highlighted with "Error".
+8   When using a cterm, and no ctermfg or ctermbg are defined, use start/stop
+    sequences.	Add remark in docs that :if 'term' == "term-name" should be
+    used.
+8   Add @spell cluster to String and Comment groups for many languages.  Will
+    allow spell checking. (Fleiner)
+8   When listing syntax items, try to sort the keywords alphabetically.  And
+    re-insert the [] if possible.
+8   Make it possible to use color of text for Visual highlight group (like for
+    the Cursor).
+8   It would be useful to make the highlight group name an expression.  Then
+    when there is a match, the expression would be evaluated to find out what
+    highlight group to use.  Could be used to check if the shell used in a
+    password file appears in /etc/shells. (Nikolai Weibull)
+	syn match =s:checkShell(v:match) contained 'pattern'
+8   Make it possible to only highlight a sub-expression of a match.  Like
+    using "\1" in a ":s" command.
+8   Support for deleting syntax items:
+    :syn keyword cTodo remove this
+    :syn match cTodo remove "pattern"
+    :syn region cString remove start="this" end="that"
+8   Add possibility to sync on something else, when the syncing in one way
+    doesn't find match.  For HTML: When no {script} is found, try looking for
+    a '<'.  (Fleiner)
+7   Replace the synchronizing method with a state machine specification?
+    Should be able to start at any line in the file, search forwards or
+    backwards, and use the result of matching a pattern.
+7   Use parsing like awk, so that e.g., a ( without a matching ) can be
+    detected.
+8   Make it possible to use "inverted" highlighting, invert the original
+    character.  For Visual mode.  (xterm-selection already does this).
+8   Highlight non-printable characters with "SpecialChar", linked to
+    "Special".  Display them with the digraph characters, if possible.
+8   Highlight the clipboard-selection with a highlight group.
+8   Be able to reset highlighting to its original (default) values.
+7   Be able to write current highlighting to a file as commands, similar to
+    ":mkvimrc".
+8   Improve c.vim:
+    - Add check for unterminated strings, with a variable to switch it on:
+      "c_strict_ansi".
+    - Detect unbalanced "#endif".  Requires looking back a long way...
+8   Add an option to restrict the updating of syntax highlighting to the
+    current line while in Insert mode.
+8   When guessing value of 'background', the syntax file has already been
+    loaded (from the .gvimrc).	After changing 'background', load it again?
+8   Add ":syn resync" command, to re-parse the whole file until the current
+    display position.
+8   Should support "me" offset for a region start pattern.  To be used to
+    allow searching for the end pattern inside the match of the end pattern.
+    Example: syn region pikeXX start="([^{]" end=")" should work on "()".
+8   When using a regexp for "contains=", should delay matching with it until
+    redrawing happens.  Set a flag when a group is added, check this flag when
+    highlighting starts.
+8   Some terminals can display colors like the GUI.  Add some setting to use
+    GUI colors for the terminal?  With something to define the escape
+    sequence.
+7   It's possible for an item to be transparent, so that the colors of an item
+    lower on the stack is used.  Also do this with highlighting, so that the
+    user can set transparent highlighting?  E.g. a number in a C comment would
+    get the color of a comment, a number in an assignment Normal. (Nikolai
+    Weibull)
+7   Add "semitrans": Add highlighting.  E.g., make the text bold, but keep the
+    colors.  And add colors, so that Green+Red becomes Yellow.
+    E.g. for this html:
+	<B> bold text <I> italic+bold text </B> italic text </I>
+7   Wild idea: Not only set highlighting, but also change what is displayed
+    (e.g., remove characters, so that "<B>bold</B>" can be shown as "bold"):
+	:syn region boldstuff start="<B>" display="" end="</B>" display=""
+7   CTRL-] checks the highlight group for finding out what the tag is.
+7   Add an explanation how a list of words can be used to highlight misspelled
+    words.
+8   Add more command line completion for :syntax.
+8   Add more command line completion for :highlight.
+8   Add more command line completion for :sign.
+7   Should find a better way to parse the :syntax and :highlight commands.
+    Use tables or lists that can be shared by parsing for execution and
+    completion?
+8   Add ColorSchemePost autocommand event, so that scripts can set up their
+    highlighting. (Salman Halim)
+7   Add a few sets of colors (e.g. Borland Turbo C one).  With a menu to
+    select one of the sets.
+8   Add offsets to sub-matches: "\(a*\) *"he=e1-1
+    'e' is end of match 'e1' is end of sub-match 1, 's2' is start of submatch
+    2, etc.
+8   In Insert mode, when there are typeahead characters, postpone the
+    highlighting (for "." command).
+8   Syncing on comments isn't 100% correct when / / lines mix with / * and * /.
+    For example: What about a line that starts with / / and contains * /?
+8   Ignore / * and  * / inside strings, when syncing.
+7   Build a few more syntax files from the file "/usr/share/misc/vgrindefs":
+    ISP, LDL, Icon, ratfor.  And check "nedit/source/highlight.c".
+6   Add possibility to have background color continue until the right edge of
+    the window.  Useful for comment blocks and function headings. (Rogall)
+-   Make it possible to add "contains" items for all items in a group.	Useful
+    when extending an already existing syntax file.
+-   Add line-continuation pattern for non-syncing items too?
+-   Add possibility to highlight the whole line, including the right margin
+    (for comment blocks).
+-   Add 'hlmatch' option: List of flags:
+    'c': highlight match for character under the cursor.
+    'b': highlight the previous (, and its match.
+    'a': highlight all text from the previous ( until its match.
+	 Also for {}, <>, etc.?
+    'e': highlight all braces without a match (slow?)
+    OR: add an argument "cursor" to the syntax command, which means that the
+    region/match/keyword is only highlighted when the cursor is on it.
+    (Campbell)
+    Or do it like Elvis: define text objects and how to highlight them around
+    the cursor. (Iain Truskett)
+7   Make it possible to use all words in the tags files as Keyword.
+    Can also be done with a script (but it's slow).
+7   Make it possible to call a ":" command when a match is found.  Should
+    allow for adding keywords from the text (e.g. variables that are set).
+    And allows for sections with different highlighting.
+7   Add highlight group for commandline: "Commandline".  Make sure it
+    highlights the command line while typing a command, and any output from
+    messages.  And external commands?
+8   Make a version that works like less, but with highlighting: read stdin for
+    text, exit at end of file, don't allow editing, etc.  moreim?  lessim?
+7   SpecialKey highlighting overrules syntax highlighting.  Can't give an
+    unprintable char another color.  Would be useful for ^M at end of line.
+
+
+Built-in script language:
+7   Execute a function with standard option values.  No need to save and
+    restore option values.  Especially useful for new options.  Problem: how
+    to avoid a performance penalty (esp. for string options)?
+8   Add referring to key options with "&t_xx".  Both for "echo &t_xx" and
+    ":let &t_xx =".  Useful for making portable mappings.
+-   Add ":let var ?= value", conditional assignment.  Patch by Dave Eggum,
+    2006 Dec 11.
+-   range for ":exec", pass it on to the executed command.  (Webb)
+7   ":include" command: just like ":source" but doesn't start a new scriptID?
+    Will be tricky for the list of script names.
+8   Have a look at VSEL.  Would it be useful to include? (Bigham)
+8   Add ":fungroup" command, to group function definitions together.  When
+    encountered, all functions in the group are removed.  Suggest using an
+    obscure name to avoid name clashes.  Require a ":fungroup END" in the same
+    sourced file?  Assume the group ends at the end of the file.  Handle
+    nested packages?
+    Alternative: Support packages.  {package-name}:{function-name}().
+    Packages are loaded automatically when first used, from
+    $VIMRUNTIME/packages (or use a search path).
+7   Pre-parse or compile Vim scripts into a bytecode.
+    1. Put the bytecode with the original script, with an ":if
+       has('bytecode')" around it, so that it's only used with a Vim that
+       supports it.  Update the code with a command, can be used in an
+       autocommand.
+    2. Use a ".vic" file (like Python use .pyc).  Create it when writing a
+       .vim file.  Problem: distribution.
+    3. Use a cache directory for each user.  How to recognize which cached
+       file belongs to a sourced script?
+7   Add argument to winwidth() to subtract the space taken by 'foldcolumn',
+    signs and/or 'number'.
+6   Add ++ and -- operators?  They only work on variables (lvals), how to
+    implement this?
+8   Add functions:
+	has(":command")		Check if ":command" works.  compare function
+				with "ex_ni".  E.g. for ":simalt".
+	system()		With a List argument.  Bypasses the shell, use
+				exec() directly.  (Bob Hiestand)
+	escape()		Add argument to specify what to escape with.
+	modestack()		Instead of just the current mode return the
+				stack of Insert / CTRL-O / :normal things.
+	realname()		Get user name (first, last, full)
+				user_fullname() patch by Nikolai Weibull, Nov
+				3 2002
+				Only add this when also implemented for
+				non-Unix systems, otherwise a shell cmd could
+				be used.
+				get_user_name() gets login name.
+	menuprop({name}, {idx}, {what})
+				Get menu property of menu {name} item {idx}.
+				menuprop("", 1, "name") returns "File".
+				menuprop("File", 1, "n") returns "nmenu
+				File.Open..." argument.
+				Patch by Ilya Sher, 2004 Apr 22
+				Return a list of menus and/or a dictionary
+				with properties instead.
+	mapname({idx}, mode)	return the name of the idx'th mapping.
+				Patch by Ilya Sher, 2004 Mar 4.
+				Return a list instead.
+	char2hex()		convert char string to hex string.
+	attributes()		return file protection flags "drwxrwxrwx"
+	filecopy(from, to)	Copy a file
+	shorten(fname)		shorten a file name, like home_replace()
+	perl(cmd)		call Perl and return string
+	inputrl()		like input() but right-to-left
+	virtualmode()		add argument to obtain whether "$" was used in
+				Visual block mode.
+	getacp()		Win32: get codepage (Glenn Maynard)
+	deletebufline()		delete line in any buffer
+	appendbufline()		append line in any buffer
+	libcall()		Allow more than one argument.
+	libcallext()		Like libcall(), but using a callback function
+				to allow the library to execute a command or
+				evaluate an expression.
+7   Make bufname("'0") return the buffer name from mark '0.  How to get the
+    column and line number?  col("'0") currently returns zero.
+8   argc() returns 0 when using "vim -t tag".  How to detect that no file was
+    specified in any way?  To be able to jump to the last edited file.
+8   Pass the command line arguments to Vim scripts in some way.  As v:args
+    List?  Or extra parameter to argv()?
+8   Add command arguments with three dashes, passed on to Vim scripts.
+7   Add optional arguments to user functions:
+	:func myFunc(arg1, arg2, arg3 = "blah", arg4 = 17)
+6   User functions: Functions local to buffer "b:func()"?
+8   For Strings add ":let var[{expr}] = {expr}".  When past the end of "var"
+    just ignore.
+8   The "= register should be writable, if followed by the name of a variable,
+    option or environment variable.
+8   ":let &option" should list the value of the option.
+8   ":let Func().foo = value" should work, also when "foo" doesn't exist.
+7   Add synIDlist(), making the whole list of syntax items on the syntax stack
+    available as a List.
+8   Add autocommand-event for when a variable is changed:
+	:au VarChanged {varname} {commands}
+8   Add "has("gui_capable")", to check if the GUI can be started.
+8   Add possibility to use variables like registers: characterwise (default),
+    linewise (when ending in '\n'), blockwise (when ending in '\001').	reg0,
+    rega, reg%, etc.  Add functions linewise({expr}), blockwise({expr}) and
+    charwise({expr}).
+7   Make it possible to do any command on a string variable (make a buffer
+    with one line, containing the string).  Maybe add an (invisible) scratch
+    buffer for this?
+	result = scratch(string, command)
+	result = apply(string, command)
+	result = execute(string, command)
+    "command" would use <> notation.
+    Does scratch buffer have a number?  Or re-use same number?
+7   Add function to generate unique number (date in milliseconds).
+7   Automatically load a function from a file when it is called.  Need an
+    option for the search path. (Sekera)
+
+
+Robustness:
+6   Add file locking.  Lock a file when starting to edit it with flock() or
+    fcntl().  This patch has advisory file locking while reading/writing
+    the file for Vim 5.4: ~/vim/patches/kahn_file_locking .
+    The patch is incomplete (needs support for more systems, autoconf).
+    Andy doesn't have time to work on it.
+    Disadvantage: Need to find ways to gracefully handle failure to obtain a
+    lock.  When to release a lock: When buffer is unloaded?
+
+
+Performance:
+7   For strings up to 3 bytes don't allocate memory, use v_list itself as a
+    character array.  Use VAR_SSTRING (short string).
+8   Instead of loading rgb.txt every time a color wasn't recognized load it
+    once and keep it in memory.  Move the code to a common place to avoid
+    repeating it in various system files.
+8   Turn b_syn_ic and b_syn_containedin into b_syn_flags.
+9   Loading menu.vim still takes quite a bit of time.  How to make it faster?
+8   in_id_list() takes much time for syntax highlighting.  Cache the result?
+7   setpcmark() shifts the jumplist, this takes quite a bit of time when
+    jumping around.  Instead use an index for the start?
+8   When displaying a space with only foreground highlighting, it's the same
+    as a space without attributes.  Avoid displaying spaces for the "~" lines
+    when starting up in a color terminal.
+8   Avoid alloc() for scratch buffer use, esp. in syntax.c.  It's very slow on
+    Win16.
+9   Setting GUI options in the console (e.g., 'guifont') should not cause a
+    redraw.
+8   Profiling shows that in_id_list() is used very often for C code.  Can this
+    function be improved?
+8   For an existing file, the page size of the swap file is always the
+    default, instead of using the block size of the device, because the swap
+    file is created only after setting the block size in mf_open().  How can
+    this be improved?
+8   Set default for 'ttyscroll' to half a screen height?  Should speed up
+    MS-DOS version. (Negri)
+7   C syntax highlighting gets a lot slower after ":set foldmethod=syntax".
+    (Charles Campbell)  Inserting a "{" is very slow. (dman)
+7   HTML syntax highlighting is slow for long lines.  Try displaying
+    http://www.theregister.co.uk/content/4/22908.html. (Andre Pang)
+7   Check how performance of loading the wordlist can be improved (adding a
+    lot of abbreviations).
+7   DOS console: Add t_DL support, to make scrolling faster.
+7   Compile Ex commands to byte codes.  Store byte codes in a vim script file
+    at the end, after "compiled:.  Make it look like a single comment line
+    for old Vim versions.  Insert first line "Vim script compiled <timestamp>.
+    Only used compiled code when timestamp matches the file stat.
+    Add command to compile a vim script and add it to the file in-place.
+    Split Ex command executing into a parsing and executing phase.
+    Use compiled code for functions, while loops, etc.
+8   When editing a file with extremely long lines (e.g., an executable), the
+    "linerest" in readfile() is allocated twice to be able to copy what was
+    read so far.  Use realloc() instead?  Or split the line when allocating
+    memory fails and "linerest" is big (> 100000)?
+8   When defining autocommands (e.g., from $VIMRUNTIME/filetype.vim), need to
+    compare each pattern with all existing patterns.  Use a hash code to avoid
+    using strcmp() too often?
+7   Include turbo_loader patches, speeding up reading a file?
+    Speed up reading a file by reading it into a fixed-size buffer, creating
+    the list of indexes in another buffer, and then copying the result into a
+    memfile block with two copies.  Then read the next block into another
+    fixed-size buffer, create the second list of indexes and copy text from
+    the two blocks to the memfile block.
+7   do_cmdline(): Avoid that the command line is copied to allocated memory
+    and freed again later all the time.  For while loops, and for when called
+    with an argument that can be messed with.
+    Generic solution: Make a struct that contains a pointer and a flag that
+    indicates if the pointer should be freed when replaced.
+7   Check that the file size is not more than "sizeof(long)".
+-   Further improve finding mappings in maphash[] in vgetorpeek()
+8   Syntax highlighting is slow when deleting lines.  Try in
+    $VIMRUNTIME/filetype.vim.
+-   "out of memory" after deleting (1,$d) and changing (:%s/^/> /) a lot of
+    lines (27000) a few times.  Memory fragmentation?
+-   Have a look at how pdksh does memory allocation (alloc.c). (Dalecki)
+-   Do profiling on:
+    - :g/pat/normal cmd
+    - 1000ii<Esc>
+    - deleting 10Mbyte worth of lines (netscape binary)
+    - "[i" and "[d" (Yegappan Lakshmanan)
+    - ":g/^/m0" on a 450Kbyte file.  And the "u".
+    - highlighting "~/vim/test/longline.tex", "~/vim/test/scwoop.tcl" and
+      "~/vim/test/lockup.pl".
+    - loading a syntax file to highlight all words not from a dictionary.
+    - editing a Vim script with syntax highlighting on (loading vim.vim).
+7   Screen updating can be further improved by only redrawing lines that were
+    changed (and lines after them, when syntax highlighting was used, and it
+    changed).
+    - On each change, remember start and end of the change.
+    - When inserting/deleting lines, remember begin, end, and line count.
+-   Use macros/duarte/capicua for profiling.  Nvi 1.71 is the fastest!
+-   When using a file with one long line (1Mbyte), then do "$hhhh", is still
+    very slow.  Avoid calling getvcol() for each "h"?
+-   Executing a register, e.g. "10000@@" is slow, because ins_typebuf has to
+    move the previous commands forward each time.  Pass count from
+    normal_cmd() down to do_execreg().
+-   Repeating insert "1000i-<Esc>" displays --INSERT-- all the time, because of
+    the <Esc> at the end.  Make this work faster (disable redrawing).
+-   Avoid calls to plines() for cursor line, use w_cline_height.
+-   After ":set nowrap" remove superfluous redraw with wrong hor. offset if
+    cursor is right of the screen.
+8   Make CTRL-C on Unix generate a signal, avoid using select() to check for a
+    CTRL-C (it's slow).
+
+
+Code size:
+8   GUI: When NO_CONSOLE is defined, more code can be excluded.
+-   Put getline() and cookie in a struct, so only one argument has to be
+    passed to do_cmdline() and other functions.
+8   Make a GUI-only version for Unix?
+8   In buf_write _() isn't needed when setting errmsg, do it once when using
+    it.
+7   When compiling with a GUI-only version, the code for cterm colors can be
+    left out.
+8   When compiled with a GUI-only version, the termcap entries for terminals
+    can be removed.
+8   Can the check for libelf in configure.in be removed?
+
+
+Messages:
+8   When using ":q" in a changed file, the error says to "add !".  Add the
+    command so that beginners understand it: "use :q!".
+8   For 'verbose' level 12 prints commands from source'ed files.  How to skip
+    lines that aren't executed?  Perhaps move the echoing to do_cmdline()?
+8   Use 'report' for ":bdel"?  (Krishna)  To avoid these messages when using a
+    script.
+-   Delete message after new command has been entered and have waited for key.
+    Perhaps after ten seconds?
+-   Make message history available in "msg" variables: msg1, msg2, .. msg9.
+8   When reading from stdin allow suppressing the "reading from stdin"
+    message.
+9   Check handling of overwriting of messages and delays:
+    Very wrong: errors while redrawing cause endless loop.
+    When switching to another file and screen scrolls because of the long
+    message and return must be typed, don't scroll the screen back before
+    redrawing.
+7   Add an option, which is a regexp, that disables warning messages which
+    match that regexp (Tsirkin).
+8   When address range is wrong you only get "Invalid range".  Be a bit more
+    specific: Negative, beyond last line, reverse range?  Include the text.
+8   Make it possible to ignore errors for a moment ('errorignore'?).  Another
+    option to switch off giving error messages ('errorquiet'?).  Also an option
+    not to give any messages ('quiet')?  Or ":quiet on", ":quiet off".
+    Careful: For a severe error (out of memory), and when the user starts
+    typing, error messages must be switched back on.
+    Also a flag to ignore error messages for shell commands (for mappings).
+-   Option to set time for emsg() sleep.  Interrupt sleep when key is typed?
+    Sleep before second message?
+8   In Ex silent mode or when reading commands from a file, what exactly is
+    not printed and what is?  Check ":print", ":set all", ":args", ":vers",
+    etc.  At least there should be no prompt. (Smulders)  And don't clear the
+    screen when reading commands from stdin. (Kendall)
+    --> Make a difference between informative messages, prompts, etc. and
+	error messages, printing text, etc.
+8   Window should be redrawn when resizing at the hit-enter prompt.
+    Also at the ":tselect" prompt.  Find a generic solution for redrawing when
+    a prompt is present (with a callback function?).
+
+
+Screen updating:
+7   Add a string to the 'display' option to make CTRL-E and CTRL-Y scroll one
+    screen line, also if this means the first line doesn't start with the
+    first character (like what happens with a single line that doesn't fit).
+-   screen_line():
+    - insert/delete character stuff.
+    - improve delete rest of line (spaces at end of line).
+-   When moving or resizing window, try to avoid a complete redraw (esp. when
+    dragging the status line with the mouse).
+-   When 'lazyredraw' set, don't echo :ex commands?  Need a flag to redraw when
+    waiting for a character.
+8   Add a ":refresh [winnr]" command, to force updating a window.  Useful from
+    an event handler where ":normal" can't be used.  Also useful when
+    'lazyredraw' is set in a mapping.
+7   Make 'list' and 'linebreak' work together.
+
+
+Scrolling:
+8   Add "zm" command: scroll horizontally to put the cursor in the middle.
+6   Add option to set the overlap for CTRL-F and CTRL-B. (Garhi)
+-   extend 'scrollbind' option: 'scrollopt' words "search", "relative", etc..
+    Also 'e'xecute some commands (search, vertical movements) in all bound
+    windows.
+7   Add 'scrollbind' feature to make the offset of one window with the next
+    one equal to the window height.  When editing one file in both windows it
+    looks like each window displays a page of the buffer.
+-   Allow scrolling by dragging with the mouse (grab a character and move it
+    up/down).  Like the "hand" in Acrobat reader.  Use Alt-LeftMouse for this?
+    (Goldfarb)
+-   Add command to execute some commands (search, vertical movements) in all
+    bound windows.
+-   Add 'search' option to 'scrollopt' to allow 'scrollbind' windows to
+    be bound by regexp searches
+-   Add "z>" and "z<": scroll sideways one screenful. (Campbell)
+-   Add option to set the number of lines when not to scroll, instead of the
+    fixed number used now (for terminals that scroll slow with a large number
+    of lines but not with a single line).
+
+
+Autoconf:
+8   Should use acconfig.h to define prototypes that are used by autoheader.
+8   Some compilers don't give an error for "-OPT:Olimit" but a warning. (Webb)
+    Add a check for the warning, so that "Olimit" can be added automatically?
+-   Autoconf: Use @datadir@ for the system independent files.  Make sure the
+    system dependent and system independent files are separated. (Leitner).
+-   Add autoconf check for waitpid()/wait4().
+-   Remove fcntl() from autoconf, all systems have it?
+-   Set default for 'dictionary', add search for dictionary to autoconf.
+
+
+Perl interface:
+8   Rename typemap file to something else?
+7   Make buffers accessed as Perl arrays. (Clark)
+7   Make it possible to compile with non-ANSI C?
+6   Tcl/Tk has the "load" command: load a shared library (.so or .dll).
+
+
+Shared libraries:
+6   Add support for loading shared libraries, and calling functions in it.
+	:libload internal-name libname
+	:libunload internal-name
+	:liblist
+	:libcall internal-name function(arg1, arg2, ...)
+	:libcall function(arg1, arg2, ...)
+    libcall() can have only one integer or String argument at the moment.
+6   Have a look on how Perl handles loading dynamic libraries.
+
+
+Tags:
+9   With ":set tags=./tags,../tags" and a tag appears in both tags files it is
+    added twice.  Requires figuring out the actual file name for each found
+    match.  Remove tag_fname from the match and combine it with the fname in
+    the match (without expanding or other things that take time).  When
+    'tagrelative' is off tag_fname isn't needed at all.
+8   Use a mechanism similar to omni completion to figure out the kind of tab
+    for CTRL-] and jump to the appropriate matching tag (if there are
+    several).
+7   Can CTRL-] (jump to tag) include a following "." and "->" to restrict the
+    number of possible matches? Check tags file for an item that has members.
+    (Flemming Madsen)
+8   Scope arguments for ":tag", e.g.: ":tag class:cPage open", like Elvis.
+8   When output of ":tselect" is long, getting the more-prompt, should be able
+    to type the tag number directly.
+7   Add the possibility to use the "-t {tag}" argument multiple times.  Open a
+    window for each tag.
+7   Make output of ":tselect" a bit nicer.  Use highlighting?
+7   Highlight the "tag 1 of >2" message.  New highlight group, or same as "hit
+    bottom" search message.
+7   When using ":tag" at the top of the tag stack, should add another entry,
+    so CTRL-T can bring you back to where you are now AND to where you were
+    before the previous ":tag" command. (Webb)
+-   When doing "[^I" or "[^D" add position to tag stack.
+-   Add command to put current position to tag stack: ":tpush".
+-   Add functions to save and restore the tag stack?  Or a command to switch
+    to another tag stack?  So that you can do something else and come back to
+    what you were working on.
+7   When using CTRL-] on someClass::someMethod, separate class from method and
+    use ":ta class:someClass someMethod".
+    Include C++ tags changes (Bertin).	Change "class::func" tag into "func"
+    with "class=class"?  Docs in oldmail/bertin/in.xxx.
+7   Add ":tagargs", to set values for fields:
+	:tagargs class:someclass file:version.c
+	:tagargs clear
+    These are then the default values (changes the order of priority in tag
+    matching).
+7   Support for "gtags" and "global"?  With ":rtag" command?
+    There is an example for how to do this in Nvi.
+    Or do it like Elvis: 'tagprg' and 'tagprgonce' options. (Yamaguchi)
+    The Elvis method is far more flexible, do it that way.
+7   Support "col:99" extra field, to position the cursor in that column.  With
+    a flag in 'cpoptions' to switch it off again.
+7   Better support for jumping to where a function or variable is used.  Use
+    the id-utils, with a connection to "gid" (Emacs can do it too).  Add
+    ":idselect", which uses an "ID" database (made by "mkid") like "tselect".
+
+
+Win32 GUI:
+8   Make debug mode work while starting up (vim -D).  Open console window for
+    the message and input?
+7   The Python interface only works with one version of Python, selected at
+    compile time.  Can this be made to work with version 2.1 and 2.2
+    dynamically?
+7   GvimExt: when there are several existing Vims, move the list to a submenu.
+    (Mike McCollister)
+8   When using "Edit with Vim" for one file it changes directory, when several
+    files are selected and using "Edit with single Vim" the directory isn't
+    changed.  At least change directory when the path is the same for all
+    files.  Perhaps just use the path of the first file or use the longest
+    common part of the path.
+8   Add font argument to set the lfCharSet. (Bobcik)
+8   Somehow automatically detect the system language and set $LANG, so that
+    gettext and menus work.
+8   Could keep console open to run multiple commands, to avoid the need to hit
+    return in every console.
+    Also: Look at how Emacs does runs external commands:
+	http://www.cs.washington.edu/homes/voelker/ntemacs.html.
+8   Need a separate PopUp menu for modeless selection.  Need two new commands:
+    Copy selection to clipboard, Paste selection (as typed text).
+8   Support copy/paste for other file formats.  At least HTML, perhaps RTF.
+    Add "copy special" and "paste special" commands?
+7   Use different default colors, to match the current Windows color scheme.
+    Sys_WindowText, Sys_Window, etc. (Lionel Schaffhauser)
+7   Use <C-Tab> to cycle through open windows (e.g., the find dialog).
+7   <Esc> should close a dialog.
+7   Keep the console for external commands open.  Don't wait for a key to be
+    hit.  Re-open it when the user has closed it anyway.  Or use a prepended
+    command: ":nowait {cmd}", or ":quiet", which executes {cmd} without any
+    prompts.
+7   Should be able to set an option so that when you double click a file that
+    is associated with Vim, you can either get a new instance of Vim, or have
+    the file added into an already running Vim.
+7   The "-P" argument only works for the current codepage.  Use wide
+    functions to find the window title.
+
+
+GUI:
+8   Make inputdialog() work for Photon, Amiga, RiscOS.
+-   <C--> cannot be mapped.  Should be possible to recognize this as a
+    normal "-" with the Ctrl modifier.
+7   Implement ":popup" for other systems than Windows.
+8   Implement ":tearoff" for other systems than Win32 GUI.
+6   Implement ":untearoff": hide a torn-off menu.
+8   When using the scrollbar to scroll, don't move the cursor position.  When
+    moving the cursor: scroll to the cursor position.
+9   Make <S-Insert> paste from the clipboard by default. (Kunze)
+7   Menu local to a buffer, like mappings.  Or local to a filetype?
+8   In Buffers menu, add a choice whether selecting a buffer opens it in the
+    current window, splits the window or uses ":hide".
+8   Dragging the mouse pointer outside of a Vim Window should make the text
+    scroll.  Return a value from gui_send_mouse_event() to the machine
+    specific code to indicate the time in which the event should be repeated.
+8   Make it possible to ignore a mouse click when it's used to give Vim (gvim)
+    window focus.  Also when a mouse click is used to bring a window to front.
+8   Make the split into system independent code and system specific code more
+    explicit.  There are too many #ifdefs in gui.c.
+    If possible, separate the Vim code completely from the GUI code, to allow
+    running them in separate processes.
+7   X11: Support cursorColor resource and "-cr" argument.
+8   X11 (and others): CTRL-; is not different from ';'.  Set the modifier mask
+    to include CTRL for keys where CTRL produces the same ASCII code.
+7   Add some code to handle proportional fonts on more systems?  Need to draw
+    each character separately (like xterm).  Also for when a double-width font
+    is not exactly double-width. (Maeda)
+8   Should take font from xterm where gvim was started (if no other default).
+8   Selecting font names in X11 is difficult, make a script or something to
+    select one.
+8   Visual highlighting should keep the same font (bold, italic, etc.).
+8   Add flag to 'guioptions' to not put anything in the clipboard at all?
+8   Should support a way to use keys that we don't recognize yet.  Add a
+    command that adds entries to special_keys somehow.	How do we make this
+    portable (X11, Win32, ..)?
+7   Add a flag to 'guioptions' that tells not to remove inactive menu items.
+    For systems where greying-out or removing menu items is very slow.  The
+    menu items would remain visibly normally, but not do anything.
+7   Add ":minimize" and ":maximize", which iconize the window and back.
+    Useful when using gvim to run a script (e.g. 2html.vim).
+7   X11: Is it possible to free allocated colors, so that other programs can
+    use them again?  Otherwise, allow disabling allocating the default colors.
+    Or allocate an own colormap (check UAE).  With an option to use it.  For
+    the commandline, "-install" is mostly used for X11 programs.
+7   Add command line argument for "gvim" not to start the GUI.  Sort of the
+    inverse of "vim -g". (Vikas)
+7   Should support multi-column menus.
+-   Should add option for where to put the "Help" menu: like Motif at the far
+    right, or with the other menus (but still at the right).
+-   Add menu item to "Keep Insert mode".
+8   ":mkgvimrc" command, that includes menus.
+6   Big change: Move GUI to separate program "vimgui", to make startup of vim a
+    lot faster, but still be able to do "vim -g" or ":gui".
+7   More explicit mouse button binding instead of 'mousemodel'?
+7   Add option to set the position of the window on the screen.  'windowpos',
+    which has a value of "123,456": <x>,<y>.
+    Or add a command, like ":winsize"?
+7   Add toolbar for more GUIs.
+8   Make it possible to use "amenu icon=BuiltIn##", so that the toolbar item
+    name can be chosen free.
+7   Make it possible to put the toolbar on top, left, right and/or bottom of
+    the window?  Allows for softkey-like use.
+6   Separate the part of Vim that does the editing from the part that runs the
+    GUI.  Communicate through a pseudo-tty.  Vim starts up, creates a
+    pty that is connected to the terminal.  When the GUI starts, the pty is
+    reconnected to the GUI process.  When the GUI stops, it is connected to
+    the terminal again.  Also use the pty for external processes, it looks
+    like a vt100 terminal to them.  Vim uses extra commands to communicate GUI
+    things.
+7   Motif: For a confirm() dialog <Enter> should be ignored when no default
+    button selected, <Esc> should close the dialog.
+7   When using a pseudo-tty Vim should behave like some terminal (vt52 looks
+    simple enough).  Terminal codes to/from shell should be translated.
+-   Would it be useful to be able to quit the GUI and go back to the terminal
+    where it was started from?
+7   Support "-visual <type>" command line argument.
+
+
+Autocommands:
+-   Put autocommand event names in a hashtable for faster lookup?
+7   For autocommand events that trigger multiple times per buffer (e.g.,
+    CursorHold), go through the list once and cache the result for a specific
+    buffer.  Invalidate the cache when adding/deleting autocommands or
+    changing the buffer name.
+8   Add ScriptReadCmd event: used to load remote Vim scripts, e.g.
+    "vim -u http://mach/path/vimrc".
+7   Add TagJump event: do something after jumping to a tag.
+8   Add "TagJumpFile" autocommand: When jumping to another file for a tag.
+    Can be used to open "main.c.gz" when "main.c" isn't found.
+8   Use another option than 'updatetime' for the CursorHold event.  The two
+    things are unrelated for the user (but the implementation is more
+    difficult).
+8   Add an event like CursorHold that is triggered repeatedly, not just once
+    after typing something.
+7   Add autocommand event for when a buffer cannot be abandoned.  So that the
+    user can define the action taking (autowrite, dialog, fail) based on the
+    kind of file. (Yakov Lerner)  Or is BufLeave sufficient?
+8   Autocommand for when modified files have been found, when getting input
+    focus again (e.g., FileChangedFocus).
+    Check when: getting focus, jumping to another buffer, ...
+7   Autocommand for when an option is changed.  Match buffer name or option
+    name?
+8   Autocommands should not change registers.  And marks?  And the jumplist?
+    And anything else?  Add a command to save and restore these things.
+8   Add autocommands, user functions and user commands to ":mkvimrc".
+6   Add KeymapChanged event, so that the effects of a different keymap can be
+    handled (e.g., other font) (Ron Aaron)
+7   When trying to open a directory, trigger an OpenDirectory event.
+7   Add file type in front of file pattern: <d> for directory, <l> for link,
+    <x> for executable, etc.  <&xxx> for Risc OS.  With commas to separate
+    alternatives.  The autocommand is only executed when both the file type
+    AND the file pattern match. (Leonard)
+5   Add option that specifies extensions which are to be discarded from the
+    file name.  E.g. 'ausuffix', with ".gz,.orig".  Such that file.c.gz will
+    trigger the "*.c" autocommands.  (Belabas)
+7   Add something to break the autocommands for the current event, and for
+    what follows.  Useful for a "BufWritePre" that wants to avoid writing the
+    file.
+8   When editing "tt.gz", which is in DOS format, 'fileformat' stays at
+    "unix", thus writing the file changes it.  Somehow detect that the read
+    command used dos fileformat.  Same for 'fileencoding'.
+-   Add events to autocommands:
+    Error	    - When an error happens
+    NormalEnter	    - Entering Normal mode
+    ReplaceEnter    - Entering Replace mode
+    CmdEnter	    - Entering Cmdline mode (with type of cmdline to allow
+			different mapping)
+    VisualEnter	    - Entering Visual mode
+    *Leave	    - Leaving a mode (in pair with the above *Enter)
+    VimLeaveCheck    - Before Vim decides to exit, so that it can be cancelled
+		      when exiting isn't a good idea.
+    CursorHoldC     - CursorHold while command-line editing
+    WinMoved	    - when windows have been moved around, e.g, ":wincmd J"
+    CmdUndefined    - Like FuncUndefined but for user commands.
+    SearchPost	    - After doing a search command (e.g. to do "M")
+    PreDirChanged/PostDirChanged
+		    - Before/after ":cd" has been used (for changing the
+		      window title)
+    BufReadAction   - replaces reading a file
+    BufWriteAction  - replaces writing a file
+    ShutDown	    - when the system is about to shut down
+    InsertCharPre   - user typed character Insert mode, before inserting the
+		      char.  Pattern is matched with text before the cursor.
+		      Set v:char to the character, can be changed.
+		      (not triggered when 'paste' is set).
+    InsertCharPost  - user typed a character in Insert mode, after inserting
+		      the char.
+    BufModified	    - When a buffer becomes modified, or unmodified (for
+		      putting a [+] in the window title or checking out the
+		      file from CVS).
+    BufFirstChange  - When making a change, when 'modified' is set.  Can be
+		      used to do a :preserve for remote files.
+    BufChange	    - after a change was made.  Set some variables to indicate
+		      the position and number of inserted/deleted lines, so
+		      that marks can be updated.  HierAssist has patch to add
+		      BufChangePre, BufChangePost and RevertBuf. (Shah)
+    ViewChanged	    - triggered when the text scrolls and when the window size
+		      changes.
+    WinResized	    - After a window has been resized
+    WinClose	    - Just before closing a window
+-   Write the file now and then ('autosave'):
+				  *'autosave'* *'as'* *'noautosave'* *'noas'*
+    'autosave' 'aw' number  (default 0)
+	    Automatically write the current buffer to file N seconds after the
+	    last change has been made and when |'modified'| is still set.
+	    Default: 0 = do not autosave the buffer.
+    Alternative: have 'autosave' use 'updatetime' and 'updatecount' but make
+    them save the file itself besides the swapfile.
+
+
+Omni completion:
+-   Ideas from the Vim 7 BOF at SANE:
+	- For interpreted languages, use the interpreter to obtain information.
+	  Should work for Java (Eclipse does this), Python, Tcl, etc.
+	  Richard Emberson mentioned working on an interface to Java.
+	- Check Readline for its completion interface.
+-   Ideas from others:
+	http://www.wholetomato.com/
+	http://www.vim.org/scripts/script.php?script_id=747
+	    http://sourceforge.net/projects/insenvim
+		or http://insenvim.sourceforge.net
+	    Java, XML, HTML, C++, JSP, SQL, C#
+	    MS-Windows only, lots of dependencies (e.g. Perl, Internet
+		explorer), uses .dll shared libraries.
+	    For C++ uses $INCLUDE environment var.
+	    Uses Perl for C++.
+	    Uses ctags to find the info:
+		ctags -f $allTagsFile --fields=+aiKmnsSz --language-force=C++ --C++-kinds=+cefgmnpsut-dlux -u $files
+	www.vim.org script 1213 (Java Development Environment) (Fuchuan Wang)
+	IComplete: http://www.vim.org/scripts/script.php?script_id=1265
+	    and http://stud4.tuwien.ac.at/~e0125672/icomplete/
+	http://cedet.sourceforge.net/intellisense.shtml (for Emacs)
+	Ivan Villanueva has something for Java.
+	Emads: http://www.xref-tech.com/xrefactory/more_c_completion.html
+	Completion in .NET framework SharpDevelop: http://www.icsharpcode.net
+-   Pre-expand abbreviations, show which abbrevs would match?
+
+
+Insert mode completion/expansion:
+-   GUI implementation of the popup menu.
+7   When searching in other files the name flash by, too fast to read.  Only
+    display a name every second or so, like with ":vimgrep".
+8   When there is no word before the cursor but something like "sys." complete
+    with "sys.".  Works well for C and similar languages.
+9   ^X^L completion doesn't repeat correctly.  It uses the first match with
+    the last added line, instead of continuing where the last match ended.
+    (Webb)
+8   Add option to set different behavior for Insert mode completion:
+    - ignore/match case
+    - different characters than 'iskeyword'
+8   Add option 'isexpand', containing characters when doing expansion (so that
+    "." and "\" can be included, without changing 'iskeyword'). (Goldfarb)
+    Also: 'istagword': characters used for CTRL-].
+    When 'isexpand' or 'istagword' are empty, use 'iskeyword'.
+    Alternative: Use a pattern so that start and end of a keyword can be
+    defined, only allow dash in the middle, etc.
+8   Add a command to undo the completion, go back to the original text.
+7   Completion of an abbreviation: Can leave letters out, like what Instant
+    text does: www.textware.com
+8   Use the class information in the tags file to do context-sensitive
+    completion.  After "foo." complete all member functions/variables of
+    "foo".  Need to search backwards for the class definition of foo.
+    Should work for C++ and Java.
+    Even more context would be nice: "import java.^N" -> "io", "lang", etc.
+7   When expanding $HOME/dir with ^X^F keep the $HOME (with an option?).
+7   Add CTRL-X command in Insert mode like CTRL-X CTRL-N, that completes WORDS
+    instead of words.
+8   Add CTRL-X CTRL-R: complete words from register contents.
+8   Add completion of previously inserted texts (like what CTRL-A does).
+    Requires remembering a number of insertions.
+8   Add 'f' flag to 'complete': Expand file names.
+    Also apply 'complete' to whole line completion.
+-   Make it possible to search include files in several places.  Use the
+    'path' option?  Can this be done with the dictionary completion (use
+    wildcards in the file name)?
+-   Make CTRL-X CTRL-K do a binary search in the dictionary (if it's sorted).
+-   Speed up CTRL-X CTRL-K dictionary searching (don't use a regexp?).
+-   Set a mark at the position where the match was found (file mark, could
+    be in another file).
+-   Add CTRL-A command in CTRL-X mode: show all matches.
+-   Make CTRL-X CTRL-L use the 'complete' option?
+-   Add command in CTRL-X mode to add following words to the completed string
+    (e.g. to complete "Pointer->element" with CTRL-X CTRL-P CTRL-W CTRL-W)
+-   CTRL-X CTRL-F: Use 'path' to find completions.
+-   CTRL-X CTRL-F: Option to use forward slashes on MS-Windows?
+-   CTRL-X CTRL-F: Don't replace "$VIM" with the actual value. (Kelly)
+-   Allow listing all matches in some way (and picking one from the list).
+
+
+Command line editing:
+7   Add commands (keys) to delete from the cursor to the end of the command
+    line.
+8   Custom completion of user commands can't use the standard completion
+    functions.  Add a hook to invoke a user function that returns the type of
+    completion to be done: "file", "tag", "custom", etc.
+-   Add flags to 'whichwrap' for command line editing (cursor right at end of
+    lines wraps to start of line).
+-   Make editing the command line work like Insert mode in a single-line view
+    on a buffer that contains the command line history.  But this has many
+    disadvantages, only implement it when these can be solved.  Elvis has run
+    into these, see remarks from Steve (~/Mail/oldmail/kirkendall/in.00012).
+    - Going back in history and editing a line there would change the history.
+      Would still need to keep a copy of the history elsewhere.  Like the
+      cmdwin does now already.
+    - Use CTRL-O to execute one Normal mode command.  How to switch to normal
+      mode for more commands?  <Esc> should cancel the command line.  CTRL-T?
+    - To allow "/" and "= need to recursively call getcmdline(), overwrite the
+      cmdline.  But then we are editing a command-line again.  How to avoid
+      that the user gets confused by the stack of command lines?
+    - Use edit() for normal cmdline editing?  Would have to integrate
+      getcmdline() into edit().  Need to solve conflicts between Insert mode
+      and Command-line mode commands.  Make it work like Korn shell and tcsh.
+      Problems:
+	- Insert: completion with 'wildchar'
+	- Insert: use cmdline abbreviations
+	- Insert: CTRL-D deletes indent instead of listing matches
+	- Normal: no CTRL-W commands
+	- Normal: no ":" commands?
+	- Normal: allow Visual mode only within one line.
+    - where to show insert/normal mode message?  Change highlighting of
+      character in first column?
+    - Implementation ideas:
+      - Set "curwin" and "curbuf" to the command line window and buffer.
+      - curwin->w_topline is always equal to curwin->w_cursor.lnum.
+      - never set 'number', no folding, etc.  No status line.
+      - sync undo after entering a command line?
+      - use NV_NOCL flag for commands that are not allowed in Command-line
+	Mode.
+
+
+Command line completion:
+8   Change expand_interactively into a flag that is passed as an argument.
+8   With command line completion after '%' and '#', expand current/alternate
+    file name, so it can be edited.  Also with modifiers, such as "%:h".
+8   When completing command names, either sort them on the long name, or list
+    them with the optional part inside [].
+7   Completion of ":map x ": fill in the current mapping, so that it can be
+    edited. (Sven Guckes)
+-   For 'wildmenu': Simplify "../bar" when possible.
+-   When using <Up> in wildmenu mode for a submenu, should go back to the
+    current menu, not the first one.  E.g., ":emenu File.Save<Up>".
+8   For ":find" and ":sfind" expand files found in 'path'.
+8   When using backtick expansion, the external command may write a greeting
+    message.  Add an option or commands to remove lines that match a regexp?
+7   When listing matches of files, display the common path separately from the
+    file names, if this makes the listing shorter. (Webb)
+-   Add command line completion for ":ilist" and friends, show matching
+    identifiers (Webb).
+8   Add command line completion for "old value" of a command.  ":args <key>"
+    would result in the current list of arguments, which you can then edit.
+7   Add command line completion with CTRL-X, just like Insert mode completion.
+    Useful for ":s/word/xx/".
+-   Add command to go back to the text as it was before completion started.
+    Also to be used for <Up> in the command line.
+-   Add 'wildlongest' option: Key to use to find longest common match for
+    command line completion (default CTRL-L), like 'wildchar'. (Cregut)
+    Also: when there are several matches, show them line a CTRL-D.
+
+
+Command line history:
+9   Remember which command lines were actually typed and were not loaded from
+    viminfo.  When writing viminfo append only these lines, so that lines from
+    other Vim's are not overwritten.
+-   Add "KeyWasTyped" flag: It's reset before each command and set when a
+    character from the keyboard is consumed. Value is used to decide to put a
+    command line in history or not. Put line in history if it didn't
+    completely resulted from one mapping.
+-   When using ":browse", also put the resulting edit command in the history,
+    so that it can be repeated. (Demirel)
+
+
+Insert mode:
+9   When 'autoindent' is set, hitting <CR> twice, while there is text after
+    the cursor, doesn't delete the autoindent in the resulting blank line.
+    (Rich Wales) This is Vi compatible, but it looks like a bug.
+8   When using CTRL-O in Insert mode, then executing an insert command
+    "a" or "i", should we return to Insert mode after <Esc>? (Eggink)
+    Perhaps it can be allowed a single time, to be able to do
+    "<C-O>10axyz<Esc>".  Nesting this further is confusing.
+    ":map <F2> 5aabc<Esc>" works only once from Insert mode.
+7   Use CTRL-G <count> to repeat what follows.  Useful for inserting a
+    character multiple times or repeating CTRL-Y.
+7   Use 'matchpairs' for 'showmatch': When inserting a character check if it
+    appears in the rhs of 'matchpairs'.
+-   In Insert mode (and command line editing?): Allow undo of the last typed
+    character.	This is useful for CTRL-U, CTRL-W, delete and backspace, and
+    also for characters that wrap to the next line.
+    Also: be able to undo CTRL-R (insert register).
+    Possibly use 'backspace'="whole" for a mode where at least a <CR> that
+    inserts autoindent is undone by a single <BS>.
+-   Use CTRL-G in Insert mode for an extra range of commands, like "g" in
+    Normal mode.
+-   Make 'paste' work without resetting other options, but override their
+    value.  Avoids problems when changing files and modelines or autocommands
+    are used.
+-   When typing CTRL-V and a digit higher than 2, only expect two digits.
+-   Insert binary numbers with CTRL-V b.
+-   Make it possible to undo <BS>, <C-W> and <C-U>.  Bash uses CTRL-Y.
+
+
+'cindent', 'smartindent':
+8   Lisp indenting: "\\" confuses the indenter. (Dorai Sitaram, 2006 May 17)
+8   Java: Inside an anonymous class, after an "else" or "try" the indent is
+    too small. (Vincent Bergbauer)
+    Problem of using {} inside (), 'cindent' doesn't work then.
+8   In C++ it's possible to have {} inside (): (Kirshna)
+		func(
+			new String[] {
+			    "asdf",
+			    "asdf"
+			}
+		    );
+6   Add 'cino' flag for this function argument layout: (Spencer Collyer)
+	    func( arg1
+	        , arg2
+		, arg3
+		);
+7   Add separate "(0" option into inside/outside a function (Zellner):
+	func(
+	   int x)	// indent like "(4"
+	{
+	   if (a
+	       && b)	// indent like "(0"
+9   Using "{" in a comment: (Helmut Stiegler)
+    if (a)
+    {
+	    if (b)
+	    {
+		    // {
+	    }
+	    } <-- this is indented incorrect
+    Problem is that find_start_brace() checks for the matching brace to be in
+    a comment, but not braces in between.  Requires adding a comment check to
+    findmatchlimit().
+-   Make smartindenting configurable.  Add 'sioptions', e.g. '#' setting the
+    indent to 0 should be switched on/off.
+7   Support ANSI style function header, with each argument on its own line.
+-   "[p" and "]p" should use 'cindent' code if it's on (only for the first
+    line).
+-   Add option to 'cindent' to set indent for comments outside of {}?
+-   Make a command to line up a comment after a code line with a previous
+    comment after a code line.	Can 'cindent' do this automatically?
+7   Add 'j' flag to 'formatoptions': Remove comment leader when joining lines.
+-   When 'cindent'ing a '}', showmatch is done before fixing the indent.  It
+    looks better when the indent is fixed before the showmatch. (Webb)
+-   Add option to make indenting work in comments too (for commented-out
+    code), unless the line starts with "*".
+-   Don't use 'cindent' when doing formatting with "gq"?
+-   When formatting a comment after some text, insert the '*' for the new line
+    (indent is correct if 'cindent' is set, but '*' doesn't get inserted).
+8   When 'comments' has both "s1:/*,mb:*,ex:*/" and "s1:(*,mb:*,ex:*)", the
+    'x' flag always uses the first match.  Need to continue looking for more
+    matches of "*" and remember all characters that could end the comment.
+-   For smartindent: When typing 'else' line it up with matching 'if'.
+-   'smartindent': allow patterns in 'cinwords', for e.g. TeX files, where
+    lines start with "\item".
+-   Support this style of comments (with an option): (Brown)
+	/* here is a comment that
+	is just autoindented, and
+	nothing else */
+-   Add words to 'cinwords' to reduce the indent, e.g., "end" or "fi".
+7   Use Tabs for the indent of starting lines, pad with spaces for
+    continuation lines.  Allows changing 'tabstop' without messing up the
+    indents.
+    'keeptabs': when set don't change the tabs and spaces used for indent,
+    when the indent remains the same or increases.
+
+
+Java:
+8   Can have {} constructs inside parens.  Include changes from Steve
+    Odendahl?
+8   Recognize "import java.util.Vector" and use $CLASSPATH to find files for
+    "[i" commands and friends.
+-   For files found with 'include': handle "*" in included name, for Java.
+    (Jason)
+-   How to make a "package java.util" cause all classes in the package to be
+    searched?  Also for "import java.util.*". (Mark Brophy)
+
+
+'comments':
+8   When formatting C comments that are after code, the "*" isn't repeated
+    like it's done when there is no code.  And there is no automatic wrapping.
+    Recognize comments that come after code.  Should insert the comment leader
+    when it's "#" or "//".
+    Other way around: when a C command starts with "* 4" the "*" is repeated
+    while it should not.  Use syntax HL comment recognition?
+7   When using "comments=fg:--", Vim inserts three spaces for a new line.
+    When hitting a TAB, these spaces could be removed.
+7   The 'n'esting flag doesn't do the indenting of the last (rightmost) item.
+6   Make strings in 'comments' option a RE, to be able to match more
+    complicated things. (Phillipps)  Use a special flag to indicate that a
+    regexp is used.
+8   Make the 'comments' option with "/* * */" lines only repeat the "*" line
+    when there is a "/*" before it?  Or include this in 'cindent'?
+
+
+Virtual edit:
+8   Make the horizontal scrollbar work to move the text further left.
+7   Add a mode where the cursor is only allowed to go one character after the
+    end of the line?
+7   Allow specifying it separately for Tabs and beyond end-of-line?
+
+
+Text objects:
+8   Add test script for text object commands "aw", "iW", etc.
+8   Add text object for part of a CamelHumpedWord and under_scored_word.
+    (Scott Graham)  "ac" and "au"?
+8   Add a text object for any kind of quoting, also with multi-byte
+    characters.  Option to specify what quotes are recognized (default: all)
+    use "aq" and "iq".  Use 'quotepairs' to define pairs of quotes, like
+    'matchpairs'?
+8   Add text object for any kind of parens, also multi-byte ones.
+7   Add text object for current search pattern: "a/" and "i/".  Makes it
+    possible to turn text highlighted for 'hlsearch' into a Visual area.
+8   Add a way to make an ":omap" for a user-defined text object.
+8   Add "gp" and "gP" commands: insert text and make sure there is a single
+    space before it, unless at the start of the line, and after it, unless at
+    the end of the line or before a ".".
+7   Add objects with backwards extension?  Use "I" and "A".  Thus "2dAs"
+    deletes the current and previous sentence. (Jens Paulus)
+7   Add "g{" and "g}" to move to the first/last character of a paragraph
+    (instead of the line just before/after a paragraph as with "{" and "}").
+6   Ignore comment leaders for objects.  Make "das" work in reply-email.
+5   Make it possible to use syntax group matches as a text object.  For
+    example, define a "ccItem" group, then do "da<ccItem>" to delete one.
+    Or, maybe just define "dai", delete-an-item, to delete the syntax item the
+    cursor is on.
+
+
+Select mode:
+8   In blockwise mode, typed characters are inserted in front of the block,
+    backspace deletes a column before the block. (Steve Hall)
+7   Alt-leftmouse starts block mode selection in MS Word.
+    See http://www.vim.org/tips/tip.php?tip_id=743
+7   Add Cmdline-select mode.  Like Select mode, but used on the command line.
+    - Change gui_send_mouse_event() to pass on mouse events when 'mouse'
+      contains 'C' or 'A'.
+    - Catch mouse events in ex_getln.c.  Also shift-cursor, etc., like in
+      normal_cmd().
+    - remember start and end of selection in cmdline_info.
+    - Typing text replaces the selection.
+
+
+Visual mode:
+-   When dragging the Visual selection with the mouse and 'scrolloff' is zero,
+    behave like 'scrolloff' is one, so that the text scrolls when the pointer
+    is in the top line.
+-   Displaying size of Visual area: use 24-33 column display.
+    When selecting multiple lines, up to about a screenful, also count the
+    characters.
+8   When using "I" or "A" in Visual block mode, short lines do not get the new
+    text.  Make it possible to add the text to short lines too, with padding
+    where needed.
+7   With a Visual block selected, "2x" deletes a block of double the width,
+    "3y" yanks a block of triple width, etc.
+7   When selecting linewise, using "itext" should insert "text" at the start
+    of each selected line.
+8   What is "R" supposed to do in Visual mode?
+8   Make Visual mode local to the buffer.  Allow changing to another buffer.
+    When starting a new Visual selection, remove the Visual selection in any
+    other buffer. (Ron Aaron)
+8   Support dragging the Visual area to drop it somewhere else. (Ron Aaron,
+    Ben Godfrey)
+7   Support dragging the Visual area to drop it in another program, and
+    receive dropped text from another program. (Ben Godfrey)
+7   With blockwise Visual mode and "c", "C", "I", "A", etc., allow the use of
+    a <CR>.  The entered lines are repeated over the Visual area.
+7   CTRL-V :s should substitute only in the block, not to whole lines. (David
+    Young is working on this)
+7   Filtering a block should only apply to the block, not to the whole lines.
+    When the number of lines is increased, add lines. When decreased, pad with
+    spaces or delete? Use ":`<,`>" on the command line.
+8   After filtering the Visual area, make "gv" select the filtered text?
+    Currently "gv" only selects a single line, not useful.
+7   Don't move the cursor when scrolling?  Needed when the selection should
+    stay the same.  Scroll to the cursor at any movement command.  With an
+    option!
+7   In Visual block mode, need to be able to define a corner on a position
+    that doesn't have text?  Also: when using the mouse, be able to select
+    part of a TAB.  Even more: Add a mode where the cursor can be on a screen
+    position where there is no text.  When typing, add spaces to fill the gap.
+    Other solution: Always use curswant, so that you can move the cursor to
+    the right column, and then use up/down movements to select the line,
+    without changing the column.
+6   ":left" and ":right" should work in Visual block mode.
+7   CTRL-I and CTRL-O should work in Visual mode, but only jump to marks in the
+    current buffer.
+7   CTRL-A and CTRL-X should increase/decrease all numbers in the Visual area.
+6   In non-Block mode, "I" should insert the same text in front of each line,
+    before the first non-blank, "gI" in column 1.
+6   In non-Block mode, "A" should append the same text after each line.
+6   When in blockwise visual selection (CTRL-V), allow cursor to be placed
+    right of the line.  Could also allow cursor to be placed anywhere on a TAB
+    or other special character.
+6   Add commands to move selected text, without deselecting.
+
+
+More advanced repeating commands:
+-   Add "." command for visual mode: redo last visual command (e.g. ":fmt").
+7   Repeating "d:{cmd}" with "." doesn't work. (Benji Fisher)  Somehow remember
+    the command line so that it can be repeated?
+-   Add "." command after operator: repeat last command of same operator.  E.g.
+    "c." will repeat last change, also when "x" used since then (Webb).
+    "y." will repeat last yank.
+    "c2." will repeat the last but one change?
+    Also: keep history of Normal mode commands, add command to list the history
+    and/or pick an older command.
+-   History stack for . command?  Use "g." command.
+
+
+Mappings and Abbreviations:
+8   When "0" is mapped (it is a movement command) this mapping should not be
+    used after typing another number, e.g. "20l". (Charles Campbell)
+    Is this possible without disabling the mapping of the following command?
+8   Should mapping <C-A> and <C-S-A> both work?
+7   ":abbr b byte", append "b " to an existing word still expands to "byte".
+    This is Vi compatible, but can we avoid it anyway?
+8   To make a mapping work with a prepended "x to select a register, store the
+    last _typed_ register name and access it with "&.
+8   Add ":amap", like ":amenu".
+7   Add a mapping that works always, for remapping the keyboard.
+8   Add ":cab!", abbreviations that only apply to Command-line mode and not to
+    entering search strings.
+8   Add a flag to ":abbrev" to eat the character that triggers the
+    abbreviation.  Thus "abb ab xxx" and typing "ab<Space>" inserts "xxx" and
+    not the <Space>.
+8   Allow mapping of CTRL-@ (anywhere in the LHS).
+8   Give a warning when using CTRL-C in the lhs of a mapping.  It will never
+    (?) work.
+8   Add a way to save a current mapping and restore it later.  Use a function
+    that returns the mapping command to restore it: mapcmd()?  mapcheck() is
+    not fool proof.  How to handle ambiguous mappings?
+7   Add <0x8f> (hex), <033> (octal) and <123> (decimal) to <> notation?
+7   Allow mapping "Q" and "Q}" at the same time.  Need to put a flag with "Q",
+    that it needs an extra character before it can match.  See Vile 'maplonger'
+    option.
+7   When someone tries to unmap with a trailing space, and it fails, try
+    unmapping without the trailing space.  Helps for ":unmap xx | unmap yy".
+7   Make it possible to map 'wildchar', but only when it's a special character
+    (like CTRL-E).  Currently it's only recognized when typed.  Useful for
+    mapping a key to do something and then completion.
+6   Context-sensitive abbreviations: Specify syntax group(s) in which the
+    abbreviations are to be used.
+-   Add mappings that take arguments.  Could work like the ":s" command.  For
+    example, for a mouse escape sequence:
+	:mapexp  <Esc>{\([0-9]*\),\([0-9]*\);	H\1j\2l
+-   Add optional <Number> argument for mappings:
+    :map <Number>q	     ^W^W<Number>G
+    :map <Number>q<Number>t  ^W^W<Number1-1>G<Number2>l
+    :map q<Char>	    :s/<Char>/\u\0/g
+    Or implicit:
+    :map q			<Register>d<Number>$
+-   Make it possible to include a <Nul> in the lhs and rhs of a mapping.
+-   Add command to repeat a whole mapping ("." only repeats the last change in
+    a mapping).  Also: Repeat a whole insert command, including any mappings
+    that it included.  Sort-of automatic recording?
+-   Add an option to ":map" that makes it display the special keys in
+    <> notation (e.g. <CR> instead of ^M).  Or just always do this?
+-   Include an option (or flag to 'cpoptions') that makes errors in mappings
+    not flush the rest of the mapping (like nvi does).
+-   Use context sensitiveness of completion to switch abbreviations and
+    mappings off for :unab and :unmap.
+6   When using mappings in Insert mode, insert characters for incomplete
+    mappings first, then remove them again when a mapping matches.  Avoids
+    that characters that are the start of some mapping are not shown until you
+    hit another character.
+-   Add mappings for replace mode: ":rmap".  How do we then enter mappings for
+    non-replace Insert mode?
+-   Add separate mappings for Visual-character/block/line mode?
+-   Add 'mapstop' command, to stop recursive mappings.
+-   List mappings that have a raw escape sequence both with the name of the key
+    for that escape sequence (if there is one) and the sequence itself.
+-   List mappings: Once with special keys listed as <>, once with meta chars as
+    <M-a>, once with the byte values (octal?).  Sort of "spell mapping" command?
+-   When entering mappings: Add the possibility to enter meta keys like they
+    are displayed, within <>: <M-a>, <~@> or <|a>.
+-   Allow multiple arguments to :unmap.
+-   Command to show keys that are not used and available for mapping
+    ":freekeys".
+-   Allow any character except white space in abbreviations lhs (Riehm).
+
+
+Incsearch:
+-   Add a limit to the number of lines that are searched for 'incsearch'?
+-   When no match is found and the user types more, the screen is redrawn
+    anyway.  Could skip that.  Esp. if the line wraps and the text is scrolled
+    up every time.
+-   Temporarily open folds to show where the search ends up.  Restore the
+    folds when going to another line.
+-   When incsearch used and hitting return, no need to search again in many
+    cases, saves a lot of time in big files. (Slootman wants to work on this?)
+    When not using special characters, can continue search from the last match
+    (or not at all, when there was no match).  See oldmail/webb/in.872.
+-   With incsearch, use CTRL-N/CTRL-P to go to next/previous match, some other
+    key to copy matched word to search pattern (Alexander Schmid).
+
+
+Searching:
+8   Add "g/" and "gb" to search for a pattern in the Visually selected text?
+    "g?" is already used for rot13.
+    The vis.vim script has a ":S" command that does something like this.
+    Can use "g/" in Normal mode, uses the '< to '> area.
+    Use "&/" for searching the text in the Visual area?
+8   Add a mechanism for recursiveness: "\@(([^()]*\@g[^()]*)\)".  \@g stands
+    for "go recursive here" and \@( \) marks the recursive part.
+    Perl does it this way:
+	    $paren = qr/ \(( [^()] | (??{ $paren }) )* \) /x;
+    Here $paren is evaluated when it's encountered.  This is like a regexp
+    inside a regexp.  In the above terms it would be:
+	    \@((\([^()]\|\@g\)*)\)
+8   Show the progress every second.  Could use the code that checks for CTRL-C
+    to find out how much time has passed.  Or use SIGALRM.  Where to show the
+    number?
+7   Support for approximate-regexps to find similar words (agrep
+    http://www.tgries.de/agrep/ tre: http://laurikari.net/tre/index.html).
+8   Add an item for a big character range, so that one can search for a
+    chinese character: \z[234-1234]  or \z[XX-YY] or \z[0x23-0x234].
+7   Add an item stack to allow matching ().  One side is "push X on
+    the stack if previous atom matched".  Other side is "match with top of
+    stack, pop it when it matches".  Use "\@pX" and "\@m"?
+	Example: \((\@p).\{-}\@m\)*
+7   Add an option to accept a match at the cursor position.  Also for
+    search(). (Brett)
+7   Add a flag to "/pat/" to discard an error.  Useful to continue a mapping
+    when a search fails.  Could be "/pat/E" (e is already used for an offset).
+7   Add pattern item to use properties of Unicode characters.  In Perl it's
+    "\p{L}" for a letter.  See Regular Expression Pocket Reference.
+8   Would it be possible to allow ":23,45/pat/flags" to search for "pat" in
+    lines 23 to 45?  Or does this conflict with Ex range syntax?
+8   Allow identical pairs in 'matchpairs'.  Restrict the search to the current
+    line.
+7   Allow longer pairs in 'matchpairs'.  Use ~/vim/macros/matchit.vim as an
+    example.
+8   Make it possible to define the character that "%" checks for in
+    #if/#endif.  For nmake it's !if/!endif.
+-   For "%" command: set hierarchy for which things include other things that
+    should be ignored (like "*/" or "#endif" inside /* */).
+    Also: use "%" to jump from start to end of syntax region and back.
+    Alternative: use matchit.vim
+8   "/:/e+1" gets stuck on a match at the end of the line.  Do we care?
+8   A pattern like "\([^a]\+\)\+" takes an awful long time.  Recognize that
+    the recursive "\+" is meaningless and optimize for it.
+    This one is also very slow on "/* some comment */": "^\/\*\(.*[^/]\)*$".
+7   Recognize "[a-z]", "[0-9]", etc. and replace them with the faster "\l" and
+    "\d".
+7   Add a way to specify characters in <C-M> or <Key> form.  Could be
+    \%<C-M>.
+8   Flags that apply to the whole pattern.
+    This works for all places where a regexp is used.
+    Add "\q" to not store this pattern as the last search pattern?
+8   Add an argument after ":s/pat/str/" for a range of matches.  For example,
+    ":s/pat/str/#3-4" to replace only the third and fourth "pat" in a line.
+8   Add an option not to use 'hlsearch' highlighting for ":s" and ":g"
+    commands. (Kahn)  It would work like ":noh" is used after that command.
+    Also: An extra flag to do this once, and a flag to keep the existing
+    search pattern.
+-   Add \%h{group-name}; to search for a specific highlight group.
+    Add \%s{syntax-group}; to search for a specific syntax group.
+-   Support Perl regexp.  Use PCRE (Perl Compatible RE) package. (Shade)
+    Or translate the pattern to a Vim one.
+    Don't switch on with an option for typed commands/mappings/functions, it's
+    too confusing.  Use "\@@" in the pattern, to avoid incompatibilities.
+7   Add POSIX regexp, like Nvi, with 'extended' option?  It's like very-magic.
+-   Remember flags for backreferenced items, so that "*" can be used after it.
+    Check with "\(\S\)\1\{3}". (Hemmerling)
+-   Add flags to search command (also for ":s"?):
+    i	ignore case
+    I	use case
+    p	use Perl regexp syntax (or POSIX?)
+    v	use Vi regexp syntax
+    f	forget pattern, don't keep it for "n" command
+    F   remember pattern, keep it for "n" command
+    Perl uses these too:
+    e	evaluate the right side as an expression (Perl only)
+    m	multiple line expression (we don't need it)
+    o	compile only once (Perl only)
+    s	single line expression (we don't need it)
+    x	extended regexp (we don't need it)
+    When used after ":g" command, backslash needed to avoid confusion with the
+    following command.
+    Add 'searchflags' for default flags (replaces 'gdefault').
+-   Add command to display the last used substitute pattern and last used
+    pattern. (Margo)  Maybe make it accessible through a register (like "/
+    for search string)?
+7   Use T-search algorithm, to speed up searching for strings without special
+    characters.  See C't article, August 1997.
+-   Add 'fuzzycase' option, so that case doesn't matter, and '-' and '_' are
+    equivalent (for Unix filenames).
+-   Add 'v' flag to search command: enter Visual mode, with the matching text
+    as Visual area. (variation on idea from Bertin)
+-   Searching: "/this//that/" should find "that" after "this".
+-   Add global search commands: Instead of wrapping at the end of the buffer,
+    they continue in another buffer.  Use flag after search pattern:
+    a	for the next file in the argument list
+    f	for file in the buffer list
+    w	for file edited in a window.
+    e.g. "/pat/f".  Then "n" and "N" work through files too.  "f" flag also for
+    ":s/pat/foo/f"???  Then when 'autowrite' and 'hidden' are both not set, ask
+    before saving files: "Save modified buffer "/path/file"? (Yes/Hide/No
+    Save-all/hide-All/Quit) ".
+-   ":s/pat/foo/3": find 3rd match of "pat", like sed. (Thomas Koehler)
+7   When searching with 'n' give message when getting back where the search
+    first started.  Remember start of search in '/ mark.
+7   Add option that scrolls screen to put cursor in middle of screen after
+    search always/when off-screen/never.  And after a ":tag" command.  Maybe
+    specify how many lines below the screen causes a redraw with the cursor in
+    the middle (default would be half a screen, zero means always).
+6   Support multiple search buffers, so macros can be made without side
+    effects.
+7   From xvim: Allow a newline in search patterns (also for :s, can delete
+    newline).  Add BOW, EOW, NEWL, NLORANY, NLBUTANY, magic 'n' and 'r', etc.
+    [not in xvim:] Add option to switch on matches crossing ONE line boundary.
+7   Add ":iselect", a combination of ":ilist" and ":tselect". (Aaron) (Zellner)
+    Also ":dselect".
+
+
+Undo:
+8   Undo tree: visually show the tree somehow (Damian Conway)
+    Show only the leaves, indicating how many changed from the branch and the
+    timestamp?
+    Put branch with most recent change on the left, older changes get more
+    indent?
+8   Search for pattern in undo tree, showing when it happened and the text
+    state, so that you can jump to it.
+-   Persistent undo: store undo in a file.
+    Use timestamps, so that a version a certain time ago can be found and info
+    before some time/date can be flushed. 'undopersist' gives maximum time to
+    keep undo: "3h", "1d", "2w", "1y", etc.  For the file use dot and
+    extension: ".filename.un~" (like swapfile but "un~" instead of "swp").
+8   See ":e" as a change operation, find the changes and add them to the
+    undo info.  Needed for when an external tool changes the file.
+-   Make it possible to undo all the commands from a mapping, including a
+    trailing unfinished command, e.g. for ":map K iX^[r".
+-   When accidentally hitting "R" instead of Ctrl-R, further Ctrl-R is not
+    possible, even when typing <Esc> immediately. (Grahn)  Also for "i", "a",
+    etc.  Postpone saving for undo until something is really inserted?
+8   When Inserting a lot of text, it can only be undone as a whole.  Make undo
+    sync points at every line or word.  Could recognize the start of a new
+    word (white space and then non-white space) and backspacing.
+    Can already use CTRL-G u, but that requires remapping a lot of things.
+8   Make undo more memory-efficient: Compare text before and after change,
+    only remember the lines that really changed.
+7   Add undo for a range of lines.  Can change these back to a previous
+    version without changing the rest of the file.  Stop doing this when a
+    change includes only some of these lines and changes the line count.  Need
+    to store these undo actions as a separate change that can be undone.
+-   For u_save() include the column number. This can be used to set '[ and '].
+    And in the future the undo can be made more efficient (Webb).
+-   In out-of-memory situations: Free allocated space in undo, and reduce the
+    number of undo levels (with confirmation).
+-   Instead of [+], give the number of changes since the last write: [+123].
+    When undoing to before the last write, change this to a negative number:
+    [-99].
+-   With undo with simple line delete/insert: optimize screen updating.
+-   When executing macro's: Save each line for undo only once.
+-   When doing a global substitute, causing almost all lines to be changed,
+    undo info becomes very big.  Put undo info in swap file??
+
+
+Buffer list:
+7   Command to execute a command in another buffer: ":inbuf {bufname} {cmd}".
+    Also for other windows: ":inwin {winnr} {cmd}".  How to make sure that
+    this works properly for all commands, and still be able to return to the
+    current buffer/window?  E.g.: ":inbuf xxx only".
+8   Add File.{recent_files} menu entries: Recently edited files.
+    Ron Aaron has a plugin for this: mru.vim.
+8   Unix: Check all uses of fnamecmp() and fnamencmp() if they should check
+    inode too.
+7   Add another number for a buffer, which is visible for the user.  When
+    creating a new buffer, use the lowest number not in use (or the highest
+    number in use plus one?).
+7   Offer some buffer selection from the command line?  Like using ":ls" and
+    asking for a buffer number. (Zachmann)
+-   When starting to edit a file that is already in the buffer list, use the
+    file name argument for the new short file name. (Webb)
+-   Add an option to make ":bnext" and ":bprev" wrap around the end of the
+    buffer list.  Also for ":next" and ":prev"?
+7   Add argument to ":ls" which is a pattern for buffers to list.
+    E.g. ":ls *.c". (Thompson)
+7   Add expansion of buffer names, so that "*.c" is expanded to all buffer
+    names.  Needed for ":bdel *.c", ":bunload *.c", etc.
+8   Support for <afile> where a buffer name is expected.
+8   Some commands don't use line numbers, but buffer numbers.  '$'
+    should then mean the number of the last buffer.  E.g.: "4,$bdel".
+7   Add an option to mostly use slashes in file names.  Separately for
+    internal use and for when executing an external program?
+
+
+Swap (.swp) files:
+8   If writing to the swap file fails, should try to open one in another
+    directory from 'dir'.  Useful in case the file system is full and when
+    there are short file name problems.
+8   Also use the code to try using a short file name for the backup and swap
+    file for the Win32 and Dos 32 bit versions.
+8   When a file is edited by root, add $LOGNAME to know who did su.
+8   When the edited file is a symlink, try to put the swap file in the same
+    dir as the actual file.  Adjust FullName().  Avoids editing the same file
+    twice (e.g. when using quickfix).  Also try to make the name of the backup
+    file the same as the actual file?
+    Use the code for resolve()?
+7   When using 64 bit inode numbers, also store the top 32 bits.  Add another
+    field for this, using part of bo_fname[], to keep it compatible.
+7   When editing a file on removable media, should put swap file somewhere
+    else.  Use something like 'r' flag in 'viminfo'.  'diravoid'?
+    Also: Be able to specify minimum disk space, skip directory when not
+    enough room.
+7   Add a configure check for which directory should be used: /tmp, /var/tmp
+    or /var/preserve.
+-   Add an option to create a swap file only when making the first change to
+    the buffer.  (Liang)  Or only when the buffer is not read-only.
+-   Add option to set "umask" for backup files and swap files (Antwerpen).
+    'backupumask' and 'swapumask'?  Or 'umaskback' and 'umaskswap'?
+-   When editing a readonly file, don't use a swap file but read parts from the
+    original file.  Also do this when the file is huge (>'maxmem').  We do
+    need to load the file once to count the number of lines?  Perhaps keep a
+    cached list of which line is where.
+
+
+Viminfo:
+7   Can probably remove the code that checks for a writable viminfo file,
+    because we now do the chown() for root, and others can't overwrite someone
+    else's viminfo file.
+8   When there is no .viminfo file and someone does "su", runs Vim, a
+    root-owned .viminfo file is created.  Is there a good way to avoid this?
+    Perhaps check the owner of the directory.  Only when root?
+8   Add argument to keep the list of buffers when Vim is started with a file
+    name. (Schild)
+8   Keep the last used directory of the file browser (File/Open menu).
+8   Remember the last used register for "@@".
+8   Remember a list of last accessed files.  To be used in the
+    "File.Open Recent" menu.  Default is to remember 10 files or so.
+    Also remember which files have been read and written.  How to display
+    this?
+7   Also store the ". register (last inserted text).
+7   Make it possible to store buffer names in viminfo file relative to some
+    directory, to make them portable over a network. (Aaron)
+6   Store a snapshot of the currently opened windows.  So that when quitting
+    Vim, and then starting again (without a file name argument), you see the
+    same files in the windows.  Use ":mksession" code?
+-   Make marks present in .viminfo usable as file marks: Display a list of
+    "last visited files" and select one to jump to.
+
+
+Modelines:
+8   Before trying to execute a modeline, check that it looks like one (valid
+    option names).  If it's very wrong, silently ignore it.
+    Ignore a line that starts with "Subject: ".
+-   When an option value is coming from a modeline, do not carry it over to
+    another edited file?  Would need to remember the value from before the
+    modeline setting.
+-   Allow setting a variable from a modeline?  Only allow using fixed strings,
+    no function calls, to avoid a security problem.
+-   Allow ":doauto BufRead x.cpp" in modelines, to execute autocommands for
+    .cpp files.
+-   Support the "abbreviate" command in modelines (Kearns).  Careful for
+    characters after <Esc>, that is a security leak.
+-   Add option setting to ask user if he wants to have the modelines executed
+    or not.  Same for .exrc in local dir.
+
+
+Sessions:
+8   DOS/Windows: ":mksession" generates a "cd" command where "aa\#bb" means
+    directory "#bb" in "aa", but it's used as "aa#bb". (Ronald Hoellwarth)
+7   When there is a "help.txt" window in a session file, restoring that
+    session will not get the "LOCAL ADDITIONS" back.
+8   With ":mksession" always store the 'sessionoptions' option, even when
+    "options" isn't in it. (St-Amant)
+8   When using ":mksession", also store a command to reset all options to
+    their default value, before setting the options that are not at their
+    default value.
+7   With ":mksession" also store the tag stack and jump history. (Michal
+    Malecki)
+7   Persistent variables: "p:var"; stored in viminfo file and sessions files.
+
+
+Options:
+7   ":with option=value | command": temporarily set an option value and
+    restore it after the command has executed.
+7   Setting an option always sets "w_set_curswant", while this is only
+    required for a few options.  Only do it for those options to avoid the
+    side effect.
+8   Make "old" number options that really give a number of effects into string
+    options that are a comma separated list.  The old number values should
+    also be supported.
+8   Add commands to save and restore an option, which also preserves the flag
+    that marks if the option was set.  Useful to keep the effect of setting
+    'compatible' after ":syntax on" has been used.
+7   There is 'titleold', why is there no 'iconold'? (Chazelas)
+7   Make 'scrolloff' a global-local option, so that it can be different in the
+    quickfix window, for example. (Gary Holloway)
+
+
+External commands:
+8   When filtering text, redirect stderr so that it can't mess up the screen
+    and Vim doesn't need to redraw it.  Also for ":r !cmd".
+4   Set separate shell for ":sh", piping "range!filter", reading text "r !ls"
+    and writing text "w !wc". (Deutsche)  Allow arguments for fast start (e.g.
+    -f).
+4   Allow direct execution, without using a shell.
+4   Run an external command in the background.  But how about I/O in the GUI?
+    Careful: don't turn Vim into a shell!
+4   Add feature to disable using a shell or external commands.
+
+
+Multiple Windows:
+7   "vim -oO file ..." use both horizontal and vertical splits.
+8   Add CTRL-W T: go to the top window in the column of the current window.
+    And CTRL-W B: go to bottom window.
+7   Use CTRL-W <Tab>, like alt-tab, to switch between buffers.  Repeat <Tab>
+    to select another buffer (only loaded ones?), <BS> to go back, <Enter> to
+    select buffer, <Esc> to go back to original buffer.
+7   Add a 'tool' window: behaves like a preview window but there can be
+    several.  Don't count it in only_one_window(). (Alexei Alexandrov)
+6   Add an option to resize the shell when splitting and/or closing a window.
+    ":vsp" would make the shell wider by as many columns as needed for the new
+    window.  Specify a maximum size (or use the screen size).  ":close" would
+    shrink the shell by as many columns as come available. (Demirel)
+7   When starting Vim several times, instantiate a Vim server, that allows
+    communication between the different Vims.  Feels like one Vim running with
+    multiple top-level windows.  Esp. useful when Vim is started from an IDE
+    too.  Requires some form of inter process communication.
+-   Support a connection to an external viewer.  Could call the viewer
+    automatically after some seconds of non-activity, or with a command.
+    Allow some way of reporting scrolling and cursor positioning in the viewer
+    to Vim, so that the link between the viewed and edited text can be made.
+
+
+Marks:
+8   When cursor is first moved because of scrolling, set a mark at this
+    position.  (Rimon Barr)  Use '-.
+8   Add a command to jump to a mark and make the motion inclusive.  g'm and g`m?
+8   The '" mark is set to the first line, even when doing ":next" a few times.
+    Only set the '" mark when the cursor was really moved in a file.
+8   Make `` and '', which would position the new cursor position in the middle
+    of the window, restore the old topline (or relative position) from when
+    the mark was set.
+7   Make a list of file marks in a separate window.  For listing all buffers,
+    matching tags, errors, etc.  Normal commands to move around.  Add commands
+    to jump to the mark (in current window or new window).  Start it with
+    ":browse marks"?
+6   Add a menu that lists the Marks like ":marks". (Amerige)
+7   For ":jumps", ":tags" and ":marks", for not loaded buffers, remember the
+    text at the mark.  Highlight the column with the mark.
+7   Highlight each mark in some way (With "Mark" highlight group).
+    Or display marks in a separate column, like 'number' does.
+7   Use d"m to delete rectangular area from cursor to mark m (like Vile's \m
+    command).
+7   Try to keep marks in the same position when:
+    - replacing with a line break, like in ":s/pat/^M/", move marks after the
+      line break column to the next line. (Acevedo)
+    - inserting/deleting characters in a line.
+5   Include marks for start/end of the current word and section.  Useful in
+    mappings.
+6   Add "unnamed mark" feature: Like marks for the ":g" command, but place and
+    unplace them with commands before doing something with the lines.
+    Highlight the marked lines somehow.
+
+
+Digraphs:
+7   Make "ga" show the digraph for a character, if it exists.
+    Also the keymap?
+-   Make it possible to enter "r<C-E>" and "r<C-Y>" (get character from line
+    below/above).
+-   Use digraph table to tell Vim about the collating sequence of special
+    characters?
+8   Add command to remove one or more (all) digraphs. (Brown)
+7   Support different sets of digraphs (depending on the character set?).  At
+    least Latin1/Unicode, Latin-2, MS-DOS (esp. for Win32).
+
+
+Writing files:
+-   In vim_rename(), should lock "from" file when deleting "to" file for
+    systems other than Amiga.  Avoids problems with unexpected longname to
+    shortname conversion.
+8   write mch_isdevice() for Amiga, Mac, VMS, etc.
+8   When appending to a file, Vim should also make a backup and a 'patchmode'
+    file.
+8   'backupskip' doesn't write a backup file at all, a bit dangerous for some
+    applications.  Add 'backupelsewhere' to write a backup file in another
+    directory?  Or add a flag to 'backupdir'?
+7   The 'directory' option supports changing path separators to "%" to make
+    file names unique, also support this for 'backupdir'. (Mikolaj Machowski)
+6   Add an option to write a new, numbered, backup file each time.  Like
+    'patchmode', e.g., 'backupmode'.
+6   Make it possible to write 'patchmode' files to a different directory.
+    E.g., ":set patchmode=~/backups/*.orig". (Thomas)
+6   Add an option to prepend something to the backup file name.  E.g., "#".
+    Or maybe allow a function to modify the backup file name?
+8   Only make a backup when overwriting a file for the first time.  Avoids
+    losing the original when writing twice. (Slootman)
+7   On non-Unix machines, also overwrite the original file in some situations
+    (file system full, it's a link on an NFS partition).
+7   When editing a file, check that it has been change outside of Vim more
+    often, not only when writing over it.  E.g., at the time the swap file is
+    flushed.  Or every ten seconds or so (use the time of day, check it before
+    waiting for a character to be typed).
+8   When a file was changed since editing started, show this in the status
+    line of the window, like "[time]".
+    Make it easier to reload all outdated files that don't have changes.
+    Automatic and/or with a command.
+
+
+Substitute:
+8   Substitute with hex/unicode number "\%xff" and "\%uabcd".  Just like
+    "\%uabcd" in search pattern.
+8   Make it easier to replace in all files in the argument list.  E.g.:
+    ":argsub/oldword/newword/".  Works like ":argdo %s/oldword/newword/g|w".
+-   :s///p prints the line after a substitution.
+-   With :s///c replace \&, ~, etc. when showing the replacement pattern.
+8   With :s///c allow scrolling horizontally when 'nowrap' is effective.
+    Also allow a count before the scrolling keys.
+-   Add number option to ":s//2": replace second occurrence of string?  Or:
+    :s///N substitutes N times.
+-   Add answers to ":substitute" with 'c' flag, used in a ":global", e.g.:
+    ":g/pat1/s/pat2/pat3/cg": 'A' do all remaining replacements, 'Q' don't do
+    any replacements, 'u' undo last substitution.
+7   Substitute in a block of text.  Use {line}.{column} notation in an Ex
+    range, e.g.: ":1.3,$.5s" means to substitute from line 1 column 3 to the
+    last line column 5.
+5   Add commands to bookmark lines, display bookmarks, remove bookmarks,
+    operate on lines with bookmarks, etc.  Like ":global" but with the
+    possibility to keep the bookmarks and use them with several commands.
+    (Stanislav Sitar)
+
+
+Mouse support:
+8   Add 'o' flag to 'mouse'?
+7   Be able to set a 'mouseshape' for the popup menu.
+8   Add 'mouse' flag, which sets a behavior like Visual mode, but automatic
+    yanking at the button-up event.  Or like Select mode, but typing gets you
+    out of Select mode, instead of replacing the text. (Bhaskar)
+7   Checkout sysmouse() for FreeBSD console mouse support.
+-   Implement mouse support for the Amiga console.
+-   Using right mouse button to extend a blockwise selection should attach to
+    the nearest corner of the rectangle (four possible corners).
+-   Precede mouse click by a number to simulate double clicks?!?
+-   When mouse click after 'r' command, get character that was pointed to.
+
+
+Crypt and security:
+8   Also crypt the swapfile, each block separately.  Change mf_write() and
+    mf_read().  How to get b_p_key to these functions?
+
+
+Argument list:
+6   Add command to put all filenames from the tag files in the argument list.
+    When given an argument, only use the files where that argument matches
+    (like `grep -l ident`) and jump to the first match.
+6   Add command to form an args list from all the buffers?
+
+
+Registers:
+8   Don't display empty registers with ":display". (Etienne)
+8   Make the # register writable, so that it can be restored after jumping
+    around in windows.
+8   Add put command that overwrites existing text.  Should also work for
+    blocks.  Useful to move text around in a table.  Works like using "R ^R r"
+    for every line.
+6   When yanking into the unnamed registers several times, somehow make the
+    previous contents also available (like it's done for deleting).  What
+    register names to use?  g"1, g"2, etc.?
+-   When appending to a register, also report the total resulting number of
+    lines.  Or just say "99 more lines yanked", add the "more".
+-   When inserting a register in Insert mode with CTRL-R, don't insert comment
+    leader when line wraps?
+-   The ":@r" commands should take a range and execute the register for each
+    line in the range.
+-   Add "P" command to insert contents of unnamed register, move selected text
+	to position of previous deleted (to swap foo and bar in " + foo")
+8   Should be able to yank and delete into the "/ register.
+    How to take care of the flags (offset, magic)?
+
+
+Debug mode:
+7   Add something to enable debugging when a remote message is received.
+8   Add breakpoints for setting an option
+8   Add breakpoints for assigning to a variable.
+7   Add a watchpoint in the debug mode: An expression that breaks execution
+    when evaluating to non-zero.  Add the "watchadd expr" command, stop when
+    the value of the expression changes.  ":watchdel" deletes an item,
+    ":watchlist" lists the items. (Charles Campbell)
+7   Store the history from debug mode in viminfo.
+7   Make the debug mode history available with histget() et al.
+
+
+Various improvements:
+7   Add plugins for formatting?  Should be able to make a choice depending on
+    the language of a file (English/Korean/Japanese/etc.).
+    Setting the 'langformat' option to "chinese" would load the
+    "format/chinese.vim" plugin.
+    The plugin would set 'formatexpr' and define the function being called.
+    Edward L. Fox explains how it should be done for most Asian languages.
+    (2005 Nov 24)
+7   [t to move to previous xml/html tag (like "vatov"), ]t to move to next
+    ("vatv").
+7   [< to move to previous xml/html tag, e.g., previous <li>. ]< to move to
+    next <li>, ]< to next </li>, [< to previous </li>.
+8   Add ":rename" command: rename the file of the current buffer and rename
+    the buffer.  Buffer may be modified.
+7   Instead of filtering errors with a shell script it should be possible to
+    do this with Vim script.  A function that filters the raw text that comes
+    from the 'makeprg'?
+-   Add %b to 'errorformat': buffer number. (Yegappan Lakshmanan / Suresh
+    Govindachar)
+7   Add a command that goes back to the position from before jumping to the
+    first quickfix location.  ":cbefore"?
+6   In the quickfix window statusline add the command used to get the list of
+    errors, e.g. ":make foo", ":grep something *.c".
+6   Python interface: add vim.message() function. (Michal Vitecek, 2002 Nov 5)
+7   Support using ":vert" with User commands.  Add expandable items <vert>.
+    Do the same for ":browse" and ":confirm"?
+    For ":silent" and ":debug" apply to the whole user command.
+7   Allow a window not to have a statusline.  Makes it possible to use a
+    window as a buffer-tab selection.
+7   Add an invisible buffer which can be edited.  For use in scripts that want
+    to manipulate text without changing the window layout.
+8   Add a command to revert to the saved version of file; undo or redo until
+    all changes are gone.
+6   "vim -q -" should read the list of errors from stdin. (Gautam Mudunuri)
+8   Add "--remote-fail": When contacting the server fails, exit Vim.
+    Add "--remote-self": When contacting the server fails, do it in this Vim.
+    Overrules the default of "--remote-send" to fail and "--remote" to do it
+    in this Vim.
+8   When Vim was started without a server, make it possible to start one, as
+    if the "--servername" argument was given.  ":startserver <name>"?
+8   No address range can be used before the command modifiers.  This makes
+    them difficult to use in a menu for Visual mode.  Accept the range and
+    have it apply to the following command.
+8   Add the possibility to set 'fileformats' to force a format and strip other
+    CR characters.  For example, for "dos" files remove CR characters at the
+    end of the line, so that a file with mixed line endings is cleaned up.
+    To just not display the CR characters: Add a flag to 'display'?
+7   Some compilers give error messages in which the file name does not have a
+    path.  Be able to specify that 'path' is used for these files.
+7   Xterm sends <Esc>O3F for <M-End>.  Similarly for other <M-Home>, <M-Left>,
+    etc.  Combinations of Alt, Ctrl and Shift are also possible.  Recognize
+    these to avoid inserting the raw byte sequence, handle like the key
+    without modifier (unless mapped).
+7   Support ":browse edit" in console, using explorer.vim?
+6   Add "gG": like what "gj" is to "j": go to the N'th window line.
+8   Add command like ":normal" that accepts <Key> notation like ":map".
+9   Support ACLs on more systems.
+7   Add ModeMsgVisual, ModeMsgInsert, etc. so that each mode message can be
+    highlighted differently.
+7   Add a message area for the user.  Set some option to reserve space (above
+    the command line?).  Use an ":echouser" command to display the message
+    (truncated to fit in the space).
+7   Add %s to 'keywordprg': replace with word under the cursor. (Zellner)
+8   Support printing on Unix.  Can use "lpansi.c" as an example. (Bookout)
+8   Add put command that replaces the text under it.  Esp. for blockwise
+    Visual mode.
+7   Enhance termresponse stuff: Add t_CV(?): pattern of term response, use
+    regexp: "\e\[[>?][0-9;]*c", but only check just after sending t_RV.
+7   Add "g|" command: move to N'th column from the left margin (after wrapping
+    and applying 'leftcol').  Works as "|" like what "g0" is to "0".
+7   Support setting 'equalprg' to a user function name.
+7   Highlight the characters after the end-of-line differently.
+7   When 'whichwrap' contains "l", "$dl" should join lines?
+8   Add an argument to configure to use $CFLAGS and not modify it? (Mooney)
+8   Enabling features is a mix of configure arguments and defines in
+    feature.h.  How to make this consistent?  Feature.h is required for
+    non-unix systems.  Perhaps let configure define CONF_XXX, and use #ifdef
+    CONF_XXX in feature.h?  Then what should min-features and max-features do?
+8   Add "g^E" and "g^Y", to scroll a screen-full line up and down.
+6   Add ":timer" command, to set a command to be executed at a certain
+    interval, or once after some time has elapsed. (Aaron)
+    Perhaps an autocommand event like CursorHold is better?
+8   Add ":confirm" handling in open_exfile(), for when file already exists.
+8   When quitting with changed files, make the dialog list the changed file
+    and allow "write all", "discard all", "write some".  The last one would
+    then ask "write" or "discard" for each changed file.  Patch in HierAssist
+    does something like this. (Shah)
+7   Use growarray for replace stack.
+7   Have a look at viH (Hellenic or Greek version of Vim).  But a solution
+    outside of Vim might be satisfactory (Haritsis).
+3   Make "2d%" work like "d%d%" instead of "d2%"?
+7   "g CTRL-O" jumps back to last used buffer.	Skip CTRL-O jumps in the same
+    buffer.  Make jumplist remember the last ten accessed buffers?
+-   Keep a list of most recently used files for each window, use "[o" to go
+    back (older file) and "]n" to go forward (newer file) (like ^O and ^I for
+    jumps). (Webb)  Use ":files" and ":ls" to list the files in history order.
+7   Add a history of recently accessed buffer.	Maybe make "2 CTRL-^" jump to
+    the 2nd previously visited buffer, "3 CTRL-^" to the third, etc.  Or use
+    "3 g CTRL-^" for this?
+-   Add code to disable the CAPS key when going from Insert to Normal mode.
+-   Set date/protection/etc. of the patchfile the same as the original file.
+-   Use growarray for termcodes[] in term.c
+-   Add <window-99>, like <cword> but use filename of 99'th window.
+7   Add a way to change an operator to always work characterwise-inclusive
+    (like "v" makes the operator characterwise-exclusive).  "x" could be used.
+-   Make a set of operations on list of names: expand wildcards, replace home
+    dir, append a string, delete a string, etc.
+-   Remove mktemp() and use tmpname() only?  Ctags does this.
+-   When replacing environment variables, and there is one that is not set,
+    turn it into an empty string?  Only when expanding options? (Hiebert)
+-   Option to set command to be executed instead of producing a beep (e.g. to
+    call "play newbeep.au").
+-   Add option to show the current function name in the status line.  More or
+    less what you find with "[[k", like how 'cindent' recognizes a function.
+    (Bhatt).
+-   "[r" and "]r": like "p" and "P", but replace instead of insert (esp. for
+    blockwise registers).
+-   Add 'timecheck' option, on by default.  Makes it possible to switch off the
+    timestamp warning and question. (Dodt).
+-   Add an option to set the time after which Vim should check the timestamps
+    of the files.  Only check when an event occurs (e.g., character typed,
+    mouse moved).  Useful for non-GUI versions where keyboard focus isn't
+    noticeable.
+-   Make 'smartcase' work even though 'ic' isn't set (Webb).
+7   When formatting text, allow to break the line at a number of characters.
+    Use an option for this: 'breakchars'?  Useful for formatting Fortran code.
+-   Add flag to 'formatoptions' to be able to format book-style paragraphs
+    (first line of paragraph has larger indent, no empty lines between
+    paragraphs).  Complements the '2' flag.  Use '>' flag when larger indent
+    starts a new paragraph, use '<' flag when smaller indent starts a new
+    paragraph.	Both start a new paragraph on any indent change.
+8   The 'a' flag in 'formatoptions' is too dangerous.  In some way only do
+    auto-formatting in specific regions, e.g. defined by syntax highlighting.
+8   Allow using a trailing space to signal a paragraph that continues on the
+    next line (MIME text/plain; format=flowed, RFC 2646).  Can be used for
+    continuous formatting.  Could use 'autoformat' option, which specifies a
+    regexp which triggers auto-formatting (for one line).
+    ":set autoformat=\\s$".
+-   Be able to redefine where a sentence stops.  Use a regexp pattern?
+-   Support multi-byte characters for sentences.  Example from Ben Peterson.
+7   Add command "g)" to go to the end of a sentence, "g(" to go back to the
+    end of a sentence. (Servatius Brandt)
+-   Be able to redefine where a paragraph starts.  For "[[" where the '{' is
+    not in column 1.
+6   Add ":cdprev": go back to the previous directory.  Need to remember a
+    stack of previous directories.  We also need ":cdnext".
+7   Should ":cd" for MS-DOS go to $HOME, when it's defined?
+-   Make "gq<CR>" work on the last line in the file.  Maybe for every operator?
+-   Add more redirecting of Ex commands:
+	:redir #>  bufname
+	:redir #>> bufname   (append)
+-   Give error message when starting :redir: twice or using END when no
+    redirection was active.
+-   Setting of options, specifically for a buffer or window, with
+    ":set window.option" or ":set buffer.option=val".  Or use ":buffer.set".
+    Also: "buffer.map <F1> quit".
+6   Would it be possible to change the color of the cursor in the Win32
+    console?  (Klaus Hast)
+-   Add :delcr command:
+			    *:delcr*
+     :[range]delcr[!]	Check [range] lines (default: whole buffer) for lines
+			ending in <CR>.  If all lines end in <CR>, or [!] is
+			used, remove the <CR> at the end of lines in [range].
+			A CTRL-Z at the end of the file is removed.  If
+			[range] is omitted, or it is the whole file, and all
+			lines end in <CR> 'textmode' is set.  {not in Vi}
+-   Should integrate addstar() and file_pat_to_reg_pat().
+-   When working over a serial line with 7 bit characters, remove meta
+    characters from 'isprint'.
+-   Use fchdir() in init_homedir(), like in FullName().
+-   In win_update(), when the GUI is active, always use the scrolling area.
+    Avoid that the last status line is deleted and needs to be redrawn.
+-   That "cTx" fails when the cursor is just after 'x' is Vi compatible, but
+    may not be what you expect.  Add a flag in 'cpoptions' for this?  More
+    general: Add an option to allow "c" to work with a null motion.
+-   Give better error messages by using errno (strerror()).
+-   Give "Usage:" error message when command used with wrong arguments (like
+    Nvi).
+-   Make 'restorescreen' option also work for xterm (and others), replaces the
+    SAVE_XTERM_SCREEN define.
+7   Support for ":winpos" In xterm: report the current window position.
+-   Give warning message when using ":set t_xx=asdf" for a termcap code that
+    Vim doesn't know about.  Add flag in 'shortmess'?
+6   Add ":che <file>", list all the include paths which lead to this file.
+-   For a commandline that has several commands (:s, :d, etc.) summarize the
+    changes all together instead of for each command (e.g. for the rot13
+    macro).
+-   Add command like "[I" that also shows the tree of included files.
+-   ":set sm^L" results in ":set s", because short names of options are also
+    expanded.  Is there a better way to do this?
+-   Add ":@!" command, to ":@" like what ":source!" is to ":source".
+8   Add ":@:!": repeat last command with forceit set.
+-   Should be possible to write to a device, e.g. ":w! /dev/null".
+-   Add 't_normal': Used whenever t_me, t_se, t_ue or t_Zr is empty.
+-   ":cab map test ^V| je", ":cunab map" doesn't work.	This is vi compatible!
+-   CTRL-W CTRL-E and CTRL-W CTRL-Y should move the current window up or down
+    if it is not the first or last window.
+-   Include-file-search commands should look in the loaded buffer of a file (if
+    there is one) instead of the file itself.
+7   Change 'nrformats' to include the leader for each format.  Example:
+	nrformats=hex:$,binary:b,octal:0
+    Add setting of 'nrformats' to syntax files.
+-   'path' can become very long, don't use NameBuff for expansion.
+-   When unhiding a hidden buffer, put the same line at top of the window as
+    the one before hiding it.  Or: keep the same relative cursor position (so
+    many percent down the windows).
+-   Make it possible for the 'showbreak' to be displayed at the end of the
+    line.  Use a comma to separate the part at the end and the start of the
+    line?  Highlight the linebreak characters, add flag in 'highlight'.
+-   Some string options should be expanded if they have wildcards, e.g.
+    'dictionary' when it is "*.h".
+-   Use a specific type for number and boolean options, making it possible to
+    change it for specific machines (e.g. when a long is 64 bit).
+-   Add option for <Insert> in replace mode going to normal mode. (Nugent)
+-   Add a next/previous possibility to "[^I" and friends.
+-   Add possibility to change the HOME directory.  Use the directory from the
+    passwd file? (Antwerpen)
+8   Add commands to push and pop all or individual options. ":setpush tw",
+    ":setpop tw", ":setpush all".  Maybe pushing/popping all options is
+    sufficient.  ":setflush" resets the option stack?
+    How to handle an aborted mapping?  Remember position in tag stack when
+    mapping starts, restore it when an error aborts the mapping?
+-   Change ":fixdel" into option 'fixdel', t_del will be adjusted each time
+    t_bs is set? (Webb)
+-   "gc": goto character, move absolute character positions forward, also
+    counting newlines.  "gC" goes backwards (Weigert).
+-   When doing CTRL-^, redraw buffer with the same topline. (Demirel)  Store
+    cursor row and window height to redraw cursor at same percentage of window
+    (Webb).
+-   Besides remembering the last used line number of a file, also remember the
+    column.  Use it with CTRL-^ et. al.
+-   Check for non-digits when setting a number option (careful when entering
+    hex codes like 0xff).
+-   Add option to make "." redo the "@r" command, instead of the last command
+    executed by it.  Also to make "." redo the whole mapping.  Basically: redo
+    the last TYPED command.
+-   Support URL links for ^X^F in Insert mode, like for "gf".
+-   Support %name% expansion for "gf" on Windows.
+-   Make "gf" work on "file://c:/path/name".  "file:/c:/" and "file:///c:/"
+    should also work?
+-   Add 'urlpath', used like 'path' for when "gf" used on an URL?
+8   When using "gf" on an absolute file name, while editing a remote file
+    (starts with scp:// or http://) should prepend the method and machine
+    name.
+-   When finding an URL or file name, and it doesn't exist, try removing a
+    trailing '.'.
+-   Add ":path" command modifier.  Should work for every command that takes a
+    file name argument, to search for the file name in 'path'.	Use
+    find_file_in_path().
+-   Highlight control characters on the screen: Shows the difference between
+    CTRL-X and "^" followed by "X" (Colon).
+-   Integrate parsing of cmdline command and parsing for expansion.
+-   Create a program that can translate a .swp file from any machine into a
+    form usable by Vim on the current machine.
+-   Add ":noro" command: Reset 'ro' flag for all buffers, except ones that have
+    a readonly file.  ":noro!" will reset all 'ro' flags.
+-   Add a variant of CTRL-V that stops interpretation of more than one
+    character.	For entering mappings on the command line where a key contains
+    several special characters, e.g. a trailing newline.
+-   Add regex for 'paragraphs' and 'sections': 'parare' and 'sectre'.  Combine
+    the two into a regex for searching. (Ned Konz)
+-   Make '2' option in 'formatoptions' also work inside comments.
+-   Add 's' flag to 'formatoptions': Do not break when inside a string. (Dodt)
+-   When window size changed (with the mouse) and made too small, set it back
+    to the minimal size.
+-   Add "]>" and "[<", shift comment at end of line (command;  /* comment */).
+-   Should not call cursorcmd() for each vgetc() in getcmdline().
+-   ":split file1 file2" adds two more windows (Webb).
+-   Don't give message "Incomplete last line" when editing binary file.
+-   Add ":a", ":i" for preloading of named buffers.
+-   Allow autowrite when doing ":e file" (with an option 'eaw').
+-   Allow a "+command" argument before each file name in the Vim command line:
+    "vim +123 file1 +234 file2 +345 file3". ???
+-   When entering text, keep other windows on same buffer updated (when a line
+    entered)?
+-   Check out how screen does output optimizing.  Apparently this is possible
+    as an output filter.
+-   In dosub() regexec is called twice for the same line.  Try to avoid this.
+-   Window updating from memline.c: insert/delete/replace line.
+-   Optimize ml_append() for speed, esp. for reading a file.
+-   V..c should keep indent when 'ai' is set, just like [count]cc.
+-   Updatescript() can be done faster with a string instead of a char.
+-   Screen updating is inefficient with CTRL-F and CTRL-B when there are long
+    lines.
+-   Uppercase characters in ex commands can be made lowercase?
+8   Add option to show characters in text not as "|A" but as decimal ("^129"),
+    hex ("\x81") or octal ("\201") or meta (M-x).  Nvi has the 'octal' option
+    to switch from hex to octal.  Vile can show unprintable characters in hex
+    or in octal.
+7   Tighter integration with xxd to edit binary files.  Make it more
+    easy/obvious to use.  Command line argument?
+-   How does vi detect whether a filter has messed up the screen?  Check source.
+    After ":w !command" a wait_return?
+-   Improve screen updating code for doput() (use s_ins()).
+-   With 'p' command on last line: scroll screen up (also for terminals without
+    insert line command).
+-   Use insert/delete char when terminal supports it.
+-   Optimize screen redraw for slow terminals.
+-   Optimize "dw" for long row of spaces (say, 30000).
+-   Add "-d null" for editing from a script file without displaying.
+-   In Insert mode: Remember the characters that were removed with backspace
+    and re-insert them one at a time with <key1>, all together with <key2>.
+-   Amiga: Add possibility to set a keymap.  The code in amiga.c does not work
+    yet.
+-   Implement 'redraw' option.
+-   Add special code to 'sections' option to define something else but '{' or
+    '}' as the start of a section (e.g. one shiftwidth to the right).
+7   Allow using Vim in a pipe: "ls | vim -u xxx.vim - | yyy".  Only needs
+    implementing ":w" to stdout in the buffer that was read from stdin.
+    Perhaps writing to stdout will work, since stderr is used for the terminal
+    I/O.
+8   Allow opening an unnamed buffer with ":e !cmd" and ":sp !cmd".  Vile can
+    do it.
+-   Add commands like ]] and [[ that do not include the line jumped to.
+-   When :unab without matching "from" part and several matching "to" parts,
+    delete the entry that was used last, instead of the first in the list.
+-   Add text justification option.
+-   Set boolean options on/off with ":set paste=off", ":set paste=on".
+-   After "inv"ing an option show the value: ":set invpaste" gives "paste is
+    off".
+-   Check handling of CTRL-V and '\' for ":" commands that do not have TRLBAR.
+-   When a file cannot be opened but does exist, give error message.
+-   Amiga: When 'r' protection bit is not set, file can still be opened but
+    gives read errors.  Check protection before opening.
+-   When writing check for file exists but no permission, "Permission denied".
+-   If file does not exists, check if directory exists.
+-   MSDOS: although t_cv and t_ci are not set, do invert char under cursor.
+-   Settings edit mode: make file with ":set opt=xx", edit it, parse it as ex
+    commands.
+-   ":set -w all": list one option per line.
+-   Amiga: test for 'w' flag when reading a file.
+-   :table command (Webb)
+-   Add new operator: clear, make area white (replace with spaces): "g ".
+-   Add command to ":read" a file at a certain column (blockwise read?).
+-   Add sort of replace mode where case is taken from the old text (Goldfarb).
+-   Allow multiple arguments for ":read", read all the files.
+-   Support for tabs in specific columns: ":set tabcol=8,20,34,56" (Demirel).
+-   Add 'searchdir' option: Directories to search for file name being edited
+    (Demirel).
+-   Modifier for the put command: Change to linewise, charwise, blockwise, etc.
+-   Add commands for saving and restoring options ":set save" "set restore",
+    for use in macro's and the like.
+-   Keep output from listings in a window, so you can have a look at it while
+    working in another window.  Put cmdline in a separate window?
+-   Add possibility to put output of ex commands in a buffer or file, e.g. for
+    ":set all".  ":r :set all"?
+-   'edit' option: When off changing the buffer is not possible (Really
+    read-only mode).
+-   When the 'equalalways' option is set, creating a new window should not
+    result in windows to become bigger.  Deleting a window should not result in
+    a window to become smaller (Webb).
+-   When resizing the whole Vim window, the windows inside should be resized
+    proportionally (Webb).
+-   Include options directly in option table, no indirect pointers.  Use
+    mkopttab to make option table?
+-   When doing ":w dir", where "dir" is a directory name, write the current
+    file into that directory, with the current file name (without the path)?
+-   Support for 'dictionary's that are sorted, makes access a lot faster
+    (Haritsis).
+-   Add "^Vrx" on the command line, replace with contents of register x.  Used
+    instead of CTRL-R to make repeating possible. (Marinichev)
+-   Add "^Vb" on the command line, replace with word before or under the
+    cursor?
+-   Option to make a .swp file only when a change is made (Templeton).
+-   Support mapping for replace mode and "r" command (Vi doesn't do this)?
+5   Add 'ignorefilecase' option: Ignore case when expanding file names.
+    ":e ma<Tab>" would also find "Makefile" on Unix.
+8   Sorting of filenames for completion is wrong on systems that ignore
+    case of filenames.  Add 'ignorefncase' option.  When set, case in
+    filenames is ignored for sorting them. Patch by Mike Williams:
+    ~/vim/patches/ignorefncase.  Also change what matches?  Or use another
+    option name.
+8   Should be able to compile Vim in another directory, with $(srcdir) set to
+    where the sources are. Add $(srcdir) in the Makefile in a lot of places.
+    (Netherton)
+6   Make it configurable when "J" inserts a space or not.  Should not add a
+    space after "(", for example.
+5   When inserting spaces after the end-of-line for 'virtualedit', use tabs
+    when the user wants this (e.g., add a "tab" field to 'virtualedit').
+    (Servatius Brandt)
+
+
+From Elvis:
+-   Use "instman.sh" to install manpages?
+-   Add ":alias" command.
+-   fontchanges recognized "\\fB" etc.
+-   Search patterns:
+      \@	match word under cursor.
+    but do:
+      \@w	match the word under the cursor?
+      \@W	match the WORD under the cursor?
+8   ":window" command:
+    :win +	next window (up)
+    :win ++	idem, wrapping
+    :win -	previous window (down)
+    :win --	idem, wrapping
+    :win nr	to window number "nr"
+    :win name	to window editing buffer "name"
+7   ":cc" compiles a single file (default: current one).  'ccprg'   option is
+    program to use with ":cc".  Use ":compile" instead of ":cc"?
+
+
+From Nvi:
+-   'searchincr' option, alias for 'incsearch'?
+-   'leftright' option, alias for 'nowrap'?
+-   Have a look at "vi/doc/vi.chart", for Nvi specialties.
+8   Add 'keytime', time in 1/10 sec for mapping timeout?
+-   Add 'filec' option as an alternative for 'wildchar'.
+6   Support Nvi command names as an alias:
+    :bg		    :hide
+    :fg	fname	    :buf fname (with 'hidden' set?)
+    :dis b	    :ls
+    :Edit fname	    :split fname
+    :Fg fname	    :sbuf fname (with 'hidden' set?)
+    :Next	    :snext (can't do this, already use :Next)
+    :Previous	    :sprevious
+    :Tag	    :stag
+
+
+From xvi:
+-   CTRL-_ : swap 8th bit of character.
+-   Add egrep-like regex type, like xvi (Ned Konz) or Perl (Emmanuel Mogenet)
+
+
+From vile:
+-   When horizontal scrolling, use '>' for lines continuing right of a window.
+-   Support putting .swp files in /tmp: Command in rc.local to move .swp files
+    from /tmp to some directory before deleting files.
+
+
+Far future and "big" extensions:
+-   Instead of using a Makefile and autoconf, use a simple shell script to
+    find the C compiler and do everything with C code.  Translate something
+    like an Aap recipe and configure.in to C.  Avoids depending on Python,
+    thus will work everywhere.  With batch file to find the C compiler it
+    would also work on MS-Windows.
+-   Make it easy to setup Vim for groups of users: novice vi users, novice
+    Vim users, C programmers, xterm users, GUI users,...
+-   Change layout of blocks in swap file: Text at the start, with '\n' in
+    between lines (just load the file without changes, except for Mac).
+    Indexes for lines are from the end of the block backwards.  It's the
+    current layout mirrored.
+-   Make it possible to edit a register, in a window, like a buffer.
+-   Add stuff to syntax highlighting to change the text (upper-case keywords,
+    set indent, define other highlighting, etc.).
+-   Mode to keep C-code formatted all the time (sort of on-line indent).
+-   Several top-level windows in one Vim session.  Be able to use a different
+    font in each top-level window.
+-   Allow editing above start and below end of buffer (flag in 'virtualedit').
+-   Smart cut/paste: recognize words and adjust spaces before/after them.
+-   Add open mode, use it when terminal has no cursor positioning.
+-   Special "drawing mode": a line is drawn where the cursor is moved to.
+    Backspace deletes along the line (from jvim).
+-   Implement ":Bset", set option in all buffers.  Also ":Wset", set in all
+    windows, ":Aset, set in all arguments and ":Tset", set in all files
+    mentioned in the tags file.
+    Add buffer/arg range, like in ":2,5B%s/..." (do we really need this???)
+    Add search string: "B/*.c/%s/.."?  Or ":F/*.c/%s/.."?
+-   Support for underlining (underscore-BS-char), bold (char-BS-char) and other
+    standout modes switched on/off with , 'overstrike' option (Reiter).
+-   Add vertical mode (Paul Jury, Demirel): "5vdw" deletes a word in five
+    lines, "3vitextESC" will insert "text" in three lines, etc..
+4   Recognize l, #, p as 'flags' to EX commands:
+    :g/RE/#l shall print lines with line numbers and in list format.
+    :g/RE/dp shall print lines that are deleted.
+    POSIX: Commands where flags shall apply to all lines written: list,
+    number, open, print, substitute, visual, &, z.  For other commands, flags
+    shall apply to the current line after the command completes.  Examples:
+    :7,10j #l Join the lines 7-10 and print the result in list
+-   Allow two or more users to edit the same file at the same time.  Changes
+    are reflected in each Vim immediately.  Could work with local files but
+    also over the internet.  See http://www.codingmonkeys.de/subethaedit/.
+
+When using "do" or ":diffget" in a buffer with changes in every line an extra
+empty line would appear.
+
+vim:tw=78:sw=4:sts=4:ts=8:ft=help:norl:
+vim: set fo+=n :
--- /dev/null
+++ b/lib/vimfiles/doc/uganda.txt
@@ -1,0 +1,288 @@
+*uganda.txt*    For Vim version 7.1.  Last change: 2007 May 05
+
+
+		  VIM REFERENCE MANUAL    by Bram Moolenaar
+
+
+			*uganda* *Uganda* *copying* *copyright* *license*
+SUMMARY
+								*iccf* *ICCF*
+Vim is Charityware.  You can use and copy it as much as you like, but you are
+encouraged to make a donation for needy children in Uganda.  Please see |kcc|
+below or visit the ICCF web site, available at these URLs:
+
+	http://iccf-holland.org/
+	http://www.vim.org/iccf/
+	http://www.iccf.nl/
+
+You can also sponsor the development of Vim.  Vim sponsors can vote for
+features.  See |sponsor|.  The money goes to Uganda anyway.
+
+The Open Publication License applies to the Vim documentation, see
+|manual-copyright|.
+
+=== begin of license ===
+
+VIM LICENSE
+
+I)  There are no restrictions on distributing unmodified copies of Vim except
+    that they must include this license text.  You can also distribute
+    unmodified parts of Vim, likewise unrestricted except that they must
+    include this license text.  You are also allowed to include executables
+    that you made from the unmodified Vim sources, plus your own usage
+    examples and Vim scripts.
+
+II) It is allowed to distribute a modified (or extended) version of Vim,
+    including executables and/or source code, when the following four
+    conditions are met:
+    1) This license text must be included unmodified.
+    2) The modified Vim must be distributed in one of the following five ways:
+       a) If you make changes to Vim yourself, you must clearly describe in
+	  the distribution how to contact you.  When the maintainer asks you
+	  (in any way) for a copy of the modified Vim you distributed, you
+	  must make your changes, including source code, available to the
+	  maintainer without fee.  The maintainer reserves the right to
+	  include your changes in the official version of Vim.  What the
+	  maintainer will do with your changes and under what license they
+	  will be distributed is negotiable.  If there has been no negotiation
+	  then this license, or a later version, also applies to your changes.
+	  The current maintainer is Bram Moolenaar <Bram@vim.org>.  If this
+	  changes it will be announced in appropriate places (most likely
+	  vim.sf.net, www.vim.org and/or comp.editors).  When it is completely
+	  impossible to contact the maintainer, the obligation to send him
+	  your changes ceases.  Once the maintainer has confirmed that he has
+	  received your changes they will not have to be sent again.
+       b) If you have received a modified Vim that was distributed as
+	  mentioned under a) you are allowed to further distribute it
+	  unmodified, as mentioned at I).  If you make additional changes the
+	  text under a) applies to those changes.
+       c) Provide all the changes, including source code, with every copy of
+	  the modified Vim you distribute.  This may be done in the form of a
+	  context diff.  You can choose what license to use for new code you
+	  add.  The changes and their license must not restrict others from
+	  making their own changes to the official version of Vim.
+       d) When you have a modified Vim which includes changes as mentioned
+	  under c), you can distribute it without the source code for the
+	  changes if the following three conditions are met:
+	  - The license that applies to the changes permits you to distribute
+	    the changes to the Vim maintainer without fee or restriction, and
+	    permits the Vim maintainer to include the changes in the official
+	    version of Vim without fee or restriction.
+	  - You keep the changes for at least three years after last
+	    distributing the corresponding modified Vim.  When the maintainer
+	    or someone who you distributed the modified Vim to asks you (in
+	    any way) for the changes within this period, you must make them
+	    available to him.
+	  - You clearly describe in the distribution how to contact you.  This
+	    contact information must remain valid for at least three years
+	    after last distributing the corresponding modified Vim, or as long
+	    as possible.
+       e) When the GNU General Public License (GPL) applies to the changes,
+	  you can distribute the modified Vim under the GNU GPL version 2 or
+	  any later version.
+    3) A message must be added, at least in the output of the ":version"
+       command and in the intro screen, such that the user of the modified Vim
+       is able to see that it was modified.  When distributing as mentioned
+       under 2)e) adding the message is only required for as far as this does
+       not conflict with the license used for the changes.
+    4) The contact information as required under 2)a) and 2)d) must not be
+       removed or changed, except that the person himself can make
+       corrections.
+
+III) If you distribute a modified version of Vim, you are encouraged to use
+     the Vim license for your changes and make them available to the
+     maintainer, including the source code.  The preferred way to do this is
+     by e-mail or by uploading the files to a server and e-mailing the URL.
+     If the number of changes is small (e.g., a modified Makefile) e-mailing a
+     context diff will do.  The e-mail address to be used is
+     <maintainer@vim.org>
+
+IV)  It is not allowed to remove this license from the distribution of the Vim
+     sources, parts of it or from a modified version.  You may use this
+     license for previous Vim releases instead of the license that they came
+     with, at your option.
+
+=== end of license ===
+
+Note:
+
+- If you are happy with Vim, please express that by reading the rest of this
+  file and consider helping needy children in Uganda.
+
+- If you want to support further Vim development consider becoming a
+  |sponsor|.  The money goes to Uganda anyway.
+
+- According to Richard Stallman the Vim license is GNU GPL compatible.
+  A few minor changes have been made since he checked it, but that should not
+  make a difference.
+
+- If you link Vim with a library that goes under the GNU GPL, this limits
+  further distribution to the GNU GPL.  Also when you didn't actually change
+  anything in Vim.
+
+- Once a change is included that goes under the GNU GPL, this forces all
+  further changes to also be made under the GNU GPL or a compatible license.
+
+- If you distribute a modified version of Vim, you can include your name and
+  contact information with the "--with-modified-by" configure argument or the
+  MODIFIED_BY define.
+
+==============================================================================
+Kibaale Children's Centre						*kcc*
+
+Kibaale Children's Centre (KCC) is located in Kibaale, a small town in the
+south of Uganda, near Tanzania, in East Africa.  The area is known as Rakai
+District.  The population is mostly farmers.  Although people are poor, there
+is enough food.  But this district is suffering from AIDS more than any other
+part of the world.  Some say that it started there.  Estimations are that 10
+to 30% of the Ugandans are infected with HIV.  Because parents die, there are
+many orphans.  In this district about 60,000 children have lost one or both
+parents, out of a population of 350,000.  And this is still continuing.
+
+The children need a lot of help.  The KCC is working hard to provide the needy
+with food, medical care and education.  Food and medical care to keep them
+healthy now, and education so that they can take care of themselves in the
+future.  KCC works on a Christian base, but help is given to children of any
+religion.
+
+The key to solving the problems in this area is education.  This has been
+neglected in the past years with president Idi Amin and the following civil
+wars.  Now that the government is stable again, the children and parents have
+to learn how to take care of themselves and how to avoid infections.  There is
+also help for people who are ill and hungry, but the primary goal is to
+prevent people from getting ill and to teach them how to grow healthy food.
+
+Most of the orphans are living in an extended family.  An uncle or older
+sister is taking care of them.  Because these families are big and the income
+(if any) is low, a child is lucky if it gets healthy food.  Clothes, medical
+care and schooling is beyond its reach.  To help these needy children, a
+sponsorship program was put into place.  A child can be financially adopted.
+For a few dollars a month KCC sees to it that the child gets indispensable
+items, is healthy, goes to school and KCC takes care of anything else that
+needs to be done for the child and the family that supports it.
+
+Besides helping the child directly, the environment where the child grows up
+needs to be improved.  KCC helps schools to improve their teaching methods.
+There is a demonstration school at the centre and teacher trainings are given.
+Health workers are being trained, hygiene education is carried out and
+households are stimulated to build a proper latrine.  I helped setting up a
+production site for cement slabs.  These are used to build a good latrine.
+They are sold below cost price.
+
+There is a small clinic at the project, which provides children and their
+family with medical help.  When needed, transport to a hospital is offered.
+Immunization programs are carried out and help is provided when an epidemic is
+breaking out (measles and cholera have been a problem).
+							*donate*
+Summer 1994 to summer 1995 I spent a whole year at the centre, working as a
+volunteer.  I have helped to expand the centre and worked in the area of water
+and sanitation.  I learned that the help that the KCC provides really helps.
+Now that I'm back in Holland, I would like to continue supporting KCC.  To do
+this I'm raising funds and organizing the sponsorship program.  Please
+consider one of these possibilities:
+
+1.  Sponsor a child in primary school: 17 euro a month (or more).
+2.  Sponsor a child in secondary school: 25 euro a month (or more).
+3.  Sponsor the clinic: Any amount a month or quarter
+4.  A one-time donation
+
+Compared with other organizations that do child sponsorship the amounts are
+very low.  This is because the money goes directly to the centre.  Less than
+5% is used for administration.  This is possible because this is a small
+organization that works with volunteers.  If you would like to sponsor a
+child, you should have the intention to do this for at least one year.
+
+How do you know that the money will be spent right?  First of all you have my
+personal guarantee as the author of Vim.  I trust the people that are working
+at the centre, I know them personally.  Further more, the centre is
+co-sponsored and inspected by World Vision, Save the Children Fund and
+International Child Care Fund.  The centre is visited about once a year to
+check the progress (at our own cost).  I have visited the centre myself in
+1996, 1998, 2000, 2001 and 2003.  The visit reports are on the ICCF web site.
+
+If you have any further questions, send me e-mail: <Bram@vim.org>.
+
+The address of the centre is:
+			Kibaale Children's Centre
+			p.o. box 1658
+			Masaka, Uganda, East Africa
+
+Sending money:						*iccf-donations*
+
+Check the ICCF web site for the latest information!  See |iccf| for the URL.
+
+
+USA:		The methods mentioned below can be used.
+		Sending a check to the Nehemiah Group Outreach Society (NGOS)
+		is no longer possible, unfortunately. We are looking for
+		another way to get you an IRS tax receipt. 
+		For sponsoring a child contact KCF in Canada (see below). US
+		checks can be send to them to lower banking costs.
+
+Canada:		Contact Kibaale Children's Fund (KCF) in Surrey, Canada.  They
+		take care of the Canadian sponsors for the children in
+		Kibaale.  KCF forwards 100% of the money to the project in
+		Uganda.  You can send them a one time donation directly.
+		Please send me a note so that I know what has been donated
+		because of Vim.  Ask KCF for information about sponsorship.
+			Kibaale Children's Fund c/o Pacific Academy
+			10238-168 Street
+			Surrey, B.C. V4N 1Z4
+			Canada
+			Phone: 604-581-5353
+		If you make a donation to Kibaale Children's Fund (KCF) you
+		will receive a tax receipt which can be submitted with your
+		tax return.
+
+Holland:	Transfer to the account of "Stichting ICCF Holland" in Venlo.
+		This will allow for tax deduction if you live in Holland.
+			Postbank, nr. 4548774
+
+Germany:	It is possible to make donations that allow for a tax return.
+		Check the ICCF web site for the latest information:
+			http://iccf-holland.org/germany.html
+
+World:		Use a postal money order.  That should be possible from any
+		country, mostly from the post office.  Use this name (which is
+		in my passport): "Abraham Moolenaar".  Use Euro for the
+		currency if possible.
+
+Europe:		Use a bank transfer if possible.  Your bank should have a form
+		that you can use for this.  See "Others" below for the swift
+		code and IBAN number.
+		Any other method should work.  Ask for information about
+		sponsorship.
+
+Credit Card:	You can use PayPal to send money with a Credit card.  This is
+		the most widely used Internet based payment system.  It's
+		really simple to use.  Use this link to find more info:
+		    https://www.paypal.com/en_US/mrb/pal=XAC62PML3GF8Q
+		The e-mail address for sending the money to is:
+		    Bram@iccf-holland.org
+		For amounts above 400 Euro ($500) sending a check is
+		preferred.
+
+Others:		Transfer to one of these accounts if possible:
+		    Postbank, account 4548774
+				Swift code: INGB NL 2A
+				IBAN: NL47 PSTB 0004 5487 74
+			under the name "stichting ICCF Holland", Venlo
+		    If that doesn't work:
+		    Rabobank Venlo, account 3765.05.117
+				Swift code: RABO NL 2U
+			under the name "Bram Moolenaar", Venlo
+		Otherwise, send a check in euro or US dollars to the address
+		below.  Minimal amount: $70 (my bank does not accept smaller
+		amounts for foreign check, sorry)
+
+Address to send checks to:
+			stichting ICCF Holland
+			Bram Moolenaar
+			Molenstraat 2
+			2161 HP Lisse
+			The Netherlands
+
+This address is expected to be valid for a long time.  The address in Venlo
+will not be valid after June 2006.
+
+ vim:tw=78:ts=8:ft=help:norl:
--- /dev/null
+++ b/lib/vimfiles/doc/undo.txt
@@ -1,0 +1,242 @@
+*undo.txt*      For Vim version 7.1.  Last change: 2006 Apr 30
+
+
+		  VIM REFERENCE MANUAL    by Bram Moolenaar
+
+
+Undo and redo						*undo-redo*
+
+The basics are explained in section |02.5| of the user manual.
+
+1. Undo and redo commands	|undo-commands|
+2. Two ways of undo		|undo-two-ways|
+3. Undo blocks			|undo-blocks|
+4. Undo branches		|undo-branches|
+5. Remarks about undo		|undo-remarks|
+
+==============================================================================
+1. Undo and redo commands				*undo-commands*
+
+<Undo>		or					*undo* *<Undo>* *u*
+u			Undo [count] changes.  {Vi: only one level}
+
+							*:u* *:un* *:undo*
+:u[ndo]			Undo one change.  {Vi: only one level}
+
+:u[ndo] {N}		Jump to after change number {N}.  See |undo-branches|
+			for the meaning of {N}.  {not in Vi}
+
+							*CTRL-R*
+CTRL-R			Redo [count] changes which were undone.  {Vi: redraw
+			screen}
+
+							*:red* *:redo* *redo*
+:red[o]			Redo one change which was undone.  {Vi: no redo}
+
+							*U*
+U			Undo all latest changes on one line.  {Vi: while not
+			moved off of it}
+
+The last changes are remembered.  You can use the undo and redo commands above
+to revert the text to how it was before each change.  You can also apply the
+changes again, getting back the text before the undo.
+
+The "U" command is treated by undo/redo just like any other command.  Thus a
+"u" command undoes a "U" command and a 'CTRL-R' command redoes it again.  When
+mixing "U", "u" and 'CTRL-R' you will notice that the "U" command will
+restore the situation of a line to before the previous "U" command.  This may
+be confusing.  Try it out to get used to it.
+The "U" command will always mark the buffer as changed.  When "U" changes the
+buffer back to how it was without changes, it is still considered changed.
+Use "u" to undo changes until the buffer becomes unchanged.
+
+==============================================================================
+2. Two ways of undo					*undo-two-ways*
+
+How undo and redo commands work depends on the 'u' flag in 'cpoptions'.
+There is the Vim way ('u' excluded) and the vi-compatible way ('u' included).
+In the Vim way, "uu" undoes two changes.  In the Vi-compatible way, "uu" does
+nothing (undoes an undo).
+
+'u' excluded, the Vim way:
+You can go back in time with the undo command.  You can then go forward again
+with the redo command.  If you make a new change after the undo command,
+the redo will not be possible anymore.
+
+'u' included, the Vi-compatible way:
+The undo command undoes the previous change, and also the previous undo command.
+The redo command repeats the previous undo command.  It does NOT repeat a
+change command, use "." for that.
+
+Examples	Vim way			Vi-compatible way	~
+"uu"		two times undo		no-op
+"u CTRL-R"	no-op			two times undo
+
+Rationale:  Nvi uses the "." command instead of CTRL-R.  Unfortunately, this
+	    is not Vi compatible.  For example "dwdwu." in Vi deletes two
+	    words, in Nvi it does nothing.
+
+==============================================================================
+3. Undo blocks						*undo-blocks*
+
+One undo command normally undoes a typed command, no matter how many changes
+that command makes.  This sequence of undo-able changes forms an undo block.
+Thus if the typed key(s) call a function, all the commands in the function are
+undone together.
+
+If you want to write a function or script that doesn't create a new undoable
+change but joins in with the previous change use this command:
+
+						*:undoj* *:undojoin* *E790*
+:undoj[oin]		Join further changes with the previous undo block.
+			Warning: Use with care, it may prevent the user from
+			properly undoing changes.  Don't use this after undo
+			or redo.
+			{not in Vi}
+
+This is most useful when you need to prompt the user halfway a change.  For
+example in a function that calls |getchar()|.  Do make sure that there was a
+related change before this that you must join with.
+
+This doesn't work by itself, because the next key press will start a new
+change again.  But you can do something like this: >
+
+	:undojoin | delete
+
+After this an "u" command will undo the delete command and the previous
+change.
+
+==============================================================================
+4. Undo branches				*undo-branches* *undo-tree*
+
+Above we only discussed one line of undo/redo.  But it is also possible to
+branch off.  This happens when you undo a few changes and then make a new
+change.  The undone changes become a branch.  You can go to that branch with
+the following commands.
+
+This is explained in the user manual: |usr_32.txt|.
+
+							*:undol* *:undolist*
+:undol[ist]		List the leafs in the tree of changes.  Example:
+				number changes   time ~
+				4      10	 10:34:11
+				18     4	 11:01:46
+
+			The "number" column is the change number.  This number
+			continuously increases and can be used to identify a
+			specific undo-able change, see |:undo|.
+			The "changes" column is the number of changes to this
+			leaf from the root of the tree.
+			The "time" column is the time this change was made.
+
+							*g-*
+g-			Go to older text state.  With a count repeat that many
+			times.  {not in Vi}
+							*:ea* *:earlier*
+:earlier {count}	Go to older text state {count} times.
+:earlier {N}s		Go to older text state about {N} seconds before.
+:earlier {N}m		Go to older text state about {N} minutes before.
+:earlier {N}h		Go to older text state about {N} hours before.
+
+							*g+*
+g+			Go to newer text state.  With a count repeat that many
+			times.  {not in Vi}
+							*:lat* *:later*
+:later {count}		Go to newer text state {count} times.
+:later {N}s		Go to newer text state about {N} seconds later.
+:later {N}m		Go to newer text state about {N} minutes later.
+:later {N}h		Go to newer text state about {N} hours later.
+
+
+Note that text states will become unreachable when undo information is cleared
+for 'undolevels'.
+
+Don't be surprised when moving through time shows multiple changes to take
+place at a time.  This happens when moving through the undo tree and then
+making a new change.
+
+EXAMPLE
+
+Start with this text:
+	one two three ~
+
+Delete the first word by pressing "x" three times:
+	ne two three ~
+	e two three ~
+	 two three ~
+
+Now undo that by pressing "u" three times:
+	e two three ~
+	ne two three ~
+	one two three ~
+
+Delete the second word by pressing "x" three times:
+	one wo three ~
+	one o three ~
+	one  three ~
+
+Now undo that by using "g-" three times:
+	one o three ~
+	one wo three ~
+	 two three ~
+
+You are now back in the first undo branch, after deleting "one".  Repeating
+"g-" will now bring you back to the original text:
+	e two three ~
+	ne two three ~
+	one two three ~
+
+Jump to the last change with ":later 1h":
+	one  three ~
+
+And back to the start again with ":earlier 1h":
+	one two three ~
+
+
+Note that using "u" and CTRL-R will not get you to all possible text states
+while repeating "g-" and "g+" does.
+
+==============================================================================
+5. Remarks about undo					*undo-remarks*
+
+The number of changes that are remembered is set with the 'undolevels' option.
+If it is zero, the Vi-compatible way is always used.  If it is negative no
+undo is possible.  Use this if you are running out of memory.
+
+Marks for the buffer ('a to 'z) are also saved and restored, together with the
+text.  {Vi does this a little bit different}
+
+When all changes have been undone, the buffer is not considered to be changed.
+It is then possible to exit Vim with ":q" instead of ":q!" {not in Vi}.  Note
+that this is relative to the last write of the file.  Typing "u" after ":w"
+actually changes the buffer, compared to what was written, so the buffer is
+considered changed then.
+
+When manual |folding| is being used, the folds are not saved and restored.
+Only changes completely within a fold will keep the fold as it was, because
+the first and last line of the fold don't change.
+
+The numbered registers can also be used for undoing deletes.  Each time you
+delete text, it is put into register "1.  The contents of register "1 are
+shifted to "2, etc.  The contents of register "9 are lost.  You can now get
+back the most recent deleted text with the put command: '"1P'.  (also, if the
+deleted text was the result of the last delete or copy operation, 'P' or 'p'
+also works as this puts the contents of the unnamed register).  You can get
+back the text of three deletes ago with '"3P'.
+
+						*redo-register*
+If you want to get back more than one part of deleted text, you can use a
+special feature of the repeat command ".".  It will increase the number of the
+register used.  So if you first do ""1P", the following "." will result in a
+'"2P'.  Repeating this will result in all numbered registers being inserted.
+
+Example:	If you deleted text with 'dd....' it can be restored with
+		'"1P....'.
+
+If you don't know in which register the deleted text is, you can use the
+:display command.  An alternative is to try the first register with '"1P', and
+if it is not what you want do 'u.'.  This will remove the contents of the
+first put, and repeat the put command for the second register.  Repeat the
+'u.' until you got what you want.
+
+ vim:tw=78:ts=8:ft=help:norl:
--- /dev/null
+++ b/lib/vimfiles/doc/usr_01.txt
@@ -1,0 +1,182 @@
+*usr_01.txt*	For Vim version 7.1.  Last change: 2006 Oct 08
+
+		     VIM USER MANUAL - by Bram Moolenaar
+
+			      About the manuals
+
+
+This chapter introduces the manuals available with Vim.  Read this to know the
+conditions under which the commands are explained.
+
+|01.1|	Two manuals
+|01.2|	Vim installed
+|01.3|	Using the Vim tutor
+|01.4|	Copyright
+
+     Next chapter: |usr_02.txt|  The first steps in Vim
+Table of contents: |usr_toc.txt|
+
+==============================================================================
+*01.1*	Two manuals
+
+The Vim documentation consists of two parts:
+
+1. The User manual
+   Task oriented explanations, from simple to complex.  Reads from start to
+   end like a book.
+
+2. The Reference manual
+   Precise description of how everything in Vim works.
+
+The notation used in these manuals is explained here: |notation|
+
+
+JUMPING AROUND
+
+The text contains hyperlinks between the two parts, allowing you to quickly
+jump between the description of an editing task and a precise explanation of
+the commands and options used for it.  Use these two commands:
+
+	Press  CTRL-]  to jump to a subject under the cursor.
+	Press  CTRL-O  to jump back (repeat to go further back).
+
+Many links are in vertical bars, like this: |bars|.  An option name, like
+'number', a command in double quotes like ":write" and any other word can also
+be used as a link.  Try it out: Move the cursor to  CTRL-]  and press CTRL-]
+on it.
+
+Other subjects can be found with the ":help" command, see |help.txt|.
+
+==============================================================================
+*01.2*	Vim installed
+
+Most of the manuals assume that Vim has been properly installed.  If you
+didn't do that yet, or if Vim doesn't run properly (e.g., files can't be found
+or in the GUI the menus do not show up) first read the chapter on
+installation: |usr_90.txt|.
+							*not-compatible*
+The manuals often assume you are using Vim with Vi-compatibility switched
+off.  For most commands this doesn't matter, but sometimes it is important,
+e.g., for multi-level undo.  An easy way to make sure you are using a nice
+setup is to copy the example vimrc file.  By doing this inside Vim you don't
+have to check out where it is located.  How to do this depends on the system
+you are using:
+
+Unix: >
+	:!cp -i $VIMRUNTIME/vimrc_example.vim ~/.vimrc
+MS-DOS, MS-Windows, OS/2: >
+	:!copy $VIMRUNTIME/vimrc_example.vim $VIM/_vimrc
+Amiga: >
+	:!copy $VIMRUNTIME/vimrc_example.vim $VIM/.vimrc
+
+If the file already exists you probably want to keep it.
+
+If you start Vim now, the 'compatible' option should be off.  You can check it
+with this command: >
+
+	:set compatible?
+
+If it responds with "nocompatible" you are doing well.  If the response is
+"compatible" you are in trouble.  You will have to find out why the option is
+still set.  Perhaps the file you wrote above is not found.  Use this command
+to find out: >
+
+	:scriptnames
+
+If your file is not in the list, check its location and name.  If it is in the
+list, there must be some other place where the 'compatible' option is switched
+back on.
+
+For more info see |vimrc| and |compatible-default|.
+
+	Note:
+	This manual is about using Vim in the normal way.  There is an
+	alternative called "evim" (easy Vim).  This is still Vim, but used in
+	a way that resembles a click-and-type editor like Notepad.  It always
+	stays in Insert mode, thus it feels very different.  It is not
+	explained in the user manual, since it should be mostly self
+	explanatory.  See |evim-keys| for details.
+
+==============================================================================
+*01.3*	Using the Vim tutor				*tutor* *vimtutor*
+
+Instead of reading the text (boring!) you can use the vimtutor to learn your
+first Vim commands.  This is a 30 minute tutorial that teaches the most basic
+Vim functionality hands-on.
+
+On Unix, if Vim has been properly installed, you can start it from the shell:
+>
+	vimtutor
+
+On MS-Windows you can find it in the Program/Vim menu.  Or execute
+vimtutor.bat in the $VIMRUNTIME directory.
+
+This will make a copy of the tutor file, so that you can edit it without
+the risk of damaging the original.
+   There are a few translated versions of the tutor.  To find out if yours is
+available, use the two-letter language code.  For French: >
+
+	vimtutor fr
+
+For OpenVMS, if Vim has been properly installed, you can start vimtutor from a
+VMS prompt with: >
+
+	@VIM:vimtutor
+
+Optionally add the two-letter language code as above.
+
+
+On other systems, you have to do a little work:
+
+1. Copy the tutor file.  You can do this with Vim (it knows where to find it):
+>
+	vim -u NONE -c 'e $VIMRUNTIME/tutor/tutor' -c 'w! TUTORCOPY' -c 'q'
+<
+   This will write the file "TUTORCOPY" in the current directory.  To use a
+translated version of the tutor, append the two-letter language code to the
+filename.  For French:
+>
+	vim -u NONE -c 'e $VIMRUNTIME/tutor/tutor.fr' -c 'w! TUTORCOPY' -c 'q'
+<
+2. Edit the copied file with Vim:
+>
+	vim -u NONE -c "set nocp" TUTORCOPY
+<
+   The extra arguments make sure Vim is started in a good mood.
+
+3. Delete the copied file when you are finished with it:
+>
+	del TUTORCOPY
+<
+==============================================================================
+*01.4*	Copyright					*manual-copyright*
+
+The Vim user manual and reference manual are Copyright (c) 1988-2003 by Bram
+Moolenaar.  This material may be distributed only subject to the terms and
+conditions set forth in the Open Publication License, v1.0 or later.  The
+latest version is presently available at:
+	     http://www.opencontent.org/openpub/
+
+People who contribute to the manuals must agree with the above copyright
+notice.
+							*frombook*
+Parts of the user manual come from the book "Vi IMproved - Vim" by Steve
+Oualline (published by New Riders Publishing, ISBN: 0735710015).  The Open
+Publication License applies to this book.  Only selected parts are included
+and these have been modified (e.g., by removing the pictures, updating the
+text for Vim 6.0 and later, fixing mistakes).  The omission of the |frombook|
+tag does not mean that the text does not come from the book.
+
+Many thanks to Steve Oualline and New Riders for creating this book and
+publishing it under the OPL!  It has been a great help while writing the user
+manual.  Not only by providing literal text, but also by setting the tone and
+style.
+
+If you make money through selling the manuals, you are strongly encouraged to
+donate part of the profit to help AIDS victims in Uganda.  See |iccf|.
+
+==============================================================================
+
+Next chapter: |usr_02.txt|  The first steps in Vim
+
+Copyright: see |manual-copyright|  vim:tw=78:ts=8:ft=help:norl:
--- /dev/null
+++ b/lib/vimfiles/doc/usr_02.txt
@@ -1,0 +1,564 @@
+*usr_02.txt*	For Vim version 7.1.  Last change: 2007 Feb 28
+
+		     VIM USER MANUAL - by Bram Moolenaar
+
+			    The first steps in Vim
+
+
+This chapter provides just enough information to edit a file with Vim.  Not
+well or fast, but you can edit.  Take some time to practice with these
+commands, they form the base for what follows.
+
+|02.1|	Running Vim for the First Time
+|02.2|	Inserting text
+|02.3|	Moving around
+|02.4|	Deleting characters
+|02.5|	Undo and Redo
+|02.6|	Other editing commands
+|02.7|	Getting out
+|02.8|	Finding help
+
+     Next chapter: |usr_03.txt|  Moving around
+ Previous chapter: |usr_01.txt|  About the manuals
+Table of contents: |usr_toc.txt|
+
+==============================================================================
+*02.1*	Running Vim for the First Time
+
+To start Vim, enter this command: >
+
+	gvim file.txt
+
+In UNIX you can type this at any command prompt.  If you are running Microsoft
+Windows, open an MS-DOS prompt window and enter the command.
+   In either case, Vim starts editing a file called file.txt.  Because this
+is a new file, you get a blank window. This is what your screen will look
+like:
+
+	+---------------------------------------+
+	|#					|
+	|~					|
+	|~					|
+	|~					|
+	|~					|
+	|"file.txt" [New file]			|
+	+---------------------------------------+
+		('#" is the cursor position.)
+
+The tilde (~) lines indicate lines not in the file.  In other words, when Vim
+runs out of file to display, it displays tilde lines.  At the bottom of the
+screen, a message line indicates the file is named file.txt and shows that you
+are creating a new file.  The message information is temporary and other
+information overwrites it.
+
+
+THE VIM COMMAND
+
+The gvim command causes the editor to create a new window for editing.  If you
+use this command: >
+
+	vim file.txt
+
+the editing occurs inside your command window.  In other words, if you are
+running inside an xterm, the editor uses your xterm window.  If you are using
+an MS-DOS command prompt window under Microsoft Windows, the editing occurs
+inside this window.  The text in the window will look the same for both
+versions, but with gvim you have extra features, like a menu bar.  More about
+that later.
+
+==============================================================================
+*02.2*	Inserting text
+
+The Vim editor is a modal editor.  That means that the editor behaves
+differently, depending on which mode you are in.  The two basic modes are
+called Normal mode and Insert mode.  In Normal mode the characters you type
+are commands.  In Insert mode the characters are inserted as text.
+   Since you have just started Vim it will be in Normal mode.  To start Insert
+mode you type the "i" command (i for Insert).  Then you can enter
+the text.  It will be inserted into the file.  Do not worry if you make
+mistakes; you can correct them later.  To enter the following programmer's
+limerick, this is what you type: >
+
+	iA very intelligent turtle
+	Found programming UNIX a hurdle
+
+After typing "turtle" you press the <Enter> key to start a new line.  Finally
+you press the <Esc> key to stop Insert mode and go back to Normal mode.  You
+now have two lines of text in your Vim window:
+
+	+---------------------------------------+
+	|A very intelligent turtle		|
+	|Found programming UNIX a hurdle	|
+	|~					|
+	|~					|
+	|					|
+	+---------------------------------------+
+
+
+WHAT IS THE MODE?
+
+To be able to see what mode you are in, type this command: >
+
+	:set showmode
+
+You will notice that when typing the colon Vim moves the cursor to the last
+line of the window.  That's where you type colon commands (commands that start
+with a colon).  Finish this command by pressing the <Enter> key (all commands
+that start with a colon are finished this way).
+   Now, if you type the "i" command Vim will display --INSERT-- at the bottom
+of the window.  This indicates you are in Insert mode.
+
+	+---------------------------------------+
+	|A very intelligent turtle		|
+	|Found programming UNIX a hurdle	|
+	|~					|
+	|~					|
+	|-- INSERT --				|
+	+---------------------------------------+
+
+If you press <Esc> to go back to Normal mode the last line will be made blank.
+
+
+GETTING OUT OF TROUBLE
+
+One of the problems for Vim novices is mode confusion, which is caused by
+forgetting which mode you are in or by accidentally typing a command that
+switches modes.  To get back to Normal mode, no matter what mode you are in,
+press the <Esc> key.  Sometimes you have to press it twice.  If Vim beeps back
+at you, you already are in Normal mode.
+
+==============================================================================
+*02.3*	Moving around
+
+After you return to Normal mode, you can move around by using these keys:
+
+	h   left						*hjkl*
+	j   down
+	k   up
+	l   right
+
+At first, it may appear that these commands were chosen at random.  After all,
+who ever heard of using l for right?  But actually, there is a very good
+reason for these choices: Moving the cursor is the most common thing you do in
+an editor, and these keys are on the home row of your right hand.  In other
+words, these commands are placed where you can type them the fastest
+(especially when you type with ten fingers).
+
+	Note:
+	You can also move the cursor by using the arrow keys.  If you do,
+	however, you greatly slow down your editing because to press the arrow
+	keys, you must move your hand from the text keys to the arrow keys.
+	Considering that you might be doing it hundreds of times an hour, this
+	can take a significant amount of time.
+	   Also, there are keyboards which do not have arrow keys, or which
+	locate them in unusual places; therefore, knowing the use of the hjkl
+	keys helps in those situations.
+
+One way to remember these commands is that h is on the left, l is on the
+right and j points down.  In a picture: >
+
+		       k
+		   h     l
+		     j
+
+The best way to learn these commands is by using them.  Use the "i" command to
+insert some more lines of text.  Then use the hjkl keys to move around and
+insert a word somewhere.  Don't forget to press <Esc> to go back to Normal
+mode.  The |vimtutor| is also a nice way to learn by doing.
+
+For Japanese users, Hiroshi Iwatani suggested using this:
+
+			Komsomolsk
+			    ^
+			    |
+	   Huan Ho	<--- --->  Los Angeles
+	(Yellow river)	    |
+			    v
+			  Java (the island, not the programming language)
+
+==============================================================================
+*02.4*	Deleting characters
+
+To delete a character, move the cursor over it and type "x".  (This is a
+throwback to the old days of the typewriter, when you deleted things by typing
+xxxx over them.)  Move the cursor to the beginning of the first line, for
+example, and type xxxxxxx (seven x's) to delete "A very ".  The result should
+look like this:
+
+	+---------------------------------------+
+	|intelligent turtle			|
+	|Found programming UNIX a hurdle	|
+	|~					|
+	|~					|
+	|					|
+	+---------------------------------------+
+
+Now you can insert new text, for example by typing: >
+
+	iA young <Esc>
+
+This begins an insert (the i), inserts the words "A young", and then exits
+insert mode (the final <Esc>).	The result:
+
+	+---------------------------------------+
+	|A young intelligent turtle		|
+	|Found programming UNIX a hurdle	|
+	|~					|
+	|~					|
+	|					|
+	+---------------------------------------+
+
+
+DELETING A LINE
+
+To delete a whole line use the "dd" command.  The following line will
+then move up to fill the gap:
+
+	+---------------------------------------+
+	|Found programming UNIX a hurdle	|
+	|~					|
+	|~					|
+	|~					|
+	|					|
+	+---------------------------------------+
+
+
+DELETING A LINE BREAK
+
+In Vim you can join two lines together, which means that the line break
+between them is deleted.  The "J" command does this.
+   Take these two lines:
+
+	A young intelligent ~
+	turtle ~
+
+Move the cursor to the first line and press "J":
+
+	A young intelligent turtle ~
+
+==============================================================================
+*02.5*	Undo and Redo
+
+Suppose you delete too much.  Well, you can type it in again, but an easier
+way exists.  The "u" command undoes the last edit.  Take a look at this in
+action: After using "dd" to delete the first line, "u" brings it back.
+   Another one: Move the cursor to the A in the first line:
+
+	A young intelligent turtle ~
+
+Now type xxxxxxx to delete "A young".  The result is as follows:
+
+	 intelligent turtle ~
+
+Type "u" to undo the last delete.  That delete removed the g, so the undo
+restores the character.
+
+	g intelligent turtle ~
+
+The next u command restores the next-to-last character deleted:
+
+	ng intelligent turtle ~
+
+The next u command gives you the u, and so on:
+
+	ung intelligent turtle ~
+	oung intelligent turtle ~
+	young intelligent turtle ~
+	 young intelligent turtle ~
+	A young intelligent turtle ~
+
+	Note:
+	If you type "u" twice, and the result is that you get the same text
+	back, you have Vim configured to work Vi compatible.  Look here to fix
+	this: |not-compatible|.
+	   This text assumes you work "The Vim Way".  You might prefer to use
+	the good old Vi way, but you will have to watch out for small
+	differences in the text then.
+
+
+REDO
+
+If you undo too many times, you can press CTRL-R (redo) to reverse the
+preceding command.  In other words, it undoes the undo.  To see this in
+action, press CTRL-R twice.  The character A and the space after it disappear:
+
+	young intelligent turtle ~
+
+There's a special version of the undo command, the "U" (undo line) command.
+The undo line command undoes all the changes made on the last line that was
+edited.  Typing this command twice cancels the preceding "U".
+
+	A very intelligent turtle ~
+	  xxxx				Delete very
+
+	A intelligent turtle ~
+		      xxxxxx		Delete turtle
+
+	A intelligent ~
+					Restore line with "U"
+	A very intelligent turtle ~
+					Undo "U" with "u"
+	A intelligent ~
+
+The "U" command is a change by itself, which the "u" command undoes and CTRL-R
+redoes.  This might be a bit confusing.  Don't worry, with "u" and CTRL-R you
+can go to any of the situations you had.  More about that in section |32.1|.
+
+==============================================================================
+*02.6*	Other editing commands
+
+Vim has a large number of commands to change the text.  See |Q_in| and below.
+Here are a few often used ones.
+
+
+APPENDING
+
+The "i" command inserts a character before the character under the cursor.
+That works fine; but what happens if you want to add stuff to the end of the
+line?  For that you need to insert text after the cursor.  This is done with
+the "a" (append) command.
+   For example, to change the line
+
+	and that's not saying much for the turtle. ~
+to
+	and that's not saying much for the turtle!!! ~
+
+move the cursor over to the dot at the end of the line. Then type "x" to
+delete the period.  The cursor is now positioned at the end of the line on the
+e in turtle.  Now type >
+
+	a!!!<Esc>
+
+to append three exclamation points after the e in turtle:
+
+	and that's not saying much for the turtle!!! ~
+
+
+OPENING UP A NEW LINE
+
+The "o" command creates a new, empty line below the cursor and puts Vim in
+Insert mode.  Then you can type the text for the new line.
+   Suppose the cursor is somewhere in the first of these two lines:
+
+	A very intelligent turtle ~
+	Found programming UNIX a hurdle ~
+
+If you now use the "o" command and type new text: >
+
+	oThat liked using Vim<Esc>
+
+The result is:
+
+	A very intelligent turtle ~
+	That liked using Vim ~
+	Found programming UNIX a hurdle ~
+
+The "O" command (uppercase) opens a line above the cursor.
+
+
+USING A COUNT
+
+Suppose you want to move up nine lines.  You can type "kkkkkkkkk" or you can
+enter the command "9k".  In fact, you can precede many commands with a number.
+Earlier in this chapter, for instance, you added three exclamation points to
+the end of a line by typing "a!!!<Esc>".  Another way to do this is to use the
+command "3a!<Esc>".  The count of 3 tells the command that follows to triple
+its effect.  Similarly, to delete three characters, use the command "3x".  The
+count always comes before the command it applies to.
+
+==============================================================================
+*02.7*	Getting out
+
+To exit, use the "ZZ" command.  This command writes the file and exits.
+
+	Note:
+	Unlike many other editors, Vim does not automatically make a backup
+	file.  If you type "ZZ", your changes are committed and there's no
+	turning back.  You can configure the Vim editor to produce backup
+	files, see |07.4|.
+
+
+DISCARDING CHANGES
+
+Sometimes you will make a sequence of changes and suddenly realize you were
+better off before you started.  Not to worry; Vim has a
+quit-and-throw-things-away command.  It is: >
+
+	:q!
+
+Don't forget to press <Enter> to finish the command.
+
+For those of you interested in the details, the three parts of this command
+are the colon (:), which enters Command-line mode; the q command, which tells
+the editor to quit; and the override command modifier (!).
+   The override command modifier is needed because Vim is reluctant to throw
+away changes.  If you were to just type ":q", Vim would display an error
+message and refuse to exit:
+
+	E37: No write since last change (use ! to override) ~
+
+By specifying the override, you are in effect telling Vim, "I know that what
+I'm doing looks stupid, but I'm a big boy and really want to do this."
+
+If you want to continue editing with Vim: The ":e!" command reloads the
+original version of the file.
+
+==============================================================================
+*02.8*	Finding help
+
+Everything you always wanted to know can be found in the Vim help files.
+Don't be afraid to ask!
+   To get generic help use this command: >
+
+	:help
+
+You could also use the first function key <F1>.  If your keyboard has a <Help>
+key it might work as well.
+   If you don't supply a subject, ":help" displays the general help window.
+The creators of Vim did something very clever (or very lazy) with the help
+system: They made the help window a normal editing window.  You can use all
+the normal Vim commands to move through the help information.  Therefore h, j,
+k, and l move left, down, up and right.
+   To get out of the help window, use the same command you use to get out of
+the editor: "ZZ".  This will only close the help window, not exit Vim.
+
+As you read the help text, you will notice some text enclosed in vertical bars
+(for example, |help|).  This indicates a hyperlink.  If you position the
+cursor anywhere between the bars and press CTRL-] (jump to tag), the help
+system takes you to the indicated subject.  (For reasons not discussed here,
+the Vim terminology for a hyperlink is tag.  So CTRL-] jumps to the location
+of the tag given by the word under the cursor.)
+   After a few jumps, you might want to go back.  CTRL-T (pop tag) takes you
+back to the preceding position.  CTRL-O (jump to older position) also works
+nicely here.
+   At the top of the help screen, there is the notation *help.txt*.  This name
+between "*" characters is used by the help system to define a tag (hyperlink
+destination).
+   See |29.1| for details about using tags.
+
+To get help on a given subject, use the following command: >
+
+	:help {subject}
+
+To get help on the "x" command, for example, enter the following: >
+
+	:help x
+
+To find out how to delete text, use this command: >
+
+	:help deleting
+
+To get a complete index of all Vim commands, use the following command: >
+
+	:help index
+
+When you need to get help for a control character command (for example,
+CTRL-A), you need to spell it with the prefix "CTRL-". >
+
+	:help CTRL-A
+
+The Vim editor has many different modes.  By default, the help system displays
+the normal-mode commands.  For example, the following command displays help
+for the normal-mode CTRL-H command: >
+
+	:help CTRL-H
+
+To identify other modes, use a mode prefix.  If you want the help for the
+insert-mode version of a command, use "i_".  For CTRL-H this gives you the
+following command: >
+
+	:help i_CTRL-H
+
+When you start the Vim editor, you can use several command-line arguments.
+These all begin with a dash (-).  To find what the -t argument does, for
+example, use the command: >
+
+	:help -t
+
+The Vim editor has a number of options that enable you to configure and
+customize the editor.  If you want help for an option, you need to enclose it
+in single quotation marks.  To find out what the 'number' option does, for
+example, use the following command: >
+
+	:help 'number'
+
+The table with all mode prefixes can be found here: |help-context|.
+
+Special keys are enclosed in angle brackets.  To find help on the up-arrow key
+in Insert mode, for instance, use this command: >
+
+	:help i_<Up>
+
+If you see an error message that you don't understand, for example:
+
+	E37: No write since last change (use ! to override) ~
+
+You can use the error ID at the start to find help about it: >
+
+	:help E37
+
+
+Summary: 					*help-summary*  >
+	:help
+<		Gives you very general help.  Scroll down to see a list of all
+		helpfiles, including those added locally (i.e. not distributed
+		with Vim). >
+	:help user-toc.txt
+<		Table of contents of the User Manual. >
+	:help :subject
+<		Ex-command "subject", for instance the following: >
+	:help :help
+<		Help on getting help. >
+	:help abc
+<		normal-mode command "abc". >
+	:help CTRL-B
+<		Control key <C-B> in Normal mode. >
+	:help i_abc
+	:help i_CTRL-B
+<		The same in Insert mode. >
+	:help v_abc
+	:help v_CTRL-B
+<		The same in Visual mode. >
+	:help c_abc
+	:help c_CTRL-B
+<		The same in Command-line mode. >
+	:help 'subject'
+<		Option 'subject'. >
+	:help subject()
+<		Function "subject". >
+	:help -subject
+<		Command-line option "-subject". >
+	:help +subject
+<		Compile-time feature "+subject'. >
+	:help EventName
+<		Autocommand event "EventName". >
+	:help digraphs.txt
+<		The top of the helpfile "digraph.txt".
+		Similarly for any other helpfile. >
+	:help pattern<Tab>
+<		Find a help tag starting with "pattern".  Repeat <Tab> for
+		others. >
+	:help pattern<Ctrl-D>
+<		See all possible help tag matches "pattern" at once. >
+	:helpgrep pattern
+<		Search the whole text of all help files for pattern "pattern".
+		Jumps to the first match.  Jump to other matches with: >
+	    :cn
+<			next match >
+	    :cprev
+	    :cN
+<			previous match >
+	    :cfirst
+	    :clast
+<			first or last match >
+	    :copen
+	    :cclose
+<			open/close the quickfix window; press <Enter> to jump
+			to the item under the cursor
+
+
+==============================================================================
+
+Next chapter: |usr_03.txt|  Moving around
+
+Copyright: see |manual-copyright|  vim:tw=78:ts=8:ft=help:norl:
--- /dev/null
+++ b/lib/vimfiles/doc/usr_03.txt
@@ -1,0 +1,654 @@
+*usr_03.txt*	For Vim version 7.1.  Last change: 2006 Jun 21
+
+		     VIM USER MANUAL - by Bram Moolenaar
+
+			     Moving around
+
+
+Before you can insert or delete text the cursor has to be moved to the right
+place.  Vim has a large number of commands to position the cursor.  This
+chapter shows you how to use the most important ones.  You can find a list of
+these commands below |Q_lr|.
+
+|03.1|	Word movement
+|03.2|	Moving to the start or end of a line
+|03.3|	Moving to a character
+|03.4|	Matching a parenthesis
+|03.5|	Moving to a specific line
+|03.6|	Telling where you are
+|03.7|	Scrolling around
+|03.8|	Simple searches
+|03.9|	Simple search patterns
+|03.10|	Using marks
+
+     Next chapter: |usr_04.txt|  Making small changes
+ Previous chapter: |usr_02.txt|  The first steps in Vim
+Table of contents: |usr_toc.txt|
+
+==============================================================================
+*03.1*	Word movement
+
+To move the cursor forward one word, use the "w" command.  Like most Vim
+commands, you can use a numeric prefix to move past multiple words.  For
+example, "3w" moves three words.  This figure shows how it works:
+
+	This is a line with example text ~
+	  --->-->->----------------->
+	   w  w  w    3w
+
+Notice that "w" moves to the start of the next word if it already is at the
+start of a word.
+   The "b" command moves backward to the start of the previous word:
+
+	This is a line with example text ~
+	<----<--<-<---------<---
+	   b   b b    2b      b
+
+There is also the "e" command that moves to the next end of a word and "ge",
+which moves to the previous end of a word:
+
+	This is a line with example text ~
+	   <-   <--- ----->   ---->
+	   ge    ge     e       e
+
+If you are at the last word of a line, the "w" command will take you to the
+first word in the next line.  Thus you can use this to move through a
+paragraph, much faster than using "l".  "b" does the same in the other
+direction.
+
+A word ends at a non-word character, such as a ".", "-" or ")".  To change
+what Vim considers to be a word, see the 'iskeyword' option.
+   It is also possible to move by white-space separated WORDs.  This is not a
+word in the normal sense, that's why the uppercase is used.  The commands for
+moving by WORDs are also uppercase, as this figure shows:
+
+	       ge      b	  w				e
+	       <-     <-	 --->			       --->
+	This is-a line, with special/separated/words (and some more). ~
+	   <----- <-----	 -------------------->	       ----->
+	     gE      B			 W			 E
+
+With this mix of lowercase and uppercase commands, you can quickly move
+forward and backward through a paragraph.
+
+==============================================================================
+*03.2*	Moving to the start or end of a line
+
+The "$" command moves the cursor to the end of a line.  If your keyboard has
+an <End> key it will do the same thing.
+
+The "^" command moves to the first non-blank character of the line.  The "0"
+command (zero) moves to the very first character of the line.  The <Home> key
+does the same thing.  In a picture:
+
+		  ^
+	     <------------
+	.....This is a line with example text ~
+	<-----------------   --------------->
+		0		   $
+
+(the "....." indicates blanks here)
+
+   The "$" command takes a count, like most movement commands.  But moving to
+the end of the line several times doesn't make sense.  Therefore it causes the
+editor to move to the end of another line.  For example, "1$" moves you to
+the end of the first line (the one you're on), "2$" to the end of the next
+line, and so on.
+   The "0" command doesn't take a count argument, because the "0" would be
+part of the count.  Unexpectedly, using a count with "^" doesn't have any
+effect.
+
+==============================================================================
+*03.3*	Moving to a character
+
+One of the most useful movement commands is the single-character search
+command.  The command "fx" searches forward in the line for the single
+character x.  Hint: "f" stands for "Find".
+   For example, you are at the beginning of the following line.  Suppose you
+want to go to the h of human.  Just execute the command "fh" and the cursor
+will be positioned over the h:
+
+	To err is human.  To really foul up you need a computer. ~
+	---------->--------------->
+	    fh		 fy
+
+This also shows that the command "fy" moves to the end of the word really.
+   You can specify a count; therefore, you can go to the "l" of "foul" with
+"3fl":
+
+	To err is human.  To really foul up you need a computer. ~
+		  --------------------->
+			   3fl
+
+The "F" command searches to the left:
+
+	To err is human.  To really foul up you need a computer. ~
+		  <---------------------
+			    Fh
+
+The "tx" command works like the "fx" command, except it stops one character
+before the searched character.  Hint: "t" stands for "To".  The backward
+version of this command is "Tx".
+
+	To err is human.  To really foul up you need a computer. ~
+		   <------------  ------------->
+			Th		tn
+
+These four commands can be repeated with ";".  "," repeats in the other
+direction.  The cursor is never moved to another line.  Not even when the
+sentence continues.
+
+Sometimes you will start a search, only to realize that you have typed the
+wrong command.  You type "f" to search backward, for example, only to realize
+that you really meant "F".  To abort a search, press <Esc>.  So "f<Esc>" is an
+aborted forward search and doesn't do anything.  Note: <Esc> cancels most
+operations, not just searches.
+
+==============================================================================
+*03.4*	Matching a parenthesis
+
+When writing a program you often end up with nested () constructs.  Then the
+"%" command is very handy: It moves to the matching paren.  If the cursor is
+on a "(" it will move to the matching ")".  If it's on a ")" it will move to
+the matching "(".
+
+			    %
+			 <----->
+		if (a == (b * c) / d) ~
+		   <---------------->
+			    %
+
+This also works for [] and {} pairs.  (This can be defined with the
+'matchpairs' option.)
+
+When the cursor is not on a useful character, "%" will search forward to find
+one.  Thus if the cursor is at the start of the line of the previous example,
+"%" will search forward and find the first "(".  Then it moves to its match:
+
+		if (a == (b * c) / d) ~
+		---+---------------->
+			   %
+
+==============================================================================
+*03.5*	Moving to a specific line
+
+If you are a C or C++ programmer, you are familiar with error messages such as
+the following:
+
+	prog.c:33: j   undeclared (first use in this function) ~
+
+This tells you that you might want to fix something on line 33.  So how do you
+find line 33?  One way is to do "9999k" to go to the top of the file and "32j"
+to go down thirty two lines.  It is not a good way, but it works.  A much
+better way of doing things is to use the "G" command.  With a count, this
+command positions you at the given line number.  For example, "33G" puts you
+on line 33.  (For a better way of going through a compiler's error list, see
+|usr_30.txt|, for information on the :make command.)
+   With no argument, "G" positions you at the end of the file.  A quick way to
+go to the start of a file use "gg".  "1G" will do the same, but is a tiny bit
+more typing.
+
+	    |	first line of a file   ^
+	    |	text text text text    |
+	    |	text text text text    |  gg
+	7G  |	text text text text    |
+	    |	text text text text
+	    |	text text text text
+	    V	text text text text    |
+		text text text text    |  G
+		text text text text    |
+		last line of a file    V
+
+Another way to move to a line is using the "%" command with a count.  For
+example "50%" moves you to halfway the file.  "90%" goes to near the end.
+
+The previous assumes that you want to move to a line in the file, no matter if
+it's currently visible or not.  What if you want to move to one of the lines
+you can see?  This figure shows the three commands you can use:
+
+			+---------------------------+
+		H -->	| text sample text	    |
+			| sample text		    |
+			| text sample text	    |
+			| sample text		    |
+		M -->	| text sample text	    |
+			| sample text		    |
+			| text sample text	    |
+			| sample text		    |
+		L -->	| text sample text	    |
+			+---------------------------+
+
+Hints: "H" stands for Home, "M" for Middle and "L" for Last.
+
+==============================================================================
+*03.6*	Telling where you are
+
+To see where you are in a file, there are three ways:
+
+1.  Use the CTRL-G command.  You get a message like this (assuming the 'ruler'
+    option is off):
+
+	"usr_03.txt" line 233 of 650 --35%-- col 45-52 ~
+
+    This shows the name of the file you are editing, the line number where the
+    cursor is, the total number of lines, the percentage of the way through
+    the file and the column of the cursor.
+       Sometimes you will see a split column number.  For example, "col 2-9".
+    This indicates that the cursor is positioned on the second character, but
+    because character one is a tab, occupying eight spaces worth of columns,
+    the screen column is 9.
+
+2.  Set the 'number' option.  This will display a line number in front of
+    every line: >
+
+	:set number
+<
+    To switch this off again: >
+
+	:set nonumber
+<
+    Since 'number' is a boolean option, prepending "no" to its name has the
+    effect of switching it off.  A boolean option has only these two values,
+    it is either on or off.
+       Vim has many options.  Besides the boolean ones there are options with
+    a numerical value and string options.  You will see examples of this where
+    they are used.
+
+3.  Set the 'ruler' option.  This will display the cursor position in the
+    lower right corner of the Vim window: >
+
+	:set ruler
+
+Using the 'ruler' option has the advantage that it doesn't take much room,
+thus there is more space for your text.
+
+==============================================================================
+*03.7*	Scrolling around
+
+The CTRL-U command scrolls down half a screen of text.  Think of looking
+through a viewing window at the text and moving this window up by half the
+height of the window.  Thus the window moves up over the text, which is
+backward in the file.  Don't worry if you have a little trouble remembering
+which end is up.  Most users have the same problem.
+   The CTRL-D command moves the viewing window down half a screen in the file,
+thus scrolls the text up half a screen.
+
+				       +----------------+
+				       | some text	|
+				       | some text	|
+				       | some text	|
+	+---------------+	       | some text	|
+	| some text	|  CTRL-U  --> |		|
+	|		|	       | 123456		|
+	| 123456	|	       +----------------+
+	| 7890		|
+	|		|	       +----------------+
+	| example	|  CTRL-D -->  | 7890		|
+	+---------------+	       |		|
+				       | example	|
+				       | example	|
+				       | example	|
+				       | example	|
+				       +----------------+
+
+To scroll one line at a time use CTRL-E (scroll up) and CTRL-Y (scroll down).
+Think of CTRL-E to give you one line Extra.  (If you use MS-Windows compatible
+key mappings CTRL-Y will redo a change instead of scroll.)
+
+To scroll forward by a whole screen (except for two lines) use CTRL-F.  The
+other way is backward, CTRL-B is the command to use.  Fortunately CTRL-F is
+Forward and CTRL-B is Backward, that's easy to remember.
+
+A common issue is that after moving down many lines with "j" your cursor is at
+the bottom of the screen.  You would like to see the context of the line with
+the cursor.  That's done with the "zz" command.
+
+	+------------------+		 +------------------+
+	| some text	   |		 | some text	    |
+	| some text	   |		 | some text	    |
+	| some text	   |		 | some text	    |
+	| some text	   |   zz  -->	 | line with cursor |
+	| some text	   |		 | some text	    |
+	| some text	   |		 | some text	    |
+	| line with cursor |		 | some text	    |
+	+------------------+		 +------------------+
+
+The "zt" command puts the cursor line at the top, "zb" at the bottom.  There
+are a few more scrolling commands, see |Q_sc|.  To always keep a few lines of
+context around the cursor, use the 'scrolloff' option.
+
+==============================================================================
+*03.8*	Simple searches
+
+To search for a string, use the "/string" command.  To find the word include,
+for example, use the command: >
+
+	/include
+
+You will notice that when you type the "/" the cursor jumps to the last line
+of the Vim window, like with colon commands.  That is where you type the word.
+You can press the backspace key (backarrow or <BS>) to make corrections.  Use
+the <Left> and <Right> cursor keys when necessary.
+   Pressing <Enter> executes the command.
+
+	Note:
+	The characters .*[]^%/\?~$ have special meanings.  If you want to use
+	them in a search you must put a \ in front of them.  See below.
+
+To find the next occurrence of the same string use the "n" command.  Use this
+to find the first #include after the cursor: >
+
+	/#include
+
+And then type "n" several times.  You will move to each #include in the text.
+You can also use a count if you know which match you want.  Thus "3n" finds
+the third match.  Using a count with "/" doesn't work.
+
+The "?" command works like "/" but searches backwards: >
+
+	?word
+
+The "N" command repeats the last search the opposite direction.  Thus using
+"N" after a "/" command search backwards, using "N" after "?" searches
+forward.
+
+
+IGNORING CASE
+
+Normally you have to type exactly what you want to find.  If you don't care
+about upper or lowercase in a word, set the 'ignorecase' option: >
+
+	:set ignorecase
+
+If you now search for "word", it will also match "Word" and "WORD".  To match
+case again: >
+
+	:set noignorecase
+
+
+HISTORY
+
+Suppose you do three searches: >
+
+	/one
+	/two
+	/three
+
+Now let's start searching by typing a simple "/" without pressing <Enter>.  If
+you press <Up> (the cursor key), Vim puts "/three" on the command line.
+Pressing <Enter> at this point searches for three.  If you do not press
+<Enter>, but press <Up> instead, Vim changes the prompt to "/two".  Another
+press of <Up> moves you to "/one".
+   You can also use the <Down> cursor key to move through the history of
+search commands in the other direction.
+
+If you know what a previously used pattern starts with, and you want to use it
+again, type that character before pressing <Up>.  With the previous example,
+you can type "/o<Up>" and Vim will put "/one" on the command line.
+
+The commands starting with ":" also have a history.  That allows you to recall
+a previous command and execute it again.  These two histories are separate.
+
+
+SEARCHING FOR A WORD IN THE TEXT
+
+Suppose you see the word "TheLongFunctionName" in the text and you want to
+find the next occurrence of it.  You could type "/TheLongFunctionName", but
+that's a lot of typing.  And when you make a mistake Vim won't find it.
+   There is an easier way: Position the cursor on the word and use the "*"
+command.  Vim will grab the word under the cursor and use it as the search
+string.
+   The "#" command does the same in the other direction.  You can prepend a
+count: "3*" searches for the third occurrence of the word under the cursor.
+
+
+SEARCHING FOR WHOLE WORDS
+
+If you type "/the" it will also match "there".  To only find words that end
+in "the" use: >
+
+	/the\>
+
+The "\>" item is a special marker that only matches at the end of a word.
+Similarly "\<" only matches at the begin of a word.  Thus to search for the
+word "the" only: >
+
+	/\<the\>
+
+This does not match "there" or "soothe".  Notice that the "*" and "#" commands
+use these start-of-word and end-of-word markers to only find whole words (you
+can use "g*" and "g#" to match partial words).
+
+
+HIGHLIGHTING MATCHES
+
+While editing a program you see a variable called "nr".  You want to check
+where it's used.  You could move the cursor to "nr" and use the "*" command
+and press "n" to go along all the matches.
+   There is another way.  Type this command: >
+
+	:set hlsearch
+
+If you now search for "nr", Vim will highlight all matches.  That is a very
+good way to see where the variable is used, without the need to type commands.
+   To switch this off: >
+
+	:set nohlsearch
+
+Then you need to switch it on again if you want to use it for the next search
+command.  If you only want to remove the highlighting, use this command: >
+
+	:nohlsearch
+
+This doesn't reset the option.  Instead, it disables the highlighting.  As
+soon as you execute a search command, the highlighting will be used again.
+Also for the "n" and "N" commands.
+
+
+TUNING SEARCHES
+
+There are a few options that change how searching works.  These are the
+essential ones:
+>
+	:set incsearch
+
+This makes Vim display the match for the string while you are still typing it.
+Use this to check if the right match will be found.  Then press <Enter> to
+really jump to that location.  Or type more to change the search string.
+>
+	:set nowrapscan
+
+This stops the search at the end of the file.  Or, when you are searching
+backwards, at the start of the file.  The 'wrapscan' option is on by default,
+thus searching wraps around the end of the file.
+
+
+INTERMEZZO
+
+If you like one of the options mentioned before, and set it each time you use
+Vim, you can put the command in your Vim startup file.
+   Edit the file, as mentioned at |not-compatible|.  Or use this command to
+find out where it is: >
+
+	:scriptnames
+
+Edit the file, for example with: >
+
+	:edit ~/.vimrc
+
+Then add a line with the command to set the option, just like you typed it in
+Vim.  Example: >
+
+	Go:set hlsearch<Esc>
+
+"G" moves to the end of the file.  "o" starts a new line, where you type the
+":set" command.  You end insert mode with <Esc>.  Then write the file: >
+
+	ZZ
+
+If you now start Vim again, the 'hlsearch' option will already be set.
+
+==============================================================================
+*03.9*	Simple search patterns
+
+The Vim editor uses regular expressions to specify what to search for.
+Regular expressions are an extremely powerful and compact way to specify a
+search pattern.  Unfortunately, this power comes at a price, because regular
+expressions are a bit tricky to specify.
+   In this section we mention only a few essential ones.  More about search
+patterns and commands in chapter 27 |usr_27.txt|.  You can find the full
+explanation here: |pattern|.
+
+
+BEGINNING AND END OF A LINE
+
+The ^ character matches the beginning of a line.  On an English-US keyboard
+you find it above the 6.  The pattern "include" matches the word include
+anywhere on the line.  But the pattern "^include" matches the word include
+only if it is at the beginning of a line.
+   The $ character matches the end of a line.  Therefore, "was$" matches the
+word was only if it is at the end of a line.
+
+Let's mark the places where "the" matches in this example line with "x"s:
+
+	the solder holding one of the chips melted and the ~
+	xxx			  xxx		       xxx
+
+Using "/the$" we find this match:
+
+	the solder holding one of the chips melted and the ~
+						       xxx
+
+And with "/^the" we find this one:
+	the solder holding one of the chips melted and the ~
+	xxx
+
+You can try searching with "/^the$", it will only match a single line
+consisting of "the".  White space does matter here, thus if a line contains a
+space after the word, like "the ", the pattern will not match.
+
+
+MATCHING ANY SINGLE CHARACTER
+
+The . (dot) character matches any existing character.  For example, the
+pattern "c.m" matches a string whose first character is a c, whose second
+character is anything, and whose the third character is m.  Example:
+
+	We use a computer that became the cummin winter. ~
+		 xxx		 xxx	  xxx
+
+
+MATCHING SPECIAL CHARACTERS
+
+If you really want to match a dot, you must avoid its special meaning by
+putting a backslash before it.
+   If you search for "ter.", you will find these matches:
+
+	We use a computer that became the cummin winter. ~
+		      xxxx			    xxxx
+
+Searching for "ter\." only finds the second match.
+
+==============================================================================
+*03.10*	Using marks
+
+When you make a jump to a position with the "G" command, Vim remembers the
+position from before this jump.  This position is called a mark.  To go back
+where you came from, use this command: >
+
+	``
+
+This ` is a backtick or open single-quote character.
+   If you use the same command a second time you will jump back again.  That's
+because the ` command is a jump itself, and the position from before this jump
+is remembered.
+
+Generally, every time you do a command that can move the cursor further than
+within the same line, this is called a jump.  This includes the search
+commands "/" and "n" (it doesn't matter how far away the match is).  But not
+the character searches with "fx" and "tx" or the word movements "w" and "e".
+   Also, "j" and "k" are not considered to be a jump.  Even when you use a
+count to make them move the cursor quite a long way away.
+
+The `` command jumps back and forth, between two points.  The CTRL-O command
+jumps to older positions (Hint: O for older).  CTRL-I then jumps back to newer
+positions (Hint: I is just next to O on the keyboard).  Consider this sequence
+of commands: >
+
+	33G
+	/^The
+	CTRL-O
+
+You first jump to line 33, then search for a line that starts with "The".
+Then with CTRL-O you jump back to line 33.  Another CTRL-O takes you back to
+where you started.  If you now use CTRL-I you jump to line 33 again.  And
+to the match for "The" with another CTRL-I.
+
+
+	     |	example text   ^	     |
+	33G  |	example text   |  CTRL-O     | CTRL-I
+	     |	example text   |	     |
+	     V	line 33 text   ^	     V
+	     |	example text   |	     |
+       /^The |	example text   |  CTRL-O     | CTRL-I
+	     V	There you are  |	     V
+		example text
+
+	Note:
+	CTRL-I is the same as <Tab>.
+
+The ":jumps" command gives a list of positions you jumped to.  The entry which
+you used last is marked with a ">".
+
+
+NAMED MARKS							*bookmark*
+
+Vim enables you to place your own marks in the text.  The command "ma" marks
+the place under the cursor as mark a.  You can place 26 marks (a through z) in
+your text.  You can't see them, it's just a position that Vim remembers.
+   To go to a mark, use the command `{mark}, where {mark} is the mark letter.
+Thus to move to the a mark:
+>
+	`a
+
+The command 'mark (single quotation mark, or apostrophe) moves you to the
+beginning of the line containing the mark.  This differs from the `mark
+command, which moves you to marked column.
+
+The marks can be very useful when working on two related parts in a file.
+Suppose you have some text near the start of the file you need to look at,
+while working on some text near the end of the file.
+   Move to the text at the start and place the s (start) mark there: >
+
+	ms
+
+Then move to the text you want to work on and put the e (end) mark there: >
+
+	me
+
+Now you can move around, and when you want to look at the start of the file,
+you use this to jump there: >
+
+	's
+
+Then you can use '' to jump back to where you were, or 'e to jump to the text
+you were working on at the end.
+   There is nothing special about using s for start and e for end, they are
+just easy to remember.
+
+You can use this command to get a list of marks: >
+
+	:marks
+
+You will notice a few special marks.  These include:
+
+	'	The cursor position before doing a jump
+	"	The cursor position when last editing the file
+	[	Start of the last change
+	]	End of the last change
+
+==============================================================================
+
+Next chapter: |usr_04.txt|  Making small changes
+
+Copyright: see |manual-copyright|  vim:tw=78:ts=8:ft=help:norl:
--- /dev/null
+++ b/lib/vimfiles/doc/usr_04.txt
@@ -1,0 +1,514 @@
+*usr_04.txt*	For Vim version 7.1.  Last change: 2006 Jun 21
+
+		     VIM USER MANUAL - by Bram Moolenaar
+
+			     Making small changes
+
+
+This chapter shows you several ways of making corrections and moving text
+around.  It teaches you the three basic ways to change text: operator-motion,
+Visual mode and text objects.
+
+|04.1|	Operators and motions
+|04.2|	Changing text
+|04.3|	Repeating a change
+|04.4|	Visual mode
+|04.5|	Moving text
+|04.6|	Copying text
+|04.7|	Using the clipboard
+|04.8|	Text objects
+|04.9|	Replace mode
+|04.10|	Conclusion
+
+     Next chapter: |usr_05.txt|  Set your settings
+ Previous chapter: |usr_03.txt|  Moving around
+Table of contents: |usr_toc.txt|
+
+==============================================================================
+*04.1*	Operators and motions
+
+In chapter 2 you learned the "x" command to delete a single character.  And
+using a count: "4x" deletes four characters.
+   The "dw" command deletes a word.  You may recognize the "w" command as the
+move word command.  In fact, the "d" command may be followed by any motion
+command, and it deletes from the current location to the place where the
+cursor winds up.
+   The "4w" command, for example, moves the cursor over four words.  The d4w
+command deletes four words.
+
+	To err is human. To really foul up you need a computer. ~
+			 ------------------>
+				 d4w
+
+	To err is human. you need a computer. ~
+
+Vim only deletes up to the position where the motion takes the cursor.  That's
+because Vim knows that you probably don't want to delete the first character
+of a word.  If you use the "e" command to move to the end of a word, Vim
+guesses that you do want to include that last character:
+
+	To err is human. you need a computer. ~
+			-------->
+			   d2e
+
+	To err is human. a computer. ~
+
+Whether the character under the cursor is included depends on the command you
+used to move to that character.  The reference manual calls this "exclusive"
+when the character isn't included and "inclusive" when it is.
+
+The "$" command moves to the end of a line.  The "d$" command deletes from the
+cursor to the end of the line.  This is an inclusive motion, thus the last
+character of the line is included in the delete operation:
+
+	To err is human. a computer. ~
+		       ------------>
+			    d$
+
+	To err is human ~
+
+There is a pattern here: operator-motion.  You first type an operator command.
+For example, "d" is the delete operator.  Then you type a motion command like
+"4l" or "w".  This way you can operate on any text you can move over.
+
+==============================================================================
+*04.2*	Changing text
+
+Another operator is "c", change.  It acts just like the "d" operator, except
+it leaves you in Insert mode.  For example, "cw" changes a word.  Or more
+specifically, it deletes a word and then puts you in Insert mode.
+
+	To err is human ~
+	   ------->
+	     c2wbe<Esc>
+
+	To be human ~
+
+This "c2wbe<Esc>" contains these bits:
+
+	c	the change operator
+	2w	move two words (they are deleted and Insert mode started)
+	be	insert this text
+	<Esc>	back to Normal mode
+
+If you have paid attention, you will have noticed something strange: The space
+before "human" isn't deleted.  There is a saying that for every problem there
+is an answer that is simple, clear, and wrong.  That is the case with the
+example used here for the "cw" command.  The c operator works just like the
+d operator, with one exception: "cw".  It actually works like "ce", change to
+end of word.  Thus the space after the word isn't included.  This is an
+exception that dates back to the old Vi.  Since many people are used to it
+now, the inconsistency has remained in Vim.
+
+
+MORE CHANGES
+
+Like "dd" deletes a whole line, "cc" changes a whole line.  It keeps the
+existing indent (leading white space) though.
+
+Just like "d$" deletes until the end of the line, "c$" changes until the end
+of the line.  It's like doing "d$" to delete the text and then "a" to start
+Insert mode and append new text.
+
+
+SHORTCUTS
+
+Some operator-motion commands are used so often that they have been given a
+single letter command:
+
+	x  stands for  dl  (delete character under the cursor)
+	X  stands for  dh  (delete character left of the cursor)
+	D  stands for  d$  (delete to end of the line)
+	C  stands for  c$  (change to end of the line)
+	s  stands for  cl  (change one character)
+	S  stands for  cc  (change a whole line)
+
+
+WHERE TO PUT THE COUNT
+
+The commands "3dw" and "d3w" delete three words.  If you want to get really
+picky about things, the first command, "3dw", deletes one word three times;
+the command "d3w" deletes three words once.  This is a difference without a
+distinction.  You can actually put in two counts, however.  For example,
+"3d2w" deletes two words, repeated three times, for a total of six words.
+
+
+REPLACING WITH ONE CHARACTER
+
+The "r" command is not an operator.  It waits for you to type a character, and
+will replace the character under the cursor with it.  You could do the same
+with "cl" or with the "s" command, but with "r" you don't have to press <Esc>
+
+	there is somerhing grong here ~
+	rT	     rt    rw
+
+	There is something wrong here ~
+
+Using a count with "r" causes that many characters to be replaced with the
+same character.  Example:
+
+	There is something wrong here ~
+			   5rx
+
+	There is something xxxxx here ~
+
+To replace a character with a line break use "r<Enter>".  This deletes one
+character and inserts a line break.  Using a count here only applies to the
+number of characters deleted: "4r<Enter>" replaces four characters with one
+line break.
+
+==============================================================================
+*04.3*	Repeating a change
+
+The "." command is one of the most simple yet powerful commands in Vim.  It
+repeats the last change.  For instance, suppose you are editing an HTML file
+and want to delete all the <B> tags.  You position the cursor on the first <
+and delete the <B> with the command "df>".  You then go to the < of the next
+</B> and kill it using the "." command.  The "." command executes the last
+change command (in this case, "df>").  To delete another tag, position the
+cursor on the < and use the "." command.
+
+			      To <B>generate</B> a table of <B>contents ~
+	f<   find first <     --->
+	df>  delete to >	 -->
+	f<   find next <	   --------->
+	.    repeat df>			    --->
+	f<   find next <		       ------------->
+	.    repeat df>					    -->
+
+The "." command works for all changes you make, except for the "u" (undo),
+CTRL-R (redo) and commands that start with a colon (:).
+
+Another example: You want to change the word "four" to "five".  It appears
+several times in your text.  You can do this quickly with this sequence of
+commands:
+
+	/four<Enter>	find the first string "four"
+	cwfive<Esc>	change the word to "five"
+	n		find the next "four"
+	.		repeat the change to "five'
+	n		find the next "four"
+	.		repeat the change
+			etc.
+
+==============================================================================
+*04.4*	Visual mode
+
+To delete simple items the operator-motion changes work quite well.  But often
+it's not so easy to decide which command will move over the text you want to
+change.  Then you can use Visual mode.
+
+You start Visual mode by pressing "v".  You move the cursor over the text you
+want to work on.  While you do this, the text is highlighted.  Finally type
+the operator command.
+   For example, to delete from halfway one word to halfway another word:
+
+		This is an examination sample of visual mode ~
+			       ---------->
+				 velllld
+
+		This is an example of visual mode ~
+
+When doing this you don't really have to count how many times you have to
+press "l" to end up in the right position.  You can immediately see what text
+will be deleted when you press "d".
+
+If at any time you decide you don't want to do anything with the highlighted
+text, just press <Esc> and Visual mode will stop without doing anything.
+
+
+SELECTING LINES
+
+If you want to work on whole lines, use "V" to start Visual mode.  You will
+see right away that the whole line is highlighted, without moving around.
+When you move left or right nothing changes.  When you move up or down the
+selection is extended whole lines at a time.
+   For example, select three lines with "Vjj":
+
+			  +------------------------+
+			  | text more text	   |
+		       >> | more text more text    | |
+	selected lines >> | text text text	   | | Vjj
+		       >> | text more		   | V
+			  | more text more	   |
+			  +------------------------+
+
+
+SELECTING BLOCKS
+
+If you want to work on a rectangular block of characters, use CTRL-V to start
+Visual mode.  This is very useful when working on tables.
+
+		name		Q1	Q2	Q3
+		pierre		123	455	234
+		john		0	90	39
+		steve		392	63	334
+
+To delete the middle "Q2" column, move the cursor to the "Q" of "Q2".  Press
+CTRL-V to start blockwise Visual mode.  Now move the cursor three lines down
+with "3j" and to the next word with "w".  You can see the first character of
+the last column is included.  To exclude it, use "h".  Now press "d" and the
+middle column is gone.
+
+
+GOING TO THE OTHER SIDE
+
+If you have selected some text in Visual mode, and discover that you need to
+change the other end of the selection, use the "o" command (Hint: o for other
+end).  The cursor will go to the other end, and you can move the cursor to
+change where the selection starts.  Pressing "o" again brings you back to the
+other end.
+
+When using blockwise selection, you have four corners.  "o" only takes you to
+one of the other corners, diagonally.  Use "O" to move to the other corner in
+the same line.
+
+Note that "o" and "O" in Visual mode work very different from Normal mode,
+where they open a new line below or above the cursor.
+
+==============================================================================
+*04.5*	Moving text
+
+When you delete something with the "d", "x", or another command, the text is
+saved.  You can paste it back by using the p command.  (The Vim name for
+this is put).
+   Take a look at how this works.  First you will delete an entire line, by
+putting the cursor on the line you want to delete and typing "dd".  Now you
+move the cursor to where you want to put the line and use the "p" (put)
+command.  The line is inserted on the line below the cursor.
+
+	a line		a line	      a line
+	line 2	  dd	line 3	  p   line 3
+	line 3			      line 2
+
+Because you deleted an entire line, the "p" command placed the text line below
+the cursor.  If you delete part of a line (a word, for instance), the "p"
+command puts it just after the cursor.
+
+	Some more boring try text to out commands. ~
+			 ---->
+			  dw
+
+	Some more boring text to out commands. ~
+			 ------->
+			    welp
+
+	Some more boring text to try out commands. ~
+
+
+MORE ON PUTTING
+
+The "P" command puts text like "p", but before the cursor.  When you deleted a
+whole line with "dd", "P" will put it back above the cursor.  When you deleted
+a word with "dw", "P" will put it back just before the cursor.
+
+You can repeat putting as many times as you like.  The same text will be used.
+
+You can use a count with "p" and "P".  The text will be repeated as many times
+as specified with the count.  Thus "dd" and then "3p" puts three copies of the
+same deleted line.
+
+
+SWAPPING TWO CHARACTERS
+
+Frequently when you are typing, your fingers get ahead of your brain (or the
+other way around?).  The result is a typo such as "teh" for "the".  Vim
+makes it easy to correct such problems.  Just put the cursor on the e of "teh"
+and execute the command "xp".  This works as follows: "x" deletes the
+character e and places it in a register.  "p" puts the text after the cursor,
+which is after the h.
+
+	teh     th     the ~
+	 x       p
+
+==============================================================================
+*04.6*	Copying text
+
+To copy text from one place to another, you could delete it, use "u" to undo
+the deletion and then "p" to put it somewhere else.  There is an easier way:
+yanking.  The "y" operator copies text into a register.  Then a "p" command
+can be used to put it.
+   Yanking is just a Vim name for copying.  The "c" letter was already used
+for the change operator, and "y" was still available.  Calling this
+operator "yank" made it easier to remember to use the "y" key.
+
+Since "y" is an operator, you use "yw" to yank a word.  A count is possible as
+usual.  To yank two words use "y2w".  Example:
+
+	let sqr = LongVariable * ~
+		 -------------->
+		       y2w
+
+	let sqr = LongVariable * ~
+			       p
+
+	let sqr = LongVariable * LongVariable ~
+
+Notice that "yw" includes the white space after a word.  If you don't want
+this, use "ye".
+
+The "yy" command yanks a whole line, just like "dd" deletes a whole line.
+Unexpectedly, while "D" deletes from the cursor to the end of the line, "Y"
+works like "yy", it yanks the whole line.  Watch out for this inconsistency!
+Use "y$" to yank to the end of the line.
+
+	a text line   yy	a text line	       a text line
+	line 2			line 2		p      line 2
+	last line		last line	       a text line
+						       last line
+
+==============================================================================
+*04.7*	Using the clipboard
+
+If you are using the GUI version of Vim (gvim), you can find the "Copy" item
+in the "Edit" menu.  First select some text with Visual mode, then use the
+Edit/Copy menu.  The selected text is now copied to the clipboard.  You can
+paste the text in other programs.  In Vim itself too.
+
+If you have copied text to the clipboard in another application, you can paste
+it in Vim with the Edit/Paste menu.  This works in Normal mode and Insert
+mode.  In Visual mode the selected text is replaced with the pasted text.
+
+The "Cut" menu item deletes the text before it's put on the clipboard.  The
+"Copy", "Cut" and "Paste" items are also available in the popup menu (only
+when there is a popup menu, of course).  If your Vim has a toolbar, you can
+also find these items there.
+
+If you are not using the GUI, or if you don't like using a menu, you have to
+use another way.  You use the normal "y" (yank) and "p" (put) commands, but
+prepend "* (double-quote star) before it.  To copy a line to the clipboard: >
+
+	"*yy
+
+To put text from the clipboard back into the text: >
+
+	"*p
+
+This only works on versions of Vim that include clipboard support.  More about
+the clipboard in section |09.3| and here: |clipboard|.
+
+==============================================================================
+*04.8*	Text objects
+
+If the cursor is in the middle of a word and you want to delete that word, you
+need to move back to its start before you can do "dw".  There is a simpler way
+to do this: "daw".
+
+	this is some example text. ~
+		       daw
+
+	this is some text. ~
+
+The "d" of "daw" is the delete operator.  "aw" is a text object.  Hint: "aw"
+stands for "A Word".  Thus "daw" is "Delete A Word".  To be precise, the white
+space after the word is also deleted (the white space before the word at the
+end of the line).
+
+Using text objects is the third way to make changes in Vim.  We already had
+operator-motion and Visual mode.  Now we add operator-text object.
+   It is very similar to operator-motion, but instead of operating on the text
+between the cursor position before and after a movement command, the text
+object is used as a whole.  It doesn't matter where in the object the cursor
+was.
+
+To change a whole sentence use "cis".  Take this text:
+
+	Hello there.  This ~
+	is an example.  Just ~
+	some text. ~
+
+Move to the start of the second line, on "is an".  Now use "cis":
+
+	Hello there.    Just ~
+	some text. ~
+
+The cursor is in between the blanks in the first line.  Now you type the new
+sentence "Another line.":
+
+	Hello there.  Another line.  Just ~
+	some text. ~
+
+"cis" consists of the "c" (change) operator and the "is" text object.  This
+stands for "Inner Sentence".  There is also the "as" (a sentence) object.  The
+difference is that "as" includes the white space after the sentence and "is"
+doesn't.  If you would delete a sentence, you want to delete the white space
+at the same time, thus use "das".  If you want to type new text the white
+space can remain, thus you use "cis".
+
+You can also use text objects in Visual mode.  It will include the text object
+in the Visual selection.  Visual mode continues, thus you can do this several
+times.  For example, start Visual mode with "v" and select a sentence with
+"as".  Now you can repeat "as" to include more sentences.  Finally you use an
+operator to do something with the selected sentences.
+
+You can find a long list of text objects here: |text-objects|.
+
+==============================================================================
+*04.9*	Replace mode
+
+The "R" command causes Vim to enter replace mode.  In this mode, each
+character you type replaces the one under the cursor.  This continues until
+you type <Esc>.
+   In this example you start Replace mode on the first "t" of "text":
+
+	This is text. ~
+		Rinteresting.<Esc>
+
+	This is interesting. ~
+
+You may have noticed that this command replaced 5 characters in the line with
+twelve others.  The "R" command automatically extends the line if it runs out
+of characters to replace.  It will not continue on the next line.
+
+You can switch between Insert mode and Replace mode with the <Insert> key.
+
+When you use <BS> (backspace) to make correction, you will notice that the
+old text is put back.  Thus it works like an undo command for the last typed
+character.
+
+==============================================================================
+*04.10*	Conclusion
+
+The operators, movement commands and text objects give you the possibility to
+make lots of combinations.  Now that you know how it works, you can use N
+operators with M movement commands to make N * M commands!
+
+You can find a list of operators here: |operator|
+
+For example, there are many other ways to delete pieces of text.  Here are a
+few often used ones:
+
+x	delete character under the cursor (short for "dl")
+X	delete character before the cursor (short for "dh")
+D	delete from cursor to end of line (short for "d$")
+dw	delete from cursor to next start of word
+db	delete from cursor to previous start of word
+diw	delete word under the cursor (excluding white space)
+daw	delete word under the cursor (including white space)
+dG	delete until the end of the file
+dgg	delete until the start of the file
+
+If you use "c" instead of "d" they become change commands.  And with "y" you
+yank the text.  And so forth.
+
+
+There are a few often used commands to make changes that didn't fit somewhere
+else:
+
+	~	change case of the character under the cursor, and move the
+		cursor to the next character.  This is not an operator (unless
+		'tildeop' is set), thus you can't use it with a motion
+		command.  It does works in Visual mode and changes case for
+		all the selected text then.
+
+	I	Start Insert mode after moving the cursor to the first
+		non-blank in the line.
+
+	A	Start Insert mode after moving the cursor to the end of the
+		line.
+
+==============================================================================
+
+Next chapter: |usr_05.txt|  Set your settings
+
+Copyright: see |manual-copyright|  vim:tw=78:ts=8:ft=help:norl:
--- /dev/null
+++ b/lib/vimfiles/doc/usr_05.txt
@@ -1,0 +1,625 @@
+*usr_05.txt*	For Vim version 7.1.  Last change: 2007 May 11
+
+		     VIM USER MANUAL - by Bram Moolenaar
+
+			      Set your settings
+
+
+Vim can be tuned to work like you want it to.  This chapter shows you how to
+make Vim start with options set to different values.  Add plugins to extend
+Vim's capabilities.  Or define your own macros.
+
+|05.1|	The vimrc file
+|05.2|	The example vimrc file explained
+|05.3|	Simple mappings
+|05.4|	Adding a plugin
+|05.5|	Adding a help file
+|05.6|	The option window
+|05.7|	Often used options
+
+     Next chapter: |usr_06.txt|  Using syntax highlighting
+ Previous chapter: |usr_04.txt|  Making small changes
+Table of contents: |usr_toc.txt|
+
+==============================================================================
+*05.1*	The vimrc file					*vimrc-intro*
+
+You probably got tired of typing commands that you use very often.  To start
+Vim with all your favorite option settings and mappings, you write them in
+what is called the vimrc file.  Vim executes the commands in this file when it
+starts up.
+
+If you already have a vimrc file (e.g., when your sysadmin has one setup for
+you), you can edit it this way: >
+
+	:edit $MYVIMRC
+
+If you don't have a vimrc file yet, see |vimrc| to find out where you can
+create a vimrc file.  Also, the ":version" command mentions the name of the
+"user vimrc file" Vim looks for.
+
+For Unix and Macintosh this file is always used and is recommended:
+
+	~/.vimrc ~
+
+For MS-DOS and MS-Windows you can use one of these:
+
+	$HOME/_vimrc ~
+	$VIM/_vimrc ~
+
+The vimrc file can contain all the commands that you type after a colon.  The
+most simple ones are for setting options.  For example, if you want Vim to
+always start with the 'incsearch' option on, add this line you your vimrc
+file: >
+
+	set incsearch
+
+For this new line to take effect you need to exit Vim and start it again.
+Later you will learn how to do this without exiting Vim.
+
+This chapter only explains the most basic items.  For more information on how
+to write a Vim script file: |usr_41.txt|.
+
+==============================================================================
+*05.2*	The example vimrc file explained		*vimrc_example.vim*
+
+In the first chapter was explained how the example vimrc (included in the
+Vim distribution) file can be used to make Vim startup in not-compatible mode
+(see |not-compatible|).  The file can be found here:
+
+	$VIMRUNTIME/vimrc_example.vim ~
+
+In this section we will explain the various commands used in this file.  This
+will give you hints about how to set up your own preferences.  Not everything
+will be explained though.  Use the ":help" command to find out more.
+
+>
+	set nocompatible
+
+As mentioned in the first chapter, these manuals explain Vim working in an
+improved way, thus not completely Vi compatible.  Setting the 'compatible'
+option off, thus 'nocompatible' takes care of this.
+
+>
+	set backspace=indent,eol,start
+
+This specifies where in Insert mode the <BS> is allowed to delete the
+character in front of the cursor.  The three items, separated by commas, tell
+Vim to delete the white space at the start of the line, a line break and the
+character before where Insert mode started.
+>
+
+	set autoindent
+
+This makes Vim use the indent of the previous line for a newly created line.
+Thus there is the same amount of white space before the new line.  For example
+when pressing <Enter> in Insert mode, and when using the "o" command to open a
+new line.
+>
+
+	if has("vms")
+	  set nobackup
+	else
+	  set backup
+	endif
+
+This tells Vim to keep a backup copy of a file when overwriting it.  But not
+on the VMS system, since it keeps old versions of files already.  The backup
+file will have the same name as the original file with "~" added.  See |07.4|
+>
+
+	set history=50
+
+Keep 50 commands and 50 search patterns in the history.  Use another number if
+you want to remember fewer or more lines.
+>
+
+	set ruler
+
+Always display the current cursor position in the lower right corner of the
+Vim window.
+
+>
+	set showcmd
+
+Display an incomplete command in the lower right corner of the Vim window,
+left of the ruler.  For example, when you type "2f", Vim is waiting for you to
+type the character to find and "2f" is displayed.  When you press "w" next,
+the "2fw" command is executed and the displayed "2f" is removed.
+
+	+-------------------------------------------------+
+	|text in the Vim window				  |
+	|~						  |
+	|~						  |
+	|-- VISUAL --			2f     43,8   17% |
+	+-------------------------------------------------+
+	 ^^^^^^^^^^^		      ^^^^^^^^ ^^^^^^^^^^
+	  'showmode'		     'showcmd'	'ruler'
+
+>
+	set incsearch
+
+Display the match for a search pattern when halfway typing it.
+
+>
+	map Q gq
+
+This defines a key mapping.  More about that in the next section.  This
+defines the "Q" command to do formatting with the "gq" operator.  This is how
+it worked before Vim 5.0.  Otherwise the "Q" command starts Ex mode, but you
+will not need it.
+
+>
+	vnoremap _g y:exe "grep /" . escape(@", '\\/') . "/ *.c *.h"<CR>
+
+This mapping yanks the visually selected text and searches for it in C files.
+This is a complicated mapping.  You can see that mappings can be used to do
+quite complicated things.  Still, it is just a sequence of commands that are
+executed like you typed them.
+
+>
+	if &t_Co > 2 || has("gui_running")
+	  syntax on
+	  set hlsearch
+	endif
+
+This switches on syntax highlighting, but only if colors are available.  And
+the 'hlsearch' option tells Vim to highlight matches with the last used search
+pattern.  The "if" command is very useful to set options only when some
+condition is met.  More about that in |usr_41.txt|.
+
+							*vimrc-filetype*  >
+	filetype plugin indent on
+
+This switches on three very clever mechanisms:
+1. Filetype detection.
+   Whenever you start editing a file, Vim will try to figure out what kind of
+   file this is.  When you edit "main.c", Vim will see the ".c" extension and
+   recognize this as a "c" filetype.  When you edit a file that starts with
+   "#!/bin/sh", Vim will recognize it as a "sh" filetype.
+   The filetype detection is used for syntax highlighting and the other two
+   items below.
+   See |filetypes|.
+
+2. Using filetype plugin files
+   Many different filetypes are edited with different options.  For example,
+   when you edit a "c" file, it's very useful to set the 'cindent' option to
+   automatically indent the lines.  These commonly useful option settings are
+   included with Vim in filetype plugins.  You can also add your own, see
+   |write-filetype-plugin|.
+
+3. Using indent files
+   When editing programs, the indent of a line can often be computed
+   automatically.  Vim comes with these indent rules for a number of
+   filetypes.  See |:filetype-indent-on| and 'indentexpr'.
+
+>
+	autocmd FileType text setlocal textwidth=78
+
+This makes Vim break text to avoid lines getting longer than 78 characters.
+But only for files that have been detected to be plain text.  There are
+actually two parts here.  "autocmd FileType text" is an autocommand.  This
+defines that when the file type is set to "text" the following command is
+automatically executed.  "setlocal textwidth=78" sets the 'textwidth' option
+to 78, but only locally in one file.
+
+							*restore-cursor*  >
+	autocmd BufReadPost *
+	    \ if line("'\"") > 0 && line("'\"") <= line("$") |
+	    \   exe "normal g`\"" |
+	    \ endif
+
+Another autocommand.  This time it is used after reading any file.  The
+complicated stuff after it checks if the '" mark is defined, and jumps to it
+if so.  The backslash at the start of a line is used to continue the command
+from the previous line.  That avoids a line getting very long.
+See |line-continuation|.  This only works in a Vim script file, not when
+typing commands at the command-line.
+
+==============================================================================
+*05.3*	Simple mappings
+
+A mapping enables you to bind a set of Vim commands to a single key.  Suppose,
+for example, that you need to surround certain words with curly braces.  In
+other words, you need to change a word such as "amount" into "{amount}".  With
+the :map command, you can tell Vim that the F5 key does this job.  The command
+is as follows: >
+
+	:map <F5> i{<Esc>ea}<Esc>
+<
+	Note:
+	When entering this command, you must enter <F5> by typing four
+	characters.  Similarly, <Esc> is not entered by pressing the <Esc>
+	key, but by typing five characters.  Watch out for this difference
+	when reading the manual!
+
+Let's break this down:
+    <F5>	The F5 function key.  This is the trigger key that causes the
+		command to be executed as the key is pressed.
+
+    i{<Esc>	Insert the { character.  The <Esc> key ends Insert mode.
+
+    e		Move to the end of the word.
+
+    a}<Esc>	Append the } to the word.
+
+After you execute the ":map" command, all you have to do to put {} around a
+word is to put the cursor on the first character and press F5.
+
+In this example, the trigger is a single key; it can be any string.  But when
+you use an existing Vim command, that command will no longer be available.
+You better avoid that.
+   One key that can be used with mappings is the backslash.  Since you
+probably want to define more than one mapping, add another character.  You
+could map "\p" to add parentheses around a word, and "\c" to add curly braces,
+for example: >
+
+	:map \p i(<Esc>ea)<Esc>
+	:map \c i{<Esc>ea}<Esc>
+
+You need to type the \ and the p quickly after another, so that Vim knows they
+belong together.
+
+The ":map" command (with no arguments) lists your current mappings.  At
+least the ones for Normal mode.  More about mappings in section |40.1|.
+
+==============================================================================
+*05.4*	Adding a plugin					*add-plugin* *plugin*
+
+Vim's functionality can be extended by adding plugins.  A plugin is nothing
+more than a Vim script file that is loaded automatically when Vim starts.  You
+can add a plugin very easily by dropping it in your plugin directory.
+{not available when Vim was compiled without the |+eval| feature}
+
+There are two types of plugins:
+
+    global plugin: Used for all kinds of files
+  filetype plugin: Only used for a specific type of file
+
+The global plugins will be discussed first, then the filetype ones
+|add-filetype-plugin|.
+
+
+GLOBAL PLUGINS						*standard-plugin*
+
+When you start Vim, it will automatically load a number of global plugins.
+You don't have to do anything for this.  They add functionality that most
+people will want to use, but which was implemented as a Vim script instead of
+being compiled into Vim.  You can find them listed in the help index
+|standard-plugin-list|.  Also see |load-plugins|.
+
+							*add-global-plugin*
+You can add a global plugin to add functionality that will always be present
+when you use Vim.  There are only two steps for adding a global plugin:
+1. Get a copy of the plugin.
+2. Drop it in the right directory.
+
+
+GETTING A GLOBAL PLUGIN
+
+Where can you find plugins?
+- Some come with Vim.  You can find them in the directory $VIMRUNTIME/macros
+  and its sub-directories.
+- Download from the net.  There is a large collection on http://www.vim.org.
+- They are sometimes posted in a Vim |maillist|.
+- You could write one yourself, see |write-plugin|.
+
+Some plugins come as a vimball archive, see |vimball|.
+Some plugins can be updated automatically, see |getscript|.
+
+
+USING A GLOBAL PLUGIN
+
+First read the text in the plugin itself to check for any special conditions.
+Then copy the file to your plugin directory:
+
+	system		plugin directory ~
+	Unix		~/.vim/plugin/
+	PC and OS/2	$HOME/vimfiles/plugin or $VIM/vimfiles/plugin
+	Amiga		s:vimfiles/plugin
+	Macintosh	$VIM:vimfiles:plugin
+	Mac OS X	~/.vim/plugin/
+	RISC-OS		Choices:vimfiles.plugin
+
+Example for Unix (assuming you didn't have a plugin directory yet): >
+
+	mkdir ~/.vim
+	mkdir ~/.vim/plugin
+	cp /usr/local/share/vim/vim60/macros/justify.vim ~/.vim/plugin
+
+That's all!  Now you can use the commands defined in this plugin to justify
+text.
+
+Instead of putting plugins directly into the plugin/ directory, you may
+better organize them by putting them into subdirectories under plugin/.
+As an example, consider using "~/.vim/plugin/perl/*.vim" for all your Perl
+plugins.
+
+
+FILETYPE PLUGINS			*add-filetype-plugin* *ftplugins*
+
+The Vim distribution comes with a set of plugins for different filetypes that
+you can start using with this command: >
+
+	:filetype plugin on
+
+That's all!  See |vimrc-filetype|.
+
+If you are missing a plugin for a filetype you are using, or you found a
+better one, you can add it.  There are two steps for adding a filetype plugin:
+1. Get a copy of the plugin.
+2. Drop it in the right directory.
+
+
+GETTING A FILETYPE PLUGIN
+
+You can find them in the same places as the global plugins.  Watch out if the
+type of file is mentioned, then you know if the plugin is a global or a
+filetype one.  The scripts in $VIMRUNTIME/macros are global ones, the filetype
+plugins are in $VIMRUNTIME/ftplugin.
+
+
+USING A FILETYPE PLUGIN					*ftplugin-name*
+
+You can add a filetype plugin by dropping it in the right directory.  The
+name of this directory is in the same directory mentioned above for global
+plugins, but the last part is "ftplugin".  Suppose you have found a plugin for
+the "stuff" filetype, and you are on Unix.  Then you can move this file to the
+ftplugin directory: >
+
+	mv thefile ~/.vim/ftplugin/stuff.vim
+
+If that file already exists you already have a plugin for "stuff".  You might
+want to check if the existing plugin doesn't conflict with the one you are
+adding.  If it's OK, you can give the new one another name: >
+
+	mv thefile ~/.vim/ftplugin/stuff_too.vim
+
+The underscore is used to separate the name of the filetype from the rest,
+which can be anything.  If you use "otherstuff.vim" it wouldn't work, it would
+be loaded for the "otherstuff" filetype.
+
+On MS-DOS you cannot use long filenames.  You would run into trouble if you
+add a second plugin and the filetype has more than six characters.  You can
+use an extra directory to get around this: >
+
+	mkdir $VIM/vimfiles/ftplugin/fortran
+	copy thefile $VIM/vimfiles/ftplugin/fortran/too.vim
+
+The generic names for the filetype plugins are: >
+
+	ftplugin/<filetype>.vim
+	ftplugin/<filetype>_<name>.vim
+	ftplugin/<filetype>/<name>.vim
+
+Here "<name>" can be any name that you prefer.
+Examples for the "stuff" filetype on Unix: >
+
+	~/.vim/ftplugin/stuff.vim
+	~/.vim/ftplugin/stuff_def.vim
+	~/.vim/ftplugin/stuff/header.vim
+
+The <filetype> part is the name of the filetype the plugin is to be used for.
+Only files of this filetype will use the settings from the plugin.  The <name>
+part of the plugin file doesn't matter, you can use it to have several plugins
+for the same filetype.  Note that it must end in ".vim".
+
+
+Further reading:
+|filetype-plugins|	Documentation for the filetype plugins and information
+			about how to avoid that mappings cause problems.
+|load-plugins|		When the global plugins are loaded during startup.
+|ftplugin-overrule|	Overruling the settings from a global plugin.
+|write-plugin|		How to write a plugin script.
+|plugin-details|	For more information about using plugins or when your
+			plugin doesn't work.
+|new-filetype|		How to detect a new file type.
+
+==============================================================================
+*05.5*	Adding a help file		*add-local-help* *matchit-install*
+
+If you are lucky, the plugin you installed also comes with a help file.  We
+will explain how to install the help file, so that you can easily find help
+for your new plugin.
+   Let us use the "matchit.vim" plugin as an example (it is included with
+Vim).  This plugin makes the "%" command jump to matching HTML tags,
+if/else/endif in Vim scripts, etc.  Very useful, although it's not backwards
+compatible (that's why it is not enabled by default).
+   This plugin comes with documentation: "matchit.txt".  Let's first copy the
+plugin to the right directory.  This time we will do it from inside Vim, so
+that we can use $VIMRUNTIME.  (You may skip some of the "mkdir" commands if
+you already have the directory.) >
+
+	:!mkdir ~/.vim
+	:!mkdir ~/.vim/plugin
+	:!cp $VIMRUNTIME/macros/matchit.vim ~/.vim/plugin
+
+The "cp" command is for Unix, on MS-DOS you can use "copy".
+
+Now create a "doc" directory in one of the directories in 'runtimepath'. >
+
+	:!mkdir ~/.vim/doc
+
+Copy the help file to the "doc" directory. >
+
+	:!cp $VIMRUNTIME/macros/matchit.txt ~/.vim/doc
+
+Now comes the trick, which allows you to jump to the subjects in the new help
+file: Generate the local tags file with the |:helptags| command. >
+
+	:helptags ~/.vim/doc
+
+Now you can use the >
+
+	:help g%
+
+command to find help for "g%" in the help file you just added.  You can see an
+entry for the local help file when you do: >
+
+	:help local-additions
+
+The title lines from the local help files are automagically added to this
+section.  There you can see which local help files have been added and jump to
+them through the tag.
+
+For writing a local help file, see |write-local-help|.
+
+==============================================================================
+*05.6*	The option window
+
+If you are looking for an option that does what you want, you can search in
+the help files here: |options|.  Another way is by using this command: >
+
+	:options
+
+This opens a new window, with a list of options with a one-line explanation.
+The options are grouped by subject.  Move the cursor to a subject and press
+<Enter> to jump there.  Press <Enter> again to jump back.  Or use CTRL-O.
+
+You can change the value of an option.  For example, move to the "displaying
+text" subject.  Then move the cursor down to this line:
+
+	set wrap	nowrap ~
+
+When you hit <Enter>, the line will change to:
+
+	set nowrap	wrap ~
+
+The option has now been switched off.
+
+Just above this line is a short description of the 'wrap' option.  Move the
+cursor one line up to place it in this line.  Now hit <Enter> and you jump to
+the full help on the 'wrap' option.
+
+For options that take a number or string argument you can edit the value.
+Then press <Enter> to apply the new value.  For example, move the cursor a few
+lines up to this line:
+
+	set so=0 ~
+
+Position the cursor on the zero with "$".  Change it into a five with "r5".
+Then press <Enter> to apply the new value.  When you now move the cursor
+around you will notice that the text starts scrolling before you reach the
+border.  This is what the 'scrolloff' option does, it specifies an offset
+from the window border where scrolling starts.
+
+==============================================================================
+*05.7*	Often used options
+
+There are an awful lot of options.  Most of them you will hardly ever use.
+Some of the more useful ones will be mentioned here.  Don't forget you can
+find more help on these options with the ":help" command, with single quotes
+before and after the option name.  For example: >
+
+	:help 'wrap'
+
+In case you have messed up an option value, you can set it back to the
+default by putting an ampersand (&) after the option name.  Example: >
+
+	:set iskeyword&
+
+
+NOT WRAPPING LINES
+
+Vim normally wraps long lines, so that you can see all of the text.  Sometimes
+it's better to let the text continue right of the window.  Then you need to
+scroll the text left-right to see all of a long line.  Switch wrapping off
+with this command: >
+
+	:set nowrap
+
+Vim will automatically scroll the text when you move to text that is not
+displayed.  To see a context of ten characters, do this: >
+
+	:set sidescroll=10
+
+This doesn't change the text in the file, only the way it is displayed.
+
+
+WRAPPING MOVEMENT COMMANDS
+
+Most commands for moving around will stop moving at the start and end of a
+line.  You can change that with the 'whichwrap' option.  This sets it to the
+default value: >
+
+	:set whichwrap=b,s
+
+This allows the <BS> key, when used in the first position of a line, to move
+the cursor to the end of the previous line.  And the <Space> key moves from
+the end of a line to the start of the next one.
+
+To allow the cursor keys <Left> and <Right> to also wrap, use this command: >
+
+	:set whichwrap=b,s,<,>
+
+This is still only for Normal mode.  To let <Left> and <Right> do this in
+Insert mode as well: >
+
+	:set whichwrap=b,s,<,>,[,]
+
+There are a few other flags that can be added, see 'whichwrap'.
+
+
+VIEWING TABS
+
+When there are tabs in a file, you cannot see where they are.  To make them
+visible: >
+
+	:set list
+
+Now every tab is displayed as ^I.  And a $ is displayed at the end of each
+line, so that you can spot trailing spaces that would otherwise go unnoticed.
+   A disadvantage is that this looks ugly when there are many Tabs in a file.
+If you have a color terminal, or are using the GUI, Vim can show the spaces
+and tabs as highlighted characters.  Use the 'listchars' option: >
+
+	:set listchars=tab:>-,trail:-
+
+Now every tab will be displayed as ">---" (with more or less "-") and trailing
+white space as "-".  Looks a lot better, doesn't it?
+
+
+KEYWORDS
+
+The 'iskeyword' option specifies which characters can appear in a word: >
+
+	:set iskeyword
+<	  iskeyword=@,48-57,_,192-255 ~
+
+The "@" stands for all alphabetic letters.  "48-57" stands for ASCII
+characters 48 to 57, which are the numbers 0 to 9.  "192-255" are the
+printable latin characters.
+   Sometimes you will want to include a dash in keywords, so that commands
+like "w" consider "upper-case" to be one word.  You can do it like this: >
+
+	:set iskeyword+=-
+	:set iskeyword
+<	  iskeyword=@,48-57,_,192-255,- ~
+
+If you look at the new value, you will see that Vim has added a comma for you.
+   To remove a character use "-=".  For example, to remove the underscore: >
+
+	:set iskeyword-=_
+	:set iskeyword
+<	  iskeyword=@,48-57,192-255,- ~
+
+This time a comma is automatically deleted.
+
+
+ROOM FOR MESSAGES
+
+When Vim starts there is one line at the bottom that is used for messages.
+When a message is long, it is either truncated, thus you can only see part of
+it, or the text scrolls and you have to press <Enter> to continue.
+   You can set the 'cmdheight' option to the number of lines used for
+messages.  Example: >
+
+	:set cmdheight=3
+
+This does mean there is less room to edit text, thus it's a compromise.
+
+==============================================================================
+
+Next chapter: |usr_06.txt|  Using syntax highlighting
+
+Copyright: see |manual-copyright|  vim:tw=78:ts=8:ft=help:norl:
--- /dev/null
+++ b/lib/vimfiles/doc/usr_06.txt
@@ -1,0 +1,276 @@
+*usr_06.txt*	For Vim version 7.1.  Last change: 2006 Apr 24
+
+		     VIM USER MANUAL - by Bram Moolenaar
+
+			  Using syntax highlighting
+
+
+Black and white text is boring.  With colors your file comes to life.  This
+not only looks nice, it also speeds up your work.  Change the colors used for
+the different sorts of text.  Print your text, with the colors you see on the
+screen.
+
+|06.1|	Switching it on
+|06.2|	No or wrong colors?
+|06.3|	Different colors
+|06.4|	With colors or without colors
+|06.5|	Printing with colors
+|06.6|	Further reading
+
+     Next chapter: |usr_07.txt|  Editing more than one file
+ Previous chapter: |usr_05.txt|  Set your settings
+Table of contents: |usr_toc.txt|
+
+==============================================================================
+*06.1*	Switching it on
+
+It all starts with one simple command: >
+
+	:syntax enable
+
+That should work in most situations to get color in your files.  Vim will
+automagically detect the type of file and load the right syntax highlighting.
+Suddenly comments are blue, keywords brown and strings red.  This makes it
+easy to overview the file.  After a while you will find that black&white text
+slows you down!
+
+If you always want to use syntax highlighting, put the ":syntax enable"
+command in your |vimrc| file.
+
+If you want syntax highlighting only when the terminal supports colors, you
+can put this in your |vimrc| file: >
+
+	if &t_Co > 1
+	   syntax enable
+	endif
+
+If you want syntax highlighting only in the GUI version, put the ":syntax
+enable" command in your |gvimrc| file.
+
+==============================================================================
+*06.2*	No or wrong colors?
+
+There can be a number of reasons why you don't see colors:
+
+- Your terminal does not support colors.
+	Vim will use bold, italic and underlined text, but this doesn't look
+	very nice.  You probably will want to try to get a terminal with
+	colors.  For Unix, I recommend the xterm from the XFree86 project:
+	|xfree-xterm|.
+
+- Your terminal does support colors, but Vim doesn't know this.
+	Make sure your $TERM setting is correct.  For example, when using an
+	xterm that supports colors: >
+
+		setenv TERM xterm-color
+<
+	or (depending on your shell): >
+
+		TERM=xterm-color; export TERM
+
+<	The terminal name must match the terminal you are using.  If it
+	still doesn't work, have a look at |xterm-color|, which shows a few
+	ways to make Vim display colors (not only for an xterm).
+
+- The file type is not recognized.
+	Vim doesn't know all file types, and sometimes it's near to impossible
+	to tell what language a file uses.  Try this command: >
+
+		:set filetype
+<
+	If the result is "filetype=" then the problem is indeed that Vim
+	doesn't know what type of file this is.  You can set the type
+	manually: >
+
+		:set filetype=fortran
+
+<	To see which types are available, look in the directory
+	$VIMRUNTIME/syntax.  For the GUI you can use the Syntax menu.
+	Setting the filetype can also be done with a |modeline|, so that the
+	file will be highlighted each time you edit it.  For example, this
+	line can be used in a Makefile (put it near the start or end of the
+	file): >
+
+		# vim: syntax=make
+
+<	You might know how to detect the file type yourself.  Often the file
+	name extension (after the dot) can be used.
+	See |new-filetype| for how to tell Vim to detect that file type.
+
+- There is no highlighting for your file type.
+	You could try using a similar file type by manually setting it as
+	mentioned above.  If that isn't good enough, you can write your own
+	syntax file, see |mysyntaxfile|.
+
+
+Or the colors could be wrong:
+
+- The colored text is very hard to read.
+	Vim guesses the background color that you are using.  If it is black
+	(or another dark color) it will use light colors for text.  If it is
+	white (or another light color) it will use dark colors for text.  If
+	Vim guessed wrong the text will be hard to read.  To solve this, set
+	the 'background' option.  For a dark background: >
+
+		:set background=dark
+
+<	And for a light background: >
+
+		:set background=light
+
+<	Make sure you put this _before_ the ":syntax enable" command,
+	otherwise the colors will already have been set.  You could do
+	":syntax reset" after setting 'background' to make Vim set the default
+	colors again.
+
+- The colors are wrong when scrolling bottom to top.
+	Vim doesn't read the whole file to parse the text.  It starts parsing
+	wherever you are viewing the file.  That saves a lot of time, but
+	sometimes the colors are wrong.  A simple fix is hitting CTRL-L.  Or
+	scroll back a bit and then forward again.
+	For a real fix, see |:syn-sync|.  Some syntax files have a way to make
+	it look further back, see the help for the specific syntax file.  For
+	example, |tex.vim| for the TeX syntax.
+
+==============================================================================
+*06.3*	Different colors				*:syn-default-override*
+
+If you don't like the default colors, you can select another color scheme.  In
+the GUI use the Edit/Color Scheme menu.  You can also type the command: >
+
+	:colorscheme evening
+
+"evening" is the name of the color scheme.  There are several others you might
+want to try out.  Look in the directory $VIMRUNTIME/colors.
+
+When you found the color scheme that you like, add the ":colorscheme" command
+to your |vimrc| file.
+
+You could also write your own color scheme.  This is how you do it:
+
+1. Select a color scheme that comes close.  Copy this file to your own Vim
+   directory.  For Unix, this should work: >
+
+	!mkdir ~/.vim/colors
+	!cp $VIMRUNTIME/colors/morning.vim ~/.vim/colors/mine.vim
+<
+   This is done from Vim, because it knows the value of $VIMRUNTIME.
+
+2. Edit the color scheme file.  These entries are useful:
+
+	term		attributes in a B&W terminal
+	cterm		attributes in a color terminal
+	ctermfg		foreground color in a color terminal
+	ctermbg		background color in a color terminal
+	gui		attributes in the GUI
+	guifg		foreground color in the GUI
+	guibg		background color in the GUI
+
+   For example, to make comments green: >
+
+	:highlight Comment ctermfg=green guifg=green
+<
+   Attributes you can use for "cterm" and "gui" are "bold" and "underline".
+   If you want both, use "bold,underline".  For details see the |:highlight|
+   command.
+
+3. Tell Vim to always use your color scheme.  Put this line in your |vimrc|: >
+
+	colorscheme mine
+
+If you want to see what the most often used color combinations look like, use
+this command: >
+
+	:runtime syntax/colortest.vim
+
+You will see text in various color combinations.  You can check which ones are
+readable and look nice.
+
+==============================================================================
+*06.4*	With colors or without colors
+
+Displaying text in color takes a lot of effort.  If you find the displaying
+too slow, you might want to disable syntax highlighting for a moment: >
+
+	:syntax clear
+
+When editing another file (or the same one) the colors will come back.
+
+							*:syn-off*
+If you want to stop highlighting completely use: >
+
+	:syntax off
+
+This will completely disable syntax highlighting and remove it immediately for
+all buffers.
+
+							*:syn-manual*
+If you want syntax highlighting only for specific files, use this: >
+
+	:syntax manual
+
+This will enable the syntax highlighting, but not switch it on automatically
+when starting to edit a buffer.  To switch highlighting on for the current
+buffer, set the 'syntax' option: >
+
+	:set syntax=ON
+<
+==============================================================================
+*06.5*	Printing with colors				*syntax-printing*
+
+In the MS-Windows version you can print the current file with this command: >
+
+	:hardcopy
+
+You will get the usual printer dialog, where you can select the printer and a
+few settings.  If you have a color printer, the paper output should look the
+same as what you see inside Vim.  But when you use a dark background the
+colors will be adjusted to look good on white paper.
+
+There are several options that change the way Vim prints:
+	'printdevice'
+	'printheader'
+	'printfont'
+	'printoptions'
+
+To print only a range of lines,  use Visual mode to select the lines and then
+type the command: >
+
+	v100j:hardcopy
+
+"v" starts Visual mode.  "100j" moves a hundred lines down, they will be
+highlighted.  Then ":hardcopy" will print those lines.  You can use other
+commands to move in Visual mode, of course.
+
+This also works on Unix, if you have a PostScript printer.  Otherwise, you
+will have to do a bit more work.  You need to convert the text to HTML first,
+and then print it from a web browser such as Netscape.
+
+Convert the current file to HTML with this command: >
+
+	:source $VIMRUNTIME/syntax/2html.vim
+
+You will see it crunching away, this can take quite a while for a large file.
+Some time later another window shows the HTML code.  Now write this somewhere
+(doesn't matter where, you throw it away later):
+>
+	:write main.c.html
+
+Open this file in your favorite browser and print it from there.  If all goes
+well, the output should look exactly as it does in Vim.  See |2html.vim| for
+details.  Don't forget to delete the HTML file when you are done with it.
+
+Instead of printing, you could also put the HTML file on a web server, and let
+others look at the colored text.
+
+==============================================================================
+*06.6*	Further reading
+
+|usr_44.txt|  Your own syntax highlighted.
+|syntax|      All the details.
+
+==============================================================================
+
+Next chapter: |usr_07.txt|  Editing more than one file
+
+Copyright: see |manual-copyright|  vim:tw=78:ts=8:ft=help:norl:
--- /dev/null
+++ b/lib/vimfiles/doc/usr_07.txt
@@ -1,0 +1,479 @@
+*usr_07.txt*	For Vim version 7.1.  Last change: 2006 Apr 24
+
+		     VIM USER MANUAL - by Bram Moolenaar
+
+			  Editing more than one file
+
+
+No matter how many files you have, you can edit them without leaving Vim.
+Define a list of files to work on and jump from one to the other.  Copy text
+from one file and put it in another one.
+
+|07.1|	Edit another file
+|07.2|	A list of files
+|07.3|	Jumping from file to file
+|07.4|	Backup files
+|07.5|	Copy text between files
+|07.6|	Viewing a file
+|07.7|	Changing the file name
+
+     Next chapter: |usr_08.txt|  Splitting windows
+ Previous chapter: |usr_06.txt|  Using syntax highlighting
+Table of contents: |usr_toc.txt|
+
+==============================================================================
+*07.1*	Edit another file
+
+So far you had to start Vim for every file you wanted to edit.  There is a
+simpler way.  To start editing another file, use this command: >
+
+	:edit foo.txt
+
+You can use any file name instead of "foo.txt".  Vim will close the current
+file and open the new one.  If the current file has unsaved changes, however,
+Vim displays an error message and does not open the new file:
+
+	E37: No write since last change (use ! to override) ~
+
+	Note:
+	Vim puts an error ID at the start of each error message.  If you do
+	not understand the message or what caused it, look in the help system
+	for this ID.  In this case: >
+
+		:help E37
+
+At this point, you have a number of alternatives.  You can write the file
+using this command: >
+
+	:write
+
+Or you can force Vim to discard your changes and edit the new file, using the
+force (!) character: >
+
+	:edit! foo.txt
+
+If you want to edit another file, but not write the changes in the current
+file yet, you can make it hidden: >
+
+	:hide edit foo.txt
+
+The text with changes is still there, but you can't see it.  This is further
+explained in section |22.4|: The buffer list.
+
+==============================================================================
+*07.2*	A list of files
+
+You can start Vim to edit a sequence of files.  For example: >
+
+	vim one.c two.c three.c
+
+This command starts Vim and tells it that you will be editing three files.
+Vim displays just the first file.  After you have done your thing in this
+file, to edit the next file you use this command: >
+
+	:next
+
+If you have unsaved changes in the current file, you will get an error
+message and the ":next" will not work.  This is the same problem as with
+":edit" mentioned in the previous section.  To abandon the changes: >
+
+	:next!
+
+But mostly you want to save the changes and move on to the next file.  There
+is a special command for this: >
+
+	:wnext
+
+This does the same as using two separate commands: >
+
+	:write
+	:next
+
+
+WHERE AM I?
+
+To see which file in the argument list you are editing, look in the window
+title.  It should show something like "(2 of 3)".  This means you are editing
+the second file out of three files.
+   If you want to see the list of files, use this command: >
+
+	:args
+
+This is short for "arguments".  The output might look like this:
+
+	one.c [two.c] three.c ~
+
+These are the files you started Vim with.  The one you are currently editing,
+"two.c", is in square brackets.
+
+
+MOVING TO OTHER ARGUMENTS
+
+To go back one file: >
+
+	:previous
+
+This is just like the ":next" command, except that it moves in the other
+direction.  Again, there is a shortcut command for when you want to write the
+file first: >
+
+	:wprevious
+
+To move to the very last file in the list: >
+
+	:last
+
+And to move back to the first one again: >
+
+	:first
+
+There is no ":wlast" or ":wfirst" command though!
+
+You can use a count for ":next" and ":previous".  To skip two files forward: >
+
+	:2next
+
+
+AUTOMATIC WRITING
+
+When moving around the files and making changes, you have to remember to use
+":write".  Otherwise you will get an error message.  If you are sure you
+always want to write modified files, you can tell Vim to automatically write
+them: >
+
+	:set autowrite
+
+When you are editing a file which you may not want to write, switch it off
+again: >
+
+	:set noautowrite
+
+
+EDITING ANOTHER LIST OF FILES
+
+You can redefine the list of files without the need to exit Vim and start it
+again.  Use this command to edit three other files: >
+
+	:args five.c six.c seven.h
+
+Or use a wildcard, like it's used in the shell: >
+
+	:args *.txt
+
+Vim will take you to the first file in the list.  Again, if the current file
+has changes, you can either write the file first, or use ":args!" (with !
+added) to abandon the changes.
+
+
+DID YOU EDIT THE LAST FILE?
+							*arglist-quit*
+When you use a list of files, Vim assumes you want to edit them all.  To
+protect you from exiting too early, you will get this error when you didn't
+edit the last file in the list yet:
+
+	E173: 46 more files to edit ~
+
+If you really want to exit, just do it again.  Then it will work (but not when
+you did other commands in between).
+
+==============================================================================
+*07.3*	Jumping from file to file
+
+To quickly jump between two files, press CTRL-^ (on English-US keyboards the ^
+is above the 6 key).  Example: >
+
+	:args one.c two.c three.c
+
+You are now in one.c. >
+
+	:next
+
+Now you are in two.c.  Now use CTRL-^ to go back to one.c.  Another CTRL-^ and
+you are back in two.c.  Another CTRL-^ and you are in one.c again.  If you now
+do: >
+
+	:next
+
+You are in three.c.  Notice that the CTRL-^ command does not change the idea
+of where you are in the list of files.  Only commands like ":next" and
+":previous" do that.
+
+The file you were previously editing is called the "alternate" file.  When you
+just started Vim CTRL-^ will not work, since there isn't a previous file.
+
+
+PREDEFINED MARKS
+
+After jumping to another file, you can use two predefined marks which are very
+useful: >
+
+	`"
+
+This takes you to the position where the cursor was when you left the file.
+Another mark that is remembered is the position where you made the last
+change: >
+
+	`.
+
+Suppose you are editing the file "one.txt".  Somewhere halfway the file you
+use "x" to delete a character.  Then you go to the last line with "G" and
+write the file with ":w".  You edit several other files, and then use ":edit
+one.txt" to come back to "one.txt".  If you now use `" Vim jumps to the last
+line of the file.  Using `. takes you to the position where you deleted the
+character.  Even when you move around in the file `" and `. will take you to
+the remembered position.  At least until you make another change or leave the
+file.
+
+
+FILE MARKS
+
+In chapter 4 was explained how you can place a mark in a file with "mx" and
+jump to that position with "`x".  That works within one file.  If you edit
+another file and place marks there, these are specific for that file.  Thus
+each file has its own set of marks, they are local to the file.
+   So far we were using marks with a lowercase letter.  There are also marks
+with an uppercase letter.  These are global, they can be used from any file.
+For example suppose that we are editing the file "foo.txt".  Go to halfway the
+file ("50%") and place the F mark there (F for foo): >
+
+	50%mF
+
+Now edit the file "bar.txt" and place the B mark (B for bar) at its last line:
+>
+	GmB
+
+Now you can use the "'F" command to jump back to halfway foo.txt.  Or edit yet
+another file, type "'B" and you are at the end of bar.txt again.
+
+The file marks are remembered until they are placed somewhere else.  Thus you
+can place the mark, do hours of editing and still be able to jump back to that
+mark.
+   It's often useful to think of a simple connection between the mark letter
+and where it is placed.  For example, use the H mark in a header file, M in
+a Makefile and C in a C code file.
+
+To see where a specific mark is, give an argument to the ":marks" command: >
+
+	:marks M
+
+You can also give several arguments: >
+
+	:marks MCP
+
+Don't forget that you can use CTRL-O and CTRL-I to jump to older and newer
+positions without placing marks there.
+
+==============================================================================
+*07.4*	Backup files
+
+Usually Vim does not produce a backup file.  If you want to have one, all you
+need to do is execute the following command: >
+
+	:set backup
+
+The name of the backup file is the original file with a  ~  added to the end.
+If your file is named data.txt, for example, the backup file name is
+data.txt~.
+   If you do not like the fact that the backup files end with ~, you can
+change the extension: >
+
+	:set backupext=.bak
+
+This will use data.txt.bak instead of data.txt~.
+   Another option that matters here is 'backupdir'.  It specifies where the
+backup file is written.  The default, to write the backup in the same
+directory as the original file, will mostly be the right thing.
+
+	Note:
+	When the 'backup' option isn't set but the 'writebackup' is, Vim will
+	still create a backup file.  However, it is deleted as soon as writing
+	the file was completed successfully.  This functions as a safety
+	against losing your original file when writing fails in some way (disk
+	full is the most common cause; being hit by lightning might be
+	another, although less common).
+
+
+KEEPING THE ORIGINAL FILE
+
+If you are editing source files, you might want to keep the file before you
+make any changes.  But the backup file will be overwritten each time you write
+the file.  Thus it only contains the previous version, not the first one.
+   To make Vim keep the original file, set the 'patchmode' option.  This
+specifies the extension used for the first backup of a changed file.  Usually
+you would do this: >
+
+	:set patchmode=.orig
+
+When you now edit the file data.txt for the first time, make changes and write
+the file, Vim will keep a copy of the unchanged file under the name
+"data.txt.orig".
+   If you make further changes to the file, Vim will notice that
+"data.txt.orig" already exists and leave it alone.  Further backup files will
+then be called "data.txt~" (or whatever you specified with 'backupext').
+   If you leave 'patchmode' empty (that is the default), the original file
+will not be kept.
+
+==============================================================================
+*07.5*	Copy text between files
+
+This explains how to copy text from one file to another.  Let's start with a
+simple example.  Edit the file that contains the text you want to copy.  Move
+the cursor to the start of the text and press "v".  This starts Visual mode.
+Now move the cursor to the end of the text and press "y".  This yanks (copies)
+the selected text.
+   To copy the above paragraph, you would do: >
+
+	:edit thisfile
+	/This
+	vjjjj$y
+
+Now edit the file you want to put the text in.  Move the cursor to the
+character where you want the text to appear after.  Use "p" to put the text
+there. >
+	:edit otherfile
+	/There
+	p
+
+Of course you can use many other commands to yank the text.  For example, to
+select whole lines start Visual mode with "V".  Or use CTRL-V to select a
+rectangular block.  Or use "Y" to yank a single line, "yaw" to yank-a-word,
+etc.
+   The "p" command puts the text after the cursor.  Use "P" to put the text
+before the cursor.  Notice that Vim remembers if you yanked a whole line or a
+block, and puts it back that way.
+
+
+USING REGISTERS
+
+When you want to copy several pieces of text from one file to another, having
+to switch between the files and writing the target file takes a lot of time.
+To avoid this, copy each piece of text to its own register.
+   A register is a place where Vim stores text.  Here we will use the
+registers named a to z (later you will find out there are others).  Let's copy
+a sentence to the f register (f for First): >
+
+	"fyas
+
+The "yas" command yanks a sentence like before.  It's the "f that tells Vim
+the text should be place in the f register.  This must come just before the
+yank command.
+   Now yank three whole lines to the l register (l for line): >
+
+	"l3Y
+
+The count could be before the "l just as well.  To yank a block of text to the
+b (for block) register: >
+
+	CTRL-Vjjww"by
+
+Notice that the register specification "b is just before the "y" command.
+This is required.  If you would have put it before the "w" command, it would
+not have worked.
+   Now you have three pieces of text in the f, l and b registers.  Edit
+another file, move around and place the text where you want it: >
+
+	"fp
+
+Again, the register specification "f comes before the "p" command.
+   You can put the registers in any order.  And the text stays in the register
+until you yank something else into it.  Thus you can put it as many times as
+you like.
+
+When you delete text, you can also specify a register.  Use this to move
+several pieces of text around.  For example, to delete-a-word and write it in
+the w register: >
+
+	"wdaw
+
+Again, the register specification comes before the delete command "d".
+
+
+APPENDING TO A FILE
+
+When collecting lines of text into one file, you can use this command: >
+
+	:write >> logfile
+
+This will write the text of the current file to the end of "logfile".  Thus it
+is appended.  This avoids that you have to copy the lines, edit the log file
+and put them there.  Thus you save two steps.  But you can only append to the
+end of a file.
+   To append only a few lines, select them in Visual mode before typing
+":write".  In chapter 10 you will learn other ways to select a range of lines.
+
+==============================================================================
+*07.6*	Viewing a file
+
+Sometimes you only want to see what a file contains, without the intention to
+ever write it back.  There is the risk that you type ":w" without thinking and
+overwrite the original file anyway.  To avoid this, edit the file read-only.
+   To start Vim in readonly mode, use this command: >
+
+	vim -R file
+
+On Unix this command should do the same thing: >
+
+	view file
+
+You are now editing "file" in read-only mode.  When you try using ":w" you
+will get an error message and the file won't be written.
+   When you try to make a change to the file Vim will give you a warning:
+
+	W10: Warning: Changing a readonly file ~
+
+The change will be done though.  This allows for formatting the file, for
+example, to be able to read it easily.
+   If you make changes to a file and forgot that it was read-only, you can
+still write it.  Add the ! to the write command to force writing.
+
+If you really want to forbid making changes in a file, do this: >
+
+	vim -M file
+
+Now every attempt to change the text will fail.  The help files are like this,
+for example.  If you try to make a change you get this error message:
+
+	E21: Cannot make changes, 'modifiable' is off ~
+
+You could use the -M argument to setup Vim to work in a viewer mode.  This is
+only voluntary though, since these commands will remove the protection: >
+
+	:set modifiable
+	:set write
+
+==============================================================================
+*07.7*	Changing the file name
+
+A clever way to start editing a new file is by using an existing file that
+contains most of what you need.  For example, you start writing a new program
+to move a file.  You know that you already have a program that copies a file,
+thus you start with: >
+
+	:edit copy.c
+
+You can delete the stuff you don't need.  Now you need to save the file under
+a new name.  The ":saveas" command can be used for this: >
+
+	:saveas move.c
+
+Vim will write the file under the given name, and edit that file.  Thus the
+next time you do ":write", it will write "move.c".  "copy.c" remains
+unmodified.
+   When you want to change the name of the file you are editing, but don't
+want to write the file, you can use this command: >
+
+	:file move.c
+
+Vim will mark the file as "not edited".  This means that Vim knows this is not
+the file you started editing.  When you try to write the file, you might get
+this message:
+
+	E13: File exists (use ! to override) ~
+
+This protects you from accidentally overwriting another file.
+
+==============================================================================
+
+Next chapter: |usr_08.txt|  Splitting windows
+
+Copyright: see |manual-copyright|  vim:tw=78:ts=8:ft=help:norl:
--- /dev/null
+++ b/lib/vimfiles/doc/usr_08.txt
@@ -1,0 +1,601 @@
+*usr_08.txt*	For Vim version 7.1.  Last change: 2006 Jul 18
+
+		     VIM USER MANUAL - by Bram Moolenaar
+
+			      Splitting windows
+
+
+Display two different files above each other.  Or view two locations in the
+file at the same time.  See the difference between two files by putting them
+side by side.  All this is possible with split windows.
+
+|08.1|	Split a window
+|08.2|	Split a window on another file
+|08.3|	Window size
+|08.4|	Vertical splits
+|08.5|	Moving windows
+|08.6|	Commands for all windows
+|08.7|	Viewing differences with vimdiff
+|08.8|	Various
+|08.9|  Tab pages
+
+     Next chapter: |usr_09.txt|  Using the GUI
+ Previous chapter: |usr_07.txt|  Editing more than one file
+Table of contents: |usr_toc.txt|
+
+==============================================================================
+*08.1*	Split a window
+
+The easiest way to open a new window is to use the following command: >
+
+	:split
+
+This command splits the screen into two windows and leaves the cursor in the
+top one:
+
+	+----------------------------------+
+	|/* file one.c */		   |
+	|~				   |
+	|~				   |
+	|one.c=============================|
+	|/* file one.c */		   |
+	|~				   |
+	|one.c=============================|
+	|				   |
+	+----------------------------------+
+
+What you see here is two windows on the same file.  The line with "====" is
+that status line.  It displays information about the window above it.  (In
+practice the status line will be in reverse video.)
+   The two windows allow you to view two parts of the same file.  For example,
+you could make the top window show the variable declarations of a program, and
+the bottom one the code that uses these variables.
+
+The CTRL-W w command can be used to jump between the windows.  If you are in
+the top window, CTRL-W w jumps to the window below it.  If you are in the
+bottom window it will jump to the first window.  (CTRL-W CTRL-W does the same
+thing, in case you let go of the CTRL key a bit later.)
+
+
+CLOSE THE WINDOW
+
+To close a window, use the command: >
+
+	:close
+
+Actually, any command that quits editing a file works, like ":quit" and "ZZ".
+But ":close" prevents you from accidentally exiting Vim when you close the
+last window.
+
+
+CLOSING ALL OTHER WINDOWS
+
+If you have opened a whole bunch of windows, but now want to concentrate on
+one of them, this command will be useful: >
+
+	:only
+
+This closes all windows, except for the current one.  If any of the other
+windows has changes, you will get an error message and that window won't be
+closed.
+
+==============================================================================
+*08.2*	Split a window on another file
+
+The following command opens a second window and starts editing the given file:
+>
+	:split two.c
+
+If you were editing one.c, then the result looks like this:
+
+	+----------------------------------+
+	|/* file two.c */		   |
+	|~				   |
+	|~				   |
+	|two.c=============================|
+	|/* file one.c */		   |
+	|~				   |
+	|one.c=============================|
+	|				   |
+	+----------------------------------+
+
+To open a window on a new, empty file, use this: >
+
+	:new
+
+You can repeat the ":split" and ":new" commands to create as many windows as
+you like.
+
+==============================================================================
+*08.3*	Window size
+
+The ":split" command can take a number argument.  If specified, this will be
+the height of the new window.  For example, the following opens a new window
+three lines high and starts editing the file alpha.c: >
+
+	:3split alpha.c
+
+For existing windows you can change the size in several ways.  When you have a
+working mouse, it is easy: Move the mouse pointer to the status line that
+separates two windows, and drag it up or down.
+
+To increase the size of a window: >
+
+	CTRL-W +
+
+To decrease it: >
+
+	CTRL-W -
+
+Both of these commands take a count and increase or decrease the window size
+by that many lines.  Thus "4 CTRL-W +" make the window four lines higher.
+
+To set the window height to a specified number of lines: >
+
+	{height}CTRL-W _
+
+That's: a number {height}, CTRL-W and then an underscore (the - key with Shift
+on English-US keyboards).
+   To make a window as high as it can be, use the CTRL-W _ command without a
+count.
+
+
+USING THE MOUSE
+
+In Vim you can do many things very quickly from the keyboard.  Unfortunately,
+the window resizing commands require quite a bit of typing.  In this case,
+using the mouse is faster.  Position the mouse pointer on a status line.  Now
+press the left mouse button and drag.  The status line will move, thus making
+the window on one side higher and the other smaller.
+
+
+OPTIONS
+
+The 'winheight' option can be set to a minimal desired height of a window and
+'winminheight' to a hard minimum height.
+   Likewise, there is 'winwidth' for the minimal desired width and
+'winminwidth' for the hard minimum width.
+   The 'equalalways' option, when set, makes Vim equalize the windows sizes
+when a window is closed or opened.
+
+==============================================================================
+*08.4*	Vertical splits
+
+The ":split" command creates the new window above the current one.  To make
+the window appear at the left side, use: >
+
+	:vsplit
+
+or: >
+	:vsplit two.c
+
+The result looks something like this:
+
+	+--------------------------------------+
+	|/* file two.c */   |/* file one.c */  |
+	|~		    |~		       |
+	|~		    |~		       |
+	|~		    |~		       |
+	|two.c===============one.c=============|
+	|				       |
+	+--------------------------------------+
+
+Actually, the | lines in the middle will be in reverse video.  This is called
+the vertical separator.  It separates the two windows left and right of it.
+
+There is also the ":vnew" command, to open a vertically split window on a new,
+empty file.  Another way to do this: >
+
+	:vertical new
+
+The ":vertical" command can be inserted before another command that splits a
+window.  This will cause that command to split the window vertically instead
+of horizontally.  (If the command doesn't split a window, it works
+unmodified.)
+
+
+MOVING BETWEEN WINDOWS
+
+Since you can split windows horizontally and vertically as much as you like,
+you can create almost any layout of windows.  Then you can use these commands
+to move between them:
+
+	CTRL-W h	move to the window on the left
+	CTRL-W j	move to the window below
+	CTRL-W k	move to the window above
+	CTRL-W l	move to the window on the right
+
+	CTRL-W t	move to the TOP window
+	CTRL-W b	move to the BOTTOM window
+
+You will notice the same letters as used for moving the cursor.  And the
+cursor keys can also be used, if you like.
+   More commands to move to other windows: |Q_wi|.
+
+==============================================================================
+*08.5*	Moving windows
+
+You have split a few windows, but now they are in the wrong place.  Then you
+need a command to move the window somewhere else.  For example, you have three
+windows like this:
+
+	+----------------------------------+
+	|/* file two.c */		   |
+	|~				   |
+	|~				   |
+	|two.c=============================|
+	|/* file three.c */		   |
+	|~				   |
+	|~				   |
+	|three.c===========================|
+	|/* file one.c */		   |
+	|~				   |
+	|one.c=============================|
+	|				   |
+	+----------------------------------+
+
+Clearly the last one should be at the top.  Go to that window (using CTRL-W w)
+and the type this command: >
+
+	CTRL-W K
+
+This uses the uppercase letter K.  What happens is that the window is moved to
+the very top.  You will notice that K is again used for moving upwards.
+   When you have vertical splits, CTRL-W K will move the current window to the
+top and make it occupy the full width of the Vim window.  If this is your
+layout:
+
+	+-------------------------------------------+
+	|/* two.c */  |/* three.c */  |/* one.c */  |
+	|~	      |~	      |~	    |
+	|~	      |~	      |~	    |
+	|~	      |~	      |~	    |
+	|~	      |~	      |~	    |
+	|~	      |~	      |~	    |
+	|two.c=========three.c=========one.c========|
+	|					    |
+	+-------------------------------------------+
+
+Then using CTRL-W K in the middle window (three.c) will result in:
+
+	+-------------------------------------------+
+	|/* three.c */				    |
+	|~					    |
+	|~					    |
+	|three.c====================================|
+	|/* two.c */	       |/* one.c */	    |
+	|~		       |~		    |
+	|two.c==================one.c===============|
+	|					    |
+	+-------------------------------------------+
+
+The other three similar commands (you can probably guess these now):
+
+	CTRL-W H	move window to the far left
+	CTRL-W J	move window to the bottom
+	CTRL-W L	move window to the far right
+
+==============================================================================
+*08.6*	Commands for all windows
+
+When you have several windows open and you want to quit Vim, you can close
+each window separately.  A quicker way is using this command: >
+
+	:qall
+
+This stands for "quit all".  If any of the windows contain changes, Vim will
+not exit.  The cursor will automatically be positioned in a window with
+changes.  You can then either use ":write" to save the changes, or ":quit!" to
+throw them away.
+
+If you know there are windows with changes, and you want to save all these
+changes, use this command: >
+
+	:wall
+
+This stands for "write all".  But actually, it only writes files with
+changes.  Vim knows it doesn't make sense to write files that were not
+changed.
+   And then there is the combination of ":qall" and ":wall": the "write and
+quit all" command: >
+
+	:wqall
+
+This writes all modified files and quits Vim.
+   Finally, there is a command that quits Vim and throws away all changes: >
+
+	:qall!
+
+Be careful, there is no way to undo this command!
+
+
+OPENING A WINDOW FOR ALL ARGUMENTS
+
+To make Vim open a window for each file, start it with the "-o" argument: >
+
+	vim -o one.txt two.txt three.txt
+
+This results in:
+
+	+-------------------------------+
+	|file one.txt			|
+	|~				|
+	|one.txt========================|
+	|file two.txt			|
+	|~				|
+	|two.txt========================|
+	|file three.txt			|
+	|~				|
+	|three.txt======================|
+	|				|
+	+-------------------------------+
+
+The "-O" argument is used to get vertically split windows.
+   When Vim is already running, the ":all" command opens a window for each
+file in the argument list.  ":vertical all" does it with vertical splits.
+
+==============================================================================
+*08.7*	Viewing differences with vimdiff
+
+There is a special way to start Vim, which shows the differences between two
+files.  Let's take a file "main.c" and insert a few characters in one line.
+Write this file with the 'backup' option set, so that the backup file
+"main.c~" will contain the previous version of the file.
+   Type this command in a shell (not in Vim): >
+
+	vimdiff main.c~ main.c
+
+Vim will start, with two windows side by side.  You will only see the line
+in which you added characters, and a few lines above and below it.
+
+	 VV		      VV
+	+-----------------------------------------+
+	|+ +--123 lines: /* a|+ +--123 lines: /* a|  <- fold
+	|  text		     |	text		  |
+	|  text		     |	text		  |
+	|  text		     |	text		  |
+	|  text		     |	changed text	  |  <- changed line
+	|  text		     |	text		  |
+	|  text		     |	------------------|  <- deleted line
+	|  text		     |	text		  |
+	|  text		     |	text		  |
+	|  text		     |	text		  |
+	|+ +--432 lines: text|+ +--432 lines: text|  <- fold
+	|  ~		     |	~		  |
+	|  ~		     |	~		  |
+	|main.c~==============main.c==============|
+	|					  |
+	+-----------------------------------------+
+
+(This picture doesn't show the highlighting, use the vimdiff command for a
+better look.)
+
+The lines that were not modified have been collapsed into one line.  This is
+called a closed fold.  They are indicated in the picture with "<- fold".  Thus
+the single fold line at the top stands for 123 text lines.  These lines are
+equal in both files.
+   The line marked with "<- changed line" is highlighted, and the inserted
+text is displayed with another color.  This clearly shows what the difference
+is between the two files.
+   The line that was deleted is displayed with "---" in the main.c window.
+See the "<- deleted line" marker in the picture.  These characters are not
+really there.  They just fill up main.c, so that it displays the same number
+of lines as the other window.
+
+
+THE FOLD COLUMN
+
+Each window has a column on the left with a slightly different background.  In
+the picture above these are indicated with "VV".  You notice there is a plus
+character there, in front of each closed fold.  Move the mouse pointer to that
+plus and click the left button.  The fold will open, and you can see the text
+that it contains.
+   The fold column contains a minus sign for an open fold.  If you click on
+this -, the fold will close.
+   Obviously, this only works when you have a working mouse.  You can also use
+"zo" to open a fold and "zc" to close it.
+
+
+DIFFING IN VIM
+
+Another way to start in diff mode can be done from inside Vim.  Edit the
+"main.c" file, then make a split and show the differences: >
+
+	:edit main.c
+	:vertical diffsplit main.c~ 
+
+The ":vertical" command is used to make the window split vertically.  If you
+omit this, you will get a horizontal split.
+
+If you have a patch or diff file, you can use the third way to start diff
+mode.  First edit the file to which the patch applies.  Then tell Vim the name
+of the patch file: >
+
+	:edit main.c
+	:vertical diffpatch main.c.diff
+
+WARNING: The patch file must contain only one patch, for the file you are
+editing.  Otherwise you will get a lot of error messages, and some files might
+be patched unexpectedly.
+   The patching will only be done to the copy of the file in Vim.  The file on
+your harddisk will remain unmodified (until you decide to write the file).
+
+
+SCROLL BINDING
+
+When the files have more changes, you can scroll in the usual way.  Vim will
+try to keep both the windows start at the same position, so you can easily see
+the differences side by side.
+   When you don't want this for a moment, use this command: >
+
+	:set noscrollbind
+
+
+JUMPING TO CHANGES
+
+When you have disabled folding in some way, it may be difficult to find the
+changes.  Use this command to jump forward to the next change: >
+
+	]c
+
+To go the other way use: >
+
+	[c
+
+Prepended a count to jump further away.
+
+
+REMOVING CHANGES
+
+You can move text from one window to the other.  This either removes
+differences or adds new ones.  Vim doesn't keep the highlighting updated in
+all situations.  To update it use this command: >
+
+	:diffupdate
+
+To remove a difference, you can move the text in a highlighted block from one
+window to another.  Take the "main.c" and "main.c~" example above.  Move the
+cursor to the left window, on the line that was deleted in the other window.
+Now type this command: >
+
+	dp
+
+The change will be removed by putting the text of the current window in the
+other window.  "dp" stands for "diff put".
+   You can also do it the other way around.  Move the cursor to the right
+window, to the line where "changed" was inserted.  Now type this command: >
+
+	do
+
+The change will now be removed by getting the text from the other window.
+Since there are no changes left now, Vim puts all text in a closed fold.
+"do" stands for "diff obtain".  "dg" would have been better, but that already
+has a different meaning ("dgg" deletes from the cursor until the first line).
+
+For details about diff mode, see |vimdiff|.
+
+==============================================================================
+*08.8*	Various
+
+The 'laststatus' option can be used to specify when the last window has a
+statusline:
+
+	0	never
+	1	only when there are split windows (the default)
+	2	always
+
+Many commands that edit another file have a variant that splits the window.
+For Command-line commands this is done by prepending an "s".  For example:
+":tag" jumps to a tag, ":stag" splits the window and jumps to a
+tag.
+   For Normal mode commands a CTRL-W is prepended.  CTRL-^ jumps to the
+alternate file, CTRL-W CTRL-^ splits the window and edits the alternate file.
+
+The 'splitbelow' option can be set to make a new window appear below the
+current window.  The 'splitright' option can be set to make a vertically split
+window appear right of the current window.
+
+When splitting a window you can prepend a modifier command to tell where the
+window is to appear:
+
+	:leftabove {cmd}	left or above the current window
+	:aboveleft {cmd}	idem
+	:rightbelow {cmd}	right or below the current window
+	:belowright {cmd}	idem
+	:topleft {cmd}		at the top or left of the Vim window
+	:botright {cmd}		at the bottom or right of the Vim window
+
+
+==============================================================================
+*08.9*	Tab pages
+
+You will have noticed that windows never overlap.  That means you quickly run
+out of screen space.  The solution for this is called Tab pages.
+
+Assume you are editing "thisfile".  To create a new tab page use this command: >
+
+	:tabedit thatfile
+
+This will edit the file "thatfile" in a window that occupies the whole Vim
+window.  And you will notice a bar at the top with the two file names:
+
+	+----------------------------------+
+	| thisfile | /thatfile/ __________X|    (thatfile is bold)
+	|/* thatfile */			   |
+	|that				   |
+	|that				   |
+	|~				   |
+	|~				   |
+	|~				   |
+	|				   |
+	+----------------------------------+
+
+You now have two tab pages.  The first one has a window for "thisfile" and the
+second one a window for "thatfile".  It's like two pages that are on top of
+eachother, with a tab sticking out of each page showing the file name.
+
+Now use the mouse to click on "thisfile" in the top line.  The result is
+
+	+----------------------------------+
+	| /thisfile/ | thatfile __________X|    (thisfile is bold)
+	|/* thisfile */			   |
+	|this				   |
+	|this				   |
+	|~				   |
+	|~				   |
+	|~				   |
+	|				   |
+	+----------------------------------+
+
+Thus you can switch between tab pages by clicking on the label in the top
+line.  If you don't have a mouse or don't want to use it, you can use the "gt"
+command.  Mnemonic: Goto Tab.
+
+Now let's create another tab page with the command: >
+
+	:tab split
+
+This makes a new tab page with one window that is editing the same buffer as
+the window we were in:
+
+	+-------------------------------------+
+	| thisfile | /thisfile/ | thatfile __X|   (thisfile is bold)
+	|/* thisfile */			      |
+	|this				      |
+	|this				      |
+	|~				      |
+	|~				      |
+	|~				      |
+	|				      |
+	+-------------------------------------+
+
+You can put ":tab" before any Ex command that opens a window.  The window will
+be opened in a new tab page.  Another example: >
+
+	:tab help gt
+
+Will show the help text for "gt" in a new tab page.
+
+A few more things you can do with tab pages:
+
+- click with the mouse in the space after the last label
+	The next tab page will be selected, like with "gt".
+
+- click with the mouse on the "X" in the top right corner
+	The current tab page will be closed.  Unless there are unsaved
+	changes in the current tab page.
+
+- double click with the mouse in the top line
+	A new tab page will be created.
+
+- the "tabonly" command
+	Closes all tab pages except the current one.  Unless there are unsaved
+	changes in other tab pages.
+
+For more information about tab pages see |tab-page|.
+
+==============================================================================
+
+Next chapter: |usr_09.txt|  Using the GUI
+
+Copyright: see |manual-copyright|  vim:tw=78:ts=8:ft=help:norl:
--- /dev/null
+++ b/lib/vimfiles/doc/usr_09.txt
@@ -1,0 +1,289 @@
+*usr_09.txt*	For Vim version 7.1.  Last change: 2006 Apr 24
+
+		     VIM USER MANUAL - by Bram Moolenaar
+
+				Using the GUI
+
+
+Vim works in an ordinary terminal.  GVim can do the same things and a few
+more.  The GUI offers menus, a toolbar, scrollbars and other items.  This
+chapter is about these extra things that the GUI offers.
+
+|09.1|	Parts of the GUI
+|09.2|	Using the mouse
+|09.3|	The clipboard
+|09.4|	Select mode
+
+     Next chapter: |usr_10.txt|  Making big changes
+ Previous chapter: |usr_08.txt|  Splitting windows
+Table of contents: |usr_toc.txt|
+
+==============================================================================
+*09.1*	Parts of the GUI
+
+You might have an icon on your desktop that starts gVim.  Otherwise, one of
+these commands should do it: >
+
+	gvim file.txt
+	vim -g file.txt
+
+If this doesn't work you don't have a version of Vim with GUI support.  You
+will have to install one first.
+   Vim will open a window and display "file.txt" in it.  What the window looks
+like depends on the version of Vim.  It should resemble the following picture
+(for as far as this can be shown in ASCII!).
+
+	+----------------------------------------------------+
+	| file.txt + (~/dir) - VIM			   X |	<- window title
+	+----------------------------------------------------+
+	| File	Edit  Tools  Syntax  Buffers  Window  Help   |	<- menubar
+	+----------------------------------------------------+
+	| aaa  bbb  ccc  ddd  eee  fff	ggg  hhh  iii  jjj   |	<- toolbar
+	| aaa  bbb  ccc  ddd  eee  fff	ggg  hhh  iii  jjj   |
+	+----------------------------------------------------+
+	| file text					 | ^ |
+	| ~						 | # |
+	| ~						 | # |	<- scrollbar
+	| ~						 | # |
+	| ~						 | # |
+	| ~						 | # |
+	|						 | V |
+	+----------------------------------------------------+
+
+The largest space is occupied by the file text.  This shows the file in the
+same way as in a terminal.  With some different colors and another font
+perhaps.
+
+
+THE WINDOW TITLE
+
+At the very top is the window title.  This is drawn by your window system.
+Vim will set the title to show the name of the current file.  First comes the
+name of the file.  Then some special characters and the directory of the file
+in parens.  These special character can be present:
+
+	-	The file cannot be modified (e.g., a help file)
+	+	The file contains changes
+	=	The file is read-only
+	=+	The file is read-only, contains changes anyway
+
+If nothing is shown you have an ordinary, unchanged file.
+
+
+THE MENUBAR
+
+You know how menus work, right?  Vim has the usual items, plus a few more.
+Browse them to get an idea of what you can use them for.  A relevant submenu
+is Edit/Global Settings.  You will find these entries:
+
+	Toggle Toolbar		make the toolbar appear/disappear
+	Toggle Bottom Scrollbar	make a scrollbar appear/disappear at the bottom
+	Toggle Left Scrollbar	make a scrollbar appear/disappear at the left
+	Toggle Right Scrollbar	make a scrollbar appear/disappear at the right
+
+On most systems you can tear-off the menus.  Select the top item of the menu,
+the one that looks like a dashed line.  You will get a separate window with
+the items of the menu.  It will hang around until you close the window.
+
+
+THE TOOLBAR
+
+This contains icons for the most often used actions.  Hopefully the icons are
+self-explanatory.  There are tooltips to get an extra hint (move the mouse
+pointer to the icon without clicking and don't move it for a second).
+
+The "Edit/Global Settings/Toggle Toolbar" menu item can be used to make the
+toolbar disappear.  If you never want a toolbar, use this command in your
+vimrc file: >
+
+	:set guioptions-=T
+
+This removes the 'T' flag from the 'guioptions' option.  Other parts of the
+GUI can also be enabled or disabled with this option.  See the help for it.
+
+
+THE SCROLLBARS
+
+By default there is one scrollbar on the right.  It does the obvious thing.
+When you split the window, each window will get its own scrollbar.
+   You can make a horizontal scrollbar appear with the menu item
+Edit/Global Settings/Toggle Bottom Scrollbar.  This is useful in diff mode, or
+when the 'wrap' option has been reset (more about that later).
+
+When there are vertically split windows, only the windows on the right side
+will have a scrollbar.  However, when you move the cursor to a window on the
+left, it will be this one the that scrollbar controls.  This takes a bit of
+time to get used to.
+   When you work with vertically split windows, consider adding a scrollbar on
+the left.  This can be done with a menu item, or with the 'guioptions' option:
+>
+	:set guioptions+=l
+
+This adds the 'l' flag to 'guioptions'.
+
+==============================================================================
+*09.2*	Using the mouse
+
+Standards are wonderful.  In Microsoft Windows, you can use the mouse to
+select text in a standard manner.  The X Window system also has a standard
+system for using the mouse.  Unfortunately, these two standards are not the
+same.
+   Fortunately, you can customize Vim.  You can make the behavior of the mouse
+work like an X Window system mouse or a Microsoft Windows mouse.  The following
+command makes the mouse behave like an X Window mouse: >
+
+	:behave xterm
+
+The following command makes the mouse work like a Microsoft Windows mouse: >
+
+	:behave mswin
+
+The default behavior of the mouse on UNIX systems is xterm.  The default
+behavior on a Microsoft Windows system is selected during the installation
+process.  For details about what the two behaviors are, see |:behave|.  Here
+follows a summary.
+
+
+XTERM MOUSE BEHAVIOR
+
+Left mouse click		position the cursor
+Left mouse drag			select text in Visual mode
+Middle mouse click		paste text from the clipboard
+Right mouse click		extend the selected text until the mouse
+				pointer
+
+
+MSWIN MOUSE BEHAVIOR
+
+Left mouse click		position the cursor
+Left mouse drag			select text in Select mode (see |09.4|)
+Left mouse click, with Shift	extend the selected text until the mouse
+				pointer
+Middle mouse click		paste text from the clipboard
+Right mouse click		display a pop-up menu
+
+
+The mouse can be further tuned.  Check out these options if you want to change
+the way how the mouse works:
+
+	'mouse'			in which mode the mouse is used by Vim
+	'mousemodel'		what effect a mouse click has
+	'mousetime'		time between clicks for a double-click
+	'mousehide'		hide the mouse while typing
+	'selectmode'		whether the mouse starts Visual or Select mode
+
+==============================================================================
+*09.3*	The clipboard
+
+In section |04.7| the basic use of the clipboard was explained.  There is one
+essential thing to explain about X-windows: There are actually two places to
+exchange text between programs.  MS-Windows doesn't have this.
+
+In X-Windows there is the "current selection".  This is the text that is
+currently highlighted.  In Vim this is the Visual area (this assumes you are
+using the default option settings).  You can paste this selection in another
+application without any further action.
+   For example, in this text select a few words with the mouse.  Vim will
+switch to Visual mode and highlight the text.  Now start another gVim, without
+a file name argument, so that it displays an empty window.  Click the middle
+mouse button.  The selected text will be inserted.
+
+The "current selection" will only remain valid until some other text is
+selected.  After doing the paste in the other gVim, now select some characters
+in that window.  You will notice that the words that were previously selected
+in the other gVim window are displayed differently.  This means that it no
+longer is the current selection.
+
+You don't need to select text with the mouse, using the keyboard commands for
+Visual mode works just as well.
+
+
+THE REAL CLIPBOARD
+
+Now for the other place with which text can be exchanged.  We call this the
+"real clipboard", to avoid confusion.  Often both the "current selection" and
+the "real clipboard" are called clipboard, you'll have to get used to that.
+   To put text on the real clipboard, select a few different words in one of
+the gVims you have running.  Then use the Edit/Copy menu entry.  Now the text
+has been copied to the real clipboard.  You can't see this, unless you have
+some application that shows the clipboard contents (e.g., KDE's klipper).
+   Now select the other gVim, position the cursor somewhere and use the
+Edit/Paste menu.  You will see the text from the real clipboard is inserted.
+
+
+USING BOTH
+
+This use of both the "current selection" and the "real clipboard" might sound
+a bit confusing.  But it is very useful.  Let's show this with an example.
+Use one gVim with a text file and perform these actions:
+
+-  Select two words in Visual mode.
+-  Use the Edit/Copy menu to get these words onto the clipboard.
+-  Select one other word in Visual mode.
+-  Use the Edit/Paste menu item.  What will happen is that the single selected
+   word is replaced with the two words from the clipboard.
+-  Move the mouse pointer somewhere else and click the middle button.  You
+   will see that the word you just overwrote with the clipboard is inserted
+   here.
+
+If you use the "current selection" and the "real clipboard" with care, you can
+do a lot of useful editing with them.
+
+
+USING THE KEYBOARD
+
+If you don't like using the mouse, you can access the current selection and
+the real clipboard with two registers.  The "* register is for the current
+selection.
+   To make text become the current selection, use Visual mode.  For example,
+to select a whole line just press "V".
+   To insert the current selection before the cursor: >
+
+	"*P
+
+Notice the uppercase "P".  The lowercase "p" puts the text after the cursor.
+
+The "+ register is used for the real clipboard.  For example, to copy the text
+from the cursor position until the end of the line to the clipboard: >
+
+	"+y$
+
+Remember, "y" is yank, which is Vim's copy command.
+   To insert the contents of the real clipboard before the cursor: >
+
+	"+P
+
+It's the same as for the current selection, but uses the plus (+) register
+instead of the star (*) register.
+
+==============================================================================
+*09.4*	Select mode
+
+And now something that is used more often on MS-Windows than on X-Windows.
+But both can do it.  You already know about Visual mode.  Select mode is like
+Visual mode, because it is also used to select text.  But there is an obvious
+difference: When typing text, the selected text is deleted and the typed text
+replaces it.
+
+To start working with Select mode, you must first enable it (for MS-Windows
+it is probably already enabled, but you can do this anyway): >
+
+	:set selectmode+=mouse
+
+Now use the mouse to select some text.  It is highlighted like in Visual mode.
+Now press a letter.  The selected text is deleted, and the single letter
+replaces it.  You are in Insert mode now, thus you can continue typing.
+
+Since typing normal text causes the selected text to be deleted, you can not
+use the normal movement commands "hjkl", "w", etc.  Instead, use the shifted
+function keys.  <S-Left> (shifted cursor left key) moves the cursor left.  The
+selected text is changed like in Visual mode.  The other shifted cursor keys
+do what you expect.  <S-End> and <S-Home> also work.
+
+You can tune the way Select mode works with the 'selectmode' option.
+
+==============================================================================
+
+Next chapter: |usr_10.txt|  Making big changes
+
+Copyright: see |manual-copyright|  vim:tw=78:ts=8:ft=help:norl:
--- /dev/null
+++ b/lib/vimfiles/doc/usr_10.txt
@@ -1,0 +1,824 @@
+*usr_10.txt*	For Vim version 7.1.  Last change: 2006 Nov 05
+
+		     VIM USER MANUAL - by Bram Moolenaar
+
+			     Making big changes
+
+
+In chapter 4 several ways to make small changes were explained.  This chapter
+goes into making changes that are repeated or can affect a large amount of
+text.  The Visual mode allows doing various things with blocks of text.  Use
+an external program to do really complicated things.
+
+|10.1|	Record and playback commands
+|10.2|	Substitution
+|10.3|	Command ranges
+|10.4|	The global command
+|10.5|	Visual block mode
+|10.6|	Reading and writing part of a file
+|10.7|	Formatting text
+|10.8|	Changing case
+|10.9|	Using an external program
+
+     Next chapter: |usr_11.txt|  Recovering from a crash
+ Previous chapter: |usr_09.txt|  Using the GUI
+Table of contents: |usr_toc.txt|
+
+==============================================================================
+*10.1*	Record and playback commands
+
+The "." command repeats the preceding change.  But what if you want to do
+something more complex than a single change?  That's where command recording
+comes in.  There are three steps:
+
+1. The "q{register}" command starts recording keystrokes into the register
+   named {register}.  The register name must be between a and z.
+2. Type your commands.
+3. To finish recording, press q (without any extra character).
+
+You can now execute the macro by typing the command "@{register}".
+
+Take a look at how to use these commands in practice.  You have a list of
+filenames that look like this:
+
+	stdio.h ~
+	fcntl.h ~
+	unistd.h ~
+	stdlib.h ~
+
+And what you want is the following:
+
+	#include "stdio.h" ~
+	#include "fcntl.h" ~
+	#include "unistd.h" ~
+	#include "stdlib.h" ~
+
+You start by moving to the first character of the first line.  Next you
+execute the following commands:
+
+	qa			Start recording a macro in register a.
+	^			Move to the beginning of the line.
+	i#include "<Esc>	Insert the string #include " at the beginning
+				of the line.
+	$			Move to the end of the line.
+	a"<Esc>			Append the character double quotation mark (")
+				to the end of the line.
+	j			Go to the next line.
+	q			Stop recording the macro.
+
+Now that you have done the work once, you can repeat the change by typing the
+command "@a" three times.
+   The "@a" command can be preceded by a count, which will cause the macro to
+be executed that number of times.  In this case you would type: >
+
+	3@a
+
+
+MOVE AND EXECUTE
+
+You might have the lines you want to change in various places.  Just move the
+cursor to each location and use the "@a" command.  If you have done that once,
+you can do it again with "@@".  That's a bit easier to type.  If you now
+execute register b with "@b", the next "@@" will use register b.
+   If you compare the playback method with using ".", there are several
+differences.  First of all, "." can only repeat one change.  As seen in the
+example above, "@a" can do several changes, and move around as well.
+Secondly, "." can only remember the last change.  Executing a register allows
+you to make any changes and then still use "@a" to replay the recorded
+commands.  Finally, you can use 26 different registers.  Thus you can remember
+26 different command sequences to execute.
+
+
+USING REGISTERS
+
+The registers used for recording are the same ones you used for yank and
+delete commands.  This allows you to mix recording with other commands to
+manipulate the registers.
+   Suppose you have recorded a few commands in register n.  When you execute
+this with "@n" you notice you did something wrong.  You could try recording
+again, but perhaps you will make another mistake.  Instead, use this trick:
+
+	G			Go to the end of the file.
+	o<Esc>			Create an empty line.
+	"np			Put the text from the n register.  You now see
+				the commands you typed as text in the file.
+	{edits}			Change the commands that were wrong.  This is
+				just like editing text.
+	0			Go to the start of the line.
+	"ny$			Yank the corrected commands into the n
+				register.
+	dd			Delete the scratch line.
+
+Now you can execute the corrected commands with "@n".  (If your recorded
+commands include line breaks, adjust the last two items in the example to
+include all the lines.)
+
+
+APPENDING TO A REGISTER
+
+So far we have used a lowercase letter for the register name.  To append to a
+register, use an uppercase letter.
+   Suppose you have recorded a command to change a word to register c.  It
+works properly, but you would like to add a search for the next word to
+change.  This can be done with: >
+
+	qC/word<Enter>q
+
+You start with "qC", which records to the c register and appends.  Thus
+writing to an uppercase register name means to append to the register with
+the same letter, but lowercase.
+
+This works both with recording and with yank and delete commands.  For
+example, you want to collect a sequence of lines into the a register.  Yank
+the first line with: >
+
+	"aY
+
+Now move to the second line, and type: >
+
+	"AY
+
+Repeat this command for all lines.  The a register now contains all those
+lines, in the order you yanked them.
+
+==============================================================================
+*10.2*	Substitution						*find-replace*
+
+The ":substitute" command enables you to perform string replacements on a
+whole range of lines.  The general form of this command is as follows: >
+
+	:[range]substitute/from/to/[flags]
+
+This command changes the "from" string to the "to" string in the lines
+specified with [range].  For example, you can change "Professor" to "Teacher"
+in all lines with the following command: >
+
+	:%substitute/Professor/Teacher/
+<
+	Note:
+	The ":substitute" command is almost never spelled out completely.
+	Most of the time, people use the abbreviated version ":s".  From here
+	on the abbreviation will be used.
+
+The "%" before the command specifies the command works on all lines.  Without
+a range, ":s" only works on the current line.  More about ranges in the next
+section |10.3|.
+
+By default, the ":substitute" command changes only the first occurrence on
+each line.  For example, the preceding command changes the line:
+
+	Professor Smith criticized Professor Johnson today. ~
+
+to:
+
+	Teacher Smith criticized Professor Johnson today. ~
+
+To change every occurrence on the line, you need to add the g (global) flag.
+The command: >
+
+	:%s/Professor/Teacher/g
+
+results in (starting with the original line):
+
+	Teacher Smith criticized Teacher Johnson today. ~
+
+Other flags include p (print), which causes the ":substitute" command to print
+out the last line it changes.  The c (confirm) flag tells ":substitute" to ask
+you for confirmation before it performs each substitution.  Enter the
+following: >
+
+	:%s/Professor/Teacher/c
+
+Vim finds the first occurrence of "Professor" and displays the text it is
+about to change.  You get the following prompt: >
+
+	replace with Teacher (y/n/a/q/l/^E/^Y)?
+
+At this point, you must enter one of the following answers:
+
+	y		Yes; make this change.
+	n		No; skip this match.
+	a		All; make this change and all remaining ones without
+			further confirmation.
+	q		Quit; don't make any more changes.
+	l		Last; make this change and then quit.
+	CTRL-E		Scroll the text one line up.
+	CTRL-Y		Scroll the text one line down.
+
+
+The "from" part of the substitute command is actually a pattern.  The same
+kind as used for the search command.  For example, this command only
+substitutes "the" when it appears at the start of a line: >
+
+	:s/^the/these/
+
+If you are substituting with a "from" or "to" part that includes a slash, you
+need to put a backslash before it.  A simpler way is to use another character
+instead of the slash.  A plus, for example: >
+
+	:s+one/two+one or two+
+
+==============================================================================
+*10.3*	Command ranges
+
+The ":substitute" command, and many other : commands, can be applied to a
+selection of lines.  This is called a range.
+   The simple form of a range is {number},{number}.  For example: >
+
+	:1,5s/this/that/g
+
+Executes the substitute command on the lines 1 to 5.  Line 5 is included.
+The range is always placed before the command.
+
+A single number can be used to address one specific line: >
+
+	:54s/President/Fool/
+
+Some commands work on the whole file when you do not specify a range.  To make
+them work on the current line the "." address is used.  The ":write" command
+works like that.  Without a range, it writes the whole file.  To make it write
+only the current line into a file: >
+
+	:.write otherfile
+
+The first line always has number one.  How about the last line?  The "$"
+character is used for this.  For example, to substitute in the lines from the
+cursor to the end: >
+
+	:.,$s/yes/no/
+
+The "%" range that we used before, is actually a short way to say "1,$", from
+the first to the last line.
+
+
+USING A PATTERN IN A RANGE
+
+Suppose you are editing a chapter in a book, and want to replace all
+occurrences of "grey" with "gray".  But only in this chapter, not in the next
+one.  You know that only chapter boundaries have the word "Chapter" in the
+first column.  This command will work then: >
+
+	:?^Chapter?,/^Chapter/s=grey=gray=g
+
+You can see a search pattern is used twice.  The first "?^Chapter?" finds the
+line above the current position that matches this pattern.  Thus the ?pattern?
+range is used to search backwards.  Similarly, "/^Chapter/" is used to search
+forward for the start of the next chapter.
+   To avoid confusion with the slashes, the "=" character was used in the
+substitute command here.  A slash or another character would have worked as
+well.
+
+
+ADD AND SUBTRACT
+
+There is a slight error in the above command: If the title of the next chapter
+had included "grey" it would be replaced as well.  Maybe that's what you
+wanted, but what if you didn't?  Then you can specify an offset.
+   To search for a pattern and then use the line above it: >
+
+	/Chapter/-1
+
+You can use any number instead of the 1.  To address the second line below the
+match: >
+
+	/Chapter/+2
+
+The offsets can also be used with the other items in a range.  Look at this
+one: >
+
+	:.+3,$-5
+
+This specifies the range that starts three lines below the cursor and ends
+five lines before the last line in the file.
+
+
+USING MARKS
+
+Instead of figuring out the line numbers of certain positions, remembering them
+and typing them in a range, you can use marks.
+   Place the marks as mentioned in chapter 3.  For example, use "mt" to mark
+the top of an area and "mb" to mark the bottom.  Then you can use this range
+to specify the lines between the marks (including the lines with the marks): >
+
+	:'t,'b
+
+
+VISUAL MODE AND RANGES
+
+You can select text with Visual mode.  If you then press ":" to start a colon
+command, you will see this: >
+
+	:'<,'>
+
+Now you can type the command and it will be applied to the range of lines that
+was visually selected.
+
+	Note:
+	When using Visual mode to select part of a line, or using CTRL-V to
+	select a block of text, the colon commands will still apply to whole
+	lines.  This might change in a future version of Vim.
+
+The '< and '> are actually marks, placed at the start and end of the Visual
+selection.  The marks remain at their position until another Visual selection
+is made.  Thus you can use the "'<" command to jump to position where the
+Visual area started.  And you can mix the marks with other items: >
+
+	:'>,$
+
+This addresses the lines from the end of the Visual area to the end of the
+file.
+
+
+A NUMBER OF LINES
+
+When you know how many lines you want to change, you can type the number and
+then ":".  For example, when you type "5:", you will get: >
+
+	:.,.+4
+
+Now you can type the command you want to use.  It will use the range "."
+(current line) until ".+4" (four lines down).  Thus it spans five lines.
+
+==============================================================================
+*10.4*	The global command
+
+The ":global" command is one of the more powerful features of Vim.  It allows
+you to find a match for a pattern and execute a command there.  The general
+form is: >
+
+	:[range]global/{pattern}/{command}
+
+This is similar to the ":substitute" command.  But, instead of replacing the
+matched text with other text, the command {command} is executed.
+
+	Note:
+	The command executed for ":global" must be one that starts with a
+	colon.  Normal mode commands can not be used directly.  The |:normal|
+	command can do this for you.
+
+Suppose you want to change "foobar" to "barfoo", but only in C++ style
+comments.  These comments start with "//".  Use this command: >
+
+	:g+//+s/foobar/barfoo/g
+
+This starts with ":g".  That is short for ":global", just like ":s" is short
+for ":substitute".  Then the pattern, enclosed in plus characters.  Since the
+pattern we are looking for contains a slash, this uses the plus character to
+separate the pattern.  Next comes the substitute command that changes "foobar"
+into "barfoo".
+   The default range for the global command is the whole file.  Thus no range
+was specified in this example.  This is different from ":substitute", which
+works on one line without a range.
+   The command isn't perfect, since it also matches lines where "//" appears
+halfway a line, and the substitution will also take place before the "//".
+
+Just like with ":substitute", any pattern can be used.  When you learn more
+complicated patterns later, you can use them here.
+
+==============================================================================
+*10.5*	Visual block mode
+
+With CTRL-V you can start selection of a rectangular area of text.  There are
+a few commands that do something special with the text block.
+
+There is something special about using the "$" command in Visual block mode.
+When the last motion command used was "$", all lines in the Visual selection
+will extend until the end of the line, also when the line with the cursor is
+shorter.  This remains effective until you use a motion command that moves the
+cursor horizontally.  Thus using "j" keeps it, "h" stops it.
+
+
+INSERTING TEXT
+
+The command  "I{string}<Esc>" inserts the text {string} in each line, just
+left of the visual block.  You start by pressing CTRL-V to enter visual block
+mode.  Now you move the cursor to define your block.  Next you type I to enter
+Insert mode, followed by the text to insert.  As you type, the text appears on
+the first line only.
+   After you press <Esc> to end the insert, the text will magically be
+inserted in the rest of the lines contained in the visual selection.  Example:
+
+	include one ~
+	include two ~
+	include three ~
+	include four ~
+
+Move the cursor to the "o" of "one" and press CTRL-V.  Move it down with "3j"
+to "four".  You now have a block selection that spans four lines.  Now type: >
+
+	Imain.<Esc>
+
+The result:
+
+	include main.one ~
+	include main.two ~
+	include main.three ~
+	include main.four ~
+
+If the block spans short lines that do not extend into the block, the text is
+not inserted in that line.  For example, make a Visual block selection that
+includes the word "long" in the first and last line of this text, and thus has
+no text selected in the second line:
+
+	This is a long line ~
+	short ~
+	Any other long line ~
+
+		  ^^^^ selected block
+
+Now use the command "Ivery <Esc>".  The result is:
+
+	This is a very long line ~
+	short ~
+	Any other very long line ~
+
+In the short line no text was inserted.
+
+If the string you insert contains a newline, the "I" acts just like a Normal
+insert command and affects only the first line of the block.
+
+The "A" command works the same way, except that it appends after the right
+side of the block.  And it does insert text in a short line.  Thus you can
+make a choice whether you do or don't want to append text to a short line.
+   There is one special case for "A": Select a Visual block and then use "$"
+to make the block extend to the end of each line.  Using "A" now will append
+the text to the end of each line.
+   Using the same example from above, and then typing "$A XXX<Esc>, you get
+this result:
+
+	This is a long line XXX ~
+	short XXX ~
+	Any other long line XXX ~
+
+This really requires using the "$" command.  Vim remembers that it was used.
+Making the same selection by moving the cursor to the end of the longest line
+with other movement commands will not have the same result.
+
+
+CHANGING TEXT
+
+The Visual block "c" command deletes the block and then throws you into Insert
+mode to enable you to type in a string.  The string will be inserted in each
+line in the block.
+   Starting with the same selection of the "long" words as above, then typing
+"c_LONG_<Esc>", you get this:
+
+	This is a _LONG_ line ~
+	short ~
+	Any other _LONG_ line ~
+
+Just like with "I" the short line is not changed.  Also, you can't enter a
+newline in the new text.
+
+The "C" command deletes text from the left edge of the block to the end of
+line.  It then puts you in Insert mode so that you can type in a string,
+which is added to the end of each line.
+   Starting with the same text again, and typing "Cnew text<Esc>" you get:
+
+	This is a new text ~
+	short ~
+	Any other new text ~
+
+Notice that, even though only the "long" word was selected, the text after it
+is deleted as well.  Thus only the location of the left edge of the visual
+block really matters.
+   Again, short lines that do not reach into the block are excluded.
+
+Other commands that change the characters in the block:
+
+	~	swap case	(a -> A and A -> a)
+	U	make uppercase  (a -> A and A -> A)
+	u	make lowercase  (a -> a and A -> a)
+
+
+FILLING WITH A CHARACTER
+
+To fill the whole block with one character, use the "r" command.  Again,
+starting with the same example text from above, and then typing "rx":
+
+	This is a xxxx line ~
+	short ~
+	Any other xxxx line ~
+
+
+	Note:
+	If you want to include characters beyond the end of the line in the
+	block, check out the 'virtualedit' feature in chapter 25.
+
+
+SHIFTING
+
+The command ">" shifts the selected text to the right one shift amount,
+inserting whitespace.  The starting point for this shift is the left edge of
+the visual block.
+   With the same example again, ">" gives this result:
+
+	This is a	  long line ~
+	short ~
+	Any other	  long line ~
+
+The shift amount is specified with the 'shiftwidth' option.  To change it to
+use 4 spaces: >
+
+	:set shiftwidth=4
+
+The "<" command removes one shift amount of whitespace at the left
+edge of the block.  This command is limited by the amount of text that is
+there; so if there is less than a shift amount of whitespace available, it
+removes what it can.
+
+
+JOINING LINES
+
+The "J" command joins all selected lines together into one line.  Thus it
+removes the line breaks.  Actually, the line break, leading white space and
+trailing white space is replaced by one space.  Two spaces are used after a
+line ending (that can be changed with the 'joinspaces' option).
+   Let's use the example that we got so familiar with now.  The result of
+using the "J" command:
+
+	This is a long line short Any other long line ~
+
+The "J" command doesn't require a blockwise selection.  It works with "v" and
+"V" selection in exactly the same way.
+
+If you don't want the white space to be changed, use the "gJ" command.
+
+==============================================================================
+*10.6*	Reading and writing part of a file
+
+When you are writing an e-mail message, you may want to include another file.
+This can be done with the ":read {filename}" command.  The text of the file is
+put below the cursor line.
+   Starting with this text:
+
+	Hi John, ~
+	Here is the diff that fixes the bug: ~
+	Bye, Pierre. ~
+
+Move the cursor to the second line and type: >
+
+	:read patch
+
+The file named "patch" will be inserted, with this result:
+
+	Hi John, ~
+	Here is the diff that fixes the bug: ~
+	2c2 ~
+	<	for (i = 0; i <= length; ++i) ~
+	--- ~
+	>	for (i = 0; i < length; ++i) ~
+	Bye, Pierre. ~
+
+The ":read" command accepts a range.  The file will be put below the last line
+number of this range.  Thus ":$r patch" appends the file "patch" at the end of
+the file.
+   What if you want to read the file above the first line?  This can be done
+with the line number zero.  This line doesn't really exist, you will get an
+error message when using it with most commands.  But this command is allowed:
+>
+	:0read patch
+
+The file "patch" will be put above the first line of the file.
+
+
+WRITING A RANGE OF LINES
+
+To write a range of lines to a file, the ":write" command can be used.
+Without a range it writes the whole file.  With a range only the specified
+lines are written: >
+
+	:.,$write tempo
+
+This writes the lines from the cursor until the end of the file into the file
+"tempo".  If this file already exists you will get an error message.  Vim
+protects you from accidentally overwriting an existing file.  If you know what
+you are doing and want to overwrite the file, append !: >
+
+	:.,$write! tempo
+
+CAREFUL: The ! must follow the ":write" command immediately, without white
+space.  Otherwise it becomes a filter command, which is explained later in
+this chapter.
+
+
+APPENDING TO A FILE
+
+In the first section of this chapter was explained how to collect a number of
+lines into a register.  The same can be done to collect lines in a file.
+Write the first line with this command: >
+
+	:.write collection
+
+Now move the cursor to the second line you want to collect, and type this: >
+
+	:.write >>collection
+
+The ">>" tells Vim the "collection" file is not to be written as a new file,
+but the line must be appended at the end.   You can repeat this as many times
+as you like.
+
+==============================================================================
+*10.7*	Formatting text
+
+When you are typing plain text, it's nice if the length of each line is
+automatically trimmed to fit in the window.  To make this happen while
+inserting text, set the 'textwidth' option: >
+
+	:set textwidth=72
+
+You might remember that in the example vimrc file this command was used for
+every text file.  Thus if you are using that vimrc file, you were already
+using it.  To check the current value of 'textwidth': >
+
+	:set textwidth
+
+Now lines will be broken to take only up to 72 characters.  But when you
+insert text halfway a line, or when you delete a few words, the lines will get
+too long or too short.  Vim doesn't automatically reformat the text.
+   To tell Vim to format the current paragraph: >
+
+	gqap
+
+This starts with the "gq" command, which is an operator.  Following is "ap",
+the text object that stands for "a paragraph".  A paragraph is separated from
+the next paragraph by an empty line.
+
+	Note:
+	A blank line, which contains white space, does NOT separate
+	paragraphs.  This is hard to notice!
+
+Instead of "ap" you could use any motion or text object.  If your paragraphs
+are properly separated, you can use this command to format the whole file: >
+
+	gggqG
+
+"gg" takes you to the first line, "gq" is the format operator and "G" the
+motion that jumps to the last line.
+
+In case your paragraphs aren't clearly defined, you can format just the lines
+you manually select.  Move the cursor to the first line you want to format.
+Start with the command "gqj".  This formats the current line and the one below
+it.  If the first line was short, words from the next line will be appended.
+If it was too long, words will be moved to the next line.  The cursor moves to
+the second line.  Now you can use "." to repeat the command.  Keep doing this
+until you are at the end of the text you want to format.
+
+==============================================================================
+*10.8*	Changing case
+
+You have text with section headers in lowercase.  You want to make the word
+"section" all uppercase.  Do this with the "gU" operator.  Start with the
+cursor in the first column: >
+
+			     gUw
+<	section header	    ---->      SECTION header
+
+The "gu" operator does exactly the opposite: >
+
+			     guw
+<	SECTION header	    ---->      section header
+
+You can also use "g~" to swap case.  All these are operators, thus they work
+with any motion command, with text objects and in Visual mode.
+   To make an operator work on lines you double it.  The delete operator is
+"d", thus to delete a line you use "dd".  Similarly, "gugu" makes a whole line
+lowercase.  This can be shortened to "guu".  "gUgU" is shortened to "gUU" and
+"g~g~" to "g~~".  Example: >
+
+				g~~ 
+<	Some GIRLS have Fun    ---->   sOME girls HAVE fUN ~
+
+==============================================================================
+*10.9*	Using an external program
+
+Vim has a very powerful set of commands, it can do anything.  But there may
+still be something that an external command can do better or faster.
+   The command "!{motion}{program}" takes a block of text and filters it
+through an external program.  In other words, it runs the system command
+represented by {program}, giving it the block of text represented by {motion}
+as input.  The output of this command then replaces the selected block.
+   Because this summarizes badly if you are unfamiliar with UNIX filters, take
+a look at an example.  The sort command sorts a file.  If you execute the
+following command, the unsorted file input.txt will be sorted and written to
+output.txt.  (This works on both UNIX and Microsoft Windows.) >
+
+	sort <input.txt >output.txt
+
+Now do the same thing in Vim.  You want to sort lines 1 through 5 of a file.
+You start by putting the cursor on line 1.  Next you execute the following
+command: >
+
+	!5G
+
+The "!" tells Vim that you are performing a filter operation.  The Vim editor
+expects a motion command to follow, indicating which part of the file to
+filter.  The "5G" command tells Vim to go to line 5, so it now knows that it
+is to filter lines 1 (the current line) through 5.
+   In anticipation of the filtering, the cursor drops to the bottom of the
+screen and a ! prompt displays.  You can now type in the name of the filter
+program, in this case "sort".  Therefore, your full command is as follows: >
+
+	!5Gsort<Enter>
+
+The result is that the sort program is run on the first 5 lines.  The output
+of the program replaces these lines.
+
+	line 55			      line 11
+	line 33			      line 22
+	line 11		-->	      line 33
+	line 22			      line 44
+	line 44			      line 55
+	last line		      last line
+
+The "!!" command filters the current line through a filter.  In Unix the "date"
+command prints the current time and date.  "!!date<Enter>" replaces the current
+line with the output of "date".  This is useful to add a timestamp to a file.
+
+
+WHEN IT DOESN'T WORK
+
+Starting a shell, sending it text and capturing the output requires that Vim
+knows how the shell works exactly.  When you have problems with filtering,
+check the values of these options:
+
+	'shell'		specifies the program that Vim uses to execute
+			external programs.
+	'shellcmdflag'	argument to pass a command to the shell
+	'shellquote'	quote to be used around the command
+	'shellxquote'	quote to be used around the command and redirection
+	'shelltype'	kind of shell (only for the Amiga)
+	'shellslash'	use forward slashes in the command (only for
+			MS-Windows and alikes)
+	'shellredir'	string used to write the command output into a file
+
+On Unix this is hardly ever a problem, because there are two kinds of shells:
+"sh" like and "csh" like.  Vim checks the 'shell' option and sets related
+options automatically, depending on whether it sees "csh" somewhere in
+'shell'.
+   On MS-Windows, however, there are many different shells and you might have
+to tune the options to make filtering work.  Check the help for the options
+for more information.
+
+
+READING COMMAND OUTPUT
+
+To read the contents of the current directory into the file, use this:
+
+on Unix: >
+	:read !ls
+on MS-Windows: >
+	:read !dir
+
+The output of the "ls" or "dir" command is captured and inserted in the text,
+below the cursor.  This is similar to reading a file, except that the "!" is
+used to tell Vim that a command follows.
+   The command may have arguments.  And a range can be used to tell where Vim
+should put the lines: >
+
+	:0read !date -u
+
+This inserts the current time and date in UTC format at the top of the file.
+(Well, if you have a date command that accepts the "-u" argument.)  Note the
+difference with using "!!date": that replaced a line, while ":read !date" will
+insert a line.
+
+
+WRITING TEXT TO A COMMAND
+
+The Unix command "wc" counts words.  To count the words in the current file: >
+
+	:write !wc
+
+This is the same write command as before, but instead of a file name the "!"
+character is used and the name of an external command.  The written text will
+be passed to the specified command as its standard input.  The output could
+look like this:
+
+       4      47     249 ~
+
+The "wc" command isn't verbose.  This means you have 4 lines, 47 words and 249
+characters.
+
+Watch out for this mistake: >
+
+	:write! wc
+
+This will write the file "wc" in the current directory, with force.  White
+space is important here!
+
+
+REDRAWING THE SCREEN
+
+If the external command produced an error message, the display may have been
+messed up.  Vim is very efficient and only redraws those parts of the screen
+that it knows need redrawing.  But it can't know about what another program
+has written.  To tell Vim to redraw the screen: >
+
+	CTRL-L
+
+==============================================================================
+
+Next chapter: |usr_11.txt|  Recovering from a crash
+
+Copyright: see |manual-copyright|  vim:tw=78:ts=8:ft=help:norl:
--- /dev/null
+++ b/lib/vimfiles/doc/usr_11.txt
@@ -1,0 +1,287 @@
+*usr_11.txt*	For Vim version 7.1.  Last change: 2006 Apr 24
+
+		     VIM USER MANUAL - by Bram Moolenaar
+
+			   Recovering from a crash
+
+
+Did your computer crash?  And you just spent hours editing?  Don't panic!  Vim
+keeps enough information on harddisk to be able to restore most of your work.
+This chapter shows you how to get your work back and explains how the swap
+file is used.
+
+|11.1|	Basic recovery
+|11.2|	Where is the swap file?
+|11.3|	Crashed or not?
+|11.4|	Further reading
+
+     Next chapter: |usr_12.txt|  Clever tricks
+ Previous chapter: |usr_10.txt|  Making big changes
+Table of contents: |usr_toc.txt|
+
+==============================================================================
+*11.1*	Basic recovery
+
+In most cases recovering a file is quite simple, assuming you know which file
+you were editing (and the harddisk is still working).  Start Vim on the file,
+with the "-r" argument added: >
+
+	vim -r help.txt
+
+Vim will read the swap file (used to store text you were editing) and may read
+bits and pieces of the original file.  If all is well, you will see these
+messages (with different file names, of course):
+
+	Using swap file ".help.txt.swp" ~
+	Original file "~/vim/runtime/doc/help.txt" ~
+	Recovery completed. You should check if everything is OK. ~
+	(You might want to write out this file under another name ~
+	and run diff with the original file to check for changes) ~
+	Delete the .swp file afterwards. ~
+
+To be on the safe side, write this file under another name: >
+
+	:write help.txt.recovered
+
+Compare the file with the original file to check if you ended up with what you
+expected.  Vimdiff is very useful for this |08.7|.  Watch out for the original
+file to contain a more recent version (you saved the file just before the
+computer crashed).  And check that no lines are missing (something went wrong
+that Vim could not recover).
+   If Vim produces warning messages when recovering, read them carefully.
+This is rare though.
+
+It's normal that the last few changes can not be recovered.  Vim flushes the
+changes to disk when you don't type for about four seconds, or after typing
+about two hundred characters.  This is set with the 'updatetime' and
+'updatecount' options.  Thus when Vim didn't get a chance to save itself when
+the system went down, the changes after the last flush will be lost.
+
+If you were editing without a file name, give an empty string as argument: >
+
+	vim -r ""
+
+You must be in the right directory, otherwise Vim can't find the swap file.
+
+==============================================================================
+*11.2*	Where is the swap file?
+
+Vim can store the swap file in several places.  Normally it is in the same
+directory as the original file.  To find it, change to the directory of the
+file, and use: >
+
+	vim -r
+
+Vim will list the swap files that it can find.  It will also look in other
+directories where the swap file for files in the current directory may be
+located.  It will not find swap files in any other directories though, it
+doesn't search the directory tree.
+   The output could look like this:
+
+	Swap files found: ~
+	   In current directory: ~
+	1.    .main.c.swp ~
+		  owned by: mool   dated: Tue May 29 21:00:25 2001 ~
+		 file name: ~mool/vim/vim6/src/main.c ~
+		  modified: YES ~
+		 user name: mool   host name: masaka.moolenaar.net ~
+		process ID: 12525 ~
+	   In directory ~/tmp: ~
+	      -- none -- ~
+	   In directory /var/tmp: ~
+	      -- none -- ~
+	   In directory /tmp: ~
+	      -- none -- ~
+
+If there are several swap files that look like they may be the one you want to
+use, a list is given of these swap files and you are requested to enter the
+number of the one you want to use.  Carefully look at the dates to decide
+which one you want to use.
+   In case you don't know which one to use, just try them one by one and check
+the resulting files if they are what you expected.
+
+
+USING A SPECIFIC SWAP FILE
+
+If you know which swap file needs to be used, you can recover by giving the
+swap file name.  Vim will then finds out the name of the original file from
+the swap file.
+
+Example: >
+	vim -r .help.txt.swo
+
+This is also handy when the swap file is in another directory than expected.
+If this still does not work, see what file names Vim reports and rename the
+files accordingly.  Check the 'directory' option to see where Vim may have
+put the swap file.
+
+	Note:
+	Vim tries to find the swap file by searching the directories in the
+	'dir' option, looking for files that match "filename.sw?".  If
+	wildcard expansion doesn't work (e.g., when the 'shell' option is
+	invalid), Vim does a desperate try to find the file "filename.swp".
+	If that fails too, you will have to give the name of the swapfile
+	itself to be able to recover the file.
+
+==============================================================================
+*11.3*	Crashed or not?					*ATTENTION* *E325*
+
+Vim tries to protect you from doing stupid things.  Suppose you innocently
+start editing a file, expecting the contents of the file to show up.  Instead,
+Vim produces a very long message:
+
+		E325: ATTENTION ~
+	Found a swap file by the name ".main.c.swp" ~
+		  owned by: mool   dated: Tue May 29 21:09:28 2001 ~
+		 file name: ~mool/vim/vim6/src/main.c ~
+		  modified: no ~
+		 user name: mool   host name: masaka.moolenaar.net ~
+		process ID: 12559 (still running) ~
+	While opening file "main.c" ~
+		     dated: Tue May 29 19:46:12 2001 ~
+ ~
+	(1) Another program may be editing the same file. ~
+	    If this is the case, be careful not to end up with two ~
+	    different instances of the same file when making changes. ~
+	    Quit, or continue with caution. ~
+ ~
+	(2) An edit session for this file crashed. ~
+	    If this is the case, use ":recover" or "vim -r main.c" ~
+	    to recover the changes (see ":help recovery"). ~
+	    If you did this already, delete the swap file ".main.c.swp" ~
+	    to avoid this message. ~
+
+You get this message, because, when starting to edit a file, Vim checks if a
+swap file already exists for that file.  If there is one, there must be
+something wrong.  It may be one of these two situations.
+
+1. Another edit session is active on this file.  Look in the message for the
+   line with "process ID".  It might look like this:
+
+		process ID: 12559 (still running) ~
+
+   The text "(still running)" indicates that the process editing this file
+   runs on the same computer.  When working on a non-Unix system you will not
+   get this extra hint.  When editing a file over a network, you may not see
+   the hint, because the process might be running on another computer.  In
+   those two cases you must find out what the situation is yourself.
+      If there is another Vim editing the same file, continuing to edit will
+   result in two versions of the same file.  The one that is written last will
+   overwrite the other one, resulting in loss of changes.  You better quit
+   this Vim.
+
+2. The swap file might be the result from a previous crash of Vim or the
+   computer.  Check the dates mentioned in the message.  If the date of the
+   swap file is newer than the file you were editing, and this line appears:
+
+		modified: YES ~
+
+   Then you very likely have a crashed edit session that is worth recovering.
+      If the date of the file is newer than the date of the swap file, then
+   either it was changed after the crash (perhaps you recovered it earlier,
+   but didn't delete the swap file?), or else the file was saved before the
+   crash but after the last write of the swap file (then you're lucky: you
+   don't even need that old swap file).  Vim will warn you for this with this
+   extra line:
+
+      NEWER than swap file! ~
+
+
+UNREADABLE SWAP FILE
+
+Sometimes the line
+
+	[cannot be read] ~
+
+will appear under the name of the swap file.  This can be good or bad,
+depending on circumstances.
+
+It is good if a previous editing session crashed without having made any
+changes to the file.  Then a directory listing of the swap file will show
+that it has zero bytes.  You may delete it and proceed.
+
+It is slightly bad if you don't have read permission for the swap file.  You
+may want to view the file read-only, or quit.  On multi-user systems, if you
+yourself did the last changes under a different login name, a logout
+followed by a login under that other name might cure the "read error".  Or
+else you might want to find out who last edited (or is editing) the file and
+have a talk with them.
+
+It is very bad if it means there is a physical read error on the disk
+containing the swap file.  Fortunately, this almost never happens.
+You may want to view the file read-only at first (if you can), to see the
+extent of the changes that were "forgotten".  If you are the one in charge of
+that file, be prepared to redo your last changes.
+
+
+WHAT TO DO?
+
+If dialogs are supported you will be asked to select one of five choices:
+
+  Swap file ".main.c.swp" already exists! ~
+  [O]pen Read-Only, (E)dit anyway, (R)ecover, (Q)uit, (A)bort, (D)elete it: ~
+
+O  Open the file readonly.  Use this when you just want to view the file and
+   don't need to recover it.  You might want to use this when you know someone
+   else is editing the file, but you just want to look in it and not make
+   changes.
+
+E  Edit the file anyway.  Use this with caution!  If the file is being edited
+   in another Vim, you might end up with two versions of the file.  Vim will
+   try to warn you when this happens, but better be safe then sorry.
+
+R  Recover the file from the swap file.  Use this if you know that the swap
+   file contains changes that you want to recover.
+
+Q  Quit.  This avoids starting to edit the file.  Use this if there is another
+   Vim editing the same file.
+      When you just started Vim, this will exit Vim.  When starting Vim with
+   files in several windows, Vim quits only if there is a swap file for the
+   first one.  When using an edit command, the file will not be loaded and you
+   are taken back to the previously edited file.
+
+A  Abort.  Like Quit, but also abort further commands.  This is useful when
+   loading a script that edits several files, such as a session with multiple
+   windows.
+
+D  Delete the swap file.  Use this when you are sure you no longer need it.
+   For example, when it doesn't contain changes, or when the file itself is
+   newer than the swap file.
+      On Unix this choice is only offered when the process that created the
+   swap file does not appear to be running.
+
+If you do not get the dialog (you are running a version of Vim that does not
+support it), you will have to do it manually.  To recover the file, use this
+command: >
+
+	:recover
+
+
+Vim cannot always detect that a swap file already exists for a file.  This is
+the case when the other edit session puts the swap files in another directory
+or when the path name for the file is different when editing it on different
+machines.  Therefore, don't rely on Vim always warning you.
+
+If you really don't want to see this message, you can add the 'A' flag to the
+'shortmess' option.  But it's very unusual that you need this.
+
+==============================================================================
+*11.4*	Further reading
+
+|swap-file|	An explanation about where the swap file will be created and
+		what its name is.
+|:preserve|	Manually flushing the swap file to disk.
+|:swapname|	See the name of the swap file for the current file.
+'updatecount'	Number of key strokes after which the swap file is flushed to
+		disk.
+'updatetime'	Timeout after which the swap file is flushed to disk.
+'swapsync'	Whether the disk is synced when the swap file is flushed.
+'directory'	List of directory names where to store the swap file.
+'maxmem'	Limit for memory usage before writing text to the swap file.
+'maxmemtot'	Same, but for all files in total.
+
+==============================================================================
+
+Next chapter: |usr_12.txt|  Clever tricks
+
+Copyright: see |manual-copyright|  vim:tw=78:ts=8:ft=help:norl:
--- /dev/null
+++ b/lib/vimfiles/doc/usr_12.txt
@@ -1,0 +1,358 @@
+*usr_12.txt*	For Vim version 7.1.  Last change: 2007 May 11
+
+		     VIM USER MANUAL - by Bram Moolenaar
+
+				Clever tricks
+
+
+By combining several commands you can make Vim do nearly everything.  In this
+chapter a number of useful combinations will be presented.  This uses the
+commands introduced in the previous chapters and a few more.
+
+|12.1|	Replace a word
+|12.2|	Change "Last, First" to "First Last"
+|12.3|	Sort a list
+|12.4|	Reverse line order
+|12.5|	Count words
+|12.6|	Find a man page
+|12.7|	Trim blanks
+|12.8|	Find where a word is used
+
+     Next chapter: |usr_20.txt|  Typing command-line commands quickly
+ Previous chapter: |usr_11.txt|  Recovering from a crash
+Table of contents: |usr_toc.txt|
+
+==============================================================================
+*12.1*	Replace a word
+
+The substitute command can be used to replace all occurrences of a word with
+another word: >
+
+	:%s/four/4/g
+
+The "%" range means to replace in all lines.  The "g" flag at the end causes
+all words in a line to be replaced.
+   This will not do the right thing if your file also contains "thirtyfour".
+It would be replaced with "thirty4".  To avoid this, use the "\<" item to
+match the start of a word: >
+
+	:%s/\<four/4/g
+
+Obviously, this still goes wrong on "fourteen".  Use "\>" to match the end of
+a word: >
+
+	:%s/\<four\>/4/g
+
+If you are programming, you might want to replace "four" in comments, but not
+in the code.  Since this is difficult to specify, add the "c" flag to have the
+substitute command prompt you for each replacement: >
+
+
+	:%s/\<four\>/4/gc
+
+
+REPLACING IN SEVERAL FILES
+
+Suppose you want to replace a word in more than one file.  You could edit each
+file and type the command manually.  It's a lot faster to use record and
+playback.
+   Let's assume you have a directory with C++ files, all ending in ".cpp".
+There is a function called "GetResp" that you want to rename to "GetAnswer".
+
+	vim *.cpp		Start Vim, defining the argument list to
+				contain all the C++ files.  You are now in the
+				first file.
+	qq			Start recording into the q register
+	:%s/\<GetResp\>/GetAnswer/g
+				Do the replacements in the first file.
+	:wnext			Write this file and move to the next one.
+	q			Stop recording.
+	@q			Execute the q register.  This will replay the
+				substitution and ":wnext".  You can verify
+				that this doesn't produce an error message.
+	999@q			Execute the q register on the remaining files.
+
+At the last file you will get an error message, because ":wnext" cannot move
+to the next file.  This stops the execution, and everything is done.
+
+	Note:
+	When playing back a recorded sequence, an error stops the execution.
+	Therefore, make sure you don't get an error message when recording.
+
+There is one catch: If one of the .cpp files does not contain the word
+"GetResp", you will get an error and replacing will stop.  To avoid this, add
+the "e" flag to the substitute command: >
+
+	:%s/\<GetResp\>/GetAnswer/ge
+
+The "e" flag tells ":substitute" that not finding a match is not an error.
+
+==============================================================================
+*12.2*	Change "Last, First" to "First Last"
+
+You have a list of names in this form:
+
+	Doe, John ~
+	Smith, Peter ~
+
+You want to change that to:
+
+	John Doe ~
+	Peter Smith ~
+
+This can be done with just one command: >
+
+	:%s/\([^,]*\), \(.*\)/\2 \1/
+
+Let's break this down in parts.  Obviously it starts with a substitute
+command.  The "%" is the line range, which stands for the whole file.  Thus
+the substitution is done in every line in the file.
+   The arguments for the substitute command are "/from/to/".  The slashes
+separate the "from" pattern and the "to" string.  This is what the "from"
+pattern contains:
+							\([^,]*\), \(.*\) ~
+
+	The first part between \( \) matches "Last"	\(     \)
+	    match anything but a comma			  [^,]
+	    any number of times				      *
+	matches ", " literally					 ,
+	The second part between \( \) matches "First"		   \(  \)
+	    any character					     .
+	    any number of times					      *
+
+In the "to" part we have "\2" and "\1".  These are called backreferences.
+They refer to the text matched by the "\( \)" parts in the pattern.  "\2"
+refers to the text matched by the second "\( \)", which is the "First" name.
+"\1" refers to the first "\( \)", which is the "Last" name.
+   You can use up to nine backreferences in the "to" part of a substitute
+command.  "\0" stands for the whole matched pattern.  There are a few more
+special items in a substitute command, see |sub-replace-special|.
+
+==============================================================================
+*12.3*	Sort a list
+
+In a Makefile you often have a list of files.  For example:
+
+	OBJS = \ ~
+		version.o \ ~
+		pch.o \ ~
+		getopt.o \ ~
+		util.o \ ~
+		getopt1.o \ ~
+		inp.o \ ~
+		patch.o \ ~
+		backup.o ~
+
+To sort this list, filter the text through the external sort command: >
+
+	/^OBJS
+	j
+	:.,/^$/-1!sort
+
+This goes to the first line, where "OBJS" is the first thing in the line.
+Then it goes one line down and filters the lines until the next empty line.
+You could also select the lines in Visual mode and then use "!sort".  That's
+easier to type, but more work when there are many lines.
+   The result is this:
+
+	OBJS = \ ~
+		backup.o ~
+		getopt.o \ ~
+		getopt1.o \ ~
+		inp.o \ ~
+		patch.o \ ~
+		pch.o \ ~
+		util.o \ ~
+		version.o \ ~
+
+
+Notice that a backslash at the end of each line is used to indicate the line
+continues.  After sorting, this is wrong!  The "backup.o" line that was at
+the end didn't have a backslash.  Now that it sorts to another place, it
+must have a backslash.
+   The simplest solution is to add the backslash with "A \<Esc>".  You can
+keep the backslash in the last line, if you make sure an empty line comes
+after it.  That way you don't have this problem again.
+
+==============================================================================
+*12.4*	Reverse line order
+
+The |:global| command can be combined with the |:move| command to move all the
+lines before the first line, resulting in a reversed file.  The command is: >
+
+	:global/^/m 0
+
+Abbreviated: >
+
+	:g/^/m 0
+
+The "^" regular expression matches the beginning of the line (even if the line
+is blank).  The |:move| command moves the matching line to after the mythical
+zeroth line, so the current matching line becomes the first line of the file.
+As the |:global| command is not confused by the changing line numbering,
+|:global| proceeds to match all remaining lines of the file and puts each as
+the first.
+
+This also works on a range of lines.  First move to above the first line and
+mark it with "mt".  Then move the cursor to the last line in the range and
+type: >
+
+	:'t+1,.g/^/m 't
+
+==============================================================================
+*12.5*	Count words
+
+Sometimes you have to write a text with a maximum number of words.  Vim can
+count the words for you.
+   When the whole file is what you want to count the words in, use this
+command: >
+
+	g CTRL-G
+
+Do not type a space after the g, this is just used here to make the command
+easy to read.
+   The output looks like this:
+
+	Col 1 of 0; Line 141 of 157; Word 748 of 774; Byte 4489 of 4976 ~
+
+You can see on which word you are (748), and the total number of words in the
+file (774).
+
+When the text is only part of a file, you could move to the start of the text,
+type "g CTRL-G", move to the end of the text, type "g CTRL-G" again, and then
+use your brain to compute the difference in the word position.  That's a good
+exercise, but there is an easier way.  With Visual mode, select the text you
+want to count words in.  Then type g CTRL-G.  The result:
+
+	Selected 5 of 293 Lines; 70 of 1884 Words; 359 of 10928 Bytes ~
+
+For other ways to count words, lines and other items, see |count-items|.
+
+==============================================================================
+*12.6*	Find a man page					*find-manpage*
+
+While editing a shell script or C program, you are using a command or function
+that you want to find the man page for (this is on Unix).  Let's first use a
+simple way: Move the cursor to the word you want to find help on and press >
+
+	K
+
+Vim will run the external "man" program on the word.  If the man page is
+found, it is displayed.  This uses the normal pager to scroll through the text
+(mostly the "more" program).  When you get to the end pressing <Enter> will
+get you back into Vim.
+
+A disadvantage is that you can't see the man page and the text you are working
+on at the same time.  There is a trick to make the man page appear in a Vim
+window.  First, load the man filetype plugin: >
+
+	:runtime! ftplugin/man.vim
+
+Put this command in your vimrc file if you intend to do this often.  Now you
+can use the ":Man" command to open a window on a man page: >
+
+	:Man csh
+
+You can scroll around and the text is highlighted.  This allows you to find
+the help you were looking for.  Use CTRL-W w to jump to the window with the
+text you were working on.
+   To find a man page in a specific section, put the section number first.
+For example, to look in section 3 for "echo": >
+
+	:Man 3 echo
+
+To jump to another man page, which is in the text with the typical form
+"word(1)", press CTRL-] on it.  Further ":Man" commands will use the same
+window.
+
+To display a man page for the word under the cursor, use this: >
+
+	\K
+
+(If you redefined the <Leader>, use it instead of the backslash).
+For example, you want to know the return value of "strstr()" while editing
+this line:
+
+	if ( strstr (input, "aap") == ) ~
+
+Move the cursor to somewhere on "strstr" and type "\K".  A window will open
+to display the man page for strstr().
+
+==============================================================================
+*12.7*	Trim blanks
+
+Some people find spaces and tabs at the end of a line useless, wasteful, and
+ugly.  To remove whitespace at the end of every line, execute the following
+command: >
+
+	:%s/\s\+$//
+
+The line range "%" is used, thus this works on the whole file.  The pattern
+that the ":substitute" command matches with is "\s\+$".  This finds white
+space characters (\s), 1 or more of them (\+), before the end-of-line ($).
+Later will be explained how you write patterns like this |usr_27.txt|.
+   The "to" part of the substitute command is empty: "//".  Thus it replaces
+with nothing, effectively deleting the matched white space.
+
+Another wasteful use of spaces is placing them before a tab.  Often these can
+be deleted without changing the amount of white space.  But not always!
+Therefore, you can best do this manually.  Use this search command: >
+
+	/ 	
+
+You cannot see it, but there is a space before a tab in this command.  Thus
+it's "/<Space><Tab>".   Now use "x" to delete the space and check that the
+amount of white space doesn't change.  You might have to insert a tab if it
+does change.  Type "n" to find the next match.  Repeat this until no more
+matches can be found.
+
+==============================================================================
+*12.8*	Find where a word is used
+
+If you are a UNIX user, you can use a combination of Vim and the grep command
+to edit all the files that contain a given word.  This is extremely useful if
+you are working on a program and want to view or edit all the files that
+contain a specific variable.
+   For example, suppose you want to edit all the C program files that contain
+the word "frame_counter".  To do this you use the command: >
+
+	vim `grep -l frame_counter *.c`
+
+Let's look at this command in detail.  The grep command searches through a set
+of files for a given word.  Because the -l argument is specified, the command
+will only list the files containing the word and not print the matching lines.
+The word it is searching for is "frame_counter".  Actually, this can be any
+regular expression.  (Note: What grep uses for regular expressions is not
+exactly the same as what Vim uses.)
+   The entire command is enclosed in backticks (`).  This tells the UNIX shell
+to run this command and pretend that the results were typed on the command
+line.  So what happens is that the grep command is run and produces a list of
+files, these files are put on the Vim command line.  This results in Vim
+editing the file list that is the output of grep.  You can then use commands
+like ":next" and ":first" to browse through the files.
+
+
+FINDING EACH LINE
+
+The above command only finds the files in which the word is found.  You still
+have to find the word within the files.
+   Vim has a built-in command that you can use to search a set of files for a
+given string.  If you want to find all occurrences of "error_string" in all C
+program files, for example, enter the following command: >
+
+	:grep error_string *.c
+
+This causes Vim to search for the string "error_string" in all the specified
+files (*.c).  The editor will now open the first file where a match is found
+and position the cursor on the first matching line.  To go to the next
+matching line (no matter in what file it is), use the ":cnext" command.  To go
+to the previous match, use the ":cprev" command.  Use ":clist" to see all the
+matches and where they are.
+   The ":grep" command uses the external commands grep (on Unix) or findstr
+(on Windows).  You can change this by setting the option 'grepprg'.
+
+==============================================================================
+
+Next chapter: |usr_20.txt|  Typing command-line commands quickly
+
+Copyright: see |manual-copyright|  vim:tw=78:ts=8:ft=help:norl:
--- /dev/null
+++ b/lib/vimfiles/doc/usr_20.txt
@@ -1,0 +1,384 @@
+*usr_20.txt*	For Vim version 7.1.  Last change: 2006 Apr 24
+
+		     VIM USER MANUAL - by Bram Moolenaar
+
+		     Typing command-line commands quickly
+
+
+Vim has a few generic features that makes it easier to enter commands.  Colon
+commands can be abbreviated, edited and repeated.  Completion is available for
+nearly everything.
+
+|20.1|	Command line editing
+|20.2|	Command line abbreviations
+|20.3|	Command line completion
+|20.4|	Command line history
+|20.5|	Command line window
+
+     Next chapter: |usr_21.txt|  Go away and come back
+ Previous chapter: |usr_12.txt|  Clever tricks
+Table of contents: |usr_toc.txt|
+
+==============================================================================
+*20.1*	Command line editing
+
+When you use a colon (:) command or search for a string with / or ?, Vim puts
+the cursor on the bottom of the screen.  There you type the command or search
+pattern.  This is called the Command line.  Also when it's used for entering a
+search command.
+
+The most obvious way to edit the command you type is by pressing the <BS> key.
+This erases the character before the cursor.  To erase another character,
+typed earlier, first move the cursor with the cursor keys.
+   For example, you have typed this: >
+
+	:s/col/pig/
+
+Before you hit <Enter>, you notice that "col" should be "cow".  To correct
+this, you type <Left> five times.  The cursor is now just after "col".  Type
+<BS> and "w" to correct: >
+
+	:s/cow/pig/
+
+Now you can press <Enter> directly.  You don't have to move the cursor to the
+end of the line before executing the command.
+
+The most often used keys to move around in the command line:
+
+	<Left>			one character left
+	<Right>			one character right
+	<S-Left> or <C-Left>	one word left
+	<S-Right> or <C-Right>	one word right
+	CTRL-B or <Home>	to begin of command line
+	CTRL-E or <End>		to end of command line
+
+	Note:
+	<S-Left> (cursor left key with Shift key pressed) and <C-Left> (cursor
+	left key with Control pressed) will not work on all keyboards.  Same
+	for the other Shift and Control combinations.
+
+You can also use the mouse to move the cursor.
+
+
+DELETING
+
+As mentioned, <BS> deletes the character before the cursor.  To delete a whole
+word use CTRL-W.
+
+	/the fine pig ~
+
+		     CTRL-W
+
+	/the fine ~
+
+CTRL-U removes all text, thus allows you to start all over again.
+
+
+OVERSTRIKE
+
+The <Insert> key toggles between inserting characters and replacing the
+existing ones.  Start with this text:
+
+	/the fine pig ~
+
+Move the cursor to the start of "fine" with <S-Left> twice (or <Left> eight
+times, if <S-Left> doesn't work).  Now press <Insert> to switch to overstrike
+and type "great":
+
+	/the greatpig ~
+
+Oops, we lost the space.  Now, don't use <BS>, because it would delete the
+"t" (this is different from Replace mode).  Instead, press <Insert> to switch
+from overstrike to inserting, and type the space:
+
+	/the great pig ~
+
+
+CANCELLING
+
+You thought of executing a : or / command, but changed your mind.  To get rid
+of what you already typed, without executing it, press CTRL-C or <Esc>.
+
+	Note:
+	<Esc> is the universal "get out" key.  Unfortunately, in the good old
+	Vi pressing <Esc> in a command line executed the command!  Since that
+	might be considered to be a bug, Vim uses <Esc> to cancel the command.
+	But with the 'cpoptions' option it can be made Vi compatible.  And
+	when using a mapping (which might be written for Vi) <Esc> also works
+	Vi compatible.  Therefore, using CTRL-C is a method that always works.
+
+If you are at the start of the command line, pressing <BS> will cancel the
+command.  It's like deleting the ":" or "/" that the line starts with.
+
+==============================================================================
+*20.2*	Command line abbreviations
+
+Some of the ":" commands are really long.  We already mentioned that
+":substitute" can be abbreviated to ":s".  This is a generic mechanism, all
+":" commands can be abbreviated.
+
+How short can a command get?  There are 26 letters, and many more commands.
+For example, ":set" also starts with ":s", but ":s" doesn't start a ":set"
+command.  Instead ":set" can be abbreviated to ":se".
+   When the shorter form of a command could be used for two commands, it
+stands for only one of them.  There is no logic behind which one, you have to
+learn them.  In the help files the shortest form that works is mentioned.  For
+example: >
+
+	:s[ubstitute]
+
+This means that the shortest form of ":substitute" is ":s".  The following
+characters are optional.  Thus ":su" and ":sub" also work.
+
+In the user manual we will either use the full name of command, or a short
+version that is still readable.  For example, ":function" can be abbreviated
+to ":fu".  But since most people don't understand what that stands for, we
+will use ":fun".  (Vim doesn't have a ":funny" command, otherwise ":fun" would
+be confusing too.)
+
+It is recommended that in Vim scripts you write the full command name.  That
+makes it easier to read back when you make later changes.  Except for some
+often used commands like ":w" (":write") and ":r" (":read").
+   A particularly confusing one is ":end", which could stand for ":endif",
+":endwhile" or ":endfunction".  Therefore, always use the full name.
+
+
+SHORT OPTION NAMES
+
+In the user manual the long version of the option names is used.  Many options
+also have a short name.  Unlike ":" commands, there is only one short name
+that works.  For example, the short name of 'autoindent' is 'ai'.  Thus these
+two commands do the same thing: >
+
+	:set autoindent
+	:set ai
+
+You can find the full list of long and short names here: |option-list|.
+
+==============================================================================
+*20.3*	Command line completion
+
+This is one of those Vim features that, by itself, is a reason to switch from
+Vi to Vim.  Once you have used this, you can't do without.
+
+Suppose you have a directory that contains these files:
+
+	info.txt
+	intro.txt
+	bodyofthepaper.txt
+
+To edit the last one, you use the command: >
+
+	:edit bodyofthepaper.txt
+
+It's easy to type this wrong.  A much quicker way is: >
+
+	:edit b<Tab>
+
+Which will result in the same command.  What happened?  The <Tab> key does
+completion of the word before the cursor.  In this case "b".  Vim looks in the
+directory and finds only one file that starts with a "b".  That must be the
+one you are looking for, thus Vim completes the file name for you.
+
+Now type: >
+
+	:edit i<Tab>
+
+Vim will beep, and give you: >
+
+	:edit info.txt
+
+The beep means that Vim has found more than one match.  It then uses the first
+match it found (alphabetically).  If you press <Tab> again, you get: >
+
+	:edit intro.txt
+
+Thus, if the first <Tab> doesn't give you the file you were looking for, press
+it again.  If there are more matches, you will see them all, one at a time.
+   If you press <Tab> on the last matching entry, you will go back to what you
+first typed: >
+
+	:edit i
+
+Then it starts all over again.  Thus Vim cycles through the list of matches.
+Use CTRL-P to go through the list in the other direction:
+
+	      <------------------- <Tab> -------------------------+
+								  |
+		  <Tab> -->		       <Tab> -->
+	:edit i		      :edit info.txt		   :edit intro.txt
+		  <-- CTRL-P		       <-- CTRL-P
+	   |
+	   +---------------------- CTRL-P ------------------------>
+
+
+CONTEXT
+
+When you type ":set i" instead of ":edit i" and press <Tab> you get: >
+
+	:set icon
+
+Hey, why didn't you get ":set info.txt"?  That's because Vim has context
+sensitive completion.  The kind of words Vim will look for depends on the
+command before it.  Vim knows that you cannot use a file name just after a
+":set" command, but you can use an option name.
+   Again, if you repeat typing the <Tab>, Vim will cycle through all matches.
+There are quite a few, it's better to type more characters first: >
+
+	:set isk<Tab>
+
+Gives: >
+
+	:set iskeyword
+
+Now type "=" and press <Tab>: >
+
+	:set iskeyword=@,48-57,_,192-255
+
+What happens here is that Vim inserts the old value of the option.  Now you
+can edit it.
+   What is completed with <Tab> is what Vim expects in that place.  Just try
+it out to see how it works.  In some situations you will not get what you
+want.  That's either because Vim doesn't know what you want, or because
+completion was not implemented for that situation.  In that case you will get
+a <Tab> inserted (displayed as ^I).
+
+
+LIST MATCHES
+
+When there are many matches, you would like to see an overview.  Do this by
+pressing CTRL-D.  For example, pressing CTRL-D after: >
+
+	:set is
+
+results in: >
+
+	:set is
+	incsearch  isfname    isident    iskeyword  isprint
+	:set is
+
+Vim lists the matches and then comes back with the text you typed.  You can
+now check the list for the item you wanted.  If it isn't there, you can use
+<BS> to correct the word.  If there are many matches, type a few more
+characters before pressing <Tab> to complete the rest.
+   If you have watched carefully, you will have noticed that "incsearch"
+doesn't start with "is".  In this case "is" stands for the short name of
+"incsearch".  (Many options have a short and a long name.)  Vim is clever
+enough to know that you might have wanted to expand the short name of the
+option into the long name.
+
+
+THERE IS MORE
+
+The CTRL-L command completes the word to the longest unambiguous string.  If
+you type ":edit i" and there are files "info.txt" and "info_backup.txt" you
+will get ":edit info".
+
+The 'wildmode' option can be used to change the way completion works.
+The 'wildmenu' option can be used to get a menu-like list of matches.
+Use the 'suffixes' option to specify files that are less important and appear
+at the end of the list of files.
+The 'wildignore' option specifies files that are not listed at all.
+
+More about all of this here: |cmdline-completion|
+
+==============================================================================
+*20.4*	Command line history
+
+In chapter 3 we briefly mentioned the history.  The basics are that you can
+use the <Up> key to recall an older command line.  <Down> then takes you back
+to newer commands.
+
+There are actually four histories.  The ones we will mention here are for ":"
+commands and for "/" and "?" search commands.  The "/" and "?" commands share
+the same history, because they are both search commands.  The two other
+histories are for expressions and input lines for the input() function.
+|cmdline-history|
+
+Suppose you have done a ":set" command, typed ten more colon commands and then
+want to repeat that ":set" command again.  You could press ":" and then ten
+times <Up>.  There is a quicker way: >
+
+	:se<Up>
+
+Vim will now go back to the previous command that started with "se".  You have
+a good chance that this is the ":set" command you were looking for.  At least
+you should not have to press <Up> very often (unless ":set" commands is all
+you have done).
+
+The <Up> key will use the text typed so far and compare it with the lines in
+the history.  Only matching lines will be used.
+   If you do not find the line you were looking for, use <Down> to go back to
+what you typed and correct that.  Or use CTRL-U to start all over again.
+
+To see all the lines in the history: >
+
+	:history
+
+That's the history of ":" commands.  The search history is displayed with this
+command: >
+
+	:history /
+
+CTRL-P will work like <Up>, except that it doesn't matter what you already
+typed.  Similarly for CTRL-N and <Down>.  CTRL-P stands for previous, CTRL-N
+for next.
+
+==============================================================================
+*20.5*	Command line window
+
+Typing the text in the command line works different from typing text in Insert
+mode.  It doesn't allow many commands to change the text.  For most commands
+that's OK, but sometimes you have to type a complicated command.  That's where
+the command line window is useful.
+
+Open the command line window with this command: >
+
+	q:
+
+Vim now opens a (small) window at the bottom.  It contains the command line
+history, and an empty line at the end:
+
+	+-------------------------------------+
+	|other window			      |
+	|~				      |
+	|file.txt=============================|
+	|:e c				      |
+	|:e config.h.in			      |
+	|:set path=.,/usr/include,,	      |
+	|:set iskeyword=@,48-57,_,192-255     |
+	|:set is			      |
+	|:q				      |
+	|:				      |
+	|command-line=========================|
+	|				      |
+	+-------------------------------------+
+
+You are now in Normal mode.  You can use the "hjkl" keys to move around.  For
+example, move up with "5k" to the ":e config.h.in" line.  Type "$h" to go to
+the "i" of "in" and type "cwout".  Now you have changed the line to:
+
+	:e config.h.out ~
+
+Now press <Enter> and this command will be executed.  The command line window
+will close.
+   The <Enter> command will execute the line under the cursor.  It doesn't
+matter whether Vim is in Insert mode or in Normal mode.
+   Changes in the command line window are lost.  They do not result in the
+history to be changed.  Except that the command you execute will be added to
+the end of the history, like with all executed commands.
+
+The command line window is very useful when you want to have overview of the
+history, lookup a similar command, change it a bit and execute it.  A search
+command can be used to find something.
+   In the previous example the "?config" search command could have been used
+to find the previous command that contains "config".  It's a bit strange,
+because you are using a command line to search in the command line window.
+While typing that search command you can't open another command line window,
+there can be only one.
+
+==============================================================================
+
+Next chapter: |usr_21.txt|  Go away and come back
+
+Copyright: see |manual-copyright|  vim:tw=78:ts=8:ft=help:norl:
--- /dev/null
+++ b/lib/vimfiles/doc/usr_21.txt
@@ -1,0 +1,457 @@
+*usr_21.txt*	For Vim version 7.1.  Last change: 2007 May 01
+
+		     VIM USER MANUAL - by Bram Moolenaar
+
+			   Go away and come back
+
+
+This chapter goes into mixing the use of other programs with Vim.  Either by
+executing program from inside Vim or by leaving Vim and coming back later.
+Furthermore, this is about the ways to remember the state of Vim and restore
+it later.
+
+|21.1|	Suspend and resume
+|21.2|	Executing shell commands
+|21.3|	Remembering information; viminfo
+|21.4|	Sessions
+|21.5|	Views
+|21.6|	Modelines
+
+     Next chapter: |usr_22.txt|  Finding the file to edit
+ Previous chapter: |usr_20.txt|  Typing command-line commands quickly
+Table of contents: |usr_toc.txt|
+
+==============================================================================
+*21.1*	Suspend and resume
+
+Like most Unix programs Vim can be suspended by pressing CTRL-Z.  This stops
+Vim and takes you back to the shell it was started in.  You can then do any
+other commands until you are bored with them.  Then bring back Vim with the
+"fg" command. >
+
+	CTRL-Z
+	{any sequence of shell commands}
+	fg
+
+You are right back where you left Vim, nothing has changed.
+   In case pressing CTRL-Z doesn't work, you can also use ":suspend".
+Don't forget to bring Vim back to the foreground, you would lose any changes
+that you made!
+
+Only Unix has support for this.  On other systems Vim will start a shell for
+you.  This also has the functionality of being able to execute shell commands.
+But it's a new shell, not the one that you started Vim from.
+   When you are running the GUI you can't go back to the shell where Vim was
+started.  CTRL-Z will minimize the Vim window instead.
+
+==============================================================================
+*21.2*	Executing shell commands
+
+To execute a single shell command from Vim use ":!{command}".  For example, to
+see a directory listing: >
+
+	:!ls
+	:!dir
+
+The first one is for Unix, the second one for MS-Windows.
+   Vim will execute the program.  When it ends you will get a prompt to hit
+<Enter>.  This allows you to have a look at the output from the command before
+returning to the text you were editing.
+   The "!" is also used in other places where a program is run.  Let's take
+a look at an overview:
+
+	:!{program}		execute {program}
+	:r !{program}		execute {program} and read its output
+	:w !{program}		execute {program} and send text to its input
+	:[range]!{program}	filter text through {program}
+
+Notice that the presence of a range before "!{program}" makes a big
+difference.  Without it executes the program normally, with the range a number
+of text lines is filtered through the program.
+
+Executing a whole row of programs this way is possible.  But a shell is much
+better at it.  You can start a new shell this way: >
+
+	:shell
+
+This is similar to using CTRL-Z to suspend Vim.  The difference is that a new
+shell is started.
+
+When using the GUI the shell will be using the Vim window for its input and
+output.  Since Vim is not a terminal emulator, this will not work perfectly.
+If you have trouble, try toggling the 'guipty' option.  If this still doesn't
+work well enough, start a new terminal to run the shell in.  For example with:
+>
+	:!xterm&
+
+==============================================================================
+*21.3*	Remembering information; viminfo
+
+After editing for a while you will have text in registers, marks in various
+files, a command line history filled with carefully crafted commands.  When
+you exit Vim all of this is lost.  But you can get it back!
+
+The viminfo file is designed to store status information:
+
+	Command-line and Search pattern history
+	Text in registers
+	Marks for various files
+	The buffer list
+	Global variables
+
+Each time you exit Vim it will store this information in a file, the viminfo
+file.  When Vim starts again, the viminfo file is read and the information
+restored.
+
+The 'viminfo' option is set by default to restore a limited number of items.
+You might want to set it to remember more information.  This is done through
+the following command: >
+
+	:set viminfo=string
+
+The string specifies what to save.  The syntax of this string is an option
+character followed by an argument.  The option/argument pairs are separated by
+commas.
+   Take a look at how you can build up your own viminfo string.  First, the '
+option is used to specify how many files for which you save marks (a-z).  Pick
+a nice even number for this option (1000, for instance).  Your command now
+looks like this: >
+
+	:set viminfo='1000
+
+The f option controls whether global marks (A-Z and 0-9) are stored.  If this
+option is 0, none are stored.  If it is 1 or you do not specify an f option,
+the marks are stored.  You want this feature, so now you have this: >
+
+	:set viminfo='1000,f1
+
+The < option controls how many lines are saved for each of the registers.  By
+default, all the lines are saved.  If 0, nothing is saved.  To avoid adding
+thousands of lines to your viminfo file (which might never get used and makes
+starting Vim slower) you use a maximum of 500 lines: >
+
+	:set viminfo='1000,f1,<500
+<
+Other options you might want to use:
+	:	number of lines to save from the command line history
+	@	number of lines to save from the input line history
+	/	number of lines to save from the search history
+	r	removable media, for which no marks will be stored (can be
+		used several times)
+	!	global variables that start with an uppercase letter and
+		don't contain lowercase letters
+	h	disable 'hlsearch' highlighting when starting
+	%	the buffer list (only restored when starting Vim without file
+		arguments)
+	c	convert the text using 'encoding'
+	n	name used for the viminfo file (must be the last option)
+
+See the 'viminfo' option and |viminfo-file| for more information.
+
+When you run Vim multiple times, the last one exiting will store its
+information.  This may cause information that previously exiting Vims stored
+to be lost.  Each item can be remembered only once.
+
+
+GETTING BACK TO WHERE YOU WERE
+
+You are halfway editing a file and it's time to leave for holidays.  You exit
+Vim and go enjoy yourselves, forgetting all about your work.  After a couple
+of weeks you start Vim, and type:
+>
+	'0
+
+And you are right back where you left Vim.  So you can get on with your work.
+   Vim creates a mark each time you exit Vim.  The last one is '0.  The
+position that '0 pointed to is made '1.  And '1 is made to '2, and so forth.
+Mark '9 is lost.
+   The |:marks| command is useful to find out where '0 to '9 will take you.
+
+
+MOVE INFO FROM ONE VIM TO ANOTHER
+
+You can use the ":wviminfo" and ":rviminfo" commands to save and restore the
+information while still running Vim.  This is useful for exchanging register
+contents between two instances of Vim, for example.  In the first Vim do: >
+
+	:wviminfo! ~/tmp/viminfo
+
+And in the second Vim do: >
+
+	:rviminfo! ~/tmp/viminfo
+
+Obviously, the "w" stands for "write" and the "r" for "read".
+   The ! character is used by ":wviminfo" to forcefully overwrite an existing
+file.  When it is omitted, and the file exists, the information is merged into
+the file.
+   The ! character used for ":rviminfo" means that all the information is
+used, this may overwrite existing information.  Without the ! only information
+that wasn't set is used.
+   These commands can also be used to store info and use it again later.  You
+could make a directory full of viminfo files, each containing info for a
+different purpose.
+
+==============================================================================
+*21.4*	Sessions
+
+Suppose you are editing along, and it is the end of the day.  You want to quit
+work and pick up where you left off the next day.  You can do this by saving
+your editing session and restoring it the next day.
+   A Vim session contains all the information about what you are editing.
+This includes things such as the file list, window layout, global variables,
+options and other information.  (Exactly what is remembered is controlled by
+the 'sessionoptions' option, described below.)
+   The following command creates a session file: >
+
+	:mksession vimbook.vim
+
+Later if you want to restore this session, you can use this command: >
+
+	:source vimbook.vim
+
+If you want to start Vim and restore a specific session, you can use the
+following command: >
+
+	vim -S vimbook.vim
+
+This tells Vim to read a specific file on startup.  The 'S' stands for
+session (actually, you can source any Vim script with -S, thus it might as
+well stand for "source").
+
+The windows that were open are restored, with the same position and size as
+before.  Mappings and option values are like before.
+   What exactly is restored depends on the 'sessionoptions' option.  The
+default value is "blank,buffers,curdir,folds,help,options,winsize".
+
+	blank		keep empty windows
+	buffers		all buffers, not only the ones in a window
+	curdir		the current directory
+	folds		folds, also manually created ones
+	help		the help window
+	options		all options and mappings
+	winsize		window sizes
+
+Change this to your liking.  To also restore the size of the Vim window, for
+example, use: >
+
+	:set sessionoptions+=resize
+
+
+SESSION HERE, SESSION THERE
+
+The obvious way to use sessions is when working on different projects.
+Suppose you store you session files in the directory "~/.vim".  You are
+currently working on the "secret" project and have to switch to the "boring"
+project: >
+
+	:wall
+	:mksession! ~/.vim/secret.vim
+	:source ~/.vim/boring.vim
+
+This first uses ":wall" to write all modified files.  Then the current session
+is saved, using ":mksession!".  This overwrites the previous session.  The
+next time you load the secret session you can continue where you were at this
+point.  And finally you load the new "boring" session.
+
+If you open help windows, split and close various window, and generally mess
+up the window layout, you can go back to the last saved session: >
+
+	:source ~/.vim/boring.vim
+
+Thus you have complete control over whether you want to continue next time
+where you are now, by saving the current setup in a session, or keep the
+session file as a starting point.
+   Another way of using sessions is to create a window layout that you like to
+use, and save this in a session.  Then you can go back to this layout whenever
+you want.
+   For example, this is a nice layout to use:
+
+	+----------------------------------------+
+	|		   VIM - main help file  |
+	|					 |
+	|Move around:  Use the cursor keys, or "h|
+	|help.txt================================|
+	|explorer   |				 |
+	|dir	    |~				 |
+	|dir	    |~				 |
+	|file	    |~				 |
+	|file	    |~				 |
+	|file	    |~				 |
+	|file	    |~				 |
+	|~/=========|[No File]===================|
+	|					 |
+	+----------------------------------------+
+
+This has a help window at the top, so that you can read this text.  The narrow
+vertical window on the left contains a file explorer.  This is a Vim plugin
+that lists the contents of a directory.  You can select files to edit there.
+More about this in the next chapter.
+   Create this from a just started Vim with: >
+
+	:help
+	CTRL-W w
+	:vertical split ~/
+
+You can resize the windows a bit to your liking.  Then save the session with:
+>
+	:mksession ~/.vim/mine.vim
+
+Now you can start Vim with this layout: >
+
+	vim -S ~/.vim/mine.vim
+
+Hint: To open a file you see listed in the explorer window in the empty
+window, move the cursor to the filename and press "O".  Double clicking with
+the mouse will also do this.
+
+
+UNIX AND MS-WINDOWS
+
+Some people have to do work on MS-Windows systems one day and on Unix another
+day.  If you are one of them, consider adding "slash" and "unix" to
+'sessionoptions'.  The session files will then be written in a format that can
+be used on both systems.  This is the command to put in your vimrc file: >
+
+	:set sessionoptions+=unix,slash
+
+Vim will use the Unix format then, because the MS-Windows Vim can read and
+write Unix files, but Unix Vim can't read MS-Windows format session files.
+Similarly, MS-Windows Vim understands file names with / to separate names, but
+Unix Vim doesn't understand \.
+
+
+SESSIONS AND VIMINFO
+
+Sessions store many things, but not the position of marks, contents of
+registers and the command line history.  You need to use the viminfo feature
+for these things.
+   In most situations you will want to use sessions separately from viminfo.
+This can be used to switch to another session, but keep the command line
+history.  And yank text into registers in one session, and paste it back in
+another session.
+   You might prefer to keep the info with the session.  You will have to do
+this yourself then.  Example: >
+
+	:mksession! ~/.vim/secret.vim
+	:wviminfo! ~/.vim/secret.viminfo
+
+And to restore this again: >
+
+	:source ~/.vim/secret.vim
+	:rviminfo! ~/.vim/secret.viminfo
+
+==============================================================================
+*21.5*	Views
+
+A session stores the looks of the whole of Vim.  When you want to store the
+properties for one window only, use a view.
+   The use of a view is for when you want to edit a file in a specific way.
+For example, you have line numbers enabled with the 'number' option and
+defined a few folds.  Just like with sessions, you can remember this view on
+the file and restore it later.  Actually, when you store a session, it stores
+the view of each window.
+   There are two basic ways to use views.  The first is to let Vim pick a name
+for the view file.  You can restore the view when you later edit the same
+file.  To store the view for the current window: >
+
+	:mkview
+
+Vim will decide where to store the view.  When you later edit the same file
+you get the view back with this command: >
+
+	:loadview
+
+That's easy, isn't it?
+   Now you want to view the file without the 'number' option on, or with all
+folds open, you can set the options to make the window look that way.  Then
+store this view with: >
+
+	:mkview 1
+
+Obviously, you can get this back with: >
+
+	:loadview 1
+
+Now you can switch between the two views on the file by using ":loadview" with
+and without the "1" argument.
+   You can store up to ten views for the same file this way, one unnumbered
+and nine numbered 1 to 9.
+
+
+A VIEW WITH A NAME
+
+The second basic way to use views is by storing the view in a file with a name
+you chose.  This view can be loaded while editing another file.  Vim will then
+switch to editing the file specified in the view.  Thus you can use this to
+quickly switch to editing another file, with all its options set as you saved
+them.
+   For example, to save the view of the current file: >
+
+	:mkview ~/.vim/main.vim
+
+You can restore it with: >
+
+	:source ~/.vim/main.vim
+
+==============================================================================
+*21.6*	Modelines
+
+When editing a specific file, you might set options specifically for that
+file.  Typing these commands each time is boring.  Using a session or view for
+editing a file doesn't work when sharing the file between several people.
+   The solution for this situation is adding a modeline to the file.  This is
+a line of text that tells Vim the values of options, to be used in this file
+only.
+   A typical example is a C program where you make indents by a multiple of 4
+spaces.  This requires setting the 'shiftwidth' option to 4.  This modeline
+will do that:
+
+	/* vim:set shiftwidth=4: */ ~
+
+Put this line as one of the first or last five lines in the file.  When
+editing the file, you will notice that 'shiftwidth' will have been set to
+four.  When editing another file, it's set back to the default value of eight.
+   For some files the modeline fits well in the header, thus it can be put at
+the top of the file.  For text files and other files where the modeline gets
+in the way of the normal contents, put it at the end of the file.
+
+The 'modelines' option specifies how many lines at the start and end of the
+file are inspected for containing a modeline.  To inspect ten lines: >
+
+	:set modelines=10
+
+The 'modeline' option can be used to switch this off.  Do this when you are
+working as root on Unix or Administrator on MS-Windows, or when you don't
+trust the files you are editing: >
+
+	:set nomodeline
+
+Use this format for the modeline:
+
+	any-text vim:set {option}={value} ... : any-text ~
+
+The "any-text" indicates that you can put any text before and after the part
+that Vim will use.  This allows making it look like a comment, like what was
+done above with /* and */.
+   The " vim:" part is what makes Vim recognize this line.  There must be
+white space before "vim", or "vim" must be at the start of the line.  Thus
+using something like "gvim:" will not work.
+   The part between the colons is a ":set" command.  It works the same way as
+typing the ":set" command, except that you need to insert a backslash before a
+colon (otherwise it would be seen as the end of the modeline).
+
+Another example:
+
+	// vim:set textwidth=72 dir=c\:\tmp:  use c:\tmp here ~
+
+There is an extra backslash before the first colon, so that it's included in
+the ":set" command.  The text after the second colon is ignored, thus a remark
+can be placed there.
+
+For more details see |modeline|.
+
+==============================================================================
+
+Next chapter: |usr_22.txt|  Finding the file to edit
+
+Copyright: see |manual-copyright|  vim:tw=78:ts=8:ft=help:norl:
--- /dev/null
+++ b/lib/vimfiles/doc/usr_22.txt
@@ -1,0 +1,364 @@
+*usr_22.txt*	For Vim version 7.1.  Last change: 2006 Apr 24
+
+		     VIM USER MANUAL - by Bram Moolenaar
+
+			   Finding the file to edit
+
+
+Files can be found everywhere.  So how do you find them?  Vim offers various
+ways to browse the directory tree.  There are commands to jump to a file that
+is mentioned in another.  And Vim remembers which files have been edited
+before.
+
+|22.1|	The file explorer
+|22.2|	The current directory
+|22.3|	Finding a file
+|22.4|	The buffer list
+
+     Next chapter: |usr_23.txt|  Editing other files
+ Previous chapter: |usr_21.txt|  Go away and come back
+Table of contents: |usr_toc.txt|
+
+==============================================================================
+*22.1*	The file explorer
+
+Vim has a plugin that makes it possible to edit a directory.  Try this: >
+
+	:edit .
+
+Through the magic of autocommands and Vim scripts, the window will be filled
+with the contents of the directory.  It looks like this:
+
+	" Press ? for keyboard shortcuts ~
+	" Sorted by name (.bak,~,.o,.h,.info,.swp,.obj,.orig,.rej at end of list) ~
+	"= /home/mool/vim/vim6/runtime/doc/ ~
+	../ ~
+	check/ ~
+	Makefile ~
+	autocmd.txt ~
+	change.txt ~
+	eval.txt~ ~
+	filetype.txt~ ~
+	help.txt.info ~
+
+You can see these items:
+1.  A comment about using ? to get help for the functionality of the file
+    explorer.
+2.  The second line mentions how the items in the directory are listed.  They
+    can be sorted in several ways.
+3.  The third line is the name of the current directory.
+4.  The "../" directory item.  This is the parent directory.
+5.  The directory names.
+6.  The ordinary file names.  As mentioned in the second line, some are not
+    here but "at the end of the list".
+7.  The less ordinary file names.  You are expected to use these less often,
+    therefore they have been moved to the end.
+
+If you have syntax highlighting enabled, the different parts are highlighted
+to make it easier to spot them.
+
+You can use Normal mode Vim commands to move around in the text.  For example,
+move to a file and press <Enter>.  Now you are editing that file.  To go back
+to the explorer use ":edit ." again.  CTRL-O also works.
+   Try using <Enter> while the cursor is on a directory name.  The result is
+that the explorer moves into that directory and displays the items found
+there.  Pressing <Enter> on the first directory "../" moves you one level
+higher.  Pressing "-" does the same thing, without the need to move to the
+"../" item first.
+
+You can press ? to get short help on the things you can do in the explorer.
+This is what you get:
+
+	" <enter> : open file or directory ~
+	" o : open new window for file/directory ~
+	" O : open file in previously visited window ~
+	" p : preview the file ~
+	" i : toggle size/date listing ~
+	" s : select sort field    r : reverse sort ~
+	" - : go up one level      c : cd to this dir ~
+	" R : rename file	   D : delete file ~
+	" :help file-explorer for detailed help ~
+
+The first few commands are for selecting a file to display.  Depending on what
+command you use, the file appears somewhere:
+
+	<Enter>		Uses the current window.
+	o		Opens a new window.
+	O		Uses the previously visited window.
+	p		Uses the preview window, and moves the cursor back
+			into the explorer window. |preview-window|
+
+The following commands are used to display other information:
+
+	i		Display the size and date for the file.  Using i again
+			will hide the information.
+	s		Use the field the cursor is in to sort on.  First
+			display the size and date with i.  Then Move the
+			cursor to the size of any file and press s.  The files
+			will now be sorted on size.  Press s while the cursor
+			is on a date and the items will be sorted on date.
+	r		reverse the sorting order (either size or date)
+
+There are a few extra commands:
+
+	c		Change the current directory to the displayed
+			directory.  You can then type an ":edit" command for
+			one of the files without prepending the path.
+	R		Rename the file under the cursor.  You will be
+			prompted for the new name.
+	D		Delete the file under the cursor.  You will get a
+			prompt to confirm this.
+
+==============================================================================
+*22.2*	The current directory
+
+Just like the shell, Vim has the concept of a current directory.  Suppose you
+are in your home directory and want to edit several files in a directory
+"VeryLongFileName".  You could do: >
+
+	:edit VeryLongFileName/file1.txt
+	:edit VeryLongFileName/file2.txt
+	:edit VeryLongFileName/file3.txt
+
+To avoid much of the typing, do this: >
+
+	:cd VeryLongFileName
+	:edit file1.txt
+	:edit file2.txt
+	:edit file3.txt
+
+The ":cd" command changes the current directory.  You can see what the current
+directory is with the ":pwd" command: >
+
+	:pwd
+	/home/Bram/VeryLongFileName
+
+Vim remembers the last directory that you used.  Use "cd -" to go back to it.
+Example: >
+
+	:pwd
+	/home/Bram/VeryLongFileName
+	:cd /etc
+	:pwd
+	/etc
+	:cd -
+	:pwd
+	/home/Bram/VeryLongFileName
+	:cd -
+	:pwd
+	/etc
+
+
+WINDOW LOCAL DIRECTORY
+
+When you split a window, both windows use the same current directory.  When
+you want to edit a number of files somewhere else in the new window, you can
+make it use a different directory, without changing the current directory in
+the other window.  This is called a local directory. >
+
+	:pwd
+	/home/Bram/VeryLongFileName
+	:split
+	:lcd /etc
+	:pwd
+	/etc
+	CTRL-W w
+	:pwd
+	/home/Bram/VeryLongFileName
+
+So long as no ":lcd" command has been used, all windows share the same current
+directory.  Doing a ":cd" command in one window will also change the current
+directory of the other window.
+   For a window where ":lcd" has been used a different current directory is
+remembered.  Using ":cd" or ":lcd" in other windows will not change it.
+   When using a ":cd" command in a window that uses a different current
+directory, it will go back to using the shared directory.
+
+==============================================================================
+*22.3*	Finding a file
+
+You are editing a C program that contains this line:
+
+	#include "inits.h" ~
+
+You want to see what is in that "inits.h" file.  Move the cursor on the name
+of the file and type: >
+
+	gf
+
+Vim will find the file and edit it.
+   What if the file is not in the current directory?  Vim will use the 'path'
+option to find the file.  This option is a list of directory names where to
+look for your file.
+   Suppose you have your include files located in "c:/prog/include".  This
+command will add it to the 'path' option: >
+
+	:set path+=c:/prog/include
+
+This directory is an absolute path.  No matter where you are, it will be the
+same place.  What if you have located files in a subdirectory, below where the
+file is?  Then you can specify a relative path name.  This starts with a dot:
+>
+	:set path+=./proto
+
+This tells Vim to look in the directory "proto", below the directory where the
+file in which you use "gf" is.  Thus using "gf" on "inits.h" will make Vim
+look for "proto/inits.h", starting in the directory of the file.
+   Without the "./", thus "proto", Vim would look in the "proto" directory
+below the current directory.  And the current directory might not be where the
+file that you are editing is located.
+
+The 'path' option allows specifying the directories where to search for files
+in many more ways.  See the help on the 'path' option.
+   The 'isfname' option is used to decide which characters are included in the
+file name, and which ones are not (e.g., the " character in the example
+above).
+
+When you know the file name, but it's not to be found in the file, you can
+type it: >
+
+	:find inits.h
+
+Vim will then use the 'path' option to try and locate the file.  This is the
+same as the ":edit" command, except for the use of 'path'.
+
+To open the found file in a new window use CTRL-W f instead of "gf", or use
+":sfind" instead of ":find".
+
+
+A nice way to directly start Vim to edit a file somewhere in the 'path': >
+
+	vim "+find stdio.h"
+
+This finds the file "stdio.h" in your value of 'path'.  The quotes are
+necessary to have one argument |-+c|.
+
+==============================================================================
+*22.4*	The buffer list
+
+The Vim editor uses the term buffer to describe a file being edited.
+Actually, a buffer is a copy of the file that you edit.  When you finish
+changing the buffer, you write the contents of the buffer to the file.
+Buffers not only contain file contents, but also all the marks, settings, and
+other stuff that goes with it.
+
+
+HIDDEN BUFFERS
+
+Suppose you are editing the file one.txt and need to edit the file two.txt.
+You could simply use ":edit two.txt", but since you made changes to one.txt
+that won't work.  You also don't want to write one.txt yet.  Vim has a
+solution for you: >
+
+	:hide edit two.txt
+
+The buffer "one.txt" disappears from the screen, but Vim still knows that you
+are editing this buffer, so it keeps the modified text.  This is called a
+hidden buffer: The buffer contains text, but you can't see it.
+   The ":hide" command argument is another command.  It makes that command
+behave like the 'hidden' option was set.  You could also set this option
+yourself.  The effect is that when any buffer is abandoned, it becomes hidden.
+   Be careful!  When you have hidden buffers with changes, don't exit Vim
+without making sure you have saved all the buffers.
+
+
+INACTIVE BUFFERS
+
+   When a buffer has been used once, Vim remembers some information about it.
+When it is not displayed in a window and it is not hidden, it is still in the
+buffer list.  This is called an inactive buffer.  Overview:
+
+   Active		Appears in a window, text loaded.
+   Hidden		Not in a window, text loaded.
+   Inactive		Not in a window, no text loaded.
+
+The inactive buffers are remembered, because Vim keeps information about them,
+like marks.  And remembering the file name is useful too, so that you can see
+which files you have edited.  And edit them again.
+
+
+LISTING BUFFERS
+
+View the buffer list with this command: >
+
+	:buffers
+
+A command which does the same, is not so obvious to list buffers, but is much
+shorter to type: >
+
+	:ls
+
+The output could look like this:
+
+  1 #h	"help.txt"			line 62 ~
+  2 %a+	"usr_21.txt"			line 1 ~
+  3	"usr_toc.txt"			line 1 ~
+
+The first column contains the buffer number.  You can use this to edit the
+buffer without having to type the name, see below.
+   After the buffer number come the flags.  Then the name of the file
+and the line number where the cursor was the last time.
+   The flags that can appear are these (from left to right):
+
+	u	Buffer is unlisted |unlisted-buffer|.
+	 %	Current buffer.
+	 #	Alternate buffer.
+	  a	Buffer is loaded and displayed.
+	  h	Buffer is loaded but hidden.
+	   =	Buffer is read-only.
+	   -	Buffer is not modifiable, the 'modifiable' option is off.
+	    +	Buffer has been modified.
+
+
+EDITING A BUFFER
+
+You can edit a buffer by its number.  That avoids having to type the file
+name: >
+
+	:buffer 2
+
+But the only way to know the number is by looking in the buffer list.  You can
+use the name, or part of it, instead: >
+
+	:buffer help
+
+Vim will find a best match for the name you type.  If there is only one
+buffer that matches the name, it will be used.  In this case "help.txt".
+   To open a buffer in a new window: >
+
+	:sbuffer 3
+
+This works with a name as well.
+
+
+USING THE BUFFER LIST
+
+You can move around in the buffer list with these commands:
+
+	:bnext		go to next buffer
+	:bprevious	go to previous buffer
+	:bfirst		go to the first buffer
+	:blast		go to the last buffer
+
+To remove a buffer from the list, use this command: >
+
+	:bdelete 3
+
+Again, this also works with a name.
+   If you delete a buffer that was active (visible in a window), that window
+will be closed.  If you delete the current buffer, the current window will be
+closed.  If it was the last window, Vim will find another buffer to edit.  You
+can't be editing nothing!
+
+	Note:
+	Even after removing the buffer with ":bdelete" Vim still remembers it.
+	It's actually made "unlisted", it no longer appears in the list from
+	":buffers".  The ":buffers!" command will list unlisted buffers (yes,
+	Vim can do the impossible).  To really make Vim forget about a buffer,
+	use ":bwipe".  Also see the 'buflisted' option.
+
+==============================================================================
+
+Next chapter: |usr_23.txt|  Editing other files
+
+Copyright: see |manual-copyright|  vim:tw=78:ts=8:ft=help:norl:
--- /dev/null
+++ b/lib/vimfiles/doc/usr_23.txt
@@ -1,0 +1,343 @@
+*usr_23.txt*	For Vim version 7.1.  Last change: 2006 Apr 24
+
+		     VIM USER MANUAL - by Bram Moolenaar
+
+			     Editing other files
+
+
+This chapter is about editing files that are not ordinary files.  With Vim you
+can edit files that are compressed or encrypted.  Some files need to be
+accessed over the internet.  With some restrictions, binary files can be
+edited as well.
+
+|23.1|	DOS, Mac and Unix files
+|23.2|	Files on the internet
+|23.3|	Encryption
+|23.4|	Binary files
+|23.5|	Compressed files
+
+     Next chapter: |usr_24.txt|  Inserting quickly
+ Previous chapter: |usr_22.txt|  Finding the file to edit
+Table of contents: |usr_toc.txt|
+
+==============================================================================
+*23.1*	DOS, Mac and Unix files
+
+Back in the early days, the old Teletype machines used two characters to
+start a new line.  One to move the carriage back to the first position
+(carriage return, <CR>), another to move the paper up (line feed, <LF>).
+   When computers came out, storage was expensive.  Some people decided that
+they did not need two characters for end-of-line.  The UNIX people decided
+they could use <Line Feed> only for end-of-line.  The Apple people
+standardized on <CR>.  The MS-DOS (and Microsoft Windows) folks decided to
+keep the old <CR><LF>.
+   This means that if you try to move a file from one system to another, you
+have line-break problems.  The Vim editor automatically recognizes the
+different file formats and handles things properly behind your back.
+   The option 'fileformats' contains the various formats that will be tried
+when a new file is edited.  The following command, for example, tells Vim to
+try UNIX format first and MS-DOS format second: >
+
+	:set fileformats=unix,dos
+
+You will notice the format in the message you get when editing a file.  You
+don't see anything if you edit a native file format.  Thus editing a Unix file
+on Unix won't result in a remark.  But when you edit a dos file, Vim will
+notify you of this:
+
+	"/tmp/test" [dos] 3L, 71C ~
+
+For a Mac file you would see "[mac]".
+   The detected file format is stored in the 'fileformat' option.  To see
+which format you have, execute the following command: >
+
+	:set fileformat?
+
+The three names that Vim uses are:
+
+	unix		<LF>
+	dos		<CR><LF>
+	mac		<CR>
+
+
+USING THE MAC FORMAT
+
+On Unix, <LF> is used to break a line.  It's not unusual to have a <CR>
+character halfway a line.  Incidentally, this happens quite often in Vi (and
+Vim) scripts.
+   On the Macintosh, where <CR> is the line break character, it's possible to
+have a <LF> character halfway a line.
+   The result is that it's not possible to be 100% sure whether a file
+containing both <CR> and <LF> characters is a Mac or a Unix file.  Therefore,
+Vim assumes that on Unix you probably won't edit a Mac file, and doesn't check
+for this type of file.  To check for this format anyway, add "mac" to
+'fileformats': >
+
+	:set fileformats+=mac
+
+Then Vim will take a guess at the file format.  Watch out for situations where
+Vim guesses wrong.
+
+
+OVERRULING THE FORMAT
+
+If you use the good old Vi and try to edit an MS-DOS format file, you will
+find that each line ends with a ^M character.  (^M is <CR>).  The automatic
+detection avoids this.  Suppose you do want to edit the file that way?  Then
+you need to overrule the format: >
+
+	:edit ++ff=unix file.txt
+
+The "++" string is an item that tells Vim that an option name follows, which
+overrules the default for this single command.  "++ff" is used for
+'fileformat'.  You could also use "++ff=mac" or "++ff=dos".
+   This doesn't work for any option, only "++ff" and "++enc" are currently
+implemented.  The full names "++fileformat" and "++encoding" also work.
+
+
+CONVERSION
+
+You can use the 'fileformat' option to convert from one file format to
+another.  Suppose, for example, that you have an MS-DOS file named README.TXT
+that you want to convert to UNIX format.  Start by editing the MS-DOS format
+file: >
+	vim README.TXT
+
+Vim will recognize this as a dos format file.  Now change the file format to
+UNIX: >
+
+	:set fileformat=unix
+	:write
+
+The file is written in Unix format.
+
+==============================================================================
+*23.2*	Files on the internet
+
+Someone sends you an e-mail message, which refers to a file by its URL.  For
+example:
+
+	You can find the information here: ~
+		ftp://ftp.vim.org/pub/vim/README ~
+
+You could start a program to download the file, save it on your local disk and
+then start Vim to edit it.
+   There is a much simpler way.  Move the cursor to any character of the URL.
+Then use this command: >
+
+	gf
+
+With a bit of luck, Vim will figure out which program to use for downloading
+the file, download it and edit the copy.  To open the file in a new window use
+CTRL-W f.
+   If something goes wrong you will get an error message.  It's possible that
+the URL is wrong, you don't have permission to read it, the network connection
+is down, etc.  Unfortunately, it's hard to tell the cause of the error.  You
+might want to try the manual way of downloading the file.
+
+Accessing files over the internet works with the netrw plugin.  Currently URLs
+with these formats are recognized:
+
+	ftp://		uses ftp
+	rcp://		uses rcp
+	scp://		uses scp
+	http://		uses wget (reading only)
+
+Vim doesn't do the communication itself, it relies on the mentioned programs
+to be available on your computer.  On most Unix systems "ftp" and "rcp" will
+be present.  "scp" and "wget" might need to be installed.
+
+Vim detects these URLs for each command that starts editing a new file, also
+with ":edit" and ":split", for example.  Write commands also work, except for
+http://.
+
+For more information, also about passwords, see |netrw|.
+
+==============================================================================
+*23.3*	Encryption
+
+Some information you prefer to keep to yourself.  For example, when writing
+a test on a computer that students also use.  You don't want clever students
+to figure out a way to read the questions before the exam starts.  Vim can
+encrypt the file for you, which gives you some protection.
+   To start editing a new file with encryption, use the "-x" argument to start
+Vim.  Example: >
+
+	vim -x exam.txt
+
+Vim prompts you for a key used for encrypting and decrypting the file:
+
+	Enter encryption key: ~
+
+Carefully type the secret key now.  You cannot see the characters you type,
+they will be replaced by stars.  To avoid the situation that a typing mistake
+will cause trouble, Vim asks you to enter the key again:
+
+	Enter same key again: ~
+
+You can now edit this file normally and put in all your secrets.  When you
+finish editing the file and tell Vim to exit, the file is encrypted and
+written.
+   When you edit the file with Vim, it will ask you to enter the same key
+again.  You don't need to use the "-x" argument.  You can also use the normal
+":edit" command.  Vim adds a magic string to the file by which it recognizes
+that the file was encrypted.
+   If you try to view this file using another program, all you get is garbage.
+Also, if you edit the file with Vim and enter the wrong key, you get garbage.
+Vim does not have a mechanism to check if the key is the right one (this makes
+it much harder to break the key).
+
+
+SWITCHING ENCRYPTION ON AND OFF
+
+To disable the encryption of a file, set the 'key' option to an empty string:
+>
+	:set key=
+
+The next time you write the file this will be done without encryption.
+   Setting the 'key' option to enable encryption is not a good idea, because
+the password appears in the clear.  Anyone shoulder-surfing can read your
+password.
+   To avoid this problem, the ":X" command was created.  It asks you for an
+encryption key, just like the "-x" argument did: >
+
+	:X
+	Enter encryption key: ******
+	Enter same key again: ******
+
+
+LIMITS ON ENCRYPTION
+
+The encryption algorithm used by Vim is weak.  It is good enough to keep out
+the casual prowler, but not good enough to keep out a cryptology expert with
+lots of time on his hands.  Also you should be aware that the swap file is not
+encrypted; so while you are editing, people with superuser privileges can read
+the unencrypted text from this file.
+   One way to avoid letting people read your swap file is to avoid using one.
+If the -n argument is supplied on the command line, no swap file is used
+(instead, Vim puts everything in memory).  For example, to edit the encrypted
+file "file.txt" without a swap file use the following command: >
+
+	vim -x -n file.txt
+
+When already editing a file, the swapfile can be disabled with: >
+
+	:setlocal noswapfile
+
+Since there is no swapfile, recovery will be impossible.  Save the file a bit
+more often to avoid the risk of losing your changes.
+
+While the file is in memory, it is in plain text.  Anyone with privilege can
+look in the editor's memory and discover the contents of the file.
+   If you use a viminfo file, be aware that the contents of text registers are
+written out in the clear as well.
+   If you really want to secure the contents of a file, edit it only on a
+portable computer not connected to a network, use good encryption tools, and
+keep the computer locked up in a big safe when not in use.
+
+==============================================================================
+*23.4*	Binary files
+
+You can edit binary files with Vim.  Vim wasn't really made for this, thus
+there are a few restrictions.  But you can read a file, change a character and
+write it back, with the result that only that one character was changed and
+the file is identical otherwise.
+   To make sure that Vim does not use its clever tricks in the wrong way, add
+the "-b" argument when starting Vim: >
+
+	vim -b datafile
+
+This sets the 'binary' option.  The effect of this is that unexpected side
+effects are turned off.  For example, 'textwidth' is set to zero, to avoid
+automatic formatting of lines.  And files are always read in Unix file format.
+
+Binary mode can be used to change a message in a program.  Be careful not to
+insert or delete any characters, it would stop the program from working.  Use
+"R" to enter replace mode.
+
+Many characters in the file will be unprintable.  To see them in Hex format: >
+
+	:set display=uhex
+
+Otherwise, the "ga" command can be used to see the value of the character
+under the cursor.  The output, when the cursor is on an <Esc>, looks like
+this:
+
+	<^[>  27,  Hex 1b,  Octal 033 ~
+
+There might not be many line breaks in the file.  To get some overview switch
+the 'wrap' option off: >
+
+	:set nowrap
+
+
+BYTE POSITION
+
+To see on which byte you are in the file use this command: >
+
+	g CTRL-G
+
+The output is verbose:
+
+    Col 9-16 of 9-16; Line 277 of 330; Word 1806 of 2058; Byte 10580 of 12206 ~
+
+The last two numbers are the byte position in the file and the total number of
+bytes.  This takes into account how 'fileformat' changes the number of bytes
+that a line break uses.
+    To move to a specific byte in the file, use the "go" command.  For
+example, to move to byte 2345: >
+
+	2345go
+
+
+USING XXD
+
+A real binary editor shows the text in two ways: as it is and in hex format.
+You can do this in Vim by first converting the file with the "xxd" program.
+This comes with Vim.
+   First edit the file in binary mode: >
+
+	vim -b datafile
+
+Now convert the file to a hex dump with xxd: >
+
+	:%!xxd
+
+The text will look like this:
+
+	0000000: 1f8b 0808 39d7 173b 0203 7474 002b 4e49  ....9..;..tt.+NI ~
+	0000010: 4b2c 8660 eb9c ecac c462 eb94 345e 2e30  K,.`.....b..4^.0 ~
+	0000020: 373b 2731 0b22 0ca6 c1a2 d669 1035 39d9  7;'1.".....i.59. ~
+
+You can now view and edit the text as you like.  Vim treats the information as
+ordinary text.  Changing the hex does not cause the printable character to be
+changed, or the other way around.
+   Finally convert it back with:
+>
+	:%!xxd -r
+
+Only changes in the hex part are used.  Changes in the printable text part on
+the right are ignored.
+
+See the manual page of xxd for more information.
+
+==============================================================================
+*23.5*	Compressed files
+
+This is easy: You can edit a compressed file just like any other file.  The
+"gzip" plugin takes care of decompressing the file when you edit it.  And
+compressing it again when you write it.
+   These compression methods are currently supported:
+
+	.Z	compress
+	.gz	gzip
+	.bz2	bzip2
+
+Vim uses the mentioned programs to do the actual compression and
+decompression.  You might need to install the programs first.
+
+==============================================================================
+
+Next chapter: |usr_24.txt|  Inserting quickly
+
+Copyright: see |manual-copyright|  vim:tw=78:ts=8:ft=help:norl:
--- /dev/null
+++ b/lib/vimfiles/doc/usr_24.txt
@@ -1,0 +1,606 @@
+*usr_24.txt*	For Vim version 7.1.  Last change: 2006 Jul 23
+
+		     VIM USER MANUAL - by Bram Moolenaar
+
+			     Inserting quickly
+
+
+When entering text, Vim offers various ways to reduce the number of keystrokes
+and avoid typing mistakes.  Use Insert mode completion to repeat previously
+typed words.  Abbreviate long words to short ones.  Type characters that
+aren't on your keyboard.
+
+|24.1|	Making corrections
+|24.2|	Showing matches
+|24.3|	Completion
+|24.4|	Repeating an insert
+|24.5|	Copying from another line
+|24.6|	Inserting a register
+|24.7|	Abbreviations
+|24.8|	Entering special characters
+|24.9|	Digraphs
+|24.10|	Normal mode commands
+
+     Next chapter: |usr_25.txt|  Editing formatted text
+ Previous chapter: |usr_23.txt|  Editing other files
+Table of contents: |usr_toc.txt|
+
+==============================================================================
+*24.1*	Making corrections
+
+The <BS> key was already mentioned.  It deletes the character just before the
+cursor.  The <Del> key does the same for the character under (after) the
+cursor.
+   When you typed a whole word wrong, use CTRL-W:
+
+	The horse had fallen to the sky ~
+				       CTRL-W
+	The horse had fallen to the ~
+
+If you really messed up a line and want to start over, use CTRL-U to delete
+it.  This keeps the text after the cursor and the indent.  Only the text from
+the first non-blank to the cursor is deleted.  With the cursor on the "f" of
+"fallen" in the next line pressing CTRL-U does this:
+
+	The horse had fallen to the ~
+		      CTRL-U
+	fallen to the ~
+
+When you spot a mistake a few words back, you need to move the cursor there to
+correct it.  For example, you typed this:
+
+	The horse had follen to the ground ~
+
+You need to change "follen" to "fallen".  With the cursor at the end, you
+would type this to correct it: >
+
+					<Esc>4blraA
+
+<	get out of Insert mode		<Esc>
+	four words back			     4b
+	move on top of the "o"		       l
+	replace with "a"			ra
+	restart Insert mode			  A
+
+Another way to do this: >
+
+		<C-Left><C-Left><C-Left><C-Left><Right><Del>a<End>
+
+<	four words back		     <C-Left><C-Left><C-Left><C-Left>
+	move on top of the "o"			<Right>
+	delete the "o"				       <Del>
+	insert an "a"					    a
+	go to end of the line				     <End>
+
+This uses special keys to move around, while remaining in Insert mode.  This
+resembles what you would do in a modeless editor.  It's easier to remember,
+but takes more time (you have to move your hand from the letters to the cursor
+keys, and the <End> key is hard to press without looking at the keyboard).
+   These special keys are most useful when writing a mapping that doesn't
+leave Insert mode.  The extra typing doesn't matter then.
+   An overview of the keys you can use in Insert mode:
+
+	<C-Home>	to start of the file
+	<PageUp>	a whole screenful up
+	<Home>		to start of line
+	<S-Left>	one word left
+	<C-Left>	one word left
+	<S-Right>	one word right
+	<C-Right>	one word right
+	<End>		to end of the line
+	<PageDown>	a whole screenful down
+	<C-End>		to end of the file
+
+There are a few more, see |ins-special-special|.
+
+==============================================================================
+*24.2*	Showing matches
+
+When you type a ) it would be nice to see with which ( it matches.  To make
+Vim do that use this command: >
+
+	:set showmatch
+
+When you now type a text like "(example)", as soon as you type the ) Vim will
+briefly move the cursor to the matching (, keep it there for half a second,
+and move back to where you were typing.
+   In case there is no matching (, Vim will beep.  Then you know that you
+might have forgotten the ( somewhere, or typed a ) too many.
+   The match will also be shown for [] and {} pairs.  You don't have to wait
+with typing the next character, as soon as Vim sees it the cursor will move
+back and inserting continues as before.
+   You can change the time Vim waits with the 'matchtime' option.  For
+example, to make Vim wait one and a half second: >
+
+	:set matchtime=15
+
+The time is specified in tenths of a second.
+
+==============================================================================
+*24.3*	Completion
+
+Vim can automatically complete words on insertion.  You type the first part of
+a word, press CTRL-P, and Vim guesses the rest.
+   Suppose, for example, that you are creating a C program and want to type in
+the following:
+
+	total = ch_array[0] + ch_array[1] + ch_array[2]; ~
+
+You start by entering the following:
+
+	total = ch_array[0] + ch_ ~
+
+At this point, you tell Vim to complete the word using the command CTRL-P.
+Vim searches for a word that starts with what's in front of the cursor.  In
+this case, it is "ch_", which matches with the word ch_array.  So typing
+CTRL-P gives you the following:
+
+	total = ch_array[0] + ch_array ~
+
+After a little more typing, you get this (ending in a space):
+
+	total = ch_array[0] + ch_array[1] +  ~
+
+If you now type CTRL-P Vim will search again for a word that completes the
+word before the cursor.  Since there is nothing in front of the cursor, it
+finds the first word backwards, which is "ch_array".  Typing CTRL-P again
+gives you the next word that matches, in this case "total".  A third CTRL-P
+searches further back.  If there is nothing else, it causes the editor to run
+out of words, so it returns to the original text, which is nothing.  A fourth
+CTRL-P causes the editor to start over again with "ch_array".
+
+To search forward, use CTRL-N.  Since the search wraps around the end of the
+file, CTRL-N and CTRL-P will find the same matches, but in a different
+sequence.  Hint: CTRL-N is Next-match and CTRL-P is Previous-match.
+
+The Vim editor goes through a lot of effort to find words to complete.  By
+default, it searches the following places:
+
+	1. Current file
+	2. Files in other windows
+	3. Other loaded files (hidden buffers)
+	4. Files which are not loaded (inactive buffers)
+	5. Tag files
+	6. All files #included by the current file
+
+
+OPTIONS
+
+You can customize the search order with the 'complete' option.
+
+The 'ignorecase' option is used.  When it is set, case differences are ignored
+when searching for matches.
+
+A special option for completion is 'infercase'.  This is useful to find
+matches while ignoring case ('ignorecase' must be set) but still using the
+case of the word typed so far.  Thus if you type "For" and Vim finds a match
+"fortunately", it will result in "Fortunately".
+
+
+COMPLETING SPECIFIC ITEMS
+
+If you know what you are looking for, you can use these commands to complete
+with a certain type of item:
+
+	CTRL-X CTRL-F		file names
+	CTRL-X CTRL-L		whole lines
+	CTRL-X CTRL-D		macro definitions (also in included files)
+	CTRL-X CTRL-I		current and included files
+	CTRL-X CTRL-K		words from a dictionary
+	CTRL-X CTRL-T		words from a thesaurus
+	CTRL-X CTRL-]		tags
+	CTRL-X CTRL-V		Vim command line
+
+After each of them CTRL-N can be used to find the next match, CTRL-P to find
+the previous match.
+   More information for each of these commands here: |ins-completion|.
+
+
+COMPLETING FILE NAMES
+
+Let's take CTRL-X CTRL-F as an example.  This will find file names.  It scans
+the current directory for files and displays each one that matches the word in
+front of the cursor.
+   Suppose, for example, that you have the following files in the current
+directory:
+
+	main.c  sub_count.c  sub_done.c  sub_exit.c
+
+Now enter Insert mode and start typing:
+
+	The exit code is in the file sub ~
+
+At this point, you enter the command CTRL-X CTRL-F.  Vim now completes the
+current word "sub" by looking at the files in the current directory.  The
+first match is sub_count.c.  This is not the one you want, so you match the
+next file by typing CTRL-N.  This match is sub_done.c.  Typing CTRL-N again
+takes you to sub_exit.c.  The results:
+
+	The exit code is in the file sub_exit.c ~
+
+If the file name starts with / (Unix) or C:\ (MS-Windows) you can find all
+files in the file system.  For example, type "/u" and CTRL-X CTRL-F.  This
+will match "/usr" (this is on Unix):
+
+	the file is found in /usr/ ~
+
+If you now press CTRL-N you go back to "/u".  Instead, to accept the "/usr/"
+and go one directory level deeper, use CTRL-X CTRL-F again:
+
+	the file is found in /usr/X11R6/ ~
+
+The results depend on what is found in your file system, of course.  The
+matches are sorted alphabetically.
+
+
+COMPLETING IN SOURCE CODE
+
+Source code files are well structured.  That makes it possible to do
+completion in an intelligent way.  In Vim this is called Omni completion.  In
+some other editors it's called intellisense, but that is a trademark.
+
+The key to Omni completion is CTRL-X CTRL-O.  Obviously the O stands for Omni
+here, so that you can remember it easier.  Let's use an example for editing C
+source:
+
+	{ ~
+	    struct foo *p; ~
+	    p-> ~
+
+The cursor is after "p->".  Now type CTRL-X CTRL-O.  Vim will offer you a list
+of alternatives, which are the items that "struct foo" contains.  That is
+quite different from using CTRL-P, which would complete any word, while only
+members of "struct foo" are valid here.
+
+For Omni completion to work you may need to do some setup.  At least make sure
+filetype plugins are enabled.  Your vimrc file should contain a line like
+this: >
+	filetype plugin on
+Or: >
+	filetype plugin indent on
+
+For C code you need to create a tags file and set the 'tags' option.  That is
+explained |ft-c-omni|.  For other filetypes you may need to do something
+similar, look below |compl-omni-filetypes|.  It only works for specific
+filetypes.  Check the value of the 'omnifunc' option to find out if it would
+work.
+
+==============================================================================
+*24.4*	Repeating an insert
+
+If you press CTRL-A, the editor inserts the text you typed the last time you
+were in Insert mode.
+   Assume, for example, that you have a file that begins with the following:
+
+	"file.h" ~
+	/* Main program begins */ ~
+
+You edit this file by inserting "#include " at the beginning of the first
+line:
+
+	#include "file.h" ~
+	/* Main program begins */ ~
+
+You go down to the beginning of the next line using the commands "j^".  You
+now start to insert a new "#include" line.  So you type: >
+
+	i CTRL-A
+
+The result is as follows:
+
+	#include "file.h" ~
+	#include /* Main program begins */ ~
+
+The "#include " was inserted because CTRL-A inserts the text of the previous
+insert.  Now you type  "main.h"<Enter>  to finish the line:
+
+
+	#include "file.h" ~
+	#include "main.h" ~
+	/* Main program begins */ ~
+
+The CTRL-@ command does a CTRL-A and then exits Insert mode.  That's a quick
+way of doing exactly the same insertion again.
+
+==============================================================================
+*24.5*	Copying from another line
+
+The CTRL-Y command inserts the character above the cursor.  This is useful
+when you are duplicating a previous line.  For example, you have this line of
+C code:
+
+	b_array[i]->s_next = a_array[i]->s_next; ~
+
+Now you need to type the same line, but with "s_prev" instead of "s_next".
+Start the new line, and press CTRL-Y 14 times, until you are at the "n" of
+"next":
+
+	b_array[i]->s_next = a_array[i]->s_next; ~
+	b_array[i]->s_ ~
+
+Now you type "prev":
+
+	b_array[i]->s_next = a_array[i]->s_next; ~
+	b_array[i]->s_prev ~
+
+Continue pressing CTRL-Y until the following "next":
+
+	b_array[i]->s_next = a_array[i]->s_next; ~
+	b_array[i]->s_prev = a_array[i]->s_ ~
+
+Now type "prev;" to finish it off.
+
+The CTRL-E command acts like CTRL-Y except it inserts the character below the
+cursor.
+
+==============================================================================
+*24.6*	Inserting a register
+
+The command CTRL-R {register} inserts the contents of the register.  This is
+useful to avoid having to type a long word.  For example, you need to type
+this:
+
+	r = VeryLongFunction(a) + VeryLongFunction(b) + VeryLongFunction(c) ~
+
+The function name is defined in a different file.  Edit that file and move the
+cursor on top of the function name there, and yank it into register v: >
+
+	"vyiw
+
+"v is the register specification, "yiw" is yank-inner-word.  Now edit the file
+where the new line is to be inserted, and type the first letters:
+
+	r = ~
+
+Now use CTRL-R v to insert the function name:
+
+	r = VeryLongFunction ~
+
+You continue to type the characters in between the function name, and use
+CTRL-R v two times more.
+   You could have done the same with completion.  Using a register is useful
+when there are many words that start with the same characters.
+
+If the register contains characters such as <BS> or other special characters,
+they are interpreted as if they had been typed from the keyboard.  If you do
+not want this to happen (you really want the <BS> to be inserted in the text),
+use the command CTRL-R CTRL-R {register}.
+
+==============================================================================
+*24.7*	Abbreviations
+
+An abbreviation is a short word that takes the place of a long one.  For
+example, "ad" stands for "advertisement".  Vim enables you to type an
+abbreviation and then will automatically expand it for you.
+   To tell Vim to expand "ad" into "advertisement" every time you insert it,
+use the following command: >
+
+	:iabbrev ad advertisement
+
+Now, when you type "ad", the whole word "advertisement" will be inserted into
+the text.  This is triggered by typing a character that can't be part of a
+word, for example a space:
+
+	What Is Entered		What You See
+	I saw the a		I saw the a ~
+	I saw the ad		I saw the ad ~
+	I saw the ad<Space>	I saw the advertisement<Space> ~
+
+The expansion doesn't happen when typing just "ad".  That allows you to type a
+word like "add", which will not get expanded.  Only whole words are checked
+for abbreviations.
+
+
+ABBREVIATING SEVERAL WORDS
+
+It is possible to define an abbreviation that results in multiple words.  For
+example, to define "JB" as "Jack Benny", use the following command: >
+
+	:iabbrev JB Jack Benny
+
+As a programmer, I use two rather unusual abbreviations: >
+
+	:iabbrev #b /****************************************
+	:iabbrev #e <Space>****************************************/
+
+These are used for creating boxed comments.  The comment starts with #b, which
+draws the top line.  I then type the comment text and use #e to draw the
+bottom line.
+   Notice that the #e abbreviation begins with a space.  In other words, the
+first two characters are space-star.  Usually Vim ignores spaces between the
+abbreviation and the expansion.  To avoid that problem, I spell space as seven
+characters: <, S, p, a, c, e, >.
+
+	Note:
+	":iabbrev" is a long word to type.  ":iab" works just as well.
+	That's abbreviating the abbreviate command!
+
+
+FIXING TYPING MISTAKES
+
+It's very common to make the same typing mistake every time.  For example,
+typing "teh" instead of "the".  You can fix this with an abbreviation: >
+
+	:abbreviate teh the
+
+You can add a whole list of these.  Add one each time you discover a common
+mistake.
+
+
+LISTING ABBREVIATIONS
+
+The ":abbreviate" command lists the abbreviations:
+
+	:abbreviate
+	i  #e		  ****************************************/
+	i  #b		 /****************************************
+	i  JB		 Jack Benny
+	i  ad		 advertisement
+	!  teh		 the
+
+The "i" in the first column indicates Insert mode.  These abbreviations are
+only active in Insert mode.  Other possible characters are:
+
+	c	Command-line mode			:cabbrev
+	!	both Insert and Command-line mode	:abbreviate
+
+Since abbreviations are not often useful in Command-line mode, you will mostly
+use the ":iabbrev" command.  That avoids, for example, that "ad" gets expanded
+when typing a command like: >
+
+	:edit ad
+
+
+DELETING ABBREVIATIONS
+
+To get rid of an abbreviation, use the ":unabbreviate" command.  Suppose you
+have the following abbreviation: >
+
+	:abbreviate @f fresh
+
+You can remove it with this command: >
+
+	:unabbreviate @f
+
+While you type this, you will notice that @f is expanded to "fresh".  Don't
+worry about this, Vim understands it anyway (except when you have an
+abbreviation for "fresh", but that's very unlikely).
+   To remove all the abbreviations: >
+
+	:abclear
+
+":unabbreviate" and ":abclear" also come in the variants for Insert mode
+(":iunabbreviate and ":iabclear") and Command-line mode (":cunabbreviate" and
+":cabclear").
+
+
+REMAPPING ABBREVIATIONS
+
+There is one thing to watch out for when defining an abbreviation: The
+resulting string should not be mapped.  For example: >
+
+	:abbreviate @a adder
+	:imap dd disk-door
+
+When you now type @a, you will get "adisk-doorer".  That's not what you want.
+To avoid this, use the ":noreabbrev" command.  It does the same as
+":abbreviate", but avoids that the resulting string is used for mappings: >
+
+	:noreabbrev @a adder
+
+Fortunately, it's unlikely that the result of an abbreviation is mapped.
+
+==============================================================================
+*24.8*	Entering special characters
+
+The CTRL-V command is used to insert the next character literally.  In other
+words, any special meaning the character has, it will be ignored.  For
+example: >
+
+	CTRL-V <Esc>
+
+Inserts an escape character.  Thus you don't leave Insert mode.  (Don't type
+the space after CTRL-V, it's only to make this easier to read).
+
+	Note:
+	On MS-Windows CTRL-V is used to paste text.  Use CTRL-Q instead of
+	CTRL-V.  On Unix, on the other hand, CTRL-Q does not work on some
+	terminals, because it has a special meaning.
+
+You can also use the command CTRL-V {digits} to insert a character with the
+decimal number {digits}.  For example, the character number 127 is the <Del>
+character (but not necessarily the <Del> key!).  To insert <Del> type: >
+
+	CTRL-V 127
+
+You can enter characters up to 255 this way.  When you type fewer than two
+digits, a non-digit will terminate the command.  To avoid the need of typing a
+non-digit, prepend one or two zeros to make three digits.
+   All the next commands insert a <Tab> and then a dot:
+
+	CTRL-V 9.
+	CTRL-V 09.
+	CTRL-V 009.
+
+To enter a character in hexadecimal, use an "x" after the CTRL-V: >
+
+	CTRL-V x7f
+
+This also goes up to character 255 (CTRL-V xff).  You can use "o" to type a
+character as an octal number and two more methods allow you to type up to
+a 16 bit and a 32 bit number (e.g., for a Unicode character): >
+
+	CTRL-V o123
+	CTRL-V u1234
+	CTRL-V U12345678
+
+==============================================================================
+*24.9*	Digraphs
+
+Some characters are not on the keyboard.  For example, the copyright character
+(�).  To type these characters in Vim, you use digraphs, where two characters
+represent one.  To enter a �, for example, you press three keys: >
+
+	CTRL-K Co
+
+To find out what digraphs are available, use the following command: >
+
+	:digraphs
+
+Vim will display the digraph table.  Here are three lines of it:
+
+  AC ~_ 159  NS |  160  !I �  161  Ct �  162  Pd �  163  Cu �  164  Ye �  165 ~
+  BB �  166  SE �  167  ': �  168  Co �  169  -a �  170  << �  171  NO �  172 ~
+  -- �  173  Rg �  174  'm �  175  DG �  176  +- �  177  2S �  178  3S �  179 ~
+
+This shows, for example, that the digraph you get by typing CTRL-K Pd is the
+character (�).  This is character number 163 (decimal).
+   Pd is short for Pound.  Most digraphs are selected to give you a hint about
+the character they will produce.  If you look through the list you will
+understand the logic.
+   You can exchange the first and second character, if there is no digraph for
+that combination.  Thus CTRL-K dP also works.  Since there is no digraph for
+"dP" Vim will also search for a "Pd" digraph.
+
+	Note:
+	The digraphs depend on the character set that Vim assumes you are
+	using.  On MS-DOS they are different from MS-Windows.  Always use
+	":digraphs" to find out which digraphs are currently available.
+
+You can define your own digraphs.  Example: >
+
+	:digraph a" +
+This defines that CTRL-K a" inserts an � character.  You can also specify the
+character with a decimal number.  This defines the same digraph: >
+
+	:digraph a" 228
+
+More information about digraphs here: |digraphs|
+   Another way to insert special characters is with a keymap.  More about that
+here: |45.5|
+
+==============================================================================
+*24.10*	Normal mode commands
+
+Insert mode offers a limited number of commands.  In Normal mode you have many
+more.  When you want to use one, you usually leave Insert mode with <Esc>,
+execute the Normal mode command, and re-enter Insert mode with "i" or "a".
+   There is a quicker way.  With CTRL-O {command} you can execute any Normal
+mode command from Insert mode.  For example, to delete from the cursor to the
+end of the line: >
+
+	CTRL-O D
+
+You can execute only one Normal mode command this way.  But you can specify a
+register or a count.  A more complicated example: >
+
+	CTRL-O "g3dw
+
+This deletes up to the third word into register g.
+
+==============================================================================
+
+Next chapter: |usr_25.txt|  Editing formatted text
+
+Copyright: see |manual-copyright|  vim:tw=78:ts=8:ft=help:norl:
--- /dev/null
+++ b/lib/vimfiles/doc/usr_25.txt
@@ -1,0 +1,578 @@
+*usr_25.txt*	For Vim version 7.1.  Last change: 2007 May 11
+
+		     VIM USER MANUAL - by Bram Moolenaar
+
+			     Editing formatted text
+
+
+Text hardly ever comes in one sentence per line.  This chapter is about
+breaking sentences to make them fit on a page and other formatting.
+Vim also has useful features for editing single-line paragraphs and tables.
+
+|25.1|	Breaking lines
+|25.2|	Aligning text
+|25.3|	Indents and tabs
+|25.4|	Dealing with long lines
+|25.5|	Editing tables
+
+     Next chapter: |usr_26.txt|  Repeating
+ Previous chapter: |usr_24.txt|  Inserting quickly
+Table of contents: |usr_toc.txt|
+
+==============================================================================
+*25.1*	Breaking lines
+
+Vim has a number of functions that make dealing with text easier.  By default,
+the editor does not perform automatic line breaks.  In other words, you have
+to press <Enter> yourself.  This is useful when you are writing programs where
+you want to decide where the line ends.  It is not so good when you are
+creating documentation and want the text to be at most 70 character wide.
+   If you set the 'textwidth' option, Vim automatically inserts line breaks.
+Suppose, for example, that you want a very narrow column of only 30
+characters.  You need to execute the following command: >
+
+	:set textwidth=30
+
+Now you start typing (ruler added):
+
+		 1	   2	     3
+	12345678901234567890123456789012345
+	I taught programming for a whi ~
+
+If you type "l" next, this makes the line longer than the 30-character limit.
+When Vim sees this, it inserts a line break and you get the following:
+
+		 1	   2	     3
+	12345678901234567890123456789012345
+	I taught programming for a ~
+	whil ~
+
+Continuing on, you can type in the rest of the paragraph:
+
+		 1	   2	     3
+	12345678901234567890123456789012345
+	I taught programming for a ~
+	while. One time, I was stopped ~
+	by the Fort Worth police, ~
+	because my homework was too ~
+	hard. True story. ~
+
+You do not have to type newlines; Vim puts them in automatically.
+
+	Note:
+	The 'wrap' option makes Vim display lines with a line break, but this
+	doesn't insert a line break in the file.
+
+
+REFORMATTING
+
+The Vim editor is not a word processor.  In a word processor, if you delete
+something at the beginning of the paragraph, the line breaks are reworked.  In
+Vim they are not; so if you delete the word "programming" from the first line,
+all you get is a short line:
+
+		 1	   2	     3
+	12345678901234567890123456789012345
+	I taught for a ~
+	while. One time, I was stopped ~
+	by the Fort Worth police, ~
+	because my homework was too ~
+	hard. True story. ~
+
+This does not look good.  To get the paragraph into shape you use the "gq"
+operator.
+   Let's first use this with a Visual selection.  Starting from the first
+line, type: >
+
+	v4jgq
+
+"v" to start Visual mode, "4j' to move to the end of the paragraph and then
+the "gq" operator.  The result is:
+
+		 1	   2	     3
+	12345678901234567890123456789012345
+	I taught for a while. One ~
+	time, I was stopped by the ~
+	Fort Worth police, because my ~
+	homework was too hard. True ~
+	story. ~
+
+Note: there is a way to do automatic formatting for specific types of text
+layouts, see |auto-format|.
+
+Since "gq" is an operator, you can use one of the three ways to select the
+text it works on: With Visual mode, with a movement and with a text object.
+   The example above could also be done with "gq4j".  That's less typing, but
+you have to know the line count.  A more useful motion command is "}".  This
+moves to the end of a paragraph.  Thus "gq}" formats from the cursor to the
+end of the current paragraph.
+   A very useful text object to use with "gq" is the paragraph.  Try this: >
+
+	gqap
+
+"ap" stands for "a-paragraph".  This formats the text of one paragraph
+(separated by empty lines).  Also the part before the cursor.
+   If you have your paragraphs separated by empty lines, you can format the
+whole file by typing this: >
+
+	gggqG
+
+"gg" to move to the first line, "gqG" to format until the last line.
+   Warning: If your paragraphs are not properly separated, they will be joined
+together.  A common mistake is to have a line with a space or tab.  That's a
+blank line, but not an empty line.
+
+Vim is able to format more than just plain text.  See |fo-table| for how to
+change this.  See the 'joinspaces' option to change the number of spaces used
+after a full stop.
+   It is possible to use an external program for formatting.  This is useful
+if your text can't be properly formatted with Vim's builtin command.  See the
+'formatprg' option.
+
+==============================================================================
+*25.2*	Aligning text
+
+To center a range of lines, use the following command: >
+
+	:{range}center [width]
+
+{range} is the usual command-line range.  [width] is an optional line width to
+use for centering.  If [width] is not specified, it defaults to the value of
+'textwidth'.  (If 'textwidth' is 0, the default is 80.)
+   For example: >
+
+	:1,5center 40
+
+results in the following:
+
+       I taught for a while. One ~
+       time, I was stopped by the ~
+     Fort Worth police, because my ~
+      homework was too hard. True ~
+		 story. ~
+
+
+RIGHT ALIGNMENT
+
+Similarly, the ":right" command right-justifies the text: >
+
+	:1,5right 37
+
+gives this result:
+
+	    I taught for a while. One ~
+	   time, I was stopped by the ~
+	Fort Worth police, because my ~
+	  homework was too hard. True ~
+			       story. ~
+
+LEFT ALIGNMENT
+
+Finally there is this command: >
+
+	:{range}left [margin]
+
+Unlike ":center" and ":right", however, the argument to ":left" is not the
+length of the line.  Instead it is the left margin.  If it is omitted, the
+text will be put against the left side of the screen (using a zero margin
+would do the same).  If it is 5, the text will be indented 5 spaces.  For
+example, use these commands: >
+
+	:1left 5
+	:2,5left
+
+This results in the following:
+
+	     I taught for a while. One ~
+	time, I was stopped by the ~
+	Fort Worth police, because my ~
+	homework was too hard. True ~
+	story. ~
+
+
+JUSTIFYING TEXT
+
+Vim has no built-in way of justifying text.  However, there is a neat macro
+package that does the job.  To use this package, execute the following
+command: >
+
+	:runtime macros/justify.vim
+
+This Vim script file defines a new visual command "_j".  To justify a block of
+text, highlight the text in Visual mode and then execute "_j".
+   Look in the file for more explanations.  To go there, do "gf" on this name:
+$VIMRUNTIME/macros/justify.vim.
+
+An alternative is to filter the text through an external program.  Example: >
+
+	:%!fmt
+
+==============================================================================
+*25.3*	Indents and tabs
+
+Indents can be used to make text stand out from the rest.  The example texts
+in this manual, for example, are indented by eight spaces or a tab.  You would
+normally enter this by typing a tab at the start of each line.  Take this
+text:
+	the first line ~
+	the second line ~
+
+This is entered by typing a tab, some text, <Enter>, tab and more text.
+   The 'autoindent' option inserts indents automatically: >
+
+	:set autoindent
+
+When a new line is started it gets the same indent as the previous line.  In
+the above example, the tab after the <Enter> is not needed anymore.
+
+
+INCREASING INDENT
+
+To increase the amount of indent in a line, use the ">" operator.  Often this
+is used as ">>", which adds indent to the current line.
+   The amount of indent added is specified with the 'shiftwidth' option.  The
+default value is 8.  To make ">>" insert four spaces worth of indent, for
+example, type this: >
+
+	:set shiftwidth=4
+
+When used on the second line of the example text, this is what you get:
+
+	the first line ~
+	    the second line ~
+
+"4>>" will increase the indent of four lines.
+
+
+TABSTOP
+
+If you want to make indents a multiple of 4, you set 'shiftwidth' to 4.  But
+when pressing a <Tab> you still get 8 spaces worth of indent.  To change this,
+set the 'softtabstop' option: >
+
+	:set softtabstop=4
+
+This will make the <Tab> key insert 4 spaces worth of indent.  If there are
+already four spaces, a <Tab> character is used (saving seven characters in the
+file).  (If you always want spaces and no tab characters, set the 'expandtab'
+option.)
+
+	Note:
+	You could set the 'tabstop' option to 4.  However, if you edit the
+	file another time, with 'tabstop' set to the default value of 8, it
+	will look wrong.  In other programs and when printing the indent will
+	also be wrong.  Therefore it is recommended to keep 'tabstop' at eight
+	all the time.  That's the standard value everywhere.
+
+
+CHANGING TABS
+
+You edit a file which was written with a tabstop of 3.  In Vim it looks ugly,
+because it uses the normal tabstop value of 8.  You can fix this by setting
+'tabstop' to 3.  But you have to do this every time you edit this file.
+   Vim can change the use of tabstops in your file.  First, set 'tabstop' to
+make the indents look good, then use the ":retab" command: >
+
+	:set tabstop=3
+	:retab 8
+
+The ":retab" command will change 'tabstop' to 8, while changing the text such
+that it looks the same.  It changes spans of white space into tabs and spaces
+for this.  You can now write the file.  Next time you edit it the indents will
+be right without setting an option.
+   Warning: When using ":retab" on a program, it may change white space inside
+a string constant.  Therefore it's a good habit to use "\t" instead of a
+real tab.
+
+==============================================================================
+*25.4*	Dealing with long lines
+
+Sometimes you will be editing a file that is wider than the number of columns
+in the window.  When that occurs, Vim wraps the lines so that everything fits
+on the screen.
+   If you switch the 'wrap' option off, each line in the file shows up as one
+line on the screen.  Then the ends of the long lines disappear off the screen
+to the right.
+   When you move the cursor to a character that can't be seen, Vim will scroll
+the text to show it.  This is like moving a viewport over the text in the
+horizontal direction.
+   By default, Vim does not display a horizontal scrollbar in the GUI.  If you
+want to enable one, use the following command: >
+
+	:set guioptions+=b
+
+One horizontal scrollbar will appear at the bottom of the Vim window.
+
+If you don't have a scrollbar or don't want to use it, use these commands to
+scroll the text.  The cursor will stay in the same place, but it's move back
+into the visible text if necessary.
+
+	zh		scroll right
+	4zh		scroll four characters right
+	zH		scroll half a window width right
+	ze		scroll right to put the cursor at the end
+	zl		scroll left
+	4zl		scroll four characters left
+	zL		scroll half a window width left
+	zs		scroll left to put the cursor at the start
+
+Let's attempt to show this with one line of text.  The cursor is on the "w" of
+"which".  The "current window" above the line indicates the text that is
+currently visible.  The "window"s below the text indicate the text that is
+visible after the command left of it.
+
+			      |<-- current window -->|
+		some long text, part of which is visible in the window ~
+	ze	  |<--	   window     -->|
+	zH	   |<--     window     -->|
+	4zh		  |<--	   window     -->|
+	zh		     |<--     window	 -->|
+	zl		       |<--	window	   -->|
+	4zl			  |<--	   window     -->|
+	zL				|<--	 window     -->|
+	zs			       |<--	window	   -->|
+
+
+MOVING WITH WRAP OFF
+
+When 'wrap' is off and the text has scrolled horizontally, you can use the
+following commands to move the cursor to a character you can see.  Thus text
+left and right of the window is ignored.  These never cause the text to
+scroll:
+
+	g0		to first visible character in this line
+	g^		to first non-blank visible character in this line
+	gm		to middle of this line
+	g$		to last visible character in this line
+
+		|<--	 window    -->|
+	some long    text, part of which is visible ~
+		 g0  g^    gm	     g$
+
+
+BREAKING AT WORDS				*edit-no-break*
+
+When preparing text for use by another program, you might have to make
+paragraphs without a line break.  A disadvantage of using 'nowrap' is that you
+can't see the whole sentence you are working on.  When 'wrap' is on, words are
+broken halfway, which makes them hard to read.
+   A good solution for editing this kind of paragraph is setting the
+'linebreak' option.  Vim then breaks lines at an appropriate place when
+displaying the line.  The text in the file remains unchanged.
+   Without 'linebreak' text might look like this:
+
+	+---------------------------------+
+	|letter generation program for a b|
+	|ank.  They wanted to send out a s|
+	|pecial, personalized letter to th|
+	|eir richest 1000 customers.  Unfo|
+	|rtunately for the programmer, he |
+	+---------------------------------+
+After: >
+
+	:set linebreak
+
+it looks like this:
+
+	+---------------------------------+
+	|letter generation program for a  |
+	|bank.  They wanted to send out a |
+	|special, personalized letter to  |
+	|their richest 1000 customers.    |
+	|Unfortunately for the programmer,|
+	+---------------------------------+
+
+Related options:
+'breakat' specifies the characters where a break can be inserted.
+'showbreak' specifies a string to show at the start of broken line.
+Set 'textwidth' to zero to avoid a paragraph to be split.
+
+
+MOVING BY VISIBLE LINES
+
+The "j" and "k" commands move to the next and previous lines.  When used on
+a long line, this means moving a lot of screen lines at once.
+   To move only one screen line, use the "gj" and "gk" commands.  When a line
+doesn't wrap they do the same as "j" and "k".  When the line does wrap, they
+move to a character displayed one line below or above.
+   You might like to use these mappings, which bind these movement commands to
+the cursor keys: >
+
+	:map <Up> gk
+	:map <Down> gj
+
+
+TURNING A PARAGRAPH INTO ONE LINE
+
+If you want to import text into a program like MS-Word, each paragraph should
+be a single line.  If your paragraphs are currently separated with empty
+lines, this is how you turn each paragraph into a single line: >
+
+	:g/./,/^$/join
+
+That looks complicated.  Let's break it up in pieces:
+
+	:g/./		A ":global" command that finds all lines that contain
+			at least one character.
+	     ,/^$/	A range, starting from the current line (the non-empty
+			line) until an empty line.
+		  join	The ":join" command joins the range of lines together
+			into one line.
+
+Starting with this text, containing eight lines broken at column 30:
+
+	+----------------------------------+
+	|A letter generation program	   |
+	|for a bank.  They wanted to	   |
+	|send out a special,		   |
+	|personalized letter.		   |
+	|				   |
+	|To their richest 1000		   |
+	|customers.  Unfortunately for	   |
+	|the programmer,		   |
+	+----------------------------------+
+
+You end up with two lines:
+
+	+----------------------------------+
+	|A letter generation program for a |
+	|bank.	They wanted to send out a s|
+	|pecial, personalized letter.	   |
+	|To their richest 1000 customers.  |
+	|Unfortunately for the programmer, |
+	+----------------------------------+
+
+Note that this doesn't work when the separating line is blank but not empty;
+when it contains spaces and/or tabs.  This command does work with blank lines:
+>
+	:g/\S/,/^\s*$/join
+
+This still requires a blank or empty line at the end of the file for the last
+paragraph to be joined.
+
+==============================================================================
+*25.5*	Editing tables
+
+Suppose you are editing a table with four columns:
+
+	nice table	  test 1	test 2	    test 3 ~
+	input A		  0.534 ~
+	input B		  0.913 ~
+
+You need to enter numbers in the third column.  You could move to the second
+line, use "A", enter a lot of spaces and type the text.
+   For this kind of editing there is a special option: >
+
+	set virtualedit=all
+
+Now you can move the cursor to positions where there isn't any text.  This is
+called "virtual space".  Editing a table is a lot easier this way.
+   Move the cursor by searching for the header of the last column: >
+
+	/test 3
+
+Now press "j" and you are right where you can enter the value for "input A".
+Typing "0.693" results in:
+
+	nice table	  test 1     test 2	 test 3 ~
+	input A		  0.534			 0.693 ~
+	input B		  0.913 ~
+
+Vim has automatically filled the gap in front of the new text for you.  Now,
+to enter the next field in this column use "Bj".  "B" moves back to the start
+of a white space separated word.  Then "j" moves to the place where the next
+field can be entered.
+
+	Note:
+	You can move the cursor anywhere in the display, also beyond the end
+	of a line.  But Vim will not insert spaces there, until you insert a
+	character in that position.
+
+
+COPYING A COLUMN
+
+You want to add a column, which should be a copy of the third column and
+placed before the "test 1" column.  Do this in seven steps:
+1.  Move the cursor to the left upper corner of this column, e.g., with
+    "/test 3".
+2.  Press CTRL-V to start blockwise Visual mode.
+3.  Move the cursor down two lines with "2j".  You are now in "virtual space":
+    the "input B" line of the "test 3" column.
+4.  Move the cursor right, to include the whole column in the selection, plus
+    the space that you want between the columns.  "9l" should do it.
+5.  Yank the selected rectangle with "y".
+6.  Move the cursor to "test 1", where the new column must be placed.
+7.  Press "P".
+
+The result should be:
+
+	nice table	  test 3    test 1     test 2	   test 3 ~
+	input A		  0.693     0.534		   0.693 ~
+	input B			    0.913 ~
+
+Notice that the whole "test 1" column was shifted right, also the line where
+the "test 3" column didn't have text.
+
+Go back to non-virtual cursor movements with: >
+
+	:set virtualedit=
+
+
+VIRTUAL REPLACE MODE
+
+The disadvantage of using 'virtualedit' is that it "feels" different.  You
+can't recognize tabs or spaces beyond the end of line when moving the cursor
+around.  Another method can be used: Virtual Replace mode.
+   Suppose you have a line in a table that contains both tabs and other
+characters.  Use "rx" on the first tab:
+
+	inp	0.693   0.534	0.693 ~
+
+	       |
+	   rx  |
+	       V
+
+	inpx0.693   0.534	0.693 ~
+
+The layout is messed up.  To avoid that, use the "gr" command:
+
+	inp	0.693   0.534	0.693 ~
+
+	       |
+	  grx  |
+	       V
+
+	inpx	0.693   0.534	0.693 ~
+
+What happens is that the "gr" command makes sure the new character takes the
+right amount of screen space.  Extra spaces or tabs are inserted to fill the
+gap.  Thus what actually happens is that a tab is replaced by "x" and then
+blanks added to make the text after it keep it's place.  In this case a
+tab is inserted.
+   When you need to replace more than one character, you use the "R" command
+to go to Replace mode (see |04.9|).  This messes up the layout and replaces
+the wrong characters:
+
+	inp	0	0.534	0.693 ~
+
+		|
+	 R0.786 |
+		V
+
+	inp	0.78634	0.693 ~
+
+The "gR" command uses Virtual Replace mode.  This preserves the layout:
+
+	inp	0	0.534	0.693 ~
+
+		|
+	gR0.786 |
+		V
+
+	inp	0.786	0.534	0.693 ~
+
+==============================================================================
+
+Next chapter: |usr_26.txt|  Repeating
+
+Copyright: see |manual-copyright|  vim:tw=78:ts=8:ft=help:norl:
--- /dev/null
+++ b/lib/vimfiles/doc/usr_26.txt
@@ -1,0 +1,221 @@
+*usr_26.txt*	For Vim version 7.1.  Last change: 2006 Apr 24
+
+		     VIM USER MANUAL - by Bram Moolenaar
+
+				  Repeating
+
+
+An editing task is hardly ever unstructured.  A change often needs to be made
+several times.  In this chapter a number of useful ways to repeat a change
+will be explained.
+
+|26.1|	Repeating with Visual mode
+|26.2|	Add and subtract
+|26.3|	Making a change in many files
+|26.4|	Using Vim from a shell script
+
+     Next chapter: |usr_27.txt|  Search commands and patterns
+ Previous chapter: |usr_25.txt|  Editing formatted text
+Table of contents: |usr_toc.txt|
+
+==============================================================================
+*26.1*	Repeating with Visual mode
+
+Visual mode is very handy for making a change in any sequence of lines.  You
+can see the highlighted text, thus you can check if the correct lines are
+changed.  But making the selection takes some typing.  The "gv" command
+selects the same area again.  This allows you to do another operation on the
+same text.
+   Suppose you have some lines where you want to change "2001" to "2002" and
+"2000" to "2001":
+
+	The financial results for 2001 are better ~
+	than for 2000.  The income increased by 50%, ~
+	even though 2001 had more rain than 2000. ~
+			2000		2001 ~
+	income		45,403		66,234 ~
+
+First change "2001" to "2002".  Select the lines in Visual mode, and use: >
+
+	:s/2001/2002/g
+
+Now use "gv" to reselect the same text.  It doesn't matter where the cursor
+is.  Then use ":s/2000/2001/g" to make the second change.
+   Obviously, you can repeat these changes several times.
+
+==============================================================================
+*26.2*	Add and subtract
+
+When repeating the change of one number into another, you often have a fixed
+offset.  In the example above, one was added to each year.  Instead of typing
+a substitute command for each year that appears, the CTRL-A command can be
+used.
+   Using the same text as above, search for a year: >
+
+	/19[0-9][0-9]\|20[0-9][0-9]
+
+Now press CTRL-A.  The year will be increased by one:
+
+	The financial results for 2002 are better ~
+	than for 2000.  The income increased by 50%, ~
+	even though 2001 had more rain than 2000. ~
+			2000		2001 ~
+	income		45,403		66,234 ~
+
+Use "n" to find the next year, and press "." to repeat the CTRL-A ("." is a
+bit quicker to type).  Repeat "n" and "." for all years that appear.
+   Hint: set the 'hlsearch' option to see the matches you are going to change,
+then you can look ahead and do it faster.
+
+Adding more than one can be done by prepending the number to CTRL-A.  Suppose
+you have this list:
+
+	1.  item four ~
+	2.  item five ~
+	3.  item six ~
+
+Move the cursor to "1." and type: >
+
+	3 CTRL-A
+
+The "1." will change to "4.".  Again, you can use "." to repeat this on the
+other numbers.
+
+Another example:
+
+	006	foo bar ~
+	007	foo bar ~
+
+Using CTRL-A on these numbers results in:
+
+	007	foo bar ~
+	010	foo bar ~
+
+7 plus one is 10?  What happened here is that Vim recognized "007" as an octal
+number, because there is a leading zero.  This notation is often used in C
+programs.  If you do not want a number with leading zeros to be handled as
+octal, use this: >
+
+	:set nrformats-=octal
+
+The CTRL-X command does subtraction in a similar way.
+
+==============================================================================
+*26.3*	Making a change in many files
+
+Suppose you have a variable called "x_cnt" and you want to change it to
+"x_counter".  This variable is used in several of your C files.  You need to
+change it in all files.  This is how you do it.
+   Put all the relevant files in the argument list: >
+
+	:args *.c
+<
+This finds all C files and edits the first one.  Now you can perform a
+substitution command on all these files: >
+
+	:argdo %s/\<x_cnt\>/x_counter/ge | update
+
+The ":argdo" command takes an argument that is another command.  That command
+will be executed on all files in the argument list.
+   The "%s" substitute command that follows works on all lines.  It finds the
+word "x_cnt" with "\<x_cnt\>".  The "\<" and "\>" are used to match the whole
+word only, and not "px_cnt" or "x_cnt2".
+   The flags for the substitute command include "g" to replace all occurrences
+of "x_cnt" in the same line.  The "e" flag is used to avoid an error message
+when "x_cnt" does not appear in the file.  Otherwise ":argdo" would abort on
+the first file where "x_cnt" was not found.
+   The "|" separates two commands.  The following "update" command writes the
+file only if it was changed.  If no "x_cnt" was changed to "x_counter" nothing
+happens.
+
+There is also the ":windo" command, which executes its argument in all
+windows.  And ":bufdo" executes its argument on all buffers.  Be careful with
+this, because you might have more files in the buffer list than you think.
+Check this with the ":buffers" command (or ":ls").
+
+==============================================================================
+*26.4*	Using Vim from a shell script
+
+Suppose you have a lot of files in which you need to change the string
+"-person-" to "Jones" and then print it.  How do you do that?  One way is to
+do a lot of typing.  The other is to write a shell script to do the work.
+   The Vim editor does a superb job as a screen-oriented editor when using
+Normal mode commands.  For batch processing, however, Normal mode commands do
+not result in clear, commented command files; so here you will use Ex mode
+instead.  This mode gives you a nice command-line interface that makes it easy
+to put into a batch file.  ("Ex command" is just another name for a
+command-line (:) command.)
+   The Ex mode commands you need are as follows: >
+
+	%s/-person-/Jones/g
+	write tempfile
+	quit
+
+You put these commands in the file "change.vim".  Now to run the editor in
+batch mode, use this shell script: >
+
+	for file in *.txt; do
+	  vim -e -s $file < change.vim
+	  lpr -r tempfile
+	done
+
+The for-done loop is a shell construct to repeat the two lines in between,
+while the $file variable is set to a different file name each time.
+   The second line runs the Vim editor in Ex mode (-e argument) on the file
+$file and reads commands from the file "change.vim".  The -s argument tells
+Vim to operate in silent mode.  In other words, do not keep outputting the
+:prompt, or any other prompt for that matter.
+   The "lpr -r tempfile" command prints the resulting "tempfile" and deletes
+it (that's what the -r argument does).
+
+
+READING FROM STDIN
+
+Vim can read text on standard input.  Since the normal way is to read commands
+there, you must tell Vim to read text instead.  This is done by passing the
+"-" argument in place of a file.  Example: >
+
+	ls | vim -
+
+This allows you to edit the output of the "ls" command, without first saving
+the text in a file.
+   If you use the standard input to read text from, you can use the "-S"
+argument to read a script: >
+
+	producer | vim -S change.vim -
+
+
+NORMAL MODE SCRIPTS
+
+If you really want to use Normal mode commands in a script, you can use it
+like this: >
+
+	vim -s script file.txt ...
+<
+	Note:
+	"-s" has a different meaning when it is used without "-e".  Here it
+	means to source the "script" as Normal mode commands.  When used with
+	"-e" it means to be silent, and doesn't use the next argument as a
+	file name.
+
+The commands in "script" are executed like you typed them.  Don't forget that
+a line break is interpreted as pressing <Enter>.  In Normal mode that moves
+the cursor to the next line.
+   To create the script you can edit the script file and type the commands.
+You need to imagine what the result would be, which can be a bit difficult.
+Another way is to record the commands while you perform them manually.  This
+is how you do that: >
+
+	vim -w script file.txt ...
+
+All typed keys will be written to "script".  If you make a small mistake you
+can just continue and remember to edit the script later.
+   The "-w" argument appends to an existing script.  That is good when you
+want to record the script bit by bit.  If you want to start from scratch and
+start all over, use the "-W" argument.  It overwrites any existing file.
+
+==============================================================================
+
+Next chapter: |usr_27.txt|  Search commands and patterns
+
+Copyright: see |manual-copyright|  vim:tw=78:ts=8:ft=help:norl:
--- /dev/null
+++ b/lib/vimfiles/doc/usr_27.txt
@@ -1,0 +1,563 @@
+*usr_27.txt*	For Vim version 7.1.  Last change: 2006 Apr 24
+
+		     VIM USER MANUAL - by Bram Moolenaar
+
+			 Search commands and patterns
+
+
+In chapter 3 a few simple search patterns were mentioned |03.9|.  Vim can do
+much more complex searches.  This chapter explains the most often used ones.
+A detailed specification can be found here: |pattern|
+
+|27.1|	Ignoring case
+|27.2|	Wrapping around the file end
+|27.3|	Offsets
+|27.4|	Matching multiple times
+|27.5|	Alternatives
+|27.6|	Character ranges
+|27.7|	Character classes
+|27.8|	Matching a line break
+|27.9|	Examples
+
+     Next chapter: |usr_28.txt|  Folding
+ Previous chapter: |usr_26.txt|  Repeating
+Table of contents: |usr_toc.txt|
+
+==============================================================================
+*27.1*	Ignoring case
+
+By default, Vim's searches are case sensitive.  Therefore, "include",
+"INCLUDE", and "Include" are three different words and a search will match
+only one of them.
+   Now switch on the 'ignorecase' option: >
+
+	:set ignorecase
+
+Search for "include" again, and now it will match "Include", "INCLUDE" and
+"InClUDe".  (Set the 'hlsearch' option to quickly see where a pattern
+matches.)
+   You can switch this off again with: >
+
+	:set noignorecase
+
+But lets keep it set, and search for "INCLUDE".  It will match exactly the
+same text as "include" did.  Now set the 'smartcase' option: >
+
+	:set ignorecase smartcase
+
+If you have a pattern with at least one uppercase character, the search
+becomes case sensitive.  The idea is that you didn't have to type that
+uppercase character, so you must have done it because you wanted case to
+match.  That's smart!
+    With these two options set you find the following matches:
+
+	pattern			matches	~
+	word			word, Word, WORD, WoRd, etc.
+	Word			Word
+	WORD			WORD
+	WoRd			WoRd
+
+
+CASE IN ONE PATTERN
+
+If you want to ignore case for one specific pattern, you can do this by
+prepending the "\c" string.  Using "\C" will make the pattern to match case.
+This overrules the 'ignorecase' and 'smartcase' options, when "\c" or "\C" is
+used their value doesn't matter.
+
+	pattern			matches	~
+	\Cword			word
+	\CWord			Word
+	\cword			word, Word, WORD, WoRd, etc.
+	\cWord			word, Word, WORD, WoRd, etc.
+
+A big advantage of using "\c" and "\C" is that it sticks with the pattern.
+Thus if you repeat a pattern from the search history, the same will happen, no
+matter if 'ignorecase' or 'smartcase' was changed.
+
+	Note:
+	The use of "\" items in search patterns depends on the 'magic' option.
+	In this chapters we will assume 'magic' is on, because that is the
+	standard and recommended setting.  If you would change 'magic', many
+	search patterns would suddenly become invalid.
+
+	Note:
+	If your search takes much longer than you expected, you can interrupt
+	it with CTRL-C on Unix and  CTRL-Break on MS-DOS and MS-Windows.
+
+==============================================================================
+*27.2*	Wrapping around the file end
+
+By default, a forward search starts searching for the given string at the
+current cursor location.  It then proceeds to the end of the file.  If it has
+not found the string by that time, it starts from the beginning and searches
+from the start of the file to the cursor location.
+   Keep in mind that when repeating the "n" command to search for the next
+match, you eventually get back to the first match.  If you don't notice this
+you keep searching forever!  To give you a hint, Vim displays this message:
+
+	search hit BOTTOM, continuing at TOP ~
+
+If you use the "?" command, to search in the other direction, you get this
+message:
+
+	search hit TOP, continuing at BOTTOM ~
+
+Still, you don't know when you are back at the first match.  One way to see
+this is by switching on the 'ruler' option: >
+
+	:set ruler
+
+Vim will display the cursor position in the lower righthand corner of the
+window (in the status line if there is one).  It looks like this:
+
+	101,29       84% ~
+
+The first number is the line number of the cursor.  Remember the line number
+where you started, so that you can check if you passed this position again.
+
+
+NOT WRAPPING
+
+To turn off search wrapping, use the following command: >
+
+	:set nowrapscan
+
+Now when the search hits the end of the file, an error message displays:
+
+	E385: search hit BOTTOM without match for: forever ~
+
+Thus you can find all matches by going to the start of the file with "gg" and
+keep searching until you see this message.
+   If you search in the other direction, using "?", you get:
+
+	E384: search hit TOP without match for: forever ~
+
+==============================================================================
+*27.3*	Offsets
+
+By default, the search command leaves the cursor positioned on the beginning
+of the pattern.  You can tell Vim to leave it some other place by specifying
+an offset.  For the forward search command "/", the offset is specified by
+appending a slash (/) and the offset: >
+
+	/default/2
+
+This command searches for the pattern "default" and then moves to the
+beginning of the second line past the pattern.  Using this command on the
+paragraph above, Vim finds the word "default" in the first line.  Then the
+cursor is moved two lines down and lands on "an offset".
+
+If the offset is a simple number, the cursor will be placed at the beginning
+of the line that many lines from the match.  The offset number can be positive
+or negative.  If it is positive, the cursor moves down that many lines; if
+negative, it moves up.
+
+
+CHARACTER OFFSETS
+
+The "e" offset indicates an offset from the end of the match.  It moves the
+cursor onto the last character of the match.  The command: >
+
+	/const/e
+
+puts the cursor on the "t" of "const".
+   From that position, adding a number moves forward that many characters.
+This command moves to the character just after the match: >
+
+	/const/e+1
+
+A positive number moves the cursor to the right, a negative number moves it to
+the left.  For example: >
+
+	/const/e-1
+
+moves the cursor to the "s" of "const".
+
+If the offset begins with "b", the cursor moves to the beginning of the
+pattern.  That's not very useful, since leaving out the "b" does the same
+thing.  It does get useful when a number is added or subtracted.  The cursor
+then goes forward or backward that many characters.  For example: >
+
+	/const/b+2
+
+Moves the cursor to the beginning of the match and then two characters to the
+right.  Thus it lands on the "n".
+
+
+REPEATING
+
+To repeat searching for the previously used search pattern, but with a
+different offset, leave out the pattern: >
+
+	/that
+	//e
+
+Is equal to: >
+
+	/that/e
+
+To repeat with the same offset: >
+
+	/
+
+"n" does the same thing.  To repeat while removing a previously used offset: >
+
+	//
+
+
+SEARCHING BACKWARDS
+
+The "?" command uses offsets in the same way, but you must use "?" to separate
+the offset from the pattern, instead of "/": >
+
+	?const?e-2
+
+The "b" and "e" keep their meaning, they don't change direction with the use
+of "?".
+
+
+START POSITION
+
+When starting a search, it normally starts at the cursor position.  When you
+specify a line offset, this can cause trouble.  For example: >
+
+	/const/-2
+
+This finds the next word "const" and then moves two lines up.  If you
+use "n" to search again, Vim could start at the current position and find the same
+"const" match.  Then using the offset again, you would be back where you started.
+You would be stuck!
+   It could be worse: Suppose there is another match with "const" in the next
+line.  Then repeating the forward search would find this match and move two
+lines up.  Thus you would actually move the cursor back!
+
+When you specify a character offset, Vim will compensate for this.  Thus the
+search starts a few characters forward or backward, so that the same match
+isn't found again.
+
+==============================================================================
+*27.4*	Matching multiple times
+
+The "*" item specifies that the item before it can match any number of times.
+Thus: >
+
+	/a*
+
+matches "a", "aa", "aaa", etc.  But also "" (the empty string), because zero
+times is included.
+   The "*" only applies to the item directly before it.  Thus "ab*" matches
+"a", "ab", "abb", "abbb", etc.  To match a whole string multiple times, it
+must be grouped into one item.  This is done by putting "\(" before it and
+"\)" after it.  Thus this command: >
+
+	/\(ab\)*
+
+Matches: "ab", "abab", "ababab", etc.  And also "".
+
+To avoid matching the empty string, use "\+".  This makes the previous item
+match one or more times. >
+
+	/ab\+
+
+Matches "ab", "abb", "abbb", etc.  It does not match "a" when no "b" follows.
+
+To match an optional item, use "\=".  Example: >
+
+	/folders\=
+
+Matches "folder" and "folders".
+
+
+SPECIFIC COUNTS
+
+To match a specific number of items use the form "\{n,m}".  "n" and "m" are
+numbers.  The item before it will be matched "n" to "m" times |inclusive|.
+Example: >
+
+	/ab\{3,5}
+
+matches "abbb", "abbbb" and "abbbbb".
+  When "n" is omitted, it defaults to zero.  When "m" is omitted it defaults
+to infinity.  When ",m" is omitted, it matches exactly "n" times.
+Examples:
+
+	pattern		match count ~
+	\{,4}		0, 1, 2, 3 or 4
+	\{3,}		3, 4, 5, etc.
+	\{0,1}		0 or 1, same as \=
+	\{0,}		0 or more, same as *
+	\{1,}		1 or more, same as \+
+	\{3}		3
+
+
+MATCHING AS LITTLE AS POSSIBLE
+
+The items so far match as many characters as they can find.  To match as few
+as possible, use "\{-n,m}".  It works the same as "\{n,m}", except that the
+minimal amount possible is used.
+   For example, use: >
+
+	/ab\{-1,3}
+
+Will match "ab" in "abbb".  Actually, it will never match more than one b,
+because there is no reason to match more.  It requires something else to force
+it to match more than the lower limit.
+   The same rules apply to removing "n" and "m".  It's even possible to remove
+both of the numbers, resulting in "\{-}".  This matches the item before it
+zero or more times, as few as possible.  The item by itself always matches
+zero times.  It is useful when combined with something else.  Example: >
+
+	/a.\{-}b
+
+This matches "axb" in "axbxb".  If this pattern would be used: >
+
+	/a.*b
+
+It would try to match as many characters as possible with ".*", thus it
+matches "axbxb" as a whole.
+
+==============================================================================
+*27.5*	Alternatives
+
+The "or" operator in a pattern is "\|".  Example: >
+
+	/foo\|bar
+
+This matches "foo" or "bar".  More alternatives can be concatenated: >
+
+	/one\|two\|three
+
+Matches "one", "two" and "three".
+   To match multiple times, the whole thing must be placed in "\(" and "\)": >
+
+	/\(foo\|bar\)\+
+
+This matches "foo", "foobar", "foofoo", "barfoobar", etc.
+   Another example: >
+
+	/end\(if\|while\|for\)
+
+This matches "endif", "endwhile" and "endfor".
+
+A related item is "\&".  This requires that both alternatives match in the
+same place.  The resulting match uses the last alternative.  Example: >
+
+	/forever\&...
+
+This matches "for" in "forever".  It will not match "fortuin", for example.
+
+==============================================================================
+*27.6*	Character ranges
+
+To match "a", "b" or "c" you could use "/a\|b\|c".  When you want to match all
+letters from "a" to "z" this gets very long.  There is a shorter method: >
+
+	/[a-z]
+
+The [] construct matches a single character.  Inside you specify which
+characters to match.  You can include a list of characters, like this: >
+
+	/[0123456789abcdef]
+
+This will match any of the characters included.  For consecutive characters
+you can specify the range.  "0-3" stands for "0123".  "w-z" stands for "wxyz".
+Thus the same command as above can be shortened to: >
+
+	/[0-9a-f]
+
+To match the "-" character itself make it the first or last one in the range.
+These special characters are accepted to make it easier to use them inside a
+[] range (they can actually be used anywhere in the search pattern):
+
+	\e	<Esc>
+	\t	<Tab>
+	\r	<CR>
+	\b	<BS>
+
+There are a few more special cases for [] ranges, see |/[]| for the whole
+story.
+
+
+COMPLEMENTED RANGE
+
+To avoid matching a specific character, use "^" at the start of the range.
+The [] item then matches everything but the characters included.  Example: >
+
+	/"[^"]*"
+<
+	 "	  a double quote
+	  [^"]	  any character that is not a double quote
+	      *	  as many as possible
+	       "  a double quote again
+
+This matches "foo" and "3!x", including the double quotes.
+
+
+PREDEFINED RANGES
+
+A number of ranges are used very often.  Vim provides a shortcut for these.
+For example: >
+
+	/\a
+
+Finds alphabetic characters.  This is equal to using "/[a-zA-Z]".  Here are a
+few more of these:
+
+	item	matches			equivalent ~
+	\d	digit			[0-9]
+	\D	non-digit		[^0-9]
+	\x	hex digit		[0-9a-fA-F]
+	\X	non-hex digit		[^0-9a-fA-F]
+	\s	white space		[ 	]     (<Tab> and <Space>)
+	\S	non-white characters	[^ 	]     (not <Tab> and <Space>)
+	\l	lowercase alpha		[a-z]
+	\L	non-lowercase alpha	[^a-z]
+	\u	uppercase alpha		[A-Z]
+	\U	non-uppercase alpha	[^A-Z]
+
+	Note:
+	Using these predefined ranges works a lot faster than the character
+	range it stands for.
+	These items can not be used inside [].  Thus "[\d\l]" does NOT work to
+	match a digit or lowercase alpha.  Use "\(\d\|\l\)" instead.
+
+See |/\s| for the whole list of these ranges.
+
+==============================================================================
+*27.7*	Character classes
+
+The character range matches a fixed set of characters.  A character class is
+similar, but with an essential difference: The set of characters can be
+redefined without changing the search pattern.
+   For example, search for this pattern: >
+
+	/\f\+
+
+The "\f" items stands for file name characters.  Thus this matches a sequence
+of characters that can be a file name.
+   Which characters can be part of a file name depends on the system you are
+using.  On MS-Windows, the backslash is included, on Unix it is not.  This is
+specified with the 'isfname' option.  The default value for Unix is: >
+
+	:set isfname
+	isfname=@,48-57,/,.,-,_,+,,,#,$,%,~,=
+
+For other systems the default value is different.  Thus you can make a search
+pattern with "\f" to match a file name, and it will automatically adjust to
+the system you are using it on.
+
+	Note:
+	Actually, Unix allows using just about any character in a file name,
+	including white space.  Including these characters in 'isfname' would
+	be theoretically correct.  But it would make it impossible to find the
+	end of a file name in text.  Thus the default value of 'isfname' is a
+	compromise.
+
+The character classes are:
+
+	item	matches				option ~
+	\i	identifier characters		'isident'
+	\I	like \i, excluding digits
+	\k	keyword characters		'iskeyword'
+	\K	like \k, excluding digits
+	\p	printable characters		'isprint'
+	\P	like \p, excluding digits
+	\f	file name characters		'isfname'
+	\F	like \f, excluding digits
+
+==============================================================================
+*27.8*	Matching a line break
+
+Vim can find a pattern that includes a line break.  You need to specify where
+the line break happens, because all items mentioned so far don't match a line
+break.
+   To check for a line break in a specific place, use the "\n" item: >
+
+	/the\nword
+
+This will match at a line that ends in "the" and the next line starts with
+"word".  To match "the word" as well, you need to match a space or a line
+break.  The item to use for it is "\_s": >
+
+	/the\_sword
+
+To allow any amount of white space: >
+
+	/the\_s\+word
+
+This also matches when "the  " is at the end of a line and "   word" at the
+start of the next one.
+
+"\s" matches white space, "\_s" matches white space or a line break.
+Similarly, "\a" matches an alphabetic character, and "\_a" matches an
+alphabetic character or a line break.  The other character classes and ranges
+can be modified in the same way by inserting a "_".
+
+Many other items can be made to match a line break by prepending "\_".  For
+example: "\_." matches any character or a line break.
+
+	Note:
+	"\_.*" matches everything until the end of the file.  Be careful with
+	this, it can make a search command very slow.
+
+Another example is "\_[]", a character range that includes a line break: >
+
+	/"\_[^"]*"
+
+This finds a text in double quotes that may be split up in several lines.
+
+==============================================================================
+*27.9*	Examples
+
+Here are a few search patterns you might find useful.  This shows how the
+items mentioned above can be combined.
+
+
+FINDING A CALIFORNIA LICENSE PLATE
+
+A sample license place number is "1MGU103".  It has one digit, three uppercase
+letters and three digits.  Directly putting this into a search pattern: >
+
+	/\d\u\u\u\d\d\d
+
+Another way is to specify that there are three digits and letters with a
+count: >
+
+	/\d\u\{3}\d\{3}
+
+Using [] ranges instead: >
+
+	/[0-9][A-Z]\{3}[0-9]\{3}
+
+Which one of these you should use?  Whichever one you can remember.  The
+simple way you can remember is much faster than the fancy way that you can't.
+If you can remember them all, then avoid the last one, because it's both more
+typing and slower to execute.
+
+
+FINDING AN IDENTIFIER
+
+In C programs (and many other computer languages) an identifier starts with a
+letter and further consists of letters and digits.  Underscores can be used
+too.  This can be found with: >
+
+	/\<\h\w*\>
+
+"\<" and "\>" are used to find only whole words.  "\h" stands for "[A-Za-z_]"
+and "\w" for "[0-9A-Za-z_]".
+
+	Note:
+	"\<" and "\>" depend on the 'iskeyword' option.  If it includes "-",
+	for example, then "ident-" is not matched.  In this situation use: >
+
+		/\w\@<!\h\w*\w\@!
+<
+	This checks if "\w" does not match before or after the identifier.
+	See |/\@<!| and |/\@!|.
+
+==============================================================================
+
+Next chapter: |usr_28.txt|  Folding
+
+Copyright: see |manual-copyright|  vim:tw=78:ts=8:ft=help:norl:
--- /dev/null
+++ b/lib/vimfiles/doc/usr_28.txt
@@ -1,0 +1,426 @@
+*usr_28.txt*	For Vim version 7.1.  Last change: 2006 Apr 24
+
+		     VIM USER MANUAL - by Bram Moolenaar
+
+				   Folding
+
+
+Structured text can be separated in sections.  And sections in sub-sections.
+Folding allows you to display a section as one line, providing an overview.
+This chapter explains the different ways this can be done.
+
+|28.1|	What is folding?
+|28.2|	Manual folding
+|28.3|	Working with folds
+|28.4|	Saving and restoring folds
+|28.5|	Folding by indent
+|28.6|	Folding with markers
+|28.7|	Folding by syntax
+|28.8|	Folding by expression
+|28.9|	Folding unchanged lines
+|28.10| Which fold method to use?
+
+     Next chapter: |usr_29.txt|  Moving through programs
+ Previous chapter: |usr_27.txt|  Search commands and patterns
+Table of contents: |usr_toc.txt|
+
+==============================================================================
+*28.1*	What is folding?
+
+Folding is used to show a range of lines in the buffer as a single line on the
+screen.  Like a piece of paper which is folded to make it shorter:
+
+	+------------------------+
+	| line 1		 |
+	| line 2		 |
+	| line 3		 |
+	|_______________________ |
+	\			 \
+	 \________________________\
+	 / folded lines		  /
+	/________________________/
+	| line 12		 |
+	| line 13		 |
+	| line 14		 |
+	+------------------------+
+
+The text is still in the buffer, unchanged.  Only the way lines are displayed
+is affected by folding.
+
+The advantage of folding is that you can get a better overview of the
+structure of text, by folding lines of a section and replacing it with a line
+that indicates that there is a section.
+
+==============================================================================
+*28.2*	Manual folding
+
+Try it out: Position the cursor in a paragraph and type: >
+
+	zfap
+
+You will see that the paragraph is replaced by a highlighted line.  You have
+created a fold.  |zf| is an operator and |ap| a text object selection.  You
+can use the |zf| operator with any movement command to create a fold for the
+text that it moved over.  |zf| also works in Visual mode.
+
+To view the text again, open the fold by typing: >
+
+	zo
+
+And you can close the fold again with: >
+
+	zc
+
+All the folding commands start with "z".  With some fantasy, this looks like a
+folded piece of paper, seen from the side.  The letter after the "z" has a
+mnemonic meaning to make it easier to remember the commands:
+
+	zf	F-old creation
+	zo	O-pen a fold
+	zc	C-lose a fold
+
+Folds can be nested: A region of text that contains folds can be folded
+again.  For example, you can fold each paragraph in this section, and then
+fold all the sections in this chapter.  Try it out.  You will notice that
+opening the fold for the whole chapter will restore the nested folds as they
+were, some may be open and some may be closed.
+
+Suppose you have created several folds, and now want to view all the text.
+You could go to each fold and type "zo".  To do this faster, use this command: >
+
+	zr
+
+This will R-educe the folding.  The opposite is: >
+
+	zm
+
+This folds M-ore.  You can repeat "zr" and "zm" to open and close nested folds
+of several levels.
+
+If you have nested several levels deep, you can open all of them with: >
+
+	zR
+
+This R-educes folds until there are none left.  And you can close all folds
+with: >
+
+	zM
+
+This folds M-ore and M-ore.
+
+You can quickly disable the folding with the |zn| command.  Then |zN| brings
+back the folding as it was.  |zi| toggles between the two.  This is a useful
+way of working:
+- create folds to get overview on your file
+- move around to where you want to do your work
+- do |zi| to look at the text and edit it
+- do |zi| again to go back to moving around
+
+More about manual folding in the reference manual: |fold-manual|
+
+==============================================================================
+*28.3*	Working with folds
+
+When some folds are closed, movement commands like "j" and "k" move over a
+fold like it was a single, empty line.  This allows you to quickly move around
+over folded text.
+
+You can yank, delete and put folds as if it was a single line.  This is very
+useful if you want to reorder functions in a program.  First make sure that
+each fold contains a whole function (or a bit less) by selecting the right
+'foldmethod'.  Then delete the function with "dd", move the cursor and put it
+with "p".  If some lines of the function are above or below the fold, you can
+use Visual selection:
+- put the cursor on the first line to be moved
+- hit "V" to start Visual mode
+- put the cursor on the last line to be moved
+- hit "d" to delete the selected lines.
+- move the cursor to the new position and "p"ut the lines there.
+
+It is sometimes difficult to see or remember where a fold is located, thus
+where a |zo| command would actually work.  To see the defined folds: >
+
+	:set foldcolumn=4
+
+This will show a small column on the left of the window to indicate folds.
+A "+" is shown for a closed fold.  A "-" is shown at the start of each open
+fold and "|" at following lines of the fold.
+
+You can use the mouse to open a fold by clicking on the "+" in the foldcolumn.
+Clicking on the "-" or a "|" below it will close an open fold.
+
+To open all folds at the cursor line use |zO|.
+To close all folds at the cursor line use |zC|.
+To delete a fold at the cursor line use |zd|.
+To delete all folds at the cursor line use |zD|.
+
+When in Insert mode, the fold at the cursor line is never closed.  That allows
+you to see what you type!
+
+Folds are opened automatically when jumping around or moving the cursor left
+or right.  For example, the "0" command opens the fold under the cursor
+(if 'foldopen' contains "hor", which is the default).  The 'foldopen' option
+can be changed to open folds for specific commands.  If you want the line
+under the cursor always to be open, do this: >
+
+	:set foldopen=all
+
+Warning: You won't be able to move onto a closed fold then.  You might want to
+use this only temporarily and then set it back to the default: >
+
+	:set foldopen&
+
+You can make folds close automatically when you move out of it: >
+
+	:set foldclose=all
+
+This will re-apply 'foldlevel' to all folds that don't contain the cursor.
+You have to try it out if you like how this feels.  Use |zm| to fold more and
+|zr| to fold less (reduce folds).
+
+The folding is local to the window.  This allows you to open two windows on
+the same buffer, one with folds and one without folds.  Or one with all folds
+closed and one with all folds open.
+
+==============================================================================
+*28.4*	Saving and restoring folds
+
+When you abandon a file (starting to edit another one), the state of the folds
+is lost.  If you come back to the same file later, all manually opened and
+closed folds are back to their default.  When folds have been created
+manually, all folds are gone!  To save the folds use the |:mkview| command: >
+
+	:mkview
+
+This will store the settings and other things that influence the view on the
+file.  You can change what is stored with the 'viewoptions' option.
+When you come back to the same file later, you can load the view again: >
+
+	:loadview
+
+You can store up to ten views on one file.  For example, to save the current
+setup as the third view and load the second view: >
+
+	:mkview 3
+	:loadview 2
+
+Note that when you insert or delete lines the views might become invalid.
+Also check out the 'viewdir' option, which specifies where the views are
+stored.  You might want to delete old views now and then.
+
+==============================================================================
+*28.5*	Folding by indent
+
+Defining folds with |zf| is a lot of work.  If your text is structured by
+giving lower level items a larger indent, you can use the indent folding
+method.  This will create folds for every sequence of lines with the same
+indent.  Lines with a larger indent will become nested folds.  This works well
+with many programming languages.
+
+Try this by setting the 'foldmethod' option: >
+
+	:set foldmethod=indent
+
+Then you can use the |zm| and |zr| commands to fold more and reduce folding.
+It's easy to see on this example text:
+
+This line is not indented
+	This line is indented once
+		This line is indented twice
+		This line is indented twice
+	This line is indented once
+This line is not indented
+	This line is indented once
+	This line is indented once
+
+Note that the relation between the amount of indent and the fold depth depends
+on the 'shiftwidth' option.  Each 'shiftwidth' worth of indent adds one to the
+depth of the fold.  This is called a fold level.
+
+When you use the |zr| and |zm| commands you actually increase or decrease the
+'foldlevel' option.  You could also set it directly: >
+
+	:set foldlevel=3
+
+This means that all folds with three times a 'shiftwidth' indent or more will
+be closed.  The lower the foldlevel, the more folds will be closed.  When
+'foldlevel' is zero, all folds are closed.  |zM| does set 'foldlevel' to zero.
+The opposite command |zR| sets 'foldlevel' to the deepest fold level that is
+present in the file.
+
+Thus there are two ways to open and close the folds:
+(A) By setting the fold level.
+    This gives a very quick way of "zooming out" to view the structure of the
+    text, move the cursor, and "zoom in" on the text again.
+
+(B) By using |zo| and |zc| commands to open or close specific folds.
+    This allows opening only those folds that you want to be open, while other
+    folds remain closed.
+
+This can be combined: You can first close most folds by using |zm| a few times
+and then open a specific fold with |zo|.  Or open all folds with |zR| and
+then close specific folds with |zc|.
+
+But you cannot manually define folds when 'foldmethod' is "indent", as that
+would conflict with the relation between the indent and the fold level.
+
+More about folding by indent in the reference manual: |fold-indent|
+
+==============================================================================
+*28.6*	Folding with markers
+
+Markers in the text are used to specify the start and end of a fold region.
+This gives precise control over which lines are included in a fold.  The
+disadvantage is that the text needs to be modified.
+
+Try it: >
+
+	:set foldmethod=marker
+
+Example text, as it could appear in a C program:
+
+	/* foobar () {{{ */
+	int foobar()
+	{
+		/* return a value {{{ */
+		return 42;
+		/* }}} */
+	}
+	/* }}} */
+
+Notice that the folded line will display the text before the marker.  This is
+very useful to tell what the fold contains.
+
+It's quite annoying when the markers don't pair up correctly after moving some
+lines around.  This can be avoided by using numbered markers.  Example:
+
+	/* global variables {{{1 */
+	int varA, varB;
+
+	/* functions {{{1 */
+	/* funcA() {{{2 */
+	void funcA() {}
+
+	/* funcB() {{{2 */
+	void funcB() {}
+	/* }}}1 */
+
+At every numbered marker a fold at the specified level begins.  This will make
+any fold at a higher level stop here.  You can just use numbered start markers
+to define all folds.  Only when you want to explicitly stop a fold before
+another starts you need to add an end marker.
+
+More about folding with markers in the reference manual: |fold-marker|
+
+==============================================================================
+*28.7*	Folding by syntax
+
+For each language Vim uses a different syntax file.  This defines the colors
+for various items in the file.  If you are reading this in Vim, in a terminal
+that supports colors, the colors you see are made with the "help" syntax file.
+   In the syntax files it is possible to add syntax items that have the "fold"
+argument.  These define a fold region.  This requires writing a syntax file
+and adding these items in it.  That's not so easy to do.  But once it's done,
+all folding happens automatically.
+   Here we'll assume you are using an existing syntax file.  Then there is
+nothing more to explain.  You can open and close folds as explained above.
+The folds will be created and deleted automatically when you edit the file.
+
+More about folding by syntax in the reference manual: |fold-syntax|
+
+==============================================================================
+*28.8*	Folding by expression
+
+This is similar to folding by indent, but instead of using the indent of a
+line a user function is called to compute the fold level of a line.  You can
+use this for text where something in the text indicates which lines belong
+together.  An example is an e-mail message where the quoted text is indicated
+by a ">" before the line.  To fold these quotes use this: >
+
+	:set foldmethod=expr
+	:set foldexpr=strlen(substitute(substitute(getline(v:lnum),'\\s','',\"g\"),'[^>].*','',''))
+
+You can try it out on this text:
+
+> quoted text he wrote
+> quoted text he wrote
+> > double quoted text I wrote
+> > double quoted text I wrote
+
+Explanation for the 'foldexpr' used in the example (inside out):
+   getline(v:lnum)			gets the current line
+   substitute(...,'\\s','','g')		removes all white space from the line
+   substitute(...,'[^>].*','','')	removes everything after leading '>'s
+   strlen(...)				counts the length of the string, which
+					is the number of '>'s found
+
+Note that a backslash must be inserted before every space, double quote and
+backslash for the ":set" command.  If this confuses you, do >
+
+	:set foldexpr
+
+to check the actual resulting value.  To correct a complicated expression, use
+the command-line completion: >
+
+	:set foldexpr=<Tab>
+
+Where <Tab> is a real Tab.  Vim will fill in the previous value, which you can
+then edit.
+
+When the expression gets more complicated you should put it in a function and
+set 'foldexpr' to call that function.
+
+More about folding by expression in the reference manual: |fold-expr|
+
+==============================================================================
+*28.9*	Folding unchanged lines
+
+This is useful when you set the 'diff' option in the same window.  The
+|vimdiff| command does this for you.  Example: >
+
+	setlocal diff foldmethod=diff scrollbind nowrap foldlevel=1
+
+Do this in every window that shows a different version of the same file.  You
+will clearly see the differences between the files, while the text that didn't
+change is folded.
+
+For more details see |fold-diff|.
+
+==============================================================================
+*28.10* Which fold method to use?
+
+All these possibilities makes you wonder which method you should chose.
+Unfortunately, there is no golden rule.  Here are some hints.
+
+If there is a syntax file with folding for the language you are editing, that
+is probably the best choice.  If there isn't one, you might try to write it.
+This requires a good knowledge of search patterns.  It's not easy, but when
+it's working you will not have to define folds manually.
+
+Typing commands to manually fold regions can be used for unstructured text.
+Then use the |:mkview| command to save and restore your folds.
+
+The marker method requires you to change the file.  If you are sharing the
+files with other people or you have to meet company standards, you might not
+be allowed to add them.
+   The main advantage of markers is that you can put them exactly where you
+want them.  That avoids that a few lines are missed when you cut and paste
+folds.  And you can add a comment about what is contained in the fold.
+
+Folding by indent is something that works in many files, but not always very
+well.  Use it when you can't use one of the other methods.  However, it is
+very useful for outlining.  Then you specifically use one 'shiftwidth' for
+each nesting level.
+
+Folding with expressions can make folds in almost any structured text.  It is
+quite simple to specify, especially if the start and end of a fold can easily
+be recognized.
+   If you use the "expr" method to define folds, but they are not exactly how
+you want them, you could switch to the "manual" method.  This will not remove
+the defined folds.  Then you can delete or add folds manually.
+
+==============================================================================
+
+Next chapter: |usr_29.txt|  Moving through programs
+
+Copyright: see |manual-copyright|  vim:tw=78:ts=8:ft=help:norl:
--- /dev/null
+++ b/lib/vimfiles/doc/usr_29.txt
@@ -1,0 +1,613 @@
+*usr_29.txt*	For Vim version 7.1.  Last change: 2006 Apr 24
+
+		     VIM USER MANUAL - by Bram Moolenaar
+
+			    Moving through programs
+
+
+The creator of Vim is a computer programmer.  It's no surprise that Vim
+contains many features to aid in writing programs.  Jump around to find where
+identifiers are defined and used.  Preview declarations in a separate window.
+There is more in the next chapter.
+
+|29.1|	Using tags
+|29.2|	The preview window
+|29.3|	Moving through a program
+|29.4|	Finding global identifiers
+|29.5|	Finding local identifiers
+
+     Next chapter: |usr_30.txt|  Editing programs
+ Previous chapter: |usr_28.txt|  Folding
+Table of contents: |usr_toc.txt|
+
+==============================================================================
+*29.1*	Using tags
+
+What is a tag?  It is a location where an identifier is defined.  An example
+is a function definition in a C or C++ program.  A list of tags is kept in a
+tags file.  This can be used by Vim to directly jump from any place to the
+tag, the place where an identifier is defined.
+   To generate the tags file for all C files in the current directory, use the
+following command: >
+
+	ctags *.c
+
+"ctags" is a separate program.  Most Unix systems already have it installed.
+If you do not have it yet, you can find Exuberant ctags here:
+
+	http://ctags.sf.net ~
+
+Now when you are in Vim and you want to go to a function definition, you can
+jump to it by using the following command: >
+
+	:tag startlist
+
+This command will find the function "startlist" even if it is in another file.
+   The CTRL-] command jumps to the tag of the word that is under the cursor.
+This makes it easy to explore a tangle of C code.  Suppose, for example, that
+you are in the function "write_block".  You can see that it calls
+"write_line".  But what does "write_line" do?  By placing the cursor on the
+call to "write_line" and pressing CTRL-], you jump to the definition of this
+function.
+   The "write_line" function calls "write_char".  You need to figure out what
+it does.  So you position the cursor over the call to "write_char" and press
+CTRL-].  Now you are at the definition of "write_char".
+
+	+-------------------------------------+
+	|void write_block(char **s; int cnt)  |
+	|{				      |
+	|   int i;			      |
+	|   for (i = 0; i < cnt; ++i)	      |
+	|      write_line(s[i]);	      |
+	|}	    |			      |
+	+-----------|-------------------------+
+		    |
+	     CTRL-] |
+		    |	 +----------------------------+
+		    +--> |void write_line(char *s)    |
+			 |{			      |
+			 |   while (*s != 0)	      |
+			 |	write_char(*s++);     |
+			 |}	  |		      |
+			 +--------|-------------------+
+				  |
+			   CTRL-] |
+				  |    +------------------------------------+
+				  +--> |void write_char(char c)		    |
+				       |{				    |
+				       |    putchar((int)(unsigned char)c); |
+				       |}				    |
+				       +------------------------------------+
+
+The ":tags" command shows the list of tags that you traversed through:
+
+	:tags
+	  # TO tag	   FROM line  in file/text ~
+	  1  1 write_line	   8  write_block.c ~
+	  2  1 write_char	   7  write_line.c ~
+	> ~
+>
+Now to go back.  The CTRL-T command goes to the preceding tag.  In the example
+above you get back to the "write_line" function, in the call to "write_char".
+   This command takes a count argument that indicates how many tags to jump
+back.  You have gone forward, and now back.  Let's go forward again.  The
+following command goes to the tag on top of the list: >
+
+	:tag
+
+You can prefix it with a count and jump forward that many tags.  For example:
+":3tag".  CTRL-T also can be preceded with a count.
+   These commands thus allow you to go down a call tree with CTRL-] and back
+up again with CTRL-T.  Use ":tags" to find out where you are.
+
+
+SPLIT WINDOWS
+
+The ":tag" command replaces the file in the current window with the one
+containing the new function.  But suppose you want to see not only the old
+function but also the new one?  You can split the window using the ":split"
+command followed by the ":tag" command.  Vim has a shorthand command that does
+both: >
+	:stag tagname
+
+To split the current window and jump to the tag under the cursor use this
+command: >
+
+	CTRL-W ]
+
+If a count is specified, the new window will be that many lines high.
+
+
+MORE TAGS FILES
+
+When you have files in many directories, you can create a tags file in each of
+them.  Vim will then only be able to jump to tags within that directory.
+   To find more tags files, set the 'tags' option to include all the relevant
+tags files.  Example: >
+
+	:set tags=./tags,./../tags,./*/tags
+
+This finds a tags file in the same directory as the current file, one
+directory level higher and in all subdirectories.
+   This is quite a number of tags files, but it may still not be enough.  For
+example, when editing a file in "~/proj/src", you will not find the tags file
+"~/proj/sub/tags".  For this situation Vim offers to search a whole directory
+tree for tags files.  Example: >
+
+	:set tags=~/proj/**/tags
+
+
+ONE TAGS FILE
+
+When Vim has to search many places for tags files, you can hear the disk
+rattling.  It may get a bit slow.  In that case it's better to spend this
+time while generating one big tags file.  You might do this overnight.
+   This requires the Exuberant ctags program, mentioned above.  It offers an
+argument to search a whole directory tree: >
+
+	cd ~/proj
+	ctags -R .
+
+The nice thing about this is that Exuberant ctags recognizes various file
+types.  Thus this doesn't work just for C and C++ programs, also for Eiffel
+and even Vim scripts.  See the ctags documentation to tune this.
+   Now you only need to tell Vim where your big tags file is: >
+
+	:set tags=~/proj/tags
+
+
+MULTIPLE MATCHES
+
+When a function is defined multiple times (or a method in several classes),
+the ":tag" command will jump to the first one.  If there is a match in the
+current file, that one is used first.
+   You can now jump to other matches for the same tag with: >
+
+	:tnext
+
+Repeat this to find further matches.  If there are many, you can select which
+one to jump to: >
+
+	:tselect tagname
+
+Vim will present you with a list of choices:
+
+	  # pri kind tag	       file ~
+	  1 F	f    mch_init	       os_amiga.c ~
+		       mch_init() ~
+	  2 F	f    mch_init	       os_mac.c ~
+		       mch_init() ~
+	  3 F	f    mch_init	       os_msdos.c ~
+		       mch_init(void) ~
+	  4 F	f    mch_init	       os_riscos.c ~
+		       mch_init() ~
+	Enter nr of choice (<CR> to abort):  ~
+
+You can now enter the number (in the first column) of the match that you would
+like to jump to.  The information in the other columns give you a good idea of
+where the match is defined.
+
+To move between the matching tags, these commands can be used:
+
+	:tfirst			go to first match
+	:[count]tprevious	go to [count] previous match
+	:[count]tnext		go to [count] next match
+	:tlast			go to last match
+
+If [count] is omitted then one is used.
+
+
+GUESSING TAG NAMES
+
+Command line completion is a good way to avoid typing a long tag name.  Just
+type the first bit and press <Tab>: >
+
+	:tag write_<Tab>
+
+You will get the first match.  If it's not the one you want, press <Tab> until
+you find the right one.
+   Sometimes you only know part of the name of a function.  Or you have many
+tags that start with the same string, but end differently.  Then you can tell
+Vim to use a pattern to find the tag.
+   Suppose you want to jump to a tag that contains "block".  First type
+this: >
+
+	:tag /block
+
+Now use command line completion: press <Tab>.  Vim will find all tags that
+contain "block" and use the first match.
+   The "/" before a tag name tells Vim that what follows is not a literal tag
+name, but a pattern.  You can use all the items for search patterns here.  For
+example, suppose you want to select a tag that starts with "write_": >
+
+	:tselect /^write_
+
+The "^" specifies that the tag starts with "write_".  Otherwise it would also
+be found halfway a tag name.  Similarly "$" at the end makes sure the pattern
+matches until the end of a tag.
+
+
+A TAGS BROWSER
+
+Since CTRL-] takes you to the definition of the identifier under the cursor,
+you can use a list of identifier names as a table of contents.  Here is an
+example.
+   First create a list of identifiers (this requires Exuberant ctags): >
+
+	ctags --c-types=f -f functions *.c
+
+Now start Vim without a file, and edit this file in Vim, in a vertically split
+window: >
+
+	vim
+	:vsplit functions
+
+The window contains a list of all the functions.  There is some more stuff,
+but you can ignore that.  Do ":setlocal ts=99" to clean it up a bit.
+   In this window, define a mapping: >
+
+	:nnoremap <buffer> <CR> 0ye<C-W>w:tag <C-R>"<CR>
+
+Move the cursor to the line that contains the function you want to go to.
+Now press <Enter>.  Vim will go to the other window and jump to the selected
+function.
+
+
+RELATED ITEMS
+
+You can set 'ignorecase' to make case in tag names be ignored.
+
+The 'tagbsearch' option tells if the tags file is sorted or not.  The default
+is to assume a sorted tags file, which makes a tags search a lot faster, but
+doesn't work if the tags file isn't sorted.
+
+The 'taglength' option can be used to tell Vim the number of significant
+characters in a tag.
+
+When you use the SNiFF+ program, you can use the Vim interface to it |sniff|.
+SNiFF+ is a commercial program.
+
+Cscope is a free program.  It does not only find places where an identifier is
+declared, but also where it is used.  See |cscope|.
+
+==============================================================================
+*29.2*	The preview window
+
+When you edit code that contains a function call, you need to use the correct
+arguments.  To know what values to pass you can look at how the function is
+defined.  The tags mechanism works very well for this.  Preferably the
+definition is displayed in another window.  For this the preview window can be
+used.
+   To open a preview window to display the function "write_char": >
+
+	:ptag write_char
+
+Vim will open a window, and jumps to the tag "write_char".  Then it takes you
+back to the original position.  Thus you can continue typing without the need
+to use a CTRL-W command.
+   If the name of a function appears in the text, you can get its definition
+in the preview window with: >
+
+	CTRL-W }
+
+There is a script that automatically displays the text where the word under
+the cursor was defined.  See |CursorHold-example|.
+
+To close the preview window use this command: >
+
+	:pclose
+
+To edit a specific file in the preview window, use ":pedit".  This can be
+useful to edit a header file, for example: >
+
+	:pedit defs.h
+
+Finally, ":psearch" can be used to find a word in the current file and any
+included files and display the match in the preview window.  This is
+especially useful when using library functions, for which you do not have a
+tags file.  Example: >
+
+	:psearch popen
+
+This will show the "stdio.h" file in the preview window, with the function
+prototype for popen():
+
+	FILE	*popen __P((const char *, const char *)); ~
+
+You can specify the height of the preview window, when it is opened, with the
+'previewheight' option.
+
+==============================================================================
+*29.3*	Moving through a program
+
+Since a program is structured, Vim can recognize items in it.  Specific
+commands can be used to move around.
+   C programs often contain constructs like this:
+
+	#ifdef USE_POPEN ~
+	    fd = popen("ls", "r") ~
+	#else ~
+	    fd = fopen("tmp", "w") ~
+	#endif ~
+
+But then much longer, and possibly nested.  Position the cursor on the
+"#ifdef" and press %.  Vim will jump to the "#else".  Pressing % again takes
+you to the "#endif".  Another % takes you to the "#ifdef" again.
+   When the construct is nested, Vim will find the matching items.  This is a
+good way to check if you didn't forget an "#endif".
+   When you are somewhere inside a "#if" - "#endif", you can jump to the start
+of it with: >
+
+	[#
+
+If you are not after a "#if" or "#ifdef" Vim will beep.  To jump forward to
+the next "#else" or "#endif" use: >
+
+	]#
+
+These two commands skip any "#if" - "#endif" blocks that they encounter.
+Example:
+
+	#if defined(HAS_INC_H) ~
+	    a = a + inc(); ~
+	# ifdef USE_THEME ~
+	    a += 3; ~
+	# endif ~
+	    set_width(a); ~
+
+With the cursor in the last line, "[#" moves to the first line.  The "#ifdef"
+- "#endif" block in the middle is skipped.
+
+
+MOVING IN CODE BLOCKS
+
+In C code blocks are enclosed in {}.  These can get pretty long.  To move to
+the start of the outer block use the "[[" command.  Use "][" to find the end.
+This assumes that the "{" and "}" are in the first column.
+   The "[{" command moves to the start of the current block.  It skips over
+pairs of {} at the same level.  "]}" jumps to the end.
+   An overview:
+
+			function(int a)
+	   +->		{
+	   |		    if (a)
+	   |	   +->	    {
+	[[ |	   |		for (;;)	       --+
+	   |	   |	  +->	{			 |
+	   |	[{ |	  |	    foo(32);		 |     --+
+	   |	   |   [{ |	    if (bar(a))  --+	 | ]}	 |
+	   +--	   |	  +--		break;	   | ]}  |	 |
+		   |		}		 <-+	 |	 | ][
+		   +--		foobar(a)		 |	 |
+			    }			       <-+	 |
+			}				       <-+
+
+When writing C++ or Java, the outer {} block is for the class.  The next level
+of {} is for a method.  When somewhere inside a class use "[m" to find the
+previous start of a method.  "]m" finds the next end of a method.
+
+Additionally, "[]" moves backward to the end of a function and "]]" moves
+forward to the start of the next function.  The end of a function is defined
+by a "}" in the first column.
+
+				int func1(void)
+				{
+					return 1;
+		  +---------->  }
+		  |
+	      []  |		int func2(void)
+		  |	   +->	{
+		  |    [[  |		if (flag)
+	start	  +--	   +--			return flag;
+		  |    ][  |		return 2;
+		  |	   +->	}
+	      ]]  |
+		  |		int func3(void)
+		  +---------->	{
+					return 3;
+				}
+
+Don't forget you can also use "%" to move between matching (), {} and [].
+That also works when they are many lines apart.
+
+
+MOVING IN BRACES
+
+The "[(" and "])" commands work similar to "[{" and "]}", except that they
+work on () pairs instead of {} pairs.
+>
+				  [(
+<		    <--------------------------------
+			      <-------
+		if (a == b && (c == d || (e > f)) && x > y) ~
+				  -------------->
+			  --------------------------------> >
+				       ])
+
+MOVING IN COMMENTS
+
+To move back to the start of a comment use "[/".  Move forward to the end of a
+comment with "]/".  This only works for /* - */ comments.
+
+	  +->	  +-> /*
+	  |    [/ |    * A comment about      --+
+       [/ |	  +--  * wonderful life.	| ]/
+	  |	       */		      <-+
+	  |
+	  +--	       foo = bar * 3;	      --+
+						| ]/
+		       /* a short comment */  <-+
+
+==============================================================================
+*29.4*	Finding global identifiers
+
+You are editing a C program and wonder if a variable is declared as "int" or
+"unsigned".  A quick way to find this is with the "[I" command.
+   Suppose the cursor is on the word "column".  Type: >
+
+	[I
+
+Vim will list the matching lines it can find.  Not only in the current file,
+but also in all included files (and files included in them, etc.).  The result
+looks like this:
+
+	structs.h ~
+	 1:   29     unsigned     column;    /* column number */ ~
+
+The advantage over using tags or the preview window is that included files are
+searched.  In most cases this results in the right declaration to be found.
+Also when the tags file is out of date.  Also when you don't have tags for the
+included files.
+   However, a few things must be right for "[I" to do its work.  First of all,
+the 'include' option must specify how a file is included.  The default value
+works for C and C++.  For other languages you will have to change it.
+
+
+LOCATING INCLUDED FILES
+
+   Vim will find included files in the places specified with the 'path'
+option.  If a directory is missing, some include files will not be found.  You
+can discover this with this command: >
+
+	:checkpath
+
+It will list the include files that could not be found.  Also files included
+by the files that could be found.  An example of the output:
+
+	--- Included files not found in path --- ~
+	<io.h> ~
+	vim.h --> ~
+	  <functions.h> ~
+	  <clib/exec_protos.h> ~
+
+The "io.h" file is included by the current file and can't be found.  "vim.h"
+can be found, thus ":checkpath" goes into this file and checks what it
+includes.  The "functions.h" and "clib/exec_protos.h" files, included by
+"vim.h" are not found.
+
+	Note:
+	Vim is not a compiler.  It does not recognize "#ifdef" statements.
+	This means every "#include" statement is used, also when it comes
+	after "#if NEVER".
+
+To fix the files that could not be found, add a directory to the 'path'
+option.  A good place to find out about this is the Makefile.  Look out for
+lines that contain "-I" items, like "-I/usr/local/X11".  To add this directory
+use: >
+
+	:set path+=/usr/local/X11
+
+When there are many subdirectories, you an use the "*" wildcard.  Example: >
+
+	:set path+=/usr/*/include
+
+This would find files in "/usr/local/include" as well as "/usr/X11/include".
+
+When working on a project with a whole nested tree of included files, the "**"
+items is useful.  This will search down in all subdirectories.  Example: >
+
+	:set path+=/projects/invent/**/include
+
+This will find files in the directories:
+
+	/projects/invent/include ~
+	/projects/invent/main/include ~
+	/projects/invent/main/os/include ~
+	etc.
+
+There are even more possibilities.  Check out the 'path' option for info.
+   If you want to see which included files are actually found, use this
+command: >
+
+	:checkpath!
+
+You will get a (very long) list of included files, the files they include, and
+so on.  To shorten the list a bit, Vim shows "(Already listed)" for files that
+were found before and doesn't list the included files in there again.
+
+
+JUMPING TO A MATCH
+
+"[I" produces a list with only one line of text.  When you want to have a
+closer look at the first item, you can jump to that line with the command: >
+
+	[<Tab>
+
+You can also use "[ CTRL-I", since CTRL-I is the same as pressing <Tab>.
+
+The list that "[I" produces has a number at the start of each line.  When you
+want to jump to another item than the first one, type the number first: >
+
+	3[<Tab>
+
+Will jump to the third item in the list.  Remember that you can use CTRL-O to
+jump back to where you started from.
+
+
+RELATED COMMANDS
+
+	[i		only lists the first match
+	]I		only lists items below the cursor
+	]i		only lists the first item below the cursor
+
+
+FINDING DEFINED IDENTIFIERS
+
+The "[I" command finds any identifier.  To find only macros, defined with
+"#define" use: >
+
+	[D
+
+Again, this searches in included files.  The 'define' option specifies what a
+line looks like that defines the items for "[D".  You could change it to make
+it work with other languages than C or C++.
+   The commands related to "[D" are:
+
+	[d		only lists the first match
+	]D		only lists items below the cursor
+	]d		only lists the first item below the cursor
+
+==============================================================================
+*29.5*	Finding local identifiers
+
+The "[I" command searches included files.  To search in the current file only,
+and jump to the first place where the word under the cursor is used: >
+
+	gD
+
+Hint: Goto Definition.  This command is very useful to find a variable or
+function that was declared locally ("static", in C terms).  Example (cursor on
+"counter"):
+
+	   +->   static int counter = 0;
+	   |
+	   |     int get_counter(void)
+	gD |     {
+	   |	     ++counter;
+	   +--	     return counter;
+		 }
+
+To restrict the search even further, and look only in the current function,
+use this command: >
+
+	gd
+
+This will go back to the start of the current function and find the first
+occurrence of the word under the cursor.  Actually, it searches backwards to
+an empty line above the a "{" in the first column.  From there it searches
+forward for the identifier.  Example (cursor on "idx"):
+
+		int find_entry(char *name)
+		{
+	   +->	    int idx;
+	   |
+	gd |	    for (idx = 0; idx < table_len; ++idx)
+	   |		if (strcmp(table[idx].name, name) == 0)
+	   +--		    return idx;
+		}
+
+==============================================================================
+
+Next chapter: |usr_30.txt|  Editing programs
+
+Copyright: see |manual-copyright|  vim:tw=78:ts=8:ft=help:norl:
--- /dev/null
+++ b/lib/vimfiles/doc/usr_30.txt
@@ -1,0 +1,643 @@
+*usr_30.txt*	For Vim version 7.1.  Last change: 2007 Apr 22
+
+		     VIM USER MANUAL - by Bram Moolenaar
+
+			      Editing programs
+
+
+Vim has various commands that aid in writing computer programs.  Compile a
+program and directly jump to reported errors.  Automatically set the indent
+for many languages and format comments.
+
+|30.1|	Compiling
+|30.2|	Indenting C files
+|30.3|	Automatic indenting
+|30.4|	Other indenting
+|30.5|	Tabs and spaces
+|30.6|	Formatting comments
+
+     Next chapter: |usr_31.txt|  Exploiting the GUI
+ Previous chapter: |usr_29.txt|  Moving through programs
+Table of contents: |usr_toc.txt|
+
+==============================================================================
+*30.1*	Compiling
+
+Vim has a set of so called "quickfix" commands.  They enable you to compile a
+program from within Vim and then go through the errors generated and fix them
+(hopefully).  You can then recompile and fix any new errors that are found
+until finally your program compiles without any error.
+
+The following command runs the program "make" (supplying it with any argument
+you give) and captures the results: >
+
+	:make {arguments}
+
+If errors were generated, they are captured and the editor positions you where
+the first error occurred.
+   Take a look at an example ":make" session.  (Typical :make sessions generate
+far more errors and fewer stupid ones.)  After typing ":make" the screen looks
+like this:
+
+	:!make | &tee /tmp/vim215953.err ~
+	gcc -g -Wall -o prog main.c sub.c ~
+	main.c: In function 'main': ~
+	main.c:6: too many arguments to function 'do_sub' ~
+	main.c: At top level: ~
+	main.c:10: parse error before '}' ~
+	make: *** [prog] Error 1 ~
+
+	2 returned ~
+	"main.c" 11L, 111C ~
+	(3 of 6): too many arguments to function 'do_sub' ~
+	Press ENTER or type command to continue ~
+
+From this you can see that you have errors in the file "main.c".  When you
+press <Enter>, Vim displays the file "main.c", with the cursor positioned on
+line 6, the first line with an error.  You did not need to specify the file or
+the line number, Vim knew where to go by looking in the error messages.
+
+		+---------------------------------------------------+
+		|int main()					    |
+		|{						    |
+		|	int i=3;				    |
+      cursor -> |	do_sub("foo");				    |
+		|	++i;					    |
+		|	return (0);				    |
+		|}						    |
+		|}						    |
+		| ~						    |
+		|(3 of 12): too many arguments to function 'do_sub' |
+		+---------------------------------------------------+
+
+The following command goes to where the next error occurs: >
+
+	:cnext
+
+Vim jumps to line 10, the last line in the file, where there is an extra '}'.
+   When there is not enough room, Vim will shorten the error message.  To see
+the whole message use: >
+
+	:cc
+
+You can get an overview of all the error messages with the ":clist" command.
+The output looks like this: >
+
+	:clist
+<	3 main.c: 6:too many arguments to function 'do_sub' ~
+	5 main.c: 10:parse error before '}' ~
+
+Only the lines where Vim recognized a file name and line number are listed
+here.  It assumes those are the interesting lines and the rest is just boring
+messages.  However, sometimes unrecognized lines do contain something you want
+to see.  Output from the linker, for example, about an undefined function.
+To see all the messages add a "!" to the command: >
+
+	:clist!
+<	1 gcc -g -Wall -o prog main.c sub.c ~
+	2 main.c: In function 'main': ~
+	3 main.c:6: too many arguments to function 'do_sub' ~
+	4 main.c: At top level: ~
+	5 main.c:10: parse error before '}' ~
+	6 make: *** [prog] Error 1 ~
+
+Vim will highlight the current error.  To go back to the previous error, use:
+>
+	:cprevious
+
+Other commands to move around in the error list:
+
+	:cfirst		to first error
+	:clast		to last error
+	:cc 3		to error nr 3
+
+
+USING ANOTHER COMPILER
+
+The name of the program to run when the ":make" command is executed is defined
+by the 'makeprg' option.  Usually this is set to "make", but Visual C++ users
+should set this to "nmake" by executing the following command: >
+
+	:set makeprg=nmake
+
+You can also include arguments in this option.  Special characters need to
+be escaped with a backslash.  Example: >
+
+	:set makeprg=nmake\ -f\ project.mak
+
+You can include special Vim keywords in the command specification.  The %
+character expands to the name of the current file.  So if you execute the
+command: >
+	:set makeprg=make\ %
+
+When you are editing main.c, then ":make" executes the following command: >
+
+	make main.c
+
+This is not too useful, so you will refine the command a little and use the :r
+(root) modifier: >
+
+	:set makeprg=make\ %:r.o
+
+Now the command executed is as follows: >
+
+	make main.o
+
+More about these modifiers here: |filename-modifiers|.
+
+
+OLD ERROR LISTS
+
+Suppose you ":make" a program.  There is a warning message in one file and an
+error message in another.  You fix the error and use ":make" again to check if
+it was really fixed.  Now you want to look at the warning message.  It doesn't
+show up in the last error list, since the file with the warning wasn't
+compiled again.  You can go back to the previous error list with: >
+
+	:colder
+
+Then use ":clist" and ":cc {nr}" to jump to the place with the warning.
+   To go forward to the next error list: >
+
+	:cnewer
+
+Vim remembers ten error lists.
+
+
+SWITCHING COMPILERS
+
+You have to tell Vim what format the error messages are that your compiler
+produces.  This is done with the 'errorformat' option.  The syntax of this
+option is quite complicated and it can be made to fit almost any compiler.
+You can find the explanation here: |errorformat|.
+
+You might be using various different compilers.  Setting the 'makeprg' option,
+and especially the 'errorformat' each time is not easy.  Vim offers a simple
+method for this.  For example, to switch to using the Microsoft Visual C++
+compiler: >
+
+	:compiler msvc
+
+This will find the Vim script for the "msvc" compiler and set the appropriate
+options.
+   You can write your own compiler files.  See |write-compiler-plugin|.
+
+
+OUTPUT REDIRECTION
+
+The ":make" command redirects the output of the executed program to an error
+file.  How this works depends on various things, such as the 'shell'.  If your
+":make" command doesn't capture the output, check the 'makeef' and
+'shellpipe' options.  The 'shellquote' and 'shellxquote' options might also
+matter.
+
+In case you can't get ":make" to redirect the file for you, an alternative is
+to compile the program in another window and redirect the output into a file.
+Then have Vim read this file with: >
+
+	:cfile {filename}
+
+Jumping to errors will work like with the ":make" command.
+
+==============================================================================
+*30.2*	Indenting C files
+
+A program is much easier to understand when the lines have been properly
+indented.  Vim offers various ways to make this less work.
+   For C programs set the 'cindent' option.  Vim knows a lot about C programs
+and will try very hard to automatically set the indent for you.  Set the
+'shiftwidth' option to the amount of spaces you want for a deeper level.  Four
+spaces will work fine.  One ":set" command will do it: >
+
+	:set cindent shiftwidth=4
+
+With this option enabled, when you type something such as "if (x)", the next
+line will automatically be indented an additional level.
+
+				    if (flag)
+	Automatic indent   --->		do_the_work();
+	Automatic unindent <--	    if (other_flag) {
+	Automatic indent   --->		do_file();
+	keep indent			do_some_more();
+	Automatic unindent <--	    }
+
+When you type something in curly braces ({}), the text will be indented at the
+start and unindented at the end.  The unindenting will happen after typing the
+'}', since Vim can't guess what you are going to type.
+
+One side effect of automatic indentation is that it helps you catch errors in
+your code early.  When you type a } to finish a function, only to find that
+the automatic indentation gives it more indent than what you expected, there
+is probably a } missing.  Use the "%" command to find out which { matches the
+} you typed.
+   A missing ) and ; also cause extra indent.  Thus if you get more white
+space than you would expect, check the preceding lines.
+
+When you have code that is badly formatted, or you inserted and deleted lines,
+you need to re-indent the lines.  The "=" operator does this.  The simplest
+form is: >
+
+	==
+
+This indents the current line.  Like with all operators, there are three ways
+to use it.  In Visual mode "=" indents the selected lines.  A useful text
+object is "a{".  This selects the current {} block.  Thus, to re-indent the
+code block the cursor is in: >
+
+	=a{
+
+I you have really badly indented code, you can re-indent the whole file with:
+>
+	gg=G
+
+However, don't do this in files that have been carefully indented manually.
+The automatic indenting does a good job, but in some situations you might want
+to overrule it.
+
+
+SETTING INDENT STYLE
+
+Different people have different styles of indentation.  By default Vim does a
+pretty good job of indenting in a way that 90% of programmers do.  There are
+different styles, however; so if you want to, you can customize the
+indentation style with the 'cinoptions' option.
+   By default 'cinoptions' is empty and Vim uses the default style.  You can
+add various items where you want something different.  For example, to make
+curly braces be placed like this:
+
+	if (flag) ~
+	  { ~
+	    i = 8; ~
+	    j = 0; ~
+	  } ~
+
+Use this command: >
+
+	:set cinoptions+={2
+
+There are many of these items.  See |cinoptions-values|.
+
+==============================================================================
+*30.3*	Automatic indenting
+
+You don't want to switch on the 'cindent' option manually every time you edit
+a C file.  This is how you make it work automatically: >
+
+	:filetype indent on
+
+Actually, this does a lot more than switching on 'cindent' for C files.  First
+of all, it enables detecting the type of a file.  That's the same as what is
+used for syntax highlighting.
+   When the filetype is known, Vim will search for an indent file for this
+type of file.  The Vim distribution includes a number of these for various
+programming languages.  This indent file will then prepare for automatic
+indenting specifically for this file.
+
+If you don't like the automatic indenting, you can switch it off again: >
+
+	:filetype indent off
+
+If you don't like the indenting for one specific type of file, this is how you
+avoid it.  Create a file with just this one line: >
+
+	:let b:did_indent = 1
+
+Now you need to write this in a file with a specific name:
+
+	{directory}/indent/{filetype}.vim
+
+The {filetype} is the name of the file type, such as "cpp" or "java".  You can
+see the exact name that Vim detected with this command: >
+
+	:set filetype
+
+In this file the output is:
+
+	filetype=help ~
+
+Thus you would use "help" for {filetype}.
+   For the {directory} part you need to use your runtime directory.  Look at
+the output of this command: >
+
+	set runtimepath
+
+Now use the first item, the name before the first comma.  Thus if the output
+looks like this:
+
+	runtimepath=~/.vim,/usr/local/share/vim/vim60/runtime,~/.vim/after ~
+
+You use "~/.vim" for {directory}.  Then the resulting file name is:
+
+	~/.vim/indent/help.vim ~
+
+Instead of switching the indenting off, you could write your own indent file.
+How to do that is explained here: |indent-expression|.
+
+==============================================================================
+*30.4*	Other indenting
+
+The most simple form of automatic indenting is with the 'autoindent' option.
+It uses the indent from the previous line.  A bit smarter is the 'smartindent'
+option.  This is useful for languages where no indent file is available.
+'smartindent' is not as smart as 'cindent', but smarter than 'autoindent'.
+   With 'smartindent' set, an extra level of indentation is added for each {
+and removed for each }.  An extra level of indentation will also be added for
+any of the words in the 'cinwords' option.  Lines that begin with # are
+treated specially: all indentation is removed.  This is done so that
+preprocessor directives will all start in column 1.  The indentation is
+restored for the next line.
+
+
+CORRECTING INDENTS
+
+When you are using 'autoindent' or 'smartindent' to get the indent of the
+previous line, there will be many times when you need to add or remove one
+'shiftwidth' worth of indent.  A quick way to do this is using the CTRL-D and
+CTRL-T commands in Insert mode.
+   For example, you are typing a shell script that is supposed to look like
+this:
+
+	if test -n a; then ~
+	   echo a ~
+	   echo "-------" ~
+	fi ~
+
+Start off by setting these option: >
+
+	:set autoindent shiftwidth=3
+
+You start by typing the first line, <Enter> and the start of the second line:
+
+	if test -n a; then ~
+	echo ~
+
+Now you see that you need an extra indent.  Type CTRL-T.  The result:
+
+	if test -n a; then ~
+	   echo ~
+
+The CTRL-T command, in Insert mode, adds one 'shiftwidth' to the indent, no
+matter where in the line you are.
+   You continue typing the second line, <Enter> and the third line.  This time
+the indent is OK.  Then <Enter> and the last line.  Now you have this:
+
+	if test -n a; then ~
+	   echo a ~
+	   echo "-------" ~
+	   fi ~
+
+To remove the superfluous indent in the last line press CTRL-D.  This deletes
+one 'shiftwidth' worth of indent, no matter where you are in the line.
+   When you are in Normal mode, you can use the ">>" and "<<" commands to
+shift lines.  ">" and "<" are operators, thus you have the usual three ways to
+specify the lines you want to indent.  A useful combination is: >
+
+	>i{
+
+This adds one indent to the current block of lines, inside {}.  The { and }
+lines themselves are left unmodified.  ">a{" includes them.  In this example
+the cursor is on "printf":
+
+	original text		after ">i{"		after ">a{"
+
+	if (flag)		if (flag)		if (flag) ~
+	{			{			    { ~
+	printf("yes");		    printf("yes");	    printf("yes"); ~
+	flag = 0;		    flag = 0;		    flag = 0;  ~
+	}			}			    } ~
+
+==============================================================================
+*30.5*	Tabs and spaces
+
+'tabstop' is set to eight by default.  Although you can change it, you quickly
+run into trouble later.  Other programs won't know what tabstop value you
+used.  They probably use the default value of eight, and your text suddenly
+looks very different.  Also, most printers use a fixed tabstop value of eight.
+Thus it's best to keep 'tabstop' alone.  (If you edit a file which was written
+with a different tabstop setting, see |25.3| for how to fix that.)
+   For indenting lines in a program, using a multiple of eight spaces makes
+you quickly run into the right border of the window.  Using a single space
+doesn't provide enough visual difference.  Many people prefer to use four
+spaces, a good compromise.
+   Since a <Tab> is eight spaces and you want to use an indent of four spaces,
+you can't use a <Tab> character to make your indent.  There are two ways to
+handle this:
+
+1.  Use a mix of <Tab> and space characters.  Since a <Tab> takes the place of
+    eight spaces, you have fewer characters in your file.  Inserting a <Tab>
+    is quicker than eight spaces.  Backspacing works faster as well.
+
+2.  Use spaces only.  This avoids the trouble with programs that use a
+    different tabstop value.
+
+Fortunately, Vim supports both methods quite well.
+
+
+SPACES AND TABS
+
+If you are using a combination of tabs and spaces, you just edit normally.
+The Vim defaults do a fine job of handling things.
+   You can make life a little easier by setting the 'softtabstop' option.
+This option tells Vim to make the <Tab> key look and feel as if tabs were set
+at the value of 'softtabstop', but actually use a combination of tabs and
+spaces.
+   After you execute the following command, every time you press the <Tab> key
+the cursor moves to the next 4-column boundary: >
+
+	:set softtabstop=4
+
+When you start in the first column and press <Tab>, you get 4 spaces inserted
+in your text.  The second time, Vim takes out the 4 spaces and puts in a <Tab>
+(thus taking you to column 8).  Thus Vim uses as many <Tab>s as possible, and
+then fills up with spaces.
+   When backspacing it works the other way around.  A <BS> will always delete
+the amount specified with 'softtabstop'.  Then <Tabs> are used as many as
+possible and spaces to fill the gap.
+   The following shows what happens pressing <Tab> a few times, and then using
+<BS>.  A "." stands for a space and "------->" for a <Tab>.
+
+	type			  result ~
+	<Tab>			  ....
+	<Tab><Tab>		  ------->
+	<Tab><Tab><Tab>		  ------->....
+	<Tab><Tab><Tab><BS>	  ------->
+	<Tab><Tab><Tab><BS><BS>   ....
+
+An alternative is to use the 'smarttab' option.  When it's set, Vim uses
+'shiftwidth' for a <Tab> typed in the indent of a line, and a real <Tab> when
+typed after the first non-blank character.  However, <BS> doesn't work like
+with 'softtabstop'.
+
+
+JUST SPACES
+
+If you want absolutely no tabs in your file, you can set the 'expandtab'
+option: >
+
+	:set expandtab
+
+When this option is set, the <Tab> key inserts a series of spaces.  Thus you
+get the same amount of white space as if a <Tab> character was inserted, but
+there isn't a real <Tab> character in your file.
+   The backspace key will delete each space by itself.  Thus after typing one
+<Tab> you have to press the <BS> key up to eight times to undo it.  If you are
+in the indent, pressing CTRL-D will be a lot quicker.
+
+
+CHANGING TABS IN SPACES (AND BACK)
+
+Setting 'expandtab' does not affect any existing tabs.  In other words, any
+tabs in the document remain tabs.  If you want to convert tabs to spaces, use
+the ":retab" command.  Use these commands: >
+
+	:set expandtab
+	:%retab
+
+Now Vim will have changed all indents to use spaces instead of tabs.  However,
+all tabs that come after a non-blank character are kept.  If you want these to
+be converted as well, add a !: >
+
+	:%retab!
+
+This is a little bit dangerous, because it can also change tabs inside a
+string.  To check if these exist, you could use this: >
+
+	/"[^"\t]*\t[^"]*"
+
+It's recommended not to use hard tabs inside a string.  Replace them with
+"\t" to avoid trouble.
+
+The other way around works just as well: >
+
+	:set noexpandtab
+	:%retab!
+
+==============================================================================
+*30.6*	Formatting comments
+
+One of the great things about Vim is that it understands comments.  You can
+ask Vim to format a comment and it will do the right thing.
+   Suppose, for example, that you have the following comment:
+
+	/* ~
+	 * This is a test ~
+	 * of the text formatting. ~
+	 */ ~
+
+You then ask Vim to format it by positioning the cursor at the start of the
+comment and type: >
+
+	gq]/
+
+"gq" is the operator to format text.  "]/" is the motion that takes you to the
+end of a comment.  The result is:
+
+	/* ~
+	 * This is a test of the text formatting. ~
+	 */ ~
+
+Notice that Vim properly handled the beginning of each line.
+  An alternative is to select the text that is to be formatted in Visual mode
+and type "gq".
+
+To add a new line to the comment, position the cursor on the middle line and
+press "o".  The result looks like this:
+
+	/* ~
+	 * This is a test of the text formatting. ~
+	 * ~
+	 */ ~
+
+Vim has automatically inserted a star and a space for you.  Now you can type
+the comment text.  When it gets longer than 'textwidth', Vim will break the
+line.  Again, the star is inserted automatically:
+
+	/* ~
+	 * This is a test of the text formatting. ~
+	 * Typing a lot of text here will make Vim ~
+	 * break ~
+	 */ ~
+
+For this to work some flags must be present in 'formatoptions':
+
+	r	insert the star when typing <Enter> in Insert mode
+	o	insert the star when using "o" or "O" in Normal mode
+	c	break comment text according to 'textwidth'
+
+See |fo-table| for more flags.
+
+
+DEFINING A COMMENT
+
+The 'comments' option defines what a comment looks like.  Vim distinguishes
+between a single-line comment and a comment that has a different start, end
+and middle part.
+   Many single-line comments start with a specific character.  In C++ // is
+used, in Makefiles #, in Vim scripts ".  For example, to make Vim understand
+C++ comments: >
+
+	:set comments=://
+
+The colon separates the flags of an item from the text by which the comment is
+recognized.  The general form of an item in 'comments' is:
+
+	{flags}:{text}
+
+The {flags} part can be empty, as in this case.
+   Several of these items can be concatenated, separated by commas.  This
+allows recognizing different types of comments at the same time.  For example,
+let's edit an e-mail message.  When replying, the text that others wrote is
+preceded with ">" and "!" characters.  This command would work: >
+
+	:set comments=n:>,n:!
+
+There are two items, one for comments starting with ">" and one for comments
+that start with "!".  Both use the flag "n".  This means that these comments
+nest.  Thus a line starting with ">" may have another comment after the ">".
+This allows formatting a message like this:
+
+	> ! Did you see that site? ~
+	> ! It looks really great. ~
+	> I don't like it.  The ~
+	> colors are terrible. ~
+	What is the URL of that ~
+	site? ~
+
+Try setting 'textwidth' to a different value, e.g., 80, and format the text by
+Visually selecting it and typing "gq".  The result is:
+
+	> ! Did you see that site?  It looks really great. ~
+	> I don't like it.  The colors are terrible. ~
+	What is the URL of that site? ~
+
+You will notice that Vim did not move text from one type of comment to
+another.  The "I" in the second line would have fit at the end of the first
+line, but since that line starts with "> !" and the second line with ">", Vim
+knows that this is a different kind of comment.
+
+
+A THREE PART COMMENT
+
+A C comment starts with "/*", has "*" in the middle and "*/" at the end.  The
+entry in 'comments' for this looks like this: >
+
+	:set comments=s1:/*,mb:*,ex:*/
+
+The start is defined with "s1:/*".  The "s" indicates the start of a
+three-piece comment.  The colon separates the flags from the text by which the
+comment is recognized: "/*".  There is one flag: "1".  This tells Vim that the
+middle part has an offset of one space.
+   The middle part "mb:*" starts with "m", which indicates it is a middle
+part.  The "b" flag means that a blank must follow the text.  Otherwise Vim
+would consider text like "*pointer" also to be the middle of a comment.
+   The end part "ex:*/" has the "e" for identification.  The "x" flag has a
+special meaning.  It means that after Vim automatically inserted a star,
+typing / will remove the extra space.
+
+For more details see |format-comments|.
+
+==============================================================================
+
+Next chapter: |usr_31.txt|  Exploiting the GUI
+
+Copyright: see |manual-copyright|  vim:tw=78:ts=8:ft=help:norl:
--- /dev/null
+++ b/lib/vimfiles/doc/usr_31.txt
@@ -1,0 +1,272 @@
+*usr_31.txt*	For Vim version 7.1.  Last change: 2007 May 08
+
+		     VIM USER MANUAL - by Bram Moolenaar
+
+			      Exploiting the GUI
+
+
+Vim works well in a terminal, but the GUI has a few extra items.  A file
+browser can be used for commands that use a file.  A dialog to make a choice
+between alternatives.  Use keyboard shortcuts to access menu items quickly.
+
+|31.1|	The file browser
+|31.2|	Confirmation
+|31.3|	Menu shortcuts
+|31.4|	Vim window position and size
+|31.5|	Various
+
+     Next chapter: |usr_32.txt|  The undo tree
+ Previous chapter: |usr_30.txt|  Editing programs
+Table of contents: |usr_toc.txt|
+
+==============================================================================
+*31.1*	The file browser
+
+When using the File/Open... menu you get a file browser.  This makes it easier
+to find the file you want to edit.  But what if you want to split a window to
+edit another file?  There is no menu entry for this.  You could first use
+Window/Split and then File/Open..., but that's more work.
+   Since you are typing most commands in Vim, opening the file browser with a
+typed command is possible as well.  To make the split command use the file
+browser, prepend "browse": >
+
+	:browse split
+
+Select a file and then the ":split" command will be executed with it.  If you
+cancel the file dialog nothing happens, the window isn't split.
+   You can also specify a file name argument.  This is used to tell the file
+browser where to start.  Example: >
+
+	:browse split /etc
+
+The file browser will pop up, starting in the directory "/etc".
+
+The ":browse" command can be prepended to just about any command that opens a
+file.
+   If no directory is specified, Vim will decide where to start the file
+browser.  By default it uses the same directory as the last time.  Thus when
+you used ":browse split" and selected a file in "/usr/local/share", the next
+time you use a ":browse" it will start in "/usr/local/share" again.
+   This can be changed with the 'browsedir' option.  It can have one of three
+values:
+
+	last		Use the last directory browsed (default)
+	buffer		Use the same directory as the current buffer
+	current		use the current directory
+
+For example, when you are in the directory "/usr", editing the file
+"/usr/local/share/readme", then the command: >
+
+	:set browsedir=buffer
+	:browse edit
+
+Will start the browser in "/usr/local/share".  Alternatively: >
+
+	:set browsedir=current
+	:browse edit
+
+Will start the browser in "/usr".
+
+	Note:
+	To avoid using the mouse, most file browsers offer using key presses
+	to navigate.  Since this is different for every system, it is not
+	explained here.  Vim uses a standard browser when possible, your
+	system documentation should contain an explanation on the keyboard
+	shortcuts somewhere.
+
+When you are not using the GUI version, you could use the file explorer window
+to select files like in a file browser.  However, this doesn't work for the
+":browse" command.  See |netrw-browse|.
+
+==============================================================================
+*31.2*	Confirmation
+
+Vim protects you from accidentally overwriting a file and other ways to lose
+changes.  If you do something that might be a bad thing to do, Vim produces an
+error message and suggests appending ! if you really want to do it.
+   To avoid retyping the command with the !, you can make Vim give you a
+dialog.  You can then press "OK" or "Cancel" to tell Vim what you want.
+   For example, you are editing a file and made changes to it.  You start
+editing another file with: >
+
+	:confirm edit foo.txt
+
+Vim will pop up a dialog that looks something like this:
+
+	+-----------------------------------+
+	|				    |
+	|   ?	Save changes to "bar.txt"?  |
+	|				    |
+	|   YES   NO		 CANCEL     |
+	+-----------------------------------+
+
+Now make your choice.  If you do want to save the changes, select "YES".  If
+you want to lose the changes for ever: "NO".  If you forgot what you were
+doing and want to check what really changed use "CANCEL".  You will be back in
+the same file, with the changes still there.
+
+Just like ":browse", the ":confirm" command can be prepended to most commands
+that edit another file.  They can also be combined: >
+
+	:confirm browse edit
+
+This will produce a dialog when the current buffer was changed.  Then it will
+pop up a file browser to select the file to edit.
+
+	Note:
+	In the dialog you can use the keyboard to select the choice.
+	Typically the <Tab> key and the cursor keys change the choice.
+	Pressing <Enter> selects the choice.  This depends on the system
+	though.
+
+When you are not using the GUI, the ":confirm" command works as well.  Instead
+of popping up a dialog, Vim will print the message at the bottom of the Vim
+window and ask you to press a key to make a choice. >
+
+	:confirm edit main.c
+<	Save changes to "Untitled"? ~
+	[Y]es, (N)o, (C)ancel:  ~
+
+You can now press the single key for the choice.  You don't have to press
+<Enter>, unlike other typing on the command line.
+
+==============================================================================
+*31.3*	Menu shortcuts
+
+The keyboard is used for all Vim commands.  The menus provide a simple way to
+select commands, without knowing what they are called.  But you have to move
+your hand from the keyboard and grab the mouse.
+   Menus can often be selected with keys as well.  This depends on your
+system, but most often it works this way.  Use the <Alt> key in combination
+with the underlined letter of a menu.  For example, <A-w> (<Alt> and w) pops
+up the Window menu.
+   In the Window menu, the "split" item has the p underlined.  To select it,
+let go of the <Alt> key and press p.
+
+After the first selection of a menu with the <Alt> key, you can use the cursor
+keys to move through the menus.  <Right> selects a submenu and <left> closes
+it.  <Esc> also closes a menu.  <Enter> selects a menu item.
+
+There is a conflict between using the <Alt> key to select menu items, and
+using <Alt> key combinations for mappings.  The 'winaltkeys' option tells Vim
+what it should do with the <Alt> key.
+   The default value "menu" is the smart choice: If the key combination is a
+menu shortcut it can't be mapped.  All other keys are available for mapping.
+   The value "no" doesn't use any <Alt> keys for the menus.  Thus you must use
+the mouse for the menus, and all <Alt> keys can be mapped.
+   The value "yes" means that Vim will use any <Alt> keys for the menus.  Some
+<Alt> key combinations may also do other things than selecting a menu.
+
+==============================================================================
+*31.4*	Vim window position and size
+
+To see the current Vim window position on the screen use: >
+
+	:winpos
+
+This will only work in the GUI.  The output may look like this:
+
+	Window position: X 272, Y 103 ~
+
+The position is given in screen pixels.  Now you can use the numbers to move
+Vim somewhere else.  For example, to move it to the left a hundred pixels: >
+
+	:winpos 172 103
+<
+	Note:
+	There may be a small offset between the reported position and where
+	the window moves.  This is because of the border around the window.
+	This is added by the window manager.
+
+You can use this command in your startup script to position the window at a
+specific position.
+
+The size of the Vim window is computed in characters.  Thus this depends on
+the size of the font being used.  You can see the current size with this
+command: >
+
+	:set lines columns
+
+To change the size set the 'lines' and/or 'columns' options to a new value: >
+
+	:set lines=50
+	:set columns=80
+
+Obtaining the size works in a terminal just like in the GUI.  Setting the size
+is not possible in most terminals.
+
+You can start the X-Windows version of gvim with an argument to specify the
+size and position of the window: >
+
+	gvim -geometry {width}x{height}+{x_offset}+{y_offset}
+
+{width} and {height} are in characters, {x_offset} and {y_offset} are in
+pixels.  Example: >
+
+	gvim -geometry 80x25+100+300
+
+==============================================================================
+*31.5*	Various
+
+You can use gvim to edit an e-mail message.  In your e-mail program you must
+select gvim to be the editor for messages.  When you try that, you will
+see that it doesn't work: The mail program thinks that editing is finished,
+while gvim is still running!
+   What happens is that gvim disconnects from the shell it was started in.
+That is fine when you start gvim in a terminal, so that you can do other work
+in that terminal.  But when you really want to wait for gvim to finish, you
+must prevent it from disconnecting.  The "-f" argument does this: >
+
+	gvim -f file.txt
+
+The "-f" stands for foreground.  Now Vim will block the shell it was started
+in until you finish editing and exit.
+
+
+DELAYED START OF THE GUI
+
+On Unix it's possible to first start Vim in a terminal.  That's useful if you
+do various tasks in the same shell.  If you are editing a file and decide you
+want to use the GUI after all, you can start it with: >
+
+	:gui
+
+Vim will open the GUI window and no longer use the terminal.  You can continue
+using the terminal for something else.  The "-f" argument is used here to run
+the GUI in the foreground.  You can also use ":gui -f".
+
+
+THE GVIM STARTUP FILE
+
+When gvim starts, it reads the gvimrc file.  That's similar to the vimrc file
+used when starting Vim.  The gvimrc file can be used for settings and commands
+that are only to be used when the GUI is going to be started.  For example,
+you can set the 'lines' option to set a different window size: >
+
+	:set lines=55
+
+You don't want to do this in a terminal, since it's size is fixed (except for
+an xterm that supports resizing).
+   The gvimrc file is searched for in the same locations as the vimrc file.
+Normally its name is "~/.gvimrc" for Unix and "$VIM/_gvimrc" for MS-Windows.
+The $MYGVIMRC environment variable is set to it, thus you can use this command
+to edit the file, if you have one: >
+
+	:edit $MYGVIMRC
+<
+   If for some reason you don't want to use the normal gvimrc file, you can
+specify another one with the "-U" argument: >
+
+	gvim -U thisrc ...
+
+That allows starting gvim for different kinds of editing.  You could set
+another font size, for example.
+   To completely skip reading a gvimrc file: >
+
+	gvim -U NONE ...
+
+==============================================================================
+
+Next chapter: |usr_32.txt|  The undo tree
+
+Copyright: see |manual-copyright|  vim:tw=78:ts=8:ft=help:norl:
--- /dev/null
+++ b/lib/vimfiles/doc/usr_32.txt
@@ -1,0 +1,151 @@
+*usr_32.txt*	For Vim version 7.1.  Last change: 2006 Apr 30
+
+		     VIM USER MANUAL - by Bram Moolenaar
+
+			      The undo tree
+
+
+Vim provides multi-level undo.  If you undo a few changes and then make a new
+change you create a branch in the undo tree.  This text is about moving
+through the branches.
+
+|32.1|	Numbering changes
+|32.2|	Jumping around the tree
+|32.3|	Time travelling
+
+     Next chapter: |usr_40.txt|  Make new commands
+ Previous chapter: |usr_31.txt|  Exploiting the GUI
+Table of contents: |usr_toc.txt|
+
+==============================================================================
+*32.1*	Numbering changes
+
+In section |02.5| we only discussed one line of undo/redo.  But it is also
+possible to branch off.  This happens when you undo a few changes and then
+make a new change.  The new changes become a branch in the undo tree.
+
+Let's start with the text "one".  The first change to make is to append
+" too".  And then move to the first 'o' and change it into 'w'.  We then have
+two changes, numbered 1 and 2, and three states of the text:
+
+		one ~
+		 |
+	      change 1
+		 |
+	      one too ~
+		 |
+	      change 2
+		 |
+	      one two ~
+
+If we now undo one change, back to "one too", and change "one" to "me" we
+create a branch in the undo tree:
+
+		one ~
+		 |
+	      change 1
+		 |
+	      one too ~
+	      /     \
+	 change 2  change 3
+	    |	      |
+	 one two    me too ~
+
+You can now use the |u| command to undo.  If you do this twice you get to
+"one".  Use |CTRL-R| to redo, and you will go to "one too".  One more |CTRL-R|
+takes you to "me too".  Thus undo and redo go up and down in the tree, using
+the branch that was last used.
+
+What matters here is the order in which the changes are made.  Undo and redo
+are not considered changes in this context.  After each change you have a new
+state of the text.
+
+Note that only the changes are numbered, the text shown in the tree above has
+no identifier.  They are mostly referred to by the number of the change above
+it.  But sometimes by the number of one of the changes below it, especially
+when moving up in the tree, so that you know which change was just undone.
+
+==============================================================================
+*32.2*	Jumping around the tree
+
+So how do you get to "one two" now?  You can use this command: >
+
+	:undo 2
+
+The text is now "one two", you are below change 2.  You can use the |:undo|
+command to jump to below any change in the tree.
+
+Now make another change: change "one" to "not":
+
+		one ~
+		 |
+	      change 1
+		 |
+	      one too ~
+	      /     \
+	 change 2  change 3
+	    |	      |
+	 one two    me too ~
+	    |
+	 change 4
+	    |
+	 not two ~
+
+Now you change your mind and want to go back to "me too".  Use the |g-|
+command.  This moves back in time.  Thus it doesn't walk the tree upwards or
+downwards, but goes to the change made before.
+
+You can repeat |g-| and you will see the text change:
+	me too ~
+	one two ~
+	one too ~
+	one ~
+
+Use |g+| to move forward in time:
+	one ~
+	one too ~
+	one two ~
+	me too ~
+	not two ~
+
+Using |:undo| is useful if you know what change you want to jump to.  |g-| and
+|g+| are useful if you don't know exactly what the change number is.
+
+You can type a count before |g-| and |g+| to repeat them.
+
+==============================================================================
+*32.3*	Time travelling
+
+When you have been working on text for a while the tree grows to become big.
+Then you may want to go to the text of some minutes ago.
+
+To see what branches there are in the undo tree use this command: >
+
+	:undolist
+<	number changes  time ~
+	     3       2  16 seconds ago
+	     4       3  5 seconds ago
+
+Here you can see the number of the leaves in each branch and when the change
+was made.  Assuming we are below change 4, at "not two", you can go back ten
+seconds with this command: >
+
+	:earlier 10s
+
+Depending on how much time you took for the changes you end up at a certain
+position in the tree.  The |:earlier| command argument can be "m" for minutes
+and "h" for hours.  To go all the way back use a big number: >
+
+	:earlier 10h
+
+To travel forward in time again use the |:later| command: >
+
+	:later 1m
+
+The arguments are "s", "m" and "h", just like with |:earlier|.
+
+==============================================================================
+
+Next chapter: |usr_40.txt|  Make new commands
+
+Copyright: see |manual-copyright|  vim:tw=78:ts=8:ft=help:norl:
--- /dev/null
+++ b/lib/vimfiles/doc/usr_40.txt
@@ -1,0 +1,657 @@
+*usr_40.txt*	For Vim version 7.1.  Last change: 2006 Jun 21
+
+		     VIM USER MANUAL - by Bram Moolenaar
+
+			      Make new commands
+
+
+Vim is an extensible editor.  You can take a sequence of commands you use
+often and turn it into a new command.  Or redefine an existing command.
+Autocommands make it possible to execute commands automatically.
+
+|40.1|	Key mapping
+|40.2|	Defining command-line commands
+|40.3|	Autocommands
+
+     Next chapter: |usr_41.txt|  Write a Vim script
+ Previous chapter: |usr_32.txt|  The undo tree
+Table of contents: |usr_toc.txt|
+
+==============================================================================
+*40.1*	Key mapping
+
+A simple mapping was explained in section |05.3|.  The principle is that one
+sequence of key strokes is translated into another sequence of key strokes.
+This is a simple, yet powerful mechanism.
+   The simplest form is that one key is mapped to a sequence of keys.  Since
+the function keys, except <F1>, have no predefined meaning in Vim, these are a
+good choice to map.  Example: >
+
+	:map <F2> GoDate: <Esc>:read !date<CR>kJ
+
+This shows how three modes are used.  After going to the last line with "G",
+the "o" command opens a new line and starts Insert mode.  The text "Date: " is
+inserted and <Esc> takes you out of insert mode.
+   Notice the use of special keys inside <>.  This is called angle bracket
+notation.  You type these as separate characters, not by pressing the key
+itself.  This makes the mappings better readable and you can copy and paste
+the text without problems.
+   The ":" character takes Vim to the command line.  The ":read !date" command
+reads the output from the "date" command and appends it below the current
+line.  The <CR> is required to execute the ":read" command.
+   At this point of execution the text looks like this:
+
+	Date:  ~
+	Fri Jun 15 12:54:34 CEST 2001 ~
+
+Now "kJ" moves the cursor up and joins the lines together.
+   To decide which key or keys you use for mapping, see |map-which-keys|.
+
+
+MAPPING AND MODES
+
+The ":map" command defines remapping for keys in Normal mode.  You can also
+define mappings for other modes.  For example, ":imap" applies to Insert mode.
+You can use it to insert a date below the cursor: >
+
+	:imap <F2> <CR>Date: <Esc>:read !date<CR>kJ
+
+It looks a lot like the mapping for <F2> in Normal mode, only the start is
+different.  The <F2> mapping for Normal mode is still there.  Thus you can map
+the same key differently for each mode.
+   Notice that, although this mapping starts in Insert mode, it ends in Normal
+mode.  If you want it to continue in Insert mode, append an "a" to the
+mapping.
+
+Here is an overview of map commands and in which mode they work:
+
+	:map		Normal, Visual and Operator-pending
+	:vmap		Visual
+	:nmap		Normal
+	:omap		Operator-pending
+	:map!		Insert and Command-line
+	:imap		Insert
+	:cmap		Command-line
+
+Operator-pending mode is when you typed an operator character, such as "d" or
+"y", and you are expected to type the motion command or a text object.  Thus
+when you type "dw", the "w" is entered in operator-pending mode.
+
+Suppose that you want to define <F7> so that the command d<F7> deletes a C
+program block (text enclosed in curly braces, {}).  Similarly y<F7> would yank
+the program block into the unnamed register.  Therefore, what you need to do
+is to define <F7> to select the current program block.  You can do this with
+the following command: >
+
+	:omap <F7> a{
+
+This causes <F7> to perform a select block "a{" in operator-pending mode, just
+like you typed it.  This mapping is useful if typing a { on your keyboard is a
+bit difficult.
+
+
+LISTING MAPPINGS
+
+To see the currently defined mappings, use ":map" without arguments.  Or one
+of the variants that include the mode in which they work.  The output could
+look like this:
+
+	   _g		 :call MyGrep(1)<CR> ~
+	v  <F2>		 :s/^/> /<CR>:noh<CR>`` ~
+	n  <F2>		 :.,$s/^/> /<CR>:noh<CR>`` ~
+	   <xHome>	 <Home>
+	   <xEnd>	 <End>
+
+
+The first column of the list shows in which mode the mapping is effective.
+This is "n" for Normal mode, "i" for Insert mode, etc.  A blank is used for a
+mapping defined with ":map", thus effective in both Normal and Visual mode.
+   One useful purpose of listing the mapping is to check if special keys in <>
+form have been recognized (this only works when color is supported).  For
+example, when <Esc> is displayed in color, it stands for the escape character.
+When it has the same color as the other text, it is five characters.
+
+
+REMAPPING
+
+The result of a mapping is inspected for other mappings in it.  For example,
+the mappings for <F2> above could be shortened to: >
+
+	:map <F2> G<F3>
+	:imap <F2> <Esc><F3>
+	:map <F3>  oDate: <Esc>:read !date<CR>kJ
+
+For Normal mode <F2> is mapped to go to the last line, and then behave like
+<F3> was pressed.  In Insert mode <F2> stops Insert mode with <Esc> and then
+also uses <F3>.  Then <F3> is mapped to do the actual work.
+
+Suppose you hardly ever use Ex mode, and want to use the "Q" command to format
+text (this was so in old versions of Vim).  This mapping will do it: >
+
+	:map Q gq
+
+But, in rare cases you need to use Ex mode anyway.  Let's map "gQ" to Q, so
+that you can still go to Ex mode: >
+
+	:map gQ Q
+
+What happens now is that when you type "gQ" it is mapped to "Q".  So far so
+good.  But then "Q" is mapped to "gq", thus typing "gQ" results in "gq", and
+you don't get to Ex mode at all.
+   To avoid keys to be mapped again, use the ":noremap" command: >
+
+	:noremap gQ Q
+
+Now Vim knows that the "Q" is not to be inspected for mappings that apply to
+it.  There is a similar command for every mode:
+
+	:noremap	Normal, Visual and Operator-pending
+	:vnoremap	Visual
+	:nnoremap	Normal
+	:onoremap	Operator-pending
+	:noremap!	Insert and Command-line
+	:inoremap	Insert
+	:cnoremap	Command-line
+
+
+RECURSIVE MAPPING
+
+When a mapping triggers itself, it will run forever.  This can be used to
+repeat an action an unlimited number of times.
+   For example, you have a list of files that contain a version number in the
+first line.  You edit these files with "vim *.txt".  You are now editing the
+first file.  Define this mapping: >
+
+	:map ,, :s/5.1/5.2/<CR>:wnext<CR>,,
+
+Now you type ",,".  This triggers the mapping.  It replaces "5.1" with "5.2"
+in the first line.  Then it does a ":wnext" to write the file and edit the
+next one.  The mapping ends in ",,".  This triggers the same mapping again,
+thus doing the substitution, etc.
+   This continues until there is an error.  In this case it could be a file
+where the substitute command doesn't find a match for "5.1".  You can then
+make a change to insert "5.1" and continue by typing ",," again.  Or the
+":wnext" fails, because you are in the last file in the list.
+   When a mapping runs into an error halfway, the rest of the mapping is
+discarded.  CTRL-C interrupts the mapping (CTRL-Break on MS-Windows).
+
+
+DELETE A MAPPING
+
+To remove a mapping use the ":unmap" command.  Again, the mode the unmapping
+applies to depends on the command used:
+
+	:unmap		Normal, Visual and Operator-pending
+	:vunmap		Visual
+	:nunmap		Normal
+	:ounmap		Operator-pending
+	:unmap!		Insert and Command-line
+	:iunmap		Insert
+	:cunmap		Command-line
+
+There is a trick to define a mapping that works in Normal and Operator-pending
+mode, but not in Visual mode.  First define it for all three modes, then
+delete it for Visual mode: >
+
+	:map <C-A> /---><CR>
+	:vunmap <C-A>
+
+Notice that the five characters "<C-A>" stand for the single key CTRL-A.
+
+To remove all mappings use the |:mapclear| command.  You can guess the
+variations for different modes by now.  Be careful with this command, it can't
+be undone.
+
+
+SPECIAL CHARACTERS
+
+The ":map" command can be followed by another command.  A | character
+separates the two commands.  This also means that a | character can't be used
+inside a map command.  To include one, use <Bar> (five characters).  Example:
+>
+	:map <F8> :write <Bar> !checkin %<CR>
+
+The same problem applies to the ":unmap" command, with the addition that you
+have to watch out for trailing white space.  These two commands are different:
+>
+	:unmap a | unmap b
+	:unmap a| unmap b
+
+The first command tries to unmap "a ", with a trailing space.
+
+When using a space inside a mapping, use <Space> (seven characters): >
+
+	:map <Space> W
+
+This makes the spacebar move a blank-separated word forward.
+
+It is not possible to put a comment directly after a mapping, because the "
+character is considered to be part of the mapping.  You can use |", this
+starts a new, empty command with a comment.  Example: >
+
+	:map <Space> W|     " Use spacebar to move forward a word
+
+
+MAPPINGS AND ABBREVIATIONS
+
+Abbreviations are a lot like Insert mode mappings.  The arguments are handled
+in the same way.  The main difference is the way they are triggered.  An
+abbreviation is triggered by typing a non-word character after the word.  A
+mapping is triggered when typing the last character.
+   Another difference is that the characters you type for an abbreviation are
+inserted in the text while you type them.  When the abbreviation is triggered
+these characters are deleted and replaced by what the abbreviation produces.
+When typing the characters for a mapping, nothing is inserted until you type
+the last character that triggers it.  If the 'showcmd' option is set, the
+typed characters are displayed in the last line of the Vim window.
+   An exception is when a mapping is ambiguous.  Suppose you have done two
+mappings: >
+
+	:imap aa foo
+	:imap aaa bar
+
+Now, when you type "aa", Vim doesn't know if it should apply the first or the
+second mapping.  It waits for another character to be typed.  If it is an "a",
+the second mapping is applied and results in "bar".  If it is a space, for
+example, the first mapping is applied, resulting in "foo", and then the space
+is inserted.
+
+
+ADDITIONALLY...
+
+The <script> keyword can be used to make a mapping local to a script.  See
+|:map-<script>|.
+
+The <buffer> keyword can be used to make a mapping local to a specific buffer.
+See |:map-<buffer>|
+
+The <unique> keyword can be used to make defining a new mapping fail when it
+already exists.  Otherwise a new mapping simply overwrites the old one.  See
+|:map-<unique>|.
+
+To make a key do nothing, map it to <Nop> (five characters).  This will make
+the <F7> key do nothing at all: >
+
+	:map <F7> <Nop>| map! <F7> <Nop>
+
+There must be no space after <Nop>.
+
+==============================================================================
+*40.2*	Defining command-line commands
+
+The Vim editor enables you to define your own commands.  You execute these
+commands just like any other Command-line mode command.
+   To define a command, use the ":command" command, as follows: >
+
+	:command DeleteFirst 1delete
+
+Now when you execute the command ":DeleteFirst" Vim executes ":1delete", which
+deletes the first line.
+
+	Note:
+	User-defined commands must start with a capital letter.  You cannot
+	use ":X", ":Next" and ":Print".  The underscore cannot be used!  You
+	can use digits, but this is discouraged.
+
+To list the user-defined commands, execute the following command: >
+
+	:command
+
+Just like with the builtin commands, the user defined commands can be
+abbreviated.  You need to type just enough to distinguish the command from
+another.  Command line completion can be used to get the full name.
+
+
+NUMBER OF ARGUMENTS
+
+User-defined commands can take a series of arguments.  The number of arguments
+must be specified by the -nargs option.  For instance, the example
+:DeleteFirst command takes no arguments, so you could have defined it as
+follows: >
+
+	:command -nargs=0 DeleteFirst 1delete
+
+However, because zero arguments is the default, you do not need to add
+"-nargs=0".  The other values of -nargs are as follows:
+
+	-nargs=0	No arguments
+	-nargs=1	One argument
+	-nargs=*	Any number of arguments
+	-nargs=?	Zero or one argument
+	-nargs=+	One or more arguments
+
+
+USING THE ARGUMENTS
+
+Inside the command definition, the arguments are represented by the
+<args> keyword.  For example: >
+
+	:command -nargs=+ Say :echo "<args>"
+
+Now when you type >
+
+	:Say Hello World
+
+Vim echoes "Hello World".  However, if you add a double quote, it won't work.
+For example: >
+
+	:Say he said "hello"
+
+To get special characters turned into a string, properly escaped to use as an
+expression, use "<q-args>": >
+
+	:command -nargs=+ Say :echo <q-args>
+
+Now the above ":Say" command will result in this to be executed: >
+
+	:echo "he said \"hello\""
+
+The <f-args> keyword contains the same information as the <args> keyword,
+except in a format suitable for use as function call arguments.  For example:
+>
+	:command -nargs=* DoIt :call AFunction(<f-args>)
+	:DoIt a b c
+
+Executes the following command: >
+
+	:call AFunction("a", "b", "c")
+
+
+LINE RANGE
+
+Some commands take a range as their argument.  To tell Vim that you are
+defining such a command, you need to specify a -range option.  The values for
+this option are as follows:
+
+	-range		Range is allowed; default is the current line.
+	-range=%	Range is allowed; default is the whole file.
+	-range={count}	Range is allowed; the last number in it is used as a
+			single number whose default is {count}.
+
+When a range is specified, the keywords <line1> and <line2> get the values of
+the first and last line in the range.  For example, the following command
+defines the SaveIt command, which writes out the specified range to the file
+"save_file": >
+
+	:command -range=% SaveIt :<line1>,<line2>write! save_file
+
+
+OTHER OPTIONS
+
+Some of the other options and keywords are as follows:
+
+	-count={number}		The command can take a count whose default is
+				{number}.  The resulting count can be used
+				through the <count> keyword.
+	-bang			You can use a !.  If present, using <bang> will
+				result in a !.
+	-register		You can specify a register.  (The default is
+				the unnamed register.)
+				The register specification is available as
+				<reg> (a.k.a. <register>).
+	-complete={type}	Type of command-line completion used.  See
+				|:command-completion| for the list of possible
+				values.
+	-bar			The command can be followed by | and another
+				command, or " and a comment.
+	-buffer			The command is only available for the current
+				buffer.
+
+Finally, you have the <lt> keyword.  It stands for the character <.  Use this
+to escape the special meaning of the <> items mentioned.
+
+
+REDEFINING AND DELETING
+
+To redefine the same command use the ! argument: >
+
+	:command -nargs=+ Say :echo "<args>"
+	:command! -nargs=+ Say :echo <q-args>
+
+To delete a user command use ":delcommand".  It takes a single argument, which
+is the name of the command.  Example: >
+
+	:delcommand SaveIt
+
+To delete all the user commands: >
+
+	:comclear
+
+Careful, this can't be undone!
+
+More details about all this in the reference manual: |user-commands|.
+
+==============================================================================
+*40.3*	Autocommands
+
+An autocommand is a command that is executed automatically in response to some
+event, such as a file being read or written or a buffer change.  Through the
+use of autocommands you can train Vim to edit compressed files, for example.
+That is used in the |gzip| plugin.
+   Autocommands are very powerful.  Use them with care and they will help you
+avoid typing many commands.  Use them carelessly and they will cause a lot of
+trouble.
+
+Suppose you want to replace a datestamp on the end of a file every time it is
+written.  First you define a function: >
+
+	:function DateInsert()
+	:  $delete
+	:  read !date
+	:endfunction
+
+You want this function to be called each time, just before a file is written.
+This will make that happen: >
+
+	:autocmd FileWritePre *  call DateInsert()
+
+"FileWritePre" is the event for which this autocommand is triggered: Just
+before (pre) writing a file.  The "*" is a pattern to match with the file
+name.  In this case it matches all files.
+   With this command enabled, when you do a ":write", Vim checks for any
+matching FileWritePre autocommands and executes them, and then it
+performs the ":write".
+   The general form of the :autocmd command is as follows: >
+
+	:autocmd [group] {events} {file_pattern} [nested] {command}
+
+The [group] name is optional.  It is used in managing and calling the commands
+(more on this later).  The {events} parameter is a list of events (comma
+separated) that trigger the command.
+   {file_pattern} is a filename, usually with wildcards.  For example, using
+"*.txt" makes the autocommand be used for all files whose name end in ".txt".
+The optional [nested] flag allows for nesting of autocommands (see below), and
+finally, {command} is the command to be executed.
+
+
+EVENTS
+
+One of the most useful events is BufReadPost.  It is triggered after a new
+file is being edited.  It is commonly used to set option values.  For example,
+you know that "*.gsm" files are GNU assembly language.  To get the syntax file
+right, define this autocommand: >
+
+	:autocmd BufReadPost *.gsm  set filetype=asm
+
+If Vim is able to detect the type of file, it will set the 'filetype' option
+for you.  This triggers the Filetype event.  Use this to do something when a
+certain type of file is edited.  For example, to load a list of abbreviations
+for text files: >
+
+	:autocmd Filetype text  source ~/.vim/abbrevs.vim
+
+When starting to edit a new file, you could make Vim insert a skeleton: >
+
+	:autocmd BufNewFile *.[ch]  0read ~/skeletons/skel.c
+
+See |autocmd-events| for a complete list of events.
+
+
+PATTERNS
+
+The {file_pattern} argument can actually be a comma-separated list of file
+patterns.  For example: "*.c,*.h" matches files ending in ".c" and ".h".
+   The usual file wildcards can be used.  Here is a summary of the most often
+used ones:
+
+	*		Match any character any number of times
+	?		Match any character once
+	[abc]		Match the character a, b or c
+	.		Matches a dot
+	a{b,c}		Matches "ab" and "ac"
+
+When the pattern includes a slash (/) Vim will compare directory names.
+Without the slash only the last part of a file name is used.  For example,
+"*.txt" matches "/home/biep/readme.txt".  The pattern "/home/biep/*" would
+also match it.  But "home/foo/*.txt" wouldn't.
+   When including a slash, Vim matches the pattern against both the full path
+of the file ("/home/biep/readme.txt") and the relative path (e.g.,
+"biep/readme.txt").
+
+	Note:
+	When working on a system that uses a backslash as file separator, such
+	as MS-Windows, you still use forward slashes in autocommands.  This
+	makes it easier to write the pattern, since a backslash has a special
+	meaning.  It also makes the autocommands portable.
+
+
+DELETING
+
+To delete an autocommand, use the same command as what it was defined with,
+but leave out the {command} at the end and use a !.  Example: >
+
+	:autocmd! FileWritePre *
+
+This will delete all autocommands for the "FileWritePre" event that use the
+"*" pattern.
+
+
+LISTING
+
+To list all the currently defined autocommands, use this: >
+
+	:autocmd
+
+The list can be very long, especially when filetype detection is used.  To
+list only part of the commands, specify the group, event and/or pattern.  For
+example, to list all BufNewFile autocommands: >
+
+	:autocmd BufNewFile
+
+To list all autocommands for the pattern "*.c": >
+
+	:autocmd * *.c
+
+Using "*" for the event will list all the events.  To list all autocommands
+for the cprograms group: >
+
+	:autocmd cprograms
+
+
+GROUPS
+
+The {group} item, used when defining an autocommand, groups related autocommands
+together.  This can be used to delete all the autocommands in a certain group,
+for example.
+   When defining several autocommands for a certain group, use the ":augroup"
+command.  For example, let's define autocommands for C programs: >
+
+	:augroup cprograms
+	:  autocmd BufReadPost *.c,*.h :set sw=4 sts=4
+	:  autocmd BufReadPost *.cpp   :set sw=3 sts=3
+	:augroup END
+
+This will do the same as: >
+
+	:autocmd cprograms BufReadPost *.c,*.h :set sw=4 sts=4
+	:autocmd cprograms BufReadPost *.cpp   :set sw=3 sts=3
+
+To delete all autocommands in the "cprograms" group: >
+
+	:autocmd! cprograms
+
+
+NESTING
+
+Generally, commands executed as the result of an autocommand event will not
+trigger any new events.  If you read a file in response to a FileChangedShell
+event, it will not trigger the autocommands that would set the syntax, for
+example.  To make the events triggered, add the "nested" argument: >
+
+	:autocmd FileChangedShell * nested  edit
+
+
+EXECUTING AUTOCOMMANDS
+
+It is possible to trigger an autocommand by pretending an event has occurred.
+This is useful to have one autocommand trigger another one.  Example: >
+
+	:autocmd BufReadPost *.new  execute "doautocmd BufReadPost " . expand("<afile>:r")
+
+This defines an autocommand that is triggered when a new file has been edited.
+The file name must end in ".new".  The ":execute" command uses expression
+evaluation to form a new command and execute it.  When editing the file
+"tryout.c.new" the executed command will be: >
+
+	:doautocmd BufReadPost tryout.c
+
+The expand() function takes the "<afile>" argument, which stands for the file
+name the autocommand was executed for, and takes the root of the file name
+with ":r".
+
+":doautocmd" executes on the current buffer.  The ":doautoall" command works
+like "doautocmd" except it executes on all the buffers.
+
+
+USING NORMAL MODE COMMANDS
+
+The commands executed by an autocommand are Command-line commands.  If you
+want to use a Normal mode command, the ":normal" command can be used.
+Example: >
+
+	:autocmd BufReadPost *.log normal G
+
+This will make the cursor jump to the last line of *.log files when you start
+to edit it.
+   Using the ":normal" command is a bit tricky.  First of all, make sure its
+argument is a complete command, including all the arguments.  When you use "i"
+to go to Insert mode, there must also be a <Esc> to leave Insert mode again.
+If you use a "/" to start a search pattern, there must be a <CR> to execute
+it.
+   The ":normal" command uses all the text after it as commands.  Thus there
+can be no | and another command following.  To work around this, put the
+":normal" command inside an ":execute" command.  This also makes it possible
+to pass unprintable characters in a convenient way.  Example: >
+
+	:autocmd BufReadPost *.chg execute "normal ONew entry:\<Esc>" |
+		\ 1read !date
+
+This also shows the use of a backslash to break a long command into more
+lines.  This can be used in Vim scripts (not at the command line).
+
+When you want the autocommand do something complicated, which involves jumping
+around in the file and then returning to the original position, you may want
+to restore the view on the file.  See |restore-position| for an example.
+
+
+IGNORING EVENTS
+
+At times, you will not want to trigger an autocommand.  The 'eventignore'
+option contains a list of events that will be totally ignored.  For example,
+the following causes events for entering and leaving a window to be ignored: >
+
+	:set eventignore=WinEnter,WinLeave
+
+To ignore all events, use the following command: >
+
+	:set eventignore=all
+
+To set it back to the normal behavior, make 'eventignore' empty: >
+
+	:set eventignore=
+
+==============================================================================
+
+Next chapter: |usr_41.txt|  Write a Vim script
+
+Copyright: see |manual-copyright|  vim:tw=78:ts=8:ft=help:norl:
--- /dev/null
+++ b/lib/vimfiles/doc/usr_41.txt
@@ -1,0 +1,2387 @@
+*usr_41.txt*	For Vim version 7.1.  Last change: 2007 Apr 26
+
+		     VIM USER MANUAL - by Bram Moolenaar
+
+			      Write a Vim script
+
+
+The Vim script language is used for the startup vimrc file, syntax files, and
+many other things.  This chapter explains the items that can be used in a Vim
+script.  There are a lot of them, thus this is a long chapter.
+
+|41.1|	Introduction
+|41.2|	Variables
+|41.3|	Expressions
+|41.4|	Conditionals
+|41.5|	Executing an expression
+|41.6|	Using functions
+|41.7|	Defining a function
+|41.8|	Lists and Dictionaries
+|41.9|	Exceptions
+|41.10|	Various remarks
+|41.11|	Writing a plugin
+|41.12|	Writing a filetype plugin
+|41.13|	Writing a compiler plugin
+|41.14|	Writing a plugin that loads quickly
+|41.15|	Writing library scripts
+|41.16|	Distributing Vim scripts
+
+     Next chapter: |usr_42.txt|  Add new menus
+ Previous chapter: |usr_40.txt|  Make new commands
+Table of contents: |usr_toc.txt|
+
+==============================================================================
+*41.1*	Introduction				*vim-script-intro* *script*
+
+Your first experience with Vim scripts is the vimrc file.  Vim reads it when
+it starts up and executes the commands.  You can set options to values you
+prefer.  And you can use any colon command in it (commands that start with a
+":"; these are sometimes referred to as Ex commands or command-line commands).
+   Syntax files are also Vim scripts.  As are files that set options for a
+specific file type.  A complicated macro can be defined by a separate Vim
+script file.  You can think of other uses yourself.
+
+Let's start with a simple example: >
+
+	:let i = 1
+	:while i < 5
+	:  echo "count is" i
+	:  let i += 1
+	:endwhile
+<
+	Note:
+	The ":" characters are not really needed here.  You only need to use
+	them when you type a command.  In a Vim script file they can be left
+	out.  We will use them here anyway to make clear these are colon
+	commands and make them stand out from Normal mode commands.
+	Note:
+	You can try out the examples by yanking the lines from the text here
+	and executing them with :@"
+
+The output of the example code is:
+
+	count is 1 ~
+	count is 2 ~
+	count is 3 ~
+	count is 4 ~
+
+In the first line the ":let" command assigns a value to a variable.  The
+generic form is: >
+
+	:let {variable} = {expression}
+
+In this case the variable name is "i" and the expression is a simple value,
+the number one.
+   The ":while" command starts a loop.  The generic form is: >
+
+	:while {condition}
+	:  {statements}
+	:endwhile
+
+The statements until the matching ":endwhile" are executed for as long as the
+condition is true.  The condition used here is the expression "i < 5".  This
+is true when the variable i is smaller than five.
+	Note:
+	If you happen to write a while loop that keeps on running, you can
+	interrupt it by pressing CTRL-C (CTRL-Break on MS-Windows).
+
+The ":echo" command prints its arguments.  In this case the string "count is"
+and the value of the variable i.  Since i is one, this will print:
+
+	count is 1 ~
+
+Then there is the ":let i += 1" command.  This does the same thing as
+":let i = i + 1".  This adds one to the variable i and assigns the new value
+to the same variable.
+
+The example was given to explain the commands, but would you really want to
+make such a loop it can be written much more compact: >
+
+	:for i in range(1, 4)
+	:  echo "count is" i
+	:endfor
+
+We won't explain how |:for| and |range()| work until later.  Follow the links
+if you are impatient.
+
+
+THREE KINDS OF NUMBERS
+
+Numbers can be decimal, hexadecimal or octal.  A hexadecimal number starts
+with "0x" or "0X".  For example "0x1f" is decimal 31.  An octal number starts
+with a zero.  "017" is decimal 15.  Careful: don't put a zero before a decimal
+number, it will be interpreted as an octal number!
+   The ":echo" command always prints decimal numbers.  Example: >
+
+	:echo 0x7f 036
+<	127 30 ~
+
+A number is made negative with a minus sign.  This also works for hexadecimal
+and octal numbers.   A minus sign is also used for subtraction.  Compare this
+with the previous example: >
+
+	:echo 0x7f -036
+<	97 ~
+
+White space in an expression is ignored.  However, it's recommended to use it
+for separating items, to make the expression easier to read.  For example, to
+avoid the confusion with a negative number above, put a space between the
+minus sign and the following number: >
+
+	:echo 0x7f - 036
+
+==============================================================================
+*41.2*	Variables
+
+A variable name consists of ASCII letters, digits and the underscore.  It
+cannot start with a digit.  Valid variable names are:
+
+	counter
+	_aap3
+	very_long_variable_name_with_underscores
+	FuncLength
+	LENGTH
+
+Invalid names are "foo+bar" and "6var".
+   These variables are global.  To see a list of currently defined variables
+use this command: >
+
+	:let
+
+You can use global variables everywhere.  This also means that when the
+variable "count" is used in one script file, it might also be used in another
+file.  This leads to confusion at least, and real problems at worst.  To avoid
+this, you can use a variable local to a script file by prepending "s:".  For
+example, one script contains this code: >
+
+	:let s:count = 1
+	:while s:count < 5
+	:  source other.vim
+	:  let s:count += 1
+	:endwhile
+
+Since "s:count" is local to this script, you can be sure that sourcing the
+"other.vim" script will not change this variable.  If "other.vim" also uses an
+"s:count" variable, it will be a different copy, local to that script.  More
+about script-local variables here: |script-variable|.
+
+There are more kinds of variables, see |internal-variables|.  The most often
+used ones are:
+
+	b:name		variable local to a buffer
+	w:name		variable local to a window
+	g:name		global variable (also in a function)
+	v:name		variable predefined by Vim
+
+
+DELETING VARIABLES
+
+Variables take up memory and show up in the output of the ":let" command.  To
+delete a variable use the ":unlet" command.  Example: >
+
+	:unlet s:count
+
+This deletes the script-local variable "s:count" to free up the memory it
+uses.  If you are not sure if the variable exists, and don't want an error
+message when it doesn't, append !: >
+
+	:unlet! s:count
+
+When a script finishes, the local variables used there will not be
+automatically freed.  The next time the script executes, it can still use the
+old value.  Example: >
+
+	:if !exists("s:call_count")
+	:  let s:call_count = 0
+	:endif
+	:let s:call_count = s:call_count + 1
+	:echo "called" s:call_count "times"
+
+The "exists()" function checks if a variable has already been defined.  Its
+argument is the name of the variable you want to check.  Not the variable
+itself!  If you would do this: >
+
+	:if !exists(s:call_count)
+
+Then the value of s:call_count will be used as the name of the variable that
+exists() checks.  That's not what you want.
+   The exclamation mark ! negates a value.  When the value was true, it
+becomes false.  When it was false, it becomes true.  You can read it as "not".
+Thus "if !exists()" can be read as "if not exists()".
+   What Vim calls true is anything that is not zero.  Zero is false.
+	Note:
+	Vim automatically converts a string to a number when it is looking for
+	a number.  When using a string that doesn't start with a digit the
+	resulting number is zero.  Thus look out for this: >
+		:if "true"
+<	The "true" will be interpreted as a zero, thus as false!
+
+
+STRING VARIABLES AND CONSTANTS
+
+So far only numbers were used for the variable value.  Strings can be used as
+well.  Numbers and strings are the basic types of variables that Vim supports.
+The type is dynamic, it is set each time when assigning a value to the
+variable with ":let".  More about types in |41.8|.
+   To assign a string value to a variable, you need to use a string constant.
+There are two types of these.  First the string in double quotes: >
+
+	:let name = "peter"
+	:echo name
+<	peter ~
+
+If you want to include a double quote inside the string, put a backslash in
+front of it: >
+
+	:let name = "\"peter\""
+	:echo name
+<	"peter" ~
+
+To avoid the need for a backslash, you can use a string in single quotes: >
+
+	:let name = '"peter"'
+	:echo name
+<	"peter" ~
+
+Inside a single-quote string all the characters are as they are.  Only the
+single quote itself is special: you need to use two to get one.  A backslash
+is taken literally, thus you can't use it to change the meaning of the
+character after it.
+   In double-quote strings it is possible to use special characters.  Here are
+a few useful ones:
+
+	\t		<Tab>
+	\n		<NL>, line break
+	\r		<CR>, <Enter>
+	\e		<Esc>
+	\b		<BS>, backspace
+	\"		"
+	\\		\, backslash
+	\<Esc>		<Esc>
+	\<C-W>		CTRL-W
+
+The last two are just examples.  The  "\<name>" form can be used to include
+the special key "name".
+   See |expr-quote| for the full list of special items in a string.
+
+==============================================================================
+*41.3*	Expressions
+
+Vim has a rich, yet simple way to handle expressions.  You can read the
+definition here: |expression-syntax|.  Here we will show the most common
+items.
+   The numbers, strings and variables mentioned above are expressions by
+themselves.  Thus everywhere an expression is expected, you can use a number,
+string or variable.  Other basic items in an expression are:
+
+	$NAME		environment variable
+	&name		option
+	@r		register
+
+Examples: >
+
+	:echo "The value of 'tabstop' is" &ts
+	:echo "Your home directory is" $HOME
+	:if @a > 5
+
+The &name form can be used to save an option value, set it to a new value,
+do something and restore the old value.  Example: >
+
+	:let save_ic = &ic
+	:set noic
+	:/The Start/,$delete
+	:let &ic = save_ic
+
+This makes sure the "The Start" pattern is used with the 'ignorecase' option
+off.  Still, it keeps the value that the user had set.  (Another way to do
+this would be to add "\C" to the pattern, see |/\C|.)
+
+
+MATHEMATICS
+
+It becomes more interesting if we combine these basic items.  Let's start with
+mathematics on numbers:
+
+	a + b		add
+	a - b		subtract
+	a * b		multiply
+	a / b		divide
+	a % b		modulo
+
+The usual precedence is used.  Example: >
+
+	:echo 10 + 5 * 2
+<	20 ~
+
+Grouping is done with braces.  No surprises here.  Example: >
+
+	:echo (10 + 5) * 2
+<	30 ~
+
+Strings can be concatenated with ".".  Example: >
+
+	:echo "foo" . "bar"
+<	foobar ~
+
+When the ":echo" command gets multiple arguments, it separates them with a
+space.  In the example the argument is a single expression, thus no space is
+inserted.
+
+Borrowed from the C language is the conditional expression:
+
+	a ? b : c
+
+If "a" evaluates to true "b" is used, otherwise "c" is used.  Example: >
+
+	:let i = 4
+	:echo i > 5 ? "i is big" : "i is small"
+<	i is small ~
+
+The three parts of the constructs are always evaluated first, thus you could
+see it work as:
+
+	(a) ? (b) : (c)
+
+==============================================================================
+*41.4*	Conditionals
+
+The ":if" commands executes the following statements, until the matching
+":endif", only when a condition is met.  The generic form is:
+
+	:if {condition}
+	   {statements}
+	:endif
+
+Only when the expression {condition} evaluates to true (non-zero) will the
+{statements} be executed.  These must still be valid commands.  If they
+contain garbage, Vim won't be able to find the ":endif".
+   You can also use ":else".  The generic form for this is:
+
+	:if {condition}
+	   {statements}
+	:else
+	   {statements}
+	:endif
+
+The second {statements} is only executed if the first one isn't.
+   Finally, there is ":elseif":
+
+	:if {condition}
+	   {statements}
+	:elseif {condition}
+	   {statements}
+	:endif
+
+This works just like using ":else" and then "if", but without the need for an
+extra ":endif".
+   A useful example for your vimrc file is checking the 'term' option and
+doing something depending upon its value: >
+
+	:if &term == "xterm"
+	:  " Do stuff for xterm
+	:elseif &term == "vt100"
+	:  " Do stuff for a vt100 terminal
+	:else
+	:  " Do something for other terminals
+	:endif
+
+
+LOGIC OPERATIONS
+
+We already used some of them in the examples.  These are the most often used
+ones:
+
+	a == b		equal to
+	a != b		not equal to
+	a >  b		greater than
+	a >= b		greater than or equal to
+	a <  b		less than
+	a <= b		less than or equal to
+
+The result is one if the condition is met and zero otherwise.  An example: >
+
+	:if v:version >= 700
+	:  echo "congratulations"
+	:else
+	:  echo "you are using an old version, upgrade!"
+	:endif
+
+Here "v:version" is a variable defined by Vim, which has the value of the Vim
+version.  600 is for version 6.0.  Version 6.1 has the value 601.  This is
+very useful to write a script that works with multiple versions of Vim.
+|v:version|
+
+The logic operators work both for numbers and strings.  When comparing two
+strings, the mathematical difference is used.  This compares byte values,
+which may not be right for some languages.
+   When comparing a string with a number, the string is first converted to a
+number.  This is a bit tricky, because when a string doesn't look like a
+number, the number zero is used.  Example: >
+
+	:if 0 == "one"
+	:  echo "yes"
+	:endif
+
+This will echo "yes", because "one" doesn't look like a number, thus it is
+converted to the number zero.
+
+For strings there are two more items:
+
+	a =~ b		matches with
+	a !~ b		does not match with
+
+The left item "a" is used as a string.  The right item "b" is used as a
+pattern, like what's used for searching.  Example: >
+
+	:if str =~ " "
+	:  echo "str contains a space"
+	:endif
+	:if str !~ '\.$'
+	:  echo "str does not end in a full stop"
+	:endif
+
+Notice the use of a single-quote string for the pattern.  This is useful,
+because backslashes would need to be doubled in a double-quote string and
+patterns tend to contain many backslashes.
+
+The 'ignorecase' option is used when comparing strings.  When you don't want
+that, append "#" to match case and "?" to ignore case.  Thus "==?" compares
+two strings to be equal while ignoring case.  And "!~#" checks if a pattern
+doesn't match, also checking the case of letters.  For the full table see
+|expr-==|.
+
+
+MORE LOOPING
+
+The ":while" command was already mentioned.  Two more statements can be used
+in between the ":while" and the ":endwhile":
+
+	:continue		Jump back to the start of the while loop; the
+				loop continues.
+	:break			Jump forward to the ":endwhile"; the loop is
+				discontinued.
+
+Example: >
+
+	:while counter < 40
+	:  call do_something()
+	:  if skip_flag
+	:    continue
+	:  endif
+	:  if finished_flag
+	:    break
+	:  endif
+	:  sleep 50m
+	:endwhile
+
+The ":sleep" command makes Vim take a nap.  The "50m" specifies fifty
+milliseconds.  Another example is ":sleep 4", which sleeps for four seconds.
+
+Even more looping can be done with the ":for" command, see below in |41.8|.
+
+==============================================================================
+*41.5*	Executing an expression
+
+So far the commands in the script were executed by Vim directly.  The
+":execute" command allows executing the result of an expression.  This is a
+very powerful way to build commands and execute them.
+   An example is to jump to a tag, which is contained in a variable: >
+
+	:execute "tag " . tag_name
+
+The "." is used to concatenate the string "tag " with the value of variable
+"tag_name".  Suppose "tag_name" has the value "get_cmd", then the command that
+will be executed is: >
+
+	:tag get_cmd
+
+The ":execute" command can only execute colon commands.  The ":normal" command
+executes Normal mode commands.  However, its argument is not an expression but
+the literal command characters.  Example: >
+
+	:normal gg=G
+
+This jumps to the first line and formats all lines with the "=" operator.
+   To make ":normal" work with an expression, combine ":execute" with it.
+Example: >
+
+	:execute "normal " . normal_commands
+
+The variable "normal_commands" must contain the Normal mode commands.
+   Make sure that the argument for ":normal" is a complete command.  Otherwise
+Vim will run into the end of the argument and abort the command.  For example,
+if you start Insert mode, you must leave Insert mode as well.  This works: >
+
+	:execute "normal Inew text \<Esc>"
+
+This inserts "new text " in the current line.  Notice the use of the special
+key "\<Esc>".  This avoids having to enter a real <Esc> character in your
+script.
+
+If you don't want to execute a string but evaluate it to get its expression
+value, you can use the eval() function: >
+
+	:let optname = "path"
+	:let optval = eval('&' . optname)
+
+A "&" character is prepended to "path", thus the argument to eval() is
+"&path".  The result will then be the value of the 'path' option.
+   The same thing can be done with: >
+	:exe 'let optval = &' . optname
+
+==============================================================================
+*41.6*	Using functions
+
+Vim defines many functions and provides a large amount of functionality that
+way.  A few examples will be given in this section.  You can find the whole
+list here: |functions|.
+
+A function is called with the ":call" command.  The parameters are passed in
+between braces, separated by commas.  Example: >
+
+	:call search("Date: ", "W")
+
+This calls the search() function, with arguments "Date: " and "W".  The
+search() function uses its first argument as a search pattern and the second
+one as flags.  The "W" flag means the search doesn't wrap around the end of
+the file.
+
+A function can be called in an expression.  Example: >
+
+	:let line = getline(".")
+	:let repl = substitute(line, '\a', "*", "g")
+	:call setline(".", repl)
+
+The getline() function obtains a line from the current buffer.  Its argument
+is a specification of the line number.  In this case "." is used, which means
+the line where the cursor is.
+   The substitute() function does something similar to the ":substitute"
+command.  The first argument is the string on which to perform the
+substitution.  The second argument is the pattern, the third the replacement
+string.  Finally, the last arguments are the flags.
+   The setline() function sets the line, specified by the first argument, to a
+new string, the second argument.  In this example the line under the cursor is
+replaced with the result of the substitute().  Thus the effect of the three
+statements is equal to: >
+
+	:substitute/\a/*/g
+
+Using the functions becomes more interesting when you do more work before and
+after the substitute() call.
+
+
+FUNCTIONS						*function-list*
+
+There are many functions.  We will mention them here, grouped by what they are
+used for.  You can find an alphabetical list here: |functions|.  Use CTRL-] on
+the function name to jump to detailed help on it.
+
+String manipulation:
+	nr2char()		get a character by its ASCII value
+	char2nr()		get ASCII value of a character
+	str2nr()		convert a string to a number
+	printf()		format a string according to % items
+	escape()		escape characters in a string with a '\'
+	tr()			translate characters from one set to another
+	strtrans()		translate a string to make it printable
+	tolower()		turn a string to lowercase
+	toupper()		turn a string to uppercase
+	match()			position where a pattern matches in a string
+	matchend()		position where a pattern match ends in a string
+	matchstr()		match of a pattern in a string
+	matchlist()		like matchstr() and also return submatches
+	stridx()		first index of a short string in a long string
+	strridx()		last index of a short string in a long string
+	strlen()		length of a string
+	substitute()		substitute a pattern match with a string
+	submatch()		get a specific match in a ":substitute"
+	strpart()		get part of a string
+	expand()		expand special keywords
+	iconv()			convert text from one encoding to another
+	byteidx()		byte index of a character in a string
+	repeat()		repeat a string multiple times
+	eval()			evaluate a string expression
+
+List manipulation:
+	get()			get an item without error for wrong index
+	len()			number of items in a List
+	empty()			check if List is empty
+	insert()		insert an item somewhere in a List
+	add()			append an item to a List
+	extend()		append a List to a List
+	remove()		remove one or more items from a List
+	copy()			make a shallow copy of a List
+	deepcopy()		make a full copy of a List
+	filter()		remove selected items from a List
+	map()			change each List item
+	sort()			sort a List
+	reverse()		reverse the order of a List
+	split()			split a String into a List
+	join()			join List items into a String
+	range()			return a List with a sequence of numbers
+	string()		String representation of a List
+	call()			call a function with List as arguments
+	index()			index of a value in a List
+	max()			maximum value in a List
+	min()			minimum value in a List
+	count()			count number of times a value appears in a List
+	repeat()		repeat a List multiple times
+
+Dictionary manipulation:
+	get()			get an entry without an error for a wrong key
+	len()			number of entries in a Dictionary
+	has_key()		check whether a key appears in a Dictionary
+	empty()			check if Dictionary is empty
+	remove()		remove an entry from a Dictionary
+	extend()		add entries from one Dictionary to another
+	filter()		remove selected entries from a Dictionary
+	map()			change each Dictionary entry
+	keys()			get List of Dictionary keys
+	values()		get List of Dictionary values
+	items()			get List of Dictionary key-value pairs
+	copy()			make a shallow copy of a Dictionary
+	deepcopy()		make a full copy of a Dictionary
+	string()		String representation of a Dictionary
+	max()			maximum value in a Dictionary
+	min()			minimum value in a Dictionary
+	count()			count number of times a value appears
+
+Variables:
+	type()			type of a variable
+	islocked()		check if a variable is locked
+	function()		get a Funcref for a function name
+	getbufvar()		get a variable value from a specific buffer
+	setbufvar()		set a variable in a specific buffer
+	getwinvar()		get a variable from specific window
+	gettabwinvar()		get a variable from specific window & tab page
+	setwinvar()		set a variable in a specific window
+	settabwinvar()		set a variable in a specific window & tab page
+	garbagecollect()	possibly free memory
+
+Cursor and mark position:
+	col()			column number of the cursor or a mark
+	virtcol()		screen column of the cursor or a mark
+	line()			line number of the cursor or mark
+	wincol()		window column number of the cursor
+	winline()		window line number of the cursor
+	cursor()		position the cursor at a line/column
+	getpos()		get position of cursor, mark, etc.
+	setpos()		set position of cursor, mark, etc.
+	byte2line()		get line number at a specific byte count
+	line2byte()		byte count at a specific line
+	diff_filler()		get the number of filler lines above a line
+
+Working with text in the current buffer:
+	getline()		get a line or list of lines from the buffer
+	setline()		replace a line in the buffer
+	append()		append line or list of lines in the buffer
+	indent()		indent of a specific line
+	cindent()		indent according to C indenting
+	lispindent()		indent according to Lisp indenting
+	nextnonblank()		find next non-blank line
+	prevnonblank()		find previous non-blank line
+	search()		find a match for a pattern
+	searchpos()		find a match for a pattern
+	searchpair()		find the other end of a start/skip/end
+	searchpairpos()		find the other end of a start/skip/end
+	searchdecl()		search for the declaration of a name
+
+System functions and manipulation of files:
+	glob()			expand wildcards
+	globpath()		expand wildcards in a number of directories
+	findfile()		find a file in a list of directories
+	finddir()		find a directory in a list of directories
+	resolve()		find out where a shortcut points to
+	fnamemodify()		modify a file name
+	pathshorten()		shorten directory names in a path
+	simplify()		simplify a path without changing its meaning
+	executable()		check if an executable program exists
+	filereadable()		check if a file can be read
+	filewritable()		check if a file can be written to
+	getfperm()		get the permissions of a file
+	getftype()		get the kind of a file
+	isdirectory()		check if a directory exists
+	getfsize()		get the size of a file
+	getcwd()		get the current working directory
+	haslocaldir()		check if current window used |:lcd|
+	tempname()		get the name of a temporary file
+	mkdir()			create a new directory
+	delete()		delete a file
+	rename()		rename a file
+	system()		get the result of a shell command
+	hostname()		name of the system
+	readfile()		read a file into a List of lines
+	writefile()		write a List of lines into a file
+
+Date and Time:
+	getftime()		get last modification time of a file
+	localtime()		get current time in seconds
+	strftime()		convert time to a string
+	reltime()		get the current or elapsed time accurately
+	reltimestr()		convert reltime() result to a string
+
+Buffers, windows and the argument list:
+	argc()			number of entries in the argument list
+	argidx()		current position in the argument list
+	argv()			get one entry from the argument list
+	bufexists()		check if a buffer exists
+	buflisted()		check if a buffer exists and is listed
+	bufloaded()		check if a buffer exists and is loaded
+	bufname()		get the name of a specific buffer
+	bufnr()			get the buffer number of a specific buffer
+	tabpagebuflist()	return List of buffers in a tab page
+	tabpagenr()		get the number of a tab page
+	tabpagewinnr()		like winnr() for a specified tab page
+	winnr()			get the window number for the current window
+	bufwinnr()		get the window number of a specific buffer
+	winbufnr()		get the buffer number of a specific window
+	getbufline()		get a list of lines from the specified buffer
+
+Command line:
+	getcmdline()		get the current command line
+	getcmdpos()		get position of the cursor in the command line
+	setcmdpos()		set position of the cursor in the command line
+	getcmdtype()		return the current command-line type
+
+Quickfix and location lists:
+	getqflist()		list of quickfix errors
+	setqflist()		modify a quickfix list
+	getloclist()		list of location list items
+	setloclist()		modify a location list
+
+Insert mode completion:
+	complete()		set found matches
+	complete_add()		add to found matches
+	complete_check()	check if completion should be aborted
+	pumvisible()		check if the popup menu is displayed
+
+Folding:
+	foldclosed()		check for a closed fold at a specific line
+	foldclosedend()		like foldclosed() but return the last line
+	foldlevel()		check for the fold level at a specific line
+	foldtext()		generate the line displayed for a closed fold
+	foldtextresult()	get the text displayed for a closed fold
+
+Syntax and highlighting:
+	hlexists()		check if a highlight group exists
+	hlID()			get ID of a highlight group
+	synID()			get syntax ID at a specific position
+	synIDattr()		get a specific attribute of a syntax ID
+	synIDtrans()		get translated syntax ID
+	diff_hlID()		get highlight ID for diff mode at a position
+	matcharg()		get info about |:match| arguments
+
+Spelling:
+	spellbadword()		locate badly spelled word at or after cursor
+	spellsuggest()		return suggested spelling corrections
+	soundfold()		return the sound-a-like equivalent of a word
+
+History:
+	histadd()		add an item to a history
+	histdel()		delete an item from a history
+	histget()		get an item from a history
+	histnr()		get highest index of a history list
+
+Interactive:
+	browse()		put up a file requester
+	browsedir()		put up a directory requester
+	confirm()		let the user make a choice
+	getchar()		get a character from the user
+	getcharmod()		get modifiers for the last typed character
+	input()			get a line from the user
+	inputlist()		let the user pick an entry from a list
+	inputsecret()		get a line from the user without showing it
+	inputdialog()		get a line from the user in a dialog
+	inputsave()		save and clear typeahead
+	inputrestore()		restore typeahead
+
+GUI:
+	getfontname()		get name of current font being used
+	getwinposx()		X position of the GUI Vim window
+	getwinposy()		Y position of the GUI Vim window
+
+Vim server:
+	serverlist()		return the list of server names
+	remote_send()		send command characters to a Vim server
+	remote_expr()		evaluate an expression in a Vim server
+	server2client()		send a reply to a client of a Vim server
+	remote_peek()		check if there is a reply from a Vim server
+	remote_read()		read a reply from a Vim server
+	foreground()		move the Vim window to the foreground
+	remote_foreground()	move the Vim server window to the foreground
+
+Window size and position:
+	winheight()		get height of a specific window
+	winwidth()		get width of a specific window
+	winrestcmd()		return command to restore window sizes
+	winsaveview()		get view of current window
+	winrestview()		restore saved view of current window
+
+Various:
+	mode()			get current editing mode
+	visualmode()		last visual mode used
+	hasmapto()		check if a mapping exists
+	mapcheck()		check if a matching mapping exists
+	maparg()		get rhs of a mapping
+	exists()		check if a variable, function, etc. exists
+	has()			check if a feature is supported in Vim
+	changenr()		return number of most recent change
+	cscope_connection()	check if a cscope connection exists
+	did_filetype()		check if a FileType autocommand was used
+	eventhandler()		check if invoked by an event handler
+
+	libcall()		call a function in an external library
+	libcallnr()		idem, returning a number
+
+	getreg()		get contents of a register
+	getregtype()		get type of a register
+	setreg()		set contents and type of a register
+
+	taglist()		get list of matching tags
+	tagfiles()		get a list of tags files
+
+==============================================================================
+*41.7*	Defining a function
+
+Vim enables you to define your own functions.  The basic function declaration
+begins as follows: >
+
+	:function {name}({var1}, {var2}, ...)
+	:  {body}
+	:endfunction
+<
+	Note:
+	Function names must begin with a capital letter.
+
+Let's define a short function to return the smaller of two numbers.  It starts
+with this line: >
+
+	:function Min(num1, num2)
+
+This tells Vim that the function is named "Min" and it takes two arguments:
+"num1" and "num2".
+   The first thing you need to do is to check to see which number is smaller:
+   >
+	:  if a:num1 < a:num2
+
+The special prefix "a:" tells Vim that the variable is a function argument.
+Let's assign the variable "smaller" the value of the smallest number: >
+
+	:  if a:num1 < a:num2
+	:    let smaller = a:num1
+	:  else
+	:    let smaller = a:num2
+	:  endif
+
+The variable "smaller" is a local variable.  Variables used inside a function
+are local unless prefixed by something like "g:", "a:", or "s:".
+
+	Note:
+	To access a global variable from inside a function you must prepend
+	"g:" to it.  Thus "g:count" inside a function is used for the global
+	variable "count", and "count" is another variable, local to the
+	function.
+
+You now use the ":return" statement to return the smallest number to the user.
+Finally, you end the function: >
+
+	:  return smaller
+	:endfunction
+
+The complete function definition is as follows: >
+
+	:function Min(num1, num2)
+	:  if a:num1 < a:num2
+	:    let smaller = a:num1
+	:  else
+	:    let smaller = a:num2
+	:  endif
+	:  return smaller
+	:endfunction
+
+For people who like short functions, this does the same thing: >
+
+	:function Min(num1, num2)
+	:  if a:num1 < a:num2
+	:    return a:num1
+	:  endif
+	:  return a:num2
+	:endfunction
+
+A user defined function is called in exactly the same way as a built-in
+function.  Only the name is different.  The Min function can be used like
+this: >
+
+	:echo Min(5, 8)
+
+Only now will the function be executed and the lines be interpreted by Vim.
+If there are mistakes, like using an undefined variable or function, you will
+now get an error message.  When defining the function these errors are not
+detected.
+
+When a function reaches ":endfunction" or ":return" is used without an
+argument, the function returns zero.
+
+To redefine a function that already exists, use the ! for the ":function"
+command: >
+
+	:function!  Min(num1, num2, num3)
+
+
+USING A RANGE
+
+The ":call" command can be given a line range.  This can have one of two
+meanings.  When a function has been defined with the "range" keyword, it will
+take care of the line range itself.
+  The function will be passed the variables "a:firstline" and "a:lastline".
+These will have the line numbers from the range the function was called with.
+Example: >
+
+	:function Count_words() range
+	:  let n = a:firstline
+	:  let count = 0
+	:  while n <= a:lastline
+	:    let count = count + Wordcount(getline(n))
+	:    let n = n + 1
+	:  endwhile
+	:  echo "found " . count . " words"
+	:endfunction
+
+You can call this function with: >
+
+	:10,30call Count_words()
+
+It will be executed once and echo the number of words.
+   The other way to use a line range is by defining a function without the
+"range" keyword.  The function will be called once for every line in the
+range, with the cursor in that line.  Example: >
+
+	:function  Number()
+	:  echo "line " . line(".") . " contains: " . getline(".")
+	:endfunction
+
+If you call this function with: >
+
+	:10,15call Number()
+
+The function will be called six times.
+
+
+VARIABLE NUMBER OF ARGUMENTS
+
+Vim enables you to define functions that have a variable number of arguments.
+The following command, for instance, defines a function that must have 1
+argument (start) and can have up to 20 additional arguments: >
+
+	:function Show(start, ...)
+
+The variable "a:1" contains the first optional argument, "a:2" the second, and
+so on.  The variable "a:0" contains the number of extra arguments.
+   For example: >
+
+	:function Show(start, ...)
+	:  echohl Title
+	:  echo "Show is " . a:start
+	:  echohl None
+	:  let index = 1
+	:  while index <= a:0
+	:    echo "  Arg " . index . " is " . a:{index}
+	:    let index = index + 1
+	:  endwhile
+	:  echo ""
+	:endfunction
+
+This uses the ":echohl" command to specify the highlighting used for the
+following ":echo" command.  ":echohl None" stops it again.  The ":echon"
+command works like ":echo", but doesn't output a line break.
+
+You can also use the a:000 variable, it is a List of all the "..." arguments.
+See |a:000|.
+
+
+LISTING FUNCTIONS
+
+The ":function" command lists the names and arguments of all user-defined
+functions: >
+
+	:function
+<	function Show(start, ...) ~
+	function GetVimIndent() ~
+	function SetSyn(name) ~
+
+To see what a function does, use its name as an argument for ":function": >
+
+	:function SetSyn
+<	1     if &syntax == '' ~
+	2       let &syntax = a:name ~
+	3     endif ~
+	   endfunction ~
+
+
+DEBUGGING
+
+The line number is useful for when you get an error message or when debugging.
+See |debug-scripts| about debugging mode.
+   You can also set the 'verbose' option to 12 or higher to see all function
+calls.  Set it to 15 or higher to see every executed line.
+
+
+DELETING A FUNCTION
+
+To delete the Show() function: >
+
+	:delfunction Show
+
+You get an error when the function doesn't exist.
+
+
+FUNCTION REFERENCES
+
+Sometimes it can be useful to have a variable point to one function or
+another.  You can do it with the function() function.  It turns the name of a
+function into a reference: >
+
+	:let result = 0		" or 1
+	:function! Right()
+	:  return 'Right!'
+	:endfunc
+	:function! Wrong()
+	:  return 'Wrong!'
+	:endfunc
+	:
+	:if result == 1
+	:  let Afunc = function('Right')
+	:else
+	:  let Afunc = function('Wrong')
+	:endif
+	:echo call(Afunc, [])
+<	Wrong! ~
+
+Note that the name of a variable that holds a function reference must start
+with a capital.  Otherwise it could be confused with the name of a builtin
+function.
+   The way to invoke a function that a variable refers to is with the call()
+function.  Its first argument is the function reference, the second argument
+is a List with arguments.
+
+Function references are most useful in combination with a Dictionary, as is
+explained in the next section.
+
+==============================================================================
+*41.8*	Lists and Dictionaries
+
+So far we have used the basic types String and Number.  Vim also supports two
+composite types: List and Dictionary.
+
+A List is an ordered sequence of things.  The things can be any kind of value,
+thus you can make a List of numbers, a List of Lists and even a List of mixed
+items.  To create a List with three strings: >
+
+	:let alist = ['aap', 'mies', 'noot']
+
+The List items are enclosed in square brackets and separated by commas.  To
+create an empty List: >
+
+	:let alist = []
+
+You can add items to a List with the add() function: >
+
+	:let alist = []
+	:call add(alist, 'foo')
+	:call add(alist, 'bar')
+	:echo alist
+<	['foo', 'bar'] ~
+
+List concatenation is done with +: >
+
+	:echo alist + ['foo', 'bar']
+<	['foo', 'bar', 'foo', 'bar'] ~
+
+Or, if you want to extend a List directly: >
+
+	:let alist = ['one']
+	:call extend(alist, ['two', 'three'])
+	:echo alist
+<	['one', 'two', 'three'] ~
+
+Notice that using add() will have a different effect: >
+
+	:let alist = ['one']
+	:call add(alist, ['two', 'three'])
+	:echo alist
+<	['one', ['two', 'three']] ~
+
+The second argument of add() is added as a single item.
+
+
+FOR LOOP
+
+One of the nice things you can do with a List is iterate over it: >
+
+	:let alist = ['one', 'two', 'three']
+	:for n in alist
+	:  echo n
+	:endfor
+<	one ~
+	two ~
+	three ~
+
+This will loop over each element in List "alist", assigning the value to
+variable "n".  The generic form of a for loop is: >
+
+	:for {varname} in {listexpression}
+	:  {commands}
+	:endfor
+
+To loop a certain number of times you need a List of a specific length.  The
+range() function creates one for you: >
+
+	:for a in range(3)
+	:  echo a
+	:endfor
+<	0 ~
+	1 ~
+	2 ~
+
+Notice that the first item of the List that range() produces is zero, thus the
+last item is one less than the length of the list.
+   You can also specify the maximum value, the stride and even go backwards: >
+
+	:for a in range(8, 4, -2)
+	:  echo a
+	:endfor
+<	8 ~
+	6 ~
+	4 ~
+
+A more useful example, looping over lines in the buffer: >
+
+	:for line in getline(1, 20)
+	:  if line =~ "Date: "
+	:    echo matchstr(line, 'Date: \zs.*')
+	:  endif
+	:endfor
+
+This looks into lines 1 to 20 (inclusive) and echoes any date found in there.
+
+
+DICTIONARIES
+
+A Dictionary stores key-value pairs.  You can quickly lookup a value if you
+know the key.  A Dictionary is created with curly braces: >
+
+	:let uk2nl = {'one': 'een', 'two': 'twee', 'three': 'drie'}
+
+Now you can lookup words by putting the key in square brackets: >
+
+	:echo uk2nl['two']
+<	twee ~
+
+The generic form for defining a Dictionary is: >
+
+	{<key> : <value>, ...}
+
+An empty Dictionary is one without any keys: >
+
+	{}
+
+The possibilities with Dictionaries are numerous.  There are various functions
+for them as well.  For example, you can obtain a list of the keys and loop
+over them: >
+
+	:for key in keys(uk2nl)
+	:  echo key
+	:endfor
+<	three ~
+	one ~
+	two ~
+
+The will notice the keys are not ordered.  You can sort the list to get a
+specific order: >
+
+	:for key in sort(keys(uk2nl))
+	:  echo key
+	:endfor
+<	one ~
+	three ~
+	two ~
+
+But you can never get back the order in which items are defined.  For that you
+need to use a List, it stores items in an ordered sequence.
+
+
+DICTIONARY FUNCTIONS
+
+The items in a Dictionary can normally be obtained with an index in square
+brackets: >
+
+	:echo uk2nl['one']
+<	een ~
+
+A method that does the same, but without so many punctuation characters: >
+
+	:echo uk2nl.one
+<	een ~
+
+This only works for a key that is made of ASCII letters, digits and the
+underscore.  You can also assign a new value this way: >
+
+	:let uk2nl.four = 'vier'
+	:echo uk2nl
+<	{'three': 'drie', 'four': 'vier', 'one': 'een', 'two': 'twee'} ~
+
+And now for something special: you can directly define a function and store a
+reference to it in the dictionary: >
+
+	:function uk2nl.translate(line) dict
+	:  return join(map(split(a:line), 'get(self, v:val, "???")'))
+	:endfunction
+
+Let's first try it out: >
+
+	:echo uk2nl.translate('three two five one')
+<	drie twee ??? een ~
+
+The first special thing you notice is the "dict" at the end of the ":function"
+line.  This marks the function as being used from a Dictionary.  The "self"
+local variable will then refer to that Dictionary.
+   Now let's break up the complicated return command: >
+
+	split(a:line)
+
+The split() function takes a string, chops it into white separated words
+and returns a list with these words.  Thus in the example it returns: >
+
+	:echo split('three two five one')
+<	['three', 'two', 'five', 'one'] ~
+
+This list is the first argument to the map() function.  This will go through
+the list, evaluating its second argument with "v:val" set to the value of each
+item.  This is a shortcut to using a for loop.  This command: >
+
+	:let alist = map(split(a:line), 'get(self, v:val, "???")')
+
+Is equivalent to: >
+
+	:let alist = split(a:line)
+	:for idx in range(len(alist))
+	:  let alist[idx] = get(self, alist[idx], "???")
+	:endfor
+
+The get() function checks if a key is present in a Dictionary.  If it is, then
+the value is retrieved.  If it isn't, then the default value is returned, in
+the example it's '???'.  This is a convenient way to handle situations where a
+key may not be present and you don't want an error message.
+
+The join() function does the opposite of split(): it joins together a list of
+words, putting a space in between.
+  This combination of split(), map() and join() is a nice way to filter a line
+of words in a very compact way.
+
+
+OBJECT ORIENTED PROGRAMMING
+
+Now that you can put both values and functions in a Dictionary, you can
+actually use a Dictionary like an object.
+   Above we used a Dictionary for translating Dutch to English.  We might want
+to do the same for other languages.  Let's first make an object (aka
+Dictionary) that has the translate function, but no words to translate: >
+
+	:let transdict = {}
+	:function transdict.translate(line) dict
+	:  return join(map(split(a:line), 'get(self.words, v:val, "???")'))
+	:endfunction
+
+It's slightly different from the function above, using 'self.words' to lookup
+word translations.  But we don't have a self.words.  Thus you could call this
+an abstract class.
+
+Now we can instantiate a Dutch translation object: >
+
+	:let uk2nl = copy(transdict)
+	:let uk2nl.words = {'one': 'een', 'two': 'twee', 'three': 'drie'}
+	:echo uk2nl.translate('three one')
+<	drie een ~
+
+And a German translator: >
+
+	:let uk2de = copy(transdict)
+	:let uk2de.words = {'one': 'ein', 'two': 'zwei', 'three': 'drei'}
+	:echo uk2de.translate('three one')
+<	drei ein ~
+
+You see that the copy() function is used to make a copy of the "transdict"
+Dictionary and then the copy is changed to add the words.  The original
+remains the same, of course.
+
+Now you can go one step further, and use your preferred translator: >
+
+	:if $LANG =~ "de"
+	:  let trans = uk2de
+	:else
+	:  let trans = uk2nl
+	:endif
+	:echo trans.translate('one two three')
+<	een twee drie ~
+
+Here "trans" refers to one of the two objects (Dictionaries).  No copy is
+made.  More about List and Dictionary identity can be found at |list-identity|
+and |dict-identity|.
+
+Now you might use a language that isn't supported.  You can overrule the
+translate() function to do nothing: >
+
+	:let uk2uk = copy(transdict)
+	:function! uk2uk.translate(line)
+	:  return a:line
+	:endfunction
+	:echo uk2uk.translate('three one wladiwostok')
+<	three one wladiwostok ~
+
+Notice that a ! was used to overwrite the existing function reference.  Now
+use "uk2uk" when no recognized language is found: >
+
+	:if $LANG =~ "de"
+	:  let trans = uk2de
+	:elseif $LANG =~ "nl"
+	:  let trans = uk2nl
+	:else
+	:  let trans = uk2uk
+	:endif
+	:echo trans.translate('one two three')
+<	one two three ~
+
+For further reading see |Lists| and |Dictionaries|.
+
+==============================================================================
+*41.9*	Exceptions
+
+Let's start with an example: >
+
+	:try
+	:   read ~/templates/pascal.tmpl
+	:catch /E484:/
+	:   echo "Sorry, the Pascal template file cannot be found."
+	:endtry
+
+The ":read" command will fail if the file does not exist.  Instead of
+generating an error message, this code catches the error and gives the user a
+nice message instead.
+
+For the commands in between ":try" and ":endtry" errors are turned into
+exceptions.  An exception is a string.  In the case of an error the string
+contains the error message.  And every error message has a number.  In this
+case, the error we catch contains "E484:".  This number is guaranteed to stay
+the same (the text may change, e.g., it may be translated).
+
+When the ":read" command causes another error, the pattern "E484:" will not
+match in it.  Thus this exception will not be caught and result in the usual
+error message.
+
+You might be tempted to do this: >
+
+	:try
+	:   read ~/templates/pascal.tmpl
+	:catch
+	:   echo "Sorry, the Pascal template file cannot be found."
+	:endtry
+
+This means all errors are caught.  But then you will not see errors that are
+useful, such as "E21: Cannot make changes, 'modifiable' is off".
+
+Another useful mechanism is the ":finally" command: >
+
+	:let tmp = tempname()
+	:try
+	:   exe ".,$write " . tmp
+	:   exe "!filter " . tmp
+	:   .,$delete
+	:   exe "$read " . tmp
+	:finally
+	:   call delete(tmp)
+	:endtry
+
+This filters the lines from the cursor until the end of the file through the
+"filter" command, which takes a file name argument.  No matter if the
+filtering works, something goes wrong in between ":try" and ":finally" or the
+user cancels the filtering by pressing CTRL-C, the "call delete(tmp)" is
+always executed.  This makes sure you don't leave the temporary file behind.
+
+More information about exception handling can be found in the reference
+manual: |exception-handling|.
+
+==============================================================================
+*41.10*	Various remarks
+
+Here is a summary of items that apply to Vim scripts.  They are also mentioned
+elsewhere, but form a nice checklist.
+
+The end-of-line character depends on the system.  For Unix a single <NL>
+character is used.  For MS-DOS, Windows, OS/2 and the like, <CR><LF> is used.
+This is important when using mappings that end in a <CR>.  See |:source_crnl|.
+
+
+WHITE SPACE
+
+Blank lines are allowed and ignored.
+
+Leading whitespace characters (blanks and TABs) are always ignored.  The
+whitespaces between parameters (e.g. between the 'set' and the 'cpoptions' in
+the example below) are reduced to one blank character and plays the role of a
+separator, the whitespaces after the last (visible) character may or may not
+be ignored depending on the situation, see below.
+
+For a ":set" command involving the "=" (equal) sign, such as in: >
+
+	:set cpoptions    =aABceFst
+
+the whitespace immediately before the "=" sign is ignored.  But there can be
+no whitespace after the "=" sign!
+
+To include a whitespace character in the value of an option, it must be
+escaped by a "\" (backslash)  as in the following example: >
+
+	:set tags=my\ nice\ file
+
+The same example written as >
+
+	:set tags=my nice file
+
+will issue an error, because it is interpreted as: >
+
+	:set tags=my
+	:set nice
+	:set file
+
+
+COMMENTS
+
+The character " (the double quote mark) starts a comment.  Everything after
+and including this character until the end-of-line is considered a comment and
+is ignored, except for commands that don't consider comments, as shown in
+examples below.  A comment can start on any character position on the line.
+
+There is a little "catch" with comments for some commands.  Examples: >
+
+	:abbrev dev development		" shorthand
+	:map <F3> o#include		" insert include
+	:execute cmd			" do it
+	:!ls *.c			" list C files
+
+The abbreviation 'dev' will be expanded to 'development     " shorthand'.  The
+mapping of <F3> will actually be the whole line after the 'o# ....' including
+the '" insert include'.  The "execute" command will give an error.  The "!"
+command will send everything after it to the shell, causing an error for an
+unmatched '"' character.
+   There can be no comment after ":map", ":abbreviate", ":execute" and "!"
+commands (there are a few more commands with this restriction).  For the
+":map", ":abbreviate" and ":execute" commands there is a trick: >
+
+	:abbrev dev development|" shorthand
+	:map <F3> o#include|" insert include
+	:execute cmd			|" do it
+
+With the '|' character the command is separated from the next one.  And that
+next command is only a comment.  For the last command you need to do two
+things: |:execute| and use '|': >
+	:exe '!ls *.c'			|" list C files
+
+Notice that there is no white space before the '|' in the abbreviation and
+mapping.  For these commands, any character until the end-of-line or '|' is
+included.  As a consequence of this behavior, you don't always see that
+trailing whitespace is included: >
+
+	:map <F4> o#include  
+
+To spot these problems, you can set the 'list' option when editing vimrc
+files.
+
+For Unix there is one special way to comment a line, that allows making a Vim
+script executable: >
+	#!/usr/bin/env vim -S
+	echo "this is a Vim script"
+	quit
+
+The "#" command by itself lists a line with the line number.  Adding an
+exclamation mark changes it into doing nothing, so that you can add the shell
+command to execute the rest of the file. |:#!| |-S|
+
+
+PITFALLS
+
+Even bigger problem arises in the following example: >
+
+	:map ,ab o#include
+	:unmap ,ab 
+
+Here the unmap command will not work, because it tries to unmap ",ab ".  This
+does not exist as a mapped sequence.  An error will be issued, which is very
+hard to identify, because the ending whitespace character in ":unmap ,ab " is
+not visible.
+
+And this is the same as what happens when one uses a comment after an 'unmap'
+command: >
+
+	:unmap ,ab     " comment
+
+Here the comment part will be ignored.  However, Vim will try to unmap
+',ab     ', which does not exist.  Rewrite it as: >
+
+	:unmap ,ab|    " comment
+
+
+RESTORING THE VIEW
+
+Sometimes you want to make a change and go back to where cursor was.
+Restoring the relative position would also be nice, so that the same line
+appears at the top of the window.
+   This example yanks the current line, puts it above the first line in the
+file and then restores the view: >
+
+	map ,p ma"aYHmbgg"aP`bzt`a
+
+What this does: >
+	ma"aYHmbgg"aP`bzt`a
+<	ma			set mark a at cursor position
+	  "aY			yank current line into register a
+	     Hmb		go to top line in window and set mark b there
+		gg		go to first line in file
+		  "aP		put the yanked line above it
+		     `b		go back to top line in display
+		       zt	position the text in the window as before
+			 `a	go back to saved cursor position
+
+
+PACKAGING
+
+To avoid your function names to interfere with functions that you get from
+others, use this scheme:
+- Prepend a unique string before each function name.  I often use an
+  abbreviation.  For example, "OW_" is used for the option window functions.
+- Put the definition of your functions together in a file.  Set a global
+  variable to indicate that the functions have been loaded.  When sourcing the
+  file again, first unload the functions.
+Example: >
+
+	" This is the XXX package
+
+	if exists("XXX_loaded")
+	  delfun XXX_one
+	  delfun XXX_two
+	endif
+
+	function XXX_one(a)
+		... body of function ...
+	endfun
+
+	function XXX_two(b)
+		... body of function ...
+	endfun
+
+	let XXX_loaded = 1
+
+==============================================================================
+*41.11*	Writing a plugin				*write-plugin*
+
+You can write a Vim script in such a way that many people can use it.  This is
+called a plugin.  Vim users can drop your script in their plugin directory and
+use its features right away |add-plugin|.
+
+There are actually two types of plugins:
+
+  global plugins: For all types of files.
+filetype plugins: Only for files of a specific type.
+
+In this section the first type is explained.  Most items are also relevant for
+writing filetype plugins.  The specifics for filetype plugins are in the next
+section |write-filetype-plugin|.
+
+
+NAME
+
+First of all you must choose a name for your plugin.  The features provided
+by the plugin should be clear from its name.  And it should be unlikely that
+someone else writes a plugin with the same name but which does something
+different.  And please limit the name to 8 characters, to avoid problems on
+old Windows systems.
+
+A script that corrects typing mistakes could be called "typecorr.vim".  We
+will use it here as an example.
+
+For the plugin to work for everybody, it should follow a few guidelines.  This
+will be explained step-by-step.  The complete example plugin is at the end.
+
+
+BODY
+
+Let's start with the body of the plugin, the lines that do the actual work: >
+
+ 14	iabbrev teh the
+ 15	iabbrev otehr other
+ 16	iabbrev wnat want
+ 17	iabbrev synchronisation
+ 18		\ synchronization
+ 19	let s:count = 4
+
+The actual list should be much longer, of course.
+
+The line numbers have only been added to explain a few things, don't put them
+in your plugin file!
+
+
+HEADER
+
+You will probably add new corrections to the plugin and soon have several
+versions laying around.  And when distributing this file, people will want to
+know who wrote this wonderful plugin and where they can send remarks.
+Therefore, put a header at the top of your plugin: >
+
+  1	" Vim global plugin for correcting typing mistakes
+  2	" Last Change:	2000 Oct 15
+  3	" Maintainer:	Bram Moolenaar <Bram@vim.org>
+
+About copyright and licensing: Since plugins are very useful and it's hardly
+worth restricting their distribution, please consider making your plugin
+either public domain or use the Vim |license|.  A short note about this near
+the top of the plugin should be sufficient.  Example: >
+
+  4	" License:	This file is placed in the public domain.
+
+
+LINE CONTINUATION, AVOIDING SIDE EFFECTS		*use-cpo-save*
+
+In line 18 above, the line-continuation mechanism is used |line-continuation|.
+Users with 'compatible' set will run into trouble here, they will get an error
+message.  We can't just reset 'compatible', because that has a lot of side
+effects.  To avoid this, we will set the 'cpoptions' option to its Vim default
+value and restore it later.  That will allow the use of line-continuation and
+make the script work for most people.  It is done like this: >
+
+ 11	let s:save_cpo = &cpo
+ 12	set cpo&vim
+ ..
+ 42	let &cpo = s:save_cpo
+
+We first store the old value of 'cpoptions' in the s:save_cpo variable.  At
+the end of the plugin this value is restored.
+
+Notice that a script-local variable is used |s:var|.  A global variable could
+already be in use for something else.  Always use script-local variables for
+things that are only used in the script.
+
+
+NOT LOADING
+
+It's possible that a user doesn't always want to load this plugin.  Or the
+system administrator has dropped it in the system-wide plugin directory, but a
+user has his own plugin he wants to use.  Then the user must have a chance to
+disable loading this specific plugin.  This will make it possible: >
+
+  6	if exists("loaded_typecorr")
+  7	  finish
+  8	endif
+  9	let loaded_typecorr = 1
+
+This also avoids that when the script is loaded twice it would cause error
+messages for redefining functions and cause trouble for autocommands that are
+added twice.
+
+
+MAPPING
+
+Now let's make the plugin more interesting: We will add a mapping that adds a
+correction for the word under the cursor.  We could just pick a key sequence
+for this mapping, but the user might already use it for something else.  To
+allow the user to define which keys a mapping in a plugin uses, the <Leader>
+item can be used: >
+
+ 22	  map <unique> <Leader>a  <Plug>TypecorrAdd
+
+The "<Plug>TypecorrAdd" thing will do the work, more about that further on.
+
+The user can set the "mapleader" variable to the key sequence that he wants
+this mapping to start with.  Thus if the user has done: >
+
+	let mapleader = "_"
+
+the mapping will define "_a".  If the user didn't do this, the default value
+will be used, which is a backslash.  Then a map for "\a" will be defined.
+
+Note that <unique> is used, this will cause an error message if the mapping
+already happened to exist. |:map-<unique>|
+
+But what if the user wants to define his own key sequence?  We can allow that
+with this mechanism: >
+
+ 21	if !hasmapto('<Plug>TypecorrAdd')
+ 22	  map <unique> <Leader>a  <Plug>TypecorrAdd
+ 23	endif
+
+This checks if a mapping to "<Plug>TypecorrAdd" already exists, and only
+defines the mapping from "<Leader>a" if it doesn't.  The user then has a
+chance of putting this in his vimrc file: >
+
+	map ,c  <Plug>TypecorrAdd
+
+Then the mapped key sequence will be ",c" instead of "_a" or "\a".
+
+
+PIECES
+
+If a script gets longer, you often want to break up the work in pieces.  You
+can use functions or mappings for this.  But you don't want these functions
+and mappings to interfere with the ones from other scripts.  For example, you
+could define a function Add(), but another script could try to define the same
+function.  To avoid this, we define the function local to the script by
+prepending it with "s:".
+
+We will define a function that adds a new typing correction: >
+
+ 30	function s:Add(from, correct)
+ 31	  let to = input("type the correction for " . a:from . ": ")
+ 32	  exe ":iabbrev " . a:from . " " . to
+ ..
+ 36	endfunction
+
+Now we can call the function s:Add() from within this script.  If another
+script also defines s:Add(), it will be local to that script and can only
+be called from the script it was defined in.  There can also be a global Add()
+function (without the "s:"), which is again another function.
+
+<SID> can be used with mappings.  It generates a script ID, which identifies
+the current script.  In our typing correction plugin we use it like this: >
+
+ 24	noremap <unique> <script> <Plug>TypecorrAdd  <SID>Add
+ ..
+ 28	noremap <SID>Add  :call <SID>Add(expand("<cword>"), 1)<CR>
+
+Thus when a user types "\a", this sequence is invoked: >
+
+	\a  ->  <Plug>TypecorrAdd  ->  <SID>Add  ->  :call <SID>Add()
+
+If another script would also map <SID>Add, it would get another script ID and
+thus define another mapping.
+
+Note that instead of s:Add() we use <SID>Add() here.  That is because the
+mapping is typed by the user, thus outside of the script.  The <SID> is
+translated to the script ID, so that Vim knows in which script to look for
+the Add() function.
+
+This is a bit complicated, but it's required for the plugin to work together
+with other plugins.  The basic rule is that you use <SID>Add() in mappings and
+s:Add() in other places (the script itself, autocommands, user commands).
+
+We can also add a menu entry to do the same as the mapping: >
+
+ 26	noremenu <script> Plugin.Add\ Correction      <SID>Add
+
+The "Plugin" menu is recommended for adding menu items for plugins.  In this
+case only one item is used.  When adding more items, creating a submenu is
+recommended.  For example, "Plugin.CVS" could be used for a plugin that offers
+CVS operations "Plugin.CVS.checkin", "Plugin.CVS.checkout", etc.
+
+Note that in line 28 ":noremap" is used to avoid that any other mappings cause
+trouble.  Someone may have remapped ":call", for example.  In line 24 we also
+use ":noremap", but we do want "<SID>Add" to be remapped.  This is why
+"<script>" is used here.  This only allows mappings which are local to the
+script. |:map-<script>|  The same is done in line 26 for ":noremenu".
+|:menu-<script>|
+
+
+<SID> AND <Plug>					*using-<Plug>*
+
+Both <SID> and <Plug> are used to avoid that mappings of typed keys interfere
+with mappings that are only to be used from other mappings.  Note the
+difference between using <SID> and <Plug>:
+
+<Plug>	is visible outside of the script.  It is used for mappings which the
+	user might want to map a key sequence to.  <Plug> is a special code
+	that a typed key will never produce.
+	To make it very unlikely that other plugins use the same sequence of
+	characters, use this structure: <Plug> scriptname mapname
+	In our example the scriptname is "Typecorr" and the mapname is "Add".
+	This results in "<Plug>TypecorrAdd".  Only the first character of
+	scriptname and mapname is uppercase, so that we can see where mapname
+	starts.
+
+<SID>	is the script ID, a unique identifier for a script.
+	Internally Vim translates <SID> to "<SNR>123_", where "123" can be any
+	number.  Thus a function "<SID>Add()" will have a name "<SNR>11_Add()"
+	in one script, and "<SNR>22_Add()" in another.  You can see this if
+	you use the ":function" command to get a list of functions.  The
+	translation of <SID> in mappings is exactly the same, that's how you
+	can call a script-local function from a mapping.
+
+
+USER COMMAND
+
+Now let's add a user command to add a correction: >
+
+ 38	if !exists(":Correct")
+ 39	  command -nargs=1  Correct  :call s:Add(<q-args>, 0)
+ 40	endif
+
+The user command is defined only if no command with the same name already
+exists.  Otherwise we would get an error here.  Overriding the existing user
+command with ":command!" is not a good idea, this would probably make the user
+wonder why the command he defined himself doesn't work.  |:command|
+
+
+SCRIPT VARIABLES
+
+When a variable starts with "s:" it is a script variable.  It can only be used
+inside a script.  Outside the script it's not visible.  This avoids trouble
+with using the same variable name in different scripts.  The variables will be
+kept as long as Vim is running.  And the same variables are used when sourcing
+the same script again. |s:var|
+
+The fun is that these variables can also be used in functions, autocommands
+and user commands that are defined in the script.  In our example we can add
+a few lines to count the number of corrections: >
+
+ 19	let s:count = 4
+ ..
+ 30	function s:Add(from, correct)
+ ..
+ 34	  let s:count = s:count + 1
+ 35	  echo s:count . " corrections now"
+ 36	endfunction
+
+First s:count is initialized to 4 in the script itself.  When later the
+s:Add() function is called, it increments s:count.  It doesn't matter from
+where the function was called, since it has been defined in the script, it
+will use the local variables from this script.
+
+
+THE RESULT
+
+Here is the resulting complete example: >
+
+  1	" Vim global plugin for correcting typing mistakes
+  2	" Last Change:	2000 Oct 15
+  3	" Maintainer:	Bram Moolenaar <Bram@vim.org>
+  4	" License:	This file is placed in the public domain.
+  5
+  6	if exists("loaded_typecorr")
+  7	  finish
+  8	endif
+  9	let loaded_typecorr = 1
+ 10
+ 11	let s:save_cpo = &cpo
+ 12	set cpo&vim
+ 13
+ 14	iabbrev teh the
+ 15	iabbrev otehr other
+ 16	iabbrev wnat want
+ 17	iabbrev synchronisation
+ 18		\ synchronization
+ 19	let s:count = 4
+ 20
+ 21	if !hasmapto('<Plug>TypecorrAdd')
+ 22	  map <unique> <Leader>a  <Plug>TypecorrAdd
+ 23	endif
+ 24	noremap <unique> <script> <Plug>TypecorrAdd  <SID>Add
+ 25
+ 26	noremenu <script> Plugin.Add\ Correction      <SID>Add
+ 27
+ 28	noremap <SID>Add  :call <SID>Add(expand("<cword>"), 1)<CR>
+ 29
+ 30	function s:Add(from, correct)
+ 31	  let to = input("type the correction for " . a:from . ": ")
+ 32	  exe ":iabbrev " . a:from . " " . to
+ 33	  if a:correct | exe "normal viws\<C-R>\" \b\e" | endif
+ 34	  let s:count = s:count + 1
+ 35	  echo s:count . " corrections now"
+ 36	endfunction
+ 37
+ 38	if !exists(":Correct")
+ 39	  command -nargs=1  Correct  :call s:Add(<q-args>, 0)
+ 40	endif
+ 41
+ 42	let &cpo = s:save_cpo
+
+Line 33 wasn't explained yet.  It applies the new correction to the word under
+the cursor.  The |:normal| command is used to use the new abbreviation.  Note
+that mappings and abbreviations are expanded here, even though the function
+was called from a mapping defined with ":noremap".
+
+Using "unix" for the 'fileformat' option is recommended.  The Vim scripts will
+then work everywhere.  Scripts with 'fileformat' set to "dos" do not work on
+Unix.  Also see |:source_crnl|.  To be sure it is set right, do this before
+writing the file: >
+
+	:set fileformat=unix
+
+
+DOCUMENTATION						*write-local-help*
+
+It's a good idea to also write some documentation for your plugin.  Especially
+when its behavior can be changed by the user.  See |add-local-help| for how
+they are installed.
+
+Here is a simple example for a plugin help file, called "typecorr.txt": >
+
+  1	*typecorr.txt*	Plugin for correcting typing mistakes
+  2
+  3	If you make typing mistakes, this plugin will have them corrected
+  4	automatically.
+  5
+  6	There are currently only a few corrections.  Add your own if you like.
+  7
+  8	Mappings:
+  9	<Leader>a   or   <Plug>TypecorrAdd
+ 10		Add a correction for the word under the cursor.
+ 11
+ 12	Commands:
+ 13	:Correct {word}
+ 14		Add a correction for {word}.
+ 15
+ 16							*typecorr-settings*
+ 17	This plugin doesn't have any settings.
+
+The first line is actually the only one for which the format matters.  It will
+be extracted from the help file to be put in the "LOCAL ADDITIONS:" section of
+help.txt |local-additions|.  The first "*" must be in the first column of the
+first line.  After adding your help file do ":help" and check that the entries
+line up nicely.
+
+You can add more tags inside ** in your help file.  But be careful not to use
+existing help tags.  You would probably use the name of your plugin in most of
+them, like "typecorr-settings" in the example.
+
+Using references to other parts of the help in || is recommended.  This makes
+it easy for the user to find associated help.
+
+
+FILETYPE DETECTION					*plugin-filetype*
+
+If your filetype is not already detected by Vim, you should create a filetype
+detection snippet in a separate file.  It is usually in the form of an
+autocommand that sets the filetype when the file name matches a pattern.
+Example: >
+
+	au BufNewFile,BufRead *.foo			set filetype=foofoo
+
+Write this single-line file as "ftdetect/foofoo.vim" in the first directory
+that appears in 'runtimepath'.  For Unix that would be
+"~/.vim/ftdetect/foofoo.vim".  The convention is to use the name of the
+filetype for the script name.
+
+You can make more complicated checks if you like, for example to inspect the
+contents of the file to recognize the language.  Also see |new-filetype|.
+
+
+SUMMARY							*plugin-special*
+
+Summary of special things to use in a plugin:
+
+s:name			Variables local to the script.
+
+<SID>			Script-ID, used for mappings and functions local to
+			the script.
+
+hasmapto()		Function to test if the user already defined a mapping
+			for functionality the script offers.
+
+<Leader>		Value of "mapleader", which the user defines as the
+			keys that plugin mappings start with.
+
+:map <unique>		Give a warning if a mapping already exists.
+
+:noremap <script>	Use only mappings local to the script, not global
+			mappings.
+
+exists(":Cmd")		Check if a user command already exists.
+
+==============================================================================
+*41.12*	Writing a filetype plugin	*write-filetype-plugin* *ftplugin*
+
+A filetype plugin is like a global plugin, except that it sets options and
+defines mappings for the current buffer only.  See |add-filetype-plugin| for
+how this type of plugin is used.
+
+First read the section on global plugins above |41.11|.  All that is said there
+also applies to filetype plugins.  There are a few extras, which are explained
+here.  The essential thing is that a filetype plugin should only have an
+effect on the current buffer.
+
+
+DISABLING
+
+If you are writing a filetype plugin to be used by many people, they need a
+chance to disable loading it.  Put this at the top of the plugin: >
+
+	" Only do this when not done yet for this buffer
+	if exists("b:did_ftplugin")
+	  finish
+	endif
+	let b:did_ftplugin = 1
+
+This also needs to be used to avoid that the same plugin is executed twice for
+the same buffer (happens when using an ":edit" command without arguments).
+
+Now users can disable loading the default plugin completely by making a
+filetype plugin with only this line: >
+
+	let b:did_ftplugin = 1
+
+This does require that the filetype plugin directory comes before $VIMRUNTIME
+in 'runtimepath'!
+
+If you do want to use the default plugin, but overrule one of the settings,
+you can write the different setting in a script: >
+
+	setlocal textwidth=70
+
+Now write this in the "after" directory, so that it gets sourced after the
+distributed "vim.vim" ftplugin |after-directory|.  For Unix this would be
+"~/.vim/after/ftplugin/vim.vim".  Note that the default plugin will have set
+"b:did_ftplugin", but it is ignored here.
+
+
+OPTIONS
+
+To make sure the filetype plugin only affects the current buffer use the >
+
+	:setlocal
+
+command to set options.  And only set options which are local to a buffer (see
+the help for the option to check that).  When using |:setlocal| for global
+options or options local to a window, the value will change for many buffers,
+and that is not what a filetype plugin should do.
+
+When an option has a value that is a list of flags or items, consider using
+"+=" and "-=" to keep the existing value.  Be aware that the user may have
+changed an option value already.  First resetting to the default value and
+then changing it often a good idea.  Example: >
+
+	:setlocal formatoptions& formatoptions+=ro
+
+
+MAPPINGS
+
+To make sure mappings will only work in the current buffer use the >
+
+	:map <buffer>
+
+command.  This needs to be combined with the two-step mapping explained above.
+An example of how to define functionality in a filetype plugin: >
+
+	if !hasmapto('<Plug>JavaImport')
+	  map <buffer> <unique> <LocalLeader>i <Plug>JavaImport
+	endif
+	noremap <buffer> <unique> <Plug>JavaImport oimport ""<Left><Esc>
+
+|hasmapto()| is used to check if the user has already defined a map to
+<Plug>JavaImport.  If not, then the filetype plugin defines the default
+mapping.  This starts with |<LocalLeader>|, which allows the user to select
+the key(s) he wants filetype plugin mappings to start with.  The default is a
+backslash.
+"<unique>" is used to give an error message if the mapping already exists or
+overlaps with an existing mapping.
+|:noremap| is used to avoid that any other mappings that the user has defined
+interferes.  You might want to use ":noremap <script>" to allow remapping
+mappings defined in this script that start with <SID>.
+
+The user must have a chance to disable the mappings in a filetype plugin,
+without disabling everything.  Here is an example of how this is done for a
+plugin for the mail filetype: >
+
+	" Add mappings, unless the user didn't want this.
+	if !exists("no_plugin_maps") && !exists("no_mail_maps")
+	  " Quote text by inserting "> "
+	  if !hasmapto('<Plug>MailQuote')
+	    vmap <buffer> <LocalLeader>q <Plug>MailQuote
+	    nmap <buffer> <LocalLeader>q <Plug>MailQuote
+	  endif
+	  vnoremap <buffer> <Plug>MailQuote :s/^/> /<CR>
+	  nnoremap <buffer> <Plug>MailQuote :.,$s/^/> /<CR>
+	endif
+
+Two global variables are used:
+no_plugin_maps		disables mappings for all filetype plugins
+no_mail_maps		disables mappings for a specific filetype
+
+
+USER COMMANDS
+
+To add a user command for a specific file type, so that it can only be used in
+one buffer, use the "-buffer" argument to |:command|.  Example: >
+
+	:command -buffer  Make  make %:r.s
+
+
+VARIABLES
+
+A filetype plugin will be sourced for each buffer of the type it's for.  Local
+script variables |s:var| will be shared between all invocations.  Use local
+buffer variables |b:var| if you want a variable specifically for one buffer.
+
+
+FUNCTIONS
+
+When defining a function, this only needs to be done once.  But the filetype
+plugin will be sourced every time a file with this filetype will be opened.
+This construct make sure the function is only defined once: >
+
+	:if !exists("*s:Func")
+	:  function s:Func(arg)
+	:    ...
+	:  endfunction
+	:endif
+<
+
+UNDO							*undo_ftplugin*
+
+When the user does ":setfiletype xyz" the effect of the previous filetype
+should be undone.  Set the b:undo_ftplugin variable to the commands that will
+undo the settings in your filetype plugin.  Example: >
+
+	let b:undo_ftplugin = "setlocal fo< com< tw< commentstring<"
+		\ . "| unlet b:match_ignorecase b:match_words b:match_skip"
+
+Using ":setlocal" with "<" after the option name resets the option to its
+global value.  That is mostly the best way to reset the option value.
+
+This does require removing the "C" flag from 'cpoptions' to allow line
+continuation, as mentioned above |use-cpo-save|.
+
+
+FILE NAME
+
+The filetype must be included in the file name |ftplugin-name|.  Use one of
+these three forms:
+
+	.../ftplugin/stuff.vim
+	.../ftplugin/stuff_foo.vim
+	.../ftplugin/stuff/bar.vim
+
+"stuff" is the filetype, "foo" and "bar" are arbitrary names.
+
+
+SUMMARY							*ftplugin-special*
+
+Summary of special things to use in a filetype plugin:
+
+<LocalLeader>		Value of "maplocalleader", which the user defines as
+			the keys that filetype plugin mappings start with.
+
+:map <buffer>		Define a mapping local to the buffer.
+
+:noremap <script>	Only remap mappings defined in this script that start
+			with <SID>.
+
+:setlocal		Set an option for the current buffer only.
+
+:command -buffer	Define a user command local to the buffer.
+
+exists("*s:Func")	Check if a function was already defined.
+
+Also see |plugin-special|, the special things used for all plugins.
+
+==============================================================================
+*41.13*	Writing a compiler plugin		*write-compiler-plugin*
+
+A compiler plugin sets options for use with a specific compiler.  The user can
+load it with the |:compiler| command.  The main use is to set the
+'errorformat' and 'makeprg' options.
+
+Easiest is to have a look at examples.  This command will edit all the default
+compiler plugins: >
+
+	:next $VIMRUNTIME/compiler/*.vim
+
+Use |:next| to go to the next plugin file.
+
+There are two special items about these files.  First is a mechanism to allow
+a user to overrule or add to the default file.  The default files start with: >
+
+	:if exists("current_compiler")
+	:  finish
+	:endif
+	:let current_compiler = "mine"
+
+When you write a compiler file and put it in your personal runtime directory
+(e.g., ~/.vim/compiler for Unix), you set the "current_compiler" variable to
+make the default file skip the settings.
+							*:CompilerSet*
+The second mechanism is to use ":set" for ":compiler!" and ":setlocal" for
+":compiler".  Vim defines the ":CompilerSet" user command for this.  However,
+older Vim versions don't, thus your plugin should define it then.  This is an
+example: >
+
+  if exists(":CompilerSet") != 2
+    command -nargs=* CompilerSet setlocal <args>
+  endif
+  CompilerSet errorformat&		" use the default 'errorformat'
+  CompilerSet makeprg=nmake
+
+When you write a compiler plugin for the Vim distribution or for a system-wide
+runtime directory, use the mechanism mentioned above.  When
+"current_compiler" was already set by a user plugin nothing will be done.
+
+When you write a compiler plugin to overrule settings from a default plugin,
+don't check "current_compiler".  This plugin is supposed to be loaded
+last, thus it should be in a directory at the end of 'runtimepath'.  For Unix
+that could be ~/.vim/after/compiler.
+
+==============================================================================
+*41.14*	Writing a plugin that loads quickly	*write-plugin-quickload*
+
+A plugin may grow and become quite long.  The startup delay may become
+noticeable, while you hardly every use the plugin.  Then it's time for a
+quickload plugin.
+
+The basic idea is that the plugin is loaded twice.  The first time user
+commands and mappings are defined that offer the functionality.  The second
+time the functions that implement the functionality are defined.
+
+It may sound surprising that quickload means loading a script twice.  What we
+mean is that it loads quickly the first time, postponing the bulk of the
+script to the second time, which only happens when you actually use it.  When
+you always use the functionality it actually gets slower!
+
+Note that since Vim 7 there is an alternative: use the |autoload|
+functionality |41.15|.
+
+The following example shows how it's done: >
+
+	" Vim global plugin for demonstrating quick loading
+	" Last Change:	2005 Feb 25
+	" Maintainer:	Bram Moolenaar <Bram@vim.org>
+	" License:	This file is placed in the public domain.
+
+	if !exists("s:did_load")
+		command -nargs=* BNRead  call BufNetRead(<f-args>)
+		map <F19> :call BufNetWrite('something')<CR>
+
+		let s:did_load = 1
+		exe 'au FuncUndefined BufNet* source ' . expand('<sfile>')
+		finish
+	endif
+
+	function BufNetRead(...)
+		echo 'BufNetRead(' . string(a:000) . ')'
+		" read functionality here
+	endfunction
+
+	function BufNetWrite(...)
+		echo 'BufNetWrite(' . string(a:000) . ')'
+		" write functionality here
+	endfunction
+
+When the script is first loaded "s:did_load" is not set.  The commands between
+the "if" and "endif" will be executed.  This ends in a |:finish| command, thus
+the rest of the script is not executed.
+
+The second time the script is loaded "s:did_load" exists and the commands
+after the "endif" are executed.  This defines the (possible long)
+BufNetRead() and BufNetWrite() functions.
+
+If you drop this script in your plugin directory Vim will execute it on
+startup.  This is the sequence of events that happens:
+
+1. The "BNRead" command is defined and the <F19> key is mapped when the script
+   is sourced at startup.  A |FuncUndefined| autocommand is defined.  The
+   ":finish" command causes the script to terminate early.
+
+2. The user types the BNRead command or presses the <F19> key.  The
+   BufNetRead() or BufNetWrite() function will be called.
+
+3. Vim can't find the function and triggers the |FuncUndefined| autocommand
+   event.  Since the pattern "BufNet*" matches the invoked function, the
+   command "source fname" will be executed.  "fname" will be equal to the name
+   of the script, no matter where it is located, because it comes from
+   expanding "<sfile>" (see |expand()|).
+
+4. The script is sourced again, the "s:did_load" variable exists and the
+   functions are defined.
+
+Notice that the functions that are loaded afterwards match the pattern in the
+|FuncUndefined| autocommand.  You must make sure that no other plugin defines
+functions that match this pattern.
+
+==============================================================================
+*41.15*	Writing library scripts			*write-library-script*
+
+Some functionality will be required in several places.  When this becomes more
+than a few lines you will want to put it in one script and use it from many
+scripts.  We will call that one script a library script.
+
+Manually loading a library script is possible, so long as you avoid loading it
+when it's already done.  You can do this with the |exists()| function.
+Example: >
+
+	if !exists('*MyLibFunction')
+	   runtime library/mylibscript.vim
+	endif
+	call MyLibFunction(arg)
+
+Here you need to know that MyLibFunction() is defined in a script
+"library/mylibscript.vim" in one of the directories in 'runtimepath'.
+
+To make this a bit simpler Vim offers the autoload mechanism.  Then the
+example looks like this: >
+
+	call mylib#myfunction(arg)
+
+That's a lot simpler, isn't it?  Vim will recognize the function name and when
+it's not defined search for the script "autoload/mylib.vim" in 'runtimepath'.
+That script must define the "mylib#myfunction()" function.
+
+You can put many other functions in the mylib.vim script, you are free to
+organize your functions in library scripts.  But you must use function names
+where the part before the '#' matches the script name.  Otherwise Vim would
+not know what script to load.
+
+If you get really enthusiastic and write lots of library scripts, you may
+want to use subdirectories.  Example: >
+
+	call netlib#ftp#read('somefile')
+
+For Unix the library script used for this could be:
+
+	~/.vim/autoload/netlib/ftp.vim
+
+Where the function is defined like this: >
+
+	function netlib#ftp#read(fname)
+		"  Read the file fname through ftp
+	endfunction
+
+Notice that the name the function is defined with is exactly the same as the
+name used for calling the function.  And the part before the last '#'
+exactly matches the subdirectory and script name.
+
+You can use the same mechanism for variables: >
+
+	let weekdays = dutch#weekdays
+
+This will load the script "autoload/dutch.vim", which should contain something
+like: >
+
+	let dutch#weekdays = ['zondag', 'maandag', 'dinsdag', 'woensdag',
+		\ 'donderdag', 'vrijdag', 'zaterdag']
+
+Further reading: |autoload|.
+
+==============================================================================
+*41.16*	Distributing Vim scripts			*distribute-script*
+
+Vim users will look for scripts on the Vim website: http://www.vim.org.
+If you made something that is useful for others, share it!
+
+Vim scripts can be used on any system.  There might not be a tar or gzip
+command.  If you want to pack files together and/or compress them the "zip"
+utility is recommended.
+
+For utmost portability use Vim itself to pack scripts together.  This can be
+done with the Vimball utility.  See |vimball|.
+
+It's good if you add a line to allow automatic updating.  See |glvs-plugins|.
+
+==============================================================================
+
+Next chapter: |usr_42.txt|  Add new menus
+
+Copyright: see |manual-copyright|  vim:tw=78:ts=8:ft=help:norl:
--- /dev/null
+++ b/lib/vimfiles/doc/usr_42.txt
@@ -1,0 +1,365 @@
+*usr_42.txt*	For Vim version 7.1.  Last change: 2006 Apr 24
+
+		     VIM USER MANUAL - by Bram Moolenaar
+
+			      Add new menus
+
+
+By now you know that Vim is very flexible.  This includes the menus used in
+the GUI.  You can define your own menu entries to make certain commands easily
+accessible.  This is for mouse-happy users only.
+
+|42.1|	Introduction
+|42.2|	Menu commands
+|42.3|	Various
+|42.4|	Toolbar and popup menus
+
+     Next chapter: |usr_43.txt|  Using filetypes
+ Previous chapter: |usr_41.txt|  Write a Vim script
+Table of contents: |usr_toc.txt|
+
+==============================================================================
+*42.1*	Introduction
+
+The menus that Vim uses are defined in the file "$VIMRUNTIME/menu.vim".  If
+you want to write your own menus, you might first want to look through that
+file.
+   To define a menu item, use the ":menu" command.  The basic form of this
+command is as follows: >
+
+	:menu {menu-item} {keys}
+
+The {menu-item} describes where on the menu to put the item.  A typical
+{menu-item} is "File.Save", which represents the item "Save" under the
+"File" menu.  A dot is used to separate the names.  Example: >
+
+	:menu File.Save  :update<CR>
+
+The ":update" command writes the file when it was modified.
+   You can add another level: "Edit.Settings.Shiftwidth" defines a submenu
+"Settings" under the "Edit" menu, with an item "Shiftwidth".  You could use
+even deeper levels.  Don't use this too much, you need to move the mouse quite
+a bit to use such an item.
+   The ":menu" command is very similar to the ":map" command: the left side
+specifies how the item is triggered and the right hand side defines the
+characters that are executed.  {keys} are characters, they are used just like
+you would have typed them.  Thus in Insert mode, when {keys} is plain text,
+that text is inserted.
+
+
+ACCELERATORS
+
+The ampersand character (&) is used to indicate an accelerator.  For instance,
+you can use Alt-F to select "File" and S to select "Save".  (The 'winaltkeys'
+option may disable this though!).  Therefore, the {menu-item} looks like
+"&File.&Save".  The accelerator characters will be underlined in the menu.
+   You must take care that each key is used only once in each menu.  Otherwise
+you will not know which of the two will actually be used.  Vim doesn't warn
+you for this.
+
+
+PRIORITIES
+
+The actual definition of the File.Save menu item is as follows: >
+
+	:menu 10.340 &File.&Save<Tab>:w  :confirm w<CR>
+
+The number 10.340 is called the priority number.  It is used by the editor to
+decide where it places the menu item.  The first number (10) indicates the
+position on the menu bar.  Lower numbered menus are positioned to the left,
+higher numbers to the right.
+   These are the priorities used for the standard menus:
+
+	  10	20     40     50      60       70		9999
+
+	+------------------------------------------------------------+
+	| File	Edit  Tools  Syntax  Buffers  Window		Help |
+	+------------------------------------------------------------+
+
+Notice that the Help menu is given a very high number, to make it appear on
+the far right.
+   The second number (340) determines the location of the item within the
+pull-down menu.  Lower numbers go on top, higher number on the bottom.  These
+are the priorities in the File menu:
+
+			+-----------------+
+	    10.310	|Open...	  |
+	    10.320	|Split-Open...	  |
+	    10.325	|New		  |
+	    10.330	|Close		  |
+	    10.335	|---------------- |
+	    10.340	|Save		  |
+	    10.350	|Save As...	  |
+	    10.400	|---------------- |
+	    10.410	|Split Diff with  |
+	    10.420	|Split Patched By |
+	    10.500	|---------------- |
+	    10.510	|Print		  |
+	    10.600	|---------------- |
+	    10.610	|Save-Exit	  |
+	    10.620	|Exit		  |
+			+-----------------+
+
+Notice that there is room in between the numbers.  This is where you can
+insert your own items, if you really want to (it's often better to leave the
+standard menus alone and add a new menu for your own items).
+   When you create a submenu, you can add another ".number" to the priority.
+Thus each name in {menu-item} has its priority number.
+
+
+SPECIAL CHARACTERS
+
+The {menu-item} in this example is "&File.&Save<Tab>:w".  This brings up an
+important point: {menu-item} must be one word.  If you want to put a dot,
+space or tabs in the name, you either use the <> notation (<Space> and <Tab>,
+for instance) or use the backslash (\) escape. >
+
+	:menu 10.305 &File.&Do\ It\.\.\. :exit<CR>
+
+In this example, the name of the menu item "Do It..." contains a space and the
+command is ":exit<CR>".
+
+The <Tab> character in a menu name is used to separate the part that defines
+the menu name from the part that gives a hint to the user.  The part after the
+<Tab> is displayed right aligned in the menu.  In the File.Save menu the name
+used is "&File.&Save<Tab>:w".  Thus the menu name is "File.Save" and the hint
+is ":w".
+
+
+SEPARATORS
+
+The separator lines, used to group related menu items together, can be defined
+by using a name that starts and ends in a '-'.  For example "-sep-".  When
+using several separators the names must be different.  Otherwise the names
+don't matter.
+   The command from a separator will never be executed, but you have to define
+one anyway.  A single colon will do.  Example: >
+
+	:amenu 20.510 Edit.-sep3- :
+
+==============================================================================
+*42.2*	Menu commands
+
+You can define menu items that exist for only certain modes.  This works just
+like the variations on the ":map" command:
+
+	:menu		Normal, Visual and Operator-pending mode
+	:nmenu		Normal mode
+	:vmenu		Visual mode
+	:omenu		Operator-pending mode
+	:menu!		Insert and Command-line mode
+	:imenu		Insert mode
+	:cmenu		Command-line mode
+	:amenu		All modes
+
+To avoid that the commands of a menu item are being mapped, use the command
+":noremenu", ":nnoremenu", ":anoremenu", etc.
+
+
+USING :AMENU
+
+The ":amenu" command is a bit different.  It assumes that the {keys} you
+give are to be executed in Normal mode.  When Vim is in Visual or Insert mode
+when the menu is used, Vim first has to go back to Normal mode.  ":amenu"
+inserts a CTRL-C or CTRL-O for you.  For example, if you use this command:
+>
+	:amenu  90.100 Mine.Find\ Word  *
+
+Then the resulting menu commands will be:
+
+	Normal mode:		*
+	Visual mode:		CTRL-C *
+	Operator-pending mode:	CTRL-C *
+	Insert mode:		CTRL-O *
+	Command-line mode:	CTRL-C *
+
+When in Command-line mode the CTRL-C will abandon the command typed so far.
+In Visual and Operator-pending mode CTRL-C will stop the mode.  The CTRL-O in
+Insert mode will execute the command and then return to Insert mode.
+   CTRL-O only works for one command.  If you need to use two or more
+commands, put them in a function and call that function.  Example: >
+
+	:amenu  Mine.Next\ File  :call <SID>NextFile()<CR>
+	:function <SID>NextFile()
+	:  next
+	:  1/^Code
+	:endfunction
+
+This menu entry goes to the next file in the argument list with ":next".  Then
+it searches for the line that starts with "Code".
+   The <SID> before the function name is the script ID.  This makes the
+function local to the current Vim script file.  This avoids problems when a
+function with the same name is defined in another script file.  See |<SID>|.
+
+
+SILENT MENUS
+
+The menu executes the {keys} as if you typed them.  For a ":" command this
+means you will see the command being echoed on the command line.  If it's a
+long command, the hit-Enter prompt will appear.  That can be very annoying!
+   To avoid this, make the menu silent.  This is done with the <silent>
+argument.  For example, take the call to NextFile() in the previous example.
+When you use this menu, you will see this on the command line:
+
+	:call <SNR>34_NextFile() ~
+
+To avoid this text on the command line, insert "<silent>" as the first
+argument: >
+
+	:amenu <silent> Mine.Next\ File :call <SID>NextFile()<CR>
+
+Don't use "<silent>" too often.  It is not needed for short commands.  If you
+make a menu for someone else, being able the see the executed command will
+give him a hint about what he could have typed, instead of using the mouse.
+
+
+LISTING MENUS
+
+When a menu command is used without a {keys} part, it lists the already
+defined menus.  You can specify a {menu-item}, or part of it, to list specific
+menus.  Example: >
+
+	:amenu
+
+This lists all menus.  That's a long list!  Better specify the name of a menu
+to get a shorter list: >
+
+	:amenu Edit
+
+This lists only the "Edit" menu items for all modes.  To list only one
+specific menu item for Insert mode: >
+
+	:imenu Edit.Undo
+
+Take care that you type exactly the right name.  Case matters here.  But the
+'&' for accelerators can be omitted.  The <Tab> and what comes after it can be
+left out as well.
+
+
+DELETING MENUS
+
+To delete a menu, the same command is used as for listing, but with "menu"
+changed to "unmenu".  Thus ":menu" becomes, ":unmenu", ":nmenu" becomes
+":nunmenu", etc.  To delete the "Tools.Make" item for Insert mode: >
+
+	:iunmenu Tools.Make
+
+You can delete a whole menu, with all its items, by using the menu name.
+Example: >
+
+	:aunmenu Syntax
+
+This deletes the Syntax menu and all the items in it.
+
+==============================================================================
+*42.3*	Various
+
+You can change the appearance of the menus with flags in 'guioptions'.  In the
+default value they are all included.  You can remove a flag with a command
+like: >
+
+	:set guioptions-=m
+<
+	m		When removed the menubar is not displayed.
+
+	M		When removed the default menus are not loaded.
+
+	g		When removed the inactive menu items are not made grey
+			but are completely removed.  (Does not work on all
+			systems.)
+
+	t		When removed the tearoff feature is not enabled.
+
+The dotted line at the top of a menu is not a separator line.  When you select
+this item, the menu is "teared-off": It is displayed in a separate window.
+This is called a tearoff menu.  This is useful when you use the same menu
+often.
+
+For translating menu items, see |:menutrans|.
+
+Since the mouse has to be used to select a menu item, it is a good idea to use
+the ":browse" command for selecting a file.  And ":confirm" to get a dialog
+instead of an error message, e.g., when the current buffer contains changes.
+These two can be combined: >
+
+	:amenu File.Open  :browse confirm edit<CR>
+
+The ":browse" makes a file browser appear to select the file to edit.  The
+":confirm" will pop up a dialog when the current buffer has changes.  You can
+then select to save the changes, throw them away or cancel the command.
+   For more complicated items, the confirm() and inputdialog() functions can
+be used.  The default menus contain a few examples.
+
+==============================================================================
+*42.4*	Toolbar and popup menus
+
+There are two special menus: ToolBar and PopUp.  Items that start with these
+names do not appear in the normal menu bar.
+
+
+TOOLBAR
+
+The toolbar appears only when the "T" flag is included in the 'guioptions'
+option.
+   The toolbar uses icons rather than text to represent the command.  For
+example, the {menu-item} named "ToolBar.New" causes the "New" icon to appear
+on the toolbar.
+   The Vim editor has 28 built-in icons.  You can find a table here:
+|builtin-tools|.  Most of them are used in the default toolbar.  You can
+redefine what these items do (after the default menus are setup).
+   You can add another bitmap for a toolbar item.  Or define a new toolbar
+item with a bitmap.  For example, define a new toolbar item with: >
+
+	:tmenu ToolBar.Compile  Compile the current file
+	:amenu ToolBar.Compile  :!cc % -o %:r<CR>
+
+Now you need to create the icon.  For MS-Windows it must be in bitmap format,
+with the name "Compile.bmp".  For Unix XPM format is used, the file name is
+"Compile.xpm".  The size must be 18 by 18 pixels.  On MS-Windows other sizes
+can be used as well, but it will look ugly.
+   Put the bitmap in the directory "bitmaps" in one of the directories from
+'runtimepath'.  E.g., for Unix "~/.vim/bitmaps/Compile.xpm".
+
+You can define tooltips for the items in the toolbar.  A tooltip is a short
+text that explains what a toolbar item will do.  For example "Open file".  It
+appears when the mouse pointer is on the item, without moving for a moment.
+This is very useful if the meaning of the picture isn't that obvious.
+Example: >
+
+	:tmenu ToolBar.Make  Run make in the current directory
+<
+	Note:
+	Pay attention to the case used.  "Toolbar" and "toolbar" are different
+	from "ToolBar"!
+
+To remove a tooltip, use the |:tunmenu| command.
+
+The 'toolbar' option can be used to display text instead of a bitmap, or both
+text and a bitmap.  Most people use just the bitmap, since the text takes
+quite a bit of space.
+
+
+POPUP MENU
+
+The popup menu pops up where the mouse pointer is.  On MS-Windows you activate
+it by clicking the right mouse button.  Then you can select an item with the
+left mouse button.  On Unix the popup menu is used by pressing and holding the
+right mouse button.
+   The popup menu only appears when the 'mousemodel' has been set to "popup"
+or "popup_setpos".  The difference between the two is that "popup_setpos"
+moves the cursor to the mouse pointer position.  When clicking inside a
+selection, the selection will be used unmodified.  When there is a selection
+but you click outside of it, the selection is removed.
+   There is a separate popup menu for each mode.  Thus there are never grey
+items like in the normal menus.
+
+What is the meaning of life, the universe and everything?  *42*
+Douglas Adams, the only person who knew what this question really was about is
+now dead, unfortunately.  So now you might wonder what the meaning of death
+is...
+
+==============================================================================
+
+Next chapter: |usr_43.txt|  Using filetypes
+
+Copyright: see |manual-copyright|  vim:tw=78:ts=8:ft=help:norl:
--- /dev/null
+++ b/lib/vimfiles/doc/usr_43.txt
@@ -1,0 +1,172 @@
+*usr_43.txt*	For Vim version 7.1.  Last change: 2006 Apr 24
+
+		     VIM USER MANUAL - by Bram Moolenaar
+
+			       Using filetypes
+
+
+When you are editing a file of a certain type, for example a C program or a
+shell script, you often use the same option settings and mappings.  You
+quickly get tired of manually setting these each time.  This chapter explains
+how to do it automatically.
+
+|43.1|	Plugins for a filetype
+|43.2|	Adding a filetype
+
+     Next chapter: |usr_44.txt|  Your own syntax highlighted
+ Previous chapter: |usr_42.txt|  Add new menus
+Table of contents: |usr_toc.txt|
+
+==============================================================================
+*43.1*	Plugins for a filetype				*filetype-plugin*
+
+How to start using filetype plugins has already been discussed here:
+|add-filetype-plugin|.  But you probably are not satisfied with the default
+settings, because they have been kept minimal.  Suppose that for C files you
+want to set the 'softtabstop' option to 4 and define a mapping to insert a
+three-line comment.  You do this with only two steps:
+
+							*your-runtime-dir*
+1. Create your own runtime directory.  On Unix this usually is "~/.vim".  In
+   this directory create the "ftplugin" directory: >
+
+	mkdir ~/.vim
+	mkdir ~/.vim/ftplugin
+<
+   When you are not on Unix, check the value of the 'runtimepath' option to
+   see where Vim will look for the "ftplugin" directory: >
+
+	set runtimepath
+
+<  You would normally use the first directory name (before the first comma).
+   You might want to prepend a directory name to the 'runtimepath' option in
+   your |vimrc| file if you don't like the default value.
+
+2. Create the file "~/.vim/ftplugin/c.vim", with the contents: >
+
+	setlocal softtabstop=4
+	noremap <buffer> <LocalLeader>c o/**************<CR><CR>/<Esc>
+
+Try editing a C file.  You should notice that the 'softtabstop' option is set
+to 4.  But when you edit another file it's reset to the default zero.  That is
+because the ":setlocal" command was used.  This sets the 'softtabstop' option
+only locally to the buffer.  As soon as you edit another buffer, it will be
+set to the value set for that buffer.  For a new buffer it will get the
+default value or the value from the last ":set" command.
+
+Likewise, the mapping for "\c" will disappear when editing another buffer.
+The ":map <buffer>" command creates a mapping that is local to the current
+buffer.  This works with any mapping command: ":map!", ":vmap", etc.  The
+|<LocalLeader>| in the mapping is replaced with the value of "maplocalleader".
+
+You can find examples for filetype plugins in this directory: >
+
+	$VIMRUNTIME/ftplugin/
+
+More details about writing a filetype plugin can be found here:
+|write-plugin|.
+
+==============================================================================
+*43.2*	Adding a filetype
+
+If you are using a type of file that is not recognized by Vim, this is how to
+get it recognized.  You need a runtime directory of your own.  See
+|your-runtime-dir| above.
+
+Create a file "filetype.vim" which contains an autocommand for your filetype.
+(Autocommands were explained in section |40.3|.)  Example: >
+
+	augroup filetypedetect
+	au BufNewFile,BufRead *.xyz	setf xyz
+	augroup END
+
+This will recognize all files that end in ".xyz" as the "xyz" filetype.  The
+":augroup" commands put this autocommand in the "filetypedetect" group.  This
+allows removing all autocommands for filetype detection when doing ":filetype
+off".  The "setf" command will set the 'filetype' option to its argument,
+unless it was set already.  This will make sure that 'filetype' isn't set
+twice.
+
+You can use many different patterns to match the name of your file.  Directory
+names can also be included.  See |autocmd-patterns|.  For example, the files
+under "/usr/share/scripts/" are all "ruby" files, but don't have the expected
+file name extension.  Adding this to the example above: >
+
+	augroup filetypedetect
+	au BufNewFile,BufRead *.xyz			setf xyz
+	au BufNewFile,BufRead /usr/share/scripts/*	setf ruby
+	augroup END
+
+However, if you now edit a file /usr/share/scripts/README.txt, this is not a
+ruby file.  The danger of a pattern ending in "*" is that it quickly matches
+too many files.  To avoid trouble with this, put the filetype.vim file in
+another directory, one that is at the end of 'runtimepath'.  For Unix for
+example, you could use "~/.vim/after/filetype.vim".
+   You now put the detection of text files in ~/.vim/filetype.vim: >
+
+	augroup filetypedetect
+	au BufNewFile,BufRead *.txt			setf text
+	augroup END
+
+That file is found in 'runtimepath' first.  Then use this in
+~/.vim/after/filetype.vim, which is found last: >
+
+	augroup filetypedetect
+	au BufNewFile,BufRead /usr/share/scripts/*	setf ruby
+	augroup END
+
+What will happen now is that Vim searches for "filetype.vim" files in each
+directory in 'runtimepath'.  First ~/.vim/filetype.vim is found.  The
+autocommand to catch *.txt files is defined there.  Then Vim finds the
+filetype.vim file in $VIMRUNTIME, which is halfway 'runtimepath'.  Finally
+~/.vim/after/filetype.vim is found and the autocommand for detecting ruby
+files in /usr/share/scripts is added.
+   When you now edit /usr/share/scripts/README.txt, the autocommands are
+checked in the order in which they were defined.  The *.txt pattern matches,
+thus "setf text" is executed to set the filetype to "text".  The pattern for
+ruby matches too, and the "setf ruby" is executed.  But since 'filetype' was
+already set to "text", nothing happens here.
+   When you edit the file /usr/share/scripts/foobar the same autocommands are
+checked.  Only the one for ruby matches and "setf ruby" sets 'filetype' to
+ruby.
+
+
+RECOGNIZING BY CONTENTS
+
+If your file cannot be recognized by its file name, you might be able to
+recognize it by its contents.  For example, many script files start with a
+line like:
+
+	#!/bin/xyz ~
+
+To recognize this script create a file "scripts.vim" in your runtime directory
+(same place where filetype.vim goes).  It might look like this: >
+
+	if did_filetype()
+	  finish
+	endif
+	if getline(1) =~ '^#!.*[/\\]xyz\>'
+	  setf xyz
+	endif
+
+The first check with did_filetype() is to avoid that you will check the
+contents of files for which the filetype was already detected by the file
+name.  That avoids wasting time on checking the file when the "setf" command
+won't do anything.
+   The scripts.vim file is sourced by an autocommand in the default
+filetype.vim file.  Therefore, the order of checks is:
+
+	1. filetype.vim files before $VIMRUNTIME in 'runtimepath'
+	2. first part of $VIMRUNTIME/filetype.vim
+	3. all scripts.vim files in 'runtimepath'
+	4. remainder of $VIMRUNTIME/filetype.vim
+	5. filetype.vim files after $VIMRUNTIME in 'runtimepath'
+
+If this is not sufficient for you, add an autocommand that matches all files
+and sources a script or executes a function to check the contents of the file.
+
+==============================================================================
+
+Next chapter: |usr_44.txt|  Your own syntax highlighted
+
+Copyright: see |manual-copyright|  vim:tw=78:ts=8:ft=help:norl:
--- /dev/null
+++ b/lib/vimfiles/doc/usr_44.txt
@@ -1,0 +1,719 @@
+*usr_44.txt*	For Vim version 7.1.  Last change: 2006 Apr 24
+
+		     VIM USER MANUAL - by Bram Moolenaar
+
+			 Your own syntax highlighted
+
+
+Vim comes with highlighting for a couple of hundred different file types.  If
+the file you are editing isn't included, read this chapter to find out how to
+get this type of file highlighted.  Also see |:syn-define| in the reference
+manual.
+
+|44.1|	Basic syntax commands
+|44.2|	Keywords
+|44.3|	Matches
+|44.4|	Regions
+|44.5|	Nested items
+|44.6|	Following groups
+|44.7|	Other arguments
+|44.8|	Clusters
+|44.9|	Including another syntax file
+|44.10|	Synchronizing
+|44.11|	Installing a syntax file
+|44.12|	Portable syntax file layout
+
+     Next chapter: |usr_45.txt|  Select your language
+ Previous chapter: |usr_43.txt|  Using filetypes
+Table of contents: |usr_toc.txt|
+
+==============================================================================
+*44.1*	Basic syntax commands
+
+Using an existing syntax file to start with will save you a lot of time.  Try
+finding a syntax file in $VIMRUNTIME/syntax for a language that is similar.
+These files will also show you the normal layout of a syntax file.  To
+understand it, you need to read the following.
+
+Let's start with the basic arguments.  Before we start defining any new
+syntax, we need to clear out any old definitions: >
+
+	:syntax clear
+
+This isn't required in the final syntax file, but very useful when
+experimenting.
+
+There are more simplifications in this chapter.  If you are writing a syntax
+file to be used by others, read all the way through the end to find out the
+details.
+
+
+LISTING DEFINED ITEMS
+
+To check which syntax items are currently defined, use this command: >
+
+	:syntax
+
+You can use this to check which items have actually been defined.  Quite
+useful when you are experimenting with a new syntax file.  It also shows the
+colors used for each item, which helps to find out what is what.
+   To list the items in a specific syntax group use: >
+
+	:syntax list {group-name}
+
+This also can be used to list clusters (explained in |44.8|).  Just include
+the @ in the name.
+
+
+MATCHING CASE
+
+Some languages are not case sensitive, such as Pascal.  Others, such as C, are
+case sensitive.  You need to tell which type you have with the following
+commands: >
+	:syntax case match
+	:syntax case ignore
+
+The "match" argument means that Vim will match the case of syntax elements.
+Therefore, "int" differs from "Int" and "INT".  If the "ignore" argument is
+used, the following are equivalent: "Procedure", "PROCEDURE" and "procedure".
+   The ":syntax case" commands can appear anywhere in a syntax file and affect
+the syntax definitions that follow.  In most cases, you have only one ":syntax
+case" command in your syntax file; if you work with an unusual language that
+contains both case-sensitive and non-case-sensitive elements, however, you can
+scatter the ":syntax case" command throughout the file.
+
+==============================================================================
+*44.2*	Keywords
+
+The most basic syntax elements are keywords.  To define a keyword, use the
+following form: >
+
+	:syntax keyword {group} {keyword} ...
+
+The {group} is the name of a syntax group.  With the ":highlight" command you
+can assign colors to a {group}.  The {keyword} argument is an actual keyword.
+Here are a few examples: >
+
+	:syntax keyword xType int long char
+	:syntax keyword xStatement if then else endif
+
+This example uses the group names "xType" and "xStatement".  By convention,
+each group name is prefixed by the filetype for the language being defined.
+This example defines syntax for the x language (eXample language without an
+interesting name).  In a syntax file for "csh" scripts the name "cshType"
+would be used.  Thus the prefix is equal to the value of 'filetype'.
+   These commands cause the words "int", "long" and "char" to be highlighted
+one way and the words "if", "then", "else" and "endif" to be highlighted
+another way.  Now you need to connect the x group names to standard Vim
+names.  You do this with the following commands: >
+
+	:highlight link xType Type
+	:highlight link xStatement Statement
+
+This tells Vim to highlight "xType" like "Type" and "xStatement" like
+"Statement".  See |group-name| for the standard names.
+
+
+UNUSUAL KEYWORDS
+
+The characters used in a keyword must be in the 'iskeyword' option.  If you
+use another character, the word will never match.  Vim doesn't give a warning
+message for this.
+   The x language uses the '-' character in keywords.  This is how it's done:
+>
+	:setlocal iskeyword+=-
+	:syntax keyword xStatement when-not
+
+The ":setlocal" command is used to change 'iskeyword' only for the current
+buffer.  Still it does change the behavior of commands like "w" and "*".  If
+that is not wanted, don't define a keyword but use a match (explained in the
+next section).
+
+The x language allows for abbreviations.  For example, "next" can be
+abbreviated to "n", "ne" or "nex".  You can define them by using this command:
+>
+	:syntax keyword xStatement n[ext]
+
+This doesn't match "nextone", keywords always match whole words only.
+
+==============================================================================
+*44.3*	Matches
+
+Consider defining something a bit more complex.  You want to match ordinary
+identifiers.  To do this, you define a match syntax item.  This one matches
+any word consisting of only lowercase letters: >
+
+	:syntax match xIdentifier /\<\l\+\>/
+<
+	Note:
+	Keywords overrule any other syntax item.  Thus the keywords "if",
+	"then", etc., will be keywords, as defined with the ":syntax keyword"
+	commands above, even though they also match the pattern for
+	xIdentifier.
+
+The part at the end is a pattern, like it's used for searching.  The // is
+used to surround the pattern (like how it's done in a ":substitute" command).
+You can use any other character, like a plus or a quote.
+
+Now define a match for a comment.  In the x language it is anything from # to
+the end of a line: >
+
+	:syntax match xComment /#.*/
+
+Since you can use any search pattern, you can highlight very complex things
+with a match item.  See |pattern| for help on search patterns.
+
+==============================================================================
+*44.4*	Regions
+
+In the example x language, strings are enclosed in double quotation marks (").
+To highlight strings you define a region.  You need a region start (double
+quote) and a region end (double quote).  The definition is as follows: >
+
+	:syntax region xString start=/"/ end=/"/
+
+The "start" and "end" directives define the patterns used to find the start
+and end of the region.  But what about strings that look like this?
+
+	"A string with a double quote (\") in it" ~
+
+This creates a problem: The double quotation marks in the middle of the string
+will end the region.  You need to tell Vim to skip over any escaped double
+quotes in the string.  Do this with the skip keyword: >
+
+	:syntax region xString start=/"/ skip=/\\"/ end=/"/
+
+The double backslash matches a single backslash, since the backslash is a
+special character in search patterns.
+
+When to use a region instead of a match?  The main difference is that a match
+item is a single pattern, which must match as a whole.  A region starts as
+soon as the "start" pattern matches.  Whether the "end" pattern is found or
+not doesn't matter.  Thus when the item depends on the "end" pattern to match,
+you cannot use a region.  Otherwise, regions are often simpler to define.  And
+it is easier to use nested items, as is explained in the next section.
+
+==============================================================================
+*44.5*	Nested items
+
+Take a look at this comment:
+
+	%Get input  TODO: Skip white space ~
+
+You want to highlight TODO in big yellow letters, even though it is in a
+comment that is highlighted blue.  To let Vim know about this, you define the
+following syntax groups: >
+
+	:syntax keyword xTodo TODO contained
+	:syntax match xComment /%.*/ contains=xTodo
+
+In the first line, the "contained" argument tells Vim that this keyword can
+exist only inside another syntax item.  The next line has "contains=xTodo".
+This indicates that the xTodo syntax element is inside it.  The result is that
+the comment line as a whole is matched with "xComment" and made blue.  The
+word TODO inside it is matched by xTodo and highlighted yellow (highlighting
+for xTodo was setup for this).
+
+
+RECURSIVE NESTING
+
+The x language defines code blocks in curly braces.  And a code block may
+contain other code blocks.  This can be defined this way: >
+
+	:syntax region xBlock start=/{/ end=/}/ contains=xBlock
+
+Suppose you have this text:
+
+	while i < b { ~
+		if a { ~
+			b = c; ~
+		} ~
+	} ~
+
+First a xBlock starts at the { in the first line.  In the second line another
+{ is found.  Since we are inside a xBlock item, and it contains itself, a
+nested xBlock item will start here.  Thus the "b = c" line is inside the
+second level xBlock region.  Then a } is found in the next line, which matches
+with the end pattern of the region.  This ends the nested xBlock.  Because the
+} is included in the nested region, it is hidden from the first xBlock region.
+Then at the last } the first xBlock region ends.
+
+
+KEEPING THE END
+
+Consider the following two syntax items: >
+
+	:syntax region xComment start=/%/ end=/$/ contained
+	:syntax region xPreProc start=/#/ end=/$/ contains=xComment
+
+You define a comment as anything from % to the end of the line.  A
+preprocessor directive is anything from # to the end of the line.  Because you
+can have a comment on a preprocessor line, the preprocessor definition
+includes a "contains=xComment" argument.  Now look what happens with this
+text:
+
+	#define X = Y  % Comment text ~
+	int foo = 1; ~
+
+What you see is that the second line is also highlighted as xPreProc.  The
+preprocessor directive should end at the end of the line.  That is why
+you have used "end=/$/".  So what is going wrong?
+   The problem is the contained comment.  The comment starts with % and ends
+at the end of the line.  After the comment ends, the preprocessor syntax
+continues.  This is after the end of the line has been seen, so the next
+line is included as well.
+   To avoid this problem and to avoid a contained syntax item eating a needed
+end of line, use the "keepend" argument.  This takes care of
+the double end-of-line matching: >
+
+	:syntax region xComment start=/%/ end=/$/ contained
+	:syntax region xPreProc start=/#/ end=/$/ contains=xComment keepend
+
+
+CONTAINING MANY ITEMS
+
+You can use the contains argument to specify that everything can be contained.
+For example: >
+
+	:syntax region xList start=/\[/ end=/\]/ contains=ALL
+
+All syntax items will be contained in this one.  It also contains itself, but
+not at the same position (that would cause an endless loop).
+   You can specify that some groups are not contained.  Thus contain all
+groups but the ones that are listed:
+>
+	:syntax region xList start=/\[/ end=/\]/ contains=ALLBUT,xString
+
+With the "TOP" item you can include all items that don't have a "contained"
+argument.  "CONTAINED" is used to only include items with a "contained"
+argument.  See |:syn-contains| for the details.
+
+==============================================================================
+*44.6*	Following groups
+
+The x language has statements in this form:
+
+	if (condition) then ~
+
+You want to highlight the three items differently.  But "(condition)" and
+"then" might also appear in other places, where they get different
+highlighting.  This is how you can do this: >
+
+	:syntax match xIf /if/ nextgroup=xIfCondition skipwhite
+	:syntax match xIfCondition /([^)]*)/ contained nextgroup=xThen skipwhite
+	:syntax match xThen /then/ contained
+
+The "nextgroup" argument specifies which item can come next.  This is not
+required.  If none of the items that are specified are found, nothing happens.
+For example, in this text:
+
+	if not (condition) then ~
+
+The "if" is matched by xIf.  "not" doesn't match the specified nextgroup
+xIfCondition, thus only the "if" is highlighted.
+
+The "skipwhite" argument tells Vim that white space (spaces and tabs) may
+appear in between the items.  Similar arguments are "skipnl", which allows a
+line break in between the items, and "skipempty", which allows empty lines.
+Notice that "skipnl" doesn't skip an empty line, something must match after
+the line break.
+
+==============================================================================
+*44.7*	Other arguments
+
+MATCHGROUP
+
+When you define a region, the entire region is highlighted according to the
+group name specified.  To highlight the text enclosed in parentheses () with
+the group xInside, for example, use the following command: >
+
+	:syntax region xInside start=/(/ end=/)/
+
+Suppose, that you want to highlight the parentheses differently.  You can do
+this with a lot of convoluted region statements, or you can use the
+"matchgroup" argument.  This tells Vim to highlight the start and end of a
+region with a different highlight group (in this case, the xParen group): >
+
+	:syntax region xInside matchgroup=xParen start=/(/ end=/)/
+
+The "matchgroup" argument applies to the start or end match that comes after
+it.  In the previous example both start and end are highlighted with xParen.
+To highlight the end with xParenEnd: >
+
+	:syntax region xInside matchgroup=xParen start=/(/
+		\ matchgroup=xParenEnd end=/)/
+
+A side effect of using "matchgroup" is that contained items will not match in
+the start or end of the region.  The example for "transparent" uses this.
+
+
+TRANSPARENT
+
+In a C language file you would like to highlight the () text after a "while"
+differently from the () text after a "for".  In both of these there can be
+nested () items, which should be highlighted in the same way.  You must make
+sure the () highlighting stops at the matching ).  This is one way to do this:
+>
+	:syntax region cWhile matchgroup=cWhile start=/while\s*(/ end=/)/
+		\ contains=cCondNest
+	:syntax region cFor matchgroup=cFor start=/for\s*(/ end=/)/
+		\ contains=cCondNest
+	:syntax region cCondNest start=/(/ end=/)/ contained transparent
+
+Now you can give cWhile and cFor different highlighting.  The cCondNest item
+can appear in either of them, but take over the highlighting of the item it is
+contained in.  The "transparent" argument causes this.
+   Notice that the "matchgroup" argument has the same group as the item
+itself.  Why define it then?  Well, the side effect of using a matchgroup is
+that contained items are not found in the match with the start item then.
+This avoids that the cCondNest group matches the ( just after the "while" or
+"for".  If this would happen, it would span the whole text until the matching
+) and the region would continue after it.  Now cCondNest only matches after
+the match with the start pattern, thus after the first (.
+
+
+OFFSETS
+
+Suppose you want to define a region for the text between ( and ) after an
+"if".  But you don't want to include the "if" or the ( and ).  You can do this
+by specifying offsets for the patterns.  Example: >
+
+	:syntax region xCond start=/if\s*(/ms=e+1 end=/)/me=s-1
+
+The offset for the start pattern is "ms=e+1".  "ms" stands for Match Start.
+This defines an offset for the start of the match.  Normally the match starts
+where the pattern matches.  "e+1" means that the match now starts at the end
+of the pattern match, and then one character further.
+   The offset for the end pattern is "me=s-1".  "me" stands for Match End.
+"s-1" means the start of the pattern match and then one character back.  The
+result is that in this text:
+
+	if (foo == bar) ~
+
+Only the text "foo == bar" will be highlighted as xCond.
+
+More about offsets here: |:syn-pattern-offset|.
+
+
+ONELINE
+
+The "oneline" argument indicates that the region does not cross a line
+boundary.  For example: >
+
+	:syntax region xIfThen start=/if/ end=/then/ oneline
+
+This defines a region that starts at "if" and ends at "then".  But if there is
+no "then" after the "if", the region doesn't match.
+
+	Note:
+	When using "oneline" the region doesn't start if the end pattern
+	doesn't match in the same line.  Without "oneline" Vim does _not_
+	check if there is a match for the end pattern.  The region starts even
+	when the end pattern doesn't match in the rest of the file.
+
+
+CONTINUATION LINES AND AVOIDING THEM
+
+Things now become a little more complex.  Let's define a preprocessor line.
+This starts with a # in the first column and continues until the end of the
+line.  A line that ends with \ makes the next line a continuation line.  The
+way you handle this is to allow the syntax item to contain a continuation
+pattern: >
+
+	:syntax region xPreProc start=/^#/ end=/$/ contains=xLineContinue
+	:syntax match xLineContinue "\\$" contained
+
+In this case, although xPreProc normally matches a single line, the group
+contained in it (namely xLineContinue) lets it go on for more than one line.
+For example, it would match both of these lines:
+
+	#define SPAM  spam spam spam \ ~
+			bacon and spam ~
+
+In this case, this is what you want.  If it is not what you want, you can call
+for the region to be on a single line by adding "excludenl" to the contained
+pattern.  For example, you want to highlight "end" in xPreProc, but only at
+the end of the line.  To avoid making the xPreProc continue on the next line,
+like xLineContinue does, use "excludenl" like this: >
+
+	:syntax region xPreProc start=/^#/ end=/$/
+		\ contains=xLineContinue,xPreProcEnd
+	:syntax match xPreProcEnd excludenl /end$/ contained
+	:syntax match xLineContinue "\\$" contained
+
+"excludenl" must be placed before the pattern.  Since "xLineContinue" doesn't
+have "excludenl", a match with it will extend xPreProc to the next line as
+before.
+
+==============================================================================
+*44.8*	Clusters
+
+One of the things you will notice as you start to write a syntax file is that
+you wind up generating a lot of syntax groups.  Vim enables you to define a
+collection of syntax groups called a cluster.
+   Suppose you have a language that contains for loops, if statements, while
+loops, and functions.  Each of them contains the same syntax elements: numbers
+and identifiers.  You define them like this: >
+
+	:syntax match xFor /^for.*/ contains=xNumber,xIdent
+	:syntax match xIf /^if.*/ contains=xNumber,xIdent
+	:syntax match xWhile /^while.*/ contains=xNumber,xIdent
+
+You have to repeat the same "contains=" every time.  If you want to add
+another contained item, you have to add it three times.  Syntax clusters
+simplify these definitions by enabling you to have one cluster stand for
+several syntax groups.
+   To define a cluster for the two items that the three groups contain, use
+the following command: >
+
+	:syntax cluster xState contains=xNumber,xIdent
+
+Clusters are used inside other syntax items just like any syntax group.
+Their names start with @.  Thus, you can define the three groups like this: >
+
+	:syntax match xFor /^for.*/ contains=@xState
+	:syntax match xIf /^if.*/ contains=@xState
+	:syntax match xWhile /^while.*/ contains=@xState
+
+You can add new group names to this cluster with the "add" argument: >
+
+	:syntax cluster xState add=xString
+
+You can remove syntax groups from this list as well: >
+
+	:syntax cluster xState remove=xNumber
+
+==============================================================================
+*44.9*	Including another syntax file
+
+The C++ language syntax is a superset of the C language.  Because you do not
+want to write two syntax files, you can have the C++ syntax file read in the
+one for C by using the following command: >
+
+	:runtime! syntax/c.vim
+
+The ":runtime!" command searches 'runtimepath' for all "syntax/c.vim" files.
+This makes the C syntax be defined like for C files.  If you have replaced the
+c.vim syntax file, or added items with an extra file, these will be loaded as
+well.
+   After loading the C syntax items the specific C++ items can be defined.
+For example, add keywords that are not used in C: >
+
+	:syntax keyword cppStatement	new delete this friend using
+
+This works just like in any other syntax file.
+
+Now consider the Perl language.  It consists of two distinct parts: a
+documentation section in POD format, and a program written in Perl itself.
+The POD section starts with "=head" and ends with "=cut".
+   You want to define the POD syntax in one file, and use it from the Perl
+syntax file.  The ":syntax include" command reads in a syntax file and stores
+the elements it defined in a syntax cluster.  For Perl, the statements are as
+follows: >
+
+	:syntax include @Pod <sfile>:p:h/pod.vim
+	:syntax region perlPOD start=/^=head/ end=/^=cut/ contains=@Pod
+
+When "=head" is found in a Perl file, the perlPOD region starts.  In this
+region the @Pod cluster is contained.  All the items defined as top-level
+items in the pod.vim syntax files will match here.  When "=cut" is found, the
+region ends and we go back to the items defined in the Perl file.
+   The ":syntax include" command is clever enough to ignore a ":syntax clear"
+command in the included file.  And an argument such as "contains=ALL" will
+only contain items defined in the included file, not in the file that includes
+it.
+   The "<sfile>:p:h/" part uses the name of the current file (<sfile>),
+expands it to a full path (:p) and then takes the head (:h).  This results in
+the directory name of the file.  This causes the pod.vim file in the same
+directory to be included.
+
+==============================================================================
+*44.10*	Synchronizing
+
+Compilers have it easy.  They start at the beginning of a file and parse it
+straight through.  Vim does not have it so easy.  It must start in the middle,
+where the editing is being done.  So how does it tell where it is?
+   The secret is the ":syntax sync" command.  This tells Vim how to figure out
+where it is.  For example, the following command tells Vim to scan backward
+for the beginning or end of a C-style comment and begin syntax coloring from
+there: >
+
+	:syntax sync ccomment
+
+You can tune this processing with some arguments.  The "minlines" argument
+tells Vim the minimum number of lines to look backward, and "maxlines" tells
+the editor the maximum number of lines to scan.
+   For example, the following command tells Vim to look at least 10 lines
+before the top of the screen: >
+
+	:syntax sync ccomment minlines=10 maxlines=500
+
+If it cannot figure out where it is in that space, it starts looking farther
+and farther back until it figures out what to do.  But it looks no farther
+back than 500 lines.  (A large "maxlines" slows down processing.  A small one
+might cause synchronization to fail.)
+   To make synchronizing go a bit faster, tell Vim which syntax items can be
+skipped.  Every match and region that only needs to be used when actually
+displaying text can be given the "display" argument.
+   By default, the comment to be found will be colored as part of the Comment
+syntax group.  If you want to color things another way, you can specify a
+different syntax group: >
+
+	:syntax sync ccomment xAltComment
+
+If your programming language does not have C-style comments in it, you can try
+another method of synchronization.  The simplest way is to tell Vim to space
+back a number of lines and try to figure out things from there.  The following
+command tells Vim to go back 150 lines and start parsing from there: >
+
+	:syntax sync minlines=150
+
+A large "minlines" value can make Vim slower, especially when scrolling
+backwards in the file.
+   Finally, you can specify a syntax group to look for by using this command:
+>
+	:syntax sync match {sync-group-name}
+		\ grouphere {group-name} {pattern}
+
+This tells Vim that when it sees {pattern} the syntax group named {group-name}
+begins just after the pattern given.  The {sync-group-name} is used to give a
+name to this synchronization specification.  For example, the sh scripting
+language begins an if statement with "if" and ends it with "fi":
+
+	if [ --f file.txt ] ; then ~
+		echo "File exists" ~
+	fi ~
+
+To define a "grouphere" directive for this syntax, you use the following
+command: >
+
+	:syntax sync match shIfSync grouphere shIf "\<if\>"
+
+The "groupthere" argument tells Vim that the pattern ends a group.  For
+example, the end of the if/fi group is as follows: >
+
+	:syntax sync match shIfSync groupthere NONE "\<fi\>"
+
+In this example, the NONE tells Vim that you are not in any special syntax
+region.  In particular, you are not inside an if block.
+
+You also can define matches and regions that are with no "grouphere" or
+"groupthere" arguments.  These groups are for syntax groups skipped during
+synchronization.  For example, the following skips over anything inside {},
+even if it would normally match another synchronization method: >
+
+	:syntax sync match xSpecial /{.*}/
+
+More about synchronizing in the reference manual: |:syn-sync|.
+
+==============================================================================
+*44.11*	Installing a syntax file
+
+When your new syntax file is ready to be used, drop it in a "syntax" directory
+in 'runtimepath'.  For Unix that would be "~/.vim/syntax".
+  The name of the syntax file must be equal to the file type, with ".vim"
+added.  Thus for the x language, the full path of the file would be:
+
+	~/.vim/syntax/x.vim ~
+
+You must also make the file type be recognized.  See |43.2|.
+
+If your file works well, you might want to make it available to other Vim
+users.  First read the next section to make sure your file works well for
+others.  Then e-mail it to the Vim maintainer: <maintainer@vim.org>.  Also
+explain how the filetype can be detected.  With a bit of luck your file will
+be included in the next Vim version!
+
+
+ADDING TO AN EXISTING SYNTAX FILE
+
+We were assuming you were adding a completely new syntax file.  When an existing
+syntax file works, but is missing some items, you can add items in a separate
+file.  That avoids changing the distributed syntax file, which will be lost
+when installing a new version of Vim.
+   Write syntax commands in your file, possibly using group names from the
+existing syntax.  For example, to add new variable types to the C syntax file:
+>
+	:syntax keyword cType off_t uint
+
+Write the file with the same name as the original syntax file.  In this case
+"c.vim".  Place it in a directory near the end of 'runtimepath'.  This makes
+it loaded after the original syntax file.  For Unix this would be:
+
+	~/.vim/after/syntax/c.vim ~
+
+==============================================================================
+*44.12*	Portable syntax file layout
+
+Wouldn't it be nice if all Vim users exchange syntax files?  To make this
+possible, the syntax file must follow a few guidelines.
+
+Start with a header that explains what the syntax file is for, who maintains
+it and when it was last updated.  Don't include too much information about
+changes history, not many people will read it.  Example: >
+
+	" Vim syntax file
+	" Language:	C
+	" Maintainer:	Bram Moolenaar <Bram@vim.org>
+	" Last Change:	2001 Jun 18
+	" Remark:	Included by the C++ syntax.
+
+Use the same layout as the other syntax files.  Using an existing syntax file
+as an example will save you a lot of time.
+
+Choose a good, descriptive name for your syntax file.  Use lowercase letters
+and digits.  Don't make it too long, it is used in many places: The name of
+the syntax file "name.vim", 'filetype', b:current_syntax the start of each
+syntax group (nameType, nameStatement, nameString, etc).
+
+Start with a check for "b:current_syntax".  If it is defined, some other
+syntax file, earlier in 'runtimepath' was already loaded: >
+
+	if exists("b:current_syntax")
+	  finish
+	endif
+
+To be compatible with Vim 5.8 use: >
+
+	if version < 600
+	  syntax clear
+	elseif exists("b:current_syntax")
+	  finish
+	endif
+
+Set "b:current_syntax" to the name of the syntax at the end.  Don't forget
+that included files do this too, you might have to reset "b:current_syntax" if
+you include two files.
+
+If you want your syntax file to work with Vim 5.x, add a check for v:version.
+See yacc.vim for an example.
+
+Do not include anything that is a user preference.  Don't set 'tabstop',
+'expandtab', etc.  These belong in a filetype plugin.
+
+Do not include mappings or abbreviations.  Only include setting 'iskeyword' if
+it is really necessary for recognizing keywords.
+
+To allow users select their own preferred colors, make a different group name
+for every kind of highlighted item.  Then link each of them to one of the
+standard highlight groups.  That will make it work with every color scheme.
+If you select specific colors it will look bad with some color schemes.  And
+don't forget that some people use a different background color, or have only
+eight colors available.
+
+For the linking use "hi def link", so that the user can select different
+highlighting before your syntax file is loaded.  Example: >
+
+	  hi def link nameString	String
+	  hi def link nameNumber	Number
+	  hi def link nameCommand	Statement
+	  ... etc ...
+
+Add the "display" argument to items that are not used when syncing, to speed
+up scrolling backwards and CTRL-L.
+
+==============================================================================
+
+Next chapter: |usr_45.txt|  Select your language
+
+Copyright: see |manual-copyright|  vim:tw=78:ts=8:ft=help:norl:
--- /dev/null
+++ b/lib/vimfiles/doc/usr_45.txt
@@ -1,0 +1,419 @@
+*usr_45.txt*	For Vim version 7.1.  Last change: 2006 Apr 24
+
+		     VIM USER MANUAL - by Bram Moolenaar
+
+			     Select your language
+
+
+The messages in Vim can be given in several languages.  This chapter explains
+how to change which one is used.  Also, the different ways to work with files
+in various languages is explained.
+
+|45.1|	Language for Messages
+|45.2|	Language for Menus
+|45.3|	Using another encoding
+|45.4|	Editing files with a different encoding
+|45.5|	Entering language text
+
+     Next chapter: |usr_90.txt|  Installing Vim
+ Previous chapter: |usr_44.txt|  Your own syntax highlighted
+Table of contents: |usr_toc.txt|
+
+==============================================================================
+*45.1*	Language for Messages
+
+When you start Vim, it checks the environment to find out what language you
+are using.  Mostly this should work fine, and you get the messages in your
+language (if they are available).  To see what the current language is, use
+this command: >
+
+	:language
+
+If it replies with "C", this means the default is being used, which is
+English.
+
+	Note:
+	Using different languages only works when Vim was compiled to handle
+	it.  To find out if it works, use the ":version" command and check the
+	output for "+gettext" and "+multi_lang".  If they are there, you are
+	OK.  If you see "-gettext" or "-multi_lang" you will have to find
+	another Vim.
+
+What if you would like your messages in a different language?  There are
+several ways.  Which one you should use depends on the capabilities of your
+system.
+   The first way is to set the environment to the desired language before
+starting Vim.  Example for Unix: >
+
+	env LANG=de_DE.ISO_8859-1  vim
+
+This only works if the language is available on your system.  The advantage is
+that all the GUI messages and things in libraries will use the right language
+as well.  A disadvantage is that you must do this before starting Vim.  If you
+want to change language while Vim is running, you can use the second method: >
+
+	:language fr_FR.ISO_8859-1
+
+This way you can try out several names for your language.  You will get an
+error message when it's not supported on your system.  You don't get an error
+when translated messages are not available.  Vim will silently fall back to
+using English.
+   To find out which languages are supported on your system, find the
+directory where they are listed.  On my system it is "/usr/share/locale".  On
+some systems it's in "/usr/lib/locale".  The manual page for "setlocale"
+should give you a hint where it is found on your system.
+   Be careful to type the name exactly as it should be.  Upper and lowercase
+matter, and the '-' and '_' characters are easily confused.
+
+You can also set the language separately for messages, edited text and the
+time format.  See |:language|.
+
+
+DO-IT-YOURSELF MESSAGE TRANSLATION
+
+If translated messages are not available for your language, you could write
+them yourself.  To do this, get the source code for Vim and the GNU gettext
+package.  After unpacking the sources, instructions can be found in the
+directory src/po/README.txt.
+   It's not too difficult to do the translation.  You don't need to be a
+programmer.  You must know both English and the language you are translating
+to, of course.
+   When you are satisfied with the translation, consider making it available
+to others.  Upload it at vim-online (http://vim.sf.net) or e-mail it to
+the Vim maintainer <maintainer@vim.org>.  Or both.
+
+==============================================================================
+*45.2*	Language for Menus
+
+The default menus are in English.  To be able to use your local language, they
+must be translated.  Normally this is automatically done for you if the
+environment is set for your language, just like with messages.  You don't need
+to do anything extra for this.  But it only works if translations for the
+language are available.
+   Suppose you are in Germany, with the language set to German, but prefer to
+use "File" instead of "Datei".  You can switch back to using the English menus
+this way: >
+
+	:set langmenu=none
+
+It is also possible to specify a language: >
+
+	:set langmenu=nl_NL.ISO_8859-1
+
+Like above, differences between "-" and "_" matter.  However, upper/lowercase
+differences are ignored here.
+   The 'langmenu' option must be set before the menus are loaded.  Once the
+menus have been defined changing 'langmenu' has no direct effect.  Therefore,
+put the command to set 'langmenu' in your vimrc file.
+   If you really want to switch menu language while running Vim, you can do it
+this way: >
+
+	:source $VIMRUNTIME/delmenu.vim
+	:set langmenu=de_DE.ISO_8859-1
+	:source $VIMRUNTIME/menu.vim
+
+There is one drawback: All menus that you defined yourself will be gone.  You
+will need to redefine them as well.
+
+
+DO-IT-YOURSELF MENU TRANSLATION
+
+To see which menu translations are available, look in this directory:
+
+	$VIMRUNTIME/lang ~
+
+The files are called menu_{language}.vim.  If you don't see the language you
+want to use, you can do your own translations.  The simplest way to do this is
+by copying one of the existing language files, and change it.
+   First find out the name of your language with the ":language" command.  Use
+this name, but with all letters made lowercase.  Then copy the file to your
+own runtime directory, as found early in 'runtimepath'.  For example, for Unix
+you would do: >
+
+	:!cp $VIMRUNTIME/lang/menu_ko_kr.euckr.vim ~/.vim/lang/menu_nl_be.iso_8859-1.vim
+
+You will find hints for the translation in "$VIMRUNTIME/lang/README.txt".
+
+==============================================================================
+*45.3*	Using another encoding
+
+Vim guesses that the files you are going to edit are encoded for your
+language.  For many European languages this is "latin1".  Then each byte is
+one character.  That means there are 256 different characters possible.  For
+Asian languages this is not sufficient.  These mostly use a double-byte
+encoding, providing for over ten thousand possible characters.  This still
+isn't enough when a text is to contain several different languages.  This is
+where Unicode comes in.  It was designed to include all characters used in
+commonly used languages.  This is the "Super encoding that replaces all
+others".  But it isn't used that much yet.
+   Fortunately, Vim supports these three kinds of encodings.  And, with some
+restrictions, you can use them even when your environment uses another
+language than the text.
+   Nevertheless, when you only edit files that are in the encoding of your
+language, the default should work fine and you don't need to do anything.  The
+following is only relevant when you want to edit different languages.
+
+	Note:
+	Using different encodings only works when Vim was compiled to handle
+	it.  To find out if it works, use the ":version" command and check the
+	output for "+multi_byte".  If it's there, you are OK.  If you see
+	"-multi_byte" you will have to find another Vim.
+
+
+USING UNICODE IN THE GUI
+
+The nice thing about Unicode is that other encodings can be converted to it
+and back without losing information.  When you make Vim use Unicode
+internally, you will be able to edit files in any encoding.
+   Unfortunately, the number of systems supporting Unicode is still limited.
+Thus it's unlikely that your language uses it.  You need to tell Vim you want
+to use Unicode, and how to handle interfacing with the rest of the system.
+   Let's start with the GUI version of Vim, which is able to display Unicode
+characters.  This should work: >
+
+	:set encoding=utf-8
+	:set guifont=-misc-fixed-medium-r-normal--18-120-100-100-c-90-iso10646-1
+
+The 'encoding' option tells Vim the encoding of the characters that you use.
+This applies to the text in buffers (files you are editing), registers, Vim
+script files, etc.  You can regard 'encoding' as the setting for the internals
+of Vim.
+   This example assumes you have this font on your system.  The name in the
+example is for the X Window System.  This font is in a package that is used to
+enhance xterm with Unicode support.  If you don't have this font, you might
+find it here:
+
+	http://www.cl.cam.ac.uk/~mgk25/download/ucs-fonts.tar.gz ~
+
+For MS-Windows, some fonts have a limited number of Unicode characters.  Try
+using the "Courier New" font.  You can use the Edit/Select Font... menu to
+select and try out the fonts available.  Only fixed-width fonts can be used
+though.  Example: >
+
+	:set guifont=courier_new:h12
+
+If it doesn't work well, try getting a fontpack.  If Microsoft didn't move it,
+you can find it here:
+
+	http://www.microsoft.com/typography/fontpack/default.htm ~
+
+Now you have told Vim to use Unicode internally and display text with a
+Unicode font.  Typed characters still arrive in the encoding of your original
+language.  This requires converting them to Unicode.  Tell Vim the language
+from which to convert with the 'termencoding' option.  You can do it like
+this: >
+
+	:let &termencoding = &encoding
+	:set encoding=utf-8
+
+This assigns the old value of 'encoding' to 'termencoding' before setting
+'encoding' to utf-8.  You will have to try out if this really works for your
+setup.  It should work especially well when using an input method for an Asian
+language, and you want to edit Unicode text.
+
+
+USING UNICODE IN A UNICODE TERMINAL
+
+There are terminals that support Unicode directly.  The standard xterm that
+comes with XFree86 is one of them.  Let's use that as an example.
+   First of all, the xterm must have been compiled with Unicode support.  See
+|UTF8-xterm| how to check that and how to compile it when needed.
+   Start the xterm with the "-u8" argument.  You might also need so specify a
+font.  Example: >
+
+   xterm -u8 -fn -misc-fixed-medium-r-normal--18-120-100-100-c-90-iso10646-1
+
+Now you can run Vim inside this terminal.  Set 'encoding' to "utf-8" as
+before.  That's all.
+
+
+USING UNICODE IN AN ORDINARY TERMINAL
+
+Suppose you want to work with Unicode files, but don't have a terminal with
+Unicode support.  You can do this with Vim, although characters that are not
+supported by the terminal will not be displayed.  The layout of the text
+will be preserved.  >
+
+	:let &termencoding = &encoding
+	:set encoding=utf-8
+
+This is the same as what was used for the GUI.  But it works differently: Vim
+will convert the displayed text before sending it to the terminal.  That
+avoids that the display is messed up with strange characters.
+   For this to work the conversion between 'termencoding' and 'encoding' must
+be possible.  Vim will convert from latin1 to Unicode, thus that always works.
+For other conversions the |+iconv| feature is required.
+   Try editing a file with Unicode characters in it.  You will notice that Vim
+will put a question mark (or underscore or some other character) in places
+where a character should be that the terminal can't display.  Move the cursor
+to a question mark and use this command: >
+
+	ga
+
+Vim will display a line with the code of the character.  This gives you a hint
+about what character it is.  You can look it up in a Unicode table.  You could
+actually view a file that way, if you have lots of time at hand.
+
+	Note:
+	Since 'encoding' is used for all text inside Vim, changing it makes
+	all non-ASCII text invalid.  You will notice this when using registers
+	and the 'viminfo' file (e.g., a remembered search pattern).  It's
+	recommended to set 'encoding' in your vimrc file, and leave it alone.
+
+==============================================================================
+*45.4*	Editing files with a different encoding
+
+Suppose you have setup Vim to use Unicode, and you want to edit a file that is
+in 16-bit Unicode.  Sounds simple, right?  Well, Vim actually uses utf-8
+encoding internally, thus the 16-bit encoding must be converted.  Thus there
+is a difference between the character set (Unicode) and the encoding (utf-8 or
+16-bit).
+   Vim will try to detect what kind of file you are editing.  It uses the
+encoding names in the 'fileencodings' option.  When using Unicode, the default
+value is: "ucs-bom,utf-8,latin1".  This means that Vim checks the file to see
+if it's one of these encodings:
+
+	ucs-bom		File must start with a Byte Order Mark (BOM).  This
+			allows detection of 16-bit, 32-bit and utf-8 Unicode
+			encodings.
+	utf-8		utf-8 Unicode.  This is rejected when a sequence of
+			bytes is illegal in utf-8.
+	latin1		The good old 8-bit encoding.  Always works.
+
+When you start editing that 16-bit Unicode file, and it has a BOM, Vim will
+detect this and convert the file to utf-8 when reading it.  The 'fileencoding'
+option (without s at the end) is set to the detected value.  In this case it
+is "ucs-2le".  That means it's Unicode, two bytes and little-endian.  This
+file format is common on MS-Windows (e.g., for registry files).
+   When writing the file, Vim will compare 'fileencoding' with 'encoding'.  If
+they are different, the text will be converted.
+   An empty value for 'fileencoding' means that no conversion is to be done.
+Thus the text is assumed to be encoded with 'encoding'.
+
+If the default 'fileencodings' value is not good for you, set it to the
+encodings you want Vim to try.  Only when a value is found to be invalid will
+the next one be used.  Putting "latin1" first doesn't work, because it is
+never illegal.  An example, to fall back to Japanese when the file doesn't
+have a BOM and isn't utf-8: >
+
+	:set fileencodings=ucs-bom,utf-8,sjis
+
+See |encoding-values| for suggested values.  Other values may work as well.
+This depends on the conversion available.
+
+
+FORCING AN ENCODING
+
+If the automatic detection doesn't work you must tell Vim what encoding the
+file is.  Example: >
+
+	:edit ++enc=koi8-r russian.txt
+
+The "++enc" part specifies the name of the encoding to be used for this file
+only.  Vim will convert the file from the specified encoding, Russian in this
+example, to 'encoding'.  'fileencoding' will also be set to the specified
+encoding, so that the reverse conversion can be done when writing the file.
+   The same argument can be used when writing the file.  This way you can
+actually use Vim to convert a file.  Example: >
+
+	:write ++enc=utf-8 russian.txt
+<
+	Note:
+	Conversion may result in lost characters.  Conversion from an encoding
+	to Unicode and back is mostly free of this problem, unless there are
+	illegal characters.  Conversion from Unicode to other encodings often
+	loses information when there was more than one language in the file.
+
+==============================================================================
+*45.5*	Entering language text
+
+Computer keyboards don't have much more than a hundred keys.  Some languages
+have thousands of characters, Unicode has ten thousands.  So how do you type
+these characters?
+   First of all, when you don't use too many of the special characters, you
+can use digraphs.  This was already explained in |24.9|.
+   When you use a language that uses many more characters than keys on your
+keyboard, you will want to use an Input Method (IM).  This requires learning
+the translation from typed keys to resulting character.  When you need an IM
+you probably already have one on your system.  It should work with Vim like
+with other programs.  For details see |mbyte-XIM| for the X Window system and
+|mbyte-IME| for MS-Windows.
+
+
+KEYMAPS
+
+For some languages the character set is different from latin, but uses a
+similar number of characters.  It's possible to map keys to characters.  Vim
+uses keymaps for this.
+   Suppose you want to type Hebrew.  You can load the keymap like this: >
+
+	:set keymap=hebrew
+
+Vim will try to find a keymap file for you.  This depends on the value of
+'encoding'.  If no matching file was found, you will get an error message.
+
+Now you can type Hebrew in Insert mode.  In Normal mode, and when typing a ":"
+command, Vim automatically switches to English.  You can use this command to
+switch between Hebrew and English: >
+
+	CTRL-^
+
+This only works in Insert mode and Command-line mode.  In Normal mode it does
+something completely different (jumps to alternate file).
+   The usage of the keymap is indicated in the mode message, if you have the
+'showmode' option set.  In the GUI Vim will indicate the usage of keymaps with
+a different cursor color.
+   You can also change the usage of the keymap with the 'iminsert' and
+'imsearch' options.
+
+To see the list of mappings, use this command: >
+
+	:lmap
+
+To find out which keymap files are available, in the GUI you can use the
+Edit/Keymap menu.  Otherwise you can use this command: >
+
+	:echo globpath(&rtp, "keymap/*.vim")
+
+
+DO-IT-YOURSELF KEYMAPS
+
+You can create your own keymap file.  It's not very difficult.  Start with
+a keymap file that is similar to the language you want to use.  Copy it to the
+"keymap" directory in your runtime directory.  For example, for Unix, you
+would use the directory "~/.vim/keymap".
+   The name of the keymap file must look like this:
+
+	keymap/{name}.vim ~
+or
+	keymap/{name}_{encoding}.vim ~
+
+{name} is the name of the keymap.  Chose a name that is obvious, but different
+from existing keymaps (unless you want to replace an existing keymap file).
+{name} cannot contain an underscore.  Optionally, add the encoding used after
+an underscore.  Examples:
+
+	keymap/hebrew.vim ~
+	keymap/hebrew_utf-8.vim ~
+
+The contents of the file should be self-explanatory.  Look at a few of the
+keymaps that are distributed with Vim.  For the details, see |mbyte-keymap|.
+
+
+LAST RESORT
+
+If all other methods fail, you can enter any character with CTRL-V:
+
+	encoding   type			range ~
+	8-bit	   CTRL-V 123		decimal 0-255
+	8-bit	   CTRL-V x a1		hexadecimal 00-ff
+	16-bit     CTRL-V u 013b	hexadecimal 0000-ffff
+	31-bit	   CTRL-V U 001303a4	hexadecimal 00000000-7fffffff
+
+Don't type the spaces.  See |i_CTRL-V_digit| for the details.
+
+==============================================================================
+
+Next chapter: |usr_90.txt|  Installing Vim
+
+Copyright: see |manual-copyright|  vim:tw=78:ts=8:ft=help:norl:
--- /dev/null
+++ b/lib/vimfiles/doc/usr_90.txt
@@ -1,0 +1,498 @@
+*usr_90.txt*	For Vim version 7.1.  Last change: 2006 Apr 24
+
+		     VIM USER MANUAL - by Bram Moolenaar
+
+				Installing Vim
+
+								*install*
+Before you can use Vim you have to install it.  Depending on your system it's
+simple or easy.  This chapter gives a few hints and also explains how
+upgrading to a new version is done.
+
+|90.1|	Unix
+|90.2|	MS-Windows
+|90.3|	Upgrading
+|90.4|	Common installation issues
+|90.5|	Uninstalling Vim
+
+ Previous chapter: |usr_45.txt|  Select your language
+Table of contents: |usr_toc.txt|
+
+==============================================================================
+*90.1*	Unix
+
+First you have to decide if you are going to install Vim system-wide or for a
+single user.  The installation is almost the same, but the directory where Vim
+is installed in differs.
+   For a system-wide installation the base directory "/usr/local" is often
+used.  But this may be different for your system.  Try finding out where other
+packages are installed.
+   When installing for a single user, you can use your home directory as the
+base.  The files will be placed in subdirectories like "bin" and "shared/vim".
+
+
+FROM A PACKAGE
+
+You can get precompiled binaries for many different UNIX systems.  There is a
+long list with links on this page:
+
+	http://www.vim.org/binaries.html ~
+
+Volunteers maintain the binaries, so they are often out of date.  It is a
+good idea to compile your own UNIX version from the source.  Also, creating
+the editor from the source allows you to control which features are compiled.
+This does require a compiler though.
+
+If you have a Linux distribution, the "vi" program is probably a minimal
+version of Vim.  It doesn't do syntax highlighting, for example.  Try finding
+another Vim package in your distribution, or search on the web site.
+
+
+FROM SOURCES
+
+To compile and install Vim, you will need the following:
+
+	-  A C compiler (GCC preferred)
+	-  The GZIP program (you can get it from www.gnu.org)
+	-  The Vim source and runtime archives
+
+To get the Vim archives, look in this file for a mirror near you, this should
+provide the fastest download:
+
+	ftp://ftp.vim.org/pub/vim/MIRRORS ~
+
+Or use the home site ftp.vim.org, if you think it's fast enough.  Go to the
+"unix" directory and you'll find a list of files there.  The version number is
+embedded in the file name.  You will want to get the most recent version.
+   You can get the files for Unix in two ways: One big archive that contains
+everything, or four smaller ones that each fit on a floppy disk.  For version
+6.1 the single big one is called:
+
+	vim-6.1.tar.bz2 ~
+
+You need the bzip2 program to uncompress it.  If you don't have it, get the
+four smaller files, which can be uncompressed with gzip.  For Vim 6.1 they are
+called:
+
+	vim-6.1-src1.tar.gz ~
+	vim-6.1-src2.tar.gz ~
+	vim-6.1-rt1.tar.gz ~
+	vim-6.1-rt2.tar.gz ~
+
+
+COMPILING
+
+First create a top directory to work in, for example: >
+
+	mkdir ~/vim
+	cd ~/vim
+
+Then unpack the archives there.  If you have the one big archive, you unpack
+it like this: >
+
+	bzip2 -d -c path/vim-6.1.tar.bz2 | tar xf -
+
+Change "path" to where you have downloaded the file. >
+
+	gzip -d -c path/vim-6.1-src1.tar.gz | tar xf -
+	gzip -d -c path/vim-6.1-src2.tar.gz | tar xf -
+	gzip -d -c path/vim-6.1-rt1.tar.gz | tar xf -
+	gzip -d -c path/vim-6.1-rt2.tar.gz | tar xf -
+
+If you are satisfied with getting the default features, and your environment
+is setup properly, you should be able to compile Vim with just this: >
+
+	cd vim61/src
+	make
+
+The make program will run configure and compile everything.  Further on we
+will explain how to compile with different features.
+   If there are errors while compiling, carefully look at the error messages.
+There should be a hint about what went wrong.  Hopefully you will be able to
+correct it.  You might have to disable some features to make Vim compile.
+Look in the Makefile for specific hints for your system.
+
+
+TESTING
+
+Now you can check if compiling worked OK: >
+
+	make test
+
+This will run a sequence of test scripts to verify that Vim works as expected.
+Vim will be started many times and all kinds of text and messages flash by.
+If it is alright you will finally see:
+
+	test results: ~
+	ALL DONE ~
+
+If there are one or two messages about failed tests, Vim might still work, but
+not perfectly.  If you see a lot of error messages or Vim doesn't finish until
+the end, there must be something wrong.  Either try to find out yourself, or
+find someone who can solve it.  You could look in the |maillist-archive| for a
+solution.  If everything else fails, you could ask in the vim |maillist| if
+someone can help you.
+
+
+INSTALLING
+							*install-home*
+If you want to install in your home directory, edit the Makefile and search
+for a line:
+
+	#prefix = $(HOME) ~
+
+Remove the # at the start of the line.
+   When installing for the whole system, Vim has most likely already selected
+a good installation directory for you.  You can also specify one, see below.
+You need to become root for the following.
+
+To install Vim do: >
+
+	make install
+
+That should move all the relevant files to the right place.  Now you can try
+running vim to verify that it works.  Use two simple tests to check if Vim can
+find its runtime files: >
+
+	:help
+	:syntax enable
+
+If this doesn't work, use this command to check where Vim is looking for the
+runtime files: >
+
+	:echo $VIMRUNTIME
+
+You can also start Vim with the "-V" argument to see what happens during
+startup: >
+
+	vim -V
+
+Don't forget that the user manual assumes you Vim in a certain way.  After
+installing Vim, follow the instructions at |not-compatible| to make Vim work
+as assumed in this manual.
+
+
+SELECTING FEATURES
+
+Vim has many ways to select features.  One of the simple ways is to edit the
+Makefile.  There are many directions and examples.  Often you can enable or
+disable a feature by uncommenting a line.
+   An alternative is to run "configure" separately.  This allows you to
+specify configuration options manually.  The disadvantage is that you have to
+figure out what exactly to type.
+   Some of the most interesting configure arguments follow.  These can also be
+enabled from the Makefile.
+
+	--prefix={directory}		Top directory where to install Vim.
+
+	--with-features=tiny		Compile with many features disabled.
+	--with-features=small		Compile with some features disabled.
+	--with-features=big		Compile with more features enabled.
+	--with-features=huge		Compile with most features enabled.
+					See |+feature-list| for which feature
+					is enabled in which case.
+
+	--enable-perlinterp		Enable the Perl interface.  There are
+					similar arguments for ruby, python and
+					tcl.
+
+	--disable-gui			Do not compile the GUI interface.
+	--without-x			Do not compile X-windows features.
+					When both of these are used, Vim will
+					not connect to the X server, which
+					makes startup faster.
+
+To see the whole list use: >
+
+	./configure --help
+
+You can find a bit of explanation for each feature, and links for more
+information here: |feature-list|.
+   For the adventurous, edit the file "feature.h".  You can also change the
+source code yourself!
+
+==============================================================================
+*90.2*	MS-Windows
+
+There are two ways to install the Vim program for Microsoft Windows.  You can
+uncompress several archives, or use a self-installing big archive.  Most users
+with fairly recent computers will prefer the second method.  For the first
+one, you will need:
+
+	- An archive with binaries for Vim.
+	- The Vim runtime archive.
+	- A program to unpack the zip files.
+
+To get the Vim archives, look in this file for a mirror near you, this should
+provide the fastest download:
+
+	ftp://ftp.vim.org/pub/vim/MIRRORS ~
+
+Or use the home site ftp.vim.org, if you think it's fast enough.  Go to the
+"pc" directory and you'll find a list of files there.  The version number is
+embedded in the file name.  You will want to get the most recent version.
+We will use "61" here, which is version 6.1.
+
+	gvim61.exe		The self-installing archive.
+
+This is all you need for the second method.  Just launch the executable, and
+follow the prompts.
+
+For the first method you must chose one of the binary archives.  These are
+available:
+
+	gvim61.zip		The normal MS-Windows GUI version.
+	gvim61ole.zip		The MS-Windows GUI version with OLE support.
+				Uses more memory, supports interfacing with
+				other OLE applications.
+	vim61w32.zip		32 bit MS-Windows console version.  For use in
+				a Win NT/2000/XP console.  Does not work well
+				on Win 95/98.
+	vim61d32.zip		32 bit MS-DOS version.  For use in the
+				Win 95/98 console window.
+	vim61d16.zip		16 bit MS-DOS version.  Only for old systems.
+				Does not support long filenames.
+
+You only need one of them.  Although you could install both a GUI and a
+console version.  You always need to get the archive with runtime files.
+
+	vim61rt.zip		The runtime files.
+
+Use your un-zip program to unpack the files.  For example, using the "unzip"
+program: >
+
+	cd c:\
+	unzip path\gvim61.zip
+	unzip path\vim61rt.zip
+
+This will unpack the files in the directory "c:\vim\vim61".  If you already
+have a "vim" directory somewhere, you will want to move to the directory just
+above it.
+   Now change to the "vim\vim61" directory and run the install program: >
+
+	install
+
+Carefully look through the messages and select the options you want to use.
+If you finally select "do it" the install program will carry out the actions
+you selected.
+   The install program doesn't move the runtime files.  They remain where you
+unpacked them.
+
+In case you are not satisfied with the features included in the supplied
+binaries, you could try compiling Vim yourself.  Get the source archive from
+the same location as where the binaries are.  You need a compiler for which a
+makefile exists.  Microsoft Visual C works, but is expensive.  The Free
+Borland command-line compiler 5.5 can be used, as well as the free MingW and
+Cygwin compilers.  Check the file src/INSTALLpc.txt for hints.
+
+==============================================================================
+*90.3*	Upgrading
+
+If you are running one version of Vim and want to install another, here is
+what to do.
+
+
+UNIX
+
+When you type "make install" the runtime files will be copied to a directory
+which is specific for this version.  Thus they will not overwrite a previous
+version.  This makes it possible to use two or more versions next to
+each other.
+   The executable "vim" will overwrite an older version.  If you don't care
+about keeping the old version, running "make install" will work fine.  You can
+delete the old runtime files manually.  Just delete the directory with the
+version number in it and all files below it.  Example: >
+
+	rm -rf /usr/local/share/vim/vim58
+
+There are normally no changed files below this directory.  If you did change
+the "filetype.vim" file, for example, you better merge the changes into the
+new version before deleting it.
+
+If you are careful and want to try out the new version for a while before
+switching to it, install the new version under another name.  You need to
+specify a configure argument.  For example: >
+
+	./configure --with-vim-name=vim6
+
+Before running "make install", you could use "make -n install" to check that
+no valuable existing files are overwritten.
+   When you finally decide to switch to the new version, all you need to do is
+to rename the binary to "vim".  For example: >
+
+	mv /usr/local/bin/vim6 /usr/local/bin/vim
+
+
+MS-WINDOWS
+
+Upgrading is mostly equal to installing a new version.  Just unpack the files
+in the same place as the previous version.  A new directory will be created,
+e.g., "vim61", for the files of the new version.  Your runtime files, vimrc
+file, viminfo, etc. will be left alone.
+   If you want to run the new version next to the old one, you will have to do
+some handwork.  Don't run the install program, it will overwrite a few files
+of the old version.  Execute the new binaries by specifying the full path.
+The program should be able to automatically find the runtime files for the
+right version.  However, this won't work if you set the $VIMRUNTIME variable
+somewhere.
+   If you are satisfied with the upgrade, you can delete the files of the
+previous version.  See |90.5|.
+
+==============================================================================
+*90.4*	Common installation issues
+
+This section describes some of the common problems that occur when installing
+Vim and suggests some solutions.  It also contains answers to many
+installation questions.
+
+
+Q: I Do Not Have Root Privileges.  How Do I Install Vim? (Unix)
+
+Use the following configuration command to install Vim in a directory called
+$HOME/vim: >
+
+	./configure --prefix=$HOME
+
+This gives you a personal copy of Vim.  You need to put $HOME/bin in your
+path to execute the editor.  Also see |install-home|.
+
+
+Q: The Colors Are Not Right on My Screen. (Unix)
+
+Check your terminal settings by using the following command in a shell: >
+
+	echo $TERM
+
+If the terminal type listed is not correct, fix it.  For more hints, see
+|06.2|.  Another solution is to always use the GUI version of Vim, called
+gvim.  This avoids the need for a correct terminal setup.
+
+
+Q: My Backspace And Delete Keys Don't Work Right
+
+The definition of what key sends what code is very unclear for backspace <BS>
+and Delete <Del> keys.  First of all, check your $TERM setting.  If there is
+nothing wrong with it, try this: >
+
+	:set t_kb=^V<BS>
+	:set t_kD=^V<Del>
+
+In the first line you need to press CTRL-V and then hit the backspace key.
+In the second line you need to press CTRL-V and then hit the Delete key.
+You can put these lines in your vimrc file, see |05.1|.  A disadvantage is
+that it won't work when you use another terminal some day.  Look here for
+alternate solutions: |:fixdel|.
+
+
+Q: I Am Using RedHat Linux.  Can I Use the Vim That Comes with the System?
+
+By default RedHat installs a minimal version of Vim.  Check your RPM packages
+for something named "Vim-enhanced-version.rpm" and install that.
+
+
+Q: How Do I Turn Syntax Coloring On?  How do I make plugins work?
+
+Use the example vimrc script.  You can find an explanation on how to use it
+here: |not-compatible|.
+
+See chapter 6 for information about syntax highlighting: |usr_06.txt|.
+
+
+Q: What Is a Good vimrc File to Use?
+
+See the www.vim.org Web site for several good examples.
+
+
+Q: Where Do I Find a Good Vim Plugin?
+
+See the Vim-online site: http://vim.sf.net.  Many users have uploaded useful
+Vim scripts and plugins there.
+
+
+Q: Where Do I Find More Tips?
+
+See the Vim-online site: http://vim.sf.net.  There is an archive with hints
+from Vim users.  You might also want to search in the |maillist-archive|.
+
+==============================================================================
+*90.5*	Uninstalling Vim
+
+In the unlikely event you want to uninstall Vim completely, this is how you do
+it.
+
+
+UNIX
+
+When you installed Vim as a package, check your package manager to find out
+how to remove the package again.
+   If you installed Vim from sources you can use this command: >
+
+	make uninstall
+
+However, if you have deleted the original files or you used an archive that
+someone supplied, you can't do this.  Do delete the files manually, here is an
+example for when "/usr/local" was used as the root: >
+
+	rm -rf /usr/local/share/vim/vim61
+	rm /usr/local/bin/eview
+	rm /usr/local/bin/evim
+	rm /usr/local/bin/ex
+	rm /usr/local/bin/gview
+	rm /usr/local/bin/gvim
+	rm /usr/local/bin/gvim
+	rm /usr/local/bin/gvimdiff
+	rm /usr/local/bin/rgview
+	rm /usr/local/bin/rgvim
+	rm /usr/local/bin/rview
+	rm /usr/local/bin/rvim
+	rm /usr/local/bin/rvim
+	rm /usr/local/bin/view
+	rm /usr/local/bin/vim
+	rm /usr/local/bin/vimdiff
+	rm /usr/local/bin/vimtutor
+	rm /usr/local/bin/xxd
+	rm /usr/local/man/man1/eview.1
+	rm /usr/local/man/man1/evim.1
+	rm /usr/local/man/man1/ex.1
+	rm /usr/local/man/man1/gview.1
+	rm /usr/local/man/man1/gvim.1
+	rm /usr/local/man/man1/gvimdiff.1
+	rm /usr/local/man/man1/rgview.1
+	rm /usr/local/man/man1/rgvim.1
+	rm /usr/local/man/man1/rview.1
+	rm /usr/local/man/man1/rvim.1
+	rm /usr/local/man/man1/view.1
+	rm /usr/local/man/man1/vim.1
+	rm /usr/local/man/man1/vimdiff.1
+	rm /usr/local/man/man1/vimtutor.1
+	rm /usr/local/man/man1/xxd.1
+
+
+MS-WINDOWS
+
+If you installed Vim with the self-installing archive you can run
+the "uninstall-gui" program located in the same directory as the other Vim
+programs, e.g. "c:\vim\vim61".  You can also launch it from the Start menu if
+installed the Vim entries there.  This will remove most of the files, menu
+entries and desktop shortcuts.  Some files may remain however, as they need a
+Windows restart before being deleted.
+   You will be given the option to remove the whole "vim" directory.  It
+probably contains your vimrc file and other runtime files that you created, so
+be careful.
+
+Else, if you installed Vim with the zip archives, the preferred way is to use
+the "uninstal" program (note the missing l at the end).  You can find it in
+the same directory as the "install" program, e.g., "c:\vim\vim61".  This
+should also work from the usual "install/remove software" page.
+   However, this only removes the registry entries for Vim.  You have to
+delete the files yourself.  Simply select the directory "vim\vim61" and delete
+it recursively.  There should be no files there that you changed, but you
+might want to check that first.
+   The "vim" directory probably contains your vimrc file and other runtime
+files that you created.  You might want to keep that.
+
+==============================================================================
+
+Table of contents: |usr_toc.txt|
+
+Copyright: see |manual-copyright|  vim:tw=78:ts=8:ft=help:norl:
--- /dev/null
+++ b/lib/vimfiles/doc/usr_toc.txt
@@ -1,0 +1,353 @@
+*usr_toc.txt*	For Vim version 7.1.  Last change: 2006 Apr 24
+
+		     VIM USER MANUAL - by Bram Moolenaar
+
+			      Table Of Contents			*user-manual*
+
+==============================================================================
+Overview ~
+
+Getting Started
+|usr_01.txt|  About the manuals
+|usr_02.txt|  The first steps in Vim
+|usr_03.txt|  Moving around
+|usr_04.txt|  Making small changes
+|usr_05.txt|  Set your settings
+|usr_06.txt|  Using syntax highlighting
+|usr_07.txt|  Editing more than one file
+|usr_08.txt|  Splitting windows
+|usr_09.txt|  Using the GUI
+|usr_10.txt|  Making big changes
+|usr_11.txt|  Recovering from a crash
+|usr_12.txt|  Clever tricks
+
+Editing Effectively
+|usr_20.txt|  Typing command-line commands quickly
+|usr_21.txt|  Go away and come back
+|usr_22.txt|  Finding the file to edit
+|usr_23.txt|  Editing other files
+|usr_24.txt|  Inserting quickly
+|usr_25.txt|  Editing formatted text
+|usr_26.txt|  Repeating
+|usr_27.txt|  Search commands and patterns
+|usr_28.txt|  Folding
+|usr_29.txt|  Moving through programs
+|usr_30.txt|  Editing programs
+|usr_31.txt|  Exploiting the GUI
+|usr_32.txt|  The undo tree
+
+Tuning Vim
+|usr_40.txt|  Make new commands
+|usr_41.txt|  Write a Vim script
+|usr_42.txt|  Add new menus
+|usr_43.txt|  Using filetypes
+|usr_44.txt|  Your own syntax highlighted
+|usr_45.txt|  Select your language
+
+Making Vim Run
+|usr_90.txt|  Installing Vim
+
+
+Reference manual
+|reference_toc|     More detailed information for all commands
+
+The user manual is available as a single, ready to print HTML and PDF file
+here:
+	http://vimdoc.sf.net
+
+==============================================================================
+Getting Started ~
+
+Read this from start to end to learn the essential commands.
+
+|usr_01.txt|  About the manuals
+		|01.1|	Two manuals
+		|01.2|	Vim installed
+		|01.3|	Using the Vim tutor
+		|01.4|	Copyright
+
+|usr_02.txt|  The first steps in Vim
+		|02.1|	Running Vim for the First Time
+		|02.2|	Inserting text
+		|02.3|	Moving around
+		|02.4|	Deleting characters
+		|02.5|	Undo and Redo
+		|02.6|	Other editing commands
+		|02.7|	Getting out
+		|02.8|	Finding help
+
+|usr_03.txt|  Moving around
+		|03.1|	Word movement
+		|03.2|	Moving to the start or end of a line
+		|03.3|	Moving to a character
+		|03.4|	Matching a paren
+		|03.5|	Moving to a specific line
+		|03.6|	Telling where you are
+		|03.7|	Scrolling around
+		|03.8|	Simple searches
+		|03.9|	Simple search patterns
+		|03.10|	Using marks
+
+|usr_04.txt|  Making small changes
+		|04.1|	Operators and motions
+		|04.2|	Changing text
+		|04.3|	Repeating a change
+		|04.4|	Visual mode
+		|04.5|	Moving text
+		|04.6|	Copying text
+		|04.7|	Using the clipboard
+		|04.8|	Text objects
+		|04.9|	Replace mode
+		|04.10|	Conclusion
+
+|usr_05.txt|  Set your settings
+		|05.1|	The vimrc file
+		|05.2|	The example vimrc file explained
+		|05.3|	Simple mappings
+		|05.4|	Adding a plugin
+		|05.5|	Adding a help file
+		|05.6|	The option window
+		|05.7|	Often used options
+
+|usr_06.txt|  Using syntax highlighting
+		|06.1|	Switching it on
+		|06.2|	No or wrong colors?
+		|06.3|	Different colors
+		|06.4|	With colors or without colors
+		|06.5|	Printing with colors
+		|06.6|	Further reading
+
+|usr_07.txt|  Editing more than one file
+		|07.1|	Edit another file
+		|07.2|	A list of files
+		|07.3|	Jumping from file to file
+		|07.4|	Backup files
+		|07.5|	Copy text between files
+		|07.6|	Viewing a file
+		|07.7|	Changing the file name
+
+|usr_08.txt|  Splitting windows
+		|08.1|	Split a window
+		|08.2|	Split a window on another file
+		|08.3|	Window size
+		|08.4|	Vertical splits
+		|08.5|	Moving windows
+		|08.6|	Commands for all windows
+		|08.7|	Viewing differences with vimdiff
+		|08.8|	Various
+
+|usr_09.txt|  Using the GUI
+		|09.1|	Parts of the GUI
+		|09.2|	Using the mouse
+		|09.3|	The clipboard
+		|09.4|	Select mode
+
+|usr_10.txt|  Making big changes
+		|10.1|	Record and playback commands
+		|10.2|	Substitution
+		|10.3|	Command ranges
+		|10.4|	The global command
+		|10.5|	Visual block mode
+		|10.6|	Reading and writing part of a file
+		|10.7|	Formatting text
+		|10.8|	Changing case
+		|10.9|	Using an external program
+
+|usr_11.txt|  Recovering from a crash
+		|11.1|	Basic recovery
+		|11.2|	Where is the swap file?
+		|11.3|	Crashed or not?
+		|11.4|	Further reading
+
+|usr_12.txt|  Clever tricks
+		|12.1|	Replace a word
+		|12.2|	Change "Last, First" to "First Last"
+		|12.3|	Sort a list
+		|12.4|	Reverse line order
+		|12.5|	Count words
+		|12.6|	Find a man page
+		|12.7|	Trim blanks
+		|12.8|	Find where a word is used
+
+==============================================================================
+Editing Effectively ~
+
+Subjects that can be read independently.
+
+|usr_20.txt|  Typing command-line commands quickly
+		|20.1|	Command line editing
+		|20.2|	Command line abbreviations
+		|20.3|	Command line completion
+		|20.4|	Command line history
+		|20.5|	Command line window
+
+|usr_21.txt|  Go away and come back
+		|21.1|	Suspend and resume
+		|21.2|	Executing shell commands
+		|21.3|	Remembering information; viminfo
+		|21.4|	Sessions
+		|21.5|	Views
+		|21.6|	Modelines
+
+|usr_22.txt|  Finding the file to edit
+		|22.1|	The file explorer
+		|22.2|	The current directory
+		|22.3|	Finding a file
+		|22.4|	The buffer list
+
+|usr_23.txt|  Editing other files
+		|23.1|	DOS, Mac and Unix files
+		|23.2|	Files on the internet
+		|23.3|	Encryption
+		|23.4|	Binary files
+		|23.5|	Compressed files
+
+|usr_24.txt|  Inserting quickly
+		|24.1|	Making corrections
+		|24.2|	Showing matches
+		|24.3|	Completion
+		|24.4|	Repeating an insert
+		|24.5|	Copying from another line
+		|24.6|	Inserting a register
+		|24.7|	Abbreviations
+		|24.8|	Entering special characters
+		|24.9|	Digraphs
+		|24.10|	Normal mode commands
+
+|usr_25.txt|  Editing formatted text
+		|25.1|	Breaking lines
+		|25.2|	Aligning text
+		|25.3|	Indents and tabs
+		|25.4|	Dealing with long lines
+		|25.5|	Editing tables
+
+|usr_26.txt|  Repeating
+		|26.1|	Repeating with Visual mode
+		|26.2|	Add and subtract
+		|26.3|	Making a change in many files
+		|26.4|	Using Vim from a shell script
+
+|usr_27.txt|  Search commands and patterns
+		|27.1|	Ignoring case
+		|27.2|	Wrapping around the file end
+		|27.3|	Offsets
+		|27.4|	Matching multiple times
+		|27.5|	Alternatives
+		|27.6|	Character ranges
+		|27.7|	Character classes
+		|27.8|	Matching a line break
+		|27.9|	Examples
+
+|usr_28.txt|  Folding
+		|28.1|	What is folding?
+		|28.2|	Manual folding
+		|28.3|	Working with folds
+		|28.4|	Saving and restoring folds
+		|28.5|	Folding by indent
+		|28.6|	Folding with markers
+		|28.7|	Folding by syntax
+		|28.8|	Folding by expression
+		|28.9|	Folding unchanged lines
+		|28.10| Which fold method to use?
+
+|usr_29.txt|  Moving through programs
+		|29.1|	Using tags
+		|29.2|	The preview window
+		|29.3|	Moving through a program
+		|29.4|	Finding global identifiers
+		|29.5|	Finding local identifiers
+
+|usr_30.txt|  Editing programs
+		|30.1|	Compiling
+		|30.2|	Indenting C files
+		|30.3|	Automatic indenting
+		|30.4|	Other indenting
+		|30.5|	Tabs and spaces
+		|30.6|	Formatting comments
+
+|usr_31.txt|  Exploiting the GUI
+		|31.1|	The file browser
+		|31.2|	Confirmation
+		|31.3|	Menu shortcuts
+		|31.4|	Vim window position and size
+		|31.5|	Various
+
+|usr_32.txt|  The undo tree
+		|32.1|	Numbering changes
+		|32.2|	Jumping around the tree
+		|32.3|	Time travelling
+
+==============================================================================
+Tuning Vim ~
+
+Make Vim work as you like it.
+
+|usr_40.txt|  Make new commands
+		|40.1|	Key mapping
+		|40.2|	Defining command-line commands
+		|40.3|	Autocommands
+
+|usr_41.txt|  Write a Vim script
+		|41.1|	Introduction
+		|41.2|	Variables
+		|41.3|	Expressions
+		|41.4|	Conditionals
+		|41.5|	Executing an expression
+		|41.6|	Using functions
+		|41.7|	Defining a function
+		|41.8|	Lists and Dictionaries
+		|41.9|	Exceptions
+		|41.10|	Various remarks
+		|41.11|	Writing a plugin
+		|41.12|	Writing a filetype plugin
+		|41.13|	Writing a compiler plugin
+		|41.14|	Writing a plugin that loads quickly
+		|41.15|	Writing library scripts
+		|41.16|	Distributing Vim scripts
+
+|usr_42.txt|  Add new menus
+		|42.1|	Introduction
+		|42.2|	Menu commands
+		|42.3|	Various
+		|42.4|	Toolbar and popup menus
+
+|usr_43.txt|  Using filetypes
+		|43.1|	Plugins for a filetype
+		|43.2|	Adding a filetype
+
+|usr_44.txt|  Your own syntax highlighted
+		|44.1|	Basic syntax commands
+		|44.2|	Keywords
+		|44.3|	Matches
+		|44.4|	Regions
+		|44.5|	Nested items
+		|44.6|	Following groups
+		|44.7|	Other arguments
+		|44.8|	Clusters
+		|44.9|	Including another syntax file
+		|44.10|	Synchronizing
+		|44.11|	Installing a syntax file
+		|44.12|	Portable syntax file layout
+
+|usr_45.txt|  Select your language
+		|45.1|	Language for Messages
+		|45.2|	Language for Menus
+		|45.3|	Using another encoding
+		|45.4|	Editing files with a different encoding
+		|45.5|	Entering language text
+
+==============================================================================
+Making Vim Run ~
+
+Before you can use Vim.
+
+|usr_90.txt|  Installing Vim
+		|90.1|	Unix
+		|90.2|	MS-Windows
+		|90.3|	Upgrading
+		|90.4|	Common installation issues
+		|90.5|	Uninstalling Vim
+
+==============================================================================
+
+Copyright: see |manual-copyright|  vim:tw=78:ts=8:ft=help:norl:
--- /dev/null
+++ b/lib/vimfiles/doc/various.txt
@@ -1,0 +1,850 @@
+*various.txt*   For Vim version 7.1.  Last change: 2007 Jan 14
+
+
+		  VIM REFERENCE MANUAL    by Bram Moolenaar
+
+
+Various commands					*various*
+
+1. Various commands		|various-cmds|
+2. Online help			|online-help|
+3. Using Vim like less or more	|less|
+
+==============================================================================
+1. Various commands					*various-cmds*
+
+							*CTRL-L*
+CTRL-L			Clear and redraw the screen.  The redraw may happen
+			later, after processing typeahead.
+
+							*:redr* *:redraw*
+:redr[aw][!]		Redraw the screen right now.  When ! is included it is
+			cleared first.
+			Useful to update the screen halfway executing a script
+			or function.  Also when halfway a mapping and
+			'lazyredraw' is set.
+
+						*:redraws* *:redrawstatus*
+:redraws[tatus][!]	Redraw the status line of the current window.  When !
+			is included all status lines are redrawn.
+			Useful to update the status line(s) when 'statusline'
+			includes an item that doesn't cause automatic
+			updating.
+
+							*N<Del>*
+<Del>			When entering a number: Remove the last digit.
+			Note: if you like to use <BS> for this, add this
+			mapping to your .vimrc: >
+				:map CTRL-V <BS>   CTRL-V <Del>
+<			See |:fixdel| if your <Del> key does not do what you
+			want.
+
+:as[cii]	or					*ga* *:as* *:ascii*
+ga			Print the ascii value of the character under the
+			cursor in decimal, hexadecimal and octal.  For
+			example, when the cursor is on a 'R':
+				<R>  82,  Hex 52,  Octal 122 ~
+			When the character is a non-standard ASCII character,
+			but printable according to the 'isprint' option, the
+			non-printable version is also given.  When the
+			character is larger than 127, the <M-x> form is also
+			printed.  For example:
+				<~A>  <M-^A>  129,  Hex 81,  Octal 201 ~
+				<p>  <|~>  <M-~>  254,  Hex fe,  Octal 376 ~
+			(where <p> is a special character)
+			The <Nul> character in a file is stored internally as
+			<NL>, but it will be shown as:
+				<^@>  0,  Hex 00,  Octal 000 ~
+			If the character has composing characters these are
+			also shown.  The value of 'maxcombine' doesn't matter.
+			Mnemonic: Get Ascii value.  {not in Vi}
+
+							*g8*
+g8			Print the hex values of the bytes used in the
+			character under the cursor, assuming it is in |UTF-8|
+			encoding.  This also shows composing characters.  The
+			value of 'maxcombine' doesn't matter.
+			Example of a character with two composing characters:
+				e0 b8 81 + e0 b8 b9 + e0 b9 89 ~
+			{not in Vi} {only when compiled with the |+multi_byte|
+			feature}
+
+							*8g8*
+8g8			Find an illegal UTF-8 byte sequence at or after the
+			cursor.  This works in two situations:
+			1. when 'encoding' is any 8-bit encoding
+			2. when 'encoding' is "utf-8" and 'fileencoding' is
+			   any 8-bit encoding
+			Thus it can be used when editing a file that was
+			supposed to be UTF-8 but was read as if it is an 8-bit
+			encoding because it contains illegal bytes.
+			Does not wrap around the end of the file.
+			Note that when the cursor is on an illegal byte or the
+			cursor is halfway a multi-byte character the command
+			won't move the cursor.
+			{not in Vi} {only when compiled with the |+multi_byte|
+			feature}
+
+						*:p* *:pr* *:print* *E749*
+:[range]p[rint] [flags]
+			Print [range] lines (default current line).
+			Note: If you are looking for a way to print your text
+			on paper see |:hardcopy|.  In the GUI you can use the
+			File.Print menu entry.
+			See |ex-flags| for [flags].
+
+:[range]p[rint] {count} [flags]
+			Print {count} lines, starting with [range] (default
+			current line |cmdline-ranges|).
+			See |ex-flags| for [flags].
+
+							*:P* *:Print*
+:[range]P[rint] [count] [flags]
+			Just as ":print".  Was apparently added to Vi for
+			people that keep the shift key pressed too long...
+			See |ex-flags| for [flags].
+
+							*:l* *:list*
+:[range]l[ist] [count] [flags]
+			Same as :print, but display unprintable characters
+			with '^' and put $ after the line.
+			See |ex-flags| for [flags].
+
+							*:nu* *:number*
+:[range]nu[mber] [count] [flags]
+			Same as :print, but precede each line with its line
+			number.  (See also 'highlight' and 'numberwidth'
+			option).
+			See |ex-flags| for [flags].
+
+							*:#*
+:[range]# [count] [flags]
+			synonym for :number.
+
+							*:#!*
+:#!{anything}		Ignored, so that you can start a Vim script with: >
+				#!/usr/bin/env vim -S
+				echo "this is a Vim script"
+				quit
+<
+							*:z* *E144*
+:{range}z[+-^.=]{count}	Display several lines of text surrounding the line
+			specified with {range}, or around the current line
+			if there is no {range}.  If there is a {count}, that's
+			how many lines you'll see; if there is only one window
+			then the 'window' option is used, otherwise the
+			current window size is used.
+
+			:z can be used either alone or followed by any of
+			several punctuation marks.  These have the following
+			effect:
+
+			mark   first line    last line      new location   ~
+			----   ----------    ---------      ------------
+			+      current line  1 scr forward  1 scr forward
+			-      1 scr back    current line   current line
+			^      2 scr back    1 scr back     1 scr back
+			.      1/2 scr back  1/2 scr fwd    1/2 scr fwd
+			=      1/2 scr back  1/2 scr fwd    current line
+
+			Specifying no mark at all is the same as "+".
+			If the mark is "=", a line of dashes is printed
+			around the current line.
+
+:{range}z#[+-^.=]{count}				*:z#*
+			Like ":z", but number the lines.
+			{not in all versions of Vi, not with these arguments}
+
+							*:=*
+:= [flags]		Print the last line number.
+			See |ex-flags| for [flags].
+
+:{range}= [flags]	Prints the last line number in {range}.  For example,
+			this prints the current line number: >
+				:.=
+<			See |ex-flags| for [flags].
+
+:norm[al][!] {commands}					*:norm* *:normal*
+			Execute Normal mode commands {commands}.  This makes
+			it possible to execute Normal mode commands typed on
+			the command-line.  {commands} is executed like it is
+			typed.  For undo all commands are undone together.
+			Execution stops when an error is encountered.
+			If the [!] is given, mappings will not be used.
+			{commands} should be a complete command.  If
+			{commands} does not finish a command, the last one
+			will be aborted as if <Esc> or <C-C> was typed.
+			The display isn't updated while ":normal" is busy.
+			This implies that an insert command must be completed
+			(to start Insert mode, see |:startinsert|).  A ":"
+			command must be completed as well.  And you can't use
+			"Q" or "gQ" to start Ex mode.
+			{commands} cannot start with a space.  Put a 1 (one)
+			before it, 1 space is one space.
+			The 'insertmode' option is ignored for {commands}.
+			This command cannot be followed by another command,
+			since any '|' is considered part of the command.
+			This command can be used recursively, but the depth is
+			limited by 'maxmapdepth'.
+			When this command is called from a non-remappable
+			mapping |:noremap|, the argument can be mapped anyway.
+			An alternative is to use |:execute|, which uses an
+			expression as argument.  This allows the use of
+			printable characters.  Example: >
+				:exe "normal \<c-w>\<c-w>"
+<			{not in Vi, of course}
+			{not available when the |+ex_extra| feature was
+			disabled at compile time}
+
+:{range}norm[al][!] {commands}				*:normal-range*
+			Execute Normal mode commands {commands} for each line
+			in the {range}.  Before executing the {commands}, the
+			cursor is positioned in the first column of the range,
+			for each line.  Otherwise it's the same as the
+			":normal" command without a range.
+			{not in Vi}
+			Not available when |+ex_extra| feature was disabled at
+			compile time.
+
+							*:sh* *:shell* *E371*
+:sh[ell]		This command starts a shell.  When the shell exits
+			(after the "exit" command) you return to Vim.  The
+			name for the shell command comes from 'shell' option.
+							*E360*
+			Note: This doesn't work when Vim on the Amiga was
+			started in QuickFix mode from a compiler, because the
+			compiler will have set stdin to a non-interactive
+			mode.
+
+							*:!cmd* *:!* *E34*
+:!{cmd}			Execute {cmd} with the shell.  See also the 'shell'
+			and 'shelltype' option.
+			Any '!' in {cmd} is replaced with the previous
+			external command (see also 'cpoptions').  But not when
+			there is a backslash before the '!', then that
+			backslash is removed.  Example: ":!ls" followed by
+			":!echo ! \! \\!" executes "echo ls ! \!".
+			After the command has been executed, the timestamp of
+			the current file is checked |timestamp|.
+			There cannot be a '|' in {cmd}, see |:bar|.
+			A newline character ends {cmd}, what follows is
+			interpreted as a following ":" command.  However, if
+			there is a backslash before the newline it is removed
+			and {cmd} continues.  It doesn't matter how many
+			backslashes are before the newline, only one is
+			removed.
+			On Unix the command normally runs in a non-interactive
+			shell.  If you want an interactive shell to be used
+			(to use aliases) set 'shellcmdflag' to "-ic".
+			For Win32 also see |:!start|.
+			Vim redraws the screen after the command is finished,
+			because it may have printed any text.  This requires a
+			hit-enter prompt, so that you can read any messages.
+			To avoid this use: >
+				:silent !{cmd}
+<			The screen is not redrawn then, thus you have to use
+			CTRL-L or ":redraw!" if the command did display
+			something.
+			Also see |shell-window|.
+
+							*:!!*
+:!!			Repeat last ":!{cmd}".
+
+							*:ve* *:version*
+:ve[rsion]		Print the version number of the editor.  If the
+			compiler used understands "__DATE__" the compilation
+			date is mentioned.  Otherwise a fixed release-date is
+			shown.
+			The following lines contain information about which
+			features were enabled when Vim was compiled.  When
+			there is a preceding '+', the feature is included,
+			when there is a '-' it is excluded.  To change this,
+			you have to edit feature.h and recompile Vim.
+			To check for this in an expression, see |has()|.
+			Here is an overview of the features.
+			The first column shows the smallest version in which
+			they are included:
+			   T	tiny
+			   S	small
+			   N	normal
+			   B	big
+			   H	huge
+			   m	manually enabled or depends on other features
+			 (none) system dependent
+			Thus if a feature is marked with "N", it is included
+			in the normal, big and huge versions of Vim.
+
+							*+feature-list*
+   *+ARP*		Amiga only: ARP support included
+B  *+arabic*		|Arabic| language support
+N  *+autocmd*		|:autocmd|, automatic commands
+m  *+balloon_eval*	|balloon-eval| support. Included when compiling with
+			supported GUI (Motif, GTK, GUI) and either
+			Netbeans/Sun Workshop integration or |+eval| feature.
+N  *+browse*		|:browse| command
+N  *+builtin_terms*	some terminals builtin |builtin-terms|
+B  *++builtin_terms*	maximal terminals builtin |builtin-terms|
+N  *+byte_offset*	support for 'o' flag in 'statusline' option, "go"
+			and ":goto" commands.
+N  *+cindent*		|'cindent'|, C indenting
+N  *+clientserver*	Unix and Win32: Remote invocation |clientserver|
+   *+clipboard*		|clipboard| support
+N  *+cmdline_compl*	command line completion |cmdline-completion|
+N  *+cmdline_hist*	command line history |cmdline-history|
+N  *+cmdline_info*	|'showcmd'| and |'ruler'|
+N  *+comments*		|'comments'| support
+N  *+cryptv*		encryption support |encryption|
+B  *+cscope*		|cscope| support
+m  *+cursorshape*	|termcap-cursor-shape| support
+m  *+debug*		Compiled for debugging.
+N  *+dialog_gui*	Support for |:confirm| with GUI dialog.
+N  *+dialog_con*	Support for |:confirm| with console dialog.
+N  *+dialog_con_gui*	Support for |:confirm| with GUI and console dialog.
+N  *+diff*		|vimdiff| and 'diff'
+N  *+digraphs*		|digraphs| *E196*
+   *+dnd*		Support for DnD into the "~ register |quote_~|.
+B  *+emacs_tags*	|emacs-tags| files
+N  *+eval*		expression evaluation |eval.txt|
+N  *+ex_extra*		Vim's extra Ex commands: |:center|, |:left|,
+			|:normal|, |:retab| and |:right|
+N  *+extra_search*	|'hlsearch'| and |'incsearch'| options.
+B  *+farsi*		|farsi| language
+N  *+file_in_path*	|gf|, |CTRL-W_f| and |<cfile>|
+N  *+find_in_path*	include file searches: |[I|, |:isearch|,
+			|CTRL-W_CTRL-I|, |:checkpath|, etc.
+N  *+folding*		|folding|
+   *+footer*		|gui-footer|
+   *+fork*		Unix only: |fork| shell commands
+N  *+gettext*		message translations |multi-lang|
+   *+GUI_Athena*	Unix only: Athena |GUI|
+   *+GUI_neXtaw*	Unix only: neXtaw |GUI|
+   *+GUI_GTK*		Unix only: GTK+ |GUI|
+   *+GUI_Motif*		Unix only: Motif |GUI|
+   *+GUI_Photon*	QNX only:  Photon |GUI|
+m  *+hangul_input*	Hangul input support |hangul|
+   *+iconv*		Compiled with the |iconv()| function
+   *+iconv/dyn*		Likewise |iconv-dynamic| |/dyn|
+N  *+insert_expand*	|insert_expand| Insert mode completion
+N  *+jumplist*		|jumplist|
+B  *+keymap*		|'keymap'|
+B  *+langmap*		|'langmap'|
+N  *+libcall*		|libcall()|
+N  *+linebreak*		|'linebreak'|, |'breakat'| and |'showbreak'|
+N  *+lispindent*	|'lisp'|
+N  *+listcmds*		Vim commands for the list of buffers |buffer-hidden|
+			and argument list |:argdelete|
+N  *+localmap*		Support for mappings local to a buffer |:map-local|
+N  *+menu*		|:menu|
+N  *+mksession*		|:mksession|
+N  *+modify_fname*	|filename-modifiers|
+N  *+mouse*		Mouse handling |mouse-using|
+N  *+mouseshape*	|'mouseshape'|
+B  *+mouse_dec*		Unix only: Dec terminal mouse handling |dec-mouse|
+N  *+mouse_gpm*		Unix only: Linux console mouse handling |gpm-mouse|
+B  *+mouse_netterm*	Unix only: netterm mouse handling |netterm-mouse|
+N  *+mouse_pterm*	QNX only: pterm mouse handling |qnx-terminal|
+N  *+mouse_xterm*	Unix only: xterm mouse handling |xterm-mouse|
+B  *+multi_byte*	Korean and other languages |multibyte|
+   *+multi_byte_ime*	Win32 input method for multibyte chars |multibyte-ime|
+N  *+multi_lang*	non-English language support |multi-lang|
+m  *+mzscheme*		Mzscheme interface |mzscheme|
+m  *+mzscheme/dyn*	Mzscheme interface |mzscheme-dynamic| |/dyn|
+m  *+netbeans_intg*	|netbeans|
+m  *+ole*		Win32 GUI only: |ole-interface|
+   *+osfiletype*	Support for the 'osfiletype' option and filetype
+			checking in automatic commands.  |autocmd-osfiletypes|
+N  *+path_extra*	Up/downwards search in 'path' and 'tags'
+m  *+perl*		Perl interface |perl|
+m  *+perl/dyn*		Perl interface |perl-dynamic| |/dyn|
+   *+postscript*	|:hardcopy| writes a PostScript file
+N  *+printer*		|:hardcopy| command
+H  *+profile*		|:profile| command
+m  *+python*		Python interface |python|
+m  *+python/dyn*	Python interface |python-dynamic| |/dyn|
+N  *+quickfix*		|:make| and |quickfix| commands
+N  *+reltime*		|reltime()| function
+B  *+rightleft*		Right to left typing |'rightleft'|
+m  *+ruby*		Ruby interface |ruby|
+m  *+ruby/dyn*		Ruby interface |ruby-dynamic| |/dyn|
+N  *+scrollbind*	|'scrollbind'|
+B  *+signs*		|:sign|
+N  *+smartindent*	|'smartindent'|
+m  *+sniff*		SniFF interface |sniff|
+N  *+statusline*	Options 'statusline', 'rulerformat' and special
+			formats of 'titlestring' and 'iconstring'
+m  *+sun_workshop*	|workshop|
+N  *+syntax*		Syntax highlighting |syntax|
+   *+system()*		Unix only: opposite of |+fork|
+N  *+tag_binary*	binary searching in tags file |tag-binary-search|
+N  *+tag_old_static*	old method for static tags |tag-old-static|
+m  *+tag_any_white*	any white space allowed in tags file |tag-any-white|
+m  *+tcl*		Tcl interface |tcl|
+m  *+tcl/dyn*		Tcl interface |tcl-dynamic| |/dyn|
+   *+terminfo*		uses |terminfo| instead of termcap
+N  *+termresponse*	support for |t_RV| and |v:termresponse|
+N  *+textobjects*	|text-objects| selection
+   *+tgetent*		non-Unix only: able to use external termcap
+N  *+title*		Setting the window 'title' and 'icon'
+N  *+toolbar*		|gui-toolbar|
+N  *+user_commands*	User-defined commands. |user-commands|
+N  *+viminfo*		|'viminfo'|
+N  *+vertsplit*		Vertically split windows |:vsplit|
+N  *+virtualedit*	|'virtualedit'|
+S  *+visual*		Visual mode |Visual-mode|
+N  *+visualextra*	extra Visual mode commands |blockwise-operators|
+N  *+vreplace*		|gR| and |gr|
+N  *+wildignore*	|'wildignore'|
+N  *+wildmenu*		|'wildmenu'|
+S  *+windows*		more than one window
+m  *+writebackup*	|'writebackup'| is default on
+m  *+xim*		X input method |xim|
+   *+xfontset*		X fontset support |xfontset|
+   *+xsmp*		XSMP (X session management) support
+   *+xsmp_interact*	interactive XSMP (X session management) support
+N  *+xterm_clipboard*	Unix only: xterm clipboard handling
+m  *+xterm_save*	save and restore xterm screen |xterm-screens|
+N  *+X11*		Unix only: can restore window title |X11|
+
+							*/dyn* *E370* *E448*
+			To some of the features "/dyn" is added when the
+			feature is only available when the related library can
+			be dynamically loaded.
+
+:ve[rsion] {nr}		Is now ignored.  This was previously used to check the
+			version number of a .vimrc file.  It was removed,
+			because you can now use the ":if" command for
+			version-dependent behavior.  {not in Vi}
+
+							*:redi* *:redir*
+:redi[r][!] > {file}	Redirect messages to file {file}.  The messages which
+			are the output of commands are written to that file,
+			until redirection ends.  The messages are also still
+			shown on the screen.  When [!] is included, an
+			existing file is overwritten.  When [!] is omitted,
+			and {file} exists, this command fails.
+			Only one ":redir" can be active at a time.  Calls to
+			":redir" will close any active redirection before
+			starting redirection to the new target.
+			To stop the messages and commands from being echoed to
+			the screen, put the commands in a function and call it
+			with ":silent call Function()".
+			An alternative is to use the 'verbosefile' option,
+			this can be used in combination with ":redir".
+			{not in Vi}
+
+:redi[r] >> {file}	Redirect messages to file {file}.  Append if {file}
+			already exists.  {not in Vi}
+
+:redi[r] @{a-zA-Z}>	Redirect messages to register {a-z}.  Append to the
+			contents of the register if its name is given
+			uppercase {A-Z}.  For backward compatibility, the ">"
+			after the register name can be omitted. {not in Vi}
+:redi[r] @{a-z}>>	Append messages to register {a-z}. {not in Vi}
+
+:redi[r] @*>		
+:redi[r] @+>		Redirect messages to the selection or clipboard. For
+			backward compatibility, the ">" after the register
+			name can be omitted. See |quotestar| and |quoteplus|.
+			{not in Vi}
+:redi[r] @*>>		
+:redi[r] @+>>		Append messages to the selection or clipboard.
+			{not in Vi}
+
+:redi[r] @">		Redirect messages to the unnamed register. For
+			backward compatibility, the ">" after the register
+			name can be omitted. {not in Vi}
+:redi[r] @">>		Append messages to the unnamed register. {not in Vi}
+
+:redi[r] => {var}	Redirect messages to a variable.  If the variable
+			doesn't exist, then it is created.  If the variable
+			exists, then it is initialized to an empty string.
+			The variable will remain empty until redirection ends.
+			Only string variables can be used.  After the
+			redirection starts, if the variable is removed or
+			locked or the variable type is changed, then further
+			command output messages will cause errors. {not in Vi}
+
+:redi[r] =>> {var}	Append messages to an existing variable.  Only string
+			variables can be used. {not in Vi}
+
+:redi[r] END		End redirecting messages.  {not in Vi}
+
+						*:sil* *:silent*
+:sil[ent][!] {command}	Execute {command} silently.  Normal messages will not
+			be given or added to the message history.
+			When [!] is added, error messages will also be
+			skipped, and commands and mappings will not be aborted
+			when an error is detected.  |v:errmsg| is still set.
+			When [!] is not used, an error message will cause
+			further messages to be displayed normally.
+			Redirection, started with |:redir|, will continue as
+			usual, although there might be small differences.
+			This will allow redirecting the output of a command
+			without seeing it on the screen.  Example: >
+			    :redir >/tmp/foobar
+			    :silent g/Aap/p
+			    :redir END
+<			To execute a Normal mode command silently, use the
+			|:normal| command.  For example, to search for a
+			string without messages: >
+			    :silent exe "normal /path\<CR>"
+<			":silent!" is useful to execute a command that may
+			fail, but the failure is to be ignored.  Example: >
+			    :let v:errmsg = ""
+			    :silent! /^begin
+			    :if v:errmsg != ""
+			    : ... pattern was not found
+<			":silent" will also avoid the hit-enter prompt.  When
+			using this for an external command, this may cause the
+			screen to be messed up.  Use |CTRL-L| to clean it up
+			then.
+			":silent menu ..." defines a menu that will not echo a
+			Command-line command.  The command will still produce
+			messages though.  Use ":silent" in the command itself
+			to avoid that: ":silent menu .... :silent command".
+
+						*:verb* *:verbose*
+:[count]verb[ose] {command}
+			Execute {command} with 'verbose' set to [count].  If
+			[count] is omitted one is used. ":0verbose" can be
+			used to set 'verbose' to zero.
+			The additional use of ":silent" makes messages
+			generated but not displayed.
+			The combination of ":silent" and ":verbose" can be
+			used to generate messages and check them with
+			|v:statusmsg| and friends.  For example: >
+				:let v:statusmsg = ""
+				:silent verbose runtime foobar.vim
+				:if v:statusmsg != ""
+				:  " foobar.vim could not be found
+				:endif
+<			When concatenating another command, the ":verbose"
+			only applies to the first one: >
+				:4verbose set verbose | set verbose
+<				  verbose=4 ~
+				  verbose=0 ~
+			For logging verbose messages in a file use the
+			'verbosefile' option.
+
+							*:verbose-cmd*
+When 'verbose' is non-zero, listing the value of a Vim option or a key map or
+an abbreviation or a user-defined function or a command or a highlight group
+or an autocommand will also display where it was last defined.  If it was
+defined manually then there will be no "Last set" message.  When it was
+defined while executing a function, user command or autocommand, the script in
+which it was defined is reported.
+{not available when compiled without the +eval feature}
+
+							*K*
+K			Run a program to lookup the keyword under the
+			cursor.  The name of the program is given with the
+			'keywordprg' (kp) option (default is "man").  The
+			keyword is formed of letters, numbers and the
+			characters in 'iskeyword'.  The keyword under or
+			right of the cursor is used.  The same can be done
+			with the command >
+				:!{program} {keyword}
+<			There is an example of a program to use in the tools
+			directory of Vim.  It is called 'ref' and does a
+			simple spelling check.
+			Special cases:
+			- If 'keywordprg' is empty, the ":help" command is
+			  used.  It's a good idea to include more characters
+			  in 'iskeyword' then, to be able to find more help.
+			- When 'keywordprg' is equal to "man", a count before
+			  "K" is inserted after the "man" command and before
+			  the keyword.  For example, using "2K" while the
+			  cursor is on "mkdir", results in: >
+				!man 2 mkdir
+<			- When 'keywordprg' is equal to "man -s", a count
+			  before "K" is inserted after the "-s".  If there is
+			  no count, the "-s" is removed.
+			{not in Vi}
+
+							*v_K*
+{Visual}K		Like "K", but use the visually highlighted text for
+			the keyword.  Only works when the highlighted text is
+			not more than one line.  {not in Vi}
+
+[N]gs							*gs* *:sl* *:sleep*
+:[N]sl[eep] [N]	[m]	Do nothing for [N] seconds.  When [m] is included,
+			sleep for [N] milliseconds.  The count for "gs" always
+			uses seconds.  The default is one second. >
+			     :sleep	     "sleep for one second
+			     :5sleep	     "sleep for five seconds
+			     :sleep 100m     "sleep for a hundred milliseconds
+			     10gs	     "sleep for ten seconds
+<			Can be interrupted with CTRL-C (CTRL-Break on MS-DOS).
+			"gs" stands for "goto sleep".
+			While sleeping the cursor is positioned in the text,
+			if at a visible position.  {not in Vi}
+
+							*g_CTRL-A*
+g CTRL-A		Only when Vim was compiled with MEM_PROFILING defined
+			(which is very rare): print memory usage statistics.
+			Only useful for debugging Vim.
+
+==============================================================================
+2. Online help						*online-help*
+
+			*help* *<Help>* *:h* *:help* *<F1>* *i_<F1>* *i_<Help>*
+<Help>		or
+:h[elp]			Open a window and display the help file in read-only
+			mode.  If there is a help window open already, use
+			that one.  Otherwise, if the current window uses the
+			full width of the screen or is at least 80 characters
+			wide, the help window will appear just above the
+			current window.  Otherwise the new window is put at
+			the very top.
+			The 'helplang' option is used to select a language, if
+			the main help file is available in several languages.
+			{not in Vi}
+
+						*{subject}* *E149* *E661*
+:h[elp] {subject}	Like ":help", additionally jump to the tag {subject}.
+			{subject} can include wildcards like "*", "?" and
+			"[a-z]":
+			   :help z?	jump to help for any "z" command
+			   :help z.	jump to the help for "z."
+			If there is no full match for the pattern, or there
+			are several matches, the "best" match will be used.
+			A sophisticated algorithm is used to decide which
+			match is better than another one.  These items are
+			considered in the computation:
+			- A match with same case is much better than a match
+			  with different case.
+			- A match that starts after a non-alphanumeric
+			  character is better than a match in the middle of a
+			  word.
+			- A match at or near the beginning of the tag is
+			  better than a match further on.
+			- The more alphanumeric characters match, the better.
+			- The shorter the length of the match, the better.
+
+			The 'helplang' option is used to select a language, if
+			the {subject} is available in several languages.
+			To find a tag in a specific language, append "@ab",
+			where "ab" is the two-letter language code.  See
+			|help-translated|.
+
+			Note that the longer the {subject} you give, the less
+			matches will be found.  You can get an idea how this
+			all works by using commandline completion (type CTRL-D
+			after ":help subject").
+			If there are several matches, you can have them listed
+			by hitting CTRL-D.  Example: >
+				:help cont<Ctrl-D>
+<			To use a regexp |pattern|, first do ":help" and then
+			use ":tag {pattern}" in the help window.  The
+			":tnext" command can then be used to jump to other
+			matches, "tselect" to list matches and choose one. >
+				:help index| :tse z.
+<			This command can be followed by '|' and another
+			command, but you don't need to escape the '|' inside a
+			help command.  So these both work: >
+				:help |
+				:help k| only
+<			Note that a space before the '|' is seen as part of
+			the ":help" argument.
+			You can also use <LF> or <CR> to separate the help
+			command from a following command.  You need to type
+			CTRL-V first to insert the <LF> or <CR>.  Example: >
+				:help so<C-V><CR>only
+<			{not in Vi}
+
+:h[elp]! [subject]	Like ":help", but in non-English help files prefer to
+			find a tag in a file with the same language as the
+			current file.  See |help-translated|.
+
+							*:helpg* *:helpgrep*
+:helpg[rep] {pattern}[@xx]
+			Search all help text files and make a list of lines
+			in which {pattern} matches.  Jumps to the first match.
+			The optional [@xx] specifies that only matches in the
+			"xx" language are to be found.
+			You can navigate through the matches with the
+			|quickfix| commands, e.g., |:cnext| to jump to the
+			next one.  Or use |:cwindow| to get the list of
+			matches in the quickfix window.
+			{pattern} is used as a Vim regexp |pattern|.
+			'ignorecase' is not used, add "\c" to ignore case.
+			Example for case sensitive search: >
+				:helpgrep Uganda
+<			Example for case ignoring search: >
+				:helpgrep uganda\c
+<			Example for searching in French help: >
+				:helpgrep backspace@fr
+<			Cannot be followed by another command, everything is
+			used as part of the pattern.  But you can use
+			|:execute| when needed.
+			Compressed help files will not be searched (Debian
+			compresses the help files).
+			{not in Vi}
+
+							*:lh* *:lhelpgrep*
+:lh[elpgrep] {pattern}[@xx]
+			Same as ":helpgrep", except the location list is used
+			instead of the quickfix list. If the help window is
+			already opened, then the location list for that window
+			is used. Otherwise, a new help window is opened and
+			the location list for that window is set.  The
+			location list for the current window is not changed.
+
+							*:exu* *:exusage*
+:exu[sage]		Show help on Ex commands.  Added to simulate the Nvi
+			command. {not in Vi}
+
+							*:viu* *:viusage*
+:viu[sage]		Show help on Normal mode commands.  Added to simulate
+			the Nvi command. {not in Vi}
+
+When no argument is given to |:help| the file given with the 'helpfile' option
+will be opened.  Otherwise the specified tag is searched for in all "doc/tags"
+files in the directories specified in the 'runtimepath' option.
+
+The initial height of the help window can be set with the 'helpheight' option
+(default 20).
+
+Jump to specific subjects by using tags.  This can be done in two ways:
+- Use the "CTRL-]" command while standing on the name of a command or option.
+  This only works when the tag is a keyword.  "<C-Leftmouse>" and
+  "g<LeftMouse>" work just like "CTRL-]".
+- use the ":ta {subject}" command.  This also works with non-keyword
+  characters.
+
+Use CTRL-T or CTRL-O to jump back.
+Use ":q" to close the help window.
+
+If there are several matches for an item you are looking for, this is how you
+can jump to each one of them:
+1. Open a help window
+2. Use the ":tag" command with a slash prepended to the tag.  E.g.: >
+	:tag /min
+3. Use ":tnext" to jump to the next matching tag.
+
+It is possible to add help files for plugins and other items.  You don't need
+to change the distributed help files for that.  See |add-local-help|.
+
+To write a local help file, see |write-local-help|.
+
+Note that the title lines from the local help files are automagically added to
+the "LOCAL ADDITIONS" section in the "help.txt" help file |local-additions|.
+This is done when viewing the file in Vim, the file itself is not changed.  It
+is done by going through all help files and obtaining the first line of each
+file.  The files in $VIMRUNTIME/doc are skipped.
+
+							*help-xterm-window*
+If you want to have the help in another xterm window, you could use this
+command: >
+	:!xterm -e vim +help &
+<
+
+			*:helpfind* *:helpf*
+:helpf[ind]		Like |:help|, but use a dialog to enter the argument.
+			Only for backwards compatibility.  It now executes the
+			ToolBar.FindHelp menu entry instead of using a builtin
+			dialog.  {only when compiled with |+GUI_GTK|}
+<			{not in Vi}
+
+					*:helpt* *:helptags*
+				*E154* *E150* *E151* *E152* *E153* *E670*
+:helpt[ags] {dir}	Generate the help tags file(s) for directory {dir}.
+			All "*.txt" and "*.??x" files in the directory are
+			scanned for a help tag definition in between stars.
+			The "*.??x" files are for translated docs, they
+			generate the "tags-??" file, see |help-translated|.
+			The generated tags files are sorted.
+			When there are duplicates an error message is given.
+			An existing tags file is silently overwritten.
+			To rebuild the help tags in the runtime directory
+			(requires write permission there): >
+				:helptags $VIMRUNTIME/doc
+<			{not in Vi}
+
+
+TRANSLATED HELP						*help-translated*
+
+It is possible to add translated help files, next to the original English help
+files.  Vim will search for all help in "doc" directories in 'runtimepath'.
+This is only available when compiled with the |+multi_lang| feature.
+
+At this moment translations are available for:
+	Chinese - multiple authors
+	French  - translated by David Blanchet
+	Italian - translated by Antonio Colombo
+	Polish  - translated by Mikolaj Machowski
+	Russian - translated by Vassily Ragosin
+See the Vim website to find them: http://www.vim.org/translations.php
+
+A set of translated help files consists of these files:
+
+	help.abx
+	howto.abx
+	...
+	tags-ab
+
+"ab" is the two-letter language code.  Thus for Italian the names are:
+
+	help.itx
+	howto.itx
+	...
+	tags-it
+
+The 'helplang' option can be set to the preferred language(s).  The default is
+set according to the environment.  Vim will first try to find a matching tag
+in the preferred language(s).  English is used when it cannot be found.
+
+To find a tag in a specific language, append "@ab" to a tag, where "ab" is the
+two-letter language code.  Example: >
+	:he user-manual@it
+	:he user-manual@en
+The first one finds the Italian user manual, even when 'helplang' is empty.
+The second one finds the English user manual, even when 'helplang' is set to
+"it".
+
+When using command-line completion for the ":help" command, the "@en"
+extention is only shown when a tag exists for multiple languages.  When the
+tag only exists for English "@en" is omitted.
+
+When using |CTRL-]| or ":help!" in a non-English help file Vim will try to
+find the tag in the same language.  If not found then 'helplang' will be used
+to select a language.
+
+Help files must use latin1 or utf-8 encoding.  Vim assumes the encoding is
+utf-8 when finding non-ASCII characters in the first line.  Thus you must
+translate the header with "For Vim version".
+
+The same encoding must be used for the help files of one language in one
+directory.  You can use a different encoding for different languages and use
+a different encoding for help files of the same language but in a different
+directory.
+
+Hints for translators:
+- Do not translate the tags.  This makes it possible to use 'helplang' to
+  specify the preferred language.  You may add new tags in your language.
+- When you do not translate a part of a file, add tags to the English version,
+  using the "tag@en" notation.
+- Make a package with all the files and the tags file available for download.
+  Users can drop it in one of the "doc" directories and start use it.
+  Report this to Bram, so that he can add a link on www.vim.org.
+- Use the |:helptags| command to generate the tags files.  It will find all
+  languages in the specified directory.
+
+==============================================================================
+3. Using Vim like less or more					*less*
+
+If you use the less or more program to view a file, you don't get syntax
+highlighting.  Thus you would like to use Vim instead.  You can do this by
+using the shell script "$VIMRUNTIME/macros/less.sh".
+
+This shell script uses the Vim script "$VIMRUNTIME/macros/less.vim".  It sets
+up mappings to simulate the commands that less supports.  Otherwise, you can
+still use the Vim commands.
+
+This isn't perfect.  For example, when viewing a short file Vim will still use
+the whole screen.  But it works good enough for most uses, and you get syntax
+highlighting.
+
+The "h" key will give you a short overview of the available commands.
+
+ vim:tw=78:ts=8:ft=help:norl:
--- /dev/null
+++ b/lib/vimfiles/doc/version4.txt
@@ -1,0 +1,355 @@
+*version4.txt*  For Vim version 7.1.  Last change: 2006 Apr 24
+
+
+		  VIM REFERENCE MANUAL    by Bram Moolenaar
+
+
+This document lists the incompatible differences between Vim 3.0 and Vim 4.0.
+Although 4.0 is mentioned here, this is also for version 4.1, 4.2, etc..
+
+This file is important for everybody upgrading from Vim 3.0.  Read it
+carefully to avoid unexpected problems.
+
+'backup' option default changed			|backup-changed|
+Extension for backup file changed		|backup-extension|
+Structure of swap file changed			|swapfile-changed|
+"-w scriptout" argument changed			|scriptout-changed|
+Backspace and Delete keys			|backspace-delete|
+Escape for | changed				|escape-bar|
+Key codes changed				|key-codes-changed|
+Terminal options changed			|termcap-changed|
+'errorformat' option changed			|errorformat-changed|
+'graphic' option gone				|graphic-option-gone|
+'yankendofline' option gone			|ye-option-gone|
+'icon' and 'title' default value changed	|icon-changed|
+'highlight' option changed			|highlight-changed|
+'tildeop' and 'weirdinvert' short names changed	|short-name-changed|
+Use of "v", "V" and "CTRL-V" in Visual mode	|use-visual-cmds|
+CTRL-B in Insert mode removed			|toggle-revins|
+
+
+'backup' option default changed				*backup-changed*
+-------------------------------
+
+The default value for 'backup' used to be on.  This resulted in a backup file
+being made when the original file was overwritten.
+
+Now the default for 'backup' is off.  As soon as the writing of the file has
+successfully finished, the backup file is deleted.  If you want to keep the
+backup file, set 'backup' on in your vimrc.  The reason for this change is
+that many people complained that leaving a backup file behind is not
+Vi-compatible.						|'backup'|
+
+
+Extension for backup file changed			*backup-extension*
+---------------------------------
+
+The extension for the backup file used to be ".bak".  Since other programs
+also use this extension and some users make copies with this extension, it was
+changed to the less obvious "~".  Another advantage is that this takes less
+space, which is useful when working on a system with short file names.  For
+example, on MS-DOS the backup files for "longfile.c" and "longfile.h" would
+both become "longfile.bak"; now they will be "longfile.c~" and "longfile.h~".
+
+If you prefer to use ".bak", you can set the 'backupext' option: >
+	:set bex=.bak
+
+
+Structure of swap file changed				*swapfile-changed*
+------------------------------
+
+The contents of the swap file were extended with several parameters.  Vim
+stores the user name and other information about the edited file to make
+recovery more easy and to be able to know where the swap file comes from.  The
+first part of the swap file can now be understood on a machine with a
+different byte order or sizeof(int).  When you try to recover a file on such a
+machine, you will get an error message that this is not possible.
+
+Because of this change, swap files cannot be exchanged between 3.0 and 4.0.
+If you have a swap file from a crashed session with 3.0, use Vim 3.0 to
+recover the file---don't use 4.0.			|swap-file|
+
+
+"-w scriptout" argument changed				*scriptout-changed*
+-------------------------------
+
+"vim -w scriptout" used to append to the scriptout file.  Since this was
+illogical, it now creates a new file.  An existing file is not overwritten
+(to avoid destroying an existing file for those who rely on the appending).
+[This was removed again later]					|-w|
+
+
+Backspace and Delete keys				*backspace-delete*
+-------------------------
+
+In 3.0 both the delete key and the backspace key worked as a backspace in
+insert mode; they deleted the character to the left of the cursor.  In 4.0 the
+delete key has a new function: it deletes the character under the cursor, just
+like it does on the command-line.  If the cursor is after the end of the line
+and 'bs' is set, two lines are joined.			|<Del>| |i_<Del>|
+
+In 3.0 the backspace key was always defined as CTRL-H and delete as CTRL-?.
+In 4.0 the code for the backspace and delete key is obtained from termcap or
+termlib, and adjusted for the "stty erase" value on Unix.  This helps people
+who define the erase character according to the keyboard they are working on.
+							|<BS>| |i_<BS>|
+
+If you prefer backspace and delete in Insert mode to have the old behavior,
+put this line in your vimrc:
+
+	inoremap ^? ^H
+
+And you may also want to add these, to fix the values for <BS> and <Del>:
+
+	set t_kb=^H
+	set t_kD=^?
+
+(Enter ^H with CTRL-V CTRL-H and ^? with CTRL-V CTRL-? or <Del>.)
+
+If the value for t_kb is correct, but the t_kD value is not, use the ":fixdel"
+command.  It will set t_kD according to the value of t_kb.  This is useful if
+you are using several different terminals.		|:fixdel|
+
+When ^H is not recognized as <BS> or <Del>, it is used like a backspace.
+
+
+Escape for | changed					*escape-bar*
+--------------------
+
+When the 'b' flag is present in 'cpoptions', the backslash cannot be used to
+escape '|' in mapping and abbreviate commands, only CTRL-V can.  This is
+Vi-compatible.  If you work in Vi-compatible mode and had used "\|" to include
+a bar in a mapping, this needs to be replaced by "^V|".  See |:bar|.
+
+
+Key codes changed					*key-codes-changed*
+-----------------
+
+The internal representation of key codes has changed dramatically.  In 3.0 a
+one-byte code was used to represent a key.  This caused problems with
+different characters sets that also used these codes.  In 4.0 a three-byte
+code is used that cannot be confused with a character.		|key-notation|
+
+If you have used the single-byte key codes in your vimrc for mappings, you
+will have to replace them with the 4.0 codes.  Instead of using the three-byte
+code directly, you should use the symbolic representation for this in <>.  See
+the table below.  The table also lists the old name, as it was used in the 3.0
+documentation.
+
+The key names in <> can be used in mappings directly.  This makes it possible
+to copy/paste examples or type them literally.  The <> notation has been
+introduced for this |<>|.  The 'B' and '<' flags must not be present in
+'cpoptions' to enable this to work |'cpoptions'|.
+
+old name	new name	  old code	old MS-DOS code	~
+				hex	dec	hex	dec	~
+<ESC>		<Esc>
+<TAB>		<Tab>
+<LF>		<NL> <NewLine> <LineFeed>
+<SPACE>		<Space>
+<NUL>		<Nul>
+<BELL>		<Bell>
+<BS>		<BS> <BackSpace>
+<INSERT>	<Insert>
+<DEL>		<Del> <Delete>
+<HOME>		<Home>
+<END>		<End>
+<PAGE_UP>	<PageUp>
+<PAGE_DOWN>	<PageDown>
+
+<C_UP>		<Up>		0x80	128	0xb0	176
+<C_DOWN>	<Down>		0x81	129     0xb1	177
+<C_LEFT>	<Left>		0x82	130     0xb2	178
+<C_RIGHT>	<Right>		0x83	131     0xb3	179
+<SC_UP>		<S-Up>		0x84	132     0xb4	180
+<SC_DOWN>	<S-Down>	0x85	133     0xb5	181
+<SC_LEFT>	<S-Left>	0x86	134     0xb6	182
+<SC_RIGHT>	<S-Right>	0x87	135     0xb7	183
+
+<F1>		<F1>		0x88	136     0xb8	184
+<F2>		<F2>		0x89	137     0xb9	185
+<F3>		<F3>		0x8a	138     0xba	186
+<F4>		<F4>		0x8b	139     0xbb	187
+<F5>		<F5>		0x8c	140     0xbc	188
+<F6>		<F6>		0x8d	141     0xbd	189
+<F7>		<F7>		0x8e	142     0xbe	190
+<F8>		<F8>		0x8f	143     0xbf	191
+<F9>		<F9>		0x90	144     0xc0	192
+<F10>		<F10>		0x91	145     0xc1	193
+
+<SF1>		<S-F1>		0x92	146     0xc2	194
+<SF2>		<S-F2>		0x93	147     0xc3	195
+<SF3>		<S-F3>		0x94	148     0xc4	196
+<SF4>		<S-F4>		0x95	149     0xc5	197
+<SF5>		<S-F5>		0x96	150     0xc6	198
+<SF6>		<S-F6>		0x97	151     0xc7	199
+<SF7>		<S-F7>		0x98	152     0xc8	200
+<SF8>		<S-F8>		0x99	153     0xc9	201
+<SF9>		<S-F9>		0x9a	154     0xca	202
+<SF10>		<S-F10>		0x9b	155     0xcb	203
+
+<HELP>		<Help>		0x9c	156     0xcc	204
+<UNDO>		<Undo>		0x9d	157     0xcd	205
+
+		(not used)	0x9e	158     0xce	206
+		(not used)	0x9f	159     0xcf	207
+
+
+Terminal options changed				*termcap-changed*
+------------------------
+
+The names of the terminal options have been changed to match the termcap names
+of these options.  All terminal options now have the name t_xx, where xx is
+the termcap name.  Normally these options are not used, unless you have a
+termcap entry that is wrong or incomplete, or you have set the highlight
+options to a different value.				|terminal-options|
+
+Note that for some keys there is no termcap name.  Use the <> type of name
+instead, which is a good idea anyway.
+
+Note that "t_ti" has become "t_mr" (invert/reverse output) and "t_ts" has
+become "t_ti" (init terminal mode).  Be careful when you use "t_ti"!
+
+old name	new name	meaning		~
+t_cdl		t_DL		delete number of lines		*t_cdl*
+t_ci		t_vi		cursor invisible		*t_ci*
+t_cil		t_AL		insert number of lines		*t_cil*
+t_cm		t_cm		move cursor
+t_cri		t_RI		cursor number of chars right	*t_cri*
+t_cv		t_ve		cursor visible			*t_cv*
+t_cvv		t_vs		cursor very visible		*t_cvv*
+t_dl		t_dl		delete line
+t_cs		t_cs		scroll region
+t_ed		t_cl		clear display			*t_ed*
+t_el		t_ce		clear line			*t_el*
+t_il		t_al		insert line			*t_il*
+		t_da		display may be retained above the screen
+		t_db		display may be retained below the screen
+t_ke		t_ke		put terminal out of keypad transmit mode
+t_ks		t_ks		put terminal in keypad transmit mode
+t_ms		t_ms		save to move cursor in highlight mode
+t_se		t_se		normal mode (undo t_so)
+t_so		t_so		shift out (standout) mode
+t_ti		t_mr		reverse highlight
+t_tb		t_md		bold mode			*t_tb*
+t_tp		t_me		highlight end			*t_tp*
+t_sr		t_sr		scroll reverse
+t_te		t_te		out of termcap mode
+t_ts		t_ti		into termcap mode		*t_ts_old*
+t_vb		t_vb		visual bell
+t_csc		t_CS		cursor is relative to scroll region *t_csc*
+
+t_ku	t_ku	<Up>		arrow up
+t_kd	t_kd	<Down>		arrow down
+t_kr	t_kr	<Right>		arrow right
+t_kl	t_kl	<Left>		arrow left
+t_sku		<S-Up>		shifted arrow up		*t_sku*
+t_skd		<S-Down>	shifted arrow down		*t_skd*
+t_skr	t_%i	<S-Right>	shifted arrow right		*t_skr*
+t_skl	t_#4	<S-Left>	shifted arrow left		*t_skl*
+t_f1	t_k1	<F1>		function key 1			*t_f1*
+t_f2	t_k2	<F2>		function key 2			*t_f2*
+t_f3	t_k3	<F3>		function key 3			*t_f3*
+t_f4	t_k4	<F4>		function key 4			*t_f4*
+t_f5	t_k5	<F5>		function key 5			*t_f5*
+t_f6	t_k6	<F6>		function key 6			*t_f6*
+t_f7	t_k7	<F7>		function key 7			*t_f7*
+t_f8	t_k8	<F8>		function key 8			*t_f8*
+t_f9	t_k9	<F9>		function key 9			*t_f9*
+t_f10	t_k;	<F10>		function key 10			*t_f10*
+t_sf1		<S-F1>		shifted function key 1		*t_sf1*
+t_sf2		<S-F2>		shifted function key 2		*t_sf2*
+t_sf3		<S-F3>		shifted function key 3		*t_sf3*
+t_sf4		<S-F4>		shifted function key 4		*t_sf4*
+t_sf5		<S-F5>		shifted function key 5		*t_sf5*
+t_sf6		<S-F6>		shifted function key 6		*t_sf6*
+t_sf7		<S-F7>		shifted function key 7		*t_sf7*
+t_sf8		<S-F8>		shifted function key 8		*t_sf8*
+t_sf9		<S-F9>		shifted function key 9		*t_sf9*
+t_sf10		<S-F10>		shifted function key 10		*t_sf10*
+t_help	t_%1	<Help>		help key			*t_help*
+t_undo	t_&8	<Undo>		undo key			*t_undo*
+
+
+'errorformat' option changed				*errorformat-changed*
+----------------------------
+
+'errorformat' can now contain several formats, separated by commas.  The first
+format that matches is used.  The default values have been adjusted to catch
+the most common formats.				|errorformat|
+
+If you have a format that contains a comma, it needs to be preceded with a
+backslash.  Type two backslashes, because the ":set" command will eat one.
+
+
+'graphic' option gone					*graphic-option-gone*
+---------------------
+
+The 'graphic' option was used to make the characters between <~> and 0xa0
+display directly on the screen.  Now the 'isprint' option takes care of this
+with many more possibilities.  The default setting is the same; you only need
+to look into this if you previously set the 'graphic' option in your vimrc.
+							|'isprint'|
+
+
+'yankendofline' option gone				*ye-option-gone*
+---------------------------
+
+The 'yankendofline' option has been removed.  Instead you can just use
+	:map Y y$
+
+
+'icon' and 'title' default value changed		*icon-changed*
+----------------------------------------
+
+The 'title' option is now only set by default if the original title can be
+restored.  Avoids "Thanks for flying Vim" titles.  If you want them anyway,
+put ":set title" in your vimrc.				|'title'|
+
+The default for 'icon' now depends on the possibility of restoring the
+original value, just like 'title'.  If you don't like your icon titles to be
+changed, add this line to your vimrc:			|'icon'|
+	:set noicon
+
+
+'highlight' option changed				*highlight-changed*
+--------------------------
+
+The 'i' flag now means italic highlighting, instead of invert.  The 'r' flag
+is used for reverse highlighting, which is what 'i' used to be.  Normally you
+won't see the difference, because italic mode is not supported on most
+terminals and reverse mode is used as a fallback.	|'highlight'|
+
+When an occasion is not present in 'highlight', use the mode from the default
+value for 'highlight', instead of reverse mode.
+
+
+'tildeop' and 'weirdinvert' short names changed		*short-name-changed*
+-----------------------------------------------
+
+Renamed 'to' (abbreviation for 'tildeop') to 'top'.	|'tildeop'|
+Renamed 'wi' (abbreviation for 'weirdinvert') to 'wiv'.	|'weirdinvert'|
+
+This was done because Vi uses 'wi' as the short name for 'window' and 'to' as
+the short name for 'timeout'.  This means that if you try setting these
+options, you won't get an error message, but the effect will be different.
+
+
+Use of "v", "V" and "CTRL-V" in Visual mode		*use-visual-cmds*
+-------------------------------------------
+
+In Visual mode, "v", "V", and "CTRL-V" used to end Visual mode.  Now this
+happens only if the Visual mode was in the corresponding type.  Otherwise the
+type of Visual mode is changed.  Now only ESC can be used in all circumstances
+to end Visual mode without doing anything.		|v_V|
+
+
+CTRL-B in Insert mode removed				*toggle-revins*
+-----------------------------
+
+CTRL-B in Insert mode used to toggle the 'revins' option.  If you don't know
+this and accidentally hit CTRL-B, it is very difficult to find out how to undo
+it.  Since hardly anybody uses this feature, it is disabled by default.  If
+you want to use it, define RIGHTLEFT in feature.h before compiling. |'revins'|
+
+ vim:tw=78:ts=8:ft=help:norl:
--- /dev/null
+++ b/lib/vimfiles/doc/version5.txt
@@ -1,0 +1,7813 @@
+*version5.txt*  For Vim version 7.1.  Last change: 2007 May 11
+
+
+		  VIM REFERENCE MANUAL    by Bram Moolenaar
+
+Welcome to Vim Version 5.0!
+
+This document lists the differences between Vim 4.x and Vim 5.0.
+Although 5.0 is mentioned here, this is also for version 5.1, 5.2, etc..
+See |vi_diff.txt| for an overview of differences between Vi and Vim 5.0.
+See |version4.txt| for differences between Vim 3.0 and Vim 4.0.
+
+INCOMPATIBLE:				|incompatible-5|
+
+Default value for 'compatible' changed	|cp-default|
+Text formatting command "Q" changed	|Q-command-changed|
+Command-line arguments changed		|cmdline-changed|
+Autocommands are kept			|autocmds-kept|
+Use of 'hidden' changed			|hidden-changed|
+Text object commands changed		|text-objects-changed|
+X-Windows Resources removed		|x-resources|
+Use of $VIM				|$VIM-use|
+Use of $HOME for MS-DOS and Win32	|$HOME-use|
+Tags file format changed		|tags-file-changed|
+Options changed				|options-changed|
+CTRL-B in Insert mode gone		|i_CTRL-B-gone|
+
+NEW FEATURES:				|new-5|
+
+Syntax highlighting			|new-highlighting|
+Built-in script language		|new-script|
+Perl and Python support			|new-perl-python|
+Win32 GUI version			|added-win32-GUI|
+VMS version				|added-VMS|
+BeOS version				|added-BeOS|
+Macintosh GUI version			|added-Mac|
+More Vi compatible			|more-compatible|
+Read input from stdin			|read-stdin|
+Regular expression patterns		|added-regexp|
+Overloaded tags				|tag-overloaded|
+New commands				|new-commands|
+New options				|added-options|
+New command-line arguments		|added-cmdline-args|
+Various additions			|added-various|
+
+IMPROVEMENTS				|improvements-5|
+
+COMPILE TIME CHANGES			|compile-changes-5|
+
+BUG FIXES				|bug-fixes-5|
+
+VERSION 5.1			|version-5.1|
+Changed					|changed-5.1|
+Added					|added-5.1|
+Fixed					|fixed-5.1|
+
+VERSION 5.2			|version-5.2|
+Long lines editable			|long-lines|
+File browser added			|file-browser-5.2|
+Dialogs added				|dialogs-added|
+Popup menu added			|popup-menu-added|
+Select mode added			|new-Select-mode|
+Session files added			|new-session-files|
+User defined functions and commands	|new-user-defined|
+New interfaces				|interfaces-5.2|
+New ports				|ports-5.2|
+Multi-byte support			|new-multi-byte|
+New functions				|new-functions-5.2|
+New options				|new-options-5.2|
+New Ex commands				|new-ex-commands-5.2|
+Changed					|changed-5.2|
+Added					|added-5.2|
+Fixed					|fixed-5.2|
+
+VERSION 5.3			|version-5.3|
+Changed					|changed-5.3|
+Added					|added-5.3|
+Fixed					|fixed-5.3|
+
+VERSION 5.4			|version-5.4|
+Runtime directory introduced		|new-runtime-dir|
+Filetype introduced			|new-filetype-5.4|
+Vim script line continuation		|new-line-continuation|
+Improved session files			|improved-sessions|
+Autocommands improved			|improved-autocmds-5.4|
+Encryption				|new-encryption|
+GTK GUI port				|new-GTK-GUI|
+Menu changes				|menu-changes-5.4|
+Viminfo improved			|improved-viminfo|
+Various new commands			|new-commands-5.4|
+Various new options			|new-options-5.4|
+Vim scripts				|new-script-5.4|
+Avoid hit-enter prompt			|avoid-hit-enter|
+Improved quickfix			|improved-quickfix|
+Regular expressions			|regexp-changes-5.4|
+Changed					|changed-5.4|
+Added					|added-5.4|
+Fixed					|fixed-5.4|
+
+VERSION 5.5			|version-5.5|
+Changed					|changed-5.5|
+Added					|added-5.5|
+Fixed					|fixed-5.5|
+
+VERSION 5.6			|version-5.6|
+Changed					|changed-5.6|
+Added					|added-5.6|
+Fixed					|fixed-5.6|
+
+VERSION 5.7			|version-5.7|
+Changed					|changed-5.7|
+Added					|added-5.7|
+Fixed					|fixed-5.7|
+
+VERSION 5.8			|version-5.8|
+Changed					|changed-5.8|
+Added					|added-5.8|
+Fixed					|fixed-5.8|
+
+==============================================================================
+				 INCOMPATIBLE		*incompatible-5*
+
+Default value for 'compatible' changed			*cp-default*
+--------------------------------------
+
+Vim version 5.0 tries to be more Vi compatible.  This helps people who use Vim
+as a drop-in replacement for Vi, but causes some things to be incompatible
+with version 4.x.
+
+In version 4.x the default value for the 'compatible' option was off.  Now the
+default is on.  The first thing you will notice is that the "u" command undoes
+itself.  Other side effects will be that mappings may work differently or not
+work at all.
+
+Since a lot of people switching from Vim 4.x to 5.0 will find this annoying,
+the 'compatible' option is switched off if Vim finds a vimrc file.  This is a
+bit of magic to make sure that 90% of the Vim users will not be bitten by
+this change.
+
+What does this mean?
+- If you prefer to run in 'compatible' mode and don't have a vimrc file, you
+  don't have to do anything.
+- If you prefer to run in 'nocompatible' mode and do have a vimrc file, you
+  don't have to do anything.
+- If you prefer to run in 'compatible' mode and do have a vimrc file, you
+  should put this line first in your vimrc file: >
+	:set compatible
+- If you prefer to run in 'nocompatible' mode and don't have a vimrc file,
+  you can do one of the following:
+    - Create an empty vimrc file (e.g.: "~/.vimrc" for Unix).
+    - Put this command in your .exrc file or $EXINIT: >
+		:set nocompatible
+<   - Start Vim with the "-N" argument.
+
+If you are new to Vi and Vim, using 'nocompatible' is strongly recommended,
+because Vi has a lot of unexpected side effects, which are avoided by this
+setting.  See 'compatible'.
+
+If you like some things from 'compatible' and some not, you can tune the
+compatibility with 'cpoptions'.
+
+When you invoke Vim as "ex" or "gex", Vim always starts in compatible mode.
+
+
+Text formatting command "Q" changed			*Q-command-changed*
+-----------------------------------
+
+The "Q" command formerly formatted lines to the width the 'textwidth' option
+specifies.  The command for this is now "gq" (see |gq| for more info).  The
+reason for this change is that "Q" is the standard Vi command to enter "Ex"
+mode, and Vim now does in fact have an "Ex" mode (see |Q| for more info).
+
+If you still want to use "Q" for formatting, use this mapping: >
+	:noremap Q gq
+And if you also want to use the functionality of "Q": >
+	:noremap gQ Q
+
+
+Command-line arguments changed				*cmdline-changed*
+------------------------------
+
+Command-line file-arguments and option-arguments can now be mixed.  You can
+give options after the file names.  Example: >
+   vim main.c -g
+
+This is not possible when editing a file that starts with a '-'.  Use the "--"
+argument then |---|: >
+   vim -g -- -main.c
+
+"-v" now means to start Ex in Vi mode, use "-R" for read-only mode.
+old: "vim -v file"	|-v|
+new: "vim -R file"	|-R|
+
+"-e" now means to start Vi in Ex mode, use "-q" for quickfix.
+old: "vim -e errorfile"	|-e|
+new: "vim -q errorfile" |-q|
+
+"-s" in Ex mode now means to run in silent (batch) mode. |-s-ex|
+
+"-x" reserved for crypt, use "-f" to avoid starting a new CLI (Amiga).
+old: "vim -x file"	|-x|
+new: "vim -f file"	|-f|
+
+Vim allows up to ten "+cmd" and "-c cmd" arguments.  Previously Vim executed
+only the last one.
+
+"-n" now overrides any setting for 'updatecount' in a vimrc file, but not in
+a gvimrc file.
+
+
+Autocommands are kept					*autocmds-kept*
+---------------------
+
+Before version 5.0, autocommands with the same event, file name pattern, and
+command could appear only once.  This was fine for simple autocommands (like
+setting option values), but for more complicated autocommands, where the same
+command might appear twice, this restriction caused problems.  Therefore
+Vim stores all autocommands and keeps them in the order that they are defined.
+
+The most obvious side effect of this change is that when you source a vimrc
+file twice, the autocommands in it will be defined twice.  To avoid this, do
+one of these:
+
+- Remove any autocommands that might potentially defined twice before
+  defining them.  Example: >
+	:au! * *.ext
+	:au BufEnter *.ext ...
+
+- Put the autocommands inside an ":if" command.  Example: >
+	if !exists("did_ext_autocmds")
+	  let did_ext_autocmds = 1
+	  autocmd BufEnter *.ext ...
+	endif
+
+- Put your autocommands in a different autocommand group so you can remove
+  them before defining them |:augroup|: >
+	augroup uncompress
+	  au!
+	  au BufReadPost *.gz ...
+	augroup END
+
+
+Use of 'hidden' changed					*hidden-changed*
+-----------------------
+
+In version 4.x, only some commands used the 'hidden' option.  Now all commands
+uses it whenever a buffer disappears from a window.
+
+Previously you could do ":buf xxx" in a changed buffer and that buffer would
+then become hidden.  Now you must set the 'hidden' option for this to work.
+
+The new behavior is simpler: whether Vim hides buffers no longer depends on
+the specific command that you use.
+- with 'hidden' not set, you never get hidden buffers.  Exceptions are the
+  ":hide" and ":close!" commands and, in rare cases, where you would otherwise
+  lose changes to the buffer.
+- With 'hidden' set, you almost never unload a buffer.  Exceptions are the
+  ":bunload" or ":bdel" commands.
+
+":buffer" now supports a "!": abandon changes in current buffer.  So do
+":bnext", ":brewind", etc.
+
+
+Text object commands changed				*text-objects-changed*
+----------------------------
+
+Text object commands have new names.  This allows more text objects and makes
+characters available for other Visual mode commands.  Since no more single
+characters were available, text objects names now require two characters.
+The first one is always 'i' or 'a'.
+	OLD	NEW	~
+	a	aw	a word			|v_aw|
+	A	aW	a WORD			|v_aW|
+	s	as	a sentence		|v_as|
+	p	ap	a paragraph		|v_ap|
+	S	ab	a () block		|v_ab|
+	P	aB	a {} block		|v_aB|
+
+There is another set of text objects that starts with "i", for "inner".  These
+select the same objects, but exclude white space.
+
+
+X-Windows Resources removed				*x-resources*
+--------------------------
+
+Vim no longer supports the following X resources:
+- boldColor
+- italicColor
+- underlineColor
+- cursorColor
+
+Vim now uses highlight groups to set colors.  This avoids the confusion of
+using a bold Font, which would imply a certain color.  See |:highlight| and
+|gui-resources|.
+
+
+Use of $VIM						*$VIM-use*
+-----------
+
+Vim now uses the VIM environment variable to find all Vim system files.  This
+includes the global vimrc, gvimrc, and menu.vim files and all on-line help
+and syntax files.  See |$VIM|.  Starting with version 5.4, |$VIMRUNTIME| can
+also be used.
+For Unix, Vim sets a default value for $VIM when doing "make install".
+When $VIM is not set, its default value is the directory from 'helpfile',
+excluding "/doc/help.txt".
+
+
+Use of $HOME for MS-DOS and Win32			*$HOME-use*
+---------------------------------
+
+The MS-DOS and Win32 versions of Vim now first check $HOME when searching for
+a vimrc or exrc file and for reading/storing the viminfo file.  Previously Vim
+used $VIM for these systems, but this causes trouble on a system with several
+users.  Now Vim uses $VIM only when $HOME is not set or the file is not found
+in $HOME.  See |_vimrc|.
+
+
+Tags file format changed				*tags-file-changed*
+------------------------
+
+Only tabs are allowed to separate fields in a tags file.  This allows for
+spaces in a file name and is still Vi compatible.  In previous versions of
+Vim, any white space was allowed to separate the fields.  If you have a file
+which doesn't use a single tab between fields, edit the tags file and execute
+this command: >
+	:%s/\(\S*\)\s\+\(\S*\)\s\+\(.*\)/\1\t\2\t\3/
+
+
+Options changed						*options-changed*
+---------------
+
+The default value of 'errorfile' has changed from "errors.vim" to "errors.err".
+The reason is that only Vim scripts should have the ".vim" extensions.
+
+The ":make" command no longer uses the 'errorfile' option.  This prevents the
+output of the ":make" command from overwriting a manually saved error file.
+":make" uses the 'makeef' option instead.  This also allows for generating a
+unique name, to prevent concurrently running ":make" commands from overwriting
+each other's files.
+
+With 'insertmode' set, a few more things change:
+- <Esc> in Normal mode goes to Insert mode.
+- <Esc> in Insert mode doesn't leave Insert mode.
+- When doing ":set im", go to Insert mode immediately.
+
+Vim considers a buffer to be changed when the 'fileformat' (formerly the
+'textmode' option) is different from the buffer's initial format.
+
+
+CTRL-B in Insert mode gone				*i_CTRL-B-gone*
+--------------------------
+
+When Vim was compiled with the |+rightleft| feature, you could use CTRL-B to
+toggle the 'revins' option.  Unfortunately, some people hit the 'B' key
+accidentally when trying to type CTRL-V or CTRL-N and then didn't know how to
+undo this.  Since toggling the 'revins' option can easily be done with the
+mapping below, this use of the CTRL-B key is disabled.  You can still use the
+CTRL-_ key for this |i_CTRL-_|. >
+   :imap <C-B> <C-O>:set revins!<CR>
+
+==============================================================================
+				 NEW FEATURES		*new-5*
+
+Syntax highlighting					*new-highlighting*
+-------------------
+
+Vim now has a very flexible way to highlighting just about any type of file.
+See |syntax|.  Summary: >
+   :syntax on
+
+Colors and attributes can be set for the syntax highlighting, and also for
+other highlighted items with the ':' flag in the 'highlight' option.  All
+highlighted items are assigned a highlight group which specifies their
+highlighting.  See |:highlight|.  The default colors have been improved.
+
+You can use the "Normal" group to set the default fore/background colors for a
+color terminal.  For the GUI, you can use this group to specify the font, too.
+
+The "2html.vim" script can be used to convert any file that has syntax
+highlighting to HTML.  The colors will be exactly the same as how you see them
+in Vim.  With a HTML viewer you can also print the file with colors.
+
+
+Built-in script language				*new-script*
+------------------------
+
+A few extra commands and an expression evaluator enable you to write simple
+but powerful scripts.  Commands include ":if" and ":while".  Expressions can
+manipulate numbers and strings.  You can use the '=' register to insert
+directly the result of an expression.  See |expression|.
+
+
+Perl and Python support					*new-perl-python*
+-----------------------
+
+Vim can call Perl commands with ":perldo", ":perl", etc.  See |perl|.
+Patches made by Sven Verdoolaege and Matt Gerassimoff.
+
+Vim can call Python commands with ":python" and ":pyfile".  See |python|.
+
+Both of these are only available when enabled at compile time.
+
+
+Win32 GUI version					*added-win32-GUI*
+-----------------
+
+The GUI has been ported to MS Windows 95 and NT.  All the features of the X11
+GUI are available to Windows users now.  |gui-w32|
+This also fixes problems with running the Win32 console version under Windows
+95, where console support has always been bad.
+There is also a version that supports OLE automation interface.  |if_ole.txt|
+Vim can be integrated with Microsoft Developer Studio using the VisVim DLL.
+It is possible to produce a DLL version of gvim with Borland C++ (Aaron).
+
+
+VMS version						*added-VMS*
+-----------
+
+Vim can now also be used on VMS systems.  Port done by Henk Elbers.
+This has not been tested much, but it should work.
+Sorry, no documentation!
+
+
+BeOS version						*added-BeOS*
+------------
+
+Vim can be used on BeOS systems (including the BeBox).  (Olaf Seibert)
+See |os_beos.txt|.
+
+
+Macintosh GUI version					*added-Mac*
+---------------------
+
+Vim can now be used on the Macintosh.  (Dany St-Amant)
+It has not been tested much yet, be careful!
+See |os_mac.txt|.
+
+
+More Vi compatible					*more-compatible*
+------------------
+
+There is now a real Ex mode.  Started with the "Q" command, or by calling the
+executable "ex" or "gex".  |Ex-mode|
+
+Always allow multi-level undo, also in Vi compatible mode.  When the 'u' flag
+in 'cpoptions' is included, CTRL-R is used for repeating the undo or redo
+(like "." in Nvi).
+
+
+Read input from stdin					*read-stdin*
+---------------------
+
+When using the "-" command-line argument, Vim reads its text input from stdin.
+This can be used for putting Vim at the end of a pipe: >
+   grep "^a.*" *.c | vim -
+See |--|.
+
+
+Regular expression patterns				*added-regexp*
+---------------------------
+
+Added specifying a range for the number of matches of a atom: "\{a,b}". |/\{|
+Added the "shortest match" regexp "\{-}" (Webb).
+Added "\s", matches a white character.  Can replace "[ \t]".		|/\s|
+Added "\S", matches a non-white character.  Can replace "[^ \t]".	|/\S|
+
+
+Overloaded tags						*tag-overloaded*
+---------------
+
+When using a language like C++, there can be several tags for the same
+tagname.  Commands have been added to be able to jump to any of these
+overloaded tags:
+|:tselect|	List matching tags, and jump to one of them.
+|:stselect|	Idem, and split window.
+|g_CTRL-]|	Do ":tselect" with the word under the cursor.
+
+	After ":ta {tagname}" with multiple matches:
+|:tnext|	Go to next matching tag.
+|:tprevious|	Go to previous matching tag.
+|:trewind|	Go to first matching tag.
+|:tlast|	Go to last matching tag.
+
+The ":tag" command now also accepts wildcards.  When doing command-line
+completion on tags, case-insensitive matching is also available (at the end).
+
+
+New commands						*new-commands*
+------------
+
+|:amenu|	Define menus for all modes, inserting a CTRL-O for Insert
+		mode, ESC for Visual and CTRL-C for Cmdline mode.  "amenu" is
+		used for the default menus and the Syntax menu.
+
+|:augroup|	Set group to be used for following autocommands.  Allows the
+		grouping of autocommands to enable deletion of a specific
+		group.
+
+|:crewind|	Go to first error.
+|:clast|	Go to last error.
+
+|:doautoall|	Execute autocommands for all loaded buffers.
+
+|:echo|		Echo its argument, which is an expression.  Can be used to
+		display messages which include variables.
+
+|:execute|	Execute its argument, which is an expression.  Can be used to
+		built up an Ex command with anything.
+
+|:hide|		Works like ":close".
+
+|:if|		Conditional execution, for built-in script language.
+
+|:intro|	Show introductory message.  This is always executed when Vim
+		is started without file arguments.
+
+|:let|		Assign a value to an internal variable.
+
+|:omap|		Map only in operator-pending mode.  Makes it possible to map
+		text-object commands.
+
+|:redir|	Redirect output of messages to a file.
+
+|:update|	Write when buffer has changed.
+
+|:while|	While-loop for built-in script language.
+
+Visual mode:
+|v_O|		"O" in Visual block mode, moves the cursor to the other corner
+		horizontally.
+|v_D|		"D" in Visual block mode deletes till end of line.
+
+Insert mode:
+|i_CTRL-]|	Triggers abbreviation, without inserting any character.
+
+
+New options						*added-options*
+-----------
+
+'background'	Used for selecting highlight color defaults.  Also used in
+		"syntax.vim" for selecting the syntax colors.  Often set
+		automatically, depending on the terminal used.
+
+'complete'	Specifies how Insert mode completion works.
+
+'eventignore'	Makes it possible to ignore autocommands temporarily.
+
+'fileformat'	Current file format.  Replaces 'textmode'.
+'fileformats'	Possible file formats.  Replaces 'textauto'.
+		New is that this also supports Macintosh format: A single <CR>
+		separates lines.
+		The default for 'fileformats' for MS-DOS, Win32 and OS/2 is
+		"dos,unix", also when 'compatible' set.  Unix type files
+		didn't work anyway when 'fileformats' was empty.
+
+'guicursor'	Set the cursor shape and blinking in various modes.
+		Default is to adjust the cursor for Insert and Replace mode,
+		and when an operator is pending.  Blinking is default on.
+
+'fkmap'		Farsi key mapping.
+
+'hlsearch'	Highlight all matches with the last used search pattern.
+
+'hkmapp'	Phonetic Hebrew mapping. (Ilya Dogolazky)
+
+'iconstring'	Define the name of the icon, when not empty.  (Version 5.2: the
+		string is used literally, a newline can be used to make two
+		lines.)
+
+'lazyredraw'	Don't redraw the screen while executing macros, registers or
+		other not typed commands.
+
+'makeef'	Errorfile to be used for ":make".  "##" is replaced with a
+		unique number.  Avoids that two Vim sessions overwrite each
+		others errorfile.  The Unix default is "/tmp/vim##.err"; for
+		Amiga "t:vim##.Err, for others "vim##.err".
+
+'matchtime'	1/10s of a second to show a matching paren, when 'showmatch'
+		is set.  Like Nvi.
+
+'mousehide'	Hide mouse pointer in GUI when typing text.
+
+'nrformats'	Defines what bases Vim will consider for numbers when using
+		the CTRL-A and CTRL-X commands.  Default: "hex,octal".
+
+'shellxquote'	Add extra quotes around the whole shell command, including
+		redirection.
+
+'softtabstop'	Make typing behave like tabstop is set at this value, without
+		changing the value of 'tabstop'.  Makes it more easy to keep
+		'ts' at 8, while still getting four spaces for a <Tab>.
+
+'titlestring'	String for the window title, when not empty.  (Version 5.2:
+		this string is used literally, a newline can be used to make
+		two lines.)
+
+'verbose'	Level of verbosity.  Makes it possible to show which .vimrc,
+		.exrc, .viminfo files etc. are used for initializing.  Also
+		to show autocommands that are being executed.  Can also be set
+		by using the "-V" command-line argument.
+
+
+New command-line arguments				*added-cmdline-args*
+--------------------------
+
+|-U|		Set the gvimrc file to be used.  Like "-u" for the vimrc.
+
+|-V|		Set the 'verbose' option.  E.g. "vim -V10".
+
+|-N|		Start in non-compatible mode.
+
+|-C|		Start in compatible mode.
+
+|-Z|		Start in restricted mode, disallow shell commands.  Can also
+		be done by calling the executable "rvim".
+
+|-h|		Show usage information and exit.
+
+
+Various additions					*added-various*
+-----------------
+
+Added support for SNiFF+ connection (submitted by Toni Leherbauer).  Vim can
+be used as an editor for SNiFF.  No documentation available...
+
+For producing a bug report, the bugreport.vim script has been included.
+Can be used with ":so $VIMRUNTIME/bugreport.vim", which creates the file
+"bugreport.txt" in the current directory. |bugs|
+
+Added range to ":normal" command.  Now you can repeat the same command for
+each line in the range.  |:normal-range|
+
+Included support for the Farsi language (Shiran).  Only when enabled at
+compile time.  See |farsi|.
+
+==============================================================================
+				 IMPROVEMENTS		*improvements-5*
+
+Performance:
+- When 'showcmd' was set, mappings would execute much more slowly because the
+  output would be flushed very often.  Helps a lot when executing the "life"
+  macros with 'showcmd' set.
+- Included patches for binary searching in tags file (David O'Neill).
+  Can be disabled by resetting the 'tagbsearch' option.
+- Don't update the ruler when repeating insert (slowed it down a lot).
+- For Unix, file name expansion is now done internally instead of starting a
+  shell for it.
+- Expand environment variables with expand_env(), instead of calling the
+  shell.  Makes ":so $VIMRUNTIME/syntax/syntax.vim" a LOT faster.
+- Reduced output for cursor positioning: Use CR-LF for moving to first few
+  columns in next few lines;  Don't output CR twice when using termios.
+- Optimized cursor positioning.  Use CR, BS and NL when it's shorter than
+  absolute cursor positioning.
+- Disable redrawing while repeating insert "1000ii<Esc>".
+- Made "d$" or "D" for long lines a lot faster (delete all characters at once,
+  instead of one by one).
+- Access option table by first letter, instead of searching from start.
+- Made setting special highlighting attributes a lot faster by using
+  highlight_attr[], instead of searching in the 'highlight' string.
+- Don't show the mode when redrawing is disabled.
+- When setting an option, only redraw the screen when required.
+- Improved performance of Ex commands by using a lookup table for the first
+  character.
+
+Options:
+'cinoptions'	Added 'g' flag, for C++ scope declarations.
+'cpoptions'	Added 'E' flag: Disallow yanking, deleting, etc. empty text
+		area.  Default is to allow empty yanks.  When 'E' is included,
+		"y$" in an empty line now is handled as an error (Vi
+		compatible).
+		Added 'j' flag: Only add two spaces for a join after a '.',
+		not after a '?' or '!'.
+		Added 'A' flag: don't give ATTENTION message.
+		Added 'L' flag: When not included, and 'list' is set,
+		'textwidth' formatting works like 'list' is not set.
+		Added 'W' flag:  Let ":w!" behave like Vi: don't overwrite
+		readonly files, or a file owned by someone else.
+'highlight'	Added '@' flag, for '@' characters after the last line on the
+		screen, and '$' at the end of the line when 'list' is set.
+		Added 'i' flag: Set highlighting for 'incsearch'.  Default
+		uses "IncSearch" highlight group, which is linked to "Visual".
+		Disallow 'h' flag in 'highlight' (wasn't used anymore since
+		3.0).
+'guifont'	Win32 GUI only: When set to "*" brings up a font requester.
+'guipty'	Default on, because so many people need it.
+'path'		Can contain wildcards, and "**" for searching a whole tree.
+'shortmess'	Added 'I' flag to avoid the intro message.
+'viminfo'	Added '%' flag: Store buffer list in viminfo file.
+
+- Increased defaults for 'maxmem' and 'maxmemtot' for Unix and Win32.  Most
+  machines have much more RAM now that prices have dropped.
+- Implemented ":set all&", set all options to their default value. |:set|
+
+Swap file:
+- Don't create a swap file for a readonly file.  Then create one on the first
+  change.  Also create a swapfile when the amount of memory used is getting
+  too high. |swap-file|
+- Make swap file "hidden", if possible.  On Unix this is done by prepending a
+  dot to the swap file name.  When long file names are used, the DJGPP and
+  Win32 versions also prepend a dot, in case a file on a mounted Unix file
+  system is edited.  |:swapname|  On MSDOS the hidden file attribute is NOT
+  set, because this causes problems with share.exe.
+- 'updatecount' always defaults to non-zero, also for Vi compatible mode.
+  This means there is a swap file, which can be used for recovery.
+
+Tags:
+- Included ctags 2.0 (Darren Hiebert).  The syntax for static tags changed
+  from
+	{tag}:{fname}	{fname}	{command}
+  to
+	{tag}	{fname}	{command};"	file:
+  Which is both faster to parse, shorter and Vi compatible.  The old format is
+  also still accepted, unless disabled in src/feature.h (see OLD_STATIC_TAGS).
+  |tags-file-format|
+- Completion of tags now also includes static tags for other files, at the
+  end.
+- Included "shtags" from Stephen Riehm.
+- When finding a matching tag, but the file doesn't exist, continue searching
+  for another match.  Helps when using the same tags file (with links) for
+  different versions of source code.
+- Give a tag with a global match in the current file a higher priority than a
+  global match in another file.
+
+Included xxd version V1.8 (Juergen Weigert).
+
+Autocommands:
+- VimLeave autocommands are executed after writing the viminfo file, instead
+  of before.  |VimLeave|
+- Allow changing autocommands while executing them.  This allows for
+  self-modifying autocommands.  (idea from Goldberg)
+- When using autocommands with two or more patterns, could not split
+  ":if/:endif" over two lines.  Now all matching autocommands are executed in
+  one do_cmdline().
+- Autocommands no longer change the command repeated with ".".
+- Search patterns are restored after executing autocommands.  This avoids
+  that the 'hlsearch' highlighting is messed up by autocommands.
+- When trying to execute an autocommand, also try matching the pattern with
+  the short file name.  Helps when short file name is different from full
+  file name (expanded symbolic links). |autocmd-patterns|
+- Made the output of ":autocmd" shorter and look better.
+- Expand <sfile> in an ":autocmd" when it is defined.  |<sfile>|
+- Added "nested" flag to ":autocmd", allows nesting.  |autocmd-nested|
+- Added [group] argument to ":autocmd".  Overrides the currently set group.
+  |autocmd-groups|
+- new events:
+  |BufUnload|		before a buffer is unloaded
+  |BufDelete|		before a buffer is deleted from the buffer list
+  |FileChangedShell|	when a file's modification time has changed after
+			executing a shell command
+  |User|		user-defined autocommand
+- When 'modified' was set by a BufRead* autocommand, it was reset again
+  afterwards.  Now the ":set modified" is remembered.
+
+GUI:
+- Improved GUI scrollbar handling when redrawing is slower than the scrollbar
+  events are generated.
+- "vim -u NONE" now also stops loading the .gvimrc and other GUI inits.  |-u|
+  Use "-U" to use another gvimrc file.  |-U|
+- Handle CTRL-C for external command, also for systems where "setsid()" is
+  supported.
+- When starting the GUI, restrict the window size to the screen size.
+- The default menus are read from $VIMRUNTIME/menu.vim.  This allows for a
+  customized default menu.  |menu.vim|
+- Improved the default menus.  Added File/Print, a Window menu, Syntax menu,
+  etc.
+- Added priority to the ":menu" command.  Now each menu can be put in a place
+  where you want it, independent of the order in which the menus are defined.
+  |menu-priority|
+
+Give a warning in the intro screen when running the Win32 console version on
+Windows 95 because there are problems using this version under Windows 95.
+|win32-problems|
+
+Added 'e' flag for ":substitute" command: Don't complain when not finding a
+match (Campbell).  |:s|
+
+When using search commands in a mapping, only the last one is kept in the
+history.  Avoids that the history is trashed by long mappings.
+
+Ignore characters after "ex", "view" and "gvim" when checking startup mode.
+Allows the use of "gvim5" et. al.  |gvim| "gview" starts the GUI in readonly
+mode.  |gview|
+
+When resizing windows, the cursor is kept in the same relative position, if
+possible.  (Webb)
+
+":all" and ":ball" no longer close and then open a window for the same buffer.
+Avoids losing options, jumplist, and other info.
+
+"-f" command-line argument is now ignored if Vim was compiled without GUI.
+|-f|
+
+In Visual block mode, the right mouse button picks up the nearest corner.
+
+Changed default mappings for DOS et al.  Removed the DOS-specific mappings,
+only use the Windows ones.  Added Shift-Insert, Ctrl-Insert, Ctrl-Del and
+Shift-Del.
+
+Changed the numbers in the output of ":jumps", so you can see where {count}
+CTRL-O takes you.  |:jumps|
+
+Using "~" for $HOME now works for all systems.  |$HOME|
+
+Unix: Besides using CTRL-C, also use the INTR character from the tty settings.
+Somebody has INTR set to DEL.
+
+Allow a <LF> in a ":help" command argument to end the help command, so another
+command can follow.
+
+Doing "%" on a line that starts with "   #if" didn't jump to matching "#else".
+Don't recognize "#if", "#else" etc. for '%' when 'cpo' contains the '%' flag.
+|%|
+
+Insert mode expansion with "CTRL-N", "CTRL-P" and "CTRL-X" improved
+|ins-completion|:
+- 'complete' option added.
+- When 'nowrapscan' is set, and no match found, report the searched direction
+  in the error message.
+- Repeating CTRL-X commands adds following words/lines after the match.
+- When adding-expansions, accept single character matches.
+- Made repeated CTRL-X CTRL-N not break undo, and "." repeats the whole
+  insertion.  Also fixes not being able to backspace over a word that has been
+  inserted with CTRL-N.
+
+When copying characters in Insert mode from previous/next line, with CTRL-E or
+CTRL-Y, 'textwidth' is no longer used.  |i_CTRL-E|
+
+Commands that move in the arglist, like ":n" and ":rew", keep the old cursor
+position of the file (this is mostly Vi compatible).
+
+Vim now remembers the '< and '> marks for each buffer.  This fixes a problem
+that a line-delete in one buffer invalidated the '< and '> marks in another
+buffer.  |'<|
+
+For MSDOS, Unix and OS/2: When $VIM not set, use the path from the executable.
+When using the executable path for $VIM, remove "src/" when present.  Should
+make Vim find the docs and syntax files when it is run directly after
+compiling.  |$VIM|
+
+When quitting Visual mode with <Esc>, the cursor is put at start of the Visual
+area (like after executing an operator).
+
+Win32 and Unix version: Removed 1100 character limit on external commands.
+
+Added possibility to include a space in a ":edit +command" argument, by
+putting a backslash before it.  |+cmd|
+
+After recovery, BufReadPost autocommands are applied.  |:recover|
+
+Added color support for "os2ansi", OS/2 console. (Slootman) |os2ansi|
+
+Allow "%:p:h" when % is empty.  |:_%|
+
+Included "<sfile>": file name from the ":source" command.  |<sfile>|
+
+Added "<Bslash>" special character.  Helps for avoiding multiple backslashes
+in mappings and menus.
+
+In a help window, a double-click jumps to the tag under the cursor (like
+CTRL-]).
+
+<C-Left> and <C-Right> now work like <S-Left> and <S-Right>, move a word
+forward/backward (Windows compatible). |<C-Left>|
+
+Removed the requirement for a ":version" command in a .vimrc file.  It wasn't
+used for anything.  You can use ":if" to handle differences between versions.
+|:version|
+
+For MS-DOS, Win32 and OS/2: When comparing file names for autocommands, don't
+make a difference between '/' and '\' for path separator.
+
+New termcap options:
+"mb": blink.  Can only be used by assigning it to one of the other highlight
+      options.  |t_mb|
+"bc": backspace character.  |t_bc|
+"nd": Used for moving the cursor right in the GUI, to avoid removing one line
+      of pixels from the last bold character.  |t_nd|
+"xs": highlighting not erased by overwriting, for hpterm.  Combined with
+      'weirdinvert'.  Visual mode works on hpterm now.  |t_xs|
+
+Unix: Set time of patch and backup file same as original file.  (Hiebert).
+
+Amiga: In QuickFix mode no longer opens another window.  Shell commands can be
+used now.
+
+Added decmouse patches from David Binette.  Can now use Dec and Netterm mouse.
+But only when enabled at compile time.
+
+Added '#' register: Alternate file name |quote#|.  Display '#' register with
+":dis" command. |:display|
+
+Removed ':' from 'isfname' default for Unix.  Check for "://" in a file name
+anyway.  Also check for ":\\", for MS-DOS.
+
+Added count to "K"eyword command, when 'keywordprg' is "man", is inserted in
+the man command.  "2K" results in "!man 2 <cword>".  |K|
+
+When using "gf" on a relative path name, remove "../" from the file name, like
+it's done for file names in the tags file. |gf|
+
+When finishing recording, don't make the recorded register the default put
+register.
+
+When using "!!", don't put ":5,5!" on the command-line, but ":.!".  And some
+other enhancements to replace the line number with "." or "$" when possible.
+
+MSDOS et al.: Renamed $VIM/viminfo to $VIM/_viminfo.  It's more consistent:
+.vimrc/_vimrc and .viminfo/_viminfo
+
+For systems where case doesn't matter in file names (MSDOS, Amiga), ignore
+case while sorting file names.  For buffer names too.
+
+When reading from stdin doesn't work, read from stderr (helps for "foo | xargs
+vim").
+
+32 bit MS-DOS version: Replaced csdpmi3 by csdpmi4.
+
+Changed <C-Left> and <C-Right> to skip a WORD instead of a word.
+
+Warning for changed modified time when overwriting a file now also works on
+other systems than Unix.
+
+Unix: Changed the defaults for configure to be the same as the defaults for
+Makefile: include GUI, Perl, and Python.
+
+Some versions of Motif require "-lXpm".  Added check for this in configure.
+
+Don't add "-L/usr/lib" to the link line, causes problems on a few systems.
+
+==============================================================================
+			     COMPILE TIME CHANGES	*compile-changes-5*
+
+When compiling, allow a choice for minimal, normal or maximal features in an
+easy way, by changing a single line in src/feature.h.
+The DOS16 version has been compiled with minimal features to avoid running
+out of memory too quickly. |dos16|
+The Win32, DJGPP, and OS/2 versions use maximal features, because they have
+enough memory.
+The Amiga version is available with normal and maximal features.
+
+Added "make test" to Unix version Makefile.  Allows for a quick check if most
+"normal" commands work properly.  Also tests a few specific commands.
+
+Added setlocale() with codepage support for DJGPP version.
+
+autoconf:
+- Added autoconf check for -lXdmcp.
+- Included check for -lXmu, no longer needed to edit the Makefile for this.
+- Switched to autoconf 2.12.
+- Added configure check for <poll.h>.  Seems to be needed when including
+  Perl on Linux?
+- termlib is now checked before termcap.
+- Added configure check for strncasecmp(), stricmp() and strnicmp().  Added
+  vim_stricmp() for when there's no library function for stricmp().
+- Use "datadir" in configure, instead of our own check for HELPDIR.
+
+Removed "make proto" from Makefile.manx.  Could not make it work without a lot
+of #ifdefs.
+
+Removed "proto/" from paths in proto.h.  Needed for the Mac port.
+
+Drastically changed Makefile.mint.  Now it includes the Unix Makefile.
+
+Added support for Dos16 in Makefile.b32 (renamed Makefile.b32 to Makefile.bor)
+
+All source files are now edited with a tabstop of 8 instead of 4, which is
+better when debugging and using other tools.  'softtabstop' is set to 4, to
+make editing easier.
+
+Unix: Added "link.sh" script, which removes a few unnecessary libraries from
+the link command.
+
+Don't use HPUX digraphs by default, but only when HPUX_DIGRAPHS is defined.
+|digraphs-default|
+
+==============================================================================
+				 BUG FIXES		*bug-fixes-5*
+
+Note:	Some of these fixes may only apply to test versions which were
+	created after version 4.6, but before 5.0.
+
+
+When doing ":bdel", try going to the next loaded buffer.  Don't rewind to the
+start of the buffer list.
+
+mch_isdir() for Unix returned TRUE for "" on some systems.
+
+Win32: 'shell' set to "mksnt/sh.exe" breaks ":!" commands.  Don't use
+backslashes in the temp file names.
+
+On linux, with a FAT file system, could get spurious "file xxx changed since
+editing started" messages, because the time is rounded off to two seconds
+unexpectedly.
+
+Crash in GUI, when selecting a word (double click) and then extend until an
+empty line.
+
+For systems where isdigit() can't handle characters > 255, get_number() caused
+a crash when moving the mouse during the prompt for recovery.
+
+In Insert mode, "CTRL-O P" left the cursor on the last inserted character.
+Now the cursor is left after the last putted character.
+
+When quickfix found an error type other than 'e' or 'w', it was never printed.
+
+A setting for 'errorfile' in a .vimrc overruled the "-q errorfile" argument.
+
+Some systems create a file when generating a temp file name.  Filtering would
+then create a backup file for this, which was never deleted.  Now no backup
+file is made when filtering.
+
+simplify_filename() could remove a ".." after a link, resulting in the wrong
+file name.  Made simplify_filename also work for MSDOS.  Don't use it for
+Amiga, since it doesn't have "../".
+
+otherfile() was unreliable when using links.  Could think that reading/writing
+was for a different file, when it was the same.
+
+Pasting with mouse in Replace mode didn't replace anything.
+
+Window height computed wrong when resizing a window with an autocommand (could
+cause a crash).
+
+":s!foo!bar!" wasn't possible (Vi compatible).
+
+do_bang() freed memory twice when called recursively, because of autocommands
+(test11).  Thanks to Electric Fence!
+
+"v$d" on an empty line didn't remove the "-- VISUAL --" mode message from the
+command-line, and inverted the cursor.
+
+":mkexrc" didn't check for failure to open the file, causing a crash.
+(Felderhoff).
+
+Win32 mch_write() wrote past fixed buffer, causing terminal keys no longer to
+be recognized.  Both console and GUI version.
+
+Athena GUI: Crash when removing a menu item.  Now Vim doesn't crash, but the
+reversing of the menu item is still wrong.
+
+Always reset 'list' option for the help window.
+
+When 'scrolloff' is non-zero, a 'showmatch' could cause the shown match to be
+in the wrong line and the window to be scrolled (Acevedo).
+
+After ":set all&", 'lines' and 'ttytype' were still non-default, because the
+defaults never got set.  Now the defaults for 'lines' and 'columns' are set
+after detecting the window size.  'term' and 'ttytype' defaults are set when
+detecting the terminal type.
+
+For (most) non-Unix systems, don't add file names with illegal characters when
+expanding.  Fixes "cannot open swapfile" error when doing ":e *.burp", when
+there is no match.
+
+In X11 GUI, drawing part of the cursor obscured the text.  Now the text is
+drawn over the cursor, like when it fills the block. (Seibert)
+
+when started with "-c cmd -q errfile", the cursor would be left in line 1.
+Now a ":cc" is done after executing "cmd".
+
+":ilist" never ignored case, even when 'ignorecase' set.
+
+"vim -r file" for a readonly file, then making a change, got ATTENTION message
+in insert mode, display mixed up until <Esc> typed.  Also don't give ATTENTION
+message after recovering a file.
+
+The abbreviation ":ab #i #include" could not be removed.
+
+CTRL-L completion (longest common match) on command-line didn't work properly
+for case-insensitive systems (MS-DOS, Windows, etc.).  (suggested by Richard
+Kilgore).
+
+For terminals that can hide the cursor ("vi" termcap entry), resizing the
+window caused the cursor to disappear.
+
+Using an invalid mark in an Ex address didn't abort the command.
+
+When 'smarttab' set, would use 'shiftround' when inserting a TAB after a
+space.  Now it always rounds to a tabstop.
+
+Set '[ and '] marks for ":copy", ":move", ":append", ":insert", ":substitute"
+and ":change".  (Acevedo).
+
+"d$" in an empty line still caused an error, even when 'E' is not in
+'cpoptions'.
+
+Help files were stored in the viminfo buffer list without a path.
+
+GUI: Displaying cursor was not synchronized with other displaying.  Caused
+several display errors.  For example, when the last two lines in the file
+start with spaces, "dd" on the last line copied text to the (then) last line.
+
+Win32: Needed to type CTRL-SHIFT-- to get CTRL-_.
+
+GUI: Moving the cursor forwards over bold text would remove one column of bold
+pixels.
+
+X11 GUI: When a bold character in the last column was scrolled up or down, one
+column of pixels would not be copied.
+
+Using <BS> to move the cursor left can sometimes erase a character.  Now use
+"le" termcap entry for this.
+
+Keyword completion with regexp didn't work.  e.g., for "b.*crat".
+
+Fixed: With CTRL-O that jumps to another file, cursor could end up just after
+the line.
+
+Amiga: '$' was missing from character recognized as wildcards, causing $VIM
+sometimes not to be expanded.
+
+":change" didn't adjust marks for deleted lines.
+
+":help [range]" didn't work.  Also for [pattern], [count] and [quotex].
+
+For 'cindent'ing, typing "class::method" doesn't align like a label when the
+second ':' is typed.
+When inserting a CR with 'cindent' set (and a bunch of other conditions) the
+cursor went to a wrong location.
+'cindent' was wrong for a line that ends in '}'.
+'cindent' was wrong after "else {".
+
+While editing the cmdline in the GUI, could not use the mouse to select text
+from the command-line itself.
+
+When deleting lines, marks in tag stack were only adjusted for the current
+window, not for other windows on the same buffer.
+
+Tag guessing could find a function "some_func" instead of the "func" we were
+looking for.
+
+Tags file name relative to the current file didn't work.
+
+":g/pat2/s//pat2/g", causing the number of subs to be reported, used to cause
+a scroll up.  Now you no longer have to hit <CR>.
+
+X11 GUI: Selecting text could cause a crash.
+
+32 bit DOS version: CTRL-C in external command killed Vim.  When SHELL is set
+to "sh.exe", external commands didn't work.  Removed using of command.com, no
+longer need to set 'shellquote'.
+
+Fixed crash when using ":g/pat/i".
+
+Fixed (potential) crash for X11 GUI, when using an X selection.  Was giving a
+pointer on the stack to a callback function, now it's static.
+
+Using "#" and "*" with an operator didn't work.  E.g. "c#".
+
+Command-line expansion didn't work properly after ":*". (Acevedo)
+
+Setting 'weirdinvert' caused highlighting to be wrong in the GUI.
+
+":e +4 #" didn't work, because the "4" was in unallocated memory (could cause
+a crash).
+
+Cursor position was wrong for ":e #", after ":e #" failed, because of changes
+to the buffer.
+
+When doing ":buf N", going to a buffer that was edited with ":view", the
+readonly flag was reset.  Now make a difference between ":e file" and ":buf
+file": Only set/reset 'ro' for the first one.
+
+Avoid |hit-enter| prompt when not able to write viminfo on exit.
+
+When giving error messages in the terminal where the GUI was started, GUI
+escape codes would be written to the terminal.  In an xterm this could be seen
+as a '$' after the message.
+
+Mouse would not work directly after ":gui", because full_screen isn't set,
+which causes starttermcap() not to do its work.
+
+'incsearch' did not scroll the window in the same way as the actual search.
+When 'nowrap' set, incsearch didn't show a match when it was off the side of
+the screen.  Now it also shows the whole match, instead of just the cursor
+position (if possible).
+
+":unmap", ":unab" and ":unmenu" did not accept a double quote, it was seen as
+the start of a comment.  Now it's Vi compatible.
+
+Using <Up><Left><Left><Up> in the command-line, when there is no previous
+cmdline in the history, inserted a NUL on the command-line.
+
+"i<Esc>" when on a <Tab> in column 0 left the cursor in the wrong place.
+
+GUI Motif: When adding a lot of menu items, the menu bar goes into two rows.
+Deleting menu items, reducing the number of rows, now also works.
+
+With ":g/pat/s//foo/c", a match in the first line was scrolled off of the
+screen, so you could not see it.
+When using ":s//c", with 'nowrap' set, a match could be off the side of the
+screen, so you could not see it.
+
+When 'helpfile' was set to a fixed, non-absolute path in feature.h, Vim would
+crash.  mch_Fullname can now handle file names in read-only memory. (Lottem)
+
+When using CTRL-A or CTRL-@ in Insert mode, there could be strange effects
+when using CTRL-D next.  Also, when repeating inserted text that included "0
+CTRL-D" or "^ CTRL-D" this didn't work. (Acevedo)
+Using CTRL-D after using CTRL-E or CTRL-Y in Insert mode that inserted a '0'
+or '^', removed the '0' or '^' and more indent.
+
+The command "2".p" caused the last inserted text to be executed as commands.
+(Acevedo)
+
+Repeating the insert of "CTRL-V 048" resulted in "^@" to be inserted.
+
+Repeating Insert completion could fail if there are special characters in the
+text. (Acevedo)
+
+":normal /string<CR>" caused the window to scroll.  Now all ":normal" commands
+are executed without scrolling messages.
+
+Redo of CTRL-E or CTRL-Y in Insert mode interpreted special characters as
+commands.
+
+Line wrapping for 'tw' was done one character off for insert expansion
+inserts.
+
+buffer_exists() function didn't work properly for buffer names with a symbolic
+link in them (e.g. when using buffer_exists(#)).
+
+Removed the "MOTIF_COMMENT" construction from Makefile.  It now works with
+FreeBSD make, and probably with NeXT make too.
+
+Matching the 'define' and 'include' arguments now honor the settings for
+'ignorecase'. (Acevedo)
+
+When one file shown in two windows, Visual selection mixed up cursor position
+in current window and other window.
+
+When doing ":e file" from a help file, the 'isk' option wasn't reset properly,
+because of a modeline in the help file.
+
+When doing ":e!", a cursor in another window on the same buffer could become
+invalid, leading to "ml_get: invalid lnum" errors.
+
+Matching buffer name for when expanded name has a different path from not
+expanded name (Brugnara).
+
+Normal mappings didn't work after an operator.  For example, with ":map Q gq",
+"QQ" didn't work.
+
+When ":make" resulted in zero errors, a "No Errors" error message was given
+(which breaks mappings).
+
+When ":sourcing" a file, line length was limited to 1024 characters.  CTRL-V
+before <EOL> was not handled Vi compatible.  (Acevedo)
+
+Unexpected exit for X11 GUI, caused by SAVE_YOURSELF event.  (Heimann)
+
+CTRL-X CTRL-I only found one match per line. (Acevedo)
+When using an illegal CTRL-X key in Insert mode, the CTRL-X mode message
+was stuck.
+
+Finally managed to ignore the "Quit" menu entry of the Window manager!  Now
+Vim only exists when there are no changed buffers.
+
+Trying to start the GUI when $DISPLAY is not set resulted in a crash.
+When $DISPLAY is not set and gvim starts vim, title was restored to "Thanks
+for flying Vim".
+When $DISPLAY not set, starting "gvim" (dropping back to vim) and then
+selecting text with the mouse caused a crash.
+
+"J", with 'joinspaces' set, on a line ending in ". ", caused one space too
+many to be added.  (Acevedo)
+
+In insert mode, a CTRL-R {regname} which didn't insert anything left the '"'
+on the screen.
+
+":z10" didn't work. (Clapp)
+
+"Help "*" didn't work.
+
+Renamed a lot of functions, to avoid clashes with POSIX name space.
+
+When adding characters to a line, making it wrap, the following lines were
+sometimes not shifted down (e.g. after a tag jump).
+
+CTRL-E, with 'so' set and cursor on last line, now does not move cursor as
+long as the last line is on the screen.
+
+When there are two windows, doing "^W+^W-" in the bottom window could cause
+the status line to be doubled (not redrawn correctly).
+
+This command would hang: ":n `cat`".  Now connect stdin of the external
+command to /dev/null, when expanding.
+
+Fixed lalloc(0,) error for ":echo %:e:r".  (Acevedo)
+
+The "+command" argument to ":split" didn't work when there was no file name.
+
+When selecting text in the GUI, which is the output of a command-line command
+or an external command, the inversion would sometimes remain.
+
+GUI: "-mh 70" argument was broken.  Now, when menuheight is specified, it is
+not changed anymore.
+
+GUI: When using the scrollbar or mouse while executing an external command,
+this caused garbage characters.
+
+Showmatch sometimes jumped to the wrong position.  Was caused by a call to
+findmatch() when redrawing the display (when syntax highlighting is on).
+
+Search pattern "\(a *\)\{3} did not work correctly, also matched "a a".
+Problem with brace_count not being decremented.
+
+Wildcard expansion added too many non-matching file names.
+
+When 'iskeyword' contains characters like '~', "*" and "#" didn't work
+properly. (Acevedo)
+
+On Linux, on a FAT file system, modification time can change by one second.
+Avoid a "file has changed" warning for a one second difference.
+
+When using the page-switching in an xterm, Vim would position the cursor on
+the last line of the window on exit.  Also removed the cursor positioning for
+":!" commands.
+
+":g/pat/p" command (partly) overwrote the command.  Now the output is on a
+separate line.
+
+With 'ic' and 'scs' set, a search for "Keyword", ignore-case matches were
+highlighted too.
+
+"^" on a line with only white space, put cursor beyond the end of the line.
+
+When deleting characters before where insertion started ('bs' == 2), could not
+use abbreviations.
+
+CTRL-E at end of file puts cursor below the file, in Visual mode, when 'so' is
+non-zero.  CTRL-E didn't work when 'so' is big and the line below the window
+wraps.  CTRL-E, when 'so' is non-zero, at end of the file, caused jumping
+up-down.
+
+":retab" didn't work well when 'list' is set.
+
+Amiga: When inserting characters at the last line on the screen, causing it
+to wrap, messed up the display.  It appears that a '\n' on the last line
+doesn't always cause a scroll up.
+
+In Insert mode "0<C-D><C-D>" deleted an extra character, because Vim thought
+that the "0" was still there. (Acevedo)
+
+"z{count}l" ignored the count.  Also for "zh" et. al. (Acevedo)
+
+"S" when 'autoindent' is off didn't delete leading white space.
+
+"/<Tab>" landed on the wrong character when 'incsearch' is set.
+
+Asking a yes/no question could cause a |hit-enter| prompt.
+
+When the file consists of one long line (>4100 characters), making changes
+caused various errors and a crash.
+
+DJGPP version could not save long lines (>64000) for undo.
+
+"yw" on the last char in the file didn't work.  Also fixed "6x" at the end of
+the line.  "6X" at the start of a line fails, but does not break a mapping.  In
+general, a movement for an operator doesn't beep or flush a mapping, but when
+there is nothing to operate on it beeps (this is Vi compatible).
+
+"m'" and "m`" now set the '' mark at the cursor position.
+
+Unix: Resetting of signals for external program didn't work, because SIG_DFL
+and NULL are the same!  For "!!yes|dd count=1|, the yes command kept on
+running.
+
+Partly fixed: Unix GUI: Typeahead while executing an external command was lost.
+Now it's not lost while the command is producing output.
+
+Typing <S-Tab> in Insert mode, when it isn't mapped, inserted "<S-Tab>".  Now
+it works like a normal <Tab>, just like <C-Tab> and <M-Tab>.
+
+Redrawing ruler didn't check for old value correctly (caused UMR warnings in
+Purify).
+
+Negative array index in finish_viminfo_history().
+
+":g/^/d|mo $" deleted all the lines.  The ":move" command now removes the
+:global mark from the moved lines.
+
+Using "vG" while the last line in the window is a "@" line, didn't update
+correctly.  Just the "v" showed "~" lines.
+
+"daw" on the last char of the file, when it's a space, moved the cursor beyond
+the end of the line.
+
+When 'hlsearch' was set or reset, only the current buffer was redrawn, while
+this affects all windows.
+
+CTRL-^, positioning the cursor somewhere from 1/2 to 1 1/2 screen down the
+file, put the cursor at the bottom of the window, instead of halfway.
+
+When scrolling up for ":append" command, not all windows were updated
+correctly.
+
+When 'hlsearch' is set, and an auto-indent is highlighted, pressing <Esc>
+didn't remove the highlighting, although the indent was deleted.
+
+When 'ru' set and 'nosc', using "$j" showed a wrong ruler.
+
+Under Xfree 3.2, Shift-Tab didn't work (wrong keysym is used).
+
+Mapping <S-Tab> didn't work.  Changed the key translations to use the shortest
+key code possible.  This makes the termcode translations and mappings more
+consistent.  Now all modifiers work in all combinations, not only with <Tab>,
+but also with <Space>, <CR>, etc.
+
+For Unix, restore three more signals.  And Vim catches SIGINT now, so CTRL-C
+in Ex mode doesn't make Vim exit.
+
+""a5Y" yanked 25 lines instead of 5.
+
+"vrxxx<Esc>" in an empty line could not be undone.
+
+A CTRL-C that breaks ":make" caused the errorfile not to be read (annoying
+when you want to handle what ":make" produced so far).
+
+":0;/pat" didn't find "pat" in line 1.
+
+Search for "/test/s+1" at first char of file gave bottom-top message, or
+didn't work at all with 'nowrapscan'.
+
+Bug in viminfo history.  Could cause a crash on exit.
+
+":print" didn't put cursor on first non-blank in line.
+
+":0r !cat </dev/null" left cursor in line zero, with very strange effects.
+
+With 'showcmd' set and 'timeoutlen' set to a few seconds, trick to position
+the cursor leftwards didn't work.
+
+AIX stty settings were restored to cs5 instead of cs8 (Winn).
+
+File name completion didn't work for "zsh" versions that put spaces between
+file names, instead of NULs.
+
+Changed "XawChain*" to "XtChain*", should work for more systems.
+
+Included quite a few fixes for rightleft mode (Lottem).
+
+Didn't ask to |hit-enter| when GUI is started and error messages are printed.
+
+When trying to edit a file in a non-existent directory, ended up with editing
+"No file".
+
+"gqap" to format a paragraph did too much redrawing.
+
+When 'hlsearch' set, only the current window was updated for a new search
+pattern.
+
+Sometimes error messages on startup didn't cause a |hit-enter| prompt,
+because of autocommands containing an empty line.
+
+Was possible to select part of the window in the border, below the command
+line.
+
+'< and '> marks were not at the correct position after linewise Visual
+selection.
+
+When translating a help argument to "CTRL-x", prepend or append a '_', when
+applicable.
+
+Blockwise visual mode wasn't correct when moving vertically over a special
+character (displayed as two screen characters).
+
+Renamed "struct option" to "struct vimoption" to avoid name clash with GNU
+getopt().
+
+":abclear" didn't work (but ":iabclear" and ":cabclear" did work).
+
+When 'nowrap' used, screen wasn't always updated correctly.
+
+"vim -c split file" displayed extra lines.
+
+After starting the GUI, searched the termcap for a "gui" term.
+
+When 'hls' used, search for "^$" caused a hang.
+When 'hls' was set, an error in the last regexp caused trouble.
+
+Unix: Only output an extra <EOL> on exit when outputted something in the
+alternate screen, or when there is a message that needs to be cleared.
+
+"/a\{" did strange things, depending on previous search.
+
+"c}" only redrew one line (with -u NONE).
+
+For mappings, CTRL-META-A was shown as <M-^A> instead of <MC-A>, while :map
+only accepts <MC-A>.  Now <M-C-A> is shown.
+
+Unix: When using full path name in a tags file, which contains a link, and
+'hidden' set and jumping to a tag in the current file, would get bogus
+ATTENTION message.  Solved by always expanding file names, even when starting
+with '/'.
+
+'hlsearch' highlighting of special characters (e.g., a TAB) didn't highlight
+the whole thing.
+
+"r<CR>" didn't work correctly on the last char of a line.
+
+sometimes a window resize or other signal caused an endless loop, involving
+set_winsize().
+
+"vim -r" didn't work, it would just hang (using tgetent() while 'term' is
+empty).
+
+"gk" while 'nowrap' set moved two lines up.
+
+When windows are split, a message that causes a scroll-up messed up one of the
+windows, which required a CTRL-L to be typed.
+
+Possible endless loop when using shell command in the GUI.
+
+Menus defined in the .vimrc were removed when GUI started.
+
+Crash when pasting with the mouse in insert mode.
+
+Crash with ":unmenu *" in .gvimrc for Athena.
+
+"5>>" shifted 5 lines 5 times, instead of 1 time.
+
+CTRL-C when getting a prompt in ":global" didn't interrupt.
+
+When 'so' is non-zero, and moving the scrollbar completely to the bottom,
+there was a lot of flashing.
+
+GUI: Scrollbar ident must be long for DEC Alpha.
+
+Some functions called vim_regcomp() without setting reg_magic, which could
+lead to unpredictable magicness.
+
+Crash when clicking around the status line, could get a selection with a
+backwards range.
+
+When deleting more than one line characterwise, the last character wasn't
+deleted.
+
+GUI: Status line could be overwritten when moving the scrollbar quickly (or
+when 'wd' is non-zero).
+
+An ESC at the end of a ":normal" command caused a wait for a terminal code to
+finish.  Now, a terminal code is not recognized when its start comes from a
+mapping or ":normal" command.
+
+Included patches from Robert Webb for GUI.  Layout of the windows is now done
+inside Vim, instead of letting the layout manager do this.  Makes Vim work
+with Lesstif!
+
+UMR warning in set_expand_context().
+
+Memory leak: b_winlnum list was never freed.
+
+Removed TIOCLSET/TIOCLGET code from os_unix.c.  Was changing some of the
+terminal settings, and looked like it wasn't doing anything good.  (suggested
+by Juergen Weigert).
+
+Ruler overwrote "is a directory" message.  When starting up, and 'cmdheight'
+set to > 1, first message could still be in the last line.
+
+Removed prototype for putenv() from proto.h, it's already in osdef2.h.in.
+
+In replace mode, when moving the cursor and then backspacing, wrong characters
+were inserted.
+
+Win32 GUI was checking for a CTRL-C too often, making it slow.
+
+Removed mappings for MS-DOS that were already covered by commands.
+
+When visually selecting all lines in a file, cursor at last line, then "J".
+Gave ml_get errors.  Was a problem with scrolling down during redrawing.
+
+When doing a linewise operator, and then an operator with a mouse click, it
+was also linewise, instead of characterwise.
+
+When 'list' is set, the column of the ruler was wrong.
+
+Spurious error message for "/\(b\+\)*".
+
+When visually selected many lines, message from ":w file" disappeared when
+redrawing the screen.
+
+":set <M-b>=^[b", then insert "^[b", waited for another character.  And then
+inserted "<M-b>" instead of the real <M-b> character.  Was trying to insert
+K_SPECIAL x NUL.
+
+CTRL-W ] didn't use count to set window height.
+
+GUI: "-font" command-line argument didn't override 'guifont' setting from
+.gvimrc. (Acevedo)
+
+GUI: clipboard wasn't used for "*y".  And some more Win32/X11 differences
+fixed for the clipboard (Webb).
+
+Jumping from one help file to another help file, with 'compatible' set,
+removed the 'help' flag from the buffer.
+
+File-writable bit could be reset when using ":w!" for a readonly file.
+
+There was a wait for CTRL-O n in Insert mode, because the search pattern was
+shown.
+Reduced wait, to allow reading a message, from 10 to 3 seconds.  It seemed
+nothing was happening.
+
+":recover" found same swap file twice.
+
+GUI: "*yy only worked the second time (when pasting to an xterm)."
+
+DJGPP version (dos32): The system flags were cleared.
+
+Dos32 version: Underscores were sometimes replaced with y-umlaut (Levin).
+
+Version 4.1 of ncurses can't handle tputs("", ..).  Avoid calling tputs() with
+an empty string.
+
+<S-Tab> in the command-line worked like CTRL-P when no completion started yet.
+Now it does completion, last match first.
+
+Unix: Could get annoying "can't write viminfo" message after doing "su".  Now
+the viminfo file is overwritten, and the user set back to the original one.
+
+":set term=builtin_gui" started the GUI in a wrong way.  Now it's not
+allowed anymore.  But "vim -T gui" does start the GUI correctly now.
+
+GUI: Triple click after a line only put last char in selection, when it is a
+single character word.
+
+When the window is bigger than the screen, the scrolling up of messages was
+wrong (e.g. ":vers", ":hi").  Also when the bottom part of the window was
+obscured by another window.
+
+When using a wrong option only an error message is printed, to avoid that the
+usage information makes it scroll off the screen.
+
+When exiting because of not being able to read from stdin, didn't preserve the
+swap files properly.
+
+Visual selecting all chars in more than one line, then hit "x" didn't leave an
+empty line.  For one line it did leave an empty line.
+
+Message for which autocommand is executing messed up file write message (for
+FileWritePost event).
+
+"vim -h" included "-U" even when GUI is not available, and "-l" when lisp is
+not available.
+
+Crash for ":he <C-A>" (command-line longer than screen).
+
+":s/this/that/gc", type "y" two times, then undo, did reset the modified
+option, even though the file is still modified.
+
+Empty lines in a tags file caused a ":tag" to be aborted.
+
+When hitting 'q' at the more prompt for ":menu", still scrolled a few lines.
+
+In an xterm that uses the bold trick a single row of characters could remain
+after an erased bold character.  Now erase one extra char after the bold char,
+like for the GUI.
+
+":pop!" didn't work.
+
+When the reading a buffer was interrupted, ":w" should not be able to
+overwrite the file, ":w!" is required.
+
+":cf%" caused a crash.
+
+":gui longfilename", when forking is enabled, could leave part of the
+longfilename at the shell prompt.
+
+==============================================================================
+VERSION 5.1						*version-5.1*
+
+Improvements made between version 5.0 and 5.1.
+
+This was mostly a bug-fix release, not many new features.
+
+
+Changed							*changed-5.1*
+-------
+
+The expand() function now separates file names with <NL> instead of a space.
+This avoids problems for file names with embedded spaces.  To get the old
+result, use substitute(expand(foo), "\n", " ", "g").
+
+For Insert-expanding dictionaries allow a backslash to be used for
+wildchars.  Allows expanding "ze\kra", when 'isk' includes a backslash.
+
+New icon for the Win32 GUI.
+
+":tag", ":tselect" etc. only use the argument as a regexp when it starts
+with '/'.  Avoids that ":tag xx~" gives an error message: "No previous sub.
+regexp".  Also, when the :tag argument contained wildcard characters, it was
+not Vi compatible.
+When using '/', the argument is taken literally too, with a higher priority,
+so it's found before wildcard matches.
+Only when the '/' is used are matches with different case found, even though
+'ignorecase' isn't set.
+Changed "g^]" to only do ":tselect" when there is more than on matching tag.
+
+Changed some of the default colors, because they were not very readable on a
+dark background.
+
+A character offset to a search pattern can move the cursor to the next or
+previous line.  Also fixes that "/pattern/e+2" got stuck on "pattern" at the
+end of a line.
+
+Double-clicks in the status line do no longer start Visual mode.  Dragging a
+status line no longer stops Visual mode.
+
+Perl interface: Buffers() and Windows() now use more logical arguments, like
+they are used in the rest of Vim (Moore).
+
+Init '" mark to the first character of the first line.  Makes it possible to
+use '" in an autocommand without getting an error message.
+
+
+Added							*added-5.1*
+-----
+
+"shell_error" internal variable: result of last shell command.
+
+":echohl" command: Set highlighting for ":echo".
+
+'S' flag in 'highlight' and StatusLineNC highlight group: highlighting for
+status line of not-current window.  Default is to use bold for current
+window.
+
+Added buffer_name() and buffer_number() functions (Aaron).
+Added flags argument "g" to substitute() function (Aaron).
+Added winheight() function.
+
+Win32: When an external command starts with "start ", no console is opened
+for it (Aaron).
+
+Win32 console: Use termcap codes for bold/reverse based on the current
+console attributes.
+
+Configure check for "strip". (Napier)
+
+CTRL-R CTRL-R x in Insert mode: Insert the contents of a register literally,
+instead of as typed.
+
+Made a few "No match" error messages more informative by adding the pattern
+that didn't match.
+
+"make install" now also copies the macro files.
+
+tools/tcltags, a shell script to generate a tags file from a TCL file.
+
+"--with-tlib" setting for configure.  Easy way to use termlib: "./configure
+--with-tlib=termlib".
+
+'u' flag in 'cino' for setting the indent for contained () parts.
+
+When Win32 OLE version can't load the registered type library, ask the user
+if he wants to register Vim now. (Erhardt)
+Win32 with OLE: When registered automatically, exit Vim.
+Included VisVim 1.1b, with a few enhancements and the new icon (Heiko
+Erhardt).
+
+Added patch from Vince Negri for Win32s support.  Needs to be compiled with
+VC 4.1!
+
+Perl interface: Added $curbuf.  Rationalized Buffers() and Windows().
+(Moore) Added "group" argument to Msg().
+
+Included Perl files in DOS source archive.  Changed Makefile.bor and
+Makefile.w32 to support building a Win32 version with Perl included.
+
+Included new Makefile.w32 from Ken Scott.  Now it's able to make all Win32
+versions, including OLE, Perl and Python.
+
+Added CTRL-W g ] and CTRL-W g ^]: split window and do g] or g^].
+
+Added "g]" to always do ":tselect" for the ident under the cursor.
+Added ":tjump" and ":stjump" commands.
+Improved listing of ":tselect" when tag names are a bit long.
+
+Included patches for the Macintosh version.  Also for Python interface.
+(St-Amant)
+
+":buf foo" now also restores cursor column, when the buffer was used before.
+
+Adjusted the Makefile for different final destinations for the syntax files
+and scripts (for Debian Linux).
+
+Amiga: $VIM can be used everywhere.  When $VIM is not defined, "VIM:" is
+used.  This fixes that "VIM:" had to be assigned for the help files, and
+$VIM set for the syntax files.  Now either of these work.
+
+Some xterms send vt100 compatible function keys F1-F4.  Since it's not
+possible to detect this, recognize both type of keys and translate them to
+<F1> - <F4>.
+
+Added "VimEnter" autocommand.  Executed after loading all the startup stuff.
+
+BeOS version now also runs on Intel CPUs (Seibert).
+
+
+Fixed							*fixed-5.1*
+-----
+
+":ts" changed position in the tag stack when cancelled with <CR>.
+":ts" changed the cursor position for CTRL-T when cancelled with <CR>.
+":tn" would always jump to the second match.	Was using the wrong entry in
+the tag stack.
+Doing "tag foo", then ":tselect", overwrote the original cursor position in
+the tag stack.
+
+"make install" changed the vim.1 manpage in a wrong way, causing "doc/doc"
+to appear for the documentation files.
+
+When compiled with MAX_FEAT, xterm mouse handling failed.  Was caused by DEC
+mouse handling interfering.
+
+Was leaking memory when using selection in X11.
+
+CTRL-D halfway a command-line left some characters behind the first line(s)
+of the listing.
+
+When expanding directories for ":set path=", put two extra backslashes
+before a space in a directory name.
+
+When 'lisp' set, first line of a function would be indented.  Now its indent
+is set to zero.  And use the indent of the first previous line that is at
+the same () level.  Added test33.
+
+"so<Esc>u" in an empty file didn't work.
+
+DOS: "seek error in swap file write" errors, when using DOS 6.2 share.exe,
+because the swap file was made hidden.  It's no longer hidden.
+
+":global" command would sometimes not execute on a matching line.  Happened
+when a data block is full in ml_replace().
+
+For AIX use a tgetent buffer of 2048 bytes, instead of 1024.
+
+Win32 gvim now only sets the console size for external commands to 25x80
+on Windows 95, not on NT.
+
+Win32 console: Dead key could cause a crash, because of a missing "WINAPI"
+(Deshpande).
+
+The right mouse button started Visual mode, even when 'mouse' is empty, and
+in the command-line, a left click moved the cursor when 'mouse' is empty.
+In Visual mode, 'n' in 'mouse' would be used instead of 'v'.
+
+A blinking cursor or focus change cleared a non-Visual selection.
+
+CTRL-Home and CTRL-End didn't work for MS-DOS versions.
+
+Could include NUL in 'iskeyword', causing a crash when doing insert mode
+completion.
+
+Use _dos_commit() to flush the swap file to disk for MSDOS 16 bit version.
+
+In mappings, CTRL-H was replaced by the backspace key code.  This caused
+problems when it was used as text, e.g. ":map _U :%s/.^H//g<CR>".
+
+":set t_Co=0" was not handled like a normal term.  Now it's translated into
+":set t_Co=", which works.
+
+For ":syntax keyword" the "transparent" option did work, although not
+mentioned in the help.  But synID() returned wrong name.
+
+"gqG" in a file with one-word-per-line (e.g. a dictionary) was very slow and
+not interruptible.
+
+"gq" operator inserted screen lines in the wrong situation.  Now screen
+lines are inserted or deleted when this speeds up displaying.
+
+cindent was wrong when an "if" contained "((".
+
+'r' flag in 'viminfo' was not used for '%'.  Could get files in the buffer
+list from removable media.
+
+Win32 GUI with OLE: if_ole_vc.mak could not be converted into a project.
+Hand-edited to fix this...
+
+With 'nosol' set, doing "$kdw" below an empty line positioned the cursor at
+the end of the line.
+
+Dos32 version changed "\dir\file" into "/dir/file", to work around a DJGPP
+bug.  That bug appears to have been fixed, therefore this translation has
+been removed.
+
+"/^*" didn't work (find '*' in first column).
+
+"<afile>" was not always set for autocommands.  E.g., for ":au BufEnter *
+let &tags = expand("<afile>:p:h") . "/tags".
+
+In an xterm, the window may be a child of the outer xterm window.  Use the
+parent window when getting the title and icon names. (Smith)
+
+When starting with "gvim -bg black -fg white", the value of 'background' is
+only set after reading the .gvimrc file.  This causes a ":syntax on" to use
+the wrong colors.  Now allow using ":gui" to open the GUI window and set the
+colors.  Previously ":gui" in a gvimrc crashed Vim.
+
+tempname() returned the same name all the time, unless the file was actually
+created.  Now there are at least 26 different names.
+
+File name used for <afile> was sometimes full path, sometimes file name
+relative to current directory.
+
+When 'background' was set after the GUI window was opened, it could change
+colors that were set by the user in the .gvimrc file.  Now it only changes
+colors that have not been set by the user.
+
+Ignore special characters after a CSI in the GUI version.  These could be
+interpreted as special characters in a wrong way. (St-Amant)
+
+Memory leak in farsi code, when using search or ":s" command.
+Farsi string reversing for a mapping was only done for new mappings.  Now it
+also works for replacing a mapping.
+
+Crash in Win32 when using a file name longer than _MAX_PATH. (Aaron)
+
+When BufDelete autocommands were executed, some things for the buffer were
+already deleted (esp. Perl stuff).
+
+Perl interface: Buffer specific items were deleted too soon; fixes "screen
+no longer exists" messages.  (Moore)
+
+The Perl functions didn't set the 'modified' flag.
+
+link.sh did not return an error on exit, which may cause Vim to start
+installing, even though there is no executable to install. (Riehm)
+
+Vi incompatibility: In Vi "." redoes the "y" command.  Added the 'y' flag to
+'cpoptions'.  Only for 'compatible' mode.
+
+":echohl" defined a new group, when the argument was not an existing group.
+
+"syn on" and ":syn off" could move the cursor, if there is a hidden buffer
+that is shorter that the current cursor position.
+
+The " mark was not set when doing ":b file".
+
+When a "nextgroup" is used with "skipwhite" in syntax highlighting, space at
+the end of the line made the nextgroup also be found in the next line.
+
+":he g<CTRL-D>", then ":" and backspace to the start didn't redraw.
+
+X11 GUI: "gvim -rv" reversed the colors twice on Sun.  Now Vim checks if the
+result is really reverse video (background darker than foreground).
+
+"cat link.sh | vim -" didn't set syntax highlighting.
+
+Win32: Expanding "file.sw?" matched ".file.swp".  This is an error of
+FindnextFile() that we need to work around.  (Kilgore)
+
+"gqgq" gave an "Invalid lnum" error on the last line.
+Formatting with "gq" didn't format the first line after a change of comment
+leader.
+
+There was no check for out-of-memory in win_alloc().
+
+"vim -h" didn't mention "-register" and "-unregister" for the OLE version.
+
+Could not increase 'cmdheight' when the last window is only one line.  Now
+other windows are also made smaller, when necessary.
+
+Added a few {} to avoid "suggest braces around" warnings from gcc 2.8.x.
+Changed return type of main() from void to int. (Nam)
+
+Using '~' twice in a substitute pattern caused a crash.
+
+"syn on" and ":syn off" could scroll the window, if there is a hidden buffer
+that is shorter that the current cursor position.
+
+":if 0 | if 1 | endif | endif" didn't work.  Same for ":while" and "elseif".
+
+With two windows on modified files, with 'autowrite' set, cursor in second
+window, ":qa" gave a warning for the file in the first window, but then
+auto-wrote the file in the second window. (Webb)
+
+Win32 GUI scrollbar could only handle 32767 lines.  Also makes the
+intellimouse wheel use the configurable number of scrolls. (Robinson)
+
+When using 'patchmode', and the backup file is on another partition, the file
+copying messed up the write-file message.
+
+GUI X11: Alt-Backspace and Alt-Delete didn't work.
+
+"`0" could put the cursor after the last character in the line, causing
+trouble for other commands, like "i".
+
+When completing tags in insert mode with ^X^], some matches were skipped,
+because the compare with other tags was wrong.  E.g., when "mnuFileSave" was
+already there, "mnuFile" would be skipped. (Negri)
+
+When scrolling up/down, a syntax item with "keepend" didn't work properly.
+Now the flags are also stored for the syntax state a the start of each line.
+
+When 'ic' was changed while 'hlsearch' is on, there was no redraw to show the
+effect.
+
+Win32 GUI: Don't display "No write since last chance" in a message box, but in
+the Vim window.
+
+==============================================================================
+VERSION 5.2						*version-5.2*
+
+Improvements made between version 5.1 and 5.2.
+
+
+Long lines editable					*long-lines*
+-------------------
+
+A single long line that doesn't fit in the window doesn't show a line of @@@
+anymore.  Redrawing starts at a character further on in the line, such that
+the text around the cursor can be seen.  This makes it possible to edit these
+long lines when wrapping is on.
+
+
+File browser added					*file-browser-5.2*
+------------------
+
+The Win32, Athena and Motif GUI bring up a file requester if the user asks to
+":browse" for the ":e", ":w", ":r", ":so", ":redirect" and
+":mkexrc/vimrc/vsess" commands.  ::browse e /foo/bar" opens the requester in
+the /foo/bar directory, so you can have nice mapping rhs's like ":browse so
+$vim/macros".  If no initial dir specified for ":browse e", can be compiled to
+either begin in the current directory, or that of the current buffer. (Negri
+and Kahn)
+Added the 'browsedir' option, with value "current", "last" or "buffer".  Tells
+whether a browse dialog starts in last used dir, dir of current buffer, or
+current dir.  ":browse w" is unaffected.
+The default menus have been changed to use the ":browse" command.
+
+
+Dialogs added						*dialogs-added*
+-------------
+
+Added the ":confirm" command.  Works on ":e", ":q", ":w", ":cl".  Win32,
+Athena and Motif GUI uses a window-dialog.  All other platforms can use
+prompt in command-line.  ":confirm qa" offers a choice to save all modified
+files.
+
+confirm() function: allows user access to the confirm engine.
+
+Added 'v' flag to 'guioptions'.  When included, a vertical button layout is
+always used for the Win32 GUI dialog.  Otherwise, a horizontal layout is
+preferred.
+
+Win32 GUI: ":promptfind" and ":promptrepl" pop up a dialog to find/replace.
+To be used from a menu entry. (Negri)
+
+
+Popup menu added					*popup-menu-added*
+----------------
+
+When the 'mousemodel' option is set to "popup", the right mouse button
+displays the top level menu headed with "PopUp" as pop-up context menu.  The
+"PopUp" menu is not displayed in the normal menu bar.  This currently only
+works for Win32 and Athena GUI.
+
+
+Select mode added					*new-Select-mode*
+-----------------
+
+A new mode has been added: "Select mode".  It is like Visual mode, but typing
+a printable character replaces the selection.
+- CTRL-G can be used to toggle between Visual mode and Select mode.
+- CTRL-O can be used to switch from Select mode to Visual mode for one command.
+- Added 'selectmode' option: tells when to start Select mode instead of Visual
+  mode.
+- Added 'mousemodel' option: Change use of mouse buttons.
+- Added 'keymodel' option: tells to use shifted special keys to start a
+  Visual or Select mode selection.
+- Added ":behave".  Can be used to quickly set 'selectmode', 'mousemodel'
+  and 'keymodel' for MS-Windows and xterm behavior.
+- The xterm-like selection is now called modeless selection.
+- Visual mode mappings and menus are used in Select mode.  They automatically
+  switch to Visual mode first.  Afterwards, reselect the area, unless it was
+  deleted.  The "gV" command can be used in a mapping to skip the reselection.
+- Added the "gh", "gH" and "g^H" commands: start Select (highlight) mode.
+- Backspace in Select mode deletes the selected area.
+
+"mswin.vim" script.  Sets behavior mostly like MS-Windows.
+
+
+Session files added					*new-session-files*
+-------------------
+
+":mks[ession]" acts like "mkvimrc", but also writes the full filenames of the
+currently loaded buffers and current directory, so that :so'ing the file
+re-loads those files and cd's to that directory.  Also stores and restores
+windows.  File names are made relative to session file.
+The 'sessionoptions' option sets behavior of ":mksession". (Negri)
+
+
+User defined functions and commands			*new-user-defined*
+-----------------------------------
+
+Added user defined functions.  Defined with ":function" until ":endfunction".
+Called with "Func()".  Allows the use of a variable number of arguments.
+Included support for local variables "l:name".  Return a value with ":return".
+See |:function|.
+Call a function with ":call".  When using a range, the function is called for
+each line in the range. |:call|
+"macros/justify.vim" is an example of using user defined functions.
+User functions do not change the last used search pattern or the command to be
+redone with ".".
+'maxfuncdepth' option.  Restricts the depth of function calls.  Avoids trouble
+(crash because of out-of-memory) when a function uses endless recursion.
+
+User definable Ex commands: ":command", ":delcommand" and ":comclear".
+(Moore)  See |user-commands|.
+
+
+New interfaces						*interfaces-5.2*
+--------------
+
+Tcl interface. (Wilken)  See |tcl|.
+Uses the ":tcl", ":tcldo" and "tclfile" commands.
+
+Cscope support. (Kahn) (Sekera)  See |cscope|.
+Uses the ":cscope" and ":cstag" commands.  Uses the options 'cscopeprg',
+'cscopetag', 'cscopetagorder' and 'cscopeverbose'.
+
+
+New ports						*ports-5.2*
+---------
+
+Amiga GUI port. (Nielsen)  Not tested much yet!
+
+RISC OS version. (Thomas Leonard)  See |riscos|.
+This version can run either with a GUI or in text mode, depending upon where
+it is invoked.
+Deleted the "os_archie" files, they were not working anyway.
+
+
+Multi-byte support					*new-multi-byte*
+------------------
+
+MultiByte support for Win32 GUI. (Baek)
+The 'fileencoding' option decides how the text in the file is encoded.
+":ascii" works for multi-byte characters.  Multi-byte characters work on
+Windows 95, even when using the US version. (Aaron)
+Needs to be enabled in feature.h.
+This has not been tested much yet!
+
+
+New functions						*new-functions-5.2*
+-------------
+
+|browse()|	puts up a file requester when available. (Negri)
+|escape()|	escapes characters in a string with a backslash.
+|fnamemodify()|	modifies a file name.
+|input()|	asks the user to enter a line. (Aaron)  There is a separate
+		history for lines typed for the input() function.
+|argc()|
+|argv()|	can be used to access the argument list.
+|winbufnr()|	buffer number of a window. (Aaron)
+|winnr()|	window number. (Aaron)
+|matchstr()|	Return matched string.
+|setline()|	Set a line to a string value.
+
+
+New options						*new-options-5.2*
+-----------
+
+'allowrevins'	Enable the CTRL-_ command in Insert and Command-line mode.
+'browsedir'	Tells in which directory a browse dialog starts.
+'confirm'	when set, :q :w and :e commands always act as if ":confirm"
+		is used.  (Negri)
+'cscopeprg'
+'cscopetag'
+'cscopetagorder'
+'cscopeverbose'	Set the |cscope| behavior.
+'filetype'	RISC-OS specific type of file.
+'grepformat'
+'grepprg'	For the |:grep| command.
+'keymodel'	Tells to use shifted special keys to start a Visual or Select
+		mode selection.
+'listchars'	Set character to show in 'list' mode for end-of-line, tabs and
+		trailing spaces. (partly by Smith) Also sets character to
+		display if a line doesn't fit when 'nowrap' is set.
+'matchpairs'	Allows matching '<' with '>', and other single character
+		pairs.
+'mousefocus'	Window focus follows mouse (partly by Terhaar).  Changing the
+		focus with a keyboard command moves the pointer to that
+		window.  Also move the pointer when changing the window layout
+		(split window, change window height, etc.).
+'mousemodel'	Change use of mouse buttons.
+'selection'	When set to "inclusive" or "exclusive", the cursor can go one
+		character past the end of the line in Visual or Select mode.
+		When set to "old" the old behavior is used.  When
+		"inclusive", the character under the cursor is included in the
+		operation.  When using "exclusive", the new "ve" entry of
+		'guicursor' is used.  The default is a vertical bar.
+'selectmode'	Tells when to start Select mode instead of Visual mode.
+'sessionoptions' Sets behavior of ":mksession". (Negri)
+'showfulltag'	When completing a tag in Insert mode, show the tag search
+		pattern (tidied up) as a choice as well (if there is one).
+'swapfile'	Whether to use a swap file for a buffer.
+'syntax'	When it is set, the syntax by that name is loaded.  Allows for
+		setting a specific syntax from a modeline.
+'ttymouse'	Allows using xterm mouse codes for terminals which name
+		doesn't start with "xterm".
+'wildignore'	List of patterns for files that should not be completed at
+		all.
+'wildmode'	Can be used to set the type of expansion for 'wildchar'.
+		Replaces the CTRL-T command for command line completion.
+		Don't beep when listing all matches.
+'winaltkeys'	Win32 and Motif GUI.  When "yes", ALT keys are handled
+		entirely by the window system.  When "no", ALT keys are never
+		used by the window system.  When "menu" it depends on whether
+		a key is a menu shortcut.
+'winminheight'	Minimal height for each window.  Default is 1.  Set to 0 if
+		you want zero-line windows.  Scrollbar is removed for
+		zero-height windows. (Negri)
+
+
+
+New Ex commands						*new-ex-commands-5.2*
+---------------
+
+|:badd|		Add file name to buffer list without side effects.  (Negri)
+|:behave|	Quickly set MS-Windows or xterm behavior.
+|:browse|	Use file selection dialog.
+|:call|		Call a function, optionally with a range.
+|:cnewer|
+|:colder|	To access a stack of quickfix error lists.
+|:comclear|	Clear all user-defined commands.
+|:command|	Define a user command.
+|:continue|	Go back to ":while".
+|:confirm|	Ask confirmation if something unexpected happens.
+|:cscope|	Execute cscope command.
+|:cstag|	Use cscope to jump to a tag.
+|:delcommand|	Delete a user-defined command.
+|:delfunction|	Delete a user-defined function.
+|:endfunction|	End of user-defined function.
+|:function|	Define a user function.
+|:grep|		Works similar to ":make". (Negri)
+|:mksession|	Create a session file.
+|:nohlsearch|	Stop 'hlsearch' highlighting for a moment.
+|:Print|	This is Vi compatible.  Does the same as ":print".
+|:promptfind|	Search dialog (Win32 GUI).
+|:promptrepl|	Search/replace dialog (Win32 GUI).
+|:return|	Return from a user-defined function.
+|:simalt|	Win32 GUI: Simulate alt-key pressed.  (Negri)
+|:smagic|	Like ":substitute", but always use 'magic'.
+|:snomagic|	Like ":substitute", but always use 'nomagic'.
+|:tcl|		Execute TCL command.
+|:tcldo|	Execute TCL command for a range of lines.
+|:tclfile|	Execute a TCL script file.
+|:tearoff|	Tear-off a menu (Win32 GUI).
+|:tmenu|
+|:tunmenu|	Win32 GUI: menu tooltips.  (Negri)
+|:star|	:*	Execute a register.
+
+
+Changed							*changed-5.2*
+-------
+
+Renamed functions:
+		buffer_exists()	   -> bufexists()
+		buffer_name()      -> bufname()
+		buffer_number()    -> bufnr()
+		file_readable()    -> filereadable()
+		highlight_exists() -> hlexists()
+		highlightID()      -> hlID()
+		last_buffer_nr()   -> bufnr("$")
+The old ones are still there, for backwards compatibility.
+
+The CTRL-_ command in Insert and Command-line mode is only available when the
+new 'allowrevins' option is set.  Avoids that people who want to type SHIFT-_
+accidentally enter reverse Insert mode, and don't know how to get out.
+
+When a file name path in ":tselect" listing is too long, remove a part in the
+middle and put "..." there.
+
+Win32 GUI: Made font selector appear inside Vim window, not just any odd
+place. (Negri)
+
+":bn" skips help buffers, unless currently in a help buffer. (Negri)
+
+When there is a status line and only one window, don't show '^' in the status
+line of the current window.
+
+":*" used to be used for "'<,'>", the Visual area.  But in Vi it's used as an
+alternative for ":@".  When 'cpoptions' includes '*' this is Vi compatible.
+
+When 'insertmode' is set, using CTRL-O to execute a mapping will work like
+'insertmode' was not set.  This allows "normal" mappings to be used even when
+'insertmode' is set.
+
+When 'mouse' was set already (e.g., in the .vimrc file), don't automatically
+set 'mouse' when the GUI starts.
+
+Removed the 'N', 'I' and 'A' flags from the 'mouse' option.
+
+Renamed "toggle option" to "boolean option".  Some people thought that ":set
+xyz" would toggle 'xyz' on/off each time.
+
+The internal variable "shell_error" contains the error code from the shell,
+instead of just 0 or 1.
+
+When inserting or replacing, typing CTRL-V CTRL-<CR> used to insert "<C-CR>".
+That is not very useful.  Now the CTRL key is ignored and a <CR> is inserted.
+Same for all other "normal" keys with modifiers.  Mapping these modified key
+combinations is still possible.
+In Insert mode, <C-CR> and <S-Space> can be inserted by using CTRL-K and then
+the special character.
+
+Moved "quotes" file to doc/quotes.txt, and "todo" file to doc/todo.txt.  They
+are now installed like other documentation files.
+
+winheight() function returns -1 for a non-existing window.  It used to be
+zero, but that is a valid height now.
+
+The default for 'selection' is "inclusive", which makes a difference when
+using "$" or the mouse to move the cursor in Visual mode.
+
+":q!" does not exit when there are changed buffers which are hidden.  Use
+":qa!" to exit anyway.
+
+Disabled the Perl/Python/Tcl interfaces by default.  Not many people use them
+and they make the executable a lot bigger.  The internal scripting language is
+now powerful enough for most tasks.
+
+The strings from the 'titlestring' and 'iconstring' options are used
+untranslated for the Window title and icon.  This allows for including a <CR>.
+Previously a <CR> would be shown as "^M" (two characters).
+
+When a mapping is started in Visual or Select mode which was started from
+Insert mode (the mode shows "(insert) Visual"), don't return to Insert mode
+until the mapping has ended.  Makes it possible to use a mapping in Visual
+mode that also works when the Visual mode was started from Select mode.
+
+Menus in $VIMRUNTIME/menu.vim no longer overrule existing menus.  This helps
+when defining menus in the .vimrc file, or when sourcing mswin.vim.
+
+Unix: Use /var/tmp for .swp files, if it exists.  Files there survive a
+reboot (at least on Linux).
+
+
+Added							*added-5.2*
+-----
+
+--with-motif-lib configure argument.  Allows for using a static Motif library.
+
+Support for mapping numeric keypad +,-,*,/ keys. (Negri)
+When not mapped, they produce the normal character.
+
+Win32 GUI: When directory dropped on Gvim, cd there and edit new buffer.
+(Negri)
+
+Win32 GUI: Made CTRL-Break work as interrupt, so that CTRL-C can be
+used for mappings.
+
+In the output of ":map", highlight the "*" to make clear it's not part of the
+rhs. (Roemer)
+
+When showing the Visual area, the cursor is not switched off, so that it can
+be located.  The Visual area is now highlighted with a grey background in the
+GUI.  This makes the cursor visible when it's also reversed.
+
+Win32: When started with single full pathname (e.g. via double-clicked file),
+cd to that file's directory. (Negri)
+
+Win32 GUI: Tear-off menus, with ":tearoff <menu-name>" command. (Negri)
+'t' option to 'guioptions': Add tearoff menu items for Win32 GUI and Motif.
+It's included by default.
+Win32 GUI: tearoff menu with submenus is indicated with a ">>". (Negri)
+
+Added ^Kaa and ^KAA digraphs.
+Added "euro" symbol to digraph.c. (Corry)
+
+Support for Motif menu shortcut keys, using '&' like MS-Windows (Ollis).
+Other GUIs ignore '&' in a menu name.
+
+DJGPP: Faster screen updating (John Lange).
+
+Clustering of syntax groups ":syntax cluster" (Bigham).
+Including syntax files: ":syntax include" (Bigham).
+
+Keep column when switching buffers, when 'nosol' is set (Radics).
+
+Number function for Perl interface.
+
+Support for Intellimouse in Athena GUI. (Jensen)
+
+":sleep" also accepts an argument in milliseconds, when "m" is used.
+
+Added 'p' flag in 'guioptions': Install callbacks for enter/leave window
+events.  Makes cursor blinking work for Terhaar, breaks it for me.
+
+"--help" and "--version" command-line arguments.
+
+Non-text in ":list" output is highlighted with NonText.
+
+Added text objects: "i(" and "i)" as synonym for "ib".  "i{" and "i}" as
+synonym for "iB".  New: "i<" and "i>", to select <thing>.  All this also for
+"a" objects.
+
+'O' flag in 'shortmess': message for reading a file overwrites any previous
+message. (Negri)
+
+Win32 GUI: 'T' flag in 'guioptions': switch toolbar on/off.
+Included a list with self-made toolbar bitmaps.  (Negri)
+
+Added menu priority for sub-menus.  Implemented for Win32 and Motif GUI.
+Display menu priority with ":menu" command.
+Default and Syntax menus now include priority for items.  Allows inserting
+menu items in between the default ones.
+
+When the 'number' option is on, highlight line numbers with the LineNr group.
+
+"Ignore" highlight group: Text highlighted with this is made blank.  It is
+used to hide special characters in the help text.
+
+Included Exuberant Ctags version 2.3, with C++ support, Java support and
+recurse into directories. (Hiebert)
+
+When a tags file is not sorted, and this is detected (in a simplistic way), an
+error message is given.
+
+":unlet" accepts a "!", to ignore non-existing variables, and accepts more
+than one argument. (Roemer)
+Completion of variable names for ":unlet". (Roemer)
+
+When there is an error in a function which is called by another function, show
+the call stack in the error message.
+
+New file name modifiers:
+":.": reduce file name to be relative to current dir.
+":~": reduce file name to be relative to home dir.
+":s?pat?sub?": substitute "pat" with "sub" once.
+":gs?pat?sub?": substitute "pat" with "sub" globally.
+
+New configure arguments: --enable-min-features and --enable-max-features.
+Easy way to switch to minimum or maximum features.
+
+New compile-time feature: modify_fname.  For file name modifiers, e.g,
+"%:p:h".  Can be disabled to save some code (16 bit DOS).
+
+When using whole-line completion in Insert mode, and 'cindent' is set, indent
+the line properly.
+
+MSDOS and Win32 console: 'guicursor' sets cursor thickness. (Negri)
+
+Included new set of Farsi fonts. (Shiran)
+
+Accelerator text now also works in Motif.  All menus can be defined with & for
+mnemonic and TAB for accelerator text.  They are ignored on systems that don't
+support them.
+When removing or replacing a menu, compare the menu name only up to the <Tab>
+before the mnemonic.
+
+'i' and 'I' flags after ":substitute": ignore case or not.
+
+"make install" complains if the runtime files are missing.
+
+Unix: When finding an existing swap file that can't be opened, mention the
+owner of the file in the ATTENTION message.
+
+The 'i', 't' and 'k' options in 'complete' now also print the place where they
+are looking for matches. (Acevedo)
+
+"gJ" command: Join lines without inserting a space.
+
+Setting 'keywordprg' to "man -s" is handled specifically.  The "-s" is removed
+when no count given, the count is added otherwise.  Configure checks if "man
+-s 2 read" works, and sets the default for 'keywordprg' accordingly.
+
+If you do a ":bd" and there is only one window open, Vim tries to move to a
+buffer of the same type (i.e. non-help to non-help, help to help), for
+consistent behavior to :bnext/:bprev. (Negri)
+
+Allow "<Nop>" to be used as the rhs of a mapping.  ":map xx <Nop>", maps "xx"
+to nothing at all.
+
+In a ":menu" command, "<Tab>" can be used instead of a real tab, in the menu
+path.  This makes it more easy to type, no backslash needed.
+
+POSIX compatible character classes for regexp patterns: [:alnum:], [:alpha:],
+[:blank:], [:cntrl:], [:digit:], [:graph:], [:lower:], [:print:], [:punct:],
+[:space:], [:upper:] and [:xdigit:]. (Briscoe)
+
+regexp character classes (for fast syntax highlight matching):
+	digits:	    \d [0-9]		\D  not digit (Roemer)
+	hex:	    \x [0-9a-fA-F]	\X  not hex
+	octal:	    \o [0-7]		\O  not octal
+	word:	    \w [a-zA-Z0-9_]	\W  not word
+	head:	    \h [a-zA-Z_]	\H  not head
+	alphabetic: \a [a-zA-Z]		\A  not alphabetic
+	lowercase:  \l [a-z]		\L  not lowercase
+	uppercase:  \u [A-Z]		\U  not uppercase
+
+":set" now accepts "+=", |^=" and "-=": add or remove parts of a string
+option, add or subtract a number from a number option.  A comma is
+automagically inserted or deleted for options that are a comma separated list.
+
+Filetype feature, for autocommands.  Uses a file type instead of a pattern to
+match a file.  Currently only used for RISC OS.  (Leonard)
+
+In a pattern for an autocommand, environment variables can be used.  They are
+expanded when the autocommand is defined.
+
+"BufFilePre" and "BufFilePost" autocommand evens: Before and after applying
+the ":file" command to change the name of a buffer.
+"VimLeavePre" autocommand event: before writing the .viminfo file.
+
+For autocommands argument: <abuf> is buffer number, like <afile>.
+
+Made syntax highlighting a bit faster when scrolling backwards, by keeping
+more syncing context.
+
+Win32 GUI: Made scrolling faster by avoiding a redraw when deleting or
+inserting screen lines.
+
+GUI: Made scrolling faster by not redrawing the scrollbar when the thumb moved
+less than a pixel.
+
+Included ":highlight" in bugreport.vim.
+
+Created install.exe program, for simplistic installation on DOS and
+MS-Windows.
+
+New register: '_', the black hole.  When writing to it, nothing happens.  When
+reading from it, it's always empty.  Can be used to avoid a delete or change
+command to modify the registers, or reduce memory use for big changes.
+
+CTRL-V xff enters character by hex number.  CTRL-V o123 enters character by
+octal number. (Aaron)
+
+Improved performance of syntax highlighting by skipping check for "keepend"
+when there isn't any.
+
+Moved the mode message ("-- INSERT --") to the last line of the screen.  When
+'cmdheight' is more than one, messages will remain readable.
+
+When listing matching files, they are also sorted on 'suffixes', such that
+they are listed in the same order as CTRL-N retrieves them.
+
+synIDattr() takes a third argument (optionally), which tells for which
+terminal type to get the attributes for.  This makes it possible to run
+2html.vim outside of gvim (using color names instead of #RRGGBB).
+
+Memory profiling, only for debugging.  Prints at exit, and with "g^A" command.
+(Kahn)
+
+DOS: When using a file in the current drive, remove the drive name:
+"A:\dir\file" -> "\dir\file".  This helps when moving a session file on a
+floppy from "A:\dir" to "B:\dir".
+
+Increased number of remembered jumps from 30 to 50 per window.
+
+Command to temporarily disable 'hls' highlighting until the next search:
+":nohlsearch".
+
+"gp" and "gP" commands: like "p" and "P", but leave the cursor just after the
+inserted text.  Used for the CTRL-V command in MS-Windows mode.
+
+
+Fixed							*fixed-5.2*
+-----
+
+Win32 GUI: Could draw text twice in one place, for fake-bold text.  Removed
+this, Windows will handle the bold text anyway. (Negri)
+
+patch 5.1.1: Win32s GUI: pasting caused a crash (Negri)
+
+patch 5.1.2: When entering another window, where characters before the cursor
+have been deleted, could have a cursor beyond the end of the line.
+
+patch 5.1.3: Win32s GUI: Didn't wait for external command to finish. (Negri)
+
+patch 5.1.4: Makefile.w32 can now also be used to generate the OLE version
+(Scott).
+
+patch 5.1.5: Crashed when using syntax highlighting: cursor on a line that
+doesn't fit in the window, and splitting that line in two.
+
+patch 5.1.6: Visual highlighting bug: After ":set nowrap", go to end of line
+(so that the window scrolls horizontally), ":set wrap".  Following Visual
+selection was wrong.
+
+patch 5.1.7: When 'tagbsearch' off, and 'ignorecase' off, still could do
+binary searching.
+
+patch 5.1.8: Win32 GUI: dragging the scrollbar didn't update the ruler.
+
+patch 5.1.9: Using ":gui" in .vimrc, caused xterm cursor to disappear.
+
+patch 5.1.10: A CTRL-N in Insert mode could cause a crash, when a buffer
+without a name exists.
+
+patch 5.1.11: "make test" didn't work in the shadow directory.  Also adjusted
+"make shadow" for the links in the ctags directory.
+
+patch 5.1.12: "buf 123foo" used "123" as a count, instead as the start of a
+buffer name.
+
+patch 5.1.13: When completing file names on the command-line, reallocating the
+command-line may go wrong.
+
+patch 5.1.14: ":[nvci]unmenu" removed menu for all modes, when full menu patch
+specified.
+
+Graceful handling of NULLs in drag-dropped file list.  Handle passing NULL to
+Fullname_save(). (Negri)
+
+Win32: ":!start" to invoke a program without opening a console, swapping
+screens, or waiting for completion in either console or gui version, e.g. you
+can type ":!start winfile".  ALSO fixes "can't delete swapfile after spawning
+a shell" bug. (enhancement of Aaron patch) (Negri)
+
+Win32 GUI: Fix CTRL-X default keymapping to be more Windows-like. (Negri)
+
+Shorten filenames on startup.  If in /foo/bar, entering "vim ../bar/bang.c"
+displays "bang.c" in status bar, not "/foo/bar/bang.c"  (Negri)
+
+Win32 GUI: No copy to Windows clipboard when it's not desired.
+
+Win32s: Fix pasting from clipboard - made an assumption not valid under
+Win32s. (Negri)
+
+Win32 GUI: Speed up calls to gui_mch_draw_string() and cursor drawing
+functions. (Negri)
+
+Win32 GUI: Middle mouse button emulation now works in GUI! (Negri)
+
+Could skip messages when combining commands in one line, e.g.:
+":echo "hello" | write".
+
+Perl interpreter was disabled before executing VimLeave autocommands.  Could
+not use ":perl" in them.  (Aaron)
+
+Included patch for the Intellimouse (Aaron/Robinson).
+
+Could not set 'ls' to one, when last window has only one line.  (Mitterand)
+
+Fixed a memory leak when removing menus.
+
+After ":only" the ruler could overwrite a message.
+
+Dos32: removed changing of __system_flags.  It appears to work better when
+it's left at the default value.
+
+p_aleph was an int instead of along, caused trouble on systems where
+sizeof(int) != sizeof(long). (Schmidt)
+
+Fixed enum problems for Ultrix. (Seibert)
+
+Small redraw problem: "dd" on last line in file cleared wrong line.
+
+Didn't interpret "cmd | endif" when "cmd" starts with a range.  E.g. "if 0 |
+.d | endif".
+
+Command "+|" on the last line of the file caused ml_get errors.
+
+Memory underrun in eval_vars(). (Aaron)
+
+Don't rename files in a difficult way, except on Windows 95 (was also done on
+Windows NT).
+
+Win32 GUI: An external command that produces an error code put the error
+message in a dialog box.  had to close the window and close the dialog.  Now
+the error code is displayed in the console. (Negri)
+
+"comctl32.lib" was missing from the GUI libraries in Makefile.w32. (Battle)
+
+In Insert mode, when entering a window in Insert mode, allow the cursor to be
+one char beyond the text.
+
+Renamed machine dependent rename() to mch_rename().  Define mch_rename() to
+rename() when it works properly.
+
+Rename vim_chdir() to mch_chdir(), because it's machine dependent.
+
+When using an arglist, and editing file 5 of 4, ":q" could cause "-1 more
+files to edit" error.
+
+In if_python.c, VimCommand() caused an assertion when a do_cmdline() failed.
+Moved the Python_Release_Vim() to before the VimErrorCheck().  (Harkins)
+
+Give an error message for an unknown argument after "--".  E.g. for "vim
+--xyz".
+
+The FileChangedShell autocommand didn't set <afile> to the name of the changed
+file.
+
+When doing ":e file", causing the attention message, there sometimes was no
+hit-enter prompt.  Caused by empty line or "endif" at end of sourced file.
+
+A large number of patches for the VMS version. (Hunsaker)
+
+When CTRL-L completion (find longest match) results in a shorter string, no
+completion is done (happens with ":help").
+
+Crash in Win32 GUI version, when using an Ex "@" command, because
+LinePointers[] was used while not initialized.
+
+Win32 GUI: allow mapping of Alt-Space.
+
+Output from "vim -h" was sent to stderr.  Sending it to stdout is better, so
+one can use "vim -h | more".
+
+In command-line mode, ":vi[!]" should reload the file, just like ":e[!]".
+In Ex mode, ":vi" stops Ex mode, but doesn't reload the file.  This is Vi
+compatible.
+
+When using a ":set ls=1" in the .gvimrc file, would get a status line for a
+single window.  (Robinson)
+
+Didn't give an error message for ":set ai,xx". (Roemer)
+Didn't give an error message for ":set ai?xx", ":set ai&xx", ":set ai!xx".
+
+Non-Unix systems: That a file exists but is unreadable is recognized as "new
+file".  Now check for existence when file can't be opened (like Unix).
+
+Unix: osdef.sh didn't handle declarations where the function name is at the
+first column of the line.
+
+DJGPP: Shortening of file names didn't work properly, because get_cwd()
+returned a path with backslashes. (Negri)
+
+When using a 'comments' part where a space is required after the middle part,
+always insert a space when starting a new line.  Helps for C comments, below a
+line with "/****".
+
+Replacing path of home directory with "~/" could be wrong for file names
+with embedded spaces or commas.
+
+A few fixes for the Sniff interface. (Leherbauer)
+
+When asking to hit 'y' or 'n' (e.g. for ":3,1d"), using the mouse caused
+trouble.  Same for ":s/x/y/c" prompt.
+
+With 'nowrap' and 'list', a Tab halfway on the screen was displayed as blanks,
+instead of the characters specified with 'listchars'.  Also for other
+characters that take more than one screen character.
+
+When setting 'guifont' to an unknown font name, the previous font was lost and
+a default font would be used. (Steed)
+
+DOS: Filenames in the root directory didn't get shortened properly. (Negri)
+
+DJGPP: making a full path name out of a file name didn't work properly when
+there is no _fullpath() function. (Negri)
+
+Win32 console: ":sh" caused a crash. (Negri)
+
+Win32 console: Setting 'lines' and/or 'columns' in the _vimrc failed miserably
+(could hang Windows 95). (Negri)
+
+Win32: The change-drive function was not correct, went to the wrong drive.
+(Tsindlekht)
+
+GUI: When editing a command line in Ex mode, Tabs were sometimes not
+backspaced properly, and unprintable characters were displayed directly.
+non-GUI can still be wrong, because a system function is called for this.
+
+":set" didn't stop after an error.  For example ":set no ai" gave an error for
+"no", but still set "ai".  Now ":set" stops after the first error.
+
+When running configure for ctags, $LDFLAGS wasn't passed to it, causing
+trouble for IRIX.
+
+"@%" and "@#" when file name not set gave an error message.  Now they just
+return an empty string. (Steed)
+
+CTRL-X and CTRL-A didn't work correctly with negative hex and octal numbers.
+(Steed)
+
+":echo" always started with a blank.
+
+Updating GUI cursor shape didn't always work (e.g., when blinking is off).
+
+In silent Ex mode ("ex -s" or "ex <file") ":s///p" didn't print a line.  Also
+a few other commands that explicitly print a text line didn't work.  Made this
+Vi compatible.
+
+Win32 version of _chdrive() didn't return correct value. (Tsindlekht)
+
+When using 't' in 'complete' option, no longer give an error message for a
+missing tags file.
+
+Unix: tgoto() can return NULL, which was not handled correctly in configure.
+
+When doing ":help" from a buffer where 'binary' is set, also edited the help
+file in binary mode.  Caused extra ^Ms for DOS systems.
+
+Cursor position in a file was reset to 1 when closing a window.
+
+":!ls" in Ex mode switched off echo.
+
+When doing a double click in window A, while currently in window B, first
+click would reset double click time, had to click three times to select a
+word.
+
+When using <F11> in mappings, ":mkexrc" produced an exrc file that can't be
+used in Vi compatible mode.  Added setting of 'cpo' to avoid this.  Also, add
+a CTRL-V in front of a '<', to avoid a normal string to be interpreted as a
+special key name.
+
+Gave confusing error message for ":set guifont=-*-lucida-*": first "font is
+not fixed width", then "Unknown font".
+
+Some options were still completely left out, instead of included as hidden
+options.
+
+While running the X11 GUI, ignore SIGHUP signals.  Avoids a crash after
+executing an external command (in rare cases).
+
+In os_unixx.h, signal() was defined to sigset(), while it already was.
+
+Memory leak when executing autocommands (was reported as a memory leak in
+syntax highlighting).
+
+Didn't print source of error sometimes, because pointers were the same,
+although names were different.
+
+Avoid a number of UMR errors from Purify (third argument to open()).
+
+A swap file could still be created just after setting 'updatecount' to zero,
+when there is an empty buffer and doing ":e file". (Kutschera)
+
+Test 35 failed on 64 bit machines. (Schild)
+
+With "p" and "P" commands, redrawing was slow.
+
+Awk script for html documentation didn't work correctly with AIX awk.
+Replaced "[ ,.);\]	]" with "[] ,.);	]". (Briscoe)
+The makehtml.awk script had a small problem, causing extra lines to be
+inserted. (Briscoe)
+
+"gqgq" could not be repeated.  Repeating for "gugu" and "gUgU" worked in a
+wrong way.  Also made "gqq" work to be consistent with "guu".
+
+C indent was wrong after "case ':':".
+
+":au BufReadPre *.c put": Line from put text was deleted, because the buffer
+was still assumed to be empty.
+
+Text pasted with the Edit/Paste menu was subject to 'textwidth' and
+'autoindent'.  That was inconsistent with using the mouse to paste.  Now "*p
+is used.
+
+When using CTRL-W CTRL-] on a word that's not a tag, and then CTRL-] on a tag,
+window was split.
+
+":ts" got stuck on a tags line that has two extra fields.
+
+In Insert mode, with 'showmode' on, <C-O><C-G> message was directly
+overwritten by mode message, if preceded with search command warning message.
+
+When putting the result of an expression with "=<expr>p, newlines were
+inserted like ^@ (NUL in the file).  Now the string is split up in lines at
+the newline.
+
+putenv() was declared with "const char *" in pty.c, but with "char *" in
+osdef2.h.in.  Made the last one also "const char *".
+
+":help {word}", where +{word} is a feature, jumped to the feature list instead
+of where the command was explained.  E.g., ":help browse", ":help autocmd".
+
+Using the "\<xx>" form in an expression only got one byte, even when using a
+special character that uses several bytes (e.g., "\<F9>").
+Changed "\<BS>" to produce CTRL-H instead of the special key code for the
+backspace key.  "\<Del>" produces 0x7f.
+
+":mkvimrc" didn't write a command to set 'compatible' or 'nocompatible'.
+
+The shell syntax didn't contain a "syn sync maxlines" setting.  In a long file
+without recognizable items, syncing took so long it looked like Vim hangs.
+Added a maxlines setting, and made syncing interruptible.
+
+The "gs" command didn't flush output before waiting.
+
+Memory leaks for:
+    ":if 0 | let a = b . c | endif"
+    "let a = b[c]"
+    ":so {file}" where {file} contains a ":while"
+
+GUI: allocated fonts were never released. (Leonard)
+
+Makefile.bor:
+- Changed $(DEFINES) into a list of "-D" options, so that it can also be used
+  for the resource compiler. (not tested!)
+- "bcc.cfg" was used for all configurations.  When building for another
+  configuration, the settings for the previous one would be used.  Moved
+  "bcc.cfg" to the object directory. (Geddes)
+- Included targets for vimrun, install, ctags and xxd.  Changed the default to
+  use the Borland DLL Runtime Library, makes Vim.exe a log smaller. (Aaron)
+
+"2*" search for the word under the cursor with "2" prepended. (Leonard)
+
+When deleting into a specific register, would still overwrite the non-Win32
+GUI selection.  Now ""x"*P works.
+
+When deleting into the "" register, would write to the last used register.
+Now ""x always writes to the unnamed register.
+
+GUI Athena: A submenu with a '.' in it didn't work.  E.g.,
+":amenu Syntax.XY\.Z.foo lll".
+
+When first doing ":tag foo" and then ":tnext" and/or ":tselect" the order of
+matching tags could change, because the current file is different.  Now the
+existing matches are kept in the same order, newly found matches are added
+after them, not matter what the current file is.
+
+":ta" didn't find the second entry in a tags file, if the second entry was
+longer than the first one.
+
+When using ":set si tw=7" inserting "foo {^P}" made the "}" inserted at the
+wrong position.  can_si was still TRUE when the cursor is not in the indent of
+the line.
+
+Running an external command in Win32 version had the problem that Vim exits
+when the X on the console is hit (and confirmed).  Now use the "vimrun"
+command to start the external command indirectly. (Negri)
+
+Win32 GUI: When running an external filter, do it in a minimized DOS box.
+(Negri)
+
+":let" listed variables without translation into printable characters.
+
+Win32 console: When resizing the window, switching back to the old size
+(when exiting or executing an external command) sometimes failed. (Negri)
+This appears to also fix a "non fixable" problem:
+Win32 console in NT 4.0: When running Vim in a cmd window with a scrollbar,
+the scrollbar disappeared and was not restored when Vim exits.  This does work
+under NT 3.51, it appears not to be a Vim problem.
+
+When executing BufDelete and BufUnload autocommands for a buffer without a
+name, the name of the current buffer was used for <afile>.
+
+When jumping to a tag it reported "tag 1 of >2", while in fact there could be
+only two matches.  Changed to "tag 1 of 2 or more".
+
+":tjump tag" did a linear search in the tags file, which can be slow.
+
+Configure didn't find "LibXm.so.2.0", a Xm library with a version number.
+
+Win32 GUI: When using a shifted key with ALT, the shift modifier would remain
+set, even when it was already used by changing the used key.  E.g., "<M-S-9>"
+resulted in "<M-S-(>", but it should be "<M-(>". (Negri)
+
+A call to ga_init() was often followed by setting growsize and itemsize.
+Created ga_init2() for this, which looks better. (Aaron)
+
+Function filereadable() could call fopen() with an empty string, which might
+be illegal.
+
+X Windows GUI: When executing an external command that outputs text, could
+write one character beyond the end of a buffer, which caused a crash. (Kohan)
+
+When using "*" or "#" on a string that includes '/' or '?' (when these are
+included in 'isk'), they were not escaped. (Parmelan)
+
+When adding a ToolBar menu in the Motif GUI, the submenu_id field was not
+cleared, causing random problems.
+
+When adding a menu, the check if this menu (or submenu) name already exists
+didn't compare with the simplified version (no mnemonic or accelerator) of the
+new menu.  Could get two menus with the same name, e.g., "File" and "&File".
+
+Breaking a line because of 'textwidth' at the last line in the window caused a
+redraw of the whole window instead of a scroll.  Speeds up normal typing with
+'textwidth' a lot for slow terminals.
+
+An invalid line number produced an "invalid range" error, even when it wasn't
+to be executed (inside "if 0").
+
+When the unnamed, first buffer is re-used, the "BufDelete" autocommand was
+not called.  It would stick in a buffer list menu.
+
+When doing "%" on the NUL after the line, a "{" or "}" in the last character
+of the line was not found.
+
+The Insert mode menu was not used for the "s" command, the Operator-pending
+menu was used instead.
+
+With 'compatible' set, some syntax highlighting was not correct, because of
+using "[\t]" for a search pattern.  Now use the regexps for syntax
+highlighting like the 'cpoptions' option is empty (as was documented already).
+
+When using "map <M-Space> ms" or "map <Space> sss" the output of ":map" didn't
+show any lhs for the mapping (if 'isprint' includes 160).  Now always use
+<Space> and <M-Space>, even when they are printable.
+
+Adjusted the Syntax menu, so that the lowest entry fits on a small screen (for
+Athena, where menus don't wrap).
+
+When using CTRL-E or CTRL-Y in Insert mode for characters like 'o', 'x' and
+digits, repeating the insert didn't work.
+
+The file "tools/ccfilter.README.txt" could not be unpacked when using short
+file names, because of the two dots.  Renamed it to
+"tools/ccfilter_README.txt".
+
+For a dark 'background', using Blue for Directory and SpecialKey highlight
+groups is not very readable.  Use Cyan instead.
+
+In the function uc_scan_attr() in ex_docmd.c there was a goto that jumped into
+a block with a local variable.  That's illegal for some compilers.
+
+Win32 GUI: There was a row of pixels at the bottom of the window which was not
+drawn. (Aaron)
+
+Under DOS, editing "filename/" created a swap file of "filename/.swp".  Should
+be "filename/_swp".
+
+Win32 GUI: pointer was hidden when executing an external command.
+
+When 'so' is 999, "J" near the end of the file didn't redisplay correctly.
+
+":0a" inserted after the first line, instead of before the first line.
+
+Unix: Wildcard expansion didn't handle single quotes and {} patterns.  Now
+":file 'window.c'" removes the quotes and ":e 'main*.c'" works (literal '*').
+":file {o}{n}{e}" now results in file name "one".
+
+Memory leak when setting a string option back to its default value.
+
+==============================================================================
+VERSION 5.3						*version-5.3*
+
+Version 5.3 was a bug-fix version of 5.2.  There are not many changes.
+Improvements made between version 5.2 and 5.3:
+
+Changed							*changed-5.3*
+-------
+
+Renamed "IDE" menu to "Tools" menu.
+
+
+Added							*added-5.3*
+-----
+
+Win32 GUI: Give a warning when Vim is activated, and one of the files changed
+since editing started. (Negri)
+
+
+Fixed							*fixed-5.3*
+-----
+
+5.2.1: Win32 GUI: space for external command was not properly allocated, could
+cause a crash. (Aaron)  This was the reason to bring out 5.3 quickly after
+5.2.
+
+5.2.2: Some commands didn't complain when used without an argument, although
+they need one: ":badd", ":browse", ":call", ":confirm", ":behave",
+":delfunction", ":delcommand" and ":tearoff".
+":endfunction" outside of a function gave wrong error message: "Command not
+implemented".  Should be ":endfunction not inside a function".
+
+5.2.3: Win32 GUI: When gvim was installed in "Program files", or another path
+with a space in it, executing external commands with vimrun didn't work.
+
+5.2.4: Pasting with the mouse in Insert mode left the cursor on the last
+pasted character, instead of behind it.
+
+5.2.5: In Insert mode, cursor after the end of the line, a shift-cursor-left
+didn't include the last character in the selection.
+
+5.2.6: When deleting text from Insert mode (with "<C-O>D" or the mouse), which
+includes the last character in the line, the cursor could be left on the last
+character in the line, instead of just after it.
+
+5.2.7: Win32 GUI: scrollbar was one pixel too big.
+
+5.2.8: Completion of "PopUp" menu showed the derivates "PopUpc", "PopUPi",
+etc.  ":menu" also showed these.
+
+5.2.9: When using two input() functions on a row, the prompt would not be
+drawn in column 0.
+
+5.2.10: A loop with input() could not be broken with CTRL-C.
+
+5.2.11: ":call asdf" and ":call asdf(" didn't give an error message.
+
+5.2.12: Recursively using ":normal" crashes Vim after a while.  E.g.:
+":map gq :normal gq<CR>"
+
+5.2.13: Syntax highlighting used 'iskeyword' from wrong buffer.  When using
+":help", then "/\k*" in another window with 'hlsearch' set.
+
+5.2.14: When using ":source" from a function, global variables would not be
+available unless "g:" was used.
+
+5.2.15: XPM files can have the extension ".pm", which is the same as for Perl
+modules.  Added "syntax/pmfile.vim" to handle this.
+
+5.2.16: On Win32 and Amiga, "echo expand("%:p:h")" removed one dirname in an
+empty buffer.  mch_Fullname() didn't append a slash at the end of a directory
+name.
+
+Should include the character under the cursor in the Visual area when using
+'selection' "exclusive".  This wasn't done for "%", "e", "E", "t" and "f".
+
+""p would always put register 0, instead of the unnamed (last used) register.
+Reverse the change that ""x doesn't write in the unnamed (last used) register.
+It would always write in register 0, which isn't very useful.  Use "-x for the
+paste mappings in Visual mode.
+
+When there is one long line on the screen, and 'showcmd' is off, "0$" didn't
+redraw the screen.
+
+Win32 GUI: When using 'mousehide', the pointer would flicker when the cursor
+shape is changed. (Negri)
+
+When cancelling Visual mode, and the cursor moves to the start, the wanted
+column wasn't set, "k" or "j" moved to the wrong column.
+
+When using ":browse" or ":confirm", was checking for a comment and separating
+bar, which can break some commands.
+
+Included fixes for Macintosh. (Kielhorn)
+
+==============================================================================
+VERSION 5.4						*version-5.4*
+
+Version 5.4 adds new features, useful changes and a lot of bug fixes.
+
+
+Runtime directory introduced				*new-runtime-dir*
+----------------------------
+
+The distributed runtime files are now in $VIMRUNTIME, the user files in $VIM.
+You normally don't set $VIMRUNTIME but let Vim find it, by using
+$VIM/vim{version}, or use $VIM when that doesn't exist.  This allows for
+separating the user files from the distributed files and makes it more easy to
+upgrade to another version.  It also makes it possible to keep two versions of
+Vim around, each with their own runtime files.
+
+In the Unix distribution the runtime files have been moved to the "runtime"
+directory.  This makes it possible to copy all the runtime files at once,
+without the need to know what needs to be copied.
+
+The archives for DOS, Windows, Amiga and OS/2 now have an extra top-level
+"vim" directory.  This is to make clear that user-modified files should be put
+here.  The directory that contains the executables doesn't have '-' or '.'
+characters.  This avoids strange extensions.
+
+The $VIM and $VIMRUNTIME variables are set when they are first used.  This
+allows them to be used by Perl, for example.
+
+The runtime files are also found in a directory called "$VIM/runtime".  This
+helps when running Vim after just unpacking the runtime archive.  When using
+an executable in the "src" directory, Vim checks if "vim54" or "runtime" can
+be added after removing it.  This make the runtime files be found just after
+compiling.
+
+A default for $VIMRUNTIME can be given in the Unix Makefile.  This is useful
+if $VIM doesn't point to above the runtime directory but to e.g., "/etc/".
+
+
+Filetype introduced					*new-filetype-5.4*
+-------------------
+
+Syntax files are now loaded with the new FileType autocommand.  Old
+"mysyntaxfile" files will no longer work. |filetypes|
+
+The scripts for loading syntax highlighting have been changed to use the
+new Syntax autocommand event.
+
+This combination of Filetype and Syntax events allows tuning the syntax
+highlighting a bit more, also when selected from the Syntax menu.  The
+FileType autocommand can also be used to set options and mappings specifically
+for that type of file.
+
+The "$VIMRUNTIME/filetype.vim" file is not loaded automatically.  The
+":filetype on" command has been added for this.  ":syntax on" also loads it.
+
+The 'filetype' option has been added.  It is used to trigger the FileType
+autocommand event, like the 'syntax' option does for the Syntax event.
+
+":set syntax=OFF" and ":set syntax=ON" can be used (in a modeline) to switch
+syntax highlighting on/off for the current file.
+
+The Syntax menu commands have been moved to $VIMRUNTIME/menu.vim.  The Syntax
+menu is included both when ":filetype on" and when ":syntax manual" is used.
+
+Renamed the old 'filetype' option to 'osfiletype'.  It was only used for
+RISCOS.  'filetype' is now used for the common file type.
+
+Added the ":syntax manual" command.  Allows manual selection of the syntax to
+be used, e.g., from a modeline.
+
+
+Vim script line continuation			*new-line-continuation*
+----------------------------
+
+When an Ex line starts with a backslash, it is concatenated to the previous
+line.  This avoids the need for long lines. |line-continuation| (Roemer)
+Example: >
+	if   has("dialog_con") ||
+	   \ has("dialog_gui")
+	    :let result = confirm("Enter your choice",
+				\ "&Yes\n&No\n&Maybe",
+				\ 2)
+	endif
+
+
+Improved session files				*improved-sessions*
+----------------------
+
+New words for 'sessionoptions':
+- "help"	Restore the help window.
+- "blank"	Restore empty windows.
+- "winpos"	Restore the Vim window position.  Uses the new ":winpos"
+		command
+- "buffers"	Restore hidden and unloaded buffers.  Without it only the
+		buffers in windows are restored.
+- "slash"	Replace backward by forward slashes in file names.
+- "globals"	Store global variables.
+- "unix"	Use unix file format (<NL> instead of <CR><NL>)
+
+The ":mksession" and 'sessionoptions' are now in the +mksession feature.
+
+The top line of the window is also restored when using a session file.
+
+":mksession" and ":mkvimrc" don't store 'fileformat', it should be detected
+when loading a file.
+
+(Most of this was done by Vince Negri and Robert Webb)
+
+
+Autocommands improved				*improved-autocmds-5.4*
+---------------------
+
+New events:
+|FileType|	When the file type has been detected.
+|FocusGained|	When Vim got input focus. (Negri)
+|FocusLost|	When Vim lost input focus. (Negri)
+|BufCreate|	Called just after a new buffer has been created or has been
+		renamed. (Madsen)
+|CursorHold|	Triggered when no key has been typed for 'updatetime'.  Can be
+		used to do something with the word under the cursor. (Negri)
+		Implemented CursorHold autocommand event for Unix. (Zellner)
+		Also for Amiga and MS-DOS.
+|GUIEnter|	Can be used to do something with the GUI window after it has
+		been created (e.g., a ":winpos 100 50").
+|BufHidden|	When a buffer becomes hidden.  Used to delete the
+		option-window when it becomes hidden.
+
+Also trigger |BufDelete| just before a buffer is going to be renamed. (Madsen)
+
+The "<amatch>" pattern can be used like "<afile>" for autocommands, except
+that it is the matching value for the FileType and Syntax events.
+
+When ":let @/ = <string>" is used in an autocommand, this last search pattern
+will be used after the autocommand finishes.
+
+Made loading autocommands a bit faster.  Avoid doing strlen() on each exiting
+pattern for each new pattern by remembering the length.
+
+
+Encryption						*new-encryption*
+----------
+
+Files can be encrypted when writing and decrypted when reading.  Added the
+'key' option, "-x" command line argument and ":X" command. |encryption| (based
+on patch from Mohsin Ahmed)
+
+When reading a file, there is an automatic detection whether it has been
+crypted.  Vim will then prompt for the key.
+
+Note that the encryption method is not compatible with Vi.  The encryption is
+not unbreakable.  This allows it to be exported from the US.
+
+
+GTK GUI port						*new-GTK-GUI*
+------------
+
+New GUI port for GTK+.  Includes a toolbar, menu tearoffs, etc. |gui-gtk|
+Added the |:helpfind| command. (Kahn and Dalecki)
+
+
+Menu changes						*menu-changes-5.4*
+------------
+
+Menus can now also be used in the console.  It is enabled by the new
+'wildmenu' option.  This shows matches for command-line completion like a
+menu.  This works as a minimal file browser.
+
+The new |:emenu| command can be used to execute a menu item.
+
+Uses the last status line to list items, or inserts a line just above the
+command line.  (Negri)
+
+The 'wildcharx' option can be used to trigger 'wildmenu' completion from a
+mapping.
+
+When compiled without menus, this can be detected with has("menu").  Also show
+this in the ":version" output.  Allow compiling GUI versions without menu
+support.  Only include toolbar support when there is menu support.
+
+Moved the "Window" menu all the way to the right (priority 70).  Looks more
+familiar for people working with MS-Windows, shouldn't matter for others.
+
+Included "Buffers" menu.  Works with existing autocommands and functions.  It
+can be disabled by setting the "no_buffers_menu" variable.  (Aaron and Madsen)
+
+Win32 supports separators in a menu: "-.*-". (Geddes)
+Menu separators for Motif now work too.
+
+Made Popup menu for Motif GUI work. (Madsen)
+
+'M' flag in 'guioptions': Don't source the system menu.
+
+All the menu code has been moved from gui.c to menu.c.
+
+
+Viminfo improved					*improved-viminfo*
+----------------
+
+New flags for 'viminfo':
+'!'	Store global variables in the viminfo file if they are in uppercase
+	letters. (Negri)
+'h'	Do ":nohlsearch" when loading a viminfo file.
+
+Store search patterns in the viminfo file with their offset, magic, etc.  Also
+store the flag whether 'hlsearch' highlighting is on or off (which is not used
+if the 'h' flag is in 'viminfo').
+
+Give an error message when setting 'viminfo' without commas.
+
+
+Various new commands					*new-commands-5.4*
+--------------------
+
+Operator |g?|: rot13 encoding. (Negri)
+
+|zH| and |zL| commands: Horizontal scrolling by half a page.
+|gm| move cursor to middle of screen line. (Ideas by Campbell)
+
+Operations on Visual blocks: |v_b_I|, |v_b_A|, |v_b_c|, |v_b_C|, |v_b_r|,
+|v_b_<| and |v_b_>|. (Kelly)
+
+New command: CTRL-\ CTRL-N, which does nothing in Normal mode, and goes to
+Normal mode when in Insert or Command-line mode.  Can be used by VisVim or
+other OLE programs to make sure Vim is in Normal mode, without causing a beep.
+|CTRL-\_CTRL-N|
+
+":cscope kill" command to use the connection filename. |:cscope| (Kahn)
+
+|:startinsert| command: Start Insert mode next.
+
+|:history| command, to show all four types of histories. (Roemer)
+
+|[m|, |[M|, |]m| and |]M| commands, for jumping backward/forward to start/end
+of method in a (Java) class.
+
+":@*" executes the * register. |:@| (Acevedo)
+
+|go| and |:goto| commands: Jump to byte offset in the file.
+
+|gR| and |gr| command: Virtual Replace mode.  Replace characters without
+changing the layout. (Webb)
+
+":cd -" changes to the directory from before the previous ":cd" command.
+|:cd-| (Webb)
+
+Tag preview commands |:ptag|.  Shows the result of a ":tag" in a dedicated
+window.  Can be used to see the context of the tag (e.g., function arguments).
+(Negri)
+|:pclose| command, and CTRL-W CTRL-Z: Close preview window. (Moore)
+'previewheight' option, height for the preview window.
+Also |:ppop|, |:ptnext|, |:ptprevious|, |:ptNext|, |:ptrewind|, |:ptlast|.
+
+|:find| and |:sfind| commands: Find a file in 'path', (split window) and edit
+it.
+
+The |:options| command opens an option window that shows the current option
+values.  Or use ":browse set" to open it.  Options are grouped by function.
+Offers short help on each option.  Hit <CR> to jump to more help.  Edit the
+option value and hit <CR> on a "set" line to set a new value.
+
+
+Various new options					*new-options-5.4*
+-------------------
+
+Scroll-binding: 'scrollbind' and 'scrollopt' options.  Added |:syncbind|
+command.  Makes windows scroll the same amount (horizontally and/or
+vertically). (Ralston)
+
+'conskey' option for MS-DOS.  Use direct console I/O.  This should work with
+telnet (untested!).
+
+'statusline' option: Configurable contents of the status line.  Also allows
+showing the byte offset in the file.  Highlighting with %1* to %9*, using the
+new highlight groups User1 to User9.  (Madsen)
+
+'rulerformat' option: Configurable contents of the ruler, like 'statusline'.
+(Madsen)
+
+'write' option: When off, writing files is not allowed.  Avoids overwriting a
+file even with ":w!".  The |-m| command line option resets 'write'.
+
+'clipboard' option: How the clipboard is used.  Value "unnamed": Use unnamed
+register like "*. (Cortopassi)  Value "autoselect": Like what 'a' in
+'guioptions' does but works in the terminal.
+
+'guifontset' option: Specify fonts for the +fontset feature, for the X11 GUI
+versions.  Allows using normal fonts when vim is compiled with this feature.
+(Nam)
+
+'guiheadroom' option: How much room to allow above/below the GUI window.
+Used for Motif, Athena and GTK.
+
+Implemented 'tagstack' option: When off, pushing tags onto the stack is
+disabled (Vi compatible).  Useful for mappings.
+
+'shellslash' option.  Only for systems that use a backslash as a file
+separator.  This option will use a forward slash in file names when expanding
+it.  Useful when 'shell' is sh or csh.
+
+'pastetoggle' option: Key sequence that toggles 'paste'.  Works around the
+problem that mappings don't work in Insert mode when 'paste' is set.
+
+'display' option: When set to "lastline", the last line fills the window,
+instead of being replaced with "@" lines.  Only the last three characters are
+replaced with "@@@", to indicate that the line has not finished yet.
+
+'switchbuf' option: Allows re-using existing windows on a buffer that is being
+jumped to, or split the window to open a new buffer. (Roemer)
+
+'titleold' option.  Replaces the fixed string "Thanks for flying Vim", which
+is used to set the title when exiting. (Schild)
+
+
+Vim scripts						*new-script-5.4*
+-----------
+
+The |exists()| function can also check for existence of a function. (Roemer)
+An internal function is now found with a binary search, should be a bit
+faster. (Roemer)
+
+New functions:
+- |getwinposx()| and |getwinposy()|: get Vim window position. (Webb)
+- |histnr()|, |histadd()|, |histget()| and |histdel()|: Make history
+  available. (Roemer)
+- |maparg()|: Returns rhs of a mapping.  Based on a patch from Vikas.
+- |mapcheck()|: Check if a map name matches with an existing one.
+- |visualmode()|: Return type of last Visual mode. (Webb)
+- |libcall()|: Call a function in a library.  Currently only for Win32. (Negri)
+- |bufwinnr()|: find window that contains the specified buffer. (Roemer)
+- |bufloaded()|: Whether a buffer exists and is loaded.
+- |localtime()| and |getftime()|: wall clock time and last modification time
+  of a file (Webb)
+- |glob()|: expand file name wildcards only.
+- |system()|: get the raw output of an external command. (based on a patch
+  from Aaron).
+- |strtrans()|: Translate String into printable characters.  Used for
+  2html.vim script.
+- |append()|: easy way to append a line of text in a buffer.
+
+Changed functions:
+- Optional argument to |strftime()| to give the time in seconds. (Webb)
+- |expand()| now also returns names for files that don't exist.
+
+Allow numbers in the name of a user command. (Webb)
+
+Use "v:" for internal Vim variables: "v:errmsg", "v:shell_error", etc.  The
+ones from version 5.3 can be used without "v:" too, for backwards
+compatibility.
+
+New variables:
+"v:warningmsg" and "v:statusmsg" internal variables.  Contain the last given
+warning and status message. |v:warningmsg| |v:statusmsg| (Madsen)
+"v:count1" variable: like "v:count", but defaults to one when no count is
+used. |v:count1|
+
+When compiling without expression evaluation, "if 1" can be used around the
+not supported commands to avoid it being executed.  Works like in Vim 4.x.
+Some of the runtime scripts gave errors when used with a Vim that was compiled
+with minimal features.  Now "if 1" is used around code that is not always
+supported.
+
+When evaluating an expression with && and ||, skip the parts that will not
+influence the outcome.  This makes it faster and avoids error messages. (Webb)
+Also optimized the skipping of expressions inside an "if 0".
+
+
+Avoid hit-enter prompt					*avoid-hit-enter*
+-----------------------
+
+Added 'T' flag to 'shortmess': Truncate all messages that would cause the
+hit-enter prompt (unless that would happen anyway).
+The 'O' flag in 'shortmess' now also applies to quickfix messages, e.g., from
+the ":cn" command.
+
+The default for 'shortmess' is now "filnxtToO", to make most messages fit on
+the command line, and not cause the hit-enter prompt.
+
+Previous messages can be viewed with the new |:messages| command.
+
+Some messages are shown fully, even when 'shortmess' tells to shorten
+messages, because the user is expected to want to see them in full: CTRL-G and
+some quickfix commands.
+
+
+Improved quickfix					*improved-quickfix*
+-----------------
+
+Parse change-directory lines for gmake: "make[1]: Entering directory 'name'".
+Uses "%D" and "%X" in 'errorformat'.
+Also parse "Making {target} in {dir}" messages from make.  Helps when not
+using GNU make. (Schandl)
+
+Use 'isfname' for "%f" in 'errorformat'.
+
+Parsing of multi-line messages. |errorformat-multi-line|
+
+Allow a range for the |:clist| command. (Roemer)
+
+Support for "global" file names, for error formats that output the file name
+once for several errors. (Roemer)
+
+|:cnfile| jumps to first error in next file.
+
+"$*" in 'makeprg' is replaced by arguments to ":make". (Roemer)
+
+
+Regular expressions					*regexp-changes-5.4*
+-------------------
+
+In a regexp, a '$' before "\)" is also considered to be an end-of-line. |/$|
+In patterns "^" after "\|" or "\(" is a start-of-line. |/^| (Robinson)
+
+In a regexp, in front of "\)" and "\|" both "$" and "\$" were considered
+end-of-line.  Now use "$" as end-of-line and "\$" for a literal dollar.  Same
+for '^' after "\(" and "\|". |/\$| |/\^|
+
+Some search patterns can be extremely slow, even though they are not really
+illegal.  For example: "\([^a-z]\+\)\+Q".  Allow interrupting any regexp
+search with CTRL-C.
+
+Register "/: last search string (read-only). (Kohan)  Changed to use last used
+search pattern (like what 'hlsearch' uses).  Can set the search pattern with
+":let @/ = {expr}".
+
+Added character classes to search patterns, to avoid the need for removing the
+'l' flag from 'cpoptions': |[:tab:]|, |[:return:]|, |[:backspace:]| and
+|[:escape:]|.
+
+By adding a '?' after a comparative operator in an expression, the comparison
+is done by ignoring case. |expr-==?|
+
+
+Other improvements made between version 5.3 and 5.4
+---------------------------------------------------
+
+Changed							*changed-5.4*
+-------
+
+Unix: Use $TMPDIR for temporary files, if it is set and exists.
+
+Removed "Empty buffer" message.  It isn't useful and can cause a hit-enter
+prompt. (Negri)
+
+"ex -" now reads commands from stdin and works in silent mode.  This is to be
+compatible with the original "ex" command that is used for scripts.
+
+Default range for ":tcldo" is the whole file.
+
+Cancelling Visual mode with ESC moved the cursor.  There appears to be no
+reason for this.  Now leave the cursor where it is.
+
+The ":grep" and ":make" commands see " as part of the arguments, instead of
+the start of a comment.
+
+In expressions the "=~" and "!~" operators no longer are affected by
+'ignorecase'.
+
+Renamed vimrc_example to vimrc_example.vim and gvimrc_example to
+gvimrc_example.vim.  Makes them being recognized as vim scripts.
+
+"gd" no longer starts searching at the end of the previous function, but at
+the first blank line above the start of the current function.  Avoids that
+using "gd" in the first function finds global a variable.
+
+Default for 'complete' changed from ".,b" to ".,w,b,u,t,i".  Many more matches
+will be found, at the cost of time (the search can be interrupted).
+
+It is no longer possible to set 'shell*' options from a modeline.  Previously
+only a warning message was given.  This reduces security risks.
+
+The ordering of the index of documentation files was changed to make it more
+easy to find a subject.
+
+On MS-DOS and win32, when $VIM was not set, $HOME was used.  This caused
+trouble if $HOME was set to e.g., "C:\" for some other tool, the runtime files
+would not be found.  Now use $HOME only for _vimrc, _gvimrc, etc., not to find
+the runtime file.
+
+When 'tags' is "./{fname}" and there is no file name for the current buffer,
+just use it.  Previously it was skipped, causing "vim -t {tag}" not to find
+many tags.
+
+When trying to select text in the 'scrolloff' area by mouse dragging, the
+resulting scrolling made this difficult.  Now 'scrolloff' is temporarily set
+to 0 or 1 to avoid this.  But still allow scrolling in the top line to extend
+to above the displayed text.
+
+Default for 'comments' now includes "sl:/*,mb: *,ex:*/", to make javadoc
+comments work.  Also helps for C comments that start with "/*******".
+
+CTRL-X CTRL-] Insert mode tag expansion tried to expand to all tags when used
+after a non-ID character, which can take a very long time.  Now limit this to
+200 matches.  Also used for command-line tag completion.
+
+The OS/2 distribution has been split in two files.  It was too big to fit on a
+floppy.  The same runtime archive as for the PC is now used.
+
+In the documentation, items like <a-z> have been replaced with {a-z} for
+non-optional arguments.  This avoids confusion with key names: <C-Z> is a
+CTRL-Z, not a character between C and Z, that is {C-Z}.
+
+
+Added							*added-5.4*
+-----
+
+Color support for the iris-ansi builtin termcap entry. (Tubman)
+
+Included VisVim version 1.3a. (Erhardt)
+
+Win32 port for SNiFF+ interface. (Leherbauer)
+Documentation file for sniff interface: if_sniff.txt. (Leherbauer)
+
+Included the "SendToVim" and "OpenWithVim" programs in the OleVim directory.
+To be used with the OLE version of gvim under MS-Windows. (Schaller)
+
+Included Exuberant Ctags version 3.2.4 with Eiffel support. (Hiebert)
+
+When a file that is being edited is deleted, give a warning (like when the
+time stamp changed).
+
+Included newer versions of the HTML-generating Awk and Perl scripts. (Colombo)
+
+Linux console mouse support through "gpm". (Tsindlekht)
+
+Security fix: Disallow changing 'secure' and 'exrc' from a modeline.  When
+'secure' is set, give a warning for changing options that contain a program
+name.
+
+Made the Perl interface work with Perl 5.005 and threads. (Verdoolaege)
+
+When giving an error message for an ambiguous mapping, include the offending
+mapping. (Roemer)
+
+Command line editing:
+- Command line completion of mappings. (Roemer)
+- Command line completion for ":function", ":delfunction", ":let", ":call",
+  ":if", etc. (Roemer)
+- When using CTRL-D completion for user commands that have
+  "-complete=tag_listfiles" also list the file names.  (Madsen)
+- Complete the arguments of the ":command" command. (Webb)
+- CTRL-R . in command line inserts last inserted text.  CTRL-F, CTRL-P, CTRL-W
+  and CTRL-A after CTRL-R are used to insert an object from under the cursor.
+  (Madsen)
+
+Made the text in uganda.txt about copying Vim a bit more clear.
+
+Updated the Vim tutor.  Added the "vimtutor" command, which copies the tutor
+and starts Vim on it.  "make install" now also copies the tutor.
+
+In the output of ":clist" the current entry is highlighted, with the 'i'
+highlighting (same as used for 'incsearch').
+
+For the ":clist" command, you can scroll backwards with "b" (one screenful),
+"u" (half a screenful) and "k" (one line).
+
+Multi-byte support:
+- X-input method for multi-byte characters.  And various fixes for multi-byte
+  support. (Nam)
+- Hangul input method feature: |hangul|. (Nam)
+- Cleaned up configuration of multi-byte support, XIM, fontset and Hangul
+  input.  Each is now configurable separately.
+- Changed check for GTK_KEYBOARD to HANGUL_KEYBOARD_TYPE. (Nam)
+- Added doc/hangulin.txt: Documentation for the Hangul input code. (Nam)
+- XIM support for GTK+. (Nam)
+- First attempt to include support for SJIS encoding. (Nagano)
+- When a double-byte character doesn't fit at the end of the line, put a "~"
+  there and print it on the next line.
+- Optimize output of multi-byte text. (Park)
+- Win32 IME: preedit style is like over-the-spot. (Nagano)
+- Win32 IME: IME mode change now done with ImmSetOpenStatus. (Nagano)
+- GUI Athena: file selection dialog can display multi-byte characters.
+  (Nagano)
+- Selection reply for XA_TEXT as XA_STRING. (Nagano)
+
+"runtime/macros/diffwin.vim".  Mappings to make a diff window. (Campbell)
+
+Added ".obj" to the 'suffixes' option.
+
+Reduced size of syntax/synload.vim by using the ":SynAu" user command.
+Automated numbering of Syntax menu entries in menu.vim.
+In the Syntax menu, insert separators between syntax names that start with
+a different letter. (Geddes)
+
+Xterm:
+- Clipboard support when using the mouse in an xterm. (Madsen)
+- When using the xterm mouse, track dragging of the mouse.  Use xterm escape
+  sequences when possible.  It is more precise than other methods, but
+  requires a fairly recent xterm version.  It is enabled with "xterm2" in
+  'ttymouse'.  (Madsen)
+- Check xterm patch level, to set the value of 'ttymouse'.  Has only been
+  added to xterm recently (patch level > 95).  Uses the new 't_RV' termcap
+  option.  Set 'ttymouse' to "xterm2" when a correct response is recognized.
+  Will make xterm mouse dragging work better.
+- Support for shifted function keys on xterm.  Changed codes for shifted
+  cursor keys to what the xterm actually produces.  Added codes for shifted
+  <End> and <Home>.
+- Added 't_WP' to set the window position in pixels and 't_WS' to set the
+  window size in characters.  Xterm can now move (used for ":winpos") and
+  resize (use for ":set lines=" and ":set columns=").
+
+X11:
+- When in Visual mode but not owning the selection, display the Visual area
+  with the VisualNOS group to show this. (Madsen)
+- Support for requesting the type of clipboard support.  Used for AIX and
+  dtterm. (Wittig)
+- Support compound_text selection (even when compiled without multi-byte).
+
+Swap file:
+- New variation for naming swap files: Replace path separators into %, place
+  all swap files in one directory.  Used when a name in 'dir' ends in two path
+  separators. (Madsen)
+- When a swap file is found, show whether it contains modifications or not in
+  the informative message. (Madsen)
+- When dialogs are supported, use a dialog to ask the user what to do when a
+  swapfile already exists.
+
+"popup_setpos" in 'mousemodel' option.  Allows for moving the cursor when
+using the right mouse button.
+
+When a buffer is deleted, the selection for which buffer to display instead
+now uses the most recent entry from the jump list. (Madsen)
+
+When using CTRL-O/CTRL-I, skip deleted buffers.
+
+A percentage is shown in the ruler, when there is room.
+
+Used autoconf 1.13 to generate configure.
+
+Included get_lisp_indent() from Dirk van Deun.  Does better Lisp indenting
+when 'p' flag in 'cpoptions' is not included.
+
+Made the 2html.vim script quite a bit faster.  (based on ideas from Geddes)
+
+Unix:
+- Included the name of the user that compiled Vim and the system name it was
+  compiled on in the version message.
+- "make install" now also installs the "tools" directory.  Makes them
+  available for everybody.
+- "make check" now does the same as "make test".  "make test" checks for
+  Visual block mode shift, insert, replace and change.
+- Speed up comparing a file name with existing buffers by storing the
+  device/inode number with the buffer.
+- Added configure arguments "--disable-gtk", "--disable-motif" and
+  "--disable-athena", to be able to disable a specific GUI (when it doesn't
+  work).
+- Renamed the configure arguments for disabling the check for specific GUIs.
+  Should be clearer now. (Kahn)
+- On a Digital Unix system ("OSF1") check for the curses library before
+  termlib and termcap. (Schild)
+- "make uninstall_runtime" will only delete the version-specific files.  Can
+  be used to delete the runtime files of a previous version.
+
+Macintosh: (St-Amant)
+- Dragging the scrollbar, like it's done for the Win32 GUI.  Moved common code
+  from gui_w32.c to gui.c
+- Added dialogs and file browsing.
+- Resource fork preserved, warning when it will be lost.
+- Copy original file attributes to newly written file.
+- Set title/notitle bug solved.
+- Filename completion improved.
+- Grow box limit resize to a char by char size.
+- Use of rgb.txt for more colors (but give back bad color).
+- Apple menu works (beside the about...).
+- Internal border now vim compliant.
+- Removing a menu doesn't crash anymore.
+- Weak-linking of Python 1.5.1 (only on PPC).  Python is supported when the
+  library is available.
+- If an error is encountered when sourcing the users .vimrc, the alert box now
+  shows right away with the OK button defaulted.  There's no more "Delete"-key
+  sign at the start of each line
+- Better management of environment variables.  Now $VIM is calculated only
+  once, not regenerated every time it is used.
+- No more CPU hog when in background.
+- In a sourced Vim script the Mac file format can be recognized, just like DOS
+  file format is.
+
+When both "unix" and "mac" are present in 'fileformats', prefer "mac" format
+when there are more CR than NL characters.
+When using "mac" fileformat, use CR instead of a NL, because NL is used for
+NUL.  Will preserve all characters in a file. (Madsen)
+
+The DOS install.exe now contains checks for an existing installation.  It
+avoids setting $VIM and $PATH again.
+The install program for Dos/Windows can now install Vim in the popup menu, by
+adding two registry keys.
+
+Port to EGCS/mingw32.  New Makefile.ming. (Aaron)
+
+DOS 16 bit: Don't include cursor shape stuff.  Save some bytes.
+
+TCL support to Makefile.w32. (Duperval)
+
+OS/2: Use argv[0] to find runtime files.
+
+When using "gf" to go to a buffer that has already been used, jump to the
+line where the cursor last was.
+
+Colored the output of ":tselect" a bit more.  Different highlighting between
+tag name and file name.  Highlight field name ("struct:") separately from
+argument.
+
+Backtick expansion for non-Unix systems.  Based on a patch from Aaron.
+Allows the use of things like ":n `grep -l test *.c`" and
+"echo expand('`ls m*`')".
+
+Check for the 'complete' option when it is set. (Acevedo)
+'d' flag in 'complete' searches for defined names or macros.
+While searching for Insert mode completions in include files and tags files,
+check for typeahead, so that you can use matches early. (Webb)
+The '.' flag in 'complete' now scans the current buffer completely, ignoring
+'nowrapscan'.  (Webb)
+
+Added '~' flag to 'whichwrap'. (Acevedo)
+
+When ending the Visual mode (e.g., with ESC) don't grab ownership of the
+selection.
+
+In a color terminal, "fg" and "bg" can be used as color names.  They stand for
+the "Normal" colors.
+
+A few cscope cleanups. (Kahn)
+
+Included changed vimspell.sh from Schemenauer.
+
+Concatenation of strings in an expression with "." is a bit faster. (Roemer)
+
+The ":redir" command can now redirect to a register: ":redir @r". (Roemer)
+
+Made the output of ":marks" and ":jumps" look similar.  When the mark is in
+the current file, show the text at the mark.  Also for ":tags".
+
+When configure finds ftello() and fseeko(), they are used in tag.c (for when
+you have extremely big tags files).
+
+Configure check for "-FOlimit,2000" argument for the compiler. (Borsenkow)
+
+GUI:
+- When using ":gui" in a non-GUI Vim, give a clear error message.
+- "gvim -v" doesn't start the GUI (if console support is present).
+- When in Ex mode, use non-Visual selection for the whole screen.
+- When starting with "gvim -f" and using ":gui" in the .gvimrc file, Vim
+  forked anyway.  Now the "-f" flag is remembered for ":gui".  Added "gui -b"
+  to run gvim in the background anyway.
+
+Motif GUI:
+- Check for "-lXp" library in configure (but it doesn't work yet...).
+- Let configure check for Lesstif in "/usr/local/Lesstif/Motif*".  Changed the
+  order to let a local Motif version override a system standard version.
+
+Win32 GUI:
+- When using "-register" or "-unregister" in the non-OLE version, give an
+  error message.
+- Use GTK toolbar icons.  Make window border look better.  Use sizing handles
+  on the lower left&right corners of the window. (Negri)
+- When starting an external command with ":!start" and the command can not be
+  executed, give an error message. (Webb)
+- Use sizing handles for the grey rectangles below the scrollbars.  Can draw
+  toolbar in flat mode now, looks better. (Negri)
+- Preparations for MS-Windows 3.1 addition.  Mostly changing WIN32 to MSWIN
+  and USE_GUI_WIN32 to USE_GUI_MSWIN. (Negri)
+
+Avoid allocating the same string four times in buflist_findpat(). (Williams)
+
+Set title and icon text with termcap options 't_ts', 't_fs', 't_IS' and
+'t_IE'.  Allows doing this on any terminal that supports setting the title
+and/or icon text. (Schild)
+
+New 'x' flag in 'comments': Automatically insert the end part when its last
+character is typed.  Helps to close a /* */ comment in C. (Webb)
+
+When expand() has a second argument which is non-zero, don't use 'suffixes'
+and 'wildignore', return all matches.
+
+'O' flag in 'cpoptions: When not included, Vim will not overwrite a file, if
+it didn't exist when editing started but it does exist when the buffer is
+written to the file.  The file must have been created outside of Vim, possibly
+without the user knowing it.  When this is detected after a shell command,
+give a warning message.
+
+When editing a new file, CTRL-G will show [New file].  When there were errors
+while reading the file, CTRL-G will show [Read errors].
+
+":wall" can now use a dialog and file-browsing when needed.
+
+Grouped functionality into new features, mainly to reduce the size of the
+minimal version:
++linebreak:	'showbreak', 'breakat' and 'linebreak'
++visualextra:	"I"nsert and "A"ppend in Visual block mode, "c"hange all lines
+		in a block, ">" and "<": Shifting a block, "r": Replacing a
+		Visual area with one character.
++comments:	'comments'
++cmdline_info:	'ruler' and 'showcmd'.  Replaces +showcmd.
+"+title"	Don't add code to set title or icon for MSDOS, this was not
+		possible anyway.
++cmdline_compl	Disable commandline completion at compile time, except for
+		files, directories and help items.
+
+Moved features from a list of function calls into an array.  Should save a bit
+of space.
+
+While entering the body of a function, adjust indent according to "if" and
+"while" commands.
+
+VMS: Adjusted os_vms.mms a bit according to suggestions from Arpadffy.
+
+The flags in the 'comments' option can now include an offset.  This makes it
+possible to align "/*****", "/*   xxx" and "/*" comments with the same
+'comments' setting.  The default value for 'comments' uses this.
+Added 'O' flag: Don't use this part for the "O" command.  Useful for "set
+com=sO:*\ -,mO:*\ \ ,exO:*/"
+
+FileType autocommands recognize ".bak", ".orig" and "~" extensions and remove
+them to find the relevant extension.
+
+The tutorial for writing a Vim script file has been extended.
+
+Some more highlighting in help files, for items that are not typed literally.
+
+Can use "CTRL-W CTRL-G" like "CTRL-W g".
+
+"make test" for OS/2.
+
+Adjusted configure to automatically use the GUI for BeOS.
+
+
+Fixed							*fixed-5.4*
+-----
+
+5.3.1: When using an autocommand for BufWritePre that changes the name of the
+buffer, freed memory would be used. (Geddes)
+
+Mac: Compiler didn't understand start of skip_class_name().
+
+Win32 GUI:
+- When cancelling the font requester, don't give an error message.
+- When a tearoff-menu is open and its menu is deleted, Vim could crash.
+  (Negri)
+- There was a problem on Windows 95 with (un)maximizing the window.
+  (Williams)
+- when 'mousehide' is set, the mouse would stay hidden when a menu is dropped
+  with the keyboard. (Ralston)
+- The tempname() function already created the file.  Caused problems when
+  using ":w".  Now the file is deleted.
+- Cursor disappeared when ending up in the top-left character on the screen
+  after scrolling. (Webb)
+- When adding a submenu for a torn-off menu, it was not updated.
+- Menu tooltip was using the toolbar tooltip. (Negri)
+- Setting 'notitle' didn't remove the title. (Steed)
+- Using ":!start cmd" scrolled the screen one line up, and didn't wait for
+  return when the command wasn't found.
+
+Cscope interface: Sorting of matches was wrong.  Starting the interface could
+fail. (Kahn)
+
+Motif GUI: Could not compile with Motif 1.1, because some tear-off
+functionality was not in #ifdefs.
+
+Configure could sometimes not compile or link the test program for sizeof(int)
+properly.  This caused alignment problems for the undo structure allocations.
+Added a safety check that SIZEOF_INT is not zero.
+
+Added configure check to test if strings.h can be included after string.h.
+Some systems can't handle it.
+Some systems need both string.h and strings.h included.  Adjusted vim.h for
+that.  Removed including string.h from os_unixx.h, since it's already in
+vim.h. (Savage)
+AIX: defining _NO_PROTO in os_unix.h causes a conflict between string.h and
+strings.h, but after the configure check said it was OK.  Also define
+_NO_PROTO for AIX in the configure check. (Winn)
+
+When closing a window with CTRL-W c, the value of 'hidden' was not taken into
+account, the buffer was always unloaded. (Negri)
+
+Unix Makefile: "make install" always tried to rename an older executable and
+remove it.  This caused an error message when it didn't exit.  Added a check
+for the existence of an old executable.
+The command line for "make install" could get too long, because of the many
+syntax files.  Now first do a "cd" to reduce the length.
+
+On RISCOS and MSDOS, reading a file could fail, because the short filename was
+used, which can be wrong after a ":!cd".
+
+In the DOS versions, the wrong install.exe was included (required Windows).
+Now the install.exe version is included that is the same as the Vim version.
+This also supports long file names where possible.
+
+When recording, and stopping while in Insert mode with CTRL-O q, the CTRL-O
+would also be recorded.
+
+32bit DOS version: "vim \file", while in a subdirectory, resulted in "new
+file" for "file" in the local directory, while "\file" did exist.  When
+"file" in the current directory existed, this didn't happen.
+
+MSDOS: Mouse could not go beyond 80 columns in 132 columns mode. (Young)
+
+"make test" failed in the RedHat RPM, because compatible is off by default.
+
+In Insert mode <C-O><C-W><C-W> changes to other window, but the status bars
+were not updated until another character was typed.
+
+MSDOS: environment options in lowercase didn't work, although they did in the
+Win32 versions. (Negri)
+
+After ":nohlsearch", a tag command switched highlighting back on.
+
+When using "append" command as the last line in an autocommand, Vim would
+crash.
+
+RISCOS: The scroll bumpers (?) were not working properly. (Leonard)
+
+"zl" and "zh" could move the cursor, but this didn't set the column in which
+e.g., "k" would move the cursor.
+
+When doing ":set all&" the value of 'scroll' was not set correctly.  This
+caused an error message when later setting any other number option.
+
+When 'hlsearch' highlighting has been disabled with ":nohlsearch",
+incremental searching would switch it back on too early.
+
+When listing tags for ":tselect", and using a non-search command, and the last
+character was equal to the first (e.g., "99"), the last char would not be
+shown.
+
+When searching for tags with ":tag" Vim would assume that all matches had been
+found when there were still more (e.g. from another tags file).
+
+Win32: Didn't recognize "c:\" (e.g., in tags file) as absolute path when
+upper/lowercase was different.
+
+Some xterms (Debian) send <Esc>OH for HOME and <Esc>OF for END.  Added these
+to the builtin-xterm.
+
+In ex mode, any CR was seen as the end of the line.  Only a NL should be
+handled that way.  broke ":s/foo/some^Mtext/".
+
+In menu.vim, a vmenu was used to override an amenu.  That didn't work, because
+the system menu file doesn't overwrite existing menus.  Added explicit vunmenu
+to solve this.
+
+Configure check for terminal library could find a library that doesn't work at
+runtime (Solaris: shared library not found).  Added a check that a program
+with tgoto() can run correctly.
+
+Unix: "echo -n" in the Makefile doesn't work on all systems, causing errors
+compiling pathdef.c.  Replaced it with "tr".
+
+Perl: DO_JOIN was redefined by Perl.  Undefined it in the perl files.
+
+Various XIM and multi-byte fixes:
+- Fix user cannot see his language while he is typing his language with
+  off-the-spot method. (Nagano)
+- Fix preedit position using text/edit area (using gui.wid). (Nagano)
+- remove 'fix dead key' codes.  It was needed since XNFocusWindow was
+  "x11_window", XNFocusWindow is now gui.wid. (Nagano)
+- Remove some compile warnings and fix typos. (Namsh)
+- For status area, check the gtk+ version while Vim runs.  I believe it is
+  better than compile time check. (Namsh)
+- Remove one FIXME for gtk+-xim. (Namsh)
+- XIM: Dead keys didn't work for Czech. (Vyskovsky)
+- Multibyte: If user input only 3byte such as mb1_mb2_eng or eng_mb1_mb2 VIM
+  could convert it to special character. (Nam)
+- Athena/Motif with XIM: fix preedit area. (Nam)
+- XIM: Composed strings were sometimes ignored.  Vim crashed when compose
+  string was longer than 256 bytes.  IM's geometry control is fixed. (Nam,
+  Nagano)
+- Win32 multi-byte: hollowed cursor width on a double byte char was wrong.
+  (Nagano)
+- When there is no GUI, selecting XIM caused compilation problems.
+  Automatically disable XIM when there is no GUI in configure.
+- Motif and Athena: When compiled with XIM, but the input method was not
+  enabled, there would still be a status line.  Now the status line is gone if
+  the input method doesn't work. (Nam)
+
+Win32: tooltip was not removed when selecting a parent menu (it was when
+selecting a menu entry). (Negri)
+
+Unix with X: Some systems crash on exit, because of the XtCloseDisplay() call.
+Removed it, it should not be necessary when exiting.
+
+Win32: Crash on keypress when compiled with Borland C++. (Aaron)
+
+When checking for Motif library files, prefer the same location as the include
+files (with "include" replaced with "lib") above another entry.
+
+Athena GUI: Changed "XtOffset()" in gui_at_fs.c to "XtOffsetOf()", like it's
+used in gui_x11.c.
+
+Win32: When testing for a timestamp of a file on floppy, would get a dialog
+box when the floppy has been removed.  Now return with an error.  (Negri)
+
+Win32 OLE: When forced to come to the foreground, a minimized window was still
+minimized, now it's restored. (Zivkov)
+
+There was no check for a positive 'shiftwidth'.  A negative value could cause
+a hangup, a zero value a crash.
+
+Athena GUI: horizontal scrollbar wasn't updated correctly when clicking right
+or left of the thumb.
+
+When making a Visual-block selection in one window, and trying to scroll
+another, could cause errors for accessing non-existent line numbers.
+
+When 'matchpairs' contains "`:'", jumping from the ` to the ' didn't work
+properly.
+
+Changed '\"' to '"' to make it compatible with old C compilers.
+
+The command line expansion for mappings caused a script with a TAB between lhs
+and rhs of a map command to fail.  Assume the TAB is to separate lhs and rhs
+when there are no mappings to expand.
+
+When editing a file with very long lines with 'scrolloff' set, "j" would
+sometimes end up in a line which wasn't displayed.
+
+When editing a read-only file, it was completely read into memory, even when
+it would not fit.  Now create a swap file for a read-only file when running
+out of memory while reading the file.
+
+When using ":set cino={s,e-s", a line after "} else {" was not indented
+properly.  Also added a check for this in test3.in.
+
+The Hebrew mapping for the command line was remembered for the next command
+line.  That isn't very useful, a command is not Hebrew. (Kol)
+
+When completing file names with embedded spaces, like "Program\ files", this
+didn't work.  Also for user commands.  Moved backslash_halve() down to
+mch_expandpath().
+
+When using "set mouse=a" in Ex mode, mouse events were handled like typed
+text.  Then typing "quit" screwed up the mouse behavior of the xterm.
+
+When repeating an insert with "." that contains a CTRL-Y, a number 5 was
+inserted as "053".
+
+Yanking a Visual area, with the cursor past the line, didn't move the cursor
+back onto the line.  Same for "~", "u", "U" and "g?"
+
+Win32: Default for 'grepprg' could be "findstr /n" even though there is no
+findstr.exe (Windows 95).  Check if it exists, and fall back to "grep -n" if
+it doesn't.
+
+Because gui_mouse_moved() inserted a leftmouse click in the input buffer,
+remapping a leftmouse click caused strange effects.  Now Insert another code
+in the input buffer.  Also insert a leftmouse release, to avoid the problem
+with ":map <LeftMouse> l" that the next release is seen as the release for the
+focus click.
+
+With 'wrap' on, when using a line that doesn't fit on the screen, if the start
+of the Visual area is before the start of the screen, there was no
+highlighting.  Also, 'showbreak' doesn't work properly.
+
+DOS, Win32: A pattern "[0-9]\+" didn't work in autocommands.
+
+When creating a swap file for a buffer which isn't the current buffer, could
+get a mixup of short file name, resulting in a long file name when a short
+file name was required.  makeswapname() was calling modname() instead of
+buf_modname().
+
+When a function caused an error, and the error message was very long because
+of recursiveness, this would cause a crash.
+
+'suffixes' were always compared with matching case.  For MS-DOS, Win32 and
+OS/2 case is now ignored.
+
+The use of CHARBITS in regexp.c didn't work on some Linux.  Don't use it.
+
+When generating a script file, 'cpo' was made empty.  This caused backslashes
+to disappear from mappings.  Set it to "B" to avoid that.
+
+Lots of typos in the documentation. (Campbell)
+
+When editing an existing (hidden) buffer, jump to the last used cursor
+position. (Madsen)
+
+On a Sun the xterm screen was not restored properly when suspending. (Madsen)
+
+When $VIMINIT is processed, 'nocompatible' was only set after processing it.
+
+Unix: Polling for a character wasn't done for GPM, Sniff and Xterm clipboard
+all together.  Cleaned up the code for using select() too.
+
+When executing external commands from the GUI, some typeahead was lost.  Added
+some code to regain as much typeahead as possible.
+
+When the window height is 5 lines or fewer, <PageDown> didn't use a one-line
+overlap, while <PageUp> does.  Made sure that <PageUp> uses the same overlap
+as <PageDown>, so that using them both always displays the same lines.
+
+Removed a few unused functions and variables (found with lint).
+
+Dictionary completion didn't use 'infercase'. (Raul)
+
+Configure tests failed when the Perl library was not in LD_LIBRARY_PATH.
+Don't use the Perl library for configure tests, add it to the linker line only
+when linking Vim.
+
+When using ncurses/terminfo, could get a 't_Sf' and 't_Sb' termcap entry that
+has "%d" instead of "%p1%d".  The light background colors didn't work then.
+
+GTK GUI with ncurses: Crashed when starting up in tputs().  Don't use tputs()
+when the GUI is active.
+
+Could use the ":let" command to set the "count", "shell_error" and "version"
+variables, but that didn't work.  Give an error message when trying to set
+them.
+
+On FreeBSD 3.0, tclsh is called tclsh8.0.  Adjusted configure.in to find it.
+
+When Vim is linked with -lncurses, but python uses -ltermcap, this causes
+trouble: "OOPS".  Configure now removes the -ltermcap.
+
+:@" and :*" didn't work properly, because the " was recognized as the start of
+a comment.
+
+Win32s GUI: Minimizing the console where a filter command runs in caused
+trouble for detecting that the filter command has finished. (Negri)
+
+After executing a filter command from an xterm, the mouse would be disabled.
+It would work again after changing the mode.
+
+Mac GUI: Crashed in newenv(). (St-Amant)
+
+The menus and mappings in mswin.vim didn't handle text ending in a NL
+correctly. (Acevedo)
+
+The ":k" command didn't check if it had a valid argument or extra characters.
+Now give a meaningful error message. (Webb)
+
+On SGI, the signal function doesn't always have three arguments.  Check for
+struct sigcontext to find out.  Might still be wrong...
+
+Could crash when using 'hlsearch' and search pattern is "^".
+
+When search patterns were saved and restored, status of no_hlsearch was not
+also saved and restored (from ":nohlsearch" command).
+
+When using setline() to make a line shorter, the cursor position was not
+adjusted.
+
+MS-DOS and Win95: When trying to edit a file and accidentally adding a slash
+or backslash at the end, the file was deleted.  Probably when trying to create
+the swap file.  Explicitly check for a trailing slash or backslash before
+trying to read a file.
+
+X11 GUI: When starting the GUI failed and received a deadly signal while
+setting the title, would lock up when trying to exit, because the title is
+reset again.  Avoid using mch_settitle() recursively.
+
+X11 GUI: When starting the GUI fails, and then trying it again, would crash,
+because argv[] has been freed and x11_display was reset to NULL.
+
+Win32: When $HOME was set, would put "~user" in the swap file, which would
+never compare with a file name, and never cause the attention message.  Put
+the full path in the swap file instead.
+
+Win32 console: There were funny characters at the end of the "vim -r" swap
+files message (direct output of CR CR LF).
+
+DOS 32 bit: "vim -r" put the text at the top of the window.
+
+GUI: With 'mousefocus' set, got mouse codes as text with "!sleep 100" or "Q".
+
+Motif and Win32 GUI: When changing 'guifont' to a font of the same size the
+screen wasn't redrawn.
+
+Unix: When using ":make", jumping to a file b.c, which is already open as a
+symbolic link a.c, opened a new buffer instead of using the existing one.
+
+Inserting text in the current buffer while sourcing the .vimrc file would
+cause a crash or hang.  The memfile for the current buffer was never
+allocated.  Now it's allocated as soon as something is written in the buffer.
+
+DOS 32 bit: "lightblue" background worked for text, but not drawn parts were
+black.
+
+DOS: Colors of console were not restored upon exiting.
+
+When recording, with 'cmdheight' set to 2 and typing Esc> in Insert mode
+caused the "recording" message to be doubled.
+
+Spurious "file changed" messages could happen on Windows.  Now tolerate a one
+second difference, like for Linux.
+
+GUI: When returning from Ex mode, scrollbars were not updated.
+
+Win32: Copying text to the clipboard containing a <CR>, pasting it would
+replace it with a <NL> and drop the next character.
+
+Entering a double byte character didn't work if the second byte is in [xXoO].
+(Eric Lee)
+
+vim_realloc was both defined and had a prototype in proto/misc2.pro.  Caused
+conflicts on Solaris.
+
+A pattern in an autocommand was treated differently on DOS et al. than on
+Unix.  Now it's the same, also when using backslashes.
+
+When using <Tab> twice for command line completion, without a match, the <Tab>
+would be inserted. (Negri)
+
+Bug in MS-Visual C++ 6.0 when compiling ex_docmd.c with optimization. (Negri)
+
+Testing the result of mktemp() for failure was wrong.  Could cause a crash.
+(Peters)
+
+GUI: When checking for a ".gvimrc" file in the current directory, didn't check
+for a "_gvimrc" file too.
+
+Motif GUI: When using the popup menu and then adding an item to the menu bar,
+the menu bar would get very high.
+
+Mouse clicks and special keys (e.g. cursor keys) quit the more prompt and
+dialogs.  Now they are ignored.
+
+When at the more-prompt, xterm selection didn't work.  Now use the 'r' flag in
+'mouse' also for the more-prompt.
+
+When selecting a Visual area of more than 1023 lines, with 'guioptions' set to
+"a", could mess up the display because of a message in free_yank().  Removed
+that message, except for the Amiga.
+
+Moved auto-selection from ui_write() to the screen update functions.  Avoids
+unexpected behavior from a low-level function.  Also makes the different
+feedback of owning the selection possible.
+
+Vi incompatibility: Using "i<CR>" in an indent, with 'ai' set, used the
+original indent instead of truncating it at the cursor. (Webb)
+
+":echo x" didn't stop at "q" for the more prompt.
+
+Various fixes for Macintosh. (St-Amant)
+
+When using 'selectmode' set to "exclusive", selecting a word and then using
+CTRL-] included the character under the cursor.
+
+Using ":let a:name" in a function caused a crash. (Webb)
+
+When using ":append", an empty line didn't scroll up.
+
+DOS etc.: A file name starting with '!' didn't work.  Added '!' to default for
+'isfname'.
+
+BeOS: Compilation problem with prototype of skip_class_name(). (Price)
+
+When deleting more than one line, e.g., with "de", could still use "U"
+command, which didn't work properly then.
+
+Amiga: Could not compile ex_docmd.c, it was getting too big.  Moved some
+functions to ex_cmds.c.
+
+The expand() function would add a trailing slash for directories.
+
+Didn't give an error message when trying to assign a value to an argument of a
+function.  (Webb)
+
+Moved including sys/ptem.h to after termios.h.  Needed for Sinix.
+
+OLE interface: Don't delete the object in CVimCF::Release() when the reference
+count becomes zero. (Cordell)
+VisVim could still crash on exit. (Erhardt)
+
+"case a: case b:" (two case statements in one line) aligned with the second
+case.  Now it uses one 'sw' for indent. (Webb)
+
+Font initialisation wasn't right for Athena/Motif GUI.  Moved the call to
+highlight_gui_started() gui_mch_init() to gui_mch_open(). (Nam)
+
+In Replace mode, backspacing over a TAB before where the replace mode started
+while 'sts' is different from 'ts', would delete the TAB.
+
+Win32 console: When executing external commands and switching between the two
+console screens, Vim would copy the text between the buffers.  That caused the
+screen to be messed up for backtick expansion.
+
+":winpos -1" then ":winpos" gave wrong error message.
+
+Windows commander creates files called c:\tmp\$wc\abc.txt.  Don't remove the
+backslash before the $.  Environment variables were not expanded anyway,
+because of the backslash before the dollar.
+
+Using "-=" with ":set" could remove half a part when it contains a "\,".
+E.g., ":set path+=a\\,b" and then "set path-=b"  removed ",b".
+
+When Visually selecting lines, with 'selection' set to "inclusive", including
+the last char of the line, "<<" moved an extra line.  Also for other operators
+that always work on lines.
+
+link.sh changed "-lnsl_s" to "_s" when looking for "nsl" to be removed.
+Now it only remove whole words.
+
+When jumped to a mark or using "fz", and there is an error, the current column
+was lost.  E.g. when using "$fzj".
+
+The "g CTRL-G" command could not be interrupted, even though it can take a
+long time.
+
+Some terminals do have <F4> and <xF4>.  <xF4> was always interpreted as <F4>.
+Now map <xF4> to <F4>, so that the user can override this.
+
+When compiling os_win32.c with MIN_FEAT the apply_autocmds() should not be
+used. (Aaron)
+
+This autocommand looped forever: ":au FileChangedShell * nested e <afile>"
+Now FileChangeShell never nests. (Roemer)
+
+When evaluating an ":elseif" that was not going to matter anyway, ignore
+errors. (Roemer)
+
+GUI Lesstif: Tearoff bar was the last item, instead of the first.
+
+GUI Motif: Colors of tear-off widgets was wrong when 't' flag added to
+'guioptions' afterwards.  When 't' flag in 'guioptions' is excluded, would
+still get a tearoff item in a new menu.
+
+An inode number can be "long long".  Use ino_t instead of long.  Added
+configure check for ino_t.
+
+Binary search for tags was using a file offset "long" instead of "off_t".
+
+Insert mode completion of tags was not using 'ignorecase' properly.
+
+In Insert mode, the <xFn> keys were not properly mapped to <Fn> for the
+default mappings.  Also caused errors for ":mkvimrc" and ":mksession".
+
+When jumping to another window while in Insert mode, would get the "warning:
+changing readonly file" even when not making a change.
+
+A '(' or '{' inside a trailing "//" comment would disturb C-indenting.
+When using two labels below each other, the second one was not indented
+properly.  Comments could mess up C-indenting in many places.  (Roemer)
+
+Could delete or redefine a function while it was being used.  Could cause a
+crash.
+In a function it's logical to prepend "g:" to a system variable, but this
+didn't work. (Roemer)
+
+Hangul input: Buffer would overflow when user inputs invalid key sequence.
+(Nam)
+
+When BufLoad or BufEnter autocommands change the topline of the buffer in the
+window, it was overruled and the cursor put halfway the window.  Now only put
+the cursor halfway if the autocommands didn't change the topline.
+
+Calling exists("&option") always returned 1. (Roemer)
+
+Win32: Didn't take actually available memory into account. (Williams)
+
+White space after an automatically inserted comment leader was not removed
+when 'ai' is not set and <CR> hit just after inserting it. (Webb)
+
+A few menus had duplicated accelerators. (Roemer)
+
+Spelling errors in documentation, quite a few "the the". (Roemer)
+
+Missing prototypes for Macintosh. (Kielhorn)
+
+Win32: When using 'shellquote' or 'shellxquote', the "!start cmd" wasn't
+executed in a disconnected process.
+
+When resizing the window, causing a line before the cursor to wrap or unwrap,
+the cursor was displayed in the wrong position.
+
+There was quite a bit of dead code when compiling with minimal features.
+
+When doing a ":%s///" command that makes lines shorter, such that lines above
+the final cursor position no longer wrap, the cursor position was not updated.
+
+get_id_list() could allocate an array one too small, when a "contains=" item
+has a wildcard that matches a group name that is added just after it.  E.g.:
+"contains=a.*b,axb".  Give an error message for it.
+
+When yanking a Visual area and using the middle mouse button -> crash.  When
+clipboard doesn't work, now make "* always use "".
+
+Win32: Using ":buf a\ b\file" didn't work, it was interpreted as "ab\file".
+
+Using ":ts ident", then hit <CR>, with 'cmdheight' set to 2: command line was
+not cleared, the tselect prompt was on the last but one line.
+
+mksession didn't restore the cursor column properly when it was after a tab.
+Could not get all windows back when using a smaller terminal screen.  Didn't
+restore all windows when "winsize" was not in 'sessionoptions'. (Webb)
+
+Command line completion for ":buffer" depended on 'ignorecase' for Unix, but
+not for DOS et al..  Now don't use 'ignorecase', but let it depend on whether
+file names are case sensitive or not (like when expanding file names).
+
+Win32 GUI: (Negri)
+- Redrawing the background caused flicker when resizing the window.  Removed
+  _OnEraseBG().  Removed CS_HREDRAW and CS_VREDRAW flags from the
+  sndclass.style.
+- Some parts of the window were drawn in grey, instead of using the color from
+  the user color scheme.
+- Dropping a file on gvim didn't activate the window.
+- When there is no menu ('guioptions' excludes 'm'), never use the ALT key for
+  it.
+
+GUI: When resizing the window, would make the window height a bit smaller.
+Now round off to the nearest char cell size. (Negri)
+
+In Vi the ")" and "(" commands don't stop at a single space after a dot.
+Added 'J' flag in 'cpoptions' to make this behave Vi compatible. (Roemer)
+
+When saving a session without any buffers loaded, there would be a ":normal"
+command without arguments in it. (Webb)
+
+Memory leaks fixed: (Madsen)
+- eval.c: forgot to release func structure when func deleted
+- ex_docmd.c: forgot to release string after "<sfile>"
+- misc1.c: leak when completion pattern had no matches.
+- os_unix.c: forgot to release regexp after file completions
+
+Could crash when using a buffer without a name. (Madsen)
+Could crash when doing file name completion, because of backslash_halve().
+(Madsen)
+
+":@a" would do mappings on register a, which is not Vi compatible. (Roemer)
+
+":g/foo.*()/s/foobar/_&/gc" worked fine, but then "n" searched for "foobar"
+and displayed "/foo.*()". (Roemer)
+
+OS/2: get_cmd_output() was not included.  Didn't check for $VIM/.vimrc file.
+
+Command line completion of options didn't work after "+=" and "-=".
+
+Unix configure: Test for memmove()/bcopy()/memcpy() tried redefining these
+functions, which could fail if they are defined already.  Use mch_memmove() to
+redefine.
+
+Unix: ":let a = expand("`xterm`&")" started an xterm asynchronously, but
+":let a = expand("`xterm&`")" generated an error message, because the
+redirection was put after the '&'.
+
+Win32 GUI: Dialog buttons could not be selected properly with cursor keys,
+when the default is not the first button. (Webb)
+
+The "File has changed since editing started" (when regaining focus) could not
+always be seen. (Webb)
+
+When starting with "ex filename", the file message was overwritten with
+the "entering Ex mode" message.
+
+Output of ":tselect" listed name of file directly from the tags file.  Now it
+is corrected for the position of the tags file.
+
+When 'backspace' is 0, could backspace over autoindent.  Now it is no longer
+allowed (Vi compatible).
+
+In Replace mode, when 'noexpandtab' and 'smarttab' were set, and inserting
+Tabs, backspacing didn't work correctly for Tabs inserted at the start of the
+line (unless 'sts' was set too).  Also, when replacing the first non-blank
+after which is a space, rounding the indent was done on the first non-blank
+instead of on the character under the cursor.
+
+When 'sw' at 4, 'ts' at 8 and 'smarttab' set: When a tab was appended after
+four spaces (they are replaced with a tab) couldn't backspace over the tab.
+
+In Insert mode, with 'bs' set to 0, couldn't backspace to before autoindent,
+even when it was removed with CTRL-D.
+
+When repeating an insert command where a <BS>, <Left> or other key causes an
+error, would flush buffers and remain in Insert mode.  No longer flush
+buffers, only beep and continue with the insert command.
+
+Dos and Win32 console: Setting t_me didn't work to get another color.  Made
+this works backwards compatible.
+
+For Turkish (LANG = "tr") uppercase 'i' is not an 'I'.  Use ASCII uppercase
+translation in vim_strup() to avoid language problems. (Komur)
+
+Unix: Use usleep() or nanosleep() for mch_delay() when available.  Hopefully
+this avoids a hangup in select(0, ..) for Solaris 2.6.
+
+Vim would crash when using a script file with 'let &sp = "| tee"', starting
+vim with "vim -u test", then doing ":set sp=".  The P_WAS_SET flag wasn't set
+for a string option, could cause problems with any string option.
+
+When using "cmd | vim -", stdin is not a terminal.  This gave problems with
+GPM (Linux console mouse) and when executing external commands.  Now close
+stdin and re-open it as a copy of stderr.
+
+Syntax highlighting: A "nextgroup" item was not properly stored in the state
+list.  This caused missing of next groups when not redrawing from start to
+end, but starting halfway.
+
+Didn't check for valid values of 'ttymouse'.
+
+When executing an external command from the GUI, waiting for the child to
+terminate might not work, causing a hang. (Parmelan)
+
+"make uninstall" didn't delete the vimrc_example.vim and gvimrc_example.vim
+files and the vimtutor.
+
+Win32: "expand("%:p:h")" with no buffer name removed the directory name.
+"fnamemodify("", ":p")" did not add a trailing slash, fname_case() removed it.
+
+Fixed: When 'hlsearch' was set and the 'c' flag was not in 'cpoptions':
+highlighting was not correct.  Now overlapping matches are handled correctly.
+
+Athena, Motif and GTK GUI: When started without focus, cursor was shown as if
+with focus.
+
+Don't include 'shellpipe' when compiled without quickfix, it's not used.
+Don't include 'dictionary' option when compiled without the +insert_expand
+feature.
+Only include the 'shelltype' option for the Amiga.
+
+When making a change to a line, with 'hlsearch' on, causing it to wrap, while
+executing a register, the screen would not be updated correctly.  This was a
+generic problem in update_screenline() being called while must_redraw is
+VALID.
+
+Using ":bdelete" in a BufUnload autocommand could cause a crash.  The window
+height was added to another window twice in close_window().
+
+Win32 GUI: When removing a menu item, the tearoff wasn't updated. (Negri)
+
+Some performance bottlenecks removed.  Allocating memory was not efficient.
+For Win32 checking for available memory was slow, don't check it every time
+now.  On NT obtaining the user name takes a long time, cache the result (for
+all systems).
+
+fnamemodify() with an argument ":~:." or ":.:~" didn't work properly.
+
+When editing a new file and exiting, the marks for the buffer were not saved
+in the viminfo file.
+
+":confirm only" didn't put up a dialog.
+
+These text objects didn't work when 'selection' was "exclusive": va( vi( va{
+vi{ va< vi< vi[ va[.
+
+The dialog for writing a readonly file didn't have a valid default. (Negri)
+
+The line number used for error messages when sourcing a file was reset when
+modelines were inspected.  It was wrong when executing a function.
+
+The file name and line number for an error message wasn't displayed when it
+was the same as for the last error, even when this was long ago.  Now reset
+the name/lnum after a hit-enter prompt.
+
+In a session file, a "%" in a file name caused trouble, because fprintf() was
+used to write it to the file.
+
+When skipping statements, a mark in an address wasn't skipped correctly:
+"ka|if 0|'ad|else|echo|endif". (Roemer)
+
+":wall" could overwrite a not-edited file without asking.
+
+GUI: When $DISPLAY was not set or starting the GUI failed in another way, the
+console mode then started with wrong colors and skipped initializations.  Now
+do an early check if the GUI can be started.  Don't source the menu.vim or
+gvimrc when it will not.  Also do normal terminal initializations if the GUI
+might not start.
+
+When using a BufEnter autocommand to position the cursor and scroll the
+window, the cursor was always put at the last used line and halfway the window
+anyhow.
+
+When 'wildmode' was set to "longest,list:full", ":e *.c<Tab><Tab>" didn't list
+the matches.  Also avoid that listing after a "longest" lists the wrong
+matches when the first expansion changed the string in front of the cursor.
+
+When using ":insert", ":append" or ":change" inside a while loop, was not able
+to break out of it with a CTRL-C.
+
+Win32: ":e ." took an awful long time before an error message when used in
+"C:\".  Was caused by adding another backslash and then trying to get the full
+name for "C:\\".
+
+":winpos -10 100" was working like ":winpos -10 -10", because a pointer was
+not advanced past the '-' sign.
+
+When obtaining the value of a hidden option, would give an error message.  Now
+just use a zero value.
+
+OS/2: Was using argv[0], even though it was not a useful name.  It could be
+just "vim", found in the search path.
+
+Xterm: ":set columns=78" didn't redraw properly (when lines wrap/unwrap) until
+after a delay of 'updatetime'.  Didn't check for the size-changed signal.
+
+'scrollbind' didn't work in Insert mode.
+Horizontal scrollbinding didn't always work for "0" and "$" commands (e.g.,
+when 'showcmd' was off).
+
+When compiled with minimal features but with GUI, switching on the mouse in an
+xterm caused garbage, because the mouse codes were not recognized.  Don't
+enable the mouse when it can't be recognized.  In the GUI it also didn't work,
+the arguments to the mouse code were not interpreted.
+
+When 'showbreak' used, in Insert mode, when the cursor is just after the last
+character in the line, which is also the in the rightmost column, the cursor
+position would be like the 'showbreak' string is shown, but it wasn't.
+
+Autocommands could move the cursor in a new file, so that CTRL-W i didn't show
+the right line.  Same for when using a filemark to jump to another file.
+
+When redefining the argument list, the title used for other windows could be
+showing the wrong info about the position in the argument list.  Also update
+this for a ":split" command without arguments.
+
+When editing file 97 of 13, ":Next" didn't work.  Now it goes to the last
+file in the argument list.
+
+Insert mode completion (for dictionaries or included files) could not be
+interrupted by typing an <Esc>.  Could get hit-enter prompt after line
+completion, or whenever the informative message would get too long.
+
+When using the ":edit" command to re-edit the same file, an autocommand to
+jump to the last cursor position caused the cursor to move.  Now set the last
+used cursor position to avoid this.
+
+When 'comments' has a part that starts with white space, formatting the
+comment didn't work.
+
+At the ":tselect" prompt Normal mode mappings were used.  That has been
+disabled.
+
+When 'selection' is not "old", some commands still didn't allow the cursor
+past the end-of-line in Visual mode.
+
+Athena: When a menu was deleted, it would appear again (but not functional)
+when adding another menu.  Now they don't reappear anymore (although they are
+not really deleted either).
+
+Borland C++ 4.x had an optimizer problem in fill_breakat_flags(). (Negri)
+
+"ze" didn't work when 'number' was on. (Davis)
+
+Win32 GUI: Intellimouse code didn't work properly on Windows 98. (Robinson)
+
+A few files were including proto.h a second time, after vim.h had already done
+that, which could cause problems with the vim_realloc() macro.
+
+Win32 console: <M-x> or ALT-x was not recognized.  Also keypad '+', '-' and
+'*'. (Negri)
+MS-DOS: <M-x> didn't work, produced a two-byte code.  Now the alphabetic and
+number keys work. (Negri)
+
+When finding a lot of matches for a tag completion, the check for avoiding
+double matches could take a lot of time.  Add a line_breakcheck() to be able
+to interrupt this. (Deshpande)
+
+When the command line was getting longer than the screen, the more-prompt
+would be given regularly, and the cursor position would be wrong.  Now only
+show the part of the command line that fits on the screen and force the cursor
+to be positioned on the visible part.  There can be text after the cursor
+which isn't editable.
+
+At the more prompt and with the console dialog, a cursor key was interpreted
+as <Esc> and OA.  Now recognize special keys in get_keystroke().  Ignore mouse
+and scrollbar events.
+
+When typing a BS after inserting a middle comment leader, typing the last char
+of the end comment leader still changed it into the end comment leader. (Webb)
+
+When a file system is full, writing to a swap file failed.  Now first try to
+write one block to the file.  Try next entry in 'dir' if it fails.
+
+When "~" is in 'whichwrap', doing "~" on last char of a line didn't update the
+display.
+
+Unix: Expanding wildcards for ":file {\\}" didn't work, because "\}" was
+translated to "}" before the shell got it.  Now don't remove backslashes when
+wildcards are going to be expanded.
+
+Unix: ":e /tmp/$uid" didn't work.  When expanding environment variables in a
+file name doesn't work, use the shell to expand the file name.  ":e /tmp/$tty"
+still doesn't work though.
+
+"make test" didn't always work on DOS/Windows for test30, because it depended
+on the external "echo" command.
+
+The link.sh script used "make" instead of $MAKE from the Makefile.  Caused
+problems for generating pathdef.c when "make" doesn't work properly.
+
+On versions that can do console and GUI: In the console a typed CSI code could
+cause trouble.
+
+The patterns in expression evaluation didn't ignore the 'l' flag in
+'cpoptions'.  This broke the working of <CR> in the options window.
+
+When 'hls' off and 'ai' on, "O<Esc>" did remove the indent, but it was still
+highlighted red for trailing space.
+
+Win32 GUI: Dropping an encrypted file on a running gvim didn't work right.  Vim
+would loop while outputting "*" characters.  vgetc() was called recursively,
+thus it returns NUL.  Added safe_vgetc(), which reads input directly from the
+user in this situation.
+
+While reading text from stdin, only an empty screen was shown.  Now show that
+Vim is reading from stdin.
+
+The cursor shape wasn't set properly when returning to Insert mode, after
+using a CTRL-O /asdf command which fails.  It would be OK after a few seconds.
+Now it's OK right away.
+
+The 'isfname' default for DOS/Windows didn't include the '@' character.  File
+names that contained "dir\@file" could not be edited.
+
+Win32 console: <C-S-Left> could cause a crash when compiled with Borland or
+egcs. (Aaron)
+
+Unix and VMS: "#if HAVE_DIRENT_H" caused problems for some compilers.  Use
+"#ifdef HAVE_DIRENT_H" instead. (Jones)
+
+When a matching tag is in the current file but has a search pattern that
+doesn't match, the cursor would jump to the first line.
+
+Unix: Dependencies for pty.c were not included in Makefile.  Dependency of
+ctags/config.h was not included (only matters for parallel make).
+
+Removed a few Uninitialized Memory Reads (potential crashes).  In do_call()
+calling clear_var() when not evaluating.  In win32_expandpath() and
+dos_expandpath() calling backslash_halve() past the end of a file name.
+
+Removed memory leaks: Set_vim_var_string() never freed the value.  The
+next_list for a syntax keyword was never freed.
+
+On non-Unix systems, using a file name with wildcards without a match would
+silently fail.  E.g., ":e *.sh".  Now give a "No match" error message.
+
+The life/life.mac, urm/urm.mac and hanoi/hanoi.mac files were not recognized
+as Vim scripts.  Renamed them to *.vim.
+
+[Note: some numbered patches are not relevant when upgrading from version 5.3,
+they have been removed]
+
+Patch 5.4m.1
+Problem:    When editing a file with a long name, would get the hit-enter
+	    prompt, even though all settings are such that the name should be
+	    truncated to avoid that.  filemess() was printing the file name
+	    without truncating it.
+Solution:   Truncate the message in filemess().  Use the same code as for
+	    msg_trunc_attr(), which is moved to the new function
+	    msg_may_trunc().
+Files:	    src/message.c, src/proto/message.pro, src/fileio.c
+
+Patch 5.4m.3
+Problem:    The Motif libraries were not found by configure for Digital Unix.
+Solution:   Add "/usr/shlib" to the search path. (Andy Kahn)
+Files:	    src/configure.in, src/configure
+
+Patch 5.4m.5
+Problem:    Win32 GUI: When using the Save-As menu entry and selecting an
+	    existing file in the file browser, would get a dialog to confirm
+	    overwriting twice.  (Ed Krall)
+Solution:   Removed the dialog from the file browser.  It would be nicer to
+	    set the "forceit" flag and skip Vim's ":confirm" dialog, but it
+	    requires quite a few changes to do that.
+Files:	    src/gui_w32.c
+
+Patch 5.4m.6
+Problem:    Win32 GUI: When reading text from stdin, e.g., "cat foo | gvim -",
+	    a message box would pop up with "-stdin-" (when exiting). (Michael
+	    Schaap)
+Solution:   Don't switch off termcap mode for versions that are GUI-only.
+	    They use another terminal to read from stdin.
+Files:	    src/main.c, src/fileio.c
+
+Patch 5.4m.7
+Problem:    Unix: running configure with --enable-gtk-check,
+	    --enable-motif-check, --enable-athena-check or --enable-gtktest
+	    had the reverse effect. (Thomas Koehler)
+Solution:   Use $enable_gtk_check variable correctly in AC_ARG_ENABLE().
+Files:	    src/configure.in, src/configure
+
+Patch 5.4m.9
+Problem:    Multi-byte: With wrapping lines, the cursor was sometimes 2
+	    characters to the left.  Syntax highlighting was wrong when a
+	    double-byte character was split for a wrapping line.  When
+	    'showbreak' was on the splitting also didn't work.
+Solution:   Adjust getvcol() and win_line(). (Chong-Dae Park)
+Files:	    src/charset.c, src/screen.c
+
+Patch 5.4m.11
+Problem:    The ":call" command didn't check for illegal trailing characters.
+	    (Stefan Roemer)
+Solution:   Add the check in do_call().
+Files:	    src/eval.c
+
+Patch 5.4m.13
+Problem:    With the ":s" command:
+	    1. When performing a substitute command, the mouse would be
+	       disabled and enabled for every substitution.
+	    2. The cursor position could be beyond the end of the line.
+	       Calling line_breakcheck() could try to position the cursor,
+	       which causes a crash in the Win32 GUI.
+	    3. When using ":s" in a ":g" command, the cursor was not put on
+	       the first non-white in the line.
+	    4. There was a hit-enter prompt when confirming the substitution
+	       and the replacement was a bit longer.
+Solution:   1. Only disable/enable the mouse when asking for confirmation.
+	    2. Always put the cursor on the first character, it is going to be
+	       moved to the first non-blank anyway.
+	       Don't use the cursor position in gui_mch_draw_hollow_cursor(),
+	       get the character from the screen buffer.
+	    3. Added global_need_beginline flag to call beginline() after ":g"
+	       has finished all substitutions.
+	    4. Clear the need_wait_return flag after prompting the user.
+Files:	    src/ex_cmds.c, src/gui_w32.c
+
+Patch 5.4m.14
+Problem:    When doing "vim xxx", ":opt", ":only" and then ":e xxx" we end
+	    up with two swapfiles for "xxx".  That is caused by the ":bdel"
+	    command which is executed when unloading the option-window.
+	    Also, there was no check if closing a buffer made the new one
+	    invalid, this could cause a crash.
+Solution:   When closing a buffer causes the current buffer to be deleted,
+	    use the new buffer to replace it.  Also detect that the new buffer
+	    has become invalid as a side effect of closing the current one.
+	    Make autocommand that calls ":bdel" in optwin.vim nested, so that
+	    the buffer loading it triggers also executes autocommands.
+	    Also added a test for this in test13.
+Files:	    runtime/optwin.vim, src/buffer.c, src/ex_cmds.c, src/globals.h
+	    src/testdir/test13.in, src/testdir/test13.ok
+
+Patch 5.4m.15
+Problem:    When using a BufEnter autocommand to reload the syntax file,
+	    conversion to HTML caused a crash. (Sung-Hyun Nam)
+Solution:   When using ":syntax clear" the current stack of syntax items was
+	    not cleared.  This will cause memory to be used that has already
+	    been freed.  Added call to invalidate_current_state() in
+	    syntax_clear().
+Files:	    src/syntax.c
+
+Patch 5.4m.17
+Problem:    When omitting a ')' in an expression it would not be seen as a
+	    failure.
+	    When detecting an error inside (), there would be an error message
+	    for a missing ')' too.
+	    When using ":echo 1+|echo 2" there was no error message. (Roemer)
+	    When using ":exe 1+" there was no error message.
+	    When using ":return 1+" there was no error message.
+Solution:   Fix do_echo(), do_execute() and do_return() to give an error
+	    message when eval1() returns FAIL.
+	    Fix eval6() to handle trailing ')' correctly and return FAIL when
+	    it's missing.
+Files:	    src/eval.c
+
+Patch 5.4m.18
+Problem:    When using input() from inside an expression entered with
+	    "CTRL-R =" on the command line, there could be a crash.  And the
+	    resulting command line was wrong.
+Solution:   Added getcmdline_prompt(), which handles recursive use of
+	    getcmdline() correctly.  It also sets the command line prompt.
+	    Removed cmdline_prompt().  Also use getcmdline_prompt() for
+	    getting the crypt key in get_crypt_key().
+Files:	    src/proto/ex_getln.pro, src/ex_getln.c, src/eval.c, src/misc2.c
+
+Patch 5.4m.21
+Problem:    When starting up, the screen structures were first allocated at
+	    the minimal size, then initializations were done with Rows
+	    possibly different from screen_Rows.  Caused a crash in rare
+	    situations (GTK with XIM and fontset).
+Solution:   Call screenalloc() in main() only after calling ui_get_winsize().
+	    Also avoids a potential delay because of calling screenclear()
+	    while "starting" is non-zero.
+Files:	    src/main.c
+
+Patch 5.4m.22
+Problem:    In the GUI it was possible that the screen was resized and the
+	    screen structures re-allocated while redrawing the screen.  This
+	    could cause a crash (hard to reproduce).  The call sequence goes
+	    through update_screen() .. syntax_start() .. ui_breakcheck() ..
+	    gui_resize_window() .. screenalloc().
+Solution:   Set updating_screen while redrawing.  If the window is resized
+	    remember the new size and handle it only after redrawing is
+	    finished.
+	    This also fixes that resizing the screen while still redrawing
+	    (slow syntax highlighting) would not work properly.
+	    Also disable display_hint, it was never used.
+Files:	    src/globals.h, src/gui.c, src/screen.c, src/proto/gui.pro
+
+Patch 5.4m.23
+Problem:    When using expand("<cword>") when there was no word under the
+	    cursor, would get an error message.  Same for <cWORD> and <cfile>.
+Solution:   Don't give an error message, return an empty string.
+Files:	    src/eval.c
+
+Patch 5.4m.24
+Problem:    ":help \|" didn't find anything.  It was translated to "/\\|".
+Solution:   Translate "\|" into "\\bar".  First check the table for specific
+	    translations before checking for "\x".
+Files:	    src/ex_cmds.c
+
+Patch 5.4m.25
+Problem:    Unix: When using command line completion on files that contain
+	    ''', '"' or '|' the file name could not be used.
+	    Adding this file name to the Buffers menu caused an error message.
+Solution:   Insert a backslash before these three characters.
+	    Adjust Mungename() function to insert a backslash before '|'.
+Files:	    src/ex_getln.c, runtime/menu.vim
+
+Patch 5.4m.26
+Problem:    When using a mapping of two function keys, e.g., <F1><F1>, and
+	    only the first char of the second key has been read, the mapping
+	    would not be recognized.  Noticed on some Unix systems with xterm.
+Solution:   Add 'K' flag to 'cpoptions' to wait for the whole key code, even
+	    when halfway a mapping.
+Files:	    src/option.h, src/term.c
+
+Patch 5.4m.27
+Problem:    When making test33 without the lisp feature it hangs. Interrupting
+	    the execution of the script then might cause a crash.
+Solution:   In inchar(), after closing a script, don't use buf[] anymore.
+	    closescript() has freed typebuf[] and buf[] might be pointing
+	    inside typebuf[].
+	    Avoid that test33 hangs when the lisp feature is missing.
+Files:	    src/getchar.c src/testdir/test33.in
+
+"os2" was missing from the feature list.  Useful for has("os2").
+
+BeOS:
+- Included patches from Richard Offer for BeOS R4.5.
+- menu code didn't work right.  Crashed in the Buffers menu.  The window title
+  wasn't set. (Offer)
+
+Patch 5.4n.3
+Problem:    C-indenting was wrong after "  } else".  The white space was not
+	    skipped.  Visible when 'cino' has "+10".
+Solution:   Skip white space before calling cin_iselse(). (Norbert Zeh)
+Files:	    src/misc1.c
+
+Patch 5.4n.4
+Problem:    When the 't' flag in 'cpoptions' is included, after a
+	    ":nohlsearch" the search highlighting would not be enabled again
+	    after a tag search. (Norbert Zeh)
+Solution:   When setting the new search pattern in jumpto_tag(), don't restore
+	    no_hlsearch.
+Files:	    src/tag.c
+
+Patch 5.4n.5
+Problem:    When using ":normal" from a CursorHold autocommand Vim hangs.  The
+	    autocommand is executed down from vgetc().  Calling vgetc()
+	    recursively to execute the command doesn't work then.
+Solution:   Forbid the use of ":normal" when vgetc_busy is set.  Give an error
+	    message when this happens.
+Files:	    src/ex_docmd.c, runtime/doc/autocmd.txt
+
+Patch 5.4n.6
+Problem:    "gv" could reselect a Visual that starts and/or ends past the end
+	    of a line. (Robert Webb)
+Solution:   Check that the start and end of the Visual area are on a valid
+	    character by calling adjust_cursor().
+Files:	    src/normal.c
+
+Patch 5.4n.8
+Problem:    When a mark was on a non existing line (e.g., when the .viminfo
+	    was edited), jumping to it caused ml_get errors. (Alexey
+	    Marinichev).
+Solution:   Added check_cursor_lnum() in nv_gomark().
+Files:	    src/normal.c
+
+Patch 5.4n.9
+Problem:    ":-2" moved the cursor to a negative line number. (Ralf Schandl)
+Solution:   Give an error message for a negative line number.
+Files:	    src/ex_docmd.c
+
+Patch 5.4n.10
+Problem:    Win32 GUI: At the hit-enter prompt, it was possible to scroll the
+	    text.  This erased the prompt and made Vim look like it is in
+	    Normal mode, while it is actually still waiting for a <CR>.
+Solution:   Disallow scrolling at the hit-enter prompt for systems that use
+	    on the fly scrolling.
+Files:	    src/message.c
+
+Patch 5.4n.14
+Problem:    Win32 GUI: When using ":winsize 80 46" and the height is more than
+	    what fits on the screen, the window size was made smaller than
+	    asked for (that's OK) and Vim crashed (that's not OK)>
+Solution:   Call check_winsize() from gui_set_winsize() to resize the windows.
+Files:	    src/gui.c
+
+Patch 5.4n.16
+Problem:    Win32 GUI: The <F10> key both selected the menu and was handled as
+	    a key hit.
+Solution:   Apply 'winaltkeys' to <F10>, like it is used for Alt keys.
+Files:	    src/gui_w32.c
+
+Patch 5.4n.17
+Problem:    Local buffer variables were freed when the buffer is unloaded.
+	    That's not logical, since options are not freed. (Ron Aaron)
+Solution:   Free local buffer variables only when deleting the buffer.
+Files:	    src/buffer.c
+
+Patch 5.4n.19
+Problem:    Doing ":e" (without argument) in an option-window causes trouble.
+	    The mappings for <CR> and <Space> are not removed.  When there is
+	    another buffer loaded, the swap file for it gets mixed up.
+	    (Steve Mueller)
+Solution:   Also remove the mappings at the BufUnload event, if they are still
+	    present.
+	    When re-editing the same file causes the current buffer to be
+	    deleted, don't try editing it.
+	    Also added a test for this situation.
+Files:	    runtime/optwin.vim, src/ex_cmds.c, src/testdir/test13.in,
+	    src/testdir/test13.ok
+
+Patch 5.4n.24
+Problem:    BeOS: configure never enabled the GUI, because $with_x was "no".
+	    Unix prototypes caused problems, because Display and Widget are
+	    undefined.
+	    Freeing fonts on exit caused a crash.
+Solution:   Only disable the GUI when $with_x is "no" and  $BEOS is not "yes".
+	    Add dummy defines for Display and Widget in proto.h.
+	    Don't free the fonts in gui_exit() for BeOS.
+Files:	    src/configure.in, src/configure, src/proto.h, src/gui.c.
+
+
+The runtime/vim48x48.xpm icon didn't have a transparent background. (Schild)
+
+Some versions of the mingw32/egcs compiler didn't have WINBASEAPI defined.
+(Aaron)
+
+VMS:
+- mch_setenv() had two arguments instead of three.
+- The system vimrc and gvimrc files were called ".vimrc" and ".gvimrc".
+  Removed the dot.
+- call to RealWaitForChar() had one argument too many. (Campbell)
+- WaitForChar() is static, removed the prototype from proto/os_vms.pro.
+- Many file accesses failed, because Unix style file names were used.
+  Translate file names to VMS style by using vim_fopen().
+- Filtering didn't work, because the temporary file name was generated wrong.
+- There was an extra newline every 9192 characters when writing a file.  Work
+  around it by writing line by line. (Campbell)
+- os_vms.c contained "# typedef int DESC".  Should be "typedef int DESC;".
+  Only mattered for generating prototypes.
+- Added file name translation to many places.  Made easy by defining macros
+  mch_access(), mch_fopen(), mch_fstat(), mch_lstat() and mch_stat().
+- Set default for 'tagbsearch' to off, because binary tag searching apparently
+  doesn't work for VMS.
+- make mch_get_host_name() work with /dec and /standard=vaxc. (Campbell)
+
+
+Patch 5.4o.2
+Problem:    Crash when using "gf" on "file.c://comment here". (Scott Graham)
+Solution:   Fix wrong use of pointers in get_file_name_in_path().
+Files:	    src/window.c
+
+Patch 5.4o.3
+Problem:    The horizontal scrollbar was not sized correctly when 'number' is
+	    set and 'wrap' not set.
+	    Athena: Horizontal scrollbar wasn't updated when the cursor was
+	    positioned with a mouse click just after dragging.
+Solution:   Subtract 8 from the size when 'number' set and 'wrap' not set.
+	    Reset gui.dragged_sb when a mouse click is received.
+Files:	    src/gui.c
+
+Patch 5.4o.4
+Problem:    When running in an xterm and $WINDOWID is set to an illegal value,
+	    Vim would exit with "Vim: Got X error".
+Solution:   When using the display which was opened for the xterm clipboard,
+	    check if x11_window is valid by trying to obtain the window title.
+	    Also add a check in setup_xterm_clip(), for when using X calls to
+	    get the pointer position in an xterm.
+Files:	    src/os_unix.c
+
+Patch 5.4o.5
+Problem:    Motif version with Lesstif: When removing the menubar and then
+	    using a menu shortcut key, Vim would crash. (raf)
+Solution:   Disable the menu mnemonics when the menu bar is removed.
+Files:	    src/gui_motif.c
+
+Patch 5.4o.9
+Problem:    The DOS install.exe program used the "move" program.  That doesn't
+	    work on Windows NT, where "move" is internal to cmd.exe.
+Solution:   Don't use an external program for moving the executables.  Use C
+	    functions to copy the file and delete the original.
+Files:	    src/dosinst.c
+
+Motif and Athena obtained the status area height differently from GTK.  Moved
+status_area_enabled from global.h to gui_x11.c and call
+xim_get_status_area_height() to get the status area height.
+
+Patch 5.4p.1
+Problem:    When using auto-select, and the "gv" command is used, would not
+	    always obtain ownership of the selection.  Caused by the Visual
+	    area still being the same, but ownership taken away by another
+	    program.
+Solution:   Reset the clipboard Visual mode to force updating the selection.
+Files:	    src/normal.c
+
+Patch 5.4p.2
+Problem:    Motif and Athena with XIM: Typing 3-byte
+	    <multibyte><multibyte><space> doesn't work correctly with Ami XIM.
+Solution:   Avoid using key_sym XK_VoidSymbol. (Nam)
+Files:	    src/multbyte.c, src/gui_x11.c
+
+Patch 5.4p.4
+Problem:    Win32 GUI: The scrollbar values were reduced for a file with more
+	    than 32767 lines.  But this info was kept global for all
+	    scrollbars, causing a mixup between the windows.
+	    Using the down arrow of a scrollbar in a large file didn't work.
+	    Because of round-off errors there is no scroll at all.
+Solution:   Give each scrollbar its own scroll_shift field.  When the down
+	    arrow is used, scroll several lines.
+Files:	    src/gui.h, src/gui_w32.c
+
+Patch 5.4p.5
+Problem:    When changing buffers in a BufDelete autocommand, there could be
+	    ml_line errors and/or a crash. (Schandl)  Was caused by deleting
+	    the current buffer.
+Solution:   When the buffer to be deleted unexpectedly becomes the current
+	    buffer, don't delete it.
+	    Also added a check for this in test13.
+Files:	    src/buffer.c, src/testdir/test13.in, src/testdir/test13.ok
+
+Patch 5.4p.7
+Problem:    Win32 GUI: When using 'mousemodel' set to "popup_setpos" and
+	    clicking the right mouse button outside of the selected area, the
+	    selected area wasn't removed until the popup menu has gone.
+	    (Aaron)
+Solution:   Set the cursor and update the display before showing the popup
+	    menu.
+Files:	    src/normal.c
+
+Patch 5.4p.8
+Problem:    The generated bugreport didn't contain information about
+	    $VIMRUNTIME and whether runtime files actually exist.
+Solution:   Added a few checks to the bugreport script.
+Files:	    runtime/bugreport.vim
+
+Patch 5.4p.9
+Problem:    The windows install.exe created a wrong entry in the popup menu.
+	    The "%1" was "".  The full directory was included, even when the
+	    executable had been moved elsewhere. (Ott)
+Solution:   Double the '%' to get one from printf.  Only include the path to
+	    gvim.exe when it wasn't moved and it's not in $PATH.
+Files:	    src/dosinst.c
+
+Patch 5.4p.10
+Problem:    Win32: On top of 5.4p.9: The "Edit with Vim" entry sometimes used
+	    a short file name for a directory.
+Solution:   Change the "%1" to "%L" in the registry entry.
+Files:	    src/dosinst.c
+
+Patch 5.4p.11
+Problem:    Motif, Athena and GTK: When closing the GUI window when there is a
+	    changed buffer, there was only an error message and Vim would not
+	    exit.
+Solution:   Put up a dialog, like for ":confirm qa".  Uses the code that was
+	    already used for MS-Windows.
+Files:	    src/gui.c, src/gui_w32.c
+
+Patch 5.4p.12
+Problem:    Win32: Trying to expand a string that is longer than 256
+	    characters could cause a crash. (Steed)
+Solution:   For the buffer in win32_expandpath() don't use a fixed size array,
+	    allocate it.
+Files:	    src/os_win32.c
+
+MSDOS: Added "-Wall" to Makefile.djg compile flags.  Function prototypes for
+fname_case() and mch_update_cursor() were missing.  "fd" was unused in
+mf_sync().  "puiLocation" was unused in myputch().  "newcmd" unused in
+mch_call_shell() for DJGPP version.
+
+==============================================================================
+VERSION 5.5						*version-5.5*
+
+Version 5.5 is a bug-fix version of 5.4.
+
+
+Changed							*changed-5.5*
+-------
+
+The DJGPP version is now compiled with "-O2" instead of "-O4" to reduce the
+size of the executables.
+
+Moved the src/STYLE file to runtime/doc/develop.txt.  Added the design goals
+to it.
+
+'backspace' is now a string option.  See patch 5.4.15.
+
+
+Added							*added-5.5*
+-----
+
+Included Exuberant Ctags version 3.3. (Darren Hiebert)
+
+In runtime/mswin.vim, map CTRL-Q to CTRL-V, so that CTRL-Q can be used
+everywhere to do what CTRL-V used to do.
+
+Support for decompression of bzip2 files in vimrc_example.vim.
+
+When a patch is included, the patch number is entered in a table in version.c.
+This allows skipping a patch without breaking a next one.
+
+Support for mouse scroll wheel in X11.  See patch 5.5a.14.
+
+line2byte() can be used to get the size of the buffer.  See patch 5.4.35.
+
+The CTRL-R CTRL-O r and CTRL-R CTRL-P r commands in Insert mode are used to
+insert a register literally.  See patch 5.4.48.
+
+Uninstall program for MS-Windows.  To be able to remove the registry entries
+for "Edit with Vim".  It is registered to be run from the "Add/Remove
+programs" application.  See patch 5.4.x7.
+
+
+Fixed							*fixed-5.5*
+-----
+
+When using vimrc_example.vim: An error message when the cursor is on a line
+higher than the number of lines in the compressed file.  Move the autocommand
+for jumping to the last known cursor position to after the decompressing
+autocommands.
+
+":mkexrc" and ":mksession" wrote the current value of 'textmode'.  That may
+mark a file as modified, which causes problems.  This is a buffer-specific
+setting, it should not affect all files.
+
+"vim --version" wrote two empty lines.
+
+Unix: The alarm signal could kill Vim.  It is generated by the Perl alarm()
+function.  Ignore SIGALRM.
+
+Win32 GUI: Toolbar still had the yellow bitmap for running a Vim script.
+
+BeOS: "tmo" must be bigtime_t, instead of double. (Seibert)
+
+Patch 5.4.1
+Problem:    Test11 fails when $GZIP is set to "-v". (Matthew Jackson)
+Solution:   Set $GZIP to an empty string.
+Files:	    src/testdir/test11.in
+
+Patch 5.4.2
+Problem:    Typing <Esc> at the crypt key prompt caused a crash. (Kallingal)
+Solution:   Check for a NULL pointer returned from get_crypt_key().
+Files:	    src/fileio.c
+
+Patch 5.4.3
+Problem:    Python: Trying to use the name of an unnamed buffer caused a
+	    crash. (Daniel Burrows)
+Solution:   Check for b_fname being a NULL pointer.
+Files:	    src/if_python.c
+
+Patch 5.4.4
+Problem:    Win32: When compiled without toolbar, but the 'T' flag is in
+	    'guioptions', there would be an empty space for the toolbar.
+Solution:   Add two #ifdefs where checking for the 'T' flag. (Vince Negri)
+Files:	    src/gui.c
+
+Patch 5.4.5
+Problem:    Athena GUI: Using the Buffers.Refresh menu entry caused a crash.
+	    Looks like any ":unmenu" command may cause trouble.
+Solution:   Disallow ":unmenu" in the Athena version.  Disable the Buffers
+	    menu, because the Refresh item would not work.
+Files:	    src/menu.c, runtime/menu.vim
+
+Patch 5.4.6
+Problem:    GTK GUI: Using ":gui" in the .gvimrc file caused an error.  Only
+	    happens when the GUI forks.
+Solution:   Don't fork in a recursive call of gui_start().
+Files:	    src/gui.c
+
+Patch 5.4.7
+Problem:    Typing 'q' at the more prompt for the ATTENTION message causes the
+	    file loading to be interrupted. (Will Day)
+Solution:   Reset got_int after showing the ATTENTION message.
+Files:	    src/memline.c
+
+Patch 5.4.8
+Problem:    Edit some file, ":he", ":opt": options from help window are shown,
+	    but pressing space updates from the other window. (Phillipps)
+	    Also: When there are changes in the option-window, ":q!" gives an
+	    error message.
+Solution:   Before creating the option-window, go to a non-help window.
+	    Use ":bdel!" to delete the buffer.
+Files:	    runtime/optwin.vim
+
+Patch 5.4.9
+	    Just updates version.h.  The real patch has been moved to 5.4.x1.
+	    This patch is just to keep the version number correct.
+
+Patch 5.4.10
+Problem:    GTK GUI: When $DISPLAY is invalid, "gvim -f" just exits.  It
+	    should run in the terminal.
+Solution:   Use gtk_init_check() instead of gtk_init().
+Files:	    src/gui_gtk_x11.c
+
+Patch 5.4.11
+Problem:    When using the 'S' flag in 'cpoptions', 'tabstop' is not copied to
+	    the next buffer for some commands, e.g., ":buffer".
+Solution:   When the BCO_NOHELP flag is given to buf_copy_options(), still
+	    copy the options used by do_help() when neither the "from" or "to"
+	    buffer is a help buffer.
+Files:	    src/option.c
+
+Patch 5.4.12
+Problem:    When using 'smartindent', there would be no extra indent if the
+	    current line did not have any indent already. (Hanus Adler)
+Solution:   There was a wrongly placed "else", that previously matched with
+	    the "if" that set trunc_line.  Removed the "else" and added a
+	    check for trunc_line to be false.
+Files:	    src/misc1.c
+
+Patch 5.4.13
+Problem:    New SGI C compilers need another option for optimisation.
+Solution:   Add a check in configure for "-OPT:Olimit". (Chin A Young)
+Files:	    src/configure.in, src/configure
+
+Patch 5.4.14
+Problem:    Motif GUI: When the popup menu is present, a tiny window appears
+	    on the desktop for some users.
+Solution:   Set the menu widget ID for a popup menu to 0. (Thomas Koehler)
+Files:	    src/gui_motif.c
+
+Patch 5.4.15
+Problem:    Since 'backspace' set to 0 has been made Vi compatible, it is no
+	    longer possible to only allow deleting autoindent.
+Solution:   Make 'backspace' a list of parts, to allow each kind of
+	    backspacing separately.
+Files:	    src/edit.c, src/option.c, src/option.h, src/proto/option.pro,
+	    runtime/doc/option.txt, runtime/doc/insert.txt
+
+Patch 5.4.16
+Problem:    Multibyte: Locale zh_TW.Big5 was not checked for in configure.
+Solution:   Add zh_TW.Big5 to configure check. (Chih-Tsun Huang)
+Files:	    src/configure.in, src/configure
+
+Patch 5.4.17
+Problem:    GUI: When started from inside gvim with ":!gvim", Vim would not
+	    start.  ":!gvim -f" works fine.
+Solution:   After forking, wait a moment in the parent process, to give the
+	    child a chance to set its process group.
+Files:	    src/gui.c
+
+Patch 5.4.18
+Problem:    Python: The clear_history() function also exists in a library.
+Solution:   Rename clear_history() to clear_hist().
+Files:	    src/ex_getln.c, src/eval.c, src/proto/ex_getln.pro
+
+Patch 5.4.19
+Problem:    In a terminal with 25 lines, there is a more prompt after the
+	    ATTENTION message.  When hitting 'q' here the dialog prompt
+	    doesn't appear and file loading is interrupted. (Will Day)
+Solution:   Don't allow quitting the printing of a message for the dialog
+	    prompt.  Added the msg_noquit_more flag for this.
+Files:	    src/message.c
+
+Patch 5.4.20
+Problem:    GTK: When starting gvim, would send escape sequences to the
+	    terminal to switch the cursor off and on.
+Solution:   Don't call msg_start() if the GUI is expected to start.
+Files:	    src/main.c
+
+Patch 5.4.21
+Problem:    Motif: Toplevel menu ordering was wrong when using tear-off items.
+Solution:   Don't add one to the index for a toplevel menu.
+Files:	    src/gui_motif.c
+
+Patch 5.4.22
+Problem:    In Insert mode, <C-Left>, <S-Left>, <C-Right> and <S-Right> didn't
+	    update the column used for vertical movement.
+Solution:   Set curwin->w_set_curswant for those commands.
+Files:	    src/edit.c
+
+Patch 5.4.23
+Problem:    When a Visual selection is lost to another program, and then the
+	    same text is Visually selected again, the clipboard ownership
+	    wasn't regained.
+Solution:   Set clipboard.vmode to NUL to force regaining the clipboard.
+Files:	    src/normal.c
+
+Patch 5.4.24
+Problem:    Encryption: When using ":r file" while 'key' has already entered,
+	    the 'key' option would be messed up.  When writing the file it
+	    would be encrypted with an unknown key and lost! (Brad Despres)
+Solution:   Don't free cryptkey when it is equal to the 'key' option.
+Files:	    src/fileio.c
+
+Patch 5.4.25
+Problem:    When 'cindent' is set, but 'autoindent' isn't, comments are not
+	    properly indented when starting a new line. (Mitterand)
+Solution:   When there is a comment leader for the new line, but 'autoindent'
+	    isn't set, do C-indenting.
+Files:	    src/misc1.c
+
+Patch 5.4.26
+Problem:    Multi-byte: a multi-byte character is never recognized in a file
+	    name, causing a backslash before it to be removed on Windows.
+Solution:   Assume that a leading-byte character is a file name character in
+	    vim_isfilec().
+Files:	    src/charset.c
+
+Patch 5.4.27
+Problem:    Entries in the PopUp[nvic] menus were added for several modes, but
+	    only deleted for the mode they were used for.  This resulted in
+	    the  entry remaining in the PopUp menu.
+	    When removing a PopUp[nvic] menu, the name had been truncated,
+	    could result in greying-out the whole PopUp menu.
+Solution:   Remove entries for all modes from the PopUp[nvic] menus.  Remove
+	    the PopUp[nvic] menu entries first, before the name is changed.
+Files:	    src/menu.c
+
+Patch 5.4.28
+Problem:    When using a BufWritePre autocommand to change 'fileformat', the
+	    new value would not be used for writing the file.
+Solution:   Check 'fileformat' after executing the autocommands instead of
+	    before.
+Files:	    src/fileio.c
+
+Patch 5.4.29
+Problem:    Athena GUI: When removing the 'g' flag from 'guioptions', using a
+	    menu can result in a crash.
+Solution:   Always grey-out menus for Athena, don't hide them.
+Files:	    src/menu.c
+
+Patch 5.4.30
+Problem:    BeOS: Suspending Vim with CTRL-Z didn't work (killed Vim).  The
+	    first character typed after ":sh" goes to Vim, instead of the
+	    started shell.
+Solution:   Don't suspend Vim, start a new shell.  Kill the async read thread
+	    when starting a new shell.  It will be restarted later. (Will Day)
+Files:	    src/os_unix.c, src/ui.c
+
+Patch 5.4.31
+Problem:    GUI: When 'mousefocus' is set, moving the mouse over where a
+	    window boundary was, causes a hit-enter prompt to be finished.
+	    (Jeff Walker)
+Solution:   Don't use 'mousefocus' at the hit-enter prompt.  Also ignore it
+	    for the more prompt and a few other situations.  When an operator
+	    is pending, abort it first.
+Files:	    src/gui.c
+
+Patch 5.4.32
+Problem:    Unix: $LDFLAGS was not passed to configure.
+Solution:   Pass $LDFLAGS to configure just like $CFLAGS. (Jon Miner)
+Files:	    src/Makefile
+
+Patch 5.4.33
+Problem:    Unix: After expanding an environment variable with the shell, the
+	    next expansion would also use the shell, even though it is not
+	    needed.
+Solution:   Reset "recursive" before returning from gen_expand_wildcards().
+Files:	    src/misc1.c
+
+Patch 5.4.34 (also see 5.4.x5)
+Problem:    When editing a file, and the file name is relative to a directory
+	    above the current directory, the file name was made absolute.
+	    (Gregory Margo)
+Solution:   Add an argument to shorten_fnames() which indicates if all file
+	    names should be shortened, or only absolute names.  In main() only
+	    use shorten_fnames() to shorten absolute names.
+Files:	    src/ex_docmd.c, src/fileio.c, src/main.c, src/proto/fileio.pro
+
+Patch 5.4.35
+Problem:    There is no function to get the current file size.
+Solution:   Allow using line2byte() with the number of lines in the file plus
+	    one.  This returns the offset of the line past the end of the
+	    file, which is the file size plus one.
+Files:	    src/eval.c, runtime/doc/eval.txt
+
+Patch 5.4.36
+Problem:    Comparing strings while ignoring case didn't work correctly for
+	    some machines. (Mide Steed)
+Solution:   vim_stricmp() and vim_strnicmp() only returned 0 or 1.  Changed
+	    them to return -1 when the first argument is smaller.
+Files:	    src/misc2.c
+
+Patch 5.4.37 (also see 5.4.40 and 5.4.43)
+Problem:    Long strings from the viminfo file are truncated.
+Solution:   When writing a long string to the viminfo file, first write a line
+	    with the length, then the string itself in a second line.
+Files:	    src/eval.c, src/ex_cmds.c, src/ex_getln.c, src/mark.c, src/ops.c,
+	    src/search.c, src/proto/ex_cmds.pro, runtime/syntax/viminfo.vim
+
+Patch 5.4.38
+Problem:    In the option-window, ":set go&" resulted in 'go' being handled
+	    like a boolean option.
+	    Mappings for <Space> and <CR> were overruled by the option-window.
+Solution:   When the value of an option isn't 0 or 1, don't handle it like a
+	    boolean option.
+	    Save and restore mappings for <Space> and <CR> when entering and
+	    leaving the option-window.
+Files:	    runtime/optwin.vim
+
+Patch 5.4.39
+Problem:    When setting a hidden option, spaces before the equal sign were
+	    not skipped and cause an error message.  E.g., ":set csprg =cmd".
+Solution:   When skipping over a hidden option, check for a following "=val"
+	    and skip it too.
+Files:	    src/option.c
+
+Patch 5.4.40 (depends on 5.4.37)
+Problem:    Compiler error for "atol(p + 1)". (Axel Kielhorn)
+Solution:   Add a typecast: "atol((char *)p + 1)".
+Files:	    src/ex_cmds.c
+
+Patch 5.4.41
+Problem:    Some commands that were not included would give an error message,
+	    even when after "if 0".
+Solution:   Don't give an error message for an unsupported command when not
+	    executing the command.
+Files:	    src/ex_docmd.c
+
+Patch 5.4.42
+Problem:    ":w" would also cause a truncated message to appear in the message
+	    history.
+Solution:   Don't put a kept message in the message history when it starts
+	    with "<".
+Files:	    src/message.c
+
+Patch 5.4.43 (depends on 5.4.37)
+Problem:    Mixing long lines with multiple lines in a register causes errors
+	    when writing the viminfo file. (Robinson)
+Solution:   When reading the viminfo file to skip register contents, skip
+	    lines that start with "<".
+Files:	    src/ops.c
+
+Patch 5.4.44
+Problem:    When 'whichwrap' includes '~', a "~" command that goes on to the
+	    next line cannot be properly undone. (Zellner)
+Solution:   Save each line for undo in n_swapchar().
+Files:	    src/normal.c
+
+Patch 5.4.45 (also see 5.4.x8)
+Problem:    When expand("$ASDF") fails, there is an error message.
+Solution:   Remove the global expand_interactively.  Pass a flag down to skip
+	    the error message.
+	    Also: expand("$ASDF") returns an empty string if $ASDF isn't set.
+	    Previously it returned "$ASDF" when 'shell' is "sh".
+	    Also: system() doesn't print an error when the command returns an
+	    error code.
+Files:	    many
+
+Patch 5.4.46
+Problem:    Backspacing did not always use 'softtabstop' after hitting <CR>,
+	    inserting a register, moving the cursor, etc.
+Solution:   Reset inserted_space much more often in edit().
+Files:	    src/edit.c
+
+Patch 5.4.47
+Problem:    When executing BufWritePre or BufWritePost autocommands for a
+	    hidden buffer, the cursor could be moved to a non-existing
+	    position. (Vince Negri)
+Solution:   Save and restore the cursor and topline for the current window
+	    when it is going to be used to execute autocommands for a hidden
+	    buffer.  Use an existing window for the buffer when it's not
+	    hidden.
+Files:	    src/fileio.c
+
+Patch 5.4.48
+Problem:    A paste with the mouse in Insert mode was not repeated exactly the
+	    same with ".".  For example, when 'autoindent' is set and pasting
+	    text with leading indent. (Perry)
+Solution:   Add the CTRL-R CTRL-O r and CTRL-R CTRL-P r commands in Insert
+	    mode, which insert the contents of a register literally.
+Files:	    src/edit.c, src/normal.c, runtime/doc/insert.txt
+
+Patch 5.4.49
+Problem:    When pasting text with [ <MiddleMouse>, the cursor could end up
+	    after the last character of the line.
+Solution:   Correct the cursor position for the change in indent.
+Files:	    src/ops.c
+
+Patch 5.4.x1 (note: Replaces patch 5.4.9)
+Problem:    Win32 GUI: menu hints were never used, because WANT_MENU is not
+	    defined until vim.h is included.
+Solution:   Move the #ifdef WANT_MENU from where MENUHINTS is defined to where
+	    it is used.
+Files:	    src/gui_w32.c
+
+Patch 5.4.x2
+Problem:    BeOS: When pasting text, one character was moved to the end.
+Solution:   Re-enable the BeOS code in fill_input_buf(), and fix timing out
+	    with acquire_sem_etc(). (Will Day)
+Files:	    src/os_beos.c, src/ui.c
+
+Patch 5.4.x3
+Problem:    Win32 GUI: When dropping a directory on a running gvim it crashes.
+Solution:   Avoid using a NULL file name.  Also display a message to indicate
+	    that the current directory was changed.
+Files:	    src/gui_w32.c
+
+Patch 5.4.x4
+Problem:    Win32 GUI: Removing an item from the popup menu doesn't work.
+Solution:   Don't remove the item from the menubar, but from the parent popup
+	    menu.
+Files:	    src/gui_w32.c
+
+Patch 5.4.x5 (addition to 5.4.34)
+Files:	    src/gui_w32.c
+
+Patch 5.4.x6
+Problem:    Win32: Expanding (dir)name starting with a dot doesn't work.
+	    (McCormack)  Only when there is a path before it.
+Solution:   Fix the check, done before expansion, if the file name pattern
+	    starts with a dot.
+Files:	    src/os_win32.c
+
+Patch 5.4.x7
+Problem:    Win32 GUI: Removing "Edit with Vim" from registry is difficult.
+Solution:   Add uninstall program to remove the registry keys. It is installed
+	    in the "Add/Remove programs" list for ease of use.
+	    Also: don't set $VIM when the executable is with the runtime files.
+	    Also: Add a text file with a step-by-step description of how to
+	    uninstall Vim for DOS and Windows.
+Files:	    src/uninstal.c, src/dosinst.c, src/Makefile.w32, uninstal.txt
+
+Patch 5.4.x8 (addition to 5.4.45)
+Files:	    many
+
+Patch 5.4.x9
+Problem:    Win32 GUI: After executing an external command, focus is not
+	    always regained (when using focus-follows-mouse).
+Solution:   Add SetFocus() in mch_system(). (Mike Steed)
+Files:	    src/os_win32.c
+
+
+Patch 5.5a.1
+Problem:    ":let @* = @:" did not work.  The text was not put on the
+	I   clipboard.  (Fisher)
+Solution:   Own the clipboard and put the text on it.
+Files:	    src/ops.c
+
+Patch 5.5a.2
+Problem:    append() did not mark the buffer modified.  Marks below the
+	    new line were not adjusted.
+Solution:   Fix the f_append() function.
+Files:	    src/eval.c
+
+Patch 5.5a.3
+Problem:    Editing compressed ".gz" files doesn't work on non-Unix systems,
+	    because there is no "mv" command.
+Solution:   Add the rename() function and use it instead of ":!mv".
+	    Also: Disable the automatic jump to the last position, because it
+	    changes the jumplist.
+Files:	    src/eval.c, runtime/doc/eval.txt, runtime/vimrc_example.vim
+
+Patch 5.5a.4
+Problem:    When using whole-line completion in insert mode while the cursor
+	    is in the indent, get "out of memory" error. (Stekrt)
+Solution:   Don't allocate a negative amount of memory in ins_complete().
+Files:	    src/edit.c
+
+Patch 5.5a.5
+Problem:    Win32: The 'path' option can hold only up to 256 characters,
+	    because _MAX_PATH is 256.  (Robert Webb)
+Solution:   Use a fixed path length of 1024.
+Files:	    src/os_win32.h
+
+Patch 5.5a.6
+Problem:    Compiling with gcc on Win32, using the Unix Makefile, didn't work.
+Solution:   Add $(SUFFIX) to all places where an executable is used.  Also
+	    pass it to ctags.  (Reynolds)
+Files:	    src/Makefile
+
+Patch 5.5a.7
+Problem:    When using "cat | vim -" in an xterm, the xterm version reply
+	    would end up in the file.
+Solution:   Read the file from stdin before switching the terminal to RAW
+	    mode.  Should also avoid problems with programs that use a
+	    specific terminal setting.
+	    Also: when using the GUI, print "Reading from stdin..." in the GUI
+	    window, to give a hint why it doesn't do anything.
+Files:	    src/main.c, src/fileio.c
+
+Patch 5.5a.8
+Problem:    On multi-threaded Solaris, suspending doesn't work.
+Solution:   Call pause() when the SIGCONT signal was not received after
+	    sending the SIGTSTP signal. (Nagano)
+Files:	    src/os_unix.c
+
+Patch 5.5a.9
+Problem:    'winaltkeys' could be set to an empty argument, which is illegal.
+Solution:   Give an error message when doing ":set winaltkeys=".
+Files:	    src/option.c
+
+Patch 5.5a.10
+Problem:    Win32 console: Using ALTGR on a German keyboard to produce "}"
+	    doesn't work, because the 8th bit is set when ALT is pressed.
+Solution:   Don't set the 8th bit when ALT and CTRL are used. (Leipert)
+Files:	    src/os_win32.c
+
+Patch 5.5a.11
+Problem:    Tcl: Configure always uses tclsh8.0.
+	    Also: Loading a library doesn't work.
+Solution:   Add "--with-tclsh" configure argument to allow specifying another
+	    name for the tcl shell.
+	    Call Tcl_Init() in tclinit() to make loading libraries work.
+	    (Johannes Zellner)
+Files:	    src/configure.in, src/configure, src/if_tcl.c
+
+Patch 5.5a.12
+Problem:    The "user_commands" feature is called "user-commands".
+Solution:   Replace "user-commands" with "user_commands". (Kim Sung-bom)
+	    Keep "user-commands" for the has() function, to remain backwards
+	    compatible with 5.4.
+Files:	    src/eval.c, src/version.c
+
+Patch 5.5a.13
+Problem:    OS/2: When $HOME is not defined, "C:/" is used for the viminfo
+	    file.  That is very wrong when OS/2 is on another partition.
+Solution:   Use $VIM for the viminfo file when it is defined, like for MSDOS.
+	    Also: Makefile.os2 didn't depend on os_unix.h.
+Files:	    src/os_unix.h, src/Makefile.os2
+
+Patch 5.5a.14
+Problem:    Athena, Motif and GTK: The Mouse scroll wheel doesn't work.
+Solution:   Interpret a click of the wheel as a key press of the <MouseDown>
+	    or <MouseUp> keys.  Default behavior is to scroll three lines, or
+	    a full page when Shift is used.
+Files:	    src/edit.c, src/ex_getln.c, src/gui.c, src/gui_gtk_x11.c,
+	    src/gui_x11.c, src/keymap.h, src/message.c, src/misc1.c,
+	    src/misc2.c, src/normal.c,  src/proto/normal.pro, src/vim.h,
+	    runtime/doc/scroll.txt
+
+Patch 5.5a.15
+Problem:    Using CTRL-A in Insert mode doesn't work correctly when the insert
+	    started with the <Insert> key. (Andreas Rohrschneider)
+Solution:   Replace <Insert> with "i" before setting up the redo buffer.
+Files:	    src/normal.c
+
+Patch 5.5a.16
+Problem:    VMS: GUI does not compile and run.
+Solution:   Various fixes. (Zoltan Arpadffy)
+	    Moved functions from os_unix.c to ui.c, so that VMS can use them
+	    too: open_app_context(), x11_setup_atoms() and clip_x11* functions.
+	    Made xterm_dpy global, it's now used by ui.c and os_unix.c.
+	    Use gethostname() always, sys_hostname doesn't exist.
+Files:	    src/globals.h, src/gui_x11.c, src/os_vms.mms, src/os_unix.c,
+	    src/os_vms.c, src/ui.c, src/proto/os_unix.pro, src/proto/ui.pro
+
+Renamed AdjustCursorForMultiByteCharacter() to AdjustCursorForMultiByteChar()
+to avoid symbol length limit of 31 characters. (Steve P. Wall)
+
+Patch 5.5b.1
+Problem:    SASC complains about dead assignments and implicit type casts.
+Solution:   Removed the dead assignments.  Added explicit type casts.
+Files:	    src/buffer.c, src/edit.c, src/eval.c, src/ex_cmds.c,
+	    src/ex_getln.c, src/fileio.c, src/getchar.c, src/memline.c,
+	    src/menu.c, src/misc1.c, src/normal.c, src/ops.c, src/quickfix.c,
+	    src/screen.c
+
+Patch 5.5b.2
+Problem:    When using "CTRL-O O" in Insert mode, hit <Esc> and then "o" in
+	    another line truncates that line. (Devin Weaver)
+Solution:   When using a command that starts Insert mode from CTRL-O, reset
+	    "restart_edit" first.  This avoids that edit() is called with a
+	    mix of starting a new edit command and restarting a previous one.
+Files:	    src/normal.c
+
+==============================================================================
+VERSION 5.6						*version-5.6*
+
+Version 5.6 is a bug-fix version of 5.5.
+
+
+Changed							*changed-5.6*
+-------
+
+Small changes to OleVim files. (Christian Schaller)
+
+Inserted "/**/" between patch numbers in src/version.c.  This allows for one
+line of context, which some versions of patch need.
+
+Reordered the Syntax menu to avoid long submenus.  Removed keyboard shortcuts
+for alphabetical items to avoid a clash with fixed items.
+
+
+Added							*added-5.6*
+-----
+
+Included Exuberant Ctags version 3.4. (Darren Hiebert)
+
+OpenWithVim in Python. (Christian Schaller)
+
+Win32 GUI: gvimext.dll, for the context menu "Edit with Vim" entry.  Avoids
+the reported problems with the MS Office taskbar.  Now it's a Shell Extension.
+(Tianmiao Hu)
+
+New syntax files:
+abel		Abel (John Cook)
+aml		Arc Macro Language (Nikki Knuit)
+apachestyle	Apache-style config file (Christian Hammers)
+cf		Cold Fusion (Jeff Lanzarotta)
+ctrlh		files with CTRL-H sequences (Bram Moolenaar)
+cupl		CUPL (John Cook)
+cuplsim		CUPL simulation (John Cook)
+erlang		Erlang (Kresimir Marzic)
+gedcom		Gedcom (Paul Johnson)
+icon		Icon (Wendell Turner)
+ist		MakeIndex style (Peter Meszaros)
+jsp		Java Server Pages (Rafael Garcia-Suarez)
+rcslog		Rcslog (Joe Karthauser)
+remind		Remind (Davide Alberani)
+sqr		Structured Query Report Writer (Paul Moore)
+tads		TADS (Amir Karger)
+texinfo		Texinfo (Sandor Kopanyi)
+xpm2		X Pixmap v2 (Steve Wall)
+
+The 'C' flag in 'cpoptions' can be used to switch off concatenation for
+sourced lines.  See patch 5.5.013 below. |line-continuation|
+
+"excludenl" argument for the ":syntax" command.  See patch 5.5.032 below.
+|:syn-excludenl|
+
+Implemented |z+| and |z^| commands.  See patch 5.5.050 below.
+
+Vim logo in Corel Draw format.  Can be scaled to any resolution.
+
+
+Fixed							*fixed-5.6*
+-----
+
+Using this mapping in Select mode, terminated completion:
+":vnoremap <C-N> <Esc>a<C-N>" (Benji Fisher)
+Ignore K_SELECT in ins_compl_prep().
+
+VMS (Zoltan Arpadffy, David Elins):
+- ioctl() in pty.c caused trouble, #ifndef VMS added.
+- Cut & paste mismatch corrected.
+- Popup menu line crash corrected.  (Patch 5.5.047)
+- Motif directories during open and save as corrected.
+- Handle full file names with version numbers. (Patch 5.5.046)
+- Directory handling (CD command etc.)
+- Corrected file name conversion VMS to Unix and v.v.
+- Recovery was not working.
+- Terminal and signal handling was outdated compared to os_unix.c.
+- Improved os_vms.txt.
+
+Configure used fprintf() instead of printf() to check for __DATE__ and
+__TIME__. (John Card II)
+
+BeOS: Adjust computing the char_height and char_ascent.  Round them up
+separately, avoids redrawing artifacts. (Mike Steed)
+
+Fix a few multi-byte problems in menu_name_skip(), set_reg_ic(), searchc() and
+findmatchlimit(). (Taro Muraoka)
+
+GTK GUI:
+- With GTK 1.2.5 and later the scrollbars were not redrawn correctly.
+- Adjusted the gtk_form_draw() function.
+- SNiFF connection didn't work.
+- 'mousefocus' was not working. (Dalecki)
+- Some keys were not working with modifiers: Shift-Tab, Ctrl-Space and CTRL-@.
+
+
+Patch 5.5.001
+Problem:    Configure in the top directory did not pass on an argument with a
+	    space correctly.  For example "./configure --previs="/My home".
+	    (Stephane Chazelas)
+Solution:   Use '"$@"' instead of '$*' to pass on the arguments.
+Files:	    configure
+
+Patch 5.5.002
+Problem:    Compilation error for using "fds[] & POLLIN". (Jeff Walker)
+Solution:   Use "fds[].revents & POLLIN".
+Files:	    src/os_unix.c
+
+Patch 5.5.003
+Problem:    The autoconf check for sizeof(int) is wrong on machines where
+	    sizeof(size_t) != sizeof(int).
+Solution:   Use our own configure check.  Also fixes the warning for
+	    cross-compiling.
+Files:	    src/configure.in, src/configure
+
+Patch 5.5.004
+Problem:    On Unix it's not possible to interrupt ":sleep 100".
+Solution:   Switch terminal to cooked mode while asleep, to allow a SIGINT to
+	    wake us up.  But switch off echo, added TMODE_SLEEP.
+Files:	    src/term.h, src/os_unix.c
+
+Patch 5.5.005
+Problem:    When using <f-args> with a user command, an empty argument to the
+	    command resulted in one empty string, while no string was
+	    expected.
+Solution:   Catch an empty argument and pass no argument to the function.
+	    (Paul Moore)
+Files:	    src/ex_docmd.c
+
+Patch 5.5.006
+Problem:    Python: When platform-dependent files are in another directory
+	    than the platform-independent files it doesn't work.
+Solution:   Also check the executable directory, and add it to CFLAGS. (Tessa
+	    Lau)
+Files:	    src/configure.in, src/configure
+
+Patch 5.5.007 (extra)
+Problem:    Win32 OLE: Occasional crash when exiting while still being used
+	    via OLE.
+Solution:   Move OleUninitialize() to before deleting the application object.
+	    (Vince Negri)
+Files:	    src/if_ole.cpp
+
+Patch 5.5.008
+Problem:    10000@@ takes a long time and cannot be interrupted.
+Solution:   Check for CTRL-C typed while in the loop to push the register.
+Files:	    src/normal.c
+
+Patch 5.5.009
+Problem:    Recent Sequent machines don't link with "-linet". (Kurtis Rader)
+Solution:   Remove configure check for Sequent.
+Files:	    src/configure.in, src/configure
+
+Patch 5.5.010
+Problem:    Ctags freed a memory block twice when exiting.  When out of
+	    memory, a misleading error message was given.
+Solution:   Update to ctags 3.3.2.  Also fixes a few other problems. (Darren
+	    Hiebert)
+Files:	    src/ctags/*
+
+Patch 5.5.011
+Problem:    After "CTRL-V s", the cursor jumps back to the start, while all
+	    other operators leave the cursor on the last changed character.
+	    (Xiangjiang Ma)
+Solution:   Position cursor on last changed character, if possible.
+Files:	    src/ops.c
+
+Patch 5.5.012
+Problem:    Using CTRL-] in Visual mode doesn't work when the text includes a
+	    space (just where it's useful). (Stefan Bittner)
+Solution:   Don't escape special characters in a tag name with a backslash.
+Files:	    src/normal.c
+
+Patch 5.5.013
+Problem:    The ":append" and ":insert" commands allow using a leading
+	    backslash in a line.  The ":source" command concatenates those
+	    lines. (Heinlein)
+Solution:   Add the 'C' flag in 'cpoptions' to switch off concatenation.
+Files:	    src/ex_docmd.c, src/option.h, runtime/doc/options.txt,
+	    runtime/filetype.vim, runtime/scripts.vim
+
+Patch 5.5.014
+Problem:    When executing a register with ":@", the ":append" command would
+	    get text lines with a ':' prepended. (Heinlein)
+Solution:   Remove the ':' characters.
+Files:	    src/ex_docmd.c, src/ex_getln.c, src/globals.h
+
+Patch 5.5.015
+Problem:    When using ":g/pat/p", it's hard to see where the output starts,
+	    the ":g" command is overwritten.  Vi keeps the ":g" command.
+Solution:   Keep the ":g" command, but allow overwriting it with the report
+	    for the number of changes.
+Files:	    src/ex_cmds.c
+
+Patch 5.5.016 (extra)
+Problem:    Win32: Using regedit to install Vim in the popup menu requires the
+	    user to confirm this in a dialog.
+Solution:   Use "regedit /s" to avoid the dialog
+Files:	    src/dosinst.c
+
+Patch 5.5.017
+Problem:    If an error occurs when closing the current window, Vim could get
+	    stuck in the error handling.
+Solution:   Don't set curwin to NULL when closing the current window.
+Files:	    src/window.c
+
+Patch 5.5.018
+Problem:    Absolute paths in shell scripts do not always work.
+Solution:   Use /usr/bin/env to find out the path.
+Files:	    runtime/doc/vim2html.pl, runtime/tools/efm_filter.pl,
+	    runtime/tools/shtags.pl
+
+Patch 5.5.019
+Problem:    A function call in 'statusline' stops using ":q" twice from
+	    exiting, when the last argument hasn't been edited.
+Solution:   Don't decrement quitmore when executing a function. (Madsen)
+Files:	    src/ex_docmd.c
+
+Patch 5.5.020
+Problem:    When the output of CTRL-D completion in the commandline goes all
+	    the way to the last column, there is an empty line.
+Solution:   Don't add a newline when the cursor wrapped already. (Madsen)
+Files:	    src/ex_getln.c
+
+Patch 5.5.021
+Problem:    When checking if a file name in the tags file is relative,
+	    environment variables were not expanded.
+Solution:   Expand the file name before checking if it is relative. (Madsen)
+Files:	    src/tag.c
+
+Patch 5.5.022
+Problem:    When setting or resetting 'paste' the ruler wasn't updated.
+Solution:   Update the status lines when 'ruler' changes because of 'paste'.
+Files:	    src/option.c
+
+Patch 5.5.023
+Problem:    When editing a new file and autocommands change the cursor
+	    position, the cursor was moved back to the first non-white, unless
+	    'startofline' was reset.
+Solution:   Keep the new column, just like the line number.
+Files:	    src/ex_cmds.c
+
+Patch 5.5.024 (extra)
+Problem:    Win32 GUI: When using confirm() to put up a dialog without a
+	    default button, the dialog would not have keyboard focus.
+	    (Krishna)
+Solution:   Always set focus to the dialog window.  Only set focus to a button
+	    when a default one is specified.
+Files:	    src/gui_w32.c
+
+Patch 5.5.025
+Problem:    When using "keepend" in a syntax region, a contained match that
+	    includes the end-of-line could still force that region to
+	    continue, if there is another contained match in between.
+Solution:   Check the keepend_level in check_state_ends().
+Files:	    src/syntax.c
+
+Patch 5.5.026
+Problem:    When starting Vim in a white-on-black xterm, with 'bg' set to
+	    "dark", and then starting the GUI with ":gui", setting 'bg' to
+	    "light" in the gvimrc, the highlighting isn't set.  (Tsjokwing)
+Solution:   Set the highlighting when 'bg' is changed in the gvimrc, even
+	    though full_screen isn't set.
+Files:	    src/option.c
+
+Patch 5.5.027
+Problem:    Unix: os_unix.c doesn't compile when XTERM_CLIP is used but
+	    WANT_TITLE isn't. (Barnum)
+Solution:   Move a few functions that are used by the X11 title and clipboard
+	    and put another "#if" around it.
+Files:	    src/os_unix.c
+
+Patch 5.5.028 (extra)
+Problem:    Win32 GUI: When a file is dropped on Win32 gvim while at the ":"
+	    prompt, the file is edited but the command line is actually still
+	    there, the cursor goes back to command line on the next command.
+	    (Krishna)
+Solution:   When dropping a file or directory on gvim while at the ":" prompt,
+	    insert the name of the file/directory.  Allows using the
+	    file/directory name for any Ex command.
+Files:	    src/gui_w32.c
+
+Patch 5.5.029
+Problem:    "das" at the end of the file didn't delete the last character of
+	    the sentence.
+Solution:   When there is no character after the sentence, make the operation
+	    inclusive in current_sent().
+Files:	    src/search.c
+
+Patch 5.5.030
+Problem:    Unix: in os_unix.c, "term_str" is used, which is also defined in
+	    vim.h as a macro. (wuxin)
+Solution:   Renamed "term_str" to "buf" in do_xterm_trace().
+Files:	    src/os_unix.c
+
+Patch 5.5.031 (extra)
+Problem:    Win32 GUI: When exiting Windows, gvim will leave swap files behind
+	    and will be killed ungracefully. (Krishna)
+Solution:   Catch the WM_QUERYENDSESSION and WM_ENDSESSION messages and try to
+	    exit gracefully.  Allow the user to cancel the shutdown if there
+	    is a changed buffer.
+Files:	    src/gui_w32.c
+
+Patch 5.5.032
+Problem:    Patch 5.5.025 wasn't right.  And C highlighting was still not
+	    working correctly for a #define.
+Solution:   Added "excludenl" argument to ":syntax", to be able not to extend
+	    a containing item when there is a match with the end-of-line.
+Files:	    src/syntax.c, runtime/doc/syntax.txt, runtime/syntax/c.vim
+
+Patch 5.5.033
+Problem:    When reading from stdin, a long line in viminfo would mess up the
+	    file message.  readfile() uses IObuff for keep_msg, which could be
+	    overwritten by anyone.
+Solution:   Copy the message from IObuff to msg_buf and set keep_msg to that.
+	    Also change vim_fgets() to not use IObuff any longer.
+Files:	    src/fileio.c
+
+Patch 5.5.034
+Problem:    "gvim -rv" caused a crash.  Using 't_Co' before it's set.
+Solution:   Don't try to initialize the highlighting before it has been
+	    initialized from main().
+Files:	    src/syntax.c
+
+Patch 5.5.035
+Problem:    GTK with XIM: Resizing with status area was messy, and
+	    ":set guioptions+=b" didn't work.
+Solution:   Make status area a separate widget, but not a separate window.
+	    (Chi-Deok Hwang)
+Files:	    src/gui_gtk_f.c, src/gui_gtk_x11.c, src/multbyte.c
+
+Patch 5.5.036
+Problem:    The GZIP_read() function in $VIMRUNTIME/vimrc_example.vim to
+	    uncompress a file did not do detection for 'fileformat'.  This is
+	    because the filtering is done with 'binary' set.
+Solution:   Split the filtering into separate write, filter and read commands.
+Files:	    runtime/vimrc_example.vim
+
+Patch 5.5.037
+Problem:    The "U" command didn't mark the buffer as changed. (McCormack)
+Solution:   Set the 'modified' flag when using "U".
+Files:	    src/undo.c
+
+Patch 5.5.038
+Problem:    When typing a long ":" command, so that the screen scrolls up,
+	    causes the hit-enter prompt, even though the user just typed
+	    return to execute the command.
+Solution:   Reset need_wait_return if (part of) the command was typed in
+	    getcmdline().
+Files:	    src/ex_getln.c
+
+Patch 5.5.039
+Problem:    When using a custom status line, "%a" (file # of #) reports the
+	    index of the current window for all windows.
+Solution:   Pass a window pointer to append_arg_number(), and pass the window
+	    being updated from build_stl_str_hl(). (Stephen P. Wall)
+Files:	    src/buffer.c, src/screen.c, src/proto/buffer.pro
+
+Patch 5.5.040
+Problem:    Multi-byte: When there is some error in xim_real_init(), it can
+	    close XIM and return.  After this there can be a segv.
+Solution:   Test "xic" for being non-NULL, don't set "xim" to NULL.  Also try
+	    to find more matches for supported styles. (Sung-Hyun Nam)
+Files:	    src/multbyte.c
+
+Patch 5.5.041
+Problem:    X11 GUI: CTRL-_ requires the SHIFT key only on some machines.
+Solution:   Translate CTRL-- to CTRL-_. (Robert Webb)
+Files:	    src/gui_x11.c
+
+Patch 5.5.042
+Problem:    X11 GUI: keys with ALT were assumed to be used for the menu, even
+	    when the menu has been disabled by removing 'm' from 'guioptions'.
+Solution:   Ignore keys with ALT only when gui.menu_is_active is set. (Raf)
+Files:	    src/gui_x11.c
+
+Patch 5.5.043
+Problem:    GTK: Handling of fontset fonts was not right when 'guifontset'
+	    contains exactly 14 times '-'.
+Solution:   Avoid setting fonts when working with a fontset. (Sung-Hyun Nam)
+Files:	    src/gui_gtk_x11.c
+
+Patch 5.5.044
+Problem:    pltags.pl contains an absolute path "/usr/local/bin/perl".  That
+	    might not work everywhere.
+Solution:   Use "/usr/bin/env perl" instead.
+Files:	    runtime/tools/pltags.pl
+
+Patch 5.5.045
+Problem:    Using "this_session" variable does not work, requires preceding it
+	    with "v:".  Default filename for ":mksession" isn't mentioned
+	    in the docs. (Fisher)
+Solution:   Support using "this_session" to be backwards compatible.
+Files:	    src/eval.c, runtime/doc/options.txt
+
+Patch 5.5.046 (extra)
+Problem:    VMS: problems with path and filename.
+Solution:   Truncate file name at last ';', etc. (Zoltan Arpadffy)
+Files:	    src/buffer.c, src/fileio.c, src/gui_motif.c, src/os_vms.c,
+	    src/proto/os_vms.pro
+
+Patch 5.5.047
+Problem:    VMS: Crash when using the popup menu
+Solution:   Turn the #define MENU_MODE_CHARS into an array. (Arpadffy)
+Files:	    src/structs.h, src/menu.c
+
+Patch 5.5.048
+Problem:    HP-UX 11: Compiling doesn't work, because both string.h and
+	    strings.h are included. (Squassabia)
+Solution:   The configure test for including both string.h and strings.h
+	    must include <Xm/Xm.h> first, because it causes problems.
+Files:	    src/configure.in, src/configure, src/config.h.in
+
+Patch 5.5.049
+Problem:    Unix: When installing Vim, the protection bits of files might be
+	    influenced by the umask.
+Solution:   Add $(FILEMOD) to Makefile. (Shetye)
+Files:	    src/Makefile
+
+Patch 5.5.050
+Problem:    "z+" and "z^" commands are missing.
+Solution:   Implemented "z+" and "z^".
+Files:	    src/normal.c, runtime/doc/scroll.txt, runtime/doc/index.txt
+
+Patch 5.5.051
+Problem:    Several Unix systems have a problem with the optimization limits
+	    check in configure.
+Solution:   Removed the configure check, let the user add it manually in
+	    Makefile or the environment.
+Files:	    src/configure.in, src/configure, src/Makefile
+
+Patch 5.5.052
+Problem:    Crash when using a cursor key at the ATTENTION prompt. (Alberani)
+Solution:   Ignore special keys at the console dialog.  Also ignore characters
+	    > 255 for other uses of tolower() and toupper().
+Files:	    src/menu.c, src/message.c, src/misc2.c
+
+Patch 5.5.053
+Problem:    Indenting is wrong after a function when 'cino' has "fs".  Another
+	    problem when 'cino' has "{s".
+Solution:   Put line after closing "}" of a function at the left margin.
+	    Apply ind_open_extra in the right way after a '{'.
+Files:	    src/misc1.c, src/testdir/test3.in, src/testdir/test3.ok
+
+Patch 5.5.054
+Problem:    Unix: ":e #" doesn't work if the alternate file name contains a
+	    space or backslash. (Hudacek)
+Solution:   When replacing "#", "%" or other items that stand for a file name,
+	    prepend a backslash before special characters.
+Files:	    src/ex_docmd.c
+
+Patch 5.5.055
+Problem:    Using "<C-V>$r-" in blockwise Visual mode replaces one character
+	    beyond the end of the line. (Zivkov)
+Solution:   Only replace existing characters.
+Files:	    src/ops.c
+
+Patch 5.5.056
+Problem:    After "z20<CR>" messages were printed at the old command line
+	    position once.  (Veselinovic)
+Solution:   Set msg_row and msg_col when changing cmdline_row in
+	    win_setheight().
+Files:	    src/window.c
+
+Patch 5.5.057
+Problem:    After "S<Esc>" it should be possible to restore the line with "U".
+	    (Veselinovic)
+Solution:   Don't call u_clearline() in op_delete() when changing only one
+	    line.
+Files:	    src/ops.c
+
+Patch 5.5.058
+Problem:    Using a long search pattern and then "n" causes the hit-enter
+	    prompt.  (Krishna)
+Solution:   Truncate the echoed pattern, like other messages.  Moved code for
+	    truncating from msg_attr() to msg_strtrunc().
+Files:	    src/message.c, src/proto/message.pro, src/search.c
+
+Patch 5.5.059
+Problem:    GTK GUI: When $term is invalid, using "gvim" gives an error
+	    message, even though $term isn't really used.  (Robbins)
+Solution:   When the GUI is about to start, skip the error messages for a
+	    wrong $term.
+Files:	    src/term.c
+
+Patch 5.5.060 (extra)
+Problem:    Dos 32 bit: When a directory in 'backupdir' doesn't exist, ":w"
+	    causes the file to be renamed to "axlqwqhy.ba~". (Matzdorf)
+Solution:   The code to work around a LFN bug in Windows 95 doesn't handle a
+	    non-existing target name correctly.  When renaming fails, make
+	    sure the file has its original name.  Also do this for the Win32
+	    version, although it's unlikely that it runs into this problem.
+Files:	    src/os_msdos.c, src/os_win32.c
+
+Patch 5.5.061
+Problem:    When using "\:" in a modeline, the backslash is included in the
+	    option value. (Mohsin)
+Solution:   Remove one backslash before the ':' in a modeline.
+Files:	    src/buffer.c, runtime/doc/options.txt
+
+Patch 5.5.062 (extra)
+Problem:    Win32 console: Temp files are created in the root of the current
+	    drive, which may be read-only. (Peterson)
+Solution:   Use the same mechanism of the GUI version: Use $TMP, $TEMP or the
+	    current directory.  Cleaned up vim_tempname() a bit.
+Files:	    src/fileio.c, src/os_win32.h, runtime/doc/os_dos.txt
+
+Patch 5.5.063
+Problem:    When using whole-line completion in Insert mode, 'cindent' is
+	    applied, even after changing the indent of the line.
+Solution:   Don't reindent the completed line after inserting/removing indent.
+	    (Robert Webb)
+Files:	    src/edit.c
+
+Patch 5.5.064
+Problem:    has("sniff") doesn't work correctly.
+Solution:   Return 1 when Vim was compiled with the +sniff feature. (Pruemmer)
+Files:	    src/eval.c
+
+Patch 5.5.065
+Problem:    When dropping a file on Vim, the 'shellslash' option is not
+	    effective. (Krishna)
+Solution:   Fix the slashes in the dropped file names according to
+	    'shellslash'.
+Files:	    src/ex_docmd.c, runtime/doc/options.txt
+
+Patch 5.5.066
+Problem:    For systems with backslash in file name: Setting a file name
+	    option to a value starting with "\\machine" removed a backslash.
+Solution:   Keep the double backslash for "\\machine", but do change
+	    "\\\\machine" to "\\machine" for backwards compatibility.
+Files:	    src/option.c, runtime/doc/options.txt
+
+Patch 5.5.067
+Problem:    With 'hlsearch' set, the pattern "\>" doesn't highlight the first
+	    match in a line. (Benji Fisher)
+Solution:   Fix highlighting an empty match.  Also highlight the first
+	    character in an empty line for "$".
+Files:	    src/screen.c
+
+Patch 5.5.068
+Problem:    Crash when a ":while" is used with an argument that has an error.
+	    (Sylvain Viart)
+Solution:   Was using an uninitialized index in the cs_line[] array.  The
+	    crash only happened when the index was far off.  Made sure the
+	    uninitialized index isn't used.
+Files:	    src/ex_docmd.c
+
+Patch 5.5.069
+Problem:    Shifting lines in blockwise Visual mode didn't set the 'modified'
+	    flag.
+Solution:   Do set the 'modified' flag.
+Files:	    src/ops.c
+
+Patch 5.5.070
+Problem:    When editing a new file, creating that file outside of Vim, then
+	    editing it again, ":w" still warns for overwriting an existing
+	    file. (Nam)
+Solution:   The BF_NEW flag in the "b_flags" field wasn't cleared properly.
+Files:	    src/buffer.c, src/fileio.c
+
+Patch 5.5.071
+Problem:    Using a matchgroup in a ":syn region", which is the same syntax
+	    group as the region, didn't stop a contained item from matching in
+	    the start pattern.
+Solution:   Also push an item on the stack when the syntax ID of the
+	    matchgroup is the same as the syntax ID of the region.
+Files:	    src/syntax.c
+
+Patch 5.5.072 (extra)
+Problem:    Dos 32 bit: When setting 'columns' to a too large value, Vim may
+	    crash, and the DOS console too.
+Solution:   Check that the value of 'columns' isn't larger than the number of
+	    columns that the BIOS reports.
+Files:	    src/os_msdos.c, src/proto/os_msdos.pro, src/option.c
+
+Patch 5.5.073 (extra)
+Problem:    Win 32 GUI: The Find and Find/Replace dialogs didn't show the
+	    "match case" checkbox.  The Find/Replace dialog didn't handle the
+	    "match whole word" checkbox.
+Solution:   Support the "match case" and "match whole word" checkboxes.
+Files:	    src/gui_w32.c
+
+Patch 5.6a.001
+Problem:    Using <C-End> with a count doesn't work like it does with "G".
+	    (Benji Fisher)
+Solution:   Accept a count for <C-End> and <C-Home>.
+Files:	    src/normal.c
+
+Patch 5.6a.002
+Problem:    The script for conversion to HTML was an older version.
+Solution:   Add support for running 2html.vim on a color terminal.
+Files:	    runtime/syntax/2html.vim
+
+Patch 5.6a.003
+Problem:    Defining a function inside a function didn't give an error
+	    message.  A missing ":endfunction" doesn't give an error message.
+Solution:   Allow defining a function inside a function.
+Files:	    src/eval.c, runtime/doc/eval.txt
+
+Patch 5.6a.004
+Problem:    A missing ":endwhile" or ":endif" doesn't give an error message.
+	    (Johannes Zellner)
+Solution:   Check for missing ":endwhile" and ":endif" in sourced files.
+	    Add missing ":endif" in file selection macros.
+Files:	    src/ex_docmd.c, runtime/macros/file_select.vim
+
+Patch 5.6a.005
+Problem:    'hlsearch' was not listed alphabetically.  The value of 'toolbar'
+	    was changed when 'compatible' is set.
+Solution:   Moved entry of 'hlsearch' in options[] table down.
+	    Don't reset 'toolbar' option to the default value when
+	    'compatible' is set.
+Files:	    src/option.c
+
+Patch 5.6a.006
+Problem:    Using a backwards range inside ":if 0" gave an error message.
+Solution:   Don't complain about a range when it is not going to be used.
+	    (Stefan Roemer)
+Files:	    src/ex_docmd.c
+
+Patch 5.6a.007
+Problem:    ":let" didn't show internal Vim variables.  (Ron Aaron)
+Solution:   Do show ":v" variables for ":let" and ":let v:name".
+Files:	    src/eval.c
+
+Patch 5.6a.008
+Problem:    Selecting a syntax from the Syntax menu gives an error message.
+Solution:   Replace "else if" in SetSyn() with "elseif".  (Ronald Schild)
+Files:	    runtime/menu.vim
+
+Patch 5.6a.009
+Problem:    When compiling with +extra_search but without +syntax, there is a
+	    compilation error in screen.c. (Axel Kielhorn)
+Solution:   Adjust the #ifdef for declaring and initializing "line" in
+	    win_line().  Also solve compilation problem when +statusline is
+	    used without +eval.  Another one when +cmdline_compl is used
+	    without +eval.
+Files:	    src/screen.c, src/misc2.c
+
+Patch 5.6a.010
+Problem:    In a function, ":startinsert!" does not append to the end of the
+	    line if a ":normal" command was used to move the cursor. (Fisher)
+Solution:   Reset "w_set_curswant" to avoid that w_curswant is changed again.
+Files:	    src/ex_docmd.c
+
+Patch 5.6a.011 (depends on 5.6a.004)
+Problem:    A missing ":endif" or ":endwhile" in a function doesn't give an
+	    error message.
+Solution:   Give that error message.
+Files:	    src/ex_docmd.c
+
+Patch 5.6a.012 (depends on 5.6a.008)
+Problem:    Some Syntax menu entries caused a hit-enter prompt.
+Solution:   Call a function to make the command shorter.  Also rename a few
+	    functions to avoid name clashes.
+Files:	    runtime/menu.vim
+
+Patch 5.6a.013
+Problem:    Command line completion works different when another completion
+	    was done earlier. (Johannes Zellner)
+Solution:   Reset wim_index when starting a new completion.
+Files:	    src/ex_getln.c
+
+Patch 5.6a.014
+Problem:    Various warning messages when compiling and running lint with
+	    different combinations of features.
+Solution:   Fix the warning messages.
+Files:	    src/eval.c, src/ex_cmds.c, src/ex_docmd.c, src/gui_gtk_x11.c,
+	    src/option.c, src/screen.c, src/search.c, src/syntax.c,
+	    src/feature.h, src/globals.h
+
+Patch 5.6a.015
+Problem:    The vimtutor command doesn't always know the value of $VIMRUNTIME.
+Solution:   Let Vim expand $VIMRUNTIME, instead of the shell.
+Files:	    src/vimtutor
+
+Patch 5.6a.016 (extra)
+Problem:    Mac: Window size is restricted when starting.  Cannot drag the
+	    window all over the desktop.
+Solution:   Get real screen size instead of assuming 640x400.  Do not use a
+	    fixed number for the drag limits. (Axel Kielhorn)
+Files:	    src/gui_mac.c
+
+Patch 5.6a.017
+Problem:    The "Paste" entry in popup menu for Visual, Insert and Cmdline
+	    mode is in the wrong position. (Stol)
+Solution:   Add priority numbers for all Paste menu entries.
+Files:	    runtime/menu.vim
+
+Patch 5.6a.018
+Problem:    GTK GUI: submenu priority doesn't work.
+	    Help dialog could be destroyed too soon.
+	    When closing a dialog window (e.g. the "ATTENTION" one), Vim would
+	    just hang.
+	    When GTK theme is changed, Vim doesn't adjust to the new colors.
+	    Argument for ":promptfind" isn't used.
+Solution:   Fixed the mentioned problems.
+	    Made the dialogs look&feel nicer.
+	    Moved functions to avoid the need for a forward declaration.
+	    Fixed reentrancy of the file browser dialog.
+	    Added drag&drop support for GNOME.
+	    Init the text for the Find/replace dialog from the last used
+	    search string.  Set "match whole word" toggle button correctly.
+	    Made repeat rate for drag outside of window depend on the
+	    distance from the window.  (Marcin Dalecki)
+	    Made the drag in Visual mode actually work.
+	    Removed recursiveness protection from gui_mch_get_rgb(), it might
+	    cause more trouble than it solves.
+Files:	    src/ex_docmd.c, src/gui_gtk.c, src/gui_gtk_x11.c, src/ui.c,
+	    src/proto/ui.pro, src/misc2.c
+
+Patch 5.6a.019
+Problem:    When trying to recover through NFS, which uses a large block size,
+	    Vim might think the swap file is empty, because mf_blocknr_max is
+	    zero.  (Scott McDermott)
+Solution:   When computing the number of blocks of the file in mf_open(),
+	    round up instead of down.
+Files:	    src/memfile.c
+
+Patch 5.6a.020
+Problem:    GUI GTK: Could not set display for gvim.
+Solution:   Add "-display" and "--display" arguments. (Marcin Dalecki)
+Files:	    src/gui_gtk_x11.c
+
+Patch 5.6a.021
+Problem:    Recovering still may not work when the block size of the device
+	    where the swap file is located is larger than 4096.
+Solution:   Read block 0 with the minimal block size.
+Files:	    src/memline.c, src/memfile.c, src/vim.h
+
+Patch 5.6a.022 (extra)
+Problem:    Win32 GUI: When an error in the vimrc causes a dialog to pop up
+	    (e.g., for an existing swap file), Vim crashes. (David Elins)
+Solution:   Before showing a dialog, open the main window.
+Files:	    src/gui_w32.c
+
+Patch 5.6a.023
+Problem:    Using expand("%:gs??/?") causes a crash. (Ron Aaron)
+Solution:   Check for running into the end of the string in do_string_sub().
+Files:	    src/eval.c
+
+Patch 5.6a.024
+Problem:    Using an autocommand to delete a buffer when leaving it can cause
+	    a crash when jumping to a tag. (Franz Gorkotte)
+Solution:   In do_tag(), store tagstacklen before jumping to another buffer.
+	    Check tagstackidx after jumping to another buffer.
+	    Add extra check in win_split() if tagname isn't NULL.
+Files:	    src/tag.c, src/window.c
+
+Patch 5.6a.025 (extra)
+Problem:    Win32 GUI: The tables for toupper() and tolower() are initialized
+	    too late. (Mike Steed)
+Solution:   Move the initialization to win32_init() and call it from main().
+Files:	    src/main.c, src/os_w32.c, src/proto/os_w32.pro
+
+Patch 5.6a.026
+Problem:    When the SNiFF connection is open, shell commands hang. (Pruemmer)
+Solution:   Skip a second wait() call if waitpid() already detected that the
+	    child has exited.
+Files:	    src/os_unix.c
+
+Patch 5.6a.027 (extra)
+Problem:    Win32 GUI: The "Edit with Vim" popup menu entry causes problems
+	    for the Office toolbar.
+Solution:   Use a shell extension dll. (Tianmiao Hu)
+	    Added it to the install and uninstal programs, replaces the old
+	    "Edit with Vim" menu registry entries.
+Files:	    src/dosinst.c, src/uninstal.c, gvimext/*, runtime/doc/gui_w32.txt
+
+Patch 5.6a.028 (extra)
+Problem:    Win32 GUI: Dialogs and tear-off menus can't handle multi-byte
+	    characters.
+Solution:   Adjust nCopyAnsiToWideChar() to handle multi-byte characters
+	    correctly.
+Files:	    src/gui_w32.c
+
+==============================================================================
+VERSION 5.7						*version-5.7*
+
+Version 5.7 is a bug-fix version of 5.6.
+
+Changed							*changed-5.7*
+-------
+
+Renamed src/INSTALL.mac to INSTALL_mac.txt to avoid it being recognized with a
+wrong file type.  Also renamed src/INSTALL.amiga to INSTALL_ami.txt.
+
+
+Added							*added-5.7*
+-----
+
+New syntax files:
+stp		Stored Procedures (Jeff Lanzarotta)
+snnsnet, snnspat, snnsres	SNNS (Davide Alberani)
+mel		MEL (Robert Minsk)
+ruby		Ruby (Mirko Nasato)
+tli		TealInfo (Kurt W. Andrews)
+ora		Oracle config file (Sandor Kopanyi)
+abaqus		Abaqus (Carl Osterwisch)
+jproperties	Java Properties (Simon Baldwin)
+apache		Apache config (Allan Kelly)
+csp		CSP (Jan Bredereke)
+samba		Samba config (Rafael Garcia-Suarez)
+kscript		KDE script (Thomas Capricelli)
+hb		Hyper Builder (Alejandro Forero Cuervo)
+fortran		Fortran (rewritten) (Ajit J. Thakkar)
+sml		SML (Fabrizio Zeno Cornelli)
+cvs		CVS commit (Matt Dunford)
+aspperl		ASP Perl (Aaron Hope)
+bc		BC calculator (Vladimir Scholtz)
+latte		Latte (Nick Moffitt)
+wml		WML (Gerfried Fuchs)
+
+Included Exuberant ctags 3.5.1. (Darren Hiebert)
+
+"display" and "fold" arguments for syntax items.  For future extension, they
+are ignored now.
+
+strftime() function for the Macintosh.
+
+macros/explorer.vim: A file browser script (M A Aziz Ahmed)
+
+
+Fixed							*fixed-5.7*
+-----
+
+The 16 bit MS-DOS version is now compiled with Bcc 3.1 instead of 4.0.  The
+executable is smaller.
+
+When a "make test" failed, the output file was lost.  Rename it to
+test99.failed to be able to see what went wrong.
+
+After sourcing bugreport.vim, it's not clear that bugreport.txt has been
+written in the current directory.  Edit bugreport.txt to avoid that.
+
+Adding IME support when using Makefile.w32 didn't work. (Taro Muraoka)
+
+Win32 console: Mouse drags were passed on even when the mouse didn't move.
+
+Perl interface: In Buffers(), type of argument to SvPV() was int, should be
+STRLEN. (Tony Leneis)
+
+Problem with prototype for index() on AIX 4.3.0.  Added check for _AIX43 in
+os_unix.h. (Jake Hamby)
+
+Mappings in mswin.vim could break when some commands are mapped.  Add "nore"
+to most mappings to avoid re-mapping.
+
+modify_fname() made a copy of a file name for ":p" when it already was a full
+path name, which is a bit slow.
+
+Win32 with Borland C++ 5.5: Pass the path to the compiler on to xxd and ctags,
+to avoid depending on $PATH.  Fixed "make clean".
+
+Many fixes to Macintosh specific parts: (mostly by Dany StAmant)
+- Only one Help menu.
+- No more crash when removing a menu item.
+- Support as External Editor for Codewarrior (still some little glitches).
+- Popup menu support.
+- Fixed crash when pasting after application switch.
+- Color from rgb.txt properly displayed.
+- 'isprint' default includes all chars above '~'. (Axel Kielhorn)
+- mac_expandpath() was leaking memory.
+- Add digraphs table. (Axel Kielhorn)
+- Multi-byte support: (Kenichi Asai)
+  Switch keyscript when going in/out of Insert mode.
+  Draw multi-byte character correctly.
+  Don't use mblen() but highest bit of char to detect multi-byte char.
+  Display value of multi-byte in statusline (also for other systems).
+- mouse button was not initialized properly to MOUSE_LEFT when
+  USE_CTRLCLICKMENU not defined.
+- With Japanese SJIS characters: Make "w", "b", and "e" work
+  properly.  (Kenichi Asai)
+- Replaced old CodeWarrior file os_mac.CW9.hqx with os_mac.cw5.sit.hqx.
+
+Fixes for VMS: (Zoltan Arpadffy) (also see patch 5.6.045 below)
+- Added Makefile_vms.mms and vimrc.vms to src/testdir to be able to run the
+  tests.
+- Various fixes.
+- Set 'undolevels' to 1000 by default.
+- Made mch_settitle() equivalent to the one in os_unix.c.
+
+RiscOS: A few prototypes for os_riscos.c were outdated.  Generate prototypes
+automatically.
+
+
+Previously released patches:
+
+Patch 5.6.001
+Problem:    When using "set bs=0 si cin", Inserting "#<BS>" or "}<BS>" which
+	    reduces the indent doesn't delete the "#" or "}". (Lorton)
+Solution:   Adjust ai_col in ins_try_si().
+Files:	    src/edit.c
+
+Patch 5.6.002
+Problem:    When using the vim.vim syntax file, a comment with all uppercase
+	    characters causes a hang.
+Solution:   Adjust pattern for vimCommentTitle (Charles Campbell)
+Files:	    runtime/syntax/vim.vim
+
+Patch 5.6.003
+Problem:    GTK GUI: Loading a user defined toolbar bitmap gives a warning
+	    about the colormap.  Probably because the window has not been
+	    opened yet.
+Solution:   Use gdk_pixmap_colormap_create_from_xpm() to convert the xpm file.
+	    (Keith Radebaugh)
+Files:	    src/gui_gtk.c
+
+Patch 5.6.004 (extra)
+Problem:    Win32 GUI with IME: When setting 'guifont' to "*", the font
+	    requester appears twice.
+Solution:   In gui_mch_init_font() don't call get_logfont() but copy
+	    norm_logfont from fh. (Yasuhiro Matsumoto)
+Files:	    src/gui_w32.c
+
+Patch 5.6.005
+Problem:    When 'winminheight' is zero, CTRL-W - with a big number causes a
+	    crash.  (David Kotchan)
+Solution:   Check for negative window height in win_setheight().
+Files:	    src/window.c
+
+Patch 5.6.006
+Problem:    GTK GUI: Bold font cannot always be used.  Memory is freed too
+	    early in gui_mch_init_font().
+Solution:   Move call to g_free() to after where sdup is used. (Artem Hodyush)
+Files:	    src/gui_gtk_x11.c
+
+Patch 5.6.007 (extra)
+Problem:    Win32 IME: Font is not changed when screen font is changed. And
+	    IME composition window does not trace the cursor.
+Solution:   Initialize IME font.  When cursor is moved, set IME composition
+	    window with ImeSetCompositionWindow().  Add call to
+	    ImmReleaseContext() in several places. (Taro Muraoka)
+Files:	    src/gui.c, src/gui_w32.c, src/proto/gui_w32.pro
+
+Patch 5.6.008 (extra)
+Problem:    Win32: When two files exist with the same name but different case
+	    (through NFS or Samba), fixing the file name case could cause the
+	    wrong one to be edited.
+Solution:   Prefer a perfect match above a match while ignoring case in
+	    fname_case().  (Flemming Madsen)
+Files:	    src/os_win32.c
+
+Patch 5.6.009 (extra)
+Problem:    Win32 GUI: Garbage in Windows Explorer help line when selecting
+	    "Edit with Vim" popup menu entry.
+Solution:   Only return the help line when called with the GCS_HELPTEXT flag.
+	    (Tianmiao Hu)
+Files:	    GvimExt/gvimext.cpp
+
+Patch 5.6.010
+Problem:    A file name which contains a TAB was not read correctly from the
+	    viminfo file and the ":ls" listing was not aligned properly.
+Solution:   Parse the buffer list lines in the viminfo file from the end
+	    backwards.  Count a Tab for two characters to align the ":ls" list.
+Files:	    src/buffer.c
+
+Patch 5.6.011
+Problem:    When 'columns' is huge (using a tiny font) and 'statusline' is
+	    used, Vim can crash.
+Solution:   Limit maxlen to MAXPATHL in win_redr_custom(). (John Mullin)
+Files:	    src/screen.c
+
+Patch 5.6.012
+Problem:    When using "zsh" for /bin/sh, toolcheck may hang until "exit" is
+	    typed. (Kuratczyk)
+Solution:   Add "-c exit" when checking for the shell version.
+Files:	    src/toolcheck
+
+Patch 5.6.013
+Problem:    Multibyte char in tooltip is broken.
+Solution:   Consider multibyte char in replace_termcodes(). (Taro Muraoka)
+Files:      src/term.c
+
+Patch 5.6.014
+Problem:    When cursor is at the end of line and the character under cursor
+	    is a multibyte character, "yl" doesn't yank 1 multibyte-char.
+	    (Takuhiro Nishioka)
+Solution:   Recognize a multibyte-char at end-of-line correctly in oneright().
+	    (Taro Muraoka)
+	    Also: make "+quickfix" in ":version" output appear alphabetically.
+Files:	    src/edit.c
+
+Patch 5.6.015
+Problem:    New xterm delete key sends <Esc>[3~ by default.
+Solution:   Added <kDel> and <kIns> to make the set of keypad keys complete.
+Files:	    src/edit.c, src/ex_getln.c, src/keymap.h, src/misc1.c,
+	    src/misc2.c, src/normal.c, src/os_unix.c, src/term.c
+
+Patch 5.6.016
+Problem:    When deleting a search string from history from inside a mapping,
+	    another entry is deleted too. (Benji Fisher)
+Solution:   Reset last_maptick when deleting the last entry of the search
+	    history.  Also: Increment maptick when starting a mapping from
+	    typed characters to avoid a just added search string being
+	    overwritten or removed from history.
+Files:	    src/ex_getln.c, src/getchar.c
+
+Patch 5.6.017
+Problem:    ":s/e/\^M/" should replace an "e" with a CTRL-M, not split the
+	    line. (Calder)
+Solution:   Replace the backslash with a CTRL-V internally. (Stephen P. Wall)
+Files:	    src/ex_cmds.c
+
+Patch 5.6.018
+Problem:    ":help [:digit:]" takes a long time to jump to the wrong place.
+Solution:   Insert a backslash to avoid the special meaning of '[]'.
+Files:	    src/ex_cmds.c
+
+Patch 5.6.019
+Problem:    "snd.c", "snd.java", etc. were recognized as "mail" filetype.
+Solution:   Make pattern for mail filetype more strict.
+Files:	    runtime/filetype.vim
+
+Patch 5.6.020 (extra)
+Problem:    The DJGPP version eats processor time (Walter Briscoe).
+Solution:   Call __dpmi_yield() in the busy-wait loop.
+Files:	    src/os_msdos.c
+
+Patch 5.6.021
+Problem:    When 'selection' is "exclusive", a double mouse click in Insert
+	    mode doesn't select last char in line. (Lutz)
+Solution:   Allow leaving the cursor on the NUL past the line in this case.
+Files:	    src/edit.c
+
+Patch 5.6.022
+Problem:    ":e \~<Tab>" expands to ":e ~\$ceelen", which doesn't work.
+Solution:   Re-insert the backslash before the '~'.
+Files:	    src/ex_getln.c
+
+Patch 5.6.023 (extra)
+Problem:    Various warnings for the Ming compiler.
+Solution:   Changes to avoid the warnings. (Bill McCarthy)
+Files:	    src/ex_cmds.c, src/gui_w32.c, src/os_w32exe.c, src/os_win32.c,
+	    src/syntax.c, src/vim.rc
+
+Patch 5.6.024 (extra)
+Problem:    Win32 console: Entering CTRL-_ requires the shift key. (Kotchan)
+Solution:   Specifically catch keycode 0xBD, like the GUI.
+Files:	    src/os_win32.c
+
+Patch 5.6.025
+Problem:    GTK GUI: Starting the GUI could be interrupted by a SIGWINCH.
+	    (Nils Lohner)
+Solution:   Repeat the read() call to get the gui_in_use value when
+	    interrupted by a signal.
+Files:	    src/gui.c
+
+Patch 5.6.026 (extra)
+Problem:    Win32 GUI: Toolbar bitmaps are searched for in
+	    $VIMRUNTIME/bitmaps, while GTK looks in $VIM/bitmaps. (Keith
+	    Radebaugh)
+Solution:   Use $VIM/bitmaps for both, because these are not part of the
+	    distribution but defined by the user.
+Files:	    src/gui_w32.c, runtime/doc/gui.txt
+
+Patch 5.6.027
+Problem:    TCL: Crash when using a Tcl script (reported for Win32).
+Solution:   Call Tcl_FindExecutable() in main(). (Brent Fulgham)
+Files:	    src/main.c
+
+Patch 5.6.028
+Problem:    Xterm patch level 126 sends codes for mouse scroll wheel.
+	    Fully works with xterm patch level 131.
+Solution:   Recognize the codes for button 4 (0x60) and button 5 (0x61).
+Files:	    src/term.c
+
+Patch 5.6.029
+Problem:    GTK GUI: Shortcut keys cannot be used for a dialog. (Johannes
+	    Zellner)
+Solution:   Add support for shortcut keys. (Marcin Dalecki)
+Files:	    src/gui_gtk.c
+
+Patch 5.6.030
+Problem:    When closing a window and 'ea' is set, Vim can crash. (Yasuhiro
+	    Matsumoto)
+Solution:   Set "curbuf" to a valid value in win_close().
+Files:	    src/window.c
+
+Patch 5.6.031
+Problem:    Multi-byte: When a double-byte character ends in CSI, Vim waits
+	    for another character to be typed.
+Solution:   Recognize the CSI as the second byte of a character and don't wait
+	    for another one. (Yasuhiro Matsumoto)
+Files:	    src/getchar.c
+
+Patch 5.6.032
+Problem:    Functions with an argument that is a line number don't all accept
+	    ".", "$", etc. (Ralf Arens)
+Solution:   Add get_art_lnum() and use it for setline(), line2byte() and
+	    synID().
+Files:	    src/eval.c
+
+Patch 5.6.033
+Problem:    Multi-byte: "f " sometimes skips to the second space.  (Sung-Hyun
+	    Nam)
+Solution:   Change logic in searchc() to skip trailing byte of a double-byte
+	    character.
+	    Also: Ask for second byte when searching for double-byte
+	    character. (Park Chong-Dae)
+Files:	    src/search.c
+
+Patch 5.6.034 (extra)
+Problem:    Compiling with Borland C++ 5.5 fails on tolower() and toupper().
+Solution:   Use TO_LOWER() and TO_UPPER() instead.  Also adjust the Makefile
+	    to make using bcc 5.5 easier.
+Files:	    src/edit.c, src/ex_docmd.c, src/misc1.c, src/Makefile.bor
+
+Patch 5.6.035
+Problem:    Listing the"+comments" feature in the ":version" output depended
+	    on the wrong ID. (Stephen P. Wall)
+Solution:   Change "CRYPTV" to "COMMENTS".
+Files:	    src/version.c
+
+Patch 5.6.036
+Problem:    GTK GUI: Copy/paste text doesn't work between gvim and Eterm.
+Solution:   Support TEXT and COMPOUND_TEXT selection targets. (ChiDeok Hwang)
+Files:	    src/gui_gtk_x11.c
+
+Patch 5.6.037
+Problem:    Multi-byte: Can't use "f" command with multi-byte character in GUI.
+Solution:   Enable XIM in Normal mode for the GUI. (Sung-Hyun Nam)
+Files:	    src/gui_gtk_x11.c, src/multbyte.c
+
+Patch 5.6.038
+Problem:    Multi-clicks in GUI are interpreted as a mouse wheel click.  When
+	    'ttymouse' is "xterm" a mouse click is interpreted as a mouse
+	    wheel click.
+Solution:   Don't recognize the mouse wheel in check_termcode() in the GUI.
+	    Use 0x43 for a mouse drag in do_xterm_trace(), not 0x63.
+Files:	    src/term.c, src/os_unix.c
+
+Patch 5.6.039
+Problem:    Motif GUI under KDE: When trying to logout, Vim hangs up the
+	    system. (Hermann Rochholz)
+Solution:   When handling the WM_SAVE_YOURSELF event, set the WM_COMMAND
+	    property of the window to let the session manager know we finished
+	    saving ourselves.
+Files:	    src/gui_x11.c
+
+Patch 5.6.040
+Problem:    When using ":s" command, matching the regexp is done twice.
+Solution:   After copying the matched line, adjust the pointers instead of
+	    finding the match again. (Loic Grenie)  Added vim_regnewptr().
+Files:	    src/ex_cmds.c, src/regexp.c, src/proto/regexp.pro
+
+Patch 5.6.041
+Problem:    GUI: Athena, Motif and GTK don't give more than 10 dialog buttons.
+Solution:   Remove the limit on the number of buttons.
+	    Also support the 'v' flag in 'guioptions'.
+	    For GTK: Center the buttons.
+Files:	    src/gui_athena.c, src/gui_gtk.c, src/gui_motif.c
+
+Patch 5.6.042
+Problem:    When doing "vim -u vimrc" and vimrc contains ":q", the cursor in
+	    the terminal can remain off.
+Solution:   Call cursor_on() in mch_windexit().
+Files:	    src/os_unix.c
+
+Patch 5.6.043 (extra)
+Problem:    Win32 GUI: When selecting guifont with the dialog, 'guifont'
+	    doesn't include the bold or italic attributes.
+Solution:   Append ":i" and/or ":b" to 'guifont' in gui_mch_init_font().
+Files:	    src/gui_w32.c
+
+Patch 5.6.044 (extra)
+Problem:    MS-DOS and Windows: The line that dosinst.exe appends to
+	    autoexec.bat to set PATH is wrong when Vim is in a directory with
+	    an embedded space.
+Solution:   Use double quotes for the value when there is an embedded space.
+Files:	    src/dosinst.c
+
+Patch 5.6.045 (extra) (fixed version)
+Problem:    VMS: Various small problems.
+Solution:   Many small changes. (Zoltan Arpadffy)
+	    File name modifier ":h" keeps the path separator.
+	    File name modifier ":e" also removes version.
+	    Compile with MAX_FEAT by default.
+	    When checking for autocommands ignore version in file name.
+	    Be aware of file names being case insensitive.
+	    Added vt320 builtin termcap.
+	    Be prepared for an empty default_vim_dir.
+Files:	    runtime/gvimrc_example.vim, runtime/vimrc_example.vim,
+	    runtime/doc/os_vms.txt, src/eval.c, src/feature.h, src/fileio.c,
+	    src/gui_motif.c, src/gui_vms_conf.h, src/main.c, src/memline.c,
+	    src/misc1.c, src/option.c, src/os_vms_conf.h, src/os_vms.c,
+	    src/os_vms.h, src/os_vms.mms, src/tag.c, src/term.c, src/version.c
+
+Patch 5.6.046
+Problem:    Systems with backslash in file name: With 'shellslash' set, "vim
+	    */*.c" only uses a slash for the first file name.  (Har'El)
+Solution:   Fix slashes in file name arguments after reading the vimrc file.
+Files:	    src/option.c
+
+Patch 5.6.047
+Problem:    $CPPFLAGS is not passed on to ctags configure.
+Solution:   Add it. (Walter Briscoe)
+Files:	    src/config.mk.in, src/Makefile
+
+Patch 5.6.048
+Problem:    CTRL-R in Command-line mode is documented to insert text as typed,
+	    but inserts text literally.
+Solution:   Make CTRL-R insert text as typed, use CTRL-R CTRL-R to insert
+	    literally.  This is consistent with Insert mode.  But characters
+	    that end Command-line mode are inserted literally.
+Files:	    runtime/doc/index.txt, runtime/doc/cmdline.txt, src/ex_getln.c,
+	    src/ops.c, src/proto/ops.pro
+
+Patch 5.6.049
+Problem:    Documentation for [!] after ":ijump" is wrong way around. (Benji
+	    Fisher)
+Solution:   Fix the documentation.  Also improve the code to check for a match
+	    after a /* */ comment.
+Files:	    runtime/doc/tagsearch.txt, src/search.c
+
+Patch 5.6.050
+Problem:    Replacing is wrong when replacing a single-byte char with
+	    double-byte char or the other way around.
+Solution:   Shift the text after the character when it is replaced.
+	    (Yasuhiro Matsumoto)
+Files:	    src/normal.c, src/misc1.c
+
+Patch 5.6.051
+Problem:    ":tprev" and ":tnext" don't give an error message when trying to
+	    go before the first or beyond the last tag. (Robert Webb)
+Solution:   Added error messages.  Also: Delay a second when a file-read
+	    message is going to overwrite an error message, otherwise it won't
+	    be seen.
+Files:	    src/fileio.c, src/tag.c
+
+Patch 5.6.052
+Problem:    Multi-byte: When an Ex command has a '|' or '"' as a second byte,
+	    it terminates the command.
+Solution:   Skip second byte of multi-byte char when checking for '|' and '"'.
+	    (Asai Kenichi)
+Files:	    src/ex_docmd.c
+
+Patch 5.6.053
+Problem:    CTRL-] doesn't work on a tag that contains a '|'. (Cesar Crusius)
+Solution:   Escape '|', '"' and '\' in tag names when using CTRL-] and also
+	    for command-line completion.
+Files:	    src/ex_getln.c, src/normal.c
+
+Patch 5.6.054
+Problem:    When using ":e" and ":e #" the cursor is put in the first column
+	    when 'startofline' is set. (Cordell)
+Solution:   Use the last known column when 'startofline' is set.
+	    Also, use ECMD_LAST more often to simplify the code.
+Files:	    src/buffer.c, src/ex_cmds.c, src/ex_docmd.c, src/proto/buffer.pro
+
+Patch 5.6.055
+Problem:    When 'statusline' only contains a text without "%" and doesn't fit
+	    in the window, Vim crashes. (Ron Aaron)
+Solution:   Don't use the pointer for the first item if there is no item.
+Files:	    src/screen.c
+
+Patch 5.6.056 (extra)
+Problem:    MS-DOS: F11 and F12 don't work when 'bioskey' is set.
+Solution:   Use enhanced keyboard functions. (Vince Negri)
+	    Detect presence of enhanced keyboard and set bioskey_read and
+	    bioskey_ready.
+Files:	    src/os_msdos.c
+
+Patch 5.6.057 (extra)
+Problem:    Win32 GUI: Multi-byte characters are wrong in dialogs and tear-off
+	    menus.
+Solution:   Use system font instead of a fixed font. (Matsumoto, Muraoka)
+Files:	    src/gui_w32.c
+
+Patch 5.6.058
+Problem:    When the 'a' flag is not in 'guioptions', non-Windows systems
+	    copy Visually selected text to the clipboard/selection on a yank
+	    or delete command anyway.  On Windows it isn't done even when the
+	    'a' flag is included.
+Solution:   Respect the 'a' flag in 'guioptions' on all systems.
+Files:	    src/normal.c
+
+Patch 5.6.059 (extra)
+Problem:    When moving the cursor over italic text and the characters spill
+	    over to the cell on the right, that spill-over is deleted.
+	    Noticed in the Win32 GUI, can happen on other systems too.
+Solution:   Redraw italic text starting from a blank, like this is already
+	    done for bold text. (Vince Negri)
+Files:	    src/gui.c, src/gui.h, src/gui_w32.c
+
+Patch 5.6.060
+Problem:    Some bold characters spill over to the cell on the left, that
+	    spill-over can remain sometimes.
+Solution:   Redraw a characters when the next character was bold and needs
+	    redrawing. (Robert Webb)
+Files:	    src/screen.c
+
+Patch 5.6.061
+Problem:    When xterm sends 8-bit controls, recognizing the version response
+	    doesn't work.
+	    When using CSI instead of <Esc>[ for the termcap color codes,
+	    using 16 colors doesn't work. (Neil Bird)
+Solution:   Also accept CSI in place of <Esc>[ for the version string.
+	    Also check for CSI when handling colors 8-15 in term_color().
+	    Use CSI for builtin xterm termcap entries when 'term' contains
+	    "8bit".
+Files:	    runtime/doc/term.txt, src/ex_cmds.c, src/option.c, src/term.c,
+	    src/os_unix.c, src/proto/option.pro, src/proto/term.pro
+
+Patch 5.6.062
+Problem:    The documentation says that setting 'smartindent' doesn't have an
+	    effect when 'cindent' is set, but it does make a difference for
+	    lines starting with "#". (Neil Bird)
+Solution:   Really ignore 'smartindent' when 'cindent' is set.
+Files:	    src/misc1.c, src/ops.c
+
+Patch 5.6.063
+Problem:    Using "I" in Visual-block mode doesn't accept a count. (Johannes
+	    Zellner)
+Solution:   Pass the count on to do_insert() and edit(). (Allan Kelly)
+Files:	    src/normal.c, src/ops.c, src/proto/ops.pro
+
+Patch 5.6.064
+Problem:    MS-DOS and Win32 console: Mouse doesn't work correctly after
+	    including patch 5.6.28. (Vince Negri)
+Solution:   Don't check for mouse scroll wheel when the mouse code contains
+	    the number of clicks.
+Files:	    src/term.c
+
+Patch 5.6.065
+Problem:    After moving the cursor around in Insert mode, typing a space can
+	    still trigger an abbreviation. (Benji Fisher)
+Solution:   Don't check for an abbreviation after moving around in Insert mode.
+Files:	    src/edit.c
+
+Patch 5.6.066
+Problem:    Still a few bold character spill-over remains after patch 60.
+Solution:   Clear character just in front of blanking out rest of the line.
+	    (Robert Webb)
+Files:	    src/screen.c
+
+Patch 5.6.067
+Problem:    When a file name contains a NL, the viminfo file is corrupted.
+Solution:   Use viminfo_writestring() to convert the NL to CTRL-V n.
+	    Also fix the Buffers menu and listing a menu name with a newline.
+Files:	    runtime/menu.vim, src/buffer.c, src/mark.c, src/menu.c
+
+Patch 5.6.068
+Problem:    Compiling the Perl interface doesn't work with Perl 5.6.0.
+	    (Bernhard Rosenkraenzer)
+Solution:   Also check xs_apiversion for the version number when prepending
+	    defines for PL_*.
+Files:	    src/Makefile
+
+Patch 5.6.069
+Problem:    "go" doesn't always end up at the right character when
+	    'fileformat' is "dos". (Bruce DeVisser)
+Solution:   Correct computations in ml_find_line_or_offset().
+Files:	    src/memline.
+
+Patch 5.6.070 (depends on 5.6.068)
+Problem:    Compiling the Perl interface doesn't work with Perl 5.6.0.
+	    (Bernhard Rosenkraenzer)
+Solution:   Simpler check instead of the one from patch 68.
+Files:	    src/Makefile
+
+Patch 5.6.071
+Problem:    "A" in Visual block mode on a Tab positions the cursor one char to
+	    the right. (Michael Haumann)
+Solution:   Correct the column computation in op_insert().
+Files:	    src/ops.c
+
+Patch 5.6.072
+Problem:    When starting Vim with "vim +startinsert", it enters Insert mode
+	    only after typing the first command. (Andrew Pimlott)
+Solution:   Insert a dummy command in the stuff buffer.
+Files:	    src/main.c
+
+Patch 5.6.073 (extra) (depends on 5.6.034)
+Problem:    Win32 GUI: When compiled with Bcc 5.5 menus don't work.
+	    In dosinst.c toupper() and tolower() give an "internal compiler
+	    error" for Bcc 5.5.
+Solution:   Define WINVER to 4 to avoid compiling for Windows 2000. (Dan
+	    Sharp)  Also cleaned up compilation arguments.
+	    Use our own implementation of toupper() in dosinst.c.  Use
+	    mytoupper() instead of tolower().
+Files:	    src/Makefile.bor, src/dosinst.c
+
+Patch 5.6.074 (extra)
+Problem:    Entering CSI directly doesn't always work, because it's recognized
+	    as the start of a special key.  Mostly a problem with multi-byte
+	    in the GUI.
+Solution:   Use K_CSI for a typed CSI character.  Use <CSI> for a normal CSI,
+	    <xCSI> for a CSI typed in the GUI.
+Files:	    runtime/doc/intro.txt, src/getchar.c, src/gui_amiga.c,
+	    src/gui_gtk_x11.c, src/gui_mac.c, src/gui_riscos.c, src/gui_w32.c,
+	    src/keymap.h, src/misc2.c
+
+Patch 5.6.075
+Problem:    When using "I" or "A" in Visual block mode while 'sts' is set may
+	    change spaces to a Tab the inserted text is not correct. (Mike
+	    Steed)  And some other problems when using "A" to append after the
+	    end of the line.
+Solution:   Check for change in spaces/tabs after inserting the text.  Append
+	    spaces to fill the gap between the end-of-line and the right edge
+	    of the block.
+Files:	    src/ops.c
+
+Patch 5.6.076
+Problem:    GTK GUI: Mapping <M-Space> doesn't work.
+Solution:   Don't use the "Alt" modifier twice in key_press_event().
+Files:	    src/gui_gtk_x11.c
+
+Patch 5.6.077
+Problem:    GUI: When interrupting an external program with CTRL-C, gvim might
+	    crash. (Benjamin Korvemaker)
+Solution:   Avoid using a NULL pointer in ui_inchar_undo().
+Files:	    src/ui.c
+
+Patch 5.6.078
+Problem:    Locale doesn't always work on FreeBSD. (David O'Brien)
+Solution:   Link with the "xpg4" library when available.
+Files:	    src/configure.in, src/configure
+
+Patch 5.6.079
+Problem:    Vim could crash when several Tcl interpreters are created and
+	    destroyed.
+Solution:   handle the "exit" command and nested ":tcl" commands better. (Ingo
+	    Wilken)
+Files:	    runtime/doc/if_tcl.txt, src/if_tcl.c
+
+Patch 5.6.080
+Problem:    When jumping to a tag, generating the tags file and jumping to the
+	    same tag again uses the old search pattern. (Sung-Hyun Nam)
+Solution:   Flush cached tag matches when executing an external command.
+Files:	    src/misc2.c, src/proto/tag.pro, src/tag.c
+
+Patch 5.6.081
+Problem:    ":syn include" uses a level for the included file, this confuses
+	    contained items included at the same level.
+Solution:   Use a unique tag for each included file.  Changed sp_syn_inc_lvl
+	    to sp_syn_inc_tag. (Scott Bigham)
+Files:	    src/syntax.c, src/structs.h
+
+Patch 5.6.082
+Problem:    When using cscope, Vim can crash.
+Solution:   Initialize tag_fname in find_tags(). (Anton Blanchard)
+Files:	    src/tag.c
+
+Patch 5.6.083 (extra)
+Problem:    Win32: The visual beep can't be seen. (Eric Roesinger)
+Solution:   Flush the output before waiting with GdiFlush(). (Maurice S. Barnum)
+	    Also: Allow specifying the delay in t_vb for the GUI.
+Files:	    src/gui.c, src/gui_amiga.c, src/gui_gtk_x11.c, src/gui_mac.c,
+	    src/gui_riscos.c, src/gui_w32.c, src/gui_x11.c, src/gui_beos.cc,
+	    src/proto/gui_amiga.pro, src/proto/gui_gtk_x11.pro,
+	    src/proto/gui_mac.pro, src/proto/gui_riscos.pro,
+	    src/proto/gui_w32.pro, src/proto/gui_x11.pro,
+	    src/proto/gui_beos.pro
+
+Patch 5.6.084 (depends on 5.6.074)
+Problem:    GUI: Entering CSI doesn't always work for Athena and Motif.
+Solution:   Handle typed CSI as <xCSI> (forgot this bit in 5.6.074).
+Files:	    src/gui_x11.c
+
+Patch 5.6.085
+Problem:    Multi-byte: Using "r" to replace a double-byte char with a
+	    single-byte char moved the cursor one character. (Matsumoto)
+	    Also, using a count when replacing a single-byte char with a
+	    double-byte char didn't work.
+Solution:   Don't use del_char() to delete the second byte.
+	    Get "ptr" again after calling ins_char().
+Files:	    src/normal.c
+
+Patch 5.6.086 (extra)
+Problem:    Win32: When using libcall() and the returned value is not a valid
+	    pointer, Vim crashes.
+Solution:   Use IsBadStringPtr() to check if the pointer is valid.
+Files:	    src/os_win32.c
+
+Patch 5.6.087
+Problem:    Multi-byte: Commands and messages with multi-byte characters are
+	    displayed wrong.
+Solution:   Detect double-byte characters. (Yasuhiro Matsumoto)
+Files:	    src/ex_getln.c, src/message.c, src/misc2.c, src/screen.c
+
+Patch 5.6.088
+Problem:    Multi-byte with Motif or Athena: The message "XIM requires
+	    fontset" is annoying when Vim was compiled with XIM support but it
+	    is not being used.
+Solution:   Remove that message.
+Files:	    src/multbyte.c
+
+Patch 5.6.089
+Problem:    On non-Unix systems it's possible to overwrite a read-only file
+	    without using "!".
+Solution:   Check if the file permissions allow overwriting before moving the
+	    file to become the backup file.
+Files:	    src/fileio.c
+
+Patch 5.6.090
+Problem:    When editing a file in "/home/dir/home/dir" this was replaced with
+	    "~~".  (Andreas Jellinghaus)
+Solution:   Replace the home directory only once in home_replace().
+Files:	    src/misc1.c
+
+Patch 5.6.091
+Problem:    When editing many "no file" files, can't create swap file, because
+	    .sw[a-p] have all been used.  (Neil Bird)
+Solution:   Also use ".sv[a-z]", ".su[a-z]", etc.
+Files:	    src/memline.c
+
+Patch 5.6.092
+Problem:    FreeBSD: When setting $TERM to a non-valid terminal name, Vim
+	    hangs in tputs().
+Solution:   After tgetent() returns an error code, call it again with the
+	    terminal name "dumb".  This apparently creates an environment in
+	    which tputs() doesn't fail.
+Files:	    src/term.c
+
+Patch 5.6.093 (extra)
+Problem:    Win32 GUI: "ls | gvim -" will show a message box about reading
+	    stdin when Vim exits. (Donohue)
+Solution:   Don't write a message about the file read from stdin until the GUI
+	    has started.
+Files:	    src/fileio.c
+
+Patch 5.6.094
+Problem:    Problem with multi-byte string for ":echo var".
+Solution:   Check for length in msg_outtrans_len_attr(). (Sung-Hyun Nam)
+	    Also make do_echo() aware of multi-byte characters.
+Files:	    src/eval.c, src/message.c
+
+Patch 5.6.095
+Problem:    With an Emacs TAGS file that include another a relative path
+	    doesn't always work.
+Solution:   Use expand_tag_fname() on the name of the included file.
+	    (Utz-Uwe Haus)
+Files:	    src/tag.c
+
+Patch 5.6.096
+Problem:    Unix: When editing many files, startup can be slow. (Paul
+	    Ackersviller)
+Solution:   Halve the number of stat() calls used to add a file to the buffer
+	    list.
+Files:	    src/buffer.c
+
+Patch 5.7a.001
+Problem:    GTK doesn't respond on drag&drop from ROX-Filer.
+Solution:   Add "text/uri-list" target. (Thomas Leonard)
+	    Also: fix problem with checking for trash arguments.
+Files:	    src/gui_gtk_x11.c
+
+Patch 5.7a.002
+Problem:    Multi-byte: 'showmatch' is performed when second byte of an
+	    inserted double-byte char is a paren or brace.
+Solution:   Check IsTrailByte() before calling showmatch(). (Taro Muraoka)
+Files:	    src/misc1.c
+
+Patch 5.7a.003
+Problem:    Multi-byte: After using CTRL-O in Insert mode with the cursor at
+	    the end of the line on a multi-byte character the cursor moves to
+	    the left.
+Solution:   Check for multi-byte character at end-of-line. (Taro Muraoka)
+	    Also: fix cls() to detect a double-byte character. (Chong-Dae Park)
+Files:	    src/edit.c, src/search.c
+
+Patch 5.7a.004
+Problem:    When reporting the search pattern offset, the string could be
+	    unterminated, which may cause a crash.
+Solution:   Terminate the string for the search offset. (Stephen P. Wall)
+Files:	    src/search.c
+
+Patch 5.7a.005
+Problem:    When ":s//~/" doesn't find a match it reports "[NULL]" for the
+	    pattern.
+Solution:   Use get_search_pat() to obtain the actually used pattern.
+Files:	    src/ex_cmds.c, src/proto/search.pro, src/search.c
+
+Patch 5.7a.006 (extra)
+Problem:    VMS: Various problems, also with the VAXC compiler.
+Solution:   In many places use the Unix code for VMS too.
+	    Added time, date and compiler version to version message.
+	    (Zoltan Arpadffy)
+Files:	    src/ex_cmds.c, src/ex_docmd.c, src/globals.h, src/gui_vms_conf.h,
+	    src/main.c, src/message.c, src/misc1.c, src/os_vms.c,
+	    src/os_vms.h, src/os_vms.mms, src/os_vms_conf.h,
+	    src/proto/os_vms.pro, src/proto/version.pro, src/term.c,
+	    src/version.c, src/xxd/os_vms.mms, src/xxd/xxd.c
+
+Patch 5.7a.007
+Problem:    Motif and Athena GUI: CTRL-@ is interpreted as CTRL-C.
+Solution:   Only use "intr_char" when it has been set.
+Files:	    src/gui_x11.c
+
+Patch 5.7a.008
+Problem:    GTK GUI: When using CTRL-L the screen is redrawn twice, causing
+	    trouble for bold characters.  Also happens when moving with the
+	    scrollbar.  Best seen when 'writedelay' is non-zero.
+	    When starting the GUI with ":gui" the screen is redrawn once with
+	    the wrong colors.
+Solution:   Only set the geometry hints when the window size really changed.
+	    This avoids setting it each time the scrollbar is forcefully
+	    redrawn.
+	    Don't redraw in expose_event() when gui.starting is still set.
+Files:	    src/gui_gtk_x11.c
+
+
+==============================================================================
+VERSION 5.8						*version-5.8*
+
+Version 5.8 is a bug-fix version of 5.7.
+
+
+Changed							*changed-5.8*
+-------
+
+Ctags is no longer included with Vim.  It has grown into a project of its own.
+You can find it here:  http://ctags.sf.net.  It is highly recommended as a Vim
+companion when you are writing programs.
+
+
+Added							*added-5.8*
+-----
+
+New syntax files:
+acedb		AceDB (Stewart Morris)
+aflex		Aflex (Mathieu Clabaut)
+antlr		Antlr (Mathieu Clabaut)
+asm68k		68000 Assembly (Steve Wall)
+automake	Automake (John Williams)
+ayacc		Ayacc (Mathieu Clabaut)
+b		B (Mathieu Clabaut)
+bindzone	BIND zone (glory hump)
+blank		Blank (Rafal Sulejman)
+cfg		Configure files (Igor Prischepoff)
+changelog	ChangeLog (Gediminas Paulauskas)
+cl		Clever (Phil Uren)
+crontab		Crontab (John Hoelzel)
+csc		Essbase script (Raul Segura Acevedo)
+cynlib		Cynlib(C++) (Phil Derrick)
+cynpp		Cyn++ (Phil Derrick)
+debchangelog	Debian Changelog (Wichert Akkerman)
+debcontrol	Debian Control (Wichert Akkerman)
+dns		DNS zone file (Jehsom)
+dtml		Zope's DTML (Jean Jordaan)
+dylan		Dylan, Dylan-intr and Dylan-lid (Brent Fulgham)
+ecd		Embedix Component Description (John Beppu)
+fgl		Informix 4GL (Rafal Sulejman)
+foxpro		FoxPro (Powing Tse)
+gsp		GNU Server Pages (Nathaniel Harward)
+gtkrc		GTK rc (David Necas)
+hercules	Hercules (Avant! Corporation) (Dana Edwards)
+htmlos		HTML/OS by Aestiva (Jason Rust)
+inittab		SysV process control (David Necas)
+iss		Inno Setup (Dominique Stephan)
+jam		Jam (Ralf Lemke)
+jess		Jess (Paul Baleme)
+lprolog		LambdaProlog (Markus Mottl)
+ia64		Intel Itanium (parth malwankar)
+kix		Kixtart (Nigel Gibbs)
+mgp		MaGic Point (Gerfried Fuchs)
+mason		Mason (HTML with Perl) (Andrew Smith)
+mma		Mathematica (Wolfgang Waltenberger)
+nqc		Not Quite C (Stefan Scherer)
+omnimark	Omnimark (Paul Terray)
+openroad	OpenROAD (Luis Moreno Serrano)
+named		BIND configuration (glory hump)
+papp		PApp (Marc Lehmann)
+pfmain		Postfix main config (Peter Kelemen)
+pic		PIC assembly (Aleksandar Veselinovic)
+ppwiz		PPWizard (Stefan Schwarzer)
+progress	Progress (Phil Uren)
+psf		Product Specification File (Rex Barzee)
+r		R (Tom Payne)
+registry	MS-Windows registry (Dominique Stephan)
+robots		Robots.txt (Dominique Stephan)
+rtf		Rich Text Format (Dominique Stephan)
+setl		SETL (Alex Poylisher)
+sgmldecl	SGML Declarations (Daniel A. Molina W.)
+sinda		Sinda input (Adrian Nagle)
+sindacmp	Sinda compare (Adrian Nagle)
+sindaout	Sinda output (Adrian Nagle)
+smith		SMITH (Rafal Sulejman)
+snobol4		Snobol 4 (Rafal Sulejman)
+strace		Strace (David Necas)
+tak		TAK input (Adrian Nagle)
+takcmp		TAK compare (Adrian Nagle)
+takout		TAK output (Adrian Nagle)
+tasm		Turbo assembly (FooLman)
+texmf		TeX configuration (David Necas)
+trasys		Trasys input (Adrian Nagle)
+tssgm		TSS Geometry (Adrian Nagle)
+tssop		TSS Optics (Adrian Nagle)
+tsscl		TSS Command line (Adrian Nagle)
+virata		Virata Configuration Script (Manuel M.H. Stol)
+vsejcl		VSE JCL (David Ondrejko)
+wdiff		Wordwise diff (Gerfried Fuchs)
+wsh		Windows Scripting Host (Paul Moore)
+xkb		X Keyboard Extension (David Necas)
+
+Renamed php3 to php, it now also supports php4 (Lutz Eymers)
+
+Patch 5.7.015
+Problem:    Syntax files for Vim 6.0 can't be used with 5.x.
+Solution:   Add the "default" argument to the ":highlight" command: Ignore the
+	    command if highlighting was already specified.
+Files:	    src/syntax.c
+
+Generate the Syntax menu with makemenu.vim, so that it doesn't have to be done
+when Vim is starting up.  Reduces the startup time of the GUI.
+
+
+Fixed							*fixed-5.8*
+-----
+
+Conversion of docs to HTML didn't convert "|tag|s" to a hyperlink.
+
+Fixed compiling under NeXT. (Jeroen C.M. Goudswaard)
+
+optwin.vim gave an error when used in Vi compatible mode ('cpo' contains 'C').
+
+Tcl interpreter: "buffer" command didn't check for presence of an argument.
+(Dave Bodenstab)
+
+dosinst.c: Added checks for too long file name.
+
+Amiga: a file name starting with a colon was considered absolute but it isn't.
+Amiga: ":pwd" added a slash when in the root of a drive.
+
+Macintosh: Warnings for unused variables. (Bernhard Pruemmer)
+
+Unix: When catching a deadly signal, handle it in such a way that it's
+unlikely that Vim will hang.  Call _exit() instead of exit() in case of a
+severe problem.
+
+Setting the window title from nothing to something didn't work after patch 29.
+
+Check for ownership of .exrc and .vimrc was done with stat().  Use lstat() as
+well for extra security.
+
+Win32 GUI: Printing a file with 'fileformat' "unix" didn't work.  Set
+'fileformat' to "dos" before writing the temp file.
+
+Unix: Could start waiting for a character when checking for a CTRL-C typed
+when an X event is received.
+
+Could not use Perl and Python at the same time on FreeBSD, because Perl used
+"-lc" and Python used the threaded C library.
+
+Win32: The Mingw compiler gave a few warning messages.
+
+When using "ZZ" and an autocommand for writing uses an abbreviation it didn't
+work.  Don't stuff the ":x" command but execute it directly. (Mikael Berthe)
+
+VMS doesn't always have lstat(), added an #ifdef around it.
+
+Added a few corrections for the Macintosh. (Axel Kielhorn)
+
+Win32: Gvimext could not edit more than a few files at once, the length of the
+argument was fixed.
+
+
+Previously released patches for Vim 5.7:
+
+Patch 5.7.001
+Problem:    When the current buffer is crypted, and another modified buffer
+	    isn't, ":wall" will encrypt the other buffer.
+Solution:   In buf_write() use "buf" instead of "curbuf" to check for the
+	    crypt key.
+Files:	    src/fileio.c
+
+Patch 5.7.002
+Problem:    When 'showmode' is set, using "CTRL-O :r file" waits three seconds
+	    before displaying the read text. (Wichert Akkerman)
+Solution:   Set "keep_msg" to the file message so that the screen is redrawn
+	    before the three seconds wait for displaying the mode message.
+Files:	    src/fileio.c
+
+Patch 5.7.003
+Problem:    Searching for "[[:cntrl:]]" doesn't work.
+Solution:   Exclude NUL from the matching characters, it terminates the list.
+Files:	    src/regexp.c
+
+Patch 5.7.004
+Problem:    GTK: When selecting a new font, Vim can crash.
+Solution:   In gui_mch_init_font() unreference the old font, not the new one.
+Files:	    src/gui_gtk_x11.c
+
+Patch 5.7.005
+Problem:    Multibyte: Inserting a wrapped line corrupts kterm screen.
+	    Pasting TEXT/COMPOUND_TEXT into Vim does not work.
+	    On Motif no XIM status line is displayed even though it is
+	    available.
+Solution:   Don't use xterm trick for wrapping lines for multibyte mode.
+	    Correct a missing "break", added TEXT/COMPOUND_TEXT selection
+	    request.
+	    Add XIMStatusArea fallback code.
+	    (Katsuhito Nagano)
+Files:	    src/gui_gtk_x11.c, src/multbyte.c, src/screen.c, src/ui.c
+
+Patch 5.7.006
+Problem:    GUI: redrawing the non-Visual selection is wrong when the window
+	    is unobscured. (Jean-Pierre Etienne)
+Solution:   Redraw the selection properly and don't clear it.  Added "len"
+	    argument to clip_may_redraw_selection().
+Files:	    src/gui.c, src/ui.c, src/proto/ui.pro
+
+Patch 5.7.007
+Problem:    Python: Crash when using the current buffer twice.
+Solution:   Increase the reference count for buffer and window objects.
+	    (Johannes Zellner)
+Files:	    src/if_python.c
+
+Patch 5.7.008
+Problem:    In Ex mode, backspacing over the first TAB doesn't work properly.
+	    (Wichert Akkerman)
+Solution:   Switch the cursor on before printing the newline.
+Files:	    src/ex_getln.c
+
+Patch 5.7.009 (extra)
+Problem:    Mac: Crash when using a long file.
+Solution:   Don't redefine malloc() and free(), because it will break using
+	    realloc().
+Files:	    src/os_mac.h
+
+Patch 5.7.010
+Problem:    When using CTRL-A on a very long number Vim can crash.  (Michael
+	    Naumann)
+Solution:   Truncate the length of the new number to avoid a buffer overflow.
+Files:	    src/ops.c
+
+Patch 5.7.011 (extra)
+Problem:    Win32 GUI on NT 5 and Win98: Displaying Hebrew is reversed.
+Solution:   Output each character separately, to avoid that Windows reverses
+	    the text for some fonts. (Ron Aaron)
+Files:	    src/gui_w32.c
+
+Patch 5.7.012
+Problem:    When using "-complete=buffer" for ":command" the user command
+	    fails.
+Solution:   In a user command don't replace the buffer name with a count for
+	    the  buffer number.
+Files:	    src/ex_docmd.c
+
+Patch 5.7.013
+Problem:    "gD" didn't always find a match in the first line, depending on
+	    the column the search started at.
+Solution:   Reset the column to zero before starting to search.
+Files:	    src/normal.c
+
+Patch 5.7.014
+Problem:    Rot13 encoding was done on characters with accents, which is
+	    wrong. (Sven Gottwald)
+Solution:   Only do rot13 encoding on ASCII characters.
+Files:	    src/ops.c
+
+Patch 5.7.016
+Problem:    When hitting 'n' for a ":s///c" command, the ignore-case flag was
+	    not restored, some matches were skipped. (Daniel Blaustein)
+Solution:   Restore the reg_ic variable when 'n' was hit.
+Files:	    src/ex_cmds.c
+
+Patch 5.7.017
+Problem:    When using a Vim script for Vim 6.0 with <SID> before a function
+	    name, it produces an error message even when inside an "if version
+	    >= 600".  (Charles Campbell)
+Solution:   Ignore errors in the function name when the function is not going
+	    to be defined.
+Files:	    src/eval.c
+
+Patch 5.7.018
+Problem:    When running "rvim" or "vim -Z" it was still possible to execute a
+	    shell command with system() and backtick-expansion. (Antonios A.
+	    Kavarnos)
+Solution:   Disallow executing a shell command in get_cmd_output() and
+	    mch_expand_wildcards().
+Files:	    src/misc1.c, src/os_unix.c
+
+Patch 5.7.019
+Problem:    Multibyte: In a substitute string, a multi-byte character isn't
+	    skipped properly, can be a problem when the second byte is a
+	    backslash.
+Solution:   Skip an extra byte for a double-byte character. (Muraoka Taro)
+Files:	    src/ex_cmds.c
+
+Patch 5.7.020
+Problem:    Compilation doesn't work on MacOS-X.
+Solution:   Add a couple of #ifdefs. (Jamie Curmi)
+Files:	    src/regexp.c, src/ctags/general.h
+
+Patch 5.7.021
+Problem:    Vim sometimes produces a beep when started in an xterm.  Only
+	    happens when compiled without mouse support.
+Solution:   Requesting the xterm version results in a K_IGNORE.  This wasn't
+	    handled when mouse support is disabled.  Accept K_IGNORE always.
+Files:	    src/normal.c
+
+Patch 5.7.022
+Problem:    %v in 'statusline' is not displayed when it's equal to %c.
+Solution:   Check if %V or %v is used and handle them differently.
+Files:	    src/screen.c
+
+Patch 5.7.023
+Problem:    Crash when a WinLeave autocommand deletes the buffer in the other
+	    window.
+Solution:   Check that after executing the WinLeave autocommands there still
+	    is a window to be closed.  Also update the test that was supposed
+	    to check for this problem.
+Files:	    src/window.c, testdir/test13.in, testdir/test13.ok
+
+Patch 5.7.024
+Problem:    Evaluating an expression for 'statusline' can have side effects.
+Solution:   Evaluate the expression in a sandbox.
+Files:	    src/edit.c, src/eval.c, src/proto/eval.pro, src/ex_cmds.c,
+	    src/ex_cmds.h, src/ex_docmd.c, src/globals.h, src/option.c,
+	    src/screen.c, src/undo.c
+
+Patch 5.7.025 (fixed)
+Problem:    Creating a temp file has a race condition.
+Solution:   Create a private directory to write the temp files in.
+Files:	    src/fileio.c, src/misc1.c, src/proto/misc1.pro,
+	    src/proto/fileio.pro, src/memline.c, src/os_unix.h
+
+Patch 5.7.026 (extra)
+Problem:    Creating a temp file has a race condition.
+Solution:   Create a private directory to write the temp files in.
+	    This is the extra part of patch 5.7.025.
+Files:	    src/os_msdos.h
+
+Patch 5.7.027
+Problem:    Starting to edit a file can cause a crash.  For example when in
+	    Insert mode, using CTRL-O :help abbr<Tab> to scroll the screen and
+	    then <CR>, which edits a help file. (Robert Bogomip)
+Solution:   Check if keep_msg is NULL before copying it.
+Files:	    src/fileio.c
+
+Patch 5.7.028
+Problem:    Creating a backup or swap file could fail in rare situations.
+Solution:   Use O_EXCL for open().
+Files:	    src/fileio.c, src/memfile.c
+
+Patch 5.7.029
+Problem:    Editing a file with an extremely long name crashed Vim.
+Solution:   Check for length of the name when setting the window title.
+Files:	    src/buffer.c
+
+Patch 5.7.030
+Problem:    A ":make" or ":grep" command with a very long argument could cause
+	    a crash.
+Solution:   Allocate the buffer for the shell command.
+Files:	    src/ex_docmd.c
+
+
+ vim:tw=78:ts=8:ft=help:norl:
--- /dev/null
+++ b/lib/vimfiles/doc/version6.txt
@@ -1,0 +1,14530 @@
+*version6.txt*  For Vim version 7.1.  Last change: 2007 May 11
+
+
+		  VIM REFERENCE MANUAL    by Bram Moolenaar
+
+
+Welcome to Vim Version 6.0!  A large number of features has been added.  This
+file mentions all the new items that have been added, changes to existing
+features and bug fixes compared to Vim 5.x.
+
+See |vi_diff.txt| for an overview of differences between Vi and Vim 6.0.
+See |version4.txt| for differences between Vim 3.0 and Vim 4.0.
+See |version5.txt| for differences between Vim 4.0 and Vim 5.0.
+
+INCOMPATIBLE CHANGES			|incompatible-6|
+
+Cursor position in Visual mode		|curpos-visual|
+substitute command Vi compatible	|substitute-CR|
+global option values introduced		|new-global-values|
+'fileencoding' changed			|fileencoding-changed|
+Digraphs changed			|digraphs-changed|
+Filetype detection changed		|filetypedetect-changed|
+Unlisted buffers introduced		|new-unlisted-buffers|
+CTRL-U in Command-line mode changed	|CTRL-U-changed|
+Ctags gone				|ctags-gone|
+Documentation reorganized		|documentation-6|
+Modeless selection and clipboard	|modeless-and-clipboard|
+Small incompatibilities			|incomp-small-6|
+
+NEW FEATURES				|new-6|
+
+Folding					|new-folding|
+Vertically split windows		|new-vertsplit|
+Diff mode				|new-diff-mode|
+Easy Vim: click-and-type		|new-evim|
+User manual				|new-user-manual|
+Flexible indenting			|new-indent-flex|
+Extended search patterns		|new-searchpat|
+UTF-8 support				|new-utf-8|
+Multi-language support			|new-multi-lang|
+Plugin support				|new-plugins|
+Filetype plugins			|new-filetype-plugins|
+File browser				|new-file-browser|
+Editing files over a network		|new-network-files|
+Window for command-line editing		|new-cmdwin|
+Debugging mode				|new-debug-mode|
+Cursor in virtual position		|new-virtedit|
+Debugger interface			|new-debug-itf|
+Communication between Vims		|new-vim-server|
+Buffer type options			|new-buftype|
+Printing				|new-printing|
+Ports					|ports-6|
+Quickfix extended			|quickfix-6|
+Operator modifiers			|new-operator-mod|
+Search Path				|new-search-path|
+Writing files improved			|new-file-writing|
+Argument list				|new-argument-list|
+Restore a View				|new-View|
+Color schemes				|new-color-schemes|
+Various new items			|new-items-6|
+
+IMPROVEMENTS				|improvements-6|
+
+COMPILE TIME CHANGES			|compile-changes-6|
+
+BUG FIXES				|bug-fixes-6|
+
+VERSION 6.1			|version-6.1|
+Changed					|changed-6.1|
+Added					|added-6.1|
+Fixed					|fixed-6.1|
+
+VERSION 6.2			|version-6.2|
+Changed					|changed-6.2|
+Added					|added-6.2|
+Fixed					|fixed-6.2|
+
+VERSION 6.3			|version-6.3|
+Changed					|changed-6.3|
+Added					|added-6.3|
+Fixed					|fixed-6.3|
+
+VERSION 6.4			|version-6.4|
+Changed					|changed-6.4|
+Added					|added-6.4|
+Fixed					|fixed-6.4|
+
+==============================================================================
+INCOMPATIBLE CHANGES				*incompatible-6*
+
+These changes are incompatible with previous releases.  Check this list if you
+run into a problem when upgrading from Vim 5.x to 6.0
+
+
+Cursor position in Visual mode			*curpos-visual*
+------------------------------
+
+When going from one window to another window on the same buffer while in
+Visual mode, the cursor position of the other window is adjusted to keep the
+same Visual area.  This can be used to set the start of the Visual area in one
+window and the end in another.  In vim 5.x the cursor position of the other
+window would be used, which could be anywhere and was not very useful.
+
+
+Substitute command Vi compatible		*substitute-CR*
+--------------------------------
+
+The substitute string (the "to" part of the substitute command) has been made
+Vi compatible.  Previously a CTRL-V had a special meaning and could be used to
+prevent a <CR> to insert a line break.  This made it impossible to insert a
+CTRL-V before a line break.  Now a backslash is used to prevent a <CR> to
+cause a line break.  Since the number of backslashes is halved, it is still
+possible to insert a line break at the end of the line.  This now works just
+like Vi, but it's not compatible with Vim versions before 6.0.
+
+When a ":s" command doesn't make any substitutions, it no longer sets the '[
+and '] marks.  This is not related to Vi, since it doesn't have these marks.
+
+
+Global option values introduced			*new-global-values*
+-------------------------------
+
+There are now global values for options which are local to a buffer or window.
+Previously the local options were copied from one buffer to another.  When
+editing another file this could cause option values from a modeline to be used
+for the wrong file.  Now the global values are used when entering a buffer
+that has not been used before.  Also, when editing another buffer in a window,
+the local window options are reset to their global values.  The ":set" command
+sets both the local and global values, this is still compatible.  But a
+modeline only sets the local value, this is not backwards compatible.
+
+":let &opt = val" now sets the local and global values, like ":set".  New
+commands have been added to set the global or local value:
+	:let &opt = val		like ":set"
+	:let &g:opt = val	like ":setglobal"
+	:let &l:opt = val	like ":setlocal"
+
+
+'fileencoding' changed				*fileencoding-changed*
+----------------------
+
+'fileencoding' was used in Vim 5.x to set the encoding used inside all of Vim.
+This was a bit strange, because it was local to a buffer and worked for all
+buffers.  It could never be different between buffers, because it changed the
+way text in all buffers was interpreted.
+It is now used for the encoding of the file related to the buffer.  If you
+still set 'fileencoding' it is likely to be overwritten by the detected
+encoding from 'fileencodings', thus it is "mostly harmless".
+The old FileEncoding autocommand now does the same as the new EncodingChanged
+event.
+
+
+Digraphs changed				*digraphs-changed*
+----------------
+
+The default digraphs now correspond to RFC1345.  This is very different from
+what was used in Vim 5.x. |digraphs|
+
+
+Filetype detection changed			*filetypedetect-changed*
+--------------------------
+
+The filetype detection previously was using the "filetype" autocommand group.
+This caused confusion with the FileType event name (case is ignored).  The
+group is now called "filetypedetect".  It still works, but if the "filetype"
+group is used the autocommands will not be removed by ":filetype off".
+   The support for 'runtimepath' has made the "myfiletypefile" and
+"mysyntaxfile" mechanism obsolete.  They are still used for backwards
+compatibility.
+
+The connection between the FileType event and setting the 'syntax' option was
+previously in the "syntax" autocommand group.  That caused confusion with the
+Syntax event name.  The group is now called "syntaxset".
+
+The distributed syntax files no longer contain "syntax clear".  That makes it
+possible to include one in the other without tricks.  The syntax is now
+cleared when the 'syntax' option is set (by an autocommand added from
+synload.vim).  This makes the syntax cleared when the value of 'syntax' does
+not correspond to a syntax file.  Previously the existing highlighting was
+kept.
+
+
+Unlisted buffers introduced			*new-unlisted-buffers*
+---------------------------
+
+There is now a difference between buffers which don't appear in the buffer
+list and buffers which are really not in the buffer list.  Commands like
+":ls", ":bnext", ":blast" and the Buffers menu will skip buffers not in the
+buffer list. |unlisted-buffer|
+The 'buflisted' option can be used to make a buffer appear in the buffer list
+or not.
+
+Several commands that previously added a buffer to the buffer list now create
+an unlisted buffer.  This means that a ":bnext" and ":ball" will not find these
+files until they have actually been edited.  For example, buffers used for the
+alternative file by ":write file" and ":read file".
+   Other commands previously completely deleted a buffer and now only remove
+the buffer from the buffer list.  Commands relying on a buffer not to be
+present might fail.  For example, a ":bdelete" command in an autocommand that
+relied on something following to fail (was used in the automatic tests).
+|:bwipeout| can be used for the old meaning of ":bdelete".
+
+The BufDelete autocommand event is now triggered when a buffer is removed from
+the buffer list.  The BufCreate event is only triggered when a buffer is
+created that is added to the buffer list, or when an existing buffer is added
+to the buffer list.  BufAdd is a new name for BufCreate.
+The new BufNew event is for creating any buffer and BufWipeout for really
+deleting a buffer.
+
+When doing Insert mode completion, only buffers in the buffer list are
+scanned.  Added the 'U' flag to 'complete' to do completion from unlisted
+buffers.
+
+Unlisted buffers are not stored in a viminfo file.
+
+
+CTRL-U in Command-line mode changed		*CTRL-U-changed*
+-----------------------------------
+
+Using CTRL-U when editing the command line cleared the whole line.  Most
+shells only delete the characters before the cursor.  Made it work like that.
+(Steve Wall)
+
+You can get the old behavior with CTRL-E CTRL-U: >
+	:cnoremap <C-U> <C-E><C-U>
+
+
+Ctags gone					*ctags-gone*
+----------
+
+Ctags is no longer part of the Vim distribution.  It's now a grown-up program
+by itself, it deserves to be distributed separately.
+Ctags can be found here: http://ctags.sf.net/.
+
+
+Documentation reorganized			*documentation-6*
+-------------------------
+
+The documentation has been reorganized, an item may not be where you found it
+in Vim 5.x.
+- The user manual was added, some items have been moved to it from the
+  reference manual.
+- The quick reference is now in a separate file (so that it can be printed).
+
+The examples in the documentation were previously marked with a ">" in the
+first column.  This made it difficult to copy/paste them.  There is now a
+single ">" before the example and it ends at a "<" or a non-blank in the first
+column.  This also looks better without highlighting.
+
+'helpfile' is no longer used to find the help tags file.  This allows a user
+to add its own help files (e.g., for plugins).
+
+
+Modeless selection and clipboard		*modeless-and-clipboard*
+--------------------------------
+
+The modeless selection is used to select text when Visual mode can't be used,
+for example when editing the command line or at the more prompt.
+In Vim 5.x the modeless selection was always used.  On MS-Windows this caused
+the clipboard to be overwritten, with no way to avoid that.  The modeless
+selection now obeys the 'a' and 'A' flags in 'guioptions' and "autoselect" and
+"autoselectml" in 'clipboard'.  By default there is no automatic copy on
+MS-Windows.  Use the |c_CTRL-Y| command to manually copy the selection.
+
+To get the old behavior back, do this: >
+
+	:set clipboard^=autoselectml guioptions+=A
+
+
+Small incompatibilities				*incomp-small-6*
+-----------------------
+
+'backupdir', 'cdpath', 'directory', 'equalprg', 'errorfile', 'formatprg',
+'grepprg', 'helpfile', 'makeef', 'makeprg', 'keywordprg', 'cscopeprg',
+'viminfo' and 'runtimepath' can no longer be set from a modeline, for better
+security.
+
+Removed '_' from the 'breakat' default: It's commonly used in keywords.
+
+The default for 'mousehide' is on, because this works well for most people.
+
+The Amiga binary is now always compiled with "big" features.  The "big" binary
+archive no longer exists.
+
+The items "[RO]", "[+]", "[help]", "[Preview]" and "[filetype]" in
+'statusline' no longer have a leading space.
+
+Non-Unix systems: When expanding wildcards for the Vim arguments, don't use
+'suffixes'.  It now works as if the shell had expanded the arguments.
+
+The 'lisp', 'smartindent' and 'cindent' options are not switched off when
+'paste' is set.  The auto-indenting is disabled when 'paste' is set, but
+manual indenting with "=" still works.
+
+When formatting with "=" uses 'cindent' or 'indentexpr' indenting, and there
+is no change in indent, this is not counted as a change ('modified' isn't set
+and there is nothing to undo).
+
+Report 'modified' as changed when 'fileencoding' or 'fileformat' was set.
+Thus it reflects the possibility to abandon the buffer without losing changes.
+
+The "Save As" menu entry now edits the saved file.  Most people expect it to
+work like this.
+
+A buffer for a directory is no longer added to the Buffers menu.
+
+Renamed <Return> to <Enter>, since that's what it's called on most keyboards.
+Thus it's now the hit-enter prompt instead of the hit-return prompt.
+Can map <Enter> just like <CR> or <Return>.
+
+The default for the 'viminfo' option is now '20,"50,h when 'compatible' isn't
+set.  Most people will want to use it, including beginners, but it required
+setting the option, which isn't that easy.
+
+After using ":colder" the newer error lists are overwritten.  This makes it
+possible to use ":grep" to browse in a tree-like way.  Must use ":cnewer 99"
+to get the old behavior.
+
+The patterns in 'errorformat' would sometimes ignore case (MS-Windows) and
+sometimes not (Unix).  Now case is always ignored.  Add "\C" to the pattern to
+match case.
+
+The 16 bit MS-DOS version is now compiled without the +listcmds feature
+(buffer list manipulation commands).  They are not often needed and this
+executable needs to be smaller.
+
+'sessionoptions' now includes "curdir" by default.  This means that restoring
+a session will result in the current directory being restored, instead of
+going to the directory where the session file is located.
+
+A session deleted all buffers, deleting all marks.  Now keep the buffer list,
+it shouldn't hurt for some existing buffers to remain present.
+When the argument list is empty ":argdel *" caused an error message.
+
+No longer put the search pattern from a tag jump in the history.
+
+Use "SpecialKey" highlighting for unprintable characters instead of "NonText".
+The idea is that unprintable text or any text that's displayed differently
+from the characters in the file is using "SpecialKey", and "NonText" is used
+for text that doesn't really exist in the file.
+
+Motif now uses the system default colors for the menu and scrollbar.  Used to
+be grey.  It's still possible to set the colors with ":highlight" commands and
+resources.
+
+Formatting text with "gq" breaks a paragraph at a non-empty blank line.
+Previously the line would be removed, which wasn't very useful.
+
+":normal" does no longer hang when the argument ends in half a command.
+Previously Vim would wait for more characters to be typed, without updating
+the screen.  Now it pretends an <Esc> was typed.
+
+Bitmaps for the toolbar are no longer searched for in "$VIM/bitmaps" but in
+the "bitmaps" directories in 'runtimepath'.
+
+Now use the Cmdline-mode menus for the hit-enter prompt instead of the Normal
+mode menus.  This generally works better and allows using the "Copy" menu to
+produce CTRL-Y to copy the modeless selection.
+
+Moved the font selection from the Window to the Edit menu, together with the
+other settings.
+
+The default values for 'isfname' include more characters to make "gf" work
+better.
+
+Changed the license for the documentation to the Open Publication License.
+This seemed fair, considering the inclusion of parts of the Vim book, which is
+also published under the OPL.  The downside is that we can't force someone who
+would sell copies of the manual to contribute to Uganda.
+
+After  "ayy  don't let  ""yy  or  :let @" = val  overwrite the "a register.
+Use the unnamed register instead.
+
+MSDOS: A pattern "*.*" previously also matched a file name without a dot.
+This was inconsistent with other versions.
+
+In Insert mode, CTRL-O CTRL-\ CTRL-N {cmd} remains in Normal mode.  Previously
+it would go back to Insert mode, thus confusing the meaning of CTRL-\ CTRL-N,
+which is supposed to take us to Normal mode (especially in ":amenu").
+
+Allow using ":" commands after an operator.  Could be used to implement a new
+movement command.  Thus it no longer aborts a pending operator.
+
+For the Amiga the "-d {device}" argument was possible.  When compiled with the
+diff feature, this no longer works.  Use "-dev {device}" instead. |-dev|
+
+Made the default mappings for <S-Insert> in Insert mode insert the text
+literally, avoids that special characters like BS cause side effects.
+
+Using ":confirm" applied to the rest of the line.  Now it applies only to the
+command right after it.  Thus ":confirm if x | edit | endif" no longer works,
+use ":if x | confirm edit | endif".  This was the original intention, that it
+worked differently was a bug.
+
+==============================================================================
+NEW FEATURES						*new-6*
+
+Folding							*new-folding*
+-------
+
+Vim can now display a buffer with text folded.  This allows overviewing the
+structure of a file quickly.  It is also possible to yank, delete and put
+folded text, for example to move a function to another position.
+
+There is a whole bunch of new commands and options related to folding.
+See |folding|.
+
+
+Vertically split windows				*new-vertsplit*
+------------------------
+
+Windows can also be split vertically.  This makes it possible to have windows
+side by side.  One nice use for this is to compare two similar files (see
+|new-diff-mode|).  The 'scrollbind' option can be used to synchronize
+scrolling.
+
+A vertical split can be created with the commands:
+	:vsplit	  or  CTRL-W v  or CTRL-W CTRL-V	|:vsplit|
+	:vnew						|:vnew|
+	:vertical {cmd}					|:vertical|
+The last one is a modifier, which has a meaning for any command that splits a
+window.  For example: >
+	:vertical stag main
+Will vertically split the window and jump to the tag "main" in the new window.
+
+Moving from window to window horizontally can be done with the |CTRL-W_h| and
+|CTRL-W_l| commands.  The |CTRL-W_k| and |CTRL-W_j| commands have been changed
+to jump to the window above or below the cursor position.
+
+The vertical and horizontal splits can be mixed as you like.  Resizing windows
+is easy when using the mouse, just position the pointer on a status line or
+vertical separator and drag it.  In the GUI a special mouse pointer shape
+indicates where you can drag a status or separator line.
+
+To resize vertically split windows use the |CTRL-W_<| and |CTRL-W_>| commands.
+To make a window the maximum width use the CTRL-W | command |CTRL-W_bar|.
+
+To force a new window to use the full width or height of the Vim window,
+these two modifiers are available:
+	:topleft {cmd}		New window appears at the top with full
+				width or at the left with full height.
+	:botright {cmd}		New window appears at the bottom with full
+				width or at the right with full height.
+This can be combined with ":vertical" to force a vertical split: >
+	:vert bot dsplit DEBUG
+This will open a window at the far right, occupying the full height of the Vim
+window, with the cursor on the first definition of "DEBUG".
+The help window is opened at the top, like ":topleft" was used, if the current
+window is fewer than 80 characters wide.
+
+A few options can be used to set the preferences for vertically split windows.
+They work similar to their existing horizontal equivalents:
+	horizontal	vertical ~
+	'splitbelow'	'splitright'
+	'winheight'	'winwidth'
+	'winminheight'	'winminwidth'
+It's possible to set 'winminwidth' to zero, so that temporarily unused windows
+hardly take up space without closing them.
+
+The new 'eadirection' option tells where 'equalalways' applies:
+	:set eadirection=both		both directions
+	:set eadirection=ver		equalize window heights
+	:set eadirection=hor		equalize windows widths
+This can be used to avoid changing window sizes when you want to keep them.
+
+Since windows can become quite narrow with vertical splits, text lines will
+often not fit.  The 'sidescrolloff' has been added to keep some context left
+and right of the cursor.  The 'listchars' option has been extended with the
+"precedes" item, to show a "<" for example, when there is text left off the
+screen. (Utz-Uwe Haus)
+
+"-O" command line argument: Like "-o" but split windows vertically. (Scott
+Urban)
+
+Added commands to move the current window to the very top (CTRL-W K), bottom
+(CTRL-W J), left (CTRL-W H) and right (CTRL-W L).  In the new position the
+window uses the full width/height of the screen.
+
+When there is not enough room in the status line for both the file name and
+the ruler, use up to half the width for the ruler.  Useful for narrow windows.
+
+
+Diff mode						*new-diff-mode*
+---------
+
+In diff mode Vim shows the differences between two, three or four files.
+Folding is used to hide the parts of the file that are equal.
+Highlighting is used to show deleted and changed lines.
+See |diff-mode|.
+
+An easy way to start in diff mode is to start Vim as "vimdiff file1 file2".
+Added the vimdiff manpage.
+
+In a running Vim the |:diffsplit| command starts diff mode for the current
+file and another file.  The |:diffpatch| command starts diff mode using the
+current file and a patch file.  The |:diffthis| command starts diff mode for
+the current window.
+
+Differences can be removed with the |:diffget| and |:diffput| commands.
+
+- The 'diff' option switches diff mode on in a window.
+- The |:diffupdate| command refreshes the diffs.
+- The 'diffopt' option changes how diffs are displayed.
+- The 'diffexpr' option can be set how a diff is to be created.
+- The 'patchexpr' option can be set how patch is applied to a file.
+- Added the "diff" folding method.  When opening a window for diff-mode, set
+  'foldlevel' to zero and 'foldenable' on, to close the folds.
+- Added the DiffAdd, DiffChange, DiffDelete and DiffText highlight groups to
+  specify the highlighting for differences.  The defaults are ugly...
+- Unix: make a vimdiff symbolic link for "make install".
+- Removed the now obsolete "vimdiff.vim" script from the distribution.
+- Added the "[c" and "]c" commands to move to the next/previous change in diff
+  mode.
+
+
+Easy Vim: click-and-type				*new-evim*
+------------------------
+
+eVim stands for "Easy Vim".  This is a separate program, but can also be
+started as "vim -y".
+
+This starts Vim with 'insertmode' set to allow click-and-type editing.  The
+$VIMRUNTIME/evim.vim script is used to add mappings and set options to be able
+to do most things like Notepad.  This is only for people who can't stand two
+modes.
+
+eView does the same but in readonly mode.
+
+In the GUI a CTRL-C now only interrupts when busy with something, not when
+waiting for a character.  Allows using CTRL-C to copy text to the clipboard.
+
+
+User manual						*new-user-manual*
+-----------
+
+The user manual has been added.  It is organised around editing tasks.  It
+reads like a book, from start to end.  It should allow beginners to start
+learning Vim.  It helps everybody to learn using the most useful Vim features.
+It is much easier to read than the reference manual, but omits details.  See
+|user-manual|.
+
+The user manual includes parts of the Vim book by Steve Oualline |frombook|.
+It is published under the OPL |manual-copyright|.
+
+When syntax highlighting is not enabled, the characters in the help file which
+mark examples ('>' and '<') and header lines ('~') are replaced with a space.
+
+When closing the help window, the window layout is restored from before
+opening it, if the window layout didn't change since then.
+When opening the help window, put it at the top of the Vim window if the
+current window is fewer than 80 characters and not full width.
+
+
+Flexible indenting					*new-indent-flex*
+------------------
+
+Automatic indenting is now possible for any language.  It works with a Vim
+script, which makes it very flexible to compute the indent.
+
+The ":filetype indent on" command enables using the provided indent scripts.
+This is explained in the user manual: |30.3|.
+
+The 'indentexpr' option is evaluated to get the indent for a line.  The
+'indentkeys' option tells when to trigger re-indenting.  Normally these
+options are set from an indent script.  Like Syntax files, indent scripts will
+be created and maintained by many people.
+
+
+Extended search patterns				*new-searchpat*
+------------------------
+
+Added the possibility to match more than one line with a pattern. (partly by
+Loic Grenie)
+New items in a search pattern for multi-line matches:
+\n		match end-of-line, also in []
+\_[]		match characters in range and end-of-line
+\_x		match character class and end-of-line
+\_.		match any character or end-of-line
+\_^		match start-of-line, can be used anywhere in the regexp
+\_$		match end-of-line, can be used anywhere in the regexp
+
+Various other new items in search patterns:
+\c		ignore case for the whole pattern
+\C		match case for the whole pattern
+\m		magic on for the following
+\M		magic off for the following
+\v		make following characters "very magic"
+\V		make following characters "very nomagic"
+
+\@!		don't match atom before this.
+		Example: "foo\(bar\)\@!" matches "foo " but not "foobar".
+\@=		match atom, resulting in  zero-width match
+		Example: "foo\(bar\)\@=" matches "foo" in "foobar".
+\@<!		don't match preceding atom before the current position
+\@<=		match preceding atom before the current position
+\@>		match preceding atom as a subexpression
+
+\&		match only when branch before and after it match
+
+\%[]		optionally match a list of atoms; "end\%[if]" matches "end",
+		"endi" and "endif"
+\%(\)		like \(\), but without creating a back-reference; there can be
+		any number of these, overcomes the limit of nine \( \) pairs
+\%^		match start-of-file (Chase Tingley)
+\%$		match end-of-file (Chase Tingley)
+\%#		Match with the cursor position. (Chase Tingley)
+\?		Just like "\=" but can't be used in a "?" command.
+
+\%23l		match in line 23
+\%<23l		match before line 23
+\%>23l		match after line 23
+\%23c, \%<23c, \%>23c   match in/before/after column 23
+\%23v, \%<23v, \%>23v	match in/before/after virtual column 23
+
+
+For syntax items:
+\z(...\)	external reference match set (in region start pattern)
+\z1 - \z9	external reference match use (in region skip or end pattern)
+	(Scott Bigham)
+
+\zs		use position as start of match
+\ze		use position as end of match
+
+Removed limit of matching only up to 32767 times with *, \+, etc.
+
+Added support to match multi-byte characters. (partly by Muraoka Taro)
+Made "\<" and "\>" work for UTF-8. (Muraoka Taro)
+
+
+UTF-8 support						*new-utf-8*
+-------------
+
+Vim can now edit files in UTF-8 encoding.  Up to 31 bit characters can be
+used, but only 16 bit characters are displayed.  Up to two combining
+characters are supported, they overprint the preceding character.
+Double-wide characters are also supported.  See |UTF-8|.
+
+UCS-2, UCS-4 and UTF-16 encodings are supported too, they are converted to
+UTF-8 internally.  There is also support for editing Unicode files in a Latin1
+environment.  Other encodings are converted with iconv() or an external
+converter specified with 'charconvert'.
+
+Many new items for Multi-byte support:
+- Added 'encoding' option: specifies character encoding used inside Vim.  It
+  can be any 8-bit encoding, some double-byte encodings or Unicode.
+  It is initialized from the environment when a supported value is found.
+- Added 'fileencoding' and 'fileencodings': specify character coding in a
+  file, similar to 'fileformat' and 'fileformats'.
+  When 'encoding' is "utf-8" and 'fileencodings' is "utf-8,latin1" this will
+  automatically switch to latin1 if a file does not contain valid UTF-8.
+- Added 'bomb' option and detection of a BOM at the start of a file.  Can be
+  used with "ucs-bom" in 'fileencodings' to automatically detect a Unicode
+  file if it starts with a BOM.  Especially useful on MS-Windows (NT and
+  2000), which uses ucs-2le files with a BOM (e.g., when exporting the
+  registry).
+- Added the 'termencoding' option: Specifies the encoding used for the
+  terminal.  Useful to put Vim in utf-8 mode while in a non-Unicode locale: >
+    :let &termencoding = &encoding
+    :set encoding=utf-8
+- When 'viminfo' contains the 'c' flag, the viminfo file is converted from the
+  'encoding' it was written with to the current 'encoding'.
+- Added ":scriptencoding" command: convert lines in a sourced script to
+  'encoding'.  Useful for menu files.
+- Added 'guifontwide' to specify a font for double-wide characters.
+- Added Korean support for character class detection.  Also fix cls() in
+  search.c. (Chong-Dae Park)
+- Win32: Typing multi-byte characters without IME. (Alexander Smishlajev)
+- Win32 with Mingw: compile with iconv library. (Ron Aaron)
+- Win32 with MSVC: dynamically load iconv.dll library. (Muraoka Taro)
+- Make it possible to build a version with multi-byte and iconv support with
+  Borland 5.5.  (Yasuhiro Matsumoto)
+- Added 'delcombine' option: Delete combining character separately. (Ron
+  Aaron)
+- The "xfontset" feature isn't required for "xim".  These are now two
+  independent features.
+- XIM: enable XIM when typing a language character (Insert mode, Search
+  pattern, "f" or "r" command).  Disable XIM when typing a Normal mode
+  command.
+- When the XIM is active, show "XIM" in the 'showmode' message. (Nam SungHyun)
+- Support "CursorIM" for XIM.  (Nam SungHyun)
+- Added 'm' flag to 'formatoptions': When wrapping words, allow splitting at
+  each multibyte character, not only at a space.
+- Made ":syntax keyword" work with multi-byte characters.
+- Added support for Unicode upper/lowercase flipping and comparing. (based on
+  patch by Raphael Finkel)
+  Let "~" on multi-byte characters that have a third case ("title case")
+  switch between the three cases. (Raphael Finkel)
+
+Allow defining digraphs for multi-byte characters.
+Added RFC1345 digraphs for Unicode.
+Most Normal mode commands that accept a character argument, like "r", "t" and
+"f" now accept a digraph.  The 'D' flag in 'cpoptions' disables this to remain
+Vi compatible.
+
+Added Language mapping and 'keymap' to be able to type multi-byte characters:
+- Added the ":lmap" command and friends: Define mappings that are used when
+  typing characters in the language of the text.  Also for "r", "t", etc.  In
+  Insert and Command-line mode CTRL-^ switches the use of the mappings on/off.
+  CTRL-^ also toggles the use of an input method when no language mappings are
+  present.  Allows switching the IM back on halfway typing.
+- "<char-123>" argument to ":map", allows to specify the decimal, octal or
+  hexadecimal value of a character.
+- Implemented the 'keymap' option: Load a keymap file.  Uses ":lnoremap" to
+  define mappings for the keymap.  The new ":loadkeymap" command is used in
+  the keymap file.
+- Added 'k' flag in 'statusline': Value of "b:keymap_name" or 'keymap' when
+  it's being used.  Uses "<lang>" when no keymap is loaded and ":lmap"s are
+  active.  Show this text in the default statusline too.
+- Added the 'iminsert' and 'imsearch' options: Specify use of langmap mappings
+  and Input Method with an option. (Muraoka Taro)
+  Added 'imcmdline' option: When set the input method is always enabled when
+  starting to edit a command line.  Useful for a XIM that uses dead keys to
+  type accented characters.
+  Added 'imactivatekey' option to better control XIM.  (Muraoka Taro)
+- When typing a mapping that's not finished yet, display the last character
+  under the cursor in Insert mode and Command-line mode.  Looks good for dead
+  characters.
+- Made the 'langmap' option recognize multi-byte characters.  But mapping only
+  works for 8-bit characters.  Helps when using UTF-8.
+- Use a different cursor for when ":lmap" mappings are active.  Can specify
+  two highlight groups for an item in 'guicursor'.  By default "lCursor" and
+  "Cursor" are equal, the user must set a color he likes.
+  Use the cursor color for hangul input as well. (Sung-Hyun Nam)
+- Show "(lang)" for 'showmode' when language mapping is enabled.
+- UTF-8: Made "r" work with a ":lmap" that includes a composing character.
+  Also works for "f", which now works to find a character that includes a
+  composing character.
+
+Other multi-byte character additions:
+- Support double-byte single-width characters for euc-jp: Characters starting
+  with 0x8E.  Added ScreenLines2[] to store the second byte.
+
+
+Multi-language support					*new-multi-lang*
+----------------------
+
+The messages used in Vim can be translated.  Several translations are
+available.  This uses the gettext mechanism.  It allows adding a translation
+without recompiling Vim.  |multi-lang| (partly by Marcin Dalecki)
+
+The translation files are in the src/po directory.  The src/po/README.txt file
+explains a few things about doing a translation.
+
+Menu translations are available as well.  This uses the new |:menutranslate|
+command.  The translations are found in the runtime directory "lang".  This
+allows a user to add a translation.
+
+Added |:language| command to set the language (locale) for messages, time and
+character type.  This allows switching languages in Vim without changing the
+locale outside of Vim.
+
+Made it possible to have vimtutor use different languages.  (Eduardo Fernandez)
+Spanish (Eduardo Fernandez), Italian (Antonio Colombo), Japanese (Yasuhiro
+Matsumoto) and French (Adrien Beau) translations are included.
+Added "vimtutor.bat": script to start Vim on a copy of the tutor file for
+MS-Windows. (Dan Sharp)
+
+- Added v:lang variable to be able to get current language setting.
+  (Marcin Dalecki)  Also v:lc_time and v:ctype.
+- Make it possible to translate the dialogs used by the menus.  Uses global
+  "menutrans_" variables.  ":menutrans clear" deletes them.
+- removed "broken locale" (Marcin Dalecki).
+- Don't use color names in icons, use RGB values.  The names could be
+  translated.
+- Win32: Added global IME support (Muraoka)
+- Win32: Added dynamic loading of IME support.
+- ":messages" prints a message about who maintains the messages or the
+  translations.  Useful to find out where to make a remark about a wrong
+  translation.
+- --disable-nls argument for configure: Disable use of gettext(). (Sung-Hyun
+  Nam)
+- Added NLS support for Win32 with the MingW compiler. (Eduardo Fernandez)
+- When available, call bind_textdomain_codeset() to have gettext() translate
+  messages to 'encoding'.  This requires GNU gettext 0.10.36 or later.
+- Added gettext support for Win32.  This means messages will be translated
+  when the locale is set and libintl.dll can be found.  (Muraoka Taro)
+  Also made it work with MingW compiler.  (Eduardo Fernandez)
+  Detect the language and set $LANG to get the appropriate translated messages
+  (if supported).  Also use $LANG to select a language, v:lang is a very
+  different kind of name.
+- Made gvimext.dll use translated messages, if possible. (Yasuhiro Matsumoto)
+
+
+Plugin support					*new-plugins*
+--------------
+
+To make it really easy to load a Vim script when starting Vim, the "plugin"
+runtime directory can be used.  All "*.vim" files in it will be automatically
+loaded.  For Unix, the directory "~/.vim/plugin" is used by default.  The
+'runtimepath' option can be set to look in other directories for plugins.
+|load-plugins| |add-plugin|
+
+The |:runtime| command has been added to load one or more files in
+'runtimepath'.
+
+Standard plugins:
+netrw.vim - Edit files over a network |new-network-files|
+gzip.vim - Edit compressed files
+explorer.vim - Browse directories |new-file-browser|
+
+Added support for local help files. |add-local-help|.
+When searching for help tags, all "doc/tags" files in 'runtimepath' are used.
+Added the ":helptags" command: Generate a tags file for a help directory.
+The first line of each help file is automagically added to the "LOCAL
+ADDITIONS" section in doc/help.txt.
+
+Added the <unique> argument to ":map": only add a mapping when it wasn't
+defined before.
+
+When displaying an option value with 'verbose' set will give a message about
+where the option was last set.  Very useful to find out which script did set
+the value.
+
+The new |:scriptnames| command displays a list of all scripts that have been
+sourced.
+
+GUI: For Athena, Motif and GTK look for a toolbar bitmap in the "bitmaps"
+directories in 'runtimepath'.  Allows adding your own bitmaps.
+
+
+Filetype plugins				*new-filetype-plugins*
+-----------------
+
+A new group of files has been added to do settings for specific file types.
+These can be options and mappings which are specifically used for one value of
+'filetype'.
+
+The files are located in "$VIMRUNTIME/ftplugin".  The 'runtimepath' option
+makes it possible to use several sets of plugins: Your own, system-wide,
+included in the Vim distribution, etc.
+
+To be able to make this work, several features were added:
+- Added the "s:" variables, local to a script.  Avoids name conflicts with
+  global variables.  They can be used in the script and in functions,
+  autocommands and user commands defined in the script.  They are kept between
+  invocations of the same script.  |s:var|
+- Added the global value for local options.  This value is used when opening
+  a new buffer or editing another file.  The option value specified in a
+  modeline or filetype setting is not carried over to another buffer.
+  ":set" sets both the local and the global value.
+  ":setlocal" sets the local option value only.
+  ":setglobal" sets or displays the global value for a local option.
+  ":setlocal name<" sets a local option to its global value.
+- Added the buffer-local value for some global options: 'equalprg', 'makeprg',
+  'errorformat', 'grepprg', 'path', 'dictionary', 'thesaurus', 'tags',
+  'include' and 'define'.  This allows setting a local value for these global
+  options, without making it incompatible.
+- Added mappings and abbreviations local to a buffer: ":map <buffer>".
+- In a mapping "<Leader>" can be used to get the value of the "mapleader"
+  variable.  This simplifies mappings that use "mapleader".  "<Leader>"
+  defaults to "\".  "<LocalLeader>" does the same with "maplocalleader".  This
+  is to be used for mappings local to a buffer.
+- Added <SID> Script ID to define functions and mappings local to a script.
+- Added <script> argument to ":noremap" and ":noremenu": Only remap
+  script-local mappings.  Avoids that mappings from other scripts get in the
+  way, but does allow using mappings defined in the script.
+- User commands can be local to a buffer: ":command -buffer".
+
+The new ":setfiletype" command is used in the filetype detection autocommands,
+to avoid that 'filetype' is set twice.
+
+
+File browser						*new-file-browser*
+------------
+
+When editing a directory, the explorer plugin will list the files in the
+directory.  Pressing <Enter> on a file name edits that file.  Pressing <Enter>
+on a directory moves the browser to that directory.
+
+There are several other possibilities, such as opening a file in the preview
+window, renaming files and deleting files.
+
+
+Editing files over a network				*new-network-files*
+----------------------------
+
+Files starting with scp://, rcp://, ftp:// and http:// are recognized as
+remote files.  An attempt is made to access these files with the indicated
+method.  For http:// only reading is possible, for the others writing is also
+supported.  Uses the netrw.vim script as a standard "plugin". |netrw|
+
+Made "gf" work on a URL.  It no longer assumes the file is local on the
+computer (mostly didn't work anyway, because the full path was required).
+Adjusted test2 for this.
+
+Allow using a URL in 'path'.  Makes ":find index.html" work.
+
+GTK: Allow dropping a http:// and ftp:// URL on Vim.  The netrw plugin takes
+care of downloading the file. (MiKael Berthe)
+
+
+Window for command-line editing				*new-cmdwin*
+-------------------------------
+
+The Command-line window can be used to edit a command-line with Normal and
+Insert mode commands.  When it is opened it contains the history.  This allows
+copying parts of previous command lines. |cmdwin|
+
+The command-line window can be opened from the command-line with the key
+specified by the 'cedit' option (like Nvi).  It can also be opened directly
+from Normal mode with "q:", "q/" and "q?".
+
+The 'cmdwinheight' is used to specify the initial height of the window.
+
+In Insert mode CTRL-X CTRL-V can be used to complete an Ex command line, like
+it's done on the command-line.  This is also useful for writing Vim scripts!
+
+Additionally, there is "improved Ex mode".  Entered when Vim is started as
+"exim" or "vim -E", and with the "gQ" command.  Works like repeated use of
+":", with full command-line editing and completion. (Ulf Carlsson)
+
+
+Debugging mode						*new-debug-mode*
+--------------
+
+In debugging mode sourced scripts and user functions can be executed line by
+line.  There are commands to step over a command or step into it. |debug-mode|
+
+Breakpoints can be set to run until a certain line in a script or user
+function is executed. |:breakadd|
+
+Debugging can be started with ":debug {cmd}" to debug what happens when a
+command executes.  The |-D| argument can be used to debug while starting up.
+
+
+Cursor in virtual position				*new-virtedit*
+--------------------------
+
+Added the 'virtualedit' option: Allow positioning the cursor where there is no
+actual character in Insert mode, Visual mode or always. (Matthias Kramm)
+This is especially useful in Visual-block mode.  It allows positioning a
+corner of the area where there is no text character.  (Many improvements by
+Chase Tingley)
+
+
+Debugger interface					*new-debug-itf*
+------------------
+
+This was originally made to work with Sun Visual Workshop. (Gordon Prieur)
+See |debugger.txt|, |sign.txt| and |workshop.txt|.
+
+Added the ":sign" command to define and place signs.  They can be displayed
+with two ASCII characters or an icon.  The line after it can be highlighted.
+Useful to display breakpoints and the current PC position.
+
+Added the |:wsverb| command to execute debugger commands.
+
+Added balloon stuff: 'balloondelay' and 'ballooneval' options.
+
+Added "icon=" argument for ":menu".  Allows defining a specific icon for a
+ToolBar item.
+
+
+Communication between Vims				*new-vim-server*
+--------------------------
+
+Added communication between two Vims.  Makes it possible to send commands from
+one Vim to another.  Works for X-Windows and MS-Windows |clientserver|.
+
+Use "--remote" to have files be edited in an already running Vim.
+Use "--remote-wait" to do the same and wait for the editing to finish.
+Use "--remote-send" to send commands from one Vim to another.
+Use "--remote-expr" to have an expression evaluated in another Vim.
+Use "--serverlist" to list the currently available Vim servers.  (X only)
+There are also functions to communicate between the server and the client.
+|remote_send()| |remote_expr()|
+
+(X-windows version implemented by Flemming Madsen, MS-Windows version by Paul
+Moore)
+
+Added the command server name to the window title, so you can see which server
+name belongs to which Vim.
+
+Removed the OleVim directory and SendToVim.exe and EditWithVim.exe from the
+distribution.  Can now use "gvim --remote" and "gvim --remote-send", which is
+portable.
+
+GTK+: Support running Vim inside another window.  Uses the --socketid argument
+(Neil Bird)
+
+
+Buffer type options					*new-buftype*
+-------------------
+
+The 'buftype' and 'bufhidden' options have been added.  They can be set to
+have different kinds of buffers.  For example:
+- 'buftype' = "quickfix": buffer with error list
+- 'buftype' = "nofile" and 'bufhidden' = "delete": scratch buffer that will be
+  deleted as soon as there is no window displaying it.
+
+'bufhidden' can be used to overrule the 'hidden' option for one buffer.
+
+In combination with 'buflisted' and 'swapfile' this offers the possibility to
+use various kinds of special buffers.  See |special-buffers|.
+
+
+Printing						*new-printing*
+--------
+
+Included first implementation of the ":hardcopy" command for printing
+to paper.  For MS-Windows any installed printer can be used.  For other
+systems a PostScript file is generated, which can be printed with the
+'printexpr' option.
+(MS-Windows part by Vince Negri, Vipin Aravind, PostScript by Vince Negri and
+Mike Williams)
+
+Made ":hardcopy" work with multi-byte characters. (Muraoka Taro, Yasuhiro
+Matsumoto)
+
+Added options to tune the way printing works: (Vince Negri)
+- 'printoptions' defines various things.
+- 'printheader' specifies the header format.  Added "N" field to 'statusline'
+  for the page number.
+- 'printfont' specifies the font name and attributes.
+- 'printdevice' defines the default printer for ":hardcopy!".
+
+
+Ports							*ports-6*
+-----
+
+Port to OS/390 Unix (Ralf Schandl)
+- A lot of changes to handle EBCDIC encoding.
+- Changed Ctrl('x') to Ctrl_x define.
+
+Included jsbmouse support. (Darren Garth)
+Support for dec mouse in Unix. (Steve Wall)
+
+Port to 16-bit MS Windows (Windows 3.1x) (Vince Negri)
+
+Port to QNX.  Supports the Photon GUI, mouse, etc. (Julian Kinraid)
+
+Allow cross-compiling the Win32 version with Make_ming.mak. (Ron Aaron)
+Added Python support for compiling with Mingw. (Ron Aaron)
+
+Dos 32 bit: Added support the Windows clipboard. (David Kotchan)
+
+Win32: Dynamically load Perl and Python.  Allows compiling Vim with these
+interfaces and will try to find the DLLs at runtime. (Muraoka Taro)
+
+Compiling the Win32 GUI with Cygwin.  Also compile vimrun, dosinst and
+uninstall.  (Gerfried)
+
+Mac: Make Vim compile with the free MPW compiler supplied by Apple.  And
+updates for CodeWarrior. (Axel Kielhorn)
+
+Added typecasts and ifdefs as a start to make Vim work on Win64 (George
+Reilly)
+
+
+Quickfix extended					*quickfix-6*
+-----------------
+
+Added the "error window".  It contains all the errors of the current error
+list.  Pressing <Enter> in a line makes Vim jump to that line (in another
+window).  This makes it easy to navigate through the error list.
+|quickfix-window|.
+
+- |:copen| opens the quickfix window.
+- |:cclose| closes the quickfix window.
+- |:cwindow| takes care that there is a quickfix window only when there are
+  recognized errors. (Dan Sharp)
+
+- Quickfix also knows "info", next to "warning" and "error" types.  "%I" can be
+  used for the start of a multi-line informational message. (Tony Leneis)
+- The "%p" argument can be used in 'errorformat' to get the column number from
+  a line where "^" points to the column. (Stefan Roemer)
+- When using "%f" in 'errorformat' on a DOS/Windows system, also include "c:"
+  in the filename, even when using "%f:".
+
+
+Operator modifiers					*new-operator-mod*
+------------------
+
+Insert "v", "V" or CTRL-V between an operator and a motion command to force
+the operator to work characterwise, linewise or blockwise. |o_v|
+
+
+Search Path						*new-search-path*
+-----------
+
+Vim can search in a directory tree not only in downwards but also upwards.
+Works for the 'path', 'cdpath' and 'tags' options. (Ralf Schandl)
+
+Also use "**" for 'tags' option. (Ralf Schandl)
+
+Added 'includeexpr', can be used to modify file name found by 'include'
+option.
+Also use 'includeexpr' for "gf" and "<cfile>" when the file can't be found
+without modification.  Useful for doing "gf" on the name after an include or
+import statement.
+
+Added the 'cdpath' option: Locations to find a ":cd" argument. (Raf)
+
+Added the 'suffixesadd' option: Suffixes to be added to a file name when
+searching for a file for the "gf", "[I", etc. commands.
+
+
+Writing files improved					*new-file-writing*
+----------------------
+
+Added the 'backupcopy' option: Select whether a file is to be copied or
+renamed to make a backup file.  Useful on Unix to speed up writing an ordinary
+file.  Useful on other systems to preserve file attributes and when editing a
+file on a Unix filesystem.
+
+Added the 'autowriteall' option.  Works like 'autowrite' but for more
+commands.
+
+Added the 'backupskip' option: A list of file patterns to skip making a backup
+file when it matches.  The default for Unix includes "/tmp/*", this makes
+"crontab -e" work.
+
+Added support for Access Control Lists (ACL) for FreeBSD and Win32.  The ACL
+is copied from the original file to the new file (or the backup if it's
+copied).
+ACL is also supported for AIX, Solaris and generic POSIX. (Tomas Ogren)
+And on SGI.
+
+
+Argument list						*new-argument-list*
+-------------
+
+The support for the argument list has been extended.  It can now be
+manipulated to contain the files you want it to contain.
+
+The argument list can now be local to a window.  It is created with the
+|:arglocal| command.  The |:argglobal| command can be used to go back to the
+global argument list.
+
+The |:argdo| command executes a command on all files in the argument list.
+
+File names can be added to the argument list with |:argadd|.  File names can
+be removed with |:argdelete|.
+
+"##" can be used like "#", it is replaced by all the names in the argument
+list concatenated.  Useful for ":grep foo ##".
+
+The |:argedit| adds a file to the argument list and edits it.  Like ":argadd"
+and then ":edit".
+
+
+Restore a View						*new-View*
+--------------
+
+The ":mkview" command writes a Vim script with the settings and mappings for
+one window.  When the created file is sourced, the view of the window is
+restored.  It's like ":mksession" for one window.
+The View also contains the local argument list and manually created, opened
+and closed folds.
+
+Added the ":loadview" command and the 'viewdir' option: Allows for saving and
+restoring views of a file with simple commands.  ":mkview 1" saves view 1 for
+the current file, ":loadview 1" loads it again.  Also allows quickly switching
+between two views on one file.  And saving and restoring manual folds and the
+folding state.
+
+Added 'viewoptions' to specify how ":mkview" works.
+
+":mksession" now also works fine with vertical splits.  It has been further
+improved and restores the view of each window.  It also works properly with
+preview and quickfix windows.
+
+'sessionoptions' is used for ":mkview" as well.
+Added "curdir" and "sesdir" to 'sessionoptions'.  Allows selection of what
+the current directory will be restored to.
+
+The session file now also contains the argument list(s).
+
+
+Color schemes						*new-color-schemes*
+-------------
+
+Support for loading a color scheme.  Added the ":colorscheme" command.
+Automatically add menu entries for available schemes.
+Should now properly reset the colors when 'background' or 't_Co' is changed.
+":highlight clear" sets the default colors again.
+":syntax reset" sets the syntax highlight colors back to the defaults.
+For ":set bg&" guess the value.  This allows a color scheme to switch back to
+the default colors.
+When syntax highlighting is switched on and a color scheme was defined, reload
+the color scheme to define the colors.
+
+
+Various new items					*new-items-6*
+-----------------
+
+Normal mode commands: ~
+
+"gi"		Jump to the ^ mark and start Insert mode.  Also works when the
+		mark is just after the line. |gi|
+
+"g'm" and "g`m"
+		Jump to a mark without changing the jumplist.  Now you can use
+		g`" to jump to the last known position in a file without side
+		effects.  Also useful in mappings.
+
+[', [`, ]' and ]`
+		move the cursor to the next/previous lowercase mark.
+
+g_		Go to last non-blank in line. (Steve Wall)
+
+
+Options: ~
+
+'autoread'	When detected that a file changed outside of Vim,
+		automatically read a buffer again when it's not changed.
+		It has a global and a local value.  Use ":setlocal autoread<"
+		to go back to using the global value for 'autoread'.
+
+'debug'		When set to "msg" it will print error messages that would
+		otherwise be omitted.  Useful for debugging 'indentexpr' and
+		'foldexpr'.
+
+'lispwords'	List of words used for lisp indenting.  It was previously hard
+		coded.  Added a number of Lisp names to the default.
+
+'fold...'	Many new options for folding.
+
+'modifiable'	When off, it is impossible to make changes to a buffer.
+		The %m and %M items in 'statusline' show a '-'.
+
+'previewwindow' Set in the preview window.  Used in a session file to mark a
+		window as the preview window.
+
+'printfont'
+'printexpr'
+'printheader'
+'printdevice'
+'printoptions'	for ":hardcopy".
+
+'buflisted'	Makes a buffer appear in the buffer list or not.
+
+Use "vim{version}:" for modelines, only to be executed when the version is
+>= {version}.  Also "vim>{version}", "vim<{version}" and "vim={version}".
+
+
+Ex commands: ~
+
+:sav[eas][!] {file}
+		Works like ":w file" and ":e #", but without loading the file
+		again and avoiding other side effects. |:saveas|
+
+:silent[!] {cmd}
+		Execute a command silently.  Also don't use a delay that would
+		come after the message.  And don't do 'showmatch'.
+		RISCOS: Removed that "!~cmd" didn't output anything, and
+		didn't wait for <Enter> afterwards.  Can use ":silent !cmd"
+		now.
+:menu <silent>  Add a menu that won't echo Ex commands.
+:map <silent>   Add a mapping that won't echo Ex commands.
+
+:checktime	Check for changed buffers.
+
+:verbose {cmd}  Set 'verbose' for one command.
+
+:echomsg {expr}
+:echoerr {expr} Like ":echo" but store the message in the history. (Mark
+		Waggoner)
+
+:grepadd	Works just like ":grep" but adds to the current error list
+		instead of defining a new list. |:grepadd|
+
+:finish		Finish sourcing a file.  Can be used to skip the rest of a Vim
+		script. |:finish|
+
+:leftabove
+:aboveleft	Split left/above current window.
+
+:rightbelow
+:belowright	Split right/below current window.
+
+:first, :bfirst, :ptfirst, etc.
+		Alias for ":rewind".  It's more logical compared to ":last".
+
+:enew		Edit a new, unnamed buffer.  This is needed, because ":edit"
+		re-edits the same file. (Wall)
+
+:quitall	Same as ":qall".
+
+:match		Define match highlighting local to a window.  Allows
+		highlighting an item in the current window without interfering
+		with syntax highlighting.
+
+:menu enable
+:menu disable	Commands to enable/disable menu entries without removing them.
+		(Monish Shah)
+
+:windo		Execute a command in all windows.
+:bufdo		Execute a command in all buffers.
+
+:wincmd		Window (CTRL-W) command.  Useful when a Normal mode command
+		can't be used (e.g., for a CursorHold autocommand).  See
+		|CursorHold-example| for a nice application with it.
+
+:lcd and :lchdir
+		Set local directory for a window. (Benjie Chen)
+
+:hide {command}
+		Execute {command} with 'hidden' set.
+
+:emenu		in Visual mode to execute a ":vmenu" entry.
+
+:popup		Pop up a popup menu.
+
+:redraw		Redraw the screen even when busy with a script or function.
+
+:hardcopy	Print to paper.
+
+:compiler	Load a Vim script to do settings for a specific compiler.
+
+:z#		List numbered lines. (Bohdan Vlasyuk)
+
+
+New marks: ~
+
+'( and ')	Begin or end of current sentence.  Useful in Ex commands.
+'{ and '}	Begin or end of current paragraph.  Useful in Ex commands.
+'.		Position of the last change in the current buffer.
+'^		Position where Insert mode was stopped.
+
+Store the ^ and . marks in the viminfo file.  Makes it possible to jump to the
+last insert position or changed text.
+
+
+New functions: ~
+argidx()	Current index in argument list.
+buflisted()	Checks if the buffer exists and has 'buflisted' set.
+cindent()	Get indent according to 'cindent'.
+eventhandler()	Returns 1 when inside an event handler and interactive
+		commands can't be used.
+executable()	Checks if a program or batch script can be executed.
+filewritable()	Checks if a file can be written. (Ron Aaron)
+foldclosed()	Find out if there is a closed fold. (Johannes Zellner).
+foldcloseend()	Find the end of a closed fold.
+foldlevel()	Find out the foldlevel. (Johannes Zellner)
+foreground()	Move the GUI window to the foreground.
+getchar()	Get one character from the user.  Can be used to define a
+		mapping that takes an argument.
+getcharmod()	Get last used key modifier.
+getbufvar()	gets the value of an option or local variable in a buffer (Ron
+		Aaron)
+getfsize()	Return the size of a file.
+getwinvar()	gets the value of an option or local variable in a window (Ron
+		Aaron)
+globpath()	Find matching files in a list of directories.
+hasmapto()	Detect if a mapping to a string is already present.
+iconv()		Convert a string from one encoding to another.
+indent()	gets the indent of a line (Ron Aaron)
+inputdialog()	Like input() but use a GUI dialog when possible.  Currently
+		only works for Win32, Motif, Athena and GTK.
+		Use inputdialog() for the Edit/Settings/Text Width menu.  Also
+		for the Help/Find.. and Toolbar FindHelp items.
+		(Win32 support by Thore B. Karlsen)
+		(Win16 support by Vince Negri)
+inputsecret()	Ask the user to type a string without showing the typed keys.
+		(Charles Campbell)
+libcall()	for Unix (Neil Bird, Johannes Zellner, Stephen Wall)
+libcallnr()	for Win32 and Unix
+lispindent()	Get indent according to 'lisp'.
+mode()		Return a string that indicates the current mode.
+nextnonblank()	Skip blank lines forwards.
+prevnonblank()	Skip blank lines backwards.  Useful to for indent scripts.
+resolve()	MS-Windows: resolve a shortcut to the file it points to.
+		Unix: resolve a symbolic link.
+search()	Search for a pattern.
+searchpair()	Search for matching pair.  Can be used in indent files to find
+		the "if" matching an endif.
+setbufvar()	sets an option or variable local to a buffer (Ron Aaron)
+setwinvar()	sets an option or variable local to a window (Ron Aaron)
+stridx()	Search for first occurrence of one string in another.
+strridx()	Search for last occurrence of one string in another.
+tolower()	Convert string to all-lowercase.
+toupper()	Convert string to all-uppercase.
+type()		Check the type of an expression.
+wincol()	window column of the cursor
+winwidth()	Width of a window. (Johannes Zellner)
+winline()	window line of the cursor
+
+
+Added expansion of curly braces in variable and function names.  This can be
+used for variable names that include the value of an option.  Or a primitive
+form of arrays. (Vince Negri)
+
+
+New autocommand events: ~
+BufWinEnter	Triggered when a buffer is displayed in a window, after using
+		the modelines.  Can be used to load a view.
+BufWinLeave	Triggered when a buffer is no longer in a window.  Also
+		triggered when exiting Vim.  Can be used to save views.
+FileChangedRO	Triggered before making the first change to a read-only file.
+		Can be used to check-out the file. (Scott Graham)
+TermResponse	Triggered when the terminal replies to the version-request.
+		The v:termresponse internal variable holds the result.  Can be
+		used to react to the version of the terminal.  (Ronald Schild)
+FileReadCmd	Triggered before reading a file.
+BufReadCmd	Triggered before reading a file into a buffer.
+FileWriteCmd	Triggered before writing a file.
+BufWriteCmd	Triggered before writing a buffer into a file.
+FileAppendCmd	Triggered before appending to a file.
+FuncUndefined	Triggered when a user function is not defined. (Ron Aaron)
+
+The autocommands for the *Cmd events read or write the file instead of normal
+file read/write.  Use this in netrw.vim to be able to edit files on a remote
+system. (Charles Campbell)
+
+
+New Syntax files: ~
+
+bdf		BDF font definition (Nikolai Weibull)
+catalog		SGML catalog (Johannes Zellner)
+debchangelog	Debian Changelog (Wichert Akkerman)
+debcontrol	Debian Control (Wichert Akkerman)
+dot		dot (Markus Mottl)
+dsl		DSSSL syntax (Johannes Zellner)
+eterm		Eterm configuration (Nikolai Weibull)
+indent		Indent profile (Nikolai Weibull)
+lftp		LFTP (Nikolai Weibull)
+lynx		Lynx config (Doug Kearns)
+mush		mush sourcecode (Bek Oberin)
+natural		Natural (Marko Leipert)
+pilrc		Pal resource compiler (Brian Schau)
+plm		PL/M (Philippe Coulonges)
+povini		Povray configuration (David Necas)
+ratpoison	Ratpoison config/command (Doug Kearns)
+readline	readline config (Nikolai Weibull)
+screen		Screen RC (Nikolai Weibull)
+specman		Specman (Or Freund)
+sqlforms	SQL*Forms (Austin Ziegler)
+terminfo	terminfo (Nikolai Weibull)
+tidy		Tidy configuration (Doug Kearns)
+wget		Wget configuration (Doug Kearns)
+
+
+Updated many syntax files to work both with Vim 5.7 and 6.0.
+
+Interface to Ruby. (Shugo Maeda)
+Support dynamic loading of the Ruby interface on MS-Windows. (Muraoka Taro)
+Support this for Mingw too. (Benoit Cerrina)
+
+Win32: Added possibility to load TCL dynamically. (Muraoka Taro)
+Also for Borland 5.5. (Dan Sharp)
+
+Win32: When editing a file that is a shortcut (*.lnk file), edit the file it
+links to.  Unless 'binary' is set, then edit the shortcut file itself.
+(Yasuhiro Matsumoto)
+
+The ":command" command now accepts a "-bar" argument.  This allows the user
+command to be followed by "| command".
+
+The preview window is now also used by these commands:
+- |:pedit| edits the specified file in the preview window
+- |:psearch| searches for a word in included files, like |:ijump|, and
+  displays the found text in the preview window.
+Added the CTRL-W P command: go to preview window.
+
+MS-DOS and MS-Windows also read the system-wide vimrc file $VIM/vimrc.  Mostly
+for NT systems with multiple users.
+
+A double-click of the mouse on a character that has a "%" match selects from
+that character to the match.  Similar to "v%".
+
+"-S session.vim" argument: Source a script file when starting up.  Convenient
+way to start Vim with a session file.
+
+Added "--cmd {command}" Vim argument to execute a command before a vimrc file
+is loaded. (Vince Negri)
+
+Added the "-M" Vim argument: reset 'modifiable' and 'write', thus disallow
+making changes and writing files.
+
+Added runtime/delmenu.vim.  Source this to remove all menus and prepare for
+loading new menus.  Useful when changing 'langmenu'.
+
+Perl script to filter Perl error messages to quickfix usable format. (Joerg
+Ziefle)
+
+Added runtime/macros/less.vim: Vim script to simulate less, but with syntax
+highlighting.
+
+MS-Windows install program: (Jon Merz)
+- The Win32 program can now create shortcuts on the desktop and install Vim in
+  the Start menu.
+- Possibly remove old "Edit with Vim" entries.
+- The Vim executable is never moved or $PATH changed.  A small batch file is
+  created in a directory in $PATH.  Fewer choices to be made.
+- Detect already installed Vim versions and offer to uninstall them first.
+
+Improved the MS-Windows uninstal program.  It now also deletes the entries in
+the Start menu, icons from the desktop and the created batch files. (Jon Merz)
+Also made it possible to delete only some of these.  Also unregister gvim for
+OLE.
+
+Generate a self-installing Vim package for MS-Windows.  This uses NSIS. (Jon
+Merz et al.)
+
+Added ":filetype detect".  Try detecting the filetype again.  Helps when
+writing a new shell script, after adding "#!/bin/csh".
+
+Added ":augroup! name" to delete an autocommand group.  Needed for the
+client-server "--remote-wait".
+
+Add the Vim version number to the viminfo file, useful for debugging.
+
+==============================================================================
+IMPROVEMENTS						*improvements-6*
+
+Added the 'n' flag in 'cpoptions': When omitted text of wrapped lines is not
+put between line numbers from 'number' option.  Makes it a lot easier to read
+wrapped lines.
+
+When there is a format error in a tags file, the byte position is reported so
+that the error can be located.
+
+"gf" works in Visual mode: Use the selected text as the file name. (Chase
+Tingley)
+
+Allow ambiguous mappings.  Thus "aa" and "aaa" can both be mapped, the longest
+matching one is used.  Especially useful for ":lmap" and 'keymap'.
+
+Encryption: Ask the key to be typed twice when crypting the first time.
+Otherwise a typo might cause the text to be lost forever. (Chase Tingley)
+
+The window title now has "VIM" on the end.  The file name comes first, useful
+in the taskbar.  A "+" is added when the file is modified.  "=" is added for
+a read-only file.  "-" is added for a file with 'modifiable' off.
+
+In Visual mode, mention the size of the selected area in the 'showcmd'
+position.
+
+Added the "b:changedtick" variable.  Incremented at each change, also for
+undo.  Can be used to take action only if the buffer has been changed.
+
+In the replacement string of a ":s" command "\=" can be used to replace with
+the result of an expression.  From this expression the submatch() function can
+be used to access submatches.
+
+When doing ":qall" and there is a change in a buffer that is being edited in
+another window, jump to that window, instead of editing that buffer in the
+current window.
+
+Added the "++enc=" and "++ff=" arguments to file read/write commands to force
+using the given 'encoding' or 'fileformat'.  And added the "v:cmdarg"
+variable, to be used for FileReadCmd autocommands that read/write the file
+themselves.
+
+When reading stdin, first read the text in binary mode and then re-read it
+with automatic selection of 'fileformat' and 'fileencoding'.  This avoids
+problems with not being able to rewind the file (e.g., when a line near the
+end of the file ends in LF instead of CR-LF).
+When reading text from stdin and the buffer is empty, don't mark it changed.
+Allows exiting without trouble.
+
+Added an ID to many error messages.  This will make it easier to find help for
+a message.
+
+Insert mode:
+- "CTRL-G j" and "CTRL-G k" can be used to insert in another line in the same
+  column.  Useful for editing a table.
+- Added Thesaurus completion with CTRL-X CTRL-T. (Vince Negri)
+- Added the 'thesaurus' option, to use instead of 'dictionary' for thesaurus
+  completion.  Added the 's' flag in 'complete'.
+- Made CTRL-X CTRL-L in Insert mode use the 'complete' option.  It now also
+  scans other loaded buffers for matching lines.
+- CTRL-R now also works in Insert mode while doing completion with CTRL-X or
+  CTRL-N. (Neil Bird)
+- When doing Insert mode completion, when completion is finished check for a
+  match with words from 'cinkeys' or 'indentkeys'.
+
+Performance:
+- Made display updating more efficient.  Insert/delete lines may be used for
+  all changes, also for undo/redo.
+- The display is not redrawn when there is typeahead in Insert mode.  Speeds
+  up CTRL-R a lot.
+- Improved speed of screen output for 32 bit DOS version. (Vince Negri)
+- When dragging with the mouse, there is a lookahead to skip mouse codes when
+  there is another one next.  Makes dragging with the mouse a lot faster.
+- Also a memory usage improvement: When calling u_save with a single line,
+  don't save it if the line was recently saved for the same undo already.
+- When using a script that appends one character at a time, the amount of
+  allocated memory was growing steadily.  Also when 'undolevels' is -1.
+  Caused by the line saved for "U" never to be freed.  Now free an undo block
+  when it becomes empty.
+- GUI and Dos32: Use a vertical scroll region, to make scrolling in a
+  vertically split window faster.  No need to redraw the whole window.
+- When scrolling isn't possible with terminal codes (e.g., for a vertically
+  split window) redraw from ScreenLines[].  That should be faster than going
+  through the lines with win_line(), especially when using syntax
+  highlighting.
+- The Syntax menu is now pre-generated by a separate script.  Makes loading
+  the menu 70% faster.  This can halve the startup time of gvim.
+- When doing ":help tag", don't open help.txt first, jump directly to the help
+  tag.  It's faster and avoids an extra message.
+- Win32: When a file name doesn't end in ".lnk" don't try resolving a
+  shortcut, it takes quite a bit of time.
+- Don't update the mouse pointer shape while there are typeahead characters.
+- Change META[] from a string into an array, avoids using strchr() on it.
+- Don't clear the command line when adding characters, avoids that screen_fill
+  is called but doesn't do anything.
+
+Robustness:
+- Unix: Check for running out of stack space when executing a regexp.  Avoids
+  a nasty crash.  Only works when the system supports running the signal
+  function on another stack.
+- Disallow ":source <dirname>".  On unix it's possible to read a directory,
+  does not make sense to use it as Vim commands.
+
+Security:
+- When reading from or writing to a temporary file, check that it isn't a
+  symbolic link.  Gives some protection against symlink attacks.
+- When creating a backup file copy or a swap file, check for it already
+  existing to avoid a symlink attack. (Colin Phipps)
+- Evaluating options which are an expression is done in a |sandbox|.  If the
+  option was set by a modeline, it cannot cause damage.
+- Use a secure way to generate temp file names: Create a private directory for
+  temp files.  Used for Unix, MS-DOS and OS/2.
+- 'makeef' can be empty, which means that an internally generated file name is
+  used.  The old default was "/tmp/file", which is a security risk.
+  Writing 'makeef' in the current directory fails in a read-only directory and
+  causes trouble when using ":grep" on all files.  Made the default empty for
+  all systems, so that a temp file is used.
+- The command from a tags file is executed in the sandbox for better security.
+- The Ruby, Tcl and Python interfaces cannot be used from the sandbox.  They
+  might do dangerous things.  Perl is still possible, but limited to the Safe
+  environment. (Donnie Smith)
+
+Syntax highlighting:
+- Optimized the speed by caching the state stack all over the file, not just
+  the part being displayed.  Required for folding.
+- Added ":syntax sync fromstart": Always parse from the start of the file.
+- Added the "display" argument for syntax items: use the item only when
+  displaying the result.  Can make parsing faster for text that isn't going to
+  be displayed.
+- When using CTRL-L, the cached states are deleted, to force parsing the text
+  again.
+- Use elfhash algorithm for table of keywords.  This should give a better
+  distribution and speedup keyword lookup. (Campbell)
+- Also allow the "lc" leading context for skip and end patterns. (Scott
+  Bigham)
+- Syntax items can have the "extend" argument to undo the effect of a
+  "keepend" argument of an item it is contained in.  Makes it possible to have
+  some contained items extend a region while others don't.
+- ":syntax clear" now deletes the b:current_syntax variable.  That's logical,
+  since no syntax is defined after this command.
+- Added ":syntax enable": switch on syntax highlighting without changing the
+  colors.  This allows specifying the colors in the .vimrc file without the
+  need for a mysyntaxfile.
+- Added ":syntax reset": reset the colors to their defaults.
+- Added the "contains=TOP" and "contains=CONTAINED" arguments.  Makes it
+  possible to define a transparent item that doesn't contain itself.
+- Added a "containedin" argument to syntax items.  Allows adding a contained
+  item to an existing item (e.g., to highlight a name in a comment).
+
+Modeless selection:
+- When in the command-line window, use modeless selection in the other
+  windows.  Makes it possible to copy visible text to the command-line window.
+- Support modeless selection on the cmdline in a terminal.  Previously it was
+  only possible for the GUI.
+- Make double-right-click in modeless selection select a whole word.  Single
+  right click doesn't use the word selection started by a double-left-click.
+  Makes it work like in Visual mode.
+- The modeless selection no longer has an implied automatic copy to the
+  clipboard.  It now obeys the 'a' and 'A' flags in 'guioptions' or
+  "autoselect" and "autoselectml" in 'clipboard'.
+- Added the CTRL-Y command in Cmdline-mode to copy the modeless selection to
+  the clipboard.  Also works at the hit-enter prompt and the more prompt.
+  Removed the mappings in runtime/mswin.vim for CTRL-Y and CTRL-Z in
+  cmdline-mode to be able to use CTRL-Y in the new way.
+
+Reduced the amount of stack space used by regmatch() to allow it to handle
+complicated patterns on a longer text.
+
+'isfname' now includes '%' and '#'.  Makes "vim dir\#file" work for MS-DOS.
+
+Added keypad special keys <kEnter>, <k0> - <k9>.  When not mapped they behave
+like the ASCII equivalent. (Ivan Wellesz and Vince Negri)
+Recognize a few more xterm keys: <C-Right>, <C-Left>, <C-End>, <C-Home>
+
+Also trigger the BufUnload event when Vim is going to exit.  Perhaps a script
+needs to do some cleaning up.
+
+Expand expression in backticks: `={expr}`.  Can be used where backtick
+expansion is done. (Vince Negri)
+
+GUI:
+- Added 'L' and 'R' flags in 'guioptions': Add a left or right scrollbar only
+  when there is a vertically split window.
+- X11: When a color can't be allocated, use the nearest match from the
+  colormap.  This avoids that black is used for many things. (Monish Shah)
+  Also do this for the menu and scrollbar, to avoid that they become black.
+- Win32 and X11: Added 'mouseshape' option: Adjust the mouse pointer shape to
+  the current mode. (Vince Negri)
+- Added the 'linespace' option: Insert a pixel line between lines. (Nam)
+- Allow modeless selection (without moving the cursor) by keeping CTRL and
+  SHIFT pressed. (Ivan Wellesz)
+- Motif: added toolbar. (Gordon Prieur)  Also added tooltips.
+- Athena: added toolbar and tooltips. (David Harrison -- based on Gordon
+  Prieur's work)
+- Made the 'toolbar' option work for Athena and Motif.  Can now switch between
+  text and icons on the fly.  (David Harrison)
+- Support menu separator lines for Athena.  (David Harrison)
+- Athena: Adjust the arrow pixmap used in a pullright menu to the size of the
+  font. (David Harrison)
+- Win32: Added "c" flag to 'guifont' to be able to specify the charset. (Artem
+  Khodush)
+- When no --enable-xim argument is given, automatically enable it when a X GUI
+  is used.  Required for dead key support (and multi-byte input).
+- After a file selection dialog, check that the edited files were not changed
+  or deleted.  The Win32 dialog allows deleting and renaming files.
+- Motif and Athena: Added support for "editres". (Marcin Dalecki)
+- Motif and Athena: Added "menuFont" to be able to specify a font or fontset
+  for the menus.  Can also be set with the "Menu" highlight group.  Useful
+  when the locale is different from 'encoding'. (David Harrison)
+  When FONTSET_ALWAYS is defined, always use a fontset for the menus.  Should
+  avoid trouble with changing from a font to a fontset.  (David Harrison)
+- Highlighting and font for the tooltips can be specified with the "Tooltip"
+  highlight group. (David Harrison)
+- The Cmdline-mode menus can be used at the more-prompt.  This mostly works
+  fine, because they start with a CTRL-C.  The "Copy" menu works to copy the
+  modeless selection.  Allows copying the output of ":set all" or ":intro"
+  without auto-selection.
+- When starting the GUI when there is no terminal connected to stdout and
+  stderr, display error messages in a dialog.  Previously they wouldn't be
+  displayed at all.
+- Allow setting 'browsedir' to the name of a directory, to be used for the
+  file dialog. (Dan Sharp)
+- b:browsefilter and g:browsefilter can be set to the filters used for the
+  file dialog.  Supported for Win32 and Motif GUI. (Dan Sharp)
+
+X11:
+- Support for the clipboard selection as register "+.  When exiting or
+  suspending copy the selection to cut buffer 0.  Should allow copy/paste with
+  more applications in a X11-standard way.  (Neil Bird)
+- Use the X clipboard in any terminal, not just in an xterm.
+  Added "exclude:" in 'clipboard': Specify a pattern to match against terminal
+  names for which no connection should be made to the X server.  The default
+  currently work for FreeBSD and Linux consoles.
+- Added a few messages for when 'verbose' is non-zero to show what happens
+  when trying to connect to the X server.  Should help when trying to find out
+  why startup is slow.
+
+GTK GUI: (partly by Marcin Dalecki)
+- With some fonts the characters can be taller than ascent + descent.  E.g.,
+  "-misc-fixed-*-*-*-*-18-*-*-*-*-*-iso10646-1".  Add one to the character
+  cell height.
+- Implement "no" value for 'winaltkeys': don't use Alt-Key as a menu shortcut,
+  when 'wak' changed after creating the menus.
+- Setting 'wak' after the GUI started works.
+- recycle text GC's to reduce communication.
+- Adjust icon size to window manager.
+- Cleanup in font handling.
+- Replace XQueryColor with GDK calls.
+- Gnome support.  Detects Gnome in configure and uses different widgets.
+  Otherwise it's much like GTK. (Andy Kahn)
+  It is disabled by default, because it causes a few problems.
+- Removed the special code to fork first and then start the GUI.  Now use
+  _exit() instead of exit(), this works fine without special tricks.
+- Dialogs sometimes appeared a bit far away.  Position the dialogs inside
+  the gvim window. (Brent Verner)
+- When dropping a file on Vim, remove extra slashes from the start of the
+  path.  Also shorten the file name if possible.
+
+Motif: (Marcin Dalecki)
+- Made the dialog layout better.
+- Added find and find/replace dialogs.
+- For the menus, change "iso-8859" to "iso_8859", Linux appears to need this.
+- Added icon to dialogs, like for GTK.
+- Use XPM bitmaps for the icon when possible.  Use the Solaris XpmP.h include
+  file when it's available.
+- Change the shadow of the toolbar items to get a visual feedback of it being
+  pressed on non-LessTif.
+- Use gadgets instead of windows for some items for speed.
+
+Command line completion:
+- Complete environment variable names. (Mike Steed)
+- For ":command", added a few completion methods: "mapping", "function",
+  "expression" and "environment".
+- When a function doesn't take arguments, let completion add () instead of (.
+
+For MS-DOS, MS-Windows and OS/2: Expand %VAR% environment variables like $VAR.
+(Walter Briscoe)
+
+Redirect messages to the clipboard ":redir @*" and to the unnamed register
+":redir @"". (Wall)
+
+":let @/ = ''" clears the search pattern, instead of setting it to an empty
+string.
+
+Expression evaluation:
+- "? :" can be used like in C.
+- col("$") returns the length of the cursor line plus one. (Stephen P. Wall)
+- Optional extra argument for match(), matchend() and matchstr(): Offset to
+  start looking for a match.
+- Made third argument to strpart() optional.  (Paul Moore, Zdenek Sekera)
+- exists() can also be used to check for Ex commands and defined autocommands.
+- Added extra argument to input(): Default text.
+- Also set "v:errmsg" when using ":silent! cmd".
+- Added the v:prevcount variable: v:count for the previous command.
+- Added "v:progname", name with which Vim was started. (Vince Negri)
+- In the verbose message about returning from a function, also show the return
+  value.
+
+Cscope:
+- Added the cscope_connection() function. (Andy Kahn)
+- ":cscope kill -1" kills all cscope connections. (Andy Kahn)
+- Added the 'cscopepathcomp' option. (Scott Hauck)
+- Added ":scscope" command, split window and execute Cscope command. (Jason
+  Duell)
+
+VMS:
+- Command line arguments are always uppercase.  Interpret a "-X" argument as
+  "-x" and "-/X" as "-X".
+- Set 'makeprg' and 'grepprg' to meaningful defaults. (Zoltan Arpadffy)
+- Use the X-clipboard feature and the X command server. (Zoltan Arpadffy)
+
+Macintosh: (Dany St-Amant)
+- Allow a tags file to have CR, CR-LF or LF line separator. (Axel Kielhorn)
+- Carbonized (while keeping non Carbon code)
+  (Some work "stolen" from Ammon Skidmore)
+- Improved the menu item index handling (should be faster)
+- Runtime commands now handle / in file name (MacOS 9 version)
+- Added ":winpos" support.
+- Support using "~" in file names for home directory.
+
+Options:
+- When using set += or ^= , check for items used twice.  Duplicates are
+  removed.  (Vince Negri)
+- When setting an option that is a list of flags, remove duplicate flags.
+- If possible, use getrlimit() to set 'maxmemtot' and 'maxmem'. (Pina)
+- Added "alpha" to 'nrformats': increment or decrement an alphabetic character
+  with CTRL-A and CTRL-X.
+- ":set opt&vi" sets an option to its Vi default, ":set opt&vim" to its Vim
+  default.  Useful to set 'cpo' to its Vim default without knowing what flags
+  that includes.
+- 'scrolloff' now also applies to a long, wrapped line that doesn't fit in the
+  window.
+- Added more option settings to the default menus.
+- Updated the option window with new options.  Made it a bit easier to read.
+
+Internal changes:
+- Split line pointers in text part and attributes part.  Allows for future
+  change to make attribute more than one byte.
+- Provide a qsort() function for systems that don't have it.
+- Changed the big switch for Normal mode commands into a table.  This cleans
+  up the code considerably and avoids trouble for some optimizing compilers.
+- Assigned a negative value to special keys, to avoid them being mixed up with
+  Unicode characters.
+- Global variables expand_context and expand_pattern were not supposed to be
+  global.  Pass them to ExpandOne() and all functions called by it.
+- No longer use the global reg_ic flag.  It caused trouble and in a few places
+  it was not set.
+- Removed the use of the stuff buffer for "*", "K", CTRL-], etc.  Avoids
+  problem with autocommands.
+- Moved some code from ex_docmd.c to ex_cmds2.c.  The file was getting too
+  big.  Also moved some code from screen.c to move.c.
+- Don't include the CRC table for encryption, generate it.  Saves quite a bit
+  of space in the source code. (Matthias Kramm)
+- Renamed multibyte.c to mbyte.c to avoid a problem with 8.3 filesystems.
+- Removed the GTK implementation of ":findhelp", it now uses the
+  ToolBar.FindHelp  menu entry.
+- Renamed mch_windexit() to mch_exit(), mch_init() to mch_early_init() and
+  mch_shellinit() to mch_init().
+
+Highlighting:
+- In a ":highlight" listing, show "xxx" with the highlight color.
+- Added support for xterm with 88 or 256 colors.  The right color numbers will
+  be used for the name used in a ":highlight" command. (Steve Wall)
+- Added "default" argument for ":highlight".  When included, the command is
+  ignored if highlighting for the group was already defined.
+  All syntax files now use ":hi default ..." to allow the user to specify
+  colors in his vimrc file.  Also, the "if did_xxx_syntax_inits" is not needed
+  anymore.  This greatly simplifies using non-default colors for a specific
+  language.
+- Adjusted colortest.vim: Included colors on normal background and reduced the
+  size by using a while loop. (Rafael Garcia-Suarez)
+- Added the "DarkYellow" color name.  Just to make the list of standard colors
+  consistent, it's not really a nice color to use.
+
+When an xterm is in 8-bit mode this is detected by the code returned for
+|t_RV|.  All key codes are automatically converted to their 8-bit versions.
+
+The OPT_TCAP_QUERY in xterm patch level 141 and later is used to obtain the
+actual key codes used and the number of colors for t_Co.  Only when |t_RV| is
+also used.
+
+":browse set" now also works in the console mode.  ":browse edit" will give an
+error message.
+
+":bdelete" and ":bunload" only report the number of deleted/unloaded buffers
+when more than 'report'.  The message was annoying when deleting a buffer in a
+script.
+
+Jump list:
+- The number of marks kept in the jumplist has been increased from 50 to 100.
+- The jumplist is now stored in the viminfo file.  CTRL-O can be used to jump
+  to positions from a previous edit session.
+- When doing ":split" copy the jumplist to the new window.
+
+Also set the '[ and '] marks for the "~" and "r" commands.  These marks are
+now always set when making a change with a Normal mode command.
+
+Python interface: Allow setting the width of a vertically split window. (John
+Cook)
+
+Added "=word" and "=~word" to 'cinkeys' (also used in 'indentkeys').
+
+Added "j1" argument in 'cinoptions': indent {} inside () for Java. (Johannes
+Zellner)
+Added the "l" flag in 'cinoptions'. (Anduin Withers)
+Added 'C', 'U', 'w' and 'm' flags to 'cinoptions'. (Servatius Brandt)
+
+When doing ":wall" or ":wqall" and a modified buffer doesn't have a name,
+mention its buffer number in the error message.
+
+":function Name" lists the function with line numbers.  Makes it easier to
+find out where an error happened.
+
+In non-blockwise Visual mode, "r" replaces all selected characters with the
+typed one, like in blockwise Visual mode.
+
+When editing the last file in the argument list in any way, allow exiting.
+Previously this was only possible when getting to that file with ":next" or
+":last".
+
+Added the '1' flag to 'formatoptions'. (Vit Stradal)
+Added 'n' flag in 'formatoptions': format a numbered list.
+
+Swap file:
+- When a swap file already exists, and the user selects "Delete" at the
+  ATTENTION prompt, use the same ".swp" swapfile, to avoid creating a ".swo"
+  file which won't always be found.
+- When giving the ATTENTION message and the date of the file is newer than the
+  date of swap file, give a warning about this.
+- Made the info for an existing swap file a bit shorter, so that it still fits
+  on a 24 line screen.
+- It was possible to make a symlink with the name of a swap file, linking to a
+  file that doesn't exist.  Vim would then silently use another file (if open
+  with O_EXCL refuses a symlink).  Now check for a symlink to exist.  Also do
+  another check for an existing swap file just before creating it to catch a
+  symlink attack.
+
+The g CTRL-G command also works in Visual mode and counts the number of words.
+(Chase Tingley)
+
+Give an error message when using 'shell' and it's empty.
+
+Added the possibility to include "%s" in 'shellpipe'.
+
+Added "uhex" value for 'display': show non-printable characters as <xx>.
+Show unprintable characters with NonText highlighting, also in the command
+line.
+
+When asked to display the value of a hidden option, tell it's not supported.
+
+Win32:
+- When dropping a shortcut on gvim (.lnk file) edit the target, not the
+  shortcut itself.  (Yasuhiro Matsumoto)
+- Added C versions of the OpenWithVim and SendToVim programs. (Walter Briscoe)
+- When 'shell' is "cmd" or "cmd.exe", set 'shellredir' to redirect stderr too.
+  Also check for the Unix shell names.
+- When $HOMEDRIVE and $HOMEPATH are defined, use them to define $HOME.  (Craig
+  Barkhouse)
+
+Win32 console version:
+- Includes the user and system name in the ":version" message, when available.
+  It generates a pathdef.c file for this.  (Jon Miner)
+- Set the window icon to Vim's icon (only for Windows 2000).  While executing
+  a shell command, modify the window title to show this.  When exiting,
+  restore the cursor position too.  (Craig Barkhouse)
+- The Win32 console version can be compiled with OLE support.  It can only
+  function as a client, not as an OLE server.
+
+Errorformat:
+- Let "%p" in 'errorformat' (column of error indicated by a row of characters)
+  also accept a line of dots.
+- Added "%v" item in 'errorformat': Virtual column number. (Dan Sharp)
+- Added a default 'errorformat' value for VMS. (Jim Bush)
+
+The "p" command can now be used in Visual mode.  It overwrites the selected
+text with the contents of a register.
+
+Highlight the <> items in the intro message to make clear they are special.
+
+When using the "c" flag for ":substitute", allow typing "l" for replacing this
+item and then stop: "last".
+
+When printing a verbose message about sourcing another file, print the line
+number.
+
+When resizing the Vim window, don't use 'equalalways'.  Avoids that making the
+Vim window smaller makes split windows bigger.  And it's what the docs say.
+
+When typing CTRL-D in Insert mode, just after an autoindent, then hitting CR
+kept the remaining white space.  Now made it work like BS: delete the
+autoindent to avoid a blank non-empty line results.
+
+Added a GetHwnd() call to the OLE interface.  (Vince Negri)
+
+Made ":normal" work in an event handler.  Useful when dropping a file on Vim
+and for CursorHold autocommands.
+
+For the MS-Windows version, don't change to the directory of the file when a
+slash is used instead of a backslash.  Explorer should always use a backslash,
+the user can use a slash when typing the command.
+
+Timestamps:
+- When a buffer was changed outside of Vim and regaining focus, give a dialog
+  to allow the user to reload the file.  Now also for other GUIs than
+  MS-Windows.  And also used in the console, when compiled with dialog
+  support.
+- Inspect the file contents to find out if it really changed, ignore
+  situations where only the time stamp changed (e.g., checking the file out
+  from CVS).
+- When checking the timestamp, first check if the file size changed, to avoid
+  a file compare then.  Makes it quicker for large (log) files that are
+  appended to.
+- Don't give a warning for a changed or deleted file when 'buftype' is set.
+- No longer warn for a changed directory.  This avoids that the file explorer
+  produces warnings.
+- Checking timestamps is only done for buffers that are not hidden.  These
+  will be checked when they become unhidden.
+- When checking for a file being changed outside of Vim, also check if the
+  file permissions changed.  When the file contents didn't change but the
+  permissions did, give a warning.
+- Avoid checking too often, otherwise the dialog keeps popping up for a log
+  file that steadily grows.
+
+Mapping <M-A> when 'encoding' is "latin1" and then setting 'encoding' to
+"utf-8" causes the first byte of a multi-byte to be mapped.  Can cause very
+hard to find problems.  Disallow mapping part of a multi-byte character.
+
+For ":python" and ":tcl" accept an in-line script. (Johannes Zellner)
+Also for ":ruby" and ":perl". (Benoit Cerrina)
+
+Made ":syn include" use 'runtimepath' when the file name is not a full path.
+
+When 'switchbuf' contains "split" and the current window is empty, don't split
+the window.
+
+Unix: Catch SIGPWR to preserve files when the power is about to go down.
+
+Sniff interface: (Anton Leherbauer)
+- fixed windows code, esp. the event handling stuff
+- adaptations for sniff 4.x ($SNIFF_DIR4)
+- support for adding sniff requests at runtime
+
+Support the notation <A-x> as an alias for <M-x>.  This logical, since the Alt
+key is used.
+
+":find" accepts a count, which means that the count'th match in 'path' is
+used.
+
+":ls" and ":buffers" output shows modified/readonly/modifiable flag.  When a
+buffer is active show "a" instead of nothing.  When a buffer isn't loaded
+show nothing instead of "-".
+
+Unix install:
+- When installing the tools, set absolute paths in tools scripts efm_perl.pl
+  and mve.awk.  Avoids that the user has to edit these files.
+- Install Icons for KDE when the directories exist and the icons do not exist
+  yet.
+
+Added has("win95"), to be able to distinguish between MS-Windows 95/98/ME and
+NT/2000/XP in a Vim script.
+
+When a ":cd" command was typed, echo the new current directory. (Dan Sharp)
+
+When using ":winpos" before the GUI window has been opened, remember the
+values until it is opened.
+
+In the ":version" output, add "/dyn" for features that are dynamically loaded.
+This indicates the feature may not always work.
+
+On Windows NT it is possible that a directory is read-only, but a file can be
+deleted.  When making a backup by renaming the file and 'backupdir' doesn't
+use the current directory, this causes the original file to be deleted,
+without the possibility to create a new file.  Give an extra error message
+then to warn to user about this.
+
+Made CTRL-R CTRL-O at the command line work like CTRL-R CTRL-R, so that it's
+consistent with Insert mode.
+
+==============================================================================
+COMPILE TIME CHANGES					*compile-changes-6*
+
+All generated files have been moved out of the "src" directory.  This makes it
+easy to see which files are not edited by hand.  The files generated by
+configure are now in the "src/auto" directory.  For Unix, compiled object
+files go in the objects directory.
+
+The source archive was over the 1.4M floppy limit.  The archives are now split
+up into two runtime and two source archives.  Also provide a bzip2 compressed
+archive that contains all the sources and runtime files.
+
+Added "reconfig" as a target for make.  Useful when changing some of the
+arguments that require flushing the cache, such as switching from GTK to
+Motif.  Adjusted the meaning of GUI_INC_LOC and GUI_LIB_LOC to be consistent
+over different GUIs.
+
+Added src/README.txt to give an overview of the main parts of the source code.
+
+The Unix Makefile now fully supports using $(DESTDIR) to install to a specific
+location.  Replaces the manual setting of *ENDLOC variables.
+
+Added the possibility for a maintainer of a binary version to include his
+e-mail address with the --with-compiledby configure argument.
+
+Included features are now grouped in "tiny", "small", "normal", "big" and
+"huge".  This replaces "min-features" and "max-features".  Using "tiny"
+disables multiple windows for a really small Vim.
+
+For the tiny version or when FEAT_WINDOWS is not defined: Firstwin and lastwin
+are equal to curwin and don't use w_next and w_prev.
+
+Added the +listcmds feature.  Can be used to compile without the Vim commands
+that manipulate the buffer list and argument list (the buffer list itself is
+still there, can't do without it).
+
+Added the +vreplace feature.  It is disabled in the "small" version to avoid
+that the 16 bit DOS version runs out of memory.
+
+Removed GTK+ support for versions older than 1.1.16.
+
+The configure checks for using PTYs have been improved.  Code taken from a
+recent version of screen.
+
+Added configure options to install Vim, Ex and View under another name (e.g.,
+vim6, ex6 and view6).
+
+Added "--with-global-runtime" configure argument.  Allows specifying the
+global directory used in the 'runtimepath' default.
+
+Made enabling the SNiFF+ interface possible with a configure argument.
+
+Configure now always checks /usr/local/lib for libraries and
+/usr/local/include for include files.  Helps finding the stuff for iconv() and
+gettext().
+
+Moved the command line history stuff into the +cmdline_hist feature, to
+exclude the command line history from the tiny version.
+
+MS-Windows: Moved common functions from Win16 and Win32 to os_mswin.c.  Avoids
+having to change two files for one problem.  (Vince Negri)
+
+Moved common code from gui_w16.c and gui_w32.c to gui_w48.c (Vince Negri)
+
+The jumplist is now a separate feature.  It is disabled for the "small"
+version (16 bit MS-DOS).
+
+Renamed all types ending in _t to end in _T.  Avoids potential problems with
+system types.
+
+Added a configure check for X11 header files that implicitly define the return
+type to int. (Steve Wall)
+
+"make doslang" in the top directory makes an archive with the menu and .mo
+files for Windows.  This uses the files generated on Unix, these should work
+on MS-Windows as well.
+
+Merged a large part of os_vms.c with os_unix.c.  The code was duplicated in
+the past which made maintenance more work.  (Zoltan Arpadffy)
+
+Updated the Borland C version 5 Makefile: (Dan Sharp)
+- Fixed the Perl build
+- Added python and tcl builds
+- Added dynamic perl and dynamic python builds
+- Added uninstal.exe build
+- Use "yes" and "no" for the options, like in Make_mvc.mak.
+
+Win32: Merged Make_gvc.mak and Make_ovc.mak into one file: Make_ivc.mak.  It's
+much smaller, many unnecessary text has been removed. (Walter Briscoe)
+Added Make_dvc.mak to be able to debug exe generated with Make_mvc.mak in
+MS-Devstudio. (Walter Briscoe)
+
+MS-Windows: The big gvim.exe, which includes OLE, now also includes
+dynamically loaded Tcl, Perl and Python.  This uses ActivePerl 5.6.1,
+ActivePython 2.1.1 and ActiveTCL 8.3.3
+
+Added AC_EXEEXT to configure.in, to check if the executable needs ".exe" for
+Cygwin or MingW.  Renamed SUFFIX to EXEEXT in Makefile.
+
+Win32: Load comdlg32.dll delayed for faster startup.  Only when using VC 6.
+(Vipin Aravind)
+
+Win32: When compiling with Borland, allow using IME. (Yasuhiro Matsumoto)
+
+Win32: Added Makefile for Borland 5 to compile gvimext.dll. (Yasuhiro
+Matsumoto)
+
+==============================================================================
+BUG FIXES						*bug-fixes-6*
+
+When checking the command name for "gvim", "ex", etc. ignore case.  Required
+for systems where case is ignored in command names.
+
+Search pattern "[a-c-e]" also matched a 'd' and didn't match a '-'.
+
+When double-clicking in another window, wasn't recognized as double click,
+because topline is different.  Added set_mouse_topline().
+
+The BROKEN_LOCALE check was broken.  (Marcin Dalecki)
+
+When "t_Co" is set, the default colors remain the same, thus wrong.  Reset the
+colors after changing "t_Co". (Steve Wall)
+
+When exiting with ":wqall" the messages about writing files could overwrite
+each other and be lost forever.
+
+When starting Vim with an extremely long file name (around 1024 characters) it
+would crash.  Added a few checks to avoid buffer overflows.
+
+CTRL-E could get stuck in a file with very long lines.
+
+":au syntax<Tab>" expanded event names while it should expand groups starting
+with "syntax".
+
+When expanding a file name caused an error (e.g., for <amatch>) it was
+produced even when inside an "if 0".
+
+'cindent' formatted C comments differently from what the 'comments' option
+specified. (Steve Wall)
+
+Default for 'grepprg' didn't include the file name when only grepping in one
+file.  Now /dev/null has been added for Unix.
+
+Opening the option window twice caused trouble.  Now the cursor goes to the
+existing option window.
+
+":sview" and ":view" didn't set 'readonly' for an existing buffer.  Now do set
+'readonly', unless the buffer is also edited in another window.
+
+GTK GUI: When 'guioptions' excluded 'g', the more prompt caused the toolbar
+and menubar to disappear and resize the window (which clears the text).
+Now always grey-out the toplevel menus to avoid that the menubar changes size
+or disappears.
+
+When re-using the current buffer for a new buffer, buffer-local variables were
+not deleted.
+
+GUI: when 'scrolloff' is 0 dragging the mouse above the window didn't cause a
+down scroll.  Now pass on a mouse event with mouse_row set to -1.
+
+Win32: Console version didn't work on telnet, because of switching between two
+console screens.  Now use one console screen and save/restore the contents
+when needed.  (Craig Barkhouse)
+
+When reading a file the magic number for encryption was included in the file
+length. (Antonio Colombo)
+
+The quickfix window contained leading whitespace and NULs for multi-line
+messages. (David Harrison)
+
+When using cscope, redundant tags were removed.  This caused a numbering
+problem, because they were all listed.  Don't remove redundant cscope tags.
+(David Bustos).
+
+Cscope: Test for which matches are in the current buffer sometimes failed,
+causing a jump to another match than selected. (David Bustos)
+
+Win32: Buffer overflow when adding a charset name in a font.
+
+'titlestring' and 'iconstring' were evaluating an expression in the current
+context, which could be a user function, which is a problem for local
+variables vs global variables.
+
+Win32 GUI: Mapping <M-F> didn't work.  Now handle SHIFT and CTRL in
+_OnSysChar().
+
+Win32 GUI: (on no file), :vs<CR>:q<CR> left a trail of pixels down the middle.
+Could also happen for the ruler.  screen_puts() didn't clear the right char in
+ScreenLines[] for the bold trick.
+
+Win32: ":%!sort|uniq" didn't work, because the input file name touches the
+"|".  Insert a space before the "|".
+
+OS/2: Expanding wildcards included non-existing files.  Caused ":runtime" to
+fail, which caused syntax highlighting to fail.
+
+Pasting a register containing CTRL-R on the command line could cause an
+endless loop that can't be interrupted.  Now it can be stopped with CTRL-C.
+
+When 'verbose' is set, a message for file read/write could overwrite the
+previous message.
+When 'verbose' is set, the header from ":select" was put after the last
+message.  Now start a new line.
+
+The hit-enter prompt reacted to the response of the t_RV string, causing
+messages at startup to disappear.
+
+When t_Co was set to 1, colors were still used.  Now only use color when t_Co
+> 1.
+
+Listing functions with ":function" didn't quit when 'q' or ':' was typed at
+the more prompt.
+
+Use mkstemp() instead of mktemp() when it's available, avoids a warning for
+linking on FreeBSD.
+
+When doing Insert mode completion it's possible that b_sfname is NULL.  Don't
+give it to printf() for the "Scanning" message.
+
+":set runtimepath-=$VIMRUNTIME" didn't work, because expansion of wildcards
+was done after trying to remove the string.  Now for ":set opt+=val" and ":set
+opt-=val" the expansion of wildcards is done before adding or removing "val".
+
+Using CTRL-V with the "r" command with a blockwise Visual selection inserted a
+CTRL-V instead of getting a special character.
+
+Unix: Changed the order of libraries: Put -lXdmcp after -lX11 and -lSM -lICE
+after -lXdmcp.  Should fix link problem on HP-UX 10.20.
+
+Don't remove the last "-lm" from the link line.  Vim may link but fail later
+when the GUI starts.
+
+When the shell returns with an error when trying to expand wildcards, do
+include the pattern when the "EW_NOTFOUND" flag was set.
+When expanding wildcards with the shell fails, give a clear error message
+instead of just "1 returned".
+
+Selecting a Visual block, with the start partly on a Tab, deleting it leaves
+the cursor too far to the left.  Causes "s" to work in the wrong position.
+
+Pound sign in normal.c caused trouble on some compilers.  Use 0xA3 instead.
+
+Warning for changing a read-only file wasn't given when 'insertmode' was set.
+
+Win32: When 'shellxquote' is set to a double quote (e.g., using csh), ":!start
+notepad file" doesn't work.  Remove the double quotes added by 'shellxquote'
+when using ":!start". (Pavol Juhas)
+
+The "<f-args>" argument of ":command" didn't accept Tabs for white space.
+Also, don't add an empty argument when there are trailing blanks.
+
+":e test\\je" edited "test\je", but ":next test\\je" edited "testje".
+Backslashes were removed one time too many for ":next".
+
+VMS: "gf" didn't work properly.  Use vms_fixfilename() to translate the file
+name. (Zoltan Arpadffy)
+
+After ":hi Normal ctermbg=black ctermfg=white" and suspending Vim not all
+characters are redrawn with the right background.
+
+When doing "make test" without +eval or +windows feature, many tests failed.
+Now have test1 generate a script to copy the correct output, so that a test
+that doesn't work is skipped.
+
+On FreeBSD the Perl interface added "-lc" to the link command and Python added
+"-pthread".  These two don't work together, because the libc_r library should
+be used.  Removed "-lc" from Perl, it should not be needed.
+Also: Add "-pthread" to $LIBS, so that the checks for functions is done with
+libc_r.  Sigaltstack() appears to be missing from libc_r.
+
+The Syntax sub-menus were getting too long, reorganized them and added another
+level for some languages.
+
+Visual block "r"eplace didn't work well when a Tab is partly included.
+(Matthias Kramm)
+
+When yanking a Visual block, where some lines end halfway the block, putting
+the text somewhere else doesn't insert a block.  Padd with spaces for missing
+characters.  Added "y_width" to struct yankreg. (Matthias Kramm)
+
+If a substitute string has a multibyte character after a backslash only the
+first byte of it was skipped. (Muraoka Taro)
+
+Win32: Numeric keypad keys were missing from the builtin termcap entry.
+
+When a file was read-only ":wa!" didn't force it to be written. (Vince Negri)
+
+Amiga: A file name starting with a colon was considered absolute but it isn't.
+Amiga: ":pwd" added a slash when in the root of a drive.
+
+Don't let 'ttymouse' default to "dec" when compiled with dec mouse support.
+It breaks the gpm mouse (Linux console).
+
+The prototypes for the Perl interface didn't work for threaded Perl.  Added a
+sed command to remove the prototypes from proto/if_perl.pro and added them
+manually to if_perl.xs.
+
+When ":w!" resets the 'readonly' option the title and status lines were not
+updated.
+
+":args" showed the current file when the argument list was empty.  Made this
+work like Vi: display nothing.
+
+"99:<C-U>echo v:count" echoed "99" in Normal mode, but 0 in Visual mode.
+Don't set v:count when executing a stuffed command.
+
+Amiga: Got a requester for "home:" because it's in the default runtime path.
+Don't bring up a requester when searching for a file in 'path', sourcing the
+.vimrc file or using ":runtime".
+
+Win16 and Win32: Considered a file "\path\file" absolute.  Can cause the same
+file to appear as two different buffers.
+
+Win32: Renaming a file to an empty string crashed Vim.  Happened when using
+explorer.vim and hitting ESC at the rename prompt.
+
+Win32: strftime() crashed when called with a "-1" value for the time.
+
+Win32 with Borland compiler: mch_FullName() didn't work, caused tag file not
+to be found.
+
+Cscope sometimes jumped to the wrong tag. (David Bustos)
+
+OS/2: Could not find the tags file.  mch_expand_wildcards() added another
+slash to a directory name.
+
+When using ">>" the `] mark was not in the last column.
+
+When Vim was compiled without menu support, filetype.vim was still trying to
+source the menu.vim script. (Rafael Garcia-Suarez)
+
+":ptag" added an item to the tag stack.
+
+Win32 IME: "gr" didn't use IME mode.
+
+In the "vim --help" message the term "options" was used for arguments.  That's
+confusing, call them "arguments".
+
+When there are two windows, and a BufUnload autocommand for closing window #1
+closed window #2, Vim would crash.
+
+When there is a preview window and only one other window, ":q" wouldn't exit.
+
+In Insert mode, when cancelling a digraph with ESC, the '?' wasn't removed.
+
+On Unix glob(".*") returned "." and "..", on Windows it didn't.  On Windows
+glob("*") also returned files starting with a dot.  Made this work like Unix
+on all systems.
+
+Win32: Removed old code to open a console.  Vimrun is now used and works fine.
+
+Compute the room needed by the intro message accurately, so that it also fits
+on a 25 line console. (Craig Barkhouse)
+
+":ptnext" was broken.  Now remember the last tag used in the preview window
+separately from the tagstack.
+
+Didn't check for "-display" being the last argument. (Wichert Akkerman)
+
+GTK GUI: When starting "gvim" under some conditions there would be an X error.
+Don't replace the error handler when creating the xterm clipboard. (Wichert
+Akkerman)
+
+Adding a space after a help tag caused the tag not to be found.  E.g., ":he
+autoindent ".
+
+Was trying to expand a URL into a full path name.  On Windows this resulted in
+the current directory to be prepended to the URL.  Added vim_isAbsName() and
+vim_FullName() to avoid that various machine specific functions do it
+differently.
+
+":n *.c" ":cd .." ":n" didn't use the original directory of the file.  Vi only
+does it for the current file (looks like a bug).  Now remember the buffer used
+for the entry in the argument list and use it's name (adjusted when doing
+":cd"), unless it's deleted.
+
+When inserting a special key as its name ("<F8>" as four characters) after
+moving around in Insert mode, undo didn't work properly.
+
+Motif GUI: When using the right mouse button, for some people gvim froze for
+a couple of seconds (Motif 1.2?).  This doesn't happen when there is no Popup
+menu.  Solved by only creating a popup menu when 'mousemodel' is "popup" or
+"popup_setpos". (David Harrison)
+
+Motif: When adding many menu items, the "Help" menu disappeared but the
+menubar didn't wrap.  Now manually set the menubar height.
+
+When using <BS> in Insert mode to remove a line break, or using "J" to join
+lines, the cursor could end up halfway a multi-byte character. (Muraoka Taro)
+
+Removed defining SVR4 in configure.  It causes problems for some X header
+files and doesn't appear to be used anywhere.
+
+When 'wildignore' is used, 'ignorecase' for a tag match was not working.
+
+When 'wildignore' contains "*~" it was impossible to edit a file ending in a
+"~".  Now don't recognize a file ending in "~" as containing wildcards.
+
+Disabled the mouse code for OS/2.  It was not really used.
+
+":mksession" always used the full path name for a buffer, also when the short
+name could be used.
+":mkvimrc" and ":mksession" didn't save 'wildchar' and 'pastetoggle' in such a
+way that they would be restored.  Now use the key name if possible, this is
+portable.
+
+After recovering a file and abandoning it, an ":edit" command didn't give the
+ATTENTION prompt again.  Would be useful to be able to delete the file in an
+easy way.  Reset the BF_RECOVERED flag when unloading the buffer.
+
+histdel() could match or ignore case, depending on what happened before it.
+Now always match case.
+
+When a window size was specified when splitting a window, it would still get
+the size from 'winheight' or 'winwidth' if it's larger.
+
+When using "append" or "insert" inside a function definition, a line starting
+with "function" or "endfunction" caused confusion.  Now recognize the commands
+and skip lines until a ".".
+
+At the end of any function or sourced file need_wait_return could be reset,
+causing messages to disappear when redrawing.
+
+When in a while loop the line number for error messages stayed fixed.  Now the
+line number is remembered in the while loop.
+
+"cd c:/" didn't work on MS-DOS.  mch_isdir() removed a trailing slash.
+
+MS-Windows: getftime() didn't work when a directory had a trailing slash or
+backslash.  Didn't show the time in the explorer because of this.
+
+When doing wildcard completion, a directory "a/" sorted after "a-b".  Now
+recognize path separators when sorting files.
+
+Non-Unix systems: When editing "c:/dir/../file" and "c:/file" they were
+created as different buffers, although it's the same file.  Expand to a full
+file name also when an absolute name contains "..".
+
+"g&" didn't repeat the last substitute properly.
+
+When 'clipboard' was set to "unnamed", a "Y" command would not write to "0.
+Now make a copy of register 0 to the clipboard register.
+
+When the search pattern matches in many ways, it could not always be
+interrupted with a CTRL-C.  And CTRL-C would have to be hit once for every
+line when 'hlsearch' is on.
+When 'incsearch' is on and interrupting the search for a match, don't abandon
+the command line.
+
+When turning a directory name into a full path, e.g., with fnamemodify(),
+sometimes a slash was added.  Make this consistent: Don't add a slash.
+
+When a file name contains a "!", using it in a shell command will cause
+trouble: ":!cat %".  Escape the "!" to avoid that.  Escape it another time
+when 'shell' contains "sh".
+
+Completing a file name that has a tail that starts with a "~" didn't work:
+":e view/~<Tab>".
+
+Using a ":command" argument that contains < and > but not for a special
+argument was not skipped properly.
+
+The DOS install program: On Win2000 the check for a vim.exe or gvim.exe in
+$PATH didn't work, it always found it in the current directory.
+Rename the vim.exe in the current dir to avoid this. (Walter Briscoe)
+
+In the MS-DOS/Windows install program, use %VIM% instead of an absolute path,
+so that moving Vim requires only one change in the batch file.
+
+Mac: mch_FullName() changed the "fname" argument and didn't always initialize
+the buffer.
+
+MS-DOS: mch_FullName() didn't fix forward/backward slashes in an absolute file
+name.
+
+"echo expand("%:p:h")" with an empty file name removed one directory name on
+MS-DOS.  For Unix, when the file name is a directory, the directory name was
+removed.  Now make it consistent: "%:p" adds a path separator for all systems,
+but no path separator is added in other situations.
+
+Unix: When checking for a CTRL-C (could happen any time) and there is an X
+event (e.g., clipboard updated) and there is typeahead, Vim would hang until a
+character was typed.
+
+MS-DOS, MS-Windows and Amiga: expanding "$ENV/foo" when $ENV ends in a colon,
+had the slash removed.
+
+":he \^=" gave an error for using \_.  ":he ^=" didn't find tag :set^=.  Even
+"he :set^=" didn't find it.
+
+A tags file name "D:/tags" was used as file "tags" in "D:".  That doesn't work
+when the current path for D: isn't the root of the drive.
+
+Removed calls to XtInitializeWidgetClass(), they shouldn't be necessary.
+
+When using a dtterm or various other color terminals, and the Normal group has
+been set to use a different background color, the background wouldn't always
+be displayed with that color.  Added check for "ut" termcap entry: If it's
+missing, clearing the screen won't give us the current background color.  Need
+to draw each character instead.  Vim now also works when the "cl" (clear
+screen) termcap entry is missing.
+
+When repeating a "/" search command with a line offset, the "n" did use the
+offset but didn't make the motion linewise.  Made "d/pat/+2" and "dn" do the
+same.
+
+Win32: Trying to use ":tearoff" for a menu that doesn't exist caused a crash.
+
+OpenPTY() didn't work on Sequent.  Add a configure check for getpseudotty().
+
+C-indenting: Indented a line starting with ")" with the matching "(", but not
+a line starting with "x)" looks strange.  Also compute the indent for aligning
+with items inside the () and use the lowest indent.
+
+MS-DOS and Windows: ":n *.vim" also matched files ending in "~".
+Moved mch_expandpath() from os_win16.c and os_msdos.c to misc1.c, they are
+equal.
+
+Macintosh: (Dany St-Amant)
+- In Vi-compatible mode didn't read files with CR line separators.
+- Fixed a bug in the handling of Activate/Deactivate Event
+- Fixed a bug in gui_mch_dialog (using wrong pointer)
+
+Multibyte GDK XIM: While composing a multibyte-word, if user presses a
+mouse button, then the word is removed.  It should remain and composing end.
+(Sung-Hyun Nam)
+
+MS-DOS, MS-Windows and OS/2: When reading from stdin, automatic CR-LF
+conversion by the C library got in the way of detecting a "dos" 'fileformat'.
+
+When 'smartcase' is set, patterns with "\S" would also make 'ignorecase'
+reset.
+
+When clicking the mouse in a column larger than 222, it moved to the first
+column.  Can't encode a larger number in a character.  Now limit the number to
+222, don't jump back to the first column.
+
+GUI: In some versions CSI would cause trouble, either when typed directly or
+when part of a multi-byte sequence.
+
+When using multibyte characters in a ":normal" command, a trailing byte that
+is CSI or K_SPECIAL caused problems.
+
+Wildmenu didn't handle multi-byte characters.
+
+":sleep 10" could not be interrupted on Windows, while "gs" could.  Made them
+both work the same.
+
+Unix: When waiting for a character is interrupted by an X-windows event (e.g.,
+to obtain the contents of the selection), the wait time would not be honored.
+A message could be overwritten quickly.  Now compute the remaining waiting
+time.
+
+Windows: Completing "\\share\c$\S" inserted a backslash before the $ and then
+the name is invalid.  Don't insert the backslash.
+
+When doing an auto-write before ":make", IObuff was overwritten and the wrong
+text displayed later.
+
+On the Mac the directories "c:/tmp" and "c:/temp" were used in the defaults
+for 'backupdir' and 'directory', they don't exist.
+
+The check for a new file not to be on an MS-DOS filesystem created the file
+temporarily, which can be slow.  Don't do this if there is another check for
+the swap file being on an MS-DOS filesystem.
+
+Don't give the "Changing a readonly file" warning when reading from stdin.
+
+When using the "Save As" menu entry and not entering a file name, would get an
+error message for the trailing ":edit #".  Now only do that when the
+alternate file name was changed.
+
+When Vim owns the X11 selection and is being suspended, an application that
+tries to use the selection hangs.  When Vim continues it could no longer
+obtain the selection.  Now give up the selection when suspending.
+
+option.h and globals.h were included in some files, while they were already
+included in vim.h.  Moved the definition of EXTERN to vim.h to avoid doing it
+twice.
+
+When repeating an operator that used a search pattern and the search pattern
+contained characters that have a special meaning on the cmdline (e.g., CTRL-U)
+it didn't work.
+
+Fixed various problems with using K_SPECIAL (0x80) and CSI (0x9b) as a byte in
+a (multibyte) character.  For example, the "r" command could not be repeated.
+
+The DOS/Windows install program didn't always work from a directory with a
+long filename, because $VIM and the executable name would not have the same
+path.
+
+Multi-byte:
+- Using an any-but character range [^x] in a regexp didn't work for UTF-8.
+  (Muraoka Taro)
+- When backspacing over inserted characters in Replace mode multi-byte
+  characters were not handled correctly. (Muraoka Taro)
+- Search commands "#" and "*" didn't work with multibyte characters. (Muraoka
+  Taro)
+- Word completion in Insert mode didn't work with multibyte characters.
+  (Muraoka Taro)
+- Athena/Motif GUI: when 'linespace' is non-zero the cursor would be drawn too
+  wide (number of bytes instead of cell width).
+- When changing 'encoding' to "euc-jp" and inserting a character Vim would
+  crash.
+- For euc-jp characters positioning the cursor would sometimes be wrong.
+  Also, with two characters with 0x8e leading byte only the first one would be
+  displayed.
+- When using DYNAMIC_ICONV on Win32 conversion might fail because of using the
+  wrong error number. (Muraoka Taro)
+- Using Alt-x in the GUI while 'encoding' was set to "utf-8" didn't produce
+  the right character.
+- When using Visual block selection and only the left halve of a double-wide
+  character is selected, the highlighting continued to the end of the line.
+- Visual-block delete didn't work properly when deleting the right halve of a
+  double-wide character.
+- Overstrike mode for the cmdline replaced only the first byte of a multibyte
+  character.
+- The cursor in Replace mode (also in the cmdline) was to small on a
+  double-wide character.
+- When a multibyte character contained a 0x80 byte, it didn't work (was using
+  a CSI byte instead). (Muraoka Taro)
+- Wordwise selection with the mouse didn't work.
+- Yanking a modeless selection of multi-byte characters didn't work.
+- When 'selection' is "exclusive", selecting a word that ends in a multi-byte
+  character used wrong highlighting for the following character.
+
+Win32 with Make_mvc.mak: Didn't compile for debugging. (Craig Barkhouse)
+
+Win32 GUI: When "vimrun.exe" is used to execute an external command, don't
+give a message box with the return value, it was already printed by vimrun.
+Also avoid printing the return value of the shell when ":silent!" is used.
+
+Win32: selecting a lot of text and using the "find/replace" dialog caused a
+crash.
+
+X11 GUI: When typing a character with the 8th bit set and the Meta/Alt
+modifier, the modifier was removed without changing the character.
+
+Truncating a message to make it fit on the command line, using "..." for the
+middle, didn't always compute the space correctly.
+
+Could not imap <C-@>.  Now it works like <Nul>.
+
+VMS:
+- Fixed a few things for VAXC.  os_vms_fix.com had some strange CTRL-M
+  characters. (Zoltan Arpadffy and John W. Hamill)
+- Added VMS-specific defaults for the 'isfname' and 'isprint' options.
+  (Zoltan Arpadffy)
+- Removed os_vms_osdef.h, it's no longer used.
+
+The gzip plugin used a ":normal" command, this doesn't work when dropping a
+compressed file on Vim.
+
+In very rare situations a binary search for a tag would fail, because an
+uninitialized value happens to be half the size of the tag file. (Narendran)
+
+When using BufEnter and BufLeave autocommands to enable/disable a menu, it
+wasn't updated right away.
+
+When doing a replace with the "c"onfirm flag, the cursor was positioned after
+the ruler, instead of after the question.  With a long replacement string the
+screen could scroll up and cause a "more" prompt.  Now the message is
+truncated to make it fit.
+
+Motif: The autoconf check for the Xp library didn't work.
+
+When 'verbose' is set to list lines of a sourced file, defining a function
+would reset the counter used for the "more" prompt.
+
+In the Win32 find/replace dialog, a '/' character caused problems.  Escape it
+with a backslash.
+
+Starting a shell with ":sh" was different from starting a shell for CTRL-Z
+when suspending doesn't work.  They now work the same way.
+
+Jumping to a file mark while in a changed buffer gave a "mark not set" error.
+
+":execute histget("cmd")" causes an endless loop and crashed Vim.  Now catch
+all commands that cause too much recursiveness.
+
+Removed "Failed to open input method" error message, too many people got this
+when they didn't want to use a XIM.
+
+GUI: When compiled without the +windows feature, the scrollbar would start
+below line one.
+
+Removed the trick with redefining character class functions from regexp.c.
+
+Win32 GUI: Find dialog gives focus back to main window, when typing a
+character mouse pointer is blanked, it didn't reappear when moving it in the
+dialog window. (Vince Negri)
+
+When recording and typing a CTRL-C, no character was recorded.  When in Insert
+mode or cancelling half a command, playing back the recorded sequence wouldn't
+work.  Now record the CTRL-C.
+
+When the GUI was started, mouse codes for DEC and netterm were still checked
+for.
+
+GUI: When scrolling and 'writedelay' is non-zero, the character under the
+cursor was displayed in the wrong position (one line above/below with
+CTRL-E/CTRL-Y).
+
+A ":normal" command would reset the 'scrollbind' info.  Causes problems when
+using a ":normal" command in an autocommand for opening a file.
+
+Windows GUI: a point size with a dot, like "7.5", wasn't recognized. (Muraoka
+Taro)
+
+When 'scrollbind' wasn't set would still remember the current position,
+wasting time.
+
+GTK: Crash when 'shell' doesn't exist and doing":!ls".  Use _exit() instead of
+exit() when the child couldn't execute the shell.
+
+Multi-byte:
+- GUI with double-byte encoding: a mouse click in left halve of double-wide
+  character put the cursor in previous char.
+- Using double-byte encoding and 'selection' is "exclusive": "vey" and "^Vey"
+  included the character after the word.
+- When using a double-byte encoding and there is a lead byte at the end of the
+  line, the preceding line would be displayed.  "ga" also showed wrong info.
+- "gf" didn't include multi-byte characters before the cursor properly.
+  (Muraoka Taro)
+
+GUI: The cursor was sometimes not removed when scrolling.  Changed the policy
+from redrawing the cursor after each call to gui_write() to only update it at
+the end of update_screen() or when setting the cursor position.  Also only
+update the scrollbars at the end of update_screen(), that's the only place
+where the window text may have been scrolled.
+
+Formatting "/*<Tab>long text", produced "* <Tab>" in the next line.  Now
+remove the space before the Tab.
+Formatting "/*<Tab>  long text", produced "* <Tab> long text" in the next
+line.  Now keep the space after the Tab.
+
+In some places non-ASCII alphabetical characters were accepted, which could
+cause problems.  For example, ":X" (X being such a character).
+
+When a pattern matches the end of the line, the last character in the line was
+highlighted for 'hlsearch'.  That looks wrong for "/\%3c".  Now highlight the
+character just after the line.
+
+Motif: If a dialog was closed by clicking on the "X" of the window frame Vim
+would no longer respond.
+
+When using CTRL-X or CTRL-A on a number with many leading zeros, Vim would
+crash. (Matsumoto)
+
+When 'insertmode' is set, the mapping in mswin.vim for CTRL-V didn't work in
+Select mode.  Insert mode wasn't restarted after overwriting the text.
+Now allow nesting Insert mode with insert and change commands.  CTRL-O
+cwfoo<Esc> now also works.
+
+Clicking with the right mouse button in another window started Visual mode,
+but used the start position of the current window.  Caused ml_get errors when
+the line number was invalid.  Now stay in the same window.
+
+When 'selection' is "exclusive", "gv" sometimes selected one character fewer.
+
+When 'comments' contains more than one start/middle/end triplet, the optional
+flags could be mixed up.  Also didn't align the end with the middle part.
+
+Double-right-click in Visual mode didn't update the shown mode.
+
+When the Normal group has a font name, it was never used when starting up.
+Now use it when 'guifont' and 'guifontset' are empty.
+Setting a font name to a highlight group before the GUI was started didn't
+work.
+
+"make test" didn't use the name of the generated Vim executable.
+
+'cindent' problems:
+- Aligned with an "else" inside a do-while loop for a line below that loop.
+  (Meikel Brandmeyer)
+- A line before a function would be indented even when terminated with a
+  semicolon. (Meikel Brandmeyer)
+- 'cindent' gave too much indent to a line after a "};" that ends an array
+  init.
+- Support declaration lines ending in "," and "\".  (Meikel Brandmeyer)
+- A case statement inside a do-while loop was used for indenting a line after
+  the do-while loop. (Meikel Brandmeyer)
+- When skipping a string in a line with one double quote it could continue in
+  the previous line. (Meikel Brandmeyer)
+
+When 'list' is set, 'hlsearch' didn't highlight a match at the end of the
+line.  Now highlight the '$'.
+
+The Paste menu item in the menu bar, the popup menu and the toolbar were all
+different.  Now made them all equal to how it was done in mswin.vim.
+
+st_dev can be smaller than "unsigned".  The compiler may give an overflow
+warning.  Added a configure check for dev_t.
+
+Athena: closing a confirm() dialog killed Vim.
+
+Various typos in the documentation. (Matt Dunford)
+
+Python interface: The definition of _DEBUG could cause trouble, undefine it.
+The error message for not being able to load the shared library wasn't
+translated.  (Muraoka Taro)
+
+Mac: (Dany St-Amant and Axel Kielhorn)
+- Several fixes.
+- Vim was eating 80% of the CPU time.
+- The project os_mac.pbxproj didn't work,  Moved it to a subdirectory.
+- Made the menu priority work for the menubar.
+- Fixed a problem with dragging the scrollbar.
+- Cleaned up the various #ifdefs.
+
+Unix: When catching a deadly signal and we keep getting one use _exit() to
+exit in a quick and dirty way.
+
+Athena menu ordering didn't work correctly. (David Harrison)
+
+A ":make" or ":grep" command with a long argument could cause a crash.
+
+Doing ":new file" and using "Quit" for the ATTENTION dialog still opened a new
+window.
+
+GTK: When starting the GUI and there is an error in the .vimrc file, don't
+present the wait-return prompt, since the message was given in the terminal.
+
+When there was an error in a .vimrc file the terminal where gvim was started
+could be cleared.  Set msg_row in main.c before writing any messages.
+
+GTK and X11 GUI: When trying to read characters from the user (e.g. with
+input()) before the Vim window was opened caused Vim to hang when it was
+started from the desktop.
+
+OS/390 uses 31 bit pointers.  That broke some computations with MAX_COL.
+Reduce MAX_COL by one bit for OS/390. (Ralf Schandl)
+
+When defining a function and it already exists, Vim didn't say it existed
+until after typing it.  Now do this right away when typing it.
+
+The message remembered for displaying later (keep_msg) was sometimes pointing
+into a generic buffer, which might be changed by the time the message is
+displayed.  Now make a copy of the message.
+
+When using multi-byte characters in a menu and a trailing byte is a backslash,
+the menu would not be created correctly.  (Muraoka Taro)
+Using a multibyte character in the substitute string where a trail byte is a
+backslash didn't work.  (Muraoka Taro)
+
+When setting "t_Co" in a vimrc file, then setting it automatically from an
+xterm termresponse and then setting it again manually caused a crash.
+
+When getting the value of a string option that is not supported, the number
+zero was returned.  This breaks a check like "&enc == "asdf".  Now an empty
+string is returned for string options.
+
+Crashed when starting the GTK GUI while using 'notitle' in the vimrc, setting
+'title' in the gvimrc and starting the GUI with ":gui".  Closed the connection
+to the X server accidentally.
+
+Had to hit return after selecting an entry for ":ts".
+
+The message from ":cn" message was sometimes cleared.  Now display it after
+redrawing if it doesn't cause a scroll (truncated when necessary).
+
+hangulin.c didn't compile when the GUI was disabled.  Disable it when it won't
+work.
+
+When setting a termcap option like "t_CO", the value could be displayed as
+being for a normal key with a modifier, like "<M-=>".
+
+When expanding the argument list, entries which are a directory name did not
+get included.  This stopped "vim c:/" from opening the file explorer.
+
+":syn match sd "^" nextgroup=asdf" skipped the first column and matched the
+nextgroup in the second column.
+
+GUI: When 'lazyredraw' is set, 'showmatch' didn't work.  Required flushing
+the output.
+
+Don't define the <NetMouse> termcode in an xterm, reduces the problem when
+someone types <Esc> } in Insert mode.
+
+Made slash_adjust() work correctly for multi-byte characters. (Yasuhiro
+Matsumoto)
+Using a filename in Big5 encoding for autocommands didn't work (backslash in
+trailbyte).  (Yasuhiro Matsumoto)
+
+DOS and Windows: Expanding *.vim also matched file.vimfoo.  Expand path like
+Unix to avoid problems with Windows dir functions.  Merged the DOS and Win32
+functions.
+
+Win32: Gvimext could not edit more than a few files at once, the length of the
+argument was fixed.
+
+"ls -1 * | xargs vim" worked, but the input was in cooked mode.  Now switch to
+raw mode when needed.  Use dup() to copy the stderr file descriptor to stdin
+to make shell commands work.  No longer requires an external program to do
+this.
+
+When using ":filetype off", ftplugin and indent usage would be switched off at
+the same time.  Don't do this, setting 'filetype' manually can still use them.
+
+GUI: When writing a double-byte character, it could be split up in two calls
+to gui_write(), which doesn't work.  Now flush before the output buffer
+becomes full.
+
+When 'laststatus' is set and 'cmdheight' is two or bigger, the intro message
+would be written over the status line.
+The ":intro" command didn't work when there wasn't enough room.
+
+Configuring for Ruby failed with a recent version of Ruby. (Akinori Musha)
+
+Athena: When deleting the directory in which Vim was started, using the file
+browser made Vim exit.  Removed the use of XtAppError().
+
+When using autoconf 2.50, UNIX was not defined.  Moved the comment for "#undef
+UNIX" to a separate line.
+
+Win32: Disabled _OnWindowPosChanging() to make maximize work better.
+
+Win32: Compiling with VC 4.0 didn't work. (Walter Briscoe)
+
+Athena:
+- Finally fixed the problems with deleting a menu. (David Harrison)
+- Athena: When closing the confirm() dialog, worked like OK was pressed,
+  instead of Cancel.
+
+The file explorer didn't work in compatible mode, because of line
+continuation.
+
+Didn't give an error message for ":digraph a".
+
+When using Ex mode in the GUI and typing a special key, <BS> didn't delete it
+correctly.  Now display '?' for a special key.
+
+When an operator is pending, clicking in another window made it apply to that
+window, even though the line numbers could be beyond the end of the buffer.
+
+When a function call doesn't have a terminating ")" Vim could crash.
+
+Perl interface: could crash on exit with perl 5.6.1. (Anduin Withers)
+
+Using %P in 'errorformat' wasn't handled correctly. (Tomas Zellerin)
+
+Using a syntax cluster that includes itself made Vim crash.
+
+GUI: With 'ls' set to 2, dragging the status line all the way up, then making
+the Vim window smaller: Could not the drag status line anymore.
+
+"vim -c startinsert! file" placed cursor on last char of a line, instead of
+after it.  A ":set" command in the buffer menu set w_set_curswant.  Now don't
+do this when w_curswant is MAXCOL.
+
+Win32: When the gvim window was maximized and selecting another font, the
+window would no longer fill the screen.
+
+The line with 'pastetoggle' in ":options" didn't show the right value when it
+is a special key.  Hitting <CR> didn't work either.
+
+Formatting text, resulting in a % landing in the first line, repeated the % in
+the following lines, like it's the start of a comment.
+
+GTK: When adding a toolbar item while gvim is already running, it wasn't
+possible to use the tooltip.  Now it works by adding the tooltip first.
+
+The output of "g CTRL-G" mentioned "Char" but it's actually bytes.
+
+Searching for the end of a oneline region didn't work correctly when there is
+an offset for the highlighting.
+
+Syntax highlighting: When synchronizing on C-comments, //*/ was seen as the
+start of a comment.
+
+Win32: Without scrollbars present, the MS mouse scroll wheel didn't work.
+Also handle the scrollbars when they are not visible.
+
+Motif: When there is no right scrollbar, the bottom scrollbar would still
+leave room for it.  (Marcin Dalecki)
+
+When changing 'guicursor' and the value is invalid, some of the effects would
+still take place.  Now first check for errors and only make the new value
+effective when it's OK.
+
+Using "A" In Visual block mode, appending to lines that don't extend into the
+block, padding was wrong.
+
+When pasting a block of text, a character that occupies more than one screen
+column could be deleted and spaces inserted instead.  Now only do that with a
+tab.
+
+Fixed conversion of documentation to HTML using Perl. (Dan Sharp)
+
+Give an error message when a menu name starts with a dot.
+
+Avoid a hang when executing a shell from the GUI on HP-UX by pushing "ptem"
+even when sys/ptem.h isn't present.
+
+When creating the temp directory, make sure umask is 077, otherwise the
+directory is not accessible when it was set to 0177.
+
+Unix: When resizing the window and a redraw is a bit slow, could get a window
+resize event while redrawing, resulting in a messed up window.  Any input
+(e.g., a mouse click) would redraw.
+
+The "%B" item in the status line became zero in Insert mode (that's normal)
+for another than the current window.
+
+The menu entries to convert to xxd and back didn't work in Insert mode.
+
+When ":vglobal" didn't find a line where the pattern doesn't match, the error
+message would be the wrong way around.
+
+When ignoring a multi-line error message with "%-A", the continuation lines
+would be used anyway. (Servatius Brandt)
+
+"grx" on a double-wide character inserted "x", instead of replacing the
+character with "x ".  "gR" on <xx> ('display' set the "uhex") didn't replace
+at all.  When doing "gRxx" on a control character the first "x" would be
+inserted, breaking the alignment.
+
+Added "0)" to 'cinkeys', so that when typing a ) it is put in the same place
+as where "==" would put it.
+
+Win32: When maximized, adding/removing toolbar didn't resize the text area.
+
+When using <C-RightMouse> a count was discarded.
+
+When typing CTRL-V and <RightMouse> in the command line, would insert
+<LeftMouse>.
+
+Using "vis" or "vas" when 'selection' is exclusive didn't include the last
+character.
+
+When adding to an option like 'grepprg', leading space would be lost.  Don't
+expand environment variables when there is no comma separating the items.
+
+GUI: When using a bold-italic font, would still use the bold trick and
+underlining.
+
+Motif: The default button didn't work in dialogs, the first one was always
+used.  Had to give input focus to the default button.
+
+When using CTRL-T to jump within the same file, the '' mark wasn't set.
+
+Undo wasn't Vi compatible when using the 'c' flag for ":s".  Now it undoes the
+whole ":s" command instead of each confirmed replacement.
+
+The Buffers menu, when torn-off, disappeared when being refreshed.  Add a
+dummy item to avoid this.
+
+Removed calling msg_start() in main(), it should not be needed.
+
+vim_strpbrk() did not support multibyte characters. (Muraoka Taro)
+
+The Amiga version didn't compile, the code was too big for relative jumps.
+Moved a few files from ex_docmd.c to ex_cmds2.c
+
+When evaluating the "= register resulted in the "= register being changed, Vim
+would crash.
+
+When doing ":view file" and it fails, the current buffer was made read-only.
+
+Motif: For some people the separators in the toolbar disappeared when resizing
+the Vim window. (Marcin Dalecki)
+
+Win32 GUI: when setting 'lines' to a huge number, would not compute the
+available space correctly.  Was counting the menu height twice.
+
+Conversion of the docs to HTML didn't handle the line with the +quickfix tag
+correctly. (Antonio Colombo)
+
+Win32: fname_case() didn't handle multi-byte characters correctly. (Yasuhiro
+Matsumoto)
+
+The Cygwin version had trouble with fchdir().  Don't use that function for
+Cygwin.
+
+The generic check in scripts.vim for "conf" syntax was done before some checks
+in filetype.vim, resulting in "conf" syntax too often.
+
+Dos32: Typing lagged behind.  Would wait for one biostick when checking if a
+character is available.
+
+GTK: When setting 'columns' while starting up "gvim", would set the width of
+the terminal it was started in.
+
+When using ESC in Insert mode, an autoindent that wraps to the next line
+caused the cursor to move to the end of the line temporarily.  When the
+character before the cursor was a double-wide multi-byte character the cursor
+would be on the right halve, which causes problems with some terminals.
+
+Didn't handle multi-byte characters correctly when expanding a file name.
+(Yasuhiro Matsumoto)
+
+Win32 GUI: Errors generated before the GUI is decided to start were not
+reported.
+
+globpath() didn't reserve enough room for concatenated results. (Anduin
+Withers)
+
+When expanding an option that is very long already, don't do the expansion, it
+would be truncated to MAXPATHL. (Anduin Withers)
+
+When 'selection' is "exclusive", using "Fx" in Visual mode only moved until
+just after the character.
+
+When using IME on the console to enter a file name, the screen may scroll up.
+Redraw the screen then. (Yasuhiro Matsumoto)
+
+Motif: In the find/replace dialog the "Replace" button didn't work first time,
+second time it replaced all matches.  Removed the use of ":s///c".
+GTK: Similar problems with the find/replace dialog, moved the code to a common
+function.
+
+X11: Use shared GC's for text. (Marcin Dalecki)
+
+"]i" found the match under the cursor, instead of the first one below it.
+Same for "]I", "] CTRL-I", "]d", "]D" and "] CTRL-D".
+
+Win16: When maximized and the font is changed, don't change the window size.
+(Vince Negri)
+
+When 'lbr' is set, deleting a block of text could leave the cursor in the
+wrong position.
+
+Win32: When opening a file with the "Edit with Vim" popup menu entry,
+wildcards would cause trouble.  Added the "--literal" argument to avoid
+expanding file names.
+
+When using "gv", it didn't restore that "$" was used in Visual block mode.
+
+Win32 GUI: While waiting for a shell command to finish, the window wasn't
+redrawn at all. (Yasuhiro Matsumoto)
+
+Syntax highlighting: A match that continues on a next line because of a
+contained region didn't end when that region ended.
+
+The ":s" command didn't allow flags like 'e' and 'i' right after it.
+
+When using ":s" to split a line, marks were moved to the next line.  Vi keeps
+them in the first line.
+
+When using ":n" ":rew", the previous context mark was at the top of the file,
+while Vi puts it in the same place as the cursor.  Made it Vi compatible.
+
+Fixed Vi incompatibility: Text was not put in register 1 when using "c" and
+"d" with a motion character, when deleting within one line with one of the
+commands: % ( ) `<character> / ? N n { }
+
+Win32 GUI: The tooltip for tear-off items remained when the tear-off item was
+no longer selected.
+
+GUI: When typing ":" at the more prompt, would return to Normal mode and not
+redraw the screen.
+
+When starting Vim with an argument "-c g/at/p" the printed lines would
+overwrite each other.
+
+BeOS: Didn't compile.  Configure didn't add the os_beos files, the QNX check
+removed them.  Various changes to os_beos.cc. (Joshua Haberman)
+Removed the check for the hardware platform, the BeBox has not been produced
+for a long time now.
+
+Win32 GUI: don't use a message box when the shell returns an error code,
+display the message in the Vim window.
+
+Make_mvc.mak always included "/debug" for linking.  "GUI=no" argument didn't
+work.  Use "DEBUG=yes" instead of "DEBUG=1" to make it consistent. (Dan Sharp)
+
+When a line in the tags file ended in ;" (no TAB following) the command would
+not be recognized as a search command.
+
+X11: The inputMethod resource never worked.  Don't use the "none" input method
+for SGI, it apparently makes the first character in Input method dropped.
+
+Fixed incorrect tests in os_mac.h. (Axel Kielhorn)
+
+Win32 console: When the console where Vim runs in is closed, Vim could hang in
+trying to restore the window icon. (Yasuhiro Matsumoto)
+
+When using ":3call func()" or ":3,3call func() the line number was ignored.
+
+When 'showbreak' and 'linebreak' were both set, Visual highlighting sometimes
+continued until the end of the line.
+
+GTK GUI: Tearoff items were added even when 'guioptions' didn't contain 't'
+when starting up.
+
+MS-Windows: When the current directory includes a "~", searching files with
+"gf" or ":find" didn't work.  A "$" in the directory had the same problem.
+Added mch_has_exp_wildcard() functions.
+
+When reducing the Vim window height while starting up, would get an
+out-of-memory error message.
+
+When editing a very long search pattern, 'incsearch' caused the redraw of the
+command line to fail.
+
+Motif GUI: On some systems the "Help" menu would not be on the far right, as
+it should be.  On some other systems (esp. IRIX) the command line would not
+completely show.  Solution is to only resize the menubar for Lesstif.
+
+Using "%" in a line that contains "\\" twice didn't take care of the quotes
+properly.  Now make a difference between \" and \\".
+
+For non-Unix systems a dummy file is created when finding a swap name to
+detect a 8.3 filesystem.  When there is an existing swap file, would get a
+warning for the file being created outside of Vim.  Also, when closing the Vim
+window the file would remain.
+
+Motif: The menu height was always computed, using a "-menuheight" argument
+was setting the room for the command line.  Now make clear the argument is not
+supported.
+
+For some (EBCDIC) systems, POUND was equal to '#'.  Added an #if for that to
+avoid a duplicate case in a switch.
+
+The GUI may have problems when forking.  Always call _exit() instead of exit()
+in the parent, the child will call exit().
+
+Win32 GUI: Accented characters were often wrong in dialogs and tearoff menus.
+Now use CP_ACP instead of CP_OEMCP. (Vince Negri)
+
+When displaying text with syntax highlighting causes an error (e.g., running
+out of stack) the syntax highlighting is disabled to avoid further messages.
+
+When a command in a .vimrc or .gvimrc causes an ATTENTION prompt, and Vim was
+started from the desktop (no place to display messages) it would hang.  Now
+open the GUI window early to be able to display the messages and pop up the
+dialog.
+
+"r<CR>" on a multi-byte character deleted only the first byte of the
+character.  "3r<CR>" deleted three bytes instead of three characters.
+
+When interrupting reading a file, Vi considers the buffer modified.  Added the
+'i' flag in 'cpoptions' flag for this (we don't want it modified to be able to
+do ":q").
+
+When using an item in 'guicursor' that starts with a colon, Vim would get
+stuck or crash.
+
+When putting a file mark in a help file and later jumping back to it, the
+options would not be set.  Extended the modeline in all help files to make
+this work better.
+
+When a modeline contained "::" the local option values would be printed.  Now
+ignore it.
+
+Some help files did not use a 8.3 names, which causes problems when using
+MS-DOS unzip.  Renamed "multibyte.txt" to "mbyte.txt", "rightleft.txt" to
+"rileft.txt", "tagsearch.txt" to "tagsrch.txt", "os_riscos.txt" to
+"os_risc.txt".
+
+When Visual mode is blockwise, using "iw" or "aw" made it characterwise.  That
+doesn't seem right, only do this when in linewise mode.  But then do it
+always, not only when start and end of Visual mode are equal.
+
+When using "viw" on a single-letter word and 'selection' is exclusive, would
+not include the word.
+
+When formatting text from Insert mode, using CTRL-O, could mess up undo
+information.
+
+While writing a file (also for the backup file) there was no check for an
+interrupt (hitting CTRL-C).  Vim could hang when writing a large file over a
+slow network, and moving the mouse didn't make it appear (when 'mousehide' is
+set) and the screen wasn't updated in the GUI.  Also allow interrupting when
+syncing the swap file, it can take a long time.
+
+When using ":mksession" while there is help window, it would later be restored
+to the right file but not marked as a help buffer.  ":help" would then open
+another window.  Now use the value "help" for 'buftype' to mark a help buffer.
+
+The session file contained absolute path names in option values, that doesn't
+work when the home directory depends on the situation.  Replace the home
+directory with ~/ when possible.
+
+When using 'showbreak' a TAB just after the shown break would not be counted
+correctly, the cursor would be positioned wrong.
+
+With 'showbreak' set to "--->" or "------->" and 'sts' set to 4, inserting
+tabs did not work right.  Could cause a crash.  Backspacing was also wrong,
+could get stuck at a line break.
+
+Win32: crashed when tearing off a menu with over 300 items.
+
+GUI: A menu or toolbar item would appear when only a tooltip was defined for
+it.
+
+When 'scrolloff' is non-zero and "$" is in 'cpoptions', using "s" while the
+last line of the file is the first line on screen, the text wasn't displayed.
+
+When running "autoconf", delete the configure cache to force starting cleanly
+when configure is run again.
+
+When changing the Normal colors for cterm, the value of 'background' was
+changed even when the GUI was used.
+
+The warning for a missing vimrun.exe was always given on startup, but some
+people just editing a file don't need to be bothered by it.  Only show it when
+vimrun would be used.
+
+When using "%" in a multibyte text it could get confused by trailbytes that
+match. (Muraoka Taro)
+
+Termcap entry for RiscOS was wrong, using 7 and 8 in octal codes.
+
+Athena: The title of a dialog window and the file selector window were not
+set. (David Harrison)
+
+The "htmlLink" highlight group specified colors, which gives problems when
+using a color scheme.  Added the "Underlined" highlight group for this.
+
+After using ":insert" or ":change" the '[ mark would be one line too low.
+
+When looking for the file name after a match with 'include' one character was
+skipped.  Same for 'define'.
+
+Win32 and DJGPP: When editing a file with a short name in a directory, and
+editing the same file but using the long name, would end up with two buffers
+on the same file.
+
+"gf" on a filename that starts with "../" only worked when the file being
+edited is in the current directory.  An include file search didn't work
+properly for files starting with "../" or ".".  Now search both relative to
+the file and to the current directory.
+
+When 'printheader', 'titlestring', 'iconstring', 'rulerformat' or 'statusline'
+contained "%{" but no following "}" memory was corrupted and a crash could
+happen.
+
+":0append" and then inserting two lines did not redraw the blank lines that
+were scrolled back down.
+
+When using insert mode completion in a narrow window, the message caused a
+scroll up.  Now shorten the message if it doesn't fit and avoid writing the
+ruler over the message.
+
+XIM still didn't work correctly on some systems, especially SGI/IRIX.  Added
+the 'imdisable' option, which is set by default for that system.
+
+Patch 6.0aw.008
+Problem:    When the first character of a file name is over 127, the Buffers
+	    menu entry would get a negative priority and cause problems.
+Solution:   Reduce the multiplier for the first character when computing
+	    the hash value for a Buffers menu entry.
+Files:	    runtime/menu.vim
+
+Patch 6.0aw.010
+Problem:    Win32: ":browse edit dir/dir" didn't work. (Vikas)
+Solution:   Change slashes to backslashes in the directory passed to the file
+	    browser.
+Files:	    src/gui_w48.c
+
+Athena file browser: On some systems wcstombs() can't be used to get the
+length of a multi-byte string.  Use the maximum length then. (Yasuhiro
+Matsumoto)
+
+Patch 6.0ax.001
+Problem:    When 'patchmode' is set, appending to a file gives an empty
+	    original file. (Ed Ralston)
+Solution:   Also make a backup copy when appending and 'patchmode' is set.
+Files:	    src/fileio.c
+
+Patch 6.0ax.002
+Problem:    When 'patchmode' is set, appending to a compressed file gives an
+	    uncompressed original file. (Ed Ralston)
+Solution:   Create the original file before decompressing.
+Files:	    runtime/plugin/gzip.vim
+
+Patch 6.0ax.005
+Problem:    Athena file selector keeps the title of the first invocation.
+Solution:   Set the title each time the file selector is opened. (David
+	    Harrison)
+Files:	    src/gui_at_fs.c
+
+Patch 6.0ax.007
+Problem:    When using GPM (mouse driver in a Linux console) a double click is
+	    interpreted as a scroll wheel click.
+Solution:   Check if GPM is being used when deciding if a mouse event is for
+	    the scroll wheel.
+Files:	    src/term.c
+
+Patch 6.0ax.010
+Problem:    The Edit.Save menu and the Save toolbar button didn't work when
+	    the buffer has no file name.
+Solution:   Use a file browser to ask for a file name.  Also fix the toolbar
+	    Find item in Visual mode.
+Files:	    runtime/menu.vim
+
+Patch 6.0ax.012
+Problem:    When 'cpoptions' contains "$", breaking a line for 'textwidth'
+	    doesn't redraw properly. (Stefan Schulze)
+Solution:   Remove the dollar before breaking the line.
+Files:	    src/edit.c
+
+Patch 6.0ax.014
+Problem:    Win32: On Windows 98 ":make -f file" doesn't work when 'shell' is
+	    "command.com" and 'makeprg' is "nmake".  The environment isn't
+	    passed on to "nmake".
+Solution:   Also use vimrun.exe when redirecting the output of a command.
+Files:	    src/os_win32.c
+
+Patch 6.0ax.016
+Problem:    The version number was reported wrong in the intro screen.
+Solution:   Check for a version number with two additional letters.
+Files:	    src/version.c
+
+Patch 6.0ax.019
+Problem:    When scrolling a window with folds upwards, switching to another
+	    vertically split window and back may not update the scrollbar.
+Solution:   Limit w_botline to the number of lines in the buffer plus one.
+Files:	    src/move.c
+
+
+==============================================================================
+VERSION 6.1						*version-6.1*
+
+This section is about improvements made between version 6.0 and 6.1.
+
+This is a bug-fix release, there are not really any new features.
+
+
+Changed							*changed-6.1*
+-------
+
+'iminsert' and 'imsearch' are no longer set as a side effect of defining a
+language-mapping using ":lmap".
+
+
+Added							*added-6.1*
+-----
+
+Syntax files:
+ampl		AMPL (David Krief)
+ant		Ant (Johannes Zellner)
+baan		Baan (Her van de Vliert)
+cs		C# (Johannes Zellner)
+lifelines	Lifelines (Patrick Texier)
+lscript		LotusScript (Taryn East)
+moo		MOO (Timo Frenay)
+nsis		NSIS (Alex Jakushev)
+ppd		Postscript Printer Description (Bjoern Jacke)
+rpl		RPL/2 (Joel Bertrand)
+scilab		Scilab (Benoit Hamelin)
+splint		Splint (Ralf Wildenhues)
+sqlj		SQLJ (Andreas Fischbach)
+wvdial		WvDial (Prahlad Vaidyanathan)
+xf86conf	XFree86 config (Nikolai Weibull)
+xmodmap		Xmodmap (Nikolai Weibull)
+xslt		Xslt (Johannes Zellner)
+monk		Monk (Mike Litherland)
+xsd		Xsd (Johannes Zellner)
+cdl		CDL (Raul Segura Acevedo)
+sendpr		Send-pr (Hendrik Scholz)
+
+Added indent file for Scheme. (Dorai Sitaram)
+Added indent file for Prolog. (Kontra Gergely)
+Added indent file for Povray (David Necas)
+Added indent file for IDL (Aleksandar Jelenak)
+Added C# indent and ftplugin scripts.
+
+Added Ukrainian menu translations. (Bohdan Vlasyuk)
+Added ASCII version of the Czech menus. (Jiri Brezina)
+
+Added Simplified Chinese translation of the tutor. (Mendel L Chan)
+
+Added Russian keymap for yawerty keyboard.
+
+Added an explanation of using the vimrc file in the tutor.
+Changed tutor.vim to get the right encoding for the Taiwainese tutor.
+
+Added Russian tutor. (Andrey Kiselev)
+Added Polish tutor. (Mikolaj Machowski)
+
+Added darkblue color scheme. (Bohdan Vlasyuk)
+
+When packing the dos language archive automatically generate the .mo files
+that are required.
+
+Improved NSIS script to support NSIS 180.  Added icons for the
+enabled/disabled status. (Mirek Pruchnik)
+
+cp1250 version of the Slovak message translations.
+
+Compiler plugins for IRIX compilers. (David Harrison)
+
+
+Fixed							*fixed-6.1*
+-----
+
+The license text was updated to make the meaning clearer and make it
+compatible with the GNU GPL.  Otherwise distributors have a problem when
+linking Vim with a GPL'ed library.
+
+When installing the "less.sh" script it was not made executable. (Chuck Berg)
+
+Win32: The "9" key on the numpad wasn't working. (Julian Kinraid)
+
+The NSIS install script didn't work with NSIS 1.80 or later.  Also add
+Vim-specific icons. (Pruchnik)
+
+The script for conversion to HTML contained an "if" in the wrong place.
+(Michael Geddes)
+
+Allow using ":ascii" in the sandbox, it's harmless.
+
+Removed creat() from osdef2.h.in, it wasn't used and may cause a problem when
+it's redefined to creat64().
+
+The text files in the VisVim directory were in "dos" format.  This caused
+problems when applying a patch.  Now keep them in "unix" format and convert
+them to "dos" format only for the PC archives.
+
+Add ruby files to the dos source archive, they can be used by Make_mvc.mak.
+(Mirek Pruchnik)
+
+"cp -f" doesn't work on all systems.  Change "cp -f" in the Makefile to "rm
+-f" and "cp".
+
+Didn't compile on a Compaq Tandem Himalaya OSS. (Michael A. Benzinger)
+
+The GTK file selection dialog didn't include the "Create Dir", "Delete File"
+and "Rename File" buttons.
+
+When doing ":browse source" the dialog has the title "Run Macro".  Better
+would be "Source Vim script". (Yegappan Lakshmanan)
+
+Win32: Don't use the printer font as default for the font dialog.
+
+"make doslang" didn't work when configure didn't run (yet).  Set $MAKEMO to
+"yes". (Mirek Pruchnik)
+
+The ToolBar TagJump item used "g]", which prompts for a selection even when
+there is only one matching tag.  Use "g<C-]>" instead.
+
+The ming makefile for message translations didn't have the right list of
+files.
+
+The MS-Windows 3.1 version complains about LIBINTL.DLL not found.  Compile
+this version without message translations.
+
+The Borland 5 makefile contained a check for Ruby which is no longer needed.
+The URLs for the TCL library was outdated. (Dan Sharp)
+
+The eviso.ps file was missing from the DOS runtime archive, it's needed for
+printing PostScript in the 32bit DOS version.
+
+In menu files ":scriptencoding" was used in a wrong way after patch 6.1a.032
+Now use ":scriptencoding" in the file where the translations are given.  Do
+the same for all menus in latin1 encoding.
+
+Included a lot of fixes for the Macintosh, mostly to make it work with Carbon.
+(Dany StAmant, Axel Kielhorn, Benji Fisher)
+
+Improved the vimtutor shell script to use $TMPDIR when it exists, and delete
+the copied file when exiting in an abnormal way. (Max Ischenko)
+
+When "iconv.dll" can't be found, try using "libiconv.dll".
+
+When encryption is used, filtering with a shell command wasn't possible.
+
+DJGPP: ":cd c:" always failed, can't get permissions for "c:".
+Win32: ":cd c:/" failed if the previous current directory on c: had become
+invalid.
+
+DJGPP: Shift-Del and Del both produce \316\123.  Default mapping for Del is
+wrong.  Disabled it.
+
+Dependencies on header files in MingW makefile was wrong.
+
+Win32: Don't use ACL stuff for MSVC 4.2, it's not supported. (Walter Briscoe)
+
+Win32 with Borland: bcc.cfg was caching the value for $(BOR), but providing a
+different argument to make didn't regenerate it.
+
+Win32 with MSVC: Make_ivc.mak generates a new if_ole.h in a different
+directory, the if_ole.h in the src directory may be used instead.  Delete the
+distributed file.
+
+When a window is vertically split and then ":ball" is used, the window layout
+is messed up, can cause a crash. (Muraoka Taro)
+
+When 'insertmode' is set, using File/New menu and then double clicking, "i" is
+soon inserted. (Merlin Hansen)
+
+When Select mode is active and using the Buffers menu to switch to another
+buffer, an old selection comes back.  Reset VIsual_reselect for a ":buffer"
+command.
+
+When Select mode is active and 'insertmode' is set, using the Buffers menu to
+switch to another buffer, did not return to Insert mode.  Make sure
+"restart_edit" is set.
+
+When double clicking on the first character of a word while 'selection' is
+"exclusive" didn't select that word.
+
+
+Patch 6.0.001
+Problem:    Loading the sh.vim syntax file causes error messages . (Corinna
+	    Vinschen)
+Solution:   Add an "if". (Charles Campbell)
+Files:	    runtime/syntax/sh.vim
+
+Patch 6.0.002
+Problem:    Using a '@' item in 'viminfo' doesn't work. (Marko Leipert)
+Solution:   Add '@' to the list of accepted items.
+Files:	    src/option.c
+
+Patch 6.0.003
+Problem:    The configure check for ACLs on AIX doesn't work.
+Solution:   Fix the test program so that it compiles. (Tomas Ogren)
+Files:	    src/configure.in, src/auto/configure
+
+Patch 6.0.004
+Problem:    The find/replace dialog doesn't reuse a previous argument
+	    properly.
+Solution:   After removing a "\V" terminate the string. (Zwane Mwaikambo)
+Files:	    src/gui.c
+
+Patch 6.0.005
+Problem:    In Insert mode, "CTRL-O :ls" has a delay before redrawing.
+Solution:   Don't delay just after wait_return() was called.  Added the
+	    did_wait_return flag.
+Files:	    src/globals.h, src/message.c, src/normal.c, src/screen.c
+
+Patch 6.0.006
+Problem:    With a vertical split, 'number' set and 'scrolloff' non-zero,
+	    making the window width very small causes a crash. (Niklas
+	    Lindstrom)
+Solution:   Check for a zero width.
+Files:	    src/move.c
+
+Patch 6.0.007
+Problem:    When setting 'filetype' while there is no FileType autocommand, a
+	    following ":setfiletype" would set 'filetype' again. (Kobus
+	    Retief)
+Solution:   Set did_filetype always when 'filetype' has been set.
+Files:	    src/option.c
+
+Patch 6.0.008
+Problem:    'imdisable' is missing from the options window. (Michael Naumann)
+Solution:   Add an entry for it.
+Files:	    runtime/optwin.vim
+
+Patch 6.0.009
+Problem:    Nextstep doesn't have S_ISBLK. (John Beppu)
+Solution:   Define S_ISBLK using S_IFBLK.
+Files:	    src/os_unix.h
+
+Patch 6.0.010
+Problem:    Using "gf" on a file name starting with "./" or "../" in a buffer
+	    without a name causes a crash. (Roy Lewis)
+Solution:   Check for a NULL file name.
+Files:	    src/misc2.c
+
+Patch 6.0.011
+Problem:    Python: After replacing or deleting lines get an ml_get error.
+	    (Leo Lipelis)
+Solution:   Adjust the cursor position for deleted or added lines.
+Files:	    src/if_python.c
+
+Patch 6.0.012
+Problem:    Polish translations contain printf format errors, this can result
+	    in a crash when using one of them.
+Solution:   Fix for translated messages. (Michal Politowski)
+Files:	    src/po/pl.po
+
+Patch 6.0.013
+Problem:    Using ":silent! cmd" still gives some error messages, like for an
+	    invalid range. (Salman Halim)
+Solution:   Reset emsg_silent after calling emsg() in do_one_cmd().
+Files:	    src/ex_docmd.c
+
+Patch 6.0.014
+Problem:    When 'modifiable' is off and 'virtualedit' is "all", "rx" on a TAB
+	    still changes the buffer. (Muraoka Taro)
+Solution:   Check if saving the line for undo fails.
+Files:	    src/normal.c
+
+Patch 6.0.015
+Problem:    When 'cpoptions' includes "S" and "filetype plugin on" has been
+	    used, can get an error for deleting the b:did_ftplugin variable.
+	    (Ralph Henderson)
+Solution:   Only delete the variable when it exists.
+Files:	    runtime/ftplugin.vim
+
+Patch 6.0.016
+Problem:    bufnr(), bufname() and bufwinnr() don't find unlisted buffers when
+	    the argument is a string. (Hari Krishna Dara)
+	    Also for setbufvar() and getbufvar().
+Solution:   Also find unlisted buffers.
+Files:	    src/eval.c
+
+Patch 6.0.017
+Problem:    When 'ttybuiltin' is set and a builtin termcap entry defines t_Co
+	    and the external one doesn't, it gets reset to empty. (David
+	    Harrison)
+Solution:   Only set t_Co when it wasn't set yet.
+Files:	    src/term.c
+
+Patch 6.0.018
+Problem:    Initializing 'encoding' may cause a crash when setlocale() is not
+	    used. (Dany St-Amant)
+Solution:   Check for a NULL pointer.
+Files:	    src/mbyte.c
+
+Patch 6.0.019
+Problem:    Converting a string with multi-byte characters to a printable
+	    string, e.g., with strtrans(), may cause a crash. (Tomas Zellerin)
+Solution:   Correctly compute the length of the result in transstr().
+Files:	    src/charset.c
+
+Patch 6.0.020
+Problem:    When obtaining the value of a global variable internally, could
+	    get the function-local value instead.  Applies to using <Leader>
+	    and <LocalLeader> and resetting highlighting in a function.
+Solution:   Prepend "g:" to the variable name. (Aric Blumer)
+Files:	    src/syntax.c, src/term.c
+
+Patch 6.0.021
+Problem:    The 'cscopepathcomp' option didn't work.
+Solution:   Change USE_CSCOPE to FEAT_CSCOPE. (Mark Feng)
+Files:	    src/option.c
+
+Patch 6.0.022
+Problem:    When using the 'langmap' option, the second character of a command
+	    starting with "g" isn't adjusted.
+Solution:   Apply 'langmap' to the second character. (Alex Kapranoff)
+Files:	    src/normal.c
+
+Patch 6.0.023
+Problem:    Loading the lhaskell syntax doesn't work. (Thore B. Karlsen)
+Solution:   Use ":runtime" instead of "source" to load haskell.vim.
+Files:	    runtime/syntax/lhaskell.vim
+
+Patch 6.0.024
+Problem:    Using "CTRL-V u 9900" in Insert mode may cause a crash. (Noah
+	    Levitt)
+Solution:   Don't insert a NUL byte in the text, use a newline.
+Files:	    src/misc1.c
+
+Patch 6.0.025
+Problem:    The pattern "\vx(.|$)" doesn't match "x" at the end of a line.
+	    (Preben Peppe Guldberg)
+Solution:   Always see a "$" as end-of-line after "\v".  Do the same for "^".
+Files:	    src/regexp.c
+
+Patch 6.0.026
+Problem:    GTK: When using arrow keys to navigate through the menus, the
+	    separators are selected.
+Solution:   Set the separators "insensitive". (Pavel Kankovsky)
+Files:	    src/gui_gtk.c, src/gui_gtk_x11.c
+
+Patch 6.0.027
+Problem:    VMS: Printing doesn't work, the file is deleted too quickly.
+	    No longer need the VMS specific printing menu.
+	    gethostname() is not available with VAXC.
+	    The makefile was lacking selection of the tiny-huge feature set.
+Solution:   Adjust the 'printexpr' option default.  Fix the other problems and
+	    update the documentation.  (Zoltan Arpadffy)
+Files:	    runtime/doc/os_vms.txt, runtime/menu.vim, src/INSTALLvms.txt,
+	    src/Make_vms.mms, src/option.c, src/os_unix.c, src/os_vms_conf.h
+
+Patch 6.0.028
+Problem:    Can't compile without +virtualedit and with +visualextra. (Geza
+	    Lakner)
+Solution:   Add an #ifdef for +virtualedit.
+Files:	    src/ops.c
+
+Patch 6.0.029
+Problem:    When making a change in line 1, then in line 2 and then deleting
+	    line 1, undo info could be wrong.  Only when the changes are undone
+	    at once. (Gerhard Hochholzer)
+Solution:   When not saving a line for undo because it was already done
+	    before, remember for which entry the last line must be computed.
+	    Added ue_getbot_entry pointer for this.  When the number of lines
+	    changes, adjust the position of newer undo entries.
+Files:	    src/structs.h, src/undo.c
+
+Patch 6.0.030
+Problem:    Using ":source! file" doesn't work inside a loop or after
+	    ":argdo". (Pavol Juhas)
+Solution:   Execute the commands in the file right away, do not let the main
+	    loop do it.
+Files:	    src/ex_cmds2.c, src/ex_docmd.c, src/getchar.c, src/globals.h,
+	    src/proto/ex_docmd.pro, src/proto/getchar.pro
+
+Patch 6.0.031
+Problem:    Nextstep doesn't have setenv() or putenv().  (John Beppu)
+Solution:   Move putenv() from pty.c to misc2.c
+Files:	    src/misc2.c, src/pty.c
+
+Patch 6.0.032
+Problem:    When changing a setting that affects all folds, they are not
+	    displayed immediately.
+Solution:   Set the redraw flag in foldUpdateAll().
+Files:	    src/fold.c
+
+Patch 6.0.033
+Problem:    Using 'wildmenu' on MS-Windows, file names that include a space
+	    are only displayed starting with that space. (Xie Yuheng)
+Solution:   Don't recognize a backslash before a space as a path separator.
+Files:	    src/screen.c
+
+Patch 6.0.034
+Problem:    Calling searchpair() with three arguments could result in a crash
+	    or strange error message. (Kalle Bjorklid)
+Solution:   Don't use the fifth argument when there is no fourth argument.
+Files:	    src/eval.c
+
+Patch 6.0.035
+Problem:    The menu item Edit/Global_Settings/Toggle_Toolbar doesn't work
+	    when 'ignorecase' is set. (Allen Castaban)
+Solution:   Always match case when checking if a flag is already present in
+	    'guioptions'.
+Files:	    runtime/menu.vim
+
+Patch 6.0.036
+Problem:    OS/2, MS-DOS and MS-Windows: Using a path that starts with a
+	    slash in 'tags' doesn't work as expected. (Mathias Koehrer)
+Solution:   Only use the drive, not the whole path to the current directory.
+	    Also make it work for "c:dir/file".
+Files:	    src/misc2.c
+
+Patch 6.0.037
+Problem:    When the user has set "did_install_syntax_menu" to avoid the
+	    default Syntax menu it still appears. (Virgilio)
+Solution:   Don't add the three default items when "did_install_syntax_menu"
+	    is set.
+Files:	    runtime/menu.vim
+
+Patch 6.0.038
+Problem:    When 'selection' is "exclusive", deleting a block of text at the
+	    end of a line can leave the cursor beyond the end of the line.
+Solution:   Correct the cursor position.
+Files:	    src/ops.c
+
+Patch 6.0.039
+Problem:    "gP" leaves the cursor in the wrong position when 'virtualedit' is
+	    used.  Using "c" in blockwise Visual mode leaves the cursor in a
+	    strange position.
+Solution:   For "gP" reset the "coladd" field for the '] mark.  For "c" leave
+	    the cursor on the last inserted character.
+Files:	    src/ops.c
+
+Patch 6.0.040
+Problem:    When 'fileencoding' is invalid and writing fails because of
+	    this, the original file is gone. (Eric Carlier)
+Solution:   Restore the original file from the backup.
+Files:	    src/fileio.c
+
+Patch 6.0.041
+Problem:    Using ":language messages en" when LC_MESSAGES is undefined
+	    results in setting LC_CTYPE. (Eric Carlier)
+Solution:   Set $LC_MESSAGES instead.
+Files:	    src/ex_cmds2.c
+
+Patch 6.0.042
+Problem:    ":mksession" can't handle file names with a space.
+Solution:   Escape special characters in file names with a backslash.
+Files:	    src/ex_docmd.c
+
+Patch 6.0.043
+Problem:    Patch 6.0.041 was wrong.
+Solution:   Use mch_getenv() instead of vim_getenv().
+Files:	    src/ex_cmds2.c
+
+Patch 6.0.044
+Problem:    Using a "containedin" list for a syntax item doesn't work for an
+	    item that doesn't have a "contains" argument.  Also, "containedin"
+	    doesn't ignore a transparent item. (Timo Frenay)
+Solution:   When there is a "containedin" argument somewhere, always check for
+	    contained items.  Don't check for the transparent item but the
+	    item it's contained in.
+Files:	    src/structs.h, src/syntax.c
+
+Patch 6.0.045
+Problem:    After creating a fold with a Visual selection, another window
+	    with the same buffer still has inverted text. (Sami Salonen)
+Solution:   Redraw the inverted text.
+Files:	    src/normal.c
+
+Patch 6.0.046
+Problem:    When getrlimit() returns an 8 byte number the check for running
+	    out of stack may fail. (Anthony Meijer)
+Solution:   Skip the stack check if the limit doesn't fit in a long.
+Files:	    src/auto/configure, src/config.h.in, src/configure.in,
+	    src/os_unix.c
+
+Patch 6.0.047
+Problem:    Using a regexp with "\(\)" inside a "\%[]" item causes a crash.
+	    (Samuel Lacas)
+Solution:   Don't allow nested atoms inside "\%[]".
+Files:	    src/regexp.c
+
+Patch 6.0.048
+Problem:    Win32: In the console the mouse doesn't always work correctly.
+	    Sometimes after getting focus a mouse movement is interpreted like
+	    a button click.
+Solution:   Use a different function to obtain the number of mouse buttons.
+	    Avoid recognizing a button press from undefined bits. (Vince Negri)
+Files:	    src/os_win32.c
+
+Patch 6.0.049
+Problem:    When using evim the intro screen is misleading. (Adrian Nagle)
+Solution:   Mention whether 'insertmode' is set and the menus to be used.
+Files:	    runtime/menu.vim, src/version.c
+
+Patch 6.0.050
+Problem:    UTF-8: "viw" doesn't include non-ASCII characters before the
+	    cursor. (Bertilo Wennergren)
+Solution:   Use dec_cursor() instead of decrementing the column number.
+Files:	    src/search.c
+
+Patch 6.0.051
+Problem:    UTF-8: Using CTRL-R on the command line doesn't insert composing
+	    characters. (Ron Aaron)
+Solution:   Also include the composing characters and fix redrawing them.
+Files:	    src/ex_getln.c, src/ops.c
+
+Patch 6.0.052
+Problem:    The check for rlim_t in patch 6.0.046 does not work on some
+	    systems. (Zdenek Sekera)
+Solution:   Also look in sys/resource.h for rlim_t.
+Files:	    src/auto/configure, src/configure.in
+
+Patch 6.0.053 (extra)
+Problem:    Various problems with QNX.
+Solution:   Minor fix for configure.  Switch on terminal clipboard support in
+	    main.c.  Fix "pterm" mouse support.  os_qnx.c didn't build without
+	    photon. (Julian Kinraid)
+Files:	    src/auto/configure, src/configure.in, src/gui_photon.c,
+	    src/main.c, src/misc2.c, src/option.h, src/os_qnx.c, src/os_qnx.h,
+	    src/syntax.c
+
+Patch 6.0.054
+Problem:    When using mswin.vim, CTRL-V pastes a block of text like it is
+	    normal text.  Using CTRL-V in blockwise Visual mode leaves "x"
+	    characters behind.
+Solution:   Make CTRL-V work as it should.  Do the same for the Paste menu
+	    entries.
+Files:	    runtime/menu.vim, runtime/mswin.vim
+
+Patch 6.0.055
+Problem:    GTK: The selection isn't copied the first time.
+Solution:   Own the selection at the right moment.
+Files:	    src/gui_gtk_x11.c
+
+Patch 6.0.056
+Problem:    Using "CTRL-O cw" in Insert mode results in a nested Insert mode.
+	    <Esc> doesn't leave Insert mode then.
+Solution:   Only use nested Insert mode when 'insertmode' is set or when a
+	    mapping is used.
+Files:	    src/normal.c
+
+Patch 6.0.057
+Problem:    Using ":wincmd g}" in a function doesn't work.  (Gary Holloway)
+Solution:   Execute the command directly, instead of putting it in the
+	    typeahead buffer.
+Files:	    src/normal.c, src/proto/normal.pro, src/window.c
+
+Patch 6.0.058
+Problem:    When a Cursorhold autocommand moved the cursor, the ruler wasn't
+	    updated. (Bohdan Vlasyuk)
+Solution:   Update the ruler after executing the autocommands.
+Files:	    src/gui.c
+
+Patch 6.0.059
+Problem:    Highlighting for 'hlsearch' isn't visible in lines that are
+	    highlighted for diff highlighting.  (Gary Holloway)
+Solution:   Let 'hlsearch' highlighting overrule diff highlighting.
+Files:	    src/screen.c
+
+Patch 6.0.060
+Problem:    Motif: When the tooltip is to be popped up, Vim crashes.
+	    (Gary Holloway)
+Solution:   Check for a NULL return value from gui_motif_fontset2fontlist().
+Files:	    src/gui_beval.c
+
+Patch 6.0.061
+Problem:    The toolbar buttons to load and save a session do not correctly
+	    use v:this_session.
+Solution:   Check for v:this_session to be empty instead of existing.
+Files:	    runtime/menu.vim
+
+Patch 6.0.062
+Problem:    Crash when 'verbose' is > 3 and using ":shell". (Yegappan
+	    Lakshmanan)
+Solution:   Avoid giving a NULL pointer to printf().  Also output a newline
+	    and switch the cursor on.
+Files:	    src/misc2.c
+
+Patch 6.0.063
+Problem:    When 'cpoptions' includes "$", using "cw" to type a ')' on top of
+	    the "$" doesn't update syntax highlighting after it.
+Solution:   Stop displaying the "$" when typing a ')' in its position.
+Files:	    src/search.c
+
+Patch 6.0.064 (extra)
+Problem:    The NSIS install script doesn't work with newer versions of NSIS.
+	    The diff feature doesn't work when there isn't a good diff.exe on
+	    the system.
+Solution:   Replace the GetParentDir instruction by a user function.
+	    Fix a few cosmetic problems.  Use defined constants for the
+	    version number, so that it's defined in one place only.
+	    Only accept the install directory when it ends in "vim".
+	    (Eduardo Fernandez)
+	    Add a diff.exe and use it from the default _vimrc.
+Files:	    nsis/gvim.nsi, nsis/README.txt, src/dosinst.c
+
+Patch 6.0.065
+Problem:    When using ":normal" in 'indentexpr' it may use redo characters
+	    before its argument.  (Neil Bird)
+Solution:   Save and restore the stuff buffer in ex_normal().
+Files:	    src/ex_docmd.c, src/getchar.c, src/globals.h, src/structs.h
+
+Patch 6.0.066
+Problem:    Sometimes undo for one command is split into two undo actions.
+	    (Halim Salman)
+Solution:   Don't set the undo-synced flag when reusing a line that was
+	    already saved for undo.
+Files:	    src/undo.c
+
+Patch 6.0.067
+Problem:    if_xcmdsrv.c doesn't compile on systems where fd_set isn't defined
+	    in the usual header file (e.g., AIX). (Mark Waggoner)
+Solution:   Include sys/select.h in if_xcmdsrv.c for systems that have it.
+Files:	    src/if_xcmdsrv.c
+
+Patch 6.0.068
+Problem:    When formatting a Visually selected area with "gq" and the number
+	    of lines increases the last line may not be redrawn correctly.
+	    (Yegappan Lakshmanan)
+Solution:   Correct the area to be redrawn for inserted/deleted lines.
+Files:	    src/ops.c
+
+Patch 6.0.069
+Problem:    Using "K" on a word that includes a "!" causes a "No previous
+	    command" error, because the "!" is expanded. (Craig Jeffries)
+Solution:   Put a backslash before the "!".
+Files:	    src/normal.c
+
+Patch 6.0.070
+Problem:    Win32: The error message for a failed dynamic linking of a Perl,
+	    Ruby, Tcl and Python library is unclear about what went wrong.
+Solution:   Give the name of the library or function that could not be loaded.
+	    Also for the iconv and gettext libraries when 'verbose' is set.
+Files:	    src/eval.c, src/if_perl.xs, src/if_python.c, src/if_ruby.c,
+	    src/if_tcl.c, src/mbyte.c, src/os_win32.c, src/proto/if_perl.pro,
+	    src/proto/if_python.pro, src/proto/if_ruby.pro,
+	    src/proto/if_tcl.pro, src/proto/mbyte.pro
+
+Patch 6.0.071
+Problem:    The "iris-ansi" builtin termcap isn't very good.
+Solution:   Fix the wrong entries. (David Harrison)
+Files:	    src/term.c
+
+Patch 6.0.072
+Problem:    When 'lazyredraw' is set, a mapping that stops Visual mode, moves
+	    the cursor and starts Visual mode again causes a redraw problem.
+	    (Brian Silverman)
+Solution:   Redraw both the old and the new Visual area when necessary.
+Files:	    src/normal.c, src/screen.c
+
+Patch 6.0.073 (extra)
+Problem:    DJGPP: When using CTRL-Z to start a shell, the prompt is halfway
+	    the text. (Volker Kiefel)
+Solution:   Position the system cursor before starting the shell.
+Files:	    src/os_msdos.c
+
+Patch 6.0.074
+Problem:    When using "&" in a substitute string a multi-byte character with
+	    a trailbyte 0x5c is not handled correctly.
+Solution:   Recognize multi-byte characters inside the "&" part. (Muraoka Taro)
+Files:	    src/regexp.c
+
+Patch 6.0.075
+Problem:    When closing a horizontally split window while 'eadirection' is
+	    "hor" another horizontally split window is still resized. (Aron
+	    Griffis)
+Solution:   Only resize windows in the same top frame as the window that is
+	    split or closed.
+Files:	    src/main.c, src/proto/window.pro, src/window.c
+
+Patch 6.0.076
+Problem:    Warning for wrong pointer type when compiling.
+Solution:   Use char instead of char_u pointer.
+Files:	    src/version.c
+
+Patch 6.0.077
+Problem:    Patch 6.0.075 was incomplete.
+Solution:   Fix another call to win_equal().
+Files:	    src/option.c
+
+Patch 6.0.078
+Problem:    Using "daw" at the end of a line on a single-character word didn't
+	    include the white space before it.  At the end of the file it
+	    didn't work at all.  (Gavin Sinclair)
+Solution:   Include the white space before the word.
+Files:	    src/search.c
+
+Patch 6.0.079
+Problem:    When "W" is in 'cpoptions' and 'backupcopy' is "no" or "auto", can
+	    still overwrite a read-only file, because it's renamed. (Gary
+	    Holloway)
+Solution:   Add a check for a read-only file before renaming the file to
+	    become the backup.
+Files:	    src/fileio.c
+
+Patch 6.0.080
+Problem:    When using a session file that has the same file in two windows,
+	    the fileinfo() call in do_ecmd() causes a scroll and a hit-enter
+	    prompt. (Robert Webb)
+Solution:   Don't scroll this message when 'shortmess' contains 'O'.
+Files:	    src/ex_cmds.c
+
+Patch 6.0.081
+Problem:    After using ":saveas" the new buffer name is added to the Buffers
+	    menu with a wrong number. (Chauk-Mean Proum)
+Solution:   Trigger BufFilePre and BufFilePost events for the renamed buffer
+	    and BufAdd for the old name (which is with a new buffer).
+Files:	    src/ex_cmds.c
+
+Patch 6.0.082
+Problem:    When swapping screens in an xterm and there is an (error) message
+	    from the vimrc script, the shell prompt is after the message.
+Solution:   Output a newline when there was output on the alternate screen.
+	    Also when starting the GUI.
+Files:	    src/main.c
+
+Patch 6.0.083
+Problem:    GTK: When compiled without menu support the buttons in a dialog
+	    don't have any text. (Erik Edelmann)
+Solution:   Add the text also when GTK_USE_ACCEL isn't defined.  And define
+	    GTK_USE_ACCEL also when not using menus.
+Files:	    src/gui_gtk.c
+
+Patch 6.0.084
+Problem:    UTF-8: a "r" command with an argument that is a keymap for a
+	    character with a composing character can't be repeated with ".".
+	    (Raphael Finkel)
+Solution:   Add the composing characters to the redo buffer.
+Files:	    src/normal.c
+
+Patch 6.0.085
+Problem:    When 'mousefocus' is set, using "s" to go to Insert mode and then
+	    moving the mouse pointer to another window stops Insert mode,
+	    while this doesn't happen with "a" or "i". (Robert Webb)
+Solution:   Reset finish_op before calling edit().
+Files:	    src/normal.c
+
+Patch 6.0.086
+Problem:    When using "gu" the message says "~ed".
+Solution:   Make the message say "changed".
+Files:	    src/ops.c
+
+Patch 6.0.087 (lang)
+Problem:    Message translations are incorrect, which may cause a crash.
+	    (Peter Figura)
+	    The Turkish translations needed more work and the maintainer
+	    didn't have time.
+Solution:   Fix order of printf arguments.  Remove %2$d constructs.
+	    Add "-v" to msgfmt to get a warning for wrong translations.
+	    Don't install the Turkish translations for now.
+	    Update a few more translations.
+Files:	    src/po/Makefile, src/po/af.po, src/po/cs.po, src/po/cs.cp1250.po,
+	    src/po/de.po, src/po/es.po, src/po/fr.po, src/po/it.po,
+	    src/po/ja.po, src/po/ja.sjis.po, src/po/ko.po, src/po/pl.po,
+	    src/po/sk.po, src/po/uk.po, src/po/zh_CN.UTF-8.po,
+	    src/po/zh_CN.cp936.po, src/po/zh_CN.po, src/po/zh_TW.po
+
+Patch 6.0.088
+Problem:    "." doesn't work after using "rx" in Visual mode.  (Charles
+	    Campbell)
+Solution:   Also store the replacement character in the redo buffer.
+Files:	    src/normal.c
+
+Patch 6.0.089
+Problem:    In a C file, using "==" to align a line starting with "*  " after
+	    a line with "* -" indents one space too few.  (Piet Delport)
+Solution:   Align with the previous line if the comment-start-string matches
+	    there.
+Files:	    src/misc1.c
+
+Patch 6.0.090
+Problem:    When a wrapping line does not fit in a window and 'scrolloff' is
+	    bigger than half the window height, moving the cursor left or
+	    right causes the screen to flash badly. (Lubomir Host)
+Solution:   When there is not enough room to show 'scrolloff' screen lines and
+	    near the end of the line, show the end of the line.
+Files:	    src/move.c
+
+Patch 6.0.091
+Problem:    Using CTRL-O in Insert mode, while 'virtualedit' is "all" and the
+	    cursor is after the end-of-line, moves the cursor left. (Yegappan
+	    Lakshmanan)
+Solution:   Keep the cursor in the same position.
+Files:	    src/edit.c
+
+Patch 6.0.092
+Problem:    The explorer plugin doesn't ignore case of 'suffixes' on
+	    MS-Windows. (Mike Williams)
+Solution:   Match or ignore case as appropriate for the OS.
+Files:	    runtime/plugin/explorer.vim
+
+Patch 6.0.093
+Problem:    When the Tcl library couldn't be loaded dynamically, get an error
+	    message when closing a buffer or window. (Muraoka Taro)
+Solution:   Only free structures if already using the Tcl interpreter.
+Files:	    src/if_tcl.c
+
+Patch 6.0.094
+Problem:    Athena: When clicking in the horizontal scrollbar Vim crashes.
+	    (Paul Ackersviller)
+Solution:   Use the thumb size instead of the window pointer of the scrollbar
+	    (which is NULL). (David Harrison)
+	    Also avoid that scrolling goes the wrong way in a narrow window.
+Files:	    src/gui_athena.c
+
+Patch 6.0.095
+Problem:    Perl: Deleting lines may leave the cursor beyond the end of the
+	    file.
+Solution:   Check the cursor position after deleting a line. (Serguei)
+Files:	    src/if_perl.xs
+
+Patch 6.0.096
+Problem:    When ":saveas fname" fails because the file already exists, the
+	    file name is changed anyway and a following ":w" will overwrite
+	    the file. (Eric Carlier)
+Solution:   Don't change the file name if the file already exists.
+Files:	    src/ex_cmds.c
+
+Patch 6.0.097
+Problem:    Re-indenting in Insert mode with CTRL-F may cause a crash with a
+	    multi-byte encoding.
+Solution:   Avoid using a character before the start of a line. (Sergey
+	    Vlasov)
+Files:	    src/edit.c
+
+Patch 6.0.098
+Problem:    GTK: When using Gnome the "Search" and "Search and Replace" dialog
+	    boxes are not translated.
+Solution:   Define ENABLE_NLS before including gnome.h. (Eduardo Fernandez)
+Files:	    src/gui_gtk.c, src/gui_gtk_x11.c
+
+Patch 6.0.099
+Problem:    Cygwin: When running Vi compatible MS-DOS line endings cause
+	    trouble.
+Solution:   Make the default for 'fileformats' "unix,dos" in Vi compatible
+	    mode.  (Michael Schaap)
+Files:	    src/option.h
+
+Patch 6.0.100
+Problem:    ":badd +0 test%file" causes a crash.
+Solution:   Take into account that the "+0" is NUL terminated when allocating
+	    room for replacing the "%".
+Files:	    src/ex_docmd.c
+
+Patch 6.0.101
+Problem:    ":mksession" doesn't restore editing a file that has a '#' or '%'
+	    in its name.  (Wolfgang Blankenburg)
+Solution:   Put a backslash before the '#' and '%'.
+Files:	    src/ex_docmd.c
+
+Patch 6.0.102
+Problem:    When changing folds the cursor may appear halfway a closed fold.
+	    (Nam SungHyun)
+Solution:   Set w_cline_folded correctly. (Yasuhiro Matsumoto)
+Files:	    src/move.c
+
+Patch 6.0.103
+Problem:    When using 'scrollbind' a large value of 'scrolloff' will make the
+	    scroll binding stop near the end of the file. (Coen Engelbarts)
+Solution:   Don't use 'scrolloff' when limiting the topline for scroll
+	    binding. (Dany StAmant)
+Files:	    src/normal.c
+
+Patch 6.0.104
+Problem:    Multi-byte: When '$' is in 'cpoptions', typing a double-wide
+	    character that overwrites the left halve of an old double-wide
+	    character causes a redraw problem and the cursor stops blinking.
+Solution:   Clear the right half of the old character. (Yasuhiro Matsumoto)
+Files:	    src/edit.c, src/screen.c
+
+Patch 6.0.105
+Problem:    Multi-byte: In a window of one column wide, with syntax
+	    highlighting enabled a crash might happen.
+Solution:   Skip getting the syntax attribute when the character doesn't fit
+	    anyway.  (Yasuhiro Matsumoto)
+Files:	    src/screen.c
+
+Patch 6.0.106 (extra)
+Problem:    Win32: When the printer font is wrong, there is no error message.
+Solution:   Give an appropriate error message. (Yasuhiro Matsumoto)
+Files:	    src/os_mswin.c
+
+Patch 6.0.107 (extra)
+Problem:    VisVim: When editing another file, a modified file may be written
+	    unexpectedly and without warning.
+Solution:   Split the window if a file was modified.
+Files:	    VisVim/Commands.cpp
+
+Patch 6.0.108
+Problem:    When using folding could try displaying line zero, resulting in an
+	    error for a NULL pointer.
+Solution:   Stop decrementing w_topline when the first line of a window is in
+	    a closed fold.
+Files:	    src/window.c
+
+Patch 6.0.109
+Problem:    XIM: When the input method is enabled, repeating an insertion with
+	    "." disables it. (Marcel Svitalsky)
+Solution:   Don't store the input method status when a command comes from the
+	    stuff buffer.
+Files:	    src/ui.c
+
+Patch 6.0.110
+Problem:    Using undo after executing "OxjAxkdd" from a register in
+	    an empty buffer gives an error message.  (Gerhard Hochholzer)
+Solution:   Don't adjust the bottom line number of an undo block when it's
+	    zero.  Add a test for this problem.
+Files:	    src/undo.c, src/testdir/test20.in, src/testdir/test20.ok
+
+Patch 6.0.111
+Problem:    The virtcol() function doesn't take care of 'virtualedit'.
+Solution:   Add the column offset when needed. (Yegappan Lakshmanan)
+Files:	    src/eval.c
+
+Patch 6.0.112
+Problem:    The explorer plugin doesn't sort directories with a space or
+	    special character after a directory with a shorter name.
+Solution:   Ignore the trailing slash when comparing directory names.  (Mike
+	    Williams)
+Files:	    runtime/plugin/explorer.vim
+
+Patch 6.0.113
+Problem:    ":edit ~/fname" doesn't work if $HOME includes a space.  Also,
+	    expanding wildcards with the shell may fail. (John Daniel)
+Solution:   Escape spaces with a backslash when needed.
+Files:	    src/ex_docmd.c, src/misc1.c, src/proto/misc1.pro, src/os_unix.c
+
+Patch 6.0.114
+Problem:    Using ":p" with fnamemodify() didn't expand "~/" or "~user/" to a
+	    full path.  For Win32 the current directory was prepended.
+	    (Michael Geddes)
+Solution:   Expand the home directory.
+Files:	    src/eval.c
+
+Patch 6.0.115 (extra)
+Problem:    Win32: When using a dialog with a textfield it cannot scroll the
+	    text.
+Solution:   Add ES_AUTOHSCROLL to the textfield style. (Pedro Gomes)
+Files:	    src/gui_w32.c
+
+Patch 6.0.116 (extra)
+Problem:    MS-Windows NT/2000/XP: filewritable() doesn't work correctly for
+	    filesystems that use ACLs.
+Solution:   Use ACL functions to check if a file is writable. (Mike Williams)
+Files:	    src/eval.c, src/macros.h, src/os_win32.c, src/proto/os_win32.pro
+
+Patch 6.0.117 (extra)
+Problem:    Win32: when disabling the menu, "set lines=999" doesn't use all
+	    the available screen space.
+Solution:   Don't subtract the fixed caption height but the real menu height
+	    from the available screen space.  Also: Avoid recursion in
+	    gui_mswin_get_menu_height().
+Files:	    src/gui_w32.c, src/gui_w48.c
+
+Patch 6.0.118
+Problem:    When $TMPDIR is a relative path, the temp directory is missing a
+	    trailing slash and isn't deleted when Vim exits. (Peter Holm)
+Solution:   Add the slash after expanding the directory to an absolute path.
+Files:	    src/fileio.c
+
+Patch 6.0.119 (depends on patch 6.0.116)
+Problem:    VMS: filewritable() doesn't work properly.
+Solution:   Use the same method as for Unix. (Zoltan Arpadffy)
+Files:	    src/eval.c
+
+Patch 6.0.120
+Problem:    The conversion to html isn't compatible with XHTML.
+Solution:   Quote the values. (Jess Thrysoee)
+Files:	    runtime/syntax/2html.vim
+
+Patch 6.0.121 (extra) (depends on patch 6.0.116)
+Problem:    Win32: After patch 6.0.116 Vim doesn't compile with mingw32.
+Solution:   Add an #ifdef HAVE_ACL.
+Files:	    src/os_win32.c
+
+Patch 6.0.122 (extra)
+Problem:    Win16: Same resize problems as patch 6.0.117 fixed for Win32.  And
+	    dialog textfield problem from patch 6.0.115.
+Solution:   Set old_menu_height only when used.  Add ES_AUTOHSCROLL flag.
+	    (Vince Negri)
+Files:	    src/gui_w16.c
+
+Patch 6.0.123 (depends on patch 6.0.119)
+Problem:    Win16: Compilation problems.
+Solution:   Move "&&" to other lines. (Vince Negri)
+Files:	    src/eval.c
+
+Patch 6.0.124
+Problem:    When using a ":substitute" command that starts with "\="
+	    (evaluated as an expression), "~" was still replaced with the
+	    previous substitute string.
+Solution:   Skip the replacement when the substitute string starts with "\=".
+	    Also adjust the documentation about doubling backslashes.
+Files:	    src/ex_cmds.c, runtime/doc/change.txt
+
+Patch 6.0.125 (extra)
+Problem:    Win32: When using the multi_byte_ime feature pressing the shift
+	    key would be handled as if a character was entered, thus mappings
+	    with a shifted key didn't work. (Charles Campbell)
+Solution:   Ignore pressing the shift, control and alt keys.
+Files:	    src/os_win32.c
+
+Patch 6.0.126
+Problem:    The python library was always statically linked.
+Solution:   Link the python library dynamically. (Matthias Klose)
+Files:	    src/auto/configure, src/configure.in
+
+Patch 6.0.127
+Problem:    When using a terminal that swaps screens and the Normal background
+	    color has a different background, using an external command may
+	    cause the color of the wrong screen to be changed. (Mark Waggoner)
+Solution:   Don't call screen_stop_highlight() in stoptermcap().
+Files:	    src/term.c
+
+Patch 6.0.128
+Problem:    When moving a vertically split window to the far left or right,
+	    the scrollbars are not adjusted. (Scott E Lee)  When 'mousefocus'
+	    is set the mouse pointer wasn't adjusted.
+Solution:   Adjust the scrollbars and the mouse pointer.
+Files:	    src/window.c
+
+Patch 6.0.129
+Problem:    When using a very long file name, ":ls" (repeated a few times)
+	    causes a crash.  Test with "vim `perl -e 'print "A"x1000'`".
+	    (Tejeda)
+Solution:   Terminate a string before getting its length in buflist_list().
+Files:	    src/buffer.c
+
+Patch 6.0.130
+Problem:    When using ":cprev" while the error window is open, and the new
+	    line at the top wraps, the window isn't correctly drawn.
+	    (Yegappan Lakshmanan)
+Solution:   When redrawing the topline don't scroll twice.
+Files:	    src/screen.c
+
+Patch 6.0.131
+Problem:    When using bufname() and there are two matches for listed buffers
+	    and one match for an unlisted buffer, the unlisted buffer is used.
+	    (Aric Blumer)
+Solution:   When there is a match with a listed buffer, don't check for
+	    unlisted buffers.
+Files:	    src/buffer.c
+
+Patch 6.0.132
+Problem:    When setting 'iminsert' in the vimrc and using an xterm with two
+	    screens the ruler is drawn in the wrong screen. (Igor Goldenberg)
+Solution:   Only draw the ruler when using the right screen.
+Files:	    src/option.c
+
+Patch 6.0.133
+Problem:    When opening another buffer while 'keymap' is set and 'iminsert'
+	    is zero, 'iminsert' is set to one unexpectedly. (Igor Goldenberg)
+Solution:   Don't set 'iminsert' as a side effect of defining a ":lmap"
+	    mapping.  Only do that when 'keymap' is set.
+Files:	    src/getchar.c, src/option.c
+
+Patch 6.0.134
+Problem:    When completing ":set tags=" a path with an embedded space causes
+	    the completion to stop. (Sektor van Skijlen)
+Solution:   Escape spaces with backslashes, like for ":set path=".  Also take
+	    backslashes into account when searching for the start of the path
+	    to complete (e.g., for 'backupdir' and 'cscopeprg').
+Files:	    src/ex_docmd.c, src/ex_getln.c, src/option.c, src/structs.h
+
+Patch 6.0.135
+Problem:    Menus that are not supposed to do anything used "<Nul>", which
+	    still produced an error beep.
+	    When CTRL-O is mapped for Insert mode, ":amenu" commands didn't
+	    work in Insert mode.
+	    Menu language falls back to English when $LANG ends in "@euro".
+Solution:   Use "<Nop>" for a menu item that doesn't do anything, just like
+	    mappings.
+	    Use ":anoremenu" instead of ":amenu".
+	    Ignore "@euro" in the locale name.
+Files:	    runtime/makemenu.vim, runtime/menu.vim, src/menu.c
+
+Patch 6.0.136
+Problem:    When completing in Insert mode, a mapping could be unexpectedly
+	    applied.
+Solution:   Don't use mappings when checking for a typed character.
+Files:	    src/edit.c
+
+Patch 6.0.137
+Problem:    GUI: When using the find or find/replace dialog from Insert mode,
+	    the input mode is stopped.
+Solution:   Don't use the input method status when the main window doesn't
+	    have focus.
+Files:	    src/ui.c
+
+Patch 6.0.138
+Problem:    GUI: When using the find or find/replace dialog from Insert mode,
+	    the text is inserted when CTRL-O is mapped. (Andre Pang)
+	    When opening the dialog again, a whole word search isn't
+	    recognized.
+	    When doing "replace all" a whole word search was never done.
+Solution:   Don't put a search or replace command in the input buffer,
+	    execute it directly.
+	    Recognize "\<" and "\>" after removing "\V".
+	    Add "\<" and "\>" also for "replace all".
+Files:	    src/gui.c
+
+Patch 6.0.139
+Problem:    When stopping 'wildmenu' completion, the statusline of the
+	    bottom-left vertically split window isn't redrawn. (Yegappan
+	    Lakshmanan)
+Solution:   Redraw all the bottom statuslines.
+Files:	    src/ex_getln.c, src/proto/screen.pro, src/screen.c
+
+Patch 6.0.140
+Problem:    Memory allocated for local mappings and abbreviations is leaked
+	    when the buffer is wiped out.
+Solution:   Clear the local mappings when deleting a buffer.
+Files:	    src/buffer.c, src/getchar.c, src/proto/getchar.pro, src/vim.h
+
+Patch 6.0.141
+Problem:    When using ":enew" in an empty buffer, some buffer-local things
+	    are not cleared.  b:keymap_name is not set.
+Solution:   Clear user commands and mappings local to the buffer when re-using
+	    the current buffer.  Reload the keymap.
+Files:	    src/buffer.c
+
+Patch 6.0.142
+Problem:    When Python is linked statically, loading dynamic extensions might
+	    fail.
+Solution:   Add an extra linking flag when needed. (Andrew Rodionoff)
+Files:	    src/configure.in, src/auto/configure
+
+Patch 6.0.143
+Problem:    When a syntax item includes a line break in a pattern, the syntax
+	    may not be updated properly when making a change.
+Solution:   Add the "linebreaks" argument to ":syn sync".
+Files:	    runtime/doc/syntax.txt, src/screen.c, src/structs.h, src/syntax.c
+
+Patch 6.0.144
+Problem:    After patch 6.0.088 redoing "veU" doesn't work.
+Solution:   Don't add the "U" to the redo buffer, it will be used as an undo
+	    command.
+Files:	    src/normal.c
+
+Patch 6.0.145
+Problem:    When Vim can't read any input it might get stuck.  When
+	    redirecting stdin and stderr Vim would not read commands from a
+	    file.  (Servatius Brandt)
+Solution:   When repeatedly trying to read a character when it's not possible,
+	    exit Vim.  When stdin and stderr are not a tty, still try reading
+	    from them, but don't do a blocking wait.
+Files:	    src/ui.c
+
+Patch 6.0.146
+Problem:    When 'statusline' contains "%{'-'}" this results in a zero.
+	    (Milan Vancura)
+Solution:   Don't handle numbers with a minus as a number, they were not
+	    displayed anyway.
+Files:	    src/buffer.c
+
+Patch 6.0.147
+Problem:    It's not easy to mark a Vim version as being modified.  The new
+	    license requires this.
+Solution:   Add the --modified-by argument to configure and the MODIFIED_BY
+	    define.  It's used in the intro screen and the ":version" output.
+Files:	    src/auto/configure, src/configure.in, src/config.h.in,
+	    src/feature.h, src/version.c
+
+Patch 6.0.148
+Problem:    After "p" in an empty line, `[ goes to the second character.
+	    (Kontra Gergely)
+Solution:   Don't increment the column number in an empty line.
+Files:	    src/ops.c
+
+Patch 6.0.149
+Problem:    The pattern "\(.\{-}\)*" causes a hang.  When using a search
+	    pattern that causes a stack overflow to be detected Vim could
+	    still hang.
+Solution:   Correctly report "operand could be empty" when using "\{-}".
+	    Check for "out_of_stack" inside loops to avoid a hang.
+Files:	    src/regexp.c
+
+Patch 6.0.150
+Problem:    When using a multi-byte encoding, patch 6.0.148 causes "p" to work
+	    like "P". (Sung-Hyun Nam)
+Solution:   Compute the byte length of a multi-byte character.
+Files:	    src/ops.c
+
+Patch 6.0.151
+Problem:    Redrawing the status line and ruler can be wrong when it contains
+	    multi-byte characters.
+Solution:   Use character width and byte length correctly. (Yasuhiro Matsumoto)
+Files:	    src/screen.c
+
+Patch 6.0.152
+Problem:    strtrans() could hang on an illegal UTF-8 byte sequence.
+Solution:   Skip over illegal bytes. (Yasuhiro Matsumoto)
+Files:	    src/charset.c
+
+Patch 6.0.153
+Problem:    When using (illegal) double-byte characters and Vim syntax
+	    highlighting Vim can crash. (Yasuhiro Matsumoto)
+Solution:   Increase a pointer over a character instead of a byte.
+Files:	    src/regexp.c
+
+Patch 6.0.154
+Problem:    MS-DOS and MS-Windows: The menu entries for xxd don't work when
+	    there is no xxd in the path.
+	    When converting back from Hex the filetype may remain "xxd" if it
+	    is not detected.
+Solution:   When xxd is not in the path use the one in the runtime directory,
+	    where the install program has put it.
+	    Clear the 'filetype' option before detecting the new value.
+Files:	    runtime/menu.vim
+
+Patch 6.0.155
+Problem:    Mac: compilation problems in ui.c after patch 6.0.145. (Axel
+	    Kielhorn)
+Solution:   Don't call mch_inchar() when NO_CONSOLE is defined.
+Files:	    src/ui.c
+
+Patch 6.0.156
+Problem:    Starting Vim with the -b argument and two files, ":next" doesn't
+	    set 'binary' in the second file, like Vim 5.7. (Norman Diamond)
+Solution:   Set the global value for 'binary'.
+Files:	    src/option.c
+
+Patch 6.0.157
+Problem:    When defining a user command with "-complete=dir" files will also
+	    be expanded.  Also, "-complete=mapping" doesn't appear to work.
+	    (Michael Naumann)
+Solution:   Use the expansion flags defined with the user command.
+	    Handle expanding mappings specifically.
+Files:	    src/ex_docmd.c
+
+Patch 6.0.158
+Problem:    When getting the warning for a file being changed outside of Vim
+	    and reloading the file, the 'readonly' option is reset, even when
+	    the permissions didn't change. (Marcel Svitalsky)
+Solution:   Keep 'readonly' set when reloading a file and the permissions
+	    didn't change.
+Files:	    src/fileio.c
+
+Patch 6.0.159
+Problem:    Wildcard expansion for ":emenu" also shows separators.
+Solution:   Skip menu separators for ":emenu", ":popup" and ":tearoff".
+	    Also, don't handle ":tmenu" as if it was ":tearoff".  And leave
+	    out the alternatives with "&" included.
+Files:	    src/menu.c
+
+Patch 6.0.160
+Problem:    When compiling with GCC 3.0.2 and using the "-O2" argument, the
+	    optimizer causes a problem that makes Vim crash.
+Solution:   Add a configure check to avoid "-O2" for this version of gcc.
+Files:	    src/configure.in, src/auto/configure
+
+Patch 6.0.161 (extra)
+Problem:    Win32: Bitmaps don't work with signs.
+Solution:   Make it possible to use bitmaps with signs. (Muraoka Taro)
+Files:	    src/ex_cmds.c, src/feature.h, src/gui_w32.c, src/gui_x11.c,
+	    src/proto/gui_w32.pro, src/proto/gui_x11.pro
+
+Patch 6.0.162
+Problem:    Client-server: An error message for a wrong expression appears in
+	    the server instead of the client.
+Solution:   Pass the error message from the server to the client.  Also
+	    adjust the example code. (Flemming Madsen)
+Files:	    src/globals.h, src/if_xcmdsrv.c, src/main.c, src/os_mswin.c,
+	    src/proto/if_xcmdsrv.pro, src/proto/os_mswin.pro,
+	    runtime/doc/eval.txt, runtime/tools/xcmdsrv_client.c
+
+Patch 6.0.163
+Problem:    When using a GUI dialog, a file name is sometimes used like it was
+	    a directory.
+Solution:   Separate path and file name properly.
+	    For GTK, Motif and Athena concatenate directory and file name for
+	    the default selection.
+Files:	    src/diff.c, src/ex_cmds.c, src/ex_cmds2.c, src/ex_docmd.c,
+	    src/gui_athena.c, src/gui_gtk.c, src/gui_motif.c, src/message.c
+
+Patch 6.0.164
+Problem:    After patch 6.0.135 the menu entries for pasting don't work in
+	    Insert and Visual mode. (Muraoka Taro)
+Solution:   Add <script> to allow script-local mappings.
+Files:	    runtime/menu.vim
+
+Patch 6.0.165
+Problem:    Using --remote and executing locally gives unavoidable error
+	    messages.
+Solution:   Add --remote-silent and --remote-wait-silent to silently execute
+	    locally.
+	    For Win32 there was no error message when a server didn't exist.
+Files:	    src/eval.c, src/if_xcmdsrv.c, src/main.c, src/os_mswin.c,
+	    src/proto/if_xcmdsrv.pro, src/proto/os_mswin.pro
+
+Patch 6.0.166
+Problem:    GUI: There is no way to avoid dialogs to pop up.
+Solution:   Add the 'c' flag to 'guioptions': Use console dialogs.  (Yegappan
+	    Lakshmanan)
+Files:	    runtime/doc/options.txt, src/option.h, src/message.c
+
+Patch 6.0.167
+Problem:    When 'fileencodings' is "latin2" some characters in the help files
+	    are displayed wrong.
+Solution:   Force the 'fileencoding' for the help files to be "latin1".
+Files:	    src/fileio.c
+
+Patch 6.0.168
+Problem:    ":%s/\n/#/" doesn't replace at an empty line. (Bruce DeVisser)
+Solution:   Don't skip matches after joining two lines.
+Files:	    src/ex_cmds.c
+
+Patch 6.0.169
+Problem:    When run as evim and the GUI can't be started we get stuck in a
+	    terminal without menus in Insert mode.
+Solution:   Exit when using "evim" and "gvim -y" when the GUI can't be
+	    started.
+Files:	    src/main.c
+
+Patch 6.0.170
+Problem:    When printing double-width characters the size of tabs after them
+	    is wrong.  (Muraoka Taro)
+Solution:   Correctly compute the column after a double-width character.
+Files:	    src/ex_cmds2.c
+
+Patch 6.0.171
+Problem:    With 'keymodel' including "startsel", in Insert mode after the end
+	    of a line, shift-Left does not move the cursor. (Steve Hall)
+Solution:   CTRL-O doesn't move the cursor left, need to do that explicitly.
+Files:	    src/edit.c
+
+Patch 6.0.172
+Problem:    CTRL-Q doesn't replace CTRL-V after CTRL-X in Insert mode while it
+	    does in most other situations.
+Solution:   Make CTRL-X CTRL-Q work like CTRL-X CTRL-V in Insert mode.
+Files:	    src/edit.c
+
+Patch 6.0.173
+Problem:    When using "P" to insert a line break the cursor remains past the
+	    end of the line.
+Solution:   Check for the cursor being beyond the end of the line.
+Files:	    src/ops.c
+
+Patch 6.0.174
+Problem:    After using "gd" or "gD" the search direction for "n" may still be
+	    backwards. (Servatius Brandt)
+Solution:   Reset the search direction to forward.
+Files:	    src/normal.c, src/search.c, src/proto/search.pro
+
+Patch 6.0.175
+Problem:    ":help /\z(\)" doesn't work. (Thomas Koehler)
+Solution:   Double the backslashes.
+Files:	    src/ex_cmds.c
+
+Patch 6.0.176
+Problem:    When killed by a signal autocommands are still triggered as if
+	    nothing happened.
+Solution:   Add the v:dying variable to allow autocommands to work differently
+	    when a deadly signal has been trapped.
+Files:	    src/eval.c, src/os_unix.c, src/vim.h
+
+Patch 6.0.177
+Problem:    When 'commentstring' is empty and 'foldmethod' is "marker", "zf"
+	    doesn't work. (Thomas S. Urban)
+Solution:   Add the marker even when 'commentstring' is empty.
+Files:	    src/fold.c, src/normal.c
+
+Patch 6.0.178
+Problem:    Uninitialized memory read from xp_backslash field.
+Solution:   Initialize xp_backslash field properly.
+Files:	    src/eval.c, src/ex_docmd.c, src/ex_getln.c, src/misc1.c, src/tag.c
+
+Patch 6.0.179
+Problem:    Win32: When displaying UTF-8 characters may read uninitialized
+	    memory.
+Solution:   Add utfc_ptr2len_check_len() to avoid reading past the end of a
+	    string.
+Files:	    src/mbyte.c, src/proto/mbyte.pro, src/gui_w32.c
+
+Patch 6.0.180
+Problem:    Expanding environment variables in a string that ends in a
+	    backslash could go past the end of the string.
+Solution:   Detect the trailing backslash.
+Files:	    src/misc1.c
+
+Patch 6.0.181
+Problem:    When using ":cd dir" memory was leaked.
+Solution:   Free the allocated memory.  Also avoid an uninitialized memory
+	    read.
+Files:	    src/misc2.c
+
+Patch 6.0.182
+Problem:    When using a regexp on multi-byte characters, could try to read a
+	    character before the start of the line.
+Solution:   Don't decrement a pointer to before the start of the line.
+Files:	    src/regexp.c
+
+Patch 6.0.183
+Problem:    Leaking memory when ":func!" redefines a function.
+Solution:   Free the function name when it's not used.
+Files:	    src/eval.c
+
+Patch 6.0.184
+Problem:    Leaking memory when expanding option values.
+Solution:   Don't always copy the expanded option into allocated memory.
+Files:	    src/option.c
+
+Patch 6.0.185
+Problem:    Crash in Vim when pasting a selection in another application, on a
+	    64 bit machine.
+Solution:   Fix the format for an Atom to 32 bits. (Peter Derr)
+Files:	    src/ui.c
+
+Patch 6.0.186
+Problem:    X11: Three warnings when compiling the client-server code.
+Solution:   Add a typecast to unsigned char.
+Files:	    src/if_xcmdsrv.c
+
+Patch 6.0.187
+Problem:    "I" in Visual mode and then "u" reports too many changes. (Andrew
+	    Stryker)
+	    "I" in Visual linewise mode adjusts the indent for no apparent
+	    reason.
+Solution:   Only save those lines for undo that are changed.
+	    Don't change the indent after inserting in Visual linewise mode.
+Files:	    src/ops.c
+
+Patch 6.0.188
+Problem:    Win32: After patch 6.0.161 signs defined in the vimrc file don't
+	    work.
+Solution:   Initialize the sign icons after initializing the GUI. (Vince
+	    Negri)
+Files:	    src/gui.c, src/gui_x11.c
+
+Patch 6.0.189
+Problem:    The size of the Visual area isn't always displayed when scrolling
+	    ('ruler' off, 'showcmd' on).  Also not when using a search
+	    command. (Sylvain Hitier)
+Solution:   Redisplay the size of the selection after showing the mode.
+Files:	    src/screen.c
+
+Patch 6.0.190
+Problem:    GUI: when 'mouse' is empty a click with the middle button still
+	    moves the cursor.
+Solution:   Paste at the cursor position instead of the mouse position.
+Files:	    src/normal.c
+
+Patch 6.0.191
+Problem:    When no servers are available serverlist() gives an error instead
+	    of returning an empty string. (Hari Krishna)
+Solution:   Don't give an error message.
+Files:	    src/eval.c
+
+Patch 6.0.192
+Problem:    When 'virtualedit' is set, "ylj" goes to the wrong column. (Andrew
+	    Nikitin)
+Solution:   Reset the flag that w_virtcol is valid when moving the cursor back
+	    to the start of the operated area.
+Files:	    src/normal.c
+
+Patch 6.0.193
+Problem:    When 'virtualedit' is set, col(".") after the end of the line
+	    should return one extra.
+Solution:   Add one to the column.
+Files:	    src/eval.c
+
+Patch 6.0.194
+Problem:    "--remote-silent" tries to send a reply to the client, like it was
+	    "--remote-wait".
+Solution:   Properly check for the argument.
+Files:	    src/main.c
+
+Patch 6.0.195
+Problem:    When 'virtualedit' is set and a search starts in virtual space
+	    ":call search('x')" goes to the wrong position. (Eric Long)
+Solution:   Reset coladd when finding a match.
+Files:	    src/search.c
+
+Patch 6.0.196
+Problem:    When 'virtualedit' is set, 'selection' is "exclusive" and visually
+	    selecting part of a tab at the start of a line, "x" joins it with
+	    the previous line.  Also, when the selection spans more than one
+	    line the whole tab is deleted.
+Solution:   Take coladd into account when adjusting for 'selection' being
+	    "exclusive".  Also expand a tab into spaces when deleting more
+	    than one line.
+Files:	    src/normal.c, src/ops.c
+
+Patch 6.0.197
+Problem:    When 'virtualedit' is set and 'selection' is "exclusive", "v$x"
+	    doesn't delete the last character in the line. (Eric Long)
+Solution:   Don't reset the inclusive flag. (Helmut Stiegler)
+Files:	    src/normal.c
+
+Patch 6.0.198
+Problem:    When 'virtualedit' is set and 'showbreak' is not empty, moving the
+	    cursor over the line break doesn't work properly. (Eric Long)
+Solution:   Make getviscol() and getviscol2() use getvvcol() to obtain the
+	    virtual cursor position.  Adjust coladvance() and oneleft() to
+	    skip over the 'showbreak' characters.
+Files:	    src/edit.c, src/misc2.c
+
+Patch 6.0.199
+Problem:    Multi-byte: could use iconv() after calling iconv_end().
+	    (Yasuhiro Matsumoto)
+Solution:   Stop converting input and output stream after calling iconv_end().
+Files:	    src/mbyte.c
+
+Patch 6.0.200
+Problem:    A script that starts with "#!perl" isn't recognized as a Perl
+	    filetype.
+Solution:   Ignore a missing path in a script header.  Also, speed up
+	    recognizing scripts by simplifying the patterns used.
+Files:	    runtime/scripts.vim
+
+Patch 6.0.201
+Problem:    When scrollbinding and doing a long jump, switching windows jumps
+	    to another position in the file.  Scrolling a few lines at a time
+	    is OK. (Johannes Zellner)
+Solution:   When setting w_topline reset the flag that indicates w_botline is
+	    valid.
+Files:	    src/diff.c
+
+Patch 6.0.202
+Problem:    The "icon=" argument for the menu command to define a toolbar icon
+	    with a file didn't work for GTK. (Christian J. Robinson)
+	    For Motif and Athena a full path was required.
+Solution:   Search the icon file using the specified path.  Expand environment
+	    variables in the file name.
+Files:	    src/gui_gtk.c, src/gui_x11.c
+
+Patch 6.0.203
+Problem:    Can change 'fileformat' even though 'modifiable' is off.
+	    (Servatius Brandt)
+Solution:   Correct check for kind of set command.
+Files:	    src/option.c
+
+Patch 6.0.204
+Problem:    ":unlet" doesn't work for variables with curly braces. (Thomas
+	    Scott Urban)
+Solution:   Handle variable names with curly braces properly. (Vince Negri)
+Files:	    src/eval.c
+
+Patch 6.0.205 (extra)
+Problem:    "gvim -f" still forks when using the batch script to start Vim.
+Solution:   Add an argument to "start" to use a foreground session (Michael
+	    Geddes)
+Files:	    src/dosinst.c
+
+Patch 6.0.206
+Problem:    Unix: if expanding a wildcard in a file name results in a
+	    wildcard character and there are more parts in the path with a
+	    wildcard, it is expanded again.
+	    Windows: ":edit \[abc]" could never edit the file "[abc]".
+Solution:   Don't expand wildcards in already expanded parts.
+	    Don't remove backslashes used to escape the special meaning of a
+	    wildcard; can edit "[abc]" if '[' is removed from 'isfname'.
+Files:	    src/misc1.c, src/os_unix.c
+
+Patch 6.0.207 (extra)
+Problem:    Win32: The shortcuts and start menu entries let Vim startup in the
+	    desktop directory, which is not very useful.
+Solution:   Let shortcuts start Vim in $HOME or $HOMEDIR$HOMEPATH.
+Files:	    src/dosinst.c
+
+Patch 6.0.208
+Problem:    GUI: When using a keymap and the cursor is not blinking, CTRL-^ in
+	    Insert mode doesn't directly change the cursor color.  (Alex
+	    Solow)
+Solution:   Force a redraw of the cursor after CTRL-^.
+Files:	    src/edit.c
+
+Patch 6.0.209
+Problem:    GUI GTK: After selecting a 'guifont' with the font dialog there
+	    are redraw problems for multi-byte characters.
+Solution:   Separate the font dialog from setting the new font name to avoid
+	    that "*" is used to find wide and bold fonts.
+	    When redrawing extra characters for the bold trick, take care of
+	    UTF-8 characters.
+Files:	    src/gui.c, src/gui_gtk_x11.c, src/option.c, src/proto/gui.pro,
+	    src/proto/gui_gtk_x11.pro
+
+Patch 6.0.210
+Problem:    After patch 6.0.167 it's no longer possible to edit a help file in
+	    another encoding than latin1.
+Solution:   Let the "++enc=" argument overrule the encoding.
+Files:	    src/fileio.c
+
+Patch 6.0.211
+Problem:    When reading a file fails, the buffer is empty, but it might still
+	    be possible to write it with ":w" later.  The original file is
+	    lost then. (Steve Amerige)
+Solution:   Set the 'readonly' option for the buffer.
+Files:	    src/fileio.c
+
+Patch 6.0.212
+Problem:    GUI GTK: confirm("foo", "") causes a crash.
+Solution:   Don't make a non-existing button the default.  Add a default "OK"
+	    button if none is specified.
+Files:	    src/eval.c, src/gui_gtk.c
+
+Patch 6.0.213
+Problem:    When a file name contains unprintable characters, CTRL-G and other
+	    commands don't work well.
+Solution:   Turn unprintable into printable characters. (Yasuhiro Matsumoto)
+Files:	    src/buffer.c, src/charset.c
+
+Patch 6.0.214
+Problem:    When there is a buffer without a name, empty entries appear in the
+	    jumplist saved in the viminfo file.
+Solution:   Don't write jumplist entries without a file name.
+Files:	    src/mark.c
+
+Patch 6.0.215
+Problem:    After using "/" from Visual mode the Paste menu and Toolbar
+	    entries don't work.  Pasting with the middle mouse doesn't work
+	    and modeless selection doesn't work.
+Solution:   Use the command line mode menus and use the mouse like in the
+	    command line.
+Files:	    src/gui.c, src/menu.c, src/ui.c
+
+Patch 6.0.216
+Problem:    After reloading a file, displayed in another window than the
+	    current one, which was changed outside of Vim the part of the file
+	    around the cursor set by autocommands may be displayed, but
+	    jumping back to the original cursor position when entering the
+	    window again.
+Solution:   Restore the topline of the window.
+Files:	    src/fileio.c
+
+Patch 6.0.217
+Problem:    When getting help from a help file that was used before, an empty
+	    unlisted buffer remains in the buffer list. (Eric Long)
+Solution:   Wipe out the buffer used to do the tag jump from.
+Files:	    src/buffer.c, src/ex_cmds.c, src/proto/buffer.pro
+
+Patch 6.0.218
+Problem:    With explorer plugin: "vim -o filename dirname" doesn't load the
+	    explorer window until entering the window.
+Solution:   Call s:EditDir() for each window after starting up.
+Files:	    runtime/plugin/explorer.vim
+
+Patch 6.0.219
+Problem:    ":setlocal" and ":setglobal", without arguments, display terminal
+	    options. (Zdenek Sekera)
+Solution:   Skip terminal options for these two commands.
+Files:	    src/option.c
+
+Patch 6.0.220
+Problem:    After patch 6.0.218 get a beep on startup. (Muraoka Taro)
+Solution:   Don't try going to another window when there isn't one.
+Files:	    runtime/plugin/explorer.vim
+
+Patch 6.0.221
+Problem:    When using ":bdel" and all other buffers are unloaded the lowest
+	    numbered buffer is jumped to instead of the most recent one. (Dave
+	    Cecil)
+Solution:   Prefer an unloaded buffer from the jumplist.
+Files:	    src/buffer.c
+
+Patch 6.0.222
+Problem:    When 'virtualedit' is set and using autoindent, pressing Esc after
+	    starting a new line leaves behind part of the autoindent. (Helmut
+	    Stiegler)
+Solution:   After deleting the last char in the line adjust the cursor
+	    position in del_bytes().
+Files:	    src/misc1.c, src/ops.c
+
+Patch 6.0.223
+Problem:    When splitting a window that contains the explorer, hitting CR on
+	    a file name gives error messages.
+Solution:   Set the window variables after splitting the window.
+Files:	    runtime/plugin/explorer.vim
+
+Patch 6.0.224
+Problem:    When 'sidescroll' and 'sidescrolloff' are set in a narrow window
+	    the text may jump left-right and the cursor is displayed in the
+	    wrong position. (Aric Blumer)
+Solution:   When there is not enough room, compute the left column for the
+	    window to put the cursor in the middle.
+Files:	    src/move.c
+
+Patch 6.0.225
+Problem:    In Visual mode "gk" gets stuck in a closed fold. (Srinath
+	    Avadhanula)
+Solution:   Behave differently in a closed fold.
+Files:	    src/normal.c
+
+Patch 6.0.226
+Problem:    When doing ":recover file" get the ATTENTION prompt.
+	    After recovering the same file five times get a read error or a
+	    crash.  (Alex Davis)
+Solution:   Set the recoverymode flag before setting the file name.
+	    Correct the amount of used memory for the size of block zero.
+Files:	    src/ex_docmd.c
+
+Patch 6.0.227 (extra)
+Problem:    The RISC OS port has several problems.
+Solution:   Update the makefile and fix some of the problems. (Andy Wingate)
+Files:	    src/Make_ro.mak, src/os_riscos.c, src/os_riscos.h,
+	    src/proto/os_riscos.pro, src/search.c
+
+Patch 6.0.228
+Problem:    After putting text in Visual mode the '] mark is not at the end of
+	    the put text.
+	    Undo doesn't work properly when putting a word into a Visual
+	    selection that spans more than one line.
+Solution:   Correct the '] mark for the deleting the Visually selected text.
+	    #ifdef code that depends on FEAT_VISUAL properly.
+	    Also fix that "d" crossing line boundary puts '[ just before
+	    deleted text.
+	    Fix undo by saving all deleted lines at once.
+Files:	    src/ex_docmd.c, src/globals.h, src/normal.c, src/ops.c,
+	    src/structs.h, src/vim.h
+
+Patch 6.0.229
+Problem:    Multi-byte: With 'm' in 'formatoptions', formatting doesn't break
+	    at a multi-byte char followed by an ASCII char, and the other way
+	    around. (Muraoka Taro)
+	    When joining lines a space is inserted between multi-byte
+	    characters, which is not always wanted.
+Solution:   Check for multi-byte character before and after the breakpoint.
+	    Don't insert a space before or after a multi-byte character when
+	    joining lines and the 'M' flag is in 'formatoptions'.  Don't
+	    insert a space between multi-byte characters when the 'B' flag is
+	    in 'formatoptions'.
+Files:	    src/edit.c, src/ops.c, src/option.h
+
+Patch 6.0.230
+Problem:    The ":" used as a motion after an operator is exclusive, but
+	    sometimes it should be inclusive.
+Solution:   Make the "v" in between an operator and motion toggle
+	    inclusive/exclusive. (Servatius Brandt)
+Files:	    runtime/doc/motion.txt, src/normal.c
+
+Patch 6.0.231
+Problem:    "gd" and "gD" don't work when the variable matches in a comment
+	    just above the match to be found. (Servatius Brandt)
+Solution:   Continue searching in the first column below the comment.
+Files:	    src/normal.c
+
+Patch 6.0.232
+Problem:    "vim --version" prints on stderr while "vim --help" prints on
+	    stdout.
+Solution:   Make "vim --version" use stdout.
+Files:	    runtime/doc/starting.txt, src/globals.h, src/main.c, src/message.c
+
+Patch 6.0.233
+Problem:    "\1\{,8}" in a regexp is not allowed, but it should work, because
+	    there is an upper limit.  (Jim Battle)
+Solution:   Allow using "\{min,max}" after an atom that can be empty if there
+	    is an upper limit.
+Files:	    src/regexp.c
+
+Patch 6.0.234
+Problem:    It's not easy to set the cursor position without modifying marks.
+Solution:   Add the cursor() function. (Yegappan Lakshmanan)
+Files:	    runtime/doc/eval.txt, src/eval.c
+
+Patch 6.0.235
+Problem:    When writing a file and renaming the original file to make the
+	    backup, permissions could change when setting the owner.
+Solution:   Only set the owner when it's needed and set the permissions again
+	    afterwards.
+	    When 'backupcopy' is "auto" check that the owner and permissions
+	    of a newly created file can be set properly.
+Files:	    src/fileio.c
+
+Patch 6.0.236
+Problem:    ":edit" without argument should move cursor to line 1 in Vi
+	    compatible mode.
+Solution:   Add 'g' flag to 'cpoptions'.
+Files:	    runtime/doc/options.txt, src/ex_docmd.c, src/option.h
+
+Patch 6.0.237
+Problem:    In a C file, using the filetype plugin, re-indenting a comment
+	    with two spaces after the middle "*" doesn't align properly.
+Solution:   Don't use a middle entry from a start/middle/end to line up with
+	    the start of the comment when the start part doesn't match with
+	    the actual comment start.
+Files:	    src/misc1.c
+
+Patch 6.0.238
+Problem:    Using a ":substitute" command with a substitute() call in the
+	    substitution expression causes errors. (Srinath Avadhanula)
+Solution:   Save and restore pointers when doing substitution recursively.
+Files:	    src/regexp.c
+
+Patch 6.0.239
+Problem:    Using "A" to append after a Visually selected block which is after
+	    the end of the line, spaces are inserted in the wrong line and
+	    other unexpected effects. (Michael Naumann)
+Solution:   Don't advance the cursor to the next line.
+Files:	    src/ops.c
+
+Patch 6.0.240
+Problem:    Win32: building with Python 2.2 doesn't work.
+Solution:   Add support for Python 2.2 with dynamic linking. (Paul Moore)
+Files:	    src/if_python.c
+
+Patch 6.0.241
+Problem:    Win32: Expanding the old value of an option that is a path that
+	    starts with a backslash, an extra backslash is inserted.
+Solution:   Only insert backslashes where needed.
+	    Also handle multi-byte characters properly when removing
+	    backslashes.
+Files:	    src/option.c
+
+Patch 6.0.242
+Problem:    GUI: On a system with an Exceed X server sometimes get a "Bad
+	    Window" error. (Tommi Maekitalo)
+Solution:   When forking, use a pipe to wait in the parent for the child to
+	    have done the setsid() call.
+Files:	    src/gui.c
+
+Patch 6.0.243
+Problem:    Unix: "vim --version" outputs a NL before the last line instead of
+	    after it. (Charles Campbell)
+Solution:   Send the NL to the same output stream as the text.
+Files:	    src/message.c, src/os_unix.c, src/proto/message.pro
+
+Patch 6.0.244
+Problem:    Multi-byte: Problems with (illegal) UTF-8 characters in menu and
+	    file name (e.g., icon text, status line).
+Solution:   Correctly handle unprintable characters.  Catch illegal UTF-8
+	    characters and replace them with <xx>.  Truncating the status line
+	    wasn't done correctly at a multi-byte character. (Yasuhiro
+	    Matsumoto)
+	    Added correct_cmdspos() and transchar_byte().
+Files:	    src/buffer.c, src/charset.c, src/ex_getln.c, src/gui.c,
+	    src/message.c, src/screen.c, src/vim.h
+
+Patch 6.0.245
+Problem:    After using a color scheme, setting the 'background' option might
+	    not work. (Peter Horst)
+Solution:   Disable the color scheme if it switches 'background' back to the
+	    wrong value.
+Files:	    src/option.c
+
+Patch 6.0.246
+Problem:    ":echomsg" didn't use the highlighting set by ":echohl". (Gary
+	    Holloway)
+Solution:   Use the specified attributes for the message. (Yegappan
+	    Lakshmanan)
+Files:	    src/eval.c
+
+Patch 6.0.247
+Problem:    GTK GUI: Can't use gvim in a kpart widget.
+Solution:   Add the "--echo-wid" argument to let Vim echo the window ID on
+	    stdout. (Philippe Fremy)
+Files:	    runtime/doc/starting.txt, src/globals.h, src/gui_gtk_x11.c,
+	    src/main.c
+
+Patch 6.0.248
+Problem:    When using compressed help files and 'encoding' isn't "latin1",
+	    Vim converts the help file before decompressing. (David Reviejo)
+Solution:   Don't convert a help file when 'binary' is set.
+Files:	    src/fileio.c
+
+Patch 6.0.249
+Problem:    "vim -t edit -c 'sta ex_help'" doesn't move cursor to edit().
+Solution:   Don't set the cursor on the first line for "-c" arguments when
+	    there also is a "-t" argument.
+Files:	    src/main.c
+
+Patch 6.0.250 (extra)
+Problem:    Macintosh: Various problems when compiling.
+Solution:   Various fixes, mostly #ifdefs. (Dany St. Amant)
+Files:	    src/gui_mac.c, src/main.c, src/misc2.c, src/os_mac.h,
+	    src/os_mac.pbproj/project.pbxproj, src/os_unix.c
+
+Patch 6.0.251 (extra)
+Problem:    Macintosh: menu shortcuts are not very clear.
+Solution:   Show the shortcut with the Mac clover symbol. (raindog)
+Files:	    src/gui_mac.c
+
+Patch 6.0.252
+Problem:    When a user function was defined with "abort", an error that is
+	    not inside if/endif or while/endwhile doesn't abort the function.
+	    (Servatius Brandt)
+Solution:   Don't reset did_emsg when the function is to be aborted.
+Files:	    src/ex_docmd.c
+
+Patch 6.0.253
+Problem:    When 'insertmode' is set, after "<C-O>:edit file" the next <C-O>
+	    doesn't work. (Benji Fisher)  <C-L> has the same problem.
+Solution:   Reset need_start_insertmode once in edit().
+Files:	    src/edit.c
+
+Patch 6.0.254 (extra)
+Problem:    Borland C++ 5.5: Checking for stack overflow doesn't work
+	    correctly.  Matters when using a complicated regexp.
+Solution:   Remove -N- from Make_bc5.mak. (Yasuhiro Matsumoto)
+Files:	    src/Make_bc5.mak
+
+Patch 6.0.255 (extra) (depends on patch 6.0.116 and 6.0.121)
+Problem:    Win32: ACL support doesn't work well on Samba drives.
+Solution:   Add a check for working ACL support. (Mike Williams)
+Files:	    src/os_win32.c
+
+Patch 6.0.256 (extra)
+Problem:    Win32: ":highlight Comment guifg=asdf" does not give an error
+	    message. (Randall W.  Morris)  Also for other systems.
+Solution:   Add gui_get_color() to give one error message for all systems.
+Files:	    src/gui.c, src/gui_amiga.c, src/gui_athena.c, src/gui_motif.c,
+	    src/gui_riscos.c, src/gui_x11.c, src/gui_gtk_x11.c,
+	    src/proto/gui.pro, src/syntax.c
+
+Patch 6.0.257
+Problem:    Win32: When 'mousefocus' is set and there is a BufRead
+	    autocommand, after the dialog for permissions changed outside of
+	    Vim: 'mousefocus' stops working. (Robert Webb)
+Solution:   Reset need_mouse_correct after checking timestamps.
+Files:	    src/fileio.c
+
+Patch 6.0.258
+Problem:    When 'scrolloff' is 999 and there are folds, the text can jump up
+	    and down when moving the cursor down near the end of the file.
+	    (Lubomir Host)
+Solution:   When putting the cursor halfway the window start counting lines at
+	    the end of a fold.
+Files:	    src/move.c
+
+Patch 6.0.259
+Problem:    MS-DOS: after editing the command line the cursor shape may remain
+	    like in Insert mode. (Volker Kiefel)
+Solution:   Reset the cursor shape after editing the command line.
+Files:	    src/ex_getln.c
+
+Patch 6.0.260
+Problem:    GUI: May crash while starting up when giving an error message for
+	    missing color. (Servatius Brandt)
+Solution:   Don't call gui_write() when still starting up.  Don't give error
+	    message for empty color name.  Don't use 't_vb' while the GUI is
+	    still starting up.
+Files:	    src/fileio.c, src/gui.c, src/misc1.c, src/ui.c
+
+Patch 6.0.261
+Problem:    nr2char() and char2nr() don't work with multi-byte characters.
+Solution:   Use 'encoding' for these functions. (Yasuhiro Matsumoto)
+Files:	    runtime/doc/eval.txt, src/eval.c
+
+Patch 6.0.262 (extra)
+Problem:    Win32: IME doesn't work properly.  OnImeComposition() isn't used
+	    at all.
+Solution:   Adjust various things for IME.
+Files:	    src/globals.h, src/gui_w32.c, src/mbyte.c, src/proto/ui.pro,
+	    src/structs.h, src/ui.c
+
+Patch 6.0.263
+Problem:    GTK: When a dialog is closed by the window manager, Vim hangs.
+	    (Christian J. Robinson)
+Solution:   Use GTK_WIDGET_DRAWABLE() instead of GTK_WIDGET_VISIBLE().
+Files:	    src/gui_gtk.c, src/gui_gtk_x11.c
+
+Patch 6.0.264
+Problem:    The amount of virtual memory is used to initialize 'maxmemtot',
+	    which may be much more than the amount of physical memory,
+	    resulting in a lot of swapping.
+Solution:   Get the amount of physical memory with sysctl(), sysconf() or
+	    sysinfo() when possible.
+Files:	    src/auto/configure, src/configure.in, src/config.h.in,
+	    src/os_unix.c, src/os_unix.h
+
+Patch 6.0.265
+Problem:    Win32: Using backspace while 'fkmap' is set causes a crash.
+	    (Jamshid Oasjmoha)
+Solution:   Don't try mapping special keys.
+Files:	    src/farsi.c
+
+Patch 6.0.266
+Problem:    The rename() function deletes the file if the old and the new name
+	    are the same. (Volker Kiefel)
+Solution:   Don't do anything if the names are equal.
+Files:	    src/fileio.c
+
+Patch 6.0.267
+Problem:    UTF-8: Although 'isprint' says a character is printable,
+	    utf_char2cells() still considers it unprintable.
+Solution:   Use vim_isprintc() for characters upto 0x100. (Yasuhiro Matsumoto)
+Files:	    src/mbyte.c
+
+Patch 6.0.268 (extra) (depends on patch 6.0.255)
+Problem:    Win32: ACL check crashes when using forward slash in file name.
+Solution:   Improve the check for the path in the file name.
+Files:	    src/os_win32.c
+
+Patch 6.0.269
+Problem:    Unprintable characters in a file name may cause problems when
+	    using the 'statusline' option or when 'buftype' is "nofile".
+Solution:   call trans_characters() for the resulting statusline. (Yasuhiro
+	    Matsumoto)
+Files:	    src/buffer.c, src/screen.c, src/charset.c
+
+Patch 6.0.270 (depends on patch 6.0.267)
+Problem:    A tab causes UTF-8 text to be displayed in the wrong position.
+	    (Ron Aaron)
+Solution:   Correct utf_char2cells() again.
+Files:	    src/mbyte.c
+
+Patch 6.1a.001 (extra)
+Problem:    32bit DOS: copying text to the clipboard may cause a crash.
+	    (Jonathan D Johnston)
+Solution:   Don't copy one byte too much in SetClipboardData().
+Files:	    src/os_msdos.c
+
+Patch 6.1a.002
+Problem:    GTK: On some configurations, when closing a dialog from the window
+	    manager, Vim hangs.
+Solution:   Catch the "destroy" signal. (Aric Blumer)
+Files:	    src/gui_gtk.c
+
+Patch 6.1a.003
+Problem:    Multi-byte: With UTF-8 double-wide char and 'virtualedit' set:
+	    yanking in Visual mode doesn't include the last byte. (Eric Long)
+Solution:   Don't add a space for a double-wide character.
+Files:	    src/ops.c
+
+Patch 6.1a.004 (extra)
+Problem:    MINGW: undefined type. (Ron Aaron)
+Solution:   Make GetCompositionString_inUCS2() static.
+Files:	    src/gui_w32.c, src/gui_w48.c, src/proto/gui_w32.pro
+
+Patch 6.1a.005 (extra)
+Problem:    Win32: ":hardcopy" doesn't work after ":hardcopy!". (Jonathan
+	    Johnston)
+Solution:   Don't keep the driver context when using ":hardcopy!". (Vince
+	    Negri)
+Files:	    src/os_mswin.c
+
+Patch 6.1a.006
+Problem:    multi-byte: after setting 'encoding' the window title might be
+	    wrong.
+Solution:   Force resetting the title. (Yasuhiro Matsumoto)
+Files:	    src/option.c
+
+Patch 6.1a.007
+Problem:    Filetype detection for "*.inc" doesn't work.
+Solution:   Use a ":let" command. (David Schweikert)
+Files:	    runtime/filetype.vim
+
+Patch 6.1a.008 (extra)
+Problem:    Win32: ACL detection for network shares doesn't work.
+Solution:   Include the trailing (back)slash in the root path. (Mike Williams)
+Files:	    src/os_win32.c
+
+Patch 6.1a.009
+Problem:    When using "\@<=" or "\@<!" in a pattern, a "\1" may refer to a ()
+	    part that follows, but it generates an error message.
+Solution:   Allow a forward reference when there is a following "\@<=" or
+	    "\@<!".
+Files:	    runtime/doc/pattern.txt, src/regexp.c
+
+Patch 6.1a.010
+Problem:    When using ":help" and opening a new window, the alternate file
+	    isn't set.
+Solution:   Set the alternate file to the previously edited file.
+Files:	    src/ex_cmds.c
+
+Patch 6.1a.011
+Problem:    GTK: ":set co=77", change width with the mouse, ":set co=77"
+	    doesn't resize the window. (Darren Hiebert)
+Solution:   Set the form size after handling a resize event.
+Files:	    src/gui_gtk_x11.c
+
+Patch 6.1a.012
+Problem:    GTK: The file browser always returns a full path. (Lohner)
+Solution:   Shorten the file name if possible.
+Files:	    src/gui_gtk.c
+
+Patch 6.1a.013
+Problem:    When using "=~word" in 'cinkeys' or 'indentkeys', the case of the
+	    last character of the word isn't ignored. (Raul Segura Acevedo)
+Solution:   Ignore case when checking the last typed character.
+Files:	    src/edit.c
+
+Patch 6.1a.014
+Problem:    After patch 6.1a.006 can't compile without the title feature.
+Solution:   Add an #ifdef.
+Files:	    src/option.c
+
+Patch 6.1a.015
+Problem:    MS-Windows: When expanding a file name that contains a '[' or '{'
+	    an extra backslash is inserted. (Raul Segura Acevedo)
+Solution:   Avoid adding the backslash.
+Files:	    src/ex_getln.c
+
+Patch 6.1a.016
+Problem:    Completion after ":language" doesn't include "time". (Raul Segura
+	    Acevedo)
+Solution:   Add the alternative to the completions.
+Files:	    src/ex_cmds2.c
+
+Patch 6.1a.017
+Problem:    Clicking the mouse in the top row of a window where the first line
+	    doesn't fit moves the cursor to the wrong column.
+Solution:   Add the skipcol also for the top row of a window.
+Files:	    src/ui.c
+
+Patch 6.1a.018
+Problem:    When 'scrolloff' is one and the window height is one, "gj" can put
+	    the cursor above the window. (Raul Segura Acevedo)
+Solution:   Don't let skipcol become bigger than the cursor column.
+Files:	    src/move.c
+
+Patch 6.1a.019
+Problem:    When using a composing character on top of an ASCII character, the
+	    "l" command clears the composing character.  Only when 'ruler' and
+	    'showcmd' are off. (Raphael Finkel)
+Solution:   Don't move the cursor by displaying characters when there are
+	    composing characters.
+Files:	    src/screen.c
+
+Patch 6.1a.020
+Problem:    GTK: after patch 6.1a.011 resizing with the mouse doesn't always
+	    work well for small sizes. (Adrien Beau)
+Solution:   Use another way to avoid the problem with ":set co=77".
+Files:	    src/gui_gtk_x11.c
+
+Patch 6.1a.021
+Problem:    Several Syntax menu entries are wrong or confusing.
+Solution:   Rephrase and correct the menu entries. (Adrien Beau)
+Files:	    runtime/makemenu.vim, runtime/menu.vim
+
+Patch 6.1a.022
+Problem:    A tags file might be used twice on case insensitive systems.
+	    (Rick Swanton)
+Solution:   Don't use the same file name twice in the default for the 'tags'
+	    option.  Ignore case when comparing names of already visited
+	    files.
+Files:	    src/misc2.c, src/option.c
+
+Patch 6.1a.023
+Problem:    When starting the GUI get "C" characters echoed in the terminal.
+Solution:   Don't try sending a clear-screen command while the GUI is starting
+	    up.
+Files:	    src/screen.c
+
+Patch 6.1a.024
+Problem:    In other editors CTRL-F is often used for a find dialog.
+Solution:   In evim use CTRL-F for the find dialog.
+Files:	    runtime/evim.vim
+
+Patch 6.1a.025
+Problem:    The choices for the fileformat dialog can't be translated.
+Solution:   Add g:menutrans_fileformat_choices. (Adrien Beau)
+Files:	    runtime/menu.vim
+
+Patch 6.1a.026
+Problem:    Indenting Java files is wrong with "throws", "extends" and
+	    "implements" clauses.
+Solution:   Update the Java indent script.
+Files:	    runtime/indent/java.vim
+
+Patch 6.1a.027
+Problem:    A few Syntax menu entries missing or incorrect.
+Solution:   Add and correct the menu entries. (Adrien Beau)
+	    Shorten a few menus to avoid they become too long.
+Files:	    runtime/makemenu.vim, runtime/menu.vim
+
+Patch 6.1a.028
+Problem:    XIM: problems with feedback and some input methods.
+Solution:   Use iconv for calculating the cells.  Remove the queue for
+	    key_press_event only when text was changed. (Yasuhiro Matsumoto)
+Files:	    src/globals.h, src/mbyte.c, src/screen.c
+
+Patch 6.1a.029
+Problem:    After patch 6.1a.028 can't compile GTK version with XIM but
+	    without multi-byte chars.
+Solution:   Add an #ifdef. (Aschwin Marsman)
+Files:	    src/mbyte.c
+
+Patch 6.1a.030
+Problem:    With double-byte encodings toupper() and tolower() may have wrong
+	    results.
+Solution:   Skip double-byte characters. (Eric Long)
+Files:	    src/eval.c
+
+Patch 6.1a.031
+Problem:    Accessing the 'balloondelay' variable may cause a crash.
+Solution:   Make the variable for 'balloondelay' a long. (Olaf Seibert)
+Files:	    src/option.h
+
+Patch 6.1a.032 (extra)
+Problem:    Some menu files used a wrong encoding name for "scriptencoding".
+Solution:   Move the translations to a separate file, which is sourced after
+	    setting "scriptencoding".
+	    Also add Czech menu translations in ASCII and update the other
+	    encodings.
+Files:	    runtime/lang/menu_cs_cz.iso_8859-1.vim,
+	    runtime/lang/menu_cs_cz.iso_8859-2.vim,
+	    runtime/lang/menu_czech_czech_republic.1250.vim,
+	    runtime/lang/menu_czech_czech_republic.1252.vim,
+	    runtime/lang/menu_czech_czech_republic.ascii.vim,
+	    runtime/lang/menu_de_de.iso_8859-1.vim,
+	    runtime/lang/menu_de_de.latin1.vim,
+	    runtime/lang/menu_fr_fr.iso_8859-1.vim,
+	    runtime/lang/menu_fr_fr.latin1.vim,
+	    runtime/lang/menu_french_france.1252.vim,
+	    runtime/lang/menu_german_germany.1252.vim,
+	    runtime/lang/menu_ja_jp.euc-jp.vim,
+	    runtime/lang/menu_ja_jp.utf-8.vim,
+	    runtime/lang/menu_japanese_japan.932.vim
+
+Patch 6.1a.033
+Problem:    XIM: doesn't reset input context.
+Solution:   call xim_reset() with im_set_active(FALSE). (Takuhiro Nishioka)
+Files:	    src/mbyte.c
+
+Patch 6.1a.034 (extra)
+Problem:    Win32: The ACL checks for a readonly file still don't work well.
+Solution:   Remove the ACL checks, go back to how it worked in Vim 6.0.
+Files:	    src/os_win32.c
+
+Patch 6.1a.035
+Problem:    multi-byte: When using ":sh" in the GUI, typed and displayed
+	    multi-byte characters are not handled correctly.
+Solution:   Deal with multi-byte characters to and from the shell. (Yasuhiro
+	    Matsumoto)  Also handle UTF-8 composing characters.
+Files:	    src/os_unix.c
+
+Patch 6.1a.036
+Problem:    GTK: the save-yourself event was not handled.
+Solution:   Catch the save-yourself event and preserve swap files. (Neil Bird)
+Files:	    src/gui_gtk_x11.c
+
+Patch 6.1a.037
+Problem:    The MS-Windows key mapping doesn't include CTRL-S for saving.
+	    (Vlad Sandrini)
+Solution:   Map CTRL-S to ":update".
+Files:	    runtime/mswin.vim
+
+Patch 6.1a.038
+Problem:    Solaris: Including both sys/sysctl.h and sys/sysinfo.h doesn't
+	    work. (Antonio Colombo)
+Solution:   Don't include sys/sysinfo.h when not calling sysinfo().
+Files:	    src/os_unix.c
+
+Patch 6.1a.039
+Problem:    Not all visual basic files are recognized.
+Solution:   Add checks to catch *.ctl files. (Raul Segura Acevedo)
+Files:	    runtime/filetype.vim
+
+Patch 6.1a.040
+Problem:    A *.pl file is recognized as Perl, but it could be a prolog file.
+Solution:   Check the first non-empty line. (Kontra Gergely)
+Files:	    runtime/filetype.vim
+
+Patch 6.1a.041
+Problem:    When pressing the left mouse button in the command line and them
+	    moving the mouse upwards, nearly all the text is selected.
+Solution:   Don't try extending a modeless selection when there isn't one.
+Files:	    src/ui.c
+
+Patch 6.1a.042
+Problem:    When merging files, ":diffput" and ":diffget" are used a lot, but
+	    they require a lot of typing.
+Solution:   Add "dp" for ":diffput" and "do" for ":diffget".
+Files:	    runtime/doc/diff.txt, src/diff.c, src/normal.c, src/proto/diff.pro
+
+
+Patch 6.1b.001 (extra)
+Problem:    Checking for wildcards in a path does not handle multi-byte
+	    characters with a trail byte which is a wildcard.
+Solution:   Handle multi-byte characters correctly. (Muraoka Taro)
+Files:	    src/os_amiga.c, src/os_mac.c, src/os_msdos.c, src/os_mswin.c,
+	    src/os_unix.c
+
+Patch 6.1b.002
+Problem:    A regexp that ends in "\{" is not flagged as an error.  May cause
+	    a stack overflow when 'incsearch' is set. (Gerhard Hochholzer)
+Solution:   Handle a missing "}" as an error.
+Files:	    src/regexp.c
+
+Patch 6.1b.003 (extra)
+Problem:    The RISC OS GUI doesn't compile.
+Solution:   Include changes since Vim 5.7. (Andy Wingate)
+Files:	    src/Make_ro.mak, src/gui_riscos.c, src/os_riscos.c,
+	    src/os_riscos.h, src/proto/gui_riscos.pro
+
+Patch 6.1b.004
+Problem:    col("'>") returns a negative number for linewise selection. (Neil
+	    Bird)
+Solution:   Don't add one to MAXCOL.
+Files:	    src/eval.c
+
+Patch 6.1b.005
+Problem:    Using a search pattern that causes an out-of-stack error while
+	    'hlsearch' is set keeps giving the hit-Enter prompt.
+	    A search pattern that takes a long time delays typing when
+	    'incsearch' is set.
+Solution:   Stop 'hlsearch' highlighting when the regexp causes an error.
+	    Stop searching for 'incsearch' when a character is typed.
+Files:	    src/globals.h, src/message.c, src/screen.c, src/search.c,
+	    src/vim.h
+
+Patch 6.1b.006
+Problem:    When entering a composing character on the command line with
+	    CTRL-V, the text isn't redrawn correctly.
+Solution:   Redraw the text under and after the cursor.
+Files:	    src/ex_getln.c
+
+Patch 6.1b.007
+Problem:    When the cursor is in the white space between two sentences, "dis"
+	    deletes the first character of the following sentence, "das"
+	    deletes a space after the sentence.
+Solution:   Backup the cursor one character in these situations.
+Files:	    src/search.c
+
+Patch 6.1b.008
+Problem:    *.xsl files are not recognized as xslt but xml.
+	    Monk files are not recognized.
+Solution:   Delete the duplicate line for *.xsl. (Johannes Zellner)
+	    Recognize monk files.
+Files:	    runtime/filetype.vim
+
+Patch 6.1b.009
+Problem:    Can't always compile small features and then adding eval feature,
+	    "sandbox" is undefined. (Axel Kielhorn)
+Solution:   Always define "sandbox" when the eval feature is used.
+Files:	    src/globals.h
+
+Patch 6.1b.010 (extra)
+Problem:    When compiling gvimext.cpp with MSVC 4.2 get a number of warnings.
+Solution:   Change "true" to "TRUE". (Walter Briscoe)
+Files:	    GvimExt/gvimext.cpp
+
+Patch 6.1b.011
+Problem:    When using a very long string for confirm(), can't quit the
+	    displaying at the more prompt. (Hari Krishna Dara)
+Solution:   Jump to the end of the message to show the choices.
+Files:	    src/message.c
+
+Patch 6.1b.012
+Problem:    Multi-byte: When 'showbreak' is set and a double-wide character
+	    doesn't fit at the right window edge the cursor gets stuck there.
+	    Using cursor-left gets stuck when 'virtualedit' is set.  (Eric
+	    Long)
+Solution:   Fix the way the extra ">" character is counted when 'showbreak' is
+	    set.  Don't correct cursor for virtual editing on a double-wide
+	    character.
+Files:	    src/charset.c, src/edit.c
+
+Patch 6.1b.013
+Problem:    A user command that partly matches with a buffer-local user
+	    command and matches full with a global user command unnecessarily
+	    gives an 'ambiguous command' error.
+Solution:   Find the full global match even after a partly local match.
+Files:	    src/ex_docmd.c
+
+Patch 6.1b.014
+Problem:    EBCDIC: switching mouse events off causes garbage on screen.
+	    Positioning the cursor in the GUI causes garbage.
+Solution:   Insert an ESC in the terminal code. (Ralf Schandl)
+	    Use "\b" instead of "\010" for KS_LE.
+Files:	    src/os_unix.c, src/term.c
+
+Patch 6.1b.015
+Problem:    Vimtutor has a typo.  Get a warning for "tempfile" if it
+	    doesn't exist.
+Solution:   Move a quote to the end of a line. (Max Ischenko)
+	    Use "mktemp" first, more systems have it.
+Files:	    src/vimtutor
+
+Patch 6.1b.016
+Problem:    GTK: loading a fontset that works partly, Vim might hang or crash.
+Solution:   Avoid that char_width becomes zero. (Yasuhiro Matsumoto)
+Files:	    src/gui_gtk_x11.c
+
+Patch 6.1b.017
+Problem:    GUI: When using ":shell" and there is a beep, nothing happens.
+Solution:   Call vim_beep() to produce the beep from the shell. (Yasuhiro
+	    Matsumoto)
+Files:	    src/message.c
+
+Patch 6.1b.018 (depends on 6.1b.006)
+Problem:    When entering the encryption key, special keys may still reveal
+	    the typed characters.
+Solution:   Make sure stars are used or nothing is shown in all cases.
+Files:	    src/digraph.c, src/getchar.c, src/ex_getln.c
+
+Patch 6.1b.019 (depends on 6.1b.005)
+Problem:    A search pattern that takes a long time slows down typing when
+	    'incsearch' is set.
+Solution:   Pass SEARCH_PEEK to dosearch().
+Files:	    src/ex_getln.c
+
+Patch 6.1b.020
+Problem:    When using the matchit plugin, "%" finds a match on the "end" of a
+	    ":syntax region" command in Vim scripts.
+Solution:   Skip over ":syntax region" commands by setting b:match_skip.
+Files:	    runtime/ftplugin/vim.vim
+
+Patch 6.1b.021
+Problem:    when 'mousefocus' is set, CTRL-W CTRL-] sometimes doesn't warp the
+	    pointer to the new window. (Robert Webb)
+Solution:   Don't reset need_mouse_correct when checking the timestamp of a
+	    file.
+Files:	    src/fileio.c
+
+Patch 6.1b.022
+Problem:    With lots of folds "j" does not obey 'scrolloff' properly.
+	    (Srinath Avadhanula)
+Solution:   Go to end of the fold before counting context lines.
+Files:	    src/move.c
+
+Patch 6.1b.023
+Problem:    On MS-Windows system() may cause checking timestamps, because Vim
+	    looses and gains input focus, while this doesn't happen on Unix.
+Solution:   Don't check timestamps while system() is busy.
+Files:	    src/ex_cmds2.c, src/fileio.c, src/globals.h, src/misc1.c
+
+Patch 6.1b.024 (extra)
+Problem:    Gettext 0.11 complains that "sjis" is not a standard name.
+Solution:   Use "cp932" instead.
+Files:	    src/po/sjiscorr.c
+
+Patch 6.1b.025 (extra)
+Problem:    Win32: When closing gvim while it is minimized  and has a changed
+	    file, the file-changed dialog pops up in a corner of the screen.
+Solution:   Put the dialog in the middle of the screen.
+Files:	    src/gui_w48.c
+
+Patch 6.1b.026
+Problem:    When 'diffopt' contains 'iwhite' but not 'icase': differences in
+	    case are not highlighted properly. (Gerhard Hochholzer)
+Solution:   Don't ignore case when ignoring white space differences.
+Files:	    src/diff.c
+
+Patch 6.1b.027
+Problem:    "vim --remote +" may cause a crash.
+Solution:   Check for missing file name argument. (Martin Kahlert)
+Files:	    src/main.c
+
+Patch 6.1b.028 (extra)
+Problem:    Win16: Can't compile after patch 6.1b.025.
+Solution:   Add code specifically for Win16. (Vince Negri)
+Files:	    src/gui_w48.c
+
+Patch 6.1b.029
+Problem:    Win32: When a directory on an NTFS partition is read/execute (no
+	    delete,modify,write) and the file has modify rights, trying to
+	    write the file deletes it.  Making the file read/write/execute
+	    (not delete) solves it. (Mark Canup)
+Solution:   Use the Unix code to check for a writable directory.  If not, then
+	    make a backup copy and overwrite the file.
+Files:	    src/fileio.c
+
+Patch 6.1b.030 (extra)
+Problem:    Mac: small mistake in the build script and prototypes.
+Solution:   Fix the build script and add the prototypes. (Axel Kielhorn)
+Files:	    src/os_mac.build, src/gui_mac.c
+
+Patch 6.1b.031 (extra)
+Problem:    Win32 GUI: ":set guifont=*" doesn't set 'guifont' to the resulting
+	    font name. (Vlad Sandrini)
+Solution:   Put the code back in gui_mch_init_font() to form the font name out
+	    of the logfont.
+Files:	    src/gui_w48.c
+
+Patch 6.1b.032
+Problem:    Athena: Setting a color scheme before the GUI has started causes a
+	    crash. (Todd Blumer)
+Solution:   Don't try using color names that haven't been set yet.
+Files:	    src/gui_athena.c
+
+Patch 6.1b.033
+Problem:    When using a count after a ":s" command may get ml_get errors.
+	    (Dietmar Lang)
+Solution:   Check that the resulting range does not go past the end of the
+	    buffer.
+Files:	    src/ex_cmds.c
+
+Patch 6.1b.034
+Problem:    After sourcing mswin.vim, when using <C-S-Right> after
+	    auto-indenting and then <Del>, get warning for allocating
+	    ridiculous amount of memory. (Dave Delgreco)
+Solution:   Adjust the start of the Visual area when deleting the auto-indent.
+Files:	    src/edit.c
+
+Patch 6.1b.035
+Problem:    When using evim, dropping a file on Vim and then double clicking
+	    on a word, it is changed to "i". (Merlin Hansen)
+Solution:   Reset need_start_insertmode after editing the file.
+Files:	    src/ex_docmd.c
+
+
+==============================================================================
+VERSION 6.2						*version-6.2*
+
+This section is about improvements made between version 6.1 and 6.2.
+
+This is mainly a bug-fix release.  There are also a few new features.
+
+Main new features:
+- Support for GTK 2. (Daniel Elstner)
+- Support for editing Arabic text. (Nadim Shaikli & Isam Bayazidi)
+- ":try" command and exception handling. (Servatius Brandt)
+- Support for the neXtaw GUI toolkit (mostly like Athena). (Alexey Froloff)
+- Cscope support for Win32. (Khorev Sergey)
+- Support for PostScript printing in various 8-bit encodings. (Mike Williams)
+
+
+Changed							*changed-6.2*
+-------
+
+Removed the scheme indent file, the internal Lisp indenting works well now.
+
+Moved the GvimEXt, OleVim and VisVim directories into the "src" directory.
+This is more consistent with how xxd is handled.
+
+The VisVim.dll file is installed in the top directory, next to gvimext.dll,
+instead of in a subdirectory "VisVim".  Fixes that NSIS was uninstalling it
+from the wrong directory.
+
+Removed the art indent file, it didn't do anything.
+
+submatch() returned line breaks with CR instead of LF.
+
+Changed the Win32 Makefiles to become more uniform and compile gvimext.dll.
+(Dan Sharp)
+
+'cindent': Align a "//" comment with a "//" comment in a previous line.
+(Helmut Stiegler)
+
+Previously only for xterm-like terminals parent widgets were followed to find
+the title and icon label.  Now do this for all terminal emulators.
+
+Made it possible to recognize backslashes for "%" matching.  The 'M' flag in
+'cpoptions' disables it. (Haakon Riiser)
+
+Removed the Make_tcc.mak makefile for Turbo C.  It didn't work and we probably
+can't make it work (the compiler runs out of memory).
+
+Even though the documentation refers to keywords, "[ CTRL-D" was using
+'isident' to find matches.  Changed it to use 'iskeyword'.  Also applies to
+other commands that search for defined words in included files such as
+":dsearch", "[D" and "[d".
+
+Made 'keywordprg' global-local. (Christian Robinson)
+
+Enabled the Netbeans interface by default.  Reversed the configure argument
+from "--enable-netbeans" to "--disable-netbeans".
+
+
+Added							*added-6.2*
+-----
+
+New options:
+	'arabic'
+	'arabicshape'
+	'ambiwidth'
+	'autochdir'
+	'casemap'
+	'copyindent'
+	'cscopequickfix'
+	'preserveindent'
+	'printencoding'
+	'rightleftcmd'
+	'termbidi'
+	'toolbariconsize'
+	'winfixheight'
+
+New keymaps:
+	Serbian (Aleksandar Veselinovic)
+	Chinese Pinyin (Fredrik Roubert)
+	Esperanto (Antoine J. Mechelynck)
+
+New syntax files:
+	Valgrind (Roger Luethi)
+	Smarty template (Manfred Stienstra)
+	MySQL (Kenneth Pronovici)
+	RockLinux package description (Piotr Esden-Tempski)
+	MMIX (Dirk Huesken)
+	gkrellmrc (David Necas)
+	Tilde (Tobias Rundtrom)
+	Logtalk (Paulo Moura)
+	PLP (Juerd Waalboer)
+	fvwm2m4 (David Necas)
+	IPfilter (Hendrik Scholz)
+	fstab (Radu Dineiu)
+	Quake (Nikolai Weibull)
+	Occam (Mario Schweigler)
+	lpc (Shizhu Pan)
+	Exim conf (David Necas)
+	EDIF (Artem Zankovich)
+	.cvsrc (Nikolai Weibull)
+	.fetchmailrc (Nikolai Weibull)
+	GNU gpg (Nikolai Weibull)
+	Grub (Nikolai Weibull)
+	Modconf (Nikolai Weibull)
+	RCS (Dmitry Vasiliev)
+	Art (Dorai Sitaram)
+	Renderman Interface Bytestream (Andrew J Bromage)
+	Mailcap (Doug Kearns)
+	Subversion commit file (Dmitry Vasiliev)
+	Microsoft IDL (Vadim Zeitlin)
+	WildPackets EtherPeek Decoder (Christopher Shinn)
+	Spyce (Rimon Barr)
+	Resolv.conf (Radu Dineiu)
+	A65 (Clemens Kirchgatterer)
+	sshconfig and sshdconfig (David Necas)
+	Cheetah and HTMLCheetah (Max Ischenko)
+	Packet filter (Camiel Dobbelaar)
+
+New indent files:
+	Eiffel (David Clarke)
+	Tilde (Tobias Rundtrom)
+	Occam (Mario Schweigler)
+	Art (Dorai Sitaram)
+	PHP (Miles Lott)
+	Dylan (Brent Fulgham)
+
+New tutor translations:
+	Slovak (Lubos Celko)
+	Greek (Christos Kontas)
+	German (Joachim Hofmann)
+	Norwegian (�yvind Holm)
+
+New filetype plugins:
+	Occam (Mario Schweigler)
+	Art (Dorai Sitaram)
+	ant.vim, aspvbs.vim, config.vim, csc.vim, csh.vim, dtd.vim, html.vim,
+	jsp.vim, pascal.vim, php.vim, sgml.vim, sh.vim, svg.vim, tcsh.vim,
+	xhtml.vim, xml.vim, xsd.vim.  (Dan Sharp)
+
+New compiler plugins:
+	Checkstyle (Doug Kearns)
+	g77 (Ralf Wildenhues)
+	fortran (Johann-Guenter Simon)
+	Xmllint (Doug Kearns)
+	Ruby (Tim Hammerquist)
+	Modelsim vcom (Paul Baleme)
+
+New menu translations:
+	Brazilian (Jos� de Paula)
+	British (Mike Williams)
+	Korean in UTF-8. (Nam SungHyun)
+	Norwegian (�yvind Holm)
+	Serbian (Aleksandar Jelenak)
+
+New message translation for Norwegian. (�yvind Holm)
+
+New color scheme:
+	desert (Hans Fugal)
+
+Arabic specific features.  'arabicshape', 'termbidi', 'arabic' and
+'rightleftcmd' options.  (Nadim Shaikli & Isam Bayazidi)
+
+Support for neXtaw GUI toolkit, mostly like Athena. (Alexey Froloff)
+
+Win32: cscope support. (Khorev Sergey)
+
+VMS: various improvements to documentation and makefiles.  (Zoltan Arpadffy)
+
+Added "x" key to the explorer plugin: execute the default action. (Yasuhiro
+Matsumoto)
+
+Compile gvimext.dll with MingW. (Rene de Zwart)
+
+Add the "tohtml.vim" plugin.  It defines the ":TOhtml" user command, an easy
+way to convert text to HTML.
+
+Added ":try" / ":catch" / ":finally" / ":endtry" commands.  Add E999 numbers
+to all error messages, so that they can be caught by the number.
+(Servatius Brandt)
+Moved part of ex_docmd.c to the new ex_eval.c source file.
+
+Include support for GTK+ 2.2.x (Daniel Elstner)
+Adds the "~" register: drag & drop text.
+Adds the 'toolbariconsize' option.
+Add -Dalloca when running lint to work around a problem with alloca()
+prototype.
+
+When selecting an item in the error window to jump to, take some effort to
+find an ordinary window to show the file in (not a preview window).
+
+Support for PostScript printing of various 8-bit encodings. (Mike Williams)
+
+inputdialog() accepts a third argument that is used when the dialog is
+cancelled.  Makes it possible to see a difference between cancelling and
+entering nothing.
+
+Included Aap recipes.  Can be used to update Vim to the latest version,
+building and installing.
+
+"/" option in 'cinoptions': extra indent for comment lines. (Helmut Stiegler)
+
+Vim variable "v:register" and functions setreg(), getreg() and getregtype().
+(Michael Geddes)
+
+"v" flag in 'cpoptions': Leave text on screen with backspace in Insert mode.
+(Phillip Vandry)
+
+Dosinst.exe also finds gvimext.dll in the "GvimExt" directory.  Useful when
+running install in the "src" directory for testing.
+
+Support tag files that were sorted with case ignored. (Flemming Madsen)
+
+When completing a wildcard in a leading path element, as in "../*/Makefile",
+only the last part ("Makefile") was listed.  Support custom defined
+command line completion.  (Flemming Madsen)
+
+Also recognize "rxvt" as an xterm-like terminal. (Tomas Styblo)
+
+Proper X11 session management.  Fixes that the WM_SAVE_YOURSELF event was not
+used by popular desktops.  (Neil Bird)
+Not used for Gnome 2, it has its own handling.
+
+Support BOR, DEBUG and SPAWNO arguments for the Borland 3 Makefile. (Walter
+Briscoe)
+
+Support page breaks for printing.  Adds the "formfeed" field in
+'printoptions'.  (Mike Williams)
+
+Mac OSX: multi-language support: iconv and gettext. (Muraoka Taro, Axel
+Kielhorn)
+
+"\Z" flag in patterns: ignore differences in combining characters. (Ron Aaron)
+
+Added 'preserveindent' and 'copyindent' options.  They use existing white
+space characters instead of using Tabs as much as possible. (Chris Leishman)
+
+Updated Unicode tables to Unicode 4.0. (Raphael Finkel)
+
+Support for the mouse wheel in rxvt. (AIDA Shinra)
+
+Win32: Added ":8" file modifier to get short filename.  Test50 tests the ":8"
+expansion on Win32 systems. (Michael Geddes)
+
+'cscopequickfix' option: Open quickfix window for Cscope commands.  Also
+cleanup the code for giving messages.  (Khorev Sergey)
+
+GUI: Support more than 222 columns for mouse positions.
+
+":stopinsert" command: Don't return to Insert mode.
+
+"interrupt" command for debug mode.  Useful for simulating CTRL-C. (Servatius
+Brandt)
+
+
+Fixed							*fixed-6.2*
+-----
+
+Removed a few unused #defines from config.h.in, os_os2_cfg.h and os_vms_conf.h.
+
+The Vim icons in PNG format didn't have a transparent background. (Greg
+Roelofs)
+
+Fixed a large number of spelling mistakes in the docs. (Adri Verhoef)
+
+The #defines for prototype generation were causing trouble.  Changed them to
+typedefs.
+
+A new version of libintl.h uses __asm__, which confuses cproto.  Define a
+dummy __asm__ macro.
+
+When 'virtualedit' is set can't move to halfway an unprintable character.
+Cripples CTRL-V selection. (Taro Muraoka)
+Allow moving to halfway an unprintable character.  Don't let getvvcol() change
+the pos->coladd argument.
+
+When a tab wraps to the next line, 'listchars' is set and 'foldcolumn' is
+non-zero, only one character of the foldcolumn is highlighted. (Muraoka Taro)
+
+When using ":catch" without an argument Vim crashes. (Yasuhiro Matsumoto)
+When no argument given use the ".*" pattern.
+
+Win32: When gvim.exe is started from a shortcut with the window style property
+set to maximize Vim doesn't start with a maximized window. (Yasuhiro
+Matsumoto)  Open the window with the default size and don't call ShowWindow()
+again when it's already visible. (Helmut Stiegler)
+
+gui_gtk.c used MAX, but it's undefined to avoid a conflict with system header
+files.
+
+Win32: When closing a window from a mapping some pixels remain on the
+statusline. (Yasuhiro Matsumoto)
+
+A column number in an errorformat that goes beyond the end of the line may
+cause a crash.
+
+":throw 'test'" crashes Vim. (Yasuhiro Matsumoto)
+
+The file selector's scrollbar colors are not set after doing a ":hi Scrollbar
+guifg=color".  And the file selector's colors are not changed by the
+colorscheme command.  (David Harrison)
+
+Motif: When compiling with FEAT_FOOTER defined, the text area gets a few
+pixels extra space on the right.  Remove the special case in
+gui_get_base_width(). (David Harrison)
+
+Using CTRL-R CTRL-P in Insert mode puts the '] mark in the wrong position.
+(Helmut Stiegler)
+
+When 'formatoptions' includes "awct" a non-comment wasn't auto-formatted.
+
+Using a "--cmd" argument more than 10 times caused a crash.
+
+DEC style mouse support didn't work if the page field is not empty.
+(Uribarri)
+
+"vim -l one two" did only set 'lisp' in the first file.  Vi does it for every
+file.
+
+":set tw<" didn't work.  Was checking for '^' instead of '<'.
+
+In ":hardcopy > %.ps" the "%" was not expanded to the current filename.
+
+Made ":redraw" also update the Visual area.
+
+When a not implemented command, such as ":perl", has wrong arguments the less
+important error was reported, giving the user the idea the command could work.
+
+On non-Unix systems autocommands for writing did not attempt a match with the
+short file name, causing a pattern like "a/b" to fail.
+
+VMS: e_screenmode was not defined and a few other fixes for VMS. (Zoltan
+Arpadffy)
+
+redraw_msg() depended on FEAT_ARABIC instead of FEAT_RIGHTLEFT. (Walter
+Briscoe)
+
+Various changes for the PC Makefiles. (Walter Briscoe)
+
+Use _truename() instead of our own code to expand a file name into a full
+path. (Walter Briscoe)
+
+Error in filetype check for /etc/modutils. (Lubomir Host)
+
+Cscope interface: allocated a buffer too small.
+
+Win16: remove a trailing backslash from a path when obtaining the permission
+flags. (Vince Negri)
+
+When searching for tags with case ignored Vim could hang.
+
+When searching directories with a stopdir could get a crash.  Did not
+re-allocate enough memory. (Vince Negri)
+
+A user command may cause a crash.  Don't use the command index when it's
+negative. (Vince Negri)
+
+putenv() didn't work for MingW and Cygwin. (Dan Sharp)
+
+Many functions were common between os_msdos.c and os_win16.c.  Use os_msdos.c
+for compiling the Win16 version and remove the functions from os_win16.c.
+(Vince Negri)
+
+For terminals that behave like an xterm but didn't have a name that is
+recognized, the window title would not always be set.
+
+When syntax highlighting is off ":hardcopy" could still attempt printing
+colors.
+
+Crash when using ":catch" without an argument.  (Servatius Brandt)
+
+Win32: ":n #" doubled the backslashes.
+
+Fixed Arabic shaping for the command line. (Nadim Shaikli)
+
+Avoid splitting up a string displayed on the command line into individual
+characters, it breaks Arabic shaping.
+
+Updated Cygwin and MingW makefiles to use more dependencies. (Dan Sharp)
+
+2html.vim didn't work with 'nomagic' set.
+
+When a local argument list is used and doing ":only" Vim could crash later.
+(Muraoka Taro)
+
+When using "%P" in 'statusline' and the fillchar is "-", a percentage of 3%
+could result in "-3%".  Also avoid changing a space inside a filename to the
+fill character.
+
+MSwin: Handling of backslashes and double quotes for command line arguments
+was not like what other applications do.  (Walter Briscoe)
+
+Test32 sometimes didn't work, because test11.out was written as TEST11.OUT.
+
+Avoid pointer conversions warnings for Borland C 5.5 in dosinst.c and
+uninstal.c.
+
+More improvements for Make_bc3.mak file. (Walter Briscoe)
+
+When ":syn sync linebreaks=1" is used, editing the first line caused a redraw
+of the whole screen.
+
+Making translated messages didn't work, if_perl.xs wasn't found. (Vlad
+Sandrini)
+
+Motif and Athena: moving Vim to the foreground didn't uniconify it.  Use
+XMapRaised() instead of XRaiseWindow(). (Srikanth Sankaran)
+
+When using ":ptag" in a window where 'scrollbind' is set the preview window
+would also have 'scrollbind' set.  Also reset 'foldcolumn' and 'diff'.
+
+Various commands that split a window took over 'scrollbind', which is hardly
+ever desired.  Esp. for "q:" and ":copen".  Mostly reset 'scrollbind' when
+splitting a window.
+
+When 'shellslash' is set in the vimrc file the first entry of ":scriptnames"
+would still have backslashes.  Entries in the quickfix list could also have
+wrong (back)slashes.
+
+Win32: printer dialog texts were not translated. (Yasuhiro Matsumoto)
+
+When using a multi-byte character with a K_SPECIAL byte or a special key code
+with "--remote-send" the received byte sequence was mangled.  Put it in the
+typeahead buffer instead of the input buffer.
+
+Win32: The cursor position was incorrect after changing cursor shape.
+(Yasuhiro Matsumoto).
+
+Win32: When 'encoding' is not the current codepage the title could not be set
+to non-ascii characters.
+
+"vim -d scp://machine/file1 scp://machine/file2" did not work, there was only
+one window.  Fixed the netrw plugin not to wipe out the buffer if it is
+displayed in other windows.
+
+"/$" caused "e" in last column of screen to disappear, a highlighted blank was
+displayed instead.
+
+":s/ *\ze\n//e" removed the line break and introduced arbitrary text.  Was
+using the line count including what matched after the "\ze".
+
+Using the "c" flag with ":s" changed the behavior when a line break is
+replaced and "\@<=" is used.  Without "c" a following match was not found.
+
+":%s/\vA@<=\nB@=//gce" got stuck on "A\nB" when entering "n".
+
+VMS: add HAVE_STRFTIME in the config file. (Zoltan Arpadffy)
+
+When a delete prompts if a delete should continue when yanking is not
+possible, restore msg_silent afterwards.
+
+":sign" did not complain about a missing argument.
+
+When adding or deleting a sign 'hlsearch' highlighting could disappear.
+Use the generic functions for updating signs.
+
+On MS-Windows NT, 2K and XP don't use command.com but cmd.exe for testing.
+Makes the tests work on more systems.
+
+In the DOS tests don't create "/tmp" to avoid an error.
+
+Mac classic: Problems with reading files with CR vs CR/LF.  Rely on the
+library version of fgets() to work correctly for Metrowerks 2.2. (Axel
+Kielhorn)
+
+When typing a password a "*" was shown for each byte instead of for each
+character.  Added multi-byte handling to displaying the stars. (Yasuhiro
+Matsumoto)
+
+When using Perl 5.6 accessing $curbuf doesn't work.  Add an #ifdef to use
+different code for 5.6 and 5.8.  (Dan Sharp)
+
+MingW and Cygwin: Don't strip the debug executable. (Dan Sharp)
+
+An assignment to a variable with curlies that includes "==" doesn't work.
+Skip over the curlies before searching for an "=". (Vince Negri)
+
+When cancelling the selection of alternate matching tags the tag stack index
+could be advanced too far, resulting in an error message when using CTRL-T.
+
+
+Patch 6.1.001
+Problem:    When formatting UTF-8 text it might be wrapped at a space that is
+	    followed by a composing character. (Raphael Finkel)
+	    Also correct a display error for removing a composing char on top
+	    of a space.
+Solution:   Check for a composing character on a space.
+Files:	    src/edit.c, src/misc1.c, src/screen.c
+
+Patch 6.1.002 (extra)
+Problem:    Win32: after a ":popup" command the mouse pointer stays hidden.
+Solution:   Unhide the mouse pointer before showing the menu.
+Files:	    src/gui_w48.c
+
+Patch 6.1.003
+Problem:    When 'laststatus' is zero and there is a vertical split, the
+	    vertical separator is drawn in the command line. (Srikant
+	    Sankaran)
+Solution:   Don't draw the vertical separator where there is no statusline.
+Files:	    src/screen.c
+
+Patch 6.1.004
+Problem:    Unicode 3.2 changes width and composing of a few characters.
+	    (Markus Kuhn)
+Solution:   Adjust the Unicode functions for the character width and composing
+	    characters.
+Files:	    src/mbyte.c
+
+Patch 6.1.005
+Problem:    When using more than 50 items in 'statusline' Vim might crash.
+	    (Steve Hall)
+Solution:   Increment itemcnt in check_stl_option(). (Flemming Madsen)
+Files:	    src/option.c
+
+Patch 6.1.006
+Problem:    When using "P" in Visual mode to put linewise selected text, the
+	    wrong text is deleted. (Jakub Turski)
+Solution:   Put the text before the Visual area and correct the text to be
+	    deleted for the inserted lines.
+	    Also fix that "p" of linewise text in Visual block mode doesn't
+	    work correctly.
+Files:	    src/normal.c, src/ops.c
+
+Patch 6.1.007
+Problem:    Using ":filetype plugin off" when filetype plugins were never
+	    enabled causes an error message. (Yiu Wing)
+Solution:   Use ":silent!" to avoid the error message.
+Files:	    runtime/ftplugof.vim
+
+Patch 6.1.008
+Problem:    The "%" command doesn't ignore \" inside a string, it's seen as
+	    the end of the string. (Ken Clark)
+Solution:   Skip a double quote preceded by an odd number of backslashes.
+Files:	    src/search.c
+
+Patch 6.1.009
+Problem:    Vim crashes when using a huge number for the maxwid value in a
+	    statusline. (Robert M. Nowotniak)
+Solution:   Check for an overflow that makes maxwid negative.
+Files:	    src/buffer.c
+
+Patch 6.1.010
+Problem:    Searching backwards for a question mark with "?\?" doesn't work.
+	    (Alan Isaac)  Same problem in ":s?\??" and ":g?\??".
+Solution:   Change the "\?" in a pattern to "?" when using "?" as delimiter.
+Files:	    src/ex_cmds.c, src/ex_docmd.c, src/proto/regexp.pro, src/regexp.c,
+	    src/search.c, src/syntax.c, src/tag.c
+
+Patch 6.1.011
+Problem:    XIM: doesn't work correctly when 'number' is set.  Also, a focus
+	    problem when selecting candidates.
+Solution:   Fix the XIM problems. (Yasuhiro Matsumoto)
+Files:	    src/mbyte.c, src/screen.c
+
+Patch 6.1.012
+Problem:    A system() call might fail if fread() does CR-LF to LF
+	    translation.
+Solution:   Open the output file in binary mode. (Pavol Huhas)
+Files:	    src/misc1.c
+
+Patch 6.1.013
+Problem:    Win32: The default for 'printexpr' doesn't work when there are
+	    special characters in 'printdevice'.
+Solution:   Add double quotes around the device name. (Mike Williams)
+Files:	    runtime/doc/option.txt, src/option.c
+
+Patch 6.1.014
+Problem:    An operator like "r" used in Visual block mode doesn't use
+	    'virtualedit' when it's set to "block".
+Solution:   Check for 'virtualedit' being active in Visual block mode when the
+	    operator was started.
+Files:	    src/ex_docmd.c, src/globals.h, src/misc2.c, src/normal.c,
+	    src/ops.c, src/undo.c
+
+Patch 6.1.015
+Problem:    After patch 6.1.014 can't compile with tiny features. (Christian
+	    J. Robinson)
+Solution:   Add the missing define of virtual_op.
+Files:	    src/vim.h
+
+Patch 6.1.016 (extra)
+Problem:    Win32: Outputting Hebrew or Arabic text might have a problem with
+	    reversing.
+Solution:   Replace the RevOut() function with ETO_IGNORELANGUAGE. (Ron Aaron)
+Files:	    src/gui_w32.c
+
+Patch 6.1.017
+Problem:    Cygwin: After patch 6.1.012 Still doesn't do binary file I/O.
+	    (Pavol Juhas)
+Solution:   Define BINARY_FILE_IO for Cygwin.
+Files:	    src/os_unix.h
+
+Patch 6.1.018
+Problem:    Error message when using cterm highlighting. (Leonardo Di Lella)
+Solution:   Remove a backslash before a question mark.
+Files:	    runtime/syntax/cterm.vim
+
+Patch 6.1.019 (extra)
+Problem:    Win32: File name is messed up when editing just a drive name.
+	    (Walter Briscoe)
+Solution:   Append a NUL after the drive name. (Vince Negri)
+Files:	    src/os_win32.c
+
+Patch 6.1.020
+Problem:    col("'>") returns a huge number after using Visual line mode.
+Solution:   Return the length of the line instead.
+Files:	    src/eval.c
+
+Patch 6.1.021 (depends on patch 6.1.009)
+Problem:    Vim crashes when using a huge number for the minwid value in a
+	    statusline. (Robert M. Nowotniak)
+Solution:   Check for an overflow that makes minwid negative.
+Files:	    src/buffer.c
+
+Patch 6.1.022
+Problem:    Grabbing the status line above the command-line window works like
+	    the bottom status line was grabbed. (Jim Battle)
+Solution:   Make it possible to grab the status line above the command-line
+	    window, so that it can be resized.
+Files:	    src/ui.c
+
+Patch 6.1.023 (extra)
+Problem:    VMS: running tests doesn't work properly.
+Solution:   Adjust the makefile. (Zoltan Arpadffy)
+Files:	    src/testdir/Make_vms.mms
+
+Patch 6.1.024
+Problem:    When header files use a new syntax for declaring functions, Vim
+	    can't figure out missing prototypes properly.
+Solution:   Accept braces around a function name. (M. Warner Losh)
+Files:	    src/osdef.sh
+
+Patch 6.1.025
+Problem:    Five messages for "vim --help" don't start with a capital. (Vlad
+	    Sandrini)
+Solution:   Make the messages consistent.
+Files:	    src/main.c
+
+Patch 6.1.026
+Problem:    *.patch files are not recognized as diff files.  In a script a
+	    "VAR=val" argument after "env" isn't ignored.  PHP scripts are not
+	    recognized.
+Solution:   Add *.patch for diff filetypes.  Ignore "VAR=val".  Recognize PHP
+	    scripts. (Roman Neuhauser)
+Files:	    runtime/filetype.vim, runtime/scripts.vim
+
+Patch 6.1.027
+Problem:    When 'foldcolumn' is non-zero, a special character that wraps to
+	    the next line disturbs the foldcolumn highlighting.  (Yasuhiro
+	    Matsumoto)
+Solution:   Only use the special highlighting when drawing text characters.
+Files:	    src/screen.c
+
+Patch 6.1.028
+Problem:    Client-server: When a --remote-expr fails, Vim still exits with
+	    status zero.
+Solution:   Exit Vim with a non-zero status to indicate the --remote-expr
+	    failed. (Thomas Scott Urban)
+Files:	    src/main.c
+
+Patch 6.1.029
+Problem:    When 'encoding' is an 8-bit encoding other than "latin1", editing
+	    a utf-8 or other Unicode file uses the wrong conversion. (Jan
+	    Fedak)
+Solution:   Don't use Unicode to latin1 conversion for 8-bit encodings other
+	    than "latin1".
+Files:	    src/fileio.c
+
+Patch 6.1.030
+Problem:    When CTRL-N is mapped in Insert mode, it is also mapped after
+	    CTRL-X CTRL-N, while it is not mapped after CTRL-X CTRL-F.
+	    (Kontra Gergely)
+Solution:   Don't map CTRL-N after CTRL-X CTRL-N.  Same for CTRL-P.
+Files:	    src/getchar.c
+
+Patch 6.1.031
+Problem:    Cygwin: Xxd could read a file in text mode instead of binary mode.
+Solution:   Use "rb" or "rt" when needed. (Pavol Juhas)
+Files:	    src/xxd/xxd.c
+
+Patch 6.1.032
+Problem:    Can't specify a quickfix file without jumping to the first error.
+Solution:   Add the ":cgetfile" command. (Yegappan Lakshmanan)
+Files:	    runtime/doc/index.txt, runtime/doc/quickfix.txt, src/ex_cmds.h,
+	    src/quickfix.c
+
+Patch 6.1.033
+Problem:    GUI: When the selection is lost and the Visual highlighting is
+	    changed to underlining, the cursor is left in a different
+	    position. (Christian Michon)
+Solution:   Update the cursor position after redrawing the selection.
+Files:	    src/ui.c
+
+Patch 6.1.034
+Problem:    A CVS diff file isn't recognized as diff filetype.
+Solution:   Skip lines starting with "? " before checking for an "Index:" line.
+Files:	    runtime/scripts.vim
+
+Patch 6.1.035 (extra, depends on 6.1.016)
+Problem:    Win32: Outputting Hebrew or Arabic text might have a problem with
+	    reversing on MS-Windows 95/98/ME.
+Solution:   Restore the RevOut() function and use it in specific situations
+	    only. (Ron Aaron)
+Files:	    src/gui_w32.c
+
+Patch 6.1.036
+Problem:    This command may cause a crash: ":v/./,//-j". (Ralf Arens)
+Solution:   Compute the right length of the regexp when it's empty.
+Files:	    src/search.c
+
+Patch 6.1.037
+Problem:    When 'lazyredraw' is set, pressing "q" at the hit-enter prompt
+	    causes an incomplete redraw and the cursor isn't positioned.
+	    (Lubomir Host)
+Solution:   Overrule 'lazyredraw' when do_redraw is set.
+Files:	    src/main.c, src/screen.c
+
+Patch 6.1.038
+Problem:    Multi-byte: When a ":s" command contains a multi-byte character
+	    where the trail byte is '~' the text is messed up.
+Solution:   Properly skip multi-byte characters in regtilde() (Muraoka Taro)
+Files:	    src/regexp.c
+
+Patch 6.1.039
+Problem:    When folds are defined and the file is changed outside of Vim,
+	    reloading the file doesn't update the folds. (Anders
+	    Schack-Nielsen)
+Solution:   Recompute the folds after reloading the file.
+Files:	    src/fileio.c
+
+Patch 6.1.040
+Problem:    When changing directory for expanding a file name fails there is
+	    no error message.
+Solution:   Give an error message for this situation.  Don't change directory
+	    if we can't return to the original directory.
+Files:	    src/diff.c, src/ex_docmd.c, src/globals.h, src/misc1.c,
+	    src/os_unix.c
+
+Patch 6.1.041
+Problem:    ":mkvimrc" doesn't handle a mapping that has a leading space in
+	    the rhs. (Davyd Ondrejko)
+Solution:   Insert a CTRL-V before the leading space.  Also display leading
+	    and trailing white space in <> form.
+Files:	    src/getchar.c, src/message.c
+
+Patch 6.1.042
+Problem:    "vim -r" doesn't show all matches when 'wildignore' removes swap
+	    files. (Steve Talley)
+Solution:   Keep all matching swap file names.
+Files:	    src/memline.c
+
+Patch 6.1.043
+Problem:    After patch 6.1.040 a few warnings are produced.
+Solution:   Add a type cast to "char *" for mch_chdir(). (Axel Kielhorn)
+Files:	    src/diff.c, src/ex_docmd.c.c, src/misc1.c, src/os_unix.c
+
+Patch 6.1.044 (extra)
+Problem:    GUI: When using the find/replace dialog with text that contains a
+	    slash, an invalid substitute command is generated.
+	    On Win32 a find doesn't work when 'insertmode' is set.
+Solution:   Escape slashes with a backslash.
+	    Make the Win32, Motif and GTK gui use common code for the
+	    find/replace dialog.
+	    Add the "match case" option for Motif and GTK.
+Files:	    src/feature.h, src/proto/gui.pro, src/gui.c, src/gui.h,
+	    src/gui_motif.c, src/gui_gtk.c, src/gui_w48.c
+
+Patch 6.1.045
+Problem:    In Visual mode, with lots of folds and 'scrolloff' set to 999,
+	    moving the cursor down near the end of the file causes the text to
+	    jump up and down. (Lubomir Host)
+Solution:   Take into account that the cursor may be on the last line of a
+	    closed fold.
+Files:	    src/move.c
+
+Patch 6.1.046
+Problem:    X11 GUI: ":set lsp=2 gcr=n-v-i:hor1-blinkon0" draws a black
+	    rectangle.  ":set lsp=2 gcr=n-v-i:hor10-blinkon0" makes the cursor
+	    disappear.  (Nam SungHyun)
+Solution:   Correctly compute the height of the horizontal cursor.
+Files:	    src/gui_gtk_x11.c, src/gui_x11.c
+
+Patch 6.1.047
+Problem:    When skipping commands after an error was encountered, expressions
+	    for ":if", ";elseif" and ":while" are still evaluated.
+Solution:   Skip the expression after an error. (Servatius Brandt)
+Files:	    src/ex_docmd.c
+
+Patch 6.1.048
+Problem:    Unicode 3.2 changes were missing a few Hangul Jamo characters.
+Solution:   Recognize more characters as composing characters. (Jungshik Shin)
+Files:	    src/mbyte.c
+
+Patch 6.1.049 (extra)
+Problem:    On a 32 bit display a valid color may cause an error message,
+	    because its pixel value is negative. (Chris Paulson-Ellis)
+Solution:   Check for -11111 instead of the color being negative.
+	    Don't add one to the pixel value, -1 may be used for white.
+Files:	    src/globals.h, src/gui.c, src/gui.h, src/gui_amiga.c,
+	    src/gui_athena.c, src/gui_beos.cc, src/gui_gtk_x11.c,
+	    src/gui_mac.c, src/gui_motif.c, src/gui_photon.c,
+	    src/gui_riscos.c, src/gui_w16.c, src/gui_w32.c, src/gui_w48.c,
+	    src/gui_x11.c, src/mbyte.c, src/syntax.c
+
+Patch 6.1.050 (depends on 6.1.049)
+Problem:    After patch 6.1.049 the non-GUI version doesn't compile.
+Solution:   Add an #ifdef FEAT_GUI.  (Robert Stanton)
+Files:	    src/syntax.c
+
+Patch 6.1.051 (depends on 6.1.044)
+Problem:    Doesn't compile with GUI and small features.
+Solution:   Adjust the #if for ga_append().
+Files:	    src/misc2.c
+
+Patch 6.1.052
+Problem:    Unix: The executable() function doesn't work when the "which"
+	    command isn't available.
+Solution:   Go through $PATH manually.  Also makes it work for VMS.
+Files:	    src/os_unix.c
+
+Patch 6.1.053
+Problem:    When 'sessionoptions' contains "globals", or "localoptions" and an
+	    option value contains a line break, the resulting script is wrong.
+Solution:   Use "\n" and "\r" for a line break. (Srinath Avadhanula)
+Files:	    src/eval.c
+
+Patch 6.1.054
+Problem:    GUI: A mouse click is not recognized at the more prompt, even when
+	    'mouse' includes 'r'.
+Solution:   Recognize a mouse click at the more prompt.
+	    Also accept a mouse click in the last line in the GUI.
+	    Add "ml" entry in 'mouseshape'.
+Files:	    src/gui.c, src/message.c, src/misc1.c, src/misc2.c, src/option.c,
+	    src/structs.h
+
+Patch 6.1.055
+Problem:    When editing a compressed file, Vim will inspect the contents to
+	    guess the filetype.
+Solution:   Don't source scripts.vim for .Z, .gz, .bz2, .zip and .tgz files.
+Files:	    runtime/filetype.vim, runtime/plugin/gzip.vim
+
+Patch 6.1.056
+Problem:    Loading the Syntax menu can take quite a bit of time.
+Solution:   Add the "skip_syntax_sel_menu" variable.  When it's defined the
+	    available syntax files are not in the Syntax menu.
+Files:	    runtime/doc/gui.txt, runtime/menu.vim
+
+Patch 6.1.057
+Problem:    An ESC inside a mapping doesn't work as documented when
+	    'insertmode' is set, it does go from Visual or Normal mode to
+	    Insert mode. (Benji Fisher)
+Solution:   Make it work as documented.
+Files:	    src/normal.c
+
+Patch 6.1.058
+Problem:    When there is a closed fold just above the first line in the
+	    window, using CTRL-X CTRL-Y in Insert mode will show only one line
+	    of the fold. (Alexey Marinichev)
+Solution:   Correct the topline by putting it at the start of the fold.
+Files:	    src/move.c
+
+Patch 6.1.059
+Problem:    ":redir > ~/file" doesn't work. (Stephen Rasku)
+Solution:   Expand environment variables in the ":redir >" argument.
+Files:	    src/ex_docmd.c
+
+Patch 6.1.060
+Problem:    When 'virtualedit' is set and 'selection' is "exclusive", deleting
+	    a character just before a tab changes the tab into spaces.  Undo
+	    doesn't restore the tab. (Helmut Stiegler)
+Solution:   Don't replace the tab by spaces when it's not needed.  Correctly
+	    save the line before it's changed.
+Files:	    src/ops.c
+
+Patch 6.1.061
+Problem:    When 'virtualedit' is set and 'selection' is "exclusive", a Visual
+	    selection that ends just after a tab doesn't include that tab in
+	    the highlighting.  (Helmut Stiegler)
+Solution:   Use a different way to exclude the character under the cursor.
+Files:	    src/screen.c
+
+Patch 6.1.062
+Problem:    The "man" filetype plugin doesn't work properly on Solaris 5.
+Solution:   Use a different way to detect that "man -s" should be used. (Hugh
+	    Sasse)
+Files:	    runtime/ftplugin/man.vim
+
+Patch 6.1.063
+Problem:    Java indenting doesn't work properly.
+Solution:   Ignore comments when checking if the indent doesn't increase after
+	    a "}".
+Files:	    runtime/indent/java.vim
+
+Patch 6.1.064
+Problem:    The URLs that the netrw plugin recognized for ftp and rcp did not
+	    conform to the standard method://[user@]host[:port]/path.
+Solution:   Use ftp://[user@]host[[:#]port]/path, which supports both the new
+	    and the previous style.  Also added a bit of dav/cadaver support.
+	    (Charles Campbell)
+Files:	    runtime/plugin/netrw.vim
+
+Patch 6.1.065
+Problem:    VMS: The colorscheme, keymap and compiler menus are not filled in.
+Solution:   Ignore case when looking for ".vim" files. (Coen Engelbarts)
+Files:	    runtime/menu.vim
+
+Patch 6.1.066 (extra)
+Problem:    When calling system() in a plugin reading stdin hangs.
+Solution:   Don't set the terminal to RAW mode when it wasn't in RAW mode
+	    before the system() call.
+Files:	    src/os_amiga.c, src/os_msdos.c, src/os_riscos.c, src/os_unix.c,
+	    src/os_win16.c, src/os_win32.c
+
+Patch 6.1.067
+Problem:    ":set viminfo+=f0" is not working. (Benji Fisher)
+Solution:   Check the "f" flag instead of "'" in 'viminfo'.
+Files:	    src/mark.c
+
+Patch 6.1.068
+Problem:    When a file is reloaded after it was changed outside of Vim, diff
+	    mode isn't updated. (Michael Naumann)
+Solution:   Invalidate the diff info so that it's updated when needed.
+Files:	    src/fileio.c
+
+Patch 6.1.069
+Problem:    When 'showmatch' is set and "$" is in 'cpoptions', using
+	    "C}<Esc>" may forget to remove the "$". (Preben Guldberg)
+Solution:   Restore dollar_vcol after displaying the matching cursor position.
+Files:	    src/search.c
+
+Patch 6.1.070 (depends on 6.1.060)
+Problem:    Compiler warning for signed/unsigned mismatch. (Mike Williams)
+Solution:   Add a typecast to int.
+Files:	    src/ops.c
+
+Patch 6.1.071
+Problem:    When 'selection' is exclusive, g CTRL-G in Visual mode counts one
+	    character too much. (David Necas)
+Solution:   Subtract one from the end position.
+Files:	    src/ops.c
+
+Patch 6.1.072
+Problem:    When a file name in a tags file starts with http:// or something
+	    else for which there is a BufReadCmd autocommand, the file isn't
+	    opened anyway.
+Solution:   Check if there is a matching BufReadCmd autocommand and try to
+	    open the file.
+Files:	    src/fileio.c, src/proto/fileio.pro, src/tag.c
+
+Patch 6.1.073 (extra)
+Problem:    BC5: Can't easily specify a tiny, small, normal, big or huge
+	    version.
+Solution:   Allow selecting the version with the FEATURES variable. (Ajit
+	    Thakkar)
+Files:	    src/Make_bc5.mak
+
+Patch 6.1.074
+Problem:    When 'cdpath' includes "../..", changing to a directory in which
+	    we currently already are doesn't work.  ff_check_visited() adds
+	    the directory both when using it as the root for searching and for
+	    the actual matches. (Stephen Rasku)
+Solution:   Use a separate list for the already searched directories.
+Files:	    src/misc2.c
+
+Patch 6.1.075 (depends on 6.1.072)
+Problem:    Can't compile fileio.c on MS-Windows.
+Solution:   Add a declaration for the "p" pointer. (Madoka Machitani)
+Files:	    src/fileio.c
+
+Patch 6.1.076 (extra)
+Problem:    Macintosh: explorer plugin doesn't work on Mac Classic.
+	    IME doesn't work.  Dialog boxes don't work on Mac OS X
+Solution:   Fix explorer plugin and key modifiers. (Axel Kielhorn)
+	    Fix IME support. (Muraoka Taro)
+	    Disable dialog boxes. (Benji Fisher)
+Files:	    src/edit.c, src/feature.h, src/gui_mac.c, src/os_mac.c
+
+Patch 6.1.077
+Problem:    On a Debian system with ACL linking fails. (Lubomir Host)
+Solution:   When the "acl" library is used, check if the "attr" library is
+	    present and use it.
+Files:	    src/auto/configure, src/configure.in, src/link.sh
+
+Patch 6.1.078
+Problem:    When using 'foldmethod' "marker" and the end marker appears before
+	    the start marker in the file, no fold is found. (Nazri Ramliy)
+Solution:   Don't let the fold depth go negative.
+Files:	    src/fold.c
+
+Patch 6.1.079
+Problem:    When using "s" in Visual block mode with 'virtualedit' set, when
+	    the selected block is after the end of some lines the wrong text
+	    is inserted and some lines are skipped. (Servatius Brandt)
+Solution:   Insert the right text and extend short lines.
+Files:	    src/ops.c
+
+Patch 6.1.080
+Problem:    When using gcc with /usr/local already in the search path, adding
+	    it again causes problems.
+Solution:   Adjust configure.in to avoid adding /usr/local/include and
+	    /usr/local/lib when using GCC and they are already used. (Johannes
+	    Zellner)
+Files:	    src/auto/configure, src/configure.in
+
+Patch 6.1.081
+Problem:    ":help CTRL-\_CTRL-N" doesn't work.  (Christian J. Robinson)
+Solution:   Double the backslash to avoid the special meaning of "\_".
+Files:	    src/ex_cmds.c
+
+Patch 6.1.082
+Problem:    On MS-Windows the vimrc_example.vim script is sourced and then
+	    mswin.vim.  This enables using select mode, but since "p" is
+	    mapped it doesn't replace the selection.
+Solution:   Remove the mapping of "p" from vimrc_example.vim, it's obsolete.
+	    (Vlad Sandrini)
+Files:	    runtime/vimrc_example.vim
+
+Patch 6.1.083
+Problem:    When $LANG is "sk" or "sk_sk", the Slovak menu file isn't found.
+	    (Martin Lacko)
+Solution:   Guess the right menu file based on the system.
+Files:	    runtime/lang/menu_sk_sk.vim
+
+Patch 6.1.084 (depends on 6.1.080)
+Problem:    "include" and "lib" are mixed up when checking the directories gcc
+	    already searches.
+Solution:   Swap the variable names. (SunHo Kim)
+Files:	    src/auto/configure, src/configure.in
+
+Patch 6.1.085
+Problem:    When using CTRL-O CTRL-\ CTRL-N from Insert mode, the displayed
+	    mode "(insert)" isn't removed. (Benji Fisher)
+Solution:   Clear the command line.
+Files:	    src/normal.c
+
+Patch 6.1.086 (depends on 6.1.049)
+Problem:    The guifg color for CursorIM doesn't take effect.
+Solution:   Use the foreground color when it's defined. (Muraoka Taro)
+Files:	    src/gui.c
+
+Patch 6.1.087
+Problem:    A thesaurus with Japanese characters has problems with characters
+	    in different word classes.
+Solution:   Only separate words with single-byte non-word characters.
+	    (Muraoka Taro)
+Files:	    src/edit.c
+
+Patch 6.1.088 (extra)
+Problem:    Win32: no debugging info is generated.  Tags file excludes .cpp
+	    files.
+Solution:   Add "/map" to compiler flags.  Add "*.cpp" to ctags command.
+	    (Muraoka Taro)
+Files:	    src/Make_mvc.mak
+
+Patch 6.1.089
+Problem:    On BSDI systems there is no ss_sp field in stack_t. (Robert Jan)
+Solution:   Use ss_base instead.
+Files:	    src/auto/configure, src/configure.in, src/config.h.in,
+	    src/os_unix.c
+
+Patch 6.1.090
+Problem:    CTRL-F gets stuck when 'scrolloff' is non-zero and there is a mix
+	    of long wrapping lines and a non-wrapping line.
+Solution:   Check that CTRL-F scrolls at least one line.
+Files:	    src/move.c
+
+Patch 6.1.091
+Problem:    GTK: Can't change preeditstate without setting 'imactivatekey'.
+Solution:   Add some code to change preeditstate for OnTheSpot. (Yasuhiro
+	    Matsumoto)
+Files:	    src/mbyte.c
+
+Patch 6.1.092
+Problem:    ":mapclear <buffer>" doesn't work. (Srikanth Adayapalam)
+Solution:   Allow an argument for ":mapclear".
+Files:	    src/ex_cmds.h
+
+Patch 6.1.093 (extra)
+Problem:    Mac and MS-Windows GUI: when scrolling while ":s" is working the
+	    results can be messed up, because the cursor is moved.
+Solution:   Disallow direct scrolling when not waiting for a character.
+Files:	    src/gui_mac.c, src/gui_w16.c, src/gui_w32.c, src/gui_w48.c
+
+Patch 6.1.094
+Problem:    Cygwin: Passing a file name that has backslashes isn't handled
+	    very well.
+Solution:   Convert file name arguments to Posix.  (Chris Metcalf)
+Files:	    src/main.c
+
+Patch 6.1.095
+Problem:    When using signs can free an item on the stack.
+	    Overruling sign colors doesn't work. (Srikanth Sankaran)
+Solution:   Don't free the item on the stack.  Use NULL instead of "none" for
+	    the value of the color.
+Files:	    src/gui_x11.c
+
+Patch 6.1.096
+Problem:    When erasing the right halve of a double-byte character, it may
+	    cause further characters to be erased. (Yasuhiro Matsumoto)
+Solution:   Make sure only one character is erased.
+Files:	    src/screen.c
+
+Patch 6.1.097 (depends on 6.1.090)
+Problem:    When 'scrolloff' is set to a huge value, CTRL-F at the end of the
+	    file scrolls one line. (Lubomir Host)
+Solution:   Don't scroll when CTRL-F detects the end-of-file.
+Files:	    src/move.c
+
+Patch 6.1.098
+Problem:    MS-Windows: When the xxd program is under "c:\program files" the
+	    "Convert to Hex" menu doesn't work. (Brian Mathis)
+Solution:   Put the path to xxd in double quotes.
+Files:	    runtime/menu.vim
+
+Patch 6.1.099
+Problem:    Memory corrupted when closing a fold with more than 99999 lines.
+Solution:   Allocate more space for the fold text. (Walter Briscoe)
+Files:	    src/eval.c
+
+Patch 6.1.100 (extra, depends on 6.1.088)
+Problem:    Win32: VC5 and earlier don't support the /mapinfo option.
+Solution:   Add "/mapinfo" only when "MAP=lines" is specified. (Muraoka Taro)
+Files:	    src/Make_mvc.mak
+
+Patch 6.1.101
+Problem:    After using ":options" the tabstop of a new window is 15.  Entry
+	    in ":options" window for 'autowriteall' is wrong. (Antoine J
+	    Mechelynck)  Can't insert a space in an option value.
+Solution:   Use ":setlocal" instead of ":set".  Change "aw" to "awa".
+	    Don't map space in Insert mode.
+Files:	    runtime/optwin.vim
+
+Patch 6.1.102
+Problem:    Unprintable and multi-byte characters in a statusline item are not
+	    truncated correctly. (Yasuhiro Matsumoto)
+Solution:   Count the width of characters instead of the number of bytes.
+Files:	    src/buffer.c
+
+Patch 6.1.103
+Problem:    A function returning from a while loop, with 'verbose' set to 12
+	    or higher, doesn't mention the return value.  A function with the
+	    'abort' attribute may return -1 while the verbose message says
+	    something else.
+Solution:   Move the verbose message about returning from a function to
+	    call_func(). (Servatius Brandt)
+Files:	    src/eval.c
+
+Patch 6.1.104
+Problem:    GCC 3.1 appears to have an optimizer problem that makes test 3
+	    crash.
+Solution:   For GCC 3.1 add -fno-strength-reduce to avoid the optimizer bug.
+	    Filter out extra info from "gcc --version".
+Files:	    src/auto/configure, src/configure.in
+
+Patch 6.1.105
+Problem:    Win32: The default for 'shellpipe' doesn't redirect stderr. (Dion
+	    Nicolaas)
+Solution:   Redirect stderr, depending on the shell (like for 'shellredir').
+Files:	    src/option.c
+
+Patch 6.1.106
+Problem:    The maze program crashes.
+Solution:   Change "11" to "27" and it works. (Greg Roelofs)
+Files:	    runtime/macros/maze/mazeansi.c
+
+Patch 6.1.107
+Problem:    When 'list' is set the current line in the error window may be
+	    displayed wrong. (Muraoka Taro)
+Solution:   Don't continue the line after the $ has been displayed and the
+	    rightmost column is reached.
+Files:	    src/screen.c
+
+Patch 6.1.108
+Problem:    When interrupting a filter command such as "!!sleep 20" the file
+	    becomes read-only. (Mark Brader)
+Solution:   Only set the read-only flag when opening a buffer is interrupted.
+	    When the shell command was interrupted, read the output that was
+	    produced so far.
+Files:	    src/ex_cmds.c, src/fileio.c
+
+Patch 6.1.109
+Problem:    When 'eadirection' is "hor", using CTRL-W = doesn't equalize the
+	    window heights. (Roman Neuhauser)
+Solution:   Ignore 'eadirection' for CTRL-W =
+Files:	    src/window.c
+
+Patch 6.1.110
+Problem:    When using ":badd file" when "file" is already present but not
+	    listed, it stays unlisted. (David Frey)
+Solution:   Set 'buflisted'.
+Files:	    src/buffer.c
+
+Patch 6.1.111
+Problem:    It's not possible to detect using the Unix sources on Win32 or Mac.
+Solution:   Add has("macunix") and has("win32unix").
+Files:	    runtime/doc/eval.txt, src/eval.c
+
+Patch 6.1.112
+Problem:    When using ":argdo", ":bufdo" or ":windo", CTRL-O doesn't go to
+	    the cursor position from before this command but every position
+	    where the argument was executed.
+Solution:   Only remember the cursor position from before the ":argdo",
+	    ":bufdo" and ":windo".
+Files:	    src/ex_cmds2.c, src/mark.c
+
+Patch 6.1.113
+Problem:    ":bufdo bwipe" only wipes out half the buffers.  (Roman Neuhauser)
+Solution:   Decide what buffer to go to next before executing the command.
+Files:	    src/ex_cmds2.c
+
+Patch 6.1.114
+Problem:    ":python import vim", ":python vim.current.buffer[0:0] = []" gives
+	    a lalloc(0) error. (Chris Southern)
+Solution:   Don't allocate an array when it's size is zero.
+Files:	    src/if_python.c
+
+Patch 6.1.115
+Problem:    "das" on the white space at the end of a paragraph does not delete
+	    the "." the sentence ends with.
+Solution:   Don't exclude the last character when it is not white space.
+Files:	    src/search.c
+
+Patch 6.1.116
+Problem:    When 'endofline' is changed while 'binary' is set a file should be
+	    considered modified. (Olaf Buddenhagen)
+Solution:   Remember the 'eol' value when editing started and consider the
+	    file changed when the current value is different and 'binary' is
+	    set.  Also fix that the window title isn't updated when 'ff' or
+	    'bin' changes.
+Files:	    src/option.c, src/structs.h
+
+Patch 6.1.117
+Problem:    Small problem with editing a file over ftp: and with Cygwin.
+Solution:   Remove a dot from a ":normal" command.  Use "cygdrive" where
+	    appropriate.  (Charles Campbell)
+Files:	    runtime/plugin/netrw.vim
+
+Patch 6.1.118
+Problem:    When a file in diff mode is reloaded because it changed outside
+	    of Vim, other windows in diff mode are not always updated.
+	    (Michael Naumann)
+Solution:   After reloading a file in diff mode mark all windows in diff mode
+	    for redraw.
+Files:	    src/diff.c
+
+Patch 6.1.119 (extra)
+Problem:    With the Sniff interface, using Sniff 4.0.X on HP-UX, there may be
+	    a crash when connecting to Sniff.
+Solution:   Initialize sniff_rq_sep such that its value can be changed.
+	    (Martin Egloff)
+Files:	    src/if_sniff.c
+
+Patch 6.1.120 (depends on 6.1.097)
+Problem:    When 'scrolloff' is non-zero and there are folds, CTRL-F at the
+	    end of the file scrolls part of a closed fold.  (Lubomir Host)
+Solution:   Adjust the first line to the start of a fold.
+Files:	    src/move.c
+
+Patch 6.1.121 (depends on 6.1.098)
+Problem:    When starting Select mode from Insert mode, then using the Paste
+	    menu entry, the cursor is left before the last pasted character.
+	    (Mario Schweigler)
+Solution:   Set the cursor for Insert mode one character to the right.
+Files:	    runtime/menu.vim
+
+Patch 6.1.122
+Problem:    ":file name" creates a new buffer to hold the old buffer name,
+	    which becomes the alternate file.  This buffer is unexpectedly
+	    listed.
+Solution:   Create the buffer for the alternate name unlisted.
+Files:	    src/ex_cmds.c
+
+Patch 6.1.123
+Problem:    A ":match" command with more than one argument doesn't report an
+	    error.
+Solution:   Check for extra characters. (Servatius Brandt)
+Files:	    src/ex_docmd.c
+
+Patch 6.1.124
+Problem:    When trying to exit and there is a hidden buffer that had 'eol'
+	    off and 'bin' set exiting isn't possible. (John McGowan)
+Solution:   Set b_start_eol when clearing the buffer.
+Files:	    src/buffer.c
+
+Patch 6.1.125
+Problem:    Explorer plugin asks for saving a modified buffer even when it's
+	    open in another window as well.
+Solution:   Count the number of windows using the buffer.
+Files:	    runtime/plugin/explorer.vim
+
+Patch 6.1.126
+Problem:    Adding the choices in the syntax menu is consuming much of the
+	    startup time of the GUI while it's not often used.
+Solution:   Only add the choices when the user wants to use them.
+Files:	    Makefile, runtime/makemenu.vim, runtime/menu.vim,
+	    runtime/synmenu.vim, src/Makefile
+
+Patch 6.1.127
+Problem:    When using "--remote file" and the server has 'insertmode' set,
+	    commands are inserted instead of being executed. (Niklas Volbers)
+Solution:   Go to Normal mode again after the ":drop" command.
+Files:	    src/main.c
+
+Patch 6.1.128
+Problem:    The expression "input('very long prompt')" puts the cursor in the
+	    wrong line (column is OK).
+Solution:   Add the wrapped lines to the indent. (Yasuhiro Matsumoto)
+Files:	    src/ex_getln.c
+
+Patch 6.1.129
+Problem:    On Solaris editing "file/" and then "file" results in using the
+	    same buffer.  (Jim Battle)
+Solution:   Before using stat(), check that there is no illegal trailing
+	    slash.
+Files:	    src/auto/configure, src/config.h.in, src/configure.in,
+	    src/macros.h src/misc2.c, src/proto/misc2.pro
+
+Patch 6.1.130
+Problem:    The documentation for some of the 'errorformat' items is unclear.
+Solution:   Add more examples and explain hard to understand items. (Stefan
+	    Roemer)
+Files:	    runtime/doc/quickfix.txt
+
+Patch 6.1.131
+Problem:    X11 GUI: when expanding a CSI byte in the input stream to K_CSI,
+	    the CSI byte itself isn't copied.
+Solution:   Copy the CSI byte.
+Files:	    src/gui_x11.c
+
+Patch 6.1.132
+Problem:    Executing a register in Ex mode may cause commands to be skipped.
+	    (John McGowan)
+Solution:   In Ex mode use an extra check if the register contents was
+	    consumed, to avoid input goes into the typeahead buffer.
+Files:	    src/ex_docmd.c
+
+Patch 6.1.133
+Problem:    When drawing double-wide characters in the statusline, may clear
+	    half of a character. (Yasuhiro Matsumoto)
+Solution:   Force redraw of the next character by setting the attributes
+	    instead of putting a NUL in ScreenLines[].  Do put a NUL in
+	    ScreenLines[] when overwriting half of a double-wide character.
+Files:	    src/screen.c
+
+Patch 6.1.134
+Problem:    An error for a trailing argument of ":match" should not be given
+	    after ":if 0". (Servatius Brandt)
+Solution:   Only do the check when executing commands.
+Files:	    src/ex_docmd.c
+
+Patch 6.1.135
+Problem:    Passing a command to the shell that includes a newline always has
+	    a backslash before the newline.
+Solution:   Remove one backslash before the newline.  (Servatius Brandt)
+Files:	    src/ex_docmd.c
+
+Patch 6.1.136
+Problem:    When $TERM is "linux" the default for 'background' is "dark", even
+	    though the GUI uses a light background. (Hugh Allen)
+Solution:   Don't mark the option as set when defaulting to "dark" for the
+	    linux console.  Also reset 'background' to "light" when the GUI
+	    has a light background.
+Files:	    src/option.c
+
+Patch 6.1.137
+Problem:    Converting to HTML has a clumsy way of dealing with tabs which may
+	    change the highlighting.
+Solution:   Replace tabs with spaces after converting a line to HTML. (Preben
+	    Guldberg)
+Files:	    runtime/syntax/2html.vim
+
+Patch 6.1.138 (depends on 6.1.126)
+Problem:    Adding extra items to the Syntax menu can't be done when the "Show
+	    individual choices" menu is used.
+Solution:   Use ":runtime!" instead of ":source", so that all synmenu.vim
+	    files in the runtime path are loaded. (Servatius Brandt)
+	    Also fix that a translated menu can't be removed.
+Files:	    runtime/menu.vim
+
+Patch 6.1.139
+Problem:    Cygwin: PATH_MAX is not defined.
+Solution:   Include limits.h. (Dan Sharp)
+Files:	    src/main.c
+
+Patch 6.1.140
+Problem:    Cygwin: ":args `ls *.c`" does not work if the shell command
+	    produces CR NL line separators.
+Solution:   Remove the CR characters ourselves. (Pavol Juhas)
+Files:	    src/os_unix.c
+
+Patch 6.1.141
+Problem:    ":wincmd gx" may cause problems when mixed with other commands.
+	    ":wincmd c" doesn't close the window immediately. (Benji Fisher)
+Solution:   Pass the extra command character directly instead of using the
+	    stuff buffer and call ex_close() directly.
+Files:	    src/ex_docmd.c, src/normal.c, src/proto/normal.pro,
+	    src/proto/window.pro, src/window.c
+
+Patch 6.1.142
+Problem:    Defining paragraphs without a separating blank line isn't
+	    possible.  Paragraphs can't be formatted automatically.
+Solution:   Allow defining paragraphs with lines that end in white space.
+	    Added the 'w' and 'a' flags in 'formatoptions'.
+Files:	    runtime/doc/change.txt, src/edit.c, src/misc1.c, src/normal.c,
+	    src/option.h, src/ops.c, src/proto/edit.pro, src/proto/ops.pro,
+	    src/vim.h
+
+Patch 6.1.143 (depends on 6.1.142)
+Problem:    Auto formatting near the end of the file moves the cursor to a
+	    wrong position.  In Insert mode some lines are made one char too
+	    narrow.  When deleting a line undo might not always work properly.
+Solution:   Don't always move to the end of the line in the last line.  Don't
+	    position the cursor past the end of the line in Insert mode.
+	    After deleting a line save the cursor line for undo.
+Files:	    src/edit.c, src/ops.c, src/normal.c
+
+Patch 6.1.144
+Problem:    Obtaining the size of a line in screen characters can be wrong.
+	    A pointer may wrap around zero.
+Solution:   In win_linetabsize() check for a MAXCOL length argument. (Jim
+	    Dunleavy)
+Files:	    src/charset.c
+
+Patch 6.1.145
+Problem:    GTK: Drag&drop with more than 3 files may cause a crash. (Mickael
+	    Marchand)
+Solution:   Rewrite the code that parses the received list of files to be more
+	    robust.
+Files:	    src/charset.c, src/gui_gtk_x11.c
+
+Patch 6.1.146
+Problem:    MS-Windows: When $HOME is constructed from $HOMEDRIVE and
+	    $HOMEPATH, it is not used for storing the _viminfo file.  (Normal
+	    Diamond)
+Solution:   Set $HOME with the value obtained from $HOMEDRIVE and $HOMEPATH.
+Files:	    src/misc1.c
+
+Patch 6.1.147 (extra)
+Problem:    MS-Windows: When a dialog has no default button, pressing Enter
+	    ends it anyway and all buttons are selected.
+Solution:   Don't end a dialog when there is no default button.  Don't select
+	    all button when there is no default. (Vince Negri)
+Files:	    src/gui_w32.c
+
+Patch 6.1.148 (extra)
+Problem:    MS-Windows: ACL is not properly supported.
+Solution:   Add an access() replacement that also works for ACL. (Mike
+	    Williams)
+Files:	    runtime/doc/editing.txt, src/os_win32.c
+
+Patch 6.1.149 (extra)
+Problem:    MS-Windows: Can't use diff mode from the file explorer.
+Solution:   Add a "diff with Vim" context menu entry. (Dan Sharp)
+Files:	    GvimExt/gvimext.cpp, GvimExt/gvimext.h
+
+Patch 6.1.150
+Problem:    OS/2, MS-Windows and MS-DOS: When 'shellslash' is set getcwd()
+	    still uses backslash. (Yegappan Lakshmanan)
+Solution:   Adjust slashes in getcwd().
+Files:	    src/eval.c
+
+Patch 6.1.151 (extra)
+Problem:    Win32: The NTFS substream isn't copied.
+Solution:   Copy the substream when making a backup copy. (Muraoka Taro)
+Files:	    src/fileio.c, src/os_win32.c, src/proto/os_win32.pro
+
+Patch 6.1.152
+Problem:    When $LANG is iso8859-1 translated menus are not used.
+Solution:   Change iso8859 to iso_8859.
+Files:	    runtime/menu.vim
+
+Patch 6.1.153
+Problem:    Searching in included files may search recursively when the path
+	    starts with "../".  (Sven Berkvens-Matthijsse)
+Solution:   Compare full file names, use inode/device when possible.
+Files:	    src/search.c
+
+Patch 6.1.154 (extra)
+Problem:    DJGPP: "vim -h" leaves the cursor in a wrong position.
+Solution:   Don't position the cursor using uninitialized variables. (Jim
+	    Dunleavy)
+Files:	    src/os_msdos.c
+
+Patch 6.1.155
+Problem:    Win32: Cursor may sometimes disappear in Insert mode.
+Solution:   Change "hor10" in 'guicursor' to "hor15". (Walter Briscoe)
+Files:	    src/option.c
+
+Patch 6.1.156
+Problem:    Conversion between DBCS and UCS-2 isn't implemented cleanly.
+Solution:   Clean up a few things.
+Files:	    src/mbyte.c, src/structs.h
+
+Patch 6.1.157
+Problem:    'hlsearch' highlights only the second comma in ",,,,," with
+	    "/,\@<=[^,]*". (Preben Guldberg)
+Solution:   Also check for an empty match to start just after a previous
+	    match.
+Files:	    src/screen.c
+
+Patch 6.1.158
+Problem:    "zs" and "ze" don't work correctly with ":set nowrap siso=1".
+	    (Preben Guldberg)
+Solution:   Take 'siso' into account when computing the horizontal scroll
+	    position for "zs" and "ze".
+Files:	    src/normal.c
+
+Patch 6.1.159
+Problem:    When expanding an abbreviation that includes a multi-byte
+	    character too many characters are deleted. (Andrey Urazov)
+Solution:   Delete the abbreviation counting characters instead of bytes.
+Files:	    src/getchar.c
+
+Patch 6.1.160
+Problem:    ":$read file.gz" doesn't work. (Preben Guldberg)
+Solution:   Don't use the '[ mark after it has become invalid.
+Files:	    runtime/plugin/gzip.vim
+
+Patch 6.1.161 (depends on 6.1.158)
+Problem:    Warning for signed/unsigned compare.  Can set 'siso' to a negative
+	    value. (Mike Williams)
+Solution:   Add a typecast.  Add a check for 'siso' being negative.
+Files:	    src/normal.c, src/option.c
+
+Patch 6.1.162
+Problem:    Python interface: Didn't initialize threads properly.
+Solution:   Call PyEval_InitThreads() when starting up.
+Files:	    src/if_python.c
+
+Patch 6.1.163
+Problem:    Win32: Can't compile with Python after 6.1.162.
+Solution:   Dynamically load  PyEval_InitThreads(). (Dan Sharp)
+Files:	    src/if_python.c
+
+Patch 6.1.164
+Problem:    If 'modifiable' is off, converting to xxd fails and 'filetype' is
+	    changed to "xxd" anyway.
+Solution:   Don't change 'filetype' when conversion failed.
+Files:	    runtime/menu.vim
+
+Patch 6.1.165
+Problem:    Making changes in several lines and then a change in one of these
+	    lines that splits it in two or more lines, undo information was
+	    corrupted.  May cause a crash. (Dave Fishburn)
+Solution:   When skipping to save a line for undo because it was already
+	    saved, move it to become the last saved line, so that when the
+	    command changes the line count other saved lines are not involved.
+Files:	    src/undo.c
+
+Patch 6.1.166
+Problem:    When 'autoindent' is set and mswin.vim has been sourced, pasting
+	    with CTRL-V just after auto-indenting removes the indent. (Shlomi
+	    Fish)
+Solution:   First insert an "x" and delete it again, so that the auto-indent
+	    remains.
+Files:	    runtime/mswin.vim
+
+Patch 6.1.167
+Problem:    When giving a negative argument to ":retab" strange things start
+	    happening. (Hans Ginzel)
+Solution:   Check for a negative value.
+Files:	    src/ex_cmds.c
+
+Patch 6.1.168
+Problem:    Pressing CTRL-C at the hit-enter prompt doesn't end the prompt.
+Solution:   Make CTRL-C stop the hit-enter prompt.
+Files:	    src/message.c
+
+Patch 6.1.169
+Problem:    bufexists() finds a buffer by using the name of a symbolic link to
+	    it, but bufnr() doesn't. (Yegappan Lakshmanan)
+Solution:   When bufnr() can't find a buffer, try using the same method as
+	    bufexists().
+Files:	    src/eval.c
+
+Patch 6.1.170
+Problem:    Using ":mksession" uses the default session file name, but "vim
+	    -S" doesn't. (Hans Ginzel)
+Solution:   Use the default session file name if "-S" is the last command
+	    line argument or another option follows.
+Files:	    runtime/doc/starting.txt, src/main.c
+
+Patch 6.1.171
+Problem:    When opening a line just above a closed fold with "O" and the
+	    comment leader is automatically inserted, the cursor is displayed
+	    in the first column. (Sung-Hyun Nam)
+Solution:   Update the flag that indicates the cursor is in a closed fold.
+Files:	    src/misc1.c
+
+Patch 6.1.172
+Problem:    Command line completion of ":tag /pat" does not show the same
+	    results as the tags the command actually finds. (Gilles Roy)
+Solution:   Don't modify the pattern to make it a regexp.
+Files:	    src/ex_getln.c, src/tag.c
+
+Patch 6.1.173
+Problem:    When using remote control to edit a position in a file and this
+	    file is the current buffer and it's modified, the window is split
+	    and the ":drop" command fails.
+Solution:   Don't split the window, keep editing the same buffer.
+	    Use the ":drop" command in VisVim to avoid the problem there.
+Files:	    src/ex_cmds.c, src/ex_cmds2.c, src/proto/ex_cmds2.pro,
+	    VisVim/Commands.cpp
+
+Patch 6.1.174
+Problem:    It is difficult to know in a script whether an option not only
+	    exists but really works.
+Solution:   Add "exists('+option')".
+Files:	    runtime/doc/eval.txt, src/eval.c
+
+Patch 6.1.175
+Problem:    When reading commands from a pipe and a CTRL-C is pressed, Vim
+	    will hang. (Piet Delport)
+Solution:   Don't keep reading characters to clear typeahead when an interrupt
+	    was detected, stop when a single CTRL-C is read.
+Files:	    src/getchar.c, src/ui.c
+
+Patch 6.1.176
+Problem:    When the stack limit is very big a false out-of-stack error may
+	    be detected.
+Solution:   Add a check for overflow of the stack limit computation. (Jim
+	    Dunleavy)
+Files:	    src/os_unix.c
+
+Patch 6.1.177 (depends on 6.1.141)
+Problem:    ":wincmd" does not allow a following command. (Gary Johnson)
+Solution:   Check for a following " | cmd".  Also give an error for trailing
+	    characters.
+Files:	    src/ex_docmd.c
+
+Patch 6.1.178
+Problem:    When 'expandtab' is set "r<C-V><Tab>" still expands the Tab.
+	    (Bruce deVisser)
+Solution:   Replace with a literal Tab.
+Files:	    src/normal.c
+
+Patch 6.1.179 (depends on 6.1.091)
+Problem:    When using X11R5 XIMPreserveState is undefined. (Albert Chin)
+Solution:   Include the missing definitions.
+Files:	    src/mbyte.c
+
+Patch 6.1.180
+Problem:    Use of the GUI code for forking is inconsistent.
+Solution:   Define MAY_FORK and use it for later #ifdefs. (Ben Fowlwer)
+Files:	    src/gui.c
+
+Patch 6.1.181
+Problem:    If the terminal doesn't wrap from the last char in a line to the
+	    next line, the last column is blanked out. (Peter Karp)
+Solution:   Don't output a space to mark the wrap, but the same character
+	    again.
+Files:	    src/screen.c
+
+Patch 6.1.182 (depends on 6.1.142)
+Problem:    It is not possible to auto-format comments only. (Moshe Kaminsky)
+Solution:   When the 'a' and 'c' flags are in 'formatoptions' only auto-format
+	    comments.
+Files:	    runtime/doc/change.txt, src/edit.c
+
+Patch 6.1.183
+Problem:    When 'fencs' is empty and 'enc' is utf-8, reading a file with
+	    illegal bytes gives "CONVERSION ERROR" even though no conversion
+	    is done.  'readonly' is set, even though writing the file results
+	    in an unmodified file.
+Solution:   For this specific error use "ILLEGAL BYTE" and don't set
+	    'readonly'.
+Files:	    src/fileio.c
+
+Patch 6.1.184 (extra)
+Problem:    The extra mouse buttons found on some mice don't work.
+Solution:   Support two extra buttons for MS-Windows. (Michael Geddes)
+Files:	    runtime/doc/term.txt, src/edit.c, src/ex_getln.c, src/gui.c,
+	    src/gui_w32.c, src/gui_w48.c, src/keymap.h, src/message.c,
+	    src/misc1.c, src/misc2.c, src/normal.c, src/vim.h
+
+Patch 6.1.185 (depends on 6.1.182)
+Problem:    Can't compile without +comments feature.
+Solution:   Add #ifdef FEAT_COMMENTS. (Christian J. Robinson)
+Files:	    src/edit.c
+
+Patch 6.1.186 (depends on 6.1.177)
+Problem:    ":wincmd" does not allow a following comment. (Aric Blumer)
+Solution:   Check for a following double quote.
+Files:	    src/ex_docmd.c
+
+Patch 6.1.187
+Problem:    Using ":doarg" with 'hidden' set and the current file is the only
+	    argument and was modified gives an error message. (Preben
+	    Guldberg)
+Solution:   Don't try re-editing the same file.
+Files:	    src/ex_cmds2.c
+
+Patch 6.1.188 (depends on 6.1.173)
+Problem:    Unused variable in the small version.
+Solution:   Move the declaration for "p" inside #ifdef FEAT_LISTCMDS.
+Files:	    src/ex_cmds2.c
+
+Patch 6.1.189
+Problem:    inputdialog() doesn't work when 'c' is in 'guioptions'. (Aric
+	    Blumer)
+Solution:   Fall back to the input() function in this situation.
+Files:	    src/eval.c
+
+Patch 6.1.190 (extra)
+Problem:    VMS: doesn't build with GTK GUI.  Various other problems.
+Solution:   Fix building for GTK.  Improved Perl, Python and TCL support.
+	    Improved VMS documentation. (Zoltan Arpadffy)
+	    Added Vimtutor for VMS (T. R. Wyant)
+Files:	    runtime/doc/os_vms.txt, src/INSTALLvms.txt, src/gui_gtk_f.h,
+	    src/if_tcl.c, src/main.c, src/gui_gtk_vms.h, src/Make_vms.mms,
+	    src/os_vms.opt, src/proto/if_tcl.pro, vimtutor.com,
+	    src/testdir/Make_vms.mms
+
+Patch 6.1.191
+Problem:    When using "vim -s script" and redirecting the output, the delay
+	    for the "Output is not to a terminal" warning slows Vim down too
+	    much.
+Solution:   Don't delay when reading commands from a script.
+Files:	    src/main.c
+
+Patch 6.1.192
+Problem:    ":diffsplit" doesn't add "hor" to 'scrollopt'. (Gary Johnson)
+Solution:   Add "hor" to 'scrollopt' each time ":diffsplit" is used.
+Files:	    src/diff.c, src/main.c
+
+Patch 6.1.193
+Problem:    Crash in in_id_list() for an item with a "containedin" list. (Dave
+	    Fishburn)
+Solution:   Check for a negative syntax id, used for keywords.
+Files:	    src/syntax.c
+
+Patch 6.1.194
+Problem:    When "t_ti" is set but it doesn't cause swapping terminal pages,
+	    "ZZ" may cause the shell prompt to appear on top of the file-write
+	    message.
+Solution:   Scroll the text up in the Vim page before swapping to the terminal
+	    page. (Michael Schroeder)
+Files:	    src/os_unix.c
+
+Patch 6.1.195
+Problem:    The quickfix and preview windows always keep their height, while
+	    other windows can't fix their height.
+Solution:   Add the 'winfixheight' option, so that a fixed height can be
+	    specified for any window.  Also fix that the wildmenu may resize a
+	    one-line window to a two-line window if 'ls' is zero.
+Files:	    runtime/doc/options.txt, runtime/optwin.vim, src/ex_cmds.c,
+	    src/ex_getln.c, src/globals.h, src/option.c, src/quickfix.c,
+	    src/screen.c, src/structs.h, src/window.c
+
+Patch 6.1.196  (depends on 6.1.084)
+Problem:    On Mac OS X 10.2 generating osdef.h fails.
+Solution:   Add -no-cpp-precomp to avoid using precompiled header files, which
+	    disables printing the search path. (Ben Fowler)
+Files:	    src/auto/configure, src/configure.in
+
+Patch 6.1.197
+Problem:    ":help <C-V><C-\><C-V><C-N>" (resulting in <1c><0e>) gives an
+	    error message. (Servatius Brandt)
+Solution:   Double the backslash in "CTRL-\".
+Files:	    src/ex_cmds.c
+
+Patch 6.1.198 (extra) (depends on 6.1.076)
+Problem:    Mac OS X: Dialogues don't work.
+Solution:   Fix a crashing problem for some GUI dialogues.  Fix a problem when
+	    saving to a new file from the GUI. (Peter Cucka)
+Files:	    src/feature.h, src/gui_mac.c
+
+Patch 6.1.199
+Problem:    'guifontwide' doesn't work on Win32.
+Solution:   Output each wide character separately. (Michael Geddes)
+Files:	    src/gui.c
+
+Patch 6.1.200
+Problem:    ":syn sync fromstart" is not skipped after ":if 0".  This can make
+	    syntax highlighting very slow.
+Solution:   Check "eap->skip" appropriately. (Rob West)
+Files:	    src/syntax.c
+
+Patch 6.1.201 (depends on 6.1.192)
+Problem:    Warning for illegal pointer combination. (Zoltan Arpadffy)
+Solution:   Add a typecast.
+Files:	    src/diff.c
+
+Patch 6.1.202  (extra)(depends on 6.1.148)
+Problem:    Win32: filewritable() doesn't work properly on directories.
+Solution:   fix filewritable(). (Mike Williams)
+Files:	    src/os_win32.c
+
+Patch 6.1.203
+Problem:    ":%s/~//" causes a crash after ":%s/x//". (Gary Holloway)
+Solution:   Avoid reading past the end of a line when "~" is empty.
+Files:	    src/regexp.c
+
+Patch 6.1.204 (depends on 6.1.129)
+Problem:    Warning for an illegal pointer on Solaris.
+Solution:   Add a typecast. (Derek Wyatt)
+Files:	    src/misc2.c
+
+Patch 6.1.205
+Problem:    The gzip plugin changes the alternate file when editing a
+	    compressed file. (Oliver Fuchs)
+Solution:   Temporarily remove the 'a' and 'A' flags from 'cpo'.
+Files:	    runtime/plugin/gzip.vim
+
+Patch 6.1.206
+Problem:    The script generated with ":mksession" doesn't work properly when
+	    some commands are mapped.
+Solution:   Use ":normal!" instead of ":normal".  And use ":wincmd" where
+	    possible. (Muraoka Taro)
+Files:	    src/ex_docmd.c, src/fold.c
+
+Patch 6.1.207
+Problem:    Indenting a Java file hangs below a line with a comment after a
+	    command.
+Solution:   Break out of a loop. (Andre Pang)
+	    Also line up } with matching {.
+Files:	    runtime/indent/java.vim
+
+Patch 6.1.208
+Problem:    Can't use the buffer number from the Python interface.
+Solution:   Add buffer.number. (Michal Vitecek)
+Files:	    src/if_python.c
+
+Patch 6.1.209
+Problem:    Printing doesn't work on Mac OS classic.
+Solution:   Use a ":" for path separator when opening the resource file. (Axel
+	    Kielhorn)
+Files:	    src/ex_cmds2.c
+
+Patch 6.1.210
+Problem:    When there is an iconv() conversion error when reading a file
+	    there can be an error the next time iconv() is used.
+Solution:   Reset the state of the iconv() descriptor. (Yasuhiro Matsumoto)
+Files:	    src/fileio.c
+
+Patch 6.1.211
+Problem:    The message "use ! to override" is confusing.
+Solution:   Make it "add ! to override".
+Files:	    src/buffer.c, src/eval.c, src/ex_docmd.c, src/fileio.c,
+	    src/globals.h
+
+Patch 6.1.212
+Problem:    When Vim was started with "-R" ":new" creates a buffer
+	    'noreadonly' while ":enew" has 'readonly' set. (Preben Guldberg)
+Solution:   Don't set 'readonly in a new empty buffer for ":enew".
+Files:	    src/ex_docmd.c
+
+Patch 6.1.213
+Problem:    Using CTRL-W H may cause a big gap to appear below the last
+	    window. (Aric Blumer)
+Solution:   Don't set the window height when there is a vertical split.
+	    (Yasuhiro Matsumoto)
+Files:	    src/window.c
+
+Patch 6.1.214
+Problem:    When installing Vim and the runtime files were checked out from
+	    CVS the CVS directories will also be installed.
+Solution:   Avoid installing the CVS dirs and their contents.
+Files:	    src/Makefile
+
+Patch 6.1.215
+Problem:    Win32: ":pwd" uses backslashes even when 'shellslash' is set.
+	    (Xiangjiang Ma)
+Solution:   Adjust backslashes before printing the message.
+Files:	    src/ex_docmd.c
+
+Patch 6.1.216
+Problem:    When dynamically loading the iconv library, the error codes may be
+	    confused.
+Solution:   Use specific error codes for iconv and redefine them for dynamic
+	    loading. (Yasuhiro Matsumoto)
+Files:	    src/fileio.c, src/mbyte.c, src/vim.h
+
+Patch 6.1.217
+Problem:    When sourcing the same Vim script using a different name (symbolic
+	    link or MS-Windows 8.3 name) it is listed twice with
+	    ":scriptnames".  (Tony Mechelynck)
+Solution:   Turn the script name into a full path before using it.  On Unix
+	    compare inode/device numbers.
+Files:	    src/ex_cmds2.c
+
+Patch 6.1.218
+Problem:    No error message for using the function argument "5+".  (Servatius
+	    Brandt)
+Solution:   Give an error message if a function or variable is expected but is
+	    not found.
+Files:	    src/eval.c
+
+Patch 6.1.219
+Problem:    When using ":amenu :b 1<CR>" with a Visual selection and
+	    'insertmode' is set, Vim does not return to Insert mode. (Mickael
+	    Marchand)
+Solution:   Add the command CTRL-\ CTRL-G that goes to Insert mode if
+	    'insertmode' is set and to Normal mode otherwise.  Append this to
+	    menus defined with ":amenu".
+Files:	    src/edit.c, src/ex_getln.c, src/normal.c
+
+Patch 6.1.220
+Problem:    When using a BufReadPost autocommand that changes the line count,
+	    e.g., "$-1join", reloading a file that was changed outside Vim
+	    does not work properly. (Alan G Isaac)
+Solution:   Make the buffer empty before reading the new version of the file.
+	    Save the lines in a dummy buffer, so that they can be put back
+	    when reading the file fails.
+Files:	    src/buffer.c, src/ex_cmds.c, src/fileio.c, src/globals.h,
+	    src/proto/buffer.pro
+
+Patch 6.1.221
+Problem:    Changing case may not work properly, depending on the current
+	    locale.
+Solution:   Add the 'casemap' option to let the user chose how changing case
+	    is to be done.
+	    Also fix lowering case when an UTF-8 character doesn't keep the
+	    same byte length.
+Files:	    runtime/doc/options.txt, src/ascii.h, src/auto/configure,
+	    src/buffer.c, src/charset.c, src/config.h.in, src/configure.in,
+	    src/diff.c, src/edit.c, src/eval.c, src/ex_cmds2.c,
+	    src/ex_docmd.c, src/ex_getln.c, src/fileio.c, src/gui_amiga.c
+	    src/gui_mac.c, src/gui_photon.c, src/gui_w48.c, src/gui_beos.cc,
+	    src/macros.h, src/main.c, src/mbyte.c, src/menu.c, src/message.c,
+	    src/misc1.c, src/misc2.c, src/option.c, src/os_msdos.c,
+	    src/os_mswin.c, src/proto/charset.pro, src/regexp.c, src/option.h,
+	    src/syntax.c
+
+Patch 6.1.222 (depends on 6.1.219)
+Problem:    Patch 6.1.219 was incomplete.
+Solution:   Add the changes for ":amenu".
+Files:	    src/menu.c
+
+Patch 6.1.223 (extra)
+Problem:    Win32: When IME is activated 'iminsert' is set, but it might never
+	    be reset when IME is disabled. (Muraoka Taro)
+	    All systems: 'iminsert' is set to 2 when leaving Insert mode, even
+	    when langmap is being used. (Peter Valach)
+Solution:   Don't set "b_p_iminsert" in _OnImeNotify(). (Muraoka Taro)
+	    Don't store the status of the input method in 'iminsert' when
+	    'iminsert' is one.  Also for editing the command line and for
+	    arguments to Normal mode commands.
+Files:	    src/edit.c, src/ex_getln.c, src/gui_w32.c, src/normal.c
+
+Patch 6.1.224
+Problem:    "expand('$VAR')" returns an empty string when the expanded $VAR
+	    is not an existing file. (Aric Blumer)
+Solution:   Included non-existing files, as documented.
+Files:	    src/eval.c
+
+Patch 6.1.225
+Problem:    Using <C-O><C-^> in Insert mode has a delay when starting "vim -u
+	    NONE" and ":set nocp hidden". (Emmanuel)  do_ecmd() uses
+	    fileinfo(), the redraw is done after a delay to give the user time
+	    to read the message.
+Solution:   Put the message from fileio() in "keep_msg", so that the redraw is
+	    done before the delay (still needed to avoid the mode message
+	    overwrites the fileinfo() message).
+Files:	    src/buffer.c
+
+Patch 6.1.226
+Problem:    Using ":debug" with a ":normal" command may cause a hang.  (Colin
+	    Keith)
+Solution:   Save the typeahead buffer when obtaining a debug command.
+Files:	    src/ex_cmds2.c, src/getchar.c, src/proto/getchar.pro
+
+Patch 6.1.227
+Problem:    It is possible to use a variable name "asdf:asdf" and ":let j:asdf
+	    = 5" does not give an error message. (Mikolaj Machowski)
+Solution:   Check for a ":" inside the variable name.
+Files:	    src/eval.c
+
+Patch 6.1.228 (extra)
+Problem:    Win32: The special output function for Hangul is used too often,
+	    causing special handling for other situations to be skipped.
+	    bInComposition is always FALSE, causing ImeGetTempComposition()
+	    always to return NULL.
+Solution:   Remove HanExtTextOut().  Delete the dead code around
+	    bInComposition and ImeGetTempComposition().
+Files:	    src/gui_w16.c, src/gui_w32.c, src/gui_w48.c
+
+Patch 6.1.229
+Problem:    Win32: Conversion to/from often used codepages requires the iconv
+	    library, which is not always available.
+Solution:   Use standard MS-Windows functions for the conversion when
+	    possible. (mostly by Glenn Maynard)
+	    Also fixes missing declaration for patch 6.1.220.
+Files:	    src/fileio.c
+
+Patch 6.1.230 (extra)
+Problem:    Win16: building doesn't work.
+Solution:   Exclude the XBUTTON handling. (Vince Negri)
+Files:	    src/gui_w48.c
+
+Patch 6.1.231
+Problem:    Double clicking with the mouse to select a word does not work for
+	    multi-byte characters.
+Solution:   Use vim_iswordc() instead of vim_isIDc().  This means 'iskeyword'
+	    is used instead of 'isident'.  Also fix that mixing ASCII with
+	    multi-byte word characters doesn't work, the mouse class for
+	    punctuation and word characters was mixed up.
+Files:	    src/normal.c
+
+Patch 6.1.232 (depends on 6.1.226)
+Problem:    Using ex_normal_busy while it might not be available. (Axel
+	    Kielhorn)
+Solution:   Only use ex_normal_busy when FEAT_EX_EXTRA is defined.
+Files:	    src/ex_cmds2.c
+
+Patch 6.1.233
+Problem:    ":help expr-||" does not work.
+Solution:   Don't use the '|' as a command separator
+Files:	    src/ex_cmds.c
+
+Patch 6.1.234 (depends on 6.1.217)
+Problem:    Get a warning for using a negative value for st_dev.
+Solution:   Don't assign a negative value to st_dev.
+Files:	    src/ex_cmds2.c
+
+Patch 6.1.235 (depends on 6.1.223)
+Problem:    'iminsert' is changed from 1 to 2 when leaving Insert mode. (Peter
+	    Valach)
+Solution:   Check "State" before resetting it to NORMAL.
+Files:	    src/edit.c
+
+Patch 6.1.236
+Problem:    Memory leaks when appending lines for ":diffget" or ":diffput" and
+	    when reloading a changed buffer.
+Solution:   Free a line after calling ml_append().
+Files:	    src/diff.c, src/fileio.c
+
+Patch 6.1.237
+Problem:    Putting in Visual block mode does not work correctly when "$" was
+	    used or when the first line is short.  (Christian Michon)
+Solution:   First delete the selected text and then put the new text.  Save
+	    and restore registers as necessary.
+Files:	    src/globals.h, src/normal.c, src/ops.c, src/proto/ops.pro,
+	    src/vim.h
+
+Patch 6.1.238 (extra)
+Problem:    Win32: The "icon=" argument for the ":menu" command does not
+	    search for the bitmap file.
+Solution:   Expand environment variables and search for the bitmap file.
+	    (Vince Negri)
+	    Make it consistent, use the same mechanism for X11 and GTK.
+Files:	    src/gui.c src/gui_gtk.c, src/gui_w32.c, src/gui_x11.c,
+	    src/proto/gui.pro
+
+Patch 6.1.239
+Problem:    Giving an error for missing :endif or :endwhile when being
+	    interrupted.
+Solution:   Don't give these messages when interrupted.
+Files:	    src/ex_docmd.c, src/os_unix.c
+
+Patch 6.1.240 (extra)
+Problem:    Win32 with BCC 5: CPU may be defined in the environment, which
+	    causes a wrong argument for the compiler. (Walter Briscoe)
+Solution:   Use CPUNR instead of CPU.
+Files:	    src/Make_bc5.mak
+
+Patch 6.1.241
+Problem:    Something goes wrong when drawing or undrawing the cursor.
+Solution:   Remember when the cursor invalid in a better way.
+Files:	    src/gui.c
+
+Patch 6.1.242
+Problem:    When pasting a large number of lines on the command line it is not
+	    possible to interrupt. (Jean Jordaan)
+Solution:   Check for an interrupt after each pasted line.
+Files:	    src/ops.c
+
+Patch 6.1.243 (extra)
+Problem:    Win32: When the OLE version is started and wasn't registered, a
+	    message pops up to suggest registering, even when this isn't
+	    possible (when the registry is not writable).
+Solution:   Check if registering is possible before asking whether it should
+	    be done. (Walter Briscoe)
+	    Also avoid restarting Vim after registering.
+Files:	    src/if_ole.cpp
+
+Patch 6.1.244
+Problem:    Patch 6.1.237 was missing the diff for vim.h. (Igor Goldenberg)
+Solution:   Include it here.
+Files:	    src/vim.h
+
+Patch 6.1.245
+Problem:    Comparing with ignored case does not work properly for Unicode
+	    with a locale where case folding an ASCII character results in a
+	    multi-byte character. (Glenn Maynard)
+Solution:   Handle ignore-case compare for Unicode differently.
+Files:	    src/mbyte.c
+
+Patch 6.1.246
+Problem:    ":blast" goes to the first buffer if the last one is unlisted.
+	    (Andrew Stryker)
+Solution:   From the last buffer search backwards for the first listed buffer
+	    instead of forwards.
+Files:	    src/ex_docmd.c
+
+Patch 6.1.247
+Problem:    ACL support doesn't always work properly.
+Solution:   Add a configure argument to disable ACL "--disable-acl". (Thierry
+	    Vignaud)
+Files:	    src/auto/configure, src/configure.in
+
+Patch 6.1.248
+Problem:    Typing 'q' at the more-prompt for ":let" does not quit the
+	    listing. (Hari Krishna Dara)
+Solution:   Quit the listing when got_int is set.
+Files:	    src/eval.c
+
+Patch 6.1.249
+Problem:    Can't expand a path on the command line if it includes a "|" as a
+	    trail byte of a multi-byte character.
+Solution:   Check for multi-byte characters. (Yasuhiro Matsumoto)
+Files:	    src/ex_docmd.c
+
+Patch 6.1.250
+Problem:    When changing the value of 'lines' inside the expression set with
+	    'diffexpr' Vim might crash. (Dave Fishburn)
+Solution:   Don't allow changing the screen size while updating the screen.
+Files:	    src/globals.h, src/option.c, src/screen.c
+
+Patch 6.1.251
+Problem:    Can't use completion for ":lcd" and ":lchdir" like ":cd".
+Solution:   Expand directory names for these commands. (Servatius Brandt)
+Files:	    src/ex_docmd.c
+
+Patch 6.1.252
+Problem:    "vi}" does not include a line break when the "}" is at the start
+	    of a following line. (Kamil Burzynski)
+Solution:   Include the line break.
+Files:	    src/search.c
+
+Patch 6.1.253 (extra)
+Problem:    Win32 with Cygwin: Changes the path of arguments in a wrong way.
+	    (Xiangjiang Ma)
+Solution:   Don't use cygwin_conv_to_posix_path() for the Win32 version.
+	    Update the Cygwin makefile to support more features.  (Dan Sharp)
+Files:	    src/Make_cyg.mak, src/if_ole.cpp, src/main.c
+
+Patch 6.1.254
+Problem:    exists("foo{bar}") does not work.  ':unlet v{"a"}r' does not work.
+	    ":let v{a}r1 v{a}r2" does not work. ":func F{(1)}" does not work.
+	    ":delfunc F{" does not give an error message.  ':delfunc F{"F"}'
+	    does not work.
+Solution:   Support magic braces for the exists() argument. (Vince Negri)
+	    Check for trailing comments explicitly for ":unlet".  Add support
+	    for magic braces in further arguments of ":let".  Look for a
+	    parenthesis only after the function name.  (Servatius Brandt)
+	    Also expand magic braces for "exists('*expr')".  Give an error
+	    message for an invalid ":delfunc" argument.  Allow quotes in the
+	    ":delfunc" argument.
+Files:	    src/eval.c, src/ex_cmds.h, src/ex_docmd.c
+
+Patch 6.1.255 (depends on 6.1.254)
+Problem:    Crash when loading menu.vim a second time. (Christian Robinson)
+	    ":unlet garbage foo" tries unletting "foo" after an error message.
+	    (Servatius Brandt)
+	    Very long function arguments cause very long messages when
+	    'verbose' is 14 or higher.
+Solution:   Avoid reading from uninitialized memory.
+	    Break out of a loop after an invalid argument for ":unlet".
+	    Truncate long function arguments to 80 characters.
+Files:	    src/eval.c
+
+Patch 6.1.256 (depends on 6.1.255)
+Problem:    Defining a function after ":if 0" could still cause an error
+	    message for an existing function.
+	    Leaking memory when there are trailing characters for ":delfunc".
+Solution:   Check the "skip" flag.  Free the memory. (Servatius Brandt)
+Files:	    src/eval.c
+
+Patch 6.1.257
+Problem:    ":cwindow" always sets the previous window to the last but one
+	    window.  (Benji Fisher)
+Solution:   Set the previous window properly.
+Files:	    src/globals.c, src/quickfix.c, src/window.c
+
+Patch 6.1.258
+Problem:    Buffers menu doesn't work properly for multibyte buffer names.
+Solution:   Use a pattern to get the left and right part of the name.
+	    (Yasuhiro Matsumoto)
+Files:	    runtime/menu.vim
+
+Patch 6.1.259 (extra)
+Problem:    Mac: with 'patchmode' is used filenames are truncated.
+Solution:   Increase the BASENAMELEN for Mac OS X. (Ed Ralston)
+Files:	    src/os_mac.h
+
+Patch 6.1.260 (depends on 6.1.104)
+Problem:    GCC 3.2 still seems to have an optimizer problem. (Zvi Har'El)
+Solution:   Use the same configure check as used for GCC 3.1.
+Files:	    src/auto/configure, src/configure.in
+
+Patch 6.1.261
+Problem:    When deleting a line in a buffer which is not the current buffer,
+	    using the Perl interface Delete(), the cursor in the current
+	    window may move. (Chris Houser)
+Solution:   Don't adjust the cursor position when changing another buffer.
+Files:	    src/if_perl.xs
+
+Patch 6.1.262
+Problem:    When jumping over folds with "z[", "zj" and "zk" the previous
+	    position is not remembered. (Hari Krishna Dara)
+Solution:   Set the previous context mark before jumping.
+Files:	    src/fold.c
+
+Patch 6.1.263
+Problem:    When typing a multi-byte character that triggers an abbreviation
+	    it is not inserted properly.
+Solution:   Handle adding the typed multi-byte character. (Yasuhiro Matsumoto)
+Files:	    src/getchar.c
+
+Patch 6.1.264 (depends on patch 6.1.254)
+Problem:    exists() does not work for built-in functions. (Steve Wall)
+Solution:   Don't check for the function name to start with a capital.
+Files:	    src/eval.c
+
+Patch 6.1.265
+Problem:    libcall() can be used in 'foldexpr' to call any system function.
+	    rename(), delete() and remote_send() can also be used in
+	    'foldexpr'.  These are security problems. (Georgi Guninski)
+Solution:   Don't allow using libcall(), rename(), delete(), remote_send() and
+	    similar functions in the sandbox.
+Files:	    src/eval.c
+
+Patch 6.1.266 (depends on 6.1.265)
+Problem:    Win32: compile error in eval.c. (Bill McCarthy)
+Solution:   Move a variable declaration.
+Files:	    src/eval.c
+
+Patch 6.1.267
+Problem:    Using "p" to paste into a Visual selected area may cause a crash.
+Solution:   Allocate enough memory for saving the register contents. (Muraoka
+	    Taro)
+Files:	    src/ops.c
+
+Patch 6.1.268
+Problem:    When triggering an abbreviation with a multi-byte character, this
+	    character is not correctly inserted after expanding the
+	    abbreviation. (Taro Muraoka)
+Solution:   Add ABBR_OFF to all characters above 0xff.
+Files:	    src/edit.c, src/ex_getln.c, src/getchar.c
+
+Patch 6.1.269
+Problem:    After using input() text written with ":redir" gets extra indent.
+	    (David Fishburn)
+Solution:   Restore msg_col after using input().
+Files:	    src/ex_getln.c
+
+Patch 6.1.270 (depends on 6.1.260)
+Problem:    GCC 3.2.1 still seems to have an optimizer problem.
+Solution:   Use the same configure check as used for GCC 3.1.
+Files:	    src/auto/configure, src/configure.in
+
+Patch 6.1.271
+Problem:    When compiling without the +syntax feature there are errors.
+Solution:   Don't use some code for syntax highlighting. (Roger Cornelius)
+	    Make test 45 work without syntax highlighting.
+	    Also fix an error in a pattern matching: "\%(" was not supported.
+Files:	    src/ex_cmds2.c, src/regexp.c, src/testdir/test45.in
+
+Patch 6.1.272
+Problem:    After using ":set define<" a crash may happen. (Christian Robinson)
+Solution:   Make a copy of the option value in allocated memory.
+Files:	    src/option.c
+
+Patch 6.1.273
+Problem:    When the cursor doesn't blink, redrawing an exposed area may hide
+	    the cursor.
+Solution:   Always draw the cursor, also when it didn't move. (Muraoka Taro)
+Files:	    src/gui.c
+
+Patch 6.1.274 (depends on 6.1.210)
+Problem:    Resetting the iconv() state after each error is wrong for an
+	    incomplete sequence.
+Solution:   Don't reset the iconv() state.
+Files:	    src/fileio.c
+
+Patch 6.1.275
+Problem:    When using "v" in a startup script, get warning message that
+	    terminal cannot highlight. (Charles Campbell)
+Solution:   Only give the message after the terminal has been initialized.
+Files:	    src/normal.c
+
+Patch 6.1.276
+Problem:    "gvim --remote file" doesn't prompt for an encryption key.
+Solution:   The further characters the client sends to the server are used.
+	    Added inputsave() and inputrestore() to allow prompting the
+	    user directly and not using typeahead.
+	    Also fix possible memory leak for ":normal".
+Files:	    src/eval.c, src/ex_cmds2.c, src/ex_docmd.c, src/getchar.c,
+	    src/main.c, src/proto/getchar.pro, src/proto/ui.pro,
+	    src/runtime/doc/eval.txt, src/structs.h, src/ui.c, src/vim.h
+
+Patch 6.1.277 (depends on 6.1.276)
+Problem:    Compilation error when building with small features.
+Solution:   Define trash_input_buf() when needed. (Kelvin Lee)
+Files:	    src/ui.c
+
+Patch 6.1.278
+Problem:    When using signs the line number of a closed fold doesn't line up
+	    with the other line numbers. (Kamil Burzynski)
+Solution:   Insert two spaces for the sign column.
+Files:	    src/screen.c
+
+Patch 6.1.279
+Problem:    The prototype for smsg() and smsg_attr() do not match the function
+	    definition.  This may cause trouble for some compilers. (Nix)
+Solution:   Use va_list for systems that have stdarg.h.  Use "int" instead of
+	    "void" for the return type.
+Files:	    src/auto/configure, src/config.h.in, src/configure.in,
+	    src/proto.h, src/message.c
+
+Patch 6.1.280
+Problem:    It's possible to use an argument "firstline" or "lastline" for a
+	    function but using "a:firstline" or "a:lastline" in the function
+	    won't work.  (Benji Fisher)
+Solution:   Give an error message for these arguments.
+	    Also avoid that the following function body causes a whole row of
+	    errors, skip over it after an error in the first line.
+Files:	    src/eval.c
+
+Patch 6.1.281
+Problem:    In Insert mode CTRL-X CTRL-G leaves the cursor after the ruler.
+Solution:   Set the cursor position before waiting for the argument of CTRL-G.
+	    (Yasuhiro Matsumoto)
+Files:	    src/edit.c
+
+Patch 6.1.282
+Problem:    Elvis uses "se" in a modeline, Vim doesn't recognize this.
+Solution:   Also accept "se " where "set " is accepted in a modeline.
+	    (Yasuhiro Matsumoto)
+Files:	    src/buffer.c
+
+Patch 6.1.283
+Problem:    For ":sign" the icon file name cannot contain a space.
+Solution:   Handle backslashes in the file name.  (Yasuhiro Matsumoto)
+Files:	    src/ex_cmds.c
+
+Patch 6.1.284
+Problem:    On Solaris there is a warning for "struct utimbuf".
+Solution:   Move including "utime.h" to outside the function. (Derek Wyatt)
+Files:	    src/fileio.c
+
+Patch 6.1.285
+Problem:    Can't wipe out a buffer with 'bufhide' option.
+Solution:   Add "wipe" value to 'bufhide'. (Yegappan Lakshmanan)
+Files:	    runtime/doc/options.txt, src/buffer.c, src/option.c,
+	    src/quickfix.c
+
+Patch 6.1.286
+Problem:    'showbreak' cannot contain multi-byte characters.
+Solution:   Allow using all printable characters for 'showbreak'.
+Files:	    src/charset.c, src/move.c, src/option.c
+
+Patch 6.1.287 (depends on 6.1.285)
+Problem:    Effect of "delete" and "wipe" in 'bufhide' were mixed up.
+Solution:   Wipe out when wiping out is asked for.
+Files:	    src/buffer.c
+
+Patch 6.1.288
+Problem:    ":silent function F" hangs. (Hari Krishna Dara)
+Solution:   Don't use msg_col, it is not incremented when using ":silent".
+	    Also made the function output look a bit better.  Don't translate
+	    "function".
+Files:	    src/eval.c
+
+Patch 6.1.289 (depends on 6.1.278)
+Problem:    Compiler warning for pointer. (Axel Kielhorn)
+Solution:   Add a typecast for "  ".
+Files:	    src/screen.c
+
+Patch 6.1.290 (extra)
+Problem:    Truncating long text for message box may break multi-byte
+	    character.
+Solution:   Adjust to start of multi-byte character. (Yasuhiro Matsumoto)
+Files:	    src/os_mswin.c
+
+Patch 6.1.291 (extra)
+Problem:    Win32: CTRL-@ doesn't work.  Don't even get a message for it.
+Solution:   Recognize the keycode for CTRL-@. (Yasuhiro Matsumoto)
+Files:	    src/gui_w48.c
+
+Patch 6.1.292 (extra, depends on 6.1.253)
+Problem:    Win32: Can't compile with new MingW compiler.
+	    Borland 5 makefile doesn't generate pathdef.c.
+Solution:   Remove -wwide-multiply argument. (Rene de Zwart)
+	    Various fixes for other problems in Win32 makefiles. (Dan Sharp)
+Files:	    src/Make_bc5.mak, src/Make_cyg.mak, src/Make_ming.mak,
+	    src/Make_mvc.mak
+
+Patch 6.1.293
+Problem:    byte2line() returns a wrong result for some values.
+Solution:   Change ">=" to ">" in ml_find_line_or_offset(). (Bradford C Smith)
+	    Add one to the line number when at the end of a block.
+Files:	    src/memline.c
+
+Patch 6.1.294
+Problem:    Can't include a multi-byte character in a string by its hex value.
+	    (Benji Fisher)
+Solution:   Add "\u....": a character specified with up to four hex numbers
+	    and stored according to the value of 'encoding'.
+Files:	    src/eval.c
+
+Patch 6.1.295 (extra)
+Problem:    Processing the cs.po file generates an error. (Rahul Agrawal)
+Solution:   Fix the printf format characters in the translation.
+Files:	    src/po/cs.po
+
+Patch 6.1.296
+Problem:    Win32: When cancelling the font dialog 'guifont' remains set to
+	    "*".
+Solution:   Restore the old value of 'guifont' (Yasuhiro Matsumoto)
+Files:	    src/option.c
+
+Patch 6.1.297
+Problem:    "make test" fails in test6 in an UTF-8 environment. (Benji Fisher)
+Solution:   Before executing the BufReadPost autocommands save the current
+	    fileencoding, so that the file isn't marked changed.
+Files:	    src/fileio.c
+
+Patch 6.1.298
+Problem:    When using signs and the first line of a closed fold has a sign
+	    it can be redrawn as if the fold was open.  (Kamil Burzynski)
+Solution:   Don't redraw a sign inside a closed fold.
+Files:	    src/screen.c
+
+Patch 6.1.299
+Problem:    ":edit +set\ ro file" doesn't work.
+Solution:   Halve the number of backslashes in the "+cmd" argument.
+Files:	    src/ex_docmd.c
+
+Patch 6.1.300 (extra)
+Problem:    Handling of ETO_IGNORELANGUAGE is confusing.
+Solution:   Clean up the handling of ETO_IGNORELANGUAGE. (Glenn Maynard)
+Files:	    src/gui_w32.c
+
+Patch 6.1.301 (extra)
+Problem:    French translation of file-save dialog doesn't show file name.
+Solution:   Insert a star in the printf string. (Francois Terrot)
+Files:	    src/po/fr.po
+
+Patch 6.1.302
+Problem:    Counting lines of the Visual area is incorrect for closed folds.
+	    (Mikolaj Machowski)
+Solution:   Correct the start and end for the closed fold.
+Files:	    src/normal.c
+
+Patch 6.1.303 (extra)
+Problem:    The Top/Bottom/All text does not always fit in the ruler when
+	    translated to Japanese.  Problem with a character being wider when
+	    in a bold font.
+Solution:   Use ETO_PDY to specify the width of each character. (Yasuhiro
+	    Matsumoto)
+Files:	    src/gui_w32.c
+
+Patch 6.1.304 (extra, depends on 6.1.292)
+Problem:    Win32: Postscript is always enabled in the MingW Makefile.
+	    Pathdef.c isn't generated properly with Make_bc5.mak. (Yasuhiro
+	    Matsumoto)
+Solution:   Change an ifdef to an ifeq. (Madoka Machitani)
+	    Use the Borland make redirection to generate pathdef.c. (Maurice
+	    Barnum)
+Files:	    src/Make_bc5.mak, src/Make_ming.mak
+
+Patch 6.1.305
+Problem:    When 'verbose' is 14 or higher, a function call may cause reading
+	    uninitialized data. (Walter Briscoe)
+Solution:   Check for end-of-string in trunc_string().
+Files:	    src/message.c
+
+Patch 6.1.306
+Problem:    The AIX VisualAge cc compiler doesn't define __STDC__.
+Solution:   Use __EXTENDED__ like __STDC__. (Jess Thrysoee)
+Files:	    src/os_unix.h
+
+Patch 6.1.307
+Problem:    When a double-byte character has an illegal tail byte the display
+	    is messed up. (Yasuhiro Matsumoto)
+Solution:   Draw "XX" instead of the wrong character.
+Files:	    src/screen.c
+
+Patch 6.1.308
+Problem:    Can't reset the Visual mode returned by visualmode().
+Solution:   Use an optional argument to visualmode(). (Charles Campbell)
+Files:	    runtime/doc/eval.txt, src/eval.c, src/normal.c,
+	    src/structs.h
+
+Patch 6.1.309
+Problem:    The tutor doesn't select German if the locale name is
+	    "German_Germany.1252". (Joachim Hofmann)
+Solution:   Check for "German" in the locale name.  Also check for
+	    ".ge".  And include the German and Greek tutors.
+Files:	    runtime/tutor/tutor.de, runtime/tutor/tutor.vim,
+	    runtime/tutor/tutor.gr, runtime/tutor/tutor.gr.cp737
+
+Patch 6.1.310 (depends on 6.1.307)
+Problem:    All double-byte characters are displayed as "XX".
+Solution:   Use ">= 32" instead of "< 32".  (Yasuhiro Matsumoto)
+Files:	    src/screen.c
+
+Patch 6.1.311 (extra)
+Problem:    VMS: path in window title doesn't include necessary separator.
+	    file version doesn't always work properly with Unix.
+	    Crashes because of memory overwrite in GUI.
+	    Didn't always handle files with lowercase and correct path.
+Solution:   Fix the problems.  Remove unnecessary file name translations.
+	    (Zoltan Arpadffy)
+Files:	    src/buffer.c, src/ex_cmds2.c, src/fileio.c, src/memline.c,
+	    src/misc1.c, src/misc2.c, src/os_unix.c, src/os_vms.c, src/tag.c
+
+Patch 6.1.312
+Problem:    When using ":silent" debugging is also done silently.
+Solution:   Disable silence while at the debug prompt.
+Files:	    src/ex_cmds2.c
+
+Patch 6.1.313
+Problem:    When a ":drop fname" command is used and "fname" is open in
+	    another window, it is also opened in the current window.
+Solution:   Change to the window with "fname" instead.
+	    Don't redefine the argument list when dropping only one file.
+Files:	    runtime/doc/windows.txt, src/ex_cmds2.c, src/ex_cmds.c,
+	    src/ex_docmd.c, src/proto/ex_cmds2.pro, src/proto/ex_docmd.pro
+
+Patch 6.1.314 (depends on 6.1.126)
+Problem:    Missing backslash in "Generic Config file" syntax menu.
+Solution:   Insert the backslash. (Zak Beck)
+Files:	    runtime/makemenu.vim, runtime/synmenu.vim
+
+Patch 6.1.315 (extra)
+Problem:    A very long hostname may lead to an unterminated string.  Failing
+	    to obtain a hostname may result in garbage.  (Walter Briscoe)
+Solution:   Add a NUL at the end of the hostname buffer.
+Files:	    src/os_mac.c, src/os_msdos.c, src/os_unix.c, src/os_win16.c,
+	    src/os_win32.c
+
+Patch 6.1.316
+Problem:    When exiting with "wq" and there is a hidden buffer, after the
+	    "file changed" dialog there is a warning for a changed buffer.
+	    (Ajit Thakkar)
+Solution:   Do update the buffer timestamps when exiting.
+Files:	    src/fileio.c
+
+Patch 6.1.317
+Problem:    Closing a window may cause some of the remaining windows to be
+	    positioned wrong if there is a mix of horizontal and vertical
+	    splits. (Stefan Ingi Valdimarsson)
+Solution:   Update the frame sizes before updating the window positions.
+Files:	    src/window.c
+
+Patch 6.1.318
+Problem:    auto/pathdef.c can include wrong quotes when a compiler flag
+	    includes quotes.
+Solution:   Put a backslash before the quotes in compiler flags. (Shinra Aida)
+Files:	    src/Makefile
+
+Patch 6.1.319 (depends on 6.1.276)
+Problem:    Using "--remote +cmd file" does not execute "cmd".
+Solution:   Call inputrestore() in the same command line as inputsave(),
+	    otherwise it will never get executed.
+Files:	    src/main.c
+
+Patch 6.1.320 (depends on 6.1.313)
+Problem:    When a ":drop one\ file" command is used the file "one\ file" is
+	    opened, the backslash is not removed. (Taro Muraoka)
+Solution:   Handle backslashes correctly.  Always set the argument list to
+	    keep it simple.
+Files:	    runtime/doc/windows.txt, src/ex_cmds.c
+
+Patch 6.1.321
+Problem:    When 'mouse' includes 'n' but not 'v', don't allow starting Visual
+	    mode with the mouse.
+Solution:   Don't use MOUSE_MAY_VIS when there is no 'v' in 'mouse'. (Flemming
+	    Madsen)
+Files:	    src/normal.c
+
+Patch 6.1.322 (extra, depends on 6.1.315)
+Problem:    Win32: The host name is always "PC " plus the real host name.
+Solution:   Don't insert "PC " before the host name.
+Files:	    src/os_win32.c
+
+Patch 6.1.323
+Problem:    ":registers" doesn't stop listing for a "q" at the more prompt.
+	    (Hari Krishna Dara)
+Solution:   Check for interrupt and got_int.
+Files:	    src/ops.c, src/proto/ops.pro
+
+Patch 6.1.324
+Problem:    Crash when dragging a vertical separator when <LeftMouse> is
+	    remapped to jump to another window.
+Solution:   Pass the window pointer to the function doing the dragging instead
+	    of always using the current window. (Daniel Elstner)
+	    Also fix that starting a drag changes window focus.
+Files:	    src/normal.c, src/proto/window.pro, src/ui.c, src/vim.h,
+	    src/window.c
+
+Patch 6.1.325
+Problem:    Shift-Tab is not automatically recognized in an xterm.
+Solution:   Add <Esc>[Z as the termcap code. (Andrew Pimlott)
+Files:	    src/term.c
+
+Patch 6.1.326
+Problem:    Using a search pattern may read from uninitialized data (Yasuhiro
+	    Matsumoto)
+Solution:   Initialize pointers to NULL.
+Files:	    src/regexp.c
+
+Patch 6.1.327
+Problem:    When opening the "mbyte.txt" help file the utf-8 characters are
+	    unreadable, because the fileencoding is forced to be latin1.
+Solution:   Check for utf-8 encoding first in help files. (Daniel Elstner)
+Files:	    runtime/doc/mbyte.txt, src/fileio.c
+
+Patch 6.1.328
+Problem:    Prototype for enc_canon_search() is missing.
+Solution:   Add the prototype. (Walter Briscoe)
+Files:	    src/mbyte.c
+
+Patch 6.1.329
+Problem:    When editing a file "a b c" replacing "%" in ":Cmd %" or ":next %"
+	    does not work properly.  (Hari Krishna Dara)
+Solution:   Always escape spaces when expanding "%".  Don't split argument for
+	    <f-args> in a user command when only one argument is used.
+Files:	    src/ex_docmd.c
+
+Patch 6.1.330
+Problem:    GTK, Motif and Athena: Keypad keys produce the same code as
+	    non-keypad keys, making it impossible to map them separately.
+Solution:   Use different termcap codes for the keypad keys. (Neil Bird)
+Files:	    src/gui_gtk_x11.c, src/gui_x11.c
+
+Patch 6.1.331
+Problem:    When translating the help files, "LOCAL ADDITIONS" no longer marks
+	    the spot where help files from plugins are to be listed.
+Solution:   Add a "local-additions" tag and use that to find the right spot.
+Files:	    runtime/doc/help.txt, src/ex_cmds.c
+
+Patch 6.1.332 (extra)
+Problem:    Win32: Loading Perl dynamically doesn't work with Perl 5.8.
+	    Perl 5.8 also does not work with Cygwin and Ming.
+Solution:   Adjust the function calls. (Taro Muraoka)
+	    Adjust the cyg and ming makefiles. (Dan Sharp)
+Files:	    src/Make_cyg.mak, src/Make_ming.mak, src/Make_mvc.mak,
+	    src/if_perl.xs
+
+Patch 6.1.333 (extra)
+Problem:    Win32: Can't handle Unicode text on the clipboard.
+	    Can't pass NUL byte, it becomes a line break.  (Bruce DeVisser)
+Solution:   Support Unicode for the clipboard (Ron Aaron and Glenn Maynard)
+	    Also support copy/paste of NUL bytes.
+Files:	    src/os_mswin.c, src/os_win16.c src/os_win32.c
+
+Patch 6.1.334 (extra, depends on 6.1.303)
+Problem:    Problem with drawing Hebrew characters.
+Solution:   Only use ETO_PDY for Windows NT and the like. (Yasuhiro Matsumoto)
+Files:	    src/gui_w32.c
+
+Patch 6.1.335 (extra)
+Problem:    Failure of obtaining the cursor position and window size is
+	    ignored.
+Solution:   Remove a semicolon after an "if". (Walter Briscoe)
+Files:	    src/gui_w32.c
+
+Patch 6.1.336 (extra)
+Problem:    Warning for use of function prototypes of smsg().
+Solution:   Define HAVE_STDARG_H. (Walter Briscoe)
+Files:	    src/os_win32.h
+
+Patch 6.1.337
+Problem:    When using "finish" in debug mode in function B() for ":call
+	    A(B())" does not stop after B() is finished.
+Solution:   Increase debug_level while evaluating a function.
+Files:	    src/ex_docmd.c
+
+Patch 6.1.338
+Problem:    When using a menu that checks out the current file from Insert
+	    mode, there is no warning for the changed file until exiting
+	    Insert mode.  (Srikanth Sankaran)
+Solution:   Add a check for need_check_timestamps in the Insert mode loop.
+Files:	    src/edit.c
+
+Patch 6.1.339
+Problem:    Completion doesn't allow "g:" in ":let g:did_<Tab>". (Benji
+	    Fisher)
+Solution:   Return "g:var" for global variables when that is what is being
+	    expanded. (Flemming Madsen)
+Files:	    src/eval.c
+
+Patch 6.1.340 (extra, depends on 6.1.332)
+Problem:    Win32: Can't compile the Perl interface with nmake.
+Solution:   Don't compare the version number as a string but as a number.
+	    (Juergen Kraemer)
+Files:	    src/Make_mvc.mak
+
+Patch 6.1.341
+Problem:    In Insert mode with 'rightleft' set the cursor is drawn halfway a
+	    double-wide character.  For CTRL-R and CTRL-K in Insert mode the "
+	    or ? is not displayed.
+Solution:   Draw the cursor in the next character cell.  Display the " or ?
+	    over the right half of the double-wide character. (Yasuhiro
+	    Matsumoto)  Also fix that cancelling a digraph doesn't redraw
+	    a double-byte character correctly.
+Files:	    src/edit.c, src/gui.c, src/mbyte.c
+
+Patch 6.1.342 (depends on 6.1.341)
+Problem:    With 'rightleft' set typing "c" on a double-wide character causes
+	    the cursor to be displayed one cell to the left.
+Solution:   Draw the cursor in the next character cell.  (Yasuhiro Matsumoto)
+Files:	    src/gui.c
+
+Patch 6.1.343 (depends on 6.1.342)
+Problem:    Cannot compile with the +multi_byte feature but without +rightleft.
+	    Cannot compile without the GUI.
+Solution:   Fix the #ifdefs.  (partly by Nam SungHyun)
+Files:	    src/gui.c, src/mbyte.c, src/ui.c
+
+Patch 6.1.344
+Problem:    When using ":silent filetype" the output is still put in the
+	    message history. (Hari Krishna Dara)
+Solution:   Don't add messages in the history when ":silent" is used.
+Files:	    src/message.c
+
+Patch 6.1.345 (extra)
+Problem:    Win32: 'imdisable' doesn't work.
+Solution:   Make 'imdisable' work. (Yasuhiro Matsumoto)
+Files:	    src/gui_w32.c
+
+Patch 6.1.346
+Problem:    The scroll wheel can only scroll the current window.
+Solution:   Make the scroll wheel scroll the window that the mouse points to.
+	    (Daniel Elstner)
+Files:	    src/edit.c, src/gui.c, src/normal.c, src/term.c
+
+Patch 6.1.347
+Problem:    When using cscope to list matching tags, the listed number is
+	    sometimes not equal to what cscope uses. (Vihren Milev)
+Solution:   For cscope tags use only one table, don't give tags in the current
+	    file a higher priority.
+Files:	    src/tag.c
+
+Patch 6.1.348
+Problem:    Wildmode with wildmenu: ":set wildmode=list,full", ":colorscheme
+	    <tab>" results in "zellner" instead of the first entry. (Anand
+	    Hariharan)
+Solution:   Don't call ExpandOne() from globpath(). (Flemming Madsen)
+Files:	    src/ex_getln.c
+
+Patch 6.1.349
+Problem:    "vim --serverlist" when no server was ever started gives an error
+	    message without "\n".
+	    "vim --serverlist" doesn't exit when the X server can't be
+	    contacted, it starts Vim unexpectedly. (Ricardo Signes)
+Solution:   Don't give an error when no Vim server was ever started.
+	    Treat failing of opening the display equal to errors inside the
+	    remote*() functions. (Flemming Madsen)
+Files:	    src/if_xcmdsrv.c, src/main.c
+
+Patch 6.1.350
+Problem:    When entering a buffer with ":bnext" for the first time, using an
+	    autocommand to restore the last used cursor position doesn't work.
+	    (Paolo Giarusso)
+Solution:   Don't use the last known cursor position of the current Vim
+	    invocation if an autocommand changed the position.
+Files:	    src/buffer.c
+
+Patch 6.1.351 (depends on 6.1.349)
+Problem:    Crash when starting Vim the first time in an X server. (John
+	    McGowan)
+Solution:   Don't call xFree() with a fixed string.
+Files:	    src/if_xcmdsrv.c
+
+Patch 6.1.352 (extra, depends on 6.1.345)
+Problem:    Win32: Crash when setting "imdisable" in _vimrc.
+Solution:   Don't call IME functions when imm32.dll was not loaded (yet).
+	    Also add typecasts to avoid Compiler warnings for
+	    ImmAssociateContext() argument.
+Files:	    src/gui_w32.c
+
+Patch 6.1.353 (extra, depends on 6.1.334)
+Problem:    Problem with drawing Arabic characters.
+Solution:   Don't use ETO_PDY, do use padding.
+Files:	    src/gui_w32.c
+
+Patch 6.1.354 (extra, depends on 6.1.333)
+Problem:    MS-Windows 98: Notepad can't paste text copied from Vim when
+	    'encoding' is "utf-8".
+Solution:   Also make CF_TEXT available on the clipboard. (Ron Aaron)
+Files:	    src/os_mswin.c
+
+Patch 6.1.355
+Problem:    In a regexp '\n' will never match anything in a string.
+Solution:   Make '\n' match a newline character.
+Files:	    src/buffer.c, src/edit.c, src/eval.c, src/ex_cmds2.c,
+	    src/ex_docmd.c, src/ex_getln.c, src/fileio.c, src/misc1.c,
+	    src/option.c, src/os_mac.c, src/os_unix.c, src/quickfix.c,
+	    src/regexp.c, src/search.c, src/syntax.c, src/tag.c, src/vim.h
+
+Patch 6.1.356 (extra, depends on, well, eh, several others)
+Problem:    Compiler warnings for using convert_setup() and a few other
+	    things.
+Solution:   Add typecasts.
+Files:	    src/mbyte.c, src/os_mswin.c, src/proto/os_win32.pro, src/os_win32.c
+
+Patch 6.1.357
+Problem:    CR in the quickfix window jumps to the error under the cursor, but
+	    this doesn't work in Insert mode. (Srikanth Sankaran)
+Solution:   Handle CR in Insert mode in the quickfix window.
+Files:	    src/edit.c
+
+Patch 6.1.358
+Problem:    The tutor doesn't select another locale version properly.
+Solution:   Insert the "let" command. (Yasuhiro Matsumoto)
+Files:	    runtime/tutor/tutor.vim
+
+Patch 6.1.359 (extra)
+Problem:    Mac Carbon: Vim doesn't get focus when started from the command
+	    line.  Crash when using horizontal scroll bar.
+Solution:   Set Vim as the frontprocess.  Fix scrolling.  (Peter Cucka)
+Files:	    src/gui_mac.c
+
+Patch 6.1.360 (depends on 6.1.341)
+Problem:    In Insert mode CTRL-K ESC messes up a multi-byte character.
+	    (Anders Helmersson)
+Solution:   Save all bytes of a character when displaying a character
+	    temporarily.
+Files:	    src/edit.c, src/proto/screen.pro, src/screen.c
+
+Patch 6.1.361
+Problem:    Cannot jump to a file mark with ":'M".
+Solution:   Allow jumping to another file for a mark in an Ex address when it
+	    is the only thing in the command line.
+Files:	    src/ex_docmd.c
+
+Patch 6.1.362
+Problem:    tgetent() may return zero for success. tgetflag() may return -1
+	    for an error.
+Solution:   Check tgetflag() for returning a positive value.  Add an autoconf
+	    check for the value that tgetent() returns.
+Files:	    src/auto/configure, src/config.h.in, src/configure.in, src/term.c
+
+Patch 6.1.363
+Problem:    byte2line() can return one more than the number of lines.
+Solution:   Return -1 if the offset is one byte past the end.
+Files:	    src/memline.c
+
+Patch 6.1.364
+Problem:    That the FileChangedShell autocommand event never nests makes it
+	    difficult to reload a file in a normal way.
+Solution:   Allow nesting for the FileChangedShell event but do not allow
+	    triggering itself again.
+	    Also avoid autocommands for the cmdline window in rare cases.
+Files:	    src/ex_getln.c, src/fileio.c, src/window.c
+
+Patch 6.1.365 (depends on 6.1.217)
+Problem:    Setting a breakpoint in a sourced file with a relative path name
+	    doesn't work. (Servatius Brandt)
+Solution:   Expand the file name to a full path.
+Files:	    src/ex_cmds2.c
+
+Patch 6.1.366
+Problem:    Can't use Vim with Netbeans.
+Solution:   Add the Netbeans interface.  Includes support for sign icons and
+	    "-fg" and "-bg" arguments for GTK.  Add the 'autochdir'
+	    option.  (Gordon Prieur, George Hernandez, Dave Weatherford)
+	    Make it possible to display both a sign with a text and one with
+	    line highlighting in the same line.
+	    Add support for Agide, interface version 2.1.
+	    Also fix that when 'iskeyword' includes '?' the "*" command
+	    doesn't work properly on a word that includes "?" (Bill McCarthy):
+	    Don't escape "?" to "\?" when searching forward.
+Files:	    runtime/doc/Makefile, runtime/doc/netbeans.txt,
+	    runtime/doc/options.txt, runtime/doc/various.txt,
+	    src/Makefile, src/auto/configure, src/buffer.c, src/config.h.in,
+	    src/config.mk.in, src/configure.in, src/edit.c, src/ex_cmds.c,
+	    src/ex_docmd.c, src/feature.h, src/fileio.c, src/globals.h,
+	    src/gui.c, src/gui_beval.c, src/gui_gtk_x11.c, src/gui_x11.c,
+	    src/main.c, src/memline.c, src/misc1.c, src/misc2.c, src/move.c,
+	    src/nbdebug.c, src/nbdebug.h, src/netbeans.c, src/normal.c,
+	    src/ops.c, src/option.c, src/option.h, src/proto/buffer.pro,
+	    src/proto/gui_beval.pro, src/proto/gui_gtk_x11.pro,
+	    src/proto/gui_x11.pro, src/proto/misc2.pro,
+	    src/proto/netbeans.pro, src/proto/normal.pro, src/proto/ui.pro,
+	    src/proto.h, src/screen.c, src/structs.h, src/ui.c, src/undo.c,
+	    src/vim.h, src/window.c, src/workshop.c
+
+Patch 6.1.367 (depends on 6.1.365)
+Problem:    Setting a breakpoint in a function doesn't work.  For a sourced
+	    file it doesn't work when symbolic links are involved.  (Servatius
+	    Brandt)
+Solution:   Expand the file name in the same way as do_source() does.  Don't
+	    prepend the path to a function name.
+Files:	    src/ex_cmds2.c
+
+Patch 6.1.368
+Problem:    Completion for ":map" does not include <silent> and <script>.
+	    ":mkexrc" do not save the <silent> attribute of mappings.
+Solution:   Add "<silent>" to the generated map commands when appropriate.
+	    (David Elstner)
+	    Add <silent> and <script> to command line completion.
+Files:	    src/getchar.c
+
+Patch 6.1.369 (extra)
+Problem:    VMS: Vim hangs when attempting to edit a read-only file in the
+	    terminal.  Problem with VMS filenames for quickfix.
+Solution:   Rewrite low level input.  Remove version number from file name in
+	    a couple more places.  Fix crash after patch 6.1.362.  Correct
+	    return code for system().  (Zoltan Arpadffy, Tomas Stehlik)
+Files:	    src/misc1.c, src/os_unix.c, src/os_vms.c, src/proto/os_vms.pro,
+	    src/os_vms_conf.h, src/quickfix.c, src/ui.c
+
+Patch 6.1.370
+Problem:    #ifdef nesting is unclear.
+Solution:   Insert spaces to indicate the nesting.
+Files:	    src/os_unix.c
+
+Patch 6.1.371
+Problem:    "%V" in 'statusline' doesn't show "0-1" in an empty line.
+Solution:   Add one to the column when comparing with virtual column (Andrew
+	    Pimlott)
+Files:	    src/buffer.c
+
+Patch 6.1.372
+Problem:    With 16 bit ints there are compiler warnings. (Walter Briscoe)
+Solution:   Change int into long.
+Files:	    src/structs.h, src/syntax.c
+
+Patch 6.1.373
+Problem:    The default page header for printing is not translated.
+Solution:   Add _() around the two places where "Page" is used. (Mike
+	    Williams)  Translate the default value of the 'titleold' and
+	    'printheader' options.
+Files:	    src/ex_cmds2.c, src/option.c
+
+Patch 6.1.374 (extra)
+Problem:    MS-Windows: Cannot build GvimExt with MingW or Cygwin.
+Solution:   Add makefile and modified resource files. (Rene de Zwart)
+	    Also support Cygwin. (Alejandro Lopez_Valencia)
+Files:	    GvimExt/Make_cyg.mak, GvimExt/Make_ming.mak, GvimExt/Makefile,
+	    GvimExt/gvimext_ming.def, GvimExt/gvimext_ming.rc
+
+Patch 6.1.375
+Problem:    MS-Windows: ':!dir "%"' does not work for a file name with spaces.
+	    (Xiangjiang Ma)
+Solution:   Don't insert backslashes for spaces in a shell command.
+Files:	    src/ex_docmd.c
+
+Patch 6.1.376
+Problem:    "vim --version" and "vim --help" have a non-zero exit code.
+	    That is unusual. (Petesea)
+Solution:   Use a zero exit code.
+Files:	    src/main.c
+
+Patch 6.1.377
+Problem:    Can't add words to 'lispwords' option.
+Solution:   Add P_COMMA and P_NODUP flags. (Haakon Riiser)
+Files:	    src/option.c
+
+Patch 6.1.378
+Problem:    When two buffer-local user commands are ambiguous, a full match
+	    with a global user command isn't found. (Hari Krishna Dara)
+Solution:   Detect this situation and accept the global command.
+Files:	    src/ex_docmd.c
+
+Patch 6.1.379
+Problem:    Linux with kernel 2.2 can't use the alternate stack in combination
+	    with threading, causes an infinite loop.
+Solution:   Don't use the alternate stack in this situation.
+Files:	    src/os_unix.c
+
+Patch 6.1.380
+Problem:    When 'winminheight' is zero and the quickfix window is zero lines,
+	    entering the window doesn't make it higher. (Christian J.
+	    Robinson)
+Solution:   Make sure the current window is at least one line high.
+Files:	    src/window.c
+
+Patch 6.1.381
+Problem:    When a BufWriteCmd is used and it leaves the buffer modified, the
+	    window may still be closed. (Hari Krishna Dara)
+Solution:   Return FAIL from buf_write() when the buffer is still modified
+	    after a BufWriteCmd autocommand was used.
+Files:	    src/fileio.c
+
+Patch 6.1.382 (extra)
+Problem:    Win32 GUI: When using two monitors, the code that checks/fixes the
+	    window size and position (e.g. when a font changes) doesn't work
+	    properly.  (George Reilly)
+Solution:   Handle a double monitor situation. (Helmut Stiegler)
+Files:	    src/gui_w32.c
+
+Patch 6.1.383
+Problem:    The filling of the status line doesn't work properly for
+	    multi-byte characters. (Nam SungHyun)
+	    There is no check for going past the end of the buffer.
+Solution:   Properly distinguish characters and bytes.  Properly check for
+	    running out of buffer space.
+Files:	    src/buffer.c, src/ex_cmds2.c, src/proto/buffer.pro, src/screen.c
+
+Patch 6.1.384
+Problem:    It is not possible to find if a certain patch has been included.
+	    (Lubomir Host)
+Solution:   Support using has() to check if a patch was included.
+Files:	    runtime/doc/eval.txt, src/eval.c, src/proto/version.pro,
+	    src/version.c
+
+Patch 6.1.385 (depends on 6.1.383)
+Problem:    Can't compile without the multi-byte feature.
+Solution:   Move an #ifdef.  (Christian J. Robinson)
+Files:	    src/buffer.c
+
+Patch 6.1.386
+Problem:    Get duplicate tags when running ":helptags".
+Solution:   Do the other halve of moving a section to another help file.
+Files:	    runtime/tagsrch.txt
+
+Patch 6.1.387 (depends on 6.1.373)
+Problem:    Compiler warning for pointer cast.
+Solution:   Add (char_u *).
+Files:	    src/option.c
+
+Patch 6.1.388 (depends on 6.1.384)
+Problem:    Compiler warning for pointer cast.
+Solution:   Add (char *).  Only include has_patch() when used.
+Files:	    src/eval.c, src/version.c
+
+Patch 6.1.389 (depends on 6.1.366)
+Problem:    Balloon evaluation doesn't work for GTK.
+	    has("balloon_eval") doesn't work.
+Solution:   Add balloon evaluation for GTK.  Also improve displaying of signs.
+	    (Daniel Elstner)
+	    Also make ":gui" start the netbeans connection and avoid using
+	    netbeans functions when the connection is not open.
+Files:	    src/Makefile, src/feature.h, src/gui.c, src/gui.h,
+	    src/gui_beval.c, src/gui_beval.h, src/gui_gtk.c,
+	    src/gui_gtk_x11.c, src/eval.c, src/memline.c, src/menu.c,
+	    src/netbeans.c, src/proto/gui_beval.pro, src/proto/gui_gtk.pro,
+	    src/structs.h, src/syntax.c, src/ui.c, src/workshop.c
+
+Patch 6.1.390 (depends on 6.1.389)
+Problem:    It's not possible to tell Vim to save and exit through the
+	    Netbeans interface.  Would still try to send balloon eval text
+	    after the connection is closed.
+	    Can't use Unicode characters for sign text.
+Solution:   Add functions "saveAndExit" and "getModified".  Check for a
+	    working connection before sending a balloonText event.
+	    various other cleanups.
+	    Support any character for sign text. (Daniel Elstner)
+Files:	    runtime/doc/netbeans.txt, runtime/doc/sign.txt, src/ex_cmds.c,
+	    src/netbeans.c, src/screen.c
+
+Patch 6.1.391
+Problem:    ml_get() error when using virtualedit. (Charles Campbell)
+Solution:   Get a line from a specific window, not the current one.
+Files:	    src/charset.c
+
+Patch 6.1.392 (depends on 6.1.383)
+Problem:    Highlighting in the 'statusline' is in the wrong position when an
+	    item is truncated. (Zak Beck)
+Solution:   Correct the start of 'statusline' items properly for a truncated
+	    item.
+Files:	    src/buffer.c
+
+Patch 6.1.393
+Problem:    When compiled with Python and threads, detaching the terminal may
+	    cause Vim to loop forever.
+Solution:   Add -pthread to $CFLAGS when using Python and gcc. (Daniel
+	    Elstner)
+Files:	    src/auto/configure,, src/configure.in
+
+Patch 6.1.394 (depends on 6.1.390)
+Problem:    The netbeans interface doesn't recognize multibyte glyph names.
+Solution:   Check the number of cells rather than bytes to decide
+	    whether a glyph name is not a filename. (Daniel Elstner)
+Files:	    src/netbeans.c
+
+Patch 6.1.395 (extra, depends on 6.1.369)
+Problem:    VMS: OLD_VMS is never defined.  Missing function prototype.
+Solution:   Define OLD_VMS in Make_vms.mms.  Add vms_sys_status() to
+	    os_vms.pro. (Zoltan Arpadffy)
+Files:	    src/Make_vms.mms, src/proto/os_vms.pro
+
+Patch 6.1.396 (depends on 6.1.330)
+Problem:    Compiler warnings for using enum.
+Solution:   Add typecast to char_u.
+Files:	    src/gui_gtk_x11.c, src/gui_x11.c
+
+Patch 6.1.397 (extra)
+Problem:    The install program may use a wrong path for the diff command if
+	    there is a space in the install directory path.
+Solution:   Use double quotes around the path if necessary. (Alejandro
+	    Lopez-Valencia)  Also use double quotes around the file name
+	    arguments.
+Files:	    src/dosinst.c
+
+Patch 6.1.398
+Problem:    Saving the typeahead for debug mode causes trouble for a test
+	    script. (Servatius Brandt)
+Solution:   Add the ":debuggreedy" command to avoid saving the typeahead.
+Files:	    runtime/doc/repeat.txt, src/ex_cmds.h, src/ex_cmds2.c,
+	    src/ex_docmd.c, src/proto/ex_cmds2.pro
+
+Patch 6.1.399
+Problem:    Warning for unused variable.
+Solution:   Remove the variable two_or_more.
+Files:	    src/ex_cmds.c
+
+Patch 6.1.400 (depends on 6.1.381)
+Problem:    When a BufWriteCmd wipes out the buffer it may still be accessed.
+Solution:   Don't try accessing a buffer that has been wiped out.
+Files:	    src/fileio.c
+
+Patch 6.1.401 (extra)
+Problem:    Building the Win16 version with Borland 5.01 doesn't work.
+	    "make test" doesn't work with Make_dos.mak. (Walter Briscoe)
+Solution:   Various fixes to the w16 makefile. (Walter Briscoe)
+	    Don't use deltree.  Use "mkdir \tmp" instead of "mkdir /tmp".
+Files:	    src/Make_w16.mak, src/testdir/Make_dos.mak
+
+Patch 6.1.402
+Problem:    When evaluating a function name with curly braces, an error
+	    is not handled consistently.
+Solution:   Accept the result of an curly braces expression when an
+	    error was encountered.  Skip evaluating an expression in curly
+	    braces when skipping.  (Servatius Brandt)
+Files:	    src/eval.c
+
+Patch 6.1.403 (extra)
+Problem:    MS-Windows 16 bit: compiler warnings.
+Solution:   Add typecasts. (Walter Briscoe)
+Files:	    src/ex_cmds2.c, src/gui_w48.c, src/os_mswin.c, src/os_win16.c,
+	    src/syntax.c
+
+Patch 6.1.404 (extra)
+Problem:    Various small problems.
+Solution:   Fix comments.  Various small additions, changes in indent, removal
+	    of unused items and fixes.
+Files:	    Makefile, README.txt, runtime/menu.vim, runtime/vimrc_example.vim,
+	    src/INSTALL, src/INSTALLole.txt, src/Make_bc5.mak,
+	    src/Make_cyg.mak, src/Make_ming.mak, src/Makefile,
+	    src/config.h.in, src/edit.c, src/eval.c, src/ex_cmds2.c,
+	    src/ex_docmd.c, src/ex_getln.c, src/fileio.c, src/getchar.c,
+	    src/gui.c, src/gui_gtk.c, src/gui_photon.c, src/if_cscope.c,
+	    src/if_python.c, src/keymap.h, src/mark.c, src/mbyte.c,
+	    src/message.c, src/misc1.c, src/misc2.c, src/normal.c,
+	    src/option.c, src/os_os2_cfg.h, src/os_win32.c,
+	    src/proto/getchar.pro, src/proto/message.pro,
+	    src/proto/regexp.pro, src/screen.c, src/structs.h, src/syntax.c,
+	    src/term.c, src/testdir/test15.in, src/testdir/test15.ok,
+	    src/vim.rc, src/xxd/Make_cyg.mak, src/xxd/Makefile
+
+Patch 6.1.405
+Problem:    A few files are missing from the toplevel Makefile.
+Solution:   Add the missing files.
+Files:	    Makefile
+
+Patch 6.1.406 (depends on 6.1.392)
+Problem:    When a statusline item doesn't fit arbitrary text appears.
+	    (Christian J. Robinson)
+Solution:   When there is just enough room but not for the "<" truncate the
+	    statusline item like there is no room.
+Files:	    src/buffer.c
+
+Patch 6.1.407
+Problem:    ":set scrollbind | help" scrollbinds the help window. (Andrew
+	    Pimlott)
+Solution:   Reset 'scrollbind' when opening a help window.
+Files:	    src/ex_cmds.c
+
+Patch 6.1.408
+Problem:    When 'rightleft' is set unprintable character 0x0c is displayed as
+	    ">c0<".
+Solution:   Reverse the text of the hex character.
+Files:	    src/screen.c
+
+Patch 6.1.409
+Problem:    Generating tags for the help doesn't work for some locales.
+Solution:   Set LANG=C LC_ALL=C in the environment for "sort". (Daniel
+	    Elstner)
+Files:	    runtime/doc/Makefile
+
+Patch 6.1.410 (depends on 6.1.390)
+Problem:    Linking error when compiling with Netbeans but without sign icons.
+	    (Malte Neumann)
+Solution:   Don't define buf_signcount() when sign icons are unavailable.
+Files:	    src/buffer.c
+
+Patch 6.1.411
+Problem:    When 'virtualedit' is set, highlighting a Visual block beyond the
+	    end of a line may be wrong.
+Solution:   Correct the virtual column when the end of the line is before the
+	    displayed part of the line. (Muraoka Taro)
+Files:	    src/screen.c
+
+Patch 6.1.412
+Problem:    When swapping terminal screens and using ":gui" to start the GUI,
+	    the shell prompt may be after a hit-enter prompt.
+Solution:   Output a newline in the terminal when starting the GUI and there
+	    was a hit-enter prompt..
+Files:	    src/gui.c
+
+Patch 6.1.413
+Problem:    When 'clipboard' contains "unnamed", "p" in Visual mode doesn't
+	    work correctly.
+Solution:   Save the register before overwriting it and put the resulting text
+	    on the clipboard afterwards.  (Muraoka Taro)
+Files:	    src/normal.c, src/ops.c
+
+Patch 6.1.414 (extra, depends on 6.1.369)
+Problem:    VMS: Vim busy waits when waiting for input.
+Solution:   Delay for a short while before getting another character.  (Zoltan
+	    Arpadffy)
+Files:	    src/os_vms.c
+
+Patch 6.1.415
+Problem:    When there is a vertical split and a quickfix window, reducing the
+	    size of the Vim window may result in a wrong window layout and a
+	    crash.
+Solution:   When reducing the window size and there is not enough space for
+	    'winfixheight' set the frame height to the larger height, so that
+	    there is a retry while ignoring 'winfixheight'. (Yasuhiro
+	    Matsumoto)
+Files:	    src/window.c
+
+Patch 6.1.416 (depends on 6.1.366)
+Problem:    When using the Netbeans interface, a line with a sign cannot be
+	    changed.
+Solution:   Respect the GUARDEDOFFSET for sign IDs when checking for a guarded
+	    area.
+Files:	    src/netbeans.c
+
+Patch 6.1.417
+Problem:    Unprintable multi-byte characters are not handled correctly.
+	    Multi-byte characters above 0xffff are displayed as another
+	    character.
+Solution:   Handle unprintable multi-byte characters.  Display multi-byte
+	    characters above 0xffff with a marker.  Recognize UTF-16 words and
+	    BOM words as unprintable.  (Daniel Elstner)
+Files:	    src/charset.c, src/mbyte.c, src/screen.c
+
+Patch 6.1.418
+Problem:    The result of strftime() is in the current locals.  Need to
+	    convert it to 'encoding'.
+Solution:   Obtain the current locale and convert the argument for strftime()
+	    to it and the result back to 'encoding'.  (Daniel Elstner)
+Files:	    src/eval.c, src/ex_cmds.c, src/ex_cmds2.c, src/mbyte.c,
+	    src/proto/mbyte.pro, src/option.c, src/os_mswin.c
+
+Patch 6.1.419
+Problem:    Vim doesn't compile on AIX 5.1.
+Solution:   Don't define _NO_PROTO on this system. (Uribarri)
+Files:	    src/auto/configure, src/configure.in
+
+Patch 6.1.420 (extra)
+Problem:    convert_input() has an unnecessary STRLEN().
+	    Conversion from UCS-2 to a codepage uses word count instead of
+	    byte count.
+Solution:   Remove the STRLEN() call. (Daniel Elstner)
+	    Always use byte count for string_convert().
+Files:	    src/gui_w32.c, src/mbyte.c
+
+Patch 6.1.421 (extra, depends on 6.1.354)
+Problem:    MS-Windows 9x: When putting text on the clipboard it can be in
+	    the wrong encoding.
+Solution:   Convert text to the active codepage for CF_TEXT. (Glenn Maynard)
+Files:	    src/os_mswin.c
+
+Patch 6.1.422
+Problem:    Error in .vimrc doesn't cause hit-enter prompt when swapping
+	    screens. (Neil Bird)
+Solution:   Set msg_didany also when sending a message to the terminal
+	    directly.
+Files:	    src/message.c
+
+Patch 6.1.423
+Problem:    Can't find arbitrary text in help files.
+Solution:   Added the ":helpgrep" command.
+Files:	    runtime/doc/various.txt, src/ex_cmds.h, src/ex_docmd.c,
+	    src/proto/quickfix.pro, src/quickfix.c
+
+Patch 6.1.424 (extra)
+Problem:    Win32: Gvim compiled with VC++ 7.0 run on Windows 95 does not show
+	    menu items.
+Solution:   Define $WINVER to avoid an extra item is added to MENUITEMINFO.
+	    (Muraoka Taro)
+Files:	    src/Make_mvc.mak
+
+Patch 6.1.425
+Problem:    ":helptags $VIMRUNTIME/doc" does not add the "help-tags" tag.
+Solution:   Do add the "help-tags" tag for that specific directory.
+Files:	    src/ex_cmds.c
+
+Patch 6.1.426
+Problem:    "--remote-wait +cmd file" waits forever. (Valery Kondakoff)
+Solution:   Don't wait for the "+cmd" argument to have been edited.
+Files:	    src/main.c
+
+Patch 6.1.427
+Problem:    Several error messages for regexp patterns are not translated.
+Solution:   Use _() properly. (Muraoka Taro)
+Files:	    src/regexp.c
+
+Patch 6.1.428
+Problem:    FreeBSD: wait() may hang when compiled with Python support and
+	    doing a system() call in a startup script.
+Solution:   Use waitpid() instead of wait() and poll every 10 msec, just like
+	    what is done in the GUI.
+Files:	    src/os_unix.c
+
+Patch 6.1.429 (depends on 6.1.390)
+Problem:    Crash when using showmarks.vim plugin. (Charles Campbell)
+Solution:   Check for sign_get_text() returning a NULL pointer.
+Files:	    src/screen.c
+
+Patch 6.1.430
+Problem:    In Lisp code backslashed parens should be ignored for "%". (Dorai)
+Solution:   Skip over backslashed parens.
+Files:	    src/search.c
+
+Patch 6.1.431
+Problem:    Debug commands end up in redirected text.
+Solution:   Disable redirection while handling debug commands.
+Files:	    src/ex_cmds2.c
+
+Patch 6.1.432 (depends on 6.1.375)
+Problem:    MS-Windows: ":make %:p" inserts extra backslashes. (David Rennalls)
+Solution:   Don't add backslashes, handle it like ":!cmd".
+Files:	    src/ex_docmd.c
+
+Patch 6.1.433
+Problem:    ":popup" only works for Win32.
+Solution:   Add ":popup" support for GTK.  (Daniel Elstner)
+Files:	    runtime/doc/gui.txt, src/ex_docmd.c, src/gui_gtk.c, src/menu.c,
+	    src/proto/gui_gtk.pro
+
+Patch 6.1.434 (extra)
+Problem:    Win32: When there are more than 32767 lines, the scrollbar has a
+	    roundoff error.
+Solution:   Make a click on an arrow move one line.  Also move the code to
+	    gui_w48.c, there is hardly any difference between the 16 bit and
+	    32 bit versions. (Walter Briscoe)
+Files:	    src/gui_w16.c, src/gui_w32.c, src/gui_w48.c
+
+Patch 6.1.435
+Problem:    ":winsize x" resizes the Vim window to the minimal size. (Andrew
+	    Pimlott)
+Solution:   Give an error message for wrong arguments of ":winsize" and
+	    ":winpos".
+Files:	    src/ex_docmd.c
+
+Patch 6.1.436
+Problem:    When a long UTF-8 file contains an illegal byte it's hard to find
+	    out where it is. (Ron Aaron)
+Solution:   Add the line number to the error message.
+Files:	    src/fileio.c
+
+Patch 6.1.437 (extra, depends on 6.1.421)
+Problem:    Using multi-byte functions when they are not available.
+Solution:   Put the clipboard conversion inside an #ifdef. (Vince Negri)
+	    Also fix a pointer type mistake. (Walter Briscoe)
+Files:	    src/os_mswin.c
+
+Patch 6.1.438
+Problem:    When Perl has thread support Vim cannot use the Perl interface.
+Solution:   Add a configure check and disable Perl when it will not work.
+	    (Aron Griffis)
+Files:	    src/auto/configure, src/configure.in
+
+Patch 6.1.439
+Problem:    Netbeans: A "create" function doesn't actually create a buffer,
+	    following functions may fail.
+Solution:   Create a Vim buffer without a name when "create" is called.
+	    (Gordon Prieur)
+Files:	    runtime/doc/netbeans.txt, src/netbeans.c
+
+Patch 6.1.440
+Problem:    The "@*" command doesn't obtain the actual contents of the
+	    clipboard. (Hari Krishna Dara)
+Solution:   Obtain the clipboard text before executing the command.
+Files:	    src/ops.c
+
+Patch 6.1.441
+Problem:    "zj" and "zk" cannot be used as a motion command after an
+	    operator. (Ralf Hetzel)
+Solution:   Accept these commands as motion commands.
+Files:	    src/normal.c
+
+Patch 6.1.442
+Problem:    Unicode 3.2 defines more space and punctuation characters.
+Solution:   Add the new characters to the Unicode tables. (Raphael Finkel)
+Files:	    src/mbyte.c
+
+Patch 6.1.443 (extra)
+Problem:    Win32: The gvimext.dll build with Borland 5.5 requires another
+	    DLL.
+Solution:   Build a statically linked version by default. (Dan Sharp)
+Files:	    GvimExt/Make_bc5.mak
+
+Patch 6.1.444 (extra)
+Problem:    Win32: Enabling a build with gettext support is not consistent.
+Solution:   Use "GETTEXT" for Borland and msvc makefiles. (Dan Sharp)
+Files:	    src/Make_bc5.mak, src/Make_mvc.mak
+
+Patch 6.1.445 (extra)
+Problem:    DJGPP: get warning for argument of putenv()
+Solution:   Define HAVE_PUTENV to use DJGPP's putenv(). (Walter Briscoe)
+Files:	    src/os_msdos.h
+
+Patch 6.1.446 (extra)
+Problem:    Win32: The MingW makefile uses a different style of arguments than
+	    other makefiles.
+	    Dynamic IME is not supported for Cygwin.
+Solution:   Use "no" and "yes" style arguments.  Remove the use of the
+	    dyn-ming.h include file. (Dan Sharp)
+	    Do not include the ime.h file and adjust the makefile. (Alejandro
+	    Lopez-Valencia)
+Files:	    src/Make_cyg.mak, src/Make_ming.mak, src/gui_w32.c,
+	    src/if_perl.xs, src/if_python.c, src/if_ruby.c, src/os_win32.c
+
+Patch 6.1.447
+Problem:    "make install" uses "make" directly for generating help tags.
+Solution:   Use $(MAKE) instead of "make". (Tim Mooney)
+Files:	    src/Makefile
+
+Patch 6.1.448
+Problem:    'titlestring' has a default maximum width of 50 chars per item.
+Solution:   Remove the default maximum (also for 'statusline').
+Files:	    src/buffer.c
+
+Patch 6.1.449
+Problem:    When "1" and "a" are in 'formatoptions', auto-formatting always
+	    moves a newly added character to the next line. (Servatius Brandt)
+Solution:   Don't move a single character to the next line when it was just
+	    typed.
+Files:	    src/edit.c
+
+Patch 6.1.450
+Problem:    Termcap entry "kB" for back-tab is not recognized.
+Solution:   Use back-tab as the shift-tab code.
+Files:	    src/keymap.h, src/misc2.c, src/term.c
+
+Patch 6.1.451
+Problem:    GUI: When text in the find dialog contains a slash, a backslash is
+	    inserted the next time it is opened. (Mezz)
+Solution:   Remove escaped backslashes and question marks. (Daniel Elstner)
+Files:	    src/gui.c
+
+Patch 6.1.452 (extra, after 6.1.446)
+Problem:    Win32: IME support doesn't work for MSVC.
+Solution:   Use _MSC_VER instead of __MSVC. (Alejandro Lopez-Valencia)
+Files:	    src/gui_w32.c
+
+Patch 6.1.453 (after 6.1.429)
+Problem:    When compiled without sign icons but with sign support, adding a
+	    sign may cause a crash.
+Solution:   Check for the text sign to exist before using it. (Kamil
+	    Burzynski)
+Files:	    src/screen.c
+
+Patch 6.1.454 (extra)
+Problem:    Win32: pasting Russian text in Vim with 'enc' set to cp1251
+	    results in utf-8 bytes.  (Perelyubskiy)
+	    Conversion from DBCS to UCS2 does not work when 'encoding' is not
+	    the active codepage.
+Solution:   Introduce enc_codepage and use it for conversion to 'encoding'
+	    (Glenn Maynard)
+	    Use MultiByteToWideChar() and WideCharToMultiByte() instead of
+	    iconv().  Should do most needed conversions without iconv.dll.
+Files:	    src/globals.h, src/gui_w32.c, src/mbyte.c, src/os_mswin.c,
+	    src/proto/mbyte.pro, src/proto/os_mswin.pro, src/structs.h
+
+Patch 6.1.455
+Problem:    Some Unicode characters can be one or two character cells wide.
+Solution:   Add the 'ambiwidth' option to tell Vim how to display these
+	    characters. (Jungshik Shin)
+	    Also reset the script ID when setting an option to its default
+	    value, so that ":verbose set" won't give wrong info.
+Files:	    runtime/doc/options.txt, src/mbyte.c, src/option.c, src/option.h
+
+Patch 6.1.456 (extra, after 6.1.454)
+Problem:    Win32: IME doesn't work.
+Solution:   ImmGetCompositionStringW() returns the size in bytes, not words.
+	    (Yasuhiro Matsumoto)  Also fix typecast problem.
+Files:	    src/gui_w32.c, src/os_mswin.c
+
+Patch 6.1.457
+Problem:    An empty register in viminfo causes conversion to fail.
+Solution:   Don't convert an empty string. (Yasuhiro Matsumoto)
+Files:	    src/ex_cmds.c, src/mbyte.c
+
+Patch 6.1.458
+Problem:    Compiler warning for pointer.
+Solution:   Add a typecast.
+Files:	    src/ex_cmds.c
+
+Patch 6.1.459 (extra)
+Problem:    Win32: libcall() may return an invalid pointer and cause Vim to
+	    crash.
+Solution:   Add a strict check for the returned pointer. (Bruce Mellows)
+Files:	    src/os_mswin.c
+
+Patch 6.1.460
+Problem:    GTK: after scrolling the text one line with a key, clicking the
+	    arrow of the scrollbar does not always work. (Nam SungHyun)
+Solution:   Always update the scrollbar thumb when the value changed, even
+	    when it would not move, like for RISCOS.  (Daniel Elstner)
+Files:	    src/gui.c, src/gui.h
+
+Patch 6.1.461
+Problem:    When a keymap is active, typing a character in Select mode does
+	    not use it. (Benji Fisher)
+Solution:   Apply Insert mode mapping to the character typed in Select mode.
+Files:	    src/normal.c
+
+Patch 6.1.462
+Problem:    When autocommands wipe out a buffer, a crash may happen. (Hari
+	    Krishna Dara)
+Solution:   Don't decrement the window count of a buffer before calling the
+	    autocommands for it.  When re-using the current buffer, watch out
+	    for autocommands changing the current buffer.
+Files:	    src/buffer.c, src/ex_cmds.c, src/proto/buffer.pro
+
+Patch 6.1.463
+Problem:    When writing a compressed file, the file name that gzip stores in
+	    the file is the weird temporary file name. (David Rennalls)
+Solution:   Use the real file name when possible.
+Files:	    runtime/plugin/gzip.vim
+
+Patch 6.1.464
+Problem:    Crash when using C++ syntax highlighting. (Gerhard Hochholzer)
+Solution:   Check for a negative index.
+Files:	    src/syntax.c
+
+Patch 6.1.465 (after 6.1.454)
+Problem:    Compile error when using cygwin.
+Solution:   Change #ifdef WIN32 to #ifdef WIN3264. (Alejandro Lopez-Valencia)
+	    Undefine WIN32 after including windows.h
+Files:	    src/mbyte.c
+
+Patch 6.1.466
+Problem:    The "-f" argument is a bit obscure.
+Solution:   Add the "--nofork" argument.  Improve the help text a bit.
+Files:	    runtime/doc/starting.txt, src/main.c
+
+Patch 6.1.467
+Problem:    Setting the window title doesn't work for Chinese.
+Solution:   Use an X11 function to convert text to a text property. (Kentaro
+	    Nakazawa)
+Files:	    src/os_unix.c
+
+Patch 6.1.468
+Problem:    ":mksession" also stores folds for buffers which will not be
+	    restored.
+Solution:   Only store folds for a buffer with 'buftype' empty and help files.
+Files:	    src/ex_docmd.c
+
+Patch 6.1.469
+Problem:    'listchars' cannot contain multi-byte characters.
+Solution:   Handle multi-byte UTF-8 list characters. (Matthew Samsonoff)
+Files:	    src/message.c, src/option.c, src/screen.c
+
+Patch 6.1.470 (lang)
+Problem:    Polish messages don't show up correctly on MS-Windows.
+Solution:   Convert messages to cp1250. (Mikolaj Machowski)
+	    Also add English message translations, because it got in the way
+	    of the patch.
+Files:	    Makefile, src/po/Makefile, src/po/en_gb.po, src/po/pl.po
+
+Patch 6.1.471
+Problem:    ":jumps" output continues after pressing "q" at the more-prompt.
+	    (Hari Krishna Dara)
+Solution:   Check for "got_int" being set.
+Files:	    src/mark.c
+
+Patch 6.1.472
+Problem:    When there is an authentication error when connecting to the X
+	    server Vim exits.
+Solution:   Use XSetIOErrorHandler() to catch the error and longjmp() to avoid
+	    the exit.  Also do this in the main loop, so that when the X
+	    server exits a Vim running in a console isn't killed.
+Files:	    src/globals.h, src/main.c, src/os_unix.c
+
+Patch 6.1.473
+Problem:    Referring to $curwin or $curbuf in Perl 5.6 causes a crash.
+Solution:   Add "pTHX_" to cur_val(). (Yasuhiro Matsumoto)
+Files:	    src/if_perl.xs
+
+Patch 6.1.474
+Problem:    When opening the command-line window in Ex mode it's impossible to
+	    go back. (Pavol Juhas)
+Solution:   Reset "exmode_active" and restore it when the command-line window
+	    is closed.
+Files:	    src/ex_getln.c
+
+
+Patch 6.2f.001
+Problem:    The configure check for Ruby didn't work properly for Ruby 1.8.0.
+Solution:   Change the way the Ruby check is done. (Aron Griffis)
+Files:	    src/auto/configure, src/configure.in
+
+Patch 6.2f.002
+Problem:    The output of ":ls" doesn't show whether a buffer had read errors.
+Solution:   Add the "x" flag in the ":ls" output.
+Files:	    runtime/doc/windows.txt, src/buffer.c
+
+Patch 6.2f.003
+Problem:    Test49 doesn't properly test the behavior of ":catch" without an
+	    argument.
+Solution:   Update test49. (Servatius Brandt)
+Files:	    src/testdir/test49.ok, src/testdir/test49.vim
+
+Patch 6.2f.004
+Problem:    "vim --version" always uses CR/LF in the output.
+Solution:   Omit the CR.
+Files:	    src/message.c, src/os_unix.c
+
+Patch 6.2f.005
+Problem:    Two error messages without a colon after the number.
+Solution:   Add the colon. (Taro Muraoka)
+Files:	    src/if_cscope.c
+
+Patch 6.2f.006
+Problem:    When saving a file takes a while and Vim regains focus this can
+	    result in a "file changed outside of Vim" warning and ml_get()
+	    errors. (Mike Williams)
+Solution:   Add the "b_saving" flag to avoid checking the timestamp while the
+	    buffer is being saved. (Michael Schaap)
+Files:	    src/fileio.c, src/structs.h
+
+Patch 6.2f.007
+Problem:    Irix compiler complains about multiple defined symbols.
+	    vsnprintf() is not available.  (Charles Campbell)
+Solution:   Insert EXTERN for variables in globals.h.  Change the configure
+	    check for vsnprintf() from compiling to linking.
+Files:	    src/auto/configure, src/configure.in, src/globals.h
+
+Patch 6.2f.008
+Problem:    The Aap recipe doesn't work with Aap 0.149.
+Solution:   Change targetarg to TARGETARG.  Update the mysign file.
+Files:	    src/main.aap, src/mysign
+
+Patch 6.2f.009 (extra)
+Problem:    Small problem when building with Borland 5.01.
+Solution:   Use mkdir() instead of _mkdir(). (Walter Briscoe)
+Files:	    src/dosinst.h
+
+Patch 6.2f.010
+Problem:    Warning for missing prototypes.
+Solution:   Add missing prototypes. (Walter Briscoe)
+Files:	    src/if_cscope.c
+
+Patch 6.2f.011
+Problem:    The configure script doesn't work with autoconf 2.5x.
+Solution:   Add square brackets around a header check. (Aron Griffis)
+	    Note: touch src/auto/configure after applying this patch.
+Files:	    src/configure.in
+
+Patch 6.2f.012
+Problem:    ":echoerr" doesn't work correctly inside try/endtry.
+Solution:   Don't reset did_emsg inside a try/endtry. (Servatius Brandt)
+Files:	    src/eval.c
+
+Patch 6.2f.013 (extra)
+Problem:    Macintosh: Compiler warning for a trigraph.
+Solution:   Insert a backslash before each question mark. (Peter Cucka)
+Files:	    src/os_mac.h
+
+Patch 6.2f.014 (extra)
+Problem:    Macintosh: ex_eval is not included in the project file.
+Solution:   Add ex_eval. (Dany St-Amant)
+Files:	    src/os_mac.pbproj/project.pbxproj
+
+Patch 6.2f.015 (extra)
+Problem:    Win32: When changing header files not all source files involved
+	    are recompiled.
+Solution:   Improve the dependency rules. (Dan Sharp)
+Files:	    src/Make_cyg.mak, src/Make_ming.mak
+
+Patch 6.2f.016
+Problem:    "vim --version > ff" on non-Unix systems results in a file with a
+	    missing line break at the end. (Bill McCArthy)
+Solution:   Add a line break.
+Files:	    src/main.c
+
+Patch 6.2f.017
+Problem:    Unix: starting Vim in the background and then bringing it to the
+	    foreground may cause the terminal settings to be wrong.
+Solution:   Check for tcsetattr() to return an error, retry when it does.
+	    (Paul Tapper)
+Files:	    src/os_unix.c
+
+Patch 6.2f.018
+Problem:    Mac OS X 10.2: OK is defined to zero in cursus.h while Vim uses
+	    one.  Redefining it causes a warning message.
+Solution:   Undefine OK before defining it to one. (Taro Muraoka)
+Files:	    src/vim.h
+
+Patch 6.2f.019
+Problem:    Mac OS X 10.2: COLOR_BLACK and COLOR_WHITE are defined in
+	    curses.h.
+Solution:   Rename them to PRCOLOR_BLACK and PRCOLOR_WHITE.
+Files:	    src/ex_cmds2.c
+
+Patch 6.2f.020
+Problem:    Win32: test50 produces beeps and fails with some versions of diff.
+Solution:   Remove empty lines and convert the output to dos fileformat.
+Files:	    src/testdir/test50.in
+
+Patch 6.2f.021
+Problem:    Running configure with "--enable-netbeans" disables Netbeans.
+	    (Gordon Prieur)
+Solution:   Fix the tests in configure.in where the default is to enable a
+	    feature.  Fix that "--enable-acl" reported "yes" confusingly.
+Files:	    src/auto/configure, src/configure.in, src/mysign
+
+Patch 6.2f.022
+Problem:    A bogus value for 'foldmarker' is not rejected, possibly causing a
+	    hang. (Derek Wyatt)
+Solution:   Check for a non-empty string before and after the comma.
+Files:	    src/option.c
+
+Patch 6.2f.023
+Problem:    When the help files are not in $VIMRUNTIME but 'helpfile' is
+	    correct Vim still can't find the help files.
+Solution:   Also look for a tags file in the directory of 'helpfile'.
+Files:	    src/tag.c
+
+Patch 6.2f.024
+Problem:    When 'delcombine' is set and a character has more than two
+	    composing characters "x" deletes them all.
+Solution:   Always delete only the last composing character.
+Files:	    src/misc1.c
+
+Patch 6.2f.025
+Problem:    When reading a file from stdin that has DOS line endings but a
+	    missing end-of-line for the last line 'fileformat' becomes "unix".
+	    (Bill McCarthy)
+Solution:   Don't add the missing line break when re-reading the text from the
+	    buffer.
+Files:	    src/fileio.c
+
+Patch 6.2f.026
+Problem:    When typing new text at the command line, old composing characters
+	    may be displayed.
+Solution:   Don't read composing characters from after the end of the
+	    text to be displayed.
+Files:	    src/ex_getln.c, src/mbyte.c, src/message.c, src/proto/mbyte.pro,
+	    src/screen.c
+
+Patch 6.2f.027
+Problem:    Compiler warnings for unsigned char pointers. (Tony Leneis)
+Solution:   Add typecasts to char pointer.
+Files:	    src/quickfix.c
+
+Patch 6.2f.028
+Problem:    GTK: When 'imactivatekey' is empty and XIM is inactive it can't be
+	    made active again.  Cursor isn't updated immediately when changing
+	    XIM activation.  Japanese XIM may hang when using 'imactivatekey'.
+	    Can't activate XIM after typing fFtT command or ":sh".
+Solution:   Properly set the flag that indicates the IM is active.  Update the
+	    cursor right away.  Do not send a key-release event.  Handle
+	    Normal mode and running an external command differently.
+	    (Yasuhiro Matsumoto)
+Files:	    src/mbyte.c
+
+Patch 6.2f.029
+Problem:    Mixing use of int and enum.
+Solution:   Adjust argument type of cs_usage_msg().  Fix wrong typedef.
+Files:	    src/if_cscope.c, src/if_cscope.h
+
+Patch 6.2f.030 (after 6.2f.028)
+Problem:    Cursor moves up when using XIM.
+Solution:   Reset im_preedit_cursor.  (Yasuhiro Matsumoto)
+Files:	    src/mbyte.c
+
+Patch 6.2f.031
+Problem:    Crash when listing a function argument in the debugger. (Ron Aaron)
+Solution:   Init the name field of an argument to NULL.
+Files:	    src/eval.c
+
+Patch 6.2f.032
+Problem:    When a write fails for a ":silent!" while inside try/endtry the
+	    BufWritePost autocommands are not triggered.
+Solution:   Check the emsg_silent flag in should_abort(). (Servatius Brandt)
+Files:	    src/ex_eval.c, src/testdir/test49.ok, src/testdir/test49.vim
+
+Patch 6.2f.033
+Problem:    Cscope: re-entrance problem for ":cscope" command.  Checking for
+	    duplicate database didn't work well for Win95.  Didn't check for
+	    duplicate databases after an empty entry.
+Solution:   Don't set postponed_split too early.  Remember first empty
+	    database entry. (Sergey Khorev)
+Files:	    src/if_cscope.c
+
+Patch 6.2f.034
+Problem:    The netbeans interface cannot be used on systems without
+	    vsnprintf(). (Tony Leneis)
+Solution:   Use EMSG(), EMSGN() and EMSG2() instead.
+Files:	    src/auto/configure, src/configure.in, src/netbeans.c
+
+Patch 6.2f.035
+Problem:    The configure check for the netbeans interface doesn't work if the
+	    socket and nsl libraries are required.
+Solution:   Check for the socket and nsl libraries before the netbeans check.
+Files:	    src/auto/configure, src/configure.in
+
+Patch 6.2f.036
+Problem:    Moving leftwards over text with an illegal UTF-8 byte moves one
+	    byte instead of one character.
+Solution:   Ignore an illegal byte after the cursor position.
+Files:	    src/mbyte.c
+
+Patch 6.2f.037
+Problem:    When receiving a Netbeans command at the hit-enter or more prompt
+	    the screen is redrawn but Vim is still waiting at the prompt.
+Solution:   Quit the prompt like a CTRL-C was typed.
+Files:	    src/netbeans.c
+
+Patch 6.2f.038
+Problem:    The dependency to run autoconf causes a patch for configure.in
+	    to run autoconf, even though the configure script was updated as
+	    well.
+Solution:   Only run autoconf with "make autoconf".
+Files:	    src/Makefile
+
+Patch 6.2f.039
+Problem:    CTRL-W K makes the new top window very high.
+Solution:   When 'equalalways' is set equalize the window heights.
+Files:	    src/window.c
+
+
+==============================================================================
+VERSION 6.3						*version-6.3*
+
+This section is about improvements made between version 6.2 and 6.3.
+
+This is mainly a bug-fix release.  There are also a few new features.
+The major number of new items is in the runtime files and translations.
+
+
+Changed							*changed-6.3*
+-------
+
+The intro message also displays a note about sponsoring Vim, mixed randomly
+with the message about helping children in Uganda.
+
+Included the translated menus, keymaps and tutors with the normal runtime
+files.  The separate "lang" archive now only contains translated messages.
+
+Made the translated menu file names a bit more consistent.  Use "latin1" for
+"iso_8859-1" and "iso_8859-15".
+
+Removed the "file_select.vim" script from the distribution.  It's not more
+useful than other scripts that can be downloaded from www.vim.org.
+
+The "runtime/doc/tags" file is now always in unix fileformat.  On MS-Windows
+it used to be dos fileformat, but ":helptags" generates a unix format file.
+
+
+Added							*added-6.3*
+-----
+
+New commands:
+	:cNfile		go to last error in previous file
+	:cpfile		idem
+	:changes	print the change list
+	:keepmarks	following command keeps marks where they are
+	:keepjumps	following command keeps jumplist and marks
+	:lockmarks	following command keeps marks where they are
+	:redrawstatus	force a redraw of the status line(s)
+
+New options:
+	'antialias'	Mac OS X: use smooth, antialiased fonts
+	'helplang'	preferred help languages
+
+Syntax files:
+	Arch inventory (Nikolai Weibull)
+	Calendar (Nikolai Weibull)
+	Ch (Wayne Cheng)
+	Controllable Regex Mutilator (Nikolai Weibull)
+	D (Jason Mills)
+	Desktop (Mikolaj Machowski)
+	Dircolors (Nikolai Weibull)
+	Elinks configuration (Nikolai Weibull)
+	FASM (Ron Aaron)
+	GrADS scripts (Stefan Fronzek)
+	Icewm menu (James Mahler)
+	LDIF (Zak Johnson)
+	Locale input, fdcc. (Dwayne Bailey)
+	Pinfo config (Nikolai Weibull)
+	Pyrex (Marco Barisione)
+	Relax NG Compact (Nikolai Weibull)
+	Slice (Morel Bodin)
+	VAX Macro Assembly (Tom Uijldert)
+	grads (Stefan Fronzek)
+	libao (Nikolai Weibull)
+	mplayer (Nikolai Weibull)
+	rst (Nikolai Weibull)
+	tcsh (Gautam Iyer)
+	yaml (Nikolai Weibull)
+
+Compiler plugins:
+	ATT dot (Marcos Macedo)
+	Apple Project Builder (Alexander von Below)
+	Intel (David Harrison)
+	bdf (Nikolai Weibull)
+	icc (Peter Puck)
+	javac (Doug Kearns)
+	neato (Marcos Macedo)
+	onsgmls (Robert B. Rowsome)
+	perl (Christian J. Robinson)
+	rst (Nikolai Weibull)
+	se (SmartEiffel) (Doug Kearns)
+	tcl (Doug Kearns)
+	xmlwf (Robert B. Rowsome)
+
+Filetype plugins:
+	Aap (Bram Moolenaar)
+	Ch (Wayne Cheng)
+	Css (Nikolai Weibull)
+	Pyrex (Marco Barisione)
+	Rst (Nikolai Weibull)
+
+Indent scripts:
+	Aap (Bram Moolenaar)
+	Ch (Wayne Cheng)
+	DocBook (Nikolai Weibull)
+	MetaPost (Eugene Minkovskii)
+	Objective-C (Kazunobu Kuriyama)
+	Pyrex (Marco Barisione)
+	Rst (Nikolai Weibull)
+	Tcsh (Gautam Iyer)
+	XFree86 configuration file (Nikolai Weibull)
+	Zsh (Nikolai Weibull)
+
+Keymaps:
+	Greek for cp1253 (Panagiotis Louridas)
+	Hungarian (Magyar) (Laszlo Zavaleta)
+	Persian-Iranian (Behnam Esfahbod)
+
+Message translations:
+	Catalan (Ernest Adrogue)
+	Russian (Vassily Ragosin)
+	Swedish (Johan Svedberg)
+
+Menu translations:
+	Catalan (Ernest Adrogue)
+	Russian (Tim Alexeevsky)
+	Swedish (Johan Svedberg)
+
+Tutor translations:
+	Catalan (Ernest Adrogue)
+	Russian in cp1251 (Alexey Froloff)
+	Slovak in cp1250 and iso8859-2 (Lubos Celko)
+	Swedish (Johan Svedberg)
+	Korean (Kee-Won Seo)
+	UTF-8 version of the Japanese tutor (Yasuhiro Matsumoto) Use this as
+		the original, create the other Japanese tutor by conversion.
+
+Included "russian.txt" help file. (Vassily Ragosin)
+
+Include Encapsulated PostScript and PDF versions of the Vim logo in the extra
+archive.
+
+The help highlighting finds the highlight groups and shows them in the color
+that is actually being used. (idea from Yakov Lerner)
+
+The big Win32 version is now compiled with Ruby interface, version 1.8.  For
+Python version 2.3 is used.  For Perl version 5.8 is used.
+
+The "ftdetect" directory is mentioned in the documentation.  The DOS install
+program creates it.
+
+
+Fixed							*fixed-6.3*
+-----
+
+Test 42 failed on MS-Windows.  Set and reset 'fileformat' and 'binary' options
+here and there.  (Walter Briscoe)
+
+The explorer plugin didn't work for double-byte 'encoding's.
+
+Use "copy /y" in Make_bc5.mak to avoid a prompt for overwriting.
+
+Patch 6.2.001
+Problem:    The ":stopinsert" command doesn't have a help tag.
+Solution:   Add the tag. (Antoine J.  Mechelynck)
+Files:	    runtime/doc/insert.txt, runtime/doc/tags
+
+Patch 6.2.002
+Problem:    When compiled with the +multi_byte feature but without +eval,
+	    displaying UTF-8 characters may cause a crash. (Karsten Hopp)
+Solution:   Also set the default for 'ambiwidth' when compiled without the
+	    +eval feature.
+Files:	    src/option.c
+
+Patch 6.2.003
+Problem:    GTK 2: double-wide characters below 256 are not displayed
+	    correctly.
+Solution:   Check the cell width for characters above 127. (Yasuhiro
+	    Matsumoto)
+Files:	    src/gui_gtk_x11.c
+
+Patch 6.2.004
+Problem:    With a line-Visual selection at the end of the file a "p" command
+	    puts the text one line upwards.
+Solution:   Detect that the last line was deleted and put forward. (Taro
+	    Muraoka)
+Files:	    src/normal.c
+
+Patch 6.2.005
+Problem:    GTK: the "Find" and "Find and Replace" tools don't work. (Aschwin
+	    Marsman)
+Solution:   Show the dialog after creating it.  (David Necas)
+Files:	    src/gui_gtk.c
+
+Patch 6.2.006
+Problem:    The Netbeans code contains an obsolete function that uses "vim61"
+	    and sets the fall-back value for $VIMRUNTIME.
+Solution:   Delete the obsolete function.
+Files:	    src/main.c, src/netbeans.c, src/proto/netbeans.pro
+
+Patch 6.2.007
+Problem:    Listing tags for Cscope doesn't always work.
+Solution:   Avoid using smgs_attr(). (Sergey Khorev)
+Files:	    src/if_cscope.c
+
+Patch 6.2.008
+Problem:    XIM with GTK 2: After backspacing preedit characters are wrong.
+Solution:   Reset the cursor position. (Yasuhiro Matsumoto)
+Files:	    src/mbyte.c
+
+Patch 6.2.009
+Problem:    Win32: The self-installing executable "Full" selection only
+	    selects some of the items to install. (Salman Mohsin)
+Solution:   Change commas to spaces in between section numbers.
+Files:	    nsis/gvim.nsi
+
+Patch 6.2.010
+Problem:    When 'virtualedit' is effective and a line starts with a
+	    multi-byte character, moving the cursor right doesn't work.
+Solution:   Obtain the right character to compute the column offset. (Taro
+	    Muraoka)
+Files:	    src/charset.c
+
+Patch 6.2.011
+Problem:    Alpha OSF1: stat() is a macro and doesn't allow an #ifdef halfway.
+	    (Moshe Kaminsky)
+Solution:   Move the #ifdef outside of stat().
+Files:	    src/os_unix.c
+
+Patch 6.2.012
+Problem:    May hang when polling for a character.
+Solution:   Break the wait loop when not waiting for a character.
+Files:	    src/os_unix.c
+
+Patch 6.2.013 (extra)
+Problem:    Win32: The registry key for uninstalling GvimExt still uses "6.1".
+Solution:   Change the version number to "6.2". (Ajit Thakkar)
+Files:	    src/GvimExt/GvimExt.reg
+
+Patch 6.2.014 (after 6.2.012)
+Problem:    XSMP doesn't work when using poll().
+Solution:   Use xsmp_idx instead of gpm_idx. (Neil Bird)
+Files:	    src/os_unix.c
+
+Patch 6.2.015
+Problem:    The +xsmp feature is never enabled.
+Solution:   Move the #define for USE_XSMP to below where WANT_X11 is defined.
+	    (Alexey Froloff)
+Files:	    src/feature.h
+
+Patch 6.2.016
+Problem:    Using ":scscope find" with 'cscopequickfix' does not always split
+	    the window. (Gary Johnson)
+	    Win32: ":cscope add" could make the script that contains it
+	    read-only until the corresponding ":cscope kill".
+	    Errors during ":cscope add" may not be handled properly.
+Solution:   When using the quickfix window may need to split the window.
+	    Avoid file handle inheritance for the script.
+	    Check for a failed connection and/or process.  (Sergey Khorev)
+Files:	    src/ex_cmds2.c, src/if_cscope.c
+
+Patch 6.2.017
+Problem:    Test11 sometimes prompts the user, because a file would have been
+	    changed outside of Vim. (Antonio Colombo)
+Solution:   Add a FileChangedShell autocommand to avoid the prompt.
+Files:	    src/testdir/test11.in
+
+Patch 6.2.018
+Problem:    When using the XSMP protocol and reading from stdin Vim may wait
+	    for a key to be pressed.
+Solution:   Avoid that RealWaitForChar() is used recursively.
+Files:	    src/os_unix.c
+
+Patch 6.2.019 (lang)
+Problem:    Loading the Portuguese menu causes an error message.
+Solution:   Join two lines.  (Jose Pedro Oliveira, Jos� de Paula)
+Files:	    runtime/lang/menu_pt_br.vim
+
+Patch 6.2.020
+Problem:    The "Syntax/Set syntax only" menu item causes an error message.
+	    (Oyvind Holm)
+Solution:   Set the script-local variable in a function. (Benji Fisher)
+Files:	    runtime/synmenu.vim
+
+Patch 6.2.021
+Problem:    The user manual section on exceptions contains small mistakes.
+Solution:   Give a good example of an error that could be missed and other
+	    improvements. (Servatius Brandt)
+Files:	    runtime/doc/usr_41.txt
+
+Patch 6.2.022 (extra)
+Problem:    Win32: After deleting a menu item it still appears in a tear-off
+	    window.
+Solution:   Set the mode to zero for the deleted item. (Yasuhiro Matsumoto)
+Files:	    src/gui_w32.c
+
+Patch 6.2.023 (extra)
+Problem:    Win32: Make_ivc.mak does not clean everything.
+Solution:   Delete more files in the clean rule. (Walter Briscoe)
+Files:	    src/Make_ivc.mak
+
+Patch 6.2.024 (extra)
+Problem:    Win32: Compiler warnings for typecasts.
+Solution:   Use DWORD instead of WORD. (Walter Briscoe)
+Files:	    src/gui_w32.c
+
+Patch 6.2.025
+Problem:    Missing prototype for sigaltstack().
+Solution:   Add the prototype when it is not found in a header file.
+Files:	    src/os_unix.c
+
+Patch 6.2.026
+Problem:    Warning for utimes() argument.
+Solution:   Add a typecast.
+Files:	    src/fileio.c
+
+Patch 6.2.027
+Problem:    Warning for uninitialized variable.
+Solution:   Set mb_l to one when not using multi-byte characters.
+Files:	    src/message.c
+
+Patch 6.2.028
+Problem:    Cscope connection may kill Vim process and others.
+Solution:   Check for pid being larger than one. (Khorev Sergey)
+Files:	    src/if_cscope.c
+
+Patch 6.2.029
+Problem:    When using the remote server functionality Vim may leak memory.
+	    (Srikanth Sankaran)
+Solution:   Free the result of XListProperties().
+Files:	    src/if_xcmdsrv.c
+
+Patch 6.2.030
+Problem:    Mac: Warning for not being able to use precompiled header files.
+Solution:   Don't redefine select.  Use -no-cpp-precomp for compiling, so that
+	    function prototypes are still found.
+Files:	    src/os_unix.c, src/osdef.sh
+
+Patch 6.2.031
+Problem:    The langmenu entry in the options window doesn't work. (Rodolfo
+	    Lima)
+	    With GTK 1 the ":options" command causes an error message.
+	    (Michael Naumann)
+Solution:   Change "lmenu" to "langmenu".  Only display the 'tbis' option for
+	    GTK 2.
+Files:	    runtime/optwin.vim
+
+Patch 6.2.032
+Problem:    The lpc filetype is never recognized. (Shizhu Pan)
+Solution:   Check for g:lpc_syntax_for_c instead of the local variable
+	    lpc_syntax_for_c. (Benji Fisher)
+Files:	    runtime/filetype.vim
+
+Patch 6.2.033 (extra)
+Problem:    Mac: Various compiler warnings.
+Solution:   Don't include Classic-only headers in Unix version.
+	    Remove references to several unused variables. (Ben Fowler)
+	    Fix double definition of DEFAULT_TERM.
+	    Use int instead of unsigned short for pixel values, so that the
+	    negative error values are recognized.
+Files:	    src/gui_mac.c, src/term.c
+
+Patch 6.2.034
+Problem:    Mac: Compiler warning for redefining DEFAULT_TERM.
+Solution:   Fix double definition of DEFAULT_TERM.
+Files:	    src/term.c
+
+Patch 6.2.035
+Problem:    Mac: Compiler warnings in Python interface.
+Solution:   Make a difference between pure Mac and Unix-Mac. (Peter Cucka)
+Files:	    src/if_python.c
+
+Patch 6.2.036 (extra)
+Problem:    Mac Unix version: If foo is a directory, then ":e f<Tab>" should
+	    expand to ":e foo/" instead of ":e foo" .  (Vadim Zeitlin)
+Solution:   Define DONT_ADD_PATHSEP_TO_DIR only for pure Mac. (Benji Fisher)
+Files:	    src/os_mac.h
+
+Patch 6.2.037
+Problem:    Win32: converting an encoding name to a codepage could result in
+	    an arbitrary number.
+Solution:   make encname2codepage() return zero if the encoding name doesn't
+	    contain a codepage number.
+Files:	    src/mbyte.c
+
+Patch 6.2.038 (extra)
+Problem:    Warning messages when using the MingW compiler. (Bill McCarthy)
+	    Can't compile console version without +mouse feature.
+Solution:   Initialize variables, add parenthesis.
+	    Add an #ifdef around g_nMouseClick. (Ajit Thakkar)
+Files:	    src/eval.c, src/os_win32.c, src/gui_w32.c, src/dosinst.c
+
+Patch 6.2.039 (extra)
+Problem:    More warning messages when using the MingW compiler.
+Solution:   Initialize variables. (Bill McCarthy)
+Files:	    src/os_mswin.c
+
+Patch 6.2.040
+Problem:    FreeBSD: Crash while starting up when compiled with +xsmp feature.
+Solution:   Pass a non-NULL argument to IceAddConnectionWatch().
+Files:	    src/os_unix.c
+
+Patch 6.2.041 (extra, after 6.2.033)
+Problem:    Mac: Compiler warnings for conversion types, missing prototype,
+	    missing return type.
+Solution:   Change sscanf "%hd" to "%d", the argument is an int now.  Add
+	    gui_mch_init_check() prototype.  Add "int" to termlib functions.
+Files:	    src/gui_mac.c, src/proto/gui_mac.pro, src/termlib.c.
+
+Patch 6.2.042 (extra)
+Problem:    Cygwin: gcc 3.2 has an optimizer problem, sometimes causing a
+	    crash.
+Solution:   Add -fno-strength-reduce to the compiler arguments. (Dan Sharp)
+Files:	    src/Make_cyg.mak
+
+Patch 6.2.043
+Problem:    Compiling with both netbeans and workshop doesn't work.
+Solution:   Move the shellRectangle() function to gui_x11.c. (Gordon Prieur)
+Files:	    src/gui_x11.c, src/integration.c, src/netbeans.c,
+	    src/proto/netbeans.pro
+
+Patch 6.2.044
+Problem:    ":au filetypedetect" gives an error for a non-existing event name,
+	    but it's actually a non-existing group name. (Antoine Mechelynck)
+Solution:   Make the error message clearer.
+Files:	    src/fileio.c
+
+Patch 6.2.045
+Problem:    Obtaining the '( mark changes the '' mark. (Gary Holloway)
+Solution:   Don't set the '' mark when searching for the start/end of the
+	    current sentence/paragraph.
+Files:	    src/mark.c
+
+Patch 6.2.046
+Problem:    When evaluating an argument of a function throws an exception the
+	    function is still called. (Hari Krishna Dara)
+Solution:   Don't call the function when an exception was thrown.
+Files:	    src/eval.c
+
+Patch 6.2.047 (extra)
+Problem:    Compiler warnings when using MingW. (Bill McCarthy)
+Solution:   Give the s_dwLastClickTime variable a type.  Initialize dwEndTime.
+Files:	    src/os_win32.c
+
+Patch 6.2.048
+Problem:    The Python interface doesn't compile with Python 2.3 when
+	    dynamically loaded.
+Solution:   Use dll_PyObject_Malloc and dll_PyObject_Free. (Paul Moore)
+Files:	    src/if_python.c
+
+Patch 6.2.049
+Problem:    Using a "-range=" argument with ":command" doesn't work and
+	    doesn't generate an error message.
+Solution:   Generate an error message.
+Files:	    src/ex_docmd.c
+
+Patch 6.2.050
+Problem:    Test 32 didn't work on MS-Windows.
+Solution:   Write the temp file in Unix fileformat. (Walter Briscoe)
+Files:	    src/testdir/test32.in
+
+Patch 6.2.051
+Problem:    When using "\=submatch(0)" in a ":s" command, line breaks become
+	    NUL characters.
+Solution:   Change NL to CR characters, so that they become line breaks.
+Files:	    src/regexp.c
+
+Patch 6.2.052
+Problem:    A few messages are not translated.
+Solution:   Add _() to the messages. (Muraoka Taro)
+Files:	    src/ex_cmds.c
+
+Patch 6.2.053
+Problem:    Prototype for bzero() doesn't match most systems.
+Solution:   Use "void *" instead of "char *" and "size_t" instead of "int".
+Files:	    src/osdef1.h.in
+
+Patch 6.2.054
+Problem:    A double-byte character with a second byte that is a backslash
+	    causes problems inside a string.
+Solution:   Skip over multi-byte characters in a string properly. (Yasuhiro
+	    Matsumoto)
+Files:	    src/eval.c
+
+Patch 6.2.055
+Problem:    Using col('.') from CTRL-O in Insert mode does not return the
+	    correct value for multi-byte characters.
+Solution:   Correct the cursor position when it is necessary, move to the
+	    first byte of a multi-byte character. (Yasuhiro Matsumoto)
+Files:	    src/edit.c
+
+Patch 6.2.056 (extra)
+Problem:    Building with Sniff++ doesn't work.
+Solution:   Use the multi-threaded libc when needed. (Holger Ditting)
+Files:	    src/Make_mvc.mak
+
+Patch 6.2.057 (extra)
+Problem:    Mac: With -DMACOS_X putenv() is defined twice, it is in a system
+	    library.  Get a warning for redefining OK.  Unused variables in
+	    os_mac.c
+Solution:   Define HAVE_PUTENV.  Undefine OK after including curses.h.
+	    Remove declarations for unused variables.
+Files:	    src/os_mac.c, src/os_mac.h, src/vim.h
+
+Patch 6.2.058
+Problem:    When 'autochdir' is set ":bnext" to a buffer without a name causes
+	    a crash.
+Solution:   Don't call vim_chdirfile() when the file name is NULL. (Taro
+	    Muraoka)
+Files:	    src/buffer.c
+
+Patch 6.2.059
+Problem:    When 'scrolloff' is a large number and listing completion results
+	    on the command line, then executing a command that jumps close to
+	    where the cursor was before, part of the screen is not updated.
+	    (Yakov Lerner)
+Solution:   Don't skip redrawing part of the window when it was scrolled.
+Files:	    src/screen.c
+
+Patch 6.2.060 (extra)
+Problem:    Win32: When 'encoding' is set to "iso-8859-7" copy/paste to/from
+	    the clipboard gives a lalloc(0) error. (Kriton Kyrimis)
+Solution:   When the string length is zero allocate one byte.  Also fix that
+	    when the length of the Unicode text is zero (conversion from
+	    'encoding' to UCS-2 was not possible) the normal text is used.
+Files:	    src/os_mswin.c
+
+Patch 6.2.061
+Problem:    GUI: Using the left mouse button with the shift key should work
+	    like "*" but it scrolls instead. (Martin Beller)
+Solution:   Don't recognize an rxvt scroll wheel event when using the GUI.
+Files:	    src/term.c
+
+Patch 6.2.062
+Problem:    When one buffer uses a syntax with "containedin" and another
+	    buffer does not, redrawing depends on what the current buffer is.
+	    (Brett Pershing Stahlman)
+Solution:   Use "syn_buf" instead of "curbuf" to get the b_syn_containedin
+	    flag.
+Files:	    src/syntax.c
+
+Patch 6.2.063
+Problem:    When using custom completion end up with no matches.
+Solution:   Make cmd_numfiles and cmd_files local to completion to avoid that
+	    they are overwritten when ExpandOne() is called recursively by
+	    f_glob().
+Files:	    src/eval.c, src/ex_docmd.c, src/ex_getln.c, src/proto/ex_getln.pro,
+	    src/misc1.c, src/structs.h, src/tag.c
+
+Patch 6.2.064
+Problem:    resolve() only handles one symbolic link, need to repeat it to
+	    resolve all of them.  Then need to simplify the file name.
+Solution:   Make resolve() resolve all symbolic links and simplify the result.
+	    Add simplify() to just simplify a file name.  Fix that test49
+	    doesn't work if /tmp is a symbolic link.  (Servatius Brandt)
+Files:	    runtime/doc/eval.txt, src/eval.c, src/tag.c,
+	    src/testdir/test49.vim
+
+Patch 6.2.065
+Problem:    ":windo 123" only updates other windows when entering them.
+	    (Walter Briscoe)
+Solution:   Update the topline before going to the next window.
+Files:	    src/ex_cmds2.c
+
+Patch 6.2.066 (extra)
+Problem:    Ruby interface doesn't work with Ruby 1.8.0.
+Solution:   Change "defout" to "stdout". (Aron Grifis)
+	    Change dynamic loading. (Taro Muraoka)
+Files:	    src/if_ruby.c, src/Make_mvc.mak
+
+Patch 6.2.067
+Problem:    When searching for a string that starts with a composing character
+	    the command line isn't drawn properly.
+Solution:   Don't count the space to draw the composing character on and
+	    adjust the cursor column after drawing the string.
+Files:	    src/message.c
+
+Patch 6.2.068
+Problem:    Events for the netbeans interface that include a file name with
+	    special characters don't work properly.
+Solution:   Use nb_quote() on the file name. (Sergey Khorev)
+Files:	    src/netbeans.c
+
+Patch 6.2.069 (after 6.2.064)
+Problem:    Unused variables "limit" and "new_st" and unused label "fail" in
+	    some situation. (Bill McCarthy)
+Solution:   Put the declarations inside an #ifdef. (Servatius Brandt)
+Files:	    src/eval.c, src/tag.c
+
+Patch 6.2.070 (after 6.2.069)
+Problem:    Still unused variable "new_st". (Bill McCarthy)
+Solution:   Move the declaration to the right block this time.
+Files:	    src/tag.c
+
+Patch 6.2.071
+Problem:    'statusline' can only contain 50 % items. (Antony Scriven)
+Solution:   Allow 80 items and mention it in the docs.
+Files:	    runtime/doc/option.txt, src/vim.h
+
+Patch 6.2.072
+Problem:    When using expression folding, foldexpr() mostly returns -1 for
+	    the previous line, which makes it difficult to write a fold
+	    expression.
+Solution:   Make the level of the previous line available while still looking
+	    for the end of a fold.
+Files:	    src/fold.c
+
+Patch 6.2.073
+Problem:    When adding detection of a specific filetype for a plugin you need
+	    to edit "filetype.vim".
+Solution:   Source files from the "ftdetect" directory, so that a filetype
+	    detection plugin only needs to be dropped in a directory.
+Files:	    runtime/doc/filetype.txt, runtime/doc/usr_05.txt,
+	    runtime/doc/usr_41.txt, runtime/filetype.vim
+
+Patch 6.2.074
+Problem:    Warnings when compiling the Python interface. (Ajit Thakkar)
+Solution:   Use ANSI function declarations.
+Files:	    src/if_python.c
+
+Patch 6.2.075
+Problem:    When the temp file for writing viminfo can't be used "NULL"
+	    appears in the error message. (Ben Lavender)
+Solution:   Print the original file name when there is no temp file name.
+Files:	    src/ex_cmds.c
+
+Patch 6.2.076
+Problem:    The tags listed for cscope are in the wrong order. (Johannes
+	    Stezenbach)
+Solution:   Remove the reordering of tags for the current file. (Sergey
+	    Khorev)
+Files:	    src/if_cscope.c
+
+Patch 6.2.077
+Problem:    When a user function specifies custom completion, the function
+	    gets a zero argument instead of an empty string when there is no
+	    word before the cursor. (Preben Guldberg)
+Solution:   Don't convert an empty string to a zero.
+Files:	    src/eval.c
+
+Patch 6.2.078
+Problem:    "make test" doesn't work if Vim wasn't compiled yet. (Ed Avis)
+Solution:   Build Vim before running the tests.
+Files:	    src/Makefile
+
+Patch 6.2.079
+Problem:    ":w ++enc=utf-8 !cmd" doesn't work.
+Solution:   Check for the "++" argument before the "!".
+Files:	    src/ex_docmd.c
+
+Patch 6.2.080
+Problem:    When 't_ti' is not empty but doesn't swap screens, using "ZZ" in
+	    an unmodified file doesn't clear the last line.
+Solution:   Call msg_clr_eos() when needed. (Michael Schroeder)
+Files:	    src/os_unix.c
+
+Patch 6.2.081
+Problem:    Problem when using a long multibyte string for the statusline.
+Solution:   Use the right pointer to get the cell size. (Taro Muraoka)
+Files:	    src/buffer.c
+
+Patch 6.2.082
+Problem:    Can't compile with Perl 5.8.1.
+Solution:   Rename "e_number" to "e_number_exp". (Sascha Blank)
+Files:	    src/digraph.c, src/globals.h
+
+Patch 6.2.083
+Problem:    When a compiler uses ^^^^ to mark a word the information is not
+	    visible in the quickfix window. (Srikanth Sankaran)
+Solution:   Don't remove the indent for a line that is not recognized as an
+	    error message.
+Files:	    src/quickfix.c
+
+Patch 6.2.084
+Problem:    "g_" in Visual mode always goes to the character after the line.
+	    (Jean-Rene David)
+Solution:   Ignore the NUL at the end of the line.
+Files:	    src/normal.c
+
+Patch 6.2.085
+Problem:    ":verbose set ts" doesn't say an option was set with a "-c" or
+	    "--cmd" argument.
+Solution:   Remember the option was set from a Vim argument.
+Files:	    src/main.c, src/ex_cmds2.c, src/vim.h
+
+Patch 6.2.086
+Problem:    "{" and "}" stop inside a closed fold.
+Solution:   Only stop once inside a closed fold. (Stephen Riehm)
+Files:	    src/search.c
+
+Patch 6.2.087
+Problem:    CTRL-^ doesn't use the 'confirm' option.  Same problem with
+	    ":bnext". (Yakov Lerner)
+Solution:   Put up a dialog for a changed file when 'confirm' is set in more
+	    situations.
+Files:	    src/buffer.c, src/ex_cmds.c
+
+Patch 6.2.088
+Problem:    When 'sidescrolloff' is set 'showmatch' doesn't work correctly if
+	    the match is less than 'sidescrolloff' off from the side of the
+	    window.  (Roland Stahn)
+Solution:   Set 'sidescrolloff' to zero while displaying the match.
+Files:	    src/search.c
+
+Patch 6.2.089
+Problem:    ":set isk+=" adds a comma. (Mark Waggoner)
+Solution:   Don't add a comma when the added value is empty.
+Files:	    src/option.c
+
+Patch 6.2.090 (extra)
+Problem:    Win32: MingW compiler complains about #pragmas. (Bill McCarthy)
+Solution:   Put an #ifdef around the #pragmas.
+Files:	    src/os_win32.c
+
+Patch 6.2.091
+Problem:    When an autocommand is triggered when a file is dropped on Vim and
+	    it produces output, messages from a following command may be
+	    scrolled unexpectedly. (David Rennalls)
+Solution:   Save and restore msg_scroll in handle_drop().
+Files:	    src/ex_docmd.c
+
+Patch 6.2.092
+Problem:    Invalid items appear in the help file tags. (Antonio Colombo)
+Solution:   Only accept tags with white space before the first "*".
+Files:	    runtime/doc/doctags.c, src/ex_cmds.c
+
+Patch 6.2.093
+Problem:    ":nnoremenu" also defines menu for Visual mode. (Klaus Bosau)
+Solution:   Check the second command character for an "o", not the third.
+Files:	    src/menu.c
+
+Patch 6.2.094
+Problem:    Can't compile with GTK and tiny features.
+Solution:   Include handle_drop() and vim_chdirfile() when FEAT_DND is defined.
+	    Do not try to split the window.
+Files:	    src/ex_docmd.c, src/misc2.c
+
+Patch 6.2.095
+Problem:    The message "Cannot go to buffer x" is confusing for ":buf 6".
+	    (Frans Englich)
+Solution:   Make it "Buffer x does not exist".
+Files:	    src/buffer.c
+
+Patch 6.2.096
+Problem:    Win32: ":let @* = ''" put a newline on the clipboard. (Klaus
+	    Bosau)
+Solution:   Put zero bytes on the clipboard for an empty string.
+Files:	    src/ops.c
+
+Patch 6.2.097
+Problem:    Setting or resetting 'insertmode' in a BufEnter autocommand
+	    doesn't always have immediate effect. (Nagger)
+Solution:   When 'insertmode' is set, set need_start_insertmode, when it's
+	    reset set stop_insert_mode.
+Files:	    src/option.c
+
+Patch 6.2.098 (after 6.2.097)
+Problem:    Can't build Vim with tiny features. (Christian J. Robinson)
+Solution:   Declare stop_insert_mode always.
+Files:	    src/edit.c, src/globals.h
+
+Patch 6.2.099 (extra)
+Problem:    Test 49 fails. (Mikolaj Machowski)
+Solution:   The Polish translation must not change "E116" to "R116".
+Files:	    src/po/pl.po
+
+Patch 6.2.100
+Problem:    "make proto" fails when compiled with the Perl interface.
+Solution:   Remove "-fno.*" from PERL_CFLAGS, cproto sees it as its option.
+Files:	    src/auto/configure, src/configure.in
+
+Patch 6.2.101
+Problem:    When using syntax folding, opening a file slows down a lot when
+	    it's size increases by only 20%. (Gary Johnson)
+Solution:   The array with cached syntax states is leaking entries.  After
+	    cleaning up the list obtain the current entry again.
+Files:	    src/syntax.c
+
+Patch 6.2.102
+Problem:    The macros equal() and CR conflict with a Carbon header file.
+Solution:   Rename equal() to equalpos().  Rename CR to CAR.
+	    Do this in the non-extra files only.
+Files:	    src/ascii.h, src/buffer.c, src/charset.c, src/edit.c, src/eval.c,
+	    src/ex_cmds.c, src/ex_cmds2.c, src/ex_getln.c, src/fileio.c,
+	    src/getchar.c, src/gui.c, src/gui_athena.c, src/gui_gtk_x11.c,
+	    src/gui_motif.c, src/macros.h, src/mark.c, src/message.c,
+	    src/misc1.c, src/misc2.c, src/normal.c, src/ops.c, src/os_unix.c,
+	    src/regexp.c, src/search.c, src/ui.c, src/workshop.c
+
+Patch 6.2.103 (extra)
+Problem:    The macros equal() and CR conflict with a Carbon header file.
+Solution:   Rename equal() to equalpos().  Rename CR to CAR.
+	    Do this in the extra files only.
+Files:	    src/gui_photon.c, src/gui_w48.c
+
+Patch 6.2.104
+Problem:    Unmatched braces in the table with options.
+Solution:   Move the "}," outside of the #ifdef. (Yakov Lerner)
+Files:	    src/option.c
+
+Patch 6.2.105
+Problem:    When the cursor is past the end of the line when calling
+	    get_c_indent() a crash might occur.
+Solution:   Don't look past the end of the line. (NJ Verenini)
+Files:	    src/misc1.c
+
+Patch 6.2.106
+Problem:    Tag searching gets stuck on a very long line in the tags file.
+Solution:   When skipping back to search the first matching tag remember the
+	    offset where searching started looking for a line break.
+Files:	    src/tag.c
+
+Patch 6.2.107 (extra)
+Problem:    The NetBeans interface cannot be used on Win32.
+Solution:   Add support for the NetBeans for Win32.  Add support for reading
+	    XPM files on Win32.  Also fixes that a sign icon with a space in
+	    the file name did not work through the NetBeans interface.
+	    (Sergey Khorev)
+	    Also: avoid repeating error messages when the connection is lost.
+Files:	    Makefile, runtime/doc/netbeans.txt, src/Make_bc5.mak,
+	    src/Make_cyg.mak, src/Make_ming.mak, src/Make_mvc.mak,
+	    src/bigvim.bat, src/feature.h, src/gui_beval.c, src/gui_beval.h,
+	    src/gui_w32.c, src/gui_w48.c, src/menu.c, src/nbdebug.c,
+	    src/nbdebug.h, src/netbeans.c, src/os_mswin.c, src/os_win32.h,
+	    src/proto/gui_beval.pro, src/proto/gui_w32.pro,
+	    src/proto/netbeans.pro, src/proto.h, src/version.c, src/vim.h,
+	    src/xpm_w32.c, src/xpm_w32.h
+
+Patch 6.2.108
+Problem:    Crash when giving a message about ignoring case in a tag. (Manfred
+	    Kuehn)
+Solution:   Use a longer buffer for the message.
+Files:	    src/tag.c
+
+Patch 6.2.109
+Problem:    Compiler warnings with various Amiga compilers.
+Solution:   Add typecast, prototypes, et al. that are also useful for other
+	    systems.  (Flavio Stanchina)
+Files:	    src/eval.c, src/ops.c
+
+Patch 6.2.110
+Problem:    When $LANG includes the encoding, a menu without an encoding name
+	    is not found.
+Solution:   Also look for a menu file without any encoding.
+Files:	    runtime/menu.vim
+
+Patch 6.2.111
+Problem:    Encoding "cp1251" is not recognized.
+Solution:   Add "cp1251" to the table of encodings. (Alexey Froloff)
+Files:	    src/mbyte.c
+
+Patch 6.2.112
+Problem:    After applying patches test32 fails. (Antonio Colombo)
+Solution:   Have "make clean" in the testdir delete *.rej and *.orig files.
+	    Use this when doing "make clean" in the src directory.
+Files:	    src/Makefile, src/testdir/Makefile
+
+Patch 6.2.113
+Problem:    Using ":startinsert" after "$" works like "a" instead of "i".
+	    (Ajit Thakkar)
+Solution:   Reset "w_curswant" for ":startinsert" and reset o_eol in edit().
+Files:	    src/edit.c, src/ex_docmd.c
+
+Patch 6.2.114
+Problem:    When stdout is piped through "tee", the size of the screen may not
+	    be correct.
+Solution:   Use stdin instead of stdout for ioctl() when stdin is a tty and
+	    stdout isn't.
+Files:	    src/os_unix.c
+
+Patch 6.2.115 (extra)
+Problem:    Compiler warnings with various Amiga compilers.
+Solution:   Add typecast, prototypes, et al.  Those changes that are
+	    Amiga-specific. (Flavio Stanchina)
+Files:	    src/fileio.c, src/memfile.c, src/os_amiga.c, src/os_amiga.h,
+	    src/vim.h
+
+Patch 6.2.116 (extra)
+Problem:    German keyboard with Numlock set different from system startup
+	    causes problems.
+Solution:   Ignore keys with code 0xff. (Helmut Stiegler)
+Files:	    src/gui_w48.c
+
+Patch 6.2.117
+Problem:    Breakpoints in loops of sourced files and functions are not
+	    detected. (Hari Krishna Dara)
+Solution:   Check for breakpoints when using lines that were previously read.
+	    (Servatius Brandt)
+Files:	    src/eval.c, src/ex_cmds2.c, src/ex_docmd.c, src/proto/eval.pro,
+	    src/proto/ex_cmds2.pro
+
+Patch 6.2.118 (extra)
+Problem:    Mac: Compiling is done in a non-standard way.
+Solution:   Use the Unix method for Mac OS X, with autoconf.  Add "CARBONGUI"
+	    to Makefile and configure. (Eric Kow)
+	    Move a few prototypes from os_mac.pro to gui_mac.pro.
+Files:	    src/Makefile, src/auto/configure, src/configure.in,
+	    src/config.mk.in, src/gui_mac.c, src/os_mac.h, src/os_macosx.c,
+	    src/proto/gui_mac.pro, src/proto/os_mac.pro,
+	    src/infplist.xml, src/vim.h
+
+Patch 6.2.119 (after 6.2.107)
+Problem:    When packing the MS-Windows archives a few files are missing.
+	    (Guopeng Wen)
+Solution:   Add gui_beval.* to the list of generic source files.
+Files:	    Makefile
+
+Patch 6.2.120
+Problem:    Win32 GUI: The console dialogs are not supported on MS-Windows,
+	    disabling the 'c' flag of 'guioptions'. (Servatius Brandt)
+Solution:   Define FEAT_CON_DIALOG also for GUI-only builds.
+Files:	    src/feature.h
+
+Patch 6.2.121 (after 6.2.118)
+Problem:    Not all make programs support "+=". (Charles Campbell)
+Solution:   Use a normal assignment.
+Files:	    src/Makefile
+
+Patch 6.2.122 (after 6.2.119)
+Problem:    Not all shells can expand [^~].  File missing.  (Guopeng Wen)
+Solution:   Use a simpler pattern.  Add the Aap recipe for the maze program
+	    and a clean version of the source code.
+Files:	    Makefile, runtime/macros/maze/Makefile,
+	    runtime/macros/maze/README.txt, runtime/macros/maze/main.aap,
+	    runtime/macros/maze/mazeclean.c
+
+Patch 6.2.123 (after 6.2.118)
+Problem:    Running configure fails. (Tony Leneis)
+Solution:   Change "==" to "=" for a test.
+Files:	    src/auto/configure, src/configure.in
+
+Patch 6.2.124 (after 6.2.121)(extra)
+Problem:    Mac: Recursive use of M4FLAGS causes problems.  When running Vim
+	    directly it can't find the runtime files.  (Emily Jackson)
+	    Using GNU constructs causes warnings with other make programs.
+	    (Ronald Schild)
+Solution:   Use another name for the M4FLAGS variable.
+	    Don't remove "Vim.app" from the path.
+	    Update the explanation for compiling on the Mac. (Eric Kow)
+	    Don't use $(shell ) and $(addprefix ).
+Files:	    src/INSTALLmac.txt, src/Makefile, src/misc1.c
+
+Patch 6.2.125 (after 6.2.107)
+Problem:    The "winsock2.h" file isn't always available.
+Solution:   Don't include this header file.
+Files:	    src/netbeans.c
+
+Patch 6.2.126
+Problem:    Typing CTRL-C at a confirm() prompt doesn't throw an exception.
+Solution:   Reset "mapped_ctrl_c" in get_keystroke(), so that "got_int" is set
+	    in _OnChar().
+Files:	    src/misc1.c
+
+Patch 6.2.127 (extra)
+Problem:    Win32 console: Typing CTRL-C doesn't throw an exception.
+Solution:   Set got_int immediately when CTRL-C is typed, don't wait for
+	    mch_breakcheck() being called.
+Files:	    src/os_win32.c
+
+Patch 6.2.128 (after 6.2.118)
+Problem:    src/auto/configure is not consistent with src/configure.in.
+Solution:   Use the newly generated configure script.
+Files:	    src/auto/configure
+
+Patch 6.2.129
+Problem:    When 'number' is set 'wrapmargin' does not work Vi-compatible.
+	    (Yasuhiro Matsumoto)
+Solution:   Reduce the textwidth when 'number' is set.  Also for 'foldcolumn'
+	    and similar things.
+Files:	    src/edit.c
+
+Patch 6.2.130 (extra)
+Problem:    Win32 console: When 'restorescreen' is not set exiting Vim causes
+	    the screen to be cleared. (Michael A. Mangino)
+Solution:   Don't clear the screen when exiting and 'restorescreen' isn't set.
+Files:	    src/os_win32.c
+
+Patch 6.2.131 (extra)
+Problem:    Win32: Font handles are leaked.
+Solution:   Free italic, bold and bold-italic handles before overwriting them.
+	    (Michael Wookey)
+Files:	    src/gui_w48.c
+
+Patch 6.2.132 (extra)
+Problem:    Win32: console version doesn't work on latest Windows Server 2003.
+Solution:   Copy 12000 instead of 15000 cells at a time to avoid running out
+	    of memory.
+Files:	    src/os_win32.c
+
+Patch 6.2.133
+Problem:    When starting the GUI a bogus error message about 'imactivatekey'
+	    may be given.
+Solution:   Only check the value of 'imactivatekey' when the GUI is running.
+Files:	    src/gui.c, src/option.c
+
+Patch 6.2.134 (extra)
+Problem:    Win32: When scrolling parts of the window are redrawn when this
+	    isn't necessary.
+Solution:   Only invalidate parts of the window when they are obscured by
+	    other windows. (Michael Wookey)
+Files:	    src/gui_w48.c
+
+Patch 6.2.135
+Problem:    An item <> in the ":command" argument is interpreted as <args>.
+Solution:   Avoid that <> is recognized as <args>.
+Files:	    src/ex_docmd.c
+
+Patch 6.2.136
+Problem:    ":e ++enc=latin1 newfile" doesn't set 'fenc' when the file doesn't
+	    exist.  (Miroslaw Dobrzanski-Neumann)
+Solution:   Set 'fileencoding' to the specified encoding when editing a file
+	    that does not exist.
+Files:	    src/fileio.c
+
+Patch 6.2.137
+Problem:    "d:cmd<CR>" cannot be repeated with ".".  Breaks repeating "d%"
+	    when using the matchit plugin.
+Solution:   Store the command to be repeated.  This is restricted to
+	    single-line commands.
+Files:	    src/ex_docmd.c, src/globals.h, src/normal.c, src/vim.h
+
+Patch 6.2.138 (extra)
+Problem:    Compilation problem on VMS with dynamic buffer on the stack.
+Solution:   Read one byte less than the size of the buffer, so that we can
+	    check for the string length without an extra buffer.
+Files:	    src/os_vms.c
+
+Patch 6.2.139
+Problem:    Code is repeated in the two Perl files.
+Solution:   Move common code from if_perl.xs and if_perlsfio.c to vim.h.
+	    Also fix a problem with generating prototypes.
+Files:	    src/if_perl.xs, src/if_perlsfio.c, src/vim.h
+
+Patch 6.2.140 (after 6.2.121)
+Problem:    Mac: Compiling with Python and Perl doesn't work.
+Solution:   Adjust the configure check for Python to use "-framework Python"
+	    for Python 2.3 on Mac OS/X.
+	    Move "-ldl" after "DynaLoader.a" in the link command.
+	    Change "perllibs" to "PERL_LIBS".
+Files:	    src/auto/configure, src/configure.in, src/config.mk.in
+
+Patch 6.2.141 (extra)
+Problem:    Mac: The b_FSSpec field is sometimes unused.
+Solution:   Change the #ifdef to FEAT_CW_EDITOR and defined it in feature.h
+Files:	    src/fileio.c, src/gui_mac.c, src/structs.h, src/feature.h
+
+Patch 6.2.142 (after 6.2.124)
+Problem:    Mac: building without GUI through configure doesn't work.
+	    When the system is slow, unpacking the resource file takes too
+	    long.
+Solution:   Don't always define FEAT_GUI_MAC when MACOS is defined, define it
+	    in the Makefile.
+	    Add a configure option to skip Darwin detection.
+	    Use a Python script to unpack the resources to avoid a race
+	    condition. (Taro Muraoka)
+Files:	    Makefile, src/Makefile, src/auto/configure, src/configure.in,
+	    src/dehqx.py, src/vim.h
+
+Patch 6.2.143
+Problem:    Using "K" on Visually selected text doesn't work if it ends in
+	    a multi-byte character.
+Solution:   Include all the bytes of the last character. (Taro Muraoka)
+Files:	    src/normal.c
+
+Patch 6.2.144
+Problem:    When "g:html_use_css" is set the HTML header generated by the
+	    2html script is wrong.
+Solution:   Add the header after adding HREF for links.
+	    Also use ":normal!" instead of ":normal" to avoid mappings
+	    getting in the way.
+Files:	    runtime/syntax/2html.vim
+
+Patch 6.2.145 (after 6.2.139)
+Problem:    Undefining "bool" doesn't work for older systems. (Wojtek Pilorz)
+Solution:   Only undefine "bool" on Mac OS.
+Files:	    src/vim.h
+
+Patch 6.2.146
+Problem:    On some systems the prototype for iconv() is wrong, causing a
+	    warning message.
+Solution:   Use a cast (void *) to avoid the warning. (Charles Campbell)
+Files:	    src/fileio.c, src/mbyte.c
+
+Patch 6.2.147
+Problem:    ":s/pat/\=col('.')" always replaces with "1".
+Solution:   Set the cursor to the start of the match before substituting.
+	    (Helmut Stiegler)
+Files:	    src/ex_cmds.c
+
+Patch 6.2.148
+Problem:    Can't break an Insert into several undoable parts.
+Solution:   Add the CTRL-G u command.
+Files:	    runtime/doc/insert.txt, src/edit.c
+
+Patch 6.2.149
+Problem:    When the cursor is on a line past 21,474,748 the indicated
+	    percentage of the position is invalid.  With that many lines
+	    "100%" causes a negative cursor line number, resulting in a crash.
+	    (Daniel Goujot)
+Solution:   Divide by 100 instead of multiplying.  Avoid overflow when
+	    computing the line number for "100%".
+Files:	    src/buffer.c, src/ex_cmds2.c, src/normal.c
+
+Patch 6.2.150
+Problem:    When doing "vim - < file" lines are broken at NUL chars.
+	    (Daniel Goujot)
+Solution:   Change NL characters back to NUL when reading from the temp
+	    buffer.
+Files:	    src/fileio.c
+
+Patch 6.2.151
+Problem:    When doing "vim --remote +startinsert file" some commands are
+	    inserted as text. (Klaus Bosau)
+Solution:   Put all the init commands in one Ex line, not using a <CR>, so
+	    that Insert mode isn't started too early.
+Files:	    src/main.c
+
+Patch 6.2.152
+Problem:    The cursor() function doesn't reset the column offset for
+	    'virtualedit'.
+Solution:   Reset the offset to zero. (Helmut Stiegler)
+Files:	    src/eval.c
+
+Patch 6.2.153
+Problem:    Win32: ":lang german" doesn't use German messages.
+Solution:   Add a table to translate the Win32 language names to two-letter
+	    language codes.
+Files:	    src/ex_cmds2.c
+
+Patch 6.2.154
+Problem:    Python bails out when giving a warning message. (Eugene
+	    Minkovskii)
+Solution:   Set sys.argv[] to an empty string.
+Files:	    src/if_python.c
+
+Patch 6.2.155
+Problem:    Win32: Using ":tjump www" in a help file gives two results.
+	    (Dave Roberts)
+Solution:   Ignore differences between slashes and backslashes when checking
+	    for identical tag matches.
+Files:	    src/tag.c
+
+Patch 6.2.156 (after 6.2.125)
+Problem:    Win32: Netbeans fails to build, EINTR is not defined.
+Solution:   Redefine EINTR to WSAEINTR. (Mike Williams)
+Files:	    src/netbeans.c
+
+Patch 6.2.157
+Problem:    Using "%p" in 'errorformat' gives a column number that is too
+	    high.
+Solution:   Set the flag to use the number as a virtual column.  (Lefteris
+	    Koutsoloukas)
+Files:	    src/quickfix.c
+
+Patch 6.2.158
+Problem:    The sed command on Solaris and HPUX doesn't work for a line that
+	    doesn't end in a newline.
+Solution:   Add a newline when feeding text to sed. (Mark Waggoner)
+Files:	    src/configure.in, src/auto/configure
+
+Patch 6.2.159
+Problem:    When using expression folding and 'foldopen' is "undo" an undo
+	    command doesn't always open the fold.
+Solution:   Save and restore the KeyTyped variable when evaluating 'foldexpr'.
+	    (Taro Muraoka)
+Files:	    src/fold.c
+
+Patch 6.2.160
+Problem:    When 'virtualedit' is "all" and 'selection is "exclusive",
+	    selecting a double-width character below a single-width character
+	    may cause a crash.
+Solution:   Avoid overflow on unsigned integer decrement. (Taro Muraoka)
+Files:	    src/normal.c
+
+Patch 6.2.161 (extra)
+Problem:    VMS: Missing header file.  Reading input busy loops.
+Solution:   Include termdef.h.  Avoid the use of a wait function in
+	    vms_read().  (Frank Ries)
+Files:	    src/os_unix.h, src/os_vms.c
+
+Patch 6.2.162
+Problem:    ":redraw" doesn't always display the text that includes the cursor
+	    position, e.g. after ":call cursor(1, 0)". (Eugene Minkovskii)
+Solution:   Call update_topline() before redrawing.
+Files:	    src/ex_docmd.c
+
+Patch 6.2.163
+Problem:    "make install" may also copy AAPDIR directories.
+Solution:   Delete AAPDIR directories, just like CVS directories.
+Files:	    src/Makefile
+
+Patch 6.2.164 (after 6.2.144)
+Problem:    When "g:html_use_css" is set the HTML header generated by the
+	    2html script is still wrong.
+Solution:   Search for a string instead of jumping to a fixed line number.
+	    Go to the start of the line before inserting the header.
+	    (Jess Thrysoee)
+Files:	    runtime/syntax/2html.vim
+
+Patch 6.2.165
+Problem:    The configure checks hang when using autoconf 2.57.
+Solution:   Invoke AC_PROGRAM_EGREP to set $EGREP. (Aron Griffis)
+Files:	    src/auto/configure, src/configure.in
+
+Patch 6.2.166
+Problem:    When $GZIP contains "-N" editing compressed files doesn't work
+	    properly.
+Solution:   Add "-n" to "gzip -d" to avoid restoring the file name. (Oyvind
+	    Holm)
+Files:	    runtime/plugin/gzip.vim
+
+Patch 6.2.167
+Problem:    The Python interface leaks memory when assigning lines to a
+	    buffer. (Sergey Khorev)
+Solution:   Do not copy the line when calling ml_replace().
+Files:	    src/if_python.c
+
+Patch 6.2.168
+Problem:    Python interface: There is no way to get the indices from a range
+	    object.
+Solution:   Add the "start" and "end" attributes. (Maurice S. Barnum)
+Files:	    src/if_python.c, runtime/doc/if_pyth.txt
+
+Patch 6.2.169
+Problem:    The prototype for _Xmblen() appears in a recent XFree86 header
+	    file, causing a warning for our prototype. (Hisashi T Fujinaka)
+Solution:   Move the prototype to an osdef file, so that it's filtered out.
+Files:	    src/mbyte.c, src/osdef2.h.in
+
+Patch 6.2.170
+Problem:    When using Sun WorkShop the current directory isn't changed to
+	    where the file is.
+Solution:   Set the 'autochdir' option when using WorkShop.  And avoid using
+	    the basename when 'autochdir' is not set.
+Files:	    src/gui_x11.c, src/ex_cmds.c
+
+Patch 6.2.171 (after 6.2.163)
+Problem:    The "-or" argument of "find" doesn't work for SysV systems.
+Solution:   Use "-o" instead. (Gordon Prieur)
+Files:	    src/Makefile
+
+Patch 6.2.172 (after 6.2.169)
+Problem:    The prototype for _Xmblen() still causes trouble.
+Solution:   Include the X11 header file that defines the prototype.
+Files:	    src/osdef2.h.in, src/osdef.sh
+
+Patch 6.2.173 (extra)
+Problem:    Win32: Ruby interface doesn't work with Ruby 1.8.0 for other
+	    compilers than MSVC.
+Solution:   Fix the BC5, Cygwin and Mingw makefiles. (Dan Sharp)
+Files:	    src/Make_bc5.mak, src/Make_cyg.mak, src/Make_ming.mak
+
+Patch 6.2.174
+Problem:    After the ":intro" message only a mouse click in the last line
+	    gets past the hit-return prompt.
+Solution:   Accept a click at or below the hit-return prompt.
+Files:	    src/gui.c, src/message.c
+
+Patch 6.2.175
+Problem:    Changing 'backupext' in a *WritePre autocommand doesn't work.
+	    (William Natter)
+Solution:   Move the use of p_bex to after executing the *WritePre
+	    autocommands.  Also avoids reading allocated memory after freeing.
+Files:	    src/fileio.c
+
+Patch 6.2.176
+Problem:    Accented characters in translated help files are not handled
+	    correctly. (Fabien Vayssiere)
+Solution:   Include "192-255" in 'iskeyword' for the help window.
+Files:	    src/ex_cmds.c
+
+Patch 6.2.177 (extra)
+Problem:    VisVim: Opening a file with a space in the name doesn't work. (Rob
+	    Retter)  Arbitrary commands are being executed. (Neil Bird)
+Solution:   Put a backslash in front of every space in the file name.
+	    (Gerard Blais)  Terminate the CTRL-\ CTRL-N command with a NUL.
+Files:	    src/VisVim/Commands.cpp, src/VisVim/VisVim.rc
+
+Patch 6.2.178
+Problem:    People who don't know how to exit Vim try pressing CTRL-C.
+Solution:   Give a message how to exit Vim when CTRL-C is pressed and it
+	    doesn't cancel anything.
+Files:	    src/normal.c
+
+Patch 6.2.179 (extra)
+Problem:    The en_gb messages file isn't found on case sensitive systems.
+Solution:   Rename en_gb to en_GB. (Mike Williams)
+Files:	    src/po/en_gb.po, src/po/en_GB.po, src/po/Make_ming.mak,
+	    src/po/Make_mvc.mak, src/po/Makefile, src/po/README_mvc.txt
+
+Patch 6.2.180
+Problem:    Compiling with GTK2 on Win32 doesn't work.
+Solution:   Include gdkwin32.h instead of gdkx.h. (Srinath Avadhanula)
+Files:	    src/gui_gtk.c, src/gui_gtk_f.c, src/gui_gtk_x11.c, src/mbyte.c
+
+Patch 6.2.181 (after 6.2.171)
+Problem:    The "-o" argument of "find" has lower priority than the implied
+	    "and" with "-print".
+Solution:   Add parenthesis around the "-o" expression. (Gordon Prieur)
+Files:	    src/Makefile
+
+Patch 6.2.182 (after 6.2.094)
+Problem:    Compilation with tiny features fails because of missing
+	    get_past_head() function.
+Solution:   Adjust the #ifdef for get_past_head().
+Files:	    src/misc1.c
+
+Patch 6.2.183 (after 6.2.178)
+Problem:    Warning for char/unsigned char mixup.
+Solution:   Use MSG() instead of msg(). (Tony Leneis)
+Files:	    src/normal.c
+
+Patch 6.2.184
+Problem:    With 'formatoptions' set to "1aw" inserting text may cause the
+	    paragraph to be ended. (Alan Schmitt)
+Solution:   Temporarily add an extra space to make the paragraph continue
+	    after moving the word after the cursor to the next line.
+	    Also format when pressing Esc.
+Files:	    src/edit.c, src/normal.c, src/proto/edit.pro
+
+Patch 6.2.185
+Problem:    Restoring a session with zero-height windows does not work
+	    properly. (Charles Campbell)
+Solution:   Accept a zero argument to ":resize" as intended.  Add a window
+	    number argument to ":resize" to be able to set the size of other
+	    windows, because the current window cannot be zero-height.
+	    Fix the explorer plugin to avoid changing the window sizes.  Add
+	    the winrestcmd() function for this.
+Files:	    runtime/doc/eval.txt, runtime/plugin/explorer.vim, src/eval.c,
+	    src/ex_cmds.h, src/ex_docmd.c, src/proto/window.pro, src/window.c
+
+Patch 6.2.186 (after 6.2.185)
+Problem:    Documentation file eval.txt contains examples without indent.
+Solution:   Insert the indent.  Also fix other mistakes.
+Files:	    runtime/doc/eval.txt
+
+Patch 6.2.187
+Problem:    Using Insure++ reveals a number of bugs.  (Dominique Pelle)
+Solution:   Initialize variables where needed.  Free allocated memory to avoid
+	    leaks.  Fix comparing tags to avoid reading past allocated memory.
+Files:	    src/buffer.c, src/diff.c, src/fileio.c, src/mark.c, src/misc1.c,
+	    src/misc2.c, src/ops.c, src/option.c, src/tag.c, src/ui.c
+
+Patch 6.2.188 (extra)
+Problem:    MS-Windows: Multi-byte characters in a filename cause trouble for
+	    the window title.
+Solution:   Return when the wide function for setting the title did its work.
+Files:	    src/gui_w48.c
+
+Patch 6.2.189
+Problem:    When setting 'viminfo' after editing a new buffer its marks are
+	    not stored. (Keith Roberts)
+Solution:   Set the "b_marks_read" flag when skipping to read marks from the
+	    viminfo file.
+Files:	    src/fileio.c
+
+Patch 6.2.190
+Problem:    When editing a compressed files, marks are lost.
+Solution:   Add the ":lockmarks" modifier and use it in the gzip plugin.
+	    Make exists() also check for command modifiers, so that the
+	    existence of ":lockmarks" can be checked for.
+	    Also add ":keepmarks" to avoid that marks are deleted when
+	    filtering text.
+	    When deleting lines put marks 'A - 'Z and '0 - '9 at the first
+	    deleted line instead of clearing the mark.  They were kept in the
+	    viminfo file anyway.
+	    Avoid that the gzip plugin puts deleted text in registers.
+Files:	    runtime/doc/motion.txt, runtime/plugin/gzip.vim, src/ex_cmds.c,
+	    src/ex_docmd.c, src/mark.c, src/structs.h
+
+Patch 6.2.191
+Problem:    The intro message is outdated.  Information about sponsoring and
+	    registering is missing.
+Solution:   Show info about sponsoring and registering Vim in the intro
+	    message now and then.  Add help file about sponsoring.
+Files:	    runtime/doc/help.txt, runtime/doc/sponsor.txt, runtime/doc/tags,
+	    runtime/menu.vim, src/version.c
+
+Patch 6.2.192
+Problem:    Using CTRL-T and CTRL-D with "gR" messes up the text.  (Jonahtan
+	    Hankins)
+Solution:   Avoid calling change_indent() recursively.
+Files:	    src/edit.c
+
+Patch 6.2.193
+Problem:    When recalling a search pattern from the history from a ":s,a/c,"
+	    command the '/' ends the search string. (JC van Winkel)
+Solution:   Store the separator character with the history entries.  Escape
+	    characters when needed, replace the old separator with the new one.
+	    Also fixes that recalling a "/" search for a "?" command messes up
+	    trailing flags.
+Files:	    src/eval.c, src/ex_getln.c, src/normal.c, src/proto/ex_getln.pro,
+	    src/search.c, src/tag.c
+
+Patch 6.2.194 (after 6.2.068)
+Problem:    For NetBeans, instead of writing the file and sending an event
+	    about it, tell NetBeans to write the file.
+Solution:   Add the "save" command, "netbeansBuffer" command and
+	    "buttonRelease" event to the netbeans protocol.  Updated the
+	    interface to version 2.2.  (Gordon Prieur)
+	    Also: open a fold when the cursor has been positioned.
+	    Also: fix memory leak, free result of nb_quote().
+Files:	    runtime/doc/netbeans.txt, src/fileio.c, src/netbeans.c,
+	    src/normal.c, src/proto/netbeans.pro, src/structs.h
+
+Patch 6.2.195 (after 6.2.190)
+Problem:    Compiling fails for missing CPO_REMMARK symbol.
+Solution:   Add the patch I forgot to include...
+Files:	    src/option.h
+
+Patch 6.2.196 (after 6.2.191)
+Problem:    Rebuilding the documentation doesn't use the sponsor.txt file.
+Solution:   Add sponsor.txt to the Makefile. (Christian J. Robinson)
+Files:	    runtime/doc/Makefile
+
+Patch 6.2.197
+Problem:    It is not possible to force a redraw of status lines. (Gary
+	    Johnson)
+Solution:   Add the ":redrawstatus" command.
+Files:	    runtime/doc/various.txt, src/ex_cmds.h, src/ex_docmd.c,
+	    src/screen.c
+
+Patch 6.2.198
+Problem:    A few messages are not translated. (Ernest Adrogue)
+Solution:   Mark the messages to be translated.
+Files:	    src/ex_cmds.c
+
+Patch 6.2.199 (after 6.2.194)
+Problem:    Vim doesn't work perfectly well with NetBeans.
+Solution:   When NetBeans saves the file, reset the timestamp to avoid "file
+	    changed" warnings.  Close a buffer in a proper way.  Don't try
+	    giving a debug message with an invalid pointer.  Send a
+	    newDotAndMark message when needed.  Report a change by the "r"
+	    command to NetBeans.  (Gordon Prieur)
+Files:	    src/netbeans.c, src/normal.c
+
+Patch 6.2.200
+Problem:    When recovering a file, 'fileformat' is always the default, thus
+	    writing the file may result in differences. (Penelope Fudd)
+Solution:   Before recovering the file try reading the original file to obtain
+	    the values of 'fileformat', 'fileencoding', etc.
+Files:	    src/memline.c
+
+Patch 6.2.201
+Problem:    When 'autowriteall' is set ":qall" still refuses to exit if there
+	    is a modified buffer. (Antoine Mechelynck)
+Solution:   Attempt writing modified buffers as intended.
+Files:	    src/ex_cmds2.c
+
+Patch 6.2.202
+Problem:    Filetype names of CHILL and ch script are confusing.
+Solution:   Rename "ch" to "chill" and "chscript" to "ch".
+Files:	    runtime/filetype.vim, runtime/makemenu.vim, runtime/synmenu.vim
+	    runtime/syntax/ch.vim, runtime/syntax/chill.vim
+
+Patch 6.2.203
+Problem:    With characterwise text that has more than one line, "3P" works
+	    wrong.  "3p" has the same problem.  There also is a display
+	    problem. (Daniel Goujot)
+Solution:   Perform characterwise puts with a count in the right position.
+Files:	    src/ops.c
+
+Patch 6.2.204 (after 6.2.086)
+Problem:    "]]" in a file with closed folds moves to the end of the file.
+	    (Nam SungHyun)
+Solution:   Find one position in each closed fold, then move to after the fold.
+Files:	    src/search.c
+
+Patch 6.2.205 (extra)
+Problem:    MS-Windows: When the taskbar is at the left or top of the screen,
+	    the Vim window placement is wrong.
+Solution:   Compute the size and position of the window correctly. (Taro
+	    Muraoka)
+Files:	    src/gui_w32.c, src/gui_w48.c
+
+Patch 6.2.206
+Problem:    Multi-byte characters cannot be used as hotkeys in a console
+	    dialog.  (Mattias Erkisson)
+Solution:   Handle multi-byte characters properly.  Also put () or [] around
+	    default hotkeys.
+Files:	    src/message.c, src/macros.h
+
+Patch 6.2.207
+Problem:    When 'encoding' is a multi-byte encoding, expanding an
+	    abbreviation that starts where insertion started results in
+	    characters before the insertion to be deleted.  (Xiangjiang Ma)
+Solution:   Stop searching leftwards for the start of the word at the position
+	    where insertion started.
+Files:	    src/getchar.c
+
+Patch 6.2.208
+Problem:    When using fold markers, three lines in a row have the start
+	    marker and deleting the first one with "dd", a nested fold is not
+	    deleted.  (Kamil Burzynski)
+	    Using marker folding, a level 1 fold doesn't stop when it is
+	    followed by "{{{2", starting a level 2 fold.
+Solution:   Don't stop updating folds at the end of a change when the nesting
+	    level of folds is larger than the fold level.
+	    Correctly compute the number of folds that start at "{{{2".
+	    Also avoid a crash for a NULL pointer.
+Files:	    src/fold.c
+
+Patch 6.2.209
+Problem:    A bogus fold is created when using "P" while the cursor is in the
+	    middle of a closed fold. (Kamil Burzynski)
+Solution:   Correct the line number where marks are modified for closed folds.
+Files:	    src/ops.c
+
+Patch 6.2.210 (extra)
+Problem:    Mac OSX: antialiased fonts are not supported.
+Solution:   Add the 'antialias' option to switch on antialiasing on Mac OSX
+	    10.2 and later. (Peter Cucka)
+Files:	    runtime/doc/options.txt, src/gui_mac.c, src/option.h, src/option.c
+
+Patch 6.2.211 (extra)
+Problem:    Code for handling file dropped on Vim is duplicated.
+Solution:   Move the common code to gui_handle_drop().
+	    Add code to drop the files in the window under the cursor.
+	    Support drag&drop on the Macintosh.  (Taro Muraoka)
+	    When dropping a directory name edit that directory (using the
+	    explorer plugin)
+	    Fix that changing directory with Shift pressed didn't work for
+	    relative path names.
+Files:	    src/fileio.c, src/gui.c, src/gui_gtk_x11.c, src/gui_mac.c,
+	    src/gui_w48.c, src/proto/fileio.pro, src/proto/gui.pro
+
+Patch 6.2.212 (after 6.2.199)
+Problem:    NetBeans: Replacing with a count is not handled correctly.
+Solution:   Move reporting the change outside of the loop for the count.
+	    (Gordon Prieur)
+Files:	    src/normal.c
+
+Patch 6.2.213 (after 6.2.208)
+Problem:    Using marker folding, "{{{1" doesn't start a new fold when already
+	    at fold level 1. (Servatius Brandt)
+Solution:   Correctly compute the number of folds that start at "{{{1".
+Files:	    src/fold.c
+
+Patch 6.2.214 (after 6.2.211) (extra)
+Problem:    Warning for an unused variable.
+Solution:   Delete the declaration. (Bill McCarthy)
+Files:	    src/gui_w48.c
+
+Patch 6.2.215
+Problem:    NetBeans: problems saving an unmodified file.
+Solution:   Add isNetbeansModified() function.  Disable netbeans_unmodified().
+	    (Gordon Prieur)
+Files:	    src/fileio.c, src/netbeans.c, src/proto/netbeans.pro,
+	    runtime/doc/netbeans.txt, runtime/doc/tags
+
+Patch 6.2.216 (after 6.2.206)
+Problem:    Multi-byte characters still cannot be used as hotkeys in a console
+	    dialog.  (Mattias Erkisson)
+Solution:   Make get_keystroke() handle multi-byte characters.
+Files:	    src/misc1.c
+
+Patch 6.2.217
+Problem:    GTK: setting the title doesn't always work correctly.
+Solution:   Invoke gui_mch_settitle(). (Tomas Stehlik)
+Files:	    src/os_unix.c
+
+Patch 6.2.218
+Problem:    Warning for function without prototype.
+Solution:   Add argument types to the msgCB field of the BalloonEval struct.
+Files:	    src/gui_beval.h
+
+Patch 6.2.219
+Problem:    Syntax highlighting hangs on an empty match of an item with a
+	    nextgroup.  (Charles Campbell)
+Solution:   Remember that the item has already matched and don't match it
+	    again at the same position.
+Files:	    src/syntax.c
+
+Patch 6.2.220
+Problem:    When a Vim server runs in a console a remote command isn't handled
+	    before a key is typed.  (Joshua Neuheisel)
+Solution:   Don't try reading more input when a client-server command has been
+	    received.
+Files:	    src/os_unix.c
+
+Patch 6.2.221
+Problem:    No file name completion for ":cscope add".
+Solution:   Add the XFILE flag to ":cscope". (Gary Johnson)
+Files:	    src/ex_cmds.h
+
+Patch 6.2.222
+Problem:    Using "--remote" several times on a row only opens some of the
+	    files. (Dany St-Amant)
+Solution:   Don't delete all typeahead when the server receives a command from
+	    a client, only delete typed characters.
+Files:	    src/main.c
+
+Patch 6.2.223
+Problem:    Cscope: Avoid a hang when cscope waits for a response while Vim
+	    waits for a prompt.
+	    Error messages from Cscope mess up the display.
+Solution:   Detect the hit-enter message and respond by sending a return
+	    character to cscope. (Gary Johnson)
+	    Use EMSG() and strerror() when possible.  Replace perror() with
+	    PERROR() everywhere, add emsg3().
+Files:	    src/diff.c, src/if_cscope.c, src/integration.c, src/message.c,
+	    src/proto/message.pro, src/misc2.c, src/netbeans.c, src/vim.h
+
+Patch 6.2.224
+Problem:    Mac: Can't compile with small features. (Axel Kielhorn)
+Solution:   Also include vim_chdirfile() when compiling for the Mac.
+Files:	    src/misc2.c
+
+Patch 6.2.225
+Problem:    NetBeans: Reported modified state isn't exactly right.
+Solution:   Report a file being modified in the NetBeans way.
+Files:	    src/netbeans.c
+
+Patch 6.2.226 (after 6.2.107) (extra)
+Problem:    The "ws2-32.lib" file isn't always available.
+Solution:   Use "WSock32.lib" instead. (Taro Muraoka, Dan Sharp)
+Files:	    src/Make_cyg.mak, src/Make_ming.mak, src/Make_mvc.mak
+
+Patch 6.2.227 (extra)
+Problem:    The "PC" symbol is defined but not used anywhere.
+Solution:   Remove "-DPC" from the makefiles.
+Files:	    src/Make_bc3.mak, src/Make_bc5.mak, src/Make_cyg.mak,
+	    src/Make_ming.mak
+
+Patch 6.2.228
+Problem:    Receiving CTRL-\ CTRL-N after typing "f" or "m" doesn't switch Vim
+	    back to Normal mode.  Same for CTRL-\ CTRL-G.
+Solution:   Check if the character typed after a command is CTRL-\ and obtain
+	    another character to check for CTRL-N or CTRL-G, waiting up to
+	    'ttimeoutlen' msec.
+Files:	    src/normal.c
+
+Patch 6.2.229
+Problem:    ":function" with a name that uses magic curlies does not work
+	    inside a function.  (Servatius Brandt)
+Solution:   Skip over the function name properly.
+Files:	    src/eval.c
+
+Patch 6.2.230 (extra)
+Problem:    Win32: a complex pattern may cause a crash.
+Solution:   Use __try and __except to catch the exception and handle it
+	    gracefully, when possible.  Add myresetstkoflw() to reset the
+	    stack overflow. (Benjamin Peterson)
+Files:	    src/Make_bc5.mak, src/os_mswin.c src/os_win32.c, src/os_win32.h,
+	    src/proto/os_win32.pro, src/regexp.c
+
+Patch 6.2.231 (after 6.2.046)
+Problem:    Various problems when an error exception is raised from within a
+	    builtin function.  When it is invoked while evaluating arguments
+	    to a function following arguments are still evaluated.  When
+	    invoked with a line range it will be called for remaining lines.
+Solution:   Update "force_abort" also after calling a builtin function, so
+	    that aborting() always returns the correct value. (Servatius
+	    Brandt)
+Files:	    src/eval.c, src/ex_eval.c, src/proto/ex_eval.pro,
+	    src/testdir/test49.ok, src/testdir/test49.vim
+
+Patch 6.2.232
+Problem:    ":python vim.command('python print 2*2')" crashes Vim.  (Eugene
+	    Minkovskii)
+Solution:   Disallow executing a Python command recursively and give an error
+	    message.
+Files:	    src/if_python.c
+
+Patch 6.2.233
+Problem:    On Mac OSX adding -pthread for Python only generates a warning.
+	    The test for Perl threads rejects Perl while it's OK.
+	    Tcl doesn't work at all.
+	    The test for Ruby fails if ruby exists but there are no header
+	    files.  The Ruby library isn't detected properly
+Solution:   Avoid adding -pthread on Mac OSX.  Accept Perl threads when it's
+	    not the 5.5 threads.
+	    Use the Tcl framework for header files.  For Ruby rename cWindow
+	    to cVimWindow to avoid a name clash. (Ken Scott)
+	    Only enable Ruby when the header files can be found.  Use "-lruby"
+	    instead of "libruby.a" when it can't be found.
+Files:	    src/auto/configure, src/configure.in, src/if_ruby.c
+
+Patch 6.2.234
+Problem:    GTK 2 GUI: ":sp" and the ":q" leaves the cursor on the command
+	    line.
+Solution:   Flush output before removing scrollbars.  Also do this in other
+	    places where gui_mch_*() functions are invoked.
+Files:	    src/ex_cmds.c, src/option.c, src/window.c
+
+Patch 6.2.235 (extra)
+Problem:    Win32: Cursor isn't removed with a 25x80 window and doing:
+	    "1830ia<Esc>400a-<Esc>0w0". (Yasuhiro Matsumoto)
+Solution:   Remove the call to gui_undraw_cursor() from gui_mch_insert_lines().
+Files:	    src/gui_w48.c
+
+Patch 6.2.236
+Problem:    Using gvim with Agide gives "connection lost" error messages.
+Solution:   Only give the "connection lost" message when the buffer was once
+	    owned by NetBeans.
+Files:	    src/netbeans.c, src/structs.h
+
+Patch 6.2.237
+Problem:    GTK 2: Thai text is drawn wrong.  It changes when moving the
+	    cursor over it.
+Solution:   Disable the shaping engine, it moves combining characters to a
+	    wrong position and combines characters, while drawing the cursor
+	    doesn't combine characters.
+Files:	    src/gui_gtk_x11.c
+
+Patch 6.2.238 (after 6.2.231)
+Problem:    ":function" does not work inside a while loop. (Servatius Brandt)
+Solution:   Add get_while_line() and pass it to do_one_cmd() when in a while
+	    loop, so that all lines are stored and can be used again when
+	    repeating the loop.
+	    Adjust test 49 so that it checks for the fixed problems.
+	    (Servatius Brandt)
+Files:	    src/digraph.c, src/ex_cmds2.c, src/ex_docmd.c, src/ex_eval.c,
+	    src/proto/ex_cmds2.pro, src/proto/ex_docmd.pro,
+	    src/testdir/test49.in, src/testdir/test49.ok,
+	    src/testdir/test49.vim
+
+Patch 6.2.239
+Problem:    GTK 2: With closed folds the arrow buttons of a vertical scrollbar
+	    often doesn't scroll. (Moshe Kaminsky)
+Solution:   Hackish solution: Detect that the button was pressed from the
+	    mouse pointer position.
+Files:	    src/gui_gtk.c, src/gui.c
+
+Patch 6.2.240
+Problem:    GTK 2: Searching for bitmaps for the toolbar doesn't work as with
+	    other systems.  Need to explicitly use "icon=name".  (Ned Konz,
+	    Christian J.  Robinson)
+Solution:   Search for icons like done for Motif.
+Files:	    src/gui_gtk.c
+
+Patch 6.2.241
+Problem:    GTK 2: Search and Search/Replace dialogs are synced, that makes no
+	    sense.  Buttons are sometimes greyed-out. (Jeremy Messenger)
+Solution:   Remove the code to sync the two dialogs.  Adjust the code to react
+	    to an empty search string to also work for GTK2. (David Necas)
+Files:	    src/gui_gtk.c
+
+Patch 6.2.242
+Problem:    Gnome: "vim --help" only shows the Gnome arguments, not the Vim
+	    arguments.
+Solution:   Don't let the Gnome code remove the "--help" argument and don't
+	    exit at the end of usage().
+Files:	    src/gui_gtk_x11.c, src/main.c
+
+Patch 6.2.243 (extra)
+Problem:    Mac: Dropping a file on a Vim icon causes a hit-enter prompt.
+Solution:   Move the dropped files to the global argument list, instead of the
+	    usual drop handling. (Eckehard Berns)
+Files:	    src/main.c, src/gui_mac.c
+
+Patch 6.2.244
+Problem:    ':echo "\xf7"' displays the illegal byte as if it was a character
+	    and leaves "cho" after it.
+Solution:   When checking the length of a UTF-8 byte sequence and it's shorter
+	    than the number of bytes available, assume it's an illegal byte.
+Files:	    src/mbyte.c
+
+Patch 6.2.245
+Problem:    Completion doesn't work for ":keepmarks" and ":lockmarks".
+Solution:   Add the command modifiers to the table of commands. (Madoka
+	    Machitani)
+Files:	    src/ex_cmds.h, src/ex_docmd.c
+
+Patch 6.2.246
+Problem:    Mac: Starting Vim from Finder doesn't show error messages.
+Solution:   Recognize that output is being displayed by stderr being
+	    "/dev/console".  (Eckehard Berns)
+Files:	    src/main.c, src/message.c
+
+Patch 6.2.247 (after 6.2.193)
+Problem:    When using a search pattern from the viminfo file the last
+	    character is replaced with a '/'.
+Solution:   Store the separator character in the right place. (Kelvin Lee)
+Files:	    src/ex_getln.c
+
+Patch 6.2.248
+Problem:    GTK: When XIM is enabled normal "2" and keypad "2" cannot be
+	    distinguished.
+Solution:   Detect that XIM changes the keypad key to the expected ASCII
+	    character and fall back to the non-XIM code. (Neil Bird)
+Files:	    src/gui_gtk_x11.c, src/mbyte.c, src/proto/mbyte.pro
+
+Patch 6.2.249
+Problem:    ":cnext" moves to the error in the next file, but there is no
+	    method to go back.
+Solution:   Add ":cpfile" and ":cNfile".
+Files:	    src/ex_cmds.h, src/quickfix.c, src/vim.h, runtime/doc/quickfix.txt
+
+Patch 6.2.250
+Problem:    Memory leaks when using signs. (Xavier de Gaye)
+Solution:   Delete the list of signs when unloading a buffer.
+Files:	    src/buffer.c
+
+Patch 6.2.251
+Problem:    GTK: The 'v' flag in 'guioptions' doesn't work. (Steve Hall)
+	    Order of buttons is reversed for GTK 2.2.4.  Don't always get
+	    focus back after handling a dialog.
+Solution:   Make buttons appear vertically when desired.  Reverse the order in
+	    which buttons are added to a dialog.  Move mouse pointer around
+	    when the dialog is done and we don't have focus.
+Files:	    src/gui_gtk.c
+
+Patch 6.2.252 (extra, after 6.2.243)
+Problem:    Mac: Dropping a file on a Vim icon causes a hit-enter prompt for
+	    Mac OS classic.
+Solution:   Remove the #ifdef from the code that fixes it for Mac OSX.
+Files:	    src/gui_mac.c
+
+Patch 6.2.253
+Problem:    When 'tagstack' is not set a ":tag id" command does not work after
+	    a ":tjump" command.
+Solution:   Set "new_tag" when 'tagstack' isn't set. (G. Narendran)
+Files:	    src/tag.c
+
+Patch 6.2.254
+Problem:    May run out of space for error messages.
+Solution:   Keep room for two more bytes.
+Files:	    src/quickfix.c
+
+Patch 6.2.255
+Problem:    GTK: A new item in the popup menu is put just after instead of
+	    just before the right item. (Gabriel Zachmann)
+Solution:   Don't increment the menu item index.
+Files:	    src/gui_gtk.c
+
+Patch 6.2.256
+Problem:    Mac: "macroman" encoding isn't recognized, need to use
+	    "8bit-macroman.
+Solution:   Recognize "macroman" with an alias "mac". (Eckehard Berns)
+Files:	    src/mbyte.c
+
+Patch 6.2.257 (after 6.2.250)
+Problem:    Signs are deleted for ":bdel", but they could still be useful.
+Solution:   Delete signs only for ":bwipe".
+Files:	    src/buffer.c
+
+Patch 6.2.258
+Problem:    GUI: can't disable (grey-out) a popup menu item.  (Ajit Thakkar)
+Solution:   Loop over the popup menus for all modes.
+Files:	    src/menu.c
+
+Patch 6.2.259
+Problem:    If there are messages when exiting, on the console there is a
+	    hit-enter prompt while the message can be read; in the GUI the
+	    message may not be visible.
+Solution:   Use the hit-enter prompt when there is an error message from
+	    writing the viminfo file or autocommands, or when there is any
+	    output in the GUI and 'verbose' is set.  Don't use a hit-enter
+	    prompt for the non-GUI version unless there is an error message.
+Files:	    src/main.c
+
+Patch 6.2.260
+Problem:    GTK 2: Can't quit a dialog with <Esc>.
+	    GTK 1 and 2: <Enter> always gives a result, even when the default
+	    button has been disabled.
+Solution:   Handle these keys explicitly.  When no default button is specified
+	    use the first one (works mostly like it was before).
+Files:	    src/gui_gtk.c
+
+Patch 6.2.261
+Problem:    When 'autoindent' and 'cindent' are set and a line is recognized
+	    as a comment, starting a new line won't do 'cindent' formatting.
+Solution:   Also use 'cindent' formatting for lines that are used as a
+	    comment. (Servatius Brandt)
+Files:	    src/misc1.c
+
+Patch 6.2.262
+Problem:    1 CTRL-W w beeps, even though going to the first window is
+	    possible. (Charles Campbell)
+Solution:   Don't beep.
+Files:	    src/window.c
+
+Patch 6.2.263
+Problem:    Lint warnings: Duplicate function prototypes, duplicate macros,
+	    use of a zero character instead of a zero pointer, unused
+	    variable.  Clearing allocated memory in a complicated way.
+Solution:   Remove the function prototypes from farsi.h.  Remove the
+	    duplicated lines in keymap.h.  Change getvcol() argument from NUL
+	    to NULL.  Remove the "col" variable in regmatch().  Use
+	    lalloc_clear() instead of lalloc(). (Walter Briscoe)
+Files:	    src/farsi.h, src/keymap.h, src/ops.c, src/regexp.c, src/search.c
+
+Patch 6.2.264 (after 6.2.247)
+Problem:    Writing past allocated memory when using a command line from the
+	    viminfo file.
+Solution:   Store the NUL in the right place.
+Files:	    src/ex_getln.c
+
+Patch 6.2.265
+Problem:    Although ":set" is not allowed in the sandbox, ":let &opt = val"
+	    works.
+Solution:   Do allow changing options in the sandbox, but not the ones that
+	    can't be changed from a modeline.
+Files:	    src/ex_cmds.h, src/options.c
+
+Patch 6.2.266
+Problem:    When redirecting output and using ":silent", line breaks are
+	    missing from output of ":map" and ":tselect".  Alignment of
+	    columns is wrong.
+Solution:   Insert a line break where "msg_didout" was tested.  Update msg_col
+	    when redirecting and using ":silent".
+Files:	    src/getchar.c, src/message.c
+
+Patch 6.2.267 (extra)
+Problem:    Win32: "&&" in a tearoff menu is not shown. (Luc Hermitte)
+Solution:   Use the "name" item from the menu instead of the "dname" item.
+Files:	    src/gui_w32.c, src/menu.c
+
+Patch 6.2.268
+Problem:    GUI: When changing 'guioptions' part of the window may be off
+	    screen. (Randall Morris)
+Solution:   Adjust the size of the window when changing 'guioptions', but only
+	    when adding something.
+Files:	    src/gui.c
+
+Patch 6.2.269
+Problem:    Diff mode does not highlight a change in a combining character.
+	    (Raphael Finkel)
+Solution:   Make diff_find_change() multi-byte aware: find the start byte of
+	    a character that contains a change.
+Files:	    src/diff.c
+
+Patch 6.2.270
+Problem:    Completion in Insert mode, then repeating with ".", doesn't handle
+	    composing characters in the completed text. (Raphael Finkel)
+Solution:   Don't skip over composing chars when adding completed text to the
+	    redo buffer.
+Files:	    src/getchar.c
+
+Patch 6.2.271
+Problem:    NetBeans: Can't do "tail -f" on the log.  Passing socket info with
+	    an argument or environment variable is not secure.
+Solution:   Wait after initializing the log.  Allow passing the socket info
+	    through a file. (Gordon Prieur)
+Files:	    runtime/doc/netbeans.txt, src/main.c, src/netbeans.c
+
+Patch 6.2.272
+Problem:    When the "po" directory exists, but "po/Makefile" doesn't,
+	    building fails.  Make loops when the "po" directory has been
+	    deleted after running configure.
+Solution:   Check for the "po/Makefile" instead of just the "po" directory.
+	    Check this again before trying to run make with that Makefile.
+Files:	    src/auto/configure, src/configure.in, src/Makefile
+
+Patch 6.2.273
+Problem:    Changing the sort order in an explorer window for an empty
+	    directory produces error messages. (Doug Kearns)
+Solution:   When an invalid range is used for a function that is not going to
+	    be executed, skip over the arguments anyway.
+Files:	    src/eval.c
+
+Patch 6.2.274
+Problem:    ":print" skips empty lines when 'list' is set and there is no
+	    "eol" in 'listchars'. (Yakov Lerner)
+Solution:   Skip outputting a space for an empty line only when 'list' is set
+	    and the end-of-line character is not empty.
+Files:	    src/message.c
+
+Patch 6.2.275 (extra, after 6.2.267)
+Problem:    Warning for uninitialized variable when using gcc.
+Solution:   Initialize "acLen" to zero. (Bill McCarthy)
+Files:	    src/gui_w32.c
+
+Patch 6.2.276
+Problem:    ":echo X()" does not put a line break between the message that X()
+	    displays and the text that X() returns. (Yakov Lerner)
+Solution:   Invoke msg_start() after evaluating the argument.
+Files:	    src/eval.c
+
+Patch 6.2.277
+Problem:    Vim crashes when a ":runtime ftplugin/ada.vim" causes a recursive
+	    loop. (Robert Nowotniak)
+Solution:   Restore "msg_list" before returning from do_cmdline().
+Files:	    src/ex_docmd.c
+
+Patch 6.2.278
+Problem:    Using "much" instead of "many".
+Solution:   Correct the error message.
+Files:	    src/eval.c
+
+Patch 6.2.279
+Problem:    There is no default choice for a confirm() dialog, now that it is
+	    possible not to have a default choice.
+Solution:   Make the first choice the default choice.
+Files:	    runtime/doc/eval.txt, src/eval.c
+
+Patch 6.2.280
+Problem:    "do" and ":diffget" don't work in the first line and the last line
+	    of a buffer. (Aron Griffis)
+Solution:   Find a difference above the first line and below the last line.
+	    Also fix a few display updating bugs.
+Files:	    src/diff.c, src/fold.c, src/move.c
+
+Patch 6.2.281
+Problem:    PostScript printing doesn't work on Mac OS X 10.3.2.
+Solution:   Adjust the header file. (Mike Williams)
+Files:	    runtime/print/prolog.ps
+
+Patch 6.2.282
+Problem:    When using CTRL-O to go back to a help file, it becomes listed.
+	    (Andrew Nesbit)
+	    Using ":tag" or ":tjump" in a help file doesn't keep the help file
+	    settings (e.g. for 'iskeyword').
+Solution:   Don't mark a buffer as listed when its help flag is set.  Put all
+	    the option settings for a help buffer together in do_ecmd().
+Files:	    src/ex_cmds.c
+
+Patch 6.2.283
+Problem:    The "local additions" in help.txt are used without conversion,
+	    causing latin1 characters showing up wrong when 'enc' is utf-8.
+	    (Antoine J. Mechelynck)
+Solution:   Convert the text to 'encoding'.
+Files:	    src/ex_cmds.c
+
+Patch 6.2.284
+Problem:    Listing a function puts "endfunction" in the message history.
+	    Typing "q" at the more prompt isn't handled correctly when listing
+	    variables and functions.  (Hara Krishna Dara)
+Solution:   Don't use msg() for "endfunction".  Check "got_int" regularly.
+Files:	    src/eval.c
+
+Patch 6.2.285
+Problem:    GUI: In a single wrapped line that fills the window, "gj" in the
+	    last screen line leaves the cursor behind. (Ivan Tarasov)
+Solution:   Undraw the cursor before scrolling the text up.
+Files:	    src/gui.c
+
+Patch 6.2.286
+Problem:    When trying to rename a file and it doesn't exist, the destination
+	    file is deleted anyway. (Luc Deux)
+Solution:   Don't delete the destination when the source doesn't exist. (Taro
+	    Muraoka)
+Files:	    src/fileio.c
+
+Patch 6.2.287 (after 6.2.264)
+Problem:    Duplicate lines are added to the viminfo file.
+Solution:   Compare with existing entries without an offset.  Also fixes
+	    reading very long history lines from viminfo.
+Files:	    src/ex_getln.c
+
+Patch 6.2.288 (extra)
+Problem:    Mac: An external program can't be interrupted.
+Solution:   Don't use the 'c' key for backspace. (Eckehard Berns)
+Files:	    src/gui_mac.c
+
+Patch 6.2.289
+Problem:    Compiling the Tcl interface with thread support causes ":make" to
+	    fail.  (Juergen Salk)
+Solution:   Use $TCL_DEFS from the Tcl config script to obtain the required
+	    compile flags for using the thread library.
+Files:	    src/auto/configure, src/configure.in
+
+Patch 6.2.290 (extra)
+Problem:    Mac: The mousewheel doesn't work.
+Solution:   Add mousewheel support.  Also fix updating the thumb after a drag
+	    and then using another way to scroll.  (Eckehard Berns)
+Files:	    src/gui_mac.c
+
+Patch 6.2.291 (extra)
+Problem:    Mac: the plus button and close button don't do anything.
+Solution:   Make the plus button maximize the window and the close button
+	    close Vim. (Eckehard Berns)
+Files:	    src/gui.c, src/gui_mac.c
+
+Patch 6.2.292
+Problem:    Motif: When removing GUI arguments from argv[] a "ps -ef" shows
+	    the last argument repeated.
+Solution:   Set argv[argc] to NULL. (Michael Jarvis)
+Files:	    src/gui_x11.c
+
+Patch 6.2.293 (after 6.2.255)
+Problem:    GTK: A new item in a menu is put before the tearoff item.
+Solution:   Do increment the menu item index for non-popup menu items.
+Files:	    src/gui_gtk.c
+
+Patch 6.2.294 (extra)
+Problem:    Mac: Cannot use modifiers with Space, Tab, Enter and Escape.
+Solution:   Handle all modifiers for these keys.  (Eckehard Berns)
+Files:	    src/gui_mac.c
+
+Patch 6.2.295
+Problem:    When in debug mode, receiving a message from a remote client
+	    causes a crash.  Evaluating an expression causes Vim to wait for
+	    "cont" to be typed, without a prompt.  (Hari Krishna Dara)
+Solution:   Disable debugging when evaluating an expression for a client.
+	    (Michael Geddes)  Don't try reading into the typeahead buffer when
+	    it may have been filled in another way.
+Files:	    src/ex_getln.c, src/getchar.c, src/if_xcmdsrv.c, src/main.c,
+	    src/misc1.c, src/proto/getchar.pro, src/proto/main.pro,
+	    src/proto/os_unix.pro, src/proto/ui.pro, src/structs.h,
+	    src/os_unix.c, src/ui.c
+
+Patch 6.2.296 (extra)
+Problem:    Same as 6.2.295.
+Solution:   Extra files for patch 6.2.295.
+Files:	    src/os_amiga.c, src/os_msdos.c, src/os_riscos.c, src/os_win32.c,
+	    src/proto/os_amiga.pro, src/proto/os_msdos.pro,
+	    src/proto/os_riscos.pro, src/proto/os_win32.pro
+
+Patch 6.2.297 (after 6.2.232)
+Problem:    Cannot invoke Python commands recursively.
+Solution:   With Python 2.3 and later use the available mechanisms to invoke
+	    Python recursively. (Matthew Mueller)
+Files:	    src/if_python.c
+
+Patch 6.2.298
+Problem:    A change always sets the '. mark and an insert always sets the '^
+	    mark, even when this is not wanted.
+	    Cannot go back to the position of older changes without undoing
+	    those changes.
+Solution:   Add the ":keepjumps" command modifier.
+	    Add the "g," and "g;" commands.
+Files:	    runtime/doc/motion.txt, src/ex_cmds.h, src/ex_docmd.c, src/edit.c,
+	    src/mark.c, src/misc1.c, src/normal.c, src/proto/mark.pro,
+	    src/structs.h, src/undo.c
+
+Patch 6.2.299
+Problem:    Can only use one language for help files.
+Solution:   Add the 'helplang' option to select the preferred language(s).
+	    Make ":helptags" generate tags files for all languages.
+Files:	    runtime/doc/options.txt, runtime/doc/various.txt, src/Makefile,
+	    src/ex_cmds.c, src/ex_cmds2.c, src/ex_cmds.h, src/ex_getln.c,
+	    src/normal.c, src/option.c, src/option.h, src/proto/ex_cmds.pro,
+	    src/proto/ex_cmds2.pro, src/proto/option.pro, src/structs.h,
+	    src/tag.c, src/vim.h
+
+Patch 6.2.300 (after 6.2.297)
+Problem:    Cannot build Python interface with Python 2.2 or earlier.
+Solution:   Add a semicolon.
+Files:	    src/if_python.c
+
+Patch 6.2.301
+Problem:    The "select all" item from the popup menu doesn't work for Select
+	    mode.
+Solution:   Use the same commands as for the "Edit.select all" menu.
+	    (Benji Fisher)
+Files:	    runtime/menu.vim
+
+Patch 6.2.302
+Problem:    Using "CTRL-O ." in Insert mode doesn't work properly. (Benji
+	    Fisher)
+Solution:   Restore "restart_edit" after an insert command that was not typed.
+	    Avoid waiting with displaying the mode when there is no text to be
+	    overwritten.
+	    Fix that "CTRL-O ." sometimes doesn't put the cursor back after
+	    the end-of-line.  Only reset the flag that CTRL-O was used past
+	    the end of the line when restarting editing.  Update "o_lnum"
+	    number when inserting text and "o_eol" is set.
+Files:	    src/edit.c, src/normal.c
+
+Patch 6.2.303
+Problem:    Cannot use Unicode digraphs while 'encoding' is not Unicode.
+Solution:   Convert the character from Unicode to 'encoding' when needed.
+	    Use the Unicode digraphs for the Macintosh. (Eckehard Berns)
+Files:	    src/digraph.c
+
+Patch 6.2.304 (extra, after 6.2.256)
+Problem:    Mac: No proper support for 'encoding'.  Conversion without iconv()
+	    is not possible.
+Solution:   Convert input from 'termencoding' to 'encoding'.  Add
+	    mac_string_convert().  Convert text for the clipboard when needed.
+	    (Eckehard Berns)
+Files:	    src/gui_mac.c, src/mbyte.c, src/structs.h, src/vim.h
+
+Patch 6.2.305 (after 6.2.300)
+Problem:    Win32: Cannot build Python interface with Python 2.3. (Ajit
+	    Thakkar)
+Solution:   Add two functions to the dynamic loading feature.
+Files:	    src/if_python.c
+
+Patch 6.2.306 (extra)
+Problem:    Win32: Building console version with BCC 5.5 gives a warning for
+	    get_cmd_args() prototype missing.  (Ajit Thakkar)
+Solution:   Don't build os_w32exe.c for the console version.
+Files:	    src/Make_bc5.mak
+
+Patch 6.2.307 (after 6.2.299)
+Problem:    Installing help files fails.
+Solution:   Expand wildcards for translated help files separately.
+Files:	    src/Makefile
+
+Patch 6.2.308
+Problem:    Not all systems have "whoami", resulting in an empty user name.
+Solution:   Use "logname" when possible, "whoami" otherwise.  (David Boyce)
+Files:	    src/Makefile
+
+Patch 6.2.309
+Problem:    "3grx" waits for two ESC to be typed.  (Jens Paulus)
+Solution:   Append the ESC to the stuff buffer when redoing the "gr" insert.
+Files:	    src/edit.c
+
+Patch 6.2.310
+Problem:    When setting 'undolevels' to -1, making a change and setting
+	    'undolevels' to a positive value an "undo list corrupt" error
+	    occurs. (Madoka Machitani)
+Solution:   Sync undo before changing 'undolevels'.
+Files:	    src/option.c
+
+Patch 6.2.311 (after 6.2.298)
+Problem:    When making several changes in one line the changelist grows
+	    quickly.  There is no error message for reaching the end of the
+	    changelist.  Reading changelist marks from viminfo doesn't work
+	    properly.
+Solution:   Only make a new entry in the changelist when making a change in
+	    another line or 'textwidth' columns away.  Add E662, E663 and E664
+	    error messages.  Put a changelist mark from viminfo one position
+	    before the end.
+Files:	    runtime/doc/motion.txt, src/mark.c, src/misc1.c, src/normal.c
+
+Patch 6.2.312 (after 6.2.299)
+Problem:    "make install" clears the screen when installing the docs.
+Solution:   Execute ":helptags" in silent mode.
+Files:	    runtime/doc/Makefile
+
+Patch 6.2.313
+Problem:    When opening folds in a diff window, other diff windows no longer
+	    show the same text.
+Solution:   Sync the folds in diff windows.
+Files:	    src/diff.c, src/fold.c, src/move.c, src/proto/diff.pro,
+	    src/proto/move.pro
+
+Patch 6.2.314
+Problem:    When 'virtualedit' is set "rx" may cause a crash with a blockwise
+	    selection and using "$". (Moritz Orbach)
+Solution:   Don't try replacing chars in a line that has no characters in the
+	    block.
+Files:	    src/ops.c
+
+Patch 6.2.315
+Problem:    Using CTRL-C in a Visual mode mapping while 'insertmode' is set
+	    stops Vim from returning to Insert mode.
+Solution:   Don't reset "restart_edit" when a CTRL-C is found and 'insertmode'
+	    is set.
+Files:	    src/normal.c
+
+Patch 6.2.316 (after 6.2.312)
+Problem:    "make install" tries connecting to the X server when installing
+	    the docs. (Stephen Thomas)
+Solution:   Add the "-X" argument.
+Files:	    runtime/doc/Makefile
+
+Patch 6.2.317 (after 6.2.313)
+Problem:    When using "zi" in a diff window, other diff windows are not
+	    adjusted. (Richard Curnow)
+Solution:   Distribute a change in 'foldenable' to other diff windows.
+Files:	    src/normal.c
+
+Patch 6.2.318
+Problem:    When compiling with _THREAD_SAFE external commands don't echo
+	    typed characters.
+Solution:   Don't set the terminal mode to TMODE_SLEEP when it's already at
+	    TMODE_COOK.
+Files:	    src/os_unix.c
+
+Patch 6.2.319 (extra)
+Problem:    Building gvimext.dll with Mingw doesn't work properly.
+Solution:   Use gcc instead of dllwrap.  Use long option names. (Alejandro
+	    Lopez-Valencia)
+Files:	    src/GvimExt/Make_ming.mak
+
+Patch 6.2.320
+Problem:    Win32: Adding and removing the menubar resizes the Vim window.
+	    (Jonathon Merz)
+Solution:   Don't let a resize event change 'lines' unexpectedly.
+Files:	    src/gui.c
+
+Patch 6.2.321
+Problem:    When using modeless selection, wrapping lines are not recognized,
+	    a line break is always inserted.
+Solution:   Add LineWraps[] to remember whether a line wrapped or not.
+Files:	    src/globals.h, src/screen.c, src/ui.c
+
+Patch 6.2.322
+Problem:    With 'showcmd' set, after typing "dd" the next "d" may not be
+	    displayed. (Jens Paulus)
+Solution:   Redraw the command line after updating the screen, scrolling may
+	    have set "clear_cmdline".
+Files:	    src/screen.c
+
+Patch 6.2.323
+Problem:    Win32: expanding "~/file" in an autocommand pattern results in
+	    backslashes, while this pattern should only have forward slashes.
+Solution:   Make expanding environment variables respect 'shellslash' and set
+	    p_ssl when expanding the autocommand pattern.
+Files:	    src/fileio.c, src/misc1.c, src/proto/fileio.pro
+
+Patch 6.2.324 (extra)
+Problem:    Win32: when "vimrun.exe" has a path with white space, such as
+	    "Program Files", executing external commands may fail.
+Solution:   Put double quotes around the path to "vimrun".
+Files:	    src/os_win32.c
+
+Patch 6.2.325
+Problem:    When $HOME includes a space, doing ":set tags=~/tags" doesn't
+	    work, the space is used to separate file names.  (Brett Stahlman)
+Solution:   Escape the space with a backslash.
+Files:	    src/option.c
+
+Patch 6.2.326
+Problem:    ":windo set syntax=foo" doesn't work.  (Tim Chase)
+Solution:   Don't change 'eventignore' for ":windo".
+Files:	    src/ex_cmds2.c
+
+Patch 6.2.327
+Problem:    When formatting text all marks in the formatted lines are lost.
+	    A word is not joined to a previous line when this would be
+	    possible.  (Mikolaj Machowski)
+Solution:   Try to keep marks in the same position as much as possible.
+	    Also keep mark positions when joining lines.
+	    Start auto-formatting in the previous line when appropriate.
+	    Add the "gw" operator: Like "gq" but keep the cursor where it is.
+Files:	    runtime/doc/change.txt, src/edit.c, src/globals.h, src/mark.c,
+	    src/misc1.c, src/normal.c, src/ops.c, src/proto/edit.pro,
+	    src/proto/mark.pro, src/proto/ops.pro, src/structs.h, src/vim.h
+
+Patch 6.2.328
+Problem:    XIM with GTK: It is hard to understand what XIM is doing.
+Solution:   Add xim_log() to log XIM events and help with debugging.
+Files:	    src/mbyte.c
+
+Patch 6.2.329
+Problem:    ":=" does not work Vi compatible. (Antony Scriven)
+Solution:   Print the last line number instead of the current line.  Don't
+	    print "line".
+Files:	    src/ex_cmds.h, src/ex_docmd.c
+
+Patch 6.2.330 (extra, after 6.2.267)
+Problem:    Win32: Crash when tearing off a menu.
+Solution:   Terminate a string with a NUL. (Yasuhiro Matsumoto)
+Files:	    src/gui_w32.c
+
+Patch 6.2.331 (after 6.2.327)
+Problem:    "gwap" leaves cursor in the wrong line.
+Solution:   Remember the cursor position before finding the ends of the
+	    paragraph.
+Files:	    src/normal.c, src/ops.c, src/structs.h
+
+Patch 6.2.332 (extra)
+Problem:    Amiga: Compile error for string array. Compiling the Amiga GUI
+	    doesn't work.
+Solution:   Use a char pointer instead.  Move including "gui_amiga.h" to after
+	    including "vim.h".  Add a semicolon. (Ali Akcaagac)
+Files:	    src/gui_amiga.c, src/os_amiga.c
+
+Patch 6.2.333 (extra)
+Problem:    Win32: printing doesn't work with specified font charset.
+Solution:   Use the specified font charset. (Mike Williams)
+Files:	    src/os_mswin.c
+
+Patch 6.2.334 (extra, after 6.2.296)
+Problem:    Win32: evaluating client expression in debug mode requires typing
+	    "cont".
+Solution:   Use eval_client_expr_to_string().
+Files:	    src/os_mswin.c
+
+Patch 6.2.335
+Problem:    The ":sign" command cannot be followed by another command.
+Solution:   Add TRLBAR to the command flags.
+Files:	    src/ex_cmds.h
+
+Patch 6.2.336 (after 6.2.327)
+Problem:    Mixup of items in an expression.
+Solution:   Move "== NUL" to the right spot.
+Files:	    src/edit.c
+
+Patch 6.2.337 (extra, after 6.2.319)
+Problem:    Building gvimext.dll with Mingw doesn't work properly.
+Solution:   Fix white space and other details. (Alejandro Lopez-Valencia)
+Files:	    src/GvimExt/Make_ming.mak
+
+Patch 6.2.338 (after 6.2.331)
+Problem:    When undoing "gwap" the cursor is always put at the start of the
+	    paragraph.  When undoing auto-formatting the cursor may be above
+	    the change.
+Solution:   Try to move the cursor back to where it was or to the first line
+	    that actually changed.
+Files:	    src/normal.c, src/ops.c, src/undo.c
+
+Patch 6.2.339
+Problem:    Crash when using many different highlight groups and a User
+	    highlight group.  (Juergen Kraemer)
+Solution:   Do not use the sg_name_u pointer when it is NULL.  Also simplify
+	    use of the highlight group table.
+Files:	    src/syntax.c
+
+Patch 6.2.340
+Problem:    ":reg" doesn't show the actual contents of the clipboard if it was
+	    filled outside of Vim. (Stuart MacDonald)
+Solution:   Obtain the clipboard contents before displaying it.
+Files:	    src/ops.c
+
+Patch 6.2.341 (extra)
+Problem:    Win32: When the path to diff.exe contains a space and using the
+	    vimrc generated by the install program, diff mode does not work.
+Solution:   Put the first double quote just before the space instead of before
+	    the path.
+Files:	    src/dosinst.c
+
+Patch 6.2.342 (extra)
+Problem:    Win32: macros are not always used as expected.
+Solution:   Define WINVER to 0x0400 instead of 0x400. (Alejandro
+	    Lopez-Valencia)
+Files:	    src/Make_bc5.mak, src/Make_cyg.mak, src/Make_mvc.mak
+
+Patch 6.2.343
+Problem:    Title doesn't work with some window managers.  X11: Setting the
+	    text property for the window title is hard coded.
+Solution:   Use STRING format when possible.  Use the UTF-8 function when
+	    it's available and 'encoding' is utf-8. Use
+	    XStringListToTextProperty().  Do the same for the icon name.
+	    (David Harrison)
+Files:	    src/os_unix.c
+
+Patch 6.2.344 (extra, after 6.2.337)
+Problem:    Cannot build gvimext.dll with MingW on Linux.
+Solution:   Add support for cross compiling. (Ronald Hoellwarth)
+Files:	    src/GvimExt/Make_ming.mak
+
+Patch 6.2.345 (extra)
+Problem:    Win32: Copy/paste between two Vims fails if 'encoding' is not set
+	    properly or there are illegal bytes.
+Solution:   Use a raw byte format.  Always set it when copying.  When pasting
+	    use the raw format if 'encoding' is the same.
+Files:	    src/os_mswin.c, src/os_win16.c, src/os_win32.c, src/vim.h
+
+Patch 6.2.346
+Problem:    Win32 console: After using "chcp" Vim does not detect the
+	    different codepage.
+Solution:   Use GetConsoleCP() and when it is different from GetACP() set
+	    'termencoding'.
+Files:	    src/option.c
+
+Patch 6.2.347 (extra)
+Problem:    Win32: XP theme support is missing.
+Solution:   Add a manifest and refer to it from the resource file.  (Michael
+	    Wookey)
+Files:	    Makefile, src/gvim.exe.mnf, src/vim.rc
+
+Patch 6.2.348
+Problem:    Win32: "vim c:\dir\(test)" doesn't work, because the 'isfname'
+	    default value doesn't contain parenthesis.
+Solution:   Temporarily add '(' and ')' to 'isfname' when expanding file name
+	    arguments.
+Files:	    src/main.c
+
+Patch 6.2.349
+Problem:    Finding a match using 'matchpairs' may cause a crash.
+	    'matchpairs' is not used for 'showmatch'.
+Solution:   Don't look past the NUL in 'matchpairs'.  Use 'matchpairs' for
+	    'showmatch'. (Dave Olszewkski)
+Files:	    src/misc1.c, src/normal.c, src/proto/search.pro, src/search.c
+
+Patch 6.2.350
+Problem:    Not enough info about startup timing.
+Solution:   Add a few more TIME_MSG() calls.
+Files:	    src/main.c
+
+Patch 6.2.351
+Problem:    Win32: $HOME may be set to %USERPROFILE%.
+Solution:   Expand %VAR% at the start of $HOME.
+Files:	    src/misc1.c
+
+Patch 6.2.352 (after 6.2.335)
+Problem:    ":sign texthl=||" does not work.
+Solution:   Remove the check for a following command.  Give an error for extra
+	    arguments after "buff=1".
+Files:	    src/ex_cmds.c, src/ex_cmds.h
+
+Patch 6.2.353 (extra)
+Problem:    Win32: Supported server name length is limited. (Paul Bossi)
+Solution:   Use MAX_PATH instead of 25.
+Files:	    src/os_mswin.c
+
+Patch 6.2.354 (extra)
+Problem:    Win32: When the mouse pointer is on a tear-off menu it is hidden
+	    when typing but is not redisplayed when moved. (Markx Hackmann)
+Solution:   Handle the pointer move event for the tear-off menu window.
+Files:	    src/gui_w32.c
+
+Patch 6.2.355 (after 6.2.303)
+Problem:    When 'encoding' is a double-byte encoding different from the
+	    current locale, the width of characters is not correct.
+	    Possible failure and memory leak when using iconv, Unicode
+	    digraphs and 'encoding' is not "utf-8".
+Solution:   Use iconv() to discover the actual width of characters.
+	    Add the "vc_fail" field to vimconv_T.
+	    When converting a digraph, init the conversion type to NONE and
+	    cleanup afterwards.
+Files:	    src/digraph.c, src/mbyte.c, src/structs.h
+
+Patch 6.2.356
+Problem:    When using a double-byte 'encoding' and 'selection' is
+	    "exclusive", "vy" only yanks the first byte of a double-byte
+	    character.  (Xiangjiang Ma)
+Solution:   Correct the column in unadjust_for_sel() to position on the first
+	    byte, always include the trailing byte of the selected text.
+Files:	    src/normal.c
+
+Patch 6.2.357 (after 6.2.321)
+Problem:    Memory leak when resizing the Vim window.
+Solution:   Free the LineWraps array.
+Files:	    src/screen.c
+
+Patch 6.2.358 (after 6.2.299)
+Problem:    Memory leak when using ":help" and the language doesn't match.
+Solution:   Free the array with matching tags.
+Files:	    src/ex_cmds.c
+
+Patch 6.2.359 (after 6.2.352)
+Problem:    Compiler warning for long to int type cast.
+Solution:   Add explicit type cast.
+Files:	    src/ex_cmds.c
+
+Patch 6.2.360
+Problem:    "100|" in an empty line results in a ruler "1,0-100". (Pavol
+	    Juhas)
+Solution:   Recompute w_virtcol if the target column was not reached.
+Files:	    src/misc2.c
+
+Patch 6.2.361 (extra)
+Problem:    Win32: Run gvim, ":set go-=m", use Alt-Tab, keep Alt pressed while
+	    pressing Esc, then release Alt: Cursor disappears and typing a key
+	    causes a beep. (Hari Krishna Dara)
+Solution:   Don't ignore the WM_SYSKEYUP event when the menu is disabled.
+Files:	    src/gui_w32.c
+
+Patch 6.2.362 (extra, after 6.2.347)
+Problem:    Win32: The manifest causes Gvim not to work. (Dave Roberts)
+Solution:   Change "x86" to "X86". (Serge Pirotte)
+Files:	    src/gvim.exe.mnf
+
+Patch 6.2.363
+Problem:    In an empty file with 'showmode' off, "i" doesn't change the ruler
+	    from "0-1" to "1".  Typing "x<BS>" does show "1", but then <Esc>
+	    doesn't make it "0-1" again.  Same problem for ruler in
+	    statusline.  (Andrew Pimlott)
+Solution:   Remember the "empty line" flag with Insert mode and'ed to it.
+Files:	    src/screen.c
+
+Patch 6.2.364
+Problem:    HTML version of the documentation doesn't mention the encoding,
+	    which is a problem for mbyte.txt.
+Solution:   Adjust the awk script. (Ilya Sher)
+Files:	    runtime/doc/makehtml.awk
+
+Patch 6.2.365
+Problem:    The configure checks for Perl and Python may add compile and link
+	    arguments that break building Vim.
+Solution:   Do a sanity check: try building with the arguments.
+Files:	    src/auto/configure, src/configure.in
+
+Patch 6.2.366
+Problem:    When the GUI can't start because no valid font is found, there is
+	    no error message. (Ugen)
+Solution:   Add an error message.
+Files:	    src/gui.c
+
+Patch 6.2.367
+Problem:    Building the help tags file while installing may fail if there is
+	    another Vim in $PATH.
+Solution:   Specify the just installed Vim executable. (Gordon Prieur)
+Files:	    src/Makefile
+
+Patch 6.2.368
+Problem:    When 'autochdir' is set, closing a window doesn't change to the
+	    directory of the new current window. (Salman Halim)
+Solution:   Handle 'autochdir' always when a window becomes the current one.
+Files:	    src/window.c
+
+Patch 6.2.369
+Problem:    Various memory leaks: when using globpath(), when searching for
+	    help tags files, when defining a function inside a function, when
+	    giving an error message through an exception, for the final "."
+	    line in ":append", in expression "cond ? a : b" that fails and for
+	    missing ")" in an expression.  Using NULL pointer when adding
+	    first user command and for pointer computations with regexp.
+	    (tests by Dominique Pelle)
+Solution:   Fix the leaks by freeing the allocated memory.  Don't use the
+	    array of user commands when there are no entries.  Use a macro
+	    instead of a function call for saving and restoring regexp states.
+Files:	    src/eval.c, src/ex_cmds.c, src/ex_docmd.c, src/ex_getln.c,
+	    src/misc2.c, src/regexp.c, src/screen.c, src/tag.c
+
+Patch 6.2.370 (extra, after6.2.341)
+Problem:    Win32: When the path to diff.exe contains a space and using the
+	    vimrc generated by the install program, diff mode may not work.
+	    (Alejandro Lopez-Valencia)
+Solution:   Do not use double quotes for arguments that do not have a space.
+Files:	    src/dosinst.c
+
+Patch 6.2.371
+Problem:    When 'virtualedit' is set and there is a Tab before the next "x",
+	    "dtx" does not delete the whole Tab. (Ken Hashishi)
+Solution:   Move the cursor to the last position of the Tab.  Also for
+	    "df<Tab>".
+Files:	    src/normal.c
+
+Patch 6.2.372
+Problem:    When using balloon evaluation, no value is displayed for members
+	    of structures and items of an array.
+Solution:   Include "->", "." and "[*]" in the expression.
+Files:	    src/gui_beval.c, src/normal.c, src/vim.h
+
+Patch 6.2.373
+Problem:    When 'winminheight' is zero and a window is reduced to zero
+	    height, the ruler always says "Top" instead of the cursor
+	    position. (Antoine J. Mechelynck)
+Solution:   Don't recompute w_topline for a zero-height window.
+Files:	    src/window.c
+
+Patch 6.2.374
+Problem:    ":echo "hello" | silent normal n" removes the "hello" message.
+	    (Servatius Brandt)
+Solution:   Don't echo the search string when ":silent" was used.  Also don't
+	    show the mode.  In general: don't clear to the end of the screen.
+Files:	    src/gui.c, src/message.c, src/os_unix.c, src/proto/message.pro,
+	    src/screen.c, src/search.c, src/window.c
+
+Patch 6.2.375
+Problem:    When changing 'guioptions' the hit-enter prompt may be below the
+	    end of the Vim window.
+Solution:   Call screen_alloc() before showing the prompt.
+Files:	    src/message.c
+
+Patch 6.2.376
+Problem:    Win32: Ruby interface cannot be dynamically linked with Ruby 1.6.
+Solution:   Add #ifdefs around use of rb_w32_snprintf().  (Beno�t Cerrina)
+Files:	    src/if_ruby.c
+
+Patch 6.2.377 (after 6.2.372)
+Problem:    Compiler warnings for signed/unsigned compare. (Michael Wookey)
+Solution:   Add type cast.
+Files:	    src/normal.c
+
+Patch 6.2.378 (extra, after 6.2.118)
+Problem:    Mac: cannot build with Project Builder.
+Solution:   Add remove_tail_with_ext() to locate and remove the "build"
+	    directory from the runtime path.  Include os_unix.c when needed.
+	    (Dany St Amant)
+Files:	    src/misc1.c, src/os_macosx.c, src/vim.h
+
+Patch 6.2.379
+Problem:    Using ":mkvimrc" in the ":options" window sets 'bufhidden' to
+	    "delete". (Michael Naumann)
+Solution:   Do not add buffer-specific option values to a global vimrc file.
+Files:	    src/option.c
+
+Patch 6.2.380 (extra)
+Problem:    DOS: "make test" fails when running it again.  Can't "make test"
+	    with Borland C.
+Solution:   Make sure ".out" files are deleted when they get in the way.  Add
+	    a "test" target to the Borland C Makefile.
+Files:	    src/Make_bc5.mak, src/testdir/Make_dos.mak
+
+Patch 6.2.381
+Problem:    Setting 'fileencoding' to a comma separated list (confusing it
+	    with 'fileencodings') does not result in an error message.
+	    Setting 'fileencoding' in an empty file marks it as modified.
+	    There is no "+" in the title after setting 'fileencoding'.
+Solution:   Check for a comma in 'fileencoding'.  Only consider a non-empty
+	    file modified by changing 'fileencoding'.  Update the title after
+	    changing 'fileencoding'.
+Files:	    src/option.c
+
+Patch 6.2.382
+Problem:    Running "make test" puts marks from test files in viminfo.
+Solution:   Specify a different viminfo file to use.
+Files:	    src/testdir/test15.in, src/testdir/test49.in
+
+Patch 6.2.383
+Problem:    ":hi foo term='bla" crashes Vim. (Antony Scriven)
+Solution:   Check that the closing ' is there.
+Files:	    src/syntax.c
+
+Patch 6.2.384
+Problem:    ":menu a.&b" ":unmenu a.b" only works if "&b" isn't translated.
+Solution:   Also compare the names without '&' characters.
+Files:	    src/menu.c
+
+Patch 6.2.385  (extra)
+Problem:    Win32: forward_slash() and trash_input_buf() are undefined when
+	    compiling with small features. (Ajit Thakkar)
+Solution:   Change the #ifdefs for forward_slash().  Don't call
+	    trash_input_buf() if the input buffer isn't used.
+Files:	    src/fileio.c, src/os_win32.c
+
+Patch 6.2.386
+Problem:    Wasting time trying to read marks from the viminfo file for a
+	    buffer without a name.
+Solution:   Skip reading marks when the buffer has no name.
+Files:	    src/fileio.c
+
+Patch 6.2.387
+Problem:    There is no highlighting of translated items in help files.
+Solution:   Search for a "help_ab.vim" syntax file when the help file is
+	    called "*.abx".  Also improve the help highlighting a bit.
+Files:	    runtime/syntax/help.vim
+
+Patch 6.2.388
+Problem:    GTK: When displaying some double-width characters they are drawn
+	    as single-width, because of conversion to UTF-8.
+Solution:   Check the width that GTK uses and add a space if it's one instead
+	    of two.
+Files:	    src/gui_gtk_x11.c
+
+Patch 6.2.389
+Problem:    When working over a slow connection, it's very annoying that the
+	    last line is partly drawn and then cleared for every change.
+Solution:   Don't redraw the bottom line if no rows were inserted or deleted.
+	    Don't draw the line if we know "@" lines will be used.
+Files:	    src/screen.c
+
+Patch 6.2.390
+Problem:    Using "r*" in Visual mode on multi-byte characters only replaces
+	    every other character. (Tyson Roberts)
+Solution:   Correct the cursor position after replacing each character.
+Files:	    src/ops.c
+
+Patch 6.2.391 (extra)
+Problem:    The ":highlight" command is not tested.
+Solution:   Add a test script for ":highlight".
+Files:	    src/testdir/Makefile, src/testdir/Make_amiga.mak,
+	    src/testdir/Make_dos.mak, src/testdir/Make_os2.mak,
+	    src/testdir/Make_vms.mms, src/testdir/test51.in,
+	    src/testdir/test51.ok
+
+Patch 6.2.392 (after 6.2.384)
+Problem:    Unused variable.
+Solution:   Remove "dlen".
+Files:	    src/menu.c
+
+Patch 6.2.393
+Problem:    When using very long lines the viminfo file can become very big.
+Solution:   Add the "s" flag to 'viminfo': skip registers with more than the
+	    specified Kbyte of text.
+Files:	    runtime/doc/options.txt, src/ops.c, src/option.c
+
+Patch 6.2.394  (after 6.2.391)
+Problem:    Test 51 fails on a terminal with 8 colors. (Tony Leneis)
+Solution:   Use "DarkBlue" instead of "Blue" to avoid the "bold" attribute.
+Files:	    src/testdir/test51.in
+
+Patch 6.2.395
+Problem:    When using ":tag" or ":pop" the previous matching tag is used.
+	    But since the current file is different, the ordering of the tags
+	    may change.
+Solution:   Remember what the current buffer was for when re-using cur_match.
+Files:	    src/edit.c, src/ex_cmds.c, src/proto/tag.pro, src/structs.h,
+	    src/tag.c
+
+Patch 6.2.396
+Problem:    When CTRL-T jumps to another file and an autocommand moves the
+	    cursor to the '" mark, don't end up on the right line.  (Michal
+	    Malecki)
+Solution:   Set the line number after loading the file.
+Files:	    src/tag.c
+
+Patch 6.2.397
+Problem:    When using a double-byte 'encoding' mapping <M-x> doesn't work.
+	    (Yasuhiro Matsumoto)
+Solution:   Do not set the 8th bit of the character but use a modifier.
+Files:	    src/gui_gtk_x11.c, src/gui_x11.c, src/misc2.c
+
+Patch 6.2.398 (extra)
+Problem:    Win32 console: no extra key modifiers are supported.
+Solution:   Encode the modifiers into the input stream.  Also fix that special
+	    keys are converted and stop working when 'tenc' is set.  Also fix
+	    that when 'tenc' is initialized the input and output conversion is
+	    not setup properly until 'enc' or 'tenc' is set.
+Files:	    src/getchar.c, src/option.c, src/os_win32.c
+
+Patch 6.2.399
+Problem:    A ":set" command that fails still writes a message when it is
+	    inside a try/catch block.
+Solution:   Include all the text of the message in the error message.
+Files:	    src/charset.c, src/option.c
+
+Patch 6.2.400
+Problem:    Can't compile if_xcmdsrv.c on HP-UX 11.0.
+Solution:   Include header file poll.h. (Malte Neumann)
+Files:	    src/if_xcmdsrv.c
+
+Patch 6.2.401
+Problem:    When opening a buffer that was previously opened, Vim does not
+	    restore the cursor position if the first line starts with white
+	    space.  (Gregory Margo)
+Solution:   Don't skip restoring the cursor position if it is past the blanks
+	    in the first line.
+Files:	    src/buffer.c
+
+Patch 6.2.402
+Problem:    Mac: "make install" doesn't generate help tags. (Benji Fisher)
+Solution:   Generate help tags before copying the runtime files.
+Files:	    src/Makefile
+
+Patch 6.2.403
+Problem:    ":@y" checks stdin if there are more commands to execute.  This
+	    fails if stdin is not connected, e.g., when starting the GUI from
+	    KDE. (Ned Konz)
+Solution:   Only check for a next command if there still is typeahead.
+Files:	    src/ex_docmd.c
+
+Patch 6.2.404
+Problem:    Our own function to determine width of Unicode characters may get
+	    outdated. (Markus Kuhn)
+Solution:   Use wcwidth() when it is available.  Also use iswprint().
+Files:	    src/auto/configure, src/configure.in, src/config.h.in, src/mbyte.c
+
+Patch 6.2.405
+Problem:    Cannot map zero without breaking the count before a command.
+	    (Benji Fisher)
+Solution:   Disable mapping zero when entering a count.
+Files:	    src/getchar.c, src/globals.h, src/normal.c
+
+Patch 6.2.406
+Problem:    ":help \zs", ":help \@=" and similar don't find useful help.
+Solution:   Prepend "/\" to the arguments to find the desired help tag.
+Files:	    src/ex_cmds.c
+
+Patch 6.2.407 (after 6.2.299)
+Problem:    ":help \@<=" doesn't find help.
+Solution:   Avoid that ":help \@<=" searches for the "<=" language.
+Files:	    src/tag.c
+
+Patch 6.2.408
+Problem:    ":compiler" is not consistent: Sets local options and a global
+	    variable. (Douglas Potts)  There is no error message when a
+	    compiler is not supported.
+Solution:   Use ":compiler!" to set a compiler globally, otherwise it's local
+	    to the buffer and "b:current_compiler" is used.  Give an error
+	    when no compiler script could be found.
+	    Note: updated compiler plugins can be found at
+	    ftp://ftp.vim.org/pub/vim/runtime/compiler/
+Files:	    runtime/compiler/msvc.vim, runtime/doc/quickfix.txt, src/eval.c,
+	    src/ex_cmds2.c
+
+Patch 6.2.409
+Problem:    The cursor ends up in the last column instead of after the line
+	    when doing "i//<Esc>o" with 'indentexpr' set to "cindent(v:lnum)".
+	    (Toby Allsopp)
+Solution:   Adjust the cursor as if in Insert mode.
+Files:	    src/misc1.c
+
+Patch 6.2.410 (after 6.2.389)
+Problem:    In diff mode, when there are more filler lines than fit in the
+	    window, they are not drawn.
+Solution:   Check for filler lines when skipping to draw a line that doesn't
+	    fit.
+Files:	    src/screen.c
+
+Patch 6.2.411
+Problem:    A "\n" inside a string is not seen as a line break by the regular
+	    expression matching. (Hari Krishna Dara)
+Solution:   Add the vim_regexec_nl() function for strings where "\n" is to be
+	    matched with a line break.
+Files:	    src/eval.c, src/ex_eval.c, src/proto/regexp.c, src/regexp.c
+
+Patch 6.2.412
+Problem:    Ruby: "ruby << EOF" inside a function doesn't always work.  Also
+	    for ":python", ":tcl" and ":perl".
+Solution:   Check for "<< marker" and skip until "marker" before checking for
+	    "endfunction".
+Files:	    src/eval.c
+
+Patch 6.2.413 (after 6.2.411)
+Problem:    Missing prototype for vim_regexec_nl(). (Marcel Svitalsky)
+Solution:   Now really include the prototype.
+Files:	    src/proto/regexp.pro
+
+Patch 6.2.414
+Problem:    The function used for custom completion of user commands cannot
+	    have <SID> to make it local. (Hari Krishna Dara)
+Solution:   Pass the SID of the script where the user command was defined on
+	    to the completion.  Also clean up #ifdefs.
+Files:	    src/ex_docmd.c, src/eval.c, src/ex_getln.c, src/structs.h
+
+Patch 6.2.415
+Problem:    Vim may crash after a sequence of events that change the window
+	    size.  The window layout assumes a larger window than is actually
+	    available. (Servatius Brandt)
+Solution:   Invoke win_new_shellsize() from screenalloc() instead of from
+	    set_shellsize().
+Files:	    src/screen.c, src/term.c
+
+Patch 6.2.416
+Problem:    Compiler warning for incompatible pointer.
+Solution:   Remove the "&" in the call to poll(). (Xavier de Gaye)
+Files:	    src/os_unix.c
+
+Patch 6.2.417 (after 6.2.393)
+Problem:    Many people forget that the '"' item in 'viminfo' needs to be
+	    preceded with a backslash,
+Solution:   Add '<' as an alias for the '"' item.
+Files:	    runtime/doc/options.txt, src/ops.c, src/option.c
+
+Patch 6.2.418
+Problem:    Using ":nnoremap <F12> :echo "cheese" and ":cabbr cheese xxx":
+	    when pressing <F12> still uses the abbreviation. (Hari Krishna)
+Solution:   Also apply "noremap" to abbreviations.
+Files:	    src/getchar.c
+
+Patch 6.2.419 (extra)
+Problem:    Win32: Cannot open the Vim window inside another application.
+Solution:   Add the "-P" argument to specify the window title of the
+	    application to run inside. (Zibo Zhao)
+Files:	    runtime/doc/starting.txt, src/main.c, src/gui_w32.c,
+	    src/gui_w48.c, src/if_ole.cpp, src/os_mswin.c,
+	    src/proto/gui_w32.pro
+
+Patch 6.2.420
+Problem:    Cannot specify a file to be edited in binary mode without setting
+	    the global value of the 'binary' option.
+Solution:   Support ":edit ++bin file".
+Files:	    runtime/doc/editing.txt, src/buffer.c, src/eval.c, src/ex_cmds.h,
+	    src/ex_docmd.c, src/fileio.c, src/misc2.c
+
+Patch 6.2.421
+Problem:    Cannot set the '[ and '] mark, which may be necessary when an
+	    autocommand simulates reading a file.
+Solution:   Allow using "m[" and "m]".
+Files:	    runtime/doc/motion.txt, src/mark.c
+
+Patch 6.2.422
+Problem:    In CTRL-X completion messages the "/" makes them less readable.
+Solution:   Remove the slashes. (Antony Scriven)
+Files:	    src/edit.c
+
+Patch 6.2.423
+Problem:    ":vertical wincmd ]" does not split vertically.
+Solution:   Add "postponed_split_flags".
+Files:	    src/ex_docmd.c, src/globals.h, src/if_cscope.c, src/tag.c
+
+Patch 6.2.424
+Problem:    A BufEnter autocommand that sets an option stops 'mousefocus' from
+	    working in Insert mode (Normal mode is OK). (Gregory Seidman)
+Solution:   In the Insert mode loop invoke gui_mouse_correct() when needed.
+Files:	    src/edit.c
+
+Patch 6.2.425
+Problem:    Vertical split and command line window: can only drag status line
+	    above the cmdline window on the righthand side, not lefthand side.
+Solution:   Check the status line row instead of the window pointer.
+Files:	    src/ui.c
+
+Patch 6.2.426
+Problem:    A syntax region end match with a matchgroup that includes a line
+	    break only highlights the last line with matchgroup. (Gary
+	    Holloway)
+Solution:   Also use the line number of the position where the region
+	    highlighting ends.
+Files:	    src/syntax.c
+
+Patch 6.2.427 (extra)
+Problem:    When pasting a lot of text in a multi-byte encoding, conversion
+	    from 'termencoding' to 'encoding' may fail for some characters.
+	    (Kuang-che Wu)
+Solution:   When there is an incomplete byte sequence at the end of the read
+	    text keep it for the next time.
+Files:	    src/mbyte.c, src/os_amiga.c, src/os_mswin.c, src/proto/mbyte.pro,
+	    src/proto/os_mswin.pro, src/ui.c
+
+Patch 6.2.428
+Problem:    The X11 clipboard supports the Vim selection for char/line/block
+	    mode, but since the encoding is not included  can't copy/paste
+	    between two Vims with a different 'encoding'.
+Solution:   Add a new selection format that includes the 'encoding'.  Perform
+	    conversion when necessary.
+Files:	    src/gui_gtk_x11.c, src/ui.c, src/vim.h
+
+Patch 6.2.429
+Problem:    Unix: glob() doesn't work for a directory with a single quote in
+	    the name. (Nazri Ramliy)
+Solution:   When using the shell to expand, only put double quotes around
+	    spaces and single quotes, not the whole thing.
+Files:	    src/os_unix.c
+
+Patch 6.2.430
+Problem:    BOM at start of a vim script file is not recognized and causes an
+	    error message.
+Solution:   Detect the BOM and skip over it.  Also fix that after using
+	    ":scriptencoding" the iconv() file descriptor was not closed
+	    (memory leak).
+Files:	    src/ex_cmds2.c
+
+Patch 6.2.431
+Problem:    When using the horizontal scrollbar, the scrolling is limited to
+	    the length of the cursor line.
+Solution:   Make the scroll limit depend on the longest visible line.  The
+	    cursor is moved when necessary.  Including the 'h' flag in
+	    'guioptions' disables this.
+Files:	    runtime/doc/gui.txt, runtime/doc/options.txt, src/gui.c,
+	    src/misc2.c, src/option.h
+
+Patch 6.2.432 (after 6.2.430 and 6.2.431)
+Problem:    Lint warnings.
+Solution:   Add type casts.
+Files:	    src/ex_cmds2.c, src/gui.c
+
+Patch 6.2.433
+Problem:    Translating "VISUAL" and "BLOCK" separately doesn't give a good
+	    result. (Alejandro Lopez Valencia)
+Solution:   Use a string for each combination.
+Files:	    src/screen.c
+
+Patch 6.2.434 (after 6.2.431)
+Problem:    Compiler warning. (Salman Halim)
+Solution:   Add type casts.
+Files:	    src/gui.c
+
+Patch 6.2.435
+Problem:    When there are vertically split windows the minimal Vim window
+	    height is computed wrong.
+Solution:   Use frame_minheight() to correctly compute the minimal height.
+Files:	    src/window.c
+
+Patch 6.2.436
+Problem:    Running the tests changes the user's viminfo file.
+Solution:   In test 49 tell the extra Vim to use the test viminfo file.
+Files:	    src/testdir/test49.vim
+
+Patch 6.2.437
+Problem:    ":mksession" always puts "set nocompatible" in the session file.
+	    This changes option settings. (Ron Aaron)
+Solution:   Add an "if" to only change 'compatible' when needed.
+Files:	    src/ex_docmd.c
+
+Patch 6.2.438
+Problem:    When the 'v' flag is present in 'cpoptions', backspacing and then
+	    typing text again: one character too much is overtyped before
+	    inserting is done again.
+Solution:   Set "dollar_vcol" to the right column.
+Files:	    src/edit.c
+
+Patch 6.2.439
+Problem:    GTK 2: Changing 'lines' may cause a mismatch between the window
+	    layout and the size of the window.
+Solution:   Disable the hack with force_shell_resize_idle().
+Files:	    src/gui_gtk_x11.c
+
+Patch 6.2.440
+Problem:    When 'lazyredraw' is set the window title is still updated.
+	    The size of the Visual area and the ruler are displayed too often.
+Solution:   Postpone redrawing the window title.  Only show the Visual area
+	    size when waiting for a character.  Don't draw the ruler
+	    unnecessary.
+Files:	    src/buffer.c, src/normal.c, src/screen.c
+
+Patch 6.2.441
+Problem:    ":unabbreviate foo " doesn't work, because of the trailing space,
+	    while an abbreviation with a trailing space is not possible. (Paul
+	    Jolly)
+Solution:   Accept a match with the lhs of an abbreviation without the
+	    trailing space.
+Files:	    src/getchar.c
+
+Patch 6.2.442
+Problem:    Cannot manipulate the command line from a function.
+Solution:   Add getcmdline(), getcmdpos() and setcmdpos() functions and the
+	    CTRL-\ e command.
+Files:	    runtime/doc/cmdline.txt, runtime/doc/eval.txt, src/eval.c
+	    src/ex_getln.c, src/ops.c, src/proto/ex_getln.pro,
+	    src/proto/ops.pro
+
+Patch 6.2.443
+Problem:    With ":silent! echoerr something" you don't get the position of
+	    the error.  emsg() only writes the message itself and returns.
+Solution:   Also redirect the position of the error.
+Files:	    src/message.c
+
+Patch 6.2.444
+Problem:    When adding the 'c' flag to a ":substitute" command it may replace
+	    more times than without the 'c' flag.  Happens for a  match that
+	    starts with "\ze" (Marcel Svitalsk) and when using "\@<=" (Klaus
+	    Bosau).
+Solution:   Correct "prev_matchcol" when replacing the line.  Don't replace
+	    the line when the pattern uses look-behind matching.
+Files:	    src/ex_cmds.c, src/proto/regexp.pro, src/regexp.c
+
+Patch 6.2.445
+Problem:    Copying vimtutor to /tmp/something is not secure, a symlink may
+	    cause trouble.
+Solution:   Create a directory and create the file in it.  Use "umask" to
+	    create the directory with mode 700.  (Stefan Nordhausen)
+Files:	    src/vimtutor
+
+Patch 6.2.446 (after 6.2.404)
+Problem:    Using library functions wcwidth() and iswprint() results in
+	    display problems for Hebrew characters. (Ron Aaron)
+Solution:   Disable the code to use the library functions, use our own.
+Files:	    src/mbyte.c
+
+Patch 6.2.447 (after 6.2.440)
+Problem:    Now that the title is only updated when redrawing, it is no longer
+	    possible to show it while executing a function. (Madoka Machitani)
+Solution:   Make ":redraw" also update the title.
+Files:	    src/ex_docmd.c
+
+Patch 6.2.448 (after 6.2.427)
+Problem:    Mac: conversion done when 'termencoding' differs from 'encoding'
+	    fails when pasting a longer text.
+Solution:   Check for an incomplete sequence at the end of the chunk to be
+	    converted. (Eckehard Berns)
+Files:	    src/mbyte.c
+
+Patch 6.2.449 (after 6.2.431)
+Problem:    Get error messages when switching files.
+Solution:   Check for a valid line number when calculating the width of the
+	    horizontal scrollbar. (Helmut Stiegler)
+Files:	    src/gui.c
+
+Patch 6.2.450
+Problem:    "  #include" and "  #define" are not recognized with the default
+	    option values for 'include' and 'defined'. (RG Kiran)
+Solution:   Adjust the default values to allow white space before the #.
+Files:	    runtime/doc/options.txt, src/option.c
+
+Patch 6.2.451
+Problem:    GTK: when using XIM there are various problems, including setting
+	    'modified' and breaking undo at the wrong moment.
+Solution:   Add "xim_changed_while_preediting", "preedit_end_col" and
+	    im_is_preediting(). (Yasuhiro Matsumoto)
+Files:	    src/ex_getln.c, src/globals.h, src/gui_gtk.c, src/gui_gtk_x11.c,
+	    src/mbyte.c, src/misc1.c, src/proto/mbyte.pro, src/screen.c,
+	    src/undo.c
+
+Patch 6.2.452
+Problem:    In diff mode, when DiffAdd and DiffText highlight settings are
+	    equal, an added line is highlighted with DiffChange. (Tom Schumm)
+Solution:   Remember the diff highlight type instead of the attributes.
+Files:	    src/screen.c
+
+Patch 6.2.453
+Problem:    ":s/foo\|\nbar/x/g" does not replace two times in "foo\nbar".
+	    (Pavel Papushev)
+Solution:   When the pattern can match a line break also try matching at the
+	    NUL at the end of a line.
+Files:	    src/ex_cmds.c, src/regexp.c
+
+Patch 6.2.454
+Problem:    ":let b:changedtick" doesn't work. (Alan Schmitt)  ":let
+	    b:changedtick = 99" does not give an error message.
+Solution:   Add code to recognize ":let b:changedtick".
+Files:	    src/eval.c
+
+Patch 6.2.455 (after 6.2.297)
+Problem:    In Python commands the current locale changes how certain Python
+	    functions work. (Eugene M. Minkovskii)
+Solution:   Set the LC_NUMERIC locale to "C" while executing a Python command.
+Files:	    src/if_python.c
+
+Patch 6.2.456 (extra)
+Problem:    Win32: Editing a file by its Unicode name (dropping it on Vim or
+	    using the file selection dialog) doesn't work. (Yakov Lerner, Alex
+	    Jakushev)
+Solution:   Use wide character functions when file names are involved and
+	    convert from/to 'encoding' where needed.
+Files:	    src/gui_w48.c, src/macros.h, src/memfile.c, src/memline.c,
+	    src/os_mswin.c, src/os_win32.c
+
+Patch 6.2.457 (after 6.2.244)
+Problem:    When 'encoding' is "utf-8" and writing text with chars above 0x80
+	    in latin1, conversion is wrong every 8200 bytes. (Oyvind Holm)
+Solution:   Correct the utf_ptr2len_check_len() function and fix the problem
+	    of displaying 0xf7 in utfc_ptr2len_check_len().
+Files:	    src/mbyte.c
+
+Patch 6.2.458
+Problem:    When 'virtualedit' is set "$" doesn't move to the end of an
+	    unprintable character, causing "y$" not to include that character.
+	    (Fred Ma)
+Solution:   Set "coladd" to move the cursor to the end of the character.
+Files:	    src/misc2.c
+
+Patch 6.2.459 (after 6.2.454)
+Problem:    Variable "b" cannot be written. (Salman Halim)
+Solution:   Compare strings properly.
+Files:	    src/eval.c
+
+Patch 6.2.460 (extra, after 6.2.456)
+Problem:    Compiler warnings for missing prototypes.
+Solution:   Include the missing prototypes.
+Files:	    src/proto/os_win32.pro
+
+Patch 6.2.461
+Problem:    After using a search command "x" starts putting single characters
+	    in the numbered registers.
+Solution:   Reset "use_reg_one" at the right moment.
+Files:	    src/normal.c
+
+Patch 6.2.462
+Problem:    Finding a matching parenthesis does not correctly handle a
+	    backslash in a trailing byte.
+Solution:   Handle multi-byte characters correctly. (Taro Muraoka)
+Files:	    src/search.c
+
+Patch 6.2.463 (extra)
+Problem:    Win32: An NTFS file system may contain files with extra info
+	    streams.  The current method to copy them creates one and then
+	    deletes it again.  (Peter Toennies)  Also, only three streams with
+	    hard coded names are copied.
+Solution:   Use BackupRead() to check which info streams the original file
+	    contains and only copy these streams.
+Files:	    src/os_win32.c
+
+Patch 6.2.464 (extra, after 6.2.427)
+Problem:    Amiga: Compilation error with gcc. (Ali Akcaagac)
+Solution:   Move the #ifdef outside of Read().
+Files:	    src/os_amiga.c
+
+Patch 6.2.465
+Problem:    When resizing the GUI window the window manager sometimes moves it
+	    left of or above the screen. (Michael McCarty)
+Solution:   Check the window position after resizing it and move it onto the
+	    screen when it isn't.
+Files:	    src/gui.c
+
+Patch 6.2.466 (extra, after 6.2.456)
+Problem:    Win32: Compiling with Borland C fails, and an un/signed warning.
+Solution:   Redefine wcsicmp() to wcscmpi() and add type casts. (Yasuhiro
+	    Matsumoto)
+Files:	    src/os_win32.c
+
+Patch 6.2.467 (extra, after 6.2.463)
+Problem:    Win32: can't compile without multi-byte feature. (Ajit Thakkar)
+Solution:   Add #ifdefs around the info stream code.
+Files:	    src/os_win32.c
+
+Patch 6.2.468
+Problem:    Compiler warnings for shadowed variables. (Matthias Mohr)
+Solution:   Delete superfluous variables and rename others.
+Files:	    src/eval.c, src/ex_docmd.c, src/ex_eval.c, src/if_cscope.c,
+	    src/fold.c, src/option.c, src/os_unix.c, src/quickfix.c,
+	    src/regexp.c
+
+Patch 6.2.469 (extra, after 6.2.456)
+Problem:    Win32: Can't create swap file when 'encoding' differs from the
+	    active code page. (Kriton Kyrimis)
+Solution:   In enc_to_ucs2() terminate the converted string with a NUL
+Files:	    src/os_mswin.c
+
+Patch 6.2.470
+Problem:    The name returned by tempname() may be equal to the file used for
+	    shell output when ignoring case.
+Solution:   Skip 'O' and 'I' in tempname().
+Files:	    src/eval.c
+
+Patch 6.2.471
+Problem:    "-L/usr/lib" is used in the link command, even though it's
+	    supposed to be filtered out. "-lw" and "-ldl" are not
+	    automatically added when needed for "-lXmu". (Antonio Colombo)
+Solution:   Check for a space after the argument instead of before.  Also
+	    remove "-R/usr/lib" if it's there.  Check for "-lw" and "-ldl"
+	    before trying "-lXmu".
+Files:	    src/auto/configure, src/configure.in, src/link.sh
+
+Patch 6.2.472
+Problem:    When using a FileChangedShell autocommand that changes the current
+	    buffer, a buffer exists that can't be wiped out.
+	    Also, Vim sometimes crashes when executing an external command
+	    that changes the buffer and a FileChangedShell autocommand is
+	    used.  (Hari Krishna Dara)
+	    Users are confused by the warning for a file being changed outside
+	    of Vim.
+Solution:   Avoid that the window counter for a buffer is incremented twice.
+	    Avoid that buf_check_timestamp() is used recursively.
+	    Add a hint to look in the help for more info.
+Files:	    src/ex_cmds.c, src/fileio.c
+
+Patch 6.2.473
+Problem:    Using CTRL-] in a help buffer without a name causes a crash.
+Solution:   Check for name to be present before using it. (Taro Muraoka)
+Files:	    src/tag.c
+
+Patch 6.2.474 (extra, after 6.2.456)
+Problem:    When Vim is starting up conversion is done unnecessarily.  Failure
+	    to find the runtime files on Windows 98. (Randall W. Morris)
+Solution:   Init enc_codepage negative, only use it when not negative.
+	    Don't use GetFileAttributesW() on Windows 98 or earlier.
+Files:	    src/globals.h, src/gui_w32.c, src/gui_w48.c, src/os_mswin.c,
+	    src/os_win32.c
+
+Patch 6.2.475
+Problem:    Commands after "perl <<EOF" are parsed as Vim commands when they
+	    are not executed.
+Solution:   Properly skip over the perl commands.
+Files:	    src/ex_docmd.c, src/ex_getln.c, src/if_perl.xs, src/if_python.c,
+	    src/if_ruby.c, src/if_tcl.c, src/misc2.c
+
+Patch 6.2.476
+Problem:    When reloading a hidden buffer changed outside of Vim and the
+	    current buffer is read-only, the reloaded buffer becomes
+	    read-only.  (Hari Krishna Dara)
+Solution:   Save the 'readonly' flag of the reloaded buffer instead of the
+	    current buffer.
+Files:	    src/fileio.c
+
+Patch 6.2.477
+Problem:    Using remote_send(v:servername, "\<C-V>") causes Vim to hang.
+	    (Yakov Lerner)
+Solution:   When the resulting string is empty don't set received_from_client.
+Files:	    src/main.c
+
+Patch 6.2.478
+Problem:    Win32: "--remote file" fails changing directory if the current
+	    directory name starts with a single quote.  (Iestyn Walters)
+Solution:   Add a backslash where it will be removed later.
+Files:	    src/main.c, src/misc2.c, src/proto/misc2.pro
+
+Patch 6.2.479
+Problem:    The error message for errors during recovery goes unnoticed.
+Solution:   Avoid that the hit-enter prompt overwrites the message.  Add a few
+	    lines to make the error stand out.
+Files:	    src/main.c, src/message.c, src/memline.c
+
+Patch 6.2.480
+Problem:    NetBeans: Using negative index in array.  backslash at end of
+	    message may cause Vim to crash. (Xavier de Gaye)
+Solution:   Initialize buf_list_used to zero. Check for trailing backslash.
+Files:	    src/netbeans.c
+
+Patch 6.2.481
+Problem:    When writing a file it is not possible to specify that hard and/or
+	    symlinks are to be broken instead of preserved.
+Solution:   Add the "breaksymlink" and "breakhardlink" values to 'backupcopy'.
+	    (Simon Ekstrand)
+Files:	    runtime/doc/options.txt, src/fileio.c, src/option.c, src/option.h
+
+Patch 6.2.482
+Problem:    Repeating insert of CTRL-K 1 S doesn't work.  The superscript 1 is
+	    considered to be a digit. (Juergen Kraemer)
+Solution:   In vim_isdigit() only accept '0' to '9'.  Use VIM_ISDIGIT() for
+	    speed where possible.  Also add vim_isxdigit().
+Files:	    src/buffer.c, src/charset.c, src/diff.c, src/digraph.c,
+	    src/edit.c, src/eval.c,, src/ex_cmds.c, src/ex_cmds2.c,
+	    src/ex_docmd.c, src/ex_eval.c, src/ex_getln.c,
+	    src/if_xcmdsrv.c, src/farsi.c, src/fileio.c, src/fold.c,
+	    src/getchar.c, src/gui.c, src/if_cscope.c, src/macros.h,
+	    src/main.c, src/mark.c, src/mbyte.c, src/menu.c, src/misc1.c,
+	    src/misc2.c, src/normal.c, src/ops.c, src/option.c,
+	    src/proto/charset.pro, src/regexp.c, src/screen.c, src/search.c,
+	    src/syntax.c, src/tag.c, src/term.c, src/termlib.c
+
+Patch 6.2.483 (extra, after 6.2.482)
+Problem:    See 6.2.482.
+Solution:   Extra part of patch 6.2.482.
+Files:	    src/gui_photon.c, src/gui_w48.c, src/os_msdos.c, src/os_mswin.c
+
+Patch 6.2.484
+Problem:    MS-Windows: With the included diff.exe, differences after a CTRL-Z
+	    are not recognized.  (Peter Keresztes)
+Solution:   Write the files with unix fileformat and invoke diff with --binary
+	    if possible.
+Files:	    src/diff.c
+
+Patch 6.2.485
+Problem:    A BufWriteCmd autocommand cannot know if "!" was used or not.
+	    (Hari Krishna Dara)
+Solution:   Add the v:cmdbang variable.
+Files:	    runtime/doc/eval.txt, src/eval.c, src/proto/eval.pro,
+	    src/fileio.c, src/vim.h
+
+Patch 6.2.486 (6.2.482)
+Problem:    Diff for eval.c is missing.
+Solution:   Addition to patch 6.2.482.
+Files:	    src/eval.c
+
+Patch 6.2.487 (extra, after 6.2.456)
+Problem:    Compiler warnings for wrong prototype. (Alejandro Lopez Valencia)
+Solution:   Delete the prototype for Handle_WM_Notify().
+Files:	    src/proto/gui_w32.pro
+
+Patch 6.2.488
+Problem:    Missing ")" in *.ch filetype detection.
+Solution:   Add the ")".  (Ciaran McCreesh)
+Files:	    runtime/filetype.vim
+
+Patch 6.2.489
+Problem:    When accidentally opening a session in Vim which has already been
+	    opened in another Vim there is a long row of ATTENTION prompts.
+	    Need to quit each of them to get out. (Robert Webb)
+Solution:   Add the "Abort" alternative to the dialog.
+Files:	    src/memline.c
+
+Patch 6.2.490
+Problem:    With 'paragraph' it is not possible to use a single dot as a
+	    paragraph boundary.  (Dorai Sitaram)
+Solution:   Allow using "  " (two spaces) in 'paragraph' to match ".$" or
+	    ". $"
+Files:	    src/search.c
+
+Patch 6.2.491
+Problem:    Decrementing a position doesn't take care of multi-byte chars.
+Solution:   Adjust the column for multi-byte characters.  Remove mb_dec().
+	    (Yasuhiro Matsumoto)
+Files:	    src/mbyte.c, src/misc2.c, src/proto/mbyte.pro
+
+Patch 6.2.492
+Problem:    When using ":redraw" while there is a message, the next ":echo"
+	    still causes text to scroll. (Yasuhiro Matsumoto)
+Solution:   Reset msg_didout and msg_col, so that after ":redraw" the next
+	    message overwrites an existing one.
+Files:	    src/ex_docmd.c
+
+Patch 6.2.493
+Problem:    "@x" doesn't work when 'insertmode' is set. (Benji Fisher)
+Solution:   Put "restart_edit" in the typeahead buffer, so that it's used
+	    after executing the register contents.
+Files:	    src/ops.c
+
+Patch 6.2.494
+Problem:    Using diff mode with two windows, when moving horizontally in
+	    inserted lines, a fold in the other window may open.
+Solution:   Compute the line number in the other window correctly.
+Files:	    src/diff.c
+
+Patch 6.2.495 (extra, after 6.2.456)
+Problem:    Win32: The file dialog doesn't work on Windows 95.
+Solution:   Put the wide code of gui_mch_browse() in gui_mch_browseW() and use
+	    it only on Windows NT/2000/XP.
+Files:	    src/gui_w32.c, src/gui_w48.c
+
+Patch 6.2.496
+Problem:    FreeBSD 4.x: When compiled with the pthread library (Python) a
+	    complicated pattern may cause Vim to crash.  Catching the signal
+	    doesn't work.
+Solution:   When compiled with threads, instead of using the normal stacksize
+	    limit, use the size of the initial stack.
+Files:	    src/auto/configure, src/config.h.in, src/configure.in,
+	    src/os_unix.c
+
+Patch 6.2.497 (extra)
+Problem:    Russian messages are only available in one encoding.
+Solution:   Convert the messages to MS-Windows codepages. (Vassily Ragosin)
+Files:	    src/po/Makefile
+
+Patch 6.2.498
+Problem:    Non-latin1 help files are not properly supported.
+Solution:   Support utf-8 help files and convert them to 'encoding' when
+	    needed.
+Files:	    src/fileio.c
+
+Patch 6.2.499
+Problem:    When writing a file and halting the system, the file might be lost
+	    when using a journalling file system.
+Solution:   Use fsync() to flush the file data to disk after writing a file.
+	    (Radim Kolar)
+Files:	    src/fileio.c
+
+Patch 6.2.500 (extra)
+Problem:    The DOS/MS-Windows the installer doesn't use the --binary flag for
+	    diff.
+Solution:   Add --binary to the diff argument in MyDiff(). (Alejandro Lopez-
+	    Valencia)
+Files:	    src/dosinst.c
+
+Patch 6.2.501
+Problem:    Vim does not compile with MorphOS.
+Solution:   Add a Makefile and a few changes to make Vim work with MorphOS.
+	    (Ali Akcaagac)
+Files:	    runtime/doc/os_amiga.txt, src/INSTALLami.txt,
+	    src/Make_morphos.mak, src/memfile.c, src/term.c
+
+Patch 6.2.502
+Problem:    Building fails for generating message files.
+Solution:   Add dummy message files.
+Files:	    src/po/ca.po, src/po/ru.po, src/po/sv.po
+
+Patch 6.2.503
+Problem:    Mac: Can't compile MacRoman conversions without the GUI.
+Solution:   Also link with the Carbon framework for the terminal version, for
+	    the MacRoman conversion functions. (Eckehard Berns)
+	    Remove -ltermcap from the GUI link command, it is not needed.
+Files:	    src/auto/configure, src/Makefile, src/configure.in
+
+Patch 6.2.504
+Problem:    Various problems with 'cindent', among which that a
+	    list of variable declarations is not indented properly.
+Solution:   Fix the wrong indenting.  Improve indenting of C++ methods.
+	    Add the 'i', 'b' and 'W' options to 'cinoptions'. (mostly by
+	    Helmut Stiegler)
+	    Improve indenting of preprocessor-continuation lines.
+Files:	    runtime/doc/indent.txt, src/misc1.c, src/testdir/test3.in,
+	    src/testdir/test3.ok
+
+Patch 6.2.505
+Problem:    Help for -P argument is missing. (Ronald Hoellwarth)
+Solution:   Add the patch that was missing in 6.2.419.
+Files:	    runtime/doc/starting.txt
+
+Patch 6.2.506 (extra)
+Problem:    Win32: When 'encoding' is a codepage then reading a utf-8 file
+	    only works when iconv is available.  Writing a file in another
+	    codepage uses the wrong kind of conversion.
+Solution:   Use internal conversion functions.  Enable reading and writing
+	    files with 'fileencoding' different from 'encoding' for all valid
+	    codepages and utf-8 without the need for iconv.
+Files:	    src/fileio.c, src/testdir/Make_dos.mak, src/testdir/test52.in,
+	    src/testdir/test52.ok
+
+Patch 6.2.507
+Problem:    The ownership of the file with the password for the NetBeans
+	    connection is not checked.  "-nb={file}" doesn't work for GTK.
+Solution:   Only accept the file when owned by the user and not accessible by
+	    others.  Detect "-nb=" for GTK.
+Files:	    src/netbeans.c, src/gui_gtk_x11.c
+
+Patch 6.2.508
+Problem:    Win32: "v:lang" does not show the current language for messages if
+	    it differs from the other locale settings.
+Solution:   Use the value of the $LC_MESSAGES environment variable.
+Files:	    src/ex_cmds2.c
+
+Patch 6.2.509 (after 6.2.508)
+Problem:    Crash when $LANG is not set.
+Solution:   Add check for NULL pointer. (Ron Aaron)
+Files:	    src/ex_cmds2.c
+
+Patch 6.2.510 (after 6.2.507)
+Problem:    Warning for pointer conversion.
+Solution:   Add a type cast.
+Files:	    src/gui_gtk_x11.c
+
+Patch 6.2.511
+Problem:    Tags in Russian help files are in utf-8 encoding, which may be
+	    different from 'encoding'.
+Solution:   Use the "TAG_FILE_ENCODING" field in the tags file to specify the
+	    encoding of the tags.  Convert help tags from 'encoding' to the
+	    tag file encoding when searching for matches, do the reverse when
+	    listing help tags.
+Files:	    runtime/doc/tagsrch.txt, src/ex_cmds.c, src/tag.c
+
+Patch 6.2.512
+Problem:    Translating "\"\n" is useless. (Gerfried Fuchs)
+Solution:   Remove the _() around it.
+Files:	    src/main.c, src/memline.c
+
+Patch 6.2.513 (after 6.2.507)
+Problem:    NetBeans: the check for owning the connection info file can be
+	    simplified. (Nikolay Molchanov)
+Solution:   Only check if the access mode is right.
+Files:	    src/netbeans.c
+
+Patch 6.2.514
+Problem:    When a highlight/syntax group name contains invalid characters
+	    there is no warning.
+Solution:   Add an error for unprintable characters and a warning for other
+	    invalid characters.
+Files:	    src/syntax.c
+
+Patch 6.2.515
+Problem:    When using the options window 'swapfile' is reset.
+Solution:   Use ":setlocal" instead of ":set".
+Files:	    runtime/optwin.vim
+
+Patch 6.2.516
+Problem:    The sign column cannot be seen, looks like there are two spaces
+	    before the text. (Rob Retter)
+Solution:   Add the SignColumn highlight group.
+Files:	    runtime/doc/options.txt, runtime/doc/sign.txt, src/option.c,
+	    src/screen.c, src/syntax.c, src/vim.h
+
+Patch 6.2.517
+Problem:    Using "r*" in Visual mode on multi-byte characters replaces
+	    too many characters.  In Visual Block mode replacing with a
+	    multi-byte character doesn't work.
+Solution:   Adjust the operator end for the difference in byte length of the
+	    original and the replaced character.  Insert all bytes of a
+	    multi-byte character, take care of double-wide characters.
+Files:	    src/ops.c
+
+Patch 6.2.518
+Problem:    Last line of a window is not updated after using "J" and then "D".
+	    (Adri Verhoef)
+Solution:   When no line is found below a change that doesn't need updating,
+	    update all lines below the change.
+Files:	    src/screen.c
+
+Patch 6.2.519
+Problem:    Mac: cannot read/write files in MacRoman format.
+Solution:   Do internal conversion from/to MacRoman to/from utf-8 and latin1.
+	    (Eckehard Berns)
+Files:	    src/fileio.c
+
+Patch 6.2.520 (extra)
+Problem:    The NSIS installer is outdated.
+Solution:   Make it work with NSIS 2.0.  Also include console executables for
+	    Win 95/98/ME and Win NT/2000/XP.  Use LZWA compression.  Use
+	    "/oname" to avoid having to rename files before running NSIS.
+Files:	    Makefile, nsis/gvim.nsi
+
+Patch 6.2.521
+Problem:    When using silent Ex mode the "changing a readonly file" warning
+	    is omitted but the one second wait isn't. (Yakov Lerner)
+Solution:   Skip the delay when "silent_mode" is set.
+Files:	    src/misc1.c
+
+Patch 6.2.522
+Problem:    GUI: when changing 'cmdheight' in the gvimrc file the window
+	    layout is messed up. (Keith Dart)
+Solution:   Skip updating the window layout when changing 'cmdheight' while
+	    still starting up.
+Files:	    src/option.c
+
+Patch 6.2.523
+Problem:    When loading a session and aborting when a swap file already
+	    exists, the user is left with useless windows. (Robert Webb)
+Solution:   Load one file before creating the windows.
+Files:	    src/ex_docmd.c
+
+Patch 6.2.524 (extra, after 6.2.520)
+Problem:    Win32: (un)installing gvimext.dll may fail if it was used.
+	    The desktop and start menu links are created for the current user
+	    instead of all users.
+	    Using the home directory as working directory for the links is a
+	    bad idea for multi-user systems.
+	    Cannot use Vim from the "Open With..." menu.
+Solution:   Force a reboot if necessary. (Alejandro Lopez-Valencia)  Also use
+	    macros for the directory of the source and runtime files.  Use
+	    "CSIDL_COMMON_*" instead of "CSIDL_*" when possible.
+	    Do not specify a working directory in the links.
+	    Add Vim to the "Open With..." menu. (Giuseppe Bilotta)
+Files:	    nsis/gvim.nsi, src/dosinst.c, src/dosinst.h, src/uninstal.c
+
+Patch 6.2.525
+Problem:    When the history contains a very long line ":history" causes a
+	    crash. (Volker Kiefel)
+Solution:   Shorten the history entry to fit it in one line.
+Files:	    src/ex_getln.c
+
+Patch 6.2.526
+Problem:    When s:lang is "ja" the Japanese menus are not used.
+Solution:   Add 'encoding' to the language when there is no charset.
+Files:	    runtime/menu.vim
+
+Patch 6.2.527
+Problem:    The 2html script uses ":wincmd p", which breaks when using some
+	    autocommands.
+Solution:   Remember the window numbers and jump to them with ":wincmd w".
+	    Also add XHTML support. (Panagiotis Issaris)
+Files:	    runtime/syntax/2html.vim
+
+Patch 6.2.528
+Problem:    NetBeans: Changes of the "~" command are not reported.
+Solution:   Call netbeans_inserted() after performing "~". (Gordon Prieur)
+	    Also change NetBeans debugging to append to the log file.
+	    Also fix that "~" in Visual block mode changes too much if there
+	    are multi-byte characters.
+Files:	    src/nbdebug.c, src/normal.c, src/ops.c
+
+Patch 6.2.529 (extra)
+Problem:    VisVim only works for Admin.  Doing it for one user doesn't work.
+	    (Alexandre Gouraud)
+Solution:   When registering the module fails, simply continue.
+Files:	    src/VisVim/VisVim.cpp
+
+Patch 6.2.530
+Problem:    Warning for missing prototype on the Amiga.
+Solution:   Include time.h
+Files:	    src/version.c
+
+Patch 6.2.531
+Problem:    In silent ex mode no messages are given, which makes debugging
+	    very difficult.
+Solution:   Do output messages when 'verbose' is set.
+Files:	    src/message.c, src/ui.c
+
+Patch 6.2.532 (extra)
+Problem:    Compiling for Win32s with VC 4.1 doesn't work.
+Solution:   Don't use CP_UTF8 if it's not defined.  Don't use CSIDL_COMMON*
+	    when not defined.
+Files:	    src/dosinst.h, src/fileio.c
+
+Win32 console: After patch 6.2.398 Ex mode did not work. (Yasuhiro Matsumoto)
+
+Patch 6.3a.001
+Problem:    Win32: if testing for the "--binary" option fails, diff isn't used
+	    at all.
+Solution:   Handle the "ok" flag properly. (Yasuhiro Matsumoto)
+Files:	    src/diff.c
+
+Patch 6.3a.002
+Problem:    NetBeans: An insert command from NetBeans beyond the end of a
+	    buffer crashes Vim. (Xavier de Gaye)
+Solution:   Use a local pos_T structure for the position.
+Files:	    src/netbeans.c
+
+Patch 6.3a.003
+Problem:    E315 error with auto-formatting comments. (Henry Van Roessel)
+Solution:   Pass the line number to same_leader().
+Files:	    src/ops.c
+
+Patch 6.3a.004
+Problem:    Test32 fails on Windows XP for the DJGPP version.  Renaming
+	    test11.out fails.
+Solution:   Don't try renaming, create new files to use for the test.
+Files:	    src/testdir/test32.in, src/testdir/test32.ok
+
+Patch 6.3a.005
+Problem:    ":checkpath!" does not use 'includeexpr'.
+Solution:   Use a file name that was found directly.  When a file was not
+	    found and the located name is empty, use the rest of the line.
+Files:	    src/search.c
+
+Patch 6.3a.006
+Problem:    "yip" moves the cursor to the first yanked line, but not to the
+	    first column.  Looks like not all text was yanked. (Jens Paulus)
+Solution:   Move the cursor to the first column.
+Files:	    src/search.c
+
+Patch 6.3a.007
+Problem:    'cindent' recognizes "enum" but not "typedef enum".
+Solution:   Skip over "typedef" before checking for "enum". (Helmut Stiegler)
+	    Also avoid that searching for this item goes too far back.
+Files:	    src/misc1.c, src/testdir/test3.in, src/testdir/test3.ok
+
+Patch 6.3a.008 (extra)
+Problem:    Windows 98: Some of the wide functions are not implemented,
+	    resulting in file I/O to fail.  This depends on what Unicode
+	    support is installed.
+Solution:   Handle the failure and fall back to non-wide functions.
+Files:	    src/os_win32.c
+
+Patch 6.3a.009
+Problem:    Win32: Completion of filenames does not work properly when
+	    'encoding' differs from the active code page.
+Solution:   Use wide functions for expanding wildcards when appropriate.
+Files:	    src/misc1.c
+
+Patch 6.3a.010 (extra)
+Problem:    Win32: Characters in the window title that do not appear in the
+	    active codepage are replaced by a question mark.
+Solution:   Use DefWindowProcW() instead of DefWindowProc() when possible.
+Files:	    src/glbl_ime.cpp, src/globals.h, src/proto/gui_w16.pro,
+	    src/proto/gui_w32.pro, src/gui_w16.c, src/gui_w32.c, src/gui_w48.c
+
+Patch 6.3a.011
+Problem:    Using the explorer plugin changes a local directory to the global
+	    directory.
+Solution:   Don't use ":chdir" to restore the current directory.  Make
+	    "expand('%:p')" remove "/../" and "/./" items from the path.
+Files:	    runtime/plugin/explorer.vim, src/eval.c, src/os_unix.c
+
+Patch 6.3a.012 (extra)
+Problem:    On Windows 98 the installer doesn't work, don't even get the "I
+	    agree" button.  The check for the path ending in "vim" makes the
+	    browse dialog hard to use.  The default path when no previous Vim
+	    is installed is "c:\vim" instead of "c:\Program Files\Vim".
+Solution:   Remove the background gradient command.  Change the
+	    .onVerifyInstDir function to a leave function for the directory
+	    page.  Don't let the install program default to c:\vim when no
+	    path could be found.
+Files:	    nsis/gvim.nsi, src/dosinst.c
+
+Patch 6.3a.013 (extra)
+Problem:    Win32: Characters in the menu that are not in the active codepage
+	    are garbled.
+Solution:   Convert menu strings from 'encoding' to the active codepage.
+Files:	    src/gui_w32.c, src/gui_w48.c
+
+Patch 6.3a.014
+Problem:    Using multi-byte text and highlighting in a statusline causes gaps
+	    to appear. (Helmut Stiegler)
+Solution:   Advance the column by text width instead of number of bytes.  Add
+	    the vim_strnsize() function.
+Files:	    src/charset.c, src/proto/charset.pro, src/screen.c
+
+Patch 6.3a.015
+Problem:    Using the "select all" menu item when 'insertmode' is set and
+	    clicking the mouse button doesn't return to Insert mode.  The
+	    Buffers/Delete menu doesn't offer a choice to abandon a changed
+	    buffer.  (Jens Paulus)
+Solution:   Don't use CTRL-\ CTRL-N.  Add ":confirm" for the Buffers menu
+	    items.
+Files:	    runtime/menu.vim
+
+Patch 6.3a.016
+Problem:    After cancelling the ":confirm" dialog the error message and
+	    hit-enter prompt may not be displayed properly.
+Solution:   Flush output after showing the dialog.
+Files:	    src/message.c
+
+Patch 6.3a.017
+Problem:    servername() doesn't work when Vim was started with the "-X"
+	    argument or when the "exclude" in 'clipboard' matches the terminal
+	    name.  (Robert Nowotniak)
+Solution:   Force connecting to the X server when using client-server
+	    commands.
+Files:	    src/eval.c, src/globals.h, src/os_unix.c
+
+Patch 6.3a.018 (after 6.3a.017)
+Problem:    Compiler warning for return value of make_connection().
+Solution:   Use void return type.
+Files:	    src/eval.c
+
+Patch 6.3a.019 (extra)
+Problem:    Win32: typing non-latin1 characters doesn't work.
+Solution:   Invoke _OnChar() directly to avoid that the argument is truncated
+	    to a byte.  Convert the UTF-16 character to bytes according to
+	    'encoding' and ignore 'termencoding'.  Same for _OnSysChar().
+Files:	    src/gui_w32.c, src/gui_w48.c
+
+Patch 6.3a.020 (extra)
+Problem:    Missing support for AROS (AmigaOS reimplementation).  Amiga GUI
+	    doesn't work.
+Solution:   Add AROS support.  (Adam Chodorowski)
+	    Fix Amiga GUI problems. (Georg Steger, Ali Akcaagac)
+Files:	    Makefile, src/Make_aros.mak, src/gui_amiga.c, src/gui_amiga.h,
+	    src/memfile.c, src/os_amiga.c, src/term.c
+
+Patch 6.3a.021 (after 6.3a.017)
+Problem:    Can't compile with X11 but without GUI.
+Solution:   Put use of "gui.in_use" inside an #ifdef.
+Files:	    src/eval.c
+
+Patch 6.3a.022
+Problem:    When typing Tabs when 'softtabstop' is used and 'list' is set a
+	    tab is counted for two spaces.
+Solution:   Use the "L" flag in 'cpoptions' to tell whether a tab is counted
+	    as two spaces or as 'tabstop'. (Antony Scriven)
+Files:	    runtime/doc/options.txt, src/edit.c
+
+Patch 6.3a.023
+Problem:    Completion on the command line doesn't handle backslashes
+	    properly.  Only the tail of matches is shown, even when not
+	    completing filenames.
+Solution:   When turning the string into a pattern double backslashes.  Don't
+	    omit the path when not expanding files or directories.
+Files:	    src/ex_getln.c
+
+Patch 6.3a.024
+Problem:    The "save all" toolbar item fails for buffers that don't have a
+	    name.  When using ":wa" or closing the Vim window and there are
+	    nameless buffers, browsing for a name may cause the name being
+	    given to the wrong buffer or not stored properly.  ":browse" only
+	    worked for one file.
+Solution:   Use ":confirm browse" for "save all".
+	    Pass buffer argument to setfname().  Restore "browse" flag and
+	    "forceit" after doing the work for one file.
+Files:	    runtime/menu.vim, src/buffer.c, src/ex_cmds.c, src/ex_cmds2.c,
+	    src/ex_docmd.c, src/ex_getln.c, src/fileio.c, src/memline.c,
+	    src/message.c, src/window.c, src/proto/buffer.pro,
+	    src/proto/ex_cmds2.pro, src/proto/memline.pro
+
+Patch 6.3a.025
+Problem:    Setting 'virtualedit' moves the cursor. (Benji Fisher)
+Solution:   Update the virtual column before using it.
+Files:	    src/option.c
+
+Patch 6.3a.026 (extra, after 6.3a.008)
+Problem:    Editing files on Windows 98 doesn't work when 'encoding' is
+	    "utf-8" (Antoine Mechelynck)
+	    Warning for missing function prototype.
+Solution:   For all wide functions check if it failed because it is not
+	    implemented.  Use ANSI function declaration for char_to_string().
+Files:	    src/gui_w48.c, src/os_mswin.c, src/os_win32.c
+
+Patch 6.3a.027 (extra, after 6.3a.026)
+Problem:    Compiler warning for function argument.
+Solution:   Declare both char and WCHAR arrays.
+Files:	    src/gui_w48.c
+
+Patch 6.3a.028
+Problem:    ":normal ." doesn't work inside a function, because redo is saved
+	    and restored. (Benji Fisher)
+Solution:   Make a copy of the redo buffer when executing a function.
+Files:	    src/getchar.c
+
+Patch 6.3b.001 (extra)
+Problem:    Bcc 5: The generated auto/pathdef can't be compiled.
+Solution:   Fix the way quotes and backslashes are escaped.
+Files:	    src/Make_bc5.mak
+
+Patch 6.3b.002
+Problem:    Win32: conversion during file write fails when a double-byte
+	    character is split over two writes.
+Solution:   Fix the conversion retry without a trailing byte. (Taro Muraoka)
+Files:	    src/fileio.c
+
+Patch 6.3b.003 (extra)
+Problem:    Win32: When compiling with Borland C 5.5 and 'encoding' is "utf-8"
+	    then Vim can't open files under MS-Windows 98. (Antoine J.
+	    Mechelynck)
+Solution:   Don't use _wstat(), _wopen() and _wfopen() in this situation.
+Files:	    src/os_mswin.c, src/os_win32.c
+
+Patch 6.3b.004
+Problem:    ":helpgrep" includes a trailing CR in the text line.
+Solution:   Remove the CR.
+Files:	    src/quickfix.c
+
+Patch 6.3b.005
+Problem:    ":echo &g:ai" results in the local option value. (Salman Halim)
+Solution:   Pass the flags from find_option_end() to get_option_value().
+Files:	    src/eval.c
+
+Patch 6.3b.006
+Problem:    When using "mswin.vim", CTRL-V in Insert mode leaves cursor before
+	    last pasted character.  (Mathew Davis)
+Solution:   Use the same Paste() function as in menu.vim.
+Files:	    runtime/mswin.vim
+
+Patch 6.3b.007
+Problem:    Session file doesn't restore view on windows properly. (Robert
+	    Webb)
+Solution:   Restore window sizes both before and after restoring the view, so
+	    that the view, cursor position and size are restored properly.
+Files:	    src/ex_docmd.c
+
+Patch 6.3b.008
+Problem:    Using ":finally" in a user command doesn't always work. (Hari
+	    Krishna Dara)
+Solution:   Don't assume that using getexline() means the command was typed.
+Files:	    src/ex_docmd.c
+
+Patch 6.3b.009 (extra)
+Problem:    Win32: When the -P argument is not found in a window title, there
+	    is no error message.
+Solution:   When the window can't be found give an error message and exit.
+	    Also use try/except to catch failing to open the MDI window.
+	    (Michael Wookey)
+Files:	    src/gui_w32.c
+
+Patch 6.3b.010
+Problem:    Win32: Using the "-D" argument and expanding arguments may cause a
+	    hang, because the terminal isn't initialized yet. (Vince Negri)
+Solution:   Don't go into debug mode before the terminal is initialized.
+Files:	    src/main.c
+
+Patch 6.3b.011
+Problem:    Using CTRL-\ e while obtaining an expression aborts the command
+	    line. (Hari Krishna Dara)
+Solution:   Insert the CTRL-\ e as typed.
+Files:	    src/ex_getln.c
+
+Patch 6.3b.012 (after 6.3b.010)
+Problem:    Can't compile with tiny features. (Norbert Tretkowski)
+Solution:   Add #ifdefs.
+Files:	    src/main.c
+
+Patch 6.3b.013
+Problem:    Loading a session file results in editing the wrong file in the
+	    first window when this is not the file at the current position in
+	    the argument list. (Robert Webb)
+Solution:   Check w_arg_idx_invalid to decide whether to edit a file.
+Files:	    src/ex_docmd.c
+
+Patch 6.3b.014
+Problem:    ":runtime! foo*.vim" may using freed memory when a sourced script
+	    changes the value of 'runtimepath'.
+Solution:   Make a copy of 'runtimepath' when looping over the matches.
+Files:	    src/ex_cmds2.c
+
+Patch 6.3b.015
+Problem:    Get lalloc(0) error when using "p" in Visual mode while
+	    'clipboard' contains "autoselect,unnamed". (Mark Wagonner)
+Solution:   Avoid allocating zero bytes.  Obtain the clipboard when necessary.
+Files:	    src/ops.c
+
+Patch 6.3b.016
+Problem:    When 'virtualedit' is used "x" doesn't delete the last character
+	    of a line that has as many characters as 'columns'. (Yakov Lerner)
+Solution:   When the cursor isn't moved let oneright() return FAIL.
+Files:	    src/edit.c
+
+Patch 6.3b.017
+Problem:    Win32: "vim --remote-wait" doesn't exit when the server finished
+	    editing the file. (David Fishburn)
+Solution:   In the rrhelper plugin change backslashes to forward slashes and
+	    escape special characters.
+Files:	    runtime/plugin/rrhelper.vim
+
+Patch 6.3b.018
+Problem:    The list of help files in the "local additions" table doesn't
+	    recognize utf-8 encoding. (Yasuhiro Matsumoto)
+Solution:   Recognize utf-8 characters.
+Files:	    src/ex_cmds.c
+
+Patch 6.3b.019
+Problem:    When $VIMRUNTIME is not a full path name the "local additions"
+	    table lists all the help files.
+Solution:   Use fullpathcmp() instead of fnamecmp() to compare the directory
+	    names.
+Files:	    src/ex_cmds.c
+
+Patch 6.3b.020
+Problem:    When using CTRL-^ when entering a search string, the item in the
+	    statusline that indicates the keymap is not updated. (Ilya
+	    Dogolazky)
+Solution:   Mark the statuslines for updating.
+Files:	    src/ex_getln.c
+
+Patch 6.3b.021
+Problem:    The swapfile is not readable for others, the ATTENTION prompt does
+	    not show all info when someone else is editing the same file.
+	    (Marcel Svitalsky)
+Solution:   Use the protection of original file for the swapfile and set it
+	    after creating the swapfile.
+Files:	    src/fileio.c
+
+Patch 6.3b.022
+Problem:    Using "4v" to select four times the old Visual area may put the
+	    cursor beyond the end of the line. (Jens Paulus)
+Solution:   Correct the cursor column.
+Files:	    src/normal.c
+
+Patch 6.3b.023
+Problem:    When "3dip" starts in an empty line, white lines after the
+	    non-white lines are not deleted. (Jens Paulus)
+Solution:   Include the white lines.
+Files:	    src/search.c
+
+Patch 6.3b.024
+Problem:    "2daw" does not delete leading white space like "daw" does.  (Jens
+	    Paulus)
+Solution:   Include the white space when a count is used.
+Files:	    src/search.c
+
+Patch 6.3b.025
+Problem:    Percentage in ruler isn't updated when a line is deleted. (Jens
+	    Paulus)
+Solution:   Check for a change in line count when deciding to update the ruler.
+Files:	    src/screen.c, src/structs.h
+
+Patch 6.3b.026
+Problem:    When selecting "abort" at the ATTENTION prompt for a file that is
+	    already being edited Vim crashes.
+Solution:   Don't abort creating a new buffer when we really need it.
+Files:	    src/buffer.c, src/vim.h
+
+Patch 6.3b.027
+Problem:    Win32: When enabling the menu in a maximized window, Vim uses more
+	    lines than what is room for. (Shizhu Pan)
+Solution:   When deciding to call shell_resized(), also compare the text area
+	    size with Rows and Columns, not just with screen_Rows and
+	    screen_Columns.
+Files:	    src/gui.c
+
+Patch 6.3b.028
+Problem:    When in diff mode, setting 'rightleft' causes a crash. (Eddine)
+Solution:   Check for last column differently when 'rightleft' is set.
+Files:	    src/screen.c
+
+Patch 6.3b.029
+Problem:    Win32: warning for uninitialized variable.
+Solution:   Initialize to zero.
+Files:	    src/misc1.c
+
+Patch 6.3b.030
+Problem:    After Visually selecting four characters, changing it to other
+	    text, Visually selecting and yanking two characters: "." changes
+	    four characters, another "." changes two characters. (Robert Webb)
+Solution:   Don't store the size of the Visual area when redo is active.
+Files:	    src/normal.c
+
+==============================================================================
+VERSION 6.4						*version-6.4*
+
+This section is about improvements made between version 6.3 and 6.4.
+
+This is a bug-fix release.  There are also a few new features.  The major
+number of new items is in the runtime files and translations.
+
+The big MS-Windows version now uses:
+	Ruby version 1.8.3
+	Perl version 5.8.7
+	Python version 2.4.2
+
+
+Changed							*changed-6.4*
+-------
+
+Removed runtime/tools/tcltags, Exuberant ctags does it better.
+
+
+Added							*added-6.4*
+-----
+
+Alsaconf syntax file (Nikolai Weibull)
+Eruby syntax, indent, compiler and ftplugin file (Doug Kearns)
+Esterel syntax file (Maurizio Tranchero)
+Mathematica indent file (Steve Layland)
+Netrc syntax file (Nikolai Weibull)
+PHP compiler file (Doug Kearns)
+Pascal indent file (Neil Carter)
+Prescribe syntax file (Klaus Muth)
+Rubyunit compiler file (Doug Kearns)
+SMTPrc syntax file (Kornel Kielczewski)
+Sudoers syntax file (Nikolai Weibull)
+TPP syntax file (Gerfried Fuchs)
+VHDL ftplugin file (R. Shankar)
+Verilog-AMS syntax file (S. Myles Prather)
+
+Bulgarian keymap (Alberto Mardegan)
+Canadian keymap (Eric Joanis)
+
+Hungarian menu translations in UTF-8 (Kantra Gergely)
+Ukrainian menu translations (Bohdan Vlasyuk)
+
+Irish message translations (Kevin Patrick Scannell)
+
+Configure also checks for tclsh8.4.
+
+
+Fixed							*fixed-6.4*
+-----
+
+"dFxd;" deleted the character under the cursor, "d;" didn't remember the
+exclusiveness of the motion.
+
+When using "set laststatus=2 cmdheight=2" in the .gvimrc you may only get one
+line for the cmdline. (Christian Robinson)  Invoke command_height() after the
+GUI has started up.
+
+Gcc would warn "dereferencing type-punned pointer will break strict -aliasing
+rules".  Avoid using typecasts for variable pointers.
+
+Gcc 3.x interprets the -MM argument differently.  Change "-I /path" to
+"-isystem /path" for "make depend".
+
+
+Patch 6.3.001
+Problem:    ":browse split" gives the file selection dialog twice. (Gordon
+	    Bazeley)  Same problem for ":browse diffpatch".
+Solution:   Reset cmdmod.browse before calling do_ecmd().
+Files:	    src/diff.c, src/ex_docmd.c
+
+Patch 6.3.002
+Problem:    When using translated help files with non-ASCII latin1 characters
+	    in the first line the utf-8 detection is wrong.
+Solution:   Properly detect utf-8 characters.  When a mix of encodings is
+	    detected continue with the next language and avoid a "no matches"
+	    error because of "got_int" being set.  Add the directory name to
+	    the error message for a duplicate tag.
+Files:	    src/ex_cmds.c
+
+Patch 6.3.003
+Problem:    Crash when using a console dialog and the first choice does not
+	    have a default button. (Darin Ohashi)
+Solution:   Allocate two more characters for the [] around the character for
+	    the default choice.
+Files:	    src/message.c
+
+Patch 6.3.004
+Problem:    When searching for a long string (140 chars in a 80 column
+	    terminal) get three hit-enter prompts. (Robert Webb)
+Solution:   Avoid the hit-enter prompt when giving the message for wrapping
+	    around the end of the buffer.  Don't give that message again when
+	    the string was not found.
+Files:	    src/message.c, src/search.c
+
+Patch 6.3.005
+Problem:    Crash when searching for a pattern with a character offset and
+	    starting in a closed fold. (Frank Butler)
+Solution:   Check for the column to be past the end of the line.  Also fix
+	    that a pattern with a character offset relative to the end isn't
+	    read back from the viminfo properly.
+Files:	    src/search.c
+
+Patch 6.3.006
+Problem:    ":breakadd file *foo" prepends the current directory to the file
+	    pattern. (Hari Krishna Dara)
+Solution:   Keep the pattern as-is.
+Files:	    src/ex_cmds2.c
+
+Patch 6.3.007
+Problem:    When there is a buffer with 'buftype' set to "nofile" and using a
+	    ":cd" command, the swap file is not deleted when exiting.
+Solution:   Use the full path of the swap file also for "nofile" buffers.
+Files:	    src/fileio.c
+
+Patch 6.3.008
+Problem:    Compiling fails under OS/2.
+Solution:   Include "e_screenmode" also for OS/2. (David Sanders)
+Files:	    src/globals.h
+
+Patch 6.3.009 (after 6.3.006)
+Problem:    ":breakadd file /path/foo.vim" does not match when a symbolic link
+	    is involved.  (Servatius Brandt)
+Solution:   Do expand the pattern when it does not start with "*".
+Files:	    runtime/doc/repeat.txt, src/ex_cmds2.c
+
+Patch 6.3.010
+Problem:    When writing to a named pipe there is an error for fsync()
+	    failing.
+Solution:   Ignore the fsync() error for devices.
+Files:	    src/fileio.c
+
+Patch 6.3.011
+Problem:    Crash when the completion function of a user-command uses a
+	    "normal :cmd" command.  (Hari Krishna Dara)
+Solution:   Save the command line when invoking the completion function.
+Files:	    src/ex_getln.c
+
+Patch 6.3.012
+Problem:    Internal lalloc(0) error when using a complicated multi-line
+	    pattern in a substitute command. (Luc Hermitte)
+Solution:   Avoid going past the end of a line.
+Files:	    src/ex_cmds.c
+
+Patch 6.3.013
+Problem:    Crash when editing a command line and typing CTRL-R = to evaluate
+	    a function that uses "normal :cmd". (Hari Krishna Dara)
+Solution:   Save and restore the command line when evaluating an expression
+	    for CTRL-R =.
+Files:	    src/ex_getln.c, src/ops.c, src/proto/ex_getln.pro,
+	    src/proto/ops.pro
+
+Patch 6.3.014
+Problem:    When using Chinese or Taiwanese the default for 'helplang' is
+	    wrong. (Simon Liang)
+Solution:   Use the part of the locale name after "zh_".
+Files:	    src/option.c
+
+Patch 6.3.015
+Problem:    The string that winrestcmd() returns may end in garbage.
+Solution:   NUL-terminate the string. (Walter Briscoe)
+Files:	    src/eval.c
+
+Patch 6.3.016
+Problem:    The default value for 'define' has "\s" before '#'.
+Solution:   Add a star after "\s". (Herculano de Lima Einloft Neto)
+Files:	    src/option.c
+
+Patch 6.3.017
+Problem:    "8zz" may leave the cursor beyond the end of the line. (Niko
+	    Maatjes)
+Solution:   Correct the cursor column after moving to another line.
+Files:	    src/normal.c
+
+Patch 6.3.018
+Problem:    ":0argadd zero" added the argument after the first one, instead of
+	    before it. (Adri Verhoef)
+Solution:   Accept a zero range for ":argadd".
+Files:	    src/ex_cmds.h
+
+Patch 6.3.019
+Problem:    Crash in startup for debug version. (David Rennals)
+Solution:   Move the call to nbdebug_wait() to after allocating NameBuff.
+Files:	    src/main.c
+
+Patch 6.3.020
+Problem:    When 'encoding' is "utf-8" and 'delcombine' is set, "dw" does not
+	    delete a word but only a combining character of the first
+	    character, if there is one. (Raphael Finkel)
+Solution:   Correctly check that one character is being deleted.
+Files:	    src/misc1.c
+
+Patch 6.3.021
+Problem:    When the last character of a file name is a multi-byte character
+	    and the last byte is a path separator, the file cannot be edited.
+Solution:   Check for the last byte to be part of a multi-byte character.
+	    (Taro Muraoka)
+Files:	    src/fileio.c
+
+Patch 6.3.022 (extra)
+Problem:    Win32: When the last character of a file name is a multi-byte
+	    character and the last byte is a path separator, the file cannot
+	    be written.  A trail byte that is a space makes that a file cannot
+	    be opened from the command line.
+Solution:   Recognize double-byte characters when parsing the command line.
+	    In mch_stat() check for the last byte to be part of a multi-byte
+	    character.  (Taro Muraoka)
+Files:	    src/gui_w48.c, src/os_mswin.c
+
+Patch 6.3.023
+Problem:    When the "to" part of a mapping starts with its "from" part,
+	    abbreviations for the same characters is not possible.  For
+	    example, when <Space> is mapped to something that starts with a
+	    space, typing <Space> does not expand abbreviations.
+Solution:   Only disable expanding abbreviations when a mapping is not
+	    remapped, don't disable it when the RHS of a mapping starts with
+	    the LHS.
+Files:	    src/getchar.c, src/vim.h
+
+Patch 6.3.024
+Problem:    In a few places a string in allocated memory is not terminated
+	    with a NUL.
+Solution:   Add ga_append(NUL) in script_get(), gui_do_findrepl() and
+	    serverGetVimNames().
+Files:	    src/ex_getln.c, src/gui.c, src/if_xcmdsrv.c, src/os_mswin.c
+
+Patch 6.3.025 (extra)
+Problem:    Missing NUL for list of server names.
+Solution:   Add ga_append(NUL) in serverGetVimNames().
+Files:	    src/os_mswin.c
+
+Patch 6.3.026
+Problem:    When ~/.vim/after/syntax/syncolor.vim contains a command that
+	    reloads the colors an endless loop and/or a crash may occur.
+Solution:   Only free the old value of an option when it was originally
+	    allocated.  Limit recursiveness of init_highlight() to 5 levels.
+Files:	    src/option.c, src/syntax.c
+
+Patch 6.3.027
+Problem:    VMS: Writing a file may insert extra CR characters.  Not all
+	    terminals are recognized correctly.  Vt320 doesn't support colors.
+	    Environment variables are not expanded correctly.
+Solution:   Use another method to write files.  Add vt320 termcap codes for
+	    colors.  (Zoltan Arpadffy)
+Files:	    src/fileio.c, src/misc1.c, src/os_unix.c, src/structs.h,
+	    src/term.c
+
+Patch 6.3.028
+Problem:    When appending to a file the BOM marker may be written.  (Alex
+	    Jakushev)
+Solution:   Do not write the BOM marker when appending.
+Files:	    src/fileio.c
+
+Patch 6.3.029
+Problem:    Crash when inserting a line break. (Walter Briscoe)
+Solution:   In the syntax highlighting code, don't use an old state after a
+	    change was made, current_col may be past the end of the line.
+Files:	    src/syntax.c
+
+Patch 6.3.030
+Problem:    GTK 2: Crash when sourcing a script that deletes the menus, sets
+	    'encoding' to "utf-8" and loads the menus again.  GTK error
+	    message when tooltip text is in a wrong encoding.
+Solution:   Don't copy characters from the old screen to the new screen when
+	    switching 'encoding' to utf-8, they may be invalid.  Only set the
+	    tooltip when it is valid utf-8.
+Files:	    src/gui_gtk.c, src/mbyte.c, src/proto/mbyte.pro, src/screen.c
+
+Patch 6.3.031
+Problem:    When entering a mapping and pressing Tab halfway the command line
+	    isn't redrawn properly. (Adri Verhoef)
+Solution:   Reposition the cursor after drawing over the "..." of the
+	    completion attempt.
+Files:	    src/ex_getln.c
+
+Patch 6.3.032
+Problem:    Using Python 2.3 with threads doesn't work properly.
+Solution:   Release the lock after initialization.
+Files:	    src/if_python.c
+
+Patch 6.3.033
+Problem:    When a mapping ends in a Normal mode command of more than one
+	    character Vim doesn't return to Insert mode.
+Solution:   Check that the mapping has ended after obtaining all characters of
+	    the Normal mode command.
+Files:	    src/normal.c
+
+Patch 6.3.034
+Problem:    VMS: crash when using ":help".
+Solution:   Avoid using "tags-??", some Open VMS systems can't handle the "?"
+	    wildcard.  (Zoltan Arpadffy)
+Files:	    src/tag.c
+
+Patch 6.3.035 (extra)
+Problem:    RISC OS: Compile errors.
+Solution:   Change e_screnmode to e_screenmode.  Change the way
+	    __riscosify_control is set.  Improve the makefile.  (Andy Wingate)
+Files:	    src/os_riscos.c, src/search.c, src/Make_ro.mak
+
+Patch 6.3.036
+Problem:    ml_get errors when the whole file is a fold, switching
+	    'foldmethod' and doing "zj". (Christian J. Robinson) Was not
+	    deleting the fold but creating a fold with zero lines.
+Solution:   Delete the fold properly.
+Files:	    src/fold.c
+
+Patch 6.3.037 (after 6.3.032)
+Problem:    Warning for unused variable.
+Solution:   Change the #ifdefs for the saved thread stuff.
+Files:	    src/if_python.c
+
+Patch 6.3.038 (extra)
+Problem:    Win32: When the "file changed" dialog pops up after a click that
+	    gives gvim focus and not moving the mouse after that, the effect
+	    of the click may occur when moving the mouse later. (Ken Clark)
+	    Happened because the release event was missed.
+Solution:   Clear the s_button_pending variable when any input is received.
+Files:	    src/gui_w48.c
+
+Patch 6.3.039
+Problem:    When 'number' is set and inserting lines just above the first
+	    displayed line (in another window on the same buffer), the line
+	    numbers are not updated.  (Hitier Sylvain)
+Solution:   When 'number' is set and lines are inserted/deleted redraw all
+	    lines below the change.
+Files:	    src/screen.c
+
+Patch 6.3.040
+Problem:    Error handling does not always work properly and may cause a
+	    buffer to be marked as if it's viewed in a window while it isn't.
+	    Also when selecting "Abort" at the attention prompt.
+Solution:   Add enter_cleanup() and leave_cleanup() functions to move
+	    saving/restoring things for error handling to one place.
+	    Clear a buffer read error when it's unloaded.
+Files:	    src/buffer.c, src/ex_docmd.c, src/ex_eval.c,
+	    src/proto/ex_eval.pro, src/structs.h, src/vim.h
+
+Patch 6.3.041 (extra)
+Problem:    Win32: When the path to a file has Russian characters, ":cd %:p:h"
+	    doesn't work. (Valery Kondakoff)
+Solution:   Use a wide function to change directory.
+Files:	    src/os_mswin.c
+
+Patch 6.3.042
+Problem:    When there is a closed fold at the top of the window, CTRL-X
+	    CTRL-E in Insert mode reduces the size of the fold instead of
+	    scrolling the text up. (Gautam)
+Solution:   Scroll over the closed fold.
+Files:	    src/move.c
+
+Patch 6.3.043
+Problem:    'hlsearch' highlighting sometimes disappears when inserting text
+	    in PHP code with syntax highlighting. (Marcel Svitalsky)
+Solution:   Don't use pointers to remember where a match was found, use an
+	    index.  The pointers may become invalid when searching in other
+	    lines.
+Files:	    src/screen.c
+
+Patch 6.3.044 (extra)
+Problem:    Mac: When 'linespace' is non-zero the Insert mode cursor leaves
+	    pixels behind. (Richard Sandilands)
+Solution:   Erase the character cell before drawing the text when needed.
+Files:	    src/gui_mac.c
+
+
+Patch 6.3.045
+Problem:    Unusual characters in an option value may cause unexpected
+	    behavior, especially for a modeline. (Ciaran McCreesh)
+Solution:   Don't allow setting termcap options or 'printdevice' in a
+	    modeline.  Don't list options for "termcap" and "all" in a
+	    modeline.  Don't allow unusual characters in 'filetype', 'syntax',
+	    'backupext', 'keymap', 'patchmode' and 'langmenu'.
+Files:	    src/option.c, runtime/doc/options.txt
+
+Patch 6.3.046
+Problem:    ":registers" doesn't show multi-byte characters properly.
+	    (Valery Kondakoff)
+Solution:   Get the length of each character before displaying it.
+Files:	    src/ops.c
+
+Patch 6.3.047 (extra)
+Problem:    Win32 with Borland C 5.5 on Windows XP: A new file is created with
+	    read-only attributes. (Tony Mechelynck)
+Solution:   Don't use the _wopen() function for Borland.
+Files:	    src/os_win32.c
+
+Patch 6.3.048 (extra)
+Problem:    Build problems with VMS on IA64.
+Solution:   Add dependencies to the build file. (Zoltan Arpadffy)
+Files:	    src/Make_vms.mms
+
+Patch 6.3.049 (after 6.3.045)
+Problem:    Compiler warning for "char" vs "char_u" mixup. (Zoltan Arpadffy)
+Solution:   Add a typecast.
+Files:	    src/option.c
+
+Patch 6.3.050
+Problem:    When SIGHUP is received while busy exiting, non-reentrant
+	    functions such as free() may cause a crash.
+Solution:   Ignore SIGHUP when exiting because of an error. (Scott Anderson)
+Files:	    src/misc1.c, src/main.c
+
+Patch 6.3.051
+Problem:    When 'wildmenu' is set and completed file names contain multi-byte
+	    characters Vim may crash.
+Solution:   Reserve room for multi-byte characters. (Yasuhiro Matsumoto)
+Files:	    src/screen.c
+
+Patch 6.3.052 (extra)
+Problem:    Windows 98: typed keys that are not ASCII may not work properly.
+	    For example with a Russian input method. (Jiri Jezdinsky)
+Solution:   Assume that the characters arrive in the current codepage instead
+	    of UCS-2.  Perform conversion based on that.
+Files:	    src/gui_w48.c
+
+Patch 6.3.053
+Problem:    Win32: ":loadview" cannot find a file with non-ASCII characters.
+	    (Valerie Kondakoff)
+Solution:   Use mch_open() instead of open() to open the file.
+Files:	    src/ex_cmds2.c
+
+Patch 6.3.054
+Problem:    When 'insertmode' is set <C-L>4ixxx<C-L> hangs Vim. (Jens Paulus)
+	    Vim is actually still working but redraw is disabled.
+Solution:   When stopping Insert mode with CTRL-L don't put an Esc in the redo
+	    buffer but a CTRL-L.
+Files:	    src/edit.c
+
+Patch 6.3.055 (after 6.3.013)
+Problem:    Can't use getcmdline(), getcmdpos() or setcmdpos() with <C-R>=
+	    when editing a command line.  Using <C-\>e may crash Vim. (Peter
+	    Winters)
+Solution:   When moving ccline out of the way for recursive use, make it
+	    available to the functions that need it.  Also save and restore
+	    ccline when calling get_expr_line().  Make ccline.cmdbuf NULL at
+	    the end of getcmdline().
+Files:	    src/ex_getln.c
+
+Patch 6.3.056
+Problem:    The last characters of a multi-byte file name may not be displayed
+	    in the window title.
+Solution:   Avoid to remove a multi-byte character where the last byte looks
+	    like a path separator character. (Yasuhiro Matsumoto)
+Files:	    src/buffer.c, src/ex_getln.c
+
+Patch 6.3.057
+Problem:    When filtering lines folds are not updated. (Carl Osterwisch)
+Solution:   Update folds for filtered lines.
+Files:	    src/ex_cmds.c
+
+Patch 6.3.058
+Problem:    When 'foldcolumn' is equal to the window width and 'wrap' is on
+	    Vim may crash.  Disabling the vertical split feature breaks
+	    compiling.  (Peter Winters)
+Solution:   Check for zero room for wrapped text.  Make compiling without
+	    vertical splits possible.
+Files:	    src/move.c, src/quickfix.c, src/screen.c, src/netbeans.c
+
+Patch 6.3.059
+Problem:    Crash when expanding an ":edit" command containing several spaces
+	    with the shell. (Brian Hirt)
+Solution:   Allocate enough space for the quotes.
+Files:	    src/os_unix.c
+
+Patch 6.3.060
+Problem:    Using CTRL-R CTRL-O in Insert mode with an invalid register name
+	    still causes something to be inserted.
+Solution:   Check the register name for being valid.
+Files:	    src/edit.c
+
+Patch 6.3.061
+Problem:    When editing a utf-8 file in an utf-8 xterm and there is a
+	    multi-byte character in the last column, displaying is messed up.
+	    (Jo�l Rio)
+Solution:   Check for a multi-byte character, not a multi-column character.
+Files:	    src/screen.c
+
+Patch 6.3.062
+Problem:    ":normal! gQ" hangs.
+Solution:   Quit getcmdline() and do_exmode() when out of typeahead.
+Files:	    src/ex_getln.c, src/ex_docmd.c
+
+Patch 6.3.063
+Problem:    When a CursorHold autocommand changes to another window
+	    (temporarily) 'mousefocus' stops working.
+Solution:   Call gui_mouse_correct() after triggering CursorHold.
+Files:	    src/gui.c
+
+Patch 6.3.064
+Problem:    line2byte(line("$") + 1) sometimes returns the wrong number.
+	    (Charles Campbell)
+Solution:   Flush the cached line before counting the bytes.
+Files:	    src/memline.c
+
+Patch 6.3.065
+Problem:    The euro digraph doesn't always work.
+Solution:   Add an "e=" digraph for Unicode euro character and adjust the
+	    help files.
+Files:	    src/digraph.c, runtime/doc/digraph.txt
+
+Patch 6.3.066
+Problem:    Backup file may get wrong permissions.
+Solution:   Use permissions of original file for backup file in more places.
+Files:	    src/fileio.c
+
+Patch 6.3.067 (after 6.3.066)
+Problem:    Newly created file gets execute permission.
+Solution:   Check for "perm" to be negative before using it.
+Files:	    src/fileio.c
+
+Patch 6.3.068
+Problem:    When editing a compressed file xxx.gz which is a symbolic link to
+	    the actual file a ":write" renames the link.
+Solution:   Resolve the link, so that the actual file is renamed and
+	    compressed.
+Files:	    runtime/plugin/gzip.vim
+
+Patch 6.3.069
+Problem:    When converting text with illegal characters Vim may crash.
+Solution:   Avoid that too much is subtracted from the length. (Da Woon Jung)
+Files:	    src/mbyte.c
+
+Patch 6.3.070
+Problem:    After ":set number linebreak wrap" and a vertical split, moving
+	    the vertical separator far left will crash Vim. (Georg Dahn)
+Solution:   Avoid dividing by zero.
+Files:	    src/charset.c
+
+Patch 6.3.071
+Problem:    The message for CTRL-X mode is still displayed after an error for
+	    'thesaurus' or 'dictionary' being empty.
+Solution:   Clear "edit_submode".
+Files:	    src/edit.c
+
+Patch 6.3.072
+Problem:    Crash in giving substitute message when language is Chinese and
+	    encoding is utf-8. (Yongwei)
+Solution:   Make the msg_buf size larger when using multi-byte.
+Files:	    src/vim.h
+
+Patch 6.3.073
+Problem:    Win32 GUI: When the Vim window is partly above or below the
+	    screen, scrolling causes display errors when the taskbar is not on
+	    that side.
+Solution:   Use the SW_INVALIDATE flag when the Vim window is partly below or
+	    above the screen.
+Files:	    src/gui_w48.c
+
+Patch 6.3.074
+Problem:    When mswin.vim is used and 'insertmode' is set, typing text in
+	    Select mode and then using CTRL-V results in <SNR>99_Pastegi.
+	    (Georg Dahn)
+Solution:   When restart_edit is set use "d" instead of "c" to remove the
+	    selected text to avoid calling edit() twice.
+Files:	    src/normal.c
+
+Patch 6.3.075
+Problem:    After unloading another buffer, syntax highlighting in the current
+	    buffer may be wrong when it uses "containedin". (Eric Arnold)
+Solution:   Use "buf" instead of "curbuf" in syntax_clear().
+Files:	    src/syntax.c
+
+Patch 6.3.076
+Problem:    Crash when using cscope and there is a parse error (e.g., line too
+	    long). (Alexey I. Froloff)
+Solution:   Pass the actual number of matches to cs_manage_matches() and
+	    correctly handle the error situation.
+Files:	    src/if_cscope.c
+
+Patch 6.3.077 (extra)
+Problem:    VMS: First character input after ESC was not recognized.
+Solution:   Added TRM$M_TM_TIMED in vms_read().  (Zoltan Arpadffy)
+Files:	    src/os_vms.c
+
+Patch 6.3.078 (extra, after 6.3.077)
+Problem:    VMS: Performance issue after patch 6.3.077
+Solution:   Add a timeout in the itemlist.  (Zoltan Arpadffy)
+Files:	    src/os_vms.c
+
+Patch 6.3.079
+Problem:    Crash when executing a command in the command line window while
+	    syntax highlighting is enabled. (Pero Brbora)
+Solution:   Don't use a pointer to a buffer that has been deleted.
+Files:	    src/syntax.c
+
+Patch 6.3.080 (extra)
+Problem:    Win32: With 'encoding' set to utf-8 while the current codepage is
+	    Chinese editing a file with some specific characters in the name
+	    fails.
+Solution:   Use _wfullpath() instead of _fullpath() when necessary.
+Files:	    src/os_mswin.c
+
+Patch 6.3.081
+Problem:    Unix: glob() may execute a shell command when it's not wanted.
+	    (Georgi Guninski)
+Solution:   Verify the sandbox flag is not set.
+Files:	    src/os_unix.c
+
+Patch 6.3.082 (after 6.3.081)
+Problem:    Unix: expand() may execute a shell command when it's not wanted.
+	    (Georgi Guninski)
+Solution:   A more generic solution than 6.3.081.
+Files:	    src/os_unix.c
+
+Patch 6.3.083
+Problem:    VMS: The vt320 termcap entry is incomplete.
+Solution:   Add missing function keys.  (Zoltan Arpadffy)
+Files:	    src/term.c
+
+Patch 6.3.084 (extra)
+Problem:    Cygwin: compiling with DEBUG doesn't work.  Perl path was ignored.
+	    Failure when $(OUTDIR) already exists.  "po" makefile is missing.
+Solution:   Use changes tested in Vim 7. (Tony Mechelynck)
+Files:	    src/Make_cyg.mak, src/po/Make_cyg.mak
+
+Patch 6.3.085
+Problem:    Crash in syntax highlighting code. (Marc Espie)
+Solution:   Prevent current_col going past the end of the line.
+Files:	    src/syntax.c
+
+Patch 6.3.086 (extra)
+Problem:    Can't produce message translation file with msgfmt that checks
+	    printf strings.
+Solution:   Fix the Russian translation.
+Files:	    src/po/ru.po, src/po/ru.cp1251.po
+
+Patch 6.3.087
+Problem:    MS-DOS: Crash. (Jason Hood)
+Solution:   Don't call fname_case() with a NULL pointer.
+Files:	    src/ex_cmds.c
+
+Patch 6.3.088
+Problem:    Editing ".in" causes error E218. (Stefan Karlsson)
+Solution:   Require some characters before ".in".  Same for ".orig" and others.
+Files:	    runtime/filetype.vim
+
+Patch 6.3.089
+Problem:    A session file doesn't work when created while the current
+	    directory contains a space or the directory of the session files
+	    contains a space. (Paolo Giarrusso)
+Solution:   Escape spaces with a backslash.
+Files:	    src/ex_docmd.c
+
+Patch 6.3.090
+Problem:    A very big value for 'columns' or 'lines' may cause a crash.
+Solution:   Limit the values to 10000 and 1000.
+Files:	    src/option.c
+
+Patch 6.4a.001
+Problem:    The Unix Makefile contained too many dependencies and a few
+	    uncommented lines.
+Solution:   Run "make depend" with manual changes to avoid a gcc
+	    incompatibility.  Comment a few lines.
+Files:	    src/Makefile
+
+Patch 6.4b.001
+Problem:    Vim reports "Vim 6.4a" in the ":version" output.
+Solution:   Change "a" to "b". (Tony Mechelynck)
+Files:	    src/version.h
+
+Patch 6.4b.002
+Problem:    In Insert mode, pasting a multi-byte character after the end of
+	    the line leaves the cursor just before that character.
+Solution:   Make sure "gP" leaves the cursor in the right place when
+	    'virtualedit' is set.
+Files:	    src/ops.c
+
+Patch 6.4b.003 (after 6.4b.002)
+Problem:    The problem still exists when 'encoding' is set to "cp936".
+Solution:   Fix the problem in getvvcol(), compute the coladd field correctly.
+Files:	    src/charset.c, src/ops.c
+
+Patch 6.4b.004
+Problem:    Selecting a {} block with "viB" includes the '}' when there is an
+	    empty line before it.
+Solution:   Don't advance the cursor to include a line break when it's already
+	    at the line break.
+Files:	    src/search.c
+
+
+ vim:tw=78:ts=8:ft=help:norl:
--- /dev/null
+++ b/lib/vimfiles/doc/version7.txt
@@ -1,0 +1,4620 @@
+*version7.txt*  For Vim version 7.1.  Last change: 2007 May 12
+
+
+		  VIM REFERENCE MANUAL    by Bram Moolenaar
+
+									*vim7*
+Welcome to Vim 7!  A large number of features has been added.  This file
+mentions all the new items, changes to existing features and bug fixes
+since Vim 6.x.  Use this command to see the version you are using: >
+	:version
+
+See |vi_diff.txt| for an overview of differences between Vi and Vim 7.0.
+See |version4.txt| for differences between Vim 3.x and Vim 4.x.
+See |version5.txt| for differences between Vim 4.x and Vim 5.x.
+See |version6.txt| for differences between Vim 5.x and Vim 6.x.
+
+INCOMPATIBLE CHANGES			|incompatible-7|
+
+NEW FEATURES				|new-7|
+
+Vim script enhancements			|new-vim-script|
+Spell checking				|new-spell|
+Omni completion				|new-omni-completion|
+MzScheme interface			|new-MzScheme|
+Printing multi-byte text		|new-print-multi-byte|
+Tab pages				|new-tab-pages|
+Undo branches				|new-undo-branches|
+Extended Unicode support		|new-more-unicode|
+More highlighting			|new-more-highlighting|
+Translated manual pages			|new-manpage-trans|
+Internal grep				|new-vimgrep|
+Scroll back in messages			|new-scroll-back|
+Cursor past end of the line		|new-onemore|
+POSIX compatibility			|new-posix|
+Debugger support			|new-debug-support|
+Remote file explorer			|new-netrw-explore|
+Define an operator			|new-define-operator|
+Mapping to an expression		|new-map-expression|
+Visual and Select mode mappings		|new-map-select|
+Location list				|new-location-list|
+Various new items			|new-items-7|
+
+IMPROVEMENTS				|improvements-7|
+
+COMPILE TIME CHANGES			|compile-changes-7|
+
+BUG FIXES				|bug-fixes-7|
+
+VERSION 7.1			|version-7.1|
+Changed					|changed-7.1|
+Added					|added-7.1|
+Fixed					|fixed-7.1|
+
+==============================================================================
+INCOMPATIBLE CHANGES				*incompatible-7*
+
+These changes are incompatible with previous releases.  Check this list if you
+run into a problem when upgrading from Vim 6.x to 7.0.
+
+A ":write file" command no longer resets the 'modified' flag of the buffer,
+unless the '+' flag is in 'cpoptions' |cpo-+|.  This was illogical, since the
+buffer is still modified compared to the original file.  And when undoing
+all changes the file would actually be marked modified.  It does mean that
+":quit" fails now.
+
+":helpgrep" now uses a help window to display a match.
+
+In an argument list double quotes could be used to include spaces in a file
+name.  This caused a difference between ":edit" and ":next" for escaping
+double quotes and it is incompatible with some versions of Vi.
+	Command			Vim 6.x	file name	Vim 7.x file name ~
+	:edit foo\"888		foo"888			foo"888
+	:next foo\"888		foo888			foo"888
+	:next a\"b c\"d		ab cd			a"b  and  c"d
+
+In a |literal-string| a single quote can be doubled to get one.
+":echo 'a''b'" would result in "a b", but now that two quotes stand for one it
+results in "a'b".
+
+When overwriting a file with ":w! fname" there was no warning for when "fname"
+was being edited by another Vim.  Vim now gives an error message |E768|.
+
+The support for Mac OS 9 has been removed.
+
+Files ending in .tex now have 'filetype' set to "context", "plaintex", or
+"tex".  |ft-tex-plugin|
+
+
+Minor incompatibilities:
+
+For filetype detection: For many types, use */.dir/filename instead of
+~/.dir/filename, so that it also works for other user's files.
+
+For quite a few filetypes the indent settings have been moved from the
+filetype plugin to the indent plugin.  If you used: >
+	:filetype plugin on
+Then some indent settings may be missing.  You need to use: >
+	:filetype plugin indent on
+
+":0verbose" now sets 'verbose' to zero instead of one.
+
+Removed the old and incomplete "VimBuddy" code.
+
+Buffers without a name report "No Name" instead of "No File".  It was
+confusing for buffers with a name and 'buftype' set to "nofile".
+
+When ":file xxx" is used in a buffer without a name, the alternate file name
+isn't set.  This avoids creating buffers without a name, they are not useful.
+
+The "2html.vim" script now converts closed folds to HTML.  This means the HTML
+looks like it's displayed, with the same folds open and closed.  Use "zR", or
+"let html_ignore_folding=1", if no folds should appear in the HTML. (partly by
+Carl Osterwisch)
+Diff mode is now also converted to HTML as it is displayed.
+
+Win32: The effect of the <F10> key depended on 'winaltkeys'.  Now it depends
+on whether <F10> has been mapped or not.  This allows mapping <F10> without
+changing 'winaltkeys'.
+
+When 'octal' is in 'nrformats' and using CTRL-A on "08" it became "018", which
+is illogical.  Now it becomes "9".  The leading zero(s) is(are) removed to
+avoid the number becoming octal after incrementing "009" to "010".
+
+When 'encoding' is set to a Unicode encoding, the value for 'fileencodings'
+now includes "default" before "latin1".  This means that for files with 8-bit
+encodings the default is to use the encoding specified by the environment, if
+possible.  Previously latin1 would always be used, which is wrong in a
+non-latin1 environment, such as Russian.
+
+Previously Vim would exit when there are two windows, both of them displaying
+a help file, and using ":quit".  Now only the window is closed.
+
+"-w {scriptout}" only works when {scriptout} doesn't start with a digit.
+Otherwise it's used to set the 'window' option.
+
+Previously <Home> and <xHome> could be mapped separately.  This had the
+disadvantage that all mappings (with modifiers) had to be duplicated, since
+you can't be sure what the keyboard generates.  Now all <xHome> are internally
+translated to <Home>, both for the keys and for mappings.  Also for <xEnd>,
+<xF1>, etc.
+
+":put" now leaves the cursor on the last inserted line.
+
+When a .gvimrc file exists then 'compatible' is off, just like when a ".vimrc"
+file exists.
+
+When making a string upper-case with "vlllU" or similar then the German sharp
+s is replaced with "SS".  This does not happen with "~" to avoid backwards
+compatibility problems and because "SS" can't be changed back to a sharp s.
+
+"gd" previously found the very first occurrence of a variable in a function,
+that could be the function argument without type.  Now it finds the position
+where the type is given.
+
+The line continuation in functions was not taken into account, line numbers in
+errors were logical lines, not lines in the sourced file.  That made it
+difficult to locate errors.  Now the line number in the sourced file is
+reported, relative to the function start.  This also means that line numbers
+for ":breakadd func" are different.
+
+When defining a user command with |:command| the special items could be
+abbreviated.  This caused unexpected behavior, such as <li> being recognized
+as <line1>.  The items can no longer be abbreviated.
+
+When executing a FileChangedRO autocommand it is no longer allowed to switch
+to another buffer or edit another file.  This is to prevent crashes (the event
+is triggered deep down in the code where changing buffers is not anticipated).
+It is still possible to reload the buffer.
+
+At the |more-prompt| and the |hit-enter-prompt|, when the 'more' option is
+set, the 'k', 'u', 'g' and 'b' keys are now used to scroll back to previous
+messages.  Thus they are no longer used as typeahead.
+
+==============================================================================
+NEW FEATURES						*new-7*
+
+Vim script enhancements					*new-vim-script*
+-----------------------
+
+In Vim scripts the following types have been added:
+
+	|List|		ordered list of items
+	|Dictionary|	associative array of items
+	|Funcref|	reference to a function
+
+Many functions and commands have been added to support the new types.
+
+The |string()| function can be used to get a string representation of a
+variable.  Works for Numbers, Strings and composites of them.  Then |eval()|
+can be used to turn the string back into the variable value.
+
+The |:let| command can now use "+=", "-=" and ".=": >
+	:let var += expr	" works like :let var = var + expr
+	:let var -= expr	" works like :let var = var - expr
+	:let var .= string	" works like :let var = var . string
+
+With the |:profile| command you can find out where your function or script
+is wasting time.
+
+In the Python interface vim.eval() also handles Dictionaries and Lists.
+|python-eval| (G. Sumner Hayes)
+
+The |getscript| plugin was added as a convenient way to update scripts from
+www.vim.org automatically. (Charles Campbell)
+
+The |vimball| plugin was added as a convenient way to distribute a set of
+files for a plugin (plugin file, autoload script, documentation). (Charles
+Campbell)
+
+
+Spell checking						*new-spell*
+--------------
+
+Spell checking has been integrated in Vim.  There were a few implementations
+with scripts, but they were slow and/or required an external program.
+
+The 'spell'	   option is used to switch spell checking on or off
+The 'spelllang'    option is used to specify the accepted language(s)
+The 'spellfile'    option specifies where new words are added
+The 'spellsuggest' option specifies the methods used for making suggestions
+
+The |[s| and |]s| commands can be used to move to the next or previous error
+The |zg| and |zw| commands can be used to add good and wrong words
+The |z=|	  command can be used to list suggestions and correct the word
+The |:mkspell|    command is used to generate a Vim spell file from word lists
+
+The "undercurl" highlighting attribute was added to nicely point out spelling
+mistakes in the GUI (based on patch from Marcin Dalecki).
+The "guisp" color can be used to give it a color different from foreground and
+background.
+The number of possible different highlight attributes was raised from about
+220 to over 30000.  This allows for the attributes of spelling to be combined
+with syntax highlighting attributes.  This is also used for syntax
+highlighting and marking the Visual area.
+
+Much more info here: |spell|.
+
+
+Omni completion					*new-omni-completion*
+---------------
+
+This could also be called "intellisense", but that is a trademark.  It is a
+smart kind of completion.  The text in front of the cursor is inspected to
+figure out what could be following.  This may suggest struct and class
+members, system functions, etc.
+
+Use CTRL-X CTRL-O in Insert mode to start the completion.  |i_CTRL-X_CTRL-O|
+
+The 'omnifunc' option is set by filetype plugins to define the function that
+figures out the completion.
+
+Currently supported languages:
+	C					|ft-c-omni|
+	(X)HTML with CSS			|ft-html-omni|
+	JavaScript				|ft-javascript-omni|
+	PHP					|ft-php-omni|
+	Python
+	Ruby					|ft-ruby-omni|
+	SQL					|ft-sql-omni|
+	XML					|ft-xml-omni|
+	any language wih syntax highligting	|ft-syntax-omni|
+
+You can add your own omni completion scripts.
+
+When the 'completeopt' option contains "menu" then matches for Insert mode
+completion are displayed in a (rather primitive) popup menu.
+
+
+MzScheme interface					*new-MzScheme*
+------------------
+
+The MzScheme interpreter is supported. |MzScheme|
+
+The |:mzscheme| command can be used to execute MzScheme commands
+The |:mzfile|   command can be used to execute an MzScheme script file
+
+This depends on Vim being compiled with the |+mzscheme| feature.
+
+
+Printing multi-byte text				*new-print-multi-byte*
+------------------------
+
+The |:hardcopy| command now supports printing multi-byte characters when using
+PostScript.
+
+The 'printmbcharset' and 'printmbfont' options are used for this.
+Also see |postscript-cjk-printing|.  (Mike Williams)
+
+
+Tab pages						*new-tab-pages*
+---------
+
+A tab page is page with one or more windows with a label (aka tab) at the top.
+By clicking on the label you can quickly switch between the tab pages.  And
+with the keyboard, using the |gt| (Goto Tab) command.  This is a convenient
+way to work with many windows.
+
+To start Vim with each file argument in a separate tab page use the |-p|
+argument.  The maximum number of pages can be set with 'tabpagemax'.
+
+The line with tab labels is either made with plain text and highlighting or
+with a GUI mechanism.  The GUI labels look better but are only available on a
+few systems.  The line can be customized with 'tabline', 'guitablabel' and
+'guitabtooltip'.  Whether it is displayed is set with 'showtabline'.  Whether
+to use the GUI labels is set with the "e" flag in 'guioptions'.
+
+The |:tab| command modifier can be used to have most commands that open a new
+window open a new tab page instead.
+
+The |--remote-tab| argument can be used to edit a file in a new tab page in an
+already running Vim server.
+
+Variables starting with "t:" are local to a tab page.
+
+More info here: |tabpage|
+Most of the GUI stuff was implemented by Yegappan Lakshmanan.
+
+
+Undo branches						*new-undo-branches*
+-------------
+
+Previously there was only one line of undo-redo.  If, after undoing a number
+of changes, a new change was made all the undone changes were lost.  This
+could lead to accidentally losing work.
+
+Vim now makes an undo branch in this situation.  Thus you can go back to the
+text after any change, even if they were undone.  So long as you do not run
+into 'undolevels', when undo information is freed up to limit the memory used.
+
+To be able to navigate the undo branches each change is numbered sequentially.
+The commands |g-| and |:earlier| go back in time, to older changes.  The
+commands |g+| and |:later| go forward in time, to newer changes.
+
+The changes are also timestamped.  Use ":earlier 10m" to go to the text as it
+was about ten minutes earlier.
+
+The |:undolist| command can be used to get an idea of which undo branches
+exist.  The |:undo| command now takes an argument to directly jump to a
+specific position in this list.  The |changenr()| function can be used to
+obtain the change number.
+
+There is no graphical display of the tree with changes, navigation can be
+quite confusing.
+
+
+Extended Unicode support				*new-more-unicode*
+------------------------
+
+Previously only two combining characters were displayed.  The limit is now
+raised to 6.  This can be set with the 'maxcombine' option.  The default is
+still 2.
+
+|ga| now shows all combining characters, not just the first two.
+
+Previously only 16 bit Unicode characters were supported for displaying.  Now
+the full 32 bit character set can be used.  Unless manually disabled at
+compile time to save a bit of memory.
+
+For pattern matching it is now possible to search for individual composing
+characters. |patterns-composing|
+
+The |8g8| command searches for an illegal UTF-8 byte sequence.
+
+
+More highlighting				*new-more-highlighting*
+-----------------
+
+Highlighting matching parens:
+
+When moving the cursor through the text and it is on a paren, then the
+matching paren can be highlighted.  This uses the new |CursorMoved|
+autocommand event.
+
+This means some commands are executed every time you move the cursor.  If this
+slows you down too much switch it off with: >
+	:NoMatchParen
+
+See |matchparen| for more information.
+
+The plugin uses the |:match| command.  It now supports three match patterns.
+The plugin uses the third one.  The first one is for the user and the second
+one can be used by another plugin.
+
+Highlighting the cursor line and column:
+
+The 'cursorline' and 'cursorcolumn' options have been added.  These highlight
+the screen line and screen column of the cursor.  This makes the cursor
+position easier to spot.  'cursorcolumn' is also useful to align text.  This
+may make screen updating quite slow.  The CursorColumn and CursorLine
+highlight groups allow changing the colors used.  |hl-CursorColumn|
+|hl-CursorLine|
+
+The number of possible different highlight attributes was raised from about
+220 to over 30000.  This allows for the attributes of spelling to be combined
+with syntax highlighting attributes.  This is also used for syntax
+highlighting, marking the Visual area, CursorColumn, etc.
+
+
+Translated manual pages					*new-manpage-trans*
+-----------------------
+
+The manual page of Vim and associated programs is now also available in
+several other languages.
+
+French  - translated by David Blanchet
+Italian - translated by Antonio Colombo
+Russian - translated by Vassily Ragosin
+Polish  - translated by Mikolaj Machowski
+
+The Unix Makefile installs the Italian manual pages in .../man/it/man1/,
+.../man/it.ISO8859-1/man1/ and .../man/it.UTF-8/man1/.  There appears to be no
+standard for what encoding goes in the "it" directory, the 8-bit encoded file
+is used there as a best guess.
+Other languages are installed in similar places.
+The translated pages are not automatically installed when Vim was configured
+with "--disable-nls", but "make install-languages install-tool-languages" will
+do it anyway.
+
+
+Internal grep						*new-vimgrep*
+-------------
+
+The ":vimgrep" command can be used to search for a pattern in a list of files.
+This is like the ":grep" command, but no external program is used.  Besides
+better portability, handling of different file encodings and using multi-line
+patterns, this also allows grepping in compressed and remote files.
+|:vimgrep|.
+
+If you want to use the search results in a script you can use the
+|getqflist()| function.
+
+To grep files in various directories the "**" pattern can be used.  It expands
+into an arbitrary depth of directories.  "**" can be used in all places where
+file names are expanded, thus also with |:next| and |:args|.
+
+
+Scroll back in messages					*new-scroll-back*
+-----------------------
+
+When displaying messages, at the |more-prompt| and the |hit-enter-prompt|, The
+'k', 'u', 'g' and 'b' keys can be used to scroll back to previous messages.
+This is especially useful for commands such as ":syntax", ":autocommand" and
+":highlight".  This is implemented in a generic way thus it works for all
+commands and highlighting is kept.  Only works when the 'more' option is set.
+Previously it only partly worked for ":clist".
+
+The |g<| command can be used to see the last page of messages after you have
+hit <Enter> at the |hit-enter-prompt|.  Then you can scroll further back.
+
+
+Cursor past end of the line				*new-onemore*
+---------------------------
+
+When the 'virtualedit' option contains "onemore" the cursor can move just past
+the end of the line.  As if it's on top of the line break.
+
+This makes some commands more consistent.  Previously the cursor was always
+past the end of the line if the line was empty.  But it is far from Vi
+compatible.  It may also break some plugins or Vim scripts.  Use with care!
+
+The patch was provided by Mattias Flodin.
+
+
+POSIX compatibility					*new-posix*
+-------------------
+
+The POSIX test suite was used to verify POSIX compatibility.  A number of
+problems have been fixed to make Vim more POSIX compatible.  Some of them
+conflict with traditional Vi or expected behavior.  The $VIM_POSIX environment
+variable can be set to get POSIX compatibility.  See |posix|.
+
+Items that were fixed for both Vi and POSIX compatibility:
+- repeating "R" with a count only overwrites text once; added the 'X' flag to
+  'cpoptions' |cpo-X|
+- a vertical movement command that moves to a non-existing line fails; added
+  the '-' flag to 'cpoptions' |cpo--|
+- when preserving a file and doing ":q!" the file can be recovered; added the
+  '&' flag to 'cpoptions' |cpo-&|
+- The 'window' option is partly implemented.  It specifies how much CTRL-F and
+  CTRL-B scroll when there is one window.  The "-w {number}" argument is now
+  accepted.  "-w {scriptout}" only works when {scriptout} doesn't start with a
+  digit.
+- Allow "-c{command}" argument, no space between "-c" and {command}.
+- When writing a file with ":w!" don't reset 'readonly' when 'Z' is present in
+  'cpoptions'.
+- Allow 'l' and '#' flags for ":list", ":print" and ":number".
+- Added the '.' flag to 'cpoptions': ":cd" fails when the buffer is modified.
+- In Ex mode with an empty buffer ":read file" doesn't keep an empty line
+  above or below the new lines.
+- Remove a backslash before a NL for the ":global" command.
+- When ":append", ":insert" or ":change" is used with ":global", get the
+  inserted lines from the command.  Can use backslash-NL to separate lines.
+- Can use ":global /pat/ visual" to execute Normal mode commands at each
+  matched line.  Use "Q" to continue and go to the next line.
+- The |:open| command has been partially implemented.  It stops Ex mode, but
+  redraws the whole screen, not just one line as open mode is supposed to do.
+- Support using a pipe to read the output from and write input to an external
+  command.  Added the 'shelltemp' option and has("filterpipe").
+- In ex silent mode the ":set" command output is displayed.
+- The ":@@" and ":**" give an error message when no register was used before.
+- The search pattern "[]-`]" matches ']', '^', '_' and '`'.
+- Autoindent for ":insert" is using the line below the insert.
+- Autoindent for ":change" is using the first changed line.
+- Editing Ex command lines is not done in cooked mode, because CTRL-D and
+  CTRL-T cannot be handled then.
+- In Ex mode, "1,3" prints three lines.  "%" prints all lines.
+- In Ex mode "undo" would undo all changes since Ex mode was started.
+- Implemented the 'prompt' option.
+
+
+Debugger support					*new-debug-support*
+----------------
+
+The 'balloonexpr' option has been added.  This is a generic way to implement
+balloon functionality.  You can use it to show info for the word under the
+mouse pointer.
+
+
+Remote file explorer					*new-netrw-explore*
+--------------------
+
+The netrw plugin now also supports viewing a directory, when "scp://" is used.
+Deleting and renaming files is possible.
+
+To avoid duplicating a lot of code, the previous file explorer plugin has been
+integrated in the netrw plugin.  This means browsing local and remote files
+works the same way.
+
+":browse edit" and ":browse split" use the netrw plugin when it's available
+and a GUI dialog is not possible.
+
+The netrw plugin is maintained by Charles Campbell.
+
+
+Define an operator					*new-define-operator*
+------------------
+
+Previously it was not possible to define your own operator; a command that is
+followed by a {motion}.  Vim 7 introduces the 'operatorfunc' option and the
+|g@| operator.  This makes it possible to define a mapping that works like an
+operator.  The actual work is then done by a function, which is invoked
+through the |g@| operator.
+
+See |:map-operator| for the explanation and an example.
+
+
+Mapping to an expression				*new-map-expression*
+------------------------
+
+The {rhs} argument of a mapping can be an expression.  That means the
+resulting characters can depend on the context.  Example: >
+	:inoremap <expr> . InsertDot()
+Here the dot will be mapped to whatever InsertDot() returns.
+
+This also works for abbreviations.  See |:map-<expr>| for the details.
+
+
+Visual and Select mode mappings				*new-map-select*
+-------------------------------
+
+Previously Visual mode mappings applied both to Visual and Select mode.  With
+a trick to have the mappings work in Select mode like they would in Visual
+mode.
+
+Commands have been added to define mappings for Visual and Select mode
+separately: |:xmap| and |:smap|.  With the associated "noremap" and "unmap"
+commands.
+
+The same is done for menus: |:xmenu|, |:smenu|, etc.
+
+
+Location list						*new-location-list*
+-------------
+
+The support for a per-window quickfix list (location list) is added. The
+location list can be displayed in a location window (similar to the quickfix
+window).  You can open more than one location list window.  A set of commands
+similar to the quickfix commands are added to browse the location list.
+(Yegappan Lakshmanan)
+
+
+Various new items					*new-items-7*
+-----------------
+
+Normal mode commands: ~
+
+a", a' and a`		New text objects to select quoted strings. |a'|
+i", i' and i`		(Taro Muraoka)
+
+CTRL-W <Enter>		In the quickfix window: opens a new window to show the
+			location of the error under the cursor.
+
+|at| and |it| text objects select a block of text between HTML or XML tags.
+
+<A-LeftMouse> ('mousemodel' "popup" or "popup-setpos")
+<A-RightMouse> ('mousemodel' "extend")
+			Make a blockwise selection. |<A-LeftMouse>|
+
+gF			Start editing the filename under the cursor and jump
+			to the line number following the file name.
+			(Yegappan Lakshmanan)
+
+CTRL-W F		Start editing the filename under the cursor in a new
+			window and jump to the line number following the file
+			name.  (Yegappan Lakshmanan)
+
+Insert mode commands: ~
+
+CTRL-\ CTRL-O		Execute a Normal mode command.  Like CTRL-O but
+			without moving the cursor. |i_CTRL-\_CTRL-O|
+
+Options: ~
+
+'balloonexpr'		expression for text to show in evaluation balloon
+'completefunc'		The name of the function used for user-specified
+			Insert mode completion.  CTRL-X CTRL-U can be used in
+			Insert mode to do any kind of completion.  (Taro
+			Muraoka)
+'completeopt'		Enable popup menu and other settings for Insert mode
+			completion.
+'cursorcolumn'		highlight column of the cursor
+'cursorline'		highlight line of the cursor
+'formatexpr'		expression for formatting text with |gq| and when text
+			goes over 'textwidth' in Insert mode.
+'formatlistpat'		pattern to recognize a numbered list for formatting.
+			(idea by Hugo Haas)
+'fsync'			Whether fsync() is called after writing a file.
+			(Ciaran McCreesh)
+'guitablabel'		expression for text to display in GUI tab page label
+'guitabtooltip'		expression for text to display in GUI tab page tooltip
+'macatsui'		Mac: use ATSUI text display functions
+'maxcombine'		maximum number of combining characters displayed
+'maxmempattern'		maximum amount of memory to use for pattern matching
+'mkspellmem'		parameters for |:mkspell| memory use
+'mzquantum'		Time in msec to schedule MzScheme threads.
+'numberwidth'		Minimal width of the space used for the 'number'
+			option. (Emmanuel Renieris)
+'omnifunc'		The name of the function used for omni completion.
+'operatorfunc'		function to be called for |g@| operator
+'printmbcharset'	CJK character set to be used for :hardcopy
+'printmbfont'		font names to be used for CJK output of :hardcopy
+'pumheight'		maximum number of items to show in the popup menu
+'quoteescape'		Characters used to escape quotes inside a string.
+			Used for the a", a' and a` text objects. |a'|
+'shelltemp'		whether to use a temp file or pipes for shell commands
+'showtabline'		whether to show the tab pages line
+'spell'			switch spell checking on/off
+'spellcapcheck'		pattern to locate the end of a sentence
+'spellfile'		file where good and wrong words are added
+'spelllang'		languages to check spelling for
+'spellsuggest'		methods for spell suggestions
+'synmaxcol'		maximum column to look for syntax items; avoids very
+			slow redrawing when there are very long lines
+'tabline'		expression for text to display in the tab pages line
+'tabpagemax'		maximum number of tab pages to open for |-p|
+'verbosefile'		Log messages in a file.
+'wildoptions'		"tagfile" value enables listing the file name of
+			matching tags for CTRL-D command line completion.
+			(based on an idea from Yegappan Lakshmanan)
+'winfixwidth'		window with fixed width, similar to 'winfixheight'
+
+
+Ex commands: ~
+
+Win32: The ":winpos" command now also works in the console. (Vipin Aravind)
+
+|:startreplace|		Start Replace mode. (Charles Campbell)
+|:startgreplace|	Start Virtual Replace mode.
+
+|:0file|		Removes the name of the buffer. (Charles Campbell)
+
+|:diffoff|		Switch off diff mode in the current window or in all
+			windows.
+
+|:delmarks|		Delete marks.
+
+|:exusage|		Help for Ex commands (Nvi command).
+|:viusage|		Help for Vi commands (Nvi command).
+
+|:sort|			Sort lines in the buffer without depending on an
+			external command. (partly by Bryce Wagner)
+
+|:vimgrep|		Internal grep command, search for a pattern in files.
+|:vimgrepadd|		Like |:vimgrep| but don't make a new list.
+
+|:caddfile|		Add error messages to an existing quickfix list
+			(Yegappan Lakshmanan).
+|:cbuffer|		Read error lines from a buffer. (partly by Yegappan
+			Lakshmanan)
+|:cgetbuffer|		Create a quickfix list from a buffer but don't jump to
+			the first error.
+|:caddbuffer|		Add errors from the current buffer to the quickfix
+			list.
+|:cexpr|		Read error messages from a Vim expression (Yegappan
+			Lakshmanan).
+|:caddexpr|		Add error messages from a Vim expression to an
+			existing quickfix list. (Yegappan Lakshmanan).
+|:cgetexpr|		Create a quickfix list from a Vim expression, but
+			don't jump to the first error. (Yegappan Lakshmanan).
+
+|:lfile|		Like |:cfile| but use the location list.
+|:lgetfile|		Like |:cgetfile| but use the location list.
+|:laddfile|		Like |:caddfile| but use the location list.
+|:lbuffer|		Like |:cbuffer| but use the location list.
+|:lgetbuffer|		Like |:cgetbuffer| but use the location list.
+|:laddbuffer|		Like |:caddbuffer| but use the location list.
+|:lexpr|		Like |:cexpr| but use the location list.
+|:lgetexpr|		Like |:cgetexpr| but use the location list.
+|:laddexpr|		Like |:caddexpr| but use the location list.
+|:ll|			Like |:cc| but use the location list.
+|:llist|		Like |:clist| but use the location list.
+|:lnext|		Like |:cnext| but use the location list.
+|:lprevious|		Like |:cprevious| but use the location list.
+|:lNext|		Like |:cNext| but use the location list.
+|:lfirst|		Like |:cfirst| but use the location list.
+|:lrewind|		Like |:crewind| but use the location list.
+|:llast|		Like |:clast| but use the location list.
+|:lnfile|		Like |:cnfile| but use the location list.
+|:lpfile|		Like |:cpfile| but use the location list.
+|:lNfile|		Like |:cNfile| but use the location list.
+|:lolder|		Like |:colder| but use the location list.
+|:lnewer|		Like |:cnewer| but use the location list.
+|:lwindow|		Like |:cwindow| but use the location list.
+|:lopen|		Like |:copen| but use the location list.
+|:lclose|		Like |:cclose| but use the location list.
+|:lmake|		Like |:make| but use the location list.
+|:lgrep|		Like |:grep| but use the location list.
+|:lgrepadd|		Like |:grepadd| but use the location list.
+|:lvimgrep|		Like |:vimgrep| but use the location list.
+|:lvimgrepadd|		Like |:vimgrepadd| but use the location list.
+|:lhelpgrep|		Like |:helpgrep| but use the location list.
+|:lcscope|		Like |:cscope| but use the location list.
+|:ltag|			Jump to a tag and add matching tags to a location list.
+
+|:undojoin|		Join a change with the previous undo block.
+|:undolist|		List the leafs of the undo tree.
+
+|:earlier|		Go back in time for changes in the text.
+|:later|		Go forward in time for changes in the text.
+
+|:for|			Loop over a |List|.
+|:endfor|
+
+|:lockvar|		Lock a variable, prevents it from being changed.
+|:unlockvar|		Unlock a locked variable.
+
+|:mkspell|		Create a Vim spell file.
+|:spellgood|		Add a word to the list of good words.
+|:spellwrong|		Add a word to the list of bad words
+|:spelldump|		Dump list of good words.
+|:spellinfo|		Show information about the spell files used.
+|:spellrepall|		Repeat a spelling correction for the whole buffer.
+|:spellundo|		Remove a word from list of good and bad words.
+
+|:mzscheme|		Execute MzScheme commands.
+|:mzfile|		Execute an MzScheme script file.
+
+|:nbkey|		Pass a key to NetBeans for processing.
+
+|:profile|		Commands for Vim script profiling.
+|:profdel|		Stop profiling for specified items.
+
+|:smap|			Select mode mapping.
+|:smapclear|
+|:snoremap|
+|:sunmap|
+
+|:xmap|			Visual mode mapping, not used for Select mode.
+|:xmapclear|
+|:xnoremap|
+|:xunmap|
+
+|:smenu|		Select mode menu.
+|:snoremenu|
+|:sunmenu|
+
+|:xmenu|		Visual mode menu, not used for Select mode.
+|:xnoremenu|
+|:xunmenu|
+
+|:tabclose|		Close the current tab page.
+|:tabdo|		Perform a command in every tab page.
+|:tabedit|		Edit a file in a new tab page.
+|:tabnew|		Open a new tab page.
+|:tabfind|		Search for a file and open it in a new tab page.
+|:tabnext|		Go to the next tab page.
+|:tabprevious|		Go to the previous tab page.
+|:tabNext|		Go to the previous tab page.
+|:tabfirst|		Go to the first tab page.
+|:tabrewind|		Go to the first tab page.
+|:tablast|		Go to the last tab page.
+|:tabmove|		Move the current tab page elsewhere.
+|:tabonly|		Close all other tab pages.
+|:tabs|			List the tab pages and the windows they contain.
+
+Ex command modifiers: ~
+
+|:keepalt|		Do not change the alternate file.
+
+|:noautocmd|		Do not trigger autocommand events.
+
+|:sandbox|		Execute a command in the sandbox.
+
+|:tab|			When opening a new window create a new tab page.
+
+
+Ex command arguments: ~
+
+|++bad|			Specify what happens with characters that can't be
+			converted and illegal bytes. (code example by Yasuhiro
+			Matsumoto)
+			Also, when a conversion error occurs or illegal bytes
+			are found include the line number in the error
+			message.
+
+
+New and extended functions: ~
+
+|add()|			append an item to a List
+|append()|		append List of lines to the buffer
+|argv()|		without an argument return the whole argument list
+|browsedir()|		dialog to select a directory
+|bufnr()|		takes an extra argument: create buffer
+|byteidx()|		index of a character (Ilya Sher)
+|call()|		call a function with List as arguments
+|changenr()|		number of current change
+|complete()|		set matches for Insert mode completion
+|complete_add()|	add match for 'completefunc'
+|complete_check()|	check for key pressed, for 'completefunc'
+|copy()|		make a shallow copy of a List or Dictionary
+|count()|		count nr of times a value is in a List or Dictionary
+|cursor()|		also accepts an offset for 'virtualedit', and
+			the first argument can be a list: [lnum, col, off]
+|deepcopy()|		make a full copy of a List or Dictionary
+|diff_filler()|		returns number of filler lines above line {lnum}.
+|diff_hlID()|		returns the highlight ID for diff mode
+|empty()|		check if List or Dictionary is empty
+|eval()|		evaluate {string} and return the result
+|extend()|		append one List to another or add items from one
+			Dictionary to another
+|feedkeys()|		put characters in the typeahead buffer
+|filter()|		remove selected items from a List or Dictionary
+|finddir()|		find a directory in 'path'
+|findfile()|		find a file in 'path' (Johannes Zellner)
+|foldtextresult()|	the text displayed for a closed fold at line "lnum"
+|function()|		make a Funcref out of a function name
+|garbagecollect()|	cleanup unused |Lists| and |Dictionaries| with circular
+			references
+|get()|			get an item from a List or Dictionary
+|getbufline()|		get a list of lines from a specified buffer
+			(Yegappan Lakshmanan)
+|getcmdtype()|		return the current command-line type
+			(Yegappan Lakshmanan)
+|getfontname()|		get actual font name being used
+|getfperm()|		get file permission string (Nikolai Weibull)
+|getftype()|		get type of file (Nikolai Weibull)
+|getline()|		with second argument: get List with buffer lines
+|getloclist()|		list of location list items (Yegappan Lakshmanan)
+|getpos()|		return a list with the position of cursor, mark, etc.
+|getqflist()|		list of quickfix errors (Yegappan Lakshmanan)
+|getreg()|		get contents of a register
+|gettabwinvar()|	get variable from window in specified tab page.
+|has_key()|		check whether a key appears in a Dictionary
+|haslocaldir()|		check if current window used |:lcd|
+|hasmapto()|		check for a mapping to a string
+|index()|		index of item in List
+|inputlist()|		prompt the user to make a selection from a list
+|insert()|		insert an item somewhere in a List
+|islocked()|		check if a variable is locked
+|items()|		get List of Dictionary key-value pairs
+|join()|		join List items into a String
+|keys()|		get List of Dictionary keys
+|len()|			number of items in a List or Dictionary
+|map()|			change each List or Dictionary item
+|maparg()|		extra argument: use abbreviation
+|mapcheck()|		extra argument: use abbreviation
+|match()|		extra argument: count
+|matcharg()|		return arguments of |:match| command
+|matchend()|		extra argument: count
+|matchlist()|		list with match and submatches of a pattern in a string
+|matchstr()|		extra argument: count
+|max()|			maximum value in a List or Dictionary
+|min()|			minimum value in a List or Dictionary
+|mkdir()|		create a directory
+|pathshorten()|		reduce directory names to a single character
+|printf()|		format text
+|pumvisible()|		check whether the popup menu is displayed
+|range()|		generate a List with numbers
+|readfile()|		read a file into a list of lines
+|reltime()|		get time value, possibly relative
+|reltimestr()|		turn a time value into a string
+|remove()|		remove one or more items from a List or Dictionary
+|repeat()|		repeat "expr" "count" times (Christophe Poucet)
+|reverse()|		reverse the order of a List
+|search()|		extra argument:
+|searchdecl()|		search for declaration of variable
+|searchpair()|		extra argument: line to stop searching
+|searchpairpos()|	return a List with the position of the match
+|searchpos()|		return a List with the position of the match
+|setloclist()|		modify a location list (Yegappan Lakshmanan)
+|setpos()|		set cursor or mark to a position
+|setqflist()|		modify a quickfix list (Yegappan Lakshmanan)
+|settabwinvar()|	set variable in window of specified tab page
+|sort()|		sort a List
+|soundfold()|		get the sound-a-like equivalent of a word
+|spellbadword()|	get a badly spelled word
+|spellsuggest()|	get suggestions for correct spelling
+|split()|		split a String into a List
+|str2nr()|		convert a string to a number, base 8, 10 or 16
+|stridx()|		extra argument: start position
+|strridx()|		extra argument: start position
+|string()|		string representation of a List or Dictionary
+|system()|		extra argument: filters {input} through a shell command
+|tabpagebuflist()|	List of buffers in a tab page
+|tabpagenr()|		number of current or last tab page
+|tabpagewinnr()|	window number in a tab page
+|tagfiles()|		List with tags file names
+|taglist()|		get list of matching tags (Yegappan Lakshmanan)
+|tr()|			translate characters (Ron Aaron)
+|values()|		get List of Dictionary values
+|winnr()|		takes an argument: what window to use
+|winrestview()|		restore the view of the current window
+|winsaveview()|		save the view of the current window
+|writefile()|		write a list of lines into a file
+
+User defined functions can now be loaded automatically from the "autoload"
+directory in 'runtimepath'.  See |autoload-functions|.
+
+
+New Vim variables: ~
+
+|v:insertmode|		used for |InsertEnter| and |InsertChange| autocommands
+|v:val|			item value in a |map()| or |filter()| function
+|v:key|			item key in a |map()| or |filter()| function
+|v:profiling|		non-zero after a ":profile start" command
+|v:fcs_reason|		the reason why |FileChangedShell| was triggered
+|v:fcs_choice|		what should happen after |FileChangedShell|
+|v:beval_bufnr|		buffer number for 'balloonexpr'
+|v:beval_winnr|		window number for 'balloonexpr'
+|v:beval_lnum|		line number for 'balloonexpr'
+|v:beval_col|		column number for 'balloonexpr'
+|v:beval_text|		text under the mouse pointer for 'balloonexpr'
+|v:scrollstart|		what caused the screen to be scrolled up
+|v:swapname|		name of the swap file for the |SwapExists| event
+|v:swapchoice|		what to do for an existing swap file
+|v:swapcommand|		command to be executed after handling |SwapExists|
+|v:char|		argument for evaluating 'formatexpr'
+
+
+New autocommand events: ~
+
+|ColorScheme|		after loading a color scheme
+
+|CursorHoldI|		the user doesn't press a key for a while in Insert mode
+|CursorMoved|		the cursor was moved in Normal mode
+|CursorMovedI|		the cursor was moved in Insert mode
+
+|FileChangedShellPost|	after handling a file changed outside of Vim
+
+|InsertEnter|		starting Insert or Replace mode
+|InsertChange|		going from Insert to Replace mode or back
+|InsertLeave|		leaving Insert or Replace mode
+
+|MenuPopup|		just before showing popup menu
+
+|QuickFixCmdPre|	before :make, :grep et al. (Ciaran McCreesh)
+|QuickFixCmdPost|	after :make, :grep et al. (Ciaran McCreesh)
+
+|SessionLoadPost|	after loading a session file. (Yegappan Lakshmanan)
+
+|ShellCmdPost|		after executing a shell command
+|ShellFilterPost|	after filtering with a shell command
+
+|SourcePre|		before sourcing a Vim script
+
+|SpellFileMissing|	when a spell file can't be found
+
+|SwapExists|		found existing swap file when editing a file
+
+|TabEnter|		just after entering a tab page
+|TabLeave|		just before leaving a tab page
+
+|VimResized|		after the Vim window size changed (Yakov Lerner)
+
+
+New highlight groups: ~
+
+Pmenu                   Popup menu: normal item |hl-Pmenu|
+PmenuSel                Popup menu: selected item |hl-PmenuSel|
+PmenuThumb              Popup menu: scrollbar |hl-PmenuThumb|
+PmenuSbar               Popup menu: Thumb of the scrollbar |hl-PmenuSbar|
+
+TabLine                 tab pages line, inactive label |hl-TabLine|
+TabLineSel              tab pages line, selected label |hl-TabLineSel|
+TabLineFill             tab pages line, filler |hl-TabLineFill|
+
+SpellBad                badly spelled word |hl-SpellBad|
+SpellCap                word with wrong caps |hl-SpellCap|
+SpellRare               rare word |hl-SpellRare|
+SpellLocal              word only exists in other region |hl-SpellLocal|
+
+CursorColumn            'cursorcolumn' |hl-CursorColumn|
+CursorLine              'cursorline' |hl-CursorLine|
+
+MatchParen              matching parens |pi_paren.txt| |hl-MatchParen|
+
+
+New items in search patterns: ~
+|/\%d| \%d123		search for character with decimal number
+|/\]|  [\d123]		idem, in a collection
+|/\%o| \%o103		search for character with octal number
+|/\]|  [\o1o3]		idem, in a collection
+|/\%x| \%x1a		search for character with 2 pos. hex number
+|/\]|  [\x1a]		idem, in a collection
+|/\%u| \%u12ab		search for character with 4 pos. hex number
+|/\]|  [\u12ab]		idem, in a collection
+|/\%U| \%U1234abcd	search for character with 8 pos. hex number
+|/\]|  [\U1234abcd]	idem, in a collection
+			    (The above partly by Ciaran McCreesh)
+
+|/[[=| [[=a=]]		an equivalence class (only for latin1 characters)
+|/[[.| [[.a.]]		a collation element (only works with single char)
+
+|/\%'m|  \%'m		match at mark m
+|/\%<'m| \%<'m		match before mark m
+|/\%>'m| \%>'m		match after mark m
+|/\%V|   \%V		match in Visual area
+
+Nesting |/multi| items no longer is an error when an empty match is possible.
+
+It is now possible to use \{0}, it matches the preceding atom zero times.  Not
+useful, just for compatibility.
+
+
+New Syntax/Indent/FTplugin files: ~
+
+Moved all the indent settings from the filetype plugin to the indent file.
+Implemented b:undo_indent to undo indent settings when setting 'filetype' to a
+different value.
+
+a2ps syntax and ftplugin file. (Nikolai Weibull)
+ABAB/4 syntax file. (Marius van Wyk)
+alsaconf ftplugin file. (Nikolai Weibull)
+AppendMatchGroup ftplugin file. (Dave Silvia)
+arch ftplugin file. (Nikolai Weibull)
+asterisk and asteriskvm syntax file. (Tilghman Lesher)
+BDF ftplugin file. (Nikolai Weibull)
+BibTeX indent file. (Dorai Sitaram)
+BibTeX Bibliography Style syntax file. (Tim Pope)
+BTM ftplugin file. (Bram Moolenaar)
+calendar ftplugin file. (Nikolai Weibull)
+Changelog indent file. (Nikolai Weibull)
+ChordPro syntax file. (Niels Bo Andersen)
+Cmake indent and syntax file. (Andy Cedilnik)
+conf ftplugin file. (Nikolai Weibull)
+context syntax and ftplugin file. (Nikolai Weibull)
+CRM114 ftplugin file. (Nikolai Weibull)
+cvs RC ftplugin file. (Nikolai Weibull)
+D indent file. (Jason Mills)
+Debian Sources.list syntax file. (Matthijs Mohlmann)
+dictconf and dictdconf syntax, indent and ftplugin files. (Nikolai Weibull)
+diff ftplugin file. (Bram Moolenaar)
+dircolors ftplugin file. (Nikolai Weibull)
+django and htmldjango syntax file. (Dave Hodder)
+doxygen syntax file. (Michael Geddes)
+elinks ftplugin file. (Nikolai Weibull)
+eterm ftplugin file. (Nikolai Weibull)
+eviews syntax file. (Vaidotas Zemlys)
+fetchmail RC ftplugin file. (Nikolai Weibull)
+FlexWiki syntax and ftplugin file. (George Reilly)
+Generic indent file. (Dave Silvia)
+gpg ftplugin file. (Nikolai Weibull)
+gretl syntax file. (Vaidotas Zemlys)
+groovy syntax file. (Alessio Pace)
+group syntax and ftplugin file. (Nikolai Weibull)
+grub ftplugin file. (Nikolai Weibull)
+Haskell ftplugin file. (Nikolai Weibull)
+help ftplugin file. (Nikolai Weibull)
+indent ftplugin file. (Nikolai Weibull)
+Javascript ftplugin file. (Bram Moolenaar)
+Kconfig ftplugin and syntax file. (Nikolai Weibull)
+ld syntax, indent and ftplugin file. (Nikolai Weibull)
+lftp ftplugin file. (Nikolai Weibull)
+libao config ftplugin file. (Nikolai Weibull)
+limits syntax and ftplugin file. (Nikolai Weibull)
+Lisp indent file. (Sergey Khorev)
+loginaccess and logindefs syntax and ftplugin file. (Nikolai Weibull)
+m4 ftplugin file. (Nikolai Weibull)
+mailaliases syntax file. (Nikolai Weibull)
+mailcap ftplugin file. (Nikolai Weibull)
+manconf syntax and ftplugin file. (Nikolai Weibull)
+matlab ftplugin file. (Jake Wasserman)
+Maxima syntax file. (Robert Dodier)
+MGL syntax file. (Gero Kuhlmann)
+modconf ftplugin file. (Nikolai Weibull)
+mplayer config ftplugin file. (Nikolai Weibull)
+Mrxvtrc syntax and ftplugin file. (Gautam Iyer)
+MuPAD source syntax, indent and ftplugin. (Dave Silvia)
+mutt RC ftplugin file. (Nikolai Weibull)
+nanorc syntax and ftplugin file. (Nikolai Weibull)
+netrc ftplugin file. (Nikolai Weibull)
+pamconf syntax and ftplugin file. (Nikolai Weibull)
+Pascal indent file. (Neil Carter)
+passwd syntax and ftplugin file. (Nikolai Weibull)
+PHP compiler plugin. (Doug Kearns)
+pinfo ftplugin file. (Nikolai Weibull)
+plaintex syntax and ftplugin files. (Nikolai Weibull, Benji Fisher)
+procmail ftplugin file. (Nikolai Weibull)
+prolog ftplugin file. (Nikolai Weibull)
+protocols syntax and ftplugin file. (Nikolai Weibull)
+quake ftplugin file. (Nikolai Weibull)
+racc syntax and ftplugin file. (Nikolai Weibull)
+readline ftplugin file. (Nikolai Weibull)
+rhelp syntax file. (Johannes Ranke)
+rnoweb syntax file. (Johannes Ranke)
+Relax NG compact ftplugin file. (Nikolai Weibull)
+Scheme indent file. (Sergey Khorev)
+screen ftplugin file. (Nikolai Weibull)
+sensors syntax and ftplugin file. (Nikolai Weibull)
+services syntax and ftplugin file. (Nikolai Weibull)
+setserial syntax and ftplugin file. (Nikolai Weibull)
+sieve syntax and ftplugin file. (Nikolai Weibull)
+SiSU syntax file (Ralph Amissah)
+Sive syntax file. (Nikolai Weibull)
+slp config, reg and spi syntax and ftplugin files. (Nikolai Weibull)
+SML indent file. (Saikat Guha)
+SQL anywhere syntax and indent file. (David Fishburn)
+SQL indent file.
+SQL-Informix syntax file. (Dean L Hill)
+SQL: Handling of various variants. (David Fishburn)
+sshconfig ftplugin file. (Nikolai Weibull)
+Stata and SMCL syntax files. (Jeff Pitblado)
+sudoers ftplugin file. (Nikolai Weibull)
+sysctl syntax and ftplugin file. (Nikolai Weibull)
+terminfo ftplugin file. (Nikolai Weibull)
+trustees syntax file. (Nima Talebi)
+Vera syntax file. (David Eggum)
+udev config, permissions and rules syntax and ftplugin files. (Nikolai Weibull)
+updatedb syntax and ftplugin file. (Nikolai Weibull)
+VHDL indent file (Gerald Lai)
+WSML syntax file. (Thomas Haselwanter)
+Xdefaults ftplugin file. (Nikolai Weibull)
+XFree86 config ftplugin file. (Nikolai Weibull)
+xinetd syntax, indent and ftplugin file. (Nikolai Weibull)
+xmodmap ftplugin file. (Nikolai Weibull)
+Xquery syntax file. (Jean-Marc Vanel)
+xsd (XML schema) indent file.
+YAML ftplugin file. (Nikolai Weibull)
+Zsh ftplugin file. (Nikolai Weibull)
+
+
+New Keymaps: ~
+
+Sinhala (Sri Lanka) (Harshula Jayasuriya)
+Tamil in TSCII encoding (Yegappan Lakshmanan)
+Greek in cp737 (Panagiotis Louridas)
+Polish-slash (HS6_06)
+Ukrainian-jcuken (Anatoli Sakhnik)
+Kana (Edward L. Fox)
+
+
+New message translations: ~
+
+The Ukranian messages are now also available in cp1251.
+Vietnamese message translations and menu. (Phan Vinh Thinh)
+
+
+Others: ~
+
+The |:read| command has the |++edit| argument.  This means it will use the
+detected 'fileformat', 'fileencoding' and other options for the buffer.  This
+also fixes the problem that editing a compressed file didn't set these
+options.
+
+The Netbeans interface was updated for Sun Studio 10.  The protocol number
+goes from 2.2 to 2.3. (Gordon Prieur)
+
+Mac: When starting up Vim will load the $VIMRUNTIME/macmap.vim script to
+define default command-key mappings. (mostly by Benji Fisher)
+
+Mac: Add the selection type to the clipboard, so that Block, line and
+character selections can be used between two Vims. (Eckehard Berns)
+Also fixes the problem that setting 'clipboard' to "unnamed" breaks using
+"yyp".
+
+Mac: GUI font selector. (Peter Cucka)
+
+Mac: support for multi-byte characters. (Da Woon Jung)
+This doesn't always work properly.  If you see text drawing problems try
+switching the 'macatsui' option off.
+
+Mac: Support the xterm mouse in the non-GUI version.
+
+Mac: better integration with Xcode.  Post a fake mouse-up event after the odoc
+event and the drag receive handler to work around a stall after Vim loads a
+file.  Fixed an off-by-one line number error. (Da Woon Jung)
+
+Mac: When started from Finder change directory to the file being edited or the
+user home directory.
+
+Added the t_SI and t_EI escape sequences for starting and ending Insert mode.
+To be used to set the cursor shape to a bar or a block.  No default values,
+they are not supported by termcap/terminfo.
+
+GUI font selector for Motif. (Marcin Dalecki)
+
+Nicer toolbar buttons for Motif. (Marcin Dalecki)
+
+Mnemonics for the Motif find/replace dialog. (Marcin Dalecki)
+
+Included a few improvements for Motif from Marcin Dalecki.  Draw label
+contents ourselves to make them handle fonts in a way configurable by Vim and
+a bit less dependent on the X11 font management.
+
+Autocommands can be defined local to a buffer.  This means they will also work
+when the buffer does not have a name or no specific name.  See
+|autocmd-buflocal|.  (Yakov Lerner)
+
+For xterm most combinations of modifiers with function keys are recognized.
+|xterm-modifier-keys|
+
+When 'verbose' is set the output of ":highlight" will show where a highlight
+item was last set.
+When 'verbose' is set the output of the ":map", ":abbreviate", ":command",
+":function" and ":autocmd" commands will show where it was last defined.
+(Yegappan Lakshmanan)
+
+":function /pattern" lists functions matching the pattern.
+
+"1gd" can be used like "gd" but ignores matches in a {} block that ends before
+the cursor position.  Likewise for "1gD" and "gD".
+
+'scrolljump' can be set to a negative number to scroll a percentage of the
+window height.
+
+The |v:scrollstart| variable has been added to help finding the location in
+your script that causes the hit-enter prompt.
+
+To make it possible to handle the situation that a file is being edited that
+is already being edited by another Vim instance, the |SwapExists| event has
+been added.  The |v:swapname|, |v:swapchoice| and |v:swapcommand| variables
+can be used, for example to use the |client-server| functionality to bring the
+other Vim to the foreground.
+When starting Vim with a "-t tag" argument, there is an existing swapfile and
+the user selects "quit" or "abort" then exit Vim.
+
+Undo now also restores the '< and '> marks.  "gv" selects the same area as
+before the change and undo.
+
+When editing a search pattern for a "/" or "?" command and 'incsearch' is set
+CTRL-L can be used to add a character from the current match.  CTRL-R CTRL-W
+will add a word, but exclude the part of the word that was already typed.
+
+Ruby interface: add line number methods. (Ryan Paul)
+
+The $MYVIMRC environment variable is set to the first found vimrc file.
+The $MYGVIMRC environment variable is set to the first found gvimrc file.
+
+==============================================================================
+IMPROVEMENTS						*improvements-7*
+
+":helpgrep" accepts a language specifier after the pattern: "pat@it".
+
+Moved the help for printing to a separate help file.  It's quite a lot now.
+
+When doing completion for ":!cmd", ":r !cmd" or ":w !cmd" executable files are
+found in $PATH instead of looking for ordinary files in the current directory.
+
+When ":silent" is used and a backwards range is given for an Ex command the
+range is swapped automatically instead of asking if that is OK.
+
+The pattern matching code was changed from a recursive function to an
+iterative mechanism.  This avoids out-of-stack errors.  State is stored in
+allocated memory, running out of memory can always be detected.  Allows
+matching more complex things, but Vim may seem to hang while doing that.
+
+Previously some options were always evaluated in the |sandbox|.  Now that only
+happens when the option was set from a modeline or in secure mode.  Applies to
+'balloonexpr', 'foldexpr', 'foldtext' and 'includeexpr'. (Sumner Hayes)
+
+Some commands and expressions could have nasty side effects, such as using
+CTRL-R = while editing a search pattern and the expression invokes a function
+that jumps to another window.  The |textlock| has been added to prevent this
+from happening.
+
+":breakadd here" and ":breakdel here" can be used to set or delete a
+breakpoint at the cursor.
+
+It is now possible to define a function with: >
+	:exe "func Test()\n ...\n endfunc"
+
+The tutor was updated to make it simpler to use and text was added to explain
+a few more important commands.  Used ideas from Gabriel Zachmann.
+
+Unix: When libcall() fails obtain an error message with dlerror() and display
+it. (Johannes Zellner)
+
+Mac and Cygwin: When editing an existing file make the file name the same case
+of the edited file.  Thus when typing ":e os_UNIX.c" the file name becomes
+"os_unix.c".
+
+Added "nbsp" in 'listchars'. (David Blanchet)
+
+Added the "acwrite" value for the 'buftype' option.  This is for a buffer that
+does not have a name that refers to a file and is written with BufWriteCmd
+autocommands.
+
+For lisp indenting and matching parenthesis: (Sergey Khorev)
+- square brackets are recognized properly
+- #\(, #\), #\[ and #\] are recognized as character literals
+- Lisp line comments (delimited by semicolon) are recognized
+
+Added the "count" argument to match(), matchend() and matchstr(). (Ilya Sher)
+
+winnr() takes an optional "$" or "#" argument.  (Nikolai Weibull, Yegappan
+Lakshmanan)
+
+Added 's' flag to search(): set ' mark if cursor moved. (Yegappan Lakshmanan)
+Added 'n' flag to search(): don't move the cursor. (Nikolai Weibull)
+Added 'c' flag to search(): accept match at the cursor.
+Added 'e' flag to search(): move to end of the match. (Benji Fisher)
+Added 'p' flag to search(): return number of sub-pattern. (Benji Fisher)
+These also apply to searchpos(), searchpair() and searchpairpos().
+
+The search() and searchpair() functions have an extra argument to specify
+where to stop searching.  Speeds up searches that should not continue too far.
+
+When uncompressing fails in the gzip plugin, give an error message but don't
+delete the raw text.  Helps if the file has a .gz extension but is not
+actually compressed. (Andrew Pimlott)
+
+When C, C++ or IDL syntax is used, may additionally load doxygen syntax.
+(Michael Geddes)
+
+Support setting 'filetype' and 'syntax' to "aaa.bbb" for "aaa" plus "bbb"
+filetype or syntax.
+
+The ":registers" command now displays multi-byte characters properly.
+
+VMS: In the usage message mention that a slash can be used to make a flag
+upper case.  Add color support to the builtin vt320 terminal codes.
+(Zoltan Arpadffy)
+
+For the '%' item in 'viminfo', allow a number to set a maximum for the number
+of buffers.
+
+For recognizing the file type: When a file looks like a shell script, check
+for an "exec" command that starts the tcl interpreter. (suggested by Alexios
+Zavras)
+
+Support conversion between utf-8 and latin9 (iso-8859-15) internally, so that
+digraphs still work when iconv is not available.
+
+When a session file is loaded while editing an unnamed, empty buffer that
+buffer is wiped out.  Avoids that there is an unused buffer in the buffer
+list.
+
+Win32: When libintl.dll supports bind_textdomain_codeset(), use it.
+(NAKADAIRA Yukihiro)
+
+Win32: Vim was not aware of hard links on NTFS file systems.  These are
+detected now for when 'backupcopy' is "auto".  Also fixed a bogus "file has
+been changed since reading it" error for links.
+
+When foldtext() finds no text after removing the comment leader, use the
+second line of the fold.  Helps for C-style /* */ comments where the first
+line is just "/*".
+
+When editing the same file from two systems (e.g., Unix and MS-Windows) there
+mostly was no warning for an existing swap file, because the name of the
+edited file differs (e.g., y:\dir\file vs /home/me/dir/file).  Added a flag to
+the swap file to indicate it is in the same directory as the edited file.  The
+used path then doesn't matter and the check for editing the same file is much
+more reliable.
+
+Unix: When editing a file through a symlink the swap file would use the name
+of the symlink.  Now use the name of the actual file, so that editing the same
+file twice is detected. (suggestions by Stefano Zacchiroli and James Vega)
+
+Client-server communication now supports 'encoding'.  When setting 'encoding'
+in a Vim server to "utf-8", and using "vim --remote fname" in a console,
+"fname" is converted from the console encoding to utf-8.  Also allows Vims
+with different 'encoding' settings to exchange messages.
+
+Internal: Changed ga_room into ga_maxlen, so that it doesn't need to be
+incremented/decremented each time.
+
+When a register is empty it is not stored in the viminfo file.
+
+Removed the tcltags script, it's obsolete.
+
+":redir @*>>" and ":redir @+>>" append to the clipboard.  Better check for
+invalid characters after the register name. |:redir|
+
+":redir => variable" and ":redir =>> variable" write or append to a variable.
+(Yegappan Lakshmanan) |:redir|
+
+":redir @{a-z}>>" appends to register a to z. (Yegappan Lakshmanan)
+
+The 'verbosefile' option can be used to log messages in a file.  Verbose
+messages are not displayed then.  The "-V{filename}" argument can be used to
+log startup messages.
+
+":let g:" lists global variables.
+":let b:" lists buffer-local variables.
+":let w:" lists window-local variables.
+":let v:" lists Vim variables.
+
+The stridx() and strridx() functions take a third argument, where to start
+searching.  (Yegappan Lakshmanan)
+
+The getreg() function takes an extra argument to be able to get the expression
+for the '=' register instead of the result of evaluating it.
+
+The setline() function can take a List argument to set multiple lines.  When
+the line number is just below the last line the line is appended.
+
+g CTRL-G also shows the number of characters if it differs from the number of
+bytes.
+
+Completion for ":debug" and entering an expression for the '=' register.  Skip
+":" between range and command name. (Peter winters)
+
+CTRL-Q in Insert mode now works like CTRL-V by default.  Previously it was
+ignored.
+
+When "beep" is included in 'debug' a function or script that causes a beep
+will result in a message with the source of the error.
+
+When completing buffer names, match with "\(^\|[\/]\)" instead of "^", so that
+":buf stor<Tab>" finds both "include/storage.h" and "storage/main.c".
+
+To count items (pattern matches) without changing the buffer the 'n' flag has
+been added to |:substitute|.  See |count-items|.
+
+In a |:substitute| command the \u, \U, \l and \L items now also work for
+multi-byte characters.
+
+The "screen.linux" $TERM name is recognized to set the default for
+'background' to "dark". (Ciaran McCreesh)  Also for "cygwin" and "putty".
+
+The |FileChangedShell| autocommand event can now use the |v:fcs_reason|
+variable that specifies what triggered the event.  |v:fcs_choice| can be used
+to reload the buffer or ask the user what to do.
+
+Not all modifiers were recognized for xterm function keys.  Added the
+possibility in term codes to end in ";*X" or "O*X", where X is any character
+and the * stands for the modifier code.
+Added the <xUp>, <xDown>, <xLeft> and <xRight> keys, to be able to recognize
+the two forms that xterm can send their codes in and still handle all possible
+modifiers.
+
+getwinvar() now also works to obtain a buffer-local option from the specified
+window.
+
+Added the "%s" item to 'errorformat'. (Yegappan Lakshmanan)
+Added the "%>" item to 'errorformat'.
+
+For 'errorformat' it was not possible to have a file name that contains the
+character that follows after "%f".  For example, in "%f:%l:%m" the file name
+could not contain ":".  Now include the first ":" where the rest of the
+pattern matches.  In the example a ":" not followed by a line number is
+included in the file name. (suggested by Emanuele Giaquinta)
+
+GTK GUI: use the GTK file dialog when it's available.  Mix from patches by
+Grahame Bowland and Evan Webb.
+
+Added ":scriptnames" to bugreport.vim, so that we can see what plugins were
+used.
+
+Win32: If the user changes the setting for the number of lines a scroll wheel
+click scrolls it is now used immediately.  Previously Vim would need to be
+restarted.
+
+When using @= in an expression the value is expression @= contains.  ":let @=
+= value" can be used to set the register contents.
+
+A ! can be added to ":popup" to have the popup menu appear at the mouse
+pointer position instead of the text cursor.
+
+The table with encodings has been expanded with many MS-Windows codepages,
+such as cp1250 and cp737, so that these can also be used on Unix without
+prepending "8bit-".
+When an encoding name starts with "microsoft-cp" ignore the "microsoft-" part.
+
+Added the "customlist" completion argument to a user-defined command.  The
+user-defined completion function should return the completion candidates as a
+Vim List and the returned results are not filtered by Vim. (Yegappan
+Lakshmanan)
+
+Win32: Balloons can have multiple lines if common controls supports it.
+(Sergey Khorev)
+
+For command-line completion the matches for various types of arguments are now
+sorted: user commands, variables, syntax names, etc.
+
+When no locale is set, thus using the "C" locale, Vim will work with latin1
+characters, using its own isupper()/toupper()/etc. functions.
+
+When using an rxvt terminal emulator guess the value of 'background' using the
+COLORFGBG environment variable. (Ciaran McCreesh)
+
+Also support t_SI and t_EI on Unix with normal features. (Ciaran McCreesh)
+
+When 'foldcolumn' is one then put as much info in it as possible.  This allows
+closing a fold with the mouse by clicking on the '-'.
+
+input() takes an optional completion argument to specify the type of
+completion supported for the input. (Yegappan Lakshmanan)
+
+"dp" works with more than two buffers in diff mode if there is only one where
+'modifiable' is set.
+
+The 'diffopt' option has three new values: "horizontal", "vertical" and
+"foldcolumn".
+
+When the 'include' option contains \zs the file name found is what is being
+matched from \zs to the end or \ze.  Useful to pass more to 'includeexpr'.
+
+Loading plugins on startup now supports subdirectories in the plugin
+directory. |load-plugins|
+
+In the foldcolumn always show the '+' for a closed fold, so that it can be
+opened easily.  It may overwrite another character, esp. if 'foldcolumn' is 1.
+
+It is now possible to get the W10 message again by setting 'readonly'.  Useful
+in the FileChangedRO autocommand when checking out the file fails.
+
+Unix: When open() returns EFBIG give an appropriate message.
+
+":mksession" sets the SessionLoad variable to notify plugins.  A modeline is
+added to the session file to set 'filetype' to "vim".
+
+In the ATTENTION prompt put the "Delete it" choice before "Quit" to make it
+more logical.  (Robert Webb)
+
+When appending to a file while the buffer has no name the name of the appended
+file would be used for the current buffer.  But the buffer contents is
+actually different from the file content.  Don't set the file name, unless the
+'P' flag is present in 'cpoptions'.
+
+When starting to edit a new file and the directory for the file doesn't exist
+then Vim will report "[New DIRECTORY]" instead of "[New File] to give the user
+a hint that something might be wrong.
+
+Win32: Preserve the hidden attribute of the viminfo file.
+
+In Insert mode CTRL-A didn't keep the last inserted text when using CTRL-O and
+then a cursor key.  Now keep the previously inserted text if nothing is
+inserted after the CTRL-O.  Allows using CTRL-O commands to move the cursor
+without losing the last inserted text.
+
+The exists() function now supports checking for autocmd group definition
+and for supported autocommand events. (Yegappan Lakshmanan)
+
+Allow using ":global" in the sandbox, it doesn't do anything harmful by
+itself.
+
+":saveas asdf.c" will set 'filetype' to c when it's empty.  Also for ":w
+asdf.c" when it sets the filename for the buffer.
+
+Insert mode completion for whole lines now also searches unloaded buffers.
+
+The colortest.vim script can now be invoked directly with ":source" or
+":runtime syntax/colortest.vim".
+
+The 'statusline' option can be local to the window, so that each window can
+have a different value.  (partly by Yegappan Lakshmanan)
+
+The 'statusline' option and other options that support the same format can now
+use these new features:
+- When it starts with "%!" the value is first evaluated as an expression
+  before parsing the value.
+- "%#HLname#" can be used to start highlighting with HLname.
+
+When 'statusline' is set to something that causes an error message then it is
+made empty to avoid an endless redraw loop.  Also for other options, such at
+'tabline' and 'titlestring'.  ":verbose set statusline" will mention that it
+was set in an error handler.
+
+When there are several matching tags, the ":tag <name>" and CTRL-] commands
+jump to the [count] matching tag. (Yegappan Lakshmanan)
+
+Win32: In the batch files generated by the install program, use $VIMRUNTIME or
+$VIM if it's set.  Example provided by Mathias Michaelis.
+Also create a vimtutor.bat batch file.
+
+The 'balloonexpr' option is now |global-local|.
+
+The system() function now runs in cooked mode, thus can be interrupted by
+CTRL-C.
+
+==============================================================================
+COMPILE TIME CHANGES					*compile-changes-7*
+
+Dropped the support for the BeOS and Amiga GUI.  They were not maintained and
+probably didn't work.  If you want to work on this: get the Vim 6.x version
+and merge it back in.
+
+When running the tests and one of them fails to produce "test.out" the
+following tests are still executed.  This helps when running out of memory.
+
+When compiling with EXITFREE defined and the ccmalloc library it is possible
+to detect memory leaks.  Some memory will always reported as leaked, such as
+allocated by X11 library functions and the memory allocated in alloc_cmdbuff()
+to store the ":quit" command.
+
+Moved the code for printing to src/hardcopy.c.
+
+Moved some code from main() to separate functions to make it easier to see
+what is being done.  Using a structure to avoid a lot of arguments to the
+functions.
+
+Moved unix_expandpath() to misc1.c, so that it can also be used by os_mac.c
+without copying the code.
+
+--- Mac ---
+
+"make" now creates the Vim.app directory and "make install" copies it to its
+final destination. (Raf)
+
+Put the runtime directory not directly in Vim.app but in
+Vim.app/Contents/Resources/vim, so that it's according to Mac specs.
+
+Made it possible to compile with Motif, Athena or GTK without tricks and still
+being able to use the MacRoman conversion.  Added the os_mac_conv.c file.
+
+When running "make install" the runtime files are installed as for Unix.
+Avoids that too many files are copied.  When running "make" a link to the
+runtime files is created to avoid a recursive copy that takes much time.
+
+Configure will attempt to build Vim for both Intel and PowerPC.  The
+--with-mac-arch configure argument can change it.
+
+--- Win32 ---
+
+The Make_mvc.mak file was adjusted to work with the latest MS compilers,
+including the free version of Visual Studio 2005. (George Reilly)
+
+INSTALLpc.txt was updated for the recent changes. (George Reilly)
+
+The distributed executable is now produced with the free Visual C++ Toolkit
+2003 and other free SDK chunks.  msvcsetup.bat was added to support this.
+
+Also generate the .pdb file that can be used to generate a useful crash report
+on MS-Windows. (George Reilly)
+
+==============================================================================
+BUG FIXES						*bug-fixes-7*
+
+When using PostScript printing on MS-DOS the default 'printexpr' used "lpr"
+instead of "copy".  When 'printdevice' was empty the copy command did not
+work.  Use "LPT1" then.
+
+The GTK font dialog uses a font size zero when the font name doesn't include a
+size.  Use a default size of 10.
+
+This example in the documentation didn't work:
+    :e `=foo . ".c" `
+Skip over the expression in `=expr` when looking for comments, |, % and #.
+
+When ":helpgrep" doesn't find anything there is no error message.
+
+"L" and "H" did not take closed folds into account.
+
+Win32: The "-P title" argument stopped at the first title that matched, even
+when it doesn't support MDI.
+
+Mac GUI: CTRL-^ and CTRL-@ did not work.
+
+"2daw" on "word." at the end of a line didn't include the preceding white
+space.
+
+Win32: Using FindExecutable() doesn't work to find a program.  Use
+SearchPath() instead.  For executable() use $PATHEXT when the program searched
+for doesn't have an extension.
+
+When 'virtualedit' is set, moving the cursor up after appending a character
+may move it to a different column.  Was caused by auto-formatting moving the
+cursor and not putting it back where it was.
+
+When indent was added automatically and then moving the cursor, the indent was
+not deleted (like when pressing ESC).  The "I" flag in 'cpoptions' can be used
+to make it work the old way.
+
+When opening a command-line window, 'textwidth' gets set to 78 by the Vim
+filetype plugin.  Reset 'textwidth' to 0 to avoid lines are broken.
+
+After using cursor(line, col) moving up/down doesn't keep the same column.
+
+Win32: Borland C before 5.5 requires using ".u." for LowPart and HighPart
+fields. (Walter Briscoe)
+
+On Sinix SYS_NMLN isn't always defined.  Define it ourselves. (Cristiano De
+Michele)
+
+Printing with PostScript may keep the printer waiting for more.  Append a
+CTRL-D to the printer output. (Mike Williams)
+
+When converting a string with a hex or octal number the leading '-' was
+ignored.  ":echo '-05' + 0" resulted in 5 instead of -5.
+
+Using "@:" to repeat a command line didn't work when it contains control
+characters.  Also remove "'<,'>" when in Visual mode to avoid that it appears
+twice.
+
+When using file completion for a user command, it would not expand environment
+variables like for a regular command with a file argument.
+
+'cindent': When the argument of a #define looks like a C++ class the next line
+is indented too much.
+
+When 'comments' includes multi-byte characters inserting the middle part and
+alignment may go wrong.  'cindent' also suffers from this for right-aligned
+items.
+
+Win32: when 'encoding' is set to "utf-8" getenv() still returns strings in the
+active codepage.  Convert to utf-8.  Also for $HOME.
+
+The default for 'helplang' was "zh" for both "zh_cn" and "zh_tw".  Now use
+"cn" or "tw" as intended.
+
+When 'bin' is set and 'eol' is not set then line2byte() added the line break
+after the last line while it's not there.
+
+Using foldlevel() in a WinEnter autocommand may not work.  Noticed when
+resizing the GUI shell upon startup.
+
+Python: Using buffer.append(f.readlines()) didn't work.  Allow appending a
+string with a trailing newline.  The newline is ignored.
+
+When using the ":saveas f2" command for buffer "f1", the Buffers menu would
+contain "f2" twice, one of them leading to "f1".  Also trigger the BufFilePre
+and BufFilePost events for the alternate buffer that gets the old name.
+
+strridx() did not work well when the needle is empty. (Ciaran McCreesh)
+
+GTK: Avoid a potential hang in gui_mch_wait_for_chars() when input arrives
+just before it is invoked
+
+VMS: Occasionally CR characters were inserted in the file.  Expansion of
+environment variables was not correct. (Zoltan Arpadffy)
+
+UTF-8: When 'delcombine' is set "dw" only deleted the last combining character
+from the first character of the word.
+
+When using ":sball" in an autocommand only the filetype in one buffer was
+detected.  Reset did_filetype in enter_buffer().
+
+When using ":argdo" and the window already was at the first argument index,
+but not actually editing it, the current buffer would be used instead.
+
+When ":next dir/*" includes many matches, adding the names to the argument
+list may take an awful lot of time and can't be interrupted.  Allow
+interrupting this.
+
+When editing a file that was already loaded in a buffer, modelines were not
+used.  Now window-local options in the modeline are set.  Buffer-local options
+and global options remain unmodified.
+
+Win32: When 'encoding' is set to "utf-8" in the vimrc file, files from the
+command line with non-ASCII characters are not used correctly.  Recode the
+file names when 'encoding' is set, using the Unicode command line.
+
+Win32 console: When the default for 'encoding' ends up to be "latin1", the
+default value of 'isprint' was wrong.
+
+When an error message is given while waiting for a character (e.g., when an
+xterm reports the number of colors), the hit-enter prompt overwrote the last
+line.  Don't reset msg_didout in normal_cmd() for K_IGNORE.
+
+Mac GUI: Shift-Tab didn't work.
+
+When defining tooltip text, don't translate terminal codes, since it's not
+going to be used like a command.
+
+GTK 2: Check the tooltip text for valid utf-8 characters to avoid getting a
+GTK error.  Invalid characters may appear when 'encoding' is changed.
+
+GTK 2: Add a safety check for invalid utf-8 sequences, they can crash pango.
+
+Win32: When 'encoding' is changed while starting up, use the Unicode command
+line to convert the file arguments to 'encoding'.  Both for the GUI and the
+console version.
+
+Win32 GUI: latin9 text (iso-8859-15) was not displayed correctly, because
+there is no codepage for latin9.  Do our own conversion from latin9 to UCS2.
+
+When two versions of GTK+ 2 are installed it was possible to use the header
+files from one and the library from the other.  Use GTK_LIBDIR to put the
+directory for the library early in the link flags.
+
+With the GUI find/replace dialog a replace only worked if the pattern was
+literal text.  Now it works for any pattern.
+
+When 'equalalways' is set and 'eadirection' is "hor", ":quit" would still
+cause equalizing window heights in the vertical direction.
+
+When ":emenu" is used in a startup script the command was put in the typeahead
+buffer, causing a prompt for the crypt key to be messed up.
+
+Mac OS/X: The default for 'isprint' included characters 128-160, causes
+problems for Terminal.app.
+
+When a syntax item with "containedin" is used, it may match in the start or
+end of a region with a matchgroup, while this doesn't happen for a "contains"
+argument.
+
+When a transparent syntax items matches in another item where the highlighting
+has already stopped (because of a he= argument), the highlighting would come
+back.
+
+When cscope is used to set the quickfix error list, it didn't get set if there
+was only one match. (Sergey Khorev)
+
+When 'confirm' is set and using ":bdel" in a modified buffer, then selecting
+"cancel", would still give an error message.
+
+The PopUp menu items that started Visual mode didn't work when not in Normal
+mode.  Switching between selecting a word and a line was not possible.
+
+Win32: The keypad decimal point always resulted in a '.', while on some
+keyboards it's a ','.  Use MapVirtualKey(VK_DECIMAL, 2).
+
+Removed unused function DisplayCompStringOpaque() from gui_w32.c
+
+In Visual mode there is not always an indication whether the line break is
+selected or not.  Highlight the character after the line when the line break
+is included, e.g., after "v$o".
+
+GTK: The <F10> key can't be mapped, it selects the menu.  Disable that with a
+GTK setting and do select the menu when <F10> isn't mapped. (David Necas)
+
+After "Y" '[ and '] were not at start/end of the yanked text.
+
+When a telnet connection is dropped Vim preserves files and exits.  While
+doing that a SIGHUP may arrive and disturb us, thus ignore it. (Scott
+Anderson)  Also postpone SIGHUP, SIGQUIT and SIGTERM until it's safe to
+handle.  Added handle_signal().
+
+When completing a file name on the command line backslashes are required for
+white space.  Was only done for a space, not for a Tab.
+
+When configure could not find a terminal library, compiling continued for a
+long time before reporting the problem.  Added a configure check for tgetent()
+being found in a library.
+
+When the cursor is on the first char of the last line a ":g/pat/s///" command
+may cause the cursor to be displayed below the text.
+
+Win32: Editing a file with non-ASCII characters doesn't work when 'encoding'
+is "utf-8".  use _wfullpath() instead of _fullpath(). (Yu-sung Moon)
+
+When recovering the 'fileformat' and 'fileencoding' were taken from the
+original file instead of from the swapfile.  When the file didn't exist, was
+empty or the option was changed (e.g., with ":e ++fenc=cp123 file") it could
+be wrong.  Now store 'fileformat' and 'fileencoding' in the swapfile and use
+the values when recovering.
+
+":bufdo g/something/p" overwrites each last printed text line with the file
+message for the next buffer.  Temporarily clear 'shortmess' to avoid that.
+
+Win32: Cannot edit a file starting with # with --remote.  Do escape % and #
+when building the ":drop" command.
+
+A comment or | just after a expression-backtick argument was not recognized.
+E.g. in :e `="foo"`"comment.
+
+"(" does not stop at an empty sentence (single dot and white space) while ")"
+does.  Also breaks "das" on that dot.
+
+When doing "yy" with the cursor on a TAB the ruler could be wrong and "k"
+moved the cursor to another column.
+
+When 'commentstring' is '"%s' and there is a double quote in the line a double
+quote before the fold marker isn't removed in the text displayed for a  closed
+fold.
+
+In Visual mode, when 'bin' and 'eol' set, g CTRL-G counted the last line
+break, resulting in "selected 202 of 201 bytes".
+
+Motif: fonts were not used for dialog components. (Marcin Dalecki)
+
+Motif: After using a toolbar button the keyboard focus would be on the toolbar
+(Lesstif problem). (Marcin Dalecki)
+
+When using "y<C-V>`x" where mark x is in the first column, the last line was
+not included.
+
+Not all test scripts work properly on MS-Windows when checked out from CVS.
+Use a Vim command to fix all fileformats to dos before executing the tests.
+
+When using ":new" and the file fits in the window, lines could still be above
+the window.  Now remove empty lines instead of keeping the relative position.
+
+Cmdline completion didn't work after ":let var1 var<Tab>".
+
+When using ":startinsert" or ":startreplace" when already in Insert mode
+(possible when using CTRL-R =), pressing Esc would directly restart Insert
+mode. (Peter Winters)
+
+"2daw" didn't work at end of file if the last word is a single character.
+
+Completion for ":next a'<Tab>" put a backslash before single quote, but it was
+not removed when editing a file.  Now halve backslashes in save_patterns().
+Also fix expanding a file name with the shell that contains "\'".
+
+When doing "1,6d|put" only "fewer lines" was reported.  Now a following "more
+lines" overwrites the message.
+
+Configure could not handle "-Dfoo=long\ long" in the TCL config output.
+
+When searching backwards, using a pattern that matches a newline and uses \zs
+after that, didn't find a match.  Could also get a hang or end up in the right
+column in the wrong line.
+
+When $LANG is "sl" for slovenian, the slovak menu was used, since "slovak"
+starts with "sl".
+
+When 'paste' is set in the GUI the Paste toolbar button doesn't work.  Clear
+'paste' when starting the GUI.
+
+A message about a wrong viminfo line included the trailing NL.
+
+When 'paste' is set in the GUI the toolbar button doesn't work in Insert mode.
+Use ":exe" in menu.vim to avoid duplicating the commands, instead of using a
+mapping.
+
+Treat "mlterm" as an xterm-like terminal. (Seiichi Sato)
+
+":z.4" and ":z=4" didn't work Vi compatible.
+
+When sourcing a file, editing it and sourcing it again, it could appear twice
+in ":scriptnames" and get a new <SID>, because the inode has changed.
+
+When $SHELL is set but empty the 'shell' option would be empty.  Don't use an
+empty $SHELL value.
+
+A command "w! file" in .vimrc or $EXINIT didn't work.  Now it writes an empty
+file.
+
+When a CTRL-F command at the end of the file failed, the cursor was still
+moved to the start of the line.  Now it remains where it is.
+
+When using ":s" or "&" to repeat the last substitute and "$" was used to put
+the cursor in the last column, put the cursor in the last column again.  This
+is Vi compatible.
+
+Vim is not fully POSIX compliant but sticks with traditional Vi behavior.
+Added a few flags in 'cpoptions' to behave the POSIX way when wanted.  The
+$VIM_POSIX environment variable is checked to set the default.
+
+Appending to a register didn't insert a line break like Vi.  Added the '>'
+flag to 'cpoptions' for this.
+
+Using "I" in a line with only blanks appended to the line.  This is not Vi
+compatible.  Added the 'H' flag in 'coptions' for this.
+
+When joining multiple lines the cursor would be at the last joint, but Vi
+leaves it at the position where "J" would put it.  Added the 'q' flag in
+'cpoptions' for this.
+
+Autoindent didn't work for ":insert" and ":append".
+
+Using ":append" in an empty buffer kept the dummy line.  Now it's deleted to
+be Vi compatible.
+
+When reading commands from a file and stdout goes to a terminal, would still
+request the xterm version.  Vim can't read it, thus the output went to the
+shell and caused trouble there.
+
+When redirecting to a register with an invalid name the redirection would
+still be done (after an error message).  Now reset "redir_reg". (Yegappan
+Lakshmanan)
+
+It was not possible to use a NL after a backslash in Ex mode.  This is
+sometimes used to feed multiple lines to a shell command.
+
+When 'cmdheight' is set to 2 in .vimrc and the GUI uses the number of lines
+from the terminal we actually get 3 lines for the cmdline in gvim.
+
+When setting $HOME allocated memory would leak.
+
+Win32: bold characters may sometimes write in another character cell.  Use
+unicodepdy[] as for UTF-8. (Taro Muraoka)
+
+":w fname" didn't work for files with 'buftype' set to "nofile".
+
+The method used to locate user commands for completion differed from when they
+are executed.  Ambiguous command names were not completed properly.
+
+Incremental search may cause a crash when there is a custom statusline that
+indirectly invokes ":normal".
+
+Diff mode failed when $DIFF_OPTIONS was set in the environment.  Unset it
+before invoking "diff".
+
+Completion didn't work after ":argdo", ":windo" and ":bufdo".  Also for ":set
+&l:opt" and ":set &g:opt". (Peter Winters)
+
+When setting 'ttymouse' to "dec" in an xterm that supports the DEC mouse
+locator it doesn't work.  Now switch off the mouse before selecting another
+mouse model.
+
+When the CursorHold event is triggered and the commands peek for typed
+characters the typeahead buffer may be messed up, e.g., when a mouse-up event
+is received.  Avoid invoking the autocommands from the function waiting for a
+character, let it put K_CURSORHOLD in the input buffer.
+
+Removed the "COUNT" flag from ":argadd", to avoid ":argadd 1*" to be used like
+":1argadd *".  Same for ":argdelete" and ":argedit".
+
+Avoid that $LANG is used for the menus when LC_MESSAGES is "en_US".
+
+Added backslashes before dashes in the vim.1 manual page to make the appear as
+real dashes. (Pierr Habouzit)
+
+Where "gq" left the cursor depended on the value of 'formatprg'.  Now "gq"
+always leaves the cursor at the last line of the formatted text.
+
+When editing a compressed file, such as "changelog.Debian.gz" file, filetype
+detection may try to check the contents of the file while it's still
+compressed.  Skip setting 'filetype' for compressed files until they have been
+decompressed.  Required for patterns that end in a "*".
+
+Starting with an argument "+cmd" or "-S script" causes the cursor the be moved
+to the first line.  That breaks a BufReadPost autocommand that uses g`".
+Don't move the cursor if it's somewhere past the first line.
+
+"gg=G" while 'modifiable' is off was uninterruptible.
+
+When 'encoding' is "sjis" inserting CTRL-V u d800 a few times causes a crash.
+Don't insert a DBCS character with a NUL second byte.
+
+In Insert mode CTRL-O <Home> didn't move the cursor.  Made "ins_at_eol" global
+and reset it in nv_home().
+
+Wildcard expansion failed: ":w /tmp/$$.`echo test`".  Don't put quotes around
+spaces inside backticks.
+
+After this sequence of commands: Y V p gv: the wrong line is selected.  Now
+let "gv" select the text that was put, since the original text is deleted.
+This should be the most useful thing to do.
+
+":sleep 100u" sleeps for 100 seconds, not 100 usec as one might expect.  Give
+an error message when the argument isn't recognized.
+
+In gui_mch_draw_string() in gui_w32.c "unibuflen" wasn't static, resulting in
+reallocating the buffer every time. (Alexei Alexandrov)
+
+When using a Python "atexit" function it was not invoked when Vim exits.  Now
+call Py_Finalize() for that. (Ugo Di Girolamo)
+This breaks the thread stuff though, fixed by Ugo.
+
+GTK GUI: using a .vimrc with "set cmdheight=2 lines=43" and ":split" right
+after startup, the window layout is messed up. (Michael Schaap)  Added
+win_new_shellsize() call in gui_init() to fix the topframe size.
+
+Trick to get ...MOUSE_NM not used when there are vertical splits.  Now pass
+column -1 for the left most window and add MOUSE_COLOFF for others.  Limits
+mouse column to 10000.
+
+searchpair() may hang when the end pattern has "\zs" at the end.  Check that
+we find the same position again and advance one character.
+
+When in diff mode and making a change that causes the "changed" highlighting
+to disappear or reappear, it was still highlighted in another window.
+
+When a ":next" command fails because the user selects "Abort" at the ATTENTION
+prompt the argument index was advanced anyway.
+
+When "~" is in 'iskeyword' the "gd" doesn't work, it's used for the previous
+substitute pattern.  Put "\V" in the pattern to avoid that.
+
+Use of sprintf() sometimes didn't check properly for buffer overflow.  Also
+when using smsg().  Included code for snprintf() to avoid having to do size
+checks where invoking them
+
+":help \=<Tab>" didn't find "sub-replace-\=".  Wild menu for help tags didn't
+show backslashes.  ":he :s\=" didn't work.
+
+When reading an errorfile "~/" in a file name was not expanded.
+
+GTK GUI: When adding a scrollbar (e.g. when using ":vsplit") in a script or
+removing it the window size may change.  GTK sends us resize events when we
+change the window size ourselves, but they may come at an unexpected moment.
+Peek for a character to get any window resize events and fix 'columns' and
+'lines' to undo this.
+
+When using the GTK plug mechanism, resizing and focus was not working
+properly. (Neil Bird)
+
+After deleting files from the argument list a session file generated with
+":mksession" may contain invalid ":next" commands.
+
+When 'shortmess' is empty and 'keymap' set to accents, in Insert mode CTRL-N
+may cause the hit-enter prompt.  Typing 'a then didn't result in the accented
+character.  Put the character typed at the prompt back in the typeahead buffer
+so that mapping is done in the right mode.
+
+setbufvar() and setwinvar() did not give error messages.
+
+It was possible to set a variable with an illegal name, e.g. with setbufvar().
+It was possible to define a function with illegal name, e.t. ":func F{-1}()"
+
+CTRL-W F and "gf" didn't use the same method to get the file name.
+
+When reporting a conversion error the line number of the last error could be
+given.  Now report the first encountered error.
+
+When using ":e ++enc=name file" and iconv() was used for conversion an error
+caused a fall-back to no conversion.  Now replace a character with '?' and
+continue.
+
+When opening a new buffer the local value of 'bomb' was not initialized from
+the global value.
+
+Win32: When using the "Edit with Vim" entry the file name was limited to about
+200 characters.
+
+When using command line completion for ":e *foo" and the file "+foo" exists
+the resulting command ":e +foo" doesn't work.  Now insert a backslash: ":e
+\+foo".
+
+When the translation of "-- More --" was not 10 characters long the following
+message would be in the wrong position.
+
+At the more-prompt the last character in the last line wasn't drawn.
+
+When deleting non-existing text while 'virtualedit' is set the '[ and '] marks
+were not set.
+
+Win32: Could not use "**/" in 'path', it had to be "**\".
+
+The search pattern "\n" did not match at the end of the last line.
+
+Searching for a pattern backwards, starting on the NUL at the end of the line
+and 'encoding' is "utf-8" would match the pattern just before it incorrectly.
+Affected searchpair('/\*', '', '\*/').
+
+For the Find/Replace dialog it was possible that not finding the text resulted
+in an error message while redrawing, which cleared the syntax highlighting
+while it was being used, resulting in a crash.  Now don't clear syntax
+highlighting, disable it with b_syn_error.
+
+Win32: Combining UTF-8 characters were drawn on the previous character.
+Could be noticed with a Thai font.
+
+Output of ":function" could leave some of the typed text behind. (Yegappan
+Lakshmanan)
+
+When the command line history has only a few lines the command line window
+would be opened with these lines above the first window line.
+
+When using a command line window for search strings ":qa" would result in
+searching for "qa" instead of quitting all windows.
+
+GUI: When scrolling with the scrollbar and there is a line that doesn't fit
+redrawing may fail.  Make sure w_skipcol is valid before redrawing.
+
+Limit the values of 'columns' and 'lines' to avoid an overflow in Rows *
+Columns.  Fixed bad effects when running out of memory (command line would be
+reversed, ":qa!" resulted in ":!aq").
+
+Motif: "gvim -iconic" opened the window anyway.  (David Harrison)
+
+There is a tiny chance that a symlink gets created between checking for an
+existing file and creating a file.  Use the O_NOFOLLOW for open() if it's
+available.
+
+In an empty line "ix<CTRL-O>0" moved the cursor to after the line instead of
+sticking to the first column.
+
+When using ":wq" and a BufWriteCmd autocmd uses inputsecret() the text was
+echoed anyway.  Set terminal to raw mode in getcmdline().
+
+Unix: ":w a;b~c" caused an error in expanding wildcards.
+
+When appending to a file with ":w >>fname" in a buffer without a name, causing
+the buffer to use "fname", the modified flag was reset.
+
+When appending to the current file the "not edited" flag would be reset.
+":w" would overwrite the file accidentally.
+
+Unix: When filtering text with an external command Vim would still read input,
+causing text typed for the command (e.g., a password) to be eaten and echoed.
+Don't read input when the terminal is in cooked mode.
+
+The Cygwin version of xxd used CR/LF line separators. (Corinna Vinschen)
+
+Unix: When filtering text through a shell command some resulting text may be
+dropped.  Now after detecting that the child has exited try reading some more
+of its output.
+
+When inside input(), using "CTRL-R =" and the expression throws an exception
+the command line was not abandoned but it wasn't used either.  Now abandon
+typing the command line.
+
+'delcombine' was also used in Visual and Select mode and for commands like
+"cl".  That was illogical and has been disabled.
+
+When recording while a CursorHold autocommand was defined special keys would
+appear in the register.  Now the CursorHold event is not triggered while
+recording.
+
+Unix: the src/configure script used ${srcdir-.}, not all shells understand
+that.  Use ${srcdir:-.} instead.
+
+When editing file "a" which is a symlink to file "b" that doesn't exist,
+writing file "a" to create "b" and then ":split b" resulted in two buffers on
+the same file with two different swapfile names.  Now set the inode in the
+buffer when creating a new file.
+
+When 'esckeys' is not set don't send the xterm code to request the version
+string, because it may cause trouble in Insert mode.
+
+When evaluating an expression for CTRL-R = on the command line it was possible
+to call a function that opens a new window, resulting in errors for
+incremental search, and many other nasty things were possible.  Now use the
+|textlock| to disallow changing the buffer or jumping to another window
+to protect from unexpected behavior.  Same for CTRL-\ e.
+
+"d(" deleted the character under the cursor, while the documentation specified
+an exclusive motion.  Vi also doesn't delete the character under the cursor.
+
+Shift-Insert in Insert mode could put the cursor before the last character
+when it just fits in the window.  In coladvance() don't stop at the window
+edge when filling with spaces and when in Insert mode.  In mswin.vim avoid
+getting a beep from the "l" command.
+
+Win32 GUI: When Alt-F4 is used to close the window and Cancel is selected in
+the dialog then Vim would insert <M-F4> in the text.  Now it's ignored.
+
+When ":silent! {cmd}" caused the swap file dialog, which isn't displayed,
+there would still be a hit-enter prompt.
+
+Requesting the termresponse (|t_RV|) early may cause problems with "-c"
+arguments that invoke an external command or even "-c quit".  Postpone it
+until after executing "-c" arguments.
+
+When typing in Insert mode so that a new line is started, using CTRL-G u to
+break undo and start a new change, then joining the lines with <BS> caused
+undo info to be missing.  Now reset the insertion start point.
+
+Syntax HL: When a region start match has a matchgroup and an offset that
+happens to be after the end of the line then it continued in the next line and
+stopped at the region end match, making the region continue after that.
+Now check for the column being past the end of the line in syn_add_end_off().
+
+When changing a file, setting 'swapfile' off and then on again, making another
+change and killing Vim, then some blocks may be missing from the swapfile.
+When 'swapfile' is switched back on mark all blocks in the swapfile as dirty.
+Added mf_set_dirty().
+
+Expanding wildcards in a command like ":e aap;<>!" didn't work.  Put
+backslashes before characters that are special to the shell. (Adri Verhoef)
+
+A CursorHold autocommand would cause a message to be cleared.  Don't show the
+special key for the event for 'showcmd'.
+
+When expanding a file name for a shell command, as in "!cmd foo<Tab>" or ":r
+!cmd foo<Tab>" also escape characters that are special for the shell:
+"!;&()<>".
+
+When the name of the buffer was set by a ":r fname" command |cpo-f| no
+autocommands were triggered to notify about the change in the buffer list.
+
+In the quickfix buffer 'bufhidden' was set to "delete", which caused closing
+the quickfix window to leave an unlisted "No Name" buffer behind every time.
+
+Win32: when using two screens of different size, setting 'lines' to a large
+value didn't fill the whole screen. (SungHyun Nam)
+
+Win32 installer: The generated _vimrc contained an absolute path to diff.exe.
+After upgrading it becomes invalid.  Now use $VIMRUNTIME instead.
+
+The command line was cleared to often when 'showmode' was set and ":silent
+normal vy" was used.  Don't clear the command line unless the mode was
+actually displayed.  Added the "mode_displayed" variable.
+
+The "load session" toolbar item could not handle a space or other special
+characters in v:this_session.
+
+":set sta ts=8 sw=4 sts=2" deleted 4 spaces halfway a line instead of 2.
+
+In a multi-byte file the foldmarker could be recognized in the trail byte.
+(Taro Muraoka)
+
+Pasting with CTRL-V and menu didn't work properly when some commands are
+mapped.  Use ":normal!" instead of ":normal". (Tony Apuzzo)
+
+Crashed when expanding a file name argument in backticks.
+
+In some situations the menu and scrollbar didn't work, when the value contains
+a CSI byte. (Yukihiro Nakadaira)
+
+GTK GUI: When drawing the balloon focus changes and we might get a key release
+event that removed the balloon again.  Ignore the key release event.
+
+'titleold' was included in ":mkexrc" and ":mksession" files.
+
+":set background&" didn't use the same logic as was used when starting up.
+
+When "umask" is set such that nothing is writable then the viminfo file would
+be written without write permission. (Julian Bridle)
+
+Motif: In diff mode dragging one scrollbar didn't update the scrollbar of the
+other diff'ed window.
+
+When editing in an xterm with a different number of colors than expected the
+screen would be cleared and redrawn, causing the message about the edited file
+to be cleared.  Now set "keep_msg" to redraw the last message.
+
+For a color terminal: When the Normal HL uses bold, possibly to make the color
+lighter, and another HL group specifies a color it might become light as well.
+Now reset bold if a HL group doesn't specify bold itself.
+
+When using 256 color xterm the color 255 would show up as color 0.  Use a
+short instead of a char to store the color number.
+
+ml_get errors when searching for "\n\zs" in an empty file.
+
+When selecting a block and using "$" to select until the end of every line and
+not highlighting the character under the cursor the first character of the
+block could be unhighlighted.
+
+When counting words for the Visual block area and using "$" to select until
+the end of every line only up to the length of the last line was counted.
+
+"dip" in trailing empty lines left one empty line behind.
+
+The script ID was only remembered globally for each option. When a buffer- or
+window-local option was set the same "last set" location was changed for all
+buffers and windows.  Now remember the script ID for each local option
+separately.
+
+GUI: The "Replace All" button didn't handle backslashes in the replacement in
+the same way as "Replace".  Escape backslashes so that they are taken
+literally.
+
+When using Select mode from Insert mode and typing a key, causing lines to be
+deleted and a message displayed, delayed the effect of inserting the key.
+Now overwrite the message without delay.
+
+When 'whichwrap' includes "l" then "dl" and "yl" on a single letter line
+worked differently.  Now recognize all operators when using "l" at the end of
+a line.
+
+GTK GUI: when the font selector returned a font name with a comma in it then
+it would be handled like two font names.  Now put a backslash before the
+comma.
+
+MS-DOS, Win32: When 'encoding' defaults to "latin1" then the value for
+'iskeyword' was still for CPxxx.  And when 'nocompatible' was set 'isprint'
+would also be the wrong value.
+
+When a command was defined not to take arguments and no '|' no warning message
+would be given for using a '|'.  Also with ":loadkeymap".
+
+Motif: When using a fontset and 'encoding' is "utf-8" and sizeof(wchar_t) !=
+sizeof(XChar2b) then display was wrong. (Yukihiro Nakadaira)
+
+":all" always set the current window to the first window, even when it
+contains a buffer that is not in the argument list (can't be closed because it
+is modified).  Now go to the window that has the first item of the argument
+list.
+
+GUI: To avoid left-over pixels from bold text all characters after a character
+with special attributes were redrawn.  Now only do this for characters that
+actually are bold.  Speeds up displaying considerably.
+
+When only highlighting changes and the text is scrolled at the same time
+everything is redraw instead of using a scroll and updating the changed text.
+E.g., when using ":match" to highlight a paren that the cursor landed on.
+Added SOME_VALID: Redraw the whole window but also try to scroll to minimize
+redrawing.
+
+Win32: When using Korean IME making it active didn't work properly. (Moon,
+Yu-sung, 2005 March 21)
+
+Ruby interface: when inserting/deleting lines display wasn't updated. (Ryan
+Paul)
+
+--- fixes since Vim 7.0b ---
+
+Getting the GCC version in configure didn't work with Solaris sed.  First
+strip any "darwin." and then get the version number.
+
+The "autoload" directory was missing from the self-installing executable for
+MS-Windows.
+
+The MS-Windows install program would find "vimtutor.bat" in the install
+directory.  After changing to "c:" also change to "\" to avoid looking in the
+install directory.
+
+To make the 16 bit DOS version compile exclude not used highlight
+initializations and build a tiny instead of small version.
+
+finddir() and findfile() accept a negative count and return a List then.
+
+The Python indent file contained a few debugging statements, removed.
+
+Expanding {} for a function name, resulting in a name starting with "s:" was
+not handled correctly.
+
+Spelling: renamed COMPOUNDMAX to COMPOUNDWORDMAX.  Added several items to be
+able to handle the new Hungarian dictionary.
+
+Mac: Default to building for the current platform only, that is much faster
+than building a universal binary.  Also, using Perl/Python/etc. only works for
+the current platform.
+
+The time on undo messages disappeared for someone.  Using %T for strftime()
+apparently doesn't work everywhere.  Use %H:%M:%S instead.
+
+Typing BS at the "z=" prompt removed the prompt.
+
+--- fixes and changes since Vim 7.0c ---
+
+When jumping to another tab page the Vim window size was always set, even when
+nothing in the layout changed.
+
+Win32 GUI tab pages line wasn't always enabled.  Do a proper check for the
+compiler version.
+
+Win32: When switching between tab pages the Vim window was moved when part of
+it was outside of the screen.  Now only do that in the direction of a size
+change.
+
+Win32: added menu to GUI tab pages line. (Yegappan Lakshmanan)
+
+Mac: Added document icons. (Benji Fisher)
+
+Insert mode completion: Using Enter to accept the current match causes
+confusion.  Use CTRL-Y instead.  Also, use CTRL-E to go back to the typed
+text.
+
+GUI: When there are left and right scrollbars, ":tabedit" kept them instead of
+using the one that isn't needed.
+
+Using "gP" to replace al the text could leave the cursor below the last line,
+causing ml_get errors.
+
+When 'cursorline' is set don't use the highlighting when Visual mode is
+active, otherwise it's difficult to see the selected area.
+
+The matchparen plugin restricts the search to 100 lines, to avoid a long delay
+when there are closed folds.
+
+Sometimes using CTRL-X s to list spelling suggestions used text from another
+line.
+
+Win32: Set the default for 'isprint' back to the wrong default "@,~-255",
+because many people use Windows-1252 while 'encoding' is "latin1".
+
+GTK: Added a workaround for gvim crashing when used over an untrusted ssh
+link, caused by GTK doing something nasty. (Ed Catmur)
+
+Win32: The font used for the tab page labels is too big.  Use the system menu
+font. (George Reilly)
+
+Win32: Adjusting the window position and size to keep it on the screen didn't
+work properly when the taskbar is on the left or top of the screen.
+
+The installman.sh and installml.sh scripts use ${10}, that didn't work with
+old shells.  And use "test -f" instead of "test -e".
+
+Win32: When 'encoding' was set in the vimrc then a directory argument for diff
+mode didn't work.
+
+GUI: at the inputlist() prompt the cursorshape was adjusted as if the windows
+were still at their old position.
+
+The parenmatch plugin didn't remember the highlighting per window.
+
+Using ":bd" for a buffer that's the current window in another tab page caused
+a crash.
+
+For a new tab page the 'scroll' option wasn't set to a good default.
+
+Using an end offset for a search "/pat/e" didn't work properly for multi-byte
+text. (Yukihiro Nakadaira)
+
+":s/\n/,/" doubled the text when used on the last line.
+
+When "search" is in 'foldopen' "[s" and "]s" now open folds.
+
+When using a numbered function "dict" can be omitted, but "self" didn't work
+then.  Always add FC_DICT to the function flags when it's part of a
+dictionary.
+
+When "--remote-tab" executes locally it left an empty tab page.
+
+"gvim -u NONE", ":set cursorcolumn", "C" in the second line didn't update
+text.  Do update further lines even though the "$" is displayed.
+
+VMS: Support GTK better, also enable +clientserver. (Zoltan Arpadffy)
+
+When highlighting of statusline or tabline is changed there was no redraw to
+show the effect.
+
+Mac: Added "CFBundleIdentifier" to infplist.xml.
+
+Added tabpage-local variables t:var.
+
+Win32: Added double-click in tab pages line creates new tab. (Yegappan
+Lakshmanan)
+
+Motif: Added GUI tab pages line. (Yegappan Lakshmanan)
+
+Fixed crash when 'lines' was set to 1000 in a modeline.
+
+When init_spellfile() finds a writable directory in 'runtimepath' but it
+doesn't contain a "spell" directory, create one.
+
+Win32: executable() also finds "xxd" in the directory where Vim was started,
+but "!xxd" doesn't work.  Append the Vim starting directory to $PATH.
+
+The tab page labels are shortened, directory names are reduced to a single
+letter by default.  Added the pathshorten() function to allow a user to do the
+same.
+
+":saveas" now resets 'readonly' if the file was successfully written.
+
+Set $MYVIMRC file to the first found .vimrc file.
+Set $MYGVIMRC file to the first found .gvimrc file.
+Added menu item "Startup Settings" that edits the $MYVIMRC file
+
+Added matcharg().
+
+Error message E745 appeared twice.  Renamed one to E786.
+
+Fixed crash when using "au BufRead * Sexplore" and doing ":help".  Was wiping
+out a buffer that's still in a window.
+
+":hardcopy" resulted in an error message when 'encoding' is "utf-8" and
+'printencoding' is empty.  Now it assumes latin1. (Mike Williams)
+
+The check for the toolbar feature for Motif, depending on certain included
+files, wasn't detailed enough, causing building to fail in gui_xmebw.c.
+
+Using CTRL-E in Insert mode completion after CTRL-P inserted the first match
+instead of the original text.
+
+When displaying a UTF-8 character with a zero lower byte Vim might think the
+previous character is double-wide.
+
+The "nbsp" item of 'listchars' didn't work when 'encoding' was utf-8.
+
+Motif: when Xm/xpm.h is missing gui_xmebw.c would not compile.
+HAVE_XM_UNHIGHLIGHTT_H was missing a T.
+
+Mac: Moved the .icns files into src/os_mac_rsrc, so that they can all be
+copied at once.  Adjusted the Info.plist file for three icons.
+
+When Visual mode is active while switching to another tabpage could get ml_get
+errors.
+
+When 'list' is set, 'nowrap' the $ in the first column caused 'cursorcolumn'
+to move to the right.
+
+When a line wraps, 'cursorcolumn' was never displayed past the end of the
+line.
+
+'autochdir' was only available when compiled with NetBeans and GUI.  Now it's
+a separate feature, also available in the "big" version.
+
+Added CTRL-W gf: open file under cursor in new tab page.
+
+When using the menu in the tab pages line, "New Tab" opens the new tab before
+where the click was.  Beyond the labels the new tab appears at the end instead
+of after the current tab page.
+
+Inside a mapping with an expression getchar() could not be used.
+
+When vgetc is used recursively vgetc_busy protects it from being used
+recursively.  But after a ":normal" command the protection was reset.
+
+":s/a/b/n" didn't work when 'modifiable' was off.
+
+When $VIMRUNTIME includes a multi-byte character then rgb.txt could not be
+found. (Yukihiro Nakadaira)
+
+":mkspell" didn't work correctly for non-ASCII affix flags when conversion is
+needed on the spell file.
+
+glob('/dir/\$ABC/*') didn't work.
+
+When using several tab pages and changing 'cmdheight' the display could become
+messed up.  Now store the value of 'cmdheight' separately for each tab page.
+
+The user of the Enter key while the popup menu is visible was still confusing.
+Now use Enter to select the match after using a cursor key.
+
+Added "usetab" to 'switchbuf'.
+
+
+--- fixes and changes since Vim 7.0d ---
+
+Added CTRL-W T: move a window to a new tab page.
+
+Using CTRL-X s in Insert mode to complete spelling suggestions and using BS
+deleted characters before the bad word.
+
+A few small fixes for the VMS makefile. (Zoltan Arpadffy)
+
+With a window of 91 lines 45 cols, ":vsp" scrolled the window.  Copy w_wrow
+when splitting a window and skip setting the height when it's already at the
+right value.
+
+Using <silent> in a mapping with a shell command and the GUI caused redraw
+to use wrong attributes.
+
+Win32: Using MSVC 4.1 for install.exe resulted in the start menu items to be
+created in the administrator directory instead of "All Users".  Define the
+CSIDL_ items if they are missing.
+
+Motif: The GUI tabline did not use the space above the right scrollbar.  Work
+around a bug in the Motif library. (Yegappan Lakshmanan)
+
+The extra files for XML Omni completion are now also installed.
+|xml-omni-datafile|
+
+GTK GUI: when 'm' is missing from 'guioptions' during startup and pressing
+<F10> GTK produced error messages.  Now do create the menu but disable it just
+after the first gui_mch_update().
+
+":mkspell" doesn't work well with the Hungarian dictionary from the Hunspell
+project.  Back to the Myspell dictionary.
+
+In help files hide the | used around tags.
+
+Renamed pycomplete to pythoncomplete.
+
+Added "tabpages" to 'sessionoptions'.
+
+When 'guitablabel' is set the effect wasn't visible right away.
+
+Fixed a few 'cindent' errors.
+
+When completing menu names, e.g., after ":emenu", don't sort the entries but
+keep them in the original order.
+
+Fixed a crash when editing a directory in diff mode.  Don't trigger
+autocommands when executing the diff command.
+
+Getting a keystroke could get stuck if 'encoding' is a multi-byte encoding and
+typing a special key.
+
+When 'foldignore' is set the folds were not updated right away.
+
+When a list is indexed with [a : b] and b was greater than the length an error
+message was given.  Now silently truncate the result.
+
+When using BS during Insert mode completion go back to the original text, so
+that CTRL-N selects the first matching entry.
+
+Added the 'M' flag to 'cinoptions'.
+
+Win32: Make the "gvim --help" window appear in the middle of the screen
+instead of at an arbitrary position. (Randall W. Morris)
+
+Added gettabwinvar() and settabwinvar().
+
+Command line completion: pressing <Tab> after ":e /usr/*" expands the whole
+tree, because it becomes ":e /usr/**".  Don't add a star if there already is
+one.
+
+Added grey10 to grey90 to all GUIs, so that they can all be used for
+initializing highlighting.  Use grey40 for CursorColumn and CursorLine when
+'background' is "dark".
+
+When reading a file and using iconv for conversion, an incomplete byte
+sequence at the end caused problems. (Yukihiro Nakadaira)
+
+
+--- fixes and changes since Vim 7.0e ---
+
+Default color for MatchParen when 'background' is "dark" is now DarkCyan.
+
+":syn off" had to be used twice in a file that sets 'syntax' in a modeline.
+(Michael Geddes)
+
+When using ":vsp" or ":sp" the available space wasn't used equally between
+windows. (Servatius Brandt)
+
+Expanding <cWORD> on a trailing blank resulted in the first word in the line
+if 'encoding' is a multi-byte encoding.
+
+Spell checking: spellbadword() didn't see a missing capital in the first word
+of a line.  Popup menu now only suggest the capitalized word when appropriate.
+
+When using whole line completion CTRL-L moves through the matches but it
+didn't work when at the original text.
+
+When completion finds the longest match, don't go to the first match but stick
+at the original text, so that CTRL-N selects the first one.
+
+Recognize "zsh-beta" like "zsh" for setting the 'shellpipe' default. (James
+Vega)
+
+When using ":map <expr>" and the expression results in something with a
+special byte (NUL or CSI) then it didn't work properly.  Now escape special
+bytes.
+
+The default Visual highlighting for a color xterm with 8 colors was a magenta
+background, which made magenta text disappear.  Now use reverse in this
+specific situation.
+
+After completing the longest match "." didn't insert the same text.  Repeating
+also didn't work correctly for multi-byte text.
+
+When using Insert mode completion and BS the whole word that was completed
+would result in all possible matches.  Now stop completion.  Also fixes that
+for spell completion the previous word was deleted.
+
+GTK: When 'encoding' is "latin1" and using non-ASCII characters in a file name
+the tab page label was wrong and an error message would be given.
+
+The taglist() function could hang on a tags line with a non-ASCII character.
+
+Win32: When 'encoding' differs from the system encoding tab page labels with
+non-ASCII characters looked wrong. (Yegappan Lakshmanan)
+
+Motif: building failed when Xm/Notebook.h doesn't exist.  Added a configure
+check, disable GUI tabline when it's missing.
+
+Mac: When compiled without multi-byte feature the clipboard didn't work.
+
+It was possible to switch to another tab page when the cmdline window is open.
+
+Completion could hang when 'lines' is 6 and a preview window was opened.
+
+Added CTRL-W gF: open file under cursor in new tab page and jump to the line
+number following the file name.
+Added 'guitabtooltip'.  Implemented for Win32 (Yegappan Lakshmanan).
+
+Added "throw" to 'debug' option: throw an exception for error messages even
+whey they would otherwise be ignored.
+
+When 'keymap' is set and a line contains an invalid entry could get a "No
+mapping found" warning instead of a proper error message.
+
+Motif: default to using XpmAttributes instead of XpmAttributes_21.
+
+A few more changes for 64 bit MS-Windows. (George Reilly)
+
+Got ml_get errors when doing "o" and selecting in other window where there are
+less line shorter than the cursor position in the other window.  ins_mouse()
+was using position in wrong window.
+
+Win32 GUI: Crash when giving a lot of messages during startup.  Allocate twice
+as much memory for the dialog template.
+
+Fixed a few leaks and wrong pointer use reported by coverity.
+
+When showing menus the mode character was sometimes wrong.
+
+Added feedkeys(). (Yakov Lerner)
+
+Made matchlist() always return all submatches.
+
+Moved triggering QuickFixCmdPost to before jumping to the first location.
+
+Mac: Added the 'macatsui' option as a temporary work around for text drawing
+problems.
+
+Line completion on "/**" gave error messages when scanning an unloaded buffer.
+
+--- fixes and changes since Vim 7.0f ---
+
+Win32: The height of the tab page labels is now adjusted to the font height.
+(Yegappan Lakshmanan)
+
+Win32: selecting the tab label was off by one. (Yegappan Lakshmanan)
+
+Added tooltips for Motif and GTK tab page labels. (Yegappan Lakshmanan)
+
+When 'encoding' is "utf-8" then ":help spell" would report an illegal byte and
+the file was not converted from latin1 to utf-8.  Now retry with latin1 if
+reading the file as utf-8 results in illegal bytes.
+
+Escape the argument of feedkeys() before putting it in the typeahead buffer.
+(Yukihiro Nakadaira)
+
+Added the v:char variable for evaluating 'formatexpr'. (Yukihiro Nakadaira)
+
+With 8 colors Search highlighting combined with Statement highlighted text
+made the text disappear.
+
+VMS: avoid warnings for redefining MAX and MIN. (Zoltan Arpadffy)
+
+When 'virtualedit' includes "onemore", stopping Visual selection would still
+move the cursor left.
+
+Prevent that using CTRL-R = in Insert mode can start Visual mode.
+
+Fixed a crash that occurred when in Insert mode with completion active and a
+mapping caused edit() to be called recursively.
+
+When using CTRL-O in Insert mode just after the last character while
+'virtualedit' is "all", then typing CR moved the last character to the next
+line.  Call coladvance() before starting the new line.
+
+When using |:shell| ignore clicks on the tab page labels.  Also when using the
+command line window.
+
+When 'eventignore' is "all" then adding more to ignoring some events, e.g.,
+for ":vimgrep", would actually trigger more events.
+
+Win32: When a running Vim uses server name GVIM1 then "gvim --remote fname"
+didn't find it.  When looking for a server name that doesn't end in a digit
+and it is not found then use another server with that name and a number (just
+like on Unix).
+
+When using "double" in 'spellsuggest' when the language doesn't support sound
+folding resulted in too many suggestions.
+
+Win32: Dropping a shortcut on the Vim icon didn't edit the referred file like
+editing it in another way would.  Use fname_expand() in buf_set_name() instead
+of simply make the file name a full path.
+
+Using feedkeys() could cause Vim to hang.
+
+When closing another tab page from the tabline menu in Insert mode the tabline
+was not updated right away.
+
+The syntax menu didn't work in compatible mode.
+
+After using ":tag id" twice with the same "id", ":ts" and then ":pop" a ":ts"
+reported no matching tag.  Clear the cached tag name.
+
+In Insert mode the matchparen plugin highlighted the wrong paren when there is
+a string just next to a paren.
+
+GTK: After opening a new tab page the text was sometimes not drawn correctly.
+Flush output and catch up with events when updating the tab page labels.
+
+In the GUI, using CTRL-W q to close the last window of a tab page could cause
+a crash.
+
+GTK: The tab pages line menu was not converted from 'encoding' to utf-8.
+
+Typing a multi-byte character or a special key at the hit-enter prompt did not
+work.
+
+When 'virtualedit' contains "onemore" CTRL-O in Insert mode still moved the
+cursor left when it was after the end of the line, even though it's allowed to
+be there.
+
+Added test for using tab pages.
+
+towupper() and towlower() were not used, because of checking for
+__STDC__ISO_10646__ instead of __STDC_ISO_10646__. (sertacyildiz)
+
+For ":map <expr>" forbid changing the text, jumping to another buffer and
+using ":normal" to avoid nasty side effects.
+
+--- fixes and changes since Vim 7.0g ---
+
+Compilation error on HP-UX, use of "dlerr" must be inside a #ifdef.
+(Gary Johnson)
+
+Report +reltime feature in ":version" output.
+
+The tar and zip plugins detect failure to get the contents of the archive and
+edit the file as-is.
+
+When the result of 'guitablabel' is empty fall back to the default label.
+
+Fixed crash when using ":insert" in a while loop and missing "endwhile".
+
+"gt" and other commands could move to another window when |textlock| active
+and when the command line window was open.
+
+Spell checking a file with syntax highlighting and a bad word at the end of
+the line is ignored could make "]s" hang.
+
+Mac: inputdialog() didn't work when compiled with big features.
+
+Interrupting ":vimgrep" while it is busy loading a file left a modified and
+hidden buffer behind.  Use enter_cleanup() and leave_cleanup() around
+wipe_buffer().
+
+When making 'keymap' empty the b:keymap_name variable wasn't deleted.
+
+Using CTRL-N that searches a long time, pressing space to interrupt the
+searching and accept the first match, the popup menu was still displayed
+briefly.
+
+When setting the Vim window height with -geometry the 'window' option could be
+at a value that makes CTRL-F behave differently.
+
+When opening a quickfix window in two tabs they used different buffers,
+causing redrawing problems later.  Now use the same buffer for all quickfix
+windows. (Yegappan Lakshmanan)
+
+When 'mousefocus' is set moving the mouse to the text tab pages line would
+move focus to the first window.  Also, the mouse pointer would jump to the
+active window.
+
+In a session file, when an empty buffer is wiped out, do this silently.
+
+When one window has the cursor on the last line and another window is resized
+to make that window smaller, the cursor line could go below the displayed
+lines.  In win_new_height() subtract one from the available space.
+Also avoid that using "~" lines makes the window scroll down.
+
+Mac: When sourcing the "macmap.vim" script and then finding a .vimrc file the
+'cpo' option isn't set properly, because it was already set and restored.
+Added the <special> argument to ":map", so that 'cpo' doesn't need to be
+changed to be able to use <> notation.  Also do this for ":menu" for
+consistency.
+
+When using "/encoding=abc" in a spell word list, only "bc" was used.
+
+When 'encoding' and 'printencoding' were both "utf-8" then ":hardcopy" didn't
+work. (Mike Williams)
+
+Mac: When building with "--disable-gui" the install directory would still be
+"/Applications" and Vim.app would be installed.  Now install in /usr/local as
+usual for a console application.
+
+GUI: when doing completion and there is one match and still searching for
+another, the cursor was displayed at the end of the line instead of after the
+match.  Now show the cursor after the match while still searching for matches.
+
+GUI: The mouse shape changed on the statusline even when 'mouse' was empty and
+they can't be dragged..
+
+GTK2: Selecting a button in the confirm() dialog with Tab or cursor keys and
+hitting Enter didn't select that button.  Removed GTK 1 specific code. (Neil
+Bird)
+
+When evaluating 'balloonexpr' takes a long time it could be called
+recursively, which could cause a crash.
+
+exists() could not be used to detect whether ":2match" is supported.  Added a
+check for it specifically.
+
+GTK1: Tab page labels didn't work. (Yegappan Lakshmanan)
+
+Insert mode completion: When finding matches use 'ignorecase', but when adding
+matches to the list don't use it, so that all words with different case are
+added, "word", "Word" and "WORD".
+
+When 'cursorline' and 'hlsearch' are set and the search pattern is "x\n"
+the rest of the line was highlighted as a match.
+
+Cursor moved while evaluating 'balloonexpr' that invokes ":isearch" and
+redirects the output.  Don't move the cursor to the command line if msg_silent
+is set.
+
+exists() ignored text after a function name and option name, which could
+result in false positives.
+
+exists() ignored characters after the recognized word, which can be wrong when
+using a name with non-keyword characters.  Specifically, these calls no longer
+allow characters after the name: exists('*funcname') exists('*funcname(...')
+exists('&option') exists(':cmd') exists('g:name') exists('g:name[n]')
+exists('g:name.n')
+
+Trigger the TabEnter autocommand only after entering the current window of the
+tab page, otherwise the commands are executed with an invalid current window.
+
+Win32: When using two monitors and Vim is on the second monitor, changing the
+width of the Vim window could make it jump to the first monitor.
+
+When scrolling back at the more prompt and the quitting a line of text would
+be left behind when 'cmdheight' is 2 or more.
+
+Fixed a few things for Insert mode completion, especially when typing BS,
+CTRL-N or a printable character while still searching for matches.
+
+
+==============================================================================
+VERSION 7.1						*version-7.1*
+
+This section is about improvements made between version 7.0 and 7.1.
+
+This is a bug-fix release, there are no fancy new features.
+
+
+Changed							*changed-7.1*
+-------
+
+Added setting 'mouse' in vimrc_example.vim.
+
+When building with MZscheme also look for include files in the "plt"
+subdirectory.  That's where they are for FreeBSD.
+
+The Ruby interface module is now called "Vim" instead of "VIM".  But "VIM" is
+an alias, so it's backwards compatible. (Tim Pope)
+
+
+Added							*added-7.1*
+-----
+
+New syntax files:
+	/var/log/messages (Yakov Lerner)
+	Autohotkey (Nikolai Weibull)
+	AutoIt v3 (Jared Breland)
+	Bazaar commit file "bzr". (Dmitry Vasiliev)
+	Cdrdao TOC (Nikolai Weibull)
+	Cmusrc (Nikolai Weibull)
+	Conary recipe (rPath Inc)
+	Framescript (Nikolai Weibull)
+	FreeBasic (Mark Manning)
+	Hamster (David Fishburn)
+	IBasic (Mark Manning)
+	Initng (Elan Ruusamae)
+	Ldapconf (Nikolai Weibull)
+	Litestep (Nikolai Weibull)
+	Privoxy actions file (Doug Kearns)
+	Streaming Descriptors "sd" (Puria Nafisi Azizi)
+
+New tutor files:
+	Czech (Lubos Turek)
+	Hungarian (Arpad Horvath)
+	Turkish (Serkan kkk)
+	utf-8 version of Greek tutor.
+	utf-8 version of Russian tutor.
+	utf-8 version of Slowak tutor.
+
+New filetype plugins:
+	Bst (Tim Pope)
+	Cobol (Tim Pope)
+	Fvwm (Gautam Iyer)
+	Hamster (David Fishburn)
+	Django HTML template (Dave Hodder)
+
+New indent files:
+	Bst (Tim Pope)
+	Cobol (Tim Pope)
+	Hamster (David Fishburn)
+	Django HTML template (Dave Hodder)
+	Javascript
+	JSP (David Fishburn)
+
+New keymap files:
+	Bulgarian (Boyko Bantchev)
+	Mongolian (Natsagdorj Shagdar)
+	Thaana (Ibrahim Fayaz)
+	Vietnamese (Samuel Thibault)
+
+Other new runtime files:
+	Ada support files. (Neil Bird, Martin Krischik)
+	Slovenian menu translations (Mojca Miklavec)
+	Mono C# compiler plugin (Jarek Sobiecki)
+
+
+Fixed							*fixed-7.1*
+-----
+
+Could not build the Win32s version.  Added a few structure definitions in
+src/gui_w32.c
+
+
+Patch 7.0.001
+Problem:    ":set spellsuggest+=10" does not work. (Suresh Govindachar)
+Solution:   Add P_COMMA to the 'spellsuggest' flags.
+Files:	    src/option.c
+
+Patch 7.0.002
+Problem:    C omni completion has a problem with tags files with a path
+	    containing "#" or "%".
+Solution:   Escape these characters. (Sebastian Baberowski)
+Files:	    runtime/autoload/ccomplete.vim
+
+Patch 7.0.003
+Problem:    GUI: clicking in the lower part of a label in the tab pages line
+	    while 'mousefocus' is set may warp the mouse pointer. (Robert
+	    Webb)
+Solution:   Check for a negative mouse position.
+Files:	    src/gui.c
+
+Patch 7.0.004
+Problem:    Compiler warning for debug_saved used before set. (Todd Blumer)
+Solution:   Remove the "else" for calling save_dbg_stuff().
+Files:	    src/ex_docmd.c
+
+Patch 7.0.005 (extra)
+Problem:    Win32: The installer doesn't remove the "autoload" and "spell"
+	    directories. (David Fishburn)
+Solution:   Add the directories to the list to be removed.
+Files:	    nsis/gvim.nsi
+
+Patch 7.0.006
+Problem:    Mac: "make shadow" doesn't make a link for infplist.xml. (Axel
+	    Kielhorn)
+Solution:   Make the link.
+Files:	    src/Makefile
+
+Patch 7.0.007
+Problem:    AIX: compiling fails for message.c. (Ruediger Hornig)
+Solution:   Move the #if outside of memchr().
+Files:	    src/message.c
+
+Patch 7.0.008
+Problem:    Can't call a function that uses both <SID> and {expr}. (Thomas)
+Solution:   Check both the expanded and unexpanded name for <SID>.
+Files:	    src/eval.c
+
+Patch 7.0.009
+Problem:    ml_get errors with both 'sidescroll' and 'spell' set.
+Solution:   Use ml_get_buf() instead of ml_get(), get the line from the right
+	    buffer, not the current one.
+Files:	    src/spell.c
+
+Patch 7.0.010
+Problem:    The spellfile plugin required typing login name and password.
+Solution:   Use "anonymous" and "vim7user" by default.  No need to setup a
+	    .netrc file.
+Files:	    runtime/autoload/spellfile.vim
+
+Patch 7.0.011
+Problem:    Can't compile without the folding and with the eval feature.
+Solution:   Add an #ifdef. (Vallimar)
+Files:	    src/option.c
+
+Patch 7.0.012
+Problem:    Using the matchparen plugin, moving the cursor in Insert mode to a
+	    shorter line that ends in a brace, changes the preferred column
+Solution:   Use winsaveview()/winrestview() instead of getpos()/setpos().
+Files:	    runtime/plugin/matchparen.vim
+
+Patch 7.0.013
+Problem:    Insert mode completion: using CTRL-L to add an extra character
+	    also deselects the current match, making it impossible to use
+	    CTRL-L a second time.
+Solution:   Keep the current match.  Also make CTRL-L work at the original
+	    text, using the first displayed match.
+Files:	    src/edit.c
+
+Patch 7.0.014
+Problem:    Compiling gui_xmebw.c fails on Dec Alpha Tru64. (Rolfe)
+Solution:   Disable some code for Motif 1.2 and older.
+Files:	    src/gui_xmebw.c
+
+Patch 7.0.015
+Problem:    Athena: compilation problems with modern compiler.
+Solution:   Avoid type casts for lvalue. (Alexey Froloff)
+Files:	    src/gui_at_fs.c
+
+Patch 7.0.016
+Problem:    Printing doesn't work for "dec-mcs" encoding.
+Solution:   Add "dec-mcs", "mac-roman" and "hp-roman8" to the list of
+	    recognized 8-bit encodings. (Mike Williams)
+Files:	    src/mbyte.c
+
+Patch 7.0.017 (after 7.0.014)
+Problem:    Linking gui_xmebw.c fails on Dec Alpha Tru64. (Rolfe)
+Solution:   Adjust defines for Motif 1.2 and older.
+Files:	    src/gui_xmebw.c
+
+Patch 7.0.018
+Problem:    VMS: plugins are not loaded on startup.
+Solution:   Remove "**" from the path. (Zoltan Arpadffy)
+Files:	    src/main.c
+
+Patch 7.0.019
+Problem:    Repeating "VjA789" may cause a crash. (James Vega)
+Solution:   Check the cursor column after moving it to another line.
+Files:	    src/ops.c
+
+Patch 7.0.020
+Problem:    Crash when using 'mousefocus'. (William Fulton)
+Solution:   Make buffer for mouse coordinates 2 bytes longer. (Juergen Weigert)
+Files:	    src/gui.c
+
+Patch 7.0.021
+Problem:    Crash when using "\\[" and "\\]" in 'errorformat'. (Marc Weber)
+Solution:   Check for valid submatches after matching the pattern.
+Files:	    src/quickfix.c
+
+Patch 7.0.022
+Problem:    Using buffer.append() in Ruby may append the line to the wrong
+	    buffer. (Alex Norman)
+Solution:   Properly switch to the buffer to do the appending.  Also for
+	    buffer.delete() and setting a buffer line.
+Files:	    src/if_ruby.c
+
+Patch 7.0.023
+Problem:    Crash when doing spell completion in an empty line and pressing
+	    CTRL-E.
+Solution:   Check for a zero pointer. (James Vega)
+	    Also handle a situation without a matching pattern better, report
+	    "No matches" instead of remaining in undefined CTRL-X mode.  And
+	    get out of CTRL-X mode when typing a letter.
+Files:	    src/edit.c
+
+Patch 7.0.024
+Problem:    It is possible to set arbitrary "v:" variables.
+Solution:   Disallow setting "v:" variables that are not predefined.
+Files:	    src/eval.c
+
+Patch 7.0.025
+Problem:    Crash when removing an element of a:000.  (Nikolai Weibull)
+Solution:   Mark the a:000 list with VAR_FIXED.
+Files:	    src/eval.c
+
+Patch 7.0.026
+Problem:    Using libcall() may show an old error.
+Solution:   Invoke dlerror() to clear a previous error. (Yukihiro Nakadaira)
+Files:	    src/os_unix.c
+
+Patch 7.0.027 (extra)
+Problem:    Win32: When compiled with SNIFF gvim may hang on exit.
+Solution:   Translate and dispatch the WM_USER message. (Mathias Michaelis)
+Files:	    src/gui_w48.c
+
+Patch 7.0.028 (extra)
+Problem:    OS/2: Vim doesn't compile with gcc 3.2.1.
+Solution:   Add argument to after_pathsep(), don't define vim_handle_signal(),
+	    define HAVE_STDARG_H. (David Sanders)
+Files:	    src/os_unix.c, src/vim.h, src/os_os2_cfg.h
+
+Patch 7.0.029
+Problem:    getchar() may not position the cursor after a space.
+Solution:   Position the cursor explicitly.
+Files:	    src/eval.c
+
+Patch 7.0.030
+Problem:    The ":compiler" command can't be used in a FileChangedRO event.
+	    (Hari Krishna Dara)
+Solution:   Add the CMDWIN flag to the ":compiler" command.
+Files:	    src/ex_cmds.h
+
+Patch 7.0.031
+Problem:    When deleting a buffer the buffer-local mappings for Select mode
+	    remain.
+Solution:   Add the Select mode bit to MAP_ALL_MODES. (Edwin Steiner)
+Files:	    src/vim.h
+
+Patch 7.0.032 (extra, after 7.0.027)
+Problem:    Missing semicolon.
+Solution:   Add the semicolon.
+Files:	    src/gui_w48.c
+
+Patch 7.0.033
+Problem:    When pasting text, with the menu or CTRL-V, autoindent is removed.
+Solution:   Use "x<BS>" to avoid indent to be removed. (Benji Fisher)
+Files:	    runtime/autoload/paste.vim
+
+Patch 7.0.034
+Problem:    After doing completion and typing more characters or using BS
+	    repeating with "." didn't work properly. (Martin Stubenschrott)
+Solution:   Don't put BS and other characters in the redo buffer right away,
+	    do this when finishing completion.
+Files:	    src/edit.c
+
+Patch 7.0.035
+Problem:    Insert mode completion works when typed but not when replayed from
+	    a register. (Hari Krishna Dara)
+	    Also: Mappings for Insert mode completion don't always work.
+Solution:   When finding a non-completion key in the input don't interrupt
+	    completion when it wasn't typed.
+	    Do use mappings when checking for typeahead while still finding
+	    completions.  Avoids that completion is interrupted too soon.
+	    Use "compl_pending" in a different way.
+Files:	    src/edit.c
+
+Patch 7.0.036
+Problem:    Can't compile with small features and syntax highlighting or the
+	    diff feature.
+Solution:   Define LINE_ATTR whenever syntax highlighting or the diff feature
+	    is enabled.
+Files:	    src/screen.c
+
+Patch 7.0.037
+Problem:    Crash when resizing the GUI window vertically when there is a line
+	    that doesn't fit.
+Solution:   Don't redraw while the screen data is invalid.
+Files:	    src/screen.c
+
+Patch 7.0.038
+Problem:    When calling complete() from an Insert mode expression mapping
+	    text could be inserted in an improper way.
+Solution:   Make undo_allowed() global and use it in complete().
+Files:	    src/undo.c, src/proto/undo.pro, src/eval.c
+
+Patch 7.0.039
+Problem:    Calling inputdialog() with a third argument in the console doesn't
+	    work.
+Solution:   Make a separate function for input() and inputdialog(). (Yegappan
+	    Lakshmanan)
+Files:	    src/eval.c
+
+Patch 7.0.040
+Problem:    When 'cmdheight' is larger than 1 using inputlist() or selecting
+	    a spell suggestion with the mouse gets the wrong entry.
+Solution:   Start listing the first alternative on the last line of the screen.
+Files:	    src/eval.c, src/spell.c
+
+Patch 7.0.041
+Problem:    cursor([1, 1]) doesn't work. (Peter Hodge)
+Solution:   Allow leaving out the third item of the list and use zero for the
+	    virtual column offset.
+Files:	    src/eval.c
+
+Patch 7.0.042
+Problem:    When pasting a block of text in Insert mode Vim hangs or crashes.
+	    (Noam Halevy)
+Solution:   Avoid that the cursor is positioned past the NUL of a line.
+Files:	    src/ops.c
+
+Patch 7.0.043
+Problem:    Using "%!" at the start of 'statusline' doesn't work.
+Solution:   Recognize the special item when the option is being set.
+Files:	    src/option.c
+
+Patch 7.0.044
+Problem:    Perl: setting a buffer line in another buffer may result in
+	    changing the current buffer.
+Solution:   Properly change to the buffer to be changed.
+Files:	    src/if_perl.xs
+
+Patch 7.0.045 (extra)
+Problem:    Win32: Warnings when compiling OLE version with MSVC 2005.
+Solution:   Move including vim.h to before windows.h. (Ilya Bobir)
+Files:	    src/if_ole.cpp
+
+Patch 7.0.046
+Problem:    The matchparen plugin ignores parens in strings, but not in single
+	    quotes, often marked with "character".
+Solution:   Also ignore parens in syntax items matching "character".
+Files:	    runtime/plugin/matchparen.vim
+
+Patch 7.0.047
+Problem:    When running configure the exit status is wrong.
+Solution:   Handle the exit status properly. (Matthew Woehlke)
+Files:	    configure, src/configure
+
+Patch 7.0.048
+Problem:    Writing a compressed file fails when there are parens in the name.
+	    (Wang Jian)
+Solution:   Put quotes around the temp file name.
+Files:	    runtime/autoload/gzip.vim
+
+Patch 7.0.049
+Problem:    Some TCL scripts are not recognized. (Steven Atkinson)
+Solution:   Check for "exec wish" in the file.
+Files:	    runtime/scripts.vim
+
+Patch 7.0.050
+Problem:    After using the netbeans interface close command a stale pointer
+	    may be used.
+Solution:   Clear the pointer to the closed buffer. (Xaview de Gaye)
+Files:	    src/netbeans.c
+
+Patch 7.0.051 (after 7.0.44)
+Problem:    The Perl interface doesn't compile or doesn't work properly.
+Solution:   Remove the spaces before #ifdef and avoid an empty line above it.
+Files:	    src/if_perl.xs
+
+Patch 7.0.052
+Problem:    The user may not be aware that the Vim server allows others more
+	    functionality than desired.
+Solution:   When running Vim as root don't become a Vim server without an
+	    explicit --servername argument.
+Files:	    src/main.c
+
+Patch 7.0.053
+Problem:    Shortening a directory name may fail when there are multi-byte
+	    characters.
+Solution:   Copy the correct bytes. (Titov Anatoly)
+Files:	    src/misc1.c
+
+Patch 7.0.054
+Problem:    Mac: Using a menu name that only has a mnemonic or accelerator
+	    causes a crash.  (Elliot Shank)
+Solution:   Check for an empty menu name.  Also delete empty submenus that
+	    were created before detecting the error.
+Files:	    src/menu.c
+
+Patch 7.0.055
+Problem:    ":startinsert" in a CmdwinEnter autocommand doesn't take immediate
+	    effect. (Bradley White)
+Solution:   Put a NOP key in the typeahead buffer.  Also avoid that using
+	    CTRL-C to go back to the command line moves the cursor left.
+Files:	    src/edit.c, src/ex_getln.c
+
+Patch 7.0.056
+Problem:    "#!something" gives an error message.
+Solution:   Ignore this line, so that it can be used in an executable Vim
+	    script.
+Files:	    src/ex_docmd.c
+
+Patch 7.0.057 (extra, after 7.0.45)
+Problem:    Win32: Compilation problem with Borland C 5.5.
+Solution:   Include vim.h as before. (Mark S. Williams)
+Files:	    src/if_ole.cpp
+
+Patch 7.0.058
+Problem:    The gbk and and gb18030 encodings are not recognized.
+Solution:   Add aliases to cp936. (Edward L. Fox)
+Files:	    src/mbyte.c
+
+Patch 7.0.059
+Problem:    The Perl interface doesn't compile with ActiveState Perl 5.8.8.
+Solution:   Remove the __attribute__() items. (Liu Yubao)
+Files:	    src/if_perl.xs
+
+Patch 7.0.060 (after 7.0.51)
+Problem:    Code for temporarily switching to another buffer is duplicated in
+	    quite a few places.
+Solution:   Use aucmd_prepbuf() and aucmd_restbuf() also when FEAT_AUTOCMD is
+	    not defined.
+Files:	    src/buffer.c, src/eval.c, src/fileio.c, src/if_ruby.c,
+	    src/if_perl.xs, src/quickfix.c, src/structs.h
+
+Patch 7.0.061
+Problem:    Insert mode completion for Vim commands may crash if there is
+	    nothing to complete.
+Solution:   Instead of freeing the pattern make it empty, so that a "not
+	    found" error is given. (Yukihiro Nakadaira)
+Files:	    src/edit.c
+
+Patch 7.0.062
+Problem:    Mac: Crash when using the popup menu for spell correction.  The
+	    popup menu appears twice when letting go of the right mouse button
+	    early.
+Solution:   Don't show the popup menu on the release of the right mouse
+	    button.  Also check that a menu pointer is actually valid.
+Files:	    src/proto/menu.pro, src/menu.c, src/normal.c, src/term.c
+
+Patch 7.0.063
+Problem:    Tiny chance for a memory leak. (coverity)
+Solution:   Free pointer when next memory allocation fails.
+Files:	    src/eval.c
+
+Patch 7.0.064
+Problem:    Using uninitialized variable. (Tony Mechelynck)
+Solution:   When not used set "temp" to zero.  Also avoid a warning for
+	    "files" in ins_compl_dictionaries().
+Files:	    src/edit.c
+
+Patch 7.0.065 (extra)
+Problem:    Mac: left-right movement of the scrollwheel causes up-down
+	    scrolling.
+Solution:   Ignore mouse wheel events that are not up-down. (Nicolas Weber)
+Files:	    src/gui_mac.c
+
+Patch 7.0.066
+Problem:    After the popup menu for Insert mode completion overlaps the tab
+	    pages line it is not completely removed.
+Solution:   Redraw the tab pages line after removing the popup menu. (Ori
+	    Avtalion)
+Files:	    src/popupmnu.c
+
+Patch 7.0.067
+Problem:    Undo doesn't always work properly when using "scim" input method.
+	    Undo is split up when using preediting.
+Solution:   Reset xim_has_preediting also when preedit_start_col is not
+	    MAXCOL.  Don't split undo when <Left> is used while preediting.
+	    (Yukihiro Nakadaira)
+Files:	    src/edit.c, src/mbyte.c
+
+Patch 7.0.068
+Problem:    When 'ignorecase' is set and using Insert mode completion,
+	    typing characters to change the list of matches, case is not
+	    ignored. (Hugo Ahlenius)
+Solution:   Store the 'ignorecase' flag with the matches where needed.
+Files:	    src/edit.c, src/search.c, src/spell.c
+
+Patch 7.0.069
+Problem:    Setting 'guitablabel' to %!expand(\%)  causes Vim to free an
+	    invalid pointer. (Kim Schulz)
+Solution:   Don't try freeing a constant string pointer.
+Files:	    src/buffer.c
+
+Patch 7.0.070
+Problem:    Compiler warnings for shadowed variables and uninitialized
+	    variables.
+Solution:   Rename variables such as "index", "msg" and "dup".  Initialize
+	    variables.
+Files:	    src/edit.c, src/eval.c, src/ex_cmds.c, src/ex_cmds2.c,
+	    src/ex_docmd.c, src/gui_beval.c, src/gui_gtk.c, src/gui_gtk_x11.c,
+	    src/hardcopy.c, src/if_cscope.c, src/main.c, src/mbyte.c,
+	    src/memline.c, src/netbeans.c, src/normal.c, src/option.c,
+	    src/os_unix.c, src/quickfix.c, src/regexp.c, src/screen.c,
+	    src/search.c, src/spell.c, src/ui.c, src/undo.c, src/window.c,
+	    src/version.c
+
+Patch 7.0.071
+Problem:    Using an empty search pattern may cause a crash.
+Solution:   Avoid using a NULL pointer.
+Files:	    src/search.c
+
+Patch 7.0.072
+Problem:    When starting the GUI fails there is no way to adjust settings or
+	    do something else.
+Solution:   Add the GUIFailed autocommand event.
+Files:	    src/fileio.c, src/gui.c, src/vim.h
+
+Patch 7.0.073
+Problem:    Insert mode completion: Typing <CR> sometimes selects the original
+	    text instead of keeping what was typed.  (Justin Constantino)
+Solution:   Don't let <CR> select the original text if there is no popup menu.
+Files:	    src/edit.c
+
+Patch 7.0.074 (extra)
+Problem:    Win32: tooltips were not converted from 'encoding' to Unicode.
+Solution:   Set the tooltip to use Unicode and do the conversion.  Also
+	    cleanup the code for the tab pages tooltips. (Yukihiro Nakadaira)
+Files:	    src/gui_w32.c, src/gui_w48.c
+
+Patch 7.0.075
+Problem:    winsaveview() did not store the actual value of the desired cursor
+	    column.  This could move the cursor in the matchparen plugin.
+Solution:   Call update_curswant() before using the value w_curswant.
+Files:	    src/eval.c
+
+Patch 7.0.076 (after 7.0.010)
+Problem:    Automatic downloading of spell files only works for ftp.
+Solution:   Don't add login and password for non-ftp URLs. (Alexander Patrakov)
+Files:	    runtime/autoload/spellfile.vim
+
+Patch 7.0.077
+Problem:    ":unlet v:this_session" causes a crash. (Marius Roets)
+Solution:   When trying to unlet a fixed variable give an error message.
+Files:	    src/eval.c
+
+Patch 7.0.078
+Problem:    There are two error messages E46.
+Solution:   Change the number for the sandbox message to E794.
+Files:	    src/globals.h
+
+Patch 7.0.079
+Problem:    Russian tutor doesn't work when 'encoding' is "utf-8".
+Solution:   Use tutor.ru.utf-8 as the master, and generate the other encodings
+	    from it.  Select the right tutor depending on 'encoding'. (Alexey
+	    Froloff)
+Files:	    runtime/tutor/Makefile, runtime/tutor/tutor.vim,
+	    runtime/tutor/tutor.ru.utf-8
+
+Patch 7.0.080
+Problem:    Generating auto/pathdef.c fails for CFLAGS with a backslash.
+Solution:   Double backslashes in the string. (Alexey Froloff)
+Files:	    src/Makefile
+
+Patch 7.0.081
+Problem:    Command line completion doesn't work for a shell command with an
+	    absolute path.
+Solution:   Don't use $PATH when there is an absolute path.
+Files:	    src/ex_getln.c
+
+Patch 7.0.082
+Problem:    Calling a function that waits for input may cause List and
+	    Dictionary arguments to be freed by the garbage collector.
+Solution:   Keep a list of all arguments to internal functions.
+Files:	    src/eval.c
+
+Patch 7.0.083
+Problem:    Clicking with the mouse on an item for inputlist() doesn't work
+	    when 'compatible' is set and/or when 'cmdheight' is more than one.
+	    (Christian J.  Robinson)
+Solution:   Also decrement "lines_left" when 'more' isn't set.  Set
+	    "cmdline_row" to zero to get all mouse events.
+Files:	    src/message.c, src/misc1.c
+
+Patch 7.0.084
+Problem:    The garbage collector may do its work while some Lists or
+	    Dictionaries are used internally, e.g., by ":echo" that runs into
+	    the more-prompt or ":echo [garbagecollect()]".
+Solution:   Only do garbage collection when waiting for a character at the
+	    toplevel.  Let garbagecollect() set a flag that is handled at the
+	    toplevel before waiting for a character.
+Files:	    src/eval.c, src/getchar.c, src/globals.h, src/main.c
+
+Patch 7.0.085
+Problem:    When doing "make test" the viminfo file is modified.
+Solution:   Use another viminfo file after setting 'compatible.
+Files:	    src/testdir/test56.in
+
+Patch 7.0.086
+Problem:    getqflist() returns entries for pattern and text with the number
+	    zero.  Passing these to setqflist() results in the string "0".
+Solution:   Use an empty string instead of the number zero.
+Files:	    src/quickfix.c
+
+Patch 7.0.087
+Problem:    After ":file fname" and ":saveas fname" the 'autochdir' option
+	    does not take effect. (Yakov Lerner)
+	    Commands for handling 'autochdir' are repeated many times.
+Solution:   Add the DO_AUTOCHDIR macro and do_autochdir().  Use it for
+	    ":file fname" and ":saveas fname".
+Files:	    src/proto/buffer.pro, src/buffer.c, src/ex_cmds.c, src/macros.h,
+	    src/netbeans.c, src/option.c, src/window.c
+
+Patch 7.0.088
+Problem:    When compiled with Perl the generated prototypes have "extern"
+	    unnecessarily added.
+Solution:   Remove the "-pipe" argument from PERL_CFLAGS.
+Files:	    src/auto/configure, src/configure.in
+
+Patch 7.0.089
+Problem:    "ga" does not work properly for a non-Unicode multi-byte encoding.
+Solution:   Only check for composing chars for utf-8. (Taro Muraoka)
+Files:	    src/ex_cmds.c
+
+Patch 7.0.090
+Problem:    Cancelling the conform() dialog on the console with Esc requires
+	    typing it twice. (Benji Fisher)
+Solution:   When the start of an escape sequence is found use 'timeoutlen' or
+	    'ttimeoutlen'.
+Files:	    src/misc1.c
+
+Patch 7.0.091
+Problem:    Using winrestview() while 'showcmd' is set causes the cursor to be
+	    displayed in the wrong position. (Yakov Lerner)
+Solution:   Set the window topline properly.
+Files:	    src/eval.c
+
+Patch 7.0.092 (after 7.0.082 and 7.0.084)
+Problem:    The list of internal function arguments is obsolete now that
+	    garbage collection is only done at the toplevel.
+Solution:   Remove the list of all arguments to internal functions.
+Files:	    src/eval.c
+
+Patch 7.0.093
+Problem:    The matchparen plugin can't handle a 'matchpairs' value where a
+	    colon is matched.
+Solution:   Change the split() that is used to change 'matchpairs' into a
+	    List.
+Files:	    runtime/plugin/matchparen.vim
+
+Patch 7.0.094
+Problem:    When a hidden buffer is made the current buffer and another file
+	    edited later, the file message will still be given.  Using
+	    ":silent" also doesn't prevent the file message. (Marvin Renich)
+Solution:   Reset the need_fileinfo flag when reading a file.  Don't set
+	    need_fileinfo when msg_silent is set.
+Files:	    src/buffer.c, src/fileio.c
+
+Patch 7.0.095
+Problem:    The Greek tutor is not available in utf-8.  "el" is used for the
+	    language, only "gr" for the country is recognized.
+Solution:   Add the utf-8 Greek tutor.  Use it for conversion to iso-8859-7
+	    and cp737.  (Lefteris Dimitroulakis)
+Files:	    runtime/tutor/Makefile, runtime/tutor/tutor.gr.utf-8,
+	    runtime/tutor/tutor.vim
+
+Patch 7.0.096
+Problem:    taglist() returns the filename relative to the tags file, while
+	    the directory of the tags file is unknown. (Hari Krishna Dara)
+Solution:   Expand the file name. (Yegappan Lakshmanan)
+Files:	    src/tag.c
+
+Patch 7.0.097
+Problem:    ":tabclose N" that closes another tab page does not remove the tab
+	    pages line.  Same problem when using the mouse.
+Solution:   Adjust the tab pages line when needed in tabpage_close_other().
+Files:	    src/ex_docmd.c
+
+Patch 7.0.098
+Problem:    Redirecting command output in a cmdline completion function
+	    doesn't work. (Hari Krishna Dara)
+Solution:   Enable redirection when redirection is started.
+Files:	    src/ex_docmd.c, src/ex_getln.c
+
+Patch 7.0.099
+Problem:    GUI: When the popup menu is visible using the scrollbar messes up
+	    the display.
+Solution:   Disallow scrolling the current window.  Redraw the popup menu
+	    after scrolling another window.
+Files:	    src/gui.c
+
+Patch 7.0.100
+Problem:    "zug" may report the wrong filename. (Lawrence Kesteloot)
+Solution:   Call home_replace() to fill NameBuff[].
+Files:	    src/spell.c
+
+Patch 7.0.101
+Problem:    When the "~/.vim/spell" directory does not exist "zg" may create
+	    a wrong directory.  "zw" doesn't work.
+Solution:   Use the directory of the file name instead of NameBuff.  For "zw"
+	    not only remove a good word but also add the word with "!".
+Files:	    src/spell.c
+
+Patch 7.0.102
+Problem:    Redrawing cmdline is not correct when using SCIM.
+Solution:   Don't call im_get_status(). (Yukihiro Nakadaira)
+Files:	    src/ex_getln.c
+
+Patch 7.0.103 (after 7.0.101)
+Problem:    Compiler warning for uninitialized variable. (Tony Mechelynck)
+Solution:   Init variable.
+Files:	    src/spell.c
+
+Patch 7.0.104
+Problem:    The CursorHoldI event only triggers once in Insert mode.  It also
+	    triggers after CTRL-V and other two-key commands.
+Solution:   Set "did_cursorhold" before getting a second key.  Reset
+	    "did_cursorhold" after handling a command.
+Files:	    src/edit.c, src/fileio.c
+
+Patch 7.0.105
+Problem:    When using incremental search the statusline ruler isn't updated.
+	    (Christoph Koegl)
+Solution:   Update the statusline when it contains the ruler.
+Files:	    src/ex_getln.c
+
+Patch 7.0.106
+Problem:    The spell popup menu uses ":amenu", triggering mappings.  Other
+	    PopupMenu autocommands are removed. (John Little)
+Solution:   Use ":anoremenu" and use an autocmd group.
+Files:	    runtime/menu.vim
+
+Patch 7.0.107
+Problem:    Incremental search doesn't redraw the text tabline. (Ilya Bobir)
+	    Also happens in other situations with one window in a tab page.
+Solution:   Redraw the tabline after clearing the screen.
+Files:	    src/screen.c
+
+Patch 7.0.108 (extra)
+Problem:    Amiga: Compilation problem.
+Solution:   Have mch_mkdir() return a failure flag. (Willy Catteau)
+Files:	    src/os_amiga.c, src/proto/os_amiga.pro
+
+Patch 7.0.109
+Problem:    Lisp indenting is confused by escaped quotes in strings. (Dorai
+	    Sitaram)
+Solution:   Check for backslash inside strings. (Sergey Khorev)
+Files:	    src/misc1.c
+
+Patch 7.0.110
+Problem:    Amiga: Compilation problems when not using libnix.
+Solution:   Change a few #ifdefs. (Willy Catteau)
+Files:	    src/memfile.c
+
+Patch 7.0.111
+Problem:    The gzip plugin can't handle filenames with single quotes.
+Solution:   Add and use the shellescape() function. (partly by Alexey Froloff)
+Files:	    runtime/autoload/gzip.vim, runtime/doc/eval.txt, src/eval.c,
+	    src/mbyte.c, src/misc2.c, src/proto/misc2.pro
+
+Patch 7.0.112
+Problem:    Python interface does not work with Python 2.5.
+Solution:   Change PyMem_DEL() to Py_DECREF(). (Sumner Hayes)
+Files:	    src/if_python.c
+
+Patch 7.0.113
+Problem:    Using CTRL-L in Insert completion when there is no current match
+	    may cause a crash. (Yukihiro Nakadaira)
+Solution:   Check for compl_leader to be NULL
+Files:	    src/edit.c
+
+Patch 7.0.114
+Problem:    When aborting an insert with CTRL-C an extra undo point is
+	    created in the GUI. (Yukihiro Nakadaira)
+Solution:   Call gotchars() only when advancing.
+Files:	    src/getchar.c
+
+Patch 7.0.115
+Problem:    When 'ignorecase' is set, Insert mode completion only adds "foo"
+	    and not "Foo" when both are found.
+	    A found match isn't displayed right away when 'completeopt' does
+	    not have "menu" or "menuone".
+Solution:   Do not ignore case when checking if a completion match already
+	    exists.  call ins_compl_check_keys() also when not using a popup
+	    menu. (Yukihiro Nakadaira)
+Files:	    src/edit.c
+
+Patch 7.0.116
+Problem:    64 bit Windows version reports "32 bit" in the ":version" output.
+	    (M. Veerman)
+Solution:   Change the text for Win64.
+Files:	    src/version.c
+
+Patch 7.0.117
+Problem:    Using "extend" on a syntax item inside a region with "keepend", an
+	    intermediate item may be truncated.
+	    When applying the "keepend" and there is an offset to the end
+	    pattern the highlighting of a contained item isn't adjusted.
+Solution:   Use the seen_keepend flag to remember when to apply the "keepend"
+	    flag.  Adjust the keepend highlighting properly. (Ilya Bobir)
+Files:	    src/syntax.c
+
+Patch 7.0.118
+Problem:    printf() does not do zero padding for strings.
+Solution:   Do allow zero padding for strings.
+Files:	    src/message.c
+
+Patch 7.0.119
+Problem:    When going back from Insert to Normal mode the CursorHold event
+	    doesn't trigger. (Yakov Lerner)
+Solution:   Reset "did_cursorhold" when leaving Insert mode.
+Files:	    src/edit.c
+
+Patch 7.0.120
+Problem:    Crash when using CTRL-R = at the command line and entering
+	    "getreg('=')". (James Vega)
+Solution:   Avoid recursiveness of evaluating the = register.
+Files:	    src/ops.c
+
+Patch 7.0.121
+Problem:    GUI: Dragging the last status line doesn't work when there is a
+	    text tabline.  (Markus Wolf)
+Solution:   Take the text tabline into account when deciding to start modeless
+	    selection.
+Files:	    src/gui.c
+
+Patch 7.0.122
+Problem:    GUI: When clearing after a bold, double-wide character half a
+	    character may be drawn.
+Solution:   Check for double-wide character and redraw it. (Yukihiro Nakadaira)
+Files:	    src/screen.c
+
+Patch 7.0.123
+Problem:    On SCO Openserver configure selects the wrong terminal library.
+Solution:   Put terminfo before the other libraries. (Roger Cornelius)
+	    Also fix a small problem compiling on Mac without Darwin.
+Files:	    src/configure.in, src/auto/configure
+
+Patch 7.0.124
+Problem:    getwinvar() obtains a dictionary with window-local variables, but
+	    it's always for the current window.
+Solution:   Get the variables of the specified window. (Geoff Reedy)
+Files:	    src/eval.c
+
+Patch 7.0.125
+Problem:    When "autoselect" is in the 'clipboard' option then the '< and '>
+	    marks are set while Visual mode is still active.
+Solution:   Don't set the '< and '> marks when yanking the selected area for
+	    the clipboard.
+Files:	    src/normal.c
+
+Patch 7.0.126
+Problem:    When 'formatexpr' uses setline() and later internal formatting is
+	    used undo information is not correct. (Jiri Cerny, Benji Fisher)
+Solution:   Set ins_need_undo after using 'formatexpr'.
+Files:	    src/edit.c
+
+Patch 7.0.127
+Problem:    Crash when swap files has invalid timestamp.
+Solution:   Check return value of ctime() for being NULL.
+Files:	    src/memline.c
+
+Patch 7.0.128
+Problem:    GUI: when closing gvim is cancelled because there is a changed
+	    buffer the screen isn't updated to show the changed buffer in the
+	    current window.  (Krzysztof Kacprzak)
+Solution:   Redraw when closing gvim is cancelled.
+Files:	    src/gui.c
+
+Patch 7.0.129
+Problem:    GTK GUI: the GTK file dialog can't handle a relative path.
+Solution:   Make the initial directory a full path before passing it to GTK.
+	    (James Vega)  Also postpone adding the default file name until
+	    after setting the directory.
+Files:	    src/gui_gtk.c
+
+Patch 7.0.130 (extra)
+Problem:    Win32: Trying to edit or write devices may cause Vim to get stuck.
+Solution:   Add the 'opendevice' option, default off.  Disallow
+	    reading/writing from/to devices when it's off.
+	    Also detect more devices by the full name starting with "\\.\".
+Files:	    runtime/doc/options.txt, src/fileio.c, src/option.c, src/option.h,
+	    src/os_win32.c
+
+Patch 7.0.131
+Problem:    Win32: "vim -r" does not list all the swap files.
+Solution:   Also check for swap files starting with a dot.
+Files:	    src/memline.c
+
+Patch 7.0.132 (after 7.0.130)
+Problem:    Win32: Crash when Vim reads from stdin.
+Solution:   Only use mch_nodetype() when there is a file name.
+Files:	    src/fileio.c
+
+Patch 7.0.133
+Problem:    When searching included files messages are added to the history.
+Solution:   Set msg_hist_off for messages about scanning included files.
+            Set msg_silent to avoid message about wrapping around.
+Files:	    src/edit.c, src/globals.h, src/message.c, src/search.c
+
+Patch 7.0.134
+Problem:    Crash when comparing a recursively looped List or Dictionary.
+Solution:   Limit recursiveness for comparing to 1000.
+Files:	    src/eval.c
+
+Patch 7.0.135
+Problem:    Crash when garbage collecting list or dict with loop.
+Solution:   Don't use DEL_REFCOUNT but don't recurse into Lists and
+	    Dictionaries when freeing them in the garbage collector.
+	    Also add allocated Dictionaries to the list of Dictionaries to
+	    avoid leaking memory.
+Files:	    src/eval.c, src/proto/eval.pro, src/tag.c
+
+Patch 7.0.136
+Problem:    Using "O" while matching parens are highlighted may not remove the
+	    highlighting. (Ilya Bobir)
+Solution:   Also trigger CursorMoved when a line is inserted under the cursor.
+Files:	    src/misc1.c
+
+Patch 7.0.137
+Problem:    Configure check for big features is wrong.
+Solution:   Change "==" to "=". (Martti Kuparinen)
+Files:	    src/auto/configure, src/configure.in
+
+Patch 7.0.138 (extra)
+Problem:    Mac: modifiers don't work with function keys.
+Solution:   Use GetEventParameter() to obtain modifiers. (Nicolas Weber)
+Files:	    src/gui_mac.c
+
+Patch 7.0.139
+Problem:    Using CTRL-PageUp or CTRL-PageDown in Insert mode to go to another
+	    tab page does not prepare for undo properly. (Stefano Zacchiroli)
+Solution:   Call start_arrow() before switching tab page.
+Files:	    src/edit.c
+
+Patch 7.0.140 (after 7.0.134)
+Problem:    Comparing recursively looped List or Dictionary doesn't work well.
+Solution:   Detect comparing a List or Dictionary with itself.
+Files:	    src/eval.c
+
+Patch 7.0.141
+Problem:    When pasting a while line on the command line an extra CR is added
+	    literally.
+Solution:   Don't add the trailing CR when pasting with the mouse.
+Files:	    src/ex_getln.c, src/proto/ops.pro, src/ops.c
+
+Patch 7.0.142
+Problem:    Using the middle mouse button in Select mode to paste text results
+	    in an extra "y". (Kriton Kyrimis)
+Solution:   Let the middle mouse button replace the selected text with the
+	    contents of the clipboard.
+Files:	    src/normal.c
+
+Patch 7.0.143
+Problem:    Setting 'scroll' to its default value was not handled correctly.
+Solution:   Compare the right field to PV_SCROLL.
+Files:	    src/option.c
+
+Patch 7.0.144
+Problem:    May compare two unrelated pointers when matching a pattern against
+	    a string.  (Dominique Pelle)
+Solution:   Avoid calling reg_getline() when REG_MULTI is false.
+Files:	    src/regexp.c
+
+Patch 7.0.145 (after 7.0.142)
+Problem:    Compiler warning.
+Solution:   Add type cast.
+Files:	    src/normal.c
+
+Patch 7.0.146
+Problem:    When 'switchbuf' is set to "usetab" and the current tab has only a
+	    quickfix window, jumping to an error always opens a new window.
+	    Also, when the buffer is open in another tab page it's not found.
+Solution:   Check for the "split" value of 'switchbuf' properly.  Search in
+	    other tab pages for the desired buffer. (Yegappan Lakshmanan)
+Files:	    src/buffer.c, src/quickfix.c
+
+Patch 7.0.147
+Problem:    When creating a session file and there are several tab pages and
+	    some windows have a local directory a short file name may be used
+	    when it's not valid. (Marius Roets)
+	    A session with multiple tab pages may result in "No Name" buffers.
+	    (Bill McCarthy)
+Solution:   Don't enter tab pages when going through the list, only use a
+	    pointer to the first window in each tab page.
+            Use "tabedit" instead of "tabnew | edit" when possible.
+Files:	    src/ex_docmd.c
+
+Patch 7.0.148
+Problem:    When doing "call a.xyz()" and "xyz" does not exist in dictionary
+	    "a" there is no error message. (Yegappan Lakshmanan)
+Solution:   Add the error message.
+Files:	    src/eval.c
+
+Patch 7.0.149
+Problem:    When resizing a window that shows "~" lines the text sometimes
+	    jumps down.
+Solution:   Remove code that uses "~" lines in some situations.  Fix the
+            computation of the screen line of the cursor.  Also set w_skipcol
+	    to handle very long lines.
+Files:	    src/misc1.c, src/window.c
+
+Patch 7.0.150
+Problem:    When resizing the Vim window scrollbinding doesn't work. (Yakov
+	    Lerner)
+Solution:   Do scrollbinding in set_shellsize().
+Files:	    src/term.c
+
+Patch 7.0.151
+Problem:    Buttons in file dialog are not according to Gnome guidelines.
+Solution:   Swap Cancel and Open buttons. (Stefano Zacchiroli)
+Files:	    src/gui_gtk.c
+
+Patch 7.0.152
+Problem:    Crash when using lesstif 2.
+Solution:   Fill in the extension field. (Ben Hutchings)
+Files:	    src/gui_xmebw.c
+
+Patch 7.0.153
+Problem:    When using cscope and opening the temp file fails Vim crashes.
+	    (Kaya Bekiroglu)
+Solution:   Check for NULL pointer returned from mch_open().
+Files:	    src/if_cscope.c
+
+Patch 7.0.154
+Problem:    When 'foldnextmax' is negative Vim can hang. (James Vega)
+Solution:   Avoid the fold level becoming negative.
+Files:	    src/fold.c, src/syntax.c
+
+Patch 7.0.155
+Problem:    When getchar() returns a mouse button click there is no way to get
+	    the mouse coordinates.
+Solution:   Add v:mouse_win, v:mouse_lnum and v:mouse_col.
+Files:	    runtime/doc/eval.txt, src/eval.c, src/vim.h
+
+Patch 7.0.156 (extra)
+Problem:    Vim doesn't compile for Amiga OS 4.
+Solution:   Various changes for Amiga OS4. (Peter Bengtsson)
+Files:	    src/feature.h, src/mbyte.c, src/memfile.c, src/memline.c,
+	    src/os_amiga.c, src/os_amiga.h, src/pty.c
+
+Patch 7.0.157
+Problem:    When a function is used recursively the profiling information is
+	    invalid. (Mikolaj Machowski)
+Solution:   Put the start time on the stack instead of in the function.
+Files:	    src/eval.c
+
+Patch 7.0.158
+Problem:    In a C file with ":set foldmethod=syntax", typing {<CR> on the
+	    last line results in the cursor being in a closed fold. (Gautam
+	    Iyer)
+Solution:   Open fold after inserting a new line.
+Files:	    src/edit.c
+
+Patch 7.0.159
+Problem:    When there is an I/O error in the swap file the cause of the error
+	    cannot be seen.
+Solution:   Use PERROR() instead of EMSG() where possible.
+Files:	    src/memfile.c
+
+Patch 7.0.160
+Problem:    ":@a" echoes the command, Vi doesn't do that.
+Solution:   Set the silent flag in the typeahead buffer to avoid echoing the
+	    command.
+Files:	    src/ex_docmd.c, src/normal.c, src/ops.c, src/proto/ops.pro
+
+Patch 7.0.161
+Problem:    Win32: Tab pages line popup menu isn't using the right encoding.
+            (Yongwei Wu)
+Solution:   Convert the text when necessary.  Also fixes the Find/Replace
+	    dialog title. (Yegappan Lakshmanan)
+Files:	    src/gui_w48.c
+
+Patch 7.0.162
+Problem:    "vim -o a b" when file "a" triggers the ATTENTION dialog,
+	    selecting "Quit" exits Vim instead of editing "b" only.
+	    When file "b" triggers the ATTENTION dialog selecting "Quit" or
+	    "Abort" results in editing file "a" in that window.
+Solution:   When selecting "Abort" exit Vim.  When selecting "Quit" close the
+	    window.  Also avoid hit-enter prompt when selecting Abort.
+Files:	    src/buffer.c, src/main.c
+
+Patch 7.0.163
+Problem:    Can't retrieve the position of a sign after it was set.
+Solution:   Add the netbeans interface getAnno command. (Xavier de Gaye)
+Files:	    runtime/doc/netbeans.txt, src/netbeans.c
+
+Patch 7.0.164
+Problem:    ":redir @+" doesn't work.
+Solution:   Accept "@+" just like "@*". (Yegappan Lakshmanan)
+Files:	    src/ex_docmd.c
+
+Patch 7.0.165
+Problem:    Using CTRL-L at the search prompt adds a "/" and other characters
+	    without escaping, causing the pattern not to match.
+Solution:   Escape special characters with a backslash.
+Files:	    src/ex_getln.c
+
+Patch 7.0.166
+Problem:    Crash in cscope code when connection could not be opened.
+	    (Kaya Bekiroglu)
+Solution:   Check for the file descriptor to be NULL.
+Files:	    src/if_cscope.c
+
+Patch 7.0.167
+Problem:    ":function" redefining a dict function doesn't work properly.
+	    (Richard Emberson)
+Solution:   Allow a function name to be a number when it's a function
+	    reference.
+Files:	    src/eval.c
+
+Patch 7.0.168
+Problem:    Using uninitialized memory and memory leak. (Dominique Pelle)
+Solution:   Use alloc_clear() instead of alloc() for w_lines.  Free
+	    b_ml.ml_stack after recovery.
+Files:	    src/memline.c, src/window.c
+
+Patch 7.0.169
+Problem:    With a Visual block selection, with the cursor in the left upper
+	    corner, pressing "I" doesn't remove the highlighting. (Guopeng
+	    Wen)
+Solution:   When checking if redrawing is needed also check if Visual
+	    selection is still active.
+Files:	    src/screen.c
+
+Patch 7.0.170 (extra)
+Problem:    Win32: Using "gvim --remote-tab foo" when gvim is minimized while
+	    it previously was maximized, un-maximizing doesn't work properly.
+	    And the labels are not displayed properly when 'encoding' is
+	    utf-8.
+Solution:   When minimized check for SW_SHOWMINIMIZED.  When updating the tab
+	    pages line use TCM_SETITEMW instead of TCM_INSERTITEMW. (Liu
+	    Yubao)
+Files:	    src/gui_w48.c
+
+Patch 7.0.171 (extra)
+Problem:    VMS: A file name with multiple paths is written in the wrong file.
+Solution:   Get the actually used file name. (Zoltan Arpadffy)
+	    Also add info to the :version command about compilation.
+Files:	    src/Make_vms.mms, src/buffer.c, src/os_unix.c, src/version.c
+
+Patch 7.0.172
+Problem:    Crash when recovering and quitting at the "press-enter" prompt.
+Solution:   Check for "msg_list" to be NULL. (Liu Yubao)
+Files:	    src/ex_eval.c
+
+Patch 7.0.173
+Problem:    ":call f().TT()" doesn't work.  (Richard Emberson)
+Solution:   When a function returns a Dictionary or another composite continue
+	    evaluating what follows.
+Files:	    src/eval.c    
+
+Patch 7.0.174
+Problem:    ":mksession" doesn't restore window layout correctly in tab pages
+	    other than the current one. (Zhibin He)
+Solution:   Use the correct topframe for producing the window layout commands.
+Files:	    src/ex_docmd.c
+
+Patch 7.0.175
+Problem:    The result of tr() is missing the terminating NUL. (Ingo Karkat)
+Solution:   Add the NUL.
+Files:	    src/eval.c
+
+Patch 7.0.176
+Problem:    ":emenu" isn't executed directly, causing the encryption key
+	    prompt to fail. (Life Jazzer)
+Solution:   Fix wrong #ifdef.
+Files:	    src/menu.c
+
+Patch 7.0.177
+Problem:    When the press-enter prompt gets a character from a non-remappable
+	    mapping, it's put back in the typeahead buffer as remappable,
+	    which may cause an endless loop.
+Solution:   Restore the non-remappable flag and the silent flag when putting a
+	    char back in the typeahead buffer.
+Files:	    src/getchar.c, src/message.c, src/normal.c
+
+Patch 7.0.178
+Problem:    When 'enc' is "utf-8" and 'ignorecase' is set the result of ":echo
+	    ("\xe4" == "\xe4")" varies.
+Solution:   In mb_strnicmp() avoid looking past NUL bytes.
+Files:	    src/mbyte.c
+
+Patch 7.0.179
+Problem:    Using ":recover" or "vim -r" without a swapfile crashes Vim.
+Solution:   Check for "buf" to be unequal NULL. (Yukihiro Nakadaira)
+Files:	    src/memline.c
+
+Patch 7.0.180 (extra, after 7.0.171)
+Problem:    VMS: build failed.  Problem with swapfiles.
+Solution:   Add "compiled_arch".  Always expand path and pass it to
+	    buf_modname().  (Zoltan Arpadffy)
+Files:	    src/globals.h, src/memline.c, src/os_unix.c, runtime/menu.vim
+
+Patch 7.0.181
+Problem:    When reloading a file that starts with an empty line, the reloaded
+	    buffer has an extra empty line at the end. (Motty Lentzitzky)
+Solution:   Delete all lines, don't use bufempty().
+Files:	    src/fileio.c
+
+Patch 7.0.182
+Problem:    When using a mix of undo and "g-" it may no longer be possible to
+	    go to every point in the undo tree.  (Andy Wokula)
+Solution:   Correctly update pointers in the undo tree.
+Files:	    src/undo.c
+
+Patch 7.0.183
+Problem:    Crash in ":let" when redirecting to a variable that's being
+	    displayed. (Thomas Link)
+Solution:   When redirecting to a variable only do the assignment when
+	    stopping redirection to avoid that setting the variable causes a
+	    freed string to be accessed.
+Files:	    src/eval.c
+
+Patch 7.0.184
+Problem:    When the cscope program is called "mlcscope" the Cscope interface
+	    doesn't work.
+Solution:   Accept "\S*cscope:" instead of "cscope:". (Frodak D. Baksik)
+Files:	    src/if_cscope.c
+
+Patch 7.0.185
+Problem:    Multi-byte characters in a message are displayed with attributes
+	    from what comes before it.
+Solution:   Don't use the attributes for a multi-byte character.  Do use
+	    attributes for special characters. (Yukihiro Nakadaira)
+Files:	    src/message.c
+
+Patch 7.0.186
+Problem:    Get an ml_get error when 'encoding' is "utf-8" and searching for
+	    "/\_s*/e" in an empty buffer.  (Andrew Maykov)
+Solution:   Don't try getting the line just below the last line.
+Files:	    src/search.c
+
+Patch 7.0.187
+Problem:    Can't source a remote script properly.
+Solution:   Add the SourceCmd event. (Charles Campbell)
+Files:	    runtime/doc/autocmd.txt, src/ex_cmds2.c, src/fileio.c, src/vim.h
+
+Patch 7.0.188 (after 7.0.186)
+Problem:    Warning for wrong pointer type.
+Solution:   Add a type cast.
+Files:	    src/search.c
+
+Patch 7.0.189
+Problem:    Translated message about finding matches is truncated. (Yukihiro
+	    Nakadaira)
+Solution:   Enlarge the buffer.  Also use vim_snprintf().
+Files:	    src/edit.c
+
+Patch 7.0.190
+Problem:    "syntax spell default" results in an error message.
+Solution:   Change 4 to 7 for STRNICMP(). (Raul Nunez de Arenas Coronado)
+Files:	    src/syntax.c
+
+Patch 7.0.191
+Problem:    The items used by getqflist() and setqflist() don't match.
+Solution:   Support the "bufnum" item for setqflist(). (Yegappan Lakshmanan)
+Files:	    runtime/doc/eval.txt, src/quickfix.c
+
+Patch 7.0.192
+Problem:    When 'swapfile' is switched off in an empty file it is possible
+	    that not all blocks are loaded into memory, causing ml_get errors
+	    later.
+Solution:   Rename "dont_release" to "mf_dont_release" and also use it to
+	    avoid using the cached line and locked block. 
+Files:	    src/globals.h, src/memfile.c, src/memline.c
+
+Patch 7.0.193
+Problem:    Using --remote or --remote-tab with an argument that matches
+	    'wildignore' causes a crash.
+Solution:   Check the argument count before using ARGLIST[0].
+Files:	    src/ex_cmds.c
+
+Patch 7.0.194
+Problem:    Once an ml_get error is given redrawing part of the screen may
+	    cause it again, resulting in an endless loop.
+Solution:   Don't give the error message for a recursive call.
+Files:	    src/memline.c
+
+Patch 7.0.195
+Problem:    When a buffer is modified and 'autowriteall' is set, ":quit"
+	    results in an endless loop when there is a conversion error while
+	    writing. (Nikolai Weibull)
+Solution:   Make autowrite() return FAIL if the buffer is still changed after
+	    writing it.
+	    /* put the cursor on the last char, for 'tw' formatting */
+Files:	    src/ex_cmds2.c
+
+Patch 7.0.196
+Problem:    When using ":vert ball" the computation of the mouse pointer
+	    position may be off by one column. (Stefan Karlsson)
+Solution:   Recompute the frame width when moving the vertical separator from
+	    one window to another.
+Files:	    src/window.c
+
+Patch 7.0.197 (extra)
+Problem:    Win32: Compiling with EXITFREE doesn't work.
+Solution:   Adjust a few #ifdefs. (Alexei Alexandrof)
+Files:	    src/misc2.c, src/os_mswin.c
+
+Patch 7.0.198 (extra)
+Problem:    Win32: Compiler warnings.  No need to generate gvim.exe.mnf.
+Solution:   Add type casts.  Use "*" for processorArchitecture. (George Reilly)
+Files:	    src/Make_mvc.mak, src/eval.c, src/gvim.exe.mnf, src/misc2.c
+
+Patch 7.0.199
+Problem:    When using multi-byte characters the combination of completion and
+	    formatting may result in a wrong cursor position.
+Solution:   Don't decrement the cursor column, use dec_cursor(). (Yukihiro
+	    Nakadaira)  Also check for the column to be zero.
+Files:	    src/edit.c
+
+Patch 7.0.200
+Problem:    Memory leaks when out of memory.
+Solution:   Free the memory.
+Files:	    src/edit.c, src/diff.c
+
+Patch 7.0.201
+Problem:    Message for ":diffput" about buffer not being in diff mode may be
+	    wrong.
+Solution:   Check for buffer in diff mode but not modifiable.
+Files:	    src/diff.c
+
+Patch 7.0.202
+Problem:    Problems on Tandem systems while compiling and at runtime.
+Solution:   Recognize root uid is 65535.  Check select() return value for it
+	    not being supported.  Avoid wrong function prototypes.  Mention
+	    use of -lfloss.  (Matthew Woehlke)
+Files:	    src/Makefile, src/ex_cmds.c, src/fileio.c, src/main.c,
+	    src/osdef1.h.in, src/osdef2.h.in, src/os_unix.c, src/pty.c,
+	    src/vim.h
+
+Patch 7.0.203
+Problem:    0x80 characters in a register are not handled correctly for the
+	    "@" command.
+Solution:   Escape CSI and 0x80 characters. (Yukihiro Nakadaira)
+Files:	    src/ops.c
+
+Patch 7.0.204
+Problem:    Cscope: Parsing matches for listing isn't done properly.
+Solution:   Check for line number being found. (Yu Zhao)
+Files:	    src/if_cscope.c
+
+Patch 7.0.205 (after 7.0.203)
+Problem:    Can't compile.
+Solution:   Always include the vim_strsave_escape_csi function.
+Files:	    src/getchar.c
+
+Patch 7.0.206 (after 7.0.058)
+Problem:    Some characters of the "gb18030" encoding are not handled
+	    properly.
+Solution:   Do not use "cp936" as an alias for "gb18030" encoding.  Instead
+	    initialize 'encoding' to "cp936".
+Files:	    src/mbyte.c, src/option.c
+
+Patch 7.0.207
+Problem:    After patch 2.0.203 CSI and K_SPECIAL characters are escaped when
+	    recorded and then again when the register is executed.
+Solution:   Remove escaping before putting the recorded characters in a
+	    register.  (Yukihiro Nakadaira)
+Files:	    src/getchar.c, src/ops.c, src/proto/getchar.pro
+
+Patch 7.0.208 (after 7.0.171 and 7.0.180)
+Problem:    VMS: changes to path handling cause more trouble than they solve.
+Solution:   Revert changes.
+Files:	    src/buffer.c, src/memline.c, src/os_unix.c
+
+Patch 7.0.209
+Problem:    When replacing a line through Python the cursor may end up beyond
+	    the end of the line.
+Solution:   Check the cursor column after replacing the line.
+Files:	    src/if_python.c
+
+Patch 7.0.210
+Problem:    ":cbuffer" and ":lbuffer" always fail when the buffer is modified.
+	    (Gary Johnson)
+Solution:   Support adding a !. (Yegappan Lakshmanan)
+Files:	    runtime/doc/quickfix.txt, src/ex_cmds.h
+
+Patch 7.0.211
+Problem:    With ":set cindent noai bs=0" using CTRL-U in Insert mode will
+	    delete auto-indent.  After ":set ai" it doesn't.
+Solution:   Also check 'cindent' being set. (Ryan Lortie)
+Files:	    src/edit.c
+
+Patch 7.0.212
+Problem:    The GUI can't be terminated with SIGTERM. (Mark Logan)
+Solution:   Use the signal protection in the GUI as in the console, allow
+	    signals when waiting for 100 msec or longer.
+Files:	    src/ui.c
+
+Patch 7.0.213
+Problem:    When 'spellfile' has two regions that use the same sound folding
+	    using "z=" will cause memory to be freed twice. (Mark Woodward)
+Solution:   Clear the hashtable properly so that the items are only freed once.
+Files:	    src/spell.c
+
+Patch 7.0.214
+Problem:    When using <f-args> in a user command it's not possible to have an
+	    argument end in '\ '.
+Solution:   Change the handling of backslashes. (Yakov Lerner)
+Files:	    runtime/doc/map.txt, src/ex_docmd.c
+
+Patch 7.0.215 (extra)
+Problem:    Mac: Scrollbar size isn't set.  Context menu has disabled useless
+	    Help entry.  Call to MoreMasterPointers() is ignored.
+Solution:   Call SetControlViewSize() in gui_mch_set_scrollbar_thumb().  Use
+	    kCMHelpItemRemoveHelp for ContextualMenuSelect().  Remove call to
+	    MoreMasterPointers(). (Nicolas Weber)
+Files:	    src/gui_mac.c
+
+Patch 7.0.216
+Problem:    ":tab wincmd ]" does not open a tab page. (Tony Mechelynck)
+Solution:   Copy the cmdmod.tab value to postponed_split_tab and use it.
+Files:	    src/globals.h, src/ex_docmd.c, src/if_cscope.c, src/window.c
+
+Patch 7.0.217
+Problem:    This hangs when pressing "n": ":%s/\n/,\r/gc". (Ori Avtalion)
+Solution:   Set "skip_match" to advance to the next line.
+Files:	    src/ex_cmds.c
+
+Patch 7.0.218
+Problem:    "%B" in 'statusline' always shows zero in Insert mode. (DervishD)
+Solution:   Remove the exception for Insert mode, check the column for being
+	    valid instead.
+Files:	    src/buffer.c
+
+Patch 7.0.219
+Problem:    When using the 'editexisting.vim' script and a file is being
+	    edited in another tab page the window is split.  The "+123"
+	    argument is not used.
+Solution:   Make the tab page with the file the current tab page.  Set
+	    v:swapcommand when starting up to the first "+123" or "-c" command
+	    line argument.
+Files:	    runtime/macros/editexisting.vim, src/main.c
+
+Patch 7.0.220
+Problem:    Crash when using winnr('#') in a new tab page. (Andy Wokula)
+Solution:   Check for not finding the window.
+Files:	    src/eval.c
+
+Patch 7.0.221
+Problem:    finddir() uses 'path' by default, where "." means relative to the
+	    current file.  But it works relative to the current directory.
+	    (Tye Zdrojewski)
+Solution:   Add the current buffer name to find_file_in_path_option() for the
+	    relative file name.
+Files:	    runtime/doc/eval.txt, src/eval.c
+
+Patch 7.0.222
+Problem:    Perl indenting using 'cindent' works almost right.
+Solution:   Recognize '#' to start a comment. (Alex Manoussakis)  Added '#'
+	    flag in 'cinoptions'.
+Files:	    runtime/doc/indent.txt, src/misc1.c
+
+Patch 7.0.223
+Problem:    Unprintable characters in completion text mess up the popup menu.
+	    (Gombault Damien)
+Solution:   Use strtrans() to make the text printable.
+Files:	    src/charset.c, src/popupmnu.c
+
+Patch 7.0.224
+Problem:    When expanding "##" spaces are escaped twice.  (Pavol Juhas)
+Solution:   Don't escape the spaces that separate arguments.
+Files:	    src/eval.c, src/ex_docmd.c, src/proto/ex_docmd.pro
+
+Patch 7.0.225
+Problem:    When using setline() in an InsertEnter autocommand and doing "A"
+	    the cursor ends up on the last byte in the line. (Yukihiro
+	    Nakadaira)
+Solution:   Only adjust the column when using setline() for the cursor line.
+	    Move it back to the head byte if necessary.
+Files:	    src/eval.c, src/misc2.c
+
+Patch 7.0.226
+Problem:    Display flickering when updating signs through the netbeans
+	    interface. (Xavier de Gaye)
+Solution:   Remove the redraw_later(CLEAR) call.
+Files:	    src/netbeans.c
+
+Patch 7.0.227
+Problem:    Crash when closing a window in the GUI. (Charles Campbell)
+Solution:   Don't call out_flush() from win_free().
+Files:	    src/window.c
+
+Patch 7.0.228
+Problem:    Cygwin: problem with symlink to DOS style path.
+Solution:   Invoke cygwin_conv_to_posix_path(). (Luca Masini)
+Files:	    src/os_unix.c
+
+Patch 7.0.229
+Problem:    When 'pastetoggle' starts with Esc then pressing Esc in Insert
+	    mode will not time out. (Jeffery Small)
+Solution:   Use KL_PART_KEY instead of KL_PART_MAP, so that 'ttimeout' applies
+	    to the 'pastetoggle' key.
+Files:	    src/getchar.c
+
+Patch 7.0.230
+Problem:    After using ":lcd" a script doesn't know how to restore the
+	    current directory.
+Solution:   Add the haslocaldir() function. (Bob Hiestand)
+Files:	    runtime/doc/usr_41.txt, runtime/doc/eval.txt, src/eval.c
+
+Patch 7.0.231
+Problem:    When recovering from a swap file the page size is likely to be
+	    different from the minimum.  The block used for the first page
+	    then has a buffer of the wrong size, causing a crash when it's
+	    reused later.  (Zephaniah Hull)
+Solution:   Reallocate the buffer when the page size changes.  Also check that
+	    the page size is at least the minimum value.
+Files:	    src/memline.c
+
+Patch 7.0.232 (extra)
+Problem:    Mac: doesn't support GUI tab page labels.
+Solution:   Add GUI tab page labels. (Nicolas Weber)
+Files:	    src/feature.h, src/gui.c, src/gui.h, src/gui_mac.c,
+	    src/proto/gui_mac.pro
+
+Patch 7.0.233 (extra)
+Problem:    Mac: code formatted badly.
+Solution:   Fix code formatting
+Files:	    src/gui_mac.c
+
+Patch 7.0.234
+Problem:    It's possible to use feedkeys() from a modeline.  That is a
+	    security issue, can be used for a trojan horse.
+Solution:   Disallow using feedkeys() in the sandbox.
+Files:	    src/eval.c
+
+Patch 7.0.235
+Problem:    It is possible to use writefile() in the sandbox.
+Solution:   Add a few more checks for the sandbox.
+Files:	    src/eval.c
+
+Patch 7.0.236
+Problem:    Linux 2.4 uses sysinfo() with a mem_unit field, which is not
+	    backwards compatible.
+Solution:   Add an autoconf check for sysinfo.mem_unit.  Let mch_total_mem()
+	    return Kbyte to avoid overflow.
+Files:	    src/auto/configure, src/configure.in, src/config.h.in,
+	    src/option.c, src/os_unix.c
+
+Patch 7.0.237
+Problem:    For root it is recommended to not use 'modeline', but in
+	    not-compatible mode the default is on.
+Solution:   Let 'modeline' default to off for root.
+Files:	    runtime/doc/options.txt, src/option.c
+
+Patch 7.0.238
+Problem:    Crash when ":match" pattern runs into 'maxmempattern'. (Yakov
+	    Lerner)
+Solution:   Don't free the regexp program of match_hl.
+Files:	    src/screen.c
+
+Patch 7.0.239
+Problem:    When using local directories and tab pages ":mksession" uses a
+	    short file name when it shouldn't.  Window-local options from a
+	    modeline may be applied to the wrong window. (Teemu Likonen)
+Solution:   Add the did_lcd flag, use the full path when it's set.  Don't use
+	    window-local options from the modeline when using the current
+	    window for another buffer in ":doautoall".
+Files:	    src/fileio.c,  src/ex_docmd.c
+
+Patch 7.0.240
+Problem:    Crash when splitting a window in the GUI. (opposite of 7.0.227)
+Solution:   Don't call out_flush() from win_alloc().  Also avoid this for
+	    win_delete().  Also block autocommands while the window structure
+	    is invalid.
+Files:	    src/window.c
+
+Patch 7.0.241
+Problem:    ":windo throw 'foo'" loops forever. (Andy Wokula)
+Solution:   Detect that win_goto() doesn't work.
+Files:	    src/ex_cmds2.c
+
+Patch 7.0.242 (extra)
+Problem:    Win32: Using "-register" in a Vim that does not support OLE causes
+	    a crash.
+Solution:   Don't use EMSG() but mch_errmsg().  Check p_go for being NULL.
+	    (partly by Michael Wookey)
+Files:	    src/gui_w32.c
+
+Patch 7.0.243 (extra)
+Problem:    Win32: When GvimExt is built with MSVC 2005 or later, the "Edit
+	    with vim" context menu doesn't appear in the Windows Explorer.
+Solution:   Embed the linker manifest file into the resources of GvimExt.dll.
+	    (Mathias Michaelis)
+Files:	    src/GvimExt/Makefile
+
+
+Fixes after Vim 7.1a BETA:
+
+The extra archive had CVS directories included below "farsi" and
+"runtime/icons".  CVS was missing the farsi icon files.
+
+Fix compiling with Gnome 2.18, undefine bind_textdomain_codeset. (Daniel
+Drake)
+
+Mac: "make install" didn't copy rgb.txt.
+
+When editing a compressed file while there are folds caused "ml_get" errors
+and some lines could be missing.  When decompressing failed option values were
+not restored.
+
+
+Patch 7.1a.001
+Problem:    Crash when downloading a spell file.  (Szabolcs Horvat)
+Solution:   Avoid that did_set_spelllang() is used recursively when a new
+	    window is opened for the download.
+	    Also avoid wiping out the wrong buffer.
+Files:	    runtime/autoload/spellfile.vim, src/buffer.c, src/ex_cmds.c,
+            src/spell.c
+
+Patch 7.1a.002 (extra)
+Problem:    Compilation error with MingW.
+Solution:   Check for LPTOOLTIPTEXT to be defined.
+Files:	    src/gui_w32.c
+
+
+Fixes after Vim 7.1b BETA:
+
+Made the Mzscheme interface build both with old and new versions of Mzscheme,
+using an #ifdef. (Sergey Khorev)
+Mzscheme interface didn't link, missing function.  Changed order of libraries
+in the configure script.
+
+Ruby interface didn't compile on Mac.  Changed #ifdef. (Kevin Ballard)
+
+Patch 7.1b.001 (extra)
+Problem:    Random text in a source file.  No idea how it got there.
+Solution:   Delete the text.
+Files:	    src/gui_w32.c
+
+Patch 7.1b.002
+Problem:    When 'maxmem' is large there can be an overflow in computations.
+	    (Thomas Wiegner)
+Solution:   Use the same mechanism as in mch_total_mem(): first reduce the
+	    multiplier as much as possible.
+Files:	    src/memfile.c
+
+
+
+ vim:tw=78:ts=8:ft=help:norl:
--- /dev/null
+++ b/lib/vimfiles/doc/vi_diff.txt
@@ -1,0 +1,1006 @@
+*vi_diff.txt*   For Vim version 7.1.  Last change: 2007 May 07
+
+
+		  VIM REFERENCE MANUAL    by Bram Moolenaar
+
+
+Differences between Vim and Vi				*vi-differences*
+
+Throughout the help files differences between Vim and Vi/Ex are given in
+curly braces, like "{not in Vi}".  This file only lists what has not been
+mentioned in other files and gives an overview.
+
+Vim is mostly POSIX 1003.2-1 compliant.  The only command known to be missing
+is ":open".  There are probably a lot of small differences (either because Vim
+is missing something or because Posix is beside the mark).
+
+1. Simulated command			|simulated-command|
+2. Missing options			|missing-options|
+3. Limits				|limits|
+4. The most interesting additions	|vim-additions|
+5. Other vim features			|other-features|
+6. Command-line arguments		|cmdline-arguments|
+7. POSIX compliance			|posix-compliance|
+
+==============================================================================
+1. Simulated command					*simulated-command*
+
+This command is in Vi, but Vim only simulates it:
+
+							*:o* *:op* *:open*
+:[range]o[pen]			Works like |:visual|: end Ex mode.
+				{Vi: start editing in open mode}
+
+:[range]o[pen] /pattern/	As above, additionally move the cursor to the
+				column where "pattern" matches in the cursor
+				line.
+
+Vim does not support open mode, since it's not really useful.  For those
+situations where ":open" would start open mode Vim will leave Ex mode, which
+allows executing the same commands, but updates the whole screen instead of
+only one line.
+
+==============================================================================
+2. Missing options					*missing-options*
+
+These options are in the Unix Vi, but not in Vim.  If you try to set one of
+them you won't get an error message, but the value is not used and cannot be
+printed.
+
+autoprint (ap)		boolean	(default on)		*'autoprint'* *'ap'*
+beautify (bf)		boolean	(default off)		*'beautify'* *'bf'*
+flash (fl)		boolean	(default ??)		*'flash'* *'fl'*
+graphic (gr)		boolean	(default off)		*'graphic'* *'gr'*
+hardtabs (ht)		number	(default 8)		*'hardtabs'* *'ht'*
+	number of spaces that a <Tab> moves on the display
+mesg			boolean	(default on)		*'mesg'*
+novice			boolean	(default off)		*'novice'*
+open			boolean	(default on)		*'open'*
+optimize (op)		boolean	(default off)		*'optimize'* *'op'*
+redraw			boolean	(default off)		*'redraw'*
+slowopen (slow)		boolean	(default off)		*'slowopen'* *'slow'*
+sourceany		boolean	(default off)		*'sourceany'*
+w300			number	(default 23)		*'w300'*
+w1200			number	(default 23)		*'w1200'*
+w9600			number	(default 23)		*'w9600'*
+
+==============================================================================
+3. Limits						*limits*
+
+Vim has only a few limits for the files that can be edited {Vi: can not handle
+<Nul> characters and characters above 128, has limited line length, many other
+limits}.
+							*E340*
+Maximum line length	   On machines with 16-bit ints (Amiga and MS-DOS real
+			   mode): 32767, otherwise 2147483647 characters.
+			   Longer lines are split.
+Maximum number of lines	   2147483647 lines.
+Maximum file size	   2147483647 bytes (2 Gbyte) when a long integer is
+			   32 bits.  Much more for 64 bit longs.  Also limited
+			   by available disk space for the |swap-file|.
+							*E75*
+Length of a file path	   Unix and Win32: 1024 characters, otherwise 256
+			   characters (or as much as the system supports).
+Length of an expanded string option
+			   Unix and Win32: 1024 characters, otherwise 256
+			   characters
+Maximum display width	   Unix and Win32: 1024 characters, otherwise 255
+			   characters
+Maximum lhs of a mapping   50 characters.
+Number of different highlighting types: over 30000
+Range of a Number variable:  -2147483648 to 2147483647 (more on 64 bit
+			   systems)
+
+Information for undo and text in registers is kept in memory, thus when making
+(big) changes the amount of (virtual) memory available limits the number of
+undo levels and the text that can be kept in registers.  Other things are also
+kept in memory:  Command-line history, error messages for Quickfix mode, etc.
+
+Memory usage limits
+-------------------
+
+The option 'maxmem' ('mm') is used to set the maximum memory used for one
+buffer (in kilobytes).  'maxmemtot' is used to set the maximum memory used for
+all buffers (in kilobytes).  The defaults depend on the system used.  For the
+Amiga and MS-DOS, 'maxmemtot' is set depending on the amount of memory
+available.
+These are not hard limits, but tell Vim when to move text into a swap file.
+If you don't like Vim to swap to a file, set 'maxmem' and 'maxmemtot' to a
+very large value.  The swap file will then only be used for recovery.  If you
+don't want a swap file at all, set 'updatecount' to 0, or use the "-n"
+argument when starting Vim.
+
+==============================================================================
+4. The most interesting additions			*vim-additions*
+
+Vi compatibility.					|'compatible'|
+	Although Vim is 99% Vi compatible, some things in Vi can be
+	considered to be a bug, or at least need improvement.  But still, Vim
+	starts in a mode which behaves like the "real" Vi as much as possible.
+	To make Vim behave a little bit better, try resetting the 'compatible'
+	option:
+		:set nocompatible
+	Or start Vim with the "-N" argument:
+		vim -N
+	Vim starts with 'nocompatible' automatically if you have a .vimrc
+	file.  See |startup|.
+	The 'cpoptions' option can be used to set Vi compatibility on/off for
+	a number of specific items.
+
+Support for different systems.
+	Vim can be used on:
+	- All Unix systems (it works on all systems it was tested on, although
+	  the GUI and Perl interface may not work everywhere).
+	- Amiga (500, 1000, 1200, 2000, 3000, 4000, ...).
+	- MS-DOS in real-mode (no additional drivers required).
+	- In protected mode on Windows 3.1 and MS-DOS (DPMI driver required).
+	- Windows 95 and Windows NT, with support for long file names.
+	- OS/2 (needs emx.dll)
+	- Atari MiNT
+	- VMS
+	- BeOS
+	- Macintosh
+	- Risc OS
+	- IBM OS/390
+	Note that on some systems features need to be disabled to reduce
+	resource usage, esp. on MS-DOS.  For some outdated systems you need to
+	use an older Vim version.
+
+Multi level undo.					|undo|
+	'u' goes backward in time, 'CTRL-R' goes forward again.  Set option
+	'undolevels' to the number of changes to be remembered (default 1000).
+	Set 'undolevels' to 0 for a vi-compatible one level undo.  Set it to
+	-1 for no undo at all.
+	When all changes in a buffer have been undone, the buffer is not
+	considered changed anymore.  You can exit it with :q, without <!>.
+	When undoing a few changes and then making a new change Vim will
+	create a branch in the undo tree.  This means you can go back to any
+	state of the text, there is no risk of a change causing text to be
+	lost forever. |undo-tree|
+
+Graphical User Interface (GUI).				|gui|
+	Included support for GUI: menu's, mouse, scrollbars, etc.  You can
+	define your own menus.  Better support for CTRL/SHIFT/ALT keys in
+	combination with special keys and mouse.  Supported for various
+	platforms, such as X11 (with Motif and Athena interfaces), GTK, Win32
+	(Windows 95 and later), BeOS, Amiga and Macintosh.
+
+Multiple windows and buffers.				|windows.txt|
+	Vim can split the screen into several windows, each editing a
+	different buffer or the same buffer at a different location.  Buffers
+	can still be loaded (and changed) but not displayed in a window.  This
+	is called a hidden buffer.  Many commands and options have been added
+	for this facility.
+	Vim can also use multiple tab pages, each with one or more windows.  A
+	line with tab labels can be used to quickly switch between these pages.
+	|tab-page|
+
+Syntax highlighting.					|:syntax|
+	Vim can highlight keywords, patterns and other things.  This is
+	defined by a number of |:syntax| commands, and can be made to
+	highlight most languages and file types.  A number of files are
+	included for highlighting the most common languages, like C, C++,
+	Java, Pascal, Makefiles, shell scripts, etc.  The colors used for
+	highlighting can be defined for ordinary terminals, color terminals
+	and the GUI with the |:highlight| command.  A convenient way to do
+	this is using a |:colorscheme| command.
+	The highlighted text can be exported as HTML. |convert-to-HTML|
+	Other items that can be highlighted are matches with the search string
+	|'hlsearch'|, matching parens |matchparen| and the cursor line and
+	column |'cursorline'| |'cursorcolumn'|.
+
+Spell checking.						|spell|
+	When the 'spell' option is set Vim will highlight spelling mistakes.
+	About 40 languages are currently supported, selected with the
+	'spellang' option.  In source code only comments and strings are
+	checked for spelling.
+
+Folding.						|folding|
+	A range of lines can be shown as one "folded" line.  This allows
+	overviewing a file and moving blocks of text around quickly.
+	Folds can be created manually, from the syntax of the file, by indent,
+	etc.
+
+Diff mode.						|diff|
+	Vim can show two versions of a file with the differences highlighted.
+	Parts of the text that are equal are folded away.  Commands can be
+	used to move text from one version to the other.
+
+Plugins.						|add-plugin|
+	The functionality can be extended by dropping a plugin file in the
+	right directory.  That's an easy way to start using Vim scripts
+	written by others.  Plugins can be for all kind of files, or
+	specifically for a filetype.
+
+Repeat a series of commands.				|q|
+	"q{c}" starts recording typed characters into named register {c}.
+	A subsequent "q" stops recording.  The register can then be executed
+	with the "@{c}" command.  This is very useful to repeat a complex
+	action.
+
+Flexible insert mode.					|ins-special-special|
+	The arrow keys can be used in insert mode to move around in the file.
+	This breaks the insert in two parts as far as undo and redo is
+	concerned.
+
+	CTRL-O can be used to execute a single Normal mode command.  This is
+	almost the same as hitting <Esc>, typing the command and doing |a|.
+
+Visual mode.						|Visual-mode|
+	Visual mode can be used to first highlight a piece of text and then
+	give a command to do something with it.  This is an (easy to use)
+	alternative to first giving the operator and then moving to the end of
+	the text to be operated upon.
+	|v| and |V| are used to start Visual mode.  |v| works on characters
+	and |V| on lines.  Move the cursor to extend the Visual area.  It is
+	shown highlighted on the screen.  By typing "o" the other end of the
+	Visual area can be moved.  The Visual area can be affected by an
+	operator:
+		d	delete
+		c	change
+		y	yank
+		> or <	insert or delete indent
+		!	filter through external program
+		=	filter through indent
+		:	start |:| command for the Visual lines.
+		gq	format text to 'textwidth' columns
+		J	join lines
+		~	swap case
+		u	make lowercase
+		U	make uppercase
+
+Block operators.					|visual-block|
+	With Visual mode a rectangular block of text can be selected.  Start
+	Visual mode with CTRL-V.  The block can be deleted ("d"), yanked ("y")
+	or its case can be changed ("~", "u" and "U").  A deleted or yanked
+	block can be put into the text with the "p" and "P" commands.
+
+Help system.						|:help|
+	Help is displayed in a window.  The usual commands can be used to
+	move around, search for a string, etc.  Tags can be used to jump
+	around in the help files, just like hypertext links.  The |:help|
+	command takes an argument to quickly jump to the info on a subject.
+	<F1> is the quick access to the help system.  The name of the help
+	index file can be set with the 'helpfile' option.
+
+Command-line editing and history.			|cmdline-editing|
+	You can insert or delete at any place in the command-line using the
+	cursor keys.  The right/left cursor keys can be used to move
+	forward/backward one character.  The shifted right/left cursor keys
+	can be used to move forward/backward one word.  CTRL-B/CTRL-E can be
+	used to go to the begin/end of the command-line.
+							|cmdline-history|
+	The command-lines are remembered.  The up/down cursor keys can be used
+	to recall previous command-lines.  The 'history' option can be set to
+	the number of lines that will be remembered.  There is a separate
+	history for commands and for search patterns.
+
+Command-line completion.				|cmdline-completion|
+	While entering a command-line (on the bottom line of the screen)
+	<Tab> can be typed to complete
+	   what		example		~
+	- command	:e<Tab>
+	- tag		:ta scr<Tab>
+	- option	:set sc<Tab>
+	- option value  :set hf=<Tab>
+	- file name	:e ve<Tab>
+	- etc.
+
+	If there are multiple matches, CTRL-N (next) and CTRL-P (previous)
+	will walk through the matches.  <Tab> works like CTRL-N, but wraps
+	around to the first match.
+
+	The 'wildchar' option can be set to the character for command-line
+	completion, <Tab> is the default.  CTRL-D can be typed after an
+	(incomplete) wildcard; all matches will be listed.  CTRL-A will insert
+	all matches.  CTRL-L will insert the longest common part of the
+	matches.
+
+Insert-mode completion.					|ins-completion|
+	In Insert mode the CTRL-N and CTRL-P keys can be used to complete a
+	word that appears elsewhere.	|i_CTRL-N|
+	With CTRL-X another mode is entered, through which completion can be
+	done for:
+	|i_CTRL-X_CTRL-F|	file names
+	|i_CTRL-X_CTRL-K|	words from 'dictionary' files
+	|i_CTRL-X_CTRL-T|	words from 'thesaurus' files
+	|i_CTRL-X_CTRL-I|	words from included files
+	|i_CTRL-X_CTRL-L|	whole lines
+	|i_CTRL-X_CTRL-]|	words from the tags file
+	|i_CTRL-X_CTRL-D|	definitions or macros
+	|i_CTRL-X_CTRL-O|	Omni completion: clever completion
+				specifically for a file type
+	etc.
+
+Long line support.					|'wrap'| |'linebreak'|
+	If the 'wrap' option is off, long lines will not wrap and only part
+	of them will be shown.  When the cursor is moved to a part that is not
+	shown, the screen will scroll horizontally.  The minimum number of
+	columns to scroll can be set with the 'sidescroll' option.  The |zh|
+	and |zl| commands can be used to scroll sideways.
+	Alternatively, long lines are broken in between words when the
+	'linebreak' option is set.  This allows editing a single-line
+	paragraph conveniently (e.g. when the text is later read into a DTP
+	program).  Move the cursor up/down with the |gk| and |gj| commands.
+
+Text formatting.					|formatting|
+	The 'textwidth' option can be used to automatically limit the line
+	length.  This supplements the 'wrapmargin' option of Vi, which was not
+	very useful.  The |gq| operator can be used to format a piece of text
+	(for example, |gqap| formats the current paragraph).  Commands for
+	text alignment: |:center|, |:left| and |:right|.
+
+Extended search patterns.				|pattern|
+	There are many extra items to match various text items.  Examples:
+	A "\n" can be used in a search pattern to match a line break.
+	"x\{2,4}" matches "x" 2 to 4 times.
+	"\s" matches a white space character.
+
+Directory, remote and archive browsing.			|netrw|
+	Vim can browse the file system.  Simply edit a directory.  Move around
+	in the list with the usual commands and press <Enter> to go to the
+	directory or file under the cursor.
+	This also works for remote files over ftp, http, ssh, etc.
+	Zip and tar archives can also be browsed. |tar| |zip|
+
+Edit-compile-edit speedup.				|quickfix|
+	The |:make| command can be used to run the compilation and jump to the
+	first error.  A file with compiler error messages is interpreted.  Vim
+	jumps to the first error.
+
+	Each line in the error file is scanned for the name of a file, line
+	number and error message.  The 'errorformat' option can be set to a
+	list of scanf-like strings to handle output from many compilers.
+
+	The |:cn| command can be used to jump to the next error.
+	|:cl| lists all the error messages.  Other commands are available.
+	The 'makeef' option has the name of the file with error messages.
+	The 'makeprg' option contains the name of the program to be executed
+	with the |:make| command.
+	The 'shellpipe' option contains the string to be used to put the
+	output of the compiler into the errorfile.
+
+Finding matches in files.				|:vimgrep|
+	Vim can search for a pattern in multiple files.  This uses the
+	advanced Vim regexp pattern, works on all systems and also works to
+	search in compressed files.
+
+Improved indenting for programs.			|'cindent'|
+	When the 'cindent' option is on the indent of each line is
+	automatically adjusted.  C syntax is mostly recognized.  The indent
+	for various styles can be set with 'cinoptions'.  The keys to trigger
+	indenting can be set with 'cinkeys'.
+
+	Comments can be automatically formatted.  The 'comments' option can be
+	set to the characters that start and end a comment.  This works best
+	for C code, but also works for e-mail (">" at start of the line) and
+	other types of text.  The |=| operator can be used to re-indent
+	lines.
+
+	For many other languages an indent plugin is present to support
+	automatic indenting. |30.3|
+
+Searching for words in included files.			|include-search|
+	The |[i| command can be used to search for a match of the word under
+	the cursor in the current and included files.  The 'include' option
+	can be set the a pattern that describes a command to include a file
+	(the default is for C programs).
+	The |[I| command lists all matches, the |[_CTRL-I| command jumps to
+	a match.
+	The |[d|, |[D| and |[_CTRL-D| commands do the same, but only for
+	lines where the pattern given with the 'define' option matches.
+
+Automatic commands.					|autocommand|
+	Commands can be automatically executed when reading a file, writing a
+	file, jumping to another buffer, etc., depending on the file name.
+	This is useful to set options and mappings for C programs,
+	documentation, plain text, e-mail, etc.  This also makes it possible
+	to edit compressed files.
+
+Scripts and Expressions.				|expression|
+	Commands have been added to form up a powerful script language.
+	|:if|		Conditional execution, which can be used for example
+			to set options depending on the value of $TERM.
+	|:while|	Repeat a number of commands.
+	|:for|		Loop over a list.
+	|:echo|		Print the result of an expression.
+	|:let|		Assign a value to an internal variable, option, etc.
+			Variable types are Number, String, List and Dictionary.
+	|:execute|	Execute a command formed by an expression.
+	|:try|		Catch exceptions.
+	etc., etc.  See |eval|.
+	Debugging and profiling are supported. |debug-scripts| |profile|
+	If this is not enough, an interface is provided to |Python|, |Ruby|,
+	|Tcl|, |Perl| and |MzScheme|.
+
+Viminfo.						|viminfo-file|
+	The command-line history, marks and registers can be stored in a file
+	that is read on startup.  This can be used to repeat a search command
+	or command-line command after exiting and restarting Vim.  It is also
+	possible to jump right back to where the last edit stopped with |'0|.
+	The 'viminfo' option can be set to select which items to store in the
+	.viminfo file.  This is off by default.
+
+Printing.						|printing|
+	The |:hardcopy| command sends text to the printer.  This can include
+	syntax highlighting.
+
+Mouse support.						|mouse-using|
+	The mouse is supported in the GUI version, in an xterm for Unix, for
+	Linux with gpm, for MS-DOS, and Win32.  It can be used to position the
+	cursor, select the visual area, paste a register, etc.
+
+Usage of key names.					|<>| |key-notation|
+	Special keys now all have a name like <Up>, <End>, etc.
+	This name can be used in mappings, to make it easy to edit them.
+
+Editing binary files.					|edit-binary|
+	Vim can edit binary files.  You can change a few characters in an
+	executable file, without corrupting it.  Vim doesn't remove NUL
+	characters (they are represented as <NL> internally).
+	|-b|		command-line argument to start editing a binary file
+	|'binary'|	Option set by |-b|.  Prevents adding an <EOL> for the
+			last line in the file.
+
+Multi-language support.					|multi-lang|
+	Files in double-byte or multi-byte encodings can be edited.  There is
+	UTF-8 support to be able to edit various languages at the same time,
+	without switching fonts. |UTF-8|
+	Messages and menus are available in different languages.
+
+Move cursor beyond lines.
+	When the 'virtualedit' option is set the cursor can move all over the
+	screen, also where there is no text.  This is useful to edit tables
+	and figures easily.
+
+==============================================================================
+5. Other vim features					*other-features*
+
+A random collection of nice extra features.
+
+
+When Vim is started with "-s scriptfile", the characters read from
+"scriptfile" are treated as if you typed them.  If end of file is reached
+before the editor exits, further characters are read from the console.
+
+The "-w" option can be used to record all typed characters in a script file.
+This file can then be used to redo the editing, possibly on another file or
+after changing some commands in the script file.
+
+The "-o" option opens a window for each argument.  "-o4" opens four windows.
+
+Vi requires several termcap entries to be able to work full-screen.  Vim only
+requires the "cm" entry (cursor motion).
+
+
+In command mode:
+
+When the 'showcmd' option is set, the command characters are shown in the last
+line of the screen.  They are removed when the command is finished.
+
+If the 'ruler' option is set, the current cursor position is shown in the
+last line of the screen.
+
+"U" still works after having moved off the last changed line and after "u".
+
+Characters with the 8th bit set are displayed.  The characters between '~' and
+0xa0 are displayed as "~?", "~@", "~A", etc., unless they are included in the
+'isprint' option.
+
+"][" goes to the next ending of a C function ('}' in column 1).
+"[]" goes to the previous ending of a C function ('}' in column 1).
+
+"]f", "[f" and "gf" start editing the file whose name is under the cursor.
+CTRL-W f splits the window and starts editing the file whose name is under
+the cursor.
+
+"*" searches forward for the identifier under the cursor, "#" backward.
+"K" runs the program defined by the 'keywordprg' option, with the identifier
+under the cursor as argument.
+
+"%" can be preceded with a count.  The cursor jumps to the line that
+percentage down in the file.  The normal "%" function to jump to the matching
+brace skips braces inside quotes.
+
+With the CTRL-] command, the cursor may be in the middle of the identifier.
+
+The used tags are remembered.  Commands that can be used with the tag stack
+are CTRL-T, ":pop" and ":tag".  ":tags" lists the tag stack.
+
+The 'tags' option can be set to a list of tag file names.  Thus multiple
+tag files can be used.  For file names that start with "./", the "./" is
+replaced with the path of the current file.  This makes it possible to use a
+tags file in the same directory as the file being edited.
+
+Previously used file names are remembered in the alternate file name list.
+CTRL-^ accepts a count, which is an index in this list.
+":files" command shows the list of alternate file names.
+"#<N>" is replaced with the <N>th alternate file name in the list.
+"#<" is replaced with the current file name without extension.
+
+Search patterns have more features.  The <NL> character is seen as part of the
+search pattern and the substitute string of ":s".  Vi sees it as the end of
+the command.
+
+Searches can put the cursor on the end of a match and may include a character
+offset.
+
+Count added to "~", ":next", ":Next", "n" and "N".
+
+The command ":next!" with 'autowrite' set does not write the file.  In vi the
+file was written, but this is considered to be a bug, because one does not
+expect it and the file is not written with ":rewind!".
+
+In Vi when entering a <CR> in replace mode deletes a character only when 'ai'
+is set (but does not show it until you hit <Esc>).  Vim always deletes a
+character (and shows it immediately).
+
+Added :wnext command.  Same as ":write" followed by ":next".
+
+The ":w!" command always writes, also when the file is write protected.  In Vi
+you would have to do ":!chmod +w %" and ":set noro".
+
+When 'tildeop' has been set, "~" is an operator (must be followed by a
+movement command).
+
+With the "J" (join) command you can reset the 'joinspaces' option to have only
+one space after a period (Vi inserts two spaces).
+
+"cw" can be used to change white space formed by several characters (Vi is
+confusing: "cw" only changes one space, while "dw" deletes all white space).
+
+"o" and "O" accept a count for repeating the insert (Vi clears a part of
+display).
+
+Flags after Ex commands not supported (no plans to include it).
+
+On non-UNIX systems ":cd" command shows current directory instead of going to
+the home directory (there isn't one).  ":pwd" prints the current directory on
+all systems.
+
+After a ":cd" command the file names (in the argument list, opened files)
+still point to the same files.  In Vi ":cd" is not allowed in a changed file;
+otherwise the meaning of file names change.
+
+":source!" command reads Vi commands from a file.
+
+":mkexrc" command writes current modified options and mappings to a ".exrc"
+file.  ":mkvimrc" writes to a ".vimrc" file.
+
+No check for "tail recursion" with mappings.  This allows things like
+":map! foo ^]foo".
+
+When a mapping starts with number, vi loses the count typed before it (e.g.
+when using the mapping ":map g 4G" the command "7g" goes to line 4).  This is
+considered a vi bug.  Vim concatenates the counts (in the example it becomes
+"74G"), as most people would expect.
+
+The :put! command inserts the contents of a register above the current line.
+
+The "p" and "P" commands of vi cannot be repeated with "." when the putted
+text is less than a line.  In Vim they can always be repeated.
+
+":noremap" command can be used to enter a mapping that will not be remapped.
+This is useful to exchange the meaning of two keys.  ":cmap", ":cunmap" and
+":cnoremap" can be used for mapping in command-line editing only.  ":imap",
+":iunmap" and ":inoremap" can be used for mapping in insert mode only.
+Similar commands exist for abbreviations: ":noreabbrev", ":iabbrev"
+":cabbrev", ":iunabbrev", ":cunabbrev", ":inoreabbrev", ":cnoreabbrev".
+
+In Vi the command ":map foo bar" would remove a previous mapping
+":map bug foo".  This is considered a bug, so it is not included in Vim.
+":unmap! foo" does remove ":map! bug foo", because unmapping would be very
+difficult otherwise (this is vi compatible).
+
+The ':' register contains the last command-line.
+The '%' register contains the current file name.
+The '.' register contains the last inserted text.
+
+":dis" command shows the contents of the yank registers.
+
+CTRL-O/CTRL-I can be used to jump to older/newer positions.  These are the
+same positions as used with the '' command, but may be in another file.  The
+":jumps" command lists the older positions.
+
+If the 'shiftround' option is set, an indent is rounded to a multiple of
+'shiftwidth' with ">" and "<" commands.
+
+The 'scrolljump' option can be set to the minimum number of lines to scroll
+when the cursor gets off the screen.  Use this when scrolling is slow.
+
+The 'scrolloff' option can be set to the minimum number of lines to keep
+above and below the cursor.  This gives some context to where you are
+editing.  When set to a large number the cursor line is always in the middle
+of the window.
+
+Uppercase marks can be used to jump between files.  The ":marks" command lists
+all currently set marks.  The commands "']" and "`]" jump to the end of the
+previous operator or end of the text inserted with the put command.  "'[" and
+"`[" do jump to the start.
+
+The 'shelltype' option can be set to reflect the type of shell used on the
+Amiga.
+
+The 'highlight' option can be set for the highlight mode to be used for
+several commands.
+
+The CTRL-A (add) and CTRL-X (subtract) commands are new.  The count to the
+command (default 1) is added to/subtracted from the number at or after the
+cursor.  That number may be decimal, octal (starts with a '0') or hexadecimal
+(starts with '0x').  Very useful in macros.
+
+With the :set command the prefix "inv" can be used to invert boolean options.
+
+In both Vi and Vim you can create a line break with the ":substitute" command
+by using a CTRL-M.  For Vi this means you cannot insert a real CTRL-M in the
+text.  With Vim you can put a real CTRL-M in the text by preceding it with a
+CTRL-V.
+
+
+In Insert mode:
+
+If the 'revins' option is set, insert happens backwards.  This is for typing
+Hebrew.  When inserting normal characters the cursor will not be shifted and
+the text moves rightwards.  Backspace, CTRL-W and CTRL-U will also work in
+the opposite direction.  CTRL-B toggles the 'revins' option.  In replace mode
+'revins' has no effect.  Only when enabled at compile time.
+
+The backspace key can be used just like CTRL-D to remove auto-indents.
+
+You can backspace, CTRL-U and CTRL-W over line breaks if the 'backspace' (bs)
+option includes "eol".  You can backspace over the start of insert if the
+'backspace' option includes "start".
+
+When the 'paste' option is set, a few option are reset and mapping in insert
+mode and abbreviation are disabled.  This allows for pasting text in windowing
+systems without unexpected results.  When the 'paste' option is reset, the old
+option values are restored.
+
+CTRL-T/CTRL-D always insert/delete an indent in the current line, no matter
+what column the cursor is in.
+
+CTRL-@ (insert previously inserted text) works always (Vi: only when typed as
+first character).
+
+CTRL-A works like CTRL-@ but does not leave insert mode.
+
+CTRL-R {0-9a-z..} can be used to insert the contents of a register.
+
+When the 'smartindent' option is set, C programs will be better auto-indented.
+With 'cindent' even more.
+
+CTRL-Y and CTRL-E can be used to copy a character from above/below the
+current cursor position.
+
+After CTRL-V you can enter a three digit decimal number.  This byte value is
+inserted in the text as a single character.  Useful for international
+characters that are not on your keyboard.
+
+When the 'expandtab' (et) option is set, a <Tab> is expanded to the
+appropriate number of spaces.
+
+The window always reflects the contents of the buffer (Vi does not do this
+when changing text and in some other cases).
+
+If Vim is compiled with DIGRAPHS defined, digraphs are supported.  A set of
+normal digraphs is included.  They are shown with the ":digraph" command.
+More can be added with ":digraph {char1}{char2} {number}".  A digraph is
+entered with "CTRL-K {char1} {char2}" or "{char1} BS {char2}" (only when
+'digraph' option is set).
+
+When repeating an insert, e.g. "10atest <Esc>" vi would only handle wrapmargin
+for the first insert.  Vim does it for all.
+
+A count to the "i" or "a" command is used for all the text.  Vi uses the count
+only for one line.  "3iabc<NL>def<Esc>" would insert "abcabcabc<NL>def" in Vi
+but "abc<NL>defabc<NL>defabc<NL>def" in Vim.
+
+
+In Command-line mode:
+
+<Esc> terminates the command-line without executing it.  In vi the command
+line would be executed, which is not what most people expect (hitting <Esc>
+should always get you back to command mode).  To avoid problems with some
+obscure macros, an <Esc> in a macro will execute the command.  If you want a
+typed <Esc> to execute the command like vi does you can fix this with
+	":cmap ^V<Esc> ^V<CR>"
+
+General:
+
+The 'ttimeout' option is like 'timeout', but only works for cursor and
+function keys, not for ordinary mapped characters.  The 'timeoutlen' option
+gives the number of milliseconds that is waited for.  If the 'esckeys' option
+is not set, cursor and function keys that start with <Esc> are not recognized
+in insert mode.
+
+There is an option for each terminal string.  Can be used when termcap is not
+supported or to change individual strings.
+
+The 'fileformat' option can be set to select the <EOL>: "dos" <CR><NL>, "unix"
+<NL> or "mac" <CR>.
+When the 'fileformats' option is not empty, Vim tries to detect the type of
+<EOL> automatically.  The 'fileformat' option is set accordingly.
+
+On systems that have no job control (older Unix systems and non-Unix systems)
+the CTRL-Z, ":stop" or ":suspend" command starts a new shell.
+
+If Vim is started on the Amiga without an interactive window for output, a
+window is opened (and :sh still works).  You can give a device to use for
+editing with the |-d| argument, e.g. "-d con:20/20/600/150".
+
+The 'columns' and 'lines' options are used to set or get the width and height
+of the display.
+
+Option settings are read from the first and last few lines of the file.
+Option 'modelines' determines how many lines are tried (default is 5).  Note
+that this is different from the Vi versions that can execute any Ex command
+in a modeline (a major security problem).  |trojan-horse|
+
+If the 'insertmode' option is set (e.g. in .exrc), Vim starts in insert mode.
+And it comes back there, when pressing <Esc>.
+
+Undo information is kept in memory.  Available memory limits the number and
+size of change that can be undone.  This may be a problem with MS-DOS, is
+hardly a problem on the Amiga and almost never with Unix and Win32.
+
+If the 'backup' or 'writebackup' option is set: Before a file is overwritten,
+a backup file (.bak) is made.  If the "backup" option is set it is left
+behind.
+
+Vim creates a file ending in ".swp" to store parts of the file that have been
+changed or that do not fit in memory.  This file can be used to recover from
+an aborted editing session with "vim -r file".  Using the swap file can be
+switched off by setting the 'updatecount' option to 0 or starting Vim with
+the "-n" option.  Use the 'directory' option for placing the .swp file
+somewhere else.
+
+Vim is able to work correctly on filesystems with 8.3 file names, also when
+using messydos or crossdos filesystems on the Amiga, or any 8.3 mounted
+filesystem under Unix.  See |'shortname'|.
+
+Error messages are shown at least one second (Vi overwrites error messages).
+
+If Vim gives the |hit-enter| prompt, you can hit any key.  Characters other
+than <CR>, <NL> and <Space> are interpreted as the (start of) a command.  (Vi
+only accepts a command starting with ':').
+
+The contents of the numbered and unnamed registers is remembered when
+changing files.
+
+The "No lines in buffer" message is a normal message instead of an error
+message, since that may cause a mapping to be aborted.
+
+The AUX: device of the Amiga is supported.
+
+==============================================================================
+6. Command-line arguments				*cmdline-arguments*
+
+Different versions of Vi have different command-line arguments.  This can be
+confusing.  To help you, this section gives an overview of the differences.
+
+Five variants of Vi will be considered here:
+	Elvis	Elvis version 2.1b
+	Nvi	Nvi version 1.79
+	Posix	Posix 1003.2
+	Vi	Vi version 3.7 (for Sun 4.1.x)
+	Vile	Vile version 7.4 (incomplete)
+	Vim	Vim version 5.2
+
+Only Vim is able to accept options in between and after the file names.
+
++{command}	Elvis, Nvi, Posix, Vi, Vim: Same as "-c {command}".
+
+-		Nvi, Posix, Vi: Run Ex in batch mode.
+		Vim: Read file from stdin (use -s for batch mode).
+
+--		Vim: End of options, only file names are following.
+
+--cmd {command}	Vim: execute {command} before sourcing vimrc files.
+
+--echo-wid	Vim: GTK+ echoes the Window ID on stdout
+
+--help		Vim: show help message and exit.
+
+--literal	Vim: take file names literally, don't expand wildcards.
+
+--nofork	Vim: same as |-f|
+
+--noplugin[s]	Vim: Skip loading plugins.
+
+--remote	Vim: edit the files in another Vim server
+
+--remote-expr {expr}	Vim: evaluate {expr} in another Vim server
+
+--remote-send {keys}	Vim: send {keys} to a Vim server and exit
+
+--remote-silent {file}	Vim: edit the files in another Vim server if possible
+
+--remote-wait	Vim: edit the files in another Vim server and wait for it
+
+--remote-wait-silent	Vim: like --remote-wait, no complaints if not possible
+
+--role {role}	Vim: GTK+ 2: set role of main window
+
+--serverlist	Vim: Output a list of Vim servers and exit
+
+--servername {name}	Vim: Specify Vim server name
+
+--socketid {id}		Vim: GTK window socket to run Vim in
+
+--version	Vim: show version message and exit.
+
+-?		Vile: print usage summary and exit.
+
+-a		Elvis: Load all specified file names into a window (use -o for
+		Vim).
+
+-A		Vim: Start in Arabic mode (when compiled with Arabic).
+
+-b {blksize}	Elvis: Use {blksize} blocksize for the session file.
+-b		Vim: set 'binary' mode.
+
+-C		Vim: Compatible mode.
+
+-c {command}	Elvis, Nvi, Posix, Vim: run {command} as an Ex command after
+		loading the edit buffer.
+		Vim: allow up to 10 "-c" arguments
+
+-d {device}	Vim: Use {device} for I/O (Amiga only). {only when compiled
+		without the |+diff| feature}
+-d		Vim: start with 'diff' set. |vimdiff|
+
+-dev {device}	Vim: Use {device} for I/O (Amiga only).
+
+-D		Vim: debug mode.
+
+-e		Elvis, Nvi, Vim: Start in Ex mode, as if the executable is
+		called "ex".
+
+-E		Vim: Start in improved Ex mode |gQ|, like "exim".
+
+-f		Vim: Run GUI in foreground (Amiga: don't open new window).
+-f {session}	Elvis: Use {session} as the session file.
+
+-F		Vim: Start in Farsi mode (when compiled with Farsi).
+		Nvi: Fast start, don't read the entire file when editing
+		starts.
+
+-G {gui}	Elvis: Use the {gui} as user interface.
+
+-g		Vim: Start GUI.
+-g N		Vile: start editing at line N
+
+-h		Vim: Give help message.
+		Vile: edit the help file
+
+-H		Vim: start Hebrew mode (when compiled with it).
+
+-i		Elvis: Start each window in Insert mode.
+-i {viminfo}	Vim: Use {viminfo} for viminfo file.
+
+-L		Vim: Same as "-r" (also in some versions of Vi).
+
+-l		Nvi, Vi, Vim: Set 'lisp' and 'showmatch' options.
+
+-m		Vim: Modifications not allowed to be written, resets 'write'
+		option.
+
+-M		Vim: Modifications not allowed, resets 'modifiable' and the
+		'write' option.
+
+-N		Vim: No-compatible mode.
+
+-n		Vim: No swap file used.
+
+-nb[args]	Vim: open a NetBeans interface connection
+
+-O[N]		Vim: Like -o, but use vertically split windows.
+
+-o[N]		Vim: Open [N] windows, or one for each file.
+
+-p[N]		Vim: Open [N] tab pages, or one for each file.
+
+-P {parent-title} Win32 Vim: open Vim inside a parent application window
+
+-q {name}	Vim: Use {name} for quickfix error file.
+-q{name}	Vim: Idem.
+
+-R		Elvis, Nvi, Posix, Vile, Vim: Set the 'readonly' option.
+
+-r		Elvis, Nvi, Posix, Vi, Vim: Recovery mode.
+
+-S		Nvi: Set 'secure' option.
+-S {script}	Vim: source script after starting up.
+
+-s		Nvi, Posix, Vim: Same as "-" (silent mode), when in Ex mode.
+		Elvis: Sets the 'safer' option.
+-s {scriptin}	Vim: Read from script file {scriptin}; only when not in Ex
+		mode.
+-s {pattern}	Vile: search for {pattern}
+
+-t {tag}	Elvis, Nvi, Posix, Vi, Vim: Edit the file containing {tag}.
+-t{tag}		Vim: Idem.
+
+-T {term}	Vim: Set terminal name to {term}.
+
+-u {vimrc}	Vim: Read initializations from {vimrc} file.
+
+-U {gvimrc}	Vim: Read GUI initializations from {gvimrc} file.
+
+-v		Nvi, Posix, Vi, Vim: Begin in Normal mode (visual mode, in Vi
+		terms).
+		Vile: View mode, no changes possible.
+
+-V		Elvis, Vim: Verbose mode.
+-V{nr}		Vim: Verbose mode with specified level.
+
+-w {size}	Elvis, Posix, Nvi, Vi, Vim: Set value of 'window' to {size}.
+-w{size}	Nvi, Vi: Same as "-w {size}".
+-w {name}	Vim: Write to script file {name} (must start with non-digit).
+
+-W {name}	Vim: Append to script file {name}.
+
+-x		Vi, Vim: Ask for encryption key.  See |encryption|.
+
+-X		Vim: Don't connect to the X server.
+
+-y		Vim: Start in easy mode, like |evim|.
+
+-Z		Vim: restricted mode
+
+@{cmdfile}	Vile: use {cmdfile} as startup file.
+
+==============================================================================
+7. POSIX compliance				*posix* *posix-compliance*
+
+In 2005 the POSIX test suite was run to check the compatibility of Vim.  Most
+of the test was executed properly.  There are the few things where Vim
+is not POSIX compliant, even when run in Vi compatibility mode.
+
+Set the $VIM_POSIX environment variable to have 'cpoptions' include the POSIX
+flags when Vim starts up.  This makes Vim run as POSIX as it can.  That's
+a bit different from being Vi compatible.
+
+This is where Vim does not behave as POSIX specifies and why:
+
+							*posix-screen-size*
+	The $COLUMNS and $LINES environment variables are ignored by Vim if
+	the size can be obtained from the terminal in a more reliable way.
+	Add the '|' flag to 'cpoptions' to have $COLUMNS and $LINES overrule
+	sizes obtained in another way.
+
+	The "{" and "}" commands don't stop at a "{" in the original Vi, but
+	POSIX specifies it does.  Add the '{' flag to 'cpoptions' if you want
+	it the POSIX way.
+
+	The "D", "o" and "O" commands accept a count.  Also when repeated.
+	Add the '#' flag to 'cpoptions' if you want to ignore the count.
+
+	The ":cd" command fails if the current buffer is modified when the '.'
+	flag is present in 'cpoptions'.
+
+	There is no ATTENTION message, the "A" flag is added to 'shortmess'.
+
+These are remarks about running the POSIX test suite:
+- vi test 33 sometimes fails for unknown reasons
+- vi test 250 fails; behavior will be changed in a new revision
+    http://www.opengroup.org/austin/mailarchives/ag-review/msg01710.html
+- vi test 310 fails; exit code non-zero when any error occurred?
+- ex test 24 fails because test is wrong.  Changed between SUSv2 and SUSv3.
+- ex tests 47, 48, 49, 72, 73 fail because .exrc file isn't read in silent
+  mode and $EXINIT isn't used.
+- ex tests 76, 78 fail because echo is used instead of printf. (fixed)
+    Also: problem with \s not changed to space.
+- ex test 355 fails because 'window' isn't used for "30z".
+- ex test 368 fails because shell command isn't echoed in silent mode.
+- ex test 394 fails because "=" command output isn't visible in silent mode.
+- ex test 411 fails because test file is wrong, contains stray ':'.
+- ex test 475 and 476 fail because reprint output isn't visible in silent mode.
+- ex test 480 and 481 fail because the tags file has spaces instead of a tab.
+- ex test 502 fails because .exrc isn't read in silent mode.
+- ex test 509 fails because .exrc isn't read in silent mode. and exit code is
+  1 instead of 2.
+- ex test 534 fails because .exrc isn't read in silent mode.
+
+
+ vim:tw=78:ts=8:ft=help:norl:
--- /dev/null
+++ b/lib/vimfiles/doc/vim.1
@@ -1,0 +1,553 @@
+.TH VIM 1 "2006 Apr 11"
+.SH NAME
+vim \- Vi IMproved, a programmers text editor
+.SH SYNOPSIS
+.br
+.B vim
+[options] [file ..]
+.br
+.B vim
+[options] \-
+.br
+.B vim
+[options] \-t tag
+.br
+.B vim
+[options] \-q [errorfile]
+.PP
+.br
+.B ex
+.br
+.B view
+.br
+.B gvim
+.B gview
+.B evim
+.B eview
+.br
+.B rvim
+.B rview
+.B rgvim
+.B rgview
+.SH DESCRIPTION
+.B Vim
+is a text editor that is upwards compatible to Vi.
+It can be used to edit all kinds of plain text.
+It is especially useful for editing programs.
+.PP
+There are a lot of enhancements above Vi: multi level undo,
+multi windows and buffers, syntax highlighting, command line
+editing, filename completion, on-line help, visual selection, etc..
+See ":help vi_diff.txt" for a summary of the differences between
+.B Vim
+and Vi.
+.PP
+While running
+.B Vim
+a lot of help can be obtained from the on-line help system, with the ":help"
+command.
+See the ON-LINE HELP section below.
+.PP
+Most often
+.B Vim
+is started to edit a single file with the command
+.PP
+	vim file
+.PP
+More generally
+.B Vim
+is started with:
+.PP
+	vim [options] [filelist]
+.PP
+If the filelist is missing, the editor will start with an empty buffer.
+Otherwise exactly one out of the following four may be used to choose one or
+more files to be edited.
+.TP 12
+file ..
+A list of filenames.
+The first one will be the current file and read into the buffer.
+The cursor will be positioned on the first line of the buffer.
+You can get to the other files with the ":next" command.
+To edit a file that starts with a dash, precede the filelist with "\-\-".
+.TP
+\-
+The file to edit is read from stdin.  Commands are read from stderr, which
+should be a tty.
+.TP
+\-t {tag}
+The file to edit and the initial cursor position depends on a "tag", a sort
+of goto label.
+{tag} is looked up in the tags file, the associated file becomes the current
+file and the associated command is executed.
+Mostly this is used for C programs, in which case {tag} could be a function
+name.
+The effect is that the file containing that function becomes the current file
+and the cursor is positioned on the start of the function.
+See ":help tag\-commands".
+.TP
+\-q [errorfile]
+Start in quickFix mode.
+The file [errorfile] is read and the first error is displayed.
+If [errorfile] is omitted, the filename is obtained from the 'errorfile'
+option (defaults to "AztecC.Err" for the Amiga, "errors.err" on other
+systems).
+Further errors can be jumped to with the ":cn" command.
+See ":help quickfix".
+.PP
+.B Vim
+behaves differently, depending on the name of the command (the executable may
+still be the same file).
+.TP 10
+vim
+The "normal" way, everything is default.
+.TP
+ex
+Start in Ex mode.
+Go to Normal mode with the ":vi" command.
+Can also be done with the "\-e" argument.
+.TP
+view
+Start in read-only mode.  You will be protected from writing the files.  Can
+also be done with the "\-R" argument.
+.TP
+gvim gview
+The GUI version.
+Starts a new window.
+Can also be done with the "\-g" argument.
+.TP
+evim eview
+The GUI version in easy mode.
+Starts a new window.
+Can also be done with the "\-y" argument.
+.TP
+rvim rview rgvim rgview
+Like the above, but with restrictions.  It will not be possible to start shell
+commands, or suspend
+.B Vim.
+Can also be done with the "\-Z" argument.
+.SH OPTIONS
+The options may be given in any order, before or after filenames.
+Options without an argument can be combined after a single dash.
+.TP 12
++[num]
+For the first file the cursor will be positioned on line "num".
+If "num" is missing, the cursor will be positioned on the last line.
+.TP
++/{pat}
+For the first file the cursor will be positioned on the
+first occurrence of {pat}.
+See ":help search\-pattern" for the available search patterns.
+.TP
++{command}
+.TP
+\-c {command}
+{command} will be executed after the
+first file has been read.
+{command} is interpreted as an Ex command.
+If the {command} contains spaces it must be enclosed in double quotes (this
+depends on the shell that is used).
+Example: Vim "+set si" main.c
+.br
+Note: You can use up to 10 "+" or "\-c" commands.
+.TP
+\-S {file}
+{file} will be sourced after the first file has been read.
+This is equivalent to \-c "source {file}".
+{file} cannot start with '\-'.
+If {file} is omitted "Session.vim" is used (only works when \-S is the last
+argument).
+.TP
+\-\-cmd {command}
+Like using "\-c", but the command is executed just before
+processing any vimrc file.
+You can use up to 10 of these commands, independently from "\-c" commands.
+.TP
+\-A
+If
+.B Vim
+has been compiled with ARABIC support for editing right-to-left
+oriented files and Arabic keyboard mapping, this option starts
+.B Vim
+in Arabic mode, i.e. 'arabic' is set.  Otherwise an error
+message is given and
+.B Vim
+aborts.
+.TP
+\-b
+Binary mode.
+A few options will be set that makes it possible to edit a binary or
+executable file.
+.TP
+\-C
+Compatible.  Set the 'compatible' option.
+This will make
+.B Vim
+behave mostly like Vi, even though a .vimrc file exists.
+.TP
+\-d
+Start in diff mode.
+There should be two or three file name arguments.
+.B Vim
+will open all the files and show differences between them.
+Works like vimdiff(1).
+.TP
+\-d {device}
+Open {device} for use as a terminal.
+Only on the Amiga.
+Example:
+"\-d con:20/30/600/150".
+.TP
+\-D
+Debugging.  Go to debugging mode when executing the first command from a
+script.
+.TP
+\-e
+Start
+.B Vim
+in Ex mode, just like the executable was called "ex".
+.TP
+\-E
+Start
+.B Vim
+in improved Ex mode, just like the executable was called "exim".
+.TP
+\-f
+Foreground.  For the GUI version,
+.B Vim
+will not fork and detach from the shell it was started in.
+On the Amiga,
+.B Vim
+is not restarted to open a new window.
+This option should be used when
+.B Vim
+is executed by a program that will wait for the edit
+session to finish (e.g. mail).
+On the Amiga the ":sh" and ":!" commands will not work.
+.TP
+\-\-nofork
+Foreground.  For the GUI version,
+.B Vim
+will not fork and detach from the shell it was started in.
+.TP
+\-F
+If
+.B Vim
+has been compiled with FKMAP support for editing right-to-left
+oriented files and Farsi keyboard mapping, this option starts
+.B Vim
+in Farsi mode, i.e. 'fkmap' and 'rightleft' are set.
+Otherwise an error message is given and
+.B Vim
+aborts.
+.TP
+\-g
+If
+.B Vim
+has been compiled with GUI support, this option enables the GUI.
+If no GUI support was compiled in, an error message is given and
+.B Vim
+aborts.
+.TP
+\-h
+Give a bit of help about the command line arguments and options.
+After this
+.B Vim
+exits.
+.TP
+\-H
+If
+.B Vim
+has been compiled with RIGHTLEFT support for editing right-to-left
+oriented files and Hebrew keyboard mapping, this option starts
+.B Vim
+in Hebrew mode, i.e. 'hkmap' and 'rightleft' are set.
+Otherwise an error message is given and
+.B Vim
+aborts.
+.TP
+\-i {viminfo}
+When using the viminfo file is enabled, this option sets the filename to use,
+instead of the default "~/.viminfo".
+This can also be used to skip the use of the .viminfo file, by giving the name
+"NONE".
+.TP
+\-L
+Same as \-r.
+.TP
+\-l
+Lisp mode.
+Sets the 'lisp' and 'showmatch' options on.
+.TP
+\-m
+Modifying files is disabled.
+Resets the 'write' option.
+You can still modify the buffer, but writing a file is not possible.
+.TP
+\-M
+Modifications not allowed.  The 'modifiable' and 'write' options will be unset,
+so that changes are not allowed and files can not be written.  Note that these
+options can be set to enable making modifications.
+.TP
+\-N
+No-compatible mode.  Reset the 'compatible' option.
+This will make
+.B Vim
+behave a bit better, but less Vi compatible, even though a .vimrc file does
+not exist.
+.TP
+\-n
+No swap file will be used.
+Recovery after a crash will be impossible.
+Handy if you want to edit a file on a very slow medium (e.g. floppy).
+Can also be done with ":set uc=0".
+Can be undone with ":set uc=200".
+.TP
+\-nb
+Become an editor server for NetBeans.  See the docs for details.
+.TP
+\-o[N]
+Open N windows stacked.
+When N is omitted, open one window for each file.
+.TP
+\-O[N]
+Open N windows side by side.
+When N is omitted, open one window for each file.
+.TP
+\-p[N]
+Open N tab pages.
+When N is omitted, open one tab page for each file.
+.TP
+\-R
+Read-only mode.
+The 'readonly' option will be set.
+You can still edit the buffer, but will be prevented from accidently
+overwriting a file.
+If you do want to overwrite a file, add an exclamation mark to the Ex command,
+as in ":w!".
+The \-R option also implies the \-n option (see below).
+The 'readonly' option can be reset with ":set noro".
+See ":help 'readonly'".
+.TP
+\-r
+List swap files, with information about using them for recovery.
+.TP
+\-r {file}
+Recovery mode.
+The swap file is used to recover a crashed editing session.
+The swap file is a file with the same filename as the text file with ".swp"
+appended.
+See ":help recovery".
+.TP
+\-s
+Silent mode.  Only when started as "Ex" or when the "\-e" option was given
+before the "\-s" option.
+.TP
+\-s {scriptin}
+The script file {scriptin} is read.
+The characters in the file are interpreted as if you had typed them.
+The same can be done with the command ":source! {scriptin}".
+If the end of the file is reached before the editor exits, further characters
+are read from the keyboard.
+.TP
+\-T {terminal}
+Tells
+.B Vim
+the name of the terminal you are using.
+Only required when the automatic way doesn't work.
+Should be a terminal known
+to
+.B Vim
+(builtin) or defined in the termcap or terminfo file.
+.TP
+\-u {vimrc}
+Use the commands in the file {vimrc} for initializations.
+All the other initializations are skipped.
+Use this to edit a special kind of files.
+It can also be used to skip all initializations by giving the name "NONE".
+See ":help initialization" within vim for more details.
+.TP
+\-U {gvimrc}
+Use the commands in the file {gvimrc} for GUI initializations.
+All the other GUI initializations are skipped.
+It can also be used to skip all GUI initializations by giving the name "NONE".
+See ":help gui\-init" within vim for more details.
+.TP
+\-V[N]
+Verbose.  Give messages about which files are sourced and for reading and
+writing a viminfo file.  The optional number N is the value for 'verbose'.
+Default is 10.
+.TP
+\-v
+Start
+.B Vim
+in Vi mode, just like the executable was called "vi".  This only has effect
+when the executable is called "ex".
+.TP
+\-w {scriptout}
+All the characters that you type are recorded in the file
+{scriptout}, until you exit
+.B Vim.
+This is useful if you want to create a script file to be used with "vim \-s" or
+":source!".
+If the {scriptout} file exists, characters are appended.
+.TP
+\-W {scriptout}
+Like \-w, but an existing file is overwritten.
+.TP
+\-x
+Use encryption when writing files.  Will prompt for a crypt key.
+.TP
+\-X
+Don't connect to the X server.  Shortens startup time in a terminal, but the
+window title and clipboard will not be used.
+.TP
+\-y
+Start
+.B Vim
+in easy mode, just like the executable was called "evim" or "eview".
+Makes
+.B Vim
+behave like a click-and-type editor.
+.TP
+\-Z
+Restricted mode.  Works like the executable starts with "r".
+.TP
+\-\-
+Denotes the end of the options.
+Arguments after this will be handled as a file name.
+This can be used to edit a filename that starts with a '\-'.
+.TP
+\-\-echo\-wid
+GTK GUI only: Echo the Window ID on stdout.
+.TP
+\-\-help
+Give a help message and exit, just like "\-h".
+.TP
+\-\-literal
+Take file name arguments literally, do not expand wildcards.  This has no
+effect on Unix where the shell expands wildcards.
+.TP
+\-\-noplugin
+Skip loading plugins.  Implied by \-u NONE.
+.TP
+\-\-remote
+Connect to a Vim server and make it edit the files given in the rest of the
+arguments.  If no server is found a warning is given and the files are edited
+in the current Vim.
+.TP
+\-\-remote\-expr {expr}
+Connect to a Vim server, evaluate {expr} in it and print the result on stdout.
+.TP
+\-\-remote\-send {keys}
+Connect to a Vim server and send {keys} to it.
+.TP
+\-\-remote\-silent
+As \-\-remote, but without the warning when no server is found.
+.TP
+\-\-remote\-wait
+As \-\-remote, but Vim does not exit until the files have been edited.
+.TP
+\-\-remote\-wait\-silent
+As \-\-remote\-wait, but without the warning when no server is found.
+.TP
+\-\-serverlist
+List the names of all Vim servers that can be found.
+.TP
+\-\-servername {name}
+Use {name} as the server name.  Used for the current Vim, unless used with a
+\-\-remote argument, then it's the name of the server to connect to.
+.TP
+\-\-socketid {id}
+GTK GUI only: Use the GtkPlug mechanism to run gvim in another window.
+.TP
+\-\-version
+Print version information and exit.
+.SH ON-LINE HELP
+Type ":help" in
+.B Vim
+to get started.
+Type ":help subject" to get help on a specific subject.
+For example: ":help ZZ" to get help for the "ZZ" command.
+Use <Tab> and CTRL-D to complete subjects (":help cmdline\-completion").
+Tags are present to jump from one place to another (sort of hypertext links,
+see ":help").
+All documentation files can be viewed in this way, for example
+":help syntax.txt".
+.SH FILES
+.TP 15
+/usr/local/lib/vim/doc/*.txt
+The
+.B Vim
+documentation files.
+Use ":help doc\-file\-list" to get the complete list.
+.TP
+/usr/local/lib/vim/doc/tags
+The tags file used for finding information in the documentation files.
+.TP
+/usr/local/lib/vim/syntax/syntax.vim
+System wide syntax initializations.
+.TP
+/usr/local/lib/vim/syntax/*.vim
+Syntax files for various languages.
+.TP
+/usr/local/lib/vim/vimrc
+System wide
+.B Vim
+initializations.
+.TP
+~/.vimrc
+Your personal
+.B Vim
+initializations.
+.TP
+/usr/local/lib/vim/gvimrc
+System wide gvim initializations.
+.TP
+~/.gvimrc
+Your personal gvim initializations.
+.TP
+/usr/local/lib/vim/optwin.vim
+Script used for the ":options" command, a nice way to view and set options.
+.TP
+/usr/local/lib/vim/menu.vim
+System wide menu initializations for gvim.
+.TP
+/usr/local/lib/vim/bugreport.vim
+Script to generate a bug report.  See ":help bugs".
+.TP
+/usr/local/lib/vim/filetype.vim
+Script to detect the type of a file by its name.  See ":help 'filetype'".
+.TP
+/usr/local/lib/vim/scripts.vim
+Script to detect the type of a file by its contents.  See ":help 'filetype'".
+.TP
+/usr/local/lib/vim/*.ps
+Files used for PostScript printing.
+.PP
+For recent info read the VIM home page:
+.br
+<URL:http://www.vim.org/>
+.SH SEE ALSO
+vimtutor(1)
+.SH AUTHOR
+Most of
+.B Vim
+was made by Bram Moolenaar, with a lot of help from others.
+See ":help credits" in
+.B Vim.
+.br
+.B Vim
+is based on Stevie, worked on by: Tim Thompson,
+Tony Andrews and G.R. (Fred) Walter.
+Although hardly any of the original code remains.
+.SH BUGS
+Probably.
+See ":help todo" for a list of known problems.
+.PP
+Note that a number of things that may be regarded as bugs by some, are in fact
+caused by a too-faithful reproduction of Vi's behaviour.
+And if you think other things are bugs "because Vi does it differently",
+you should take a closer look at the vi_diff.txt file (or type :help
+vi_diff.txt when in Vim).
+Also have a look at the 'compatible' and 'cpoptions' options.
--- /dev/null
+++ b/lib/vimfiles/doc/vim2html.pl
@@ -1,0 +1,228 @@
+#!/usr/bin/env perl
+
+# converts vim documentation to simple html
+# Sirtaj Singh Kang (taj@kde.org)
+
+# Sun Feb 24 14:49:17 CET 2002
+
+use strict;
+use vars qw/%url $date/;
+
+%url = ();
+$date = `date`;
+chop $date;
+
+sub maplink
+{
+	my $tag = shift;
+	if( exists $url{ $tag } ){
+		return $url{ $tag };
+	} else {
+		#warn "Unknown hyperlink target: $tag\n";
+		$tag =~ s/\.txt//;
+		$tag =~ s/</&lt;/g;
+		$tag =~ s/>/&gt;/g;
+		return "<code class=\"badlink\">$tag</code>";
+	}
+}
+
+sub readTagFile
+{
+	my($tagfile) = @_;
+	my( $tag, $file, $name );
+
+	open(TAGS,"$tagfile") || die "can't read tags\n";
+
+	while( <TAGS> ) {
+		next unless /^(\S+)\s+(\S+)\s+/;
+
+		$tag = $1;
+		my $label = $tag;
+		($file= $2) =~ s/.txt$/.html/g;
+		$label =~ s/\.txt//;
+
+		$url{ $tag } = "<a href=\"$file#".escurl($tag)."\">".esctext($label)."</a>";
+	}
+	close( TAGS );
+}
+
+sub esctext
+{
+	my $text = shift;
+	$text =~ s/&/&amp;/g;
+	$text =~ s/</&lt;/g;
+	$text =~ s/>/&gt;/g;
+	return $text;
+}
+
+sub escurl
+{
+	my $url = shift;
+	$url =~ s/"/%22/g;
+	$url =~ s/~/%7E/g;
+	$url =~ s/</%3C/g;
+	$url =~ s/>/%3E/g;
+	$url =~ s/=/%20/g;
+	$url =~ s/#/%23/g;
+	$url =~ s/\//%2F/g;
+
+	return $url;
+}
+
+sub vim2html
+{
+	my( $infile ) = @_;
+	my( $outfile );
+
+	open(IN, "$infile" ) || die "Couldn't read from $infile: $!.\n";
+
+	($outfile = $infile) =~ s:.*/::g;
+	$outfile =~ s/\.txt$//g;
+
+	open( OUT, ">$outfile.html" )
+			|| die "Couldn't write to $outfile.html: $!.\n";
+	my $head = uc( $outfile );
+
+	print OUT<<EOF;
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+<head>
+<title>VIM: $outfile</title>
+<link rel="stylesheet" href="vim-stylesheet.css" type="text/css">
+</head>
+<body>
+<h2>$head</h2>
+<pre>
+EOF
+
+	my $inexample = 0;
+	while( <IN> ) {
+		chop;
+		if ( /^\s*[-=]+\s*$/ ) {
+			print OUT "</pre><hr><pre>";
+			next;
+		}
+
+		# examples
+		elsif( /^>$/ || /\s>$/ ) {
+			$inexample = 1;
+			chop;
+		}
+		elsif ( $inexample && /^([<\S])/ ) {
+			$inexample = 0;
+			$_ = $' if $1 eq "<";
+		}
+
+		s/\s+$//g;
+
+		# Various vim highlights. note that < and > have already been escaped
+		# so that HTML doesn't get screwed up.
+
+		my @out = ();
+		#		print "Text: $_\n";
+		LOOP:
+		foreach my $token ( split /((?:\|[^\|]+\|)|(?:\*[^\*]+\*))/ ) {
+			if ( $token =~ /^\|([^\|]+)\|/ ) {
+				# link
+				push( @out, "|".maplink( $1 )."|" );
+				next LOOP;
+			}
+			elsif ( $token =~ /^\*([^\*]+)\*/ ) {
+				# target
+				push( @out,
+					"<b class=\"vimtag\">\*<a name=\"".escurl($1)."\">".esctext($1)."<\/a>\*<\/b>");
+				next LOOP;
+			}
+
+			$_ = esctext($token);
+			s/CTRL-(\w+)/<code class="keystroke">CTRL-$1<\/code>/g;
+			# parameter <...>
+			s/&lt;(.*?)&gt;/<code class="special">&lt;$1&gt;<\/code>/g;
+
+			# parameter {...}
+			s/\{([^}]*)\}/<code class="special">{$1}<\/code>/g;
+
+			# parameter [...]
+			s/\[(range|line|count|offset|cmd|[-+]?num)\]/<code class="special">\[$1\]<\/code>/g;
+			# note
+			s/(Note:?)/<code class="note">$1<\/code>/gi;
+
+			# local heading
+			s/^(.*)\~$/<code class="section">$1<\/code>/g;
+			push( @out, $_ );
+		}
+
+		$_ = join( "", @out );
+
+		if( $inexample == 2 ) {
+			print OUT "<code class=\"example\">$_</code>\n";
+		} else {
+			print OUT $_,"\n";
+		}
+
+		$inexample = 2 if $inexample == 1;
+	}
+	print OUT<<EOF;
+</pre>
+<p><i>Generated by vim2html on $date</i></p>
+</body>
+</html>
+EOF
+
+}
+
+sub usage
+{
+die<<EOF;
+vim2html.pl: converts vim documentation to HTML.
+usage:
+
+	vim2html.pl <tag file> <text files>
+EOF
+}
+
+
+sub writeCSS
+{
+	open( CSS, ">vim-stylesheet.css"  ) || die "Couldn't write stylesheet: $!\n";
+	print CSS<<EOF;
+body { background-color: white; color: black;}
+:link { color: rgb(0,137,139); }
+:visited { color: rgb(0,100,100);
+           background-color: white; /* should be inherit */ }
+:active { color: rgb(0,200,200);
+          background-color: white; /* should be inherit */ }
+
+B.vimtag { color : rgb(250,0,250); }
+
+h1, h2 { color: rgb(82,80,82); text-align: center; }
+h3, h4, h5, h6 { color: rgb(82,80,82); }
+.headline { color: rgb(0,137,139); }
+.header { color: rgb(164, 32, 246); }
+.section { color: rgb(164, 32, 246); }
+.keystroke { color: rgb(106, 89, 205); }
+.vim { }
+.example { color: rgb(0, 0, 255); }
+.option { }
+.notvi { }
+.special { color: rgb(106, 89, 205); }
+.note { color: blue; background-color: yellow; }
+.sub {}
+.badlink { color: rgb(0,37,39); }
+EOF
+
+}
+
+# main
+usage() if $#ARGV < 2;
+
+print "Processing tags...\n";
+readTagFile( $ARGV[ 0 ] );
+
+foreach my $file ( 1..$#ARGV ) {
+	print "Processing ".$ARGV[ $file ]."...\n";
+	vim2html( $ARGV[ $file ] );
+}
+print "Writing stylesheet...\n";
+writeCSS();
+print "done.\n"
--- /dev/null
+++ b/lib/vimfiles/doc/vimdiff.1
@@ -1,0 +1,46 @@
+.TH VIMDIFF 1 "2001 March 30"
+.SH NAME
+vimdiff \- edit two or three versions of a file with Vim and show differences
+.SH SYNOPSIS
+.br
+.B vimdiff
+[options] file1 file2 [file3]
+.PP
+.B gvimdiff
+.SH DESCRIPTION
+.B Vimdiff
+starts
+.B Vim
+on two (or three) files.
+Each file gets its own window.
+The differences between the files are highlighted.
+This is a nice way to inspect changes and to move changes from one version
+to another version of the same file.
+.PP
+See vim(1) for details about Vim itself.
+.PP
+When started as
+.B gvimdiff
+the GUI will be started, if available.
+.PP
+In each window the 'diff' option will be set, which causes the differences
+to be highlighted.
+.br
+The 'wrap' and 'scrollbind' options are set to make the text look good.
+.br
+The 'foldmethod' option is set to "diff", which puts ranges of lines without
+changes in a fold.  'foldcolumn' is set to two to make it easy to spot the
+folds and open or close them.
+.SH OPTIONS
+Vertical splits are used to align the lines, as if the "\-O" argument was used.
+To use horizontal splits instead, use the "\-o" argument.
+.PP
+For all other arguments see vim(1).
+.SH SEE ALSO
+vim(1)
+.SH AUTHOR
+Most of
+.B Vim
+was made by Bram Moolenaar, with a lot of help from others.
+See ":help credits" in
+.B Vim.
--- /dev/null
+++ b/lib/vimfiles/doc/vimtutor.1
@@ -1,0 +1,54 @@
+.TH VIMTUTOR 1 "2001 April 2"
+.SH NAME
+vimtutor \- the Vim tutor
+.SH SYNOPSIS
+.br
+.B vimtutor [language]
+.SH DESCRIPTION
+.B Vimtutor
+starts the
+.B Vim
+tutor.
+It copies the tutor file first, so that it can be modified without changing
+the original file.
+.PP
+The
+.B Vimtutor
+is useful for people that want to learn their first
+.B Vim
+commands.
+.PP
+The optional [language] argument is the two-letter name of a language, like
+"it" or "es".
+If the [language] argument is missing, the language of the current locale will
+be used.
+If a tutor in this language is available, it will be used.
+Otherwise the English version will be used.
+.PP
+.B Vim
+is always started in Vi compatible mode.
+.SH FILES
+.TP 15
+/usr/local/lib/vim/tutor/tutor[.language]
+The
+.B Vimtutor
+text file(s).
+.TP 15
+/usr/local/lib/vim/tutor/tutor.vim
+The Vim script used to copy the
+.B Vimtutor
+text file.
+.SH AUTHOR
+The
+.B Vimtutor
+was originally written for Vi by Michael C. Pierce and Robert K. Ware,
+Colorado School of Mines using ideas supplied by Charles Smith,
+Colorado State University.
+E-mail: bware@mines.colorado.edu.
+.br
+It was modified for
+.B Vim
+by Bram Moolenaar.
+For the names of the translators see the tutor files.
+.SH SEE ALSO
+vim(1)
--- /dev/null
+++ b/lib/vimfiles/doc/visual.txt
@@ -1,0 +1,499 @@
+*visual.txt*    For Vim version 7.1.  Last change: 2006 Sep 26
+
+
+		  VIM REFERENCE MANUAL    by Bram Moolenaar
+
+
+Visual mode				*Visual* *Visual-mode* *visual-mode*
+
+Visual mode is a flexible and easy way to select a piece of text for an
+operator.  It is the only way to select a block of text.
+
+This is introduced in section |04.4| of the user manual.
+
+1. Using Visual mode			|visual-use|
+2. Starting and stopping Visual mode	|visual-start|
+3. Changing the Visual area		|visual-change|
+4. Operating on the Visual area		|visual-operators|
+5. Blockwise operators			|blockwise-operators|
+6. Repeating				|visual-repeat|
+7. Examples				|visual-examples|
+8. Select mode				|Select-mode|
+
+{Vi has no Visual mode, the name "visual" is used for Normal mode, to
+distinguish it from Ex mode}
+{not available when the |+visual| feature was disabled when compiling}
+
+==============================================================================
+1. Using Visual mode					*visual-use*
+
+Using Visual mode consists of three parts:
+1. Mark the start of the text with "v", "V" or CTRL-V.
+   The character under the cursor will be used as the start.
+2. Move to the end of the text.
+   The text from the start of the Visual mode up to and including the
+   character under the cursor is highlighted.
+3. Type an operator command.
+   The highlighted characters will be operated upon.
+
+The 'highlight' option can be used to set the display mode to use for
+highlighting in Visual mode.
+The 'virtualedit' option can be used to allow positioning the cursor to
+positions where there is no actual character.
+
+The highlighted text normally includes the character under the cursor.
+However, when the 'selection' option is set to "exclusive" and the cursor is
+after the Visual area, the character under the cursor is not included.
+
+With "v" the text before the start position and after the end position will
+not be highlighted.  However, all uppercase and non-alpha operators, except
+"~" and "U", will work on whole lines anyway.  See the list of operators
+below.
+
+							*visual-block*
+With CTRL-V (blockwise Visual mode) the highlighted text will be a rectangle
+between start position and the cursor.  However, some operators work on whole
+lines anyway (see the list below).  The change and substitute operators will
+delete the highlighted text and then start insertion at the top left
+position.
+
+==============================================================================
+2. Starting and stopping Visual mode			*visual-start*
+
+						*v* *characterwise-visual*
+v			start Visual mode per character.
+
+						*V* *linewise-visual*
+V			start Visual mode linewise.
+
+						*CTRL-V* *blockwise-visual*
+CTRL-V			start Visual mode blockwise.  Note: Under Windows
+			CTRL-V could be mapped to paste text, it doesn't work
+			to start Visual mode then, see |CTRL-V-alternative|.
+
+If you use <Esc>, click the left mouse button or use any command that
+does a jump to another buffer while in Visual mode, the highlighting stops
+and no text is affected.  Also when you hit "v" in characterwise Visual mode,
+"CTRL-V" in blockwise Visual mode or "V" in linewise Visual mode.  If you hit
+CTRL-Z the highlighting stops and the editor is suspended or a new shell is
+started |CTRL-Z|.
+
+	      new mode after typing:		*v_v* *v_CTRL-V* *v_V*
+old mode	     "v"	      "CTRL-V"		     "V"	~
+
+Normal		    Visual	   blockwise Visual	  linewise Visual
+Visual		    Normal	   blockwise Visual	  linewise Visual
+blockwise Visual    Visual	   Normal		  linewise Visual
+linewise Visual     Visual	   blockwise Visual	  Normal
+
+						*gv* *v_gv* *reselect-Visual*
+gv			Start Visual mode with the same area as the previous
+			area and the same mode.
+			In Visual mode the current and the previous Visual
+			area are exchanged.
+			After using "p" or "P" in Visual mode the text that
+			was put will be selected.
+
+							*<LeftMouse>*
+<LeftMouse>		Set the current cursor position.  If Visual mode is
+			active it is stopped.  Only when 'mouse' option is
+			contains 'n' or 'a'.  If the position is within 'so'
+			lines from the last line on the screen the text is
+			scrolled up.  If the position is within 'so' lines from
+			the first line on the screen the text is scrolled
+			down.
+
+							*<RightMouse>*
+<RightMouse>		Start Visual mode if it is not active.  The text from
+			the cursor position to the position of the click is
+			highlighted.  If Visual mode was already active move
+			the start or end of the highlighted text, which ever
+			is closest, to the position of the click.  Only when
+			'mouse' option contains 'n' or 'a'.
+
+			Note: when 'mousemodel' is set to "popup",
+			<S-LeftMouse> has to be used instead of <RightMouse>.
+
+							*<LeftRelease>*
+<LeftRelease>		This works like a <LeftMouse>, if it is not at
+			the same position as <LeftMouse>.  In an older version
+			of xterm you won't see the selected area until the
+			button is released, unless there is access to the
+			display where the xterm is running (via the DISPLAY
+			environment variable or the -display argument).  Only
+			when 'mouse' option contains 'n' or 'a'.
+
+If Visual mode is not active and the "v", "V" or CTRL-V is preceded with a
+count, the size of the previously highlighted area is used for a start.  You
+can then move the end of the highlighted area and give an operator.  The type
+of the old area is used (character, line or blockwise).
+- Linewise Visual mode: The number of lines is multiplied with the count.
+- Blockwise Visual mode: The number of lines and columns is multiplied with
+  the count.
+- Normal Visual mode within one line: The number of characters is multiplied
+  with the count.
+- Normal Visual mode with several lines: The number of lines is multiplied
+  with the count, in the last line the same number of characters is used as
+  in the last line in the previously highlighted area.
+The start of the text is the Cursor position.  If the "$" command was used as
+one of the last commands to extend the highlighted text, the area will be
+extended to the rightmost column of the longest line.
+
+If you want to highlight exactly the same area as the last time, you can use
+"gv" |gv| |v_gv|.
+
+							*v_<Esc>*
+<Esc>			In Visual mode: Stop Visual mode.
+
+							*v_CTRL-C*
+CTRL-C			In Visual mode: Stop Visual mode.  When insert mode is
+			pending (the mode message shows
+			"-- (insert) VISUAL --"), it is also stopped.
+
+==============================================================================
+3. Changing the Visual area				*visual-change*
+
+							*v_o*
+o			Go to Other end of highlighted text: The current
+			cursor position becomes the start of the highlighted
+			text and the cursor is moved to the other end of the
+			highlighted text.  The highlighted area remains the
+			same.
+
+							*v_O*
+O			Go to Other end of highlighted text.  This is like
+			"o", but in Visual block mode the cursor moves to the
+			other corner in the same line.  When the corner is at
+			a character that occupies more than one position on
+			the screen (e.g., a <Tab>), the highlighted text may
+			change.
+
+							*v_$*
+When the "$" command is used with blockwise Visual mode, the right end of the
+highlighted text will be determined by the longest highlighted line.  This
+stops when a motion command is used that does not move straight up or down.
+
+For moving the end of the block many commands can be used, but you cannot
+use Ex commands, commands that make changes or abandon the file.  Commands
+(starting with) ".", "&", CTRL-^, "Z", CTRL-], CTRL-T, CTRL-R, CTRL-I
+and CTRL-O cause a beep and Visual mode continues.
+
+When switching to another window on the same buffer, the cursor position in
+that window is adjusted, so that the same Visual area is still selected.  This
+is especially useful to view the start of the Visual area in one window, and
+the end in another.  You can then use <RightMouse> (or <S-LeftMouse> when
+'mousemodel' is "popup") to drag either end of the Visual area.
+
+==============================================================================
+4. Operating on the Visual area				*visual-operators*
+
+The operators that can be used are:
+	~	switch case					|v_~|
+	d	delete						|v_d|
+	c	change (4)					|v_c|
+	y	yank						|v_y|
+	>	shift right (4)					|v_>|
+	<	shift left (4)					|v_<|
+	!	filter through external command (1)		|v_!|
+	=	filter through 'equalprg' option command (1)	|v_=|
+	gq	format lines to 'textwidth' length (1)		|v_gq|
+
+The objects that can be used are:
+	aw	a word (with white space)			|v_aw|
+	iw	inner word					|v_iw|
+	aW	a WORD (with white space)			|v_aW|
+	iW	inner WORD					|v_iW|
+	as	a sentence (with white space)			|v_as|
+	is	inner sentence					|v_is|
+	ap	a paragraph (with white space)			|v_ap|
+	ip	inner paragraph					|v_ip|
+	ab	a () block (with parenthesis)			|v_ab|
+	ib	inner () block					|v_ib|
+	aB	a {} block (with braces)			|v_aB|
+	iB	inner {} block					|v_iB|
+	a<	a <> block (with <>)				|v_a<|
+	i<	inner <> block					|v_i<|
+	a[	a [] block (with [])				|v_a[|
+	i[	inner [] block					|v_i[|
+
+Additionally the following commands can be used:
+	:	start ex command for highlighted lines (1)	|v_:|
+	r	change (4)					|v_r|
+	s	change						|v_s|
+	C	change (2)(4)					|v_C|
+	S	change (2)					|v_S|
+	R	change (2)					|v_R|
+	x	delete						|v_x|
+	D	delete (3)					|v_D|
+	X	delete (2)					|v_X|
+	Y	yank (2)					|v_Y|
+	p	put						|v_p|
+	J	join (1)					|v_J|
+	U	make uppercase					|v_U|
+	u	make lowercase					|v_u|
+	^]	find tag					|v_CTRL-]|
+	I	block insert					|v_b_I|
+	A	block append					|v_b_A|
+
+(1): Always whole lines, see |:visual_example|.
+(2): Whole lines when not using CTRL-V.
+(3): Whole lines when not using CTRL-V, delete until the end of the line when
+     using CTRL-V.
+(4): When using CTRL-V operates on the block only.
+
+Note that the ":vmap" command can be used to specifically map keys in Visual
+mode.  For example, if you would like the "/" command not to extend the Visual
+area, but instead take the highlighted text and search for that: >
+	:vmap / y/<C-R>"<CR>
+(In the <> notation |<>|, when typing it you should type it literally; you
+need to remove the 'B' and '<' flags from 'cpoptions'.)
+
+If you want to give a register name using the """ command, do this just before
+typing the operator character: "v{move-around}"xd".
+
+If you want to give a count to the command, do this just before typing the
+operator character: "v{move-around}3>" (move lines 3 indents to the right).
+
+							*{move-around}*
+The {move-around} is any sequence of movement commands.  Note the difference
+with {motion}, which is only ONE movement command.
+
+Another way to operate on the Visual area is using the |/\%V| item in a
+pattern.  For example, to replace all '(' in the Visual area with '#': >
+
+	:%s/\%V(/X/g
+
+==============================================================================
+5. Blockwise operators					*blockwise-operators*
+
+{not available when compiled without the |+visualextra| feature}
+
+Reminder: Use 'virtualedit' to be able to select blocks that start or end
+after the end of a line or halfway a tab.
+
+Visual-block Insert						*v_b_I*
+With a blockwise selection, I{string}<ESC> will insert {string} at the start
+of block on every line of the block, provided that the line extends into the
+block.  Thus lines that are short will remain unmodified.  TABs are split to
+retain visual columns.
+See |v_b_I_example|.
+
+Visual-block Append						*v_b_A*
+With a blockwise selection, A{string}<ESC> will append {string} to the end of
+block on every line of the block.  There is some differing behavior where the
+block RHS is not straight, due to different line lengths:
+
+1. Block was created with <C-v>$
+    In this case the string is appended to the end of each line.
+2. Block was created with <C-v>{move-around}
+    In this case the string is appended to the end of the block on each line,
+    and whitespace is inserted to pad to the end-of-block column.
+See |v_b_A_example|.
+Note: "I" and "A" behave differently for lines that don't extend into the
+selected block.  This was done intentionally, so that you can do it the way
+you want.
+
+Visual-block change						*v_b_c*
+All selected text in the block will be replaced by the same text string.  When
+using "c" the selected text is deleted and Insert mode started.  You can then
+enter text (without a line break).  When you hit <Esc>, the same string is
+inserted in all previously selected lines.
+
+Visual-block Change						*v_b_C*
+Like using "c", but the selection is extended until the end of the line for
+all lines.
+
+								*v_b_<*
+Visual-block Shift						*v_b_>*
+The block is shifted by 'shiftwidth'.  The RHS of the block is irrelevant.  The
+LHS of the block determines the point from which to apply a right shift, and
+padding includes TABs optimally according to 'ts' and 'et'.  The LHS of the
+block determines the point upto which to shift left.
+    Note: v_< padding is buggy if the Visual Block starts and ends in the same
+    TAB. (Vim 5.4c)
+See |v_b_>_example|.
+See |v_b_<_example|.
+
+Visual-block Replace						*v_b_r*
+Every screen char in the highlighted region is replaced with the same char, ie
+TABs are split and the virtual whitespace is replaced, maintaining screen
+layout.
+See |v_b_r_example|.
+
+
+==============================================================================
+6. Repeating						*visual-repeat*
+
+When repeating a Visual mode operator, the operator will be applied to the
+same amount of text as the last time:
+- Linewise Visual mode: The same number of lines.
+- Blockwise Visual mode: The same number of lines and columns.
+- Normal Visual mode within one line: The same number of characters.
+- Normal Visual mode with several lines: The same number of lines, in the
+  last line the same number of characters as in the last line the last time.
+The start of the text is the Cursor position.  If the "$" command was used as
+one of the last commands to extend the highlighted text, the repeating will
+be applied up to the rightmost column of the longest line.
+
+
+==============================================================================
+7. Examples						*visual-examples*
+
+							*:visual_example*
+Currently the ":" command works on whole lines only.  When you select part of
+a line, doing something like ":!date" will replace the whole line.  If you
+want only part of the line to be replaced you will have to make a mapping for
+it.  In a future release ":" may work on partial lines.
+
+Here is an example, to replace the selected text with the output of "date": >
+	:vmap _a <Esc>`>a<CR><Esc>`<i<CR><Esc>!!date<CR>kJJ
+
+(In the <> notation |<>|, when typing it you should type it literally; you
+need to remove the 'B' and '<' flags from 'cpoptions')
+
+What this does is:
+<Esc>		stop Visual mode
+`>		go to the end of the Visual area
+a<CR><Esc>	break the line after the Visual area
+`<		jump to the start of the Visual area
+i<CR><Esc>	break the line before the Visual area
+!!date<CR>	filter the Visual text through date
+kJJ		Join the lines back together
+
+							*visual-search*
+Here is an idea for a mapping that makes it possible to do a search for the
+selected text: >
+	:vmap X y/<C-R>"<CR>
+
+(In the <> notation |<>|, when typing it you should type it literally; you
+need to remove the 'B' and '<' flags from 'cpoptions')
+
+Note that special characters (like '.' and '*') will cause problems.
+
+Visual-block Examples					*blockwise-examples*
+With the following text, I will indicate the commands to produce the block and
+the results below.  In all cases, the cursor begins on the 'a' in the first
+line of the test text.
+The following modeline settings are assumed ":ts=8:sw=4:".
+
+It will be helpful to
+:set hls
+/<TAB>
+where <TAB> is a real TAB.  This helps visualise the operations.
+
+The test text is:
+
+abcdefghijklmnopqrstuvwxyz
+abc		defghijklmnopqrstuvwxyz
+abcdef  ghi		jklmnopqrstuvwxyz
+abcdefghijklmnopqrstuvwxyz
+
+1. fo<C-v>3jISTRING<ESC>					*v_b_I_example*
+
+abcdefghijklmnSTRINGopqrstuvwxyz
+abc	      STRING  defghijklmnopqrstuvwxyz
+abcdef  ghi   STRING	jklmnopqrstuvwxyz
+abcdefghijklmnSTRINGopqrstuvwxyz
+
+2. fo<C-v>3j$ASTRING<ESC>					*v_b_A_example*
+
+abcdefghijklmnopqrstuvwxyzSTRING
+abc		defghijklmnopqrstuvwxyzSTRING
+abcdef  ghi		jklmnopqrstuvwxyzSTRING
+abcdefghijklmnopqrstuvwxyzSTRING
+
+3. fo<C-v>3j3l<..						*v_b_<_example*
+
+abcdefghijklmnopqrstuvwxyz
+abc	      defghijklmnopqrstuvwxyz
+abcdef  ghi   jklmnopqrstuvwxyz
+abcdefghijklmnopqrstuvwxyz
+
+4. fo<C-v>3j>..							*v_b_>_example*
+
+abcdefghijklmn		  opqrstuvwxyz
+abc			    defghijklmnopqrstuvwxyz
+abcdef  ghi			    jklmnopqrstuvwxyz
+abcdefghijklmn		  opqrstuvwxyz
+
+5. fo<C-v>5l3jrX						*v_b_r_example*
+
+abcdefghijklmnXXXXXXuvwxyz
+abc	      XXXXXXhijklmnopqrstuvwxyz
+abcdef  ghi   XXXXXX    jklmnopqrstuvwxyz
+abcdefghijklmnXXXXXXuvwxyz
+
+==============================================================================
+8. Select mode						*Select* *Select-mode*
+
+Select mode looks like Visual mode, but the commands accepted are quite
+different.  This resembles the selection mode in Microsoft Windows.
+When the 'showmode' option is set, "-- SELECT --" is shown in the last line.
+
+Entering Select mode:
+- Using the mouse to select an area, and 'selectmode' contains "mouse".
+  'mouse' must also contain a flag for the current mode.
+- Using a non-printable movement command, with the Shift key pressed, and
+  'selectmode' contains "key".  For example: <S-Left> and <S-End>.  'keymodel'
+  must also contain "startsel".
+- Using "v", "V" or CTRL-V command, and 'selectmode' contains "cmd".
+- Using "gh", "gH" or "g_CTRL-H" command in Normal mode.
+- From Visual mode, press CTRL-G.			*v_CTRL-G*
+
+Commands in Select mode:
+- Printable characters, <NL> and <CR> cause the selection to be deleted, and
+  Vim enters Insert mode.  The typed character is inserted.
+- Non-printable movement commands, with the Shift key pressed, extend the
+  selection.  'keymodel' must include "startsel".
+- Non-printable movement commands, with the Shift key NOT pressed, stop Select
+  mode.  'keymodel' must include "stopsel".
+- ESC stops Select mode.
+- CTRL-O switches to Visual mode for the duration of one command. *v_CTRL-O*
+- CTRL-G switches to Visual mode.
+
+Otherwise, typed characters are handled as in Visual mode.
+
+When using an operator in Select mode, and the selection is linewise, the
+selected lines are operated upon, but like in characterwise selection.  For
+example, when a whole line is deleted, it can later be pasted halfway a line.
+
+
+Mappings and menus in Select mode.			*Select-mode-mapping*
+
+When mappings and menus are defined with the |:vmap| or |:vmenu| command they
+work both in Visual mode and in Select mode.  When these are used in Select
+mode Vim automatically switches to Visual mode, so that the same behavior as
+in Visual mode is effective.  If you don't want this use |:xmap| or |:smap|.
+
+After the mapping or menu finishes, the selection is enabled again and Select
+mode entered, unless the selected area was deleted, another buffer became
+the current one or the window layout was changed.
+
+When a character was typed that causes the selection to be deleted and Insert
+mode started, Insert mode mappings are applied to this character.  This may
+cause some confusion, because it means Insert mode mappings apply to a
+character typed in Select mode.  Language mappings apply as well.
+
+							*gV* *v_gV*
+gV			Avoid the automatic reselection of the Visual area
+			after a Select mode mapping or menu has finished.
+			Put this just before the end of the mapping or menu.
+			At least it should be after any operations on the
+			selection.
+
+							*gh*
+gh			Start Select mode, characterwise.  This is like "v",
+			but starts Select mode instead of Visual mode.
+			Mnemonic: "get highlighted".
+
+							*gH*
+gH			Start Select mode, linewise.  This is like "V",
+			but starts Select mode instead of Visual mode.
+			Mnemonic: "get Highlighted".
+
+							*g_CTRL-H*
+g CTRL-H		Start Select mode, blockwise.  This is like CTRL-V,
+			but starts Select mode instead of Visual mode.
+			Mnemonic: "get Highlighted".
+
+ vim:tw=78:ts=8:ft=help:norl:
--- /dev/null
+++ b/lib/vimfiles/doc/windows.txt
@@ -1,0 +1,1182 @@
+*windows.txt*   For Vim version 7.1.  Last change: 2007 Mar 17
+
+
+		  VIM REFERENCE MANUAL    by Bram Moolenaar
+
+
+Editing with multiple windows and buffers.		*windows* *buffers*
+
+The commands which have been added to use multiple windows and buffers are
+explained here.  Additionally, there are explanations for commands that work
+differently when used in combination with more than one window.
+
+The basics are explained in chapter 7 and 8 of the user manual |usr_07.txt|
+|usr_08.txt|.
+
+1.  Introduction				|windows-intro|
+2.  Starting Vim				|windows-starting|
+3.  Opening and closing a window		|opening-window|
+4.  Moving cursor to other windows		|window-move-cursor|
+5.  Moving windows around			|window-moving|
+6.  Window resizing				|window-resize|
+7.  Argument and buffer list commands		|buffer-list|
+8.  Do a command in all buffers or windows	|list-repeat|
+9.  Tag or file name under the cursor		|window-tag|
+10. The preview window				|preview-window|
+11. Using hidden buffers			|buffer-hidden|
+12. Special kinds of buffers			|special-buffers|
+
+{Vi does not have any of these commands}
+{not able to use multiple windows when the |+windows| feature was disabled at
+compile time}
+{not able to use vertically split windows when the |+vertsplit| feature was
+disabled at compile time}
+
+==============================================================================
+1. Introduction					*windows-intro* *window*
+
+A window is a viewport onto a buffer.  You can use multiple windows on one
+buffer, or several windows on different buffers.
+
+A buffer is a file loaded into memory for editing.  The original file remains
+unchanged until you write the buffer to the file.
+
+A buffer can be in one of three states:
+
+							*active-buffer*
+active:   The buffer is displayed in a window.  If there is a file for this
+	  buffer, it has been read into the buffer.  The buffer may have been
+	  modified since then and thus be different from the file.
+							*hidden-buffer*
+hidden:   The buffer is not displayed.  If there is a file for this buffer, it
+	  has been read into the buffer.  Otherwise it's the same as an active
+	  buffer, you just can't see it.
+							*inactive-buffer*
+inactive: The buffer is not displayed and does not contain anything.  Options
+	  for the buffer are remembered if the file was once loaded.  It can
+	  contain marks from the |viminfo| file.  But the buffer doesn't
+	  contain text.
+
+In a table:
+
+state		displayed	loaded		":buffers"  ~
+		in window			shows	    ~
+active		  yes		 yes		  'a'
+hidden		  no		 yes		  'h'
+inactive	  no		 no		  ' '
+
+Note: All CTRL-W commands can also be executed with |:wincmd|, for those
+places where a Normal mode command can't be used or is inconvenient.
+
+The main Vim window can hold several split windows.  There are also tab pages
+|tab-page|, each of which can hold multiple windows.
+
+==============================================================================
+2. Starting Vim						*windows-starting*
+
+By default, Vim starts with one window, just like Vi.
+
+The "-o" and "-O" arguments to Vim can be used to open a window for each file
+in the argument list.  The "-o" argument will split the windows horizontally;
+the "-O" argument will split the windows vertically.  If both "-o" and "-O"
+are given, the last one encountered will be used to determine the split
+orientation.  For example, this will open three windows, split horizontally: >
+	vim -o file1 file2 file3
+
+"-oN", where N is a decimal number, opens N windows split horizontally.  If
+there are more file names than windows, only N windows are opened and some
+files do not get a window.  If there are more windows than file names, the
+last few windows will be editing empty buffers.  Similarly, "-ON" opens N
+windows split vertically, with the same restrictions.
+
+If there are many file names, the windows will become very small.  You might
+want to set the 'winheight' and/or 'winwidth' options to create a workable
+situation.
+
+Buf/Win Enter/Leave |autocommand|s are not executed when opening the new
+windows and reading the files, that's only done when they are really entered.
+
+							*status-line*
+A status line will be used to separate windows.  The 'laststatus' option tells
+when the last window also has a status line:
+	'laststatus' = 0	never a status line
+	'laststatus' = 1	status line if there is more than one window
+	'laststatus' = 2	always a status line
+
+You can change the contents of the status line with the 'statusline' option.
+This option can be local to the window, so that you can have a different
+status line in each window.
+
+Normally, inversion is used to display the status line.  This can be changed
+with the 's' character in the 'highlight' option.  For example, "sb" sets it to
+bold characters.  If no highlighting is used for the status line ("sn"), the
+'^' character is used for the current window, and '=' for other windows.  If
+the mouse is supported and enabled with the 'mouse' option, a status line can
+be dragged to resize windows.
+
+Note: If you expect your status line to be in reverse video and it isn't,
+check if the 'highlight' option contains "si".  In version 3.0, this meant to
+invert the status line.  Now it should be "sr", reverse the status line, as
+"si" now stands for italic!  If italic is not available on your terminal, the
+status line is inverted anyway; you will only see this problem on terminals
+that have termcap codes for italics.
+
+==============================================================================
+3. Opening and closing a window				*opening-window* *E36*
+
+CTRL-W s						*CTRL-W_s*
+CTRL-W S						*CTRL-W_S*
+CTRL-W CTRL-S						*CTRL-W_CTRL-S*
+:[N]sp[lit] [++opt] [+cmd]				*:sp* *:split*
+		Split current window in two.  The result is two viewports on
+		the same file.  Make new window N high (default is to use half
+		the height of the current window).  Reduces the current window
+		height to create room (and others, if the 'equalalways' option
+		is set and 'eadirection' isn't "hor").
+		Note: CTRL-S does not work on all terminals and might block
+		further input, use CTRL-Q to get going again.
+		Also see |++opt| and |+cmd|.
+
+CTRL-W CTRL-V						*CTRL-W_CTRL-V*
+CTRL-W v						*CTRL-W_v*
+:[N]vs[plit] [++opt] [+cmd] [file]			*:vs* *:vsplit*
+		Like |:split|, but split vertically.  If 'equalalways' is set
+		and 'eadirection' isn't "ver" the windows will be spread out
+		horizontally, unless a width was specified.
+		Note: In other places CTRL-Q does the same as CTRL-V, but here
+		it doesn't!
+
+CTRL-W n						*CTRL-W_n*
+CTRL-W CTRL_N						*CTRL-W_CTRL-N*
+:[N]new [++opt] [+cmd]					*:new*
+		Create a new window and start editing an empty file in it.
+		Make new window N high (default is to use half the existing
+		height).  Reduces the current window height to create room (and
+		others, if the 'equalalways' option is set and 'eadirection'
+		isn't "hor").
+		Also see |++opt| and |+cmd|.
+		If 'fileformats' is not empty, the first format given will be
+		used for the new buffer.  If 'fileformats' is empty, the
+		'fileformat' of the current buffer is used.  This can be
+		overridden with the |++opt| argument.
+		Autocommands are executed in this order:
+		1. WinLeave for the current window
+		2. WinEnter for the new window
+		3. BufLeave for the current buffer
+		4. BufEnter for the new buffer
+		This behaves like a ":split" first, and then a ":e" command.
+
+:[N]vne[w] [++opt] [+cmd] [file]			*:vne* *:vnew*
+		Like |:new|, but split vertically.  If 'equalalways' is set
+		and 'eadirection' isn't "ver" the windows will be spread out
+		horizontally, unless a width was specified.
+
+:[N]new [++opt] [+cmd] {file}
+:[N]sp[lit] [++opt] [+cmd] {file}			*:split_f*
+		Create a new window and start editing file {file} in it.
+		If [+cmd] is given, execute the command when the file has been
+		loaded |+cmd|.
+		Also see |++opt|.
+		Make new window N high (default is to use half the existing
+		height).  Reduces the current window height to create room
+		(and others, if the 'equalalways' option is set).
+
+:[N]sv[iew] [++opt] [+cmd] {file}		*:sv* *:sview* *splitview*
+		Same as ":split", but set 'readonly' option for this buffer.
+
+:[N]sf[ind] [++opt] [+cmd] {file}		*:sf* *:sfind* *splitfind*
+		Same as ":split", but search for {file} in 'path'.  Doesn't
+		split if {file} is not found.
+
+CTRL-W CTRL-^					*CTRL-W_CTRL-^* *CTRL-W_^*
+CTRL-W ^	Does ":split #", split window in two and edit alternate file.
+		When a count is given, it becomes ":split #N", split window
+		and edit buffer N.
+
+Note that the 'splitbelow' and 'splitright' options influence where a new
+window will appear.
+
+						*:vert* *:vertical*
+:vert[ical] {cmd}
+		Execute {cmd}.  If it contains a command that splits a window,
+		it will be split vertically.
+		Doesn't work for |:execute| and |:normal|.
+
+:lefta[bove] {cmd}				*:lefta* *:leftabove*
+:abo[veleft] {cmd}				*:abo* *:aboveleft*
+		Execute {cmd}.  If it contains a command that splits a window,
+		it will be opened left (vertical split) or above (horizontal
+		split) the current window.  Overrules 'splitbelow' and
+		'splitright'.
+		Doesn't work for |:execute| and |:normal|.
+
+:rightb[elow] {cmd}				*:rightb* *:rightbelow*
+:bel[owright] {cmd}				*:bel* *:belowright*
+		Execute {cmd}.  If it contains a command that splits a window,
+		it will be opened right (vertical split) or below (horizontal
+		split) the current window.  Overrules 'splitbelow' and
+		'splitright'.
+		Doesn't work for |:execute| and |:normal|.
+
+						*:topleft* *E442*
+:to[pleft] {cmd}
+		Execute {cmd}.  If it contains a command that splits a window,
+		it will appear at the top and occupy the full width of the Vim
+		window.  When the split is vertical the window appears at the
+		far left and occupies the full height of the Vim window.
+		Doesn't work for |:execute| and |:normal|.
+
+						*:botright*
+:bo[tright] {cmd}
+		Execute {cmd}.  If it contains a command that splits a window,
+		it will appear at the bottom and occupy the full width of the
+		Vim window.  When the split is vertical the window appears at
+		the far right and occupies the full height of the Vim window.
+		Doesn't work for |:execute| and |:normal|.
+
+These command modifiers can be combined to make a vertically split window
+occupy the full height.  Example: >
+	:vertical topleft edit tags
+Opens a vertically split, full-height window on the "tags" file at the far
+left of the Vim window.
+
+
+Closing a window
+----------------
+
+CTRL-W q						*CTRL-W_q*
+CTRL-W CTRL-Q						*CTRL-W_CTRL-Q*
+:q[uit]		Quit current window.  When quitting the last window (not
+		counting a help window), exit Vim.
+		When 'hidden' is set, and there is only one window for the
+		current buffer, it becomes hidden.
+		When 'hidden' is not set, and there is only one window for the
+		current buffer, and the buffer was changed, the command fails.
+		(Note: CTRL-Q does not work on all terminals)
+
+:q[uit]!	Quit current window.  If this was the last window for a buffer,
+		any changes to that buffer are lost.  When quitting the last
+		window (not counting help windows), exit Vim.  The contents of
+		the buffer are lost, even when 'hidden' is set.
+
+CTRL-W c					*CTRL-W_c* *:clo* *:close*
+:clo[se][!]	Close current window.  When the 'hidden' option is set, or
+		when the buffer was changed and the [!] is used, the buffer
+		becomes hidden (unless there is another window editing it).
+		When there is only one window in the current tab page and
+		there is another tab page, this closes the current tab page.
+		|tab-page|.
+		This command fails when:			*E444*
+		- There is only one window on the screen.
+		- When 'hidden' is not set, [!] is not used, the buffer has
+		  changes, and there is no other window on this buffer.
+		Changes to the buffer are not written and won't get lost, so
+		this is a "safe" command.
+
+CTRL-W CTRL-C						*CTRL-W_CTRL-C*
+		You might have expected that CTRL-W CTRL-C closes the current
+		window, but that does not work, because the CTRL-C cancels the
+		command.
+
+							*:hide*
+:hid[e]		Quit current window, unless it is the last window on the
+		screen.  The buffer becomes hidden (unless there is another
+		window editing it or 'bufhidden' is "unload" or "delete").
+		If the window is the last one in the current tab page the tab
+		page is closed. |tab-page|
+		The value of 'hidden' is irrelevant for this command.
+		Changes to the buffer are not written and won't get lost, so
+		this is a "safe" command.
+
+:hid[e] {cmd}	Execute {cmd} with 'hidden' is set.  The previous value of
+		'hidden' is restored after {cmd} has been executed.
+		Example: >
+		    :hide edit Makefile
+<		This will edit "Makefile", and hide the current buffer if it
+		has any changes.
+
+CTRL-W o						*CTRL-W_o* *E445*
+CTRL-W CTRL-O					*CTRL-W_CTRL-O* *:on* *:only*
+:on[ly][!]	Make the current window the only one on the screen.  All other
+		windows are closed.
+		When the 'hidden' option is set, all buffers in closed windows
+		become hidden.
+		When 'hidden' is not set, and the 'autowrite' option is set,
+		modified buffers are written.  Otherwise, windows that have
+		buffers that are modified are not removed, unless the [!] is
+		given, then they become hidden.  But modified buffers are
+		never abandoned, so changes cannot get lost.
+
+==============================================================================
+4. Moving cursor to other windows			*window-move-cursor*
+
+CTRL-W <Down>					*CTRL-W_<Down>*
+CTRL-W CTRL-J					*CTRL-W_CTRL-J* *CTRL-W_j*
+CTRL-W j	Move cursor to Nth window below current one.  Uses the cursor
+		position to select between alternatives.
+
+CTRL-W <Up>					*CTRL-W_<Up>*
+CTRL-W CTRL-K					*CTRL-W_CTRL-K* *CTRL-W_k*
+CTRL-W k	Move cursor to Nth window above current one.  Uses the cursor
+		position to select between alternatives.
+
+CTRL-W <Left>					*CTRL-W_<Left>*
+CTRL-W CTRL-H					*CTRL-W_CTRL-H*
+CTRL-W <BS>					*CTRL-W_<BS>* *CTRL-W_h*
+CTRL-W h	Move cursor to Nth window left of current one.  Uses the
+		cursor position to select between alternatives.
+
+CTRL-W <Right>					*CTRL-W_<Right>*
+CTRL-W CTRL-L					*CTRL-W_CTRL-L* *CTRL-W_l*
+CTRL-W l	Move cursor to Nth window right of current one.  Uses the
+		cursor position to select between alternatives.
+
+CTRL-W w					*CTRL-W_w* *CTRL-W_CTRL-W*
+CTRL-W CTRL-W	Without count: move cursor to window below/right of the
+		current one.  If there is no window below or right, go to
+		top-left window.
+		With count: go to Nth window (windows are numbered from
+		top-left to bottom-right).  To obtain the window number see
+		|bufwinnr()| and |winnr()|.
+
+						*CTRL-W_W*
+CTRL-W W	Without count: move cursor to window above/left of current
+		one.  If there is no window above or left, go to bottom-right
+		window.  With count: go to Nth window (windows are numbered
+		from top-left to bottom-right).
+
+CTRL-W t					*CTRL-W_t* *CTRL-W_CTRL-T*
+CTRL-W CTRL-T	Move cursor to top-left window.
+
+CTRL-W b					*CTRL-W_b* *CTRL-W_CTRL-B*
+CTRL-W CTRL-B	Move cursor to bottom-right window.
+
+CTRL-W p					*CTRL-W_p* *CTRL-W_CTRL-P*
+CTRL-W CTRL-P	Go to previous (last accessed) window.
+
+						*CTRL-W_P* *E441*
+CTRL-W P	Go to preview window.  When there is no preview window this is
+		an error.
+		{not available when compiled without the |+quickfix| feature}
+
+If Visual mode is active and the new window is not for the same buffer, the
+Visual mode is ended.  If the window is on the same buffer, the cursor
+position is set to keep the same Visual area selected.
+
+						*:winc* *:wincmd*
+These commands can also be executed with ":wincmd":
+
+:[count]winc[md] {arg}
+		Like executing CTRL-W [count] {arg}.  Example: >
+			:wincmd j
+<		Moves to the window below the current one.
+		This command is useful when a Normal mode cannot be used (for
+		the |CursorHold| autocommand event).  Or when a Normal mode
+		command is inconvenient.
+		The count can also be a window number.  Example: >
+			:exe nr . "wincmd w"
+<		This goes to window "nr".
+
+==============================================================================
+5. Moving windows around				*window-moving*
+
+CTRL-W r				*CTRL-W_r* *CTRL-W_CTRL-R* *E443*
+CTRL-W CTRL-R	Rotate windows downwards/rightwards.  The first window becomes
+		the second one, the second one becomes the third one, etc.
+		The last window becomes the first window.  The cursor remains
+		in the same window.
+		This only works within the row or column of windows that the
+		current window is in.
+
+						*CTRL-W_R*
+CTRL-W R	Rotate windows upwards/leftwards.  The second window becomes
+		the first one, the third one becomes the second one, etc.  The
+		first window becomes the last window.  The cursor remains in
+		the same window.
+		This only works within the row or column of windows that the
+		current window is in.
+
+CTRL-W x					*CTRL-W_x* *CTRL-W_CTRL-X*
+CTRL-W CTRL-X	Without count: Exchange current window with next one.  If there
+		is no next window, exchange with previous window.
+		With count: Exchange current window with Nth window (first
+		window is 1).  The cursor is put in the other window.
+		When vertical and horizontal window splits are mixed, the
+		exchange is only done in the row or column of windows that the
+		current window is in.
+
+The following commands can be used to change the window layout.  For example,
+when there are two vertically split windows, CTRL-W K will change that in
+horizontally split windows.  CTRL-W H does it the other way around.
+
+						*CTRL-W_K*
+CTRL-W K	Move the current window to be at the very top, using the full
+		width of the screen.  This works like closing the current
+		window and then creating another one with ":topleft split",
+		except that the current window contents is used for the new
+		window.
+
+						*CTRL-W_J*
+CTRL-W J	Move the current window to be at the very bottom, using the
+		full width of the screen.  This works like closing the current
+		window and then creating another one with ":botright split",
+		except that the current window contents is used for the new
+		window.
+
+						*CTRL-W_H*
+CTRL-W H	Move the current window to be at the far left, using the
+		full height of the screen.  This works like closing the
+		current window and then creating another one with
+		":vert topleft split", except that the current window contents
+		is used for the new window.
+		{not available when compiled without the +vertsplit feature}
+
+						*CTRL-W_L*
+CTRL-W L	Move the current window to be at the far right, using the full
+		height of the screen.  This works like closing the
+		current window and then creating another one with
+		":vert botright split", except that the current window
+		contents is used for the new window.
+		{not available when compiled without the +vertsplit feature}
+
+						*CTRL-W_T*
+CTRL-W T	Move the current window to a new tab page.  This fails if
+		there is only one window in the current tab page.
+		When a count is specified the new tab page will be opened
+		before the tab page with this index.  Otherwise it comes after
+		the current tab page.
+
+==============================================================================
+6. Window resizing					*window-resize*
+
+						*CTRL-W_=*
+CTRL-W =	Make all windows (almost) equally high and wide, but use
+		'winheight' and 'winwidth' for the current window.
+		Windows with 'winfixheight' set keep their height and windows
+		with 'winfixwidth' set keep their width.
+
+:res[ize] -N					*:res* *:resize* *CTRL-W_-*
+CTRL-W -	Decrease current window height by N (default 1).
+		If used after 'vertical': decrease width by N.
+
+:res[ize] +N					*CTRL-W_+*
+CTRL-W +	Increase current window height by N (default 1).
+		If used after 'vertical': increase width by N.
+
+:res[ize] [N]
+CTRL-W CTRL-_					*CTRL-W_CTRL-_* *CTRL-W__*
+CTRL-W _	Set current window height to N (default: highest possible).
+
+z{nr}<CR>	Set current window height to {nr}.
+
+						*CTRL-W_<*
+CTRL-W <	Decrease current window width by N (default 1).
+
+						*CTRL-W_>*
+CTRL-W >	Increase current window width by N (default 1).
+
+:vertical res[ize] [N]			*:vertical-resize* *CTRL-W_bar*
+CTRL-W |	Set current window width to N (default: widest possible).
+
+You can also resize a window by dragging a status line up or down with the
+mouse.  Or by dragging a vertical separator line left or right.  This only
+works if the version of Vim that is being used supports the mouse and the
+'mouse' option has been set to enable it.
+
+The option 'winheight' ('wh') is used to set the minimal window height of the
+current window.  This option is used each time another window becomes the
+current window.  If the option is '0', it is disabled.  Set 'winheight' to a
+very large value, e.g., '9999', to make the current window always fill all
+available space.  Set it to a reasonable value, e.g., '10', to make editing in
+the current window comfortable.
+
+The equivalent 'winwidth' ('wiw') option is used to set the minimal width of
+the current window.
+
+When the option 'equalalways' ('ea') is set, all the windows are automatically
+made the same size after splitting or closing a window.  If you don't set this
+option, splitting a window will reduce the size of the current window and
+leave the other windows the same.  When closing a window, the extra lines are
+given to the window above it.
+
+The 'eadirection' option limits the direction in which the 'equalalways'
+option is applied.  The default "both" resizes in both directions.  When the
+value is "ver" only the heights of windows are equalized.  Use this when you
+have manually resized a vertically split window and want to keep this width.
+Likewise, "hor" causes only the widths of windows to be equalized.
+
+The option 'cmdheight' ('ch') is used to set the height of the command-line.
+If you are annoyed by the |hit-enter| prompt for long messages, set this
+option to 2 or 3.
+
+If there is only one window, resizing that window will also change the command
+line height.  If there are several windows, resizing the current window will
+also change the height of the window below it (and sometimes the window above
+it).
+
+The minimal height and width of a window is set with 'winminheight' and
+'winminwidth'.  These are hard values, a window will never become smaller.
+
+==============================================================================
+7. Argument and buffer list commands			*buffer-list*
+
+      args list		       buffer list	   meaning ~
+1. :[N]argument [N]	11. :[N]buffer [N]	to arg/buf N
+2. :[N]next [file ..]	12. :[N]bnext [N]	to Nth next arg/buf
+3. :[N]Next [N]		13. :[N]bNext [N]	to Nth previous arg/buf
+4. :[N]previous	[N]	14. :[N]bprevious [N]	to Nth previous arg/buf
+5. :rewind / :first	15. :brewind / :bfirst	to first arg/buf
+6. :last		16. :blast		to last arg/buf
+7. :all			17. :ball		edit all args/buffers
+			18. :unhide		edit all loaded buffers
+			19. :[N]bmod [N]	to Nth modified buf
+
+  split & args list	  split & buffer list	   meaning ~
+21. :[N]sargument [N]   31. :[N]sbuffer [N]	split + to arg/buf N
+22. :[N]snext [file ..] 32. :[N]sbnext [N]      split + to Nth next arg/buf
+23. :[N]sNext [N]       33. :[N]sbNext [N]      split + to Nth previous arg/buf
+24. :[N]sprevious [N]   34. :[N]sbprevious [N]  split + to Nth previous arg/buf
+25. :srewind / :sfirst	35. :sbrewind / :sbfirst split + to first arg/buf
+26. :slast		36. :sblast		split + to last arg/buf
+27. :sall		37. :sball		edit all args/buffers
+			38. :sunhide		edit all loaded buffers
+			39. :[N]sbmod [N]	split + to Nth modified buf
+
+40. :args		list of arguments
+41. :buffers		list of buffers
+
+The meaning of [N] depends on the command:
+ [N] is number of buffers to go forward/backward on ?2, ?3, and ?4
+ [N] is an argument number, defaulting to current argument, for 1 and 21
+ [N] is a buffer number, defaulting to current buffer, for 11 and 31
+ [N] is a count for 19 and 39
+
+Note: ":next" is an exception, because it must accept a list of file names
+for compatibility with Vi.
+
+
+The argument list and multiple windows
+--------------------------------------
+
+The current position in the argument list can be different for each window.
+Remember that when doing ":e file", the position in the argument list stays
+the same, but you are not editing the file at that position.  To indicate
+this, the file message (and the title, if you have one) shows
+"(file (N) of M)", where "(N)" is the current position in the file list, and
+"M" the number of files in the file list.
+
+All the entries in the argument list are added to the buffer list.  Thus, you
+can also get to them with the buffer list commands, like ":bnext".
+
+:[N]al[l][!] [N]				*:al* *:all* *:sal* *:sall*
+:[N]sal[l][!] [N]
+		Rearrange the screen to open one window for each argument.
+		All other windows are closed.  When a count is given, this is
+		the maximum number of windows to open.
+		With the |:tab| modifier open a tab page for each argument.
+		When there are more arguments than 'tabpagemax' further ones
+		become split windows in the last tab page.
+		When the 'hidden' option is set, all buffers in closed windows
+		become hidden.
+		When 'hidden' is not set, and the 'autowrite' option is set,
+		modified buffers are written.  Otherwise, windows that have
+		buffers that are modified are not removed, unless the [!] is
+		given, then they become hidden.  But modified buffers are
+		never abandoned, so changes cannot get lost.
+		[N] is the maximum number of windows to open.  'winheight'
+		also limits the number of windows opened ('winwidth' if
+		|:vertical| was prepended).
+		Buf/Win Enter/Leave autocommands are not executed for the new
+		windows here, that's only done when they are really entered.
+
+:[N]sa[rgument][!] [++opt] [+cmd] [N]			*:sa* *:sargument*
+		Short for ":split | argument [N]": split window and go to Nth
+		argument.  But when there is no such argument, the window is
+		not split.  Also see |++opt| and |+cmd|.
+
+:[N]sn[ext][!] [++opt] [+cmd] [file ..]			*:sn* *:snext*
+		Short for ":split | [N]next": split window and go to Nth next
+		argument.  But when there is no next file, the window is not
+		split.  Also see |++opt| and |+cmd|.
+
+:[N]spr[evious][!] [++opt] [+cmd] [N]			*:spr* *:sprevious*
+:[N]sN[ext][!] [++opt] [+cmd] [N]			*:sN* *:sNext*
+		Short for ":split | [N]Next": split window and go to Nth
+		previous argument.  But when there is no previous file, the
+		window is not split.  Also see |++opt| and |+cmd|.
+
+						*:sre* *:srewind*
+:sre[wind][!] [++opt] [+cmd]
+		Short for ":split | rewind": split window and go to first
+		argument.  But when there is no argument list, the window is
+		not split.  Also see |++opt| and |+cmd|.
+
+						*:sfir* *:sfirst*
+:sfir[st] [++opt] [+cmd]
+		Same as ":srewind".
+
+						*:sla* *:slast*
+:sla[st][!] [++opt] [+cmd]
+		Short for ":split | last": split window and go to last
+		argument.  But when there is no argument list, the window is
+		not split.  Also see |++opt| and |+cmd|.
+
+						*:dr* *:drop*
+:dr[op] {file} ..
+		Edit the first {file} in a window.
+		- If the file is already open in a window change to that
+		  window.
+		- If the file is not open in a window edit the file in the
+		  current window.  If the current buffer can't be |abandon|ed,
+		  the window is split first.
+		The |argument-list| is set, like with the |:next| command.
+		The purpose of this command is that it can be used from a
+		program that wants Vim to edit another file, e.g., a debugger.
+		When using the |:tab| modifier each argument is opened in a
+		tab page.  The last window is used if it's empty.
+		{only available when compiled with the +gui feature}
+
+==============================================================================
+8. Do a command in all buffers or windows			*list-repeat*
+
+							*:windo*
+:windo {cmd}		Execute {cmd} in each window.
+			It works like doing this: >
+				CTRL-W t
+				:{cmd}
+				CTRL-W w
+				:{cmd}
+				etc.
+<			This only operates in the current tab page.
+			When an error is detected on one window, further
+			windows will not be visited.
+			The last window (or where an error occurred) becomes
+			the current window.
+			{cmd} can contain '|' to concatenate several commands.
+			{cmd} must not open or close windows or reorder them.
+			{not in Vi} {not available when compiled without the
+			|+listcmds| feature}
+			Also see |:tabdo|, |:argdo| and |:bufdo|.
+
+							*:bufdo*
+:bufdo[!] {cmd}		Execute {cmd} in each buffer in the buffer list.
+			It works like doing this: >
+				:bfirst
+				:{cmd}
+				:bnext
+				:{cmd}
+				etc.
+<			When the current file can't be |abandon|ed and the [!]
+			is not present, the command fails.
+			When an error is detected on one buffer, further
+			buffers will not be visited.
+			Unlisted buffers are skipped.
+			The last buffer (or where an error occurred) becomes
+			the current buffer.
+			{cmd} can contain '|' to concatenate several commands.
+			{cmd} must not delete buffers or add buffers to the
+			buffer list.
+			Note: While this command is executing, the Syntax
+			autocommand event is disabled by adding it to
+			'eventignore'.  This considerably speeds up editing
+			each buffer.
+			{not in Vi} {not available when compiled without the
+			|+listcmds| feature}
+			Also see |:tabdo|, |:argdo| and |:windo|.
+
+Examples: >
+
+	:windo set nolist nofoldcolumn | normal zn
+
+This resets the 'list' option and disables folding in all windows. >
+
+	:bufdo set fileencoding= | update
+
+This resets the 'fileencoding' in each buffer and writes it if this changed
+the buffer.  The result is that all buffers will use the 'encoding' encoding
+(if conversion works properly).
+
+==============================================================================
+9. Tag or file name under the cursor			*window-tag*
+
+							*:sta* *:stag*
+:sta[g][!] [tagname]
+		Does ":tag[!] [tagname]" and splits the window for the found
+		tag.  See also |:tag|.
+
+CTRL-W ]					*CTRL-W_]* *CTRL-W_CTRL-]*
+CTRL-W CTRL-]	Split current window in two.  Use identifier under cursor as a
+		tag and jump to it in the new upper window.  Make new window N
+		high.
+
+							*CTRL-W_g]*
+CTRL-W g ]	Split current window in two.  Use identifier under cursor as a
+		tag and perform ":tselect" on it in the new upper window.
+		Make new window N high.
+
+							*CTRL-W_g_CTRL-]*
+CTRL-W g CTRL-]	Split current window in two.  Use identifier under cursor as a
+		tag and perform ":tjump" on it in the new upper window.  Make
+		new window N high.
+
+CTRL-W f					*CTRL-W_f* *CTRL-W_CTRL-F*
+CTRL-W CTRL-F	Split current window in two.  Edit file name under cursor.
+		Like ":split gf", but window isn't split if the file does not
+		exist.
+		Uses the 'path' variable as a list of directory names where to
+		look for the file.  Also the path for current file is
+		used to search for the file name.
+		If the name is a hypertext link that looks like
+		"type://machine/path", only "/path" is used.
+		If a count is given, the count'th matching file is edited.
+		{not available when the |+file_in_path| feature was disabled
+		at compile time}
+
+CTRL-W F						*CTRL-W_F*
+		Split current window in two.  Edit file name under cursor and
+		jump to the line number following the file name. See |gF| for
+		details on how the line number is obtained.
+		{not available when the |+file_in_path| feature was disabled
+		at compile time}
+
+CTRL-W gf						*CTRL-W_gf*
+		Open a new tab page and edit the file name under the cursor.
+		Like "tab split" and "gf", but the new tab page isn't created
+		if the file does not exist.
+		{not available when the |+file_in_path| feature was disabled
+		at compile time}
+
+CTRL-W gF						*CTRL-W_gF*
+		Open a new tab page and edit the file name under the cursor
+		and jump to the line number following the file name.  Like
+		"tab split" and "gF", but the new tab page isn't created if
+		the file does not exist.
+		{not available when the |+file_in_path| feature was disabled
+		at compile time}
+
+Also see |CTRL-W_CTRL-I|: open window for an included file that includes
+the keyword under the cursor.
+
+==============================================================================
+10. The preview window				*preview-window*
+
+The preview window is a special window to show (preview) another file.  It is
+normally a small window used to show an include file or definition of a
+function.
+{not available when compiled without the |+quickfix| feature}
+
+There can be only one preview window (per tab page).  It is created with one
+of the commands below.  The 'previewheight' option can be set to specify the
+height of the preview window when it's opened.  The 'previewwindow' option is
+set in the preview window to be able to recognize it.  The 'winfixheight'
+option is set to have it keep the same height when opening/closing other
+windows.
+
+						*:pta* *:ptag*
+:pta[g][!] [tagname]
+		Does ":tag[!] [tagname]" and shows the found tag in a
+		"Preview" window without changing the current buffer or cursor
+		position.  If a "Preview" window already exists, it is re-used
+		(like a help window is).  If a new one is opened,
+		'previewheight' is used for the height of the window.   See
+		also |:tag|.
+		See below for an example. |CursorHold-example|
+		Small difference from |:tag|: When [tagname] is equal to the
+		already displayed tag, the position in the matching tag list
+		is not reset.  This makes the CursorHold example work after a
+		|:ptnext|.
+
+CTRL-W z					*CTRL-W_z*
+CTRL-W CTRL-Z					*CTRL-W_CTRL-Z* *:pc* *:pclose*
+:pc[lose][!]	Close any "Preview" window currently open.  When the 'hidden'
+		option is set, or when the buffer was changed and the [!] is
+		used, the buffer becomes hidden (unless there is another
+		window editing it).  The command fails if any "Preview" buffer
+		cannot be closed.  See also |:close|.
+
+							*:pp* *:ppop*
+:[count]pp[op][!]
+		Does ":[count]pop[!]" in the preview window.  See |:pop| and
+		|:ptag|.  {not in Vi}
+
+CTRL-W }						*CTRL-W_}*
+		Use identifier under cursor as a tag and perform a :ptag on
+		it.  Make the new Preview window (if required) N high.  If N is
+		not given, 'previewheight' is used.
+
+CTRL-W g }						*CTRL-W_g}*
+		Use identifier under cursor as a tag and perform a :ptjump on
+		it.  Make the new Preview window (if required) N high.  If N is
+		not given, 'previewheight' is used.
+
+							*:ped* *:pedit*
+:ped[it][!] [++opt] [+cmd] {file}
+		Edit {file} in the preview window.  The preview window is
+		opened like with |:ptag|.  The current window and cursor
+		position isn't changed.  Useful example: >
+			:pedit +/fputc /usr/include/stdio.h
+<
+							*:ps* *:psearch*
+:[range]ps[earch][!] [count] [/]pattern[/]
+		Works like |:ijump| but shows the found match in the preview
+		window.  The preview window is opened like with |:ptag|.  The
+		current window and cursor position isn't changed.  Useful
+		example: >
+			:psearch popen
+<		Like with the |:ptag| command, you can use this to
+		automatically show information about the word under the
+		cursor.  This is less clever than using |:ptag|, but you don't
+		need a tags file and it will also find matches in system
+		include files.  Example: >
+  :au! CursorHold *.[ch] nested exe "silent! psearch " . expand("<cword>")
+<		Warning: This can be slow.
+
+Example						*CursorHold-example*  >
+
+  :au! CursorHold *.[ch] nested exe "silent! ptag " . expand("<cword>")
+
+This will cause a ":ptag" to be executed for the keyword under the cursor,
+when the cursor hasn't moved for the time set with 'updatetime'.  The "nested"
+makes other autocommands be executed, so that syntax highlighting works in the
+preview window.  The "silent!" avoids an error message when the tag could not
+be found.  Also see |CursorHold|.  To disable this again: >
+
+  :au! CursorHold
+
+A nice addition is to highlight the found tag, avoid the ":ptag" when there
+is no word under the cursor, and a few other things: >
+
+  :au! CursorHold *.[ch] nested call PreviewWord()
+  :func PreviewWord()
+  :  if &previewwindow			" don't do this in the preview window
+  :    return
+  :  endif
+  :  let w = expand("<cword>")		" get the word under cursor
+  :  if w =~ '\a'			" if the word contains a letter
+  :
+  :    " Delete any existing highlight before showing another tag
+  :    silent! wincmd P			" jump to preview window
+  :    if &previewwindow			" if we really get there...
+  :      match none			" delete existing highlight
+  :      wincmd p			" back to old window
+  :    endif
+  :
+  :    " Try displaying a matching tag for the word under the cursor
+  :    try
+  :       exe "ptag " . w
+  :    catch
+  :      return
+  :    endtry
+  :
+  :    silent! wincmd P			" jump to preview window
+  :    if &previewwindow		" if we really get there...
+  :	 if has("folding")
+  :	   silent! .foldopen		" don't want a closed fold
+  :	 endif
+  :	 call search("$", "b")		" to end of previous line
+  :	 let w = substitute(w, '\\', '\\\\', "")
+  :	 call search('\<\V' . w . '\>')	" position cursor on match
+  :	 " Add a match highlight to the word at this position
+  :      hi previewWord term=bold ctermbg=green guibg=green
+  :	 exe 'match previewWord "\%' . line(".") . 'l\%' . col(".") . 'c\k*"'
+  :      wincmd p			" back to old window
+  :    endif
+  :  endif
+  :endfun
+
+==============================================================================
+11. Using hidden buffers				*buffer-hidden*
+
+A hidden buffer is not displayed in a window, but is still loaded into memory.
+This makes it possible to jump from file to file, without the need to read or
+write the file every time you get another buffer in a window.
+{not available when compiled without the |+listcmds| feature}
+
+							*:buffer-!*
+If the option 'hidden' ('hid') is set, abandoned buffers are kept for all
+commands that start editing another file: ":edit", ":next", ":tag", etc.  The
+commands that move through the buffer list sometimes make the current buffer
+hidden although the 'hidden' option is not set.  This happens when a buffer is
+modified, but is forced (with '!') to be removed from a window, and
+'autowrite' is off or the buffer can't be written.
+
+You can make a hidden buffer not hidden by starting to edit it with any
+command.  Or by deleting it with the ":bdelete" command.
+
+The 'hidden' is global, it is used for all buffers.  The 'bufhidden' option
+can be used to make an exception for a specific buffer.  It can take these
+values:
+	<empty>		Use the value of 'hidden'.
+	hide		Hide this buffer, also when 'hidden' is not set.
+	unload		Don't hide but unload this buffer, also when 'hidden'
+			is set.
+	delete		Delete the buffer.
+
+							*hidden-quit*
+When you try to quit Vim while there is a hidden, modified buffer, you will
+get an error message and Vim will make that buffer the current buffer.  You
+can then decide to write this buffer (":wq") or quit without writing (":q!").
+Be careful: there may be more hidden, modified buffers!
+
+A buffer can also be unlisted.  This means it exists, but it is not in the
+list of buffers. |unlisted-buffer|
+
+
+:files[!]					*:files*
+:buffers[!]					*:buffers* *:ls*
+:ls[!]		Show all buffers.  Example:
+
+			1 #h  "/test/text"		line 1 ~
+			2u    "asdf"			line 0 ~
+			3 %a+ "version.c"		line 1 ~
+
+		When the [!] is included the list will show unlisted buffers
+		(the term "unlisted" is a bit confusing then...).
+
+		Each buffer has a unique number.  That number will not change,
+		so you can always go to a specific buffer with ":buffer N" or
+		"N CTRL-^", where N is the buffer number.
+
+		Indicators (chars in the same column are mutually exclusive):
+		u	an unlisted buffer (only displayed when [!] is used)
+			   |unlisted-buffer|
+		 %	the buffer in the current window
+		 #	the alternate buffer for ":e #" and CTRL-^
+		  a	an active buffer: it is loaded and visible
+		  h	a hidden buffer: It is loaded, but currently not
+			   displayed in a window |hidden-buffer|
+		   -	a buffer with 'modifiable' off
+		   =	a readonly buffer
+		    +	a modified buffer
+		    x   a buffer with read errors
+
+						*:bad* *:badd*
+:bad[d]	[+lnum] {fname}
+		Add file name {fname} to the buffer list, without loading it.
+		If "lnum" is specified, the cursor will be positioned at that
+		line when the buffer is first entered.  Note that other
+		commands after the + will be ignored.
+
+:[N]bd[elete][!]			*:bd* *:bdel* *:bdelete* *E516*
+:bd[elete][!] [N]
+		Unload buffer [N] (default: current buffer) and delete it from
+		the buffer list.  If the buffer was changed, this fails,
+		unless when [!] is specified, in which case changes are lost.
+		The file remains unaffected.  Any windows for this buffer are
+		closed.  If buffer [N] is the current buffer, another buffer
+		will be displayed instead.  This is the most recent entry in
+		the jump list that points into a loaded buffer.
+		Actually, the buffer isn't completely deleted, it is removed
+		from the buffer list |unlisted-buffer| and option values,
+		variables and mappings/abbreviations for the buffer are
+		cleared.
+
+:bdelete[!] {bufname}						*E93* *E94*
+		Like ":bdelete[!] [N]", but buffer given by name.  Note that a
+		buffer whose name is a number cannot be referenced by that
+		name; use the buffer number instead.  Insert a backslash
+		before a space in a buffer name.
+
+:bdelete[!] N1 N2 ...
+		Do ":bdelete[!]" for buffer N1, N2, etc.  The arguments can be
+		buffer numbers or buffer names (but not buffer names that are
+		a number).  Insert a backslash before a space in a buffer
+		name.
+
+:N,Mbdelete[!]	Do ":bdelete[!]" for all buffers in the range N to M
+		|inclusive|.
+
+:[N]bw[ipeout][!]			*:bw* *:bwipe* *:bwipeout* *E517*
+:bw[ipeout][!] {bufname}
+:N,Mbw[ipeout][!]
+:bw[ipeout][!] N1 N2 ...
+		Like |:bdelete|, but really delete the buffer.  Everything
+		related to the buffer is lost.  All marks in this buffer
+		become invalid, option settings are lost, etc.  Don't use this
+		unless you know what you are doing.
+
+:[N]bun[load][!]				*:bun* *:bunload* *E515*
+:bun[load][!] [N]
+		Unload buffer [N] (default: current buffer).  The memory
+		allocated for this buffer will be freed.  The buffer remains
+		in the buffer list.
+		If the buffer was changed, this fails, unless when [!] is
+		specified, in which case the changes are lost.
+		Any windows for this buffer are closed.  If buffer [N] is the
+		current buffer, another buffer will be displayed instead.
+		This is the most recent entry in the jump list that points
+		into a loaded buffer.
+
+:bunload[!] {bufname}
+		Like ":bunload[!] [N]", but buffer given by name.  Note that a
+		buffer whose name is a number cannot be referenced by that
+		name; use the buffer number instead.  Insert a backslash
+		before a space in a buffer name.
+
+:N,Mbunload[!]	Do ":bunload[!]" for all buffers in the range N to M
+		|inclusive|.
+
+:bunload[!] N1 N2 ...
+		Do ":bunload[!]" for buffer N1, N2, etc.  The arguments can be
+		buffer numbers or buffer names (but not buffer names that are
+		a number).  Insert a backslash before a space in a buffer
+		name.
+
+:[N]b[uffer][!] [N]			*:b* *:bu* *:buf* *:buffer* *E86*
+		Edit buffer [N] from the buffer list.  If [N] is not given,
+		the current buffer remains being edited.  See |:buffer-!| for
+		[!].  This will also edit a buffer that is not in the buffer
+		list, without setting the 'buflisted' flag.
+
+:[N]b[uffer][!] {filename}
+		Edit buffer for {filename} from the buffer list.  See
+		|:buffer-!| for [!].  This will also edit a buffer that is not
+		in the buffer list, without setting the 'buflisted' flag.
+
+:[N]sb[uffer] [N]					*:sb* *:sbuffer*
+		Split window and edit buffer [N] from the buffer list.  If [N]
+		is not given, the current buffer is edited.  Respects the
+		"useopen" setting of 'switchbuf' when splitting.  This will
+		also edit a buffer that is not in the buffer list, without
+		setting the 'buflisted' flag.
+
+:[N]sb[uffer] {filename}
+		Split window and edit buffer for {filename} from the buffer
+		list.  This will also edit a buffer that is not in the buffer
+		list, without setting the 'buflisted' flag.
+		Note: If what you want to do is split the buffer, make a copy
+		under another name, you can do it this way: >
+			:w foobar | sp #
+
+:[N]bn[ext][!] [N]					*:bn* *:bnext* *E87*
+		Go to [N]th next buffer in buffer list.  [N] defaults to one.
+		Wraps around the end of the buffer list.
+		See |:buffer-!| for [!].
+		If you are in a help buffer, this takes you to the next help
+		buffer (if there is one).  Similarly, if you are in a normal
+		(non-help) buffer, this takes you to the next normal buffer.
+		This is so that if you have invoked help, it doesn't get in
+		the way when you're browsing code/text buffers.  The next three
+		commands also work like this.
+
+							*:sbn* *:sbnext*
+:[N]sbn[ext] [N]
+		Split window and go to [N]th next buffer in buffer list.
+		Wraps around the end of the buffer list.  Uses 'switchbuf'
+
+:[N]bN[ext][!] [N]			*:bN* *:bNext* *:bp* *:bprevious* *E88*
+:[N]bp[revious][!] [N]
+		Go to [N]th previous buffer in buffer list.  [N] defaults to
+		one.  Wraps around the start of the buffer list.
+		See |:buffer-!| for [!] and 'switchbuf'.
+
+:[N]sbN[ext] [N]			*:sbN* *:sbNext* *:sbp* *:sbprevious*
+:[N]sbp[revious] [N]
+		Split window and go to [N]th previous buffer in buffer list.
+		Wraps around the start of the buffer list.
+		Uses 'switchbuf'.
+
+							*:br* *:brewind*
+:br[ewind][!]	Go to first buffer in buffer list.  If the buffer list is
+		empty, go to the first unlisted buffer.
+		See |:buffer-!| for [!].
+
+							*:bf* *:bfirst*
+:bf[irst]	Same as ":brewind".
+
+							*:sbr* *:sbrewind*
+:sbr[ewind]	Split window and go to first buffer in buffer list.  If the
+		buffer list is empty, go to the first unlisted buffer.
+		Respects the 'switchbuf' option.
+
+							*:sbf* *:sbfirst*
+:sbf[irst]	Same as ":sbrewind".
+
+							*:bl* *:blast*
+:bl[ast][!]	Go to last buffer in buffer list.  If the buffer list is
+		empty, go to the last unlisted buffer.
+		See |:buffer-!| for [!].
+
+							*:sbl* *:sblast*
+:sbl[ast]	Split window and go to last buffer in buffer list.  If the
+		buffer list is empty, go to the last unlisted buffer.
+		Respects 'switchbuf' option.
+
+:[N]bm[odified][!] [N]				*:bm* *:bmodified* *E84*
+		Go to [N]th next modified buffer.  Note: this command also
+		finds unlisted buffers.  If there is no modified buffer the
+		command fails.
+
+:[N]sbm[odified] [N]					*:sbm* *:sbmodified*
+		Split window and go to [N]th next modified buffer.
+		Respects 'switchbuf' option.
+		Note: this command also finds buffers not in the buffer list.
+
+:[N]unh[ide] [N]			*:unh* *:unhide* *:sun* *:sunhide*
+:[N]sun[hide] [N]
+		Rearrange the screen to open one window for each loaded buffer
+		in the buffer list.  When a count is given, this is the
+		maximum number of windows to open.
+
+:[N]ba[ll] [N]					*:ba* *:ball* *:sba* *:sball*
+:[N]sba[ll] [N]	Rearrange the screen to open one window for each buffer in
+		the buffer list.  When a count is given, this is the maximum
+		number of windows to open.  'winheight' also limits the number
+		of windows opened ('winwidth' if |:vertical| was prepended).
+		Buf/Win Enter/Leave autocommands are not executed for the new
+		windows here, that's only done when they are really entered.
+		When the |:tab| modifier is used new windows are opened in a
+		new tab, up to 'tabpagemax'.
+
+Note: All the commands above that start editing another buffer, keep the
+'readonly' flag as it was.  This differs from the ":edit" command, which sets
+the 'readonly' flag each time the file is read.
+
+==============================================================================
+12. Special kinds of buffers			*special-buffers*
+
+Instead of containing the text of a file, buffers can also be used for other
+purposes.  A few options can be set to change the behavior of a buffer:
+	'bufhidden'	what happens when the buffer is no longer displayed
+			in a window.
+	'buftype'	what kind of a buffer this is
+	'swapfile'	whether the buffer will have a swap file
+	'buflisted'	buffer shows up in the buffer list
+
+A few useful kinds of a buffer:
+
+quickfix	Used to contain the error list or the location list.  See
+		|:cwindow| and |:lwindow|.  This command sets the 'buftype'
+		option to "quickfix".  You are not supposed to change this!
+		'swapfile' is off.
+
+help		Contains a help file.  Will only be created with the |:help|
+		command.  The flag that indicates a help buffer is internal
+		and can't be changed.  The 'buflisted' option will be reset
+		for a help buffer.
+
+directory	Displays directory contents.  Can be used by a file explorer
+		plugin.  The buffer is created with these settings: >
+			:setlocal buftype=nowrite
+			:setlocal bufhidden=delete
+			:setlocal noswapfile
+<		The buffer name is the name of the directory and is adjusted
+		when using the |:cd| command.
+
+scratch		Contains text that can be discarded at any time.  It is kept
+		when closing the window, it must be deleted explicitly.
+		Settings: >
+			:setlocal buftype=nofile
+			:setlocal bufhidden=hide
+			:setlocal noswapfile
+<		The buffer name can be used to identify the buffer.
+
+						*unlisted-buffer*
+unlisted	The buffer is not in the buffer list.  It is not used for
+		normal editing, but to show a help file, remember a file name
+		or marks.  The ":bdelete" command will also set this option,
+		thus it doesn't completely delete the buffer.  Settings: >
+			:setlocal nobuflisted
+<
+
+ vim:tw=78:ts=8:ft=help:norl:
--- /dev/null
+++ b/lib/vimfiles/doc/workshop.txt
@@ -1,0 +1,98 @@
+*workshop.txt*  For Vim version 7.1.  Last change: 2006 Apr 24
+
+
+		  VIM REFERENCE MANUAL    by Gordon Prieur
+
+
+Sun Visual WorkShop Features			*workshop* *workshop-support*
+
+1. Introduction						|workshop-intro|
+2. Commands						|workshop-commands|
+3. Compiling vim/gvim for WorkShop			|workshop-compiling|
+4. Configuring gvim for a WorkShop release tree		|workshop-configure|
+5. Obtaining the latest version of the XPM library	|workshop-xpm|
+
+{Vi does not have any of these features}
+{only available when compiled with the |+sun_workshop| feature}
+
+==============================================================================
+1. Introduction						*workshop-intro*
+
+Sun Visual WorkShop has an "Editor of Choice" feature designed to let users
+debug using their favorite editors.  For the 6.0 release we have added support
+for gvim.  A workshop debug session will have a debugging window and an editor
+window (possibly others as well).  The user can do many debugging operations
+from the editor window, minimizing the need to switch from window to window.
+
+The version of vim shipped with Sun Visual WorkShop 6 (also called Forte
+Developer 6) is vim 5.3.  The features in this release are much more reliable
+than the vim/gvim shipped with Visual WorkShop.  VWS users wishing to use vim
+as their editor should compile these sources and install them in their
+workshop release tree.
+
+==============================================================================
+2. Commands						*workshop-commands*
+
+						*:ws* *:wsverb*
+:ws[verb] verb			Pass the verb to the verb executor
+
+Pass the verb to a workshop function which gathers some arguments and
+sends the verb and data to workshop over an IPC connection.
+
+==============================================================================
+3. Compiling vim/gvim for WorkShop			*workshop-compiling*
+
+Compiling vim with FEAT_SUN_WORKSHOP turns on all compile time flags necessary
+for building a vim to work with Visual WorkShop.  The features required for VWS
+have been built and tested using the Sun compilers from the VWS release.  They
+have not been built or tested using Gnu compilers.  This does not mean the
+features won't build and run if compiled with gcc, just that nothing is
+guaranteed with gcc!
+
+==============================================================================
+4. Configuring gvim for a WorkShop release tree		*workshop-configure*
+
+There are several assumptions which must be met in order to compile a gvim for
+use with Sun Visual WorkShop 6.
+
+    o You should use the compiler in VWS rather than gcc.  We have neither
+      built nor tested with gcc and cannot guarantee it will build properly.
+
+    o You must supply your own XPM library.  See |workshop-xpm| below for
+      details on obtaining the latest version of XPM.
+
+    o Edit the Makefile in the src directory and uncomment the lines for Sun
+      Visual WorkShop.  You can easily find these by searching for the string
+      FEAT_SUN_WORKSHOP
+
+    o We also suggest you use Motif for your gui.  This will provide gvim with
+      the same look-and-feel as the rest of Sun Visual WorkShop.
+
+The following configuration line can be used to configure vim to build for use
+with Sun Visual WorkShop:
+
+    $ CC=cc configure --enable-workshop --enable-gui=motif \
+	-prefix=<VWS-install-dir>/contrib/contrib6/<vim-version>
+
+The VWS-install-dir should be the base directory where your Sun Visual WorkShop
+was installed.  By default this is /opt/SUNWspro.  It will normally require
+root permissions to install the vim release.  You will also need to change the
+symlink <VWS-install-dir>/bin/gvim to point to the vim in your newly installed
+directory.  The <vim-version> should be a unique version string.  I use "vim"
+concatenated with the equivalent of version.h's VIM_VERSION_SHORT.
+
+==============================================================================
+5. Obtaining the latest version of the XPM library	*workshop-xpm*
+
+The XPM library is required to show images within Vim with Motif or Athena.
+Without it the toolbar and signs will be disabled.
+
+The XPM library is provide by Arnaud Le Hors of the French National Institute
+for Research in Computer Science and Control.  It can be downloaded from
+http://koala.ilog.fr/ftp/pub/xpm.  The current release, as of this writing, is
+xpm-3.4k-solaris.tgz, which is a gzip'ed tar file.  If you create the directory
+/usr/local/xpm and untar the file there you can use the uncommented lines in
+the Makefile without changing them.  If you use another xpm directory you will
+need to change the XPM_DIR in src/Makefile.
+
+ vim:tw=78:ts=8:ft=help:norl:
--- /dev/null
+++ b/lib/vimfiles/doc/xxd.1
@@ -1,0 +1,370 @@
+.TH XXD 1 "August 1996" "Manual page for xxd"
+.\"
+.\" 21st May 1996
+.\" Man page author:
+.\"    Tony Nugent <tony@sctnugen.ppp.gu.edu.au> <T.Nugent@sct.gu.edu.au>
+.\"    Changes by Bram Moolenaar <Bram@vim.org>
+.SH NAME
+.I xxd
+\- make a hexdump or do the reverse.
+.SH SYNOPSIS
+.B xxd
+\-h[elp]
+.br
+.B xxd
+[options] [infile [outfile]]
+.br
+.B xxd
+\-r[evert] [options] [infile [outfile]]
+.SH DESCRIPTION
+.I xxd
+creates a hex dump of a given file or standard input.
+It can also convert a hex dump back to its original binary form.
+Like
+.BR uuencode (1)
+and
+.BR uudecode (1)
+it allows the transmission of binary data in a `mail-safe' ASCII representation,
+but has the advantage of decoding to standard output.
+Moreover, it can be used to perform binary file patching.
+.SH OPTIONS
+If no
+.I infile
+is given, standard input is read.
+If
+.I infile
+is specified as a
+.RB \` \- '
+character, then input is taken from standard input.
+If no
+.I outfile
+is given (or a
+.RB \` \- '
+character is in its place), results are sent to standard output.
+.PP
+Note that a "lazy" parser is used which does not check for more than the first
+option letter, unless the option is followed by a parameter.
+Spaces between a single option letter and its parameter are optional.
+Parameters to options can be specified in decimal, hexadecimal or octal
+notation.
+Thus
+.BR \-c8 ,
+.BR "\-c 8" ,
+.B \-c 010
+and
+.B \-cols 8
+are all equivalent.
+.PP
+.TP
+.IR \-a " | " \-autoskip
+toggle autoskip: A single '*' replaces nul-lines.  Default off.
+.TP
+.IR \-b " | " \-bits
+Switch to bits (binary digits) dump, rather than hexdump.
+This option writes octets as eight digits "1"s and "0"s instead of a normal
+hexadecimal dump. Each line is preceded by a line number in hexadecimal and
+followed by an ascii (or ebcdic) representation. The command line switches
+\-r, \-p, \-i do not work with this mode.
+.TP
+.IR "\-c cols " | " \-cols cols"
+format
+.RI < cols >
+octets per line. Default 16 (\-i: 12, \-ps: 30, \-b: 6). Max 256.
+.TP
+.IR \-E " | " \-EBCDIC
+Change the character encoding in the righthand column from ASCII to EBCDIC.
+This does not change the hexadecimal representation. The option is
+meaningless in combinations with \-r, \-p or \-i.
+.TP
+.IR "\-g bytes " | " \-groupsize bytes"
+separate the output of every
+.RI < bytes >
+bytes (two hex characters or eight bit-digits each) by a whitespace.
+Specify
+.I \-g 0
+to suppress grouping.
+.RI < Bytes "> defaults to " 2
+in normal mode and \fI1\fP in bits mode.
+Grouping does not apply to postscript or include style.
+.TP
+.IR \-h " | " \-help
+print a summary of available commands and exit.  No hex dumping is performed.
+.TP
+.IR \-i " | " \-include
+output in C include file style. A complete static array definition is written
+(named after the input file), unless xxd reads from stdin.
+.TP
+.IR "\-l len " | " \-len len"
+stop after writing
+.RI  < len >
+octets.
+.TP
+.IR \-p " | " \-ps " | " \-postscript " | " \-plain
+output in postscript continuous hexdump style. Also known as plain hexdump
+style.
+.TP
+.IR \-r " | " \-revert
+reverse operation: convert (or patch) hexdump into binary.
+If not writing to stdout, xxd writes into its output file without truncating
+it. Use the combination
+.I \-r \-p
+to read plain hexadecimal dumps without line number information and without a
+particular column layout. Additional Whitespace and line-breaks are allowed
+anywhere.
+.TP
+.I \-seek offset
+When used after
+.IR \-r :
+revert with
+.RI < offset >
+added to file positions found in hexdump.
+.TP
+.I \-s [+][\-]seek
+start at
+.RI < seek >
+bytes abs. (or rel.) infile offset.
+\fI+ \fRindicates that the seek is relative to the current stdin file position
+(meaningless when not reading from stdin).  \fI\- \fRindicates that the seek
+should be that many characters from the end of the input (or if combined with
+\fI+\fR: before the current stdin file position).
+Without \-s option, xxd starts at the current file position.
+.TP
+.I \-u
+use upper case hex letters. Default is lower case.
+.TP
+.IR \-v " | " \-version
+show version string.
+.SH CAVEATS
+.PP
+.I xxd \-r
+has some builtin magic while evaluating line number information.
+If the output file is seekable, then the linenumbers at the start of each
+hexdump line may be out of order, lines may be missing, or overlapping. In
+these cases xxd will lseek(2) to the next position. If the output file is not
+seekable, only gaps are allowed, which will be filled by null-bytes.
+.PP
+.I xxd \-r
+never generates parse errors. Garbage is silently skipped.
+.PP
+When editing hexdumps, please note that
+.I xxd \-r
+skips everything on the input line after reading enough columns of hexadecimal
+data (see option \-c). This also means, that changes to the printable ascii (or
+ebcdic) columns are always ignored. Reverting a plain (or postscript) style
+hexdump with xxd \-r \-p does not depend on the correct number of columns. Here anything that looks like a pair of hex-digits is interpreted.
+.PP
+Note the difference between
+.br
+\fI% xxd \-i file\fR
+.br
+and
+.br
+\fI% xxd \-i < file\fR
+.PP
+.I xxd \-s +seek
+may be different from
+.IR "xxd \-s seek" ,
+as lseek(2) is used to "rewind" input.  A '+'
+makes a difference if the input source is stdin, and if stdin's file position
+is not at the start of the file by the time xxd is started and given its input.
+The following examples may help to clarify (or further confuse!)...
+.PP
+Rewind stdin before reading; needed because the `cat' has already read to the
+end of stdin.
+.br
+\fI% sh \-c "cat > plain_copy; xxd \-s 0 > hex_copy" < file\fR
+.PP
+Hexdump from file position 0x480 (=1024+128) onwards.
+The `+' sign means "relative to the current position", thus the `128' adds to
+the 1k where dd left off.
+.br
+\fI% sh \-c "dd of=plain_snippet bs=1k count=1; xxd \-s +128 > hex_snippet" < file\fR
+.PP
+Hexdump from file position 0x100 ( = 1024\-768) on.
+.br
+\fI% sh \-c "dd of=plain_snippet bs=1k count=1; xxd \-s +\-768 > hex_snippet" < file\fR
+.PP
+However, this is a rare situation and the use of `+' is rarely needed.
+The author prefers to monitor the effect of xxd with strace(1) or truss(1), whenever \-s is used.
+.SH EXAMPLES
+.PP
+.br
+Print everything but the first three lines (hex 0x30 bytes) of
+.BR file .
+.br
+\fI% xxd \-s 0x30 file\fR
+.PP
+.br
+Print 3 lines (hex 0x30 bytes) from the end of
+.BR file .
+.br
+\fI% xxd \-s \-0x30 file\fR
+.PP
+.br
+Print 120 bytes as continuous hexdump with 20 octets per line.
+.br
+\fI% xxd \-l 120 \-ps \-c 20 xxd.1\fR
+.br
+2e54482058584420312022417567757374203139
+.br
+39362220224d616e75616c207061676520666f72
+.br
+20787864220a2e5c220a2e5c222032317374204d
+.br
+617920313939360a2e5c22204d616e2070616765
+.br
+20617574686f723a0a2e5c2220202020546f6e79
+.br
+204e7567656e74203c746f6e79407363746e7567
+.br
+
+.br
+Hexdump the first 120 bytes of this man page with 12 octets per line.
+.br
+\fI% xxd \-l 120 \-c 12 xxd.1\fR
+.br
+0000000: 2e54 4820 5858 4420 3120 2241  .TH XXD 1 "A
+.br
+000000c: 7567 7573 7420 3139 3936 2220  ugust 1996" 
+.br
+0000018: 224d 616e 7561 6c20 7061 6765  "Manual page
+.br
+0000024: 2066 6f72 2078 7864 220a 2e5c   for xxd"..\\
+.br
+0000030: 220a 2e5c 2220 3231 7374 204d  "..\\" 21st M
+.br
+000003c: 6179 2031 3939 360a 2e5c 2220  ay 1996..\\" 
+.br
+0000048: 4d61 6e20 7061 6765 2061 7574  Man page aut
+.br
+0000054: 686f 723a 0a2e 5c22 2020 2020  hor:..\\"    
+.br
+0000060: 546f 6e79 204e 7567 656e 7420  Tony Nugent 
+.br
+000006c: 3c74 6f6e 7940 7363 746e 7567  <tony@sctnug
+.PP
+.br
+Display just the date from the file xxd.1
+.br
+\fI% xxd \-s 0x36 \-l 13 \-c 13 xxd.1\fR
+.br
+0000036: 3231 7374 204d 6179 2031 3939 36  21st May 1996
+.PP
+.br
+Copy
+.B input_file
+to
+.B output_file
+and prepend 100 bytes of value 0x00.
+.br
+\fI% xxd input_file | xxd \-r \-s 100 > output_file\fR
+.br
+
+.br
+Patch the date in the file xxd.1
+.br
+\fI% echo "0000037: 3574 68" | xxd \-r \- xxd.1\fR
+.br
+\fI% xxd \-s 0x36 \-l 13 \-c 13 xxd.1\fR
+.br
+0000036: 3235 7468 204d 6179 2031 3939 36  25th May 1996
+.PP
+.br
+Create a 65537 byte file with all bytes 0x00,
+except for the last one which is 'A' (hex 0x41).
+.br
+\fI% echo "010000: 41" | xxd \-r > file\fR
+.PP
+.br
+Hexdump this file with autoskip.
+.br
+\fI% xxd \-a \-c 12 file\fR
+.br
+0000000: 0000 0000 0000 0000 0000 0000  ............
+.br
+*
+.br
+000fffc: 0000 0000 40                   ....A
+.PP
+Create a 1 byte file containing a single 'A' character.
+The number after '\-r \-s' adds to the linenumbers found in the file;
+in effect, the leading bytes are suppressed.
+.br
+\fI% echo "010000: 41" | xxd \-r \-s \-0x10000 > file\fR
+.PP
+Use xxd as a filter within an editor such as
+.B vim(1)
+to hexdump a region marked between `a' and `z'.
+.br
+\fI:'a,'z!xxd\fR
+.PP
+Use xxd as a filter within an editor such as
+.B vim(1)
+to recover a binary hexdump marked between `a' and `z'.
+.br
+\fI:'a,'z!xxd \-r\fR
+.PP
+Use xxd as a filter within an editor such as
+.B vim(1)
+to recover one line of a hexdump.  Move the cursor over the line and type:
+.br
+\fI!!xxd \-r\fR
+.PP
+Read single characters from a serial line
+.br
+\fI% xxd \-c1 < /dev/term/b &\fR
+.br
+\fI% stty < /dev/term/b \-echo \-opost \-isig \-icanon min 1\fR
+.br
+\fI% echo \-n foo > /dev/term/b\fR
+.PP
+.SH "RETURN VALUES"
+The following error values are returned:
+.TP
+0
+no errors encountered.
+.TP
+\-1
+operation not supported (
+.I xxd \-r \-i
+still impossible).
+.TP
+1
+error while parsing options.
+.TP
+2
+problems with input file.
+.TP
+3
+problems with output file.
+.TP
+4,5
+desired seek position is unreachable.
+.SH "SEE ALSO"
+uuencode(1), uudecode(1), patch(1)
+.br
+.SH WARNINGS
+The tools weirdness matches its creators brain.
+Use entirely at your own risk. Copy files. Trace it. Become a wizard.
+.br
+.SH VERSION
+This manual page documents xxd version 1.7
+.SH AUTHOR
+.br
+(c) 1990-1997 by Juergen Weigert
+.br
+<jnweiger@informatik.uni\-erlangen.de>
+.LP
+Distribute freely and credit me,
+.br
+make money and share with me,
+.br
+lose money and don't ask me.
+.PP
+Manual page started by Tony Nugent
+.br
+<tony@sctnugen.ppp.gu.edu.au> <T.Nugent@sct.gu.edu.au>
+.br
+Small changes by Bram Moolenaar.
+Edited by Juergen Weigert.
+.PP
--- /dev/null
+++ b/lib/vimfiles/evim.vim
@@ -1,0 +1,66 @@
+" Vim script for Evim key bindings
+" Maintainer:	Bram Moolenaar <Bram@vim.org>
+" Last Change:	2006 Mar 29
+
+" Don't use Vi-compatible mode.
+set nocompatible
+
+" Use the mswin.vim script for most mappings
+source <sfile>:p:h/mswin.vim
+
+" Vim is in Insert mode by default
+set insertmode
+
+" Make a buffer hidden when editing another one
+set hidden
+
+" Make cursor keys ignore wrapping
+inoremap <Down> <C-R>=pumvisible() ? "\<lt>Down>" : "\<lt>C-O>gj"<CR>
+inoremap <Up> <C-R>=pumvisible() ? "\<lt>Up>" : "\<lt>C-O>gk"<CR>
+
+" CTRL-F does Find dialog instead of page forward
+noremap <C-F> :promptfind<CR>
+vnoremap <C-F> y:promptfind <C-R>"<CR>
+onoremap <C-F> <C-C>:promptfind<CR>
+inoremap <C-F> <C-O>:promptfind<CR>
+cnoremap <C-F> <C-C>:promptfind<CR>
+
+
+set backspace=2		" allow backspacing over everything in insert mode
+set autoindent		" always set autoindenting on
+if has("vms")
+  set nobackup		" do not keep a backup file, use versions instead
+else
+  set backup		" keep a backup file
+endif
+set history=50		" keep 50 lines of command line history
+set ruler		" show the cursor position all the time
+set incsearch		" do incremental searching
+set mouse=a		" always use the mouse
+
+" Don't use Ex mode, use Q for formatting
+map Q gq
+
+" Switch syntax highlighting on, when the terminal has colors
+" Highlight the last used search pattern on the next search command.
+if &t_Co > 2 || has("gui_running")
+  syntax on
+  set hlsearch
+  nohlsearch
+endif
+
+" Only do this part when compiled with support for autocommands.
+if has("autocmd")
+
+  " Enable file type detection.
+  " Use the default filetype settings, so that mail gets 'tw' set to 72,
+  " 'cindent' is on in C files, etc.
+  " Also load indent files, to automatically do language-dependent indenting.
+  filetype plugin indent on
+
+  " For all text files set 'textwidth' to 78 characters.
+  au FileType text setlocal tw=78
+
+endif " has("autocmd")
+
+" vim: set sw=2 :
--- /dev/null
+++ b/lib/vimfiles/filetype.vim
@@ -1,0 +1,2293 @@
+" Vim support file to detect file types
+"
+" Maintainer:	Bram Moolenaar <Bram@vim.org>
+" Last Change:	2007 May 10
+
+" Listen very carefully, I will say this only once
+if exists("did_load_filetypes")
+  finish
+endif
+let did_load_filetypes = 1
+
+" Line continuation is used here, remove 'C' from 'cpoptions'
+let s:cpo_save = &cpo
+set cpo&vim
+
+augroup filetypedetect
+
+" Ignored extensions
+au BufNewFile,BufRead ?\+.orig,?\+.bak,?\+.old,?\+.new,?\+.rpmsave,?\+.rpmnew
+	\ exe "doau filetypedetect BufRead " . expand("<afile>:r")
+au BufNewFile,BufRead *~
+	\ let s:name = expand("<afile>") |
+	\ let s:short = substitute(s:name, '\~$', '', '') |
+	\ if s:name != s:short && s:short != "" |
+	\   exe "doau filetypedetect BufRead " . s:short |
+	\ endif |
+	\ unlet s:name |
+	\ unlet s:short
+au BufNewFile,BufRead ?\+.in
+	\ if expand("<afile>:t") != "configure.in" |
+	\   exe "doau filetypedetect BufRead " . expand("<afile>:r") |
+	\ endif
+
+" Pattern used to match file names which should not be inspected.
+" Currently finds compressed files.
+if !exists("g:ft_ignore_pat")
+  let g:ft_ignore_pat = '\.\(Z\|gz\|bz2\|zip\|tgz\)$'
+endif
+
+" Function used for patterns that end in a star: don't set the filetype if the
+" file name matches ft_ignore_pat.
+func! s:StarSetf(ft)
+  if expand("<amatch>") !~ g:ft_ignore_pat
+    exe 'setf ' . a:ft
+  endif
+endfunc
+
+" Abaqus or Trasys
+au BufNewFile,BufRead *.inp			call s:Check_inp()
+
+func! s:Check_inp()
+  if getline(1) =~ '^\*'
+    setf abaqus
+  else
+    let n = 1
+    if line("$") > 500
+      let nmax = 500
+    else
+      let nmax = line("$")
+    endif
+    while n <= nmax
+      if getline(n) =~? "^header surface data"
+	setf trasys
+	break
+      endif
+      let n = n + 1
+    endwhile
+  endif
+endfunc
+
+" A-A-P recipe
+au BufNewFile,BufRead *.aap			setf aap
+
+" A2ps printing utility
+au BufNewFile,BufRead etc/a2ps.cfg,etc/a2ps/*.cfg,a2psrc,.a2psrc setf a2ps
+
+" ABAB/4
+au BufNewFile,BufRead *.abap			setf abap
+
+" ABC music notation
+au BufNewFile,BufRead *.abc			setf abc
+
+" ABEL
+au BufNewFile,BufRead *.abl			setf abel
+
+" AceDB
+au BufNewFile,BufRead *.wrm			setf acedb
+
+" Ada (83, 9X, 95)
+au BufNewFile,BufRead *.adb,*.ads,*.ada		setf ada
+if has("vms")
+  au BufNewFile,BufRead *.gpr,*.ada_m,*.adc 	setf ada
+else
+  au BufNewFile,BufRead *.gpr 			setf ada
+endif
+
+" AHDL
+au BufNewFile,BufRead *.tdf			setf ahdl
+
+" AMPL
+au BufNewFile,BufRead *.run			setf ampl
+
+" Ant
+au BufNewFile,BufRead build.xml			setf ant
+
+" Apache style config file
+au BufNewFile,BufRead proftpd.conf*		call s:StarSetf('apachestyle')
+
+" Apache config file
+au BufNewFile,BufRead .htaccess			 setf apache
+au BufNewFile,BufRead httpd.conf*,srm.conf*,access.conf*,apache.conf*,apache2.conf*,/etc/apache2/*.conf* call s:StarSetf('apache')
+
+" XA65 MOS6510 cross assembler
+au BufNewFile,BufRead *.a65			setf a65
+
+" Applix ELF
+au BufNewFile,BufRead *.am
+	\ if expand("<afile>") !~? 'Makefile.am\>' | setf elf | endif
+
+" ALSA configuration
+au BufNewFile,BufRead ~/.asoundrc,/usr/share/alsa/alsa.conf,/etc/asound.conf	setf alsaconf
+
+" Arc Macro Language
+au BufNewFile,BufRead *.aml			setf aml
+
+" Arch Inventory file
+au BufNewFile,BufRead .arch-inventory,=tagging-method	setf arch
+
+" ART*Enterprise (formerly ART-IM)
+au BufNewFile,BufRead *.art			setf art
+
+" ASN.1
+au BufNewFile,BufRead *.asn,*.asn1		setf asn
+
+" Active Server Pages (with Visual Basic Script)
+au BufNewFile,BufRead *.asa
+	\ if exists("g:filetype_asa") |
+	\   exe "setf " . g:filetype_asa |
+	\ else |
+	\   setf aspvbs |
+	\ endif
+
+" Active Server Pages (with Perl or Visual Basic Script)
+au BufNewFile,BufRead *.asp
+	\ if exists("g:filetype_asp") |
+	\   exe "setf " . g:filetype_asp |
+	\ elseif getline(1) . getline(2) . getline(3) =~? "perlscript" |
+	\   setf aspperl |
+	\ else |
+	\   setf aspvbs |
+	\ endif
+
+" Grub (must be before catch *.lst)
+au BufNewFile,BufRead /boot/grub/menu.lst,/boot/grub/grub.conf,/etc/grub.conf	setf grub
+
+" Assembly (all kinds)
+" *.lst is not pure assembly, it has two extra columns (address, byte codes)
+au BufNewFile,BufRead *.asm,*.[sS],*.[aA],*.mac,*.lst	call s:FTasm()
+
+" This function checks for the kind of assembly that is wanted by the user, or
+" can be detected from the first five lines of the file.
+func! s:FTasm()
+  " make sure b:asmsyntax exists
+  if !exists("b:asmsyntax")
+    let b:asmsyntax = ""
+  endif
+
+  if b:asmsyntax == ""
+    call s:FTasmsyntax()
+  endif
+
+  " if b:asmsyntax still isn't set, default to asmsyntax or GNU
+  if b:asmsyntax == ""
+    if exists("g:asmsyntax")
+      let b:asmsyntax = g:asmsyntax
+    else
+      let b:asmsyntax = "asm"
+    endif
+  endif
+
+  exe "setf " . b:asmsyntax
+endfunc
+
+func! s:FTasmsyntax()
+  " see if file contains any asmsyntax=foo overrides. If so, change
+  " b:asmsyntax appropriately
+  let head = " ".getline(1)." ".getline(2)." ".getline(3)." ".getline(4).
+	\" ".getline(5)." "
+  if head =~ '\sasmsyntax=\S\+\s'
+    let b:asmsyntax = substitute(head, '.*\sasmsyntax=\(\S\+\)\s.*','\1', "")
+  elseif ((head =~? '\.title') || (head =~? '\.ident') || (head =~? '\.macro') || (head =~? '\.subtitle') || (head =~? '\.library'))
+    let b:asmsyntax = "vmasm"
+  endif
+endfunc
+
+" Macro (VAX)
+au BufNewFile,BufRead *.mar			setf vmasm
+
+" Atlas
+au BufNewFile,BufRead *.atl,*.as		setf atlas
+
+" Autoit v3
+au BufNewFile,BufRead *.au3			setf autoit
+
+" Autohotkey
+au BufNewFile,BufRead *.ahk			setf autohotkey
+
+" Automake
+au BufNewFile,BufRead [mM]akefile.am,GNUmakefile.am	setf automake
+
+" Autotest .at files are actually m4
+au BufNewFile,BufRead *.at			setf m4
+
+" Avenue
+au BufNewFile,BufRead *.ave			setf ave
+
+" Awk
+au BufNewFile,BufRead *.awk			setf awk
+
+" B
+au BufNewFile,BufRead *.mch,*.ref,*.imp		setf b
+
+" BASIC or Visual Basic
+au BufNewFile,BufRead *.bas			call s:FTVB("basic")
+
+" Check if one of the first five lines contains "VB_Name".  In that case it is
+" probably a Visual Basic file.  Otherwise it's assumed to be "alt" filetype.
+func! s:FTVB(alt)
+  if getline(1).getline(2).getline(3).getline(4).getline(5) =~? 'VB_Name\|Begin VB\.\(Form\|MDIForm\|UserControl\)'
+    setf vb
+  else
+    exe "setf " . a:alt
+  endif
+endfunc
+
+" Visual Basic Script (close to Visual Basic)
+au BufNewFile,BufRead *.vbs,*.dsm,*.ctl		setf vb
+
+" IBasic file (similar to QBasic)
+au BufNewFile,BufRead *.iba,*.ibi		setf ibasic
+
+" FreeBasic file (similar to QBasic)
+au BufNewFile,BufRead *.fb,*.bi			setf freebasic
+
+" Batch file for MSDOS.
+au BufNewFile,BufRead *.bat,*.sys		setf dosbatch
+" *.cmd is close to a Batch file, but on OS/2 Rexx files also use *.cmd.
+au BufNewFile,BufRead *.cmd
+	\ if getline(1) =~ '^/\*' | setf rexx | else | setf dosbatch | endif
+
+" Batch file for 4DOS
+au BufNewFile,BufRead *.btm			call s:FTbtm()
+func! s:FTbtm()
+  if exists("g:dosbatch_syntax_for_btm") && g:dosbatch_syntax_for_btm
+    setf dosbatch
+  else
+    setf btm
+  endif
+endfunc
+
+" BC calculator
+au BufNewFile,BufRead *.bc			setf bc
+
+" BDF font
+au BufNewFile,BufRead *.bdf			setf bdf
+
+" BibTeX bibliography database file
+au BufNewFile,BufRead *.bib			setf bib
+
+" BibTeX Bibliography Style
+au BufNewFile,BufRead *.bst			setf bst
+
+" BIND configuration
+au BufNewFile,BufRead named.conf,rndc.conf	setf named
+
+" BIND zone
+au BufNewFile,BufRead named.root		setf bindzone
+au BufNewFile,BufRead *.db			call s:BindzoneCheck('')
+
+func! s:BindzoneCheck(default)
+  if getline(1).getline(2).getline(3).getline(4) =~ '^; <<>> DiG [0-9.]\+ <<>>\|BIND.*named\|$ORIGIN\|$TTL\|IN\s\+SOA'
+    setf bindzone
+  elseif a:default != ''
+    exe 'setf ' . a:default
+  endif
+endfunc
+
+" Blank
+au BufNewFile,BufRead *.bl			setf blank
+
+" C or lpc
+au BufNewFile,BufRead *.c			call s:FTlpc()
+
+func! s:FTlpc()
+  if exists("g:lpc_syntax_for_c")
+    let lnum = 1
+    while lnum <= 12
+      if getline(lnum) =~# '^\(//\|inherit\|private\|protected\|nosave\|string\|object\|mapping\|mixed\)'
+	setf lpc
+	return
+      endif
+      let lnum = lnum + 1
+    endwhile
+  endif
+  setf c
+endfunc
+
+" Calendar
+au BufNewFile,BufRead calendar			setf calendar
+au BufNewFile,BufRead */.calendar/*,
+	\*/share/calendar/*/calendar.*,*/share/calendar/calendar.*
+	\					call s:StarSetf('calendar')
+
+" C#
+au BufNewFile,BufRead *.cs			setf cs
+
+" Cdrdao TOC
+au BufNewFile,BufRead *.toc			setf cdrtoc
+
+" Cfengine
+au BufNewFile,BufRead cfengine.conf		setf cfengine
+
+" Comshare Dimension Definition Language
+au BufNewFile,BufRead *.cdl			setf cdl
+
+" Conary Recipe
+au BufNewFile,BufRead *.recipe			setf conaryrecipe
+
+" Controllable Regex Mutilator
+au BufNewFile,BufRead *.crm			setf crm
+
+" Cyn++
+au BufNewFile,BufRead *.cyn			setf cynpp
+
+" Cynlib
+" .cc and .cpp files can be C++ or Cynlib.
+au BufNewFile,BufRead *.cc
+	\ if exists("cynlib_syntax_for_cc")|setf cynlib|else|setf cpp|endif
+au BufNewFile,BufRead *.cpp
+	\ if exists("cynlib_syntax_for_cpp")|setf cynlib|else|setf cpp|endif
+
+" C++
+if has("fname_case")
+  au BufNewFile,BufRead *.cxx,*.c++,*.C,*.H,*.hh,*.hxx,*.hpp,*.moc,*.tcc,*.inl setf cpp
+else
+  au BufNewFile,BufRead *.cxx,*.c++,*.hh,*.hxx,*.hpp,*.moc,*.tcc,*.inl setf cpp
+endif
+
+" .h files can be C, Ch or C++, set c_syntax_for_h if you want C,
+" ch_syntax_for_h if you want Ch.
+au BufNewFile,BufRead *.h
+	\ if exists("c_syntax_for_h") | setf c |
+	\ elseif exists("ch_syntax_for_h") | setf ch |
+	\ else | setf cpp | endif
+
+" Ch (CHscript)
+au BufNewFile,BufRead *.chf			setf ch
+
+" TLH files are C++ headers generated by Visual C++'s #import from typelibs
+au BufNewFile,BufRead *.tlh			setf cpp
+
+" Cascading Style Sheets
+au BufNewFile,BufRead *.css			setf css
+
+" Century Term Command Scripts (*.cmd too)
+au BufNewFile,BufRead *.con			setf cterm
+
+" Changelog
+au BufNewFile,BufRead changelog.Debian,changelog.dch,NEWS.Debian,NEWS.dch
+					\	setf debchangelog
+
+au BufNewFile,BufRead [cC]hange[lL]og
+	\  if getline(1) =~ '; urgency='
+	\|   setf debchangelog
+	\| else
+	\|   setf changelog
+	\| endif
+
+au BufNewFile,BufRead NEWS
+	\  if getline(1) =~ '; urgency='
+	\|   setf debchangelog
+	\| endif
+
+" CHILL
+au BufNewFile,BufRead *..ch			setf chill
+
+" Changes for WEB and CWEB or CHILL
+au BufNewFile,BufRead *.ch			call s:FTchange()
+
+" This function checks if one of the first ten lines start with a '@'.  In
+" that case it is probably a change file.
+" If the first line starts with # or ! it's probably a ch file.
+" If a line has "main", "include", "//" ir "/*" it's probably ch.
+" Otherwise CHILL is assumed.
+func! s:FTchange()
+  let lnum = 1
+  while lnum <= 10
+    if getline(lnum)[0] == '@'
+      setf change
+      return
+    endif
+    if lnum == 1 && (getline(1)[0] == '#' || getline(1)[0] == '!')
+      setf ch
+      return
+    endif
+    if getline(lnum) =~ "MODULE"
+      setf chill
+      return
+    endif
+    if getline(lnum) =~ 'main\s*(\|#\s*include\|//'
+      setf ch
+      return
+    endif
+    let lnum = lnum + 1
+  endwhile
+  setf chill
+endfunc
+
+" ChordPro
+au BufNewFile,BufRead *.chopro,*.crd,*.cho,*.crdpro,*.chordpro	setf chordpro
+
+" Clean
+au BufNewFile,BufRead *.dcl,*.icl		setf clean
+
+" Clever
+au BufNewFile,BufRead *.eni			setf cl
+
+" Clever or dtd
+au BufNewFile,BufRead *.ent			call s:FTent()
+
+func! s:FTent()
+  " This function checks for valid cl syntax in the first five lines.
+  " Look for either an opening comment, '#', or a block start, '{".
+  " If not found, assume SGML.
+  let lnum = 1
+  while lnum < 6
+    let line = getline(lnum)
+    if line =~ '^\s*[#{]'
+      setf cl
+      return
+    elseif line !~ '^\s*$'
+      " Not a blank line, not a comment, and not a block start,
+      " so doesn't look like valid cl code.
+      break
+    endif
+    let lnum = lnum + 1
+  endw
+  setf dtd
+endfunc
+
+" Clipper (or FoxPro; could also be eviews)
+au BufNewFile,BufRead *.prg
+	\ if exists("g:filetype_prg") |
+	\   exe "setf " . g:filetype_prg |
+	\ else |
+	\   setf clipper |
+	\ endif
+
+" Cmake
+au BufNewFile,BufRead CMakeLists.txt,*.cmake,*.cmake.in		setf cmake
+
+" Cmusrc
+au BufNewFile,BufRead ~/.cmus/{autosave,rc,command-history,*.theme} setf cmusrc
+au BufNewFile,BufRead */cmus/{rc,*.theme}			setf cmusrc
+
+" Cobol
+au BufNewFile,BufRead *.cbl,*.cob,*.lib	setf cobol
+"   cobol or zope form controller python script? (heuristic)
+au BufNewFile,BufRead *.cpy
+	\ if getline(1) =~ '^##' |
+	\   setf python |
+	\ else |
+	\   setf cobol |
+	\ endif
+
+" Cold Fusion
+au BufNewFile,BufRead *.cfm,*.cfi,*.cfc		setf cf
+
+" Configure scripts
+au BufNewFile,BufRead configure.in,configure.ac setf config
+
+" WildPackets EtherPeek Decoder
+au BufNewFile,BufRead *.dcd			setf dcd
+
+" Enlightenment configuration files
+au BufNewFile,BufRead *enlightenment/*.cfg	setf c
+
+" Eterm
+au BufNewFile,BufRead *Eterm/*.cfg		setf eterm
+
+" Lynx config files
+au BufNewFile,BufRead lynx.cfg			setf lynx
+
+" Quake
+au BufNewFile,BufRead *baseq[2-3]/*.cfg,*id1/*.cfg	setf quake
+au BufNewFile,BufRead *quake[1-3]/*.cfg			setf quake
+
+" Quake C
+au BufNewFile,BufRead *.qc			setf c
+
+" Configure files
+au BufNewFile,BufRead *.cfg			setf cfg
+
+" Communicating Sequential Processes
+au BufNewFile,BufRead *.csp,*.fdr		setf csp
+
+" CUPL logic description and simulation
+au BufNewFile,BufRead *.pld			setf cupl
+au BufNewFile,BufRead *.si			setf cuplsim
+
+" Debian Control
+au BufNewFile,BufRead */debian/control		setf debcontrol
+
+" Debian Sources.list
+au BufNewFile,BufRead /etc/apt/sources.list	setf debsources
+
+" ROCKLinux package description
+au BufNewFile,BufRead *.desc			setf desc
+
+" the D language
+au BufNewFile,BufRead *.d			setf d
+
+" Desktop files
+au BufNewFile,BufRead *.desktop,.directory	setf desktop
+
+" Dict config
+au BufNewFile,BufRead dict.conf,.dictrc		setf dictconf
+
+" Dictd config
+au BufNewFile,BufRead dictd.conf		setf dictdconf
+
+" Diff files
+au BufNewFile,BufRead *.diff,*.rej,*.patch	setf diff
+
+" Dircolors
+au BufNewFile,BufRead .dir_colors,/etc/DIR_COLORS	setf dircolors
+
+" Diva (with Skill) or InstallShield
+au BufNewFile,BufRead *.rul
+	\ if getline(1).getline(2).getline(3).getline(4).getline(5).getline(6) =~? 'InstallShield' |
+	\   setf ishd |
+	\ else |
+	\   setf diva |
+	\ endif
+
+" DCL (Digital Command Language - vms) or DNS zone file
+au BufNewFile,BufRead *.com			call s:BindzoneCheck('dcl')
+
+" DOT
+au BufNewFile,BufRead *.dot			setf dot
+
+" Dylan - lid files
+au BufNewFile,BufRead *.lid			setf dylanlid
+
+" Dylan - intr files (melange)
+au BufNewFile,BufRead *.intr			setf dylanintr
+
+" Dylan
+au BufNewFile,BufRead *.dylan			setf dylan
+
+" Microsoft Module Definition
+au BufNewFile,BufRead *.def			setf def
+
+" Dracula
+au BufNewFile,BufRead *.drac,*.drc,*lvs,*lpe	setf dracula
+
+" dsl
+au BufNewFile,BufRead *.dsl			setf dsl
+
+" DTD (Document Type Definition for XML)
+au BufNewFile,BufRead *.dtd			setf dtd
+
+" EDIF (*.edf,*.edif,*.edn,*.edo)
+au BufNewFile,BufRead *.ed\(f\|if\|n\|o\)	setf edif
+
+" Embedix Component Description
+au BufNewFile,BufRead *.ecd			setf ecd
+
+" Eiffel or Specman
+au BufNewFile,BufRead *.e,*.E			call s:FTe()
+
+" Elinks configuration
+au BufNewFile,BufRead */etc/elinks.conf,*/.elinks/elinks.conf	setf elinks
+
+func! s:FTe()
+  let n = 1
+  while n < 100 && n < line("$")
+    if getline(n) =~ "^\\s*\\(<'\\|'>\\)\\s*$"
+      setf specman
+      return
+    endif
+    let n = n + 1
+  endwhile
+  setf eiffel
+endfunc
+
+" ERicsson LANGuage
+au BufNewFile,BufRead *.erl			setf erlang
+
+" Elm Filter Rules file
+au BufNewFile,BufRead filter-rules		setf elmfilt
+
+" ESMTP rc file
+au BufNewFile,BufRead *esmtprc			setf esmtprc
+
+" ESQL-C
+au BufNewFile,BufRead *.ec,*.EC			setf esqlc
+
+" Esterel
+au BufNewFile,BufRead *.strl			setf esterel
+
+" Essbase script
+au BufNewFile,BufRead *.csc			setf csc
+
+" Exim
+au BufNewFile,BufRead exim.conf			setf exim
+
+" Expect
+au BufNewFile,BufRead *.exp			setf expect
+
+" Exports
+au BufNewFile,BufRead exports			setf exports
+
+" Factor
+au BufNewFile,BufRead *.factor			setf factor
+
+" Fetchmail RC file
+au BufNewFile,BufRead .fetchmailrc		setf fetchmail
+
+" FlexWiki
+au BufNewFile,BufRead *.wiki			setf flexwiki
+
+" Focus Executable
+au BufNewFile,BufRead *.fex,*.focexec		setf focexec
+
+" Focus Master file (but not for auto.master)
+au BufNewFile,BufRead auto.master		setf conf
+au BufNewFile,BufRead *.mas,*.master		setf master
+
+" Forth
+au BufNewFile,BufRead *.fs,*.ft			setf forth
+
+" Fortran
+if has("fname_case")
+  au BufNewFile,BufRead *.F,*.FOR,*.FPP,*.FTN,*.F77,*.F90,*.F95	 setf fortran
+endif
+au BufNewFile,BufRead   *.f,*.for,*.fpp,*.ftn,*.f77,*.f90,*.f95  setf fortran
+
+" FStab
+au BufNewFile,BufRead fstab,mtab		setf fstab
+
+" GDB command files
+au BufNewFile,BufRead .gdbinit			setf gdb
+
+" GDMO
+au BufNewFile,BufRead *.mo,*.gdmo		setf gdmo
+
+" Gedcom
+au BufNewFile,BufRead *.ged			setf gedcom
+
+" Gkrellmrc
+au BufNewFile,BufRead gkrellmrc,gkrellmrc_?	setf gkrellmrc
+
+" GP scripts (2.0 and onward)
+au BufNewFile,BufRead *.gp,.gprc		setf gp
+
+" GPG
+au BufNewFile,BufRead */.gnupg/options		setf gpg
+au BufNewFile,BufRead */.gnupg/gpg.conf		setf gpg
+au BufNewFile,BufRead /usr/**/gnupg/options.skel setf gpg
+
+" Gnuplot scripts
+au BufNewFile,BufRead *.gpi			setf gnuplot
+
+" GrADS scripts
+au BufNewFile,BufRead *.gs			setf grads
+
+" Gretl
+au BufNewFile,BufRead *.gretl			setf gretl
+
+" Groovy
+au BufNewFile,BufRead *.groovy			setf groovy
+
+" GNU Server Pages
+au BufNewFile,BufRead *.gsp			setf gsp
+
+" Group file
+au BufNewFile,BufRead /etc/group		setf group
+
+" GTK RC
+au BufNewFile,BufRead .gtkrc,gtkrc		setf gtkrc
+
+" Hamster Classic | Playground files
+au BufNewFile,BufRead *.hsc,*.hsm		setf hamster
+
+" Haskell
+au BufNewFile,BufRead *.hs			setf haskell
+au BufNewFile,BufRead *.lhs			setf lhaskell
+au BufNewFile,BufRead *.chs			setf chaskell
+
+" Hercules
+au BufNewFile,BufRead *.vc,*.ev,*.rs,*.sum,*.errsum	setf hercules
+
+" HEX (Intel)
+au BufNewFile,BufRead *.hex,*.h32		setf hex
+
+" Tilde (must be before HTML)
+au BufNewFile,BufRead *.t.html			setf tilde
+
+" HTML (.shtml and .stm for server side)
+au BufNewFile,BufRead *.html,*.htm,*.shtml,*.stm  call s:FThtml()
+
+" Distinguish between HTML, XHTML and Django
+func! s:FThtml()
+  let n = 1
+  while n < 10 && n < line("$")
+    if getline(n) =~ '\<DTD\s\+XHTML\s'
+      setf xhtml
+      return
+    endif
+    if getline(n) =~ '{%\s*\(extends\|block\)\>'
+      setf htmldjango
+      return
+    endif
+    let n = n + 1
+  endwhile
+  setf html
+endfunc
+
+" HTML with Ruby - eRuby
+au BufNewFile,BufRead *.erb,*.rhtml		setf eruby
+
+" HTML with M4
+au BufNewFile,BufRead *.html.m4			setf htmlm4
+
+" HTML Cheetah template
+au BufNewFile,BufRead *.tmpl			setf htmlcheetah
+
+" Hyper Builder
+au BufNewFile,BufRead *.hb			setf hb
+
+" Icon
+au BufNewFile,BufRead *.icn			setf icon
+
+" IDL (Interface Description Language)
+au BufNewFile,BufRead *.idl			call s:FTidl()
+
+" Distinguish between standard IDL and MS-IDL
+func! s:FTidl()
+  let n = 1
+  while n < 50 && n < line("$")
+    if getline(n) =~ '^\s*import\s\+"\(unknwn\|objidl\)\.idl"'
+      setf msidl
+      return
+    endif
+    let n = n + 1
+  endwhile
+  setf idl
+endfunc
+
+" Microsoft IDL (Interface Description Language)  Also *.idl
+" MOF = WMI (Windows Management Instrumentation) Managed Object Format
+au BufNewFile,BufRead *.odl,*.mof		setf msidl
+
+" Icewm menu
+au BufNewFile,BufRead */.icewm/menu		setf icemenu
+
+" Indent profile (must come before IDL *.pro!)
+au BufNewFile,BufRead .indent.pro		setf indent
+au BufNewFile,BufRead indent.pro		call s:ProtoCheck('indent')
+
+" IDL (Interactive Data Language)
+au BufNewFile,BufRead *.pro			call s:ProtoCheck('idlang')
+
+" Distinguish between "default" and Cproto prototype file. */
+func! s:ProtoCheck(default)
+  " Cproto files have a comment in the first line and a function prototype in
+  " the second line, it always ends in ";".  Indent files may also have
+  " comments, thus we can't match comments to see the difference.
+  if getline(2) =~ ';$'
+    setf cpp
+  else
+    exe 'setf ' . a:default
+  endif
+endfunc
+
+
+" Indent RC
+au BufNewFile,BufRead indentrc			setf indentrc
+
+" Inform
+au BufNewFile,BufRead *.inf,*.INF		setf inform
+
+" Initng
+au BufNewFile,BufRead /etc/initng/**/*.i,*.ii	setf initng
+
+" Ipfilter
+au BufNewFile,BufRead ipf.conf,ipf6.conf,ipf.rules	setf ipfilter
+
+" Informix 4GL (source - canonical, include file, I4GL+M4 preproc.)
+au BufNewFile,BufRead *.4gl,*.4gh,*.m4gl	setf fgl
+
+" .INI file for MSDOS
+au BufNewFile,BufRead *.ini			setf dosini
+
+" SysV Inittab
+au BufNewFile,BufRead inittab			setf inittab
+
+" Inno Setup
+au BufNewFile,BufRead *.iss			setf iss
+
+" JAL
+au BufNewFile,BufRead *.jal,*.JAL		setf jal
+
+" Jam
+au BufNewFile,BufRead *.jpl,*.jpr		setf jam
+
+" Java
+au BufNewFile,BufRead *.java,*.jav		setf java
+
+" JavaCC
+au BufNewFile,BufRead *.jj,*.jjt		setf javacc
+
+" JavaScript, ECMAScript
+au BufNewFile,BufRead *.js,*.javascript,*.es	setf javascript
+
+" Java Server Pages
+au BufNewFile,BufRead *.jsp			setf jsp
+
+" Java Properties resource file (note: doesn't catch font.properties.pl)
+au BufNewFile,BufRead *.properties,*.properties_??,*.properties_??_??	setf jproperties
+au BufNewFile,BufRead *.properties_??_??_*	call s:StarSetf('jproperties')
+
+" Jess
+au BufNewFile,BufRead *.clp			setf jess
+
+" Jgraph
+au BufNewFile,BufRead *.jgr			setf jgraph
+
+" Kixtart
+au BufNewFile,BufRead *.kix			setf kix
+
+" Kimwitu[++]
+au BufNewFile,BufRead *.k			setf kwt
+
+" KDE script
+au BufNewFile,BufRead *.ks			setf kscript
+
+" Kconfig
+au BufNewFile,BufRead Kconfig,Kconfig.debug	setf kconfig
+
+" Lace (ISE)
+au BufNewFile,BufRead *.ace,*.ACE		setf lace
+
+" Latte
+au BufNewFile,BufRead *.latte,*.lte		setf latte
+
+" Limits
+au BufNewFile,BufRead /etc/limits		setf limits
+
+" LambdaProlog (*.mod too, see Modsim)
+au BufNewFile,BufRead *.sig			setf lprolog
+
+" LDAP LDIF
+au BufNewFile,BufRead *.ldif			setf ldif
+
+" Ld loader
+au BufNewFile,BufRead *.ld			setf ld
+
+" Lex
+au BufNewFile,BufRead *.lex,*.l			setf lex
+
+" Libao
+au BufNewFile,BufRead /etc/libao.conf,*/.libao	setf libao
+
+" Libsensors
+au BufNewFile,BufRead /etc/sensors.conf		setf sensors
+
+" LFTP
+au BufNewFile,BufRead lftp.conf,.lftprc,*lftp/rc	setf lftp
+
+" Lifelines (or Lex for C++!)
+au BufNewFile,BufRead *.ll			setf lifelines
+
+" Lilo: Linux loader
+au BufNewFile,BufRead lilo.conf*		call s:StarSetf('lilo')
+
+" Lisp (*.el = ELisp, *.cl = Common Lisp, *.jl = librep Lisp)
+if has("fname_case")
+  au BufNewFile,BufRead *.lsp,*.lisp,*.el,*.cl,*.jl,*.L,.emacs,.sawfishrc setf lisp
+else
+  au BufNewFile,BufRead *.lsp,*.lisp,*.el,*.cl,*.jl,.emacs,.sawfishrc setf lisp
+endif
+
+" SBCL implementation of Common Lisp
+au BufNewFile,BufRead sbclrc,.sbclrc		setf lisp
+
+" Lite
+au BufNewFile,BufRead *.lite,*.lt		setf lite
+
+" LiteStep RC files
+au BufNewFile,BufRead */LiteStep/*/*.rc		setf litestep
+
+" Login access
+au BufNewFile,BufRead /etc/login.access		setf loginaccess
+
+" Login defs
+au BufNewFile,BufRead /etc/login.defs		setf logindefs
+
+" Logtalk
+au BufNewFile,BufRead *.lgt			setf logtalk
+
+" LOTOS
+au BufNewFile,BufRead *.lot,*.lotos		setf lotos
+
+" Lout (also: *.lt)
+au BufNewFile,BufRead *.lou,*.lout		setf lout
+
+" Lua
+au BufNewFile,BufRead *.lua			setf lua
+
+" Lynx style file (or LotusScript!)
+au BufNewFile,BufRead *.lss			setf lss
+
+" M4
+au BufNewFile,BufRead *.m4
+	\ if expand("<afile>") !~? 'html.m4$\|fvwm2rc' | setf m4 | endif
+
+" MaGic Point
+au BufNewFile,BufRead *.mgp			setf mgp
+
+" Mail (for Elm, trn, mutt, muttng, rn, slrn)
+au BufNewFile,BufRead snd.\d\+,.letter,.letter.\d\+,.followup,.article,.article.\d\+,pico.\d\+,mutt{ng,}-*-\w\+,mutt[[:alnum:]._-]\{6\},ae\d\+.txt,/tmp/SLRN[0-9A-Z.]\+,*.eml setf mail
+
+" Mail aliases
+au BufNewFile,BufRead /etc/mail/aliases,/etc/aliases	setf mailaliases
+
+" Mailcap configuration file
+au BufNewFile,BufRead .mailcap,mailcap		setf mailcap
+
+" Makefile
+au BufNewFile,BufRead *[mM]akefile,*.mk,*.mak,*.dsp setf make
+
+" MakeIndex
+au BufNewFile,BufRead *.ist,*.mst		setf ist
+
+" Manpage
+au BufNewFile,BufRead *.man			setf man
+
+" Man config
+au BufNewFile,BufRead /etc/man.conf,man.config	setf manconf
+
+" Maple V
+au BufNewFile,BufRead *.mv,*.mpl,*.mws		setf maple
+
+" Mason
+au BufNewFile,BufRead *.mason,*.mhtml		setf mason
+
+" Matlab or Objective C
+au BufNewFile,BufRead *.m			call s:FTm()
+
+func! s:FTm()
+  let n = 1
+  while n < 10
+    let line = getline(n)
+    if line =~ '^\s*\(#\s*\(include\|import\)\>\|/\*\)'
+      setf objc
+      return
+    endif
+    if line =~ '^\s*%'
+      setf matlab
+      return
+    endif
+    if line =~ '^\s*(\*'
+      setf mma
+      return
+    endif
+    let n = n + 1
+  endwhile
+  if exists("g:filetype_m")
+    exe "setf " . g:filetype_m
+  else
+    setf matlab
+  endif
+endfunc
+
+" Maya Extension Language
+au BufNewFile,BufRead *.mel			setf mel
+
+" Messages
+au BufNewFile,BufRead /var/log/messages,/var/log/messages.*[0-9]  setf messages
+
+" Metafont
+au BufNewFile,BufRead *.mf			setf mf
+
+" MetaPost
+au BufNewFile,BufRead *.mp			setf mp
+
+" MGL
+au BufNewFile,BufRead *.mgl			setf mgl
+
+" MMIX or VMS makefile
+au BufNewFile,BufRead *.mms			call s:FTmms()
+
+func! s:FTmms()
+  let n = 1
+  while n < 10
+    let line = getline(n)
+    if line =~ '^\s*\(%\|//\)' || line =~ '^\*'
+      setf mmix
+      return
+    endif
+    if line =~ '^\s*#'
+      setf make
+      return
+    endif
+    let n = n + 1
+  endwhile
+  setf mmix
+endfunc
+
+
+" Modsim III (or LambdaProlog)
+au BufNewFile,BufRead *.mod
+	\ if getline(1) =~ '\<module\>' |
+	\   setf lprolog |
+	\ else |
+	\   setf modsim3 |
+	\ endif
+
+" Modula 2
+au BufNewFile,BufRead *.m2,*.DEF,*.MOD,*.md,*.mi setf modula2
+
+" Modula 3 (.m3, .i3, .mg, .ig)
+au BufNewFile,BufRead *.[mi][3g]		setf modula3
+
+" Monk
+au BufNewFile,BufRead *.isc,*.monk,*.ssc,*.tsc	setf monk
+
+" MOO
+au BufNewFile,BufRead *.moo			setf moo
+
+" Modconf
+au BufNewFile,BufRead /etc/modules.conf,/etc/conf.modules	setf modconf
+au BufNewFile,BufRead /etc/modutils/*
+	\ if executable(expand("<afile>")) != 1
+	\|  call s:StarSetf('modconf')
+	\|endif
+
+" Mplayer config
+au BufNewFile,BufRead mplayer.conf,*/.mplayer/config	setf mplayerconf
+
+" Moterola S record
+au BufNewFile,BufRead *.s19,*.s28,*.s37		setf srec
+
+" Mrxvtrc
+au BufNewFile,BufRead mrxvtrc,.mrxvtrc		setf mrxvtrc
+
+" Msql
+au BufNewFile,BufRead *.msql			setf msql
+
+" Mysql
+au BufNewFile,BufRead *.mysql			setf mysql
+
+" M$ Resource files
+au BufNewFile,BufRead *.rc			setf rc
+
+" MuPAD source
+au BufRead,BufNewFile *.mu			setf mupad
+
+" Mush
+au BufNewFile,BufRead *.mush			setf mush
+
+" Mutt setup file (also for Muttng)
+au BufNewFile,BufRead Mutt{ng,}rc			setf muttrc
+au BufNewFile,BufRead .mutt{ng,}rc*,*/.mutt{ng,}/mutt{ng,}rc*	call s:StarSetf('muttrc')
+
+" Nano
+au BufNewFile,BufRead /etc/nanorc,.nanorc	setf nanorc
+
+" Nastran input/DMAP
+"au BufNewFile,BufRead *.dat			setf nastran
+
+" Natural
+au BufNewFile,BufRead *.NS[ACGLMNPS]		setf natural
+
+" Netrc
+au BufNewFile,BufRead .netrc			setf netrc
+
+" Novell netware batch files
+au BufNewFile,BufRead *.ncf			setf ncf
+
+" Nroff/Troff (*.ms and *.t are checked below)
+au BufNewFile,BufRead *.me
+	\ if expand("<afile>") != "read.me" && expand("<afile>") != "click.me" |
+	\   setf nroff |
+	\ endif
+au BufNewFile,BufRead *.tr,*.nr,*.roff,*.tmac,*.mom	setf nroff
+au BufNewFile,BufRead *.[1-9]			call s:FTnroff()
+
+" This function checks if one of the first five lines start with a dot.  In
+" that case it is probably an nroff file: 'filetype' is set and 1 is returned.
+func! s:FTnroff()
+  if getline(1)[0] . getline(2)[0] . getline(3)[0] . getline(4)[0] . getline(5)[0] =~ '\.'
+    setf nroff
+    return 1
+  endif
+  return 0
+endfunc
+
+" Nroff or Objective C++
+au BufNewFile,BufRead *.mm			call s:FTmm()
+
+func! s:FTmm()
+  let n = 1
+  while n < 10
+    let line = getline(n)
+    if line =~ '^\s*\(#\s*\(include\|import\)\>\|/\*\)'
+      setf objcpp
+      return
+    endif
+    let n = n + 1
+  endwhile
+  setf nroff
+endfunc
+
+" Not Quite C
+au BufNewFile,BufRead *.nqc			setf nqc
+
+" NSIS
+au BufNewFile,BufRead *.nsi			setf nsis
+
+" OCAML
+au BufNewFile,BufRead *.ml,*.mli,*.mll,*.mly	setf ocaml
+
+" Occam
+au BufNewFile,BufRead *.occ			setf occam
+
+" Omnimark
+au BufNewFile,BufRead *.xom,*.xin		setf omnimark
+
+" OpenROAD
+au BufNewFile,BufRead *.or			setf openroad
+
+" OPL
+au BufNewFile,BufRead *.[Oo][Pp][Ll]		setf opl
+
+" Oracle config file
+au BufNewFile,BufRead *.ora			setf ora
+
+" Packet filter conf
+au BufNewFile,BufRead pf.conf			setf pf
+
+" Pam conf
+au BufNewFile,BufRead /etc/pam.conf		setf pamconf
+
+" PApp
+au BufNewFile,BufRead *.papp,*.pxml,*.pxsl	setf papp
+
+" Password file
+au BufNewFile,BufRead /etc/passwd,/etc/shadow,/etc/shadow- setf passwd
+
+" Pascal (also *.p)
+au BufNewFile,BufRead *.pas			setf pascal
+
+" Delphi project file
+au BufNewFile,BufRead *.dpr			setf pascal
+
+" Perl
+if has("fname_case")
+  au BufNewFile,BufRead *.pl,*.PL		call s:FTpl()
+else
+  au BufNewFile,BufRead *.pl			call s:FTpl()
+endif
+au BufNewFile,BufRead *.plx			setf perl
+
+func! s:FTpl()
+  if exists("g:filetype_pl")
+    exe "setf " . g:filetype_pl
+  else
+    " recognize Prolog by specific text in the first non-empty line
+    " require a blank after the '%' because Perl uses "%list" and "%translate"
+    let l = getline(nextnonblank(1))
+    if l =~ '\<prolog\>' || l =~ '^\s*\(%\+\(\s\|$\)\|/\*\)' || l =~ ':-'
+      setf prolog
+    else
+      setf perl
+    endif
+  endif
+endfunc
+
+" Perl, XPM or XPM2
+au BufNewFile,BufRead *.pm
+	\ if getline(1) =~ "XPM2" |
+	\   setf xpm2 |
+	\ elseif getline(1) =~ "XPM" |
+	\   setf xpm |
+	\ else |
+	\   setf perl |
+	\ endif
+
+" Perl POD
+au BufNewFile,BufRead *.pod			setf pod
+
+" Php, php3, php4, etc.
+au BufNewFile,BufRead *.php,*.php\d		setf php
+
+" Phtml
+au BufNewFile,BufRead *.phtml			setf phtml
+
+" Pike
+au BufNewFile,BufRead *.pike,*.lpc,*.ulpc,*.pmod setf pike
+
+" Pinfo config
+au BufNewFile,BufRead */etc/pinforc,*/.pinforc	setf pinfo
+
+" Palm Resource compiler
+au BufNewFile,BufRead *.rcp			setf pilrc
+
+" Pine config
+au BufNewFile,BufRead .pinerc,pinerc,.pinercex,pinercex		setf pine
+
+" PL/M (also: *.inp)
+au BufNewFile,BufRead *.plm,*.p36,*.pac		setf plm
+
+" PL/SQL
+au BufNewFile,BufRead *.pls,*.plsql		setf plsql
+
+" PLP
+au BufNewFile,BufRead *.plp			setf plp
+
+" PO and PO template (GNU gettext)
+au BufNewFile,BufRead *.po,*.pot		setf po
+
+" Postfix main config
+au BufNewFile,BufRead main.cf			setf pfmain
+
+" PostScript (+ font files, encapsulated PostScript, Adobe Illustrator)
+au BufNewFile,BufRead *.ps,*.pfa,*.afm,*.eps,*.epsf,*.epsi,*.ai	  setf postscr
+
+" PostScript Printer Description
+au BufNewFile,BufRead *.ppd			setf ppd
+
+" Povray
+au BufNewFile,BufRead *.pov			setf pov
+
+" Povray configuration
+au BufNewFile,BufRead .povrayrc			setf povini
+
+" Povray, PHP or assembly
+au BufNewFile,BufRead *.inc			call s:FTinc()
+
+func! s:FTinc()
+  if exists("g:filetype_inc")
+    exe "setf " . g:filetype_inc
+  else
+    let lines = getline(1).getline(2).getline(3)
+    if lines =~? "perlscript"
+      setf aspperl
+    elseif lines =~ "<%"
+      setf aspvbs
+    elseif lines =~ "<?"
+      setf php
+    else
+      call s:FTasmsyntax()
+      if exists("b:asmsyntax")
+	exe "setf " . b:asmsyntax
+      else
+	setf pov
+      endif
+    endif
+  endif
+endfunc
+
+" Printcap and Termcap
+au BufNewFile,BufRead *printcap
+	\ let b:ptcap_type = "print" | setf ptcap
+au BufNewFile,BufRead *termcap
+	\ let b:ptcap_type = "term" | setf ptcap
+
+" PCCTS / ANTRL
+"au BufNewFile,BufRead *.g			setf antrl
+au BufNewFile,BufRead *.g			setf pccts
+
+" PPWizard
+au BufNewFile,BufRead *.it,*.ih			setf ppwiz
+
+" Oracle Pro*C/C++
+au BufNewFile,BufRead .pc			setf proc
+
+" Privoxy actions file
+au BufNewFile,BufRead *.action			setf privoxy
+
+" Procmail
+au BufNewFile,BufRead .procmail,.procmailrc	setf procmail
+
+" Progress or CWEB
+au BufNewFile,BufRead *.w			call s:FTprogress_cweb()
+
+func! s:FTprogress_cweb()
+  if exists("g:filetype_w")
+    exe "setf " . g:filetype_w
+    return
+  endif
+  if getline(1) =~ '&ANALYZE' || getline(3) =~ '&GLOBAL-DEFINE'
+    setf progress
+  else
+    setf cweb
+  endif
+endfunc
+
+" Progress or assembly
+au BufNewFile,BufRead *.i			call s:FTprogress_asm()
+
+func! s:FTprogress_asm()
+  if exists("g:filetype_i")
+    exe "setf " . g:filetype_i
+    return
+  endif
+  " This function checks for an assembly comment the first ten lines.
+  " If not found, assume Progress.
+  let lnum = 1
+  while lnum <= 10 && lnum < line('$')
+    let line = getline(lnum)
+    if line =~ '^\s*;' || line =~ '^\*'
+      call s:FTasm()
+      return
+    elseif line !~ '^\s*$' || line =~ '^/\*'
+      " Not an empty line: Doesn't look like valid assembly code.
+      " Or it looks like a Progress /* comment
+      break
+    endif
+    let lnum = lnum + 1
+  endw
+  setf progress
+endfunc
+
+" Progress or Pascal
+au BufNewFile,BufRead *.p			call s:FTprogress_pascal()
+
+func! s:FTprogress_pascal()
+  if exists("g:filetype_p")
+    exe "setf " . g:filetype_p
+    return
+  endif
+  " This function checks for valid Pascal syntax in the first ten lines.
+  " Look for either an opening comment or a program start.
+  " If not found, assume Progress.
+  let lnum = 1
+  while lnum <= 10 && lnum < line('$')
+    let line = getline(lnum)
+    if line =~ '^\s*\(program\|unit\|procedure\|function\|const\|type\|var\)\>'
+	\ || line =~ '^\s*{' || line =~ '^\s*(\*'
+      setf pascal
+      return
+    elseif line !~ '^\s*$' || line =~ '^/\*'
+      " Not an empty line: Doesn't look like valid Pascal code.
+      " Or it looks like a Progress /* comment
+      break
+    endif
+    let lnum = lnum + 1
+  endw
+  setf progress
+endfunc
+
+
+" Software Distributor Product Specification File (POSIX 1387.2-1995)
+au BufNewFile,BufRead *.psf			setf psf
+au BufNewFile,BufRead INDEX,INFO
+	\ if getline(1) =~ '^\s*\(distribution\|installed_software\|root\|bundle\|product\)\s*$' |
+	\   setf psf |
+	\ endif
+
+" Prolog
+au BufNewFile,BufRead *.pdb			setf prolog
+
+" Protocols
+au BufNewFile,BufRead /etc/protocols		setf protocols
+
+" Pyrex
+au BufNewFile,BufRead *.pyx,*.pxd		setf pyrex
+
+" Python
+au BufNewFile,BufRead *.py,*.pyw		setf python
+
+" Radiance
+au BufNewFile,BufRead *.rad,*.mat		setf radiance
+
+" Ratpoison config/command files
+au BufNewFile,BufRead .ratpoisonrc,ratpoisonrc	setf ratpoison
+
+" RCS file
+au BufNewFile,BufRead *\,v			setf rcs
+
+" Readline
+au BufNewFile,BufRead .inputrc,inputrc		setf readline
+
+" Registry for MS-Windows
+au BufNewFile,BufRead *.reg
+	\ if getline(1) =~? '^REGEDIT[0-9]*\s*$\|^Windows Registry Editor Version \d*\.\d*\s*$' | setf registry | endif
+
+" Renderman Interface Bytestream
+au BufNewFile,BufRead *.rib			setf rib
+
+" Rexx
+au BufNewFile,BufRead *.rexx,*.rex		setf rexx
+
+" R (Splus)
+if has("fname_case")
+  au BufNewFile,BufRead *.s,*.S			setf r
+else
+  au BufNewFile,BufRead *.s			setf r
+endif
+
+" R Help file
+if has("fname_case")
+  au BufNewFile,BufRead *.rd,*.Rd		setf rhelp
+else
+  au BufNewFile,BufRead *.rd			setf rhelp
+endif
+
+" R noweb file
+if has("fname_case")
+  au BufNewFile,BufRead *.Rnw,*.rnw,*.Snw,*.snw		setf rnoweb
+else
+  au BufNewFile,BufRead *.rnw,*.snw			setf rnoweb
+endif
+
+" Rexx, Rebol or R
+au BufNewFile,BufRead *.r,*.R			call s:FTr()
+
+func! s:FTr()
+  let max = line("$") > 50 ? 50 : line("$")
+
+  for n in range(1, max)
+    " Rebol is easy to recognize, check for that first
+    if getline(n) =~ '\<REBOL\>'
+      setf rebol
+      return
+    endif
+  endfor
+
+  for n in range(1, max)
+    " R has # comments
+    if getline(n) =~ '^\s*#'
+      setf r
+      return
+    endif
+    " Rexx has /* comments */
+    if getline(n) =~ '^\s*/\*'
+      setf rexx
+      return
+    endif
+  endfor
+
+  " Nothing recognized, assume Rexx
+  setf rexx
+endfunc
+
+" Remind
+au BufNewFile,BufRead .reminders*		call s:StarSetf('remind')
+
+" Resolv.conf
+au BufNewFile,BufRead resolv.conf		setf resolv
+
+" Relax NG Compact
+au BufNewFile,BufRead *.rnc			setf rnc
+
+" RPL/2
+au BufNewFile,BufRead *.rpl			setf rpl
+
+" Robots.txt
+au BufNewFile,BufRead robots.txt		setf robots
+
+" Rpcgen
+au BufNewFile,BufRead *.x			setf rpcgen
+
+" reStructuredText Documentation Format
+au BufNewFile,BufRead *.rst			setf rst
+
+" RTF
+au BufNewFile,BufRead *.rtf			setf rtf
+
+" Ruby
+au BufNewFile,BufRead *.rb,*.rbw,*.gem,*.gemspec	setf ruby
+
+" Ruby on Rails
+au BufNewFile,BufRead *.builder,*.rxml,*.rjs	setf ruby
+
+" Rantfile and Rakefile is like Ruby
+au BufNewFile,BufRead [rR]antfile,*.rant,[rR]akefile,*.rake	setf ruby
+
+" S-lang (or shader language!)
+au BufNewFile,BufRead *.sl			setf slang
+
+" Samba config
+au BufNewFile,BufRead smb.conf			setf samba
+
+" SAS script
+au BufNewFile,BufRead *.sas			setf sas
+
+" Sather
+au BufNewFile,BufRead *.sa			setf sather
+
+" Scilab
+au BufNewFile,BufRead *.sci,*.sce		setf scilab
+
+" SD: Streaming Descriptors
+au BufNewFile,BufRead *.sd			setf sd
+
+" SDL
+au BufNewFile,BufRead *.sdl,*.pr		setf sdl
+
+" sed
+au BufNewFile,BufRead *.sed			setf sed
+
+" Sieve (RFC 3028)
+au BufNewFile,BufRead *.siv			setf sieve
+
+" Sendmail
+au BufNewFile,BufRead sendmail.cf		setf sm
+
+" Sendmail .mc files are actually m4
+au BufNewFile,BufRead *.mc			setf m4
+
+" Services
+au BufNewFile,BufRead /etc/services		setf services
+
+" Service Location config
+au BufNewFile,BufRead /etc/slp.conf		setf slpconf
+
+" Service Location registration
+au BufNewFile,BufRead /etc/slp.reg		setf slpreg
+
+" Service Location SPI
+au BufNewFile,BufRead /etc/slp.spi		setf slpspi
+
+" Setserial config
+au BufNewFile,BufRead /etc/serial.conf		setf setserial
+
+" SGML
+au BufNewFile,BufRead *.sgm,*.sgml
+	\ if getline(1).getline(2).getline(3).getline(4).getline(5) =~? 'linuxdoc' |
+	\   setf sgmllnx |
+	\ elseif getline(1) =~ '<!DOCTYPE.*DocBook' || getline(2) =~ '<!DOCTYPE.*DocBook' |
+	\   let b:docbk_type="sgml" |
+	\   setf docbk |
+	\ else |
+	\   setf sgml |
+	\ endif
+
+" SGMLDECL
+au BufNewFile,BufRead *.decl,*.dcl,*.dec
+	\ if getline(1).getline(2).getline(3) =~? '^<!SGML' |
+	\    setf sgmldecl |
+	\ endif
+
+" SGML catalog file
+au BufNewFile,BufRead catalog			setf catalog
+au BufNewFile,BufRead sgml.catalog*		call s:StarSetf('catalog')
+
+" Shell scripts (sh, ksh, bash, bash2, csh); Allow .profile_foo etc.
+" Gentoo ebuilds are actually bash scripts
+au BufNewFile,BufRead .bashrc*,bashrc,bash.bashrc,.bash_profile*,.bash_logout*,*.bash,*.ebuild call SetFileTypeSH("bash")
+au BufNewFile,BufRead .kshrc*,*.ksh call SetFileTypeSH("ksh")
+au BufNewFile,BufRead /etc/profile,.profile*,*.sh,*.env call SetFileTypeSH(getline(1))
+
+" Also called from scripts.vim.
+func! SetFileTypeSH(name)
+  if expand("<amatch>") =~ g:ft_ignore_pat
+    return
+  endif
+  if a:name =~ '\<ksh\>'
+    let b:is_kornshell = 1
+    if exists("b:is_bash")
+      unlet b:is_bash
+    endif
+    if exists("b:is_sh")
+      unlet b:is_sh
+    endif
+  elseif exists("g:bash_is_sh") || a:name =~ '\<bash\>' || a:name =~ '\<bash2\>'
+    let b:is_bash = 1
+    if exists("b:is_kornshell")
+      unlet b:is_kornshell
+    endif
+    if exists("b:is_sh")
+      unlet b:is_sh
+    endif
+  elseif a:name =~ '\<sh\>'
+    let b:is_sh = 1
+    if exists("b:is_kornshell")
+      unlet b:is_kornshell
+    endif
+    if exists("b:is_bash")
+      unlet b:is_bash
+    endif
+  endif
+  call SetFileTypeShell("sh")
+endfunc
+
+" For shell-like file types, check for an "exec" command hidden in a comment,
+" as used for Tcl.
+" Also called from scripts.vim, thus can't be local to this script.
+func! SetFileTypeShell(name)
+  if expand("<amatch>") =~ g:ft_ignore_pat
+    return
+  endif
+  let l = 2
+  while l < 20 && l < line("$") && getline(l) =~ '^\s*\(#\|$\)'
+    " Skip empty and comment lines.
+    let l = l + 1
+  endwhile
+  if l < line("$") && getline(l) =~ '\s*exec\s' && getline(l - 1) =~ '^\s*#.*\\$'
+    " Found an "exec" line after a comment with continuation
+    let n = substitute(getline(l),'\s*exec\s\+\([^ ]*/\)\=', '', '')
+    if n =~ '\<tclsh\|\<wish'
+      setf tcl
+      return
+    endif
+  endif
+  exe "setf " . a:name
+endfunc
+
+" tcsh scripts
+au BufNewFile,BufRead .tcshrc*,*.tcsh,tcsh.tcshrc,tcsh.login	call SetFileTypeShell("tcsh")
+
+" csh scripts, but might also be tcsh scripts (on some systems csh is tcsh)
+au BufNewFile,BufRead .login*,.cshrc*,csh.cshrc,csh.login,csh.logout,*.csh,.alias  call s:CSH()
+
+func! s:CSH()
+  if exists("g:filetype_csh")
+    call SetFileTypeShell(g:filetype_csh)
+  elseif &shell =~ "tcsh"
+    call SetFileTypeShell("tcsh")
+  else
+    call SetFileTypeShell("csh")
+  endif
+endfunc
+
+" Z-Shell script
+au BufNewFile,BufRead .zprofile,/etc/zprofile,.zfbfmarks  setf zsh
+au BufNewFile,BufRead .zsh*,.zlog*,.zcompdump*  call s:StarSetf('zsh')
+
+" Scheme
+au BufNewFile,BufRead *.scm,*.ss		setf scheme
+
+" Screen RC
+au BufNewFile,BufRead .screenrc,screenrc	setf screen
+
+" Simula
+au BufNewFile,BufRead *.sim			setf simula
+
+" SINDA
+au BufNewFile,BufRead *.sin,*.s85		setf sinda
+
+" SiSU
+au BufNewFile,BufRead *.sst,*.ssm,*.ssi,*.-sst,*._sst setf sisu
+au BufNewFile,BufRead *.sst.meta,*.-sst.meta,*._sst.meta setf sisu
+
+" SKILL
+au BufNewFile,BufRead *.il,*.ils,*.cdf		setf skill
+
+" SLRN
+au BufNewFile,BufRead .slrnrc			setf slrnrc
+au BufNewFile,BufRead *.score			setf slrnsc
+
+" Smalltalk (and TeX)
+au BufNewFile,BufRead *.st			setf st
+au BufNewFile,BufRead *.cls
+	\ if getline(1) =~ '^%' |
+	\  setf tex |
+	\ else |
+	\  setf st |
+	\ endif
+
+" Smarty templates
+au BufNewFile,BufRead *.tpl			setf smarty
+
+" SMIL or XML
+au BufNewFile,BufRead *.smil
+	\ if getline(1) =~ '<?\s*xml.*?>' |
+	\   setf xml |
+	\ else |
+	\   setf smil |
+	\ endif
+
+" SMIL or SNMP MIB file
+au BufNewFile,BufRead *.smi
+	\ if getline(1) =~ '\<smil\>' |
+	\   setf smil |
+	\ else |
+	\   setf mib |
+	\ endif
+
+" SMITH
+au BufNewFile,BufRead *.smt,*.smith		setf smith
+
+" Snobol4 and spitbol
+au BufNewFile,BufRead *.sno,*.spt		setf snobol4
+
+" SNMP MIB files
+au BufNewFile,BufRead *.mib,*.my		setf mib
+
+" Snort Configuration
+au BufNewFile,BufRead *.hog,snort.conf,vision.conf	setf hog
+au BufNewFile,BufRead *.rules			call s:FTRules()
+
+let s:ft_rules_udev_rules_pattern = '^\s*\cudev_rules\s*=\s*"\([^"]\{-1,}\)/*".*'
+func! s:FTRules()
+  try
+    let config_lines = readfile('/etc/udev/udev.conf')
+  catch /^Vim\%((\a\+)\)\=:E484/
+    setf hog
+    return
+  endtry
+  for line in config_lines
+    if line =~ s:ft_rules_udev_rules_pattern
+      let udev_rules = substitute(line, s:ft_rules_udev_rules_pattern, '\1', "")
+      let amatch_dirname = substitute(expand('<amatch>'), '^\(.*\)/[^/]\+$', '\1', "")
+      if amatch_dirname == udev_rules
+        setf udevrules
+      endif
+      break
+    endif
+  endfor
+  setf hog
+endfunc
+
+
+" Spec (Linux RPM)
+au BufNewFile,BufRead *.spec			setf spec
+
+" Speedup (AspenTech plant simulator)
+au BufNewFile,BufRead *.speedup,*.spdata,*.spd	setf spup
+
+" Slice
+au BufNewFile,BufRead *.ice			setf slice
+
+" Spice
+au BufNewFile,BufRead *.sp,*.spice		setf spice
+
+" Spyce
+au BufNewFile,BufRead *.spy,*.spi		setf spyce
+
+" Squid
+au BufNewFile,BufRead squid.conf		setf squid
+
+" SQL for Oracle Designer
+au BufNewFile,BufRead *.tyb,*.typ,*.tyc,*.pkb,*.pks	setf sql
+
+" SQL
+au BufNewFile,BufRead *.sql			call s:SQL()
+
+func! s:SQL()
+  if exists("g:filetype_sql")
+    exe "setf " . g:filetype_sql
+  else
+    setf sql
+  endif
+endfunc
+
+" SQLJ
+au BufNewFile,BufRead *.sqlj			setf sqlj
+
+" SQR
+au BufNewFile,BufRead *.sqr,*.sqi		setf sqr
+
+" OpenSSH configuration
+au BufNewFile,BufRead ssh_config,*/.ssh/config	setf sshconfig
+
+" OpenSSH server configuration
+au BufNewFile,BufRead sshd_config		setf sshdconfig
+
+" Stata
+au BufNewFile,BufRead *.ado,*.class,*.do,*.imata,*.mata   setf stata
+
+" SMCL
+au BufNewFile,BufRead *.hlp,*.ihlp,*.smcl	setf smcl
+
+" Stored Procedures
+au BufNewFile,BufRead *.stp			setf stp
+
+" Standard ML
+au BufNewFile,BufRead *.sml			setf sml
+
+" Sysctl
+au BufNewFile,BufRead /etc/sysctl.conf		setf sysctl
+
+" Sudoers
+au BufNewFile,BufRead /etc/sudoers,sudoers.tmp	setf sudoers
+
+" If the file has an extension of 't' and is in a directory 't' then it is
+" almost certainly a Perl test file.
+" If the first line starts with '#' and contains 'perl' it's probably a Perl
+" file.
+" (Slow test) If a file contains a 'use' statement then it is almost certainly
+" a Perl file.
+func! s:FTperl()
+  if expand("%:e") == 't' && expand("%:p:h:t") == 't'
+    setf perl
+    return 1
+  endif
+  if getline(1)[0] == '#' && getline(1) =~ 'perl'
+    setf perl
+    return 1
+  endif
+  if search('^use\s\s*\k', 'nc', 30)
+    setf perl
+    return 1
+  endif
+  return 0
+endfunc
+
+" Tads (or Nroff or Perl test file)
+au BufNewFile,BufRead *.t
+	\ if !s:FTnroff() && !s:FTperl() | setf tads | endif
+
+" Tags
+au BufNewFile,BufRead tags			setf tags
+
+" TAK
+au BufNewFile,BufRead *.tak			setf tak
+
+" Tcl (JACL too)
+au BufNewFile,BufRead *.tcl,*.tk,*.itcl,*.itk,*.jacl	setf tcl
+
+" TealInfo
+au BufNewFile,BufRead *.tli			setf tli
+
+" Telix Salt
+au BufNewFile,BufRead *.slt			setf tsalt
+
+" Terminfo
+au BufNewFile,BufRead *.ti			setf terminfo
+
+" TeX
+au BufNewFile,BufRead *.latex,*.sty,*.dtx,*.ltx,*.bbl	setf tex
+au BufNewFile,BufRead *.tex			call s:FTtex()
+
+" Choose context, plaintex, or tex (LaTeX) based on these rules:
+" 1. Check the first line of the file for "%&<format>".
+" 2. Check the first 1000 non-comment lines for LaTeX or ConTeXt keywords.
+" 3. Default to "latex" or to g:tex_flavor, can be set in user's vimrc.
+func! s:FTtex()
+  let firstline = getline(1)
+  if firstline =~ '^%&\s*\a\+'
+    let format = tolower(matchstr(firstline, '\a\+'))
+    let format = substitute(format, 'pdf', '', '')
+    if format == 'tex'
+      let format = 'plain'
+    endif
+  else
+    " Default value, may be changed later:
+    let format = exists("g:tex_flavor") ? g:tex_flavor : 'plain'
+    " Save position, go to the top of the file, find first non-comment line.
+    let save_cursor = getpos('.')
+    call cursor(1,1)
+    let firstNC = search('^\s*[^[:space:]%]', 'c', 1000)
+    if firstNC " Check the next thousand lines for a LaTeX or ConTeXt keyword.
+      let lpat = 'documentclass\>\|usepackage\>\|begin{\|newcommand\>\|renewcommand\>'
+      let cpat = 'start\a\+\|setup\a\+\|usemodule\|enablemode\|enableregime\|setvariables\|useencoding\|usesymbols\|stelle\a\+\|verwende\a\+\|stel\a\+\|gebruik\a\+\|usa\a\+\|imposta\a\+\|regle\a\+\|utilisemodule\>'
+      let kwline = search('^\s*\\\%(' . lpat . '\)\|^\s*\\\(' . cpat . '\)',
+			      \ 'cnp', firstNC + 1000)
+      if kwline == 1	" lpat matched
+	let format = 'latex'
+      elseif kwline == 2	" cpat matched
+	let format = 'context'
+      endif		" If neither matched, keep default set above.
+      " let lline = search('^\s*\\\%(' . lpat . '\)', 'cn', firstNC + 1000)
+      " let cline = search('^\s*\\\%(' . cpat . '\)', 'cn', firstNC + 1000)
+      " if cline > 0
+      "   let format = 'context'
+      " endif
+      " if lline > 0 && (cline == 0 || cline > lline)
+      "   let format = 'tex'
+      " endif
+    endif " firstNC
+    call setpos('.', save_cursor)
+  endif " firstline =~ '^%&\s*\a\+'
+
+  " Translation from formats to file types.  TODO:  add AMSTeX, RevTex, others?
+  if format == 'plain'
+    setf plaintex
+  elseif format == 'context'
+    setf context
+  else " probably LaTeX
+    setf tex
+  endif
+  return
+endfunc
+
+" Context
+au BufNewFile,BufRead tex/context/*/*.tex	setf context
+
+" Texinfo
+au BufNewFile,BufRead *.texinfo,*.texi,*.txi	setf texinfo
+
+" TeX configuration
+au BufNewFile,BufRead texmf.cnf			setf texmf
+
+" Tidy config
+au BufNewFile,BufRead .tidyrc,tidyrc		setf tidy
+
+" TF mud client
+au BufNewFile,BufRead *.tf,.tfrc,tfrc		setf tf
+
+" TPP - Text Presentation Program
+au BufNewFile,BufReadPost *.tpp			setf tpp
+
+" Trustees
+au BufNewFile,BufRead trustees.conf		setf trustees
+
+" TSS - Geometry
+au BufNewFile,BufReadPost *.tssgm		setf tssgm
+
+" TSS - Optics
+au BufNewFile,BufReadPost *.tssop		setf tssop
+
+" TSS - Command Line (temporary)
+au BufNewFile,BufReadPost *.tsscl		setf tsscl
+
+" Motif UIT/UIL files
+au BufNewFile,BufRead *.uit,*.uil		setf uil
+
+" Udev conf
+au BufNewFile,BufRead /etc/udev/udev.conf	setf udevconf
+
+" Udev rules
+au BufNewFile,BufRead /etc/udev/rules.d/*.rules setf udevrules
+
+" Udev permissions
+au BufNewFile,BufRead /etc/udev/permissions.d/*.permissions setf udevperm
+"
+" Udev symlinks config
+au BufNewFile,BufRead /etc/udev/cdsymlinks.conf	setf sh
+
+" UnrealScript
+au BufNewFile,BufRead *.uc			setf uc
+
+" Updatedb
+au BufNewFile,BufRead /etc/updatedb.conf	setf updatedb
+
+" Vera
+au BufNewFile,BufRead *.vr,*.vri,*.vrh		setf vera
+
+" Verilog HDL
+au BufNewFile,BufRead *.v			setf verilog
+
+" Verilog-AMS HDL
+au BufNewFile,BufRead *.va,*.vams		setf verilogams
+
+" VHDL
+au BufNewFile,BufRead *.hdl,*.vhd,*.vhdl,*.vbe,*.vst  setf vhdl
+au BufNewFile,BufRead *.vhdl_[0-9]*		call s:StarSetf('vhdl')
+
+" Vim script
+au BufNewFile,BufRead *.vim,*.vba,.exrc,_exrc	setf vim
+
+" Viminfo file
+au BufNewFile,BufRead .viminfo,_viminfo		setf viminfo
+
+" Virata Config Script File
+au BufRead,BufNewFile *.hw,*.module,*.pkg	setf virata
+
+" Visual Basic (also uses *.bas) or FORM
+au BufNewFile,BufRead *.frm			call s:FTVB("form")
+
+" SaxBasic is close to Visual Basic
+au BufNewFile,BufRead *.sba			setf vb
+
+" Vgrindefs file
+au BufNewFile,BufRead vgrindefs			setf vgrindefs
+
+" VRML V1.0c
+au BufNewFile,BufRead *.wrl			setf vrml
+
+" Webmacro
+au BufNewFile,BufRead *.wm			setf webmacro
+
+" Wget config
+au BufNewFile,BufRead .wgetrc,wgetrc		setf wget
+
+" Website MetaLanguage
+au BufNewFile,BufRead *.wml			setf wml
+
+" Winbatch
+au BufNewFile,BufRead *.wbt			setf winbatch
+
+" WSML
+au BufNewFile,BufRead *.wsml			setf wsml
+
+" WvDial
+au BufNewFile,BufRead wvdial.conf,.wvdialrc	setf wvdial
+
+" CVS RC file
+au BufNewFile,BufRead .cvsrc			setf cvsrc
+
+" CVS commit file
+au BufNewFile,BufRead cvs\d\+			setf cvs
+
+" WEB (*.web is also used for Winbatch: Guess, based on expecting "%" comment
+" lines in a WEB file).
+au BufNewFile,BufRead *.web
+	\ if getline(1)[0].getline(2)[0].getline(3)[0].getline(4)[0].getline(5)[0] =~ "%" |
+	\   setf web |
+	\ else |
+	\   setf winbatch |
+	\ endif
+
+" Windows Scripting Host and Windows Script Component
+au BufNewFile,BufRead *.ws[fc]			setf wsh
+
+" XHTML
+au BufNewFile,BufRead *.xhtml,*.xht		setf xhtml
+
+" X Pixmap (dynamically sets colors, use BufEnter to make it work better)
+au BufEnter *.xpm
+	\ if getline(1) =~ "XPM2" |
+	\   setf xpm2 |
+	\ else |
+	\   setf xpm |
+	\ endif
+au BufEnter *.xpm2				setf xpm2
+
+" XFree86 config
+au BufNewFile,BufRead XF86Config
+	\ if getline(1) =~ '\<XConfigurator\>' |
+	\   let b:xf86c_xfree86_version = 3 |
+	\ endif |
+	\ setf xf86conf
+
+" Xorg config
+au BufNewFile,BufRead xorg.conf,xorg.conf-4	let b:xf86c_xfree86_version = 4 | setf xf86conf
+
+" Xinetd conf
+au BufNewFile,BufRead /etc/xinetd.conf		setf xinetd
+
+" XS Perl extension interface language
+au BufNewFile,BufRead *.xs			setf xs
+
+" X resources file
+au BufNewFile,BufRead .Xdefaults,.Xpdefaults,.Xresources,xdm-config,*.ad setf xdefaults
+
+" Xmath
+au BufNewFile,BufRead *.msc,*.msf		setf xmath
+au BufNewFile,BufRead *.ms
+	\ if !s:FTnroff() | setf xmath | endif
+
+" XML
+au BufNewFile,BufRead *.xml
+	\ if getline(1) . getline(2) . getline(3) =~ '<!DOCTYPE.*DocBook' |
+	\   let b:docbk_type="xml" |
+	\   setf docbk |
+	\ else |
+	\   setf xml |
+	\ endif
+
+" XMI (holding UML models) is also XML
+au BufNewFile,BufRead *.xmi			setf xml
+
+" CSPROJ files are Visual Studio.NET's XML-based project config files
+au BufNewFile,BufRead *.csproj,*.csproj.user	setf xml
+
+" Qt Linguist translation source and Qt User Interface Files are XML
+au BufNewFile,BufRead *.ts,*.ui			setf xml
+
+" TPM's are RDF-based descriptions of TeX packages (Nikolai Weibull)
+au BufNewFile,BufRead *.tpm			setf xml
+
+" Xdg menus
+au BufNewFile,BufRead /etc/xdg/menus/*.menu	setf xml
+
+" Xquery
+au BufNewFile,BufRead *.xq,*.xql,*.xqm,*.xquery,*.xqy	setf xquery
+
+" XSD
+au BufNewFile,BufRead *.xsd			setf xsd
+
+" Xslt
+au BufNewFile,BufRead *.xsl,*.xslt		setf xslt
+
+" Yacc
+au BufNewFile,BufRead *.yy			setf yacc
+
+" Yacc or racc
+au BufNewFile,BufRead *.y			call s:FTy()
+
+func! s:FTy()
+  let n = 1
+  while n < 100 && n < line("$")
+    let line = getline(n)
+    if line =~ '^\s*%'
+      setf yacc
+      return
+    endif
+    if getline(n) =~ '^\s*\(#\|class\>\)' && getline(n) !~ '^\s*#\s*include'
+      setf racc
+      return
+    endif
+    let n = n + 1
+  endwhile
+  setf yacc
+endfunc
+
+
+" Yaml
+au BufNewFile,BufRead *.yaml,*.yml		setf yaml
+
+" Zope
+"   dtml (zope dynamic template markup language), pt (zope page template),
+"   cpt (zope form controller page template)
+au BufNewFile,BufRead *.dtml,*.pt,*.cpt		call s:FThtml()
+"   zsql (zope sql method)
+au BufNewFile,BufRead *.zsql			call s:SQL()
+
+" Z80 assembler asz80
+au BufNewFile,BufRead *.z8a			setf z8a
+
+augroup END
+
+
+" Source the user-specified filetype file, for backwards compatibility with
+" Vim 5.x.
+if exists("myfiletypefile") && filereadable(expand(myfiletypefile))
+  execute "source " . myfiletypefile
+endif
+
+
+" Check for "*" after loading myfiletypefile, so that scripts.vim is only used
+" when there are no matching file name extensions.
+" Don't do this for compressed files.
+augroup filetypedetect
+au BufNewFile,BufRead *
+	\ if !did_filetype() && expand("<amatch>") !~ g:ft_ignore_pat
+	\ | runtime! scripts.vim | endif
+au StdinReadPost * if !did_filetype() | runtime! scripts.vim | endif
+
+
+" Extra checks for when no filetype has been detected now.  Mostly used for
+" patterns that end in "*".  E.g., "zsh*" matches "zsh.vim", but that's a Vim
+" script file.
+" Most of these should call s:StarSetf() to avoid names ending in .gz and the
+" like are used.
+
+" Asterisk config file
+au BufNewFile,BufRead *asterisk/*.conf*		call s:StarSetf('asterisk')
+au BufNewFile,BufRead *asterisk*/*voicemail.conf* call s:StarSetf('asteriskvm')
+
+" Bazaar version control
+au BufNewFile,BufRead bzr_log.*			setf bzr
+
+" BIND zone
+au BufNewFile,BufRead */named/db.*,*/bind/db.*	call s:StarSetf('bindzone')
+
+" Changelog
+au BufNewFile,BufRead [cC]hange[lL]og*
+	\ if getline(1) =~ '; urgency='
+	\|  call s:StarSetf('debchangelog')
+	\|else
+	\|  call s:StarSetf('changelog')
+	\|endif
+
+" Crontab
+au BufNewFile,BufRead crontab,crontab.*		call s:StarSetf('crontab')
+
+" Debian Sources.list
+au BufNewFile,BufRead /etc/apt/sources.list.d/*	call s:StarSetf('debsources')
+
+" Dracula
+au BufNewFile,BufRead drac.*			call s:StarSetf('dracula')
+
+" Fvwm
+au BufNewFile,BufRead */.fvwm/*			call s:StarSetf('fvwm')
+au BufNewFile,BufRead *fvwmrc*,*fvwm95*.hook
+	\ let b:fvwm_version = 1 | call s:StarSetf('fvwm')
+au BufNewFile,BufRead *fvwm2rc*
+	\ if expand("<afile>:e") == "m4"
+	\|  call s:StarSetf('fvwm2m4')
+	\|else
+	\|  let b:fvwm_version = 2 | call s:StarSetf('fvwm')
+	\|endif
+
+" GTK RC
+au BufNewFile,BufRead .gtkrc*,gtkrc*		call s:StarSetf('gtkrc')
+
+" Jam
+au BufNewFile,BufRead Prl*.*,JAM*.*		call s:StarSetf('jam')
+
+" Jargon
+au! BufNewFile,BufRead *jarg*
+	\ if getline(1).getline(2).getline(3).getline(4).getline(5) =~? 'THIS IS THE JARGON FILE'
+	\|  call s:StarSetf('jargon')
+	\|endif
+
+" Kconfig
+au BufNewFile,BufRead Kconfig.*			call s:StarSetf('kconfig')
+
+" Makefile
+au BufNewFile,BufRead [mM]akefile*		call s:StarSetf('make')
+
+" Modconf
+au BufNewFile,BufRead /etc/modprobe.*		call s:StarSetf('modconf')
+
+" Ruby Makefile
+au BufNewFile,BufRead [rR]akefile*		call s:StarSetf('ruby')
+
+" Mutt setup file
+au BufNewFile,BufRead mutt{ng,}rc*,Mutt{ng,}rc*		call s:StarSetf('muttrc')
+
+" Nroff macros
+au BufNewFile,BufRead tmac.*			call s:StarSetf('nroff')
+
+" Pam conf
+au BufNewFile,BufRead /etc/pam.d/*		call s:StarSetf('pamconf')
+
+" Printcap and Termcap
+au BufNewFile,BufRead *printcap*
+	\ if !did_filetype()
+	\|  let b:ptcap_type = "print" | call s:StarSetf('ptcap')
+	\|endif
+au BufNewFile,BufRead *termcap*
+	\ if !did_filetype()
+	\|  let b:ptcap_type = "term" | call s:StarSetf('ptcap')
+	\|endif
+
+" Vim script
+au BufNewFile,BufRead *vimrc*			call s:StarSetf('vim')
+
+" Subversion commit file
+au BufNewFile,BufRead svn-commit*.tmp		setf svn
+
+" X resources file
+au BufNewFile,BufRead Xresources*,*/app-defaults/*,*/Xresources/* call s:StarSetf('xdefaults')
+
+" XFree86 config
+au BufNewFile,BufRead XF86Config-4*
+	\ let b:xf86c_xfree86_version = 4 | call s:StarSetf('xf86conf')
+au BufNewFile,BufRead XF86Config*
+	\ if getline(1) =~ '\<XConfigurator\>'
+	\|  let b:xf86c_xfree86_version = 3
+	\|endif
+	\|call s:StarSetf('xf86conf')
+
+" X11 xmodmap
+au BufNewFile,BufRead *xmodmap*			call s:StarSetf('xmodmap')
+
+" Xinetd conf
+au BufNewFile,BufRead /etc/xinetd.d/*		call s:StarSetf('xinetd')
+
+" Z-Shell script
+au BufNewFile,BufRead zsh*,zlog*		call s:StarSetf('zsh')
+
+
+" Generic configuration file (check this last, it's just guessing!)
+au BufNewFile,BufRead,StdinReadPost *
+	\ if !did_filetype() && expand("<amatch>") !~ g:ft_ignore_pat
+	\    && (getline(1) =~ '^#' || getline(2) =~ '^#' || getline(3) =~ '^#'
+	\	|| getline(4) =~ '^#' || getline(5) =~ '^#') |
+	\   setf conf |
+	\ endif
+
+" Use the plugin-filetype checks last, they may overrule any of the previously
+" detected filetypes.
+runtime! ftdetect/*.vim
+
+augroup END
+
+
+" If the GUI is already running, may still need to install the Syntax menu.
+" Don't do it when the 'M' flag is included in 'guioptions'.
+if has("menu") && has("gui_running")
+      \ && !exists("did_install_syntax_menu") && &guioptions !~# "M"
+  source <sfile>:p:h/menu.vim
+endif
+
+" Function called for testing all functions defined here.  These are
+" script-local, thus need to be executed here.
+" Returns a string with error messages (hopefully empty).
+func! TestFiletypeFuncs(testlist)
+  let output = ''
+  for f in a:testlist
+    try
+      exe f
+    catch
+      let output = output . "\n" . f . ": " . v:exception
+    endtry
+  endfor
+  return output
+endfunc
+
+" Restore 'cpoptions'
+let &cpo = s:cpo_save
+unlet s:cpo_save
--- /dev/null
+++ b/lib/vimfiles/ftoff.vim
@@ -1,0 +1,11 @@
+" Vim support file to switch off detection of file types
+"
+" Maintainer:	Bram Moolenaar <Bram@vim.org>
+" Last change:	2001 Jun 11
+
+if exists("did_load_filetypes")
+  unlet did_load_filetypes
+endif
+
+" Remove all autocommands in the filetypedetect group
+silent! au! filetypedetect *
--- /dev/null
+++ b/lib/vimfiles/ftplugin.vim
@@ -1,0 +1,35 @@
+" Vim support file to switch on loading plugins for file types
+"
+" Maintainer:	Bram Moolenaar <Bram@vim.org>
+" Last change:	2006 Apr 30
+
+if exists("did_load_ftplugin")
+  finish
+endif
+let did_load_ftplugin = 1
+
+augroup filetypeplugin
+  au FileType * call s:LoadFTPlugin()
+
+  func! s:LoadFTPlugin()
+    if exists("b:undo_ftplugin")
+      exe b:undo_ftplugin
+      unlet! b:undo_ftplugin b:did_ftplugin
+    endif
+
+    let s = expand("<amatch>")
+    if s != ""
+      if &cpo =~# "S" && exists("b:did_ftplugin")
+	" In compatible mode options are reset to the global values, need to
+	" set the local values also when a plugin was already used.
+	unlet b:did_ftplugin
+      endif
+
+      " When there is a dot it is used to separate filetype names.  Thus for
+      " "aaa.bbb" load "aaa" and then "bbb".
+      for name in split(s, '\.')
+	exe 'runtime! ftplugin/' . name . '.vim ftplugin/' . name . '_*.vim ftplugin/' . name . '/*.vim'
+      endfor
+    endif
+  endfunc
+augroup END
--- /dev/null
+++ b/lib/vimfiles/ftplugin/AppendMatchGroup.vim
@@ -1,0 +1,125 @@
+" Vim filetype plugin file utility
+" Language:    * (various)
+" Maintainer:  Dave Silvia <dsilvia@mchsi.com>
+" Date:        6/30/2004
+
+" The start of match (b:SOM) default is:
+"       '\<'
+" The end of match (b:EOM) default is:
+"       '\>'
+"
+" If you want to use some other start/end of match, just assign the
+" value to the b:SOM|EOM variable in your filetype script.
+"
+" SEE: :h pattern.txt
+"      :h pattern-searches
+"      :h regular-expression
+"      :h matchit
+
+let s:myName=expand("<sfile>:t")
+
+" matchit.vim not loaded -- don't do anyting
+if !exists("loaded_matchit")
+	echomsg s:myName.": matchit.vim not loaded -- finishing without loading"
+	finish
+endif
+
+" already been here -- don't redefine
+if exists("*AppendMatchGroup")
+	finish
+endif
+
+" Function To Build b:match_words
+" The following function, 'AppendMatchGroup', helps to increase
+" readability of your filetype script if you choose to use matchit.
+" It also precludes many construction errors, reducing the
+" construction to simply invoking the function with the match words.
+" As an example, let's take the ubiquitous if/then/else/endif type
+" of construct.  This is how the entry in your filetype script would look.
+"
+"     " source the AppendMatchGroup function file
+"     runtime ftplugin/AppendMatchGroup.vim
+"
+"     " fill b:match_words
+"     call AppendMatchGroup('if,then,else,endif')
+"
+" And the b:match_words constructed would look like:
+"
+"     \<if\>:\<then\>:\<else\>:\<endif\>
+" 
+" Use of AppendMatchGroup makes your filetype script is a little
+" less busy and a lot more readable.  Additionally, it
+" checks three critical things:
+"
+"      1)  Do you have at least 2 entries in your match group.
+"
+"      2)  Does the buffer variable 'b:match_words' exist?  if not, create it.
+"
+"      3)  If the buffer variable 'b:match_words' does exist, is the last
+"          character a ','?  If not, add it before appending.
+" 
+" You should now be able to match 'if/then/else/endif' in succession
+" in your source file, in just about any construction you may have
+" chosen for them.
+"
+" To add another group, simply call 'AppendMatchGroup again.  E.G.:
+"
+"      call AppendMatchGroup('while,do,endwhile')
+
+function AppendMatchGroup(mwordList)
+	let List=a:mwordList
+	let Comma=match(List,',')
+	if Comma == -1 || Comma == strlen(List)-1
+		echoerr "Must supply a comma separated list of at least 2 entries."
+		echoerr "Supplied list: <".List.">"
+		return
+	endif
+	let listEntryBegin=0
+	let listEntryEnd=Comma
+	let listEntry=strpart(List,listEntryBegin,listEntryEnd-listEntryBegin)
+	let List=strpart(List,Comma+1)
+	let Comma=match(List,',')
+	" if listEntry is all spaces || List is empty || List is all spaces
+	if (match(listEntry,'\s\+') == 0 && match(listEntry,'\S\+') == -1)
+			\ || List == '' || (match(List,'\s\+') == 0 && match(List,'\S\+') == -1)
+		echoerr "Can't use all spaces for an entry <".listEntry.">"
+		echoerr "Remaining supplied list: <".List.">"
+		return
+	endif
+
+	if !exists("b:SOM")
+		let b:SOM='\<'
+	endif
+	if !exists("b:EOM")
+		let b:EOM='\>'
+	endif
+	if !exists("b:match_words")
+		let b:match_words=''
+	endif
+	if b:match_words != '' && match(b:match_words,',$') == -1
+		let b:match_words=b:match_words.','
+	endif
+	" okay, all set add first entry in this list
+	let b:match_words=b:match_words.b:SOM.listEntry.b:EOM.':'
+	while Comma != -1
+		let listEntryEnd=Comma
+		let listEntry=strpart(List,listEntryBegin,listEntryEnd-listEntryBegin)
+		let List=strpart(List,Comma+1)
+		let Comma=match(List,',')
+		" if listEntry is all spaces
+		if match(listEntry,'\s\+') == 0 && match(listEntry,'\S\+') == -1
+			echoerr "Can't use all spaces for an entry <".listEntry."> - skipping"
+			echoerr "Remaining supplied list: <".List.">"
+			continue
+		endif
+		let b:match_words=b:match_words.b:SOM.listEntry.b:EOM.':'
+	endwhile
+	let listEntry=List
+	let b:match_words=b:match_words.b:SOM.listEntry.b:EOM
+endfunction
+
+" TODO:  Write a wrapper to handle multiple groups in one function call.
+"        Don't see a lot of utility in this as it would undoubtedly warrant
+"        continuation lines in the filetype script and it would be a toss
+"        up as to which is more readable: individual calls one to a line or
+"        a single call with continuation lines.  I vote for the former.
--- /dev/null
+++ b/lib/vimfiles/ftplugin/README.txt
@@ -1,0 +1,24 @@
+The ftplugin directory is for Vim plugin scripts that are only used for a
+specific filetype.
+
+All files ending in .vim in this directory and subdirectories will be sourced
+by Vim when it detects the filetype that matches the name of the file or
+subdirectory.
+For example, these are all loaded for the "c" filetype:
+
+	c.vim
+	c_extra.vim
+	c/settings.vim
+
+Note that the "_" in "c_extra.vim" is required to separate the filetype name
+from the following arbitrary name.
+
+The filetype plugins are only loaded when the ":filetype plugin" command has
+been used.
+
+The default filetype plugin files contain settings that 95% of the users will
+want to use.  They do not contain personal preferences, like the value of
+'shiftwidth'.
+
+If you want to do additional settings, or overrule the default filetype
+plugin, you can create your own plugin file.  See ":help ftplugin" in Vim.
--- /dev/null
+++ b/lib/vimfiles/ftplugin/a2ps.vim
@@ -1,0 +1,14 @@
+" Vim filetype plugin file
+" Language:         a2ps(1) configuration file
+" Maintainer:       Nikolai Weibull <now@bitwi.se>
+" Latest Revision:  2006-04-19
+
+if exists("b:did_ftplugin")
+  finish
+endif
+let b:did_ftplugin = 1
+
+let b:undo_ftplugin = "setl com< cms< inc< fo<"
+
+setlocal comments=:# commentstring=#\ %s include=^\\s*Include:
+setlocal formatoptions-=t formatoptions+=croql
--- /dev/null
+++ b/lib/vimfiles/ftplugin/aap.vim
@@ -1,0 +1,25 @@
+" Vim filetype plugin file
+" Language:	Aap recipe
+" Maintainer:	Bram Moolenaar <Bram@vim.org>
+" Last Change:	2003 Nov 04
+
+" Only do this when not done yet for this buffer
+if exists("b:did_ftplugin")
+  finish
+endif
+
+" Don't load another plugin for this buffer
+let b:did_ftplugin = 1
+
+" Reset 'formatoptions', 'comments' and 'expandtab' to undo this plugin.
+let b:undo_ftplugin = "setl fo< com< et<"
+
+" Set 'formatoptions' to break comment lines but not other lines,
+" and insert the comment leader when hitting <CR> or using "o".
+setlocal fo-=t fo+=croql
+
+" Set 'comments' to format dashed lists in comments.
+setlocal comments=s:#\ -,m:#\ \,e:#,n:#,fb:-
+
+" Expand tabs to spaces to avoid trouble.
+setlocal expandtab
--- /dev/null
+++ b/lib/vimfiles/ftplugin/abaqus.vim
@@ -1,0 +1,79 @@
+" Vim filetype plugin file
+" Language:     Abaqus finite element input file (www.abaqus.com)
+" Maintainer:   Carl Osterwisch <osterwischc@asme.org>
+" Last Change:  2004 Jul 06
+
+" Only do this when not done yet for this buffer
+if exists("b:did_ftplugin") | finish | endif
+
+" Don't load another plugin for this buffer
+let b:did_ftplugin = 1
+
+" Save the compatibility options and temporarily switch to vim defaults
+let s:cpo_save = &cpoptions
+set cpoptions&vim
+
+" Folding
+if version >= 600
+    " Fold all lines that do not begin with *
+    setlocal foldexpr=getline(v:lnum)[0]!=\"\*\"
+    setlocal foldmethod=expr
+endif
+
+" Set the format of the include file specification for Abaqus
+" Used in :check gf ^wf [i and other commands
+setlocal include=\\<\\cINPUT\\s*=
+
+" Remove characters up to the first = when evaluating filenames
+setlocal includeexpr=substitute(v:fname,'.\\{-}=','','')
+
+" Remove comma from valid filename characters since it is used to
+" separate keyword parameters
+setlocal isfname-=,
+
+" Define format of comment lines (see 'formatoptions' for uses)
+setlocal comments=:**
+setlocal commentstring=**%s
+
+" Definitions start with a * and assign a NAME, NSET, or ELSET
+" Used in [d ^wd and other commands
+setlocal define=^\\*\\a.*\\c\\(NAME\\\|NSET\\\|ELSET\\)\\s*=
+
+" Abaqus keywords and identifiers may include a - character
+setlocal iskeyword+=-
+
+" Set the file browse filter (currently only supported under Win32 gui)
+if has("gui_win32") && !exists("b:browsefilter")
+    let b:browsefilter = "Abaqus Input Files (*.inp *.inc)\t*.inp;*.inc\n" .
+    \ "Abaqus Results (*.dat)\t*.dat\n" .
+    \ "Abaqus Messages (*.pre *.msg *.sta)\t*.pre;*.msg;*.sta\n" .
+    \ "All Files (*.*)\t*.*\n"
+endif
+
+" Define keys used to move [count] sections backward or forward.
+" TODO: Make this do something intelligent in visual mode.
+nnoremap <silent> <buffer> [[ :call <SID>Abaqus_Jump('?^\*\a?')<CR>
+nnoremap <silent> <buffer> ]] :call <SID>Abaqus_Jump('/^\*\a/')<CR>
+function! <SID>Abaqus_Jump(motion) range
+    let s:count = v:count1
+    mark '
+    while s:count > 0
+        silent! execute a:motion
+        let s:count = s:count - 1
+    endwhile
+endfunction
+
+" Define key to toggle commenting of the current line or range
+noremap <silent> <buffer> <m-c> :call <SID>Abaqus_ToggleComment()<CR>j
+function! <SID>Abaqus_ToggleComment() range
+    if strpart(getline(a:firstline), 0, 2) == "**"
+        " Un-comment all lines in range
+        silent execute a:firstline . ',' . a:lastline . 's/^\*\*//'
+    else
+        " Comment all lines in range
+        silent execute a:firstline . ',' . a:lastline . 's/^/**/'
+    endif
+endfunction
+
+" Restore saved compatibility options
+let &cpoptions = s:cpo_save
--- /dev/null
+++ b/lib/vimfiles/ftplugin/ada.vim
@@ -1,0 +1,190 @@
+"------------------------------------------------------------------------------
+"  Description: Perform Ada specific completion & tagging.
+"     Language: Ada (2005)
+"	   $Id: ada.vim,v 1.3 2007/05/05 17:17:45 vimboss Exp $
+"   Maintainer: Martin Krischik
+"		Neil Bird <neil@fnxweb.com>
+"      $Author: vimboss $
+"	 $Date: 2007/05/05 17:17:45 $
+"      Version: 4.2
+"    $Revision: 1.3 $
+"     $HeadURL: https://svn.sourceforge.net/svnroot/gnuada/trunk/tools/vim/ftplugin/ada.vim $
+"      History: 24.05.2006 MK Unified Headers
+"		26.05.2006 MK ' should not be in iskeyword.
+"		16.07.2006 MK Ada-Mode as vim-ball
+"		02.10.2006 MK Better folding.
+"		15.10.2006 MK Bram's suggestion for runtime integration
+"               05.11.2006 MK Bram suggested not to use include protection for
+"                             autoload
+"		05.11.2006 MK Bram suggested to save on spaces
+"    Help Page: ft-ada-plugin
+"------------------------------------------------------------------------------
+" Provides mapping overrides for tag jumping that figure out the current
+" Ada object and tag jump to that, not the 'simple' vim word.
+" Similarly allows <Ctrl-N> matching of full-length ada entities from tags.
+"------------------------------------------------------------------------------
+
+" Only do this when not done yet for this buffer
+if exists ("b:did_ftplugin") || version < 700
+   finish
+endif
+
+" Don't load another plugin for this buffer
+let b:did_ftplugin = 38
+
+"
+" Temporarily set cpoptions to ensure the script loads OK
+"
+let s:cpoptions = &cpoptions
+set cpoptions-=C
+
+" Section: Comments {{{1
+"
+setlocal comments=O:--,:--\ \
+setlocal commentstring=--\ \ %s
+setlocal complete=.,w,b,u,t,i
+
+" Section: Tagging {{{1
+"
+if exists ("g:ada_extended_tagging")
+   " Make local tag mappings for this buffer (if not already set)
+   if g:ada_extended_tagging == 'jump'
+      if mapcheck('<C-]>','n') == ''
+	 nnoremap <unique> <buffer> <C-]>    :call ada#Jump_Tag ('', 'tjump')<cr>
+      endif
+      if mapcheck('g<C-]>','n') == ''
+	 nnoremap <unique> <buffer> g<C-]>   :call ada#Jump_Tag ('','stjump')<cr>
+      endif
+   elseif g:ada_extended_tagging == 'list'
+      if mapcheck('<C-]>','n') == ''
+	 nnoremap <unique> <buffer> <C-]>    :call ada#List_Tag ()<cr>
+      endif
+      if mapcheck('g<C-]>','n') == ''
+	 nnoremap <unique> <buffer> g<C-]>   :call ada#List_Tag ()<cr>
+      endif
+   endif
+endif
+
+" Section: Completion {{{1
+"
+setlocal completefunc=ada#User_Complete
+setlocal omnifunc=adacomplete#Complete
+
+if exists ("g:ada_extended_completion")
+   if mapcheck ('<C-N>','i') == ''
+      inoremap <unique> <buffer> <C-N> <C-R>=ada#Completion("\<lt>C-N>")<cr>
+   endif
+   if mapcheck ('<C-P>','i') == ''
+      inoremap <unique> <buffer> <C-P> <C-R>=ada#Completion("\<lt>C-P>")<cr>
+   endif
+   if mapcheck ('<C-X><C-]>','i') == ''
+      inoremap <unique> <buffer> <C-X><C-]> <C-R>=<SID>ada#Completion("\<lt>C-X>\<lt>C-]>")<cr>
+   endif
+   if mapcheck ('<bs>','i') == ''
+      inoremap <silent> <unique> <buffer> <bs> <C-R>=ada#Insert_Backspace ()<cr>
+   endif
+endif
+
+" Section: Matchit {{{1
+"
+" Only do this when not done yet for this buffer & matchit is used
+"
+if !exists ("b:match_words")  &&
+  \ exists ("loaded_matchit")
+   "
+   " The following lines enable the macros/matchit.vim plugin for
+   " Ada-specific extended matching with the % key.
+   "
+   let s:notend      = '\%(\<end\s\+\)\@<!'
+   let b:match_words =
+      \ s:notend . '\<if\>:\<elsif\>:\<else\>:\<end\>\s\+\<if\>,' .
+      \ s:notend . '\<case\>:\<when\>:\<end\>\s\+\<case\>,' .
+      \ '\%(\<while\>.*\|\<for\>.*\|'.s:notend.'\)\<loop\>:\<end\>\s\+\<loop\>,' .
+      \ '\%(\<do\>\|\<begin\>\):\<exception\>:\<end\>\s*\%($\|[;A-Z]\),' .
+      \ s:notend . '\<record\>:\<end\>\s\+\<record\>'
+endif
+
+" Section: Compiler {{{1
+"
+if ! exists("current_compiler")			||
+   \ current_compiler != g:ada_default_compiler
+   execute "compiler " . g:ada_default_compiler
+endif
+
+" Section: Folding {{{1
+"
+if exists("g:ada_folding")
+   if g:ada_folding[0] == 'i'
+      setlocal foldmethod=indent
+      setlocal foldignore=--
+      setlocal foldnestmax=5
+   elseif g:ada_folding[0] == 'g'
+      setlocal foldmethod=expr
+      setlocal foldexpr=ada#Pretty_Print_Folding(v:lnum)
+   elseif g:ada_folding[0] == 's'
+      setlocal foldmethod=syntax
+   endif
+   setlocal tabstop=8
+   setlocal softtabstop=3
+   setlocal shiftwidth=3
+endif
+
+" Section: Abbrev {{{1
+"
+if exists("g:ada_abbrev")
+   iabbrev ret	return
+   iabbrev proc procedure
+   iabbrev pack package
+   iabbrev func function
+endif
+
+" Section: Commands, Mapping, Menus {{{1
+"
+call ada#Map_Popup (
+   \ 'Tag.List',
+   \  'l',
+   \ 'call ada#List_Tag ()')
+call ada#Map_Popup (
+   \'Tag.Jump',
+   \'j',
+   \'call ada#Jump_Tag ()')
+call ada#Map_Menu (
+   \'Tag.Create File',
+   \':AdaTagFile',
+   \'call ada#Create_Tags (''file'')')
+call ada#Map_Menu (
+   \'Tag.Create Dir',
+   \':AdaTagDir',
+   \'call ada#Create_Tags (''dir'')')
+
+call ada#Map_Menu (
+   \'Highlight.Toggle Space Errors',
+   \ ':AdaSpaces',
+   \'call ada#Switch_Syntax_Option (''space_errors'')')
+call ada#Map_Menu (
+   \'Highlight.Toggle Lines Errors',
+   \ ':AdaLines',
+   \'call ada#Switch_Syntax_Option (''line_errors'')')
+call ada#Map_Menu (
+   \'Highlight.Toggle Rainbow Color',
+   \ ':AdaRainbow',
+   \'call ada#Switch_Syntax_Option (''rainbow_color'')')
+call ada#Map_Menu (
+   \'Highlight.Toggle Standard Types',
+   \ ':AdaTypes',
+   \'call ada#Switch_Syntax_Option (''standard_types'')')
+
+" 1}}}
+" Reset cpoptions
+let &cpoptions = s:cpoptions
+unlet s:cpoptions
+
+finish " 1}}}
+
+"------------------------------------------------------------------------------
+"   Copyright (C) 2006	Martin Krischik
+"
+"   Vim is Charityware - see ":help license" or uganda.txt for licence details.
+"------------------------------------------------------------------------------
+" vim: textwidth=78 nowrap tabstop=8 shiftwidth=3 softtabstop=3 noexpandtab
+" vim: foldmethod=marker
--- /dev/null
+++ b/lib/vimfiles/ftplugin/alsaconf.vim
@@ -1,0 +1,13 @@
+" Vim filetype plugin file
+" Language:         alsaconf(8) configuration file
+" Maintainer:       Nikolai Weibull <now@bitwi.se>
+" Latest Revision:  2006-04-19
+
+if exists("b:did_ftplugin")
+  finish
+endif
+let b:did_ftplugin = 1
+
+let b:undo_ftplugin = "setl com< cms< fo<"
+
+setlocal comments=:# commentstring=#\ %s formatoptions-=t formatoptions+=croql
--- /dev/null
+++ b/lib/vimfiles/ftplugin/ant.vim
@@ -1,0 +1,43 @@
+" Vim filetype plugin file
+" Language:	ant
+" Maintainer:	Dan Sharp <dwsharp at hotmail dot com>
+" Last Changed: 2003 Sep 29
+" URL:		http://mywebpage.netscape.com/sharppeople/vim/ftplugin
+
+if exists("b:did_ftplugin") | finish | endif
+
+" Make sure the continuation lines below do not cause problems in
+" compatibility mode.
+let s:save_cpo = &cpo
+set cpo-=C
+
+" Define some defaults in case the included ftplugins don't set them.
+let s:undo_ftplugin = ""
+let s:browsefilter = "XML Files (*.xml)\t*.xml\n" .
+	    \	     "All Files (*.*)\t*.*\n"
+
+runtime! ftplugin/xml.vim ftplugin/xml_*.vim ftplugin/xml/*.vim
+let b:did_ftplugin = 1
+
+" Override our defaults if these were set by an included ftplugin.
+if exists("b:undo_ftplugin")
+    let s:undo_ftplugin = b:undo_ftplugin
+endif
+if exists("b:browsefilter")
+    let s:browsefilter = b:browsefilter
+endif
+
+" Change the :browse e filter to primarily show Ant-related files.
+if has("gui_win32")
+    let b:browsefilter = "Build Files (build.xml)\tbuild.xml\n" .
+		\	 "Java Files (*.java)\t*.java\n" .
+		\	 "Properties Files (*.prop*)\t*.prop*\n" .
+		\	 "Manifest Files (*.mf)\t*.mf\n" .
+		\	 s:browsefilter
+endif
+
+" Undo the stuff we changed.
+let b:undo_ftplugin = "unlet! b:browsefilter | " . s:undo_ftplugin
+
+" Restore the saved compatibility options.
+let &cpo = s:save_cpo
--- /dev/null
+++ b/lib/vimfiles/ftplugin/arch.vim
@@ -1,0 +1,13 @@
+" Vim filetype plugin file
+" Language:         GNU Arch inventory file
+" Maintainer:       Nikolai Weibull <now@bitwi.se>
+" Latest Revision:  2006-04-19
+
+if exists("b:did_ftplugin")
+  finish
+endif
+let b:did_ftplugin = 1
+
+let b:undo_ftplugin = "setl com< cms< fo<"
+
+setlocal comments=:# commentstring=#\ %s formatoptions-=t formatoptions+=croql
--- /dev/null
+++ b/lib/vimfiles/ftplugin/art.vim
@@ -1,0 +1,16 @@
+" Vim filetype plugin
+" Language:      ART-IM and ART*Enterprise
+" Maintainer:    Dorai Sitaram <ds26@gte.com>
+" URL:		 http://www.ccs.neu.edu/~dorai/vimplugins/vimplugins.html
+" Last Change:   Apr 2, 2003
+
+" Only do this when not done yet for this buffer
+if exists("b:did_ftplugin")
+  finish
+endif
+
+run ftplugin/lisp.vim
+
+setl lw-=if
+setl lw+=def-art-fun,deffacts,defglobal,defrule,defschema,
+      \for,schema,while
--- /dev/null
+++ b/lib/vimfiles/ftplugin/aspvbs.vim
@@ -1,0 +1,59 @@
+" Vim filetype plugin file
+" Language:	aspvbs
+" Maintainer:	Dan Sharp <dwsharp at hotmail dot com>
+" Last Changed: 2004 Jun 28
+" URL:		http://mywebpage.netscape.com/sharppeople/vim/ftplugin
+
+if exists("b:did_ftplugin") | finish | endif
+
+" Make sure the continuation lines below do not cause problems in
+" compatibility mode.
+let s:save_cpo = &cpo
+set cpo-=C
+
+" Define some defaults in case the included ftplugins don't set them.
+let s:undo_ftplugin = ""
+let s:browsefilter = "HTML Files (*.html, *.htm)\t*.htm*\n" .
+	    \	     "All Files (*.*)\t*.*\n"
+let s:match_words = ""
+
+runtime! ftplugin/html.vim ftplugin/html_*.vim ftplugin/html/*.vim
+let b:did_ftplugin = 1
+
+" Override our defaults if these were set by an included ftplugin.
+if exists("b:undo_ftplugin")
+    let s:undo_ftplugin = b:undo_ftplugin
+endif
+if exists("b:browsefilter")
+    let s:browsefilter = b:browsefilter
+endif
+if exists("b:match_words")
+    let s:match_words = b:match_words
+endif
+
+" ASP:  Active Server Pages (with Visual Basic Script)
+" thanks to Gontran BAERTS
+if exists("loaded_matchit")
+  let s:notend = '\%(\<end\s\+\)\@<!'
+  let b:match_ignorecase = 1
+  let b:match_words =
+  \ s:notend . '\<if\>\%(.\{-}then\s\+\w\)\@!:\<elseif\>:^\s*\<else\>:\<end\s\+\<if\>,' .
+  \ s:notend . '\<select\s\+case\>:\<case\>:\<case\s\+else\>:\<end\s\+select\>,' .
+  \ '^\s*\<sub\>:\<end\s\+sub\>,' .
+  \ '^\s*\<function\>:\<end\s\+function\>,' .
+  \ '\<class\>:\<end\s\+class\>,' .
+  \ '^\s*\<do\>:\<loop\>,' .
+  \ '^\s*\<for\>:\<next\>,' .
+  \ '\<while\>:\<wend\>,' .
+  \ s:match_words
+endif
+
+" Change the :browse e filter to primarily show ASP-related files.
+if has("gui_win32")
+    let  b:browsefilter="ASP Files (*.asp)\t*.asp\n" . s:browsefilter
+endif
+
+let b:undo_ftplugin = "unlet! b:match_words b:match_ignorecase b:browsefilter | " . s:undo_ftplugin
+
+" Restore the saved compatibility options.
+let &cpo = s:save_cpo
--- /dev/null
+++ b/lib/vimfiles/ftplugin/automake.vim
@@ -1,0 +1,10 @@
+" Vim filetype plugin file
+" Language:         Automake
+" Maintainer:       Nikolai Weibull <now@bitwi.se>
+" Latest Revision:  2006-04-19
+
+if exists("b:did_ftplugin")
+  finish
+endif
+
+runtime! ftplugin/make.vim ftplugin/make_*.vim ftplugin/make/*.vim
--- /dev/null
+++ b/lib/vimfiles/ftplugin/bdf.vim
@@ -1,0 +1,14 @@
+" Vim filetype plugin file
+" Language:         BDF font definition
+" Maintainer:       Nikolai Weibull <now@bitwi.se>
+" Latest Revision:  2006-04-19
+
+if exists("b:did_ftplugin")
+  finish
+endif
+let b:did_ftplugin = 1
+
+let b:undo_ftplugin = "setl com< cms< fo<"
+
+setlocal comments=b:COMMENT commentstring=COMMENT\ %s
+setlocal formatoptions-=t formatoptions+=croql
--- /dev/null
+++ b/lib/vimfiles/ftplugin/bst.vim
@@ -1,0 +1,15 @@
+" Vim filetype plugin file
+" Language:	bst
+" Author:	Tim Pope <vimNOSPAM@tpope.info>
+" $Id: bst.vim,v 1.1 2007/05/05 17:37:57 vimboss Exp $
+
+if exists("b:did_ftplugin")
+    finish
+endif
+let b:did_ftplugin = 1
+
+setlocal commentstring=%\ %s
+setlocal comments=:%
+setlocal fo-=t fo+=croql
+
+let b:undo_ftplugin = "setlocal com< cms< fo<"
--- /dev/null
+++ b/lib/vimfiles/ftplugin/btm.vim
@@ -1,0 +1,12 @@
+" Vim filetype plugin file
+" Language:	BTM
+" Maintainer:	Bram Moolenaar <Bram@vim.org>
+" Last Change:	2004 Jul 06
+
+" Only do this when not done yet for this buffer
+if exists("b:did_ftplugin")
+  finish
+endif
+
+" Behaves just like dosbatch
+runtime! ftplugin/dosbatch.vim ftplugin/dosbatch_*.vim ftplugin/dosbatch/*.vim
--- /dev/null
+++ b/lib/vimfiles/ftplugin/c.vim
@@ -1,0 +1,59 @@
+" Vim filetype plugin file
+" Language:	C
+" Maintainer:	Bram Moolenaar <Bram@vim.org>
+" Last Change:	2005 Sep 01
+
+" Only do this when not done yet for this buffer
+if exists("b:did_ftplugin")
+  finish
+endif
+
+" Don't load another plugin for this buffer
+let b:did_ftplugin = 1
+
+" Using line continuation here.
+let s:cpo_save = &cpo
+set cpo-=C
+
+let b:undo_ftplugin = "setl fo< com< ofu< | if has('vms') | setl isk< | endif"
+
+" Set 'formatoptions' to break comment lines but not other lines,
+" and insert the comment leader when hitting <CR> or using "o".
+setlocal fo-=t fo+=croql
+
+" Set completion with CTRL-X CTRL-O to autoloaded function.
+if exists('&ofu')
+  setlocal ofu=ccomplete#Complete
+endif
+
+" Set 'comments' to format dashed lists in comments.
+setlocal comments=sO:*\ -,mO:*\ \ ,exO:*/,s1:/*,mb:*,ex:*/,://
+
+" In VMS C keywords contain '$' characters.
+if has("vms")
+  setlocal iskeyword+=$
+endif
+
+" Win32 can filter files in the browse dialog
+if has("gui_win32") && !exists("b:browsefilter")
+  if &ft == "cpp"
+    let b:browsefilter = "C++ Source Files (*.cpp *.c++)\t*.cpp;*.c++\n" .
+	  \ "C Header Files (*.h)\t*.h\n" .
+	  \ "C Source Files (*.c)\t*.c\n" .
+	  \ "All Files (*.*)\t*.*\n"
+  elseif &ft == "ch"
+    let b:browsefilter = "Ch Source Files (*.ch *.chf)\t*.ch;*.chf\n" .
+	  \ "C Header Files (*.h)\t*.h\n" .
+	  \ "C Source Files (*.c)\t*.c\n" .
+	  \ "All Files (*.*)\t*.*\n"
+  else
+    let b:browsefilter = "C Source Files (*.c)\t*.c\n" .
+	  \ "C Header Files (*.h)\t*.h\n" .
+	  \ "Ch Source Files (*.ch *.chf)\t*.ch;*.chf\n" .
+	  \ "C++ Source Files (*.cpp *.c++)\t*.cpp;*.c++\n" .
+	  \ "All Files (*.*)\t*.*\n"
+  endif
+endif
+
+let &cpo = s:cpo_save
+unlet s:cpo_save
--- /dev/null
+++ b/lib/vimfiles/ftplugin/calendar.vim
@@ -1,0 +1,14 @@
+" Vim filetype plugin file
+" Language:         calendar(1) input file
+" Maintainer:       Nikolai Weibull <now@bitwi.se>
+" Latest Revision:  2006-04-19
+
+if exists("b:did_ftplugin")
+  finish
+endif
+let b:did_ftplugin = 1
+
+let b:undo_ftplugin = "setl com< cms< inc< fo<"
+
+setlocal comments=s1:/*,mb:*,ex:*/ commentstring& include&
+setlocal formatoptions-=t formatoptions+=croql
--- /dev/null
+++ b/lib/vimfiles/ftplugin/ch.vim
@@ -1,0 +1,17 @@
+" Vim filetype plugin file
+" Language:     Ch
+" Maintainer:   SoftIntegration, Inc. <info@softintegration.com>
+" URL:		http://www.softintegration.com/download/vim/ftplugin/ch.vim
+" Last change:	2004 May 16
+"		Created based on cpp.vim
+"
+" Ch is a C/C++ interpreter with many high level extensions
+"
+
+" Only do this when not done yet for this buffer
+if exists("b:did_ftplugin")
+  finish
+endif
+
+" Behaves just like C
+runtime! ftplugin/c.vim ftplugin/c_*.vim ftplugin/c/*.vim
--- /dev/null
+++ b/lib/vimfiles/ftplugin/changelog.vim
@@ -1,0 +1,259 @@
+" Vim filetype plugin file
+" Language:         generic Changelog file
+" Maintainer:       Nikolai Weibull <now@bitwi.se>
+" Latest Revision:  2007-05-06
+" Variables:
+"   g:changelog_timeformat (deprecated: use g:changelog_dateformat instead) -
+"       description: the timeformat used in ChangeLog entries.
+"       default: "%Y-%m-%d".
+"   g:changelog_dateformat -
+"       description: the format sent to strftime() to generate a date string.
+"       default: "%Y-%m-%d".
+"   g:changelog_username -
+"       description: the username to use in ChangeLog entries
+"       default: try to deduce it from environment variables and system files.
+" Local Mappings:
+"   <Leader>o -
+"       adds a new changelog entry for the current user for the current date.
+" Global Mappings:
+"   <Leader>o -
+"       switches to the ChangeLog buffer opened for the current directory, or
+"       opens it in a new buffer if it exists in the current directory.  Then
+"       it does the same as the local <Leader>o described above.
+" Notes:
+"   run 'runtime ftplugin/changelog.vim' to enable the global mapping for
+"   changelog files.
+" TODO:
+"  should we perhaps open the ChangeLog file even if it doesn't exist already?
+"  Problem is that you might end up with ChangeLog files all over the place.
+
+" If 'filetype' isn't "changelog", we must have been to add ChangeLog opener
+if &filetype == 'changelog'
+  if exists('b:did_ftplugin')
+    finish
+  endif
+  let b:did_ftplugin = 1
+
+  let s:cpo_save = &cpo
+  set cpo&vim
+
+  " Set up the format used for dates.
+  if !exists('g:changelog_dateformat')
+    if exists('g:changelog_timeformat')
+      let g:changelog_dateformat = g:changelog_timeformat
+    else
+      let g:changelog_dateformat = "%Y-%m-%d"
+    endif
+  endif
+
+  " Try to figure out a reasonable username of the form:
+  "   Full Name <user@host>.
+  if !exists('g:changelog_username')
+    if exists('$EMAIL') && $EMAIL != ''
+      let g:changelog_username = $EMAIL
+    elseif exists('$EMAIL_ADDRESS') && $EMAIL_ADDRESS != ''
+      " This is some Debian junk if I remember correctly.
+      let g:changelog_username = $EMAIL_ADDRESS
+    else
+      " Get the users login name.
+      let login = system('whoami')
+      if v:shell_error
+        let login = 'unknown'
+      else
+        let newline = stridx(login, "\n")
+        if newline != -1
+          let login = strpart(login, 0, newline)
+        endif
+      endif
+
+      " Try to get the full name from gecos field in /etc/passwd.
+      if filereadable('/etc/passwd')
+        for line in readfile('/etc/passwd')
+          if line =~ '^' . login
+            let name = substitute(line,'^\%([^:]*:\)\{4}\([^:]*\):.*$','\1','')
+            " Only keep stuff before the first comma.
+            let comma = stridx(name, ',')
+            if comma != -1
+              let name = strpart(name, 0, comma)
+            endif
+            " And substitute & in the real name with the login of our user.
+            let amp = stridx(name, '&')
+            if amp != -1
+              let name = strpart(name, 0, amp) . toupper(login[0]) .
+                       \ strpart(login, 1) . strpart(name, amp + 1)
+            endif
+          endif
+        endfor
+      endif
+
+      " If we haven't found a name, try to gather it from other places.
+      if !exists('name')
+        " Maybe the environment has something of interest.
+        if exists("$NAME")
+          let name = $NAME
+        else
+          " No? well, use the login name and capitalize first
+          " character.
+          let name = toupper(login[0]) . strpart(login, 1)
+        endif
+      endif
+
+      " Get our hostname.
+      let hostname = system('hostname')
+      if v:shell_error
+        let hostname = 'localhost'
+      else
+        let newline = stridx(hostname, "\n")
+        if newline != -1
+          let hostname = strpart(hostname, 0, newline)
+        endif
+      endif
+
+      " And finally set the username.
+      let g:changelog_username = name . '  <' . login . '@' . hostname . '>'
+    endif
+  endif
+
+  " Format used for new date entries.
+  if !exists('g:changelog_new_date_format')
+    let g:changelog_new_date_format = "%d  %u\n\n\t* %c\n\n"
+  endif
+
+  " Format used for new entries to current date entry.
+  if !exists('g:changelog_new_entry_format')
+    let g:changelog_new_entry_format = "\t* %c"
+  endif
+
+  " Regular expression used to find a given date entry.
+  if !exists('g:changelog_date_entry_search')
+    let g:changelog_date_entry_search = '^\s*%d\_s*%u'
+  endif
+
+  " Regular expression used to find the end of a date entry
+  if !exists('g:changelog_date_end_entry_search')
+    let g:changelog_date_entry_search = '^\s*$'
+  endif
+
+
+  " Substitutes specific items in new date-entry formats and search strings.
+  " Can be done with substitute of course, but unclean, and need \@! then.
+  function! s:substitute_items(str, date, user)
+    let str = a:str
+    let middles = {'%': '%', 'd': a:date, 'u': a:user, 'c': '{cursor}'}
+    let i = stridx(str, '%')
+    while i != -1
+      let inc = 0
+      if has_key(middles, str[i + 1])
+        let mid = middles[str[i + 1]]
+        let str = strpart(str, 0, i) . mid . strpart(str, i + 2)
+        let inc = strlen(mid)
+      endif
+      let i = stridx(str, '%', i + 1 + inc)
+    endwhile
+    return str
+  endfunction
+
+  " Position the cursor once we've done all the funky substitution.
+  function! s:position_cursor()
+    if search('{cursor}') > 0
+      let lnum = line('.')
+      let line = getline(lnum)
+      let cursor = stridx(line, '{cursor}')
+      call setline(lnum, substitute(line, '{cursor}', '', ''))
+    endif
+    startinsert!
+  endfunction
+
+  " Internal function to create a new entry in the ChangeLog.
+  function! s:new_changelog_entry()
+    " Deal with 'paste' option.
+    let save_paste = &paste
+    let &paste = 1
+    call cursor(1, 1)
+    " Look for an entry for today by our user.
+    let date = strftime(g:changelog_dateformat)
+    let search = s:substitute_items(g:changelog_date_entry_search, date,
+                                  \ g:changelog_username)
+    if search(search) > 0
+      " Ok, now we look for the end of the date entry, and add an entry.
+      call cursor(nextnonblank(line('.') + 1), 1)
+      if search(g:changelog_date_end_entry_search, 'W') > 0
+        let p = line('.') - 1
+      else
+        let p = line('.')
+      endif
+      let ls = split(s:substitute_items(g:changelog_new_entry_format, '', ''),
+                   \ '\n')
+      call append(p, ls)
+      call cursor(p + 1, 1)
+    else
+      " Flag for removing empty lines at end of new ChangeLogs.
+      let remove_empty = line('$') == 1
+
+      " No entry today, so create a date-user header and insert an entry.
+      let todays_entry = s:substitute_items(g:changelog_new_date_format,
+                                          \ date, g:changelog_username)
+      " Make sure we have a cursor positioning.
+      if stridx(todays_entry, '{cursor}') == -1
+        let todays_entry = todays_entry . '{cursor}'
+      endif
+
+      " Now do the work.
+      call append(0, split(todays_entry, '\n'))
+      
+      " Remove empty lines at end of file.
+      if remove_empty
+        $-/^\s*$/-1,$delete
+      endif
+
+      " Reposition cursor once we're done.
+      call cursor(1, 1)
+    endif
+
+    call s:position_cursor()
+
+    " And reset 'paste' option
+    let &paste = save_paste
+  endfunction
+
+  if exists(":NewChangelogEntry") != 2
+    map <buffer> <silent> <Leader>o <Esc>:call <SID>new_changelog_entry()<CR>
+    command! -nargs=0 NewChangelogEntry call s:new_changelog_entry()
+  endif
+
+  let b:undo_ftplugin = "setl com< fo< et< ai<"
+
+  setlocal comments=
+  setlocal formatoptions+=t
+  setlocal noexpandtab
+  setlocal autoindent
+
+  if &textwidth == 0
+    setlocal textwidth=78
+    let b:undo_ftplugin .= " tw<"
+  endif
+
+  let &cpo = s:cpo_save
+  unlet s:cpo_save
+else
+  " Add the Changelog opening mapping
+  nmap <silent> <Leader>o :call <SID>open_changelog()<CR>
+
+  function! s:open_changelog()
+    if !filereadable('ChangeLog')
+      return
+    endif
+    let buf = bufnr('ChangeLog')
+    if buf != -1
+      if bufwinnr(buf) != -1
+        execute bufwinnr(buf) . 'wincmd w'
+      else
+        execute 'sbuffer' buf
+      endif
+    else
+      split ChangeLog
+    endif
+
+    call s:new_changelog_entry()
+  endfunction
+endif
--- /dev/null
+++ b/lib/vimfiles/ftplugin/cobol.vim
@@ -1,0 +1,266 @@
+" Vim filetype plugin file
+" Language:	cobol
+" Author:	Tim Pope <vimNOSPAM@tpope.info>
+" $Id: cobol.vim,v 1.1 2007/05/05 17:24:38 vimboss Exp $
+
+" Insert mode mappings: <C-T> <C-D> <Tab>
+" Normal mode mappings: < > << >> [[ ]] [] ][
+" Visual mode mappings: < >
+
+if exists("b:did_ftplugin")
+    finish
+endif
+let b:did_ftplugin = 1
+
+let s:cpo_save = &cpo
+set cpo&vim
+
+setlocal commentstring=\ \ \ \ \ \ *%s
+setlocal comments=:*
+setlocal fo+=croqlt
+setlocal expandtab
+setlocal textwidth=72
+
+" matchit support
+if exists("loaded_matchit")
+    let s:ordot = '\|\ze\.\%( \@=\|$\)'
+    let b:match_ignorecase=1
+    "let b:match_skip = 'getline(".") =~ "^.\\{6\\}[*/C]"'
+    let b:match_words=
+    \ '\$if\>:$else\>:\$endif\>,' .
+    \ '[$-]\@<!\<if\>:\<\%(then\|else\)\>:\<end-if\>'.s:ordot.',' .
+    \ '-\@<!\<perform\s\+\%(\d\+\s\+times\|until\|varying\|with\s\+test\)\>:\<end-perform\>'.s:ordot . ',' .
+    \ '-\@<!\<\%(search\|evaluate\)\>:\<\%(when\)\>:\<end-\%(search\|evaluate\)\>' .s:ordot . ',' .
+    \ '-\@<!\<\%(add\|compute\|divide\|multiply\|subtract\)\>\%(.*\(\%$\|\%(\n\%(\%(\s*\|.\{6\}\)[*/].*\n\)*\)\=\s*\%(not\s\+\)\=on\s\+size\s\+error\>\)\)\@=:\%(\<not\s\+\)\@<!\<\%(not\s\+\)\=on\s\+size\s\+error\>:\<end-\%(add\|compute\|divide\|multiply\|subtract\)\>' .s:ordot . ',' .
+    \ '-\@<!\<\%(string\|unstring\|accept\|display\|call\)\>\%(.*\(\%$\|\%(\n\%(\%(\s*\|.\{6\}\)[*/].*\n\)*\)\=\s*\%(not\s\+\)\=on\s\+\%(overflow\|exception\)\>\)\)\@=:\%(\<not\s\+\)\@<!\<\%(not\s\+\)\=on\s\+\%(overflow\|exception\)\>:\<end-\%(string\|unstring\|accept\|display\|call\)\>' .s:ordot . ',' .
+    \ '-\@<!\<\%(delete\|rewrite\|start\|write\|read\)\>\%(.*\(\%$\|\%(\n\%(\%(\s*\|.\{6\}\)[*/].*\n\)*\)\=\s*\%(invalid\s\+key\|at\s\+end\|no\s\+data\|at\s\+end-of-page\)\>\)\)\@=:\%(\<not\s\+\)\@<!\<\%(not\s\+\)\=\%(invalid\s\+key\|at\s\+end\|no\s\+data\|at\s\+end-of-page\)\>:\<end-\%(delete\|rewrite\|start\|write\|read\)\>' .s:ordot
+endif
+
+if has("gui_win32") && !exists("b:browsefilter")
+  let b:browsefilter = "COBOL Source Files (*.cbl, *.cob)\t*.cbl;*.cob;*.lib\n".
+		     \ "All Files (*.*)\t*.*\n"
+endif
+
+let b:undo_ftplugin = "setlocal com< cms< fo< et< tw<" .
+            \ " | unlet! b:browsefilter b:match_words b:match_ignorecase b:match_skip"
+if !exists("g:no_plugin_maps") && !exists("g:no_cobol_maps")
+    let b:undo_ftplugin = b:undo_ftplugin .
+            \ " | sil! exe 'nunmap <buffer> <'" .
+            \ " | sil! exe 'nunmap <buffer> >'" .
+            \ " | sil! exe 'nunmap <buffer> <<'" .
+            \ " | sil! exe 'nunmap <buffer> >>'" .
+            \ " | sil! exe 'vunmap <buffer> <'" .
+            \ " | sil! exe 'vunmap <buffer> >'" .
+            \ " | sil! exe 'iunmap <buffer> <C-D>'" .
+            \ " | sil! exe 'iunmap <buffer> <C-T>'" .
+            \ " | sil! exe 'iunmap <buffer> <Tab>'" .
+            \ " | sil! exe 'nunmap <buffer> <Plug>Traditional'" .
+            \ " | sil! exe 'nunmap <buffer> <Plug>Comment'" .
+            \ " | sil! exe 'nunmap <buffer> <Plug>DeComment'" .
+            \ " | sil! exe 'vunmap <buffer> <Plug>VisualTraditional'" .
+            \ " | sil! exe 'vunmap <buffer> <Plug>VisualComment'" .
+            \ " | sil! exe 'iunmap <buffer> <Plug>VisualDeComment'" .
+            \ " | sil! exe 'unmap  <buffer> [['" .
+            \ " | sil! exe 'unmap  <buffer> ]]'" .
+            \ " | sil! exe 'unmap  <buffer> []'" .
+            \ " | sil! exe 'unmap  <buffer> ]['"
+endif
+
+if !exists("g:no_plugin_maps") && !exists("g:no_cobol_maps")
+    if version >= 700
+        nnoremap <silent> <buffer> > :set opfunc=<SID>IncreaseFunc<CR>g@
+        nnoremap <silent> <buffer> < :set opfunc=<SID>DecreaseFunc<CR>g@
+    endif
+    nnoremap <silent> <buffer> >> :call CobolIndentBlock(1)<CR>
+    nnoremap <silent> <buffer> << :call CobolIndentBlock(-1)<CR>
+    vnoremap <silent> <buffer> > :call CobolIndentBlock(v:count1)<CR>
+    vnoremap <silent> <buffer> < :call CobolIndentBlock(-v:count1)<CR>
+    inoremap <silent> <buffer> <C-T> <C-R>=<SID>IncreaseIndent()<CR><C-R>=<SID>RestoreShiftwidth()<CR>
+    inoremap <silent> <buffer> <C-D> <C-R>=<SID>DecreaseIndent()<CR><C-R>=<SID>RestoreShiftwidth()<CR>
+    if !maparg("<Tab>","i")
+        inoremap <silent> <buffer> <Tab> <C-R>=<SID>Tab()<CR><C-R>=<SID>RestoreShiftwidth()<CR>
+    endif
+    noremap <silent> <buffer> [[ m':call search('\c^\%(\s*\<Bar>.\{6\}\s\+\)\zs[A-Za-z0-9-]\+\s\+\%(division\<Bar>section\)\s*\.','bW')<CR>
+    noremap <silent> <buffer> ]] m':call search('\c^\%(\s*\<Bar>.\{6\}\s\+\)\zs[A-Za-z0-9-]\+\s\+\%(division\<Bar>section\)\.','W')<CR>
+    noremap <silent> <buffer> [] m':call <SID>toend('b')<CR>
+    noremap <silent> <buffer> ][ m':call <SID>toend('')<CR>
+    " For EnhancedCommentify
+    noremap <silent> <buffer> <Plug>Traditional      :call <SID>Comment('t')<CR>
+    noremap <silent> <buffer> <Plug>Comment          :call <SID>Comment('c')<CR>
+    noremap <silent> <buffer> <Plug>DeComment        :call <SID>Comment('u')<CR>
+    noremap <silent> <buffer> <Plug>VisualTraditional :'<,'>call <SID>Comment('t')<CR>
+    noremap <silent> <buffer> <Plug>VisualComment     :'<,'>call <SID>Comment('c')<CR>
+    noremap <silent> <buffer> <Plug>VisualDeComment   :'<,'>call <SID>Comment('u')<CR>
+endif
+
+let &cpo = s:cpo_save
+unlet s:cpo_save
+
+if exists("g:did_cobol_ftplugin_functions")
+    finish
+endif
+let g:did_cobol_ftplugin_functions = 1
+
+function! s:repeat(str,count)
+    let i = 0
+    let ret = ""
+    while i < a:count
+        let ret = ret . a:str
+        let i = i + 1
+    endwhile
+    return ret
+endfunction
+
+function! s:increase(...)
+    let lnum = '.'
+    let sw = &shiftwidth
+    let i = a:0 ? a:1 : indent(lnum)
+    if i >= 11
+        return sw - (i - 11) % sw
+    elseif i >= 7
+        return 11-i
+    elseif i == 6
+        return 1
+    else
+        return 6-i
+    endif
+endfunction
+
+function! s:decrease(...)
+    let lnum = '.'
+    let sw = &shiftwidth
+    let i = indent(a:0 ? a:1 : lnum)
+    if i >= 11 + sw
+        return 1 + (i + 12) % sw
+    elseif i > 11
+        return i-11
+    elseif i > 7
+        return i-7
+    elseif i == 7
+        return 1
+    else
+        return i
+    endif
+endfunction
+
+function! CobolIndentBlock(shift)
+    let head = strpart(getline('.'),0,7)
+    let tail = strpart(getline('.'),7)
+    let indent = match(tail,'[^ ]')
+    let sw = &shiftwidth
+    let shift = a:shift
+    if shift > 0
+        if indent < 4
+            let tail = s:repeat(" ",4-indent).tail
+            let shift = shift - 1
+        endif
+        let tail = s:repeat(" ",shift*sw).tail
+        let shift = 0
+    elseif shift < 0
+        if (indent-4) > -shift * sw
+            let tail = strpart(tail,-shift * sw)
+        elseif (indent-4) > (-shift-1) * sw
+            let tail = strpart(tail,indent - 4)
+        else
+            let tail = strpart(tail,indent)
+        endif
+    endif
+    call setline('.',head.tail)
+endfunction
+
+function! s:IncreaseFunc(type)
+    '[,']call CobolIndentBlock(1)
+endfunction
+
+function! s:DecreaseFunc(type)
+    '[,']call CobolIndentBlock(-1)
+endfunction
+
+function! s:IncreaseIndent()
+    let c = "\<C-T>"
+    if exists("*InsertCtrlTWrapper")
+        let key = InsertCtrlTWrapper()
+        if key != c
+            return key
+        endif
+    endif
+    let interval = s:increase()
+    let b:cobol_shiftwidth = &shiftwidth
+    let &shiftwidth = 1
+    let lastchar = strpart(getline('.'),col('.')-2,1)
+    if lastchar == '0' || lastchar == '^'
+        return "\<BS>".lastchar.c
+    else
+        return s:repeat(c,interval)
+    endif
+endfunction
+
+function! s:DecreaseIndent()
+    let c = "\<C-D>"
+    if exists("*InsertCtrlDWrapper")
+        " I hack Ctrl-D to delete when not at the end of the line.
+        let key = InsertCtrlDWrapper()
+        if key != c
+            return key
+        endif
+    endif
+    let interval = s:decrease()
+    let b:cobol_shiftwidth = &shiftwidth
+    let &shiftwidth = 1
+    return s:repeat(c,interval)
+endfunction
+
+function! s:RestoreShiftwidth()
+    if exists("b:cobol_shiftwidth")
+        let &shiftwidth=b:cobol_shiftwidth
+        unlet b:cobol_shiftwidth
+    endif
+    return ""
+endfunction
+
+function! s:Tab()
+    if (strpart(getline('.'),0,col('.')-1) =~ '^\s*$' && &sta)
+        return s:IncreaseIndent()
+    elseif &sts == &sw && &sts != 8 && &et
+        return s:repeat(" ",s:increase(col('.')-1))
+    else
+        return "\<Tab>"
+    endif
+endfunction
+
+function! s:Comment(arg)
+    " For EnhancedCommentify
+    let line = getline('.')
+    if (line =~ '^.\{6\}[*/C]' || a:arg == 'c') && a:arg != 'u'
+        let line = substitute(line,'^.\{6\}\zs.',' ','')
+    else
+        let line = substitute(line,'^.\{6\}\zs.','*','')
+    endif
+    call setline('.',line)
+endfunction
+
+function! s:toend(direction)
+    let ignore = '^\(\s*\|.\{6\}\)\%([*/]\|\s*$\)'
+    let keep = line('.')
+    keepjumps +
+    while line('.') < line('$') && getline('.') =~ ignore
+        keepjumps +
+    endwhile
+    let res = search('\c^\%(\s*\|.\{6\}\s\+\)\zs[A-Za-z0-9-]\+\s\+\%(division\|section\)\s*\.',a:direction.'W')
+    if a:direction != 'b' && !res
+        let res = line('$')
+        keepjumps $
+    elseif res
+        keepjumps -
+    endif
+    if res
+        while line('.') > 1 && getline('.') =~ ignore
+            keepjumps -
+        endwhile
+        if line('.') == 1 && getline('.') =~ ignore
+            exe "keepjumps ".keep
+        endif
+    else
+        exe "keepjumps ".keep
+    endif
+endfunction
--- /dev/null
+++ b/lib/vimfiles/ftplugin/conf.vim
@@ -1,0 +1,13 @@
+" Vim filetype plugin file
+" Language:         generic configuration file
+" Maintainer:       Nikolai Weibull <now@bitwi.se>
+" Latest Revision:  2006-04-19
+
+if exists("b:did_ftplugin")
+  finish
+endif
+let b:did_ftplugin = 1
+
+let b:undo_ftplugin = "setl com< cms< fo<"
+
+setlocal comments=:# commentstring=#\ %s formatoptions-=t formatoptions+=croql
--- /dev/null
+++ b/lib/vimfiles/ftplugin/config.vim
@@ -1,0 +1,41 @@
+" Vim filetype plugin file
+" Language:	config
+" Maintainer:	Dan Sharp <dwsharp at hotmail dot com>
+" Last Changed: 2004 Jul 08
+" URL:		http://mywebpage.netscape.com/sharppeople/vim/ftplugin
+
+if exists("b:did_ftplugin") | finish | endif
+
+" Make sure the continuation lines below do not cause problems in
+" compatibility mode.
+let s:save_cpo = &cpo
+set cpo-=C
+
+" Define some defaults in case the included ftplugins don't set them.
+let s:undo_ftplugin = ""
+let s:browsefilter = "Bourne Shell Files (*.sh)\t*.sh\n" .
+	    \	 "All Files (*.*)\t*.*\n"
+let s:match_words = ""
+
+runtime! ftplugin/sh.vim ftplugin/sh_*.vim ftplugin/sh/*.vim
+let b:did_ftplugin = 1
+
+" Override our defaults if these were set by an included ftplugin.
+if exists("b:undo_ftplugin")
+    let s:undo_ftplugin = b:undo_ftplugin
+endif
+if exists("b:browsefilter")
+    let s:browsefilter = b:browsefilter
+endif
+
+" Change the :browse e filter to primarily show configure-related files.
+if has("gui_win32")
+    let  b:browsefilter="Configure Scripts (configure.*, config.*)\tconfigure*;config.*\n" .
+		\	s:browsefilter
+endif
+
+" Undo the stuff we changed.
+let b:undo_ftplugin = "unlet! b:browsefilter | " . b:undo_ftplugin
+
+" Restore the saved compatibility options.
+let &cpo = s:save_cpo
--- /dev/null
+++ b/lib/vimfiles/ftplugin/context.vim
@@ -1,0 +1,36 @@
+" Vim filetype plugin file
+" Language:         ConTeXt typesetting engine
+" Maintainer:       Nikolai Weibull <now@bitwi.se>
+" Latest Revision:  2006-04-19
+
+if exists("b:did_ftplugin")
+  finish
+endif
+let b:did_ftplugin = 1
+
+let s:cpo_save = &cpo
+set cpo&vim
+
+let b:undo_ftplugin = "setl com< cms< def< inc< sua< fo<"
+
+setlocal comments=b:%D,b:%C,b:%M,:% commentstring=%\ %s formatoptions+=tcroql
+
+let &l:define='\\\%([egx]\|char\|mathchar\|count\|dimen\|muskip\|skip\|toks\)\='
+        \ .     'def\|\\font\|\\\%(future\)\=let'
+        \ . '\|\\new\%(count\|dimen\|skip\|muskip\|box\|toks\|read\|write'
+        \ .     '\|fam\|insert\|if\)'
+
+let &l:include = '^\s*\%(input\|component\)'
+
+setlocal suffixesadd=.tex
+
+if exists("loaded_matchit")
+  let b:match_ignorecase = 0
+  let b:match_skip = 'r:\\\@<!\%(\\\\\)*%'
+  let b:match_words = '(:),\[:],{:},\\(:\\),\\\[:\\],' .
+        \ '\\start\(\a\+\):\\stop\1'
+endif " exists("loaded_matchit")
+
+
+let &cpo = s:cpo_save
+unlet s:cpo_save
--- /dev/null
+++ b/lib/vimfiles/ftplugin/cpp.vim
@@ -1,0 +1,12 @@
+" Vim filetype plugin file
+" Language:	C++
+" Maintainer:	Bram Moolenaar <Bram@vim.org>
+" Last Change:	2001 Jan 15
+
+" Only do this when not done yet for this buffer
+if exists("b:did_ftplugin")
+  finish
+endif
+
+" Behaves just like C
+runtime! ftplugin/c.vim ftplugin/c_*.vim ftplugin/c/*.vim
--- /dev/null
+++ b/lib/vimfiles/ftplugin/crm.vim
@@ -1,0 +1,13 @@
+" Vim filetype plugin file
+" Language:         CRM114
+" Maintainer:       Nikolai Weibull <now@bitwi.se>
+" Latest Revision:  2006-04-19
+
+if exists("b:did_ftplugin")
+  finish
+endif
+let b:did_ftplugin = 1
+
+let b:undo_ftplugin = "setl com< cms< fo<"
+
+setlocal comments=:# commentstring=#\ %s formatoptions-=t formatoptions+=croql
--- /dev/null
+++ b/lib/vimfiles/ftplugin/cs.vim
@@ -1,0 +1,24 @@
+" Vim filetype plugin file
+" Language:	C#
+" Maintainer:	Johannes Zellner <johannes@zellner.org>
+" Last Change:	Tue, 09 Mar 2004 14:09:33 CET
+
+" Only do this when not done yet for this buffer
+if exists("b:did_ftplugin")
+  finish
+endif
+
+" Don't load another plugin for this buffer
+let b:did_ftplugin = 1
+
+" Set 'formatoptions' to break comment lines but not other lines,
+" and insert the comment leader when hitting <CR> or using "o".
+setlocal fo-=t fo+=croql
+
+" Set 'comments' to format dashed lists in comments.
+setlocal comments=sO:*\ -,mO:*\ \ ,exO:*/,s1:/*,mb:*,ex:*/,:///,://
+
+if has("gui_win32") && !exists("b:browsefilter")
+    let b:browsefilter = "C# Source Files (*.cs)\t*.cs\n" .
+		       \ "All Files (*.*)\t*.*\n"
+endif
--- /dev/null
+++ b/lib/vimfiles/ftplugin/csc.vim
@@ -1,0 +1,26 @@
+" Vim filetype plugin file
+" Language:	csc
+" Maintainer:	Dan Sharp <dwsharp at hotmail dot com>
+" Last Changed: 2003 Sep 29
+" URL:		http://mywebpage.netscape.com/sharppeople/vim/ftplugin
+
+if exists("b:did_ftplugin") | finish | endif
+let b:did_ftplugin = 1
+
+" Make sure the continuation lines below do not cause problems in
+" compatibility mode.
+let s:save_cpo = &cpo
+set cpo-=C
+
+if exists("loaded_matchit")
+    let b:match_words=
+	\ '\<fix\>:\<endfix\>,' .
+	\ '\<if\>:\<else\%(if\)\=\>:\<endif\>,' .
+	\ '\<!loopondimensions\>\|\<!looponselected\>:\<!endloop\>'
+endif
+
+" Undo the stuff we changed.
+let b:undo_ftplugin = "unlet! b:match_words"
+
+" Restore the saved compatibility options.
+let &cpo = s:save_cpo
--- /dev/null
+++ b/lib/vimfiles/ftplugin/csh.vim
@@ -1,0 +1,47 @@
+" Vim filetype plugin file
+" Language:	csh
+" Maintainer:	Dan Sharp <dwsharp at hotmail dot com>
+" Last Changed: 2003 Sep 29
+" URL:		http://mywebpage.netscape.com/sharppeople/vim/ftplugin
+
+if exists("b:did_ftplugin") | finish | endif
+let b:did_ftplugin = 1
+
+" Make sure the continuation lines below do not cause problems in
+" compatibility mode.
+let s:save_cpo = &cpo
+set cpo-=C
+
+setlocal commentstring=#%s
+setlocal formatoptions-=t
+setlocal formatoptions+=crql
+
+" Csh:  thanks to Johannes Zellner
+" - Both foreach and end must appear alone on separate lines.
+" - The words else and endif must appear at the beginning of input lines;
+"   the if must appear alone on its input line or after an else.
+" - Each case label and the default label must appear at the start of a
+"   line.
+" - while and end must appear alone on their input lines.
+if exists("loaded_matchit")
+    let b:match_words =
+      \ '^\s*\<if\>.*(.*).*\<then\>:'.
+      \   '^\s*\<else\>\s\+\<if\>.*(.*).*\<then\>:^\s*\<else\>:'.
+      \   '^\s*\<endif\>,'.
+      \ '\%(^\s*\<foreach\>\s\+\S\+\|^s*\<while\>\).*(.*):'.
+      \   '\<break\>:\<continue\>:^\s*\<end\>,'.
+      \ '^\s*\<switch\>.*(.*):^\s*\<case\>\s\+:^\s*\<default\>:^\s*\<endsw\>'
+endif
+
+" Change the :browse e filter to primarily show csh-related files.
+if has("gui_win32")
+    let  b:browsefilter="csh Scripts (*.csh)\t*.csh\n" .
+		\	"All Files (*.*)\t*.*\n"
+endif
+
+" Undo the stuff we changed.
+let b:undo_ftplugin = "setlocal commentstring< formatoptions<" .
+		\     " | unlet! b:match_words b:browsefilter"
+
+" Restore the saved compatibility options.
+let &cpo = s:save_cpo
--- /dev/null
+++ b/lib/vimfiles/ftplugin/css.vim
@@ -1,0 +1,17 @@
+" Vim filetype plugin file
+" Language:         CSS
+" Maintainer:       Nikolai Weibull <now@bitwi.se>
+" Latest Revision:  2007-05-08
+
+if exists("b:did_ftplugin")
+  finish
+endif
+let b:did_ftplugin = 1
+
+let b:undo_ftplugin = "setl com< cms< inc< fo< ofu<"
+
+setlocal comments=s1:/*,mb:*,ex:*/ commentstring&
+setlocal formatoptions-=t formatoptions+=croql
+setlocal omnifunc=csscomplete#CompleteCSS
+
+let &l:include = '^\s*@import\s\+\%(url(\)\='
--- /dev/null
+++ b/lib/vimfiles/ftplugin/cvsrc.vim
@@ -1,0 +1,13 @@
+" Vim filetype plugin file
+" Language:         cvs(1) RC file
+" Maintainer:       Nikolai Weibull <now@bitwi.se>
+" Latest Revision:  2006-04-19
+
+if exists("b:did_ftplugin")
+  finish
+endif
+let b:did_ftplugin = 1
+
+let b:undo_ftplugin = "setl com< cms< fo<"
+
+setlocal comments= commentstring= formatoptions-=tcroql
--- /dev/null
+++ b/lib/vimfiles/ftplugin/debchangelog.vim
@@ -1,0 +1,268 @@
+" Vim filetype plugin file (GUI menu and folding)
+" Language:	Debian Changelog
+" Maintainer:	Michael Piefel <piefel@informatik.hu-berlin.de>
+"		Stefano Zacchiroli <zack@debian.org>
+" Last Change:	$LastChangedDate: 2006-08-24 23:41:26 +0200 (gio, 24 ago 2006) $
+" License:	GNU GPL, version 2.0 or later
+" URL:		http://svn.debian.org/wsvn/pkg-vim/trunk/runtime/ftplugin/debchangelog.vim?op=file&rev=0&sc=0
+
+if exists("b:did_ftplugin")
+  finish
+endif
+let b:did_ftplugin=1
+
+" {{{1 Local settings (do on every load)
+setlocal foldmethod=expr
+setlocal foldexpr=GetDebChangelogFold(v:lnum)
+setlocal foldtext=DebChangelogFoldText()
+
+" Debian changelogs are not supposed to have any other text width,
+" so the user cannot override this setting
+setlocal tw=78
+setlocal comments=f:* 
+
+" Clean unloading
+let b:undo_ftplugin = "setlocal tw< comments< foldmethod< foldexpr< foldtext<"
+" }}}1
+
+if exists("g:did_changelog_ftplugin")
+  finish
+endif
+
+" Don't load another plugin (this is global)
+let g:did_changelog_ftplugin = 1
+
+" {{{1 GUI menu
+
+" Helper functions returning various data.
+" Returns full name, either from $DEBFULLNAME or debianfullname.
+" TODO Is there a way to determine name from anywhere else?
+function <SID>FullName()
+    if exists("$DEBFULLNAME")
+	return $DEBFULLNAME
+    elseif exists("g:debianfullname")
+	return g:debianfullname
+    else
+	return "Your Name"
+    endif
+endfunction
+
+" Returns email address, from $DEBEMAIL, $EMAIL or debianemail.
+function <SID>Email()
+    if exists("$DEBEMAIL")
+	return $DEBEMAIL
+    elseif exists("$EMAIL")
+	return $EMAIL
+    elseif exists("g:debianemail")
+	return g:debianemail
+    else
+	return "your@email.address"
+    endif
+endfunction
+
+" Returns date in RFC822 format.
+function <SID>Date()
+    let savelang = v:lc_time
+    execute "language time C"
+    let dateandtime = strftime("%a, %d %b %Y %X %z")
+    execute "language time " . savelang
+    return dateandtime
+endfunction
+
+function <SID>WarnIfNotUnfinalised()
+    if match(getline("."), " -- [[:alpha:]][[:alnum:].]")!=-1
+	echohl WarningMsg
+	echo "The entry has not been unfinalised before editing."
+	echohl None
+	return 1
+    endif
+    return 0
+endfunction
+
+function <SID>Finalised()
+    let savelinenum = line(".")
+    normal 1G
+    call search("^ -- ")
+    if match(getline("."), " -- [[:alpha:]][[:alnum:].]")!=-1
+	let returnvalue = 1
+    else
+	let returnvalue = 0
+    endif
+    execute savelinenum
+    return returnvalue
+endfunction
+
+" These functions implement the menus
+function NewVersion()
+    " The new entry is unfinalised and shall be changed
+    amenu disable Changelog.New\ Version
+    amenu enable Changelog.Add\ Entry
+    amenu enable Changelog.Close\ Bug
+    amenu enable Changelog.Set\ Distribution
+    amenu enable Changelog.Set\ Urgency
+    amenu disable Changelog.Unfinalise
+    amenu enable Changelog.Finalise
+    call append(0, substitute(getline(1), '-\([[:digit:]]\+\))', '-$$\1)', ''))
+    call append(1, "")
+    call append(2, "")
+    call append(3, " -- ")
+    call append(4, "")
+    call Distribution("unstable")
+    call Urgency("low")
+    normal 1G
+    call search(")")
+    normal h
+    normal 
+    call setline(1, substitute(getline(1), '-\$\$', '-', ''))
+    normal zo
+    call AddEntry()
+endfunction
+
+function AddEntry()
+    normal 1G
+    call search("^ -- ")
+    normal kk
+    call append(".", "  * ")
+    normal jjj
+    let warn=<SID>WarnIfNotUnfinalised()
+    normal kk
+    if warn
+	echohl MoreMsg
+	call input("Hit ENTER")
+	echohl None
+    endif
+    startinsert!
+endfunction
+
+function CloseBug()
+    normal 1G
+    call search("^ -- ")
+    let warn=<SID>WarnIfNotUnfinalised()
+    normal kk
+    call append(".", "  *  (closes: #" . input("Bug number to close: ") . ")")
+    normal j^ll
+    startinsert
+endfunction
+
+function Distribution(dist)
+    call setline(1, substitute(getline(1), ") [[:lower:] ]*;", ") " . a:dist . ";", ""))
+endfunction
+
+function Urgency(urg)
+    call setline(1, substitute(getline(1), "urgency=.*$", "urgency=" . a:urg, ""))
+endfunction
+
+function <SID>UnfinaliseMenu()
+    " This means the entry shall be changed
+    amenu disable Changelog.New\ Version
+    amenu enable Changelog.Add\ Entry
+    amenu enable Changelog.Close\ Bug
+    amenu enable Changelog.Set\ Distribution
+    amenu enable Changelog.Set\ Urgency
+    amenu disable Changelog.Unfinalise
+    amenu enable Changelog.Finalise
+endfunction
+
+function Unfinalise()
+    call <SID>UnfinaliseMenu()
+    normal 1G
+    call search("^ -- ")
+    call setline(".", " -- ")
+endfunction
+
+function <SID>FinaliseMenu()
+    " This means the entry should not be changed anymore
+    amenu enable Changelog.New\ Version
+    amenu disable Changelog.Add\ Entry
+    amenu disable Changelog.Close\ Bug
+    amenu disable Changelog.Set\ Distribution
+    amenu disable Changelog.Set\ Urgency
+    amenu enable Changelog.Unfinalise
+    amenu disable Changelog.Finalise
+endfunction
+
+function Finalise()
+    call <SID>FinaliseMenu()
+    normal 1G
+    call search("^ -- ")
+    call setline(".", " -- " . <SID>FullName() . " <" . <SID>Email() . ">  " . <SID>Date())
+endfunction
+
+
+function <SID>MakeMenu()
+    amenu &Changelog.&New\ Version			:call NewVersion()<CR>
+    amenu Changelog.&Add\ Entry				:call AddEntry()<CR>
+    amenu Changelog.&Close\ Bug				:call CloseBug()<CR>
+    menu Changelog.-sep-				<nul>
+
+    amenu Changelog.Set\ &Distribution.&unstable	:call Distribution("unstable")<CR>
+    amenu Changelog.Set\ Distribution.&frozen		:call Distribution("frozen")<CR>
+    amenu Changelog.Set\ Distribution.&stable		:call Distribution("stable")<CR>
+    menu Changelog.Set\ Distribution.-sep-		<nul>
+    amenu Changelog.Set\ Distribution.frozen\ unstable	:call Distribution("frozen unstable")<CR>
+    amenu Changelog.Set\ Distribution.stable\ unstable	:call Distribution("stable unstable")<CR>
+    amenu Changelog.Set\ Distribution.stable\ frozen	:call Distribution("stable frozen")<CR>
+    amenu Changelog.Set\ Distribution.stable\ frozen\ unstable	:call Distribution("stable frozen unstable")<CR>
+
+    amenu Changelog.Set\ &Urgency.&low			:call Urgency("low")<CR>
+    amenu Changelog.Set\ Urgency.&medium		:call Urgency("medium")<CR>
+    amenu Changelog.Set\ Urgency.&high			:call Urgency("high")<CR>
+
+    menu Changelog.-sep-				<nul>
+    amenu Changelog.U&nfinalise				:call Unfinalise()<CR>
+    amenu Changelog.&Finalise				:call Finalise()<CR>
+
+    if <SID>Finalised()
+	call <SID>FinaliseMenu()
+    else
+	call <SID>UnfinaliseMenu()
+    endif
+endfunction
+
+augroup changelogMenu
+au BufEnter * if &filetype == "debchangelog" | call <SID>MakeMenu() | endif
+au BufLeave * if &filetype == "debchangelog" | aunmenu Changelog | endif
+augroup END
+
+" }}}
+" {{{1 folding
+
+" look for an author name in the [zonestart zoneend] lines searching backward
+function! s:getAuthor(zonestart, zoneend)
+  let linepos = a:zoneend
+  while linepos >= a:zonestart
+    let line = getline(linepos)
+    if line =~ '^ --'
+      return substitute(line, '^ --\s*\([^<]\+\)\s*.*', '\1', '')
+    endif
+    let linepos -= 1
+  endwhile
+  return '[unknown]'
+endfunction
+
+function! DebChangelogFoldText()
+  if v:folddashes == '-'  " changelog entry fold
+    return foldtext() . ' -- ' . s:getAuthor(v:foldstart, v:foldend) . ' '
+  endif
+  return foldtext()
+endfunction
+
+function! GetDebChangelogFold(lnum)
+  let line = getline(a:lnum)
+  if line =~ '^\w\+'
+    return '>1' " beginning of a changelog entry
+  endif
+  if line =~ '^\s\+\[.*\]'
+    return '>2' " beginning of an author-specific chunk
+  endif
+  if line =~ '^ --'
+    return '1'
+  endif
+  return '='
+endfunction
+
+foldopen!   " unfold the entry the cursor is on (usually the first one)
+
+" }}}
+
+" vim: set foldmethod=marker:
--- /dev/null
+++ b/lib/vimfiles/ftplugin/dictconf.vim
@@ -1,0 +1,13 @@
+" Vim filetype plugin file
+" Language:         dict(1) configuration file
+" Maintainer:       Nikolai Weibull <now@bitwi.se>
+" Latest Revision:  2006-04-19
+
+if exists("b:did_ftplugin")
+  finish
+endif
+let b:did_ftplugin = 1
+
+let b:undo_ftplugin = "setl com< cms< fo<"
+
+setlocal comments=:# commentstring=#\ %s formatoptions-=t formatoptions+=croql
--- /dev/null
+++ b/lib/vimfiles/ftplugin/dictdconf.vim
@@ -1,0 +1,13 @@
+" Vim filetype plugin file
+" Language:         dictd(8) configuration file
+" Maintainer:       Nikolai Weibull <now@bitwi.se>
+" Latest Revision:  2006-04-19
+
+if exists("b:did_ftplugin")
+  finish
+endif
+let b:did_ftplugin = 1
+
+let b:undo_ftplugin = "setl com< cms< fo<"
+
+setlocal comments=:# commentstring=#\ %s formatoptions-=t formatoptions+=croql
--- /dev/null
+++ b/lib/vimfiles/ftplugin/diff.vim
@@ -1,0 +1,15 @@
+" Vim filetype plugin file
+" Language:	Diff
+" Maintainer:	Bram Moolenaar <Bram@vim.org>
+" Last Change:	2005 Jul 27
+
+" Only do this when not done yet for this buffer
+if exists("b:did_ftplugin")
+  finish
+endif
+let b:did_ftplugin = 1
+
+let b:undo_ftplugin = "setl modeline<"
+
+" Don't use modelines in a diff, they apply to the diffed file
+setlocal nomodeline
--- /dev/null
+++ b/lib/vimfiles/ftplugin/dircolors.vim
@@ -1,0 +1,13 @@
+" Vim filetype plugin file
+" Language:         dircolors(1) input file
+" Maintainer:       Nikolai Weibull <now@bitwi.se>
+" Latest Revision:  2006-04-19
+
+if exists("b:did_ftplugin")
+  finish
+endif
+let b:did_ftplugin = 1
+
+let b:undo_ftplugin = "setl com< cms< fo<"
+
+setlocal comments=:# commentstring=#\ %s formatoptions-=t formatoptions+=croql
--- /dev/null
+++ b/lib/vimfiles/ftplugin/dosbatch.vim
@@ -1,0 +1,21 @@
+" Vim filetype plugin file
+" Language:    MS-DOS .bat files
+" Maintainer:  Mike Williams <mrw@eandem.co.uk>
+" Last Change: 5th February 2003
+
+" Only do this when not done yet for this buffer
+if exists("b:did_ftplugin")
+  finish
+endif
+
+" Don't load another plugin for this buffer
+let b:did_ftplugin = 1
+
+" BAT comment formatting
+setlocal comments=b:rem,b:@rem,b:REM,b:@REM,b:::
+setlocal formatoptions-=t formatoptions+=rol
+
+" Define patterns for the browse file filter
+if has("gui_win32") && !exists("b:browsefilter")
+  let b:browsefilter = "DOS Batch Files (*.bat, *.btm, *.cmd)\t*.bat;*.btm;*.cmd\nAll Files (*.*)\t*.*\n"
+endif
--- /dev/null
+++ b/lib/vimfiles/ftplugin/dtd.vim
@@ -1,0 +1,33 @@
+" Vim filetype plugin file
+" Language:	dtd
+" Maintainer:	Dan Sharp <dwsharp at hotmail dot com>
+" Last Changed: 2003 Sep 29
+" URL:		http://mywebpage.netscape.com/sharppeople/vim/ftplugin
+
+if exists("b:did_ftplugin") | finish | endif
+let b:did_ftplugin = 1
+
+" Make sure the continuation lines below do not cause problems in
+" compatibility mode.
+let s:save_cpo = &cpo
+set cpo-=C
+
+setlocal commentstring=<!--%s-->
+
+if exists("loaded_matchit")
+    let b:match_words = '<!--:-->,<!:>'
+endif
+
+" Change the :browse e filter to primarily show Java-related files.
+if has("gui_win32")
+    let  b:browsefilter="DTD Files (*.dtd)\t*.dtd\n" .
+		\	"XML Files (*.xml)\t*.xml\n" .
+		\	"All Files (*.*)\t*.*\n"
+endif
+
+" Undo the stuff we changed.
+let b:undo_ftplugin = "setlocal commentstring<" .
+		\     " | unlet! b:matchwords b:browsefilter"
+
+" Restore the saved compatibility options.
+let &cpo = s:save_cpo
--- /dev/null
+++ b/lib/vimfiles/ftplugin/elinks.vim
@@ -1,0 +1,13 @@
+" Vim filetype plugin file
+" Language:         elinks(1) configuration file
+" Maintainer:       Nikolai Weibull <now@bitwi.se>
+" Latest Revision:  2006-04-19
+
+if exists("b:did_ftplugin")
+  finish
+endif
+let b:did_ftplugin = 1
+
+let b:undo_ftplugin = "setl com< cms< fo<"
+
+setlocal comments=:# commentstring=#\ %s formatoptions-=t formatoptions+=croql
--- /dev/null
+++ b/lib/vimfiles/ftplugin/eruby.vim
@@ -1,0 +1,101 @@
+" Vim filetype plugin
+" Language:		eRuby
+" Maintainer:		Tim Pope <vimNOSPAM@tpope.info>
+" Info:			$Id: eruby.vim,v 1.10 2007/05/06 16:05:40 tpope Exp $
+" URL:			http://vim-ruby.rubyforge.org
+" Anon CVS:		See above site
+" Release Coordinator:	Doug Kearns <dougkearns@gmail.com>
+
+" Only do this when not done yet for this buffer
+if exists("b:did_ftplugin")
+  finish
+endif
+
+let s:save_cpo = &cpo
+set cpo-=C
+
+" Define some defaults in case the included ftplugins don't set them.
+let s:undo_ftplugin = ""
+let s:browsefilter = "All Files (*.*)\t*.*\n"
+let s:match_words = ""
+
+if !exists("g:eruby_default_subtype")
+  let g:eruby_default_subtype = "html"
+endif
+
+if !exists("b:eruby_subtype")
+  let s:lines = getline(1)."\n".getline(2)."\n".getline(3)."\n".getline(4)."\n".getline(5)."\n".getline("$")
+  let b:eruby_subtype = matchstr(s:lines,'eruby_subtype=\zs\w\+')
+  if b:eruby_subtype == ''
+    let b:eruby_subtype = matchstr(substitute(expand("%:t"),'\c\%(\.erb\)\+$','',''),'\.\zs\w\+$')
+  endif
+  if b:eruby_subtype == 'rhtml'
+    let b:eruby_subtype = 'html'
+  elseif b:eruby_subtype == 'rb'
+    let b:eruby_subtype = 'ruby'
+  elseif b:eruby_subtype == 'yml'
+    let b:eruby_subtype = 'yaml'
+  elseif b:eruby_subtype == 'js'
+    let b:eruby_subtype = 'javascript'
+  elseif b:eruby_subtype == 'txt'
+    " Conventional; not a real file type
+    let b:eruby_subtype = 'text'
+  elseif b:eruby_subtype == ''
+    let b:eruby_subtype = g:eruby_default_subtype
+  endif
+endif
+
+if exists("b:eruby_subtype") && b:eruby_subtype != ''
+  exe "runtime! ftplugin/".b:eruby_subtype.".vim ftplugin/".b:eruby_subtype."_*.vim ftplugin/".b:eruby_subtype."/*.vim"
+else
+  runtime! ftplugin/html.vim ftplugin/html_*.vim ftplugin/html/*.vim
+endif
+unlet! b:did_ftplugin
+
+" Override our defaults if these were set by an included ftplugin.
+if exists("b:undo_ftplugin")
+  let s:undo_ftplugin = b:undo_ftplugin
+  unlet b:undo_ftplugin
+endif
+if exists("b:browsefilter")
+  let s:browsefilter = b:browsefilter
+  unlet b:browsefilter
+endif
+if exists("b:match_words")
+  let s:match_words = b:match_words
+  unlet b:match_words
+endif
+
+runtime! ftplugin/ruby.vim ftplugin/ruby_*.vim ftplugin/ruby/*.vim
+let b:did_ftplugin = 1
+
+" Combine the new set of values with those previously included.
+if exists("b:undo_ftplugin")
+  let s:undo_ftplugin = b:undo_ftplugin . " | " . s:undo_ftplugin
+endif
+if exists ("b:browsefilter")
+  let s:browsefilter = substitute(b:browsefilter,'\cAll Files (\*\.\*)\t\*\.\*\n','','') . s:browsefilter
+endif
+if exists("b:match_words")
+  let s:match_words = b:match_words . ',' . s:match_words
+endif
+
+" Change the browse dialog on Win32 to show mainly eRuby-related files
+if has("gui_win32")
+  let b:browsefilter="eRuby Files (*.erb, *.rhtml)\t*.erb;*.rhtml\n" . s:browsefilter
+endif
+
+" Load the combined list of match_words for matchit.vim
+if exists("loaded_matchit")
+  let b:match_words = s:match_words
+endif
+
+" TODO: comments=
+setlocal commentstring=<%#%s%>
+
+let b:undo_ftplugin = "setl cms< "
+      \ " | unlet! b:browsefilter b:match_words | " . s:undo_ftplugin
+
+let &cpo = s:save_cpo
+
+" vim: nowrap sw=2 sts=2 ts=8 ff=unix:
--- /dev/null
+++ b/lib/vimfiles/ftplugin/eterm.vim
@@ -1,0 +1,14 @@
+" Vim filetype plugin file
+" Language:         eterm(1) configuration file
+" Maintainer:       Nikolai Weibull <now@bitwi.se>
+" Latest Revision:  2006-04-19
+
+if exists("b:did_ftplugin")
+  finish
+endif
+let b:did_ftplugin = 1
+
+let b:undo_ftplugin = "setl com< cms< inc< fo<"
+
+setlocal comments=:# commentstring=#\ %s include=^\\s*include
+setlocal formatoptions-=t formatoptions+=croql
--- /dev/null
+++ b/lib/vimfiles/ftplugin/fetchmail.vim
@@ -1,0 +1,13 @@
+" Vim filetype plugin file
+" Language:         fetchmail(1) RC File
+" Maintainer:       Nikolai Weibull <now@bitwi.se>
+" Latest Revision:  2006-04-19
+
+if exists("b:did_ftplugin")
+  finish
+endif
+let b:did_ftplugin = 1
+
+let b:undo_ftplugin = "setl com< cms< fo<"
+
+setlocal comments=:# commentstring=#\ %s formatoptions-=t formatoptions+=croql
--- /dev/null
+++ b/lib/vimfiles/ftplugin/flexwiki.vim
@@ -1,0 +1,59 @@
+" Vim filetype plugin file
+" Language:     FlexWiki, http://www.flexwiki.com/
+" Maintainer:   George V. Reilly  <george@reilly.org>
+" Home:         http://www.georgevreilly.com/vim/flexwiki/
+" Other Home:   http://www.vim.org/scripts/script.php?script_id=1529
+" Author:       George V. Reilly
+" Filenames:    *.wiki
+" Last Change: Wed Apr 26 11:00 PM 2006 P
+" Version:      0.3
+
+if exists("b:did_ftplugin")
+  finish
+endif
+
+let b:did_ftplugin = 1  " Don't load another plugin for this buffer
+
+" Reset the following options to undo this plugin.
+let b:undo_ftplugin = "setl tw< wrap< lbr< et< ts< fenc< bomb< ff<"
+
+" Allow lines of unlimited length. Do NOT want automatic linebreaks,
+" as a newline starts a new paragraph in FlexWiki.
+setlocal textwidth=0
+" Wrap long lines, rather than using horizontal scrolling.
+setlocal wrap
+" Wrap at a character in 'breakat' rather than at last char on screen
+setlocal linebreak
+" Don't transform <TAB> characters into spaces, as they are significant
+" at the beginning of the line for numbered and bulleted lists.
+setlocal noexpandtab
+" 4-char tabstops, per flexwiki.el
+setlocal tabstop=4
+" Save *.wiki files in UTF-8
+setlocal fileencoding=utf-8
+" Add the UTF-8 Byte Order Mark to the beginning of the file
+setlocal bomb
+" Save <EOL>s as \n, not \r\n
+setlocal fileformat=unix
+
+if exists("g:flexwiki_maps")
+  " Move up and down by display lines, to account for screen wrapping
+  " of very long lines
+  nmap <buffer> <Up>   gk
+  nmap <buffer> k      gk
+  vmap <buffer> <Up>   gk
+  vmap <buffer> k      gk
+
+  nmap <buffer> <Down> gj
+  nmap <buffer> j      gj
+  vmap <buffer> <Down> gj
+  vmap <buffer> j      gj
+
+  " for earlier versions - for when 'wrap' is set
+  imap <buffer> <S-Down>   <C-o>gj
+  imap <buffer> <S-Up>     <C-o>gk
+  if v:version >= 700
+      imap <buffer> <Down>   <C-o>gj
+      imap <buffer> <Up>     <C-o>gk
+  endif
+endif
--- /dev/null
+++ b/lib/vimfiles/ftplugin/fortran.vim
@@ -1,0 +1,117 @@
+" Vim settings file
+" Language:	Fortran90 (and Fortran95, Fortran77, F and elf90)
+" Version:	0.45
+" Last Change:	2006 Apr. 03
+" URL:		http://www.unb.ca/chem/ajit/ftplugin/fortran.vim
+" Maintainer:	Ajit J. Thakkar <ajit@unb.ca>; <http://www.unb.ca/chem/ajit/>
+" Usage:	Do :help fortran-plugin from Vim
+" Credits:      Useful suggestions were made by Stefano Zacchiroli
+
+" Only do these settings when not done yet for this buffer
+if exists("b:did_ftplugin")
+  finish
+endif
+
+" Don't do other file type settings for this buffer
+let b:did_ftplugin = 1
+
+" Determine whether this is a fixed or free format source file
+" if this hasn't been done yet
+if !exists("b:fortran_fixed_source")
+  if exists("fortran_free_source")
+    " User guarantees free source form
+    let b:fortran_fixed_source = 0
+  elseif exists("fortran_fixed_source")
+    " User guarantees fixed source form
+    let b:fortran_fixed_source = 1
+  else
+    " f90 and f95 allow both fixed and free source form
+    " assume fixed source form unless signs of free source form
+    " are detected in the first five columns of the first 250 lines
+    " Detection becomes more accurate and time-consuming if more lines
+    " are checked. Increase the limit below if you keep lots of comments at
+    " the very top of each file and you have a fast computer
+    let s:lmax = 250
+    if ( s:lmax > line("$") )
+      let s:lmax = line("$")
+    endif
+    let b:fortran_fixed_source = 1
+    let s:ln=1
+    while s:ln <= s:lmax
+      let s:test = strpart(getline(s:ln),0,5)
+      if s:test[0] !~ '[Cc*!#]' && s:test !~ '^ \+[!#]' && s:test =~ '[^ 0-9\t]'
+	let b:fortran_fixed_source = 0
+	break
+      endif
+      let s:ln = s:ln + 1
+    endwhile
+  endif
+endif
+
+" Set comments and textwidth according to source type
+if (b:fortran_fixed_source == 1)
+  setlocal comments=:!,:*,:C
+  " Fixed format requires a textwidth of 72 for code
+  setlocal tw=72
+  " If you need to add "&" on continued lines so that the code is
+  " compatible with both free and fixed format, then you should do so
+  " in column 73 and uncomment the next line
+  " setlocal tw=73
+else
+  setlocal comments=:!
+  " Free format allows a textwidth of 132 for code but 80 is more usual
+  setlocal tw=80
+endif
+
+" Set commentstring for foldmethod=marker
+setlocal cms=!%s
+
+" Tabs are not a good idea in Fortran so the default is to expand tabs
+if !exists("fortran_have_tabs")
+  setlocal expandtab
+endif
+
+" Set 'formatoptions' to break comment and text lines but allow long lines
+setlocal fo+=tcql
+
+setlocal include=^\\c#\\=\\s*include\\s\\+
+setlocal suffixesadd+=.f95,.f90,.for,.f,.F,.f77,.ftn,.fpp
+
+let s:cposet=&cpoptions
+set cpoptions-=C
+
+" Define patterns for the matchit plugin
+if !exists("b:match_words")
+  let s:notend = '\%(\<end\s\+\)\@<!'
+  let s:notselect = '\%(\<select\s\+\)\@<!'
+  let s:notelse = '\%(\<end\s\+\|\<else\s\+\)\@<!'
+  let s:notprocedure = '\%(\s\+procedure\>\)\@!'
+  let b:match_ignorecase = 1
+  let b:match_words =
+    \ '\<select\s*case\>:' . s:notselect. '\<case\>:\<end\s*select\>,' .
+    \ s:notelse . '\<if\s*(.\+)\s*then\>:' .
+    \ '\<else\s*\%(if\s*(.\+)\s*then\)\=\>:\<end\s*if\>,'.
+    \ 'do\s\+\(\d\+\):\%(^\s*\)\@<=\1\s,'.
+    \ s:notend . '\<do\>:\<end\s*do\>,'.
+    \ s:notelse . '\<where\>:\<elsewhere\>:\<end\s*where\>,'.
+    \ s:notend . '\<type\s*[^(]:\<end\s*type\>,'.
+    \ s:notend . '\<interface\>:\<end\s*interface\>,'.
+    \ s:notend . '\<subroutine\>:\<end\s*subroutine\>,'.
+    \ s:notend . '\<function\>:\<end\s*function\>,'.
+    \ s:notend . '\<module\>' . s:notprocedure . ':\<end\s*module\>,'.
+    \ s:notend . '\<program\>:\<end\s*program\>'
+endif
+
+" File filters for :browse e
+if has("gui_win32") && !exists("b:browsefilter")
+  let b:browsefilter = "Fortran Files (*.f;*.F;*.for;*.f77;*.f90;*.f95;*.fpp;*.ftn)\t*.f;*.F;*.for;*.f77;*.f90;*.f95;*.fpp;*.ftn\n" .
+    \ "All Files (*.*)\t*.*\n"
+endif
+
+let b:undo_ftplugin = "setl fo< com< tw< cms< et< inc<"
+	\ . "| unlet! b:match_ignorecase b:match_words b:browsefilter"
+
+let &cpoptions=s:cposet
+unlet s:cposet
+
+" vim:sw=2
--- /dev/null
+++ b/lib/vimfiles/ftplugin/fvwm.vim
@@ -1,0 +1,14 @@
+" Created	: Tue 09 May 2006 02:07:31 PM CDT
+" Modified	: Tue 09 May 2006 02:07:31 PM CDT
+" Author	: Gautam Iyer <gi1242@users.sourceforge.net>
+" Description	: ftplugin for fvwm config files
+
+if exists("b:did_ftplugin")
+  finish
+endif
+let b:did_ftplugin = 1
+
+let b:undo_ftplugin = "setl com< cms< fo<"
+
+setlocal comments=:# commentstring=#\ %s
+setlocal formatoptions-=t formatoptions+=croql
--- /dev/null
+++ b/lib/vimfiles/ftplugin/gpg.vim
@@ -1,0 +1,13 @@
+" Vim filetype plugin file
+" Language:         gpg(1) configuration file
+" Maintainer:       Nikolai Weibull <now@bitwi.se>
+" Latest Revision:  2006-04-19
+
+if exists("b:did_ftplugin")
+  finish
+endif
+let b:did_ftplugin = 1
+
+let b:undo_ftplugin = "setl com< cms< fo<"
+
+setlocal comments=:# commentstring=#\ %s formatoptions-=t formatoptions+=croql
--- /dev/null
+++ b/lib/vimfiles/ftplugin/group.vim
@@ -1,0 +1,13 @@
+" Vim filetype plugin file
+" Language:         group(5) user group file
+" Maintainer:       Nikolai Weibull <now@bitwi.se>
+" Latest Revision:  2006-04-19
+
+if exists("b:did_ftplugin")
+  finish
+endif
+let b:did_ftplugin = 1
+
+let b:undo_ftplugin = "setl com< cms< fo<"
+
+setlocal comments= commentstring= formatoptions-=tcroq formatoptions+=l
--- /dev/null
+++ b/lib/vimfiles/ftplugin/grub.vim
@@ -1,0 +1,13 @@
+" Vim filetype plugin file
+" Language:         grub(8) configuration file
+" Maintainer:       Nikolai Weibull <now@bitwi.se>
+" Latest Revision:  2006-04-19
+
+if exists("b:did_ftplugin")
+  finish
+endif
+let b:did_ftplugin = 1
+
+let b:undo_ftplugin = "setl com< cms< fo<"
+
+setlocal comments=:# commentstring=#\ %s formatoptions-=t formatoptions+=croql
--- /dev/null
+++ b/lib/vimfiles/ftplugin/hamster.vim
@@ -1,0 +1,61 @@
+" Vim filetype plugin
+" Language:    Hamster Script
+" Version:     2.0.6.0
+" Maintainer:  David Fishburn <fishburn@ianywhere.com>
+" Last Change: Wed Nov 08 2006 12:03:09 PM
+
+" Only do this when not done yet for this buffer
+if exists("b:did_ftplugin")
+  finish
+endif
+
+" Don't load another plugin for this buffer
+let b:did_ftplugin = 1
+
+let cpo_save = &cpo
+set cpo-=C
+
+let b:undo_ftplugin = "setl fo< com< tw< commentstring<"
+	\ . "| unlet! b:match_ignorecase b:match_words b:match_skip"
+
+" Set 'formatoptions' to break comment lines but not other lines,
+" and insert the comment leader when hitting <CR> or using "o".
+setlocal fo-=t fo+=croql
+
+" Use the # sign for comments
+setlocal comments=:#
+
+" Format comments to be up to 78 characters long
+if &tw == 0
+  setlocal tw=78
+endif
+
+" Comments start with a double quote
+setlocal commentstring=#%s
+
+" Move around functions.
+noremap <silent><buffer> [[ :call search('^\s*sub\>', "bW")<CR>
+noremap <silent><buffer> ]] :call search('^\s*sub\>', "W")<CR>
+noremap <silent><buffer> [] :call search('^\s*endsub\>', "bW")<CR>
+noremap <silent><buffer> ][ :call search('^\s*endsub\>', "W")<CR>
+
+" Move around comments
+noremap <silent><buffer> ]# :call search('^\s*#\@!', "W")<CR>
+noremap <silent><buffer> [# :call search('^\s*#\@!', "bW")<CR>
+
+" Let the matchit plugin know what items can be matched.
+if exists("loaded_matchit")
+  let b:match_ignorecase = 0
+  let b:match_words =
+	\ '\<sub\>:\<return\>:\<endsub\>,' .
+        \ '\<do\|while\|repeat\|for\>:\<break\>:\<continue\>:\<loop\|endwhile\|until\|endfor\>,' .
+	\ '\<if\>:\<else\%[if]\>:\<endif\>' 
+
+  " Ignore ":syntax region" commands, the 'end' argument clobbers if-endif
+  " let b:match_skip = 'getline(".") =~ "^\\s*sy\\%[ntax]\\s\\+region" ||
+  "	\ synIDattr(synID(line("."),col("."),1),"name") =~? "comment\\|string"'
+endif
+
+setlocal ignorecase
+let &cpo = cpo_save
+setlocal cpo+=M		" makes \%( match \)
--- /dev/null
+++ b/lib/vimfiles/ftplugin/haskell.vim
@@ -1,0 +1,14 @@
+" Vim filetype plugin file
+" Language:         Haskell
+" Maintainer:       Nikolai Weibull <now@bitwi.se>
+" Latest Revision:  2006-04-19
+
+if exists("b:did_ftplugin")
+  finish
+endif
+let b:did_ftplugin = 1
+
+let b:undo_ftplugin = "setl com< cms< fo<"
+
+setlocal comments=s1fl:{-,mb:-,ex:-},:-- commentstring=--\ %s
+setlocal formatoptions-=t formatoptions+=croql
--- /dev/null
+++ b/lib/vimfiles/ftplugin/help.vim
@@ -1,0 +1,13 @@
+" Vim filetype plugin file
+" Language:         Vim help file
+" Maintainer:       Nikolai Weibull <now@bitwi.se>
+" Latest Revision:  2006-04-19
+
+if exists("b:did_ftplugin")
+  finish
+endif
+let b:did_ftplugin = 1
+
+let b:undo_ftplugin = "setl fo< tw<"
+
+setlocal formatoptions+=tcroql textwidth=78
--- /dev/null
+++ b/lib/vimfiles/ftplugin/html.vim
@@ -1,0 +1,92 @@
+" Vim filetype plugin file
+" Language:	html
+" Maintainer:	Dan Sharp <dwsharp at hotmail dot com>
+" Last Changed: 2006 Apr 26
+" URL:		http://mywebpage.netscape.com/sharppeople/vim/ftplugin
+
+if exists("b:did_ftplugin") | finish | endif
+let b:did_ftplugin = 1
+
+" Make sure the continuation lines below do not cause problems in
+" compatibility mode.
+let s:save_cpo = &cpo
+set cpo-=C
+
+setlocal commentstring=<!--%s-->
+
+if exists('&omnifunc')
+" Distinguish between HTML versions
+" To use with other HTML versions add another
+" elseif condition to match proper DOCTYPE
+setlocal omnifunc=htmlcomplete#CompleteTags
+
+if &filetype == 'xhtml'
+	let b:html_omni_flavor = 'xhtml10s'
+else
+	let b:html_omni_flavor = 'html401t'
+endif
+let i = 1
+while i < 10 && i < line("$")
+	let line = getline(i)
+	if line =~ '<!DOCTYPE.*\<DTD HTML 3\.2'
+		let b:html_omni_flavor = 'html32'
+		break
+	elseif line =~ '<!DOCTYPE.*\<DTD HTML 4\.0 Transitional'
+		let b:html_omni_flavor = 'html40t'
+		break
+	elseif line =~ '<!DOCTYPE.*\<DTD HTML 4\.0 Frameset'
+		let b:html_omni_flavor = 'html40f'
+		break
+	elseif line =~ '<!DOCTYPE.*\<DTD HTML 4\.0'
+		let b:html_omni_flavor = 'html40s'
+		break
+	elseif line =~ '<!DOCTYPE.*\<DTD HTML 4\.01 Transitional'
+		let b:html_omni_flavor = 'html401t'
+		break
+	elseif line =~ '<!DOCTYPE.*\<DTD HTML 4\.01 Frameset'
+		let b:html_omni_flavor = 'html401f'
+		break
+	elseif line =~ '<!DOCTYPE.*\<DTD HTML 4\.01'
+		let b:html_omni_flavor = 'html401s'
+		break
+	elseif line =~ '<!DOCTYPE.*\<DTD XHTML 1\.0 Transitional'
+		let b:html_omni_flavor = 'xhtml10t'
+		break
+	elseif line =~ '<!DOCTYPE.*\<DTD XHTML 1\.0 Frameset'
+		let b:html_omni_flavor = 'xhtml10f'
+		break
+	elseif line =~ '<!DOCTYPE.*\<DTD XHTML 1\.0 Strict'
+		let b:html_omni_flavor = 'xhtml10s'
+		break
+	elseif line =~ '<!DOCTYPE.*\<DTD XHTML 1\.1'
+		let b:html_omni_flavor = 'xhtml11'
+		break
+	endif
+	let i += 1
+endwhile
+endif
+
+" HTML:  thanks to Johannes Zellner and Benji Fisher.
+if exists("loaded_matchit")
+    let b:match_ignorecase = 1
+    let b:match_skip = 's:Comment'
+    let b:match_words = '<:>,' .
+    \ '<\@<=[ou]l\>[^>]*\%(>\|$\):<\@<=li\>:<\@<=/[ou]l>,' .
+    \ '<\@<=dl\>[^>]*\%(>\|$\):<\@<=d[td]\>:<\@<=/dl>,' .
+    \ '<\@<=\([^/][^ \t>]*\)[^>]*\%(>\|$\):<\@<=/\1>'
+endif
+
+" Change the :browse e filter to primarily show HTML-related files.
+if has("gui_win32")
+    let  b:browsefilter="HTML Files (*.html,*.htm)\t*.htm;*.html\n" .
+		\	"JavaScript Files (*.js)\t*.js\n" .
+		\	"Cascading StyleSheets (*.css)\t*.css\n" .
+		\	"All Files (*.*)\t*.*\n"
+endif
+
+" Undo the stuff we changed.
+let b:undo_ftplugin = "setlocal commentstring<"
+    \	" | unlet! b:match_ignorecase b:match_skip b:match_words b:browsefilter"
+
+" Restore the saved compatibility options.
+let &cpo = s:save_cpo
--- /dev/null
+++ b/lib/vimfiles/ftplugin/htmldjango.vim
@@ -1,0 +1,13 @@
+" Vim filetype plugin file
+" Language:	Django HTML template
+" Maintainer:	Dave Hodder <dmh@dmh.org.uk>
+" Last Change:	2007 Jan 25
+
+" Only use this filetype plugin when no other was loaded.
+if exists("b:did_ftplugin")
+  finish
+endif
+
+" Use HTML and Django template ftplugins.
+runtime! ftplugin/html.vim
+runtime! ftplugin/django.vim
--- /dev/null
+++ b/lib/vimfiles/ftplugin/indent.vim
@@ -1,0 +1,14 @@
+" Vim filetype plugin file
+" Language:         indent(1) configuration file
+" Maintainer:       Nikolai Weibull <now@bitwi.se>
+" Latest Revision:  2006-04-19
+
+if exists("b:did_ftplugin")
+  finish
+endif
+let b:did_ftplugin = 1
+
+let b:undo_ftplugin = "setl com< cms< fo<"
+
+setlocal comments=s1:/*,mb:*,ex:*/ commentstring&
+setlocal formatoptions-=t formatoptions+=croql
--- /dev/null
+++ b/lib/vimfiles/ftplugin/initex.vim
@@ -1,0 +1,38 @@
+" filetype plugin for TeX and variants
+" Language:     TeX (ft=initex)
+" Maintainer:   Benji Fisher, Ph.D. <benji@member.AMS.org>
+" Version:	1.0
+" Last Change:	Wed 19 Apr 2006
+
+" Only do this when not done yet for this buffer.
+if exists("b:did_ftplugin")
+  finish
+endif
+
+" Don't load another plugin for this buffer.
+let b:did_ftplugin = 1
+
+" Avoid problems if running in 'compatible' mode.
+let s:save_cpo = &cpo
+set cpo&vim
+
+let b:undo_ftplugin = "setl com< cms< define< include< sua<"
+
+" Set 'comments' to format dashed lists in comments
+setlocal com=sO:%\ -,mO:%\ \ ,eO:%%,:%
+
+" Set 'commentstring' to recognize the % comment character:
+" (Thanks to Ajit Thakkar.)
+setlocal cms=%%s
+
+" Allow "[d" to be used to find a macro definition:
+let &l:define='\\\([egx]\|char\|mathchar\|count\|dimen\|muskip\|skip\|toks\)\='
+	\ .	'def\|\\font\|\\\(future\)\=let'
+
+" Tell Vim to recognize \input bar :
+let &l:include = '\\input'
+setlocal suffixesadd=.tex
+
+let &cpo = s:save_cpo
+
+" vim:sts=2:sw=2:
--- /dev/null
+++ b/lib/vimfiles/ftplugin/ishd.vim
@@ -1,0 +1,28 @@
+" Vim filetype plugin file
+" Language:	InstallShield (ft=ishd)
+" Maintainer:	Johannes Zellner <johannes@zellner.org>
+" Last Change:	Sat, 24 May 2003 11:55:36 CEST
+
+if exists("b:did_ftplugin") | finish | endif
+let b:did_ftplugin = 1
+
+setlocal foldmethod=syntax
+
+set cpo-=C
+
+" matchit support
+if exists("loaded_matchit")
+    let b:match_ignorecase=0
+    let b:match_words=
+    \ '\%(^\s*\)\@<=\<function\>\s\+[^()]\+\s*(:\%(^\s*\)\@<=\<begin\>\s*$:\%(^\s*\)\@<=\<return\>:\%(^\s*\)\@<=\<end\>\s*;\s*$,' .
+    \ '\%(^\s*\)\@<=\<repeat\>\s*$:\%(^\s*\)\@<=\<until\>\s\+.\{-}\s*;\s*$,' .
+    \ '\%(^\s*\)\@<=\<switch\>\s*(.\{-}):\%(^\s*\)\@<=\<\%(case\|default\)\>:\%(^\s*\)\@<=\<endswitch\>\s*;\s*$,' .
+    \ '\%(^\s*\)\@<=\<while\>\s*(.\{-}):\%(^\s*\)\@<=\<endwhile\>\s*;\s*$,' .
+    \ '\%(^\s*\)\@<=\<for\>.\{-}\<\%(to\|downto\)\>:\%(^\s*\)\@<=\<endfor\>\s*;\s*$,' .
+    \ '\%(^\s*\)\@<=\<if\>\s*(.\{-})\s*then:\%(^\s*\)\@<=\<else\s*if\>\s*([^)]*)\s*then:\%(^\s*\)\@<=\<else\>:\%(^\s*\)\@<=\<endif\>\s*;\s*$'
+endif
+
+if has("gui_win32") && !exists("b:browsefilter")
+    let b:browsefilter = "InstallShield Files (*.rul)\t*.rul\n" .
+		       \ "All Files (*.*)\t*.*\n"
+endif
--- /dev/null
+++ b/lib/vimfiles/ftplugin/java.vim
@@ -1,0 +1,50 @@
+" Vim filetype plugin file
+" Language:	Java
+" Maintainer:	Dan Sharp <dwsharp at hotmail dot com>
+" Last Change:  2005 Mar 28
+" URL:		http://mywebpage.netscape.com/sharppeople/vim/ftplugin
+
+if exists("b:did_ftplugin") | finish | endif
+let b:did_ftplugin = 1
+
+" Make sure the continuation lines below do not cause problems in
+" compatibility mode.
+let s:save_cpo = &cpo
+set cpo-=C
+
+" For filename completion, prefer the .java extension over the .class
+" extension.
+set suffixes+=.class
+
+" Enable gf on import statements.  Convert . in the package
+" name to / and append .java to the name, then search the path.
+setlocal includeexpr=substitute(v:fname,'\\.','/','g')
+setlocal suffixesadd=.java
+if exists("g:ftplugin_java_source_path")
+    let &l:path=g:ftplugin_java_source_path . ',' . &l:path
+endif
+
+" Set 'formatoptions' to break comment lines but not other lines,
+" and insert the comment leader when hitting <CR> or using "o".
+setlocal formatoptions-=t formatoptions+=croql
+
+" Set 'comments' to format dashed lists in comments. Behaves just like C.
+setlocal comments& comments^=sO:*\ -,mO:*\ \ ,exO:*/
+
+setlocal commentstring=//%s
+
+" Change the :browse e filter to primarily show Java-related files.
+if has("gui_win32")
+    let  b:browsefilter="Java Files (*.java)\t*.java\n" .
+		\	"Properties Files (*.prop*)\t*.prop*\n" .
+		\	"Manifest Files (*.mf)\t*.mf\n" .
+		\	"All Files (*.*)\t*.*\n"
+endif
+
+" Undo the stuff we changed.
+let b:undo_ftplugin = "setlocal suffixes< suffixesadd<" .
+		\     " formatoptions< comments< commentstring< path< includeexpr<" .
+		\     " | unlet! b:browsefilter"
+
+" Restore the saved compatibility options.
+let &cpo = s:save_cpo
--- /dev/null
+++ b/lib/vimfiles/ftplugin/javascript.vim
@@ -1,0 +1,38 @@
+" Vim filetype plugin file
+" Language:	Javascript
+" Maintainer:	Doug Kearns <dougkearns@gmail.com>
+" Last Change:  2007 Feb 21
+" URL:		http://gus.gscit.monash.edu.au/~djkea2/vim/ftplugin/javascript.vim
+
+if exists("b:did_ftplugin")
+  finish
+endif
+let b:did_ftplugin = 1
+
+let s:cpo_save = &cpo
+set cpo-=C
+
+" Set 'formatoptions' to break comment lines but not other lines,
+" " and insert the comment leader when hitting <CR> or using "o".
+setlocal formatoptions-=t formatoptions+=croql
+
+" Set completion with CTRL-X CTRL-O to autoloaded function.
+if exists('&ofu')
+    setlocal omnifunc=javascriptcomplete#CompleteJS
+endif
+
+" Set 'comments' to format dashed lists in comments.
+setlocal comments=sO:*\ -,mO:*\ \ ,exO:*/,s1:/*,mb:*,ex:*/,://
+
+setlocal commentstring=//%s
+
+" Change the :browse e filter to primarily show Java-related files.
+if has("gui_win32")
+    let  b:browsefilter="Javascript Files (*.js)\t*.js\n"
+		\	"All Files (*.*)\t*.*\n"
+endif
+       
+let b:undo_ftplugin = "setl fo< ofu< com< cms<" 
+
+let &cpo = s:cpo_save
+unlet s:cpo_save
--- /dev/null
+++ b/lib/vimfiles/ftplugin/jsp.vim
@@ -1,0 +1,66 @@
+" Vim filetype plugin file
+" Language:	jsp
+" Maintainer:	Dan Sharp <dwsharp at hotmail dot com>
+" Last Changed: 2005 Oct 10
+" URL:		http://mywebpage.netscape.com/sharppeople/vim/ftplugin
+
+if exists("b:did_ftplugin") | finish | endif
+
+" Make sure the continuation lines below do not cause problems in
+" compatibility mode.
+let s:save_cpo = &cpo
+set cpo-=C
+
+" Define some defaults in case the included ftplugins don't set them.
+let s:undo_ftplugin = ""
+let s:browsefilter = "Java Files (*.java)\t*.java\n" .
+	    \	 "HTML Files (*.html, *.htm)\t*.html;*.htm\n" .
+	    \	 "All Files (*.*)\t*.*\n"
+let s:match_words = ""
+
+runtime! ftplugin/html.vim ftplugin/html_*.vim ftplugin/html/*.vim
+unlet b:did_ftplugin
+
+" Override our defaults if these were set by an included ftplugin.
+if exists("b:undo_ftplugin")
+    let s:undo_ftplugin = b:undo_ftplugin
+    unlet b:undo_ftplugin
+endif
+if exists("b:browsefilter")
+    let s:browsefilter = b:browsefilter
+    unlet b:browsefilter
+endif
+if exists("b:match_words")
+    let s:match_words = b:match_words
+    unlet b:match_words
+endif
+
+runtime! ftplugin/java.vim ftplugin/java_*.vim ftplugin/java/*.vim
+let b:did_ftplugin = 1
+
+" Combine the new set of values with those previously included.
+if exists("b:undo_ftplugin")
+    let s:undo_ftplugin = b:undo_ftplugin . " | " . s:undo_ftplugin
+endif
+if exists ("b:browsefilter")
+    let s:browsefilter = b:browsefilter . s:browsefilter
+endif
+if exists("b:match_words")
+    let s:match_words = b:match_words . ',' . s:match_words
+endif
+
+" Load the combined list of match_words for matchit.vim
+if exists("loaded_matchit")
+    let b:match_words = s:match_words
+endif
+
+" Change the :browse e filter to primarily show JSP-related files.
+if has("gui_win32")
+    let  b:browsefilter="JSP Files (*.jsp)\t*.jsp\n" . s:browsefilter
+endif
+
+" Undo the stuff we changed.
+let b:undo_ftplugin = "unlet! b:browsefilter b:match_words | " . s:undo_ftplugin
+
+" Restore the saved compatibility options.
+let &cpo = s:save_cpo
--- /dev/null
+++ b/lib/vimfiles/ftplugin/kconfig.vim
@@ -1,0 +1,12 @@
+" Vim filetype plugin file
+" Maintainer:       Nikolai Weibull <now@bitwi.se>
+" Latest Revision:  2006-04-10
+
+if exists("b:did_ftplugin")
+  finish
+endif
+let b:did_ftplugin = 1
+
+let b:undo_ftplugin = "setl com< cms< fo<"
+
+setlocal comments=:# commentstring=#\ %s formatoptions-=t formatoptions+=croql
--- /dev/null
+++ b/lib/vimfiles/ftplugin/kwt.vim
@@ -1,0 +1,20 @@
+" Vim filetype plugin file
+" Language:	Kimwitu++
+" Maintainer:	Michael Piefel <piefel@informatik.hu-berlin.de>
+" Last Change:	16 August 2001
+
+" Behaves almost like C++
+runtime! ftplugin/cpp.vim ftplugin/cpp_*.vim ftplugin/cpp/*.vim
+
+set cpo-=C
+
+" Limit the browser to related files
+if has("gui_win32") && !exists("b:browsefilter")
+    let b:browsefilter = "Kimwitu/Kimwitu++ Files (*.k)\t*.k\n" .
+		\ "Lex/Flex Files (*.l)\t*.l\n" .
+		\ "Yacc/Bison Files (*.y)\t*.y\n" .
+		\ "All Files (*.*)\t*.*\n"
+endif
+
+" Set the errorformat for the Kimwitu++ compiler
+set efm+=kc%.%#:\ error\ at\ %f:%l:\ %m
--- /dev/null
+++ b/lib/vimfiles/ftplugin/ld.vim
@@ -1,0 +1,14 @@
+" Vim filetype plugin file
+" Language:         ld(1) script
+" Maintainer:       Nikolai Weibull <now@bitwi.se>
+" Latest Revision:  2006-04-19
+
+if exists("b:did_ftplugin")
+  finish
+endif
+let b:did_ftplugin = 1
+
+let b:undo_ftplugin = "setl com< cms< inc< fo<"
+
+setlocal comments=s1:/*,mb:*,ex:*/ commentstring=/*%s*/ include=^\\s*INCLUDE
+setlocal formatoptions-=t formatoptions+=croql
--- /dev/null
+++ b/lib/vimfiles/ftplugin/lftp.vim
@@ -1,0 +1,13 @@
+" Vim filetype plugin file
+" Language:         lftp(1) configuration file
+" Maintainer:       Nikolai Weibull <now@bitwi.se>
+" Latest Revision:  2006-04-19
+
+if exists("b:did_ftplugin")
+  finish
+endif
+let b:did_ftplugin = 1
+
+let b:undo_ftplugin = "setl com< cms< fo<"
+
+setlocal comments=:# commentstring=#\ %s formatoptions-=t formatoptions+=croql
--- /dev/null
+++ b/lib/vimfiles/ftplugin/libao.vim
@@ -1,0 +1,13 @@
+" Vim filetype plugin file
+" Language:         libao.conf(5) configuration file
+" Maintainer:       Nikolai Weibull <now@bitwi.se>
+" Latest Revision:  2006-04-19
+
+if exists("b:did_ftplugin")
+  finish
+endif
+let b:did_ftplugin = 1
+
+let b:undo_ftplugin = "setl com< cms< fo<"
+
+setlocal comments=:# commentstring=#\ %s formatoptions-=t formatoptions+=croql
--- /dev/null
+++ b/lib/vimfiles/ftplugin/limits.vim
@@ -1,0 +1,13 @@
+" Vim filetype plugin file
+" Language:         limits(5) configuration file
+" Maintainer:       Nikolai Weibull <now@bitwi.se>
+" Latest Revision:  2006-04-19
+
+if exists("b:did_ftplugin")
+  finish
+endif
+let b:did_ftplugin = 1
+
+let b:undo_ftplugin = "setl com< cms< fo<"
+
+setlocal comments=:# commentstring=#\ %s formatoptions-=t formatoptions+=croql
--- /dev/null
+++ b/lib/vimfiles/ftplugin/lisp.vim
@@ -1,0 +1,26 @@
+" Vim filetype plugin
+" Language:      Lisp
+" Maintainer:    Sergey Khorev <sergey.khorev@gmail.com>
+" URL:		 http://iamphet.nm.ru/vim
+" Original author:    Dorai Sitaram <ds26@gte.com>
+" Original URL:		 http://www.ccs.neu.edu/~dorai/vimplugins/vimplugins.html
+" Last Change:   Nov 8, 2004
+
+" Only do this when not done yet for this buffer
+if exists("b:did_ftplugin")
+  finish
+endif
+
+" Don't load another plugin for this buffer
+let b:did_ftplugin = 1
+
+setl comments=:;
+setl define=^\\s*(def\\k*
+setl formatoptions-=t
+setl iskeyword+=+,-,*,/,%,<,=,>,:,$,?,!,@-@,94
+setl lisp
+
+" make comments behaviour like in c.vim
+" e.g. insertion of ;;; and ;; on normal "O" or "o" when staying in comment
+setl comments^=:;;;,:;;,sr:#\|,mb:\|,ex:\|#
+setl formatoptions+=croql
--- /dev/null
+++ b/lib/vimfiles/ftplugin/loginaccess.vim
@@ -1,0 +1,13 @@
+" Vim filetype plugin file
+" Language:         login.access(5) configuration file
+" Maintainer:       Nikolai Weibull <now@bitwi.se>
+" Latest Revision:  2006-04-19
+
+if exists("b:did_ftplugin")
+  finish
+endif
+let b:did_ftplugin = 1
+
+let b:undo_ftplugin = "setl com< cms< fo<"
+
+setlocal comments=:# commentstring=#\ %s formatoptions-=t formatoptions+=croql
--- /dev/null
+++ b/lib/vimfiles/ftplugin/logindefs.vim
@@ -1,0 +1,13 @@
+" Vim filetype plugin file
+" Language:         login.defs(5) configuration file
+" Maintainer:       Nikolai Weibull <now@bitwi.se>
+" Latest Revision:  2006-04-19
+
+if exists("b:did_ftplugin")
+  finish
+endif
+let b:did_ftplugin = 1
+
+let b:undo_ftplugin = "setl com< cms< fo<"
+
+setlocal comments=:# commentstring=#\ %s formatoptions-=t formatoptions+=croql
--- /dev/null
+++ b/lib/vimfiles/ftplugin/lprolog.vim
@@ -1,0 +1,37 @@
+" Vim settings file
+" Language:     LambdaProlog (Teyjus)
+" Maintainer:   Markus Mottl  <markus.mottl@gmail.com>
+" URL:          http://www.ocaml.info/vim/ftplugin/lprolog.vim
+" Last Change:  2006 Feb 05
+"               2001 Sep 16 - fixed 'no_mail_maps'-bug (MM)
+"               2001 Sep 02 - initial release  (MM)
+
+" Only do these settings when not done yet for this buffer
+if exists("b:did_ftplugin")
+  finish
+endif
+
+" Don't do other file type settings for this buffer
+let b:did_ftplugin = 1
+
+" Error format
+setlocal efm=%+A./%f:%l.%c:\ %m formatprg=fmt\ -w75\ -p\\%
+
+" Formatting of comments
+setlocal formatprg=fmt\ -w75\ -p\\%
+
+" Add mappings, unless the user didn't want this.
+if !exists("no_plugin_maps") && !exists("no_lprolog_maps")
+  " Uncommenting
+  if !hasmapto('<Plug>Comment')
+    nmap <buffer> <LocalLeader>c <Plug>LUncomOn
+    vmap <buffer> <LocalLeader>c <Plug>BUncomOn
+    nmap <buffer> <LocalLeader>C <Plug>LUncomOff
+    vmap <buffer> <LocalLeader>C <Plug>BUncomOff
+  endif
+
+  nnoremap <buffer> <Plug>LUncomOn mz0i/* <ESC>$A */<ESC>`z
+  nnoremap <buffer> <Plug>LUncomOff <ESC>:s/^\/\* \(.*\) \*\//\1/<CR>
+  vnoremap <buffer> <Plug>BUncomOn <ESC>:'<,'><CR>`<O<ESC>0i/*<ESC>`>o<ESC>0i*/<ESC>`<
+  vnoremap <buffer> <Plug>BUncomOff <ESC>:'<,'><CR>`<dd`>dd`<
+endif
--- /dev/null
+++ b/lib/vimfiles/ftplugin/lua.vim
@@ -1,0 +1,36 @@
+" Vim filetype plugin file.
+" Language:	Lua 4.0+
+" Maintainer:	Max Ischenko <mfi@ukr.net>
+" Last Change:	2001 Sep 17
+
+" Only do this when not done yet for this buffer
+if exists("b:did_ftplugin")
+  finish
+endif
+
+" Don't load another plugin for this buffer
+let b:did_ftplugin = 1
+
+" Set 'formatoptions' to break comment lines but not other lines, and insert
+" the comment leader when hitting <CR> or using "o".
+setlocal fo-=t fo+=croql
+
+setlocal com=:--
+setlocal cms="--%s"
+setlocal suffixesadd=.lua
+
+
+" The following lines enable the macros/matchit.vim plugin for
+" extended matching with the % key.
+
+set cpo-=C
+if exists("loaded_matchit")
+
+  let b:match_ignorecase = 0
+  let b:match_words =
+    \ '\<\%(do\|function\|if\)\>:' .
+    \ '\<\%(return\|else\|elseif\)\>:' .
+    \ '\<end\>,' .
+    \ '\<repeat\>:\<until\>'
+
+endif " exists("loaded_matchit")
--- /dev/null
+++ b/lib/vimfiles/ftplugin/m4.vim
@@ -1,0 +1,14 @@
+" Vim filetype plugin file
+" Language:         m4
+" Maintainer:       Nikolai Weibull <now@bitwi.se>
+" Latest Revision:  2006-04-19
+
+if exists("b:did_ftplugin")
+  finish
+endif
+let b:did_ftplugin = 1
+
+let b:undo_ftplugin = "setl com< cms< fo<"
+
+setlocal comments=:#,:dnl commentstring=dnl\ %s
+setlocal formatoptions-=t formatoptions+=croql
--- /dev/null
+++ b/lib/vimfiles/ftplugin/mail.vim
@@ -1,0 +1,35 @@
+" Vim filetype plugin file
+" Language:	Mail
+" Maintainer:	Bram Moolenaar <Bram@vim.org>
+" Last Change:	2007 Apr 30
+
+" Only do this when not done yet for this buffer
+if exists("b:did_ftplugin")
+  finish
+endif
+let b:did_ftplugin = 1
+
+let b:undo_ftplugin = "setl modeline< tw< fo<"
+
+" Don't use modelines in e-mail messages, avoid trojan horses and nasty
+" "jokes" (e.g., setting 'textwidth' to 5).
+setlocal nomodeline
+
+" many people recommend keeping e-mail messages 72 chars wide
+if &tw == 0
+  setlocal tw=72
+endif
+
+" Set 'formatoptions' to break text lines and keep the comment leader ">".
+setlocal fo+=tcql
+
+" Add mappings, unless the user didn't want this.
+if !exists("no_plugin_maps") && !exists("no_mail_maps")
+  " Quote text by inserting "> "
+  if !hasmapto('<Plug>MailQuote')
+    vmap <buffer> <LocalLeader>q <Plug>MailQuote
+    nmap <buffer> <LocalLeader>q <Plug>MailQuote
+  endif
+  vnoremap <buffer> <Plug>MailQuote :s/^/> /<CR>:noh<CR>``
+  nnoremap <buffer> <Plug>MailQuote :.,$s/^/> /<CR>:noh<CR>``
+endif
--- /dev/null
+++ b/lib/vimfiles/ftplugin/mailaliases.vim
@@ -1,0 +1,12 @@
+" Vim filetype plugin file
+" Maintainer:       Nikolai Weibull <now@bitwi.se>
+" Latest Revision:  2006-03-27
+
+if exists("b:did_ftplugin")
+  finish
+endif
+let b:did_ftplugin = 1
+
+let b:undo_ftplugin = "setl com< cms< fo<"
+
+setlocal comments=:# commentstring=#\ %s formatoptions-=t formatoptions+=croql
--- /dev/null
+++ b/lib/vimfiles/ftplugin/mailcap.vim
@@ -1,0 +1,13 @@
+" Vim filetype plugin file
+" Language:         Mailcap configuration file
+" Maintainer:       Nikolai Weibull <now@bitwi.se>
+" Latest Revision:  2006-04-19
+
+if exists("b:did_ftplugin")
+  finish
+endif
+let b:did_ftplugin = 1
+
+let b:undo_ftplugin = "setl com< cms< fo<"
+
+setlocal comments=:# commentstring=#\ %s formatoptions-=t formatoptions+=croql
--- /dev/null
+++ b/lib/vimfiles/ftplugin/make.vim
@@ -1,0 +1,28 @@
+" Vim filetype plugin file
+" Language:	Make
+" Maintainer:	Bram Moolenaar <Bram@vim.org>
+" Last Change:	2006 Jun 17
+
+" Only do this when not done yet for this buffer
+if exists("b:did_ftplugin")
+  finish
+endif
+let b:did_ftplugin = 1
+
+let b:undo_ftplugin = "setl et< sts< fo< com< cms< inc<"
+
+" Make sure a hard tab is used, required for most make programs
+setlocal noexpandtab softtabstop=0
+
+" Set 'formatoptions' to break comment lines but not other lines,
+" and insert the comment leader when hitting <CR> or using "o".
+setlocal fo-=t fo+=croql
+
+" Set 'comments' to format dashed lists in comments
+setlocal com=sO:#\ -,mO:#\ \ ,b:#
+
+" Set 'commentstring' to put the marker after a #.
+setlocal commentstring=#\ %s
+
+" Including files.
+let &l:include = '^\s*include'
--- /dev/null
+++ b/lib/vimfiles/ftplugin/man.vim
@@ -1,0 +1,178 @@
+" Vim filetype plugin file
+" Language:	man
+" Maintainer:	Nam SungHyun <namsh@kldp.org>
+" Last Change:	2006 Dec 04
+
+" To make the ":Man" command available before editing a manual page, source
+" this script from your startup vimrc file.
+
+" If 'filetype' isn't "man", we must have been called to only define ":Man".
+if &filetype == "man"
+
+  " Only do this when not done yet for this buffer
+  if exists("b:did_ftplugin")
+    finish
+  endif
+  let b:did_ftplugin = 1
+
+  " allow dot and dash in manual page name.
+  setlocal iskeyword+=\.,-
+
+  " Add mappings, unless the user didn't want this.
+  if !exists("no_plugin_maps") && !exists("no_man_maps")
+    if !hasmapto('<Plug>ManBS')
+      nmap <buffer> <LocalLeader>h <Plug>ManBS
+    endif
+    nnoremap <buffer> <Plug>ManBS :%s/.\b//g<CR>:setl nomod<CR>''
+
+    nnoremap <buffer> <c-]> :call <SID>PreGetPage(v:count)<CR>
+    nnoremap <buffer> <c-t> :call <SID>PopPage()<CR>
+  endif
+
+endif
+
+if exists(":Man") != 2
+  com -nargs=+ Man call s:GetPage(<f-args>)
+  nmap <Leader>K :call <SID>PreGetPage(0)<CR>
+endif
+
+" Define functions only once.
+if !exists("s:man_tag_depth")
+
+let s:man_tag_depth = 0
+
+if !has("win32") && $OSTYPE !~ 'cygwin\|linux' && system('uname -s') =~ "SunOS" && system('uname -r') =~ "^5"
+  let s:man_sect_arg = "-s"
+  let s:man_find_arg = "-l"
+else
+  let s:man_sect_arg = ""
+  let s:man_find_arg = "-w"
+endif
+
+func <SID>PreGetPage(cnt)
+  if a:cnt == 0
+    let old_isk = &iskeyword
+    setl iskeyword+=(,)
+    let str = expand("<cword>")
+    let &l:iskeyword = old_isk
+    let page = substitute(str, '(*\(\k\+\).*', '\1', '')
+    let sect = substitute(str, '\(\k\+\)(\([^()]*\)).*', '\2', '')
+    if match(sect, '^[0-9 ]\+$') == -1
+      let sect = ""
+    endif
+    if sect == page
+      let sect = ""
+    endif
+  else
+    let sect = a:cnt
+    let page = expand("<cword>")
+  endif
+  call s:GetPage(sect, page)
+endfunc
+
+func <SID>GetCmdArg(sect, page)
+  if a:sect == ''
+    return a:page
+  endif
+  return s:man_sect_arg.' '.a:sect.' '.a:page
+endfunc
+
+func <SID>FindPage(sect, page)
+  let where = system("/usr/bin/man ".s:man_find_arg.' '.s:GetCmdArg(a:sect, a:page))
+  if where !~ "^/"
+    if matchstr(where, " [^ ]*$") !~ "^ /"
+      return 0
+    endif
+  endif
+  return 1
+endfunc
+
+func <SID>GetPage(...)
+  if a:0 >= 2
+    let sect = a:1
+    let page = a:2
+  elseif a:0 >= 1
+    let sect = ""
+    let page = a:1
+  else
+    return
+  endif
+
+  " To support:	    nmap K :Man <cword>
+  if page == '<cword>'
+    let page = expand('<cword>')
+  endif
+
+  if sect != "" && s:FindPage(sect, page) == 0
+    let sect = ""
+  endif
+  if s:FindPage(sect, page) == 0
+    echo "\nCannot find a '".page."'."
+    return
+  endif
+  exec "let s:man_tag_buf_".s:man_tag_depth." = ".bufnr("%")
+  exec "let s:man_tag_lin_".s:man_tag_depth." = ".line(".")
+  exec "let s:man_tag_col_".s:man_tag_depth." = ".col(".")
+  let s:man_tag_depth = s:man_tag_depth + 1
+
+  " Use an existing "man" window if it exists, otherwise open a new one.
+  if &filetype != "man"
+    let thiswin = winnr()
+    exe "norm! \<C-W>b"
+    if winnr() > 1
+      exe "norm! " . thiswin . "\<C-W>w"
+      while 1
+	if &filetype == "man"
+	  break
+	endif
+	exe "norm! \<C-W>w"
+	if thiswin == winnr()
+	  break
+	endif
+      endwhile
+    endif
+    if &filetype != "man"
+      new
+      setl nonu fdc=0
+    endif
+  endif
+  silent exec "edit $HOME/".page.".".sect."~"
+  " Avoid warning for editing the dummy file twice
+  setl buftype=nofile noswapfile
+
+  setl ma
+  silent exec "norm 1GdG"
+  let $MANWIDTH = winwidth(0)
+  silent exec "r!/usr/bin/man ".s:GetCmdArg(sect, page)." | col -b"
+  " Remove blank lines from top and bottom.
+  while getline(1) =~ '^\s*$'
+    silent norm ggdd
+  endwhile
+  while getline('$') =~ '^\s*$'
+    silent norm Gdd
+  endwhile
+  1
+  setl ft=man nomod
+  setl bufhidden=hide
+  setl nobuflisted
+endfunc
+
+func <SID>PopPage()
+  if s:man_tag_depth > 0
+    let s:man_tag_depth = s:man_tag_depth - 1
+    exec "let s:man_tag_buf=s:man_tag_buf_".s:man_tag_depth
+    exec "let s:man_tag_lin=s:man_tag_lin_".s:man_tag_depth
+    exec "let s:man_tag_col=s:man_tag_col_".s:man_tag_depth
+    exec s:man_tag_buf."b"
+    exec s:man_tag_lin
+    exec "norm ".s:man_tag_col."|"
+    exec "unlet s:man_tag_buf_".s:man_tag_depth
+    exec "unlet s:man_tag_lin_".s:man_tag_depth
+    exec "unlet s:man_tag_col_".s:man_tag_depth
+    unlet s:man_tag_buf s:man_tag_lin s:man_tag_col
+  endif
+endfunc
+
+endif
+
+" vim: set sw=2:
--- /dev/null
+++ b/lib/vimfiles/ftplugin/manconf.vim
@@ -1,0 +1,13 @@
+" Vim filetype plugin file
+" Language:         man.conf(5) - man configuration file
+" Maintainer:       Nikolai Weibull <now@bitwi.se>
+" Latest Revision:  2006-04-19
+
+if exists("b:did_ftplugin")
+  finish
+endif
+let b:did_ftplugin = 1
+
+let b:undo_ftplugin = "setl com< cms< fo<"
+
+setlocal comments=:# commentstring=#\ %s formatoptions-=t formatoptions+=croql
--- /dev/null
+++ b/lib/vimfiles/ftplugin/matlab.vim
@@ -1,0 +1,30 @@
+" Vim filetype plugin file
+" Language:	matlab
+" Maintainer:	Jake Wasserman <jwasserman at gmail dot com>
+" Last Changed: 2006 Jan 12
+
+if exists("b:did_ftplugin")
+	finish
+endif
+let b:did_ftplugin = 1
+
+let s:save_cpo = &cpo
+set cpo-=C
+
+if exists("loaded_matchit")
+	let s:conditionalEnd = '\(([^()]*\)\@!\<end\>\([^()]*)\)\@!'
+	let b:match_words = '\<if\>\|\<while\>\|\<for\>\|\<switch\>:' .
+		\ s:conditionalEnd . ',\<if\>:\<elseif\>:\<else\>:' .
+		\ s:conditionalEnd
+endif
+
+setlocal suffixesadd=.m
+setlocal suffixes+=.asv
+
+let b:undo_ftplugin = "setlocal suffixesadd< suffixes< "
+	\ . "| unlet! b:match_words"
+
+let &cpo = s:save_cpo
+
+
+
--- /dev/null
+++ b/lib/vimfiles/ftplugin/mf.vim
@@ -1,0 +1,14 @@
+" Vim filetype plugin file
+" Language:         MetaFont
+" Maintainer:       Nikolai Weibull <now@bitwi.se>
+" Latest Revision:  2006-04-19
+
+if exists("b:did_ftplugin")
+  finish
+endif
+let b:did_ftplugin = 1
+
+let b:undo_ftplugin = "setl com< cms< fo<"
+
+setlocal comments=:% commentstring=%\ %s formatoptions-=t formatoptions+=croql
+
--- /dev/null
+++ b/lib/vimfiles/ftplugin/modconf.vim
@@ -1,0 +1,14 @@
+" Vim filetype plugin file
+" Language:         modules.conf(5) configuration file
+" Maintainer:       Nikolai Weibull <now@bitwi.se>
+" Latest Revision:  2006-04-19
+
+if exists("b:did_ftplugin")
+  finish
+endif
+let b:did_ftplugin = 1
+
+let b:undo_ftplugin = "setl com< cms< inc< fo<"
+
+setlocal comments=:# commentstring=#\ %s include=^\\s*include
+setlocal formatoptions-=t formatoptions+=croql
--- /dev/null
+++ b/lib/vimfiles/ftplugin/mp.vim
@@ -1,0 +1,22 @@
+" Vim filetype plugin file
+" Language:         MetaPost
+" Maintainer:       Nikolai Weibull <now@bitwi.se>
+" Latest Revision:  2006-07-04
+
+if exists("b:did_ftplugin")
+  finish
+endif
+let b:did_ftplugin = 1
+
+let b:undo_ftplugin = "setl com< cms< fo<"
+
+setlocal comments=:% commentstring=%\ %s formatoptions-=t formatoptions+=croql
+
+if exists(":FixBeginfigs") != 2
+  command -nargs=0 FixBeginfigs call s:fix_beginfigs()
+
+  function! s:fix_beginfigs()
+    let i = 1
+    g/^beginfig(\d*);$/s//\='beginfig('.i.');'/ | let i = i + 1
+  endfunction
+endif
--- /dev/null
+++ b/lib/vimfiles/ftplugin/mplayerconf.vim
@@ -1,0 +1,14 @@
+" Vim filetype plugin file
+" Language:         mplayer(1) configuration file
+" Maintainer:       Nikolai Weibull <now@bitwi.se>
+" Latest Revision:  2006-04-19
+
+if exists("b:did_ftplugin")
+  finish
+endif
+let b:did_ftplugin = 1
+
+let b:undo_ftplugin = "setl com< cms< inc< fo<"
+
+setlocal comments=:# commentstring=#\ %s include=^\\s*include
+setlocal formatoptions-=t formatoptions+=croql
--- /dev/null
+++ b/lib/vimfiles/ftplugin/mrxvtrc.vim
@@ -1,0 +1,22 @@
+" Created	: Wed 26 Apr 2006 01:20:53 AM CDT
+" Modified	: Fri 28 Apr 2006 03:24:01 AM CDT
+" Author	: Gautam Iyer <gi1242@users.sourceforge.net>
+" Description	: ftplugin for mrxvtrc
+
+if exists("b:did_ftplugin")
+  finish
+endif
+let b:did_ftplugin = 1
+
+let b:undo_ftplugin = "setl com< cms< fo<"
+
+" Really any line that does not match an option is a comment. But use '!' for
+" compatibility with x-defaults files, and "#" (preferred) for compatibility
+" with all other config files.
+"
+" Comments beginning with "#" are preferred because Vim will not flag the
+" first word as a spelling error if it is not capitalised. The '!' used as
+" comment leaders makes Vim think that every comment line is a new sentence.
+
+setlocal comments=:!,:# commentstring=#\ %s
+setlocal formatoptions-=t formatoptions+=croql
--- /dev/null
+++ b/lib/vimfiles/ftplugin/mupad.vim
@@ -1,0 +1,30 @@
+" Vim filetype plugin file
+" Language:    MuPAD source files
+" Maintainer:  Dave Silvia <dsilvia@mchsi.com>
+" Filenames:   *.mu
+" Date:        6/30/2004
+
+if exists("b:did_ftplugin") | finish | endif
+let b:did_ftplugin = 1
+
+" Change the :browse e filter to primarily show MuPAD source files.
+if has("gui_win32")
+  let  b:browsefilter=
+		\ "MuPAD source (*.mu)\t*.mu\n" .
+		\	"All Files (*.*)\t*.*\n"
+endif
+
+" matchit.vim not loaded -- don't do anyting below
+if !exists("loaded_matchit")
+	" echomsg "matchit.vim not loaded -- finishing"
+	finish
+endif
+
+" source the AppendMatchGroup function file
+runtime ftplugin/AppendMatchGroup.vim
+
+" fill b:match_words for MuPAD
+call AppendMatchGroup('domain,end_domain')
+call AppendMatchGroup('proc,begin,end_proc')
+call AppendMatchGroup('if,then,elif,else,end_if')
+call AppendMatchGroup('\%(for\|while\|repeat\|case\),of,do,break,next,until,\%(end_for\|end_while\|end_repeat\|end_case\)')
--- /dev/null
+++ b/lib/vimfiles/ftplugin/muttrc.vim
@@ -1,0 +1,16 @@
+" Vim filetype plugin file
+" Language:         mutt RC File
+" Maintainer:       Nikolai Weibull <now@bitwi.se>
+" Latest Revision:  2006-04-19
+
+if exists("b:did_ftplugin")
+  finish
+endif
+let b:did_ftplugin = 1
+
+let b:undo_ftplugin = "setl com< cms< inc< fo<"
+
+setlocal comments=:# commentstring=#\ %s
+setlocal formatoptions-=t formatoptions+=croql
+
+let &l:include = '^\s*source\>'
--- /dev/null
+++ b/lib/vimfiles/ftplugin/nanorc.vim
@@ -1,0 +1,13 @@
+" Vim filetype plugin file
+" Language:         nanorc(5) - GNU nano configuration file
+" Maintainer:       Nikolai Weibull <now@bitwi.se>
+" Latest Revision:  2006-04-19
+
+if exists("b:did_ftplugin")
+  finish
+endif
+let b:did_ftplugin = 1
+
+let b:undo_ftplugin = "setl com< cms< fo<"
+
+setlocal comments=:# commentstring=#\ %s formatoptions-=t formatoptions+=croql
--- /dev/null
+++ b/lib/vimfiles/ftplugin/netrc.vim
@@ -1,0 +1,13 @@
+" Vim filetype plugin file
+" Language:         netrc(5) configuration file
+" Maintainer:       Nikolai Weibull <now@bitwi.se>
+" Latest Revision:  2006-04-19
+
+if exists("b:did_ftplugin")
+  finish
+endif
+let b:did_ftplugin = 1
+
+let b:undo_ftplugin = "setl com< cms< fo<"
+
+setlocal comments= commentstring= formatoptions-=tcroq formatoptions+=l
--- /dev/null
+++ b/lib/vimfiles/ftplugin/objc.vim
@@ -1,0 +1,12 @@
+" Vim filetype plugin file
+" Language:	Objective C
+" Maintainer:	Bram Moolenaar <Bram@vim.org>
+" Last Change:	2003 Jan 15
+
+" Only do this when not done yet for this buffer
+if exists("b:did_ftplugin")
+  finish
+endif
+
+" Behaves just like C
+runtime! ftplugin/c.vim ftplugin/c_*.vim ftplugin/c/*.vim
--- /dev/null
+++ b/lib/vimfiles/ftplugin/ocaml.vim
@@ -1,0 +1,382 @@
+" Language:    OCaml
+" Maintainer:  David Baelde        <firstname.name@ens-lyon.org>
+"              Mike Leary          <leary@nwlink.com>
+"              Markus Mottl        <markus.mottl@gmail.com>
+"              Stefano Zacchiroli  <zack@bononia.it>
+" URL:         http://www.ocaml.info/vim/ftplugin/ocaml.vim
+" Last Change: 2006 May 01 - Added .annot support for file.whateverext (SZ)
+"	       2006 Apr 11 - Fixed an initialization bug; fixed ASS abbrev (MM)
+"              2005 Oct 13 - removed GPL; better matchit support (MM, SZ)
+"
+if exists("b:did_ftplugin")
+  finish
+endif
+let b:did_ftplugin=1
+
+" Error handling -- helps moving where the compiler wants you to go
+let s:cposet=&cpoptions
+set cpo-=C
+setlocal efm=
+      \%EFile\ \"%f\"\\,\ line\ %l\\,\ characters\ %c-%*\\d:,
+      \%EFile\ \"%f\"\\,\ line\ %l\\,\ character\ %c:%m,
+      \%+EReference\ to\ unbound\ regexp\ name\ %m,
+      \%Eocamlyacc:\ e\ -\ line\ %l\ of\ \"%f\"\\,\ %m,
+      \%Wocamlyacc:\ w\ -\ %m,
+      \%-Zmake%.%#,
+      \%C%m,
+      \%D%*\\a[%*\\d]:\ Entering\ directory\ `%f',
+      \%X%*\\a[%*\\d]:\ Leaving\ directory\ `%f',
+      \%D%*\\a:\ Entering\ directory\ `%f',
+      \%X%*\\a:\ Leaving\ directory\ `%f',
+      \%DMaking\ %*\\a\ in\ %f
+
+" Add mappings, unless the user didn't want this.
+if !exists("no_plugin_maps") && !exists("no_ocaml_maps")
+  " (un)commenting
+  if !hasmapto('<Plug>Comment')
+    nmap <buffer> <LocalLeader>c <Plug>LUncomOn
+    vmap <buffer> <LocalLeader>c <Plug>BUncomOn
+    nmap <buffer> <LocalLeader>C <Plug>LUncomOff
+    vmap <buffer> <LocalLeader>C <Plug>BUncomOff
+  endif
+
+  nnoremap <buffer> <Plug>LUncomOn mz0i(* <ESC>$A *)<ESC>`z
+  nnoremap <buffer> <Plug>LUncomOff :s/^(\* \(.*\) \*)/\1/<CR>:noh<CR>
+  vnoremap <buffer> <Plug>BUncomOn <ESC>:'<,'><CR>`<O<ESC>0i(*<ESC>`>o<ESC>0i*)<ESC>`<
+  vnoremap <buffer> <Plug>BUncomOff <ESC>:'<,'><CR>`<dd`>dd`<
+
+  if !hasmapto('<Plug>Abbrev')
+    iabbrev <buffer> ASS (assert (0=1) (* XXX *))
+  endif
+endif
+
+" Let % jump between structure elements (due to Issac Trotts)
+let b:mw = ''
+let b:mw = b:mw . ',\<let\>:\<and\>:\(\<in\>\|;;\)'
+let b:mw = b:mw . ',\<if\>:\<then\>:\<else\>'
+let b:mw = b:mw . ',\<\(for\|while\)\>:\<do\>:\<done\>,'
+let b:mw = b:mw . ',\<\(object\|sig\|struct\|begin\)\>:\<end\>'
+let b:mw = b:mw . ',\<\(match\|try\)\>:\<with\>'
+let b:match_words = b:mw
+
+let b:match_ignorecase=0
+
+" switching between interfaces (.mli) and implementations (.ml)
+if !exists("g:did_ocaml_switch")
+  let g:did_ocaml_switch = 1
+  map <LocalLeader>s :call OCaml_switch(0)<CR>
+  map <LocalLeader>S :call OCaml_switch(1)<CR>
+  fun OCaml_switch(newwin)
+    if (match(bufname(""), "\\.mli$") >= 0)
+      let fname = substitute(bufname(""), "\\.mli$", ".ml", "")
+      if (a:newwin == 1)
+        exec "new " . fname
+      else
+        exec "arge " . fname
+      endif
+    elseif (match(bufname(""), "\\.ml$") >= 0)
+      let fname = bufname("") . "i"
+      if (a:newwin == 1)
+        exec "new " . fname
+      else
+        exec "arge " . fname
+      endif
+    endif
+  endfun
+endif
+
+" Folding support
+
+" Get the modeline because folding depends on indentation
+let s:s = line2byte(line('.'))+col('.')-1
+if search('^\s*(\*:o\?caml:')
+  let s:modeline = getline(".")
+else
+  let s:modeline = ""
+endif
+if s:s > 0
+  exe 'goto' s:s
+endif
+
+" Get the indentation params
+let s:m = matchstr(s:modeline,'default\s*=\s*\d\+')
+if s:m != ""
+  let s:idef = matchstr(s:m,'\d\+')
+elseif exists("g:omlet_indent")
+  let s:idef = g:omlet_indent
+else
+  let s:idef = 2
+endif
+let s:m = matchstr(s:modeline,'struct\s*=\s*\d\+')
+if s:m != ""
+  let s:i = matchstr(s:m,'\d\+')
+elseif exists("g:omlet_indent_struct")
+  let s:i = g:omlet_indent_struct
+else
+  let s:i = s:idef
+endif
+
+" Set the folding method
+if exists("g:ocaml_folding")
+  setlocal foldmethod=expr
+  setlocal foldexpr=OMLetFoldLevel(v:lnum)
+endif
+
+" - Only definitions below, executed once -------------------------------------
+
+if exists("*OMLetFoldLevel")
+  finish
+endif
+
+function s:topindent(lnum)
+  let l = a:lnum
+  while l > 0
+    if getline(l) =~ '\s*\%(\<struct\>\|\<sig\>\|\<object\>\)'
+      return indent(l)
+    endif
+    let l = l-1
+  endwhile
+  return -s:i
+endfunction
+
+function OMLetFoldLevel(l)
+
+  " This is for not merging blank lines around folds to them
+  if getline(a:l) !~ '\S'
+    return -1
+  endif
+
+  " We start folds for modules, classes, and every toplevel definition
+  if getline(a:l) =~ '^\s*\%(\<val\>\|\<module\>\|\<class\>\|\<type\>\|\<method\>\|\<initializer\>\|\<inherit\>\|\<exception\>\|\<external\>\)'
+    exe 'return ">' (indent(a:l)/s:i)+1 '"'
+  endif
+
+  " Toplevel let are detected thanks to the indentation
+  if getline(a:l) =~ '^\s*let\>' && indent(a:l) == s:i+s:topindent(a:l)
+    exe 'return ">' (indent(a:l)/s:i)+1 '"'
+  endif
+
+  " We close fold on end which are associated to struct, sig or object.
+  " We use syntax information to do that.
+  if getline(a:l) =~ '^\s*end\>' && synIDattr(synID(a:l, indent(a:l)+1, 0), "name") != "ocamlKeyword"
+    return (indent(a:l)/s:i)+1
+  endif
+
+  " Folds end on ;;
+  if getline(a:l) =~ '^\s*;;'
+    exe 'return "<' (indent(a:l)/s:i)+1 '"'
+  endif
+
+  " Comments around folds aren't merged to them.
+  if synIDattr(synID(a:l, indent(a:l)+1, 0), "name") == "ocamlComment"
+    return -1
+  endif
+
+  return '='
+endfunction
+
+" Vim support for OCaml .annot files (requires Vim with python support)
+"
+" Executing OCamlPrintType(<mode>) function will display in the Vim bottom
+" line(s) the type of an ocaml value getting it from the corresponding .annot
+" file (if any).  If Vim is in visual mode, <mode> should be "visual" and the
+" selected ocaml value correspond to the highlighted text, otherwise (<mode>
+" can be anything else) it corresponds to the literal found at the current
+" cursor position.
+"
+" .annot files are parsed lazily the first time OCamlPrintType is invoked; is
+" also possible to force the parsing using the OCamlParseAnnot() function.
+"
+" Typing ',3' will cause OCamlPrintType function to be invoked with
+" the right argument depending on the current mode (visual or not).
+"
+" Copyright (C) <2003-2004> Stefano Zacchiroli <zack@bononia.it>
+"
+" Created:        Wed, 01 Oct 2003 18:16:22 +0200 zack
+" LastModified:   Wed, 25 Aug 2004 18:28:39 +0200 zack
+
+if !has("python")
+  finish
+endif
+
+python << EOF
+
+import re
+import os
+import os.path
+import string
+import time
+import vim
+
+debug = False
+
+class AnnExc(Exception):
+    def __init__(self, reason):
+        self.reason = reason
+
+no_annotations = AnnExc("No type annotations (.annot) file found")
+annotation_not_found = AnnExc("No type annotation found for the given text")
+def malformed_annotations(lineno):
+    return AnnExc("Malformed .annot file (line = %d)" % lineno)
+
+class Annotations:
+    """
+      .annot ocaml file representation
+
+      File format (copied verbatim from caml-types.el)
+
+      file ::= block *
+      block ::= position <SP> position <LF> annotation *
+      position ::= filename <SP> num <SP> num <SP> num
+      annotation ::= keyword open-paren <LF> <SP> <SP> data <LF> close-paren
+
+      <SP> is a space character (ASCII 0x20)
+      <LF> is a line-feed character (ASCII 0x0A)
+      num is a sequence of decimal digits
+      filename is a string with the lexical conventions of O'Caml
+      open-paren is an open parenthesis (ASCII 0x28)
+      close-paren is a closed parenthesis (ASCII 0x29)
+      data is any sequence of characters where <LF> is always followed by
+           at least two space characters.
+
+      - in each block, the two positions are respectively the start and the
+        end of the range described by the block.
+      - in a position, the filename is the name of the file, the first num
+        is the line number, the second num is the offset of the beginning
+        of the line, the third num is the offset of the position itself.
+      - the char number within the line is the difference between the third
+        and second nums.
+
+      For the moment, the only possible keyword is \"type\"."
+    """
+
+    def __init__(self):
+        self.__filename = None  # last .annot parsed file
+        self.__ml_filename = None # as above but s/.annot/.ml/
+        self.__timestamp = None # last parse action timestamp
+        self.__annot = {}
+        self.__re = re.compile(
+          '^"[^"]*"\s+(\d+)\s+(\d+)\s+(\d+)\s+"[^"]*"\s+(\d+)\s+(\d+)\s+(\d+)$')
+
+    def __parse(self, fname):
+        try:
+            f = open(fname)
+            line = f.readline() # position line
+            lineno = 1
+            while (line != ""):
+                m = self.__re.search(line)
+                if (not m):
+                    raise malformed_annotations(lineno)
+                line1 = int(m.group(1))
+                col1 = int(m.group(3)) - int(m.group(2))
+                line2 = int(m.group(4))
+                col2 = int(m.group(6)) - int(m.group(5))
+                line = f.readline() # "type(" string
+                lineno += 1
+                if (line == ""): raise malformed_annotations(lineno)
+                type = []
+                line = f.readline() # type description
+                lineno += 1
+                if (line == ""): raise malformed_annotations(lineno)
+                while line != ")\n":
+                    type.append(string.strip(line))
+                    line = f.readline()
+                    lineno += 1
+                    if (line == ""): raise malformed_annotations(lineno)
+                type = string.join(type, "\n")
+                key = ((line1, col1), (line2, col2))
+                if not self.__annot.has_key(key):
+                    self.__annot[key] = type
+                line = f.readline() # position line
+            f.close()
+            self.__filename = fname
+            self.__ml_filename = vim.current.buffer.name
+            self.__timestamp = int(time.time())
+        except IOError:
+            raise no_annotations
+
+    def parse(self):
+        annot_file = os.path.splitext(vim.current.buffer.name)[0] + ".annot"
+        self.__parse(annot_file)
+
+    def get_type(self, (line1, col1), (line2, col2)):
+        if debug:
+            print line1, col1, line2, col2
+        if vim.current.buffer.name == None:
+            raise no_annotations
+        if vim.current.buffer.name != self.__ml_filename or  \
+          os.stat(self.__filename).st_mtime > self.__timestamp:
+            self.parse()
+        try:
+            return self.__annot[(line1, col1), (line2, col2)]
+        except KeyError:
+            raise annotation_not_found
+
+word_char_RE = re.compile("^[\w.]$")
+
+  # TODO this function should recognize ocaml literals, actually it's just an
+  # hack that recognize continuous sequences of word_char_RE above
+def findBoundaries(line, col):
+    """ given a cursor position (as returned by vim.current.window.cursor)
+    return two integers identify the beggining and end column of the word at
+    cursor position, if any. If no word is at the cursor position return the
+    column cursor position twice """
+    left, right = col, col
+    line = line - 1 # mismatch vim/python line indexes
+    (begin_col, end_col) = (0, len(vim.current.buffer[line]) - 1)
+    try:
+        while word_char_RE.search(vim.current.buffer[line][left - 1]):
+            left = left - 1
+    except IndexError:
+        pass
+    try:
+        while word_char_RE.search(vim.current.buffer[line][right + 1]):
+            right = right + 1
+    except IndexError:
+        pass
+    return (left, right)
+
+annot = Annotations() # global annotation object
+
+def printOCamlType(mode):
+    try:
+        if mode == "visual":  # visual mode: lookup highlighted text
+            (line1, col1) = vim.current.buffer.mark("<")
+            (line2, col2) = vim.current.buffer.mark(">")
+        else: # any other mode: lookup word at cursor position
+            (line, col) = vim.current.window.cursor
+            (col1, col2) = findBoundaries(line, col)
+            (line1, line2) = (line, line)
+        begin_mark = (line1, col1)
+        end_mark = (line2, col2 + 1)
+        print annot.get_type(begin_mark, end_mark)
+    except AnnExc, exc:
+        print exc.reason
+
+def parseOCamlAnnot():
+    try:
+        annot.parse()
+    except AnnExc, exc:
+        print exc.reason
+
+EOF
+
+fun! OCamlPrintType(current_mode)
+  if (a:current_mode == "visual")
+    python printOCamlType("visual")
+  else
+    python printOCamlType("normal")
+  endif
+endfun
+
+fun! OCamlParseAnnot()
+  python parseOCamlAnnot()
+endfun
+
+map <LocalLeader>t :call OCamlPrintType("normal")<RETURN>
+vmap <LocalLeader>t :call OCamlPrintType("visual")<RETURN>
+
+let &cpoptions=s:cposet
+unlet s:cposet
+
+" vim:sw=2
--- /dev/null
+++ b/lib/vimfiles/ftplugin/occam.vim
@@ -1,0 +1,39 @@
+" Vim filetype plugin file
+" Language:	occam
+" Copyright:	Christian Jacobsen <clj3@kent.ac.uk>, Mario Schweigler <ms44@kent.ac.uk>
+" Maintainer:	Mario Schweigler <ms44@kent.ac.uk>
+" Last Change:	23 April 2003
+
+" Only do this when not done yet for this buffer
+if exists("b:did_ftplugin")
+  finish
+endif
+let b:did_ftplugin = 1
+
+"{{{  Indent settings
+" Set shift width for indent
+setlocal shiftwidth=2
+" Set the tab key size to two spaces
+setlocal softtabstop=2
+" Let tab keys always be expanded to spaces
+setlocal expandtab
+"}}}
+
+"{{{  Formatting
+" Break comment lines and insert comment leader in this case
+setlocal formatoptions-=t formatoptions+=cql
+setlocal comments+=:--
+" Maximum length of comments is 78
+setlocal textwidth=78
+"}}}
+
+"{{{  File browsing filters
+" Win32 can filter files in the browse dialog
+if has("gui_win32") && !exists("b:browsefilter")
+  let b:browsefilter = "All Occam Files (*.occ *.inc)\t*.occ;*.inc\n" .
+	\ "Occam Include Files (*.inc)\t*.inc\n" .
+	\ "Occam Source Files (*.occ)\t*.occ\n" .
+	\ "All Files (*.*)\t*.*\n"
+endif
+"}}}
+
--- /dev/null
+++ b/lib/vimfiles/ftplugin/pamconf.vim
@@ -1,0 +1,13 @@
+" Vim filetype plugin file
+" Language:         pam(8) configuration file
+" Maintainer:       Nikolai Weibull <now@bitwi.se>
+" Latest Revision:  2006-04-19
+
+if exists("b:did_ftplugin")
+  finish
+endif
+let b:did_ftplugin = 1
+
+let b:undo_ftplugin = "setl com< cms< fo<"
+
+setlocal comments=:# commentstring=#\ %s formatoptions-=t formatoptions+=croql
--- /dev/null
+++ b/lib/vimfiles/ftplugin/pascal.vim
@@ -1,0 +1,15 @@
+" Vim filetype plugin file
+" Language:	pascal
+" Maintainer:	Dan Sharp <dwsharp at hotmail dot com>
+" Last Changed: 2005 Sep 05
+" URL:		http://mywebpage.netscape.com/sharppeople/vim/ftplugin
+
+if exists("b:did_ftplugin") | finish | endif
+let b:did_ftplugin = 1
+
+if exists("loaded_matchit")
+    let b:match_words='\<\%(begin\|case\|try\)\>:\<end\>'
+endif
+
+" Undo the stuff we changed.
+let b:undo_ftplugin = "unlet! b:match_words"
--- /dev/null
+++ b/lib/vimfiles/ftplugin/passwd.vim
@@ -1,0 +1,13 @@
+" Vim filetype plugin file
+" Language:         passwd(5) password file
+" Maintainer:       Nikolai Weibull <now@bitwi.se>
+" Latest Revision:  2006-04-19
+
+if exists("b:did_ftplugin")
+  finish
+endif
+let b:did_ftplugin = 1
+
+let b:undo_ftplugin = "setl com< cms< fo<"
+
+setlocal comments= commentstring= formatoptions-=tcroq formatoptions+=l
--- /dev/null
+++ b/lib/vimfiles/ftplugin/perl.vim
@@ -1,0 +1,66 @@
+" Vim filetype plugin file
+" Language:	Perl
+" Maintainer:	Dan Sharp <dwsharp at hotmail dot com>
+" Last Change:  2005 Dec 16
+" URL:		http://mywebpage.netscape.com/sharppeople/vim/ftplugin
+
+if exists("b:did_ftplugin") | finish | endif
+let b:did_ftplugin = 1
+
+" Make sure the continuation lines below do not cause problems in
+" compatibility mode.
+let s:save_cpo = &cpo
+set cpo-=C
+
+setlocal formatoptions+=crq
+
+setlocal comments=:#
+setlocal commentstring=#%s
+
+" Change the browse dialog on Win32 to show mainly Perl-related files
+if has("gui_win32")
+    let b:browsefilter = "Perl Source Files (*.pl)\t*.pl\n" .
+		       \ "Perl Modules (*.pm)\t*.pm\n" .
+		       \ "Perl Documentation Files (*.pod)\t*.pod\n" .
+		       \ "All Files (*.*)\t*.*\n"
+endif
+
+" Provided by Ned Konz <ned at bike-nomad dot com>
+"---------------------------------------------
+setlocal include=\\<\\(use\\\|require\\)\\>
+setlocal includeexpr=substitute(substitute(v:fname,'::','/','g'),'$','.pm','')
+setlocal define=[^A-Za-z_]
+
+" The following line changes a global variable but is necessary to make
+" gf and similar commands work.  The change to iskeyword was incorrect.
+" Thanks to Andrew Pimlott for pointing out the problem. If this causes a
+" problem for you, add an after/ftplugin/perl.vim file that contains
+"       set isfname-=:
+set isfname+=:
+"setlocal iskeyword=48-57,_,A-Z,a-z,:
+
+" Set this once, globally.
+if !exists("perlpath")
+    if executable("perl")
+	if &shellxquote != '"'
+	    let perlpath = system('perl -e "print join(q/,/,@INC)"')
+	else
+	    let perlpath = system("perl -e 'print join(q/,/,@INC)'")
+	endif
+	let perlpath = substitute(perlpath,',.$',',,','')
+    else
+	" If we can't call perl to get its path, just default to using the
+	" current directory and the directory of the current file.
+	let perlpath = ".,,"
+    endif
+endif
+
+let &l:path=perlpath
+"---------------------------------------------
+
+" Undo the stuff we changed.
+let b:undo_ftplugin = "setlocal fo< com< cms< inc< inex< def< isf<" .
+	    \	      " | unlet! b:browsefilter"
+
+" Restore the saved compatibility options.
+let &cpo = s:save_cpo
--- /dev/null
+++ b/lib/vimfiles/ftplugin/php.vim
@@ -1,0 +1,71 @@
+" Vim filetype plugin file
+" Language:	php
+" Maintainer:	Dan Sharp <dwsharp at hotmail dot com>
+" Last Changed: 2006 Jul 15
+" URL:		http://mywebpage.netscape.com/sharppeople/vim/ftplugin
+
+if exists("b:did_ftplugin") | finish | endif
+
+" Make sure the continuation lines below do not cause problems in
+" compatibility mode.
+let s:save_cpo = &cpo
+set cpo-=C
+
+" Define some defaults in case the included ftplugins don't set them.
+let s:undo_ftplugin = ""
+let s:browsefilter = "HTML Files (*.html, *.htm)\t*.html;*.htm\n" .
+	    \	     "All Files (*.*)\t*.*\n"
+let s:match_words = ""
+
+runtime! ftplugin/html.vim ftplugin/html_*.vim ftplugin/html/*.vim
+let b:did_ftplugin = 1
+
+" Override our defaults if these were set by an included ftplugin.
+if exists("b:undo_ftplugin")
+    let s:undo_ftplugin = b:undo_ftplugin
+endif
+if exists("b:browsefilter")
+    let s:browsefilter = b:browsefilter
+endif
+if exists("b:match_words")
+    let s:match_words = b:match_words
+endif
+if exists("b:match_skip")
+    unlet b:match_skip
+endif
+
+" Change the :browse e filter to primarily show PHP-related files.
+if has("gui_win32")
+    let  b:browsefilter="PHP Files (*.php)\t*.php\n" . s:browsefilter
+endif
+
+" ###
+" Provided by Mikolaj Machowski <mikmach at wp dot pl>
+setlocal include=\\\(require\\\|include\\\)\\\(_once\\\)\\\?
+setlocal iskeyword+=$
+if exists("loaded_matchit")
+    let b:match_words = '<?php:?>,\<switch\>:\<endswitch\>,' .
+		      \ '\<if\>:\<elseif\>:\<else\>:\<endif\>,' .
+		      \ '\<while\>:\<endwhile\>,' .
+		      \ '\<do\>:\<while\>,' .
+		      \ '\<for\>:\<endfor\>,' .
+		      \ '\<foreach\>:\<endforeach\>,' .
+                      \ '(:),[:],{:},' .
+		      \ s:match_words
+endif
+" ###
+
+if exists('&ofu')
+  setlocal ofu=phpcomplete#CompletePHP
+endif
+
+
+setlocal commentstring=/*%s*/
+
+" Undo the stuff we changed.
+let b:undo_ftplugin = "setlocal cms< inc< isk<" .
+	    \	      " | unlet! b:browsefilter b:match_words | " .
+	    \	      s:undo_ftplugin
+
+" Restore the saved compatibility options.
+let &cpo = s:save_cpo
--- /dev/null
+++ b/lib/vimfiles/ftplugin/pinfo.vim
@@ -1,0 +1,13 @@
+" Vim filetype plugin file
+" Language:         pinfo(1) configuration file
+" Maintainer:       Nikolai Weibull <now@bitwi.se>
+" Latest Revision:  2006-04-19
+
+if exists("b:did_ftplugin")
+  finish
+endif
+let b:did_ftplugin = 1
+
+let b:undo_ftplugin = "setl com< cms< fo<"
+
+setlocal comments=:# commentstring=#\ %s formatoptions-=t formatoptions+=croql
--- /dev/null
+++ b/lib/vimfiles/ftplugin/plaintex.vim
@@ -1,0 +1,36 @@
+" plain TeX filetype plugin
+" Language:     plain TeX (ft=plaintex)
+" Maintainer:   Benji Fisher, Ph.D. <benji@member.AMS.org>
+" Version:	1.1
+" Last Change:	Wed 19 Apr 2006
+
+" Only do this when not done yet for this buffer.
+if exists("b:did_ftplugin")
+  finish
+endif
+
+" Start with initex.  This will also define b:did_ftplugin and b:undo_ftplugin .
+source $VIMRUNTIME/ftplugin/initex.vim
+
+" Avoid problems if running in 'compatible' mode.
+let s:save_cpo = &cpo
+set cpo&vim
+
+let b:undo_ftplugin .= "| unlet! b:match_ignorecase b:match_skip b:match_words"
+
+" Allow "[d" to be used to find a macro definition:
+let &l:define .= '\|\\new\(count\|dimen\|skip\|muskip\|box\|toks\|read\|write'
+	\ .	'\|fam\|insert\)'
+
+" The following lines enable the macros/matchit.vim plugin for
+" extended matching with the % key.
+" There is no default meaning for \(...\) etc., but many users define one.
+if exists("loaded_matchit")
+  let b:match_ignorecase = 0
+    \ | let b:match_skip = 'r:\\\@<!\%(\\\\\)*%'
+    \ | let b:match_words = '(:),\[:],{:},\\(:\\),\\\[:\\],\\{:\\}'
+endif " exists("loaded_matchit")
+
+let &cpo = s:save_cpo
+
+" vim:sts=2:sw=2:
--- /dev/null
+++ b/lib/vimfiles/ftplugin/postscr.vim
@@ -1,0 +1,31 @@
+" Vim filetype plugin file
+" Language:     PostScript
+" Maintainer:   Mike Williams <mrw@eandem.co.uk>
+" Last Change:  27th June 2002
+
+" Only do this when not done yet for this buffer
+if exists("b:did_ftplugin")
+  finish
+endif
+
+" Don't load another plugin for this buffer
+let b:did_ftplugin = 1
+
+" PS comment formatting
+setlocal comments=b:%
+setlocal formatoptions-=t formatoptions+=rol
+
+" Define patterns for the matchit macro
+if !exists("b:match_words")
+  let b:match_ignorecase = 0
+  let b:match_words = '<<:>>,\<begin\>:\<end\>,\<save\>:\<restore\>,\<gsave\>:\<grestore\>'
+endif
+
+set cpo-=C
+
+" Define patterns for the browse file filter
+if has("gui_win32") && !exists("b:browsefilter")
+  let b:browsefilter = "PostScript Files (*.ps)\t*.ps\n" .
+    \ "EPS Files (*.eps)\t*.eps\n" .
+    \ "All Files (*.*)\t*.*\n"
+endif
--- /dev/null
+++ b/lib/vimfiles/ftplugin/procmail.vim
@@ -1,0 +1,15 @@
+" Vim filetype plugin file
+" Language:         procmail(1) configuration file
+" Maintainer:       Nikolai Weibull <now@bitwi.se>
+" Latest Revision:  2006-04-19
+
+if exists("b:did_ftplugin")
+  finish
+endif
+let b:did_ftplugin = 1
+
+let b:undo_ftplugin = "setl com< cms< inc< fo<"
+
+setlocal comments=:# commentstring=#\ %s formatoptions-=t formatoptions+=croql
+
+let &l:include = '^\s*INCLUDERC\>'
--- /dev/null
+++ b/lib/vimfiles/ftplugin/prolog.vim
@@ -1,0 +1,14 @@
+" Vim filetype plugin file
+" Language:         Prolog
+" Maintainer:       Nikolai Weibull <now@bitwi.se>
+" Latest Revision:  2006-04-19
+
+if exists("b:did_ftplugin")
+  finish
+endif
+let b:did_ftplugin = 1
+
+let b:undo_ftplugin = "setl com< cms< fo<"
+
+setlocal comments=s1:/*,mb:*,ex:*/,:% commentstring=%\ %s
+setlocal formatoptions-=t formatoptions+=croql
--- /dev/null
+++ b/lib/vimfiles/ftplugin/protocols.vim
@@ -1,0 +1,13 @@
+" Vim filetype plugin file
+" Language:         protocols(5) - Internet protocols definition file
+" Maintainer:       Nikolai Weibull <now@bitwi.se>
+" Latest Revision:  2006-04-19
+
+if exists("b:did_ftplugin")
+  finish
+endif
+let b:did_ftplugin = 1
+
+let b:undo_ftplugin = "setl com< cms< fo<"
+
+setlocal comments=:# commentstring=#\ %s formatoptions-=t formatoptions+=croql
--- /dev/null
+++ b/lib/vimfiles/ftplugin/pyrex.vim
@@ -1,0 +1,22 @@
+" Vim filetype plugin file
+" Language:	Pyrex
+" Maintainer:	Marco Barisione <marco.bari@people.it>
+" URL:		http://marcobari.altervista.org/pyrex_vim.html
+" Last Change:	2004 May 16
+
+" Only do this when not done yet for this buffer
+if exists("b:did_ftplugin")
+  finish
+endif
+
+" Behaves just like Python
+runtime! ftplugin/python.vim ftplugin/python_*.vim ftplugin/python/*.vim
+
+if has("gui_win32") && exists("b:browsefilter")
+    let  b:browsefilter = "Pyrex files (*.pyx,*.pxd)\t*.pyx;*.pxd\n" .
+			\ "Python Files (*.py)\t*.py\n" .
+			\ "C Source Files (*.c)\t*.c\n" .
+			\ "C Header Files (*.h)\t*.h\n" .
+			\ "C++ Source Files (*.cpp *.c++)\t*.cpp;*.c++\n" .
+			\ "All Files (*.*)\t*.*\n"
+endif
--- /dev/null
+++ b/lib/vimfiles/ftplugin/python.vim
@@ -1,0 +1,43 @@
+" Vim filetype plugin file
+" Language:	python
+" Maintainer:	Johannes Zellner <johannes@zellner.org>
+" Last Change:	Wed, 21 Apr 2004 13:13:08 CEST
+
+if exists("b:did_ftplugin") | finish | endif
+let b:did_ftplugin = 1
+
+setlocal cinkeys-=0#
+setlocal indentkeys-=0#
+setlocal include=\s*\\(from\\\|import\\)
+setlocal includeexpr=substitute(v:fname,'\\.','/','g')
+setlocal suffixesadd=.py
+setlocal comments-=:%
+setlocal commentstring=#%s
+
+setlocal omnifunc=pythoncomplete#Complete
+
+set wildignore+=*.pyc
+
+nnoremap <silent> <buffer> ]] :call <SID>Python_jump('/^\(class\\|def\)')<cr>
+nnoremap <silent> <buffer> [[ :call <SID>Python_jump('?^\(class\\|def\)')<cr>
+nnoremap <silent> <buffer> ]m :call <SID>Python_jump('/^\s*\(class\\|def\)')<cr>
+nnoremap <silent> <buffer> [m :call <SID>Python_jump('?^\s*\(class\\|def\)')<cr>
+
+if exists('*<SID>Python_jump') | finish | endif
+
+fun! <SID>Python_jump(motion) range
+    let cnt = v:count1
+    let save = @/    " save last search pattern
+    mark '
+    while cnt > 0
+	silent! exe a:motion
+	let cnt = cnt - 1
+    endwhile
+    call histdel('/', -1)
+    let @/ = save    " restore last search pattern
+endfun
+
+if has("gui_win32") && !exists("b:browsefilter")
+    let b:browsefilter = "Python Files (*.py)\t*.py\n" .
+		       \ "All Files (*.*)\t*.*\n"
+endif
--- /dev/null
+++ b/lib/vimfiles/ftplugin/quake.vim
@@ -1,0 +1,13 @@
+" Vim filetype plugin file
+" Language:         Quake[1-3] configuration file
+" Maintainer:       Nikolai Weibull <now@bitwi.se>
+" Latest Revision:  2006-04-19
+
+if exists("b:did_ftplugin")
+  finish
+endif
+let b:did_ftplugin = 1
+
+let b:undo_ftplugin = "setl com< cms< fo<"
+
+setlocal comments=:// commentstring=//\ %s formatoptions-=t formatoptions+=croql
--- /dev/null
+++ b/lib/vimfiles/ftplugin/racc.vim
@@ -1,0 +1,14 @@
+" Vim filetype plugin file
+" Language:         Racc input file
+" Maintainer:       Nikolai Weibull <now@bitwi.se>
+" Latest Revision:  2006-04-19
+
+if exists("b:did_ftplugin")
+  finish
+endif
+let b:did_ftplugin = 1
+
+let b:undo_ftplugin = "setl com< cms< fo<"
+
+setlocal comments=s1:/*,mb:*,ex:*/,:# commentstring=#\ %s
+setlocal formatoptions-=t formatoptions+=croql
--- /dev/null
+++ b/lib/vimfiles/ftplugin/readline.vim
@@ -1,0 +1,13 @@
+" Vim filetype plugin file
+" Language:         readline(3) configuration file
+" Maintainer:       Nikolai Weibull <now@bitwi.se>
+" Latest Revision:  2006-04-19
+
+if exists("b:did_ftplugin")
+  finish
+endif
+let b:did_ftplugin = 1
+
+let b:undo_ftplugin = "setl com< cms< fo<"
+
+setlocal comments=:# commentstring=#\ %s formatoptions-=t formatoptions+=croql
--- /dev/null
+++ b/lib/vimfiles/ftplugin/rnc.vim
@@ -1,0 +1,13 @@
+" Vim filetype plugin file
+" Language:         Relax NG compact syntax
+" Maintainer:       Nikolai Weibull <now@bitwi.se>
+" Latest Revision:  2006-04-19
+
+if exists("b:did_ftplugin")
+  finish
+endif
+let b:did_ftplugin = 1
+
+let b:undo_ftplugin = "setl com< cms< fo<"
+
+setlocal comments=:# commentstring=#\ %s formatoptions-=t formatoptions+=croql
--- /dev/null
+++ b/lib/vimfiles/ftplugin/rpl.vim
@@ -1,0 +1,20 @@
+" Vim filetype plugin file
+" Language:     RPL/2
+" Maintainer:   Jo�l BERTRAND <rpl2@free.fr>
+" Last Change:	2005 Mar 28
+" Version: 		0.1
+
+" Only do this when not done yet for this buffer
+if exists("b:did_ftplugin")
+  finish
+endif
+
+" Don't load another plugin for this buffer
+let b:did_ftplugin = 1
+
+" Set 'formatoptions' to break comment lines but not other lines,
+" and insert the comment leader when hitting <CR> or using "o".
+setlocal fo-=t fo+=croql
+
+" Set 'comments' to format dashed lists in comments.
+setlocal comments=sO:*\ -,mO:*\ \ ,exO:*/,s1:/*,mb:*,ex:*/,://
--- /dev/null
+++ b/lib/vimfiles/ftplugin/rst.vim
@@ -1,0 +1,14 @@
+" Vim filetype plugin file
+" Language:         reStructuredText documentation format
+" Maintainer:       Nikolai Weibull <now@bitwi.se>
+" Latest Revision:  2006-04-19
+
+if exists("b:did_ftplugin")
+  finish
+endif
+let b:did_ftplugin = 1
+
+let b:undo_ftplugin = "setl com< cms< et< fo<"
+
+setlocal comments=fb:.. commentstring=..\ %s expandtab
+setlocal formatoptions+=tcroql
--- /dev/null
+++ b/lib/vimfiles/ftplugin/ruby.vim
@@ -1,0 +1,230 @@
+" Vim filetype plugin
+" Language:		Ruby
+" Maintainer:		Gavin Sinclair <gsinclair at gmail.com>
+" Info:			$Id: ruby.vim,v 1.39 2007/05/06 16:38:40 tpope Exp $
+" URL:			http://vim-ruby.rubyforge.org
+" Anon CVS:		See above site
+" Release Coordinator:  Doug Kearns <dougkearns@gmail.com>
+" ----------------------------------------------------------------------------
+"
+" Original matchit support thanks to Ned Konz.  See his ftplugin/ruby.vim at
+"   http://bike-nomad.com/vim/ruby.vim.
+" ----------------------------------------------------------------------------
+
+" Only do this when not done yet for this buffer
+if (exists("b:did_ftplugin"))
+  finish
+endif
+let b:did_ftplugin = 1
+
+let s:cpo_save = &cpo
+set cpo&vim
+
+if has("gui_running") && !has("gui_win32")
+  setlocal keywordprg=ri\ -T
+else
+  setlocal keywordprg=ri
+endif
+
+" Matchit support
+if exists("loaded_matchit") && !exists("b:match_words")
+  let b:match_ignorecase = 0
+
+  let b:match_words =
+	\ '\<\%(if\|unless\|case\|while\|until\|for\|do\|class\|module\|def\|begin\)\>=\@!' .
+	\ ':' .
+	\ '\<\%(else\|elsif\|ensure\|when\|rescue\|break\|redo\|next\|retry\)\>' .
+	\ ':' .
+	\ '\<end\>' .
+	\ ',{:},\[:\],(:)'
+
+  let b:match_skip =
+	\ "synIDattr(synID(line('.'),col('.'),0),'name') =~ '" .
+	\ "\\<ruby\\%(String\\|StringDelimiter\\|ASCIICode\\|Escape\\|" .
+	\ "Interpolation\\|NoInterpolation\\|Comment\\|Documentation\\|" .
+	\ "ConditionalModifier\\|RepeatModifier\\|OptionalDo\\|" .
+	\ "Function\\|BlockArgument\\|KeywordAsMethod\\|ClassVariable\\|" .
+	\ "InstanceVariable\\|GlobalVariable\\|Symbol\\)\\>'"
+endif
+
+setlocal formatoptions-=t formatoptions+=croql
+
+setlocal include=^\\s*\\<\\(load\\\|\w*require\\)\\>
+setlocal includeexpr=substitute(substitute(v:fname,'::','/','g'),'$','.rb','')
+setlocal suffixesadd=.rb
+
+if exists("&ofu") && has("ruby")
+  setlocal omnifunc=rubycomplete#Complete
+endif
+
+" To activate, :set ballooneval
+if has('balloon_eval') && exists('+balloonexpr')
+  setlocal balloonexpr=RubyBalloonexpr()
+endif
+
+
+" TODO:
+"setlocal define=^\\s*def
+
+setlocal comments=:#
+setlocal commentstring=#\ %s
+
+if !exists("s:rubypath")
+  if has("ruby") && has("win32")
+    ruby VIM::command( 'let s:rubypath = "%s"' % ($: + begin; require %q{rubygems}; Gem.all_load_paths.sort.uniq; rescue LoadError; []; end).join(%q{,}) )
+    let s:rubypath = '.,' . substitute(s:rubypath, '\%(^\|,\)\.\%(,\|$\)', ',,', '')
+  elseif executable("ruby")
+    let s:code = "print ($: + begin; require %q{rubygems}; Gem.all_load_paths.sort.uniq; rescue LoadError; []; end).join(%q{,})"
+    if &shellxquote == "'"
+      let s:rubypath = system('ruby -e "' . s:code . '"')
+    else
+      let s:rubypath = system("ruby -e '" . s:code . "'")
+    endif
+    let s:rubypath = '.,' . substitute(s:rubypath, '\%(^\|,\)\.\%(,\|$\)', ',,', '')
+  else
+    " If we can't call ruby to get its path, just default to using the
+    " current directory and the directory of the current file.
+    let s:rubypath = ".,,"
+  endif
+endif
+
+let &l:path = s:rubypath
+
+if has("gui_win32") && !exists("b:browsefilter")
+  let b:browsefilter = "Ruby Source Files (*.rb)\t*.rb\n" .
+                     \ "All Files (*.*)\t*.*\n"
+endif
+
+let b:undo_ftplugin = "setl fo< inc< inex< sua< def< com< cms< path< kp<"
+      \."| unlet! b:browsefilter b:match_ignorecase b:match_words b:match_skip"
+      \."| if exists('&ofu') && has('ruby') | setl ofu< | endif"
+      \."| if has('balloon_eval') && exists('+bexpr') | setl bexpr< | endif"
+
+if !exists("g:no_plugin_maps") && !exists("g:no_ruby_maps")
+
+  noremap <silent> <buffer> [m :<C-U>call <SID>searchsyn('\<def\>','rubyDefine','b')<CR>
+  noremap <silent> <buffer> ]m :<C-U>call <SID>searchsyn('\<def\>','rubyDefine','')<CR>
+  noremap <silent> <buffer> [M :<C-U>call <SID>searchsyn('\<end\>','rubyDefine','b')<CR>
+  noremap <silent> <buffer> ]M :<C-U>call <SID>searchsyn('\<end\>','rubyDefine','')<CR>
+
+  noremap <silent> <buffer> [[ :<C-U>call <SID>searchsyn('\<\%(class\<Bar>module\)\>','rubyModule\<Bar>rubyClass','b')<CR>
+  noremap <silent> <buffer> ]] :<C-U>call <SID>searchsyn('\<\%(class\<Bar>module\)\>','rubyModule\<Bar>rubyClass','')<CR>
+  noremap <silent> <buffer> [] :<C-U>call <SID>searchsyn('\<end\>','rubyModule\<Bar>rubyClass','b')<CR>
+  noremap <silent> <buffer> ][ :<C-U>call <SID>searchsyn('\<end\>','rubyModule\<Bar>rubyClass','')<CR>
+
+  let b:undo_ftplugin = b:undo_ftplugin
+        \."| sil! exe 'unmap <buffer> [[' | sil! exe 'unmap <buffer> ]]' | sil! exe 'unmap <buffer> []' | sil! exe 'unmap <buffer> ]['"
+        \."| sil! exe 'unmap <buffer> [m' | sil! exe 'unmap <buffer> ]m' | sil! exe 'unmap <buffer> [M' | sil! exe 'unmap <buffer> ]M'"
+endif
+
+let &cpo = s:cpo_save
+unlet s:cpo_save
+
+if exists("g:did_ruby_ftplugin_functions")
+  finish
+endif
+let g:did_ruby_ftplugin_functions = 1
+
+function! RubyBalloonexpr()
+  if !exists('s:ri_found')
+    let s:ri_found = executable('ri')
+  endif
+  if s:ri_found
+    let line = getline(v:beval_lnum)
+    let b = matchstr(strpart(line,0,v:beval_col),'\%(\w\|[:.]\)*$')
+    let a = substitute(matchstr(strpart(line,v:beval_col),'^\w*\%([?!]\|\s*=\)\?'),'\s\+','','g')
+    let str = b.a
+    let before = strpart(line,0,v:beval_col-strlen(b))
+    let after  = strpart(line,v:beval_col+strlen(a))
+    if str =~ '^\.'
+      let str = substitute(str,'^\.','#','g')
+      if before =~ '\]\s*$'
+        let str = 'Array'.str
+      elseif before =~ '}\s*$'
+        " False positives from blocks here
+        let str = 'Hash'.str
+      elseif before =~ "[\"'`]\\s*$" || before =~ '\$\d\+\s*$'
+        let str = 'String'.str
+      elseif before =~ '\$\d\+\.\d\+\s*$'
+        let str = 'Float'.str
+      elseif before =~ '\$\d\+\s*$'
+        let str = 'Integer'.str
+      elseif before =~ '/\s*$'
+        let str = 'Regexp'.str
+      else
+        let str = substitute(str,'^#','.','')
+      endif
+    endif
+    let str = substitute(str,'.*\.\s*to_f\s*\.\s*','Float#','')
+    let str = substitute(str,'.*\.\s*to_i\%(nt\)\=\s*\.\s*','Integer#','')
+    let str = substitute(str,'.*\.\s*to_s\%(tr\)\=\s*\.\s*','String#','')
+    let str = substitute(str,'.*\.\s*to_sym\s*\.\s*','Symbol#','')
+    let str = substitute(str,'.*\.\s*to_a\%(ry\)\=\s*\.\s*','Array#','')
+    let str = substitute(str,'.*\.\s*to_proc\s*\.\s*','Proc#','')
+    if str !~ '^\w'
+      return ''
+    endif
+    silent! let res = substitute(system("ri -f simple -T \"".str.'"'),'\n$','','')
+    if res =~ '^Nothing known about' || res =~ '^Bad argument:' || res =~ '^More than one method'
+      return ''
+    endif
+    return res
+  else
+    return ""
+  endif
+endfunction
+
+function! s:searchsyn(pattern,syn,flags)
+    norm! m'
+    let i = 0
+    let cnt = v:count ? v:count : 1
+    while i < cnt
+        let i = i + 1
+        let line = line('.')
+        let col  = col('.')
+        let pos = search(a:pattern,'W'.a:flags)
+        while pos != 0 && s:synname() !~# a:syn
+            let pos = search(a:pattern,'W'.a:flags)
+        endwhile
+        if pos == 0
+            call cursor(line,col)
+            return
+        endif
+    endwhile
+endfunction
+
+function! s:synname()
+    return synIDattr(synID(line('.'),col('.'),0),'name')
+endfunction
+
+"
+" Instructions for enabling "matchit" support:
+"
+" 1. Look for the latest "matchit" plugin at
+"
+"         http://www.vim.org/scripts/script.php?script_id=39
+"
+"    It is also packaged with Vim, in the $VIMRUNTIME/macros directory.
+"
+" 2. Copy "matchit.txt" into a "doc" directory (e.g. $HOME/.vim/doc).
+"
+" 3. Copy "matchit.vim" into a "plugin" directory (e.g. $HOME/.vim/plugin).
+"
+" 4. Ensure this file (ftplugin/ruby.vim) is installed.
+"
+" 5. Ensure you have this line in your $HOME/.vimrc:
+"         filetype plugin on
+"
+" 6. Restart Vim and create the matchit documentation:
+"
+"         :helptags ~/.vim/doc
+"
+"    Now you can do ":help matchit", and you should be able to use "%" on Ruby
+"    keywords.  Try ":echo b:match_words" to be sure.
+"
+" Thanks to Mark J. Reed for the instructions.  See ":help vimrc" for the
+" locations of plugin directories, etc., as there are several options, and it
+" differs on Windows.  Email gsinclair@soyabean.com.au if you need help.
+"
+
+" vim: nowrap sw=2 sts=2 ts=8 ff=unix:
--- /dev/null
+++ b/lib/vimfiles/ftplugin/scheme.vim
@@ -1,0 +1,26 @@
+" Vim filetype plugin
+" Language:      Scheme
+" Maintainer:    Sergey Khorev <sergey.khorev@gmail.com>
+" URL:		 http://iamphet.nm.ru/vim
+" Original author:    Dorai Sitaram <ds26@gte.com>
+" Original URL:		 http://www.ccs.neu.edu/~dorai/vimplugins/vimplugins.html
+" Last Change:   Nov 22, 2004
+
+runtime! ftplugin/lisp.vim ftplugin/lisp_*.vim ftplugin/lisp/*.vim
+
+if exists("b:is_mzscheme") || exists("is_mzscheme")
+    " improve indenting
+    setl iskeyword+=#,%,^
+    setl lispwords+=module,parameterize,let-values,let*-values,letrec-values
+    setl lispwords+=define-values,opt-lambda,case-lambda,syntax-rules,with-syntax,syntax-case
+    setl lispwords+=define-signature,unit,unit/sig,compund-unit/sig,define-values/invoke-unit/sig
+endif
+
+if exists("b:is_chicken") || exists("is_chicken")
+    " improve indenting
+    setl iskeyword+=#,%,^
+    setl lispwords+=let-optionals,let-optionals*,declare
+    setl lispwords+=let-values,let*-values,letrec-values
+    setl lispwords+=define-values,opt-lambda,case-lambda,syntax-rules,with-syntax,syntax-case
+    setl lispwords+=cond-expand,and-let*,foreign-lambda,foreign-lambda*
+endif
--- /dev/null
+++ b/lib/vimfiles/ftplugin/screen.vim
@@ -1,0 +1,13 @@
+" Vim filetype plugin file
+" Language:         screen(1) configuration file
+" Maintainer:       Nikolai Weibull <now@bitwi.se>
+" Latest Revision:  2006-04-19
+
+if exists("b:did_ftplugin")
+  finish
+endif
+let b:did_ftplugin = 1
+
+let b:undo_ftplugin = "setl com< cms< fo<"
+
+setlocal comments=:# commentstring=#\ %s formatoptions-=t formatoptions+=croql
--- /dev/null
+++ b/lib/vimfiles/ftplugin/sensors.vim
@@ -1,0 +1,13 @@
+" Vim filetype plugin file
+" Language:         sensors.conf(5) - libsensors configuration file
+" Maintainer:       Nikolai Weibull <now@bitwi.se>
+" Latest Revision:  2006-04-19
+
+if exists("b:did_ftplugin")
+  finish
+endif
+let b:did_ftplugin = 1
+
+let b:undo_ftplugin = "setl com< cms< fo<"
+
+setlocal comments=:# commentstring=#\ %s formatoptions-=t formatoptions+=croql
--- /dev/null
+++ b/lib/vimfiles/ftplugin/services.vim
@@ -1,0 +1,13 @@
+" Vim filetype plugin file
+" Language:         services(5) - Internet network services list
+" Maintainer:       Nikolai Weibull <now@bitwi.se>
+" Latest Revision:  2006-04-19
+
+if exists("b:did_ftplugin")
+  finish
+endif
+let b:did_ftplugin = 1
+
+let b:undo_ftplugin = "setl com< cms< fo<"
+
+setlocal comments=:# commentstring=#\ %s formatoptions-=t formatoptions+=croql
--- /dev/null
+++ b/lib/vimfiles/ftplugin/setserial.vim
@@ -1,0 +1,13 @@
+" Vim filetype plugin file
+" Language:         setserial(8) configuration file
+" Maintainer:       Nikolai Weibull <now@bitwi.se>
+" Latest Revision:  2006-04-19
+
+if exists("b:did_ftplugin")
+  finish
+endif
+let b:did_ftplugin = 1
+
+let b:undo_ftplugin = "setl com< cms< fo<"
+
+setlocal comments=:# commentstring=#\ %s formatoptions-=t formatoptions+=croql
--- /dev/null
+++ b/lib/vimfiles/ftplugin/sgml.vim
@@ -1,0 +1,39 @@
+" Vim filetype plugin file
+" Language:	sgml
+" Maintainer:	Dan Sharp <dwsharp at hotmail dot com>
+" Last Changed: 2003 Sep 30
+" URL:		http://mywebpage.netscape.com/sharppeople/vim/ftplugin
+
+if exists("b:did_ftplugin") | finish | endif
+
+" Make sure the continuation lines below do not cause problems in
+" compatibility mode.
+let s:save_cpo = &cpo
+set cpo-=C
+
+" Define some defaults in case the included ftplugins don't set them.
+let s:undo_ftplugin = ""
+let s:browsefilter = "XML Files (*.xml)\t*.xml\n" .
+	    \	     "All Files (*.*)\t*.*\n"
+
+runtime! ftplugin/xml.vim ftplugin/xml_*.vim ftplugin/xml/*.vim
+let b:did_ftplugin = 1
+
+" Override our defaults if these were set by an included ftplugin.
+if exists("b:undo_ftplugin")
+    let s:undo_ftplugin = b:undo_ftplugin
+endif
+if exists("b:browsefilter")
+    let s:browsefilter = b:browsefilter
+endif
+
+" Change the :browse e filter to primarily show xml-related files.
+if has("gui_win32")
+    let  b:browsefilter="SGML Files (*.sgml,*.sgm)\t*.sgm*\n" . s:browsefilter
+endif
+
+" Undo the stuff we changed.
+let b:undo_ftplugin = "unlet! b:browsefilter | " . s:undo_ftplugin
+
+" Restore the saved compatibility options.
+let &cpo = s:save_cpo
--- /dev/null
+++ b/lib/vimfiles/ftplugin/sh.vim
@@ -1,0 +1,38 @@
+" Vim filetype plugin file
+" Language:	sh
+" Maintainer:	Dan Sharp <dwsharp at hotmail dot com>
+" Last Changed: 2003 Sep 29
+" URL:		http://mywebpage.netscape.com/sharppeople/vim/ftplugin
+
+if exists("b:did_ftplugin") | finish | endif
+let b:did_ftplugin = 1
+
+" Make sure the continuation lines below do not cause problems in
+" compatibility mode.
+let s:save_cpo = &cpo
+set cpo-=C
+
+setlocal commentstring=#%s
+
+" Shell:  thanks to Johannes Zellner
+if exists("loaded_matchit")
+    let s:sol = '\%(;\s*\|^\s*\)\@<='  " start of line
+    let b:match_words =
+    \ s:sol.'if\>:' . s:sol.'elif\>:' . s:sol.'else\>:' . s:sol. 'fi\>,' .
+    \ s:sol.'\%(for\|while\)\>:' . s:sol. 'done\>,' .
+    \ s:sol.'case\>:' . s:sol. 'esac\>'
+endif
+
+" Change the :browse e filter to primarily show shell-related files.
+if has("gui_win32")
+    let  b:browsefilter="Bourne Shell Scripts (*.sh)\t*.sh\n" .
+		\	"Korn Shell Scripts (*.ksh)\t*.ksh\n" .
+		\	"Bash Shell Scripts (*.bash)\t*.bash\n" .
+		\	"All Files (*.*)\t*.*\n"
+endif
+
+" Undo the stuff we changed.
+let b:undo_ftplugin = "setlocal cms< | unlet! b:browsefilter b:match_words"
+
+" Restore the saved compatibility options.
+let &cpo = s:save_cpo
--- /dev/null
+++ b/lib/vimfiles/ftplugin/sieve.vim
@@ -1,0 +1,14 @@
+" Vim filetype plugin file
+" Language:         Sieve filtering language input file
+" Maintainer:       Nikolai Weibull <now@bitwi.se>
+" Latest Revision:  2006-04-19
+
+if exists("b:did_ftplugin")
+  finish
+endif
+let b:did_ftplugin = 1
+
+let b:undo_ftplugin = "setl com< cms< fo<"
+
+setlocal comments=s1:/*,mb:*,ex:*/,:# commentstring=#\ %s
+setlocal formatoptions-=t formatoptions+=croql
--- /dev/null
+++ b/lib/vimfiles/ftplugin/slpconf.vim
@@ -1,0 +1,14 @@
+" Vim filetype plugin file
+" Language:         RFC 2614 - An API for Service Location configuration file
+" Maintainer:       Nikolai Weibull <now@bitwi.se>
+" Latest Revision:  2006-04-19
+
+if exists("b:did_ftplugin")
+  finish
+endif
+let b:did_ftplugin = 1
+
+let b:undo_ftplugin = "setl com< cms< fo<"
+
+setlocal comments=:#,:; commentstring=#\ %s
+setlocal formatoptions-=t formatoptions+=croql
--- /dev/null
+++ b/lib/vimfiles/ftplugin/slpreg.vim
@@ -1,0 +1,14 @@
+" Vim filetype plugin file
+" Language:         RFC 2614 - An API for Service Location registration file
+" Maintainer:       Nikolai Weibull <now@bitwi.se>
+" Latest Revision:  2006-04-19
+
+if exists("b:did_ftplugin")
+  finish
+endif
+let b:did_ftplugin = 1
+
+let b:undo_ftplugin = "setl com< cms< fo<"
+
+setlocal comments=:#,:; commentstring=#\ %s
+setlocal formatoptions-=t formatoptions+=croql
--- /dev/null
+++ b/lib/vimfiles/ftplugin/slpspi.vim
@@ -1,0 +1,14 @@
+" Vim filetype plugin file
+" Language:         RFC 2614 - An API for Service Location SPI file
+" Maintainer:       Nikolai Weibull <now@bitwi.se>
+" Latest Revision:  2006-04-19
+
+if exists("b:did_ftplugin")
+  finish
+endif
+let b:did_ftplugin = 1
+
+let b:undo_ftplugin = "setl com< cms< fo<"
+
+setlocal comments=:#,:; commentstring=#\ %s
+setlocal formatoptions-=t formatoptions+=croql
--- /dev/null
+++ b/lib/vimfiles/ftplugin/spec.vim
@@ -1,0 +1,168 @@
+" Plugin to update the %changelog section of RPM spec files
+" Filename: spec.vim
+" Maintainer: Gustavo Niemeyer <niemeyer@conectiva.com>
+" Last Change: Wed, 10 Apr 2002 16:28:52 -0300
+
+if exists("b:did_ftplugin")
+	finish
+endif
+let b:did_ftplugin = 1
+
+if !exists("no_plugin_maps") && !exists("no_spec_maps")
+	if !hasmapto("<Plug>SpecChangelog")
+		map <buffer> <LocalLeader>c <Plug>SpecChangelog
+	endif
+endif
+
+noremap <buffer> <unique> <script> <Plug>SpecChangelog :call <SID>SpecChangelog("")<CR>
+
+if !exists("*s:SpecChangelog")
+	function s:SpecChangelog(format)
+		if strlen(a:format) == 0
+			if !exists("g:spec_chglog_format")
+				let email = input("Email address: ")
+				let g:spec_chglog_format = "%a %b %d %Y " . l:email
+				echo "\r"
+			endif
+			let format = g:spec_chglog_format
+		else
+			if !exists("g:spec_chglog_format")
+				let g:spec_chglog_format = a:format
+			endif
+			let format = a:format
+		endif
+		let line = 0
+		let name = ""
+		let ver = ""
+		let rel = ""
+		let nameline = -1
+		let verline = -1
+		let relline = -1
+		let chgline = -1
+		while (line <= line("$"))
+			let linestr = getline(line)
+			if (name == "" && linestr =~? '^Name:')
+				let nameline = line
+				let name = substitute(strpart(linestr,5), '^[	 ]*\([^ 	]\+\)[		]*$','\1','')
+			elseif (ver == "" && linestr =~? '^Version:')
+				let verline = line
+				let ver = substitute(strpart(linestr,8), '^[	 ]*\([^ 	]\+\)[		]*$','\1','')
+			elseif (rel == "" && linestr =~? '^Release:')
+				let relline = line
+				let rel = substitute(strpart(linestr,8), '^[	 ]*\([^ 	]\+\)[		]*$','\1','')
+			elseif (linestr =~? '^%changelog')
+				let chgline = line
+				execute line
+				break
+			endif
+			let line = line+1
+		endwhile
+		if (nameline != -1 && verline != -1 && relline != -1)
+			let include_release_info = exists("g:spec_chglog_release_info")
+			let name = s:ParseRpmVars(name, nameline)
+			let ver = s:ParseRpmVars(ver, verline)
+			let rel = s:ParseRpmVars(rel, relline)
+		else
+			let include_release_info = 0
+		endif
+		if (chgline == -1)
+			let option = confirm("Can't find %changelog. Create one? ","&End of file\n&Here\n&Cancel",3)
+			if (option == 1)
+				call append(line("$"),"")
+				call append(line("$"),"%changelog")
+				execute line("$")
+				let chgline = line(".")
+			elseif (option == 2)
+				call append(line("."),"%changelog")
+				normal j
+				chgline = line(".")
+			endif
+		endif
+		if (chgline != -1)
+			let parsed_format = "* ".strftime(format)
+			let release_info = "+ ".name."-".ver."-".rel
+			let wrong_format = 0
+			let wrong_release = 0
+			let insert_line = 0
+			if (getline(chgline+1) != parsed_format)
+				let wrong_format = 1
+			endif
+			if (include_release_info && getline(chgline+2) != release_info)
+				let wrong_release = 1
+			endif
+			if (wrong_format || wrong_release)
+				if (include_release_info && !wrong_release && !exists("g:spec_chglog_never_increase_release"))
+					let option = confirm("Increase release? ","&Yes\n&No",1)
+					if (option == 1)
+						execute relline
+						normal 
+						let rel = substitute(strpart(getline(relline),8), '^[	 ]*\([^ 	]\+\)[		]*$','\1','')
+						let release_info = "+ ".name."-".ver."-".rel
+					endif
+				endif
+				let n = 0
+				call append(chgline+n, parsed_format)
+				if include_release_info
+					let n = n + 1
+					call append(chgline+n, release_info)
+				endif
+				let n = n + 1
+				call append(chgline+n,"- ")
+				let n = n + 1
+				call append(chgline+n,"")
+				let insert_line = chgline+n
+			else
+				let line = chgline
+				if !exists("g:spec_chglog_prepend")
+					while !(getline(line+2) =~ '^\( *\|\*.*\)$')
+						let line = line+1
+					endwhile
+				endif
+				call append(line+1,"- ")
+				let insert_line = line+2
+			endif
+			execute insert_line
+			startinsert!
+		endif
+	endfunction
+endif
+
+if !exists("*s:ParseRpmVars")
+    function s:ParseRpmVars(str, strline)
+	let end = -1
+	let ret = ""
+	while (1)
+		let start = match(a:str, "\%{", end+1)
+		if (start == -1)
+			let ret = ret . strpart(a:str, end+1)
+			break
+		endif
+		let ret = ret . strpart(a:str, end+1, start-(end+1))
+		let end = match(a:str, "}", start)
+		if (end == -1)
+			let ret = ret . strpart(a:str, start)
+			break
+		endif
+		let varname = strpart(a:str, start+2, end-(start+2))
+		execute a:strline
+		let definestr = "^[ \t]*%define[ \t]\\+" . varname . "[ \t]\\+\\(.*\\)$"
+		let linenum = search(definestr, "bW")
+		if (linenum != -1)
+			let ret = ret .  substitute(getline(linenum), definestr, "\\1", "")
+		else
+			let ret = ret . strpart(str, start, end+1-start)
+		endif
+	endwhile
+	return ret
+    endfunction
+endif
+
+" The following lines, along with the macros/matchit.vim plugin,
+" make it easy to navigate the different sections of a spec file
+" with the % key (thanks to Max Ischenko).
+
+let b:match_ignorecase = 0
+let b:match_words =
+  \ '^Name:^%description:^%clean:^%setup:^%build:^%install:^%files:' .
+  \ '^%package:^%preun:^%postun:^%changelog'
+
--- /dev/null
+++ b/lib/vimfiles/ftplugin/sql.vim
@@ -1,0 +1,418 @@
+" SQL filetype plugin file
+" Language:    SQL (Common for Oracle, Microsoft SQL Server, Sybase)
+" Version:     3.0
+" Maintainer:  David Fishburn <fishburn at ianywhere dot com>
+" Last Change: Wed Apr 26 2006 3:02:32 PM
+" Download:    http://vim.sourceforge.net/script.php?script_id=454
+
+" For more details please use:
+"        :h sql.txt
+"
+" This file should only contain values that are common to all SQL languages
+" Oracle, Microsoft SQL Server, Sybase ASA/ASE, MySQL, and so on
+" If additional features are required create:
+"        vimfiles/after/ftplugin/sql.vim (Windows)
+"        .vim/after/ftplugin/sql.vim     (Unix)
+" to override and add any of your own settings.
+
+
+" This file also creates a command, SQLSetType, which allows you to change
+" SQL dialects on the fly.  For example, if I open an Oracle SQL file, it
+" is color highlighted appropriately.  If I open an Informix SQL file, it
+" will still be highlighted according to Oracles settings.  By running:
+"     :SQLSetType sqlinformix
+"
+" All files called sqlinformix.vim will be loaded from the indent and syntax
+" directories.  This allows you to easily flip SQL dialects on a per file
+" basis.  NOTE: you can also use completion:
+"     :SQLSetType <tab>
+"
+" To change the default dialect, add the following to your vimrc:
+"    let g:sql_type_default = 'sqlanywhere'
+
+
+" Only do this when not done yet for this buffer
+if exists("b:did_ftplugin")
+  finish
+endif
+
+let s:save_cpo = &cpo
+set cpo=
+
+" Functions/Commands to allow the user to change SQL syntax dialects
+" through the use of :SQLSetType <tab> for completion.
+" This works with both Vim 6 and 7.
+
+if !exists("*SQL_SetType")
+    " NOTE: You cannot use function! since this file can be 
+    " sourced from within this function.  That will result in
+    " an error reported by Vim.
+    function SQL_GetList(ArgLead, CmdLine, CursorPos)
+
+        if !exists('s:sql_list')
+            " Grab a list of files that contain "sql" in their names
+            let list_indent   = globpath(&runtimepath, 'indent/*sql*')
+            let list_syntax   = globpath(&runtimepath, 'syntax/*sql*')
+            let list_ftplugin = globpath(&runtimepath, 'ftplugin/*sql*')
+
+            let sqls = "\n".list_indent."\n".list_syntax."\n".list_ftplugin."\n"
+
+            " Strip out everything (path info) but the filename
+            " Regex
+            "    From between two newline characters
+            "    Non-greedily grab all characters
+            "    Followed by a valid filename \w\+\.\w\+ (sql.vim)
+            "    Followed by a newline, but do not include the newline
+            "
+            "    Replace it with just the filename (get rid of PATH)
+            "
+            "    Recursively, since there are many filenames that contain
+            "    the word SQL in the indent, syntax and ftplugin directory
+            let sqls = substitute( sqls, 
+                        \ '[\n]\%(.\{-}\)\(\w\+\.\w\+\)\n\@=', 
+                        \ '\1\n', 
+                        \ 'g'
+                        \ )
+
+            " Remove duplicates, since sqlanywhere.vim can exist in the
+            " sytax, indent and ftplugin directory, yet we only want
+            " to display the option once
+            let index = match(sqls, '.\{-}\ze\n')
+            while index > -1
+                " Get the first filename
+                let file = matchstr(sqls, '.\{-}\ze\n', index)
+                " Recursively replace any *other* occurrence of that
+                " filename with nothing (ie remove it)
+                let sqls = substitute(sqls, '\%>'.(index+strlen(file)).'c\<'.file.'\>\n', '', 'g')
+                " Move on to the next filename
+                let index = match(sqls, '.\{-}\ze\n', (index+strlen(file)+1))
+            endwhile
+
+            " Sort the list if using version 7
+            if v:version >= 700
+                let mylist = split(sqls, "\n")
+                let mylist = sort(mylist)
+                let sqls   = join(mylist, "\n")
+            endif
+
+            let s:sql_list = sqls
+        endif
+
+        return s:sql_list
+
+    endfunction
+
+    function SQL_SetType(name)
+
+        " User has decided to override default SQL scripts and
+        " specify a vendor specific version 
+        " (ie Oracle, Informix, SQL Anywhere, ...)
+        " So check for an remove any settings that prevent the
+        " scripts from being executed, and then source the 
+        " appropriate Vim scripts.
+        if exists("b:did_ftplugin")
+            unlet b:did_ftplugin
+        endif
+        if exists("b:current_syntax")
+            " echomsg 'SQLSetType - clearing syntax'
+            syntax clear
+        endif
+        if exists("b:did_indent")
+            " echomsg 'SQLSetType - clearing indent'
+            unlet b:did_indent
+            " Set these values to their defaults
+            setlocal indentkeys&
+            setlocal indentexpr&
+        endif
+
+        " Ensure the name is in the correct format
+        let new_sql_type = substitute(a:name, 
+                    \ '\s*\([^\.]\+\)\(\.\w\+\)\?', '\L\1', '')
+
+        " Do not specify a buffer local variable if it is 
+        " the default value
+        if new_sql_type == 'sql'
+          let new_sql_type = 'sqloracle'
+        endif
+        let b:sql_type_override = new_sql_type
+
+        " Vim will automatically source the correct files if we
+        " change the filetype.  You cannot do this with setfiletype
+        " since that command will only execute if a filetype has
+        " not already been set.  In this case we want to override
+        " the existing filetype.
+        let &filetype = 'sql'
+    endfunction
+    command! -nargs=* -complete=custom,SQL_GetList SQLSetType :call SQL_SetType(<q-args>)
+
+endif
+
+if exists("b:sql_type_override")
+    " echo 'sourcing buffer ftplugin/'.b:sql_type_override.'.vim'
+    if globpath(&runtimepath, 'ftplugin/'.b:sql_type_override.'.vim') != ''
+        exec 'runtime ftplugin/'.b:sql_type_override.'.vim'
+    " else
+    "     echomsg 'ftplugin/'.b:sql_type_override.' not exist, using default'
+    endif
+elseif exists("g:sql_type_default")
+    " echo 'sourcing global ftplugin/'.g:sql_type_default.'.vim'
+    if globpath(&runtimepath, 'ftplugin/'.g:sql_type_default.'.vim') != ''
+        exec 'runtime ftplugin/'.g:sql_type_default.'.vim'
+    " else
+    "     echomsg 'ftplugin/'.g:sql_type_default.'.vim not exist, using default'
+    endif
+endif
+
+" If the above runtime command succeeded, do not load the default settings
+if exists("b:did_ftplugin")
+  finish
+endif
+
+let b:undo_ftplugin = "setl comments<"
+
+" Don't load another plugin for this buffer
+let b:did_ftplugin     = 1
+let b:current_ftplugin = 'sql'
+
+" Win32 can filter files in the browse dialog
+if has("gui_win32") && !exists("b:browsefilter")
+    let b:browsefilter = "SQL Files (*.sql)\t*.sql\n" .
+	  \ "All Files (*.*)\t*.*\n"
+endif
+
+" Some standard expressions for use with the matchit strings
+let s:notend = '\%(\<end\s\+\)\@<!'
+let s:when_no_matched_or_others = '\%(\<when\>\%(\s\+\%(\%(\<not\>\s\+\)\?<matched\>\)\|\<others\>\)\@!\)'
+let s:or_replace = '\%(or\s\+replace\s\+\)\?'
+
+" Define patterns for the matchit macro
+if !exists("b:match_words")
+    " SQL is generally case insensitive
+    let b:match_ignorecase = 1
+
+    " Handle the following:
+    " if
+    " elseif | elsif
+    " else [if]
+    " end if
+    "
+    " [while condition] loop
+    "     leave
+    "     break
+    "     continue
+    "     exit
+    " end loop
+    "
+    " for
+    "     leave
+    "     break
+    "     continue
+    "     exit
+    " end loop
+    "
+    " do
+    "     statements
+    " doend
+    "
+    " case
+    " when 
+    " when
+    " default
+    " end case
+    "
+    " merge
+    " when not matched
+    " when matched
+    "
+    " EXCEPTION
+    " WHEN column_not_found THEN
+    " WHEN OTHERS THEN
+    "
+    " create[ or replace] procedure|function|event
+
+    let b:match_words =
+		\ '\<begin\>:\<end\>\W*$,'.
+		\
+                \ s:notend . '\<if\>:'.
+                \ '\<elsif\>\|\<elseif\>\|\<else\>:'.
+                \ '\<end\s\+if\>,'.
+                \
+                \ '\<do\>\|'.
+                \ '\<while\>\|'.
+                \ '\%(' . s:notend . '\<loop\>\)\|'.
+                \ '\%(' . s:notend . '\<for\>\):'.
+                \ '\<exit\>\|\<leave\>\|\<break\>\|\<continue\>:'.
+                \ '\%(\<end\s\+\%(for\|loop\>\)\)\|\<doend\>,'.
+                \
+                \ '\%('. s:notend . '\<case\>\):'.
+                \ '\%('.s:when_no_matched_or_others.'\):'.
+                \ '\%(\<when\s\+others\>\|\<end\s\+case\>\),' .
+                \
+                \ '\<merge\>:' .
+                \ '\<when\s\+not\s\+matched\>:' .
+                \ '\<when\s\+matched\>,' .
+                \
+                \ '\%(\<create\s\+' . s:or_replace . '\)\?'.
+                \ '\%(function\|procedure\|event\):'.
+                \ '\<returns\?\>'
+                " \ '\<begin\>\|\<returns\?\>:'.
+                " \ '\<end\>\(;\)\?\s*$'
+                " \ '\<exception\>:'.s:when_no_matched_or_others.
+                " \ ':\<when\s\+others\>,'.
+		"
+                " \ '\%(\<exception\>\|\%('. s:notend . '\<case\>\)\):'.
+                " \ '\%(\<default\>\|'.s:when_no_matched_or_others.'\):'.
+                " \ '\%(\%(\<when\s\+others\>\)\|\<end\s\+case\>\),' .
+endif
+
+" Define how to find the macro definition of a variable using the various
+" [d, [D, [_CTRL_D and so on features
+" Match these values ignoring case
+" ie  DECLARE varname INTEGER
+let &l:define = '\c\<\(VARIABLE\|DECLARE\|IN\|OUT\|INOUT\)\>'
+
+
+" Mappings to move to the next BEGIN ... END block
+" \W - no characters or digits
+nmap <buffer> <silent> ]] :call search('\\c^\\s*begin\\>', 'W' )<CR>
+nmap <buffer> <silent> [[ :call search('\\c^\\s*begin\\>', 'bW' )<CR>
+nmap <buffer> <silent> ][ :call search('\\c^\\s*end\\W*$', 'W' )<CR>
+nmap <buffer> <silent> [] :call search('\\c^\\s*end\\W*$', 'bW' )<CR>
+vmap <buffer> <silent> ]] /\\c^\\s*begin\\><CR>
+vmap <buffer> <silent> [[ ?\\c^\\s*begin\\><CR>
+vmap <buffer> <silent> ][ /\\c^\\s*end\\W*$<CR>
+vmap <buffer> <silent> [] ?\\c^\\s*end\\W*$<CR>
+
+
+" By default only look for CREATE statements, but allow
+" the user to override
+if !exists('g:ftplugin_sql_statements')
+    let g:ftplugin_sql_statements = 'create'
+endif
+
+" Predefined SQL objects what are used by the below mappings using
+" the ]} style maps.
+" This global variable allows the users to override it's value
+" from within their vimrc.
+" Note, you cannot use \?, since these patterns can be used to search
+" backwards, you must use \{,1}
+if !exists('g:ftplugin_sql_objects')
+    let g:ftplugin_sql_objects = 'function,procedure,event,' .
+                \ '\\(existing\\\\|global\\s\\+temporary\\s\\+\\)\\\{,1}' .
+                \ 'table,trigger' .
+                \ ',schema,service,publication,database,datatype,domain' .
+                \ ',index,subscription,synchronization,view,variable'
+endif
+
+" Replace all ,'s with bars, except ones with numbers after them.
+" This will most likely be a \{,1} string.
+let s:ftplugin_sql_objects = 
+            \ '\\c^\\s*' .
+            \ '\\(\\(' .
+            \ substitute(g:ftplugin_sql_statements, ',\d\@!', '\\\\\\|', 'g') .
+            \ '\\)\\s\\+\\(or\\s\\+replace\\\s\+\\)\\{,1}\\)\\{,1}' .
+            \ '\\<\\(' .
+            \ substitute(g:ftplugin_sql_objects, ',\d\@!', '\\\\\\|', 'g') .
+            \ '\\)\\>' 
+
+" Mappings to move to the next CREATE ... block
+exec "nmap <buffer> <silent> ]} :call search('".s:ftplugin_sql_objects."', 'W')<CR>"
+exec "nmap <buffer> <silent> [{ :call search('".s:ftplugin_sql_objects."', 'bW')<CR>"
+" Could not figure out how to use a :call search() string in visual mode
+" without it ending visual mode
+" Unfortunately, this will add a entry to the search history
+exec 'vmap <buffer> <silent> ]} /'.s:ftplugin_sql_objects.'<CR>'
+exec 'vmap <buffer> <silent> [{ ?'.s:ftplugin_sql_objects.'<CR>'
+
+" Mappings to move to the next COMMENT
+"
+" Had to double the \ for the \| separator since this has a special
+" meaning on maps
+let b:comment_leader = '\\(--\\\|\\/\\/\\\|\\*\\\|\\/\\*\\\|\\*\\/\\)'
+" Find the start of the next comment
+let b:comment_start  = '^\\(\\s*'.b:comment_leader.'.*\\n\\)\\@<!'.
+            \ '\\(\\s*'.b:comment_leader.'\\)'
+" Find the end of the previous comment
+let b:comment_end = '\\(^\\s*'.b:comment_leader.'.*\\n\\)'.
+            \ '\\(^\\s*'.b:comment_leader.'\\)\\@!'
+" Skip over the comment
+let b:comment_jump_over  = "call search('".
+            \ '^\\(\\s*'.b:comment_leader.'.*\\n\\)\\@<!'.
+            \ "', 'W')"
+let b:comment_skip_back  = "call search('".
+            \ '^\\(\\s*'.b:comment_leader.'.*\\n\\)\\@<!'.
+            \ "', 'bW')"
+" Move to the start and end of comments
+exec 'nnoremap <silent><buffer> ]" /'.b:comment_start.'<CR>'
+exec 'nnoremap <silent><buffer> [" /'.b:comment_end.'<CR>'
+exec 'vnoremap <silent><buffer> ]" /'.b:comment_start.'<CR>'
+exec 'vnoremap <silent><buffer> [" /'.b:comment_end.'<CR>'
+
+" Comments can be of the form:
+"   /*
+"    *
+"    */
+" or
+"   --
+" or
+"   // 
+setlocal comments=s1:/*,mb:*,ex:*/,:--,://
+
+" Set completion with CTRL-X CTRL-O to autoloaded function.
+if exists('&omnifunc')
+    " Since the SQL completion plugin can be used in conjunction
+    " with other completion filetypes it must record the previous
+    " OMNI function prior to setting up the SQL OMNI function
+    let b:sql_compl_savefunc = &omnifunc
+
+    " This is used by the sqlcomplete.vim plugin
+    " Source it for it's global functions
+    runtime autoload/syntaxcomplete.vim 
+
+    setlocal omnifunc=sqlcomplete#Complete
+    " Prevent the intellisense plugin from loading
+    let b:sql_vis = 1
+    if !exists('g:omni_sql_no_default_maps')
+        " Static maps which use populate the completion list
+        " using Vim's syntax highlighting rules
+        imap <buffer> <c-c>a <C-\><C-O>:call sqlcomplete#Map('syntax')<CR><C-X><C-O>
+        imap <buffer> <c-c>k <C-\><C-O>:call sqlcomplete#Map('sqlKeyword')<CR><C-X><C-O>
+        imap <buffer> <c-c>f <C-\><C-O>:call sqlcomplete#Map('sqlFunction')<CR><C-X><C-O>
+        imap <buffer> <c-c>o <C-\><C-O>:call sqlcomplete#Map('sqlOption')<CR><C-X><C-O>
+        imap <buffer> <c-c>T <C-\><C-O>:call sqlcomplete#Map('sqlType')<CR><C-X><C-O>
+        imap <buffer> <c-c>s <C-\><C-O>:call sqlcomplete#Map('sqlStatement')<CR><C-X><C-O>
+        " Dynamic maps which use populate the completion list
+        " using the dbext.vim plugin
+        imap <buffer> <c-c>t <C-\><C-O>:call sqlcomplete#Map('table')<CR><C-X><C-O>
+        imap <buffer> <c-c>p <C-\><C-O>:call sqlcomplete#Map('procedure')<CR><C-X><C-O>
+        imap <buffer> <c-c>v <C-\><C-O>:call sqlcomplete#Map('view')<CR><C-X><C-O>
+        imap <buffer> <c-c>c <C-\><C-O>:call sqlcomplete#Map('column')<CR><C-X><C-O>
+        imap <buffer> <c-c>l <C-\><C-O>:call sqlcomplete#Map('column_csv')<CR><C-X><C-O>
+        " The next 3 maps are only to be used while the completion window is
+        " active due to the <CR> at the beginning of the map
+        imap <buffer> <c-c>L <C-Y><C-\><C-O>:call sqlcomplete#Map('column_csv')<CR><C-X><C-O>
+        " <C-Right> is not recognized on most Unix systems, so only create
+        " these additional maps on the Windows platform.
+        " If you would like to use these maps, choose a different key and make
+        " the same map in your vimrc.
+        if has('win32')
+            imap <buffer> <c-right>  <C-R>=sqlcomplete#DrillIntoTable()<CR>
+            imap <buffer> <c-left>  <C-R>=sqlcomplete#DrillOutOfColumns()<CR>
+        endif
+        " Remove any cached items useful for schema changes
+        imap <buffer> <c-c>R <C-\><C-O>:call sqlcomplete#Map('resetCache')<CR><C-X><C-O>
+    endif
+
+    if b:sql_compl_savefunc != ""
+        " We are changing the filetype to SQL from some other filetype
+        " which had OMNI completion defined.  We need to activate the
+        " SQL completion plugin in order to cache some of the syntax items
+        " while the syntax rules for SQL are active.
+        call sqlcomplete#PreCacheSyntax()
+    endif
+endif
+
+let &cpo = s:save_cpo
+
+" vim:sw=4:
+
--- /dev/null
+++ b/lib/vimfiles/ftplugin/sshconfig.vim
@@ -1,0 +1,13 @@
+" Vim filetype plugin file
+" Language:         OpenSSH client configuration file
+" Maintainer:       Nikolai Weibull <now@bitwi.se>
+" Latest Revision:  2006-04-19
+
+if exists("b:did_ftplugin")
+  finish
+endif
+let b:did_ftplugin = 1
+
+let b:undo_ftplugin = "setl com< cms< fo<"
+
+setlocal comments=:# commentstring=#\ %s formatoptions-=t formatoptions+=croql
--- /dev/null
+++ b/lib/vimfiles/ftplugin/sudoers.vim
@@ -1,0 +1,13 @@
+" Vim filetype plugin file
+" Language:         sudoers(5) configuration files
+" Maintainer:       Nikolai Weibull <now@bitwi.se>
+" Latest Revision:  2006-04-19
+
+if exists("b:did_ftplugin")
+  finish
+endif
+let b:did_ftplugin = 1
+
+let b:undo_ftplugin = "setl com< cms< fo<"
+
+setlocal comments=:# commentstring=#\ %s formatoptions-=t formatoptions+=croql
--- /dev/null
+++ b/lib/vimfiles/ftplugin/svg.vim
@@ -1,0 +1,39 @@
+" Vim filetype plugin file
+" Language:	svg
+" Maintainer:	Dan Sharp <dwsharp at hotmail dot com>
+" Last Changed: 2003 Sep 29
+" URL:		http://mywebpage.netscape.com/sharppeople/vim/ftplugin
+
+if exists("b:did_ftplugin") | finish | endif
+
+" Make sure the continuation lines below do not cause problems in
+" compatibility mode.
+let s:save_cpo = &cpo
+set cpo-=C
+
+" Define some defaults in case the included ftplugins don't set them.
+let s:undo_ftplugin = ""
+let s:browsefilter = "XML Files (*.xml)\t*.xml\n" .
+	    \	     "All Files (*.*)\t*.*\n"
+
+runtime! ftplugin/xml.vim ftplugin/xml_*.vim ftplugin/xml/*.vim
+let b:did_ftplugin = 1
+
+" Override our defaults if these were set by an included ftplugin.
+if exists("b:undo_ftplugin")
+    let s:undo_ftplugin = b:undo_ftplugin
+endif
+if exists("b:browsefilter")
+    let s:browsefilter = b:browsefilter
+endif
+
+" Change the :browse e filter to primarily show xml-related files.
+if has("gui_win32")
+    let  b:browsefilter="SVG Files (*.svg)\t*.svg\n" . s:browsefilter
+endif
+
+" Undo the stuff we changed.
+let b:undo_ftplugin = "unlet! b:browsefilter | " . s:undo_ftplugin
+
+" Restore the saved compatibility options.
+let &cpo = s:save_cpo
--- /dev/null
+++ b/lib/vimfiles/ftplugin/sysctl.vim
@@ -1,0 +1,14 @@
+" Vim filetype plugin file
+" Language:         sysctl.conf(5) configuration file
+" Maintainer:       Nikolai Weibull <now@bitwi.se>
+" Latest Revision:  2006-04-19
+
+if exists("b:did_ftplugin")
+  finish
+endif
+let b:did_ftplugin = 1
+
+let b:undo_ftplugin = "setl com< cms< fo<"
+
+setlocal comments=:;,:# commentstring=#\ %s
+setlocal formatoptions-=t formatoptions+=croql
--- /dev/null
+++ b/lib/vimfiles/ftplugin/tcsh.vim
@@ -1,0 +1,39 @@
+" Vim filetype plugin file
+" Language:	tcsh
+" Maintainer:	Dan Sharp <dwsharp at hotmail dot com>
+" Last Changed: 2003 Sep 29
+" URL:		http://mywebpage.netscape.com/sharppeople/vim/ftplugin
+
+if exists("b:did_ftplugin") | finish | endif
+
+" Make sure the continuation lines below do not cause problems in
+" compatibility mode.
+let s:save_cpo = &cpo
+set cpo-=C
+
+" Define some defaults in case the included ftplugins don't set them.
+let s:undo_ftplugin = ""
+let s:browsefilter = "csh Files (*.csh)\t*.csh\n" .
+	    \	     "All Files (*.*)\t*.*\n"
+
+runtime! ftplugin/csh.vim ftplugin/csh_*.vim ftplugin/csh/*.vim
+let b:did_ftplugin = 1
+
+" Override our defaults if these were set by an included ftplugin.
+if exists("b:undo_ftplugin")
+    let s:undo_ftplugin = b:undo_ftplugin
+endif
+if exists("b:browsefilter")
+    let s:browsefilter = b:browsefilter
+endif
+
+" Change the :browse e filter to primarily show tcsh-related files.
+if has("gui_win32")
+    let  b:browsefilter="tcsh Scripts (*.tcsh)\t*.tcsh\n" . s:browsefilter
+endif
+
+" Undo the stuff we changed.
+let b:undo_ftplugin = "unlet! b:browsefilter | " . s:undo_ftplugin
+
+" Restore the saved compatibility options.
+let &cpo = s:save_cpo
--- /dev/null
+++ b/lib/vimfiles/ftplugin/terminfo.vim
@@ -1,0 +1,13 @@
+" Vim filetype plugin file
+" Language:         terminfo(5) definition
+" Maintainer:       Nikolai Weibull <now@bitwi.se>
+" Latest Revision:  2006-04-19
+
+if exists("b:did_ftplugin")
+  finish
+endif
+let b:did_ftplugin = 1
+
+let b:undo_ftplugin = "setl com< cms< fo<"
+
+setlocal comments=:# commentstring=#\ %s formatoptions-=t formatoptions+=croql
--- /dev/null
+++ b/lib/vimfiles/ftplugin/tex.vim
@@ -1,0 +1,45 @@
+" LaTeX filetype plugin
+" Language:     LaTeX (ft=tex)
+" Maintainer:   Benji Fisher, Ph.D. <benji@member.AMS.org>
+" Version:	1.4
+" Last Change:	Wed 19 Apr 2006
+"  URL:		http://www.vim.org/script.php?script_id=411
+
+" Only do this when not done yet for this buffer.
+if exists("b:did_ftplugin")
+  finish
+endif
+
+" Start with plain TeX.  This will also define b:did_ftplugin .
+source $VIMRUNTIME/ftplugin/plaintex.vim
+
+" Avoid problems if running in 'compatible' mode.
+let s:save_cpo = &cpo
+set cpo&vim
+
+let b:undo_ftplugin .= "| setl inex<"
+
+" Allow "[d" to be used to find a macro definition:
+" Recognize plain TeX \def as well as LaTeX \newcommand and \renewcommand .
+" I may as well add the AMS-LaTeX DeclareMathOperator as well.
+let &l:define .= '\|\\\(re\)\=new\(boolean\|command\|counter\|environment\|font'
+	\ . '\|if\|length\|savebox\|theorem\(style\)\=\)\s*\*\=\s*{\='
+	\ . '\|DeclareMathOperator\s*{\=\s*'
+
+" Tell Vim how to recognize LaTeX \include{foo} and plain \input bar :
+let &l:include .= '\|\\include{'
+" On some file systems, "{" and "}" are inluded in 'isfname'.  In case the
+" TeX file has \include{fname} (LaTeX only), strip everything except "fname".
+let &l:includeexpr = "substitute(v:fname, '^.\\{-}{\\|}.*', '', 'g')"
+
+" The following lines enable the macros/matchit.vim plugin for
+" extended matching with the % key.
+" ftplugin/plaintex.vim already defines b:match_skip and b:match_ignorecase
+" and matches \(, \), \[, \], \{, and \} .
+if exists("loaded_matchit")
+  let b:match_words .= ',\\begin\s*\({\a\+\*\=}\):\\end\s*\1'
+endif " exists("loaded_matchit")
+
+let &cpo = s:save_cpo
+
+" vim:sts=2:sw=2:
--- /dev/null
+++ b/lib/vimfiles/ftplugin/udevconf.vim
@@ -1,0 +1,13 @@
+" Vim filetype plugin file
+" Language:         udev(8) configuration file
+" Maintainer:       Nikolai Weibull <now@bitwi.se>
+" Latest Revision:  2006-04-19
+
+if exists("b:did_ftplugin")
+  finish
+endif
+let b:did_ftplugin = 1
+
+let b:undo_ftplugin = "setl com< cms< fo<"
+
+setlocal comments=:# commentstring=#\ %s formatoptions-=t formatoptions+=croql
--- /dev/null
+++ b/lib/vimfiles/ftplugin/udevperm.vim
@@ -1,0 +1,13 @@
+" Vim filetype plugin file
+" Language:         udev(8) permissions file
+" Maintainer:       Nikolai Weibull <now@bitwi.se>
+" Latest Revision:  2006-04-19
+
+if exists("b:did_ftplugin")
+  finish
+endif
+let b:did_ftplugin = 1
+
+let b:undo_ftplugin = "setl com< cms< fo<"
+
+setlocal comments=:# commentstring=#\ %s formatoptions-=t formatoptions+=croql
--- /dev/null
+++ b/lib/vimfiles/ftplugin/udevrules.vim
@@ -1,0 +1,13 @@
+" Vim filetype plugin file
+" Language:         udev(8) rules file
+" Maintainer:       Nikolai Weibull <now@bitwi.se>
+" Latest Revision:  2006-04-19
+
+if exists("b:did_ftplugin")
+  finish
+endif
+let b:did_ftplugin = 1
+
+let b:undo_ftplugin = "setl com< cms< fo<"
+
+setlocal comments=:# commentstring=#\ %s formatoptions-=t formatoptions+=croql
--- /dev/null
+++ b/lib/vimfiles/ftplugin/updatedb.vim
@@ -1,0 +1,13 @@
+" Vim filetype plugin file
+" Language:         updatedb.conf(5) configuration file
+" Maintainer:       Nikolai Weibull <now@bitwi.se>
+" Latest Revision:  2006-04-19
+
+if exists("b:did_ftplugin")
+  finish
+endif
+let b:did_ftplugin = 1
+
+let b:undo_ftplugin = "setl com< cms< fo<"
+
+setlocal comments=:# commentstring=#\ %s formatoptions-=t formatoptions+=croql
--- /dev/null
+++ b/lib/vimfiles/ftplugin/vb.vim
@@ -1,0 +1,45 @@
+" Vim filetype plugin file
+" Language:	VisualBasic (ft=vb)
+" Maintainer:	Johannes Zellner <johannes@zellner.org>
+" Last Change:	Thu, 22 Nov 2001 12:56:14 W. Europe Standard Time
+
+if exists("b:did_ftplugin") | finish | endif
+let b:did_ftplugin = 1
+
+setlocal com=sr:'\ -,mb:'\ \ ,el:'\ \ ,:'
+
+" we need this wrapper, as call doesn't allow a count
+fun! <SID>VbSearch(pattern, flags)
+    let cnt = v:count1
+    while cnt > 0
+	call search(a:pattern, a:flags)
+	let cnt = cnt - 1
+    endwhile
+endfun
+
+let s:cpo_save = &cpo
+set cpo&vim
+
+" NOTE the double escaping \\|
+nnoremap <buffer> <silent> [[ :call <SID>VbSearch('^\s*\(\(private\|public\)\s\+\)\=\(function\\|sub\)', 'bW')<cr>
+nnoremap <buffer> <silent> ]] :call <SID>VbSearch('^\s*\(\(private\|public\)\s\+\)\=\(function\\|sub\)', 'W')<cr>
+nnoremap <buffer> <silent> [] :call <SID>VbSearch('^\s*\<end\>\s\+\(function\\|sub\)', 'bW')<cr>
+nnoremap <buffer> <silent> ][ :call <SID>VbSearch('^\s*\<end\>\s\+\(function\\|sub\)', 'W')<cr>
+
+" matchit support
+if exists("loaded_matchit")
+    let b:match_ignorecase=1
+    let b:match_words=
+    \ '\%(^\s*\)\@<=\<if\>.*\<then\>\s*$:\%(^\s*\)\@<=\<else\>:\%(^\s*\)\@<=\<elseif\>:\%(^\s*\)\@<=\<end\>\s\+\<if\>,' .
+    \ '\%(^\s*\)\@<=\<for\>:\%(^\s*\)\@<=\<next\>,' .
+    \ '\%(^\s*\)\@<=\<while\>:\%(^\s*\)\@<=\<wend\>,' .
+    \ '\%(^\s*\)\@<=\<do\>:\%(^\s*\)\@<=\<loop\>\s\+\<while\>,' .
+    \ '\%(^\s*\)\@<=\<select\>\s\+\<case\>:\%(^\s*\)\@<=\<case\>:\%(^\s*\)\@<=\<end\>\s\+\<select\>,' .
+    \ '\%(^\s*\)\@<=\<enum\>:\%(^\s*\)\@<=\<end\>\s\<enum\>,' .
+    \ '\%(^\s*\)\@<=\<with\>:\%(^\s*\)\@<=\<end\>\s\<with\>,' .
+    \ '\%(^\s*\)\@<=\%(\<\%(private\|public\)\>\s\+\)\=\<function\>\s\+\([^ \t(]\+\):\%(^\s*\)\@<=\<\1\>\s*=:\%(^\s*\)\@<=\<end\>\s\+\<function\>,' .
+    \ '\%(^\s*\)\@<=\%(\<\%(private\|public\)\>\s\+\)\=\<sub\>\s\+:\%(^\s*\)\@<=\<end\>\s\+\<sub\>'
+endif
+
+let &cpo = s:cpo_save
+unlet s:cpo_save
--- /dev/null
+++ b/lib/vimfiles/ftplugin/verilog.vim
@@ -1,0 +1,51 @@
+" Vim filetype plugin file
+" Language:	Verilog HDL
+" Maintainer:	Chih-Tsun Huang <cthuang@larc.ee.nthu.edu.tw>
+" Last Change:	Mon Sep  5 11:05:54 CST 2005 and 2006 April 30
+" URL:		http://larc.ee.nthu.edu.tw/~cthuang/vim/ftplugin/verilog.vim
+
+" Only do this when not done yet for this buffer
+if exists("b:did_ftplugin")
+  finish
+endif
+
+" Don't load another plugin for this buffer
+let b:did_ftplugin = 1
+
+" Undo the plugin effect
+let b:undo_ftplugin = "setlocal fo< com< tw<"
+    \ . "| unlet! b:browsefilter b:match_ignorecase b:match_words"
+
+" Set 'formatoptions' to break comment lines but not other lines,
+" and insert the comment leader when hitting <CR> or using "o".
+setlocal fo-=t fo+=croqlm1
+
+" Set 'comments' to format dashed lists in comments.
+setlocal comments=sO:*\ -,mO:*\ \ ,exO:*/,s1:/*,mb:*,ex:*/,://
+
+" Format comments to be up to 78 characters long
+if &textwidth == 0 
+  setlocal tw=78
+endif
+
+set cpo-=C
+
+" Win32 can filter files in the browse dialog
+if has("gui_win32") && !exists("b:browsefilter")
+  let b:browsefilter = "Verilog Source Files (*.v)\t*.v\n" .
+	\ "All Files (*.*)\t*.*\n"
+endif
+
+" Let the matchit plugin know what items can be matched.
+if exists("loaded_matchit")
+  let b:match_ignorecase=0
+  let b:match_words=
+    \ '\<begin\>:\<end\>,' .
+    \ '\<case\>\|\<casex\>\|\<casez\>:\<endcase\>,' .
+    \ '\<module\>:\<endmodule\>,' .
+    \ '\<if\>:\<else\>,' .
+    \ '\<function\>:\<endfunction\>,' .
+    \ '`ifdef\>:`else\>:`endif\>,' .
+    \ '\<task\>:\<endtask\>,' .
+    \ '\<specify\>:\<endspecify\>'
+endif
--- /dev/null
+++ b/lib/vimfiles/ftplugin/vhdl.vim
@@ -1,0 +1,84 @@
+" VHDL filetype plugin
+" Language:    VHDL
+" Maintainer:  R.Shankar <shankar.r?freescale.com>
+" Modified By: Gerald Lai <laigera+vim?gmail.com>
+" Last Change: 2006 Feb 16
+
+" Only do this when not done yet for this buffer
+if exists("b:did_ftplugin")
+  finish
+endif
+
+" Don't load another plugin for this buffer
+let b:did_ftplugin = 1
+
+" Set 'formatoptions' to break comment lines but not other lines,
+" and insert the comment leader when hitting <CR> or using "o".
+"setlocal fo-=t fo+=croqlm1
+
+" Set 'comments' to format dashed lists in comments.
+"setlocal comments=sO:*\ -,mO:*\ \ ,exO:*/,s1:/*,mb:*,ex:*/,://
+
+" Format comments to be up to 78 characters long
+"setlocal tw=75
+
+set cpo-=C
+
+" Win32 can filter files in the browse dialog
+"if has("gui_win32") && !exists("b:browsefilter")
+"  let b:browsefilter = "Verilog Source Files (*.v)\t*.v\n" .
+"   \ "All Files (*.*)\t*.*\n"
+"endif
+
+" Let the matchit plugin know what items can be matched.
+if ! exists("b:match_words")  &&  exists("loaded_matchit")
+  let b:match_ignorecase=1
+  let s:notend = '\%(\<end\s\+\)\@<!'
+  let b:match_words =
+    \ s:notend.'\<if\>:\<elsif\>:\<else\>:\<end\s\+if\>,'.
+    \ s:notend.'\<case\>:\<when\>:\<end\s\+case\>,'.
+    \ s:notend.'\<loop\>:\<end\s\+loop\>,'.
+    \ s:notend.'\<for\>:\<end\s\+for\>,'.
+    \ s:notend.'\<generate\>:\<end\s\+generate\>,'.
+    \ s:notend.'\<record\>:\<end\s\+record\>,'.
+    \ s:notend.'\<units\>:\<end\s\+units\>,'.
+    \ s:notend.'\<process\>:\<end\s\+process\>,'.
+    \ s:notend.'\<block\>:\<end\s\+block\>,'.
+    \ s:notend.'\<function\>:\<end\s\+function\>,'.
+    \ s:notend.'\<entity\>:\<end\s\+entity\>,'.
+    \ s:notend.'\<component\>:\<end\s\+component\>,'.
+    \ s:notend.'\<architecture\>:\<end\s\+architecture\>,'.
+    \ s:notend.'\<package\>:\<end\s\+package\>,'.
+    \ s:notend.'\<procedure\>:\<end\s\+procedure\>,'.
+    \ s:notend.'\<configuration\>:\<end\s\+configuration\>'
+endif
+
+" count repeat
+function! <SID>CountWrapper(cmd)
+  let i = v:count1
+  if a:cmd[0] == ":"
+    while i > 0
+      execute a:cmd
+      let i = i - 1
+    endwhile
+  else
+    execute "normal! gv\<Esc>"
+    execute "normal ".i.a:cmd
+    let curcol = col(".")
+    let curline = line(".")
+    normal! gv
+    call cursor(curline, curcol)
+  endif
+endfunction
+
+" explore motion
+" keywords: "architecture", "block", "configuration", "component", "entity", "function", "package", "procedure", "process", "record", "units"
+let b:vhdl_explore = '\%(architecture\|block\|configuration\|component\|entity\|function\|package\|procedure\|process\|record\|units\)'
+noremap  <buffer><silent>[[ :<C-u>cal <SID>CountWrapper(':cal search("\\%(--.*\\)\\@<!\\%(\\<end\\s\\+\\)\\@<!\\<".b:vhdl_explore."\\>\\c\\<Bar>\\%^","bW")')<CR>
+noremap  <buffer><silent>]] :<C-u>cal <SID>CountWrapper(':cal search("\\%(--.*\\)\\@<!\\%(\\<end\\s\\+\\)\\@<!\\<".b:vhdl_explore."\\>\\c\\<Bar>\\%$","W")')<CR>
+noremap  <buffer><silent>[] :<C-u>cal <SID>CountWrapper(':cal search("\\%(--.*\\)\\@<!\\<end\\s\\+".b:vhdl_explore."\\>\\c\\<Bar>\\%^","bW")')<CR>
+noremap  <buffer><silent>][ :<C-u>cal <SID>CountWrapper(':cal search("\\%(--.*\\)\\@<!\\<end\\s\\+".b:vhdl_explore."\\>\\c\\<Bar>\\%$","W")')<CR>
+vnoremap <buffer><silent>[[ :<C-u>cal <SID>CountWrapper('[[')<CR>
+vnoremap <buffer><silent>]] :<C-u>cal <SID>CountWrapper(']]')<CR>
+vnoremap <buffer><silent>[] :<C-u>cal <SID>CountWrapper('[]')<CR>
+vnoremap <buffer><silent>][ :<C-u>cal <SID>CountWrapper('][')<CR>
--- /dev/null
+++ b/lib/vimfiles/ftplugin/vim.vim
@@ -1,0 +1,64 @@
+" Vim filetype plugin
+" Language:	Vim
+" Maintainer:	Bram Moolenaar <Bram@vim.org>
+" Last Change:	2006 Sep 26
+
+" Only do this when not done yet for this buffer
+if exists("b:did_ftplugin")
+  finish
+endif
+
+" Don't load another plugin for this buffer
+let b:did_ftplugin = 1
+
+let cpo_save = &cpo
+set cpo-=C
+
+let b:undo_ftplugin = "setl fo< com< tw< commentstring<"
+	\ . "| unlet! b:match_ignorecase b:match_words b:match_skip"
+
+" Set 'formatoptions' to break comment lines but not other lines,
+" and insert the comment leader when hitting <CR> or using "o".
+setlocal fo-=t fo+=croql
+
+" Set 'comments' to format dashed lists in comments
+setlocal com=sO:\"\ -,mO:\"\ \ ,eO:\"\",:\"
+
+" Format comments to be up to 78 characters long
+if &tw == 0
+  setlocal tw=78
+endif
+
+" Comments start with a double quote
+setlocal commentstring=\"%s
+
+" Move around functions.
+noremap <silent><buffer> [[ m':call search('^\s*fu\%[nction]\>', "bW")<CR>
+noremap <silent><buffer> ]] m':call search('^\s*fu\%[nction]\>', "W")<CR>
+noremap <silent><buffer> [] m':call search('^\s*endf*\%[unction]\>', "bW")<CR>
+noremap <silent><buffer> ][ m':call search('^\s*endf*\%[unction]\>', "W")<CR>
+
+" Move around comments
+noremap <silent><buffer> ]" :call search('^\(\s*".*\n\)\@<!\(\s*"\)', "W")<CR>
+noremap <silent><buffer> [" :call search('\%(^\s*".*\n\)\%(^\s*"\)\@!', "bW")<CR>
+
+" Let the matchit plugin know what items can be matched.
+if exists("loaded_matchit")
+  let b:match_ignorecase = 0
+  let b:match_words =
+	\ '\<fu\%[nction]\>:\<retu\%[rn]\>:\<endf\%[unction]\>,' .
+	\ '\<wh\%[ile]\>:\<brea\%[k]\>:\<con\%[tinue]\>:\<endw\%[hile]\>,' .
+	\ '\<for\>:\<brea\%[k]\>:\<con\%[tinue]\>:\<endfo\%[r]\>,' .
+	\ '\<if\>:\<el\%[seif]\>:\<en\%[dif]\>,' .
+	\ '\<try\>:\<cat\%[ch]\>:\<fina\%[lly]\>:\<endt\%[ry]\>,' .
+	\ '\<aug\%[roup]\s\+\%(END\>\)\@!\S:\<aug\%[roup]\s\+END\>,' .
+	\ '(:)'
+  " Ignore ":syntax region" commands, the 'end' argument clobbers if-endif
+  let b:match_skip = 'getline(".") =~ "^\\s*sy\\%[ntax]\\s\\+region" ||
+	\ synIDattr(synID(line("."),col("."),1),"name") =~? "comment\\|string"'
+endif
+
+let &cpo = cpo_save
+
+" removed this, because 'cpoptions' is a global option.
+" setlocal cpo+=M		" makes \%( match \)
--- /dev/null
+++ b/lib/vimfiles/ftplugin/xdefaults.vim
@@ -1,0 +1,14 @@
+" Vim filetype plugin file
+" Language:         X resources files like ~/.Xdefaults (xrdb)
+" Maintainer:       Nikolai Weibull <now@bitwi.se>
+" Latest Revision:  2006-04-19
+
+if exists("b:did_ftplugin")
+  finish
+endif
+let b:did_ftplugin = 1
+
+let b:undo_ftplugin = "setl com< cms< inc< fo<"
+
+setlocal comments=s1:/*,mb:*,ex:*/,:! commentstring& inc&
+setlocal formatoptions-=t formatoptions+=croql
--- /dev/null
+++ b/lib/vimfiles/ftplugin/xf86conf.vim
@@ -1,0 +1,13 @@
+" Vim filetype plugin file
+" Language:         XFree86 Configuration File
+" Maintainer:       Nikolai Weibull <now@bitwi.se>
+" Latest Revision:  2006-04-19
+
+if exists("b:did_ftplugin")
+  finish
+endif
+let b:did_ftplugin = 1
+
+let b:undo_ftplugin = "setl com< cms< fo<"
+
+setlocal comments=:# commentstring=#\ %s formatoptions-=t formatoptions+=croql
--- /dev/null
+++ b/lib/vimfiles/ftplugin/xhtml.vim
@@ -1,0 +1,66 @@
+" Vim filetype plugin file
+" Language:	xhtml
+" Maintainer:	Dan Sharp <dwsharp at hotmail dot com>
+" Last Changed: 2004 Jul 08
+" URL:		http://mywebpage.netscape.com/sharppeople/vim/ftplugin
+
+if exists("b:did_ftplugin") | finish | endif
+
+" Make sure the continuation lines below do not cause problems in
+" compatibility mode.
+let s:save_cpo = &cpo
+set cpo-=C
+
+" Define some defaults in case the included ftplugins don't set them.
+let s:undo_ftplugin = ""
+let s:browsefilter = "HTML Files (*.html, *.htm)\t*.html;*.htm\n" .
+	    \	     "XML Files (*.xml)\t*.xml\n" .
+	    \	     "All Files (*.*)\t*.*\n"
+let s:match_words = ""
+
+runtime! ftplugin/xml.vim ftplugin/xml_*.vim ftplugin/xml/*.vim
+unlet b:did_ftplugin
+
+" Override our defaults if these were set by an included ftplugin.
+if exists("b:undo_ftplugin")
+    let s:undo_ftplugin = b:undo_ftplugin
+    unlet b:undo_ftplugin
+endif
+if exists("b:browsefilter")
+    let s:browsefilter = b:browsefilter
+    unlet b:browsefilter
+endif
+if exists("b:match_words")
+    let s:match_words = b:match_words
+    unlet b:match_words
+endif
+
+runtime! ftplugin/html.vim ftplugin/html_*.vim ftplugin/html/*.vim
+let b:did_ftplugin = 1
+
+" Combine the new set of values with those previously included.
+if exists("b:undo_ftplugin")
+    let s:undo_ftplugin = b:undo_ftplugin . " | " . s:undo_ftplugin
+endif
+if exists("b:browsefilter")
+    let s:browsefilter = b:browsefilter . s:browsefilter
+endif
+if exists("b:match_words")
+    let s:match_words = b:match_words . "," . s:match_words
+endif
+
+" Load the combined list of match_words for matchit.vim
+if exists("loaded_matchit")
+    let b:match_words = s:match_words
+endif
+
+" Change the :browse e filter to primarily show tcsh-related files.
+if has("gui_win32")
+    let  b:browsefilter="XHTML files (*.xhtml, *.xhtm)\t*.xhtml;*.xhtm\n" . s:browsefilter
+endif
+
+" Undo the stuff we changed.
+let b:undo_ftplugin = "unlet! b:browsefilter b:match_words | " . s:undo_ftplugin
+
+" Restore the saved compatibility options.
+let &cpo = s:save_cpo
--- /dev/null
+++ b/lib/vimfiles/ftplugin/xinetd.vim
@@ -1,0 +1,14 @@
+" Vim filetype plugin file
+" Language:         xinetd.conf(5) configuration file
+" Maintainer:       Nikolai Weibull <now@bitwi.se>
+" Latest Revision:  2006-04-19
+
+if exists("b:did_ftplugin")
+  finish
+endif
+let b:did_ftplugin = 1
+
+let b:undo_ftplugin = "setl com< cms< inc< fo<"
+
+setlocal comments=:# commentstring=#\ %s include=^\\s*include
+setlocal formatoptions-=t formatoptions+=croql
--- /dev/null
+++ b/lib/vimfiles/ftplugin/xml.vim
@@ -1,0 +1,56 @@
+" Vim filetype plugin file
+" Language:	xml
+" Maintainer:	Dan Sharp <dwsharp at hotmail dot com>
+" Last Changed: 2003 Sep 29
+" URL:		http://mywebpage.netscape.com/sharppeople/vim/ftplugin
+
+if exists("b:did_ftplugin") | finish | endif
+let b:did_ftplugin = 1
+
+" Make sure the continuation lines below do not cause problems in
+" compatibility mode.
+let s:save_cpo = &cpo
+set cpo-=C
+
+setlocal commentstring=<!--%s-->
+
+" XML:  thanks to Johannes Zellner and Akbar Ibrahim
+" - case sensitive
+" - don't match empty tags <fred/>
+" - match <!--, --> style comments (but not --, --)
+" - match <!, > inlined dtd's. This is not perfect, as it
+"   gets confused for example by
+"       <!ENTITY gt ">">
+if exists("loaded_matchit")
+    let b:match_ignorecase=0
+    let b:match_words =
+     \  '<:>,' .
+     \  '<\@<=!\[CDATA\[:]]>,'.
+     \  '<\@<=!--:-->,'.
+     \  '<\@<=?\k\+:?>,'.
+     \  '<\@<=\([^ \t>/]\+\)\%(\s\+[^>]*\%([^/]>\|$\)\|>\|$\):<\@<=/\1>,'.
+     \  '<\@<=\%([^ \t>/]\+\)\%(\s\+[^/>]*\|$\):/>'
+endif
+
+"
+" For Omni completion, by Mikolaj Machowski.
+if exists('&ofu')
+  setlocal ofu=xmlcomplete#CompleteTags
+endif
+command! -nargs=+ XMLns call xmlcomplete#CreateConnection(<f-args>)
+command! -nargs=? XMLent call xmlcomplete#CreateEntConnection(<f-args>)
+
+
+" Change the :browse e filter to primarily show xml-related files.
+if has("gui_win32")
+    let  b:browsefilter="XML Files (*.xml)\t*.xml\n" .
+		\	"DTD Files (*.dtd)\t*.dtd\n" .
+		\	"All Files (*.*)\t*.*\n"
+endif
+
+" Undo the stuff we changed.
+let b:undo_ftplugin = "setlocal cms<" .
+		\     " | unlet! b:match_ignorecase b:match_words b:browsefilter"
+
+" Restore the saved compatibility options.
+let &cpo = s:save_cpo
--- /dev/null
+++ b/lib/vimfiles/ftplugin/xmodmap.vim
@@ -1,0 +1,13 @@
+" Vim filetype plugin file
+" Language:         xmodmap(1) definition file
+" Maintainer:       Nikolai Weibull <now@bitwi.se>
+" Latest Revision:  2006-04-19
+
+if exists("b:did_ftplugin")
+  finish
+endif
+let b:did_ftplugin = 1
+
+let b:undo_ftplugin = "setl com< cms< fo<"
+
+setlocal comments=:! commentstring=!\ %s formatoptions-=t formatoptions+=croql
--- /dev/null
+++ b/lib/vimfiles/ftplugin/xs.vim
@@ -1,0 +1,12 @@
+" Vim filetype plugin file
+" Language:	XS (Perl extension interface language)
+" Maintainer:	Bram Moolenaar <Bram@vim.org>
+" Last Change:	2001 Sep 18
+
+" Only do this when not done yet for this buffer
+if exists("b:did_ftplugin")
+  finish
+endif
+
+" Just use the C plugin for now.
+runtime! ftplugin/c.vim ftplugin/c_*.vim ftplugin/c/*.vim
--- /dev/null
+++ b/lib/vimfiles/ftplugin/xsd.vim
@@ -1,0 +1,38 @@
+" Vim filetype plugin file
+" Language:	xsd
+" Maintainer:	Dan Sharp <dwsharp at hotmail dot com>
+" Last Changed: 2003 Sep 29
+" URL:		http://mywebpage.netscape.com/sharppeople/vim/ftplugin
+
+if exists("b:did_ftplugin") | finish | endif
+
+" Make sure the continuation lines below do not cause problems in
+" compatibility mode.
+let s:save_cpo = &cpo
+set cpo-=C
+
+" Define some defaults in case the included ftplugins don't set them.
+let s:undo_ftplugin = ""
+let s:browsefilter = "XML Files (*.xml)\t*.xml\n" .
+	    \	     "All Files (*.*)\t*.*\n"
+
+runtime! ftplugin/xml.vim ftplugin/xml_*.vim ftplugin/xml/*.vim
+let b:did_ftplugin = 1
+
+" Override our defaults if these were set by an included ftplugin.
+if exists("b:undo_ftplugin")
+    let s:undo_ftplugin = b:undo_ftplugin
+endif
+if exists("b:browsefilter")
+    let s:browsefilter = b:browsefilter
+endif
+
+" Change the :browse e filter to primarily show xsd-related files.
+if has("gui_win32")
+    let  b:browsefilter="XSD Files (*.xsd)\t*.xsd\n" . s:browsefilter
+endif
+
+let b:undo_ftplugin = "unlet! b:browsefilter | " . s:undo_ftplugin
+
+" Restore the saved compatibility options.
+let &cpo = s:save_cpo
--- /dev/null
+++ b/lib/vimfiles/ftplugin/xslt.vim
@@ -1,0 +1,16 @@
+" Vim filetype plugin file
+" Language:	xslt
+" Maintainer:	Dan Sharp <dwsharp at hotmail dot com>
+" Last Changed: 2004 Jul 08
+" URL:		http://mywebpage.netscape.com/sharppeople/vim/ftplugin
+
+if exists("b:did_ftplugin") | finish | endif
+
+runtime! ftplugin/xml.vim ftplugin/xml_*.vim ftplugin/xml/*.vim
+
+let b:did_ftplugin = 1
+
+" Change the :browse e filter to primarily show xsd-related files.
+if has("gui_win32") && exists("b:browsefilter")
+    let  b:browsefilter="XSLT Files (*.xsl,*.xslt)\t*.xsl;*.xslt\n" . b:browsefilter
+endif
--- /dev/null
+++ b/lib/vimfiles/ftplugin/yaml.vim
@@ -1,0 +1,14 @@
+" Vim filetype plugin file
+" Language:         YAML (YAML Ain't Markup Language)
+" Maintainer:       Nikolai Weibull <now@bitwi.se>
+" Latest Revision:  2006-04-19
+
+if exists("b:did_ftplugin")
+  finish
+endif
+let b:did_ftplugin = 1
+
+let b:undo_ftplugin = "setl com< cms< et< fo<"
+
+setlocal comments=:# commentstring=#\ %s expandtab
+setlocal formatoptions-=t formatoptions+=croql
--- /dev/null
+++ b/lib/vimfiles/ftplugin/zsh.vim
@@ -1,0 +1,13 @@
+" Vim filetype plugin file
+" Language:         Zsh shell script
+" Maintainer:       Nikolai Weibull <now@bitwi.se>
+" Latest Revision:  2006-04-19
+
+if exists("b:did_ftplugin")
+  finish
+endif
+let b:did_ftplugin = 1
+
+let b:undo_ftplugin = "setl com< cms< fo<"
+
+setlocal comments=:# commentstring=#\ %s formatoptions-=t formatoptions+=croql
--- /dev/null
+++ b/lib/vimfiles/ftplugof.vim
@@ -1,0 +1,11 @@
+" Vim support file to switch off loading plugins for file types
+"
+" Maintainer:	Bram Moolenaar <Bram@vim.org>
+" Last Change:	2002 Apr 04
+
+if exists("did_load_ftplugin")
+  unlet did_load_ftplugin
+endif
+
+" Remove all autocommands in the filetypeplugin group
+silent! au! filetypeplugin *
--- /dev/null
+++ b/lib/vimfiles/gvimrc_example.vim
@@ -1,0 +1,59 @@
+" An example for a gvimrc file.
+" The commands in this are executed when the GUI is started.
+"
+" Maintainer:	Bram Moolenaar <Bram@vim.org>
+" Last change:	2001 Sep 02
+"
+" To use it, copy it to
+"     for Unix and OS/2:  ~/.gvimrc
+"	      for Amiga:  s:.gvimrc
+"  for MS-DOS and Win32:  $VIM\_gvimrc
+"	    for OpenVMS:  sys$login:.gvimrc
+
+" Make external commands work through a pipe instead of a pseudo-tty
+"set noguipty
+
+" set the X11 font to use
+" set guifont=-misc-fixed-medium-r-normal--14-130-75-75-c-70-iso8859-1
+
+set ch=2		" Make command line two lines high
+
+set mousehide		" Hide the mouse when typing text
+
+" Make shift-insert work like in Xterm
+map <S-Insert> <MiddleMouse>
+map! <S-Insert> <MiddleMouse>
+
+" Only do this for Vim version 5.0 and later.
+if version >= 500
+
+  " I like highlighting strings inside C comments
+  let c_comment_strings=1
+
+  " Switch on syntax highlighting if it wasn't on yet.
+  if !exists("syntax_on")
+    syntax on
+  endif
+
+  " Switch on search pattern highlighting.
+  set hlsearch
+
+  " For Win32 version, have "K" lookup the keyword in a help file
+  "if has("win32")
+  "  let winhelpfile='windows.hlp'
+  "  map K :execute "!start winhlp32 -k <cword> " . winhelpfile <CR>
+  "endif
+
+  " Set nice colors
+  " background for normal text is light grey
+  " Text below the last line is darker grey
+  " Cursor is green, Cyan when ":lmap" mappings are active
+  " Constants are not underlined but have a slightly lighter background
+  highlight Normal guibg=grey90
+  highlight Cursor guibg=Green guifg=NONE
+  highlight lCursor guibg=Cyan guifg=NONE
+  highlight NonText guibg=grey80
+  highlight Constant gui=NONE guibg=grey95
+  highlight Special gui=NONE guibg=grey95
+
+endif
--- /dev/null
+++ b/lib/vimfiles/indent.vim
@@ -1,0 +1,25 @@
+" Vim support file to switch on loading indent files for file types
+"
+" Maintainer:	Bram Moolenaar <Bram@vim.org>
+" Last Change:	2005 Mar 28
+
+if exists("did_indent_on")
+  finish
+endif
+let did_indent_on = 1
+
+augroup filetypeindent
+  au FileType * call s:LoadIndent()
+  func! s:LoadIndent()
+    if exists("b:undo_indent")
+      exe b:undo_indent
+      unlet! b:undo_indent b:did_indent
+    endif
+    if expand("<amatch>") != ""
+      if exists("b:did_indent")
+	unlet b:did_indent
+      endif
+      runtime! indent/<amatch>.vim
+    endif
+  endfunc
+augroup END
--- /dev/null
+++ b/lib/vimfiles/indent/GenericIndent.vim
@@ -1,0 +1,322 @@
+" Vim indent file generic utility functions
+" Language:    * (various)
+" Maintainer:  Dave Silvia <dsilvia@mchsi.com>
+" Date:        6/30/2004
+
+" SUMMARY:  To use GenericIndent, indent/<your_filename>.vim would have the
+"           following general format:
+"
+"      if exists("b:did_indent") | finish | endif
+"      let b:did_indent = 1
+"      runtime indent/GenericIndent.vim
+"      let b:indentStmts=''
+"      let b:dedentStmts=''
+"      let b:allStmts=''
+"      setlocal indentexpr=GenericIndent()
+"      setlocal indentkeys=<your_keys>
+"      call GenericIndentStmts(<your_stmts>)
+"      call GenericDedentStmts(<your_stmts>)
+"      call GenericAllStmts()
+"
+" END SUMMARY:
+
+" NOTE:  b:indentStmts, b:dedentStmts, and b:allStmts need to be initialized
+"        to '' before callin the functions because 'indent.vim' explicitly
+"        'unlet's b:did_indent.  This means that the lists will compound if
+"        you change back and forth between buffers.  This is true as of
+"        version 6.3, 6/23/2004.
+"
+" NOTE:  By default, GenericIndent is case sensitive.
+"        let b:case_insensitive=1 if you want to ignore case, e.g. DOS batch files
+
+" The function 'GenericIndent' is data driven and handles most all cases of
+" indent checking if you first set up the data.  To use this function follow
+" the example below (taken from the file indent/MuPAD_source.vim)
+"
+" Before you start, source this file in indent/<your_script>.vim to have it
+" define functions for your use.
+"
+"runtime indent/GenericIndent.vim
+"
+" The data is in 5 sets:
+"
+" First, set the data set 'indentexpr' to GenericIndent().
+"
+"setlocal indentexpr=GenericIndent()
+"
+" Second, set the data set 'indentkeys' to the keywords/expressions that need
+" to be checked for 'indenting' _as_ they typed.
+"
+"setlocal indentkeys==end_proc,=else,=then,=elif,=end_if,=end_case,=until,=end_repeat,=end_domain,=end_for,=end_while,=end,o,O
+"
+" NOTE: 'o,O' at the end of the previous line says you wish to be called
+" whenever a newline is placed in the buffer.  This allows the previous line
+" to be checked for indentation parameters.
+"
+" Third, set the data set 'b:indentStmts' to the keywords/expressions that, when
+" they are on a line  _when_  you  _press_  the  _<Enter>_  key,
+" you wish to have the next line indented.
+"
+"call GenericIndentStmts('begin,if,then,else,elif,case,repeat,until,domain,do')
+"
+" Fourth, set the data set 'b:dedentStmts' to the keywords/expressions that, when
+" they are on a line you are currently typing, you wish to have that line
+" 'dedented' (having already been indented because of the previous line's
+" indentation).
+"
+"call GenericDedentStmts('end_proc,then,else,elif,end_if,end_case,until,end_repeat,end_domain,end_for,end_while,end')
+"
+" Fifth, set the data set 'b:allStmts' to the concatenation of the third and
+" fourth data sets, used for checking when more than one keyword/expression
+" is on a line.
+"
+"call GenericAllStmts()
+"
+" NOTE:  GenericIndentStmts uses two variables: 'b:indentStmtOpen' and
+" 'b:indentStmtClose' which default to '\<' and '\>' respectively.  You can
+" set (let) these to any value you wish before calling GenericIndentStmts with
+" your list.  Similarly, GenericDedentStmts uses 'b:dedentStmtOpen' and
+" 'b:dedentStmtClose'.
+"
+" NOTE:  Patterns may be used in the lists passed to Generic[In|De]dentStmts
+" since each element in the list is copied verbatim.
+"
+" Optionally, you can set the DEBUGGING flag within your script to have the
+" debugging messages output.  See below for description.  This can also be set
+" (let) from the command line within your editing buffer.
+"
+"let b:DEBUGGING=1
+"
+" See:
+"      :h runtime
+"      :set runtimepath ?
+" to familiarize yourself with how this works and where you should have this
+" file and your file(s) installed.
+"
+" For help with setting 'indentkeys' see:
+"      :h indentkeys
+" Also, for some good examples see 'indent/sh.vim' and 'indent/vim.vim' as
+" well as files for other languages you may be familiar with.
+"
+"
+" Alternatively, if you'd rather specify yourself, you can enter
+" 'b:indentStmts', 'b:dedentStmts', and 'b:allStmts' 'literally':
+"
+"let b:indentStmts='\<begin\>\|\<if\>\|\<then\>\|\<else\>\|\<elif\>\|\<case\>\|\<repeat\>\|\<until\>\|\<domain\>\|\<do\>'
+"let b:dedentStmts='\<end_proc\>\|\<else\>\|\<elif\>\|\<end_if\>\|\<end_case\>\|\<until\>\|\<end_repeat\>\|\<end_domain\>\|\<end_for\>\|\<end_while\>\|\<end\>'
+"let b:allStmts=b:indentStmts.'\|'.b:dedentStmts
+"
+" This is only useful if you have particularly different parameters for
+" matching each statement.
+
+" RECAP:  From indent/MuPAD_source.vim
+"
+"if exists("b:did_indent") | finish | endif
+"
+"let b:did_indent = 1
+"
+"runtime indent/GenericIndent.vim
+"
+"setlocal indentexpr=GenericIndent()
+"setlocal indentkeys==end_proc,=then,=else,=elif,=end_if,=end_case,=until,=end_repeat,=end_domain,=end_for,=end_while,=end,o,O
+"call GenericIndentStmts('begin,if,then,else,elif,case,repeat,until,domain,do')
+"call GenericDedentStmts('end_proc,then,else,elif,end_if,end_case,until,end_repeat,end_domain,end_for,end_while,end')
+"call GenericAllStmts()
+"
+" END RECAP:
+
+let s:hit=0
+let s:lastVlnum=0
+let s:myScriptName=expand("<sfile>:t")
+
+if exists("*GenericIndent")
+	finish
+endif
+
+function GenericAllStmts()
+	let b:allStmts=b:indentStmts.'\|'.b:dedentStmts
+	call DebugGenericIndent(expand("<sfile>").": "."b:indentStmts: ".b:indentStmts.", b:dedentStmts: ".b:dedentStmts.", b:allStmts: ".b:allStmts)
+endfunction
+
+function GenericIndentStmts(stmts)
+	let Stmts=a:stmts
+	let Comma=match(Stmts,',')
+	if Comma == -1 || Comma == strlen(Stmts)-1
+		echoerr "Must supply a comma separated list of at least 2 entries."
+		echoerr "Supplied list: <".Stmts.">"
+		return
+	endif
+
+	if !exists("b:indentStmtOpen")
+		let b:indentStmtOpen='\<'
+	endif
+	if !exists("b:indentStmtClose")
+		let b:indentStmtClose='\>'
+	endif
+	if !exists("b:indentStmts")
+		let b:indentStmts=''
+	endif
+	if b:indentStmts != ''
+		let b:indentStmts=b:indentStmts.'\|'
+	endif
+	call DebugGenericIndent(expand("<sfile>").": "."b:indentStmtOpen: ".b:indentStmtOpen.", b:indentStmtClose: ".b:indentStmtClose.", b:indentStmts: ".b:indentStmts.", Stmts: ".Stmts)
+	let stmtEntryBegin=0
+	let stmtEntryEnd=Comma
+	let stmtEntry=strpart(Stmts,stmtEntryBegin,stmtEntryEnd-stmtEntryBegin)
+	let Stmts=strpart(Stmts,Comma+1)
+	let Comma=match(Stmts,',')
+	let b:indentStmts=b:indentStmts.b:indentStmtOpen.stmtEntry.b:indentStmtClose
+	while Comma != -1
+		let stmtEntryEnd=Comma
+		let stmtEntry=strpart(Stmts,stmtEntryBegin,stmtEntryEnd-stmtEntryBegin)
+		let Stmts=strpart(Stmts,Comma+1)
+		let Comma=match(Stmts,',')
+		let b:indentStmts=b:indentStmts.'\|'.b:indentStmtOpen.stmtEntry.b:indentStmtClose
+	endwhile
+	let stmtEntry=Stmts
+	let b:indentStmts=b:indentStmts.'\|'.b:indentStmtOpen.stmtEntry.b:indentStmtClose
+endfunction
+
+function GenericDedentStmts(stmts)
+	let Stmts=a:stmts
+	let Comma=match(Stmts,',')
+	if Comma == -1 || Comma == strlen(Stmts)-1
+		echoerr "Must supply a comma separated list of at least 2 entries."
+		echoerr "Supplied list: <".Stmts.">"
+		return
+	endif
+
+	if !exists("b:dedentStmtOpen")
+		let b:dedentStmtOpen='\<'
+	endif
+	if !exists("b:dedentStmtClose")
+		let b:dedentStmtClose='\>'
+	endif
+	if !exists("b:dedentStmts")
+		let b:dedentStmts=''
+	endif
+	if b:dedentStmts != ''
+		let b:dedentStmts=b:dedentStmts.'\|'
+	endif
+	call DebugGenericIndent(expand("<sfile>").": "."b:dedentStmtOpen: ".b:dedentStmtOpen.", b:dedentStmtClose: ".b:dedentStmtClose.", b:dedentStmts: ".b:dedentStmts.", Stmts: ".Stmts)
+	let stmtEntryBegin=0
+	let stmtEntryEnd=Comma
+	let stmtEntry=strpart(Stmts,stmtEntryBegin,stmtEntryEnd-stmtEntryBegin)
+	let Stmts=strpart(Stmts,Comma+1)
+	let Comma=match(Stmts,',')
+	let b:dedentStmts=b:dedentStmts.b:dedentStmtOpen.stmtEntry.b:dedentStmtClose
+	while Comma != -1
+		let stmtEntryEnd=Comma
+		let stmtEntry=strpart(Stmts,stmtEntryBegin,stmtEntryEnd-stmtEntryBegin)
+		let Stmts=strpart(Stmts,Comma+1)
+		let Comma=match(Stmts,',')
+		let b:dedentStmts=b:dedentStmts.'\|'.b:dedentStmtOpen.stmtEntry.b:dedentStmtClose
+	endwhile
+	let stmtEntry=Stmts
+	let b:dedentStmts=b:dedentStmts.'\|'.b:dedentStmtOpen.stmtEntry.b:dedentStmtClose
+endfunction
+
+" Debugging function.  Displays messages in the command area which can be
+" reviewed using ':messages'.  To turn it on use ':let b:DEBUGGING=1'.  Once
+" on, turn off by using ':let b:DEBUGGING=0.  If you don't want it at all and
+" feel it's slowing down your editing (you must have an _awfully_ slow
+" machine!;-> ), you can just comment out the calls to it from 'GenericIndent'
+" below.  No need to remove the function or the calls, tho', as you never can
+" tell when they might come in handy!;-)
+function DebugGenericIndent(msg)
+  if exists("b:DEBUGGING") && b:DEBUGGING
+		echomsg '['.s:hit.']'.s:myScriptName."::".a:msg
+	endif
+endfunction
+
+function GenericIndent()
+	" save ignore case option.  Have to set noignorecase for the match
+	" functions to do their job the way we want them to!
+	" NOTE: if you add a return to this function be sure you do
+	"           if IgnoreCase | set ignorecase | endif
+	"       before returning.  You can just cut and paste from here.
+	let IgnoreCase=&ignorecase
+	" let b:case_insensitive=1 if you want to ignore case, e.g. DOS batch files
+	if !exists("b:case_insensitive")
+		set noignorecase
+	endif
+	" this is used to let DebugGenericIndent display which invocation of the
+	" function goes with which messages.
+	let s:hit=s:hit+1
+  let lnum=v:lnum
+	let cline=getline(lnum)
+	let lnum=prevnonblank(lnum)
+	if lnum==0 | if IgnoreCase | set ignorecase | endif | return 0 | endif
+	let pline=getline(lnum)
+  let ndnt=indent(lnum)
+	if !exists("b:allStmts")
+		call GenericAllStmts()
+	endif
+
+	call DebugGenericIndent(expand("<sfile>").": "."cline=<".cline.">, pline=<".pline.">, lnum=".lnum.", v:lnum=".v:lnum.", ndnt=".ndnt)
+	if lnum==v:lnum
+		" current line, only check dedent
+		"
+		" just dedented this line, don't need to do it again.
+		" another dedentStmts was added or an end%[_*] was completed.
+		if s:lastVlnum==v:lnum
+ 			if IgnoreCase | set ignorecase | endif
+			return ndnt
+		endif
+		let s:lastVlnum=v:lnum
+		call DebugGenericIndent(expand("<sfile>").": "."Checking dedent")
+		let srcStr=cline
+		let dedentKeyBegin=match(srcStr,b:dedentStmts)
+		if dedentKeyBegin != -1
+			let dedentKeyEnd=matchend(srcStr,b:dedentStmts)
+			let dedentKeyStr=strpart(srcStr,dedentKeyBegin,dedentKeyEnd-dedentKeyBegin)
+			"only dedent if it's the beginning of the line
+			if match(srcStr,'^\s*\<'.dedentKeyStr.'\>') != -1
+				call DebugGenericIndent(expand("<sfile>").": "."It's the beginning of the line, dedent")
+				let ndnt=ndnt-&shiftwidth
+			endif
+		endif
+		call DebugGenericIndent(expand("<sfile>").": "."dedent - returning ndnt=".ndnt)
+	else
+		" previous line, only check indent
+		call DebugGenericIndent(expand("<sfile>").": "."Checking indent")
+		let srcStr=pline
+		let indentKeyBegin=match(srcStr,b:indentStmts)
+		if indentKeyBegin != -1
+			" only indent if it's the last indentStmts in the line
+			let allKeyBegin=match(srcStr,b:allStmts)
+			let allKeyEnd=matchend(srcStr,b:allStmts)
+			let allKeyStr=strpart(srcStr,allKeyBegin,allKeyEnd-allKeyBegin)
+			let srcStr=strpart(srcStr,allKeyEnd)
+			let allKeyBegin=match(srcStr,b:allStmts)
+			if allKeyBegin != -1
+				" not the end of the line, check what is and only indent if
+				" it's an indentStmts
+				call DebugGenericIndent(expand("<sfile>").": "."Multiple words in line, checking if last is indent")
+				while allKeyBegin != -1
+					let allKeyEnd=matchend(srcStr,b:allStmts)
+					let allKeyStr=strpart(srcStr,allKeyBegin,allKeyEnd-allKeyBegin)
+					let srcStr=strpart(srcStr,allKeyEnd)
+					let allKeyBegin=match(srcStr,b:allStmts)
+				endwhile
+				if match(b:indentStmts,allKeyStr) != -1
+					call DebugGenericIndent(expand("<sfile>").": "."Last word in line is indent")
+					let ndnt=ndnt+&shiftwidth
+				endif
+			else
+				" it's the last indentStmts in the line, go ahead and indent
+				let ndnt=ndnt+&shiftwidth
+			endif
+		endif
+		call DebugGenericIndent(expand("<sfile>").": "."indent - returning ndnt=".ndnt)
+	endif
+	if IgnoreCase | set ignorecase | endif
+	return ndnt
+endfunction
+
+
+" TODO:  I'm open!
+"
+" BUGS:  You tell me!  Probably.  I just haven't found one yet or haven't been
+"        told about one.
+"
--- /dev/null
+++ b/lib/vimfiles/indent/README.txt
@@ -1,0 +1,45 @@
+This directory contains files to automatically compute the indent for a
+type of file.
+
+If you want to add your own indent file for your personal use, read the docs
+at ":help indent-expression".  Looking at the existing files should give you
+inspiration.
+
+If you make a new indent file which would be useful for others, please send it
+to Bram@vim.org.  Include instructions for detecting the file type for this
+language, by file name extension or by checking a few lines in the file.
+And please stick to the rules below.
+
+If you have remarks about an existing file, send them to the maintainer of
+that file.  Only when you get no response send a message to Bram@vim.org.
+
+If you are the maintainer of an indent file and make improvements, e-mail the
+new version to Bram@vim.org.
+
+
+Rules for making an indent file:
+
+You should use this check for "b:did_indent":
+
+	" Only load this indent file when no other was loaded yet.
+	if exists("b:did_indent")
+	  finish
+	endif
+	let b:did_indent = 1
+
+Always use ":setlocal" to set 'indentexpr'.  This avoids it being carried over
+to other buffers.
+
+To trigger the indenting after typing a word like "endif", add the word to the
+'cinkeys' option with "+=".
+
+You normally set 'indentexpr' to evaluate a function and then define that
+function.  That function only needs to be defined once for as long as Vim is
+running.  Add a test if the function exists and use ":finish", like this:
+	if exists("*GetMyIndent")
+	  finish
+	endif
+
+The user may have several options set unlike you, try to write the file such
+that it works with any option settings.  Also be aware of certain features not
+being compiled in.
--- /dev/null
+++ b/lib/vimfiles/indent/aap.vim
@@ -1,0 +1,12 @@
+" Vim indent file
+" Language:	Aap recipe
+" Maintainer:	Bram Moolenaar <Bram@vim.org>
+" Last Change:	2005 Jun 24
+
+" Only load this indent file when no other was loaded.
+if exists("b:did_indent")
+  finish
+endif
+
+" Works mostly like Python.
+runtime! indent/python.vim
--- /dev/null
+++ b/lib/vimfiles/indent/ada.vim
@@ -1,0 +1,300 @@
+"------------------------------------------------------------------------------
+"  Description: Vim Ada indent file
+"     Language: Ada (2005)
+"	   $Id: ada.vim,v 1.4 2007/05/05 17:25:37 vimboss Exp $
+"    Copyright: Copyright (C) 2006 Martin Krischik
+"   Maintainer: Martin Krischik
+"		Neil Bird <neil@fnxweb.com>
+"      $Author: vimboss $
+"	 $Date: 2007/05/05 17:25:37 $
+"      Version: 4.2
+"    $Revision: 1.4 $
+"     $HeadURL: https://svn.sourceforge.net/svnroot/gnuada/trunk/tools/vim/indent/ada.vim $
+"      History: 24.05.2006 MK Unified Headers
+"		16.07.2006 MK Ada-Mode as vim-ball
+"		15.10.2006 MK Bram's suggestion for runtime integration
+"		05.11.2006 MK Bram suggested to save on spaces
+"    Help Page: ft-vim-indent
+"------------------------------------------------------------------------------
+" ToDo:
+"  Verify handling of multi-line exprs. and recovery upon the final ';'.
+"  Correctly find comments given '"' and "" ==> " syntax.
+"  Combine the two large block-indent functions into one?
+"------------------------------------------------------------------------------
+
+" Only load this indent file when no other was loaded.
+if exists("b:did_indent") || version < 700
+   finish
+endif
+
+let b:did_indent = 1
+
+setlocal indentexpr=GetAdaIndent()
+setlocal indentkeys-=0{,0}
+setlocal indentkeys+=0=~then,0=~end,0=~elsif,0=~when,0=~exception,0=~begin,0=~is,0=~record
+
+" Only define the functions once.
+if exists("*GetAdaIndent")
+   finish
+endif
+
+if exists("g:ada_with_gnat_project_files")
+   let s:AdaBlockStart = '^\s*\(if\>\|while\>\|else\>\|elsif\>\|loop\>\|for\>.*\<\(loop\|use\)\>\|declare\>\|begin\>\|type\>.*\<is\>[^;]*$\|\(type\>.*\)\=\<record\>\|procedure\>\|function\>\|accept\>\|do\>\|task\>\|package\>\|project\>\|then\>\|when\>\|is\>\)'
+else
+   let s:AdaBlockStart = '^\s*\(if\>\|while\>\|else\>\|elsif\>\|loop\>\|for\>.*\<\(loop\|use\)\>\|declare\>\|begin\>\|type\>.*\<is\>[^;]*$\|\(type\>.*\)\=\<record\>\|procedure\>\|function\>\|accept\>\|do\>\|task\>\|package\>\|then\>\|when\>\|is\>\)'
+endif
+
+" Section: s:MainBlockIndent {{{1
+"
+" Try to find indent of the block we're in
+" prev_indent = the previous line's indent
+" prev_lnum   = previous line (to start looking on)
+" blockstart  = expr. that indicates a possible start of this block
+" stop_at     = if non-null, if a matching line is found, gives up!
+" No recursive previous block analysis: simply look for a valid line
+" with a lesser or equal indent than we currently (on prev_lnum) have.
+" This shouldn't work as well as it appears to with lines that are currently
+" nowhere near the correct indent (e.g., start of line)!
+" Seems to work OK as it 'starts' with the indent of the /previous/ line.
+function s:MainBlockIndent (prev_indent, prev_lnum, blockstart, stop_at)
+   let lnum = a:prev_lnum
+   let line = substitute( getline(lnum), ada#Comment, '', '' )
+   while lnum > 1
+      if a:stop_at != ''  &&  line =~ '^\s*' . a:stop_at  &&  indent(lnum) < a:prev_indent
+	 return a:prev_indent
+      elseif line =~ '^\s*' . a:blockstart
+	 let ind = indent(lnum)
+	 if ind < a:prev_indent
+	    return ind
+	 endif
+      endif
+
+      let lnum = prevnonblank(lnum - 1)
+      " Get previous non-blank/non-comment-only line
+      while 1
+	 let line = substitute( getline(lnum), ada#Comment, '', '' )
+	 if line !~ '^\s*$' && line !~ '^\s*#'
+	    break
+	 endif
+	 let lnum = prevnonblank(lnum - 1)
+	 if lnum <= 0
+	    return a:prev_indent
+	 endif
+      endwhile
+   endwhile
+   " Fallback - just move back one
+   return a:prev_indent - &sw
+endfunction MainBlockIndent
+
+" Section: s:EndBlockIndent {{{1
+"
+" Try to find indent of the block we're in (and about to complete),
+" including handling of nested blocks. Works on the 'end' of a block.
+" prev_indent = the previous line's indent
+" prev_lnum   = previous line (to start looking on)
+" blockstart  = expr. that indicates a possible start of this block
+" blockend    = expr. that indicates a possible end of this block
+function s:EndBlockIndent( prev_indent, prev_lnum, blockstart, blockend )
+   let lnum = a:prev_lnum
+   let line = getline(lnum)
+   let ends = 0
+   while lnum > 1
+      if getline(lnum) =~ '^\s*' . a:blockstart
+	 let ind = indent(lnum)
+	 if ends <= 0
+	    if ind < a:prev_indent
+	       return ind
+	    endif
+	 else
+	    let ends = ends - 1
+	 endif
+      elseif getline(lnum) =~ '^\s*' . a:blockend
+	 let ends = ends + 1
+      endif
+
+      let lnum = prevnonblank(lnum - 1)
+      " Get previous non-blank/non-comment-only line
+      while 1
+	 let line = getline(lnum)
+	 let line = substitute( line, ada#Comment, '', '' )
+	 if line !~ '^\s*$'
+	    break
+	 endif
+	 let lnum = prevnonblank(lnum - 1)
+	 if lnum <= 0
+	    return a:prev_indent
+	 endif
+      endwhile
+   endwhile
+   " Fallback - just move back one
+   return a:prev_indent - &sw
+endfunction EndBlockIndent
+
+" Section: s:StatementIndent {{{1
+"
+" Return indent of previous statement-start
+" (after we've indented due to multi-line statements).
+" This time, we start searching on the line *before* the one given (which is
+" the end of a statement - we want the previous beginning).
+function s:StatementIndent( current_indent, prev_lnum )
+   let lnum  = a:prev_lnum
+   while lnum > 0
+      let prev_lnum = lnum
+      let lnum = prevnonblank(lnum - 1)
+      " Get previous non-blank/non-comment-only line
+      while 1
+	 let line = substitute( getline(lnum), ada#Comment, '', '' )
+	 if line !~ '^\s*$' && line !~ '^\s*#'
+	    break
+	 endif
+	 let lnum = prevnonblank(lnum - 1)
+	 if lnum <= 0
+	    return a:current_indent
+	 endif
+      endwhile
+      " Leave indent alone if our ';' line is part of a ';'-delineated
+      " aggregate (e.g., procedure args.) or first line after a block start.
+      if line =~ s:AdaBlockStart || line =~ '(\s*$'
+	 return a:current_indent
+      endif
+      if line !~ '[.=(]\s*$'
+	 let ind = indent(prev_lnum)
+	 if ind < a:current_indent
+	    return ind
+	 endif
+      endif
+   endwhile
+   " Fallback - just use current one
+   return a:current_indent
+endfunction StatementIndent
+
+
+" Section: GetAdaIndent {{{1
+"
+" Find correct indent of a new line based upon what went before
+"
+function GetAdaIndent()
+   " Find a non-blank line above the current line.
+   let lnum = prevnonblank(v:lnum - 1)
+   let ind = indent(lnum)
+   let package_line = 0
+
+   " Get previous non-blank/non-comment-only/non-cpp line
+   while 1
+      let line = substitute( getline(lnum), g:ada#Comment, '', '' )
+      if line !~ '^\s*$' && line !~ '^\s*#'
+	 break
+      endif
+      let lnum = prevnonblank(lnum - 1)
+      if lnum <= 0
+	 return ind
+      endif
+   endwhile
+
+   " Get default indent (from prev. line)
+   let ind = indent(lnum)
+   let initind = ind
+
+   " Now check what's on the previous line
+   if line =~ s:AdaBlockStart  ||  line =~ '(\s*$'
+      " Check for false matches to AdaBlockStart
+      let false_match = 0
+      if line =~ '^\s*\(procedure\|function\|package\)\>.*\<is\s*new\>'
+	 " Generic instantiation
+	 let false_match = 1
+      elseif line =~ ')\s*;\s*$'  ||  line =~ '^\([^(]*([^)]*)\)*[^(]*;\s*$'
+	 " forward declaration
+	 let false_match = 1
+      endif
+      " Move indent in
+      if ! false_match
+	 let ind = ind + &sw
+      endif
+   elseif line =~ '^\s*\(case\|exception\)\>'
+      " Move indent in twice (next 'when' will move back)
+      let ind = ind + 2 * &sw
+   elseif line =~ '^\s*end\s*record\>'
+      " Move indent back to tallying 'type' preceeding the 'record'.
+      " Allow indent to be equal to 'end record's.
+      let ind = s:MainBlockIndent( ind+&sw, lnum, 'type\>', '' )
+   elseif line =~ '\(^\s*new\>.*\)\@<!)\s*[;,]\s*$'
+      " Revert to indent of line that started this parenthesis pair
+      exe lnum
+      exe 'normal! $F)%'
+      if getline('.') =~ '^\s*('
+	 " Dire layout - use previous indent (could check for ada#Comment here)
+	 let ind = indent( prevnonblank( line('.')-1 ) )
+      else
+	 let ind = indent('.')
+      endif
+      exe v:lnum
+   elseif line =~ '[.=(]\s*$'
+      " A statement continuation - move in one
+      let ind = ind + &sw
+   elseif line =~ '^\s*new\>'
+      " Multiple line generic instantiation ('package blah is\nnew thingy')
+      let ind = s:StatementIndent( ind - &sw, lnum )
+   elseif line =~ ';\s*$'
+      " Statement end (but not 'end' ) - try to find current statement-start indent
+      let ind = s:StatementIndent( ind, lnum )
+   endif
+
+   " Check for potential argument list on next line
+   let continuation = (line =~ '[A-Za-z0-9_]\s*$')
+
+
+   " Check current line; search for simplistic matching start-of-block
+   let line = getline(v:lnum)
+   if line =~ '^\s*#'
+      " Start of line for ada-pp
+      let ind = 0
+   elseif continuation && line =~ '^\s*('
+      " Don't do this if we've already indented due to the previous line
+      if ind == initind
+	 let ind = ind + &sw
+      endif
+   elseif line =~ '^\s*\(begin\|is\)\>'
+      let ind = s:MainBlockIndent( ind, lnum, '\(procedure\|function\|declare\|package\|task\)\>', 'begin\>' )
+   elseif line =~ '^\s*record\>'
+      let ind = s:MainBlockIndent( ind, lnum, 'type\>\|for\>.*\<use\>', '' ) + &sw
+   elseif line =~ '^\s*\(else\|elsif\)\>'
+      let ind = s:MainBlockIndent( ind, lnum, 'if\>', '' )
+   elseif line =~ '^\s*when\>'
+      " Align 'when' one /in/ from matching block start
+      let ind = s:MainBlockIndent( ind, lnum, '\(case\|exception\)\>', '' ) + &sw
+   elseif line =~ '^\s*end\>\s*\<if\>'
+      " End of if statements
+      let ind = s:EndBlockIndent( ind, lnum, 'if\>', 'end\>\s*\<if\>' )
+   elseif line =~ '^\s*end\>\s*\<loop\>'
+      " End of loops
+      let ind = s:EndBlockIndent( ind, lnum, '\(\(while\|for\)\>.*\)\?\<loop\>', 'end\>\s*\<loop\>' )
+   elseif line =~ '^\s*end\>\s*\<record\>'
+      " End of records
+      let ind = s:EndBlockIndent( ind, lnum, '\(type\>.*\)\=\<record\>', 'end\>\s*\<record\>' )
+   elseif line =~ '^\s*end\>\s*\<procedure\>'
+      " End of procedures
+      let ind = s:EndBlockIndent( ind, lnum, 'procedure\>.*\<is\>', 'end\>\s*\<procedure\>' )
+   elseif line =~ '^\s*end\>\s*\<case\>'
+      " End of case statement
+      let ind = s:EndBlockIndent( ind, lnum, 'case\>.*\<is\>', 'end\>\s*\<case\>' )
+   elseif line =~ '^\s*end\>'
+      " General case for end
+      let ind = s:MainBlockIndent( ind, lnum, '\(if\|while\|for\|loop\|accept\|begin\|record\|case\|exception\|package\)\>', '' )
+   elseif line =~ '^\s*exception\>'
+      let ind = s:MainBlockIndent( ind, lnum, 'begin\>', '' )
+   elseif line =~ '^\s*then\>'
+      let ind = s:MainBlockIndent( ind, lnum, 'if\>', '' )
+   endif
+
+   return ind
+endfunction GetAdaIndent
+
+finish " 1}}}
+
+"------------------------------------------------------------------------------
+"   Copyright (C) 2006	Martin Krischik
+"
+"   Vim is Charityware - see ":help license" or uganda.txt for licence details.
+"------------------------------------------------------------------------------
+" vim: textwidth=78 wrap tabstop=8 shiftwidth=3 softtabstop=3 noexpandtab
+" vim: foldmethod=marker
--- /dev/null
+++ b/lib/vimfiles/indent/ant.vim
@@ -1,0 +1,12 @@
+" Vim indent file
+" Language:    ANT files
+" Maintainer:  David Fishburn <fishburn@ianywhere.com>
+" Last Change: Thu May 15 2003 10:02:54 PM
+
+" Only load this indent file when no other was loaded.
+if exists("b:did_indent")
+  finish
+endif
+
+" Use XML formatting rules
+runtime! indent/xml.vim
--- /dev/null
+++ b/lib/vimfiles/indent/automake.vim
@@ -1,0 +1,11 @@
+" Vim indent file
+" Language:	    automake
+" Maintainer:       Nikolai Weibull <now@bitwi.se>
+" Latest Revision:  2006-04-19
+
+if exists("b:did_indent")
+  finish
+endif
+
+" same as makefile indenting for now.
+runtime! indent/make.vim
--- /dev/null
+++ b/lib/vimfiles/indent/awk.vim
@@ -1,0 +1,228 @@
+"  vim: set sw=3 sts=3:
+
+" Awk indent script. It can handle multi-line statements and expressions.
+" It works up to the point where the distinction between correct/incorrect
+" and personal taste gets fuzzy. Drop me an e-mail for bug reports and
+" reasonable style suggestions.
+"
+" Bugs:
+" =====
+" - Some syntax errors may cause erratic indentation.
+" - Same for very unusual but syntacticly correct use of { }
+" - In some cases it's confused by the use of ( and { in strings constants
+" - This version likes the closing brace of a multiline pattern-action be on
+"   character position 1 before the following pattern-action combination is
+"   formatted
+
+" Author:
+" =======
+" Erik Janssen, ejanssen@itmatters.nl
+"
+" History:
+" ========
+" 26-04-2002 Got initial version working reasonably well
+" 29-04-2002 Fixed problems in function headers and max line width
+"	     Added support for two-line if's without curly braces
+
+" Only load this indent file when no other was loaded.
+if exists("b:did_indent")
+    finish
+endif
+
+let b:did_indent = 1
+
+setlocal indentexpr=GetAwkIndent()
+" Mmm, copied from the tcl indent program. Is this okay?
+setlocal indentkeys-=:,0#
+
+" Only define the function once.
+if exists("*GetAwkIndent")
+    finish
+endif
+
+" This function contains a lot of exit points. It checks for simple cases
+" first to get out of the function as soon as possible, thereby reducing the
+" number of possibilities later on in the difficult parts
+
+function! GetAwkIndent()
+
+   " Find previous line and get it's indentation
+   let prev_lineno = s:Get_prev_line( v:lnum )
+   if prev_lineno == 0
+      return 0
+   endif
+   let prev_data = getline( prev_lineno )
+   let ind = indent( prev_lineno )
+
+   " Increase indent if the previous line contains an opening brace. Search
+   " for this brace the hard way to prevent errors if the previous line is a
+   " 'pattern { action }' (simple check match on /{/ increases the indent then)
+
+   if s:Get_brace_balance( prev_data, '{', '}' ) > 0
+      return ind + &sw
+   endif
+
+   let brace_balance = s:Get_brace_balance( prev_data, '(', ')' )
+
+   " If prev line has positive brace_balance and starts with a word (keyword
+   " or function name), align the current line on the first '(' of the prev
+   " line
+
+   if brace_balance > 0 && s:Starts_with_word( prev_data )
+      return s:Safe_indent( ind, s:First_word_len(prev_data), getline(v:lnum))
+   endif
+
+   " If this line starts with an open brace bail out now before the line
+   " continuation checks.
+
+   if getline( v:lnum ) =~ '^\s*{'
+      return ind
+   endif
+
+   " If prev line seems to be part of multiline statement:
+   " 1. Prev line is first line of a multiline statement
+   "    -> attempt to indent on first ' ' or '(' of prev line, just like we
+   "       indented the positive brace balance case above
+   " 2. Prev line is not first line of a multiline statement
+   "    -> copy indent of prev line
+
+   let continue_mode = s:Seems_continuing( prev_data )
+   if continue_mode > 0
+     if s:Seems_continuing( getline(s:Get_prev_line( prev_lineno )) )
+       " Case 2
+       return ind
+     else
+       " Case 1
+       if continue_mode == 1
+	  " Need continuation due to comma, backslash, etc
+	  return s:Safe_indent( ind, s:First_word_len(prev_data), getline(v:lnum))
+       else
+	 " if/for/while without '{'
+	 return ind + &sw
+       endif
+     endif
+   endif
+
+   " If the previous line doesn't need continuation on the current line we are
+   " on the start of a new statement.  We have to make sure we align with the
+   " previous statement instead of just the previous line. This is a bit
+   " complicated because the previous statement might be multi-line.
+   "
+   " The start of a multiline statement can be found by:
+   "
+   " 1 If the previous line contains closing braces and has negative brace
+   "   balance, search backwards until cumulative brace balance becomes zero,
+   "   take indent of that line
+   " 2 If the line before the previous needs continuation search backward
+   "   until that's not the case anymore. Take indent of one line down.
+
+   " Case 1
+   if prev_data =~ ')' && brace_balance < 0
+      while brace_balance != 0
+	 let prev_lineno = s:Get_prev_line( prev_lineno )
+	 let prev_data = getline( prev_lineno )
+	 let brace_balance=brace_balance+s:Get_brace_balance(prev_data,'(',')' )
+      endwhile
+      let ind = indent( prev_lineno )
+   else
+      " Case 2
+      if s:Seems_continuing( getline( prev_lineno - 1 ) )
+	 let prev_lineno = prev_lineno - 2
+	 let prev_data = getline( prev_lineno )
+	 while prev_lineno > 0 && (s:Seems_continuing( prev_data ) > 0)
+	    let prev_lineno = s:Get_prev_line( prev_lineno )
+	    let prev_data = getline( prev_lineno )
+	 endwhile
+	 let ind = indent( prev_lineno + 1 )
+      endif
+   endif
+
+   " Decrease indent if this line contains a '}'.
+   if getline(v:lnum) =~ '^\s*}'
+      let ind = ind - &sw
+   endif
+
+   return ind
+endfunction
+
+" Find the open and close braces in this line and return how many more open-
+" than close braces there are. It's also used to determine cumulative balance
+" across multiple lines.
+
+function! s:Get_brace_balance( line, b_open, b_close )
+   let line2 = substitute( a:line, a:b_open, "", "g" )
+   let openb = strlen( a:line ) - strlen( line2 )
+   let line3 = substitute( line2, a:b_close, "", "g" )
+   let closeb = strlen( line2 ) - strlen( line3 )
+   return openb - closeb
+endfunction
+
+" Find out whether the line starts with a word (i.e. keyword or function
+" call). Might need enhancements here.
+
+function! s:Starts_with_word( line )
+  if a:line =~ '^\s*[a-zA-Z_0-9]\+\s*('
+     return 1
+  endif
+  return 0
+endfunction
+
+" Find the length of the first word in a line. This is used to be able to
+" align a line relative to the 'print ' or 'if (' on the previous line in case
+" such a statement spans multiple lines.
+" Precondition: only to be used on lines where 'Starts_with_word' returns 1.
+
+function! s:First_word_len( line )
+   let white_end = matchend( a:line, '^\s*' )
+   if match( a:line, '^\s*func' ) != -1
+     let word_end = matchend( a:line, '[a-z]\+\s\+[a-zA-Z_0-9]\+[ (]*' )
+   else
+     let word_end = matchend( a:line, '[a-zA-Z_0-9]\+[ (]*' )
+   endif
+   return word_end - white_end
+endfunction
+
+" Determine if 'line' completes a statement or is continued on the next line.
+" This one is far from complete and accepts illegal code. Not important for
+" indenting, however.
+
+function! s:Seems_continuing( line )
+  " Unfinished lines
+  if a:line =~ '[\\,\|\&\+\-\*\%\^]\s*$'
+    return 1
+  endif
+  " if/for/while (cond) eol
+  if a:line =~ '^\s*\(if\|while\|for\)\s*(.*)\s*$' || a:line =~ '^\s*else\s*'
+      return 2
+   endif
+  return 0
+endfunction
+
+" Get previous relevant line. Search back until a line is that is no
+" comment or blank and return the line number
+
+function! s:Get_prev_line( lineno )
+   let lnum = a:lineno - 1
+   let data = getline( lnum )
+   while lnum > 0 && (data =~ '^\s*#' || data =~ '^\s*$')
+      let lnum = lnum - 1
+      let data = getline( lnum )
+   endwhile
+   return lnum
+endfunction
+
+" This function checks whether an indented line exceeds a maximum linewidth
+" (hardcoded 80). If so and it is possible to stay within 80 positions (or
+" limit num of characters beyond linewidth) by decreasing the indent (keeping
+" it > base_indent), do so.
+
+function! s:Safe_indent( base, wordlen, this_line )
+   let line_base = matchend( a:this_line, '^\s*' )
+   let line_len = strlen( a:this_line ) - line_base
+   let indent = a:base
+   if (indent + a:wordlen + line_len) > 80
+     " Simple implementation good enough for the time being
+     let indent = indent + 3
+   endif
+   return indent + a:wordlen
+endfunction
--- /dev/null
+++ b/lib/vimfiles/indent/bib.vim
@@ -1,0 +1,15 @@
+" Vim indent file
+" Language:      BibTeX
+" Maintainer:    Dorai Sitaram <ds26@gte.com>
+" URL:		 http://www.ccs.neu.edu/~dorai/vimplugins/vimplugins.html
+" Last Change:   2005 Mar 28
+
+" Only do this when not done yet for this buffer
+if exists("b:did_indent")
+  finish
+endif
+let b:did_indent = 1
+
+setlocal cindent
+
+let b:undo_indent = "setl cin<"
--- /dev/null
+++ b/lib/vimfiles/indent/bst.vim
@@ -1,0 +1,75 @@
+" Vim indent file
+" Language:	bst
+" Author:	Tim Pope <vimNOSPAM@tpope.info>
+" $Id: bst.vim,v 1.1 2007/05/05 18:11:12 vimboss Exp $
+
+if exists("b:did_indent")
+    finish
+endif
+let b:did_indent = 1
+
+setlocal expandtab
+setlocal indentexpr=GetBstIndent(v:lnum)
+"setlocal smartindent
+setlocal cinkeys&
+setlocal cinkeys-=0#
+setlocal indentkeys&
+"setlocal indentkeys+=0%
+
+" Only define the function once.
+if exists("*GetBstIndent")
+    finish
+endif
+
+function! s:prevgood(lnum)
+    " Find a non-blank line above the current line.
+    " Skip over comments.
+    let lnum = a:lnum
+    while lnum > 0
+        let lnum = prevnonblank(lnum - 1)
+        if getline(lnum) !~ '^\s*%.*$'
+            break
+        endif
+    endwhile
+    return lnum
+endfunction
+
+function! s:strip(lnum)
+    let line = getline(a:lnum)
+    let line = substitute(line,'"[^"]*"','""','g')
+    let line = substitute(line,'%.*','','')
+    let line = substitute(line,'^\s\+','','')
+    return line
+endfunction
+
+function! s:count(string,char)
+    let str = substitute(a:string,'[^'.a:char.']','','g')
+    return strlen(str)
+endfunction
+
+function! GetBstIndent(lnum) abort
+    if a:lnum == 1
+        return 0
+    endif
+    let lnum = s:prevgood(a:lnum)
+    if lnum <= 0
+        return indent(a:lnum - 1)
+    endif
+    let line = s:strip(lnum)
+    let cline = s:strip(a:lnum)
+    if cline =~ '^}' && exists("b:current_syntax")
+        call cursor(a:lnum,indent(a:lnum))
+        if searchpair('{','','}','bW',"synIDattr(synID(line('.'),col('.'),1),'name') =~? 'comment\\|string'")
+            if col('.')+1 == col('$')
+                return indent('.')
+            else
+                return virtcol('.')-1
+            endif
+        endif
+    endif
+    let fakeline = substitute(line,'^}','','').matchstr(cline,'^}')
+    let ind = indent(lnum)
+    let ind = ind + &sw * s:count(line,'{')
+    let ind = ind - &sw * s:count(fakeline,'}')
+    return ind
+endfunction
--- /dev/null
+++ b/lib/vimfiles/indent/c.vim
@@ -1,0 +1,15 @@
+" Vim indent file
+" Language:	C
+" Maintainer:	Bram Moolenaar <Bram@vim.org>
+" Last Change:	2005 Mar 27
+
+" Only load this indent file when no other was loaded.
+if exists("b:did_indent")
+   finish
+endif
+let b:did_indent = 1
+
+" C indenting is built-in, thus this is very simple
+setlocal cindent
+
+let b:undo_indent = "setl cin<"
--- /dev/null
+++ b/lib/vimfiles/indent/cdl.vim
@@ -1,0 +1,129 @@
+" Description:	Comshare Dimension Definition Language (CDL)
+" Author:	Raul Segura Acevedo <raulseguraaceved@netscape.net>
+" Last Change:	Fri Nov 30 13:35:48  2001 CST
+
+if exists("b:did_indent")
+    "finish
+endif
+let b:did_indent = 1
+
+setlocal indentexpr=CdlGetIndent(v:lnum)
+setlocal indentkeys&
+setlocal indentkeys+==~else,=~endif,=~then,;,),=
+
+" Only define the function once.
+if exists("*CdlGetIndent")
+    "finish
+endif
+
+" find out if an "...=..." expresion its an asignment (or a conditional)
+" it scans 'line' first, and then the previos lines
+fun! CdlAsignment(lnum, line)
+  let f = -1
+  let lnum = a:lnum
+  let line = a:line
+  while lnum > 0 && f == -1
+    " line without members [a] of [b]:[c]...
+    let inicio = 0
+    while 1
+      " keywords that help to decide
+      let inicio = matchend(line, '\c\<\(expr\|\a*if\|and\|or\|not\|else\|then\|memberis\|\k\+of\)\>\|[<>;]', inicio)
+      if inicio < 0
+	break
+      endif
+      " it's formula if there's a ';', 'elsE', 'theN', 'enDif' or 'expr'
+      " conditional if there's a '<', '>', 'elseif', 'if', 'and', 'or', 'not',
+      " 'memberis', 'childrenof' and other \k\+of funcions
+      let f = line[inicio-1] =~? '[en;]' || strpart(line, inicio-4, 4) =~? 'ndif\|expr'
+    endw
+    let lnum = prevnonblank(lnum-1)
+    let line = substitute(getline(lnum), '\c\(\[[^]]*]\(\s*of\s*\|:\)*\)\+', ' ', 'g')
+  endw
+  " if we hit the start of the file then f = -1, return 1 (formula)
+  return f != 0
+endf
+
+fun! CdlGetIndent(lnum)
+  let thisline = getline(a:lnum)
+  if match(thisline, '^\s*\(\k\+\|\[[^]]*]\)\s*\(,\|;\s*$\)') >= 0
+    " it's an attributes line
+    return &sw
+  elseif match(thisline, '^\c\s*\([{}]\|\/[*/]\|dimension\|schedule\|group\|hierarchy\|class\)') >= 0
+    " it's a header or '{' or '}' or a comment
+    return 0
+  end
+
+  let lnum = prevnonblank(a:lnum-1)
+  " Hit the start of the file, use zero indent.
+  if lnum == 0
+    return 0
+  endif
+
+  " PREVIOUS LINE
+  let ind = indent(lnum)
+  let line = getline(lnum)
+  let f = -1 " wether a '=' is a conditional or a asignment, -1 means we don't know yet
+  " one 'closing' element at the beginning of the line has already reduced the
+  "   indent, but 'else', 'elseif' & 'then' increment it for the next line
+  " '=' at the beginning has already de right indent (increased for asignments)
+  let inicio = matchend(line, '^\c\s*\(else\a*\|then\|endif\|/[*/]\|[);={]\)')
+  if inicio > 0
+    let c = line[inicio-1]
+    " ')' and '=' don't change indent and are useless to set 'f'
+    if c == '{'
+      return &sw
+    elseif c != ')' && c != '='
+      let f = 1 " all but 'elseif' are followed by a formula
+      if c ==? 'n' || c ==? 'e' " 'then', 'else'
+	let ind = ind + &sw
+      elseif strpart(line, inicio-6, 6) ==? 'elseif' " elseif, set f to conditional
+	let ind = ind + &sw
+	let f = 0
+      end
+    end
+  end
+
+  " remove members [a] of [b]:[c]... (inicio remainds valid)
+  let line = substitute(line, '\c\(\[[^]]*]\(\s*of\s*\|:\)*\)\+', ' ', 'g')
+  while 1
+    " search for the next interesting element
+    let inicio=matchend(line, '\c\<if\|endif\|[()=;]', inicio)
+    if inicio < 0
+      break
+    end
+
+    let c = line[inicio-1]
+    " 'expr(...)' containing the formula
+    if strpart(line, inicio-5, 5) ==? 'expr('
+      let ind = 0
+      let f = 1
+    elseif c == ')' || c== ';' || strpart(line, inicio-5, 5) ==? 'endif'
+      let ind = ind - &sw
+    elseif c == '(' || c ==? 'f' " '(' or 'if'
+      let ind = ind + &sw
+    else " c == '='
+      " if it is an asignment increase indent
+      if f == -1 " we don't know yet, find out
+	let f = CdlAsignment(lnum, strpart(line, 0, inicio))
+      end
+      if f == 1 " formula increase it
+	let ind = ind + &sw
+      end
+    end
+  endw
+
+  " CURRENT LINE, if it starts with a closing element, decrease indent
+  " or if it starts with '=' (asignment), increase indent
+  if match(thisline, '^\c\s*\(else\|then\|endif\|[);]\)') >= 0
+    let ind = ind - &sw
+  elseif match(thisline, '^\s*=') >= 0
+    if f == -1 " we don't know yet if is an asignment, find out
+      let f = CdlAsignment(lnum, "")
+    end
+    if f == 1 " formula increase it
+      let ind = ind + &sw
+    end
+  end
+
+  return ind
+endfun
--- /dev/null
+++ b/lib/vimfiles/indent/ch.vim
@@ -1,0 +1,18 @@
+" Vim indent file
+" Language:	Ch
+" Maintainer:	SoftIntegration, Inc. <info@softintegration.com>
+" URL:		http://www.softintegration.com/download/vim/indent/ch.vim
+" Last change:	2006 Apr 30
+"		Created based on cpp.vim
+"
+" Ch is a C/C++ interpreter with many high level extensions
+
+
+" Only load this indent file when no other was loaded.
+if exists("b:did_indent")
+   finish
+endif
+let b:did_indent = 1
+
+" Ch indenting is built-in, thus this is very simple
+setlocal cindent
--- /dev/null
+++ b/lib/vimfiles/indent/changelog.vim
@@ -1,0 +1,14 @@
+" Vim indent file
+" Language:	generic Changelog file
+" Maintainer:	noone
+" Last Change:	2005 Mar 29
+
+" Only load this indent file when no other was loaded.
+if exists("b:did_indent")
+   finish
+endif
+let b:did_indent = 1
+
+setlocal ai
+
+let b:undo_indent = "setl ai<"
--- /dev/null
+++ b/lib/vimfiles/indent/cmake.vim
@@ -1,0 +1,92 @@
+" =============================================================================
+"
+"   Program:   CMake - Cross-Platform Makefile Generator
+"   Module:    $RCSfile: cmake.vim,v $
+"   Language:  VIM
+"   Date:      $Date: 2006/04/30 18:41:59 $
+"   Version:   $Revision: 1.3 $
+"
+" =============================================================================
+
+" Vim indent file
+" Language:     CMake (ft=cmake)
+" Author:       Andy Cedilnik <andy.cedilnik@kitware.com>
+" Maintainer:   Andy Cedilnik <andy.cedilnik@kitware.com>
+" Last Change:  $Date: 2006/04/30 18:41:59 $
+" Version:      $Revision: 1.3 $
+"
+" Licence:      The CMake license applies to this file. See
+"               http://www.cmake.org/HTML/Copyright.html
+"               This implies that distribution with Vim is allowed
+
+if exists("b:did_indent")
+  finish
+endif
+let b:did_indent = 1
+
+setlocal indentexpr=CMakeGetIndent(v:lnum)
+
+" Only define the function once.
+if exists("*CMakeGetIndent")
+  finish
+endif
+
+fun! CMakeGetIndent(lnum)
+  let this_line = getline(a:lnum)
+
+  " Find a non-blank line above the current line.
+  let lnum = a:lnum
+  let lnum = prevnonblank(lnum - 1)
+  let previous_line = getline(lnum)
+
+  " Hit the start of the file, use zero indent.
+  if lnum == 0
+    return 0
+  endif
+
+  let ind = indent(lnum)
+
+  let or = '\|'
+  " Regular expressions used by line indentation function.
+  let cmake_regex_comment = '#.*'
+  let cmake_regex_identifier = '[A-Za-z][A-Za-z0-9_]*'
+  let cmake_regex_quoted = '"\([^"\\]\|\\.\)*"'
+  let cmake_regex_arguments = '\(' . cmake_regex_quoted .
+                    \       or . '\$(' . cmake_regex_identifier . ')' .
+                    \       or . '[^()\\#"]' . or . '\\.' . '\)*'
+
+  let cmake_indent_comment_line = '^\s*' . cmake_regex_comment
+  let cmake_indent_blank_regex = '^\s*$'
+  let cmake_indent_open_regex = '^\s*' . cmake_regex_identifier .
+                    \           '\s*(' . cmake_regex_arguments .
+                    \           '\(' . cmake_regex_comment . '\)\?$'
+
+  let cmake_indent_close_regex = '^' . cmake_regex_arguments .
+                    \            ')\s*' .
+                    \            '\(' . cmake_regex_comment . '\)\?$'
+
+  let cmake_indent_begin_regex = '^\s*\(IF\|MACRO\|FOREACH\|ELSE\|WHILE\)\s*('
+  let cmake_indent_end_regex = '^\s*\(ENDIF\|ENDFOREACH\|ENDMACRO\|ELSE\|ENDWHILE\)\s*('
+
+  " Add
+  if previous_line =~? cmake_indent_comment_line " Handle comments
+    let ind = ind
+  else
+    if previous_line =~? cmake_indent_begin_regex
+      let ind = ind + &sw
+    endif
+    if previous_line =~? cmake_indent_open_regex
+      let ind = ind + &sw
+    endif
+  endif
+
+  " Subtract
+  if this_line =~? cmake_indent_end_regex
+    let ind = ind - &sw
+  endif
+  if previous_line =~? cmake_indent_close_regex
+    let ind = ind - &sw
+  endif
+
+  return ind
+endfun
--- /dev/null
+++ b/lib/vimfiles/indent/cobol.vim
@@ -1,0 +1,216 @@
+" Vim indent file
+" Language:	cobol
+" Author:	Tim Pope <vimNOSPAM@tpope.info>
+" $Id: cobol.vim,v 1.1 2007/05/05 18:08:19 vimboss Exp $
+
+if exists("b:did_indent")
+    finish
+endif
+let b:did_indent = 1
+
+setlocal expandtab
+setlocal indentexpr=GetCobolIndent(v:lnum)
+setlocal indentkeys&
+setlocal indentkeys+=0<*>,0/,0$,0=01,=~division,=~section,0=~end,0=~then,0=~else,0=~when,*<Return>,.
+
+" Only define the function once.
+if exists("*GetCobolIndent")
+    finish
+endif
+
+let s:skip = 'getline(".") =~ "^.\\{6\\}[*/$-]\\|\"[^\"]*\""'
+
+function! s:prevgood(lnum)
+    " Find a non-blank line above the current line.
+    " Skip over comments.
+    let lnum = a:lnum
+    while lnum > 0
+        let lnum = prevnonblank(lnum - 1)
+        let line = getline(lnum)
+        if line !~? '^\s*[*/$-]' && line !~? '^.\{6\}[*/$CD-]'
+            break
+        endif
+    endwhile
+    return lnum
+endfunction
+
+function! s:stripped(lnum)
+    return substitute(strpart(getline(a:lnum),0,72),'^\s*','','')
+endfunction
+
+function! s:optionalblock(lnum,ind,blocks,clauses)
+    let ind = a:ind
+    let clauses = '\c\<\%(\<NOT\s\+\)\@<!\%(NOT\s\+\)\=\%('.a:clauses.'\)'
+    let begin = '\c-\@<!\<\%('.a:blocks.'\)\>'
+    let beginfull = begin.'\ze.*\%(\n\%(\s*\%([*/$-].*\)\=\n\)*\)\=\s*\%('.clauses.'\)'
+    let end   = '\c\<end-\%('.a:blocks.'\)\>\|\%(\.\%( \|$\)\)\@='
+    let cline = s:stripped(a:lnum)
+    let line  = s:stripped(s:prevgood(a:lnum))
+    if cline =~? clauses "&& line !~? '^search\>'
+        call cursor(a:lnum,1)
+        let lastclause = searchpair(beginfull,clauses,end,'bWr',s:skip)
+        if getline(lastclause) =~? clauses && s:stripped(lastclause) !~? '^'.begin
+            let ind = indent(lastclause)
+        elseif lastclause > 0
+            let ind = indent(lastclause) + &sw
+            "let ind = ind + &sw
+        endif
+    elseif line =~? clauses && cline !~? end
+        let ind = ind + &sw
+    endif
+    return ind
+endfunction
+
+function! GetCobolIndent(lnum) abort
+    let minshft = 6
+    let ashft = minshft + 1
+    let bshft = ashft + 4
+    " (Obsolete) numbered lines
+    if getline(a:lnum) =~? '^\s*\d\{6\}\%($\|[ */$CD-]\)'
+        return 0
+    endif
+    let cline = s:stripped(a:lnum)
+    " Comments, etc. must start in the 7th column
+    if cline =~? '^[*/$-]'
+        return minshft
+    elseif cline =~# '^[CD]' && indent(a:lnum) == minshft
+        return minshft
+    endif
+    " Divisions, sections, and file descriptions start in area A
+    if cline =~? '\<\(DIVISION\|SECTION\)\%($\|\.\)' || cline =~? '^[FS]D\>'
+        return ashft
+    endif
+    " Fields
+    if cline =~? '^0*\(1\|77\)\>'
+        return ashft
+    endif
+    if cline =~? '^\d\+\>'
+        let cnum = matchstr(cline,'^\d\+\>')
+        let default = 0
+        let step = -1
+        while step < 2
+        let lnum = a:lnum
+        while lnum > 0 && lnum < line('$') && lnum > a:lnum - 500 && lnum < a:lnum + 500
+            let lnum = step > 0 ? nextnonblank(lnum + step) : prevnonblank(lnum + step)
+            let line = getline(lnum)
+            let lindent = indent(lnum)
+            if line =~? '^\s*\d\+\>'
+                let num = matchstr(line,'^\s*\zs\d\+\>')
+                if 0+cnum == num
+                    return lindent
+                elseif 0+cnum > num && default < lindent + &sw
+                    let default = lindent + &sw
+                endif
+            elseif lindent < bshft && lindent >= ashft
+                break
+            endif
+        endwhile
+        let step = step + 2
+        endwhile
+        return default ? default : bshft
+    endif
+    let lnum = s:prevgood(a:lnum)
+    " Hit the start of the file, use "zero" indent.
+    if lnum == 0
+        return ashft
+    endif
+    " Initial spaces are ignored
+    let line = s:stripped(lnum)
+    let ind = indent(lnum)
+    " Paragraphs.  There may be some false positives.
+    if cline =~? '^\(\a[A-Z0-9-]*[A-Z0-9]\|\d[A-Z0-9-]*\a\)\.' "\s*$'
+        if cline !~? '^EXIT\s*\.' && line =~? '\.\s*$'
+            return ashft
+        endif
+    endif
+    " Paragraphs in the identification division.
+    "if cline =~? '^\(PROGRAM-ID\|AUTHOR\|INSTALLATION\|' .
+                "\ 'DATE-WRITTEN\|DATE-COMPILED\|SECURITY\)\>'
+        "return ashft
+    "endif
+    if line =~? '\.$'
+        " XXX
+        return bshft
+    endif
+    if line =~? '^PERFORM\>'
+        let perfline = substitute(line, '\c^PERFORM\s*', "", "")
+        if perfline =~? '^\%(\k\+\s\+TIMES\)\=\s*$'
+            let ind = ind + &sw
+        elseif perfline =~? '^\%(WITH\s\+TEST\|VARYING\|UNTIL\)\>.*[^.]$'
+            let ind = ind + &sw
+        endif
+    endif
+    if line =~? '^\%(IF\|THEN\|ELSE\|READ\|EVALUATE\|SEARCH\|SELECT\)\>'
+        let ind = ind + &sw
+    endif
+    let ind = s:optionalblock(a:lnum,ind,'ADD\|COMPUTE\|DIVIDE\|MULTIPLY\|SUBTRACT','ON\s\+SIZE\s\+ERROR')
+    let ind = s:optionalblock(a:lnum,ind,'STRING\|UNSTRING\|ACCEPT\|DISPLAY\|CALL','ON\s\+OVERFLOW\|ON\s\+EXCEPTION')
+    if cline !~? '^AT\s\+END\>' || line !~? '^SEARCH\>'
+        let ind = s:optionalblock(a:lnum,ind,'DELETE\|REWRITE\|START\|WRITE\|READ','INVALID\s\+KEY\|AT\s\+END\|NO\s\+DATA\|AT\s\+END-OF-PAGE')
+    endif
+    if cline =~? '^WHEN\>'
+        call cursor(a:lnum,1)
+        " We also search for READ so that contained AT ENDs are skipped
+        let lastclause = searchpair('\c-\@<!\<\%(SEARCH\|EVALUATE\|READ\)\>','\c\<\%(WHEN\|AT\s\+END\)\>','\c\<END-\%(SEARCH\|EVALUATE\|READ\)\>','bW',s:skip)
+        let g:foo = s:stripped(lastclause)
+        if s:stripped(lastclause) =~? '\c\<\%(WHEN\|AT\s\+END\)\>'
+            "&& s:stripped(lastclause) !~? '^\%(SEARCH\|EVALUATE\|READ\)\>'
+            let ind = indent(lastclause)
+        elseif lastclause > 0
+            let ind = indent(lastclause) + &sw
+        endif
+    elseif line =~? '^WHEN\>'
+        let ind = ind + &sw
+    endif
+    "I'm not sure why I had this
+    "if line =~? '^ELSE\>-\@!' && line !~? '\.$'
+        "let ind = indent(s:prevgood(lnum))
+    "endif
+    if cline =~? '^\(END\)\>-\@!'
+        " On lines with just END, 'guess' a simple shift left
+        let ind = ind - &sw
+    elseif cline =~? '^\(END-IF\|THEN\|ELSE\)\>-\@!'
+        call cursor(a:lnum,indent(a:lnum))
+        let match = searchpair('\c-\@<!\<IF\>','\c-\@<!\%(THEN\|ELSE\)\>','\c-\@<!\<END-IF\>\zs','bnW',s:skip)
+        if match > 0
+            let ind = indent(match)
+        endif
+    elseif cline =~? '^END-[A-Z]'
+        let beginword = matchstr(cline,'\c\<END-\zs[A-Z0-9-]\+')
+        let endword = 'END-'.beginword
+        let first = 0
+        let suffix = '.*\%(\n\%(\%(\s*\|.\{6\}\)[*/].*\n\)*\)\=\s*'
+        if beginword =~? '^\%(ADD\|COMPUTE\|DIVIDE\|MULTIPLY\|SUBTRACT\)$'
+            let beginword = beginword . suffix . '\<\%(NOT\s\+\)\=ON\s\+SIZE\s\+ERROR'
+            let g:beginword = beginword
+            let first = 1
+        elseif beginword =~? '^\%(STRING\|UNSTRING\)$'
+            let beginword = beginword . suffix . '\<\%(NOT\s\+\)\=ON\s\+OVERFLOW'
+            let first = 1
+        elseif beginword =~? '^\%(ACCEPT\|DISPLAY\)$'
+            let beginword = beginword . suffix . '\<\%(NOT\s\+\)\=ON\s\+EXCEPTION'
+            let first = 1
+        elseif beginword ==? 'CALL'
+            let beginword = beginword . suffix . '\<\%(NOT\s\+\)\=ON\s\+\%(EXCEPTION\|OVERFLOW\)'
+            let first = 1
+        elseif beginword =~? '^\%(DELETE\|REWRITE\|START\|READ\|WRITE\)$'
+            let first = 1
+            let beginword = beginword . suffix . '\<\%(NOT\s\+\)\=\(INVALID\s\+KEY'
+            if beginword =~? '^READ'
+                let first = 0
+                let beginword = beginword . '\|AT\s\+END\|NO\s\+DATA'
+            elseif beginword =~? '^WRITE'
+                let beginword = beginword . '\|AT\s\+END-OF-PAGE'
+            endif
+            let beginword = beginword . '\)'
+        endif
+        call cursor(a:lnum,indent(a:lnum))
+        let match = searchpair('\c-\@<!\<'.beginword.'\>','','\c\<'.endword.'\>\zs','bnW'.(first? 'r' : ''),s:skip)
+        if match > 0
+            let ind = indent(match)
+        elseif cline =~? '^\(END-\(READ\|EVALUATE\|SEARCH\|PERFORM\)\)\>'
+            let ind = ind - &sw
+        endif
+    endif
+    return ind < bshft ? bshft : ind
+endfunction
--- /dev/null
+++ b/lib/vimfiles/indent/config.vim
@@ -1,0 +1,82 @@
+" Vim indent file
+" Language:         Autoconf configure.{ac,in} file
+" Maintainer:       Nikolai Weibull <now@bitwi.se>
+" Latest Revision:  2006-12-20
+" TODO:             how about nested [()]'s in one line
+"                   what's wrong with '\\\@!'?
+
+" Only load this indent file when no other was loaded.
+if exists("b:did_indent")
+  finish
+endif
+
+runtime! indent/sh.vim          " will set b:did_indent
+
+setlocal indentexpr=GetConfigIndent()
+setlocal indentkeys=!^F,o,O,=then,=do,=else,=elif,=esac,=fi,=fin,=fil,=done
+setlocal nosmartindent
+
+" Only define the function once.
+if exists("*GetConfigIndent")
+  finish
+endif
+
+" get the offset (indent) of the end of the match of 'regexp' in 'line'
+function s:GetOffsetOf(line, regexp)
+  let end = matchend(a:line, a:regexp)
+  let width = 0
+  let i = 0
+  while i < end
+    if a:line[i] != "\t"
+      let width = width + 1
+    else
+      let width = width + &ts - (width % &ts)
+    endif
+    let i = i + 1
+  endwhile
+  return width
+endfunction
+
+function GetConfigIndent()
+  " Find a non-blank line above the current line.
+  let lnum = prevnonblank(v:lnum - 1)
+
+  " Hit the start of the file, use zero indent.
+  if lnum == 0
+    return 0
+  endif
+
+  " where to put this
+  let ind = GetShIndent()
+  let line = getline(lnum)
+
+  " if previous line has unmatched, unescaped opening parentheses,
+  " indent to its position. TODO: not failsafe if multiple ('s
+  if line =~ '\\\@<!([^)]*$'
+    let ind = s:GetOffsetOf(line, '\\\@!(')
+  endif
+
+  " if previous line has unmatched opening bracket,
+  " indent to its position. TODO: same as above
+  if line =~ '\[[^]]*$'
+    let ind = s:GetOffsetOf(line, '\[')
+  endif
+
+  " if previous line had an unmatched closing parantheses,
+  " indent to the matching opening parantheses
+  if line =~ '[^(]\+\\\@<!)$'
+    call search(')', 'bW')
+    let lnum = searchpair('\\\@<!(', '', ')', 'bWn')
+    let ind = indent(lnum)
+  endif
+
+  " if previous line had an unmatched closing bracket,
+  " indent to the matching opening bracket
+  if line =~ '[^[]\+]$'
+    call search(']', 'bW')
+    let lnum = searchpair('\[', '', ']', 'bWn')
+    let ind = indent(lnum)
+  endif
+
+  return ind
+endfunction
--- /dev/null
+++ b/lib/vimfiles/indent/cpp.vim
@@ -1,0 +1,13 @@
+" Vim indent file
+" Language:	C++
+" Maintainer:	Bram Moolenaar <Bram@vim.org>
+" Last Change:	2001 Jun 12
+
+" Only load this indent file when no other was loaded.
+if exists("b:did_indent")
+   finish
+endif
+let b:did_indent = 1
+
+" C++ indenting is built-in, thus this is very simple
+setlocal cindent
--- /dev/null
+++ b/lib/vimfiles/indent/cs.vim
@@ -1,0 +1,15 @@
+" Vim indent file
+" Language:	C#
+" Maintainer:	Johannes Zellner <johannes@zellner.org>
+" Last Change:	Fri, 15 Mar 2002 07:53:54 CET
+
+" Only load this indent file when no other was loaded.
+if exists("b:did_indent")
+   finish
+endif
+let b:did_indent = 1
+
+" C# is like indenting C
+setlocal cindent
+
+let b:undo_indent = "setl cin<"
--- /dev/null
+++ b/lib/vimfiles/indent/css.vim
@@ -1,0 +1,84 @@
+" Vim indent file
+" Language:	    CSS
+" Maintainer:	    Nikolai Weibull <now@bitwi.se>
+" Latest Revision:  2006-12-20
+
+if exists("b:did_indent")
+  finish
+endif
+let b:did_indent = 1
+
+setlocal indentexpr=GetCSSIndent()
+setlocal indentkeys=0{,0},!^F,o,O
+setlocal nosmartindent
+
+if exists("*GetCSSIndent")
+  finish
+endif
+
+function s:prevnonblanknoncomment(lnum)
+  let lnum = a:lnum
+  while lnum > 1
+    let lnum = prevnonblank(lnum)
+    let line = getline(lnum)
+    if line =~ '\*/'
+      while lnum > 1 && line !~ '/\*'
+        let lnum -= 1
+      endwhile
+      if line =~ '^\s*/\*'
+        let lnum -= 1
+      else
+        break
+      endif
+    else
+      break
+    endif
+  endwhile
+  return lnum
+endfunction
+
+function s:count_braces(lnum, count_open)
+  let n_open = 0
+  let n_close = 0
+  let line = getline(a:lnum)
+  let pattern = '[{}]'
+  let i = match(line, pattern)
+  while i != -1
+    if synIDattr(synID(a:lnum, i + 1, 0), 'name') !~ 'css\%(Comment\|StringQ\{1,2}\)'
+      if line[i] == '{'
+        let n_open += 1
+      elseif line[i] == '}'
+        if n_open > 0
+          let n_open -= 1
+        else
+          let n_close += 1
+        endif
+      endif
+    endif
+    let i = match(line, pattern, i + 1)
+  endwhile
+  return a:count_open ? n_open : n_close
+endfunction
+
+function GetCSSIndent()
+  let line = getline(v:lnum)
+  if line =~ '^\s*\*'
+    return cindent(v:lnum)
+  elseif line =~ '^\s*}'
+    return indent(v:lnum) - &sw
+  endif
+
+  let pnum = s:prevnonblanknoncomment(v:lnum - 1)
+  if pnum == 0
+    return 0
+  endif
+
+  let ind = indent(pnum) + s:count_braces(pnum, 1) * &sw
+
+  let pline = getline(pnum)
+  if pline =~ '}\s*$'
+    let ind -= (s:count_braces(pnum, 0) - (pline =~ '^\s*}' ? 1 : 0)) * &sw
+  endif
+
+  return ind
+endfunction
--- /dev/null
+++ b/lib/vimfiles/indent/d.vim
@@ -1,0 +1,22 @@
+" Vim indent file for the D programming language (version 0.137).
+"
+" Language:	D
+" Maintainer:	Jason Mills<jmills@cs.mun.ca>
+" Last Change:	2005 Nov 22
+" Version:	0.1
+"
+" Please email me with bugs, comments, and suggestion. Put vim in the subject
+" to ensure the email will not be marked has spam.
+"
+
+" Only load this indent file when no other was loaded.
+if exists("b:did_indent")
+  finish
+endif
+
+let b:did_indent = 1
+
+" D indenting is a lot like the built-in C indenting.
+setlocal cindent
+
+" vim: ts=8 noet
--- /dev/null
+++ b/lib/vimfiles/indent/dictconf.vim
@@ -1,0 +1,13 @@
+" Vim indent file
+" Language:         dict(1) configuration file
+" Maintainer:       Nikolai Weibull <now@bitwi.se>
+" Latest Revision:  2006-12-20
+
+if exists("b:did_indent")
+  finish
+endif
+let b:did_indent = 1
+
+setlocal indentkeys=0{,0},!^F,o,O cinwords= autoindent smartindent
+setlocal nosmartindent
+inoremap <buffer> # X#
--- /dev/null
+++ b/lib/vimfiles/indent/dictdconf.vim
@@ -1,0 +1,13 @@
+" Vim indent file
+" Language:         dictd(8) configuration file
+" Maintainer:       Nikolai Weibull <now@bitwi.se>
+" Latest Revision:  2006-12-20
+
+if exists("b:did_indent")
+  finish
+endif
+let b:did_indent = 1
+
+setlocal indentkeys=0{,0},!^F,o,O cinwords= autoindent smartindent
+setlocal nosmartindent
+inoremap <buffer> # X#
--- /dev/null
+++ b/lib/vimfiles/indent/docbk.vim
@@ -1,0 +1,15 @@
+" Vim indent file
+" Language:	    DocBook Documentation Format
+" Maintainer:       Nikolai Weibull <now@bitwi.se>
+" Latest Revision:  2006-04-19
+
+if exists("b:did_indent")
+  finish
+endif
+
+" Same as XML indenting for now.
+runtime! indent/xml.vim
+
+if exists('*XmlIndentGet')
+  setlocal indentexpr=XmlIndentGet(v:lnum,0)
+endif
--- /dev/null
+++ b/lib/vimfiles/indent/dylan.vim
@@ -1,0 +1,90 @@
+" Vim indent file
+" Language:	Dylan
+" Version:	0.01
+" Last Change:	2003 Feb 04
+" Maintainer:	Brent A. Fulgham <bfulgham@debian.org>
+
+" Only load this indent file when no other was loaded.
+if exists("b:did_indent")
+  finish
+endif
+let b:did_indent = 1
+
+setlocal indentkeys+==~begin,=~block,=~case,=~cleanup,=~define,=~end,=~else,=~elseif,=~exception,=~for,=~finally,=~if,=~otherwise,=~select,=~unless,=~while
+
+" Define the appropriate indent function but only once
+setlocal indentexpr=DylanGetIndent()
+if exists("*DylanGetIndent")
+  finish
+endif
+
+function DylanGetIndent()
+  " Get the line to be indented
+  let cline = getline(v:lnum)
+
+  " Don't reindent comments on first column
+  if cline =~ '^/\[/\*]'
+    return 0
+  endif
+
+  "Find the previous non-blank line
+  let lnum = prevnonblank(v:lnum - 1)
+  "Use zero indent at the top of the file
+  if lnum == 0
+    return 0
+  endif
+
+  let prevline=getline(lnum)
+  let ind = indent(lnum)
+  let chg = 0
+
+  " If previous line was a comment, use its indent
+  if prevline =~ '^\s*//'
+    return ind
+  endif
+
+  " If previous line was a 'define', indent
+  if prevline =~? '\(^\s*\(begin\|block\|case\|define\|else\|elseif\|for\|finally\|if\|select\|unless\|while\)\|\s*\S*\s*=>$\)'
+    let chg = &sw
+  " local methods indent the shift-width, plus 6 for the 'local'
+  elseif prevline =~? '^\s*local'
+    let chg = &sw + 6
+  " If previous line was a let with no closing semicolon, indent
+  elseif prevline =~? '^\s*let.*[^;]\s*$'
+    let chg = &sw
+  " If previous line opened a parenthesis, and did not close it, indent
+  elseif prevline =~ '^.*(\s*[^)]*\((.*)\)*[^)]*$'
+    return = match( prevline, '(.*\((.*)\|[^)]\)*.*$') + 1
+  "elseif prevline =~ '^.*(\s*[^)]*\((.*)\)*[^)]*$'
+  elseif prevline =~ '^[^(]*)\s*$'
+    " This line closes a parenthesis.  Find opening
+    let curr_line = prevnonblank(lnum - 1)
+    while curr_line >= 0
+      let str = getline(curr_line)
+      if str !~ '^.*(\s*[^)]*\((.*)\)*[^)]*$'
+	let curr_line = prevnonblank(curr_line - 1)
+      else
+	break
+      endif
+    endwhile
+    if curr_line < 0
+      return -1
+    endif
+    let ind = indent(curr_line)
+    " Although we found the closing parenthesis, make sure this
+    " line doesn't start with an indentable command:
+    let curr_str = getline(curr_line)
+    if curr_str =~? '^\s*\(begin\|block\|case\|define\|else\|elseif\|for\|finally\|if\|select\|unless\|while\)'
+      let chg = &sw
+    endif
+  endif
+
+  " If a line starts with end, un-indent (even if we just indented!)
+  if cline =~? '^\s*\(cleanup\|end\|else\|elseif\|exception\|finally\|otherwise\)'
+    let chg = chg - &sw
+  endif
+
+  return ind + chg
+endfunction
+
+" vim:sw=2 tw=130
--- /dev/null
+++ b/lib/vimfiles/indent/eiffel.vim
@@ -1,0 +1,106 @@
+" Vim indent file
+" Language:	Eiffel
+" Maintainer:	Jocelyn Fiat <eiffel@djoce.net>
+" Previous-Maintainer:	David Clarke <gadicath@dishevelled.net>
+" $Date: 2004/12/09 21:33:52 $
+" $Revision: 1.3 $
+" URL: http://www.djoce.net/page/vim/
+" Last Change:	2004 Sept 14 : removed specific value for tab (sw)
+
+" Only load this indent file when no other was loaded.
+if exists("b:did_indent")
+  finish
+endif
+let b:did_indent = 1
+
+setlocal indentexpr=GetEiffelIndent()
+setlocal nolisp
+setlocal nosmartindent
+setlocal nocindent
+setlocal autoindent
+setlocal comments=:--
+setlocal indentkeys+==end,=else,=ensure,=require,=check,=loop,=until
+setlocal indentkeys+==creation,=feature,=inherit,=class,=is,=redefine,=rename,=variant
+setlocal indentkeys+==invariant,=do,=local,=export
+
+" Define some stuff
+" keywords grouped by indenting
+let s:trust_user_indent = '\(+\)\(\s*\(--\).*\)\=$'
+let s:relative_indent = '^\s*\(deferred\|class\|feature\|creation\|inherit\|loop\|from\|until\|if\|else\|elseif\|ensure\|require\|check\|do\|local\|invariant\|variant\|rename\|redefine\|do\|export\)\>'
+let s:outdent = '^\s*\(else\|invariant\|variant\|do\|require\|until\|loop\|local\)\>'
+let s:no_indent = '^\s*\(class\|feature\|creation\|inherit\)\>'
+let s:single_dent = '^[^-]\+[[:alnum:]]\+ is\(\s*\(--\).*\)\=$'
+let s:inheritance_dent = '\s*\(redefine\|rename\|export\)\>'
+
+
+" Only define the function once.
+if exists("*GetEiffelIndent")
+  finish
+endif
+
+function GetEiffelIndent()
+
+  " Eiffel Class indenting
+  "
+  " Find a non-blank line above the current line.
+  let lnum = prevnonblank(v:lnum - 1)
+
+  " At the start of the file use zero indent.
+  if lnum == 0
+    return 0
+  endif
+
+  " trust the user's indenting
+  if getline(lnum) =~ s:trust_user_indent
+    return -1
+  endif
+
+  " Add a 'shiftwidth' after lines that start with an indent word
+  let ind = indent(lnum)
+  if getline(lnum) =~ s:relative_indent
+    let ind = ind + &sw
+  endif
+
+  " Indent to single indent
+  if getline(v:lnum) =~ s:single_dent && getline(v:lnum) !~ s:relative_indent
+	   \ && getline(v:lnum) !~ '\s*\<\(and\|or\|implies\)\>'
+     let ind = &sw
+  endif
+
+  " Indent to double indent
+  if getline(v:lnum) =~ s:inheritance_dent
+     let ind = 2 * &sw
+  endif
+
+  " Indent line after the first line of the function definition
+  if getline(lnum) =~ s:single_dent
+     let ind = ind + &sw
+  endif
+
+  " The following should always be at the start of a line, no indenting
+  if getline(v:lnum) =~ s:no_indent
+     let ind = 0
+  endif
+
+  " Subtract a 'shiftwidth', if this isn't the first thing after the 'is'
+  " or first thing after the 'do'
+  if getline(v:lnum) =~ s:outdent && getline(v:lnum - 1) !~ s:single_dent
+	\ && getline(v:lnum - 1) !~ '^\s*do\>'
+    let ind = ind - &sw
+  endif
+
+  " Subtract a shiftwidth for end statements
+  if getline(v:lnum) =~ '^\s*end\>'
+    let ind = ind - &sw
+  endif
+
+  " set indent of zero end statements that are at an indent of 3, this should
+  " only ever be the class's end.
+  if getline(v:lnum) =~ '^\s*end\>' && ind == &sw
+    let ind = 0
+  endif
+
+  return ind
+endfunction
+
+" vim:sw=2
--- /dev/null
+++ b/lib/vimfiles/indent/eruby.vim
@@ -1,0 +1,73 @@
+" Vim indent file
+" Language:		eRuby
+" Maintainer:		Tim Pope <vimNOSPAM@tpope.info>
+" Info:			$Id: eruby.vim,v 1.9 2007/04/16 17:03:36 tpope Exp $
+" URL:			http://vim-ruby.rubyforge.org
+" Anon CVS:		See above site
+" Release Coordinator:	Doug Kearns <dougkearns@gmail.com>
+
+if exists("b:did_indent")
+  finish
+endif
+
+runtime! indent/ruby.vim
+unlet! b:did_indent
+set indentexpr=
+
+if exists("b:eruby_subtype")
+  exe "runtime! indent/".b:eruby_subtype.".vim"
+else
+  runtime! indent/html.vim
+endif
+unlet! b:did_indent
+
+if &l:indentexpr == ''
+  if &l:cindent
+    let &l:indentexpr = 'cindent(v:lnum)'
+  else
+    let &l:indentexpr = 'indent(prevnonblank(v:lnum-1))'
+  endif
+endif
+let b:eruby_subtype_indentexpr = &l:indentexpr
+
+let b:did_indent = 1
+
+setlocal indentexpr=GetErubyIndent()
+setlocal indentkeys=o,O,*<Return>,<>>,{,},0),0],o,O,!^F,=end,=else,=elsif,=rescue,=ensure,=when
+
+" Only define the function once.
+if exists("*GetErubyIndent")
+  finish
+endif
+
+function! GetErubyIndent()
+  let vcol = col('.')
+  call cursor(v:lnum,1)
+  let inruby = searchpair('<%','','%>')
+  call cursor(v:lnum,vcol)
+  if inruby && getline(v:lnum) !~ '^<%'
+    let ind = GetRubyIndent()
+  else
+    exe "let ind = ".b:eruby_subtype_indentexpr
+  endif
+  let lnum = prevnonblank(v:lnum-1)
+  let line = getline(lnum)
+  let cline = getline(v:lnum)
+  if cline =~# '<%\s*\%(end\|else\|\%(ensure\|rescue\|elsif\|when\).\{-\}\)\s*\%(-\=%>\|$\)'
+    let ind = ind - &sw
+  endif
+  if line =~# '\<do\%(\s*|[^|]*|\)\=\s*-\=%>'
+    let ind = ind + &sw
+  elseif line =~# '<%\s*\%(module\|class\|def\|if\|for\|while\|until\|else\|elsif\|case\|when\|unless\|begin\|ensure\|rescue\)\>.*%>'
+    let ind = ind + &sw
+  endif
+  if line =~# '^\s*<%[=#]\=\s*$' && cline !~# '^\s*end\>'
+    let ind = ind + &sw
+  endif
+  if cline =~# '^\s*-\=%>\s*$'
+    let ind = ind - &sw
+  endif
+  return ind
+endfunction
+
+" vim:set sw=2 sts=2 ts=8 noet ff=unix:
--- /dev/null
+++ b/lib/vimfiles/indent/eterm.vim
@@ -1,0 +1,36 @@
+" Vim indent file
+" Language:         Eterm configuration file
+" Maintainer:       Nikolai Weibull <now@bitwi.se>
+" Latest Revision:  2006-12-20
+
+if exists("b:did_indent")
+  finish
+endif
+let b:did_indent = 1
+
+setlocal indentexpr=GetEtermIndent()
+setlocal indentkeys=!^F,o,O,=end
+setlocal nosmartindent
+
+if exists("*GetEtermIndent")
+  finish
+endif
+
+function GetEtermIndent()
+  let lnum = prevnonblank(v:lnum - 1)
+  if lnum == 0
+    return 0
+  endif
+
+  let ind = indent(lnum)
+
+  if getline(lnum) =~ '^\s*begin\>'
+    let ind = ind + &sw
+  endif
+
+  if getline(v:lnum) =~ '^\s*end\>'
+    let ind = ind - &sw
+  endif
+
+  return ind
+endfunction
--- /dev/null
+++ b/lib/vimfiles/indent/fortran.vim
@@ -1,0 +1,167 @@
+" Vim indent file
+" Language:	Fortran95 (and Fortran90, Fortran77, F and elf90)
+" Version:	0.37
+" URL:		http://www.unb.ca/chem/ajit/indent/fortran.vim
+" Last Change:	2006 Nov 16
+" Maintainer:	Ajit J. Thakkar <ajit@unb.ca>; <http://www.unb.ca/chem/ajit/>
+" Usage:	Do :help fortran-indent from Vim
+
+" Only load this indent file when no other was loaded.
+if exists("b:did_indent")
+  finish
+endif
+let b:did_indent = 1
+
+setlocal indentkeys+==~end,=~case,=~if,=~else,=~do,=~where,=~elsewhere,=~select
+setlocal indentkeys+==~endif,=~enddo,=~endwhere,=~endselect
+setlocal indentkeys+==~type,=~interface
+
+" Determine whether this is a fixed or free format source file
+" if this hasn't been done yet
+if !exists("b:fortran_fixed_source")
+  if exists("fortran_free_source")
+    " User guarantees free source form
+    let b:fortran_fixed_source = 0
+  elseif exists("fortran_fixed_source")
+    " User guarantees fixed source form
+    let b:fortran_fixed_source = 1
+  else
+    " f90 and f95 allow both fixed and free source form
+    " assume fixed source form unless signs of free source form
+    " are detected in the first five columns of the first 250 lines
+    " Detection becomes more accurate and time-consuming if more lines
+    " are checked. Increase the limit below if you keep lots of comments at
+    " the very top of each file and you have a fast computer
+    let s:lmax = 250
+    if ( s:lmax > line("$") )
+      let s:lmax = line("$")
+    endif
+    let b:fortran_fixed_source = 1
+    let s:ln=1
+    while s:ln <= s:lmax
+      let s:test = strpart(getline(s:ln),0,5)
+      if s:test[0] !~ '[Cc*!#]' && s:test !~ '^ \+[!#]' && s:test =~ '[^ 0-9\t]'
+	let b:fortran_fixed_source = 0
+	break
+      endif
+      let s:ln = s:ln + 1
+    endwhile
+  endif
+endif
+
+" Define the appropriate indent function but only once
+if (b:fortran_fixed_source == 1)
+  setlocal indentexpr=FortranGetFixedIndent()
+  if exists("*FortranGetFixedIndent")
+    finish
+  endif
+else
+  setlocal indentexpr=FortranGetFreeIndent()
+  if exists("*FortranGetFreeIndent")
+    finish
+  endif
+endif
+
+let s:cposet=&cpoptions
+set cpoptions-=C
+
+function FortranGetIndent(lnum)
+  let ind = indent(a:lnum)
+  let prevline=getline(a:lnum)
+  " Strip tail comment
+  let prevstat=substitute(prevline, '!.*$', '', '')
+
+  "Indent do loops only if they are all guaranteed to be of do/end do type
+  if exists("b:fortran_do_enddo") || exists("g:fortran_do_enddo")
+    if prevstat =~? '^\s*\(\d\+\s\)\=\s*\(\a\w*\s*:\)\=\s*do\>'
+      let ind = ind + &sw
+    endif
+    if getline(v:lnum) =~? '^\s*\(\d\+\s\)\=\s*end\s*do\>'
+      let ind = ind - &sw
+    endif
+  endif
+
+  "Add a shiftwidth to statements following if, else, case,
+  "where, elsewhere, type and interface statements
+  if prevstat =~? '^\s*\(\d\+\s\)\=\s*\(else\|case\|where\|elsewhere\)\>'
+	\ ||prevstat =~? '^\s*\(\d\+\s\)\=\s*\(type\|interface\)\>'
+	\ || prevstat =~? '^\s*\(\d\+\s\)\=\s*\(\a\w*\s*:\)\=\s*if\>'
+     let ind = ind + &sw
+    " Remove unwanted indent after logical and arithmetic ifs
+    if prevstat =~? '\<if\>' && prevstat !~? '\<then\>'
+      let ind = ind - &sw
+    endif
+    " Remove unwanted indent after type( statements
+    if prevstat =~? '\<type\s*('
+      let ind = ind - &sw
+    endif
+  endif
+
+  "Subtract a shiftwidth from else, elsewhere, case, end if,
+  " end where, end select, end interface and end type statements
+  if getline(v:lnum) =~? '^\s*\(\d\+\s\)\=\s*'
+	\. '\(else\|elsewhere\|case\|end\s*\(if\|where\|select\|interface\|type\)\)\>'
+    let ind = ind - &sw
+    " Fix indent for case statement immediately after select
+    if prevstat =~? '\<select\>'
+      let ind = ind + &sw
+    endif
+  endif
+
+  return ind
+endfunction
+
+function FortranGetFreeIndent()
+  "Find the previous non-blank line
+  let lnum = prevnonblank(v:lnum - 1)
+
+  "Use zero indent at the top of the file
+  if lnum == 0
+    return 0
+  endif
+
+  let ind=FortranGetIndent(lnum)
+  return ind
+endfunction
+
+function FortranGetFixedIndent()
+  let currline=getline(v:lnum)
+  "Don't indent comments, continuation lines and labelled lines
+  if strpart(currline,0,6) =~ '[^ \t]'
+    let ind = indent(v:lnum)
+    return ind
+  endif
+
+  "Find the previous line which is not blank, not a comment,
+  "not a continuation line, and does not have a label
+  let lnum = v:lnum - 1
+  while lnum > 0
+    let prevline=getline(lnum)
+    if (prevline =~ "^[C*!]") || (prevline =~ "^\s*$")
+	\ || (strpart(prevline,5,1) !~ "[ 0]")
+      " Skip comments, blank lines and continuation lines
+      let lnum = lnum - 1
+    else
+      let test=strpart(prevline,0,5)
+      if test =~ "[0-9]"
+	" Skip lines with statement numbers
+	let lnum = lnum - 1
+      else
+	break
+      endif
+    endif
+  endwhile
+
+  "First line must begin at column 7
+  if lnum == 0
+    return 6
+  endif
+
+  let ind=FortranGetIndent(lnum)
+  return ind
+endfunction
+
+let &cpoptions=s:cposet
+unlet s:cposet
+
+" vim:sw=2 tw=130
--- /dev/null
+++ b/lib/vimfiles/indent/hamster.vim
@@ -1,0 +1,55 @@
+" Vim indent file
+" Language:    Hamster Script 
+" Version:     2.0.6.0
+" Last Change: Wed Nov 08 2006 12:02:42 PM
+" Maintainer:  David Fishburn <fishburn@ianywhere.com>
+
+" Only load this indent file when no other was loaded.
+if exists("b:did_indent")
+  finish
+endif
+let b:did_indent = 1
+
+setlocal indentkeys+==~if,=~else,=~endif,=~endfor,=~endwhile
+setlocal indentkeys+==~do,=~until,=~while,=~repeat,=~for,=~loop
+setlocal indentkeys+==~sub,=~endsub
+
+" Define the appropriate indent function but only once
+setlocal indentexpr=HamGetFreeIndent()
+if exists("*HamGetFreeIndent")
+  finish
+endif
+
+function HamGetIndent(lnum)
+  let ind = indent(a:lnum)
+  let prevline=getline(a:lnum)
+
+  " Add a shiftwidth to statements following if,  else, elseif,
+  " case, select, default, do, until, while, for, start
+  if prevline =~? '^\s*\<\(if\|else\%(if\)\?\|for\|repeat\|do\|while\|sub\)\>' 
+    let ind = ind + &sw
+  endif
+
+  " Subtract a shiftwidth from else, elseif, end(if|while|for), until
+  let line = getline(v:lnum)
+  if line =~? '^\s*\(else\|elseif\|loop\|until\|end\%(if\|while\|for\|sub\)\)\>'
+    let ind = ind - &sw
+  endif
+
+  return ind
+endfunction
+
+function HamGetFreeIndent()
+  " Find the previous non-blank line
+  let lnum = prevnonblank(v:lnum - 1)
+
+  " Use zero indent at the top of the file
+  if lnum == 0
+    return 0
+  endif
+
+  let ind=HamGetIndent(lnum)
+  return ind
+endfunction
+
+" vim:sw=2 tw=80
--- /dev/null
+++ b/lib/vimfiles/indent/html.vim
@@ -1,0 +1,242 @@
+" Description:	html indenter
+" Author:	Johannes Zellner <johannes@zellner.org>
+" Last Change:	Mo, 05 Jun 2006 22:32:41 CEST
+" 		Restoring 'cpo' and 'ic' added by Bram 2006 May 5
+" Globals:	g:html_indent_tags	   -- indenting tags
+"		g:html_indent_strict       -- inhibit 'O O' elements
+"		g:html_indent_strict_table -- inhibit 'O -' elements
+
+" Only load this indent file when no other was loaded.
+if exists("b:did_indent")
+    finish
+endif
+let b:did_indent = 1
+
+
+" [-- local settings (must come before aborting the script) --]
+setlocal indentexpr=HtmlIndentGet(v:lnum)
+setlocal indentkeys=o,O,*<Return>,<>>,{,}
+
+
+if exists('g:html_indent_tags')
+    unlet g:html_indent_tags
+endif
+
+" [-- helper function to assemble tag list --]
+fun! <SID>HtmlIndentPush(tag)
+    if exists('g:html_indent_tags')
+	let g:html_indent_tags = g:html_indent_tags.'\|'.a:tag
+    else
+	let g:html_indent_tags = a:tag
+    endif
+endfun
+
+
+" [-- <ELEMENT ? - - ...> --]
+call <SID>HtmlIndentPush('a')
+call <SID>HtmlIndentPush('abbr')
+call <SID>HtmlIndentPush('acronym')
+call <SID>HtmlIndentPush('address')
+call <SID>HtmlIndentPush('b')
+call <SID>HtmlIndentPush('bdo')
+call <SID>HtmlIndentPush('big')
+call <SID>HtmlIndentPush('blockquote')
+call <SID>HtmlIndentPush('button')
+call <SID>HtmlIndentPush('caption')
+call <SID>HtmlIndentPush('center')
+call <SID>HtmlIndentPush('cite')
+call <SID>HtmlIndentPush('code')
+call <SID>HtmlIndentPush('colgroup')
+call <SID>HtmlIndentPush('del')
+call <SID>HtmlIndentPush('dfn')
+call <SID>HtmlIndentPush('dir')
+call <SID>HtmlIndentPush('div')
+call <SID>HtmlIndentPush('dl')
+call <SID>HtmlIndentPush('em')
+call <SID>HtmlIndentPush('fieldset')
+call <SID>HtmlIndentPush('font')
+call <SID>HtmlIndentPush('form')
+call <SID>HtmlIndentPush('frameset')
+call <SID>HtmlIndentPush('h1')
+call <SID>HtmlIndentPush('h2')
+call <SID>HtmlIndentPush('h3')
+call <SID>HtmlIndentPush('h4')
+call <SID>HtmlIndentPush('h5')
+call <SID>HtmlIndentPush('h6')
+call <SID>HtmlIndentPush('i')
+call <SID>HtmlIndentPush('iframe')
+call <SID>HtmlIndentPush('ins')
+call <SID>HtmlIndentPush('kbd')
+call <SID>HtmlIndentPush('label')
+call <SID>HtmlIndentPush('legend')
+call <SID>HtmlIndentPush('map')
+call <SID>HtmlIndentPush('menu')
+call <SID>HtmlIndentPush('noframes')
+call <SID>HtmlIndentPush('noscript')
+call <SID>HtmlIndentPush('object')
+call <SID>HtmlIndentPush('ol')
+call <SID>HtmlIndentPush('optgroup')
+" call <SID>HtmlIndentPush('pre')
+call <SID>HtmlIndentPush('q')
+call <SID>HtmlIndentPush('s')
+call <SID>HtmlIndentPush('samp')
+call <SID>HtmlIndentPush('script')
+call <SID>HtmlIndentPush('select')
+call <SID>HtmlIndentPush('small')
+call <SID>HtmlIndentPush('span')
+call <SID>HtmlIndentPush('strong')
+call <SID>HtmlIndentPush('style')
+call <SID>HtmlIndentPush('sub')
+call <SID>HtmlIndentPush('sup')
+call <SID>HtmlIndentPush('table')
+call <SID>HtmlIndentPush('textarea')
+call <SID>HtmlIndentPush('title')
+call <SID>HtmlIndentPush('tt')
+call <SID>HtmlIndentPush('u')
+call <SID>HtmlIndentPush('ul')
+call <SID>HtmlIndentPush('var')
+
+
+" [-- <ELEMENT ? O O ...> --]
+if !exists('g:html_indent_strict')
+    call <SID>HtmlIndentPush('body')
+    call <SID>HtmlIndentPush('head')
+    call <SID>HtmlIndentPush('html')
+    call <SID>HtmlIndentPush('tbody')
+endif
+
+
+" [-- <ELEMENT ? O - ...> --]
+if !exists('g:html_indent_strict_table')
+    call <SID>HtmlIndentPush('th')
+    call <SID>HtmlIndentPush('td')
+    call <SID>HtmlIndentPush('tr')
+    call <SID>HtmlIndentPush('tfoot')
+    call <SID>HtmlIndentPush('thead')
+endif
+
+delfun <SID>HtmlIndentPush
+
+let s:cpo_save = &cpo
+set cpo-=C
+
+" [-- count indent-increasing tags of line a:lnum --]
+fun! <SID>HtmlIndentOpen(lnum, pattern)
+    let s = substitute('x'.getline(a:lnum),
+    \ '.\{-}\(\(<\)\('.a:pattern.'\)\>\)', "\1", 'g')
+    let s = substitute(s, "[^\1].*$", '', '')
+    return strlen(s)
+endfun
+
+" [-- count indent-decreasing tags of line a:lnum --]
+fun! <SID>HtmlIndentClose(lnum, pattern)
+    let s = substitute('x'.getline(a:lnum),
+    \ '.\{-}\(\(<\)/\('.a:pattern.'\)\>>\)', "\1", 'g')
+    let s = substitute(s, "[^\1].*$", '', '')
+    return strlen(s)
+endfun
+
+" [-- count indent-increasing '{' of (java|css) line a:lnum --]
+fun! <SID>HtmlIndentOpenAlt(lnum)
+    return strlen(substitute(getline(a:lnum), '[^{]\+', '', 'g'))
+endfun
+
+" [-- count indent-decreasing '}' of (java|css) line a:lnum --]
+fun! <SID>HtmlIndentCloseAlt(lnum)
+    return strlen(substitute(getline(a:lnum), '[^}]\+', '', 'g'))
+endfun
+
+" [-- return the sum of indents respecting the syntax of a:lnum --]
+fun! <SID>HtmlIndentSum(lnum, style)
+    if a:style == match(getline(a:lnum), '^\s*</')
+	if a:style == match(getline(a:lnum), '^\s*</\<\('.g:html_indent_tags.'\)\>')
+	    let open = <SID>HtmlIndentOpen(a:lnum, g:html_indent_tags)
+	    let close = <SID>HtmlIndentClose(a:lnum, g:html_indent_tags)
+	    if 0 != open || 0 != close
+		return open - close
+	    endif
+	endif
+    endif
+    if '' != &syntax &&
+	\ synIDattr(synID(a:lnum, 1, 1), 'name') =~ '\(css\|java\).*' &&
+	\ synIDattr(synID(a:lnum, strlen(getline(a:lnum)), 1), 'name')
+	\ =~ '\(css\|java\).*'
+	if a:style == match(getline(a:lnum), '^\s*}')
+	    return <SID>HtmlIndentOpenAlt(a:lnum) - <SID>HtmlIndentCloseAlt(a:lnum)
+	endif
+    endif
+    return 0
+endfun
+
+fun! HtmlIndentGet(lnum)
+    " Find a non-empty line above the current line.
+    let lnum = prevnonblank(a:lnum - 1)
+
+    " Hit the start of the file, use zero indent.
+    if lnum == 0
+	return 0
+    endif
+
+    let restore_ic = &ic
+    setlocal ic " ignore case
+
+    " [-- special handling for <pre>: no indenting --]
+    if getline(a:lnum) =~ '\c</pre>'
+		\ || 0 < searchpair('\c<pre>', '', '\c</pre>', 'nWb')
+		\ || 0 < searchpair('\c<pre>', '', '\c</pre>', 'nW')
+	" we're in a line with </pre> or inside <pre> ... </pre>
+	if restore_ic == 0
+	  setlocal noic
+	endif
+	return -1
+    endif
+
+    " [-- special handling for <javascript>: use cindent --]
+    let js = '<script.*type\s*=\s*.*java'
+
+    """"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
+    " by Tye Zdrojewski <zdro@yahoo.com>, 05 Jun 2006
+    " ZDR: This needs to be an AND (we are 'after the start of the pair' AND
+    "      we are 'before the end of the pair').  Otherwise, indentation
+    "      before the start of the script block will be affected; the end of
+    "      the pair will still match if we are before the beginning of the
+    "      pair.
+    "
+    if   0 < searchpair(js, '', '</script>', 'nWb')
+    \ && 0 < searchpair(js, '', '</script>', 'nW')
+	" we're inside javascript
+	if getline(lnum) !~ js && getline(a:lnum) != '</script>'
+	    if restore_ic == 0
+	      setlocal noic
+	    endif
+	    return cindent(a:lnum)
+	endif
+    endif
+
+    if getline(lnum) =~ '\c</pre>'
+	" line before the current line a:lnum contains
+	" a closing </pre>. --> search for line before
+	" starting <pre> to restore the indent.
+	let preline = prevnonblank(search('\c<pre>', 'bW') - 1)
+	if preline > 0
+	    if restore_ic == 0
+	      setlocal noic
+	    endif
+	    return indent(preline)
+	endif
+    endif
+
+    let ind = <SID>HtmlIndentSum(lnum, -1)
+    let ind = ind + <SID>HtmlIndentSum(a:lnum, 0)
+
+    if restore_ic == 0
+	setlocal noic
+    endif
+
+    return indent(lnum) + (&sw * ind)
+endfun
+
+let &cpo = s:cpo_save
+unlet s:cpo_save
+
+" [-- EOF <runtime>/indent/html.vim --]
--- /dev/null
+++ b/lib/vimfiles/indent/htmldjango.vim
@@ -1,0 +1,12 @@
+" Vim indent file
+" Language:	Django HTML template
+" Maintainer:	Dave Hodder <dmh@dmh.org.uk>
+" Last Change:	2007 Jan 25
+
+" Only load this indent file when no other was loaded.
+if exists("b:did_indent")
+  finish
+endif
+
+" Use HTML formatting rules.
+runtime! indent/html.vim
--- /dev/null
+++ b/lib/vimfiles/indent/idlang.vim
@@ -1,0 +1,63 @@
+" IDL (Interactive Data Language) indent file.
+" Language: IDL (ft=idlang)
+" Last change:	2002 Sep 23
+" Maintainer: Aleksandar Jelenak <ajelenak AT yahoo.com>
+
+" Only load this indent file when no other was loaded.
+if exists("b:did_indent")
+   finish
+endif
+let b:did_indent = 1
+
+setlocal indentkeys=o,O,0=endif,0=ENDIF,0=endelse,0=ENDELSE,0=endwhile,
+		    \0=ENDWHILE,0=endfor,0=ENDFOR,0=endrep,0=ENDREP
+
+setlocal indentexpr=GetIdlangIndent(v:lnum)
+
+" Only define the function once.
+if exists("*GetIdlangIndent")
+   finish
+endif
+
+function GetIdlangIndent(lnum)
+   " First non-empty line above the current line.
+   let pnum = prevnonblank(v:lnum-1)
+   " v:lnum is the first non-empty line -- zero indent.
+   if pnum == 0
+      return 0
+   endif
+   " Second non-empty line above the current line.
+   let pnum2 = prevnonblank(pnum-1)
+
+   " Current indent.
+   let curind = indent(pnum)
+
+   " Indenting of continued lines.
+   if getline(pnum) =~ '\$\s*\(;.*\)\=$'
+      if getline(pnum2) !~ '\$\s*\(;.*\)\=$'
+	 let curind = curind+&sw
+      endif
+   else
+      if getline(pnum2) =~ '\$\s*\(;.*\)\=$'
+	 let curind = curind-&sw
+      endif
+   endif
+
+   " Indenting blocks of statements.
+   if getline(v:lnum) =~? '^\s*\(endif\|endelse\|endwhile\|endfor\|endrep\)\>'
+      if getline(pnum) =~? 'begin\>'
+      elseif indent(v:lnum) > curind-&sw
+	 let curind = curind-&sw
+      else
+	 return -1
+      endif
+   elseif getline(pnum) =~? 'begin\>'
+      if indent(v:lnum) < curind+&sw
+	 let curind = curind+&sw
+      else
+	 return -1
+      endif
+   endif
+   return curind
+endfunction
+
--- /dev/null
+++ b/lib/vimfiles/indent/ishd.vim
@@ -1,0 +1,68 @@
+" Description:	InstallShield indenter
+" Author:	Johannes Zellner <johannes@zellner.org>
+" Last Change:	Tue, 27 Apr 2004 14:54:59 CEST
+
+" Only load this indent file when no other was loaded.
+if exists("b:did_indent")
+    finish
+endif
+let b:did_indent = 1
+
+setlocal autoindent
+setlocal indentexpr=GetIshdIndent(v:lnum)
+setlocal indentkeys&
+setlocal indentkeys+==else,=elseif,=endif,=end,=begin,<:>
+" setlocal indentkeys-=0#
+
+let b:undo_indent = "setl ai< indentexpr< indentkeys<"
+
+" Only define the function once.
+if exists("*GetIshdIndent")
+    finish
+endif
+
+fun! GetIshdIndent(lnum)
+    " labels and preprocessor get zero indent immediately
+    let this_line = getline(a:lnum)
+    let LABELS_OR_PREPROC = '^\s*\(\<\k\+\>:\s*$\|#.*\)'
+    let LABELS_OR_PREPROC_EXCEPT = '^\s*\<default\+\>:'
+    if this_line =~ LABELS_OR_PREPROC && this_line !~ LABELS_OR_PREPROC_EXCEPT
+	return 0
+    endif
+
+    " Find a non-blank line above the current line.
+    " Skip over labels and preprocessor directives.
+    let lnum = a:lnum
+    while lnum > 0
+	let lnum = prevnonblank(lnum - 1)
+	let previous_line = getline(lnum)
+	if previous_line !~ LABELS_OR_PREPROC || previous_line =~ LABELS_OR_PREPROC_EXCEPT
+	    break
+	endif
+    endwhile
+
+    " Hit the start of the file, use zero indent.
+    if lnum == 0
+	return 0
+    endif
+
+    let ind = indent(lnum)
+
+    " Add
+    if previous_line =~ '^\s*\<\(function\|begin\|switch\|case\|default\|if.\{-}then\|else\|elseif\|while\|repeat\)\>'
+	let ind = ind + &sw
+    endif
+
+    " Subtract
+    if this_line =~ '^\s*\<endswitch\>'
+	let ind = ind - 2 * &sw
+    elseif this_line =~ '^\s*\<\(begin\|end\|endif\|endwhile\|else\|elseif\|until\)\>'
+	let ind = ind - &sw
+    elseif this_line =~ '^\s*\<\(case\|default\)\>'
+	if previous_line !~ '^\s*\<switch\>'
+	    let ind = ind - &sw
+	endif
+    endif
+
+    return ind
+endfun
--- /dev/null
+++ b/lib/vimfiles/indent/java.vim
@@ -1,0 +1,130 @@
+" Vim indent file
+" Language:	Java
+" Maintainer:	Toby Allsopp <toby.allsopp@peace.com> (resigned)
+" Last Change:	2005 Mar 28
+
+" Only load this indent file when no other was loaded.
+if exists("b:did_indent")
+  finish
+endif
+let b:did_indent = 1
+
+" Indent Java anonymous classes correctly.
+setlocal cindent cinoptions& cinoptions+=j1
+
+" The "extends" and "implements" lines start off with the wrong indent.
+setlocal indentkeys& indentkeys+=0=extends indentkeys+=0=implements
+
+" Set the function to do the work.
+setlocal indentexpr=GetJavaIndent()
+
+let b:undo_indent = "set cin< cino< indentkeys< indentexpr<"
+
+" Only define the function once.
+if exists("*GetJavaIndent")
+  finish
+endif
+
+function! SkipJavaBlanksAndComments(startline)
+  let lnum = a:startline
+  while lnum > 1
+    let lnum = prevnonblank(lnum)
+    if getline(lnum) =~ '\*/\s*$'
+      while getline(lnum) !~ '/\*' && lnum > 1
+        let lnum = lnum - 1
+      endwhile
+      if getline(lnum) =~ '^\s*/\*'
+        let lnum = lnum - 1
+      else
+        break
+      endif
+    elseif getline(lnum) =~ '^\s*//'
+      let lnum = lnum - 1
+    else
+      break
+    endif
+  endwhile
+  return lnum
+endfunction
+
+function GetJavaIndent()
+
+  " Java is just like C; use the built-in C indenting and then correct a few
+  " specific cases.
+  let theIndent = cindent(v:lnum)
+
+  " If we're in the middle of a comment then just trust cindent
+  if getline(v:lnum) =~ '^\s*\*'
+    return theIndent
+  endif
+
+  " find start of previous line, in case it was a continuation line
+  let lnum = SkipJavaBlanksAndComments(v:lnum - 1)
+  let prev = lnum
+  while prev > 1
+    let next_prev = SkipJavaBlanksAndComments(prev - 1)
+    if getline(next_prev) !~ ',\s*$'
+      break
+    endif
+    let prev = next_prev
+  endwhile
+
+  " Try to align "throws" lines for methods and "extends" and "implements" for
+  " classes.
+  if getline(v:lnum) =~ '^\s*\(extends\|implements\)\>'
+        \ && getline(lnum) !~ '^\s*\(extends\|implements\)\>'
+    let theIndent = theIndent + &sw
+  endif
+
+  " correct for continuation lines of "throws", "implements" and "extends"
+  let cont_kw = matchstr(getline(prev),
+        \ '^\s*\zs\(throws\|implements\|extends\)\>\ze.*,\s*$')
+  if strlen(cont_kw) > 0
+    let amount = strlen(cont_kw) + 1
+    if getline(lnum) !~ ',\s*$'
+      let theIndent = theIndent - (amount + &sw)
+      if theIndent < 0
+        let theIndent = 0
+      endif
+    elseif prev == lnum
+      let theIndent = theIndent + amount
+      if cont_kw ==# 'throws'
+        let theIndent = theIndent + &sw
+      endif
+    endif
+  elseif getline(prev) =~ '^\s*\(throws\|implements\|extends\)\>'
+        \ && (getline(prev) =~ '{\s*$'
+        \  || getline(v:lnum) =~ '^\s*{\s*$')
+    let theIndent = theIndent - &sw
+  endif
+
+  " When the line starts with a }, try aligning it with the matching {,
+  " skipping over "throws", "extends" and "implements" clauses.
+  if getline(v:lnum) =~ '^\s*}\s*\(//.*\|/\*.*\)\=$'
+    call cursor(v:lnum, 1)
+    silent normal %
+    let lnum = line('.')
+    if lnum < v:lnum
+      while lnum > 1
+        let next_lnum = SkipJavaBlanksAndComments(lnum - 1)
+        if getline(lnum) !~ '^\s*\(throws\|extends\|implements\)\>'
+              \ && getline(next_lnum) !~ ',\s*$'
+          break
+        endif
+        let lnum = prevnonblank(next_lnum)
+      endwhile
+      return indent(lnum)
+    endif
+  endif
+
+  " Below a line starting with "}" never indent more.  Needed for a method
+  " below a method with an indented "throws" clause.
+  let lnum = SkipJavaBlanksAndComments(v:lnum - 1)
+  if getline(lnum) =~ '^\s*}\s*\(//.*\|/\*.*\)\=$' && indent(lnum) < theIndent
+    let theIndent = indent(lnum)
+  endif
+
+  return theIndent
+endfunction
+
+" vi: sw=2 et
--- /dev/null
+++ b/lib/vimfiles/indent/javascript.vim
@@ -1,0 +1,15 @@
+" Vim indent file
+" Language:	Javascript
+" Maintainer:	None!  Wanna improve this?
+" Last Change:	2007 Jan 22
+
+" Only load this indent file when no other was loaded.
+if exists("b:did_indent")
+   finish
+endif
+let b:did_indent = 1
+
+" C indenting is not too bad.
+setlocal cindent
+
+let b:undo_indent = "setl cin<"
--- /dev/null
+++ b/lib/vimfiles/indent/jsp.vim
@@ -1,0 +1,17 @@
+" Vim filetype indent file
+" Language:    JSP files
+" Maintainer:  David Fishburn <fishburn@ianywhere.com>
+" Version:     1.0
+" Last Change: Wed Nov 08 2006 11:08:05 AM
+
+" Only load this indent file when no other was loaded.
+if exists("b:did_indent")
+    finish
+endif
+
+" If there has been no specific JSP indent script created, 
+" use the default html indent script which will handle
+" html, javascript and most of the JSP constructs.
+runtime! indent/html.vim
+
+
--- /dev/null
+++ b/lib/vimfiles/indent/ld.vim
@@ -1,0 +1,84 @@
+" Vim indent file
+" Language:         ld(1) script
+" Maintainer:       Nikolai Weibull <now@bitwi.se>
+" Latest Revision:  2006-12-20
+
+if exists("b:did_indent")
+  finish
+endif
+let b:did_indent = 1
+
+setlocal indentexpr=GetLDIndent()
+setlocal indentkeys=0{,0},!^F,o,O
+setlocal nosmartindent
+
+if exists("*GetLDIndent")
+  finish
+endif
+
+function s:prevnonblanknoncomment(lnum)
+  let lnum = a:lnum
+  while lnum > 1
+    let lnum = prevnonblank(lnum)
+    let line = getline(lnum)
+    if line =~ '\*/'
+      while lnum > 1 && line !~ '/\*'
+        let lnum -= 1
+      endwhile
+      if line =~ '^\s*/\*'
+        let lnum -= 1
+      else
+        break
+      endif
+    else
+      break
+    endif
+  endwhile
+  return lnum
+endfunction
+
+function s:count_braces(lnum, count_open)
+  let n_open = 0
+  let n_close = 0
+  let line = getline(a:lnum)
+  let pattern = '[{}]'
+  let i = match(line, pattern)
+  while i != -1
+    if synIDattr(synID(a:lnum, i + 1, 0), 'name') !~ 'ld\%(Comment\|String\)'
+      if line[i] == '{'
+        let n_open += 1
+      elseif line[i] == '}'
+        if n_open > 0
+          let n_open -= 1
+        else
+          let n_close += 1
+        endif
+      endif
+    endif
+    let i = match(line, pattern, i + 1)
+  endwhile
+  return a:count_open ? n_open : n_close
+endfunction
+
+function GetLDIndent()
+  let line = getline(v:lnum)
+  if line =~ '^\s*\*'
+    return cindent(v:lnum)
+  elseif line =~ '^\s*}'
+    return indent(v:lnum) - &sw
+  endif
+
+  let pnum = s:prevnonblanknoncomment(v:lnum - 1)
+  if pnum == 0
+    return 0
+  endif
+
+  let ind = indent(pnum) + s:count_braces(pnum, 1) * &sw
+
+  let pline = getline(pnum)
+  if pline =~ '}\s*$'
+    let ind -= (s:count_braces(pnum, 0) - (pline =~ '^\s*}' ? 1 : 0)) * &sw
+  endif
+
+  return ind
+endfunction
--- /dev/null
+++ b/lib/vimfiles/indent/lisp.vim
@@ -1,0 +1,15 @@
+" Vim indent file
+" Language:	Lisp
+" Maintainer:    Sergey Khorev <sergey.khorev@gmail.com>
+" URL:		 http://iamphet.nm.ru/vim
+" Last Change:	2005 May 19
+
+" Only load this indent file when no other was loaded.
+if exists("b:did_indent")
+   finish
+endif
+let b:did_indent = 1
+
+setlocal ai nosi
+
+let b:undo_indent = "setl ai< si<"
--- /dev/null
+++ b/lib/vimfiles/indent/lua.vim
@@ -1,0 +1,59 @@
+" Vim indent file
+" Language:	Lua script
+" Maintainer:	Marcus Aurelius Farias <marcus.cf 'at' bol.com.br>
+" First Author:	Max Ischenko <mfi 'at' ukr.net>
+" Last Change:	2005 Jun 23
+
+" Only load this indent file when no other was loaded.
+if exists("b:did_indent")
+  finish
+endif
+let b:did_indent = 1
+
+setlocal indentexpr=GetLuaIndent()
+
+" To make Vim call GetLuaIndent() when it finds '\s*end' or '\s*until'
+" on the current line ('else' is default and includes 'elseif').
+setlocal indentkeys+=0=end,0=until
+
+setlocal autoindent
+
+" Only define the function once.
+if exists("*GetLuaIndent")
+  finish
+endif
+
+function! GetLuaIndent()
+  " Find a non-blank line above the current line.
+  let lnum = prevnonblank(v:lnum - 1)
+
+  " Hit the start of the file, use zero indent.
+  if lnum == 0
+    return 0
+  endif
+
+  " Add a 'shiftwidth' after lines that start a block:
+  " 'function', 'if', 'for', 'while', 'repeat', 'else', 'elseif', '{'
+  let ind = indent(lnum)
+  let flag = 0
+  let prevline = getline(lnum)
+  if prevline =~ '^\s*\%(if\>\|for\>\|while\>\|repeat\>\|else\>\|elseif\>\|do\>\|then\>\)'
+        \ || prevline =~ '{\s*$' || prevline =~ '\<function\>\s*\%(\k\|[.:]\)\{-}\s*('
+    let ind = ind + &shiftwidth
+    let flag = 1
+  endif
+
+  " Subtract a 'shiftwidth' after lines ending with
+  " 'end' when they begin with 'while', 'if', 'for', etc. too.
+  if flag == 1 && prevline =~ '\<end\>\|\<until\>'
+    let ind = ind - &shiftwidth
+  endif
+
+  " Subtract a 'shiftwidth' on end, else (and elseif), until and '}'
+  " This is the part that requires 'indentkeys'.
+  if getline(v:lnum) =~ '^\s*\%(end\|else\|until\|}\)'
+    let ind = ind - &shiftwidth
+  endif
+
+  return ind
+endfunction
--- /dev/null
+++ b/lib/vimfiles/indent/make.vim
@@ -1,0 +1,116 @@
+" Vim indent file
+" Language:         Makefile
+" Maintainer:       Nikolai Weibull <now@bitwi.se>
+" Latest Revision:  2007-05-07
+
+if exists("b:did_indent")
+  finish
+endif
+let b:did_indent = 1
+
+setlocal indentexpr=GetMakeIndent()
+setlocal indentkeys=!^F,o,O,<:>,=else,=endif
+setlocal nosmartindent
+
+if exists("*GetMakeIndent")
+  finish
+endif
+
+let s:comment_rx = '^\s*#'
+let s:rule_rx = '^[^ \t#:][^#:]*:\{1,2}\%([^=:]\|$\)'
+let s:continued_rule_rx = '^[^#:]*:\{1,2}\%([^=:]\|$\)'
+let s:continuation_rx = '\\$'
+let s:assignment_rx = '^\s*\h\w*\s*[+?]\==\s*\zs.*\\$'
+let s:folded_assignment_rx = '^\s*\h\w*\s*[+?]\=='
+" TODO: This needs to be a lot more restrictive in what it matches.
+let s:just_inserted_rule_rx = '^\s*[^#:]\+:\{1,2}$'
+let s:conditional_directive_rx = '^ *\%(ifn\=\%(eq\|def\)\|else\)\>'
+let s:end_conditional_directive_rx = '^\s*\%(else\|endif\)\>'
+
+function s:remove_continuation(line)
+  return substitute(a:line, s:continuation_rx, "", "")
+endfunction
+
+function GetMakeIndent()
+  " TODO: Should this perhaps be v:lnum -1?
+"  let prev_lnum = prevnonblank(v:lnum - 1)
+  let prev_lnum = v:lnum - 1
+  if prev_lnum == 0
+    return 0
+  endif
+  let prev_line = getline(prev_lnum)
+
+  let prev_prev_lnum = prev_lnum - 1
+  let prev_prev_line = prev_prev_lnum != 0 ? getline(prev_prev_lnum) : ""
+
+  " TODO: Deal with comments.  In comments, continuations aren't interesting.
+  if prev_line =~ s:continuation_rx
+    if prev_prev_line =~ s:continuation_rx
+      return indent(prev_lnum)
+    elseif prev_line =~ s:rule_rx
+      return &sw
+    elseif prev_line =~ s:assignment_rx
+      call cursor(prev_lnum, 1)
+      if search(s:assignment_rx, 'W') != 0
+        return virtcol('.') - 1
+      else
+        " TODO: ?
+        return &sw
+      endif
+    else
+      " TODO: OK, this might be a continued shell command, so perhaps indent
+      " properly here?  Leave this out for now, but in the next release this
+      " should be using indent/sh.vim somehow.
+      "if prev_line =~ '^\t' " s:rule_command_rx
+      "  if prev_line =~ '^\s\+[@-]\%(if\)\>'
+      "    return indent(prev_lnum) + 2
+      "  endif
+      "endif
+      return indent(prev_lnum) + &sw
+    endif
+  elseif prev_prev_line =~ s:continuation_rx
+    let folded_line = s:remove_continuation(prev_prev_line) . ' ' . s:remove_continuation(prev_line)
+    let lnum = prev_prev_lnum - 1
+    let line = getline(lnum)
+    while line =~ s:continuation_rx
+      let folded_line = s:remove_continuation(line) . ' ' . folded_line
+      let lnum -= 1
+      let line = getline(lnum)
+    endwhile
+    let folded_lnum = lnum + 1
+    if folded_line =~ s:rule_rx
+      if getline(v:lnum) =~ s:rule_rx
+        return 0
+      else
+        return &ts
+      endif
+    else
+"    elseif folded_line =~ s:folded_assignment_rx
+      if getline(v:lnum) =~ s:rule_rx
+        return 0
+      else
+        return indent(folded_lnum)
+      endif
+"    else
+"      " TODO: ?
+"      return indent(prev_lnum)
+    endif
+  elseif prev_line =~ s:rule_rx
+    if getline(v:lnum) =~ s:rule_rx
+      return 0
+    else
+      return &ts
+    endif
+  elseif prev_line =~ s:conditional_directive_rx
+    return &sw
+  else
+    let line = getline(v:lnum)
+    if line =~ s:just_inserted_rule_rx
+      return 0
+    elseif line =~ s:end_conditional_directive_rx
+      return v:lnum - 1 == 0 ? 0 : indent(v:lnum - 1) - &sw
+    else
+      return v:lnum - 1 == 0 ? 0 : indent(v:lnum - 1)
+    endif
+  endif
+endfunction
--- /dev/null
+++ b/lib/vimfiles/indent/matlab.vim
@@ -1,0 +1,74 @@
+" Matlab indent file
+" Language:	Matlab
+" Maintainer:	Christophe Poucet <christophe.poucet@pandora.be>
+" Last Change:	6 January, 2001
+
+" Only load this indent file when no other was loaded.
+if exists("b:did_indent")
+  finish
+endif
+let b:did_indent = 1
+
+" Some preliminary setting
+setlocal indentkeys=!,o,O=end,=case,=else,=elseif,=otherwise,=catch
+
+
+setlocal indentexpr=GetMatlabIndent(v:lnum)
+
+" Only define the function once.
+if exists("*GetMatlabIndent")
+  finish
+endif
+
+function GetMatlabIndent(lnum)
+  " Give up if this line is explicitly joined.
+  if getline(a:lnum - 1) =~ '\\$'
+    return -1
+  endif
+
+  " Search backwards for the first non-empty line.
+  let plnum = a:lnum - 1
+  while plnum > 0 && getline(plnum) =~ '^\s*$'
+    let plnum = plnum - 1
+  endwhile
+
+  if plnum == 0
+    " This is the first non-empty line, use zero indent.
+    return 0
+  endif
+
+  let curind = indent(plnum)
+
+  " If the current line is a stop-block statement...
+  if getline(v:lnum) =~ '^\s*\(end\|else\|elseif\|case\|otherwise\|catch\)\>'
+    " See if this line does not follow the line right after an openblock
+    if getline(plnum) =~ '^\s*\(for\|if\|else\|elseif\|case\|while\|switch\|try\|otherwise\|catch\)\>'
+    " See if the user has already dedented
+    elseif indent(v:lnum) > curind - &sw
+      " If not, recommend one dedent
+	let curind = curind - &sw
+    else
+      " Otherwise, trust the user
+      return -1
+    endif
+"  endif
+
+  " If the previous line opened a block
+  elseif getline(plnum) =~ '^\s*\(for\|if\|else\|elseif\|case\|while\|switch\|try\|otherwise\|catch\)\>'
+    " See if the user has already indented
+    if indent(v:lnum) < curind + &sw
+      "If not, recommend indent
+      let curind = curind + &sw
+    else
+      " Otherwise, trust the user
+      return -1
+    endif
+  endif
+
+
+
+  " If we got to here, it means that the user takes the standardversion, so we return it
+  return curind
+endfunction
+
+" vim:sw=2
--- /dev/null
+++ b/lib/vimfiles/indent/mma.vim
@@ -1,0 +1,75 @@
+" Vim indent file
+" Language:     Mathematica
+" Author:       steve layland <layland@wolfram.com>
+" Last Change:  Sat May  10 18:56:22 CDT 2005
+" Source:       http://vim.sourceforge.net/scripts/script.php?script_id=1274
+"               http://members.wolfram.com/layland/vim/indent/mma.vim
+"
+" NOTE:
+" Empty .m files will automatically be presumed to be Matlab files
+" unless you have the following in your .vimrc:
+"
+"       let filetype_m="mma"
+"
+" Credits:
+" o steve hacked this out of a random indent file in the Vim 6.1
+"   distribution that he no longer remembers...sh.vim?  Thanks!
+
+" Only load this indent file when no other was loaded.
+if exists("b:did_indent")
+    finish
+endif
+let b:did_indent = 1
+
+setlocal indentexpr=GetMmaIndent()
+setlocal indentkeys+=0[,0],0(,0)
+setlocal nosi "turn off smart indent so we don't over analyze } blocks
+
+if exists("*GetMmaIndent")
+    finish
+endif
+
+function GetMmaIndent()
+
+    " Hit the start of the file, use zero indent.
+    if v:lnum == 0
+        return 0
+    endif
+
+     " Find a non-blank line above the current line.
+    let lnum = prevnonblank(v:lnum - 1)
+
+    " use indenting as a base
+    let ind = indent(v:lnum)
+    let lnum = v:lnum
+
+    " if previous line has an unmatched bracket, or ( indent.
+    " doesn't do multiple parens/blocks/etc...
+
+    " also, indent only if this line if this line isn't starting a new
+    " block... TODO - fix this with indentkeys?
+    if getline(v:lnum-1) =~ '\\\@<!\%(\[[^\]]*\|([^)]*\|{[^}]*\)$' && getline(v:lnum) !~ '\s\+[\[({]'
+        let ind = ind+&sw
+    endif
+
+    " if this line had unmatched closing block,
+    " indent to the matching opening block
+    if getline(v:lnum) =~ '[^[]*]\s*$'
+        " move to the closing bracket
+        call search(']','bW')
+        " and find it's partner's indent
+        let ind = indent(searchpair('\[','',']','bWn'))
+    " same for ( blocks
+    elseif getline(v:lnum) =~ '[^(]*)$'
+        call search(')','bW')
+        let ind = indent(searchpair('(','',')','bWn'))
+
+    " and finally, close { blocks if si ain't already set
+    elseif getline(v:lnum) =~ '[^{]*}'
+        call search('}','bW')
+        let ind = indent(searchpair('{','','}','bWn'))
+    endif
+
+    return ind
+endfunction
+
--- /dev/null
+++ b/lib/vimfiles/indent/mp.vim
@@ -1,0 +1,206 @@
+" MetaPost indent file
+" Language:	MetaPost
+" Maintainer:	Eugene Minkovskii <emin@mccme.ru>
+" Last Change:	2003 Nov 21
+" Version: 0.1
+" ==========================================================================
+
+" Identation Rules: {{{1
+" First of all, MetaPost language don't expect any identation rules.
+" This screept need for you only if you (not MetaPost) need to do
+" exactly code. If you don't need to use indentation, see
+" :help filetype-indent-off
+"
+" Note: Every rules of identation in MetaPost or TeX languages (and in some
+" other of course) is very subjective. I can release only my vision of this
+" promlem.
+"
+" ..........................................................................
+" Example of correct (by me) identation {{{2
+" shiftwidth=4
+" ==========================================================================
+" for i=0 upto 99:
+"     z[i] = (0,1u) rotated (i*360/100);
+" endfor
+" draw z0 -- z10 -- z20
+"         withpen ...     % <- 2sw because breaked line
+"         withcolor ...;  % <- same as previous
+" draw z0 for i=1 upto 99:
+"             -- z[i]             % <- 1sw from left end of 'for' satement
+"         endfor withpen ...      % <- 0sw from left end of 'for' satement
+"                 withcolor ...;  % <- 2sw because breaked line
+" draw if One:     % <- This is internal if (like 'for' above)
+"          one
+"      elsif Other:
+"          other
+"      fi withpen ...;
+" if one:          % <- This is external if
+"     draw one;
+" elseif other:
+"     draw other;
+" fi
+" draw z0; draw z1;
+" }}}
+" }}}
+
+" Only load this indent file when no other was loaded.
+if exists("b:did_indent")
+  finish
+endif
+let b:did_indent = 1
+
+setlocal indentexpr=GetMetaPostIndent()
+setlocal indentkeys+=;,<:>,=if,=for,=def,=end,=else,=fi
+
+" Only define the function once.
+if exists("*GetMetaPostIndent")
+  finish
+endif
+
+" Auxiliary Definitions: {{{1
+function! MetaNextNonblankNoncomment(pos)
+  " Like nextnonblank() but ignore comment lines
+  let tmp = nextnonblank(a:pos)
+  while tmp && getline(tmp) =~ '^\s*%'
+    let tmp = nextnonblank(tmp+1)
+  endwhile
+  return tmp
+endfunction
+
+function! MetaPrevNonblankNoncomment(pos)
+  " Like prevnonblank() but ignore comment lines
+  let tmp = prevnonblank(a:pos)
+  while tmp && getline(tmp) =~ '^\s*%'
+    let tmp = prevnonblank(tmp-1)
+  endwhile
+  return tmp
+endfunction
+
+function! MetaSearchNoncomment(pattern, ...)
+  " Like search() but ignore commented areas
+  if a:0
+    let flags = a:1
+  elseif &wrapscan
+    let flags = "w"
+  else
+    let flags = "W"
+  endif
+  let cl  = line(".")
+  let cc  = col(".")
+  let tmp = search(a:pattern, flags)
+  while tmp && synIDattr(synID(line("."), col("."), 1), "name") =~
+        \ 'm[fp]\(Comment\|TeXinsert\|String\)'
+    let tmp = search(a:pattern, flags)
+  endwhile
+  if !tmp
+    call cursor(cl,cc)
+  endif
+  return tmp
+endfunction
+" }}}
+
+function! GetMetaPostIndent()
+  " not indent in comment ???
+  if synIDattr(synID(line("."), col("."), 1), "name") =~
+        \ 'm[fp]\(Comment\|TeXinsert\|String\)'
+    return -1
+  endif
+  " Some RegExps: {{{1
+  " end_of_item: all of end by ';'
+  "            + all of end by :endfor, :enddef, :endfig, :endgroup, :fi
+  "            + all of start by :beginfig(num), :begingroup
+  "            + all of start by :for, :if, :else, :elseif and end by ':'
+  "            + all of start by :def, :vardef             and end by '='
+  let end_of_item = '\('                              .
+        \ ';\|'                                       .
+        \ '\<\(end\(for\|def\|fig\|group\)\|fi\)\>\|' .
+        \ '\<begin\(group\>\|fig\s*(\s*\d\+\s*)\)\|'  .
+        \ '\<\(for\|if\|else\(if\)\=\)\>.\+:\|'       .
+        \ '\<\(var\)\=def\>.\+='                      . '\)'
+  " }}}
+  " Save: current position {{{1
+  let cl = line   (".")
+  let cc = col    (".")
+  let cs = getline(".")
+  " if it is :beginfig or :endfig use zero indent
+  if  cs =~ '^\s*\(begin\|end\)fig\>'
+    return 0
+  endif
+  " }}}
+  " Initialise: ind variable {{{1
+  " search previous item not in current line
+  let p_semicol_l = MetaSearchNoncomment(end_of_item,"bW")
+  while p_semicol_l == cl
+    let p_semicol_l = MetaSearchNoncomment(end_of_item,"bW")
+  endwhile
+  " if this is first item in program use zero indent
+  if !p_semicol_l
+    return 0
+  endif
+  " if this is multiline item, remember first indent
+  if MetaNextNonblankNoncomment(p_semicol_l+1) < cl
+    let ind = indent(MetaNextNonblankNoncomment(p_semicol_l+1))
+  " else --- search pre-previous item for search first line in previous item
+  else
+    " search pre-previous item not in current line
+    let pp_semicol_l = MetaSearchNoncomment(end_of_item,"bW")
+    while pp_semicol_l == p_semicol_l
+      let pp_semicol_l = MetaSearchNoncomment(end_of_item,"bW")
+    endwhile
+    " if we find pre-previous item, remember indent of previous item
+    " else --- remember zero
+    if pp_semicol_l
+      let ind = indent(MetaNextNonblankNoncomment(line(".")+1))
+    else
+      let ind = 0
+    endif
+  endif
+  " }}}
+  " Increase Indent: {{{1
+  " if it is an internal/external :for or :if statements {{{2
+  let pnn_s = getline(MetaPrevNonblankNoncomment(cl-1))
+  if  pnn_s =~ '\<\(for\|if\)\>.\+:\s*\($\|%\)'
+    let ind = match(pnn_s, '\<\(for\|if\)\>.\+:\s*\($\|%\)') + &sw
+  " }}}
+  " if it is a :def, :vardef, :beginfig, :begingroup, :else, :elseif {{{2
+  elseif pnn_s =~ '^\s*\('                       .
+        \ '\(var\)\=def\|'                       .
+        \ 'begin\(group\|fig\s*(\s*\d\+\s*)\)\|' .
+        \ 'else\(if\)\='                         . '\)\>'
+    let ind = ind + &sw
+  " }}}
+  " if it is a broken line {{{2
+  elseif pnn_s !~ end_of_item.'\s*\($\|%\)'
+    let ind = ind + (2 * &sw)
+  endif
+  " }}}
+  " }}}
+  " Decrease Indent: {{{1
+  " if this is :endfor or :enddef statements {{{2
+  " this is correct because :def cannot be inside :for
+  if  cs  =~ '\<end\(for\|def\)\=\>'
+    call MetaSearchNoncomment('\<for\>.\+:\s*\($\|%\)' . '\|' .
+                            \ '^\s*\(var\)\=def\>',"bW")
+    if col(".") > 1
+      let ind = col(".") - 1
+    else
+      let ind = indent(".")
+    endif
+  " }}}
+  " if this is :fi, :else, :elseif statements {{{2
+  elseif cs =~ '\<\(else\(if\)\=\|fi\)\>'
+    call MetaSearchNoncomment('\<if\>.\+:\s*\($\|%\)',"bW")
+    let ind = col(".") - 1
+  " }}}
+  " if this is :endgroup statement {{{2
+  elseif cs =~ '^\s*endgroup\>'
+    let ind = ind - &sw
+  endif
+  " }}}
+  " }}}
+
+  return ind
+endfunction
+"
+
+" vim:sw=2:fdm=marker
--- /dev/null
+++ b/lib/vimfiles/indent/mupad.vim
@@ -1,0 +1,35 @@
+" Vim indent file
+" Language:    MuPAD source files
+" Maintainer:  Dave Silvia <dsilvia@mchsi.com>
+" Filenames:   *.mu
+" Date:        6/30/2004
+
+if exists("b:did_indent")
+	finish
+endif
+
+let b:did_indent = 1
+
+runtime indent/GenericIndent.vim
+
+let b:indentStmts=''
+let b:dedentStmts=''
+let b:allStmts=''
+" NOTE:  b:indentStmts, b:dedentStmts, and b:allStmts need to be initialized
+"        to '' before callin the functions because 'indent.vim' explicitly
+"        'unlet's b:did_indent.  This means that the lists will compound if
+"        you change back and forth between buffers.  This is true as of
+"        version 6.3, 6/23/2004.
+setlocal indentexpr=GenericIndent()
+setlocal indentkeys==end_proc,=then,=else,=elif,=end_if,=end_case,=until,=end_repeat,=end_domain,=end_for,=end_while,=end,o,O
+
+call GenericIndentStmts('begin,if,then,else,elif,case,repeat,until,domain,do')
+call GenericDedentStmts('end_proc,then,else,elif,end_if,end_case,until,end_repeat,end_domain,end_for,end_while,end')
+call GenericAllStmts()
+
+
+" TODO:  More comprehensive indentstmt, dedentstmt, and indentkeys values.
+"
+" BUGS:  You tell me!  Probably.  I just haven't found one yet or haven't been
+"        told about one.
+"
--- /dev/null
+++ b/lib/vimfiles/indent/objc.vim
@@ -1,0 +1,79 @@
+"   Vim indent file
+"   Language:	    Objective-C
+"   Maintainer:	    Kazunobu Kuriyama <kazunobu.kuriyama@nifty.com>
+"   Last Change:    2004 May 16
+"
+
+
+" Only load this indent file when no other was loaded.
+if exists("b:did_indent")
+    finish
+endif
+let b:did_indent = 1
+setlocal cindent
+
+" Set the function to do the work.
+setlocal indentexpr=GetObjCIndent()
+
+" To make a colon (:) suggest an indentation other than a goto/swich label,
+setlocal indentkeys-=:
+setlocal indentkeys+=<:>
+
+" Only define the function once.
+if exists("*GetObjCIndent")
+    finish
+endif
+
+function s:GetWidth(line, regexp)
+    let end = matchend(a:line, a:regexp)
+    let width = 0
+    let i = 0
+    while i < end
+	if a:line[i] != "\t"
+	    let width = width + 1
+	else
+	    let width = width + &ts - (width % &ts)
+	endif
+	let i = i + 1
+    endwhile
+    return width
+endfunction
+
+function s:LeadingWhiteSpace(line)
+    let end = strlen(a:line)
+    let width = 0
+    let i = 0
+    while i < end
+	let char = a:line[i]
+	if char != " " && char != "\t"
+	    break
+	endif
+	if char != "\t"
+	    let width = width + 1
+	else
+	    let width = width + &ts - (width % &ts)
+	endif
+	let i = i + 1
+    endwhile
+    return width
+endfunction
+
+
+function GetObjCIndent()
+    let theIndent = cindent(v:lnum)
+
+    let prev_line = getline(v:lnum - 1)
+    let cur_line = getline(v:lnum)
+
+    if prev_line !~# ":" || cur_line !~# ":"
+	return theIndent
+    endif
+
+    if prev_line !~# ";"
+	let prev_colon_pos = s:GetWidth(prev_line, ":")
+	let delta = s:GetWidth(cur_line, ":") - s:LeadingWhiteSpace(cur_line)
+	let theIndent = prev_colon_pos - delta
+    endif
+
+    return theIndent
+endfunction
--- /dev/null
+++ b/lib/vimfiles/indent/ocaml.vim
@@ -1,0 +1,253 @@
+" Vim indent file
+" Language:     OCaml
+" Maintainers:	Jean-Francois Yuen   <jfyuen@happycoders.org>
+"		Mike Leary	     <leary@nwlink.com>
+"		Markus Mottl	     <markus.mottl@gmail.com>
+" URL:		http://www.ocaml.info/vim/indent/ocaml.vim
+" Last Change:  2005 Jun 25 - Fixed multiple bugs due to 'else\nreturn ind' working
+"		2005 May 09 - Added an option to not indent OCaml-indents specially (MM)
+"		2005 Apr 11 - Fixed an indentation bug concerning "let" (MM)
+
+" Only load this indent file when no other was loaded.
+if exists("b:did_indent")
+ finish
+endif
+let b:did_indent = 1
+
+setlocal expandtab
+setlocal indentexpr=GetOCamlIndent()
+setlocal indentkeys+=0=and,0=class,0=constraint,0=done,0=else,0=end,0=exception,0=external,0=if,0=in,0=include,0=inherit,0=initializer,0=let,0=method,0=open,0=then,0=type,0=val,0=with,0;;,0>\],0\|\],0>},0\|,0},0\],0)
+setlocal nolisp
+setlocal nosmartindent
+setlocal textwidth=80
+
+" Comment formatting
+if !exists("no_ocaml_comments")
+ if (has("comments"))
+   setlocal comments=sr:(*,mb:*,ex:*)
+   setlocal fo=cqort
+ endif
+endif
+
+" Only define the function once.
+if exists("*GetOCamlIndent")
+ finish
+endif
+
+" Define some patterns:
+let s:beflet = '^\s*\(initializer\|method\|try\)\|\(\<\(begin\|do\|else\|in\|then\|try\)\|->\|<-\|=\|;\|(\)\s*$'
+let s:letpat = '^\s*\(let\|type\|module\|class\|open\|exception\|val\|include\|external\)\>'
+let s:letlim = '\(\<\(sig\|struct\)\|;;\)\s*$'
+let s:lim = '^\s*\(exception\|external\|include\|let\|module\|open\|type\|val\)\>'
+let s:module = '\<\%(begin\|sig\|struct\|object\)\>'
+let s:obj = '^\s*\(constraint\|inherit\|initializer\|method\|val\)\>\|\<\(object\|object\s*(.*)\)\s*$'
+let s:type = '^\s*\%(class\|let\|type\)\>.*='
+
+" Skipping pattern, for comments
+function s:GetLineWithoutFullComment(lnum)
+ let lnum = prevnonblank(a:lnum - 1)
+ let lline = substitute(getline(lnum), '(\*.*\*)\s*$', '', '')
+ while lline =~ '^\s*$' && lnum > 0
+   let lnum = prevnonblank(lnum - 1)
+   let lline = substitute(getline(lnum), '(\*.*\*)\s*$', '', '')
+ endwhile
+ return lnum
+endfunction
+
+" Indent for ';;' to match multiple 'let'
+function s:GetInd(lnum, pat, lim)
+ let llet = search(a:pat, 'bW')
+ let old = indent(a:lnum)
+ while llet > 0
+   let old = indent(llet)
+   let nb = s:GetLineWithoutFullComment(llet)
+   if getline(nb) =~ a:lim
+     return old
+   endif
+   let llet = search(a:pat, 'bW')
+ endwhile
+ return old
+endfunction
+
+" Indent pairs
+function s:FindPair(pstart, pmid, pend)
+ call search(a:pend, 'bW')
+ return indent(searchpair(a:pstart, a:pmid, a:pend, 'bWn', 'synIDattr(synID(line("."), col("."), 0), "name") =~? "string\\|comment"'))
+endfunction
+
+" Indent 'let'
+function s:FindLet(pstart, pmid, pend)
+ call search(a:pend, 'bW')
+ return indent(searchpair(a:pstart, a:pmid, a:pend, 'bWn', 'synIDattr(synID(line("."), col("."), 0), "name") =~? "string\\|comment" || getline(".") =~ "^\\s*let\\>.*=.*\\<in\\s*$" || getline(prevnonblank(".") - 1) =~ s:beflet'))
+endfunction
+
+function GetOCamlIndent()
+ " Find a non-commented line above the current line.
+ let lnum = s:GetLineWithoutFullComment(v:lnum)
+
+ " At the start of the file use zero indent.
+ if lnum == 0
+   return 0
+ endif
+
+ let ind = indent(lnum)
+ let lline = substitute(getline(lnum), '(\*.*\*)\s*$', '', '')
+
+ " Return double 'shiftwidth' after lines matching:
+ if lline =~ '^\s*|.*->\s*$'
+   return ind + &sw + &sw
+ endif
+
+ let line = getline(v:lnum)
+
+ " Indent if current line begins with 'end':
+ if line =~ '^\s*end\>'
+   return s:FindPair(s:module, '','\<end\>')
+
+ " Indent if current line begins with 'done' for 'do':
+ elseif line =~ '^\s*done\>'
+   return s:FindPair('\<do\>', '','\<done\>')
+
+ " Indent if current line begins with '}' or '>}':
+ elseif line =~ '^\s*\(\|>\)}'
+   return s:FindPair('{', '','}')
+
+ " Indent if current line begins with ']', '|]' or '>]':
+ elseif line =~ '^\s*\(\||\|>\)\]'
+   return s:FindPair('\[', '','\]')
+
+ " Indent if current line begins with ')':
+ elseif line =~ '^\s*)'
+   return s:FindPair('(', '',')')
+
+ " Indent if current line begins with 'let':
+ elseif line =~ '^\s*let\>'
+   if lline !~ s:lim . '\|' . s:letlim . '\|' . s:beflet
+     return s:FindLet(s:type, '','\<let\s*$')
+   endif
+
+ " Indent if current line begins with 'class' or 'type':
+ elseif line =~ '^\s*\(class\|type\)\>'
+   if lline !~ s:lim . '\|\<and\s*$\|' . s:letlim
+     return s:FindLet(s:type, '','\<\(class\|type\)\s*$')
+   endif
+
+ " Indent for pattern matching:
+ elseif line =~ '^\s*|'
+   if lline !~ '^\s*\(|[^\]]\|\(match\|type\|with\)\>\)\|\<\(function\|parser\|private\|with\)\s*$'
+     call search('|', 'bW')
+     return indent(searchpair('^\s*\(match\|type\)\>\|\<\(function\|parser\|private\|with\)\s*$', '', '^\s*|', 'bWn', 'synIDattr(synID(line("."), col("."), 0), "name") =~? "string\\|comment" || getline(".") !~ "^\\s*|.*->"'))
+   endif
+
+ " Indent if current line begins with ';;':
+ elseif line =~ '^\s*;;'
+   if lline !~ ';;\s*$'
+     return s:GetInd(v:lnum, s:letpat, s:letlim)
+   endif
+
+ " Indent if current line begins with 'in':
+ elseif line =~ '^\s*in\>'
+   if lline !~ '^\s*\(let\|and\)\>'
+     return s:FindPair('\<let\>', '', '\<in\>')
+   endif
+
+ " Indent if current line begins with 'else':
+ elseif line =~ '^\s*else\>'
+   if lline !~ '^\s*\(if\|then\)\>'
+     return s:FindPair('\<if\>', '', '\<else\>')
+   endif
+
+ " Indent if current line begins with 'then':
+ elseif line =~ '^\s*then\>'
+   if lline !~ '^\s*\(if\|else\)\>'
+     return s:FindPair('\<if\>', '', '\<then\>')
+   endif
+
+ " Indent if current line begins with 'and':
+ elseif line =~ '^\s*and\>'
+   if lline !~ '^\s*\(and\|let\|type\)\>\|\<end\s*$'
+     return ind - &sw
+   endif
+
+ " Indent if current line begins with 'with':
+ elseif line =~ '^\s*with\>'
+   if lline !~ '^\s*\(match\|try\)\>'
+     return s:FindPair('\<\%(match\|try\)\>', '','\<with\>')
+   endif
+
+ " Indent if current line begins with 'exception', 'external', 'include' or
+ " 'open':
+ elseif line =~ '^\s*\(exception\|external\|include\|open\)\>'
+   if lline !~ s:lim . '\|' . s:letlim
+     call search(line)
+     return indent(search('^\s*\(\(exception\|external\|include\|open\|type\)\>\|val\>.*:\)', 'bW'))
+   endif
+
+ " Indent if current line begins with 'val':
+ elseif line =~ '^\s*val\>'
+   if lline !~ '^\s*\(exception\|external\|include\|open\)\>\|' . s:obj . '\|' . s:letlim
+     return indent(search('^\s*\(\(exception\|include\|initializer\|method\|open\|type\|val\)\>\|external\>.*:\)', 'bW'))
+   endif
+
+ " Indent if current line begins with 'constraint', 'inherit', 'initializer'
+ " or 'method':
+ elseif line =~ '^\s*\(constraint\|inherit\|initializer\|method\)\>'
+   if lline !~ s:obj
+     return indent(search('\<\(object\|object\s*(.*)\)\s*$', 'bW')) + &sw
+   endif
+
+ endif
+
+ " Add a 'shiftwidth' after lines ending with:
+ if lline =~ '\(:\|=\|->\|<-\|(\|\[\|{\|{<\|\[|\|\[<\|\<\(begin\|do\|else\|fun\|function\|functor\|if\|initializer\|object\|parser\|private\|sig\|struct\|then\|try\)\|\<object\s*(.*)\)\s*$'
+   let ind = ind + &sw
+
+ " Back to normal indent after lines ending with ';;':
+ elseif lline =~ ';;\s*$' && lline !~ '^\s*;;'
+   let ind = s:GetInd(v:lnum, s:letpat, s:letlim)
+
+ " Back to normal indent after lines ending with 'end':
+ elseif lline =~ '\<end\s*$'
+   let ind = s:FindPair(s:module, '','\<end\>')
+
+ " Back to normal indent after lines ending with 'in':
+ elseif lline =~ '\<in\s*$' && lline !~ '^\s*in\>'
+   let ind = s:FindPair('\<let\>', '', '\<in\>')
+
+ " Back to normal indent after lines ending with 'done':
+ elseif lline =~ '\<done\s*$'
+   let ind = s:FindPair('\<do\>', '','\<done\>')
+
+ " Back to normal indent after lines ending with '}' or '>}':
+ elseif lline =~ '\(\|>\)}\s*$'
+   let ind = s:FindPair('{', '','}')
+
+ " Back to normal indent after lines ending with ']', '|]' or '>]':
+ elseif lline =~ '\(\||\|>\)\]\s*$'
+   let ind = s:FindPair('\[', '','\]')
+
+ " Back to normal indent after comments:
+ elseif lline =~ '\*)\s*$'
+   call search('\*)', 'bW')
+   let ind = indent(searchpair('(\*', '', '\*)', 'bWn', 'synIDattr(synID(line("."), col("."), 0), "name") =~? "string"'))
+
+ " Back to normal indent after lines ending with ')':
+ elseif lline =~ ')\s*$'
+   let ind = s:FindPair('(', '',')')
+
+ " If this is a multiline comment then align '*':
+ elseif lline =~ '^\s*(\*' && line =~ '^\s*\*'
+   let ind = ind + 1
+
+ endif
+
+ " Subtract a 'shiftwidth' after lines matching 'match ... with parser':
+ if lline =~ '\<match\>.*\<with\>\s*\<parser\s*$'
+   let ind = ind - &sw
+ endif
+
+ return ind
+
+endfunction
+
+" vim:sw=2
--- /dev/null
+++ b/lib/vimfiles/indent/occam.vim
@@ -1,0 +1,182 @@
+" Vim indent file
+" Language:	occam
+" Maintainer:	Mario Schweigler <ms44@kent.ac.uk>
+" Last Change:	23 April 2003
+
+" Only load this indent file when no other was loaded.
+if exists("b:did_indent")
+  finish
+endif
+let b:did_indent = 1
+
+"{{{  Settings
+" Set the occam indent function
+setlocal indentexpr=GetOccamIndent()
+" Indent after new line and after initial colon
+setlocal indentkeys=o,O,0=:
+"}}}
+
+" Only define the function once
+if exists("*GetOccamIndent")
+  finish
+endif
+
+"{{{  Indent definitions
+" Define carriage return indent
+let s:FirstLevelIndent = '^\C\s*\(IF\|ALT\|PRI\s\+ALT\|PAR\|SEQ\|PRI\s\+PAR\|WHILE\|VALOF\|CLAIM\|FORKING\)\>\|\(--.*\)\@<!\(\<PROC\>\|??\|\<CASE\>\s*\(--.*\)\=\_$\)'
+let s:FirstLevelNonColonEndIndent = '^\C\s*PROTOCOL\>\|\(--.*\)\@<!\<\(\(CHAN\|DATA\)\s\+TYPE\|FUNCTION\)\>'
+let s:SecondLevelIndent = '^\C\s*\(IF\|ALT\|PRI\s\+ALT\)\>\|\(--.*\)\@<!?\s*\<CASE\>\s*\(--.*\)\=\_$'
+let s:SecondLevelNonColonEndIndent = '\(--.*\)\@<!\<\(CHAN\|DATA\)\s\+TYPE\>'
+
+" Define colon indent
+let s:ColonIndent = '\(--.*\)\@<!\<PROC\>'
+let s:ColonNonColonEndIndent = '^\C\s*PROTOCOL\>\|\(--.*\)\@<!\<\(\(CHAN\|DATA\)\s\+TYPE\|FUNCTION\)\>'
+
+let s:ColonEnd = '\(--.*\)\@<!:\s*\(--.*\)\=$'
+let s:ColonStart = '^\s*:\s*\(--.*\)\=$'
+
+" Define comment
+let s:CommentLine = '^\s*--'
+"}}}
+
+"{{{  function GetOccamIndent()
+" Auxiliary function to get the correct indent for a line of occam code
+function GetOccamIndent()
+
+  " Ensure magic is on
+  let save_magic = &magic
+  setlocal magic
+
+  " Get reference line number
+  let linenum = prevnonblank(v:lnum - 1)
+  while linenum > 0 && getline(linenum) =~ s:CommentLine
+    let linenum = prevnonblank(linenum - 1)
+  endwhile
+
+  " Get current indent
+  let curindent = indent(linenum)
+
+  " Get current line
+  let line = getline(linenum)
+
+  " Get previous line number
+  let prevlinenum = prevnonblank(linenum - 1)
+  while prevlinenum > 0 && getline(prevlinenum) =~ s:CommentLine
+    let prevlinenum = prevnonblank(prevlinenum - 1)
+  endwhile
+
+  " Get previous line
+  let prevline = getline(prevlinenum)
+
+  " Colon indent
+  if getline(v:lnum) =~ s:ColonStart
+
+    let found = 0
+
+    while found < 1
+
+      if line =~ s:ColonStart
+	let found = found - 1
+      elseif line =~ s:ColonIndent || (line =~ s:ColonNonColonEndIndent && line !~ s:ColonEnd)
+	let found = found + 1
+      endif
+
+      if found < 1
+	let linenum = prevnonblank(linenum - 1)
+	if linenum > 0
+	  let line = getline(linenum)
+	else
+	  let found = 1
+	endif
+      endif
+
+    endwhile
+
+    if linenum > 0
+      let curindent = indent(linenum)
+    else
+      let colonline = getline(v:lnum)
+      let tabstr = ''
+      while strlen(tabstr) < &tabstop
+	let tabstr = ' ' . tabstr
+      endwhile
+      let colonline = substitute(colonline, '\t', tabstr, 'g')
+      let curindent = match(colonline, ':')
+    endif
+
+    " Restore magic
+    if !save_magic|setlocal nomagic|endif
+
+    return curindent
+  endif
+
+  if getline(v:lnum) =~ '^\s*:'
+    let colonline = getline(v:lnum)
+    let tabstr = ''
+    while strlen(tabstr) < &tabstop
+      let tabstr = ' ' . tabstr
+    endwhile
+    let colonline = substitute(colonline, '\t', tabstr, 'g')
+    let curindent = match(colonline, ':')
+
+    " Restore magic
+    if !save_magic|setlocal nomagic|endif
+
+    return curindent
+  endif
+
+  " Carriage return indenat
+  if line =~ s:FirstLevelIndent || (line =~ s:FirstLevelNonColonEndIndent && line !~ s:ColonEnd)
+	\ || (line !~ s:ColonStart && (prevline =~ s:SecondLevelIndent
+	\ || (prevline =~ s:SecondLevelNonColonEndIndent && prevline !~ s:ColonEnd)))
+    let curindent = curindent + &shiftwidth
+
+    " Restore magic
+    if !save_magic|setlocal nomagic|endif
+
+    return curindent
+  endif
+
+  " Commented line
+  if getline(prevnonblank(v:lnum - 1)) =~ s:CommentLine
+
+    " Restore magic
+    if !save_magic|setlocal nomagic|endif
+
+    return indent(prevnonblank(v:lnum - 1))
+  endif
+
+  " Look for previous second level IF / ALT / PRI ALT
+  let found = 0
+
+  while !found
+
+    if indent(prevlinenum) == curindent - &shiftwidth
+      let found = 1
+    endif
+
+    if !found
+      let prevlinenum = prevnonblank(prevlinenum - 1)
+      while prevlinenum > 0 && getline(prevlinenum) =~ s:CommentLine
+	let prevlinenum = prevnonblank(prevlinenum - 1)
+      endwhile
+      if prevlinenum == 0
+	let found = 1
+      endif
+    endif
+
+  endwhile
+
+  if prevlinenum > 0
+    if getline(prevlinenum) =~ s:SecondLevelIndent
+      let curindent = curindent + &shiftwidth
+    endif
+  endif
+
+  " Restore magic
+  if !save_magic|setlocal nomagic|endif
+
+  return curindent
+
+endfunction
+"}}}
--- /dev/null
+++ b/lib/vimfiles/indent/pascal.vim
@@ -1,0 +1,173 @@
+" Vim indent file
+" Language:    Pascal
+" Maintainer:  Neil Carter <n.carter@swansea.ac.uk>
+" Created:     2004 Jul 13
+" Last Change: 2005 Jul 05
+
+
+if exists("b:did_indent")
+	finish
+endif
+let b:did_indent = 1
+
+setlocal indentexpr=GetPascalIndent(v:lnum)
+setlocal indentkeys&
+setlocal indentkeys+==end;,==const,==type,==var,==begin,==repeat,==until,==for
+setlocal indentkeys+==program,==function,==procedure,==object,==private
+setlocal indentkeys+==record,==if,==else,==case
+
+if exists("*GetPascalIndent")
+	finish
+endif
+
+
+function! s:GetPrevNonCommentLineNum( line_num )
+
+	" Skip lines starting with a comment
+	let SKIP_LINES = '^\s*\(\((\*\)\|\(\*\ \)\|\(\*)\)\|{\|}\)'
+
+	let nline = a:line_num
+	while nline > 0
+		let nline = prevnonblank(nline-1)
+		if getline(nline) !~? SKIP_LINES
+			break
+		endif
+	endwhile
+
+	return nline
+endfunction
+
+
+function! GetPascalIndent( line_num )
+	" Line 0 always goes at column 0
+	if a:line_num == 0
+		return 0
+	endif
+
+	let this_codeline = getline( a:line_num )
+
+	" If in the middle of a three-part comment
+	if this_codeline =~ '^\s*\*'
+		return indent( a:line_num )
+	endif
+
+	let prev_codeline_num = s:GetPrevNonCommentLineNum( a:line_num )
+	let prev_codeline = getline( prev_codeline_num )
+	let indnt = indent( prev_codeline_num )
+
+	" Compiler directives should always go in column zero.
+	if this_codeline =~ '^\s*{\(\$IFDEF\|\$ELSE\|\$ENDIF\)'
+		return 0
+	endif
+
+	" These items have nothing before or after (not even a comment), and
+	" go on column 0. Make sure that the ^\s* is followed by \( to make
+	" ORs work properly, and not include the start of line (this must
+	" always appear).
+	" The bracketed expression with the underline is a routine
+	" separator. This is one case where we do indent comment lines.
+	if this_codeline =~ '^\s*\((\*\ _\+\ \*)\|\<\(const\|var\)\>\)$'
+		return 0
+	endif
+
+	" These items may have text after them, and go on column 0 (in most
+	" cases). The problem is that "function" and "procedure" keywords
+	" should be indented if within a class declaration.
+	if this_codeline =~ '^\s*\<\(program\|type\|uses\|procedure\|function\)\>'
+		return 0
+	endif
+
+	" BEGIN
+	" If the begin does not come after "if", "for", or "else", then it
+	" goes in column 0
+	if this_codeline =~ '^\s*begin\>' && prev_codeline !~ '^\s*\<\(if\|for\|else\)\>'
+		return 0
+	endif
+
+	" These keywords are indented once only.
+	if this_codeline =~ '^\s*\<\(private\)\>'
+		return &shiftwidth
+	endif
+
+	" If the PREVIOUS LINE contained these items, the current line is
+	" always indented once.
+	if prev_codeline =~ '^\s*\<\(type\|uses\)\>'
+		return &shiftwidth
+	endif
+
+	" These keywords are indented once only. Possibly surrounded by
+	" other chars.
+	if this_codeline =~ '^.\+\<\(object\|record\)\>'
+		return &shiftwidth
+	endif
+
+	" If the previous line was indenting...
+	if prev_codeline =~ '^\s*\<\(for\|if\|case\|else\|end\ else\)\>'
+		" then indent.
+		let indnt = indnt + &shiftwidth
+		" BUT... if this is the start of a multistatement block then we
+		" need to align the begin with the previous line.
+		if this_codeline =~ '^\s*begin\>'
+			return indnt - &shiftwidth
+		endif
+
+		" We also need to keep the indentation level constant if the
+		" whole if-then statement was on one line.
+		if prev_codeline =~ '\<then\>.\+'
+			let indnt = indnt - &shiftwidth
+		endif
+	endif
+
+	" PREVIOUS-LINE BEGIN
+	" If the previous line was an indenting keyword then indent once...
+	if prev_codeline =~ '^\s*\<\(const\|var\|begin\|repeat\|private\)\>'
+		" But only if this is another var in a list.
+		if this_codeline !~ '^\s*var\>'
+			return indnt + &shiftwidth
+		endif
+	endif
+
+	" PREVIOUS-LINE BEGIN
+	" Indent code after a case statement begin
+	if prev_codeline =~ '\:\ begin\>'
+		return indnt + &shiftwidth
+	endif
+
+	" These words may have text before them on the line (hence the .*)
+	" but are followed by nothing. Always indent once only.
+	if prev_codeline =~ '^\(.*\|\s*\)\<\(object\|record\)\>$'
+		return indnt + &shiftwidth
+	endif
+
+	" If we just closed a bracket that started on a previous line, then
+	" unindent. But don't return yet -- we need to check for further
+	" unindentation (for end/until/else)
+	if prev_codeline =~ '^[^(]*[^*])'
+		let indnt = indnt - &shiftwidth
+	endif
+
+	" At the end of a block, we have to unindent both the current line
+	" (the "end" for instance) and the newly-created line.
+	if this_codeline =~ '^\s*\<\(end\|until\|else\)\>'
+		return indnt - &shiftwidth
+	endif
+
+	" If we have opened a bracket and it continues over one line,
+	" then indent once.
+	"
+	" RE = an opening bracket followed by any amount of anything other
+	" than a closing bracket and then the end-of-line.
+	"
+	" If we didn't include the end of line, this RE would match even
+	" closed brackets, since it would match everything up to the closing
+	" bracket.
+	"
+	" This test isn't clever enough to handle brackets inside strings or
+	" comments.
+	if prev_codeline =~ '([^*]\=[^)]*$'
+		return indnt + &shiftwidth
+	endif
+
+	return indnt
+endfunction
+
--- /dev/null
+++ b/lib/vimfiles/indent/perl.vim
@@ -1,0 +1,180 @@
+" Vim indent file
+" Language:	Perl
+" Author:	Rafael Garcia-Suarez <rgarciasuarez@free.fr>
+" URL:		http://rgarciasuarez.free.fr/vim/indent/perl.vim
+" Last Change:	2005 Sep 07
+
+" Suggestions and improvements by :
+"   Aaron J. Sherman (use syntax for hints)
+"   Artem Chuprina (play nice with folding)
+
+" TODO things that are not or not properly indented (yet) :
+" - Continued statements
+"     print "foo",
+"	"bar";
+"     print "foo"
+"	if bar();
+" - Multiline regular expressions (m//x)
+" (The following probably needs modifying the perl syntax file)
+" - qw() lists
+" - Heredocs with terminators that don't match \I\i*
+
+" Only load this indent file when no other was loaded.
+if exists("b:did_indent")
+  finish
+endif
+let b:did_indent = 1
+
+" Is syntax highlighting active ?
+let b:indent_use_syntax = has("syntax")
+
+setlocal indentexpr=GetPerlIndent()
+setlocal indentkeys+=0=,0),0=or,0=and
+if !b:indent_use_syntax
+  setlocal indentkeys+=0=EO
+endif
+
+" Only define the function once.
+if exists("*GetPerlIndent")
+  finish
+endif
+
+let s:cpo_save = &cpo
+set cpo-=C
+
+function GetPerlIndent()
+
+  " Get the line to be indented
+  let cline = getline(v:lnum)
+
+  " Indent POD markers to column 0
+  if cline =~ '^\s*=\L\@!'
+    return 0
+  endif
+
+  " Don't reindent coments on first column
+  if cline =~ '^#.'
+    return 0
+  endif
+
+  " Get current syntax item at the line's first char
+  let csynid = ''
+  if b:indent_use_syntax
+    let csynid = synIDattr(synID(v:lnum,1,0),"name")
+  endif
+
+  " Don't reindent POD and heredocs
+  if csynid == "perlPOD" || csynid == "perlHereDoc" || csynid =~ "^pod"
+    return indent(v:lnum)
+  endif
+
+  " Indent end-of-heredocs markers to column 0
+  if b:indent_use_syntax
+    " Assumes that an end-of-heredoc marker matches \I\i* to avoid
+    " confusion with other types of strings
+    if csynid == "perlStringStartEnd" && cline =~ '^\I\i*$'
+      return 0
+    endif
+  else
+    " Without syntax hints, assume that end-of-heredocs markers begin with EO
+    if cline =~ '^\s*EO'
+      return 0
+    endif
+  endif
+
+  " Now get the indent of the previous perl line.
+
+  " Find a non-blank line above the current line.
+  let lnum = prevnonblank(v:lnum - 1)
+  " Hit the start of the file, use zero indent.
+  if lnum == 0
+    return 0
+  endif
+  let line = getline(lnum)
+  let ind = indent(lnum)
+  " Skip heredocs, POD, and comments on 1st column
+  if b:indent_use_syntax
+    let skippin = 2
+    while skippin
+      let synid = synIDattr(synID(lnum,1,0),"name")
+      if (synid == "perlStringStartEnd" && line =~ '^\I\i*$')
+	    \ || (skippin != 2 && synid == "perlPOD")
+	    \ || (skippin != 2 && synid == "perlHereDoc")
+	    \ || synid == "perlComment"
+	    \ || synid =~ "^pod"
+	let lnum = prevnonblank(lnum - 1)
+	if lnum == 0
+	  return 0
+	endif
+	let line = getline(lnum)
+	let ind = indent(lnum)
+	let skippin = 1
+      else
+	let skippin = 0
+      endif
+    endwhile
+  else
+    if line =~ "^EO"
+      let lnum = search("<<[\"']\\=EO", "bW")
+      let line = getline(lnum)
+      let ind = indent(lnum)
+    endif
+  endif
+
+  " Indent blocks enclosed by {} or ()
+  if b:indent_use_syntax
+    " Find a real opening brace
+    let bracepos = match(line, '[(){}]', matchend(line, '^\s*[)}]'))
+    while bracepos != -1
+      let synid = synIDattr(synID(lnum, bracepos + 1, 0), "name")
+      " If the brace is highlighted in one of those groups, indent it.
+      " 'perlHereDoc' is here only to handle the case '&foo(<<EOF)'.
+      if synid == ""
+	    \ || synid == "perlMatchStartEnd"
+	    \ || synid == "perlHereDoc"
+	    \ || synid =~ "^perlFiledescStatement"
+	    \ || synid =~ '^perl\(Sub\|BEGINEND\|If\)Fold'
+	let brace = strpart(line, bracepos, 1)
+	if brace == '(' || brace == '{'
+	  let ind = ind + &sw
+	else
+	  let ind = ind - &sw
+	endif
+      endif
+      let bracepos = match(line, '[(){}]', bracepos + 1)
+    endwhile
+    let bracepos = matchend(cline, '^\s*[)}]')
+    if bracepos != -1
+      let synid = synIDattr(synID(v:lnum, bracepos, 0), "name")
+      if synid == ""
+	    \ || synid == "perlMatchStartEnd"
+	    \ || synid =~ '^perl\(Sub\|BEGINEND\|If\)Fold'
+	let ind = ind - &sw
+      endif
+    endif
+  else
+    if line =~ '[{(]\s*\(#[^)}]*\)\=$'
+      let ind = ind + &sw
+    endif
+    if cline =~ '^\s*[)}]'
+      let ind = ind - &sw
+    endif
+  endif
+
+  " Indent lines that begin with 'or' or 'and'
+  if cline =~ '^\s*\(or\|and\)\>'
+    if line !~ '^\s*\(or\|and\)\>'
+      let ind = ind + &sw
+    endif
+  elseif line =~ '^\s*\(or\|and\)\>'
+    let ind = ind - &sw
+  endif
+
+  return ind
+
+endfunction
+
+let &cpo = s:cpo_save
+unlet s:cpo_save
+
+" vim:ts=8:sts=2:sw=2
--- /dev/null
+++ b/lib/vimfiles/indent/php.vim
@@ -1,0 +1,716 @@
+" Vim indent file
+" Language:	PHP
+" Author:	John Wellesz <John.wellesz (AT) teaser (DOT) fr>
+" URL:		http://www.2072productions.com/vim/indent/php.vim
+" Last Change:  2007 February 25th
+" Newsletter:   http://www.2072productions.com/?to=php-indent-for-vim-newsletter.php
+" Version:	1.24
+"
+"  The change log and all the comments have been removed from this file.
+"
+"  For a complete change log and fully commented code, download the script on
+"  2072productions.com at the URI provided above.
+"
+"  If you find a bug, please e-mail me at John.wellesz (AT) teaser (DOT) fr
+"  with an example of code that breaks the algorithm.
+"
+"
+"	Thanks a lot for using this script.
+"
+"
+" NOTE: This script must be used with PHP syntax ON and with the php syntax
+"	script by Lutz Eymers ( http://www.isp.de/data/php.vim ) that's the script bundled with Vim.
+"
+"
+"	In the case you have syntax errors in your script such as end of HereDoc
+"	tags not at col 1 you'll have to indent your file 2 times (This script
+"	will automatically put HereDoc end tags at col 1).
+"
+"
+" NOTE: If you are editing file in Unix file format and that (by accident)
+" there are '\r' before new lines, this script won't be able to proceed
+" correctly and will make many mistakes because it won't be able to match
+" '\s*$' correctly.
+" So you have to remove those useless characters first with a command like:
+"
+" :%s /\r$//g
+"
+" or simply 'let' the option PHP_removeCRwhenUnix to 1 and the script will
+" silently remove them when VIM load this script (at each bufread).
+
+
+" Options: PHP_autoformatcomment = 0 to not enable autoformating of comment by
+"		    default, if set to 0, this script will let the 'formatoptions' setting intact.
+"
+" Options: PHP_default_indenting = # of sw (default is 0), # of sw will be
+"		   added to the indent of each line of PHP code.
+"
+" Options: PHP_removeCRwhenUnix = 1 to make the script automatically remove CR
+"		   at end of lines (by default this option is unset), NOTE that you
+"		   MUST remove CR when the fileformat is UNIX else the indentation
+"		   won't be correct...
+"
+" Options: PHP_BracesAtCodeLevel = 1 to indent the '{' and '}' at the same
+"		   level than the code they contain.
+"		   Exemple:
+"			Instead of:
+"				if ($foo)
+"				{
+"					foo();
+"				}
+"
+"			You will write:
+"				if ($foo)
+"					{
+"					foo();
+"					}
+"
+"			NOTE: The script will be a bit slower if you use this option because
+"			some optimizations won't be available.
+
+if exists("b:did_indent")
+    finish
+endif
+let b:did_indent = 1
+
+
+let php_sync_method = 0
+
+
+if exists("PHP_default_indenting")
+    let b:PHP_default_indenting = PHP_default_indenting * &sw
+else
+    let b:PHP_default_indenting = 0
+endif
+
+if exists("PHP_BracesAtCodeLevel")
+    let b:PHP_BracesAtCodeLevel = PHP_BracesAtCodeLevel
+else
+    let b:PHP_BracesAtCodeLevel = 0
+endif
+
+if exists("PHP_autoformatcomment")
+    let b:PHP_autoformatcomment = PHP_autoformatcomment
+else
+    let b:PHP_autoformatcomment = 1
+endif
+
+let b:PHP_lastindented = 0
+let b:PHP_indentbeforelast = 0
+let b:PHP_indentinghuge = 0
+let b:PHP_CurrentIndentLevel = b:PHP_default_indenting
+let b:PHP_LastIndentedWasComment = 0
+let b:PHP_InsideMultilineComment = 0
+let b:InPHPcode = 0
+let b:InPHPcode_checked = 0
+let b:InPHPcode_and_script = 0
+let b:InPHPcode_tofind = ""
+let b:PHP_oldchangetick = b:changedtick
+let b:UserIsTypingComment = 0
+let b:optionsset = 0
+
+setlocal nosmartindent
+setlocal noautoindent
+setlocal nocindent
+setlocal nolisp
+
+setlocal indentexpr=GetPhpIndent()
+setlocal indentkeys=0{,0},0),:,!^F,o,O,e,*<Return>,=?>,=<?,=*/
+
+
+
+let s:searchpairflags = 'bWr'
+
+if &fileformat == "unix" && exists("PHP_removeCRwhenUnix") && PHP_removeCRwhenUnix
+    silent! %s/\r$//g
+endif
+
+if exists("*GetPhpIndent")
+    finish " XXX
+endif
+
+let s:endline= '\s*\%(//.*\|#.*\|/\*.*\*/\s*\)\=$'
+let s:PHP_startindenttag = '<?\%(.*?>\)\@!\|<script[^>]*>\%(.*<\/script>\)\@!'
+"setlocal debug=msg " XXX
+
+
+function! GetLastRealCodeLNum(startline) " {{{
+
+    let lnum = a:startline
+
+    if b:GetLastRealCodeLNum_ADD && b:GetLastRealCodeLNum_ADD == lnum + 1
+	let lnum = b:GetLastRealCodeLNum_ADD
+    endif
+
+    let old_lnum = lnum
+
+    while lnum > 1
+	let lnum = prevnonblank(lnum)
+	let lastline = getline(lnum)
+
+	if b:InPHPcode_and_script && lastline =~ '?>\s*$'
+	    let lnum = lnum - 1
+	elseif lastline =~ '^\s*?>.*<?\%(php\)\=\s*$'
+	    let lnum = lnum - 1
+	elseif lastline =~ '^\s*\%(//\|#\|/\*.*\*/\s*$\)'
+	    let lnum = lnum - 1
+	elseif lastline =~ '\*/\s*$'
+	    call cursor(lnum, 1)
+	    if lastline !~ '^\*/'
+		call search('\*/', 'W')
+	    endif
+	    let lnum = searchpair('/\*', '', '\*/', s:searchpairflags, 'Skippmatch2()')
+
+	    let lastline = getline(lnum)
+	    if lastline =~ '^\s*/\*'
+		let lnum = lnum - 1
+	    else
+		break
+	    endif
+
+
+	elseif lastline =~? '\%(//\s*\|?>.*\)\@<!<?\%(php\)\=\s*$\|^\s*<script\>'
+
+	    while lastline !~ '\(<?.*\)\@<!?>' && lnum > 1
+		let lnum = lnum - 1
+		let lastline = getline(lnum)
+	    endwhile
+	    if lastline =~ '^\s*?>'
+		let lnum = lnum - 1
+	    else
+		break
+	    endif
+
+
+	elseif lastline =~? '^\a\w*;$' && lastline !~? s:notPhpHereDoc
+	    let tofind=substitute( lastline, '\([^;]\+\);', '<<<\1$', '')
+	    while getline(lnum) !~? tofind && lnum > 1
+		let lnum = lnum - 1
+	    endwhile
+	else
+	    break
+	endif
+    endwhile
+
+    if lnum==1 && getline(lnum)!~ '<?'
+	let lnum=0
+    endif
+
+    if b:InPHPcode_and_script && !b:InPHPcode
+	let b:InPHPcode_and_script = 0
+    endif
+
+
+
+    return lnum
+endfunction " }}}
+
+function! Skippmatch2()
+
+    let line = getline(".")
+
+   if line =~ '\%(".*\)\@<=/\*\%(.*"\)\@=' || line =~ '\%(//.*\)\@<=/\*'
+       return 1
+   else
+       return 0
+   endif
+endfun
+
+function! Skippmatch()  " {{{
+    let synname = synIDattr(synID(line("."), col("."), 0), "name")
+    if synname == "Delimiter" || synname == "phpRegionDelimiter" || synname =~# "^phpParent" || synname == "phpArrayParens" || synname =~# '^php\%(Block\|Brace\)' || synname == "javaScriptBraces" || synname == "phpComment" && b:UserIsTypingComment
+	return 0
+    else
+	return 1
+    endif
+endfun " }}}
+
+function! FindOpenBracket(lnum) " {{{
+    call cursor(a:lnum, 1)
+    return searchpair('{', '', '}', 'bW', 'Skippmatch()')
+endfun " }}}
+
+function! FindTheIfOfAnElse (lnum, StopAfterFirstPrevElse) " {{{
+
+    if getline(a:lnum) =~# '^\s*}\s*else\%(if\)\=\>'
+	let beforeelse = a:lnum
+    else
+	let beforeelse = GetLastRealCodeLNum(a:lnum - 1)
+    endif
+
+    if !s:level
+	let s:iftoskip = 0
+    endif
+
+    if getline(beforeelse) =~# '^\s*\%(}\s*\)\=else\%(\s*if\)\@!\>'
+	let s:iftoskip = s:iftoskip + 1
+    endif
+
+    if getline(beforeelse) =~ '^\s*}'
+	let beforeelse = FindOpenBracket(beforeelse)
+
+	if getline(beforeelse) =~ '^\s*{'
+	    let beforeelse = GetLastRealCodeLNum(beforeelse - 1)
+	endif
+    endif
+
+
+    if !s:iftoskip && a:StopAfterFirstPrevElse && getline(beforeelse) =~# '^\s*\%([}]\s*\)\=else\%(if\)\=\>'
+	return beforeelse
+    endif
+
+    if getline(beforeelse) !~# '^\s*if\>' && beforeelse>1 || s:iftoskip && beforeelse>1
+
+	if  s:iftoskip && getline(beforeelse) =~# '^\s*if\>'
+	    let s:iftoskip = s:iftoskip - 1
+	endif
+
+	let s:level =  s:level + 1
+	let beforeelse = FindTheIfOfAnElse(beforeelse, a:StopAfterFirstPrevElse)
+    endif
+
+    return beforeelse
+
+endfunction " }}}
+
+function! IslinePHP (lnum, tofind) " {{{
+    let cline = getline(a:lnum)
+
+    if a:tofind==""
+	let tofind = "^\\s*[\"']*\\s*\\zs\\S"
+    else
+	let tofind = a:tofind
+    endif
+
+    let tofind = tofind . '\c'
+
+    let coltotest = match (cline, tofind) + 1
+
+    let synname = synIDattr(synID(a:lnum, coltotest, 0), "name")
+
+    if synname =~ '^php' || synname=="Delimiter" || synname =~? '^javaScript'
+	return synname
+    else
+	return ""
+    endif
+endfunction " }}}
+
+let s:notPhpHereDoc = '\%(break\|return\|continue\|exit\);'
+let s:blockstart = '\%(\%(\%(}\s*\)\=else\%(\s\+\)\=\)\=if\>\|else\>\|while\>\|switch\>\|for\%(each\)\=\>\|declare\>\|class\>\|interface\>\|abstract\>\|try\>\|catch\>\|[|&]\)'
+
+let s:autorestoptions = 0
+if ! s:autorestoptions
+    au BufWinEnter,Syntax	*.php,*.php3,*.php4,*.php5	call ResetOptions()
+    let s:autorestoptions = 1
+endif
+
+function! ResetOptions()
+    if ! b:optionsset
+	if b:PHP_autoformatcomment
+
+	    setlocal comments=s1:/*,mb:*,ex:*/,://,:#
+
+	    setlocal formatoptions-=t
+	    setlocal formatoptions+=q
+	    setlocal formatoptions+=r
+	    setlocal formatoptions+=o
+	    setlocal formatoptions+=w
+	    setlocal formatoptions+=c
+	    setlocal formatoptions+=b
+	endif
+	let b:optionsset = 1
+    endif
+endfunc
+
+function! GetPhpIndent()
+
+    let b:GetLastRealCodeLNum_ADD = 0
+
+    let UserIsEditing=0
+    if	b:PHP_oldchangetick != b:changedtick
+	let b:PHP_oldchangetick = b:changedtick
+	let UserIsEditing=1
+    endif
+
+    if b:PHP_default_indenting
+	let b:PHP_default_indenting = g:PHP_default_indenting * &sw
+    endif
+
+    let cline = getline(v:lnum)
+
+    if !b:PHP_indentinghuge && b:PHP_lastindented > b:PHP_indentbeforelast
+	if b:PHP_indentbeforelast
+	    let b:PHP_indentinghuge = 1
+	    echom 'Large indenting detected, speed optimizations engaged'
+	endif
+	let b:PHP_indentbeforelast = b:PHP_lastindented
+    endif
+
+    if b:InPHPcode_checked && prevnonblank(v:lnum - 1) != b:PHP_lastindented
+	if b:PHP_indentinghuge
+	    echom 'Large indenting deactivated'
+	    let b:PHP_indentinghuge = 0
+	    let b:PHP_CurrentIndentLevel = b:PHP_default_indenting
+	endif
+	let b:PHP_lastindented = v:lnum
+	let b:PHP_LastIndentedWasComment=0
+	let b:PHP_InsideMultilineComment=0
+	let b:PHP_indentbeforelast = 0
+
+	let b:InPHPcode = 0
+	let b:InPHPcode_checked = 0
+	let b:InPHPcode_and_script = 0
+	let b:InPHPcode_tofind = ""
+
+    elseif v:lnum > b:PHP_lastindented
+	let real_PHP_lastindented = b:PHP_lastindented
+	let b:PHP_lastindented = v:lnum
+    endif
+
+
+    if !b:InPHPcode_checked " {{{ One time check
+	let b:InPHPcode_checked = 1
+
+	let synname = ""
+	if cline !~ '<?.*?>'
+	    let synname = IslinePHP (prevnonblank(v:lnum), "")
+	endif
+
+	if synname!=""
+	    if synname != "phpHereDoc" && synname != "phpHereDocDelimiter"
+		let b:InPHPcode = 1
+		let b:InPHPcode_tofind = ""
+
+		if synname == "phpComment"
+		    let b:UserIsTypingComment = 1
+		else
+		    let b:UserIsTypingComment = 0
+		endif
+
+		if synname =~? '^javaScript'
+		    let b:InPHPcode_and_script = 1
+		endif
+
+	    else
+		let b:InPHPcode = 0
+		let b:UserIsTypingComment = 0
+
+		let lnum = v:lnum - 1
+		while getline(lnum) !~? '<<<\a\w*$' && lnum > 1
+		    let lnum = lnum - 1
+		endwhile
+
+		let b:InPHPcode_tofind = substitute( getline(lnum), '^.*<<<\(\a\w*\)\c', '^\\s*\1;$', '')
+	    endif
+	else
+	    let b:InPHPcode = 0
+	    let b:UserIsTypingComment = 0
+	    let b:InPHPcode_tofind = '<?\%(.*?>\)\@!\|<script.*>'
+	endif
+    endif "!b:InPHPcode_checked }}}
+
+
+    " Test if we are indenting PHP code {{{
+    let lnum = prevnonblank(v:lnum - 1)
+    let last_line = getline(lnum)
+
+    if b:InPHPcode_tofind!=""
+	if cline =~? b:InPHPcode_tofind
+	    let	b:InPHPcode = 1
+	    let b:InPHPcode_tofind = ""
+	    let b:UserIsTypingComment = 0
+	    if cline =~ '\*/'
+		call cursor(v:lnum, 1)
+		if cline !~ '^\*/'
+		    call search('\*/', 'W')
+		endif
+		let lnum = searchpair('/\*', '', '\*/', s:searchpairflags, 'Skippmatch2()')
+
+		let b:PHP_CurrentIndentLevel = b:PHP_default_indenting
+
+		let b:PHP_LastIndentedWasComment = 0
+
+		if cline =~ '^\s*\*/'
+		    return indent(lnum) + 1
+		else
+		    return indent(lnum)
+		endif
+
+	    elseif cline =~? '<script\>'
+		let b:InPHPcode_and_script = 1
+		let b:GetLastRealCodeLNum_ADD = v:lnum
+	    endif
+	endif
+    endif
+
+    if b:InPHPcode
+
+	if !b:InPHPcode_and_script && last_line =~ '\%(<?.*\)\@<!?>\%(.*<?\)\@!' && IslinePHP(lnum, '?>')=~"Delimiter"
+	    if cline !~? s:PHP_startindenttag
+		let b:InPHPcode = 0
+		let b:InPHPcode_tofind = s:PHP_startindenttag
+	    elseif cline =~? '<script\>'
+		let b:InPHPcode_and_script = 1
+	    endif
+
+	elseif last_line =~? '<<<\a\w*$'
+	    let b:InPHPcode = 0
+	    let b:InPHPcode_tofind = substitute( last_line, '^.*<<<\(\a\w*\)\c', '^\\s*\1;$', '')
+
+	elseif !UserIsEditing && cline =~ '^\s*/\*\%(.*\*/\)\@!' && getline(v:lnum + 1) !~ '^\s*\*'
+	    let b:InPHPcode = 0
+	    let b:InPHPcode_tofind = '\*/'
+
+	elseif cline =~? '^\s*</script>'
+	    let b:InPHPcode = 0
+	    let b:InPHPcode_tofind = s:PHP_startindenttag
+	endif
+    endif " }}}
+
+
+    if !b:InPHPcode && !b:InPHPcode_and_script
+	return -1
+    endif
+
+    " Indent successive // or # comment the same way the first is {{{
+    if cline =~ '^\s*\%(//\|#\|/\*.*\*/\s*$\)'
+	if b:PHP_LastIndentedWasComment == 1
+	    return indent(real_PHP_lastindented)
+	endif
+	let b:PHP_LastIndentedWasComment = 1
+    else
+	let b:PHP_LastIndentedWasComment = 0
+    endif " }}}
+
+    " Indent multiline /* comments correctly {{{
+
+    if b:PHP_InsideMultilineComment || b:UserIsTypingComment
+	if cline =~ '^\s*\*\%(\/\)\@!'
+	    if last_line =~ '^\s*/\*'
+		return indent(lnum) + 1
+	    else
+		return indent(lnum)
+	    endif
+	else
+	    let b:PHP_InsideMultilineComment = 0
+	endif
+    endif
+
+    if !b:PHP_InsideMultilineComment && cline =~ '^\s*/\*' && cline !~ '\*/\s*$'
+	if getline(v:lnum + 1) !~ '^\s*\*'
+	    return -1
+	endif
+	let b:PHP_InsideMultilineComment = 1
+    endif " }}}
+
+
+    " Things always indented at col 1 (PHP delimiter: <?, ?>, Heredoc end) {{{
+    if cline =~# '^\s*<?' && cline !~ '?>'
+	return 0
+    endif
+
+    if  cline =~ '^\s*?>' && cline !~# '<?'
+	return 0
+    endif
+
+    if cline =~? '^\s*\a\w*;$' && cline !~? s:notPhpHereDoc
+	return 0
+    endif " }}}
+
+    let s:level = 0
+
+    let lnum = GetLastRealCodeLNum(v:lnum - 1)
+
+    let last_line = getline(lnum)
+    let ind = indent(lnum)
+    let endline= s:endline
+
+    if ind==0 && b:PHP_default_indenting
+	let ind = b:PHP_default_indenting
+    endif
+
+    if lnum == 0
+	return b:PHP_default_indenting
+    endif
+
+
+    if cline =~ '^\s*}\%(}}\)\@!'
+	let ind = indent(FindOpenBracket(v:lnum))
+	let b:PHP_CurrentIndentLevel = b:PHP_default_indenting
+	return ind
+    endif
+
+    if cline =~ '^\s*\*/'
+	call cursor(v:lnum, 1)
+	if cline !~ '^\*/'
+	    call search('\*/', 'W')
+	endif
+	let lnum = searchpair('/\*', '', '\*/', s:searchpairflags, 'Skippmatch2()')
+
+	let b:PHP_CurrentIndentLevel = b:PHP_default_indenting
+
+	if cline =~ '^\s*\*/'
+	    return indent(lnum) + 1
+	else
+	    return indent(lnum)
+	endif
+    endif
+
+    let defaultORcase = '^\s*\%(default\|case\).*:'
+
+    if last_line =~ '[;}]'.endline && last_line !~# defaultORcase
+	if ind==b:PHP_default_indenting
+	    return b:PHP_default_indenting
+	elseif b:PHP_indentinghuge && ind==b:PHP_CurrentIndentLevel && cline !~# '^\s*\%(else\|\%(case\|default\).*:\|[})];\=\)' && last_line !~# '^\s*\%(\%(}\s*\)\=else\)' && getline(GetLastRealCodeLNum(lnum - 1))=~';'.endline
+	    return b:PHP_CurrentIndentLevel
+	endif
+    endif
+
+    let LastLineClosed = 0
+
+    let terminated = '\%(;\%(\s*?>\)\=\|<<<\a\w*\|}\)'.endline
+
+    let unstated   = '\%(^\s*'.s:blockstart.'.*)\|\%(//.*\)\@<!\<e'.'lse\>\)'.endline
+
+    if ind != b:PHP_default_indenting && cline =~# '^\s*else\%(if\)\=\>'
+	let b:PHP_CurrentIndentLevel = b:PHP_default_indenting
+	return indent(FindTheIfOfAnElse(v:lnum, 1))
+    elseif cline =~ '^\s*{'
+	let previous_line = last_line
+	let last_line_num = lnum
+
+	while last_line_num > 1
+
+	    if previous_line =~ '^\s*\%(' . s:blockstart . '\|\%([a-zA-Z]\s*\)*function\)' && previous_line !~ '^\s*[|&]'
+
+		let ind = indent(last_line_num)
+
+		if  b:PHP_BracesAtCodeLevel
+		    let ind = ind + &sw
+		endif
+
+		return ind
+	    endif
+
+	    let last_line_num = last_line_num - 1
+	    let previous_line = getline(last_line_num)
+	endwhile
+
+    elseif last_line =~# unstated && cline !~ '^\s*{\|^\s*);\='.endline
+	let ind = ind + &sw
+	return ind
+
+    elseif ind != b:PHP_default_indenting && last_line =~ terminated
+	let previous_line = last_line
+	let last_line_num = lnum
+	let LastLineClosed = 1
+
+	while 1
+	    if previous_line =~ '^\s*}'
+		let last_line_num = FindOpenBracket(last_line_num)
+
+		if getline(last_line_num) =~ '^\s*{'
+		    let last_line_num = GetLastRealCodeLNum(last_line_num - 1)
+		endif
+
+		let previous_line = getline(last_line_num)
+
+		continue
+	    else
+
+		if getline(last_line_num) =~# '^\s*else\%(if\)\=\>'
+		    let last_line_num = FindTheIfOfAnElse(last_line_num, 0)
+		    continue
+		endif
+
+
+		let last_match = last_line_num
+
+		let one_ahead_indent = indent(last_line_num)
+		let last_line_num = GetLastRealCodeLNum(last_line_num - 1)
+		let two_ahead_indent = indent(last_line_num)
+		let after_previous_line = previous_line
+		let previous_line = getline(last_line_num)
+
+
+		if previous_line =~# defaultORcase.'\|{'.endline
+		    break
+		endif
+
+		if after_previous_line=~# '^\s*'.s:blockstart.'.*)'.endline && previous_line =~# '[;}]'.endline
+		    break
+		endif
+
+		if one_ahead_indent == two_ahead_indent || last_line_num < 1
+		    if previous_line =~# '[;}]'.endline || last_line_num < 1
+			break
+		    endif
+		endif
+	    endif
+	endwhile
+
+	if indent(last_match) != ind
+	    let ind = indent(last_match)
+	    let b:PHP_CurrentIndentLevel = b:PHP_default_indenting
+
+	    if cline =~# defaultORcase
+		let ind = ind - &sw
+	    endif
+	    return ind
+	endif
+    endif
+
+    let plinnum = GetLastRealCodeLNum(lnum - 1)
+    let pline = getline(plinnum)
+
+    let last_line = substitute(last_line,"\\(//\\|#\\)\\(\\(\\([^\"']*\\([\"']\\)[^\"']*\\5\\)\\+[^\"']*$\\)\\|\\([^\"']*$\\)\\)",'','')
+
+
+    if ind == b:PHP_default_indenting
+	if last_line =~ terminated
+	    let LastLineClosed = 1
+	endif
+    endif
+
+    if !LastLineClosed
+
+	if last_line =~# '[{(]'.endline || last_line =~? '\h\w*\s*(.*,$' && pline !~ '[,(]'.endline
+
+	    if !b:PHP_BracesAtCodeLevel || last_line !~# '^\s*{'
+		let ind = ind + &sw
+	    endif
+
+	    if b:PHP_BracesAtCodeLevel || cline !~# defaultORcase
+		let b:PHP_CurrentIndentLevel = ind
+		return ind
+	    endif
+
+	elseif last_line =~ '\S\+\s*),'.endline
+	    call cursor(lnum, 1)
+	    call search('),'.endline, 'W')
+	    let openedparent = searchpair('(', '', ')', 'bW', 'Skippmatch()')
+	    if openedparent != lnum
+		let ind = indent(openedparent)
+	    endif
+
+
+	elseif cline !~ '^\s*{' && pline =~ '\%(;\%(\s*?>\)\=\|<<<\a\w*\|{\|^\s*'.s:blockstart.'\s*(.*)\)'.endline.'\|^\s*}\|'.defaultORcase
+
+	    let ind = ind + &sw
+
+	endif
+
+    elseif last_line =~# defaultORcase
+	let ind = ind + &sw
+    endif
+
+    if cline =~  '^\s*);\='
+	let ind = ind - &sw
+    elseif cline =~# defaultORcase
+	let ind = ind - &sw
+
+    endif
+
+    let b:PHP_CurrentIndentLevel = ind
+    return ind
+endfunction
--- /dev/null
+++ b/lib/vimfiles/indent/postscr.vim
@@ -1,0 +1,68 @@
+" PostScript indent file
+" Language:    PostScript
+" Maintainer:  Mike Williams <mrw@netcomuk.co.uk>
+" Last Change: 2nd July 2001
+"
+
+" Only load this indent file when no other was loaded.
+if exists("b:did_indent")
+  finish
+endif
+let b:did_indent = 1
+
+setlocal indentexpr=PostscrIndentGet(v:lnum)
+setlocal indentkeys+=0],0=>>,0=%%,0=end,0=restore,0=grestore indentkeys-=:,0#,e
+
+" Catch multiple instantiations
+if exists("*PostscrIndentGet")
+  finish
+endif
+
+function! PostscrIndentGet(lnum)
+  " Find a non-empty non-comment line above the current line.
+  " Note: ignores DSC comments as well!
+  let lnum = a:lnum - 1
+  while lnum != 0
+    let lnum = prevnonblank(lnum)
+    if getline(lnum) !~ '^\s*%.*$'
+      break
+    endif
+    let lnum = lnum - 1
+  endwhile
+
+  " Hit the start of the file, use user indent.
+  if lnum == 0
+    return -1
+  endif
+
+  " Start with the indent of the previous line
+  let ind = indent(lnum)
+  let pline = getline(lnum)
+
+  " Indent for dicts, arrays, and saves with possible trailing comment
+  if pline =~ '\(begin\|<<\|g\=save\|{\|[\)\s*\(%.*\)\=$'
+    let ind = ind + &sw
+  endif
+
+  " Remove indent for popped dicts, and restores.
+  if pline =~ '\(end\|g\=restore\)\s*$'
+    let ind = ind - &sw
+
+  " Else handle immediate dedents of dicts, restores, and arrays.
+  elseif getline(a:lnum) =~ '\(end\|>>\|g\=restore\|}\|]\)'
+    let ind = ind - &sw
+
+  " Else handle DSC comments - always start of line.
+  elseif getline(a:lnum) =~ '^\s*%%'
+    let ind = 0
+  endif
+
+  " For now catch excessive left indents if they occur.
+  if ind < 0
+    let ind = -1
+  endif
+
+  return ind
+endfunction
+
+" vim:sw=2
--- /dev/null
+++ b/lib/vimfiles/indent/pov.vim
@@ -1,0 +1,84 @@
+" Vim indent file
+" Language: PoV-Ray Scene Description Language
+" Maintainer: David Necas (Yeti) <yeti@physics.muni.cz>
+" Last Change: 2002-10-20
+" URI: http://trific.ath.cx/Ftp/vim/indent/pov.vim
+
+" Only load this indent file when no other was loaded.
+if exists("b:did_indent")
+  finish
+endif
+let b:did_indent = 1
+
+" Some preliminary settings.
+setlocal nolisp " Make sure lisp indenting doesn't supersede us.
+
+setlocal indentexpr=GetPoVRayIndent()
+setlocal indentkeys+==else,=end,0]
+
+" Only define the function once.
+if exists("*GetPoVRayIndent")
+  finish
+endif
+
+" Counts matches of a regexp <rexp> in line number <line>.
+" Doesn't count matches inside strings and comments (as defined by current
+" syntax).
+function! s:MatchCount(line, rexp)
+  let str = getline(a:line)
+  let i = 0
+  let n = 0
+  while i >= 0
+    let i = matchend(str, a:rexp, i)
+    if i >= 0 && synIDattr(synID(a:line, i, 0), "name") !~? "string\|comment"
+      let n = n + 1
+    endif
+  endwhile
+  return n
+endfunction
+
+" The main function.  Returns indent amount.
+function GetPoVRayIndent()
+  " If we are inside a comment (may be nested in obscure ways), give up
+  if synIDattr(synID(v:lnum, indent(v:lnum)+1, 0), "name") =~? "string\|comment"
+    return -1
+  endif
+
+  " Search backwards for the frist non-empty, non-comment line.
+  let plnum = prevnonblank(v:lnum - 1)
+  let plind = indent(plnum)
+  while plnum > 0 && synIDattr(synID(plnum, plind+1, 0), "name") =~? "comment"
+    let plnum = prevnonblank(plnum - 1)
+    let plind = indent(plnum)
+  endwhile
+
+  " Start indenting from zero
+  if plnum == 0
+    return 0
+  endif
+
+  " Analyse previous nonempty line.
+  let chg = 0
+  let chg = chg + s:MatchCount(plnum, '[[{(]')
+  let chg = chg + s:MatchCount(plnum, '#\s*\%(if\|ifdef\|ifndef\|switch\|while\|macro\|else\)\>')
+  let chg = chg - s:MatchCount(plnum, '#\s*end\>')
+  let chg = chg - s:MatchCount(plnum, '[]})]')
+  " Dirty hack for people writing #if and #else on the same line.
+  let chg = chg - s:MatchCount(plnum, '#\s*\%(if\|ifdef\|ifndef\|switch\)\>.*#\s*else\>')
+  " When chg > 0, then we opened groups and we should indent more, but when
+  " chg < 0, we closed groups and this already affected the previous line,
+  " so we should not dedent.  And when everything else fails, scream.
+  let chg = chg > 0 ? chg : 0
+
+  " Analyse current line
+  " FIXME: If we have to dedent, we should try to find the indentation of the
+  " opening line.
+  let cur = s:MatchCount(v:lnum, '^\s*\%(#\s*\%(end\|else\)\>\|[]})]\)')
+  if cur > 0
+    let final = plind + (chg - cur) * &sw
+  else
+    let final = plind + chg * &sw
+  endif
+
+  return final < 0 ? 0 : final
+endfunction
--- /dev/null
+++ b/lib/vimfiles/indent/prolog.vim
@@ -1,0 +1,58 @@
+"  vim: set sw=4 sts=4:
+"  Maintainer	: Gergely Kontra <kgergely@mcl.hu>
+"  Revised on	: 2002.02.18. 23:34:05
+"  Language	: Prolog
+
+" TODO:
+"   checking with respect to syntax highlighting
+"   ignoring multiline comments
+"   detecting multiline strings
+
+" Only load this indent file when no other was loaded.
+if exists("b:did_indent")
+    finish
+endif
+
+let b:did_indent = 1
+
+setlocal indentexpr=GetPrologIndent()
+setlocal indentkeys-=:,0#
+setlocal indentkeys+=0%,-,0;,>,0)
+
+" Only define the function once.
+"if exists("*GetPrologIndent")
+"    finish
+"endif
+
+function! GetPrologIndent()
+    " Find a non-blank line above the current line.
+    let pnum = prevnonblank(v:lnum - 1)
+    " Hit the start of the file, use zero indent.
+    if pnum == 0
+       return 0
+    endif
+    let line = getline(v:lnum)
+    let pline = getline(pnum)
+
+    let ind = indent(pnum)
+    " Previous line was comment -> use previous line's indent
+    if pline =~ '^\s*%'
+	retu ind
+    endif
+    " Check for clause head on previous line
+    if pline =~ ':-\s*\(%.*\)\?$'
+	let ind = ind + &sw
+    " Check for end of clause on previous line
+    elseif pline =~ '\.\s*\(%.*\)\?$'
+	let ind = ind - &sw
+    endif
+    " Check for opening conditional on previous line
+    if pline =~ '^\s*\([(;]\|->\)'
+	let ind = ind + &sw
+    endif
+    " Check for closing an unclosed paren, or middle ; or ->
+    if line =~ '^\s*\([);]\|->\)'
+	let ind = ind - &sw
+    endif
+    return ind
+endfunction
--- /dev/null
+++ b/lib/vimfiles/indent/pyrex.vim
@@ -1,0 +1,13 @@
+" Vim indent file
+" Language:	Pyrex
+" Maintainer:	Marco Barisione <marco.bari@people.it>
+" URL:		http://marcobari.altervista.org/pyrex_vim.html
+" Last Change:	2005 Jun 24
+
+" Only load this indent file when no other was loaded.
+if exists("b:did_indent")
+  finish
+endif
+
+" Use Python formatting rules
+runtime! indent/python.vim
--- /dev/null
+++ b/lib/vimfiles/indent/python.vim
@@ -1,0 +1,193 @@
+" Vim indent file
+" Language:		Python
+" Maintainer:		Bram Moolenaar <Bram@vim.org>
+" Original Author:	David Bustos <bustos@caltech.edu>
+" Last Change:		2006 Jun 18
+
+" Only load this indent file when no other was loaded.
+if exists("b:did_indent")
+  finish
+endif
+let b:did_indent = 1
+
+" Some preliminary settings
+setlocal nolisp		" Make sure lisp indenting doesn't supersede us
+setlocal autoindent	" indentexpr isn't much help otherwise
+
+setlocal indentexpr=GetPythonIndent(v:lnum)
+setlocal indentkeys+=<:>,=elif,=except
+
+" Only define the function once.
+if exists("*GetPythonIndent")
+  finish
+endif
+
+" Come here when loading the script the first time.
+
+let s:maxoff = 50	" maximum number of lines to look backwards for ()
+
+function GetPythonIndent(lnum)
+
+  " If this line is explicitly joined: If the previous line was also joined,
+  " line it up with that one, otherwise add two 'shiftwidth'
+  if getline(a:lnum - 1) =~ '\\$'
+    if a:lnum > 1 && getline(a:lnum - 2) =~ '\\$'
+      return indent(a:lnum - 1)
+    endif
+    return indent(a:lnum - 1) + (exists("g:pyindent_continue") ? eval(g:pyindent_continue) : (&sw * 2))
+  endif
+
+  " If the start of the line is in a string don't change the indent.
+  if has('syntax_items')
+	\ && synIDattr(synID(a:lnum, 1, 1), "name") =~ "String$"
+    return -1
+  endif
+
+  " Search backwards for the previous non-empty line.
+  let plnum = prevnonblank(v:lnum - 1)
+
+  if plnum == 0
+    " This is the first non-empty line, use zero indent.
+    return 0
+  endif
+
+  " If the previous line is inside parenthesis, use the indent of the starting
+  " line.
+  " Trick: use the non-existing "dummy" variable to break out of the loop when
+  " going too far back.
+  call cursor(plnum, 1)
+  let parlnum = searchpair('(\|{\|\[', '', ')\|}\|\]', 'nbW',
+	  \ "line('.') < " . (plnum - s:maxoff) . " ? dummy :"
+	  \ . " synIDattr(synID(line('.'), col('.'), 1), 'name')"
+	  \ . " =~ '\\(Comment\\|String\\)$'")
+  if parlnum > 0
+    let plindent = indent(parlnum)
+    let plnumstart = parlnum
+  else
+    let plindent = indent(plnum)
+    let plnumstart = plnum
+  endif
+
+
+  " When inside parenthesis: If at the first line below the parenthesis add
+  " two 'shiftwidth', otherwise same as previous line.
+  " i = (a
+  "       + b
+  "       + c)
+  call cursor(a:lnum, 1)
+  let p = searchpair('(\|{\|\[', '', ')\|}\|\]', 'bW',
+	  \ "line('.') < " . (a:lnum - s:maxoff) . " ? dummy :"
+	  \ . " synIDattr(synID(line('.'), col('.'), 1), 'name')"
+	  \ . " =~ '\\(Comment\\|String\\)$'")
+  if p > 0
+    if p == plnum
+      " When the start is inside parenthesis, only indent one 'shiftwidth'.
+      let pp = searchpair('(\|{\|\[', '', ')\|}\|\]', 'bW',
+	  \ "line('.') < " . (a:lnum - s:maxoff) . " ? dummy :"
+	  \ . " synIDattr(synID(line('.'), col('.'), 1), 'name')"
+	  \ . " =~ '\\(Comment\\|String\\)$'")
+      if pp > 0
+	return indent(plnum) + (exists("g:pyindent_nested_paren") ? eval(g:pyindent_nested_paren) : &sw)
+      endif
+      return indent(plnum) + (exists("g:pyindent_open_paren") ? eval(g:pyindent_open_paren) : (&sw * 2))
+    endif
+    if plnumstart == p
+      return indent(plnum)
+    endif
+    return plindent
+  endif
+
+
+  " Get the line and remove a trailing comment.
+  " Use syntax highlighting attributes when possible.
+  let pline = getline(plnum)
+  let pline_len = strlen(pline)
+  if has('syntax_items')
+    " If the last character in the line is a comment, do a binary search for
+    " the start of the comment.  synID() is slow, a linear search would take
+    " too long on a long line.
+    if synIDattr(synID(plnum, pline_len, 1), "name") =~ "Comment$"
+      let min = 1
+      let max = pline_len
+      while min < max
+	let col = (min + max) / 2
+	if synIDattr(synID(plnum, col, 1), "name") =~ "Comment$"
+	  let max = col
+	else
+	  let min = col + 1
+	endif
+      endwhile
+      let pline = strpart(pline, 0, min - 1)
+    endif
+  else
+    let col = 0
+    while col < pline_len
+      if pline[col] == '#'
+	let pline = strpart(pline, 0, col)
+	break
+      endif
+      let col = col + 1
+    endwhile
+  endif
+
+  " If the previous line ended with a colon, indent this line
+  if pline =~ ':\s*$'
+    return plindent + &sw
+  endif
+
+  " If the previous line was a stop-execution statement...
+  if getline(plnum) =~ '^\s*\(break\|continue\|raise\|return\|pass\)\>'
+    " See if the user has already dedented
+    if indent(a:lnum) > indent(plnum) - &sw
+      " If not, recommend one dedent
+      return indent(plnum) - &sw
+    endif
+    " Otherwise, trust the user
+    return -1
+  endif
+
+  " If the current line begins with a keyword that lines up with "try"
+  if getline(a:lnum) =~ '^\s*\(except\|finally\)\>'
+    let lnum = a:lnum - 1
+    while lnum >= 1
+      if getline(lnum) =~ '^\s*\(try\|except\)\>'
+	let ind = indent(lnum)
+	if ind >= indent(a:lnum)
+	  return -1	" indent is already less than this
+	endif
+	return ind	" line up with previous try or except
+      endif
+      let lnum = lnum - 1
+    endwhile
+    return -1		" no matching "try"!
+  endif
+
+  " If the current line begins with a header keyword, dedent
+  if getline(a:lnum) =~ '^\s*\(elif\|else\)\>'
+
+    " Unless the previous line was a one-liner
+    if getline(plnumstart) =~ '^\s*\(for\|if\|try\)\>'
+      return plindent
+    endif
+
+    " Or the user has already dedented
+    if indent(a:lnum) <= plindent - &sw
+      return -1
+    endif
+
+    return plindent - &sw
+  endif
+
+  " When after a () construct we probably want to go back to the start line.
+  " a = (b
+  "       + c)
+  " here
+  if parlnum > 0
+    return plindent
+  endif
+
+  return -1
+
+endfunction
+
+" vim:sw=2
--- /dev/null
+++ b/lib/vimfiles/indent/readline.vim
@@ -1,0 +1,36 @@
+" Vim indent file
+" Language:         readline configuration file
+" Maintainer:       Nikolai Weibull <now@bitwi.se>
+" Latest Revision:  2006-12-20
+
+if exists("b:did_indent")
+  finish
+endif
+let b:did_indent = 1
+
+setlocal indentexpr=GetReadlineIndent()
+setlocal indentkeys=!^F,o,O,=$else,=$endif
+setlocal nosmartindent
+
+if exists("*GetReadlineIndent")
+  finish
+endif
+
+function GetReadlineIndent()
+  let lnum = prevnonblank(v:lnum - 1)
+  if lnum == 0
+    return 0
+  endif
+
+  let ind = indent(lnum)
+
+  if getline(lnum) =~ '^\s*$\(if\|else\)\>'
+    let ind = ind + &sw
+  endif
+
+  if getline(v:lnum) =~ '^\s*$\(else\|endif\)\>'
+    let ind = ind - &sw
+  endif
+
+  return ind
+endfunction
--- /dev/null
+++ b/lib/vimfiles/indent/rpl.vim
@@ -1,0 +1,63 @@
+" Vim indent file
+" Language:	RPL/2
+" Version:	0.2
+" Last Change:	2005 Mar 28
+" Maintainer:	BERTRAND Jo�l <rpl2@free.fr>
+
+" Only load this indent file when no other was loaded.
+if exists("b:did_indent")
+  finish
+endif
+let b:did_indent = 1
+
+setlocal autoindent
+setlocal indentkeys+==~end,=~case,=~if,=~then,=~else,=~do,=~until,=~while,=~repeat,=~select,=~default,=~for,=~start,=~next,=~step,<<>,<>>
+
+" Define the appropriate indent function but only once
+setlocal indentexpr=RplGetFreeIndent()
+if exists("*RplGetFreeIndent")
+  finish
+endif
+
+let b:undo_indent = "set ai< indentkeys< indentexpr<"
+
+function RplGetIndent(lnum)
+  let ind = indent(a:lnum)
+  let prevline=getline(a:lnum)
+  " Strip tail comment
+  let prevstat=substitute(prevline, '!.*$', '', '')
+
+  " Add a shiftwidth to statements following if, iferr, then, else, elseif,
+  " case, select, default, do, until, while, repeat, for, start
+  if prevstat =~? '\<\(if\|iferr\|do\|while\)\>' && prevstat =~? '\<end\>'
+  elseif prevstat =~? '\(^\|\s\+\)<<\($\|\s\+\)' && prevstat =~? '\s\+>>\($\|\s\+\)'
+  elseif prevstat =~? '\<\(if\|iferr\|then\|else\|elseif\|select\|case\|do\|until\|while\|repeat\|for\|start\|default\)\>' || prevstat =~? '\(^\|\s\+\)<<\($\|\s\+\)'
+    let ind = ind + &sw
+  endif
+
+  " Subtract a shiftwidth from then, else, elseif, end, until, repeat, next,
+  " step
+  let line = getline(v:lnum)
+  if line =~? '^\s*\(then\|else\|elseif\|until\|repeat\|next\|step\|default\|end\)\>'
+    let ind = ind - &sw
+  elseif line =~? '^\s*>>\($\|\s\+\)'
+    let ind = ind - &sw
+  endif
+
+  return ind
+endfunction
+
+function RplGetFreeIndent()
+  " Find the previous non-blank line
+  let lnum = prevnonblank(v:lnum - 1)
+
+  " Use zero indent at the top of the file
+  if lnum == 0
+    return 0
+  endif
+
+  let ind=RplGetIndent(lnum)
+  return ind
+endfunction
+
+" vim:sw=2 tw=130
--- /dev/null
+++ b/lib/vimfiles/indent/rst.vim
@@ -1,0 +1,53 @@
+" Vim indent file
+" Language:         reStructuredText Documentation Format
+" Maintainer:       Nikolai Weibull <now@bitwi.se>
+" Latest Revision:  2006-12-20
+
+if exists("b:did_indent")
+  finish
+endif
+let b:did_indent = 1
+
+setlocal indentexpr=GetRSTIndent()
+setlocal indentkeys=!^F,o,O
+setlocal nosmartindent
+
+if exists("*GetRSTIndent")
+  finish
+endif
+
+function GetRSTIndent()
+  let lnum = prevnonblank(v:lnum - 1)
+  if lnum == 0
+    return 0
+  endif
+
+  let ind = indent(lnum)
+  let line = getline(lnum)
+
+  if line =~ '^\s*[-*+]\s'
+    let ind = ind + 2
+  elseif line =~ '^\s*\d\+.\s'
+    let ind = ind + matchend(substitute(line, '^\s*', '', ''), '\d\+.\s\+')
+  endif
+
+  let line = getline(v:lnum - 1)
+
+  if line =~ '^\s*$'
+    execute lnum
+    call search('^\s*\%([-*+]\s\|\d\+.\s\|\.\.\|$\)', 'bW')
+    let line = getline('.')
+    if line =~ '^\s*[-*+]'
+      let ind = ind - 2
+    elseif line =~ '^\s*\d\+\.\s'
+      let ind = ind - matchend(substitute(line, '^\s*', '', ''),
+            \ '\d\+\.\s\+')
+    elseif line =~ '^\s*\.\.'
+      let ind = ind - 3
+    else
+      let ind = ind
+    endif
+  endif
+
+  return ind
+endfunction
--- /dev/null
+++ b/lib/vimfiles/indent/ruby.vim
@@ -1,0 +1,373 @@
+" Vim indent file
+" Language:		Ruby
+" Maintainer:		Nikolai Weibull <now at bitwi.se>
+" Info:			$Id: ruby.vim,v 1.40 2007/03/20 13:54:25 dkearns Exp $
+" URL:			http://vim-ruby.rubyforge.org
+" Anon CVS:		See above site
+" Release Coordinator:	Doug Kearns <dougkearns@gmail.com>
+
+" 0. Initialization {{{1
+" =================
+
+" Only load this indent file when no other was loaded.
+if exists("b:did_indent")
+  finish
+endif
+let b:did_indent = 1
+
+setlocal nosmartindent
+
+" Now, set up our indentation expression and keys that trigger it.
+setlocal indentexpr=GetRubyIndent()
+setlocal indentkeys=0{,0},0),0],!^F,o,O,e
+setlocal indentkeys+==end,=elsif,=when,=ensure,=rescue,==begin,==end
+
+" Only define the function once.
+if exists("*GetRubyIndent")
+  finish
+endif
+
+let s:cpo_save = &cpo
+set cpo&vim
+
+" 1. Variables {{{1
+" ============
+
+" Regex of syntax group names that are or delimit string or are comments.
+let s:syng_strcom = '\<ruby\%(String\|StringDelimiter\|ASCIICode' .
+      \ '\|Interpolation\|NoInterpolation\|Escape\|Comment\|Documentation\)\>'
+
+" Regex of syntax group names that are strings.
+let s:syng_string =
+      \ '\<ruby\%(String\|StringDelimiter\|Interpolation\|NoInterpolation\|Escape\)\>'
+
+" Regex of syntax group names that are strings or documentation.
+let s:syng_stringdoc =
+  \'\<ruby\%(String\|StringDelimiter\|Interpolation\|NoInterpolation\|Escape\|Documentation\)\>'
+
+" Expression used to check whether we should skip a match with searchpair().
+let s:skip_expr =
+      \ "synIDattr(synID(line('.'),col('.'),0),'name') =~ '".s:syng_strcom."'"
+
+" Regex used for words that, at the start of a line, add a level of indent.
+let s:ruby_indent_keywords = '^\s*\zs\<\%(module\|class\|def\|if\|for' .
+      \ '\|while\|until\|else\|elsif\|case\|when\|unless\|begin\|ensure' .
+      \ '\|rescue\)\>' .
+      \ '\|\%([*+/,=:-]\|<<\|>>\)\s*\zs' .
+      \    '\<\%(if\|for\|while\|until\|case\|unless\|begin\)\>'
+
+" Regex used for words that, at the start of a line, remove a level of indent.
+let s:ruby_deindent_keywords =
+      \ '^\s*\zs\<\%(ensure\|else\|rescue\|elsif\|when\|end\)\>'
+
+" Regex that defines the start-match for the 'end' keyword.
+"let s:end_start_regex = '\%(^\|[^.]\)\<\%(module\|class\|def\|if\|for\|while\|until\|case\|unless\|begin\|do\)\>'
+" TODO: the do here should be restricted somewhat (only at end of line)?
+let s:end_start_regex = '^\s*\zs\<\%(module\|class\|def\|if\|for' .
+      \ '\|while\|until\|case\|unless\|begin\)\>' .
+      \ '\|\%([*+/,=:-]\|<<\|>>\)\s*\zs' .
+      \    '\<\%(if\|for\|while\|until\|case\|unless\|begin\)\>' .
+      \ '\|\<do\>'
+
+" Regex that defines the middle-match for the 'end' keyword.
+let s:end_middle_regex = '\<\%(ensure\|else\|\%(\%(^\|;\)\s*\)\@<=\<rescue\>\|when\|elsif\)\>'
+
+" Regex that defines the end-match for the 'end' keyword.
+let s:end_end_regex = '\%(^\|[^.:@$]\)\@<=\<end\>'
+
+" Expression used for searchpair() call for finding match for 'end' keyword.
+let s:end_skip_expr = s:skip_expr .
+      \ ' || (expand("<cword>") == "do"' .
+      \ ' && getline(".") =~ "^\\s*\\<while\\|until\\|for\\>")'
+
+" Regex that defines continuation lines, not including (, {, or [.
+let s:continuation_regex = '\%([\\*+/.,=:-]\|\W[|&?]\|||\|&&\)\s*\%(#.*\)\=$'
+
+" Regex that defines continuation lines.
+" TODO: this needs to deal with if ...: and so on
+let s:continuation_regex2 =
+      \ '\%([\\*+/.,=:({[-]\|\W[|&?]\|||\|&&\)\s*\%(#.*\)\=$'
+
+" Regex that defines blocks.
+let s:block_regex =
+      \ '\%(\<do\>\|{\)\s*\%(|\%([*@]\=\h\w*,\=\s*\)\%(,\s*[*@]\=\h\w*\)*|\)\=\s*\%(#.*\)\=$'
+
+" 2. Auxiliary Functions {{{1
+" ======================
+
+" Check if the character at lnum:col is inside a string, comment, or is ascii.
+function s:IsInStringOrComment(lnum, col)
+  return synIDattr(synID(a:lnum, a:col, 0), 'name') =~ s:syng_strcom
+endfunction
+
+" Check if the character at lnum:col is inside a string.
+function s:IsInString(lnum, col)
+  return synIDattr(synID(a:lnum, a:col, 0), 'name') =~ s:syng_string
+endfunction
+
+" Check if the character at lnum:col is inside a string or documentation.
+function s:IsInStringOrDocumentation(lnum, col)
+  return synIDattr(synID(a:lnum, a:col, 0), 'name') =~ s:syng_stringdoc
+endfunction
+
+" Find line above 'lnum' that isn't empty, in a comment, or in a string.
+function s:PrevNonBlankNonString(lnum)
+  let in_block = 0
+  let lnum = prevnonblank(a:lnum)
+  while lnum > 0
+    " Go in and out of blocks comments as necessary.
+    " If the line isn't empty (with opt. comment) or in a string, end search.
+    let line = getline(lnum)
+    if line =~ '^=begin$'
+      if in_block
+	let in_block = 0
+      else
+	break
+      endif
+    elseif !in_block && line =~ '^=end$'
+      let in_block = 1
+    elseif !in_block && line !~ '^\s*#.*$' && !(s:IsInStringOrComment(lnum, 1)
+	  \ && s:IsInStringOrComment(lnum, strlen(line)))
+      break
+    endif
+    let lnum = prevnonblank(lnum - 1)
+  endwhile
+  return lnum
+endfunction
+
+" Find line above 'lnum' that started the continuation 'lnum' may be part of.
+function s:GetMSL(lnum)
+  " Start on the line we're at and use its indent.
+  let msl = a:lnum
+  let lnum = s:PrevNonBlankNonString(a:lnum - 1)
+  while lnum > 0
+    " If we have a continuation line, or we're in a string, use line as MSL.
+    " Otherwise, terminate search as we have found our MSL already.
+    let line = getline(lnum)
+    let col = match(line, s:continuation_regex2) + 1
+    if (col > 0 && !s:IsInStringOrComment(lnum, col))
+	  \ || s:IsInString(lnum, strlen(line))
+      let msl = lnum
+    else
+      break
+    endif
+    let lnum = s:PrevNonBlankNonString(lnum - 1)
+  endwhile
+  return msl
+endfunction
+
+" Check if line 'lnum' has more opening brackets than closing ones.
+function s:LineHasOpeningBrackets(lnum)
+  let open_0 = 0
+  let open_2 = 0
+  let open_4 = 0
+  let line = getline(a:lnum)
+  let pos = match(line, '[][(){}]', 0)
+  while pos != -1
+    if !s:IsInStringOrComment(a:lnum, pos + 1)
+      let idx = stridx('(){}[]', line[pos])
+      if idx % 2 == 0
+	let open_{idx} = open_{idx} + 1
+      else
+	let open_{idx - 1} = open_{idx - 1} - 1
+      endif
+    endif
+    let pos = match(line, '[][(){}]', pos + 1)
+  endwhile
+  return (open_0 > 0) . (open_2 > 0) . (open_4 > 0)
+endfunction
+
+function s:Match(lnum, regex)
+  let col = match(getline(a:lnum), a:regex) + 1
+  return col > 0 && !s:IsInStringOrComment(a:lnum, col) ? col : 0
+endfunction
+
+function s:MatchLast(lnum, regex)
+  let line = getline(a:lnum)
+  let col = match(line, '.*\zs' . a:regex)
+  while col != -1 && s:IsInStringOrComment(a:lnum, col)
+    let line = strpart(line, 0, col)
+    let col = match(line, '.*' . a:regex)
+  endwhile
+  return col + 1
+endfunction
+
+" 3. GetRubyIndent Function {{{1
+" =========================
+
+function GetRubyIndent()
+  " 3.1. Setup {{{2
+  " ----------
+
+  " Set up variables for restoring position in file.  Could use v:lnum here.
+  let vcol = col('.')
+
+  " 3.2. Work on the current line {{{2
+  " -----------------------------
+
+  " Get the current line.
+  let line = getline(v:lnum)
+  let ind = -1
+
+  " If we got a closing bracket on an empty line, find its match and indent
+  " according to it.  For parentheses we indent to its column - 1, for the
+  " others we indent to the containing line's MSL's level.  Return -1 if fail.
+  let col = matchend(line, '^\s*[]})]')
+  if col > 0 && !s:IsInStringOrComment(v:lnum, col)
+    call cursor(v:lnum, col)
+    let bs = strpart('(){}[]', stridx(')}]', line[col - 1]) * 2, 2)
+    if searchpair(escape(bs[0], '\['), '', bs[1], 'bW', s:skip_expr) > 0
+      if line[col-1]==')' && col('.') != col('$') - 1
+	let ind = virtcol('.')-1
+      else
+	let ind = indent(s:GetMSL(line('.')))
+      endif
+    endif
+    return ind
+  endif
+
+  " If we have a =begin or =end set indent to first column.
+  if match(line, '^\s*\%(=begin\|=end\)$') != -1
+    return 0
+  endif
+
+  " If we have a deindenting keyword, find its match and indent to its level.
+  " TODO: this is messy
+  if s:Match(v:lnum, s:ruby_deindent_keywords)
+    call cursor(v:lnum, 1)
+    if searchpair(s:end_start_regex, s:end_middle_regex, s:end_end_regex, 'bW',
+	    \ s:end_skip_expr) > 0
+      let line = getline('.')
+      if strpart(line, 0, col('.') - 1) =~ '=\s*$' &&
+       \ strpart(line, col('.') - 1, 2) !~ 'do'
+	let ind = virtcol('.') - 1
+      else
+	let ind = indent('.')
+      endif
+    endif
+    return ind
+  endif
+
+  " If we are in a multi-line string or line-comment, don't do anything to it.
+  if s:IsInStringOrDocumentation(v:lnum, matchend(line, '^\s*') + 1)
+    return indent('.')
+  endif
+
+  " 3.3. Work on the previous line. {{{2
+  " -------------------------------
+
+  " Find a non-blank, non-multi-line string line above the current line.
+  let lnum = s:PrevNonBlankNonString(v:lnum - 1)
+
+  " At the start of the file use zero indent.
+  if lnum == 0
+    return 0
+  endif
+
+  " Set up variables for current line.
+  let line = getline(lnum)
+  let ind = indent(lnum)
+
+  " If the previous line ended with a block opening, add a level of indent.
+  if s:Match(lnum, s:block_regex)
+    return indent(s:GetMSL(lnum)) + &sw
+  endif
+
+  " If the previous line contained an opening bracket, and we are still in it,
+  " add indent depending on the bracket type.
+  if line =~ '[[({]'
+    let counts = s:LineHasOpeningBrackets(lnum)
+    if counts[0] == '1' && searchpair('(', '', ')', 'bW', s:skip_expr) > 0
+      if col('.') + 1 == col('$')
+	return ind + &sw
+      else
+	return virtcol('.')
+      endif
+    elseif counts[1] == '1' || counts[2] == '1'
+      return ind + &sw
+    else
+      call cursor(v:lnum, vcol)
+    end
+  endif
+
+  " If the previous line ended with an "end", match that "end"s beginning's
+  " indent.
+  let col = s:Match(lnum, '\%(^\|[^.:@$]\)\<end\>\s*\%(#.*\)\=$')
+  if col > 0
+    call cursor(lnum, col)
+    if searchpair(s:end_start_regex, '', s:end_end_regex, 'bW',
+		\ s:end_skip_expr) > 0
+      let n = line('.')
+      let ind = indent('.')
+      let msl = s:GetMSL(n)
+      if msl != n
+	let ind = indent(msl)
+      end
+      return ind
+    endif
+  end
+
+  let col = s:Match(lnum, s:ruby_indent_keywords)
+  if col > 0
+    call cursor(lnum, col)
+    let ind = virtcol('.') - 1 + &sw
+"    let ind = indent(lnum) + &sw
+    " TODO: make this better (we need to count them) (or, if a searchpair
+    " fails, we know that something is lacking an end and thus we indent a
+    " level
+    if s:Match(lnum, s:end_end_regex)
+      let ind = indent('.')
+    endif
+    return ind
+  endif
+
+  " 3.4. Work on the MSL line. {{{2
+  " --------------------------
+
+  " Set up variables to use and search for MSL to the previous line.
+  let p_lnum = lnum
+  let lnum = s:GetMSL(lnum)
+
+  " If the previous line wasn't a MSL and is continuation return its indent.
+  " TODO: the || s:IsInString() thing worries me a bit.
+  if p_lnum != lnum
+    if s:Match(p_lnum,s:continuation_regex)||s:IsInString(p_lnum,strlen(line))
+      return ind
+    endif
+  endif
+
+  " Set up more variables, now that we know we wasn't continuation bound.
+  let line = getline(lnum)
+  let msl_ind = indent(lnum)
+
+  " If the MSL line had an indenting keyword in it, add a level of indent.
+  " TODO: this does not take into account contrived things such as
+  " module Foo; class Bar; end
+  if s:Match(lnum, s:ruby_indent_keywords)
+    let ind = msl_ind + &sw
+    if s:Match(lnum, s:end_end_regex)
+      let ind = ind - &sw
+    endif
+    return ind
+  endif
+
+  " If the previous line ended with [*+/.-=], indent one extra level.
+  if s:Match(lnum, s:continuation_regex)
+    if lnum == p_lnum
+      let ind = msl_ind + &sw
+    else
+      let ind = msl_ind
+    endif
+  endif
+
+  " }}}2
+
+  return ind
+endfunction
+
+" }}}1
+
+let &cpo = s:cpo_save
+unlet s:cpo_save
+
+" vim:set sw=2 sts=2 ts=8 noet ff=unix:
--- /dev/null
+++ b/lib/vimfiles/indent/scheme.vim
@@ -1,0 +1,11 @@
+" Vim indent file
+" Language:	Scheme
+" Maintainer:	Sergey Khorev <sergey.khorev@gmail.com>
+" Last Change:	2005 Jun 24
+
+" Only load this indent file when no other was loaded.
+if exists("b:did_indent")
+  finish
+endif
+
+runtime! indent/lisp.vim
--- /dev/null
+++ b/lib/vimfiles/indent/sdl.vim
@@ -1,0 +1,89 @@
+" Vim indent file
+" Language:	SDL
+" Maintainer:	Michael Piefel <piefel@informatik.hu-berlin.de>
+" Last Change:	2001 Sep 17
+
+" Shamelessly stolen from the Vim-Script indent file
+
+" Only load this indent file when no other was loaded.
+if exists("b:did_indent")
+  finish
+endif
+let b:did_indent = 1
+
+setlocal indentexpr=GetSDLIndent()
+setlocal indentkeys+==~end,=~state,*<Return>
+
+" Only define the function once.
+if exists("*GetSDLIndent")
+"  finish
+endif
+
+set cpo-=C
+
+function! GetSDLIndent()
+  " Find a non-blank line above the current line.
+  let lnum = prevnonblank(v:lnum - 1)
+
+  " At the start of the file use zero indent.
+  if lnum == 0
+    return 0
+  endif
+
+  let ind = indent(lnum)
+  let virtuality = '^\s*\(\(virtual\|redefined\|finalized\)\s\+\)\=\s*'
+
+  " Add a single space to comments which use asterisks
+  if getline(lnum) =~ '^\s*\*'
+    let ind = ind - 1
+  endif
+  if getline(v:lnum) =~ '^\s*\*'
+    let ind = ind + 1
+  endif
+
+  " Add a 'shiftwidth' after states, different blocks, decision (and alternatives), inputs
+  if (getline(lnum) =~? '^\s*\(start\|state\|system\|package\|connection\|channel\|alternative\|macro\|operator\|newtype\|select\|substructure\|decision\|generator\|refinement\|service\|method\|exceptionhandler\|asntype\|syntype\|value\|(.*):\|\(priority\s\+\)\=input\|provided\)'
+    \ || getline(lnum) =~? virtuality . '\(process\|procedure\|block\|object\)')
+    \ && getline(lnum) !~? 'end[[:alpha:]]\+;$'
+    let ind = ind + &sw
+  endif
+
+  " Subtract a 'shiftwidth' after states
+  if getline(lnum) =~? '^\s*\(stop\|return\>\|nextstate\)'
+    let ind = ind - &sw
+  endif
+
+  " Subtract a 'shiftwidth' on on end (uncompleted line)
+  if getline(v:lnum) =~? '^\s*end\>'
+    let ind = ind - &sw
+  endif
+
+  " Put each alternatives where the corresponding decision was
+  if getline(v:lnum) =~? '^\s*\((.*)\|else\):'
+    normal k
+    let ind = indent(searchpair('^\s*decision', '', '^\s*enddecision', 'bW',
+      \ 'synIDattr(synID(line("."), col("."), 0), "name") =~? "sdlString"'))
+  endif
+
+  " Put each state where the preceding state was
+  if getline(v:lnum) =~? '^\s*state\>'
+    let ind = indent(search('^\s*start', 'bW'))
+  endif
+
+  " Systems and packages are always in column 0
+  if getline(v:lnum) =~? '^\s*\(\(end\)\=system\|\(end\)\=package\)'
+    return 0;
+  endif
+
+  " Put each end* where the corresponding begin was
+  if getline(v:lnum) =~? '^\s*end[[:alpha:]]'
+    normal k
+    let partner=matchstr(getline(v:lnum), '\(' . virtuality . 'end\)\@<=[[:alpha:]]\+')
+    let ind = indent(searchpair(virtuality . partner, '', '^\s*end' . partner, 'bW',
+      \ 'synIDattr(synID(line("."), col("."), 0), "name") =~? "sdlString"'))
+  endif
+
+  return ind
+endfunction
+
+" vim:sw=2
--- /dev/null
+++ b/lib/vimfiles/indent/sh.vim
@@ -1,0 +1,52 @@
+" Vim indent file
+" Language:	    Shell Script
+" Maintainer:       Nikolai Weibull <now@bitwi.se>
+" Latest Revision:  2006-04-19
+
+if exists("b:did_indent")
+  finish
+endif
+let b:did_indent = 1
+
+setlocal indentexpr=GetShIndent()
+setlocal indentkeys+==then,=do,=else,=elif,=esac,=fi,=fin,=fil,=done
+setlocal indentkeys-=:,0#
+
+if exists("*GetShIndent")
+  finish
+endif
+
+let s:cpo_save = &cpo
+set cpo&vim
+
+function GetShIndent()
+  let lnum = prevnonblank(v:lnum - 1)
+  if lnum == 0
+    return 0
+  endif
+
+  " Add a 'shiftwidth' after if, while, else, case, until, for, function()
+  " Skip if the line also contains the closure for the above
+  let ind = indent(lnum)
+  let line = getline(lnum)
+  if line =~ '^\s*\(if\|then\|do\|else\|elif\|case\|while\|until\|for\)\>'
+	\ || line =~ '^\s*\<\k\+\>\s*()\s*{'
+	\ || line =~ '^\s*{'
+    if line !~ '\(esac\|fi\|done\)\>\s*$' && line !~ '}\s*$'
+      let ind = ind + &sw
+    endif
+  endif
+
+  " Subtract a 'shiftwidth' on a then, do, else, esac, fi, done
+  " Retain the indentation level if line matches fin (for find)
+  let line = getline(v:lnum)
+  if (line =~ '^\s*\(then\|do\|else\|elif\|esac\|fi\|done\)\>' || line =~ '^\s*}')
+	\ && line !~ '^\s*fi[ln]\>'
+    let ind = ind - &sw
+  endif
+
+  return ind
+endfunction
+
+let &cpo = s:cpo_save
+unlet s:cpo_save
--- /dev/null
+++ b/lib/vimfiles/indent/sml.vim
@@ -1,0 +1,217 @@
+" Vim indent file
+" Language:     SML
+" Maintainer:	Saikat Guha <sg266@cornell.edu>
+" 				Hubert Chao <hc85@cornell.edu>
+" Original OCaml Version:
+" 				Jean-Francois Yuen  <jfyuen@ifrance.com>
+"               Mike Leary          <leary@nwlink.com>
+"               Markus Mottl        <markus@oefai.at>
+" OCaml URL:    http://www.oefai.at/~markus/vim/indent/ocaml.vim
+" Last Change:  2003 Jan 04	- Adapted to SML
+" 				2002 Nov 06 - Some fixes (JY)
+"               2002 Oct 28 - Fixed bug with indentation of ']' (MM)
+"               2002 Oct 22 - Major rewrite (JY)
+
+" Only load this indent file when no other was loaded.
+if exists("b:did_indent")
+  finish
+endif
+let b:did_indent = 1
+
+setlocal expandtab
+setlocal indentexpr=GetSMLIndent()
+setlocal indentkeys+=0=and,0=else,0=end,0=handle,0=if,0=in,0=let,0=then,0=val,0=fun,0=\|,0=*),0)
+setlocal nolisp
+setlocal nosmartindent
+setlocal textwidth=80
+setlocal shiftwidth=2
+
+" Comment formatting
+if (has("comments"))
+  set comments=sr:(*,mb:*,ex:*)
+  set fo=cqort
+endif
+
+" Only define the function once.
+"if exists("*GetSMLIndent")
+"finish
+"endif
+
+" Define some patterns:
+let s:beflet = '^\s*\(initializer\|method\|try\)\|\(\<\(begin\|do\|else\|in\|then\|try\)\|->\|;\)\s*$'
+let s:letpat = '^\s*\(let\|type\|module\|class\|open\|exception\|val\|include\|external\)\>'
+let s:letlim = '\(\<\(sig\|struct\)\|;;\)\s*$'
+let s:lim = '^\s*\(exception\|external\|include\|let\|module\|open\|type\|val\)\>'
+let s:module = '\<\%(let\|sig\|struct\)\>'
+let s:obj = '^\s*\(constraint\|inherit\|initializer\|method\|val\)\>\|\<\(object\|object\s*(.*)\)\s*$'
+let s:type = '^\s*\%(let\|type\)\>.*='
+let s:val = '^\s*\(val\|external\)\>.*:'
+
+" Skipping pattern, for comments
+function! s:SkipPattern(lnum, pat)
+  let def = prevnonblank(a:lnum - 1)
+  while def > 0 && getline(def) =~ a:pat
+    let def = prevnonblank(def - 1)
+  endwhile
+  return def
+endfunction
+
+" Indent for ';;' to match multiple 'let'
+function! s:GetInd(lnum, pat, lim)
+  let llet = search(a:pat, 'bW')
+  let old = indent(a:lnum)
+  while llet > 0
+    let old = indent(llet)
+    let nb = s:SkipPattern(llet, '^\s*(\*.*\*)\s*$')
+    if getline(nb) =~ a:lim
+      return old
+    endif
+    let llet = search(a:pat, 'bW')
+  endwhile
+  return old
+endfunction
+
+" Indent pairs
+function! s:FindPair(pstart, pmid, pend)
+  call search(a:pend, 'bW')
+"  return indent(searchpair(a:pstart, a:pmid, a:pend, 'bWn', 'synIDattr(synID(line("."), col("."), 0), "name") =~? "string\\|comment"'))
+  let lno = searchpair(a:pstart, a:pmid, a:pend, 'bW', 'synIDattr(synID(line("."), col("."), 0), "name") =~? "string\\|comment"')
+  if lno == -1
+	return indent(lno)
+  else
+	return col(".") - 1
+  endif
+endfunction
+
+function! s:FindLet(pstart, pmid, pend)
+  call search(a:pend, 'bW')
+"  return indent(searchpair(a:pstart, a:pmid, a:pend, 'bWn', 'synIDattr(synID(line("."), col("."), 0), "name") =~? "string\\|comment"'))
+  let lno = searchpair(a:pstart, a:pmid, a:pend, 'bW', 'synIDattr(synID(line("."), col("."), 0), "name") =~? "string\\|comment"')
+  let moduleLine = getline(lno)
+  if lno == -1 || moduleLine =~ '^\s*\(fun\|structure\|signature\)\>'
+	return indent(lno)
+  else
+	return col(".") - 1
+  endif
+endfunction
+
+" Indent 'let'
+"function! s:FindLet(pstart, pmid, pend)
+"  call search(a:pend, 'bW')
+"  return indent(searchpair(a:pstart, a:pmid, a:pend, 'bWn', 'synIDattr(synID(line("."), col("."), 0), "name") =~? "string\\|comment" || getline(".") =~ "^\\s*let\\>.*=.*\\<in\\s*$" || getline(prevnonblank(".") - 1) =~ "^\\s*let\\>.*=\\s*$\\|" . s:beflet'))
+"endfunction
+
+function! GetSMLIndent()
+  " Find a non-blank line above the current line.
+  let lnum = prevnonblank(v:lnum - 1)
+
+  " At the start of the file use zero indent.
+  if lnum == 0
+    return 0
+  endif
+
+  let ind = indent(lnum)
+  let lline = getline(lnum)
+
+	" Return double 'shiftwidth' after lines matching:
+	if lline =~ '^\s*|.*=>\s*$'
+		return ind + &sw + &sw
+	elseif lline =~ '^\s*val\>.*=\s*$'
+		return ind + &sw
+	endif
+
+  let line = getline(v:lnum)
+
+	" Indent lines starting with 'end' to matching module
+	if line =~ '^\s*end\>'
+		return s:FindLet(s:module, '', '\<end\>')
+
+	" Match 'else' with 'if'
+	elseif line =~ '^\s*else\>'
+	  	if lline !~ '^\s*\(if\|else\|then\)\>'
+				return s:FindPair('\<if\>', '', '\<then\>')
+	  	else
+		  return ind
+		endif
+
+	" Match 'then' with 'if'
+	elseif line =~ '^\s*then\>'
+  	if lline !~ '^\s*\(if\|else\|then\)\>'
+		  return s:FindPair('\<if\>', '', '\<then\>')
+	else
+	  return ind
+	endif
+
+	" Indent if current line begins with ']'
+	elseif line =~ '^\s*\]'
+		return s:FindPair('\[','','\]')
+
+  " Indent current line starting with 'in' to last matching 'let'
+	elseif line =~ '^\s*in\>'
+		let ind = s:FindLet('\<let\>','','\<in\>')
+
+	" Indent from last matching module if line matches:
+	elseif line =~ '^\s*\(fun\|val\|open\|structure\|and\|datatype\|type\|exception\)\>'
+		cursor(lnum,1)
+  		let lastModule = indent(searchpair(s:module, '', '\<end\>', 'bWn', 'synIDattr(synID(line("."), col("."), 0), "name") =~? "string\\|comment"'))
+		if lastModule == -1
+			return 0
+		else
+			return lastModule + &sw
+		endif
+
+	" Indent lines starting with '|' from matching 'case', 'handle'
+	elseif line =~ '^\s*|'
+		" cursor(lnum,1)
+		let lastSwitch = search('\<\(case\|handle\|fun\|datatype\)\>','bW')
+		let switchLine = getline(lastSwitch)
+		let switchLineIndent = indent(lastSwitch)
+		if lline =~ '^\s*|'
+		  return ind
+		endif
+		if switchLine =~ '\<case\>'
+			return col(".") + 2
+		elseif switchLine =~ '\<handle\>'
+			return switchLineIndent + &sw
+		elseif switchLine =~ '\<datatype\>'
+			call search('=')
+			return col(".") - 1
+		else
+			return switchLineIndent + 2
+		endif
+
+
+  " Indent if last line ends with 'sig', 'struct', 'let', 'then', 'else',
+  " 'in'
+  elseif lline =~ '\<\(sig\|struct\|let\|in\|then\|else\)\s*$'
+		let ind = ind + &sw
+
+  " Indent if last line ends with 'of', align from 'case'
+  elseif lline =~ '\<\(of\)\s*$'
+		call search('\<case\>',"bW")
+		let ind = col(".")+4
+
+	" Indent if current line starts with 'of'
+  elseif line =~ '^\s*of\>'
+		call search('\<case\>',"bW")
+		let ind = col(".")+1
+
+
+	" Indent if last line starts with 'fun', 'case', 'fn'
+	elseif lline =~ '^\s*\(fun\|fn\|case\)\>'
+		let ind = ind + &sw
+
+	endif
+
+	" Don't indent 'let' if last line started with 'fun', 'fn'
+	if line =~ '^\s*let\>'
+		if lline =~ '^\s*\(fun\|fn\)'
+			let ind = ind - &sw
+		endif
+  endif
+
+  return ind
+
+endfunction
+
+" vim:sw=2
--- /dev/null
+++ b/lib/vimfiles/indent/sql.vim
@@ -1,0 +1,39 @@
+" Vim indent file loader
+" Language:    SQL
+" Maintainer:  David Fishburn <fishburn at ianywhere dot com>
+" Last Change: Thu Sep 15 2005 10:27:51 AM
+" Version:     1.0
+" Download:    http://vim.sourceforge.net/script.php?script_id=495
+
+" Description: Checks for a:
+"                  buffer local variable,
+"                  global variable,
+"              If the above exist, it will source the type specified.
+"              If none exist, it will source the default sqlanywhere.vim file.
+
+
+" Only load this indent file when no other was loaded.
+if exists("b:did_indent")
+    finish
+endif
+
+" Default to the standard Vim distribution file
+let filename = 'sqlanywhere'
+
+" Check for overrides.  Buffer variables have the highest priority.
+if exists("b:sql_type_override")
+    " Check the runtimepath to see if the file exists
+    if globpath(&runtimepath, 'indent/'.b:sql_type_override.'.vim') != ''
+        let filename = b:sql_type_override
+    endif
+elseif exists("g:sql_type_default")
+    if globpath(&runtimepath, 'indent/'.g:sql_type_default.'.vim') != ''
+        let filename = g:sql_type_default
+    endif
+endif
+
+" Source the appropriate file
+exec 'runtime indent/'.filename.'.vim'
+
+
+" vim:sw=4:ff=unix:
--- /dev/null
+++ b/lib/vimfiles/indent/sqlanywhere.vim
@@ -1,0 +1,384 @@
+" Vim indent file
+" Language:    SQL
+" Maintainer:  David Fishburn <fishburn at ianywhere dot com>
+" Last Change: Wed Sep 14 2005 10:21:15 PM
+" Version:     1.4
+" Download:    http://vim.sourceforge.net/script.php?script_id=495
+
+" Notes:
+"    Indenting keywords are based on Oracle and Sybase Adaptive Server
+"    Anywhere (ASA).  Test indenting was done with ASA stored procedures and
+"    fuctions and Oracle packages which contain stored procedures and
+"    functions.
+"    This has not been tested against Microsoft SQL Server or
+"    Sybase Adaptive Server Enterprise (ASE) which use the Transact-SQL
+"    syntax.  That syntax does not have end tags for IF's, which makes
+"    indenting more difficult.
+"
+" Known Issues:
+"    The Oracle MERGE statement does not have an end tag associated with
+"    it, this can leave the indent hanging to the right one too many.
+
+" Only load this indent file when no other was loaded.
+if exists("b:did_indent")
+    finish
+endif
+let b:did_indent     = 1
+let b:current_indent = "sqlanywhere"
+
+setlocal indentkeys-=0{
+setlocal indentkeys-=0}
+setlocal indentkeys-=:
+setlocal indentkeys-=0#
+setlocal indentkeys-=e
+
+" This indicates formatting should take place when one of these
+" expressions is used.  These expressions would normally be something
+" you would type at the BEGINNING of a line
+" SQL is generally case insensitive, so this files assumes that
+" These keywords are something that would trigger an indent LEFT, not
+" an indent right, since the SQLBlockStart is used for those keywords
+setlocal indentkeys+==~end,=~else,=~elseif,=~elsif,0=~when,0=)
+
+" GetSQLIndent is executed whenever one of the expressions
+" in the indentkeys is typed
+setlocal indentexpr=GetSQLIndent()
+
+" Only define the functions once.
+if exists("*GetSQLIndent")
+    finish
+endif
+
+" List of all the statements that start a new block.
+" These are typically words that start a line.
+" IS is excluded, since it is difficult to determine when the
+" ending block is (especially for procedures/functions).
+let s:SQLBlockStart = '^\s*\%('.
+            \ 'if\|else\|elseif\|elsif\|'.
+                \ 'while\|loop\|do\|'.
+                \ 'begin\|'.
+                \ 'case\|when\|merge\|exception'.
+                \ '\)\>'
+let s:SQLBlockEnd = '^\s*\(end\)\>'
+
+" The indent level is also based on unmatched paranethesis
+" If a line has an extra "(" increase the indent
+" If a line has an extra ")" decrease the indent
+function s:CountUnbalancedParan( line, paran_to_check )
+    let l = a:line
+    let lp = substitute(l, '[^(]', '', 'g')
+    let l = a:line
+    let rp = substitute(l, '[^)]', '', 'g')
+
+    if a:paran_to_check =~ ')'
+        " echom 'CountUnbalancedParan ) returning: ' .
+        " \ (strlen(rp) - strlen(lp))
+        return (strlen(rp) - strlen(lp))
+    elseif a:paran_to_check =~ '('
+        " echom 'CountUnbalancedParan ( returning: ' .
+        " \ (strlen(lp) - strlen(rp))
+        return (strlen(lp) - strlen(rp))
+    else
+        " echom 'CountUnbalancedParan unknown paran to check: ' .
+        " \ a:paran_to_check
+        return 0
+    endif
+endfunction
+
+" Unindent commands based on previous indent level
+function s:CheckToIgnoreRightParan( prev_lnum, num_levels )
+    let lnum = a:prev_lnum
+    let line = getline(lnum)
+    let ends = 0
+    let num_right_paran = a:num_levels
+    let ignore_paran = 0
+    let vircol = 1
+
+    while num_right_paran > 0
+        silent! exec 'norm! '.lnum."G\<bar>".vircol."\<bar>"
+        let right_paran = search( ')', 'W' )
+        if right_paran != lnum
+            " This should not happen since there should be at least
+            " num_right_paran matches for this line
+            break
+        endif
+        let vircol      = virtcol(".")
+
+        " if getline(".") =~ '^)'
+        let matching_paran = searchpair('(', '', ')', 'bW',
+                    \ 'IsColComment(line("."), col("."))')
+
+        if matching_paran < 1
+            " No match found
+            " echom 'CTIRP - no match found, ignoring'
+            break
+        endif
+
+        if matching_paran == lnum
+            " This was not an unmatched parantenses, start the search again
+            " again after this column
+            " echom 'CTIRP - same line match, ignoring'
+            continue
+        endif
+
+        " echom 'CTIRP - match: ' . line(".") . '  ' . getline(".")
+
+        if getline(matching_paran) =~? '\(if\|while\)\>'
+            " echom 'CTIRP - if/while ignored: ' . line(".") . '  ' . getline(".")
+            let ignore_paran = ignore_paran + 1
+        endif
+
+        " One match found, decrease and check for further matches
+        let num_right_paran = num_right_paran - 1
+
+    endwhile
+
+    " Fallback - just move back one
+    " return a:prev_indent - &sw
+    return ignore_paran
+endfunction
+
+" Based on the keyword provided, loop through previous non empty
+" non comment lines to find the statement that initated the keyword.
+" Return its indent level
+"    CASE ..
+"    WHEN ...
+" Should return indent level of CASE
+"    EXCEPTION ..
+"    WHEN ...
+"         something;
+"    WHEN ...
+" Should return indent level of exception.
+function s:GetStmtStarterIndent( keyword, curr_lnum )
+    let lnum  = a:curr_lnum
+
+    " Default - reduce indent by 1
+    let ind = indent(a:curr_lnum) - &sw
+
+    if a:keyword =~? 'end'
+        exec 'normal! ^'
+        let stmts = '^\s*\%('.
+                    \ '\<begin\>\|' .
+                    \ '\%(\%(\<end\s\+\)\@<!\<loop\>\)\|' .
+                    \ '\%(\%(\<end\s\+\)\@<!\<case\>\)\|' .
+                    \ '\%(\%(\<end\s\+\)\@<!\<for\>\)\|' .
+                    \ '\%(\%(\<end\s\+\)\@<!\<if\>\)'.
+                    \ '\)'
+        let matching_lnum = searchpair(stmts, '', '\<end\>\zs', 'bW',
+                    \ 'IsColComment(line("."), col(".")) == 1')
+        exec 'normal! $'
+        if matching_lnum > 0 && matching_lnum < a:curr_lnum
+            let ind = indent(matching_lnum)
+        endif
+    elseif a:keyword =~? 'when'
+        exec 'normal! ^'
+        let matching_lnum = searchpair(
+                    \ '\%(\<end\s\+\)\@<!\<case\>\|\<exception\>\|\<merge\>',
+                    \ '',
+                    \ '\%(\%(\<when\s\+others\>\)\|\%(\<end\s\+case\>\)\)',
+                    \ 'bW',
+                    \ 'IsColComment(line("."), col(".")) == 1')
+        exec 'normal! $'
+        if matching_lnum > 0 && matching_lnum < a:curr_lnum
+            let ind = indent(matching_lnum)
+        else
+            let ind = indent(a:curr_lnum)
+        endif
+    endif
+
+    return ind
+endfunction
+
+
+" Check if the line is a comment
+function IsLineComment(lnum)
+    let rc = synIDattr(
+                \ synID(a:lnum,
+                \     match(getline(a:lnum), '\S')+1, 0)
+                \ , "name")
+                \ =~? "comment"
+
+    return rc
+endfunction
+
+
+" Check if the column is a comment
+function IsColComment(lnum, cnum)
+    let rc = synIDattr(synID(a:lnum, a:cnum, 0), "name")
+                \           =~? "comment"
+
+    return rc
+endfunction
+
+
+" Check if the column is a comment
+function ModuloIndent(ind)
+    let ind = a:ind
+
+    if ind > 0
+        let modulo = ind % &shiftwidth
+
+        if modulo > 0
+            let ind = ind - modulo
+        endif
+    endif
+
+    return ind
+endfunction
+
+
+" Find correct indent of a new line based upon the previous line
+function GetSQLIndent()
+    let lnum = v:lnum
+    let ind = indent(lnum)
+
+    " If the current line is a comment, leave the indent as is
+    " Comment out this additional check since it affects the
+    " indenting of =, and will not reindent comments as it should
+    " if IsLineComment(lnum) == 1
+    "     return ind
+    " endif
+
+    " while 1
+        " Get previous non-blank line
+        let prevlnum = prevnonblank(lnum - 1)
+        if prevlnum <= 0
+            return ind
+        endif
+
+        if IsLineComment(prevlnum) == 1
+            if getline(v:lnum) =~ '^\s*\*'
+                let ind = ModuloIndent(indent(prevlnum))
+                return ind + 1
+            endif
+            " If the previous line is a comment, then return -1
+            " to tell Vim to use the formatoptions setting to determine
+            " the indent to use
+            " But only if the next line is blank.  This would be true if
+            " the user is typing, but it would not be true if the user
+            " is reindenting the file
+            if getline(v:lnum) =~ '^\s*$'
+                return -1
+            endif
+        endif
+
+    "     let prevline = getline(prevlnum)
+    "     if prevline !~ '^\s*$'
+    "         " echom 'previous non blank - break: ' . prevline
+    "         break
+    "     endif
+    " endwhile
+
+    " echom 'PREVIOUS INDENT: ' . indent(prevlnum) . '  LINE: ' . getline(prevlnum)
+
+    " This is the line you just hit return on, it is not the current line
+    " which is new and empty
+    " Based on this line, we can determine how much to indent the new
+    " line
+
+    " Get default indent (from prev. line)
+    let ind      = indent(prevlnum)
+    let prevline = getline(prevlnum)
+
+    " Now check what's on the previous line to determine if the indent
+    " should be changed, for example IF, BEGIN, should increase the indent
+    " where END IF, END, should decrease the indent.
+    if prevline =~? s:SQLBlockStart
+        " Move indent in
+        let ind = ind + &sw
+        " echom 'prevl - SQLBlockStart - indent ' . ind . '  line: ' . prevline
+    elseif prevline =~ '[()]'
+        if prevline =~ '('
+            let num_unmatched_left = s:CountUnbalancedParan( prevline, '(' )
+        else
+            let num_unmatched_left = 0
+        endif
+        if prevline =~ ')'
+            let num_unmatched_right  = s:CountUnbalancedParan( prevline, ')' )
+        else
+            let num_unmatched_right  = 0
+            " let num_unmatched_right  = s:CountUnbalancedParan( prevline, ')' )
+        endif
+        if num_unmatched_left > 0
+            " There is a open left paranethesis
+            " increase indent
+            let ind = ind + ( &sw * num_unmatched_left )
+        elseif num_unmatched_right > 0
+            " if it is an unbalanced paranethesis only unindent if
+            " it was part of a command (ie create table(..)  )
+            " instead of part of an if (ie if (....) then) which should
+            " maintain the indent level
+            let ignore = s:CheckToIgnoreRightParan( prevlnum, num_unmatched_right )
+            " echom 'prevl - ) unbalanced - CTIRP - ignore: ' . ignore
+
+            if prevline =~ '^\s*)'
+                let ignore = ignore + 1
+                " echom 'prevl - begins ) unbalanced ignore: ' . ignore
+            endif
+
+            if (num_unmatched_right - ignore) > 0
+                let ind = ind - ( &sw * (num_unmatched_right - ignore) )
+            endif
+
+        endif
+    endif
+
+
+    " echom 'CURRENT INDENT: ' . ind . '  LINE: '  . getline(v:lnum)
+
+    " This is a new blank line since we just typed a carriage return
+    " Check current line; search for simplistic matching start-of-block
+    let line = getline(v:lnum)
+
+    if line =~? '^\s*els'
+        " Any line when you type else will automatically back up one
+        " ident level  (ie else, elseif, elsif)
+        let ind = ind - &sw
+        " echom 'curr - else - indent ' . ind
+    elseif line =~? '^\s*end\>'
+        let ind = s:GetStmtStarterIndent('end', v:lnum)
+        " General case for end
+        " let ind = ind - &sw
+        " echom 'curr - end - indent ' . ind
+    elseif line =~? '^\s*when\>'
+        let ind = s:GetStmtStarterIndent('when', v:lnum)
+        " If the WHEN clause is used with a MERGE or EXCEPTION
+        " clause, do not change the indent level, since these
+        " statements do not have a corresponding END statement.
+        " if stmt_starter =~? 'case'
+        "    let ind = ind - &sw
+        " endif
+        " elseif line =~ '^\s*)\s*;\?\s*$'
+        " elseif line =~ '^\s*)'
+    elseif line =~ '^\s*)'
+        let num_unmatched_right  = s:CountUnbalancedParan( line, ')' )
+        let ignore = s:CheckToIgnoreRightParan( v:lnum, num_unmatched_right )
+        " If the line ends in a ), then reduce the indent
+        " This catches items like:
+        " CREATE TABLE T1(
+        "    c1 int,
+        "    c2 int
+        "    );
+        " But we do not want to unindent a line like:
+        " IF ( c1 = 1
+        " AND  c2 = 3 ) THEN
+        " let num_unmatched_right  = s:CountUnbalancedParan( line, ')' )
+        " if num_unmatched_right > 0
+        " elseif strpart( line, strlen(line)-1, 1 ) =~ ')'
+        " let ind = ind - &sw
+        if line =~ '^\s*)'
+            " let ignore = ignore + 1
+            " echom 'curr - begins ) unbalanced ignore: ' . ignore
+        endif
+
+        if (num_unmatched_right - ignore) > 0
+            let ind = ind - ( &sw * (num_unmatched_right - ignore) )
+        endif
+        " endif
+    endif
+
+    " echom 'final - indent ' . ind
+    return ModuloIndent(ind)
+endfunction
+
+" vim:sw=4:ff=unix:
--- /dev/null
+++ b/lib/vimfiles/indent/tcl.vim
@@ -1,0 +1,75 @@
+" Vim indent file
+" Language:	    Tcl
+" Maintainer:	    Nikolai Weibull <now@bitwi.se>
+" Latest Revision:  2006-12-20
+
+if exists("b:did_indent")
+  finish
+endif
+let b:did_indent = 1
+
+setlocal indentexpr=GetTclIndent()
+setlocal indentkeys=0{,0},!^F,o,O,0]
+setlocal nosmartindent
+
+if exists("*GetTclIndent")
+  finish
+endif
+
+function s:prevnonblanknoncomment(lnum)
+  let lnum = prevnonblank(a:lnum)
+  while lnum > 0
+    let line = getline(lnum)
+    if line !~ '^\s*\(#\|$\)'
+      break
+    endif
+    let lnum = prevnonblank(lnum - 1)
+  endwhile
+  return lnum
+endfunction
+
+function s:count_braces(lnum, count_open)
+  let n_open = 0
+  let n_close = 0
+  let line = getline(a:lnum)
+  let pattern = '[{}]'
+  let i = match(line, pattern)
+  while i != -1
+    if synIDattr(synID(a:lnum, i + 1, 0), 'name') !~ 'tcl\%(Comment\|String\)'
+      if line[i] == '{'
+        let n_open += 1
+      elseif line[i] == '}'
+        if n_open > 0
+          let n_open -= 1
+        else
+          let n_close += 1
+        endif
+      endif
+    endif
+    let i = match(line, pattern, i + 1)
+  endwhile
+  return a:count_open ? n_open : n_close
+endfunction
+
+function GetTclIndent()
+  let line = getline(v:lnum)
+  if line =~ '^\s*\*'
+    return cindent(v:lnum)
+  elseif line =~ '^\s*}'
+    return indent(v:lnum) - &sw
+  endif
+
+  let pnum = s:prevnonblanknoncomment(v:lnum - 1)
+  if pnum == 0
+    return 0
+  endif
+
+  let ind = indent(pnum) + s:count_braces(pnum, 1) * &sw
+
+  let pline = getline(pnum)
+  if pline =~ '}\s*$'
+    let ind -= (s:count_braces(pnum, 0) - (pline =~ '^\s*}' ? 1 : 0)) * &sw
+  endif
+
+  return ind
+endfunction
--- /dev/null
+++ b/lib/vimfiles/indent/tcsh.vim
@@ -1,0 +1,51 @@
+" Vim indent file
+" Language:		C-shell (tcsh)
+" Maintainer:		Gautam Iyer <gautam@math.uchicago.edu>
+" Last Modified:	Wed 04 Feb 2004 04:36:07 PM CST
+
+" Only load this indent file when no other was loaded.
+if exists("b:did_indent")
+    finish
+endif
+
+let b:did_indent = 1
+
+setlocal indentexpr=TcshGetIndent()
+setlocal indentkeys+=e,0=end,0=endsw,*<return> indentkeys-=0{,0},0),:,0#
+
+" Only define the function once.
+if exists("*TcshGetIndent")
+    finish
+endif
+
+set cpoptions-=C
+
+function TcshGetIndent()
+    " Find a non-blank line above the current line.
+    let lnum = prevnonblank(v:lnum - 1)
+
+    " Hit the start of the file, use zero indent.
+    if lnum == 0
+	return 0
+    endif
+
+    " Add indent if previous line begins with while or foreach
+    " OR line ends with case <str>:, default:, else, then or \
+    let ind = indent(lnum)
+    let line = getline(lnum)
+    if line =~ '\v^\s*%(while|foreach)>|^\s*%(case\s.*:|default:|else)\s*$|%(<then|\\)$'
+	let ind = ind + &sw
+    endif
+
+    if line =~ '\v^\s*breaksw>'
+	let ind = ind - &sw
+    endif
+
+    " Subtract indent if current line has on end, endif, case commands
+    let line = getline(v:lnum)
+    if line =~ '\v^\s*%(else|end|endif)\s*$'
+	let ind = ind - &sw
+    endif
+
+    return ind
+endfunction
--- /dev/null
+++ b/lib/vimfiles/indent/tilde.vim
@@ -1,0 +1,36 @@
+"Description: Indent scheme for the tilde weblanguage
+"Author: Tobias Rundstr�m <tobi@tobi.nu>
+"URL: http://tilde.tildesoftware.net
+"Last Change: May  8 09:15:09 CEST 2002
+
+if exists ("b:did_indent")
+	finish
+endif
+
+let b:did_indent = 1
+
+setlocal autoindent
+setlocal indentexpr=GetTildeIndent(v:lnum)
+setlocal indentkeys=o,O,)
+
+if exists("*GetTildeIndent")
+	finish
+endif
+
+function GetTildeIndent(lnum)
+	let plnum = prevnonblank(v:lnum-1)
+
+	if plnum == 0
+		return 0
+	endif
+
+	if getline(v:lnum) =~ '^\s*\~\(endif\|else\|elseif\|end\)\>'
+		return indent(v:lnum) - &sw
+	endif
+
+	if getline(plnum) =~ '^\s*\~\(if\|foreach\|foreach_row\|xml_loop\|file_loop\|file_write\|file_append\|imap_loopsections\|imap_index\|imap_list\|ldap_search\|post_loopall\|post_loop\|file_loop\|sql_loop_num\|sql_dbmsselect\|search\|sql_loop\|post\|for\|function_define\|silent\|while\|setvalbig\|mail_create\|systempipe\|mail_send\|dual\|elseif\|else\)\>'
+		return indent(plnum) + &sw
+	else
+		return -1
+	endif
+endfunction
--- /dev/null
+++ b/lib/vimfiles/indent/vb.vim
@@ -1,0 +1,75 @@
+" Vim indent file
+" Language:	VisualBasic (ft=vb) / Basic (ft=basic) / SaxBasic (ft=vb)
+" Author:	Johannes Zellner <johannes@zellner.org>
+" Last Change:	Fri, 18 Jun 2004 07:22:42 CEST
+
+if exists("b:did_indent")
+    finish
+endif
+let b:did_indent = 1
+
+setlocal autoindent
+setlocal indentexpr=VbGetIndent(v:lnum)
+setlocal indentkeys&
+setlocal indentkeys+==~else,=~elseif,=~end,=~wend,=~case,=~next,=~select,=~loop,<:>
+
+let b:undo_indent = "set ai< indentexpr< indentkeys<"
+
+" Only define the function once.
+if exists("*VbGetIndent")
+    finish
+endif
+
+fun! VbGetIndent(lnum)
+    " labels and preprocessor get zero indent immediately
+    let this_line = getline(a:lnum)
+    let LABELS_OR_PREPROC = '^\s*\(\<\k\+\>:\s*$\|#.*\)'
+    if this_line =~? LABELS_OR_PREPROC
+	return 0
+    endif
+
+    " Find a non-blank line above the current line.
+    " Skip over labels and preprocessor directives.
+    let lnum = a:lnum
+    while lnum > 0
+	let lnum = prevnonblank(lnum - 1)
+	let previous_line = getline(lnum)
+	if previous_line !~? LABELS_OR_PREPROC
+	    break
+	endif
+    endwhile
+
+    " Hit the start of the file, use zero indent.
+    if lnum == 0
+	return 0
+    endif
+
+    let ind = indent(lnum)
+
+    " Add
+    if previous_line =~? '^\s*\<\(begin\|\%(\%(private\|public\|friend\)\s\+\)\=\%(function\|sub\|property\)\|select\|case\|default\|if\>.\{-}\<then\>\s*$\|else\|elseif\|do\|for\|while\|enum\|with\)\>'
+	let ind = ind + &sw
+    endif
+
+    " Subtract
+    if this_line =~? '^\s*\<end\>\s\+\<select\>'
+	if previous_line !~? '^\s*\<select\>'
+	    let ind = ind - 2 * &sw
+	else
+	    " this case is for an empty 'select' -- 'end select'
+	    " (w/o any case statements) like:
+	    "
+	    " select case readwrite
+	    " end select
+	    let ind = ind - &sw
+	endif
+    elseif this_line =~? '^\s*\<\(end\|else\|until\|loop\|next\|wend\)\>'
+	let ind = ind - &sw
+    elseif this_line =~? '^\s*\<\(case\|default\)\>'
+	if previous_line !~? '^\s*\<select\>'
+	    let ind = ind - &sw
+	endif
+    endif
+
+    return ind
+endfun
--- /dev/null
+++ b/lib/vimfiles/indent/verilog.vim
@@ -1,0 +1,219 @@
+" Language:     Verilog HDL
+" Maintainer:	Chih-Tsun Huang <cthuang@larc.ee.nthu.edu.tw>
+" Last Change:	Wed Oct 31 16:13:11 CST 2001
+" URL:		http://larc.ee.nthu.edu.tw/~cthuang/vim/indent/verilog.vim
+"
+" Credits:
+"   Suggestions for improvement, bug reports by
+"     Leo Butlero <lbutler@brocade.com>
+"
+" Buffer Variables:
+"     b:verilog_indent_modules : indenting after the declaration
+"				 of module blocks
+"     b:verilog_indent_width   : indenting width
+"     b:verilog_indent_verbose : verbose to each indenting
+"
+
+" Only load this indent file when no other was loaded.
+if exists("b:did_indent")
+  finish
+endif
+let b:did_indent = 1
+
+setlocal indentexpr=GetVerilogIndent()
+setlocal indentkeys=!^F,o,O,0),=begin,=end,=join,=endcase
+setlocal indentkeys+==endmodule,=endfunction,=endtask,=endspecify
+setlocal indentkeys+==`else,=`endif
+
+" Only define the function once.
+if exists("*GetVerilogIndent")
+  finish
+endif
+
+set cpo-=C
+
+function GetVerilogIndent()
+
+  if exists('b:verilog_indent_width')
+    let offset = b:verilog_indent_width
+  else
+    let offset = &sw
+  endif
+  if exists('b:verilog_indent_modules')
+    let indent_modules = offset
+  else
+    let indent_modules = 0
+  endif
+
+  " Find a non-blank line above the current line.
+  let lnum = prevnonblank(v:lnum - 1)
+
+  " At the start of the file use zero indent.
+  if lnum == 0
+    return 0
+  endif
+
+  let lnum2 = prevnonblank(lnum - 1)
+  let curr_line  = getline(v:lnum)
+  let last_line  = getline(lnum)
+  let last_line2 = getline(lnum2)
+  let ind  = indent(lnum)
+  let ind2 = indent(lnum - 1)
+  let offset_comment1 = 1
+  " Define the condition of an open statement
+  "   Exclude the match of //, /* or */
+  let vlog_openstat = '\(\<or\>\|\([*/]\)\@<![*(,{><+-/%^&|!=?:]\([*/]\)\@!\)'
+  " Define the condition when the statement ends with a one-line comment
+  let vlog_comment = '\(//.*\|/\*.*\*/\s*\)'
+  if exists('b:verilog_indent_verbose')
+    let vverb_str = 'INDENT VERBOSE:'
+    let vverb = 1
+  else
+    let vverb = 0
+  endif
+
+  " Indent accoding to last line
+  " End of multiple-line comment
+  if last_line =~ '\*/\s*$' && last_line !~ '/\*.\{-}\*/'
+    let ind = ind - offset_comment1
+    if vverb
+      echo vverb_str "De-indent after a multiple-line comment."
+    endif
+
+  " Indent after if/else/for/case/always/initial/specify/fork blocks
+  elseif last_line =~ '`\@<!\<\(if\|else\)\>' ||
+    \ last_line =~ '^\s*\<\(for\|case\%[[zx]]\)\>' ||
+    \ last_line =~ '^\s*\<\(always\|initial\)\>' ||
+    \ last_line =~ '^\s*\<\(specify\|fork\)\>'
+    if last_line !~ '\(;\|\<end\>\)\s*' . vlog_comment . '*$' ||
+      \ last_line =~ '\(//\|/\*\).*\(;\|\<end\>\)\s*' . vlog_comment . '*$'
+      let ind = ind + offset
+      if vverb | echo vverb_str "Indent after a block statement." | endif
+    endif
+  " Indent after function/task blocks
+  elseif last_line =~ '^\s*\<\(function\|task\)\>'
+    if last_line !~ '\<end\>\s*' . vlog_comment . '*$' ||
+      \ last_line =~ '\(//\|/\*\).*\(;\|\<end\>\)\s*' . vlog_comment . '*$'
+      let ind = ind + offset
+      if vverb
+	echo vverb_str "Indent after function/task block statement."
+      endif
+    endif
+
+  " Indent after module/function/task/specify/fork blocks
+  elseif last_line =~ '^\s*\<module\>'
+    let ind = ind + indent_modules
+    if vverb && indent_modules
+      echo vverb_str "Indent after module statement."
+    endif
+    if last_line =~ '[(,]\s*' . vlog_comment . '*$' &&
+      \ last_line !~ '\(//\|/\*\).*[(,]\s*' . vlog_comment . '*$'
+      let ind = ind + offset
+      if vverb
+	echo vverb_str "Indent after a multiple-line module statement."
+      endif
+    endif
+
+  " Indent after a 'begin' statement
+  elseif last_line =~ '\(\<begin\>\)\(\s*:\s*\w\+\)*' . vlog_comment . '*$' &&
+    \ last_line !~ '\(//\|/\*\).*\(\<begin\>\)' &&
+    \ ( last_line2 !~ vlog_openstat . '\s*' . vlog_comment . '*$' ||
+    \ last_line2 =~ '^\s*[^=!]\+\s*:\s*' . vlog_comment . '*$' )
+    let ind = ind + offset
+    if vverb | echo vverb_str "Indent after begin statement." | endif
+
+  " De-indent for the end of one-line block
+  elseif ( last_line !~ '\<begin\>' ||
+    \ last_line =~ '\(//\|/\*\).*\<begin\>' ) &&
+    \ last_line2 =~ '\<\(`\@<!if\|`\@<!else\|for\|always\|initial\)\>.*' .
+      \ vlog_comment . '*$' &&
+    \ last_line2 !~
+      \ '\(//\|/\*\).*\<\(`\@<!if\|`\@<!else\|for\|always\|initial\)\>' &&
+    \ last_line2 !~ vlog_openstat . '\s*' . vlog_comment . '*$' &&
+    \ ( last_line2 !~ '\<begin\>' ||
+    \ last_line2 =~ '\(//\|/\*\).*\<begin\>' )
+    let ind = ind - offset
+    if vverb
+      echo vverb_str "De-indent after the end of one-line statement."
+    endif
+
+    " Multiple-line statement (including case statement)
+    " Open statement
+    "   Ident the first open line
+    elseif  last_line =~ vlog_openstat . '\s*' . vlog_comment . '*$' &&
+      \ last_line !~ '\(//\|/\*\).*' . vlog_openstat . '\s*$' &&
+      \ last_line2 !~ vlog_openstat . '\s*' . vlog_comment . '*$'
+      let ind = ind + offset
+      if vverb | echo vverb_str "Indent after an open statement." | endif
+
+    " Close statement
+    "   De-indent for an optional close parenthesis and a semicolon, and only
+    "   if there exists precedent non-whitespace char
+    elseif last_line =~ ')*\s*;\s*' . vlog_comment . '*$' &&
+      \ last_line !~ '^\s*)*\s*;\s*' . vlog_comment . '*$' &&
+      \ last_line !~ '\(//\|/\*\).*\S)*\s*;\s*' . vlog_comment . '*$' &&
+      \ ( last_line2 =~ vlog_openstat . '\s*' . vlog_comment . '*$' &&
+      \ last_line2 !~ ';\s*//.*$') &&
+      \ last_line2 !~ '^\s*' . vlog_comment . '$'
+      let ind = ind - offset
+      if vverb | echo vverb_str "De-indent after a close statement." | endif
+
+  " `ifdef and `else
+  elseif last_line =~ '^\s*`\<\(ifdef\|else\)\>'
+    let ind = ind + offset
+    if vverb
+      echo vverb_str "Indent after a `ifdef or `else statement."
+    endif
+
+  endif
+
+  " Re-indent current line
+
+  " De-indent on the end of the block
+  " join/end/endcase/endfunction/endtask/endspecify
+  if curr_line =~ '^\s*\<\(join\|end\|endcase\)\>' ||
+    \ curr_line =~ '^\s*\<\(endfunction\|endtask\|endspecify\)\>'
+    let ind = ind - offset
+    if vverb | echo vverb_str "De-indent the end of a block." | endif
+  elseif curr_line =~ '^\s*\<endmodule\>'
+    let ind = ind - indent_modules
+    if vverb && indent_modules
+      echo vverb_str "De-indent the end of a module."
+    endif
+
+  " De-indent on a stand-alone 'begin'
+  elseif curr_line =~ '^\s*\<begin\>'
+    if last_line !~ '^\s*\<\(function\|task\|specify\|module\)\>' &&
+      \ last_line !~ '^\s*\()*\s*;\|)\+\)\s*' . vlog_comment . '*$' &&
+      \ ( last_line =~
+	\ '\<\(`\@<!if\|`\@<!else\|for\|case\%[[zx]]\|always\|initial\)\>' ||
+      \ last_line =~ ')\s*' . vlog_comment . '*$' ||
+      \ last_line =~ vlog_openstat . '\s*' . vlog_comment . '*$' )
+      let ind = ind - offset
+      if vverb
+	echo vverb_str "De-indent a stand alone begin statement."
+      endif
+    endif
+
+  " De-indent after the end of multiple-line statement
+  elseif curr_line =~ '^\s*)' &&
+    \ ( last_line =~ vlog_openstat . '\s*' . vlog_comment . '*$' ||
+    \ last_line !~ vlog_openstat . '\s*' . vlog_comment . '*$' &&
+    \ last_line2 =~ vlog_openstat . '\s*' . vlog_comment . '*$' )
+    let ind = ind - offset
+    if vverb
+      echo vverb_str "De-indent the end of a multiple statement."
+    endif
+
+  " De-indent `else and `endif
+  elseif curr_line =~ '^\s*`\<\(else\|endif\)\>'
+    let ind = ind - offset
+    if vverb | echo vverb_str "De-indent `else and `endif statement." | endif
+
+  endif
+
+  " Return the indention
+  return ind
+endfunction
+
+" vim:sw=2
--- /dev/null
+++ b/lib/vimfiles/indent/vhdl.vim
@@ -1,0 +1,405 @@
+" VHDL indent ('93 syntax)
+" Language:    VHDL
+" Maintainer:  Gerald Lai <laigera+vim?gmail.com>
+" Version:     1.50
+" Last Change: 2007 Jan 29
+" URL:         http://www.vim.org/scripts/script.php?script_id=1450
+
+" only load this indent file when no other was loaded
+if exists("b:did_indent")
+  finish
+endif
+let b:did_indent = 1
+
+" setup indent options for local VHDL buffer
+setlocal indentexpr=GetVHDLindent()
+setlocal indentkeys=!^F,o,O,0(,0)
+setlocal indentkeys+==~begin,=~end\ ,=~end\	,=~is,=~select,=~when
+setlocal indentkeys+==~if,=~then,=~elsif,=~else
+setlocal indentkeys+==~case,=~loop,=~for,=~generate,=~record,=~units,=~process,=~block,=~function,=~component,=~procedure
+setlocal indentkeys+==~architecture,=~configuration,=~entity,=~package
+
+" constants
+" not a comment
+let s:NC = '\%(--.*\)\@<!'
+" end of string
+let s:ES = '\s*\%(--.*\)\=$'
+" no "end" keyword in front
+let s:NE = '\%(\<end\s\+\)\@<!'
+
+" option to disable alignment of generic/port mappings
+if !exists("g:vhdl_align_genportmap")
+  let g:vhdl_align_genportmap = 1
+endif
+
+" option to disable alignment of right-hand side assignment "<=" statements
+if !exists("g:vhdl_align_rhsassign")
+  let g:vhdl_align_rhsassign = 1
+endif
+
+" only define indent function once
+if exists("*GetVHDLindent")
+  finish
+endif
+
+function GetVHDLindent()
+  " store current line & string
+  let curn = v:lnum
+  let curs = getline(curn)
+
+  " find previous line that is not a comment
+  let prevn = prevnonblank(curn - 1)
+  let prevs = getline(prevn)
+  while prevn > 0 && prevs =~ '^\s*--'
+    let prevn = prevnonblank(prevn - 1)
+    let prevs = getline(prevn)
+  endwhile
+
+  " default indent starts as previous non-comment line's indent
+  let ind = prevn > 0 ? indent(prevn) : 0
+  " backup default
+  let ind2 = ind
+
+  " indent:   special; kill string so it would not affect other filters
+  " keywords: "report" + string
+  " where:    anywhere in current or previous line
+  let s0 = s:NC.'\<report\>\s*".*"'
+  if curs =~? s0
+    let curs = ""
+  endif
+  if prevs =~? s0
+    let prevs = ""
+  endif
+
+  " indent:   previous line's comment position, otherwise follow next non-comment line if possible
+  " keyword:  "--"
+  " where:    start of current line
+  if curs =~ '^\s*--'
+    let pn = curn - 1
+    let ps = getline(pn)
+    if ps =~ '--'
+      return stridx(ps, '--')
+    else
+      " find nextnonblank line that is not a comment
+      let nn = nextnonblank(curn + 1)
+      let ns = getline(nn)
+      while nn > 0 && ns =~ '^\s*--'
+        let nn = nextnonblank(nn + 1)
+        let ns = getline(nn)
+      endwhile
+      let n = indent(nn)
+      return n != -1 ? n : ind
+    endif
+  endif
+
+  " ****************************************************************************************
+  " indent:   align generic variables & port names
+  " keywords: "generic", "map", "port" + "(", provided current line is part of mapping
+  " where:    anywhere in previous 2 lines
+  " find following previous non-comment line
+  let pn = prevnonblank(prevn - 1)
+  let ps = getline(pn)
+  while pn > 0 && ps =~ '^\s*--'
+    let pn = prevnonblank(pn - 1)
+    let ps = getline(pn)
+  endwhile
+  if (curs =~ '^\s*)' || curs =~? '^\s*\%(\<\%(generic\|map\|port\)\>.*\)\@<!\S\+\s*\%(=>\s*\S\+\|:[^=]\@=\s*\%(\%(in\|out\|inout\|buffer\|linkage\)\>\|\w\+\s\+:=\)\)') && (prevs =~? s:NC.'\<\%(generic\|map\|port\)\s*(\%(\s*\w\)\=' || (ps =~? s:NC.'\<\%(generic\|map\|port\)'.s:ES && prevs =~ '^\s*('))
+    " align closing ")" with opening "("
+    if curs =~ '^\s*)'
+      return stridx(prevs, '(')
+    endif
+    let m = matchend(prevs, '(\s*\ze\w')
+    if m != -1
+      return m
+    else
+      if g:vhdl_align_genportmap
+        return stridx(prevs, '(') + &sw
+      else
+        return ind2 + &sw
+      endif
+    endif
+  endif
+
+  " indent:   align conditional/select statement
+  " keywords: variable + "<=" without ";" ending
+  " where:    start of previous line
+  if prevs =~? '^\s*\S\+\s*<=[^;]*'.s:ES
+    if g:vhdl_align_rhsassign
+      return matchend(prevs, '<=\s*\ze.')
+    else
+      return ind2 + &sw
+    endif
+  endif
+
+  " indent:   backtrace previous non-comment lines for next smaller or equal size indent
+  " keywords: "end" + "record", "units"
+  " where:    start of previous line
+  " keyword:  ")"
+  " where:    start of previous line
+  " keyword:  without "<=" + ";" ending
+  " where:    anywhere in previous line
+  " keyword:  "=>" + ")" ending, provided current line does not begin with ")"
+  " where:    anywhere in previous line
+  " _note_:   indent allowed to leave this filter
+  let m = 0
+  if prevs =~? '^\s*end\s\+\%(record\|units\)\>'
+    let m = 3
+  elseif prevs =~ '^\s*)'
+    let m = 1
+  elseif prevs =~ s:NC.'\%(<=.*\)\@<!;'.s:ES || (curs !~ '^\s*)' && prevs =~ s:NC.'=>.*'.s:NC.')'.s:ES)
+    let m = 2
+  endif
+
+  if m > 0
+    let pn = prevnonblank(prevn - 1)
+    let ps = getline(pn)
+    while pn > 0
+      let t = indent(pn)
+      if ps !~ '^\s*--' && t < ind
+        " make sure one of these is true
+        " keywords: variable + "<=" without ";" ending
+        " where:    start of previous non-comment line
+        " keywords: "generic", "map", "port"
+        " where:    anywhere in previous non-comment line
+        " keyword:  "("
+        " where:    start of previous non-comment line
+        if m < 3 && ps !~? '^\s*\S\+\s*<=[^;]*'.s:ES
+          if ps =~? s:NC.'\<\%(generic\|map\|port\)\>' || ps =~ '^\s*('
+            let ind = t
+          endif
+          break
+        endif
+        let ind = t
+        if m > 1
+          " find following previous non-comment line
+          let ppn = prevnonblank(pn - 1)
+          let pps = getline(ppn)
+          while ppn > 0 && pps =~ '^\s*--'
+            let ppn = prevnonblank(ppn - 1)
+            let pps = getline(ppn)
+          endwhile
+          " indent:   follow
+          " keyword:  "select"
+          " where:    end of following previous non-comment line
+          " keyword:  "type"
+          " where:    start of following previous non-comment line
+          if m == 2
+            let s1 = s:NC.'\<select'.s:ES
+            if ps !~? s1 && pps =~? s1
+              let ind = indent(ppn)
+            endif
+          elseif m == 3
+            let s1 = '^\s*type\>'
+            if ps !~? s1 && pps =~? s1
+              let ind = indent(ppn)
+            endif
+          endif
+        endif
+        break
+      endif
+      let pn = prevnonblank(pn - 1)
+      let ps = getline(pn)
+    endwhile
+  endif
+
+  " indent:   follow indent of previous opening statement, otherwise -sw
+  " keyword:  "begin"
+  " where:    anywhere in current line
+  if curs =~? s:NC.'\<begin\>'
+    let ind = ind - &sw
+    " find previous opening statement of
+    " keywords: "architecture", "block", "entity", "function", "generate", "procedure", "process"
+    let s2 = s:NC.s:NE.'\<\%(architecture\|block\|entity\|function\|generate\|procedure\|process\)\>'
+    if (curs !~? s2.'.*'.s:NC.'\<begin\>.*'.s:ES && prevs =~? s2) || m == 1
+      let ind = ind + &sw
+    endif
+    return ind
+  endif
+
+  " indent:   +sw if previous line is previous opening statement
+  " keywords: "record", "units"
+  " where:    anywhere in current line
+  if curs =~? s:NC.s:NE.'\<\%(record\|units\)\>'
+    " find previous opening statement of
+    " keyword: "type"
+    let s3 = s:NC.s:NE.'\<type\>'
+    if curs !~? s3.'.*'.s:NC.'\<\%(record\|units\)\>.*'.s:ES && prevs =~? s3
+      let ind = ind + &sw
+    endif
+    return ind
+  endif
+
+  " ****************************************************************************************
+  " indent:   0
+  " keywords: "architecture", "configuration", "entity", "library", "package"
+  " where:    start of current line
+  if curs =~? '^\s*\%(architecture\|configuration\|entity\|library\|package\)\>'
+    return 0
+  endif
+
+  " indent:   maintain indent of previous opening statement
+  " keyword:  "is"
+  " where:    start of current line
+  " find previous opening statement of
+  " keywords: "architecture", "block", "configuration", "entity", "function", "package", "procedure", "process", "type"
+  if curs =~? '^\s*\<is\>' && prevs =~? s:NC.s:NE.'\<\%(architecture\|block\|configuration\|entity\|function\|package\|procedure\|process\|type\)\>'
+    return ind2
+  endif
+
+  " indent:   maintain indent of previous opening statement
+  " keyword:  "then"
+  " where:    start of current line
+  " find previous opening statement of
+  " keywords: "elsif", "if"
+  if curs =~? '^\s*\<then\>' && prevs =~? s:NC.'\%(\<elsif\>\|'.s:NE.'\<if\>\)'
+    return ind2
+  endif
+
+  " indent:   maintain indent of previous opening statement
+  " keyword:  "generate"
+  " where:    start of current line
+  " find previous opening statement of
+  " keywords: "for", "if"
+  if curs =~? '^\s*\<generate\>' && prevs =~? s:NC.s:NE.'\%(\%(\<wait\s\+\)\@<!\<for\|\<if\)\>'
+    return ind2
+  endif
+
+  " indent:   +sw
+  " keywords: "block", "process"
+  " removed:  "begin", "case", "elsif", "if", "loop", "record", "units", "while"
+  " where:    anywhere in previous line
+  if prevs =~? s:NC.s:NE.'\<\%(block\|process\)\>'
+    return ind + &sw
+  endif
+
+  " indent:   +sw
+  " keywords: "architecture", "configuration", "entity", "package"
+  " removed:  "component", "for", "when", "with"
+  " where:    start of previous line
+  if prevs =~? '^\s*\%(architecture\|configuration\|entity\|package\)\>'
+    return ind + &sw
+  endif
+
+  " indent:   +sw
+  " keyword:  "select"
+  " removed:  "generate", "is", "=>"
+  " where:    end of previous line
+  if prevs =~? s:NC.'\<select'.s:ES
+    return ind + &sw
+  endif
+
+  " indent:   +sw
+  " keyword:  "begin", "loop", "record", "units"
+  " where:    anywhere in previous line
+  " keyword:  "component", "else", "for"
+  " where:    start of previous line
+  " keyword:  "generate", "is", "then", "=>"
+  " where:    end of previous line
+  " _note_:   indent allowed to leave this filter
+  if prevs =~? s:NC.'\%(\<begin\>\|'.s:NE.'\<\%(loop\|record\|units\)\>\)' || prevs =~? '^\s*\%(component\|else\|for\)\>' || prevs =~? s:NC.'\%('.s:NE.'\<generate\|\<\%(is\|then\)\|=>\)'.s:ES
+    let ind = ind + &sw
+  endif
+
+  " ****************************************************************************************
+  " indent:   -sw
+  " keywords: "when", provided previous line does not begin with "when", does not end with "is"
+  " where:    start of current line
+  let s4 = '^\s*when\>'
+  if curs =~? s4
+    if prevs =~? s:NC.'\<is'.s:ES
+      return ind
+    elseif prevs !~? s4
+      return ind - &sw
+    else
+      return ind2
+    endif
+  endif
+
+  " indent:   -sw
+  " keywords: "else", "elsif", "end" + "block", "for", "function", "generate", "if", "loop", "procedure", "process", "record", "units"
+  " where:    start of current line
+  if curs =~? '^\s*\%(else\|elsif\|end\s\+\%(block\|for\|function\|generate\|if\|loop\|procedure\|process\|record\|units\)\)\>'
+    return ind - &sw
+  endif
+
+  " indent:   backtrace previous non-comment lines
+  " keyword:  "end" + "case", "component"
+  " where:    start of current line
+  let m = 0
+  if curs =~? '^\s*end\s\+case\>'
+    let m = 1
+  elseif curs =~? '^\s*end\s\+component\>'
+    let m = 2
+  endif
+
+  if m > 0
+    " find following previous non-comment line
+    let pn = prevn
+    let ps = getline(pn)
+    while pn > 0
+      if ps !~ '^\s*--'
+        "indent:   -2sw
+        "keywords: "end" + "case"
+        "where:    start of previous non-comment line
+        "indent:   -sw
+        "keywords: "when"
+        "where:    start of previous non-comment line
+        "indent:   follow
+        "keywords: "case"
+        "where:    start of previous non-comment line
+        if m == 1
+          if ps =~? '^\s*end\s\+case\>'
+            return indent(pn) - 2 * &sw
+          elseif ps =~? '^\s*when\>'
+            return indent(pn) - &sw
+          elseif ps =~? '^\s*case\>'
+            return indent(pn)
+          endif
+        "indent:   follow
+        "keyword:  "component"
+        "where:    start of previous non-comment line
+        elseif m == 2
+          if ps =~? '^\s*component\>'
+            return indent(pn)
+          endif
+        endif
+      endif
+      let pn = prevnonblank(pn - 1)
+      let ps = getline(pn)
+    endwhile
+    return ind - &sw
+  endif
+
+  " indent:   -sw
+  " keyword:  ")"
+  " where:    start of current line
+  if curs =~ '^\s*)'
+    return ind - &sw
+  endif
+
+  " indent:   0
+  " keywords: "end" + "architecture", "configuration", "entity", "package"
+  " where:    start of current line
+  if curs =~? '^\s*end\s\+\%(architecture\|configuration\|entity\|package\)\>'
+    return 0
+  endif
+
+  " indent:   -sw
+  " keywords: "end" + identifier
+  " where:    start of current line
+  "if curs =~? '^\s*end\s\+\w\+\>'
+  if curs =~? '^\s*end\s'
+    return ind - &sw
+  endif
+
+  " ****************************************************************************************
+  " indent:   maintain indent of previous opening statement
+  " keywords: without "generic", "map", "port" + ":" but not ":=" + "in", "out", "inout", "buffer", "linkage", variable & ":="
+  " where:    start of current line
+  if curs =~? '^\s*\%(\<\%(generic\|map\|port\)\>.*\)\@<!\S\+\s*:[^=]\@=\s*\%(\%(in\|out\|inout\|buffer\|linkage\)\>\|\w\+\s\+:=\)'
+    return ind2
+  endif
+
+  " return leftover filtered indent
+  return ind
+endfunction
--- /dev/null
+++ b/lib/vimfiles/indent/vim.vim
@@ -1,0 +1,74 @@
+" Vim indent file
+" Language:	Vim script
+" Maintainer:	Bram Moolenaar <Bram@vim.org>
+" Last Change:	2005 Jul 06
+
+" Only load this indent file when no other was loaded.
+if exists("b:did_indent")
+  finish
+endif
+let b:did_indent = 1
+
+setlocal indentexpr=GetVimIndent()
+setlocal indentkeys+==end,=else,=cat,=fina,=END,0\\
+
+" Only define the function once.
+if exists("*GetVimIndent")
+  finish
+endif
+
+function GetVimIndent()
+  " Find a non-blank line above the current line.
+  let lnum = prevnonblank(v:lnum - 1)
+
+  " If the current line doesn't start with '\' and below a line that starts
+  " with '\', use the indent of the line above it.
+  if getline(v:lnum) !~ '^\s*\\'
+    while lnum > 0 && getline(lnum) =~ '^\s*\\'
+      let lnum = lnum - 1
+    endwhile
+  endif
+
+  " At the start of the file use zero indent.
+  if lnum == 0
+    return 0
+  endif
+
+  " Add a 'shiftwidth' after :if, :while, :try, :catch, :finally, :function
+  " and :else.  Add it three times for a line that starts with '\' after
+  " a line that doesn't (or g:vim_indent_cont if it exists).
+  let ind = indent(lnum)
+  if getline(v:lnum) =~ '^\s*\\' && v:lnum > 1 && getline(lnum) !~ '^\s*\\'
+    if exists("g:vim_indent_cont")
+      let ind = ind + g:vim_indent_cont
+    else
+      let ind = ind + &sw * 3
+    endif
+  elseif getline(lnum) =~ '\(^\||\)\s*\(if\|wh\%[ile]\|for\|try\|cat\%[ch]\|fina\%[lly]\|fu\%[nction]\|el\%[seif]\)\>'
+    let ind = ind + &sw
+  elseif getline(lnum) =~ '^\s*aug\%[roup]' && getline(lnum) !~ '^\s*aug\%[roup]\s*!\=\s\+END'
+    let ind = ind + &sw
+  endif
+
+  " If the previous line contains an "end" after a pipe, but not in an ":au"
+  " command.  And not when there is a backslash before the pipe.
+  " And when syntax HL is enabled avoid a match inside a string.
+  let line = getline(lnum)
+  let i = match(line, '[^\\]|\s*\(ene\@!\)')
+  if i > 0 && line !~ '^\s*au\%[tocmd]'
+    if !has('syntax_items') || synIDattr(synID(lnum, i + 2, 1), "name") !~ '\(Comment\|String\)$'
+      let ind = ind - &sw
+    endif
+  endif
+
+
+  " Subtract a 'shiftwidth' on a :endif, :endwhile, :catch, :finally, :endtry,
+  " :endfun, :else and :augroup END.
+  if getline(v:lnum) =~ '^\s*\(ene\@!\|cat\|fina\|el\|aug\%[roup]\s*!\=\s\+END\)'
+    let ind = ind - &sw
+  endif
+
+  return ind
+endfunction
+
+" vim:sw=2
--- /dev/null
+++ b/lib/vimfiles/indent/xf86conf.vim
@@ -1,0 +1,37 @@
+" Vim indent file
+" Language:         XFree86 Configuration File
+" Maintainer:       Nikolai Weibull <now@bitwi.se>
+" Latest Revision:  2006-12-20
+
+if exists("b:did_indent")
+  finish
+endif
+let b:did_indent = 1
+
+setlocal indentexpr=GetXF86ConfIndent()
+setlocal indentkeys=!^F,o,O,=End
+setlocal nosmartindent
+
+if exists("*GetXF86ConfIndent")
+  finish
+endif
+
+function GetXF86ConfIndent()
+  let lnum = prevnonblank(v:lnum - 1)
+
+  if lnum == 0
+    return 0
+  endif
+
+  let ind = indent(lnum)
+
+  if getline(lnum) =~? '^\s*\(Sub\)\=Section\>'
+    let ind = ind + &sw
+  endif
+
+  if getline(v:lnum) =~? '^\s*End\(Sub\)\=Section\>'
+    let ind = ind - &sw
+  endif
+
+  return ind
+endfunction
--- /dev/null
+++ b/lib/vimfiles/indent/xhtml.vim
@@ -1,0 +1,12 @@
+" Vim indent file
+" Language:	XHTML
+" Maintainer:	Bram Moolenaar <Bram@vim.org> (for now)
+" Last Change:	2005 Jun 24
+
+" Only load this indent file when no other was loaded.
+if exists("b:did_indent")
+  finish
+endif
+
+" Handled like HTML for now.
+runtime! indent/html.vim
--- /dev/null
+++ b/lib/vimfiles/indent/xinetd.vim
@@ -1,0 +1,50 @@
+" Vim indent file
+" Language:         xinetd.conf(5) configuration file
+" Maintainer:       Nikolai Weibull <now@bitwi.se>
+" Latest Revision:  2006-12-20
+
+if exists("b:did_indent")
+  finish
+endif
+let b:did_indent = 1
+
+setlocal indentexpr=GetXinetdIndent()
+setlocal indentkeys=0{,0},!^F,o,O
+setlocal nosmartindent
+
+if exists("*GetXinetdIndent")
+  finish
+endif
+
+function s:count_braces(lnum, count_open)
+  let n_open = 0
+  let n_close = 0
+  let line = getline(a:lnum)
+  let pattern = '[{}]'
+  let i = match(line, pattern)
+  while i != -1
+    if synIDattr(synID(a:lnum, i + 1, 0), 'name') !~ 'ld\%(Comment\|String\)'
+      if line[i] == '{'
+        let n_open += 1
+      elseif line[i] == '}'
+        if n_open > 0
+          let n_open -= 1
+        else
+          let n_close += 1
+        endif
+      endif
+    endif
+    let i = match(line, pattern, i + 1)
+  endwhile
+  return a:count_open ? n_open : n_close
+endfunction
+
+function GetXinetdIndent()
+  let pnum = prevnonblank(v:lnum - 1)
+  if pnum == 0
+    return 0
+  endif
+
+  return indent(pnum) + s:count_braces(pnum, 1) * &sw
+        \ - s:count_braces(v:lnum, 0) * &sw
+endfunction
--- /dev/null
+++ b/lib/vimfiles/indent/xml.vim
@@ -1,0 +1,88 @@
+" Language:	xml
+" Maintainer:	Johannes Zellner <johannes@zellner.org>
+" Last Change:	Tue, 27 Apr 2004 14:54:59 CEST
+" Notes:	1) does not indent pure non-xml code (e.g. embedded scripts)
+"		2) will be confused by unbalanced tags in comments
+"		or CDATA sections.
+" TODO:		implement pre-like tags, see xml_indent_open / xml_indent_close
+
+" Only load this indent file when no other was loaded.
+if exists("b:did_indent")
+    finish
+endif
+let b:did_indent = 1
+
+" [-- local settings (must come before aborting the script) --]
+setlocal indentexpr=XmlIndentGet(v:lnum,1)
+setlocal indentkeys=o,O,*<Return>,<>>,<<>,/,{,}
+
+set cpo-=C
+
+if !exists('b:xml_indent_open')
+    let b:xml_indent_open = '.\{-}<\a'
+    " pre tag, e.g. <address>
+    " let b:xml_indent_open = '.\{-}<[/]\@!\(address\)\@!'
+endif
+
+if !exists('b:xml_indent_close')
+    let b:xml_indent_close = '.\{-}</'
+    " end pre tag, e.g. </address>
+    " let b:xml_indent_close = '.\{-}</\(address\)\@!'
+endif
+
+" [-- finish, if the function already exists --]
+if exists('*XmlIndentGet') | finish | endif
+
+fun! <SID>XmlIndentWithPattern(line, pat)
+    let s = substitute('x'.a:line, a:pat, "\1", 'g')
+    return strlen(substitute(s, "[^\1].*$", '', ''))
+endfun
+
+" [-- check if it's xml --]
+fun! <SID>XmlIndentSynCheck(lnum)
+    if '' != &syntax
+	let syn1 = synIDattr(synID(a:lnum, 1, 1), 'name')
+	let syn2 = synIDattr(synID(a:lnum, strlen(getline(a:lnum)) - 1, 1), 'name')
+	if '' != syn1 && syn1 !~ 'xml' && '' != syn2 && syn2 !~ 'xml'
+	    " don't indent pure non-xml code
+	    return 0
+	endif
+    endif
+    return 1
+endfun
+
+" [-- return the sum of indents of a:lnum --]
+fun! <SID>XmlIndentSum(lnum, style, add)
+    let line = getline(a:lnum)
+    if a:style == match(line, '^\s*</')
+	return (&sw *
+	\  (<SID>XmlIndentWithPattern(line, b:xml_indent_open)
+	\ - <SID>XmlIndentWithPattern(line, b:xml_indent_close)
+	\ - <SID>XmlIndentWithPattern(line, '.\{-}/>'))) + a:add
+    else
+	return a:add
+    endif
+endfun
+
+fun! XmlIndentGet(lnum, use_syntax_check)
+    " Find a non-empty line above the current line.
+    let lnum = prevnonblank(a:lnum - 1)
+
+    " Hit the start of the file, use zero indent.
+    if lnum == 0
+	return 0
+    endif
+
+    if a:use_syntax_check
+	if 0 == <SID>XmlIndentSynCheck(lnum) || 0 == <SID>XmlIndentSynCheck(a:lnum)
+	    return indent(a:lnum)
+	endif
+    endif
+
+    let ind = <SID>XmlIndentSum(lnum, -1, indent(lnum))
+    let ind = <SID>XmlIndentSum(a:lnum, 0, ind)
+
+    return ind
+endfun
+
+" vim:ts=8
--- /dev/null
+++ b/lib/vimfiles/indent/xsd.vim
@@ -1,0 +1,13 @@
+" Vim indent file
+" Language: 	.xsd files (XML Schema)
+" Maintainer:	Nobody
+" Last Change:	2005 Jun 09
+
+" Only load this indent file when no other was loaded.
+if exists("b:did_indent")
+  finish
+endif
+
+" Use XML formatting rules
+runtime! indent/xml.vim
+
--- /dev/null
+++ b/lib/vimfiles/indent/xslt.vim
@@ -1,0 +1,13 @@
+" Vim indent file
+" Language:    XSLT .xslt files
+" Maintainer:  David Fishburn <fishburn@ianywhere.com>
+" Last Change: Wed May 14 2003 8:48:41 PM
+
+" Only load this indent file when no other was loaded.
+if exists("b:did_indent")
+  finish
+endif
+
+" Use XML formatting rules
+runtime! indent/xml.vim
+
--- /dev/null
+++ b/lib/vimfiles/indent/yacc.vim
@@ -1,0 +1,41 @@
+" Vim indent file
+" Language:         YACC input file
+" Maintainer:       Nikolai Weibull <now@bitwi.se>
+" Latest Revision:  2006-12-20
+
+" Only load this indent file when no other was loaded.
+if exists("b:did_indent")
+  finish
+endif
+
+let b:did_indent = 1
+
+setlocal indentexpr=GetYaccIndent()
+setlocal indentkeys=!^F,o,O
+setlocal nosmartindent
+
+" Only define the function once.
+if exists("*GetYaccIndent")
+  finish
+endif
+
+function GetYaccIndent()
+  if v:lnum == 1
+    return 0
+  endif
+
+  let ind = indent(v:lnum - 1)
+  let line = getline(v:lnum - 1)
+
+  if line == ''
+    let ind = 0
+  elseif line =~ '^\w\+\s*:'
+    let ind = ind + matchend(line, '^\w\+\s*')
+  elseif line =~ '^\s*;'
+    let ind = 0
+  else
+    let ind = indent(v:lnum)
+  endif
+
+  return ind
+endfunction
--- /dev/null
+++ b/lib/vimfiles/indent/zsh.vim
@@ -1,0 +1,11 @@
+" Vim indent file
+" Language:	    Zsh Shell Script
+" Maintainer:       Nikolai Weibull <now@bitwi.se>
+" Latest Revision:  2006-04-19
+
+if exists("b:did_indent")
+  finish
+endif
+
+" Same as sh indenting for now.
+runtime! indent/sh.vim
--- /dev/null
+++ b/lib/vimfiles/indoff.vim
@@ -1,0 +1,11 @@
+" Vim support file to switch off loading indent files for file types
+"
+" Maintainer:	Bram Moolenaar <Bram@vim.org>
+" Last Change:	2001 Jun 11
+
+if exists("did_indent_on")
+  unlet did_indent_on
+endif
+
+" Remove all autocommands in the filetypeindent group
+silent! au! filetypeindent *
--- /dev/null
+++ b/lib/vimfiles/macmap.vim
@@ -1,0 +1,75 @@
+" System gvimrc file for Mac OS X
+" Author:	Benji Fisher <benji@member.AMS.org>
+" Last Change: Thu Mar 09 09:00 AM 2006 EST
+"
+" Define Mac-standard keyboard shortcuts.
+
+" We don't change 'cpoptions' here, because it would not be set properly when
+" a .vimrc file is found later.  Thus don't use line continuation and use
+" <special> in mappings.
+
+nnoremap <special> <D-n> :confirm enew<CR>
+vmap <special> <D-n> <Esc><D-n>gv
+imap <special> <D-n> <C-O><D-n>
+cmap <special> <D-n> <C-C><D-n>
+omap <special> <D-n> <Esc><D-n>
+
+nnoremap <special> <D-o> :browse confirm e<CR>
+vmap <special> <D-o> <Esc><D-o>gv
+imap <special> <D-o> <C-O><D-o>
+cmap <special> <D-o> <C-C><D-o>
+omap <special> <D-o> <Esc><D-o>
+
+nnoremap <silent> <special> <D-w> :if winheight(2) < 0 <Bar> confirm enew <Bar> else <Bar> confirm close <Bar> endif<CR>
+vmap <special> <D-w> <Esc><D-w>gv
+imap <special> <D-w> <C-O><D-w>
+cmap <special> <D-w> <C-C><D-w>
+omap <special> <D-w> <Esc><D-w>
+
+nnoremap <silent> <special> <D-s> :if expand("%") == ""<Bar>browse confirm w<Bar> else<Bar>confirm w<Bar>endif<CR>
+vmap <special> <D-s> <Esc><D-s>gv
+imap <special> <D-s> <C-O><D-s>
+cmap <special> <D-s> <C-C><D-s>
+omap <special> <D-s> <Esc><D-s>
+
+nnoremap <special> <D-S-s> :browse confirm saveas<CR>
+vmap <special> <D-S-s> <Esc><D-s>gv
+imap <special> <D-S-s> <C-O><D-s>
+cmap <special> <D-S-s> <C-C><D-s>
+omap <special> <D-S-s> <Esc><D-s>
+
+" From the Edit menu of SimpleText:
+nnoremap <special> <D-z> u
+vmap <special> <D-z> <Esc><D-z>gv
+imap <special> <D-z> <C-O><D-z>
+cmap <special> <D-z> <C-C><D-z>
+omap <special> <D-z> <Esc><D-z>
+
+vnoremap <special> <D-x> "+x
+
+vnoremap <special> <D-c> "+y
+
+cnoremap <special> <D-c> <C-Y>
+
+nnoremap <special> <D-v> "+gP
+cnoremap <special> <D-v> <C-R>+
+execute 'vnoremap <script> <special> <D-v>' paste#paste_cmd['v']
+execute 'inoremap <script> <special> <D-v>' paste#paste_cmd['i']
+
+nnoremap <silent> <special> <D-a> :if &slm != ""<Bar>exe ":norm gggH<C-O>G"<Bar> else<Bar>exe ":norm ggVG"<Bar>endif<CR>
+vmap <special> <D-a> <Esc><D-a>
+imap <special> <D-a> <Esc><D-a>
+cmap <special> <D-a> <C-C><D-a>
+omap <special> <D-a> <Esc><D-a>
+
+nnoremap <special> <D-f> /
+vmap <special> <D-f> <Esc><D-f>
+imap <special> <D-f> <Esc><D-f>
+cmap <special> <D-f> <C-C><D-f>
+omap <special> <D-f> <Esc><D-f>
+
+nnoremap <special> <D-g> n
+vmap <special> <D-g> <Esc><D-g>
+imap <special> <D-g> <C-O><D-g>
+cmap <special> <D-g> <C-C><D-g>
+omap <special> <D-g> <Esc><D-g>
--- /dev/null
+++ b/lib/vimfiles/macros/README.txt
@@ -1,0 +1,30 @@
+The macros in the maze, hanoi and urm directories can be used to test Vim for
+vi compatibility.  They have been written for vi to show its unlimited
+possibilities.	The life macros can be used for performance comparisons.
+
+hanoi	Macros that solve the tower of hanoi problem.
+life	Macros that run Conway's game of life.
+maze	Macros that solve a maze (amazing!).
+urm	Macros that simulate a simple computer: "Universal Register Machine"
+
+
+The other files contain some handy utilities.  They also serve as examples for
+how to use Vi and Vim functionality.
+
+dvorak			for when you use a Dvorak keyboard
+
+justify.vim		user function for justifying text
+
+matchit.vim + matchit.txt  make % match if-fi, HTML tags, and much more
+
+less.sh + less.vim	make Vim work like less (or more)
+
+shellmenu.vim		menus for editing shell scripts in the GUI version
+
+swapmous.vim		swap left and right mouse buttons
+
+editexisting.vim	when editing a file that is already edited with
+			another Vim instance
+
+This one is only for Unix.  It can be found in the extra archive:
+file_select.vim		macros that make a handy file selector
--- /dev/null
+++ b/lib/vimfiles/macros/dvorak
@@ -1,0 +1,164 @@
+When using a dvorak keyboard this file may be of help to you.
+These mappings have been made by Lawrence Kesteloot <kesteloo@cs.unc.edu>.
+What they do is that the most often used keys, like hjkl, are put in a more
+easy to use position.
+It may take some time to learn using this.
+
+Put these lines in your .vimrc:
+-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
+" Key to go into dvorak mode:
+map ,d :source ~/.dvorak
+" Key to get out of dvorak mode:
+map ,q :source ~/.qwerty
+-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
+
+write these lines into the file ~/.dvorak:
+-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
+" Dvorak keyboard, only in insert mode and ex mode.
+" You may want to add a list of map's too.
+imap! a a
+imap! b x
+imap! c j
+imap! d e
+imap! e .
+imap! f u
+imap! g i
+imap! h d
+imap! i c
+imap! j h
+imap! k t
+imap! l n
+imap! m m
+imap! n b
+imap! o r
+imap! p l
+imap! q '
+imap! r p
+imap! s o
+imap! t y
+imap! u g
+imap! v k
+imap! w ,
+imap! x q
+imap! y f
+imap! z ;
+imap! ; s
+imap! ' -
+imap! " _
+imap! , w
+imap! . v
+imap! / z
+imap! A A
+imap! B X
+imap! C J
+imap! D E
+imap! E >
+imap! F U
+imap! G I
+imap! H D
+imap! I C
+imap! J H
+imap! K T
+imap! L N
+imap! M M
+imap! N B
+imap! O R
+imap! P L
+imap! Q "
+imap! R P
+imap! S O
+imap! T Y
+imap! U G
+imap! V K
+imap! W <
+imap! X Q
+imap! Y F
+imap! Z :
+imap! < W
+imap! > V
+imap! ? Z
+imap! : S
+imap! [ /
+imap! ] =
+imap! { ?
+imap! } +
+imap! - [
+imap! _ {
+imap! = ]
+imap! + }
+-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
+
+write these lines into the file ~/.qwerty
+-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
+" Qwerty keyboard
+unmap! a
+unmap! b
+unmap! c
+unmap! d
+unmap! e
+unmap! f
+unmap! g
+unmap! h
+unmap! i
+unmap! j
+unmap! k
+unmap! l
+unmap! m
+unmap! n
+unmap! o
+unmap! p
+unmap! q
+unmap! r
+unmap! s
+unmap! t
+unmap! u
+unmap! v
+unmap! w
+unmap! x
+unmap! y
+unmap! z
+unmap! ;
+unmap! '
+unmap! \"
+unmap! ,
+unmap! .
+unmap! /
+unmap! A
+unmap! B
+unmap! C
+unmap! D
+unmap! E
+unmap! F
+unmap! G
+unmap! H
+unmap! I
+unmap! J
+unmap! K
+unmap! L
+unmap! M
+unmap! N
+unmap! O
+unmap! P
+unmap! Q
+unmap! R
+unmap! S
+unmap! T
+unmap! U
+unmap! V
+unmap! W
+unmap! X
+unmap! Y
+unmap! Z
+unmap! <
+unmap! >
+unmap! ?
+unmap! :
+unmap! [
+unmap! ]
+unmap! {
+unmap! }
+unmap! -
+unmap! _
+unmap! =
+unmap! +
+-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
--- /dev/null
+++ b/lib/vimfiles/macros/editexisting.vim
@@ -1,0 +1,114 @@
+" Vim Plugin:	Edit the file with an existing Vim if possible
+" Maintainer:	Bram Moolenaar
+" Last Change:	2007 Mar 17
+
+" This is a plugin, drop it in your (Unix) ~/.vim/plugin or (Win32)
+" $VIM/vimfiles/plugin directory.  Or make a symbolic link, so that you
+" automatically use the latest version.
+
+" This plugin serves two purposes:
+" 1. On startup, if we were invoked with one file name argument and the file
+"    is not modified then try to find another Vim instance that is editing
+"    this file.  If there is one then bring it to the foreground and exit.
+" 2. When a file is edited and a swap file exists for it, try finding that
+"    other Vim and bring it to the foreground.  Requires Vim 7, because it
+"    uses the SwapExists autocommand event.
+
+" Function that finds the Vim instance that is editing "filename" and brings
+" it to the foreground.
+func s:EditElsewhere(filename)
+  let fname_esc = substitute(a:filename, "'", "''", "g")
+
+  let servers = serverlist()
+  while servers != ''
+    " Get next server name in "servername"; remove it from "servers".
+    let i = match(servers, "\n")
+    if i == -1
+      let servername = servers
+      let servers = ''
+    else
+      let servername = strpart(servers, 0, i)
+      let servers = strpart(servers, i + 1)
+    endif
+
+    " Skip ourselves.
+    if servername ==? v:servername
+      continue
+    endif
+
+    " Check if this server is editing our file.
+    if remote_expr(servername, "bufloaded('" . fname_esc . "')")
+      " Yes, bring it to the foreground.
+      if has("win32")
+	call remote_foreground(servername)
+      endif
+      call remote_expr(servername, "foreground()")
+
+      if remote_expr(servername, "exists('*EditExisting')")
+	" Make sure the file is visible in a window (not hidden).
+	" If v:swapcommand exists and is set, send it to the server.
+	if exists("v:swapcommand")
+	  let c = substitute(v:swapcommand, "'", "''", "g")
+	  call remote_expr(servername, "EditExisting('" . fname_esc . "', '" . c . "')")
+	else
+	  call remote_expr(servername, "EditExisting('" . fname_esc . "', '')")
+	endif
+      endif
+
+      if !(has('vim_starting') && has('gui_running') && has('gui_win32'))
+	" Tell the user what is happening.  Not when the GUI is starting
+	" though, it would result in a message box.
+	echomsg "File is being edited by " . servername
+	sleep 2
+      endif
+      return 'q'
+    endif
+  endwhile
+  return ''
+endfunc
+
+" When the plugin is loaded and there is one file name argument: Find another
+" Vim server that is editing this file right now.
+if argc() == 1 && !&modified
+  if s:EditElsewhere(expand("%:p")) == 'q'
+    quit
+  endif
+endif
+
+" Setup for handling the situation that an existing swap file is found.
+try
+  au! SwapExists * let v:swapchoice = s:EditElsewhere(expand("<afile>:p"))
+catch
+  " Without SwapExists we don't do anything for ":edit" commands
+endtry
+
+" Function used on the server to make the file visible and possibly execute a
+" command.
+func! EditExisting(fname, command)
+  " Get the window number of the file in the current tab page.
+  let winnr = bufwinnr(a:fname)
+  if winnr <= 0
+    " Not found, look in other tab pages.
+    let bufnr = bufnr(a:fname)
+    for i in range(tabpagenr('$'))
+      if index(tabpagebuflist(i + 1), bufnr) >= 0
+	" Make this tab page the current one and find the window number.
+	exe 'tabnext ' . (i + 1)
+	let winnr = bufwinnr(a:fname)
+	break;
+      endif
+    endfor
+  endif
+
+  if winnr > 0
+    exe winnr . "wincmd w"
+  else
+    exe "split " . escape(a:fname, ' #%"|')
+  endif
+
+  if a:command != ''
+    exe "normal " . a:command
+  endif
+
+  redraw
+endfunc
--- /dev/null
+++ b/lib/vimfiles/macros/hanoi/click.me
@@ -1,0 +1,14 @@
+
+
+See Vim solve the towers of Hanoi!
+
+Instructions:
+   type ":so hanoi.vim<RETURN>" to load the macros
+   type "g" to start it
+
+and watch it go.
+
+     to quit type ":q!<RETURN>"
+to interrupt type CTRL-C
+
+(This text will disappear as soon as you type "g")
--- /dev/null
+++ b/lib/vimfiles/macros/hanoi/hanoi.vim
@@ -1,0 +1,64 @@
+set remap
+set noterse
+set wrapscan
+" to set the height of the tower, change the digit in the following
+" two lines to the height you want (select from 1 to 9)
+map t 7
+map! t 7
+map L 1G/t
X/^0
$P1GJ$An$BGC0e$X0E0F$X/T
@f
@h
$A1GJ@f0l$Xn$PU
+map g IL
+
+map J /^0[^t]*$
+map X x
+map P p
+map U L
+map A "fyl
+map B "hyl
+map C "fp
+map e "fy2l
+map E "hp
+map F "hy2l
+
+" initialisations:
+" KM	cleanup buffer
+" Y	create tower of desired height
+" NOQ	copy it and inster a T
+" NO	copy this one
+" S	change last char into a $
+" R	change last char in previous line into a n
+" T	insert two lines containing a zero
+" V	add a last line containing a backslash
+map I KMYNOQNOSkRTV
+
+"create empty line
+map K 1Go
+
+"delete to end of file
+map M dG
+
+"yank one line
+map N yy
+
+"put
+map O p
+
+"delete more than height-of-tower characters
+map q tllD
+
+"create a tower of desired height
+map Y o0123456789Z0q
+
+"insert a T in column 1
+map Q 0iT
+
+"substitute last character with a n
+map R $rn
+
+"substitute last character with a $
+map S $r$
+
+"insert two lines containing a zero
+map T ko0
0


+
+"add a backslash at the end
+map V Go/
--- /dev/null
+++ b/lib/vimfiles/macros/hanoi/poster
@@ -1,0 +1,36 @@
+Article 2913 of alt.sources:
+Path: oce-rd1!hp4nl!mcsun!uunet!munnari.oz.au!metro!cluster!swift!softway!otc!gregm
+From: gregm@otc.otca.oz.au (Greg McFarlane)
+Newsgroups: comp.sources.d,alt.sources,comp.editors
+Subject: VI SOLVES HANOI
+Message-ID: <2323@otc.otca.oz>
+Date: 19 Feb 91 01:32:14 GMT
+Sender: news@otc.otca.oz
+Reply-To: gregm@otc.otca.oz.au (Greg McFarlane)
+Organization: OTC Development Unit, Australia
+Lines: 80
+Xref: oce-rd1 comp.sources.d:5702 alt.sources:2913 comp.editors:2313
+
+Submitted-by: gregm@otc.otca.oz.au
+Archive-name: hanoi.vi.macros/part01
+
+Everyone seems to be writing stupid Tower of Hanoi programs.
+Well, here is the stupidest of them all: the hanoi solving vi macros.
+
+Save this article, unshar it, and run uudecode on hanoi.vi.macros.uu.
+This will give you the macro file hanoi.vi.macros.
+Then run vi (with no file: just type "vi") and type:
+	:so hanoi.vi.macros
+	g
+and watch it go.
+
+The default height of the tower is 7 but can be easily changed by editing
+the macro file.
+
+The disks aren't actually shown in this version, only numbers representing
+each disk, but I believe it is possible to write some macros to show the
+disks moving about as well. Any takers?
+
+(For maze solving macros, see alt.sources or comp.editors)
+
+Greg
--- /dev/null
+++ b/lib/vimfiles/macros/justify.vim
@@ -1,0 +1,316 @@
+" Function to left and rigt align text.
+"
+" Written by:	Preben "Peppe" Guldberg <c928400@student.dtu.dk>
+" Created:	980806 14:13 (or around that time anyway)
+" Revised:	001103 00:36 (See "Revisions" below)
+
+
+" function Justify( [ textwidth [, maxspaces [, indent] ] ] )
+"
+" Justify()  will  left  and  right  align  a  line  by  filling  in  an
+" appropriate amount of spaces.  Extra  spaces  are  added  to  existing
+" spaces starting from the right side of the line.  As an  example,  the
+" following documentation has been justified.
+"
+" The function takes the following arguments:
+
+" textwidth argument
+" ------------------
+" If not specified, the value of the 'textwidth'  option  is  used.   If
+" 'textwidth' is zero a value of 80 is used.
+"
+" Additionally the arguments 'tw' and '' are  accepted.   The  value  of
+" 'textwidth' will be used. These are handy, if you just want to specify
+" the maxspaces argument.
+
+" maxspaces argument
+" ------------------
+" If specified, alignment will only be done, if the  longest  space  run
+" after alignment is no longer than maxspaces.
+"
+" An argument of '' is accepted, should the user  like  to  specify  all
+" arguments.
+"
+" To aid user defined commands, negative  values  are  accepted  aswell.
+" Using a negative value specifies the default behaviour: any length  of
+" space runs will be used to justify the text.
+
+" indent argument
+" ---------------
+" This argument specifies how a line should be indented. The default  is
+" to keep the current indentation.
+"
+" Negative  values:  Keep  current   amount   of   leading   whitespace.
+" Positive values: Indent all lines with leading whitespace  using  this
+" amount of whitespace.
+"
+" Note that the value 0, needs to be quoted as  a  string.   This  value
+" leads to a left flushed text.
+"
+" Additionally units of  'shiftwidth'/'sw'  and  'tabstop'/'ts'  may  be
+" added. In this case, if the value of indent is positive, the amount of
+" whitespace to be  added  will  be  multiplied  by  the  value  of  the
+" 'shiftwidth' and 'tabstop' settings.  If these  units  are  used,  the
+"  argument must  be  given  as  a  string,  eg.   Justify('','','2sw').
+"
+" If the values of 'sw' or 'tw' are negative, they  are  treated  as  if
+" they were 0, which means that the text is flushed left.  There  is  no
+" check if a negative number prefix is used to  change  the  sign  of  a
+" negative 'sw' or 'ts' value.
+"
+" As with the other arguments,  ''  may  be  used  to  get  the  default
+" behaviour.
+
+
+" Notes:
+"
+" If the line, adjusted for space runs and leading/trailing  whitespace,
+" is wider than the used textwidth, the line will be left untouched  (no
+" whitespace removed).  This should be equivalent to  the  behaviour  of
+" :left, :right and :center.
+"
+" If the resulting line is shorter than the used textwidth  it  is  left
+" untouched.
+"
+" All space runs in the line  are  truncated  before  the  alignment  is
+" carried out.
+"
+" If you have set 'noexpandtab', :retab!  is used to replace space  runs
+"  with whitespace  using  the  value  of  'tabstop'.   This  should  be
+" conformant with :left, :right and :center.
+"
+" If joinspaces is set, an extra space is added after '.', '?' and  '!'.
+" If 'cpooptions' include 'j', extra space  is  only  added  after  '.'.
+" (This may on occasion conflict with maxspaces.)
+
+
+" Related mappings:
+"
+" Mappings that will align text using the current text width,  using  at
+" most four spaces in a  space  run  and  keeping  current  indentation.
+nmap _j :%call Justify('tw',4)<CR>
+vmap _j :call Justify('tw',4)<CR>
+"
+" Mappings that will remove space runs and format lines (might be useful
+" prior to aligning the text).
+nmap ,gq :%s/\s\+/ /g<CR>gq1G
+vmap ,gq :s/\s\+/ /g<CR>gvgq
+
+
+" User defined command:
+"
+" The following is an ex command that works as a shortcut to the Justify
+" function.  Arguments to Justify() can  be  added  after  the  command.
+com! -range -nargs=* Justify <line1>,<line2>call Justify(<f-args>)
+"
+" The following commands are all equivalent:
+"
+" 1. Simplest use of Justify():
+"       :call Justify()
+"       :Justify
+"
+" 2. The _j mapping above via the ex command:
+"       :%Justify tw 4
+"
+" 3.  Justify  visualised  text  at  72nd  column  while  indenting  all
+" previously indented text two shiftwidths
+"       :'<,'>call Justify(72,'','2sw')
+"       :'<,'>Justify 72 -1 2sw
+"
+" This documentation has been justified  using  the  following  command:
+":se et|kz|1;/^" function Justify(/+,'z-g/^" /s/^" //|call Justify(70,3)|s/^/" /
+
+" Revisions:
+" 001103: If 'joinspaces' was set, calculations could be wrong.
+"	  Tabs at start of line could also lead to errors.
+"	  Use setline() instead of "exec 's/foo/bar/' - safer.
+"	  Cleaned up the code a bit.
+"
+" Todo:	  Convert maps to the new script specific form
+
+" Error function
+function! Justify_error(message)
+    echohl Error
+    echo "Justify([tw, [maxspaces [, indent]]]): " . a:message
+    echohl None
+endfunction
+
+
+" Now for the real thing
+function! Justify(...) range
+
+    if a:0 > 3
+    call Justify_error("Too many arguments (max 3)")
+    return 1
+    endif
+
+    " Set textwidth (accept 'tw' and '' as arguments)
+    if a:0 >= 1
+	if a:1 =~ '^\(tw\)\=$'
+	    let tw = &tw
+	elseif a:1 =~ '^\d\+$'
+	    let tw = a:1
+	else
+	    call Justify_error("tw must be a number (>0), '' or 'tw'")
+	    return 2
+	endif
+    else
+	let tw = &tw
+    endif
+    if tw == 0
+	let tw = 80
+    endif
+
+    " Set maximum number of spaces between WORDs
+    if a:0 >= 2
+	if a:2 == ''
+	    let maxspaces = tw
+	elseif a:2 =~ '^-\d\+$'
+	    let maxspaces = tw
+	elseif a:2 =~ '^\d\+$'
+	    let maxspaces = a:2
+	else
+	    call Justify_error("maxspaces must be a number or ''")
+	    return 3
+	endif
+    else
+	let maxspaces = tw
+    endif
+    if maxspaces <= 1
+	call Justify_error("maxspaces should be larger than 1")
+	return 4
+    endif
+
+    " Set the indentation style (accept sw and ts units)
+    let indent_fix = ''
+    if a:0 >= 3
+	if (a:3 == '') || a:3 =~ '^-[1-9]\d*\(shiftwidth\|sw\|tabstop\|ts\)\=$'
+	    let indent = -1
+	elseif a:3 =~ '^-\=0\(shiftwidth\|sw\|tabstop\|ts\)\=$'
+	    let indent = 0
+	elseif a:3 =~ '^\d\+\(shiftwidth\|sw\|tabstop\|ts\)\=$'
+	    let indent = substitute(a:3, '\D', '', 'g')
+	elseif a:3 =~ '^\(shiftwidth\|sw\|tabstop\|ts\)$'
+	    let indent = 1
+	else
+	    call Justify_error("indent: a number with 'sw'/'ts' unit")
+	    return 5
+	endif
+	if indent >= 0
+	    while indent > 0
+		let indent_fix = indent_fix . ' '
+		let indent = indent - 1
+	    endwhile
+	    let indent_sw = 0
+	    if a:3 =~ '\(shiftwidth\|sw\)'
+		let indent_sw = &sw
+	    elseif a:3 =~ '\(tabstop\|ts\)'
+		let indent_sw = &ts
+	    endif
+	    let indent_fix2 = ''
+	    while indent_sw > 0
+		let indent_fix2 = indent_fix2 . indent_fix
+		let indent_sw = indent_sw - 1
+	    endwhile
+	    let indent_fix = indent_fix2
+	endif
+    else
+	let indent = -1
+    endif
+
+    " Avoid substitution reports
+    let save_report = &report
+    set report=1000000
+
+    " Check 'joinspaces' and 'cpo'
+    if &js == 1
+	if &cpo =~ 'j'
+	    let join_str = '\(\. \)'
+	else
+	    let join_str = '\([.!?!] \)'
+	endif
+    endif
+
+    let cur = a:firstline
+    while cur <= a:lastline
+
+	let str_orig = getline(cur)
+	let save_et = &et
+	set et
+	exec cur . "retab"
+	let &et = save_et
+	let str = getline(cur)
+
+	let indent_str = indent_fix
+	let indent_n = strlen(indent_str)
+	" Shall we remember the current indentation
+	if indent < 0
+	    let indent_orig = matchstr(str_orig, '^\s*')
+	    if strlen(indent_orig) > 0
+		let indent_str = indent_orig
+		let indent_n = strlen(matchstr(str, '^\s*'))
+	    endif
+	endif
+
+	" Trim trailing, leading and running whitespace
+	let str = substitute(str, '\s\+$', '', '')
+	let str = substitute(str, '^\s\+', '', '')
+	let str = substitute(str, '\s\+', ' ', 'g')
+	let str_n = strlen(str)
+
+	" Possible addition of space after punctuation
+	if exists("join_str")
+	    let str = substitute(str, join_str, '\1 ', 'g')
+	endif
+	let join_n = strlen(str) - str_n
+
+	" Can extraspaces be added?
+	" Note that str_n may be less than strlen(str) [joinspaces above]
+	if strlen(str) < tw - indent_n && str_n > 0
+	    " How many spaces should be added
+	    let s_add = tw - str_n - indent_n - join_n
+	    let s_nr  = strlen(substitute(str, '\S', '', 'g') ) - join_n
+	    let s_dup = s_add / s_nr
+	    let s_mod = s_add % s_nr
+
+	    " Test if the changed line fits with tw
+	    if 0 <= (str_n + (maxspaces - 1)*s_nr + indent_n) - tw
+
+		" Duplicate spaces
+		while s_dup > 0
+		    let str = substitute(str, '\( \+\)', ' \1', 'g')
+		    let s_dup = s_dup - 1
+		endwhile
+
+		" Add extra spaces from the end
+		while s_mod > 0
+		    let str = substitute(str, '\(\(\s\+\S\+\)\{' . s_mod .  '}\)$', ' \1', '')
+		    let s_mod = s_mod - 1
+		endwhile
+
+		" Indent the line
+		if indent_n > 0
+		    let str = substitute(str, '^', indent_str, '' )
+		endif
+
+		" Replace the line
+		call setline(cur, str)
+
+		" Convert to whitespace
+		if &et == 0
+		    exec cur . 'retab!'
+		endif
+
+	    endif   " Change of line
+	endif	" Possible change
+
+	let cur = cur + 1
+    endwhile
+
+    norm ^
+
+    let &report = save_report
+
+endfunction
+
+" EOF	vim: tw=78 ts=8 sw=4 sts=4 noet ai
--- /dev/null
+++ b/lib/vimfiles/macros/less.sh
@@ -1,0 +1,9 @@
+#!/bin/sh
+# Shell script to start Vim with less.vim.
+# Read stdin if no arguments were given.
+
+if test $# = 0; then
+  vim --cmd 'let no_plugin_maps = 1' -c 'runtime! macros/less.vim' -
+else
+  vim --cmd 'let no_plugin_maps = 1' -c 'runtime! macros/less.vim' "$@"
+fi
--- /dev/null
+++ b/lib/vimfiles/macros/less.vim
@@ -1,0 +1,244 @@
+" Vim script to work like "less"
+" Maintainer:	Bram Moolenaar <Bram@vim.org>
+" Last Change:	2006 Dec 05
+
+" Avoid loading this file twice, allow the user to define his own script.
+if exists("loaded_less")
+  finish
+endif
+let loaded_less = 1
+
+" If not reading from stdin, skip files that can't be read.
+" Exit if there is no file at all.
+if argc() > 0
+  let s:i = 0
+  while 1
+    if filereadable(argv(s:i))
+      if s:i != 0
+	sleep 3
+      endif
+      break
+    endif
+    if isdirectory(argv(s:i))
+      echomsg "Skipping directory " . argv(s:i)
+    elseif getftime(argv(s:i)) < 0
+      echomsg "Skipping non-existing file " . argv(s:i)
+    else
+      echomsg "Skipping unreadable file " . argv(s:i)
+    endif
+    echo "\n"
+    let s:i = s:i + 1
+    if s:i == argc()
+      quit
+    endif
+    next
+  endwhile
+endif
+
+set nocp
+syntax on
+set so=0
+set hlsearch
+set incsearch
+nohlsearch
+" Don't remember file names and positions
+set viminfo=
+set nows
+" Inhibit screen updates while searching
+let s:lz = &lz
+set lz
+
+" Used after each command: put cursor at end and display position
+if &wrap
+  noremap <SID>L L0:redraw<CR>:file<CR>
+  au VimEnter * normal! L0
+else
+  noremap <SID>L Lg0:redraw<CR>:file<CR>
+  au VimEnter * normal! Lg0
+endif
+
+" When reading from stdin don't consider the file modified.
+au VimEnter * set nomod
+
+" Can't modify the text
+set noma
+
+" Give help
+noremap h :call <SID>Help()<CR>
+map H h
+fun! s:Help()
+  echo "<Space>   One page forward          b         One page backward"
+  echo "d         Half a page forward       u         Half a page backward"
+  echo "<Enter>   One line forward          k         One line backward"
+  echo "G         End of file               g         Start of file"
+  echo "N%        percentage in file"
+  echo "\n"
+  echo "/pattern  Search for pattern        ?pattern  Search backward for pattern"
+  echo "n         next pattern match        N         Previous pattern match"
+  echo "\n"
+  echo ":n<Enter> Next file                 :p<Enter> Previous file"
+  echo "\n"
+  echo "q         Quit                      v         Edit file"
+  let i = input("Hit Enter to continue")
+endfun
+
+" Scroll one page forward
+noremap <script> <Space> :call <SID>NextPage()<CR><SID>L
+map <C-V> <Space>
+map f <Space>
+map <C-F> <Space>
+map z <Space>
+map <Esc><Space> <Space>
+fun! s:NextPage()
+  if line(".") == line("$")
+    if argidx() + 1 >= argc()
+      quit
+    endif
+    next
+    1
+  else
+    exe "normal! \<C-F>"
+  endif
+endfun
+
+" Re-read file and page forward "tail -f"
+map F :e<CR>G<SID>L:sleep 1<CR>F
+
+" Scroll half a page forward
+noremap <script> d <C-D><SID>L
+map <C-D> d
+
+" Scroll one line forward
+noremap <script> <CR> <C-E><SID>L
+map <C-N> <CR>
+map e <CR>
+map <C-E> <CR>
+map j <CR>
+map <C-J> <CR>
+
+" Scroll one page backward
+noremap <script> b <C-B><SID>L
+map <C-B> b
+map w b
+map <Esc>v b
+
+" Scroll half a page backward
+noremap <script> u <C-U><SID>L
+noremap <script> <C-U> <C-U><SID>L
+
+" Scroll one line backward
+noremap <script> k <C-Y><SID>L
+map y k
+map <C-Y> k
+map <C-P> k
+map <C-K> k
+
+" Redraw
+noremap <script> r <C-L><SID>L
+noremap <script> <C-R> <C-L><SID>L
+noremap <script> R <C-L><SID>L
+
+" Start of file
+noremap <script> g gg<SID>L
+map < g
+map <Esc>< g
+
+" End of file
+noremap <script> G G<SID>L
+map > G
+map <Esc>> G
+
+" Go to percentage
+noremap <script> % %<SID>L
+map p %
+
+" Search
+noremap <script> / H$:call <SID>Forward()<CR>/
+if &wrap
+  noremap <script> ? H0:call <SID>Backward()<CR>?
+else
+  noremap <script> ? Hg0:call <SID>Backward()<CR>?
+endif
+
+fun! s:Forward()
+  " Searching forward
+  noremap <script> n H$nzt<SID>L
+  if &wrap
+    noremap <script> N H0Nzt<SID>L
+  else
+    noremap <script> N Hg0Nzt<SID>L
+  endif
+  cnoremap <silent> <script> <CR> <CR>:cunmap <lt>CR><CR>zt<SID>L
+endfun
+
+fun! s:Backward()
+  " Searching backward
+  if &wrap
+    noremap <script> n H0nzt<SID>L
+  else
+    noremap <script> n Hg0nzt<SID>L
+  endif
+  noremap <script> N H$Nzt<SID>L
+  cnoremap <silent> <script> <CR> <CR>:cunmap <lt>CR><CR>zt<SID>L
+endfun
+
+call s:Forward()
+
+" Quitting
+noremap q :q<CR>
+
+" Switch to editing (switch off less mode)
+map v :silent call <SID>End()<CR>
+fun! s:End()
+  set ma
+  if exists('s:lz')
+    let &lz = s:lz
+  endif
+  unmap h
+  unmap H
+  unmap <Space>
+  unmap <C-V>
+  unmap f
+  unmap <C-F>
+  unmap z
+  unmap <Esc><Space>
+  unmap F
+  unmap d
+  unmap <C-D>
+  unmap <CR>
+  unmap <C-N>
+  unmap e
+  unmap <C-E>
+  unmap j
+  unmap <C-J>
+  unmap b
+  unmap <C-B>
+  unmap w
+  unmap <Esc>v
+  unmap u
+  unmap <C-U>
+  unmap k
+  unmap y
+  unmap <C-Y>
+  unmap <C-P>
+  unmap <C-K>
+  unmap r
+  unmap <C-R>
+  unmap R
+  unmap g
+  unmap <
+  unmap <Esc><
+  unmap G
+  unmap >
+  unmap <Esc>>
+  unmap %
+  unmap p
+  unmap n
+  unmap N
+  unmap q
+  unmap v
+  unmap /
+  unmap ?
+endfun
+
+" vim: sw=2
--- /dev/null
+++ b/lib/vimfiles/macros/life/click.me
@@ -1,0 +1,9 @@
+
+To run the "Conway's game of life" macros:
+
+  1.  Type ":so life.vim".  This loads the macros.
+  2.  Type "g" to run the macros.
+  3.  Type CTRL-C to interrupt.
+  4.  Type ":q!" to get out.
+
+See life.vim for more advanced usage.
--- /dev/null
+++ b/lib/vimfiles/macros/life/life.vim
@@ -1,0 +1,260 @@
+" Macros to play Conway's Game of Life in vi
+" Version 1.0m: edges wrap
+" by Eli-the-Bearded (eli@netusa.net), Sept 1996
+" This file may be free distributed so long as these credits remain unchanged.
+"
+" Modified by Bram Moolenaar (Bram@vim.org), 1996 Sept 10
+" - Made it quite a bit faster, but now needs search patterns in the text
+" - Changed the order of mappings to top-down.
+" - Made "g" run the whole thing, "C" run one generation.
+" - Added support for any uppercase character instead of 'X'
+"
+" Rules:
+"   If a germ has 0 or 1 live neighbors it dies of loneliness
+"   If a germ has 2 or 3 live neighbors it survives
+"   If a germ has 4 to 8 live neighbors it dies of starvation
+"   If an empty box has 3 live neighbors a new germ is born
+"
+"   A new born germ is an "A".	Every generation it gets older: B, C, etc.
+"   A germ dies of old age when it reaches "Z".
+"
+" Notice the rules do not mention edges. This version has the edges wrap
+" around. I have an earlier version that offers the option of live edges or
+" dead edges. Email me if you are interested. -Eli-
+"
+" Note: This is slow!  One generation may take up to ten minutes (depends on
+" your computer and the vi version).
+"
+" Quite a lot of the messy stuff is to work around the vi error "Can't yank
+" inside global/macro".  Still doesn't work for all versions of vi.
+"
+" To use these macros:
+"
+" vi		start vi/vim
+"
+" :so life.mac	Source this file
+"
+" g		'g'o!  runs everything until interrupted: "IR".
+"
+" I		Initialize everything. A board will be drawn at the end
+"		of the current buffer. All line references in these macros
+"		are relative to the end of the file and playing the game
+"		can be done safely with any file as the current buffer.
+"
+"	Change the left field with spaces and uppercase letters to suit
+"	your taste.
+"
+" C		'C'ompute one generation.
+" +		idem, time running one generation.
+" R		'R'un 'C'ompute until interrupted.
+" i<nr><Esc>z	Make a number the only thing on the current line and use
+"		'z' to time that many generations.
+"
+" Time to run 30 generations on my 233 AMD K6 (FreeBSD 3.0):
+"   vim   5.4 xterm	51 sec
+"   gvim  5.4 Athena	42 sec
+"   gvim  5.4 Motif	42 sec
+"   gvim  5.4 GTK	50 sec
+"   nvi   1.79 xterm	58 sec
+"   vi	  3.7 xterm	2 min 30 sec
+"   Elvis 2.1 xterm	7 min 50 sec
+"   Elvis 2.1 X11	6 min 31 sec
+"
+" Time to run 30 generations on my 850 AMD Duron (FreeBSD 4.2):
+"   vim   5.8   xterm    21 sec
+"   vim   6.0   xterm    24 sec
+"   vim   6.0   Motif    32 sec
+"   nvi   1.79  xterm	 29 sec
+"   vi    3.7   xterm    32 sec
+"   elvis 2.1.4 xterm    34 sec
+"
+" And now the macros, more or less in top-down order.
+"
+"  ----- macros that can be used by the human -----
+"
+" 'g'o: 'I'nitialize and then 'R'un 'C'ompute recursively (used by the human)
+map g IR
+"
+"
+" 'R'un 'C'ompute recursively (used by the human and 'g'o)
+map R CV
+" work around "tail recursion" problem in vi, "V" == "R".
+map V R
+"
+"
+" 'I'nitialize the board (used by the human and 'g'o)
+map I G)0)0)0)0)1)0)0)2)0)0)0)0,ok,-11k,-,R,IIN
+"
+"
+" 'C'ompute next generation (used by the human and others)
+map C T>>>>>>>>B&
+"
+"
+" Time running one generation (used by the human)
+map + <1C<2
+"
+"
+" Time running N generations, where N is the number on the current line.
+" (used by the human)
+map z ,^,&,*,&<1,*<2
+"
+"  ----- END of macros that can be used by the human -----
+"
+"  ----- Initialisation -----
+"
+map ,- :s/./-/g
+map ,o oPut 'X's in the left box, then hit 'C' or 'R'
+map ,R 03stop
+"
+" Write a new line (used by 'I'nitialize board)
+map )0 o-                    --....................--....................-
+map )1 o-        VIM         --....................--....................-
+map )2 o-       LIVES        --....................--....................-
+"
+"
+" Initialisation of the pattern/command to execute for working out a square.
+" Pattern is: "#<germ><count>"
+" where <germ>   is " " if the current germ is dead, "X" when living.
+"       <count>  is the number of living neighbours (including current germ)
+"                expressed in X's
+"
+map ,Il8 O#XXXXXXXXXX .`a22lr 
+map ,Id8 o# XXXXXXXX .`a22lr 
+map ,Il7 o#XXXXXXXXX .`a22lr 
+map ,Id7 o# XXXXXXX .`a22lr 
+map ,Il6 o#XXXXXXXX .`a22lr 
+map ,Id6 o# XXXXXX .`a22lr 
+map ,Il5 o#XXXXXXX .`a22lr 
+map ,Id5 o# XXXXX .`a22lr 
+map ,Il4 o#XXXXXX .`a22lr 
+map ,Id4 o# XXXX .`a22lr 
+map ,Il3 o#XXXXX .,a
+map ,Id3 o# XXX .`a22lrA
+map ,Il2 o#XXXX .,a
+map ,Id2 o# XX .`a22lr 
+map ,Il1 o#XXX .`a22lr 
+map ,Id1 o# X .`a22lr 
+map ,Il0 o#XX .`a22lr 
+map ,Id0 o#  .`a22lr 
+"
+" Patterns used to replace a germ with it's next generation
+map ,Iaa o=AB =BC =CD =DE =EF =FG =GH =HI =IJ =JK =KL =LM =MN =NO =OP =PQ =QR
+map ,Iab o=RS =ST =TU =UV =VW =WX =XY =YZ =Z 
+"
+" Insert the searched patterns above the board
+map ,IIN G?^top
,Il8,Id8,Il7,Id7,Il6,Id6,Il5,Id5,Il4,Id4,Il3,Id3,Il2,Id2,Il1,Id1,Il0,Id0,Iaa,Iab
+"
+"  ----- END of Initialisation -----
+"
+"  ----- Work out one line -----
+"
+" Work out 'T'op line (used by show next)
+map T G,c2k,!9k,@,#j>2k,$j
+"
+" Work out 'B'ottom line (used by show next)
+map B ,%k>,$
+"
+" Work out a line (used by show next, work out top and bottom lines)
+map > 0 LWWWWWWWWWWWWWWWWWW,rj
+"
+" Refresh board (used by show next)
+map & :%s/^\(-[ A-Z]*-\)\(-[ A-Z]*-\)\(-[.]*-\)$/\2\3\3/
+"
+"
+" Work around vi multiple yank/put in a single macro limitation
+" (used by work out top and/or bottom line)
+map ,$ dd
+map ,% "cp
+map ,! "byy
+map ,@ "cyy
+map ,# "bP
+map ,c c$
+"
+"  ----- END of Work out one line -----
+"
+"  ----- Work out one square -----
+"
+" The next three work out a square: put all nine chars around the current
+" character on the bottom line (the bottom line must be empty when starting).
+"
+" 'W'ork out a center square (used by work out line)
+map W makh,3`ah,3`ajh,3(
+"
+"
+" Work out a 'L'eft square (used by work out line)
+map L makf-h,1`ak,2`af-h,1`a,2`ajf-h,1`aj,2(
+"
+"
+" Work out a 'R'ight square (used by work out line)
+map ,r makh,2`akF-l,1`ah,2`aF-l,1`ajh,2`ajF-l,1(
+"
+" 'M'ove a character to the end of the file (used by all work out square
+" macros)
+"
+map ,1 y G$p
+map ,2 2y G$p
+map ,3 3y G$p
+"
+"
+"  ----- END of Work out one square -----
+"
+"  ----- Work out one germ -----
+"
+" Generate an edit command that depends on the number of living in the last
+" line, and then run the edit command. (used by work out square).
+" Leaves the cursor on the next character to be processed.
+"
+map ( ,s,i,X0i?^#A 
0,df.l,Y21h
+"
+" Delete 's'paces (deads);
+" The number of remaining characters is the number of living neighbours.
+map ,s :.g/ /s///g
+"
+" Insert current character in the last line
+map ,i `ay GP
+"
+" Replace any uppercase letter with 'X';
+map ,X :.g/[A-Z]/s//X/g
+"
+" Delete and execute the rest of the line
+map ,d "qd$@q
+"
+" Yank and execute the rest of the line
+map ,Y "qy$@q
+"
+" Yank the character under the cursor
+map ,j y 
+"
+" Put the current cut buffer after the cursor
+map ,m p
+"
+" Delete the character under the cursor
+map ,n x
+"
+" Replace a character by it's next, A --> B,  B --> C, etc.
+map ,a `a,jGi?=,ma
0,dll,j`a21l,ml,nh
+"
+"  ----- END of Work out one germ -----
+"
+"  ----- timing macros  -----
+"
+" Get current date (used by time a generation)
+map << :r!date
+map <1 G?^top
O<<
+map <2 G?^top
k<<
+"
+"
+" Turn number on current line into edit command (used by time N generations)
+map ,^ AiC
+"
+"
+" Delete current line and save current line (used by time N generations)
+map ,& 0"gd$
+"
+"
+" Run saved line (used by time N generations)
+map ,* @g
+"
+"  ----- END of timing macros  -----
+"
+" End of the macros.
--- /dev/null
+++ b/lib/vimfiles/macros/matchit.txt
@@ -1,0 +1,404 @@
+*matchit.txt*   Extended "%" matching
+
+For instructions on installing this file, type
+	:help matchit-install
+inside Vim.
+
+For Vim version 6.3.  Last change:  2006 Feb 23
+
+
+		  VIM REFERENCE MANUAL    by Benji Fisher
+
+*matchit* *matchit.vim*
+
+1. Extended matching with "%"				|matchit-intro|
+2. Activation						|matchit-activate|
+3. Configuration					|matchit-configure|
+4. Supporting a New Language				|matchit-newlang|
+5. Known Bugs and Limitations				|matchit-bugs|
+
+The functionality mentioned here is a plugin, see |add-plugin|.
+This plugin is only available if 'compatible' is not set.
+You can avoid loading this plugin by setting the "loaded_matchit" variable
+in your |vimrc| file: >
+	:let loaded_matchit = 1
+
+{Vi does not have any of this}
+
+==============================================================================
+1. Extended matching with "%"				*matchit-intro*
+
+							*matchit-%*
+%	Cycle forward through matching groups, such as "if", "else", "endif",
+	as specified by |b:match_words|.
+
+							*g%* *v_g%* *o_g%*
+g%	Cycle backwards through matching groups, as specified by
+	|b:match_words|.  For example, go from "endif" to "else" to "if".
+
+							*[%* *v_[%* *o_[%*
+[%	Go to [count] previous unmatched group, as specified by
+	|b:match_words|.  Similar to |[{|.
+
+							*]%* *v_]%* *o_]%*
+]%	Go to [count] next unmatched group, as specified by
+	|b:match_words|.  Similar to |]}|.
+
+							*v_a%*
+a%	In Visual mode, select the matching group, as specified by
+	|b:match_words|, containing the cursor.  Similar to |v_a[|.
+	A [count] is ignored, and only the first character of the closing
+	pattern is selected.
+
+In Vim, as in plain vi, the percent key, |%|, jumps the cursor from a brace,
+bracket, or paren to its match.  This can be configured with the 'matchpairs'
+option.  The matchit plugin extends this in several ways:
+
+	    You can match whole words, such as "if" and "endif", not just
+	single characters.  You can also specify a |regular-expression|.
+	    You can define groups with more than two words, such as "if",
+	"else", "endif".  Banging on the "%" key will cycle from the "if" to
+	the first "else", the next "else", ..., the closing "endif", and back
+	to the opening "if".  Nested structures are skipped.  Using |g%| goes
+	in the reverse direction.
+	    By default, words inside comments and strings are ignored, unless
+	the cursor is inside a comment or string when you type "%".  If the
+	only thing you want to do is modify the behavior of "%" so that it
+	behaves this way, you can >
+		:let b:match_words = &matchpairs
+<
+See |matchit-details| for details on what the script does, and |b:match_words|
+for how to specify matching patterns.
+
+MODES:			*matchit-modes* *matchit-v_%* *matchit-o_%*
+
+Mostly, % and related motions (|g%| and |[%| and |]%|) work just like built-in
+|motion| commands in |Operator-pending| and |Visual| modes.  However, you
+cannot make these motions |linewise| or |characterwise|, since the |:omap|s
+that define them start with "v" in order to make the default behavior
+inclusive.  (See |o_v|.)  In other words, "dV%" will not work.  The
+work-around is to go through Visual mode:  "V%d" will work.
+
+LANGUAGES:					*matchit-languages*
+
+Currently, the following languages are supported:  Ada, ASP with VBS, Csh,
+DTD, Entity, Essbase, Fortran, HTML, JSP (same as HTML), LaTeX, Lua, Pascal,
+SGML, Shell, Tcsh, Vim, XML.  Other languages may already have support via
+|filetype-plugin|s.
+
+To support a new language, see |matchit-newlang| below.
+
+DETAILS:				*matchit-details* *matchit-parse*
+
+Here is an outline of what matchit.vim does each time you hit the "%" key.  If
+there are |backref|s in |b:match_words| then the first step is to produce a
+version in which these back references have been eliminated; if there are no
+|backref|s then this step is skipped.  This step is called parsing.  For
+example, "\(foo\|bar\):end\1" is parsed to yield
+"\(foo\|bar\):end\(foo\|bar\)".  This can get tricky, especially if there are
+nested groups.  If debugging is turned on, the parsed version is saved as
+|b:match_pat|.
+
+							*matchit-choose*
+Next, the script looks for a word on the current line that matches the pattern
+just constructed.  It includes the patterns from the 'matchpairs' option.
+The goal is to do what you expect, which turns out to be a little complicated.
+The script follows these rules:
+
+	Insist on a match that ends on or after the cursor.
+	Prefer a match that includes the cursor position (that is, one that
+		starts on or before the cursor).
+	Prefer a match that starts as close to the cursor as possible.
+	Prefer a match in |b:match_words| to a match in 'matchpairs'.
+	If more than one pattern in |b:match_words| matches, choose the one
+		that is listed first.
+
+Examples:
+
+	Suppose you >
+		:let b:match_words = '<:>,<tag>:</tag>'
+<	and hit "%" with the cursor on or before the "<" in "a <tag> is born".
+	The pattern '<' comes first, so it is preferred over '<tag>', which
+	also matches.  If the cursor is on the "t", however, then '<tag>' is
+	preferred, because this matches a bit of text containing the cursor.
+	If the two groups of patterns were reversed then '<' would never be
+	preferred.
+
+	Suppose you >
+		:let b:match_words = 'if:end if'
+<	(Note the space!) and hit "%" with the cursor at the end of "end if".
+	Then "if" matches, which is probably not what you want, but if the
+	cursor starts on the "end " then "end if" is chosen.  (You can avoid
+	this problem by using a more complicated pattern.)
+
+If there is no match, the script falls back on the usual behavior of |%|.  If
+debugging is turned on, the matched bit of text is saved as |b:match_match|
+and the cursor column of the start of the match is saved as |b:match_col|.
+
+Next, the script looks through |b:match_words| (original and parsed versions)
+for the group and pattern that match.  If debugging is turned on, the group is
+saved as |b:match_ini| (the first pattern) and |b:match_tail| (the rest).  If
+there are |backref|s then, in addition, the matching pattern is saved as
+|b:match_word| and a table of translations is saved as |b:match_table|.  If
+there are |backref|s, these are determined from the matching pattern and
+|b:match_match| and substituted into each pattern in the matching group.
+
+The script decides whether to search forwards or backwards and chooses
+arguments for the |searchpair()| function.  Then, the cursor is moved to the
+start of the match, and |searchpair()| is called.  By default, matching
+structures inside strings and comments are ignored.  This can be changed by
+setting |b:match_skip|.
+
+==============================================================================
+2. Activation						*matchit-activate*
+
+You can use this script as a plugin, by copying it to your plugin directory.
+See |add-global-plugin| for instructions.  You can also add a line to your
+|vimrc| file, such as >
+	:source $VIMRUNTIME/macros/matchit.vim
+or >
+	:runtime macros/matchit.vim
+Either way, the script should start working the next time you start up Vim.
+
+The script does nothing unless it finds a |buffer-variable| named
+|b:match_words|.  The script contains autocommands that set this variable for
+various file types:  see |matchit-languages| above.  For a new language, you
+can add autocommands to the script or to your vimrc file, but the recommended
+method is to add a line such as >
+	let b:match_words = '\<foo\>:\<bar\>'
+to the |filetype-plugin| for your language.  See |b:match_words| below for how
+this variable is interpreted.
+
+TROUBLESHOOTING					*matchit-troubleshoot*
+
+The script should work in most installations of Vim.  It may not work if Vim
+was compiled with a minimal feature set, for example if the |+syntax| option
+was not enabled.  If your Vim has support for syntax compiled in, but you do
+not have |syntax| highlighting turned on, matchit.vim should work, but it may
+fail to skip matching groups in comments and strings.  If the |filetype|
+mechanism is turned off, the |b:match_words| variable will probably not be
+defined automatically.
+
+==============================================================================
+3. Configuration					*matchit-configure*
+
+There are several variables that govern the behavior of matchit.vim.  Note
+that these are variables local to the buffer, not options, so use |:let| to
+define them, not |:set|.  Some of these variables have values that matter; for
+others, it only matters whether the variable has been defined.  All of these
+can be defined in the |filetype-plugin| or autocommand that defines
+|b:match_words| or "on the fly."
+
+The main variable is |b:match_words|.  It is described in the section below on
+supporting a new language.
+
+				*MatchError* *matchit-hl* *matchit-highlight*
+MatchError is the highlight group for error messages from the script.  By
+default, it is linked to WarningMsg.  If you do not want to be bothered by
+error messages, you can define this to be something invisible.  For example,
+if you use the GUI version of Vim and your command line is normally white, you
+can do >
+	:hi MatchError guifg=white guibg=white
+<
+						*b:match_ignorecase*
+If you >
+	:let b:match_ignorecase = 1
+then matchit.vim acts as if 'ignorecase' is set: for example, "end" and "END"
+are equivalent.  If you >
+	:let b:match_ignorecase = 0
+then matchit.vim treats "end" and "END" differently.  (There will be no
+b:match_infercase option unless someone requests it.)
+
+						*b:match_debug*
+Define b:match_debug if you want debugging information to be saved.  See
+|matchit-debug|, below.
+
+						*b:match_skip*
+If b:match_skip is defined, it is passed as the skip argument to
+|searchpair()|.  This controls when matching structures are skipped, or
+ignored.  By default, they are ignored inside comments and strings, as
+determined by the |syntax| mechanism.  (If syntax highlighting is turned off,
+nothing is skipped.)  You can set b:match_skip to a string, which evaluates to
+a non-zero, numerical value if the match is to be skipped or zero if the match
+should not be skipped.  In addition, the following special values are
+supported by matchit.vim:
+	s:foo becomes (current syntax item) =~ foo
+	S:foo becomes (current syntax item) !~ foo
+	r:foo becomes (line before cursor) =~ foo
+	R:foo becomes (line before cursor) !~ foo
+(The "s" is meant to suggest "syntax", and the "r" is meant to suggest
+"regular expression".)
+
+Examples:
+
+	You can get the default behavior with >
+		:let b:match_skip = 's:comment\|string'
+<
+	If you want to skip matching structures unless they are at the start
+	of the line (ignoring whitespace) then you can >
+		:let b:match_skip = 'R:^\s*'
+<	Do not do this if strings or comments can span several lines, since
+	the normal syntax checking will not be done if you set b:match_skip.
+
+	In LaTeX, since "%" is used as the comment character, you can >
+		:let b:match_skip = 'r:%'
+<	Unfortunately, this will skip anything after "\%", an escaped "%".  To
+	allow for this, and also "\\%" (an excaped backslash followed by the
+	comment character) you can >
+		:let b:match_skip = 'r:\(^\|[^\\]\)\(\\\\\)*%'
+<
+	See the $VIMRUNTIME/ftplugin/vim.vim for an example that uses both
+	syntax and a regular expression.
+
+==============================================================================
+4. Supporting a New Language				*matchit-newlang*
+							*b:match_words*
+In order for matchit.vim to support a new language, you must define a suitable
+pattern for |b:match_words|.  You may also want to set some of the
+|matchit-configure| variables, as described above.  If your language has a
+complicated syntax, or many keywords, you will need to know something about
+Vim's |regular-expression|s.
+
+The format for |b:match_words| is similar to that of the 'matchpairs' option:
+it is a comma (,)-separated list of groups; each group is a colon(:)-separated
+list of patterns (regular expressions).  Commas and backslashes that are part
+of a pattern should be escaped with backslashes ('\:' and '\,').  It is OK to
+have only one group; the effect is undefined if a group has only one pattern.
+A simple example is >
+	:let b:match_words = '\<if\>:\<endif\>,'
+		\ . '\<while\>:\<continue\>:\<break\>:\<endwhile\>'
+(In Vim regular expressions, |\<| and |\>| denote word boundaries.  Thus "if"
+matches the end of "endif" but "\<if\>" does not.)  Then banging on the "%"
+key will bounce the cursor between "if" and the matching "endif"; and from
+"while" to any matching "continue" or "break", then to the matching "endwhile"
+and back to the "while".  It is almost always easier to use |literal-string|s
+(single quotes) as above:  '\<if\>' rather than "\\<if\\>" and so on.
+
+Exception:  If the ":" character does not appear in b:match_words, then it is
+treated as an expression to be evaluated.  For example, >
+	:let b:match_words = 'GetMatchWords()'
+allows you to define a function.  This can return a different string depending
+on the current syntax, for example.
+
+Once you have defined the appropriate value of |b:match_words|, you will
+probably want to have this set automatically each time you edit the
+appropriate file type.  The recommended way to do this is by adding the
+definition to a |filetype-plugin| file.
+
+Tips: Be careful that your initial pattern does not match your final pattern.
+See the example above for the use of word-boundary expressions.  It is usually
+better to use ".\{-}" (as many as necessary) instead of ".*" (as many as
+possible).  See |\{-|.  For example, in the string "<tag>label</tag>", "<.*>"
+matches the whole string whereas "<.\{-}>" and "<[^>]*>" match "<tag>" and
+"</tag>".
+
+				*matchit-spaces* *matchit-s:notend*
+If "if" is to be paired with "end if" (Note the space!) then word boundaries
+are not enough.  Instead, define a regular expression s:notend that will match
+anything but "end" and use it as follows: >
+	:let s:notend = '\%(\<end\s\+\)\@<!'
+	:let b:match_words = s:notend . '\<if\>:\<end\s\+if\>'
+<							*matchit-s:sol*
+This is a simplified version of what is done for Ada.  The s:notend is a
+|script-variable|.  Similarly, you may want to define a start-of-line regular
+expression >
+	:let s:sol = '\%(^\|;\)\s*'
+if keywords are only recognized after the start of a line or after a
+semicolon (;), with optional white space.
+
+					*matchit-backref* *matchit-\1*
+In any group, the expressions |\1|, |\2|, ..., |\9| refer to parts of the
+INITIAL pattern enclosed in |\(|escaped parentheses|\)|.  These are referred
+to as back references, or backrefs.  For example, >
+	:let b:match_words = '\<b\(o\+\)\>:\(h\)\1\>'
+means that "bo" pairs with "ho" and "boo" pairs with "hoo" and so on.  Note
+that "\1" does not refer to the "\(h\)" in this example.  If you have
+"\(nested \(parentheses\)\) then "\d" refers to the d-th "\(" and everything
+up to and including the matching "\)":  in "\(nested\(parentheses\)\)", "\1"
+refers to everything and "\2" refers to "\(parentheses\)".  If you use a
+variable such as |s:notend| or |s:sol| in the previous paragraph then remember
+to count any "\(" patterns in this variable.  You do not have to count groups
+defined by |\%(\)|.
+
+It should be possible to resolve back references from any pattern in the
+group.  For example, >
+	:let b:match_words = '\(foo\)\(bar\):more\1:and\2:end\1\2'
+would not work because "\2" cannot be determined from "morefoo" and "\1"
+cannot be determined from "andbar".  On the other hand, >
+	:let b:match_words = '\(\(foo\)\(bar\)\):\3\2:end\1'
+should work (and have the same effect as "foobar:barfoo:endfoobar"), although
+this has not been thoroughly tested.
+
+You can use |zero-width| patterns such as |\@<=| and |\zs|.  (The latter has
+not been thouroughly tested in matchit.vim.)  For example, if the keyword "if"
+must occur at the start of the line, with optional white space, you might use
+the pattern "\(^\s*\)\@<=if" so that the cursor will end on the "i" instead of
+at the start of the line.  For another example, if HTML had only one tag then
+one could >
+	:let b:match_words = '<:>,<\@<=tag>:<\@<=/tag>'
+so that "%" can bounce between matching "<" and ">" pairs or (starting on
+"tag" or "/tag") between matching tags.  Without the |\@<=|, the script would
+bounce from "tag" to the "<" in "</tag>", and another "%" would not take you
+back to where you started.
+
+DEBUGGING				*matchit-debug* *:MatchDebug*
+
+If you are having trouble figuring out the appropriate definition of
+|b:match_words| then you can take advantage of the same information I use when
+debugging the script.  This is especially true if you are not sure whether
+your patterns or my script are at fault!  To make this more convenient, I have
+made the command :MatchDebug, which defines the variable |b:match_debug| and
+creates a Matchit menu.  This menu makes it convenient to check the values of
+the variables described below.  You will probably also want to read
+|matchit-details| above.
+
+Defining the variable |b:match_debug| causes the script to set the following
+variables, each time you hit the "%" key.  Several of these are only defined
+if |b:match_words| includes |backref|s.
+
+							*b:match_pat*
+The b:match_pat variable is set to |b:match_words| with |backref|s parsed.
+							*b:match_match*
+The b:match_match variable is set to the bit of text that is recognized as a
+match.
+							*b:match_col*
+The b:match_col variable is set to the cursor column of the start of the
+matching text.
+							*b:match_wholeBR*
+The b:match_wholeBR variable is set to the comma-separated group of patterns
+that matches, with |backref|s unparsed.
+							*b:match_iniBR*
+The b:match_iniBR variable is set to the first pattern in |b:match_wholeBR|.
+							*b:match_ini*
+The b:match_ini variable is set to the first pattern in |b:match_wholeBR|,
+with |backref|s resolved from |b:match_match|.
+							*b:match_tail*
+The b:match_tail variable is set to the remaining patterns in
+|b:match_wholeBR|, with |backref|s resolved from |b:match_match|.
+							*b:match_word*
+The b:match_word variable is set to the pattern from |b:match_wholeBR| that
+matches |b:match_match|.
+							*b:match_table*
+The back reference '\'.d refers to the same thing as '\'.b:match_table[d] in
+|b:match_word|.
+
+==============================================================================
+5. Known Bugs and Limitations				*matchit-bugs*
+
+Just because I know about a bug does not mean that it is on my todo list.  I
+try to respond to reports of bugs that cause real problems.  If it does not
+cause serious problems, or if there is a work-around, a bug may sit there for
+a while.  Moral:  if a bug (known or not) bothers you, let me know.
+
+The various |:vmap|s defined in the script (%, |g%|, |[%|, |]%|, |a%|) may
+have undesired effects in Select mode |Select-mode-mapping|.  At least, if you
+want to replace the selection with any character in "ag%[]" there will be a
+pause of |'updatetime'| first.
+
+It would be nice if "\0" were recognized as the entire pattern.  That is, it
+would be nice if "foo:\end\0" had the same effect as "\(foo\):\end\1".  I may
+try to implement this in a future version.  (This is not so easy to arrange as
+you might think!)
+
+==============================================================================
+vim:tw=78:fo=tcq2:
--- /dev/null
+++ b/lib/vimfiles/macros/matchit.vim
@@ -1,0 +1,812 @@
+"  matchit.vim: (global plugin) Extended "%" matching
+"  Last Change: Mon May 15 10:00 PM 2006 EDT
+"  Maintainer:  Benji Fisher PhD   <benji@member.AMS.org>
+"  Version:     1.11, for Vim 6.3+
+"  URL:		http://www.vim.org/script.php?script_id=39
+
+" Documentation:
+"  The documentation is in a separate file, matchit.txt .
+
+" Credits:
+"  Vim editor by Bram Moolenaar (Thanks, Bram!)
+"  Original script and design by Raul Segura Acevedo
+"  Support for comments by Douglas Potts
+"  Support for back references and other improvements by Benji Fisher
+"  Support for many languages by Johannes Zellner
+"  Suggestions for improvement, bug reports, and support for additional
+"  languages by Jordi-Albert Batalla, Neil Bird, Servatius Brandt, Mark
+"  Collett, Stephen Wall, Dany St-Amant, Yuheng Xie, and Johannes Zellner.
+
+" Debugging:
+"  If you'd like to try the built-in debugging commands...
+"   :MatchDebug      to activate debugging for the current buffer
+"  This saves the values of several key script variables as buffer-local
+"  variables.  See the MatchDebug() function, below, for details.
+
+" TODO:  I should think about multi-line patterns for b:match_words.
+"   This would require an option:  how many lines to scan (default 1).
+"   This would be useful for Python, maybe also for *ML.
+" TODO:  Maybe I should add a menu so that people will actually use some of
+"   the features that I have implemented.
+" TODO:  Eliminate the MultiMatch function.  Add yet another argument to
+"   Match_wrapper() instead.
+" TODO:  Allow :let b:match_words = '\(\(foo\)\(bar\)\):\3\2:end\1'
+" TODO:  Make backrefs safer by using '\V' (very no-magic).
+" TODO:  Add a level of indirection, so that custom % scripts can use my
+"   work but extend it.
+
+" allow user to prevent loading
+" and prevent duplicate loading
+if exists("loaded_matchit") || &cp
+  finish
+endif
+let loaded_matchit = 1
+let s:last_mps = ""
+let s:last_words = ""
+
+let s:save_cpo = &cpo
+set cpo&vim
+
+nnoremap <silent> %  :<C-U>call <SID>Match_wrapper('',1,'n') <CR>
+nnoremap <silent> g% :<C-U>call <SID>Match_wrapper('',0,'n') <CR>
+vnoremap <silent> %  :<C-U>call <SID>Match_wrapper('',1,'v') <CR>m'gv``
+vnoremap <silent> g% :<C-U>call <SID>Match_wrapper('',0,'v') <CR>m'gv``
+onoremap <silent> %  v:<C-U>call <SID>Match_wrapper('',1,'o') <CR>
+onoremap <silent> g% v:<C-U>call <SID>Match_wrapper('',0,'o') <CR>
+
+" Analogues of [{ and ]} using matching patterns:
+nnoremap <silent> [% :<C-U>call <SID>MultiMatch("bW", "n") <CR>
+nnoremap <silent> ]% :<C-U>call <SID>MultiMatch("W",  "n") <CR>
+vmap [% <Esc>[%m'gv``
+vmap ]% <Esc>]%m'gv``
+" vnoremap <silent> [% :<C-U>call <SID>MultiMatch("bW", "v") <CR>m'gv``
+" vnoremap <silent> ]% :<C-U>call <SID>MultiMatch("W",  "v") <CR>m'gv``
+onoremap <silent> [% v:<C-U>call <SID>MultiMatch("bW", "o") <CR>
+onoremap <silent> ]% v:<C-U>call <SID>MultiMatch("W",  "o") <CR>
+
+" text object:
+vmap a% <Esc>[%v]%
+
+" Auto-complete mappings:  (not yet "ready for prime time")
+" TODO Read :help write-plugin for the "right" way to let the user
+" specify a key binding.
+"   let g:match_auto = '<C-]>'
+"   let g:match_autoCR = '<C-CR>'
+" if exists("g:match_auto")
+"   execute "inoremap " . g:match_auto . ' x<Esc>"=<SID>Autocomplete()<CR>Pls'
+" endif
+" if exists("g:match_autoCR")
+"   execute "inoremap " . g:match_autoCR . ' <CR><C-R>=<SID>Autocomplete()<CR>'
+" endif
+" if exists("g:match_gthhoh")
+"   execute "inoremap " . g:match_gthhoh . ' <C-O>:call <SID>Gthhoh()<CR>'
+" endif " gthhoh = "Get the heck out of here!"
+
+let s:notslash = '\\\@<!\%(\\\\\)*'
+
+function! s:Match_wrapper(word, forward, mode) range
+  " In s:CleanUp(), :execute "set" restore_options .
+  let restore_options = (&ic ? " " : " no") . "ignorecase"
+  if exists("b:match_ignorecase")
+    let &ignorecase = b:match_ignorecase
+  endif
+  let restore_options = " ve=" . &ve . restore_options
+  set ve=
+  " If this function was called from Visual mode, make sure that the cursor
+  " is at the correct end of the Visual range:
+  if a:mode == "v"
+    execute "normal! gv\<Esc>"
+  endif
+  " In s:CleanUp(), we may need to check whether the cursor moved forward.
+  let startline = line(".")
+  let startcol = col(".")
+  " Use default behavior if called with a count or if no patterns are defined.
+  if v:count
+    exe "normal! " . v:count . "%"
+    return s:CleanUp(restore_options, a:mode, startline, startcol)
+  elseif !exists("b:match_words") || b:match_words == ""
+    silent! normal! %
+    return s:CleanUp(restore_options, a:mode, startline, startcol)
+  end
+
+  " First step:  if not already done, set the script variables
+  "   s:do_BR	flag for whether there are backrefs
+  "   s:pat	parsed version of b:match_words
+  "   s:all	regexp based on s:pat and the default groups
+  "
+  " Allow b:match_words = "GetVimMatchWords()" .
+  if b:match_words =~ ":"
+    let match_words = b:match_words
+  else
+    execute "let match_words =" b:match_words
+  endif
+" Thanks to Preben "Peppe" Guldberg and Bram Moolenaar for this suggestion!
+  if (match_words != s:last_words) || (&mps != s:last_mps) ||
+    \ exists("b:match_debug")
+    let s:last_words = match_words
+    let s:last_mps = &mps
+    if match_words !~ s:notslash . '\\\d'
+      let s:do_BR = 0
+      let s:pat = match_words
+    else
+      let s:do_BR = 1
+      let s:pat = s:ParseWords(match_words)
+    endif
+    " The next several lines were here before
+    " BF started messing with this script.
+    " quote the special chars in 'matchpairs', replace [,:] with \| and then
+    " append the builtin pairs (/*, */, #if, #ifdef, #else, #elif, #endif)
+    " let default = substitute(escape(&mps, '[$^.*~\\/?]'), '[,:]\+',
+    "  \ '\\|', 'g').'\|\/\*\|\*\/\|#if\>\|#ifdef\>\|#else\>\|#elif\>\|#endif\>'
+    let default = escape(&mps, '[$^.*~\\/?]') . (strlen(&mps) ? "," : "") .
+      \ '\/\*:\*\/,#if\%(def\)\=:#else\>:#elif\>:#endif\>'
+    " s:all = pattern with all the keywords
+    let s:all = s:pat . (strlen(s:pat) ? "," : "") . default
+    let s:all = substitute(s:all, s:notslash . '\zs[,:]\+', '\\|', 'g')
+    let s:all = '\%(' . s:all . '\)'
+    " let s:all = '\%(' . substitute(s:all, '\\\ze[,:]', '', 'g') . '\)'
+    if exists("b:match_debug")
+      let b:match_pat = s:pat
+    endif
+  endif
+
+  " Second step:  set the following local variables:
+  "     matchline = line on which the cursor started
+  "     curcol    = number of characters before match
+  "     prefix    = regexp for start of line to start of match
+  "     suffix    = regexp for end of match to end of line
+  " Require match to end on or after the cursor and prefer it to
+  " start on or before the cursor.
+  let matchline = getline(startline)
+  if a:word != ''
+    " word given
+    if a:word !~ s:all
+      echohl WarningMsg|echo 'Missing rule for word:"'.a:word.'"'|echohl NONE
+      return s:CleanUp(restore_options, a:mode, startline, startcol)
+    endif
+    let matchline = a:word
+    let curcol = 0
+    let prefix = '^\%('
+    let suffix = '\)$'
+  " Now the case when "word" is not given
+  else	" Find the match that ends on or after the cursor and set curcol.
+    let regexp = s:Wholematch(matchline, s:all, startcol-1)
+    let curcol = match(matchline, regexp)
+    let endcol = matchend(matchline, regexp)
+    let suf = strlen(matchline) - endcol
+    let prefix = (curcol ? '^.*\%'  . (curcol + 1) . 'c\%(' : '^\%(')
+    let suffix = (suf ? '\)\%' . (endcol + 1) . 'c.*$'  : '\)$')
+    " If the match comes from the defaults, bail out.
+    if matchline !~ prefix .
+      \ substitute(s:pat, s:notslash.'\zs[,:]\+', '\\|', 'g') . suffix
+      silent! norm! %
+      return s:CleanUp(restore_options, a:mode, startline, startcol)
+    endif
+  endif
+  if exists("b:match_debug")
+    let b:match_match = matchstr(matchline, regexp)
+    let b:match_col = curcol+1
+  endif
+
+  " Third step:  Find the group and single word that match, and the original
+  " (backref) versions of these.  Then, resolve the backrefs.
+  " Set the following local variable:
+  " group = colon-separated list of patterns, one of which matches
+  "       = ini:mid:fin or ini:fin
+  "
+  " Reconstruct the version with unresolved backrefs.
+  let patBR = substitute(match_words.',',
+    \ s:notslash.'\zs[,:]*,[,:]*', ',', 'g')
+  let patBR = substitute(patBR, s:notslash.'\zs:\{2,}', ':', 'g')
+  " Now, set group and groupBR to the matching group: 'if:endif' or
+  " 'while:endwhile' or whatever.  A bit of a kluge:  s:Choose() returns
+  " group . "," . groupBR, and we pick it apart.
+  let group = s:Choose(s:pat, matchline, ",", ":", prefix, suffix, patBR)
+  let i = matchend(group, s:notslash . ",")
+  let groupBR = strpart(group, i)
+  let group = strpart(group, 0, i-1)
+  " Now, matchline =~ prefix . substitute(group,':','\|','g') . suffix
+  if s:do_BR " Do the hard part:  resolve those backrefs!
+    let group = s:InsertRefs(groupBR, prefix, group, suffix, matchline)
+  endif
+  if exists("b:match_debug")
+    let b:match_wholeBR = groupBR
+    let i = matchend(groupBR, s:notslash . ":")
+    let b:match_iniBR = strpart(groupBR, 0, i-1)
+  endif
+
+  " Fourth step:  Set the arguments for searchpair().
+  let i = matchend(group, s:notslash . ":")
+  let j = matchend(group, '.*' . s:notslash . ":")
+  let ini = strpart(group, 0, i-1)
+  let mid = substitute(strpart(group, i,j-i-1), s:notslash.'\zs:', '\\|', 'g')
+  let fin = strpart(group, j)
+  "Un-escape the remaining , and : characters.
+  let ini = substitute(ini, s:notslash . '\zs\\\(:\|,\)', '\1', 'g')
+  let mid = substitute(mid, s:notslash . '\zs\\\(:\|,\)', '\1', 'g')
+  let fin = substitute(fin, s:notslash . '\zs\\\(:\|,\)', '\1', 'g')
+  " searchpair() requires that these patterns avoid \(\) groups.
+  let ini = substitute(ini, s:notslash . '\zs\\(', '\\%(', 'g')
+  let mid = substitute(mid, s:notslash . '\zs\\(', '\\%(', 'g')
+  let fin = substitute(fin, s:notslash . '\zs\\(', '\\%(', 'g')
+  " Set mid.  This is optimized for readability, not micro-efficiency!
+  if a:forward && matchline =~ prefix . fin . suffix
+    \ || !a:forward && matchline =~ prefix . ini . suffix
+    let mid = ""
+  endif
+  " Set flag.  This is optimized for readability, not micro-efficiency!
+  if a:forward && matchline =~ prefix . fin . suffix
+    \ || !a:forward && matchline !~ prefix . ini . suffix
+    let flag = "bW"
+  else
+    let flag = "W"
+  endif
+  " Set skip.
+  if exists("b:match_skip")
+    let skip = b:match_skip
+  elseif exists("b:match_comment") " backwards compatibility and testing!
+    let skip = "r:" . b:match_comment
+  else
+    let skip = 's:comment\|string'
+  endif
+  let skip = s:ParseSkip(skip)
+  if exists("b:match_debug")
+    let b:match_ini = ini
+    let b:match_tail = (strlen(mid) ? mid.'\|' : '') . fin
+  endif
+
+  " Fifth step:  actually start moving the cursor and call searchpair().
+  " Later, :execute restore_cursor to get to the original screen.
+  let restore_cursor = virtcol(".") . "|"
+  normal! g0
+  let restore_cursor = line(".") . "G" .  virtcol(".") . "|zs" . restore_cursor
+  normal! H
+  let restore_cursor = "normal!" . line(".") . "Gzt" . restore_cursor
+  execute restore_cursor
+  call cursor(0, curcol + 1)
+  " normal! 0
+  " if curcol
+  "   execute "normal!" . curcol . "l"
+  " endif
+  if skip =~ 'synID' && !(has("syntax") && exists("g:syntax_on"))
+    let skip = "0"
+  else
+    execute "if " . skip . "| let skip = '0' | endif"
+  endif
+  let sp_return = searchpair(ini, mid, fin, flag, skip)
+  let final_position = "call cursor(" . line(".") . "," . col(".") . ")"
+  " Restore cursor position and original screen.
+  execute restore_cursor
+  normal! m'
+  if sp_return > 0
+    execute final_position
+  endif
+  return s:CleanUp(restore_options, a:mode, startline, startcol, mid.'\|'.fin)
+endfun
+
+" Restore options and do some special handling for Operator-pending mode.
+" The optional argument is the tail of the matching group.
+fun! s:CleanUp(options, mode, startline, startcol, ...)
+  execute "set" a:options
+  " Open folds, if appropriate.
+  if a:mode != "o"
+    if &foldopen =~ "percent"
+      normal! zv
+    endif
+    " In Operator-pending mode, we want to include the whole match
+    " (for example, d%).
+    " This is only a problem if we end up moving in the forward direction.
+  elseif (a:startline < line(".")) ||
+	\ (a:startline == line(".") && a:startcol < col("."))
+    if a:0
+      " Check whether the match is a single character.  If not, move to the
+      " end of the match.
+      let matchline = getline(".")
+      let currcol = col(".")
+      let regexp = s:Wholematch(matchline, a:1, currcol-1)
+      let endcol = matchend(matchline, regexp)
+      if endcol > currcol  " This is NOT off by one!
+	execute "normal!" . (endcol - currcol) . "l"
+      endif
+    endif " a:0
+  endif " a:mode != "o" && etc.
+  return 0
+endfun
+
+" Example (simplified HTML patterns):  if
+"   a:groupBR	= '<\(\k\+\)>:</\1>'
+"   a:prefix	= '^.\{3}\('
+"   a:group	= '<\(\k\+\)>:</\(\k\+\)>'
+"   a:suffix	= '\).\{2}$'
+"   a:matchline	=  "123<tag>12" or "123</tag>12"
+" then extract "tag" from a:matchline and return "<tag>:</tag>" .
+fun! s:InsertRefs(groupBR, prefix, group, suffix, matchline)
+  if a:matchline !~ a:prefix .
+    \ substitute(a:group, s:notslash . '\zs:', '\\|', 'g') . a:suffix
+    return a:group
+  endif
+  let i = matchend(a:groupBR, s:notslash . ':')
+  let ini = strpart(a:groupBR, 0, i-1)
+  let tailBR = strpart(a:groupBR, i)
+  let word = s:Choose(a:group, a:matchline, ":", "", a:prefix, a:suffix,
+    \ a:groupBR)
+  let i = matchend(word, s:notslash . ":")
+  let wordBR = strpart(word, i)
+  let word = strpart(word, 0, i-1)
+  " Now, a:matchline =~ a:prefix . word . a:suffix
+  if wordBR != ini
+    let table = s:Resolve(ini, wordBR, "table")
+  else
+    " let table = "----------"
+    let table = ""
+    let d = 0
+    while d < 10
+      if tailBR =~ s:notslash . '\\' . d
+	" let table[d] = d
+	let table = table . d
+      else
+	let table = table . "-"
+      endif
+      let d = d + 1
+    endwhile
+  endif
+  let d = 9
+  while d
+    if table[d] != "-"
+      let backref = substitute(a:matchline, a:prefix.word.a:suffix,
+	\ '\'.table[d], "")
+	" Are there any other characters that should be escaped?
+      let backref = escape(backref, '*,:')
+      execute s:Ref(ini, d, "start", "len")
+      let ini = strpart(ini, 0, start) . backref . strpart(ini, start+len)
+      let tailBR = substitute(tailBR, s:notslash . '\zs\\' . d,
+	\ escape(backref, '\\'), 'g')
+    endif
+    let d = d-1
+  endwhile
+  if exists("b:match_debug")
+    if s:do_BR
+      let b:match_table = table
+      let b:match_word = word
+    else
+      let b:match_table = ""
+      let b:match_word = ""
+    endif
+  endif
+  return ini . ":" . tailBR
+endfun
+
+" Input a comma-separated list of groups with backrefs, such as
+"   a:groups = '\(foo\):end\1,\(bar\):end\1'
+" and return a comma-separated list of groups with backrefs replaced:
+"   return '\(foo\):end\(foo\),\(bar\):end\(bar\)'
+fun! s:ParseWords(groups)
+  let groups = substitute(a:groups.",", s:notslash.'\zs[,:]*,[,:]*', ',', 'g')
+  let groups = substitute(groups, s:notslash . '\zs:\{2,}', ':', 'g')
+  let parsed = ""
+  while groups =~ '[^,:]'
+    let i = matchend(groups, s:notslash . ':')
+    let j = matchend(groups, s:notslash . ',')
+    let ini = strpart(groups, 0, i-1)
+    let tail = strpart(groups, i, j-i-1) . ":"
+    let groups = strpart(groups, j)
+    let parsed = parsed . ini
+    let i = matchend(tail, s:notslash . ':')
+    while i != -1
+      " In 'if:else:endif', ini='if' and word='else' and then word='endif'.
+      let word = strpart(tail, 0, i-1)
+      let tail = strpart(tail, i)
+      let i = matchend(tail, s:notslash . ':')
+      let parsed = parsed . ":" . s:Resolve(ini, word, "word")
+    endwhile " Now, tail has been used up.
+    let parsed = parsed . ","
+  endwhile " groups =~ '[^,:]'
+  return parsed
+endfun
+
+" TODO I think this can be simplified and/or made more efficient.
+" TODO What should I do if a:start is out of range?
+" Return a regexp that matches all of a:string, such that
+" matchstr(a:string, regexp) represents the match for a:pat that starts
+" as close to a:start as possible, before being preferred to after, and
+" ends after a:start .
+" Usage:
+" let regexp = s:Wholematch(getline("."), 'foo\|bar', col(".")-1)
+" let i      = match(getline("."), regexp)
+" let j      = matchend(getline("."), regexp)
+" let match  = matchstr(getline("."), regexp)
+fun! s:Wholematch(string, pat, start)
+  let group = '\%(' . a:pat . '\)'
+  let prefix = (a:start ? '\(^.*\%<' . (a:start + 2) . 'c\)\zs' : '^')
+  let len = strlen(a:string)
+  let suffix = (a:start+1 < len ? '\(\%>'.(a:start+1).'c.*$\)\@=' : '$')
+  if a:string !~ prefix . group . suffix
+    let prefix = ''
+  endif
+  return prefix . group . suffix
+endfun
+
+" No extra arguments:  s:Ref(string, d) will
+" find the d'th occurrence of '\(' and return it, along with everything up
+" to and including the matching '\)'.
+" One argument:  s:Ref(string, d, "start") returns the index of the start
+" of the d'th '\(' and any other argument returns the length of the group.
+" Two arguments:  s:Ref(string, d, "foo", "bar") returns a string to be
+" executed, having the effect of
+"   :let foo = s:Ref(string, d, "start")
+"   :let bar = s:Ref(string, d, "len")
+fun! s:Ref(string, d, ...)
+  let len = strlen(a:string)
+  if a:d == 0
+    let start = 0
+  else
+    let cnt = a:d
+    let match = a:string
+    while cnt
+      let cnt = cnt - 1
+      let index = matchend(match, s:notslash . '\\(')
+      if index == -1
+	return ""
+      endif
+      let match = strpart(match, index)
+    endwhile
+    let start = len - strlen(match)
+    if a:0 == 1 && a:1 == "start"
+      return start - 2
+    endif
+    let cnt = 1
+    while cnt
+      let index = matchend(match, s:notslash . '\\(\|\\)') - 1
+      if index == -2
+	return ""
+      endif
+      " Increment if an open, decrement if a ')':
+      let cnt = cnt + (match[index]=="(" ? 1 : -1)  " ')'
+      " let cnt = stridx('0(', match[index]) + cnt
+      let match = strpart(match, index+1)
+    endwhile
+    let start = start - 2
+    let len = len - start - strlen(match)
+  endif
+  if a:0 == 1
+    return len
+  elseif a:0 == 2
+    return "let " . a:1 . "=" . start . "| let " . a:2 . "=" . len
+  else
+    return strpart(a:string, start, len)
+  endif
+endfun
+
+" Count the number of disjoint copies of pattern in string.
+" If the pattern is a literal string and contains no '0' or '1' characters
+" then s:Count(string, pattern, '0', '1') should be faster than
+" s:Count(string, pattern).
+fun! s:Count(string, pattern, ...)
+  let pat = escape(a:pattern, '\\')
+  if a:0 > 1
+    let foo = substitute(a:string, '[^'.a:pattern.']', "a:1", "g")
+    let foo = substitute(a:string, pat, a:2, "g")
+    let foo = substitute(foo, '[^' . a:2 . ']', "", "g")
+    return strlen(foo)
+  endif
+  let result = 0
+  let foo = a:string
+  let index = matchend(foo, pat)
+  while index != -1
+    let result = result + 1
+    let foo = strpart(foo, index)
+    let index = matchend(foo, pat)
+  endwhile
+  return result
+endfun
+
+" s:Resolve('\(a\)\(b\)', '\(c\)\2\1\1\2') should return table.word, where
+" word = '\(c\)\(b\)\(a\)\3\2' and table = '-32-------'.  That is, the first
+" '\1' in target is replaced by '\(a\)' in word, table[1] = 3, and this
+" indicates that all other instances of '\1' in target are to be replaced
+" by '\3'.  The hard part is dealing with nesting...
+" Note that ":" is an illegal character for source and target,
+" unless it is preceded by "\".
+fun! s:Resolve(source, target, output)
+  let word = a:target
+  let i = matchend(word, s:notslash . '\\\d') - 1
+  let table = "----------"
+  while i != -2 " There are back references to be replaced.
+    let d = word[i]
+    let backref = s:Ref(a:source, d)
+    " The idea is to replace '\d' with backref.  Before we do this,
+    " replace any \(\) groups in backref with :1, :2, ... if they
+    " correspond to the first, second, ... group already inserted
+    " into backref.  Later, replace :1 with \1 and so on.  The group
+    " number w+b within backref corresponds to the group number
+    " s within a:source.
+    " w = number of '\(' in word before the current one
+    let w = s:Count(
+    \ substitute(strpart(word, 0, i-1), '\\\\', '', 'g'), '\(', '1')
+    let b = 1 " number of the current '\(' in backref
+    let s = d " number of the current '\(' in a:source
+    while b <= s:Count(substitute(backref, '\\\\', '', 'g'), '\(', '1')
+    \ && s < 10
+      if table[s] == "-"
+	if w + b < 10
+	  " let table[s] = w + b
+	  let table = strpart(table, 0, s) . (w+b) . strpart(table, s+1)
+	endif
+	let b = b + 1
+	let s = s + 1
+      else
+	execute s:Ref(backref, b, "start", "len")
+	let ref = strpart(backref, start, len)
+	let backref = strpart(backref, 0, start) . ":". table[s]
+	\ . strpart(backref, start+len)
+	let s = s + s:Count(substitute(ref, '\\\\', '', 'g'), '\(', '1')
+      endif
+    endwhile
+    let word = strpart(word, 0, i-1) . backref . strpart(word, i+1)
+    let i = matchend(word, s:notslash . '\\\d') - 1
+  endwhile
+  let word = substitute(word, s:notslash . '\zs:', '\\', 'g')
+  if a:output == "table"
+    return table
+  elseif a:output == "word"
+    return word
+  else
+    return table . word
+  endif
+endfun
+
+" Assume a:comma = ",".  Then the format for a:patterns and a:1 is
+"   a:patterns = "<pat1>,<pat2>,..."
+"   a:1 = "<alt1>,<alt2>,..."
+" If <patn> is the first pattern that matches a:string then return <patn>
+" if no optional arguments are given; return <patn>,<altn> if a:1 is given.
+fun! s:Choose(patterns, string, comma, branch, prefix, suffix, ...)
+  let tail = (a:patterns =~ a:comma."$" ? a:patterns : a:patterns . a:comma)
+  let i = matchend(tail, s:notslash . a:comma)
+  if a:0
+    let alttail = (a:1 =~ a:comma."$" ? a:1 : a:1 . a:comma)
+    let j = matchend(alttail, s:notslash . a:comma)
+  endif
+  let current = strpart(tail, 0, i-1)
+  if a:branch == ""
+    let currpat = current
+  else
+    let currpat = substitute(current, s:notslash . a:branch, '\\|', 'g')
+  endif
+  while a:string !~ a:prefix . currpat . a:suffix
+    let tail = strpart(tail, i)
+    let i = matchend(tail, s:notslash . a:comma)
+    if i == -1
+      return -1
+    endif
+    let current = strpart(tail, 0, i-1)
+    if a:branch == ""
+      let currpat = current
+    else
+      let currpat = substitute(current, s:notslash . a:branch, '\\|', 'g')
+    endif
+    if a:0
+      let alttail = strpart(alttail, j)
+      let j = matchend(alttail, s:notslash . a:comma)
+    endif
+  endwhile
+  if a:0
+    let current = current . a:comma . strpart(alttail, 0, j-1)
+  endif
+  return current
+endfun
+
+" Call this function to turn on debugging information.  Every time the main
+" script is run, buffer variables will be saved.  These can be used directly
+" or viewed using the menu items below.
+if !exists(":MatchDebug")
+  command! -nargs=0 MatchDebug call s:Match_debug()
+endif
+
+fun! s:Match_debug()
+  let b:match_debug = 1	" Save debugging information.
+  " pat = all of b:match_words with backrefs parsed
+  amenu &Matchit.&pat	:echo b:match_pat<CR>
+  " match = bit of text that is recognized as a match
+  amenu &Matchit.&match	:echo b:match_match<CR>
+  " curcol = cursor column of the start of the matching text
+  amenu &Matchit.&curcol	:echo b:match_col<CR>
+  " wholeBR = matching group, original version
+  amenu &Matchit.wh&oleBR	:echo b:match_wholeBR<CR>
+  " iniBR = 'if' piece, original version
+  amenu &Matchit.ini&BR	:echo b:match_iniBR<CR>
+  " ini = 'if' piece, with all backrefs resolved from match
+  amenu &Matchit.&ini	:echo b:match_ini<CR>
+  " tail = 'else\|endif' piece, with all backrefs resolved from match
+  amenu &Matchit.&tail	:echo b:match_tail<CR>
+  " fin = 'endif' piece, with all backrefs resolved from match
+  amenu &Matchit.&word	:echo b:match_word<CR>
+  " '\'.d in ini refers to the same thing as '\'.table[d] in word.
+  amenu &Matchit.t&able	:echo '0:' . b:match_table . ':9'<CR>
+endfun
+
+" Jump to the nearest unmatched "(" or "if" or "<tag>" if a:spflag == "bW"
+" or the nearest unmatched "</tag>" or "endif" or ")" if a:spflag == "W".
+" Return a "mark" for the original position, so that
+"   let m = MultiMatch("bW", "n") ... execute m
+" will return to the original position.  If there is a problem, do not
+" move the cursor and return "", unless a count is given, in which case
+" go up or down as many levels as possible and again return "".
+" TODO This relies on the same patterns as % matching.  It might be a good
+" idea to give it its own matching patterns.
+fun! s:MultiMatch(spflag, mode)
+  if !exists("b:match_words") || b:match_words == ""
+    return ""
+  end
+  let restore_options = (&ic ? "" : "no") . "ignorecase"
+  if exists("b:match_ignorecase")
+    let &ignorecase = b:match_ignorecase
+  endif
+  let startline = line(".")
+  let startcol = col(".")
+
+  " First step:  if not already done, set the script variables
+  "   s:do_BR	flag for whether there are backrefs
+  "   s:pat	parsed version of b:match_words
+  "   s:all	regexp based on s:pat and the default groups
+  " This part is copied and slightly modified from s:Match_wrapper().
+  let default = escape(&mps, '[$^.*~\\/?]') . (strlen(&mps) ? "," : "") .
+    \ '\/\*:\*\/,#if\%(def\)\=:$else\>:#elif\>:#endif\>'
+  " Allow b:match_words = "GetVimMatchWords()" .
+  if b:match_words =~ ":"
+    let match_words = b:match_words
+  else
+    execute "let match_words =" b:match_words
+  endif
+  if (match_words != s:last_words) || (&mps != s:last_mps) ||
+    \ exists("b:match_debug")
+    let s:last_words = match_words
+    let s:last_mps = &mps
+    if match_words !~ s:notslash . '\\\d'
+      let s:do_BR = 0
+      let s:pat = match_words
+    else
+      let s:do_BR = 1
+      let s:pat = s:ParseWords(match_words)
+    endif
+    let s:all = '\%(' . substitute(s:pat . (strlen(s:pat)?",":"") . default,
+      \	'[,:]\+','\\|','g') . '\)'
+    if exists("b:match_debug")
+      let b:match_pat = s:pat
+    endif
+  endif
+
+  " Second step:  figure out the patterns for searchpair()
+  " and save the screen, cursor position, and 'ignorecase'.
+  " - TODO:  A lot of this is copied from s:Match_wrapper().
+  " - maybe even more functionality should be split off
+  " - into separate functions!
+  let cdefault = (s:pat =~ '[^,]$' ? "," : "") . default
+  let open =  substitute(s:pat . cdefault, ':[^,]*,', '\\),\\(', 'g')
+  let open =  '\(' . substitute(open, ':[^,]*$', '\\)', '')
+  let close = substitute(s:pat . cdefault, ',[^,]*:', '\\),\\(', 'g')
+  let close = substitute(close, '[^,]*:', '\\(', '') . '\)'
+  if exists("b:match_skip")
+    let skip = b:match_skip
+  elseif exists("b:match_comment") " backwards compatibility and testing!
+    let skip = "r:" . b:match_comment
+  else
+    let skip = 's:comment\|string'
+  endif
+  let skip = s:ParseSkip(skip)
+  " let restore_cursor = line(".") . "G" . virtcol(".") . "|"
+  " normal! H
+  " let restore_cursor = "normal!" . line(".") . "Gzt" . restore_cursor
+  let restore_cursor = virtcol(".") . "|"
+  normal! g0
+  let restore_cursor = line(".") . "G" .  virtcol(".") . "|zs" . restore_cursor
+  normal! H
+  let restore_cursor = "normal!" . line(".") . "Gzt" . restore_cursor
+  execute restore_cursor
+
+  " Third step: call searchpair().
+  " Replace '\('--but not '\\('--with '\%(' and ',' with '\|'.
+  let openpat =  substitute(open, '\(\\\@<!\(\\\\\)*\)\@<=\\(', '\\%(', 'g')
+  let openpat = substitute(openpat, ',', '\\|', 'g')
+  let closepat = substitute(close, '\(\\\@<!\(\\\\\)*\)\@<=\\(', '\\%(', 'g')
+  let closepat = substitute(closepat, ',', '\\|', 'g')
+  if skip =~ 'synID' && !(has("syntax") && exists("g:syntax_on"))
+    let skip = '0'
+  else
+    execute "if " . skip . "| let skip = '0' | endif"
+  endif
+  mark '
+  let level = v:count1
+  while level
+    if searchpair(openpat, '', closepat, a:spflag, skip) < 1
+      call s:CleanUp(restore_options, a:mode, startline, startcol)
+      return ""
+    endif
+    let level = level - 1
+  endwhile
+
+  " Restore options and return a string to restore the original position.
+  call s:CleanUp(restore_options, a:mode, startline, startcol)
+  return restore_cursor
+endfun
+
+" Search backwards for "if" or "while" or "<tag>" or ...
+" and return "endif" or "endwhile" or "</tag>" or ... .
+" For now, this uses b:match_words and the same script variables
+" as s:Match_wrapper() .  Later, it may get its own patterns,
+" either from a buffer variable or passed as arguments.
+" fun! s:Autocomplete()
+"   echo "autocomplete not yet implemented :-("
+"   if !exists("b:match_words") || b:match_words == ""
+"     return ""
+"   end
+"   let startpos = s:MultiMatch("bW")
+"
+"   if startpos == ""
+"     return ""
+"   endif
+"   " - TODO:  figure out whether 'if' or '<tag>' matched, and construct
+"   " - the appropriate closing.
+"   let matchline = getline(".")
+"   let curcol = col(".") - 1
+"   " - TODO:  Change the s:all argument if there is a new set of match pats.
+"   let regexp = s:Wholematch(matchline, s:all, curcol)
+"   let suf = strlen(matchline) - matchend(matchline, regexp)
+"   let prefix = (curcol ? '^.\{'  . curcol . '}\%(' : '^\%(')
+"   let suffix = (suf ? '\).\{' . suf . '}$'  : '\)$')
+"   " Reconstruct the version with unresolved backrefs.
+"   let patBR = substitute(b:match_words.',', '[,:]*,[,:]*', ',', 'g')
+"   let patBR = substitute(patBR, ':\{2,}', ':', "g")
+"   " Now, set group and groupBR to the matching group: 'if:endif' or
+"   " 'while:endwhile' or whatever.
+"   let group = s:Choose(s:pat, matchline, ",", ":", prefix, suffix, patBR)
+"   let i = matchend(group, s:notslash . ",")
+"   let groupBR = strpart(group, i)
+"   let group = strpart(group, 0, i-1)
+"   " Now, matchline =~ prefix . substitute(group,':','\|','g') . suffix
+"   if s:do_BR
+"     let group = s:InsertRefs(groupBR, prefix, group, suffix, matchline)
+"   endif
+" " let g:group = group
+"
+"   " - TODO:  Construct the closing from group.
+"   let fake = "end" . expand("<cword>")
+"   execute startpos
+"   return fake
+" endfun
+
+" Close all open structures.  "Get the heck out of here!"
+" fun! s:Gthhoh()
+"   let close = s:Autocomplete()
+"   while strlen(close)
+"     put=close
+"     let close = s:Autocomplete()
+"   endwhile
+" endfun
+
+" Parse special strings as typical skip arguments for searchpair():
+"   s:foo becomes (current syntax item) =~ foo
+"   S:foo becomes (current syntax item) !~ foo
+"   r:foo becomes (line before cursor) =~ foo
+"   R:foo becomes (line before cursor) !~ foo
+fun! s:ParseSkip(str)
+  let skip = a:str
+  if skip[1] == ":"
+    if skip[0] == "s"
+      let skip = "synIDattr(synID(line('.'),col('.'),1),'name') =~? '" .
+	\ strpart(skip,2) . "'"
+    elseif skip[0] == "S"
+      let skip = "synIDattr(synID(line('.'),col('.'),1),'name') !~? '" .
+	\ strpart(skip,2) . "'"
+    elseif skip[0] == "r"
+      let skip = "strpart(getline('.'),0,col('.'))=~'" . strpart(skip,2). "'"
+    elseif skip[0] == "R"
+      let skip = "strpart(getline('.'),0,col('.'))!~'" . strpart(skip,2). "'"
+    endif
+  endif
+  return skip
+endfun
+
+let &cpo = s:save_cpo
+
+" vim:sts=2:sw=2:
--- /dev/null
+++ b/lib/vimfiles/macros/maze/Makefile
@@ -1,0 +1,7 @@
+# It's simple...
+
+maze: mazeansi.c
+	cc -o maze mazeansi.c
+
+mazeclean: mazeclean.c
+	cc -o mazeclean mazeclean.c
--- /dev/null
+++ b/lib/vimfiles/macros/maze/README.txt
@@ -1,0 +1,49 @@
+To run the maze macros with Vim:
+
+	vim -u maze_mac maze_5.78
+	press "g"
+
+The "-u maze.mac" loads the maze macros and skips loading your .vimrc, which
+may contain settings and mappings that get in the way.
+
+
+The original README:
+
+To prove that you can do anything in vi, I wrote a couple of macros that
+allows vi to solve mazes. It will solve any maze produced by maze.c
+that was posted to the net recently.
+
+Just follow this recipe and SEE FOR YOURSELF.
+	1. run uudecode on the file "maze.vi.macros.uu" to
+		produce the file "maze.vi.macros"
+	(If you can't wait to see the action, jump to step 4)
+	2. compile maze.c with "cc -o maze maze.c"
+	3. run maze > maze.out and input a small number (for example 10 if
+		you are on a fast machine, 3-5 if slow) which
+		is the size of the maze to produce
+	4. edit the maze (vi maze.out)
+	5. include the macros with the vi command:
+		:so maze.vi.macros
+	6. type the letter "g" (for "go") and watch vi solve the maze
+	7. when vi solves the maze, you will see why it lies
+	8. now look at maze.vi.macros and all will be revealed
+
+Tested on a sparc, a sun and a pyramid (although maze.c will not compile
+on the pyramid).
+
+Anyone who can't get the maze.c file to compile, get a new compiler,
+try maze.ansi.c which was also posted to the net.
+If you can get it to compile but the maze comes out looking like a fence
+and not a maze and you are using SysV or DOS replace the "27" on the
+last line of maze.c by "11"
+Thanks to John Tromp (tromp@piring.cwi.nl) for maze.c.
+Thanks to antonyc@nntp-server.caltech.edu (Bill T. Cat) for maze.ansi.c.
+
+Any donations should be in unmarked small denomination bills :^)=.
+
+		   ACSnet:  gregm@otc.otca.oz.au
+Greg McFarlane	     UUCP:  {uunet,mcvax}!otc.otca.oz.au!gregm
+|||| OTC ||	    Snail:  OTC R&D GPO Box 7000, Sydney 2001, Australia
+		    Phone:  +61 2 287 3139    Fax: +61 2 287 3299
+
+
--- /dev/null
+++ b/lib/vimfiles/macros/maze/main.aap
@@ -1,0 +1,4 @@
+# Aap recipe to build the maze program
+:program maze : mazeansi.c
+
+:program mazeclean : mazeclean.c
--- /dev/null
+++ b/lib/vimfiles/macros/maze/maze.c
@@ -1,0 +1,7 @@
+char*M,A,Z,E=40,J[40],T[40];main(C){for(*J=A=scanf(M="%d",&C);
+--            E;             J[              E]             =T
+[E   ]=  E)   printf("._");  for(;(A-=Z=!Z)  ||  (printf("\n|"
+)    ,   A    =              39              ,C             --
+)    ;   Z    ||    printf   (M   ))M[Z]=Z[A-(E   =A[J-Z])&&!C
+&    A   ==             T[                                  A]
+|6<<27<rand()||!C&!Z?J[T[E]=T[A]]=E,J[T[A]=A-Z]=A,"_.":" |"];}
--- /dev/null
+++ b/lib/vimfiles/macros/maze/maze_5.78
@@ -1,0 +1,16 @@
+._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._
+| ._| . . ._| | |_._._. . ._|_._._._._. ._|_. ._|_._. ._| . ._|_. | . ._._. |
+| ._|_| |_. | | | | ._._|_._|_._. . |_. | | | ._._| |_._._| | ._. ._| . . |_|
+|_._._._. | ._|_. ._._._. | | ._. |_._. . | ._._| |_. | ._._._. |_. | |_|_| |
+| | . |_._| . ._._._| ._._. ._._| | | |_| . | |_. . ._|_| ._._. |_._|_| . | |
+|_._|_._._._|_._._._|_|_._._._|_._|_._._._|_._._._|_._._._|_._._._._._._|_._|
+
+See Vim solve a maze!
+
+   type ":so maze_mac<RETURN>" to load the macros
+
+   type "g" to start
+
+to interrupt type "<CTRL-C>"
+     to quit type ":q!<RETURN>"
+
--- /dev/null
+++ b/lib/vimfiles/macros/maze/maze_mac
@@ -1,0 +1,271 @@
+" These macros 'solve' any maze produced by the a-maze-ing maze.c program.
+"
+" First, a bit of maze theory.
+" If you were put into a maze, a guaranteed method of finding your way
+" out of the maze is to put your left hand onto a wall and just keep walking,
+" never taking your hand off the wall. This technique is only guaranteed to
+" work if the maze does not have any 'islands', or if the 'exit' is on the
+" same island as your starting point. These conditions hold for the mazes
+" under consideration.
+"
+" Assuming that the maze is made up of horizontal and vertical walls spaced
+" one step apart and that you can move either north, south, east or west,
+" then you can automate this procedure by carrying out the following steps.
+"
+" 1. Put yourself somewhere in the maze near a wall.
+" 2. Check if you have a wall on your left. If so, go to step 4.
+" 3. There is no wall on your left, so turn on the spot to your left and step
+"    forward by one step and repeat step 2.
+" 4. Check what is directly in front of you. If it is a wall, turn on the
+"    spot to your right by 90 degrees and repeat step 4.
+" 5. There is no wall in front of you, so step forward one step and
+"    go to step 2.
+"
+" In this way you will cover all the corridors of the maze (until you get back
+" to where you started from, if you do not stop).
+"
+" By examining a maze produced by the maze.c program you will see that
+" each square of the maze is one character high and two characters wide.
+" To go north or south, you move by a one character step, but to move east or
+" west you move by a two character step. Also note that in any position
+" there are four places where walls could be put - to the north, to the south,
+" to the east and to the west.
+" A wall exists to the north of you if the character to the north of
+" you is a _ (otherwise it is a space).
+" A wall exists to the east of you if the character to the east of you
+" is a | (otherwise it is a .).
+" A wall exists to the west of you if the character to the west of you
+" is a | (otherwise it is a .).
+" A wall exists to the south of you if the character where you are
+" is a _ (otherwise it is a space).
+"
+" Note the difference for direction south, where we must examine the character
+" where the cursor is rather than an adjacent cell.
+"
+" If you were implementing the above procedure is a normal computer language
+" you could use a loop with if statements and continue statements,
+" However, these constructs are not available in vi macros so I have used
+" a state machine with 8 states. Each state signifies the direction you
+" are going in and whether or not you have checked if there is a wall on
+" your left.
+"
+" The transition from state to state and the actions taken on each transition
+" are given in the state table below.
+" The names of the states are N1, N2, S1, S2, E1, E2, W1, W2, where each letter
+" stands for a direction of the compass, the number 1 indicates that the we
+" have not yet checked to see if there is a wall on our left and the number 2
+" indicates that we have checked and there is a wall on our left.
+"
+" For each state we must consider the existence or not of a wall in a
+" particular direction. This direction is given in the following table.
+"
+" NextChar table:
+" state        direction       vi commands
+"  N1              W               hF
+"  N2              N               kF
+"  S1              E               lF
+"  S2              S               F
+"  E1              N               kF
+"  E2              E               lF
+"  W1              S               F
+"  W2              W               hF
+"
+" where F is a macro which yanks the character under the cursor into
+" the NextChar register (n).
+"
+" State table:
+" In the 'vi commands' column is given the actions to carry out when in
+" this state and the NextChar is as given. The commands k, j, ll, hh move
+" the current position north, south, east and west respectively. The
+" command mm is used as a no-op command.
+" In the 'next state' column is given the new state of the machine after
+" the action is carried out.
+"
+" current state        NextChar    vi commands  next state
+"      N1                 .            hh          W1
+"      N1                 |            mm          N2
+"      N2                 _            mm          E1
+"      N2               space          k           N1
+"      S1                 .            ll          E1
+"      S1                 |            mm          S2
+"      S2                 _            mm          W1
+"      S2               space          j           S1
+"      E1               space          k           N1
+"      E1                 _            mm          E2
+"      E2                 |            mm          S1
+"      E2                 .            ll          E1
+"      W1               space          j           S1
+"      W1                 _            mm          W2
+"      W2                 |            mm          N1
+"      W2                 .            hh          W1
+"
+"
+" Complaint about vi macros:
+" It seems that you cannot have more than one 'undo-able' vi command
+" in the one macro, so you have to make lots of little macros and
+" put them together.
+"
+" I'll explain what I mean by an example. Edit a file and
+" type ':map Q rXY'. This should map the Q key to 'replace the
+" character under the cursor with X and yank the line'.
+" But when I type Q, vi tells me 'Can't yank inside global/macro' and
+" goes into ex mode. However if I type ':map Q rXT' and ':map T Y',
+" everything is OK. I`m doing all this on a Sparcstation.
+" If anyone reading this has an answer to this problem, the author would
+" love to find out. Mail to gregm@otc.otca.oz.au.
+"
+" The macros:
+" The macro to run the maze solver is 'g'. This simply calls two other
+" macros: I, to initialise everything, and L, to loop forever running
+" through the state table.
+" Both of these macros are long sequences of calls to other macros. All
+" of these other macros are quite simple and so to understand how this
+" works, all you need to do is examine macros I and L and learn what they
+" do (a simple sequence of vi actions) and how L loops (by calling U, which
+" simply calls L again).
+"
+" Macro I sets up the state table and NextChar table at the end of the file.
+" Macro L then searches these tables to find out what actions to perform and
+" what state changes to make.
+"
+" The entries in the state table all begin with a key consisting of the
+" letter 's', the current state and the NextChar.  After this is the
+" action to take in this state and after this is the next state to change to.
+"
+" The entries in the NextChar table begin with a key consisting of the
+" letter 'n' and the current state. After this is the action to take to
+" obtain NextChar - the character that must be examined to change state.
+"
+" One way to see what each part of the macros is doing is to type in the
+" body of the macros I and L manually (instead of typing 'g') and see
+" what happens at each step.
+"
+" Good luck.
+"
+" Registers used by the macros:
+" s (State)        - holds the state the machine is in
+" c (Char)         - holds the character under the current position
+" m (Macro)        - holds a vi command string to be executed later
+" n (NextChar)     - holds the character we must examine to change state
+" r (Second Macro) - holds a second vi command string to be executed later
+"
+set remap
+set nomagic
+set noterse
+set wrapscan
+"
+"================================================================
+" g - go runs the whole show
+"        I - initialise
+"        L - then loop forever
+map g   IL
+"
+"================================================================
+" I - initialise everything before running the loop
+"   G$?.^M - find the last . in the maze
+"        ^ - replace it with an X (the goal)
+"   GYKeDP - print the state table and next char table at the end of the file
+"       0S - initialise the state of the machine to E1
+"      2Gl - move to the top left cell of the maze
+map I   G$?.
^GYKeDP0S2Gl
+"
+"================================================================
+" L - the loop which is executed forever
+"        Q - save the current character in the Char register
+"        A - replace the current character with an 'O'
+"       ma - mark the current position with mark 'a'
+"      GNB - on bottom line, create a command to search the NextChar table
+"            for the current state
+" 0M0E@m^M - yank the command into the Macro register and execute it
+"       wX - we have now found the entry in the table, now yank the
+"            following word into the Macro register
+"     `a@m - go back to the current position and execute the macro, this will
+"            yank the NextChar in register n
+"   GT$B$R - on bottom line, create a command to search the state table
+"            for the current state and NextChar
+" 0M0E@m^M - yank the command into the Macro register and execute it
+"      2WS - we have now found the entry in the table, now yank the
+"            next state into the State macro
+"       bX - and yank the action corresponding to this state table entry
+"            into the Macro register
+"      GVJ - on bottom line, create a command to restore the current character
+"       0H - and save the command into the second Macro register
+"     `a@r - go back to the current position and exectute the macro to restore
+"            the current character
+"       @m - execute the action associated with this state
+"        U - and repeat
+map L   QAmaGNB0M0E@m
wX`a@mGT$B$R0M0E@m
2WSbXGVJ0H`a@r@mU
+"
+"================================================================
+" U - no tail recursion allowed in vi macros so cheat and set U = L
+map U   L
+"
+"================================================================
+" S - yank the next two characters into the State register
+map S   "sy2l
+"
+"================================================================
+" Q - save the current character in the Char register
+map Q   "cyl
+"
+"================================================================
+" A - replace the current character with an 'O'
+map A   rO
+"
+"================================================================
+" N - replace this line with the string 'n'
+map N   C/n
+"
+"================================================================
+" B - put the current state
+map B   "sp
+"
+"================================================================
+" M - yank this line into the Macro register
+map M   "my$
+"
+"================================================================
+" E - delete to the end of the line
+map E   d$
+"
+"================================================================
+" X - yank this word into the Macro register
+map X   "myt 
+"
+"================================================================
+" T - replace this line with the string 's'
+map T   C/s
+"
+"================================================================
+" R - put NextChar
+map R   "np
+"
+"================================================================
+" V - add the letter 'r' (the replace vi command)
+map V   ar
+"
+"================================================================
+" J - restore the current character
+map J   "cp
+"
+"================================================================
+" H - yank this line into the second Macro register
+map H   "ry$
+"
+"================================================================
+" F - yank NextChar (this macro is called from the Macro register)
+map F   "nyl
+"
+"================================================================
+" ^ - replace the current character with an 'X'
+map ^   rX
+"
+"================================================================
+" YKeDP - create the state table, NextChar table and initial state
+" Note that you have to escape the bar character, since it is special to
+" the map command (it indicates a new line).
+map Y   osE1  k  N1       sE1_ mm E2       sE2| mm S1       sE2. ll E1
+map K   osW1  j  S1       sW1_ mm W2       sW2| mm N1       sW2. hh W1
+map e   osN1. hh W1       sN1| mm N2       sN2  k  N1       sN2_ mm E1
+map D   osS1. ll E1       sS1| mm S2       sS2  j  S1       sS2_ mm W1
+map P   onE1 kF nE2 lF nW1 G$JF nW2 hF nN1 hF nN2 kF nS1 lF nS2 G$JF 
E1
--- /dev/null
+++ b/lib/vimfiles/macros/maze/mazeansi.c
@@ -1,0 +1,7 @@
+char*M,A,Z,E=40,J[80],T[3];main(C){for(M=J+E,*J=A=scanf("%d",&
+C)            ;--            E;J             [E            ]=M
+[E   ]=  E)   printf("._");  for(;(A-=Z=!Z)  ||  (printf("\n|"
+)    ,   A    =              39              ,C             --
+)    ;   Z    ||    printf   (T   ))T[Z]=Z[A-(E   =A[J-Z])&&!C
+&    A   ==             M[                                  A]
+|6<<27<rand()||!C&!Z?J[M[E]=M[A]]=E,J[M[A]=A-Z]=A,"_.":" |"];}
--- /dev/null
+++ b/lib/vimfiles/macros/maze/mazeclean.c
@@ -1,0 +1,22 @@
+/*
+ * Cleaned-up version of the maze program.
+ * Doesn't look as nice, but should work with all C compilers.
+ * Sascha Wilde, October 2003
+ */
+#include <stdio.h>
+#include <stdlib.h>
+
+char *M, A, Z, E = 40, line[80], T[3];
+int
+main (C)
+{
+  for (M = line + E, *line = A = scanf ("%d", &C); --E; line[E] = M[E] = E)
+    printf ("._");
+  for (; (A -= Z = !Z) || (printf ("\n|"), A = 39, C--); Z || printf (T))
+    T[Z] = Z[A - (E = A[line - Z]) && !C
+	     & A == M[A]
+	     | RAND_MAX/3 < rand ()
+	     || !C & !Z ? line[M[E] = M[A]] = E, line[M[A] = A - Z] =
+	     A, "_." : " |"];
+  return 0;
+}
--- /dev/null
+++ b/lib/vimfiles/macros/maze/poster
@@ -1,0 +1,37 @@
+Article 2846 of alt.sources:
+Path: oce-rd1!hp4nl!mcsun!uunet!munnari.oz.au!metro!otc!gregm
+From: gregm@otc.otca.oz.au (Greg McFarlane)
+Newsgroups: alt.sources
+Subject: VI SOLVES MAZE (commented macros)
+Message-ID: <2289@otc.otca.oz>
+Date: 10 Feb 91 23:31:02 GMT
+Sender: news@otc.otca.oz
+Reply-To: gregm@otc.otca.oz.au (Greg McFarlane)
+Organization: OTC Development Unit, Australia
+Lines: 464
+
+Submitted-by: gregm@otc.otca.oz.au
+Archive-name: maze_solving_vi_macros
+
+A real working model. See it walk the maze in front of your very own eyes.
+
+To prove that you can do anything in vi, I wrote a couple of macros that
+allows vi to solve mazes. It will solve any maze produced by maze.c
+that was posted to the alt.sources last month. (Maze.c is also included
+in this posting as well as an example of its output.)
+
+The uncommented version of the macros was sent to alt.sources last month.
+However, so many people mailed me requesting the commented version of the
+macros that I decided to post it. I have made some modifications to the
+original macros to make them easier to follow and also after I learnt
+that you can escape the special meaning of '|' in macros by using '^V|'.
+
+Save this article and unshar it. Then read maze.README.
+
+After studying these macros, anyone who cannot write an emacs emulator
+in vi macros should just curl up and :q!.
+
+Coming soon to a newsgroup near you: "Vi macros solve Tower of Hanoi",
+and a repost of the original "Turing Machine implemented in Vi macros"
+
+Anyone who has a version of these macros for edlin or nroff, please post.
--- /dev/null
+++ b/lib/vimfiles/macros/shellmenu.vim
@@ -1,0 +1,94 @@
+" When you're writing shell scripts and you are in doubt which test to use,
+" which shell environment variables are defined, what the syntax of the case
+" statement is, and you need to invoke 'man sh'?
+"
+" Your problems are over now!
+"
+" Attached is a Vim script file for turning gvim into a shell script editor.
+" It may also be used as an example how to use menus in Vim.
+"
+" Written by: Lennart Schultz <les@dmi.min.dk>
+
+imenu Stmts.for	for  in 
do

doneki	kk0elli
+imenu Stmts.case	case  in
) ;;
esacbki	k0elli
+imenu Stmts.if	if   
then

fiki	kk0elli
+imenu Stmts.if-else	if   
then

else

fiki	kki	kk0elli
+imenu Stmts.elif	elif   
then

ki	kk0elli
+imenu Stmts.while	while   
do

doneki	kk0elli
+imenu Stmts.break	break 
+imenu Stmts.continue	continue 
+imenu Stmts.function	() {

}ki	k0i
+imenu Stmts.return	return 
+imenu Stmts.return-true	return 0
+imenu Stmts.return-false	return 1
+imenu Stmts.exit	exit 
+imenu Stmts.shift	shift 
+imenu Stmts.trap	trap 
+imenu Test.existence	[ -e  ]hi
+imenu Test.existence - file		[ -f  ]hi
+imenu Test.existence - file (not empty)	[ -s  ]hi
+imenu Test.existence - directory	[ -d  ]hi
+imenu Test.existence - executable	[ -x  ]hi
+imenu Test.existence - readable	[ -r  ]hi
+imenu Test.existence - writable	[ -w  ]hi
+imenu Test.String is empty [ x = "x$" ]hhi
+imenu Test.String is not empty [ x != "x$" ]hhi
+imenu Test.Strings is equal [ "" = "" ]hhhhhhhi
+imenu Test.Strings is not equal [ "" != "" ]hhhhhhhhi
+imenu Test.Values is greater than [  -gt  ]hhhhhhi
+imenu Test.Values is greater equal [  -ge  ]hhhhhhi
+imenu Test.Values is equal [  -eq  ]hhhhhhi
+imenu Test.Values is not equal [  -ne  ]hhhhhhi
+imenu Test.Values is less than [  -lt  ]hhhhhhi
+imenu Test.Values is less equal [  -le  ]hhhhhhi
+imenu ParmSub.Substitute word if parm not set ${:-}hhi
+imenu ParmSub.Set parm to word if not set ${:=}hhi
+imenu ParmSub.Substitute word if parm set else nothing ${:+}hhi
+imenu ParmSub.If parm not set print word and exit ${:?}hhi
+imenu SpShVars.Number of positional parameters ${#}
+imenu SpShVars.All positional parameters (quoted spaces) ${*}
+imenu SpShVars.All positional parameters (unquoted spaces) ${@}
+imenu SpShVars.Flags set ${-}
+imenu SpShVars.Return code of last command ${?}
+imenu SpShVars.Process number of this shell ${$}
+imenu SpShVars.Process number of last background command ${!}
+imenu Environ.HOME ${HOME}
+imenu Environ.PATH ${PATH}
+imenu Environ.CDPATH ${CDPATH}
+imenu Environ.MAIL ${MAIL}
+imenu Environ.MAILCHECK ${MAILCHECK}
+imenu Environ.PS1 ${PS1}
+imenu Environ.PS2 ${PS2}
+imenu Environ.IFS ${IFS}
+imenu Environ.SHACCT ${SHACCT}
+imenu Environ.SHELL ${SHELL}
+imenu Environ.LC_CTYPE ${LC_CTYPE}
+imenu Environ.LC_MESSAGES ${LC_MESSAGES}
+imenu Builtins.cd cd
+imenu Builtins.echo echo
+imenu Builtins.eval eval
+imenu Builtins.exec exec
+imenu Builtins.export export
+imenu Builtins.getopts getopts
+imenu Builtins.hash hash
+imenu Builtins.newgrp newgrp
+imenu Builtins.pwd pwd
+imenu Builtins.read read
+imenu Builtins.readonly readonly
+imenu Builtins.return return
+imenu Builtins.times times
+imenu Builtins.type type
+imenu Builtins.umask umask
+imenu Builtins.wait wait
+imenu Set.set set
+imenu Set.unset unset
+imenu Set.mark modified or modified variables set -a
+imenu Set.exit when command returns non-zero exit code set -e
+imenu Set.Disable file name generation set -f
+imenu Set.remember function commands set -h
+imenu Set.All keyword arguments are placed in the environment set -k
+imenu Set.Read commands but do not execute them set -n
+imenu Set.Exit after reading and executing one command set -t
+imenu Set.Treat unset variables as an error when substituting set -u
+imenu Set.Print shell input lines as they are read set -v
+imenu Set.Print commands and their arguments as they are executed set -x
--- /dev/null
+++ b/lib/vimfiles/macros/swapmous.vim
@@ -1,0 +1,22 @@
+" These macros swap the left and right mouse buttons (for left handed)
+" Don't forget to do ":set mouse=a" or the mouse won't work at all
+noremap	 <LeftMouse>	<RightMouse>
+noremap	 <2-LeftMouse>	<2-RightMouse>
+noremap	 <3-LeftMouse>	<3-RightMouse>
+noremap	 <4-LeftMouse>	<4-RightMouse>
+noremap	 <LeftDrag>	<RightDrag>
+noremap	 <LeftRelease>	<RightRelease>
+noremap	 <RightMouse>	<LeftMouse>
+noremap	 <2-RightMouse>	<2-LeftMouse>
+noremap	 <3-RightMouse>	<3-LeftMouse>
+noremap	 <4-RightMouse>	<4-LeftMouse>
+noremap	 <RightDrag>	<LeftDrag>
+noremap	 <RightRelease>	<LeftRelease>
+noremap	 g<LeftMouse>	<C-RightMouse>
+noremap	 g<RightMouse>	<C-LeftMouse>
+noremap! <LeftMouse>	<RightMouse>
+noremap! <LeftDrag>	<RightDrag>
+noremap! <LeftRelease>	<RightRelease>
+noremap! <RightMouse>	<LeftMouse>
+noremap! <RightDrag>	<LeftDrag>
+noremap! <RightRelease>	<LeftRelease>
--- /dev/null
+++ b/lib/vimfiles/macros/urm/README.txt
@@ -1,0 +1,47 @@
+This is another proof that Vim is perfectly compatible with Vi.
+The URM macro package was written by Rudolf Koenig ("Rudi")
+(rudolf@koeniglich.de) for hpux-vi in August 1991.
+
+Getting started:
+
+type
+in your shell:	 vim urm<RETURN>
+in vim:		 :so urm.vim<RETURN>
+in vim:		 *	(to load the registers and boot the URM-machine :-)
+in vim:		 g	(for 'go') and watch the fun. Per default, 3 and 4
+			are multiplied. Watch the Program counter, it is
+			visible as a komma moving around.
+
+This is a "standard URM" (Universal register machine)  interpreter. The URM
+concept is used in theoretical computer science to aid in theorem proving.
+Here it proves that vim is a general problem solver (if you bring enough
+patience).
+
+The interpreter begins with register 1 (not 0), without macros and more-lines
+capability.  A dot marks the end of a program. (Bug: there must be a space
+after the dot.)
+
+The registers are the first few lines, beginning with a '>' .
+The program is the first line after the registers.
+You should always initialize the registers required by the program.
+
+Output register:	line 2
+Input registers:	line 2 to ...
+
+Commands:
+a<n>		increment register <n>
+s<n>		decrement register <n>
+<x>;<y>		execute command <x> and then <y>
+(<x>)<n>	execute command <x> while register <n> is nonzero
+. 		("dot blank")  halt the machine.
+
+Examples:
+
+Add register 2 to register 3:
+	(a2;s3)3.
+Multiply register 2 with register 3:
+	(a4;a5;s2)2; ((a2;s4)4; s3; (a1;a4;s5)5; (a5;s1)1)3.
+
+There are more (complicated) examples in the file examples.
+Note, undo may take a while after a division.
+
--- /dev/null
+++ b/lib/vimfiles/macros/urm/examples
@@ -1,0 +1,16 @@
+Note that enough temporary registers should be provided for each example.
+All should be initialised to 0.
+
+Initial register values for benchmarking: 0,8,3,0,...
+
+Performed on a Xenix 386/16:
+Operation [sec, kbyte tmp space]: program
+
+Asym. Diff.[ 7, 4]: (s2;s3)3. 
+Abs. 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. 
+Add  [  7,   4]: (a2;s3)3. 
+Mult [227, 161]: (a4;a5;s2)2; ((a2;s4)4; s3; (a1;a4;s5)5; (a5;s1)1)3. 
+Copy [ 48,  25]: (a1;a3;s2)2; (a2;s1)1. 
+sign [ 30,  17]: (a3;s2)2; (a2;(s3)3)3. 
+!sign[ 36,  28]: (a3;s2)2; (a2;(s3)3)3; a3; (s3;s2)2; (s3;a2)3.  
+Div  [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. 
--- /dev/null
+++ b/lib/vimfiles/macros/urm/urm
@@ -1,0 +1,22 @@
+>0
+>3
+>4
+>0
+>0
+>0
+(a4;a5;s2)2; ((a2;s4)4; s3; (a1;a4;s5)5; (a5;s1)1)3. 
+_________
+O	; =xp ( =x%hp ) @l a @db s @dt . =x0xkdd:ready _end_
+o	0 1 2 3 4 5 6 7 8 9 0
+_________
+INIT main(k), l, b, c, t, u, q, d 
+
"kT
"lT
"bT
"cT
"tT
"uT
"qT
"dT
+=lF'wa/O
fpaw"zdt hp@z0"xD@x@k
+=2ldwhp'wiGT'wp0P0"yD@ya =xlwP >0 =x%p I k/>0
ww"ydt 0D@y
+'wa/o
fwF'wpi`ar`aF'wffp0"vD@v0"vDp03x@v'wa @c 0 0 0I f0w"wdt 0D@w
+`ahmaF'wa  'aa1 > @b 0p0f>w"vdt 0D@v
+'wa/o
wfbF'wpi`ar`aF'wffp0"vD@v0"vDp03x@v'wa @u 9 0 0I f9w"wdt 0D@w
+`ahmaF'wa  `alr0 > @q 0p0f>w"vdt 0D@v
+`ahy2l'wa  `ax >1 @t 0p0/>1
ww"idt 0D@i
+=xwhpbldwhp'wpaG$ma0"yD@y@
+
--- /dev/null
+++ b/lib/vimfiles/macros/urm/urm.vim
@@ -1,0 +1,5 @@
+map * 1G/INIT
j"iT@i1G/INIT
dG
+map g 1G/^[(as;.]
i
>,mkkmw@k
+map T y$
+map F yl
+map = 'kf,
--- /dev/null
+++ b/lib/vimfiles/makemenu.vim
@@ -1,0 +1,560 @@
+" Script to define the syntax menu in synmenu.vim
+" Maintainer:	Bram Moolenaar <Bram@vim.org>
+" Last Change:	2007 May 10
+
+" This is used by "make menu" in the src directory.
+edit <sfile>:p:h/synmenu.vim
+
+/The Start Of The Syntax Menu/+1,/The End Of The Syntax Menu/-1d
+let s:lnum = line(".") - 1
+call append(s:lnum, "")
+let s:lnum = s:lnum + 1
+
+" Use the SynMenu command and function to define all menu entries
+command! -nargs=* SynMenu call <SID>Syn(<q-args>)
+
+let s:cur_menu_name = ""
+let s:cur_menu_nr = 0
+let s:cur_menu_item = 0
+let s:cur_menu_char = ""
+
+fun! <SID>Syn(arg)
+  " isolate menu name: until the first dot
+  let i = match(a:arg, '\.')
+  let menu_name = strpart(a:arg, 0, i)
+  let r = strpart(a:arg, i + 1, 999)
+  " isolate submenu name: until the colon
+  let i = match(r, ":")
+  let submenu_name = strpart(r, 0, i)
+  " after the colon is the syntax name
+  let syntax_name = strpart(r, i + 1, 999)
+
+  if s:cur_menu_name != menu_name
+    let s:cur_menu_name = menu_name
+    let s:cur_menu_nr = s:cur_menu_nr + 10
+    let s:cur_menu_item = 100
+    let s:cur_menu_char = submenu_name[0]
+  else
+    " When starting a new letter, insert a menu separator.
+    let c = submenu_name[0]
+    if c != s:cur_menu_char
+      exe 'an 50.' . s:cur_menu_nr . '.' . s:cur_menu_item . ' &Syntax.' . menu_name . ".-" . c . '- <nul>'
+      let s:cur_menu_item = s:cur_menu_item + 10
+      let s:cur_menu_char = c
+    endif
+  endif
+  call append(s:lnum, 'an 50.' . s:cur_menu_nr . '.' . s:cur_menu_item . ' &Syntax.' . menu_name . "." . submenu_name . ' :cal SetSyn("' . syntax_name . '")<CR>')
+  let s:cur_menu_item = s:cur_menu_item + 10
+  let s:lnum = s:lnum + 1
+endfun
+
+SynMenu AB.A2ps\ config:a2ps
+SynMenu AB.Aap:aap
+SynMenu AB.ABAP/4:abap
+SynMenu AB.Abaqus:abaqus
+SynMenu AB.ABC\ music\ notation:abc
+SynMenu AB.ABEL:abel
+SynMenu AB.AceDB\ model:acedb
+SynMenu AB.Ada:ada
+SynMenu AB.AfLex:aflex
+SynMenu AB.ALSA\ config:alsaconf
+SynMenu AB.Altera\ AHDL:ahdl
+SynMenu AB.Amiga\ DOS:amiga
+SynMenu AB.AMPL:ampl
+SynMenu AB.Ant\ build\ file:ant
+SynMenu AB.ANTLR:antlr
+SynMenu AB.Apache\ config:apache
+SynMenu AB.Apache-style\ config:apachestyle
+SynMenu AB.Applix\ ELF:elf
+SynMenu AB.Arc\ Macro\ Language:aml
+SynMenu AB.Arch\ inventory:arch
+SynMenu AB.ART:art
+SynMenu AB.ASP\ with\ VBScript:aspvbs
+SynMenu AB.ASP\ with\ Perl:aspperl
+SynMenu AB.Assembly.680x0:asm68k
+SynMenu AB.Assembly.Flat:fasm
+SynMenu AB.Assembly.GNU:asm
+SynMenu AB.Assembly.GNU\ H-8300:asmh8300
+SynMenu AB.Assembly.Intel\ IA-64:ia64
+SynMenu AB.Assembly.Microsoft:masm
+SynMenu AB.Assembly.Netwide:nasm
+SynMenu AB.Assembly.PIC:pic
+SynMenu AB.Assembly.Turbo:tasm
+SynMenu AB.Assembly.VAX\ Macro\ Assembly:vmasm
+SynMenu AB.Assembly.Z-80:z8a
+SynMenu AB.Assembly.xa\ 6502\ cross\ assember:a65
+SynMenu AB.ASN\.1:asn
+SynMenu AB.Asterisk\ config:asterisk
+SynMenu AB.Asterisk\ voicemail\ config:asteriskvm
+SynMenu AB.Atlas:atlas
+SynMenu AB.AutoHotKey:autohotkey
+SynMenu AB.AutoIt:autoit
+SynMenu AB.Automake:automake
+SynMenu AB.Avenue:ave
+SynMenu AB.Awk:awk
+SynMenu AB.AYacc:ayacc
+
+SynMenu AB.B:b
+SynMenu AB.Baan:baan
+SynMenu AB.Basic.FreeBasic:freebasic
+SynMenu AB.Basic.IBasic:ibasic
+SynMenu AB.Basic.QBasic:basic
+SynMenu AB.Basic.Visual\ Basic:vb
+SynMenu AB.Bazaar\ commit\ file:bzr
+SynMenu AB.BC\ calculator:bc
+SynMenu AB.BDF\ font:bdf
+SynMenu AB.BibTeX.Bibliography\ database:bib
+SynMenu AB.BibTeX.Bibliography\ Style:bst
+SynMenu AB.BIND.BIND\ config:named
+SynMenu AB.BIND.BIND\ zone:bindzone
+SynMenu AB.Blank:blank
+
+SynMenu C.C:c
+SynMenu C.C++:cpp
+SynMenu C.C#:cs
+SynMenu C.Calendar:calendar
+SynMenu C.Cascading\ Style\ Sheets:css
+SynMenu C.CDL:cdl
+SynMenu C.Cdrdao\ TOC:cdrtoc
+SynMenu C.Century\ Term:cterm
+SynMenu C.CH\ script:ch
+SynMenu C.ChangeLog:changelog
+SynMenu C.Cheetah\ template:cheetah
+SynMenu C.CHILL:chill
+SynMenu C.ChordPro:chordpro
+SynMenu C.Clean:clean
+SynMenu C.Clever:cl
+SynMenu C.Clipper:clipper
+SynMenu C.Cmake:cmake
+SynMenu C.Cmusrc:cmusrc
+SynMenu C.Cobol:cobol
+SynMenu C.Cold\ Fusion:cf
+SynMenu C.Conary\ Recipe:conaryrecipe
+SynMenu C.Config.Cfg\ Config\ file:cfg
+SynMenu C.Config.Configure\.in:config
+SynMenu C.Config.Generic\ Config\ file:conf
+SynMenu C.CRM114:crm
+SynMenu C.Crontab:crontab
+SynMenu C.CSP:csp
+SynMenu C.Ctrl-H:ctrlh
+SynMenu C.CUPL.CUPL:cupl
+SynMenu C.CUPL.Simulation:cuplsim
+SynMenu C.CVS.commit\ file:cvs
+SynMenu C.CVS.cvsrc:cvsrc
+SynMenu C.Cyn++:cynpp
+SynMenu C.Cynlib:cynlib
+
+SynMenu DE.D:d
+SynMenu DE.Debian.Debian\ ChangeLog:debchangelog
+SynMenu DE.Debian.Debian\ Control:debcontrol
+SynMenu DE.Debian.Debian\ Sources\.list:debsources
+SynMenu DE.Desktop:desktop
+SynMenu DE.Dict\ config:dictconf
+SynMenu DE.Dictd\ config:dictdconf
+SynMenu DE.Diff:diff
+SynMenu DE.Digital\ Command\ Lang:dcl
+SynMenu DE.Dircolors:dircolors
+SynMenu DE.Django\ template:django
+SynMenu DE.DNS/BIND\ zone:bindzone
+SynMenu DE.DocBook.auto-detect:docbk
+SynMenu DE.DocBook.SGML:docbksgml
+SynMenu DE.DocBook.XML:docbkxml
+SynMenu DE.Dot:dot
+SynMenu DE.Doxygen.C\ with\ doxygen:c.doxygen
+SynMenu DE.Doxygen.C++\ with\ doxygen:cpp.doxygen
+SynMenu DE.Doxygen.IDL\ with\ doxygen:idl.doxygen
+SynMenu DE.Doxygen.Java\ with\ doxygen:java.doxygen
+SynMenu DE.Dracula:dracula
+SynMenu DE.DSSSL:dsl
+SynMenu DE.DTD:dtd
+SynMenu DE.DTML\ (Zope):dtml
+SynMenu DE.Dylan.Dylan:dylan
+SynMenu DE.Dylan.Dylan\ interface:dylanintr
+SynMenu DE.Dylan.Dylan\ lid:dylanlid
+
+SynMenu DE.EDIF:edif
+SynMenu DE.Eiffel:eiffel
+SynMenu DE.Elinks\ config:elinks
+SynMenu DE.Elm\ filter\ rules:elmfilt
+SynMenu DE.Embedix\ Component\ Description:ecd
+SynMenu DE.ERicsson\ LANGuage:erlang
+SynMenu DE.ESMTP\ rc:esmtprc
+SynMenu DE.ESQL-C:esqlc
+SynMenu DE.Essbase\ script:csc
+SynMenu DE.Esterel:esterel
+SynMenu DE.Eterm\ config:eterm
+SynMenu DE.Eviews:eviews
+SynMenu DE.Exim\ conf:exim
+SynMenu DE.Expect:expect
+SynMenu DE.Exports:exports
+
+SynMenu FG.Fetchmail:fetchmail
+SynMenu FG.FlexWiki:flexwiki
+SynMenu FG.Focus\ Executable:focexec
+SynMenu FG.Focus\ Master:master
+SynMenu FG.FORM:form
+SynMenu FG.Forth:forth
+SynMenu FG.Fortran:fortran
+SynMenu FG.FoxPro:foxpro
+SynMenu FG.FrameScript:framescript
+SynMenu FG.Fstab:fstab
+SynMenu FG.Fvwm.Fvwm\ configuration:fvwm1
+SynMenu FG.Fvwm.Fvwm2\ configuration:fvwm2
+SynMenu FG.Fvwm.Fvwm2\ configuration\ with\ M4:fvwm2m4
+
+SynMenu FG.GDB\ command\ file:gdb
+SynMenu FG.GDMO:gdmo
+SynMenu FG.Gedcom:gedcom
+SynMenu FG.Gkrellmrc:gkrellmrc
+SynMenu FG.GP:gp
+SynMenu FG.GPG:gpg
+SynMenu FG.Group\ file:group
+SynMenu FG.Grub:grub
+SynMenu FG.GNU\ Server\ Pages:gsp
+SynMenu FG.GNUplot:gnuplot
+SynMenu FG.GrADS\ scripts:grads
+SynMenu FG.Gretl:gretl
+SynMenu FG.Groff:groff
+SynMenu FG.Groovy:groovy
+SynMenu FG.GTKrc:gtkrc
+
+SynMenu HIJK.Hamster:hamster
+SynMenu HIJK.Haskell.Haskell:haskell
+SynMenu HIJK.Haskell.Haskell-c2hs:chaskell
+SynMenu HIJK.Haskell.Haskell-literate:lhaskell
+SynMenu HIJK.Hercules:hercules
+SynMenu HIJK.Hex\ dump.XXD:xxd
+SynMenu HIJK.Hex\ dump.Intel\ MCS51:hex
+SynMenu HIJK.HTML.HTML:html
+SynMenu HIJK.HTML.HTML\ with\ M4:htmlm4
+SynMenu HIJK.HTML.HTML\ with\ Ruby\ (eRuby):eruby
+SynMenu HIJK.HTML.Cheetah\ HTML\ template:htmlcheetah
+SynMenu HIJK.HTML.Django\ HTML\ template:htmldjango
+SynMenu HIJK.HTML.HTML/OS:htmlos
+SynMenu HIJK.HTML.XHTML:xhtml
+SynMenu HIJK.Hyper\ Builder:hb
+SynMenu HIJK.Icewm\ menu:icemenu
+SynMenu HIJK.Icon:icon
+SynMenu HIJK.IDL\Generic\ IDL:idl
+SynMenu HIJK.IDL\Microsoft\ IDL:msidl
+SynMenu HIJK.Indent\ profile:indent
+SynMenu HIJK.Inform:inform
+SynMenu HIJK.Informix\ 4GL:fgl
+SynMenu HIJK.Initng:initng
+SynMenu HIJK.Inittab:inittab
+SynMenu HIJK.Inno\ setup:iss
+SynMenu HIJK.InstallShield\ script:ishd
+SynMenu HIJK.Interactive\ Data\ Lang:idlang
+SynMenu HIJK.IPfilter:ipfilter
+SynMenu HIJK.JAL:jal
+SynMenu HIJK.JAM:jam
+SynMenu HIJK.Jargon:jargon
+SynMenu HIJK.Java.Java:java
+SynMenu HIJK.Java.JavaCC:javacc
+SynMenu HIJK.Java.Java\ Server\ Pages:jsp
+SynMenu HIJK.Java.Java\ Properties:jproperties
+SynMenu HIJK.JavaScript:javascript
+SynMenu HIJK.Jess:jess
+SynMenu HIJK.Jgraph:jgraph
+SynMenu HIJK.Kconfig:kconfig
+SynMenu HIJK.KDE\ script:kscript
+SynMenu HIJK.Kimwitu++:kwt
+SynMenu HIJK.KixTart:kix
+
+SynMenu L-Ma.Lace:lace
+SynMenu L-Ma.LamdaProlog:lprolog
+SynMenu L-Ma.Latte:latte
+SynMenu L-Ma.Ld\ script:ld
+SynMenu L-Ma.LDAP.LDIF:ldif
+SynMenu L-Ma.LDAP.Configuration:ldapconf
+SynMenu L-Ma.Lex:lex
+SynMenu L-Ma.LFTP\ config:lftp
+SynMenu L-Ma.Libao:libao
+SynMenu L-Ma.LifeLines\ script:lifelines
+SynMenu L-Ma.Lilo:lilo
+SynMenu L-Ma.Limits\ config:limits
+SynMenu L-Ma.Lisp:lisp
+SynMenu L-Ma.Lite:lite
+SynMenu L-Ma.LiteStep\ RC:litestep
+SynMenu L-Ma.Locale\ Input:fdcc
+SynMenu L-Ma.Login\.access:loginaccess
+SynMenu L-Ma.Login\.defs:logindefs
+SynMenu L-Ma.Logtalk:logtalk
+SynMenu L-Ma.LOTOS:lotos
+SynMenu L-Ma.LotusScript:lscript
+SynMenu L-Ma.Lout:lout
+SynMenu L-Ma.LPC:lpc
+SynMenu L-Ma.Lua:lua
+SynMenu L-Ma.Lynx\ Style:lss
+SynMenu L-Ma.Lynx\ config:lynx
+SynMenu L-Ma.M4:m4
+SynMenu L-Ma.MaGic\ Point:mgp
+SynMenu L-Ma.Mail:mail
+SynMenu L-Ma.Mail\ aliases:mailaliases
+SynMenu L-Ma.Mailcap:mailcap
+SynMenu L-Ma.Makefile:make
+SynMenu L-Ma.MakeIndex:ist
+SynMenu L-Ma.Man\ page:man
+SynMenu L-Ma.Man\.conf:manconf
+SynMenu L-Ma.Maple\ V:maple
+SynMenu L-Ma.Mason:mason
+SynMenu L-Ma.Mathematica:mma
+SynMenu L-Ma.Matlab:matlab
+SynMenu L-Ma.Maxima:maxima
+
+SynMenu Me-NO.MEL\ (for\ Maya):mel
+SynMenu Me-NO.Messages\ (/var/log):messages
+SynMenu Me-NO.Metafont:mf
+SynMenu Me-NO.MetaPost:mp
+SynMenu Me-NO.MGL:mgl
+SynMenu Me-NO.MMIX:mmix
+SynMenu Me-NO.Modconf:modconf
+SynMenu Me-NO.Model:model
+SynMenu Me-NO.Modsim\ III:modsim3
+SynMenu Me-NO.Modula\ 2:modula2
+SynMenu Me-NO.Modula\ 3:modula3
+SynMenu Me-NO.Monk:monk
+SynMenu Me-NO.Mplayer\ config:mplayerconf
+SynMenu Me-NO.MOO:moo
+SynMenu Me-NO.Mrxvtrc:mrxvtrc
+SynMenu Me-NO.MS-DOS/Windows.4DOS\ \.bat\ file:btm
+SynMenu Me-NO.MS-DOS/Windows.\.bat\/\.cmd\ file:dosbatch
+SynMenu Me-NO.MS-DOS/Windows.\.ini\ file:dosini
+SynMenu Me-NO.MS-DOS/Windows.Module\ Definition:def
+SynMenu Me-NO.MS-DOS/Windows.Registry:registry
+SynMenu Me-NO.MS-DOS/Windows.Resource\ file:rc
+SynMenu Me-NO.Msql:msql
+SynMenu Me-NO.MuPAD:mupad
+SynMenu Me-NO.MUSHcode:mush
+SynMenu Me-NO.Muttrc:muttrc
+SynMenu Me-NO.Nanorc:nanorc
+SynMenu Me-NO.Nastran\ input/DMAP:nastran
+SynMenu Me-NO.Natural:natural
+SynMenu Me-NO.Netrc:netrc
+SynMenu Me-NO.Novell\ NCF\ batch:ncf
+SynMenu Me-NO.Not\ Quite\ C\ (LEGO):nqc
+SynMenu Me-NO.Nroff:nroff
+SynMenu Me-NO.NSIS\ script:nsis
+SynMenu Me-NO.Objective\ C:objc
+SynMenu Me-NO.Objective\ C++:objcpp
+SynMenu Me-NO.OCAML:ocaml
+SynMenu Me-NO.Occam:occam
+SynMenu Me-NO.Omnimark:omnimark
+SynMenu Me-NO.OpenROAD:openroad
+SynMenu Me-NO.Open\ Psion\ Lang:opl
+SynMenu Me-NO.Oracle\ config:ora
+
+SynMenu PQ.Packet\ filter\ conf:pf
+SynMenu PQ.Palm\ resource\ compiler:pilrc
+SynMenu PQ.Pam\ config:pamconf
+SynMenu PQ.PApp:papp
+SynMenu PQ.Pascal:pascal
+SynMenu PQ.Password\ file:passwd
+SynMenu PQ.PCCTS:pccts
+SynMenu PQ.PPWizard:ppwiz
+SynMenu PQ.Perl.Perl:perl
+SynMenu PQ.Perl.Perl\ POD:pod
+SynMenu PQ.Perl.Perl\ XS:xs
+SynMenu PQ.PHP.PHP\ 3-4:php
+SynMenu PQ.PHP.Phtml\ (PHP\ 2):phtml
+SynMenu PQ.Pike:pike
+SynMenu PQ.Pine\ RC:pine
+SynMenu PQ.Pinfo\ RC:pinfo
+SynMenu PQ.PL/M:plm
+SynMenu PQ.PL/SQL:plsql
+SynMenu PQ.PLP:plp
+SynMenu PQ.PO\ (GNU\ gettext):po
+SynMenu PQ.Postfix\ main\ config:pfmain
+SynMenu PQ.PostScript.PostScript:postscr
+SynMenu PQ.PostScript.PostScript\ Printer\ Description:ppd
+SynMenu PQ.Povray.Povray\ scene\ descr:pov
+SynMenu PQ.Povray.Povray\ configuration:povini
+SynMenu PQ.Prescribe\ (Kyocera):prescribe
+SynMenu PQ.Printcap:pcap
+SynMenu PQ.Privoxy:privoxy
+SynMenu PQ.Procmail:procmail
+SynMenu PQ.Product\ Spec\ File:psf
+SynMenu PQ.Progress:progress
+SynMenu PQ.Prolog:prolog
+SynMenu PQ.Protocols:protocols
+SynMenu PQ.Purify\ log:purifylog
+SynMenu PQ.Pyrex:pyrex
+SynMenu PQ.Python:python
+SynMenu PQ.Quake:quake
+SynMenu PQ.Quickfix\ window:qf
+
+SynMenu R-Sg.R.R:r
+SynMenu R-Sg.R.R\ help:rhelp
+SynMenu R-Sg.R.R\ noweb:rnoweb
+SynMenu R-Sg.Racc\ input:racc
+SynMenu R-Sg.Radiance:radiance
+SynMenu R-Sg.Ratpoison:ratpoison
+SynMenu R-Sg.RCS.RCS\ log\ output:rcslog
+SynMenu R-Sg.RCS.RCS\ file:rcs
+SynMenu R-Sg.Readline\ config:readline
+SynMenu R-Sg.Rebol:rebol
+SynMenu R-Sg.Remind:remind
+SynMenu R-Sg.Relax\ NG\ compact:rnc
+SynMenu R-Sg.Renderman.Renderman\ Shader\ Lang:sl
+SynMenu R-Sg.Renderman.Renderman\ Interface\ Bytestream:rib
+SynMenu R-Sg.Resolv\.conf:resolv
+SynMenu R-Sg.Rexx:rexx
+SynMenu R-Sg.Robots\.txt:robots
+SynMenu R-Sg.RockLinux\ package\ desc\.:desc
+SynMenu R-Sg.Rpcgen:rpcgen
+SynMenu R-Sg.RPL/2:rpl
+SynMenu R-Sg.ReStructuredText:rst
+SynMenu R-Sg.RTF:rtf
+SynMenu R-Sg.Ruby:ruby
+SynMenu R-Sg.S-Lang:slang
+SynMenu R-Sg.Samba\ config:samba
+SynMenu R-Sg.SAS:sas
+SynMenu R-Sg.Sather:sather
+SynMenu R-Sg.Scheme:scheme
+SynMenu R-Sg.Scilab:scilab
+SynMenu R-Sg.Screen\ RC:screen
+SynMenu R-Sg.SDL:sdl
+SynMenu R-Sg.Sed:sed
+SynMenu R-Sg.Sendmail\.cf:sm
+SynMenu R-Sg.Send-pr:sendpr
+SynMenu R-Sg.Sensors\.conf:sensors
+SynMenu R-Sg.Service\ Location\ config:slpconf
+SynMenu R-Sg.Service\ Location\ registration:slpreg
+SynMenu R-Sg.Service\ Location\ SPI:slpspi
+SynMenu R-Sg.Services:services
+SynMenu R-Sg.Setserial\ config:setserial
+SynMenu R-Sg.SGML.SGML\ catalog:catalog
+SynMenu R-Sg.SGML.SGML\ DTD:sgml
+SynMenu R-Sg.SGML.SGML\ Declaration:sgmldecl
+SynMenu R-Sg.SGML.SGML-linuxdoc:sgmllnx
+
+SynMenu Sh-S.Shell\ script.sh\ and\ ksh:sh
+SynMenu Sh-S.Shell\ script.csh:csh
+SynMenu Sh-S.Shell\ script.tcsh:tcsh
+SynMenu Sh-S.Shell\ script.zsh:zsh
+SynMenu Sh-S.SiCAD:sicad
+SynMenu Sh-S.Sieve:sieve
+SynMenu Sh-S.Simula:simula
+SynMenu Sh-S.Sinda.Sinda\ compare:sindacmp
+SynMenu Sh-S.Sinda.Sinda\ input:sinda
+SynMenu Sh-S.Sinda.Sinda\ output:sindaout
+SynMenu Sh-S.SiSU:sisu
+SynMenu Sh-S.SKILL.SKILL:skill
+SynMenu Sh-S.SKILL.SKILL\ for\ Diva:diva
+SynMenu Sh-S.Slice:slice
+SynMenu Sh-S.SLRN.Slrn\ rc:slrnrc
+SynMenu Sh-S.SLRN.Slrn\ score:slrnsc
+SynMenu Sh-S.SmallTalk:st
+SynMenu Sh-S.Smarty\ Templates:smarty
+SynMenu Sh-S.SMIL:smil
+SynMenu Sh-S.SMITH:smith
+SynMenu Sh-S.SNMP\ MIB:mib
+SynMenu Sh-S.SNNS.SNNS\ network:snnsnet
+SynMenu Sh-S.SNNS.SNNS\ pattern:snnspat
+SynMenu Sh-S.SNNS.SNNS\ result:snnsres
+SynMenu Sh-S.Snobol4:snobol4
+SynMenu Sh-S.Snort\ Configuration:hog
+SynMenu Sh-S.SPEC\ (Linux\ RPM):spec
+SynMenu Sh-S.Specman:specman
+SynMenu Sh-S.Spice:spice
+SynMenu Sh-S.Spyce:spyce
+SynMenu Sh-S.Speedup:spup
+SynMenu Sh-S.Splint:splint
+SynMenu Sh-S.Squid\ config:squid
+SynMenu Sh-S.SQL.ESQL-C:esqlc
+SynMenu Sh-S.SQL.MySQL:mysql
+SynMenu Sh-S.SQL.PL/SQL:plsql
+SynMenu Sh-S.SQL.SQL\ Anywhere:sqlanywhere
+SynMenu Sh-S.SQL.SQL\ (automatic):sql
+SynMenu Sh-S.SQL.SQL\ (Oracle):sqloracle
+SynMenu Sh-S.SQL.SQL\ Forms:sqlforms
+SynMenu Sh-S.SQL.SQLJ:sqlj
+SynMenu Sh-S.SQL.SQL-Informix:sqlinformix
+SynMenu Sh-S.SQR:sqr
+SynMenu Sh-S.Ssh.ssh_config:sshconfig
+SynMenu Sh-S.Ssh.sshd_config:sshdconfig
+SynMenu Sh-S.Standard\ ML:sml
+SynMenu Sh-S.Stata.SMCL:smcl
+SynMenu Sh-S.Stata.Stata:stata
+SynMenu Sh-S.Stored\ Procedures:stp
+SynMenu Sh-S.Strace:strace
+SynMenu Sh-S.Streaming\ descriptor\ file:sd
+SynMenu Sh-S.Subversion\ commit:svn
+SynMenu Sh-S.Sudoers:sudoers
+SynMenu Sh-S.Sysctl\.conf:sysctl
+
+SynMenu TUV.TADS:tads
+SynMenu TUV.Tags:tags
+SynMenu TUV.TAK.TAK\ compare:takcmp
+SynMenu TUV.TAK.TAK\ input:tak
+SynMenu TUV.TAK.TAK\ output:takout
+SynMenu TUV.Tcl/Tk:tcl
+SynMenu TUV.TealInfo:tli
+SynMenu TUV.Telix\ Salt:tsalt
+SynMenu TUV.Termcap/Printcap:ptcap
+SynMenu TUV.Terminfo:terminfo
+SynMenu TUV.TeX.TeX/LaTeX:tex
+SynMenu TUV.TeX.plain\ TeX:plaintex
+SynMenu TUV.TeX.ConTeXt:context
+SynMenu TUV.TeX.TeX\ configuration:texmf
+SynMenu TUV.TeX.Texinfo:texinfo
+SynMenu TUV.TF\ mud\ client:tf
+SynMenu TUV.Tidy\ configuration:tidy
+SynMenu TUV.Tilde:tilde
+SynMenu TUV.TPP:tpp
+SynMenu TUV.Trasys\ input:trasys
+SynMenu TUV.Trustees:trustees
+SynMenu TUV.TSS.Command\ Line:tsscl
+SynMenu TUV.TSS.Geometry:tssgm
+SynMenu TUV.TSS.Optics:tssop
+SynMenu TUV.Udev\ config:udevconf
+SynMenu TUV.Udev\ permissions:udevperm
+SynMenu TUV.Udev\ rules:udevrules
+SynMenu TUV.UIT/UIL:uil
+SynMenu TUV.UnrealScript:uc
+SynMenu TUV.Updatedb\.conf:updatedb
+SynMenu TUV.Valgrind:valgrind
+SynMenu TUV.Vera:vera
+SynMenu TUV.Verilog-AMS\ HDL:verilogams
+SynMenu TUV.Verilog\ HDL:verilog
+SynMenu TUV.Vgrindefs:vgrindefs
+SynMenu TUV.VHDL:vhdl
+SynMenu TUV.Vim.Vim\ help\ file:help
+SynMenu TUV.Vim.Vim\ script:vim
+SynMenu TUV.Vim.Viminfo\ file:viminfo
+SynMenu TUV.Virata\ config:virata
+SynMenu TUV.Visual\ Basic:vb
+SynMenu TUV.VRML:vrml
+SynMenu TUV.VSE\ JCL:vsejcl
+
+SynMenu WXYZ.WEB.CWEB:cweb
+SynMenu WXYZ.WEB.WEB:web
+SynMenu WXYZ.WEB.WEB\ Changes:change
+SynMenu WXYZ.Webmacro:webmacro
+SynMenu WXYZ.Website\ MetaLanguage:wml
+SynMenu WXYZ.wDiff:wdiff
+SynMenu WXYZ.Wget\ config:wget
+SynMenu WXYZ.Whitespace\ (add):whitespace
+SynMenu WXYZ.WildPackets\ EtherPeek\ Decoder:dcd
+SynMenu WXYZ.WinBatch/Webbatch:winbatch
+SynMenu WXYZ.Windows\ Scripting\ Host:wsh
+SynMenu WXYZ.WSML:wsml
+SynMenu WXYZ.WvDial:wvdial
+SynMenu WXYZ.X\ Keyboard\ Extension:xkb
+SynMenu WXYZ.X\ Pixmap:xpm
+SynMenu WXYZ.X\ Pixmap\ (2):xpm2
+SynMenu WXYZ.X\ resources:xdefaults
+SynMenu WXYZ.Xinetd\.conf:xinetd
+SynMenu WXYZ.Xmodmap:xmodmap
+SynMenu WXYZ.Xmath:xmath
+SynMenu WXYZ.XML:xml
+SynMenu WXYZ.XML\ Schema\ (XSD):xsd
+SynMenu WXYZ.XQuery:xquery
+SynMenu WXYZ.Xslt:xslt
+SynMenu WXYZ.XFree86\ Config:xf86conf
+SynMenu WXYZ.YAML:yaml
+SynMenu WXYZ.Yacc:yacc
+
+call append(s:lnum, "")
+
+wq
--- /dev/null
+++ b/lib/vimfiles/menu.vim
@@ -1,0 +1,1101 @@
+" Vim support file to define the default menus
+" You can also use this as a start for your own set of menus.
+"
+" Maintainer:	Bram Moolenaar <Bram@vim.org>
+" Last Change:	2007 Jan 09
+
+" Note that ":an" (short for ":anoremenu") is often used to make a menu work
+" in all modes and avoid side effects from mappings defined by the user.
+
+" Make sure the '<' and 'C' flags are not included in 'cpoptions', otherwise
+" <CR> would not be recognized.  See ":help 'cpoptions'".
+let s:cpo_save = &cpo
+set cpo&vim
+
+" Avoid installing the menus twice
+if !exists("did_install_default_menus")
+let did_install_default_menus = 1
+
+
+if exists("v:lang") || &langmenu != ""
+  " Try to find a menu translation file for the current language.
+  if &langmenu != ""
+    if &langmenu =~ "none"
+      let s:lang = ""
+    else
+      let s:lang = &langmenu
+    endif
+  else
+    let s:lang = v:lang
+  endif
+  " A language name must be at least two characters, don't accept "C"
+  if strlen(s:lang) > 1
+    " When the language does not include the charset add 'encoding'
+    if s:lang =~ '^\a\a$\|^\a\a_\a\a$'
+      let s:lang = s:lang . '.' . &enc
+    endif
+
+    " We always use a lowercase name.
+    " Change "iso-8859" to "iso_8859" and "iso8859" to "iso_8859", some
+    " systems appear to use this.
+    " Change spaces to underscores.
+    let s:lang = substitute(tolower(s:lang), '\.iso-', ".iso_", "")
+    let s:lang = substitute(s:lang, '\.iso8859', ".iso_8859", "")
+    let s:lang = substitute(s:lang, " ", "_", "g")
+    " Remove "@euro", otherwise "LC_ALL=de_DE@euro gvim" will show English menus
+    let s:lang = substitute(s:lang, "@euro", "", "")
+    " Change "iso_8859-1" and "iso_8859-15" to "latin1", we always use the
+    " same menu file for them.
+    let s:lang = substitute(s:lang, 'iso_8859-15\=$', "latin1", "")
+    menutrans clear
+    exe "runtime! lang/menu_" . s:lang . ".vim"
+
+    if !exists("did_menu_trans")
+      " There is no exact match, try matching with a wildcard added
+      " (e.g. find menu_de_de.iso_8859-1.vim if s:lang == de_DE).
+      let s:lang = substitute(s:lang, '\.[^.]*', "", "")
+      exe "runtime! lang/menu_" . s:lang . "[^a-z]*vim"
+
+      if !exists("did_menu_trans") && strlen($LANG) > 1 && s:lang !~ '^en_us'
+	" On windows locale names are complicated, try using $LANG, it might
+	" have been set by set_init_1().  But don't do this for "en" or "en_us".
+	" But don't match "slovak" when $LANG is "sl".
+	exe "runtime! lang/menu_" . tolower($LANG) . "[^a-z]*vim"
+      endif
+    endif
+  endif
+endif
+
+
+" Help menu
+an 9999.10 &Help.&Overview<Tab><F1>	:help<CR>
+an 9999.20 &Help.&User\ Manual		:help usr_toc<CR>
+an 9999.30 &Help.&How-to\ links		:help how-to<CR>
+an <silent> 9999.40 &Help.&Find\.\.\.	:call <SID>Helpfind()<CR>
+an 9999.45 &Help.-sep1-			<Nop>
+an 9999.50 &Help.&Credits		:help credits<CR>
+an 9999.60 &Help.Co&pying		:help copying<CR>
+an 9999.70 &Help.&Sponsor/Register	:help sponsor<CR>
+an 9999.70 &Help.O&rphans		:help kcc<CR>
+an 9999.75 &Help.-sep2-			<Nop>
+an 9999.80 &Help.&Version		:version<CR>
+an 9999.90 &Help.&About			:intro<CR>
+
+fun! s:Helpfind()
+  if !exists("g:menutrans_help_dialog")
+    let g:menutrans_help_dialog = "Enter a command or word to find help on:\n\nPrepend i_ for Input mode commands (e.g.: i_CTRL-X)\nPrepend c_ for command-line editing commands (e.g.: c_<Del>)\nPrepend ' for an option name (e.g.: 'shiftwidth')"
+  endif
+  let h = inputdialog(g:menutrans_help_dialog)
+  if h != ""
+    let v:errmsg = ""
+    silent! exe "help " . h
+    if v:errmsg != ""
+      echo v:errmsg
+    endif
+  endif
+endfun
+
+" File menu
+an 10.310 &File.&Open\.\.\.<Tab>:e		:browse confirm e<CR>
+an 10.320 &File.Sp&lit-Open\.\.\.<Tab>:sp	:browse sp<CR>
+an 10.320 &File.Open\ Tab\.\.\.<Tab>:tabnew	:browse tabnew<CR>
+an 10.325 &File.&New<Tab>:enew			:confirm enew<CR>
+an <silent> 10.330 &File.&Close<Tab>:close
+	\ :if winheight(2) < 0 <Bar>
+	\   confirm enew <Bar>
+	\ else <Bar>
+	\   confirm close <Bar>
+	\ endif<CR>
+an 10.335 &File.-SEP1-				<Nop>
+an <silent> 10.340 &File.&Save<Tab>:w		:if expand("%") == ""<Bar>browse confirm w<Bar>else<Bar>confirm w<Bar>endif<CR>
+an 10.350 &File.Save\ &As\.\.\.<Tab>:sav	:browse confirm saveas<CR>
+
+if has("diff")
+  an 10.400 &File.-SEP2-			<Nop>
+  an 10.410 &File.Split\ &Diff\ with\.\.\.	:browse vert diffsplit<CR>
+  an 10.420 &File.Split\ Patched\ &By\.\.\.	:browse vert diffpatch<CR>
+endif
+
+if has("printer")
+  an 10.500 &File.-SEP3-			<Nop>
+  an 10.510 &File.&Print			:hardcopy<CR>
+  vunmenu   &File.&Print
+  vnoremenu &File.&Print			:hardcopy<CR>
+elseif has("unix")
+  an 10.500 &File.-SEP3-			<Nop>
+  an 10.510 &File.&Print			:w !lpr<CR>
+  vunmenu   &File.&Print
+  vnoremenu &File.&Print			:w !lpr<CR>
+endif
+an 10.600 &File.-SEP4-				<Nop>
+an 10.610 &File.Sa&ve-Exit<Tab>:wqa		:confirm wqa<CR>
+an 10.620 &File.E&xit<Tab>:qa			:confirm qa<CR>
+
+func! <SID>SelectAll()
+  exe "norm gg" . (&slm == "" ? "VG" : "gH\<C-O>G")
+endfunc
+
+
+" Edit menu
+an 20.310 &Edit.&Undo<Tab>u			u
+an 20.320 &Edit.&Redo<Tab>^R			<C-R>
+an 20.330 &Edit.Rep&eat<Tab>\.			.
+
+an 20.335 &Edit.-SEP1-				<Nop>
+vnoremenu 20.340 &Edit.Cu&t<Tab>"+x		"+x
+vnoremenu 20.350 &Edit.&Copy<Tab>"+y		"+y
+cnoremenu 20.350 &Edit.&Copy<Tab>"+y		<C-Y>
+nnoremenu 20.360 &Edit.&Paste<Tab>"+gP		"+gP
+cnoremenu	 &Edit.&Paste<Tab>"+gP		<C-R>+
+exe 'vnoremenu <script> &Edit.&Paste<Tab>"+gP	' . paste#paste_cmd['v']
+exe 'inoremenu <script> &Edit.&Paste<Tab>"+gP	' . paste#paste_cmd['i']
+nnoremenu 20.370 &Edit.Put\ &Before<Tab>[p	[p
+inoremenu	 &Edit.Put\ &Before<Tab>[p	<C-O>[p
+nnoremenu 20.380 &Edit.Put\ &After<Tab>]p	]p
+inoremenu	 &Edit.Put\ &After<Tab>]p	<C-O>]p
+if has("win32") || has("win16")
+  vnoremenu 20.390 &Edit.&Delete<Tab>x		x
+endif
+noremenu  <script> <silent> 20.400 &Edit.&Select\ All<Tab>ggVG	:<C-U>call <SID>SelectAll()<CR>
+inoremenu <script> <silent> 20.400 &Edit.&Select\ All<Tab>ggVG	<C-O>:call <SID>SelectAll()<CR>
+cnoremenu <script> <silent> 20.400 &Edit.&Select\ All<Tab>ggVG	<C-U>call <SID>SelectAll()<CR>
+
+an 20.405	 &Edit.-SEP2-				<Nop>
+if has("win32")  || has("win16") || has("gui_gtk") || has("gui_kde") || has("gui_motif")
+  an 20.410	 &Edit.&Find\.\.\.			:promptfind<CR>
+  vunmenu	 &Edit.&Find\.\.\.
+  vnoremenu <silent>	 &Edit.&Find\.\.\.		y:promptfind <C-R>=<SID>FixFText()<CR><CR>
+  an 20.420	 &Edit.Find\ and\ Rep&lace\.\.\.	:promptrepl<CR>
+  vunmenu	 &Edit.Find\ and\ Rep&lace\.\.\.
+  vnoremenu <silent>	 &Edit.Find\ and\ Rep&lace\.\.\. y:promptrepl <C-R>=<SID>FixFText()<CR><CR>
+else
+  an 20.410	 &Edit.&Find<Tab>/			/
+  an 20.420	 &Edit.Find\ and\ Rep&lace<Tab>:%s	:%s/
+  vunmenu	 &Edit.Find\ and\ Rep&lace<Tab>:%s
+  vnoremenu	 &Edit.Find\ and\ Rep&lace<Tab>:s	:s/
+endif
+
+an 20.425	 &Edit.-SEP3-				<Nop>
+an 20.430	 &Edit.Settings\ &Window		:options<CR>
+an 20.435	 &Edit.Startup\ &Settings		:call <SID>EditVimrc()<CR>
+
+fun! s:EditVimrc()
+  if $MYVIMRC != ''
+    let fname = "$MYVIMRC"
+  elseif has("win32") || has("dos32") || has("dos16") || has("os2")
+    if $HOME != ''
+      let fname = "$HOME/_vimrc"
+    else
+      let fname = "$VIM/_vimrc"
+    endif
+  elseif has("amiga")
+    let fname = "s:.vimrc"
+  else
+    let fname = "$HOME/.vimrc"
+  endif
+  if &mod
+    exe "split " . fname
+  else
+    exe "edit " . fname
+  endif
+endfun
+
+fun! s:FixFText()
+  " Fix text in nameless register to be used with :promptfind.
+  return substitute(@", "[\r\n]", '\\n', 'g')
+endfun
+
+" Edit/Global Settings
+an 20.440.100 &Edit.&Global\ Settings.Toggle\ Pattern\ &Highlight<Tab>:set\ hls!	:set hls! hls?<CR>
+an 20.440.110 &Edit.&Global\ Settings.Toggle\ &Ignore-case<Tab>:set\ ic!	:set ic! ic?<CR>
+an 20.440.110 &Edit.&Global\ Settings.Toggle\ &Showmatch<Tab>:set\ sm!	:set sm! sm?<CR>
+
+an 20.440.120 &Edit.&Global\ Settings.&Context\ lines.\ 1\  :set so=1<CR>
+an 20.440.120 &Edit.&Global\ Settings.&Context\ lines.\ 2\  :set so=2<CR>
+an 20.440.120 &Edit.&Global\ Settings.&Context\ lines.\ 3\  :set so=3<CR>
+an 20.440.120 &Edit.&Global\ Settings.&Context\ lines.\ 4\  :set so=4<CR>
+an 20.440.120 &Edit.&Global\ Settings.&Context\ lines.\ 5\  :set so=5<CR>
+an 20.440.120 &Edit.&Global\ Settings.&Context\ lines.\ 7\  :set so=7<CR>
+an 20.440.120 &Edit.&Global\ Settings.&Context\ lines.\ 10\  :set so=10<CR>
+an 20.440.120 &Edit.&Global\ Settings.&Context\ lines.\ 100\  :set so=100<CR>
+
+an 20.440.130.40 &Edit.&Global\ Settings.&Virtual\ Edit.Never :set ve=<CR>
+an 20.440.130.50 &Edit.&Global\ Settings.&Virtual\ Edit.Block\ Selection :set ve=block<CR>
+an 20.440.130.60 &Edit.&Global\ Settings.&Virtual\ Edit.Insert\ mode :set ve=insert<CR>
+an 20.440.130.70 &Edit.&Global\ Settings.&Virtual\ Edit.Block\ and\ Insert :set ve=block,insert<CR>
+an 20.440.130.80 &Edit.&Global\ Settings.&Virtual\ Edit.Always :set ve=all<CR>
+an 20.440.140 &Edit.&Global\ Settings.Toggle\ Insert\ &Mode<Tab>:set\ im!	:set im!<CR>
+an 20.440.145 &Edit.&Global\ Settings.Toggle\ Vi\ C&ompatible<Tab>:set\ cp!	:set cp!<CR>
+an <silent> 20.440.150 &Edit.&Global\ Settings.Search\ &Path\.\.\.  :call <SID>SearchP()<CR>
+an <silent> 20.440.160 &Edit.&Global\ Settings.Ta&g\ Files\.\.\.  :call <SID>TagFiles()<CR>
+"
+" GUI options
+an 20.440.300 &Edit.&Global\ Settings.-SEP1-				<Nop>
+an <silent> 20.440.310 &Edit.&Global\ Settings.Toggle\ &Toolbar		:call <SID>ToggleGuiOption("T")<CR>
+an <silent> 20.440.320 &Edit.&Global\ Settings.Toggle\ &Bottom\ Scrollbar :call <SID>ToggleGuiOption("b")<CR>
+an <silent> 20.440.330 &Edit.&Global\ Settings.Toggle\ &Left\ Scrollbar	:call <SID>ToggleGuiOption("l")<CR>
+an <silent> 20.440.340 &Edit.&Global\ Settings.Toggle\ &Right\ Scrollbar :call <SID>ToggleGuiOption("r")<CR>
+
+fun! s:SearchP()
+  if !exists("g:menutrans_path_dialog")
+    let g:menutrans_path_dialog = "Enter search path for files.\nSeparate directory names with a comma."
+  endif
+  let n = inputdialog(g:menutrans_path_dialog, substitute(&path, '\\ ', ' ', 'g'))
+  if n != ""
+    let &path = substitute(n, ' ', '\\ ', 'g')
+  endif
+endfun
+
+fun! s:TagFiles()
+  if !exists("g:menutrans_tags_dialog")
+    let g:menutrans_tags_dialog = "Enter names of tag files.\nSeparate the names with a comma."
+  endif
+  let n = inputdialog(g:menutrans_tags_dialog, substitute(&tags, '\\ ', ' ', 'g'))
+  if n != ""
+    let &tags = substitute(n, ' ', '\\ ', 'g')
+  endif
+endfun
+
+fun! s:ToggleGuiOption(option)
+    " If a:option is already set in guioptions, then we want to remove it
+    if match(&guioptions, "\\C" . a:option) > -1
+	exec "set go-=" . a:option
+    else
+	exec "set go+=" . a:option
+    endif
+endfun
+
+" Edit/File Settings
+
+" Boolean options
+an 20.440.100 &Edit.F&ile\ Settings.Toggle\ Line\ &Numbering<Tab>:set\ nu!	:set nu! nu?<CR>
+an 20.440.110 &Edit.F&ile\ Settings.Toggle\ &List\ Mode<Tab>:set\ list!	:set list! list?<CR>
+an 20.440.120 &Edit.F&ile\ Settings.Toggle\ Line\ &Wrap<Tab>:set\ wrap!	:set wrap! wrap?<CR>
+an 20.440.130 &Edit.F&ile\ Settings.Toggle\ W&rap\ at\ word<Tab>:set\ lbr!	:set lbr! lbr?<CR>
+an 20.440.160 &Edit.F&ile\ Settings.Toggle\ &expand-tab<Tab>:set\ et!	:set et! et?<CR>
+an 20.440.170 &Edit.F&ile\ Settings.Toggle\ &auto-indent<Tab>:set\ ai!	:set ai! ai?<CR>
+an 20.440.180 &Edit.F&ile\ Settings.Toggle\ &C-indenting<Tab>:set\ cin!	:set cin! cin?<CR>
+
+" other options
+an 20.440.600 &Edit.F&ile\ Settings.-SEP2-		<Nop>
+an 20.440.610.20 &Edit.F&ile\ Settings.&Shiftwidth.2	:set sw=2 sw?<CR>
+an 20.440.610.30 &Edit.F&ile\ Settings.&Shiftwidth.3	:set sw=3 sw?<CR>
+an 20.440.610.40 &Edit.F&ile\ Settings.&Shiftwidth.4	:set sw=4 sw?<CR>
+an 20.440.610.50 &Edit.F&ile\ Settings.&Shiftwidth.5	:set sw=5 sw?<CR>
+an 20.440.610.60 &Edit.F&ile\ Settings.&Shiftwidth.6	:set sw=6 sw?<CR>
+an 20.440.610.80 &Edit.F&ile\ Settings.&Shiftwidth.8	:set sw=8 sw?<CR>
+
+an 20.440.620.20 &Edit.F&ile\ Settings.Soft\ &Tabstop.2	:set sts=2 sts?<CR>
+an 20.440.620.30 &Edit.F&ile\ Settings.Soft\ &Tabstop.3	:set sts=3 sts?<CR>
+an 20.440.620.40 &Edit.F&ile\ Settings.Soft\ &Tabstop.4	:set sts=4 sts?<CR>
+an 20.440.620.50 &Edit.F&ile\ Settings.Soft\ &Tabstop.5	:set sts=5 sts?<CR>
+an 20.440.620.60 &Edit.F&ile\ Settings.Soft\ &Tabstop.6	:set sts=6 sts?<CR>
+an 20.440.620.80 &Edit.F&ile\ Settings.Soft\ &Tabstop.8	:set sts=8 sts?<CR>
+
+an <silent> 20.440.630 &Edit.F&ile\ Settings.Te&xt\ Width\.\.\.  :call <SID>TextWidth()<CR>
+an <silent> 20.440.640 &Edit.F&ile\ Settings.&File\ Format\.\.\.  :call <SID>FileFormat()<CR>
+fun! s:TextWidth()
+  if !exists("g:menutrans_textwidth_dialog")
+    let g:menutrans_textwidth_dialog = "Enter new text width (0 to disable formatting): "
+  endif
+  let n = inputdialog(g:menutrans_textwidth_dialog, &tw)
+  if n != ""
+    " remove leading zeros to avoid it being used as an octal number
+    let &tw = substitute(n, "^0*", "", "")
+  endif
+endfun
+
+fun! s:FileFormat()
+  if !exists("g:menutrans_fileformat_dialog")
+    let g:menutrans_fileformat_dialog = "Select format for writing the file"
+  endif
+  if !exists("g:menutrans_fileformat_choices")
+    let g:menutrans_fileformat_choices = "&Unix\n&Dos\n&Mac\n&Cancel"
+  endif
+  if &ff == "dos"
+    let def = 2
+  elseif &ff == "mac"
+    let def = 3
+  else
+    let def = 1
+  endif
+  let n = confirm(g:menutrans_fileformat_dialog, g:menutrans_fileformat_choices, def, "Question")
+  if n == 1
+    set ff=unix
+  elseif n == 2
+    set ff=dos
+  elseif n == 3
+    set ff=mac
+  endif
+endfun
+
+" Setup the Edit.Color Scheme submenu
+let s:n = globpath(&runtimepath, "colors/*.vim")
+let s:idx = 100
+while strlen(s:n) > 0
+  let s:i = stridx(s:n, "\n")
+  if s:i < 0
+    let s:name = s:n
+    let s:n = ""
+  else
+    let s:name = strpart(s:n, 0, s:i)
+    let s:n = strpart(s:n, s:i + 1, 19999)
+  endif
+  " Ignore case for VMS and windows
+  let s:name = substitute(s:name, '\c.*[/\\:\]]\([^/\\:]*\)\.vim', '\1', '')
+  exe "an 20.450." . s:idx . ' &Edit.C&olor\ Scheme.' . s:name . " :colors " . s:name . "<CR>"
+  unlet s:name
+  unlet s:i
+  let s:idx = s:idx + 10
+endwhile
+unlet s:n
+unlet s:idx
+
+" Setup the Edit.Keymap submenu
+if has("keymap")
+  let s:n = globpath(&runtimepath, "keymap/*.vim")
+  if s:n != ""
+    let s:idx = 100
+    an 20.460.90 &Edit.&Keymap.None :set keymap=<CR>
+    while strlen(s:n) > 0
+      let s:i = stridx(s:n, "\n")
+      if s:i < 0
+	let s:name = s:n
+	let s:n = ""
+      else
+	let s:name = strpart(s:n, 0, s:i)
+	let s:n = strpart(s:n, s:i + 1, 19999)
+      endif
+      " Ignore case for VMS and windows
+      let s:name = substitute(s:name, '\c.*[/\\:\]]\([^/\\:_]*\)\(_[0-9a-zA-Z-]*\)\=\.vim', '\1', '')
+      exe "an 20.460." . s:idx . ' &Edit.&Keymap.' . s:name . " :set keymap=" . s:name . "<CR>"
+      unlet s:name
+      unlet s:i
+      let s:idx = s:idx + 10
+    endwhile
+    unlet s:idx
+  endif
+  unlet s:n
+endif
+if has("win32") || has("win16") || has("gui_motif") || has("gui_gtk") || has("gui_kde") || has("gui_photon") || has("gui_mac")
+  an 20.470 &Edit.Select\ Fo&nt\.\.\.	:set guifont=*<CR>
+endif
+
+" Programming menu
+if !exists("g:ctags_command")
+  if has("vms")
+    let g:ctags_command = "mc vim:ctags *.*"
+  else
+    let g:ctags_command = "ctags -R ."
+  endif
+endif
+
+an 40.300 &Tools.&Jump\ to\ this\ tag<Tab>g^]	g<C-]>
+vunmenu &Tools.&Jump\ to\ this\ tag<Tab>g^]
+vnoremenu &Tools.&Jump\ to\ this\ tag<Tab>g^]	g<C-]>
+an 40.310 &Tools.Jump\ &back<Tab>^T		<C-T>
+an 40.320 &Tools.Build\ &Tags\ File		:exe "!" . g:ctags_command<CR>
+
+if has("folding") || has("spell")
+  an 40.330 &Tools.-SEP1-						<Nop>
+endif
+
+" Tools.Spelling Menu
+if has("spell")
+  an 40.335.110 &Tools.&Spelling.&Spell\ Check\ On		:set spell<CR>
+  an 40.335.120 &Tools.&Spelling.Spell\ Check\ &Off		:set nospell<CR>
+  an 40.335.130 &Tools.&Spelling.To\ &Next\ error<Tab>]s	]s
+  an 40.335.130 &Tools.&Spelling.To\ &Previous\ error<Tab>[s	[s
+  an 40.335.140 &Tools.&Spelling.Suggest\ &Corrections<Tab>z=	z=
+  an 40.335.150 &Tools.&Spelling.&Repeat\ correction<Tab>:spellrepall	:spellrepall<CR>
+  an 40.335.200 &Tools.&Spelling.-SEP1-				<Nop>
+  an 40.335.210 &Tools.&Spelling.Set\ language\ to\ "en"	:set spl=en spell<CR>
+  an 40.335.220 &Tools.&Spelling.Set\ language\ to\ "en_au"	:set spl=en_au spell<CR>
+  an 40.335.230 &Tools.&Spelling.Set\ language\ to\ "en_ca"	:set spl=en_ca spell<CR>
+  an 40.335.240 &Tools.&Spelling.Set\ language\ to\ "en_gb"	:set spl=en_gb spell<CR>
+  an 40.335.250 &Tools.&Spelling.Set\ language\ to\ "en_nz"	:set spl=en_nz spell<CR>
+  an 40.335.260 &Tools.&Spelling.Set\ language\ to\ "en_us"	:set spl=en_us spell<CR>
+  an <silent> 40.335.270 &Tools.&Spelling.&Find\ More\ Languages	:call <SID>SpellLang()<CR>
+
+  let s:undo_spellang = ['aun &Tools.&Spelling.&Find\ More\ Languages']
+  func! s:SpellLang()
+    for cmd in s:undo_spellang
+      exe "silent! " . cmd
+    endfor
+    let s:undo_spellang = []
+
+    if &enc == "iso-8859-15"
+      let enc = "latin1"
+    else
+      let enc = &enc
+    endif
+
+    let found = 0
+    let s = globpath(&rtp, "spell/*." . enc . ".spl")
+    if s != ""
+      let n = 300
+      for f in split(s, "\n")
+	let nm = substitute(f, '.*spell[/\\]\(..\)\.[^/\\]*\.spl', '\1', "")
+	if nm != "en" && nm !~ '/'
+	  let found += 1
+	  let menuname = '&Tools.&Spelling.Set\ language\ to\ "' . nm . '"'
+	  exe 'an 40.335.' . n . ' ' . menuname . ' :set spl=' . nm . ' spell<CR>'
+	  let s:undo_spellang += ['aun ' . menuname]
+	endif
+	let n += 10
+      endfor
+    endif
+    if found == 0
+      echomsg "Could not find other spell files"
+    elseif found == 1
+      echomsg "Found spell file " . nm
+    else
+      echomsg "Found " . found . " more spell files"
+    endif
+    " Need to redo this when 'encoding' is changed.
+    augroup spellmenu
+    au! EncodingChanged * call <SID>SpellLang()
+    augroup END
+  endfun
+
+endif
+
+" Tools.Fold Menu
+if has("folding")
+  " open close folds
+  an 40.340.110 &Tools.&Folding.&Enable/Disable\ folds<Tab>zi		zi
+  an 40.340.120 &Tools.&Folding.&View\ Cursor\ Line<Tab>zv		zv
+  an 40.340.120 &Tools.&Folding.Vie&w\ Cursor\ Line\ only<Tab>zMzx	zMzx
+  an 40.340.130 &Tools.&Folding.C&lose\ more\ folds<Tab>zm		zm
+  an 40.340.140 &Tools.&Folding.&Close\ all\ folds<Tab>zM		zM
+  an 40.340.150 &Tools.&Folding.O&pen\ more\ folds<Tab>zr		zr
+  an 40.340.160 &Tools.&Folding.&Open\ all\ folds<Tab>zR		zR
+  " fold method
+  an 40.340.200 &Tools.&Folding.-SEP1-			<Nop>
+  an 40.340.210 &Tools.&Folding.Fold\ Met&hod.M&anual	:set fdm=manual<CR>
+  an 40.340.210 &Tools.&Folding.Fold\ Met&hod.I&ndent	:set fdm=indent<CR>
+  an 40.340.210 &Tools.&Folding.Fold\ Met&hod.E&xpression :set fdm=expr<CR>
+  an 40.340.210 &Tools.&Folding.Fold\ Met&hod.S&yntax	:set fdm=syntax<CR>
+  an 40.340.210 &Tools.&Folding.Fold\ Met&hod.&Diff	:set fdm=diff<CR>
+  an 40.340.210 &Tools.&Folding.Fold\ Met&hod.Ma&rker	:set fdm=marker<CR>
+  " create and delete folds
+  vnoremenu 40.340.220 &Tools.&Folding.Create\ &Fold<Tab>zf	zf
+  an 40.340.230 &Tools.&Folding.&Delete\ Fold<Tab>zd		zd
+  an 40.340.240 &Tools.&Folding.Delete\ &All\ Folds<Tab>zD	zD
+  " moving around in folds
+  an 40.340.300 &Tools.&Folding.-SEP2-				<Nop>
+  an 40.340.310.10 &Tools.&Folding.Fold\ col&umn\ width.\ &0\ 	:set fdc=0<CR>
+  an 40.340.310.20 &Tools.&Folding.Fold\ col&umn\ width.\ &2\ 	:set fdc=2<CR>
+  an 40.340.310.30 &Tools.&Folding.Fold\ col&umn\ width.\ &3\ 	:set fdc=3<CR>
+  an 40.340.310.40 &Tools.&Folding.Fold\ col&umn\ width.\ &4\ 	:set fdc=4<CR>
+  an 40.340.310.50 &Tools.&Folding.Fold\ col&umn\ width.\ &5\ 	:set fdc=5<CR>
+  an 40.340.310.60 &Tools.&Folding.Fold\ col&umn\ width.\ &6\ 	:set fdc=6<CR>
+  an 40.340.310.70 &Tools.&Folding.Fold\ col&umn\ width.\ &7\ 	:set fdc=7<CR>
+  an 40.340.310.80 &Tools.&Folding.Fold\ col&umn\ width.\ &8\ 	:set fdc=8<CR>
+endif  " has folding
+
+if has("diff")
+  an 40.350.100 &Tools.&Diff.&Update		:diffupdate<CR>
+  an 40.350.110 &Tools.&Diff.&Get\ Block	:diffget<CR>
+  vunmenu &Tools.&Diff.&Get\ Block
+  vnoremenu &Tools.&Diff.&Get\ Block		:diffget<CR>
+  an 40.350.120 &Tools.&Diff.&Put\ Block	:diffput<CR>
+  vunmenu &Tools.&Diff.&Put\ Block
+  vnoremenu &Tools.&Diff.&Put\ Block		:diffput<CR>
+endif
+
+an 40.358 &Tools.-SEP2-					<Nop>
+an 40.360 &Tools.&Make<Tab>:make			:make<CR>
+an 40.370 &Tools.&List\ Errors<Tab>:cl			:cl<CR>
+an 40.380 &Tools.L&ist\ Messages<Tab>:cl!		:cl!<CR>
+an 40.390 &Tools.&Next\ Error<Tab>:cn			:cn<CR>
+an 40.400 &Tools.&Previous\ Error<Tab>:cp		:cp<CR>
+an 40.410 &Tools.&Older\ List<Tab>:cold			:colder<CR>
+an 40.420 &Tools.N&ewer\ List<Tab>:cnew			:cnewer<CR>
+an 40.430.50 &Tools.Error\ &Window.&Update<Tab>:cwin	:cwin<CR>
+an 40.430.60 &Tools.Error\ &Window.&Open<Tab>:copen	:copen<CR>
+an 40.430.70 &Tools.Error\ &Window.&Close<Tab>:cclose	:cclose<CR>
+
+an 40.520 &Tools.-SEP3-					<Nop>
+an <silent> 40.530 &Tools.&Convert\ to\ HEX<Tab>:%!xxd
+	\ :call <SID>XxdConv()<CR>
+an <silent> 40.540 &Tools.Conve&rt\ back<Tab>:%!xxd\ -r
+	\ :call <SID>XxdBack()<CR>
+
+" Use a function to do the conversion, so that it also works with 'insertmode'
+" set.
+func! s:XxdConv()
+  let mod = &mod
+  if has("vms")
+    %!mc vim:xxd
+  else
+    call s:XxdFind()
+    exe '%!"' . g:xxdprogram . '"'
+  endif
+  if getline(1) =~ "^0000000:"		" only if it worked
+    set ft=xxd
+  endif
+  let &mod = mod
+endfun
+
+func! s:XxdBack()
+  let mod = &mod
+  if has("vms")
+    %!mc vim:xxd -r
+  else
+    call s:XxdFind()
+    exe '%!"' . g:xxdprogram . '" -r'
+  endif
+  set ft=
+  doautocmd filetypedetect BufReadPost
+  let &mod = mod
+endfun
+
+func! s:XxdFind()
+  if !exists("g:xxdprogram")
+    " On the PC xxd may not be in the path but in the install directory
+    if (has("win32") || has("dos32")) && !executable("xxd")
+      let g:xxdprogram = $VIMRUNTIME . (&shellslash ? '/' : '\') . "xxd.exe"
+    else
+      let g:xxdprogram = "xxd"
+    endif
+  endif
+endfun
+
+" Setup the Tools.Compiler submenu
+let s:n = globpath(&runtimepath, "compiler/*.vim")
+let s:idx = 100
+while strlen(s:n) > 0
+  let s:i = stridx(s:n, "\n")
+  if s:i < 0
+    let s:name = s:n
+    let s:n = ""
+  else
+    let s:name = strpart(s:n, 0, s:i)
+    let s:n = strpart(s:n, s:i + 1, 19999)
+  endif
+  " Ignore case for VMS and windows
+  let s:name = substitute(s:name, '\c.*[/\\:\]]\([^/\\:]*\)\.vim', '\1', '')
+  exe "an 30.440." . s:idx . ' &Tools.Se&T\ Compiler.' . s:name . " :compiler " . s:name . "<CR>"
+  unlet s:name
+  unlet s:i
+  let s:idx = s:idx + 10
+endwhile
+unlet s:n
+unlet s:idx
+
+if !exists("no_buffers_menu")
+
+" Buffer list menu -- Setup functions & actions
+
+" wait with building the menu until after loading 'session' files. Makes
+" startup faster.
+let s:bmenu_wait = 1
+
+if !exists("bmenu_priority")
+  let bmenu_priority = 60
+endif
+
+func! s:BMAdd()
+  if s:bmenu_wait == 0
+    " when adding too many buffers, redraw in short format
+    if s:bmenu_count == &menuitems && s:bmenu_short == 0
+      call s:BMShow()
+    else
+      call <SID>BMFilename(expand("<afile>"), expand("<abuf>"))
+      let s:bmenu_count = s:bmenu_count + 1
+    endif
+  endif
+endfunc
+
+func! s:BMRemove()
+  if s:bmenu_wait == 0
+    let name = expand("<afile>")
+    if isdirectory(name)
+      return
+    endif
+    let munge = <SID>BMMunge(name, expand("<abuf>"))
+
+    if s:bmenu_short == 0
+      exe 'silent! aun &Buffers.' . munge
+    else
+      exe 'silent! aun &Buffers.' . <SID>BMHash2(munge) . munge
+    endif
+    let s:bmenu_count = s:bmenu_count - 1
+  endif
+endfunc
+
+" Create the buffer menu (delete an existing one first).
+func! s:BMShow(...)
+  let s:bmenu_wait = 1
+  let s:bmenu_short = 1
+  let s:bmenu_count = 0
+  "
+  " get new priority, if exists
+  if a:0 == 1
+    let g:bmenu_priority = a:1
+  endif
+
+  " remove old menu, if exists; keep one entry to avoid a torn off menu to
+  " disappear.
+  silent! unmenu &Buffers
+  exe 'noremenu ' . g:bmenu_priority . ".1 &Buffers.Dummy l"
+  silent! unmenu! &Buffers
+
+  " create new menu; set 'cpo' to include the <CR>
+  let cpo_save = &cpo
+  set cpo&vim
+  exe 'an <silent> ' . g:bmenu_priority . ".2 &Buffers.&Refresh\\ menu :call <SID>BMShow()<CR>"
+  exe 'an ' . g:bmenu_priority . ".4 &Buffers.&Delete :confirm bd<CR>"
+  exe 'an ' . g:bmenu_priority . ".6 &Buffers.&Alternate :confirm b #<CR>"
+  exe 'an ' . g:bmenu_priority . ".7 &Buffers.&Next :confirm bnext<CR>"
+  exe 'an ' . g:bmenu_priority . ".8 &Buffers.&Previous :confirm bprev<CR>"
+  exe 'an ' . g:bmenu_priority . ".9 &Buffers.-SEP- :"
+  let &cpo = cpo_save
+  unmenu &Buffers.Dummy
+
+  " figure out how many buffers there are
+  let buf = 1
+  while buf <= bufnr('$')
+    if bufexists(buf) && !isdirectory(bufname(buf)) && buflisted(buf)
+					    \ && !getbufvar(buf, "&bufsecret")
+      let s:bmenu_count = s:bmenu_count + 1
+    endif
+    let buf = buf + 1
+  endwhile
+  if s:bmenu_count <= &menuitems
+    let s:bmenu_short = 0
+  endif
+
+  " iterate through buffer list, adding each buffer to the menu:
+  let buf = 1
+  while buf <= bufnr('$')
+    if bufexists(buf) && !isdirectory(bufname(buf)) && buflisted(buf)
+					    \ && !getbufvar(buf, "&bufsecret")
+      call <SID>BMFilename(bufname(buf), buf)
+    endif
+    let buf = buf + 1
+  endwhile
+  let s:bmenu_wait = 0
+  aug buffer_list
+  au!
+  au BufCreate,BufFilePost * call <SID>BMAdd()
+  au BufDelete,BufFilePre * call <SID>BMRemove()
+  aug END
+endfunc
+
+func! s:BMHash(name)
+  " Make name all upper case, so that chars are between 32 and 96
+  let nm = substitute(a:name, ".*", '\U\0', "")
+  if has("ebcdic")
+    " HACK: Replace all non alphabetics with 'Z'
+    "       Just to make it work for now.
+    let nm = substitute(nm, "[^A-Z]", 'Z', "g")
+    let sp = char2nr('A') - 1
+  else
+    let sp = char2nr(' ')
+  endif
+  " convert first six chars into a number for sorting:
+  return (char2nr(nm[0]) - sp) * 0x800000 + (char2nr(nm[1]) - sp) * 0x20000 + (char2nr(nm[2]) - sp) * 0x1000 + (char2nr(nm[3]) - sp) * 0x80 + (char2nr(nm[4]) - sp) * 0x20 + (char2nr(nm[5]) - sp)
+endfunc
+
+func! s:BMHash2(name)
+  let nm = substitute(a:name, ".", '\L\0', "")
+  " Not exactly right for EBCDIC...
+  if nm[0] < 'a' || nm[0] > 'z'
+    return '&others.'
+  elseif nm[0] <= 'd'
+    return '&abcd.'
+  elseif nm[0] <= 'h'
+    return '&efgh.'
+  elseif nm[0] <= 'l'
+    return '&ijkl.'
+  elseif nm[0] <= 'p'
+    return '&mnop.'
+  elseif nm[0] <= 't'
+    return '&qrst.'
+  else
+    return '&u-z.'
+  endif
+endfunc
+
+" insert a buffer name into the buffer menu:
+func! s:BMFilename(name, num)
+  if isdirectory(a:name)
+    return
+  endif
+  let munge = <SID>BMMunge(a:name, a:num)
+  let hash = <SID>BMHash(munge)
+  if s:bmenu_short == 0
+    let name = 'an ' . g:bmenu_priority . '.' . hash . ' &Buffers.' . munge
+  else
+    let name = 'an ' . g:bmenu_priority . '.' . hash . '.' . hash . ' &Buffers.' . <SID>BMHash2(munge) . munge
+  endif
+  " set 'cpo' to include the <CR>
+  let cpo_save = &cpo
+  set cpo&vim
+  exe name . ' :confirm b' . a:num . '<CR>'
+  let &cpo = cpo_save
+endfunc
+
+" Truncate a long path to fit it in a menu item.
+if !exists("g:bmenu_max_pathlen")
+  let g:bmenu_max_pathlen = 35
+endif
+func! s:BMTruncName(fname)
+  let name = a:fname
+  if g:bmenu_max_pathlen < 5
+    let name = ""
+  else
+    let len = strlen(name)
+    if len > g:bmenu_max_pathlen
+      let amountl = (g:bmenu_max_pathlen / 2) - 2
+      let amountr = g:bmenu_max_pathlen - amountl - 3
+      let pattern = '^\(.\{,' . amountl . '}\).\{-}\(.\{,' . amountr . '}\)$'
+      let left = substitute(name, pattern, '\1', '')
+      let right = substitute(name, pattern, '\2', '')
+      if strlen(left) + strlen(right) < len
+	let name = left . '...' . right
+      endif
+    endif
+  endif
+  return name
+endfunc
+
+func! s:BMMunge(fname, bnum)
+  let name = a:fname
+  if name == ''
+    if !exists("g:menutrans_no_file")
+      let g:menutrans_no_file = "[No file]"
+    endif
+    let name = g:menutrans_no_file
+  else
+    let name = fnamemodify(name, ':p:~')
+  endif
+  " detach file name and separate it out:
+  let name2 = fnamemodify(name, ':t')
+  if a:bnum >= 0
+    let name2 = name2 . ' (' . a:bnum . ')'
+  endif
+  let name = name2 . "\t" . <SID>BMTruncName(fnamemodify(name,':h'))
+  let name = escape(name, "\\. \t|")
+  let name = substitute(name, "&", "&&", "g")
+  let name = substitute(name, "\n", "^@", "g")
+  return name
+endfunc
+
+" When just starting Vim, load the buffer menu later
+if has("vim_starting")
+  augroup LoadBufferMenu
+    au! VimEnter * if !exists("no_buffers_menu") | call <SID>BMShow() | endif
+    au  VimEnter * au! LoadBufferMenu
+  augroup END
+else
+  call <SID>BMShow()
+endif
+
+endif " !exists("no_buffers_menu")
+
+" Window menu
+an 70.300 &Window.&New<Tab>^Wn			<C-W>n
+an 70.310 &Window.S&plit<Tab>^Ws		<C-W>s
+an 70.320 &Window.Sp&lit\ To\ #<Tab>^W^^	<C-W><C-^>
+an 70.330 &Window.Split\ &Vertically<Tab>^Wv	<C-W>v
+if has("vertsplit")
+  an <silent> 70.332 &Window.Split\ File\ E&xplorer	:call MenuExplOpen()<CR>
+  if !exists("*MenuExplOpen")
+    fun MenuExplOpen()
+      if @% == ""
+	20vsp .
+      else
+	exe "20vsp " . expand("%:p:h")
+      endif
+    endfun
+  endif
+endif
+an 70.335 &Window.-SEP1-				<Nop>
+an 70.340 &Window.&Close<Tab>^Wc			:confirm close<CR>
+an 70.345 &Window.Close\ &Other(s)<Tab>^Wo		:confirm only<CR>
+an 70.350 &Window.-SEP2-				<Nop>
+an 70.355 &Window.Move\ &To.&Top<Tab>^WK		<C-W>K
+an 70.355 &Window.Move\ &To.&Bottom<Tab>^WJ		<C-W>J
+an 70.355 &Window.Move\ &To.&Left\ side<Tab>^WH		<C-W>H
+an 70.355 &Window.Move\ &To.&Right\ side<Tab>^WL	<C-W>L
+an 70.360 &Window.Rotate\ &Up<Tab>^WR			<C-W>R
+an 70.362 &Window.Rotate\ &Down<Tab>^Wr			<C-W>r
+an 70.365 &Window.-SEP3-				<Nop>
+an 70.370 &Window.&Equal\ Size<Tab>^W=			<C-W>=
+an 70.380 &Window.&Max\ Height<Tab>^W_			<C-W>_
+an 70.390 &Window.M&in\ Height<Tab>^W1_			<C-W>1_
+an 70.400 &Window.Max\ &Width<Tab>^W\|			<C-W>\|
+an 70.410 &Window.Min\ Widt&h<Tab>^W1\|			<C-W>1\|
+
+" The popup menu
+an 1.10 PopUp.&Undo			u
+an 1.15 PopUp.-SEP1-			<Nop>
+vnoremenu 1.20 PopUp.Cu&t		"+x
+vnoremenu 1.30 PopUp.&Copy		"+y
+cnoremenu 1.30 PopUp.&Copy		<C-Y>
+nnoremenu 1.40 PopUp.&Paste		"+gP
+cnoremenu 1.40 PopUp.&Paste		<C-R>+
+exe 'vnoremenu <script> 1.40 PopUp.&Paste	' . paste#paste_cmd['v']
+exe 'inoremenu <script> 1.40 PopUp.&Paste	' . paste#paste_cmd['i']
+vnoremenu 1.50 PopUp.&Delete		x
+an 1.55 PopUp.-SEP2-			<Nop>
+vnoremenu 1.60 PopUp.Select\ Blockwise	<C-V>
+
+nnoremenu 1.70 PopUp.Select\ &Word	vaw
+onoremenu 1.70 PopUp.Select\ &Word	aw
+vnoremenu 1.70 PopUp.Select\ &Word	<C-C>vaw
+inoremenu 1.70 PopUp.Select\ &Word	<C-O>vaw
+cnoremenu 1.70 PopUp.Select\ &Word	<C-C>vaw
+
+nnoremenu 1.73 PopUp.Select\ &Sentence	vas
+onoremenu 1.73 PopUp.Select\ &Sentence	as
+vnoremenu 1.73 PopUp.Select\ &Sentence	<C-C>vas
+inoremenu 1.73 PopUp.Select\ &Sentence	<C-O>vas
+cnoremenu 1.73 PopUp.Select\ &Sentence	<C-C>vas
+
+nnoremenu 1.77 PopUp.Select\ Pa&ragraph	vap
+onoremenu 1.77 PopUp.Select\ Pa&ragraph	ap
+vnoremenu 1.77 PopUp.Select\ Pa&ragraph	<C-C>vap
+inoremenu 1.77 PopUp.Select\ Pa&ragraph	<C-O>vap
+cnoremenu 1.77 PopUp.Select\ Pa&ragraph	<C-C>vap
+
+nnoremenu 1.80 PopUp.Select\ &Line	V
+onoremenu 1.80 PopUp.Select\ &Line	<C-C>V
+vnoremenu 1.80 PopUp.Select\ &Line	<C-C>V
+inoremenu 1.80 PopUp.Select\ &Line	<C-O>V
+cnoremenu 1.80 PopUp.Select\ &Line	<C-C>V
+
+nnoremenu 1.90 PopUp.Select\ &Block	<C-V>
+onoremenu 1.90 PopUp.Select\ &Block	<C-C><C-V>
+vnoremenu 1.90 PopUp.Select\ &Block	<C-C><C-V>
+inoremenu 1.90 PopUp.Select\ &Block	<C-O><C-V>
+cnoremenu 1.90 PopUp.Select\ &Block	<C-C><C-V>
+
+noremenu  <script> <silent> 1.100 PopUp.Select\ &All	:<C-U>call <SID>SelectAll()<CR>
+inoremenu <script> <silent> 1.100 PopUp.Select\ &All	<C-O>:call <SID>SelectAll()<CR>
+cnoremenu <script> <silent> 1.100 PopUp.Select\ &All	<C-U>call <SID>SelectAll()<CR>
+
+if has("spell")
+  " Spell suggestions in the popup menu.  Note that this will slow down the
+  " appearance of the menu!
+  func! <SID>SpellPopup()
+    if exists("s:changeitem") && s:changeitem != ''
+      call <SID>SpellDel()
+    endif
+
+    " Return quickly if spell checking is not enabled.
+    if !&spell || &spelllang == ''
+      return
+    endif
+
+    let curcol = col('.')
+    let [w, a] = spellbadword()
+    if col('.') > curcol		" don't use word after the cursor
+      let w = ''
+      call cursor(0, curcol)	" put the cursor back where it was
+    endif
+    if w != ''
+      if a == 'caps'
+	let s:suglist = [substitute(w, '.*', '\u&', '')]
+      else
+	let s:suglist = spellsuggest(w, 10)
+      endif
+      if len(s:suglist) <= 0
+	call cursor(0, curcol)	" put the cursor back where it was
+      else
+	let s:changeitem = 'change\ "' . escape(w, ' .'). '"\ to'
+	let s:fromword = w
+	let pri = 1
+	for sug in s:suglist
+	  exe 'anoremenu 1.5.' . pri . ' PopUp.' . s:changeitem . '.' . escape(sug, ' .')
+		\ . ' :call <SID>SpellReplace(' . pri . ')<CR>'
+	  let pri += 1
+	endfor
+
+	let s:additem = 'add\ "' . escape(w, ' .') . '"\ to\ word\ list'
+	exe 'anoremenu 1.6 PopUp.' . s:additem . ' :spellgood ' . w . '<CR>'
+
+	let s:ignoreitem = 'ignore\ "' . escape(w, ' .') . '"'
+	exe 'anoremenu 1.7 PopUp.' . s:ignoreitem . ' :spellgood! ' . w . '<CR>'
+
+	anoremenu 1.8 PopUp.-SpellSep- :
+      endif
+    endif
+  endfunc
+
+  func! <SID>SpellReplace(n)
+    let l = getline('.')
+    call setline('.', strpart(l, 0, col('.') - 1) . s:suglist[a:n - 1]
+	  \ . strpart(l, col('.') + len(s:fromword) - 1))
+  endfunc
+
+  func! <SID>SpellDel()
+    exe "aunmenu PopUp." . s:changeitem
+    exe "aunmenu PopUp." . s:additem
+    exe "aunmenu PopUp." . s:ignoreitem
+    aunmenu PopUp.-SpellSep-
+    let s:changeitem = ''
+  endfun
+
+  augroup SpellPopupMenu
+    au! MenuPopup * call <SID>SpellPopup()
+  augroup END
+endif
+
+" The GUI toolbar (for MS-Windows and GTK)
+if has("toolbar")
+  an 1.10 ToolBar.Open			:browse confirm e<CR>
+  an <silent> 1.20 ToolBar.Save		:if expand("%") == ""<Bar>browse confirm w<Bar>else<Bar>confirm w<Bar>endif<CR>
+  an 1.30 ToolBar.SaveAll		:browse confirm wa<CR>
+
+  if has("printer")
+    an 1.40   ToolBar.Print		:hardcopy<CR>
+    vunmenu   ToolBar.Print
+    vnoremenu ToolBar.Print		:hardcopy<CR>
+  elseif has("unix")
+    an 1.40   ToolBar.Print		:w !lpr<CR>
+    vunmenu   ToolBar.Print
+    vnoremenu ToolBar.Print		:w !lpr<CR>
+  endif
+
+  an 1.45 ToolBar.-sep1-		<Nop>
+  an 1.50 ToolBar.Undo			u
+  an 1.60 ToolBar.Redo			<C-R>
+
+  an 1.65 ToolBar.-sep2-		<Nop>
+  vnoremenu 1.70 ToolBar.Cut		"+x
+  vnoremenu 1.80 ToolBar.Copy		"+y
+  cnoremenu 1.80 ToolBar.Copy		<C-Y>
+  nnoremenu 1.90 ToolBar.Paste		"+gP
+  cnoremenu	 ToolBar.Paste		<C-R>+
+  exe 'vnoremenu <script>	 ToolBar.Paste	' . paste#paste_cmd['v']
+  exe 'inoremenu <script>	 ToolBar.Paste	' . paste#paste_cmd['i']
+
+  if !has("gui_athena")
+    an 1.95   ToolBar.-sep3-		<Nop>
+    an 1.100  ToolBar.Replace		:promptrepl<CR>
+    vunmenu   ToolBar.Replace
+    vnoremenu ToolBar.Replace		y:promptrepl <C-R>=<SID>FixFText()<CR><CR>
+    an 1.110  ToolBar.FindNext		n
+    an 1.120  ToolBar.FindPrev		N
+  endif
+
+  an 1.215 ToolBar.-sep5-		<Nop>
+  an <silent> 1.220 ToolBar.LoadSesn	:call <SID>LoadVimSesn()<CR>
+  an <silent> 1.230 ToolBar.SaveSesn	:call <SID>SaveVimSesn()<CR>
+  an 1.240 ToolBar.RunScript		:browse so<CR>
+
+  an 1.245 ToolBar.-sep6-		<Nop>
+  an 1.250 ToolBar.Make			:make<CR>
+  an 1.270 ToolBar.RunCtags		:exe "!" . g:ctags_command<CR>
+  an 1.280 ToolBar.TagJump		g<C-]>
+
+  an 1.295 ToolBar.-sep7-		<Nop>
+  an 1.300 ToolBar.Help			:help<CR>
+  an <silent> 1.310 ToolBar.FindHelp	:call <SID>Helpfind()<CR>
+
+" Only set the tooltips here if not done in a language menu file
+if exists("*Do_toolbar_tmenu")
+  call Do_toolbar_tmenu()
+else
+  let did_toolbar_tmenu = 1
+  tmenu ToolBar.Open		Open file
+  tmenu ToolBar.Save		Save current file
+  tmenu ToolBar.SaveAll		Save all files
+  tmenu ToolBar.Print		Print
+  tmenu ToolBar.Undo		Undo
+  tmenu ToolBar.Redo		Redo
+  tmenu ToolBar.Cut		Cut to clipboard
+  tmenu ToolBar.Copy		Copy to clipboard
+  tmenu ToolBar.Paste		Paste from Clipboard
+  if !has("gui_athena")
+    tmenu ToolBar.Find		Find...
+    tmenu ToolBar.FindNext	Find Next
+    tmenu ToolBar.FindPrev	Find Previous
+    tmenu ToolBar.Replace		Find / Replace...
+  endif
+  tmenu ToolBar.LoadSesn	Choose a session to load
+  tmenu ToolBar.SaveSesn	Save current session
+  tmenu ToolBar.RunScript	Choose a Vim Script to run
+  tmenu ToolBar.Make		Make current project (:make)
+  tmenu ToolBar.RunCtags	Build tags in current directory tree (!ctags -R .)
+  tmenu ToolBar.TagJump		Jump to tag under cursor
+  tmenu ToolBar.Help		Vim Help
+  tmenu ToolBar.FindHelp	Search Vim Help
+endif
+
+" Select a session to load; default to current session name if present
+fun! s:LoadVimSesn()
+  if strlen(v:this_session) > 0
+    let name = escape(v:this_session, ' \t#%$|<>"*?[{`')
+  else
+    let name = "Session.vim"
+  endif
+  execute "browse so " . name
+endfun
+
+" Select a session to save; default to current session name if present
+fun! s:SaveVimSesn()
+  if strlen(v:this_session) == 0
+    let v:this_session = "Session.vim"
+  endif
+  execute "browse mksession! " . escape(v:this_session, ' \t#%$|<>"*?[{`')
+endfun
+
+endif
+
+endif " !exists("did_install_default_menus")
+
+" Define these items always, so that syntax can be switched on when it wasn't.
+" But skip them when the Syntax menu was disabled by the user.
+if !exists("did_install_syntax_menu")
+  an 50.212 &Syntax.&Manual		:syn manual<CR>
+  an 50.214 &Syntax.A&utomatic		:syn on<CR>
+  an <silent> 50.216 &Syntax.on/off\ for\ &This\ file :call <SID>SynOnOff()<CR>
+  if !exists("*s:SynOnOff")
+    fun s:SynOnOff()
+      if has("syntax_items")
+	syn clear
+      else
+	if !exists("g:syntax_on")
+	  syn manual
+	endif
+	set syn=ON
+      endif
+    endfun
+  endif
+endif
+
+
+" Install the Syntax menu only when filetype.vim has been loaded or when
+" manual syntax highlighting is enabled.
+" Avoid installing the Syntax menu twice.
+if (exists("did_load_filetypes") || exists("syntax_on"))
+	\ && !exists("did_install_syntax_menu")
+  let did_install_syntax_menu = 1
+
+" Skip setting up the individual syntax selection menus unless
+" do_syntax_sel_menu is defined (it takes quite a bit of time).
+if exists("do_syntax_sel_menu")
+  runtime! synmenu.vim
+else
+  an 50.10 &Syntax.&Show\ filetypes\ in\ menu	:let do_syntax_sel_menu = 1<Bar>runtime! synmenu.vim<Bar>aunmenu &Syntax.&Show\ filetypes\ in\ menu<CR>
+  an 50.195 &Syntax.-SEP1-		<Nop>
+endif
+
+an 50.210 &Syntax.&Off			:syn off<CR>
+an 50.700 &Syntax.-SEP3-		<Nop>
+an 50.710 &Syntax.Co&lor\ test		:sp $VIMRUNTIME/syntax/colortest.vim<Bar>so %<CR>
+an 50.720 &Syntax.&Highlight\ test	:runtime syntax/hitest.vim<CR>
+an 50.730 &Syntax.&Convert\ to\ HTML	:runtime syntax/2html.vim<CR>
+
+endif " !exists("did_install_syntax_menu")
+
+" Restore the previous value of 'cpoptions'.
+let &cpo = s:cpo_save
+unlet s:cpo_save
+
+" vim: set sw=2 :
--- /dev/null
+++ b/lib/vimfiles/mswin.vim
@@ -1,0 +1,106 @@
+" Set options and add mapping such that Vim behaves a lot like MS-Windows
+"
+" Maintainer:	Bram Moolenaar <Bram@vim.org>
+" Last change:	2006 Apr 02
+
+" bail out if this isn't wanted (mrsvim.vim uses this).
+if exists("g:skip_loading_mswin") && g:skip_loading_mswin
+  finish
+endif
+
+" set the 'cpoptions' to its Vim default
+if 1	" only do this when compiled with expression evaluation
+  let s:save_cpo = &cpoptions
+endif
+set cpo&vim
+
+" set 'selection', 'selectmode', 'mousemodel' and 'keymodel' for MS-Windows
+behave mswin
+
+" backspace and cursor keys wrap to previous/next line
+set backspace=indent,eol,start whichwrap+=<,>,[,]
+
+" backspace in Visual mode deletes selection
+vnoremap <BS> d
+
+" CTRL-X and SHIFT-Del are Cut
+vnoremap <C-X> "+x
+vnoremap <S-Del> "+x
+
+" CTRL-C and CTRL-Insert are Copy
+vnoremap <C-C> "+y
+vnoremap <C-Insert> "+y
+
+" CTRL-V and SHIFT-Insert are Paste
+map <C-V>		"+gP
+map <S-Insert>		"+gP
+
+cmap <C-V>		<C-R>+
+cmap <S-Insert>		<C-R>+
+
+" Pasting blockwise and linewise selections is not possible in Insert and
+" Visual mode without the +virtualedit feature.  They are pasted as if they
+" were characterwise instead.
+" Uses the paste.vim autoload script.
+
+exe 'inoremap <script> <C-V>' paste#paste_cmd['i']
+exe 'vnoremap <script> <C-V>' paste#paste_cmd['v']
+
+imap <S-Insert>		<C-V>
+vmap <S-Insert>		<C-V>
+
+" Use CTRL-Q to do what CTRL-V used to do
+noremap <C-Q>		<C-V>
+
+" Use CTRL-S for saving, also in Insert mode
+noremap <C-S>		:update<CR>
+vnoremap <C-S>		<C-C>:update<CR>
+inoremap <C-S>		<C-O>:update<CR>
+
+" For CTRL-V to work autoselect must be off.
+" On Unix we have two selections, autoselect can be used.
+if !has("unix")
+  set guioptions-=a
+endif
+
+" CTRL-Z is Undo; not in cmdline though
+noremap <C-Z> u
+inoremap <C-Z> <C-O>u
+
+" CTRL-Y is Redo (although not repeat); not in cmdline though
+noremap <C-Y> <C-R>
+inoremap <C-Y> <C-O><C-R>
+
+" Alt-Space is System menu
+if has("gui")
+  noremap <M-Space> :simalt ~<CR>
+  inoremap <M-Space> <C-O>:simalt ~<CR>
+  cnoremap <M-Space> <C-C>:simalt ~<CR>
+endif
+
+" CTRL-A is Select all
+noremap <C-A> gggH<C-O>G
+inoremap <C-A> <C-O>gg<C-O>gH<C-O>G
+cnoremap <C-A> <C-C>gggH<C-O>G
+onoremap <C-A> <C-C>gggH<C-O>G
+snoremap <C-A> <C-C>gggH<C-O>G
+xnoremap <C-A> <C-C>ggVG
+
+" CTRL-Tab is Next window
+noremap <C-Tab> <C-W>w
+inoremap <C-Tab> <C-O><C-W>w
+cnoremap <C-Tab> <C-C><C-W>w
+onoremap <C-Tab> <C-C><C-W>w
+
+" CTRL-F4 is Close window
+noremap <C-F4> <C-W>c
+inoremap <C-F4> <C-O><C-W>c
+cnoremap <C-F4> <C-C><C-W>c
+onoremap <C-F4> <C-C><C-W>c
+
+" restore 'cpoptions'
+set cpo&
+if 1
+  let &cpoptions = s:save_cpo
+  unlet s:save_cpo
+endif
--- /dev/null
+++ b/lib/vimfiles/optwin.vim
@@ -1,0 +1,1308 @@
+" These commands create the option window.
+"
+" Maintainer:	Bram Moolenaar <Bram@vim.org>
+" Last Change:	2006 Oct 10
+
+" If there already is an option window, jump to that one.
+if bufwinnr("option-window") > 0
+  let s:thiswin = winnr()
+  while 1
+    if @% == "option-window"
+      finish
+    endif
+    exe "norm! \<C-W>w"
+    if s:thiswin == winnr()
+      break
+    endif
+  endwhile
+endif
+
+" Make sure the '<' flag is not included in 'cpoptions', otherwise <CR> would
+" not be recognized.  See ":help 'cpoptions'".
+let s:cpo_save = &cpo
+set cpo&vim
+
+" function to be called when <CR> is hit in the option-window
+fun! <SID>CR()
+
+  " If on a continued comment line, go back to the first comment line
+  let lnum = line(".")
+  let line = getline(lnum)
+  while line[0] == "\t"
+    let lnum = lnum - 1
+    let line = getline(lnum)
+  endwhile
+
+  " <CR> on a "set" line executes the option line
+  if match(line, "^ \tset ") >= 0
+
+    " For a local option: go to the previous window
+    " If this is a help window, go to the window below it
+    let thiswin = winnr()
+    let local = <SID>Find(lnum)
+    if local >= 0
+      exe line
+      call <SID>Update(lnum, line, local, thiswin)
+    endif
+
+  " <CR> on a "option" line shows help for that option
+  elseif match(line, "^[a-z]") >= 0
+    let name = substitute(line, '\([^\t]*\).*', '\1', "")
+    exe "help '" . name . "'"
+
+  " <CR> on an index line jumps to the group
+  elseif match(line, '^ \=[0-9]') >= 0
+    exe "norm! /" . line . "\<CR>zt"
+  endif
+endfun
+
+" function to be called when <Space> is hit in the option-window
+fun! <SID>Space()
+
+  let lnum = line(".")
+  let line = getline(lnum)
+
+  " <Space> on a "set" line refreshes the option line
+  if match(line, "^ \tset ") >= 0
+
+    " For a local option: go to the previous window
+    " If this is a help window, go to the window below it
+    let thiswin = winnr()
+    let local = <SID>Find(lnum)
+    if local >= 0
+      call <SID>Update(lnum, line, local, thiswin)
+    endif
+
+  endif
+endfun
+
+" find the window in which the option applies
+" returns 0 for global option, 1 for local option, -1 for error
+fun! <SID>Find(lnum)
+    if getline(a:lnum - 1) =~ "(local to"
+      let local = 1
+      let thiswin = winnr()
+      exe "norm! \<C-W>p"
+      if exists("b:current_syntax") && b:current_syntax == "help"
+	exe "norm! \<C-W>j"
+	if winnr() == thiswin
+	  exe "norm! \<C-W>j"
+	endif
+      endif
+    else
+      let local = 0
+    endif
+    if local && (winnr() == thiswin || (exists("b:current_syntax")
+	\ && b:current_syntax == "help"))
+      echo "Don't know in which window"
+      let local = -1
+    endif
+    return local
+endfun
+
+" Update a "set" line in the option window
+fun! <SID>Update(lnum, line, local, thiswin)
+  " get the new value of the option and update the option window line
+  if match(a:line, "=") >= 0
+    let name = substitute(a:line, '^ \tset \([^=]*\)=.*', '\1', "")
+  else
+    let name = substitute(a:line, '^ \tset \(no\)\=\([a-z]*\).*', '\2', "")
+  endif
+  if name == "pt" && &pt =~ "\x80"
+    let val = <SID>PTvalue()
+  else
+    exe "let val = substitute(&" . name . ', "[ \\t\\\\\"|]", "\\\\\\0", "g")'
+  endif
+  if a:local
+    exe "norm! " . a:thiswin . "\<C-W>w"
+  endif
+  if match(a:line, "=") >= 0 || (val != "0" && val != "1")
+    call setline(a:lnum, " \tset " . name . "=" . val)
+  else
+    if val
+      call setline(a:lnum, " \tset " . name . "\tno" . name)
+    else
+      call setline(a:lnum, " \tset no" . name . "\t" . name)
+    endif
+  endif
+  set nomodified
+endfun
+
+" Reset 'title' and 'icon' to make it work faster.
+let s:old_title = &title
+let s:old_icon = &icon
+let s:old_sc = &sc
+let s:old_ru = &ru
+set notitle noicon nosc noru
+
+" If the current window is a help window, try finding a non-help window.
+" Relies on syntax highlighting to be switched on.
+let s:thiswin = winnr()
+while exists("b:current_syntax") && b:current_syntax == "help"
+  exe "norm! \<C-W>w"
+  if s:thiswin == winnr()
+    break
+  endif
+endwhile
+
+" Open the window
+new option-window
+setlocal ts=15 tw=0
+
+" Insert help and a "set" command for each option.
+call append(0, '" Each "set" line shows the current value of an option (on the left).')
+call append(1, '" Hit <CR> on a "set" line to execute it.')
+call append(2, '"            A boolean option will be toggled.')
+call append(3, '"            For other options you can edit the value.')
+call append(4, '" Hit <CR> on a help line to open a help window on this option.')
+call append(5, '" Hit <CR> on an index line to jump there.')
+call append(6, '" Hit <Space> on a "set" line to refresh it.')
+
+" These functions are called often below.  Keep them fast!
+
+" Init a local binary option
+fun! <SID>BinOptionL(name)
+  exe "norm! \<C-W>p"
+  exe "let val = &" . a:name
+  exe "norm! \<C-W>p"
+  call append("$", substitute(substitute(" \tset " . val . a:name . "\t" .
+	\!val . a:name, "0", "no", ""), "1", "", ""))
+endfun
+
+" Init a global binary option
+fun! <SID>BinOptionG(name, val)
+  call append("$", substitute(substitute(" \tset " . a:val . a:name . "\t" .
+	\!a:val . a:name, "0", "no", ""), "1", "", ""))
+endfun
+
+" Init a local string option
+fun! <SID>OptionL(name)
+  exe "norm! \<C-W>p"
+  exe "let val = substitute(&" . a:name . ', "[ \\t\\\\\"|]", "\\\\\\0", "g")'
+  exe "norm! \<C-W>p"
+  call append("$", " \tset " . a:name . "=" . val)
+endfun
+
+" Init a global string option
+fun! <SID>OptionG(name, val)
+  call append("$", " \tset " . a:name . "=" . substitute(a:val, '[ \t\\"|]',
+	\ '\\\0', "g"))
+endfun
+
+let s:idx = 1
+let s:lnum = line("$")
+call append("$", "")
+
+fun! <SID>Header(text)
+  let line = s:idx . " " . a:text
+  if s:idx < 10
+    let line = " " . line
+  endif
+  call append("$", "")
+  call append("$", line)
+  call append("$", "")
+  call append(s:lnum, line)
+  let s:idx = s:idx + 1
+  let s:lnum = s:lnum + 1
+endfun
+
+" Get the value of 'pastetoggle'.  It could be a special key.
+fun! <SID>PTvalue()
+  redir @a
+  silent set pt
+  redir END
+  return substitute(@a, '[^=]*=\(.*\)', '\1', "")
+endfun
+
+" Restore the previous value of 'cpoptions' here, it's used below.
+let &cpo = s:cpo_save
+
+" List of all options, organized by function.
+" The text should be sufficient to know what the option is used for.
+
+call <SID>Header("important")
+call append("$", "compatible\tbehave very Vi compatible (not advisable)")
+call <SID>BinOptionG("cp", &cp)
+call append("$", "cpoptions\tlist of flags to specify Vi compatibility")
+call <SID>OptionG("cpo", &cpo)
+call append("$", "insertmode\tuse Insert mode as the default mode")
+call <SID>BinOptionG("im", &im)
+call append("$", "paste\tpaste mode, insert typed text literally")
+call <SID>BinOptionG("paste", &paste)
+call append("$", "pastetoggle\tkey sequence to toggle paste mode")
+if &pt =~ "\x80"
+  call append("$", " \tset pt=" . <SID>PTvalue())
+else
+  call <SID>OptionG("pt", &pt)
+endif
+call append("$", "runtimepath\tlist of directories used for runtime files and plugins")
+call <SID>OptionG("rtp", &rtp)
+call append("$", "helpfile\tname of the main help file")
+call <SID>OptionG("hf", &hf)
+
+
+call <SID>Header("moving around, searching and patterns")
+call append("$", "whichwrap\tlist of flags specifying which commands wrap to another line")
+call append("$", "\t(local to window)")
+call <SID>OptionL("ww")
+call append("$", "startofline\tmany jump commands move the cursor to the first non-blank")
+call append("$", "\tcharacter of a line")
+call <SID>BinOptionG("sol", &sol)
+call append("$", "paragraphs\tnroff macro names that separate paragraphs")
+call <SID>OptionG("para", &para)
+call append("$", "sections\tnroff macro names that separate sections")
+call <SID>OptionG("sect", &sect)
+call append("$", "path\tlist of directory names used for file searching")
+call append("$", "\t(global or local to buffer)")
+call <SID>OptionG("pa", &pa)
+call append("$", "cdpath\tlist of directory names used for :cd")
+call <SID>OptionG("cd", &cd)
+if has("netbeans_intg") || has("sun_workshop")
+  call append("$", "autochdir\tchange to directory of file in buffer")
+  call <SID>BinOptionG("acd", &acd)
+endif
+call append("$", "wrapscan\tsearch commands wrap around the end of the buffer")
+call <SID>BinOptionG("ws", &ws)
+call append("$", "incsearch\tshow match for partly typed search command")
+call <SID>BinOptionG("is", &is)
+call append("$", "magic\tchange the way backslashes are used in search patterns")
+call <SID>BinOptionG("magic", &magic)
+call append("$", "ignorecase\tignore case when using a search pattern")
+call <SID>BinOptionG("ic", &ic)
+call append("$", "smartcase\toverride 'ignorecase' when pattern has upper case characters")
+call <SID>BinOptionG("scs", &scs)
+call append("$", "casemap\tWhat method to use for changing case of letters")
+call <SID>OptionG("cmp", &cmp)
+call append("$", "maxmempattern\tmaximum amount of memory in Kbyte used for pattern matching")
+call append("$", " \tset mmp=" . &mmp)
+call append("$", "define\tpattern for a macro definition line")
+call append("$", "\t(global or local to buffer)")
+call <SID>OptionG("def", &def)
+if has("find_in_path")
+  call append("$", "include\tpattern for an include-file line")
+  call append("$", "\t(local to buffer)")
+  call <SID>OptionL("inc")
+  call append("$", "includeexpr\texpression used to transform an include line to a file name")
+  call append("$", "\t(local to buffer)")
+  call <SID>OptionL("inex")
+endif
+
+
+call <SID>Header("tags")
+call append("$", "tagbsearch\tuse binary searching in tags files")
+call <SID>BinOptionG("tbs", &tbs)
+call append("$", "taglength\tnumber of significant characters in a tag name or zero")
+call append("$", " \tset tl=" . &tl)
+call append("$", "tags\tlist of file names to search for tags")
+call append("$", "\t(global or local to buffer)")
+call <SID>OptionG("tag", &tag)
+call append("$", "tagrelative\tfile names in a tags file are relative to the tags file")
+call <SID>BinOptionG("tr", &tr)
+call append("$", "tagstack\ta :tag command will use the tagstack")
+call <SID>BinOptionG("tgst", &tgst)
+call append("$", "showfulltag\twhen completing tags in Insert mode show more info")
+call <SID>BinOptionG("sft", &sft)
+if has("cscope")
+  call append("$", "cscopeprg\tcommand for executing cscope")
+  call <SID>OptionG("csprg", &csprg)
+  call append("$", "cscopetag\tuse cscope for tag commands")
+  call <SID>BinOptionG("cst", &cst)
+  call append("$", "cscopetagorder\t0 or 1; the order in which \":cstag\" performs a search")
+  call append("$", " \tset csto=" . &csto)
+  call append("$", "cscopeverbose\tgive messages when adding a cscope database")
+  call <SID>BinOptionG("csverb", &csverb)
+  call append("$", "cscopepathcomp\thow many components of the path to show")
+  call append("$", " \tset cspc=" . &cspc)
+  call append("$", "cscopequickfix\tWhen to open a quickfix window for cscope")
+  call <SID>OptionG("csqf", &csqf)
+endif
+
+
+call <SID>Header("displaying text")
+call append("$", "scroll\tnumber of lines to scroll for CTRL-U and CTRL-D")
+call append("$", "\t(local to window)")
+call <SID>OptionL("scr")
+call append("$", "scrolloff\tnumber of screen lines to show around the cursor")
+call append("$", " \tset so=" . &so)
+call append("$", "wrap\tlong lines wrap")
+call <SID>BinOptionG("wrap", &wrap)
+call append("$", "linebreak\twrap long lines at a character in 'breakat'")
+call append("$", "\t(local to window)")
+call <SID>BinOptionL("lbr")
+call append("$", "breakat\twhich characters might cause a line break")
+call <SID>OptionG("brk", &brk)
+call append("$", "showbreak\tstring to put before wrapped screen lines")
+call <SID>OptionG("sbr", &sbr)
+call append("$", "sidescroll\tminimal number of columns to scroll horizontally")
+call append("$", " \tset ss=" . &ss)
+call append("$", "sidescrolloff\tminimal number of columns to keep left and right of the cursor")
+call append("$", " \tset siso=" . &siso)
+call append("$", "display\tinclude \"lastline\" to show the last line even if it doesn't fit")
+call append("$", "\tinclude \"uhex\" to show unprintable characters as a hex number")
+call <SID>OptionG("dy", &dy)
+call append("$", "fillchars\tcharacters to use for the status line, folds and filler lines")
+call <SID>OptionG("fcs", &fcs)
+call append("$", "cmdheight\tnumber of lines used for the command-line")
+call append("$", " \tset ch=" . &ch)
+call append("$", "columns\twidth of the display")
+call append("$", " \tset co=" . &co)
+call append("$", "lines\tnumber of lines in the display")
+call append("$", " \tset lines=" . &lines)
+call append("$", "lazyredraw\tdon't redraw while executing macros")
+call <SID>BinOptionG("lz", &lz)
+call append("$", "writedelay\tdelay in msec for each char written to the display")
+call append("$", "\t(for debugging)")
+call append("$", " \tset wd=" . &wd)
+call append("$", "list\tshow <Tab> as ^I and end-of-line as $")
+call append("$", "\t(local to window)")
+call <SID>BinOptionL("list")
+call append("$", "listchars\tlist of strings used for list mode")
+call <SID>OptionG("lcs", &lcs)
+call append("$", "number\tshow the line number for each line")
+call append("$", "\t(local to window)")
+call <SID>BinOptionL("nu")
+if has("linebreak")
+  call append("$", "numberwidth\tnumber of columns to use for the line number")
+  call append("$", "\t(local to window)")
+  call <SID>OptionL("nuw")
+endif
+
+
+call <SID>Header("syntax, highlighting and spelling")
+call append("$", "background\t\"dark\" or \"light\"; the background color brightness")
+call <SID>OptionG("bg", &bg)
+if has("autocmd")
+  call append("$", "filetype\ttype of file; triggers the FileType event when set")
+  call append("$", "\t(local to buffer)")
+  call <SID>OptionL("ft")
+endif
+if has("syntax")
+  call append("$", "syntax\tname of syntax highlighting used")
+  call append("$", "\t(local to buffer)")
+  call <SID>OptionL("syn")
+  call append("$", "synmaxcol\tmaximum column to look for syntax items")
+  call append("$", "\t(local to buffer)")
+  call <SID>OptionL("smc")
+endif
+call append("$", "highlight\twhich highlighting to use for various occasions")
+call <SID>OptionG("hl", &hl)
+call append("$", "hlsearch\thighlight all matches for the last used search pattern")
+call <SID>BinOptionG("hls", &hls)
+if has("syntax")
+  call append("$", "cursorcolumn\thighlight the screen column of the cursor")
+  call append("$", "\t(local to window)")
+  call <SID>BinOptionL("cuc")
+  call append("$", "cursorline\thighlight the screen line of the cursor")
+  call append("$", "\t(local to window)")
+  call <SID>BinOptionL("cul")
+  call append("$", "spell\thighlight spelling mistakes")
+  call append("$", "\t(local to window)")
+  call <SID>BinOptionL("spell")
+  call append("$", "spelllang\tlist of accepted languages")
+  call append("$", "\t(local to buffer)")
+  call <SID>OptionL("spl")
+  call append("$", "spellfile\tfile that \"zg\" adds good words to")
+  call append("$", "\t(local to buffer)")
+  call <SID>OptionL("spf")
+  call append("$", "spellcapcheck\tpattern to locate the end of a sentence")
+  call append("$", "\t(local to buffer)")
+  call <SID>OptionL("spc")
+  call append("$", "spellsuggest\tmethods used to suggest corrections")
+  call <SID>OptionG("sps", &sps)
+  call append("$", "mkspellmem\tamount of memory used by :mkspell before compressing")
+  call <SID>OptionG("msm", &msm)
+endif
+
+
+call <SID>Header("multiple windows")
+call append("$", "laststatus\t0, 1 or 2; when to use a status line for the last window")
+call append("$", " \tset ls=" . &ls)
+if has("statusline")
+  call append("$", "statusline\talternate format to be used for a status line")
+  call <SID>OptionG("stl", &stl)
+endif
+call append("$", "equalalways\tmake all windows the same size when adding/removing windows")
+call <SID>BinOptionG("ea", &ea)
+if has("vertsplit")
+  call append("$", "eadirection\tin which direction 'equalalways' works: \"ver\", \"hor\" or \"both\"")
+  call <SID>OptionG("ead", &ead)
+endif
+call append("$", "winheight\tminimal number of lines used for the current window")
+call append("$", " \tset wh=" . &wh)
+call append("$", "winminheight\tminimal number of lines used for any window")
+call append("$", " \tset wmh=" . &wmh)
+call append("$", "winfixheight\tkeep the height of the window")
+call append("$", "\t(local to window)")
+call <SID>BinOptionL("wfh")
+if has("vertsplit")
+call append("$", "winfixwidth\tkeep the width of the window")
+call append("$", "\t(local to window)")
+call <SID>BinOptionL("wfw")
+  call append("$", "winwidth\tminimal number of columns used for the current window")
+  call append("$", " \tset wiw=" . &wiw)
+  call append("$", "winminwidth\tminimal number of columns used for any window")
+  call append("$", " \tset wmw=" . &wmw)
+endif
+call append("$", "helpheight\tinitial height of the help window")
+call append("$", " \tset hh=" . &hh)
+if has("quickfix")
+  call append("$", "previewheight\tdefault height for the preview window")
+  call append("$", " \tset pvh=" . &pvh)
+  call append("$", "previewwindow\tidentifies the preview window")
+  call append("$", "\t(local to window)")
+  call <SID>BinOptionL("pvw")
+endif
+call append("$", "hidden\tdon't unload a buffer when no longer shown in a window")
+call <SID>BinOptionG("hid", &hid)
+call append("$", "switchbuf\t\"useopen\" and/or \"split\"; which window to use when jumping")
+call append("$", "\tto a buffer")
+call <SID>OptionG("swb", &swb)
+call append("$", "splitbelow\ta new window is put below the current one")
+call <SID>BinOptionG("sb", &sb)
+if has("vertsplit")
+  call append("$", "splitright\ta new window is put right of the current one")
+  call <SID>BinOptionG("spr", &spr)
+endif
+if has("scrollbind")
+  call append("$", "scrollbind\tthis window scrolls together with other bound windows")
+  call append("$", "\t(local to window)")
+  call <SID>BinOptionL("scb")
+  call append("$", "scrollopt\t\"ver\", \"hor\" and/or \"jump\"; list of options for 'scrollbind'")
+  call <SID>OptionG("sbo", &sbo)
+endif
+
+
+call <SID>Header("multiple tab pages")
+call append("$", "showtabline\t0, 1 or 2; when to use a tab pages line")
+call append("$", " \tset stal=" . &stal)
+call append("$", "tabpagemax\tmaximum number of tab pages to open for -p and \"tab all\"")
+call append("$", " \tset tpm=" . &tpm)
+call append("$", "tabline\tcustom tab pages line")
+call <SID>OptionG("tal", &tal)
+if has("gui")
+  call append("$", "guitablabel\tcustom tab page label for the GUI")
+  call <SID>OptionG("gtl", &gtl)
+  call append("$", "guitabtooltip\tcustom tab page tooltip for the GUI")
+  call <SID>OptionG("gtt", &gtt)
+endif
+
+
+call <SID>Header("terminal")
+call append("$", "term\tname of the used terminal")
+call <SID>OptionG("term", &term)
+call append("$", "ttytype\talias for 'term'")
+call <SID>OptionG("tty", &tty)
+call append("$", "ttybuiltin\tcheck built-in termcaps first")
+call <SID>BinOptionG("tbi", &tbi)
+call append("$", "ttyfast\tterminal connection is fast")
+call <SID>BinOptionG("tf", &tf)
+call append("$", "weirdinvert\tterminal that requires extra redrawing")
+call <SID>BinOptionG("wiv", &wiv)
+call append("$", "esckeys\trecognize keys that start with <Esc> in Insert mode")
+call <SID>BinOptionG("ek", &ek)
+call append("$", "scrolljump\tminimal number of lines to scroll at a time")
+call append("$", " \tset sj=" . &sj)
+call append("$", "ttyscroll\tmaximum number of lines to use scrolling instead of redrawing")
+call append("$", " \tset tsl=" . &tsl)
+if has("gui") || has("msdos") || has("win32")
+  call append("$", "guicursor\tspecifies what the cursor looks like in different modes")
+  call <SID>OptionG("gcr", &gcr)
+endif
+if has("title")
+  let &title = s:old_title
+  call append("$", "title\tshow info in the window title")
+  call <SID>BinOptionG("title", &title)
+  set notitle
+  call append("$", "titlelen\tpercentage of 'columns' used for the window title")
+  call append("$", " \tset titlelen=" . &titlelen)
+  call append("$", "titlestring\twhen not empty, string to be used for the window title")
+  call <SID>OptionG("titlestring", &titlestring)
+  call append("$", "titleold\tstring to restore the title to when exiting Vim")
+  call <SID>OptionG("titleold", &titleold)
+  let &icon = s:old_icon
+  call append("$", "icon\tset the text of the icon for this window")
+  call <SID>BinOptionG("icon", &icon)
+  set noicon
+  call append("$", "iconstring\twhen not empty, text for the icon of this window")
+  call <SID>OptionG("iconstring", &iconstring)
+endif
+if has("win32")
+  call append("$", "restorescreen\trestore the screen contents when exiting Vim")
+  call <SID>BinOptionG("rs", &rs)
+endif
+
+
+call <SID>Header("using the mouse")
+call append("$", "mouse\tlist of flags for using the mouse")
+call <SID>OptionG("mouse", &mouse)
+if has("gui")
+  call append("$", "mousefocus\tthe window with the mouse pointer becomes the current one")
+  call <SID>BinOptionG("mousef", &mousef)
+  call append("$", "mousehide\thide the mouse pointer while typing")
+  call <SID>BinOptionG("mh", &mh)
+endif
+call append("$", "mousemodel\t\"extend\", \"popup\" or \"popup_setpos\"; what the right")
+call append("$", "\tmouse button is used for")
+call <SID>OptionG("mousem", &mousem)
+call append("$", "mousetime\tmaximum time in msec to recognize a double-click")
+call append("$", " \tset mouset=" . &mouset)
+call append("$", "ttymouse\t\"xterm\", \"xterm2\", \"dec\" or \"netterm\"; type of mouse")
+call <SID>OptionG("ttym", &ttym)
+if has("mouseshape")
+  call append("$", "mouseshape\twhat the mouse pointer looks like in different modes")
+  call <SID>OptionG("mouses", &mouses)
+endif
+
+
+if has("gui")
+  call <SID>Header("GUI")
+  call append("$", "guifont\tlist of font names to be used in the GUI")
+  call <SID>OptionG("gfn", &gfn)
+  if has("xfontset")
+    call append("$", "guifontset\tpair of fonts to be used, for multibyte editing")
+    call <SID>OptionG("gfs", &gfs)
+  endif
+  call append("$", "guifontwide\tlist of font names to be used for double-wide characters")
+  call <SID>OptionG("gfw", &gfw)
+  if has("mac")
+    call append("$", "antialias\tuse smooth, antialiased fonts")
+    call <SID>BinOptionG("anti", &anti)
+  endif
+  call append("$", "guioptions\tlist of flags that specify how the GUI works")
+  call <SID>OptionG("go", &go)
+  if has("gui_gtk")
+    call append("$", "toolbar\t\"icons\", \"text\" and/or \"tooltips\"; how to show the toolbar")
+    call <SID>OptionG("tb", &tb)
+    if has("gui_gtk2")
+      call append("$", "toolbariconsize\tSize of toolbar icons")
+      call <SID>OptionG("tbis", &tbis)
+    endif
+    call append("$", "guiheadroom\troom (in pixels) left above/below the window")
+    call append("$", " \tset ghr=" . &ghr)
+  endif
+  call append("$", "guipty\tuse a pseudo-tty for I/O to external commands")
+  call <SID>BinOptionG("guipty", &guipty)
+  if has("browse")
+    call append("$", "browsedir\t\"last\", \"buffer\" or \"current\": which directory used for the file browser")
+    call <SID>OptionG("bsdir", &bsdir)
+  endif
+  if has("multi_lang")
+    call append("$", "langmenu\tlanguage to be used for the menus")
+    call <SID>OptionG("langmenu", &lm)
+  endif
+  call append("$", "menuitems\tmaximum number of items in one menu")
+  call append("$", " \tset mis=" . &mis)
+  if has("winaltkeys")
+    call append("$", "winaltkeys\t\"no\", \"yes\" or \"menu\"; how to use the ALT key")
+    call <SID>OptionG("wak", &wak)
+  endif
+  call append("$", "linespace\tnumber of pixel lines to use between characters")
+  call append("$", " \tset lsp=" . &lsp)
+  if has("balloon_eval")
+    call append("$", "balloondelay\tdelay in milliseconds before a balloon may pop up")
+    call append("$", " \tset bdlay=" . &bdlay)
+    call append("$", "ballooneval\twhether the balloon evaluation is to be used")
+    call <SID>BinOptionG("beval", &beval)
+    if has("eval")
+      call append("$", "balloonexpr\texpression to show in balloon eval")
+      call append("$", " \tset bexpr=" . &bexpr)
+    endif
+  endif
+  if exists("+macatsui")
+    call append("$", "macatsui\tuse ATSUI text drawing; disable to avoid display problems")
+    call <SID>OptionG("macatsui", &macatsui)
+  endif
+endif
+
+if has("printer")
+  call <SID>Header("printing")
+  call append("$", "printoptions\tlist of items that control the format of :hardcopy output")
+  call <SID>OptionG("popt", &popt)
+  call append("$", "printdevice\tname of the printer to be used for :hardcopy")
+  call <SID>OptionG("pdev", &pdev)
+  if has("postscript")
+    call append("$", "printexpr\texpression used to print the PostScript file for :hardcopy")
+    call <SID>OptionG("pexpr", &pexpr)
+  endif
+  call append("$", "printfont\tname of the font to be used for :hardcopy")
+  call <SID>OptionG("pfn", &pfn)
+  call append("$", "printheader\tformat of the header used for :hardcopy")
+  call <SID>OptionG("pheader", &pheader)
+  if has("postscript")
+    call append("$", "printencoding\tencoding used to print the PostScript file for :hardcopy")
+    call <SID>OptionG("penc", &penc)
+  endif
+  if has("multi_byte")
+    call append("$", "printmbcharset\tthe CJK character set to be used for CJK output from :hardcopy")
+    call <SID>OptionG("pmbcs", &pmbcs)
+    call append("$", "printmbfont\tlist of font names to be used for CJK output from :hardcopy")
+    call <SID>OptionG("pmbfn", &pmbfn)
+  endif
+endif
+
+call <SID>Header("messages and info")
+call append("$", "terse\tadd 's' flag in 'shortmess' (don't show search message)")
+call <SID>BinOptionG("terse", &terse)
+call append("$", "shortmess\tlist of flags to make messages shorter")
+call <SID>OptionG("shm", &shm)
+call append("$", "showcmd\tshow (partial) command keys in the status line")
+let &sc = s:old_sc
+call <SID>BinOptionG("sc", &sc)
+set nosc
+call append("$", "showmode\tdisplay the current mode in the status line")
+call <SID>BinOptionG("smd", &smd)
+call append("$", "ruler\tshow cursor position below each window")
+let &ru = s:old_ru
+call <SID>BinOptionG("ru", &ru)
+set noru
+if has("statusline")
+  call append("$", "rulerformat\talternate format to be used for the ruler")
+  call <SID>OptionG("ruf", &ruf)
+endif
+call append("$", "report\tthreshold for reporting number of changed lines")
+call append("$", " \tset report=" . &report)
+call append("$", "verbose\tthe higher the more messages are given")
+call append("$", " \tset vbs=" . &vbs)
+call append("$", "verbosefile\tfile to write messages in")
+call <SID>OptionG("vfile", &vfile)
+call append("$", "more\tpause listings when the screen is full")
+call <SID>BinOptionG("more", &more)
+if has("dialog_con") || has("dialog_gui")
+  call append("$", "confirm\tstart a dialog when a command fails")
+  call <SID>BinOptionG("cf", &cf)
+endif
+call append("$", "errorbells\tring the bell for error messages")
+call <SID>BinOptionG("eb", &eb)
+call append("$", "visualbell\tuse a visual bell instead of beeping")
+call <SID>BinOptionG("vb", &vb)
+if has("multi_lang")
+  call append("$", "helplang\tlist of preferred languages for finding help")
+  call <SID>OptionG("hlg", &hlg)
+endif
+
+
+call <SID>Header("selecting text")
+call append("$", "selection\t\"old\", \"inclusive\" or \"exclusive\"; how selecting text behaves")
+call <SID>OptionG("sel", &sel)
+call append("$", "selectmode\t\"mouse\", \"key\" and/or \"cmd\"; when to start Select mode")
+call append("$", "\tinstead of Visual mode")
+call <SID>OptionG("slm", &slm)
+if has("clipboard")
+  call append("$", "clipboard\t\"unnamed\" to use the * register like unnamed register")
+  call append("$", "\t\"autoselect\" to always put selected text on the clipboard")
+  call <SID>OptionG("cb", &cb)
+endif
+call append("$", "keymodel\t\"startsel\" and/or \"stopsel\"; what special keys can do")
+call <SID>OptionG("km", &km)
+
+
+call <SID>Header("editing text")
+call append("$", "undolevels\tmaximum number of changes that can be undone")
+call append("$", " \tset ul=" . &ul)
+call append("$", "modified\tchanges have been made and not written to a file")
+call append("$", "\t(local to buffer)")
+call <SID>BinOptionL("mod")
+call append("$", "readonly\tbuffer is not to be written")
+call append("$", "\t(local to buffer)")
+call <SID>BinOptionL("ro")
+call append("$", "modifiable\tchanges to the text are not possible")
+call append("$", "\t(local to buffer)")
+call <SID>BinOptionL("ma")
+call append("$", "textwidth\tline length above which to break a line")
+call append("$", "\t(local to buffer)")
+call <SID>OptionL("tw")
+call append("$", "wrapmargin\tmargin from the right in which to break a line")
+call append("$", "\t(local to buffer)")
+call <SID>OptionL("wm")
+call append("$", "backspace\tspecifies what <BS>, CTRL-W, etc. can do in Insert mode")
+call append("$", " \tset bs=" . &bs)
+call append("$", "comments\tdefinition of what comment lines look like")
+call append("$", "\t(local to buffer)")
+call <SID>OptionL("com")
+call append("$", "formatoptions\tlist of flags that tell how automatic formatting works")
+call append("$", "\t(local to buffer)")
+call <SID>OptionL("fo")
+call append("$", "formatlistpat\tpattern to recognize a numbered list")
+call append("$", "\t(local to buffer)")
+call <SID>OptionL("flp")
+if has("eval")
+  call append("$", "formatexpr\texpression used for \"gq\" to format lines")
+  call append("$", "\t(local to buffer)")
+  call <SID>OptionL("fex")
+endif
+if has("insert_expand")
+  call append("$", "complete\tspecifies how Insert mode completion works for CTRL-N and CTRL-P")
+  call append("$", "\t(local to buffer)")
+  call <SID>OptionL("cpt")
+  call append("$", "completeopt\twhether to use a popup menu for Insert mode completion")
+  call <SID>OptionG("cot", &cot)
+  call append("$", "pumheight\tmaximum height of the popup menu")
+  call <SID>OptionG("ph", &ph)
+  call append("$", "completefunc\tuser defined function for Insert mode completion")
+  call append("$", "\t(local to buffer)")
+  call <SID>OptionL("cfu")
+  call append("$", "omnifunc\tfunction for filetype-specific Insert mode completion")
+  call append("$", "\t(local to buffer)")
+  call <SID>OptionL("ofu")
+  call append("$", "dictionary\tlist of dictionary files for keyword completion")
+  call append("$", "\t(global or local to buffer)")
+  call <SID>OptionG("dict", &dict)
+  call append("$", "thesaurus\tlist of thesaurus files for keyword completion")
+  call append("$", "\t(global or local to buffer)")
+  call <SID>OptionG("tsr", &tsr)
+endif
+call append("$", "infercase\tadjust case of a keyword completion match")
+call append("$", "\t(local to buffer)")
+call <SID>BinOptionL("inf")
+if has("digraphs")
+  call append("$", "digraph\tenable entering digraps with c1 <BS> c2")
+  call <SID>BinOptionG("dg", &dg)
+endif
+call append("$", "tildeop\tthe \"~\" command behaves like an operator")
+call <SID>BinOptionG("top", &top)
+call append("$", "operatorfunc\tfunction called for the\"g@\"  operator")
+call <SID>OptionG("opfunc", &opfunc)
+call append("$", "showmatch\tWhen inserting a bracket, briefly jump to its match")
+call <SID>BinOptionG("sm", &sm)
+call append("$", "matchtime\ttenth of a second to show a match for 'showmatch'")
+call append("$", " \tset mat=" . &mat)
+call append("$", "matchpairs\tlist of pairs that match for the \"%\" command")
+call append("$", "\t(local to buffer)")
+call <SID>OptionL("mps")
+call append("$", "joinspaces\tuse two spaces after '.' when joining a line")
+call <SID>BinOptionG("js", &js)
+call append("$", "nrformats\t\"alpha\", \"octal\" and/or \"hex\"; number formats recognized for")
+call append("$", "\tCTRL-A and CTRL-X commands")
+call append("$", "\t(local to buffer)")
+call <SID>OptionL("nf")
+
+
+call <SID>Header("tabs and indenting")
+call append("$", "tabstop\tnumber of spaces a <Tab> in the text stands for")
+call append("$", "\t(local to buffer)")
+call <SID>OptionL("ts")
+call append("$", "shiftwidth\tnumber of spaces used for each step of (auto)indent")
+call append("$", "\t(local to buffer)")
+call <SID>OptionL("sw")
+call append("$", "smarttab\ta <Tab> in an indent inserts 'shiftwidth' spaces")
+call <SID>BinOptionG("sta", &sta)
+call append("$", "softtabstop\tif non-zero, number of spaces to insert for a <Tab>")
+call append("$", "\t(local to buffer)")
+call <SID>OptionL("sts")
+call append("$", "shiftround\tround to 'shiftwidth' for \"<<\" and \">>\"")
+call <SID>BinOptionG("sr", &sr)
+call append("$", "expandtab\texpand <Tab> to spaces in Insert mode")
+call append("$", "\t(local to buffer)")
+call <SID>BinOptionL("et")
+call append("$", "autoindent\tautomatically set the indent of a new line")
+call append("$", "\t(local to buffer)")
+call <SID>BinOptionL("ai")
+if has("smartindent")
+  call append("$", "smartindent\tdo clever autoindenting")
+  call append("$", "\t(local to buffer)")
+  call <SID>BinOptionL("si")
+endif
+if has("cindent")
+  call append("$", "cindent\tenable specific indenting for C code")
+  call append("$", "\t(local to buffer)")
+  call <SID>BinOptionL("cin")
+  call append("$", "cinoptions\toptions for C-indenting")
+  call append("$", "\t(local to buffer)")
+  call <SID>OptionL("cino")
+  call append("$", "cinkeys\tkeys that trigger C-indenting in Insert mode")
+  call append("$", "\t(local to buffer)")
+  call <SID>OptionL("cink")
+  call append("$", "cinwords\tlist of words that cause more C-indent")
+  call append("$", "\t(local to buffer)")
+  call <SID>OptionL("cinw")
+  call append("$", "indentexpr\texpression used to obtain the indent of a line")
+  call append("$", "\t(local to buffer)")
+  call <SID>OptionL("inde")
+  call append("$", "indentkeys\tkeys that trigger indenting with 'indentexpr' in Insert mode")
+  call append("$", "\t(local to buffer)")
+  call <SID>OptionL("indk")
+endif
+call append("$", "copyindent\tCopy whitespace for indenting from previous line")
+call append("$", "\t(local to buffer)")
+call <SID>BinOptionL("ci")
+call append("$", "preserveindent\tPreserve kind of whitespace when changing indent")
+call append("$", "\t(local to buffer)")
+call <SID>BinOptionL("pi")
+if has("lispindent")
+  call append("$", "lisp\tenable lisp mode")
+  call append("$", "\t(local to buffer)")
+  call <SID>BinOptionL("lisp")
+  call append("$", "lispwords\twords that change how lisp indenting works")
+  call <SID>OptionG("lw", &lw)
+endif
+
+
+if has("folding")
+  call <SID>Header("folding")
+  call append("$", "foldenable\tset to display all folds open")
+  call append("$", "\t(local to window)")
+  call <SID>BinOptionL("fen")
+  call append("$", "foldlevel\tfolds with a level higher than this number will be closed")
+  call append("$", "\t(local to window)")
+  call <SID>OptionL("fdl")
+  call append("$", "foldlevelstart\tvalue for 'foldlevel' when starting to edit a file")
+  call append("$", " \tset fdls=" . &fdls)
+  call append("$", "foldcolumn\twidth of the column used to indicate folds")
+  call append("$", "\t(local to window)")
+  call <SID>OptionL("fdc")
+  call append("$", "foldtext\texpression used to display the text of a closed fold")
+  call append("$", "\t(local to window)")
+  call <SID>OptionL("fdt")
+  call append("$", "foldclose\tset to \"all\" to close a fold when the cursor leaves it")
+  call <SID>OptionG("fcl", &fcl)
+  call append("$", "foldopen\tspecifies for which commands a fold will be opened")
+  call <SID>OptionG("fdo", &fdo)
+  call append("$", "foldminlines\tminimum number of screen lines for a fold to be closed")
+  call append("$", "\t(local to window)")
+  call <SID>OptionL("fml")
+  call append("$", "commentstring\ttemplate for comments; used to put the marker in")
+  call <SID>OptionL("cms")
+  call append("$", "foldmethod\tfolding type: \"manual\", \"indent\", \"expr\", \"marker\" or \"syntax\"")
+  call append("$", "\t(local to window)")
+  call <SID>OptionL("fdm")
+  call append("$", "foldexpr\texpression used when 'foldmethod' is \"expr\"")
+  call append("$", "\t(local to window)")
+  call <SID>OptionL("fde")
+  call append("$", "foldignore\tused to ignore lines when 'foldmethod' is \"indent\"")
+  call append("$", "\t(local to window)")
+  call <SID>OptionL("fdi")
+  call append("$", "foldmarker\tmarkers used when 'foldmethod' is \"marker\"")
+  call append("$", "\t(local to window)")
+  call <SID>OptionL("fmr")
+  call append("$", "foldnestmax\tmaximum fold depth for when 'foldmethod is \"indent\" or \"syntax\"")
+  call append("$", "\t(local to window)")
+  call <SID>OptionL("fdn")
+endif
+
+
+if has("diff")
+  call <SID>Header("diff mode")
+  call append("$", "diff\tuse diff mode for the current window")
+  call append("$", "\t(local to window)")
+  call <SID>BinOptionL("diff")
+  call append("$", "diffopt\toptions for using diff mode")
+  call <SID>OptionG("dip", &dip)
+  call append("$", "diffexpr\texpression used to obtain a diff file")
+  call <SID>OptionG("dex", &dex)
+  call append("$", "patchexpr\texpression used to patch a file")
+  call <SID>OptionG("pex", &pex)
+endif
+
+
+call <SID>Header("mapping")
+call append("$", "maxmapdepth\tmaximum depth of mapping")
+call append("$", " \tset mmd=" . &mmd)
+call append("$", "remap\trecognize mappings in mapped keys")
+call <SID>BinOptionG("remap", &remap)
+call append("$", "timeout\tallow timing out halfway into a mapping")
+call <SID>BinOptionG("to", &to)
+call append("$", "ttimeout\tallow timing out halfway into a key code")
+call <SID>BinOptionG("ttimeout", &ttimeout)
+call append("$", "timeoutlen\ttime in msec for 'timeout'")
+call append("$", " \tset tm=" . &tm)
+call append("$", "ttimeoutlen\ttime in msec for 'ttimeout'")
+call append("$", " \tset ttm=" . &ttm)
+
+
+call <SID>Header("reading and writing files")
+call append("$", "modeline\tenable using settings from modelines when reading a file")
+call append("$", "\t(local to buffer)")
+call <SID>BinOptionL("ml")
+call append("$", "modelines\tnumber of lines to check for modelines")
+call append("$", " \tset mls=" . &mls)
+call append("$", "binary\tbinary file editing")
+call append("$", "\t(local to buffer)")
+call <SID>BinOptionL("bin")
+call append("$", "endofline\tlast line in the file has an end-of-line")
+call append("$", "\t(local to buffer)")
+call <SID>BinOptionL("eol")
+if has("multi_byte")
+  call append("$", "bomb\tPrepend a Byte Order Mark to the file")
+  call append("$", "\t(local to buffer)")
+  call <SID>BinOptionL("bomb")
+endif
+call append("$", "fileformat\tend-of-line format: \"dos\", \"unix\" or \"mac\"")
+call append("$", "\t(local to buffer)")
+call <SID>OptionL("ff")
+call append("$", "fileformats\tlist of file formats to look for when editing a file")
+call <SID>OptionG("ffs", &ffs)
+call append("$", "textmode\tobsolete, use 'fileformat'")
+call append("$", "\t(local to buffer)")
+call <SID>BinOptionL("tx")
+call append("$", "textauto\tobsolete, use 'fileformats'")
+call <SID>BinOptionG("ta", &ta)
+call append("$", "write\twriting files is allowed")
+call <SID>BinOptionG("write", &write)
+call append("$", "writebackup\twrite a backup file before overwriting a file")
+call <SID>BinOptionG("wb", &wb)
+call append("$", "backup\tkeep a backup after overwriting a file")
+call <SID>BinOptionG("bk", &bk)
+call append("$", "backupskip\tpatterns that specify for which files a backup is not made")
+call append("$", " \tset bsk=" . &bsk)
+call append("$", "backupcopy\twhether to make the backup as a copy or rename the existing file")
+call append("$", " \tset bkc=" . &bkc)
+call append("$", "backupdir\tlist of directories to put backup files in")
+call <SID>OptionG("bdir", &bdir)
+call append("$", "backupext\tfile name extension for the backup file")
+call <SID>OptionG("bex", &bex)
+call append("$", "autowrite\tautomatically write a file when leaving a modified buffer")
+call <SID>BinOptionG("aw", &aw)
+call append("$", "autowriteall\tas 'autowrite', but works with more commands")
+call <SID>BinOptionG("awa", &awa)
+call append("$", "writeany\talways write without asking for confirmation")
+call <SID>BinOptionG("wa", &wa)
+call append("$", "autoread\tautomatically read a file when it was modified outside of Vim")
+call append("$", "\t(global or local to buffer)")
+call <SID>BinOptionG("ar", &ar)
+call append("$", "patchmode\tkeep oldest version of a file; specifies file name extension")
+call <SID>OptionG("pm", &pm)
+call append("$", "fsync\tforcibly sync the file to disk after writing it")
+call <SID>BinOptionG("fs", &fs)
+if !has("msdos")
+  call append("$", "shortname\tuse 8.3 file names")
+  call append("$", "\t(local to buffer)")
+  call <SID>BinOptionL("sn")
+endif
+
+
+call <SID>Header("the swap file")
+call append("$", "directory\tlist of directories for the swap file")
+call <SID>OptionG("dir", &dir)
+call append("$", "swapfile\tuse a swap file for this buffer")
+call append("$", "\t(local to buffer)")
+call <SID>BinOptionL("swf")
+call append("$", "swapsync\t\"sync\", \"fsync\" or empty; how to flush a swap file to disk")
+call <SID>OptionG("sws", &sws)
+call append("$", "updatecount\tnumber of characters typed to cause a swap file update")
+call append("$", " \tset uc=" . &uc)
+call append("$", "updatetime\ttime in msec after which the swap file will be updated")
+call append("$", " \tset ut=" . &ut)
+call append("$", "maxmem\tmaximum amount of memory in Kbyte used for one buffer")
+call append("$", " \tset mm=" . &mm)
+call append("$", "maxmemtot\tmaximum amount of memory in Kbyte used for all buffers")
+call append("$", " \tset mmt=" . &mmt)
+
+
+call <SID>Header("command line editing")
+call append("$", "history\thow many command lines are remembered ")
+call append("$", " \tset hi=" . &hi)
+call append("$", "wildchar\tkey that triggers command-line expansion")
+call append("$", " \tset wc=" . &wc)
+call append("$", "wildcharm\tlike 'wildchar' but can also be used in a mapping")
+call append("$", " \tset wcm=" . &wcm)
+call append("$", "wildmode\tspecifies how command line completion works")
+call <SID>OptionG("wim", &wim)
+if has("wildoptions")
+  call append("$", "wildoptions\tempty or \"tagfile\" to list file name of matching tags")
+  call <SID>OptionG("wop", &wop)
+endif
+call append("$", "suffixes\tlist of file name extensions that have a lower priority")
+call <SID>OptionG("su", &su)
+if has("file_in_path")
+  call append("$", "suffixesadd\tlist of file name extensions added when searching for a file")
+  call append("$", "\t(local to buffer)")
+  call <SID>OptionL("sua")
+endif
+if has("wildignore")
+  call append("$", "wildignore\tlist of patterns to ignore files for file name completion")
+  call <SID>OptionG("wig", &wig)
+endif
+if has("wildmenu")
+  call append("$", "wildmenu\tcommand-line completion shows a list of matches")
+  call <SID>BinOptionG("wmnu", &wmnu)
+endif
+if has("vertsplit")
+  call append("$", "cedit\tkey used to open the command-line window")
+  call <SID>OptionG("cedit", &cedit)
+  call append("$", "cmdwinheight\theight of the command-line window")
+  call <SID>OptionG("cwh", &cwh)
+endif
+
+
+call <SID>Header("executing external commands")
+call append("$", "shell\tname of the shell program used for external commands")
+call <SID>OptionG("sh", &sh)
+if has("amiga")
+  call append("$", "shelltype\twhen to use the shell or directly execute a command")
+  call append("$", " \tset st=" . &st)
+endif
+call append("$", "shellquote\tcharacter(s) to enclose a shell command in")
+call <SID>OptionG("shq", &shq)
+call append("$", "shellxquote\tlike 'shellquote' but include the redirection")
+call <SID>OptionG("sxq", &sxq)
+call append("$", "shellcmdflag\targument for 'shell' to execute a command")
+call <SID>OptionG("shcf", &shcf)
+call append("$", "shellredir\tused to redirect command output to a file")
+call <SID>OptionG("srr", &srr)
+call append("$", "shelltemp\tuse a temp file for shell commands instead of using a pipe")
+call <SID>BinOptionG("stmp", &stmp)
+call append("$", "equalprg\tprogram used for \"=\" command")
+call append("$", "\t(global or local to buffer)")
+call <SID>OptionG("ep", &ep)
+call append("$", "formatprg\tprogram used to format lines with \"gq\" command")
+call <SID>OptionG("fp", &fp)
+call append("$", "keywordprg\tprogram used for the \"K\" command")
+call <SID>OptionG("kp", &kp)
+call append("$", "warn\twarn when using a shell command and a buffer has changes")
+call <SID>BinOptionG("warn", &warn)
+
+
+if has("quickfix")
+  call <SID>Header("running make and jumping to errors")
+  call append("$", "errorfile\tname of the file that contains error messages")
+  call <SID>OptionG("ef", &ef)
+  call append("$", "errorformat\tlist of formats for error messages")
+  call append("$", "\t(global or local to buffer)")
+  call <SID>OptionG("efm", &efm)
+  call append("$", "makeprg\tprogram used for the \":make\" command")
+  call append("$", "\t(global or local to buffer)")
+  call <SID>OptionG("mp", &mp)
+  call append("$", "shellpipe\tstring used to put the output of \":make\" in the error file")
+  call <SID>OptionG("sp", &sp)
+  call append("$", "makeef\tname of the errorfile for the 'makeprg' command")
+  call <SID>OptionG("mef", &mef)
+  call append("$", "grepprg\tprogram used for the \":grep\" command")
+  call append("$", "\t(global or local to buffer)")
+  call <SID>OptionG("gp", &gp)
+  call append("$", "grepformat\tlist of formats for output of 'grepprg'")
+  call <SID>OptionG("gfm", &gfm)
+endif
+
+
+if has("msdos") || has("os2") || has("win16") || has("win32") || has("osfiletype")
+  call <SID>Header("system specific")
+  if has("msdos")
+    call append("$", "bioskey\tcall the BIOS to get a keyoard character")
+    call <SID>BinOptionG("biosk", &biosk)
+    call append("$", "conskey\tuse direct console I/O to get a keyboard character")
+    call <SID>BinOptionG("consk", &consk)
+  endif
+  if has("osfiletype")
+    call append("$", "osfiletype\tOS-specific information about the type of file")
+    call append("$", "\t(local to buffer)")
+    call <SID>OptionL("oft")
+  endif
+  if has("msdos") || has("os2") || has("win16") || has("win32")
+    call append("$", "shellslash\tuse forward slashes in file names; for Unix-like shells")
+    call <SID>BinOptionG("ssl", &ssl)
+  endif
+endif
+
+
+call <SID>Header("language specific")
+call append("$", "isfname\tspecifies the characters in a file name")
+call <SID>OptionG("isf", &isf)
+call append("$", "isident\tspecifies the characters in an identifier")
+call <SID>OptionG("isi", &isi)
+call append("$", "iskeyword\tspecifies the characters in a keyword")
+call append("$", "\t(local to buffer)")
+call <SID>OptionL("isk")
+call append("$", "isprint\tspecifies printable characters")
+call <SID>OptionG("isp", &isp)
+if has("textobjects")
+  call append("$", "quoteescape\tspecifies escape characters in a string")
+  call append("$", "\t(local to buffer)")
+  call <SID>OptionL("qe")
+endif
+if has("rightleft")
+  call append("$", "rightleft\tdisplay the buffer right-to-left")
+  call append("$", "\t(local to window)")
+  call <SID>BinOptionL("rl")
+  call append("$", "rightleftcmd\tWhen to edit the command-line right-to-left")
+  call append("$", "\t(local to window)")
+  call <SID>OptionL("rlc")
+  call append("$", "revins\tInsert characters backwards")
+  call <SID>BinOptionG("ri", &ri)
+  call append("$", "allowrevins\tAllow CTRL-_ in Insert and Command-line mode to toggle 'revins'")
+  call <SID>BinOptionG("ari", &ari)
+  call append("$", "aleph\tthe ASCII code for the first letter of the Hebrew alphabet")
+  call append("$", " \tset al=" . &al)
+  call append("$", "hkmap\tuse Hebrew keyboard mapping")
+  call <SID>BinOptionG("hk", &hk)
+  call append("$", "hkmapp\tuse phonetic Hebrew keyboard mapping")
+  call <SID>BinOptionG("hkp", &hkp)
+endif
+if has("farsi")
+  call append("$", "altkeymap\tuse Farsi as the second language when 'revins' is set")
+  call <SID>BinOptionG("akm", &akm)
+  call append("$", "fkmap\tuse Farsi keyboard mapping")
+  call <SID>BinOptionG("fk", &fk)
+endif
+if has("arabic")
+  call append("$", "arabic\tPrepare for editing Arabic text")
+  call append("$", "\t(local to window)")
+  call <SID>BinOptionL("arab")
+  call append("$", "arabicshape\tPerform shaping of Arabic characters")
+  call <SID>BinOptionG("arshape", &arshape)
+  call append("$", "termbidi\tTerminal will perform bidi handling")
+  call <SID>BinOptionG("tbidi", &tbidi)
+endif
+if has("keymap")
+  call append("$", "keymap\tname of a keyboard mappping")
+  call <SID>OptionL("kmp")
+endif
+if has("langmap")
+  call append("$", "langmap\ttranslate characters for Normal mode")
+  call <SID>OptionG("lmap", &lmap)
+endif
+if has("xim")
+  call append("$", "imdisable\twhen set never use IM; overrules following IM options")
+  call <SID>BinOptionG("imd", &imd)
+endif
+call append("$", "iminsert\tin Insert mode: 1: use :lmap; 2: use IM; 0: neither")
+call append("$", "\t(local to window)")
+call <SID>OptionL("imi")
+call append("$", "imsearch\tentering a search pattern: 1: use :lmap; 2: use IM; 0: neither")
+call append("$", "\t(local to window)")
+call <SID>OptionL("ims")
+if has("xim")
+  call append("$", "imcmdline\twhen set always use IM when starting to edit a command line")
+  call <SID>BinOptionG("imc", &imc)
+endif
+
+
+if has("multi_byte")
+  call <SID>Header("multi-byte characters")
+  call append("$", "encoding\tcharacter encoding used in Vim: \"latin1\", \"utf-8\"")
+  call append("$", "\t\"euc-jp\", \"big5\", etc.")
+  call <SID>OptionG("enc", &enc)
+  call append("$", "fileencoding\tcharacter encoding for the current file")
+  call append("$", "\t(local to buffer)")
+  call <SID>OptionL("fenc")
+  call append("$", "fileencodings\tautomatically detected character encodings")
+  call <SID>OptionG("fencs", &fencs)
+  call append("$", "termencoding\tcharacter encoding used by the terminal")
+  call <SID>OptionG("tenc", &tenc)
+  call append("$", "charconvert\texpression used for character encoding conversion")
+  call <SID>OptionG("ccv", &ccv)
+  call append("$", "delcombine\tDelete combining (composing) characters on their own")
+  call <SID>BinOptionG("deco", &deco)
+  call append("$", "maxcombine\tMaximum number of combining (composing) characters displayed")
+  call <SID>OptionG("mco", &mco)
+  if has("xim") && has("gui_gtk")
+    call append("$", "imactivatekey\tkey that activates the X input method")
+    call <SID>OptionG("imak", &imak)
+  endif
+  call append("$", "ambiwidth\tWidth of ambiguous width characters")
+  call <SID>OptionG("ambw", &ambw)
+endif
+
+
+call <SID>Header("various")
+if has("virtualedit")
+  call append("$", "virtualedit\twhen to use virtual editing: \"block\", \"insert\" and/or \"all\"")
+  call <SID>OptionG("ve", &ve)
+endif
+if has("autocmd")
+  call append("$", "eventignore\tlist of autocommand events which are to be ignored")
+  call <SID>OptionG("ei", &ei)
+endif
+call append("$", "loadplugins\tload plugin scripts when starting up")
+call <SID>BinOptionG("lpl", &lpl)
+call append("$", "exrc\tenable reading .vimrc/.exrc/.gvimrc in the current directory")
+call <SID>BinOptionG("ex", &ex)
+call append("$", "secure\tsafer working with script files in the current directory")
+call <SID>BinOptionG("secure", &secure)
+call append("$", "gdefault\tuse the 'g' flag for \":substitute\"")
+call <SID>BinOptionG("gd", &gd)
+call append("$", "edcompatible\t'g' and 'c' flags of \":substitute\" toggle")
+call <SID>BinOptionG("ed", &ed)
+if exists("+opendevice")
+  call append("$", "opendevice\tallow reading/writing devices")
+  call <SID>BinOptionG("odev", &odev)
+endif
+if exists("+maxfuncdepth")
+  call append("$", "maxfuncdepth\tmaximum depth of function calls")
+  call append("$", " \tset mfd=" . &mfd)
+endif
+if has("mksession")
+  call append("$", "sessionoptions\tlist of words that specifies what to put in a session file")
+  call <SID>OptionG("ssop", &ssop)
+  call append("$", "viewoptions\tlist of words that specifies what to save for :mkview")
+  call <SID>OptionG("vop", &vop)
+  call append("$", "viewdir\tdirectory where to store files with :mkview")
+  call <SID>OptionG("vdir", &vdir)
+endif
+if has("viminfo")
+  call append("$", "viminfo\tlist that specifies what to write in the viminfo file")
+  call <SID>OptionG("vi", &vi)
+endif
+if has("quickfix")
+  call append("$", "bufhidden\twhat happens with a buffer when it's no longer in a window")
+  call append("$", "\t(local to buffer)")
+  call <SID>OptionL("bh")
+  call append("$", "buftype\t\"\", \"nofile\", \"nowrite\" or \"quickfix\": type of buffer")
+  call append("$", "\t(local to buffer)")
+  call <SID>OptionL("bt")
+endif
+call append("$", "buflisted\twhether the buffer shows up in the buffer list")
+call append("$", "\t(local to buffer)")
+call <SID>BinOptionL("bl")
+call append("$", "debug\tset to \"msg\" to see all error messages")
+call append("$", " \tset debug=" . &debug)
+if has("mzscheme")
+  call append("$", "mzquantum\tinterval in milliseconds between polls for MzScheme threads")
+  call append("$", " \tset mzq=" . &mzq)
+endif
+
+set cpo&vim
+
+" go to first line
+1
+
+" reset 'modified', so that ":q" can be used to close the window
+setlocal nomodified
+
+if has("syntax")
+  " Use Vim highlighting, with some additional stuff
+  setlocal ft=vim
+  syn match optwinHeader "^ \=[0-9].*"
+  syn match optwinName "^[a-z]*\t" nextgroup=optwinComment
+  syn match optwinComment ".*" contained
+  syn match optwinComment "^\t.*"
+  if !exists("did_optwin_syntax_inits")
+    let did_optwin_syntax_inits = 1
+    hi link optwinHeader Title
+    hi link optwinName Identifier
+    hi link optwinComment Comment
+  endif
+endif
+
+" Install autocommands to enable mappings in option-window
+noremap <silent> <buffer> <CR> <C-\><C-N>:call <SID>CR()<CR>
+inoremap <silent> <buffer> <CR> <Esc>:call <SID>CR()<CR>
+noremap <silent> <buffer> <Space> :call <SID>Space()<CR>
+
+" Make the buffer be deleted when the window is closed.
+setlocal buftype=nofile bufhidden=delete noswapfile
+
+augroup optwin
+  au! BufUnload,BufHidden option-window nested
+	\ call <SID>unload() | delfun <SID>unload
+augroup END
+
+fun! <SID>unload()
+  delfun <SID>CR
+  delfun <SID>Space
+  delfun <SID>Find
+  delfun <SID>Update
+  delfun <SID>OptionL
+  delfun <SID>OptionG
+  delfun <SID>BinOptionL
+  delfun <SID>BinOptionG
+  delfun <SID>Header
+  au! optwin
+endfun
+
+" Restore the previous value of 'title' and 'icon'.
+let &title = s:old_title
+let &icon = s:old_icon
+let &ru = s:old_ru
+let &sc = s:old_sc
+let &cpo = s:cpo_save
+unlet s:old_title s:old_icon s:old_ru s:old_sc s:cpo_save s:idx s:lnum
--- /dev/null
+++ b/lib/vimfiles/plugin/README.txt
@@ -1,0 +1,19 @@
+The plugin directory is for standard Vim plugin scripts.
+
+All files here ending in .vim will be sourced by Vim when it starts up.
+Look in the file for hints on how it can be disabled without deleting it.
+
+getscriptPlugin.vim  get latest version of Vim scripts
+gzip.vim	     edit compressed files
+matchparen.vim	     highlight paren matching the one under the cursor
+netrwPlugin.vim	     edit files over a network and browse (remote) directories
+rrhelper.vim	     used for --remote-wait editing
+spellfile.vim	     download a spellfile when it's missing
+tarPlugin.vim	     edit (compressed) tar files
+tohtml.vim	     convert a file with syntax highlighting to HTML
+vimballPlugin.vim    create and unpack .vba files
+zipPlugin.vim	     edit zip archives
+
+Note: the explorer.vim plugin is no longer here, the netrw.vim plugin has
+taken over browsing directories (also for remote directories).
+
--- /dev/null
+++ b/lib/vimfiles/plugin/getscriptPlugin.vim
@@ -1,0 +1,38 @@
+" ---------------------------------------------------------------------
+" getscriptPlugin.vim
+"  Author:	Charles E. Campbell, Jr.
+"  Date:	Jul 18, 2006
+"  Installing:	:help glvs-install
+"  Usage:	:help glvs
+"
+" GetLatestVimScripts: 642 1 :AutoInstall: getscript.vim
+"
+" (Rom 15:11 WEB) Again, "Praise the Lord, all you Gentiles!  Let
+" all the peoples praise Him."
+" ---------------------------------------------------------------------
+" Initialization:	{{{1
+" if you're sourcing this file, surely you can't be
+" expecting vim to be in its vi-compatible mode
+if &cp || exists("g:loaded_getscriptPlugin")
+ if &verbose
+  echo "GetLatestVimScripts is not vi-compatible; not loaded (you need to set nocp)"
+ endif
+ finish
+endif
+let g:loaded_getscriptPlugin = 1
+let s:keepfo                 = &fo
+let s:keepcpo                = &cpo
+set cpo&vim
+
+" ---------------------------------------------------------------------
+"  Public Interface: {{{1
+com!        -nargs=0 GetLatestVimScripts call getscript#GetLatestVimScripts()
+com!        -nargs=0 GetScripts          call getscript#GetLatestVimScripts()
+silent! com -nargs=0 GLVS                call getscript#GetLatestVimScripts()
+
+" Restore Options: {{{1
+let &fo = s:keepfo
+let &cpo= s:keepcpo
+
+" ---------------------------------------------------------------------
+" vim: ts=8 sts=2 fdm=marker nowrap
--- /dev/null
+++ b/lib/vimfiles/plugin/gzip.vim
@@ -1,0 +1,36 @@
+" Vim plugin for editing compressed files.
+" Maintainer: Bram Moolenaar <Bram@vim.org>
+" Last Change: 2005 Jul 26
+
+" Exit quickly when:
+" - this plugin was already loaded
+" - when 'compatible' is set
+" - some autocommands are already taking care of compressed files
+if exists("loaded_gzip") || &cp || exists("#BufReadPre#*.gz")
+  finish
+endif
+let loaded_gzip = 1
+
+augroup gzip
+  " Remove all gzip autocommands
+  au!
+
+  " Enable editing of gzipped files.
+  " The functions are defined in autoload/gzip.vim.
+  "
+  " Set binary mode before reading the file.
+  " Use "gzip -d", gunzip isn't always available.
+  autocmd BufReadPre,FileReadPre	*.gz,*.bz2,*.Z setlocal bin
+  autocmd BufReadPost,FileReadPost	*.gz  call gzip#read("gzip -dn")
+  autocmd BufReadPost,FileReadPost	*.bz2 call gzip#read("bzip2 -d")
+  autocmd BufReadPost,FileReadPost	*.Z   call gzip#read("uncompress")
+  autocmd BufWritePost,FileWritePost	*.gz  call gzip#write("gzip")
+  autocmd BufWritePost,FileWritePost	*.bz2 call gzip#write("bzip2")
+  autocmd BufWritePost,FileWritePost	*.Z   call gzip#write("compress -f")
+  autocmd FileAppendPre			*.gz  call gzip#appre("gzip -dn")
+  autocmd FileAppendPre			*.bz2 call gzip#appre("bzip2 -d")
+  autocmd FileAppendPre			*.Z   call gzip#appre("uncompress")
+  autocmd FileAppendPost		*.gz  call gzip#write("gzip")
+  autocmd FileAppendPost		*.bz2 call gzip#write("bzip2")
+  autocmd FileAppendPost		*.Z   call gzip#write("compress -f")
+augroup END
--- /dev/null
+++ b/lib/vimfiles/plugin/matchparen.vim
@@ -1,0 +1,120 @@
+" Vim plugin for showing matching parens
+" Maintainer:  Bram Moolenaar <Bram@vim.org>
+" Last Change: 2006 Oct 12
+
+" Exit quickly when:
+" - this plugin was already loaded (or disabled)
+" - when 'compatible' is set
+" - the "CursorMoved" autocmd event is not availble.
+if exists("g:loaded_matchparen") || &cp || !exists("##CursorMoved")
+  finish
+endif
+let g:loaded_matchparen = 1
+
+augroup matchparen
+  " Replace all matchparen autocommands
+  autocmd! CursorMoved,CursorMovedI * call s:Highlight_Matching_Pair()
+augroup END
+
+" Skip the rest if it was already done.
+if exists("*s:Highlight_Matching_Pair")
+  finish
+endif
+
+let cpo_save = &cpo
+set cpo-=C
+
+" The function that is invoked (very often) to define a ":match" highlighting
+" for any matching paren.
+function! s:Highlight_Matching_Pair()
+  " Remove any previous match.
+  if exists('w:paren_hl_on') && w:paren_hl_on
+    3match none
+    let w:paren_hl_on = 0
+  endif
+
+  " Avoid that we remove the popup menu.
+  if pumvisible()
+    return
+  endif
+
+  " Get the character under the cursor and check if it's in 'matchpairs'.
+  let c_lnum = line('.')
+  let c_col = col('.')
+  let before = 0
+
+  let c = getline(c_lnum)[c_col - 1]
+  let plist = split(&matchpairs, '.\zs[:,]')
+  let i = index(plist, c)
+  if i < 0
+    " not found, in Insert mode try character before the cursor
+    if c_col > 1 && (mode() == 'i' || mode() == 'R')
+      let before = 1
+      let c = getline(c_lnum)[c_col - 2]
+      let i = index(plist, c)
+    endif
+    if i < 0
+      " not found, nothing to do
+      return
+    endif
+  endif
+
+  " Figure out the arguments for searchpairpos().
+  " Restrict the search to visible lines with "stopline".
+  " And avoid searching very far (e.g., for closed folds and long lines)
+  if i % 2 == 0
+    let s_flags = 'nW'
+    let c2 = plist[i + 1]
+    if has("byte_offset") && has("syntax_items") && &smc > 0
+      let stopbyte = min([line2byte("$"), line2byte(".") + col(".") + &smc * 2])
+      let stopline = min([line('w$'), byte2line(stopbyte)])
+    else
+      let stopline = min([line('w$'), c_lnum + 100])
+    endif
+  else
+    let s_flags = 'nbW'
+    let c2 = c
+    let c = plist[i - 1]
+    if has("byte_offset") && has("syntax_items") && &smc > 0
+      let stopbyte = max([1, line2byte(".") + col(".") - &smc * 2])
+      let stopline = max([line('w0'), byte2line(stopbyte)])
+    else
+      let stopline = max([line('w0'), c_lnum - 100])
+    endif
+  endif
+  if c == '['
+    let c = '\['
+    let c2 = '\]'
+  endif
+
+  " Find the match.  When it was just before the cursor move it there for a
+  " moment.
+  if before > 0
+    let save_cursor = winsaveview()
+    call cursor(c_lnum, c_col - before)
+  endif
+
+  " When not in a string or comment ignore matches inside them.
+  let s_skip ='synIDattr(synID(line("."), col("."), 0), "name") ' .
+	\ '=~?  "string\\|character\\|singlequote\\|comment"'
+  execute 'if' s_skip '| let s_skip = 0 | endif'
+
+  let [m_lnum, m_col] = searchpairpos(c, '', c2, s_flags, s_skip, stopline)
+
+  if before > 0
+    call winrestview(save_cursor)
+  endif
+
+  " If a match is found setup match highlighting.
+  if m_lnum > 0 && m_lnum >= line('w0') && m_lnum <= line('w$')
+    exe '3match MatchParen /\(\%' . c_lnum . 'l\%' . (c_col - before) .
+	  \ 'c\)\|\(\%' . m_lnum . 'l\%' . m_col . 'c\)/'
+    let w:paren_hl_on = 1
+  endif
+endfunction
+
+" Define commands that will disable and enable the plugin.
+command! NoMatchParen 3match none | unlet! g:loaded_matchparen | au! matchparen
+command! DoMatchParen runtime plugin/matchparen.vim | doau CursorMoved
+
+let &cpo = cpo_save
--- /dev/null
+++ b/lib/vimfiles/plugin/netrwPlugin.vim
@@ -1,0 +1,180 @@
+" netrwPlugin.vim: Handles file transfer and remote directory listing across a network
+"            PLUGIN SECTION
+" Date:		Jan 05, 2007
+" Maintainer:	Charles E Campbell, Jr <NdrOchip@ScampbellPfamily.AbizM-NOSPAM>
+" GetLatestVimScripts: 1075 1 :AutoInstall: netrw.vim
+" Copyright:    Copyright (C) 1999-2005 Charles E. Campbell, Jr. {{{1
+"               Permission is hereby granted to use and distribute this code,
+"               with or without modifications, provided that this copyright
+"               notice is copied with it. Like anything else that's free,
+"               netrw.vim, netrwPlugin.vim, and netrwSettings.vim are provided
+"               *as is* and comes with no warranty of any kind, either
+"               expressed or implied. By using this plugin, you agree that
+"               in no event will the copyright holder be liable for any damages
+"               resulting from the use of this software.
+"
+"  But be doers of the Word, and not only hearers, deluding your own selves {{{1
+"  (James 1:22 RSV)
+" =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
+
+" ---------------------------------------------------------------------
+" Load Once: {{{1
+if &cp || exists("g:loaded_netrwPlugin")
+ finish
+endif
+let g:loaded_netrwPlugin = 1
+let s:keepcpo            = &cpo
+if v:version < 700
+ echohl WarningMsg | echo "***netrw*** you need vim version 7.0 for this version of netrw" | echohl None
+ finish
+endif
+let s:keepcpo= &cpo
+set cpo&vim
+
+" ---------------------------------------------------------------------
+" Public Interface: {{{1
+
+" Local Browsing: {{{2
+augroup FileExplorer
+ au!
+ au BufEnter * silent! call s:LocalBrowse(expand("<amatch>"))
+ if has("win32") || has("win95") || has("win64") || has("win16")
+  au BufEnter .* silent! call s:LocalBrowse(expand("<amatch>"))
+ endif
+augroup END
+
+" Network Browsing Reading Writing: {{{2
+augroup Network
+ au!
+ if has("win32") || has("win95") || has("win64") || has("win16")
+  au BufReadCmd  file://*		exe "silent doau BufReadPre ".netrw#RFC2396(expand("<amatch>"))|exe 'e '.substitute(netrw#RFC2396(expand("<amatch>")),'file://\(.*\)','\1',"")|exe "silent doau BufReadPost ".netrw#RFC2396(expand("<amatch>"))
+ else
+  au BufReadCmd  file://*		exe "silent doau BufReadPre ".netrw#RFC2396(expand("<amatch>"))|exe 'e '.substitute(netrw#RFC2396(expand("<amatch>")),'file://\(.*\)','\1',"")|exe "silent doau BufReadPost ".netrw#RFC2396(expand("<amatch>"))
+  au BufReadCmd  file://localhost/*	exe "silent doau BufReadPre ".netrw#RFC2396(expand("<amatch>"))|exe 'e '.substitute(netrw#RFC2396(expand("<amatch>")),'file://localhost/\(.*\)','\1',"")|exe "silent doau BufReadPost ".netrw#RFC2396(expand("<amatch>"))
+ endif
+ au BufReadCmd   ftp://*,rcp://*,scp://*,http://*,dav://*,rsync://*,sftp://*	exe "silent doau BufReadPre ".expand("<amatch>")|exe '2Nread "'.expand("<amatch>").'"'|exe "silent doau BufReadPost ".expand("<amatch>")
+ au FileReadCmd  ftp://*,rcp://*,scp://*,http://*,dav://*,rsync://*,sftp://*	exe "silent doau FileReadPre ".expand("<amatch>")|exe 'Nread "'   .expand("<amatch>").'"'|exe "silent doau FileReadPost ".expand("<amatch>")
+ au BufWriteCmd  ftp://*,rcp://*,scp://*,dav://*,rsync://*,sftp://*		exe "silent doau BufWritePre ".expand("<amatch>")|exe 'Nwrite "' .expand("<amatch>").'"'|exe "silent doau BufWritePost ".expand("<amatch>")
+ au FileWriteCmd ftp://*,rcp://*,scp://*,dav://*,rsync://*,sftp://*		exe "silent doau FileWritePre ".expand("<amatch>")|exe "'[,']".'Nwrite "' .expand("<amatch>").'"'|exe "silent doau FileWritePost ".expand("<amatch>")
+ try
+  au SourceCmd    ftp://*,rcp://*,scp://*,http://*,dav://*,rsync://*,sftp://*	exe 'Nsource "'.expand("<amatch>").'"'
+ catch /^Vim\%((\a\+)\)\=:E216/
+  au SourcePre    ftp://*,rcp://*,scp://*,http://*,dav://*,rsync://*,sftp://*	exe 'Nsource "'.expand("<amatch>").'"'
+ endtry
+augroup END
+
+" Commands: :Nread, :Nwrite, :NetUserPass {{{2
+com! -count=1 -nargs=*	Nread		call netrw#NetSavePosn()<bar>call netrw#NetRead(<count>,<f-args>)<bar>call netrw#NetRestorePosn()
+com! -range=% -nargs=*	Nwrite		call netrw#NetSavePosn()<bar><line1>,<line2>call netrw#NetWrite(<f-args>)<bar>call netrw#NetRestorePosn()
+com! -nargs=*		NetUserPass	call NetUserPass(<f-args>)
+com! -nargs=+           Ncopy           call netrw#NetObtain(<f-args>)
+com! -nargs=*	        Nsource		call netrw#NetSavePosn()<bar>call netrw#NetSource(<f-args>)<bar>call netrw#NetRestorePosn()
+
+" Commands: :Explore, :Sexplore, Hexplore, Vexplore {{{2
+com! -nargs=* -bar -bang -count=0 -complete=dir	Explore		call netrw#Explore(<count>,0,0+<bang>0,<q-args>)
+com! -nargs=* -bar -bang -count=0 -complete=dir	Sexplore	call netrw#Explore(<count>,1,0+<bang>0,<q-args>)
+com! -nargs=* -bar -bang -count=0 -complete=dir	Hexplore	call netrw#Explore(<count>,1,2+<bang>0,<q-args>)
+com! -nargs=* -bar -bang -count=0 -complete=dir	Vexplore	call netrw#Explore(<count>,1,4+<bang>0,<q-args>)
+com! -nargs=* -bar       -count=0 -complete=dir	Texplore	call netrw#Explore(<count>,0,6        ,<q-args>)
+com! -nargs=* -bar -bang			Nexplore	call netrw#Explore(-1,0,0,<q-args>)
+com! -nargs=* -bar -bang			Pexplore	call netrw#Explore(-2,0,0,<q-args>)
+
+" Commands: NetrwSettings {{{2
+com! -nargs=0 NetrwSettings :call netrwSettings#NetrwSettings()
+
+" Maps:
+if !exists("g:netrw_nogx") && maparg('g','n') == ""
+ if !hasmapto('<Plug>NetrwBrowseX')
+  nmap <unique> gx <Plug>NetrwBrowseX
+ endif
+ nno <silent> <Plug>NetrwBrowseX :call netrw#NetBrowseX(expand("<cWORD>"),0)<cr>
+endif
+
+" ---------------------------------------------------------------------
+" LocalBrowse: {{{2
+fun! s:LocalBrowse(dirname)
+  " unfortunate interaction -- debugging calls can't be used here;
+  " the BufEnter event causes triggering when attempts to write to
+  " the DBG buffer are made.
+"  echomsg "dirname<".a:dirname.">"
+  if has("amiga")
+   " The check against '' is made for the Amiga, where the empty
+   " string is the current directory and not checking would break
+   " things such as the help command.
+   if a:dirname != '' && isdirectory(a:dirname)
+    silent! call netrw#LocalBrowseCheck(a:dirname)
+   endif
+  elseif isdirectory(a:dirname)
+"   echomsg "dirname<".dirname."> isdir"
+   silent! call netrw#LocalBrowseCheck(a:dirname)
+  endif
+  " not a directory, ignore it
+endfun
+
+" ---------------------------------------------------------------------
+" NetrwStatusLine: {{{1
+fun! NetrwStatusLine()
+"  let g:stlmsg= "Xbufnr=".w:netrw_explore_bufnr." bufnr=".bufnr("%")." Xline#".w:netrw_explore_line." line#".line(".")
+  if !exists("w:netrw_explore_bufnr") || w:netrw_explore_bufnr != bufnr("%") || !exists("w:netrw_explore_line") || w:netrw_explore_line != line(".") || !exists("w:netrw_explore_list")
+   let &stl= s:netrw_explore_stl
+   if exists("w:netrw_explore_bufnr")|unlet w:netrw_explore_bufnr|endif
+   if exists("w:netrw_explore_line")|unlet w:netrw_explore_line|endif
+   return ""
+  else
+   return "Match ".w:netrw_explore_mtchcnt." of ".w:netrw_explore_listlen
+  endif
+endfun
+
+" ------------------------------------------------------------------------
+" NetUserPass: set username and password for subsequent ftp transfer {{{1
+"   Usage:  :call NetUserPass()			-- will prompt for userid and password
+"	    :call NetUserPass("uid")		-- will prompt for password
+"	    :call NetUserPass("uid","password") -- sets global userid and password
+fun! NetUserPass(...)
+
+ " get/set userid
+ if a:0 == 0
+"  call Dfunc("NetUserPass(a:0<".a:0.">)")
+  if !exists("g:netrw_uid") || g:netrw_uid == ""
+   " via prompt
+   let g:netrw_uid= input('Enter username: ')
+  endif
+ else	" from command line
+"  call Dfunc("NetUserPass(a:1<".a:1.">) {")
+  let g:netrw_uid= a:1
+ endif
+
+ " get password
+ if a:0 <= 1 " via prompt
+"  call Decho("a:0=".a:0." case <=1:")
+  let g:netrw_passwd= inputsecret("Enter Password: ")
+ else " from command line
+"  call Decho("a:0=".a:0." case >1: a:2<".a:2.">")
+  let g:netrw_passwd=a:2
+ endif
+"  call Dret("NetUserPass")
+endfun
+
+" ------------------------------------------------------------------------
+" NetReadFixup: this sort of function is typically written by the user {{{1
+"               to handle extra junk that their system's ftp dumps
+"               into the transfer.  This function is provided as an
+"               example and as a fix for a Windows 95 problem: in my
+"               experience, win95's ftp always dumped four blank lines
+"               at the end of the transfer.
+if has("win95") && exists("g:netrw_win95ftp") && g:netrw_win95ftp
+ fun! NetReadFixup(method, line1, line2)
+"   call Dfunc("NetReadFixup(method<".a:method."> line1=".a:line1." line2=".a:line2.")")
+   if method == 3   " ftp (no <.netrc>)
+    let fourblanklines= line2 - 3
+    silent fourblanklines.",".line2."g/^\s*/d"
+   endif
+"   call Dret("NetReadFixup")
+ endfun
+endif
+
+" ------------------------------------------------------------------------
+" Modelines And Restoration: {{{1
+let &cpo= s:keepcpo
+unlet s:keepcpo
+" vim:ts=8 fdm=marker
--- /dev/null
+++ b/lib/vimfiles/plugin/rrhelper.vim
@@ -1,0 +1,47 @@
+" Vim plugin with helper function(s) for --remote-wait
+" Maintainer: Flemming Madsen <fma@cci.dk>
+" Last Change: 2004 May 30
+
+" Has this already been loaded?
+if exists("loaded_rrhelper")
+  finish
+endif
+let loaded_rrhelper = 1
+
+" Setup answers for a --remote-wait client who will assume
+" a SetupRemoteReplies() function in the command server
+
+if has("clientserver")
+  function SetupRemoteReplies()
+    let cnt = 0
+    let max = argc()
+
+    let id = expand("<client>")
+    if id == 0
+      return
+    endif
+    while cnt < max
+      " Handle same file from more clients and file being more than once
+      " on the command line by encoding this stuff in the group name
+      let uniqueGroup = "RemoteReply_".id."_".cnt
+
+      " Path separators are always forward slashes for the autocommand pattern.
+      " Escape special characters with a backslash.
+      let f = escape(substitute(argv(cnt), '\\', '/', "g"), ' *,?[{')
+      execute "augroup ".uniqueGroup
+      execute "autocmd ".uniqueGroup." BufUnload ". f ."  call DoRemoteReply('".id."', '".cnt."', '".uniqueGroup."', '". f ."')"
+      let cnt = cnt + 1
+    endwhile
+    augroup END
+  endfunc
+
+  function DoRemoteReply(id, cnt, group, file)
+    call server2client(a:id, a:cnt)
+    execute 'autocmd! '.a:group.' BufUnload '.a:file
+    execute 'augroup! '.a:group
+  endfunc
+
+endif
+
+
+" vim: set sw=2 sts=2 :
--- /dev/null
+++ b/lib/vimfiles/plugin/spellfile.vim
@@ -1,0 +1,15 @@
+" Vim plugin for downloading spell files
+" Maintainer:  Bram Moolenaar <Bram@vim.org>
+" Last Change: 2006 Feb 01
+
+" Exit quickly when:
+" - this plugin was already loaded
+" - when 'compatible' is set
+" - some autocommands are already taking care of spell files
+if exists("loaded_spellfile_plugin") || &cp || exists("#SpellFileMissing")
+  finish
+endif
+let loaded_spellfile_plugin = 1
+
+" The function is in the autoload directory.
+autocmd SpellFileMissing * call spellfile#LoadFile(expand('<amatch>'))
--- /dev/null
+++ b/lib/vimfiles/plugin/tarPlugin.vim
@@ -1,0 +1,48 @@
+" tarPlugin.vim -- a Vim plugin for browsing tarfiles
+" Original was copyright (c) 2002, Michael C. Toren <mct@toren.net>
+" Modified by Charles E. Campbell, Jr.
+" Distributed under the GNU General Public License.
+"
+" Updates are available from <http://michael.toren.net/code/>.  If you
+" find this script useful, or have suggestions for improvements, please
+" let me know.
+" Also look there for further comments and documentation.
+"
+" This part only sets the autocommands.  The functions are in autoload/tar.vim.
+" ---------------------------------------------------------------------
+"  Load Once: {{{1
+if &cp || exists("g:loaded_tarPlugin")
+ finish
+endif
+let g:loaded_tarPlugin = 1
+let s:keepcpo          = &cpo
+set cpo&vim
+
+" ---------------------------------------------------------------------
+"  Public Interface: {{{1
+augroup tar
+  au!
+  au BufReadCmd   tarfile:*	call tar#Read(expand("<amatch>"), 1)
+  au FileReadCmd  tarfile:*	call tar#Read(expand("<amatch>"), 0)
+  au BufWriteCmd  tarfile:*	call tar#Write(expand("<amatch>"))
+  au FileWriteCmd tarfile:*	call tar#Write(expand("<amatch>"))
+
+  if has("unix")
+   au BufReadCmd   tarfile:*/*	call tar#Read(expand("<amatch>"), 1)
+   au FileReadCmd  tarfile:*/*	call tar#Read(expand("<amatch>"), 0)
+   au BufWriteCmd  tarfile:*/*	call tar#Write(expand("<amatch>"))
+   au FileWriteCmd tarfile:*/*	call tar#Write(expand("<amatch>"))
+  endif
+
+  au BufReadCmd   *.tar		call tar#Browse(expand("<amatch>"))
+  au BufReadCmd   *.tar.gz	call tar#Browse(expand("<amatch>"))
+  au BufReadCmd   *.tar.bz2	call tar#Browse(expand("<amatch>"))
+  au BufReadCmd   *.tar.Z	call tar#Browse(expand("<amatch>"))
+  au BufReadCmd   *.tgz		call tar#Browse(expand("<amatch>"))
+augroup END
+
+" ---------------------------------------------------------------------
+" Restoration And Modelines: {{{1
+" vim: fdm=marker
+let &cpo= s:keepcpo
+unlet s:keepcpo
--- /dev/null
+++ b/lib/vimfiles/plugin/tohtml.vim
@@ -1,0 +1,27 @@
+" Vim plugin for converting a syntax highlighted file to HTML.
+" Maintainer: Bram Moolenaar <Bram@vim.org>
+" Last Change: 2003 Apr 06
+
+" Don't do this when:
+" - when 'compatible' is set
+" - this plugin was already loaded
+" - user commands are not available.
+if !&cp && !exists(":TOhtml") && has("user_commands")
+  command -range=% TOhtml :call Convert2HTML(<line1>, <line2>)
+
+  func Convert2HTML(line1, line2)
+    if a:line2 >= a:line1
+      let g:html_start_line = a:line1
+      let g:html_end_line = a:line2
+    else
+      let g:html_start_line = a:line2
+      let g:html_end_line = a:line1
+    endif
+
+    runtime syntax/2html.vim
+
+    unlet g:html_start_line
+    unlet g:html_end_line
+  endfunc
+
+endif
--- /dev/null
+++ b/lib/vimfiles/plugin/vimballPlugin.vim
@@ -1,0 +1,36 @@
+" vimballPlugin : construct a file containing both paths and files
+" Author: Charles E. Campbell, Jr.
+" Copyright: (c) 2004-2006 by Charles E. Campbell, Jr.
+"            The VIM LICENSE applies to Vimball.vim, and Vimball.txt
+"            (see |copyright|) except use "Vimball" instead of "Vim".
+"            No warranty, express or implied.
+"  *** ***   Use At-Your-Own-Risk!   *** ***
+"
+" (Rom 2:1 WEB) Therefore you are without excuse, O man, whoever you are who
+"      judge. For in that which you judge another, you condemn yourself. For
+"      you who judge practice the same things.
+" GetLatestVimScripts: 1502 1 :AutoInstall: vimball.vim
+
+" ---------------------------------------------------------------------
+"  Load Once: {{{1
+if &cp || exists("g:loaded_vimballPlugin")
+ finish
+endif
+let g:loaded_vimballPlugin = 1
+let s:keepcpo              = &cpo
+set cpo&vim
+
+" ------------------------------------------------------------------------------
+" Public Interface: {{{1
+com! -ra   -complete=dir -na=+ -bang MkVimball call vimball#MkVimball(<line1>,<line2>,<bang>0,<f-args>)
+com! -na=? -complete=dir UseVimball  call vimball#Vimball(1,<f-args>)
+com! -na=0               VimballList call vimball#Vimball(0)
+com! -na=* -complete=dir RmVimball   call vimball#RmVimball(<f-args>)
+au BufEnter  *.vba.gz,*.vba.bz2,*.vba.zip call vimball#Decompress(expand("<amatch>"))
+au BufEnter  *.vba setlocal noma bt=nofile fmr=[[[,]]] fdm=marker|call vimball#ShowMesg(0,"Source this file to extract it! (:so %)")
+
+" =====================================================================
+" Restoration And Modelines: {{{1
+" vim: fdm=marker
+let &cpo= s:keepcpo
+unlet s:keepcpo
--- /dev/null
+++ b/lib/vimfiles/plugin/zipPlugin.vim
@@ -1,0 +1,50 @@
+" zipPlugin.vim: Handles browsing zipfiles
+"            PLUGIN PORTION
+" Date:			Jul 18, 2006
+" Maintainer:	Charles E Campbell, Jr <NdrOchip@ScampbellPfamily.AbizM-NOSPAM>
+" License:		Vim License  (see vim's :help license)
+" Copyright:    Copyright (C) 2005,2006 Charles E. Campbell, Jr. {{{1
+"               Permission is hereby granted to use and distribute this code,
+"               with or without modifications, provided that this copyright
+"               notice is copied with it. Like anything else that's free,
+"               zipPlugin.vim is provided *as is* and comes with no warranty
+"               of any kind, either expressed or implied. By using this
+"               plugin, you agree that in no event will the copyright
+"               holder be liable for any damages resulting from the use
+"               of this software.
+"
+" (James 4:8 WEB) Draw near to God, and he will draw near to you.
+" Cleanse your hands, you sinners; and purify your hearts, you double-minded.
+" ---------------------------------------------------------------------
+" Load Once: {{{1
+if &cp || exists("g:loaded_zipPlugin")
+ finish
+endif
+let g:loaded_zipPlugin = 1
+let s:keepcpo          = &cpo
+set cpo&vim
+
+" ---------------------------------------------------------------------
+" Public Interface: {{{1
+augroup zip
+ au!
+ au BufReadCmd   zipfile:*	call zip#Read(expand("<amatch>"), 1)
+ au FileReadCmd  zipfile:*	call zip#Read(expand("<amatch>"), 0)
+ au BufWriteCmd  zipfile:*	call zip#Write(expand("<amatch>"))
+ au FileWriteCmd zipfile:*	call zip#Write(expand("<amatch>"))
+
+ if has("unix")
+  au BufReadCmd   zipfile:*/*	call zip#Read(expand("<amatch>"), 1)
+  au FileReadCmd  zipfile:*/*	call zip#Read(expand("<amatch>"), 0)
+  au BufWriteCmd  zipfile:*/*	call zip#Write(expand("<amatch>"))
+  au FileWriteCmd zipfile:*/*	call zip#Write(expand("<amatch>"))
+ endif
+
+ au BufReadCmd   *.zip		call zip#Browse(expand("<amatch>"))
+augroup END
+
+" ---------------------------------------------------------------------
+"  Restoration And Modelines: {{{1
+"  vim: fdm=marker
+let &cpo= s:keepcpo
+unlet s:keepcpo
--- /dev/null
+++ b/lib/vimfiles/print/ascii.ps
@@ -1,0 +1,22 @@
+%!PS-Adobe-3.0 Resource-Encoding
+%%Title: VIM-ascii
+%%Version: 1.0 0
+%%EndComments
+/VIM-ascii[
+32{/.notdef}repeat
+/space /exclam /quotedbl /numbersign /dollar /percent /ampersand /quotesingle
+/parenleft /parenright /asterisk /plus /comma /minus /period /slash
+/zero /one /two /three /four /five /six /seven
+/eight /nine /colon /semicolon /less /equal /greater /question
+/at /A /B /C /D /E /F /G
+/H /I /J /K /L /M /N /O
+/P /Q /R /S /T /U /V /W
+/X /Y /Z /bracketleft /backslash /bracketright /asciicircum /underscore
+/grave /a /b /c /d /e /f /g
+/h /i /j /k /l /m /n /o
+/p /q /r /s /t /u /v /w
+/x /y /z /braceleft /bar /braceright /asciitilde /.notdef
+128{/.notdef}repeat]
+/Encoding defineresource pop
+% vim:ff=unix:
+%%EOF
--- /dev/null
+++ b/lib/vimfiles/print/cidfont.ps
@@ -1,0 +1,26 @@
+%!PS-Adobe-3.0 Resource-ProcSet
+%%Title: VIM-CIDFont
+%%Version: 1.0 0
+%%EndComments
+% Editing of this file is NOT RECOMMENDED.  You run a very good risk of causing
+% all PostScript printing from VIM failing if you do.  PostScript is not called
+% a write-only language for nothing!
+/CP currentpacking d T setpacking
+/SB 256 string d
+/CIDN? systemdict/composefont known d /GS? systemdict/.makeoperator known d
+CIDN?{
+GS?{/vim_findresource{2 copy resourcestatus not{1 index SB cvs runlibfile}{
+pop pop}ifelse findresource}bd/vim_composefont{0 get/CIDFont vim_findresource
+exch/CMap vim_findresource exch[exch]composefont pop}bd}{/vim_findresource
+/findresource ld/vim_composefont{composefont pop}bd}ifelse
+}{
+/vim_fontname{0 get SB cvs length dup SB exch(-)putinterval 1 add dup SB exch
+dup 256 exch sub getinterval 3 -1 roll exch cvs length add SB exch 0 exch
+getinterval cvn}bd/vim_composefont{vim_fontname findfont d}bd
+} ifelse
+/cfs{exch scalefont d}bd
+/sffs{findfont 3 1 roll 1 index mul exch 2 index/FontMatrix get matrix copy
+scale makefont d}bd
+CP setpacking
+% vim:ff=unix:
+%%EOF
--- /dev/null
+++ b/lib/vimfiles/print/cns_roman.ps
@@ -1,0 +1,23 @@
+%!PS-Adobe-3.0 Resource-Encoding
+%%Title: VIM-cns_roman
+%%Version: 1.0 0
+%%EndComments
+% Different to ASCII at code point 126
+/VIM-cns_roman[
+32{/.notdef}repeat
+/space /exclam /quotedbl /numbersign /dollar /percent /ampersand /quotesingle
+/parenleft /parenright /asterisk /plus /comma /minus /period /slash
+/zero /one /two /three /four /five /six /seven
+/eight /nine /colon /semicolon /less /equal /greater /question
+/at /A /B /C /D /E /F /G
+/H /I /J /K /L /M /N /O
+/P /Q /R /S /T /U /V /W
+/X /Y /Z /bracketleft /backslash /bracketright /asciicircum /underscore
+/grave /a /b /c /d /e /f /g
+/h /i /j /k /l /m /n /o
+/p /q /r /s /t /u /v /w
+/x /y /z /braceleft /bar /braceright /overline /.notdef
+128{/.notdef}repeat]
+/Encoding defineresource pop
+% vim:ff=unix:
+%%EOF
--- /dev/null
+++ b/lib/vimfiles/print/cp1250.ps
@@ -1,0 +1,40 @@
+%!PS-Adobe-3.0 Resource-Encoding
+%%Title: VIM-cp1250
+%%Version: 1.0 0
+%%EndComments
+/VIM-cp1250[
+/.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef
+/space /exclam /quotedbl /numbersign /dollar /percent /ampersand /quotesingle
+/parenleft /parenright /asterisk /plus /comma /minus /period /slash
+/zero /one /two /three /four /five /six /seven
+/eight /nine /colon /semicolon /less /equal /greater /question
+/at /A /B /C /D /E /F /G
+/H /I /J /K /L /M /N /O
+/P /Q /R /S /T /U /V /W
+/X /Y /Z /bracketleft /backslash /bracketright /asciicircum /underscore
+/grave /a /b /c /d /e /f /g
+/h /i /j /k /l /m /n /o
+/p /q /r /s /t /u /v /w
+/x /y /z /braceleft /bar /braceright /tilde /.notdef
+/Euro /.notdef /quotesinglbase /.notdef /quotedblbase /ellipsis /dagger /daggerdbl
+/.notdef /perthousand /Scaron /guilsinglleft /Sacute /Tcaron /Zcaron /Zacute
+/.notdef /quoteleft /quoteright /quotedblleft /quotedblright /bullet /endash /emdash
+/.notdef /trademark /scaron /guilsinglright /sacute /tcaron /zcaron /zacute
+/space /caron /breve /Lslash /currency /Aogonek /brokenbar /section
+/dieresis /copyright /Scedilla /guillemotleft /logicalnot /hyphen /registered /Zdotaccent
+/degree /plusminus /ogonek /lslash /acute /mu /paragraph /periodcentered
+/cedilla /aogonek /scedilla /guillemotright /Lcaron /hungarumlaut /lcaron /zdotaccent
+/Racute /Aacute /Acircumflex /Abreve /Adieresis /Lacute /Cacute /Ccedilla
+/Ccaron /Eacute /Eogonek /Edieresis /Ecaron /Iacute /Icircumflex /Dcaron
+/Dcroat /Nacute /Ncaron /Oacute /Ocircumflex /Ohungarumlaut /Odieresis /multiply
+/Rcaron /Uring /Uacute /Uhungarumlaut /Udieresis /Yacute /Tcedilla /germandbls
+/racute /aacute /acircumflex /abreve /adieresis /lacute /cacute /ccedilla
+/ccaron /eacute /eogonek /edieresis /ecaron /iacute /icircumflex /dcaron
+/dcroat /nacute /ncaron /oacute /ocircumflex /ohungarumlaut /odieresis /divide
+/rcaron /uring /uacute /uhungarumlaut /udieresis /yacute /tcedilla /dotaccent]
+/Encoding defineresource pop
+% vim:ff=unix:
+%%EOF
--- /dev/null
+++ b/lib/vimfiles/print/cp1251.ps
@@ -1,0 +1,40 @@
+%!PS-Adobe-3.0 Resource-Encoding
+%%Title: VIM-cp1251
+%%Version: 1.0 0
+%%EndComments
+/VIM-cp1251[
+/.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef
+/space /exclam /quotedbl /numbersign /dollar /percent /ampersand /quotesingle
+/parenleft /parenright /asterisk /plus /comma /minus /period /slash
+/zero /one /two /three /four /five /six /seven
+/eight /nine /colon /semicolon /less /equal /greater /question
+/at /A /B /C /D /E /F /G
+/H /I /J /K /L /M /N /O
+/P /Q /R /S /T /U /V /W
+/X /Y /Z /bracketleft /backslash /bracketright /asciicircum /underscore
+/grave /a /b /c /d /e /f /g
+/h /i /j /k /l /m /n /o
+/p /q /r /s /t /u /v /w
+/x /y /z /braceleft /bar /braceright /asciitilde /.notdef
+/afii10051 /afii10052 /quotesinglbase /afii10100 /quotedblbase /ellipsis /dagger /daggerdbl
+/Euro /perthousand /afii10058 /guilsinglleft /afii10059 /afii10061 /afii10060 /afii10145
+/afii10099 /quoteleft /quoteright /quotedblleft /quotedblright /bullet /endash /emdash
+/.notdef /trademark /afii10106 /guilsinglright /afii10107 /afii10109 /afii10108 /afii10193
+/space /afii10062 /afii10110 /afii10057 /currency /afii10050 /brokenbar /section
+/afii10023 /copyright /afii10053 /guillemotleft /logicalnot /hyphen /registered /afii10056
+/degree /plusminus /afii10055 /afii10103 /afii10098 /mu /paragraph /periodcentered
+/afii10071 /afii61352 /afii10101 /guillemotright /afii10105 /afii10054 /afii10102 /afii10104
+/afii10017 /afii10018 /afii10019 /afii10020 /afii10021 /afii10022 /afii10024 /afii10025
+/afii10026 /afii10027 /afii10028 /afii10029 /afii10030 /afii10031 /afii10032 /afii10033
+/afii10034 /afii10035 /afii10036 /afii10037 /afii10038 /afii10039 /afii10040 /afii10041
+/afii10042 /afii10043 /afii10044 /afii10045 /afii10046 /afii10047 /afii10048 /afii10049
+/afii10065 /afii10066 /afii10067 /afii10068 /afii10069 /afii10070 /afii10072 /afii10073
+/afii10074 /afii10075 /afii10076 /afii10077 /afii10078 /afii10079 /afii10080 /afii10081
+/afii10082 /afii10083 /afii10084 /afii10085 /afii10086 /afii10087 /afii10088 /afii10089
+/afii10090 /afii10091 /afii10092 /afii10093 /afii10094 /afii10095 /afii10096 /afii10097]
+/Encoding defineresource pop
+% vim:ff=unix:
+%%EOF
--- /dev/null
+++ b/lib/vimfiles/print/cp1252.ps
@@ -1,0 +1,40 @@
+%!PS-Adobe-3.0 Resource-Encoding
+%%Title: VIM-cp1252
+%%Version: 1.0 0
+%%EndComments
+/VIM-cp1252[
+/.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef
+/space /exclam /quotedbl /numbersign /dollar /percent /ampersand /quotesingle
+/parenleft /parenright /asterisk /plus /comma /minus /period /slash
+/zero /one /two /three /four /five /six /seven
+/eight /nine /colon /semicolon /less /equal /greater /question
+/at /A /B /C /D /E /F /G
+/H /I /J /K /L /M /N /O
+/P /Q /R /S /T /U /V /W
+/X /Y /Z /bracketleft /backslash /bracketright /asciicircum /underscore
+/grave /a /b /c /d /e /f /g
+/h /i /j /k /l /m /n /o
+/p /q /r /s /t /u /v /w
+/x /y /z /braceleft /bar /braceright /asciitilde /.notdef
+/Euro /.notdef /quotesinglbase /florin /quotedblbase /ellipsis /dagger /daggerdbl
+/circumflex /perthousand /Scaron /guilsinglleft /OE /.notdef /Zcaron /.notdef
+/.notdef /quoteleft /quoteright /quotedblleft /quotedblright /bullet /endash /emdash
+/tilde /trademark /scaron /guilsinglright /oe /.notdef /zcaron /Ydieresis
+/space /exclamdown /cent /sterling /currency /yen /brokenbar /section
+/dieresis /copyright /ordfeminine /guillemotleft /logicalnot /hyphen /registered /macron
+/degree /plusminus /twosuperior /threesuperior /acute /mu /paragraph /periodcentered
+/cedilla /onesuperior /ordmasculine /guillemotright /onequarter /onehalf /threequarters /questiondown
+/Agrave /Aacute /Acircumflex /Atilde /Adieresis /Aring /AE /Ccedilla
+/Egrave /Eacute /Ecircumflex /Edieresis /Igrave /Iacute /Icircumflex /Idieresis
+/Eth /Ntilde /Ograve /Oacute /Ocircumflex /Otilde /Odieresis /multiply
+/Oslash /Ugrave /Uacute /Ucircumflex /Udieresis /Yacute /Thorn /germandbls
+/agrave /aacute /acircumflex /atilde /adieresis /aring /ae /ccedilla
+/egrave /eacute /ecircumflex /edieresis /igrave /iacute /icircumflex /idieresis
+/eth /ntilde /ograve /oacute /ocircumflex /otilde /odieresis /divide
+/oslash /ugrave /uacute /ucircumflex /udieresis /yacute /thorn /ydieresis]
+/Encoding defineresource pop
+% vim:ff=unix:
+%%EOF
--- /dev/null
+++ b/lib/vimfiles/print/cp1253.ps
@@ -1,0 +1,40 @@
+%!PS-Adobe-3.0 Resource-Encoding
+%%Title: VIM-cp1253
+%%Version: 1.0 0
+%%EndComments
+/VIM-cp1253[
+/.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef
+/space /exclam /quotedbl /numbersign /dollar /percent /ampersand /quotesingle
+/parenleft /parenright /asterisk /plus /comma /minus /period /slash
+/zero /one /two /three /four /five /six /seven
+/eight /nine /colon /semicolon /less /equal /greater /question
+/at /A /B /C /D /E /F /G
+/H /I /J /K /L /M /N /O
+/P /Q /R /S /T /U /V /W
+/X /Y /Z /bracketleft /backslash /bracketright /asciicircum /underscore
+/grave /a /b /c /d /e /f /g
+/h /i /j /k /l /m /n /o
+/p /q /r /s /t /u /v /w
+/x /y /z /braceleft /bar /braceright /asciitilde /.notdef
+/.notdef /.notdef /quotesinglbase /florin /quotedblbase /ellipsis /dagger /daggerdbl
+/.notdef /perthousand /.notdef /guilsinglleft /.notdef /.notdef /.notdef /.notdef
+/.notdef /quoteleft /quoteright /quotedblleft /quotedblright /bullet /endash /emdash
+/.notdef /trademark /.notdef /guilsinglright /.notdef /.notdef /.notdef /.notdef
+/space /dieresistonos /Alphatonos /sterling /currency /yen /brokenbar /section
+/dieresis /copyright /ordfeminine /guillemotleft /logicalnot /hyphen /registered /emdash
+/degree /plusminus /twosuperior /threesuperior /tonos /mu /paragraph /periodcentered
+/Epsilontonos /Etatonos /Iotatonos /guillemotright /Omicrontonos /onehalf /Upsilontonos /Omegatonos
+/iotadieresistonos /Alpha /Beta /Gamma /Delta /Epsilon /Zeta /Eta
+/Theta /Iota /Kappa /Lambda /Mu /Nu /Xi /Omicron
+/Pi /Rho /.notdef /Sigma /Tau /Upsilon /Phi /Chi
+/Psi /Omega /Iotadieresis /Upsilondieresis /alphatonos /epsilontonos /etatonos /iotatonos
+/upsilondieresistonos /alpha /beta /gamma /delta /epsilon /zeta /eta
+/theta /iota /kappa /lambda /mu /nu /xi /omicron
+/pi /rho /sigma1 /sigma /tau /upsilon /phi /chi
+/psi /omega /iotadieresis /upsilondieresis /omicrontonos /upsilontonos /omegatonos /.notdef]
+/Encoding defineresource pop
+% vim:ff=unix:
+%%EOF
--- /dev/null
+++ b/lib/vimfiles/print/cp1254.ps
@@ -1,0 +1,40 @@
+%!PS-Adobe-3.0 Resource-Encoding
+%%Title: VIM-cp1254
+%%Version: 1.0 0
+%%EndComments
+/VIM-cp1254[
+/.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef
+/space /exclam /quotedbl /numbersign /dollar /percent /ampersand /quotesingle
+/parenleft /parenright /asterisk /plus /comma /minus /period /slash
+/zero /one /two /three /four /five /six /seven
+/eight /nine /colon /semicolon /less /equal /greater /question
+/at /A /B /C /D /E /F /G
+/H /I /J /K /L /M /N /O
+/P /Q /R /S /T /U /V /W
+/X /Y /Z /bracketleft /backslash /bracketright /asciicircum /underscore
+/grave /a /b /c /d /e /f /g
+/h /i /j /k /l /m /n /o
+/p /q /r /s /t /u /v /w
+/x /y /z /braceleft /bar /braceright /asciitilde /.notdef
+/Euro /.notdef /quotesinglbase /florin /quotedblbase /ellipsis /dagger /daggerdbl
+/circumflex /perthousand /Scaron /guilsinglleft /OE /.notdef /Zcaron /.notdef
+/.notdef /quoteleft /quoteright /quotedblleft /quotedblright /bullet /endash /emdash
+/tilde /trademark /scaron /guilsinglright /oe /.notdef /zcaron /Ydieresis
+/space /exclamdown /cent /sterling /currency /yen /brokenbar /section
+/dieresis /copyright /ordfeminine /guillemotleft /logicalnot /hyphen /registered /macron
+/degree /plusminus /twosuperior /threesuperior /acute /mu /paragraph /periodcentered
+/cedilla /onesuperior /ordmasculine /guillemotright /onequarter /onehalf /threequarters /questiondown
+/Agrave /Aacute /Acircumflex /Atilde /Adieresis /Aring /AE /Ccedilla
+/Egrave /Eacute /Ecircumflex /Edieresis /Igrave /Iacute /Icircumflex /Idieresis
+/Gbreve /Ntilde /Ograve /Oacute /Ocircumflex /Otilde /Odieresis /multiply
+/Oslash /Ugrave /Uacute /Ucircumflex /Udieresis /Idotaccent /Scedilla /germandbls
+/agrave /aacute /acircumflex /atilde /adieresis /aring /ae /ccedilla
+/egrave /eacute /ecircumflex /edieresis /igrave /iacute /icircumflex /idieresis
+/gbreve /ntilde /ograve /oacute /ocircumflex /otilde /odieresis /divide
+/oslash /ugrave /uacute /ucircumflex /udieresis /dotlessi /scedilla /ydieresis]
+/Encoding defineresource pop
+% vim:ff=unix:
+%%EOF
--- /dev/null
+++ b/lib/vimfiles/print/cp1255.ps
@@ -1,0 +1,40 @@
+%!PS-Adobe-3.0 Resource-Encoding
+%%Title: VIM-cp1255
+%%Version: 1.0 0
+%%EndComments
+/VIM-cp1255[
+/.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef
+/space /exclam /quotedbl /numbersign /dollar /percent /ampersand /quotesingle
+/parenleft /parenright /asterisk /plus /comma /minus /period /slash
+/zero /one /two /three /four /five /six /seven
+/eight /nine /colon /semicolon /less /equal /greater /question
+/at /A /B /C /D /E /F /G
+/H /I /J /K /L /M /N /O
+/P /Q /R /S /T /U /V /W
+/X /Y /Z /bracketleft /backslash /bracketright /asciicircum /underscore
+/grave /a /b /c /d /e /f /g
+/h /i /j /k /l /m /n /o
+/p /q /r /s /t /u /v /w
+/x /y /z /braceleft /bar /braceright /asciitilde /.notdef
+/.notdef /.notdef /quotesinglbase /florin /quotedblbase /ellipsis /dagger /daggerdbl
+/circumflex /perthousand /.notdef /guilsinglleft /.notdef /.notdef /.notdef /.notdef
+/.notdef /quoteleft /quoteright /quotedblleft /quotedblright /bullet /endash /emdash
+/tilde /trademark /.notdef /guilsinglright /.notdef /.notdef /.notdef /.notdef
+/space /.notdef /cent /sterling /newsheqelsign /yen /brokenbar /section
+/dieresis /copyright /.notdef /guillemotleft /logicalnot /hyphen /registered /macron
+/degree /plusminus /twosuperior /threesuperior /acute /mu /paragraph /periodcentered
+/.notdef /onesuperior /.notdef /guillemotright /onequarter /onehalf /threequarters /.notdef
+/sheva /hatafsegol /hatafpatah /hatafqamats /hiriq /tsere /segol /patah
+/qamats /holam /.notdef /qubuts /dagesh /meteg /maqaf /rafe
+/paseq /shindot /sindot /sofpasuq /doublevav /vavyod /doubleyod /.notdef
+/.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef
+/alef /bet /gimel /dalet /he /vav /zayin /het
+/tet /yod /finalkaf /kaf /lamed /finalmem /mem /finalnun
+/nun /samekh /ayin /finalpe /pe /finaltsadi /tsadi /qof
+/resh /shin /tav /.notdef /.notdef /.notdef /.notdef /.notdef]
+/Encoding defineresource pop
+% vim:ff=unix:
+%%EOF
--- /dev/null
+++ b/lib/vimfiles/print/cp1257.ps
@@ -1,0 +1,40 @@
+%!PS-Adobe-3.0 Resource-Encoding
+%%Title: VIM-cp1257
+%%Version: 1.0 0
+%%EndComments
+/VIM-cp1257[
+/.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef
+/space /exclam /quotedbl /numbersign /dollar /percent /ampersand /quotesingle
+/parenleft /parenright /asterisk /plus /comma /minus /period /slash
+/zero /one /two /three /four /five /six /seven
+/eight /nine /colon /semicolon /less /equal /greater /question
+/at /A /B /C /D /E /F /G
+/H /I /J /K /L /M /N /O
+/P /Q /R /S /T /U /V /W
+/X /Y /Z /bracketleft /backslash /bracketright /asciicircum /underscore
+/grave /a /b /c /d /e /f /g
+/h /i /j /k /l /m /n /o
+/p /q /r /s /t /u /v /w
+/x /y /z /braceleft /bar /braceright /asciitilde /.notdef
+/.notdef /.notdef /quotesinglbase /.notdef /quotedblbase /ellipsis /dagger /daggerdbl
+/.notdef /perthousand /.notdef /guilsinglleft /.notdef /.notdef /.notdef /.notdef
+/.notdef /quoteleft /quoteright /quotedblleft /quotedblright /bullet /endash /emdash
+/.notdef /trademark /.notdef /guilsinglright /.notdef /.notdef /.notdef /.notdef
+/space /caron /breve /sterling /currency /.notdef /brokenbar /section
+/dieresis /copyright /Rcedilla /guillemotleft /logicalnot /hyphen /registered /AE
+/degree /plusminus /ogonek /threesuperior /acute /mu /paragraph /periodcentered
+/cedilla /onesuperior /rcedilla /guillemotright /onequarter /onehalf /threequarters /ae
+/Aogonek /Iogonek /Amacron /Cacute /Adieresis /Aring /Eogonek /Emacron
+/Ccaron /Eacute /Zacute /Edot /Gcedilla /Kcedilla /Imacron /Lcedilla
+/Scaron /Nacute /Ncedilla /Oacute /Omacron /Otilde /Odieresis /multiply
+/Uogonek /Lslash /Sacute /Umacron /Udieresis /Zdotaccent /Zcaron /germandbls
+/aogonek /iogonek /amacron /cacute /adieresis /aring /eogonek /emacron
+/ccaron /eacute /zacute /edot /gcedilla /kcedilla /imacron /lcedilla
+/scaron /nacute /ncedilla /oacute /omacron /otilde /odieresis /divide
+/uogonek /lslash /sacute /umacron /udieresis /zdotaccent /zcaron /dotaccent]
+/Encoding defineresource pop
+% vim:ff=unix:
+%%EOF
--- /dev/null
+++ b/lib/vimfiles/print/dec-mcs.ps
@@ -1,0 +1,40 @@
+%!PS-Adobe-3.0 Resource-Encoding
+%%Title: VIM-dec-mcs
+%%Version: 1.0 0
+%%EndComments
+/VIM-dec-mcs[
+/.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef
+/space /exclam /quotedbl /numbersign /dollar /percent /ampersand /quotesingle
+/parenleft /parenright /asterisk /plus /comma /minus /period /slash
+/zero /one /two /three /four /five /six /seven
+/eight /nine /colon /semicolon /less /equal /greater /question
+/at /A /B /C /D /E /F /G
+/H /I /J /K /L /M /N /O
+/P /Q /R /S /T /U /V /W
+/X /Y /Z /bracketleft /backslash /bracketright /asciicircum /underscore
+/grave /a /b /c /d /e /f /g
+/h /i /j /k /l /m /n /o
+/p /q /r /s /t /u /v /w
+/x /y /z /braceleft /bar /braceright /asciitilde /.notdef
+/.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef
+/.notdef /exclamdown /cent /sterling /.notdef /yen /.notdef /section
+/currency /copyright /ordfeminine /guillemotleft /.notdef /.notdef /.notdef /.notdef
+/degree /plusminus /twosuperior /threesuperior /.notdef /mu /paragraph /periodcentered
+/.notdef /onesuperior /ordmasculine /guillemotright /onequarter /onehalf /.notdef /questiondown
+/Agrave /Aacute /Acircumflex /Atilde /Adieresis /Aring /AE /Ccedilla
+/Egrave /Eacute /Ecircumflex /Edieresis /Igrave /Iacute /Icircumflex /Idieresis
+/.notdef /Ntilde /Ograve /Oacute /Ocircumflex /Otilde /Odieresis /OE
+/Oslash /Ugrave /Uacute /Ucircumflex /Udieresis /Ydieresis /.notdef /germandbls
+/agrave /aacute /acircumflex /atilde /adieresis /aring /ae /ccedilla
+/egrave /eacute /ecircumflex /edieresis /igrave /iacute /icircumflex /idieresis
+/.notdef /ntilde /ograve /oacute /ocircumflex /otilde /odieresis /oe
+/oslash /ugrave /uacute /ucircumflex /udieresis /ydieresis /.notdef /.notdef]
+/Encoding defineresource pop
+% vim:ff=unix:
+%%EOF
--- /dev/null
+++ b/lib/vimfiles/print/ebcdic-uk.ps
@@ -1,0 +1,40 @@
+%!PS-Adobe-3.0 Resource-Encoding
+%%Title: VIM-ebcdic-uk
+%%Version: 1.0 0
+%%EndComments
+/VIM-ebcdic-uk[
+/.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef
+/space /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /dollar /period /less /parenleft /plus /bar
+/ampersand /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /exclam /sterling /asterisk /parenright /semicolon /logicalnot
+/minus /slash /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /brokenbar /comma /percent /underscore /greater /question
+/.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef
+/.notdef /quotereversed /colon /numbersign /at /quoteright /equal /quotedbl
+/.notdef /a /b /c /d /e /f /g
+/h /i /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef
+/.notdef /j /k /l /m /n /o /p
+/q /r /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef
+/.notdef /macron /s /t /u /v /w /x
+/y /z /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef
+/braceleft /A /B /C /D /E /F /G
+/H /I /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef
+/braceright /J /K /L /M /N /O /P
+/Q /R /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef
+/backslash /.notdef /S /T /U /V /W /X
+/Y /Z /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef
+/zero /one /two /three /four /five /six /seven
+/eight /nine /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef]
+/Encoding defineresource pop
+% vim:ff=unix:
+%%EOF
--- /dev/null
+++ b/lib/vimfiles/print/gb_roman.ps
@@ -1,0 +1,23 @@
+%!PS-Adobe-3.0 Resource-Encoding
+%%Title: VIM-gb_roman
+%%Version: 1.0 0
+%%EndComments
+% Different to ASCII at code points 36 and 126
+/VIM-gb_roman[
+32{/.notdef}repeat
+/space /exclam /quotedbl /numbersign /yuan /percent /ampersand /quotesingle
+/parenleft /parenright /asterisk /plus /comma /minus /period /slash
+/zero /one /two /three /four /five /six /seven
+/eight /nine /colon /semicolon /less /equal /greater /question
+/at /A /B /C /D /E /F /G
+/H /I /J /K /L /M /N /O
+/P /Q /R /S /T /U /V /W
+/X /Y /Z /bracketleft /backslash /bracketright /asciicircum /underscore
+/grave /a /b /c /d /e /f /g
+/h /i /j /k /l /m /n /o
+/p /q /r /s /t /u /v /w
+/x /y /z /braceleft /bar /braceright /overline /.notdef
+128{/.notdef}repeat]
+/Encoding defineresource pop
+% vim:ff=unix:
+%%EOF
--- /dev/null
+++ b/lib/vimfiles/print/hp-roman8.ps
@@ -1,0 +1,40 @@
+%!PS-Adobe-3.0 Resource-Encoding
+%%Title: VIM-hp-roman8
+%%Version: 1.0 0
+%%EndComments
+/VIM-hp-roman8[
+/.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef
+/space /exclam /quotedbl /numbersign /dollar /percent /ampersand /quotesingle
+/parenleft /parenright /asterisk /plus /comma /minus /period /slash
+/zero /one /two /three /four /five /six /seven
+/eight /nine /colon /semicolon /less /equal /greater /question
+/at /A /B /C /D /E /F /G
+/H /I /J /K /L /M /N /O
+/P /Q /R /S /T /U /V /W
+/X /Y /Z /bracketleft /backslash /bracketright /asciicircum /underscore
+/grave /a /b /c /d /e /f /g
+/h /i /j /k /l /m /n /o
+/p /q /r /s /t /u /v /w
+/x /y /z /braceleft /bar /braceright /asciitilde /.notdef
+/.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef
+/space /Agrave /Acircumflex /Egrave /Ecircumflex /Edieresis /Icircumflex /Idieresis
+/acute /grave /circumflex /dieresis /tilde /Ugrave /Ucircumflex /lira
+/macron /Yacute /yacute /degree /Ccedilla /ccedilla /Ntilde /ntilde
+/exclamdown /questiondown /currency /sterling /yen /section /florin /cent
+/acircumflex /ecircumflex /ocircumflex /ucircumflex /aacute /eacute /oacute /uacute
+/agrave /egrave /ograve /ugrave /adieresis /edieresis /odieresis /udieresis
+/Aring /icircumflex /Oslash /AE /aring /iacute /oslash /ae
+/Adieresis /igrave /Odieresis /Udieresis /Eacute /idieresis /germandbls /Ocircumflex
+/Aacute /Atilde /atilde /Eth /eth /Iacute /Igrave /Oacute
+/Ograve /Otilde /otilde /Scaron /scaron /Uacute /Ydieresis /ydieresis
+/Thorn /thorn /periodcentered /mu /paragraph /threequarters /hyphen /onequarter
+/onehalf /ordfeminine /ordmasculine /guillemotleft /filledbox /guillemotright /plusminus /.notdef]
+/Encoding defineresource pop
+% vim:ff=unix:
+%%EOF
--- /dev/null
+++ b/lib/vimfiles/print/iso-8859-10.ps
@@ -1,0 +1,40 @@
+%!PS-Adobe-3.0 Resource-Encoding
+%%Title: VIM-iso-8859-10
+%%Version: 1.0 0
+%%EndComments
+/VIM-iso-8859-10[
+/.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef
+/space /exclam /quotedbl /numbersign /dollar /percent /ampersand /quotesingle
+/parenleft /parenright /asterisk /plus /comma /hyphen /period /slash
+/zero /one /two /three /four /five /six /seven
+/eight /nine /colon /semicolon /less /equal /greater /question
+/at /A /B /C /D /E /F /G
+/H /I /J /K /L /M /N /O
+/P /Q /R /S /T /U /V /W
+/X /Y /Z /bracketleft /backslash /bracketright /asciicircum /underscore
+/grave /a /b /c /d /e /f /g
+/h /i /j /k /l /m /n /o
+/p /q /r /s /t /u /v /w
+/x /y /z /braceleft /bar /braceright /asciitilde /.notdef
+/.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef
+/space /Aogonek /Emacron /Gcedilla /Imacron /Itilde /Kcedilla /section
+/Lcedilla /Dcroat /Scaron /Tbar /Zcaron /endash /Umacron /Eng
+/degree /aogonek /emacron /gcedilla /imacron /itilde /kcedilla /periodcentered
+/lcedilla /dcroat /scaron /tbar /zcaron /emdash /umacron /eng
+/Amacron /Aacute /Acircumflex /Atilde /Adieresis /Aring /AE /Iogonek
+/Ccaron /Eacute /Eogonek /Edieresis /Edot /Iacute /Icircumflex /Idieresis
+/Eth /Ncedilla /Omacron /Oacute /Ocircumflex /Otilde /Odieresis /Utilde
+/Oslash /Uogonek /Uacute /Ucircumflex /Udieresis /Yacute /Thorn /germandbls
+/amacron /aacute /acircumflex /atilde /adieresis /aring /ae /iogonek
+/ccaron /eacute /eogonek /edieresis /edot /iacute /icircumflex /idieresis
+/eth /ncedilla /omacron /oacute /ocircumflex /otilde /odieresis /utilde
+/oslash /uogonek /uacute /ucircumflex /udieresis /yacute /thorn /kgreenlandic]
+/Encoding defineresource pop
+% vim:ff=unix:
+%%EOF
--- /dev/null
+++ b/lib/vimfiles/print/iso-8859-11.ps
@@ -1,0 +1,40 @@
+%!PS-Adobe-3.0 Resource-Encoding
+%%Title: VIM-iso-8859-11
+%%Version: 1.0 0
+%%EndComments
+/VIM-iso-8859-11[
+/.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef
+/space /exclam /quotedbl /numbersign /dollar /percent /ampersand /quotesingle
+/parenleft /parenright /asterisk /plus /comma /minus /period /slash
+/zero /one /two /three /four /five /six /seven
+/eight /nine /colon /semicolon /less /equal /greater /question
+/at /A /B /C /D /E /F /G
+/H /I /J /K /L /M /N /O
+/P /Q /R /S /T /U /V /W
+/X /Y /Z /bracketleft /backslash /bracketright /asciicircum /underscore
+/grave /a /b /c /d /e /f /g
+/h /i /j /k /l /m /n /o
+/p /q /r /s /t /u /v /w
+/x /y /z /braceleft /bar /braceright /asciitilde /.notdef
+/.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef
+/space /uni0E01 /uni0E02 /uni0E03 /uni0E04 /uni0E05 /uni0E06 /uni0E07
+/uni0E08 /uni0E09 /uni0E0A /uni0E0B /uni0E0C /uni0E0D /uni0E0E /uni0E0F
+/uni0E10 /uni0E11 /uni0E12 /uni0E13 /uni0E14 /uni0E15 /uni0E16 /uni0E17
+/uni0E18 /uni0E19 /uni0E1A /uni0E1B /uni0E1C /uni0E1D /uni0E1E /uni0E1F
+/uni0E20 /uni0E21 /uni0E22 /uni0E23 /uni0E24 /uni0E25 /uni0E26 /uni0E27
+/uni0E28 /uni0E29 /uni0E2A /uni0E2B /uni0E2C /uni0E2D /uni0E2E /uni0E2F
+/uni0E30 /uni0E31 /uni0E32 /uni0E33 /uni0E34 /uni0E35 /uni0E36 /uni0E37
+/uni0E38 /uni0E39 /uni0E3A /.notdef /space /.notdef /.notdef /uni0E3F
+/uni0E40 /uni0E41 /uni0E42 /uni0E43 /uni0E44 /uni0E45 /uni0E46 /uni0E47
+/uni0E48 /uni0E49 /uni0E4A /uni0E4B /uni0E4C /uni0E4D /uni0E4E /uni0E4F
+/uni0E50 /uni0E51 /uni0E52 /uni0E53 /uni0E54 /uni0E55 /uni0E56 /uni0E57
+ /uni0E58 /uni0E59 /uni0E5A /.notdef /.notdef /.notdef /.notdef /.notdef]
+/Encoding defineresource pop
+% vim:ff=unix:
+%%EOF
--- /dev/null
+++ b/lib/vimfiles/print/iso-8859-13.ps
@@ -1,0 +1,40 @@
+%!PS-Adobe-3.0 Resource-Encoding
+%%Title: VIM-iso-8859-13
+%%Version: 1.0 0
+%%EndComments
+/VIM-iso-8859-13[
+/.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef
+/space /exclam /quotedbl /numbersign /dollar /percent /ampersand /quotesingle
+/parenleft /parenright /asterisk /plus /comma /minus /period /slash
+/zero /one /two /three /four /five /six /seven
+/eight /nine /colon /semicolon /less /equal /greater /question
+/at /A /B /C /D /E /F /G
+/H /I /J /K /L /M /N /O
+/P /Q /R /S /T /U /V /W
+/X /Y /Z /bracketleft /backslash /bracketright /asciicircum /underscore
+/grave /a /b /c /d /e /f /g
+/h /i /j /k /l /m /n /o
+/p /q /r /s /t /u /v /w
+/x /y /z /braceleft /bar /braceright /asciitilde /.notdef
+/.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef
+/space /quotedblright /cent /sterling /currency /quotedblbase /brokenbar /section
+/Oslash /copyright /Rcedilla /guillemotleft /logicalnot /hyphen /registered /AE
+/degree /plusminus /twosuperior /threesuperior /quotedblleft /mu /paragraph /periodcentered
+/oslash /onesuperior /rcedilla /guillemotright /onequarter /onehalf /threequarters /ae
+/Aogonek /Iogonek /Amacron /Cacute /Adieresis /Aring /Eogonek /Emacron
+/Ccaron /Eacute /Zacute /Edot /Gcedilla /Kcedilla /Imacron /Lcedilla
+/Scaron /Nacute /Ncedilla /Oacute /Omacron /Otilde /Odieresis /multiply
+/Uogonek /Lslash /Sacute /Umacron /Udieresis /Zdotaccent /Zcaron /germandbls
+/aogonek /iogonek /amacron /cacute /adieresis /aring /eogonek /emacron
+/ccaron /eacute /zacute /edot /gcedilla /kcedilla /imacron /lcedilla
+/scaron /nacute /ncedilla /oacute /omacron /otilde /odieresis /divide
+/uogonek /lslash /sacute /umacron /udieresis /zdotaccent /zcaron /quoteright]
+/Encoding defineresource pop
+% vim:ff=unix:
+%%EOF
--- /dev/null
+++ b/lib/vimfiles/print/iso-8859-14.ps
@@ -1,0 +1,40 @@
+%!PS-Adobe-3.0 Resource-Encoding
+%%Title: VIM-iso-8859-14
+%%Version: 1.0 0
+%%EndComments
+/VIM-iso-8859-14[
+/.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef
+/space /exclam /quotedbl /numbersign /dollar /percent /ampersand /quotesingle
+/parenleft /parenright /asterisk /plus /comma /minus /period /slash
+/zero /one /two /three /four /five /six /seven
+/eight /nine /colon /semicolon /less /equal /greater /question
+/at /A /B /C /D /E /F /G
+/H /I /J /K /L /M /N /O
+/P /Q /R /S /T /U /V /W
+/X /Y /Z /bracketleft /backslash /bracketright /asciicircum /underscore
+/grave /a /b /c /d /e /f /g
+/h /i /j /k /l /m /n /o
+/p /q /r /s /t /u /v /w
+/x /y /z /braceleft /bar /braceright /asciitilde /.notdef
+/.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef
+/space /uni1E02 /uni1E03 /sterling /Cdotaccent /cdotaccent /uni1E0A /section
+/Wgrave /copyright /Wacute /uni1E0B /Ygrave /hyphen /registered /Ydieresis
+/uni1E1E /uni1E1F /Gdotaccent /gdotaccent /uni1E40 /uni1E41 /paragraph /uni1E56
+/wgrave /uni1E57 /wacute /uni1E60 /ygrave /Wdieresis /wdieresis /uni1E61
+/Agrave /Aacute /Acircumflex /Atilde /Adieresis /Aring /AE /Ccedilla
+/Egrave /Eacute /Ecircumflex /Edieresis /Igrave /Iacute /Icircumflex /Idieresis
+/Wcircumflex /Ntilde /Ograve /Oacute /Ocircumflex /Otilde /Odieresis /uni1E6A
+/Oslash /Ugrave /Uacute /Ucircumflex /Udieresis /Yacute /Ycircumflex /germandbls
+/agrave /aacute /acircumflex /atilde /adieresis /aring /ae /ccedilla
+/egrave /eacute /ecircumflex /edieresis /igrave /iacute /icircumflex /idieresis
+/wcircumflex /ntilde /ograve /oacute /ocircumflex /otilde /odieresis /uni1E6B
+/oslash /ugrave /uacute /ucircumflex /udieresis /yacute /ycircumflex /ydieresis]
+/Encoding defineresource pop
+% vim:ff=unix:
+%%EOF
--- /dev/null
+++ b/lib/vimfiles/print/iso-8859-15.ps
@@ -1,0 +1,40 @@
+%!PS-Adobe-3.0 Resource-Encoding
+%%Title: VIM-iso-8859-15
+%%Version: 1.0 0
+%%EndComments
+/VIM-iso-8859-15[
+/.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef
+/space /exclam /quotedbl /numbersign /dollar /percent /ampersand /quotesingle
+/parenleft /parenright /asterisk /plus /comma /minus /period /slash
+/zero /one /two /three /four /five /six /seven
+/eight /nine /colon /semicolon /less /equal /greater /question
+/at /A /B /C /D /E /F /G
+/H /I /J /K /L /M /N /O
+/P /Q /R /S /T /U /V /W
+/X /Y /Z /bracketleft /backslash /bracketright /asciicircum /underscore
+/grave /a /b /c /d /e /f /g
+/h /i /j /k /l /m /n /o
+/p /q /r /s /t /u /v /w
+/x /y /z /braceleft /bar /braceright /asciitilde /.notdef
+/.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef
+/space /exclamdown /cent /sterling /Euro /yen /Scaron /section
+/scaron /copyright /ordfeminine /guillemotleft /logicalnot /hyphen /registered /macron
+/degree /plusminus /twosuperior /threesuperior /Zcaron /mu /paragraph /periodcentered
+/zcaron /onesuperior /ordmasculine /guillemotright /OE /oe /Ydieresis /questiondown
+/Agrave /Aacute /Acircumflex /Atilde /Adieresis /Aring /AE /Ccedilla
+/Egrave /Eacute /Ecircumflex /Edieresis /Igrave /Iacute /Icircumflex /Idieresis
+/Eth /Ntilde /Ograve /Oacute /Ocircumflex /Otilde /Odieresis /multiply
+/Oslash /Ugrave /Uacute /Ucircumflex /Udieresis /Yacute /Thorn /germandbls
+/agrave /aacute /acircumflex /atilde /adieresis /aring /ae /ccedilla
+/egrave /eacute /ecircumflex /edieresis /igrave /iacute /icircumflex /idieresis
+/eth /ntilde /ograve /oacute /ocircumflex /otilde /odieresis /divide
+/oslash /ugrave /uacute /ucircumflex /udieresis /yacute /thorn /ydieresis]
+/Encoding defineresource pop
+% vim:ff=unix:
+%%EOF
--- /dev/null
+++ b/lib/vimfiles/print/iso-8859-2.ps
@@ -1,0 +1,40 @@
+%!PS-Adobe-3.0 Resource-Encoding
+%%Title: VIM-iso-8859-2
+%%Version: 1.0 0
+%%EndComments
+/VIM-iso-8859-2[
+/.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef
+/space /exclam /quotedbl /numbersign /dollar /percent /ampersand /quotesingle
+/parenleft /parenright /asterisk /plus /comma /minus /period /slash
+/zero /one /two /three /four /five /six /seven
+/eight /nine /colon /semicolon /less /equal /greater /question
+/at /A /B /C /D /E /F /G
+/H /I /J /K /L /M /N /O
+/P /Q /R /S /T /U /V /W
+/X /Y /Z /bracketleft /backslash /bracketright /asciicircum /underscore
+/grave /a /b /c /d /e /f /g
+/h /i /j /k /l /m /n /o
+/p /q /r /s /t /u /v /w
+/x /y /z /braceleft /bar /braceright /asciitilde /.notdef
+/.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef
+/space /Aogonek /breve /Lslash /currency /Lcaron /Sacute /section
+/dieresis /Scaron /Scedilla /Tcaron /Zacute /hyphen /Zcaron /Zdotaccent
+/degree /aogonek /ogonek /lslash /acute /lcaron /sacute /caron
+/cedilla /scaron /scedilla /tcaron /zacute /hungarumlaut /zcaron /zdotaccent
+/Racute /Aacute /Acircumflex /Abreve /Adieresis /Lacute /Cacute /Ccedilla
+/Ccaron /Eacute /Eogonek /Edieresis /Ecaron /Iacute /Icircumflex /Dcaron
+/Dcroat /Nacute /Ncaron /Oacute /Ocircumflex /Ohungarumlaut /Odieresis /multiply
+/Rcaron /Uring /Uacute /Uhungarumlaut /Udieresis /Yacute /Tcedilla /germandbls
+/racute /aacute /acircumflex /abreve /adieresis /lacute /cacute /ccedilla
+/ccaron /eacute /eogonek /edieresis /ecaron /iacute /icircumflex /dcaron
+/dcroat /nacute /ncaron /oacute /ocircumflex /ohungarumlaut /odieresis /divide
+/rcaron /uring /uacute /uhungarumlaut /udieresis /yacute /tcedilla /dotaccent]
+/Encoding defineresource pop
+% vim:ff=unix:
+%%EOF
--- /dev/null
+++ b/lib/vimfiles/print/iso-8859-3.ps
@@ -1,0 +1,40 @@
+%!PS-Adobe-3.0 Resource-Encoding
+%%Title: VIM-iso-8859-3
+%%Version: 1.0 0
+%%EndComments
+/VIM-iso-8859-3[
+/.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef
+/space /exclam /quotedbl /numbersign /dollar /percent /ampersand /quotesingle
+/parenleft /parenright /asterisk /plus /comma /minus /period /slash
+/zero /one /two /three /four /five /six /seven
+/eight /nine /colon /semicolon /less /equal /greater /question
+/at /A /B /C /D /E /F /G
+/H /I /J /K /L /M /N /O
+/P /Q /R /S /T /U /V /W
+/X /Y /Z /bracketleft /backslash /bracketright /asciicircum /underscore
+/grave /a /b /c /d /e /f /g
+/h /i /j /k /l /m /n /o
+/p /q /r /s /t /u /v /w
+/x /y /z /braceleft /bar /braceright /asciitilde /.notdef
+/.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef
+/space /Hbar /breve /sterling /currency /.notdef /Hcircumflex /section
+/dieresis /Idot /Scedilla /Gbreve /Jcircumflex /hyphen /.notdef /Zdotaccent
+/degree /hbar /twosuperior /threesuperior /acute /mu /hcircumflex /periodcentered
+/cedilla /dotlessi /scedilla /gbreve /jcircumflex /onehalf /.notdef /zdotaccent
+/Agrave /Aacute /Acircumflex /.notdef /Adieresis /Cdotaccent /Ccircumflex /Ccedilla
+/Egrave /Eacute /Ecircumflex /Edieresis /Igrave /Iacute /Icircumflex /Idieresis
+/.notdef /Ntilde /Ograve /Oacute /Ocircumflex /Gdotaccent /Odieresis /multiply
+/Gcircumflex /Ugrave /Uacute /Ucircumflex /Udieresis /Ubreve /Scircumflex /germandbls
+/agrave /aacute /acircumflex /.notdef /adieresis /cdotaccent /ccircumflex /ccedilla
+/egrave /eacute /ecircumflex /edieresis /igrave /iacute /icircumflex /idieresis
+/.notdef /ntilde /ograve /oacute /ocircumflex /gdotaccent /odieresis /divide
+/gcircumflex /ugrave /uacute /ucircumflex /udieresis /ubreve /scircumflex /dotaccent]
+/Encoding defineresource pop
+% vim:ff=unix:
+%%EOF
--- /dev/null
+++ b/lib/vimfiles/print/iso-8859-4.ps
@@ -1,0 +1,40 @@
+%!PS-Adobe-3.0 Resource-Encoding
+%%Title: VIM-iso-8859-4
+%%Version: 1.0 0
+%%EndComments
+/VIM-iso-8859-4[
+/.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef
+/space /exclam /quotedbl /numbersign /dollar /percent /ampersand /quotesingle
+/parenleft /parenright /asterisk /plus /comma /minus /period /slash
+/zero /one /two /three /four /five /six /seven
+/eight /nine /colon /semicolon /less /equal /greater /question
+/at /A /B /C /D /E /F /G
+/H /I /J /K /L /M /N /O
+/P /Q /R /S /T /U /V /W
+/X /Y /Z /bracketleft /backslash /bracketright /asciicircum /underscore
+/grave /a /b /c /d /e /f /g
+/h /i /j /k /l /m /n /o
+/p /q /r /s /t /u /v /w
+/x /y /z /braceleft /bar /braceright /asciitilde /.notdef
+/.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef
+/space /Aogonek /kgreenlandic /Rcedilla /currency /Itilde /Lcedilla /section
+/dieresis /Scaron /Emacron /Gcedilla /Tbar /.notdef /Zcaron /macron
+/degree /aogonek /ogonek /rcedilla /acute /itilde /lcedilla /caron
+/cedilla /scaron /emacron /gcedilla /tbar /Eng /zcaron /eng
+/Amacron /Aacute /Acircumflex /Atilde /Adieresis /Aring /AE /Iogonek
+/Ccaron /Eacute /Eogonek /Edieresis /Edot /Iacute /Icircumflex /Imacron
+/Dcroat /Ncedilla /Omacron /Kcedilla /Ocircumflex /Otilde /Odieresis /multiply
+/Oslash /Uogonek /Uacute /Ucircumflex /Udieresis /Utilde /Umacron /germandbls
+/amacron /aacute /acircumflex /atilde /adieresis /aring /ae /iogonek
+/ccaron /eacute /eogonek /edieresis /edot /iacute /icircumflex /imacron
+/dcroat /ncedilla /omacron /kcedilla /ocircumflex /otilde /odieresis /divide
+/oslash /uogonek /uacute /ucircumflex /udieresis /utilde /umacron /dotaccent]
+/Encoding defineresource pop
+% vim:ff=unix:
+%%EOF
--- /dev/null
+++ b/lib/vimfiles/print/iso-8859-5.ps
@@ -1,0 +1,40 @@
+%!PS-Adobe-3.0 Resource-Encoding
+%%Title: VIM-iso-8859-5
+%%Version: 1.0 0
+%%EndComments
+/VIM-iso-8859-5[
+/.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef
+/space /exclam /quotedbl /numbersign /dollar /percent /ampersand /quotesingle
+/parenleft /parenright /asterisk /plus /comma /minus /period /slash
+/zero /one /two /three /four /five /six /seven
+/eight /nine /colon /semicolon /less /equal /greater /question
+/at /A /B /C /D /E /F /G
+/H /I /J /K /L /M /N /O
+/P /Q /R /S /T /U /V /W
+/X /Y /Z /bracketleft /backslash /bracketright /asciicircum /underscore
+/grave /a /b /c /d /e /f /g
+/h /i /j /k /l /m /n /o
+/p /q /r /s /t /u /v /w
+/x /y /z /braceleft /bar /braceright /asciitilde /.notdef
+/.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef
+/space /afii10023 /afii10051 /afii10052 /afii10053 /afii10054 /afii10055 /afii10056
+/afii10057 /afii10058 /afii10059 /afii10060 /afii10061 /.notdef /afii10062 /afii10145
+/afii10017 /afii10018 /afii10019 /afii10020 /afii10021 /afii10022 /afii10024 /afii10025
+/afii10026 /afii10027 /afii10028 /afii10029 /afii10030 /afii10031 /afii10032 /afii10033
+/afii10034 /afii10035 /afii10036 /afii10037 /afii10038 /afii10039 /afii10040 /afii10041
+/afii10042 /afii10043 /afii10044 /afii10045 /afii10046 /afii10047 /afii10048 /afii10049
+/afii10065 /afii10066 /afii10067 /afii10068 /afii10069 /afii10070 /afii10072 /afii10073
+/afii10074 /afii10075 /afii10076 /afii10077 /afii10078 /afii10079 /afii10080 /afii10081
+/afii10082 /afii10083 /afii10084 /afii10085 /afii10086 /afii10087 /afii10088 /afii10089
+/afii10090 /afii10091 /afii10092 /afii10093 /afii10094 /afii10095 /afii10096 /afii10097
+/afii61352 /afii10071 /afii10099 /afii10100 /afii10101 /afii10102 /afii10103 /afii10104
+/afii10105 /afii10106 /afii10107 /afii10108 /afii10109 /section /afii10110 /afii10193]
+/Encoding defineresource pop
+% vim:ff=unix:
+%%EOF
--- /dev/null
+++ b/lib/vimfiles/print/iso-8859-7.ps
@@ -1,0 +1,40 @@
+%!PS-Adobe-3.0 Resource-Encoding
+%%Title: VIM-iso-8859-7
+%%Version: 1.0 0
+%%EndComments
+/VIM-iso-8859-7[
+/.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef
+/space /exclam /quotedbl /numbersign /dollar /percent /ampersand /quotesingle
+/parenleft /parenright /asterisk /plus /comma /minus /period /slash
+/zero /one /two /three /four /five /six /seven
+/eight /nine /colon /semicolon /less /equal /greater /question
+/at /A /B /C /D /E /F /G
+/H /I /J /K /L /M /N /O
+/P /Q /R /S /T /U /V /W
+/X /Y /Z /bracketleft /backslash /bracketright /asciicircum /underscore
+/grave /a /b /c /d /e /f /g
+/h /i /j /k /l /m /n /o
+/p /q /r /s /t /u /v /w
+/x /y /z /braceleft /bar /braceright /asciitilde /.notdef
+/.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef
+/space /quotereversed /quoteright /sterling /.notdef /.notdef /brokenbar /section
+/dieresis /copyright /.notdef /guillemotleft /logicalnot /.notdef /.notdef /emdash
+/degree /plusminus /twosuperior /threesuperior /tonos /dieresistonos /Alphatonos /periodcentered
+/Epsilontonos /Etatonos /Iotatonos /guillemotright /Omicrontonos /onehalf /Upsilontonos /Omegatonos
+/iotadieresistonos /Alpha /Beta /Gamma /Delta /Epsilon /Zeta /Eta
+/Theta /Iota /Kappa /Lambda /Mu /Nu /Xi /Omicron
+/Pi /Rho /.notdef /Sigma /Tau /Upsilon /Phi /Chi
+/Psi /Omega /Iotadieresis /Upsilondieresis /alphatonos /epsilontonos /etatonos /iotatonos
+/upsilondieresistonos /alpha /beta /gamma /delta /epsilon /zeta /eta
+/theta /iota /kappa /lambda /mu /nu /xi /omicron
+/pi /rho /sigma1 /sigma /tau /upsilon /phi /chi
+/psi /omega /iotadieresis /upsilondieresis /omicrontonos /upsilontonos /omegatonos /.notdef]
+/Encoding defineresource pop
+% vim:ff=unix:
+%%EOF
--- /dev/null
+++ b/lib/vimfiles/print/iso-8859-8.ps
@@ -1,0 +1,40 @@
+%!PS-Adobe-3.0 Resource-Encoding
+%%Title: VIM-iso-8859-8
+%%Version: 1.0 0
+%%EndComments
+/VIM-iso-8859-8[
+/.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef
+/space /exclam /quotedbl /numbersign /dollar /percent /ampersand /quotesingle
+/parenleft /parenright /asterisk /plus /comma /minus /period /slash
+/zero /one /two /three /four /five /six /seven
+/eight /nine /colon /semicolon /less /equal /greater /question
+/at /A /B /C /D /E /F /G
+/H /I /J /K /L /M /N /O
+/P /Q /R /S /T /U /V /W
+/X /Y /Z /bracketleft /backslash /bracketright /asciicircum /underscore
+/grave /a /b /c /d /e /f /g
+/h /i /j /k /l /m /n /o
+/p /q /r /s /t /u /v /w
+/x /y /z /braceleft /bar /braceright /asciitilde /.notdef
+/.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef
+/space /.notdef /cent /sterling /currency /yen /brokenbar /section
+/dieresis /copyright /multiply /guillemotleft /logicalnot /hyphen /registered /macron
+/degree /plusminus /twosuperior /threesuperior /acute /mu /paragraph /periodcentered
+/cedilla /onesuperior /divide /guillemotright /onequarter /onehalf /threequarters /.notdef
+/.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /underscoredbl
+/alef /bet /gimel /dalet /he /vav /zayin /het
+/tet /yod /finalkaf /kaf /lamed /finalmem /mem /finalnun
+/nun /samekh /ayin /finalpe /pe /finaltsadi /tsadi /qof
+/resh /shin /tav /.notdef /.notdef /.notdef /.notdef /.notdef]
+/Encoding defineresource pop
+% vim:ff=unix:
+%%EOF
--- /dev/null
+++ b/lib/vimfiles/print/iso-8859-9.ps
@@ -1,0 +1,40 @@
+%!PS-Adobe-3.0 Resource-Encoding
+%%Title: VIM-iso-8859-9
+%%Version: 1.0 0
+%%EndComments
+/VIM-iso-8859-9[
+/.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef
+/space /exclam /quotedbl /numbersign /dollar /percent /ampersand /quotesingle
+/parenleft /parenright /asterisk /plus /comma /minus /period /slash
+/zero /one /two /three /four /five /six /seven
+/eight /nine /colon /semicolon /less /equal /greater /question
+/at /A /B /C /D /E /F /G
+/H /I /J /K /L /M /N /O
+/P /Q /R /S /T /U /V /W
+/X /Y /Z /bracketleft /backslash /bracketright /asciicircum /underscore
+/grave /a /b /c /d /e /f /g
+/h /i /j /k /l /m /n /o
+/p /q /r /s /t /u /v /w
+/x /y /z /braceleft /bar /braceright /asciitilde /.notdef
+/.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef
+/space /exclamdown /cent /sterling /currency /yen /brokenbar /section
+/dieresis /copyright /ordfeminine /guillemotleft /logicalnot /hyphen /registered /macron
+/degree /plusminus /twosuperior /threesuperior /acute /mu /paragraph /periodcentered
+/cedilla /onesuperior /ordmasculine /guillemotright /onequarter /onehalf /threequarters /questiondown
+/Agrave /Aacute /Acircumflex /Atilde /Adieresis /Aring /AE /Ccedilla
+/Egrave /Eacute /Ecircumflex /Edieresis /Igrave /Iacute /Icircumflex /Idieresis
+/Gbreve /Ntilde /Ograve /Oacute /Ocircumflex /Otilde /Odieresis /multiply
+/Oslash /Ugrave /Uacute /Ucircumflex /Udieresis /Idotaccent /Scedilla /germandbls
+/agrave /aacute /acircumflex /atilde /adieresis /aring /ae /ccedilla
+/egrave /eacute /ecircumflex /edieresis /igrave /iacute /icircumflex /idieresis
+/gbreve /ntilde /ograve /oacute /ocircumflex /otilde /odieresis /divide
+/oslash /ugrave /uacute /ucircumflex /udieresis /dotlessi /scedilla /ydieresis]
+/Encoding defineresource pop
+% vim:ff=unix:
+%%EOF
--- /dev/null
+++ b/lib/vimfiles/print/jis_roman.ps
@@ -1,0 +1,23 @@
+%!PS-Adobe-3.0 Resource-Encoding
+%%Title: VIM-jis_roman
+%%Version: 1.0 0
+%%EndComments
+% Different to ASCII at code points 92 and 126
+/VIM-jis_roman[
+32{/.notdef}repeat
+/space /exclam /quotedbl /numbersign /dollar /percent /ampersand /quotesingle
+/parenleft /parenright /asterisk /plus /comma /minus /period /slash
+/zero /one /two /three /four /five /six /seven
+/eight /nine /colon /semicolon /less /equal /greater /question
+/at /A /B /C /D /E /F /G
+/H /I /J /K /L /M /N /O
+/P /Q /R /S /T /U /V /W
+/X /Y /Z /bracketleft /yen /bracketright /asciicircum /underscore
+/grave /a /b /c /d /e /f /g
+/h /i /j /k /l /m /n /o
+/p /q /r /s /t /u /v /w
+/x /y /z /braceleft /bar /braceright /overline /.notdef
+128{/.notdef}repeat]
+/Encoding defineresource pop
+% vim:ff=unix:
+%%EOF
--- /dev/null
+++ b/lib/vimfiles/print/koi8-r.ps
@@ -1,0 +1,40 @@
+%!PS-Adobe-3.0 Resource-Encoding
+%%Title: VIM-koi8-r
+%%Version: 1.0 0
+%%EndComments
+/VIM-koi8-r[
+/.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef
+/space /exclam /quotedbl /numbersign /dollar /percent /ampersand /quotesingle
+/parenleft /parenright /asterisk /plus /comma /minus /period /slash
+/zero /one /two /three /four /five /six /seven
+/eight /nine /colon /semicolon /less /equal /greater /question
+/at /A /B /C /D /E /F /G
+/H /I /J /K /L /M /N /O
+/P /Q /R /S /T /U /V /W
+/X /Y /Z /bracketleft /backslash /bracketright /asciicircum /underscore
+/grave /a /b /c /d /e /f /g
+/h /i /j /k /l /m /n /o
+/p /q /r /s /t /u /v /w
+/x /y /z /braceleft /bar /braceright /asciitilde /.notdef
+/SF100000 /SF110000 /SF010000 /SF030000 /SF020000 /SF040000 /SF080000 /SF090000
+/SF060000 /SF070000 /SF050000 /upblock /dnblock /block /lfblock /rtblock
+/ltshade /shade /dkshade /integraltp /filledbox /bullet /radical /approxequal
+/lessequal /greaterequal /space /integralbt /degree /twosuperior /periodcentered /divide
+/SF430000 /SF240000 /SF510000 /afii10071 /SF520000 /SF390000 /SF220000 /SF210000
+/SF250000 /SF500000 /SF490000 /SF380000 /SF280000 /SF270000 /SF260000 /SF360000
+/SF370000 /SF420000 /SF190000 /afii10023 /SF200000 /SF230000 /SF470000 /SF480000
+/SF410000 /SF450000 /SF460000 /SF400000 /SF540000 /SF530000 /SF440000 /copyright
+/afii10096 /afii10065 /afii10066 /afii10088 /afii10069 /afii10070 /afii10086 /afii10068
+/afii10087 /afii10074 /afii10075 /afii10076 /afii10077 /afii10078 /afii10079 /afii10080
+/afii10081 /afii10097 /afii10082 /afii10083 /afii10084 /afii10085 /afii10072 /afii10067
+/afii10094 /afii10093 /afii10073 /afii10090 /afii10095 /afii10091 /afii10089 /afii10092
+/afii10048 /afii10017 /afii10018 /afii10040 /afii10021 /afii10022 /afii10038 /afii10020
+/afii10039 /afii10026 /afii10027 /afii10028 /afii10029 /afii10030 /afii10031 /afii10032
+/afii10033 /afii10049 /afii10034 /afii10035 /afii10036 /afii10037 /afii10024 /afii10019
+/afii10046 /afii10045 /afii10025 /afii10042 /afii10047 /afii10043 /afii10041 /afii10044]
+/Encoding defineresource pop
+% vim:ff=unix:
+%%EOF
--- /dev/null
+++ b/lib/vimfiles/print/koi8-u.ps
@@ -1,0 +1,40 @@
+%!PS-Adobe-3.0 Resource-Encoding
+%%Title: VIM-koi8-u
+%%Version: 1.0 0
+%%EndComments
+/VIM-koi8-u[
+/.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef
+/space /exclam /quotedbl /numbersign /dollar /percent /ampersand /quotesingle
+/parenleft /parenright /asterisk /plus /comma /minus /period /slash
+/zero /one /two /three /four /five /six /seven
+/eight /nine /colon /semicolon /less /equal /greater /question
+/at /A /B /C /D /E /F /G
+/H /I /J /K /L /M /N /O
+/P /Q /R /S /T /U /V /W
+/X /Y /Z /bracketleft /backslash /bracketright /asciicircum /underscore
+/grave /a /b /c /d /e /f /g
+/h /i /j /k /l /m /n /o
+/p /q /r /s /t /u /v /w
+/x /y /z /braceleft /bar /braceright /asciitilde /.notdef
+/SF100000 /SF110000 /SF010000 /SF030000 /SF020000 /SF040000 /SF080000 /SF090000
+/SF060000 /SF070000 /SF050000 /upblock /dnblock /block /lfblock /rtblock
+/ltshade /shade /dkshade /integraltp /filledbox /bullet /radical /approxequal
+/lessequal /greaterequal /space /integralbt /degree /twosuperior /periodcentered /divide
+/SF430000 /SF240000 /SF510000 /afii10071 /afii10101 /SF390000 /afii10103 /afii10104
+/SF250000 /SF500000 /SF490000 /SF380000 /SF280000 /afii10098 /SF260000 /SF360000
+/SF370000 /SF420000 /SF190000 /afii10023 /afii10053 /SF230000 /afii10055 /afii10056
+/SF410000 /SF450000 /SF460000 /SF400000 /SF540000 /afii10050 /SF440000 /copyright
+/afii10096 /afii10065 /afii10066 /afii10088 /afii10069 /afii10070 /afii10086 /afii10068
+/afii10087 /afii10074 /afii10075 /afii10076 /afii10077 /afii10078 /afii10079 /afii10080
+/afii10081 /afii10097 /afii10082 /afii10083 /afii10084 /afii10085 /afii10072 /afii10067
+/afii10094 /afii10093 /afii10073 /afii10090 /afii10095 /afii10091 /afii10089 /afii10092
+/afii10048 /afii10017 /afii10018 /afii10040 /afii10021 /afii10022 /afii10038 /afii10020
+/afii10039 /afii10026 /afii10027 /afii10028 /afii10029 /afii10030 /afii10031 /afii10032
+/afii10033 /afii10049 /afii10034 /afii10035 /afii10036 /afii10037 /afii10024 /afii10019
+/afii10046 /afii10045 /afii10025 /afii10042 /afii10047 /afii10043 /afii10041 /afii10044]
+/Encoding defineresource pop
+% vim:ff=unix:
+%%EOF
--- /dev/null
+++ b/lib/vimfiles/print/ks_roman.ps
@@ -1,0 +1,23 @@
+%!PS-Adobe-3.0 Resource-Encoding
+%%Title: VIM-ks_roman
+%%Version: 1.0 0
+%%EndComments
+% Different to ASCII at code points 96 and 126
+/VIM-ks_roman[
+32{/.notdef}repeat
+/space /exclam /quotedbl /numbersign /dollar /percent /ampersand /quotesingle
+/parenleft /parenright /asterisk /plus /comma /minus /period /slash
+/zero /one /two /three /four /five /six /seven
+/eight /nine /colon /semicolon /less /equal /greater /question
+/at /A /B /C /D /E /F /G
+/H /I /J /K /L /M /N /O
+/P /Q /R /S /T /U /V /W
+/X /Y /Z /bracketleft /won /bracketright /asciicircum /underscore
+/grave /a /b /c /d /e /f /g
+/h /i /j /k /l /m /n /o
+/p /q /r /s /t /u /v /w
+/x /y /z /braceleft /bar /braceright /overline /.notdef
+128{/.notdef}repeat]
+/Encoding defineresource pop
+% vim:ff=unix:
+%%EOF
--- /dev/null
+++ b/lib/vimfiles/print/latin1.ps
@@ -1,0 +1,40 @@
+%!PS-Adobe-3.0 Resource-Encoding
+%%Title: VIM-latin1
+%%Version: 1.0 0
+%%EndComments
+/VIM-latin1[
+/.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef
+/space /exclam /quotedbl /numbersign /dollar /percent /ampersand /quotesingle
+/parenleft /parenright /asterisk /plus /comma /minus /period /slash
+/zero /one /two /three /four /five /six /seven
+/eight /nine /colon /semicolon /less /equal /greater /question
+/at /A /B /C /D /E /F /G
+/H /I /J /K /L /M /N /O
+/P /Q /R /S /T /U /V /W
+/X /Y /Z /bracketleft /backslash /bracketright /asciicircum /underscore
+/grave /a /b /c /d /e /f /g
+/h /i /j /k /l /m /n /o
+/p /q /r /s /t /u /v /w
+/x /y /z /braceleft /bar /braceright /asciitilde /.notdef
+/.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef
+/space /exclamdown /cent /sterling /currency /yen /brokenbar /section
+/dieresis /copyright /ordfeminine /guillemotleft /logicalnot /hyphen /registered /macron
+/degree /plusminus /twosuperior /threesuperior /acute /mu /paragraph /periodcentered
+/cedilla /onesuperior /ordmasculine /guillemotright /onequarter /onehalf /threequarters /questiondown
+/Agrave /Aacute /Acircumflex /Atilde /Adieresis /Aring /AE /Ccedilla
+/Egrave /Eacute /Ecircumflex /Edieresis /Igrave /Iacute /Icircumflex /Idieresis
+/Eth /Ntilde /Ograve /Oacute /Ocircumflex /Otilde /Odieresis /multiply
+/Oslash /Ugrave /Uacute /Ucircumflex /Udieresis /Yacute /Thorn /germandbls
+/agrave /aacute /acircumflex /atilde /adieresis /aring /ae /ccedilla
+/egrave /eacute /ecircumflex /edieresis /igrave /iacute /icircumflex /idieresis
+/eth /ntilde /ograve /oacute /ocircumflex /otilde /odieresis /divide
+/oslash /ugrave /uacute /ucircumflex /udieresis /yacute /thorn /ydieresis]
+/Encoding defineresource pop
+% vim:ff=unix:
+%%EOF
--- /dev/null
+++ b/lib/vimfiles/print/mac-roman.ps
@@ -1,0 +1,40 @@
+%!PS-Adobe-3.0 Resource-Encoding
+%%Title: VIM-mac-roman
+%%Version: 1.0 0
+%%EndComments
+/VIM-mac-roman[
+/.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef
+/space /exclam /quotedbl /numbersign /dollar /percent /ampersand /quotesingle
+/parenleft /parenright /asterisk /plus /comma /minus /period /slash
+/zero /one /two /three /four /five /six /seven
+/eight /nine /colon /semicolon /less /equal /greater /question
+/at /A /B /C /D /E /F /G
+/H /I /J /K /L /M /N /O
+/P /Q /R /S /T /U /V /W
+/X /Y /Z /bracketleft /backslash /bracketright /asciicircum /underscore
+/grave /a /b /c /d /e /f /g
+/h /i /j /k /l /m /n /o
+/p /q /r /s /t /u /v /w
+/x /y /z /braceleft /bar /braceright /asciitilde /.notdef
+/Adieresis /Aring /Ccedilla /Eacute /Ntilde /Odieresis /Udieresis /aacute
+/agrave /acircumflex /adieresis /atilde /aring /ccedilla /eacute /egrave
+/ecircumflex /edieresis /iacute /igrave /icircumflex /idieresis /ntilde /oacute
+/ograve /ocircumflex /odieresis /otilde /uacute /ugrave /ucircumflex /udieresis
+/dagger /degree /cent /sterling /section /bullet /paragraph /germandbls
+/registered /copyright /trademark /acute /dieresis /notequal /AE /Oslash
+/infinity /plusminus /lessequal /greaterequal /yen /mu /partialdiff /summation
+/Pi /pi /integral /ordfeminine /ordmasculine /Omega /ae /oslash
+/questiondown /exclamdown /logicalnot /radical /florin /approxequal /delta /guillemotleft
+/guillemotright /ellipsis /space /Agrave /Atilde /Otilde /OE /oe
+/endash /emdash /quotedblleft /quotedblright /quoteleft /quoteright /divide /lozenge
+/ydieresis /Ydieresis /fraction /currency /guilsinglleft /guilsinglright /fi /fl
+/daggerdbl /periodcentered /quotesinglbase /quotedblbase /perthousand /Acircumflex /Ecircumflex /Aacute
+/Edieresis /Egrave /Iacute /Icircumflex /Idieresis /Igrave /Oacute /Ocircumflex
+/heart /Ograve /Uacute /Ucircumflex /Ugrave /dotlessi /circumflex /tilde
+/macron /breve /dotaccent /ring /cedilla /hungarumlaut /ogonek /caron]
+/Encoding defineresource pop
+% vim:ff=unix:
+%%EOF
--- /dev/null
+++ b/lib/vimfiles/print/prolog.ps
@@ -1,0 +1,44 @@
+%!PS-Adobe-3.0 Resource-ProcSet
+%%Title: VIM-Prolog
+%%Version: 1.4 1
+%%EndComments
+% Editing of this file is NOT RECOMMENDED.  You run a very good risk of causing
+% all PostScript printing from VIM failing if you do.  PostScript is not called
+% a write-only language for nothing!
+/packedarray where not{userdict begin/setpacking/pop load def/currentpacking
+false def end}{pop}ifelse/CP currentpacking def true setpacking
+/bd{bind def}bind def/ld{load def}bd/ed{exch def}bd/d/def ld
+/db{dict begin}bd/cde{currentdict end}bd
+/T true d/F false d
+/SO null d/sv{/SO save d}bd/re{SO restore}bd
+/L2 systemdict/languagelevel 2 copy known{get exec}{pop pop 1}ifelse 2 ge d
+/m/moveto ld/s/show ld /ms{m s}bd /g/setgray ld/r/setrgbcolor ld/sp{showpage}bd
+/gs/gsave ld/gr/grestore ld/cp/currentpoint ld
+/ul{gs UW setlinewidth cp UO add 2 copy newpath m 3 1 roll add exch lineto
+stroke gr}bd
+/bg{gs r cp BO add 4 -2 roll rectfill gr}bd
+/sl{90 rotate 0 exch translate}bd
+L2{
+/sspd{mark exch{setpagedevice}stopped cleartomark}bd
+/nc{1 db/NumCopies ed cde sspd}bd
+/sps{3 db/Orientation ed[3 1 roll]/PageSize ed/ImagingBBox null d cde sspd}bd
+/dt{2 db/Tumble ed/Duplex ed cde sspd}bd
+/c{1 db/Collate ed cde sspd}bd
+}{
+/nc{/#copies ed}bd
+/sps{statusdict/setpage get exec}bd
+/dt{statusdict/settumble 2 copy known{get exec}{pop pop pop}ifelse
+statusdict/setduplexmode 2 copy known{get exec}{pop pop pop}ifelse}bd
+/c{pop}bd
+}ifelse
+/ffs{findfont exch scalefont d}bd/sf{setfont}bd
+/ref{1 db findfont dup maxlength dict/NFD ed{exch dup/FID ne{exch NFD 3 1 roll
+put}{pop pop}ifelse}forall/Encoding findresource dup length 256 eq{NFD/Encoding
+3 -1 roll put}{pop}ifelse NFD dup/FontType get 3 ne{/CharStrings}{/CharProcs}
+ifelse 2 copy known{2 copy get dup maxlength dict copy[/questiondown/space]{2
+copy known{2 copy get 2 index/.notdef 3 -1 roll put pop exit}if pop}forall put
+}{pop pop}ifelse dup NFD/FontName 3 -1 roll put NFD definefont pop end}bd
+CP setpacking
+(\004)cvn{}bd
+% vim:ff=unix:
+%%EOF
--- /dev/null
+++ b/lib/vimfiles/scripts.vim
@@ -1,0 +1,343 @@
+" Vim support file to detect file types in scripts
+"
+" Maintainer:	Bram Moolenaar <Bram@vim.org>
+" Last change:	2007 Apr 29
+
+" This file is called by an autocommand for every file that has just been
+" loaded into a buffer.  It checks if the type of file can be recognized by
+" the file contents.  The autocommand is in $VIMRUNTIME/filetype.vim.
+
+
+" Only do the rest when the FileType autocommand has not been triggered yet.
+if did_filetype()
+  finish
+endif
+
+" Load the user defined scripts file first
+" Only do this when the FileType autocommand has not been triggered yet
+if exists("myscriptsfile") && filereadable(expand(myscriptsfile))
+  execute "source " . myscriptsfile
+  if did_filetype()
+    finish
+  endif
+endif
+
+" Line continuation is used here, remove 'C' from 'cpoptions'
+let s:cpo_save = &cpo
+set cpo&vim
+
+let s:line1 = getline(1)
+
+if s:line1 =~ "^#!"
+  " A script that starts with "#!".
+
+  " Check for a line like "#!/usr/bin/env VAR=val bash".  Turn it into
+  " "#!/usr/bin/bash" to make matching easier.
+  if s:line1 =~ '^#!\s*\S*\<env\s'
+    let s:line1 = substitute(s:line1, '\S\+=\S\+', '', 'g')
+    let s:line1 = substitute(s:line1, '\<env\s\+', '', '')
+  endif
+
+  " Get the program name.
+  " Only accept spaces in PC style paths: "#!c:/program files/perl [args]".
+  " If the word env is used, use the first word after the space:
+  " "#!/usr/bin/env perl [path/args]"
+  " If there is no path use the first word: "#!perl [path/args]".
+  " Otherwise get the last word after a slash: "#!/usr/bin/perl [path/args]".
+  if s:line1 =~ '^#!\s*\a:[/\\]'
+    let s:name = substitute(s:line1, '^#!.*[/\\]\(\i\+\).*', '\1', '')
+  elseif s:line1 =~ '^#!.*\<env\>'
+    let s:name = substitute(s:line1, '^#!.*\<env\>\s\+\(\i\+\).*', '\1', '')
+  elseif s:line1 =~ '^#!\s*[^/\\ ]*\>\([^/\\]\|$\)'
+    let s:name = substitute(s:line1, '^#!\s*\([^/\\ ]*\>\).*', '\1', '')
+  else
+    let s:name = substitute(s:line1, '^#!\s*\S*[/\\]\(\i\+\).*', '\1', '')
+  endif
+
+  " tcl scripts may have #!/bin/sh in the first line and "exec wish" in the
+  " third line.  Suggested by Steven Atkinson.
+  if getline(3) =~ '^exec wish'
+    let s:name = 'wish'
+  endif
+
+  " Bourne-like shell scripts: bash bash2 ksh ksh93 sh
+  if s:name =~ '^\(bash\d*\|\|ksh\d*\|sh\)\>'
+    call SetFileTypeSH(s:line1)	" defined in filetype.vim
+
+    " csh scripts
+  elseif s:name =~ '^csh\>'
+    if exists("g:filetype_csh")
+      call SetFileTypeShell(g:filetype_csh)
+    else
+      call SetFileTypeShell("csh")
+    endif
+
+    " tcsh scripts
+  elseif s:name =~ '^tcsh\>'
+    call SetFileTypeShell("tcsh")
+
+    " Z shell scripts
+  elseif s:name =~ '^zsh\>'
+    set ft=zsh
+
+    " TCL scripts
+  elseif s:name =~ '^\(tclsh\|wish\|expectk\|itclsh\|itkwish\)\>'
+    set ft=tcl
+
+    " Expect scripts
+  elseif s:name =~ '^expect\>'
+    set ft=expect
+
+    " Gnuplot scripts
+  elseif s:name =~ '^gnuplot\>'
+    set ft=gnuplot
+
+    " Makefiles
+  elseif s:name =~ 'make\>'
+    set ft=make
+
+    " Lua
+  elseif s:name =~ 'lua'
+    set ft=lua
+
+    " Perl
+  elseif s:name =~ 'perl'
+    set ft=perl
+
+    " PHP
+  elseif s:name =~ 'php'
+    set ft=php
+
+    " Python
+  elseif s:name =~ 'python'
+    set ft=python
+
+    " Groovy
+  elseif s:name =~ '^groovy\>'
+    set ft=groovy
+
+    " Ruby
+  elseif s:name =~ 'ruby'
+    set ft=ruby
+
+    " BC calculator
+  elseif s:name =~ '^bc\>'
+    set ft=bc
+
+    " sed
+  elseif s:name =~ 'sed\>'
+    set ft=sed
+
+    " OCaml-scripts
+  elseif s:name =~ 'ocaml'
+    set ft=ocaml
+
+    " Awk scripts
+  elseif s:name =~ 'awk\>'
+    set ft=awk
+
+    " Website MetaLanguage
+  elseif s:name =~ 'wml'
+    set ft=wml
+
+    " Scheme scripts
+  elseif s:name =~ 'scheme'
+    set ft=scheme
+
+    " CFEngine scripts
+  elseif s:name =~ 'cfengine'
+    set ft=cfengine
+
+  endif
+  unlet s:name
+
+else
+  " File does not start with "#!".
+
+  let s:line2 = getline(2)
+  let s:line3 = getline(3)
+  let s:line4 = getline(4)
+  let s:line5 = getline(5)
+
+  " Bourne-like shell scripts: sh ksh bash bash2
+  if s:line1 =~ '^:$'
+    call SetFileTypeSH(s:line1)	" defined in filetype.vim
+
+    " Z shell scripts
+  elseif s:line1 =~ '^#compdef\>' || s:line1 =~ '^#autoload\>'
+    set ft=zsh
+
+  " ELM Mail files
+  elseif s:line1 =~ '^From [a-zA-Z][a-zA-Z_0-9\.=-]*\(@[^ ]*\)\= .*[12][09]\d\d$'
+    set ft=mail
+
+    " Mason
+  elseif s:line1 =~ '^<[%&].*>'
+    set ft=mason
+
+    " Vim scripts (must have '" vim' as the first line to trigger this)
+  elseif s:line1 =~ '^" *[vV]im$'
+    set ft=vim
+
+    " MOO
+  elseif s:line1 =~ '^\*\* LambdaMOO Database, Format Version \%([1-3]\>\)\@!\d\+ \*\*$'
+    set ft=moo
+
+    " Diff file:
+    " - "diff" in first line (context diff)
+    " - "Only in " in first line
+    " - "--- " in first line and "+++ " in second line (unified diff).
+    " - "*** " in first line and "--- " in second line (context diff).
+    " - "# It was generated by makepatch " in the second line (makepatch diff).
+    " - "Index: <filename>" in the first line (CVS file)
+    " - "=== ", line of "=", "---", "+++ " (SVK diff)
+    " - "=== ", "--- ", "+++ " (bzr diff, common case)
+    " - "=== (removed|added|renamed|modified)" (bzr diff, alternative)
+  elseif s:line1 =~ '^\(diff\>\|Only in \|\d\+\(,\d\+\)\=[cda]\d\+\>\|# It was generated by makepatch \|Index:\s\+\f\+\r\=$\|===== \f\+ \d\+\.\d\+ vs edited\|==== //\f\+#\d\+\)'
+	\ || (s:line1 =~ '^--- ' && s:line2 =~ '^+++ ')
+	\ || (s:line1 =~ '^\* looking for ' && s:line2 =~ '^\* comparing to ')
+	\ || (s:line1 =~ '^\*\*\* ' && s:line2 =~ '^--- ')
+	\ || (s:line1 =~ '^=== ' && ((s:line2 =~ '^=\{66\}' && s:line3 =~ '^--- ' && s:line4 =~ '^+++') || (s:line2 =~ '^--- ' && s:line3 =~ '^+++ ')))
+	\ || (s:line1 =~ '^=== \(removed\|added\|renamed\|modified\)')
+    set ft=diff
+
+    " PostScript Files (must have %!PS as the first line, like a2ps output)
+  elseif s:line1 =~ '^%![ \t]*PS'
+    set ft=postscr
+
+    " M4 scripts: Guess there is a line that starts with "dnl".
+  elseif s:line1 =~ '^\s*dnl\>'
+	\ || s:line2 =~ '^\s*dnl\>'
+	\ || s:line3 =~ '^\s*dnl\>'
+	\ || s:line4 =~ '^\s*dnl\>'
+	\ || s:line5 =~ '^\s*dnl\>'
+    set ft=m4
+
+    " AmigaDos scripts
+  elseif $TERM == "amiga"
+	\ && (s:line1 =~ "^;" || s:line1 =~ '^\.[bB][rR][aA]')
+    set ft=amiga
+
+    " SiCAD scripts (must have procn or procd as the first line to trigger this)
+  elseif s:line1 =~? '^ *proc[nd] *$'
+    set ft=sicad
+
+    " Purify log files start with "****  Purify"
+  elseif s:line1 =~ '^\*\*\*\*  Purify'
+    set ft=purifylog
+
+    " XML
+  elseif s:line1 =~ '<?\s*xml.*?>'
+    set ft=xml
+
+    " XHTML (e.g.: PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN")
+  elseif s:line1 =~ '\<DTD\s\+XHTML\s'
+    set ft=xhtml
+
+    " XXD output
+  elseif s:line1 =~ '^\x\{7}: \x\{2} \=\x\{2} \=\x\{2} \=\x\{2} '
+    set ft=xxd
+
+    " RCS/CVS log output
+  elseif s:line1 =~ '^RCS file:' || s:line2 =~ '^RCS file:'
+    set ft=rcslog
+
+    " CVS commit
+  elseif s:line2 =~ '^CVS:' || getline("$") =~ '^CVS: '
+    set ft=cvs
+
+    " Prescribe
+  elseif s:line1 =~ '^!R!'
+    set ft=prescribe
+
+    " Send-pr
+  elseif s:line1 =~ '^SEND-PR:'
+    set ft=sendpr
+
+    " SNNS files
+  elseif s:line1 =~ '^SNNS network definition file'
+    set ft=snnsnet
+  elseif s:line1 =~ '^SNNS pattern definition file'
+    set ft=snnspat
+  elseif s:line1 =~ '^SNNS result file'
+    set ft=snnsres
+
+    " Virata
+  elseif s:line1 =~ '^%.\{-}[Vv]irata'
+	\ || s:line2 =~ '^%.\{-}[Vv]irata'
+	\ || s:line3 =~ '^%.\{-}[Vv]irata'
+	\ || s:line4 =~ '^%.\{-}[Vv]irata'
+	\ || s:line5 =~ '^%.\{-}[Vv]irata'
+    set ft=virata
+
+    " Strace
+  elseif s:line1 =~ '^[0-9]* *execve('
+    set ft=strace
+
+    " VSE JCL
+  elseif s:line1 =~ '^\* $$ JOB\>' || s:line1 =~ '^// *JOB\>'
+    set ft=vsejcl
+
+    " TAK and SINDA
+  elseif s:line4 =~ 'K & K  Associates' || s:line2 =~ 'TAK 2000'
+    set ft=takout
+  elseif s:line3 =~ 'S Y S T E M S   I M P R O V E D '
+    set ft=sindaout
+  elseif getline(6) =~ 'Run Date: '
+    set ft=takcmp
+  elseif getline(9) =~ 'Node    File  1'
+    set ft=sindacmp
+
+    " DNS zone files
+  elseif s:line1.s:line2.s:line3.s:line4 =~ '^; <<>> DiG [0-9.]\+ <<>>\|BIND.*named\|$ORIGIN\|$TTL\|IN\s\+SOA'
+    set ft=bindzone
+
+    " BAAN
+  elseif s:line1 =~ '|\*\{1,80}' && s:line2 =~ 'VRC '
+	\ || s:line2 =~ '|\*\{1,80}' && s:line3 =~ 'VRC '
+    set ft=baan
+
+  " Valgrind
+  elseif s:line1 =~ '^==\d\+== valgrind' || s:line3 =~ '^==\d\+== Using valgrind'
+    set ft=valgrind
+
+  " Renderman Interface Bytestream
+  elseif s:line1 =~ '^##RenderMan'
+    set ft=rib
+
+  " Scheme scripts
+  elseif s:line1 =~ 'exec\s\+\S*scheme' || s:line2 =~ 'exec\s\+\S*scheme'
+    set ft=scheme
+
+  " CVS diff
+  else
+    let lnum = 1
+    while getline(lnum) =~ "^? " && lnum < line("$")
+      let lnum = lnum + 1
+    endwhile
+    if getline(lnum) =~ '^Index:\s\+\f\+$'
+      set ft=diff
+
+      " locale input files: Formal Definitions of Cultural Conventions
+      " filename must be like en_US, fr_FR@euro or en_US.UTF-8
+    elseif expand("%") =~ '\a\a_\a\a\($\|[.@]\)\|i18n$\|POSIX$\|translit_'
+      let lnum = 1
+      while lnum < 100 && lnum < line("$")
+	if getline(lnum) =~ '^LC_\(IDENTIFICATION\|CTYPE\|COLLATE\|MONETARY\|NUMERIC\|TIME\|MESSAGES\|PAPER\|TELEPHONE\|MEASUREMENT\|NAME\|ADDRESS\)$'
+	  setf fdcc
+	  break
+	endif
+	let lnum = lnum + 1
+      endwhile
+    endif
+
+  endif
+
+  unlet s:line2 s:line3 s:line4 s:line5
+
+endif
+
+" Restore 'cpoptions'
+let &cpo = s:cpo_save
+
+unlet s:cpo_save s:line1
--- /dev/null
+++ b/lib/vimfiles/synmenu.vim
@@ -1,0 +1,549 @@
+" Vim support file to define the syntax selection menu
+" This file is normally sourced from menu.vim.
+"
+" Maintainer:	Bram Moolenaar <Bram@vim.org>
+" Last Change:	2006 Apr 27
+
+" Define the SetSyn function, used for the Syntax menu entries.
+" Set 'filetype' and also 'syntax' if it is manually selected.
+fun! SetSyn(name)
+  if a:name == "fvwm1"
+    let use_fvwm_1 = 1
+    let use_fvwm_2 = 0
+    let name = "fvwm"
+  elseif a:name == "fvwm2"
+    let use_fvwm_2 = 1
+    let use_fvwm_1 = 0
+    let name = "fvwm"
+  else
+    let name = a:name
+  endif
+  if !exists("s:syntax_menu_synonly")
+    exe "set ft=" . name
+    if exists("g:syntax_manual")
+      exe "set syn=" . name
+    endif
+  else
+    exe "set syn=" . name
+  endif
+endfun
+
+" <> notation is used here, remove '<' from 'cpoptions'
+let s:cpo_save = &cpo
+set cpo&vim
+
+" The following menu items are generated by makemenu.vim.
+" The Start Of The Syntax Menu
+
+an 50.10.100 &Syntax.AB.A2ps\ config :cal SetSyn("a2ps")<CR>
+an 50.10.110 &Syntax.AB.Aap :cal SetSyn("aap")<CR>
+an 50.10.120 &Syntax.AB.ABAP/4 :cal SetSyn("abap")<CR>
+an 50.10.130 &Syntax.AB.Abaqus :cal SetSyn("abaqus")<CR>
+an 50.10.140 &Syntax.AB.ABC\ music\ notation :cal SetSyn("abc")<CR>
+an 50.10.150 &Syntax.AB.ABEL :cal SetSyn("abel")<CR>
+an 50.10.160 &Syntax.AB.AceDB\ model :cal SetSyn("acedb")<CR>
+an 50.10.170 &Syntax.AB.Ada :cal SetSyn("ada")<CR>
+an 50.10.180 &Syntax.AB.AfLex :cal SetSyn("aflex")<CR>
+an 50.10.190 &Syntax.AB.ALSA\ config :cal SetSyn("alsaconf")<CR>
+an 50.10.200 &Syntax.AB.Altera\ AHDL :cal SetSyn("ahdl")<CR>
+an 50.10.210 &Syntax.AB.Amiga\ DOS :cal SetSyn("amiga")<CR>
+an 50.10.220 &Syntax.AB.AMPL :cal SetSyn("ampl")<CR>
+an 50.10.230 &Syntax.AB.Ant\ build\ file :cal SetSyn("ant")<CR>
+an 50.10.240 &Syntax.AB.ANTLR :cal SetSyn("antlr")<CR>
+an 50.10.250 &Syntax.AB.Apache\ config :cal SetSyn("apache")<CR>
+an 50.10.260 &Syntax.AB.Apache-style\ config :cal SetSyn("apachestyle")<CR>
+an 50.10.270 &Syntax.AB.Applix\ ELF :cal SetSyn("elf")<CR>
+an 50.10.280 &Syntax.AB.Arc\ Macro\ Language :cal SetSyn("aml")<CR>
+an 50.10.290 &Syntax.AB.Arch\ inventory :cal SetSyn("arch")<CR>
+an 50.10.300 &Syntax.AB.ART :cal SetSyn("art")<CR>
+an 50.10.310 &Syntax.AB.ASP\ with\ VBScript :cal SetSyn("aspvbs")<CR>
+an 50.10.320 &Syntax.AB.ASP\ with\ Perl :cal SetSyn("aspperl")<CR>
+an 50.10.330 &Syntax.AB.Assembly.680x0 :cal SetSyn("asm68k")<CR>
+an 50.10.340 &Syntax.AB.Assembly.Flat :cal SetSyn("fasm")<CR>
+an 50.10.350 &Syntax.AB.Assembly.GNU :cal SetSyn("asm")<CR>
+an 50.10.360 &Syntax.AB.Assembly.GNU\ H-8300 :cal SetSyn("asmh8300")<CR>
+an 50.10.370 &Syntax.AB.Assembly.Intel\ IA-64 :cal SetSyn("ia64")<CR>
+an 50.10.380 &Syntax.AB.Assembly.Microsoft :cal SetSyn("masm")<CR>
+an 50.10.390 &Syntax.AB.Assembly.Netwide :cal SetSyn("nasm")<CR>
+an 50.10.400 &Syntax.AB.Assembly.PIC :cal SetSyn("pic")<CR>
+an 50.10.410 &Syntax.AB.Assembly.Turbo :cal SetSyn("tasm")<CR>
+an 50.10.420 &Syntax.AB.Assembly.VAX\ Macro\ Assembly :cal SetSyn("vmasm")<CR>
+an 50.10.430 &Syntax.AB.Assembly.Z-80 :cal SetSyn("z8a")<CR>
+an 50.10.440 &Syntax.AB.Assembly.xa\ 6502\ cross\ assember :cal SetSyn("a65")<CR>
+an 50.10.450 &Syntax.AB.ASN\.1 :cal SetSyn("asn")<CR>
+an 50.10.460 &Syntax.AB.Asterisk\ config :cal SetSyn("asterisk")<CR>
+an 50.10.470 &Syntax.AB.Asterisk\ voicemail\ config :cal SetSyn("asteriskvm")<CR>
+an 50.10.480 &Syntax.AB.Atlas :cal SetSyn("atlas")<CR>
+an 50.10.490 &Syntax.AB.AutoHotKey :cal SetSyn("autohotkey")<CR>
+an 50.10.500 &Syntax.AB.AutoIt :cal SetSyn("autoit")<CR>
+an 50.10.510 &Syntax.AB.Automake :cal SetSyn("automake")<CR>
+an 50.10.520 &Syntax.AB.Avenue :cal SetSyn("ave")<CR>
+an 50.10.530 &Syntax.AB.Awk :cal SetSyn("awk")<CR>
+an 50.10.540 &Syntax.AB.AYacc :cal SetSyn("ayacc")<CR>
+an 50.10.560 &Syntax.AB.B :cal SetSyn("b")<CR>
+an 50.10.570 &Syntax.AB.Baan :cal SetSyn("baan")<CR>
+an 50.10.580 &Syntax.AB.Basic.FreeBasic :cal SetSyn("freebasic")<CR>
+an 50.10.590 &Syntax.AB.Basic.IBasic :cal SetSyn("ibasic")<CR>
+an 50.10.600 &Syntax.AB.Basic.QBasic :cal SetSyn("basic")<CR>
+an 50.10.610 &Syntax.AB.Basic.Visual\ Basic :cal SetSyn("vb")<CR>
+an 50.10.620 &Syntax.AB.Bazaar\ commit\ file :cal SetSyn("bzr")<CR>
+an 50.10.630 &Syntax.AB.BC\ calculator :cal SetSyn("bc")<CR>
+an 50.10.640 &Syntax.AB.BDF\ font :cal SetSyn("bdf")<CR>
+an 50.10.650 &Syntax.AB.BibTeX.Bibliography\ database :cal SetSyn("bib")<CR>
+an 50.10.660 &Syntax.AB.BibTeX.Bibliography\ Style :cal SetSyn("bst")<CR>
+an 50.10.670 &Syntax.AB.BIND.BIND\ config :cal SetSyn("named")<CR>
+an 50.10.680 &Syntax.AB.BIND.BIND\ zone :cal SetSyn("bindzone")<CR>
+an 50.10.690 &Syntax.AB.Blank :cal SetSyn("blank")<CR>
+an 50.20.100 &Syntax.C.C :cal SetSyn("c")<CR>
+an 50.20.110 &Syntax.C.C++ :cal SetSyn("cpp")<CR>
+an 50.20.120 &Syntax.C.C# :cal SetSyn("cs")<CR>
+an 50.20.130 &Syntax.C.Calendar :cal SetSyn("calendar")<CR>
+an 50.20.140 &Syntax.C.Cascading\ Style\ Sheets :cal SetSyn("css")<CR>
+an 50.20.150 &Syntax.C.CDL :cal SetSyn("cdl")<CR>
+an 50.20.160 &Syntax.C.Cdrdao\ TOC :cal SetSyn("cdrtoc")<CR>
+an 50.20.170 &Syntax.C.Century\ Term :cal SetSyn("cterm")<CR>
+an 50.20.180 &Syntax.C.CH\ script :cal SetSyn("ch")<CR>
+an 50.20.190 &Syntax.C.ChangeLog :cal SetSyn("changelog")<CR>
+an 50.20.200 &Syntax.C.Cheetah\ template :cal SetSyn("cheetah")<CR>
+an 50.20.210 &Syntax.C.CHILL :cal SetSyn("chill")<CR>
+an 50.20.220 &Syntax.C.ChordPro :cal SetSyn("chordpro")<CR>
+an 50.20.230 &Syntax.C.Clean :cal SetSyn("clean")<CR>
+an 50.20.240 &Syntax.C.Clever :cal SetSyn("cl")<CR>
+an 50.20.250 &Syntax.C.Clipper :cal SetSyn("clipper")<CR>
+an 50.20.260 &Syntax.C.Cmake :cal SetSyn("cmake")<CR>
+an 50.20.270 &Syntax.C.Cmusrc :cal SetSyn("cmusrc")<CR>
+an 50.20.280 &Syntax.C.Cobol :cal SetSyn("cobol")<CR>
+an 50.20.290 &Syntax.C.Cold\ Fusion :cal SetSyn("cf")<CR>
+an 50.20.300 &Syntax.C.Conary\ Recipe :cal SetSyn("conaryrecipe")<CR>
+an 50.20.310 &Syntax.C.Config.Cfg\ Config\ file :cal SetSyn("cfg")<CR>
+an 50.20.320 &Syntax.C.Config.Configure\.in :cal SetSyn("config")<CR>
+an 50.20.330 &Syntax.C.Config.Generic\ Config\ file :cal SetSyn("conf")<CR>
+an 50.20.340 &Syntax.C.CRM114 :cal SetSyn("crm")<CR>
+an 50.20.350 &Syntax.C.Crontab :cal SetSyn("crontab")<CR>
+an 50.20.360 &Syntax.C.CSP :cal SetSyn("csp")<CR>
+an 50.20.370 &Syntax.C.Ctrl-H :cal SetSyn("ctrlh")<CR>
+an 50.20.380 &Syntax.C.CUPL.CUPL :cal SetSyn("cupl")<CR>
+an 50.20.390 &Syntax.C.CUPL.Simulation :cal SetSyn("cuplsim")<CR>
+an 50.20.400 &Syntax.C.CVS.commit\ file :cal SetSyn("cvs")<CR>
+an 50.20.410 &Syntax.C.CVS.cvsrc :cal SetSyn("cvsrc")<CR>
+an 50.20.420 &Syntax.C.Cyn++ :cal SetSyn("cynpp")<CR>
+an 50.20.430 &Syntax.C.Cynlib :cal SetSyn("cynlib")<CR>
+an 50.30.100 &Syntax.DE.D :cal SetSyn("d")<CR>
+an 50.30.110 &Syntax.DE.Debian.Debian\ ChangeLog :cal SetSyn("debchangelog")<CR>
+an 50.30.120 &Syntax.DE.Debian.Debian\ Control :cal SetSyn("debcontrol")<CR>
+an 50.30.130 &Syntax.DE.Debian.Debian\ Sources\.list :cal SetSyn("debsources")<CR>
+an 50.30.140 &Syntax.DE.Desktop :cal SetSyn("desktop")<CR>
+an 50.30.150 &Syntax.DE.Dict\ config :cal SetSyn("dictconf")<CR>
+an 50.30.160 &Syntax.DE.Dictd\ config :cal SetSyn("dictdconf")<CR>
+an 50.30.170 &Syntax.DE.Diff :cal SetSyn("diff")<CR>
+an 50.30.180 &Syntax.DE.Digital\ Command\ Lang :cal SetSyn("dcl")<CR>
+an 50.30.190 &Syntax.DE.Dircolors :cal SetSyn("dircolors")<CR>
+an 50.30.200 &Syntax.DE.Django\ template :cal SetSyn("django")<CR>
+an 50.30.210 &Syntax.DE.DNS/BIND\ zone :cal SetSyn("bindzone")<CR>
+an 50.30.220 &Syntax.DE.DocBook.auto-detect :cal SetSyn("docbk")<CR>
+an 50.30.230 &Syntax.DE.DocBook.SGML :cal SetSyn("docbksgml")<CR>
+an 50.30.240 &Syntax.DE.DocBook.XML :cal SetSyn("docbkxml")<CR>
+an 50.30.250 &Syntax.DE.Dot :cal SetSyn("dot")<CR>
+an 50.30.260 &Syntax.DE.Doxygen.C\ with\ doxygen :cal SetSyn("c.doxygen")<CR>
+an 50.30.270 &Syntax.DE.Doxygen.C++\ with\ doxygen :cal SetSyn("cpp.doxygen")<CR>
+an 50.30.280 &Syntax.DE.Doxygen.IDL\ with\ doxygen :cal SetSyn("idl.doxygen")<CR>
+an 50.30.290 &Syntax.DE.Doxygen.Java\ with\ doxygen :cal SetSyn("java.doxygen")<CR>
+an 50.30.300 &Syntax.DE.Dracula :cal SetSyn("dracula")<CR>
+an 50.30.310 &Syntax.DE.DSSSL :cal SetSyn("dsl")<CR>
+an 50.30.320 &Syntax.DE.DTD :cal SetSyn("dtd")<CR>
+an 50.30.330 &Syntax.DE.DTML\ (Zope) :cal SetSyn("dtml")<CR>
+an 50.30.340 &Syntax.DE.Dylan.Dylan :cal SetSyn("dylan")<CR>
+an 50.30.350 &Syntax.DE.Dylan.Dylan\ interface :cal SetSyn("dylanintr")<CR>
+an 50.30.360 &Syntax.DE.Dylan.Dylan\ lid :cal SetSyn("dylanlid")<CR>
+an 50.30.380 &Syntax.DE.EDIF :cal SetSyn("edif")<CR>
+an 50.30.390 &Syntax.DE.Eiffel :cal SetSyn("eiffel")<CR>
+an 50.30.400 &Syntax.DE.Elinks\ config :cal SetSyn("elinks")<CR>
+an 50.30.410 &Syntax.DE.Elm\ filter\ rules :cal SetSyn("elmfilt")<CR>
+an 50.30.420 &Syntax.DE.Embedix\ Component\ Description :cal SetSyn("ecd")<CR>
+an 50.30.430 &Syntax.DE.ERicsson\ LANGuage :cal SetSyn("erlang")<CR>
+an 50.30.440 &Syntax.DE.ESMTP\ rc :cal SetSyn("esmtprc")<CR>
+an 50.30.450 &Syntax.DE.ESQL-C :cal SetSyn("esqlc")<CR>
+an 50.30.460 &Syntax.DE.Essbase\ script :cal SetSyn("csc")<CR>
+an 50.30.470 &Syntax.DE.Esterel :cal SetSyn("esterel")<CR>
+an 50.30.480 &Syntax.DE.Eterm\ config :cal SetSyn("eterm")<CR>
+an 50.30.490 &Syntax.DE.Eviews :cal SetSyn("eviews")<CR>
+an 50.30.500 &Syntax.DE.Exim\ conf :cal SetSyn("exim")<CR>
+an 50.30.510 &Syntax.DE.Expect :cal SetSyn("expect")<CR>
+an 50.30.520 &Syntax.DE.Exports :cal SetSyn("exports")<CR>
+an 50.40.100 &Syntax.FG.Fetchmail :cal SetSyn("fetchmail")<CR>
+an 50.40.110 &Syntax.FG.FlexWiki :cal SetSyn("flexwiki")<CR>
+an 50.40.120 &Syntax.FG.Focus\ Executable :cal SetSyn("focexec")<CR>
+an 50.40.130 &Syntax.FG.Focus\ Master :cal SetSyn("master")<CR>
+an 50.40.140 &Syntax.FG.FORM :cal SetSyn("form")<CR>
+an 50.40.150 &Syntax.FG.Forth :cal SetSyn("forth")<CR>
+an 50.40.160 &Syntax.FG.Fortran :cal SetSyn("fortran")<CR>
+an 50.40.170 &Syntax.FG.FoxPro :cal SetSyn("foxpro")<CR>
+an 50.40.180 &Syntax.FG.FrameScript :cal SetSyn("framescript")<CR>
+an 50.40.190 &Syntax.FG.Fstab :cal SetSyn("fstab")<CR>
+an 50.40.200 &Syntax.FG.Fvwm.Fvwm\ configuration :cal SetSyn("fvwm1")<CR>
+an 50.40.210 &Syntax.FG.Fvwm.Fvwm2\ configuration :cal SetSyn("fvwm2")<CR>
+an 50.40.220 &Syntax.FG.Fvwm.Fvwm2\ configuration\ with\ M4 :cal SetSyn("fvwm2m4")<CR>
+an 50.40.240 &Syntax.FG.GDB\ command\ file :cal SetSyn("gdb")<CR>
+an 50.40.250 &Syntax.FG.GDMO :cal SetSyn("gdmo")<CR>
+an 50.40.260 &Syntax.FG.Gedcom :cal SetSyn("gedcom")<CR>
+an 50.40.270 &Syntax.FG.Gkrellmrc :cal SetSyn("gkrellmrc")<CR>
+an 50.40.280 &Syntax.FG.GP :cal SetSyn("gp")<CR>
+an 50.40.290 &Syntax.FG.GPG :cal SetSyn("gpg")<CR>
+an 50.40.300 &Syntax.FG.Group\ file :cal SetSyn("group")<CR>
+an 50.40.310 &Syntax.FG.Grub :cal SetSyn("grub")<CR>
+an 50.40.320 &Syntax.FG.GNU\ Server\ Pages :cal SetSyn("gsp")<CR>
+an 50.40.330 &Syntax.FG.GNUplot :cal SetSyn("gnuplot")<CR>
+an 50.40.340 &Syntax.FG.GrADS\ scripts :cal SetSyn("grads")<CR>
+an 50.40.350 &Syntax.FG.Gretl :cal SetSyn("gretl")<CR>
+an 50.40.360 &Syntax.FG.Groff :cal SetSyn("groff")<CR>
+an 50.40.370 &Syntax.FG.Groovy :cal SetSyn("groovy")<CR>
+an 50.40.380 &Syntax.FG.GTKrc :cal SetSyn("gtkrc")<CR>
+an 50.50.100 &Syntax.HIJK.Hamster :cal SetSyn("hamster")<CR>
+an 50.50.110 &Syntax.HIJK.Haskell.Haskell :cal SetSyn("haskell")<CR>
+an 50.50.120 &Syntax.HIJK.Haskell.Haskell-c2hs :cal SetSyn("chaskell")<CR>
+an 50.50.130 &Syntax.HIJK.Haskell.Haskell-literate :cal SetSyn("lhaskell")<CR>
+an 50.50.140 &Syntax.HIJK.Hercules :cal SetSyn("hercules")<CR>
+an 50.50.150 &Syntax.HIJK.Hex\ dump.XXD :cal SetSyn("xxd")<CR>
+an 50.50.160 &Syntax.HIJK.Hex\ dump.Intel\ MCS51 :cal SetSyn("hex")<CR>
+an 50.50.170 &Syntax.HIJK.HTML.HTML :cal SetSyn("html")<CR>
+an 50.50.180 &Syntax.HIJK.HTML.HTML\ with\ M4 :cal SetSyn("htmlm4")<CR>
+an 50.50.190 &Syntax.HIJK.HTML.HTML\ with\ Ruby\ (eRuby) :cal SetSyn("eruby")<CR>
+an 50.50.200 &Syntax.HIJK.HTML.Cheetah\ HTML\ template :cal SetSyn("htmlcheetah")<CR>
+an 50.50.210 &Syntax.HIJK.HTML.Django\ HTML\ template :cal SetSyn("htmldjango")<CR>
+an 50.50.220 &Syntax.HIJK.HTML.HTML/OS :cal SetSyn("htmlos")<CR>
+an 50.50.230 &Syntax.HIJK.HTML.XHTML :cal SetSyn("xhtml")<CR>
+an 50.50.240 &Syntax.HIJK.Hyper\ Builder :cal SetSyn("hb")<CR>
+an 50.50.260 &Syntax.HIJK.Icewm\ menu :cal SetSyn("icemenu")<CR>
+an 50.50.270 &Syntax.HIJK.Icon :cal SetSyn("icon")<CR>
+an 50.50.280 &Syntax.HIJK.IDL\Generic\ IDL :cal SetSyn("idl")<CR>
+an 50.50.290 &Syntax.HIJK.IDL\Microsoft\ IDL :cal SetSyn("msidl")<CR>
+an 50.50.300 &Syntax.HIJK.Indent\ profile :cal SetSyn("indent")<CR>
+an 50.50.310 &Syntax.HIJK.Inform :cal SetSyn("inform")<CR>
+an 50.50.320 &Syntax.HIJK.Informix\ 4GL :cal SetSyn("fgl")<CR>
+an 50.50.330 &Syntax.HIJK.Initng :cal SetSyn("initng")<CR>
+an 50.50.340 &Syntax.HIJK.Inittab :cal SetSyn("inittab")<CR>
+an 50.50.350 &Syntax.HIJK.Inno\ setup :cal SetSyn("iss")<CR>
+an 50.50.360 &Syntax.HIJK.InstallShield\ script :cal SetSyn("ishd")<CR>
+an 50.50.370 &Syntax.HIJK.Interactive\ Data\ Lang :cal SetSyn("idlang")<CR>
+an 50.50.380 &Syntax.HIJK.IPfilter :cal SetSyn("ipfilter")<CR>
+an 50.50.400 &Syntax.HIJK.JAL :cal SetSyn("jal")<CR>
+an 50.50.410 &Syntax.HIJK.JAM :cal SetSyn("jam")<CR>
+an 50.50.420 &Syntax.HIJK.Jargon :cal SetSyn("jargon")<CR>
+an 50.50.430 &Syntax.HIJK.Java.Java :cal SetSyn("java")<CR>
+an 50.50.440 &Syntax.HIJK.Java.JavaCC :cal SetSyn("javacc")<CR>
+an 50.50.450 &Syntax.HIJK.Java.Java\ Server\ Pages :cal SetSyn("jsp")<CR>
+an 50.50.460 &Syntax.HIJK.Java.Java\ Properties :cal SetSyn("jproperties")<CR>
+an 50.50.470 &Syntax.HIJK.JavaScript :cal SetSyn("javascript")<CR>
+an 50.50.480 &Syntax.HIJK.Jess :cal SetSyn("jess")<CR>
+an 50.50.490 &Syntax.HIJK.Jgraph :cal SetSyn("jgraph")<CR>
+an 50.50.510 &Syntax.HIJK.Kconfig :cal SetSyn("kconfig")<CR>
+an 50.50.520 &Syntax.HIJK.KDE\ script :cal SetSyn("kscript")<CR>
+an 50.50.530 &Syntax.HIJK.Kimwitu++ :cal SetSyn("kwt")<CR>
+an 50.50.540 &Syntax.HIJK.KixTart :cal SetSyn("kix")<CR>
+an 50.60.100 &Syntax.L-Ma.Lace :cal SetSyn("lace")<CR>
+an 50.60.110 &Syntax.L-Ma.LamdaProlog :cal SetSyn("lprolog")<CR>
+an 50.60.120 &Syntax.L-Ma.Latte :cal SetSyn("latte")<CR>
+an 50.60.130 &Syntax.L-Ma.Ld\ script :cal SetSyn("ld")<CR>
+an 50.60.140 &Syntax.L-Ma.LDAP.LDIF :cal SetSyn("ldif")<CR>
+an 50.60.150 &Syntax.L-Ma.LDAP.Configuration :cal SetSyn("ldapconf")<CR>
+an 50.60.160 &Syntax.L-Ma.Lex :cal SetSyn("lex")<CR>
+an 50.60.170 &Syntax.L-Ma.LFTP\ config :cal SetSyn("lftp")<CR>
+an 50.60.180 &Syntax.L-Ma.Libao :cal SetSyn("libao")<CR>
+an 50.60.190 &Syntax.L-Ma.LifeLines\ script :cal SetSyn("lifelines")<CR>
+an 50.60.200 &Syntax.L-Ma.Lilo :cal SetSyn("lilo")<CR>
+an 50.60.210 &Syntax.L-Ma.Limits\ config :cal SetSyn("limits")<CR>
+an 50.60.220 &Syntax.L-Ma.Lisp :cal SetSyn("lisp")<CR>
+an 50.60.230 &Syntax.L-Ma.Lite :cal SetSyn("lite")<CR>
+an 50.60.240 &Syntax.L-Ma.LiteStep\ RC :cal SetSyn("litestep")<CR>
+an 50.60.250 &Syntax.L-Ma.Locale\ Input :cal SetSyn("fdcc")<CR>
+an 50.60.260 &Syntax.L-Ma.Login\.access :cal SetSyn("loginaccess")<CR>
+an 50.60.270 &Syntax.L-Ma.Login\.defs :cal SetSyn("logindefs")<CR>
+an 50.60.280 &Syntax.L-Ma.Logtalk :cal SetSyn("logtalk")<CR>
+an 50.60.290 &Syntax.L-Ma.LOTOS :cal SetSyn("lotos")<CR>
+an 50.60.300 &Syntax.L-Ma.LotusScript :cal SetSyn("lscript")<CR>
+an 50.60.310 &Syntax.L-Ma.Lout :cal SetSyn("lout")<CR>
+an 50.60.320 &Syntax.L-Ma.LPC :cal SetSyn("lpc")<CR>
+an 50.60.330 &Syntax.L-Ma.Lua :cal SetSyn("lua")<CR>
+an 50.60.340 &Syntax.L-Ma.Lynx\ Style :cal SetSyn("lss")<CR>
+an 50.60.350 &Syntax.L-Ma.Lynx\ config :cal SetSyn("lynx")<CR>
+an 50.60.370 &Syntax.L-Ma.M4 :cal SetSyn("m4")<CR>
+an 50.60.380 &Syntax.L-Ma.MaGic\ Point :cal SetSyn("mgp")<CR>
+an 50.60.390 &Syntax.L-Ma.Mail :cal SetSyn("mail")<CR>
+an 50.60.400 &Syntax.L-Ma.Mail\ aliases :cal SetSyn("mailaliases")<CR>
+an 50.60.410 &Syntax.L-Ma.Mailcap :cal SetSyn("mailcap")<CR>
+an 50.60.420 &Syntax.L-Ma.Makefile :cal SetSyn("make")<CR>
+an 50.60.430 &Syntax.L-Ma.MakeIndex :cal SetSyn("ist")<CR>
+an 50.60.440 &Syntax.L-Ma.Man\ page :cal SetSyn("man")<CR>
+an 50.60.450 &Syntax.L-Ma.Man\.conf :cal SetSyn("manconf")<CR>
+an 50.60.460 &Syntax.L-Ma.Maple\ V :cal SetSyn("maple")<CR>
+an 50.60.470 &Syntax.L-Ma.Mason :cal SetSyn("mason")<CR>
+an 50.60.480 &Syntax.L-Ma.Mathematica :cal SetSyn("mma")<CR>
+an 50.60.490 &Syntax.L-Ma.Matlab :cal SetSyn("matlab")<CR>
+an 50.60.500 &Syntax.L-Ma.Maxima :cal SetSyn("maxima")<CR>
+an 50.70.100 &Syntax.Me-NO.MEL\ (for\ Maya) :cal SetSyn("mel")<CR>
+an 50.70.110 &Syntax.Me-NO.Messages\ (/var/log) :cal SetSyn("messages")<CR>
+an 50.70.120 &Syntax.Me-NO.Metafont :cal SetSyn("mf")<CR>
+an 50.70.130 &Syntax.Me-NO.MetaPost :cal SetSyn("mp")<CR>
+an 50.70.140 &Syntax.Me-NO.MGL :cal SetSyn("mgl")<CR>
+an 50.70.150 &Syntax.Me-NO.MMIX :cal SetSyn("mmix")<CR>
+an 50.70.160 &Syntax.Me-NO.Modconf :cal SetSyn("modconf")<CR>
+an 50.70.170 &Syntax.Me-NO.Model :cal SetSyn("model")<CR>
+an 50.70.180 &Syntax.Me-NO.Modsim\ III :cal SetSyn("modsim3")<CR>
+an 50.70.190 &Syntax.Me-NO.Modula\ 2 :cal SetSyn("modula2")<CR>
+an 50.70.200 &Syntax.Me-NO.Modula\ 3 :cal SetSyn("modula3")<CR>
+an 50.70.210 &Syntax.Me-NO.Monk :cal SetSyn("monk")<CR>
+an 50.70.220 &Syntax.Me-NO.Mplayer\ config :cal SetSyn("mplayerconf")<CR>
+an 50.70.230 &Syntax.Me-NO.MOO :cal SetSyn("moo")<CR>
+an 50.70.240 &Syntax.Me-NO.Mrxvtrc :cal SetSyn("mrxvtrc")<CR>
+an 50.70.250 &Syntax.Me-NO.MS-DOS/Windows.4DOS\ \.bat\ file :cal SetSyn("btm")<CR>
+an 50.70.260 &Syntax.Me-NO.MS-DOS/Windows.\.bat\/\.cmd\ file :cal SetSyn("dosbatch")<CR>
+an 50.70.270 &Syntax.Me-NO.MS-DOS/Windows.\.ini\ file :cal SetSyn("dosini")<CR>
+an 50.70.280 &Syntax.Me-NO.MS-DOS/Windows.Module\ Definition :cal SetSyn("def")<CR>
+an 50.70.290 &Syntax.Me-NO.MS-DOS/Windows.Registry :cal SetSyn("registry")<CR>
+an 50.70.300 &Syntax.Me-NO.MS-DOS/Windows.Resource\ file :cal SetSyn("rc")<CR>
+an 50.70.310 &Syntax.Me-NO.Msql :cal SetSyn("msql")<CR>
+an 50.70.320 &Syntax.Me-NO.MuPAD :cal SetSyn("mupad")<CR>
+an 50.70.330 &Syntax.Me-NO.MUSHcode :cal SetSyn("mush")<CR>
+an 50.70.340 &Syntax.Me-NO.Muttrc :cal SetSyn("muttrc")<CR>
+an 50.70.360 &Syntax.Me-NO.Nanorc :cal SetSyn("nanorc")<CR>
+an 50.70.370 &Syntax.Me-NO.Nastran\ input/DMAP :cal SetSyn("nastran")<CR>
+an 50.70.380 &Syntax.Me-NO.Natural :cal SetSyn("natural")<CR>
+an 50.70.390 &Syntax.Me-NO.Netrc :cal SetSyn("netrc")<CR>
+an 50.70.400 &Syntax.Me-NO.Novell\ NCF\ batch :cal SetSyn("ncf")<CR>
+an 50.70.410 &Syntax.Me-NO.Not\ Quite\ C\ (LEGO) :cal SetSyn("nqc")<CR>
+an 50.70.420 &Syntax.Me-NO.Nroff :cal SetSyn("nroff")<CR>
+an 50.70.430 &Syntax.Me-NO.NSIS\ script :cal SetSyn("nsis")<CR>
+an 50.70.450 &Syntax.Me-NO.Objective\ C :cal SetSyn("objc")<CR>
+an 50.70.460 &Syntax.Me-NO.Objective\ C++ :cal SetSyn("objcpp")<CR>
+an 50.70.470 &Syntax.Me-NO.OCAML :cal SetSyn("ocaml")<CR>
+an 50.70.480 &Syntax.Me-NO.Occam :cal SetSyn("occam")<CR>
+an 50.70.490 &Syntax.Me-NO.Omnimark :cal SetSyn("omnimark")<CR>
+an 50.70.500 &Syntax.Me-NO.OpenROAD :cal SetSyn("openroad")<CR>
+an 50.70.510 &Syntax.Me-NO.Open\ Psion\ Lang :cal SetSyn("opl")<CR>
+an 50.70.520 &Syntax.Me-NO.Oracle\ config :cal SetSyn("ora")<CR>
+an 50.80.100 &Syntax.PQ.Packet\ filter\ conf :cal SetSyn("pf")<CR>
+an 50.80.110 &Syntax.PQ.Palm\ resource\ compiler :cal SetSyn("pilrc")<CR>
+an 50.80.120 &Syntax.PQ.Pam\ config :cal SetSyn("pamconf")<CR>
+an 50.80.130 &Syntax.PQ.PApp :cal SetSyn("papp")<CR>
+an 50.80.140 &Syntax.PQ.Pascal :cal SetSyn("pascal")<CR>
+an 50.80.150 &Syntax.PQ.Password\ file :cal SetSyn("passwd")<CR>
+an 50.80.160 &Syntax.PQ.PCCTS :cal SetSyn("pccts")<CR>
+an 50.80.170 &Syntax.PQ.PPWizard :cal SetSyn("ppwiz")<CR>
+an 50.80.180 &Syntax.PQ.Perl.Perl :cal SetSyn("perl")<CR>
+an 50.80.190 &Syntax.PQ.Perl.Perl\ POD :cal SetSyn("pod")<CR>
+an 50.80.200 &Syntax.PQ.Perl.Perl\ XS :cal SetSyn("xs")<CR>
+an 50.80.210 &Syntax.PQ.PHP.PHP\ 3-4 :cal SetSyn("php")<CR>
+an 50.80.220 &Syntax.PQ.PHP.Phtml\ (PHP\ 2) :cal SetSyn("phtml")<CR>
+an 50.80.230 &Syntax.PQ.Pike :cal SetSyn("pike")<CR>
+an 50.80.240 &Syntax.PQ.Pine\ RC :cal SetSyn("pine")<CR>
+an 50.80.250 &Syntax.PQ.Pinfo\ RC :cal SetSyn("pinfo")<CR>
+an 50.80.260 &Syntax.PQ.PL/M :cal SetSyn("plm")<CR>
+an 50.80.270 &Syntax.PQ.PL/SQL :cal SetSyn("plsql")<CR>
+an 50.80.280 &Syntax.PQ.PLP :cal SetSyn("plp")<CR>
+an 50.80.290 &Syntax.PQ.PO\ (GNU\ gettext) :cal SetSyn("po")<CR>
+an 50.80.300 &Syntax.PQ.Postfix\ main\ config :cal SetSyn("pfmain")<CR>
+an 50.80.310 &Syntax.PQ.PostScript.PostScript :cal SetSyn("postscr")<CR>
+an 50.80.320 &Syntax.PQ.PostScript.PostScript\ Printer\ Description :cal SetSyn("ppd")<CR>
+an 50.80.330 &Syntax.PQ.Povray.Povray\ scene\ descr :cal SetSyn("pov")<CR>
+an 50.80.340 &Syntax.PQ.Povray.Povray\ configuration :cal SetSyn("povini")<CR>
+an 50.80.350 &Syntax.PQ.Prescribe\ (Kyocera) :cal SetSyn("prescribe")<CR>
+an 50.80.360 &Syntax.PQ.Printcap :cal SetSyn("pcap")<CR>
+an 50.80.370 &Syntax.PQ.Privoxy :cal SetSyn("privoxy")<CR>
+an 50.80.380 &Syntax.PQ.Procmail :cal SetSyn("procmail")<CR>
+an 50.80.390 &Syntax.PQ.Product\ Spec\ File :cal SetSyn("psf")<CR>
+an 50.80.400 &Syntax.PQ.Progress :cal SetSyn("progress")<CR>
+an 50.80.410 &Syntax.PQ.Prolog :cal SetSyn("prolog")<CR>
+an 50.80.420 &Syntax.PQ.Protocols :cal SetSyn("protocols")<CR>
+an 50.80.430 &Syntax.PQ.Purify\ log :cal SetSyn("purifylog")<CR>
+an 50.80.440 &Syntax.PQ.Pyrex :cal SetSyn("pyrex")<CR>
+an 50.80.450 &Syntax.PQ.Python :cal SetSyn("python")<CR>
+an 50.80.470 &Syntax.PQ.Quake :cal SetSyn("quake")<CR>
+an 50.80.480 &Syntax.PQ.Quickfix\ window :cal SetSyn("qf")<CR>
+an 50.90.100 &Syntax.R-Sg.R.R :cal SetSyn("r")<CR>
+an 50.90.110 &Syntax.R-Sg.R.R\ help :cal SetSyn("rhelp")<CR>
+an 50.90.120 &Syntax.R-Sg.R.R\ noweb :cal SetSyn("rnoweb")<CR>
+an 50.90.130 &Syntax.R-Sg.Racc\ input :cal SetSyn("racc")<CR>
+an 50.90.140 &Syntax.R-Sg.Radiance :cal SetSyn("radiance")<CR>
+an 50.90.150 &Syntax.R-Sg.Ratpoison :cal SetSyn("ratpoison")<CR>
+an 50.90.160 &Syntax.R-Sg.RCS.RCS\ log\ output :cal SetSyn("rcslog")<CR>
+an 50.90.170 &Syntax.R-Sg.RCS.RCS\ file :cal SetSyn("rcs")<CR>
+an 50.90.180 &Syntax.R-Sg.Readline\ config :cal SetSyn("readline")<CR>
+an 50.90.190 &Syntax.R-Sg.Rebol :cal SetSyn("rebol")<CR>
+an 50.90.200 &Syntax.R-Sg.Remind :cal SetSyn("remind")<CR>
+an 50.90.210 &Syntax.R-Sg.Relax\ NG\ compact :cal SetSyn("rnc")<CR>
+an 50.90.220 &Syntax.R-Sg.Renderman.Renderman\ Shader\ Lang :cal SetSyn("sl")<CR>
+an 50.90.230 &Syntax.R-Sg.Renderman.Renderman\ Interface\ Bytestream :cal SetSyn("rib")<CR>
+an 50.90.240 &Syntax.R-Sg.Resolv\.conf :cal SetSyn("resolv")<CR>
+an 50.90.250 &Syntax.R-Sg.Rexx :cal SetSyn("rexx")<CR>
+an 50.90.260 &Syntax.R-Sg.Robots\.txt :cal SetSyn("robots")<CR>
+an 50.90.270 &Syntax.R-Sg.RockLinux\ package\ desc\. :cal SetSyn("desc")<CR>
+an 50.90.280 &Syntax.R-Sg.Rpcgen :cal SetSyn("rpcgen")<CR>
+an 50.90.290 &Syntax.R-Sg.RPL/2 :cal SetSyn("rpl")<CR>
+an 50.90.300 &Syntax.R-Sg.ReStructuredText :cal SetSyn("rst")<CR>
+an 50.90.310 &Syntax.R-Sg.RTF :cal SetSyn("rtf")<CR>
+an 50.90.320 &Syntax.R-Sg.Ruby :cal SetSyn("ruby")<CR>
+an 50.90.340 &Syntax.R-Sg.S-Lang :cal SetSyn("slang")<CR>
+an 50.90.350 &Syntax.R-Sg.Samba\ config :cal SetSyn("samba")<CR>
+an 50.90.360 &Syntax.R-Sg.SAS :cal SetSyn("sas")<CR>
+an 50.90.370 &Syntax.R-Sg.Sather :cal SetSyn("sather")<CR>
+an 50.90.380 &Syntax.R-Sg.Scheme :cal SetSyn("scheme")<CR>
+an 50.90.390 &Syntax.R-Sg.Scilab :cal SetSyn("scilab")<CR>
+an 50.90.400 &Syntax.R-Sg.Screen\ RC :cal SetSyn("screen")<CR>
+an 50.90.410 &Syntax.R-Sg.SDL :cal SetSyn("sdl")<CR>
+an 50.90.420 &Syntax.R-Sg.Sed :cal SetSyn("sed")<CR>
+an 50.90.430 &Syntax.R-Sg.Sendmail\.cf :cal SetSyn("sm")<CR>
+an 50.90.440 &Syntax.R-Sg.Send-pr :cal SetSyn("sendpr")<CR>
+an 50.90.450 &Syntax.R-Sg.Sensors\.conf :cal SetSyn("sensors")<CR>
+an 50.90.460 &Syntax.R-Sg.Service\ Location\ config :cal SetSyn("slpconf")<CR>
+an 50.90.470 &Syntax.R-Sg.Service\ Location\ registration :cal SetSyn("slpreg")<CR>
+an 50.90.480 &Syntax.R-Sg.Service\ Location\ SPI :cal SetSyn("slpspi")<CR>
+an 50.90.490 &Syntax.R-Sg.Services :cal SetSyn("services")<CR>
+an 50.90.500 &Syntax.R-Sg.Setserial\ config :cal SetSyn("setserial")<CR>
+an 50.90.510 &Syntax.R-Sg.SGML.SGML\ catalog :cal SetSyn("catalog")<CR>
+an 50.90.520 &Syntax.R-Sg.SGML.SGML\ DTD :cal SetSyn("sgml")<CR>
+an 50.90.530 &Syntax.R-Sg.SGML.SGML\ Declaration :cal SetSyn("sgmldecl")<CR>
+an 50.90.540 &Syntax.R-Sg.SGML.SGML-linuxdoc :cal SetSyn("sgmllnx")<CR>
+an 50.100.100 &Syntax.Sh-S.Shell\ script.sh\ and\ ksh :cal SetSyn("sh")<CR>
+an 50.100.110 &Syntax.Sh-S.Shell\ script.csh :cal SetSyn("csh")<CR>
+an 50.100.120 &Syntax.Sh-S.Shell\ script.tcsh :cal SetSyn("tcsh")<CR>
+an 50.100.130 &Syntax.Sh-S.Shell\ script.zsh :cal SetSyn("zsh")<CR>
+an 50.100.140 &Syntax.Sh-S.SiCAD :cal SetSyn("sicad")<CR>
+an 50.100.150 &Syntax.Sh-S.Sieve :cal SetSyn("sieve")<CR>
+an 50.100.160 &Syntax.Sh-S.Simula :cal SetSyn("simula")<CR>
+an 50.100.170 &Syntax.Sh-S.Sinda.Sinda\ compare :cal SetSyn("sindacmp")<CR>
+an 50.100.180 &Syntax.Sh-S.Sinda.Sinda\ input :cal SetSyn("sinda")<CR>
+an 50.100.190 &Syntax.Sh-S.Sinda.Sinda\ output :cal SetSyn("sindaout")<CR>
+an 50.100.200 &Syntax.Sh-S.SiSU :cal SetSyn("sisu")<CR>
+an 50.100.210 &Syntax.Sh-S.SKILL.SKILL :cal SetSyn("skill")<CR>
+an 50.100.220 &Syntax.Sh-S.SKILL.SKILL\ for\ Diva :cal SetSyn("diva")<CR>
+an 50.100.230 &Syntax.Sh-S.Slice :cal SetSyn("slice")<CR>
+an 50.100.240 &Syntax.Sh-S.SLRN.Slrn\ rc :cal SetSyn("slrnrc")<CR>
+an 50.100.250 &Syntax.Sh-S.SLRN.Slrn\ score :cal SetSyn("slrnsc")<CR>
+an 50.100.260 &Syntax.Sh-S.SmallTalk :cal SetSyn("st")<CR>
+an 50.100.270 &Syntax.Sh-S.Smarty\ Templates :cal SetSyn("smarty")<CR>
+an 50.100.280 &Syntax.Sh-S.SMIL :cal SetSyn("smil")<CR>
+an 50.100.290 &Syntax.Sh-S.SMITH :cal SetSyn("smith")<CR>
+an 50.100.300 &Syntax.Sh-S.SNMP\ MIB :cal SetSyn("mib")<CR>
+an 50.100.310 &Syntax.Sh-S.SNNS.SNNS\ network :cal SetSyn("snnsnet")<CR>
+an 50.100.320 &Syntax.Sh-S.SNNS.SNNS\ pattern :cal SetSyn("snnspat")<CR>
+an 50.100.330 &Syntax.Sh-S.SNNS.SNNS\ result :cal SetSyn("snnsres")<CR>
+an 50.100.340 &Syntax.Sh-S.Snobol4 :cal SetSyn("snobol4")<CR>
+an 50.100.350 &Syntax.Sh-S.Snort\ Configuration :cal SetSyn("hog")<CR>
+an 50.100.360 &Syntax.Sh-S.SPEC\ (Linux\ RPM) :cal SetSyn("spec")<CR>
+an 50.100.370 &Syntax.Sh-S.Specman :cal SetSyn("specman")<CR>
+an 50.100.380 &Syntax.Sh-S.Spice :cal SetSyn("spice")<CR>
+an 50.100.390 &Syntax.Sh-S.Spyce :cal SetSyn("spyce")<CR>
+an 50.100.400 &Syntax.Sh-S.Speedup :cal SetSyn("spup")<CR>
+an 50.100.410 &Syntax.Sh-S.Splint :cal SetSyn("splint")<CR>
+an 50.100.420 &Syntax.Sh-S.Squid\ config :cal SetSyn("squid")<CR>
+an 50.100.430 &Syntax.Sh-S.SQL.ESQL-C :cal SetSyn("esqlc")<CR>
+an 50.100.440 &Syntax.Sh-S.SQL.MySQL :cal SetSyn("mysql")<CR>
+an 50.100.450 &Syntax.Sh-S.SQL.PL/SQL :cal SetSyn("plsql")<CR>
+an 50.100.460 &Syntax.Sh-S.SQL.SQL\ Anywhere :cal SetSyn("sqlanywhere")<CR>
+an 50.100.470 &Syntax.Sh-S.SQL.SQL\ (automatic) :cal SetSyn("sql")<CR>
+an 50.100.480 &Syntax.Sh-S.SQL.SQL\ (Oracle) :cal SetSyn("sqloracle")<CR>
+an 50.100.490 &Syntax.Sh-S.SQL.SQL\ Forms :cal SetSyn("sqlforms")<CR>
+an 50.100.500 &Syntax.Sh-S.SQL.SQLJ :cal SetSyn("sqlj")<CR>
+an 50.100.510 &Syntax.Sh-S.SQL.SQL-Informix :cal SetSyn("sqlinformix")<CR>
+an 50.100.520 &Syntax.Sh-S.SQR :cal SetSyn("sqr")<CR>
+an 50.100.530 &Syntax.Sh-S.Ssh.ssh_config :cal SetSyn("sshconfig")<CR>
+an 50.100.540 &Syntax.Sh-S.Ssh.sshd_config :cal SetSyn("sshdconfig")<CR>
+an 50.100.550 &Syntax.Sh-S.Standard\ ML :cal SetSyn("sml")<CR>
+an 50.100.560 &Syntax.Sh-S.Stata.SMCL :cal SetSyn("smcl")<CR>
+an 50.100.570 &Syntax.Sh-S.Stata.Stata :cal SetSyn("stata")<CR>
+an 50.100.580 &Syntax.Sh-S.Stored\ Procedures :cal SetSyn("stp")<CR>
+an 50.100.590 &Syntax.Sh-S.Strace :cal SetSyn("strace")<CR>
+an 50.100.600 &Syntax.Sh-S.Streaming\ descriptor\ file :cal SetSyn("sd")<CR>
+an 50.100.610 &Syntax.Sh-S.Subversion\ commit :cal SetSyn("svn")<CR>
+an 50.100.620 &Syntax.Sh-S.Sudoers :cal SetSyn("sudoers")<CR>
+an 50.100.630 &Syntax.Sh-S.Sysctl\.conf :cal SetSyn("sysctl")<CR>
+an 50.110.100 &Syntax.TUV.TADS :cal SetSyn("tads")<CR>
+an 50.110.110 &Syntax.TUV.Tags :cal SetSyn("tags")<CR>
+an 50.110.120 &Syntax.TUV.TAK.TAK\ compare :cal SetSyn("takcmp")<CR>
+an 50.110.130 &Syntax.TUV.TAK.TAK\ input :cal SetSyn("tak")<CR>
+an 50.110.140 &Syntax.TUV.TAK.TAK\ output :cal SetSyn("takout")<CR>
+an 50.110.150 &Syntax.TUV.Tcl/Tk :cal SetSyn("tcl")<CR>
+an 50.110.160 &Syntax.TUV.TealInfo :cal SetSyn("tli")<CR>
+an 50.110.170 &Syntax.TUV.Telix\ Salt :cal SetSyn("tsalt")<CR>
+an 50.110.180 &Syntax.TUV.Termcap/Printcap :cal SetSyn("ptcap")<CR>
+an 50.110.190 &Syntax.TUV.Terminfo :cal SetSyn("terminfo")<CR>
+an 50.110.200 &Syntax.TUV.TeX.TeX/LaTeX :cal SetSyn("tex")<CR>
+an 50.110.210 &Syntax.TUV.TeX.plain\ TeX :cal SetSyn("plaintex")<CR>
+an 50.110.220 &Syntax.TUV.TeX.ConTeXt :cal SetSyn("context")<CR>
+an 50.110.230 &Syntax.TUV.TeX.TeX\ configuration :cal SetSyn("texmf")<CR>
+an 50.110.240 &Syntax.TUV.TeX.Texinfo :cal SetSyn("texinfo")<CR>
+an 50.110.250 &Syntax.TUV.TF\ mud\ client :cal SetSyn("tf")<CR>
+an 50.110.260 &Syntax.TUV.Tidy\ configuration :cal SetSyn("tidy")<CR>
+an 50.110.270 &Syntax.TUV.Tilde :cal SetSyn("tilde")<CR>
+an 50.110.280 &Syntax.TUV.TPP :cal SetSyn("tpp")<CR>
+an 50.110.290 &Syntax.TUV.Trasys\ input :cal SetSyn("trasys")<CR>
+an 50.110.300 &Syntax.TUV.Trustees :cal SetSyn("trustees")<CR>
+an 50.110.310 &Syntax.TUV.TSS.Command\ Line :cal SetSyn("tsscl")<CR>
+an 50.110.320 &Syntax.TUV.TSS.Geometry :cal SetSyn("tssgm")<CR>
+an 50.110.330 &Syntax.TUV.TSS.Optics :cal SetSyn("tssop")<CR>
+an 50.110.350 &Syntax.TUV.Udev\ config :cal SetSyn("udevconf")<CR>
+an 50.110.360 &Syntax.TUV.Udev\ permissions :cal SetSyn("udevperm")<CR>
+an 50.110.370 &Syntax.TUV.Udev\ rules :cal SetSyn("udevrules")<CR>
+an 50.110.380 &Syntax.TUV.UIT/UIL :cal SetSyn("uil")<CR>
+an 50.110.390 &Syntax.TUV.UnrealScript :cal SetSyn("uc")<CR>
+an 50.110.400 &Syntax.TUV.Updatedb\.conf :cal SetSyn("updatedb")<CR>
+an 50.110.420 &Syntax.TUV.Valgrind :cal SetSyn("valgrind")<CR>
+an 50.110.430 &Syntax.TUV.Vera :cal SetSyn("vera")<CR>
+an 50.110.440 &Syntax.TUV.Verilog-AMS\ HDL :cal SetSyn("verilogams")<CR>
+an 50.110.450 &Syntax.TUV.Verilog\ HDL :cal SetSyn("verilog")<CR>
+an 50.110.460 &Syntax.TUV.Vgrindefs :cal SetSyn("vgrindefs")<CR>
+an 50.110.470 &Syntax.TUV.VHDL :cal SetSyn("vhdl")<CR>
+an 50.110.480 &Syntax.TUV.Vim.Vim\ help\ file :cal SetSyn("help")<CR>
+an 50.110.490 &Syntax.TUV.Vim.Vim\ script :cal SetSyn("vim")<CR>
+an 50.110.500 &Syntax.TUV.Vim.Viminfo\ file :cal SetSyn("viminfo")<CR>
+an 50.110.510 &Syntax.TUV.Virata\ config :cal SetSyn("virata")<CR>
+an 50.110.520 &Syntax.TUV.Visual\ Basic :cal SetSyn("vb")<CR>
+an 50.110.530 &Syntax.TUV.VRML :cal SetSyn("vrml")<CR>
+an 50.110.540 &Syntax.TUV.VSE\ JCL :cal SetSyn("vsejcl")<CR>
+an 50.120.100 &Syntax.WXYZ.WEB.CWEB :cal SetSyn("cweb")<CR>
+an 50.120.110 &Syntax.WXYZ.WEB.WEB :cal SetSyn("web")<CR>
+an 50.120.120 &Syntax.WXYZ.WEB.WEB\ Changes :cal SetSyn("change")<CR>
+an 50.120.130 &Syntax.WXYZ.Webmacro :cal SetSyn("webmacro")<CR>
+an 50.120.140 &Syntax.WXYZ.Website\ MetaLanguage :cal SetSyn("wml")<CR>
+an 50.120.160 &Syntax.WXYZ.wDiff :cal SetSyn("wdiff")<CR>
+an 50.120.180 &Syntax.WXYZ.Wget\ config :cal SetSyn("wget")<CR>
+an 50.120.190 &Syntax.WXYZ.Whitespace\ (add) :cal SetSyn("whitespace")<CR>
+an 50.120.200 &Syntax.WXYZ.WildPackets\ EtherPeek\ Decoder :cal SetSyn("dcd")<CR>
+an 50.120.210 &Syntax.WXYZ.WinBatch/Webbatch :cal SetSyn("winbatch")<CR>
+an 50.120.220 &Syntax.WXYZ.Windows\ Scripting\ Host :cal SetSyn("wsh")<CR>
+an 50.120.230 &Syntax.WXYZ.WSML :cal SetSyn("wsml")<CR>
+an 50.120.240 &Syntax.WXYZ.WvDial :cal SetSyn("wvdial")<CR>
+an 50.120.260 &Syntax.WXYZ.X\ Keyboard\ Extension :cal SetSyn("xkb")<CR>
+an 50.120.270 &Syntax.WXYZ.X\ Pixmap :cal SetSyn("xpm")<CR>
+an 50.120.280 &Syntax.WXYZ.X\ Pixmap\ (2) :cal SetSyn("xpm2")<CR>
+an 50.120.290 &Syntax.WXYZ.X\ resources :cal SetSyn("xdefaults")<CR>
+an 50.120.300 &Syntax.WXYZ.Xinetd\.conf :cal SetSyn("xinetd")<CR>
+an 50.120.310 &Syntax.WXYZ.Xmodmap :cal SetSyn("xmodmap")<CR>
+an 50.120.320 &Syntax.WXYZ.Xmath :cal SetSyn("xmath")<CR>
+an 50.120.330 &Syntax.WXYZ.XML :cal SetSyn("xml")<CR>
+an 50.120.340 &Syntax.WXYZ.XML\ Schema\ (XSD) :cal SetSyn("xsd")<CR>
+an 50.120.350 &Syntax.WXYZ.XQuery :cal SetSyn("xquery")<CR>
+an 50.120.360 &Syntax.WXYZ.Xslt :cal SetSyn("xslt")<CR>
+an 50.120.370 &Syntax.WXYZ.XFree86\ Config :cal SetSyn("xf86conf")<CR>
+an 50.120.390 &Syntax.WXYZ.YAML :cal SetSyn("yaml")<CR>
+an 50.120.400 &Syntax.WXYZ.Yacc :cal SetSyn("yacc")<CR>
+
+" The End Of The Syntax Menu
+
+
+an 50.195 &Syntax.-SEP1-			<Nop>
+
+an <silent> 50.200 &Syntax.Set\ '&syntax'\ only :call <SID>Setsynonly()<CR>
+fun! s:Setsynonly()
+  let s:syntax_menu_synonly = 1
+endfun
+an <silent> 50.202 &Syntax.Set\ '&filetype'\ too :call <SID>Nosynonly()<CR>
+fun! s:Nosynonly()
+  if exists("s:syntax_menu_synonly")
+    unlet s:syntax_menu_synonly
+  endif
+endfun
+
+" Restore 'cpoptions'
+let &cpo = s:cpo_save
+unlet s:cpo_save
--- /dev/null
+++ b/lib/vimfiles/syntax/2html.vim
@@ -1,0 +1,546 @@
+" Vim syntax support file
+" Maintainer: Bram Moolenaar <Bram@vim.org>
+" Last Change: 2007 Mar 10
+"	       (modified by David Ne\v{c}as (Yeti) <yeti@physics.muni.cz>)
+"	       (XHTML support by Panagiotis Issaris <takis@lumumba.luc.ac.be>)
+"	       (made w3 compliant by Edd Barrett <vext01@gmail.com>)
+"	       (added html_font. Edd Barrett <vext01@gmail.com>)
+
+" Transform a file into HTML, using the current syntax highlighting.
+
+" Number lines when explicitely requested or when `number' is set
+if exists("html_number_lines")
+  let s:numblines = html_number_lines
+else
+  let s:numblines = &number
+endif
+
+" Font
+if exists("html_font")
+  let s:htmlfont = html_font . ", monospace"
+else
+  let s:htmlfont = "monospace"
+endif
+
+" When not in gui we can only guess the colors.
+if has("gui_running")
+  let s:whatterm = "gui"
+else
+  let s:whatterm = "cterm"
+  if &t_Co == 8
+    let s:cterm_color = {0: "#808080", 1: "#ff6060", 2: "#00ff00", 3: "#ffff00", 4: "#8080ff", 5: "#ff40ff", 6: "#00ffff", 7: "#ffffff"}
+  else
+    let s:cterm_color = {0: "#000000", 1: "#c00000", 2: "#008000", 3: "#804000", 4: "#0000c0", 5: "#c000c0", 6: "#008080", 7: "#c0c0c0", 8: "#808080", 9: "#ff6060", 10: "#00ff00", 11: "#ffff00", 12: "#8080ff", 13: "#ff40ff", 14: "#00ffff", 15: "#ffffff"}
+
+    " Colors for 88 and 256 come from xterm.
+    if &t_Co == 88
+      call extend(s:cterm_color, {16: "#000000", 17: "#00008b", 18: "#0000cd", 19: "#0000ff", 20: "#008b00", 21: "#008b8b", 22: "#008bcd", 23: "#008bff", 24: "#00cd00", 25: "#00cd8b", 26: "#00cdcd", 27: "#00cdff", 28: "#00ff00", 29: "#00ff8b", 30: "#00ffcd", 31: "#00ffff", 32: "#8b0000", 33: "#8b008b", 34: "#8b00cd", 35: "#8b00ff", 36: "#8b8b00", 37: "#8b8b8b", 38: "#8b8bcd", 39: "#8b8bff", 40: "#8bcd00", 41: "#8bcd8b", 42: "#8bcdcd", 43: "#8bcdff", 44: "#8bff00", 45: "#8bff8b", 46: "#8bffcd", 47: "#8bffff", 48: "#cd0000", 49: "#cd008b", 50: "#cd00cd", 51: "#cd00ff", 52: "#cd8b00", 53: "#cd8b8b", 54: "#cd8bcd", 55: "#cd8bff", 56: "#cdcd00", 57: "#cdcd8b", 58: "#cdcdcd", 59: "#cdcdff", 60: "#cdff00", 61: "#cdff8b", 62: "#cdffcd", 63: "#cdffff", 64: "#ff0000"})
+      call extend(s:cterm_color, {65: "#ff008b", 66: "#ff00cd", 67: "#ff00ff", 68: "#ff8b00", 69: "#ff8b8b", 70: "#ff8bcd", 71: "#ff8bff", 72: "#ffcd00", 73: "#ffcd8b", 74: "#ffcdcd", 75: "#ffcdff", 76: "#ffff00", 77: "#ffff8b", 78: "#ffffcd", 79: "#ffffff", 80: "#2e2e2e", 81: "#5c5c5c", 82: "#737373", 83: "#8b8b8b", 84: "#a2a2a2", 85: "#b9b9b9", 86: "#d0d0d0", 87: "#e7e7e7"})
+    elseif &t_Co == 256
+      call extend(s:cterm_color, {16: "#000000", 17: "#00005f", 18: "#000087", 19: "#0000af", 20: "#0000d7", 21: "#0000ff", 22: "#005f00", 23: "#005f5f", 24: "#005f87", 25: "#005faf", 26: "#005fd7", 27: "#005fff", 28: "#008700", 29: "#00875f", 30: "#008787", 31: "#0087af", 32: "#0087d7", 33: "#0087ff", 34: "#00af00", 35: "#00af5f", 36: "#00af87", 37: "#00afaf", 38: "#00afd7", 39: "#00afff", 40: "#00d700", 41: "#00d75f", 42: "#00d787", 43: "#00d7af", 44: "#00d7d7", 45: "#00d7ff", 46: "#00ff00", 47: "#00ff5f", 48: "#00ff87", 49: "#00ffaf", 50: "#00ffd7", 51: "#00ffff", 52: "#5f0000", 53: "#5f005f", 54: "#5f0087", 55: "#5f00af", 56: "#5f00d7", 57: "#5f00ff", 58: "#5f5f00", 59: "#5f5f5f", 60: "#5f5f87", 61: "#5f5faf", 62: "#5f5fd7", 63: "#5f5fff", 64: "#5f8700"})
+      call extend(s:cterm_color, {65: "#5f875f", 66: "#5f8787", 67: "#5f87af", 68: "#5f87d7", 69: "#5f87ff", 70: "#5faf00", 71: "#5faf5f", 72: "#5faf87", 73: "#5fafaf", 74: "#5fafd7", 75: "#5fafff", 76: "#5fd700", 77: "#5fd75f", 78: "#5fd787", 79: "#5fd7af", 80: "#5fd7d7", 81: "#5fd7ff", 82: "#5fff00", 83: "#5fff5f", 84: "#5fff87", 85: "#5fffaf", 86: "#5fffd7", 87: "#5fffff", 88: "#870000", 89: "#87005f", 90: "#870087", 91: "#8700af", 92: "#8700d7", 93: "#8700ff", 94: "#875f00", 95: "#875f5f", 96: "#875f87", 97: "#875faf", 98: "#875fd7", 99: "#875fff", 100: "#878700", 101: "#87875f", 102: "#878787", 103: "#8787af", 104: "#8787d7", 105: "#8787ff", 106: "#87af00", 107: "#87af5f", 108: "#87af87", 109: "#87afaf", 110: "#87afd7", 111: "#87afff", 112: "#87d700"})
+      call extend(s:cterm_color, {113: "#87d75f", 114: "#87d787", 115: "#87d7af", 116: "#87d7d7", 117: "#87d7ff", 118: "#87ff00", 119: "#87ff5f", 120: "#87ff87", 121: "#87ffaf", 122: "#87ffd7", 123: "#87ffff", 124: "#af0000", 125: "#af005f", 126: "#af0087", 127: "#af00af", 128: "#af00d7", 129: "#af00ff", 130: "#af5f00", 131: "#af5f5f", 132: "#af5f87", 133: "#af5faf", 134: "#af5fd7", 135: "#af5fff", 136: "#af8700", 137: "#af875f", 138: "#af8787", 139: "#af87af", 140: "#af87d7", 141: "#af87ff", 142: "#afaf00", 143: "#afaf5f", 144: "#afaf87", 145: "#afafaf", 146: "#afafd7", 147: "#afafff", 148: "#afd700", 149: "#afd75f", 150: "#afd787", 151: "#afd7af", 152: "#afd7d7", 153: "#afd7ff", 154: "#afff00", 155: "#afff5f", 156: "#afff87", 157: "#afffaf", 158: "#afffd7"})
+      call extend(s:cterm_color, {159: "#afffff", 160: "#d70000", 161: "#d7005f", 162: "#d70087", 163: "#d700af", 164: "#d700d7", 165: "#d700ff", 166: "#d75f00", 167: "#d75f5f", 168: "#d75f87", 169: "#d75faf", 170: "#d75fd7", 171: "#d75fff", 172: "#d78700", 173: "#d7875f", 174: "#d78787", 175: "#d787af", 176: "#d787d7", 177: "#d787ff", 178: "#d7af00", 179: "#d7af5f", 180: "#d7af87", 181: "#d7afaf", 182: "#d7afd7", 183: "#d7afff", 184: "#d7d700", 185: "#d7d75f", 186: "#d7d787", 187: "#d7d7af", 188: "#d7d7d7", 189: "#d7d7ff", 190: "#d7ff00", 191: "#d7ff5f", 192: "#d7ff87", 193: "#d7ffaf", 194: "#d7ffd7", 195: "#d7ffff", 196: "#ff0000", 197: "#ff005f", 198: "#ff0087", 199: "#ff00af", 200: "#ff00d7", 201: "#ff00ff", 202: "#ff5f00", 203: "#ff5f5f", 204: "#ff5f87"})
+      call extend(s:cterm_color, {205: "#ff5faf", 206: "#ff5fd7", 207: "#ff5fff", 208: "#ff8700", 209: "#ff875f", 210: "#ff8787", 211: "#ff87af", 212: "#ff87d7", 213: "#ff87ff", 214: "#ffaf00", 215: "#ffaf5f", 216: "#ffaf87", 217: "#ffafaf", 218: "#ffafd7", 219: "#ffafff", 220: "#ffd700", 221: "#ffd75f", 222: "#ffd787", 223: "#ffd7af", 224: "#ffd7d7", 225: "#ffd7ff", 226: "#ffff00", 227: "#ffff5f", 228: "#ffff87", 229: "#ffffaf", 230: "#ffffd7", 231: "#ffffff", 232: "#080808", 233: "#121212", 234: "#1c1c1c", 235: "#262626", 236: "#303030", 237: "#3a3a3a", 238: "#444444", 239: "#4e4e4e", 240: "#585858", 241: "#626262", 242: "#6c6c6c", 243: "#767676", 244: "#808080", 245: "#8a8a8a", 246: "#949494", 247: "#9e9e9e", 248: "#a8a8a8", 249: "#b2b2b2", 250: "#bcbcbc", 251: "#c6c6c6", 252: "#d0d0d0", 253: "#dadada", 254: "#e4e4e4", 255: "#eeeeee"})
+    endif
+  endif
+endif
+
+" Return good color specification: in GUI no transformation is done, in
+" terminal return RGB values of known colors and empty string for unknown
+if s:whatterm == "gui"
+  function! s:HtmlColor(color)
+    return a:color
+  endfun
+else
+  function! s:HtmlColor(color)
+    if has_key(s:cterm_color, a:color)
+      return s:cterm_color[a:color]
+    else
+      return ""
+    endif
+  endfun
+endif
+
+if !exists("html_use_css")
+  " Return opening HTML tag for given highlight id
+  function! s:HtmlOpening(id)
+    let a = ""
+    if synIDattr(a:id, "inverse")
+      " For inverse, we always must set both colors (and exchange them)
+      let x = s:HtmlColor(synIDattr(a:id, "fg#", s:whatterm))
+      let a = a . '<span style="background-color: ' . ( x != "" ? x : s:fgc ) . '">'
+      let x = s:HtmlColor(synIDattr(a:id, "bg#", s:whatterm))
+      let a = a . '<font color="' . ( x != "" ? x : s:bgc ) . '">'
+    else
+      let x = s:HtmlColor(synIDattr(a:id, "bg#", s:whatterm))
+      if x != "" | let a = a . '<span style="background-color: ' . x . '">' | endif
+      let x = s:HtmlColor(synIDattr(a:id, "fg#", s:whatterm))
+      if x != "" | let a = a . '<font color="' . x . '">' | endif
+    endif
+    if synIDattr(a:id, "bold") | let a = a . "<b>" | endif
+    if synIDattr(a:id, "italic") | let a = a . "<i>" | endif
+    if synIDattr(a:id, "underline") | let a = a . "<u>" | endif
+    return a
+  endfun
+
+  " Return closing HTML tag for given highlight id
+  function s:HtmlClosing(id)
+    let a = ""
+    if synIDattr(a:id, "underline") | let a = a . "</u>" | endif
+    if synIDattr(a:id, "italic") | let a = a . "</i>" | endif
+    if synIDattr(a:id, "bold") | let a = a . "</b>" | endif
+    if synIDattr(a:id, "inverse")
+      let a = a . '</font></span>'
+    else
+      let x = s:HtmlColor(synIDattr(a:id, "fg#", s:whatterm))
+      if x != "" | let a = a . '</font>' | endif
+      let x = s:HtmlColor(synIDattr(a:id, "bg#", s:whatterm))
+      if x != "" | let a = a . '</span>' | endif
+    endif
+    return a
+  endfun
+endif
+
+" Return HTML valid characters enclosed in a span of class style_name with
+" unprintable characters expanded and double spaces replaced as necessary.
+function! s:HtmlFormat(text, style_name)
+  " Replace unprintable characters
+  let formatted = strtrans(a:text)
+
+  " Replace the reserved html characters
+  let formatted = substitute(substitute(substitute(substitute(substitute(formatted, '&', '\&amp;', 'g'), '<', '\&lt;', 'g'), '>', '\&gt;', 'g'), '"', '\&quot;', 'g'), "\x0c", '<hr class="PAGE-BREAK">', 'g')
+
+  " Replace double spaces and leading spaces
+  if ' ' != s:HtmlSpace
+    let formatted = substitute(formatted, '  ', s:HtmlSpace . s:HtmlSpace, 'g')
+    let formatted = substitute(formatted, '^ ', s:HtmlSpace, 'g')
+  endif
+
+  " Enclose in a span of class style_name
+  let formatted = '<span class="' . a:style_name . '">' . formatted . '</span>'
+
+  " Add the class to class list if it's not there yet
+  let s:id = hlID(a:style_name)
+  if stridx(s:idlist, "," . s:id . ",") == -1
+    let s:idlist = s:idlist . s:id . ","
+  endif
+
+  return formatted
+endfun
+
+" Return CSS style describing given highlight id (can be empty)
+function! s:CSS1(id)
+  let a = ""
+  if synIDattr(a:id, "inverse")
+    " For inverse, we always must set both colors (and exchange them)
+    let x = s:HtmlColor(synIDattr(a:id, "bg#", s:whatterm))
+    let a = a . "color: " . ( x != "" ? x : s:bgc ) . "; "
+    let x = s:HtmlColor(synIDattr(a:id, "fg#", s:whatterm))
+    let a = a . "background-color: " . ( x != "" ? x : s:fgc ) . "; "
+  else
+    let x = s:HtmlColor(synIDattr(a:id, "fg#", s:whatterm))
+    if x != "" | let a = a . "color: " . x . "; " | endif
+    let x = s:HtmlColor(synIDattr(a:id, "bg#", s:whatterm))
+    if x != "" | let a = a . "background-color: " . x . "; " | endif
+  endif
+  if synIDattr(a:id, "bold") | let a = a . "font-weight: bold; " | endif
+  if synIDattr(a:id, "italic") | let a = a . "font-style: italic; " | endif
+  if synIDattr(a:id, "underline") | let a = a . "text-decoration: underline; " | endif
+  return a
+endfun
+
+" Figure out proper MIME charset from the 'encoding' option.
+if exists("html_use_encoding")
+  let s:html_encoding = html_use_encoding
+else
+  let s:vim_encoding = &encoding
+  if s:vim_encoding =~ '^8bit\|^2byte'
+    let s:vim_encoding = substitute(s:vim_encoding, '^8bit-\|^2byte-', '', '')
+  endif
+  if s:vim_encoding == 'latin1'
+    let s:html_encoding = 'iso-8859-1'
+  elseif s:vim_encoding =~ "^cp12"
+    let s:html_encoding = substitute(s:vim_encoding, 'cp', 'windows-', '')
+  elseif s:vim_encoding == 'sjis'
+    let s:html_encoding = 'Shift_JIS'
+  elseif s:vim_encoding == 'big5'
+    let s:html_encoding = "Big5"
+  elseif s:vim_encoding == 'euc-cn'
+    let s:html_encoding = 'GB_2312-80'
+  elseif s:vim_encoding == 'euc-tw'
+    let s:html_encoding = ""
+  elseif s:vim_encoding =~ '^euc\|^iso\|^koi'
+    let s:html_encoding = substitute(s:vim_encoding, '.*', '\U\0', '')
+  elseif s:vim_encoding == 'cp949'
+    let s:html_encoding = 'KS_C_5601-1987'
+  elseif s:vim_encoding == 'cp936'
+    let s:html_encoding = 'GBK'
+  elseif s:vim_encoding =~ '^ucs\|^utf'
+    let s:html_encoding = 'UTF-8'
+  else
+    let s:html_encoding = ""
+  endif
+endif
+
+
+" Set some options to make it work faster.
+" Don't report changes for :substitute, there will be many of them.
+let s:old_title = &title
+let s:old_icon = &icon
+let s:old_et = &l:et
+let s:old_report = &report
+let s:old_search = @/
+set notitle noicon
+setlocal et
+set report=1000000
+
+" Split window to create a buffer with the HTML file.
+let s:orgbufnr = winbufnr(0)
+if expand("%") == ""
+  new Untitled.html
+else
+  new %.html
+endif
+let s:newwin = winnr()
+let s:orgwin = bufwinnr(s:orgbufnr)
+
+set modifiable
+%d
+let s:old_paste = &paste
+set paste
+let s:old_magic = &magic
+set magic
+
+if exists("use_xhtml")
+  if s:html_encoding != ""
+    exe "normal!  a<?xml version=\"1.0\" encoding=\"" . s:html_encoding . "\"?>\n\e"
+  else
+    exe "normal! a<?xml version=\"1.0\"?>\n\e"
+  endif
+  let s:tag_close = ' />'
+else
+  let s:tag_close = '>'
+endif
+
+" Cache html_no_pre incase we have to turn it on for non-css mode
+if exists("html_no_pre")
+  let s:old_html_no_pre = html_no_pre
+endif
+
+if !exists("html_use_css")
+  " Cant put font tags in <pre>
+  let html_no_pre=1
+endif
+
+let s:HtmlSpace = ' '
+let s:LeadingSpace = ' '
+let s:HtmlEndline = ''
+if exists("html_no_pre")
+  let s:HtmlEndline = '<br' . s:tag_close
+    let s:LeadingSpace = '&nbsp;'
+  let s:HtmlSpace = '\' . s:LeadingSpace
+endif
+
+" HTML header, with the title and generator ;-). Left free space for the CSS,
+" to be filled at the end.
+exe "normal! a<html>\n\e"
+exe "normal! a<head>\n<title>" . expand("%:p:~") . "</title>\n\e"
+exe "normal! a<meta name=\"Generator\" content=\"Vim/" . v:version/100 . "." . v:version %100 . '"' . s:tag_close . "\n\e"
+if s:html_encoding != ""
+  exe "normal! a<meta http-equiv=\"content-type\" content=\"text/html; charset=" . s:html_encoding . '"' . s:tag_close . "\n\e"
+endif
+
+if exists("html_use_css")
+  exe "normal! a<style type=\"text/css\">\n<!--\n-->\n</style>\n\e"
+endif
+if exists("html_no_pre")
+  exe "normal! a</head>\n<body>\n\e"
+else
+  exe "normal! a</head>\n<body>\n<pre>\n\e"
+endif
+
+exe s:orgwin . "wincmd w"
+
+" List of all id's
+let s:idlist = ","
+
+" Loop over all lines in the original text.
+" Use html_start_line and html_end_line if they are set.
+if exists("html_start_line")
+  let s:lnum = html_start_line
+  if s:lnum < 1 || s:lnum > line("$")
+    let s:lnum = 1
+  endif
+else
+  let s:lnum = 1
+endif
+if exists("html_end_line")
+  let s:end = html_end_line
+  if s:end < s:lnum || s:end > line("$")
+    let s:end = line("$")
+  endif
+else
+  let s:end = line("$")
+endif
+
+if has('folding') && !exists('html_ignore_folding')
+  let s:foldfillchar = &fillchars[matchend(&fillchars, 'fold:')]
+  if s:foldfillchar == ''
+    let s:foldfillchar = '-'
+  endif
+endif
+let s:difffillchar = &fillchars[matchend(&fillchars, 'diff:')]
+if s:difffillchar == ''
+  let s:difffillchar = '-'
+endif
+
+
+while s:lnum <= s:end
+
+  " If there are filler lines for diff mode, show these above the line.
+  let s:filler = diff_filler(s:lnum)
+  if s:filler > 0
+    let s:n = s:filler
+    while s:n > 0
+      if s:numblines
+	" Indent if line numbering is on
+	let s:new = repeat(s:LeadingSpace, strlen(s:end) + 1) . repeat(s:difffillchar, 3)
+      else
+	let s:new = repeat(s:difffillchar, 3)
+      endif
+
+      if s:n > 2 && s:n < s:filler && !exists("html_whole_filler")
+	let s:new = s:new . " " . s:filler . " inserted lines "
+	let s:n = 2
+      endif
+
+      if !exists("html_no_pre")
+	" HTML line wrapping is off--go ahead and fill to the margin
+	let s:new = s:new . repeat(s:difffillchar, &columns - strlen(s:new))
+      endif
+
+      let s:new = s:HtmlFormat(s:new, "DiffDelete")
+      exe s:newwin . "wincmd w"
+      exe "normal! a" . s:new . s:HtmlEndline . "\n\e"
+      exe s:orgwin . "wincmd w"
+
+      let s:n = s:n - 1
+    endwhile
+    unlet s:n
+  endif
+  unlet s:filler
+
+  " Start the line with the line number.
+  if s:numblines
+    let s:new = repeat(' ', strlen(s:end) - strlen(s:lnum)) . s:lnum . ' '
+  else
+    let s:new = ""
+  endif
+
+  if has('folding') && !exists('html_ignore_folding') && foldclosed(s:lnum) > -1
+    "
+    " This is the beginning of a folded block
+    "
+    let s:new = s:new . foldtextresult(s:lnum)
+    if !exists("html_no_pre")
+      " HTML line wrapping is off--go ahead and fill to the margin
+      let s:new = s:new . repeat(s:foldfillchar, &columns - strlen(s:new))
+    endif
+
+    let s:new = s:HtmlFormat(s:new, "Folded")
+
+    " Skip to the end of the fold
+    let s:lnum = foldclosedend(s:lnum)
+
+  else
+    "
+    " A line that is not folded.
+    "
+    let s:line = getline(s:lnum)
+
+    let s:len = strlen(s:line)
+
+    if s:numblines
+      let s:new = s:HtmlFormat(s:new, "lnr")
+    endif
+
+    " Get the diff attribute, if any.
+    let s:diffattr = diff_hlID(s:lnum, 1)
+
+    " Loop over each character in the line
+    let s:col = 1
+    while s:col <= s:len || (s:col == 1 && s:diffattr)
+      let s:startcol = s:col " The start column for processing text
+      if s:diffattr
+	let s:id = diff_hlID(s:lnum, s:col)
+	let s:col = s:col + 1
+	" Speed loop (it's small - that's the trick)
+	" Go along till we find a change in hlID
+	while s:col <= s:len && s:id == diff_hlID(s:lnum, s:col) | let s:col = s:col + 1 | endwhile
+	if s:len < &columns && !exists("html_no_pre")
+	  " Add spaces at the end to mark the changed line.
+	  let s:line = s:line . repeat(' ', &columns - s:len)
+	  let s:len = &columns
+	endif
+      else
+	let s:id = synID(s:lnum, s:col, 1)
+	let s:col = s:col + 1
+	" Speed loop (it's small - that's the trick)
+	" Go along till we find a change in synID
+	while s:col <= s:len && s:id == synID(s:lnum, s:col, 1) | let s:col = s:col + 1 | endwhile
+      endif
+
+      " Expand tabs
+      let s:expandedtab = strpart(s:line, s:startcol - 1, s:col - s:startcol)
+      let idx = stridx(s:expandedtab, "\t")
+      while idx >= 0
+	let i = &ts - ((idx + s:startcol - 1) % &ts)
+	let s:expandedtab = substitute(s:expandedtab, '\t', repeat(' ', i), '')
+	let idx = stridx(s:expandedtab, "\t")
+      endwhile
+
+      " Output the text with the same synID, with class set to {s:id_name}
+      let s:id = synIDtrans(s:id)
+      let s:id_name = synIDattr(s:id, "name", s:whatterm)
+      let s:new = s:new . s:HtmlFormat(s:expandedtab,  s:id_name)
+    endwhile
+  endif
+
+  exe s:newwin . "wincmd w"
+  exe "normal! a" . s:new . s:HtmlEndline . "\n\e"
+  exe s:orgwin . "wincmd w"
+  let s:lnum = s:lnum + 1
+endwhile
+" Finish with the last line
+exe s:newwin . "wincmd w"
+
+" Close off the font tag that encapsulates the whole <body>
+if !exists("html_use_css")
+  exe "normal! a</font>\e"
+endif
+
+if exists("html_no_pre")
+  exe "normal! a</body>\n</html>\e"
+else
+  exe "normal! a</pre>\n</body>\n</html>\e"
+endif
+
+
+" Now, when we finally know which, we define the colors and styles
+if exists("html_use_css")
+  1;/<style type="text/+1
+endif
+
+" Find out the background and foreground color.
+let s:fgc = s:HtmlColor(synIDattr(hlID("Normal"), "fg#", s:whatterm))
+let s:bgc = s:HtmlColor(synIDattr(hlID("Normal"), "bg#", s:whatterm))
+if s:fgc == ""
+  let s:fgc = ( &background == "dark" ? "#ffffff" : "#000000" )
+endif
+if s:bgc == ""
+  let s:bgc = ( &background == "dark" ? "#000000" : "#ffffff" )
+endif
+
+" Normal/global attributes
+" For Netscape 4, set <body> attributes too, though, strictly speaking, it's
+" incorrect.
+if exists("html_use_css")
+  if exists("html_no_pre")
+    execute "normal! A\nbody { color: " . s:fgc . "; background-color: " . s:bgc . "; font-family: ". s:htmlfont ."; }\e"
+  else
+    execute "normal! A\npre { font-family: ". s:htmlfont ."; color: " . s:fgc . "; background-color: " . s:bgc . "; }\e"
+    yank
+    put
+    execute "normal! ^cwbody\e"
+  endif
+else
+    execute '%s:<body>:<body bgcolor="' . s:bgc . '" text="' . s:fgc . '"><font face="'. s:htmlfont .'">'
+endif
+
+" Line numbering attributes
+if s:numblines
+  if exists("html_use_css")
+    execute "normal! A\n.lnr { " . s:CSS1(hlID("LineNr")) . "}\e"
+  else
+    execute '%s+^<span class="lnr">\([^<]*\)</span>+' . s:HtmlOpening(hlID("LineNr")) . '\1' . s:HtmlClosing(hlID("LineNr")) . '+g'
+  endif
+endif
+
+" Gather attributes for all other classes
+let s:idlist = strpart(s:idlist, 1)
+while s:idlist != ""
+  let s:attr = ""
+  let s:col = stridx(s:idlist, ",")
+  let s:id = strpart(s:idlist, 0, s:col)
+  let s:idlist = strpart(s:idlist, s:col + 1)
+  let s:attr = s:CSS1(s:id)
+  let s:id_name = synIDattr(s:id, "name", s:whatterm)
+  " If the class has some attributes, export the style, otherwise DELETE all
+  " its occurences to make the HTML shorter
+  if s:attr != ""
+    if exists("html_use_css")
+      execute "normal! A\n." . s:id_name . " { " . s:attr . "}"
+    else
+      execute '%s+<span class="' . s:id_name . '">\([^<]*\)</span>+' . s:HtmlOpening(s:id) . '\1' . s:HtmlClosing(s:id) . '+g'
+    endif
+  else
+    execute '%s+<span class="' . s:id_name . '">\([^<]*\)</span>+\1+ge'
+    if exists("html_use_css")
+      1;/<style type="text/+1
+    endif
+  endif
+endwhile
+
+" Add hyperlinks
+%s+\(https\=://\S\{-}\)\(\([.,;:}]\=\(\s\|$\)\)\|[\\"'<>]\|&gt;\|&lt;\|&quot;\)+<a href="\1">\1</a>\2+ge
+
+" The DTD
+if exists("use_xhtml")
+  exe "normal! gg$a\n<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">\e"
+else
+  exe "normal! gg0i<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\" \"http://www.w3.org/TR/html4/loose.dtd\">\n\e"
+endif
+
+if exists("use_xhtml")
+  exe "normal! gg/<html/e\na xmlns=\"http://www.w3.org/1999/xhtml\"\e"
+endif
+
+" Cleanup
+%s:\s\+$::e
+
+" Restore old settings
+let &report = s:old_report
+let &title = s:old_title
+let &icon = s:old_icon
+let &paste = s:old_paste
+let &magic = s:old_magic
+let @/ = s:old_search
+exe s:orgwin . "wincmd w"
+let &l:et = s:old_et
+exe s:newwin . "wincmd w"
+
+" Reset old <pre> settings
+if exists("s:old_html_no_pre")
+  let html_no_pre = s:old_html_no_pre
+  unlet s:old_html_no_pre
+elseif exists("html_no_pre")
+  unlet html_no_pre
+endif
+
+" Save a little bit of memory (worth doing?)
+unlet s:htmlfont
+unlet s:old_et s:old_paste s:old_icon s:old_report s:old_title s:old_search
+unlet s:whatterm s:idlist s:lnum s:end s:fgc s:bgc s:old_magic
+unlet! s:col s:id s:attr s:len s:line s:new s:expandedtab s:numblines
+unlet s:orgwin s:newwin s:orgbufnr
+if !v:profiling
+  delfunc s:HtmlColor
+  delfunc s:HtmlFormat
+  delfunc s:CSS1
+  if !exists("html_use_css")
+    delfunc s:HtmlOpening
+    delfunc s:HtmlClosing
+  endif
+endif
+silent! unlet s:diffattr s:difffillchar s:foldfillchar s:HtmlSpace s:LeadingSpace s:HtmlEndline
--- /dev/null
+++ b/lib/vimfiles/syntax/README.txt
@@ -1,0 +1,38 @@
+This directory contains Vim scripts for syntax highlighting.
+
+These scripts are not for a language, but are used by Vim itself:
+
+syntax.vim	Used for the ":syntax on" command.  Uses synload.vim.
+
+manual.vim	Used for the ":syntax manual" command.  Uses synload.vim.
+
+synload.vim	Contains autocommands to load a language file when a certain
+		file name (extension) is used.  And sets up the Syntax menu
+		for the GUI.
+
+nosyntax.vim	Used for the ":syntax off" command.  Undo the loading of
+		synload.vim.
+
+
+A few special files:
+
+2html.vim	Converts any highlighted file to HTML (GUI only).
+colortest.vim	Check for color names and actual color on screen.
+hitest.vim	View the current highlight settings.
+whitespace.vim  View Tabs and Spaces.
+
+
+If you want to write a syntax file, read the docs at ":help usr_44.txt".
+
+If you make a new syntax file which would be useful for others, please send it
+to Bram@vim.org.  Include instructions for detecting the file type for this
+language, by file name extension or by checking a few lines in the file.
+And please write the file in a portable way, see ":help 44.12".
+
+If you have remarks about an existing file, send them to the maintainer of
+that file.  Only when you get no response send a message to Bram@vim.org.
+
+If you are the maintainer of a syntax file and make improvements, send the new
+version to Bram@vim.org.
+
+For further info see ":help syntax" in Vim.
--- /dev/null
+++ b/lib/vimfiles/syntax/a2ps.vim
@@ -1,0 +1,71 @@
+" Vim syntax file
+" Language:         a2ps(1) configuration file
+" Maintainer:       Nikolai Weibull <now@bitwi.se>
+" Latest Revision:  2006-04-19
+
+if exists("b:current_syntax")
+  finish
+endif
+
+let s:cpo_save = &cpo
+set cpo&vim
+
+syn keyword a2psPreProc       Include
+                              \ nextgroup=a2psKeywordColon
+
+syn keyword a2psMacro         UserOption
+                              \ nextgroup=a2psKeywordColon
+
+syn keyword a2psKeyword       LibraryPath AppendLibraryPath PrependLibraryPath
+                              \ Options Medium Printer UnknownPrinter
+                              \ DefaultPrinter OutputFirstLine
+                              \ PageLabelFormat Delegation FileCommand
+                              \ nextgroup=a2psKeywordColon
+
+syn match   a2psKeywordColon  contained display ':'
+
+syn keyword a2psKeyword       Variable nextgroup=a2psVariableColon
+
+syn match   a2psVariableColon contained display ':'
+                              \ nextgroup=a2psVariable skipwhite
+
+syn match   a2psVariable      contained display '[^ \t:(){}]\+'
+                              \ contains=a2psVarPrefix
+
+syn match   a2psVarPrefix     contained display
+                              \ '\<\%(del\|pro\|ps\|pl\|toc\|user\|\)\ze\.'
+
+syn match   a2psLineCont      display '\\$'
+
+syn match   a2psSubst         display '$\%(-\=.\=\d\+\)\=\h\d\='
+syn match   a2psSubst         display '#[?!]\=\w\d\='
+syn match   a2psSubst         display '#{[^}]\+}'
+
+syn region  a2psString        display oneline start=+'+ end=+'+
+                              \ contains=a2psSubst
+
+syn region  a2psString        display oneline start=+"+ end=+"+
+                              \ contains=a2psSubst
+
+syn keyword a2psTodo          contained TODO FIXME XXX NOTE
+
+syn region  a2psComment       display oneline start='^\s*#' end='$'
+                              \ contains=a2psTodo,@Spell
+
+hi def link a2psTodo          Todo
+hi def link a2psComment       Comment
+hi def link a2psPreProc       PreProc
+hi def link a2psMacro         Macro
+hi def link a2psKeyword       Keyword
+hi def link a2psKeywordColon  Delimiter
+hi def link a2psVariableColon Delimiter
+hi def link a2psVariable      Identifier
+hi def link a2psVarPrefix     Type
+hi def link a2psLineCont      Special
+hi def link a2psSubst         PreProc
+hi def link a2psString        String
+
+let b:current_syntax = "a2ps"
+
+let &cpo = s:cpo_save
+unlet s:cpo_save
--- /dev/null
+++ b/lib/vimfiles/syntax/a65.vim
@@ -1,0 +1,166 @@
+" Vim syntax file
+" Language:	xa 6502 cross assembler
+" Maintainer:	Clemens Kirchgatterer <clemens@thf.ath.cx>
+" Last Change:	2003 May 03
+
+" For version 5.x: Clear all syntax items
+" For version 6.x: Quit when a syntax file was already loaded
+if version < 600
+  syntax clear
+elseif exists("b:current_syntax")
+  finish
+endif
+
+syn case ignore
+
+" Opcodes
+syn match a65Opcode	"\<PHP\($\|\s\)" nextgroup=a65Address
+syn match a65Opcode	"\<PLA\($\|\s\)" nextgroup=a65Address
+syn match a65Opcode	"\<PLX\($\|\s\)" nextgroup=a65Address
+syn match a65Opcode	"\<PLY\($\|\s\)" nextgroup=a65Address
+syn match a65Opcode	"\<SEC\($\|\s\)" nextgroup=a65Address
+syn match a65Opcode	"\<CLD\($\|\s\)" nextgroup=a65Address
+syn match a65Opcode	"\<SED\($\|\s\)" nextgroup=a65Address
+syn match a65Opcode	"\<CLI\($\|\s\)" nextgroup=a65Address
+syn match a65Opcode	"\<BVC\($\|\s\)" nextgroup=a65Address
+syn match a65Opcode	"\<BVS\($\|\s\)" nextgroup=a65Address
+syn match a65Opcode	"\<BCS\($\|\s\)" nextgroup=a65Address
+syn match a65Opcode	"\<BCC\($\|\s\)" nextgroup=a65Address
+syn match a65Opcode	"\<DEY\($\|\s\)" nextgroup=a65Address
+syn match a65Opcode	"\<DEC\($\|\s\)" nextgroup=a65Address
+syn match a65Opcode	"\<CMP\($\|\s\)" nextgroup=a65Address
+syn match a65Opcode	"\<CPX\($\|\s\)" nextgroup=a65Address
+syn match a65Opcode	"\<BIT\($\|\s\)" nextgroup=a65Address
+syn match a65Opcode	"\<ROL\($\|\s\)" nextgroup=a65Address
+syn match a65Opcode	"\<ROR\($\|\s\)" nextgroup=a65Address
+syn match a65Opcode	"\<ASL\($\|\s\)" nextgroup=a65Address
+syn match a65Opcode	"\<TXA\($\|\s\)" nextgroup=a65Address
+syn match a65Opcode	"\<TYA\($\|\s\)" nextgroup=a65Address
+syn match a65Opcode	"\<TSX\($\|\s\)" nextgroup=a65Address
+syn match a65Opcode	"\<TXS\($\|\s\)" nextgroup=a65Address
+syn match a65Opcode	"\<LDA\($\|\s\)" nextgroup=a65Address
+syn match a65Opcode	"\<LDX\($\|\s\)" nextgroup=a65Address
+syn match a65Opcode	"\<LDY\($\|\s\)" nextgroup=a65Address
+syn match a65Opcode	"\<STA\($\|\s\)" nextgroup=a65Address
+syn match a65Opcode	"\<PLP\($\|\s\)" nextgroup=a65Address
+syn match a65Opcode	"\<BRK\($\|\s\)" nextgroup=a65Address
+syn match a65Opcode	"\<RTI\($\|\s\)" nextgroup=a65Address
+syn match a65Opcode	"\<NOP\($\|\s\)" nextgroup=a65Address
+syn match a65Opcode	"\<SEI\($\|\s\)" nextgroup=a65Address
+syn match a65Opcode	"\<CLV\($\|\s\)" nextgroup=a65Address
+syn match a65Opcode	"\<PHA\($\|\s\)" nextgroup=a65Address
+syn match a65Opcode	"\<PHX\($\|\s\)" nextgroup=a65Address
+syn match a65Opcode	"\<BRA\($\|\s\)" nextgroup=a65Address
+syn match a65Opcode	"\<JMP\($\|\s\)" nextgroup=a65Address
+syn match a65Opcode	"\<JSR\($\|\s\)" nextgroup=a65Address
+syn match a65Opcode	"\<RTS\($\|\s\)" nextgroup=a65Address
+syn match a65Opcode	"\<CPY\($\|\s\)" nextgroup=a65Address
+syn match a65Opcode	"\<BNE\($\|\s\)" nextgroup=a65Address
+syn match a65Opcode	"\<BEQ\($\|\s\)" nextgroup=a65Address
+syn match a65Opcode	"\<BMI\($\|\s\)" nextgroup=a65Address
+syn match a65Opcode	"\<LSR\($\|\s\)" nextgroup=a65Address
+syn match a65Opcode	"\<INX\($\|\s\)" nextgroup=a65Address
+syn match a65Opcode	"\<INY\($\|\s\)" nextgroup=a65Address
+syn match a65Opcode	"\<INC\($\|\s\)" nextgroup=a65Address
+syn match a65Opcode	"\<ADC\($\|\s\)" nextgroup=a65Address
+syn match a65Opcode	"\<SBC\($\|\s\)" nextgroup=a65Address
+syn match a65Opcode	"\<AND\($\|\s\)" nextgroup=a65Address
+syn match a65Opcode	"\<ORA\($\|\s\)" nextgroup=a65Address
+syn match a65Opcode	"\<STX\($\|\s\)" nextgroup=a65Address
+syn match a65Opcode	"\<STY\($\|\s\)" nextgroup=a65Address
+syn match a65Opcode	"\<STZ\($\|\s\)" nextgroup=a65Address
+syn match a65Opcode	"\<EOR\($\|\s\)" nextgroup=a65Address
+syn match a65Opcode	"\<DEX\($\|\s\)" nextgroup=a65Address
+syn match a65Opcode	"\<BPL\($\|\s\)" nextgroup=a65Address
+syn match a65Opcode	"\<CLC\($\|\s\)" nextgroup=a65Address
+syn match a65Opcode	"\<PHY\($\|\s\)" nextgroup=a65Address
+syn match a65Opcode	"\<TRB\($\|\s\)" nextgroup=a65Address
+syn match a65Opcode	"\<BBR\($\|\s\)" nextgroup=a65Address
+syn match a65Opcode	"\<BBS\($\|\s\)" nextgroup=a65Address
+syn match a65Opcode	"\<RMB\($\|\s\)" nextgroup=a65Address
+syn match a65Opcode	"\<SMB\($\|\s\)" nextgroup=a65Address
+syn match a65Opcode	"\<TAY\($\|\s\)" nextgroup=a65Address
+syn match a65Opcode	"\<TAX\($\|\s\)" nextgroup=a65Address
+
+" Addresses
+syn match a65Address	"\s*!\=$[0-9A-F]\{2}\($\|\s\)"
+syn match a65Address	"\s*!\=$[0-9A-F]\{4}\($\|\s\)"
+syn match a65Address	"\s*!\=$[0-9A-F]\{2},X\($\|\s\)"
+syn match a65Address	"\s*!\=$[0-9A-F]\{4},X\($\|\s\)"
+syn match a65Address	"\s*!\=$[0-9A-F]\{2},Y\($\|\s\)"
+syn match a65Address	"\s*!\=$[0-9A-F]\{4},Y\($\|\s\)"
+syn match a65Address	"\s*($[0-9A-F]\{2})\($\|\s\)"
+syn match a65Address	"\s*($[0-9A-F]\{4})\($\|\s\)"
+syn match a65Address	"\s*($[0-9A-F]\{2},X)\($\|\s\)"
+syn match a65Address	"\s*($[0-9A-F]\{2}),Y\($\|\s\)"
+
+" Numbers
+syn match a65Number	"#\=[0-9]*\>"
+syn match a65Number	"#\=$[0-9A-F]*\>"
+syn match a65Number	"#\=&[0-7]*\>"
+syn match a65Number	"#\=%[01]*\>"
+
+syn case match
+
+" Types
+syn match a65Type	"\(^\|\s\)\.byt\($\|\s\)"
+syn match a65Type	"\(^\|\s\)\.word\($\|\s\)"
+syn match a65Type	"\(^\|\s\)\.asc\($\|\s\)"
+syn match a65Type	"\(^\|\s\)\.dsb\($\|\s\)"
+syn match a65Type	"\(^\|\s\)\.fopt\($\|\s\)"
+syn match a65Type	"\(^\|\s\)\.text\($\|\s\)"
+syn match a65Type	"\(^\|\s\)\.data\($\|\s\)"
+syn match a65Type	"\(^\|\s\)\.bss\($\|\s\)"
+syn match a65Type	"\(^\|\s\)\.zero\($\|\s\)"
+syn match a65Type	"\(^\|\s\)\.align\($\|\s\)"
+
+" Blocks
+syn match a65Section	"\(^\|\s\)\.(\($\|\s\)"
+syn match a65Section	"\(^\|\s\)\.)\($\|\s\)"
+
+" Strings
+syn match a65String	"\".*\""
+
+" Programm Counter
+syn region a65PC	start="\*=" end="\>" keepend
+
+" HI/LO Byte
+syn region a65HiLo	start="#[<>]" end="$\|\s" contains=a65Comment keepend
+
+" Comments
+syn keyword a65Todo	TODO XXX FIXME BUG contained
+syn match   a65Comment	";.*"hs=s+1 contains=a65Todo
+syn region  a65Comment	start="/\*" end="\*/" contains=a65Todo,a65Comment
+
+" Preprocessor
+syn region a65PreProc	start="^#" end="$" contains=a65Comment,a65Continue
+syn match  a65End			excludenl /end$/ contained
+syn match  a65Continue	"\\$" contained
+
+" Define the default highlighting.
+" For version 5.7 and earlier: only when not done already
+" For version 5.8 and later: only when an item doesn't have highlighting yet
+if version >= 508 || !exists("did_a65_syntax_inits")
+  if version < 508
+    let did_a65_syntax_inits = 1
+    command -nargs=+ HiLink hi link <args>
+  else
+    command -nargs=+ HiLink hi def link <args>
+  endif
+
+  HiLink a65Section	Special
+  HiLink a65Address	Special
+  HiLink a65Comment	Comment
+  HiLink a65PreProc	PreProc
+  HiLink a65Number	Number
+  HiLink a65String	String
+  HiLink a65Type	Statement
+  HiLink a65Opcode	Type
+  HiLink a65PC		Error
+  HiLink a65Todo	Todo
+  HiLink a65HiLo	Number
+
+  delcommand HiLink
+endif
+
+let b:current_syntax = "a65"
--- /dev/null
+++ b/lib/vimfiles/syntax/aap.vim
@@ -1,0 +1,158 @@
+" Vim syntax file
+" Language:	A-A-P recipe
+" Maintainer:	Bram Moolenaar <Bram@vim.org>
+" Last Change:	2004 Jun 13
+
+" Quit when a syntax file was already loaded
+if exists("b:current_syntax")
+    finish
+endif
+
+let s:cpo_save = &cpo
+set cpo&vim
+
+syn include @aapPythonScript syntax/python.vim
+
+syn match       aapVariable /$[-+?*="'\\!]*[a-zA-Z0-9_.]*/
+syn match       aapVariable /$[-+?*="'\\!]*([a-zA-Z0-9_.]*)/
+syn keyword	aapTodo contained TODO Todo
+syn match	aapString +'[^']\{-}'+
+syn match	aapString +"[^"]\{-}"+
+
+syn match	aapCommand '^\s*:action\>'
+syn match	aapCommand '^\s*:add\>'
+syn match	aapCommand '^\s*:addall\>'
+syn match	aapCommand '^\s*:asroot\>'
+syn match	aapCommand '^\s*:assertpkg\>'
+syn match	aapCommand '^\s*:attr\>'
+syn match	aapCommand '^\s*:attribute\>'
+syn match	aapCommand '^\s*:autodepend\>'
+syn match	aapCommand '^\s*:buildcheck\>'
+syn match	aapCommand '^\s*:cd\>'
+syn match	aapCommand '^\s*:chdir\>'
+syn match	aapCommand '^\s*:checkin\>'
+syn match	aapCommand '^\s*:checkout\>'
+syn match	aapCommand '^\s*:child\>'
+syn match	aapCommand '^\s*:chmod\>'
+syn match	aapCommand '^\s*:commit\>'
+syn match	aapCommand '^\s*:commitall\>'
+syn match	aapCommand '^\s*:conf\>'
+syn match	aapCommand '^\s*:copy\>'
+syn match	aapCommand '^\s*:del\>'
+syn match	aapCommand '^\s*:deldir\>'
+syn match	aapCommand '^\s*:delete\>'
+syn match	aapCommand '^\s*:delrule\>'
+syn match	aapCommand '^\s*:dll\>'
+syn match	aapCommand '^\s*:do\>'
+syn match	aapCommand '^\s*:error\>'
+syn match	aapCommand '^\s*:execute\>'
+syn match	aapCommand '^\s*:exit\>'
+syn match	aapCommand '^\s*:export\>'
+syn match	aapCommand '^\s*:fetch\>'
+syn match	aapCommand '^\s*:fetchall\>'
+syn match	aapCommand '^\s*:filetype\>'
+syn match	aapCommand '^\s*:finish\>'
+syn match	aapCommand '^\s*:global\>'
+syn match	aapCommand '^\s*:import\>'
+syn match	aapCommand '^\s*:include\>'
+syn match	aapCommand '^\s*:installpkg\>'
+syn match	aapCommand '^\s*:lib\>'
+syn match	aapCommand '^\s*:local\>'
+syn match	aapCommand '^\s*:log\>'
+syn match	aapCommand '^\s*:ltlib\>'
+syn match	aapCommand '^\s*:mkdir\>'
+syn match	aapCommand '^\s*:mkdownload\>'
+syn match	aapCommand '^\s*:move\>'
+syn match	aapCommand '^\s*:pass\>'
+syn match	aapCommand '^\s*:popdir\>'
+syn match	aapCommand '^\s*:produce\>'
+syn match	aapCommand '^\s*:program\>'
+syn match	aapCommand '^\s*:progsearch\>'
+syn match	aapCommand '^\s*:publish\>'
+syn match	aapCommand '^\s*:publishall\>'
+syn match	aapCommand '^\s*:pushdir\>'
+syn match	aapCommand '^\s*:quit\>'
+syn match	aapCommand '^\s*:recipe\>'
+syn match	aapCommand '^\s*:refresh\>'
+syn match	aapCommand '^\s*:remove\>'
+syn match	aapCommand '^\s*:removeall\>'
+syn match	aapCommand '^\s*:require\>'
+syn match	aapCommand '^\s*:revise\>'
+syn match	aapCommand '^\s*:reviseall\>'
+syn match	aapCommand '^\s*:route\>'
+syn match	aapCommand '^\s*:rule\>'
+syn match	aapCommand '^\s*:start\>'
+syn match	aapCommand '^\s*:symlink\>'
+syn match	aapCommand '^\s*:sys\>'
+syn match	aapCommand '^\s*:sysdepend\>'
+syn match	aapCommand '^\s*:syspath\>'
+syn match	aapCommand '^\s*:system\>'
+syn match	aapCommand '^\s*:tag\>'
+syn match	aapCommand '^\s*:tagall\>'
+syn match	aapCommand '^\s*:toolsearch\>'
+syn match	aapCommand '^\s*:totype\>'
+syn match	aapCommand '^\s*:touch\>'
+syn match	aapCommand '^\s*:tree\>'
+syn match	aapCommand '^\s*:unlock\>'
+syn match	aapCommand '^\s*:update\>'
+syn match	aapCommand '^\s*:usetool\>'
+syn match	aapCommand '^\s*:variant\>'
+syn match	aapCommand '^\s*:verscont\>'
+
+syn match	aapCommand '^\s*:print\>' nextgroup=aapPipeEnd
+syn match	aapPipeCmd '\s*:print\>' nextgroup=aapPipeEnd contained
+syn match	aapCommand '^\s*:cat\>' nextgroup=aapPipeEnd
+syn match	aapPipeCmd '\s*:cat\>' nextgroup=aapPipeEnd contained
+syn match	aapCommand '^\s*:syseval\>' nextgroup=aapPipeEnd
+syn match	aapPipeCmd '\s*:syseval\>' nextgroup=aapPipeEnd contained
+syn match	aapPipeCmd '\s*:assign\>' contained
+syn match	aapCommand '^\s*:eval\>' nextgroup=aapPipeEnd
+syn match	aapPipeCmd '\s*:eval\>' nextgroup=aapPipeEndPy contained
+syn match	aapPipeCmd '\s*:tee\>' nextgroup=aapPipeEnd contained
+syn match	aapPipeCmd '\s*:log\>' nextgroup=aapPipeEnd contained
+syn match	aapPipeEnd '[^|]*|' nextgroup=aapPipeCmd contained skipnl
+syn match	aapPipeEndPy '[^|]*|' nextgroup=aapPipeCmd contained skipnl contains=@aapPythonScript
+syn match	aapPipeStart '^\s*|' nextgroup=aapPipeCmd
+
+"
+" A Python line starts with @.  Can be continued with a trailing backslash.
+syn region aapPythonRegion start="\s*@" skip='\\$' end=+$+ contains=@aapPythonScript keepend
+"
+" A Python block starts with ":python" and continues so long as the indent is
+" bigger.
+syn region aapPythonRegion matchgroup=aapCommand start="\z(\s*\):python" skip='\n\z1\s\|\n\s*\n' end=+$+ contains=@aapPythonScript
+
+" A Python expression is enclosed in backticks.
+syn region aapPythonRegion start="`" skip="``" end="`" contains=@aapPythonScript
+
+" TODO: There is something wrong with line continuation.
+syn match	aapComment '#.*' contains=aapTodo
+syn match	aapComment '#.*\(\\\n.*\)' contains=aapTodo
+
+syn match	aapSpecial '$#'
+syn match	aapSpecial '$\$'
+syn match	aapSpecial '$(.)'
+
+" A heredoc assignment.
+syn region aapHeredoc start="^\s*\k\+\s*$\=+\=?\=<<\s*\z(\S*\)"hs=e+1 end="^\s*\z1\s*$"he=s-1
+
+" Syncing is needed for ":python" and "VAR << EOF".  Don't use Python syncing
+syn sync clear
+syn sync fromstart
+
+" The default highlighting.
+hi def link aapTodo		Todo
+hi def link aapString		String
+hi def link aapComment		Comment
+hi def link aapSpecial		Special
+hi def link aapVariable		Identifier
+hi def link aapPipeCmd		aapCommand
+hi def link aapCommand		Statement
+hi def link aapHeredoc		Constant
+
+let b:current_syntax = "aap"
+
+let &cpo = s:cpo_save
+unlet s:cpo_save
+
+" vim: ts=8
--- /dev/null
+++ b/lib/vimfiles/syntax/abap.vim
@@ -1,0 +1,153 @@
+" Vim ABAP syntax file
+"    Language: SAP - ABAP/R4
+"    Revision: 1.0
+"  Maintainer: Marius Piedallu van Wyk <marius@e.co.za>
+" Last Change: 2006 Apr 13
+
+" For version  < 6.0: Clear all syntax items
+" For version >= 6.0: Quit when a syntax file was already loaded
+if version < 600
+  syntax clear
+elseif exists("b:current_syntax")
+  finish
+endif
+
+" Always ignore case
+syn case ignore
+
+" Symbol Operators
+syn match   abapSymbolOperator  "[+\-/=<>$]"
+syn match   abapSymbolOperator  "\*"
+syn match   abapSymbolOperator  "[<>]="
+syn match   abapSymbolOperator  "<>"
+syn match   abapSymbolOperator  "\*\*"
+syn match   abapSymbolOperator  "[()]"
+syn match   abapSymbolOperator  "[:,\.]"
+
+" Literals
+syn region  abapString matchgroup=abapString start="'" end="'" contains=abapStringEscape
+syn match   abapStringEscape contained "''"
+
+syn match   abapNumber  "-\=\<\d\+\>"
+syn region  abapHex     matchgroup=abapHex start="X'" end="'"
+
+if version >= 600
+  setlocal iskeyword=-,48-57,_,A-Z,a-z
+else
+  set iskeyword=-,48-57,_,A-Z,a-z
+endif
+
+" ABAP statements
+syn keyword abapStatement ADD ADD-CORRESPONDING ASSIGN AT AUTHORITY-CHECK
+syn keyword abapStatement BACK BREAK-POINT
+syn keyword abapStatement CALL CASE CHECK CLEAR CLOSE CNT COLLECT COMMIT COMMUNICATION COMPUTE CONCATENATE CONDENSE CONSTANTS CONTINUE CONTROLS CONVERT CREATE CURRENCY
+syn keyword abapStatement DATA DEFINE DELETE DESCRIBE DETAIL DIVIDE DIVIDE-CORRESPONDING DO
+syn keyword abapStatement EDITOR-CALL ELSE ELSEIF END-OF-DEFINITION END-OF-PAGE END-OF-SELECTION ENDAT ENDCASE ENDDO ENDEXEC ENDFORM ENDFUNCTION ENDIF ENDIFEND ENDLOOP ENDMODULE ENDON ENDPROVIDE ENDSELECT ENDWHILE EXEC EXPORT EXPORTING EXTRACT
+syn keyword abapStatement FETCH FIELD-GROUPS FIELD-SYMBOLS FIELDS FORM FORMAT FREE FUNCTION FUNCTION-POOL
+syn keyword abapStatement GENERATE GET
+syn keyword abapStatement HIDE
+syn keyword abapStatement IF IMPORT IMPORTING INDEX INFOTYPES INITIALIZATION INPUT INSERT
+syn keyword abapStatement LEAVE LIKE LOAD LOCAL LOOP
+syn keyword abapStatement MESSAGE MODIFY MODULE MOVE MOVE-CORRESPONDING MULTIPLY MULTIPLY-CORRESPONDING
+syn keyword abapStatement NEW-LINE NEW-PAGE NEW-SECTION
+syn keyword abapStatement ON OVERLAY
+syn keyword abapStatement PACK PARAMETERS PERFORM POSITION PRINT-CONTROL PROGRAM PROVIDE PUT
+syn keyword abapStatement RAISE RANGES READ RECEIVE REFRESH REJECT REPLACE REPORT RESERVE RESTORE ROLLBACK RP-PROVIDE-FROM-LAST
+syn keyword abapStatement SCAN SCROLL SEARCH SELECT SELECT-OPTIONS SELECTION-SCREEN SET SHIFT SKIP SORT SPLIT START-OF-SELECTION STATICS STOP SUBMIT SUBTRACT SUBTRACT-CORRESPONDING SUM SUMMARY SUPPRESS SYNTAX-CHECK SYNTAX-TRACE
+syn keyword abapStatement TABLES TOP-OF-PAGE TRANSFER TRANSLATE TYPE TYPE-POOL TYPE-POOLS TYPES
+syn keyword abapStatement UNPACK UPDATE
+syn keyword abapStatement WHEN WHILE WINDOW WRITE
+
+" More statemets
+syn keyword abapStatement OCCURS STRUCTURE OBJECT PROPERTY
+syn keyword abapStatement CASTING APPEND RAISING VALUE COLOR
+syn keyword abapStatement LINE-SIZE LINE-COUNT MESSAGE-ID
+syn keyword abapStatement CHANGING EXCEPTIONS DEFAULT CHECKBOX COMMENT
+syn keyword abapStatement ID NUMBER FOR DISPLAY-MODE TITLE OUTPUT
+
+" More multi-word statements
+syn match   abapStatement "\(\W\|^\)\(WITH\W\+\(HEADER\W\+LINE\|FRAME\|KEY\)\|WITH\)\(\W\|$\)"ms=s+1,me=e-1
+syn match   abapStatement "\(\W\|^\)NO\W\+STANDARD\W\+PAGE\W\+HEADING\(\W\|$\)"ms=s+1,me=e-1
+syn match   abapStatement "\(\W\|^\)\(EXIT\W\+FROM\W\+STEP\W\+LOOP\|EXIT\)\(\W\|$\)"ms=s+1,me=e-1
+syn match   abapStatement "\(\W\|^\)\(BEGIN\W\+OF\W\+\(BLOCK\|LINE\)\|BEGIN\W\+OF\)\(\W\|$\)"ms=s+1,me=e-1
+syn match   abapStatement "\(\W\|^\)\(END\W\+OF\W\+\(BLOCK\|LINE\)\|END\W\+OF\)\(\W\|$\)"ms=s+1,me=e-1
+syn match   abapStatement "\(\W\|^\)IS\W\+INITIAL\(\W\|$\)"ms=s+1,me=e-1
+syn match   abapStatement "\(\W\|^\)NO\W\+INTERVALS\(\W\|$\)"ms=s+1,me=e-1
+syn match   abapStatement "\(\W\|^\)SEPARATED\W\+BY\(\W\|$\)"ms=s+1,me=e-1
+syn match   abapStatement "\(\W\|^\)\(USING\W\+\(EDIT\W\+MASK\)\|USING\)\(\W\|$\)"ms=s+1,me=e-1
+syn match   abapStatement "\(\W\|^\)\(WHERE\W\+\(LINE\)\)\(\W\|$\)"ms=s+1,me=e-1
+syn match   abapStatement "\(\W\|^\)RADIOBUTTON\W\+GROUP\(\W\|$\)"ms=s+1,me=e-1
+syn match   abapStatement "\(\W\|^\)REF\W\+TO\(\W\|$\)"ms=s+1,me=e-1
+
+" Special ABAP specific tables:
+syn match   abapSpecial       "\(\W\|^\)\(sy\|\(p\|pa\)\d\d\d\d\|t\d\d\d.\|innnn\)\(\W\|$\)"ms=s+1,me=e-1
+syn match   abapSpecialTables "\(sy\|\(p\|pa\)\d\d\d\d\|t\d\d\d.\|innnn\)-"me=e-1 contained
+syn match   abapSpecial       "\(\W\|^\)\w\+-\(\w\+-\w\+\|\w\+\)"ms=s+1 contains=abapSpecialTables
+
+" Pointer
+syn match   abapSpecial  "<\w\+>"
+
+" Abap constants:
+syn keyword abapSpecial  TRUE FALSE NULL SPACE
+
+" Includes
+syn region abapInclude   start="include" end="." contains=abapComment
+
+" Types
+syn keyword abapTypes    c n i p f d t x
+
+" Atritmitic operators
+syn keyword abapOperator abs sign ceil floor trunc frac acos asin atan cos sin tan
+syn keyword abapOperator cosh sinh tanh exp log log10 sqrt
+
+" String operators
+syn keyword abapOperator strlen xstrlen charlen numofchar dbmaxlen
+
+" Table operators
+syn keyword abapOperator lines
+
+" Table operators (SELECT operators)
+syn keyword abapOperator INTO FROM WHERE GROUP BY HAVING ORDER BY SINGLE
+syn keyword abapOperator APPENDING CORRESPONDING FIELDS OF TABLE
+syn keyword abapOperator LEFT RIGHT OUTER INNER JOIN AS CLIENT SPECIFIED BYPASSING BUFFER UP TO ROWS CONNECTING
+syn keyword abapOperator EQ NE LT LE GT GE NOT AND OR XOR IN LIKE BETWEEN
+
+" An error? Not strictly... but cannot think of reason this is intended.
+syn match   abapError    "\.\."
+
+" Comments
+syn region  abapComment  start="^\*" end="$" contains=abapTodo
+syn match   abapComment  "\".*" contains=abapTodo
+syn keyword abapTodo     contained TODO NOTE
+
+" Define the default highlighting.
+" For version 5.7 and earlier: only when not done already
+" For version 5.8 and later: only when an item doesn't have highlighting yet
+if version >= 508 || !exists("did_abap_syntax_inits")
+  if version < 508
+    let did_abap_syntax_inits = 1
+    command -nargs=+ HiLink hi link <args>
+  else
+    command -nargs=+ HiLink hi def link <args>
+  endif
+
+  HiLink abapError          Error
+  HiLink abapComment        Comment
+  HiLink abapInclude        Include
+  HiLink abapSpecial        Special
+  HiLink abapSpecialTables  PreProc
+  HiLink abapSymbolOperator abapOperator
+  HiLink abapOperator       Operator
+  HiLink abapStatement      Statement
+  HiLink abapString         String
+  HiLink abapFloat          Float
+  HiLink abapNumber         Number
+  HiLink abapHex            Number
+
+  delcommand HiLink
+endif
+
+let b:current_syntax = "abap"
+
+" vim: ts=8 sw=2
+
--- /dev/null
+++ b/lib/vimfiles/syntax/abaqus.vim
@@ -1,0 +1,48 @@
+" Vim syntax file
+" Language:	Abaqus finite element input file (www.hks.com)
+" Maintainer:	Carl Osterwisch <osterwischc@asme.org>
+" Last Change:	2002 Feb 24
+" Remark:	Huge improvement in folding performance--see filetype plugin
+
+" For version 5.x: Clear all syntax items
+" For version 6.x: Quit when a syntax file was already loaded
+if version < 600
+  syntax clear
+elseif exists("b:current_syntax")
+  finish
+endif
+
+" Abaqus comment lines
+syn match abaqusComment	"^\*\*.*$"
+
+" Abaqus keyword lines
+syn match abaqusKeywordLine "^\*\h.*" contains=abaqusKeyword,abaqusParameter,abaqusValue display
+syn match abaqusKeyword "^\*\h[^,]*" contained display
+syn match abaqusParameter ",[^,=]\+"lc=1 contained display
+syn match abaqusValue	"=\s*[^,]*"lc=1 contained display
+
+" Illegal syntax
+syn match abaqusBadLine	"^\s\+\*.*" display
+
+" Define the default highlighting.
+" For version 5.7 and earlier: only when not done already
+" For version 5.8 and later: only when an item doesn't have highlighting yet
+if version >= 508 || !exists("did_abaqus_syn_inits")
+	if version < 508
+		let did_abaqus_syn_inits = 1
+		command -nargs=+ HiLink hi link <args>
+	else
+		command -nargs=+ HiLink hi def link <args>
+	endif
+
+	" The default methods for highlighting.  Can be overridden later
+	HiLink abaqusComment	Comment
+	HiLink abaqusKeyword	Statement
+	HiLink abaqusParameter	Identifier
+	HiLink abaqusValue	Constant
+	HiLink abaqusBadLine    Error
+
+	delcommand HiLink
+endif
+
+let b:current_syntax = "abaqus"
--- /dev/null
+++ b/lib/vimfiles/syntax/abc.vim
@@ -1,0 +1,64 @@
+" Vim syntax file
+" Language:	abc music notation language
+" Maintainer:	James Allwright <J.R.Allwright@westminster.ac.uk>
+" URL:		http://perun.hscs.wmin.ac.uk/~jra/vim/syntax/abc.vim
+" Last Change:	27th April 2001
+
+" For version 5.x: Clear all syntax items
+" For version 6.x: Quit when a syntax file was already loaded
+if version < 600
+  syntax clear
+elseif exists("b:current_syntax")
+  finish
+endif
+
+" tags
+syn region abcGuitarChord start=+"[A-G]+ end=+"+ contained
+syn match abcNote "z[1-9]*[0-9]*" contained
+syn match abcNote "z[1-9]*[0-9]*/[248]\=" contained
+syn match abcNote "[=_\^]\{,2}[A-G],*[1-9]*[0-9]*" contained
+syn match abcNote "[=_\^]\{,2}[A-G],*[1-9]*[0-9]*/[248]\=" contained
+syn match abcNote "[=_\^]\{,2}[a-g]'*[1-9]*[0-9]*"  contained
+syn match abcNote "[=_\^]\{,2}[a-g]'*[1-9]*[0-9]*/[248]\="  contained
+syn match abcBar "|"  contained
+syn match abcBar "[:|][:|]"  contained
+syn match abcBar ":|2"  contained
+syn match abcBar "|1"  contained
+syn match abcBar "\[[12]"  contained
+syn match abcTuple "([1-9]\+:\=[0-9]*:\=[0-9]*" contained
+syn match abcBroken "<\|<<\|<<<\|>\|>>\|>>>" contained
+syn match abcTie    "-"
+syn match abcHeadField "^[A-EGHIK-TVWXZ]:.*$" contained
+syn match abcBodyField "^[KLMPQWVw]:.*$" contained
+syn region abcHeader start="^X:" end="^K:.*$" contained contains=abcHeadField,abcComment keepend
+syn region abcTune start="^X:" end="^ *$" contains=abcHeader,abcComment,abcBar,abcNote,abcBodyField,abcGuitarChord,abcTuple,abcBroken,abcTie
+syn match abcComment "%.*$"
+
+
+" Define the default highlighting.
+" For version 5.7 and earlier: only when not done already
+" For version 5.8 and later: only when an item doesn't have highlighting yet
+if version >= 508 || !exists("did_abc_syn_inits")
+  if version < 508
+    let did_abc_syn_inits = 1
+    command -nargs=+ HiLink hi link <args>
+  else
+    command -nargs=+ HiLink hi def link <args>
+  endif
+
+  HiLink abcComment		Comment
+  HiLink abcHeadField		Type
+  HiLink abcBodyField		Special
+  HiLink abcBar			Statement
+  HiLink abcTuple			Statement
+  HiLink abcBroken			Statement
+  HiLink abcTie			Statement
+  HiLink abcGuitarChord	Identifier
+  HiLink abcNote			Constant
+
+  delcommand HiLink
+endif
+
+let b:current_syntax = "abc"
+
+" vim: ts=4
--- /dev/null
+++ b/lib/vimfiles/syntax/abel.vim
@@ -1,0 +1,167 @@
+" Vim syntax file
+" Language:	ABEL
+" Maintainer:	John Cook <john.cook@kla-tencor.com>
+" Last Change:	2001 Sep 2
+
+" For version 5.x: Clear all syntax items
+" For version 6.x: Quit when a syntax file was already loaded
+if version < 600
+  syntax clear
+elseif exists("b:current_syntax")
+  finish
+endif
+
+" this language is oblivious to case
+syn case ignore
+
+" A bunch of keywords
+syn keyword abelHeader		module title device options
+syn keyword abelSection		declarations equations test_vectors end
+syn keyword abelDeclaration	state truth_table state_diagram property
+syn keyword abelType		pin node attribute constant macro library
+
+syn keyword abelTypeId		com reg neg pos buffer dc reg_d reg_t contained
+syn keyword abelTypeId		reg_sr reg_jk reg_g retain xor invert contained
+
+syn keyword abelStatement	when then else if with endwith case endcase
+syn keyword abelStatement	fuses expr trace
+
+" option to omit obsolete statements
+if exists("abel_obsolete_ok")
+  syn keyword abelStatement enable flag in
+else
+  syn keyword abelError enable flag in
+endif
+
+" directives
+syn match abelDirective "@alternate"
+syn match abelDirective "@standard"
+syn match abelDirective "@const"
+syn match abelDirective "@dcset"
+syn match abelDirective "@include"
+syn match abelDirective "@page"
+syn match abelDirective "@radix"
+syn match abelDirective "@repeat"
+syn match abelDirective "@irp"
+syn match abelDirective "@expr"
+syn match abelDirective "@if"
+syn match abelDirective "@ifb"
+syn match abelDirective "@ifnb"
+syn match abelDirective "@ifdef"
+syn match abelDirective "@ifndef"
+syn match abelDirective "@ifiden"
+syn match abelDirective "@ifniden"
+
+syn keyword abelTodo contained TODO XXX FIXME
+
+" wrap up type identifiers to differentiate them from normal strings
+syn region abelSpecifier start='istype' end=';' contains=abelTypeIdChar,abelTypeId,abelTypeIdEnd keepend
+syn match  abelTypeIdChar "[,']" contained
+syn match  abelTypeIdEnd  ";" contained
+
+" string contstants and special characters within them
+syn match  abelSpecial contained "\\['\\]"
+syn region abelString start=+'+ skip=+\\"+ end=+'+ contains=abelSpecial
+
+" valid integer number formats (decimal, binary, octal, hex)
+syn match abelNumber "\<[-+]\=[0-9]\+\>"
+syn match abelNumber "\^d[0-9]\+\>"
+syn match abelNumber "\^b[01]\+\>"
+syn match abelNumber "\^o[0-7]\+\>"
+syn match abelNumber "\^h[0-9a-f]\+\>"
+
+" special characters
+" (define these after abelOperator so ?= overrides ?)
+syn match abelSpecialChar "[\[\](){},;:?]"
+
+" operators
+syn match abelLogicalOperator "[!#&$]"
+syn match abelRangeOperator "\.\."
+syn match abelAlternateOperator "[/*+]"
+syn match abelAlternateOperator ":[+*]:"
+syn match abelArithmeticOperator "[-%]"
+syn match abelArithmeticOperator "<<"
+syn match abelArithmeticOperator ">>"
+syn match abelRelationalOperator "[<>!=]="
+syn match abelRelationalOperator "[<>]"
+syn match abelAssignmentOperator "[:?]\=="
+syn match abelAssignmentOperator "?:="
+syn match abelTruthTableOperator "->"
+
+" signal extensions
+syn match abelExtension "\.aclr\>"
+syn match abelExtension "\.aset\>"
+syn match abelExtension "\.clk\>"
+syn match abelExtension "\.clr\>"
+syn match abelExtension "\.com\>"
+syn match abelExtension "\.fb\>"
+syn match abelExtension "\.[co]e\>"
+syn match abelExtension "\.l[eh]\>"
+syn match abelExtension "\.fc\>"
+syn match abelExtension "\.pin\>"
+syn match abelExtension "\.set\>"
+syn match abelExtension "\.[djksrtq]\>"
+syn match abelExtension "\.pr\>"
+syn match abelExtension "\.re\>"
+syn match abelExtension "\.a[pr]\>"
+syn match abelExtension "\.s[pr]\>"
+
+" special constants
+syn match abelConstant "\.[ckudfpxz]\."
+syn match abelConstant "\.sv[2-9]\."
+
+" one-line comments
+syn region abelComment start=+"+ end=+"\|$+ contains=abelNumber,abelTodo
+" option to prevent C++ style comments
+if !exists("abel_cpp_comments_illegal")
+  syn region abelComment start=+//+ end=+$+ contains=abelNumber,abelTodo
+endif
+
+syn sync minlines=1
+
+" Define the default highlighting.
+" For version 5.7 and earlier: only when not done already
+" For version 5.8 and later: only when an item doesn't have highlighting yet
+if version >= 508 || !exists("did_abel_syn_inits")
+  if version < 508
+    let did_abel_syn_inits = 1
+    command -nargs=+ HiLink hi link <args>
+  else
+    command -nargs=+ HiLink hi def link <args>
+  endif
+
+  " The default highlighting.
+  HiLink abelHeader		abelStatement
+  HiLink abelSection		abelStatement
+  HiLink abelDeclaration	abelStatement
+  HiLink abelLogicalOperator	abelOperator
+  HiLink abelRangeOperator	abelOperator
+  HiLink abelAlternateOperator	abelOperator
+  HiLink abelArithmeticOperator	abelOperator
+  HiLink abelRelationalOperator	abelOperator
+  HiLink abelAssignmentOperator	abelOperator
+  HiLink abelTruthTableOperator	abelOperator
+  HiLink abelSpecifier		abelStatement
+  HiLink abelOperator		abelStatement
+  HiLink abelStatement		Statement
+  HiLink abelIdentifier		Identifier
+  HiLink abelTypeId		abelType
+  HiLink abelTypeIdChar		abelType
+  HiLink abelType		Type
+  HiLink abelNumber		abelString
+  HiLink abelString		String
+  HiLink abelConstant		Constant
+  HiLink abelComment		Comment
+  HiLink abelExtension		abelSpecial
+  HiLink abelSpecialChar	abelSpecial
+  HiLink abelTypeIdEnd		abelSpecial
+  HiLink abelSpecial		Special
+  HiLink abelDirective		PreProc
+  HiLink abelTodo		Todo
+  HiLink abelError		Error
+
+  delcommand HiLink
+endif
+
+let b:current_syntax = "abel"
+" vim:ts=8
--- /dev/null
+++ b/lib/vimfiles/syntax/acedb.vim
@@ -1,0 +1,123 @@
+" Vim syntax file
+" Language:	AceDB model files
+" Maintainer:	Stewart Morris (Stewart.Morris@ed.ac.uk)
+" Last change:	Thu Apr 26 10:38:01 BST 2001
+" URL:		http://www.ed.ac.uk/~swmorris/vim/acedb.vim
+
+" Syntax file to handle all $ACEDB/wspec/*.wrm files, primarily models.wrm
+" AceDB software is available from http://www.acedb.org
+
+" For version 5.x: Clear all syntax items
+" For version 6.x: Quit when a syntax file was already loaded
+if version < 600
+  syntax clear
+elseif exists("b:current_syntax")
+  finish
+endif
+
+syn keyword	acedbXref	XREF
+syn keyword	acedbModifier	UNIQUE REPEAT
+
+syn case ignore
+syn keyword	acedbModifier	Constraints
+syn keyword	acedbType	DateType Int Text Float
+
+" Magic tags from: http://genome.cornell.edu/acedocs/magic/summary.html
+syn keyword	acedbMagic	pick_me_to_call No_cache Non_graphic Title
+syn keyword	acedbMagic	Flipped Centre Extent View Default_view
+syn keyword	acedbMagic	From_map Minimal_view Main_Marker Map Includes
+syn keyword	acedbMagic	Mapping_data More_data Position Ends Left Right
+syn keyword	acedbMagic	Multi_Position Multi_Ends With Error Relative
+syn keyword	acedbMagic	Min Anchor Gmap Grid_map Grid Submenus Cambridge
+syn keyword	acedbMagic	No_buttons Columns Colour Surround_colour Tag
+syn keyword	acedbMagic	Scale_unit Cursor Cursor_on Cursor_unit
+syn keyword	acedbMagic	Locator Magnification Projection_lines_on
+syn keyword	acedbMagic	Marker_points Marker_intervals Contigs
+syn keyword	acedbMagic	Physical_genes Two_point Multi_point Likelihood
+syn keyword	acedbMagic	Point_query Point_yellow Point_width
+syn keyword	acedbMagic	Point_pne Point_pe Point_nne Point_ne
+syn keyword	acedbMagic	Derived_tags DT_query DT_width DT_no_duplicates
+syn keyword	acedbMagic	RH_data RH_query RH_spacing RH_show_all
+syn keyword	acedbMagic	Names_on Width Symbol Colours Pne Pe Nne pMap
+syn keyword	acedbMagic	Sequence Gridded FingerPrint In_Situ Cosmid_grid
+syn keyword	acedbMagic	Layout Lines_at Space_at No_stagger A1_labelling
+syn keyword	acedbMagic	DNA Structure From Source Source_Exons
+syn keyword	acedbMagic	Coding CDS Transcript Assembly_tags Allele
+syn keyword	acedbMagic	Display Colour Frame_sensitive Strand_sensitive
+syn keyword	acedbMagic	Score_bounds Percent Bumpable Width Symbol
+syn keyword	acedbMagic	Blixem_N Address E_mail Paper Reference Title
+syn keyword	acedbMagic	Point_1 Point_2 Calculation Full One_recombinant
+syn keyword	acedbMagic	Tested Selected_trans Backcross Back_one
+syn keyword	acedbMagic	Dom_semi Dom_let Direct Complex_mixed Calc
+syn keyword	acedbMagic	Calc_upper_conf Item_1 Item_2 Results A_non_B
+syn keyword	acedbMagic	Score Score_by_offset Score_by_width
+syn keyword	acedbMagic	Right_priority Blastn Blixem Blixem_X
+syn keyword	acedbMagic	Journal Year Volume Page Author
+syn keyword	acedbMagic	Selected One_all Recs_all One_let
+syn keyword	acedbMagic	Sex_full Sex_one Sex_cis Dom_one Dom_selected
+syn keyword	acedbMagic	Calc_distance Calc_lower_conf Canon_for_cosmid
+syn keyword	acedbMagic	Reversed_physical Points Positive Negative
+syn keyword	acedbMagic	Point_error_scale Point_segregate_ordered
+syn keyword	acedbMagic	Point_symbol Interval_JTM Interval_RD
+syn keyword	acedbMagic	EMBL_feature Homol Feature
+syn keyword	acedbMagic	DT_tag Spacer Spacer_colour Spacer_width
+syn keyword	acedbMagic	RH_positive RH_negative RH_contradictory Query
+syn keyword	acedbMagic	Clone Y_remark PCR_remark Hybridizes_to
+syn keyword	acedbMagic	Row Virtual_row Mixed In_pool Subpool B_non_A
+syn keyword	acedbMagic	Interval_SRK Point_show_marginal Subsequence
+syn keyword	acedbMagic	Visible Properties Transposon
+
+syn match	acedbClass	"^?\w\+\|^#\w\+"
+syn match	acedbComment	"//.*"
+syn region	acedbComment	start="/\*" end="\*/"
+syn match	acedbComment	"^#\W.*"
+syn match	acedbHelp	"^\*\*\w\+$"
+syn match	acedbTag	"[^^]?\w\+\|[^^]#\w\+"
+syn match	acedbBlock	"//#.\+#$"
+syn match	acedbOption	"^_[DVH]\S\+"
+syn match	acedbFlag	"\s\+-\h\+"
+syn match	acedbSubclass	"^Class"
+syn match	acedbSubtag	"^Visible\|^Is_a_subclass_of\|^Filter\|^Hidden"
+syn match	acedbNumber	"\<\d\+\>"
+syn match	acedbNumber	"\<\d\+\.\d\+\>"
+syn match	acedbHyb	"\<Positive_\w\+\>\|\<Negative\w\+\>"
+syn region	acedbString	start=/"/ end=/"/ skip=/\\"/ oneline
+
+" Rest of syntax highlighting rules start here
+
+" Define the default highlighting.
+" For version 5.7 and earlier: only when not done already
+" For version 5.8 and later: only when an item doesn't have highlighting yet
+if version >= 508 || !exists("did_acedb_syn_inits")
+  if version < 508
+    let did_acedb_syn_inits = 1
+    command -nargs=+ HiLink hi link <args>
+  else
+    command -nargs=+ HiLink hi def link <args>
+  endif
+
+  HiLink acedbMagic	Special
+  HiLink acedbHyb	Special
+  HiLink acedbType	Type
+  HiLink acedbOption	Type
+  HiLink acedbSubclass	Type
+  HiLink acedbSubtag	Include
+  HiLink acedbFlag	Include
+  HiLink acedbTag	Include
+  HiLink acedbClass	Todo
+  HiLink acedbHelp	Todo
+  HiLink acedbXref	Identifier
+  HiLink acedbModifier	Label
+  HiLink acedbComment	Comment
+  HiLink acedbBlock	ModeMsg
+  HiLink acedbNumber	Number
+  HiLink acedbString	String
+
+  delcommand HiLink
+endif
+
+let b:current_syntax = "acedb"
+
+" The structure of the model.wrm file is sensitive to mixed tab and space
+" indentation and assumes tabs are 8 so...
+se ts=8
--- /dev/null
+++ b/lib/vimfiles/syntax/ada.vim
@@ -1,0 +1,367 @@
+"----------------------------------------------------------------------------
+"  Description: Vim Ada syntax file
+"     Language: Ada (2005)
+"	   $Id: ada.vim,v 1.2 2007/05/05 18:22:26 vimboss Exp $
+"    Copyright: Copyright (C) 2006 Martin Krischik
+"   Maintainer: Martin Krischik
+"		David A. Wheeler <dwheeler@dwheeler.com>
+"		Simon Bradley <simon.bradley@pitechnology.com>
+" Contributors: Preben Randhol.
+"      $Author: vimboss $
+"	 $Date: 2007/05/05 18:22:26 $
+"      Version: 4.2
+"    $Revision: 1.2 $
+"     $HeadURL: https://svn.sourceforge.net/svnroot/gnuada/trunk/tools/vim/syntax/ada.vim $
+"		http://www.dwheeler.com/vim
+"      History: 24.05.2006 MK Unified Headers
+"		26.05.2006 MK ' should not be in iskeyword.
+"		16.07.2006 MK Ada-Mode as vim-ball
+"		02.10.2006 MK Better folding.
+"		15.10.2006 MK Bram's suggestion for runtime integration
+"		05.11.2006 MK Spell check for comments and strings only
+"		05.11.2006 MK Bram suggested to save on spaces
+"    Help Page: help ft-ada-syntax
+"------------------------------------------------------------------------------
+" The formal spec of Ada 2005 (ARM) is the "Ada 2005 Reference Manual".
+" For more Ada 2005 info, see http://www.gnuada.org and http://www.adapower.com.
+"
+" This vim syntax file works on vim 7.0 only and makes use of most of Voim 7.0 
+" advanced features.
+"------------------------------------------------------------------------------
+
+if exists("b:current_syntax") || version < 700
+    finish
+endif
+
+let b:current_syntax = "ada"
+
+" Section: Ada is entirely case-insensitive. {{{1
+"
+syntax   case ignore
+setlocal nosmartcase
+setlocal ignorecase
+
+" Section: Highlighting commands {{{1
+"
+" There are 72 reserved words in total in Ada2005. Some keywords are
+" used in more than one way. For example:
+" 1. "end" is a general keyword, but "end if" ends a Conditional.
+" 2. "then" is a conditional, but "and then" is an operator.
+"
+for b:Item in g:ada#Keywords
+   " Standard Exceptions (including I/O).
+   " We'll highlight the standard exceptions, similar to vim's Python mode.
+   " It's possible to redefine the standard exceptions as something else,
+   " but doing so is very bad practice, so simply highlighting them makes sense.
+   if b:Item['kind'] == "x"
+      execute "syntax keyword adaException " . b:Item['word']
+   endif
+   if b:Item['kind'] == "a"
+      execute 'syntax match adaAttribute "\V' . b:Item['word'] . '"'
+   endif
+   " We don't normally highlight types in package Standard
+   " (Integer, Character, Float, etc.).  I don't think it looks good
+   " with the other type keywords, and many Ada programs define
+   " so many of their own types that it looks inconsistent.
+   " However, if you want this highlighting, turn on "ada_standard_types".
+   " For package Standard's definition, see ARM section A.1.
+   if b:Item['kind'] == "t" && exists ("g:ada_standard_types")
+      execute "syntax keyword adaBuiltinType " . b:Item['word']
+   endif
+endfor
+
+" Section: others {{{1
+"
+syntax keyword  adaLabel	others
+
+" Section: Operatoren {{{1
+"
+syntax keyword  adaOperator abs mod not rem xor
+syntax match    adaOperator "\<and\>"
+syntax match    adaOperator "\<and\s\+then\>"
+syntax match    adaOperator "\<or\>"
+syntax match    adaOperator "\<or\s\+else\>"
+syntax match    adaOperator "[-+*/<>&]"
+syntax keyword  adaOperator **
+syntax match    adaOperator "[/<>]="
+syntax keyword  adaOperator =>
+syntax match    adaOperator "\.\."
+syntax match    adaOperator "="
+
+" Section: <> {{{1
+"
+" Handle the box, <>, specially:
+"
+syntax keyword  adaSpecial	    <>
+
+" Section: rainbow color {{{1
+"
+if exists("g:ada_rainbow_color")
+    syntax match	adaSpecial	 "[:;.,]"
+    runtime plugin/Rainbow_Parenthsis.vim
+else
+    syntax match	adaSpecial	 "[:;().,]"
+endif
+
+" Section: := {{{1
+"
+" We won't map "adaAssignment" by default, but we need to map ":=" to
+" something or the "=" inside it will be mislabelled as an operator.
+" Note that in Ada, assignment (:=) is not considered an operator.
+"
+syntax match adaAssignment		":="
+
+" Section: Numbers, including floating point, exponents, and alternate bases. {{{1
+"
+syntax match   adaNumber		"\<\d[0-9_]*\(\.\d[0-9_]*\)\=\([Ee][+-]\=\d[0-9_]*\)\=\>"
+syntax match   adaNumber		"\<\d\d\=#\x[0-9A-Fa-f_]*\(\.\x[0-9A-Fa-f_]*\)\=#\([Ee][+-]\=\d[0-9_]*\)\="
+
+" Section: Identify leading numeric signs {{{1
+"
+" In "A-5" the "-" is an operator, " but in "A:=-5" the "-" is a sign. This
+" handles "A3+-5" (etc.) correctly.  " This assumes that if you put a
+" don't put a space after +/- when it's used " as an operator, you won't
+" put a space before it either -- which is true " in code I've seen.
+"
+syntax match adaSign "[[:space:]<>=(,|:;&*/+-][+-]\d"lc=1,hs=s+1,he=e-1,me=e-1
+
+" Section: Labels for the goto statement. {{{1
+"
+syntax region  adaLabel		start="<<"  end=">>"
+
+" Section: Boolean Constants {{{1
+" Boolean Constants.
+syntax keyword adaBoolean	true false
+
+" Section: Warn C/C++ {{{1
+"
+" Warn people who try to use C/C++ notation erroneously:
+"
+syntax match adaError "//"
+syntax match adaError "/\*"
+syntax match adaError "=="
+
+
+" Section: Space Errors {{{1
+"
+if exists("g:ada_space_errors")
+   if !exists("g:ada_no_trail_space_error")
+       syntax match   adaSpaceError	 excludenl "\s\+$"
+   endif
+   if !exists("g:ada_no_tab_space_error")
+      syntax match   adaSpaceError	 " \+\t"me=e-1
+   endif
+   if !exists("g:ada_all_tab_usage")
+      syntax match   adaSpecial	 "\t"
+   endif
+endif
+
+" Section: end {{{1
+" Unless special ("end loop", "end if", etc.), "end" marks the end of a
+" begin, package, task etc. Assiging it to adaEnd.
+syntax match    adaEnd	"\<end\>"
+
+syntax keyword  adaPreproc		 pragma
+
+syntax keyword  adaRepeat	 exit for loop reverse while
+syntax match    adaRepeat		   "\<end\s\+loop\>"
+
+syntax keyword  adaStatement accept delay goto raise requeue return
+syntax keyword  adaStatement terminate
+syntax match    adaStatement  "\<abort\>"
+
+" Section: Handle Ada's record keywords. {{{1
+"
+" 'record' usually starts a structure, but "with null record;" does not,
+" and 'end record;' ends a structure.  The ordering here is critical -
+" 'record;' matches a "with null record", so make it a keyword (this can
+" match when the 'with' or 'null' is on a previous line).
+" We see the "end" in "end record" before the word record, so we match that
+" pattern as adaStructure (and it won't match the "record;" pattern).
+"
+syntax match adaStructure   "\<record\>"	contains=adaRecord
+syntax match adaStructure   "\<end\s\+record\>"	contains=adaRecord
+syntax match adaKeyword	    "\<record;"me=e-1
+
+" Section: type classes {{{1
+"
+syntax keyword adaStorageClass	abstract access aliased array at constant delta
+syntax keyword adaStorageClass	digits limited of private range tagged
+syntax keyword adaStorageClass	interface synchronized
+syntax keyword adaTypedef	subtype type
+
+" Section: Conditionals {{{1
+"
+" "abort" after "then" is a conditional of its own.
+"
+syntax match    adaConditional  "\<then\>"
+syntax match    adaConditional	"\<then\s\+abort\>"
+syntax match    adaConditional	"\<else\>"
+syntax match    adaConditional	"\<end\s\+if\>"
+syntax match    adaConditional	"\<end\s\+case\>"
+syntax match    adaConditional	"\<end\s\+select\>"
+syntax keyword  adaConditional	if case select
+syntax keyword  adaConditional	elsif when
+
+" Section: other keywords {{{1
+syntax match    adaKeyword	    "\<is\>" contains=adaRecord
+syntax keyword  adaKeyword	    all do exception in new null out
+syntax keyword  adaKeyword	    separate until overriding
+
+" Section: begin keywords {{{1
+"
+" These keywords begin various constructs, and you _might_ want to
+" highlight them differently.
+"
+syntax keyword  adaBegin	begin body declare entry generic
+syntax keyword  adaBegin	protected renames task
+
+syntax match    adaBegin	"\<function\>" contains=adaFunction
+syntax match    adaBegin	"\<procedure\>" contains=adaProcedure
+syntax match    adaBegin	"\<package\>" contains=adaPackage
+
+if exists("ada_with_gnat_project_files")
+   syntax keyword adaBegin	project
+endif
+
+" Section: with, use {{{1
+"
+if exists("ada_withuse_ordinary")
+   " Don't be fancy. Display "with" and "use" as ordinary keywords in all cases.
+   syntax keyword adaKeyword		with use
+else
+   " Highlight "with" and "use" clauses like C's "#include" when they're used
+   " to reference other compilation units; otherwise they're ordinary keywords.
+   " If we have vim 6.0 or later, we'll use its advanced pattern-matching
+   " capabilities so that we won't match leading spaces.
+   syntax match adaKeyword	"\<with\>"
+   syntax match adaKeyword	"\<use\>"
+   syntax match adaBeginWith	"^\s*\zs\(\(with\(\s\+type\)\=\)\|\(use\)\)\>" contains=adaInc
+   syntax match adaSemiWith	";\s*\zs\(\(with\(\s\+type\)\=\)\|\(use\)\)\>" contains=adaInc
+   syntax match adaInc		"\<with\>" contained contains=NONE
+   syntax match adaInc		"\<with\s\+type\>" contained contains=NONE
+   syntax match adaInc		"\<use\>" contained contains=NONE
+   " Recognize "with null record" as a keyword (even the "record").
+   syntax match adaKeyword	"\<with\s\+null\s\+record\>"
+   " Consider generic formal parameters of subprograms and packages as keywords.
+   syntax match adaKeyword	";\s*\zswith\s\+\(function\|procedure\|package\)\>"
+   syntax match adaKeyword	"^\s*\zswith\s\+\(function\|procedure\|package\)\>"
+endif
+
+" Section: String and character constants. {{{1
+"
+syntax region  adaString	contains=@Spell start=+"+ skip=+""+ end=+"+ 
+syntax match   adaCharacter "'.'"
+
+" Section: Todo (only highlighted in comments) {{{1
+"
+syntax keyword adaTodo contained TODO FIXME XXX NOTE
+
+" Section: Comments. {{{1
+"
+syntax region  adaComment 
+    \ oneline 
+    \ contains=adaTodo,adaLineError,@Spell
+    \ start="--" 
+    \ end="$"
+
+" Section: line errors {{{1
+"
+" Note: Line errors have become quite slow with Vim 7.0
+"
+if exists("g:ada_line_errors")
+    syntax match adaLineError "\(^.\{79}\)\@<=."  contains=ALL containedin=ALL
+endif
+
+" Section: syntax folding {{{1
+"
+"	Syntax folding is very tricky - for now I still suggest to use
+"	indent folding
+"
+if exists("g:ada_folding") && g:ada_folding[0] == 's'
+   if stridx (g:ada_folding, 'p') >= 0
+      syntax region adaPackage
+         \ start="\(\<package\s\+body\>\|\<package\>\)\s*\z(\k*\)"
+         \ end="end\s\+\z1\s*;"
+         \ keepend extend transparent fold contains=ALL
+   endif
+   if stridx (g:ada_folding, 'f') >= 0
+      syntax region adaProcedure
+         \ start="\<procedure\>\s*\z(\k*\)"
+         \ end="\<end\>\s\+\z1\s*;"
+         \ keepend extend transparent fold contains=ALL
+      syntax region adaFunction
+         \ start="\<procedure\>\s*\z(\k*\)"
+         \ end="end\s\+\z1\s*;"
+         \ keepend extend transparent fold contains=ALL
+   endif
+   if stridx (g:ada_folding, 'f') >= 0
+      syntax region adaRecord
+         \ start="\<is\s\+record\>"
+         \ end="\<end\s\+record\>"
+         \ keepend extend transparent fold contains=ALL
+   endif
+endif
+
+" Section: The default methods for highlighting. Can be overridden later. {{{1
+"
+highlight def link adaCharacter	    Character
+highlight def link adaComment	    Comment
+highlight def link adaConditional   Conditional
+highlight def link adaKeyword	    Keyword
+highlight def link adaLabel	    Label
+highlight def link adaNumber	    Number
+highlight def link adaSign	    Number
+highlight def link adaOperator	    Operator
+highlight def link adaPreproc	    PreProc
+highlight def link adaRepeat	    Repeat
+highlight def link adaSpecial	    Special
+highlight def link adaStatement	    Statement
+highlight def link adaString	    String
+highlight def link adaStructure	    Structure
+highlight def link adaTodo	    Todo
+highlight def link adaType	    Type
+highlight def link adaTypedef	    Typedef
+highlight def link adaStorageClass  StorageClass
+highlight def link adaBoolean	    Boolean
+highlight def link adaException	    Exception
+highlight def link adaAttribute	    Tag
+highlight def link adaInc	    Include
+highlight def link adaError	    Error
+highlight def link adaSpaceError    Error
+highlight def link adaLineError	    Error
+highlight def link adaBuiltinType   Type
+highlight def link adaAssignment    Special
+
+" Subsection: Begin, End {{{2
+"
+if exists ("ada_begin_preproc")
+   " This is the old default display:
+   highlight def link adaBegin   PreProc
+   highlight def link adaEnd     PreProc
+else
+   " This is the new default display:
+   highlight def link adaBegin   Keyword
+   highlight def link adaEnd     Keyword
+endif
+
+
+" Section: formatoptions {{{1
+"
+setlocal formatoptions+=ron
+
+" Section: sync {{{1
+"
+" We don't need to look backwards to highlight correctly;
+" this speeds things up greatly.
+syntax sync minlines=1 maxlines=1
+
+finish " 1}}}
+
+"------------------------------------------------------------------------------
+"   Copyright (C) 2006	Martin Krischik
+"
+"   Vim is Charityware - see ":help license" or uganda.txt for licence details.
+"------------------------------------------------------------------------------
+"vim: textwidth=78 nowrap tabstop=8 shiftwidth=3 softtabstop=3 noexpandtab
+"vim: foldmethod=marker
--- /dev/null
+++ b/lib/vimfiles/syntax/aflex.vim
@@ -1,0 +1,100 @@
+
+" Vim syntax file
+" Language:	AfLex (from Lex syntax file)
+" Maintainer:	Mathieu Clabaut <mathieu.clabaut@free.fr>
+" LastChange:	02 May 2001
+" Original:	Lex, maintained by Dr. Charles E. Campbell, Jr.
+" Comment:	Replaced sourcing c.vim file by ada.vim and rename lex*
+"		in aflex*
+
+" For version 5.x: Clear all syntax items
+" For version 6.x: Quit when a syntax file was already loaded
+if version < 600
+   syntax clear
+elseif exists("b:current_syntax")
+   finish
+endif
+
+" Read the Ada syntax to start with
+if version < 600
+   so <sfile>:p:h/ada.vim
+else
+   runtime! syntax/ada.vim
+   unlet b:current_syntax
+endif
+
+
+" --- AfLex stuff ---
+
+"I'd prefer to use aflex.* , but it doesn't handle forward definitions yet
+syn cluster aflexListGroup		contains=aflexAbbrvBlock,aflexAbbrv,aflexAbbrv,aflexAbbrvRegExp,aflexInclude,aflexPatBlock,aflexPat,aflexBrace,aflexPatString,aflexPatTag,aflexPatTag,aflexPatComment,aflexPatCodeLine,aflexMorePat,aflexPatSep,aflexSlashQuote,aflexPatCode,cInParen,cUserLabel,cOctalZero,cCppSkip,cErrInBracket,cErrInParen,cOctalError,cCppOut2
+syn cluster aflexListPatCodeGroup	contains=aflexAbbrvBlock,aflexAbbrv,aflexAbbrv,aflexAbbrvRegExp,aflexInclude,aflexPatBlock,aflexPat,aflexBrace,aflexPatTag,aflexPatTag,aflexPatComment,aflexPatCodeLine,aflexMorePat,aflexPatSep,aflexSlashQuote,cInParen,cUserLabel,cOctalZero,cCppSkip,cErrInBracket,cErrInParen,cOctalError,cCppOut2
+
+" Abbreviations Section
+syn region aflexAbbrvBlock	start="^\([a-zA-Z_]\+\t\|%{\)" end="^%%$"me=e-2	skipnl	nextgroup=aflexPatBlock contains=aflexAbbrv,aflexInclude,aflexAbbrvComment
+syn match  aflexAbbrv		"^\I\i*\s"me=e-1			skipwhite	contained nextgroup=aflexAbbrvRegExp
+syn match  aflexAbbrv		"^%[sx]"					contained
+syn match  aflexAbbrvRegExp	"\s\S.*$"lc=1				contained nextgroup=aflexAbbrv,aflexInclude
+syn region aflexInclude	matchgroup=aflexSep	start="^%{" end="%}"	contained	contains=ALLBUT,@aflexListGroup
+syn region aflexAbbrvComment	start="^\s\+/\*"	end="\*/"
+
+"%% : Patterns {Actions}
+syn region aflexPatBlock	matchgroup=Todo	start="^%%$" matchgroup=Todo end="^%%$"	skipnl skipwhite contains=aflexPat,aflexPatTag,aflexPatComment
+syn region aflexPat		start=+\S+ skip="\\\\\|\\."	end="\s"me=e-1	contained nextgroup=aflexMorePat,aflexPatSep contains=aflexPatString,aflexSlashQuote,aflexBrace
+syn region aflexBrace	start="\[" skip=+\\\\\|\\+		end="]"		contained
+syn region aflexPatString	matchgroup=String start=+"+	skip=+\\\\\|\\"+	matchgroup=String end=+"+	contained
+syn match  aflexPatTag	"^<\I\i*\(,\I\i*\)*>*"			contained nextgroup=aflexPat,aflexPatTag,aflexMorePat,aflexPatSep
+syn match  aflexPatTag	+^<\I\i*\(,\I\i*\)*>*\(\\\\\)*\\"+		contained nextgroup=aflexPat,aflexPatTag,aflexMorePat,aflexPatSep
+syn region aflexPatComment	start="^\s*/\*" end="\*/"		skipnl	contained contains=cTodo nextgroup=aflexPatComment,aflexPat,aflexPatString,aflexPatTag
+syn match  aflexPatCodeLine	".*$"					contained contains=ALLBUT,@aflexListGroup
+syn match  aflexMorePat	"\s*|\s*$"			skipnl	contained nextgroup=aflexPat,aflexPatTag,aflexPatComment
+syn match  aflexPatSep	"\s\+"					contained nextgroup=aflexMorePat,aflexPatCode,aflexPatCodeLine
+syn match  aflexSlashQuote	+\(\\\\\)*\\"+				contained
+syn region aflexPatCode matchgroup=Delimiter start="{" matchgroup=Delimiter end="}"	skipnl contained contains=ALLBUT,@aflexListPatCodeGroup
+
+syn keyword aflexCFunctions	BEGIN	input	unput	woutput	yyleng	yylook	yytext
+syn keyword aflexCFunctions	ECHO	output	winput	wunput	yyless	yymore	yywrap
+
+" <c.vim> includes several ALLBUTs; these have to be treated so as to exclude aflex* groups
+syn cluster cParenGroup	add=aflex.*
+syn cluster cDefineGroup	add=aflex.*
+syn cluster cPreProcGroup	add=aflex.*
+syn cluster cMultiGroup	add=aflex.*
+
+" Synchronization
+syn sync clear
+syn sync minlines=300
+syn sync match aflexSyncPat	grouphere  aflexPatBlock	"^%[a-zA-Z]"
+syn sync match aflexSyncPat	groupthere aflexPatBlock	"^<$"
+syn sync match aflexSyncPat	groupthere aflexPatBlock	"^%%$"
+
+" Define the default highlighting.
+" For version 5.7 and earlier: only when not done already
+" For version 5.8 and later: only when an item doesn't have highlighting yet
+
+if version >= 508 || !exists("did_aflex_syntax_inits")
+   if version < 508
+      let did_aflex_syntax_inits = 1
+      command -nargs=+ HiLink hi link <args>
+   else
+      command -nargs=+ HiLink hi def link <args>
+   endif
+  HiLink	aflexSlashQuote	aflexPat
+  HiLink	aflexBrace		aflexPat
+  HiLink aflexAbbrvComment	aflexPatComment
+
+  HiLink	aflexAbbrv		SpecialChar
+  HiLink	aflexAbbrvRegExp	Macro
+  HiLink	aflexCFunctions	Function
+  HiLink	aflexMorePat	SpecialChar
+  HiLink	aflexPat		Function
+  HiLink	aflexPatComment	Comment
+  HiLink	aflexPatString	Function
+  HiLink	aflexPatTag		Special
+  HiLink	aflexSep		Delimiter
+  delcommand HiLink
+endif
+
+let b:current_syntax = "aflex"
+
+" vim:ts=10
--- /dev/null
+++ b/lib/vimfiles/syntax/ahdl.vim
@@ -1,0 +1,94 @@
+" Vim syn file
+" Language:	Altera AHDL
+" Maintainer:	John Cook <john.cook@kla-tencor.com>
+" Last Change:	2001 Apr 25
+
+" For version 5.x: Clear all syntax items
+" For version 6.x: Quit when a syntax file was already loaded
+if version < 600
+  syntax clear
+elseif exists("b:current_syntax")
+  finish
+endif
+
+"this language is oblivious to case.
+syn case ignore
+
+" a bunch of keywords
+syn keyword ahdlKeyword assert begin bidir bits buried case clique
+syn keyword ahdlKeyword connected_pins constant defaults define design
+syn keyword ahdlKeyword device else elsif end for function generate
+syn keyword ahdlKeyword gnd help_id if in include input is machine
+syn keyword ahdlKeyword node of options others output parameters
+syn keyword ahdlKeyword returns states subdesign table then title to
+syn keyword ahdlKeyword tri_state_node variable vcc when with
+
+" a bunch of types
+syn keyword ahdlIdentifier carry cascade dffe dff exp global
+syn keyword ahdlIdentifier jkffe jkff latch lcell mcell memory opendrn
+syn keyword ahdlIdentifier soft srffe srff tffe tff tri wire x
+
+syn keyword ahdlMegafunction lpm_and lpm_bustri lpm_clshift lpm_constant
+syn keyword ahdlMegafunction lpm_decode lpm_inv lpm_mux lpm_or lpm_xor
+syn keyword ahdlMegafunction busmux mux
+
+syn keyword ahdlMegafunction divide lpm_abs lpm_add_sub lpm_compare
+syn keyword ahdlMegafunction lpm_counter lpm_mult
+
+syn keyword ahdlMegafunction altdpram csfifo dcfifo scfifo csdpram lpm_ff
+syn keyword ahdlMegafunction lpm_latch lpm_shiftreg lpm_ram_dq lpm_ram_io
+syn keyword ahdlMegafunction lpm_rom lpm_dff lpm_tff clklock pll ntsc
+
+syn keyword ahdlTodo contained TODO
+
+" String contstants
+syn region ahdlString start=+"+  skip=+\\"+  end=+"+
+
+" valid integer number formats (decimal, binary, octal, hex)
+syn match ahdlNumber '\<\d\+\>'
+syn match ahdlNumber '\<b"\(0\|1\|x\)\+"'
+syn match ahdlNumber '\<\(o\|q\)"\o\+"'
+syn match ahdlNumber '\<\(h\|x\)"\x\+"'
+
+" operators
+syn match   ahdlOperator "[!&#$+\-<>=?:\^]"
+syn keyword ahdlOperator not and nand or nor xor xnor
+syn keyword ahdlOperator mod div log2 used ceil floor
+
+" one line and multi-line comments
+" (define these after ahdlOperator so -- overrides -)
+syn match  ahdlComment "--.*" contains=ahdlNumber,ahdlTodo
+syn region ahdlComment start="%" end="%" contains=ahdlNumber,ahdlTodo
+
+" other special characters
+syn match   ahdlSpecialChar "[\[\]().,;]"
+
+syn sync minlines=1
+
+" Define the default highlighting.
+" For version 5.7 and earlier: only when not done already
+" For version 5.8 and later: only when an item doesn't have highlighting yet
+if version >= 508 || !exists("did_ahdl_syn_inits")
+  if version < 508
+    let did_ahdl_syn_inits = 1
+    command -nargs=+ HiLink hi link <args>
+  else
+    command -nargs=+ HiLink hi def link <args>
+  endif
+
+  " The default highlighting.
+  HiLink ahdlNumber		ahdlString
+  HiLink ahdlMegafunction	ahdlIdentifier
+  HiLink ahdlSpecialChar	SpecialChar
+  HiLink ahdlKeyword		Statement
+  HiLink ahdlString		String
+  HiLink ahdlComment		Comment
+  HiLink ahdlIdentifier		Identifier
+  HiLink ahdlOperator		Operator
+  HiLink ahdlTodo		Todo
+
+  delcommand HiLink
+endif
+
+let b:current_syntax = "ahdl"
+" vim:ts=8
--- /dev/null
+++ b/lib/vimfiles/syntax/alsaconf.vim
@@ -1,0 +1,49 @@
+" Vim syntax file
+" Language:         alsaconf(8) configuration file
+" Maintainer:       Nikolai Weibull <now@bitwi.se>
+" Latest Revision:  2006-04-19
+
+if exists("b:current_syntax")
+  finish
+endif
+
+let s:cpo_save = &cpo
+set cpo&vim
+
+syn keyword alsoconfTodo        contained FIXME TODO XXX NOTE
+
+syn region  alsaconfComment     display oneline
+                                \ start='#' end='$'
+                                \ contains=alsaconfTodo,@Spell
+
+syn match   alsaconfSpecialChar contained display '\\[ntvbrf]'
+syn match   alsaconfSpecialChar contained display '\\\o\+'
+
+syn region  alsaconfString      start=+"+ skip=+\\$+ end=+"\|$+
+                                \ contains=alsaconfSpecialChar
+
+syn match   alsaconfSpecial     contained display 'confdir:'
+
+syn region  alsaconfPreProc     start='<' end='>' contains=alsaconfSpecial
+
+syn match   alsaconfMode        display '[+?!-]'
+
+syn keyword alsaconfKeyword     card default device errors files func strings
+syn keyword alsaconfKeyword     subdevice type vars
+
+syn match   alsaconfVariables   display '@\(hooks\|func\|args\)'
+
+hi def link alsoconfTodo        Todo
+hi def link alsaconfComment     Comment
+hi def link alsaconfSpecialChar SpecialChar
+hi def link alsaconfString      String
+hi def link alsaconfSpecial     Special
+hi def link alsaconfPreProc     PreProc
+hi def link alsaconfMode        Special
+hi def link alsaconfKeyword     Keyword
+hi def link alsaconfVariables   Identifier
+
+let b:current_syntax = "alsaconf"
+
+let &cpo = s:cpo_save
+unlet s:cpo_save
--- /dev/null
+++ b/lib/vimfiles/syntax/amiga.vim
@@ -1,0 +1,101 @@
+" Vim syntax file
+" Language:	AmigaDos
+" Maintainer:	Dr. Charles E. Campbell, Jr. <NdrOchipS@PcampbellAfamily.Mbiz>
+" Last Change:	Sep 11, 2006
+" Version:     6
+" URL:	http://mysite.verizon.net/astronaut/vim/index.html#vimlinks_syntax
+
+" For version 5.x: Clear all syntax items
+" For version 6.x: Quit when a syntax file was already loaded
+if version < 600
+  syntax clear
+elseif exists("b:current_syntax")
+  finish
+endif
+
+syn case ignore
+
+" Amiga Devices
+syn match amiDev "\(par\|ser\|prt\|con\|nil\):"
+
+" Amiga aliases and paths
+syn match amiAlias	"\<[a-zA-Z][a-zA-Z0-9]\+:"
+syn match amiAlias	"\<[a-zA-Z][a-zA-Z0-9]\+:[a-zA-Z0-9/]*/"
+
+" strings
+syn region amiString	start=+"+ end=+"+ oneline contains=@Spell
+
+" numbers
+syn match amiNumber	"\<\d\+\>"
+
+" Logic flow
+syn region	amiFlow	matchgroup=Statement start="if"	matchgroup=Statement end="endif"	contains=ALL
+syn keyword	amiFlow	skip endskip
+syn match	amiError	"else\|endif"
+syn keyword	amiElse contained	else
+
+syn keyword	amiTest contained	not warn error fail eq gt ge val exists
+
+" echo exception
+syn region	amiEcho	matchgroup=Statement start="\<echo\>" end="$" oneline contains=amiComment
+syn region	amiEcho	matchgroup=Statement start="^\.[bB][rR][aA]" end="$" oneline
+syn region	amiEcho	matchgroup=Statement start="^\.[kK][eE][tT]" end="$" oneline
+
+" commands
+syn keyword	amiKey	addbuffers	copy	fault	join	pointer	setdate
+syn keyword	amiKey	addmonitor	cpu	filenote	keyshow	printer	setenv
+syn keyword	amiKey	alias	date	fixfonts	lab	printergfx	setfont
+syn keyword	amiKey	ask	delete	fkey	list	printfiles	setmap
+syn keyword	amiKey	assign	dir	font	loadwb	prompt	setpatch
+syn keyword	amiKey	autopoint	diskchange	format	lock	protect	sort
+syn keyword	amiKey	avail	diskcopy	get	magtape	quit	stack
+syn keyword	amiKey	binddrivers	diskdoctor	getenv	makedir	relabel	status
+syn keyword	amiKey	bindmonitor	display	graphicdump	makelink	remrad	time
+syn keyword	amiKey	blanker		iconedit	more	rename	type
+syn keyword	amiKey	break	ed	icontrol	mount	resident	unalias
+syn keyword	amiKey	calculator	edit	iconx	newcli	run	unset
+syn keyword	amiKey	cd	endcli	ihelp	newshell	say	unsetenv
+syn keyword	amiKey	changetaskpri	endshell	info	nocapslock	screenmode	version
+syn keyword	amiKey	clock	eval	initprinter	nofastmem	search	wait
+syn keyword	amiKey	cmd	exchange	input	overscan	serial	wbpattern
+syn keyword	amiKey	colors	execute	install	palette	set	which
+syn keyword	amiKey	conclip	failat	iprefs	path	setclock	why
+
+" comments
+syn cluster	amiCommentGroup contains=amiTodo,@Spell
+syn case ignore
+syn keyword	amiTodo	contained	todo
+syn case match
+syn match	amiComment	";.*$" contains=amiCommentGroup
+
+" sync
+syn sync lines=50
+
+" Define the default highlighting.
+" For version 5.7 and earlier: only when not done already
+" For version 5.8 and later: only when an item doesn't have highlighting yet
+if version >= 508 || !exists("did_amiga_syn_inits")
+  if version < 508
+    let did_amiga_syn_inits = 1
+    command -nargs=+ HiLink hi link <args>
+  else
+    command -nargs=+ HiLink hi def link <args>
+  endif
+
+  HiLink amiAlias	Type
+  HiLink amiComment	Comment
+  HiLink amiDev	Type
+  HiLink amiEcho	String
+  HiLink amiElse	Statement
+  HiLink amiError	Error
+  HiLink amiKey	Statement
+  HiLink amiNumber	Number
+  HiLink amiString	String
+  HiLink amiTest	Special
+
+  delcommand HiLink
+endif
+
+let b:current_syntax = "amiga"
+
+" vim:ts=15
--- /dev/null
+++ b/lib/vimfiles/syntax/aml.vim
@@ -1,0 +1,157 @@
+" Vim syntax file
+" Language:	AML (ARC/INFO Arc Macro Language)
+" Written By:	Nikki Knuit <Nikki.Knuit@gems3.gov.bc.ca>
+" Maintainer:	Todd Glover <todd.glover@gems9.gov.bc.ca>
+" Last Change:	2001 May 10
+
+" FUTURE CODING:  Bold application commands after &sys, &tty
+"		  Only highlight aml Functions at the beginning
+"		    of [], in order to avoid -read highlighted,
+"		    or [quote] strings highlighted
+
+" For version 5.x: Clear all syntax items
+" For version 6.x: Quit when a syntax file was already loaded
+if version < 600
+  syntax clear
+elseif exists("b:current_syntax")
+  finish
+endif
+
+syn case ignore
+
+" ARC, ARCEDIT, ARCPLOT, LIBRARIAN, GRID, SCHEMAEDIT reserved words,
+" defined as keywords.
+
+syn keyword amlArcCmd contained  2button abb abb[reviations] abs ac acos acosh add addc[ogoatt] addcogoatt addf[eatureclass] addh[istory] addi addim[age] addindexatt addit[em] additem addressb[uild] addressc[reate] addresse[rrors] addressedit addressm[atch] addressp[arse] addresst[est] addro[utemeasure] addroutemeasure addte[xt] addto[stack] addw[orktable] addx[y] adj[ust] adm[inlicense] adr[ggrid] ads adsa[rc] ae af ag[gregate] ai ai[request] airequest al alia[s] alig[n] alt[erarchive] am[sarc] and annoa[lignment] annoadd annocapture annocl[ip] annoco[verage] annocurve annoe[dit] annoedit annof annofeature annofit annoitem annola[yer] annole[vel] annolevel annoline annooffset annop[osition] annoplace annos[ize] annoselectfeatur annoset annosum annosymbol annot annot[ext] annotext annotype ao ap apm[ode] app[end] arc arcad[s] arcar[rows] arcc[ogo] arcdf[ad] arcdi[me] arcdl[g] arcdx[f] arced[it] arcedit arcen[dtext] arcf[ont] arcigd[s] arcige[s] arcla[bel] arcli[nes] arcma[rkers] arcmo[ss]
+syn keyword amlArcCmd contained  arcpl[ot] arcplot arcpo[int] arcr[oute] arcs arcsc[itex] arcse[ction] arcsh[ape] arcsl[f] arcsn[ap] arcsp[ot] arcte[xt] arctig[er] arctin arcto[ols] arctools arcty[pe] area areaq[uery] arm arrow arrows[ize] arrowt[ype] as asc asciig[rid] asciih[elp] asciihelp asco[nnect] asconnect asd asda[tabase] asdi[sconnect] asdisconnect asel[ect] asex[ecute] asf asin asinh asp[ect] asr[eadlocks] ast[race] at atan atan2 atanh atusage aud[ittrail] autoi[ncrement] autol[ink] axis axish[atch] axisl[abels] axisr[uler] axist[ext] bac[klocksymbol] backcoverage backenvironment backnodeangleite backsymbolitem backtextitem base[select] basi[n] bat[ch] bc be be[lls] blackout blockmaj[ority] blockmax blockmea[n] blockmed[ian] blockmin blockmino[rity] blockr[ange] blockst[d] blocksu[m] blockv[ariety] bnai bou[ndaryclean] box br[ief] bsi bti buf[fer] bug[form] bugform build builds[ta] buildv[at] calco[mp] calcomp calcu[late] cali[brateroutes] calibrateroutes can[d] cartr[ead] cartread
+syn keyword amlArcCmd contained  cartw[rite] cartwrite cei[l] cel[lvalue] cen[troidlabels] cgm cgme[scape] cha[nge] checkin checkinrel checkout checkoutrel chm[od] chown chownt[ransaction] chowntran chowntransaction ci ci[rcle] cir class classp[rob] classs[ig] classsample clean clear clears[elect] clip clipg[raphextent] clipm[apextent] clo[sedatabase] cntvrt co cod[efind] cog[oinverse] cogocom cogoenv cogomenu coll[ocate] color color2b[lue] color2g[reen] color2h[ue] color2r[ed] color2s[at] color2v[al] colorchart coloredit colorh[cbs] colorhcbs colu[mns] comb[ine] comm[ands] commands con connect connectu[ser] cons[ist] conto[ur] contr[olpoints] convertd[oc] convertdoc converti[mage] convertla[yer] convertli[brary] convertr[emap] convertw[orkspace] coo[rdinate] coordinate coordinates copy copyf[eatures] copyi[nfo] copyl[ayer] copyo copyo[ut] copyout copys[tack] copyw[orkspace] copyworkspace cor corr[idor] correlation cos cosh costa[llocation] costb[acklink] costd[istance] costp[ath] cou[ntvertices]
+syn keyword amlArcCmd contained  countvertices cpw cr create create2[dindex] createa[ttributes] createca[talog] createco[go] createcogo createf[eature] createind[ex] createinf[otable] createlab[els] createlay[er] createli[brary] createn[etindex] creater[emap] creates[ystables] createta[blespace] createti[n] createw[orkspace] createworkspace cs culdesac curs[or] curv[ature] curve3pt cut[fill] cutoff cw cx[or] da dar[cyflow] dat[aset] dba[seinfo] dbmsc dbmsc[ursor] dbmscursor dbmse[xecute] dbmsi[nfo] dbmss[et] de delete deletea[rrows] deletet[ic] deletew[orkspace] deleteworkspace demg[rid] deml[attice] dend[rogram] densify densifya[rc] describe describea[rchive] describel[attice] describeti[n] describetr[ans] describetrans dev df[adarc] dg dif[f] digi[tizer] digt[est] dim[earc] dir dir[ectory] directory disa[blepanzoom] disconnect disconnectu[ser] disp disp[lay] display dissolve dissolvee[vents] dissolveevents dista[nce] distr[ibutebuild] div dl[garc] do doce[ll] docu[ment] document dogroup drag
+syn keyword amlArcCmd contained  draw drawenvironment draworder draws[ig] drawselect drawt[raverses] drawz[oneshape] drop2[dindex] dropa[rchive] dropfeaturec[lass] dropfeatures dropfr[omstack] dropgroup droph[istory] dropind[ex] dropinf[otable] dropit[em] dropla[yer] droplib[rary] droplin[e] dropline dropn[etindex] dropt[ablespace] dropw[orktable] ds dt[edgrid] dtrans du[plicate] duplicatearcs dw dxf dxfa[rc] dxfi[nfo] dynamicpan dynpan ebe ec ed edg[esnap] edgematch editboundaryerro edit[coverage]  editdistance editf editfeature editp[lot] editplot edits[ig] editsymbol ef el[iminate] em[f] en[d] envrst envsav ep[s] eq equ[alto] er[ase] es et et[akarc] euca[llocation] eucdir[ection] eucdis[tance] eval eventa[rc] evente[nds] eventh[atch] eventi[nfo] eventlinee[ndtext] eventlines eventlinet[ext] eventlis[t] eventma[rkers] eventme[nu] eventmenu eventpoint eventpointt[ext] eventse[ction] eventso[urce] eventt[ransform] eventtransform exi[t] exp exp1[0] exp2 expa[nd] expo[rt] exten[d] external externala[ll]
+syn keyword amlArcCmd contained  fd[convert] featuregroup fg fie[lddata] file fill filt[er] fix[ownership] flip flipa[ngle] float floatg[rid] floo[r] flowa[ccumulation] flowd[irection] flowl[ength] fm[od] focalf[low] focalmaj[ority] focalmax focalmea[n] focalmed[ian] focalmin focalmino[rity] focalr[ange] focalst[d] focalsu[m] focalv[ariety] fonta[rc] fontco[py] fontcr[eate] fontd[elete] fontdump fontl[oad] fontload forc[e] form[edit] formedit forms fr[equency] ge geary general[ize] generat[e] gerbera[rc] gerberr[ead] gerberread gerberw[rite] gerberwrite get getz[factor] gi gi[rasarc] gnds grai[n] graphb[ar] graphe[xtent] graphi[cs] graphicimage graphicview graphlim[its] graphlin[e] graphp[oint] graphs[hade] gray[shade] gre[aterthan] grid grida[scii] gridcl[ip] gridclip gridco[mposite] griddesk[ew] griddesp[eckle] griddi[rection] gride[dit] gridfli[p] gridflo[at] gridim[age] gridin[sert] gridl[ine] gridma[jority] gridmi[rror] gridmo[ss] gridn[et] gridnodatasymbol gridpa[int] gridpoi[nt] gridpol[y]
+syn keyword amlArcCmd contained  gridq[uery] gridr[otate] gridshad[es] gridshap[e] gridshi[ft] gridw[arp] group groupb[y] gt gv gv[tolerance] ha[rdcopy] he[lp] help hid[densymbol] hig[hlow] hil[lshade] his[togram] historicalview ho[ldadjust] hpgl hpgl2 hsv2b[lue] hsv2g[reen] hsv2r[ed] ht[ml] hview ia ided[it] identif[y] identit[y] idw if igdsa[rc] igdsi[nfo] ige[sarc] il[lustrator] illustrator image imageg[rid] imagep[lot] imageplot imageview imp[ort] in index indexi[tem] info infodba[se] infodbm[s] infof[ile] init90[00] init9100 init9100b init91[00] init95[00] int intersect intersectarcs intersecte[rr] isn[ull] iso[cluster] it[ems] iview j[oinitem] join keeps keepselect keyan[gle] keyar[ea] keyb[ox] keyf[orms] keyl[ine] keym keym[arker] keymap keyp[osition] keyse[paration] keysh[ade] keyspot kill killm[ap] kr[iging] la labela[ngle] labele[rrors] labelm[arkers] labels labelsc[ale] labelsp[ot] labelt[ext] lal latticecl[ip] latticeco[ntour] latticed[em] latticem[erge] latticemarkers latticeo[perate]
+syn keyword amlArcCmd contained  latticep[oly] latticerep[lace] latticeres[ample] lattices[pot] latticet[in] latticetext layer layera[nno] layerca[lculate] layerco[lumns] layerde[lete] layerdo[ts] layerdr[aw] layere[xport] layerf[ilter] layerid[entify] layerim[port] layerio[mode] layerli[st] layerloc[k] layerlog[file] layerq[uery] layerse[arch] layersp[ot] layert[ext] lc ldbmst le leadera[rrows] leaders leadersy[mbol] leadert[olerance] len[gth] les[sthan] lf lg lh li lib librari[an] library limitadjust limitautolink line line2pt linea[djustment] linecl[osureangle] linecolor linecolorr[amp] linecopy linecopyl[ayer] linedelete linedeletel[ayer] lineden[sity] linedir[ection] linedis[t] lineedit lineg[rid] lineh[ollow] lineinf[o] lineint[erval] linel[ayer] linelist linem[iterangle] lineo[ffset] linepa[ttern] linepe[n] linepu[t] linesa[ve] linesc[ale] linese[t] linesi[ze] linest[ats] linesy[mbol] linete[mplate]
+syn keyword amlArcCmd contained  linety[pe] link[s] linkfeatures list listarchives listatt listc[overages] listcoverages listdbmstables listg[rids] listgrids listhistory listi[mages] listimages listinfotables listlayers listlibraries listo[utput] listse[lect] listst[acks] liststacks listtablespaces listti[ns] listtins listtr[averses] listtran listtransactions listw[orkspaces] listworkspaces lit ll ll[sfit] lla lm ln load loada[djacent] loadcolormap locko[nly] locks[ymbol] log log1[0] log2 logf[ile] logg[ing] loo[kup] lot[area] lp[os] lstk lt lts lw madditem majority majorityf[ilter] makere[gion] makero[ute] makese[ction] makest[ack] mal[ign] map mapa[ngle] mape[xtent] mapextent mapi[nfo] mapj[oin] mapl[imits] mappo[sition] mappr[ojection] mapsc[ale] mapsh[ift] mapu[nits] mapw[arp] mapz[oom] marker markera[ngle] markercolor markercolorr[amp] markercopy markercopyl[ayer] markerdelete markerdeletel[aye] markeredit markerf[ont] markeri[nfo] markerl[ayer] markerlist markerm[ask] markero[ffset]
+syn keyword amlArcCmd contained  markerpa[ttern] markerpe[n] markerpu[t] markersa[ve] markersc[ale] markerse[t] markersi[ze] markersy[mbol] mas[elect] matchc[over] matchn[ode] max mb[egin] mc[opy] md[elete] me mean measure measurer[oute] measureroute med mend menu[cover] menuedit menv[ironment] merge mergeh[istory] mergev[at] mfi[t] mfr[esh] mg[roup] miadsa[rc] miadsr[ead] miadsread min minf[o] mino[rity] mir[ror] mitems mjoin ml[classify] mma[sk] mmo[ve] mn[select] mod mor[der] moran mosa[ic] mossa[rc] mossg[rid] move movee[nd] movei[tem] mp[osition] mr mr[otate] msc[ale] mse[lect] mselect mt[olerance] mu[nselect] multcurve multinv multipleadditem multipleitems multiplejoin multipleselect multprop mw[ho] nai ne near neatline neatlineg[rid] neatlineh[atch] neatlinel[abels] neatlinet[ics] new next ni[bble] nodeangleitem nodec[olor] nodee[rrors] nodem[arkers] nodep[oint] nodes nodesi[ze] nodesn[ap] nodesp[ot] nodet[ext] nor[mal] not ns[elect] oe ogrid ogridt[ool] oldwindow oo[ps] op[endatabase] or
+syn keyword amlArcCmd contained  osymbol over overflow overflowa[rea] overflowp[osition] overflows[eparati] overl[ayevents] overlapsymbol overlayevents overp[ost] pagee[xtent] pages[ize] pageu[nits] pal[info] pan panview par[ticletrack] patc[h] path[distance] pe[nsize] pi[ck] pli[st] plot plotcopy plotg[erber] ploti[con] plotmany plotpanel plotsc[itex] plotsi[f] pointde[nsity] pointdist pointdista[nce] pointdo[ts] pointg[rid] pointi[nterp] pointm[arkers] pointn[ode] points pointsp[ot] pointst[ats] pointt[ext] polygonb[ordertex] polygond[ots] polygone[vents] polygonevents polygonl[ines] polygons polygonsh[ades] polygonsi[zelimit] polygonsp[ot] polygont[ext] polygr[id] polyr[egion] pop[ularity] por[ouspuff] pos pos[tscript] positions postscript pow prec[ision] prep[are] princ[omp] print product producti[nfo] project projectcom[pare] projectcop[y] projectd[efine] pul[litems] pur[gehistory] put pv q q[uit] quit rand rang[e] rank rb rc re readg[raphic] reads[elect] reb[ox] recl[ass] recoverdb rect[ify]
+syn keyword amlArcCmd contained  red[o] refreshview regionb[uffer] regioncla[ss] regioncle[an] regiondi[ssolve] regiondo[ts] regione[rrors] regiong[roup] regionj[oin] regionl[ines] regionpoly regionpolyc[ount] regionpolycount regionpolyl[ist] regionpolylist regionq[uery] regions regionse[lect] regionsh[ades] regionsp[ot] regiont[ext] regionxa[rea] regionxarea regionxt[ab] regionxtab register registerd[bms] regr[ession] reindex rej[ects] rela[te] rele[ase] rem remapgrid reme[asure] remo[vescalar] remove removeback removecover removeedit removesnap removetransfer rename renamew[orkspace] renameworkspace reno[de] rep[lace] reposition resa[mple] resel[ect] reset resh[ape] restore restorearce[dit] restorearch[ive] resu[me] rgb2h[ue] rgb2s[at] rgb2v[al] rotate rotatep[lot] routea[rc] routeends routeendt[ext] routeer[rors] routeev[entspot] routeh[atch] routel[ines] routes routesp[ot] routest[ats] routet[ext] rp rs rt rt[l] rtl rv rw sa sai sample samples[ig] sav[e] savecolormap sc scal[ar] scat[tergram]
+syn keyword amlArcCmd contained  scenefog sceneformat scenehaze sceneoversample sceneroll scenesave scenesize scenesky scitexl[ine] scitexpoi[nt] scitexpol[y] scitexr[ead] scitexread scitexw[rite] scitexwrite sco screenr[estore] screens[ave] sd sds sdtse[xport] sdtsim[port] sdtsin[fo] sdtsl[ist] se sea[rchtolerance] sectiona[rc] sectionends sectionendt[ext] sectionh[atch] sectionl[ines] sections sectionsn[ap] sectionsp[ot] sectiont[ext] sel select selectb[ox] selectc[ircle] selectg[et] selectm[ask] selectmode selectpoi[nt] selectpol[ygon] selectpu[t] selectt[ype] selectw[ithin] semivariogram sep[arator] separator ser[verstatus] setan[gle] setar[row] setce[ll] setcoa[lesce] setcon[nectinfo] setd[bmscheckin] setdrawsymbol sete[ditmode] setincrement setm[ask] setn[ull] setools setreference setsymbol setturn setw[indow] sext sf sfmt sfo sha shade shadea[ngle] shadeb[ackcolor] shadecolor shadecolorr[amp] shadecopy shadecopyl[ayer] shadedelete shadedeletel[ayer] shadeedit shadegrid shadei[nfo] shadela[yer]
+syn keyword amlArcCmd contained  shadeli[nepattern] shadelist shadeo[ffset] shadepa[ttern] shadepe[n] shadepu[t] shadesa[ve] shadesc[ale] shadesep[aration] shadeset shadesi[ze] shadesy[mbol] shadet[ype] shapea[rc] shapef[ile] shapeg[rid] shi[ft] show showconstants showe[ditmode] shr[ink] si sin sinfo sing[leuser] sinh sink sit[e] sl slf[arc] sli[ce] slo[pe] sm smartanno snap snapc[over] snapcover snapcoverage snapenvironment snapfeatures snapitems snapo[rder] snappi[ng] snappo[ur] so[rt] sobs sos spi[der] spiraltrans spline splinem[ethod] split spot spoto[ffset] spots[ize] sproj sqr sqrt sra sre srl ss ssc ssh ssi ssky ssz sta stackh[istogram] stackprofile stacksc[attergram] stackshade stackst[ats] stati[stics] statu[s] statuscogo std stra[ighten] streamline streamlink streamo[rder] stri[pmap] subm[it] subs[elect] sum surface surfaceabbrev surfacecontours surfacedefaults surfacedrape surfaceextent surfaceinfo surfacel[ength] surfacelimits surfacemarker surfacemenu surfaceobserver surfaceprofile
+syn keyword amlArcCmd contained  surfaceprojectio surfacerange surfaceresolutio surfacesave surfacescene surfaceshade surfacesighting surfacetarget surfacevalue surfaceviewfield surfaceviewshed surfacevisibility surfacexsection surfacezoom surfacezscale sv svfd svs sxs symboldump symboli[tem] symbolsa[ve] symbolsc[ale] symbolse[t] symbolset sz tab[les] tal[ly] tan tanh tc te tes[t] text textal[ignment] textan[gle] textcolor textcolorr[amp] textcop[y] textde[lete] textdi[rection] textedit textfil[e] textfit textfo[nt] textin[fo] textit[em] textj[ustificatio] textlist textm[ask] texto[ffset] textpe[n] textpr[ecision] textpu[t] textq[uality] textsa[ve] textsc[ale] textse[t] textset textsi[ze] textsl[ant] textspa[cing] textspl[ine] textst[yle] textsy[mbol] tf th thie[ssen] thin ti tics tict[ext] tigera[rc] tigert[ool] tigertool til[es] timped tin tina[rc] tinc[ontour] tinerrors tinhull tinl[attice] tinlines tinmarkers tins[pot] tinshades tintext tinv[rml] tl tm tol[erance] top[ogrid] topogridtool
+syn keyword amlArcCmd contained  transa[ction] transfe[r] transfercoverage transferfeature transferitems transfersymbol transfo[rm] travrst travsav tre[nd] ts tsy tt tur[ntable] turnimpedance tut[orial] una[ry] unde[lete] undo ungenerate ungeneratet[in] unio[n] unit[s] unr[egisterdbms] unse[lect] unsp[lit] update updatei[nfoschema] updatel[abels] upo[s] us[age] v va[riety] vcgl vcgl2 veri[fy] vers[ion] vertex viewrst viewsav vip visd[ecode] visdecode vise[ncode] visencode visi[bility] vo[lume] vpfe[xport] vpfi[mport] vpfl[ist] vpft[ile] w war[p] wat[ershed] weedd[raw] weedo[perator] weedt[olerance] weedtolerance whe[re] whi[le] who wi[ndows] wm[f] wo[rkspace] workspace writec[andidates] writeg[raphic] writes[elect] wt x[or] ze[ta] zeta zi zo zonala[rea] zonalc[entroid] zonalf[ill] zonalg[eometry] zonalmaj[ority] zonalmax zonalmea[n] zonalmed[ian] zonalmin zonalmino[rity] zonalp[erimeter] zonalr[ange] zonalsta[ts] zonalstd zonalsu[m] zonalt[hickness] zonalv[ariety] zoomview zv
+
+" FORMEDIT reserved words, defined as keywords.
+
+syn keyword amlFormedCmd contained  button choice display help input slider text
+
+" TABLES reserved words, defined as keywords.
+
+syn keyword amlTabCmd contained  add additem alter asciihelp aselect at calc calculate change commands commit copy define directory dropindex dropitem erase external get help indexitem items kill list move nselect purge quit redefine rename reselect rollback save select show sort statistics unload update usagecontained
+
+" INFO reserved words, defined as keywords.
+
+syn keyword amlInfoCmd contained  accept add adir alter dialog alter alt directory aret arithmetic expressions aselect automatic return calculate cchr change options change comi cominput commands list como comoutput compile concatenate controlling defaults copy cursor data delete data entry data manipulate data retrieval data update date format datafile create datafile management decode define delimiter dfmt directory management directory display do doend documentation done end environment erase execute exiting expand export external fc files first format forms control get goto help import input form ipf internal item types items label lchar list logical expressions log merge modify options modify move next nselect output password prif print programming program protect purge query quit recase redefine relate relate release notes remark rename report options reporting report reselect reserved words restrictions run save security select set sleep sort special form spool stop items system variables take terminal types terminal time topics list type update upf
+
+" VTRACE reserved words, defined as keywords.
+
+syn keyword amlVtrCmd contained  add al arcscan arrowlength arrowwidth as aw backtrack branch bt cj clearjunction commands cs dash endofline endofsession eol eos fan fg foreground gap generalizetolerance gtol help hole js junctionsensitivity linesymbol linevariation linewidth ls lv lw markersymbol mode ms raster regionofinterest reset restore retrace roi save searchradius skip sr sta status stc std str straightenangle straightencorner straightendistance straightenrange vt vtrace
+
+" The AML reserved words, defined as keywords.
+
+syn keyword amlFunction contained  abs access acos after angrad asin atan before calc close copy cos cover coverage cvtdistance date delete dignum dir directory entryname exist[s] exp extract file filelist format formatdate full getchar getchoice getcover getdatabase getdeflayers getfile getgrid getimage getitem getlayercols getlibrary getstack getsymbol gettin getunique iacclose iacconnect iacdisconnect iacopen iacrequest index indexed info invangle invdistance iteminfo joinfile keyword length listfile listitem listunique locase log max menu min mod noecho null okangle okdistance open pathname prefix query quote quoteexists r radang random read rename response round scratchname search show sin sort sqrt subst substr suffix tan task token translate trim truncate type unquote upcase username value variable verify write
+
+syn keyword amlDir contained  abbreviations above all aml amlpath append arc args atool brief by call canvas cc center cl codepage commands conv_watch_to_aml coordinates cr create current cursor cwta dalines data date_format delete delvar describe dfmt digitizer display do doend dv echo else enable encode encrypt end error expansion fail file flushpoints force form format frame fullscreen function getlastpoint getpoint goto iacreturn if ignore info inform key keypad label lc left lf lg list listchar listfiles listglobal listheader listlocal listprogram listvar ll lp lr lv map matrix menu menupath menutype mess message[s] modal mouse nopaging off on others page pause pinaction popup position pt pulldown push pushpoint r repeat return right routine run runwatch rw screen seconds select self setchar severity show sidebar single size staggered station stop stripe sys system tablet tb terminal test then thread to top translate tty ty type uc ul until ur usage w warning watch when while window workspace
+
+syn keyword amlDir2 contained  delvar dv s set setvar sv
+
+syn keyword amlOutput contained  inform warning error pause stop tty ty type
+
+
+" AML Directives:
+syn match amlDirSym "&"
+syn match amlDirective "&[a-zA-Z]*" contains=amlDir,amlDir2,amlDirSym
+
+" AML Functions
+syn region amlFunc start="\[ *[a-zA-Z]*" end="\]" contains=amlFunction,amlVar
+syn match amlFunc2 "\[.*\[.*\].*\]" contains=amlFunction,amlVar
+
+" Numbers:
+"syn match amlNumber		"-\=\<[0-9]*\.\=[0-9_]\>"
+
+" Quoted Strings:
+syn region amlQuote start=+"+ skip=+\\"+ end=+"+ contains=amlVar
+syn region amlQuote start=+'+ skip=+\\'+ end=+'+
+
+" ARC Application Commands only selected at the beginning of the line,
+" or after a one line &if &then statement
+syn match amlAppCmd "^ *[a-zA-Z]*" contains=amlArcCmd,amlInfoCmd,amlTabCmd,amlVtrCmd,amlFormedCmd
+syn region amlAppCmd start="&then" end="$" contains=amlArcCmd,amlFormedCmd,amlInfoCmd,amlTabCmd,amlVtrCmd,amlFunction,amlDirective,amlVar2,amlSkip,amlVar,amlComment
+
+" Variables
+syn region amlVar start="%" end="%"
+syn region amlVar start="%" end="%" contained
+syn match amlVar2 "&s [a-zA-Z_.0-9]*" contains=amlDir2,amlDirSym
+syn match amlVar2 "&sv [a-zA-Z_.0-9]*" contains=amlDir2,amlDirSym
+syn match amlVar2 "&set [a-zA-Z_.0-9]*" contains=amlDir2,amlDirSym
+syn match amlVar2 "&setvar [a-zA-Z_.0-9]*" contains=amlDir2,amlDirSym
+syn match amlVar2 "&dv [a-zA-Z_.0-9]*" contains=amlDir2,amlDirSym
+syn match amlVar2 "&delvar [a-zA-Z_.0-9]*" contains=amlDir2,amlDirSym
+
+" Formedit 2 word commands
+syn match amlFormed "^ *check box"
+syn match amlFormed "^ *data list"
+syn match amlFormed "^ *symbol list"
+
+" Tables 2 word commands
+syn match amlTab "^ *q stop"
+syn match amlTab "^ *quit stop"
+
+" Comments:
+syn match amlComment "/\*.*"
+
+" Regions for skipping over (not highlighting) program output strings:
+syn region amlSkip matchgroup=amlOutput start="&call" end="$" contains=amlVar
+syn region amlSkip matchgroup=amlOutput start="&routine" end="$" contains=amlVar
+syn region amlSkip matchgroup=amlOutput start="&inform" end="$" contains=amlVar
+syn region amlSkip matchgroup=amlOutput start="&return &inform" end="$" contains=amlVar
+syn region amlSkip matchgroup=amlOutput start="&return &warning" end="$" contains=amlVar
+syn region amlSkip matchgroup=amlOutput start="&return &error" end="$" contains=amlVar
+syn region amlSkip matchgroup=amlOutput start="&pause" end="$" contains=amlVar
+syn region amlSkip matchgroup=amlOutput start="&stop" end="$" contains=amlVar
+syn region amlSkip matchgroup=amlOutput start="&tty" end="$" contains=amlVar
+syn region amlSkip matchgroup=amlOutput start="&ty" end="$" contains=amlVar
+syn region amlSkip matchgroup=amlOutput start="&typ" end="$" contains=amlVar
+syn region amlSkip matchgroup=amlOutput start="&type" end="$" contains=amlVar
+
+" Define the default highlighting.
+" For version 5.7 and earlier: only when not done already
+" For version 5.8 and later: only when an item doesn't have highlighting yet
+if version >= 508 || !exists("did_aml_syntax_inits")
+  if version < 508
+    let did_aml_syntax_inits = 1
+    command -nargs=+ HiLink hi link <args>
+  else
+    command -nargs=+ HiLink hi def link <args>
+  endif
+
+  HiLink amlComment	Comment
+  HiLink amlNumber	Number
+  HiLink amlQuote	String
+  HiLink amlVar	Identifier
+  HiLink amlVar2	Identifier
+  HiLink amlFunction	PreProc
+  HiLink amlDir	Statement
+  HiLink amlDir2	Statement
+  HiLink amlDirSym	Statement
+  HiLink amlOutput	Statement
+  HiLink amlArcCmd	ModeMsg
+  HiLink amlFormedCmd	amlArcCmd
+  HiLink amlTabCmd	amlArcCmd
+  HiLink amlInfoCmd	amlArcCmd
+  HiLink amlVtrCmd	amlArcCmd
+  HiLink amlFormed	amlArcCmd
+  HiLink amlTab	amlArcCmd
+
+  delcommand HiLink
+endif
+
+let b:current_syntax = "aml"
--- /dev/null
+++ b/lib/vimfiles/syntax/ampl.vim
@@ -1,0 +1,150 @@
+" Language:     ampl (A Mathematical Programming Language)
+" Maintainer:   Krief David <david.krief@etu.enseeiht.fr> or <david_krief@hotmail.com>
+" Last Change:  2003 May 11
+
+
+if version < 600
+ syntax clear
+elseif exists("b:current_syntax")
+ finish
+endif
+
+
+
+
+"--
+syn match   amplEntityKeyword     "\(subject to\)\|\(subj to\)\|\(s\.t\.\)"
+syn keyword amplEntityKeyword	  minimize   maximize  objective
+
+syn keyword amplEntityKeyword	  coeff      coef      cover	    obj       default
+syn keyword amplEntityKeyword	  from	     to        to_come	    net_in    net_out
+syn keyword amplEntityKeyword	  dimen      dimension
+
+
+
+"--
+syn keyword amplType		  integer    binary    set	    param     var
+syn keyword amplType		  node	     ordered   circular     reversed  symbolic
+syn keyword amplType		  arc
+
+
+
+"--
+syn keyword amplStatement	  check      close     \display     drop      include
+syn keyword amplStatement	  print      printf    quit	    reset     restore
+syn keyword amplStatement	  solve      update    write	    shell     model
+syn keyword amplStatement	  data	     option    let	    solution  fix
+syn keyword amplStatement	  unfix      end       function     pipe      format
+
+
+
+"--
+syn keyword amplConditional	  if	     then      else	    and       or
+syn keyword amplConditional	  exists     forall    in	    not       within
+
+
+
+"--
+syn keyword amplRepeat		  while      repeat    for
+
+
+
+"--
+syn keyword amplOperators	  union      diff      difference   symdiff   sum
+syn keyword amplOperators	  inter      intersect intersection cross     setof
+syn keyword amplOperators	  by	     less      mod	    div       product
+"syn keyword amplOperators	   min	      max
+"conflict between functions max, min and operators max, min
+
+syn match   amplBasicOperators    "||\|<=\|==\|\^\|<\|=\|!\|-\|\.\.\|:="
+syn match   amplBasicOperators    "&&\|>=\|!=\|\*\|>\|:\|/\|+\|\*\*"
+
+
+
+
+"--
+syn match   amplComment		"\#.*"
+syn region  amplComment		start=+\/\*+		  end=+\*\/+
+
+syn region  amplStrings		start=+\'+    skip=+\\'+  end=+\'+
+syn region  amplStrings		start=+\"+    skip=+\\"+  end=+\"+
+
+syn match   amplNumerics	"[+-]\=\<\d\+\(\.\d\+\)\=\([dDeE][-+]\=\d\+\)\=\>"
+syn match   amplNumerics	"[+-]\=Infinity"
+
+
+"--
+syn keyword amplSetFunction	  card	     next     nextw	  prev	    prevw
+syn keyword amplSetFunction	  first      last     member	  ord	    ord0
+
+syn keyword amplBuiltInFunction   abs	     acos     acosh	  alias     asin
+syn keyword amplBuiltInFunction   asinh      atan     atan2	  atanh     ceil
+syn keyword amplBuiltInFunction   cos	     exp      floor	  log	    log10
+syn keyword amplBuiltInFunction   max	     min      precision   round     sin
+syn keyword amplBuiltInFunction   sinh	     sqrt     tan	  tanh	    trunc
+
+syn keyword amplRandomGenerator   Beta	     Cauchy   Exponential Gamma     Irand224
+syn keyword amplRandomGenerator   Normal     Poisson  Uniform	  Uniform01
+
+
+
+"-- to highlight the 'dot-suffixes'
+syn match   amplDotSuffix	"\h\w*\.\(lb\|ub\)"hs=e-2
+syn match   amplDotSuffix	"\h\w*\.\(lb0\|lb1\|lb2\|lrc\|ub0\)"hs=e-3
+syn match   amplDotSuffix	"\h\w*\.\(ub1\|ub2\|urc\|val\|lbs\|ubs\)"hs=e-3
+syn match   amplDotSuffix	"\h\w*\.\(init\|body\|dinit\|dual\)"hs=e-4
+syn match   amplDotSuffix	"\h\w*\.\(init0\|ldual\|slack\|udual\)"hs=e-5
+syn match   amplDotSuffix	"\h\w*\.\(lslack\|uslack\|dinit0\)"hs=e-6
+
+
+
+"--
+syn match   amplPiecewise	"<<\|>>"
+
+
+
+"-- Todo.
+syn keyword amplTodo contained	 TODO FIXME XXX
+
+
+
+
+
+
+
+
+
+
+if version >= 508 || !exists("did_ampl_syntax_inits")
+  if version < 508
+    let did_ampl_syntax_inits = 1
+    command -nargs=+ HiLink hi link <args>
+  else
+    command -nargs=+ HiLink hi def link <args>
+  endif
+
+  " The default methods for highlighting. Can be overridden later.
+  HiLink amplEntityKeyword	Keyword
+  HiLink amplType		Type
+  HiLink amplStatement		Statement
+  HiLink amplOperators		Operator
+  HiLink amplBasicOperators	Operator
+  HiLink amplConditional	Conditional
+  HiLink amplRepeat		Repeat
+  HiLink amplStrings		String
+  HiLink amplNumerics		Number
+  HiLink amplSetFunction	Function
+  HiLink amplBuiltInFunction	Function
+  HiLink amplRandomGenerator	Function
+  HiLink amplComment		Comment
+  HiLink amplDotSuffix		Special
+  HiLink amplPiecewise		Special
+
+  delcommand HiLink
+endif
+
+let b:current_syntax = "ampl"
+
+" vim: ts=8
+
+
--- /dev/null
+++ b/lib/vimfiles/syntax/ant.vim
@@ -1,0 +1,97 @@
+" Vim syntax file
+" Language:	ANT build file (xml)
+" Maintainer:	Johannes Zellner <johannes@zellner.org>
+" Last Change:	Tue Apr 27 13:05:59 CEST 2004
+" Filenames:	build.xml
+" $Id: ant.vim,v 1.1 2004/06/13 18:13:18 vimboss Exp $
+
+" Quit when a syntax file was already loaded
+if exists("b:current_syntax")
+    finish
+endif
+
+let s:ant_cpo_save = &cpo
+set cpo&vim
+
+runtime! syntax/xml.vim
+
+syn case ignore
+
+if !exists('*AntSyntaxScript')
+    fun AntSyntaxScript(tagname, synfilename)
+	unlet b:current_syntax
+	let s:include = expand("<sfile>:p:h").'/'.a:synfilename
+	if filereadable(s:include)
+	    exe 'syn include @ant'.a:tagname.' '.s:include
+	else
+	    exe 'syn include @ant'.a:tagname." $VIMRUNTIME/syntax/".a:synfilename
+	endif
+
+	exe 'syn region ant'.a:tagname
+		    \." start=#<script[^>]\\{-}language\\s*=\\s*['\"]".a:tagname."['\"]\\(>\\|[^>]*[^/>]>\\)#"
+		    \.' end=#</script>#'
+		    \.' fold'
+		    \.' contains=@ant'.a:tagname.',xmlCdataStart,xmlCdataEnd,xmlTag,xmlEndTag'
+		    \.' keepend'
+	exe 'syn cluster xmlRegionHook add=ant'.a:tagname
+    endfun
+endif
+
+" TODO: add more script languages here ?
+call AntSyntaxScript('javascript', 'javascript.vim')
+call AntSyntaxScript('jpython', 'python.vim')
+
+
+syn cluster xmlTagHook add=antElement
+
+syn keyword antElement display WsdlToDotnet addfiles and ant antcall antstructure apply archives arg argument
+syn keyword antElement display assertions attrib attribute available basename bcc blgenclient bootclasspath
+syn keyword antElement display borland bottom buildnumber buildpath buildpathelement bunzip2 bzip2 cab
+syn keyword antElement display catalogpath cc cccheckin cccheckout cclock ccmcheckin ccmcheckintask ccmcheckout
+syn keyword antElement display ccmcreatetask ccmkattr ccmkbl ccmkdir ccmkelem ccmklabel ccmklbtype
+syn keyword antElement display ccmreconfigure ccrmtype ccuncheckout ccunlock ccupdate checksum chgrp chmod
+syn keyword antElement display chown classconstants classes classfileset classpath commandline comment
+syn keyword antElement display compilerarg compilerclasspath concat concatfilter condition copy copydir
+syn keyword antElement display copyfile coveragepath csc custom cvs cvschangelog cvspass cvstagdiff cvsversion
+syn keyword antElement display daemons date defaultexcludes define delete deletecharacters deltree depend
+syn keyword antElement display depends dependset depth description different dirname dirset disable dname
+syn keyword antElement display doclet doctitle dtd ear echo echoproperties ejbjar element enable entity entry
+syn keyword antElement display env equals escapeunicode exclude excludepackage excludesfile exec execon
+syn keyword antElement display existing expandproperties extdirs extension extensionSet extensionset factory
+syn keyword antElement display fail filelist filename filepath fileset filesmatch filetokenizer filter
+syn keyword antElement display filterchain filterreader filters filterset filtersfile fixcrlf footer format
+syn keyword antElement display from ftp generic genkey get gjdoc grant group gunzip gzip header headfilter http
+syn keyword antElement display ignoreblank ilasm ildasm import importtypelib include includesfile input iplanet
+syn keyword antElement display iplanet-ejbc isfalse isreference isset istrue jar jarlib-available
+syn keyword antElement display jarlib-manifest jarlib-resolve java javac javacc javadoc javadoc2 jboss jdepend
+syn keyword antElement display jjdoc jjtree jlink jonas jpcoverage jpcovmerge jpcovreport jsharpc jspc
+syn keyword antElement display junitreport jvmarg lib libfileset linetokenizer link loadfile loadproperties
+syn keyword antElement display location macrodef mail majority manifest map mapper marker mergefiles message
+syn keyword antElement display metainf method mimemail mkdir mmetrics modified move mparse none not options or
+syn keyword antElement display os outputproperty package packageset parallel param patch path pathconvert
+syn keyword antElement display pathelement patternset permissions prefixlines present presetdef project
+syn keyword antElement display property propertyfile propertyref propertyset pvcs pvcsproject record reference
+syn keyword antElement display regexp rename renameext replace replacefilter replaceregex replaceregexp
+syn keyword antElement display replacestring replacetoken replacetokens replacevalue replyto report resource
+syn keyword antElement display revoke rmic root rootfileset rpm scp section selector sequential serverdeploy
+syn keyword antElement display setproxy signjar size sleep socket soscheckin soscheckout sosget soslabel source
+syn keyword antElement display sourcepath sql src srcfile srcfilelist srcfiles srcfileset sshexec stcheckin
+syn keyword antElement display stcheckout stlabel stlist stringtokenizer stripjavacomments striplinebreaks
+syn keyword antElement display striplinecomments style subant substitution support symlink sync sysproperty
+syn keyword antElement display syspropertyset tabstospaces tag taglet tailfilter tar tarfileset target
+syn keyword antElement display targetfile targetfilelist targetfileset taskdef tempfile test testlet text title
+syn keyword antElement display to token tokenfilter touch transaction translate triggers trim tstamp type
+syn keyword antElement display typedef unjar untar unwar unzip uptodate url user vbc vssadd vsscheckin
+syn keyword antElement display vsscheckout vsscp vsscreate vssget vsshistory vsslabel waitfor war wasclasspath
+syn keyword antElement display webapp webinf weblogic weblogictoplink websphere whichresource wlclasspath
+syn keyword antElement display wljspc wsdltodotnet xmlcatalog xmlproperty xmlvalidate xslt zip zipfileset
+syn keyword antElement display zipgroupfileset
+
+hi def link antElement Statement
+
+let b:current_syntax = "ant"
+
+let &cpo = s:ant_cpo_save
+unlet s:ant_cpo_save
+
+" vim: ts=8
--- /dev/null
+++ b/lib/vimfiles/syntax/antlr.vim
@@ -1,0 +1,70 @@
+" Vim syntax file
+" Antlr:	ANTLR, Another Tool For Language Recognition <www.antlr.org>
+" Maintainer:	Mathieu Clabaut <mathieu.clabaut@free.fr>
+" LastChange:	02 May 2001
+" Original:	Comes from JavaCC.vim
+
+" For version 5.x: Clear all syntax items
+" For version 6.x: Quit when a syntax file was already loaded
+if version < 600
+   syntax clear
+elseif exists("b:current_syntax")
+   finish
+endif
+
+" This syntac file is a first attempt. It is far from perfect...
+
+" Uses java.vim, and adds a few special things for JavaCC Parser files.
+" Those files usually have the extension  *.jj
+
+" source the java.vim file
+if version < 600
+   so <sfile>:p:h/java.vim
+else
+   runtime! syntax/java.vim
+   unlet b:current_syntax
+endif
+
+"remove catching errors caused by wrong parenthesis (does not work in antlr
+"files) (first define them in case they have not been defined in java)
+syn match	javaParen "--"
+syn match	javaParenError "--"
+syn match	javaInParen "--"
+syn match	javaError2 "--"
+syn clear	javaParen
+syn clear	javaParenError
+syn clear	javaInParen
+syn clear	javaError2
+
+" remove function definitions (they look different) (first define in
+" in case it was not defined in java.vim)
+"syn match javaFuncDef "--"
+"syn clear javaFuncDef
+"syn match javaFuncDef "[a-zA-Z][a-zA-Z0-9_. \[\]]*([^-+*/()]*)[ \t]*:" contains=javaType
+" syn region javaFuncDef start=+t[a-zA-Z][a-zA-Z0-9_. \[\]]*([^-+*/()]*,[ 	]*+ end=+)[ \t]*:+
+
+syn keyword antlrPackages options language buildAST
+syn match antlrPackages "PARSER_END([^)]*)"
+syn match antlrPackages "PARSER_BEGIN([^)]*)"
+syn match antlrSpecToken "<EOF>"
+" the dot is necessary as otherwise it will be matched as a keyword.
+syn match antlrSpecToken ".LOOKAHEAD("ms=s+1,me=e-1
+syn match antlrSep "[|:]\|\.\."
+syn keyword antlrActionToken TOKEN SKIP MORE SPECIAL_TOKEN
+syn keyword antlrError DEBUG IGNORE_IN_BNF
+
+if version >= 508 || !exists("did_antlr_syntax_inits")
+   if version < 508
+      let did_antlr_syntax_inits = 1
+      command -nargs=+ HiLink hi link <args>
+   else
+      command -nargs=+ HiLink hi def link <args>
+   endif
+   HiLink antlrSep Statement
+   HiLink antlrPackages Statement
+  delcommand HiLink
+endif
+
+let b:current_syntax = "antlr"
+
+" vim: ts=8
--- /dev/null
+++ b/lib/vimfiles/syntax/apache.vim
@@ -1,0 +1,213 @@
+" Vim syntax file
+" This is a GENERATED FILE. Please always refer to source file at the URI below.
+" Language: Apache configuration (httpd.conf, srm.conf, access.conf, .htaccess)
+" Maintainer: David Ne\v{c}as (Yeti) <yeti@physics.muni.cz>
+" License: This file can be redistribued and/or modified under the same terms
+"		as Vim itself.
+" Last Change: 2006-12-13
+" URL: http://trific.ath.cx/Ftp/vim/syntax/apache.vim
+" Notes: Last synced with apache-2.2.3, version 1.x is no longer supported
+" TODO: see particular FIXME's scattered through the file
+"		make it really linewise?
+"		+ add `display' where appropriate
+
+" Setup
+if version >= 600
+	if exists("b:current_syntax")
+		finish
+	endif
+else
+	syntax clear
+endif
+
+syn case ignore
+
+" Base constructs
+syn match apacheComment "^\s*#.*$" contains=apacheFixme
+syn match apacheUserID "#-\?\d\+\>"
+syn case match
+syn keyword apacheFixme FIXME TODO XXX NOT
+syn case ignore
+syn match apacheAnything "\s[^>]*" contained
+syn match apacheError "\w\+" contained
+syn region apacheString start=+"+ end=+"+ skip=+\\\\\|\\\"+
+
+" Core and mpm
+syn keyword apacheDeclaration AccessFileName AddDefaultCharset AllowOverride AuthName AuthType ContentDigest DefaultType DocumentRoot ErrorDocument ErrorLog HostNameLookups IdentityCheck Include KeepAlive KeepAliveTimeout LimitRequestBody LimitRequestFields LimitRequestFieldsize LimitRequestLine LogLevel MaxKeepAliveRequests NameVirtualHost Options Require RLimitCPU RLimitMEM RLimitNPROC Satisfy ScriptInterpreterSource ServerAdmin ServerAlias ServerName ServerPath ServerRoot ServerSignature ServerTokens TimeOut UseCanonicalName
+syn keyword apacheDeclaration AcceptPathInfo CGIMapExtension EnableMMAP FileETag ForceType LimitXMLRequestBody SetHandler SetInputFilter SetOutputFilter
+syn keyword apacheDeclaration AcceptFilter AllowEncodedSlashes EnableSendfile LimitInternalRecursion TraceEnable
+syn keyword apacheOption INode MTime Size
+syn keyword apacheOption Any All On Off Double EMail DNS Min Minimal OS Prod ProductOnly Full
+syn keyword apacheOption emerg alert crit error warn notice info debug
+syn keyword apacheOption registry script inetd standalone
+syn match apacheOptionOption "[+-]\?\<\(ExecCGI\|FollowSymLinks\|Includes\|IncludesNoExec\|Indexes\|MultiViews\|SymLinksIfOwnerMatch\)\>"
+syn keyword apacheOption user group
+syn match apacheOption "\<valid-user\>"
+syn case match
+syn keyword apacheMethodOption GET POST PUT DELETE CONNECT OPTIONS TRACE PATCH PROPFIND PROPPATCH MKCOL COPY MOVE LOCK UNLOCK contained
+syn case ignore
+syn match apacheSection "<\/\=\(Directory\|DirectoryMatch\|Files\|FilesMatch\|IfModule\|IfDefine\|Location\|LocationMatch\|VirtualHost\)[^>]*>" contains=apacheAnything
+syn match apacheLimitSection "<\/\=\(Limit\|LimitExcept\)[^>]*>" contains=apacheLimitSectionKeyword,apacheMethodOption,apacheError
+syn keyword apacheLimitSectionKeyword Limit LimitExcept contained
+syn match apacheAuthType "AuthType\s.*$" contains=apacheAuthTypeValue
+syn keyword apacheAuthTypeValue Basic Digest
+syn match apacheAllowOverride "AllowOverride\s.*$" contains=apacheAllowOverrideValue,apacheComment
+syn keyword apacheAllowOverrideValue AuthConfig FileInfo Indexes Limit Options contained
+syn keyword apacheDeclaration CoreDumpDirectory EnableExceptionHook GracefulShutdownTimeout Group Listen ListenBacklog LockFile MaxClients MaxMemFree MaxRequestsPerChild MaxSpareThreads MaxSpareThreadsPerChild MinSpareThreads NumServers PidFile ScoreBoardFile SendBufferSize ServerLimit StartServers StartThreads ThreadLimit ThreadsPerChild User
+syn keyword apacheDeclaration MaxThreads ThreadStackSize
+syn keyword apacheDeclaration Win32DisableAcceptEx
+syn keyword apacheDeclaration AssignUserId ChildPerUserId
+syn keyword apacheDeclaration AcceptMutex MaxSpareServers MinSpareServers
+syn keyword apacheOption flock fcntl sysvsem pthread
+
+" Modules
+syn keyword apacheDeclaration Action Script
+syn keyword apacheDeclaration Alias AliasMatch Redirect RedirectMatch RedirectTemp RedirectPermanent ScriptAlias ScriptAliasMatch
+syn keyword apacheOption permanent temp seeother gone
+syn keyword apacheDeclaration AuthAuthoritative AuthGroupFile AuthUserFile
+syn keyword apacheDeclaration AuthBasicAuthoritative AuthBasicProvider
+syn keyword apacheDeclaration AuthDigestAlgorithm AuthDigestDomain AuthDigestNcCheck AuthDigestNonceFormat AuthDigestNonceLifetime AuthDigestProvider AuthDigestQop AuthDigestShmemSize
+syn keyword apacheOption none auth auth-int MD5 MD5-sess
+syn match apacheSection "<\/\=\(<AuthnProviderAlias\)[^>]*>" contains=apacheAnything
+syn keyword apacheDeclaration Anonymous Anonymous_Authoritative Anonymous_LogEmail Anonymous_MustGiveEmail Anonymous_NoUserID Anonymous_VerifyEmail
+syn keyword apacheDeclaration AuthDBDUserPWQuery AuthDBDUserRealmQuery
+syn keyword apacheDeclaration AuthDBMGroupFile AuthDBMAuthoritative
+syn keyword apacheDeclaration AuthDBM TypeAuthDBMUserFile
+syn keyword apacheOption default SDBM GDBM NDBM DB
+syn keyword apacheDeclaration AuthDefaultAuthoritative
+syn keyword apacheDeclaration AuthUserFile
+syn keyword apacheDeclaration AuthLDAPBindON AuthLDAPEnabled AuthLDAPFrontPageHack AuthLDAPStartTLS
+syn keyword apacheDeclaration AuthLDAPBindDN AuthLDAPBindPassword AuthLDAPCharsetConfig AuthLDAPCompareDNOnServer AuthLDAPDereferenceAliases AuthLDAPGroupAttribute AuthLDAPGroupAttributeIsDN AuthLDAPRemoteUserIsDN AuthLDAPUrl AuthzLDAPAuthoritative
+syn keyword apacheOption always never searching finding
+syn keyword apacheOption ldap-user ldap-group ldap-dn ldap-attribute ldap-filter
+syn keyword apacheDeclaration AuthDBMGroupFile AuthzDBMAuthoritative AuthzDBMType
+syn keyword apacheDeclaration AuthzDefaultAuthoritative
+syn keyword apacheDeclaration AuthGroupFile AuthzGroupFileAuthoritative
+syn match apacheAllowDeny "Allow\s\+from.*$" contains=apacheAllowDenyValue,apacheComment
+syn match apacheAllowDeny "Deny\s\+from.*$" contains=apacheAllowDenyValue,apacheComment
+syn keyword apacheAllowDenyValue All None contained
+syn match apacheOrder "^\s*Order\s.*$" contains=apacheOrderValue,apacheComment
+syn keyword apacheOrderValue Deny Allow contained
+syn keyword apacheDeclaration  AuthzOwnerAuthoritative
+syn keyword apacheDeclaration  AuthzUserAuthoritative
+syn keyword apacheDeclaration AddAlt AddAltByEncoding AddAltByType AddDescription AddIcon AddIconByEncoding AddIconByType DefaultIcon HeaderName IndexIgnore IndexOptions IndexOrderDefault ReadmeName
+syn keyword apacheDeclaration IndexStyleSheet
+syn keyword apacheOption DescriptionWidth FancyIndexing FoldersFirst IconHeight IconsAreLinks IconWidth NameWidth ScanHTMLTitles SuppressColumnSorting SuppressDescription SuppressHTMLPreamble SuppressLastModified SuppressSize TrackModified
+syn keyword apacheOption Ascending Descending Name Date Size Description
+syn keyword apacheOption HTMLTable SuppressIcon SuppressRules VersionSort XHTML
+syn keyword apacheOption IgnoreClient IgnoreCase ShowForbidden SuppresRules
+syn keyword apacheDeclaration CacheForceCompletion CacheMaxStreamingBuffer
+syn keyword apacheDeclaration CacheDefaultExpire CacheDisable CacheEnable CacheIgnoreCacheControl CacheIgnoreHeaders CacheIgnoreNoLastMod CacheLastModifiedFactor CacheMaxExpire CacheStoreNoStore CacheStorePrivate
+syn keyword apacheDeclaration MetaFiles MetaDir MetaSuffix
+syn keyword apacheDeclaration ScriptLog ScriptLogLength ScriptLogBuffer
+syn keyword apacheDeclaration ScriptStock
+syn keyword apacheDeclaration CharsetDefault CharsetOptions CharsetSourceEnc
+syn keyword apacheOption DebugLevel ImplicitAdd NoImplicitAdd
+syn keyword apacheDeclaration Dav DavDepthInfinity DavMinTimeout
+syn keyword apacheDeclaration DavLockDB
+syn keyword apacheDeclaration DavGenericLockDB
+syn keyword apacheDeclaration DBDExptime DBDKeep DBDMax DBDMin DBDParams DBDPersist DBDPrepareSQL DBDriver
+syn keyword apacheDeclaration DeflateCompressionLevel DeflateBufferSize DeflateFilterNote DeflateMemLevel DeflateWindowSize
+syn keyword apacheDeclaration DirectoryIndex DirectorySlash
+syn keyword apacheDeclaration CacheExpiryCheck CacheGcClean CacheGcDaily CacheGcInterval CacheGcMemUsage CacheGcUnused CacheSize CacheTimeMargin
+syn keyword apacheDeclaration CacheDirLength CacheDirLevels CacheMaxFileSize CacheMinFileSize CacheRoot
+syn keyword apacheDeclaration DumpIOInput DumpIOOutput
+syn keyword apacheDeclaration ProtocolEcho
+syn keyword apacheDeclaration PassEnv SetEnv UnsetEnv
+syn keyword apacheDeclaration Example
+syn keyword apacheDeclaration ExpiresActive ExpiresByType ExpiresDefault
+syn keyword apacheDeclaration ExtFilterDefine ExtFilterOptions
+syn keyword apacheOption PreservesContentLength DebugLevel LogStderr NoLogStderr
+syn match apacheOption "\<\(cmd\|mode\|intype\|outtype\|ftype\|disableenv\|enableenv\)\ze="
+syn keyword apacheDeclaration CacheFile MMapFile
+syn keyword apacheDeclaration FilterChain FilterDeclare FilterProtocol FilterProvider FilterTrace
+syn keyword apacheDeclaration Header
+syn keyword apacheDeclaration RequestHeader
+syn keyword apacheOption set unset append add
+syn keyword apacheDeclaration IdentityCheck IdentityCheckTimeout
+syn keyword apacheDeclaration ImapMenu ImapDefault ImapBase
+syn keyword apacheOption none formatted semiformatted unformatted
+syn keyword apacheOption nocontent referer error map
+syn keyword apacheDeclaration SSIEndTag SSIErrorMsg SSIStartTag SSITimeFormat SSIUndefinedEcho XBitHack
+syn keyword apacheOption on off full
+syn keyword apacheDeclaration AddModuleInfo
+syn keyword apacheDeclaration ISAPIReadAheadBuffer ISAPILogNotSupported ISAPIAppendLogToErrors ISAPIAppendLogToQuery
+syn keyword apacheDeclaration ISAPICacheFile ISAIPFakeAsync
+syn keyword apacheDeclaration LDAPCertDBPath
+syn keyword apacheDeclaration LDAPCacheEntries LDAPCacheTTL LDAPConnectionTimeout LDAPOpCacheEntries LDAPOpCacheTTL LDAPSharedCacheFile LDAPSharedCacheSize LDAPTrustedClientCert LDAPTrustedGlobalCert LDAPTrustedMode LDAPVerifyServerCert
+syn keyword apacheOption CA_DER CA_BASE64 CA_CERT7_DB CA_SECMOD CERT_DER CERT_BASE64 CERT_KEY3_DB CERT_NICKNAME CERT_PFX KEY_DER KEY_BASE64 KEY_PFX
+syn keyword apacheDeclaration BufferedLogs CookieLog CustomLog LogFormat TransferLog
+syn keyword apacheDeclaration ForensicLog
+syn keyword apacheDeclaration MCacheMaxObjectCount MCacheMaxObjectSize MCacheMaxStreamingBuffer MCacheMinObjectSize MCacheRemovalAlgorithm MCacheSize
+syn keyword apacheDeclaration AddCharset AddEncoding AddHandler AddLanguage AddType DefaultLanguage RemoveEncoding RemoveHandler RemoveType TypesConfig
+syn keyword apacheDeclaration AddInputFilter AddOutputFilter ModMimeUsePathInfo MultiviewsMatch RemoveInputFilter RemoveOutputFilter RemoveCharset
+syn keyword apacheOption NegotiatedOnly Filters Handlers
+syn keyword apacheDeclaration MimeMagicFile
+syn keyword apacheDeclaration MMapFile
+syn keyword apacheDeclaration CacheNegotiatedDocs LanguagePriority ForceLanguagePriority
+syn keyword apacheDeclaration NWSSLTrustedCerts NWSSLUpgradeable SecureListen
+syn keyword apacheDeclaration PerlModule PerlRequire PerlTaintCheck PerlWarn
+syn keyword apacheDeclaration PerlSetVar PerlSetEnv PerlPassEnv PerlSetupEnv
+syn keyword apacheDeclaration PerlInitHandler PerlPostReadRequestHandler PerlHeaderParserHandler
+syn keyword apacheDeclaration PerlTransHandler PerlAccessHandler PerlAuthenHandler PerlAuthzHandler
+syn keyword apacheDeclaration PerlTypeHandler PerlFixupHandler PerlHandler PerlLogHandler
+syn keyword apacheDeclaration PerlCleanupHandler PerlChildInitHandler PerlChildExitHandler
+syn keyword apacheDeclaration PerlRestartHandler PerlDispatchHandler
+syn keyword apacheDeclaration PerlFreshRestart PerlSendHeader
+syn keyword apacheDeclaration php_value php_flag php_admin_value php_admin_flag
+syn match apacheSection "<\/\=\(Proxy\|ProxyMatch\)[^>]*>" contains=apacheAnything
+syn keyword apacheDeclaration AllowCONNECT NoProxy ProxyBadHeader ProxyBlock ProxyDomain ProxyErrorOverride ProxyIOBufferSize ProxyMaxForwards ProxyPass ProxyPassReverse ProxyPassReverseCookieDomain ProxyPassReverseCookiePath ProxyPreserveHost ProxyReceiveBufferSize ProxyRemote ProxyRemoteMatch ProxyRequests ProxyTimeout ProxyVia
+syn keyword apacheDeclaration RewriteBase RewriteCond RewriteEngine RewriteLock RewriteLog RewriteLogLevel RewriteMap RewriteOptions RewriteRule
+syn keyword apacheOption inherit
+syn keyword apacheDeclaration BrowserMatch BrowserMatchNoCase SetEnvIf SetEnvIfNoCase
+syn keyword apacheDeclaration LoadFile LoadModule
+syn keyword apacheDeclaration CheckSpelling CheckCaseOnly
+syn keyword apacheDeclaration SSLCACertificateFile SSLCACertificatePath SSLCADNRequestFile SSLCADNRequestPath SSLCARevocationFile SSLCARevocationPath SSLCertificateChainFile SSLCertificateFile SSLCertificateKeyFile SSLCipherSuite SSLCryptoDevice SSLEngine SSLHonorCipherOrder SSLMutex SSLOptions SSLPassPhraseDialog SSLProtocol SSLProxyCACertificateFile SSLProxyCACertificatePath SSLProxyCARevocationFile SSLProxyCARevocationPath SSLProxyCipherSuite SSLProxyEngine SSLProxyMachineCertificateFile SSLProxyMachineCertificatePath SSLProxyProtocol SSLProxyVerify SSLProxyVerifyDepth SSLRandomSeed SSLRequire SSLRequireSSL SSLSessionCache SSLSessionCacheTimeout SSLUserName SSLVerifyClient SSLVerifyDepth
+syn match apacheOption "[+-]\?\<\(StdEnvVars\|CompatEnvVars\|ExportCertData\|FakeBasicAuth\|StrictRequire\|OptRenegotiate\)\>"
+syn keyword apacheOption builtin sem
+syn match apacheOption "\(file\|exec\|egd\|dbm\|shm\):"
+syn match apacheOption "[+-]\?\<\(SSLv2\|SSLv3\|TLSv1\|kRSA\|kHDr\|kDHd\|kEDH\|aNULL\|aRSA\|aDSS\|aRH\|eNULL\|DES\|3DES\|RC2\|RC4\|IDEA\|MD5\|SHA1\|SHA\|EXP\|EXPORT40\|EXPORT56\|LOW\|MEDIUM\|HIGH\|RSA\|DH\|EDH\|ADH\|DSS\|NULL\)\>"
+syn keyword apacheOption optional optional_no_ca
+syn keyword apacheDeclaration ExtendedStatus
+syn keyword apacheDeclaration SuexecUserGroup
+syn keyword apacheDeclaration UserDir
+syn keyword apacheDeclaration CookieDomain CookieExpires CookieName CookieStyle CookieTracking
+syn keyword apacheOption Netscape Cookie Cookie2 RFC2109 RFC2965
+syn match apacheSection "<\/\=\(<IfVersion\)[^>]*>" contains=apacheAnything
+syn keyword apacheDeclaration VirtualDocumentRoot VirtualDocumentRootIP VirtualScriptAlias VirtualScriptAliasIP
+
+" Define the default highlighting
+if version >= 508 || !exists("did_apache_syntax_inits")
+	if version < 508
+		let did_apache_syntax_inits = 1
+		command -nargs=+ HiLink hi link <args>
+	else
+		command -nargs=+ HiLink hi def link <args>
+	endif
+
+	HiLink apacheAllowOverride apacheDeclaration
+	HiLink apacheAllowOverrideValue apacheOption
+	HiLink apacheAuthType apacheDeclaration
+	HiLink apacheAuthTypeValue apacheOption
+	HiLink apacheOptionOption apacheOption
+	HiLink apacheDeclaration Function
+	HiLink apacheAnything apacheOption
+	HiLink apacheOption Number
+	HiLink apacheComment Comment
+	HiLink apacheFixme Todo
+	HiLink apacheLimitSectionKeyword apacheLimitSection
+	HiLink apacheLimitSection apacheSection
+	HiLink apacheSection Label
+	HiLink apacheMethodOption Type
+	HiLink apacheAllowDeny Include
+	HiLink apacheAllowDenyValue Identifier
+	HiLink apacheOrder Special
+	HiLink apacheOrderValue String
+	HiLink apacheString String
+	HiLink apacheError Error
+	HiLink apacheUserID Number
+
+	delcommand HiLink
+endif
+
+let b:current_syntax = "apache"
--- /dev/null
+++ b/lib/vimfiles/syntax/apachestyle.vim
@@ -1,0 +1,65 @@
+" Vim syntax file
+" Language:	Apache-Style configuration files (proftpd.conf/apache.conf/..)
+" Maintainer:	Christian Hammers <ch@westend.com>
+" URL:		none
+" ChangeLog:
+"	2001-05-04,ch
+"		adopted Vim 6.0 syntax style
+"	1999-10-28,ch
+"		initial release
+
+" The following formats are recognised:
+" Apache-style .conf
+"	# Comment
+"	Option	value
+"	Option	value1 value2
+"	Option = value1 value2 #not apache but also allowed
+"	<Section Name?>
+"		Option	value
+"		<SubSection Name?>
+"		</SubSection>
+"	</Section>
+
+" For version 5.x: Clear all syntax items
+" For version 6.x: Quit when a syntax file was already loaded
+if version < 600
+  syntax clear
+elseif exists("b:current_syntax")
+  finish
+endif
+
+syn case ignore
+
+syn match  apComment	/^\s*#.*$/
+syn match  apOption	/^\s*[^ \t#<=]*/
+"syn match  apLastValue	/[^ \t<=#]*$/ contains=apComment	ugly
+
+" tags
+syn region apTag	start=/</ end=/>/ contains=apTagOption,apTagError
+" the following should originally be " [^<>]+" but this didn't work :(
+syn match  apTagOption	contained / [-\/_\.:*a-zA-Z0-9]\+/ms=s+1
+syn match  apTagError	contained /[^>]</ms=s+1
+
+" Define the default highlighting.
+" For version 5.7 and earlier: only when not done already
+" For version 5.8 and later: only when an item doesn't have highlighting yet
+if version >= 508 || !exists("did_apachestyle_syn_inits")
+  if version < 508
+    let did_apachestyle_syn_inits = 1
+    command -nargs=+ HiLink hi link <args>
+  else
+    command -nargs=+ HiLink hi def link <args>
+  endif
+
+  HiLink apComment	Comment
+  HiLink apOption	Keyword
+  "HiLink apLastValue	Identifier		ugly?
+  HiLink apTag		Special
+  HiLink apTagOption	Identifier
+  HiLink apTagError	Error
+
+  delcommand HiLink
+endif
+
+let b:current_syntax = "apachestyle"
+" vim: ts=8
--- /dev/null
+++ b/lib/vimfiles/syntax/arch.vim
@@ -1,0 +1,41 @@
+" Vim syntax file
+" Language:         GNU Arch inventory file
+" Maintainer:       Nikolai Weibull <now@bitwi.se>
+" Latest Revision:  2007-05-06
+
+if exists("b:current_syntax")
+  finish
+endif
+
+let s:cpo_save = &cpo
+set cpo&vim
+
+setlocal iskeyword=@,48-57,_,-
+
+syn keyword archTodo    TODO FIXME XXX NOTE
+
+syn region  archComment display start='^\%(#\|\s\)' end='$'
+                        \ contains=archTodo,@Spell
+
+syn match   archBegin   display '^' nextgroup=archKeyword,archComment
+
+syn keyword archKeyword contained implicit tagline explicit names
+syn keyword archKeyword contained untagged-source
+                        \ nextgroup=archTMethod skipwhite
+syn keyword archKeyword contained exclude junk backup precious unrecognized
+                        \ source nextgroup=archRegex skipwhite
+
+syn keyword archTMethod contained source precious backup junk unrecognized
+
+syn match   archRegex   contained '\s*\zs.*'
+
+hi def link archTodo    Todo
+hi def link archComment Comment
+hi def link archKeyword Keyword
+hi def link archTMethod Type
+hi def link archRegex   String
+
+let b:current_syntax = "arch"
+
+let &cpo = s:cpo_save
+unlet s:cpo_save
--- /dev/null
+++ b/lib/vimfiles/syntax/art.vim
@@ -1,0 +1,44 @@
+" Vim syntax file
+" Language:      ART-IM and ART*Enterprise
+" Maintainer:    Dorai Sitaram <ds26@gte.com>
+" URL:		 http://www.ccs.neu.edu/~dorai/vimplugins/vimplugins.html
+" Last Change:   Nov 6, 2002
+
+if exists("b:current_syntax")
+  finish
+endif
+
+syn case ignore
+
+syn keyword artspform => and assert bind
+syn keyword artspform declare def-art-fun deffacts defglobal defrule defschema do
+syn keyword artspform else for if in$ not or
+syn keyword artspform progn retract salience schema test then while
+
+syn match artvariable "?[^ \t";()|&~]\+"
+
+syn match artglobalvar "?\*[^ \t";()|&~]\+\*"
+
+syn match artinstance "![^ \t";()|&~]\+"
+
+syn match delimiter "[()|&~]"
+
+syn region string start=/"/ skip=/\\[\\"]/ end=/"/
+
+syn match number "\<[-+]\=\([0-9]\+\(\.[0-9]*\)\=\|\.[0-9]\+\)\>"
+
+syn match comment ";.*$"
+
+syn match comment "#+:\=ignore" nextgroup=artignore skipwhite skipnl
+
+syn region artignore start="(" end=")" contained contains=artignore,comment
+
+syn region artignore start=/"/ skip=/\\[\\"]/ end=/"/ contained
+
+hi def link artinstance type
+hi def link artglobalvar preproc
+hi def link artignore comment
+hi def link artspform statement
+hi def link artvariable function
+
+let b:current_syntax = "art"
--- /dev/null
+++ b/lib/vimfiles/syntax/asm.vim
@@ -1,0 +1,103 @@
+" Vim syntax file
+" Language:	GNU Assembler
+" Maintainer:	Kevin Dahlhausen <kdahlhaus@yahoo.com>
+" Last Change:	2002 Sep 19
+
+" For version 5.x: Clear all syntax items
+" For version 6.x: Quit when a syntax file was already loaded
+if version < 600
+  syntax clear
+elseif exists("b:current_syntax")
+  finish
+endif
+
+syn case ignore
+
+
+" storage types
+syn match asmType "\.long"
+syn match asmType "\.ascii"
+syn match asmType "\.asciz"
+syn match asmType "\.byte"
+syn match asmType "\.double"
+syn match asmType "\.float"
+syn match asmType "\.hword"
+syn match asmType "\.int"
+syn match asmType "\.octa"
+syn match asmType "\.quad"
+syn match asmType "\.short"
+syn match asmType "\.single"
+syn match asmType "\.space"
+syn match asmType "\.string"
+syn match asmType "\.word"
+
+syn match asmLabel		"[a-z_][a-z0-9_]*:"he=e-1
+syn match asmIdentifier		"[a-z_][a-z0-9_]*"
+
+" Various #'s as defined by GAS ref manual sec 3.6.2.1
+" Technically, the first decNumber def is actually octal,
+" since the value of 0-7 octal is the same as 0-7 decimal,
+" I prefer to map it as decimal:
+syn match decNumber		"0\+[1-7]\=[\t\n$,; ]"
+syn match decNumber		"[1-9]\d*"
+syn match octNumber		"0[0-7][0-7]\+"
+syn match hexNumber		"0[xX][0-9a-fA-F]\+"
+syn match binNumber		"0[bB][0-1]*"
+
+
+syn match asmSpecialComment	";\*\*\*.*"
+syn match asmComment		";.*"hs=s+1
+
+syn match asmInclude		"\.include"
+syn match asmCond		"\.if"
+syn match asmCond		"\.else"
+syn match asmCond		"\.endif"
+syn match asmMacro		"\.macro"
+syn match asmMacro		"\.endm"
+
+syn match asmDirective		"\.[a-z][a-z]\+"
+
+
+syn case match
+
+" Define the default highlighting.
+" For version 5.7 and earlier: only when not done already
+" For version 5.8 and later: only when an item doesn't have highlighting yet
+if version >= 508 || !exists("did_asm_syntax_inits")
+  if version < 508
+    let did_asm_syntax_inits = 1
+    command -nargs=+ HiLink hi link <args>
+  else
+    command -nargs=+ HiLink hi def link <args>
+  endif
+
+  " The default methods for highlighting.  Can be overridden later
+  HiLink asmSection	Special
+  HiLink asmLabel	Label
+  HiLink asmComment	Comment
+  HiLink asmDirective	Statement
+
+  HiLink asmInclude	Include
+  HiLink asmCond	PreCondit
+  HiLink asmMacro	Macro
+
+  HiLink hexNumber	Number
+  HiLink decNumber	Number
+  HiLink octNumber	Number
+  HiLink binNumber	Number
+
+  HiLink asmSpecialComment Comment
+  HiLink asmIdentifier Identifier
+  HiLink asmType	Type
+
+  " My default color overrides:
+  " hi asmSpecialComment ctermfg=red
+  " hi asmIdentifier ctermfg=lightcyan
+  " hi asmType ctermbg=black ctermfg=brown
+
+  delcommand HiLink
+endif
+
+let b:current_syntax = "asm"
+
+" vim: ts=8
--- /dev/null
+++ b/lib/vimfiles/syntax/asm68k.vim
@@ -1,0 +1,391 @@
+" Vim syntax file
+" Language:	Motorola 68000 Assembler
+" Maintainer:	Steve Wall
+" Last change:	2001 May 01
+"
+" This is incomplete.  In particular, support for 68020 and
+" up and 68851/68881 co-processors is partial or non-existant.
+" Feel free to contribute...
+"
+
+" For version 5.x: Clear all syntax items
+" For version 6.x: Quit when a syntax file was already loaded
+if version < 600
+  syntax clear
+elseif exists("b:current_syntax")
+  finish
+endif
+
+syn case ignore
+
+" Partial list of register symbols
+syn keyword asm68kReg	a0 a1 a2 a3 a4 a5 a6 a7 d0 d1 d2 d3 d4 d5 d6 d7
+syn keyword asm68kReg	pc sr ccr sp usp ssp
+
+" MC68010
+syn keyword asm68kReg	vbr sfc sfcr dfc dfcr
+
+" MC68020
+syn keyword asm68kReg	msp isp zpc cacr caar
+syn keyword asm68kReg	za0 za1 za2 za3 za4 za5 za6 za7
+syn keyword asm68kReg	zd0 zd1 zd2 zd3 zd4 zd5 zd6 zd7
+
+" MC68030
+syn keyword asm68kReg	crp srp tc ac0 ac1 acusr tt0 tt1 mmusr
+
+" MC68040
+syn keyword asm68kReg	dtt0 dtt1 itt0 itt1 urp
+
+" MC68851 registers
+syn keyword asm68kReg	cal val scc crp srp drp tc ac psr pcsr
+syn keyword asm68kReg	bac0 bac1 bac2 bac3 bac4 bac5 bac6 bac7
+syn keyword asm68kReg	bad0 bad1 bad2 bad3 bad4 bad5 bad6 bad7
+
+" MC68881/82 registers
+syn keyword asm68kReg	fp0 fp1 fp2 fp3 fp4 fp5 fp6 fp7
+syn keyword asm68kReg	control status iaddr fpcr fpsr fpiar
+
+" M68000 opcodes - order is important!
+syn match asm68kOpcode "\<abcd\(\.b\)\=\s"
+syn match asm68kOpcode "\<adda\(\.[wl]\)\=\s"
+syn match asm68kOpcode "\<addi\(\.[bwl]\)\=\s"
+syn match asm68kOpcode "\<addq\(\.[bwl]\)\=\s"
+syn match asm68kOpcode "\<addx\(\.[bwl]\)\=\s"
+syn match asm68kOpcode "\<add\(\.[bwl]\)\=\s"
+syn match asm68kOpcode "\<andi\(\.[bwl]\)\=\s"
+syn match asm68kOpcode "\<and\(\.[bwl]\)\=\s"
+syn match asm68kOpcode "\<as[lr]\(\.[bwl]\)\=\s"
+syn match asm68kOpcode "\<b[vc][cs]\(\.[bwls]\)\=\s"
+syn match asm68kOpcode "\<beq\(\.[bwls]\)\=\s"
+syn match asm68kOpcode "\<bg[et]\(\.[bwls]\)\=\s"
+syn match asm68kOpcode "\<b[hm]i\(\.[bwls]\)\=\s"
+syn match asm68kOpcode "\<bl[est]\(\.[bwls]\)\=\s"
+syn match asm68kOpcode "\<bne\(\.[bwls]\)\=\s"
+syn match asm68kOpcode "\<bpl\(\.[bwls]\)\=\s"
+syn match asm68kOpcode "\<bchg\(\.[bl]\)\=\s"
+syn match asm68kOpcode "\<bclr\(\.[bl]\)\=\s"
+syn match asm68kOpcode "\<bfchg\s"
+syn match asm68kOpcode "\<bfclr\s"
+syn match asm68kOpcode "\<bfexts\s"
+syn match asm68kOpcode "\<bfextu\s"
+syn match asm68kOpcode "\<bfffo\s"
+syn match asm68kOpcode "\<bfins\s"
+syn match asm68kOpcode "\<bfset\s"
+syn match asm68kOpcode "\<bftst\s"
+syn match asm68kOpcode "\<bkpt\s"
+syn match asm68kOpcode "\<bra\(\.[bwls]\)\=\s"
+syn match asm68kOpcode "\<bset\(\.[bl]\)\=\s"
+syn match asm68kOpcode "\<bsr\(\.[bwl]\)\=\s"
+syn match asm68kOpcode "\<btst\(\.[bl]\)\=\s"
+syn match asm68kOpcode "\<callm\s"
+syn match asm68kOpcode "\<cas2\(\.[wl]\)\=\s"
+syn match asm68kOpcode "\<cas\(\.[bwl]\)\=\s"
+syn match asm68kOpcode "\<chk2\(\.[bwl]\)\=\s"
+syn match asm68kOpcode "\<chk\(\.[wl]\)\=\s"
+syn match asm68kOpcode "\<clr\(\.[bwl]\)\=\s"
+syn match asm68kOpcode "\<cmpa\(\.[wl]\)\=\s"
+syn match asm68kOpcode "\<cmpi\(\.[bwl]\)\=\s"
+syn match asm68kOpcode "\<cmpm\(\.[bwl]\)\=\s"
+syn match asm68kOpcode "\<cmp2\(\.[bwl]\)\=\s"
+syn match asm68kOpcode "\<cmp\(\.[bwl]\)\=\s"
+syn match asm68kOpcode "\<db[cv][cs]\(\.w\)\=\s"
+syn match asm68kOpcode "\<dbeq\(\.w\)\=\s"
+syn match asm68kOpcode "\<db[ft]\(\.w\)\=\s"
+syn match asm68kOpcode "\<dbg[et]\(\.w\)\=\s"
+syn match asm68kOpcode "\<db[hm]i\(\.w\)\=\s"
+syn match asm68kOpcode "\<dbl[est]\(\.w\)\=\s"
+syn match asm68kOpcode "\<dbne\(\.w\)\=\s"
+syn match asm68kOpcode "\<dbpl\(\.w\)\=\s"
+syn match asm68kOpcode "\<dbra\(\.w\)\=\s"
+syn match asm68kOpcode "\<div[su]\(\.[wl]\)\=\s"
+syn match asm68kOpcode "\<div[su]l\(\.l\)\=\s"
+syn match asm68kOpcode "\<eori\(\.[bwl]\)\=\s"
+syn match asm68kOpcode "\<eor\(\.[bwl]\)\=\s"
+syn match asm68kOpcode "\<exg\(\.l\)\=\s"
+syn match asm68kOpcode "\<extb\(\.l\)\=\s"
+syn match asm68kOpcode "\<ext\(\.[wl]\)\=\s"
+syn match asm68kOpcode "\<illegal\>"
+syn match asm68kOpcode "\<jmp\(\.[ls]\)\=\s"
+syn match asm68kOpcode "\<jsr\(\.[ls]\)\=\s"
+syn match asm68kOpcode "\<lea\(\.l\)\=\s"
+syn match asm68kOpcode "\<link\(\.[wl]\)\=\s"
+syn match asm68kOpcode "\<ls[lr]\(\.[bwl]\)\=\s"
+syn match asm68kOpcode "\<movea\(\.[wl]\)\=\s"
+syn match asm68kOpcode "\<movec\(\.l\)\=\s"
+syn match asm68kOpcode "\<movem\(\.[wl]\)\=\s"
+syn match asm68kOpcode "\<movep\(\.[wl]\)\=\s"
+syn match asm68kOpcode "\<moveq\(\.l\)\=\s"
+syn match asm68kOpcode "\<moves\(\.[bwl]\)\=\s"
+syn match asm68kOpcode "\<move\(\.[bwl]\)\=\s"
+syn match asm68kOpcode "\<mul[su]\(\.[wl]\)\=\s"
+syn match asm68kOpcode "\<nbcd\(\.b\)\=\s"
+syn match asm68kOpcode "\<negx\(\.[bwl]\)\=\s"
+syn match asm68kOpcode "\<neg\(\.[bwl]\)\=\s"
+syn match asm68kOpcode "\<nop\>"
+syn match asm68kOpcode "\<not\(\.[bwl]\)\=\s"
+syn match asm68kOpcode "\<ori\(\.[bwl]\)\=\s"
+syn match asm68kOpcode "\<or\(\.[bwl]\)\=\s"
+syn match asm68kOpcode "\<pack\s"
+syn match asm68kOpcode "\<pea\(\.l\)\=\s"
+syn match asm68kOpcode "\<reset\>"
+syn match asm68kOpcode "\<ro[lr]\(\.[bwl]\)\=\s"
+syn match asm68kOpcode "\<rox[lr]\(\.[bwl]\)\=\s"
+syn match asm68kOpcode "\<rt[dm]\s"
+syn match asm68kOpcode "\<rt[ers]\>"
+syn match asm68kOpcode "\<sbcd\(\.b\)\=\s"
+syn match asm68kOpcode "\<s[cv][cs]\(\.b\)\=\s"
+syn match asm68kOpcode "\<seq\(\.b\)\=\s"
+syn match asm68kOpcode "\<s[ft]\(\.b\)\=\s"
+syn match asm68kOpcode "\<sg[et]\(\.b\)\=\s"
+syn match asm68kOpcode "\<s[hm]i\(\.b\)\=\s"
+syn match asm68kOpcode "\<sl[est]\(\.b\)\=\s"
+syn match asm68kOpcode "\<sne\(\.b\)\=\s"
+syn match asm68kOpcode "\<spl\(\.b\)\=\s"
+syn match asm68kOpcode "\<suba\(\.[wl]\)\=\s"
+syn match asm68kOpcode "\<subi\(\.[bwl]\)\=\s"
+syn match asm68kOpcode "\<subq\(\.[bwl]\)\=\s"
+syn match asm68kOpcode "\<subx\(\.[bwl]\)\=\s"
+syn match asm68kOpcode "\<sub\(\.[bwl]\)\=\s"
+syn match asm68kOpcode "\<swap\(\.w\)\=\s"
+syn match asm68kOpcode "\<tas\(\.b\)\=\s"
+syn match asm68kOpcode "\<tdiv[su]\(\.l\)\=\s"
+syn match asm68kOpcode "\<t\(rap\)\=[cv][cs]\(\.[wl]\)\=\s"
+syn match asm68kOpcode "\<t\(rap\)\=eq\(\.[wl]\)\=\s"
+syn match asm68kOpcode "\<t\(rap\)\=[ft]\(\.[wl]\)\=\s"
+syn match asm68kOpcode "\<t\(rap\)\=g[et]\(\.[wl]\)\=\s"
+syn match asm68kOpcode "\<t\(rap\)\=[hm]i\(\.[wl]\)\=\s"
+syn match asm68kOpcode "\<t\(rap\)\=l[est]\(\.[wl]\)\=\s"
+syn match asm68kOpcode "\<t\(rap\)\=ne\(\.[wl]\)\=\s"
+syn match asm68kOpcode "\<t\(rap\)\=pl\(\.[wl]\)\=\s"
+syn match asm68kOpcode "\<t\(rap\)\=v\>"
+syn match asm68kOpcode "\<t\(rap\)\=[cv][cs]\>"
+syn match asm68kOpcode "\<t\(rap\)\=eq\>"
+syn match asm68kOpcode "\<t\(rap\)\=[ft]\>"
+syn match asm68kOpcode "\<t\(rap\)\=g[et]\>"
+syn match asm68kOpcode "\<t\(rap\)\=[hm]i\>"
+syn match asm68kOpcode "\<t\(rap\)\=l[est]\>"
+syn match asm68kOpcode "\<t\(rap\)\=ne\>"
+syn match asm68kOpcode "\<t\(rap\)\=pl\>"
+syn match asm68kOpcode "\<trap\s"
+syn match asm68kOpcode "\<tst\(\.[bwl]\)\=\s"
+syn match asm68kOpcode "\<unlk\s"
+syn match asm68kOpcode "\<unpk\s"
+
+" Valid labels
+syn match asm68kLabel		"^[a-z_?.][a-z0-9_?.$]*$"
+syn match asm68kLabel		"^[a-z_?.][a-z0-9_?.$]*\s"he=e-1
+syn match asm68kLabel		"^\s*[a-z_?.][a-z0-9_?.$]*:"he=e-1
+
+" Various number formats
+syn match hexNumber		"\$[0-9a-fA-F]\+\>"
+syn match hexNumber		"\<[0-9][0-9a-fA-F]*H\>"
+syn match octNumber		"@[0-7]\+\>"
+syn match octNumber		"\<[0-7]\+[QO]\>"
+syn match binNumber		"%[01]\+\>"
+syn match binNumber		"\<[01]\+B\>"
+syn match decNumber		"\<[0-9]\+D\=\>"
+syn match floatE		"_*E_*" contained
+syn match floatExponent		"_*E_*[-+]\=[0-9]\+" contained contains=floatE
+syn match floatNumber		"[-+]\=[0-9]\+_*E_*[-+]\=[0-9]\+" contains=floatExponent
+syn match floatNumber		"[-+]\=[0-9]\+\.[0-9]\+\(E[-+]\=[0-9]\+\)\=" contains=floatExponent
+syn match floatNumber		":\([0-9a-f]\+_*\)\+"
+
+" Character string constants
+syn match asm68kStringError	"'[ -~]*'"
+syn match asm68kStringError	"'[ -~]*$"
+syn region asm68kString		start="'" skip="''" end="'" oneline contains=asm68kCharError
+syn match asm68kCharError	"[^ -~]" contained
+
+" Immediate data
+syn match asm68kImmediate	"#\$[0-9a-fA-F]\+" contains=hexNumber
+syn match asm68kImmediate	"#[0-9][0-9a-fA-F]*H" contains=hexNumber
+syn match asm68kImmediate	"#@[0-7]\+" contains=octNumber
+syn match asm68kImmediate	"#[0-7]\+[QO]" contains=octNumber
+syn match asm68kImmediate	"#%[01]\+" contains=binNumber
+syn match asm68kImmediate	"#[01]\+B" contains=binNumber
+syn match asm68kImmediate	"#[0-9]\+D\=" contains=decNumber
+syn match asm68kSymbol		"[a-z_?.][a-z0-9_?.$]*" contained
+syn match asm68kImmediate	"#[a-z_?.][a-z0-9_?.]*" contains=asm68kSymbol
+
+" Special items for comments
+syn keyword asm68kTodo		contained TODO
+
+" Operators
+syn match asm68kOperator	"[-+*/]"	" Must occur before Comments
+syn match asm68kOperator	"\.SIZEOF\."
+syn match asm68kOperator	"\.STARTOF\."
+syn match asm68kOperator	"<<"		" shift left
+syn match asm68kOperator	">>"		" shift right
+syn match asm68kOperator	"&"		" bit-wise logical and
+syn match asm68kOperator	"!"		" bit-wise logical or
+syn match asm68kOperator	"!!"		" exclusive or
+syn match asm68kOperator	"<>"		" inequality
+syn match asm68kOperator	"="		" must be before other ops containing '='
+syn match asm68kOperator	">="
+syn match asm68kOperator	"<="
+syn match asm68kOperator	"=="		" operand existance - used in macro definitions
+
+" Condition code style operators
+syn match asm68kOperator	"<[CV][CS]>"
+syn match asm68kOperator	"<EQ>"
+syn match asm68kOperator	"<G[TE]>"
+syn match asm68kOperator	"<[HM]I>"
+syn match asm68kOperator	"<L[SET]>"
+syn match asm68kOperator	"<NE>"
+syn match asm68kOperator	"<PL>"
+
+" Comments
+syn match asm68kComment		";.*" contains=asm68kTodo
+syn match asm68kComment		"\s!.*"ms=s+1 contains=asm68kTodo
+syn match asm68kComment		"^\s*[*!].*" contains=asm68kTodo
+
+" Include
+syn match asm68kInclude		"\<INCLUDE\s"
+
+" Standard macros
+syn match asm68kCond		"\<IF\(\.[BWL]\)\=\s"
+syn match asm68kCond		"\<THEN\(\.[SL]\)\=\>"
+syn match asm68kCond		"\<ELSE\(\.[SL]\)\=\>"
+syn match asm68kCond		"\<ENDI\>"
+syn match asm68kCond		"\<BREAK\(\.[SL]\)\=\>"
+syn match asm68kRepeat		"\<FOR\(\.[BWL]\)\=\s"
+syn match asm68kRepeat		"\<DOWNTO\s"
+syn match asm68kRepeat		"\<TO\s"
+syn match asm68kRepeat		"\<BY\s"
+syn match asm68kRepeat		"\<DO\(\.[SL]\)\=\>"
+syn match asm68kRepeat		"\<ENDF\>"
+syn match asm68kRepeat		"\<NEXT\(\.[SL]\)\=\>"
+syn match asm68kRepeat		"\<REPEAT\>"
+syn match asm68kRepeat		"\<UNTIL\(\.[BWL]\)\=\s"
+syn match asm68kRepeat		"\<WHILE\(\.[BWL]\)\=\s"
+syn match asm68kRepeat		"\<ENDW\>"
+
+" Macro definition
+syn match asm68kMacro		"\<MACRO\>"
+syn match asm68kMacro		"\<LOCAL\s"
+syn match asm68kMacro		"\<MEXIT\>"
+syn match asm68kMacro		"\<ENDM\>"
+syn match asm68kMacroParam	"\\[0-9]"
+
+" Conditional assembly
+syn match asm68kPreCond		"\<IFC\s"
+syn match asm68kPreCond		"\<IFDEF\s"
+syn match asm68kPreCond		"\<IFEQ\s"
+syn match asm68kPreCond		"\<IFGE\s"
+syn match asm68kPreCond		"\<IFGT\s"
+syn match asm68kPreCond		"\<IFLE\s"
+syn match asm68kPreCond		"\<IFLT\s"
+syn match asm68kPreCond		"\<IFNC\>"
+syn match asm68kPreCond		"\<IFNDEF\s"
+syn match asm68kPreCond		"\<IFNE\s"
+syn match asm68kPreCond		"\<ELSEC\>"
+syn match asm68kPreCond		"\<ENDC\>"
+
+" Loop control
+syn match asm68kPreCond		"\<REPT\s"
+syn match asm68kPreCond		"\<IRP\s"
+syn match asm68kPreCond		"\<IRPC\s"
+syn match asm68kPreCond		"\<ENDR\>"
+
+" Directives
+syn match asm68kDirective	"\<ALIGN\s"
+syn match asm68kDirective	"\<CHIP\s"
+syn match asm68kDirective	"\<COMLINE\s"
+syn match asm68kDirective	"\<COMMON\(\.S\)\=\s"
+syn match asm68kDirective	"\<DC\(\.[BWLSDXP]\)\=\s"
+syn match asm68kDirective	"\<DC\.\\[0-9]\s"me=e-3	" Special use in a macro def
+syn match asm68kDirective	"\<DCB\(\.[BWLSDXP]\)\=\s"
+syn match asm68kDirective	"\<DS\(\.[BWLSDXP]\)\=\s"
+syn match asm68kDirective	"\<END\>"
+syn match asm68kDirective	"\<EQU\s"
+syn match asm68kDirective	"\<FEQU\(\.[SDXP]\)\=\s"
+syn match asm68kDirective	"\<FAIL\>"
+syn match asm68kDirective	"\<FOPT\s"
+syn match asm68kDirective	"\<\(NO\)\=FORMAT\>"
+syn match asm68kDirective	"\<IDNT\>"
+syn match asm68kDirective	"\<\(NO\)\=LIST\>"
+syn match asm68kDirective	"\<LLEN\s"
+syn match asm68kDirective	"\<MASK2\>"
+syn match asm68kDirective	"\<NAME\s"
+syn match asm68kDirective	"\<NOOBJ\>"
+syn match asm68kDirective	"\<OFFSET\s"
+syn match asm68kDirective	"\<OPT\>"
+syn match asm68kDirective	"\<ORG\(\.[SL]\)\=\>"
+syn match asm68kDirective	"\<\(NO\)\=PAGE\>"
+syn match asm68kDirective	"\<PLEN\s"
+syn match asm68kDirective	"\<REG\s"
+syn match asm68kDirective	"\<RESTORE\>"
+syn match asm68kDirective	"\<SAVE\>"
+syn match asm68kDirective	"\<SECT\(\.S\)\=\s"
+syn match asm68kDirective	"\<SECTION\(\.S\)\=\s"
+syn match asm68kDirective	"\<SET\s"
+syn match asm68kDirective	"\<SPC\s"
+syn match asm68kDirective	"\<TTL\s"
+syn match asm68kDirective	"\<XCOM\s"
+syn match asm68kDirective	"\<XDEF\s"
+syn match asm68kDirective	"\<XREF\(\.S\)\=\s"
+
+syn case match
+
+" Define the default highlighting.
+" For version 5.7 and earlier: only when not done already
+" For version 5.8 and later: only when an item doesn't have highlighting yet
+if version >= 508 || !exists("did_asm68k_syntax_inits")
+  if version < 508
+    let did_asm68k_syntax_inits = 1
+    command -nargs=+ HiLink hi link <args>
+  else
+    command -nargs=+ HiLink hi def link <args>
+  endif
+
+  " The default methods for highlighting.  Can be overridden later
+  " Comment Constant Error Identifier PreProc Special Statement Todo Type
+  "
+  " Constant		Boolean Character Number String
+  " Identifier		Function
+  " PreProc		Define Include Macro PreCondit
+  " Special		Debug Delimiter SpecialChar SpecialComment Tag
+  " Statement		Conditional Exception Keyword Label Operator Repeat
+  " Type		StorageClass Structure Typedef
+
+  HiLink asm68kComment		Comment
+  HiLink asm68kTodo		Todo
+
+  HiLink hexNumber		Number		" Constant
+  HiLink octNumber		Number		" Constant
+  HiLink binNumber		Number		" Constant
+  HiLink decNumber		Number		" Constant
+  HiLink floatNumber		Number		" Constant
+  HiLink floatExponent		Number		" Constant
+  HiLink floatE			SpecialChar	" Statement
+  "HiLink floatE		Number		" Constant
+
+  HiLink asm68kImmediate	SpecialChar	" Statement
+  "HiLink asm68kSymbol		Constant
+
+  HiLink asm68kString		String		" Constant
+  HiLink asm68kCharError	Error
+  HiLink asm68kStringError	Error
+
+  HiLink asm68kReg		Identifier
+  HiLink asm68kOperator		Identifier
+
+  HiLink asm68kInclude		Include		" PreProc
+  HiLink asm68kMacro		Macro		" PreProc
+  HiLink asm68kMacroParam	Keyword		" Statement
+
+  HiLink asm68kDirective	Special
+  HiLink asm68kPreCond		Special
+
+
+  HiLink asm68kOpcode		Statement
+  HiLink asm68kCond		Conditional	" Statement
+  HiLink asm68kRepeat		Repeat		" Statement
+
+  HiLink asm68kLabel		Type
+  delcommand HiLink
+endif
+
+let b:current_syntax = "asm68k"
+
+" vim: ts=8 sw=2
--- /dev/null
+++ b/lib/vimfiles/syntax/asmh8300.vim
@@ -1,0 +1,85 @@
+" Vim syntax file
+" Language:	Hitachi H-8300h specific syntax for GNU Assembler
+" Maintainer:	Kevin Dahlhausen <kdahlhaus@yahoo.com>
+" Last Change:	2002 Sep 19
+
+" For version 5.x: Clear all syntax items
+" For version 6.x: Quit when a syntax file was already loaded
+if version < 600
+  syntax clear
+elseif exists("b:current_syntax")
+  finish
+endif
+
+syn case ignore
+
+syn match asmDirective "\.h8300[h]*"
+
+"h8300[h] registers
+syn match asmReg	"e\=r[0-7][lh]\="
+
+"h8300[h] opcodes - order is important!
+syn match asmOpcode "add\.[lbw]"
+syn match asmOpcode "add[sx :]"
+syn match asmOpcode "and\.[lbw]"
+syn match asmOpcode "bl[deots]"
+syn match asmOpcode "cmp\.[lbw]"
+syn match asmOpcode "dec\.[lbw]"
+syn match asmOpcode "divx[us].[bw]"
+syn match asmOpcode "ext[su]\.[lw]"
+syn match asmOpcode "inc\.[lw]"
+syn match asmOpcode "mov\.[lbw]"
+syn match asmOpcode "mulx[su]\.[bw]"
+syn match asmOpcode "neg\.[lbw]"
+syn match asmOpcode "not\.[lbw]"
+syn match asmOpcode "or\.[lbw]"
+syn match asmOpcode "pop\.[wl]"
+syn match asmOpcode "push\.[wl]"
+syn match asmOpcode "rotx\=[lr]\.[lbw]"
+syn match asmOpcode "sha[lr]\.[lbw]"
+syn match asmOpcode "shl[lr]\.[lbw]"
+syn match asmOpcode "sub\.[lbw]"
+syn match asmOpcode "xor\.[lbw]"
+syn keyword asmOpcode "andc" "band" "bcc" "bclr" "bcs" "beq" "bf" "bge" "bgt"
+syn keyword asmOpcode "bhi" "bhs" "biand" "bild" "bior" "bist" "bixor" "bmi"
+syn keyword asmOpcode "bne" "bnot" "bnp" "bor" "bpl" "bpt" "bra" "brn" "bset"
+syn keyword asmOpcode "bsr" "btst" "bst" "bt" "bvc" "bvs" "bxor" "cmp" "daa"
+syn keyword asmOpcode "das" "eepmov" "eepmovw" "inc" "jmp" "jsr" "ldc" "movfpe"
+syn keyword asmOpcode "movtpe" "mov" "nop" "orc" "rte" "rts" "sleep" "stc"
+syn keyword asmOpcode "sub" "trapa" "xorc"
+
+syn case match
+
+
+" Read the general asm syntax
+if version < 600
+  source <sfile>:p:h/asm.vim
+else
+  runtime! syntax/asm.vim
+endif
+
+
+" Define the default highlighting.
+" For version 5.7 and earlier: only when not done already
+" For version 5.8 and later: only when an item doesn't have highlighting yet
+if version >= 508 || !exists("did_hitachi_syntax_inits")
+  if version < 508
+    let did_hitachi_syntax_inits = 1
+    command -nargs=+ HiLink hi link <args>
+  else
+    command -nargs=+ HiLink hi def link <args>
+  endif
+
+  HiLink asmOpcode  Statement
+  HiLink asmRegister  Identifier
+
+  " My default-color overrides:
+  "hi asmOpcode ctermfg=yellow
+  "hi asmReg	ctermfg=lightmagenta
+
+  delcommand HiLink
+endif
+
+let b:current_syntax = "asmh8300"
+
+" vim: ts=8
--- /dev/null
+++ b/lib/vimfiles/syntax/asn.vim
@@ -1,0 +1,81 @@
+" Vim syntax file
+" Language:	ASN.1
+" Maintainer:	Claudio Fleiner <claudio@fleiner.com>
+" URL:		http://www.fleiner.com/vim/syntax/asn.vim
+" Last Change:	2001 Apr 26
+
+" For version 5.x: Clear all syntax items
+" For version 6.x: Quit when a syntax file was already loaded
+if version < 600
+  syntax clear
+elseif exists("b:current_syntax")
+  finish
+endif
+
+" keyword definitions
+syn keyword asnExternal		DEFINITIONS BEGIN END IMPORTS EXPORTS FROM
+syn match   asnExternal		"\<IMPLICIT\s\+TAGS\>"
+syn match   asnExternal		"\<EXPLICIT\s\+TAGS\>"
+syn keyword asnFieldOption	DEFAULT OPTIONAL
+syn keyword asnTagModifier	IMPLICIT EXPLICIT
+syn keyword asnTypeInfo		ABSENT PRESENT SIZE UNIVERSAL APPLICATION PRIVATE
+syn keyword asnBoolValue	TRUE FALSE
+syn keyword asnNumber		MIN MAX
+syn match   asnNumber		"\<PLUS-INFINITY\>"
+syn match   asnNumber		"\<MINUS-INFINITY\>"
+syn keyword asnType		INTEGER REAL STRING BIT BOOLEAN OCTET NULL EMBEDDED PDV
+syn keyword asnType		BMPString IA5String TeletexString GeneralString GraphicString ISO646String NumericString PrintableString T61String UniversalString VideotexString VisibleString
+syn keyword asnType		ANY DEFINED
+syn match   asnType		"\.\.\."
+syn match   asnType		"OBJECT\s\+IDENTIFIER"
+syn match   asnType		"TYPE-IDENTIFIER"
+syn keyword asnType		UTF8String
+syn keyword asnStructure	CHOICE SEQUENCE SET OF ENUMERATED CONSTRAINED BY WITH COMPONENTS CLASS
+
+" Strings and constants
+syn match   asnSpecial		contained "\\\d\d\d\|\\."
+syn region  asnString		start=+"+  skip=+\\\\\|\\"+  end=+"+  contains=asnSpecial
+syn match   asnCharacter	"'[^\\]'"
+syn match   asnSpecialCharacter "'\\.'"
+syn match   asnNumber		"-\=\<\d\+L\=\>\|0[xX][0-9a-fA-F]\+\>"
+syn match   asnLineComment	"--.*"
+syn match   asnLineComment	"--.*--"
+
+syn match asnDefinition "^\s*[a-zA-Z][-a-zA-Z0-9_.\[\] \t{}]* *::="me=e-3 contains=asnType
+syn match asnBraces     "[{}]"
+
+syn sync ccomment asnComment
+
+" Define the default highlighting.
+" For version 5.7 and earlier: only when not done already
+" For version 5.8 and later: only when an item doesn't have highlighting yet
+if version >= 508 || !exists("did_asn_syn_inits")
+  if version < 508
+    let did_asn_syn_inits = 1
+    command -nargs=+ HiLink hi link <args>
+  else
+    command -nargs=+ HiLink hi def link <args>
+  endif
+  HiLink asnDefinition	Function
+  HiLink asnBraces		Function
+  HiLink asnStructure	Statement
+  HiLink asnBoolValue	Boolean
+  HiLink asnSpecial		Special
+  HiLink asnString		String
+  HiLink asnCharacter	Character
+  HiLink asnSpecialCharacter	asnSpecial
+  HiLink asnNumber		asnValue
+  HiLink asnComment		Comment
+  HiLink asnLineComment	asnComment
+  HiLink asnType		Type
+  HiLink asnTypeInfo		PreProc
+  HiLink asnValue		Number
+  HiLink asnExternal		Include
+  HiLink asnTagModifier	Function
+  HiLink asnFieldOption	Type
+  delcommand HiLink
+endif
+
+let b:current_syntax = "asn"
+
+" vim: ts=8
--- /dev/null
+++ b/lib/vimfiles/syntax/aspperl.vim
@@ -1,0 +1,33 @@
+" Vim syntax file
+" Language:	Active State's PerlScript (ASP)
+" Maintainer:	Aaron Hope <edh@brioforge.com>
+" URL:		http://nim.dhs.org/~edh/aspperl.vim
+" Last Change:	2001 May 09
+
+" For version 5.x: Clear all syntax items
+" For version 6.x: Quit when a syntax file was already loaded
+if version < 600
+  syntax clear
+elseif exists("b:current_syntax")
+  finish
+endif
+
+if !exists("main_syntax")
+  let main_syntax = 'perlscript'
+endif
+
+if version < 600
+  so <sfile>:p:h/html.vim
+  syn include @AspPerlScript <sfile>:p:h/perl.vim
+else
+  runtime! syntax/html.vim
+  unlet b:current_syntax
+  syn include @AspPerlScript syntax/perl.vim
+endif
+
+syn cluster htmlPreproc add=AspPerlScriptInsideHtmlTags
+
+syn region  AspPerlScriptInsideHtmlTags keepend matchgroup=Delimiter start=+<%=\=+ skip=+".*%>.*"+ end=+%>+ contains=@AspPerlScript
+syn region  AspPerlScriptInsideHtmlTags keepend matchgroup=Delimiter start=+<script\s\+language="\=perlscript"\=[^>]*>+ end=+</script>+ contains=@AspPerlScript
+
+let b:current_syntax = "aspperl"
--- /dev/null
+++ b/lib/vimfiles/syntax/aspvbs.vim
@@ -1,0 +1,198 @@
+" Vim syntax file
+" Language:	Microsoft VBScript Web Content (ASP)
+" Maintainer:	Devin Weaver <ktohg@tritarget.com> (non-functional)
+" URL:		http://tritarget.com/pub/vim/syntax/aspvbs.vim (broken)
+" Last Change:	2006 Jun 19
+" 		by Dan Casey
+" Version:	$Revision: 1.3 $
+" Thanks to Jay-Jay <vim@jay-jay.net> for a syntax sync hack, hungarian
+" notation, and extra highlighting.
+" Thanks to patrick dehne <patrick@steidle.net> for the folding code.
+" Thanks to Dean Hall <hall@apt7.com> for testing the use of classes in
+" VBScripts which I've been too scared to do.
+
+" Quit when a syntax file was already loaded
+if version < 600
+  syn clear
+elseif exists("b:current_syntax")
+  finish
+endif
+
+if !exists("main_syntax")
+  let main_syntax = 'aspvbs'
+endif
+
+if version < 600
+  source <sfile>:p:h/html.vim
+else
+  runtime! syntax/html.vim
+endif
+unlet b:current_syntax
+
+syn cluster htmlPreProc add=AspVBScriptInsideHtmlTags
+
+
+" Colored variable names, if written in hungarian notation
+hi def AspVBSVariableSimple   term=standout  ctermfg=3  guifg=#99ee99
+hi def AspVBSVariableComplex  term=standout  ctermfg=3  guifg=#ee9900
+syn match AspVBSVariableSimple  contained "\<\(bln\|byt\|dtm\=\|dbl\|int\|str\)\u\w*"
+syn match AspVBSVariableComplex contained "\<\(arr\|ary\|obj\)\u\w*"
+
+
+" Functions and methods that are in VB but will cause errors in an ASP page
+" This is helpfull if your porting VB code to ASP
+" I removed (Count, Item) because these are common variable names in AspVBScript
+syn keyword AspVBSError contained Val Str CVar CVDate DoEvents GoSub Return GoTo
+syn keyword AspVBSError contained Stop LinkExecute Add Type LinkPoke
+syn keyword AspVBSError contained LinkRequest LinkSend Declare Optional Sleep
+syn keyword AspVBSError contained ParamArray Static Erl TypeOf Like LSet RSet Mid StrConv
+" It may seem that most of these can fit into a keyword clause but keyword takes
+" priority over all so I can't get the multi-word matches
+syn match AspVBSError contained "\<Def[a-zA-Z0-9_]\+\>"
+syn match AspVBSError contained "^\s*Open\s\+"
+syn match AspVBSError contained "Debug\.[a-zA-Z0-9_]*"
+syn match AspVBSError contained "^\s*[a-zA-Z0-9_]\+:"
+syn match AspVBSError contained "[a-zA-Z0-9_]\+![a-zA-Z0-9_]\+"
+syn match AspVBSError contained "^\s*#.*$"
+syn match AspVBSError contained "\<As\s\+[a-zA-Z0-9_]*"
+syn match AspVBSError contained "\<End\>\|\<Exit\>"
+syn match AspVBSError contained "\<On\s\+Error\>\|\<On\>\|\<Error\>\|\<Resume\s\+Next\>\|\<Resume\>"
+syn match AspVBSError contained "\<Option\s\+\(Base\|Compare\|Private\s\+Module\)\>"
+" This one I want 'cause I always seem to mis-spell it.
+syn match AspVBSError contained "Respon\?ce\.\S*"
+syn match AspVBSError contained "Respose\.\S*"
+" When I looked up the VBScript syntax it mentioned that Property Get/Set/Let
+" statements are illegal, however, I have recived reports that they do work.
+" So I commented it out for now.
+" syn match AspVBSError contained "\<Property\s\+\(Get\|Let\|Set\)\>"
+
+" AspVBScript Reserved Words.
+syn match AspVBSStatement contained "\<On\s\+Error\s\+\(Resume\s\+Next\|goto\s\+0\)\>\|\<Next\>"
+syn match AspVBSStatement contained "\<End\s\+\(If\|For\|Select\|Class\|Function\|Sub\|With\|Property\)\>"
+syn match AspVBSStatement contained "\<Exit\s\+\(Do\|For\|Sub\|Function\)\>"
+syn match AspVBSStatement contained "\<Exit\s\+\(Do\|For\|Sub\|Function\|Property\)\>"
+syn match AspVBSStatement contained "\<Option\s\+Explicit\>"
+syn match AspVBSStatement contained "\<For\s\+Each\>\|\<For\>"
+syn match AspVBSStatement contained "\<Set\>"
+syn keyword AspVBSStatement contained Call Class Const Default Dim Do Loop Erase And
+syn keyword AspVBSStatement contained Function If Then Else ElseIf Or
+syn keyword AspVBSStatement contained Private Public Randomize ReDim
+syn keyword AspVBSStatement contained Select Case Sub While With Wend Not
+
+" AspVBScript Functions
+syn keyword AspVBSFunction contained Abs Array Asc Atn CBool CByte CCur CDate CDbl
+syn keyword AspVBSFunction contained Chr CInt CLng Cos CreateObject CSng CStr Date
+syn keyword AspVBSFunction contained DateAdd DateDiff DatePart DateSerial DateValue
+syn keyword AspVBSFunction contained Date Day Exp Filter Fix FormatCurrency
+syn keyword AspVBSFunction contained FormatDateTime FormatNumber FormatPercent
+syn keyword AspVBSFunction contained GetObject Hex Hour InputBox InStr InStrRev Int
+syn keyword AspVBSFunction contained IsArray IsDate IsEmpty IsNull IsNumeric
+syn keyword AspVBSFunction contained IsObject Join LBound LCase Left Len LoadPicture
+syn keyword AspVBSFunction contained Log LTrim Mid Minute Month MonthName MsgBox Now
+syn keyword AspVBSFunction contained Oct Replace RGB Right Rnd Round RTrim
+syn keyword AspVBSFunction contained ScriptEngine ScriptEngineBuildVersion
+syn keyword AspVBSFunction contained ScriptEngineMajorVersion
+syn keyword AspVBSFunction contained ScriptEngineMinorVersion Second Sgn Sin Space
+syn keyword AspVBSFunction contained Split Sqr StrComp StrReverse String Tan Time Timer
+syn keyword AspVBSFunction contained TimeSerial TimeValue Trim TypeName UBound UCase
+syn keyword AspVBSFunction contained VarType Weekday WeekdayName Year
+
+" AspVBScript Methods
+syn keyword AspVBSMethods contained Add AddFolders BuildPath Clear Close Copy
+syn keyword AspVBSMethods contained CopyFile CopyFolder CreateFolder CreateTextFile
+syn keyword AspVBSMethods contained Delete DeleteFile DeleteFolder DriveExists
+syn keyword AspVBSMethods contained Exists FileExists FolderExists
+syn keyword AspVBSMethods contained GetAbsolutePathName GetBaseName GetDrive
+syn keyword AspVBSMethods contained GetDriveName GetExtensionName GetFile
+syn keyword AspVBSMethods contained GetFileName GetFolder GetParentFolderName
+syn keyword AspVBSMethods contained GetSpecialFolder GetTempName Items Keys Move
+syn keyword AspVBSMethods contained MoveFile MoveFolder OpenAsTextStream
+syn keyword AspVBSMethods contained OpenTextFile Raise Read ReadAll ReadLine Remove
+syn keyword AspVBSMethods contained RemoveAll Skip SkipLine Write WriteBlankLines
+syn keyword AspVBSMethods contained WriteLine
+syn match AspVBSMethods contained "Response\.\w*"
+" Colorize boolean constants:
+syn keyword AspVBSMethods contained true false
+
+" AspVBScript Number Contstants
+" Integer number, or floating point number without a dot.
+syn match  AspVBSNumber	contained	"\<\d\+\>"
+" Floating point number, with dot
+syn match  AspVBSNumber	contained	"\<\d\+\.\d*\>"
+" Floating point number, starting with a dot
+syn match  AspVBSNumber	contained	"\.\d\+\>"
+
+" String and Character Contstants
+" removed (skip=+\\\\\|\\"+) because VB doesn't have backslash escaping in
+" strings (or does it?)
+syn region  AspVBSString	contained	  start=+"+  end=+"+ keepend
+
+" AspVBScript Comments
+syn region  AspVBSComment	contained start="^REM\s\|\sREM\s" end="$" contains=AspVBSTodo keepend
+syn region  AspVBSComment   contained start="^'\|\s'"   end="$" contains=AspVBSTodo keepend
+" misc. Commenting Stuff
+syn keyword AspVBSTodo contained	TODO FIXME
+
+" Cosmetic syntax errors commanly found in VB but not in AspVBScript
+" AspVBScript doesn't use line numbers
+syn region  AspVBSError	contained start="^\d" end="\s" keepend
+" AspVBScript also doesn't have type defining variables
+syn match   AspVBSError  contained "[a-zA-Z0-9_][\$&!#]"ms=s+1
+" Since 'a%' is a VB variable with a type and in AspVBScript you can have 'a%>'
+" I have to make a special case so 'a%>' won't show as an error.
+syn match   AspVBSError  contained "[a-zA-Z0-9_]%\($\|[^>]\)"ms=s+1
+
+" Top Cluster
+syn cluster AspVBScriptTop contains=AspVBSStatement,AspVBSFunction,AspVBSMethods,AspVBSNumber,AspVBSString,AspVBSComment,AspVBSError,AspVBSVariableSimple,AspVBSVariableComplex
+
+" Folding
+syn region AspVBSFold start="^\s*\(class\)\s\+.*$" end="^\s*end\s\+\(class\)\>.*$" fold contained transparent keepend
+syn region AspVBSFold start="^\s*\(private\|public\)\=\(\s\+default\)\=\s\+\(sub\|function\)\s\+.*$" end="^\s*end\s\+\(function\|sub\)\>.*$" fold contained transparent keepend
+
+" Define AspVBScript delimeters
+" <%= func("string_with_%>_in_it") %> This is illegal in ASP syntax.
+syn region  AspVBScriptInsideHtmlTags keepend matchgroup=Delimiter start=+<%=\=+ end=+%>+ contains=@AspVBScriptTop, AspVBSFold
+syn region  AspVBScriptInsideHtmlTags keepend matchgroup=Delimiter start=+<script\s\+language="\=vbscript"\=[^>]*\s\+runatserver[^>]*>+ end=+</script>+ contains=@AspVBScriptTop
+
+
+" Synchronization
+" syn sync match AspVBSSyncGroup grouphere AspVBScriptInsideHtmlTags "<%"
+" This is a kludge so the HTML will sync properly
+syn sync match htmlHighlight grouphere htmlTag "%>"
+
+
+
+" Define the default highlighting.
+" For version 5.7 and earlier: only when not done already
+" For version 5.8 and later: only when an item doesn't have highlighting yet
+if version >= 508 || !exists("did_aspvbs_syn_inits")
+  if version < 508
+    let did_aspvbs_syn_inits = 1
+    command -nargs=+ HiLink hi link <args>
+  else
+    command -nargs=+ HiLink hi def link <args>
+  endif
+
+  "HiLink AspVBScript		Special
+  HiLink AspVBSLineNumber	Comment
+  HiLink AspVBSNumber		Number
+  HiLink AspVBSError		Error
+  HiLink AspVBSStatement	Statement
+  HiLink AspVBSString		String
+  HiLink AspVBSComment		Comment
+  HiLink AspVBSTodo		Todo
+  HiLink AspVBSFunction		Identifier
+  HiLink AspVBSMethods		PreProc
+  HiLink AspVBSEvents		Special
+  HiLink AspVBSTypeSpecifier	Type
+
+  delcommand HiLink
+endif
+
+let b:current_syntax = "aspvbs"
+
+if main_syntax == 'aspvbs'
+  unlet main_syntax
+endif
+
+" vim: ts=8:sw=2:sts=0:noet
--- /dev/null
+++ b/lib/vimfiles/syntax/asterisk.vim
@@ -1,0 +1,96 @@
+" Vim syntax file
+" Language:	Asterisk config file
+" Maintainer:	brc007 
+" Updated for 1.2 by Tilghman Lesher (Corydon76)
+" Last Change:	2006 Mar 20 
+" version 0.4
+"
+if version < 600
+  syntax clear
+elseif exists("b:current_syntax")
+  finish
+endif
+
+syn sync clear
+syn sync fromstart
+
+syn keyword     asteriskTodo    TODO contained
+syn match       asteriskComment         ";.*" contains=asteriskTodo
+syn match       asteriskContext         "\[.\{-}\]"
+syn match       asteriskExten           "^\s*exten\s*=>\?\s*[^,]\+" contains=asteriskPattern
+syn match       asteriskExten           "^\s*\(register\|channel\|ignorepat\|include\|\(no\)\?load\)\s*=>\?"
+syn match       asteriskPattern         "_\(\[[[:alnum:]#*\-]\+\]\|[[:alnum:]#*]\)*\.\?" contained
+syn match       asteriskPattern         "[^A-Za-z0-9,]\zs[[:alnum:]#*]\+\ze" contained
+syn match       asteriskApp             ",\zs[a-zA-Z]\+\ze$"
+syn match       asteriskApp             ",\zs[a-zA-Z]\+\ze("
+" Digits plus oldlabel (newlabel)
+syn match       asteriskPriority        ",\zs[[:digit:]]\+\(+[[:alpha:]][[:alnum:]_]*\)\?\(([[:alpha:]][[:alnum:]_]*)\)\?\ze," contains=asteriskLabel
+" oldlabel plus digits (newlabel)
+syn match       asteriskPriority        ",\zs[[:alpha:]][[:alnum:]_]*+[[:digit:]]\+\(([[:alpha:]][[:alnum:]_]*)\)\?\ze," contains=asteriskLabel
+" s or n plus digits (newlabel)
+syn match       asteriskPriority        ",\zs[sn]\(+[[:digit:]]\+\)\?\(([[:alpha:]][[:alnum:]_]*)\)\?\ze," contains=asteriskLabel
+syn match       asteriskLabel           "(\zs[[:alpha:]][[:alnum:]]*\ze)" contained
+syn match       asteriskError           "^\s*#\s*[[:alnum:]]*"
+syn match       asteriskInclude         "^\s*#\s*\(include\|exec\)\s.*"
+syn match       asteriskVar             "\${_\{0,2}[[:alpha:]][[:alnum:]_]*\(:-\?[[:digit:]]\+\(:[[:digit:]]\+\)\?\)\?}"
+syn match       asteriskVar             "_\{0,2}[[:alpha:]][[:alnum:]_]*\ze="
+syn match       asteriskVarLen          "\${_\{0,2}[[:alpha:]][[:alnum:]_]*(.*)}" contains=asteriskVar,asteriskVarLen,asteriskExp
+syn match       asteriskVarLen          "(\zs[[:alpha:]][[:alnum:]_]*(.\{-})\ze=" contains=asteriskVar,asteriskVarLen,asteriskExp
+syn match       asteriskExp             "\$\[.\{-}\]" contains=asteriskVar,asteriskVarLen,asteriskExp
+syn match       asteriskCodecsPermit    "^\s*\(allow\|disallow\)\s*=\s*.*$" contains=asteriskCodecs
+syn match       asteriskCodecs          "\(g723\|gsm\|ulaw\|alaw\|g726\|adpcm\|slin\|lpc10\|g729\|speex\|ilbc\|all\s*$\)"
+syn match       asteriskError           "^\(type\|auth\|permit\|deny\|bindaddr\|host\)\s*=.*$"
+syn match       asteriskType            "^\zstype=\ze\<\(peer\|user\|friend\)\>$" contains=asteriskTypeType
+syn match       asteriskTypeType        "\<\(peer\|user\|friend\)\>" contained
+syn match       asteriskAuth            "^\zsauth\s*=\ze\s*\<\(md5\|rsa\|plaintext\)\>$" contains=asteriskAuthType
+syn match       asteriskAuthType        "\<\(md5\|rsa\|plaintext\)\>"
+syn match       asteriskAuth            "^\zs\(secret\|inkeys\|outkey\)\s*=\ze.*$"
+syn match       asteriskAuth            "^\(permit\|deny\)\s*=\s*\d\{1,3}\.\d\{1,3}\.\d\{1,3}\.\d\{1,3}/\d\{1,3}\.\d\{1,3}\.\d\{1,3}\.\d\{1,3}\s*$" contains=asteriskIPRange
+syn match       asteriskIPRange         "\d\{1,3}\.\d\{1,3}\.\d\{1,3}\.\d\{1,3}/\d\{1,3}\.\d\{1,3}\.\d\{1,3}\.\d\{1,3}" contained
+syn match       asteriskIP              "\d\{1,3}\.\d\{1,3}\.\d\{1,3}\.\d\{1,3}" contained
+syn match       asteriskHostname        "[[:alnum:]][[:alnum:]\-\.]*\.[[:alpha:]]{2,10}" contained
+syn match       asteriskPort            "\d\{1,5}" contained
+syn match       asteriskSetting         "^bindaddr\s*=\s*\d\{1,3}\.\d\{1,3}\.\d\{1,3}\.\d\{1,3}$" contains=asteriskIP
+syn match       asteriskSetting         "^port\s*=\s*\d\{1,5}\s*$" contains=asteriskPort
+syn match       asteriskSetting         "^host\s*=\s*\(dynamic\|\(\d\{1,3}\.\d\{1,3}\.\d\{1,3}\.\d\{1,3}\)\|\([[:alnum:]][[:alnum:]\-\.]*\.[[:alpha:]]{2,10}\)\)" contains=asteriskIP,asteriskHostname
+
+" Define the default highlighting.
+" For version 5.7 and earlier: only when not done already
+" For version 5.8 and later: only when an item doesn't have highlighting yet
+if version >= 508 || !exists("did_conf_syntax_inits")
+  if version < 508
+    let did_conf_syntax_inits = 1
+    command -nargs=+ HiLink hi link <args>
+  else
+    command -nargs=+ HiLink hi def link <args>
+  endif
+
+  HiLink        asteriskComment		Comment
+  HiLink        asteriskExten		String
+  HiLink        asteriskContext         Preproc
+  HiLink        asteriskPattern         Type
+  HiLink        asteriskApp             Statement
+  HiLink        asteriskInclude         Preproc
+  HiLink        asteriskIncludeBad	Error
+  HiLink        asteriskPriority        Preproc
+  HiLink        asteriskLabel           Type
+  HiLink        asteriskVar             String
+  HiLink        asteriskVarLen          Function
+  HiLink        asteriskExp             Type
+  HiLink        asteriskCodecsPermit    Preproc
+  HiLink        asteriskCodecs          String
+  HiLink        asteriskType            Statement
+  HiLink        asteriskTypeType        Type
+  HiLink        asteriskAuth            String
+  HiLink        asteriskAuthType        Type
+  HiLink        asteriskIPRange         Identifier
+  HiLink        asteriskIP              Identifier
+  HiLink        asteriskPort            Identifier
+  HiLink        asteriskHostname        Identifier
+  HiLink        asteriskSetting         Statement
+  HiLink        asteriskError           Error
+ delcommand HiLink
+endif
+let b:current_syntax = "asterisk" 
+" vim: ts=8 sw=2
+
--- /dev/null
+++ b/lib/vimfiles/syntax/asteriskvm.vim
@@ -1,0 +1,62 @@
+" Vim syntax file
+" Language:	Asterisk voicemail config file
+" Maintainer: Tilghman Lesher (Corydon76)
+" Last Change:	2006 Mar 21
+" version 0.2
+"
+if version < 600
+  syntax clear
+elseif exists("b:current_syntax")
+  finish
+endif
+
+syn sync clear
+syn sync fromstart
+
+
+syn keyword     asteriskvmTodo    TODO contained
+syn match       asteriskvmComment         ";.*" contains=asteriskvmTodo
+syn match       asteriskvmContext         "\[.\{-}\]"
+
+" ZoneMessages
+syn match       asteriskvmZone            "^[[:alnum:]]\+\s*=>\?\s*[[:alnum:]/_]\+|.*$" contains=zoneName,zoneDef
+syn match       zoneName                "=\zs[[:alnum:]/_]\+\ze" contained
+syn match       zoneDef                 "|\zs.*\ze$" contained
+
+syn match       asteriskvmSetting         "\<\(format\|serveremail\|minmessage\|maxmessage\|maxgreet\|skipms\|maxsilence\|silencethreshold\|maxlogins\)="
+syn match       asteriskvmSetting         "\<\(externnotify\|externpass\|directoryintro\|charset\|adsi\(fdn\|sec\|ver\)\|\(pager\)\?fromstring\|email\(subject\|body\|cmd\)\|tz\|cidinternalcontexts\|saydurationm\|dialout\|callback\)="
+syn match       asteriskvmSettingBool     "\<\(attach\|pbxskip\|usedirectory\|saycid\|sayduration\|sendvoicemail\|review\|operator\|envelope\|delete\|nextaftercmd\|forcename\|forcegreeting\)=\(yes\|no\|1\|0\|true\|false\|t\|f\)"
+
+" Individual mailbox definitions
+syn match       asteriskvmMailbox         "^[[:digit:]]\+\s*=>\?\s*[[:digit:]]\+\(,[^,]*\(,[^,]*\(,[^,]*\(,[^,]*\)\?\)\?\)\?\)\?" contains=mailboxEmail,asteriskvmSetting,asteriskvmSettingBool,comma
+syn match       mailboxEmail            ",\zs[^@=,]*@[[:alnum:]\-\.]\+\.[[:alpha:]]\{2,10}\ze" contains=comma
+syn match       comma                   "[,|]" contained
+
+" Define the default highlighting.
+" For version 5.7 and earlier: only when not done already
+" For version 5.8 and later: only when an item doesn't have highlighting yet
+:if version >= 508 || !exists("did_conf_syntax_inits")
+  if version < 508
+    let did_conf_syntax_inits = 1
+    command -nargs=+ HiLink hi link <args>
+  else
+    command -nargs=+ HiLink hi def link <args>
+  endif
+
+  HiLink        asteriskvmComment Comment
+  HiLink        asteriskvmContext         Identifier
+  HiLink        asteriskvmZone            Type
+  HiLink        zoneName                String
+  HiLink        zoneDef                 String
+  HiLink        asteriskvmSetting         Type
+  HiLink        asteriskvmSettingBool     Type
+
+  HiLink        asteriskvmMailbox         Statement
+  HiLink        mailboxEmail            String
+ delcommand HiLink
+endif
+
+let b:current_syntax = "asteriskvm"
+
+" vim: ts=8 sw=2
+
--- /dev/null
+++ b/lib/vimfiles/syntax/atlas.vim
@@ -1,0 +1,98 @@
+" Vim syntax file
+" Language:	ATLAS
+" Maintainer:	Inaki Saez <jisaez@sfe.indra.es>
+" Last Change:	2001 May 09
+
+" For version 5.x: Clear all syntax items
+" For version 6.x: Quit when a syntax file was already loaded
+if version < 600
+  syntax clear
+elseif exists("b:current_syntax")
+  finish
+endif
+
+syn case ignore
+
+syn keyword atlasStatement	begin terminate
+syn keyword atlasStatement	fill calculate compare
+syn keyword atlasStatement	setup connect close open disconnect reset
+syn keyword atlasStatement	initiate read fetch
+syn keyword atlasStatement	apply measure verify remove
+syn keyword atlasStatement	perform leave finish output delay
+syn keyword atlasStatement	prepare execute
+syn keyword atlasStatement	do
+syn match atlasStatement	"\<go[	 ]\+to\>"
+syn match atlasStatement	"\<wait[	 ]\+for\>"
+
+syn keyword atlasInclude	include
+syn keyword atlasDefine		define require declare identify
+
+"syn keyword atlasReserved	true false go nogo hi lo via
+syn keyword atlasReserved	true false
+
+syn keyword atlasStorageClass	external global
+
+syn keyword atlasConditional	if then else end
+syn keyword atlasRepeat		while for thru
+
+" Flags BEF and statement number
+syn match atlasSpecial		"^[BE ][ 0-9]\{,6}\>"
+
+" Number formats
+syn match atlasHexNumber	"\<X'[0-9A-F]\+'"
+syn match atlasOctalNumber	"\<O'[0-7]\+'"
+syn match atlasBinNumber	"\<B'[01]\+'"
+syn match atlasNumber		"\<\d\+\>"
+"Floating point number part only
+syn match atlasDecimalNumber	"\.\d\+\([eE][-+]\=\d\)\=\>"
+
+syn region atlasFormatString	start=+((+	end=+\())\)\|\()[	 ]*\$\)+me=e-1
+syn region atlasString		start=+\<C'+	end=+'+   oneline
+
+syn region atlasComment		start=+^C+	end=+\$+
+syn region atlasComment2	start=+\$.\++ms=s+1	end=+$+ oneline
+
+syn match  atlasIdentifier	"'[A-Za-z0-9 ._-]\+'"
+
+"Synchronization with Statement terminator $
+syn sync match atlasTerminator	grouphere atlasComment "^C"
+syn sync match atlasTerminator	groupthere NONE "\$"
+syn sync maxlines=100
+
+
+" Define the default highlighting.
+" For version 5.7 and earlier: only when not done already
+" For version 5.8 and later: only when an item doesn't have highlighting yet
+if version >= 508 || !exists("did_atlas_syntax_inits")
+  if version < 508
+    let did_atlas_syntax_inits = 1
+    command -nargs=+ HiLink hi link <args>
+  else
+    command -nargs=+ HiLink hi def link <args>
+  endif
+
+  HiLink atlasConditional	Conditional
+  HiLink atlasRepeat		Repeat
+  HiLink atlasStatement	Statement
+  HiLink atlasNumber		Number
+  HiLink atlasHexNumber	Number
+  HiLink atlasOctalNumber	Number
+  HiLink atlasBinNumber	Number
+  HiLink atlasDecimalNumber	Float
+  HiLink atlasFormatString	String
+  HiLink atlasString		String
+  HiLink atlasComment		Comment
+  HiLink atlasComment2		Comment
+  HiLink atlasInclude		Include
+  HiLink atlasDefine		Macro
+  HiLink atlasReserved		PreCondit
+  HiLink atlasStorageClass	StorageClass
+  HiLink atlasIdentifier	NONE
+  HiLink atlasSpecial		Special
+
+  delcommand HiLink
+endif
+
+let b:current_syntax = "atlas"
+
+" vim: ts=8
--- /dev/null
+++ b/lib/vimfiles/syntax/autohotkey.vim
@@ -1,0 +1,278 @@
+" Vim syntax file
+" Language:         AutoHotkey script file
+" Maintainer:       Nikolai Weibull <now@bitwi.se>
+" Latest Revision:  2007-05-09
+
+if exists("b:current_syntax")
+  finish
+endif
+
+let s:cpo_save = &cpo
+set cpo&vim
+
+syn case ignore
+
+syn keyword autohotkeyTodo
+      \ contained
+      \ TODO FIXME XXX NOTE
+
+syn cluster autohotkeyCommentGroup
+      \ contains=
+      \   autohotkeyTodo,
+      \   @Spell
+
+syn match   autohotkeyComment
+      \ display
+      \ contains=@autohotkeyCommentGroup
+      \ '`\@<!;.*$'
+
+syn region  autohotkeyComment
+      \ contains=@autohotkeyCommentGroup
+      \ matchgroup=autohotkeyCommentStart
+      \ start='/\*'
+      \ end='\*/'
+
+syn match   autohotkeyEscape
+      \ display
+      \ '`.'
+
+syn match   autohotkeyHotkey
+      \ contains=autohotkeyKey,
+      \   autohotkeyHotkeyDelimiter
+      \ display
+      \ '^.\{-}::'
+
+syn match   autohotkeyKey
+      \ contained
+      \ display
+      \ '^.\{-}'
+
+syn match   autohotkeyDelimiter
+      \ contained
+      \ display
+      \ '::'
+
+syn match   autohotkeyHotstringDefinition
+      \ contains=autohotkeyHotstring,
+      \   autohotkeyHotstringDelimiter
+      \ display
+      \ '^:\%(B0\|C1\|K\d\+\|P\d\+\|S[IPE]\|Z\d\=\|[*?COR]\)*:.\{-}::'
+
+syn match   autohotkeyHotstring
+      \ contained
+      \ display
+      \ '.\{-}'
+
+syn match   autohotkeyHotstringDelimiter
+      \ contained
+      \ display
+      \ '::'
+
+syn match   autohotkeyHotstringDelimiter
+      \ contains=autohotkeyHotstringOptions
+      \ contained
+      \ display
+      \ ':\%(B0\|C1\|K\d\+\|P\d\+\|S[IPE]\|Z\d\=\|[*?COR]\):'
+
+syn match   autohotkeyHotstringOptions
+      \ contained
+      \ display
+      \ '\%(B0\|C1\|K\d\+\|P\d\+\|S[IPE]\|Z\d\=\|[*?COR]\)'
+
+syn region autohotkeyString
+      \ display
+      \ oneline
+      \ matchgroup=autohotkeyStringDelimiter
+      \ start=+"+
+      \ end=+"+
+      \ contains=autohotkeyEscape
+
+syn region autohotkeyVariable
+      \ display
+      \ oneline
+      \ contains=autohotkeyBuiltinVariable
+      \ matchgroup=autohotkeyVariableDelimiter
+      \ start="%"
+      \ end="%"
+      \ keepend
+
+syn keyword autohotkeyBuiltinVariable
+      \ A_Space A_Tab
+      \ A_WorkingDir A_ScriptDir A_ScriptName A_ScriptFullPath A_LineNumber
+      \ A_LineFile A_AhkVersion A_AhkPAth A_IsCompiled A_ExitReason
+      \ A_YYYY A_MM A_DD A_MMMM A_MMM A_DDDD A_DDD A_WDay A_YWeek A_Hour A_Min
+      \ A_Sec A_MSec A_Now A_NowUTC A_TickCount
+      \ A_IsSuspended A_BatchLines A_TitleMatchMode A_TitleMatchModeSpeed
+      \ A_DetectHiddenWindows A_DetectHiddenText A_AutoTrim A_STringCaseSense
+      \ A_FormatInteger A_FormatFloat A_KeyDelay A_WinDelay A_ControlDelay
+      \ A_MouseDelay A_DefaultMouseSpeed A_IconHidden A_IconTip A_IconFile
+      \ A_IconNumber
+      \ A_TimeIdle A_TimeIdlePhysical
+      \ A_Gui A_GuiControl A_GuiWidth A_GuiHeight A_GuiX A_GuiY A_GuiEvent
+      \ A_GuiControlEvent A_EventInfo
+      \ A_ThisMenuItem A_ThisMenu A_ThisMenuItemPos A_ThisHotkey A_PriorHotkey
+      \ A_TimeSinceThisHotkey A_TimeSincePriorHotkey A_EndChar
+      \ ComSpec A_Temp A_OSType A_OSVersion A_Language A_ComputerName A_UserName
+      \ A_WinDir A_ProgramFiles ProgramFiles A_AppData A_AppDataCommon A_Desktop
+      \ A_DesktopCommon A_StartMenu A_StartMenuCommon A_Programs
+      \ A_ProgramsCommon A_Startup A_StartupCommon A_MyDocuments A_IsAdmin
+      \ A_ScreenWidth A_ScreenHeight A_IPAddress1 A_IPAddress2 A_IPAddress3
+      \ A_IPAddress4
+      \ A_Cursor A_CaretX A_CaretY Clipboard ClipboardAll ErrorLevel A_LastError
+      \ A_Index A_LoopFileName A_LoopRegName A_LoopReadLine A_LoopField
+
+syn match   autohotkeyBuiltinVariable
+      \ contained
+      \ display
+      \ '%\d\+%'
+
+syn keyword autohotkeyCommand
+      \ ClipWait EnvGet EnvSet EnvUpdate
+      \ Drive DriveGet DriveSpaceFree FileAppend FileCopy FileCopyDir
+      \ FileCreateDir FileCreateShortcut FileDelete FileGetAttrib
+      \ FileGetShortcut FileGetSize FileGetTime FileGetVersion FileInstall
+      \ FileMove FileMoveDir FileReadLine FileRead FileRecycle FileRecycleEmpty
+      \ FileRemoveDir FileSelectFolder FileSelectFile FileSetAttrib FileSetTime
+      \ IniDelete IniRead IniWrite SetWorkingDir
+      \ SplitPath
+      \ Gui GuiControl GuiControlGet IfMsgBox InputBox MsgBox Progress
+      \ SplashImage SplashTextOn SplashTextOff ToolTip TrayTip
+      \ Hotkey ListHotkeys BlockInput ControlSend ControlSendRaw GetKeyState
+      \ KeyHistory KeyWait Input Send SendRaw SendInput SendPlay SendEvent
+      \ SendMode SetKeyDelay SetNumScrollCapsLockState SetStoreCapslockMode
+      \ EnvAdd EnvDiv EnvMult EnvSub Random SetFormat Transform
+      \ AutoTrim BlockInput CoordMode Critical Edit ImageSearch
+      \ ListLines ListVars Menu OutputDebug PixelGetColor PixelSearch
+      \ SetBatchLines SetEnv SetTimer SysGet Thread Transform URLDownloadToFile
+      \ Click ControlClick MouseClick MouseClickDrag MouseGetPos MouseMove
+      \ SetDefaultMouseSpeed SetMouseDelay
+      \ Process Run RunWait RunAs Shutdown Sleep
+      \ RegDelete RegRead RegWrite
+      \ SoundBeep SoundGet SoundGetWaveVolume SoundPlay SoundSet
+      \ SoundSetWaveVolume
+      \ FormatTime IfInString IfNotInString Sort StringCaseSense StringGetPos
+      \ StringLeft StringRight StringLower StringUpper StringMid StringReplace
+      \ StringSplit StringTrimLeft StringTrimRight
+      \ Control ControlClick ControlFocus ControlGet ControlGetFocus
+      \ ControlGetPos ControlGetText ControlMove ControlSend ControlSendRaw
+      \ ControlSetText Menu PostMessage SendMessage SetControlDelay
+      \ WinMenuSelectItem GroupActivate GroupAdd GroupClose GroupDeactivate
+      \ DetectHiddenText DetectHiddenWindows SetTitleMatchMode SetWinDelay
+      \ StatusBarGetText StatusBarWait WinActivate WinActivateBottom WinClose
+      \ WinGet WinGetActiveStats WinGetActiveTitle WinGetClass WinGetPos
+      \ WinGetText WinGetTitle WinHide WinKill WinMaximize WinMinimize
+      \ WinMinimizeAll WinMinimizeAllUndo WinMove WinRestore WinSet
+      \ WinSetTitle WinShow WinWait WinWaitActive WinWaitNotActive WinWaitClose
+
+syn keyword autohotkeyFunction
+      \ InStr RegExMatch RegExReplace StrLen SubStr Asc Chr
+      \ DllCall VarSetCapacity WinActive WinExist IsLabel OnMessage 
+      \ Abs Ceil Exp Floor Log Ln Mod Round Sqrt Sin Cos Tan ASin ACos ATan
+      \ FileExist GetKeyState
+
+syn keyword autohotkeyStatement
+      \ Break Continue Exit ExitApp Gosub Goto OnExit Pause Return
+      \ Suspend Reload
+
+syn keyword autohotkeyRepeat
+      \ Loop
+
+syn keyword autohotkeyConditional
+      \ IfExist IfNotExist If IfEqual IfLess IfGreater Else
+
+syn match   autohotkeyPreProcStart
+      \ nextgroup=
+      \   autohotkeyInclude,
+      \   autohotkeyPreProc
+      \ skipwhite
+      \ display
+      \ '^\s*\zs#'
+
+syn keyword autohotkeyInclude
+      \ contained
+      \ Include
+      \ IncludeAgain
+
+syn keyword autohotkeyPreProc
+      \ contained
+      \ HotkeyInterval HotKeyModifierTimeout
+      \ Hotstring
+      \ IfWinActive IfWinNotActive IfWinExist IfWinNotExist
+      \ MaxHotkeysPerInterval MaxThreads MaxThreadsBuffer MaxThreadsPerHotkey
+      \ UseHook InstallKeybdHook InstallMouseHook
+      \ KeyHistory
+      \ NoTrayIcon SingleInstance
+      \ WinActivateForce
+      \ AllowSameLineComments
+      \ ClipboardTimeout
+      \ CommentFlag
+      \ ErrorStdOut
+      \ EscapeChar
+      \ MaxMem
+      \ NoEnv
+      \ Persistent
+
+syn keyword autohotkeyMatchClass
+      \ ahk_group ahk_class ahk_id ahk_pid
+
+syn match   autohotkeyNumbers
+      \ display
+      \ transparent
+      \ contains=
+      \   autohotkeyInteger,
+      \   autohotkeyFloat
+      \ '\<\d\|\.\d'
+
+syn match   autohotkeyInteger
+      \ contained
+      \ display
+      \ '\d\+\>'
+
+syn match   autohotkeyInteger
+      \ contained
+      \ display
+      \ '0x\x\+\>'
+
+syn match   autohotkeyFloat
+      \ contained
+      \ display
+      \ '\d\+\.\d*\|\.\d\+\>'
+
+syn keyword autohotkeyType
+      \ local
+      \ global
+
+hi def link autohotkeyTodo                Todo
+hi def link autohotkeyComment             Comment
+hi def link autohotkeyCommentStart        autohotkeyComment
+hi def link autohotkeyEscape              Special
+hi def link autohotkeyHotkey              Type
+hi def link autohotkeyKey                 Type
+hi def link autohotkeyDelimiter           Delimiter
+hi def link autohotkeyHotstringDefinition Type
+hi def link autohotkeyHotstring           Type
+hi def link autohotkeyHotstringDelimiter  autohotkeyDelimiter
+hi def link autohotkeyHotstringOptions    Special
+hi def link autohotkeyString              String
+hi def link autohotkeyStringDelimiter     autohotkeyString
+hi def link autohotkeyVariable            Identifier
+hi def link autohotkeyVariableDelimiter   autohotkeyVariable
+hi def link autohotkeyBuiltinVariable     Macro
+hi def link autohotkeyCommand             Keyword
+hi def link autohotkeyFunction            Function
+hi def link autohotkeyStatement           autohotkeyCommand
+hi def link autohotkeyRepeat              Repeat
+hi def link autohotkeyConditional         Conditional
+hi def link autohotkeyPreProcStart        PreProc
+hi def link autohotkeyInclude             Include
+hi def link autohotkeyPreProc             PreProc
+hi def link autohotkeyMatchClass          Typedef
+hi def link autohotkeyNumber              Number
+hi def link autohotkeyInteger             autohotkeyNumber
+hi def link autohotkeyFloat               autohotkeyNumber
+hi def link autohotkeyType                Type
+
+let b:current_syntax = "autohotkey"
+
+let &cpo = s:cpo_save
+unlet s:cpo_save
--- /dev/null
+++ b/lib/vimfiles/syntax/autoit.vim
@@ -1,0 +1,1111 @@
+" Vim syntax file
+"
+" Language:	AutoIt v3 (http://www.autoitscript.com/autoit3/)
+" Maintainer:	Jared Breland <jbreland@legroom.net>
+" Authored By:	Riccardo Casini <ric@libero.it>
+" Script URL:	http://www.vim.org/scripts/script.php?script_id=1239
+" ChangeLog:	Please visit the script URL for detailed change information
+
+" AutoIt is not case dependent
+syn case ignore
+
+" Definitions for AutoIt reserved keywords
+syn keyword autoitKeyword Default False True
+syn keyword autoitKeyword Const Dim Global Local ReDim
+syn keyword autoitKeyword If Else ElseIf Then EndIf
+syn keyword autoitKeyword Select Switch Case EndSelect EndSwitch
+syn keyword autoitKeyword Enum For In To Step Next
+syn keyword autoitKeyword With While EndWith Wend Do Until
+syn keyword autoitKeyword ContinueCase ContinueLoop ExitLoop Exit
+
+" inside script inclusion and global options
+syn match autoitIncluded display contained "<[^>]*>"
+syn match autoitInclude	display "^\s*#\s*include\>\s*["<]"
+	\ contains=autoitIncluded,autoitString
+syn match autoitInclude "^\s*#include-once\>"
+syn match autoitInclude "^\s*#NoTrayIcon\>"
+syn match autoitInclude "^\s*#RequireAdmin\>"
+
+" user-defined functions
+syn keyword autoitKeyword Func ByRef EndFunc Return OnAutoItStart OnAutoItExit
+
+" built-in functions
+" environment management
+syn keyword autoitFunction ClipGet ClipPut EnvGet EnvSet EnvUpdate MemGetStats
+" file, directory, and disk management
+syn keyword autoitFunction ConsoleRead ConsoleWrite ConsoleWriteError
+syn keyword autoitFunction DirCopy DirCreate DirGetSize DirMove DirRemove
+syn keyword autoitFunction DriveGetDrive DriveGetFileSystem DriveGetLabel
+	\ DriveGetSerial DriveGetType DriveMapAdd DriveMapDel DriveMapGet
+	\ DriveSetLabel DriveSpaceFree DriveSpaceTotal DriveStatus
+syn keyword autoitFunction FileChangeDir FileClose FileCopy FileCreateNTFSLink
+	\ FileCreateShortcut FileDelete FileExists FileFindFirstFile
+	\ FileFindNextFile FileGetAttrib FileGetLongName FileGetShortcut
+	\ FileGetShortName FileGetSize FileGetTime FileGetVersion FileInstall
+	\ FileMove FileOpen FileOpenDialog FileRead FileReadLine FileRecycle
+	\ FileRecycleEmpty FileSaveDialog FileSelectFolder FileSetAttrib
+	\ FileSetTime FileWrite FileWriteLine
+syn keyword autoitFunction IniDelete IniRead IniReadSection IniReadSectionNames
+	\ IniRenameSection IniWrite IniWriteSection
+syn keyword autoitFunction StderrRead StdinWrite StdoutRead
+" graphic and sound
+syn keyword autoitFunction Beep PixelChecksum PixelGetColor PixelSearch
+	\ SoundPlay SoundSetWaveVolume
+" gui reference
+syn keyword autoitFunction GUICreate GUIDelete GUICtrlGetHandle GUICtrlGetState
+	\ GUICtrlRead GUICtrlRecvMsg GUICtrlSendMsg GUICtrlSendToDummy
+	\ GUIGetCursorInfo GUIGetMsg GUIRegisterMsg GUIStartGroup GUISwitch
+syn keyword autoitFunction GUICtrlCreateAvi GUICtrlCreateButton
+	\ GUICtrlCreateCheckbox GUICtrlCreateCombo GUICtrlCreateContextMenu
+	\ GUICtrlCreateDate GUICtrlCreateDummy GUICtrlCreateEdit
+	\ GUICtrlCreateGraphic GUICtrlCreateGroup GUICtrlCreateIcon
+	\ GUICtrlCreateInput GUICtrlCreateLabel GUICtrlCreateList
+	\ GUICtrlCreateListView GUICtrlCreateListViewItem GUICtrlCreateMenu
+	\ GUICtrlCreateMenuItem GUICtrlCreateMonthCal GUICtrlCreateObj
+	\ GUICtrlCreatePic GUICtrlCreateProgress GUICtrlCreateRadio
+	\ GUICtrlCreateSlider GUICtrlCreateTab GUICtrlCreateTabItem
+	\ GUICtrlCreateTreeView GUICtrlCreateTreeViewItem
+	\ GUICtrlCreateUpDown GUICtrlDelete
+syn keyword autoitFunction GUICtrlRegisterListViewSort GUICtrlSetBkColor
+	\ GUICtrlSetColor GUICtrlSetCursor GUICtrlSetData GUICtrlSetFont
+	\ GUICtrlSetGraphic GUICtrlSetImage GUICtrlSetLimit GUICtrlSetOnEvent
+	\ GUICtrlSetPos GUICtrlSetResizing GUICtrlSetState GUICtrlSetStyle
+	\ GUICtrlSetTip
+syn keyword autoitFunction GUISetBkColor GUISetCoord GUISetCursor GUISetFont
+	\ GUISetHelp GUISetIcon GUISetOnEvent GUISetState
+" keyboard control
+syn keyword autoitFunction HotKeySet Send
+" math
+syn keyword autoitFunction Abs ACos ASin ATan BitAND BitNOT BitOR BitRotate
+	\ BitShift BitXOR Cos Ceiling Exp Floor Log Mod Random Round Sin Sqrt
+	\ SRandom Tan
+" message boxes and dialogs
+syn keyword autoitFunction InputBox MsgBox ProgressOff ProgressOn ProgressSet
+	\ SplashImageOn SplashOff SplashTextOn ToolTip
+" miscellaneous
+syn keyword autoitFunction AdlibDisable AdlibEnable AutoItSetOption
+	\ AutoItWinGetTitle AutoItWinSetTitle BlockInput Break Call CDTray
+	\ Execute Opt SetError SetExtended
+" mouse control
+syn keyword autoitFunction MouseClick MouseClickDrag MouseDown MouseGetCursor
+	\ MouseGetPos MouseMove MouseUp MouseWheel
+" network
+syn keyword autoitFunction FtpSetProxy HttpSetProxy InetGet InetGetSize Ping
+	\ TCPAccept TCPCloseSocket TCPConnect TCPListen TCPNameToIp TCPRecv
+	\ TCPSend TCPShutDown TCPStartup UDPBind UDPCloseSocket UDPOpen UDPRecv
+	\ UDPSend UDPShutdown UDPStartup
+" obj/com reference
+syn keyword autoitFunction ObjCreate ObjEvent ObjGet ObjName
+" process management
+syn keyword autoitFunction DllCall DllClose DllOpen DllStructCreate
+	\ DllStructGetData DllStructGetPtr DllStructGetSize DllStructSetData
+	\ ProcessClose ProcessExists ProcessSetPriority ProcessList ProcessWait
+	\ ProcessWaitClose Run RunAsSet RunWait ShellExecute ShellExecuteWait
+	\ Shutdown
+	" removed from 3.2.0 docs - PluginClose PluginOpen
+" registry management
+syn keyword autoitFunction RegDelete RegEnumKey RegEnumVal RegRead RegWrite
+" string management
+syn keyword autoitFunction StringAddCR StringFormat StringInStr StringIsAlNum
+	\ StringIsAlpha StringIsASCII StringIsDigit StringIsFloat StringIsInt
+	\ StringIsLower StringIsSpace StringIsUpper StringIsXDigit StringLeft
+	\ StringLen StringLower StringMid StringRegExp StringRegExpReplace
+	\ StringReplace StringRight StringSplit StringStripCR StringStripWS
+	\ StringTrimLeft StringTrimRight StringUpper
+" timer and delay
+syn keyword autoitFunction Sleep TimerInit TimerDiff
+" tray
+syn keyword autoitFunction TrayCreateItem TrayCreateMenu TrayItemDelete
+	\ TrayItemGetHandle TrayItemGetState TrayItemGetText TrayItemSetOnEvent
+	\ TrayItemSetState TrayItemSetText TrayGetMsg TraySetClick TraySetIcon
+	\ TraySetOnEvent TraySetPauseIcon TraySetState TraySetToolTip TrayTip
+" variables and conversions
+syn keyword autoitFunction Asc Assign Binary Chr Dec Eval Hex HWnd Int IsAdmin
+	\ IsArray IsBinaryString IsBool IsDeclared IsDllStruct IsFloat IsHWnd
+	\ IsInt IsKeyword IsNumber IsObj IsString Number String UBound
+" window management
+syn keyword autoitFunction WinActivate WinActive WinClose WinExists WinFlash
+	\ WinGetCaretPos WinGetClassList WinGetClientSize WinGetHandle WinGetPos
+	\ WinGetProcess WinGetState WinGetText WinGetTitle WinKill WinList
+	\ WinMenuSelectItem WinMinimizeAll WinMinimizeAllUndo WinMove
+	\ WinSetOnTop WinSetState WinSetTitle WinSetTrans WinWait WinWaitActive
+	\ WinWaitClose WinWaitNotActive
+syn keyword autoitFunction ControlClick ControlCommand ControlDisable
+	\ ControlEnable ControlFocus ControlGetFocus ControlGetHandle
+	\ ControlGetPos ControlGetText ControlHide ControlListView ControlMove
+	\ ControlSend ControlSetText ControlShow StatusBarGetText
+
+" user defined functions
+" array
+syn keyword autoitFunction _ArrayAdd _ArrayBinarySearch _ArrayCreate
+	\ _ArrayDelete _ArrayDisplay _ArrayInsert _ArrayMax _ArrayMaxIndex
+	\ _ArrayMin _ArrayMinIndex _ArrayPop _ArrayPush _ArrayReverse
+	\ _ArraySearch _ArraySort _ArraySwap _ArrayToClip _ArrayToString
+	\ _ArrayTrim
+" color
+syn keyword autoitFunction _ColorgetBlue _ColorGetGreen _ColorGetRed
+" date
+syn keyword autoitFunction _DateAdd _DateDayOfWeek _DateDaysInMonth _DateDiff
+	\ _DateIsLeapYear _DateIsValid _DateTimeFormat _DateTimeSplit
+	\ _DateToDayOfWeek _ToDayOfWeekISO _DateToDayValue _DayValueToDate _Now
+	\ _NowCalc _NowCalcDate _NowDate _NowTime _SetDate _SetTime _TicksToTime
+	\ _TimeToTicks _WeekNumberISO
+" file
+syn keyword autoitFunction _FileCountLines _FileCreate _FileListToArray
+	\ _FilePrint _FileReadToArray _FileWriteFromArray _FileWriteLog
+	\ _FileWriteToLine _PathFull _PathMake _PathSplit _ReplaceStringInFile
+	\ _TempFile
+" guicombo
+syn keyword autoitFunction _GUICtrlComboAddDir _GUICtrlComboAddString
+	\ _GUICtrlComboAutoComplete _GUICtrlComboDeleteString
+	\ _GUICtrlComboFindString _GUICtrlComboGetCount _GUICtrlComboGetCurSel
+	\ _GUICtrlComboGetDroppedControlRect _GUICtrlComboGetDroppedState
+	\ _GUICtrlComboGetDroppedWidth _GUICtrlComboGetEditSel
+	\ _GUICtrlComboGetExtendedUI _GUICtrlComboGetHorizontalExtent
+	\ _GUICtrlComboGetItemHeight _GUICtrlComboGetLBText
+	\ _GUICtrlComboGetLBTextLen _GUICtrlComboGetList _GUICtrlComboGetLocale
+	\ _GUICtrlComboGetMinVisible _GUICtrlComboGetTopIndex
+	\ _GUICtrlComboInitStorage _GUICtrlComboInsertString
+	\ _GUICtrlComboLimitText _GUICtrlComboResetContent
+	\ _GUICtrlComboSelectString _GUICtrlComboSetCurSel
+	\ _GUICtrlComboSetDroppedWidth _GUICtrlComboSetEditSel
+	\ _GUICtrlComboSetExtendedUI _GUICtrlComboSetHorizontalExtent
+	\ _GUICtrlComboSetItemHeight _GUICtrlComboSetMinVisible
+	\ _GUICtrlComboSetTopIndex _GUICtrlComboShowDropDown
+" guiedit
+syn keyword autoitFunction _GUICtrlEditCanUndo _GUICtrlEditEmptyUndoBuffer
+	\ _GuiCtrlEditFind _GUICtrlEditGetFirstVisibleLine _GUICtrlEditGetLine
+	\ _GUICtrlEditGetLineCount _GUICtrlEditGetModify _GUICtrlEditGetRect
+	\ _GUICtrlEditGetSel _GUICtrlEditLineFromChar _GUICtrlEditLineIndex
+	\ _GUICtrlEditLineLength _GUICtrlEditLineScroll _GUICtrlEditReplaceSel
+	\ _GUICtrlEditScroll _GUICtrlEditSetModify _GUICtrlEditSetRect
+	\ _GUICtrlEditSetSel _GUICtrlEditUndo
+" guiipaddress
+syn keyword autoitFunction _GUICtrlIpAddressClear _GUICtrlIpAddressCreate
+	\ _GUICtrlIpAddressDelete _GUICtrlIpAddressGet _GUICtrlIpAddressIsBlank
+	\ _GUICtrlIpAddressSet _GUICtrlIpAddressSetFocus
+	\ _GUICtrlIpAddressSetFont
+	\ _GUICtrlIpAddressSetRange _GUICtrlIpAddressShowHide
+" guilist
+syn keyword autoitFunction _GUICtrlListAddDir _GUICtrlListAddItem
+	\ _GUICtrlListClear
+	\ _GUICtrlListCount _GUICtrlListDeleteItem _GUICtrlListFindString
+	\ _GUICtrlListGetAnchorIndex _GUICtrlListGetCaretIndex
+	\ _GUICtrlListGetHorizontalExtent _GUICtrlListGetInfo
+	\ _GUICtrlListGetItemRect _GUICtrlListGetLocale _GUICtrlListGetSelCount
+	\ _GUICtrlListGetSelItems _GUICtrlListGetSelItemsText
+	\ _GUICtrlListGetSelState _GUICtrlListGetText _GUICtrlListGetTextLen
+	\ _GUICtrlListGetTopIndex _GUICtrlListInsertItem
+	\ _GUICtrlListReplaceString _GUICtrlListSelectedIndex
+	\ _GUICtrlListSelectIndex _GUICtrlListSelectString
+	\ _GUICtrlListSelItemRange _GUICtrlListSelItemRangeEx
+	\ _GUICtrlListSetAnchorIndex _GUICtrlListSetCaretIndex
+	\ _GUICtrlListSetHorizontalExtent _GUICtrlListSetLocale
+	\ _GUICtrlListSetSel _GUICtrlListSetTopIndex _GUICtrlListSort
+	\ _GUICtrlListSwapString
+" guilistview
+syn keyword autoitFunction _GUICtrlListViewCopyItems
+	\ _GUICtrlListViewDeleteAllItems _GUICtrlListViewDeleteColumn
+	\ _GUICtrlListViewDeleteItem _GUICtrlListViewDeleteItemsSelected
+	\ _GUICtrlListViewEnsureVisible _GUICtrlListViewFindItem
+	\ _GUICtrlListViewGetBackColor _GUICtrlListViewGetCallBackMask
+	\ _GUICtrlListViewGetCheckedState _GUICtrlListViewGetColumnOrder
+	\ _GUICtrlListViewGetColumnWidth _GUICtrlListViewGetCounterPage
+	\ _GUICtrlListViewGetCurSel _GUICtrlListViewGetExtendedListViewStyle
+	\ _GUICtrlListViewGetHeader _GUICtrlListViewGetHotCursor
+	\ _GUICtrlListViewGetHotItem _GUICtrlListViewGetHoverTime
+	\ _GUICtrlListViewGetItemCount _GUICtrlListViewGetItemText
+	\ _GUICtrlListViewGetItemTextArray _GUICtrlListViewGetNextItem
+	\ _GUICtrlListViewGetSelectedCount _GUICtrlListViewGetSelectedIndices
+	\ _GUICtrlListViewGetSubItemsCount _GUICtrlListViewGetTopIndex
+	\ _GUICtrlListViewGetUnicodeFormat _GUICtrlListViewHideColumn
+	\ _GUICtrlListViewInsertColumn _GUICtrlListViewInsertItem
+	\ _GUICtrlListViewJustifyColumn _GUICtrlListViewScroll
+	\ _GUICtrlListViewSetCheckState _GUICtrlListViewSetColumnHeaderText
+	\ _GUICtrlListViewSetColumnOrder _GUICtrlListViewSetColumnWidth
+	\ _GUICtrlListViewSetHotItem _GUICtrlListViewSetHoverTime
+	\ _GUICtrlListViewSetItemCount _GUICtrlListViewSetItemSelState
+	\ _GUICtrlListViewSetItemText _GUICtrlListViewSort
+" guimonthcal
+syn keyword autoitFunction _GUICtrlMonthCalGet1stDOW _GUICtrlMonthCalGetColor
+	\ _GUICtrlMonthCalGetDelta _GUICtrlMonthCalGetMaxSelCount
+	\ _GUICtrlMonthCalGetMaxTodayWidth _GUICtrlMonthCalGetMinReqRect
+	\ _GUICtrlMonthCalSet1stDOW _GUICtrlMonthCalSetColor
+	\ _GUICtrlMonthCalSetDelta _GUICtrlMonthCalSetMaxSelCount
+" guislider
+syn keyword autoitFunction _GUICtrlSliderClearTics _GUICtrlSliderGetLineSize
+	\ _GUICtrlSliderGetNumTics _GUICtrlSliderGetPageSize
+	\ _GUICtrlSliderGetPos _GUICtrlSliderGetRangeMax
+	\ _GUICtrlSliderGetRangeMin _GUICtrlSliderSetLineSize
+	\ _GUICtrlSliderSetPageSize _GUICtrlSliderSetPos
+	\ _GUICtrlSliderSetTicFreq
+" guistatusbar
+syn keyword autoitFunction _GuiCtrlStatusBarCreate
+	\ _GUICtrlStatusBarCreateProgress _GUICtrlStatusBarDelete
+	\ _GuiCtrlStatusBarGetBorders _GuiCtrlStatusBarGetIcon
+	\ _GuiCtrlStatusBarGetParts _GuiCtrlStatusBarGetRect
+	\ _GuiCtrlStatusBarGetText _GuiCtrlStatusBarGetTextLength
+	\ _GuiCtrlStatusBarGetTip _GuiCtrlStatusBarGetUnicode
+	\ _GUICtrlStatusBarIsSimple _GuiCtrlStatusBarResize
+	\ _GuiCtrlStatusBarSetBKColor _GuiCtrlStatusBarSetIcon
+	\ _GuiCtrlStatusBarSetMinHeight _GUICtrlStatusBarSetParts
+	\ _GuiCtrlStatusBarSetSimple _GuiCtrlStatusBarSetText
+	\ _GuiCtrlStatusBarSetTip _GuiCtrlStatusBarSetUnicode
+	\ _GUICtrlStatusBarShowHide 
+" guitab
+syn keyword autoitFunction _GUICtrlTabDeleteAllItems _GUICtrlTabDeleteItem
+	\ _GUICtrlTabDeselectAll _GUICtrlTabGetCurFocus _GUICtrlTabGetCurSel
+	\ _GUICtrlTabGetExtendedStyle _GUICtrlTabGetItemCount
+	\ _GUICtrlTabGetItemRect _GUICtrlTabGetRowCount
+	\ _GUICtrlTabGetUnicodeFormat _GUICtrlTabHighlightItem
+	\ _GUICtrlTabSetCurFocus _GUICtrlTabSetCurSel
+	\ _GUICtrlTabSetMinTabWidth _GUICtrlTabSetUnicodeFormat
+" guitreeview
+syn keyword autoitFunction _GUICtrlTreeViewDeleteAllItems
+	\ _GUICtrlTreeViewDeleteItem _GUICtrlTreeViewExpand
+	\ _GUICtrlTreeViewGetBkColor _GUICtrlTreeViewGetCount
+	\ _GUICtrlTreeViewGetIndent _GUICtrlTreeViewGetLineColor
+	\ _GUICtrlTreeViewGetParentHandle _GUICtrlTreeViewGetParentID
+	\ _GUICtrlTreeViewGetState _GUICtrlTreeViewGetText
+	\ _GUICtrlTreeViewGetTextColor _GUICtrlTreeViewItemGetTree
+	\ _GUICtrlTreeViewInsertItem _GUICtrlTreeViewSetBkColor
+	\ _GUICtrlTreeViewSetIcon _GUICtrlTreeViewSetIndent
+	\ _GUICtrlTreeViewSetLineColor GUICtrlTreeViewSetState
+	\ _GUICtrlTreeViewSetText _GUICtrlTreeViewSetTextColor
+	\ _GUICtrlTreeViewSort
+" ie
+syn keyword autoitFunction _IE_Example _IE_Introduction _IE_VersionInfo
+	\ _IEAction _IEAttach _IEBodyReadHTML _IEBodyReadText _IEBodyWriteHTML
+	\ _IECreate _IECreateEmbedded _IEDocGetObj _IEDocInsertHTML
+	\ _IEDocInsertText _IEDocReadHTML _IEDocWriteHTML
+	\ _IEErrorHandlerDeRegister _IEErrorHandlerRegister _IEErrorNotify
+	\ _IEFormElementCheckboxSelect _IEFormElementGetCollection
+	\ _IEFormElementGetObjByName _IEFormElementGetValue
+	\ _IEFormElementOptionSelect _IEFormElementRadioSelect
+	\ _IEFormElementSetValue _IEFormGetCollection _IEFormGetObjByName
+	\ _IEFormImageClick _IEFormReset _IEFormSubmit _IEFrameGetCollection
+	\ _IEFrameGetObjByName _IEGetObjByName _IEHeadInsertEventScript
+	\ _IEImgClick _IEImgGetCollection _IEIsFrameSet _IELinkClickByIndex
+	\ _IELinkClickByText _IELinkGetCollection _IELoadWait _IELoadWaitTimeout
+	\ _IENavigate _IEPropertyGet _IEPropertySet _IEQuit
+	\ _IETableGetCollection _IETableWriteToArray _IETagNameAllGetCollection
+	\  _IETagNameGetCollection
+" inet
+syn keyword autoitFunction _GetIP _INetExplorerCapable _INetGetSource _INetMail
+	\ _INetSmtpMail _TCPIpToName
+" math
+syn keyword autoitFunction _Degree _MathCheckDiv _Max _Min _Radian
+" miscellaneous
+syn keyword autoitFunction _ChooseColor _ChooseFont _ClipPutFile _Iif
+	\ _IsPressed _MouseTrap _SendMessage _Singleton
+" process
+syn keyword autoitFunction _ProcessGetName _ProcessGetPriority _RunDOS
+" sound
+syn keyword autoitFunction _SoundClose _SoundLength _SoundOpen _SoundPause
+	\ _SoundPlay _SoundPos _SoundResume _SoundSeek _SoundStatus _SoundStop
+" sqlite
+syn keyword autoitFunction _SQLite_Changes _SQLite_Close
+	\ _SQLite_Display2DResult _SQLite_Encode _SQLite_ErrCode _SQLite_ErrMsg
+	\ _SQLite_Escape _SQLite_Exec _SQLite_FetchData _SQLite_FetchNames
+	\ _SQLite_GetTable _SQLite_GetTable2D _SQLite_LastInsertRowID
+	\ _SQLite_LibVersion _SQLite_Open _SQLite_Query _SQLite_QueryFinalize
+	\ _SQLite_QueryReset _SQLite_QuerySingleRow _SQLite_SaveMode
+	\ _SQLite_SetTimeout _SQLite_Shutdown _SQLite_SQLiteExe _SQLite_Startup
+	\ _SQLite_TotalChanges
+" string
+syn keyword autoitFunction _HexToString _StringAddComma _StringBetween
+	\ _StringEncrypt _StringInsert _StringProper _StringRepeat
+	\ _StringReverse _StringToHex
+" visa
+syn keyword autoitFunction _viClose _viExecCommand _viFindGpib _viGpibBusReset
+	\ _viGTL _viOpen _viSetAttribute _viSetTimeout
+
+" read-only macros
+syn match autoitBuiltin "@AppData\(Common\)\=Dir"
+syn match autoitBuiltin "@AutoItExe"
+syn match autoitBuiltin "@AutoItPID"
+syn match autoitBuiltin "@AutoItVersion"
+syn match autoitBuiltin "@COM_EventObj"
+syn match autoitBuiltin "@CommonFilesDir"
+syn match autoitBuiltin "@Compiled"
+syn match autoitBuiltin "@ComputerName"
+syn match autoitBuiltin "@ComSpec"
+syn match autoitBuiltin "@CR\(LF\)\="
+syn match autoitBuiltin "@Desktop\(Common\)\=Dir"
+syn match autoitBuiltin "@DesktopDepth"
+syn match autoitBuiltin "@DesktopHeight"
+syn match autoitBuiltin "@DesktopRefresh"
+syn match autoitBuiltin "@DesktopWidth"
+syn match autoitBuiltin "@DocumentsCommonDir"
+syn match autoitBuiltin "@Error"
+syn match autoitBuiltin "@ExitCode"
+syn match autoitBuiltin "@ExitMethod"
+syn match autoitBuiltin "@Extended"
+syn match autoitBuiltin "@Favorites\(Common\)\=Dir"
+syn match autoitBuiltin "@GUI_CtrlId"
+syn match autoitBuiltin "@GUI_CtrlHandle"
+syn match autoitBuiltin "@GUI_DragId"
+syn match autoitBuiltin "@GUI_DragFile"
+syn match autoitBuiltin "@GUI_DropId"
+syn match autoitBuiltin "@GUI_WinHandle"
+syn match autoitBuiltin "@HomeDrive"
+syn match autoitBuiltin "@HomePath"
+syn match autoitBuiltin "@HomeShare"
+syn match autoitBuiltin "@HOUR"
+syn match autoitBuiltin "@HotKeyPressed"
+syn match autoitBuiltin "@InetGetActive"
+syn match autoitBuiltin "@InetGetBytesRead"
+syn match autoitBuiltin "@IPAddress[1234]"
+syn match autoitBuiltin "@KBLayout"
+syn match autoitBuiltin "@LF"
+syn match autoitBuiltin "@Logon\(DNS\)\=Domain"
+syn match autoitBuiltin "@LogonServer"
+syn match autoitBuiltin "@MDAY"
+syn match autoitBuiltin "@MIN"
+syn match autoitBuiltin "@MON"
+syn match autoitBuiltin "@MyDocumentsDir"
+syn match autoitBuiltin "@NumParams"
+syn match autoitBuiltin "@OSBuild"
+syn match autoitBuiltin "@OSLang"
+syn match autoitBuiltin "@OSServicePack"
+syn match autoitBuiltin "@OSTYPE"
+syn match autoitBuiltin "@OSVersion"
+syn match autoitBuiltin "@ProcessorArch"
+syn match autoitBuiltin "@ProgramFilesDir"
+syn match autoitBuiltin "@Programs\(Common\)\=Dir"
+syn match autoitBuiltin "@ScriptDir"
+syn match autoitBuiltin "@ScriptFullPath"
+syn match autoitBuiltin "@ScriptLineNumber"
+syn match autoitBuiltin "@ScriptName"
+syn match autoitBuiltin "@SEC"
+syn match autoitBuiltin "@StartMenu\(Common\)\=Dir"
+syn match autoitBuiltin "@Startup\(Common\)\=Dir"
+syn match autoitBuiltin "@SW_DISABLE"
+syn match autoitBuiltin "@SW_ENABLE"
+syn match autoitBuiltin "@SW_HIDE"
+syn match autoitBuiltin "@SW_LOCK"
+syn match autoitBuiltin "@SW_MAXIMIZE"
+syn match autoitBuiltin "@SW_MINIMIZE"
+syn match autoitBuiltin "@SW_RESTORE"
+syn match autoitBuiltin "@SW_SHOW"
+syn match autoitBuiltin "@SW_SHOWDEFAULT"
+syn match autoitBuiltin "@SW_SHOWMAXIMIZED"
+syn match autoitBuiltin "@SW_SHOWMINIMIZED"
+syn match autoitBuiltin "@SW_SHOWMINNOACTIVE"
+syn match autoitBuiltin "@SW_SHOWNA"
+syn match autoitBuiltin "@SW_SHOWNOACTIVATE"
+syn match autoitBuiltin "@SW_SHOWNORMAL"
+syn match autoitBuiltin "@SW_UNLOCK"
+syn match autoitBuiltin "@SystemDir"
+syn match autoitBuiltin "@TAB"
+syn match autoitBuiltin "@TempDir"
+syn match autoitBuiltin "@TRAY_ID"
+syn match autoitBuiltin "@TrayIconFlashing"
+syn match autoitBuiltin "@TrayIconVisible"
+syn match autoitBuiltin "@UserProfileDir"
+syn match autoitBuiltin "@UserName"
+syn match autoitBuiltin "@WDAY"
+syn match autoitBuiltin "@WindowsDir"
+syn match autoitBuiltin "@WorkingDir"
+syn match autoitBuiltin "@YDAY"
+syn match autoitBuiltin "@YEAR"
+
+"comments and commenting-out
+syn match autoitComment ";.*"
+"in this way also #ce alone will be highlighted
+syn match autoitCommDelimiter "^\s*#comments-start\>"
+syn match autoitCommDelimiter "^\s*#cs\>"
+syn match autoitCommDelimiter "^\s*#comments-end\>"
+syn match autoitCommDelimiter "^\s*#ce\>"
+syn region autoitComment
+	\ matchgroup=autoitCommDelimiter
+	\ start="^\s*#comments-start\>" start="^\s*#cs\>"
+	\ end="^\s*#comments-end\>" end="^\s*#ce\>"
+
+"one character operators
+syn match autoitOperator "[-+*/&^=<>][^-+*/&^=<>]"me=e-1
+"two characters operators
+syn match autoitOperator "==[^=]"me=e-1
+syn match autoitOperator "<>"
+syn match autoitOperator "<="
+syn match autoitOperator ">="
+syn match autoitOperator "+="
+syn match autoitOperator "-="
+syn match autoitOperator "*="
+syn match autoitOperator "/="
+syn match autoitOperator "&="
+syn keyword autoitOperator NOT AND OR
+
+syn match autoitParen "(\|)"
+syn match autoitBracket "\[\|\]"
+syn match autoitComma ","
+
+"numbers must come after operator '-'
+"decimal numbers without a dot
+syn match autoitNumber "-\=\<\d\+\>"
+"hexadecimal numbers without a dot
+syn match autoitNumber "-\=\<0x\x\+\>"
+"floating point number with dot (inside or at end)
+
+syn match autoitNumber "-\=\<\d\+\.\d*\>"
+"floating point number, starting with a dot
+syn match autoitNumber "-\=\<\.\d\+\>"
+"scientific notation numbers without dots
+syn match autoitNumber "-\=\<\d\+e[-+]\=\d\+\>"
+"scientific notation numbers with dots
+syn match autoitNumber "-\=\<\(\(\d\+\.\d*\)\|\(\.\d\+\)\)\(e[-+]\=\d\+\)\=\>"
+
+"string constants
+"we want the escaped quotes marked in red
+syn match autoitDoubledSingles +''+ contained
+syn match autoitDoubledDoubles +""+ contained
+"we want the continuation character marked in red
+"(also at the top level, not just contained)
+syn match autoitCont "_$"
+
+" send key list - must be defined before autoitStrings
+syn match autoitSend "{!}" contained
+syn match autoitSend "{#}" contained
+syn match autoitSend "{+}" contained
+syn match autoitSend "{^}" contained
+syn match autoitSend "{{}" contained
+syn match autoitSend "{}}" contained
+syn match autoitSend "{SPACE}" contained
+syn match autoitSend "{ENTER}" contained
+syn match autoitSend "{ALT}" contained
+syn match autoitSend "{BACKSPACE}" contained
+syn match autoitSend "{BS}" contained
+syn match autoitSend "{DELETE}" contained
+syn match autoitSend "{DEL}" contained
+syn match autoitSend "{UP}" contained
+syn match autoitSend "{DOWN}" contained
+syn match autoitSend "{LEFT}" contained
+syn match autoitSend "{RIGHT}" contained
+syn match autoitSend "{HOME}" contained
+syn match autoitSend "{END}" contained
+syn match autoitSend "{ESCAPE}" contained
+syn match autoitSend "{ESC}" contained
+syn match autoitSend "{INSERT}" contained
+syn match autoitSend "{INS}" contained
+syn match autoitSend "{PGUP}" contained
+syn match autoitSend "{PGDN}" contained
+syn match autoitSend "{F1}" contained
+syn match autoitSend "{F2}" contained
+syn match autoitSend "{F3}" contained
+syn match autoitSend "{F4}" contained
+syn match autoitSend "{F5}" contained
+syn match autoitSend "{F6}" contained
+syn match autoitSend "{F7}" contained
+syn match autoitSend "{F8}" contained
+syn match autoitSend "{F9}" contained
+syn match autoitSend "{F10}" contained
+syn match autoitSend "{F11}" contained
+syn match autoitSend "{F12}" contained
+syn match autoitSend "{TAB}" contained
+syn match autoitSend "{PRINTSCREEN}" contained
+syn match autoitSend "{LWIN}" contained
+syn match autoitSend "{RWIN}" contained
+syn match autoitSend "{NUMLOCK}" contained
+syn match autoitSend "{CTRLBREAK}" contained
+syn match autoitSend "{PAUSE}" contained
+syn match autoitSend "{CAPSLOCK}" contained
+syn match autoitSend "{NUMPAD0}" contained
+syn match autoitSend "{NUMPAD1}" contained
+syn match autoitSend "{NUMPAD2}" contained
+syn match autoitSend "{NUMPAD3}" contained
+syn match autoitSend "{NUMPAD4}" contained
+syn match autoitSend "{NUMPAD5}" contained
+syn match autoitSend "{NUMPAD6}" contained
+syn match autoitSend "{NUMPAD7}" contained
+syn match autoitSend "{NUMPAD8}" contained
+syn match autoitSend "{NUMPAD9}" contained
+syn match autoitSend "{NUMPADMULT}" contained
+syn match autoitSend "{NUMPADADD}" contained
+syn match autoitSend "{NUMPADSUB}" contained
+syn match autoitSend "{NUMPADDIV}" contained
+syn match autoitSend "{NUMPADDOT}" contained
+syn match autoitSend "{NUMPADENTER}" contained
+syn match autoitSend "{APPSKEY}" contained
+syn match autoitSend "{LALT}" contained
+syn match autoitSend "{RALT}" contained
+syn match autoitSend "{LCTRL}" contained
+syn match autoitSend "{RCTRL}" contained
+syn match autoitSend "{LSHIFT}" contained
+syn match autoitSend "{RSHIFT}" contained
+syn match autoitSend "{SLEEP}" contained
+syn match autoitSend "{ALTDOWN}" contained
+syn match autoitSend "{SHIFTDOWN}" contained
+syn match autoitSend "{CTRLDOWN}" contained
+syn match autoitSend "{LWINDOWN}" contained
+syn match autoitSend "{RWINDOWN}" contained
+syn match autoitSend "{ASC \d\d\d\d}" contained
+syn match autoitSend "{BROWSER_BACK}" contained
+syn match autoitSend "{BROWSER_FORWARD}" contained
+syn match autoitSend "{BROWSER_REFRESH}" contained
+syn match autoitSend "{BROWSER_STOP}" contained
+syn match autoitSend "{BROWSER_SEARCH}" contained
+syn match autoitSend "{BROWSER_FAVORITES}" contained
+syn match autoitSend "{BROWSER_HOME}" contained
+syn match autoitSend "{VOLUME_MUTE}" contained
+syn match autoitSend "{VOLUME_DOWN}" contained
+syn match autoitSend "{VOLUME_UP}" contained
+syn match autoitSend "{MEDIA_NEXT}" contained
+syn match autoitSend "{MEDIA_PREV}" contained
+syn match autoitSend "{MEDIA_STOP}" contained
+syn match autoitSend "{MEDIA_PLAY_PAUSE}" contained
+syn match autoitSend "{LAUNCH_MAIL}" contained
+syn match autoitSend "{LAUNCH_MEDIA}" contained
+syn match autoitSend "{LAUNCH_APP1}" contained
+syn match autoitSend "{LAUNCH_APP2}" contained
+
+"this was tricky!
+"we use an oneline region, instead of a match, in order to use skip=
+"matchgroup= so start and end quotes are not considered as au3Doubled
+"contained
+syn region autoitString oneline contains=autoitSend matchgroup=autoitQuote start=+"+
+	\ end=+"+ end=+_\n\{1}.*"+
+	\ contains=autoitCont,autoitDoubledDoubles skip=+""+
+syn region autoitString oneline matchgroup=autoitQuote start=+'+
+	\ end=+'+ end=+_\n\{1}.*'+
+	\ contains=autoitCont,autoitDoubledSingles skip=+''+
+
+syn match autoitVarSelector "\$"	contained display
+syn match autoitVariable "$\w\+" contains=autoitVarSelector
+
+" options - must be defined after autoitStrings
+syn match autoitOption "\([\"\']\)CaretCoordMode\1"
+syn match autoitOption "\([\"\']\)ColorMode\1"
+syn match autoitOption "\([\"\']\)ExpandEnvStrings\1"
+syn match autoitOption "\([\"\']\)ExpandVarStrings\1"
+syn match autoitOption "\([\"\']\)FtpBinaryMode\1"
+syn match autoitOption "\([\"\']\)GUICloseOnEsc\1"
+syn match autoitOption "\([\"\']\)GUICoordMode\1"
+syn match autoitOption "\([\"\']\)GUIDataSeparatorChar\1"
+syn match autoitOption "\([\"\']\)GUIOnEventMode\1"
+syn match autoitOption "\([\"\']\)GUIResizeMode\1"
+syn match autoitOption "\([\"\']\)GUIEventCompatibilityMode\1"
+syn match autoitOption "\([\"\']\)MouseClickDelay\1"
+syn match autoitOption "\([\"\']\)MouseClickDownDelay\1"
+syn match autoitOption "\([\"\']\)MouseClickDragDelay\1"
+syn match autoitOption "\([\"\']\)MouseCoordMode\1"
+syn match autoitOption "\([\"\']\)MustDeclareVars\1"
+syn match autoitOption "\([\"\']\)OnExitFunc\1"
+syn match autoitOption "\([\"\']\)PixelCoordMode\1"
+syn match autoitOption "\([\"\']\)RunErrorsFatal\1"
+syn match autoitOption "\([\"\']\)SendAttachMode\1"
+syn match autoitOption "\([\"\']\)SendCapslockMode\1"
+syn match autoitOption "\([\"\']\)SendKeyDelay\1"
+syn match autoitOption "\([\"\']\)SendKeyDownDelay\1"
+syn match autoitOption "\([\"\']\)TCPTimeout\1"
+syn match autoitOption "\([\"\']\)TrayAutoPause\1"
+syn match autoitOption "\([\"\']\)TrayIconDebug\1"
+syn match autoitOption "\([\"\']\)TrayIconHide\1"
+syn match autoitOption "\([\"\']\)TrayMenuMode\1"
+syn match autoitOption "\([\"\']\)TrayOnEventMode\1"
+syn match autoitOption "\([\"\']\)WinDetectHiddenText\1"
+syn match autoitOption "\([\"\']\)WinSearchChildren\1"
+syn match autoitOption "\([\"\']\)WinTextMatchMode\1"
+syn match autoitOption "\([\"\']\)WinTitleMatchMode\1"
+syn match autoitOption "\([\"\']\)WinWaitDelay\1"
+
+" styles - must be defined after autoitVariable
+" common
+syn match autoitStyle "\$WS_BORDER"
+syn match autoitStyle "\$WS_POPUP"
+syn match autoitStyle "\$WS_CAPTION"
+syn match autoitStyle "\$WS_CLIPCHILDREN"
+syn match autoitStyle "\$WS_CLIPSIBLINGS"
+syn match autoitStyle "\$WS_DISABLED"
+syn match autoitStyle "\$WS_DLGFRAME"
+syn match autoitStyle "\$WS_HSCROLL"
+syn match autoitStyle "\$WS_MAXIMIZE"
+syn match autoitStyle "\$WS_MAXIMIZEBOX"
+syn match autoitStyle "\$WS_MINIMIZE"
+syn match autoitStyle "\$WS_MINIMIZEBOX"
+syn match autoitStyle "\$WS_OVERLAPPED"
+syn match autoitStyle "\$WS_OVERLAPPEDWINDOW"
+syn match autoitStyle "\$WS_POPUPWINDOW"
+syn match autoitStyle "\$WS_SIZEBOX"
+syn match autoitStyle "\$WS_SYSMENU"
+syn match autoitStyle "\$WS_THICKFRAME"
+syn match autoitStyle "\$WS_VSCROLL"
+syn match autoitStyle "\$WS_VISIBLE"
+syn match autoitStyle "\$WS_CHILD"
+syn match autoitStyle "\$WS_GROUP"
+syn match autoitStyle "\$WS_TABSTOP"
+syn match autoitStyle "\$DS_MODALFRAME"
+syn match autoitStyle "\$DS_SETFOREGROUND"
+syn match autoitStyle "\$DS_CONTEXTHELP"
+" common extended
+syn match autoitStyle "\$WS_EX_ACCEPTFILES"
+syn match autoitStyle "\$WS_EX_APPWINDOW"
+syn match autoitStyle "\$WS_EX_CLIENTEDGE"
+syn match autoitStyle "\$WS_EX_CONTEXTHELP"
+syn match autoitStyle "\$WS_EX_DLGMODALFRAME"
+syn match autoitStyle "\$WS_EX_MDICHILD"
+syn match autoitStyle "\$WS_EX_OVERLAPPEDWINDOW"
+syn match autoitStyle "\$WS_EX_STATICEDGE"
+syn match autoitStyle "\$WS_EX_TOPMOST"
+syn match autoitStyle "\$WS_EX_TRANSPARENT"
+syn match autoitStyle "\$WS_EX_TOOLWINDOW"
+syn match autoitStyle "\$WS_EX_WINDOWEDGE"
+syn match autoitStyle "\$WS_EX_LAYERED"
+syn match autoitStyle "\$GUI_WS_EX_PARENTDRAG"
+" checkbox
+syn match autoitStyle "\$BS_3STATE"
+syn match autoitStyle "\$BS_AUTO3STATE"
+syn match autoitStyle "\$BS_AUTOCHECKBOX"
+syn match autoitStyle "\$BS_CHECKBOX"
+syn match autoitStyle "\$BS_LEFT"
+syn match autoitStyle "\$BS_PUSHLIKE"
+syn match autoitStyle "\$BS_RIGHT"
+syn match autoitStyle "\$BS_RIGHTBUTTON"
+syn match autoitStyle "\$BS_GROUPBOX"
+syn match autoitStyle "\$BS_AUTORADIOBUTTON"
+" push button
+syn match autoitStyle "\$BS_BOTTOM"
+syn match autoitStyle "\$BS_CENTER"
+syn match autoitStyle "\$BS_DEFPUSHBUTTON"
+syn match autoitStyle "\$BS_MULTILINE"
+syn match autoitStyle "\$BS_TOP"
+syn match autoitStyle "\$BS_VCENTER"
+syn match autoitStyle "\$BS_ICON"
+syn match autoitStyle "\$BS_BITMAP"
+syn match autoitStyle "\$BS_FLAT"
+" combo
+syn match autoitStyle "\$CBS_AUTOHSCROLL"
+syn match autoitStyle "\$CBS_DISABLENOSCROLL"
+syn match autoitStyle "\$CBS_DROPDOWN"
+syn match autoitStyle "\$CBS_DROPDOWNLIST"
+syn match autoitStyle "\$CBS_LOWERCASE"
+syn match autoitStyle "\$CBS_NOINTEGRALHEIGHT"
+syn match autoitStyle "\$CBS_OEMCONVERT"
+syn match autoitStyle "\$CBS_SIMPLE"
+syn match autoitStyle "\$CBS_SORT"
+syn match autoitStyle "\$CBS_UPPERCASE"
+" list
+syn match autoitStyle "\$LBS_DISABLENOSCROLL"
+syn match autoitStyle "\$LBS_NOINTEGRALHEIGHT"
+syn match autoitStyle "\$LBS_NOSEL"
+syn match autoitStyle "\$LBS_NOTIFY"
+syn match autoitStyle "\$LBS_SORT"
+syn match autoitStyle "\$LBS_STANDARD"
+syn match autoitStyle "\$LBS_USETABSTOPS"
+" edit/input
+syn match autoitStyle "\$ES_AUTOHSCROLL"
+syn match autoitStyle "\$ES_AUTOVSCROLL"
+syn match autoitStyle "\$ES_CENTER"
+syn match autoitStyle "\$ES_LOWERCASE"
+syn match autoitStyle "\$ES_NOHIDESEL"
+syn match autoitStyle "\$ES_NUMBER"
+syn match autoitStyle "\$ES_OEMCONVERT"
+syn match autoitStyle "\$ES_MULTILINE"
+syn match autoitStyle "\$ES_PASSWORD"
+syn match autoitStyle "\$ES_READONLY"
+syn match autoitStyle "\$ES_RIGHT"
+syn match autoitStyle "\$ES_UPPERCASE"
+syn match autoitStyle "\$ES_WANTRETURN"
+" progress bar
+syn match autoitStyle "\$PBS_SMOOTH"
+syn match autoitStyle "\$PBS_VERTICAL"
+" up-down
+syn match autoitStyle "\$UDS_ALIGNLEFT"
+syn match autoitStyle "\$UDS_ALIGNRIGHT"
+syn match autoitStyle "\$UDS_ARROWKEYS"
+syn match autoitStyle "\$UDS_HORZ"
+syn match autoitStyle "\$UDS_NOTHOUSANDS"
+syn match autoitStyle "\$UDS_WRAP"
+" label/static
+syn match autoitStyle "\$SS_BLACKFRAME"
+syn match autoitStyle "\$SS_BLACKRECT"
+syn match autoitStyle "\$SS_CENTER"
+syn match autoitStyle "\$SS_CENTERIMAGE"
+syn match autoitStyle "\$SS_ETCHEDFRAME"
+syn match autoitStyle "\$SS_ETCHEDHORZ"
+syn match autoitStyle "\$SS_ETCHEDVERT"
+syn match autoitStyle "\$SS_GRAYFRAME"
+syn match autoitStyle "\$SS_GRAYRECT"
+syn match autoitStyle "\$SS_LEFT"
+syn match autoitStyle "\$SS_LEFTNOWORDWRAP"
+syn match autoitStyle "\$SS_NOPREFIX"
+syn match autoitStyle "\$SS_NOTIFY"
+syn match autoitStyle "\$SS_RIGHT"
+syn match autoitStyle "\$SS_RIGHTJUST"
+syn match autoitStyle "\$SS_SIMPLE"
+syn match autoitStyle "\$SS_SUNKEN"
+syn match autoitStyle "\$SS_WHITEFRAME"
+syn match autoitStyle "\$SS_WHITERECT"
+" tab
+syn match autoitStyle "\$TCS_SCROLLOPPOSITE"
+syn match autoitStyle "\$TCS_BOTTOM"
+syn match autoitStyle "\$TCS_RIGHT"
+syn match autoitStyle "\$TCS_MULTISELECT"
+syn match autoitStyle "\$TCS_FLATBUTTONS"
+syn match autoitStyle "\$TCS_FORCEICONLEFT"
+syn match autoitStyle "\$TCS_FORCELABELLEFT"
+syn match autoitStyle "\$TCS_HOTTRACK"
+syn match autoitStyle "\$TCS_VERTICAL"
+syn match autoitStyle "\$TCS_TABS"
+syn match autoitStyle "\$TCS_BUTTONS"
+syn match autoitStyle "\$TCS_SINGLELINE"
+syn match autoitStyle "\$TCS_MULTILINE"
+syn match autoitStyle "\$TCS_RIGHTJUSTIFY"
+syn match autoitStyle "\$TCS_FIXEDWIDTH"
+syn match autoitStyle "\$TCS_RAGGEDRIGHT"
+syn match autoitStyle "\$TCS_FOCUSONBUTTONDOWN"
+syn match autoitStyle "\$TCS_OWNERDRAWFIXED"
+syn match autoitStyle "\$TCS_TOOLTIPS"
+syn match autoitStyle "\$TCS_FOCUSNEVER"
+" avi clip
+syn match autoitStyle "\$ACS_AUTOPLAY"
+syn match autoitStyle "\$ACS_CENTER"
+syn match autoitStyle "\$ACS_TRANSPARENT"
+syn match autoitStyle "\$ACS_NONTRANSPARENT"
+" date
+syn match autoitStyle "\$DTS_UPDOWN"
+syn match autoitStyle "\$DTS_SHOWNONE"
+syn match autoitStyle "\$DTS_LONGDATEFORMAT"
+syn match autoitStyle "\$DTS_TIMEFORMAT"
+syn match autoitStyle "\$DTS_RIGHTALIGN"
+syn match autoitStyle "\$DTS_SHORTDATEFORMAT"
+" monthcal
+syn match autoitStyle "\$MCS_NOTODAY"
+syn match autoitStyle "\$MCS_NOTODAYCIRCLE"
+syn match autoitStyle "\$MCS_WEEKNUMBERS"
+" treeview
+syn match autoitStyle "\$TVS_HASBUTTONS"
+syn match autoitStyle "\$TVS_HASLINES"
+syn match autoitStyle "\$TVS_LINESATROOT"
+syn match autoitStyle "\$TVS_DISABLEDRAGDROP"
+syn match autoitStyle "\$TVS_SHOWSELALWAYS"
+syn match autoitStyle "\$TVS_RTLREADING"
+syn match autoitStyle "\$TVS_NOTOOLTIPS"
+syn match autoitStyle "\$TVS_CHECKBOXES"
+syn match autoitStyle "\$TVS_TRACKSELECT"
+syn match autoitStyle "\$TVS_SINGLEEXPAND"
+syn match autoitStyle "\$TVS_FULLROWSELECT"
+syn match autoitStyle "\$TVS_NOSCROLL"
+syn match autoitStyle "\$TVS_NONEVENHEIGHT"
+" slider
+syn match autoitStyle "\$TBS_AUTOTICKS"
+syn match autoitStyle "\$TBS_BOTH"
+syn match autoitStyle "\$TBS_BOTTOM"
+syn match autoitStyle "\$TBS_HORZ"
+syn match autoitStyle "\$TBS_VERT"
+syn match autoitStyle "\$TBS_NOTHUMB"
+syn match autoitStyle "\$TBS_NOTICKS"
+syn match autoitStyle "\$TBS_LEFT"
+syn match autoitStyle "\$TBS_RIGHT"
+syn match autoitStyle "\$TBS_TOP"
+" listview
+syn match autoitStyle "\$LVS_ICON"
+syn match autoitStyle "\$LVS_REPORT"
+syn match autoitStyle "\$LVS_SMALLICON"
+syn match autoitStyle "\$LVS_LIST"
+syn match autoitStyle "\$LVS_EDITLABELS"
+syn match autoitStyle "\$LVS_NOCOLUMNHEADER"
+syn match autoitStyle "\$LVS_NOSORTHEADER"
+syn match autoitStyle "\$LVS_SINGLESEL"
+syn match autoitStyle "\$LVS_SHOWSELALWAYS"
+syn match autoitStyle "\$LVS_SORTASCENDING"
+syn match autoitStyle "\$LVS_SORTDESCENDING"
+" listview extended
+syn match autoitStyle "\$LVS_EX_FULLROWSELECT"
+syn match autoitStyle "\$LVS_EX_GRIDLINES"
+syn match autoitStyle "\$LVS_EX_HEADERDRAGDROP"
+syn match autoitStyle "\$LVS_EX_TRACKSELECT"
+syn match autoitStyle "\$LVS_EX_CHECKBOXES"
+syn match autoitStyle "\$LVS_EX_BORDERSELECT"
+syn match autoitStyle "\$LVS_EX_DOUBLEBUFFER"
+syn match autoitStyle "\$LVS_EX_FLATSB"
+syn match autoitStyle "\$LVS_EX_MULTIWORKAREAS"
+syn match autoitStyle "\$LVS_EX_SNAPTOGRID"
+syn match autoitStyle "\$LVS_EX_SUBITEMIMAGES"
+
+" constants - must be defined after autoitVariable - excludes styles
+" constants - autoit options
+syn match autoitConst "\$OPT_COORDSRELATIVE"
+syn match autoitConst "\$OPT_COORDSABSOLUTE"
+syn match autoitConst "\$OPT_COORDSCLIENT"
+syn match autoitConst "\$OPT_ERRORSILENT"
+syn match autoitConst "\$OPT_ERRORFATAL"
+syn match autoitConst "\$OPT_CAPSNOSTORE"
+syn match autoitConst "\$OPT_CAPSSTORE"
+syn match autoitConst "\$OPT_MATCHSTART"
+syn match autoitConst "\$OPT_MATCHANY"
+syn match autoitConst "\$OPT_MATCHEXACT"
+syn match autoitConst "\$OPT_MATCHADVANCED"
+" constants - file
+syn match autoitConst "\$FC_NOOVERWRITE"
+syn match autoitConst "\$FC_OVERWRITE"
+syn match autoitConst "\$FT_MODIFIED"
+syn match autoitConst "\$FT_CREATED"
+syn match autoitConst "\$FT_ACCESSED"
+syn match autoitConst "\$FO_READ"
+syn match autoitConst "\$FO_APPEND"
+syn match autoitConst "\$FO_OVERWRITE"
+syn match autoitConst "\$EOF"
+syn match autoitConst "\$FD_FILEMUSTEXIST"
+syn match autoitConst "\$FD_PATHMUSTEXIST"
+syn match autoitConst "\$FD_MULTISELECT"
+syn match autoitConst "\$FD_PROMPTCREATENEW"
+syn match autoitConst "\$FD_PROMPTOVERWRITE"
+" constants - keyboard
+syn match autoitConst "\$KB_SENDSPECIAL"
+syn match autoitConst "\$KB_SENDRAW"
+syn match autoitConst "\$KB_CAPSOFF"
+syn match autoitConst "\$KB_CAPSON"
+" constants - message box
+syn match autoitConst "\$MB_OK"
+syn match autoitConst "\$MB_OKCANCEL"
+syn match autoitConst "\$MB_ABORTRETRYIGNORE"
+syn match autoitConst "\$MB_YESNOCANCEL"
+syn match autoitConst "\$MB_YESNO"
+syn match autoitConst "\$MB_RETRYCANCEL"
+syn match autoitConst "\$MB_ICONHAND"
+syn match autoitConst "\$MB_ICONQUESTION"
+syn match autoitConst "\$MB_ICONEXCLAMATION"
+syn match autoitConst "\$MB_ICONASTERISK"
+syn match autoitConst "\$MB_DEFBUTTON1"
+syn match autoitConst "\$MB_DEFBUTTON2"
+syn match autoitConst "\$MB_DEFBUTTON3"
+syn match autoitConst "\$MB_APPLMODAL"
+syn match autoitConst "\$MB_SYSTEMMODAL"
+syn match autoitConst "\$MB_TASKMODAL"
+syn match autoitConst "\$MB_TOPMOST"
+syn match autoitConst "\$MB_RIGHTJUSTIFIED"
+syn match autoitConst "\$IDTIMEOUT"
+syn match autoitConst "\$IDOK"
+syn match autoitConst "\$IDCANCEL"
+syn match autoitConst "\$IDABORT"
+syn match autoitConst "\$IDRETRY"
+syn match autoitConst "\$IDIGNORE"
+syn match autoitConst "\$IDYES"
+syn match autoitConst "\$IDNO"
+syn match autoitConst "\$IDTRYAGAIN"
+syn match autoitConst "\$IDCONTINUE"
+" constants - progress and splash
+syn match autoitConst "\$DLG_NOTITLE"
+syn match autoitConst "\$DLG_NOTONTOP"
+syn match autoitConst "\$DLG_TEXTLEFT"
+syn match autoitConst "\$DLG_TEXTRIGHT"
+syn match autoitConst "\$DLG_MOVEABLE"
+syn match autoitConst "\$DLG_TEXTVCENTER"
+" constants - tray tip
+syn match autoitConst "\$TIP_ICONNONE"
+syn match autoitConst "\$TIP_ICONASTERISK"
+syn match autoitConst "\$TIP_ICONEXCLAMATION"
+syn match autoitConst "\$TIP_ICONHAND"
+syn match autoitConst "\$TIP_NOSOUND"
+" constants - mouse
+syn match autoitConst "\$IDC_UNKNOWN"
+syn match autoitConst "\$IDC_APPSTARTING"
+syn match autoitConst "\$IDC_ARROW"
+syn match autoitConst "\$IDC_CROSS"
+syn match autoitConst "\$IDC_HELP"
+syn match autoitConst "\$IDC_IBEAM"
+syn match autoitConst "\$IDC_ICON"
+syn match autoitConst "\$IDC_NO"
+syn match autoitConst "\$IDC_SIZE"
+syn match autoitConst "\$IDC_SIZEALL"
+syn match autoitConst "\$IDC_SIZENESW"
+syn match autoitConst "\$IDC_SIZENS"
+syn match autoitConst "\$IDC_SIZENWSE"
+syn match autoitConst "\$IDC_SIZEWE"
+syn match autoitConst "\$IDC_UPARROW"
+syn match autoitConst "\$IDC_WAIT"
+" constants - process
+syn match autoitConst "\$SD_LOGOFF"
+syn match autoitConst "\$SD_SHUTDOWN"
+syn match autoitConst "\$SD_REBOOT"
+syn match autoitConst "\$SD_FORCE"
+syn match autoitConst "\$SD_POWERDOWN"
+" constants - string
+syn match autoitConst "\$STR_NOCASESENSE"
+syn match autoitConst "\$STR_CASESENSE"
+syn match autoitConst "\STR_STRIPLEADING"
+syn match autoitConst "\$STR_STRIPTRAILING"
+syn match autoitConst "\$STR_STRIPSPACES"
+syn match autoitConst "\$STR_STRIPALL"
+" constants - tray
+syn match autoitConst "\$TRAY_ITEM_EXIT"
+syn match autoitConst "\$TRAY_ITEM_PAUSE"
+syn match autoitConst "\$TRAY_ITEM_FIRST"
+syn match autoitConst "\$TRAY_CHECKED"
+syn match autoitConst "\$TRAY_UNCHECKED"
+syn match autoitConst "\$TRAY_ENABLE"
+syn match autoitConst "\$TRAY_DISABLE"
+syn match autoitConst "\$TRAY_FOCUS"
+syn match autoitConst "\$TRAY_DEFAULT"
+syn match autoitConst "\$TRAY_EVENT_SHOWICON"
+syn match autoitConst "\$TRAY_EVENT_HIDEICON"
+syn match autoitConst "\$TRAY_EVENT_FLASHICON"
+syn match autoitConst "\$TRAY_EVENT_NOFLASHICON"
+syn match autoitConst "\$TRAY_EVENT_PRIMARYDOWN"
+syn match autoitConst "\$TRAY_EVENT_PRIMARYUP"
+syn match autoitConst "\$TRAY_EVENT_SECONDARYDOWN"
+syn match autoitConst "\$TRAY_EVENT_SECONDARYUP"
+syn match autoitConst "\$TRAY_EVENT_MOUSEOVER"
+syn match autoitConst "\$TRAY_EVENT_MOUSEOUT"
+syn match autoitConst "\$TRAY_EVENT_PRIMARYDOUBLE"
+syn match autoitConst "\$TRAY_EVENT_SECONDARYDOUBLE"
+" constants - stdio
+syn match autoitConst "\$STDIN_CHILD"
+syn match autoitConst "\$STDOUT_CHILD"
+syn match autoitConst "\$STDERR_CHILD"
+" constants - color
+syn match autoitConst "\$COLOR_BLACK"
+syn match autoitConst "\$COLOR_SILVER"
+syn match autoitConst "\$COLOR_GRAY"
+syn match autoitConst "\$COLOR_WHITE"
+syn match autoitConst "\$COLOR_MAROON"
+syn match autoitConst "\$COLOR_RED"
+syn match autoitConst "\$COLOR_PURPLE"
+syn match autoitConst "\$COLOR_FUCHSIA"
+syn match autoitConst "\$COLOR_GREEN"
+syn match autoitConst "\$COLOR_LIME"
+syn match autoitConst "\$COLOR_OLIVE"
+syn match autoitConst "\$COLOR_YELLOW"
+syn match autoitConst "\$COLOR_NAVY"
+syn match autoitConst "\$COLOR_BLUE"
+syn match autoitConst "\$COLOR_TEAL"
+syn match autoitConst "\$COLOR_AQUA"
+" constants - reg value type
+syn match autoitConst "\$REG_NONE"
+syn match autoitConst "\$REG_SZ"
+syn match autoitConst "\$REG_EXPAND_SZ"
+syn match autoitConst "\$REG_BINARY"
+syn match autoitConst "\$REG_DWORD"
+syn match autoitConst "\$REG_DWORD_BIG_ENDIAN"
+syn match autoitConst "\$REG_LINK"
+syn match autoitConst "\$REG_MULTI_SZ"
+syn match autoitConst "\$REG_RESOURCE_LIST"
+syn match autoitConst "\$REG_FULL_RESOURCE_DESCRIPTOR"
+syn match autoitConst "\$REG_RESOURCE_REQUIREMENTS_LIST"
+" guiconstants - events and messages
+syn match autoitConst "\$GUI_EVENT_CLOSE"
+syn match autoitConst "\$GUI_EVENT_MINIMIZE"
+syn match autoitConst "\$GUI_EVENT_RESTORE"
+syn match autoitConst "\$GUI_EVENT_MAXIMIZE"
+syn match autoitConst "\$GUI_EVENT_PRIMARYDOWN"
+syn match autoitConst "\$GUI_EVENT_PRIMARYUP"
+syn match autoitConst "\$GUI_EVENT_SECONDARYDOWN"
+syn match autoitConst "\$GUI_EVENT_SECONDARYUP"
+syn match autoitConst "\$GUI_EVENT_MOUSEMOVE"
+syn match autoitConst "\$GUI_EVENT_RESIZED"
+syn match autoitConst "\$GUI_EVENT_DROPPED"
+syn match autoitConst "\$GUI_RUNDEFMSG"
+" guiconstants - state
+syn match autoitConst "\$GUI_AVISTOP"
+syn match autoitConst "\$GUI_AVISTART"
+syn match autoitConst "\$GUI_AVICLOSE"
+syn match autoitConst "\$GUI_CHECKED"
+syn match autoitConst "\$GUI_INDETERMINATE"
+syn match autoitConst "\$GUI_UNCHECKED"
+syn match autoitConst "\$GUI_DROPACCEPTED"
+syn match autoitConst "\$GUI_DROPNOTACCEPTED"
+syn match autoitConst "\$GUI_ACCEPTFILES"
+syn match autoitConst "\$GUI_SHOW"
+syn match autoitConst "\$GUI_HIDE"
+syn match autoitConst "\$GUI_ENABLE"
+syn match autoitConst "\$GUI_DISABLE"
+syn match autoitConst "\$GUI_FOCUS"
+syn match autoitConst "\$GUI_NOFOCUS"
+syn match autoitConst "\$GUI_DEFBUTTON"
+syn match autoitConst "\$GUI_EXPAND"
+syn match autoitConst "\$GUI_ONTOP"
+" guiconstants - font
+syn match autoitConst "\$GUI_FONTITALIC"
+syn match autoitConst "\$GUI_FONTUNDER"
+syn match autoitConst "\$GUI_FONTSTRIKE"
+" guiconstants - resizing
+syn match autoitConst "\$GUI_DOCKAUTO"
+syn match autoitConst "\$GUI_DOCKLEFT"
+syn match autoitConst "\$GUI_DOCKRIGHT"
+syn match autoitConst "\$GUI_DOCKHCENTER"
+syn match autoitConst "\$GUI_DOCKTOP"
+syn match autoitConst "\$GUI_DOCKBOTTOM"
+syn match autoitConst "\$GUI_DOCKVCENTER"
+syn match autoitConst "\$GUI_DOCKWIDTH"
+syn match autoitConst "\$GUI_DOCKHEIGHT"
+syn match autoitConst "\$GUI_DOCKSIZE"
+syn match autoitConst "\$GUI_DOCKMENUBAR"
+syn match autoitConst "\$GUI_DOCKSTATEBAR"
+syn match autoitConst "\$GUI_DOCKALL"
+syn match autoitConst "\$GUI_DOCKBORDERS"
+" guiconstants - graphic
+syn match autoitConst "\$GUI_GR_CLOSE"
+syn match autoitConst "\$GUI_GR_LINE"
+syn match autoitConst "\$GUI_GR_BEZIER"
+syn match autoitConst "\$GUI_GR_MOVE"
+syn match autoitConst "\$GUI_GR_COLOR"
+syn match autoitConst "\$GUI_GR_RECT"
+syn match autoitConst "\$GUI_GR_ELLIPSE"
+syn match autoitConst "\$GUI_GR_PIE"
+syn match autoitConst "\$GUI_GR_DOT"
+syn match autoitConst "\$GUI_GR_PIXEL"
+syn match autoitConst "\$GUI_GR_HINT"
+syn match autoitConst "\$GUI_GR_REFRESH"
+syn match autoitConst "\$GUI_GR_PENSIZE"
+syn match autoitConst "\$GUI_GR_NOBKCOLOR"
+" guiconstants - control default styles
+syn match autoitConst "\$GUI_SS_DEFAULT_AVI"
+syn match autoitConst "\$GUI_SS_DEFAULT_BUTTON"
+syn match autoitConst "\$GUI_SS_DEFAULT_CHECKBOX"
+syn match autoitConst "\$GUI_SS_DEFAULT_COMBO"
+syn match autoitConst "\$GUI_SS_DEFAULT_DATE"
+syn match autoitConst "\$GUI_SS_DEFAULT_EDIT"
+syn match autoitConst "\$GUI_SS_DEFAULT_GRAPHIC"
+syn match autoitConst "\$GUI_SS_DEFAULT_GROUP"
+syn match autoitConst "\$GUI_SS_DEFAULT_ICON"
+syn match autoitConst "\$GUI_SS_DEFAULT_INPUT"
+syn match autoitConst "\$GUI_SS_DEFAULT_LABEL"
+syn match autoitConst "\$GUI_SS_DEFAULT_LIST"
+syn match autoitConst "\$GUI_SS_DEFAULT_LISTVIEW"
+syn match autoitConst "\$GUI_SS_DEFAULT_MONTHCAL"
+syn match autoitConst "\$GUI_SS_DEFAULT_PIC"
+syn match autoitConst "\$GUI_SS_DEFAULT_PROGRESS"
+syn match autoitConst "\$GUI_SS_DEFAULT_RADIO"
+syn match autoitConst "\$GUI_SS_DEFAULT_SLIDER"
+syn match autoitConst "\$GUI_SS_DEFAULT_TAB"
+syn match autoitConst "\$GUI_SS_DEFAULT_TREEVIEW"
+syn match autoitConst "\$GUI_SS_DEFAULT_UPDOWN"
+syn match autoitConst "\$GUI_SS_DEFAULT_GUI"
+" guiconstants - background color special flags
+syn match autoitConst "\$GUI_BKCOLOR_DEFAULT"
+syn match autoitConst "\$GUI_BKCOLOR_LV_ALTERNATE"
+syn match autoitConst "\$GUI_BKCOLOR_TRANSPARENT"
+
+" registry constants
+syn match autoitConst "\([\"\']\)REG_BINARY\1"
+syn match autoitConst "\([\"\']\)REG_SZ\1"
+syn match autoitConst "\([\"\']\)REG_MULTI_SZ\1"
+syn match autoitConst "\([\"\']\)REG_EXPAND_SZ\1"
+syn match autoitConst "\([\"\']\)REG_DWORD\1"
+
+" Define the default highlighting.
+" Unused colors: Underlined, Ignore, Error, Todo
+hi def link autoitFunction Statement  " yellow/yellow
+hi def link autoitKeyword Statement
+hi def link autoitOperator Operator
+hi def link autoitVarSelector Operator
+hi def link autoitComment	Comment  " cyan/blue
+hi def link autoitParen Comment
+hi def link autoitComma Comment
+hi def link autoitBracket Comment
+hi def link autoitNumber Constant " magenta/red
+hi def link autoitString Constant
+hi def link autoitQuote Constant
+hi def link autoitIncluded Constant
+hi def link autoitCont Special  " red/orange
+hi def link autoitDoubledSingles Special
+hi def link autoitDoubledDoubles Special
+hi def link autoitCommDelimiter PreProc  " blue/magenta
+hi def link autoitInclude PreProc
+hi def link autoitVariable Identifier  " cyan/cyan
+hi def link autoitBuiltin Type  " green/green
+hi def link autoitOption Type
+hi def link autoitStyle Type
+hi def link autoitConst Type
+hi def link autoitSend Type
+syn sync minlines=50
--- /dev/null
+++ b/lib/vimfiles/syntax/automake.vim
@@ -1,0 +1,87 @@
+" Vim syntax file
+" Language: automake Makefile.am
+" Maintainer: Felipe Contreras <felipe.contreras@gmail.com>
+" Former Maintainer: John Williams <jrw@pobox.com>
+" Last Change: $LastChangedDate: 2006-04-16 22:06:40 -0400 (dom, 16 apr 2006) $
+" URL: http://svn.debian.org/wsvn/pkg-vim/trunk/runtime/syntax/automake.vim?op=file&rev=0&sc=0
+"
+" This script adds support for automake's Makefile.am format. It highlights
+" Makefile variables significant to automake as well as highlighting
+" autoconf-style @variable@ substitutions . Subsitutions are marked as errors
+" when they are used in an inappropriate place, such as in defining
+" EXTRA_SOURCES.
+
+
+" Read the Makefile syntax to start with
+if version < 600
+  source <sfile>:p:h/make.vim
+else
+  runtime! syntax/make.vim
+endif
+
+syn match automakePrimary "^[A-Za-z0-9_]\+_\(PROGRAMS\|LIBRARIES\|LISP\|PYTHON\|JAVA\|SCRIPTS\|DATA\|HEADERS\|MANS\|TEXINFOS\|LTLIBRARIES\)\s*="me=e-1
+
+syn match automakeSecondary "^[A-Za-z0-9_]\+_\(SOURCES\|AR\|LIBADD\|LDADD\|LDFLAGS\|DEPENDENCIES\|LINK\|SHORTNAME\)\s*="me=e-1
+syn match automakeSecondary "^[A-Za-z0-9_]\+_\(CCASFLAGS\|CFLAGS\|CPPFLAGS\|CXXFLAGS\|FFLAGS\|GCJFLAGS\|LFLAGS\|OBJCFLAGS\|RFLAGS\|YFLAGS\)\s*="me=e-1
+
+syn match automakeExtra "^EXTRA_DIST\s*="me=e-1
+syn match automakeExtra "^EXTRA_PROGRAMS\s*="me=e-1
+syn match automakeExtra "^EXTRA_[A-Za-z0-9_]\+_SOURCES\s*="me=e-1
+
+" TODO: Check these:
+syn match automakePrimary "^TESTS\s*="me=e-1
+syn match automakeSecondary "^OMIT_DEPENDENCIES\s*="me=e-1
+syn match automakeOptions "^\(AUTOMAKE_OPTIONS\|ETAGS_ARGS\|TAGS_DEPENDENCIES\)\s*="me=e-1
+syn match automakeClean "^\(MOSTLY\|DIST\|MAINTAINER\)\=CLEANFILES\s*="me=e-1
+syn match automakeSubdirs "^\(DIST_\)\=SUBDIRS\s*="me=e-1
+syn match automakeConditional "^\(if\s*[a-zA-Z0-9_]\+\|else\|endif\)\s*$"
+
+syn match automakeSubst     "@[a-zA-Z0-9_]\+@"
+syn match automakeSubst     "^\s*@[a-zA-Z0-9_]\+@"
+syn match automakeComment1 "#.*$" contains=automakeSubst
+syn match automakeComment2 "##.*$"
+
+syn match automakeMakeError "$[{(][^})]*[^a-zA-Z0-9_})][^})]*[})]" " GNU make function call
+
+syn region automakeNoSubst start="^EXTRA_[a-zA-Z0-9_]*\s*=" end="$" contains=ALLBUT,automakeNoSubst transparent
+syn region automakeNoSubst start="^DIST_SUBDIRS\s*=" end="$" contains=ALLBUT,automakeNoSubst transparent
+syn region automakeNoSubst start="^[a-zA-Z0-9_]*_SOURCES\s*=" end="$" contains=ALLBUT,automakeNoSubst transparent
+syn match automakeBadSubst  "@\([a-zA-Z0-9_]*@\=\)\=" contained
+
+syn region  automakeMakeDString start=+"+  skip=+\\"+  end=+"+  contains=makeIdent,automakeSubstitution
+syn region  automakeMakeSString start=+'+  skip=+\\'+  end=+'+  contains=makeIdent,automakeSubstitution
+syn region  automakeMakeBString start=+`+  skip=+\\`+  end=+`+  contains=makeIdent,makeSString,makeDString,makeNextLine,automakeSubstitution
+
+" Define the default highlighting.
+" For version 5.7 and earlier: only when not done already
+" For version 5.8 and later: only when an item doesn't have highlighting yet
+if version >= 508 || !exists("did_automake_syntax_inits")
+  if version < 508
+    let did_automake_syntax_inits = 1
+    command -nargs=+ HiLink hi link <args>
+  else
+    command -nargs=+ HiLink hi def link <args>
+  endif
+
+  HiLink automakePrimary     Statement
+  HiLink automakeSecondary   Type
+  HiLink automakeExtra       Special
+  HiLink automakeOptions     Special
+  HiLink automakeClean       Special
+  HiLink automakeSubdirs     Statement
+  HiLink automakeConditional PreProc
+  HiLink automakeSubst       PreProc
+  HiLink automakeComment1    makeComment
+  HiLink automakeComment2    makeComment
+  HiLink automakeMakeError   makeError
+  HiLink automakeBadSubst    makeError
+  HiLink automakeMakeDString makeDString
+  HiLink automakeMakeSString makeSString
+  HiLink automakeMakeBString makeBString
+
+  delcommand HiLink
+endif
+
+let b:current_syntax = "automake"
+
+" vi: ts=8 sw=4 sts=4
--- /dev/null
+++ b/lib/vimfiles/syntax/ave.vim
@@ -1,0 +1,92 @@
+" Vim syntax file
+" Copyright by Jan-Oliver Wagner
+" Language:	avenue
+" Maintainer:	Jan-Oliver Wagner <Jan-Oliver.Wagner@intevation.de>
+" Last change:	2001 May 10
+
+" Avenue is the ArcView built-in language. ArcView is
+" a desktop GIS by ESRI. Though it is a built-in language
+" and a built-in editor is provided, the use of VIM increases
+" development speed.
+" I use some technologies to automatically load avenue scripts
+" into ArcView.
+
+" For version 5.x: Clear all syntax items
+" For version 6.x: Quit when a syntax file was already loaded
+if version < 600
+  syntax clear
+elseif exists("b:current_syntax")
+  finish
+endif
+
+" Avenue is entirely case-insensitive.
+syn case ignore
+
+" The keywords
+
+syn keyword aveStatement	if then elseif else end break exit return
+syn keyword aveStatement	for each in continue while
+
+" String
+
+syn region aveString		start=+"+ end=+"+
+
+" Integer number
+syn match  aveNumber		"[+-]\=\<[0-9]\+\>"
+
+" Operator
+
+syn keyword aveOperator		or and max min xor mod by
+" 'not' is a kind of a problem: Its an Operator as well as a method
+" 'not' is only marked as an Operator if not applied as method
+syn match aveOperator		"[^\.]not[^a-zA-Z]"
+
+" Variables
+
+syn keyword aveFixVariables	av nil self false true nl tab cr tab
+syn match globalVariables	"_[a-zA-Z][a-zA-Z0-9]*"
+syn match aveVariables		"[a-zA-Z][a-zA-Z0-9_]*"
+syn match aveConst		"#[A-Z][A-Z_]+"
+
+" Comments
+
+syn match aveComment	"'.*"
+
+" Typical Typos
+
+" for C programmers:
+syn match aveTypos	"=="
+syn match aveTypos	"!="
+
+" Define the default highlighting.
+" For version 5.7 and earlier: only when not done already
+" For version 5.8 and later: only when an item doesn't have highlighting+yet
+if version >= 508 || !exists("did_ave_syn_inits")
+  if version < 508
+	let did_ave_syn_inits = 1
+	command -nargs=+ HiLink hi link <args>
+  else
+	command -nargs=+ HiLink hi def link <args>
+  endif
+
+  HiLink aveStatement		Statement
+
+  HiLink aveString		String
+  HiLink aveNumber		Number
+
+  HiLink aveFixVariables	Special
+  HiLink aveVariables		Identifier
+  HiLink globalVariables	Special
+  HiLink aveConst		Special
+
+  HiLink aveClassMethods	Function
+
+  HiLink aveOperator		Operator
+  HiLink aveComment		Comment
+
+  HiLink aveTypos		Error
+
+  delcommand HiLink
+endif
+
+let b:current_syntax = "ave"
--- /dev/null
+++ b/lib/vimfiles/syntax/awk.vim
@@ -1,0 +1,216 @@
+" Vim syntax file
+" Language:	awk, nawk, gawk, mawk
+" Maintainer:	Antonio Colombo <azc10@yahoo.com>
+" Last Change:	2005 Mar 16
+
+" AWK  ref.  is: Alfred V. Aho, Brian W. Kernighan, Peter J. Weinberger
+" The AWK Programming Language, Addison-Wesley, 1988
+
+" GAWK ref. is: Arnold D. Robbins
+" Effective AWK Programming, Third Edition, O'Reilly, 2001
+
+" MAWK is a "new awk" meaning it implements AWK ref.
+" mawk conforms to the Posix 1003.2 (draft 11.3)
+" definition of the AWK language which contains a few features
+" not described in the AWK book, and mawk provides a small number of extensions.
+
+" TODO:
+" Dig into the commented out syntax expressions below.
+
+" For version 5.x: Clear all syntax items
+" For version 6.x: Quit when a syntax file was already loaded
+if version < 600
+  syn clear
+elseif exists("b:current_syntax")
+  finish
+endif
+
+" A bunch of useful Awk keywords
+" AWK  ref. p. 188
+syn keyword awkStatement	break continue delete exit
+syn keyword awkStatement	function getline next
+syn keyword awkStatement	print printf return
+" GAWK ref. p. 117
+syn keyword awkStatement	nextfile
+" AWK  ref. p. 42, GAWK ref. p. 142-166
+syn keyword awkFunction	atan2 close cos exp fflush int log rand sin sqrt srand
+syn keyword awkFunction	gsub index length match split sprintf sub
+syn keyword awkFunction	substr system
+" GAWK ref. p. 142-166
+syn keyword awkFunction	asort gensub mktime strftime strtonum systime
+syn keyword awkFunction	tolower toupper
+syn keyword awkFunction	and or xor compl lshift rshift
+syn keyword awkFunction	dcgettext bindtextdomain
+
+syn keyword awkConditional	if else
+syn keyword awkRepeat	while for
+
+syn keyword awkTodo		contained TODO
+
+syn keyword awkPatterns	BEGIN END
+" AWK  ref. p. 36
+syn keyword awkVariables	ARGC ARGV FILENAME FNR FS NF NR
+syn keyword awkVariables	OFMT OFS ORS RLENGTH RS RSTART SUBSEP
+" GAWK ref. p. 120-126
+syn keyword awkVariables	ARGIND BINMODE CONVFMT ENVIRON ERRNO
+syn keyword awkVariables	FIELDWIDTHS IGNORECASE LINT PROCINFO
+syn keyword awkVariables	RT RLENGTH TEXTDOMAIN
+
+syn keyword awkRepeat	do
+
+" Octal format character.
+syn match   awkSpecialCharacter display contained "\\[0-7]\{1,3\}"
+syn keyword awkStatement	func nextfile
+" Hex   format character.
+syn match   awkSpecialCharacter display contained "\\x[0-9A-Fa-f]\+"
+
+syn match   awkFieldVars	"\$\d\+"
+
+"catch errors caused by wrong parenthesis
+syn region	awkParen	transparent start="(" end=")" contains=ALLBUT,awkParenError,awkSpecialCharacter,awkArrayElement,awkArrayArray,awkTodo,awkRegExp,awkBrktRegExp,awkBrackets,awkCharClass
+syn match	awkParenError	display ")"
+syn match	awkInParen	display contained "[{}]"
+
+" 64 lines for complex &&'s, and ||'s in a big "if"
+syn sync ccomment awkParen maxlines=64
+
+" Search strings & Regular Expressions therein.
+syn region  awkSearch	oneline start="^[ \t]*/"ms=e start="\(,\|!\=\~\)[ \t]*/"ms=e skip="\\\\\|\\/" end="/" contains=awkBrackets,awkRegExp,awkSpecialCharacter
+syn region  awkBrackets	contained start="\[\^\]\="ms=s+2 start="\[[^\^]"ms=s+1 end="\]"me=e-1 contains=awkBrktRegExp,awkCharClass
+syn region  awkSearch	oneline start="[ \t]*/"hs=e skip="\\\\\|\\/" end="/" contains=awkBrackets,awkRegExp,awkSpecialCharacter
+
+syn match   awkCharClass	contained "\[:[^:\]]*:\]"
+syn match   awkBrktRegExp	contained "\\.\|.\-[^]]"
+syn match   awkRegExp	contained "/\^"ms=s+1
+syn match   awkRegExp	contained "\$/"me=e-1
+syn match   awkRegExp	contained "[?.*{}|+]"
+
+" String and Character constants
+" Highlight special characters (those which have a backslash) differently
+syn region  awkString	start=+"+  skip=+\\\\\|\\"+  end=+"+  contains=awkSpecialCharacter,awkSpecialPrintf
+syn match   awkSpecialCharacter contained "\\."
+
+" Some of these combinations may seem weird, but they work.
+syn match   awkSpecialPrintf	contained "%[-+ #]*\d*\.\=\d*[cdefgiosuxEGX%]"
+
+" Numbers, allowing signs (both -, and +)
+" Integer number.
+syn match  awkNumber		display "[+-]\=\<\d\+\>"
+" Floating point number.
+syn match  awkFloat		display "[+-]\=\<\d\+\.\d+\>"
+" Floating point number, starting with a dot.
+syn match  awkFloat		display "[+-]\=\<.\d+\>"
+syn case ignore
+"floating point number, with dot, optional exponent
+syn match  awkFloat	display "\<\d\+\.\d*\(e[-+]\=\d\+\)\=\>"
+"floating point number, starting with a dot, optional exponent
+syn match  awkFloat	display "\.\d\+\(e[-+]\=\d\+\)\=\>"
+"floating point number, without dot, with exponent
+syn match  awkFloat	display "\<\d\+e[-+]\=\d\+\>"
+syn case match
+
+"syn match  awkIdentifier	"\<[a-zA-Z_][a-zA-Z0-9_]*\>"
+
+" Arithmetic operators: +, and - take care of ++, and --
+"syn match   awkOperator	"+\|-\|\*\|/\|%\|="
+"syn match   awkOperator	"+=\|-=\|\*=\|/=\|%="
+"syn match   awkOperator	"^\|^="
+
+" Comparison expressions.
+"syn match   awkExpression	"==\|>=\|=>\|<=\|=<\|\!="
+"syn match   awkExpression	"\~\|\!\~"
+"syn match   awkExpression	"?\|:"
+"syn keyword awkExpression	in
+
+" Boolean Logic (OR, AND, NOT)
+"syn match  awkBoolLogic	"||\|&&\|\!"
+
+" This is overridden by less-than & greater-than.
+" Put this above those to override them.
+" Put this in a 'match "\<printf\=\>.*;\="' to make it not override
+" less/greater than (most of the time), but it won't work yet because
+" keywords allways have precedence over match & region.
+" File I/O: (print foo, bar > "filename") & for nawk (getline < "filename")
+"syn match  awkFileIO		contained ">"
+"syn match  awkFileIO		contained "<"
+
+" Expression separators: ';' and ','
+syn match  awkSemicolon	";"
+syn match  awkComma		","
+
+syn match  awkComment	"#.*" contains=awkTodo
+
+syn match  awkLineSkip	"\\$"
+
+" Highlight array element's (recursive arrays allowed).
+" Keeps nested array names' separate from normal array elements.
+" Keeps numbers separate from normal array elements (variables).
+syn match  awkArrayArray	contained "[^][, \t]\+\["me=e-1
+syn match  awkArrayElement      contained "[^][, \t]\+"
+syn region awkArray		transparent start="\[" end="\]" contains=awkArray,awkArrayElement,awkArrayArray,awkNumber,awkFloat
+
+" 10 should be enough.
+" (for the few instances where it would be more than "oneline")
+syn sync ccomment awkArray maxlines=10
+
+" define the default highlighting
+" For version 5.7 and earlier: only when not done already
+" For version 5.8 and later: only when an item doesn't have highlightling yet
+if version >= 508 || !exists("did_awk_syn_inits")
+  if version < 508
+    let did_awk_syn_inits = 1
+    command -nargs=+ HiLink hi link <args>
+  else
+    command -nargs=+ HiLink hi def link <args>
+  endif
+
+  HiLink awkConditional		Conditional
+  HiLink awkFunction		Function
+  HiLink awkRepeat		Repeat
+  HiLink awkStatement		Statement
+
+  HiLink awkString		String
+  HiLink awkSpecialPrintf	Special
+  HiLink awkSpecialCharacter	Special
+
+  HiLink awkSearch		String
+  HiLink awkBrackets		awkRegExp
+  HiLink awkBrktRegExp		awkNestRegExp
+  HiLink awkCharClass		awkNestRegExp
+  HiLink awkNestRegExp		Keyword
+  HiLink awkRegExp		Special
+
+  HiLink awkNumber		Number
+  HiLink awkFloat		Float
+
+  HiLink awkFileIO		Special
+  "HiLink awkOperator		Special
+  "HiLink awkExpression		Special
+  HiLink awkBoolLogic		Special
+
+  HiLink awkPatterns		Special
+  HiLink awkVariables		Special
+  HiLink awkFieldVars		Special
+
+  HiLink awkLineSkip		Special
+  HiLink awkSemicolon		Special
+  HiLink awkComma		Special
+  "HiLink awkIdentifier		Identifier
+
+  HiLink awkComment		Comment
+  HiLink awkTodo		Todo
+
+  " Change this if you want nested array names to be highlighted.
+  HiLink awkArrayArray		awkArray
+  HiLink awkArrayElement	Special
+
+  HiLink awkParenError		awkError
+  HiLink awkInParen		awkError
+  HiLink awkError		Error
+
+  delcommand HiLink
+endif
+
+let b:current_syntax = "awk"
+
+" vim: ts=8
--- /dev/null
+++ b/lib/vimfiles/syntax/ayacc.vim
@@ -1,0 +1,86 @@
+" Vim syntax file
+" Language:	AYacc
+" Maintainer:	Mathieu Clabaut <mathieu.clabaut@free.fr>
+" LastChange:	02 May 2001
+" Original:	Yacc, maintained by Dr. Charles E. Campbell, Jr.
+" Comment:	     Replaced sourcing c.vim file by ada.vim and rename yacc*
+"		in ayacc*
+
+" For version 5.x: Clear all syntax items
+" For version 6.x: Quit when a syntax file was already loaded
+if version < 600
+   syntax clear
+elseif exists("b:current_syntax")
+   finish
+endif
+
+" Read the Ada syntax to start with
+if version < 600
+   so <sfile>:p:h/ada.vim
+else
+   runtime! syntax/ada.vim
+   unlet b:current_syntax
+endif
+
+" Clusters
+syn cluster	ayaccActionGroup	contains=ayaccDelim,cInParen,cTodo,cIncluded,ayaccDelim,ayaccCurlyError,ayaccUnionCurly,ayaccUnion,cUserLabel,cOctalZero,cCppOut2,cCppSkip,cErrInBracket,cErrInParen,cOctalError
+syn cluster	ayaccUnionGroup	contains=ayaccKey,cComment,ayaccCurly,cType,cStructure,cStorageClass,ayaccUnionCurly
+
+" Yacc stuff
+syn match	ayaccDelim	"^[ \t]*[:|;]"
+syn match	ayaccOper	"@\d\+"
+
+syn match	ayaccKey	"^[ \t]*%\(token\|type\|left\|right\|start\|ident\)\>"
+syn match	ayaccKey	"[ \t]%\(prec\|expect\|nonassoc\)\>"
+syn match	ayaccKey	"\$\(<[a-zA-Z_][a-zA-Z_0-9]*>\)\=[\$0-9]\+"
+syn keyword	ayaccKeyActn	yyerrok yyclearin
+
+syn match	ayaccUnionStart	"^%union"	skipwhite skipnl nextgroup=ayaccUnion
+syn region	ayaccUnion	contained matchgroup=ayaccCurly start="{" matchgroup=ayaccCurly end="}"	contains=@ayaccUnionGroup
+syn region	ayaccUnionCurly	contained matchgroup=ayaccCurly start="{" matchgroup=ayaccCurly end="}" contains=@ayaccUnionGroup
+syn match	ayaccBrkt	contained "[<>]"
+syn match	ayaccType	"<[a-zA-Z_][a-zA-Z0-9_]*>"	contains=ayaccBrkt
+syn match	ayaccDefinition	"^[A-Za-z][A-Za-z0-9_]*[ \t]*:"
+
+" special Yacc separators
+syn match	ayaccSectionSep	"^[ \t]*%%"
+syn match	ayaccSep	"^[ \t]*%{"
+syn match	ayaccSep	"^[ \t]*%}"
+
+" I'd really like to highlight just the outer {}.  Any suggestions???
+syn match	ayaccCurlyError	"[{}]"
+syn region	ayaccAction	matchgroup=ayaccCurly start="{" end="}" contains=ALLBUT,@ayaccActionGroup
+
+if version >= 508 || !exists("did_ayacc_syntax_inits")
+   if version < 508
+      let did_ayacc_syntax_inits = 1
+      command -nargs=+ HiLink hi link <args>
+   else
+      command -nargs=+ HiLink hi def link <args>
+   endif
+
+  " Internal ayacc highlighting links
+  HiLink ayaccBrkt	ayaccStmt
+  HiLink ayaccKey	ayaccStmt
+  HiLink ayaccOper	ayaccStmt
+  HiLink ayaccUnionStart	ayaccKey
+
+  " External ayacc highlighting links
+  HiLink ayaccCurly	Delimiter
+  HiLink ayaccCurlyError	Error
+  HiLink ayaccDefinition	Function
+  HiLink ayaccDelim	Function
+  HiLink ayaccKeyActn	Special
+  HiLink ayaccSectionSep	Todo
+  HiLink ayaccSep	Delimiter
+  HiLink ayaccStmt	Statement
+  HiLink ayaccType	Type
+
+  " since Bram doesn't like my Delimiter :|
+  HiLink Delimiter	Type
+  delcommand HiLink
+endif
+
+let b:current_syntax = "ayacc"
+
+" vim: ts=15
--- /dev/null
+++ b/lib/vimfiles/syntax/b.vim
@@ -1,0 +1,142 @@
+" Vim syntax file
+" Language:	B (A Formal Method with refinement and mathematical proof)
+" Maintainer:	Mathieu Clabaut <mathieu.clabaut@free.fr>
+" LastChange:	25 Apr 2001
+
+
+" For version 5.x: Clear all syntax items
+" For version 6.x: Quit when a syntax file was already loaded
+if version < 600
+   syntax clear
+elseif exists("b:current_syntax")
+   finish
+endif
+
+
+" A bunch of useful B keywords
+syn keyword bStatement	MACHINE SEES OPERATIONS INCLUDES DEFINITIONS CONSTRAINTS CONSTANTS VARIABLES CONCRETE_CONSTANTS CONCRETE_VARIABLES ABSTRACT_CONSTANTS ABSTRACT_VARIABLES HIDDEN_CONSTANTS HIDDEN_VARIABLES ASSERT ASSERTIONS  EXTENDS IMPLEMENTATION REFINEMENT IMPORTS USES INITIALISATION INVARIANT PROMOTES PROPERTIES REFINES SETS VALUES VARIANT VISIBLE_CONSTANTS VISIBLE_VARIABLES THEORY
+syn keyword bLabel		CASE IN EITHER OR CHOICE DO OF
+syn keyword bConditional	IF ELSE SELECT ELSIF THEN WHEN
+syn keyword bRepeat		WHILE FOR
+syn keyword bOps		bool card conc closure closure1 dom first fnc front not or id inter iseq iseq1 iterate last max min mod perm pred prj1 prj2 ran rel rev seq seq1 size skip succ tail union
+syn keyword bKeywords		LET VAR BE IN BEGIN END  POW POW1 FIN FIN1  PRE  SIGMA STRING UNION IS ANY WHERE
+syn match bKeywords	"||"
+
+syn keyword bBoolean	TRUE FALSE bfalse btrue
+syn keyword bConstant	PI MAXINT MININT User_Pass PatchProver PatchProverH0 PatchProverB0 FLAT ARI DED SUB RES
+syn keyword bGuard binhyp band bnot bguard bsearch bflat bfresh bguardi bget bgethyp barith bgetresult bresult bgoal bmatch bmodr bnewv  bnum btest bpattern bprintf bwritef bsubfrm  bvrb blvar bcall bappend bclose
+
+syn keyword bLogic	or not
+syn match bLogic	"\&\|=>\|<=>"
+
+syn keyword cTodo contained	TODO FIXME XXX
+
+" String and Character constants
+" Highlight special characters (those which have a backslash) differently
+syn match bSpecial contained	"\\[0-7][0-7][0-7]\=\|\\."
+syn region bString		start=+"+ skip=+\\\\\|\\"+ end=+"+ contains=bSpecial
+syn match bCharacter		"'[^\\]'"
+syn match bSpecialCharacter	"'\\.'"
+syn match bSpecialCharacter	"'\\[0-7][0-7]'"
+syn match bSpecialCharacter	"'\\[0-7][0-7][0-7]'"
+
+"catch errors caused by wrong parenthesis
+syn region bParen		transparent start='(' end=')' contains=ALLBUT,bParenError,bIncluded,bSpecial,bTodo,bUserLabel,bBitField
+syn match bParenError		")"
+syn match bInParen contained	"[{}]"
+
+"integer number, or floating point number without a dot and with "f".
+syn case ignore
+syn match bNumber		"\<[0-9]\+\>"
+"syn match bIdentifier	"\<[a-z_][a-z0-9_]*\>"
+syn case match
+
+if exists("b_comment_strings")
+  " A comment can contain bString, bCharacter and bNumber.
+  " But a "*/" inside a bString in a bComment DOES end the comment!  So we
+  " need to use a special type of bString: bCommentString, which also ends on
+  " "*/", and sees a "*" at the start of the line as comment again.
+  " Unfortunately this doesn't very well work for // type of comments :-(
+  syntax match bCommentSkip	contained "^\s*\*\($\|\s\+\)"
+  syntax region bCommentString	contained start=+"+ skip=+\\\\\|\\"+ end=+"+ end=+\*/+me=s-1 contains=bSpecial,bCommentSkip
+  syntax region bComment2String	contained start=+"+ skip=+\\\\\|\\"+ end=+"+ end="$" contains=bSpecial
+  syntax region bComment	start="/\*" end="\*/" contains=bTodo,bCommentString,bCharacter,bNumber,bFloat
+  syntax region bComment	start="/\?\*" end="\*\?/" contains=bTodo,bCommentString,bCharacter,bNumber,bFloat
+  syntax match  bComment	"//.*" contains=bTodo,bComment2String,bCharacter,bNumber
+else
+  syn region bComment		start="/\*" end="\*/" contains=bTodo
+  syn region bComment		start="/\?\*" end="\*\?/" contains=bTodo
+  syn match bComment		"//.*" contains=bTodo
+endif
+syntax match bCommentError	"\*/"
+
+syn keyword bType		INT INTEGER BOOL NAT NATURAL NAT1 NATURAL1
+
+syn region bPreCondit	start="^\s*#\s*\(if\>\|ifdef\>\|ifndef\>\|elif\>\|else\>\|endif\>\)" skip="\\$" end="$" contains=bComment,bString,bCharacter,bNumber,bCommentError
+syn region bIncluded contained start=+"+ skip=+\\\\\|\\"+ end=+"+
+syn match bIncluded contained "<[^>]*>"
+syn match bInclude		"^\s*#\s*include\>\s*["<]" contains=bIncluded
+
+syn region bDefine		start="^\s*#\s*\(define\>\|undef\>\)" skip="\\$" end="$" contains=ALLBUT,bPreCondit,bIncluded,bInclude,bDefine,bInParen
+syn region bPreProc		start="^\s*#\s*\(pragma\>\|line\>\|warning\>\|warn\>\|error\>\)" skip="\\$" end="$" contains=ALLBUT,bPreCondit,bIncluded,bInclude,bDefine,bInParen
+
+
+syn sync ccomment bComment minlines=10
+
+" Define the default highlighting.
+" For version 5.7 and earlier: only when not done already
+" For version 5.8 and later: only when an item doesn't have highlighting yet
+
+if version >= 508 || !exists("did_b_syntax_inits")
+   if version < 508
+      let did_b_syntax_inits = 1
+      command -nargs=+ HiLink hi link <args>
+   else
+      command -nargs=+ HiLink hi def link <args>
+   endif
+
+  " The default methods for highlighting.  Can be overridden later
+  HiLink bLabel	Label
+  HiLink bUserLabel	Label
+  HiLink bConditional	Conditional
+  HiLink bRepeat	Repeat
+  HiLink bLogic	Special
+  HiLink bCharacter	Character
+  HiLink bSpecialCharacter bSpecial
+  HiLink bNumber	Number
+  HiLink bFloat	Float
+  HiLink bOctalError	bError
+  HiLink bParenError	bError
+" HiLink bInParen	bError
+  HiLink bCommentError	bError
+  HiLink bBoolean	Identifier
+  HiLink bConstant	Identifier
+  HiLink bGuard	Identifier
+  HiLink bOperator	Operator
+  HiLink bKeywords	Operator
+  HiLink bOps		Identifier
+  HiLink bStructure	Structure
+  HiLink bStorageClass	StorageClass
+  HiLink bInclude	Include
+  HiLink bPreProc	PreProc
+  HiLink bDefine	Macro
+  HiLink bIncluded	bString
+  HiLink bError	Error
+  HiLink bStatement	Statement
+  HiLink bPreCondit	PreCondit
+  HiLink bType		Type
+  HiLink bCommentError	bError
+  HiLink bCommentString bString
+  HiLink bComment2String bString
+  HiLink bCommentSkip	bComment
+  HiLink bString	String
+  HiLink bComment	Comment
+  HiLink bSpecial	SpecialChar
+  HiLink bTodo		Todo
+  "hi link bIdentifier	Identifier
+  delcommand HiLink
+endif
+
+let b:current_syntax = "b"
+
+" vim: ts=8
--- /dev/null
+++ b/lib/vimfiles/syntax/baan.vim
@@ -1,0 +1,1934 @@
+" Vim syntax file"
+" Language:	Baan
+" Maintainer:	Erik Remmelzwaal (erik.remmelzwaal 0x40 ssaglobal.com)
+" Originally owned by: Erwin Smit / Her van de Vliert
+" Last change:  v1.17 2006/04/26 10:40:18
+
+" For version 5.x: Clear all syntax items
+" For version 6.x: Quit when a syntax file was already loaded
+"
+if version < 600
+  syntax clear
+  if exists("baan_fold")
+	  unlet baan_fold
+  endif
+elseif exists("b:current_syntax")
+  finish
+endif
+
+"********************************** Lexical setting ***************************"
+syn case ignore
+setlocal iskeyword+=.
+"setlocal ignorecase 	"This is not a local yet ;-(
+" Identifier
+syn match   baanIdentifier "\<\k\+\>"
+
+"************************************* 3GL ************************************"
+syn match   baan3glpre "#ident\>"
+syn match   baan3glpre "#include\>"
+syn region  baan3glpre start="#define\>" end="^[^^|]"me=s-1 contains=baanString,baanConstant,baanNumber,baanComment,baansql
+syn match   baan3glpre "#undef\>"
+syn match   baan3glpre "#pragma\>"
+syn match   baan3glpre "#if\>"
+syn match   baan3glpre "#ifdef\>"
+syn match   baan3glpre "#ifndef\>"
+syn match   baan3glpre "#elif\>"
+syn match   baan3glpre "#else\>"
+syn match   baan3glpre "#endif\>"
+
+" Some keywords are only defined when no foldinat based break bset call continue default
+syn keyword baan3gl empty  fixed ge global goto gt le lt mb
+syn keyword baan3gl multibyte ne ofr prompt repeat static step stop
+syn keyword baan3gl until void wherebind ref reference break continue
+syn keyword baan3gl and or to not in
+syn keyword baan3gl eq input end return at print
+syn keyword baanType domain double long string table boolean common
+syn keyword baanType bset void xmlNode
+syn keyword baanStorageClass dim base based extern global fixed MB const
+syn keyword baanConstant pi true false
+
+" Folding settings
+if exists("baan_fold") && baan_fold
+  syn region baanFunctionFold matchgroup=baan3gl start="^\z(\s*\)\<function\>" matchgroup=NONE end="^\z1}" transparent fold keepend
+else
+  syn keyword baan3gl function
+endif
+if exists("baan_fold") && baan_fold && exists("baan_fold_block") && baan_fold_block
+  syn region  baanCondFold matchgroup=baanConditional start="^\z(\s*\)\(if\>\|else\>\)" end="^\z1endif\>" end="^\z1else\>"me=s-1 transparent fold keepend extend
+  syn region  baanCondFold matchgroup=baanConditional start="^\z(\s*\)for\>"            end="^\z1endfor\>" transparent fold keepend extend
+  syn region  baanCondFold matchgroup=baanConditional start="^\z(\s*\)while\>"          end="^\z1endwhile\>" transparent fold keepend extend
+  syn region  baanDLLUsage matchgroup=baan3gl         start="^\z(\s*\)dllusage\>"       end="^\z1enddllusage\>" fold contains=baanNumber,baanConstant,baanType
+  syn region  baanFunUsage matchgroup=baan3gl         start="^\z(\s*\)functionusage\>"  end="^\z1endfunctionusage\>" fold  contains=baanNumber,baanConstant,baanType
+  syn region  baanCondFold matchgroup=baanConditional start="^\z(\s*\)\(case\>\|default\>\)\>" end="^\z1endcase\>" end="^\z1\(case\>\|default\>\)"me=s-1 transparent fold keepend extend
+  syn keyword baanConditional then else endif while endwhile endfor case endcase 
+  syn match   baanConditional "\<on case\>"
+else
+  syn match   baanConditional "\<for\>" contains=baansql
+  syn match   baanConditional "\<on case\>"
+  syn keyword baanConditional if then else endif while endwhile endfor case endcase default
+  syn region  baanDLLUsage matchgroup=baan3gl start="\<dllusage\>" end="\<enddllusage\>" contains=baanNumber,baanConstant,baanType
+  syn region  baanFunUsage matchgroup=baan3gl start="\<functionusage\>" end="\<endfunctionusage\>" contains=baanNumber,baanConstant,baanType
+endif
+
+"************************************* SQL ************************************"
+syn keyword baansql from selectbind 
+syn keyword baansql where wherebind whereused exsists  
+syn keyword baansql between inrange having
+syn keyword baansql hint ordered asc desc
+syn match   baansql "\<as set with \d\+ rows\>"
+syn match   baansql "\<as prepared set\>"
+syn match   baansql "\<as prepared set with \d\+ rows\>"
+syn match   baansql "\<with retry\>"
+syn match   baansql "\<with retry repeat last row\>"
+syn match   baansql "\<for update\>"
+syn match   baansql "\<order by\>"
+syn match   baansql "\<group by\>"
+syn match   baansql "\<union all\>"
+" references
+syn keyword path reference 
+syn match   baansql "\<refers to\>"
+syn match   baansql "\<unref clear\>"
+syn match   baansql "\<unref setunref\>"
+syn match   baansql "\<unref clearunref\>"
+syn match   baansql "\<unref skip\>"
+" hints
+syn keyword baansql hint and ordered asc desc
+syn match   baansql "\<use index \d\+ on\>"
+syn match   baansql "\<array fetching\>"
+syn match   baansql "\<no array fetching\>"
+syn match   baansql "\<array size \d\+\>"
+syn match   baansql "\<all rows\>"
+syn match   baansql "\<first rows\>"
+syn match   baansql "\<buffer \d\+ rows\>"
+syn match   baansql "\<no hints\>"
+" update
+syn keyword baansql set
+
+if exists("baan_fold") && baan_fold && exists("baan_fold_sql") && baan_fold_sql
+  syn region baanSQLFold matchgroup=baansql start="^\z(\s*\)\(select\>\|selectdo\>\|selectempty\>\|selecterror\>\|selecteos\>\)" end="^\z1endselect\>" end="^\z1\(selectdo\>\|selectempty\>\|selecterror\>\|selecteos\>\)"me=s-1 transparent fold keepend extend
+  "syn region baanSQLFold matchgroup=baansql start="^\z(\s*\)\(update\>\|updateempty\>\|updateerror\>\|selecteos\>\)"             end="^\z1endupdate\>" end="^\z1\(updateempty\>\|updateerror\>\|selecteos\>\)"me=s-1 transparent fold keepend extend
+  syn region baanSQLFold matchgroup=baansql start="^\z(\s*\)\(update\>\|updateempty\>\|updateerror\>\)"             end="^\z1endupdate\>" end="^\z1\(updateempty\>\|updateerror\>\)"me=s-1 transparent fold keepend extend
+  syn region baanSQLFold matchgroup=baansql start="^\z(\s*\)\(delete\s\+from\>\|deleteempty\>\|deleteerror\>\)"                  end="^\z1enddelete\>" end="^\z1\(deleteempty\>\|deleteerror\>\)"me=s-1 transparent fold keepend extend
+else
+  syn keyword baansql select selectdo selectempty selecterror selecteos endselect
+  " delete
+  syn match   baansql "\<delete from\>"
+  syn keyword baansql deleteempty deleteerror deleteeos enddelete
+  " update
+  syn keyword baansql update updateempty updateerror updateeos endupdate
+endif
+
+setlocal foldmethod=syntax
+"syn sync fromstart
+syn sync minlines=100
+
+
+"These are bshell functions
+if exists("baan_obsolete")
+syn match   baansql "commit\.transaction()"
+syn match   baansql "abort\.transaction()"
+syn match   baansql "db\.columns\.to\.record"
+syn match   baansql "db\.record\.to\.columns"
+syn match   baansql "db\.bind"
+syn match   baansql "db\.change\.order"
+syn match   baansql "db\.set\.to\.default"
+syn match   baansql "DB\.RETRY"
+syn match   baansql "db\.delayed\.lock"
+syn match   baansql "db\.retry\.point()"
+syn match   baansql "db\.retry\.hit()"
+syn match   baansql "db\.return\.dupl"
+syn match   baansql "db\.skip\.dupl"
+syn match   baansql "db\.row\.length"
+endif
+
+" Constants
+syn keyword baanConstant __function__
+syn keyword baanConstant __object__ 
+syn keyword baanConstant __file__
+syn keyword baanConstant __line__
+
+syn keyword baanConstant ABORT.PROGRAM
+syn keyword baanConstant ADD.SET
+syn keyword baanConstant ALL_ENUMS_EXCEPT
+syn keyword baanConstant APPL.EXCL
+syn keyword baanConstant APPL.READ
+syn keyword baanConstant APPL.WAIT
+syn keyword baanConstant APPL.WIDE
+syn keyword baanConstant APPL.WRITE
+syn keyword baanConstant ASK.HELPINFO
+syn keyword baanConstant AUTG_PRINT
+syn keyword baanConstant AUTG_DISPLAY
+syn keyword baanConstant AUTG_MODIFY
+syn keyword baanConstant AUTG_INSERT
+syn keyword baanConstant AUTG_DELETE
+syn keyword baanConstant AUTG_ALL
+syn keyword baanConstant BMS
+syn keyword baanConstant CALCULATOR
+syn keyword baanConstant CALENDAR
+syn keyword baanConstant CHANGE.ORDER
+syn keyword baanConstant CMD.OPTIONS
+syn keyword baanConstant CMD.WHATS.THIS
+syn keyword baanConstant CMF.MESSAGE
+syn keyword baanConstant CMF.TASK
+syn keyword baanConstant CMF.APPOINTMENT
+syn match   baanConstant "\<COMPANY\$"
+syn keyword baanConstant COMPNR
+syn keyword baanConstant CONT.PROCESS
+syn keyword baanConstant CREATE.JOB
+syn keyword baanConstant DALNOOBJSET
+syn keyword baanConstant DALNOMETHOD
+syn keyword baanConstant DALNOOBJSETID
+syn keyword baanConstant DALNOOBJECTID
+syn keyword baanConstant DALNOPROP
+syn keyword baanConstant DALNOLOCMODE
+syn keyword baanConstant DALNOGETPOS
+syn keyword baanConstant DALNOSETPERM
+syn keyword baanConstant DALNOOBJPERM
+syn keyword baanConstant DALDBERROR
+syn keyword baanConstant DALHOOKERROR
+syn keyword baanConstant DALNOQUERYID
+syn keyword baanConstant DAL_DESTROY
+syn keyword baanConstant DAL_FIND
+syn keyword baanConstant DAL_GET_CURR
+syn keyword baanConstant DAL_GET_FIRST
+syn keyword baanConstant DAL_GET_LAST
+syn keyword baanConstant DAL_GET_NEXT
+syn keyword baanConstant DAL_GET_PREV
+syn keyword baanConstant DAL_GET_SPECIFIED
+syn keyword baanConstant DAL_NEW
+syn keyword baanConstant DAL_UPDATE
+syn keyword baanConstant DB.ARRAY
+syn keyword baanConstant DB.BASED
+syn keyword baanConstant DB.BITSET
+syn keyword baanConstant DB.BYTE
+syn keyword baanConstant DB.CHECK.IGNORED.REF
+syn keyword baanConstant DB.CHILD
+syn keyword baanConstant DB.CLEAR.NO.ROLLBACK
+syn keyword baanConstant DB.CLEAR.WITH.ROLLBACK
+syn keyword baanConstant DB.COMBINED
+syn keyword baanConstant DB.DATE
+syn keyword baanConstant DB.DELAYED.LOCK
+syn keyword baanConstant DB.DOUBLE
+syn keyword baanConstant DB.ENUM
+syn keyword baanConstant DB.EXIT.ON.DUPL
+syn keyword baanConstant DB.EXIT.ON.NOREC
+syn keyword baanConstant DB.EXIT.ON.ROWCHANGED
+syn keyword baanConstant DB.FILLED
+syn keyword baanConstant DB.FIXED
+syn keyword baanConstant DB.FL.LOCK
+syn keyword baanConstant DB.FLOAT
+syn keyword baanConstant DB.IGNORE.ALL.REFS
+syn keyword baanConstant DB.INTEGER
+syn keyword baanConstant DB.IS.REF.TO
+syn keyword baanConstant DB.LOCK
+syn keyword baanConstant DB.LONG
+syn keyword baanConstant DB.MAIL
+syn keyword baanConstant DB.MULTIBYTE
+syn keyword baanConstant DB.NOT.ACTIV
+syn keyword baanConstant DB.PAR.IS.REF.TO
+syn keyword baanConstant DB.REF.CASCADE
+syn keyword baanConstant DB.REF.CHK.RUNTIME
+syn keyword baanConstant DB.REF.DELETE
+syn keyword baanConstant DB.REF.NOP
+syn keyword baanConstant DB.REF.NULLIFY
+syn keyword baanConstant DB.REF.RESTRICTED
+syn keyword baanConstant DB.REF.UPDATE
+syn keyword baanConstant DB.RETRY
+syn keyword baanConstant DB.RETURN.DUPL
+syn keyword baanConstant DB.RETURN.ERROR
+syn keyword baanConstant DB.RETURN.NOREC
+syn keyword baanConstant DB.RETURN.REF.EXISTS
+syn keyword baanConstant DB.RETURN.REF.NOT.EXISTS
+syn keyword baanConstant DB.RETURN.ROWCHANGED
+syn keyword baanConstant DB.RPOINT
+syn keyword baanConstant DB.SKIP.DUPL
+syn keyword baanConstant DB.SKIP.NOREC
+syn keyword baanConstant DB.SKIP.ROWCHANGED
+syn keyword baanConstant DB.STRING
+syn keyword baanConstant DB.TEXT
+syn keyword baanConstant DB.TIME
+syn keyword baanConstant DBG_BDB_ACTIONS
+syn keyword baanConstant DBG_BDB_DELAY_LOCK
+syn keyword baanConstant DBG_BDB_REFER
+syn keyword baanConstant DBG_BDB_SERVER_TYPE
+syn keyword baanConstant DBG_DATA_SIZE
+syn keyword baanConstant DBG_DEBUG_MESG
+syn keyword baanConstant DBG_DEBUG_TSS
+syn keyword baanConstant DBG_FILE
+syn keyword baanConstant DBG_FILEDEV
+syn keyword baanConstant DBG_FUN_DEBUG
+syn keyword baanConstant DBG_GET_PUT_VAR
+syn keyword baanConstant DBG_INSTR_DEBUG
+syn keyword baanConstant DBG_MUL_ACTION
+syn keyword baanConstant DBG_OBJ_SIZE
+syn keyword baanConstant DBG_PRINT_ENUMS
+syn keyword baanConstant DBG_REF_PATH
+syn keyword baanConstant DBG_RESOURCE_DBG
+syn keyword baanConstant DBG_SCHED_DEBUG
+syn keyword baanConstant DBG_SHOW_FLOW
+syn keyword baanConstant DBG_SHOW_TRACE
+syn keyword baanConstant DBG_SRDD_USAGE
+syn keyword baanConstant DEBUG
+syn keyword baanConstant DEF.FIND
+syn keyword baanConstant DISPLAY.SET
+syn keyword baanConstant DIS.RESTARTED
+syn keyword baanConstant DLL_OVERLOAD
+syn keyword baanConstant DLL_OVERLOAD_ALL
+syn keyword baanConstant DLL_SILENT_ERR
+syn keyword baanConstant DSTerminationCreateProcess
+syn keyword baanConstant DSTerminationCreateThread
+syn keyword baanConstant DSTerminationNormalExit
+syn keyword baanConstant DSTerminationOpenStderr
+syn keyword baanConstant DSTerminationOpenStdin
+syn keyword baanConstant DSTerminationOpenStdout
+syn keyword baanConstant DSTerminationSetDir
+syn keyword baanConstant DUPL.OCCUR
+syn keyword baanConstant E2BIG
+syn keyword baanConstant EABORT
+syn keyword baanConstant EACCES
+syn keyword baanConstant EAGAIN
+syn keyword baanConstant EAUDIT
+syn keyword baanConstant EBADADRS
+syn keyword baanConstant EBADARG
+syn keyword baanConstant EBADCOLL
+syn keyword baanConstant EBADCURSOR
+syn keyword baanConstant EBADF
+syn keyword baanConstant EBADFILE
+syn keyword baanConstant EBADFLD
+syn keyword baanConstant EBADKEY
+syn keyword baanConstant EBADLOG
+syn keyword baanConstant EBADMEM
+syn keyword baanConstant EBDBNOTON
+syn keyword baanConstant EBDBON
+syn keyword baanConstant EBUSY
+syn keyword baanConstant ECHILD
+syn keyword baanConstant EDDCORRUPT
+syn keyword baanConstant EDOM
+syn keyword baanConstant EDUPL
+syn keyword baanConstant EENDFILE
+syn keyword baanConstant EEXIST
+syn keyword baanConstant EFAULT
+syn keyword baanConstant EFBIG
+syn keyword baanConstant EFLOCKED
+syn keyword baanConstant EFNAME
+syn keyword baanConstant EINTR
+syn keyword baanConstant EINVAL
+syn keyword baanConstant EIO
+syn keyword baanConstant EISDIR
+syn keyword baanConstant EISREADONLY
+syn keyword baanConstant EKEXISTS
+syn keyword baanConstant ELOCKED
+syn keyword baanConstant ELOGOPEN
+syn keyword baanConstant ELOGREAD
+syn keyword baanConstant ELOGWRIT
+syn keyword baanConstant EMEMORY
+syn keyword baanConstant EMFILE
+syn keyword baanConstant EMLINK
+syn keyword baanConstant EMLOCKED
+syn keyword baanConstant END.PROGRAM
+syn keyword baanConstant ENFILE
+syn keyword baanConstant ENOBEGIN
+syn keyword baanConstant ENOCURR
+syn keyword baanConstant ENODD
+syn keyword baanConstant ENODELAYEDLOCK
+syn keyword baanConstant ENODEV
+syn keyword baanConstant ENOENT
+syn keyword baanConstant ENOEXEC
+syn keyword baanConstant ENOLOK
+syn keyword baanConstant ENOMEM
+syn keyword baanConstant ENONFS
+syn keyword baanConstant ENOREC
+syn keyword baanConstant ENOSERVER
+syn keyword baanConstant ENOSHMEM
+syn keyword baanConstant ENOSPC
+syn keyword baanConstant ENOTABLE
+syn keyword baanConstant ENOTBLK
+syn keyword baanConstant ENOTDIR
+syn keyword baanConstant ENOTEXCL
+syn keyword baanConstant ENOTINRANGE
+syn keyword baanConstant ENOTLOCKED
+syn keyword baanConstant ENOTOPEN
+syn keyword baanConstant ENOTRANS
+syn keyword baanConstant ENOTTY
+syn keyword baanConstant ENXIO
+syn keyword baanConstant ENUMMASK.INITIAL
+syn keyword baanConstant ENUMMASK.GENERAL
+syn keyword baanConstant EPERM
+syn keyword baanConstant EPIPE
+syn keyword baanConstant EPRIMKEY
+syn keyword baanConstant ERANGE
+syn keyword baanConstant EREFERENCE
+syn keyword baanConstant EREFEXISTS
+syn keyword baanConstant EREFLOCKED
+syn keyword baanConstant EREFNOTEXISTS
+syn keyword baanConstant EREFUNDEFINED
+syn keyword baanConstant EREFUPDATE
+syn keyword baanConstant EROFS
+syn keyword baanConstant EROWCHANGED
+syn keyword baanConstant ESPIPE
+syn keyword baanConstant ESQLCARDINALITYVIOLATION
+syn keyword baanConstant ESQLDIVBYZERO
+syn keyword baanConstant ESQLFILEIO
+syn keyword baanConstant ESQLINDEXOUTOFDIMS
+syn keyword baanConstant ESQLINVALIDPARAMETERTYPE
+syn keyword baanConstant ESQLQUERY
+syn keyword baanConstant ESQLREFER
+syn keyword baanConstant ESQLSTRINGTRUNCATION
+syn keyword baanConstant ESQLSUBSTRINGERROR
+syn keyword baanConstant ESQLSYNTAX
+syn keyword baanConstant ESRCH
+syn keyword baanConstant ETABLEEXIST
+syn keyword baanConstant ETOOMANY
+syn keyword baanConstant ETRANSACTIONON
+syn keyword baanConstant ETXTBSY
+syn keyword baanConstant EUNALLOWEDCOMPNR
+syn keyword baanConstant EVTALLEVENTMASK
+syn keyword baanConstant EVTARMBUTTON
+syn keyword baanConstant EVTARMBUTTONMASK
+syn keyword baanConstant EVTBUCKETMESSAGE
+syn keyword baanConstant EVTBUTTON1
+syn keyword baanConstant EVTBUTTON1MASK
+syn keyword baanConstant EVTBUTTON2
+syn keyword baanConstant EVTBUTTON2MASK
+syn keyword baanConstant EVTBUTTON3
+syn keyword baanConstant EVTBUTTON3MASK
+syn keyword baanConstant EVTBUTTON4
+syn keyword baanConstant EVTBUTTON4MASK
+syn keyword baanConstant EVTBUTTON5
+syn keyword baanConstant EVTBUTTON5MASK
+syn keyword baanConstant EVTBUTTONCHECKED
+syn keyword baanConstant EVTBUTTONDPRESS
+syn keyword baanConstant EVTBUTTONDPRESSMASK
+syn keyword baanConstant EVTBUTTONMOTION
+syn keyword baanConstant EVTBUTTONMOTIONMASK
+syn keyword baanConstant EVTBUTTONPRESS
+syn keyword baanConstant EVTBUTTONPRESSMASK
+syn keyword baanConstant EVTBUTTONRELEASE
+syn keyword baanConstant EVTBUTTONRELEASEMASK
+syn keyword baanConstant EVTBUTTONSELECT
+syn keyword baanConstant EVTBUTTONSELECTMASK
+syn keyword baanConstant EVTBUTTONUNCHECKED
+syn keyword baanConstant EVTBUTTONUNDEFINED
+syn keyword baanConstant EVTCHANGEFOCUS
+syn keyword baanConstant EVTCHANGEFOCUSMASK
+syn keyword baanConstant EVTCHANNELEVENT
+syn keyword baanConstant EVTCHECKBOXMASK
+syn keyword baanConstant EVTCHECKBOXSELECT
+syn keyword baanConstant EVTCLIENTMESSAGE
+syn keyword baanConstant EVTCONNECTREQUEST
+syn keyword baanConstant EVTCONTROLMASK
+syn keyword baanConstant EVTDEATHCHILD
+syn keyword baanConstant EVTDEATHCHILDMASK
+syn keyword baanConstant EVTDISARMBUTTON
+syn keyword baanConstant EVTDISARMBUTTONMASK
+syn keyword baanConstant EVTDLLEVENT
+syn keyword baanConstant EVTDLLEVENTMASK
+syn keyword baanConstant EVTENTERNOTIFY
+syn keyword baanConstant EVTENTERNOTIFYMASK
+syn keyword baanConstant EVTFIELDSELECT
+syn keyword baanConstant EVTFIELDSELECTMASK
+syn keyword baanConstant EVTGRIDACTIVATE
+syn keyword baanConstant EVTGRIDBUTTONPRESS
+syn keyword baanConstant EVTGRIDCHANGEDATA
+syn keyword baanConstant EVTGRIDCHANGEFOCUS
+syn keyword baanConstant EVTGRIDEVENT
+syn keyword baanConstant EVTGRIDEVENTMASK
+syn keyword baanConstant EVTGRIDFOCUSCHANGEDBYMOUSE
+syn keyword baanConstant EVTGRIDLISTBOXCHANGE
+syn keyword baanConstant EVTGRIDMARKCELL
+syn keyword baanConstant EVTGRIDMARKCOLUMN
+syn keyword baanConstant EVTGRIDMARKRANGE
+syn keyword baanConstant EVTGRIDMARKROW
+syn keyword baanConstant EVTGRIDMOVECOLUMN
+syn keyword baanConstant EVTGRIDMOVEROW
+syn keyword baanConstant EVTGRIDRESETSELECTION
+syn keyword baanConstant EVTGRIDRESIZECOLUMN
+syn keyword baanConstant EVTGRIDRESIZEROW
+syn keyword baanConstant EVTHELPCOMMAND
+syn keyword baanConstant EVTHELPCONTEXT
+syn keyword baanConstant EVTHELPEVENT
+syn keyword baanConstant EVTHELPEVENTMASK
+syn keyword baanConstant EVTIOEVENT
+syn keyword baanConstant EVTIOEVENTMASK
+syn keyword baanConstant EVTKEYPRESS
+syn keyword baanConstant EVTKEYPRESSMASK
+syn keyword baanConstant EVTKILLEVENT
+syn keyword baanConstant EVTLEAVENOTIFY
+syn keyword baanConstant EVTLEAVENOTIFYMASK
+syn keyword baanConstant EVTLISTBOXREASONACTIVATE
+syn keyword baanConstant EVTLISTBOXREASONSELECTION
+syn keyword baanConstant EVTLISTBOXREASONTEXT
+syn keyword baanConstant EVTLISTBOXSELECT
+syn keyword baanConstant EVTLISTBOXSELECTMASK
+syn keyword baanConstant EVTLOCKMASK
+syn keyword baanConstant EVTMAXSIZE
+syn keyword baanConstant EVTMENUSELECT
+syn keyword baanConstant EVTMENUSELECTMASK
+syn keyword baanConstant EVTMOD1MASK
+syn keyword baanConstant EVTMOVEWINDOW
+syn keyword baanConstant EVTMOVEWINDOWMASK
+syn keyword baanConstant EVTNAVIGATOREVENT
+syn keyword baanConstant EVTNAVIGATOREVENTMASK
+syn keyword baanConstant EVTNOEVENTMASK
+syn keyword baanConstant EVTOLEAUTOMATION
+syn keyword baanConstant EVTOLECLOSE
+syn keyword baanConstant EVTOLECREATEINSTANCE
+syn keyword baanConstant EVTOLEDATACHANGED
+syn keyword baanConstant EVTOLEEVENT
+syn keyword baanConstant EVTOLEEVENTMASK
+syn keyword baanConstant EVTOLEHIDEWINDOW
+syn keyword baanConstant EVTOLELOADDATA
+syn keyword baanConstant EVTOLELOCKSERVER
+syn keyword baanConstant EVTOLEOBJECTWINDOWINVISIBLE
+syn keyword baanConstant EVTOLEOBJECTWINDOWVISIBLE
+syn keyword baanConstant EVTOLERELEASED
+syn keyword baanConstant EVTOLESAVEDATA
+syn keyword baanConstant EVTOLESETHOSTNAMES
+syn keyword baanConstant EVTOLESHOWOBJECT
+syn keyword baanConstant EVTOLESHOWWINDOW
+syn keyword baanConstant EVTOLEUNLOCKSERVER
+syn keyword baanConstant EVTOPTIONSELECT
+syn keyword baanConstant EVTPROCESSEVENT
+syn keyword baanConstant EVTPUSHBUTTON
+syn keyword baanConstant EVTRADIOBOXMASK
+syn keyword baanConstant EVTRADIOBOXSELECT
+syn keyword baanConstant EVTRESIZEWINDOW
+syn keyword baanConstant EVTRESIZEWINDOWMASK
+syn keyword baanConstant EVTRUNPROGEXIT
+syn keyword baanConstant EVTSCROLLBARSELECT
+syn keyword baanConstant EVTSCROLLBARSELECTMASK
+syn keyword baanConstant EVTSETFOCUS
+syn keyword baanConstant EVTSETFOCUSMASK
+syn keyword baanConstant EVTSHIFTMASK
+syn keyword baanConstant EVTSLIDERSELECT
+syn keyword baanConstant EVTSLIDERSELECTMASK
+syn keyword baanConstant EVTSOCKHASDATA
+syn keyword baanConstant EVTSOCKIOERROR
+syn keyword baanConstant EVTTABSELECT
+syn keyword baanConstant EVTTABSELECTMASK
+syn keyword baanConstant EVTTERMINATION
+syn keyword baanConstant EVTTERMINATIONMASK
+syn keyword baanConstant EVTTIMEREVENT
+syn keyword baanConstant EVTTIMEREVENTMASK
+syn keyword baanConstant EVTTREEREASONACTIVATE
+syn keyword baanConstant EVTTREEREASONACTIVATEMASK
+syn keyword baanConstant EVTTREEREASONCOLLAPSE
+syn keyword baanConstant EVTTREEREASONCOLLAPSEMASK
+syn keyword baanConstant EVTTREEREASONEXPAND
+syn keyword baanConstant EVTTREEREASONEXPANDMASK
+syn keyword baanConstant EVTTREEREASONSELECT
+syn keyword baanConstant EVTTREEREASONSELECTMASK
+syn keyword baanConstant EVTTREESELECT
+syn keyword baanConstant EVTTREESELECTMASK
+syn keyword baanConstant EXDEV
+syn keyword baanConstant EXPLICIT.MODELESS
+syn keyword baanConstant EXTEND_APPEND
+syn keyword baanConstant EXTEND_OVERWRITE
+syn keyword baanConstant F.ASK.HELPINFO
+syn keyword baanConstant F.BACKTAB
+syn keyword baanConstant F.BMS
+syn keyword baanConstant F.HELP.INDEX
+syn keyword baanConstant F.NEXT.FLD
+syn keyword baanConstant F.NEXT.OBJ
+syn keyword baanConstant F.NEXT.OCC
+syn keyword baanConstant F.PREV.FLD
+syn keyword baanConstant F.PREV.OBJ
+syn keyword baanConstant F.PREV.OCC
+syn keyword baanConstant F.RESIZE
+syn keyword baanConstant F.RETURN
+syn keyword baanConstant F.SCROLL
+syn keyword baanConstant F.SELECT.FIELD
+syn keyword baanConstant F.SELECT.OPTION
+syn keyword baanConstant F.TAB
+syn keyword baanConstant F.TO.CHOICE
+syn keyword baanConstant F.TO.FIELD
+syn keyword baanConstant F.TO.FORM
+syn keyword baanConstant F.ZOOM
+syn keyword baanConstant FALSE
+syn keyword baanConstant FC.CURR.FIELD
+syn keyword baanConstant FC.FIRST.FIELD
+syn keyword baanConstant FC.FIRST.FORM
+syn keyword baanConstant FC.FRM.WINDOW
+syn keyword baanConstant FC.GET.HEIGHT.FORM
+syn keyword baanConstant FC.GET.SELECTED.FIELD
+syn keyword baanConstant FC.GET.SELECTED.OCC
+syn keyword baanConstant FC.GET.WIDTH.FORM
+syn keyword baanConstant FC.GOTO.FIELD
+syn keyword baanConstant FC.GOTO.FIRST.FLD
+syn keyword baanConstant FC.GOTO.FIRST.FORM
+syn keyword baanConstant FC.GOTO.FORM
+syn keyword baanConstant FC.GOTO.NEXT.FLD
+syn keyword baanConstant FC.GOTO.NEXT.FORM
+syn keyword baanConstant FC.GRA.WINDOW
+syn keyword baanConstant FC.KYS.WINDOW
+syn keyword baanConstant FC.LAST.FIELD
+syn keyword baanConstant FC.LAST.FORM
+syn keyword baanConstant FC.MAKE.FLD.CURR
+syn keyword baanConstant FC.MOVE.FORM
+syn keyword baanConstant FC.NEXT.FIELD
+syn keyword baanConstant FC.NEXT.FORM
+syn keyword baanConstant FC.OPT.WINDOW
+syn keyword baanConstant FC.PREV.FIELD
+syn keyword baanConstant FC.PREV.FORM
+syn keyword baanConstant FC.RESIZE.FORM
+syn keyword baanConstant FC.REST.FRM.ST
+syn keyword baanConstant FC.RPT.WINDOW
+syn keyword baanConstant FC.SAVE.FRM.ST
+syn keyword baanConstant FC.SAVE.SELECT
+syn keyword baanConstant FC.SEL.FIELD
+syn keyword baanConstant FC.SEL.FORM
+syn keyword baanConstant FC.SWITCH.ORDER.OFF
+syn keyword baanConstant FC.SWITCH.ORDER.ON
+syn keyword baanConstant FC.TEXT.MAIL.WINDOW
+syn keyword baanConstant FIND.DATA
+syn keyword baanConstant FIRST.FRM
+syn keyword baanConstant FIRST.SET
+syn keyword baanConstant FIRST.VIEW
+syn keyword baanConstant FLDCHANGED
+syn keyword baanConstant FLDKEYPRESS
+syn keyword baanConstant FORM.TAB.CHANGE
+syn keyword baanConstant GET.DEFAULTS
+syn keyword baanConstant GETS_ALL_CHARS
+syn keyword baanConstant GETS_NORMAL
+syn keyword baanConstant GETS_SKIP_ALL
+syn keyword baanConstant GLOBAL.COPY
+syn keyword baanConstant GLOBAL.DELETE
+syn keyword baanConstant HELP_ABOUT
+syn keyword baanConstant HELP_ARG_LEN
+syn keyword baanConstant HELP_BITMAP
+syn keyword baanConstant HELP_BLOCK
+syn keyword baanConstant HELP_CHOICE
+syn keyword baanConstant HELP_CLIENT_IMAGE_NOTLOADED
+syn keyword baanConstant HELP_CLIENT_IMAGE_READY
+syn keyword baanConstant HELP_CLIENT_NEW_ARGS
+syn keyword baanConstant HELP_CLIENT_NEW_INFO
+syn keyword baanConstant HELP_COMMANDS
+syn keyword baanConstant HELP_DOMAIN
+syn keyword baanConstant HELP_ENUM
+syn keyword baanConstant HELP_EXTERNAL
+syn keyword baanConstant HELP_FORM
+syn keyword baanConstant HELP_FORMFIELD
+syn keyword baanConstant HELP_FROM_INDEX
+syn keyword baanConstant HELP_GEM
+syn keyword baanConstant HELP_GIF
+syn keyword baanConstant HELP_GLOSSARY
+syn keyword baanConstant HELP_GOTO
+syn keyword baanConstant HELP_GOTOBLOCK
+syn keyword baanConstant HELP_GO_SYS_DEPENDANT
+syn keyword baanConstant HELP_HPGL
+syn keyword baanConstant HELP_IFUNCTION
+syn keyword baanConstant HELP_IFUNCTION2
+syn keyword baanConstant HELP_IFUNCTION3
+syn keyword baanConstant HELP_INDEX
+syn keyword baanConstant HELP_LABEL
+syn keyword baanConstant HELP_LABELHELP
+syn keyword baanConstant HELP_MARK
+syn keyword baanConstant HELP_MAXTYPE
+syn keyword baanConstant HELP_MAX_ARGS
+syn keyword baanConstant HELP_MAX_HIST
+syn keyword baanConstant HELP_MAX_IMAGE
+syn keyword baanConstant HELP_MENU
+syn keyword baanConstant HELP_MESSAGE
+syn keyword baanConstant HELP_ORGANIZER
+syn keyword baanConstant HELP_POPUP_TYPE
+syn keyword baanConstant HELP_POSTSCRIPT
+syn keyword baanConstant HELP_QUESTION
+syn keyword baanConstant HELP_REFERENCE
+syn keyword baanConstant HELP_RELATION
+syn keyword baanConstant HELP_RELATION2
+syn keyword baanConstant HELP_RELATION_DIAGRAM
+syn keyword baanConstant HELP_REPORT
+syn keyword baanConstant HELP_SESSION
+syn keyword baanConstant HELP_STARTSESSION
+syn keyword baanConstant HELP_STARTSHELL
+syn keyword baanConstant HELP_SUBFUNCTION
+syn keyword baanConstant HELP_SYSTEM_DEPENDANT
+syn keyword baanConstant HELP_TABLE
+syn keyword baanConstant HELP_TABLEFIELD
+syn keyword baanConstant HELP_USING
+syn keyword baanConstant HOOK_IS_APPLICABLE
+syn keyword baanConstant HOOK_IS_DERIVED
+syn keyword baanConstant HOOK_IS_MANDATORY
+syn keyword baanConstant HOOK_IS_READONLY
+syn keyword baanConstant HOOK_IS_VALID
+syn keyword baanConstant HOOK_UPDATE
+syn keyword baanConstant INCLUDE_ENUMS
+syn keyword baanConstant INTERRUPT
+syn keyword baanConstant LAST.FRM
+syn keyword baanConstant LAST.SET
+syn keyword baanConstant LAST.VIEW
+syn keyword baanConstant MARK.ABORT
+syn keyword baanConstant MARK.DELETE
+syn keyword baanConstant MARK.GOTO.NEXT
+syn keyword baanConstant MARK.GOTO.PREV
+syn keyword baanConstant MARK.OCCUR
+syn keyword baanConstant MARK.SHOW.OPT
+syn keyword baanConstant MARK.TAG
+syn keyword baanConstant MARK.TAG.ALL
+syn keyword baanConstant MARK.TO.CHOICE
+syn keyword baanConstant MARK.UNTAG
+syn keyword baanConstant MARK.UNTAG.ALL
+syn keyword baanConstant MARKONE.ACCEPT
+syn keyword baanConstant MSG.ALL
+syn keyword baanConstant MSG.ERROR
+syn keyword baanConstant MSG.INFO
+syn keyword baanConstant MSG.WARNING
+syn keyword baanConstant MSG.SUCCESS
+syn keyword baanConstant MODAL
+syn keyword baanConstant MODAL_OVERVIEW
+syn keyword baanConstant MODELESS
+syn keyword baanConstant MODELESS_ALWAYS
+syn keyword baanConstant MODIFY.SET
+syn keyword baanConstant MULTI_OCC
+syn keyword baanConstant NEXT.FRM
+syn keyword baanConstant NEXT.SET
+syn keyword baanConstant NEXT.VIEW
+syn keyword baanConstant NO.PERM.DEFINED
+syn keyword baanConstant NO.PERMISSION
+syn keyword baanConstant NO.RESTRICTION
+syn keyword baanConstant NO.ROLLBACK
+syn keyword baanConstant OLESVR.INIT
+syn keyword baanConstant OLESVR.OBJECT.CREATED
+syn keyword baanConstant OLESVR.OBJECT.DESTROYED
+syn keyword baanConstant OS_OS400
+syn keyword baanConstant OS_UNIX
+syn keyword baanConstant OS_WINDOWS_95
+syn keyword baanConstant OS_WINDOWS_NT
+syn keyword baanConstant PERM.DELETE
+syn keyword baanConstant PERM.MODIFY
+syn keyword baanConstant PERM.READ
+syn keyword baanConstant PERM.UNKNOWN
+syn keyword baanConstant PERM.WRITE
+syn keyword baanConstant PI
+syn keyword baanConstant PREV.FRM
+syn keyword baanConstant PREV.SET
+syn keyword baanConstant PREV.VIEW
+syn keyword baanConstant PRINT.DATA
+syn keyword baanConstant PROGRESS.BAR
+syn keyword baanConstant PROGRESS.CANCEL
+syn keyword baanConstant PROGRESS.NOAUTODESTROY
+syn keyword baanConstant PROGRESS.RESIZEABLE
+syn keyword baanConstant PROGRESS.STOP
+syn keyword baanConstant PROGRESS.TIMER
+syn keyword baanConstant PRTCL
+syn keyword baanConstant PRTCL.END.TRACE
+syn keyword baanConstant PRTCL.EXECUTE
+syn keyword baanConstant PRTCL.FIELD.OPTION
+syn keyword baanConstant PRTCL.GET.DATA
+syn keyword baanConstant PRTCL.GET.DATA.ANSWER
+syn keyword baanConstant PRTCL.MASK
+syn keyword baanConstant PRTCL.PUT.DATA
+syn keyword baanConstant PRTCL.START.TRACE
+syn keyword baanConstant PRTCL.UNKNOWN
+syn keyword baanConstant PSMAXSIZE
+syn keyword baanConstant QSS.EQLE
+syn keyword baanConstant QSS.EQUAL
+syn keyword baanConstant QSS.FIRST
+syn keyword baanConstant QSS.GT
+syn keyword baanConstant QSS.GTEQ
+syn keyword baanConstant QSS.LAST
+syn keyword baanConstant QSS.LESS
+syn keyword baanConstant QSS.LOOKUP.FOR.STRUCT
+syn keyword baanConstant QSS.NE
+syn keyword baanConstant QSS.SRC.DUPL.ALLOWED
+syn keyword baanConstant QSS.SRC.IS.SORTED
+syn keyword baanConstant RDI.CENTER
+syn keyword baanConstant RDI.LEFT
+syn keyword baanConstant RDI.LOWER
+syn keyword baanConstant RDI.NONE
+syn keyword baanConstant RDI.RIGHT
+syn keyword baanConstant RDI.UPPER
+syn keyword baanConstant RECOVER.SET
+syn keyword baanConstant RESIZE.FRM
+syn keyword baanConstant RESTART.INPUT
+syn keyword baanConstant ROTATE.CURR
+syn keyword baanConstant RP_IPCINFO_FLAG
+syn keyword baanConstant RP_INPROC
+syn keyword baanConstant RP_NOWAIT
+syn keyword baanConstant RP_NOWAIT_WITH_EVENT
+syn keyword baanConstant RP_WAIT
+syn keyword baanConstant RUN.JOB
+syn keyword baanConstant SAVE.DEFAULTS
+syn keyword baanConstant SBADJUST
+syn keyword baanConstant SBCONFIRM
+syn keyword baanConstant SBDOWN
+syn keyword baanConstant SBEND
+syn keyword baanConstant SBHOME
+syn keyword baanConstant SBMOVE
+syn keyword baanConstant SBPGDOWN
+syn keyword baanConstant SBPGUP
+syn keyword baanConstant SBPRESS
+syn keyword baanConstant SBRELEASE
+syn keyword baanConstant SBUP
+syn keyword baanConstant SEQ_F_R_LCK
+syn keyword baanConstant SEQ_F_W_LCK
+syn keyword baanConstant SEQ_R_LCK
+syn keyword baanConstant SEQ_W_LCK
+syn keyword baanConstant SESSION_NO_PERMISSION
+syn keyword baanConstant SESSION_DELETE_PERMISSION
+syn keyword baanConstant SESSION_INSERT_PERMISSION
+syn keyword baanConstant SESSION_MODIFY_PERMISSION
+syn keyword baanConstant SESSION_DISPLAY_PERMISSION
+syn keyword baanConstant SESSION_PRINT_PERMISSION
+syn keyword baanConstant SINGLE_OCC
+syn keyword baanConstant ST.ADD.SET
+syn keyword baanConstant ST.BITSET
+syn keyword baanConstant ST.BITSET.ZOOM
+syn keyword baanConstant ST.BRP.RUN
+syn keyword baanConstant ST.BRP.SEND
+syn keyword baanConstant ST.DEF.FIND
+syn keyword baanConstant ST.DOUBLE
+syn keyword baanConstant ST.DOUBLE.ZOOM
+syn keyword baanConstant ST.DUPL.OCCUR
+syn keyword baanConstant ST.ENUM
+syn keyword baanConstant ST.ENUM.ZOOM
+syn keyword baanConstant ST.FIND.DATA
+syn keyword baanConstant ST.FIRST.SET
+syn keyword baanConstant ST.LAST.SET
+syn keyword baanConstant ST.MARK.DELETE
+syn keyword baanConstant ST.MARK.OCCUR
+syn keyword baanConstant ST.MB
+syn keyword baanConstant ST.MB.ZOOM
+syn keyword baanConstant ST.MODIFY.SET
+syn keyword baanConstant ST.MULTI.2
+syn keyword baanConstant ST.MULTI.3
+syn keyword baanConstant ST.NUM.ZOOM
+syn keyword baanConstant ST.NUMERIC
+syn keyword baanConstant ST.PROG.BUSY
+syn keyword baanConstant ST.SINGLE.1
+syn keyword baanConstant ST.SINGLE.3
+syn keyword baanConstant ST.SINGLE.4
+syn keyword baanConstant ST.SORT
+syn keyword baanConstant ST.STRING
+syn keyword baanConstant ST.STRING.ZOOM
+syn keyword baanConstant ST.TEXT
+syn keyword baanConstant ST.TEXT.ZOOM
+syn keyword baanConstant ST.TIME
+syn keyword baanConstant ST.TIME.ZOOM
+syn keyword baanConstant ST.UPDATE.DB
+syn keyword baanConstant ST.ZOOM
+syn keyword baanConstant START.CHART
+syn keyword baanConstant START.QUERY
+syn keyword baanConstant START.SET
+syn keyword baanConstant STAT_EXECUTABLE
+syn keyword baanConstant STAT_READABLE
+syn keyword baanConstant STAT_WRITEABLE
+syn keyword baanConstant SUBDAL
+syn keyword baanConstant TDIR
+syn keyword baanConstant TEXT.MANAGER
+syn keyword baanConstant TFILE
+syn keyword baanConstant TRUE
+syn keyword baanConstant UPDATE.DB
+syn keyword baanConstant USER.0
+syn keyword baanConstant USER.1
+syn keyword baanConstant USER.2
+syn keyword baanConstant USER.3
+syn keyword baanConstant USER.4
+syn keyword baanConstant USER.5
+syn keyword baanConstant USER.6
+syn keyword baanConstant USER.7
+syn keyword baanConstant USER.8
+syn keyword baanConstant USER.9
+syn keyword baanConstant WINDOW.DIALOG
+syn keyword baanConstant WINDOW.LIST
+syn keyword baanConstant WINDOW.MMTCONTROLLER
+syn keyword baanConstant WINDOW.MMTSATELLITE
+syn keyword baanConstant WINDOW.MODAL.MENU
+syn keyword baanConstant WINDOW.MODELESS.MENU
+syn keyword baanConstant WINDOW.NONE
+syn keyword baanConstant WINDOW.PARAMETER
+syn keyword baanConstant WINDOW.SYNCHRONIZED
+syn keyword baanConstant WINDOW.WIZARD
+syn keyword baanConstant WITH.ROLLBACK
+syn keyword baanConstant WU.DLL
+syn keyword baanConstant WU.DOMA
+syn keyword baanConstant WU.FLDN
+syn keyword baanConstant WU.LANGOPT
+syn keyword baanConstant WU.MESS
+syn keyword baanConstant WU.QUES
+syn keyword baanConstant WU.SESS
+syn keyword baanConstant WU.TABL
+syn keyword baanConstant XML_DATA
+syn keyword baanConstant XML_DTD
+syn keyword baanConstant XML_ELEMENT
+syn keyword baanConstant XML_PI
+syn keyword baanConstant Z.AUTOACCEPT
+syn keyword baanConstant Z.AUTOZOOM
+syn keyword baanConstant Z.MENU
+syn keyword baanConstant Z.SESSION
+syn keyword baanConstant ZOOM
+
+
+"************************************* 4GL ************************************"
+" Program section
+syn match baan4glh "declaration:"
+syn match baan4glh "functions:"
+syn match baan4glh "before\.program:"
+syn match baan4glh "on\.error:"
+syn match baan4glh "after\.program:"
+syn match baan4glh "after\.update.db.commit:"
+syn match baan4glh "before\.display\.object:"
+
+" Form section
+syn match baan4glh "form\.\d\+:"
+syn match baan4glh "form\.all:"
+syn match baan4glh "form\.other:"
+syn match baan4gl  "init\.form:"
+syn match baan4gl  "before\.form:"
+syn match baan4gl  "after\.form:"
+
+" Choice section
+syn match baan4glh "choice\.start\.set:"
+syn match baan4glh "choice\.first\.view:"
+syn match baan4glh "choice\.next\.view:"
+syn match baan4glh "choice\.prev\.view:"
+syn match baan4glh "choice\.last\.view:"
+syn match baan4glh "choice\.def\.find:"
+syn match baan4glh "choice\.find\.data:"
+syn match baan4glh "choice\.first\.set:"
+syn match baan4glh "choice\.next\.set:"
+syn match baan4glh "choice\.display\.set:"
+syn match baan4glh "choice\.prev\.set:"
+syn match baan4glh "choice\.rotate\.curr:"
+syn match baan4glh "choice\.last\.set:"
+syn match baan4glh "choice\.add\.set:"
+syn match baan4glh "choice\.update\.db:"
+syn match baan4glh "choice\.dupl\.occur:"
+syn match baan4glh "choice\.recover\.set:"
+syn match baan4glh "choice\.mark\.delete:"
+syn match baan4glh "choice\.mark\.occur:"
+syn match baan4glh "choice\.change\.order:"
+syn match baan4glh "choice\.modify\.set:"
+syn match baan4glh "choice\.restart\.input:"
+syn match baan4glh "choice\.print\.data:"
+syn match baan4glh "choice\.create\.job:"
+syn match baan4glh "choice\.form\.tab\.change:"
+syn match baan4glh "choice\.first\.frm:"
+syn match baan4glh "choice\.next\.frm:"
+syn match baan4glh "choice\.prev\.frm:"
+syn match baan4glh "choice\.last\.frm:"
+syn match baan4glh "choice\.resize\.frm:"
+syn match baan4glh "choice\.cmd\.options:"
+syn match baan4glh "choice\.zoom:"
+syn match baan4glh "choice\.interrupt:"
+syn match baan4glh "choice\.end\.program:"
+syn match baan4glh "choice\.abort\.program:"
+syn match baan4glh "choice\.cont\.process:"
+syn match baan4glh "choice\.text\.manager:"
+syn match baan4glh "choice\.run\.job:"
+syn match baan4glh "choice\.global\.delete:"
+syn match baan4glh "choice\.global\.copy:"
+syn match baan4glh "choice\.save\.defaults"
+syn match baan4glh "choice\.get\.defaults:"
+syn match baan4glh "choice\.start\.chart:"
+syn match baan4glh "choice\.start\.query:"
+syn match baan4glh "choice\.user\.\d:"
+syn match baan4glh "choice\.ask\.helpinfo:"
+syn match baan4glh "choice\.calculator:"
+syn match baan4glh "choice\.calendar:"
+syn match baan4glh "choice\.bms:"
+syn match baan4glh "choice\.cmd\.whats\.this:"
+syn match baan4glh "choice\.help\.index:"
+syn match baan4gl  "before\.choice:"
+syn match baan4gl  "on\.choice:"
+syn match baan4gl  "after\.choice:"
+
+" Field section
+syn match baan4glh "field\.\l\{5}\d\{3}\.\l\{4,8}\.\=c\=:"
+syn match baan4glh "field\.e\..\+:"
+syn match baan4glh "field\.all:"
+syn match baan4glh "field\.other:"
+syn match baan4gl  "init\.field:"
+syn match baan4gl  "before\.field:"
+syn match baan4gl  "before\.input:"
+syn match baan4gl  "before\.display:"
+syn match baan4gl "selection\.filter:"
+syn match baan4gl  "before\.zoom:"
+syn match baan4gl  "before\.checks:"
+syn match baan4gl  "domain\.error:"
+syn match baan4gl  "ref\.input:"
+syn match baan4gl  "ref\.display:"
+syn match baan4gl  "check\.input:"
+syn match baan4gl  "on\.input:"
+syn match baan4gl  "when\.field\.changes:"
+syn match baan4gl  "after\.zoom:"
+syn match baan4gl  "after\.input:"
+syn match baan4gl  "after\.display:"
+syn match baan4gl  "after\.field:"
+
+" Group section
+syn match baan4glh "group\.\d\+:"
+syn match baan4gl "init\.group:"
+syn match baan4gl "before\.group:"
+syn match baan4gl "after\.group:"
+
+" Zoom section
+syn match baan4glh "zoom\.from\..\+:"
+syn match baan4gl "on\.entry:"
+syn match baan4gl "on\.exit:"
+
+" Main table section
+syn match baan4glh "main\.table\.io:"
+syn match baan4gl "before\.read:"
+syn match baan4gl "after\.read:"
+syn match baan4gl "before\.write:"
+syn match baan4gl "after\.write:"
+syn match baan4gl "after\.skip\.write:"
+syn match baan4gl "before\.rewrite:"
+syn match baan4gl "after\.rewrite:"
+syn match baan4gl "after\.skip\.rewrite:"
+syn match baan4gl "before\.delete:"
+syn match baan4gl "after\.delete:"
+syn match baan4gl "after\.skip\.delete:"
+syn match baan4gl "read\.view:"
+
+"**************************** Dal Hooks ********************************
+syn keyword baanDalHook after.abort.transaction after.commit.transaction after.destroy.object 
+syn keyword baanDalHook after.change.object after.get.object after.new.object after.save.object before.change.object
+syn keyword baanDalHook before.destroy.object before.get.object before.new.object before.open.object.set before.save.object
+syn keyword baanDalHook method.is.allowed set.object.defaults
+
+syn match baanDalHook "\l\{5}\d\{3}\.\l\{4,8}\.check"
+syn match baanDalHook "\l\{5}\d\{3}\.\l\{4,8}\.is.valid"
+syn match baanDalHook "\l\{5}\d\{3}\.\l\{4,8}\.is.applicable"
+syn match baanDalHook "\l\{5}\d\{3}\.\l\{4,8}\.is.never.applicable"
+syn match baanDalHook "\l\{5}\d\{3}\.\l\{4,8}\.is.derived"
+syn match baanDalHook "\l\{5}\d\{3}\.\l\{4,8}\.is.readonly"
+syn match baanDalHook "\l\{5}\d\{3}\.\l\{4,8}\.is.mandatory"
+syn match baanDalHook "\l\{5}\d\{3}\.\l\{4,8}\.make.valid"
+syn match baanDalHook "\l\{5}\d\{3}\.\l\{4,8}\.update"
+syn match baanDalHook "\l\{5}\d\{3}\.\l\{4,8}\..*\.is.applicable"
+
+
+"number without a dot."
+syn match  baanNumber		"\<\-\=\d\+\>"
+"number with dot"
+syn match  baanNumber		"\<\-\=\d\+\.\d*\>"
+"number starting with a dot"
+syn match  baanNumber		"\<\-\=\.\d\+\>"
+
+" String Error does not work correct with vim 6.0
+syn match   baanOpenStringError +^[^^"]+ display contained excludenl
+syn region  baanString	start=+"+  skip=+""+  end=+"+ end=+^[^^]+ contains=baanOpenStringError keepend
+
+" Comment"
+syn match   baanComment "|$"
+syn match   baanComment "|.$"
+syn match   baanComment "|[^ ]"
+syn match   baanComment	"|[^#].*[^ ]"
+syn match   baanCommenth "^|#lra.*$"
+syn match   baanCommenth "^|#mdm.*$"
+syn match   baanCommenth "^|#[0-9][0-9][0-9][0-9][0-9].*$"
+syn match   baanCommenth "^|#N\=o\=Include.*$"
+" Oldcode"
+syn match   baanUncommented	"^|[^*#].*[^ ]"
+" DLL section
+" SpaceError"
+syn match    baanSpaces	" "
+syn match    baanSpaceError	"\s*$"
+syn match    baanSpaceError	"        "
+
+" Baan error"
+
+if exists("baan_code_stds") && baan_code_stds
+syn match  BaanError	"^\s*i\..*=\s*\(\k\|\"\)*\s*$"		"assignment of an input var"
+syn match  BaanError	"^\s*ref.*\s[ilse]\..*$"		" ref variable defined with i, l, e and s"
+syn match  BaanError	"^\s*const.*\s[olse]\..*$"		" const variable defined with o, l, e and s"
+syn match  BaanError	"^\s*static.*\s\(i\|g\|l\|o\|io\)\..*$"	" static defined without s."
+syn match  BaanError	"^\s*\(domain\s\|long\s\|string\s\).*\so\.\k*[,)]"	" ref variable without ref"
+syn match  BaanError	"^\s*\(domain\s\|long\s\|string\s\).*\se\.\k*[,)]"	" 'e.' variable without extern"
+syn match  BaanError	"^\s*i\..*,\s*|\s*ref.*$"	" 
+endif
+
+"**************************** bshell functions ********************************
+syn match   baanBshell "\<shiftl\$"
+syn match   baanBshell "\<shiftr\$"
+syn match   baanBshell "\<shiftc\$"
+syn match   baanBshell "\<strip\$"
+syn match   baanBshell "\<tolower\$"
+syn match   baanBshell "\<toupper\$"
+syn keyword baanBshell isdigit
+syn keyword baanBshell isspace
+syn match   baanBshell "\<chr\$"
+syn keyword baanBshell len.in.bytes
+syn keyword baanBshell rpos
+syn match   baanBshell "\<sprintf\$"
+syn match   baanBshell "\<vsprintf\$"
+syn match   baanBshell "\<concat\$"
+syn keyword baanBshell gregdate
+syn match   baanBshell "\<w.to.dat\$"
+syn keyword baanBshell ttyname
+syn match   baanBshell "\<ttyname\$"
+syn match   baanBshell "\<creat.tmp.file\$"
+syn match   baanBshell "\<string.set\$"
+syn keyword baanBshell string.scan
+syn keyword baanBshell not.fixed
+syn keyword baanBshell dummy
+syn keyword baanBshell alloc.mem
+syn keyword baanBshell free.mem
+syn keyword baanBshell copy.mem
+syn keyword baanBshell cmp.mem
+syn keyword baanBshell set.mem
+syn keyword baanBshell num.to.date
+syn keyword baanBshell date.to.num
+syn keyword baanBshell num.to.week
+syn keyword baanBshell week.to.num
+syn match   baanBshell "\<num.to.date\$"
+syn keyword baanBshell expr.compile
+syn keyword baanBshell l.expr
+syn keyword baanBshell d.expr
+syn match   baanBshell "\<s.expr\$"
+syn keyword baanBshell expr.free
+syn keyword baanBshell compnr.check
+syn match   baanBshell "\<bse.dir\$"
+syn match   baanBshell "\<bse.tmp.dir\$"
+syn match   baanBshell "\<bse.release\$"
+syn match   baanBshell "\<bse.portset\$"
+syn match   baanBshell "\<getenv\$"
+syn keyword baanBshell base.extern
+syn keyword baanBshell at.base
+syn keyword baanBshell get.compnr
+syn keyword baanBshell base.next
+syn keyword baanBshell get.argc
+syn keyword baanBshell get.long.arg
+syn keyword baanBshell get.double.arg
+syn keyword baanBshell get.string.arg
+syn keyword baanBshell get.arg.type
+syn keyword baanBshell put.long.arg
+syn keyword baanBshell put.double.arg
+syn keyword baanBshell put.string.arg
+syn keyword baanBshell setenv
+syn keyword baanBshell cmp.password
+syn match   baanBshell "\<crypt.password\$"
+syn keyword baanBshell is.password.ok
+syn keyword baanBshell block.cipher.encrypt
+syn keyword baanBshell block.cipher.decrypt
+syn keyword baanBshell encrypt.user.password
+syn keyword baanBshell verify.user.password
+syn keyword baanBshell asm.put.instance.id
+syn match   baanBshell "\<date.to.inputstr\$"
+syn keyword baanBshell inputstr.to.date
+syn match   baanBshell "\<hostname\$"
+syn keyword baanBshell base64.encode
+syn keyword baanBshell base64.decode
+syn keyword baanBshell sha.create
+syn keyword baanBshell sha.initialize
+syn keyword baanBshell sha.add.data
+syn keyword baanBshell sha.compute.output
+syn keyword baanBshell sha.destroy
+syn match   baanBshell "\<uuid.generate\$"
+syn match   baanBshell "\<uuid.format\$"
+syn keyword baanBshell resolve.labels.by.lookupkey
+syn keyword baanBshell resolve.labels.by.codepair
+syn keyword baanBshell lookupkey.hash
+syn keyword baanBshell lookupkey.unhash
+syn match   baanBshell "\<mb.long.to.str\$"
+syn keyword baanBshell mb.width
+syn match   baanBshell "\<mb.localename\$"
+syn match   baanBshell "\<mb.tss.clean\$"
+syn match   baanBshell "\<mb.ext.clean\$"
+syn match   baanBshell "\<mb.import\$"
+syn match   baanBshell "\<mb.export\$"
+syn keyword baanBshell mb.import.raw
+syn keyword baanBshell mb.export.raw
+syn keyword baanBshell uni.import
+syn keyword baanBshell uni.export
+syn keyword baanBshell utf8.import
+syn keyword baanBshell utf8.export
+syn keyword baanBshell mb.strpos
+syn keyword baanBshell mb.scrpos
+syn keyword baanBshell mb.char
+syn keyword baanBshell mb.type
+syn match   baanBshell "\<mb.cast\$"
+syn match   baanBshell "\<mb.cast.to.str\$"
+syn keyword baanBshell mb.display
+syn keyword baanBshell mb.isbidi
+syn keyword baanBshell mb.isbidi.language
+syn match   baanBshell "\<mb.rev\$"
+syn keyword baanBshell mb.hasbidi
+syn keyword baanBshell mb.kb.lang
+syn keyword baanBshell mb.locale.info
+syn keyword baanBshell mb.locale.enumerate
+syn keyword baanBshell mb.nsets
+syn keyword baanBshell mb.set.info
+syn keyword baanBshell mb.char.info
+syn keyword baanBshell key.compare
+syn keyword baanBshell set.fields.default
+syn keyword baanBshell table.round
+syn keyword baanBshell halfadj
+syn keyword baanBshell round
+syn keyword baanBshell format.round
+syn match   baanBshell "\<edit\$"
+syn match   baanBshell "\<str\$"
+syn keyword baanBshell lval
+syn keyword baanBshell acos
+syn keyword baanBshell asin
+syn keyword baanBshell atan
+syn keyword baanBshell atan2
+syn keyword baanBshell cosh
+syn keyword baanBshell sinh
+syn keyword baanBshell tanh
+syn keyword baanBshell log10
+syn keyword baanBshell sqrt
+syn keyword baanBshell lpow
+syn keyword baanBshell random
+syn keyword baanBshell srand
+syn keyword baanBshell rnd.init
+syn keyword baanBshell rnd.i
+syn keyword baanBshell rnd.d
+syn keyword baanBshell double.cmp
+syn match   baanBshell "\<tab\$"
+syn keyword baanBshell aux.open
+syn keyword baanBshell aux.print
+syn keyword baanBshell aux.close
+syn keyword baanBshell refresh
+syn keyword baanBshell cl.screen
+syn match   baanBshell "\<delch\$"
+syn match   baanBshell "\<deleteln\$"
+syn match   baanBshell "\<insch\$"
+syn match   baanBshell "\<insertln\$"
+syn keyword baanBshell change.window
+syn keyword baanBshell data.input
+syn keyword baanBshell del.window
+syn keyword baanBshell frame.window
+syn keyword baanBshell new.window
+syn keyword baanBshell window.size
+syn keyword baanBshell move.window
+syn keyword baanBshell resize.window
+syn keyword baanBshell get.row
+syn keyword baanBshell get.col
+syn keyword baanBshell get.cp
+syn keyword baanBshell map.window
+syn keyword baanBshell unmap.window
+syn keyword baanBshell set.bg.color
+syn keyword baanBshell set.fg.color
+syn keyword baanBshell no.scroll
+syn keyword baanBshell scroll
+syn keyword baanBshell cursor.on
+syn keyword baanBshell cursor.off
+syn keyword baanBshell sub.window
+syn keyword baanBshell current.window
+syn match   baanBshell "\<keyin\$"
+syn keyword baanBshell dump.screen
+syn keyword baanBshell first.window
+syn keyword baanBshell last.window
+syn keyword baanBshell free.window
+syn keyword baanBshell #input
+syn keyword baanBshell #output
+syn keyword baanBshell wrebuild
+syn keyword baanBshell select.event.input
+syn keyword baanBshell next.event
+syn keyword baanBshell peek.event
+syn keyword baanBshell pending.events
+syn keyword baanBshell send.event
+syn keyword baanBshell send.signal
+syn keyword baanBshell get.display.data
+syn keyword baanBshell open.display
+syn keyword baanBshell link.display
+syn keyword baanBshell link.keyboard
+syn keyword baanBshell unlink.keyboard
+syn keyword baanBshell close.display
+syn keyword baanBshell current.display
+syn keyword baanBshell change.display
+syn keyword baanBshell sync.display.server
+syn match   baanBshell "\<get.class.name\$"
+syn keyword baanBshell create.mwindow
+syn keyword baanBshell current.mwindow
+syn keyword baanBshell change.mwindow
+syn keyword baanBshell set.mwindow.title
+syn keyword baanBshell set.mwindow.size
+syn keyword baanBshell set.mwindow.mode
+syn keyword baanBshell get.mwindow.mode
+syn keyword baanBshell destroy.mwindow
+syn keyword baanBshell dialog
+syn keyword baanBshell get.mwindow.size
+syn keyword baanBshell create.bar
+syn keyword baanBshell current.bar
+syn keyword baanBshell change.bar
+syn keyword baanBshell change.bar.attr
+syn keyword baanBshell destroy.bar
+syn keyword baanBshell create.bar.button
+syn keyword baanBshell change.bar.item.attr
+syn keyword baanBshell destroy.bar.item
+syn keyword baanBshell create.object
+syn keyword baanBshell change.object
+syn keyword baanBshell get.object
+syn keyword baanBshell query.object
+syn keyword baanBshell destroy.object
+syn keyword baanBshell get.event.attribute
+syn keyword baanBshell create.sub.object
+syn keyword baanBshell create.sub.object.by.id
+syn keyword baanBshell change.sub.object
+syn keyword baanBshell get.sub.object
+syn keyword baanBshell query.sub.object
+syn keyword baanBshell destroy.sub.object
+syn keyword baanBshell create.arglist
+syn keyword baanBshell add.arg
+syn keyword baanBshell add.ref.arg
+syn keyword baanBshell delete.arg
+syn keyword baanBshell print.arglist
+syn keyword baanBshell destroy.arglist
+syn keyword baanBshell get.object.class.list
+syn keyword baanBshell get.object.class
+syn keyword baanBshell get.sub.object.class
+syn keyword baanBshell get.resource.class
+syn keyword baanBshell get.event.class
+syn keyword baanBshell get.pixmap.info
+syn keyword baanBshell compress.pixmap
+syn keyword baanBshell decompress.pixmap
+syn keyword baanBshell get.window.attrs
+syn keyword baanBshell get.mwindow.attrs
+syn keyword baanBshell create.gc
+syn keyword baanBshell change.gc
+syn keyword baanBshell get.gc
+syn keyword baanBshell destroy.gc
+syn keyword baanBshell load.font
+syn keyword baanBshell query.font
+syn keyword baanBshell free.font
+syn keyword baanBshell get.typeface
+syn keyword baanBshell list.fonts
+syn keyword baanBshell text.extends
+syn keyword baanBshell inherit.object
+syn keyword baanBshell create.gtext
+syn keyword baanBshell create.line
+syn keyword baanBshell create.polyline
+syn keyword baanBshell create.polygon
+syn keyword baanBshell create.rectangle
+syn keyword baanBshell create.arc
+syn keyword baanBshell create.pie
+syn keyword baanBshell create.composite
+syn keyword baanBshell create.image
+syn keyword baanBshell change.gtext
+syn keyword baanBshell change.gtext.label
+syn keyword baanBshell change.line
+syn keyword baanBshell change.polyline
+syn keyword baanBshell change.polygon
+syn keyword baanBshell change.rectangle
+syn keyword baanBshell change.arc
+syn keyword baanBshell change.pie
+syn keyword baanBshell get.gtext
+syn keyword baanBshell get.gtext.label
+syn keyword baanBshell get.line
+syn keyword baanBshell get.polyline
+syn keyword baanBshell get.polygon
+syn keyword baanBshell get.rectangle
+syn keyword baanBshell get.arc
+syn keyword baanBshell get.pie
+syn keyword baanBshell get.composite
+syn keyword baanBshell get.image
+syn keyword baanBshell move.gpart
+syn keyword baanBshell shift.gpart
+syn keyword baanBshell which.gpart
+syn keyword baanBshell which.gparts
+syn keyword baanBshell change.gpart.gc
+syn keyword baanBshell get.gpart.gc
+syn keyword baanBshell destroy.gpart
+syn keyword baanBshell destroy.composite
+syn keyword baanBshell first.gpart
+syn keyword baanBshell last.gpart
+syn keyword baanBshell next.gpart
+syn keyword baanBshell prev.gpart
+syn keyword baanBshell change.gpart.attr
+syn keyword baanBshell get.gpart.attr
+syn keyword baanBshell get.gpart
+syn keyword baanBshell get.gpart.box
+syn keyword baanBshell resize.gpart.box
+syn keyword baanBshell move.gpart.box
+syn keyword baanBshell activate
+syn keyword baanBshell reactivate
+syn keyword baanBshell act.and.sleep
+syn keyword baanBshell sleep
+syn match   baanBshell "\<receive.bucket\$"
+syn keyword baanBshell send.bucket
+syn keyword baanBshell send.wait
+syn keyword baanBshell bms.send
+syn match   baanBshell "\<bms.receive\$"
+syn keyword baanBshell bms.receive.buffer
+syn keyword baanBshell bms.add.mask
+syn keyword baanBshell bms.delete.mask
+syn keyword baanBshell bms.init
+syn keyword baanBshell wait.and.activate
+syn keyword baanBshell abort
+syn keyword baanBshell kill
+syn keyword baanBshell shell
+syn match   baanBshell "\<argv\$"
+syn keyword baanBshell argc
+syn keyword baanBshell get.var
+syn keyword baanBshell put.var
+syn keyword baanBshell get.ref.var
+syn keyword baanBshell put.ref.var
+syn keyword baanBshell get.indexed.var
+syn keyword baanBshell put.indexed.var
+syn keyword baanBshell on.change.check
+syn keyword baanBshell off.change.check
+syn keyword baanBshell changed
+syn keyword baanBshell not.curr
+syn keyword baanBshell handle.report.pool
+syn keyword baanBshell get.symbol
+syn keyword baanBshell suspend
+syn keyword baanBshell set.timer
+syn keyword baanBshell set.alarm
+syn keyword baanBshell kill.timer
+syn keyword baanBshell pstat
+syn keyword baanBshell oipstat
+syn keyword baanBshell obj_in_core
+syn keyword baanBshell renice
+syn keyword baanBshell kill.pgrp
+syn keyword baanBshell set.pgrp
+syn keyword baanBshell get.pgrp
+syn keyword baanBshell grab.mwindow
+syn keyword baanBshell signal
+syn keyword baanBshell ptrace
+syn keyword baanBshell link.on.stack
+syn match   baanBshell "\<zoom.to\$"
+syn keyword baanBshell retry.point
+syn keyword baanBshell jump.retry.point
+syn keyword baanBshell retry.level
+syn keyword baanBshell get.bw.hostname
+syn keyword baanBshell exit
+syn match   baanBshell "\<dte\$"
+syn keyword baanBshell times.on
+syn keyword baanBshell times.off
+syn keyword baanBshell times.close
+syn keyword baanBshell times.total
+syn keyword baanBshell times.lines
+syn keyword baanBshell date.num
+syn keyword baanBshell time.num
+syn keyword baanBshell date.time.utc
+syn keyword baanBshell utc.to.local
+syn keyword baanBshell local.to.utc
+syn keyword baanBshell input.field
+syn keyword baanBshell output.field
+syn keyword baanBshell key.to.option
+syn keyword baanBshell option.to.key
+syn keyword baanBshell get.choice.data
+syn keyword baanBshell reset.zoom.info
+syn keyword baanBshell next.field
+syn keyword baanBshell print.form
+syn keyword baanBshell set.field.blank
+syn keyword baanBshell read.form
+syn keyword baanBshell read.fast.form
+syn keyword baanBshell change.form.field
+syn keyword baanBshell copy.form.field
+syn keyword baanBshell delete.form.field
+syn keyword baanBshell iget.field.attr
+syn keyword baanBshell sget.field.attr
+syn keyword baanBshell menu.control
+syn keyword baanBshell wait
+syn match baanBshell "\<bms.peek\$"
+syn keyword baanBshell create.menu
+syn keyword baanBshell refresh.bar.menu
+syn keyword baanBshell load.menu
+syn keyword baanBshell current.menu
+syn keyword baanBshell change.menu
+syn keyword baanBshell popup.menu
+syn keyword baanBshell set.menu
+syn keyword baanBshell change.menu.attr
+syn keyword baanBshell destroy.menu
+syn keyword baanBshell create.menu.button
+syn keyword baanBshell create.cascade.button
+syn keyword baanBshell change.menu.item.name
+syn keyword baanBshell change.cascade.menu
+syn keyword baanBshell change.menu.item.attr
+syn keyword baanBshell get.cascade.menu
+syn keyword baanBshell destroy.menu.item
+syn keyword baanBshell form.control
+syn match   baanBshell "\<form.text\$"
+syn keyword baanBshell status.on
+syn keyword baanBshell status.off
+syn keyword baanBshell status.mess
+syn keyword baanBshell status.field
+syn match   baanBshell "\<enum.descr\$"
+syn keyword baanBshell mark.occurrence
+syn keyword baanBshell start.mark
+syn keyword baanBshell end.mark
+syn keyword baanBshell get.attrs
+syn keyword baanBshell put.attrs
+syn keyword baanBshell act.zoom
+syn keyword baanBshell init.first
+syn keyword baanBshell init.last
+syn keyword baanBshell init.next
+syn keyword baanBshell init.prev
+syn keyword baanBshell set.max
+syn keyword baanBshell set.min
+syn keyword baanBshell set.fmax
+syn keyword baanBshell set.fmin
+syn keyword baanBshell print.const
+syn keyword baanBshell is.option.on
+syn keyword baanBshell brp.build
+syn keyword baanBshell brp.field
+syn keyword baanBshell pathname
+syn keyword baanBshell file.stat
+syn keyword baanBshell file.cp
+syn keyword baanBshell file.mv
+syn keyword baanBshell file.rm
+syn keyword baanBshell file.chown
+syn keyword baanBshell file.chmod
+syn keyword baanBshell stat.info
+syn keyword baanBshell disk.info
+syn keyword baanBshell mkdir
+syn keyword baanBshell rmdir
+syn keyword baanBshell open.message
+syn keyword baanBshell send.message
+syn keyword baanBshell recv.message
+syn keyword baanBshell close.message
+syn keyword baanBshell store.byte
+syn keyword baanBshell store.short
+syn keyword baanBshell store.long
+syn keyword baanBshell store.float
+syn keyword baanBshell store.double
+syn keyword baanBshell load.byte
+syn keyword baanBshell load.short
+syn keyword baanBshell load.long
+syn keyword baanBshell load.float
+syn keyword baanBshell load.double
+syn keyword baanBshell bit.and
+syn keyword baanBshell bit.or
+syn keyword baanBshell bit.exor
+syn keyword baanBshell bit.inv
+syn keyword baanBshell bit.in
+syn keyword baanBshell bit.shiftl
+syn keyword baanBshell bit.shiftr
+syn keyword baanBshell check.domain
+syn keyword baanBshell check.all.domain
+syn keyword baanBshell seq.clearerr
+syn keyword baanBshell seq.eof
+syn keyword baanBshell seq.error
+syn keyword baanBshell seq.open
+syn keyword baanBshell seq.close
+syn keyword baanBshell seq.flush
+syn keyword baanBshell seq.rewind
+syn keyword baanBshell seq.tell
+syn keyword baanBshell seq.read
+syn keyword baanBshell seq.write
+syn match   baanBshell "\<seq.getc\$"
+syn match   baanBshell "\<seq.putc\$"
+syn match   baanBshell "\<seq.ungetc\$"
+syn keyword baanBshell seq.skip
+syn keyword baanBshell seq.seek
+syn keyword baanBshell seq.gets
+syn keyword baanBshell seq.puts
+syn keyword baanBshell seq.unlink
+syn keyword baanBshell seq.spool.line
+syn keyword baanBshell seq.r.long
+syn keyword baanBshell seq.w.long
+syn keyword baanBshell seq.r.short
+syn keyword baanBshell seq.w.short
+syn keyword baanBshell seq.lock
+syn keyword baanBshell seq.unlock
+syn keyword baanBshell seq.islocked
+syn keyword baanBshell pipe.open
+syn keyword baanBshell pipe.close
+syn keyword baanBshell pipe.flush
+syn keyword baanBshell pipe.gets
+syn keyword baanBshell pipe.puts
+syn keyword baanBshell pipe.read
+syn keyword baanBshell pipe.write
+syn keyword baanBshell pipe.clearerr
+syn keyword baanBshell pipe.eof
+syn keyword baanBshell pipe.error
+syn keyword baanBshell sock.connect
+syn keyword baanBshell sock.listen
+syn keyword baanBshell sock.accept
+syn keyword baanBshell sock.recv
+syn keyword baanBshell sock.send
+syn keyword baanBshell sock.flush
+syn keyword baanBshell sock.close
+syn keyword baanBshell sock.inherit
+syn keyword baanBshell sock.clearerr
+syn keyword baanBshell sock.eof
+syn keyword baanBshell sock.error
+syn keyword baanBshell get.system.info
+syn keyword baanBshell get.db.count
+syn keyword baanBshell get.db.system.info
+syn keyword baanBshell path.is.absolute
+syn keyword baanBshell make.path.absolute
+syn keyword baanBshell fstat.info
+syn keyword baanBshell dir.open
+syn keyword baanBshell dir.open.tree
+syn keyword baanBshell dir.close
+syn keyword baanBshell dir.entry
+syn keyword baanBshell dir.rewind
+syn keyword baanBshell ims.clearerr
+syn keyword baanBshell ims.eof
+syn keyword baanBshell ims.error
+syn keyword baanBshell ims.close
+syn keyword baanBshell ims.flush
+syn keyword baanBshell ims.rewind
+syn keyword baanBshell ims.tell
+syn keyword baanBshell ims.read
+syn keyword baanBshell ims.write
+syn match   baanBshell "\<ims.getc\$"
+syn match   baanBshell "\<ims.putc\$"
+syn keyword baanBshell ims.skip
+syn keyword baanBshell ims.seek
+syn keyword baanBshell ims.gets
+syn keyword baanBshell ims.puts
+syn keyword baanBshell ims.spool.line
+syn keyword baanBshell ims.r.long
+syn keyword baanBshell ims.w.long
+syn keyword baanBshell ims.r.short
+syn keyword baanBshell ims.w.short
+syn keyword baanBshell ims.openfba
+syn keyword baanBshell ims.openvba
+syn keyword baanBshell ims.getproperties
+syn keyword baanBshell ims.setvbaproperties
+syn keyword baanBshell db.get.physical.compnr
+syn keyword baanBshell db.bind
+syn keyword baanBshell db.unbind
+syn keyword baanBshell db.error
+syn keyword baanBshell db.error.message
+syn keyword baanBshell db.detail.error
+syn keyword baanBshell db.first
+syn keyword baanBshell db.last
+syn keyword baanBshell db.next
+syn keyword baanBshell db.prev
+syn keyword baanBshell db.gt
+syn keyword baanBshell db.ge
+syn keyword baanBshell db.eq
+syn keyword baanBshell db.curr
+syn keyword baanBshell db.lt
+syn keyword baanBshell db.le
+syn keyword baanBshell db.delete
+syn keyword baanBshell db.insert
+syn keyword baanBshell db.update
+syn keyword baanBshell db.check.row.changed
+syn keyword baanBshell db.check.row.domains
+syn keyword baanBshell db.check.restricted
+syn keyword baanBshell db.ref.handle.mode
+syn keyword baanBshell db.set.to.default
+syn keyword baanBshell db.create.index
+syn keyword baanBshell db.drop.index
+syn keyword baanBshell db.change.order
+syn keyword baanBshell db.create.table
+syn keyword baanBshell db.clear.table
+syn keyword baanBshell db.drop.table
+syn keyword baanBshell db.lock.table
+syn keyword baanBshell db.table.begin.import
+syn keyword baanBshell db.table.end.import
+syn keyword baanBshell db.table.update.statistics
+syn keyword baanBshell db.indexinfo
+syn keyword baanBshell db.nr.indices
+syn keyword baanBshell db.nr.rows
+syn keyword baanBshell db.row.length
+syn keyword baanBshell db.transaction.is.on
+syn keyword baanBshell commit.transaction
+syn keyword baanBshell set.transaction.readonly
+syn keyword baanBshell abort.transaction
+syn keyword baanBshell db.record.to.columns
+syn keyword baanBshell db.columns.to.record
+syn keyword baanBshell db.schedule
+syn keyword baanBshell db.permission
+syn keyword baanBshell db.set.notransaction
+syn keyword baanBshell db.set.transaction
+syn keyword baanBshell db.set.child.transaction
+syn keyword baanBshell get.db.permission
+syn keyword baanBshell get.session.permission
+syn keyword baanBshell ams.control
+syn keyword baanBshell db.get.old.row
+syn keyword baanBshell db.max.retry
+syn keyword baanBshell sql.parse
+syn keyword baanBshell sql.select.bind
+syn keyword baanBshell sql.where.bind
+syn keyword baanBshell sql.bind.input
+syn keyword baanBshell sql.exec
+syn keyword baanBshell sql.fetch
+syn keyword baanBshell sql.break
+syn keyword baanBshell sql.close
+syn keyword baanBshell sql.error
+syn keyword baanBshell sql.set.rds.full
+syn keyword baanBshell rdi.table
+syn keyword baanBshell rdi.index
+syn keyword baanBshell rdi.column
+syn keyword baanBshell rdi.table.column
+syn keyword baanBshell rdi.reference
+syn keyword baanBshell rdi.column.combined
+syn keyword baanBshell rdi.domain
+syn keyword baanBshell rdi.domain.long
+syn keyword baanBshell rdi.domain.double
+syn keyword baanBshell rdi.domain.string
+syn keyword baanBshell rdi.domain.raw
+syn keyword baanBshell rdi.domain.enum
+syn keyword baanBshell rdi.domain.enum.value
+syn keyword baanBshell rdi.domain.combined
+syn keyword baanBshell rdi.session.info
+syn keyword baanBshell rdi.session.dlls
+syn keyword baanBshell rdi.ref.route
+syn keyword baanBshell rdi.session.subject.info
+syn keyword baanBshell rdi.session.subject
+syn keyword baanBshell rdi.session.key
+syn keyword baanBshell rdi.session.form
+syn keyword baanBshell rdi.session.textfield
+syn keyword baanBshell rdi.first.day.of.week
+syn match   baanBshell "\<rdi.date.input.format\$"
+syn keyword baanBshell rdi.format.digits
+syn keyword baanBshell rdi.permission
+syn keyword baanBshell rdi.option.info
+syn keyword baanBshell rdi.option.short
+syn keyword baanBshell rdi.vrc.path
+syn keyword baanBshell rdi.audit.hosts
+syn keyword baanBshell rdi.table.sequence
+syn keyword baanBshell iget.fld.attr
+syn keyword baanBshell sget.fld.attr
+syn keyword baanBshell iget.frm.attr
+syn keyword baanBshell sget.frm.attr
+syn keyword baanBshell iput.fld.attr
+syn keyword baanBshell sput.fld.attr
+syn keyword baanBshell iput.frm.attr
+syn keyword baanBshell put.var.to.field
+syn keyword baanBshell get.var.from.field
+syn match   baanBshell "\<rdi.etoc\$"
+syn keyword baanBshell rdi.ctoe
+syn keyword baanBshell get.cust.code
+syn keyword baanBshell get.lic.no
+syn keyword baanBshell get.cust.name
+syn keyword baanBshell get.mach.id
+syn keyword baanBshell fsum
+syn match   baanBshell "\<get.resource\$"
+syn keyword baanBshell qss.sort
+syn keyword baanBshell qss.search
+syn keyword baanBshell load_dll
+syn keyword baanBshell exec_dll_function
+syn keyword baanBshell get_function
+syn keyword baanBshell exec_function
+syn keyword baanBshell parse_and_exec_function
+syn keyword baanBshell pty.open
+syn keyword baanBshell pty.close
+syn keyword baanBshell pty.read
+syn keyword baanBshell pty.write
+syn keyword baanBshell pty.winsize
+syn keyword baanBshell pty.winsize.ok
+syn keyword baanBshell pty.ok
+syn keyword baanBshell user.exists
+syn keyword baanBshell group.exists
+syn keyword baanBshell is.administrator
+syn keyword baanBshell mtime
+syn keyword baanBshell getcwd
+syn keyword baanBshell set.strip.mode
+syn keyword baanBshell set.symbol.strip.mode
+syn keyword baanBshell nullify.symbol
+syn keyword baanBshell bshell.pid
+syn keyword baanBshell create.new.symbol
+syn keyword baanBshell push.by.name
+syn keyword baanBshell array.info
+syn keyword baanBshell array.to.string
+syn keyword baanBshell many.to.string
+syn keyword baanBshell ostype
+syn keyword baanBshell utc.num
+syn keyword baanBshell set.time.zone
+syn keyword baanBshell get.time.zone
+syn keyword baanBshell run.prog
+syn keyword baanBshell run.baan.prog
+syn keyword baanBshell get.status.text
+syn keyword baanBshell dir.is.available
+syn keyword baanBshell dir.set.server
+syn keyword baanBshell dir.get.last.error
+syn keyword baanBshell dir.init.object
+syn keyword baanBshell dir.free.object
+syn keyword baanBshell dir.clear.object
+syn keyword baanBshell dir.create.object
+syn keyword baanBshell dir.get.object
+syn keyword baanBshell dir.remove.object
+syn keyword baanBshell dir.update.object
+syn keyword baanBshell dir.init.search
+syn keyword baanBshell dir.free.search
+syn keyword baanBshell dir.execute.search
+syn keyword baanBshell dir.abandon.search
+syn keyword baanBshell dir.get.first.row
+syn keyword baanBshell dir.get.next.row
+syn keyword baanBshell dir.get.prev.row
+syn keyword baanBshell dir.get.element.count
+syn keyword baanBshell dir.get.element.name
+syn keyword baanBshell dir.get.element.type
+syn keyword baanBshell dir.get.value.count
+syn keyword baanBshell dir.add.element
+syn keyword baanBshell dir.add.element.int
+syn keyword baanBshell dir.add.element.str
+syn keyword baanBshell dir.add.element.time
+syn keyword baanBshell dir.get.value.int
+syn keyword baanBshell dir.get.value.str
+syn keyword baanBshell dir.get.value.time
+syn keyword baanBshell dir.get.value.named.str
+syn keyword baanBshell dir.set.value.int
+syn keyword baanBshell dir.set.value.str
+syn keyword baanBshell dir.set.value.time
+syn keyword baanBshell dir.set.value.named.str
+syn keyword baanBshell dir.remove.element
+syn keyword baanBshell dir.find.element
+syn keyword baanBshell utc.add
+syn keyword baanBshell type.define
+syn keyword baanBshell type.free
+syn keyword baanBshell type.get.fieldnumber
+syn keyword baanBshell container.create
+syn keyword baanBshell container.clear
+syn keyword baanBshell container.resize
+syn keyword baanBshell container.set.nfields
+syn keyword baanBshell container.set.ifields
+syn keyword baanBshell container.set.fields
+syn keyword baanBshell container.get.nfields
+syn keyword baanBshell container.get.ifields
+syn keyword baanBshell container.get.fields
+syn keyword baanBshell container.actual.size
+syn keyword baanBshell container.get.actual.size
+syn keyword baanBshell container.set.actual.size
+syn keyword baanBshell container.size
+syn keyword baanBshell container.free
+syn keyword baanBshell xma.process_next_event
+syn keyword baanBshell xma.init_instance
+syn keyword baanBshell fini.service
+syn keyword baanBshell corba.boa.process_next_event
+syn keyword baanBshell corba.boa.set_impl
+syn keyword baanBshell corba.available
+syn keyword baanBshell corba.orb.string_to_object
+syn keyword baanBshell corba.orb.release
+syn keyword baanBshell corba.request.invoke
+syn keyword baanBshell corba.request.send
+syn keyword baanBshell corba.request.get_response
+syn keyword baanBshell corba.request.object
+syn keyword baanBshell corba.request.delete
+syn keyword baanBshell set.debug.cpu.opts
+syn keyword baanBshell get.debug.cpu.opts
+syn match   baanBshell "\<bsh.mesg\$"
+syn keyword baanBshell toggle.cpu
+syn keyword baanBshell cpu.is.debug
+syn keyword baanBshell set.profprint
+syn keyword baanBshell art.init
+syn keyword baanBshell art.define.transaction.class
+syn keyword baanBshell art.begin.transaction
+syn keyword baanBshell art.update.transaction
+syn keyword baanBshell art.end.transaction
+syn keyword baanBshell java.new.queue
+syn keyword baanBshell java.destroy.queue
+syn keyword baanBshell java.install.listener
+syn keyword baanBshell java.uninstall.listener
+syn keyword baanBshell java.put.bucket
+syn keyword baanBshell java.get.bucket
+syn keyword baanBshell java.lookup.queue
+syn keyword baanBshell java.execute.static.method
+syn keyword baanBshell java.execute.static.method.sync
+syn keyword baanBshell java.execute.static.method.async
+syn keyword baanBshell xml.write
+syn keyword baanBshell xml.read
+syn keyword baanBshell xml.newnode
+syn keyword baanBshell xml.unlinknode
+syn keyword baanBshell xml.deletenode
+syn keyword baanBshell xml.appendchildnode
+syn keyword baanBshell xml.addnode
+syn keyword baanBshell xml.insertnode
+syn keyword baanBshell xml.duplicatenode
+syn keyword baanBshell xml.setnodeproperties
+syn keyword baanBshell xml.getnodeproperties
+syn keyword baanBshell xml.deletenodeproperties
+syn keyword baanBshell xml.findfirstnode
+syn keyword baanBshell xml.findnodes
+syn keyword baanBshell xml.findsetofsiblingnodes
+syn keyword baanBshell xmlcontainsvalidcharactersonly
+syn keyword baanBshell xmlwrite
+syn keyword baanBshell xmlwritepretty
+syn keyword baanBshell xmlwritetostring
+syn keyword baanBshell xmlwriteprettytostring
+syn keyword baanBshell xmlread
+syn keyword baanBshell xmlreadfromstring
+syn keyword baanBshell xmlnewnode
+syn keyword baanBshell xmlnewdataelement
+syn keyword baanBshell xmlrewritedataelement
+syn keyword baanBshell xmlgetdataelement
+syn keyword baanBshell xmlsetname
+syn keyword baanBshell xmlsetdata
+syn keyword baanBshell xmlsetattribute
+syn keyword baanBshell xmldeleteattribute
+syn keyword baanBshell xmlgetname
+syn keyword baanBshell xmlgetdata
+syn keyword baanBshell xmlgettype
+syn keyword baanBshell xmlgetparent
+syn keyword baanBshell xmlgetfirstchild
+syn keyword baanBshell xmlgetlastchild
+syn keyword baanBshell xmlgetrightsibling
+syn keyword baanBshell xmlgetleftsibling
+syn keyword baanBshell xmlgetnumattributes
+syn keyword baanBshell xmlgetnumsiblings
+syn keyword baanBshell xmlgetnumleftsiblings
+syn keyword baanBshell xmlgetnumrightsiblings
+syn keyword baanBshell xmlgetnumchilds
+syn keyword baanBshell xmlgetattribute
+syn keyword baanBshell xmlgetattributename
+syn keyword baanBshell xmldelete
+syn keyword baanBshell xmlunlink
+syn keyword baanBshell xmlinsert
+syn keyword baanBshell xmladd
+syn keyword baanBshell xmlappend
+syn keyword baanBshell xmlinsertinchilds
+syn keyword baanBshell xmlappendtochilds
+syn keyword baanBshell xmlduplicate
+syn keyword baanBshell xmlduplicateandinsert
+syn keyword baanBshell xmlduplicateandadd
+syn keyword baanBshell xmlduplicateandappend
+syn keyword baanBshell xmlduplicateandinsertinchilds
+syn keyword baanBshell xmlduplicateandappendtochilds
+syn keyword baanBshell xmlduplicatetoprocess
+syn keyword baanBshell xmlfindfirst
+syn keyword baanBshell xmlfindfirstmatch
+syn keyword baanBshell xmlfindmatch
+syn keyword baanBshell xmlfindnodes
+syn keyword baanBshell xmlfindsetofsiblingnodes
+syn keyword baanBshell xmlexecutesql
+syn keyword baanBshell xmlexecutedllmethod
+syn keyword baanBshell xmldllsignature
+syn keyword baanBshell xmlnodetosymbol
+syn keyword baanBshell xmlputstringtolog
+syn keyword baanBshell xmlgetlog
+syn keyword baanBshell xmlcleanuplog
+syn keyword baanBshell xmlinstallloglistener
+syn keyword baanBshell xmldeinstallloglistener
+syn keyword baanBshell xmlinitsql
+syn keyword baanBshell xmlrefreshsqlcache
+syn keyword baanBshell xmlstatisticssqlcache
+syn keyword baanBshell bclm.dump
+syn keyword baanBshell bclm.init
+syn keyword baanBshell bclm.requestlicense
+syn keyword baanBshell bclm.confirmlicense
+syn keyword baanBshell bclm.releaselicense
+syn keyword baanBshell bclm.customerdata
+syn keyword baanBshell bclm.enabledemoperiod
+syn keyword baanBshell bclm.productidlicensed
+syn keyword baanBshell bclm.set.desktop
+
+" Define the default highlighting.
+" For version 5.7 and earlier: only when not done already
+" For version 5.8 and later: only when an item doesn't have highlighting yet
+if version >= 508 || !exists("did_baan_syn_inits")
+  if version < 508
+    let did_baan_syn_inits = 1
+    command -nargs=+ HiLink hi link <args>
+  else
+    command -nargs=+ HiLink hi def link <args>
+  endif
+
+  HiLink baanConditional	Conditional
+  HiLink baan3gl		Statement
+  HiLink baan3glpre		PreProc
+  HiLink baan4gl		Statement
+  HiLink baan4glh		Statement
+  HiLink baansql		Statement
+  HiLink baansqlh		Statement
+  HiLink baanDalHook		Statement
+  HiLink baanNumber		Number
+  HiLink baanString		String
+  HiLink baanOpenStringError	Error
+  HiLink baanConstant		Constant
+  HiLink baanComment		Comment
+  HiLink baanCommenth		Comment
+  HiLink baanUncommented	Comment
+  HiLink baanDLLUsage		Comment
+  HiLink baanFunUsage		Comment
+  HiLink baanIdentifier		Normal
+  HiLink baanBshell		Function
+  HiLink baanType		Type
+  HiLink baanStorageClass	StorageClass
+
+  delcommand HiLink
+endif
+
+let b:current_syntax = "baan"
+
+" vim: ts=8
--- /dev/null
+++ b/lib/vimfiles/syntax/basic.vim
@@ -1,0 +1,174 @@
+" Vim syntax file
+" Language:	BASIC
+" Maintainer:	Allan Kelly <allan@fruitloaf.co.uk>
+" Last Change:	Tue Sep 14 14:24:23 BST 1999
+
+" First version based on Micro$soft QBASIC circa 1989, as documented in
+" 'Learn BASIC Now' by Halvorson&Rygmyr. Microsoft Press 1989.
+" This syntax file not a complete implementation yet.  Send suggestions to the
+" maintainer.
+
+" For version 5.x: Clear all syntax items
+" For version 6.x: Quit when a syntax file was already loaded
+if version < 600
+  syntax clear
+elseif exists("b:current_syntax")
+  finish
+endif
+
+" A bunch of useful BASIC keywords
+syn keyword basicStatement	BEEP beep Beep BLOAD bload Bload BSAVE bsave Bsave
+syn keyword basicStatement	CALL call Call ABSOLUTE absolute Absolute
+syn keyword basicStatement	CHAIN chain Chain CHDIR chdir Chdir
+syn keyword basicStatement	CIRCLE circle Circle CLEAR clear Clear
+syn keyword basicStatement	CLOSE close Close CLS cls Cls COLOR color Color
+syn keyword basicStatement	COM com Com COMMON common Common
+syn keyword basicStatement	CONST const Const DATA data Data
+syn keyword basicStatement	DECLARE declare Declare DEF def Def
+syn keyword basicStatement	DEFDBL defdbl Defdbl DEFINT defint Defint
+syn keyword basicStatement	DEFLNG deflng Deflng DEFSNG defsng Defsng
+syn keyword basicStatement	DEFSTR defstr Defstr DIM dim Dim
+syn keyword basicStatement	DO do Do LOOP loop Loop
+syn keyword basicStatement	DRAW draw Draw END end End
+syn keyword basicStatement	ENVIRON environ Environ ERASE erase Erase
+syn keyword basicStatement	ERROR error Error EXIT exit Exit
+syn keyword basicStatement	FIELD field Field FILES files Files
+syn keyword basicStatement	FOR for For NEXT next Next
+syn keyword basicStatement	FUNCTION function Function GET get Get
+syn keyword basicStatement	GOSUB gosub Gosub GOTO goto Goto
+syn keyword basicStatement	IF if If THEN then Then ELSE else Else
+syn keyword basicStatement	INPUT input Input INPUT# input# Input#
+syn keyword basicStatement	IOCTL ioctl Ioctl KEY key Key
+syn keyword basicStatement	KILL kill Kill LET let Let
+syn keyword basicStatement	LINE line Line LOCATE locate Locate
+syn keyword basicStatement	LOCK lock Lock UNLOCK unlock Unlock
+syn keyword basicStatement	LPRINT lprint Lprint USING using Using
+syn keyword basicStatement	LSET lset Lset MKDIR mkdir Mkdir
+syn keyword basicStatement	NAME name Name ON on On
+syn keyword basicStatement	ERROR error Error OPEN open Open
+syn keyword basicStatement	OPTION option Option BASE base Base
+syn keyword basicStatement	OUT out Out PAINT paint Paint
+syn keyword basicStatement	PALETTE palette Palette PCOPY pcopy Pcopy
+syn keyword basicStatement	PEN pen Pen PLAY play Play
+syn keyword basicStatement	PMAP pmap Pmap POKE poke Poke
+syn keyword basicStatement	PRESET preset Preset PRINT print Print
+syn keyword basicStatement	PRINT# print# Print# USING using Using
+syn keyword basicStatement	PSET pset Pset PUT put Put
+syn keyword basicStatement	RANDOMIZE randomize Randomize READ read Read
+syn keyword basicStatement	REDIM redim Redim RESET reset Reset
+syn keyword basicStatement	RESTORE restore Restore RESUME resume Resume
+syn keyword basicStatement	RETURN return Return RMDIR rmdir Rmdir
+syn keyword basicStatement	RSET rset Rset RUN run Run
+syn keyword basicStatement	SEEK seek Seek SELECT select Select
+syn keyword basicStatement	CASE case Case SHARED shared Shared
+syn keyword basicStatement	SHELL shell Shell SLEEP sleep Sleep
+syn keyword basicStatement	SOUND sound Sound STATIC static Static
+syn keyword basicStatement	STOP stop Stop STRIG strig Strig
+syn keyword basicStatement	SUB sub Sub SWAP swap Swap
+syn keyword basicStatement	SYSTEM system System TIMER timer Timer
+syn keyword basicStatement	TROFF troff Troff TRON tron Tron
+syn keyword basicStatement	TYPE type Type UNLOCK unlock Unlock
+syn keyword basicStatement	VIEW view View WAIT wait Wait
+syn keyword basicStatement	WHILE while While WEND wend Wend
+syn keyword basicStatement	WIDTH width Width WINDOW window Window
+syn keyword basicStatement	WRITE write Write DATE$ date$ Date$
+syn keyword basicStatement	MID$ mid$ Mid$ TIME$ time$ Time$
+
+syn keyword basicFunction	ABS abs Abs ASC asc Asc
+syn keyword basicFunction	ATN atn Atn CDBL cdbl Cdbl
+syn keyword basicFunction	CINT cint Cint CLNG clng Clng
+syn keyword basicFunction	COS cos Cos CSNG csng Csng
+syn keyword basicFunction	CSRLIN csrlin Csrlin CVD cvd Cvd
+syn keyword basicFunction	CVDMBF cvdmbf Cvdmbf CVI cvi Cvi
+syn keyword basicFunction	CVL cvl Cvl CVS cvs Cvs
+syn keyword basicFunction	CVSMBF cvsmbf Cvsmbf EOF eof Eof
+syn keyword basicFunction	ERDEV erdev Erdev ERL erl Erl
+syn keyword basicFunction	ERR err Err EXP exp Exp
+syn keyword basicFunction	FILEATTR fileattr Fileattr FIX fix Fix
+syn keyword basicFunction	FRE fre Fre FREEFILE freefile Freefile
+syn keyword basicFunction	INP inp Inp INSTR instr Instr
+syn keyword basicFunction	INT int Int LBOUND lbound Lbound
+syn keyword basicFunction	LEN len Len LOC loc Loc
+syn keyword basicFunction	LOF lof Lof LOG log Log
+syn keyword basicFunction	LPOS lpos Lpos PEEK peek Peek
+syn keyword basicFunction	PEN pen Pen POINT point Point
+syn keyword basicFunction	POS pos Pos RND rnd Rnd
+syn keyword basicFunction	SADD sadd Sadd SCREEN screen Screen
+syn keyword basicFunction	SEEK seek Seek SETMEM setmem Setmem
+syn keyword basicFunction	SGN sgn Sgn SIN sin Sin
+syn keyword basicFunction	SPC spc Spc SQR sqr Sqr
+syn keyword basicFunction	STICK stick Stick STRIG strig Strig
+syn keyword basicFunction	TAB tab Tab TAN tan Tan
+syn keyword basicFunction	UBOUND ubound Ubound VAL val Val
+syn keyword basicFunction	VALPTR valptr Valptr VALSEG valseg Valseg
+syn keyword basicFunction	VARPTR varptr Varptr VARSEG varseg Varseg
+syn keyword basicFunction	CHR$ Chr$ chr$ COMMAND$ command$ Command$
+syn keyword basicFunction	DATE$ date$ Date$ ENVIRON$ environ$ Environ$
+syn keyword basicFunction	ERDEV$ erdev$ Erdev$ HEX$ hex$ Hex$
+syn keyword basicFunction	INKEY$ inkey$ Inkey$ INPUT$ input$ Input$
+syn keyword basicFunction	IOCTL$ ioctl$ Ioctl$ LCASES$ lcases$ Lcases$
+syn keyword basicFunction	LAFT$ laft$ Laft$ LTRIM$ ltrim$ Ltrim$
+syn keyword basicFunction	MID$ mid$ Mid$ MKDMBF$ mkdmbf$ Mkdmbf$
+syn keyword basicFunction	MKD$ mkd$ Mkd$ MKI$ mki$ Mki$
+syn keyword basicFunction	MKL$ mkl$ Mkl$ MKSMBF$ mksmbf$ Mksmbf$
+syn keyword basicFunction	MKS$ mks$ Mks$ OCT$ oct$ Oct$
+syn keyword basicFunction	RIGHT$ right$ Right$ RTRIM$ rtrim$ Rtrim$
+syn keyword basicFunction	SPACE$ space$ Space$ STR$ str$ Str$
+syn keyword basicFunction	STRING$ string$ String$ TIME$ time$ Time$
+syn keyword basicFunction	UCASE$ ucase$ Ucase$ VARPTR$ varptr$ Varptr$
+syn keyword basicTodo contained	TODO
+
+"integer number, or floating point number without a dot.
+syn match  basicNumber		"\<\d\+\>"
+"floating point number, with dot
+syn match  basicNumber		"\<\d\+\.\d*\>"
+"floating point number, starting with a dot
+syn match  basicNumber		"\.\d\+\>"
+
+" String and Character contstants
+syn match   basicSpecial contained "\\\d\d\d\|\\."
+syn region  basicString		  start=+"+  skip=+\\\\\|\\"+  end=+"+  contains=basicSpecial
+
+syn region  basicComment	start="REM" end="$" contains=basicTodo
+syn region  basicComment	start="^[ \t]*'" end="$" contains=basicTodo
+syn region  basicLineNumber	start="^\d" end="\s"
+syn match   basicTypeSpecifier  "[a-zA-Z0-9][\$%&!#]"ms=s+1
+" Used with OPEN statement
+syn match   basicFilenumber  "#\d\+"
+"syn sync ccomment basicComment
+" syn match   basicMathsOperator "[<>+\*^/\\=-]"
+syn match   basicMathsOperator   "-\|=\|[:<>+\*^/\\]\|AND\|OR"
+
+" Define the default highlighting.
+" For version 5.7 and earlier: only when not done already
+" For version 5.8 and later: only when an item doesn't have highlighting yet
+if version >= 508 || !exists("did_basic_syntax_inits")
+  if version < 508
+    let did_basic_syntax_inits = 1
+    command -nargs=+ HiLink hi link <args>
+  else
+    command -nargs=+ HiLink hi def link <args>
+  endif
+
+  HiLink basicLabel		Label
+  HiLink basicConditional	Conditional
+  HiLink basicRepeat		Repeat
+  HiLink basicLineNumber	Comment
+  HiLink basicNumber		Number
+  HiLink basicError		Error
+  HiLink basicStatement	Statement
+  HiLink basicString		String
+  HiLink basicComment		Comment
+  HiLink basicSpecial		Special
+  HiLink basicTodo		Todo
+  HiLink basicFunction		Identifier
+  HiLink basicTypeSpecifier Type
+  HiLink basicFilenumber basicTypeSpecifier
+  "hi basicMathsOperator term=bold cterm=bold gui=bold
+
+  delcommand HiLink
+endif
+
+let b:current_syntax = "basic"
+
+" vim: ts=8
--- /dev/null
+++ b/lib/vimfiles/syntax/bc.vim
@@ -1,0 +1,78 @@
+" Vim syntax file
+" Language:	bc - An arbitrary precision calculator language
+" Maintainer:	Vladimir Scholtz <vlado@gjh.sk>
+" Last change:	2001 Sep 02
+" Available on:	www.gjh.sk/~vlado/bc.vim
+
+" For version 5.x: Clear all syntax items
+" For version 6.x: Quit when a syntax file was already loaded
+if version < 600
+  syntax clear
+elseif exists("b:current_syntax")
+  finish
+endif
+
+syn case ignore
+
+" Keywords
+syn keyword bcKeyword if else while for break continue return limits halt quit
+syn keyword bcKeyword define
+syn keyword bcKeyword length read sqrt print
+
+" Variable
+syn keyword bcType auto
+
+" Constant
+syn keyword bcConstant scale ibase obase last
+syn keyword bcConstant BC_BASE_MAX BC_DIM_MAX BC_SCALE_MAX BC_STRING_MAX
+syn keyword bcConstant BC_ENV_ARGS BC_LINE_LENGTH
+
+" Any other stuff
+syn match bcIdentifier		"[a-z_][a-z0-9_]*"
+
+" String
+ syn match bcString		"\"[^"]*\""
+
+" Number
+syn match bcNumber		"[0-9]\+"
+
+" Comment
+syn match bcComment		"\#.*"
+syn region bcComment		start="/\*" end="\*/"
+
+" Parent ()
+syn cluster bcAll contains=bcList,bcIdentifier,bcNumber,bcKeyword,bcType,bcConstant,bcString,bcParentError
+syn region bcList		matchgroup=Delimiter start="(" skip="|.\{-}|" matchgroup=Delimiter end=")" contains=@bcAll
+syn region bcList		matchgroup=Delimiter start="\[" skip="|.\{-}|" matchgroup=Delimiter end="\]" contains=@bcAll
+syn match bcParenError			"]"
+syn match bcParenError			")"
+
+
+
+syn case match
+
+" Define the default highlighting.
+" For version 5.7 and earlier: only when not done already
+" For version 5.8 and later: only when an item doesn't have highlighting yet
+if version >= 508 || !exists("did_bc_syntax_inits")
+  if version < 508
+    let did_bc_syntax_inits = 1
+    command -nargs=+ HiLink hi link <args>
+  else
+    command -nargs=+ HiLink hi def link <args>
+  endif
+
+  HiLink bcKeyword		Statement
+  HiLink bcType		Type
+  HiLink bcConstant		Constant
+  HiLink bcNumber		Number
+  HiLink bcComment		Comment
+  HiLink bcString		String
+  HiLink bcSpecialChar		SpecialChar
+  HiLink bcParenError		Error
+
+  delcommand HiLink
+endif
+
+let b:current_syntax = "bc"
+" vim: ts=8
--- /dev/null
+++ b/lib/vimfiles/syntax/bdf.vim
@@ -1,0 +1,97 @@
+" Vim syntax file
+" Language:         BDF font definition
+" Maintainer:       Nikolai Weibull <now@bitwi.se>
+" Latest Revision:  2006-04-19
+
+if exists("b:current_syntax")
+  finish
+endif
+
+let s:cpo_save = &cpo
+set cpo&vim
+
+syn region  bdfFontDefinition transparent matchgroup=bdfKeyword
+                              \ start='^STARTFONT\>' end='^ENDFONT\>'
+                              \ contains=bdfComment,bdfFont,bdfSize,
+                              \ bdfBoundingBox,bdfProperties,bdfChars,bdfChar
+
+syn match   bdfNumber         contained display
+                              \ '\<\%(\x\+\|[+-]\=\d\+\%(\.\d\+\)*\)'
+
+syn keyword bdfTodo           contained FIXME TODO XXX NOTE
+
+syn region  bdfComment        contained start='^COMMENT\>' end='$'
+                              \ contains=bdfTodo,@Spell
+
+syn region  bdfFont           contained matchgroup=bdfKeyword
+                              \ start='^FONT\>' end='$'
+
+syn region  bdfSize           contained transparent matchgroup=bdfKeyword
+                              \ start='^SIZE\>' end='$' contains=bdfNumber
+
+syn region  bdfBoundingBox    contained transparent matchgroup=bdfKeyword
+                              \ start='^FONTBOUNDINGBOX' end='$'
+                              \ contains=bdfNumber
+
+syn region  bdfProperties     contained transparent matchgroup=bdfKeyword
+                              \ start='^STARTPROPERTIES' end='^ENDPROPERTIES'
+                              \ contains=bdfNumber,bdfString,bdfProperty,
+                              \ bdfXProperty
+
+syn keyword bdfProperty       contained FONT_ASCENT FONT_DESCENT DEFAULT_CHAR
+syn match   bdfProperty       contained '^\S\+'
+
+syn keyword bdfXProperty      contained FONT_ASCENT FONT_DESCENT DEFAULT_CHAR
+                              \ FONTNAME_REGISTRY FOUNDRY FAMILY_NAME
+                              \ WEIGHT_NAME SLANT SETWIDTH_NAME PIXEL_SIZE
+                              \ POINT_SIZE RESOLUTION_X RESOLUTION_Y SPACING
+                              \ CHARSET_REGISTRY CHARSET_ENCODING COPYRIGHT
+                              \ ADD_STYLE_NAME WEIGHT RESOLUTION X_HEIGHT
+                              \ QUAD_WIDTH FONT AVERAGE_WIDTH
+
+syn region  bdfString         contained start=+"+ skip=+""+ end=+"+
+
+syn region  bdfChars          contained display transparent
+                              \ matchgroup=bdfKeyword start='^CHARS' end='$'
+                              \ contains=bdfNumber
+
+syn region  bdfChar           transparent matchgroup=bdfKeyword
+                              \ start='^STARTCHAR' end='^ENDCHAR'
+                              \ contains=bdfEncoding,bdfWidth,bdfAttributes,
+                              \ bdfBitmap
+
+syn region  bdfEncoding       contained transparent matchgroup=bdfKeyword
+                              \ start='^ENCODING' end='$' contains=bdfNumber
+
+syn region  bdfWidth          contained transparent matchgroup=bdfKeyword
+                              \ start='^SWIDTH\|DWIDTH\|BBX' end='$'
+                              \ contains=bdfNumber
+
+syn region  bdfAttributes     contained transparent matchgroup=bdfKeyword
+                              \ start='^ATTRIBUTES' end='$'
+
+syn keyword bdfBitmap         contained BITMAP
+
+if exists("bdf_minlines")
+  let b:bdf_minlines = bdf_minlines
+else
+  let b:bdf_minlines = 30
+endif
+exec "syn sync ccomment bdfChar minlines=" . b:bdf_minlines
+
+
+hi def link bdfKeyword        Keyword
+hi def link bdfNumber         Number
+hi def link bdfTodo           Todo
+hi def link bdfComment        Comment
+hi def link bdfFont           String
+hi def link bdfProperty       Identifier
+hi def link bdfXProperty      Identifier
+hi def link bdfString         String
+hi def link bdfChars          Keyword
+hi def link bdfBitmap         Keyword
+
+let b:current_syntax = "bdf"
+
+let &cpo = s:cpo_save
+unlet s:cpo_save
--- /dev/null
+++ b/lib/vimfiles/syntax/bib.vim
@@ -1,0 +1,93 @@
+" Vim syntax file
+" Language:	BibTeX (bibliographic database format for (La)TeX)
+" Maintainer:	Bernd Feige <Bernd.Feige@gmx.net>
+" Filenames:	*.bib
+" Last Change:	Aug 02, 2005
+
+" Thanks to those who pointed out problems with this file or supplied fixes!
+
+" Initialization
+" ==============
+" For version 5.x: Clear all syntax items
+" For version 6.x: Quit when a syntax file was already loaded
+if version < 600
+  syntax clear
+elseif exists("b:current_syntax")
+  finish
+endif
+
+" Ignore case
+syn case ignore
+
+" Keywords
+" ========
+syn keyword bibType contained	article book booklet conference inbook
+syn keyword bibType contained	incollection inproceedings manual
+syn keyword bibType contained	mastersthesis misc phdthesis
+syn keyword bibType contained	proceedings techreport unpublished
+syn keyword bibType contained	string
+
+syn keyword bibEntryKw contained	address annote author booktitle chapter
+syn keyword bibEntryKw contained	crossref edition editor howpublished
+syn keyword bibEntryKw contained	institution journal key month note
+syn keyword bibEntryKw contained	number organization pages publisher
+syn keyword bibEntryKw contained	school series title type volume year
+" Non-standard:
+syn keyword bibNSEntryKw contained	abstract isbn issn keywords url
+
+" Clusters
+" ========
+syn cluster bibVarContents	contains=bibUnescapedSpecial,bibBrace,bibParen
+" This cluster is empty but things can be added externally:
+"syn cluster bibCommentContents
+
+" Matches
+" =======
+syn match bibUnescapedSpecial contained /[^\\][%&]/hs=s+1
+syn match bibKey contained /\s*[^ \t}="]\+,/hs=s,he=e-1 nextgroup=bibField
+syn match bibVariable contained /[^{}," \t=]/
+syn region bibComment start=/./ end=/^\s*@/me=e-1 contains=@bibCommentContents nextgroup=bibEntry
+syn region bibQuote contained start=/"/ end=/"/ skip=/\(\\"\)/ contains=@bibVarContents
+syn region bibBrace contained start=/{/ end=/}/ skip=/\(\\[{}]\)/ contains=@bibVarContents
+syn region bibParen contained start=/(/ end=/)/ skip=/\(\\[()]\)/ contains=@bibVarContents
+syn region bibField contained start="\S\+\s*=\s*" end=/[}),]/me=e-1 contains=bibEntryKw,bibNSEntryKw,bibBrace,bibParen,bibQuote,bibVariable
+syn region bibEntryData contained start=/[{(]/ms=e+1 end=/[})]/me=e-1 contains=bibKey,bibField
+" Actually, 5.8 <= Vim < 6.0 would ignore the `fold' keyword anyway, but Vim<5.8 would produce
+" an error, so we explicitly distinguish versions with and without folding functionality:
+if version < 600
+  syn region bibEntry start=/@\S\+[{(]/ end=/^\s*[})]/ transparent contains=bibType,bibEntryData nextgroup=bibComment
+else
+  syn region bibEntry start=/@\S\+[{(]/ end=/^\s*[})]/ transparent fold contains=bibType,bibEntryData nextgroup=bibComment
+endif
+syn region bibComment2 start=/@Comment[{(]/ end=/^\s*@/me=e-1 contains=@bibCommentContents nextgroup=bibEntry
+
+" Synchronization
+" ===============
+syn sync match All grouphere bibEntry /^\s*@/
+syn sync maxlines=200
+syn sync minlines=50
+
+" Highlighting defaults
+" =====================
+" Define the default highlighting.
+" For version 5.7 and earlier: only when not done already
+" For version 5.8 and later: only when an item doesn't have highlighting yet
+if version >= 508 || !exists("did_bib_syn_inits")
+  if version < 508
+    let did_bib_syn_inits = 1
+    command -nargs=+ HiLink hi link <args>
+  else
+    command -nargs=+ HiLink hi def link <args>
+  endif
+  HiLink bibType	Identifier
+  HiLink bibEntryKw	Statement
+  HiLink bibNSEntryKw	PreProc
+  HiLink bibKey		Special
+  HiLink bibVariable	Constant
+  HiLink bibUnescapedSpecial	Error
+  HiLink bibComment	Comment
+  HiLink bibComment2	Comment
+  delcommand HiLink
+endif
+
+let b:current_syntax = "bib"
--- /dev/null
+++ b/lib/vimfiles/syntax/bindzone.vim
@@ -1,0 +1,110 @@
+" Vim syntax file
+" Language:     BIND zone files (RFC1035)
+" Maintainer:   Julian Mehnle <julian@mehnle.net>
+" URL:          http://www.mehnle.net/source/odds+ends/vim/syntax/
+" Last Change:  Thu 2006-04-20 12:30:45 UTC
+" 
+" Based on an earlier version by Вячеслав Горбанев (Slava Gorbanev), with
+" heavy modifications.
+" 
+" $Id: bindzone.vim,v 1.2 2006/04/20 22:06:21 vimboss Exp $
+
+" For version 5.x: Clear all syntax items
+" For version 6.x: Quit when a syntax file was already loaded
+if version < 600
+  syntax clear
+elseif exists("b:current_syntax")
+  finish
+endif
+
+syn case match
+
+" Directives
+syn region      zoneRRecord     start=/^/ end=/$/ contains=zoneOwnerName,zoneSpecial,zoneTTL,zoneClass,zoneRRType,zoneComment,zoneUnknown
+
+syn match       zoneDirective   /^\$ORIGIN\s\+/   nextgroup=zoneOrigin,zoneUnknown
+syn match       zoneDirective   /^\$TTL\s\+/      nextgroup=zoneNumber,zoneUnknown
+syn match       zoneDirective   /^\$INCLUDE\s\+/  nextgroup=zoneText,zoneUnknown
+syn match       zoneDirective   /^\$GENERATE\s/
+
+syn match       zoneUnknown     contained /\S\+/
+
+syn match       zoneOwnerName   contained /^[^[:space:]!"#$%&'()*+,\/:;<=>?@[\]\^`{|}~]\+\(\s\|;\)\@=/ nextgroup=zoneTTL,zoneClass,zoneRRType skipwhite
+syn match       zoneOrigin      contained  /[^[:space:]!"#$%&'()*+,\/:;<=>?@[\]\^`{|}~]\+\(\s\|;\|$\)\@=/
+syn match       zoneDomain      contained  /[^[:space:]!"#$%&'()*+,\/:;<=>?@[\]\^`{|}~]\+\(\s\|;\|$\)\@=/
+
+syn match       zoneSpecial     contained /^[@*.]\s/
+syn match       zoneTTL         contained /\<\d[0-9HhWwDd]*\>/  nextgroup=zoneClass,zoneRRType skipwhite
+syn keyword     zoneClass       contained IN CHAOS              nextgroup=zoneRRType,zoneTTL   skipwhite
+syn keyword     zoneRRType      contained A AAAA CNAME HINFO MX NS PTR SOA SRV TXT nextgroup=zoneRData skipwhite
+syn match       zoneRData       contained /[^;]*/ contains=zoneDomain,zoneIPAddr,zoneIP6Addr,zoneText,zoneNumber,zoneParen,zoneUnknown
+
+syn match       zoneIPAddr      contained /\<[0-9]\{1,3}\(\.[0-9]\{1,3}\)\{,3}\>/
+
+"   Plain IPv6 address          IPv6-embedded-IPv4 address
+"   1111:2:3:4:5:6:7:8          1111:2:3:4:5:6:127.0.0.1
+syn match       zoneIP6Addr     contained /\<\(\x\{1,4}:\)\{6}\(\x\{1,4}:\x\{1,4}\|\([0-2]\?\d\{1,2}\.\)\{3}[0-2]\?\d\{1,2}\)\>/
+"   ::[...:]8                   ::[...:]127.0.0.1
+syn match       zoneIP6Addr     contained /\s\@<=::\(\(\x\{1,4}:\)\{,6}\x\{1,4}\|\(\x\{1,4}:\)\{,5}\([0-2]\?\d\{1,2}\.\)\{3}[0-2]\?\d\{1,2}\)\>/
+"   1111::[...:]8               1111::[...:]127.0.0.1
+syn match       zoneIP6Addr     contained /\<\(\x\{1,4}:\)\{1}:\(\(\x\{1,4}:\)\{,5}\x\{1,4}\|\(\x\{1,4}:\)\{,4}\([0-2]\?\d\{1,2}\.\)\{3}[0-2]\?\d\{1,2}\)\>/
+"   1111:2::[...:]8             1111:2::[...:]127.0.0.1
+syn match       zoneIP6Addr     contained /\<\(\x\{1,4}:\)\{2}:\(\(\x\{1,4}:\)\{,4}\x\{1,4}\|\(\x\{1,4}:\)\{,3}\([0-2]\?\d\{1,2}\.\)\{3}[0-2]\?\d\{1,2}\)\>/
+"   1111:2:3::[...:]8           1111:2:3::[...:]127.0.0.1
+syn match       zoneIP6Addr     contained /\<\(\x\{1,4}:\)\{3}:\(\(\x\{1,4}:\)\{,3}\x\{1,4}\|\(\x\{1,4}:\)\{,2}\([0-2]\?\d\{1,2}\.\)\{3}[0-2]\?\d\{1,2}\)\>/
+"   1111:2:3:4::[...:]8         1111:2:3:4::[...:]127.0.0.1
+syn match       zoneIP6Addr     contained /\<\(\x\{1,4}:\)\{4}:\(\(\x\{1,4}:\)\{,2}\x\{1,4}\|\(\x\{1,4}:\)\{,1}\([0-2]\?\d\{1,2}\.\)\{3}[0-2]\?\d\{1,2}\)\>/
+"   1111:2:3:4:5::[...:]8       1111:2:3:4:5::127.0.0.1
+syn match       zoneIP6Addr     contained /\<\(\x\{1,4}:\)\{5}:\(\(\x\{1,4}:\)\{,1}\x\{1,4}\|\([0-2]\?\d\{1,2}\.\)\{3}[0-2]\?\d\{1,2}\)\>/
+"   1111:2:3:4:5:6::8           -
+syn match       zoneIP6Addr     contained /\<\(\x\{1,4}:\)\{6}:\x\{1,4}\>/
+"   1111[:...]::                -
+syn match       zoneIP6Addr     contained /\<\(\x\{1,4}:\)\{1,7}:\(\s\|;\|$\)\@=/
+
+syn match       zoneText        contained /"\([^"\\]\|\\.\)*"\(\s\|;\|$\)\@=/
+syn match       zoneNumber      contained /\<[0-9]\+\(\s\|;\|$\)\@=/
+syn match       zoneSerial      contained /\<[0-9]\{9,10}\(\s\|;\|$\)\@=/
+
+syn match       zoneErrParen    /)/
+syn region      zoneParen       contained start="(" end=")" contains=zoneSerial,zoneNumber,zoneComment
+syn match       zoneComment     /;.*/
+
+" Define the default highlighting.
+" For version 5.7 and earlier: only when not done already
+" For version 5.8 and later: only when an item doesn't have highlighting yet
+if version >= 508 || !exists("did_bind_zone_syn_inits")
+  if version < 508
+    let did_bind_zone_syn_inits = 1
+    command -nargs=+ HiLink hi link <args>
+  else
+    command -nargs=+ HiLink hi def link <args>
+  endif
+
+  HiLink zoneDirective    Macro
+  
+  HiLink zoneUnknown      Error
+  
+  HiLink zoneOrigin       Statement
+  HiLink zoneOwnerName    Statement
+  HiLink zoneDomain       Identifier
+  
+  HiLink zoneSpecial      Special
+  HiLink zoneTTL          Constant
+  HiLink zoneClass        Include
+  HiLink zoneRRType       Type
+  
+  HiLink zoneIPAddr       Number
+  HiLink zoneIP6Addr      Number
+  HiLink zoneText         String
+  HiLink zoneNumber       Number
+  HiLink zoneSerial       Special
+  
+  HiLink zoneErrParen     Error
+  HiLink zoneComment      Comment
+
+  delcommand HiLink
+endif
+
+let b:current_syntax = "bindzone"
+
+" vim:sts=2 sw=2
--- /dev/null
+++ b/lib/vimfiles/syntax/blank.vim
@@ -1,0 +1,46 @@
+" Vim syntax file
+" Language:     Blank 1.4.1
+" Maintainer:   Rafal M. Sulejman <unefunge@friko2.onet.pl>
+" Last change:  21 Jul 2000
+
+" For version 5.x: Clear all syntax items
+" For version 6.x: Quit when a syntax file was already loaded
+if version < 600
+  syntax clear
+elseif exists("b:current_syntax")
+  finish
+endif
+
+syn case ignore
+
+" Blank instructions
+syn match blankInstruction "{[:;,\.+\-*$#@/\\`'"!\|><{}\[\]()?xspo\^&\~=_%]}"
+
+" Common strings
+syn match blankString "\~[^}]"
+
+" Numbers
+syn match blankNumber "\[[0-9]\+\]"
+
+syn case match
+
+" Define the default highlighting.
+" For version 5.7 and earlier: only when not done already
+" For version 5.8 and later: only when an item doesn't have highlighting yet
+if version >= 508 || !exists("did_blank_syntax_inits")
+  if version < 508
+    let did_blank_syntax_inits = 1
+    command -nargs=+ HiLink hi link <args>
+  else
+    command -nargs=+ HiLink hi def link <args>
+  endif
+
+  HiLink blankInstruction      Statement
+  HiLink blankNumber	       Number
+  HiLink blankString	       String
+
+  delcommand HiLink
+endif
+
+let b:current_syntax = "blank"
+" vim: ts=8
--- /dev/null
+++ b/lib/vimfiles/syntax/bst.vim
@@ -1,0 +1,89 @@
+" Vim syntax file
+" Language:     BibTeX Bibliography Style
+" Maintainer:   Tim Pope <vimNOSPAM@tpope.info>
+" Filenames:    *.bst
+" $Id: bst.vim,v 1.2 2007/05/05 18:24:42 vimboss Exp $
+
+" For version 5.x: Clear all syntax items
+" For version 6.x: Quit when a syntax file was already loaded
+if version < 600
+    syntax clear
+elseif exists("b:current_syntax")
+    finish
+endif
+
+if version < 600
+    command -nargs=1 SetIsk set iskeyword=<args>
+else
+    command -nargs=1 SetIsk setlocal iskeyword=<args>
+endif
+SetIsk 48-57,#,$,',.,A-Z,a-z
+delcommand SetIsk
+
+syn case ignore
+
+syn match   bstString +"[^"]*\%("\|$\)+ contains=bstField,bstType,bstError
+" Highlight the last character of an unclosed string, but only when the cursor
+" is not beyond it (i.e., it is still being edited). Imperfect.
+syn match   bstError     '[^"]\%#\@!$' contained
+
+syn match   bstNumber         "#-\=\d\+\>"
+syn keyword bstNumber         entry.max$ global.max$
+syn match   bstComment        "%.*"
+
+syn keyword bstCommand        ENTRY FUNCTION INTEGERS MACRO STRINGS
+syn keyword bstCommand        READ EXECUTE ITERATE REVERSE SORT
+syn match   bstBuiltIn        "\s[-<>=+*]\|\s:="
+syn keyword bstBuiltIn        add.period$
+syn keyword bstBuiltIn        call.type$ change.case$ chr.to.int$ cite$
+syn keyword bstBuiltIn        duplicate$ empty$ format.name$
+syn keyword bstBuiltIn        if$ int.to.chr$ int.to.str$
+syn keyword bstBuiltIn        missing$
+syn keyword bstBuiltIn        newline$ num.names$
+syn keyword bstBuiltIn        pop$ preamble$ purify$ quote$
+syn keyword bstBuiltIn        skip$ stack$ substring$ swap$
+syn keyword bstBuiltIn        text.length$ text.prefix$ top$ type$
+syn keyword bstBuiltIn        warning$ while$ width$ write$
+syn match   bstIdentifier     "'\k*"
+syn keyword bstType           article book booklet conference
+syn keyword bstType           inbook incollection inproceedings
+syn keyword bstType           manual mastersthesis misc
+syn keyword bstType           phdthesis proceedings
+syn keyword bstType           techreport unpublished
+syn keyword bstField          abbr address annote author
+syn keyword bstField          booktitle chapter crossref comment
+syn keyword bstField          edition editor
+syn keyword bstField          howpublished institution journal key month
+syn keyword bstField          note number
+syn keyword bstField          organization
+syn keyword bstField          pages publisher
+syn keyword bstField          school series
+syn keyword bstField          title type
+syn keyword bstField          volume year
+
+" Define the default highlighting.
+" For version 5.7 and earlier: only when not done already
+" For version 5.8 and later: only when an item doesn't have highlighting yet
+if version >= 508 || !exists("did_bst_syn_inits")
+    if version < 508
+        let did_bst_syn_inits = 1
+        command -nargs=+ HiLink hi link <args>
+    else
+        command -nargs=+ HiLink hi def link <args>
+    endif
+
+    HiLink bstComment           Comment
+    HiLink bstString            String
+    HiLink bstCommand           PreProc
+    HiLink bstBuiltIn           Statement
+    HiLink bstField             Special
+    HiLink bstNumber            Number
+    HiLink bstType              Type
+    HiLink bstIdentifier        Identifier
+    HiLink bstError             Error
+    delcommand HiLink
+endif
+
+let b:current_syntax = "bst"
+
+" vim:set ft=vim sts=4 sw=4:
--- /dev/null
+++ b/lib/vimfiles/syntax/btm.vim
@@ -1,0 +1,229 @@
+" Vim syntax file
+" Language:	4Dos batch file
+" Maintainer:	John Leo Spetz <jls11@po.cwru.edu>
+" Last Change:	2001 May 09
+
+"//Issues to resolve:
+"//- Boolean operators surrounded by period are recognized but the
+"//  periods are not highlighted.  The only way to do that would
+"//  be separate synmatches for each possibility otherwise a more
+"//  general \.\i\+\. will highlight anything delimited by dots.
+"//- After unary operators like "defined" can assume token type.
+"//  Should there be more of these?
+
+" For version 5.x: Clear all syntax items
+" For version 6.x: Quit when a syntax file was already loaded
+if version < 600
+  syntax clear
+elseif exists("b:current_syntax")
+  finish
+endif
+
+syn case ignore
+
+syn keyword btmStatement	call off
+syn keyword btmConditional	if iff endiff then else elseiff not errorlevel
+syn keyword btmConditional	gt lt eq ne ge le
+syn match btmConditional transparent    "\.\i\+\." contains=btmDotBoolOp
+syn keyword btmDotBoolOp contained      and or xor
+syn match btmConditional	"=="
+syn match btmConditional	"!="
+syn keyword btmConditional	defined errorlevel exist isalias
+syn keyword btmConditional	isdir direxist isinternal islabel
+syn keyword btmRepeat		for in do enddo
+
+syn keyword btmTodo contained	TODO
+
+" String
+syn cluster btmVars contains=btmVariable,btmArgument,btmBIFMatch
+syn region  btmString	start=+"+  end=+"+ contains=@btmVars
+syn match btmNumber     "\<\d\+\>"
+
+"syn match  btmIdentifier	"\<\h\w*\>"
+
+" If you don't like tabs
+"syn match btmShowTab "\t"
+"syn match btmShowTabc "\t"
+"syn match  btmComment		"^\ *rem.*$" contains=btmTodo,btmShowTabc
+
+" Some people use this as a comment line
+" In fact this is a Label
+"syn match btmComment		"^\ *:\ \+.*$" contains=btmTodo
+
+syn match btmComment		"^\ *rem.*$" contains=btmTodo
+syn match btmComment		"^\ *::.*$" contains=btmTodo
+
+syn match btmLabelMark		"^\ *:[0-9a-zA-Z_\-]\+\>"
+syn match btmLabelMark		"goto [0-9a-zA-Z_\-]\+\>"lc=5
+syn match btmLabelMark		"gosub [0-9a-zA-Z_\-]\+\>"lc=6
+
+" syn match btmCmdDivider ">[>&][>&]\="
+syn match btmCmdDivider ">[>&]*"
+syn match btmCmdDivider ">>&>"
+syn match btmCmdDivider "|&\="
+syn match btmCmdDivider "%+"
+syn match btmCmdDivider "\^"
+
+syn region btmEcho start="echo" skip="echo" matchgroup=btmCmdDivider end="%+" end="$" end="|&\=" end="\^" end=">[>&]*" contains=@btmEchos oneline
+syn cluster btmEchos contains=@btmVars,btmEchoCommand,btmEchoParam
+syn keyword btmEchoCommand contained	echo echoerr echos echoserr
+syn keyword btmEchoParam contained	on off
+
+" this is also a valid Label. I don't use it.
+"syn match btmLabelMark		"^\ *:\ \+[0-9a-zA-Z_\-]\+\>"
+
+" //Environment variable can be expanded using notation %var in 4DOS
+syn match btmVariable		"%[0-9a-z_\-]\+" contains=@btmSpecialVars
+" //Environment variable can be expanded using notation %var%
+syn match btmVariable		"%[0-9a-z_\-]*%" contains=@btmSpecialVars
+" //The following are special variable in 4DOS
+syn match btmVariable		"%[=#]" contains=@btmSpecialVars
+syn match btmVariable		"%??\=" contains=@btmSpecialVars
+" //Environment variable can be expanded using notation %[var] in 4DOS
+syn match btmVariable		"%\[[0-9a-z_\-]*\]"
+" //After some keywords next word should be an environment variable
+syn match btmVariable		"defined\s\i\+"lc=8
+syn match btmVariable		"set\s\i\+"lc=4
+" //Parameters to batchfiles take the format %<digit>
+syn match btmArgument		"%\d\>"
+" //4DOS allows format %<digit>& meaning batchfile parameters digit and up
+syn match btmArgument		"%\d\>&"
+" //Variable used by FOR loops sometimes use %%<letter> in batchfiles
+syn match btmArgument		"%%\a\>"
+
+" //Show 4DOS built-in functions specially
+syn match btmBIFMatch "%@\w\+\["he=e-1 contains=btmBuiltInFunc
+syn keyword btmBuiltInFunc contained	alias ascii attrib cdrom
+syn keyword btmBuiltInFunc contained	char clip comma convert
+syn keyword btmBuiltInFunc contained	date day dec descript
+syn keyword btmBuiltInFunc contained	device diskfree disktotal
+syn keyword btmBuiltInFunc contained	diskused dosmem dow dowi
+syn keyword btmBuiltInFunc contained	doy ems eval exec execstr
+syn keyword btmBuiltInFunc contained	expand ext extended
+syn keyword btmBuiltInFunc contained	fileage fileclose filedate
+syn keyword btmBuiltInFunc contained	filename fileopen fileread
+syn keyword btmBuiltInFunc contained	files fileseek fileseekl
+syn keyword btmBuiltInFunc contained	filesize filetime filewrite
+syn keyword btmBuiltInFunc contained	filewriteb findclose
+syn keyword btmBuiltInFunc contained	findfirst findnext format
+syn keyword btmBuiltInFunc contained	full if inc index insert
+syn keyword btmBuiltInFunc contained	instr int label left len
+syn keyword btmBuiltInFunc contained	lfn line lines lower lpt
+syn keyword btmBuiltInFunc contained	makeage makedate maketime
+syn keyword btmBuiltInFunc contained	master month name numeric
+syn keyword btmBuiltInFunc contained	path random readscr ready
+syn keyword btmBuiltInFunc contained	remote removable repeat
+syn keyword btmBuiltInFunc contained	replace right search
+syn keyword btmBuiltInFunc contained	select sfn strip substr
+syn keyword btmBuiltInFunc contained	time timer trim truename
+syn keyword btmBuiltInFunc contained	unique upper wild word
+syn keyword btmBuiltInFunc contained	words xms year
+
+syn cluster btmSpecialVars contains=btmBuiltInVar,btmSpecialVar
+
+" //Show specialized variables specially
+" syn match btmSpecialVar contained	"+"
+syn match btmSpecialVar contained	"="
+syn match btmSpecialVar contained	"#"
+syn match btmSpecialVar contained	"??\="
+syn keyword btmSpecialVar contained	cmdline colordir comspec
+syn keyword btmSpecialVar contained	copycmd dircmd temp temp4dos
+syn keyword btmSpecialVar contained	filecompletion path prompt
+
+" //Show 4DOS built-in variables specially specially
+syn keyword btmBuiltInVar contained	_4ver _alias _ansi
+syn keyword btmBuiltInVar contained	_apbatt _aplife _apmac _batch
+syn keyword btmBuiltInVar contained	_batchline _batchname _bg
+syn keyword btmBuiltInVar contained	_boot _ci _cmdproc _co
+syn keyword btmBuiltInVar contained	_codepage _column _columns
+syn keyword btmBuiltInVar contained	_country _cpu _cwd _cwds _cwp
+syn keyword btmBuiltInVar contained	_cwps _date _day _disk _dname
+syn keyword btmBuiltInVar contained	_dos _dosver _dow _dowi _doy
+syn keyword btmBuiltInVar contained	_dpmi _dv _env _fg _hlogfile
+syn keyword btmBuiltInVar contained	_hour _kbhit _kstack _lastdisk
+syn keyword btmBuiltInVar contained	_logfile _minute _monitor
+syn keyword btmBuiltInVar contained	_month _mouse _ndp _row _rows
+syn keyword btmBuiltInVar contained	_second _shell _swapping
+syn keyword btmBuiltInVar contained	_syserr _time _transient
+syn keyword btmBuiltInVar contained	_video _win _wintitle _year
+
+" //Commands in 4DOS and/or DOS
+syn match btmCommand	"\s?"
+syn match btmCommand	"^?"
+syn keyword btmCommand	alias append assign attrib
+syn keyword btmCommand	backup beep break cancel case
+syn keyword btmCommand	cd cdd cdpath chcp chdir
+syn keyword btmCommand	chkdsk cls color comp copy
+syn keyword btmCommand	ctty date debug default defrag
+syn keyword btmCommand	del delay describe dir
+syn keyword btmCommand	dirhistory dirs diskcomp
+syn keyword btmCommand	diskcopy doskey dosshell
+syn keyword btmCommand	drawbox drawhline drawvline
+"syn keyword btmCommand	echo echoerr echos echoserr
+syn keyword btmCommand	edit edlin emm386 endlocal
+syn keyword btmCommand	endswitch erase eset except
+syn keyword btmCommand	exe2bin exit expand fastopen
+syn keyword btmCommand	fc fdisk ffind find format
+syn keyword btmCommand	free global gosub goto
+syn keyword btmCommand	graftabl graphics help history
+syn keyword btmCommand	inkey input join keyb keybd
+syn keyword btmCommand	keystack label lh list loadbtm
+syn keyword btmCommand	loadhigh lock log md mem
+syn keyword btmCommand	memory mirror mkdir mode more
+syn keyword btmCommand	move nlsfunc on option path
+syn keyword btmCommand	pause popd print prompt pushd
+syn keyword btmCommand	quit rd reboot recover ren
+syn keyword btmCommand	rename replace restore return
+syn keyword btmCommand	rmdir scandisk screen scrput
+syn keyword btmCommand	select set setdos setlocal
+syn keyword btmCommand	setver share shift sort subst
+syn keyword btmCommand	swapping switch sys tee text
+syn keyword btmCommand	time timer touch tree truename
+syn keyword btmCommand	type unalias undelete unformat
+syn keyword btmCommand	unlock unset ver verify vol
+syn keyword btmCommand	vscrput y
+
+" Define the default highlighting.
+" For version 5.7 and earlier: only when not done already
+" For version 5.8 and later: only when an item doesn't have highlighting yet
+if version >= 508 || !exists("did_btm_syntax_inits")
+  if version < 508
+    let did_btm_syntax_inits = 1
+    command -nargs=+ HiLink hi link <args>
+  else
+    command -nargs=+ HiLink hi def link <args>
+  endif
+
+  HiLink btmLabel		Special
+  HiLink btmLabelMark		Special
+  HiLink btmCmdDivider		Special
+  HiLink btmConditional		btmStatement
+  HiLink btmDotBoolOp		btmStatement
+  HiLink btmRepeat		btmStatement
+  HiLink btmEchoCommand	btmStatement
+  HiLink btmEchoParam		btmStatement
+  HiLink btmStatement		Statement
+  HiLink btmTodo		Todo
+  HiLink btmString		String
+  HiLink btmNumber		Number
+  HiLink btmComment		Comment
+  HiLink btmArgument		Identifier
+  HiLink btmVariable		Identifier
+  HiLink btmEcho		String
+  HiLink btmBIFMatch		btmStatement
+  HiLink btmBuiltInFunc		btmStatement
+  HiLink btmBuiltInVar		btmStatement
+  HiLink btmSpecialVar		btmStatement
+  HiLink btmCommand		btmStatement
+
+  "optional highlighting
+  "HiLink btmShowTab		Error
+  "HiLink btmShowTabc		Error
+  "hiLink btmIdentifier		Identifier
+
+  delcommand HiLink
+endif
+
+let b:current_syntax = "btm"
+
+" vim: ts=8
--- /dev/null
+++ b/lib/vimfiles/syntax/bzr.vim
@@ -1,0 +1,51 @@
+" Vim syntax file
+" Language:     Bazaar (bzr) commit file
+" Maintainer:   Dmitry Vasiliev <dima at hlabs dot spb dot ru>
+" URL:          http://www.hlabs.spb.ru/vim/bzr.vim
+" Revision:     $Id: bzr.vim,v 1.1 2007/05/05 17:20:51 vimboss Exp $
+" Filenames:    bzr_log.*
+" Version:      1.0
+
+" For version 5.x: Clear all syntax items.
+" For version 6.x: Quit when a syntax file was already loaded.
+if version < 600
+  syntax clear
+elseif exists("b:current_syntax")
+  finish
+endif
+
+syn region bzrRegion   start="^-\{14} This line and the following will be ignored -\{14}$" end="\%$" contains=ALL
+syn match bzrRemoved   "^removed:$" contained
+syn match bzrAdded     "^added:$" contained
+syn match bzrRenamed   "^renamed:$" contained
+syn match bzrModified  "^modified:$" contained
+syn match bzrUnchanged "^unchanged:$" contained
+syn match bzrUnknown   "^unknown:$" contained
+
+" Synchronization.
+syn sync clear
+syn sync match bzrSync  grouphere bzrRegion "^-\{14} This line and the following will be ignored -\{14}$"me=s-1
+
+" Define the default highlighting.
+" For version 5.7 and earlier: only when not done already.
+" For version 5.8 and later: only when an item doesn't have highlighting yet.
+if version >= 508 || !exists("did_bzr_syn_inits")
+  if version <= 508
+    let did_bzr_syn_inits = 1
+    command -nargs=+ HiLink hi link <args>
+  else
+    command -nargs=+ HiLink hi def link <args>
+  endif
+
+  HiLink bzrRegion     Comment
+  HiLink bzrRemoved    Constant
+  HiLink bzrAdded      Identifier
+  HiLink bzrModified   Special
+  HiLink bzrRenamed    Special
+  HiLink bzrUnchanged  Special
+  HiLink bzrUnknown    Special
+
+  delcommand HiLink
+endif
+
+let b:current_syntax = "bzr"
--- /dev/null
+++ b/lib/vimfiles/syntax/c.vim
@@ -1,0 +1,358 @@
+" Vim syntax file
+" Language:	C
+" Maintainer:	Bram Moolenaar <Bram@vim.org>
+" Last Change:	2007 Feb 13
+
+" Quit when a (custom) syntax file was already loaded
+if exists("b:current_syntax")
+  finish
+endif
+
+" A bunch of useful C keywords
+syn keyword	cStatement	goto break return continue asm
+syn keyword	cLabel		case default
+syn keyword	cConditional	if else switch
+syn keyword	cRepeat		while for do
+
+syn keyword	cTodo		contained TODO FIXME XXX
+
+" cCommentGroup allows adding matches for special things in comments
+syn cluster	cCommentGroup	contains=cTodo
+
+" String and Character constants
+" Highlight special characters (those which have a backslash) differently
+syn match	cSpecial	display contained "\\\(x\x\+\|\o\{1,3}\|.\|$\)"
+if !exists("c_no_utf")
+  syn match	cSpecial	display contained "\\\(u\x\{4}\|U\x\{8}\)"
+endif
+if exists("c_no_cformat")
+  syn region	cString		start=+L\="+ skip=+\\\\\|\\"+ end=+"+ contains=cSpecial,@Spell
+  " cCppString: same as cString, but ends at end of line
+  syn region	cCppString	start=+L\="+ skip=+\\\\\|\\"\|\\$+ excludenl end=+"+ end='$' contains=cSpecial,@Spell
+else
+  if !exists("c_no_c99") " ISO C99
+    syn match	cFormat		display "%\(\d\+\$\)\=[-+' #0*]*\(\d*\|\*\|\*\d\+\$\)\(\.\(\d*\|\*\|\*\d\+\$\)\)\=\([hlLjzt]\|ll\|hh\)\=\([aAbdiuoxXDOUfFeEgGcCsSpn]\|\[\^\=.[^]]*\]\)" contained
+  else
+    syn match	cFormat		display "%\(\d\+\$\)\=[-+' #0*]*\(\d*\|\*\|\*\d\+\$\)\(\.\(\d*\|\*\|\*\d\+\$\)\)\=\([hlL]\|ll\)\=\([bdiuoxXDOUfeEgGcCsSpn]\|\[\^\=.[^]]*\]\)" contained
+  endif
+  syn match	cFormat		display "%%" contained
+  syn region	cString		start=+L\="+ skip=+\\\\\|\\"+ end=+"+ contains=cSpecial,cFormat,@Spell
+  " cCppString: same as cString, but ends at end of line
+  syn region	cCppString	start=+L\="+ skip=+\\\\\|\\"\|\\$+ excludenl end=+"+ end='$' contains=cSpecial,cFormat,@Spell
+endif
+
+syn match	cCharacter	"L\='[^\\]'"
+syn match	cCharacter	"L'[^']*'" contains=cSpecial
+if exists("c_gnu")
+  syn match	cSpecialError	"L\='\\[^'\"?\\abefnrtv]'"
+  syn match	cSpecialCharacter "L\='\\['\"?\\abefnrtv]'"
+else
+  syn match	cSpecialError	"L\='\\[^'\"?\\abfnrtv]'"
+  syn match	cSpecialCharacter "L\='\\['\"?\\abfnrtv]'"
+endif
+syn match	cSpecialCharacter display "L\='\\\o\{1,3}'"
+syn match	cSpecialCharacter display "'\\x\x\{1,2}'"
+syn match	cSpecialCharacter display "L'\\x\x\+'"
+
+"when wanted, highlight trailing white space
+if exists("c_space_errors")
+  if !exists("c_no_trail_space_error")
+    syn match	cSpaceError	display excludenl "\s\+$"
+  endif
+  if !exists("c_no_tab_space_error")
+    syn match	cSpaceError	display " \+\t"me=e-1
+  endif
+endif
+
+" This should be before cErrInParen to avoid problems with #define ({ xxx })
+syntax region	cBlock		start="{" end="}" transparent fold
+
+"catch errors caused by wrong parenthesis and brackets
+" also accept <% for {, %> for }, <: for [ and :> for ] (C99)
+" But avoid matching <::.
+syn cluster	cParenGroup	contains=cParenError,cIncluded,cSpecial,cCommentSkip,cCommentString,cComment2String,@cCommentGroup,cCommentStartError,cUserCont,cUserLabel,cBitField,cCommentSkip,cOctalZero,cCppOut,cCppOut2,cCppSkip,cFormat,cNumber,cFloat,cOctal,cOctalError,cNumbersCom
+if exists("c_no_curly_error")
+  syn region	cParen		transparent start='(' end=')' contains=ALLBUT,@cParenGroup,cCppParen,cCppString,@Spell
+  " cCppParen: same as cParen but ends at end-of-line; used in cDefine
+  syn region	cCppParen	transparent start='(' skip='\\$' excludenl end=')' end='$' contained contains=ALLBUT,@cParenGroup,cParen,cString,@Spell
+  syn match	cParenError	display ")"
+  syn match	cErrInParen	display contained "^[{}]\|^<%\|^%>"
+elseif exists("c_no_bracket_error")
+  syn region	cParen		transparent start='(' end=')' contains=ALLBUT,@cParenGroup,cCppParen,cCppString,@Spell
+  " cCppParen: same as cParen but ends at end-of-line; used in cDefine
+  syn region	cCppParen	transparent start='(' skip='\\$' excludenl end=')' end='$' contained contains=ALLBUT,@cParenGroup,cParen,cString,@Spell
+  syn match	cParenError	display ")"
+  syn match	cErrInParen	display contained "[{}]\|<%\|%>"
+else
+  syn region	cParen		transparent start='(' end=')' contains=ALLBUT,@cParenGroup,cCppParen,cErrInBracket,cCppBracket,cCppString,@Spell
+  " cCppParen: same as cParen but ends at end-of-line; used in cDefine
+  syn region	cCppParen	transparent start='(' skip='\\$' excludenl end=')' end='$' contained contains=ALLBUT,@cParenGroup,cErrInBracket,cParen,cBracket,cString,@Spell
+  syn match	cParenError	display "[\])]"
+  syn match	cErrInParen	display contained "[\]{}]\|<%\|%>"
+  syn region	cBracket	transparent start='\[\|<::\@!' end=']\|:>' contains=ALLBUT,@cParenGroup,cErrInParen,cCppParen,cCppBracket,cCppString,@Spell
+  " cCppBracket: same as cParen but ends at end-of-line; used in cDefine
+  syn region	cCppBracket	transparent start='\[\|<::\@!' skip='\\$' excludenl end=']\|:>' end='$' contained contains=ALLBUT,@cParenGroup,cErrInParen,cParen,cBracket,cString,@Spell
+  syn match	cErrInBracket	display contained "[);{}]\|<%\|%>"
+endif
+
+"integer number, or floating point number without a dot and with "f".
+syn case ignore
+syn match	cNumbers	display transparent "\<\d\|\.\d" contains=cNumber,cFloat,cOctalError,cOctal
+" Same, but without octal error (for comments)
+syn match	cNumbersCom	display contained transparent "\<\d\|\.\d" contains=cNumber,cFloat,cOctal
+syn match	cNumber		display contained "\d\+\(u\=l\{0,2}\|ll\=u\)\>"
+"hex number
+syn match	cNumber		display contained "0x\x\+\(u\=l\{0,2}\|ll\=u\)\>"
+" Flag the first zero of an octal number as something special
+syn match	cOctal		display contained "0\o\+\(u\=l\{0,2}\|ll\=u\)\>" contains=cOctalZero
+syn match	cOctalZero	display contained "\<0"
+syn match	cFloat		display contained "\d\+f"
+"floating point number, with dot, optional exponent
+syn match	cFloat		display contained "\d\+\.\d*\(e[-+]\=\d\+\)\=[fl]\="
+"floating point number, starting with a dot, optional exponent
+syn match	cFloat		display contained "\.\d\+\(e[-+]\=\d\+\)\=[fl]\=\>"
+"floating point number, without dot, with exponent
+syn match	cFloat		display contained "\d\+e[-+]\=\d\+[fl]\=\>"
+if !exists("c_no_c99")
+  "hexadecimal floating point number, optional leading digits, with dot, with exponent
+  syn match	cFloat		display contained "0x\x*\.\x\+p[-+]\=\d\+[fl]\=\>"
+  "hexadecimal floating point number, with leading digits, optional dot, with exponent
+  syn match	cFloat		display contained "0x\x\+\.\=p[-+]\=\d\+[fl]\=\>"
+endif
+
+" flag an octal number with wrong digits
+syn match	cOctalError	display contained "0\o*[89]\d*"
+syn case match
+
+if exists("c_comment_strings")
+  " A comment can contain cString, cCharacter and cNumber.
+  " But a "*/" inside a cString in a cComment DOES end the comment!  So we
+  " need to use a special type of cString: cCommentString, which also ends on
+  " "*/", and sees a "*" at the start of the line as comment again.
+  " Unfortunately this doesn't very well work for // type of comments :-(
+  syntax match	cCommentSkip	contained "^\s*\*\($\|\s\+\)"
+  syntax region cCommentString	contained start=+L\=\\\@<!"+ skip=+\\\\\|\\"+ end=+"+ end=+\*/+me=s-1 contains=cSpecial,cCommentSkip
+  syntax region cComment2String	contained start=+L\=\\\@<!"+ skip=+\\\\\|\\"+ end=+"+ end="$" contains=cSpecial
+  syntax region  cCommentL	start="//" skip="\\$" end="$" keepend contains=@cCommentGroup,cComment2String,cCharacter,cNumbersCom,cSpaceError,@Spell
+  if exists("c_no_comment_fold")
+    " Use "extend" here to have preprocessor lines not terminate halfway a
+    " comment.
+    syntax region cComment	matchgroup=cCommentStart start="/\*" end="\*/" contains=@cCommentGroup,cCommentStartError,cCommentString,cCharacter,cNumbersCom,cSpaceError,@Spell extend
+  else
+    syntax region cComment	matchgroup=cCommentStart start="/\*" end="\*/" contains=@cCommentGroup,cCommentStartError,cCommentString,cCharacter,cNumbersCom,cSpaceError,@Spell fold extend
+  endif
+else
+  syn region	cCommentL	start="//" skip="\\$" end="$" keepend contains=@cCommentGroup,cSpaceError,@Spell
+  if exists("c_no_comment_fold")
+    syn region	cComment	matchgroup=cCommentStart start="/\*" end="\*/" contains=@cCommentGroup,cCommentStartError,cSpaceError,@Spell
+  else
+    syn region	cComment	matchgroup=cCommentStart start="/\*" end="\*/" contains=@cCommentGroup,cCommentStartError,cSpaceError,@Spell fold
+  endif
+endif
+" keep a // comment separately, it terminates a preproc. conditional
+syntax match	cCommentError	display "\*/"
+syntax match	cCommentStartError display "/\*"me=e-1 contained
+
+syn keyword	cOperator	sizeof
+if exists("c_gnu")
+  syn keyword	cStatement	__asm__
+  syn keyword	cOperator	typeof __real__ __imag__
+endif
+syn keyword	cType		int long short char void
+syn keyword	cType		signed unsigned float double
+if !exists("c_no_ansi") || exists("c_ansi_typedefs")
+  syn keyword   cType		size_t ssize_t off_t wchar_t ptrdiff_t sig_atomic_t fpos_t
+  syn keyword   cType		clock_t time_t va_list jmp_buf FILE DIR div_t ldiv_t
+  syn keyword   cType		mbstate_t wctrans_t wint_t wctype_t
+endif
+if !exists("c_no_c99") " ISO C99
+  syn keyword	cType		bool complex
+  syn keyword	cType		int8_t int16_t int32_t int64_t
+  syn keyword	cType		uint8_t uint16_t uint32_t uint64_t
+  syn keyword	cType		int_least8_t int_least16_t int_least32_t int_least64_t
+  syn keyword	cType		uint_least8_t uint_least16_t uint_least32_t uint_least64_t
+  syn keyword	cType		int_fast8_t int_fast16_t int_fast32_t int_fast64_t
+  syn keyword	cType		uint_fast8_t uint_fast16_t uint_fast32_t uint_fast64_t
+  syn keyword	cType		intptr_t uintptr_t
+  syn keyword	cType		intmax_t uintmax_t
+endif
+if exists("c_gnu")
+  syn keyword	cType		__label__ __complex__ __volatile__
+endif
+
+syn keyword	cStructure	struct union enum typedef
+syn keyword	cStorageClass	static register auto volatile extern const
+if exists("c_gnu")
+  syn keyword	cStorageClass	inline __attribute__
+endif
+if !exists("c_no_c99")
+  syn keyword	cStorageClass	inline restrict
+endif
+
+if !exists("c_no_ansi") || exists("c_ansi_constants") || exists("c_gnu")
+  if exists("c_gnu")
+    syn keyword cConstant __GNUC__ __FUNCTION__ __PRETTY_FUNCTION__ __func__
+  endif
+  syn keyword cConstant __LINE__ __FILE__ __DATE__ __TIME__ __STDC__
+  syn keyword cConstant __STDC_VERSION__
+  syn keyword cConstant CHAR_BIT MB_LEN_MAX MB_CUR_MAX
+  syn keyword cConstant UCHAR_MAX UINT_MAX ULONG_MAX USHRT_MAX
+  syn keyword cConstant CHAR_MIN INT_MIN LONG_MIN SHRT_MIN
+  syn keyword cConstant CHAR_MAX INT_MAX LONG_MAX SHRT_MAX
+  syn keyword cConstant SCHAR_MIN SINT_MIN SLONG_MIN SSHRT_MIN
+  syn keyword cConstant SCHAR_MAX SINT_MAX SLONG_MAX SSHRT_MAX
+  if !exists("c_no_c99")
+    syn keyword cConstant __func__
+    syn keyword cConstant LLONG_MAX ULLONG_MAX
+    syn keyword cConstant INT8_MIN INT16_MIN INT32_MIN INT64_MIN
+    syn keyword cConstant INT8_MAX INT16_MAX INT32_MAX INT64_MAX
+    syn keyword cConstant UINT8_MAX UINT16_MAX UINT32_MAX UINT64_MAX
+    syn keyword cConstant INT_LEAST8_MIN INT_LEAST16_MIN INT_LEAST32_MIN INT_LEAST64_MIN
+    syn keyword cConstant INT_LEAST8_MAX INT_LEAST16_MAX INT_LEAST32_MAX INT_LEAST64_MAX
+    syn keyword cConstant UINT_LEAST8_MAX UINT_LEAST16_MAX UINT_LEAST32_MAX UINT_LEAST64_MAX
+    syn keyword cConstant INT_FAST8_MIN INT_FAST16_MIN INT_FAST32_MIN INT_FAST64_MIN
+    syn keyword cConstant INT_FAST8_MAX INT_FAST16_MAX INT_FAST32_MAX INT_FAST64_MAX
+    syn keyword cConstant UINT_FAST8_MAX UINT_FAST16_MAX UINT_FAST32_MAX UINT_FAST64_MAX
+    syn keyword cConstant INTPTR_MIN INTPTR_MAX UINTPTR_MAX
+    syn keyword cConstant INTMAX_MIN INTMAX_MAX UINTMAX_MAX
+    syn keyword cConstant PTRDIFF_MIN PTRDIFF_MAX SIG_ATOMIC_MIN SIG_ATOMIC_MAX
+    syn keyword cConstant SIZE_MAX WCHAR_MIN WCHAR_MAX WINT_MIN WINT_MAX
+  endif
+  syn keyword cConstant FLT_RADIX FLT_ROUNDS
+  syn keyword cConstant FLT_DIG FLT_MANT_DIG FLT_EPSILON
+  syn keyword cConstant DBL_DIG DBL_MANT_DIG DBL_EPSILON
+  syn keyword cConstant LDBL_DIG LDBL_MANT_DIG LDBL_EPSILON
+  syn keyword cConstant FLT_MIN FLT_MAX FLT_MIN_EXP FLT_MAX_EXP
+  syn keyword cConstant FLT_MIN_10_EXP FLT_MAX_10_EXP
+  syn keyword cConstant DBL_MIN DBL_MAX DBL_MIN_EXP DBL_MAX_EXP
+  syn keyword cConstant DBL_MIN_10_EXP DBL_MAX_10_EXP
+  syn keyword cConstant LDBL_MIN LDBL_MAX LDBL_MIN_EXP LDBL_MAX_EXP
+  syn keyword cConstant LDBL_MIN_10_EXP LDBL_MAX_10_EXP
+  syn keyword cConstant HUGE_VAL CLOCKS_PER_SEC NULL
+  syn keyword cConstant LC_ALL LC_COLLATE LC_CTYPE LC_MONETARY
+  syn keyword cConstant LC_NUMERIC LC_TIME
+  syn keyword cConstant SIG_DFL SIG_ERR SIG_IGN
+  syn keyword cConstant SIGABRT SIGFPE SIGILL SIGHUP SIGINT SIGSEGV SIGTERM
+  " Add POSIX signals as well...
+  syn keyword cConstant SIGABRT SIGALRM SIGCHLD SIGCONT SIGFPE SIGHUP
+  syn keyword cConstant SIGILL SIGINT SIGKILL SIGPIPE SIGQUIT SIGSEGV
+  syn keyword cConstant SIGSTOP SIGTERM SIGTRAP SIGTSTP SIGTTIN SIGTTOU
+  syn keyword cConstant SIGUSR1 SIGUSR2
+  syn keyword cConstant _IOFBF _IOLBF _IONBF BUFSIZ EOF WEOF
+  syn keyword cConstant FOPEN_MAX FILENAME_MAX L_tmpnam
+  syn keyword cConstant SEEK_CUR SEEK_END SEEK_SET
+  syn keyword cConstant TMP_MAX stderr stdin stdout
+  syn keyword cConstant EXIT_FAILURE EXIT_SUCCESS RAND_MAX
+  " Add POSIX errors as well
+  syn keyword cConstant E2BIG EACCES EAGAIN EBADF EBADMSG EBUSY
+  syn keyword cConstant ECANCELED ECHILD EDEADLK EDOM EEXIST EFAULT
+  syn keyword cConstant EFBIG EILSEQ EINPROGRESS EINTR EINVAL EIO EISDIR
+  syn keyword cConstant EMFILE EMLINK EMSGSIZE ENAMETOOLONG ENFILE ENODEV
+  syn keyword cConstant ENOENT ENOEXEC ENOLCK ENOMEM ENOSPC ENOSYS
+  syn keyword cConstant ENOTDIR ENOTEMPTY ENOTSUP ENOTTY ENXIO EPERM
+  syn keyword cConstant EPIPE ERANGE EROFS ESPIPE ESRCH ETIMEDOUT EXDEV
+  " math.h
+  syn keyword cConstant M_E M_LOG2E M_LOG10E M_LN2 M_LN10 M_PI M_PI_2 M_PI_4
+  syn keyword cConstant M_1_PI M_2_PI M_2_SQRTPI M_SQRT2 M_SQRT1_2
+endif
+if !exists("c_no_c99") " ISO C99
+  syn keyword cConstant true false
+endif
+
+" Accept %: for # (C99)
+syn region	cPreCondit	start="^\s*\(%:\|#\)\s*\(if\|ifdef\|ifndef\|elif\)\>" skip="\\$" end="$" end="//"me=s-1 contains=cComment,cCppString,cCharacter,cCppParen,cParenError,cNumbers,cCommentError,cSpaceError
+syn match	cPreCondit	display "^\s*\(%:\|#\)\s*\(else\|endif\)\>"
+if !exists("c_no_if0")
+  if !exists("c_no_if0_fold")
+    syn region	cCppOut		start="^\s*\(%:\|#\)\s*if\s\+0\+\>" end=".\@=\|$" contains=cCppOut2 fold
+  else
+    syn region	cCppOut		start="^\s*\(%:\|#\)\s*if\s\+0\+\>" end=".\@=\|$" contains=cCppOut2
+  endif
+  syn region	cCppOut2	contained start="0" end="^\s*\(%:\|#\)\s*\(endif\>\|else\>\|elif\>\)" contains=cSpaceError,cCppSkip
+  syn region	cCppSkip	contained start="^\s*\(%:\|#\)\s*\(if\>\|ifdef\>\|ifndef\>\)" skip="\\$" end="^\s*\(%:\|#\)\s*endif\>" contains=cSpaceError,cCppSkip
+endif
+syn region	cIncluded	display contained start=+"+ skip=+\\\\\|\\"+ end=+"+
+syn match	cIncluded	display contained "<[^>]*>"
+syn match	cInclude	display "^\s*\(%:\|#\)\s*include\>\s*["<]" contains=cIncluded
+"syn match cLineSkip	"\\$"
+syn cluster	cPreProcGroup	contains=cPreCondit,cIncluded,cInclude,cDefine,cErrInParen,cErrInBracket,cUserLabel,cSpecial,cOctalZero,cCppOut,cCppOut2,cCppSkip,cFormat,cNumber,cFloat,cOctal,cOctalError,cNumbersCom,cString,cCommentSkip,cCommentString,cComment2String,@cCommentGroup,cCommentStartError,cParen,cBracket,cMulti
+syn region	cDefine		start="^\s*\(%:\|#\)\s*\(define\|undef\)\>" skip="\\$" end="$" end="//"me=s-1 keepend contains=ALLBUT,@cPreProcGroup,@Spell
+syn region	cPreProc	start="^\s*\(%:\|#\)\s*\(pragma\>\|line\>\|warning\>\|warn\>\|error\>\)" skip="\\$" end="$" keepend contains=ALLBUT,@cPreProcGroup,@Spell
+
+" Highlight User Labels
+syn cluster	cMultiGroup	contains=cIncluded,cSpecial,cCommentSkip,cCommentString,cComment2String,@cCommentGroup,cCommentStartError,cUserCont,cUserLabel,cBitField,cOctalZero,cCppOut,cCppOut2,cCppSkip,cFormat,cNumber,cFloat,cOctal,cOctalError,cNumbersCom,cCppParen,cCppBracket,cCppString
+syn region	cMulti		transparent start='?' skip='::' end=':' contains=ALLBUT,@cMultiGroup,@Spell
+" Avoid matching foo::bar() in C++ by requiring that the next char is not ':'
+syn cluster	cLabelGroup	contains=cUserLabel
+syn match	cUserCont	display "^\s*\I\i*\s*:$" contains=@cLabelGroup
+syn match	cUserCont	display ";\s*\I\i*\s*:$" contains=@cLabelGroup
+syn match	cUserCont	display "^\s*\I\i*\s*:[^:]"me=e-1 contains=@cLabelGroup
+syn match	cUserCont	display ";\s*\I\i*\s*:[^:]"me=e-1 contains=@cLabelGroup
+
+syn match	cUserLabel	display "\I\i*" contained
+
+" Avoid recognizing most bitfields as labels
+syn match	cBitField	display "^\s*\I\i*\s*:\s*[1-9]"me=e-1 contains=cType
+syn match	cBitField	display ";\s*\I\i*\s*:\s*[1-9]"me=e-1 contains=cType
+
+if exists("c_minlines")
+  let b:c_minlines = c_minlines
+else
+  if !exists("c_no_if0")
+    let b:c_minlines = 50	" #if 0 constructs can be long
+  else
+    let b:c_minlines = 15	" mostly for () constructs
+  endif
+endif
+exec "syn sync ccomment cComment minlines=" . b:c_minlines
+
+" Define the default highlighting.
+" Only used when an item doesn't have highlighting yet
+hi def link cFormat		cSpecial
+hi def link cCppString		cString
+hi def link cCommentL		cComment
+hi def link cCommentStart	cComment
+hi def link cLabel		Label
+hi def link cUserLabel		Label
+hi def link cConditional	Conditional
+hi def link cRepeat		Repeat
+hi def link cCharacter		Character
+hi def link cSpecialCharacter	cSpecial
+hi def link cNumber		Number
+hi def link cOctal		Number
+hi def link cOctalZero		PreProc	 " link this to Error if you want
+hi def link cFloat		Float
+hi def link cOctalError		cError
+hi def link cParenError		cError
+hi def link cErrInParen		cError
+hi def link cErrInBracket	cError
+hi def link cCommentError	cError
+hi def link cCommentStartError	cError
+hi def link cSpaceError		cError
+hi def link cSpecialError	cError
+hi def link cOperator		Operator
+hi def link cStructure		Structure
+hi def link cStorageClass	StorageClass
+hi def link cInclude		Include
+hi def link cPreProc		PreProc
+hi def link cDefine		Macro
+hi def link cIncluded		cString
+hi def link cError		Error
+hi def link cStatement		Statement
+hi def link cPreCondit		PreCondit
+hi def link cType		Type
+hi def link cConstant		Constant
+hi def link cCommentString	cString
+hi def link cComment2String	cString
+hi def link cCommentSkip	cComment
+hi def link cString		String
+hi def link cComment		Comment
+hi def link cSpecial		SpecialChar
+hi def link cTodo		Todo
+hi def link cCppSkip		cCppOut
+hi def link cCppOut2		cCppOut
+hi def link cCppOut		Comment
+
+let b:current_syntax = "c"
+
+" vim: ts=8
--- /dev/null
+++ b/lib/vimfiles/syntax/calendar.vim
@@ -1,0 +1,110 @@
+" Vim syntax file
+" Language:         calendar(1) input file
+" Maintainer:       Nikolai Weibull <now@bitwi.se>
+" Latest Revision:  2006-04-19
+
+if exists("b:current_syntax")
+  finish
+endif
+
+let s:cpo_save = &cpo
+set cpo&vim
+
+syn keyword calendarTodo          contained TODO FIXME XXX NOTE
+
+syn region  calendarComment       start='/\*' end='\*/'
+                                  \ contains=calendarTodo,@Spell
+
+syn region  calendarCppString     start=+L\="+ skip=+\\\\\|\\"\|\\$+ excludenl
+                                  \ end=+"+ end='$' contains=calendarSpecial
+syn match   calendarSpecial       display contained '\\\%(x\x\+\|\o\{1,3}\|.\|$\)'
+syn match   calendarSpecial       display contained "\\\(u\x\{4}\|U\x\{8}\)"
+
+syn region  calendarPreCondit     start='^\s*#\s*\%(if\|ifdef\|ifndef\|elif\)\>'
+                                  \ skip='\\$' end='$'
+                                  \ contains=calendarComment,calendarCppString
+syn match   calendarPreCondit     display '^\s*#\s*\%(else\|endif\)\>'
+syn region  calendarCppOut        start='^\s*#\s*if\s\+0\+' end='.\@=\|$'
+                                  \ contains=calendarCppOut2
+syn region  calendarCppOut2       contained start='0'
+                                  \ end='^\s*#\s*\%(endif\|else\|elif\)\>'
+                                  \ contains=calendarSpaceError,calendarCppSkip
+syn region  calendarCppSkip       contained
+                                  \ start='^\s*#\s*\%(if\|ifdef\|ifndef\)\>'
+                                  \ skip='\\$' end='^\s*#\s*endif\>'
+                                  \ contains=calendarSpaceError,calendarCppSkip
+syn region  calendarIncluded      display contained start=+"+ skip=+\\\\\|\\"+
+                                  \ end=+"+
+syn match   calendarIncluded      display contained '<[^>]*>'
+syn match   calendarInclude       display '^\s*#\s*include\>\s*["<]'
+                                  \ contains=calendarIncluded
+syn cluster calendarPreProcGroup  contains=calendarPreCondit,calendarIncluded,
+                                  \ calendarInclude,calendarDefine,
+                                  \ calendarCppOut,calendarCppOut2,
+                                  \ calendarCppSkip,calendarString,
+                                  \ calendarSpecial,calendarTodo
+syn region  calendarDefine        start='^\s*#\s*\%(define\|undef\)\>'
+                                  \ skip='\\$' end='$'
+                                  \ contains=ALLBUT,@calendarPreProcGroup
+syn region  calendarPreProc       start='^\s*#\s*\%(pragma\|line\|warning\|warn\|error\)\>'
+                                  \ skip='\\$' end='$' keepend
+                                  \ contains=ALLBUT,@calendarPreProcGroup
+
+syn keyword calendarKeyword       CHARSET BODUN LANG
+syn case ignore
+syn keyword calendarKeyword       Easter Pashka
+syn case match
+
+syn case ignore
+syn match   calendarNumber        display '\<\d\+\>'
+syn keyword calendarMonth         Jan[uary] Feb[ruary] Mar[ch] Apr[il] May
+                                  \ Jun[e] Jul[y] Aug[ust] Sep[tember]
+                                  \ Oct[ober] Nov[ember] Dec[ember]
+syn match   calendarMonth         display '\<\%(Jan\|Feb\|Mar\|Apr\|May\|Jun\|Jul\|Aug\|Sep\|Oct\|Nov\|Dec\)\.'
+syn keyword calendarWeekday       Mon[day] Tue[sday] Wed[nesday] Thu[rsday]
+syn keyword calendarWeekday       Fri[day] Sat[urday] Sun[day]
+syn match   calendarWeekday       display '\<\%(Mon\|Tue\|Wed\|Thu\|Fri\|Sat\|Sun\)\.'
+                                  \ nextgroup=calendarWeekdayMod
+syn match   calendarWeekdayMod    display '[+-]\d\+\>'
+syn case match
+
+syn match   calendarTime          display '\<\%([01]\=\d\|2[0-3]\):[0-5]\d\%(:[0-5]\d\)\='
+syn match   calendarTime          display '\<\%(0\=[1-9]\|1[0-2]\):[0-5]\d\%(:[0-5]\d\)\=\s*[AaPp][Mm]'
+
+syn match calendarVariable        '\*'
+
+if exists("c_minlines")
+  let b:c_minlines = c_minlines
+else
+  if !exists("c_no_if0")
+    let b:c_minlines = 50       " #if 0 constructs can be long
+  else
+    let b:c_minlines = 15       " mostly for () constructs
+  endif
+endif
+exec "syn sync ccomment calendarComment minlines=" . b:c_minlines
+
+hi def link calendarTodo          Todo
+hi def link calendarComment       Comment
+hi def link calendarCppString     String
+hi def link calendarSpecial       SpecialChar
+hi def link calendarPreCondit     PreCondit
+hi def link calendarCppOut        Comment
+hi def link calendarCppOut2       calendarCppOut
+hi def link calendarCppSkip       calendarCppOut
+hi def link calendarIncluded      String
+hi def link calendarInclude       Include
+hi def link calendarDefine        Macro
+hi def link calendarPreProc       PreProc
+hi def link calendarKeyword       Keyword
+hi def link calendarNumber        Number
+hi def link calendarMonth         String
+hi def link calendarWeekday       String
+hi def link calendarWeekdayMod    Special
+hi def link calendarTime          Number
+hi def link calendarVariable      Identifier
+
+let b:current_syntax = "calendar"
+
+let &cpo = s:cpo_save
+unlet s:cpo_save
--- /dev/null
+++ b/lib/vimfiles/syntax/catalog.vim
@@ -1,0 +1,30 @@
+" Vim syntax file
+" Language:	sgml catalog file
+" Maintainer:	Johannes Zellner <johannes@zellner.org>
+" Last Change:	Fr, 04 Nov 2005 12:46:45 CET
+" Filenames:	/etc/sgml.catalog
+" $Id: catalog.vim,v 1.2 2005/11/23 21:11:10 vimboss Exp $
+
+" Quit when a syntax file was already loaded
+if exists("b:current_syntax")
+  finish
+endif
+
+syn case ignore
+
+" strings
+syn region  catalogString start=+"+ skip=+\\\\\|\\"+ end=+"+ keepend
+syn region  catalogString start=+'+ skip=+\\\\\|\\'+ end=+'+ keepend
+
+syn region  catalogComment      start=+--+   end=+--+ contains=catalogTodo
+syn keyword catalogTodo		TODO FIXME XXX NOTE contained
+syn keyword catalogKeyword	DOCTYPE OVERRIDE PUBLIC DTDDECL ENTITY CATALOG
+
+
+" The default highlighting.
+hi def link catalogString		     String
+hi def link catalogComment		     Comment
+hi def link catalogTodo			     Todo
+hi def link catalogKeyword		     Statement
+
+let b:current_syntax = "catalog"
--- /dev/null
+++ b/lib/vimfiles/syntax/cdl.vim
@@ -1,0 +1,89 @@
+" Vim syntax file
+" Language: Comshare Dimension Definition Language
+" Maintainer:	Raul Segura Acevedo <raulseguraaceved@netscape.net>
+" Last change:	2001 Jul 31
+
+if version < 600
+	syntax clear
+elseif exists("b:current_syntax")
+	finish
+endif
+
+sy case ignore
+sy sync fromstart
+sy keyword	cdlStatement	dimension hierarchy group grouphierarchy schedule class
+sy keyword	cdlType		add update file category main altername removeall required notrequired
+sy keyword	cdlConditional	if then elseif else endif and or not cons rpt xlt
+sy keyword	cdlFunction	ChildOf IChildOf LeafChildOf DescendantOf IDescendantOf LeafDescendantOf MemberIs CountOf
+
+sy keyword	cdlIdentifier	contained id name desc description xlttype precision symbol curr_ name group_name rate_name
+sy keyword	cdlIdentifier	contained xcheck endbal accounttype natsign consolidate formula pctown usage periodicity
+sy match	cdlIdentifier	contained 'child\s*name'
+sy match	cdlIdentifier	contained 'parent\s*name'
+sy match	cdlIdentifier	contained 'grp\s*description'
+sy match	cdlIdentifier	contained 'grpchild\s*name'
+sy match	cdlIdentifier	contained 'grpparent\s*name'
+sy match	cdlIdentifier	contained 'preceding\s*member'
+sy match	cdlIdentifier	contained 'unit\s*name'
+sy match	cdlIdentifier	contained 'unit\s*id'
+sy match	cdlIdentifier	contained 'schedule\s*name'
+sy match	cdlIdentifier	contained 'schedule\s*id'
+
+sy match	cdlString	/\[[^]]*]/	contains=cdlRestricted,cdlNotSupported
+sy match	cdlRestricted	contained /[&*,_]/
+" not supported +sy match	cdlNotSupported	contained /[:"!']/
+
+sy keyword	cdlTodo		contained TODO FIXME XXX
+sy cluster	cdlCommentGroup contains=cdlTodo
+sy match	cdlComment	'//.*' contains=@cdlCommentGroup
+sy region	cdlComment	start="/\*" end="\*/" contains=@cdlCommentGroup fold
+sy match	cdlCommentE	"\*/"
+
+sy region	cdlParen	transparent start='(' end=')' contains=ALLBUT,cdlParenE,cdlRestricted,cdlNotSupported
+"sy region	cdlParen	transparent start='(' end=')' contains=cdlIdentifier,cdlComment,cdlParenWordE
+sy match	cdlParenE	")"
+"sy match	cdlParenWordE	contained "\k\+"
+
+sy keyword	cdlFxType	allocation downfoot expr xltgain
+"sy keyword	cdlFxType	contained allocation downfoot expr xltgain
+"sy region	cdlFx		transparent start='\k\+(' end=')' contains=cdlConditional,cdlFunction,cdlString,cdlComment,cdlFxType
+
+set foldmethod=expr
+set foldexpr=(getline(v:lnum+1)=~'{'\|\|getline(v:lnum)=~'//\\s\\*\\{5}.*table')?'>1':1
+%foldo!
+set foldmethod=manual
+let b:match_words='\<if\>:\<then\>:\<elseif\>:\<else\>:\<endif\>'
+
+" Define the default highlighting.
+" For version 5.7 and earlier: only when not done already
+" For version 5.8 and later: only when an item doesn't have highlighting yet
+if version >= 508 || !exists("did_csc_syntax_inits")
+	if version < 508
+		let did_csc_syntax_inits = 1
+		command -nargs=+ HiLink hi link <args>
+	else
+		command -nargs=+ HiLink hi def link <args>
+	endif
+
+	HiLink cdlStatement	Statement
+	HiLink cdlType		Type
+	HiLink cdlFxType	Type
+	HiLink cdlIdentifier	Identifier
+	HiLink cdlString	String
+	HiLink cdlRestricted	WarningMsg
+	HiLink cdlNotSupported	ErrorMsg
+	HiLink cdlTodo		Todo
+	HiLink cdlComment	Comment
+	HiLink cdlCommentE	ErrorMsg
+	HiLink cdlParenE	ErrorMsg
+	HiLink cdlParenWordE	ErrorMsg
+	HiLink cdlFunction	Function
+	HiLink cdlConditional	Conditional
+
+	delcommand HiLink
+endif
+
+let b:current_syntax = "cdl"
+
+" vim: ts=8
--- /dev/null
+++ b/lib/vimfiles/syntax/cdrtoc.vim
@@ -1,0 +1,537 @@
+" Vim syntax file
+" Language:         cdrdao(1) TOC file
+" Maintainer:       Nikolai Weibull <now@bitwi.se>
+" Latest Revision:  2007-05-10
+
+if exists("b:current_syntax")
+  finish
+endif
+
+let s:cpo_save = &cpo
+set cpo&vim
+
+syn keyword cdrtocTodo
+      \ contained
+      \ TODO
+      \ FIXME
+      \ XXX
+      \ NOTE
+
+syn cluster cdrtocCommentContents
+      \ contains=
+      \   cdrtocTodo,
+      \   @Spell
+
+syn cluster cdrtocHeaderFollowsInitial
+      \ contains=
+      \   cdrtocHeaderCommentInitial,
+      \   cdrtocHeaderCatalog,
+      \   cdrtocHeaderTOCType,
+      \   cdrtocHeaderCDText,
+      \   cdrtocTrack
+
+syn match   cdrtocHeaderBegin
+      \ nextgroup=@cdrtocHeaderFollowsInitial
+      \ skipwhite skipempty
+      \ '\%^'
+
+let s:mmssff_pattern = '\%([0-5]\d\|\d\):\%([0-5]\d\|\d\):\%([0-6]\d\|7[0-5]\|\d\)\>'
+let s:byte_pattern = '\<\%([01]\=\d\{1,2}\|2\%([0-4]\d\|5[0-5]\)\)\>'
+let s:length_pattern = '\%(\%([0-5]\d\|\d\):\%([0-5]\d\|\d\):\%([0-6]\d\|7[0-5]\|\d\)\|\d\+\)\>'
+
+function s:def_comment(name, nextgroup)
+  execute 'syn match' a:name
+        \ 'nextgroup=' . a:nextgroup . ',' . a:name
+        \ 'skipwhite skipempty'
+        \ 'contains=@cdrtocCommentContents'
+        \ 'contained'
+        \ "'//.*$'"
+  execute 'hi def link' a:name 'cdrtocComment'
+endfunction
+
+function s:def_keywords(name, nextgroup, keywords)
+  let comment_group = a:name . 'FollowComment'
+  execute 'syn keyword' a:name
+        \ 'nextgroup=' . a:nextgroup . ',' . comment_group
+        \ 'skipwhite skipempty'
+        \ 'contained'
+        \ join(a:keywords)
+
+  call s:def_comment(comment_group, a:nextgroup)
+endfunction
+
+function s:def_keyword(name, nextgroup, keyword)
+  call s:def_keywords(a:name, a:nextgroup, [a:keyword])
+endfunction
+
+" NOTE: Pattern needs to escape any “@”s.
+function s:def_match(name, nextgroup, pattern)
+  let comment_group = a:name . 'FollowComment'
+  execute 'syn match' a:name
+        \ 'nextgroup=' . a:nextgroup . ',' . comment_group
+        \ 'skipwhite skipempty'
+        \ 'contained'
+        \ '@' . a:pattern . '@'
+
+  call s:def_comment(comment_group, a:nextgroup)
+endfunction
+
+function s:def_region(name, nextgroup, start, skip, end, matchgroup, contains)
+  let comment_group = a:name . 'FollowComment'
+  execute 'syn region' a:name
+        \ 'nextgroup=' . a:nextgroup . ',' . comment_group
+        \ 'skipwhite skipempty'
+        \ 'contained'
+        \ 'matchgroup=' . a:matchgroup
+        \ 'contains=' . a:contains
+        \ 'start=@' . a:start . '@'
+        \ (a:skip != "" ? ('skip=@' . a:skip . '@') : "")
+        \ 'end=@' . a:end . '@'
+
+  call s:def_comment(comment_group, a:nextgroup)
+endfunction
+
+call s:def_comment('cdrtocHeaderCommentInitial', '@cdrtocHeaderFollowsInitial')
+
+call s:def_keyword('cdrtocHeaderCatalog', 'cdrtocHeaderCatalogNumber', 'CATALOG')
+
+call s:def_match('cdrtocHeaderCatalogNumber', '@cdrtocHeaderFollowsInitial', '"\d\{13\}"')
+
+call s:def_keywords('cdrtocHeaderTOCType', '@cdrtocHeaderFollowsInitial', ['CD_DA', 'CD_ROM', 'CD_ROM_XA'])
+
+call s:def_keyword('cdrtocHeaderCDText', 'cdrtocHeaderCDTextStart', 'CD_TEXT')
+
+" TODO: Actually, language maps aren’t required by TocParser.g, but let’s keep
+" things simple (and in agreement with what the manual page says).
+call s:def_match('cdrtocHeaderCDTextStart', 'cdrtocHeaderCDTextLanguageMap', '{')
+
+call s:def_keyword('cdrtocHeaderCDTextLanguageMap', 'cdrtocHeaderLanguageMapStart', 'LANGUAGE_MAP')
+
+call s:def_match('cdrtocHeaderLanguageMapStart', 'cdrtocHeaderLanguageMapLanguageNumber', '{')
+
+call s:def_match('cdrtocHeaderLanguageMapLanguageNumber', 'cdrtocHeaderLanguageMapColon', '\<[0-7]\>')
+
+call s:def_match('cdrtocHeaderLanguageMapColon', 'cdrtocHeaderLanguageMapCountryCode,cdrtocHeaderLanguageMapCountryCodeName', ':')
+
+syn cluster cdrtocHeaderLanguageMapCountryCodeFollow
+      \ contains=
+      \   cdrtocHeaderLanguageMapLanguageNumber,
+      \   cdrtocHeaderLanguageMapEnd
+
+call s:def_match('cdrtocHeaderLanguageMapCountryCode',
+               \ '@cdrtocHeaderLanguageMapCountryCodeFollow',
+               \ s:byte_pattern)
+
+call s:def_keyword('cdrtocHeaderLanguageMapCountryCodeName',
+                 \ '@cdrtocHeaderLanguageMapCountryCodeFollow',
+                 \ 'EN')
+
+call s:def_match('cdrtocHeaderLanguageMapEnd',
+               \ 'cdrtocHeaderLanguage,cdrtocHeaderCDTextEnd',
+               \ '}')
+
+call s:def_keyword('cdrtocHeaderLanguage', 'cdrtocHeaderLanguageNumber', 'LANGUAGE')
+
+call s:def_match('cdrtocHeaderLanguageNumber', 'cdrtocHeaderLanguageStart', '\<[0-7]\>')
+
+call s:def_match('cdrtocHeaderLanguageStart',
+               \ 'cdrtocHeaderCDTextItem,cdrtocHeaderLanguageEnd',
+               \ '{')
+
+syn cluster cdrtocHeaderCDTextData
+      \ contains=
+      \   cdrtocHeaderCDTextDataString,
+      \   cdrtocHeaderCDTextDataBinaryStart
+
+call s:def_keywords('cdrtocHeaderCDTextItem',
+                  \ '@cdrtocHeaderCDTextData',
+                  \ ['TITLE', 'PERFORMER', 'SONGWRITER', 'COMPOSER',
+                  \  'ARRANGER', 'MESSAGE', 'DISC_ID', 'GENRE', 'TOC_INFO1',
+                  \  'TOC_INFO2', 'UPC_EAN', 'ISRC', 'SIZE_INFO'])
+
+call s:def_region('cdrtocHeaderCDTextDataString',
+                \ 'cdrtocHeaderCDTextItem,cdrtocHeaderLanguageEnd',
+                \ '"',
+                \ '\\\\\|\\"',
+                \ '"',
+                \ 'cdrtocHeaderCDTextDataStringDelimiters',
+                \ 'cdrtocHeaderCDTextDataStringSpecialChar')
+
+syn match   cdrtocHeaderCDTextDataStringSpecialChar
+      \ contained
+      \ display
+      \ '\\\%(\o\o\o\|["\\]\)'
+
+call s:def_match('cdrtocHeaderCDTextDataBinaryStart',
+               \ 'cdrtocHeaderCDTextDataBinaryInteger',
+               \ '{')
+
+call s:def_match('cdrtocHeaderCDTextDataBinaryInteger',
+               \ 'cdrtocHeaderCDTextDataBinarySeparator,cdrtocHeaderCDTextDataBinaryEnd',
+               \ s:byte_pattern)
+
+call s:def_match('cdrtocHeaderCDTextDataBinarySeparator',
+               \ 'cdrtocHeaderCDTextDataBinaryInteger',
+               \ ',')
+
+call s:def_match('cdrtocHeaderCDTextDataBinaryEnd',
+               \ 'cdrtocHeaderCDTextItem,cdrtocHeaderLanguageEnd',
+               \ '}')
+
+call s:def_match('cdrtocHeaderLanguageEnd',
+               \ 'cdrtocHeaderLanguage,cdrtocHeaderCDTextEnd',
+               \ '}')
+
+call s:def_match('cdrtocHeaderCDTextEnd',
+               \ 'cdrtocTrack',
+               \ '}')
+
+syn cluster cdrtocTrackFollow
+      \ contains=
+      \   @cdrtocTrackFlags,
+      \   cdrtocTrackCDText,
+      \   cdrtocTrackPregap,
+      \   @cdrtocTrackContents
+
+call s:def_keyword('cdrtocTrack', 'cdrtocTrackMode', 'TRACK')
+
+call s:def_keywords('cdrtocTrackMode',
+                  \ 'cdrtocTrackSubChannelMode,@cdrtocTrackFollow',
+                  \ ['AUDIO', 'MODE1', 'MODE1_RAW', 'MODE2', 'MODE2_FORM1',
+                  \  'MODE2_FORM2', 'MODE2_FORM_MIX', 'MODE2_RAW'])
+
+call s:def_keywords('cdrtocTrackSubChannelMode',
+                  \ '@cdrtocTrackFollow',
+                  \ ['RW', 'RW_RAW'])
+
+syn cluster cdrtocTrackFlags
+      \ contains=
+      \   cdrtocTrackFlagNo,
+      \   cdrtocTrackFlagCopy,
+      \   cdrtocTrackFlagPreEmphasis,
+      \   cdrtocTrackFlag
+
+call s:def_keyword('cdrtocTrackFlagNo',
+                 \ 'cdrtocTrackFlagCopy,cdrtocTrackFlagPreEmphasis',
+                 \ 'NO')
+
+call s:def_keyword('cdrtocTrackFlagCopy', '@cdrtocTrackFollow', 'COPY')
+
+call s:def_keyword('cdrtocTrackFlagPreEmphasis', '@cdrtocTrackFollow', 'PRE_EMPHASIS')
+
+call s:def_keywords('cdrtocTrackFlag',
+                  \ '@cdrtocTrackFollow',
+                  \ ['TWO_CHANNEL_AUDIO', 'FOUR_CHANNEL_AUDIO'])
+
+call s:def_keyword('cdrtocTrackFlag', 'cdrtocTrackISRC', 'ISRC')
+
+call s:def_match('cdrtocTrackISRC',
+               \ '@cdrtocTrackFollow',
+               \ '"[[:upper:][:digit:]]\{5}\d\{7}"')
+
+call s:def_keyword('cdrtocTrackCDText', 'cdrtocTrackCDTextStart', 'CD_TEXT')
+
+call s:def_match('cdrtocTrackCDTextStart', 'cdrtocTrackCDTextLanguage', '{')
+
+call s:def_keyword('cdrtocTrackCDTextLanguage', 'cdrtocTrackCDTextLanguageNumber', 'LANGUAGE')
+
+call s:def_match('cdrtocTrackCDTextLanguageNumber', 'cdrtocTrackCDTextLanguageStart', '\<[0-7]\>')
+
+call s:def_match('cdrtocTrackCDTextLanguageStart',
+               \ 'cdrtocTrackCDTextItem,cdrtocTrackCDTextLanguageEnd',
+               \ '{')
+
+syn cluster cdrtocTrackCDTextData
+      \ contains=
+      \   cdrtocTrackCDTextDataString,
+      \   cdrtocTrackCDTextDataBinaryStart
+
+call s:def_keywords('cdrtocTrackCDTextItem',
+                  \ '@cdrtocTrackCDTextData',
+                  \ ['TITLE', 'PERFORMER', 'SONGWRITER', 'COMPOSER', 'ARRANGER',
+                  \  'MESSAGE', 'ISRC'])
+
+call s:def_region('cdrtocTrackCDTextDataString',
+                \ 'cdrtocTrackCDTextItem,cdrtocTrackCDTextLanguageEnd',
+                \ '"',
+                \ '\\\\\|\\"',
+                \ '"',
+                \ 'cdrtocTrackCDTextDataStringDelimiters',
+                \ 'cdrtocTrackCDTextDataStringSpecialChar')
+
+syn match   cdrtocTrackCDTextDataStringSpecialChar
+      \ contained
+      \ display
+      \ '\\\%(\o\o\o\|["\\]\)'
+
+call s:def_match('cdrtocTrackCDTextDataBinaryStart',
+               \ 'cdrtocTrackCDTextDataBinaryInteger',
+               \ '{')
+
+call s:def_match('cdrtocTrackCDTextDataBinaryInteger',
+               \ 'cdrtocTrackCDTextDataBinarySeparator,cdrtocTrackCDTextDataBinaryEnd',
+               \ s:byte_pattern)
+
+call s:def_match('cdrtocTrackCDTextDataBinarySeparator',
+               \ 'cdrtocTrackCDTextDataBinaryInteger',
+               \ ',')
+
+call s:def_match('cdrtocTrackCDTextDataBinaryEnd',
+               \ 'cdrtocTrackCDTextItem,cdrtocTrackCDTextLanguageEnd',
+               \ '}')
+
+call s:def_match('cdrtocTrackCDTextLanguageEnd',
+               \ 'cdrtocTrackCDTextLanguage,cdrtocTrackCDTextEnd',
+               \ '}')
+
+call s:def_match('cdrtocTrackCDTextEnd',
+               \ 'cdrtocTrackPregap,@cdrtocTrackContents',
+               \ '}')
+
+call s:def_keyword('cdrtocTrackPregap', 'cdrtocTrackPregapMMSSFF', 'PREGAP')
+
+call s:def_match('cdrtocTrackPregapMMSSFF',
+               \ '@cdrtocTrackContents',
+               \ s:mmssff_pattern)
+
+syn cluster cdrtocTrackContents
+      \ contains=
+      \   cdrtocTrackSubTrack,
+      \   cdrtocTrackMarker
+
+syn cluster cdrtocTrackContentsFollow
+      \ contains=
+      \   @cdrtocTrackContents,
+      \   cdrtocTrackIndex,
+      \   cdrtocTrack
+
+call s:def_keywords('cdrtocTrackSubTrack',
+                  \ 'cdrtocTrackSubTrackFileFilename',
+                  \ ['FILE', 'AUDIOFILE'])
+
+call s:def_region('cdrtocTrackSubTrackFileFilename',
+                \ 'cdrtocTrackSubTrackFileStart',
+                \ '"',
+                \ '\\\\\|\\"',
+                \ '"',
+                \ 'cdrtocTrackSubTrackFileFilenameDelimiters',
+                \ 'cdrtocTrackSubTrackFileFilenameSpecialChar')
+
+syn match   cdrtocTrackSubTrackFileFilenameSpecialChar
+      \ contained
+      \ display
+      \ '\\\%(\o\o\o\|["\\]\)'
+
+call s:def_match('cdrtocTrackSubTrackFileStart',
+               \ 'cdrtocTrackSubTrackFileLength,@cdrtocTrackContentsFollow',
+               \ s:length_pattern)
+
+call s:def_match('cdrtocTrackSubTrackFileLength',
+               \ '@cdrtocTrackContentsFollow',
+               \ s:length_pattern)
+
+call s:def_keyword('cdrtocTrackSubTrack', 'cdrtocTrackContentDatafileFilename', 'DATAFILE')
+
+call s:def_region('cdrtocTrackSubTrackDatafileFilename',
+                \ 'cdrtocTrackSubTrackDatafileLength',
+                \ '"',
+                \ '\\\\\|\\"',
+                \ '"',
+                \ 'cdrtocTrackSubTrackDatafileFilenameDelimiters',
+                \ 'cdrtocTrackSubTrackDatafileFilenameSpecialChar')
+
+syn match   cdrtocTrackSubTrackdatafileFilenameSpecialChar
+      \ contained
+      \ display
+      \ '\\\%(\o\o\o\|["\\]\)'
+
+call s:def_match('cdrtocTrackDatafileLength',
+               \ '@cdrtocTrackContentsFollow',
+               \ s:length_pattern)
+
+call s:def_keyword('cdrtocTrackSubTrack', 'cdrtocTrackContentFifoFilename', 'DATAFILE')
+
+call s:def_region('cdrtocTrackSubTrackFifoFilename',
+                \ 'cdrtocTrackSubTrackFifoLength',
+                \ '"',
+                \ '\\\\\|\\"',
+                \ '"',
+                \ 'cdrtocTrackSubTrackFifoFilenameDelimiters',
+                \ 'cdrtocTrackSubTrackFifoFilenameSpecialChar')
+
+syn match   cdrtocTrackSubTrackdatafileFilenameSpecialChar
+      \ contained
+      \ display
+      \ '\\\%(\o\o\o\|["\\]\)'
+
+call s:def_match('cdrtocTrackFifoLength',
+               \ '@cdrtocTrackContentsFollow',
+               \ s:length_pattern)
+
+call s:def_keyword('cdrtocTrackSubTrack', 'cdrtocTrackSilenceLength', 'SILENCE')
+
+call s:def_match('cdrtocTrackSilenceLength',
+               \ '@cdrtocTrackContentsFollow',
+               \ s:length_pattern)
+
+call s:def_keyword('cdrtocTrackSubTrack',
+                 \ 'cdrtocTrackSubTrackZeroDataMode,' .
+                 \ 'cdrtocTrackSubTrackZeroDataSubChannelMode,' .
+                 \ 'cdrtocTrackSubTrackZeroDataLength',
+                 \ 'ZERO')
+
+call s:def_keywords('cdrtocTrackSubTrackZeroDataMode',
+                  \ 'cdrtocTrackSubTrackZeroSubChannelMode,cdrtocTrackSubTrackZeroDataLength',
+                  \ ['AUDIO', 'MODE1', 'MODE1_RAW', 'MODE2', 'MODE2_FORM1',
+                  \  'MODE2_FORM2', 'MODE2_FORM_MIX', 'MODE2_RAW'])
+
+call s:def_keywords('cdrtocTrackSubTrackZeroDataSubChannelMode',
+                  \ 'cdrtocTrackSubTrackZeroDataLength',
+                  \ ['RW', 'RW_RAW'])
+
+call s:def_match('cdrtocTrackSubTrackZeroDataLength',
+               \ '@cdrtocTrackContentsFollow',
+               \ s:length_pattern)
+
+call s:def_keyword('cdrtocTrackMarker',
+                 \ '@cdrtocTrackContentsFollow,cdrtocTrackMarkerStartMMSSFF',
+                 \ 'START')
+
+call s:def_match('cdrtocTrackMarkerStartMMSSFF',
+               \ '@cdrtocTrackContentsFollow',
+               \ s:mmssff_pattern)
+
+call s:def_keyword('cdrtocTrackMarker',
+                 \ '@cdrtocTrackContentsFollow,cdrtocTrackMarkerEndMMSSFF',
+                 \ 'END')
+
+call s:def_match('cdrtocTrackMarkerEndMMSSFF',
+               \ '@cdrtocTrackContentsFollow',
+               \ s:mmssff_pattern)
+
+call s:def_keyword('cdrtocTrackIndex', 'cdrtocTrackIndexMMSSFF', 'INDEX')
+
+call s:def_match('cdrtocTrackIndexMMSSFF',
+               \ 'cdrtocTrackIndex,cdrtocTrack',
+               \ s:mmssff_pattern)
+
+delfunction s:def_region
+delfunction s:def_match
+delfunction s:def_keyword
+delfunction s:def_keywords
+delfunction s:def_comment
+
+syn sync fromstart
+
+hi def link cdrtocKeyword                                  Keyword
+hi def link cdrtocHeaderKeyword                            cdrtocKeyword
+hi def link cdrtocHeaderCDText                             cdrtocHeaderKeyword
+hi def link cdrtocDelimiter                                Delimiter
+hi def link cdrtocCDTextDataBinaryEnd                      cdrtocDelimiter
+hi def link cdrtocHeaderCDTextDataBinaryEnd                cdrtocHeaderCDTextDataBinaryEnd
+hi def link cdrtocNumber                                   Number
+hi def link cdrtocCDTextDataBinaryInteger                  cdrtocNumber
+hi def link cdrtocHeaderCDTextDataBinaryInteger            cdrtocCDTextDataBinaryInteger
+hi def link cdrtocCDTextDataBinarySeparator                cdrtocDelimiter
+hi def link cdrtocHeaderCDTextDataBinarySeparator          cdrtocCDTextDataBinarySeparator
+hi def link cdrtocCDTextDataBinaryStart                    cdrtocDelimiter
+hi def link cdrtocHeaderCDTextDataBinaryStart              cdrtocCDTextDataBinaryStart
+hi def link cdrtocString                                   String
+hi def link cdrtocCDTextDataString                         cdrtocString
+hi def link cdrtocHeaderCDTextDataString                   cdrtocCDTextDataString
+hi def link cdrtocCDTextDataStringDelimiters               cdrtocDelimiter
+hi def link cdrtocHeaderCDTextDataStringDelimiters         cdrtocCDTextDataStringDelimiters
+hi def link cdrtocCDTextDataStringSpecialChar              SpecialChar
+hi def link cdrtocHeaderCDTextDataStringSpecialChar        cdrtocCDTextDataStringSpecialChar
+hi def link cdrtocCDTextEnd                                cdrtocDelimiter
+hi def link cdrtocHeaderCDTextEnd                          cdrtocCDTextEnd
+hi def link cdrtocType                                     Type
+hi def link cdrtocCDTextItem                               cdrtocType
+hi def link cdrtocHeaderCDTextItem                         cdrtocCDTextItem
+hi def link cdrtocHeaderCDTextLanguageMap                  cdrtocHeaderKeyword
+hi def link cdrtocCDTextStart                              cdrtocDelimiter
+hi def link cdrtocHeaderCDTextStart                        cdrtocCDTextStart
+hi def link cdrtocHeaderCatalog                            cdrtocHeaderKeyword
+hi def link cdrtocHeaderCatalogNumber                      cdrtocString
+hi def link cdrtocComment                                  Comment
+hi def link cdrtocHeaderCommentInitial                     cdrtocComment
+hi def link cdrtocHeaderLanguage                           cdrtocKeyword
+hi def link cdrtocLanguageEnd                              cdrtocDelimiter
+hi def link cdrtocHeaderLanguageEnd                        cdrtocLanguageEnd
+hi def link cdrtocHeaderLanguageMapColon                   cdrtocDelimiter
+hi def link cdrtocIdentifier                               Identifier
+hi def link cdrtocHeaderLanguageMapCountryCode             cdrtocNumber
+hi def link cdrtocHeaderLanguageMapCountryCodeName         cdrtocIdentifier
+hi def link cdrtocHeaderLanguageMapEnd                     cdrtocDelimiter
+hi def link cdrtocHeaderLanguageMapLanguageNumber          cdrtocNumber
+hi def link cdrtocHeaderLanguageMapStart                   cdrtocDelimiter
+hi def link cdrtocLanguageNumber                           cdrtocNumber
+hi def link cdrtocHeaderLanguageNumber                     cdrtocLanguageNumber
+hi def link cdrtocLanguageStart                            cdrtocDelimiter
+hi def link cdrtocHeaderLanguageStart                      cdrtocLanguageStart
+hi def link cdrtocHeaderTOCType                            cdrtocType
+hi def link cdrtocTodo                                     Todo
+hi def link cdrtocTrackKeyword                             cdrtocKeyword
+hi def link cdrtocTrack                                    cdrtocTrackKeyword
+hi def link cdrtocTrackCDText                              cdrtocTrackKeyword
+hi def link cdrtocTrackCDTextDataBinaryEnd                 cdrtocHeaderCDTextDataBinaryEnd
+hi def link cdrtocTrackCDTextDataBinaryInteger             cdrtocHeaderCDTextDataBinaryInteger
+hi def link cdrtocTrackCDTextDataBinarySeparator           cdrtocHeaderCDTextDataBinarySeparator
+hi def link cdrtocTrackCDTextDataBinaryStart               cdrtocHeaderCDTextDataBinaryStart
+hi def link cdrtocTrackCDTextDataString                    cdrtocHeaderCDTextDataString
+hi def link cdrtocTrackCDTextDataStringDelimiters          cdrtocCDTextDataStringDelimiters
+hi def link cdrtocTrackCDTextDataStringSpecialChar         cdrtocCDTextDataStringSpecialChar
+hi def link cdrtocTrackCDTextEnd                           cdrtocCDTextEnd
+hi def link cdrtocTrackCDTextItem                          cdrtocCDTextItem
+hi def link cdrtocTrackCDTextStart                         cdrtocCDTextStart
+hi def link cdrtocLength                                   cdrtocNumber
+hi def link cdrtocTrackDatafileLength                      cdrtocLength
+hi def link cdrtocTrackFifoLength                          cdrtocLength
+hi def link cdrtocPreProc                                  PreProc
+hi def link cdrtocTrackFlag                                cdrtocPreProc
+hi def link cdrtocTrackFlagCopy                            cdrtocTrackFlag
+hi def link cdrtocSpecial                                  Special
+hi def link cdrtocTrackFlagNo                              cdrtocSpecial
+hi def link cdrtocTrackFlagPreEmphasis                     cdrtocTrackFlag
+hi def link cdrtocTrackISRC                                cdrtocTrackFlag
+hi def link cdrtocTrackIndex                               cdrtocTrackKeyword
+hi def link cdrtocMMSSFF                                   cdrtocLength
+hi def link cdrtocTrackIndexMMSSFF                         cdrtocMMSSFF
+hi def link cdrtocTrackCDTextLanguage                      cdrtocTrackKeyword
+hi def link cdrtocTrackCDTextLanguageEnd                   cdrtocLanguageEnd
+hi def link cdrtocTrackCDTextLanguageNumber                cdrtocLanguageNumber
+hi def link cdrtocTrackCDTextLanguageStart                 cdrtocLanguageStart
+hi def link cdrtocTrackContents                            StorageClass
+hi def link cdrtocTrackMarker                              cdrtocTrackContents
+hi def link cdrtocTrackMarkerEndMMSSFF                     cdrtocMMSSFF
+hi def link cdrtocTrackMarkerStartMMSSFF                   cdrtocMMSSFF
+hi def link cdrtocTrackMode                                Type
+hi def link cdrtocTrackPregap                              cdrtocTrackContents
+hi def link cdrtocTrackPregapMMSSFF                        cdrtocMMSSFF
+hi def link cdrtocTrackSilenceLength                       cdrtocLength
+hi def link cdrtocTrackSubChannelMode                      cdrtocPreProc
+hi def link cdrtocTrackSubTrack                            cdrtocTrackContents
+hi def link cdrtocFilename                                 cdrtocString
+hi def link cdrtocTrackSubTrackDatafileFilename            cdrtocFilename
+hi def link cdrtocTrackSubTrackDatafileFilenameDelimiters  cdrtocTrackSubTrackDatafileFilename
+hi def link cdrtocSpecialChar                              SpecialChar
+hi def link cdrtocTrackSubTrackDatafileFilenameSpecialChar cdrtocSpecialChar
+hi def link cdrtocTrackSubTrackDatafileLength              cdrtocLength
+hi def link cdrtocTrackSubTrackFifoFilename                cdrtocFilename
+hi def link cdrtocTrackSubTrackFifoFilenameDelimiters      cdrtocTrackSubTrackFifoFilename
+hi def link cdrtocTrackSubTrackFifoFilenameSpecialChar     cdrtocSpecialChar
+hi def link cdrtocTrackSubTrackFifoLength                  cdrtocLength
+hi def link cdrtocTrackSubTrackFileFilename                cdrtocFilename
+hi def link cdrtocTrackSubTrackFileFilenameDelimiters      cdrtocTrackSubTrackFileFilename
+hi def link cdrtocTrackSubTrackFileFilenameSpecialChar     cdrtocSpecialChar
+hi def link cdrtocTrackSubTrackFileLength                  cdrtocLength
+hi def link cdrtocTrackSubTrackFileStart                   cdrtocLength
+hi def link cdrtocTrackSubTrackZeroDataLength              cdrtocLength
+hi def link cdrtocTrackSubTrackZeroDataMode                Type
+hi def link cdrtocTrackSubTrackZeroDataSubChannelMode      cdrtocPreProc
+hi def link cdrtocTrackSubTrackdatafileFilenameSpecialChar cdrtocSpecialChar
+
+let b:current_syntax = "cdrtoc"
+
+let &cpo = s:cpo_save
+unlet s:cpo_save
--- /dev/null
+++ b/lib/vimfiles/syntax/cf.vim
@@ -1,0 +1,251 @@
+" Vim syntax file
+"    Language: ColdFusion
+"  Maintainer: Toby Woodwark (toby.woodwark+vim@gmail.com)
+" Last Change: 2005 Nov 25
+"   Filenames: *.cfc *.cfm
+"     Version: Macromedia ColdFusion MX 7
+"       Usage: Note that ColdFusion has its own comment syntax
+"              i.e. <!--- --->
+
+" For version 5.x, clear all syntax items.
+" For version 6.x+, quit if a syntax file is already loaded.
+if version < 600
+  syntax clear
+elseif exists("b:current_syntax")
+  finish
+endif
+
+" Use all the stuff from the HTML syntax file.
+" TODO remove this; CFML is not a superset of HTML
+if version < 600
+  source <sfile>:p:h/html.vim
+else
+  runtime! syntax/html.vim
+endif
+
+syn sync fromstart
+syn sync maxlines=200
+syn case ignore
+
+" Scopes and keywords.
+syn keyword cfScope contained cgi cffile request caller this thistag cfcatch variables application server session client form url attributes arguments
+syn keyword cfBool contained yes no true false
+
+" Operator strings.
+" Not exhaustive, since there are longhand equivalents.
+syn keyword cfOperator contained xor eqv and or lt le lte gt ge gte eq neq not is mod contains
+syn match cfOperatorMatch contained "[\+\-\*\/\\\^\&][\+\-\*\/\\\^\&]\@!"
+syn cluster cfOperatorCluster contains=cfOperator,cfOperatorMatch
+
+" Tag names.
+syn keyword cfTagName contained cfabort cfapplet cfapplication cfargument cfassociate cfbreak cfcache
+syn keyword cfTagName contained cfcalendar cfcase cfcatch cfchart cfchartdata cfchartseries cfcol cfcollection
+syn keyword cfTagName contained cfcomponent cfcontent cfcookie cfdefaultcase cfdirectory cfdocument
+syn keyword cfTagName contained cfdocumentitem cfdocumentsection cfdump cfelse cfelseif cferror cfexecute
+syn keyword cfTagName contained cfexit cffile cfflush cfform cfformgroup cfformitem cfftp cffunction cfgrid
+syn keyword cfTagName contained cfgridcolumn cfgridrow cfgridupdate cfheader cfhtmlhead cfhttp cfhttpparam cfif
+syn keyword cfTagName contained cfimport cfinclude cfindex cfinput cfinsert cfinvoke cfinvokeargument
+syn keyword cfTagName contained cfldap cflocation cflock cflog cflogin cfloginuser cflogout cfloop cfmail
+syn keyword cfTagName contained cfmailparam cfmailpart cfmodule cfNTauthenticate cfobject cfobjectcache
+syn keyword cfTagName contained cfoutput cfparam cfpop cfprocessingdirective cfprocparam cfprocresult
+syn keyword cfTagName contained cfproperty cfquery cfqueryparam cfregistry cfreport cfreportparam cfrethrow
+syn keyword cfTagName contained cfreturn cfsavecontent cfschedule cfscript cfsearch cfselect cfset cfsetting
+syn keyword cfTagName contained cfsilent cfslider cfstoredproc cfswitch cftable cftextarea cfthrow cftimer
+syn keyword cfTagName contained cftrace cftransaction cftree cftreeitem cftry cfupdate cfwddx cfxml 
+
+" Tag parameters.
+syn keyword cfArg contained abort accept access accessible action addnewline addtoken addtoken agentname
+syn keyword cfArg contained align appendkey appletsource application applicationtimeout applicationtoken
+syn keyword cfArg contained archive argumentcollection arguments asciiextensionlist attachmentpath
+syn keyword cfArg contained attributecollection attributes attributes autowidth backgroundcolor
+syn keyword cfArg contained backgroundvisible basetag bcc bgcolor bind bindingname blockfactor body bold
+syn keyword cfArg contained border branch cachedafter cachedwithin casesensitive categories category
+syn keyword cfArg contained categorytree cc cfsqltype charset chartheight chartwidth checked class
+syn keyword cfArg contained clientmanagement clientstorage codebase colheaderalign colheaderbold
+syn keyword cfArg contained colheaderfont colheaderfontsize colheaderitalic colheaders colheadertextcolor
+syn keyword cfArg contained collection colorlist colspacing columns completepath component condition
+syn keyword cfArg contained connection contentid context contextbytes contexthighlightbegin
+syn keyword cfArg contained contexthighlightend contextpassages cookiedomain criteria custom1 custom2
+syn keyword cfArg contained custom3 custom4 data dataalign databackgroundcolor datacollection
+syn keyword cfArg contained datalabelstyle datasource date daynames dbname dbserver dbtype dbvarname debug
+syn keyword cfArg contained default delete deletebutton deletefile delimiter delimiters description
+syn keyword cfArg contained destination detail directory disabled display displayname disposition dn domain
+syn keyword cfArg contained enablecab enablecfoutputonly enabled encoded encryption enctype enddate
+syn keyword cfArg contained endrange endrow endtime entry errorcode exception existing expand expires
+syn keyword cfArg contained expireurl expression extendedinfo extends extensions external failifexists
+syn keyword cfArg contained failto file filefield filename filter firstdayofweek firstrowasheaders font
+syn keyword cfArg contained fontbold fontembed fontitalic fontsize foregroundcolor format formfields
+syn keyword cfArg contained formula from generateuniquefilenames getasbinary grid griddataalign gridlines
+syn keyword cfArg contained groovecolor group groupcasesensitive header headeralign headerbold headerfont
+syn keyword cfArg contained headerfontsize headeritalic headerlines headertextcolor height highlighthref
+syn keyword cfArg contained hint href hrefkey hscroll hspace htmltable id idletimeout img imgopen imgstyle
+syn keyword cfArg contained index inline input insert insertbutton interval isolation italic item
+syn keyword cfArg contained itemcolumn key keyonly label labelformat language list listgroups locale
+syn keyword cfArg contained localfile log loginstorage lookandfeel mailerid mailto marginbottom marginleft
+syn keyword cfArg contained marginright marginright margintop markersize markerstyle mask maxlength maxrows
+syn keyword cfArg contained message messagenumber method mimeattach mimetype mode modifytype monthnames
+syn keyword cfArg contained multipart multiple name namecomplict nameconflict namespace new newdirectory
+syn keyword cfArg contained notsupported null numberformat object omit onchange onclick onerror onkeydown
+syn keyword cfArg contained onkeyup onload onmousedown onmouseup onreset onsubmit onvalidate operation
+syn keyword cfArg contained orderby orientation output outputfile overwrite ownerpassword pageencoding
+syn keyword cfArg contained pageheight pagetype pagewidth paintstyle param_1 param_2 param_3 param_4
+syn keyword cfArg contained param_5 parent passive passthrough password path pattern permissions picturebar
+syn keyword cfArg contained pieslicestyle port porttypename prefix preloader preservedata previouscriteria
+syn keyword cfArg contained procedure protocol provider providerdsn proxybypass proxypassword proxyport
+syn keyword cfArg contained proxyserver proxyuser publish query queryasroot queryposition range rebind
+syn keyword cfArg contained recurse redirect referral refreshlabel remotefile replyto report requesttimeout
+syn keyword cfArg contained required reset resolveurl result resultset retrycount returnasbinary returncode
+syn keyword cfArg contained returntype returnvariable roles rowheaderalign rowheaderbold rowheaderfont
+syn keyword cfArg contained rowheaderfontsize rowheaderitalic rowheaders rowheadertextcolor rowheaderwidth
+syn keyword cfArg contained rowheight scale scalefrom scaleto scope scriptprotect scriptsrc secure
+syn keyword cfArg contained securitycontext select selectcolor selected selecteddate selectedindex
+syn keyword cfArg contained selectmode separator seriescolor serieslabel seriesplacement server serviceport
+syn keyword cfArg contained serviceportname sessionmanagement sessiontimeout setclientcookies setcookie
+syn keyword cfArg contained setdomaincookies show3d showborder showdebugoutput showerror showlegend
+syn keyword cfArg contained showmarkers showxgridlines showygridlines size skin sort sortascendingbutton
+syn keyword cfArg contained sortcontrol sortdescendingbutton sortxaxis source spoolenable sql src start
+syn keyword cfArg contained startdate startrange startrow starttime status statuscode statustext step
+syn keyword cfArg contained stoponerror style subject suggestions suppresswhitespace tablename tableowner
+syn keyword cfArg contained tablequalifier taglib target task template text textcolor textqualifier
+syn keyword cfArg contained thread throwonerror throwonfailure throwontimeout time timeout timespan tipbgcolor tipstyle
+syn keyword cfArg contained title to tooltip top toplevelvariable transfermode type uid unit url urlpath
+syn keyword cfArg contained useragent username userpassword usetimezoneinfo validate validateat value
+syn keyword cfArg contained valuecolumn values valuesdelimiter valuesdisplay var variable vertical visible
+syn keyword cfArg contained vscroll vspace webservice width wmode wraptext wsdlfile xaxistitle xaxistype
+syn keyword cfArg contained xoffset yaxistitle yaxistype yoffset
+
+" ColdFusion Functions.
+syn keyword cfFunctionName contained Abs GetFunctionList Max ACos GetGatewayHelper Mid AddSOAPRequestHeader
+syn keyword cfFunctionName contained GetHttpRequestData Min AddSOAPResponseHeader GetHttpTimeString Minute
+syn keyword cfFunctionName contained ArrayAppend GetLocale Month ArrayAvg GetLocaleDisplayName MonthAsString
+syn keyword cfFunctionName contained ArrayClear GetMetaData Now ArrayDeleteAt GetMetricData NumberFormat
+syn keyword cfFunctionName contained ArrayInsertAt GetPageContext ParagraphFormat ArrayIsEmpty GetProfileSections
+syn keyword cfFunctionName contained ParseDateTime ArrayLen GetProfileString Pi ArrayMax GetSOAPRequest
+syn keyword cfFunctionName contained PreserveSingleQuotes ArrayMin GetSOAPRequestHeader Quarter ArrayNew
+syn keyword cfFunctionName contained GetSOAPResponse QueryAddColumn ArrayPrepend GetSOAPResponseHeader QueryAddRow
+syn keyword cfFunctionName contained ArrayResize GetTempDirectory QueryNew ArraySet GetTempFile QuerySetCell
+syn keyword cfFunctionName contained ArraySort GetTickCount QuotedValueList ArraySum GetTimeZoneInfo Rand ArraySwap
+syn keyword cfFunctionName contained GetToken Randomize ArrayToList Hash RandRange Asc Hour REFind ASin
+syn keyword cfFunctionName contained HTMLCodeFormat REFindNoCase Atn HTMLEditFormat ReleaseComObject BinaryDecode
+syn keyword cfFunctionName contained IIf RemoveChars BinaryEncode IncrementValue RepeatString BitAnd InputBaseN
+syn keyword cfFunctionName contained Replace BitMaskClear Insert ReplaceList BitMaskRead Int ReplaceNoCase
+syn keyword cfFunctionName contained BitMaskSet IsArray REReplace BitNot IsBinary REReplaceNoCase BitOr IsBoolean
+syn keyword cfFunctionName contained Reverse BitSHLN IsCustomFunction Right BitSHRN IsDate RJustify BitXor
+syn keyword cfFunctionName contained IsDebugMode Round Ceiling IsDefined RTrim CharsetDecode IsLeapYear Second
+syn keyword cfFunctionName contained CharsetEncode IsNumeric SendGatewayMessage Chr IsNumericDate SetEncoding
+syn keyword cfFunctionName contained CJustify IsObject SetLocale Compare IsQuery SetProfileString CompareNoCase
+syn keyword cfFunctionName contained IsSimpleValue SetVariable Cos IsSOAPRequest Sgn CreateDate IsStruct Sin
+syn keyword cfFunctionName contained CreateDateTime IsUserInRole SpanExcluding CreateObject IsValid SpanIncluding
+syn keyword cfFunctionName contained CreateODBCDate IsWDDX Sqr CreateODBCDateTime IsXML StripCR CreateODBCTime
+syn keyword cfFunctionName contained IsXmlAttribute StructAppend CreateTime IsXmlDoc StructClear CreateTimeSpan
+syn keyword cfFunctionName contained IsXmlElem StructCopy CreateUUID IsXmlNode StructCount DateAdd IsXmlRoot
+syn keyword cfFunctionName contained StructDelete DateCompare JavaCast StructFind DateConvert JSStringFormat
+syn keyword cfFunctionName contained StructFindKey DateDiff LCase StructFindValue DateFormat Left StructGet
+syn keyword cfFunctionName contained DatePart Len StructInsert Day ListAppend StructIsEmpty DayOfWeek
+syn keyword cfFunctionName contained ListChangeDelims StructKeyArray DayOfWeekAsString ListContains StructKeyExists
+syn keyword cfFunctionName contained DayOfYear ListContainsNoCase StructKeyList DaysInMonth ListDeleteAt StructNew
+syn keyword cfFunctionName contained DaysInYear ListFind StructSort DE ListFindNoCase StructUpdate DecimalFormat
+syn keyword cfFunctionName contained ListFirst Tan DecrementValue ListGetAt TimeFormat Decrypt ListInsertAt
+syn keyword cfFunctionName contained ToBase64 DeleteClientVariable ListLast ToBinary DirectoryExists ListLen
+syn keyword cfFunctionName contained ToScript DollarFormat ListPrepend ToString Duplicate ListQualify Trim Encrypt
+syn keyword cfFunctionName contained ListRest UCase Evaluate ListSetAt URLDecode Exp ListSort URLEncodedFormat
+syn keyword cfFunctionName contained ExpandPath ListToArray URLSessionFormat FileExists ListValueCount Val Find
+syn keyword cfFunctionName contained ListValueCountNoCase ValueList FindNoCase LJustify Week FindOneOf Log Wrap
+syn keyword cfFunctionName contained FirstDayOfMonth Log10 WriteOutput Fix LSCurrencyFormat XmlChildPos FormatBaseN
+syn keyword cfFunctionName contained LSDateFormat XmlElemNew GetTempDirectory LSEuroCurrencyFormat XmlFormat
+syn keyword cfFunctionName contained GetAuthUser LSIsCurrency XmlGetNodeType GetBaseTagData LSIsDate XmlNew
+syn keyword cfFunctionName contained GetBaseTagList LSIsNumeric XmlParse GetBaseTemplatePath LSNumberFormat
+syn keyword cfFunctionName contained XmlSearch GetClientVariablesList LSParseCurrency XmlTransform
+syn keyword cfFunctionName contained GetCurrentTemplatePath LSParseDateTime XmlValidate GetDirectoryFromPath
+syn keyword cfFunctionName contained LSParseEuroCurrency Year GetEncoding LSParseNumber YesNoFormat GetException
+syn keyword cfFunctionName contained LSTimeFormat GetFileFromPath LTrim 
+
+syn cluster htmlTagNameCluster add=cfTagName
+syn cluster htmlArgCluster add=cfArg,cfHashRegion,cfScope
+syn cluster htmlPreproc add=cfHashRegion
+
+syn cluster cfExpressionCluster contains=cfFunctionName,cfScope,@cfOperatorCluster,cfScriptStringD,cfScriptStringS,cfScriptNumber,cfBool
+
+" Evaluation; skip strings ( this helps with cases like nested IIf() )
+syn region cfHashRegion start=+#+ skip=+"[^"]*"\|'[^']*'+ end=+#+ contains=@cfExpressionCluster,cfScriptParenError
+
+" <cfset>, <cfif>, <cfelseif>, <cfreturn> are analogous to hashmarks (implicit evaluation) and has 'var'
+syn region cfSetRegion start="<cfset " start="<cfreturn " start="<cfelseif " start="<cfif " end='>' keepend contains=@cfExpressionCluster,cfSetLHSRegion,cfSetTagEnd,cfScriptType
+syn region cfSetLHSRegion contained start="<cfreturn" start="<cfelseif" start="<cfif" start="<cfset" end=" " keepend contains=cfTagName,htmlTag
+syn match  cfSetTagEnd contained '>'
+
+" CF comments: similar to SGML comments
+syn region  cfComment     start='<!---' end='--->' keepend contains=cfCommentTodo
+syn keyword cfCommentTodo contained TODO FIXME XXX TBD WTF 
+
+" CFscript 
+syn match   cfScriptLineComment      contained "\/\/.*$" contains=cfCommentTodo
+syn region  cfScriptComment	     contained start="/\*"  end="\*/" contains=cfCommentTodo
+" in CF, quotes are escaped by doubling
+syn region  cfScriptStringD	     contained start=+"+  skip=+\\\\\|""+  end=+"+  extend contains=@htmlPreproc,cfHashRegion
+syn region  cfScriptStringS	     contained start=+'+  skip=+\\\\\|''+  end=+'+  extend contains=@htmlPreproc,cfHashRegion
+syn match   cfScriptNumber	     contained "-\=\<\d\+L\=\>"
+syn keyword cfScriptConditional      contained if else
+syn keyword cfScriptRepeat	     contained while for in
+syn keyword cfScriptBranch	     contained break switch case try catch continue
+syn keyword cfScriptFunction	     contained function
+syn keyword cfScriptType	     contained var
+syn match   cfScriptBraces	     contained "[{}]"
+syn keyword cfScriptStatement        contained return
+
+syn cluster cfScriptCluster contains=cfScriptParen,cfScriptLineComment,cfScriptComment,cfScriptStringD,cfScriptStringS,cfScriptFunction,cfScriptNumber,cfScriptRegexpString,cfScriptBoolean,cfScriptBraces,cfHashRegion,cfFunctionName,cfScope,@cfOperatorCluster,cfScriptConditional,cfScriptRepeat,cfScriptBranch,cfScriptType,@cfExpressionCluster,cfScriptStatement
+
+" Errors caused by wrong parenthesis; skip strings
+syn region  cfScriptParen       contained transparent skip=+"[^"]*"\|'[^']*'+ start=+(+ end=+)+ contains=@cfScriptCluster
+syn match   cfScrParenError 	contained +)+
+
+syn region cfscriptBlock matchgroup=NONE start="<cfscript>"  end="<\/cfscript>"me=s-1 keepend contains=@cfScriptCluster,cfscriptTag,cfScrParenError
+syn region  cfscriptTag contained start='<cfscript' end='>' keepend contains=cfTagName,htmlTag
+
+" Define the default highlighting.
+if version >= 508 || !exists("did_cf_syn_inits")
+  if version < 508
+    let did_cf_syn_inits = 1
+    command -nargs=+ HiLink hi link <args>
+  else
+    command -nargs=+ HiLink hi def link <args>
+  endif
+
+  HiLink cfTagName 		Statement
+  HiLink cfArg 			Type
+  HiLink cfFunctionName 	Function
+  HiLink cfHashRegion 		PreProc
+  HiLink cfComment 		Comment
+  HiLink cfCommentTodo 		Todo
+  HiLink cfOperator		Operator
+  HiLink cfOperatorMatch	Operator
+  HiLink cfScope		Title
+  HiLink cfBool			Constant
+
+  HiLink cfscriptBlock 		Special
+  HiLink cfscriptTag 		htmlTag
+  HiLink cfSetRegion 		PreProc
+  HiLink cfSetLHSRegion 	htmlTag
+  HiLink cfSetTagEnd		htmlTag
+
+  HiLink cfScriptLineComment	Comment
+  HiLink cfScriptComment	Comment
+  HiLink cfScriptStringS	String
+  HiLink cfScriptStringD	String
+  HiLink cfScriptNumber	     	cfScriptValue
+  HiLink cfScriptConditional	Conditional
+  HiLink cfScriptRepeat	     	Repeat
+  HiLink cfScriptBranch	     	Conditional
+  HiLink cfScriptType		Type
+  HiLink cfScriptStatement	Statement
+  HiLink cfScriptBraces	     	Function
+  HiLink cfScriptFunction    	Function
+  HiLink cfScriptError	     	Error
+  HiLink cfScrParenError	cfScriptError
+
+  delcommand HiLink
+endif
+
+let b:current_syntax = "cf"
+
+" vim: ts=8 sw=2
--- /dev/null
+++ b/lib/vimfiles/syntax/cfg.vim
@@ -1,0 +1,60 @@
+" Vim syntax file
+" Language:	Good old CFG files
+" Maintainer:	Igor N. Prischepoff (igor@tyumbit.ru, pri_igor@mail.ru)
+" Last change:	2001 Sep 02
+
+" For version 5.x: Clear all syntax items
+" For version 6.x: Quit when a syntax file was already loaded
+if version < 600
+    syntax clear
+elseif exists ("b:current_syntax")
+    finish
+endif
+
+" case off
+syn case ignore
+syn keyword CfgOnOff  ON OFF YES NO TRUE FALSE  contained
+syn match UncPath "\\\\\p*" contained
+"Dos Drive:\Path
+syn match CfgDirectory "[a-zA-Z]:\\\p*" contained
+"Parameters
+syn match   CfgParams    ".*="me=e-1 contains=CfgComment
+"... and their values (don't want to highlight '=' sign)
+syn match   CfgValues    "=.*"hs=s+1 contains=CfgDirectory,UncPath,CfgComment,CfgString,CfgOnOff
+
+" Sections
+syn match CfgSection	    "\[.*\]"
+syn match CfgSection	    "{.*}"
+
+" String
+syn match  CfgString	"\".*\"" contained
+syn match  CfgString    "'.*'"   contained
+
+" Comments (Everything before '#' or '//' or ';')
+syn match  CfgComment	"#.*"
+syn match  CfgComment	";.*"
+syn match  CfgComment	"\/\/.*"
+
+" Define the default hightlighting.
+" For version 5.7 and earlier: only when not done already
+" For version 5.8 and later: only when an item doesn't have highlighting yet
+if version >= 508 || !exists("did_cfg_syn_inits")
+    if version < 508
+	let did_cfg_syn_inits = 1
+	command -nargs=+ HiLink hi link <args>
+    else
+	command -nargs=+ HiLink hi def link <args>
+    endif
+    HiLink CfgOnOff     Label
+    HiLink CfgComment	Comment
+    HiLink CfgSection	Type
+    HiLink CfgString	String
+    HiLink CfgParams    Keyword
+    HiLink CfgValues    Constant
+    HiLink CfgDirectory Directory
+    HiLink UncPath      Directory
+
+    delcommand HiLink
+endif
+let b:current_syntax = "cfg"
+" vim:ts=8
--- /dev/null
+++ b/lib/vimfiles/syntax/ch.vim
@@ -1,0 +1,53 @@
+" Vim syntax file
+" Language:     Ch
+" Maintainer:   SoftIntegration, Inc. <info@softintegration.com>
+" URL:		http://www.softintegration.com/download/vim/syntax/ch.vim
+" Last change:	2004 Sep 01
+"		Created based on cpp.vim
+"
+" Ch is a C/C++ interpreter with many high level extensions
+"
+
+" For version 5.x: Clear all syntax items
+" For version 6.x: Quit when a syntax file was already loaded
+if version < 600
+  syntax clear
+elseif exists("b:current_syntax")
+  finish
+endif
+
+" Read the C syntax to start with
+if version < 600
+  so <sfile>:p:h/c.vim
+else
+  runtime! syntax/c.vim
+  unlet b:current_syntax
+endif
+
+" Ch extentions
+
+syn keyword	chStatement	new delete this foreach
+syn keyword	chAccess	public private
+syn keyword	chStorageClass	__declspec(global) __declspec(local)
+syn keyword	chStructure	class
+syn keyword	chType		string_t array
+
+" Default highlighting
+if version >= 508 || !exists("did_ch_syntax_inits")
+  if version < 508
+    let did_ch_syntax_inits = 1
+    command -nargs=+ HiLink hi link <args>
+  else
+    command -nargs=+ HiLink hi def link <args>
+  endif
+  HiLink chAccess		chStatement
+  HiLink chExceptions		Exception
+  HiLink chStatement		Statement
+  HiLink chType			Type
+  HiLink chStructure		Structure
+  delcommand HiLink
+endif
+
+let b:current_syntax = "ch"
+
+" vim: ts=8
--- /dev/null
+++ b/lib/vimfiles/syntax/change.vim
@@ -1,0 +1,42 @@
+" Vim syntax file
+" Language:	WEB Changes
+" Maintainer:	Andreas Scherer <andreas.scherer@pobox.com>
+" Last Change:	April 25, 2001
+
+" Details of the change mechanism of the WEB and CWEB languages can be found
+" in the articles by Donald E. Knuth and Silvio Levy cited in "web.vim" and
+" "cweb.vim" respectively.
+
+" For version 5.x: Clear all syntax items
+" For version 6.x: Quit when a syntax file was already loaded
+if version < 600
+  syn clear
+elseif exists("b:current_syntax")
+  finish
+endif
+
+" We distinguish two groups of material, (a) stuff between @x..@y, and
+" (b) stuff between @y..@z. WEB/CWEB ignore everything else in a change file.
+syn region changeFromMaterial start="^@x.*$"ms=e+1 end="^@y.*$"me=s-1
+syn region changeToMaterial start="^@y.*$"ms=e+1 end="^@z.*$"me=s-1
+
+" Define the default highlighting.
+" For version 5.7 and earlier: only when not done already
+" For version 5.8 and later: only when an item doesn't have highlighting yet
+if version >= 508 || !exists("did_change_syntax_inits")
+  if version < 508
+    let did_change_syntax_inits = 1
+    command -nargs=+ HiLink hi link <args>
+  else
+    command -nargs=+ HiLink hi def link <args>
+  endif
+
+  HiLink changeFromMaterial String
+  HiLink changeToMaterial Statement
+
+  delcommand HiLink
+endif
+
+let b:current_syntax = "change"
+
+" vim: ts=8
--- /dev/null
+++ b/lib/vimfiles/syntax/changelog.vim
@@ -1,0 +1,78 @@
+" Vim syntax file
+" Language:	generic ChangeLog file
+" Written By:	Gediminas Paulauskas <menesis@delfi.lt>
+" Maintainer:	Corinna Vinschen <vinschen@redhat.com>
+" Last Change:	June 1, 2003
+
+" For version 5.x: Clear all syntax items
+" For version 6.x: Quit when a syntax file was already loaded
+if version < 600
+  syntax clear
+elseif exists("b:current_syntax")
+  finish
+endif
+
+syn case ignore
+
+if exists('b:changelog_spacing_errors')
+  let s:spacing_errors = b:changelog_spacing_errors
+elseif exists('g:changelog_spacing_errors')
+  let s:spacing_errors = g:changelog_spacing_errors
+else
+  let s:spacing_errors = 1
+endif
+
+if s:spacing_errors
+  syn match	changelogError "^ \+"
+endif
+
+syn match	changelogText	"^\s.*$" contains=changelogMail,changelogNumber,changelogMonth,changelogDay,changelogError
+syn match	changelogHeader	"^\S.*$" contains=changelogNumber,changelogMonth,changelogDay,changelogMail
+if version < 600
+  syn region	changelogFiles	start="^\s\+[+*]\s" end=":\s" end="^$" contains=changelogBullet,changelogColon,changelogError keepend
+  syn region	changelogFiles	start="^\s\+[([]" end=":\s" end="^$" contains=changelogBullet,changelogColon,changelogError keepend
+  syn match	changelogColon	contained ":\s"
+else
+  syn region	changelogFiles	start="^\s\+[+*]\s" end=":" end="^$" contains=changelogBullet,changelogColon,changelogFuncs,changelogError keepend
+  syn region	changelogFiles	start="^\s\+[([]" end=":" end="^$" contains=changelogBullet,changelogColon,changelogFuncs,changelogError keepend
+  syn match	changelogFuncs  contained "(.\{-})" extend
+  syn match	changelogFuncs  contained "\[.\{-}]" extend
+  syn match	changelogColon	contained ":"
+endif
+syn match	changelogBullet	contained "^\s\+[+*]\s" contains=changelogError
+syn match	changelogMail	contained "<[A-Za-z0-9\._:+-]\+@[A-Za-z0-9\._-]\+>"
+syn keyword	changelogMonth	contained jan feb mar apr may jun jul aug sep oct nov dec
+syn keyword	changelogDay	contained mon tue wed thu fri sat sun
+syn match	changelogNumber	contained "[.-]*[0-9]\+"
+
+" Define the default highlighting.
+" For version 5.7 and earlier: only when not done already
+" For version 5.8 and later: only when an item doesn't have highlighting yet
+if version >= 508 || !exists("did_changelog_syntax_inits")
+  if version < 508
+    let did_changelog_syntax_inits = 1
+    command -nargs=+ HiLink hi link <args>
+  else
+    command -nargs=+ HiLink hi def link <args>
+  endif
+
+  HiLink changelogText		Normal
+  HiLink changelogBullet	Type
+  HiLink changelogColon		Type
+  HiLink changelogFiles		Comment
+  if version >= 600
+    HiLink changelogFuncs	Comment
+  endif
+  HiLink changelogHeader	Statement
+  HiLink changelogMail		Special
+  HiLink changelogNumber	Number
+  HiLink changelogMonth		Number
+  HiLink changelogDay		Number
+  HiLink changelogError		Folded
+
+  delcommand HiLink
+endif
+
+let b:current_syntax = "changelog"
+
+" vim: ts=8
--- /dev/null
+++ b/lib/vimfiles/syntax/chaskell.vim
@@ -1,0 +1,18 @@
+" Vim syntax file
+" Language:	Haskell supporting c2hs binding hooks
+" Maintainer:	Armin Sander <armin@mindwalker.org>
+" Last Change:	2001 November 1
+"
+" 2001 November 1: Changed commands for sourcing haskell.vim
+
+" Enable binding hooks
+let b:hs_chs=1
+
+" Include standard Haskell highlighting
+if version < 600
+  source <sfile>:p:h/haskell.vim
+else
+  runtime! syntax/haskell.vim
+endif
+
+" vim: ts=8
--- /dev/null
+++ b/lib/vimfiles/syntax/cheetah.vim
@@ -1,0 +1,60 @@
+" Vim syntax file
+" Language:	Cheetah template engine
+" Maintainer:	Max Ischenko <mfi@ukr.net>
+" Last Change: 2003-05-11
+"
+" Missing features:
+"  match invalid syntax, like bad variable ref. or unmatched closing tag
+"  PSP-style tags: <% .. %> (obsoleted feature)
+"  doc-strings and header comments (rarely used feature)
+
+" For version 5.x: Clear all syntax items
+" For version 6.x: Quit when a syntax file was already loaded
+if version < 600
+	syntax clear
+elseif exists("b:current_syntax")
+	finish
+endif
+
+syntax case match
+
+syn keyword cheetahKeyword contained if else unless elif for in not
+syn keyword cheetahKeyword contained while repeat break continue pass end
+syn keyword cheetahKeyword contained set del attr def global include raw echo
+syn keyword cheetahKeyword contained import from extends implements
+syn keyword cheetahKeyword contained assert raise try catch finally
+syn keyword cheetahKeyword contained errorCatcher breakpoint silent cache filter
+syn match   cheetahKeyword contained "\<compiler-settings\>"
+
+" Matches cached placeholders
+syn match   cheetahPlaceHolder "$\(\*[0-9.]\+[wdhms]\?\*\|\*\)\?\h\w*\(\.\h\w*\)*" display
+syn match   cheetahPlaceHolder "$\(\*[0-9.]\+[wdhms]\?\*\|\*\)\?{\h\w*\(\.\h\w*\)*}" display
+syn match   cheetahDirective "^\s*#[^#].*$"  contains=cheetahPlaceHolder,cheetahKeyword,cheetahComment display
+
+syn match   cheetahContinuation "\\$"
+syn match   cheetahComment "##.*$" display
+syn region  cheetahMultiLineComment start="#\*" end="\*#"
+
+" Define the default highlighting.
+" For version 5.7 and earlier: only when not done already
+" For version 5.8 and later: only when an item doesn't have highlighting yet
+if version >= 508 || !exists("did_cheetah_syn_inits")
+	if version < 508
+		let did_cheetah_syn_inits = 1
+		command -nargs=+ HiLink hi link <args>
+	else
+		command -nargs=+ HiLink hi def link <args>
+	endif
+
+	HiLink cheetahPlaceHolder Identifier
+	HiLink cheetahDirective PreCondit
+	HiLink cheetahKeyword Define
+	HiLink cheetahContinuation Special
+	HiLink cheetahComment Comment
+	HiLink cheetahMultiLineComment Comment
+
+	delcommand HiLink
+endif
+
+let b:current_syntax = "cheetah"
+
--- /dev/null
+++ b/lib/vimfiles/syntax/chill.vim
@@ -1,0 +1,191 @@
+" Vim syntax file
+" Language:	CHILL
+" Maintainer:	YoungSang Yoon <image@lgic.co.kr>
+" Last change:	2004 Jan 21
+"
+
+" first created by image@lgic.co.kr & modified by paris@lgic.co.kr
+
+" CHILL (CCITT High Level Programming Language) is used for
+" developing software of ATM switch at LGIC (LG Information
+" & Communications LTd.)
+
+
+" For version 5.x: Clear all syntax items
+" For version 6.x: Quit when a syntax file was already loaded
+if version < 600
+  syntax clear
+elseif exists("b:current_syntax")
+  finish
+endif
+
+" A bunch of useful CHILL keywords
+syn keyword	chillStatement	goto GOTO return RETURN returns RETURNS
+syn keyword	chillLabel		CASE case ESAC esac
+syn keyword	chillConditional	if IF else ELSE elsif ELSIF switch SWITCH THEN then FI fi
+syn keyword	chillLogical	NOT not
+syn keyword	chillRepeat	while WHILE for FOR do DO od OD TO to
+syn keyword	chillProcess	START start STACKSIZE stacksize PRIORITY priority THIS this STOP stop
+syn keyword	chillBlock		PROC proc PROCESS process
+syn keyword	chillSignal	RECEIVE receive SEND send NONPERSISTENT nonpersistent PERSISTENT peristent SET set EVER ever
+
+syn keyword	chillTodo		contained TODO FIXME XXX
+
+" String and Character constants
+" Highlight special characters (those which have a backslash) differently
+syn match	chillSpecial	contained "\\x\x\+\|\\\o\{1,3\}\|\\.\|\\$"
+syn region	chillString	start=+"+ skip=+\\\\\|\\"+ end=+"+ contains=chillSpecial
+syn match	chillCharacter	"'[^\\]'"
+syn match	chillSpecialCharacter "'\\.'"
+syn match	chillSpecialCharacter "'\\\o\{1,3\}'"
+
+"when wanted, highlight trailing white space
+if exists("chill_space_errors")
+  syn match	chillSpaceError	"\s*$"
+  syn match	chillSpaceError	" \+\t"me=e-1
+endif
+
+"catch errors caused by wrong parenthesis
+syn cluster	chillParenGroup	contains=chillParenError,chillIncluded,chillSpecial,chillTodo,chillUserCont,chillUserLabel,chillBitField
+syn region	chillParen		transparent start='(' end=')' contains=ALLBUT,@chillParenGroup
+syn match	chillParenError	")"
+syn match	chillInParen	contained "[{}]"
+
+"integer number, or floating point number without a dot and with "f".
+syn case ignore
+syn match	chillNumber		"\<\d\+\(u\=l\=\|lu\|f\)\>"
+"floating point number, with dot, optional exponent
+syn match	chillFloat		"\<\d\+\.\d*\(e[-+]\=\d\+\)\=[fl]\=\>"
+"floating point number, starting with a dot, optional exponent
+syn match	chillFloat		"\.\d\+\(e[-+]\=\d\+\)\=[fl]\=\>"
+"floating point number, without dot, with exponent
+syn match	chillFloat		"\<\d\+e[-+]\=\d\+[fl]\=\>"
+"hex number
+syn match	chillNumber		"\<0x\x\+\(u\=l\=\|lu\)\>"
+"syn match chillIdentifier	"\<[a-z_][a-z0-9_]*\>"
+syn case match
+" flag an octal number with wrong digits
+syn match	chillOctalError	"\<0\o*[89]"
+
+if exists("chill_comment_strings")
+  " A comment can contain chillString, chillCharacter and chillNumber.
+  " But a "*/" inside a chillString in a chillComment DOES end the comment!  So we
+  " need to use a special type of chillString: chillCommentString, which also ends on
+  " "*/", and sees a "*" at the start of the line as comment again.
+  " Unfortunately this doesn't very well work for // type of comments :-(
+  syntax match	chillCommentSkip	contained "^\s*\*\($\|\s\+\)"
+  syntax region chillCommentString	contained start=+"+ skip=+\\\\\|\\"+ end=+"+ end=+\*/+me=s-1 contains=chillSpecial,chillCommentSkip
+  syntax region chillComment2String	contained start=+"+ skip=+\\\\\|\\"+ end=+"+ end="$" contains=chillSpecial
+  syntax region chillComment	start="/\*" end="\*/" contains=chillTodo,chillCommentString,chillCharacter,chillNumber,chillFloat,chillSpaceError
+  syntax match  chillComment	"//.*" contains=chillTodo,chillComment2String,chillCharacter,chillNumber,chillSpaceError
+else
+  syn region	chillComment	start="/\*" end="\*/" contains=chillTodo,chillSpaceError
+  syn match	chillComment	"//.*" contains=chillTodo,chillSpaceError
+endif
+syntax match	chillCommentError	"\*/"
+
+syn keyword	chillOperator	SIZE size
+syn keyword	chillType		dcl DCL int INT char CHAR bool BOOL REF ref LOC loc INSTANCE instance
+syn keyword	chillStructure	struct STRUCT enum ENUM newmode NEWMODE synmode SYNMODE
+"syn keyword	chillStorageClass
+syn keyword	chillBlock		PROC proc END end
+syn keyword	chillScope		GRANT grant SEIZE seize
+syn keyword	chillEDML		select SELECT delete DELETE update UPDATE in IN seq SEQ WHERE where INSERT insert include INCLUDE exclude EXCLUDE
+syn keyword	chillBoolConst	true TRUE false FALSE
+
+syn region	chillPreCondit	start="^\s*#\s*\(if\>\|ifdef\>\|ifndef\>\|elif\>\|else\>\|endif\>\)" skip="\\$" end="$" contains=chillComment,chillString,chillCharacter,chillNumber,chillCommentError,chillSpaceError
+syn region	chillIncluded	contained start=+"+ skip=+\\\\\|\\"+ end=+"+
+syn match	chillIncluded	contained "<[^>]*>"
+syn match	chillInclude	"^\s*#\s*include\>\s*["<]" contains=chillIncluded
+"syn match chillLineSkip	"\\$"
+syn cluster	chillPreProcGroup	contains=chillPreCondit,chillIncluded,chillInclude,chillDefine,chillInParen,chillUserLabel
+syn region	chillDefine		start="^\s*#\s*\(define\>\|undef\>\)" skip="\\$" end="$" contains=ALLBUT,@chillPreProcGroup
+syn region	chillPreProc	start="^\s*#\s*\(pragma\>\|line\>\|warning\>\|warn\>\|error\>\)" skip="\\$" end="$" contains=ALLBUT,@chillPreProcGroup
+
+" Highlight User Labels
+syn cluster	chillMultiGroup	contains=chillIncluded,chillSpecial,chillTodo,chillUserCont,chillUserLabel,chillBitField
+syn region	chillMulti		transparent start='?' end=':' contains=ALLBUT,@chillMultiGroup
+" Avoid matching foo::bar() in C++ by requiring that the next char is not ':'
+syn match	chillUserCont	"^\s*\I\i*\s*:$" contains=chillUserLabel
+syn match	chillUserCont	";\s*\I\i*\s*:$" contains=chillUserLabel
+syn match	chillUserCont	"^\s*\I\i*\s*:[^:]"me=e-1 contains=chillUserLabel
+syn match	chillUserCont	";\s*\I\i*\s*:[^:]"me=e-1 contains=chillUserLabel
+
+syn match	chillUserLabel	"\I\i*" contained
+
+" Avoid recognizing most bitfields as labels
+syn match	chillBitField	"^\s*\I\i*\s*:\s*[1-9]"me=e-1
+syn match	chillBitField	";\s*\I\i*\s*:\s*[1-9]"me=e-1
+
+syn match	chillBracket	contained "[<>]"
+if !exists("chill_minlines")
+  let chill_minlines = 15
+endif
+exec "syn sync ccomment chillComment minlines=" . chill_minlines
+
+" Define the default highlighting.
+" For version 5.7 and earlier: only when not done already
+" For version 5.8 and later: only when an item doesn't have highlighting yet
+if version >= 508 || !exists("did_ch_syntax_inits")
+  if version < 508
+    let did_ch_syntax_inits = 1
+    command -nargs=+ HiLink hi link <args>
+  else
+    command -nargs=+ HiLink hi def link <args>
+  endif
+
+  HiLink chillLabel	Label
+  HiLink chillUserLabel	Label
+  HiLink chillConditional	Conditional
+  " hi chillConditional	term=bold ctermfg=red guifg=red gui=bold
+
+  HiLink chillRepeat	Repeat
+  HiLink chillProcess	Repeat
+  HiLink chillSignal	Repeat
+  HiLink chillCharacter	Character
+  HiLink chillSpecialCharacter chillSpecial
+  HiLink chillNumber	Number
+  HiLink chillFloat	Float
+  HiLink chillOctalError	chillError
+  HiLink chillParenError	chillError
+  HiLink chillInParen	chillError
+  HiLink chillCommentError	chillError
+  HiLink chillSpaceError	chillError
+  HiLink chillOperator	Operator
+  HiLink chillStructure	Structure
+  HiLink chillBlock	Operator
+  HiLink chillScope	Operator
+  "hi chillEDML     term=underline ctermfg=DarkRed guifg=Red
+  HiLink chillEDML	PreProc
+  "hi chillBoolConst	term=bold ctermfg=brown guifg=brown
+  HiLink chillBoolConst	Constant
+  "hi chillLogical	term=bold ctermfg=brown guifg=brown
+  HiLink chillLogical	Constant
+  HiLink chillStorageClass	StorageClass
+  HiLink chillInclude	Include
+  HiLink chillPreProc	PreProc
+  HiLink chillDefine	Macro
+  HiLink chillIncluded	chillString
+  HiLink chillError	Error
+  HiLink chillStatement	Statement
+  HiLink chillPreCondit	PreCondit
+  HiLink chillType	Type
+  HiLink chillCommentError	chillError
+  HiLink chillCommentString chillString
+  HiLink chillComment2String chillString
+  HiLink chillCommentSkip	chillComment
+  HiLink chillString	String
+  HiLink chillComment	Comment
+  " hi chillComment	term=None ctermfg=lightblue guifg=lightblue
+  HiLink chillSpecial	SpecialChar
+  HiLink chillTodo	Todo
+  HiLink chillBlock	Statement
+  "HiLink chillIdentifier	Identifier
+  HiLink chillBracket	Delimiter
+
+  delcommand HiLink
+endif
+
+let b:current_syntax = "chill"
+
+" vim: ts=8
--- /dev/null
+++ b/lib/vimfiles/syntax/chordpro.vim
@@ -1,0 +1,67 @@
+" Vim syntax file
+" Language:     ChordPro (v. 3.6.2)
+" Maintainer:   Niels Bo Andersen <niels@niboan.dk>
+" Last Change:	2006 Apr 30
+" Remark:       Requires VIM version 6.00 or greater
+
+" Quit when a syntax file was already loaded
+if exists("b:current_syntax")
+  finish
+endif
+
+let s:cpo_save = &cpo
+set cpo&vim
+
+setlocal iskeyword+=-
+
+syn case ignore
+
+syn keyword chordproDirective contained
+  \ start_of_chorus soc end_of_chorus eoc new_song ns no_grid ng grid g
+  \ new_page np new_physical_page npp start_of_tab sot end_of_tab eot
+  \ column_break colb
+
+syn keyword chordproDirWithOpt contained
+  \ comment c comment_italic ci comment_box cb title t subtitle st define
+  \ textfont textsize chordfont chordsize columns col
+
+syn keyword chordproDefineKeyword contained base-fret frets
+
+syn match chordproDirMatch /{\w*}/ contains=chordproDirective contained transparent
+syn match chordproDirOptMatch /{\w*:/ contains=chordproDirWithOpt contained transparent
+
+" Workaround for a bug in VIM 6, which causes incorrect coloring of the first {
+if version < 700
+  syn region chordproOptions start=/{\w*:/ end=/}/ contains=chordproDirOptMatch contained transparent
+  syn region chordproOptions start=/{define:/ end=/}/ contains=chordproDirOptMatch, chordproDefineKeyword contained transparent
+else
+  syn region chordproOptions start=/{\w*:/hs=e+1 end=/}/he=s-1 contains=chordproDirOptMatch contained
+  syn region chordproOptions start=/{define:/hs=e+1 end=/}/he=s-1 contains=chordproDirOptMatch, chordproDefineKeyword contained
+endif
+
+syn region chordproTag start=/{/ end=/}/ contains=chordproDirMatch,chordproOptions oneline
+
+syn region chordproChord matchgroup=chordproBracket start=/\[/ end=/]/ oneline
+
+syn region chordproTab start=/{start_of_tab}\|{sot}/hs=e+1 end=/{end_of_tab}\|{eot}/he=s-1 contains=chordproTag,chordproComment keepend
+
+syn region chordproChorus start=/{start_of_chorus}\|{soc}/hs=e+1 end=/{end_of_chorus}\|{eoc}/he=s-1 contains=chordproTag,chordproChord,chordproComment keepend
+
+syn match chordproComment /^#.*/
+
+" Define the default highlighting.
+hi def link chordproDirective Statement
+hi def link chordproDirWithOpt Statement
+hi def link chordproOptions Special
+hi def link chordproChord Type
+hi def link chordproTag Constant
+hi def link chordproTab PreProc
+hi def link chordproComment Comment
+hi def link chordproBracket Constant
+hi def link chordproDefineKeyword Type
+hi def chordproChorus term=bold cterm=bold gui=bold
+
+let b:current_syntax = "chordpro"
+
+let &cpo = s:cpo_save
+unlet s:cpo_save
--- /dev/null
+++ b/lib/vimfiles/syntax/cl.vim
@@ -1,0 +1,110 @@
+" Vim syntax file
+" Language:	cl ("Clever Language" by Multibase, http://www.mbase.com.au)
+" Filename extensions: *.ent, *.eni
+" Maintainer:	Philip Uren <philuSPAX@ieee.org> - Remove SPAX spam block
+" Last update:	Wed Apr 12 08:47:18 EST 2006
+" $Id: cl.vim,v 1.3 2006/04/12 21:43:28 vimboss Exp $
+
+" For version 5.x: Clear all syntax items
+" For version 6.x: Quit when a syntax file was already loaded
+if version < 600
+	syntax clear
+elseif exists("b:current_syntax")
+	finish
+endif
+
+if version >= 600
+	setlocal iskeyword=@,48-57,_,-,
+else
+	set iskeyword=@,48-57,_,-,
+endif
+
+syn case ignore
+
+syn sync lines=300
+
+"If/else/elsif/endif and while/wend mismatch errors
+syn match	clifError		"\<wend\>"
+syn match	clifError		"\<elsif\>"
+syn match	clifError		"\<else\>"
+syn match	clifError		"\<endif\>"
+
+syn match	clSpaceError		"\s\+$"
+
+" If and while regions
+syn region	clLoop		transparent matchgroup=clWhile start="\<while\>" matchgroup=clWhile end="\<wend\>" contains=ALLBUT,clBreak,clProcedure
+syn region	clIf		transparent matchgroup=clConditional start="\<if\>" matchgroup=clConditional end="\<endif\>"   contains=ALLBUT,clBreak,clProcedure
+
+" Make those TODO notes and debugging stand out!
+syn keyword	clTodo		contained	TODO BUG DEBUG FIX
+syn match	clNeedsWork	contained	"NEED[S]*\s\s*WORK"
+syn keyword	clDebug		contained	debug
+
+syn match	clComment	"#.*$"		contains=clTodo,clNeedsWork
+syn region	clProcedure	oneline		start="^\s*[{}]" end="$"
+syn match	clInclude	"^\s*include\s.*"
+
+" We don't put "debug" in the clSetOptions;
+" we contain it in clSet so we can make it stand out.
+syn keyword	clSetOptions	transparent aauto abort align convert E fill fnum goback hangup justify null_exit output rauto rawprint rawdisplay repeat skip tab trim
+syn match	clSet		"^\s*set\s.*" contains=clSetOptions,clDebug
+
+syn match	clPreProc	"^\s*#P.*"
+
+syn keyword	clConditional	else elsif
+syn keyword	clWhile		continue endloop
+" 'break' needs to be a region so we can sync on it above.
+syn region	clBreak		oneline start="^\s*break" end="$"
+
+syn match	clOperator	"[!;|)(:.><+*=-]"
+
+syn match	clNumber	"\<\d\+\(u\=l\=\|lu\|f\)\>"
+
+syn region	clString	matchgroup=clQuote	start=+"+ end=+"+	skip=+\\"+
+syn region	clString	matchgroup=clQuote	start=+'+ end=+'+	skip=+\\'+
+
+syn keyword	clReserved	ERROR EXIT INTERRUPT LOCKED LREPLY MODE MCOL MLINE MREPLY NULL REPLY V1 V2 V3 V4 V5 V6 V7 V8 V9 ZERO BYPASS GOING_BACK AAUTO ABORT ABORT ALIGN BIGE CONVERT FNUM GOBACK HANGUP JUSTIFY NEXIT OUTPUT RAUTO RAWDISPLAY RAWPRINT REPEAT SKIP TAB TRIM LCOUNT PCOUNT PLINES SLINES SCOLS MATCH LMATCH
+
+syn keyword	clFunction	asc asize chr name random slen srandom day getarg getcgi getenv lcase scat sconv sdel skey smult srep substr sword trim ucase match
+
+syn keyword	clStatement	clear clear_eol clear_eos close copy create unique with where empty define define ldefine delay_form delete escape exit_block exit_do exit_process field fork format get getfile getnext getprev goto head join maintain message no_join on_eop on_key on_exit on_delete openin openout openapp pause popenin popenout popenio print put range read redisplay refresh restart_block screen select sleep text unlock write and not or do
+
+" Define the default highlighting.
+" For version 5.7 and earlier: only when not done already
+" For version 5.8 and later: only when an item doesn't have highlighting yet
+if	version >= 508 || !exists("did_cl_syntax_inits")
+	if	version < 508
+		let did_cl_syntax_inits = 1
+		command -nargs=+ HiLink hi link <args>
+	else
+		command -nargs=+ HiLink hi def link <args>
+	endif
+
+	HiLink clifError	Error
+	HiLink clSpaceError	Error
+	HiLink clWhile		Repeat
+	HiLink clConditional	Conditional
+	HiLink clDebug		Debug
+	HiLink clNeedsWork	Todo
+	HiLink clTodo		Todo
+	HiLink clComment	Comment
+	HiLink clProcedure	Procedure
+	HiLink clBreak		Procedure
+	HiLink clInclude	Include
+	HiLink clSetOption	Statement
+	HiLink clSet		Identifier
+	HiLink clPreProc	PreProc
+	HiLink clOperator	Operator
+	HiLink clNumber		Number
+	HiLink clString		String
+	HiLink clQuote		Delimiter
+	HiLink clReserved	Identifier
+	HiLink clFunction	Function
+	HiLink clStatement	Statement
+
+	delcommand HiLink
+endif
+
+let b:current_syntax = "cl"
+
+" vim: ts=8 sw=8
--- /dev/null
+++ b/lib/vimfiles/syntax/clean.vim
@@ -1,0 +1,94 @@
+" Vim syntax file
+" Language:		Clean
+" Author:		Pieter van Engelen <pietere@sci.kun.nl>
+" Co-Author:	Arthur van Leeuwen <arthurvl@sci.kun.nl>
+" Last Change:	Fri Sep 29 11:35:34 CEST 2000
+
+" For version 5.x: Clear all syntax items
+" For version 6.x: Quit when a syntax file was already loaded
+if version < 600
+  syntax clear
+elseif exists("b:current_syntax")
+  finish
+endif
+
+" Some Clean-keywords
+syn keyword cleanConditional if case
+syn keyword cleanLabel let! with where in of
+syn keyword cleanInclude from import
+syn keyword cleanSpecial Start
+syn keyword cleanKeyword infixl infixr infix
+syn keyword cleanBasicType Int Real Char Bool String
+syn keyword cleanSpecialType World ProcId Void Files File
+syn keyword cleanModuleSystem module implementation definition system
+syn keyword cleanTypeClass class instance export
+
+" To do some Denotation Highlighting
+syn keyword cleanBoolDenot True False
+syn region  cleanStringDenot start=+"+ end=+"+
+syn match cleanCharDenot "'.'"
+syn match cleanCharsDenot "'[^'\\]*\(\\.[^'\\]\)*'" contained
+syn match cleanIntegerDenot "[+-~]\=\<\(\d\+\|0[0-7]\+\|0x[0-9A-Fa-f]\+\)\>"
+syn match cleanRealDenot "[+-~]\=\<\d\+\.\d+\(E[+-~]\=\d+\)\="
+
+" To highlight the use of lists, tuples and arrays
+syn region cleanList start="\[" end="\]" contains=ALL
+syn region cleanRecord start="{" end="}" contains=ALL
+syn region cleanArray start="{:" end=":}" contains=ALL
+syn match cleanTuple "([^=]*,[^=]*)" contains=ALL
+
+" To do some Comment Highlighting
+syn region cleanComment start="/\*"  end="\*/" contains=cleanComment
+syn match cleanComment "//.*"
+
+" Now for some useful typedefinitionrecognition
+syn match cleanFuncTypeDef "\([a-zA-Z].*\|(\=[-~@#$%^?!+*<>\/|&=:]\+)\=\)[ \t]*\(infix[lr]\=\)\=[ \t]*\d\=[ \t]*::.*->.*" contains=cleanSpecial
+
+" Define the default highlighting.
+" For version 5.7 and earlier: only when not done already
+" For version 5.8 and later: only when an item doesn't have highlighting yet
+if version >= 508 || !exists("did_clean_syntax_init")
+  if version < 508
+    let did_clean_syntax_init = 1
+    command -nargs=+ HiLink hi link <args>
+  else
+    command -nargs=+ HiLink hi def link <args>
+  endif
+
+   " Comments
+   HiLink cleanComment      Comment
+   " Constants and denotations
+   HiLink cleanCharsDenot   String
+   HiLink cleanStringDenot  String
+   HiLink cleanCharDenot    Character
+   HiLink cleanIntegerDenot Number
+   HiLink cleanBoolDenot    Boolean
+   HiLink cleanRealDenot    Float
+   " Identifiers
+   " Statements
+   HiLink cleanTypeClass    Keyword
+   HiLink cleanConditional  Conditional
+   HiLink cleanLabel		Label
+   HiLink cleanKeyword      Keyword
+   " Generic Preprocessing
+   HiLink cleanInclude      Include
+   HiLink cleanModuleSystem PreProc
+   " Type
+   HiLink cleanBasicType    Type
+   HiLink cleanSpecialType  Type
+   HiLink cleanFuncTypeDef  Typedef
+   " Special
+   HiLink cleanSpecial      Special
+   HiLink cleanList			Special
+   HiLink cleanArray		Special
+   HiLink cleanRecord		Special
+   HiLink cleanTuple		Special
+   " Error
+   " Todo
+
+  delcommand HiLink
+endif
+
+let b:current_syntax = "clean"
+
+" vim: ts=4
--- /dev/null
+++ b/lib/vimfiles/syntax/clipper.vim
@@ -1,0 +1,143 @@
+" Vim syntax file:
+" Language:	Clipper 5.2 & FlagShip
+" Maintainer:	C R Zamana <zamana@zip.net>
+" Some things based on c.vim by Bram Moolenaar and pascal.vim by Mario Eusebio
+" Last Change:	Sat Sep 09 2000
+
+" For version 5.x: Clear all syntax items
+" For version 6.x: Quit when a syntax file was already loaded
+if version < 600
+  syntax clear
+elseif exists("b:current_syntax")
+  finish
+endif
+
+" Exceptions for my "Very Own" (TM) user variables naming style.
+" If you don't like this, comment it
+syn match  clipperUserVariable	"\<[a,b,c,d,l,n,o,u,x][A-Z][A-Za-z0-9_]*\>"
+syn match  clipperUserVariable	"\<[a-z]\>"
+
+" Clipper is case insensitive ( see "exception" above )
+syn case ignore
+
+" Clipper keywords ( in no particular order )
+syn keyword clipperStatement	ACCEPT APPEND BLANK FROM AVERAGE CALL CANCEL
+syn keyword clipperStatement	CLEAR ALL GETS MEMORY TYPEAHEAD CLOSE
+syn keyword clipperStatement	COMMIT CONTINUE SHARED NEW PICT
+syn keyword clipperStatement	COPY FILE STRUCTURE STRU EXTE TO COUNT
+syn keyword clipperStatement	CREATE FROM NIL
+syn keyword clipperStatement	DELETE FILE DIR DISPLAY EJECT ERASE FIND GO
+syn keyword clipperStatement	INDEX INPUT VALID WHEN
+syn keyword clipperStatement	JOIN KEYBOARD LABEL FORM LIST LOCATE MENU TO
+syn keyword clipperStatement	NOTE PACK QUIT READ
+syn keyword clipperStatement	RECALL REINDEX RELEASE RENAME REPLACE REPORT
+syn keyword clipperStatement	RETURN FORM RESTORE
+syn keyword clipperStatement	RUN SAVE SEEK SELECT
+syn keyword clipperStatement	SKIP SORT STORE SUM TEXT TOTAL TYPE UNLOCK
+syn keyword clipperStatement	UPDATE USE WAIT ZAP
+syn keyword clipperStatement	BEGIN SEQUENCE
+syn keyword clipperStatement	SET ALTERNATE BELL CENTURY COLOR CONFIRM CONSOLE
+syn keyword clipperStatement	CURSOR DATE DECIMALS DEFAULT DELETED DELIMITERS
+syn keyword clipperStatement	DEVICE EPOCH ESCAPE EXACT EXCLUSIVE FILTER FIXED
+syn keyword clipperStatement	FORMAT FUNCTION INTENSITY KEY MARGIN MESSAGE
+syn keyword clipperStatement	ORDER PATH PRINTER PROCEDURE RELATION SCOREBOARD
+syn keyword clipperStatement	SOFTSEEK TYPEAHEAD UNIQUE WRAP
+syn keyword clipperStatement	BOX CLEAR GET PROMPT SAY ? ??
+syn keyword clipperStatement	DELETE TAG GO RTLINKCMD TMP DBLOCKINFO
+syn keyword clipperStatement	DBEVALINFO DBFIELDINFO DBFILTERINFO DBFUNCTABLE
+syn keyword clipperStatement	DBOPENINFO DBORDERCONDINFO DBORDERCREATEINF
+syn keyword clipperStatement	DBORDERINFO DBRELINFO DBSCOPEINFO DBSORTINFO
+syn keyword clipperStatement	DBSORTITEM DBTRANSINFO DBTRANSITEM WORKAREA
+
+" Conditionals
+syn keyword clipperConditional	CASE OTHERWISE ENDCASE
+syn keyword clipperConditional	IF ELSE ENDIF IIF IFDEF IFNDEF
+
+" Loops
+syn keyword clipperRepeat	DO WHILE ENDDO
+syn keyword clipperRepeat	FOR TO NEXT STEP
+
+" Visibility
+syn keyword clipperStorageClass	ANNOUNCE STATIC
+syn keyword clipperStorageClass DECLARE EXTERNAL LOCAL MEMVAR PARAMETERS
+syn keyword clipperStorageClass PRIVATE PROCEDURE PUBLIC REQUEST STATIC
+syn keyword clipperStorageClass FIELD FUNCTION
+syn keyword clipperStorageClass EXIT PROCEDURE INIT PROCEDURE
+
+" Operators
+syn match   clipperOperator	"$\|%\|&\|+\|-\|->\|!"
+syn match   clipperOperator	"\.AND\.\|\.NOT\.\|\.OR\."
+syn match   clipperOperator	":=\|<\|<=\|<>\|!=\|#\|=\|==\|>\|>=\|@"
+syn match   clipperOperator     "*"
+
+" Numbers
+syn match   clipperNumber	"\<\d\+\(u\=l\=\|lu\|f\)\>"
+
+" Includes
+syn region clipperIncluded	contained start=+"+ skip=+\\\\\|\\"+ end=+"+
+syn match  clipperIncluded	contained "<[^>]*>"
+syn match  clipperInclude	"^\s*#\s*include\>\s*["<]" contains=clipperIncluded
+
+" String and Character constants
+syn region clipperString	start=+"+ end=+"+
+syn region clipperString	start=+'+ end=+'+
+
+" Delimiters
+syn match  ClipperDelimiters	"[()]\|[\[\]]\|[{}]\|[||]"
+
+" Special
+syn match clipperLineContinuation	";"
+
+" This is from Bram Moolenaar:
+if exists("c_comment_strings")
+  " A comment can contain cString, cCharacter and cNumber.
+  " But a "*/" inside a cString in a clipperComment DOES end the comment!
+  " So we need to use a special type of cString: clipperCommentString, which
+  " also ends on "*/", and sees a "*" at the start of the line as comment
+  " again. Unfortunately this doesn't very well work for // type of comments :-(
+  syntax match clipperCommentSkip	contained "^\s*\*\($\|\s\+\)"
+  syntax region clipperCommentString	contained start=+"+ skip=+\\\\\|\\"+ end=+"+ end=+\*/+me=s-1 contains=clipperCommentSkip
+  syntax region clipperComment2String	contained start=+"+ skip=+\\\\\|\\"+ end=+"+ end="$"
+  syntax region clipperComment		start="/\*" end="\*/" contains=clipperCommentString,clipperCharacter,clipperNumber,clipperString
+  syntax match  clipperComment		"//.*" contains=clipperComment2String,clipperCharacter,clipperNumber
+else
+  syn region clipperComment		start="/\*" end="\*/"
+  syn match clipperComment		"//.*"
+endif
+syntax match clipperCommentError	"\*/"
+
+" Lines beggining with an "*" are comments too
+syntax match clipperComment		"^\*.*"
+
+
+" Define the default highlighting.
+" For version 5.7 and earlier: only when not done already
+" For version 5.8 and later: only when an item doesn't have highlighting yet
+if version >= 508 || !exists("did_clipper_syntax_inits")
+  if version < 508
+    let did_clipper_syntax_inits = 1
+    command -nargs=+ HiLink hi link <args>
+  else
+    command -nargs=+ HiLink hi def link <args>
+  endif
+
+  HiLink clipperConditional		Conditional
+  HiLink clipperRepeat			Repeat
+  HiLink clipperNumber			Number
+  HiLink clipperInclude		Include
+  HiLink clipperComment		Comment
+  HiLink clipperOperator		Operator
+  HiLink clipperStorageClass		StorageClass
+  HiLink clipperStatement		Statement
+  HiLink clipperString			String
+  HiLink clipperFunction		Function
+  HiLink clipperLineContinuation	Special
+  HiLink clipperDelimiters		Delimiter
+  HiLink clipperUserVariable		Identifier
+
+  delcommand HiLink
+endif
+
+let b:current_syntax = "clipper"
+
+" vim: ts=4
--- /dev/null
+++ b/lib/vimfiles/syntax/cmake.vim
@@ -1,0 +1,85 @@
+" =============================================================================
+"
+"   Program:   CMake - Cross-Platform Makefile Generator
+"   Module:    $RCSfile: cmake.vim,v $
+"   Language:  VIM
+"   Date:      $Date: 2006/04/21 22:08:13 $
+"   Version:   $Revision: 1.2 $
+"
+" =============================================================================
+
+" Vim syntax file
+" Language:     CMake
+" Author:       Andy Cedilnik <andy.cedilnik@kitware.com>
+" Maintainer:   Andy Cedilnik <andy.cedilnik@kitware.com>
+" Last Change:  $Date: 2006/04/21 22:08:13 $
+" Version:      $Revision: 1.2 $
+"
+" Licence:      The CMake license applies to this file. See
+"               http://www.cmake.org/HTML/Copyright.html
+"               This implies that distribution with Vim is allowed
+
+" For version 5.x: Clear all syntax items
+" For version 6.x: Quit when a syntax file was already loaded
+if version < 600
+  syntax clear
+elseif exists("b:current_syntax")
+  finish
+endif
+
+syn case ignore
+syn match cmakeComment /#.*$/
+syn region cmakeRegistry start=/\[/ end=/\]/ skip=/\\[\[\]]/
+            \ contained
+syn match cmakeArgument /[^()"]+/
+            \ contained
+syn match cmakeVariableValue /\${[^}]*}/
+            \ contained oneline
+syn match cmakeEnvironment /\$ENV{.*}/
+            \ contained
+syn keyword cmakeSystemVariables
+            \ WIN32 UNIX APPLE CYGWIN BORLAND MINGW MSVC MSVC_IDE MSVC60 MSVC70 MSVC71 MSVC80
+syn keyword cmakeOperators
+            \ AND BOOL CACHE COMMAND DEFINED DOC EQUAL EXISTS FALSE GREATER INTERNAL LESS MATCHES NAME NAMES NAME_WE NOT OFF ON OR PATH PATHS PROGRAM STREQUAL STRGREATER STRING STRLESS TRUE
+"            \ contained
+syn region cmakeString start=/"/ end=/"/ skip=/\\"/
+            \ contains=ALLBUT,cmakeString
+syn region cmakeArguments start=/\s*(/ end=/)/
+           \ contains=ALLBUT,cmakeArguments
+syn keyword cmakeDeprecated ABSTRACT_FILES BUILD_NAME SOURCE_FILES SOURCE_FILES_REMOVE VTK_MAKE_INSTANTIATOR VTK_WRAP_JAVA VTK_WRAP_PYTHON VTK_WRAP_TCL WRAP_EXCLUDE_FILES
+           \ nextgroup=cmakeArgument
+syn keyword cmakeStatement
+           \ ADD_CUSTOM_COMMAND ADD_CUSTOM_TARGET ADD_DEFINITIONS ADD_DEPENDENCIES ADD_EXECUTABLE ADD_LIBRARY ADD_SUBDIRECTORY ADD_TEST AUX_SOURCE_DIRECTORY BUILD_COMMAND BUILD_NAME CMAKE_MINIMUM_REQUIRED CONFIGURE_FILE CREATE_TEST_SOURCELIST ELSE ENABLE_LANGUAGE ENABLE_TESTING ENDFOREACH ENDIF ENDWHILE EXEC_PROGRAM EXECUTE_PROCESS EXPORT_LIBRARY_DEPENDENCIES FILE FIND_FILE FIND_LIBRARY FIND_PACKAGE FIND_PATH FIND_PROGRAM FLTK_WRAP_UI FOREACH GET_CMAKE_PROPERTY GET_DIRECTORY_PROPERTY GET_FILENAME_COMPONENT GET_SOURCE_FILE_PROPERTY GET_TARGET_PROPERTY GET_TEST_PROPERTY IF INCLUDE INCLUDE_DIRECTORIES INCLUDE_EXTERNAL_MSPROJECT INCLUDE_REGULAR_EXPRESSION INSTALL INSTALL_FILES INSTALL_PROGRAMS INSTALL_TARGETS LINK_DIRECTORIES LINK_LIBRARIES LIST LOAD_CACHE LOAD_COMMAND MACRO MAKE_DIRECTORY MARK_AS_ADVANCED MATH MESSAGE OPTION OUTPUT_REQUIRED_FILES PROJECT QT_WRAP_CPP QT_WRAP_UI REMOVE REMOVE_DEFINITIONS SEPARATE_ARGUMENTS SET SET_DIRECTORY_PROPERTIES SET_SOURCE_FILES_PROPERTIES SET_TARGET_PROPERTIES SET_TESTS_PROPERTIES SITE_NAME SOURCE_GROUP STRING SUBDIR_DEPENDS SUBDIRS TARGET_LINK_LIBRARIES TRY_COMPILE TRY_RUN USE_MANGLED_MESA UTILITY_SOURCE VARIABLE_REQUIRES VTK_MAKE_INSTANTIATOR VTK_WRAP_JAVA VTK_WRAP_PYTHON VTK_WRAP_TCL WHILE WRITE_FILE ENDMACRO
+           \ nextgroup=cmakeArgumnts
+
+"syn match cmakeMacro /^\s*[A-Z_]\+/ nextgroup=cmakeArgumnts
+
+" Define the default highlighting.
+" For version 5.7 and earlier: only when not done already
+" For version 5.8 and later: only when an item doesn't have highlighting yet
+if version >= 508 || !exists("did_cmake_syntax_inits")
+  if version < 508
+    let did_cmake_syntax_inits = 1
+    command -nargs=+ HiLink hi link <args>
+  else
+    command -nargs=+ HiLink hi def link <args>
+  endif
+
+  HiLink cmakeStatement Statement
+  HiLink cmakeComment Comment
+  HiLink cmakeString String
+  HiLink cmakeVariableValue Type
+  HiLink cmakeRegistry Underlined
+  HiLink cmakeArguments Identifier
+  HiLink cmakeArgument Constant
+  HiLink cmakeEnvironment Special
+  HiLink cmakeOperators Operator
+  HiLink cmakeMacro PreProc
+  HiLink cmakeError	Error
+
+  delcommand HiLink
+endif
+
+let b:current_syntax = "cmake"
+
+"EOF"
--- /dev/null
+++ b/lib/vimfiles/syntax/cmusrc.vim
@@ -1,0 +1,309 @@
+" Vim syntax file
+" Maintainer:       Nikolai Weibull <now@bitwi.se>
+" Latest Revision:  2006-07-22
+
+if exists("b:current_syntax")
+  finish
+endif
+
+let s:cpo_save = &cpo
+set cpo&vim
+
+setlocal iskeyword=@,48-57,_,-
+
+syn keyword cmusrcTodo          contained TODO FIXME XXX NOTE
+
+syn match   cmusrcComment       contained display '^\s*#.*$'
+
+syn match   cmusrcBegin         display '^'
+                                \ nextgroup=cmusrcKeyword,cmusrcComment
+                                \ skipwhite
+
+syn keyword cmusrcKeyword       contained add
+                                \ nextgroup=cmusrcAddSwitches,cmusrcURI
+                                \ skipwhite
+
+syn match   cmusrcAddSwitches   contained display '-[lpqQ]'
+                                \ nextgroup=cmusrcURI
+                                \ skipwhite
+
+syn match   cmusrcURI           contained display '.\+'
+
+syn keyword cmusrcKeyword       contained bind
+                                \ nextgroup=cmusrcBindSwitches,
+                                \           cmusrcBindContext
+                                \ skipwhite
+
+syn match   cmusrcBindSwitches  contained display '-[f]'
+                                \ nextgroup=cmusrcBindContext
+                                \ skipwhite
+
+syn keyword cmusrcBindContext   contained common library playlist queue
+                                \ browser filters
+                                \ nextgroup=cmusrcBindKey
+                                \ skipwhite
+
+syn match   cmusrcBindKey       contained display '\S\+'
+                                \ nextgroup=cmusrcKeyword
+                                \ skipwhite
+
+syn keyword cmusrcKeyword       contained browser-up colorscheme echo factivate
+                                \ filter invert player-next player-pause
+                                \ player-play player-prev player-stop quit
+                                \ refresh run search-next search-prev shuffle
+                                \ unmark win-activate win-add-l win-add-p
+                                \ win-add-Q win-add-q win-bottom win-down
+                                \ win-mv-after win-mv-before win-next
+                                \ win-page-down win-page-up win-remove
+                                \ win-sel-cur win-toggle win-top win-up
+                                \ win-update
+
+syn keyword cmusrcKeyword       contained cd
+                                \ nextgroup=cmusrcDirectory
+                                \ skipwhite
+
+syn match   cmusrcDirectory     contained display '.\+'
+
+syn keyword cmusrcKeyword       contained clear
+                                \ nextgroup=cmusrcClearSwitches
+
+syn match   cmusrcClearSwitches contained display '-[lpq]'
+
+syn keyword cmusrcKeyword       contained fset
+                                \ nextgroup=cmusrcFSetName
+                                \ skipwhite
+
+syn match   cmusrcFSetName      contained display '[^=]\+'
+                                \ nextgroup=cmusrcFSetEq
+
+syn match   cmusrcFSetEq        contained display '='
+                                \ nextgroup=cmusrcFilterExpr
+
+syn match   cmusrcFilterExpr    contained display '.\+'
+
+syn keyword cmusrcKeyword       contained load
+                                \ nextgroup=cmusrcLoadSwitches,cmusrcURI
+                                \ skipwhite
+
+syn match   cmusrcLoadSwitches  contained display '-[lp]'
+                                \ nextgroup=cmusrcURI
+                                \ skipwhite
+
+syn keyword cmusrcKeyword       contained mark
+                                \ nextgroup=cmusrcFilterExpr
+
+syn keyword cmusrcKeyword       contained save
+                                \ nextgroup=cmusrcSaveSwitches,cmusrcFile
+                                \ skipwhite
+
+syn match   cmusrcSaveSwitches  contained display '-[lp]'
+                                \ nextgroup=cmusrcFile
+                                \ skipwhite
+
+syn match   cmusrcFile          contained display '.\+'
+
+syn keyword cmusrcKeyword       contained seek
+                                \ nextgroup=cmusrcSeekOffset
+                                \ skipwhite
+
+syn match   cmusrcSeekOffset    contained display
+      \ '[+-]\=\%(\d\+[mh]\=\|\%(\%(0\=\d\|[1-5]\d\):\)\=\%(0\=\d\|[1-5]\d\):\%(0\=\d\|[1-5]\d\)\)'
+
+syn keyword cmusrcKeyword       contained set
+                                \ nextgroup=cmusrcOption
+                                \ skipwhite
+
+syn keyword cmusrcOption        contained auto_reshuffle confirm_run
+                                \ continue play_library play_sorted repeat
+                                \ show_hidden show_remaining_time shuffle
+                                \ nextgroup=cmusrcSetTest,cmusrcOptEqBoolean
+
+syn match   cmusrcSetTest       contained display '?'
+
+syn match   cmusrcOptEqBoolean  contained display '='
+                                \ nextgroup=cmusrcOptBoolean
+
+syn keyword cmusrcOptBoolean    contained true false
+
+syn keyword cmusrcOption        contained aaa_mode
+                                \ nextgroup=cmusrcOptEqAAA
+
+syn match   cmusrcOptEqAAA      contained display '='
+                                \ nextgroup=cmusrcOptAAA
+
+syn keyword cmusrcOptAAA        contained all artist album
+
+syn keyword cmusrcOption        contained buffer_seconds
+                                \ nextgroup=cmusrcOptEqNumber
+
+syn match   cmusrcOptEqNumber   contained display '='
+                                \ nextgroup=cmusrcOptNumber
+
+syn match   cmusrcOptNumber     contained display '\d\+'
+
+syn keyword cmusrcOption        contained altformat_current altformat_playlist
+                                \ altformat_title altformat_trackwin
+                                \ format_current format_playlist format_title
+                                \ format_trackwin
+                                \ nextgroup=cmusrcOptEqFormat
+
+syn match   cmusrcOptEqFormat   contained display '='
+                                \ nextgroup=cmusrcOptFormat
+
+syn match   cmusrcOptFormat     contained display '.\+'
+                                \ contains=cmusrcFormatSpecial
+
+syn match   cmusrcFormatSpecial contained display '%[0-]*\d*[alDntgydfF=%]'
+
+syn keyword cmusrcOption        contained color_cmdline_bg color_cmdline_fg
+                                \ color_error color_info color_separator
+                                \ color_statusline_bg color_statusline_fg
+                                \ color_titleline_bg color_titleline_fg
+                                \ color_win_bg color_win_cur
+                                \ color_win_cur_sel_bg color_win_cur_sel_fg
+                                \ color_win_dir color_win_fg
+                                \ color_win_inactive_cur_sel_bg
+                                \ color_win_inactive_cur_sel_fg
+                                \ color_win_inactive_sel_bg
+                                \ color_win_inactive_sel_fg
+                                \ color_win_sel_bg color_win_sel_fg
+                                \ color_win_title_bg color_win_title_fg
+                                \ nextgroup=cmusrcOptEqColor
+
+syn match   cmusrcOptEqColor    contained display '='
+                                \ nextgroup=@cmusrcOptColor
+
+syn cluster cmusrcOptColor      contains=cmusrcOptColorName,cmusrcOptColorValue
+
+syn keyword cmusrcOptColorName  contained default black red green yellow blue
+                                \ magenta cyan gray darkgray lightred lightred
+                                \ lightgreen lightyellow lightblue lightmagenta
+                                \ lightcyan white
+
+syn match   cmusrcOptColorValue contained display
+                        \ '-1\|0*\%(\d\|[1-9]\d\|1\d\d\|2\%([0-4]\d\|5[0-5]\)\)'
+
+syn keyword cmusrcOption        contained id3_default_charset output_plugin
+                                \ status_display_program
+                                \ nextgroup=cmusrcOptEqString
+
+syn match   cmusrcOption        contained
+                    \ '\%(dsp\|mixer\)\.\%(alsa\|oss\|sun\)\.\%(channel\|device\)'
+                    \ nextgroup=cmusrcOptEqString
+
+syn match   cmusrcOption        contained
+                    \ 'dsp\.ao\.\%(buffer_size\|driver\|wav_counter\|wav_dir\)'
+                    \ nextgroup=cmusrcOptEqString
+
+syn match   cmusrcOptEqString   contained display '='
+                                \ nextgroup=cmusrcOptString
+
+syn match   cmusrcOptString     contained display '.\+'
+
+syn keyword cmusrcOption        contained lib_sort pl_sort
+                                \ nextgroup=cmusrcOptEqSortKeys
+
+syn match   cmusrcOptEqSortKeys contained display '='
+                                \ nextgroup=cmusrcOptSortKeys
+
+syn keyword cmusrcOptSortKeys   contained artist album title tracknumber
+                                \ discnumber date genre filename
+                                \ nextgroup=cmusrcOptSortKeys
+                                \ skipwhite
+
+syn keyword cmusrcKeyword       contained showbind
+                                \ nextgroup=cmusrcSBindContext
+                                \ skipwhite
+
+syn keyword cmusrcSBindContext  contained common library playlist queue
+                                \ browser filters
+                                \ nextgroup=cmusrcSBindKey
+                                \ skipwhite
+
+syn match   cmusrcSBindKey      contained display '\S\+'
+
+syn keyword cmusrcKeyword       contained toggle
+                                \ nextgroup=cmusrcTogglableOpt
+                                \ skipwhite
+
+syn keyword cmusrcTogglableOpt  contained auto_reshuffle aaa_mode
+                                \ confirm_run continue play_library play_sorted
+                                \ repeat show_hidden show_remaining_time shuffle
+
+syn keyword cmusrcKeyword       contained unbind
+                                \ nextgroup=cmusrcUnbindSwitches,
+                                \           cmusrcSBindContext
+                                \ skipwhite
+
+syn match   cmusrcUnbindSwitches  contained display '-[f]'
+                                  \ nextgroup=cmusrcSBindContext
+                                  \ skipwhite
+
+syn keyword cmusrcKeyword       contained view
+                                \ nextgroup=cmusrcView
+                                \ skipwhite
+
+syn keyword cmusrcView          contained library playlist queue browser filters
+syn match   cmusrcView          contained display '[1-6]'
+
+syn keyword cmusrcKeyword       contained vol
+                                \ nextgroup=cmusrcVolume1
+                                \ skipwhite
+
+syn match   cmusrcVolume1       contained display '[+-]\=\d\+%'
+                                \ nextgroup=cmusrcVolume2
+                                \ skipwhite
+
+syn match   cmusrcVolume2       contained display '[+-]\=\d\+%'
+
+hi def link cmusrcTodo            Todo
+hi def link cmusrcComment         Comment
+hi def link cmusrcKeyword         Keyword
+hi def link cmusrcSwitches        Special
+hi def link cmusrcAddSwitches     cmusrcSwitches
+hi def link cmusrcURI             Normal
+hi def link cmusrcBindSwitches    cmusrcSwitches
+hi def link cmusrcContext         Type
+hi def link cmusrcBindContext     cmusrcContext
+hi def link cmusrcKey             String
+hi def link cmusrcBindKey         cmusrcKey
+hi def link cmusrcDirectory       Normal
+hi def link cmusrcClearSwitches   cmusrcSwitches
+hi def link cmusrcFSetName        PreProc
+hi def link cmusrcEq              Normal
+hi def link cmusrcFSetEq          cmusrcEq
+hi def link cmusrcFilterExpr      Normal
+hi def link cmusrcLoadSwitches    cmusrcSwitches
+hi def link cmusrcSaveSwitches    cmusrcSwitches
+hi def link cmusrcFile            Normal
+hi def link cmusrcSeekOffset      Number
+hi def link cmusrcOption          PreProc
+hi def link cmusrcSetTest         Normal
+hi def link cmusrcOptBoolean      Boolean
+hi def link cmusrcOptEqAAA        cmusrcEq
+hi def link cmusrcOptAAA          Identifier
+hi def link cmusrcOptEqNumber     cmusrcEq
+hi def link cmusrcOptNumber       Number
+hi def link cmusrcOptEqFormat     cmusrcEq
+hi def link cmusrcOptFormat       String
+hi def link cmusrcFormatSpecial   SpecialChar
+hi def link cmusrcOptEqColor      cmusrcEq
+hi def link cmusrcOptColor        Normal
+hi def link cmusrcOptColorName    cmusrcOptColor
+hi def link cmusrcOptColorValue   cmusrcOptColor
+hi def link cmusrcOptEqString     cmusrcEq
+hi def link cmusrcOptString       Normal
+hi def link cmusrcOptEqSortKeys   cmusrcEq
+hi def link cmusrcOptSortKeys     Identifier
+hi def link cmusrcSBindContext    cmusrcContext
+hi def link cmusrcSBindKey        cmusrcKey
+hi def link cmusrcTogglableOpt    cmusrcOption
+hi def link cmusrcUnbindSwitches  cmusrcSwitches
+hi def link cmusrcView            Normal
+hi def link cmusrcVolume1         Number
+hi def link cmusrcVolume2         Number
+
+let b:current_syntax = "cmusrc"
+
+let &cpo = s:cpo_save
+unlet s:cpo_save
--- /dev/null
+++ b/lib/vimfiles/syntax/cobol.vim
@@ -1,0 +1,209 @@
+" Vim syntax file
+" Language:   COBOL
+" Maintainer: Tim Pope <vimNOSPAM@tpope.info>
+"     (formerly Davyd Ondrejko <vondraco@columbus.rr.com>)
+"     (formerly Sitaram Chamarty <sitaram@diac.com> and
+"		    James Mitchell <james_mitchell@acm.org>)
+" $Id: cobol.vim,v 1.2 2007/05/05 18:23:43 vimboss Exp $
+
+" For version 5.x: Clear all syntax items
+" For version 6.x: Quit when a syntax file was already loaded
+if version < 600
+  syntax clear
+elseif exists("b:current_syntax")
+  finish
+endif
+
+" MOST important - else most of the keywords wont work!
+if version < 600
+  set isk=@,48-57,-
+else
+  setlocal isk=@,48-57,-
+endif
+
+syn case ignore
+
+syn cluster cobolStart      contains=cobolAreaA,cobolAreaB,cobolComment,cobolCompiler
+syn cluster cobolAreaA      contains=cobolParagraph,cobolSection,cobolDivision
+"syn cluster cobolAreaB      contains=
+syn cluster cobolAreaAB     contains=cobolLine
+syn cluster cobolLine       contains=cobolReserved
+syn match   cobolMarker     "^\%( \{,5\}[^ ]\)\@=.\{,6}" nextgroup=@cobolStart
+syn match   cobolSpace      "^ \{6\}"  nextgroup=@cobolStart
+syn match   cobolAreaA      " \{1,4\}"  contained nextgroup=@cobolAreaA,@cobolAreaAB
+syn match   cobolAreaB      " \{5,\}\|- *" contained nextgroup=@cobolAreaB,@cobolAreaAB
+syn match   cobolComment    "[/*C].*$" contained
+syn match   cobolCompiler   "$.*$"     contained
+syn match   cobolLine       ".*$"      contained contains=cobolReserved,@cobolLine
+
+syn match   cobolDivision       "[A-Z][A-Z0-9-]*[A-Z0-9]\s\+DIVISION\."he=e-1 contained contains=cobolDivisionName
+syn keyword cobolDivisionName   contained IDENTIFICATION ENVIRONMENT DATA PROCEDURE
+syn match   cobolSection        "[A-Z][A-Z0-9-]*[A-Z0-9]\s\+SECTION\."he=e-1  contained contains=cobolSectionName
+syn keyword cobolSectionName    contained CONFIGURATION INPUT-OUTPUT FILE WORKING-STORAGE LOCAL-STORAGE LINKAGE
+syn match   cobolParagraph      "\a[A-Z0-9-]*[A-Z0-9]\.\|\d[A-Z0-9-]*[A-Z]\."he=e-1             contained contains=cobolParagraphName
+syn keyword cobolParagraphName  contained PROGRAM-ID SOURCE-COMPUTER OBJECT-COMPUTER SPECIAL-NAMES FILE-CONTROL I-O-CONTROL
+
+
+"syn match cobolKeys "^\a\{1,6\}" contains=cobolReserved
+syn keyword cobolReserved contained ACCEPT ACCESS ADD ADDRESS ADVANCING AFTER ALPHABET ALPHABETIC
+syn keyword cobolReserved contained ALPHABETIC-LOWER ALPHABETIC-UPPER ALPHANUMERIC ALPHANUMERIC-EDITED ALS
+syn keyword cobolReserved contained ALTERNATE AND ANY ARE AREA AREAS ASCENDING ASSIGN AT AUTHOR BEFORE BINARY
+syn keyword cobolReserved contained BLANK BLOCK BOTTOM BY CANCEL CBLL CD CF CH CHARACTER CHARACTERS CLASS
+syn keyword cobolReserved contained CLOCK-UNITS CLOSE COBOL CODE CODE-SET COLLATING COLUMN COMMA COMMON
+syn keyword cobolReserved contained COMMUNICATIONS COMPUTATIONAL COMPUTE CONTENT CONTINUE
+syn keyword cobolReserved contained CONTROL CONVERTING CORR CORRESPONDING COUNT CURRENCY DATE DATE-COMPILED
+syn keyword cobolReserved contained DATE-WRITTEN DAY DAY-OF-WEEK DE DEBUG-CONTENTS DEBUG-ITEM DEBUG-LINE
+syn keyword cobolReserved contained DEBUG-NAME DEBUG-SUB-1 DEBUG-SUB-2 DEBUG-SUB-3 DEBUGGING DECIMAL-POINT
+syn keyword cobolReserved contained DELARATIVES DELETE DELIMITED DELIMITER DEPENDING DESCENDING DESTINATION
+syn keyword cobolReserved contained DETAIL DISABLE DISPLAY DIVIDE DIVISION DOWN DUPLICATES DYNAMIC EGI ELSE EMI
+syn keyword cobolReserved contained ENABLE END-ADD END-COMPUTE END-DELETE END-DIVIDE END-EVALUATE END-IF
+syn keyword cobolReserved contained END-MULTIPLY END-OF-PAGE END-READ END-RECEIVE END-RETURN
+syn keyword cobolReserved contained END-REWRITE END-SEARCH END-START END-STRING END-SUBTRACT END-UNSTRING
+syn keyword cobolReserved contained END-WRITE EQUAL ERROR ESI EVALUATE EVERY EXCEPTION EXIT
+syn keyword cobolReserved contained EXTEND EXTERNAL FALSE FD FILLER FINAL FIRST FOOTING FOR FROM
+syn keyword cobolReserved contained GENERATE GIVING GLOBAL GREATER GROUP HEADING HIGH-VALUE HIGH-VALUES I-O
+syn keyword cobolReserved contained IN INDEX INDEXED INDICATE INITIAL INITIALIZE
+syn keyword cobolReserved contained INITIATE INPUT INSPECT INSTALLATION INTO IS JUST
+syn keyword cobolReserved contained JUSTIFIED KEY LABEL LAST LEADING LEFT LENGTH LOCK MEMORY
+syn keyword cobolReserved contained MERGE MESSAGE MODE MODULES MOVE MULTIPLE MULTIPLY NATIVE NEGATIVE NEXT NO NOT
+syn keyword cobolReserved contained NUMBER NUMERIC NUMERIC-EDITED OCCURS OF OFF OMITTED ON OPEN
+syn keyword cobolReserved contained OPTIONAL OR ORDER ORGANIZATION OTHER OUTPUT OVERFLOW PACKED-DECIMAL PADDING
+syn keyword cobolReserved contained PAGE PAGE-COUNTER PERFORM PF PH PIC PICTURE PLUS POINTER POSITION POSITIVE
+syn keyword cobolReserved contained PRINTING PROCEDURES PROCEDD PROGRAM PURGE QUEUE QUOTES
+syn keyword cobolReserved contained RANDOM RD READ RECEIVE RECORD RECORDS REDEFINES REEL REFERENCE REFERENCES
+syn keyword cobolReserved contained RELATIVE RELEASE REMAINDER REMOVAL REPLACE REPLACING REPORT REPORTING
+syn keyword cobolReserved contained REPORTS RERUN RESERVE RESET RETURN RETURNING REVERSED REWIND REWRITE RF RH
+syn keyword cobolReserved contained RIGHT ROUNDED RUN SAME SD SEARCH SECTION SECURITY SEGMENT SEGMENT-LIMITED
+syn keyword cobolReserved contained SELECT SEND SENTENCE SEPARATE SEQUENCE SEQUENTIAL SET SIGN SIZE SORT
+syn keyword cobolReserved contained SORT-MERGE SOURCE STANDARD
+syn keyword cobolReserved contained STANDARD-1 STANDARD-2 START STATUS STOP STRING SUB-QUEUE-1 SUB-QUEUE-2
+syn keyword cobolReserved contained SUB-QUEUE-3 SUBTRACT SUM SUPPRESS SYMBOLIC SYNC SYNCHRONIZED TABLE TALLYING
+syn keyword cobolReserved contained TAPE TERMINAL TERMINATE TEST TEXT THAN THEN THROUGH THRU TIME TIMES TO TOP
+syn keyword cobolReserved contained TRAILING TRUE TYPE UNIT UNSTRING UNTIL UP UPON USAGE USE USING VALUE VALUES
+syn keyword cobolReserved contained VARYING WHEN WITH WORDS WRITE
+syn match   cobolReserved contained "\<CONTAINS\>"
+syn match   cobolReserved contained "\<\(IF\|INVALID\|END\|EOP\)\>"
+syn match   cobolReserved contained "\<ALL\>"
+
+syn cluster cobolLine     add=cobolConstant,cobolNumber,cobolPic
+syn keyword cobolConstant SPACE SPACES NULL ZERO ZEROES ZEROS LOW-VALUE LOW-VALUES
+
+syn match   cobolNumber       "\<-\=\d*\.\=\d\+\>" contained
+syn match   cobolPic		"\<S*9\+\>" contained
+syn match   cobolPic		"\<$*\.\=9\+\>" contained
+syn match   cobolPic		"\<Z*\.\=9\+\>" contained
+syn match   cobolPic		"\<V9\+\>" contained
+syn match   cobolPic		"\<9\+V\>" contained
+syn match   cobolPic		"\<-\+[Z9]\+\>" contained
+syn match   cobolTodo		"todo" contained containedin=cobolComment
+
+" For MicroFocus or other inline comments, include this line.
+" syn region  cobolComment      start="*>" end="$" contains=cobolTodo,cobolMarker
+
+syn match   cobolBadLine      "[^ D\*$/-].*" contained
+" If comment mark somehow gets into column past Column 7.
+syn match   cobolBadLine      "\s\+\*.*" contained
+syn cluster cobolStart        add=cobolBadLine
+
+
+syn keyword cobolGoTo		GO GOTO
+syn keyword cobolCopy		COPY
+
+" cobolBAD: things that are BAD NEWS!
+syn keyword cobolBAD		ALTER ENTER RENAMES
+
+syn cluster cobolLine       add=cobolGoTo,cobolCopy,cobolBAD,cobolWatch,cobolEXECs
+
+" cobolWatch: things that are important when trying to understand a program
+syn keyword cobolWatch		OCCURS DEPENDING VARYING BINARY COMP REDEFINES
+syn keyword cobolWatch		REPLACING RUN
+syn match   cobolWatch		"COMP-[123456XN]"
+
+syn keyword cobolEXECs		EXEC END-EXEC
+
+
+syn cluster cobolAreaA      add=cobolDeclA
+syn cluster cobolAreaAB     add=cobolDecl
+syn match   cobolDeclA      "\(0\=1\|77\|78\) " contained nextgroup=cobolLine
+syn match   cobolDecl		"[1-4]\d " contained nextgroup=cobolLine
+syn match   cobolDecl		"0\=[2-9] " contained nextgroup=cobolLine
+syn match   cobolDecl		"66 " contained nextgroup=cobolLine
+
+syn match   cobolWatch		"88 " contained nextgroup=cobolLine
+
+"syn match   cobolBadID		"\k\+-\($\|[^-A-Z0-9]\)" contained
+
+syn cluster cobolLine       add=cobolCALLs,cobolString,cobolCondFlow
+syn keyword cobolCALLs		CALL END-CALL CANCEL GOBACK PERFORM END-PERFORM INVOKE
+syn match   cobolCALLs		"EXIT \+PROGRAM"
+syn match   cobolExtras       /\<VALUE \+\d\+\./hs=s+6,he=e-1
+
+syn match   cobolString       /"[^"]*\("\|$\)/
+syn match   cobolString       /'[^']*\('\|$\)/
+
+"syn region  cobolLine        start="^.\{6}[ D-]" end="$" contains=ALL
+syn match   cobolIndicator   "\%7c[D-]" contained
+
+if exists("cobol_legacy_code")
+  syn region  cobolCondFlow     contains=ALLBUT,cobolLine start="\<\(IF\|INVALID\|END\|EOP\)\>" skip=/\('\|"\)[^"]\{-}\("\|'\|$\)/ end="\." keepend
+endif
+
+" many legacy sources have junk in columns 1-6: must be before others
+" Stuff after column 72 is in error - must be after all other "match" entries
+if exists("cobol_legacy_code")
+    syn match   cobolBadLine      "\%73c.*" containedin=ALLBUT,cobolComment
+else
+    syn match   cobolBadLine      "\%73c.*" containedin=ALL
+endif
+
+" Define the default highlighting.
+" For version 5.7 and earlier: only when not done already
+" For version 5.8 and later: only when an item doesn't have highlighting yet
+if version >= 508 || !exists("did_cobol_syntax_inits")
+  if version < 508
+    let did_cobol_syntax_inits = 1
+    command -nargs=+ HiLink hi link <args>
+  else
+    command -nargs=+ HiLink hi def link <args>
+  endif
+
+  HiLink cobolBAD      Error
+  HiLink cobolBadID    Error
+  HiLink cobolBadLine  Error
+  if exists("g:cobol_legacy_code")
+      HiLink cobolMarker   Comment
+  else
+      HiLink cobolMarker   Error
+  endif
+  HiLink cobolCALLs    Function
+  HiLink cobolComment  Comment
+  HiLink cobolKeys     Comment
+  HiLink cobolAreaB    Special
+  HiLink cobolCompiler PreProc
+  HiLink cobolCondFlow Special
+  HiLink cobolCopy     PreProc
+  HiLink cobolDeclA    cobolDecl
+  HiLink cobolDecl     Type
+  HiLink cobolExtras   Special
+  HiLink cobolGoTo     Special
+  HiLink cobolConstant Constant
+  HiLink cobolNumber   Constant
+  HiLink cobolPic      Constant
+  HiLink cobolReserved Statement
+  HiLink cobolDivision Label
+  HiLink cobolSection  Label
+  HiLink cobolParagraph Label
+  HiLink cobolDivisionName  Keyword
+  HiLink cobolSectionName   Keyword
+  HiLink cobolParagraphName Keyword
+  HiLink cobolString   Constant
+  HiLink cobolTodo     Todo
+  HiLink cobolWatch    Special
+  HiLink cobolIndicator Special
+
+  delcommand HiLink
+endif
+
+let b:current_syntax = "cobol"
+
+" vim: ts=6 nowrap
--- /dev/null
+++ b/lib/vimfiles/syntax/colortest.vim
@@ -1,0 +1,74 @@
+" Vim script for testing colors
+" Maintainer:	Bram Moolenaar <Bram@vim.org>
+" Contributors:	Rafael Garcia-Suarez, Charles Campbell
+" Last Change:	2006 Feb 20
+
+" edit this file, then do ":source %", and check if the colors match
+
+" black		black_on_white				white_on_black
+"				black_on_black		black_on_black
+" darkred	darkred_on_white			white_on_darkred
+"				darkred_on_black	black_on_darkred
+" darkgreen	darkgreen_on_white			white_on_darkgreen
+"				darkgreen_on_black	black_on_darkgreen
+" brown		brown_on_white				white_on_brown
+"				brown_on_black		black_on_brown
+" darkblue	darkblue_on_white			white_on_darkblue
+"				darkblue_on_black	black_on_darkblue
+" darkmagenta	darkmagenta_on_white			white_on_darkmagenta
+"				darkmagenta_on_black	black_on_darkmagenta
+" darkcyan	darkcyan_on_white			white_on_darkcyan
+"				darkcyan_on_black	black_on_darkcyan
+" lightgray	lightgray_on_white			white_on_lightgray
+"				lightgray_on_black	black_on_lightgray
+" darkgray	darkgray_on_white			white_on_darkgray
+"				darkgray_on_black	black_on_darkgray
+" red		red_on_white				white_on_red
+"				red_on_black		black_on_red
+" green		green_on_white				white_on_green
+"				green_on_black		black_on_green
+" yellow	yellow_on_white				white_on_yellow
+"				yellow_on_black		black_on_yellow
+" blue		blue_on_white				white_on_blue
+"				blue_on_black		black_on_blue
+" magenta	magenta_on_white			white_on_magenta
+"				magenta_on_black	black_on_magenta
+" cyan		cyan_on_white				white_on_cyan
+"				cyan_on_black		black_on_cyan
+" white		white_on_white				white_on_white
+"				white_on_black		black_on_white
+" grey		grey_on_white				white_on_grey
+"				grey_on_black		black_on_grey
+" lightred	lightred_on_white			white_on_lightred
+"				lightred_on_black	black_on_lightred
+" lightgreen	lightgreen_on_white			white_on_lightgreen
+"				lightgreen_on_black	black_on_lightgreen
+" lightyellow	lightyellow_on_white			white_on_lightyellow
+"				lightyellow_on_black	black_on_lightyellow
+" lightblue	lightblue_on_white			white_on_lightblue
+"				lightblue_on_black	black_on_lightblue
+" lightmagenta	lightmagenta_on_white			white_on_lightmagenta
+"				lightmagenta_on_black	black_on_lightmagenta
+" lightcyan	lightcyan_on_white			white_on_lightcyan
+"				lightcyan_on_black	black_on_lightcyan
+
+" Open this file in a window if it isn't edited yet.
+" Use the current window if it's empty.
+if expand('%:p') != expand('<sfile>:p')
+  if &mod || line('$') != 1 || getline(1) != ''
+    exe "new " . expand('<sfile>')
+  else
+    exe "edit " . expand('<sfile>')
+  endif
+endif
+
+syn clear
+8
+while search("_on_", "W") < 55
+  let col1 = substitute(expand("<cword>"), '\(\a\+\)_on_\a\+', '\1', "")
+  let col2 = substitute(expand("<cword>"), '\a\+_on_\(\a\+\)', '\1', "")
+  exec 'hi col_'.col1.'_'.col2.' ctermfg='.col1.' guifg='.col1.' ctermbg='.col2.' guibg='.col2
+  exec 'syn keyword col_'.col1.'_'.col2.' '.col1.'_on_'.col2
+endwhile
+8,54g/^" \a/exec 'hi col_'.expand("<cword>").' ctermfg='.expand("<cword>").' guifg='.expand("<cword>")| exec 'syn keyword col_'.expand("<cword>")." ".expand("<cword>")
+nohlsearch
--- /dev/null
+++ b/lib/vimfiles/syntax/conaryrecipe.vim
@@ -1,0 +1,99 @@
+" Vim syntax file
+" Language:	Conary Recipe
+" Maintainer:	rPath Inc <http://www.rpath.com>
+" Updated:	2007-05-07
+
+if exists("b:current_syntax")
+  finish
+endif
+
+runtime! syntax/python.vim
+syn keyword conarySFunction	mainDir addAction addSource addArchive addPatch
+syn keyword conarySFunction	addRedirect addSvnSnapshot addMercurialSnapshot
+syn keyword conarySFunction	addCvsSnapshot
+
+syn keyword conaryGFunction     add addAll addNewGroup addReference createGroup
+syn keyword conaryGFunction     addNewGroup startGroup remove removeComponents
+syn keyword conaryGFunction     replace setByDefault setDefaultGroup 
+syn keyword conaryGFunction     setLabelPath addCopy setSearchPath
+
+syn keyword conaryBFunction 	Run Automake Configure ManualConfigure 
+syn keyword conaryBFunction 	Make MakeParallelSubdir MakeInstall
+syn keyword conaryBFunction 	MakePathsInstall CompilePython
+syn keyword conaryBFunction 	Ldconfig Desktopfile Environment SetModes
+syn keyword conaryBFunction 	Install Copy Move Symlink Link Remove Doc
+syn keyword conaryBFunction 	Create MakeDirs disableParallelMake
+syn keyword conaryBFunction 	ConsoleHelper Replace SGMLCatalogEntry
+syn keyword conaryBFunction 	XInetdService XMLCatalogEntry TestSuite
+syn keyword conaryBFunction     PythonSetup
+
+syn keyword conaryPFunction 	NonBinariesInBindirs FilesInMandir 
+syn keyword conaryPFunction 	ImproperlyShared CheckSonames CheckDestDir
+syn keyword conaryPFunction 	ComponentSpec PackageSpec 
+syn keyword conaryPFunction 	Config InitScript GconfSchema SharedLibrary
+syn keyword conaryPFunction 	ParseManifest MakeDevices DanglingSymlinks
+syn keyword conaryPFunction 	AddModes WarnWriteable IgnoredSetuid
+syn keyword conaryPFunction 	Ownership ExcludeDirectories
+syn keyword conaryPFunction 	BadFilenames BadInterpreterPaths ByDefault
+syn keyword conaryPFunction 	ComponentProvides ComponentRequires Flavor
+syn keyword conaryPFunction 	EnforceConfigLogBuildRequirements Group
+syn keyword conaryPFunction 	EnforceSonameBuildRequirements InitialContents
+syn keyword conaryPFunction 	FilesForDirectories LinkCount
+syn keyword conaryPFunction 	MakdeDevices NonMultilibComponent ObsoletePaths
+syn keyword conaryPFunction 	NonMultilibDirectories NonUTF8Filenames TagSpec
+syn keyword conaryPFunction 	Provides RequireChkconfig Requires TagHandler
+syn keyword conaryPFunction 	TagDescription Transient User UtilizeGroup
+syn keyword conaryPFunction 	WorldWritableExecutables UtilizeUser
+syn keyword conaryPFunction 	WarnWritable Strip CheckDesktopFiles
+
+" Most destdirPolicy aren't called from recipes, except for these
+syn keyword conaryPFunction     AutoDoc RemoveNonPackageFiles TestSuiteFiles
+syn keyword conaryPFunction     TestSuiteLinks
+
+syn match   conaryMacro		"%(\w\+)[sd]" contained
+syn match   conaryBadMacro	"%(\w*)[^sd]" contained " no final marker
+syn keyword conaryArches	contained x86 x86_64 alpha ia64 ppc ppc64 s390
+syn keyword conaryArches	contained sparc sparc64
+syn keyword conarySubArches	contained sse2 3dnow 3dnowext cmov i486 i586
+syn keyword conarySubArches	contained i686 mmx mmxext nx sse sse2
+syn keyword conaryBad		RPM_BUILD_ROOT EtcConfig InstallBucket subDir subdir 
+syn keyword conaryBad		RPM_OPT_FLAGS 
+syn cluster conaryArchFlags 	contains=conaryArches,conarySubArches
+syn match   conaryArch		"Arch\.[a-z0-9A-Z]\+" contains=conaryArches,conarySubArches
+syn match   conaryArch		"Arch\.[a-z0-9A-Z]\+" contains=conaryArches,conarySubArches
+syn keyword conaryKeywords	name buildRequires version clearBuildReqs
+syn keyword conaryUseFlag	contained pcre tcpwrappers gcj gnat selinux pam 
+syn keyword conaryUseFlag	contained bootstrap python perl 
+syn keyword conaryUseFlag	contained readline gdbm emacs krb builddocs 
+syn keyword conaryUseFlag	contained alternatives tcl tk X gtk gnome qt
+syn keyword conaryUseFlag	contained xfce gd ldap sasl pie desktop ssl kde
+syn keyword conaryUseFlag	contained slang netpbm nptl ipv6 buildtests
+syn keyword conaryUseFlag	contained ntpl xen dom0 domU
+syn match   conaryUse		"Use\.[a-z0-9A-Z]\+" contains=conaryUseFlag
+
+" strings
+syn region pythonString		matchgroup=Normal start=+[uU]\='+ end=+'+ skip=+\\\\\|\\'+ contains=pythonEscape,conaryMacro,conaryBadMacro
+syn region pythonString		matchgroup=Normal start=+[uU]\="+ end=+"+ skip=+\\\\\|\\"+ contains=pythonEscape,conaryMacro,conaryBadMacro
+syn region pythonString		matchgroup=Normal start=+[uU]\="""+ end=+"""+ contains=pythonEscape,conaryMacro,conaryBadMacro
+syn region pythonString		matchgroup=Normal start=+[uU]\='''+ end=+'''+ contains=pythonEscape,conaryMacro,conaryBadMacro
+syn region pythonRawString	matchgroup=Normal start=+[uU]\=[rR]'+ end=+'+ skip=+\\\\\|\\'+ contains=conaryMacro,conaryBadMacro
+syn region pythonRawString	matchgroup=Normal start=+[uU]\=[rR]"+ end=+"+ skip=+\\\\\|\\"+ contains=conaryMacro,conaryBadMacro
+syn region pythonRawString	matchgroup=Normal start=+[uU]\=[rR]"""+ end=+"""+ contains=conaryMacro,conaryBadMacro
+syn region pythonRawString	matchgroup=Normal start=+[uU]\=[rR]'''+ end=+'''+ contains=conaryMacro,conaryBadMacro
+
+hi def link conaryMacro			Special
+hi def link conaryrecipeFunction	Function
+hi def link conaryError			Error
+hi def link conaryBFunction		conaryrecipeFunction
+hi def link conaryGFunction        	conaryrecipeFunction
+hi def link conarySFunction		Operator
+hi def link conaryPFunction		Typedef
+hi def link conaryFlags			PreCondit
+hi def link conaryArches		Special
+hi def link conarySubArches		Special
+hi def link conaryBad			conaryError
+hi def link conaryBadMacro		conaryError
+hi def link conaryKeywords		Special
+hi def link conaryUseFlag		Typedef
+
+let b:current_syntax = "conaryrecipe"
--- /dev/null
+++ b/lib/vimfiles/syntax/conf.vim
@@ -1,0 +1,26 @@
+" Vim syntax file
+" Language:	generic configure file
+" Maintainer:	Bram Moolenaar <Bram@vim.org>
+" Last Change:	2005 Jun 20
+
+" Quit when a (custom) syntax file was already loaded
+if exists("b:current_syntax")
+  finish
+endif
+
+syn keyword	confTodo	contained TODO FIXME XXX
+" Avoid matching "text#text", used in /etc/disktab and /etc/gettytab
+syn match	confComment	"^#.*" contains=confTodo
+syn match	confComment	"\s#.*"ms=s+1 contains=confTodo
+syn region	confString	start=+"+ skip=+\\\\\|\\"+ end=+"+ oneline
+syn region	confString	start=+'+ skip=+\\\\\|\\'+ end=+'+ oneline
+
+" Define the default highlighting.
+" Only used when an item doesn't have highlighting yet
+hi def link confComment	Comment
+hi def link confTodo	Todo
+hi def link confString	String
+
+let b:current_syntax = "conf"
+
+" vim: ts=8 sw=2
--- /dev/null
+++ b/lib/vimfiles/syntax/config.vim
@@ -1,0 +1,57 @@
+" Vim syntax file
+" Language:		configure.in script: M4 with sh
+" Maintainer:	Christian Hammesr <ch@lathspell.westend.com>
+" Last Change:	2001 May 09
+
+" Well, I actually even do not know much about m4. This explains why there
+" is probably very much missing here, yet !
+" But I missed a good hilighting when editing my GNU autoconf/automake
+" script, so I wrote this quick and dirty patch.
+
+
+" For version 5.x: Clear all syntax items
+" For version 6.x: Quit when a syntax file was already loaded
+if version < 600
+  syntax clear
+elseif exists("b:current_syntax")
+  finish
+endif
+
+" define the config syntax
+syn match   configdelimiter "[()\[\];,]"
+syn match   configoperator  "[=|&\*\+\<\>]"
+syn match   configcomment   "\(dnl.*\)\|\(#.*\)"
+syn match   configfunction  "\<[A-Z_][A-Z0-9_]*\>"
+syn match   confignumber    "[-+]\=\<\d\+\(\.\d*\)\=\>"
+syn keyword configkeyword   if then else fi test for in do done
+syn keyword configspecial   cat rm eval
+syn region  configstring    start=+"+ skip=+\\"+ end=+"+
+syn region  configstring    start=+`+ skip=+\\'+ end=+'+
+syn region  configstring    start=+`+ skip=+\\'+ end=+`+
+
+" Define the default highlighting.
+" For version 5.7 and earlier: only when not done already
+" For version 5.8 and later: only when an item doesn't have highlighting yet
+if version >= 508 || !exists("did_config_syntax_inits")
+  if version < 508
+    let did_config_syntax_inits = 1
+    command -nargs=+ HiLink hi link <args>
+  else
+    command -nargs=+ HiLink hi def link <args>
+  endif
+
+  HiLink configdelimiter Delimiter
+  HiLink configoperator  Operator
+  HiLink configcomment   Comment
+  HiLink configfunction  Function
+  HiLink confignumber    Number
+  HiLink configkeyword   Keyword
+  HiLink configspecial   Special
+  HiLink configstring    String
+
+  delcommand HiLink
+endif
+
+let b:current_syntax = "config"
+
+" vim: ts=4
--- /dev/null
+++ b/lib/vimfiles/syntax/context.vim
@@ -1,0 +1,108 @@
+" Vim syntax file
+" Language:         ConTeXt typesetting engine
+" Maintainer:       Nikolai Weibull <now@bitwi.se>
+" Latest Revision:  2006-08-10
+
+if exists("b:current_syntax")
+  finish
+endif
+
+runtime! syntax/plaintex.vim
+unlet b:current_syntax
+
+let s:cpo_save = &cpo
+set cpo&vim
+
+if !exists('g:context_include')
+  let g:context_include = ['mp', 'javascript', 'xml']
+endif
+
+syn spell   toplevel
+
+syn match   contextBlockDelim display '\\\%(start\|stop\)\a\+'
+                              \ contains=@NoSpell
+
+syn region  contextEscaped    display matchgroup=contextPreProc
+                              \ start='\\type\z(\A\)' end='\z1'
+syn region  contextEscaped    display matchgroup=contextPreProc
+                              \ start='\\type\={' end='}'
+syn region  contextEscaped    display matchgroup=contextPreProc
+                              \ start='\\type\=<<' end='>>'
+syn region  contextEscaped    matchgroup=contextPreProc
+                              \ start='\\start\z(\a*\%(typing\|typen\)\)'
+                              \ end='\\stop\z1' contains=plaintexComment keepend
+syn region  contextEscaped    display matchgroup=contextPreProc
+                              \ start='\\\h\+Type{' end='}'
+syn region  contextEscaped    display matchgroup=contextPreProc
+                              \ start='\\Typed\h\+{' end='}'
+
+syn match   contextBuiltin    display contains=@NoSpell
+      \ '\\\%(unprotect\|protect\|unexpanded\)' 
+
+syn match   contextPreProc    '^\s*\\\%(start\|stop\)\=\%(component\|environment\|project\|product\).*$'
+                              \ contains=@NoSpell
+
+if index(g:context_include, 'mp') != -1
+  syn include @mpTop          syntax/mp.vim
+  unlet b:current_syntax
+
+  syn region  contextMPGraphic  transparent matchgroup=contextBlockDelim
+                                \ start='\\start\z(\a*MPgraphic\|MP\%(page\|inclusions\|run\)\).*'
+                                \ end='\\stop\z1'
+                                \ contains=@mpTop
+endif
+
+" TODO: also need to implement this for \\typeC or something along those
+" lines.
+function! s:include_syntax(name, group)
+  if index(g:context_include, a:name) != -1
+    execute 'syn include @' . a:name . 'Top' 'syntax/' . a:name . '.vim'
+    unlet b:current_syntax
+    execute 'syn region context' . a:group . 'Code'
+          \ 'transparent matchgroup=contextBlockDelim'
+          \ 'start=+\\start' . a:group . '+ end=+\\stop' . a:group . '+'
+          \ 'contains=@' . a:name . 'Top'
+  endif
+endfunction
+
+call s:include_syntax('c', 'C')
+call s:include_syntax('ruby', 'Ruby')
+call s:include_syntax('javascript', 'JS')
+call s:include_syntax('xml', 'XML')
+
+syn match   contextSectioning '\\chapter\>' contains=@NoSpell
+syn match   contextSectioning '\\\%(sub\)*section\>' contains=@NoSpell
+
+syn match   contextSpecial    '\\crlf\>\|\\par\>\|-\{2,3}\||[<>/]\=|'
+                              \ contains=@NoSpell
+syn match   contextSpecial    /\\[`'"]/
+syn match   contextSpecial    +\\char\%(\d\{1,3}\|'\o\{1,3}\|"\x\{1,2}\)\>+
+                              \ contains=@NoSpell
+syn match   contextSpecial    '\^\^.'
+syn match   contextSpecial    '`\%(\\.\|\^\^.\|.\)'
+
+syn match   contextStyle      '\\\%(em\|ss\|hw\|cg\|mf\)\>'
+                              \ contains=@NoSpell
+syn match   contextFont       '\\\%(CAP\|Cap\|cap\|Caps\|kap\|nocap\)\>'
+                              \ contains=@NoSpell
+syn match   contextFont       '\\\%(Word\|WORD\|Words\|WORDS\)\>'
+                              \ contains=@NoSpell
+syn match   contextFont       '\\\%(vi\{1,3}\|ix\|xi\{0,2}\)\>'
+                              \ contains=@NoSpell
+syn match   contextFont       '\\\%(tf\|b[si]\|s[cl]\|os\)\%(xx\|[xabcd]\)\=\>'
+                              \ contains=@NoSpell
+
+hi def link contextBlockDelim Keyword
+hi def link contextBuiltin    Keyword
+hi def link contextDelimiter  Delimiter
+hi def link contextPreProc    PreProc
+hi def link contextSectioning PreProc
+hi def link contextSpecial    Special
+hi def link contextType       Type
+hi def link contextStyle      contextType
+hi def link contextFont       contextType
+
+let b:current_syntax = "context"
+
+let &cpo = s:cpo_save
+unlet s:cpo_save
--- /dev/null
+++ b/lib/vimfiles/syntax/cpp.vim
@@ -1,0 +1,62 @@
+" Vim syntax file
+" Language:	C++
+" Maintainer:	Ken Shan <ccshan@post.harvard.edu>
+" Last Change:	2002 Jul 15
+
+" For version 5.x: Clear all syntax items
+" For version 6.x: Quit when a syntax file was already loaded
+if version < 600
+  syntax clear
+elseif exists("b:current_syntax")
+  finish
+endif
+
+" Read the C syntax to start with
+if version < 600
+  so <sfile>:p:h/c.vim
+else
+  runtime! syntax/c.vim
+  unlet b:current_syntax
+endif
+
+" C++ extentions
+syn keyword cppStatement	new delete this friend using
+syn keyword cppAccess		public protected private
+syn keyword cppType		inline virtual explicit export bool wchar_t
+syn keyword cppExceptions	throw try catch
+syn keyword cppOperator		operator typeid
+syn keyword cppOperator		and bitor or xor compl bitand and_eq or_eq xor_eq not not_eq
+syn match cppCast		"\<\(const\|static\|dynamic\|reinterpret\)_cast\s*<"me=e-1
+syn match cppCast		"\<\(const\|static\|dynamic\|reinterpret\)_cast\s*$"
+syn keyword cppStorageClass	mutable
+syn keyword cppStructure	class typename template namespace
+syn keyword cppNumber		NPOS
+syn keyword cppBoolean		true false
+
+" The minimum and maximum operators in GNU C++
+syn match cppMinMax "[<>]?"
+
+" Default highlighting
+if version >= 508 || !exists("did_cpp_syntax_inits")
+  if version < 508
+    let did_cpp_syntax_inits = 1
+    command -nargs=+ HiLink hi link <args>
+  else
+    command -nargs=+ HiLink hi def link <args>
+  endif
+  HiLink cppAccess		cppStatement
+  HiLink cppCast		cppStatement
+  HiLink cppExceptions		Exception
+  HiLink cppOperator		Operator
+  HiLink cppStatement		Statement
+  HiLink cppType		Type
+  HiLink cppStorageClass	StorageClass
+  HiLink cppStructure		Structure
+  HiLink cppNumber		Number
+  HiLink cppBoolean		Boolean
+  delcommand HiLink
+endif
+
+let b:current_syntax = "cpp"
+
+" vim: ts=8
--- /dev/null
+++ b/lib/vimfiles/syntax/crm.vim
@@ -1,0 +1,41 @@
+" Vim syntax file
+" Language:         CRM114
+" Maintainer:       Nikolai Weibull <now@bitwi.se>
+" Latest Revision:  2006-04-19
+
+if exists("b:current_syntax")
+  finish
+endif
+
+let s:cpo_save = &cpo
+set cpo&vim
+
+syn keyword crmTodo       contained TODO FIXME XXX NOTE
+
+syn region  crmComment    display oneline start='#' end='\\#'
+                          \ contains=crmTodo,@Spell
+
+syn match   crmVariable   display ':[*#@]:[^:]\{-1,}:'
+
+syn match   crmSpecial    display '\\\%(x\x\x\|o\o\o\o\|[]nrtabvf0>)};/\\]\)'
+
+syn keyword crmStatement  insert noop accept alius alter classify eval exit
+syn keyword crmStatement  fail fault goto hash intersect isolate input learn
+syn keyword crmStatement  liaf match output syscall trap union window
+
+syn region  crmRegex      start='/' skip='\\/' end='/' contains=crmVariable
+
+syn match   crmLabel      display '^\s*:[[:graph:]]\+:'
+
+hi def link crmTodo       Todo
+hi def link crmComment    Comment
+hi def link crmVariable   Identifier
+hi def link crmSpecial    SpecialChar
+hi def link crmStatement  Statement
+hi def link crmRegex      String
+hi def link crmLabel      Label
+
+let b:current_syntax = "crm"
+
+let &cpo = s:cpo_save
+unlet s:cpo_save
--- /dev/null
+++ b/lib/vimfiles/syntax/crontab.vim
@@ -1,0 +1,79 @@
+" Vim syntax file
+" Language: crontab
+" Maintainer: David Necas (Yeti) <yeti@physics.muni.cz>
+" Original Maintainer: John Hoelzel johnh51@users.sourceforge.net
+" License: This file can be redistribued and/or modified under the same terms
+"   as Vim itself.
+" Filenames: /tmp/crontab.* used by "crontab -e"
+" URL: http://trific.ath.cx/Ftp/vim/syntax/crontab.vim
+" Last Change: 2006-04-20
+"
+" crontab line format:
+" Minutes   Hours   Days   Months   Days_of_Week   Commands # comments
+
+" For version 5.x: Clear all syntax items
+" For version 6.x: Quit when a syntax file was already loaded
+if version < 600
+  syntax clear
+elseif exists("b:current_syntax")
+  finish
+endif
+
+syntax match crontabMin "^\s*[-0-9/,.*]\+" nextgroup=crontabHr skipwhite
+syntax match crontabHr "\s[-0-9/,.*]\+" nextgroup=crontabDay skipwhite contained
+syntax match crontabDay "\s[-0-9/,.*]\+" nextgroup=crontabMnth skipwhite contained
+
+syntax match crontabMnth "\s[-a-z0-9/,.*]\+" nextgroup=crontabDow skipwhite contained
+syntax keyword crontabMnth12 contained jan feb mar apr may jun jul aug sep oct nov dec
+
+syntax match crontabDow "\s[-a-z0-9/,.*]\+" nextgroup=crontabCmd skipwhite contained
+syntax keyword crontabDow7 contained sun mon tue wed thu fri sat
+
+syntax region crontabCmd start="\S" end="$" skipwhite contained keepend contains=crontabPercent
+syntax match crontabCmnt "^\s*#.*"
+syntax match crontabPercent "[^\\]%.*"lc=1 contained
+
+syntax match crontabNick "^\s*@\(reboot\|yearly\|annually\|monthly\|weekly\|daily\|midnight\|hourly\)\>" nextgroup=crontabCmd skipwhite
+
+syntax match crontabVar "^\s*\k\w*\s*="me=e-1
+
+" Define the default highlighting.
+" For version 5.7 and earlier: only when not done already
+" For version 5.8 and later: only when an item doesn't have highlighting yet
+if version >= 508 || !exists("did_crontab_syn_inits")
+  if version < 508
+    let did_crontab_syn_inits = 1
+    command -nargs=+ HiLink hi link <args>
+  else
+    command -nargs=+ HiLink hi def link <args>
+  endif
+
+  HiLink crontabMin		Number
+  HiLink crontabHr		PreProc
+  HiLink crontabDay		Type
+
+  HiLink crontabMnth		Number
+  HiLink crontabMnth12		Number
+  HiLink crontabMnthS		Number
+  HiLink crontabMnthN		Number
+
+  HiLink crontabDow		PreProc
+  HiLink crontabDow7		PreProc
+  HiLink crontabDowS		PreProc
+  HiLink crontabDowN		PreProc
+
+  HiLink crontabNick		Special
+  HiLink crontabVar		Identifier
+  HiLink crontabPercent		Special
+
+" comment out next line for to suppress unix commands coloring.
+  HiLink crontabCmd		Statement
+
+  HiLink crontabCmnt		Comment
+
+  delcommand HiLink
+endif
+
+let b:current_syntax = "crontab"
+
+" vim: ts=8
--- /dev/null
+++ b/lib/vimfiles/syntax/cs.vim
@@ -1,0 +1,154 @@
+" Vim syntax file
+" Language:	C#
+" Maintainer:	Anduin Withers <awithers@anduin.com>
+" Former Maintainer:	Johannes Zellner <johannes@zellner.org>
+" Last Change:	Sun Apr 30 19:26:18 PDT 2006
+" Filenames:	*.cs
+" $Id: cs.vim,v 1.4 2006/05/03 21:20:02 vimboss Exp $
+"
+" REFERENCES:
+" [1] ECMA TC39: C# Language Specification (WD13Oct01.doc)
+
+if exists("b:current_syntax")
+    finish
+endif
+
+let s:cs_cpo_save = &cpo
+set cpo&vim
+
+
+" type
+syn keyword csType			bool byte char decimal double float int long object sbyte short string uint ulong ushort void
+" storage
+syn keyword csStorage			class delegate enum interface namespace struct
+" repeat / condition / label
+syn keyword csRepeat			break continue do for foreach goto return while
+syn keyword csConditional		else if switch
+syn keyword csLabel			case default
+" there's no :: operator in C#
+syn match csOperatorError		display +::+
+" user labels (see [1] 8.6 Statements)
+syn match   csLabel			display +^\s*\I\i*\s*:\([^:]\)\@=+
+" modifier
+syn keyword csModifier			abstract const extern internal override private protected public readonly sealed static virtual volatile
+" constant
+syn keyword csConstant			false null true
+" exception
+syn keyword csException			try catch finally throw
+
+" TODO:
+syn keyword csUnspecifiedStatement	as base checked event fixed in is lock new operator out params ref sizeof stackalloc this typeof unchecked unsafe using
+" TODO:
+syn keyword csUnsupportedStatement	add remove value
+" TODO:
+syn keyword csUnspecifiedKeyword	explicit implicit
+
+
+" Contextual Keywords
+syn match csContextualStatement	/\<yield[[:space:]\n]\+\(return\|break\)/me=s+5
+syn match csContextualStatement	/\<partial[[:space:]\n]\+\(class\|struct\|interface\)/me=s+7
+syn match csContextualStatement	/\<\(get\|set\)[[:space:]\n]*{/me=s+3
+syn match csContextualStatement	/\<where\>[^:]\+:/me=s+5
+
+" Comments
+"
+" PROVIDES: @csCommentHook
+"
+" TODO: include strings ?
+"
+syn keyword csTodo		contained TODO FIXME XXX NOTE
+syn region  csComment		start="/\*"  end="\*/" contains=@csCommentHook,csTodo,@Spell
+syn match   csComment		"//.*$" contains=@csCommentHook,csTodo,@Spell
+
+" xml markup inside '///' comments
+syn cluster xmlRegionHook	add=csXmlCommentLeader
+syn cluster xmlCdataHook	add=csXmlCommentLeader
+syn cluster xmlStartTagHook	add=csXmlCommentLeader
+syn keyword csXmlTag		contained Libraries Packages Types Excluded ExcludedTypeName ExcludedLibraryName
+syn keyword csXmlTag		contained ExcludedBucketName TypeExcluded Type TypeKind TypeSignature AssemblyInfo
+syn keyword csXmlTag		contained AssemblyName AssemblyPublicKey AssemblyVersion AssemblyCulture Base
+syn keyword csXmlTag		contained BaseTypeName Interfaces Interface InterfaceName Attributes Attribute
+syn keyword csXmlTag		contained AttributeName Members Member MemberSignature MemberType MemberValue
+syn keyword csXmlTag		contained ReturnValue ReturnType Parameters Parameter MemberOfPackage
+syn keyword csXmlTag		contained ThreadingSafetyStatement Docs devdoc example overload remarks returns summary
+syn keyword csXmlTag		contained threadsafe value internalonly nodoc exception param permission platnote
+syn keyword csXmlTag		contained seealso b c i pre sub sup block code note paramref see subscript superscript
+syn keyword csXmlTag		contained list listheader item term description altcompliant altmember
+
+syn cluster xmlTagHook add=csXmlTag
+
+syn match   csXmlCommentLeader	+\/\/\/+    contained
+syn match   csXmlComment	+\/\/\/.*$+ contains=csXmlCommentLeader,@csXml
+syntax include @csXml <sfile>:p:h/xml.vim
+hi def link xmlRegion Comment
+
+
+" [1] 9.5 Pre-processing directives
+syn region	csPreCondit
+    \ start="^\s*#\s*\(define\|undef\|if\|elif\|else\|endif\|line\|error\|warning\)"
+    \ skip="\\$" end="$" contains=csComment keepend
+syn region	csRegion matchgroup=csPreCondit start="^\s*#\s*region.*$"
+    \ end="^\s*#\s*endregion" transparent fold contains=TOP
+
+
+
+" Strings and constants
+syn match   csSpecialError	contained "\\."
+syn match   csSpecialCharError	contained "[^']"
+" [1] 9.4.4.4 Character literals
+syn match   csSpecialChar	contained +\\["\\'0abfnrtvx]+
+" unicode characters
+syn match   csUnicodeNumber	+\\\(u\x\{4}\|U\x\{8}\)+ contained contains=csUnicodeSpecifier
+syn match   csUnicodeSpecifier	+\\[uU]+ contained
+syn region  csVerbatimString	start=+@"+ end=+"+ end=+$+ skip=+""+ contains=csVerbatimSpec,@Spell
+syn match   csVerbatimSpec	+@"+he=s+1 contained
+syn region  csString		start=+"+  end=+"+ end=+$+ contains=csSpecialChar,csSpecialError,csUnicodeNumber,@Spell
+syn match   csCharacter		"'[^']*'" contains=csSpecialChar,csSpecialCharError
+syn match   csCharacter		"'\\''" contains=csSpecialChar
+syn match   csCharacter		"'[^\\]'"
+syn match   csNumber		"\<\(0[0-7]*\|0[xX]\x\+\|\d\+\)[lL]\=\>"
+syn match   csNumber		"\(\<\d\+\.\d*\|\.\d\+\)\([eE][-+]\=\d\+\)\=[fFdD]\="
+syn match   csNumber		"\<\d\+[eE][-+]\=\d\+[fFdD]\=\>"
+syn match   csNumber		"\<\d\+\([eE][-+]\=\d\+\)\=[fFdD]\>"
+
+" The default highlighting.
+hi def link csType			Type
+hi def link csStorage			StorageClass
+hi def link csRepeat			Repeat
+hi def link csConditional		Conditional
+hi def link csLabel			Label
+hi def link csModifier			StorageClass
+hi def link csConstant			Constant
+hi def link csException			Exception
+hi def link csUnspecifiedStatement	Statement
+hi def link csUnsupportedStatement	Statement
+hi def link csUnspecifiedKeyword	Keyword
+hi def link csContextualStatement	Statement
+hi def link csOperatorError		Error
+
+hi def link csTodo			Todo
+hi def link csComment			Comment
+
+hi def link csSpecialError		Error
+hi def link csSpecialCharError		Error
+hi def link csString			String
+hi def link csVerbatimString		String
+hi def link csVerbatimSpec		SpecialChar
+hi def link csPreCondit			PreCondit
+hi def link csCharacter			Character
+hi def link csSpecialChar		SpecialChar
+hi def link csNumber			Number
+hi def link csUnicodeNumber		SpecialChar
+hi def link csUnicodeSpecifier		SpecialChar
+
+" xml markup
+hi def link csXmlCommentLeader		Comment
+hi def link csXmlComment		Comment
+hi def link csXmlTag			Statement
+
+let b:current_syntax = "cs"
+
+let &cpo = s:cs_cpo_save
+unlet s:cs_cpo_save
+
+" vim: ts=8
--- /dev/null
+++ b/lib/vimfiles/syntax/csc.vim
@@ -1,0 +1,199 @@
+" Vim syntax file
+" Language: Essbase script
+" Maintainer:	Raul Segura Acevedo <raulseguraaceved@netscape.net>
+" Last change:	2001 Sep 25
+
+" For version 5.x: Clear all syntax items
+" For version 6.x: Quit when a syntax file was already loaded
+if version < 600
+	syntax clear
+elseif exists("b:current_syntax")
+	finish
+endif
+
+" folds: fix/endfix and comments
+sy	region	EssFold start="\<Fix" end="EndFix" transparent fold
+
+sy	keyword	cscTodo contained TODO FIXME XXX
+
+" cscCommentGroup allows adding matches for special things in comments
+sy	cluster cscCommentGroup contains=cscTodo
+
+" Strings in quotes
+sy	match	cscError	'"'
+sy	match	cscString	'"[^"]*"'
+
+"when wanted, highlight trailing white space
+if exists("csc_space_errors")
+	if !exists("csc_no_trail_space_error")
+		sy	match	cscSpaceE	"\s\+$"
+	endif
+	if !exists("csc_no_tab_space_error")
+		sy	match	cscSpaceE	" \+\t"me=e-1
+	endif
+endif
+
+"catch errors caused by wrong parenthesis and brackets
+sy	cluster	cscParenGroup	contains=cscParenE,@cscCommentGroup,cscUserCont,cscBitField,cscFormat,cscNumber,cscFloat,cscOctal,cscNumbers,cscIfError,cscComW,cscCom,cscFormula,cscBPMacro
+sy	region	cscParen	transparent start='(' end=')' contains=ALLBUT,@cscParenGroup
+sy	match	cscParenE	")"
+
+"integer number, or floating point number without a dot and with "f".
+sy	case	ignore
+sy	match	cscNumbers	transparent "\<\d\|\.\d" contains=cscNumber,cscFloat,cscOctal
+sy	match	cscNumber	contained "\d\+\(u\=l\{0,2}\|ll\=u\)\>"
+"hex number
+sy	match	cscNumber	contained "0x\x\+\(u\=l\{0,2}\|ll\=u\)\>"
+" Flag the first zero of an octal number as something special
+sy	match	cscOctal	contained "0\o\+\(u\=l\{0,2}\|ll\=u\)\>"
+sy	match	cscFloat	contained "\d\+f"
+"floating point number, with dot, optional exponent
+sy	match	cscFloat	contained "\d\+\.\d*\(e[-+]\=\d\+\)\=[fl]\="
+"floating point number, starting with a dot, optional exponent
+sy	match	cscFloat	contained "\.\d\+\(e[-+]\=\d\+\)\=[fl]\=\>"
+"floating point number, without dot, with exponent
+sy	match	cscFloat	contained "\d\+e[-+]\=\d\+[fl]\=\>"
+
+sy	region	cscComment	start="/\*" end="\*/" contains=@cscCommentGroup,cscSpaceE fold
+sy	match	cscCommentE	"\*/"
+
+sy	keyword	cscIfError	IF ELSE ENDIF ELSEIF
+sy	keyword	cscCondition	contained IF ELSE ENDIF ELSEIF
+sy	keyword	cscFunction	contained VARPER VAR UDA TRUNCATE SYD SUMRANGE SUM
+sy	keyword	cscFunction	contained STDDEVRANGE STDDEV SPARENTVAL SLN SIBLINGS SHIFT
+sy	keyword	cscFunction	contained SANCESTVAL RSIBLINGS ROUND REMAINDER RELATIVE PTD
+sy	keyword	cscFunction	contained PRIOR POWER PARENTVAL NPV NEXT MOD MINRANGE MIN
+sy	keyword	cscFunction	contained MDSHIFT MDPARENTVAL MDANCESTVAL MAXRANGE MAX MATCH
+sy	keyword	cscFunction	contained LSIBLINGS LEVMBRS LEV
+sy	keyword	cscFunction	contained ISUDA ISSIBLING ISSAMELEV ISSAMEGEN ISPARENT ISMBR
+sy	keyword	cscFunction	contained ISLEV ISISIBLING ISIPARENT ISIDESC ISICHILD ISIBLINGS
+sy	keyword	cscFunction	contained ISIANCEST ISGEN ISDESC ISCHILD ISANCEST ISACCTYPE
+sy	keyword	cscFunction	contained IRSIBLINGS IRR INTEREST INT ILSIBLINGS IDESCENDANTS
+sy	keyword	cscFunction	contained ICHILDREN IANCESTORS IALLANCESTORS
+sy	keyword	cscFunction	contained GROWTH GENMBRS GEN FACTORIAL DISCOUNT DESCENDANTS
+sy	keyword	cscFunction	contained DECLINE CHILDREN CURRMBRRANGE CURLEV CURGEN
+sy	keyword	cscFunction	contained COMPOUNDGROWTH COMPOUND AVGRANGE AVG ANCESTVAL
+sy	keyword	cscFunction	contained ANCESTORS ALLANCESTORS ACCUM ABS
+sy	keyword	cscFunction	contained @VARPER @VAR @UDA @TRUNCATE @SYD @SUMRANGE @SUM
+sy	keyword	cscFunction	contained @STDDEVRANGE @STDDEV @SPARENTVAL @SLN @SIBLINGS @SHIFT
+sy	keyword	cscFunction	contained @SANCESTVAL @RSIBLINGS @ROUND @REMAINDER @RELATIVE @PTD
+sy	keyword	cscFunction	contained @PRIOR @POWER @PARENTVAL @NPV @NEXT @MOD @MINRANGE @MIN
+sy	keyword	cscFunction	contained @MDSHIFT @MDPARENTVAL @MDANCESTVAL @MAXRANGE @MAX @MATCH
+sy	keyword	cscFunction	contained @LSIBLINGS @LEVMBRS @LEV
+sy	keyword	cscFunction	contained @ISUDA @ISSIBLING @ISSAMELEV @ISSAMEGEN @ISPARENT @ISMBR
+sy	keyword	cscFunction	contained @ISLEV @ISISIBLING @ISIPARENT @ISIDESC @ISICHILD @ISIBLINGS
+sy	keyword	cscFunction	contained @ISIANCEST @ISGEN @ISDESC @ISCHILD @ISANCEST @ISACCTYPE
+sy	keyword	cscFunction	contained @IRSIBLINGS @IRR @INTEREST @INT @ILSIBLINGS @IDESCENDANTS
+sy	keyword	cscFunction	contained @ICHILDREN @IANCESTORS @IALLANCESTORS
+sy	keyword	cscFunction	contained @GROWTH @GENMBRS @GEN @FACTORIAL @DISCOUNT @DESCENDANTS
+sy	keyword	cscFunction	contained @DECLINE @CHILDREN @CURRMBRRANGE @CURLEV @CURGEN
+sy	keyword	cscFunction	contained @COMPOUNDGROWTH @COMPOUND @AVGRANGE @AVG @ANCESTVAL
+sy	keyword	cscFunction	contained @ANCESTORS @ALLANCESTORS @ACCUM @ABS
+sy	match	cscFunction	contained "@"
+sy	match	cscError	"@\s*\a*" contains=cscFunction
+
+sy	match	cscStatement	"&"
+sy	keyword	cscStatement	AGG ARRAY VAR CCONV CLEARDATA DATACOPY
+
+sy	match	cscComE	contained "^\s*CALC.*"
+sy	match	cscComE	contained "^\s*CLEARBLOCK.*"
+sy	match	cscComE	contained "^\s*SET.*"
+sy	match	cscComE	contained "^\s*FIX"
+sy	match	cscComE	contained "^\s*ENDFIX"
+sy	match	cscComE	contained "^\s*ENDLOOP"
+sy	match	cscComE	contained "^\s*LOOP"
+" sy	keyword	cscCom	FIX ENDFIX LOOP ENDLOOP
+
+sy	match	cscComW	"^\s*CALC.*"
+sy	match	cscCom	"^\s*CALC\s*ALL"
+sy	match	cscCom	"^\s*CALC\s*AVERAGE"
+sy	match	cscCom	"^\s*CALC\s*DIM"
+sy	match	cscCom	"^\s*CALC\s*FIRST"
+sy	match	cscCom	"^\s*CALC\s*LAST"
+sy	match	cscCom	"^\s*CALC\s*TWOPASS"
+
+sy	match	cscComW	"^\s*CLEARBLOCK.*"
+sy	match	cscCom	"^\s*CLEARBLOCK\s\+ALL"
+sy	match	cscCom	"^\s*CLEARBLOCK\s\+UPPER"
+sy	match	cscCom	"^\s*CLEARBLOCK\s\+NONINPUT"
+
+sy	match	cscComW	"^\s*\<SET.*"
+sy	match	cscCom	"^\s*\<SET\s\+Commands"
+sy	match	cscCom	"^\s*\<SET\s\+AGGMISSG"
+sy	match	cscCom	"^\s*\<SET\s\+CACHE"
+sy	match	cscCom	"^\s*\<SET\s\+CALCHASHTBL"
+sy	match	cscCom	"^\s*\<SET\s\+CLEARUPDATESTATUS"
+sy	match	cscCom	"^\s*\<SET\s\+FRMLBOTTOMUP"
+sy	match	cscCom	"^\s*\<SET\s\+LOCKBLOCK"
+sy	match	cscCom	"^\s*\<SET\s\+MSG"
+sy	match	cscCom	"^\s*\<SET\s\+NOTICE"
+sy	match	cscCom	"^\s*\<SET\s\+UPDATECALC"
+sy	match	cscCom	"^\s*\<SET\s\+UPTOLOCAL"
+
+sy	keyword	cscBPMacro	contained !LoopOnAll !LoopOnLevel !LoopOnSelected
+sy	keyword	cscBPMacro	contained !CurrentMember !LoopOnDimensions !CurrentDimension
+sy	keyword	cscBPMacro	contained !CurrentOtherLoopDimension !LoopOnOtherLoopDimensions
+sy	keyword	cscBPMacro	contained !EndLoop !AllMembers !SelectedMembers !If !Else !EndIf
+sy	keyword	cscBPMacro	contained LoopOnAll LoopOnLevel LoopOnSelected
+sy	keyword	cscBPMacro	contained CurrentMember LoopOnDimensions CurrentDimension
+sy	keyword	cscBPMacro	contained CurrentOtherLoopDimension LoopOnOtherLoopDimensions
+sy	keyword	cscBPMacro	contained EndLoop AllMembers SelectedMembers If Else EndIf
+sy	match	cscBPMacro	contained	"!"
+sy	match	cscBPW	"!\s*\a*"	contains=cscBPmacro
+
+" when wanted, highlighting lhs members or erros in asignments (may lag the editing)
+if version >= 600 && exists("csc_asignment")
+	sy	match	cscEqError	'\("[^"]*"\s*\|[^][\t !%()*+,--/:;<=>{}~]\+\s*\|->\s*\)*=\([^=]\@=\|$\)'
+	sy	region	cscFormula	transparent matchgroup=cscVarName start='\("[^"]*"\|[^][\t !%()*+,--/:;<=>{}~]\+\)\s*=\([^=]\@=\|\n\)' skip='"[^"]*"' end=';' contains=ALLBUT,cscFormula,cscFormulaIn,cscBPMacro,cscCondition
+	sy	region	cscFormulaIn	matchgroup=cscVarName transparent start='\("[^"]*"\|[^][\t !%()*+,--/:;<=>{}~]\+\)\(->\("[^"]*"\|[^][\t !%()*+,--/:;<=>{}~]\+\)\)*\s*=\([^=]\@=\|$\)' skip='"[^"]*"' end=';' contains=ALLBUT,cscFormula,cscFormulaIn,cscBPMacro,cscCondition contained
+	sy	match	cscEq	"=="
+endif
+
+if !exists("csc_minlines")
+	let csc_minlines = 50	" mostly for () constructs
+endif
+exec "sy sync ccomment cscComment minlines=" . csc_minlines
+
+" Define the default highlighting.
+" For version 5.7 and earlier: only when not done already
+" For version 5.8 and later: only when an item doesn't have highlighting yet
+if version >= 508 || !exists("did_csc_syntax_inits")
+	if version < 508
+		let did_csc_syntax_inits = 1
+		command -nargs=+ HiLink hi link <args>
+	else
+		command -nargs=+ HiLink hi def link <args>
+	endif
+
+	hi cscVarName term=bold ctermfg=9 gui=bold guifg=blue
+
+	HiLink	cscNumber	Number
+	HiLink	cscOctal	Number
+	HiLink	cscFloat	Float
+	HiLink	cscParenE	Error
+	HiLink	cscCommentE	Error
+	HiLink	cscSpaceE	Error
+	HiLink	cscError	Error
+	HiLink	cscString	String
+	HiLink	cscComment	Comment
+	HiLink	cscTodo		Todo
+	HiLink	cscStatement	Statement
+	HiLink	cscIfError	Error
+	HiLink	cscEqError	Error
+	HiLink	cscFunction	Statement
+	HiLink	cscCondition	Statement
+	HiLink	cscWarn		WarningMsg
+
+	HiLink	cscComE	Error
+	HiLink	cscCom	Statement
+	HiLink	cscComW	WarningMsg
+
+	HiLink	cscBPMacro	Identifier
+	HiLink	cscBPW		WarningMsg
+
+	delcommand HiLink
+endif
+
+let b:current_syntax = "csc"
+
+" vim: ts=8
--- /dev/null
+++ b/lib/vimfiles/syntax/csh.vim
@@ -1,0 +1,160 @@
+" Vim syntax file
+" Language:	C-shell (csh)
+" Maintainer:	Dr. Charles E. Campbell, Jr. <NdrOchipS@PcampbellAfamily.Mbiz>
+" Version:	10
+" Last Change:	Sep 11, 2006
+" URL:	http://mysite.verizon.net/astronaut/vim/index.html#vimlinks_syntax
+
+" For version 5.x: Clear all syntax items
+" For version 6.x: Quit when a syntax file was already loaded
+if version < 600
+  syntax clear
+elseif exists("b:current_syntax")
+  finish
+endif
+
+" clusters:
+syn cluster cshQuoteList	contains=cshDblQuote,cshSnglQuote,cshBckQuote
+syn cluster cshVarList	contains=cshExtVar,cshSelector,cshQtyWord,cshArgv,cshSubst
+
+" Variables which affect the csh itself
+syn match cshSetVariables	contained "argv\|histchars\|ignoreeof\|noglob\|prompt\|status"
+syn match cshSetVariables	contained "cdpath\|history\|mail\|nonomatch\|savehist\|time"
+syn match cshSetVariables	contained "cwd\|home\|noclobber\|path\|shell\|verbose"
+syn match cshSetVariables	contained "echo"
+
+syn case ignore
+syn keyword cshTodo	contained todo
+syn case match
+
+" Variable Name Expansion Modifiers
+syn match cshModifier	contained ":\(h\|t\|r\|q\|x\|gh\|gt\|gr\)"
+
+" Strings and Comments
+syn match   cshNoEndlineDQ	contained "[^\"]\(\\\\\)*$"
+syn match   cshNoEndlineSQ	contained "[^\']\(\\\\\)*$"
+syn match   cshNoEndlineBQ	contained "[^\`]\(\\\\\)*$"
+
+syn region  cshDblQuote	start=+[^\\]"+lc=1 skip=+\\\\\|\\"+ end=+"+	contains=cshSpecial,cshShellVariables,cshExtVar,cshSelector,cshQtyWord,cshArgv,cshSubst,cshNoEndlineDQ,cshBckQuote,@Spell
+syn region  cshSnglQuote	start=+[^\\]'+lc=1 skip=+\\\\\|\\'+ end=+'+	contains=cshNoEndlineSQ,@Spell
+syn region  cshBckQuote	start=+[^\\]`+lc=1 skip=+\\\\\|\\`+ end=+`+	contains=cshNoEndlineBQ,@Spell
+syn region  cshDblQuote	start=+^"+ skip=+\\\\\|\\"+ end=+"+		contains=cshSpecial,cshExtVar,cshSelector,cshQtyWord,cshArgv,cshSubst,cshNoEndlineDQ,@Spell
+syn region  cshSnglQuote	start=+^'+ skip=+\\\\\|\\'+ end=+'+		contains=cshNoEndlineSQ,@Spell
+syn region  cshBckQuote	start=+^`+ skip=+\\\\\|\\`+ end=+`+		contains=cshNoEndlineBQ,@Spell
+syn cluster cshCommentGroup	contains=cshTodo,@Spell
+syn match   cshComment	"#.*$" contains=@cshCommentGroup
+
+" A bunch of useful csh keywords
+syn keyword cshStatement	alias	end	history	onintr	setenv	unalias
+syn keyword cshStatement	cd	eval	kill	popd	shift	unhash
+syn keyword cshStatement	chdir	exec	login	pushd	source
+syn keyword cshStatement	continue	exit	logout	rehash	time	unsetenv
+syn keyword cshStatement	dirs	glob	nice	repeat	umask	wait
+syn keyword cshStatement	echo	goto	nohup
+
+syn keyword cshConditional	break	case	else	endsw	switch
+syn keyword cshConditional	breaksw	default	endif
+syn keyword cshRepeat	foreach
+
+" Special environment variables
+syn keyword cshShellVariables	HOME	LOGNAME	PATH	TERM	USER
+
+" Modifiable Variables without {}
+syn match cshExtVar	"\$[a-zA-Z_][a-zA-Z0-9_]*\(:h\|:t\|:r\|:q\|:x\|:gh\|:gt\|:gr\)\="		contains=cshModifier
+syn match cshSelector	"\$[a-zA-Z_][a-zA-Z0-9_]*\[[a-zA-Z_]\+\]\(:h\|:t\|:r\|:q\|:x\|:gh\|:gt\|:gr\)\="	contains=cshModifier
+syn match cshQtyWord	"\$#[a-zA-Z_][a-zA-Z0-9_]*\(:h\|:t\|:r\|:q\|:x\|:gh\|:gt\|:gr\)\="		contains=cshModifier
+syn match cshArgv		"\$\d\+\(:h\|:t\|:r\|:q\|:x\|:gh\|:gt\|:gr\)\="			contains=cshModifier
+syn match cshArgv		"\$\*\(:h\|:t\|:r\|:q\|:x\|:gh\|:gt\|:gr\)\="			contains=cshModifier
+
+" Modifiable Variables with {}
+syn match cshExtVar	"\${[a-zA-Z_][a-zA-Z0-9_]*\(:h\|:t\|:r\|:q\|:x\|:gh\|:gt\|:gr\)\=}"		contains=cshModifier
+syn match cshSelector	"\${[a-zA-Z_][a-zA-Z0-9_]*\[[a-zA-Z_]\+\]\(:h\|:t\|:r\|:q\|:x\|:gh\|:gt\|:gr\)\=}"	contains=cshModifier
+syn match cshQtyWord	"\${#[a-zA-Z_][a-zA-Z0-9_]*\(:h\|:t\|:r\|:q\|:x\|:gh\|:gt\|:gr\)\=}"		contains=cshModifier
+syn match cshArgv		"\${\d\+\(:h\|:t\|:r\|:q\|:x\|:gh\|:gt\|:gr\)\=}"			contains=cshModifier
+
+" UnModifiable Substitutions
+syn match cshSubstError	"\$?[a-zA-Z_][a-zA-Z0-9_]*:\(h\|t\|r\|q\|x\|gh\|gt\|gr\)"
+syn match cshSubstError	"\${?[a-zA-Z_][a-zA-Z0-9_]*:\(h\|t\|r\|q\|x\|gh\|gt\|gr\)}"
+syn match cshSubstError	"\$?[0$<]:\(h\|t\|r\|q\|x\|gh\|gt\|gr\)"
+syn match cshSubst	"\$?[a-zA-Z_][a-zA-Z0-9_]*"
+syn match cshSubst	"\${?[a-zA-Z_][a-zA-Z0-9_]*}"
+syn match cshSubst	"\$?[0$<]"
+
+" I/O redirection
+syn match cshRedir	">>&!\|>&!\|>>&\|>>!\|>&\|>!\|>>\|<<\|>\|<"
+
+" Handle set expressions
+syn region  cshSetExpr	matchgroup=cshSetStmt start="\<set\>\|\<unset\>" end="$\|;" contains=cshComment,cshSetStmt,cshSetVariables,@cshQuoteList
+
+" Operators and Expression-Using constructs
+"syn match   cshOperator	contained "&&\|!\~\|!=\|<<\|<=\|==\|=\~\|>=\|>>\|\*\|\^\|\~\|||\|!\|\|%\|&\|+\|-\|/\|<\|>\||"
+syn match   cshOperator	contained "&&\|!\~\|!=\|<<\|<=\|==\|=\~\|>=\|>>\|\*\|\^\|\~\|||\|!\|%\|&\|+\|-\|/\|<\|>\||"
+syn match   cshOperator	contained "[(){}]"
+syn region  cshTest	matchgroup=cshStatement start="\<if\>\|\<while\>" skip="\\$" matchgroup=cshStatement end="\<then\>\|$" contains=cshComment,cshOperator,@cshQuoteList,@cshVarLIst
+
+" Highlight special characters (those which have a backslash) differently
+syn match cshSpecial	contained "\\\d\d\d\|\\[abcfnrtv\\]"
+syn match cshNumber	"-\=\<\d\+\>"
+
+" All other identifiers
+"syn match cshIdentifier	"\<[a-zA-Z._][a-zA-Z0-9._]*\>"
+
+" Shell Input Redirection (Here Documents)
+if version < 600
+  syn region cshHereDoc matchgroup=cshRedir start="<<-\=\s*\**END[a-zA-Z_0-9]*\**" matchgroup=cshRedir end="^END[a-zA-Z_0-9]*$"
+  syn region cshHereDoc matchgroup=cshRedir start="<<-\=\s*\**EOF\**" matchgroup=cshRedir end="^EOF$"
+else
+  syn region cshHereDoc matchgroup=cshRedir start="<<-\=\s*\**\z(\h\w*\)\**" matchgroup=cshRedir end="^\z1$"
+endif
+
+" Define the default highlighting.
+" For version 5.7 and earlier: only when not done already
+" For version 5.8 and later: only when an item doesn't have highlighting yet
+if version >= 508 || !exists("did_csh_syntax_inits")
+  if version < 508
+    let did_csh_syntax_inits = 1
+    command -nargs=+ HiLink hi link <args>
+  else
+    command -nargs=+ HiLink hi def link <args>
+  endif
+
+  HiLink cshArgv		cshVariables
+  HiLink cshBckQuote	cshCommand
+  HiLink cshDblQuote	cshString
+  HiLink cshExtVar	cshVariables
+  HiLink cshHereDoc	cshString
+  HiLink cshNoEndlineBQ	cshNoEndline
+  HiLink cshNoEndlineDQ	cshNoEndline
+  HiLink cshNoEndlineSQ	cshNoEndline
+  HiLink cshQtyWord	cshVariables
+  HiLink cshRedir		cshOperator
+  HiLink cshSelector	cshVariables
+  HiLink cshSetStmt	cshStatement
+  HiLink cshSetVariables	cshVariables
+  HiLink cshSnglQuote	cshString
+  HiLink cshSubst		cshVariables
+
+  HiLink cshCommand	Statement
+  HiLink cshComment	Comment
+  HiLink cshConditional	Conditional
+  HiLink cshIdentifier	Error
+  HiLink cshModifier	Special
+  HiLink cshNoEndline	Error
+  HiLink cshNumber	Number
+  HiLink cshOperator	Operator
+  HiLink cshRedir		Statement
+  HiLink cshRepeat	Repeat
+  HiLink cshShellVariables	Special
+  HiLink cshSpecial	Special
+  HiLink cshStatement	Statement
+  HiLink cshString	String
+  HiLink cshSubstError	Error
+  HiLink cshTodo		Todo
+  HiLink cshVariables	Type
+
+  delcommand HiLink
+endif
+
+let b:current_syntax = "csh"
+
+" vim: ts=18
--- /dev/null
+++ b/lib/vimfiles/syntax/csp.vim
@@ -1,0 +1,195 @@
+" Vim syntax file
+" Language:	CSP (Communication Sequential Processes, using FDR input syntax)
+" Maintainer:	Jan Bredereke <brederek@tzi.de>
+" Version:	0.6.0
+" Last change:	Mon Mar 25, 2002
+" URL:		http://www.tzi.de/~brederek/vim/
+" Copying:	You may distribute and use this file freely, in the same
+"		way as the vim editor itself.
+"
+" To Do:	- Probably I missed some keywords or operators, please
+"		  fix them and notify me, the maintainer.
+"		- Currently, we do lexical highlighting only. It would be
+"		  nice to have more actual syntax checks, including
+"		  highlighting of wrong syntax.
+"		- The additional syntax for the RT-Tester (pseudo-comments)
+"		  should be optional.
+
+" For version 5.x: Clear all syntax items
+" For version 6.x: Quit when a syntax file was already loaded
+if version < 600
+  syntax clear
+elseif exists("b:current_syntax")
+  finish
+endif
+
+" case is significant to FDR:
+syn case match
+
+" Block comments in CSP are between {- and -}
+syn region cspComment	start="{-"  end="-}" contains=cspTodo
+" Single-line comments start with --
+syn region cspComment	start="--"  end="$" contains=cspTodo,cspOldRttComment,cspSdlRttComment keepend
+
+" Numbers:
+syn match  cspNumber "\<\d\+\>"
+
+" Conditionals:
+syn keyword  cspConditional if then else
+
+" Operators on processes:
+" -> ? : ! ' ; /\ \ [] |~| [> & [[..<-..]] ||| [|..|] || [..<->..] ; : @ |||
+syn match  cspOperator "->"
+syn match  cspOperator "/\\"
+syn match  cspOperator "[^/]\\"lc=1
+syn match  cspOperator "\[\]"
+syn match  cspOperator "|\~|"
+syn match  cspOperator "\[>"
+syn match  cspOperator "\[\["
+syn match  cspOperator "\]\]"
+syn match  cspOperator "<-"
+syn match  cspOperator "|||"
+syn match  cspOperator "[^|]||[^|]"lc=1,me=e-1
+syn match  cspOperator "[^|{\~]|[^|}\~]"lc=1,me=e-1
+syn match  cspOperator "\[|"
+syn match  cspOperator "|\]"
+syn match  cspOperator "\[[^>]"me=e-1
+syn match  cspOperator "\]"
+syn match  cspOperator "<->"
+syn match  cspOperator "[?:!';@]"
+syn match  cspOperator "&"
+syn match  cspOperator "\."
+
+" (not on processes:)
+" syn match  cspDelimiter	"{|"
+" syn match  cspDelimiter	"|}"
+" syn match  cspDelimiter	"{[^-|]"me=e-1
+" syn match  cspDelimiter	"[^-|]}"lc=1
+
+" Keywords:
+syn keyword cspKeyword		length null head tail concat elem
+syn keyword cspKeyword		union inter diff Union Inter member card
+syn keyword cspKeyword		empty set Set Seq
+syn keyword cspKeyword		true false and or not within let
+syn keyword cspKeyword		nametype datatype diamond normal
+syn keyword cspKeyword		sbisim tau_loop_factor model_compress
+syn keyword cspKeyword		explicate
+syn match cspKeyword		"transparent"
+syn keyword cspKeyword		external chase prioritize
+syn keyword cspKeyword		channel Events
+syn keyword cspKeyword		extensions productions
+syn keyword cspKeyword		Bool Int
+
+" Reserved keywords:
+syn keyword cspReserved		attribute embed module subtype
+
+" Include:
+syn region cspInclude matchgroup=cspIncludeKeyword start="^include" end="$" keepend contains=cspIncludeArg
+syn region cspIncludeArg start='\s\+\"' end= '\"\s*' contained
+
+" Assertions:
+syn keyword cspAssert		assert deterministic divergence free deadlock
+syn keyword cspAssert		livelock
+syn match cspAssert		"\[T="
+syn match cspAssert		"\[F="
+syn match cspAssert		"\[FD="
+syn match cspAssert		"\[FD\]"
+syn match cspAssert		"\[F\]"
+
+" Types and Sets
+" (first char a capital, later at least one lower case, no trailing underscore):
+syn match cspType     "\<_*[A-Z][A-Z_0-9]*[a-z]\(\|[A-Za-z_0-9]*[A-Za-z0-9]\)\>"
+
+" Processes (all upper case, no trailing underscore):
+" (For identifiers that could be types or sets, too, this second rule set
+" wins.)
+syn match cspProcess		"\<[A-Z_][A-Z_0-9]*[A-Z0-9]\>"
+syn match cspProcess		"\<[A-Z_]\>"
+
+" reserved identifiers for tool output (ending in underscore):
+syn match cspReservedIdentifier	"\<[A-Za-z_][A-Za-z_0-9]*_\>"
+
+" ToDo markers:
+syn match cspTodo		"FIXME"	contained
+syn match cspTodo		"TODO"	contained
+syn match cspTodo		"!!!"	contained
+
+" RT-Tester pseudo comments:
+" (The now obsolete syntax:)
+syn match cspOldRttComment	"^--\$\$AM_UNDEF"lc=2		contained
+syn match cspOldRttComment	"^--\$\$AM_ERROR"lc=2		contained
+syn match cspOldRttComment	"^--\$\$AM_WARNING"lc=2		contained
+syn match cspOldRttComment	"^--\$\$AM_SET_TIMER"lc=2	contained
+syn match cspOldRttComment	"^--\$\$AM_RESET_TIMER"lc=2	contained
+syn match cspOldRttComment	"^--\$\$AM_ELAPSED_TIMER"lc=2	contained
+syn match cspOldRttComment	"^--\$\$AM_OUTPUT"lc=2		contained
+syn match cspOldRttComment	"^--\$\$AM_INPUT"lc=2		contained
+" (The current syntax:)
+syn region cspRttPragma matchgroup=cspRttPragmaKeyword start="^pragma\s\+" end="\s*$" oneline keepend contains=cspRttPragmaArg,cspRttPragmaSdl
+syn keyword cspRttPragmaArg	AM_ERROR AM_WARNING AM_SET_TIMER contained
+syn keyword cspRttPragmaArg	AM_RESET_TIMER AM_ELAPSED_TIMER  contained
+syn keyword cspRttPragmaArg	AM_OUTPUT AM_INPUT AM_INTERNAL   contained
+" the "SDL_MATCH" extension:
+syn region cspRttPragmaSdl	matchgroup=cspRttPragmaKeyword start="SDL_MATCH\s\+" end="\s*$" contains=cspRttPragmaSdlArg contained
+syn keyword cspRttPragmaSdlArg	TRANSLATE nextgroup=cspRttPragmaSdlTransName contained
+syn keyword cspRttPragmaSdlArg	PARAM SKIP OPTIONAL CHOICE ARRAY nextgroup=cspRttPragmaSdlName contained
+syn match cspRttPragmaSdlName	"\s*\S\+\s*" nextgroup=cspRttPragmaSdlTail contained
+syn region cspRttPragmaSdlTail  start="" end="\s*$" contains=cspRttPragmaSdlTailArg contained
+syn keyword cspRttPragmaSdlTailArg	SUBSET_USED DEFAULT_VALUE Present contained
+syn match cspRttPragmaSdlTransName	"\s*\w\+\s*" nextgroup=cspRttPragmaSdlTransTail contained
+syn region cspRttPragmaSdlTransTail  start="" end="\s*$" contains=cspRttPragmaSdlTransTailArg contained
+syn keyword cspRttPragmaSdlTransTailArg	sizeof contained
+syn match cspRttPragmaSdlTransTailArg	"\*" contained
+syn match cspRttPragmaSdlTransTailArg	"(" contained
+syn match cspRttPragmaSdlTransTailArg	")" contained
+
+" temporary syntax extension for commented-out "pragma SDL_MATCH":
+syn match cspSdlRttComment	"pragma\s\+SDL_MATCH\s\+" nextgroup=cspRttPragmaSdlArg contained
+
+syn sync lines=250
+
+" Define the default highlighting.
+" For version 5.7 and earlier: only when not done already
+" For version 5.8 and later: only when an item doesn't have highlighting yet
+if version >= 508 || !exists("did_csp_syn_inits")
+  if version < 508
+    let did_csp_syn_inits = 1
+    command -nargs=+ HiLink hi link <args>
+  else
+    command -nargs=+ HiLink hi def link <args>
+  endif
+
+  " The default methods for highlighting.  Can be overridden later
+  " (For vim version <=5.7, the command groups are defined in
+  " $VIMRUNTIME/syntax/synload.vim )
+  HiLink cspComment			Comment
+  HiLink cspNumber			Number
+  HiLink cspConditional			Conditional
+  HiLink cspOperator			Delimiter
+  HiLink cspKeyword			Keyword
+  HiLink cspReserved			SpecialChar
+  HiLink cspInclude			Error
+  HiLink cspIncludeKeyword		Include
+  HiLink cspIncludeArg			Include
+  HiLink cspAssert			PreCondit
+  HiLink cspType			Type
+  HiLink cspProcess			Function
+  HiLink cspTodo			Todo
+  HiLink cspOldRttComment		Define
+  HiLink cspRttPragmaKeyword		Define
+  HiLink cspSdlRttComment		Define
+  HiLink cspRttPragmaArg		Define
+  HiLink cspRttPragmaSdlArg		Define
+  HiLink cspRttPragmaSdlName		Default
+  HiLink cspRttPragmaSdlTailArg		Define
+  HiLink cspRttPragmaSdlTransName	Default
+  HiLink cspRttPragmaSdlTransTailArg	Define
+  HiLink cspReservedIdentifier	Error
+  " (Currently unused vim method: Debug)
+
+  delcommand HiLink
+endif
+
+let b:current_syntax = "csp"
+
+" vim: ts=8
--- /dev/null
+++ b/lib/vimfiles/syntax/css.vim
@@ -1,0 +1,282 @@
+" Vim syntax file
+" Language:	Cascading Style Sheets
+" Maintainer:	Claudio Fleiner <claudio@fleiner.com>
+" URL:		http://www.fleiner.com/vim/syntax/css.vim
+" Last Change:	2006 Jun 19
+" CSS2 by Nikolai Weibull
+" Full CSS2, HTML4 support by Yeti
+
+" For version 5.x: Clear all syntax items
+" For version 6.x: Quit when a syntax file was already loaded
+if !exists("main_syntax")
+  if version < 600
+    syntax clear
+  elseif exists("b:current_syntax")
+  finish
+endif
+  let main_syntax = 'css'
+endif
+
+syn case ignore
+
+syn keyword cssTagName abbr acronym address applet area a b base
+syn keyword cssTagName basefont bdo big blockquote body br button
+syn keyword cssTagName caption center cite code col colgroup dd del
+syn keyword cssTagName dfn dir div dl dt em fieldset font form frame
+syn keyword cssTagName frameset h1 h2 h3 h4 h5 h6 head hr html img i
+syn keyword cssTagName iframe img input ins isindex kbd label legend li
+syn keyword cssTagName link map menu meta noframes noscript ol optgroup
+syn keyword cssTagName option p param pre q s samp script select small
+syn keyword cssTagName span strike strong style sub sup tbody td
+syn keyword cssTagName textarea tfoot th thead title tr tt ul u var
+syn match cssTagName "\<table\>"
+syn match cssTagName "\*"
+
+syn match cssTagName "@page\>" nextgroup=cssDefinition
+
+syn match cssSelectorOp "[+>.]"
+syn match cssSelectorOp2 "[~|]\?=" contained
+syn region cssAttributeSelector matchgroup=cssSelectorOp start="\[" end="]" transparent contains=cssUnicodeEscape,cssSelectorOp2,cssStringQ,cssStringQQ
+
+try
+syn match cssIdentifier "#[A-Za-z�-�_@][A-Za-z�-�0-9_@-]*"
+catch /^.*/
+syn match cssIdentifier "#[A-Za-z_@][A-Za-z0-9_@-]*"
+endtry
+
+
+syn match cssMedia "@media\>" nextgroup=cssMediaType skipwhite skipnl
+syn keyword cssMediaType contained screen print aural braile embosed handheld projection ty tv all nextgroup=cssMediaComma,cssMediaBlock skipwhite skipnl
+syn match cssMediaComma "," nextgroup=cssMediaType skipwhite skipnl
+syn region cssMediaBlock transparent matchgroup=cssBraces start='{' end='}' contains=cssTagName,cssError,cssComment,cssDefinition,cssURL,cssUnicodeEscape,cssIdentifier
+
+syn match cssValueInteger contained "[-+]\=\d\+"
+syn match cssValueNumber contained "[-+]\=\d\+\(\.\d*\)\="
+syn match cssValueLength contained "[-+]\=\d\+\(\.\d*\)\=\(%\|mm\|cm\|in\|pt\|pc\|em\|ex\|px\)"
+syn match cssValueAngle contained "[-+]\=\d\+\(\.\d*\)\=\(deg\|grad\|rad\)"
+syn match cssValueTime contained "+\=\d\+\(\.\d*\)\=\(ms\|s\)"
+syn match cssValueFrequency contained "+\=\d\+\(\.\d*\)\=\(Hz\|kHz\)"
+
+syn match cssFontDescriptor "@font-face\>" nextgroup=cssFontDescriptorBlock skipwhite skipnl
+syn region cssFontDescriptorBlock contained transparent matchgroup=cssBraces start="{" end="}" contains=cssComment,cssError,cssUnicodeEscape,cssFontProp,cssFontAttr,cssCommonAttr,cssStringQ,cssStringQQ,cssFontDescriptorProp,cssValue.*,cssFontDescriptorFunction,cssUnicodeRange,cssFontDescriptorAttr
+syn match cssFontDescriptorProp contained "\<\(unicode-range\|unit-per-em\|panose-1\|cap-height\|x-height\|definition-src\)\>"
+syn keyword cssFontDescriptorProp contained src stemv stemh slope ascent descent widths bbox baseline centerline mathline topline
+syn keyword cssFontDescriptorAttr contained all
+syn region cssFontDescriptorFunction contained matchgroup=cssFunctionName start="\<\(uri\|url\|local\|format\)\s*(" end=")" contains=cssStringQ,cssStringQQ oneline keepend
+syn match cssUnicodeRange contained "U+[0-9A-Fa-f?]\+"
+syn match cssUnicodeRange contained "U+\x\+-\x\+"
+
+syn keyword cssColor contained aqua black blue fuchsia gray green lime maroon navy olive purple red silver teal yellow
+" FIXME: These are actually case-insentivie too, but (a) specs recommend using
+" mixed-case (b) it's hard to highlight the word `Background' correctly in
+" all situations
+syn case match
+syn keyword cssColor contained ActiveBorder ActiveCaption AppWorkspace ButtonFace ButtonHighlight ButtonShadow ButtonText CaptionText GrayText Highlight HighlightText InactiveBorder InactiveCaption InactiveCaptionText InfoBackground InfoText Menu MenuText Scrollbar ThreeDDarkShadow ThreeDFace ThreeDHighlight ThreeDLightShadow ThreeDShadow Window WindowFrame WindowText Background
+syn case ignore
+syn match cssColor contained "\<transparent\>"
+syn match cssColor contained "\<white\>"
+syn match cssColor contained "#[0-9A-Fa-f]\{3\}\>"
+syn match cssColor contained "#[0-9A-Fa-f]\{6\}\>"
+"syn match cssColor contained "\<rgb\s*(\s*\d\+\(\.\d*\)\=%\=\s*,\s*\d\+\(\.\d*\)\=%\=\s*,\s*\d\+\(\.\d*\)\=%\=\s*)"
+syn region cssURL contained matchgroup=cssFunctionName start="\<url\s*(" end=")" oneline keepend
+syn region cssFunction contained matchgroup=cssFunctionName start="\<\(rgb\|clip\|attr\|counter\|rect\)\s*(" end=")" oneline keepend
+
+syn match cssImportant contained "!\s*important\>"
+
+syn keyword cssCommonAttr contained auto none inherit
+syn keyword cssCommonAttr contained top bottom
+syn keyword cssCommonAttr contained medium normal
+
+syn match cssFontProp contained "\<font\>\(-\(family\|style\|variant\|weight\|size\(-adjust\)\=\|stretch\)\>\)\="
+syn match cssFontAttr contained "\<\(sans-\)\=\<serif\>"
+syn match cssFontAttr contained "\<small\>\(-\(caps\|caption\)\>\)\="
+syn match cssFontAttr contained "\<x\{1,2\}-\(large\|small\)\>"
+syn match cssFontAttr contained "\<message-box\>"
+syn match cssFontAttr contained "\<status-bar\>"
+syn match cssFontAttr contained "\<\(\(ultra\|extra\|semi\|status-bar\)-\)\=\(condensed\|expanded\)\>"
+syn keyword cssFontAttr contained cursive fantasy monospace italic oblique
+syn keyword cssFontAttr contained bold bolder lighter larger smaller
+syn keyword cssFontAttr contained icon menu
+syn match cssFontAttr contained "\<caption\>"
+syn keyword cssFontAttr contained large smaller larger
+syn keyword cssFontAttr contained narrower wider
+
+syn keyword cssColorProp contained color
+syn match cssColorProp contained "\<background\(-\(color\|image\|attachment\|position\)\)\="
+syn keyword cssColorAttr contained center scroll fixed
+syn match cssColorAttr contained "\<repeat\(-[xy]\)\=\>"
+syn match cssColorAttr contained "\<no-repeat\>"
+
+syn match cssTextProp "\<\(\(word\|letter\)-spacing\|text\(-\(decoration\|transform\|align\|index\|shadow\)\)\=\|vertical-align\|unicode-bidi\|line-height\)\>"
+syn match cssTextAttr contained "\<line-through\>"
+syn match cssTextAttr contained "\<text-indent\>"
+syn match cssTextAttr contained "\<\(text-\)\=\(top\|bottom\)\>"
+syn keyword cssTextAttr contained underline overline blink sub super middle
+syn keyword cssTextAttr contained capitalize uppercase lowercase center justify baseline sub super
+
+syn match cssBoxProp contained "\<\(margin\|padding\|border\)\(-\(top\|right\|bottom\|left\)\)\=\>"
+syn match cssBoxProp contained "\<border-\(\(\(top\|right\|bottom\|left\)-\)\=\(width\|color\|style\)\)\=\>"
+syn match cssBoxProp contained "\<\(width\|z-index\)\>"
+syn match cssBoxProp contained "\<\(min\|max\)-\(width\|height\)\>"
+syn keyword cssBoxProp contained width height float clear overflow clip visibility
+syn keyword cssBoxAttr contained thin thick both
+syn keyword cssBoxAttr contained dotted dashed solid double groove ridge inset outset
+syn keyword cssBoxAttr contained hidden visible scroll collapse
+
+syn keyword cssGeneratedContentProp contained content quotes
+syn match cssGeneratedContentProp contained "\<counter-\(reset\|increment\)\>"
+syn match cssGeneratedContentProp contained "\<list-style\(-\(type\|position\|image\)\)\=\>"
+syn match cssGeneratedContentAttr contained "\<\(no-\)\=\(open\|close\)-quote\>"
+syn match cssAuralAttr contained "\<lower\>"
+syn match cssGeneratedContentAttr contained "\<\(lower\|upper\)-\(roman\|alpha\|greek\|latin\)\>"
+syn match cssGeneratedContentAttr contained "\<\(hiragana\|katakana\)\(-iroha\)\=\>"
+syn match cssGeneratedContentAttr contained "\<\(decimal\(-leading-zero\)\=\|cjk-ideographic\)\>"
+syn keyword cssGeneratedContentAttr contained disc circle square hebrew armenian georgian
+syn keyword cssGeneratedContentAttr contained inside outside
+
+syn match cssPagingProp contained "\<page\(-break-\(before\|after\|inside\)\)\=\>"
+syn keyword cssPagingProp contained size marks inside orphans widows
+syn keyword cssPagingAttr contained landscape portrait crop cross always avoid
+
+syn keyword cssUIProp contained cursor
+syn match cssUIProp contained "\<outline\(-\(width\|style\|color\)\)\=\>"
+syn match cssUIAttr contained "\<[ns]\=[ew]\=-resize\>"
+syn keyword cssUIAttr contained default crosshair pointer move wait help
+syn keyword cssUIAttr contained thin thick
+syn keyword cssUIAttr contained dotted dashed solid double groove ridge inset outset
+syn keyword cssUIAttr contained invert
+
+syn match cssRenderAttr contained "\<marker\>"
+syn match cssRenderProp contained "\<\(display\|marker-offset\|unicode-bidi\|white-space\|list-item\|run-in\|inline-table\)\>"
+syn keyword cssRenderProp contained position top bottom direction
+syn match cssRenderProp contained "\<\(left\|right\)\>"
+syn keyword cssRenderAttr contained block inline compact
+syn match cssRenderAttr contained "\<table\(-\(row-gorup\|\(header\|footer\)-group\|row\|column\(-group\)\=\|cell\|caption\)\)\=\>"
+syn keyword cssRenderAttr contained static relative absolute fixed
+syn keyword cssRenderAttr contained ltr rtl embed bidi-override pre nowrap
+syn match cssRenderAttr contained "\<bidi-override\>"
+
+
+syn match cssAuralProp contained "\<\(pause\|cue\)\(-\(before\|after\)\)\=\>"
+syn match cssAuralProp contained "\<\(play-during\|speech-rate\|voice-family\|pitch\(-range\)\=\|speak\(-\(punctuation\|numerals\)\)\=\)\>"
+syn keyword cssAuralProp contained volume during azimuth elevation stress richness
+syn match cssAuralAttr contained "\<\(x-\)\=\(soft\|loud\)\>"
+syn keyword cssAuralAttr contained silent
+syn match cssAuralAttr contained "\<spell-out\>"
+syn keyword cssAuralAttr contained non mix
+syn match cssAuralAttr contained "\<\(left\|right\)-side\>"
+syn match cssAuralAttr contained "\<\(far\|center\)-\(left\|center\|right\)\>"
+syn keyword cssAuralAttr contained leftwards rightwards behind
+syn keyword cssAuralAttr contained below level above higher
+syn match cssAuralAttr contained "\<\(x-\)\=\(slow\|fast\)\>"
+syn keyword cssAuralAttr contained faster slower
+syn keyword cssAuralAttr contained male female child code digits continuous
+
+syn match cssTableProp contained "\<\(caption-side\|table-layout\|border-collapse\|border-spacing\|empty-cells\|speak-header\)\>"
+syn keyword cssTableAttr contained fixed collapse separate show hide once always
+
+" FIXME: This allows cssMediaBlock before the semicolon, which is wrong.
+syn region cssInclude start="@import" end=";" contains=cssComment,cssURL,cssUnicodeEscape,cssMediaType
+syn match cssBraces contained "[{}]"
+syn match cssError contained "{@<>"
+syn region cssDefinition transparent matchgroup=cssBraces start='{' end='}' contains=css.*Attr,css.*Prop,cssComment,cssValue.*,cssColor,cssURL,cssImportant,cssError,cssStringQ,cssStringQQ,cssFunction,cssUnicodeEscape
+syn match cssBraceError "}"
+
+syn match cssPseudoClass ":\S*" contains=cssPseudoClassId,cssUnicodeEscape
+syn keyword cssPseudoClassId contained link visited active hover focus before after left right
+syn match cssPseudoClassId contained "\<first\(-\(line\|letter\|child\)\)\=\>"
+syn region cssPseudoClassLang matchgroup=cssPseudoClassId start=":lang(" end=")" oneline
+
+syn region cssComment start="/\*" end="\*/" contains=@Spell
+
+syn match cssUnicodeEscape "\\\x\{1,6}\s\?"
+syn match cssSpecialCharQQ +\\"+ contained
+syn match cssSpecialCharQ +\\'+ contained
+syn region cssStringQQ start=+"+ skip=+\\\\\|\\"+ end=+"+ contains=cssUnicodeEscape,cssSpecialCharQQ
+syn region cssStringQ start=+'+ skip=+\\\\\|\\'+ end=+'+ contains=cssUnicodeEscape,cssSpecialCharQ
+syn match cssClassName "\.[A-Za-z][A-Za-z0-9-]\+"
+
+if main_syntax == "css"
+  syn sync minlines=10
+endif
+
+" Define the default highlighting.
+" For version 5.7 and earlier: only when not done already
+" For version 5.8 and later: only when an item doesn't have highlighting yet
+if version >= 508 || !exists("did_css_syn_inits")
+  if version < 508
+    let did_css_syn_inits = 1
+    command -nargs=+ HiLink hi link <args>
+  else
+    command -nargs=+ HiLink hi def link <args>
+  endif
+
+  HiLink cssComment Comment
+  HiLink cssTagName Statement
+  HiLink cssSelectorOp Special
+  HiLink cssSelectorOp2 Special
+  HiLink cssFontProp StorageClass
+  HiLink cssColorProp StorageClass
+  HiLink cssTextProp StorageClass
+  HiLink cssBoxProp StorageClass
+  HiLink cssRenderProp StorageClass
+  HiLink cssAuralProp StorageClass
+  HiLink cssRenderProp StorageClass
+  HiLink cssGeneratedContentProp StorageClass
+  HiLink cssPagingProp StorageClass
+  HiLink cssTableProp StorageClass
+  HiLink cssUIProp StorageClass
+  HiLink cssFontAttr Type
+  HiLink cssColorAttr Type
+  HiLink cssTextAttr Type
+  HiLink cssBoxAttr Type
+  HiLink cssRenderAttr Type
+  HiLink cssAuralAttr Type
+  HiLink cssGeneratedContentAttr Type
+  HiLink cssPagingAttr Type
+  HiLink cssTableAttr Type
+  HiLink cssUIAttr Type
+  HiLink cssCommonAttr Type
+  HiLink cssPseudoClassId PreProc
+  HiLink cssPseudoClassLang Constant
+  HiLink cssValueLength Number
+  HiLink cssValueInteger Number
+  HiLink cssValueNumber Number
+  HiLink cssValueAngle Number
+  HiLink cssValueTime Number
+  HiLink cssValueFrequency Number
+  HiLink cssFunction Constant
+  HiLink cssURL String
+  HiLink cssFunctionName Function
+  HiLink cssColor Constant
+  HiLink cssIdentifier Function
+  HiLink cssInclude Include
+  HiLink cssImportant Special
+  HiLink cssBraces Function
+  HiLink cssBraceError Error
+  HiLink cssError Error
+  HiLink cssInclude Include
+  HiLink cssUnicodeEscape Special
+  HiLink cssStringQQ String
+  HiLink cssStringQ String
+  HiLink cssMedia Special
+  HiLink cssMediaType Special
+  HiLink cssMediaComma Normal
+  HiLink cssFontDescriptor Special
+  HiLink cssFontDescriptorFunction Constant
+  HiLink cssFontDescriptorProp StorageClass
+  HiLink cssFontDescriptorAttr Type
+  HiLink cssUnicodeRange Constant
+  HiLink cssClassName Function
+  delcommand HiLink
+endif
+
+let b:current_syntax = "css"
+
+if main_syntax == 'css'
+  unlet main_syntax
+endif
+
+
+" vim: ts=8
+
--- /dev/null
+++ b/lib/vimfiles/syntax/cterm.vim
@@ -1,0 +1,190 @@
+" Vim syntax file
+" Language:	Century Term Command Script
+" Maintainer:	Sean M. McKee <mckee@misslink.net>
+" Last Change:	2002 Apr 13
+" Version Info: @(#)cterm.vim	1.7	97/12/15 09:23:14
+
+" For version 5.x: Clear all syntax items
+" For version 6.x: Quit when a syntax file was already loaded
+if version < 600
+  syntax clear
+elseif exists("b:current_syntax")
+  finish
+endif
+
+syn case ignore
+
+"FUNCTIONS
+syn keyword ctermFunction	abort addcr addlf answer at attr batch baud
+syn keyword ctermFunction	break call capture cd cdelay charset cls color
+syn keyword ctermFunction	combase config commect copy cread
+syn keyword ctermFunction	creadint devprefix dialer dialog dimint
+syn keyword ctermFunction	dimlog dimstr display dtimeout dwait edit
+syn keyword ctermFunction	editor emulate erase escloop fcreate
+syn keyword ctermFunction	fflush fillchar flags flush fopen fread
+syn keyword ctermFunction	freadln fseek fwrite fwriteln get hangup
+syn keyword ctermFunction	help hiwait htime ignore init itime
+syn keyword ctermFunction	keyboard lchar ldelay learn lockfile
+syn keyword ctermFunction	locktime log login logout lowait
+syn keyword ctermFunction	lsend ltime memlist menu mkdir mode
+syn keyword ctermFunction	modem netdialog netport noerror pages parity
+syn keyword ctermFunction	pause portlist printer protocol quit rcv
+syn keyword ctermFunction	read readint readn redial release
+syn keyword ctermFunction	remote rename restart retries return
+syn keyword ctermFunction	rmdir rtime run runx scrollback send
+syn keyword ctermFunction	session set setcap setcolor setkey
+syn keyword ctermFunction	setsym setvar startserver status
+syn keyword ctermFunction	stime stopbits stopserver tdelay
+syn keyword ctermFunction	terminal time trans type usend version
+syn keyword ctermFunction	vi vidblink vidcard vidout vidunder wait
+syn keyword ctermFunction	wildsize wclose wopen wordlen wru wruchar
+syn keyword ctermFunction	xfer xmit xprot
+syn match ctermFunction		"?"
+"syn keyword ctermFunction	comment remark
+
+"END FUNCTIONS
+"INTEGER FUNCTIONS
+syn keyword ctermIntFunction	asc atod eval filedate filemode filesize ftell
+syn keyword ctermIntFunction	len termbits opsys pos sum time val mdmstat
+"END INTEGER FUNCTIONS
+
+"STRING FUNCTIONS
+syn keyword ctermStrFunction	cdate ctime chr chrdy chrin comin getenv
+syn keyword ctermStrFunction	gethomedir left midstr right str tolower
+syn keyword ctermStrFunction	toupper uniq comst exists feof hascolor
+
+"END STRING FUNCTIONS
+
+"PREDEFINED TERM VARIABLES R/W
+syn keyword ctermPreVarRW	f _escloop _filename _kermiteol _obufsiz
+syn keyword ctermPreVarRW	_port _rcvsync _cbaud _reval _turnchar
+syn keyword ctermPreVarRW	_txblksiz _txwindow _vmin _vtime _cparity
+syn keyword ctermPreVarRW	_cnumber false t true _cwordlen _cstopbits
+syn keyword ctermPreVarRW	_cmode _cemulate _cxprot _clogin _clogout
+syn keyword ctermPreVarRW	_cstartsrv _cstopsrv _ccmdfile _cwru
+syn keyword ctermPreVarRW	_cprotocol _captfile _cremark _combufsiz
+syn keyword ctermPreVarRW	logfile
+"END PREDEFINED TERM VARIABLES R/W
+
+"PREDEFINED TERM VARIABLES R/O
+syn keyword ctermPreVarRO	_1 _2 _3 _4 _5 _6 _7 _8 _9 _cursess
+syn keyword ctermPreVarRO	_lockfile _baud _errno _retval _sernum
+syn keyword ctermPreVarRO	_timeout _row _col _version
+"END PREDEFINED TERM VARIABLES R/O
+
+syn keyword ctermOperator not mod eq ne gt le lt ge xor and or shr not shl
+
+"SYMBOLS
+syn match   CtermSymbols	 "|"
+"syn keyword ctermOperators + - * / % = != > < >= <= & | ^ ! << >>
+"END SYMBOLS
+
+"STATEMENT
+syn keyword ctermStatement	off
+syn keyword ctermStatement	disk overwrite append spool none
+syn keyword ctermStatement	echo view wrap
+"END STATEMENT
+
+"TYPE
+"syn keyword ctermType
+"END TYPE
+
+"USERLIB FUNCTIONS
+"syn keyword ctermLibFunc
+"END USERLIB FUNCTIONS
+
+"LABEL
+syn keyword ctermLabel    case default
+"END LABEL
+
+"CONDITIONAL
+syn keyword ctermConditional on endon
+syn keyword ctermConditional proc endproc
+syn keyword ctermConditional for in do endfor
+syn keyword ctermConditional if else elseif endif iferror
+syn keyword ctermConditional switch endswitch
+syn keyword ctermConditional repeat until
+"END CONDITIONAL
+
+"REPEAT
+syn keyword ctermRepeat    while
+"END REPEAT
+
+" Function arguments (eg $1 $2 $3)
+syn match  ctermFuncArg	"\$[1-9]"
+
+syn keyword ctermTodo contained TODO
+
+syn match  ctermNumber		"\<\d\+\(u\=l\=\|lu\|f\)\>"
+"floating point number, with dot, optional exponent
+syn match  ctermNumber		"\<\d\+\.\d*\(e[-+]\=\d\+\)\=[fl]\=\>"
+"floating point number, starting with a dot, optional exponent
+syn match  ctermNumber		"\.\d\+\(e[-+]\=\d\+\)\=[fl]\=\>"
+"floating point number, without dot, with exponent
+syn match  ctermNumber		"\<\d\+e[-+]\=\d\+[fl]\=\>"
+"hex number
+syn match  ctermNumber		"0x[0-9a-f]\+\(u\=l\=\|lu\)\>"
+
+syn match  ctermComment		"![^=].*$" contains=ctermTodo
+syn match  ctermComment		"!$"
+syn match  ctermComment		"\*.*$" contains=ctermTodo
+syn region  ctermComment	start="comment" end="$" contains=ctermTodo
+syn region  ctermComment	start="remark" end="$" contains=ctermTodo
+
+syn region ctermVar		start="\$("  end=")"
+
+" String and Character contstants
+" Highlight special characters (those which have a backslash) differently
+syn match   ctermSpecial		contained "\\\d\d\d\|\\."
+syn match   ctermSpecial		contained "\^."
+syn region  ctermString			start=+"+  skip=+\\\\\|\\"+  end=+"+  contains=ctermSpecial,ctermVar,ctermSymbols
+syn match   ctermCharacter		"'[^\\]'"
+syn match   ctermSpecialCharacter	"'\\.'"
+
+" Define the default highlighting.
+" For version 5.7 and earlier: only when not done already
+" For version 5.8 and later: only when an item doesn't have highlighting yet
+if version >= 508 || !exists("did_cterm_syntax_inits")
+  if version < 508
+    let did_cterm_syntax_inits = 1
+    command -nargs=+ HiLink hi link <args>
+  else
+    command -nargs=+ HiLink hi def link <args>
+  endif
+
+	HiLink ctermStatement		Statement
+	HiLink ctermFunction		Statement
+	HiLink ctermStrFunction	Statement
+	HiLink ctermIntFunction	Statement
+	HiLink ctermLabel		Statement
+	HiLink ctermConditional	Statement
+	HiLink ctermRepeat		Statement
+	HiLink ctermLibFunc		UserDefFunc
+	HiLink ctermType		Type
+	HiLink ctermFuncArg		PreCondit
+
+	HiLink ctermPreVarRO		PreCondit
+	HiLink ctermPreVarRW		PreConditBold
+	HiLink ctermVar		Type
+
+	HiLink ctermComment		Comment
+
+	HiLink ctermCharacter		SpecialChar
+	HiLink ctermSpecial		Special
+	HiLink ctermSpecialCharacter	SpecialChar
+	HiLink ctermSymbols		Special
+	HiLink ctermString		String
+	HiLink ctermTodo		Todo
+	HiLink ctermOperator		Statement
+	HiLink ctermNumber		Number
+
+	" redefine the colors
+	"hi PreConditBold	term=bold ctermfg=1 cterm=bold guifg=Purple gui=bold
+	"hi Special	term=bold ctermfg=6 guifg=SlateBlue gui=underline
+
+	delcommand HiLink
+endif
+
+let b:current_syntax = "cterm"
+
+" vim: ts=8
--- /dev/null
+++ b/lib/vimfiles/syntax/ctrlh.vim
@@ -1,0 +1,23 @@
+" Vim syntax file
+" Language:	CTRL-H (e.g., ASCII manpages)
+" Maintainer:	Bram Moolenaar <Bram@vim.org>
+" Last Change:	2005 Jun 20
+
+" Existing syntax is kept, this file can be used as an addition
+
+" Recognize underlined text: _^Hx
+syntax match CtrlHUnderline /_\b./  contains=CtrlHHide
+
+" Recognize bold text: x^Hx
+syntax match CtrlHBold /\(.\)\b\1/  contains=CtrlHHide
+
+" Hide the CTRL-H (backspace)
+syntax match CtrlHHide /.\b/  contained
+
+" Define the default highlighting.
+" Only used when an item doesn't have highlighting yet
+hi def link CtrlHHide Ignore
+hi def CtrlHUnderline term=underline cterm=underline gui=underline
+hi def CtrlHBold term=bold cterm=bold gui=bold
+
+" vim: ts=8
--- /dev/null
+++ b/lib/vimfiles/syntax/cupl.vim
@@ -1,0 +1,130 @@
+" Vim syntax file
+" Language:	CUPL
+" Maintainer:	John Cook <john.cook@kla-tencor.com>
+" Last Change:	2001 Apr 25
+
+" For version 5.x: Clear all syntax items
+" For version 6.x: Quit when a syntax file was already loaded
+if version < 600
+  syntax clear
+elseif exists("b:current_syntax")
+  finish
+endif
+
+" this language is oblivious to case.
+syn case ignore
+
+" A bunch of keywords
+syn keyword cuplHeader name partno date revision rev designer company nextgroup=cuplHeaderContents
+syn keyword cuplHeader assembly assy location device nextgroup=cuplHeaderContents
+
+syn keyword cuplTodo contained TODO XXX FIXME
+
+" cuplHeaderContents uses default highlighting except for numbers
+syn match cuplHeaderContents ".\+;"me=e-1 contains=cuplNumber contained
+
+" String contstants
+syn region cuplString start=+'+ end=+'+
+syn region cuplString start=+"+ end=+"+
+
+syn keyword cuplStatement append condition
+syn keyword cuplStatement default else
+syn keyword cuplStatement field fld format function fuse
+syn keyword cuplStatement group if jump loc
+syn keyword cuplStatement macro min node out
+syn keyword cuplStatement pin pinnode present table
+syn keyword cuplStatement sequence sequenced sequencejk sequencers sequencet
+
+syn keyword cuplFunction log2 log8 log16 log
+
+" Valid integer number formats (decimal, binary, octal, hex)
+syn match cuplNumber "\<[-+]\=[0-9]\+\>"
+syn match cuplNumber "'d'[0-9]\+\>"
+syn match cuplNumber "'b'[01x]\+\>"
+syn match cuplNumber "'o'[0-7x]\+\>"
+syn match cuplNumber "'h'[0-9a-fx]\+\>"
+
+" operators
+syn match cuplLogicalOperator "[!#&$]"
+syn match cuplArithmeticOperator "[-+*/%]"
+syn match cuplArithmeticOperator "\*\*"
+syn match cuplAssignmentOperator ":\=="
+syn match cuplEqualityOperator ":"
+syn match cuplTruthTableOperator "=>"
+
+" Signal extensions
+syn match cuplExtension "\.[as][pr]\>"
+syn match cuplExtension "\.oe\>"
+syn match cuplExtension "\.oemux\>"
+syn match cuplExtension "\.[dlsrjk]\>"
+syn match cuplExtension "\.ck\>"
+syn match cuplExtension "\.dq\>"
+syn match cuplExtension "\.ckmux\>"
+syn match cuplExtension "\.tec\>"
+syn match cuplExtension "\.cnt\>"
+
+syn match cuplRangeOperator "\.\." contained
+
+" match ranges like memadr:[0000..1FFF]
+" and highlight both the numbers and the .. operator
+syn match cuplNumberRange "\<\x\+\.\.\x\+\>" contains=cuplRangeOperator
+
+" match vectors of type [name3..0] (decimal numbers only)
+" but assign them no special highlighting except for the .. operator
+syn match cuplBitVector "\<\a\+\d\+\.\.\d\+\>" contains=cuplRangeOperator
+
+" other special characters
+syn match cuplSpecialChar "[\[\](){},;]"
+
+" directives
+" (define these after cuplOperator so $xxx overrides $)
+syn match cuplDirective "\$msg"
+syn match cuplDirective "\$macro"
+syn match cuplDirective "\$mend"
+syn match cuplDirective "\$repeat"
+syn match cuplDirective "\$repend"
+syn match cuplDirective "\$define"
+syn match cuplDirective "\$include"
+
+" multi-line comments
+syn region cuplComment start=+/\*+ end=+\*/+ contains=cuplNumber,cuplTodo
+
+syn sync minlines=1
+
+" Define the default highlighting.
+" For version 5.7 and earlier: only when not done already
+" For version 5.8 and later: only when an item doesn't have highlighting yet
+if version >= 508 || !exists("did_cupl_syn_inits")
+  if version < 508
+    let did_cupl_syn_inits = 1
+    command -nargs=+ HiLink hi link <args>
+  else
+    command -nargs=+ HiLink hi def link <args>
+  endif
+
+  " The default highlighting.
+  HiLink cuplHeader	cuplStatement
+  HiLink cuplLogicalOperator	 cuplOperator
+  HiLink cuplRangeOperator	 cuplOperator
+  HiLink cuplArithmeticOperator cuplOperator
+  HiLink cuplAssignmentOperator cuplOperator
+  HiLink cuplEqualityOperator	 cuplOperator
+  HiLink cuplTruthTableOperator cuplOperator
+  HiLink cuplOperator	cuplStatement
+  HiLink cuplFunction	cuplStatement
+  HiLink cuplStatement Statement
+  HiLink cuplNumberRange cuplNumber
+  HiLink cuplNumber	  cuplString
+  HiLink cuplString	String
+  HiLink cuplComment	Comment
+  HiLink cuplExtension   cuplSpecial
+  HiLink cuplSpecialChar cuplSpecial
+  HiLink cuplSpecial	Special
+  HiLink cuplDirective PreProc
+  HiLink cuplTodo	Todo
+
+  delcommand HiLink
+endif
+
+let b:current_syntax = "cupl"
+" vim:ts=8
--- /dev/null
+++ b/lib/vimfiles/syntax/cuplsim.vim
@@ -1,0 +1,80 @@
+" Vim syntax file
+" Language:	CUPL simulation
+" Maintainer:	John Cook <john.cook@kla-tencor.com>
+" Last Change:	2001 Apr 25
+
+" For version 5.x: Clear all syntax items
+" For version 6.x: Quit when a syntax file was already loaded
+if version < 600
+  syntax clear
+elseif exists("b:current_syntax")
+  finish
+endif
+
+" Read the CUPL syntax to start with
+if version < 600
+  source <sfile>:p:h/cupl.vim
+else
+  runtime! syntax/cupl.vim
+  unlet b:current_syntax
+endif
+
+" omit definition-specific stuff
+syn clear cuplStatement
+syn clear cuplFunction
+syn clear cuplLogicalOperator
+syn clear cuplArithmeticOperator
+syn clear cuplAssignmentOperator
+syn clear cuplEqualityOperator
+syn clear cuplTruthTableOperator
+syn clear cuplExtension
+
+" simulation order statement
+syn match  cuplsimOrder "order:" nextgroup=cuplsimOrderSpec skipempty
+syn region cuplsimOrderSpec start="." end=";"me=e-1 contains=cuplComment,cuplsimOrderFormat,cuplBitVector,cuplSpecialChar,cuplLogicalOperator,cuplCommaOperator contained
+
+" simulation base statement
+syn match   cuplsimBase "base:" nextgroup=cuplsimBaseSpec skipempty
+syn region  cuplsimBaseSpec start="." end=";"me=e-1 contains=cuplComment,cuplsimBaseType contained
+syn keyword cuplsimBaseType octal decimal hex contained
+
+" simulation vectors statement
+syn match cuplsimVectors "vectors:"
+
+" simulator format control
+syn match cuplsimOrderFormat "%\d\+\>" contained
+
+" simulator control
+syn match cuplsimStimulus "[10ckpx]\+"
+syn match cuplsimStimulus +'\(\x\|x\)\+'+
+syn match cuplsimOutput "[lhznx*]\+"
+syn match cuplsimOutput +"\x\+"+
+
+syn sync minlines=1
+
+" Define the default highlighting.
+" For version 5.7 and earlier: only when not done already
+" For version 5.8 and later: only when an item doesn't have highlighting yet
+if version >= 508 || !exists("did_cuplsim_syn_inits")
+  if version < 508
+    let did_cuplsim_syn_inits = 1
+    command -nargs=+ HiLink hi link <args>
+  else
+    command -nargs=+ HiLink hi def link <args>
+  endif
+
+  " append to the highlighting links in cupl.vim
+  " The default highlighting.
+  HiLink cuplsimOrder		cuplStatement
+  HiLink cuplsimBase		cuplStatement
+  HiLink cuplsimBaseType	cuplStatement
+  HiLink cuplsimVectors		cuplStatement
+  HiLink cuplsimStimulus	cuplNumber
+  HiLink cuplsimOutput		cuplNumber
+  HiLink cuplsimOrderFormat	cuplNumber
+
+  delcommand HiLink
+endif
+
+let b:current_syntax = "cuplsim"
+" vim:ts=8
--- /dev/null
+++ b/lib/vimfiles/syntax/cvs.vim
@@ -1,0 +1,43 @@
+" Vim syntax file
+" Language:	CVS commit file
+" Maintainer:	Matt Dunford (zoot@zotikos.com)
+" URL:		http://www.zotikos.com/downloads/cvs.vim
+" Last Change:	Sat Nov 24 23:25:11 CET 2001
+
+" For version 5.x: Clear all syntax items
+" For version 6.x: Quit when a syntax file was already loaded
+if version < 600
+	syntax clear
+elseif exists("b:current_syntax")
+	finish
+endif
+
+syn region cvsLine start="^CVS: " end="$" contains=cvsFile,cvsCom,cvsFiles,cvsTag
+syn match cvsFile  contained " \t\(\(\S\+\) \)\+"
+syn match cvsTag   contained " Tag:"
+syn match cvsFiles contained "\(Added\|Modified\|Removed\) Files:"
+syn region cvsCom start="Committing in" end="$" contains=cvsDir contained extend keepend
+syn match cvsDir   contained "\S\+$"
+
+" Define the default highlighting.
+" For version 5.7 and earlier: only when not done already
+" For version 5.8 and later: only when an item doesn't have highlighting yet
+if version >= 508 || !exists("did_cvs_syn_inits")
+	if version < 508
+		let did_cvs_syn_inits = 1
+		command -nargs=+ HiLink hi link <args>
+	else
+		command -nargs=+ HiLink hi def link <args>
+	endif
+
+	HiLink cvsLine		Comment
+	HiLink cvsDir		cvsFile
+	HiLink cvsFile		Constant
+	HiLink cvsFiles		cvsCom
+	HiLink cvsTag		cvsCom
+	HiLink cvsCom		Statement
+
+	delcommand HiLink
+endif
+
+let b:current_syntax = "cvs"
--- /dev/null
+++ b/lib/vimfiles/syntax/cvsrc.vim
@@ -1,0 +1,39 @@
+" Vim syntax file
+" Language:         cvs(1) RC file
+" Maintainer:       Nikolai Weibull <now@bitwi.se>
+" Latest Revision:  2006-04-19
+
+if exists("b:current_syntax")
+  finish
+endif
+
+let s:cpo_save = &cpo
+set cpo&vim
+
+syn region  cvsrcString   display oneline start=+"+ skip=+\\\\\|\\\\"+ end=+"+
+syn region  cvsrcString   display oneline start=+'+ skip=+\\\\\|\\\\'+ end=+'+
+
+syn match   cvsrcNumber   display '\<\d\+\>'
+
+syn match   cvsrcBegin    display '^' nextgroup=cvsrcCommand skipwhite
+
+syn region  cvsrcCommand  contained transparent matchgroup=cvsrcCommand
+                          \ start='add\|admin\|checkout\|commit\|cvs\|diff'
+                          \ start='export\|history\|import\|init\|log'
+                          \ start='rdiff\|release\|remove\|rtag\|status\|tag'
+                          \ start='update'
+                          \ end='$'
+                          \ contains=cvsrcOption,cvsrcString,cvsrcNumber
+                          \ keepend
+
+syn match   cvsrcOption   contained display '-\a\+'
+
+hi def link cvsrcString   String
+hi def link cvsrcNumber   Number
+hi def link cvsrcCommand  Keyword
+hi def link cvsrcOption   Identifier
+
+let b:current_syntax = "cvsrc"
+
+let &cpo = s:cpo_save
+unlet s:cpo_save
--- /dev/null
+++ b/lib/vimfiles/syntax/cweb.vim
@@ -1,0 +1,80 @@
+" Vim syntax file
+" Language:	CWEB
+" Maintainer:	Andreas Scherer <andreas.scherer@pobox.com>
+" Last Change:	April 30, 2001
+
+" Details of the CWEB language can be found in the article by Donald E. Knuth
+" and Silvio Levy, "The CWEB System of Structured Documentation", included as
+" file "cwebman.tex" in the standard CWEB distribution, available for
+" anonymous ftp at ftp://labrea.stanford.edu/pub/cweb/.
+
+" TODO: Section names and C/C++ comments should be treated as TeX material.
+" TODO: The current version switches syntax highlighting off for section
+" TODO: names, and leaves C/C++ comments as such. (On the other hand,
+" TODO: switching to TeX mode in C/C++ comments might be colour overkill.)
+
+" For version 5.x: Clear all syntax items
+" For version 6.x: Quit when a syntax file was already loaded
+if version < 600
+  syntax clear
+elseif exists("b:current_syntax")
+  finish
+endif
+
+" For starters, read the TeX syntax; TeX syntax items are allowed at the top
+" level in the CWEB syntax, e.g., in the preamble.  In general, a CWEB source
+" code can be seen as a normal TeX document with some C/C++ material
+" interspersed in certain defined regions.
+if version < 600
+  source <sfile>:p:h/tex.vim
+else
+  runtime! syntax/tex.vim
+  unlet b:current_syntax
+endif
+
+" Read the C/C++ syntax too; C/C++ syntax items are treated as such in the
+" C/C++ section of a CWEB chunk or in inner C/C++ context in "|...|" groups.
+syntax include @webIncludedC <sfile>:p:h/cpp.vim
+
+" Inner C/C++ context (ICC) should be quite simple as it's comprised of
+" material in "|...|"; however the naive definition for this region would
+" hickup at the innocious "\|" TeX macro.  Note: For the time being we expect
+" that an ICC begins either at the start of a line or after some white space.
+syntax region webInnerCcontext start="\(^\|[ \t\~`(]\)|" end="|" contains=@webIncludedC,webSectionName,webRestrictedTeX,webIgnoredStuff
+
+" Genuine C/C++ material.  This syntactic region covers both the definition
+" part and the C/C++ part of a CWEB section; it is ended by the TeX part of
+" the next section.
+syntax region webCpart start="@[dfscp<(]" end="@[ \*]" contains=@webIncludedC,webSectionName,webRestrictedTeX,webIgnoredStuff
+
+" Section names contain C/C++ material only in inner context.
+syntax region webSectionName start="@[<(]" end="@>" contains=webInnerCcontext contained
+
+" The contents of "control texts" is not treated as TeX material, because in
+" non-trivial cases this completely clobbers the syntax recognition.  Instead,
+" we highlight these elements as "strings".
+syntax region webRestrictedTeX start="@[\^\.:t=q]" end="@>" oneline
+
+" Double-@ means single-@, anywhere in the CWEB source.  (This allows e-mail
+" address <someone@@fsf.org> without going into C/C++ mode.)
+syntax match webIgnoredStuff "@@"
+
+" Define the default highlighting.
+" For version 5.7 and earlier: only when not done already
+" For version 5.8 and later: only when an item doesn't have highlighting yet
+if version >= 508 || !exists("did_cweb_syntax_inits")
+  if version < 508
+    let did_cweb_syntax_inits = 1
+    command -nargs=+ HiLink hi link <args>
+  else
+    command -nargs=+ HiLink hi def link <args>
+  endif
+
+  HiLink webRestrictedTeX String
+
+  delcommand HiLink
+endif
+
+let b:current_syntax = "cweb"
+
+" vim: ts=8
--- /dev/null
+++ b/lib/vimfiles/syntax/cynlib.vim
@@ -1,0 +1,91 @@
+" Vim syntax file
+" Language:     Cynlib(C++)
+" Maintainer:   Phil Derrick <phild@forteds.com>
+" Last change:  2001 Sep 02
+" URL http://www.derrickp.freeserve.co.uk/vim/syntax/cynlib.vim
+"
+" Language Information
+"
+"		Cynlib is a library of C++ classes to allow hardware
+"		modelling in C++. Combined with a simulation kernel,
+"		the compiled and linked executable forms a hardware
+"		simulation of the described design.
+"
+"		Further information can be found from www.forteds.com
+
+
+" Remove any old syntax stuff hanging around
+" For version 5.x: Clear all syntax items
+" For version 6.x: Quit when a syntax file was already loaded
+if version < 600
+  syntax clear
+elseif exists("b:current_syntax")
+  finish
+endif
+
+
+
+" Read the C++ syntax to start with - this includes the C syntax
+if version < 600
+  source <sfile>:p:h/cpp.vim
+else
+  runtime! syntax/cpp.vim
+endif
+unlet b:current_syntax
+
+" Cynlib extensions
+
+syn keyword	cynlibMacro	   Default CYNSCON
+syn keyword	cynlibMacro	   Case CaseX EndCaseX
+syn keyword	cynlibType	   CynData CynSignedData CynTime
+syn keyword	cynlibType	   In Out InST OutST
+syn keyword	cynlibType	   Struct
+syn keyword	cynlibType	   Int Uint Const
+syn keyword	cynlibType	   Long Ulong
+syn keyword	cynlibType	   OneHot
+syn keyword	cynlibType	   CynClock Cynclock0
+syn keyword     cynlibFunction     time configure my_name
+syn keyword     cynlibFunction     CynModule epilog execute_on
+syn keyword     cynlibFunction     my_name
+syn keyword     cynlibFunction     CynBind bind
+syn keyword     cynlibFunction     CynWait CynEvent
+syn keyword     cynlibFunction     CynSetName
+syn keyword     cynlibFunction     CynTick CynRun
+syn keyword     cynlibFunction     CynFinish
+syn keyword     cynlibFunction     Cynprintf CynSimTime
+syn keyword     cynlibFunction     CynVcdFile
+syn keyword     cynlibFunction     CynVcdAdd CynVcdRemove
+syn keyword     cynlibFunction     CynVcdOn CynVcdOff
+syn keyword     cynlibFunction     CynVcdScale
+syn keyword     cynlibFunction     CynBgnName CynEndName
+syn keyword     cynlibFunction     CynClock configure time
+syn keyword     cynlibFunction     CynRedAnd CynRedNand
+syn keyword     cynlibFunction     CynRedOr CynRedNor
+syn keyword     cynlibFunction     CynRedXor CynRedXnor
+syn keyword     cynlibFunction     CynVerify
+
+
+syn match       cynlibOperator     "<<="
+syn keyword	cynlibType	   In Out InST OutST Int Uint Const Cynclock
+
+" Define the default highlighting.
+" For version 5.7 and earlier: only when not done already
+" For version 5.8 and later: only when an item doesn't have highlighting yet
+if version >= 508 || !exists("did_cynlib_syntax_inits")
+  if version < 508
+    let did_cynlib_syntax_inits = 1
+    command -nargs=+ HiLink hi link <args>
+  else
+    command -nargs=+ HiLink hi def link <args>
+  endif
+
+  HiLink cynlibOperator   Operator
+  HiLink cynlibMacro      Statement
+  HiLink cynlibFunction   Statement
+  HiLink cynlibppMacro      Statement
+  HiLink cynlibType       Type
+
+  delcommand HiLink
+endif
+
+let b:current_syntax = "cynlib"
--- /dev/null
+++ b/lib/vimfiles/syntax/cynpp.vim
@@ -1,0 +1,68 @@
+" Vim syntax file
+" Language:     Cyn++
+" Maintainer:   Phil Derrick <phild@forteds.com>
+" Last change:  2001 Sep 02
+"
+" Language Information
+"
+"		Cynpp (Cyn++) is a macro language to ease coding in Cynlib.
+"		Cynlib is a library of C++ classes to allow hardware
+"		modelling in C++. Combined with a simulation kernel,
+"		the compiled and linked executable forms a hardware
+"		simulation of the described design.
+"
+"		Cyn++ is designed to be HDL-like.
+"
+"		Further information can be found from www.forteds.com
+
+
+
+
+
+" Remove any old syntax stuff hanging around
+" For version 5.x: Clear all syntax items
+" For version 6.x: Quit when a syntax file was already loaded
+if version < 600
+  syntax clear
+elseif exists("b:current_syntax")
+  finish
+endif
+
+" Read the Cynlib syntax to start with - this includes the C++ syntax
+if version < 600
+  source <sfile>:p:h/cynlib.vim
+else
+  runtime! syntax/cynlib.vim
+endif
+unlet b:current_syntax
+
+
+
+" Cyn++ extensions
+
+syn keyword     cynppMacro      Always EndAlways
+syn keyword     cynppMacro      Module EndModule
+syn keyword     cynppMacro      Initial EndInitial
+syn keyword     cynppMacro      Posedge Negedge Changed
+syn keyword     cynppMacro      At
+syn keyword     cynppMacro      Thread EndThread
+syn keyword     cynppMacro      Instantiate
+
+" Define the default highlighting.
+" For version 5.7 and earlier: only when not done already
+" For version 5.8 and later: only when an item doesn't have highlighting yet
+if version >= 508 || !exists("did_cynpp_syntax_inits")
+  if version < 508
+    let did_cynpp_syntax_inits = 1
+    command -nargs=+ HiLink hi link <args>
+  else
+    command -nargs=+ HiLink hi def link <args>
+  endif
+
+  HiLink cLabel		Label
+  HiLink cynppMacro  Statement
+
+  delcommand HiLink
+endif
+
+let b:current_syntax = "cynpp"
--- /dev/null
+++ b/lib/vimfiles/syntax/d.vim
@@ -1,0 +1,230 @@
+" Vim syntax file for the D programming language (version 0.149).
+"
+" Language:	D
+" Maintainer:	Jason Mills<jmills@cs.mun.ca>
+"   When emailing me, please put the word vim somewhere in the subject
+"   to ensure the email does not get marked as spam.
+" Last Change:	2006 Apr 30
+" Version:	0.15
+"
+" Options:
+"   d_comment_strings - set to highlight strings and numbers in comments
+"
+"   d_hl_operator_overload - set to highlight D's specially named functions
+"   that when overloaded implement unary and binary operators (e.g. cmp).
+"
+" Todo:
+"   - Must determine a better method of sync'ing than simply setting minlines
+"   to a large number for /+ +/.
+"
+"   - Several keywords (namely, in and out) are both storage class and
+"   statements, depending on their context. Must use some matching to figure
+"   out which and highlight appropriately. For now I have made such keywords
+"   statements.
+"
+"   - Mark contents of the asm statement body as special
+"
+
+" Quit when a syntax file was already loaded
+if exists("b:current_syntax")
+  finish
+endif
+
+" Keyword definitions
+"
+syn keyword dExternal		import package module extern
+syn keyword dConditional	if else switch iftype
+syn keyword dBranch		goto break continue
+syn keyword dRepeat		while for do foreach
+syn keyword dBoolean		true false
+syn keyword dConstant		null
+syn keyword dConstant		__FILE__ __LINE__ __DATE__ __TIME__ __TIMESTAMP__
+syn keyword dTypedef		alias typedef
+syn keyword dStructure		template interface class enum struct union
+syn keyword dOperator		new delete typeof typeid cast align is
+syn keyword dOperator		this super
+if exists("d_hl_operator_overload")
+  syn keyword dOpOverload	opNeg opCom opPostInc opPostDec opCast opAdd opSub opSub_r
+  syn keyword dOpOverload	opMul opDiv opDiv_r opMod opMod_r opAnd opOr opXor
+  syn keyword dOpOverload	opShl opShl_r opShr opShr_r opUShr opUShr_r opCat
+  syn keyword dOpOverload	opCat_r opEquals opEquals opCmp opCmp opCmp opCmp
+  syn keyword dOpOverload	opAddAssign opSubAssign opMulAssign opDivAssign
+  syn keyword dOpOverload	opModAssign opAndAssign opOrAssign opXorAssign
+  syn keyword dOpOverload	opShlAssign opShrAssign opUShrAssign opCatAssign
+  syn keyword dOpOverload	opIndex opIndexAssign opCall opSlice opSliceAssign opPos
+  syn keyword dOpOverload	opAdd_r opMul_r opAnd_r opOr_r opXor_r 
+endif
+syn keyword dType		ushort int uint long ulong float
+syn keyword dType		void byte ubyte double bit char wchar ucent cent
+syn keyword dType		short bool dchar
+syn keyword dType		real ireal ifloat idouble creal cfloat cdouble
+syn keyword dDebug		deprecated unittest
+syn keyword dExceptions		throw try catch finally
+syn keyword dScopeDecl		public protected private export
+syn keyword dStatement		version debug return with invariant body scope
+syn keyword dStatement		in out inout asm mixin
+syn keyword dStatement		function delegate
+syn keyword dStorageClass	auto static override final const abstract volatile
+syn keyword dStorageClass	synchronized
+syn keyword dPragma		pragma
+
+
+" Assert is a statement and a module name.
+syn match dAssert "^assert\>"
+syn match dAssert "[^.]\s*\<assert\>"ms=s+1
+
+" Marks contents of the asm statment body as special
+"
+" TODO
+"syn match dAsmStatement "\<asm\>"
+"syn region dAsmBody start="asm[\n]*\s*{"hs=e+1 end="}"he=e-1 contains=dAsmStatement
+"
+"hi def link dAsmBody dUnicode
+"hi def link dAsmStatement dStatement
+
+" Labels
+"
+" We contain dScopeDecl so public: private: etc. are not highlighted like labels
+syn match dUserLabel	"^\s*[_$a-zA-Z][_$a-zA-Z0-9_]*\s*:"he=e-1 contains=dLabel,dScopeDecl
+syn keyword dLabel	case default
+
+" Comments
+"
+syn keyword dTodo	contained TODO FIXME TEMP XXX
+syn match dCommentStar	contained "^\s*\*[^/]"me=e-1
+syn match dCommentStar	contained "^\s*\*$"
+syn match dCommentPlus	contained "^\s*+[^/]"me=e-1
+syn match dCommentPlus	contained "^\s*+$"
+if exists("d_comment_strings")
+  syn region dBlockCommentString	contained start=+"+ end=+"+ end=+\*/+me=s-1,he=s-1 contains=dCommentStar,dUnicode,dEscSequence,@Spell
+  syn region dNestedCommentString	contained start=+"+ end=+"+ end="+"me=s-1,he=s-1 contains=dCommentPlus,dUnicode,dEscSequence,@Spell
+  syn region dLineCommentString		contained start=+"+ end=+$\|"+ contains=dUnicode,dEscSequence,@Spell
+  syn region dBlockComment	start="/\*"  end="\*/" contains=dBlockCommentString,dTodo,@Spell
+  syn region dNestedComment	start="/+"  end="+/" contains=dNestedComment,dNestedCommentString,dTodo,@Spell
+  syn match  dLineComment	"//.*" contains=dLineCommentString,dTodo,@Spell
+else
+  syn region dBlockComment	start="/\*"  end="\*/" contains=dBlockCommentString,dTodo,@Spell
+  syn region dNestedComment	start="/+"  end="+/" contains=dNestedComment,dNestedCommentString,dTodo,@Spell
+  syn match  dLineComment	"//.*" contains=dLineCommentString,dTodo,@Spell
+endif
+
+hi link dLineCommentString	dBlockCommentString
+hi link dBlockCommentString	dString
+hi link dNestedCommentString	dString
+hi link dCommentStar		dBlockComment
+hi link dCommentPlus		dNestedComment
+
+" /+ +/ style comments and strings that span multiple lines can cause
+" problems. To play it safe, set minlines to a large number.
+syn sync minlines=200
+" Use ccomment for /* */ style comments
+syn sync ccomment dBlockComment
+
+" Characters
+"
+syn match dSpecialCharError contained "[^']"
+
+" Escape sequences (oct,specal char,hex,wchar, character entities \&xxx;)
+" These are not contained because they are considered string litterals
+syn match dEscSequence	"\\\(\o\{1,3}\|[\"\\'\\?ntbrfva]\|u\x\{4}\|U\x\{8}\|x\x\x\)"
+syn match dEscSequence "\\&[^;& \t]\+;"
+syn match dCharacter	"'[^']*'" contains=dEscSequence,dSpecialCharError
+syn match dCharacter	"'\\''" contains=dEscSequence
+syn match dCharacter	"'[^\\]'"
+
+" Unicode characters
+"
+syn match dUnicode "\\u\d\{4\}"
+
+
+" String.
+"
+syn region dString	start=+"+ end=+"[cwd]\=+ contains=dEscSequence,@Spell
+syn region dRawString	start=+`+ skip=+\\`+ end=+`[cwd]\=+ contains=@Spell
+syn region dRawString	start=+r"+ skip=+\\"+ end=+"[cwd]\=+ contains=@Spell
+syn region dHexString	start=+x"+ skip=+\\"+ end=+"[cwd]\=+ contains=@Spell
+
+" Numbers
+"
+syn case ignore
+
+syn match dDec		display "\<\d[0-9_]*\(u\=l\=\|l\=u\=\)\>"
+
+" Hex number
+syn match dHex		display "\<0x[0-9a-f_]\+\(u\=l\=\|l\=u\=\)\>"
+
+syn match dOctal	display "\<0[0-7_]\+\(u\=l\=\|l\=u\=\)\>"
+" flag an octal number with wrong digits
+syn match dOctalError	display "\<0[0-7_]*[89][0-9_]*"
+
+" binary numbers
+syn match dBinary	display "\<0b[01_]\+\(u\=l\=\|l\=u\=\)\>"
+
+"floating point without the dot
+syn match dFloat	display "\<\d[0-9_]*\(fi\=\|l\=i\)\>"
+"floating point number, with dot, optional exponent
+syn match dFloat	display "\<\d[0-9_]*\.[0-9_]*\(e[-+]\=[0-9_]\+\)\=[fl]\=i\="
+"floating point number, starting with a dot, optional exponent
+syn match dFloat	display "\(\.[0-9_]\+\)\(e[-+]\=[0-9_]\+\)\=[fl]\=i\=\>"
+"floating point number, without dot, with exponent
+"syn match dFloat	display "\<\d\+e[-+]\=\d\+[fl]\=\>"
+syn match dFloat	display "\<\d[0-9_]*e[-+]\=[0-9_]\+[fl]\=\>"
+
+"floating point without the dot
+syn match dHexFloat	display "\<0x[0-9a-f_]\+\(fi\=\|l\=i\)\>"
+"floating point number, with dot, optional exponent
+syn match dHexFloat	display "\<0x[0-9a-f_]\+\.[0-9a-f_]*\(p[-+]\=[0-9_]\+\)\=[fl]\=i\="
+"floating point number, without dot, with exponent
+syn match dHexFloat	display "\<0x[0-9a-f_]\+p[-+]\=[0-9_]\+[fl]\=i\=\>"
+
+syn case match
+
+" Pragma (preprocessor) support
+" TODO: Highlight following Integer and optional Filespec.
+syn region  dPragma start="#\s*\(line\>\)" skip="\\$" end="$"
+
+
+" The default highlighting.
+"
+hi def link dBinary		Number
+hi def link dDec		Number
+hi def link dHex		Number
+hi def link dOctal		Number
+hi def link dFloat		Float
+hi def link dHexFloat		Float
+hi def link dDebug		Debug
+hi def link dBranch		Conditional
+hi def link dConditional	Conditional
+hi def link dLabel		Label
+hi def link dUserLabel		Label
+hi def link dRepeat		Repeat
+hi def link dExceptions		Exception
+hi def link dAssert		Statement
+hi def link dStatement		Statement
+hi def link dScopeDecl		dStorageClass
+hi def link dStorageClass	StorageClass
+hi def link dBoolean		Boolean
+hi def link dUnicode		Special
+hi def link dRawString		String
+hi def link dString		String
+hi def link dHexString		String
+hi def link dCharacter		Character
+hi def link dEscSequence	SpecialChar
+hi def link dSpecialCharError	Error
+hi def link dOctalError		Error
+hi def link dOperator		Operator
+hi def link dOpOverload		Operator
+hi def link dConstant		Constant
+hi def link dTypedef		Typedef
+hi def link dStructure		Structure
+hi def link dTodo		Todo
+hi def link dType		Type
+hi def link dLineComment	Comment
+hi def link dBlockComment	Comment
+hi def link dNestedComment	Comment
+hi def link dExternal		Include
+hi def link dPragma		PreProc
+
+let b:current_syntax = "d"
+   
+" vim: ts=8 noet
--- /dev/null
+++ b/lib/vimfiles/syntax/dcd.vim
@@ -1,0 +1,64 @@
+" Vim syntax file
+" Language:	WildPackets EtherPeek Decoder (.dcd) file
+" Maintainer:	Christopher Shinn <christopher@lucent.com>
+" Last Change:	2003 Apr 25
+
+" For version 5.x: Clear all syntax items
+" For version 6.x: Quit when a syntax file was already loaded
+if version < 600
+  syntax clear
+elseif exists("b:current_syntax")
+  finish
+endif
+
+" Keywords
+syn keyword dcdFunction		DCod TRTS TNXT CRLF
+syn match   dcdFunction		display "\(STR\)\#"
+syn keyword dcdLabel		LABL
+syn region  dcdLabel		start="[A-Z]" end=";"
+syn keyword dcdConditional	CEQU CNEQ CGTE CLTE CBIT CLSE
+syn keyword dcdConditional	LSTS LSTE LSTZ
+syn keyword dcdConditional	TYPE TTST TEQU TNEQ TGTE TLTE TBIT TLSE TSUB SKIP
+syn keyword dcdConditional	MARK WHOA
+syn keyword dcdConditional	SEQU SNEQ SGTE SLTE SBIT
+syn match   dcdConditional	display "\(CST\)\#" "\(TST\)\#"
+syn keyword dcdDisplay		HBIT DBIT BBIT
+syn keyword dcdDisplay		HBYT DBYT BBYT
+syn keyword dcdDisplay		HWRD DWRD BWRD
+syn keyword dcdDisplay		HLNG DLNG BLNG
+syn keyword dcdDisplay		D64B
+syn match   dcdDisplay		display "\(HEX\)\#" "\(CHR\)\#" "\(EBC\)\#"
+syn keyword dcdDisplay		HGLB DGLB BGLB
+syn keyword dcdDisplay		DUMP
+syn keyword dcdStatement	IPLG IPV6 ATLG AT03 AT01 ETHR TRNG PRTO PORT
+syn keyword dcdStatement	TIME OSTP PSTR CSTR NBNM DMPE FTPL CKSM FCSC
+syn keyword dcdStatement	GBIT GBYT GWRD GLNG
+syn keyword dcdStatement	MOVE ANDG ORRG NOTG ADDG SUBG MULG DIVG MODG INCR DECR
+syn keyword dcdSpecial		PRV1 PRV2 PRV3 PRV4 PRV5 PRV6 PRV7 PRV8
+
+" Comment
+syn region  dcdComment		start="\*" end="\;"
+
+" Define the default highlighting.
+" For version 5.7 and earlier: only when not done already
+" For version 5.8 and later: only when an item doesn't have highlighting yet
+if version >= 508 || !exists("did_dcd_syntax_inits")
+  if version < 508
+    let did_dcd_syntax_inits = 1
+    command -nargs=+ HiLink hi link <args>
+  else
+    command -nargs=+ HiLink hi def link <args>
+  endif
+
+  HiLink dcdFunction		Identifier
+  HiLink dcdLabel		Constant
+  HiLink dcdConditional		Conditional
+  HiLink dcdDisplay		Type
+  HiLink dcdStatement		Statement
+  HiLink dcdSpecial		Special
+  HiLink dcdComment		Comment
+
+  delcommand HiLink
+endif
+
+let b:current_syntax = "dcd"
--- /dev/null
+++ b/lib/vimfiles/syntax/dcl.vim
@@ -1,0 +1,164 @@
+" Vim syntax file
+" Language:	DCL (Digital Command Language - vms)
+" Maintainer:	Dr. Charles E. Campbell, Jr. <NdrOchipS@PcampbellAfamily.Mbiz>
+" Last Change:	Sep 11, 2006
+" Version:	6
+" URL:	http://mysite.verizon.net/astronaut/vim/index.html#vimlinks_syntax
+
+" For version 5.x: Clear all syntax items
+" For version 6.x: Quit when a syntax file was already loaded
+if version < 600
+  syntax clear
+elseif exists("b:current_syntax")
+  finish
+endif
+
+if version < 600
+  set iskeyword=$,@,48-57,_
+else
+  setlocal iskeyword=$,@,48-57,_
+endif
+
+syn case ignore
+syn keyword dclInstr	accounting	del[ete]	gen[cat]	mou[nt]	run
+syn keyword dclInstr	all[ocate]	dep[osit]	gen[eral]	ncp	run[off]
+syn keyword dclInstr	ana[lyze]	dia[gnose]	gos[ub]	ncs	sca
+syn keyword dclInstr	app[end]	dif[ferences]	got[o]	on	sea[rch]
+syn keyword dclInstr	ass[ign]	dir[ectory]	hel[p]	ope[n]	set
+syn keyword dclInstr	att[ach]	dis[able]	ico[nv]	pas[cal]	sho[w]
+syn keyword dclInstr	aut[horize]	dis[connect]	if	pas[sword]	sor[t]
+syn keyword dclInstr	aut[ogen]	dis[mount]	ini[tialize]	pat[ch]	spa[wn]
+syn keyword dclInstr	bac[kup]	dpm[l]	inq[uire]	pca	sta[rt]
+syn keyword dclInstr	cal[l]	dqs	ins[tall]	pho[ne]	sto[p]
+syn keyword dclInstr	can[cel]	dsr	job	pri[nt]	sub[mit]
+syn keyword dclInstr	cc	dst[graph]	lat[cp]	pro[duct]	sub[routine]
+syn keyword dclInstr	clo[se]	dtm	lib[rary]	psw[rap]	swx[cr]
+syn keyword dclInstr	cms	dum[p]	lic[ense]	pur[ge]	syn[chronize]
+syn keyword dclInstr	con[nect]	edi[t]	lin[k]	qde[lete]	sys[gen]
+syn keyword dclInstr	con[tinue]	ena[ble]	lmc[p]	qse[t]	sys[man]
+syn keyword dclInstr	con[vert]	end[subroutine]	loc[ale]	qsh[ow]	tff
+syn keyword dclInstr	cop[y]	eod	log[in]	rea[d]	then
+syn keyword dclInstr	cre[ate]	eoj	log[out]	rec[all]	typ[e]
+syn keyword dclInstr	cxx	exa[mine]	lse[dit]	rec[over]	uil
+syn keyword dclInstr	cxx[l_help]	exc[hange]	mac[ro]	ren[ame]	unl[ock]
+syn keyword dclInstr	dea[llocate]	exi[t]	mai[l]	rep[ly]	ves[t]
+syn keyword dclInstr	dea[ssign]	fdl	mer[ge]	req[uest]	vie[w]
+syn keyword dclInstr	deb[ug]	flo[wgraph]	mes[sage]	ret[urn]	wai[t]
+syn keyword dclInstr	dec[k]	fon[t]	mms	rms	wri[te]
+syn keyword dclInstr	def[ine]	for[tran]
+
+syn keyword dclLexical	f$context	f$edit	  f$getjpi	f$message	f$setprv
+syn keyword dclLexical	f$csid	f$element	  f$getqui	f$mode	f$string
+syn keyword dclLexical	f$cvsi	f$environment	  f$getsyi	f$parse	f$time
+syn keyword dclLexical	f$cvtime	f$extract	  f$identifier	f$pid	f$trnlnm
+syn keyword dclLexical	f$cvui	f$fao	  f$integer	f$privilege	f$type
+syn keyword dclLexical	f$device	f$file_attributes f$length	f$process	f$user
+syn keyword dclLexical	f$directory	f$getdvi	  f$locate	f$search	f$verify
+
+syn match   dclMdfy	"/\I\i*"	nextgroup=dclMdfySet,dclMdfySetString
+syn match   dclMdfySet	"=[^ \t"]*"	contained
+syn region  dclMdfySet	matchgroup=dclMdfyBrkt start="=\[" matchgroup=dclMdfyBrkt end="]"	contains=dclMdfySep
+syn region  dclMdfySetString	start='="'	skip='""'	end='"'	contained
+syn match   dclMdfySep	"[:,]"	contained
+
+" Numbers
+syn match   dclNumber	"\d\+"
+
+" Varname (mainly to prevent dclNumbers from being recognized when part of a dclVarname)
+syn match   dclVarname	"\I\i*"
+
+" Filenames (devices, paths)
+syn match   dclDevice	"\I\i*\(\$\I\i*\)\=:[^=]"me=e-1		nextgroup=dclDirPath,dclFilename
+syn match   dclDirPath	"\[\(\I\i*\.\)*\I\i*\]"		contains=dclDirSep	nextgroup=dclFilename
+syn match   dclFilename	"\I\i*\$\(\I\i*\)\=\.\(\I\i*\)*\(;\d\+\)\="	contains=dclDirSep
+syn match   dclFilename	"\I\i*\.\(\I\i*\)\=\(;\d\+\)\="	contains=dclDirSep	contained
+syn match   dclDirSep	"[[\].;]"
+
+" Strings
+syn region  dclString	start='"'	skip='""'	end='"'	contains=@Spell
+
+" $ stuff and comments
+syn cluster dclCommentGroup	contains=dclStart,dclTodo,@Spell
+syn match   dclStart	"^\$"	skipwhite nextgroup=dclExe
+syn match   dclContinue	"-$"
+syn match   dclComment	"^\$!.*$"	contains=@dclCommentGroup
+syn match   dclExe	"\I\i*"	contained
+syn keyword dclTodo contained	COMBAK	DEBUG	FIXME	TODO	XXX
+
+" Assignments and Operators
+syn match   dclAssign	":==\="
+syn match   dclAssign	"="
+syn match   dclOper	"--\|+\|\*\|/"
+syn match   dclLogOper	"\.[a-zA-Z][a-zA-Z][a-zA-Z]\=\." contains=dclLogical,dclLogSep
+syn keyword dclLogical contained	and	ge	gts	lt	nes
+syn keyword dclLogical contained	eq	ges	le	lts	not
+syn keyword dclLogical contained	eqs	gt	les	ne	or
+syn match   dclLogSep	"\."		contained
+
+" @command procedures
+syn match   dclCmdProcStart	"@"			nextgroup=dclCmdProc
+syn match   dclCmdProc	"\I\i*\(\.\I\i*\)\="	contained
+syn match   dclCmdProc	"\I\i*:"		contained	nextgroup=dclCmdDirPath,dclCmdProc
+syn match   dclCmdDirPath	"\[\(\I\i*\.\)*\I\i*\]"	contained	nextgroup=delCmdProc
+
+" labels
+syn match   dclGotoLabel	"^\$\s*\I\i*:\s*$"	contains=dclStart
+
+" parameters
+syn match   dclParam	"'\I[a-zA-Z0-9_$]*'\="
+
+" () matching (the clusters are commented out until a vim/vms comes out for v5.2+)
+"syn cluster dclNextGroups	contains=dclCmdDirPath,dclCmdProc,dclCmdProc,dclDirPath,dclFilename,dclFilename,dclMdfySet,dclMdfySetString,delCmdProc,dclExe,dclTodo
+"syn region  dclFuncList	matchgroup=Delimiter start="(" matchgroup=Delimiter end=")" contains=ALLBUT,@dclNextGroups
+syn region  dclFuncList	matchgroup=Delimiter start="(" matchgroup=Delimiter end=")" contains=ALLBUT,dclCmdDirPath,dclCmdProc,dclCmdProc,dclDirPath,dclFilename,dclFilename,dclMdfySet,dclMdfySetString,delCmdProc,dclExe,dclTodo
+syn match   dclError	")"
+
+" Define the default highlighting.
+" For version 5.7 and earlier: only when not done already
+" For version 5.8 and later: only when an item doesn't have highlighting yet
+if version >= 508 || !exists("did_dcl_syntax_inits")
+  if version < 508
+    let did_dcl_syntax_inits = 1
+    command -nargs=+ HiLink hi link <args>
+  else
+    command -nargs=+ HiLink hi def link <args>
+  endif
+
+ HiLink dclLogOper	dclError
+ HiLink dclLogical	dclOper
+ HiLink dclLogSep	dclSep
+
+ HiLink dclAssign	Operator
+ HiLink dclCmdProc	Special
+ HiLink dclCmdProcStart	Operator
+ HiLink dclComment	Comment
+ HiLink dclContinue	Statement
+ HiLink dclDevice	Identifier
+ HiLink dclDirPath	Identifier
+ HiLink dclDirPath	Identifier
+ HiLink dclDirSep	Delimiter
+ HiLink dclError	Error
+ HiLink dclExe		Statement
+ HiLink dclFilename	NONE
+ HiLink dclGotoLabel	Label
+ HiLink dclInstr	Statement
+ HiLink dclLexical	Function
+ HiLink dclMdfy	Type
+ HiLink dclMdfyBrkt	Delimiter
+ HiLink dclMdfySep	Delimiter
+ HiLink dclMdfySet	Type
+ HiLink dclMdfySetString	String
+ HiLink dclNumber	Number
+ HiLink dclOper	Operator
+ HiLink dclParam	Special
+ HiLink dclSep		Delimiter
+ HiLink dclStart	Delimiter
+ HiLink dclString	String
+ HiLink dclTodo	Todo
+
+ delcommand HiLink
+endif
+
+let b:current_syntax = "dcl"
+
+" vim: ts=16
--- /dev/null
+++ b/lib/vimfiles/syntax/debchangelog.vim
@@ -1,0 +1,56 @@
+" Vim syntax file
+" Language:    Debian changelog files
+" Maintainer:  Debian Vim Maintainers <pkg-vim-maintainers@lists.alioth.debian.org>
+" Former Maintainer: Wichert Akkerman <wakkerma@debian.org>
+" Last Change: $LastChangedDate: 2006-04-16 21:50:31 -0400 (dom, 16 apr 2006) $
+" URL: http://svn.debian.org/wsvn/pkg-vim/trunk/runtime/syntax/debchangelog.vim?op=file&rev=0&sc=0
+
+" Standard syntax initialization
+if version < 600
+  syntax clear
+elseif exists("b:current_syntax")
+  finish
+endif
+
+" Case doesn't matter for us
+syn case ignore
+
+" Define some common expressions we can use later on
+syn match debchangelogName	contained "^[[:alpha:]][[:alnum:].+-]\+ "
+syn match debchangelogUrgency	contained "; urgency=\(low\|medium\|high\|critical\|emergency\)\( \S.*\)\="
+syn match debchangelogTarget	contained "\( stable\| frozen\| unstable\| testing-proposed-updates\| experimental\| sarge-backports\| sarge-volatile\| stable-security\| testing-security\)\+"
+syn match debchangelogVersion	contained "(.\{-})"
+syn match debchangelogCloses	contained "closes:\s*\(bug\)\=#\=\s\=\d\+\(,\s*\(bug\)\=#\=\s\=\d\+\)*"
+syn match debchangelogEmail	contained "[_=[:alnum:].+-]\+@[[:alnum:]./\-]\+"
+syn match debchangelogEmail	contained "<.\{-}>"
+
+" Define the entries that make up the changelog
+syn region debchangelogHeader start="^[^ ]" end="$" contains=debchangelogName,debchangelogUrgency,debchangelogTarget,debchangelogVersion oneline
+syn region debchangelogFooter start="^ [^ ]" end="$" contains=debchangelogEmail oneline
+syn region debchangelogEntry start="^  " end="$" contains=debchangelogCloses oneline
+
+" Associate our matches and regions with pretty colours
+if version >= 508 || !exists("did_debchangelog_syn_inits")
+  if version < 508
+    let did_debchangelog_syn_inits = 1
+    command -nargs=+ HiLink hi link <args>
+  else
+    command -nargs=+ HiLink hi def link <args>
+  endif
+
+  HiLink debchangelogHeader		Error
+  HiLink debchangelogFooter		Identifier
+  HiLink debchangelogEntry		Normal
+  HiLink debchangelogCloses		Statement
+  HiLink debchangelogUrgency		Identifier
+  HiLink debchangelogName		Comment
+  HiLink debchangelogVersion		Identifier
+  HiLink debchangelogTarget		Identifier
+  HiLink debchangelogEmail		Special
+
+  delcommand HiLink
+endif
+
+let b:current_syntax = "debchangelog"
+
+" vim: ts=8 sw=2
--- /dev/null
+++ b/lib/vimfiles/syntax/debcontrol.vim
@@ -1,0 +1,77 @@
+" Vim syntax file
+" Language:	Debian control files
+" Maintainer:  Debian Vim Maintainers <pkg-vim-maintainers@lists.alioth.debian.org>
+" Former Maintainers: Gerfried Fuchs <alfie@ist.org>
+"                     Wichert Akkerman <wakkerma@debian.org>
+" Last Change: $LastChangedDate: 2006-04-16 21:50:31 -0400 (Sun, 16 Apr 2006) $
+" URL: http://svn.debian.org/wsvn/pkg-vim/trunk/runtime/syntax/debcontrol.vim?op=file&rev=0&sc=0
+
+" Comments are very welcome - but please make sure that you are commenting on
+" the latest version of this file.
+" SPAM is _NOT_ welcome - be ready to be reported!
+
+" Standard syntax initialization
+if version < 600
+  syntax clear
+elseif exists("b:current_syntax")
+  finish
+endif
+
+" Everything that is not explicitly matched by the rules below
+syn match debcontrolElse "^.*$"
+
+" Common seperators
+syn match debControlComma ", *"
+syn match debControlSpace " "
+
+" Define some common expressions we can use later on
+syn match debcontrolArchitecture contained "\(all\|any\|alpha\|amd64\|arm\(eb\)\=\|hppa\|i386\|ia64\|m32r\|m68k\|mipsel\|mips\|powerpc\|ppc64\|s390\|sheb\|sh\|sparc64\|sparc\|hurd-i386\|kfreebsd-\(i386\|gnu\)\|knetbsd-i386\|netbsd-\(alpha\|i386\)\)"
+syn match debcontrolName contained "[a-z][a-z0-9+-]*"
+syn match debcontrolPriority contained "\(extra\|important\|optional\|required\|standard\)"
+syn match debcontrolSection contained "\(\(contrib\|non-free\|non-US/main\|non-US/contrib\|non-US/non-free\)/\)\=\(admin\|base\|comm\|devel\|doc\|editors\|electronics\|embedded\|games\|gnome\|graphics\|hamradio\|interpreters\|kde\|libs\|libdevel\|mail\|math\|misc\|net\|news\|oldlibs\|otherosfs\|perl\|python\|science\|shells\|sound\|text\|tex\|utils\|web\|x11\|debian-installer\)"
+syn match debcontrolVariable contained "\${.\{-}}"
+
+" An email address
+syn match	debcontrolEmail	"[_=[:alnum:]\.+-]\+@[[:alnum:]\./\-]\+"
+syn match	debcontrolEmail	"<.\{-}>"
+
+" List of all legal keys
+syn match debcontrolKey contained "^\(Source\|Package\|Section\|Priority\|Maintainer\|Uploaders\|Build-Depends\|Build-Conflicts\|Build-Depends-Indep\|Build-Conflicts-Indep\|Standards-Version\|Pre-Depends\|Depends\|Recommends\|Suggests\|Provides\|Replaces\|Conflicts\|Essential\|Architecture\|Description\|Bugs\|Origin\|Enhances\): *"
+
+" Fields for which we do strict syntax checking
+syn region debcontrolStrictField start="^Architecture" end="$" contains=debcontrolKey,debcontrolArchitecture,debcontrolSpace oneline
+syn region debcontrolStrictField start="^\(Package\|Source\)" end="$" contains=debcontrolKey,debcontrolName oneline
+syn region debcontrolStrictField start="^Priority" end="$" contains=debcontrolKey,debcontrolPriority oneline
+syn region debcontrolStrictField start="^Section" end="$" contains=debcontrolKey,debcontrolSection oneline
+
+" Catch-all for the other legal fields
+syn region debcontrolField start="^\(Maintainer\|Build-Depends\|Build-Conflicts\|Build-Depends-Indep\|Build-Conflicts-Indep\|Standards-Version\|Pre-Depends\|Depends\|Recommends\|Suggests\|Provides\|Replaces\|Conflicts\|Essential\|Bugs\|Origin\|Enhances\):" end="$" contains=debcontrolKey,debcontrolVariable,debcontrolEmail oneline
+syn region debcontrolMultiField start="^\(Uploaders\|Description\):" skip="^ " end="^$"me=s-1 end="^[^ ]"me=s-1 contains=debcontrolKey,debcontrolEmail,debcontrolVariable
+
+" Associate our matches and regions with pretty colours
+if version >= 508 || !exists("did_debcontrol_syn_inits")
+  if version < 508
+    let did_debcontrol_syn_inits = 1
+    command -nargs=+ HiLink hi link <args>
+  else
+    command -nargs=+ HiLink hi def link <args>
+  endif
+
+  HiLink debcontrolKey		Keyword
+  HiLink debcontrolField	Normal
+  HiLink debcontrolStrictField	Error
+  HiLink debcontrolMultiField	Normal
+  HiLink debcontrolArchitecture	Normal
+  HiLink debcontrolName		Normal
+  HiLink debcontrolPriority	Normal
+  HiLink debcontrolSection	Normal
+  HiLink debcontrolVariable	Identifier
+  HiLink debcontrolEmail	Identifier
+  HiLink debcontrolElse		Special
+
+  delcommand HiLink
+endif
+
+let b:current_syntax = "debcontrol"
+
+" vim: ts=8 sw=2
--- /dev/null
+++ b/lib/vimfiles/syntax/debsources.vim
@@ -1,0 +1,40 @@
+" Vim syntax file
+" Language:	Debian sources.list
+" Maintainer:	Matthijs Mohlmann <matthijs@cacholong.nl>
+" Last Change:	$Date: 2006/03/28 21:08:56 $
+" URL: http://www.cacholong.nl/~matthijs/vim/syntax/debsources.vim
+" $Revision: 1.1 $
+
+" this is a very simple syntax file - I will be improving it
+" add entire DEFINE syntax
+
+" Standard syntax initialization
+if version < 600
+  syntax clear
+elseif exists("b:current_syntax")
+  finish
+endif
+
+" case sensitive
+syn case match
+
+" A bunch of useful keywords
+syn match debsourcesKeyword        /\(deb-src\|deb\|main\|contrib\|non-free\)/
+
+" Match comments
+syn match debsourcesComment        /#.*/
+
+" Match uri's
+syn match debsourcesUri            +\(http://\|ftp://\|file:///\)[^' 	<>"]\++
+syn match debsourcesDistrKeyword   +\([[:alnum:]_./]*\)\(woody\|sarge\|etch\|old-stable\|stable\|testing\|unstable\|sid\|experimental\|warty\|hoary\|breezy\)\([[:alnum:]_./]*\)+
+
+" Associate our matches and regions with pretty colours
+hi def link debsourcesLine            Error
+hi def link debsourcesKeyword         Statement
+hi def link debsourcesDistrKeyword    Type
+hi def link debsourcesComment         Comment
+hi def link debsourcesUri             Constant
+
+let b:current_syntax = "debsources"
+
+" vim: ts=8
--- /dev/null
+++ b/lib/vimfiles/syntax/def.vim
@@ -1,0 +1,57 @@
+" Vim syntax file
+" Language:	Microsoft Module-Definition (.def) File
+" Maintainer:	Rob Brady <robb@datatone.com>
+" Last Change:	$Date: 2004/06/13 18:26:37 $
+" URL: http://www.datatone.com/~robb/vim/syntax/def.vim
+" $Revision: 1.1 $
+
+" For version 5.x: Clear all syntax items
+" For version 6.x: Quit when a syntax file was already loaded
+if version < 600
+  syntax clear
+elseif exists("b:current_syntax")
+  finish
+endif
+
+syn case ignore
+
+syn match defComment	";.*"
+
+syn keyword defKeyword	LIBRARY STUB EXETYPE DESCRIPTION CODE WINDOWS DOS
+syn keyword defKeyword	RESIDENTNAME PRIVATE EXPORTS IMPORTS SEGMENTS
+syn keyword defKeyword	HEAPSIZE DATA
+syn keyword defStorage	LOADONCALL MOVEABLE DISCARDABLE SINGLE
+syn keyword defStorage	FIXED PRELOAD
+
+syn match   defOrdinal	"@\d\+"
+
+syn region  defString	start=+'+ end=+'+
+
+syn match   defNumber	"\d+"
+syn match   defNumber	"0x\x\+"
+
+
+" Define the default highlighting.
+" For version 5.7 and earlier: only when not done already
+" For version 5.8 and later: only when an item doesn't have highlighting yet
+if version >= 508 || !exists("did_def_syntax_inits")
+  if version < 508
+    let did_def_syntax_inits = 1
+    command -nargs=+ HiLink hi link <args>
+  else
+    command -nargs=+ HiLink hi def link <args>
+  endif
+
+  HiLink defComment	Comment
+  HiLink defKeyword	Keyword
+  HiLink defStorage	StorageClass
+  HiLink defString	String
+  HiLink defNumber	Number
+  HiLink defOrdinal	Operator
+
+  delcommand HiLink
+endif
+
+let b:current_syntax = "def"
+
+" vim: ts=8
--- /dev/null
+++ b/lib/vimfiles/syntax/desc.vim
@@ -1,0 +1,102 @@
+" Vim syntax file
+" Language:	T2 / ROCK Linux .desc
+" Maintainer:	René Rebe <rene@exactcode.de>, Piotr Esden-Tempski <esden@rocklinux.org>
+" Last Change:	2006 Aug 14
+
+" For version 5.x: Clear all syntax items
+" For version 6.x: Quit when a syntax file was already loaded
+if version < 600
+  syntax clear
+elseif exists("b:current_syntax")
+  finish
+endif
+
+" syntax definitions
+
+setl iskeyword+=-
+syn keyword descFlag DIETLIBC KAFFE JAIL NOPARALLEL FPIC-QUIRK LIBTOOL-WUIRK NO-LIBTOOL-FIX AUTOMAKE-QUIRK NO-AS-NEEDED NO-SSP KERNEL INIT LIBC CC CXX F77 KCC contained
+syn keyword descLicense Unknown GPL LGPL FDL MIT BSD OpenSource Free-to-use Commercial contained
+
+" tags
+syn match descTag /^\[\(COPY\)\]/
+syn match descTag /^\[\(I\|TITLE\)\]/
+syn match descTag /^\[\(T\|TEXT\)\]/ contained
+syn match descTag /^\[\(U\|URL\)\]/
+syn match descTag /^\[\(A\|AUTHOR\)\]/
+syn match descTag /^\[\(M\|MAINTAINER\)\]/
+syn match descTag /^\[\(C\|CATEGORY\)\]/ contained
+syn match descTag /^\[\(F\|FLAG\)\]/ contained
+syn match descTag /^\[\(E\|DEP\|DEPENDENCY\)\]/
+syn match descTag /^\[\(R\|ARCH\|ARCHITECTURE\)\]/
+syn match descTag /^\[\(L\|LICENSE\)\]/ contained
+syn match descTag /^\[\(S\|STATUS\)\]/
+syn match descTag /^\[\(O\|CONF\)\]/
+syn match descTag /^\[\(V\|VER\|VERSION\)\]/
+syn match descTag /^\[\(P\|PRI\|PRIORITY\)\]/ nextgroup=descInstall skipwhite
+syn match descTag /^\[\(D\|DOWN\|DOWNLOAD\)\]/ nextgroup=descSum skipwhite
+
+" misc
+syn match descUrl /\w\+:\/\/\S\+/
+syn match descCategory /\w\+\/\w\+/ contained
+syn match descEmail /<[\.A-Za-z0-9]\+@[\.A-Za-z0-9]\+>/
+
+" priority tag
+syn match descInstallX /X/ contained
+syn match descInstallO /O/ contained
+syn match descInstall /[OX]/ contained contains=descInstallX,descInstallO nextgroup=descStage skipwhite
+syn match descDash /-/ contained
+syn match descDigit /\d/ contained
+syn match descStage /[\-0][\-1][\-2][\-3][\-4][\-5][\-6][\-7][\-8][\-9]/ contained contains=descDash,descDigit nextgroup=descCompilePriority skipwhite
+syn match descCompilePriority /\d\{3}\.\d\{3}/ contained
+
+" download tag
+syn match descSum /\d\+/ contained nextgroup=descTarball skipwhite
+syn match descTarball /\S\+/ contained nextgroup=descUrl skipwhite
+
+
+" tag regions
+syn region descText start=/^\[\(T\|TEXT\)\]/ end=/$/ contains=descTag,descUrl,descEmail
+
+syn region descTagRegion start=/^\[\(C\|CATEGORY\)\]/ end=/$/ contains=descTag,descCategory
+
+syn region descTagRegion start=/^\[\(F\|FLAG\)\]/ end=/$/ contains=descTag,descFlag
+
+syn region descTagRegion start=/^\[\(L\|LICENSE\)\]/ end=/$/ contains=descTag,descLicense
+
+" For version 5.7 and earlier: only when not done already
+" Define the default highlighting.
+" For version 5.8 and later: only when an item doesn't have highlighting yet
+if version >= 508 || !exists("did_desc_syntax_inits")
+  if version < 508
+    let did_desc_syntax_inits = 1
+    command -nargs=+ HiLink hi link <args>
+  else
+    command -nargs=+ HiLink hi def link <args>
+  endif
+
+  HiLink descFlag		Identifier
+  HiLink descLicense		Identifier
+  HiLink descCategory		Identifier
+
+  HiLink descTag		Type
+  HiLink descUrl		Underlined
+  HiLink descEmail		Underlined
+
+  " priority tag colors
+  HiLink descInstallX		Boolean
+  HiLink descInstallO		Type
+  HiLink descDash		Operator
+  HiLink descDigit		Number
+  HiLink descCompilePriority	Number
+
+  " download tag colors
+  HiLink descSum		Number
+  HiLink descTarball		Underlined
+
+  " tag region colors
+  HiLink descText		Comment
+
+  delcommand HiLink
+endif
+
+let b:current_syntax = "desc"
--- /dev/null
+++ b/lib/vimfiles/syntax/desktop.vim
@@ -1,0 +1,119 @@
+" Vim syntax file
+" Language:	.desktop, .directory files
+"		according to freedesktop.org specification 0.9.4
+" http://pdx.freedesktop.org/Standards/desktop-entry-spec/desktop-entry-spec-0.9.4.html
+" Maintainer:	Mikolaj Machowski ( mikmach AT wp DOT pl )
+" Last Change:	2004 May 16
+" Version Info: desktop.vim 0.9.4-1.2
+
+" For version 5.x: Clear all syntax items
+" For version 6.x: Quit when a syntax file was already loaded
+if version < 600
+	syntax clear
+elseif exists("b:current_syntax")
+    finish
+endif
+
+" This syntax file can be used to all *nix configuration files similar to dos
+" ini format (eg. .xawtv, .radio, kde rc files) - this is default mode. But
+" you can also enforce strict following of freedesktop.org standard for
+" .desktop and .directory files . Set (eg. in vimrc)
+" let enforce_freedesktop_standard = 1
+" and nonstandard extensions not following X- notation will not be highlighted.
+if exists("enforce_freedesktop_standard")
+	let b:enforce_freedesktop_standard = 1
+else
+	let b:enforce_freedesktop_standard = 0
+endif
+
+" case on
+syn case match
+
+" General
+if b:enforce_freedesktop_standard == 0
+	syn match  dtNotStLabel	"^.\{-}=\@=" nextgroup=dtDelim
+endif
+
+syn match  dtGroup	/^\s*\[.*\]/
+syn match  dtComment	/^\s*#.*$/
+syn match  dtDelim	/=/ contained
+
+" Locale
+syn match   dtLocale /^\s*\<\(Name\|GenericName\|Comment\|SwallowTitle\|Icon\|UnmountIcon\)\>.*/ contains=dtLocaleKey,dtLocaleName,dtDelim transparent
+syn keyword dtLocaleKey Name GenericName Comment SwallowTitle Icon UnmountIcon nextgroup=dtLocaleName containedin=dtLocale
+syn match   dtLocaleName /\(\[.\{-}\]\s*=\@=\|\)/ nextgroup=dtDelim containedin=dtLocale contained
+
+" Numeric
+syn match   dtNumeric /^\s*\<Version\>/ contains=dtNumericKey,dtDelim
+syn keyword dtNumericKey Version nextgroup=dtDelim containedin=dtNumeric contained
+
+" Boolean
+syn match   dtBoolean /^\s*\<\(StartupNotify\|ReadOnly\|Terminal\|Hidden\|NoDisplay\)\>.*/ contains=dtBooleanKey,dtDelim,dtBooleanValue transparent
+syn keyword dtBooleanKey StartupNotify ReadOnly Terminal Hidden NoDisplay nextgroup=dtDelim containedin=dtBoolean contained
+syn keyword dtBooleanValue true false containedin=dtBoolean contained
+
+" String
+syn match   dtString /^\s*\<\(Encoding\|Icon\|Path\|Actions\|FSType\|MountPoint\|UnmountIcon\|URL\|Categories\|OnlyShowIn\|NotShowIn\|StartupWMClass\|FilePattern\|MimeType\)\>.*/ contains=dtStringKey,dtDelim transparent
+syn keyword dtStringKey Type Encoding TryExec Exec Path Actions FSType MountPoint URL Categories OnlyShowIn NotShowIn StartupWMClass FilePattern MimeType nextgroup=dtDelim containedin=dtString contained
+
+" Exec
+syn match   dtExec /^\s*\<\(Exec\|TryExec\|SwallowExec\)\>.*/ contains=dtExecKey,dtDelim,dtExecParam transparent
+syn keyword dtExecKey Exec TryExec SwallowExec nextgroup=dtDelim containedin=dtExec contained
+syn match   dtExecParam  /%[fFuUnNdDickv]/ containedin=dtExec contained
+
+" Type
+syn match   dtType /^\s*\<Type\>.*/ contains=dtTypeKey,dtDelim,dtTypeValue transparent
+syn keyword dtTypeKey Type nextgroup=dtDelim containedin=dtType contained
+syn keyword dtTypeValue Application Link FSDevice Directory containedin=dtType contained
+
+" X-Addition
+syn match   dtXAdd    /^\s*X-.*/ contains=dtXAddKey,dtDelim transparent
+syn match   dtXAddKey /^\s*X-.\{-}\s*=\@=/ nextgroup=dtDelim containedin=dtXAdd contains=dtXLocale contained
+
+" Locale for X-Addition
+syn match   dtXLocale /\[.\{-}\]\s*=\@=/ containedin=dtXAddKey contained
+
+" Locale for all
+syn match   dtALocale /\[.\{-}\]\s*=\@=/ containedin=ALL
+
+
+" Define the default highlighting.
+" For version 5.7 and earlier: only when not done already
+" For version 5.8 and later: only when an item doesn't have highlighting yet
+if version >= 508 || !exists("did_desktop_syntax_inits")
+	if version < 508
+		let did_dosini_syntax_inits = 1
+		command -nargs=+ HiLink hi link <args>
+	else
+		command -nargs=+ HiLink hi def link <args>
+	endif
+
+	HiLink dtGroup		 Special
+	HiLink dtComment	 Comment
+	HiLink dtDelim		 String
+
+	HiLink dtLocaleKey	 Type
+	HiLink dtLocaleName	 Identifier
+	HiLink dtXLocale	 Identifier
+	HiLink dtALocale	 Identifier
+
+	HiLink dtNumericKey	 Type
+
+	HiLink dtBooleanKey	 Type
+	HiLink dtBooleanValue	 Constant
+
+	HiLink dtStringKey	 Type
+
+	HiLink dtExecKey	 Type
+	HiLink dtExecParam	 Special
+	HiLink dtTypeKey	 Type
+	HiLink dtTypeValue	 Constant
+	HiLink dtNotStLabel	 Type
+	HiLink dtXAddKey	 Type
+
+	delcommand HiLink
+endif
+
+let b:current_syntax = "desktop"
+
+" vim:ts=8
--- /dev/null
+++ b/lib/vimfiles/syntax/dictconf.vim
@@ -1,0 +1,80 @@
+" Vim syntax file
+" Language:         dict(1) configuration file
+" Maintainer:       Nikolai Weibull <now@bitwi.se>
+" Latest Revision:  2006-04-19
+
+if exists("b:current_syntax")
+  finish
+endif
+
+let s:cpo_save = &cpo
+set cpo&vim
+
+syn keyword dictconfTodo        contained TODO FIXME XXX NOTE
+
+syn region  dictconfComment     display oneline start='#' end='$'
+                                \ contains=dictconfTodo,@Spell
+
+syn match   dictconfBegin       display '^'
+                                \ nextgroup=dictconfKeyword,dictconfComment
+                                \ skipwhite
+
+syn keyword dictconfKeyword     contained server
+                                \ nextgroup=dictconfServer skipwhite
+
+syn keyword dictconfKeyword     contained pager
+                                \ nextgroup=dictconfPager
+
+syn match   dictconfServer      contained display
+                                \ '[[:alnum:]_/.*-][[:alnum:]_/.*-]*'
+                                \ nextgroup=dictconfServerOptG skipwhite
+
+syn region  dictconfServer      contained display oneline
+                                \ start=+"+ skip=+""+ end=+"+
+                                \ nextgroup=dictconfServerOptG skipwhite
+
+syn region  dictconfServerOptG  contained transparent
+                                \ matchgroup=dictconfServerOptsD start='{'
+                                \ matchgroup=dictconfServerOptsD end='}'
+                                \ contains=dictconfServerOpts,dictconfComment
+
+syn keyword dictconfServerOpts  contained port
+                                \ nextgroup=dictconfNumber skipwhite
+
+syn keyword dictconfServerOpts  contained user
+                                \ nextgroup=dictconfUsername skipwhite
+
+syn match   dictconfUsername    contained display
+                                \ '[[:alnum:]_/.*-][[:alnum:]_/.*-]*'
+                                \ nextgroup=dictconfSecret skipwhite
+syn region  dictconfUsername    contained display oneline
+                                \ start=+"+ skip=+""+ end=+"+
+                                \ nextgroup=dictconfSecret skipwhite
+
+syn match   dictconfSecret      contained display
+                                \ '[[:alnum:]_/.*-][[:alnum:]_/.*-]*'
+syn region  dictconfSecret      contained display oneline
+                                \ start=+"+ skip=+""+ end=+"+
+
+syn match   dictconfNumber      contained '\<\d\+\>'
+
+syn match   dictconfPager       contained display
+                                \ '[[:alnum:]_/.*-][[:alnum:]_/.*-]*'
+syn region  dictconfPager       contained display oneline
+                                \ start=+"+ skip=+""+ end=+"+
+
+hi def link dictconfTodo        Todo
+hi def link dictconfComment     Comment
+hi def link dictconfKeyword     Keyword
+hi def link dictconfServer      String
+hi def link dictconfServerOptsD Delimiter
+hi def link dictconfServerOpts  Identifier
+hi def link dictconfUsername    String
+hi def link dictconfSecret      Special
+hi def link dictconfNumber      Number
+hi def link dictconfPager       String
+
+let b:current_syntax = "dictconf"
+
+let &cpo = s:cpo_save
+unlet s:cpo_save
--- /dev/null
+++ b/lib/vimfiles/syntax/dictdconf.vim
@@ -1,0 +1,146 @@
+" Vim syntax file
+" Language:         dictd(8) configuration file
+" Maintainer:       Nikolai Weibull <now@bitwi.se>
+" Latest Revision:  2006-04-19
+
+if exists("b:current_syntax")
+  finish
+endif
+
+let s:cpo_save = &cpo
+set cpo&vim
+
+syn keyword dictdconfTodo        contained TODO FIXME XXX NOTE
+
+syn region  dictdconfComment    display oneline start='#' end='$'
+                                \ contains=dictdconfTodo,dictdconfSpecialC,
+                                \ @Spell
+
+syn keyword dictdconfSpecialC   LASTLINE
+
+syn match   dictdconfBegin      display '^'
+                                \ nextgroup=dictdconfKeyword,dictdconfComment
+                                \ skipwhite
+
+syn keyword dictdconfKeyword    contained access
+                                \ nextgroup=dictdconfAccessG skipwhite
+
+syn region  dictdconfAccessG    contained transparent
+                                \ matchgroup=dictdconfDelimiter start='{'
+                                \ matchgroup=dictdconfDelimiter end='}'
+                                \ contains=dictdconfAccess,dictdconfComment
+
+syn keyword dictdconfAccess     contained allow deny authonly user
+                                \ nextgroup=dictdconfString skipwhite
+
+syn keyword dictdconfKeyword    contained database
+                                \ nextgroup=dictdconfDatabase skipwhite
+
+syn match   dictdconfDatabase   contained display
+                                \ '[[:alnum:]_/.*-][[:alnum:]_/.*-]*'
+                                \ nextgroup=dictdconfSpecG skipwhite
+syn region  dictdconfDatabase   contained display oneline
+                                \ start=+"+ skip=+""\|\\\\\|\\"+ end=+"+
+                                \ nextgroup=dictdconfSpecG skipwhite
+
+syn region  dictdconfSpecG      contained transparent
+                                \ matchgroup=dictdconfDelimiter start='{'
+                                \ matchgroup=dictdconfDelimiter end='}'
+                                \ contains=dictdconfSpec,dictdconfAccess,
+                                \ dictdconfComment
+
+syn keyword dictdconfSpec       contained data index index_suffix index_word
+                                \ filter prefilter postfilter name info
+                                \ disable_strat
+                                \ nextgroup=dictdconfString skipwhite
+
+syn keyword dictdconfSpec       contained invisible
+
+syn keyword dictdconfKeyword    contained database_virtual
+                                \ nextgroup=dictdconfVDatabase skipwhite
+
+syn match   dictdconfVDatabase  contained display
+                                \ '[[:alnum:]_/.*-][[:alnum:]_/.*-]*'
+                                \ nextgroup=dictdconfVSpecG skipwhite
+syn region  dictdconfVDatabase   contained display oneline
+                                \ start=+"+ skip=+""\|\\\\\|\\"+ end=+"+
+                                \ nextgroup=dictdconfVSpecG skipwhite
+
+syn region  dictdconfVSpecG     contained transparent
+                                \ matchgroup=dictdconfDelimiter start='{'
+                                \ matchgroup=dictdconfDelimiter end='}'
+                                \ contains=dictdconfVSpec,dictdconfAccess,
+                                \ dictdconfComment
+
+syn keyword dictdconfVSpec      contained name info database_list disable_strat
+                                \ nextgroup=dictdconfString skipwhite
+
+syn keyword dictdconfVSpec      contained invisible
+
+syn keyword dictdconfKeyword    contained database_plugin
+                                \ nextgroup=dictdconfPDatabase skipwhite
+
+syn match   dictdconfPDatabase  contained display
+                                \ '[[:alnum:]_/.*-][[:alnum:]_/.*-]*'
+                                \ nextgroup=dictdconfPSpecG skipwhite
+syn region  dictdconfPDatabase   contained display oneline
+                                \ start=+"+ skip=+""\|\\\\\|\\"+ end=+"+
+                                \ nextgroup=dictdconfPSpecG skipwhite
+
+syn region  dictdconfPSpecG     contained transparent
+                                \ matchgroup=dictdconfDelimiter start='{'
+                                \ matchgroup=dictdconfDelimiter end='}'
+                                \ contains=dictdconfPSpec,dictdconfAccess,
+                                \ dictdconfComment
+
+syn keyword dictdconfPSpec      contained name info plugin data disable_strat
+                                \ nextgroup=dictdconfString skipwhite
+
+syn keyword dictdconfPSpec      contained invisible
+
+syn keyword dictdconfKeyword    contained database_exit
+
+syn keyword dictdconfKeyword    contained site
+                                \ nextgroup=dictdconfString skipwhite
+
+syn keyword dictdconfKeyword    contained user
+                                \ nextgroup=dictdconfUsername skipwhite
+
+syn match   dictdconfUsername   contained display
+                                \ '[[:alnum:]_/.*-][[:alnum:]_/.*-]*'
+                                \ nextgroup=dictdconfSecret skipwhite
+syn region  dictdconfUsername   contained display oneline
+                                \ start=+"+ skip=+""+ end=+"+
+                                \ nextgroup=dictdconfSecret skipwhite
+
+syn match   dictdconfSecret     contained display
+                                \ '[[:alnum:]_/.*-][[:alnum:]_/.*-]*'
+syn region  dictdconfSecret     contained display oneline
+                                \ start=+"+ skip=+""+ end=+"+
+
+syn match   dictdconfString     contained display
+                                \ '[[:alnum:]_/.*-][[:alnum:]_/.*-]*'
+syn region  dictdconfString     contained display oneline
+                                \ start=+"+ skip=+""\|\\\\\|\\"+ end=+"+
+
+hi def link dictdconfTodo       Todo
+hi def link dictdconfComment    Comment
+hi def link dictdconfSpecialC   Special
+hi def link dictdconfKeyword    Keyword
+hi def link dictdconfIdentifier Identifier
+hi def link dictdconfAccess     dictdconfIdentifier
+hi def link dictdconfDatabase   dictdconfString
+hi def link dictdconfSpec       dictdconfIdentifier
+hi def link dictdconfVDatabase  dictdconfDatabase
+hi def link dictdconfVSpec      dictdconfSpec
+hi def link dictdconfPDatabase  dictdconfDatabase
+hi def link dictdconfPSpec      dictdconfSpec
+hi def link dictdconfUsername   dictdconfString
+hi def link dictdconfSecret     Special
+hi def link dictdconfString     String
+hi def link dictdconfDelimiter  Delimiter
+
+let b:current_syntax = "dictdconf"
+
+let &cpo = s:cpo_save
+unlet s:cpo_save
--- /dev/null
+++ b/lib/vimfiles/syntax/diff.vim
@@ -1,0 +1,63 @@
+" Vim syntax file
+" Language:	Diff (context or unified)
+" Maintainer:	Bram Moolenaar <Bram@vim.org>
+" Last Change:	2005 Jun 20
+
+" Quit when a (custom) syntax file was already loaded
+if exists("b:current_syntax")
+  finish
+endif
+
+syn match diffOnly	"^Only in .*"
+syn match diffIdentical	"^Files .* and .* are identical$"
+syn match diffDiffer	"^Files .* and .* differ$"
+syn match diffBDiffer	"^Binary files .* and .* differ$"
+syn match diffIsA	"^File .* is a .* while file .* is a .*"
+syn match diffNoEOL	"^No newline at end of file .*"
+syn match diffCommon	"^Common subdirectories: .*"
+
+syn match diffRemoved	"^-.*"
+syn match diffRemoved	"^<.*"
+syn match diffAdded	"^+.*"
+syn match diffAdded	"^>.*"
+syn match diffChanged	"^! .*"
+
+syn match diffSubname	" @@..*"ms=s+3 contained
+syn match diffLine	"^@.*" contains=diffSubname
+syn match diffLine	"^\<\d\+\>.*"
+syn match diffLine	"^\*\*\*\*.*"
+
+"Some versions of diff have lines like "#c#" and "#d#" (where # is a number)
+syn match diffLine	"^\d\+\(,\d\+\)\=[cda]\d\+\>.*"
+
+syn match diffFile	"^diff.*"
+syn match diffFile	"^+++ .*"
+syn match diffFile	"^Index: .*$"
+syn match diffFile	"^==== .*$"
+syn match diffOldFile	"^\*\*\* .*"
+syn match diffNewFile	"^--- .*"
+
+syn match diffComment	"^#.*"
+
+" Define the default highlighting.
+" Only used when an item doesn't have highlighting yet
+hi def link diffOldFile		diffFile
+hi def link diffNewFile		diffFile
+hi def link diffFile		Type
+hi def link diffOnly		Constant
+hi def link diffIdentical	Constant
+hi def link diffDiffer		Constant
+hi def link diffBDiffer		Constant
+hi def link diffIsA		Constant
+hi def link diffNoEOL		Constant
+hi def link diffCommon		Constant
+hi def link diffRemoved		Special
+hi def link diffChanged		PreProc
+hi def link diffAdded		Identifier
+hi def link diffLine		Statement
+hi def link diffSubname		PreProc
+hi def link diffComment		Comment
+
+let b:current_syntax = "diff"
+
+" vim: ts=8 sw=2
--- /dev/null
+++ b/lib/vimfiles/syntax/dircolors.vim
@@ -1,0 +1,752 @@
+" Vim syntax file
+" Language:         dircolors(1) input file
+" Maintainer:       Nikolai Weibull <now@bitwi.se>
+" Latest Revision:  2006-06-23
+
+if exists("b:current_syntax")
+  finish
+endif
+
+let s:cpo_save = &cpo
+set cpo&vim
+
+syn keyword dircolorsTodo       contained FIXME TODO XXX NOTE
+
+syn region  dircolorsComment    start='#' end='$' contains=dircolorsTodo,@Spell
+
+syn keyword dircolorsKeyword    TERM LEFT LEFTCODE RIGHT RIGHTCODE END ENDCODE
+
+syn keyword dircolorsKeyword    NORMAL NORM FILE DIR LNK LINK SYMLINK ORPHAN
+                                \ MISSING FIFO PIPE SOCK BLK BLOCK CHR CHAR
+                                \ DOOR EXEC
+                                \ nextgroup=@dircolorsColors skipwhite
+
+if exists("dircolors_is_slackware")
+  syn keyword dircolorsKeyword  COLOR OPTIONS EIGHTBIT
+endif
+
+syn match   dircolorsExtension  '^\s*\zs[.*]\S\+'
+                                \ nextgroup=dircolorsColorPair skipwhite
+
+syn match   dircolorsColorPair  contained '.*$'
+                                \ transparent contains=@dircolorsColors
+
+if &t_Co == 8 || &t_Co == 16
+  syn cluster dircolorsColors   contains=dircolorsBold,dircolorsUnderline,
+                                \ dircolorsBlink,dircolorsReverse,
+                                \ dircolorsInvisible,dircolorsBlack,
+                                \ dircolorsRed,dircolorsGreen,dircolorsYellow,
+                                \ dircolorsBlue,dircolorsMagenta,dircolorsCyan,
+                                \ dircolorsWhite,dircolorsBGBlack,
+                                \ dircolorsBGRed,dircolorsBGGreen,
+                                \ dircolorsBGYellow,dircolorsBGBlue,
+                                \ dircolorsBGMagenta,dircolorsBGCyan,
+                                \ dircolorsBGWhite
+
+  syn match dircolorsBold       contained '\<0\=1\>'
+  syn match dircolorsUnderline  contained '\<0\=4\>'
+  syn match dircolorsBlink      contained '\<0\=5\>'
+  syn match dircolorsReverse    contained '\<0\=7\>'
+  syn match dircolorsInvisible  contained '\<0\=8\>'
+  syn match dircolorsBlack      contained '\<30\>'
+  syn match dircolorsRed        contained '\<31\>'
+  syn match dircolorsGreen      contained '\<32\>'
+  syn match dircolorsYellow     contained '\<33\>'
+  syn match dircolorsBlue       contained '\<34\>'
+  syn match dircolorsMagenta    contained '\<35\>'
+  syn match dircolorsCyan       contained '\<36\>'
+  syn match dircolorsWhite      contained '\<37\>'
+  syn match dircolorsBGBlack    contained '\<40\>'
+  syn match dircolorsBGRed      contained '\<41\>'
+  syn match dircolorsBGGreen    contained '\<42\>'
+  syn match dircolorsBGYellow   contained '\<43\>'
+  syn match dircolorsBGBlue     contained '\<44\>'
+  syn match dircolorsBGMagenta  contained '\<45\>'
+  syn match dircolorsBGCyan     contained '\<46\>'
+  syn match dircolorsBGWhite    contained '\<47\>'
+elseif &t_Co == 256 || has("gui_running")
+  syn cluster dircolorsColors   contains=dircolorsColor0,
+                                \ dircolorsColor1,dircolorsColor2,
+                                \ dircolorsColor3,dircolorsColor4,
+                                \ dircolorsColor5,dircolorsColor6,
+                                \ dircolorsColor7,dircolorsColor8,
+                                \ dircolorsColor9,dircolorsColor10,
+                                \ dircolorsColor11,dircolorsColor12,
+                                \ dircolorsColor13,dircolorsColor14,
+                                \ dircolorsColor15,dircolorsColor16,
+                                \ dircolorsColor17,dircolorsColor18,
+                                \ dircolorsColor19,dircolorsColor20,
+                                \ dircolorsColor21,dircolorsColor22,
+                                \ dircolorsColor23,dircolorsColor24,
+                                \ dircolorsColor25,dircolorsColor26,
+                                \ dircolorsColor27,dircolorsColor28,
+                                \ dircolorsColor29,dircolorsColor30,
+                                \ dircolorsColor31,dircolorsColor32,
+                                \ dircolorsColor33,dircolorsColor34,
+                                \ dircolorsColor35,dircolorsColor36,
+                                \ dircolorsColor37,dircolorsColor38,
+                                \ dircolorsColor39,dircolorsColor40,
+                                \ dircolorsColor41,dircolorsColor42,
+                                \ dircolorsColor43,dircolorsColor44,
+                                \ dircolorsColor45,dircolorsColor46,
+                                \ dircolorsColor47,dircolorsColor48,
+                                \ dircolorsColor49,dircolorsColor50,
+                                \ dircolorsColor51,dircolorsColor52,
+                                \ dircolorsColor53,dircolorsColor54,
+                                \ dircolorsColor55,dircolorsColor56,
+                                \ dircolorsColor57,dircolorsColor58,
+                                \ dircolorsColor59,dircolorsColor60,
+                                \ dircolorsColor61,dircolorsColor62,
+                                \ dircolorsColor63,dircolorsColor64,
+                                \ dircolorsColor65,dircolorsColor66,
+                                \ dircolorsColor67,dircolorsColor68,
+                                \ dircolorsColor69,dircolorsColor70,
+                                \ dircolorsColor71,dircolorsColor72,
+                                \ dircolorsColor73,dircolorsColor74,
+                                \ dircolorsColor75,dircolorsColor76,
+                                \ dircolorsColor77,dircolorsColor78,
+                                \ dircolorsColor79,dircolorsColor80,
+                                \ dircolorsColor81,dircolorsColor82,
+                                \ dircolorsColor83,dircolorsColor84,
+                                \ dircolorsColor85,dircolorsColor86,
+                                \ dircolorsColor87,dircolorsColor88,
+                                \ dircolorsColor89,dircolorsColor90,
+                                \ dircolorsColor91,dircolorsColor92,
+                                \ dircolorsColor93,dircolorsColor94,
+                                \ dircolorsColor95,dircolorsColor96,
+                                \ dircolorsColor97,dircolorsColor98,
+                                \ dircolorsColor99,dircolorsColor100,
+                                \ dircolorsColor101,dircolorsColor102,
+                                \ dircolorsColor103,dircolorsColor104,
+                                \ dircolorsColor105,dircolorsColor106,
+                                \ dircolorsColor107,dircolorsColor108,
+                                \ dircolorsColor109,dircolorsColor110,
+                                \ dircolorsColor111,dircolorsColor112,
+                                \ dircolorsColor113,dircolorsColor114,
+                                \ dircolorsColor115,dircolorsColor116,
+                                \ dircolorsColor117,dircolorsColor118,
+                                \ dircolorsColor119,dircolorsColor120,
+                                \ dircolorsColor121,dircolorsColor122,
+                                \ dircolorsColor123,dircolorsColor124,
+                                \ dircolorsColor125,dircolorsColor126,
+                                \ dircolorsColor127,dircolorsColor128,
+                                \ dircolorsColor129,dircolorsColor130,
+                                \ dircolorsColor131,dircolorsColor132,
+                                \ dircolorsColor133,dircolorsColor134,
+                                \ dircolorsColor135,dircolorsColor136,
+                                \ dircolorsColor137,dircolorsColor138,
+                                \ dircolorsColor139,dircolorsColor140,
+                                \ dircolorsColor141,dircolorsColor142,
+                                \ dircolorsColor143,dircolorsColor144,
+                                \ dircolorsColor145,dircolorsColor146,
+                                \ dircolorsColor147,dircolorsColor148,
+                                \ dircolorsColor149,dircolorsColor150,
+                                \ dircolorsColor151,dircolorsColor152,
+                                \ dircolorsColor153,dircolorsColor154,
+                                \ dircolorsColor155,dircolorsColor156,
+                                \ dircolorsColor157,dircolorsColor158,
+                                \ dircolorsColor159,dircolorsColor160,
+                                \ dircolorsColor161,dircolorsColor162,
+                                \ dircolorsColor163,dircolorsColor164,
+                                \ dircolorsColor165,dircolorsColor166,
+                                \ dircolorsColor167,dircolorsColor168,
+                                \ dircolorsColor169,dircolorsColor170,
+                                \ dircolorsColor171,dircolorsColor172,
+                                \ dircolorsColor173,dircolorsColor174,
+                                \ dircolorsColor175,dircolorsColor176,
+                                \ dircolorsColor177,dircolorsColor178,
+                                \ dircolorsColor179,dircolorsColor180,
+                                \ dircolorsColor181,dircolorsColor182,
+                                \ dircolorsColor183,dircolorsColor184,
+                                \ dircolorsColor185,dircolorsColor186,
+                                \ dircolorsColor187,dircolorsColor188,
+                                \ dircolorsColor189,dircolorsColor190,
+                                \ dircolorsColor191,dircolorsColor192,
+                                \ dircolorsColor193,dircolorsColor194,
+                                \ dircolorsColor195,dircolorsColor196,
+                                \ dircolorsColor197,dircolorsColor198,
+                                \ dircolorsColor199,dircolorsColor200,
+                                \ dircolorsColor201,dircolorsColor202,
+                                \ dircolorsColor203,dircolorsColor204,
+                                \ dircolorsColor205,dircolorsColor206,
+                                \ dircolorsColor207,dircolorsColor208,
+                                \ dircolorsColor209,dircolorsColor210,
+                                \ dircolorsColor211,dircolorsColor212,
+                                \ dircolorsColor213,dircolorsColor214,
+                                \ dircolorsColor215,dircolorsColor216,
+                                \ dircolorsColor217,dircolorsColor218,
+                                \ dircolorsColor219,dircolorsColor220,
+                                \ dircolorsColor221,dircolorsColor222,
+                                \ dircolorsColor223,dircolorsColor224,
+                                \ dircolorsColor225,dircolorsColor226,
+                                \ dircolorsColor227,dircolorsColor228,
+                                \ dircolorsColor229,dircolorsColor230,
+                                \ dircolorsColor231,dircolorsColor232,
+                                \ dircolorsColor233,dircolorsColor234,
+                                \ dircolorsColor235,dircolorsColor236,
+                                \ dircolorsColor237,dircolorsColor238,
+                                \ dircolorsColor239,dircolorsColor240,
+                                \ dircolorsColor241,dircolorsColor242,
+                                \ dircolorsColor243,dircolorsColor244,
+                                \ dircolorsColor245,dircolorsColor246,
+                                \ dircolorsColor247,dircolorsColor248,
+                                \ dircolorsColor249,dircolorsColor250,
+                                \ dircolorsColor251,dircolorsColor252,
+                                \ dircolorsColor253,dircolorsColor254,
+                                \ dircolorsColor255
+
+  syn match dircolorsColor0     contained '\<0\=0\>'
+  syn match dircolorsColor1     contained '\<0\=1\>'
+  syn match dircolorsColor2     contained '\<0\=2\>'
+  syn match dircolorsColor3     contained '\<0\=3\>'
+  syn match dircolorsColor4     contained '\<0\=4\>'
+  syn match dircolorsColor5     contained '\<0\=5\>'
+  syn match dircolorsColor6     contained '\<0\=6\>'
+  syn match dircolorsColor7     contained '\<0\=7\>'
+  syn match dircolorsColor8     contained '\<0\=8\>'
+  syn match dircolorsColor9     contained '\<0\=9\>'
+  syn match dircolorsColor10    contained '\<10\>'
+  syn match dircolorsColor11    contained '\<11\>'
+  syn match dircolorsColor12    contained '\<12\>'
+  syn match dircolorsColor13    contained '\<13\>'
+  syn match dircolorsColor14    contained '\<14\>'
+  syn match dircolorsColor15    contained '\<15\>'
+  syn match dircolorsColor16    contained '\<16\>'
+  syn match dircolorsColor17    contained '\<17\>'
+  syn match dircolorsColor18    contained '\<18\>'
+  syn match dircolorsColor19    contained '\<19\>'
+  syn match dircolorsColor20    contained '\<20\>'
+  syn match dircolorsColor21    contained '\<21\>'
+  syn match dircolorsColor22    contained '\<22\>'
+  syn match dircolorsColor23    contained '\<23\>'
+  syn match dircolorsColor24    contained '\<24\>'
+  syn match dircolorsColor25    contained '\<25\>'
+  syn match dircolorsColor26    contained '\<26\>'
+  syn match dircolorsColor27    contained '\<27\>'
+  syn match dircolorsColor28    contained '\<28\>'
+  syn match dircolorsColor29    contained '\<29\>'
+  syn match dircolorsColor30    contained '\<30\>'
+  syn match dircolorsColor31    contained '\<31\>'
+  syn match dircolorsColor32    contained '\<32\>'
+  syn match dircolorsColor33    contained '\<33\>'
+  syn match dircolorsColor34    contained '\<34\>'
+  syn match dircolorsColor35    contained '\<35\>'
+  syn match dircolorsColor36    contained '\<36\>'
+  syn match dircolorsColor37    contained '\<37\>'
+  syn match dircolorsColor38    contained '\<38\>'
+  syn match dircolorsColor39    contained '\<39\>'
+  syn match dircolorsColor40    contained '\<40\>'
+  syn match dircolorsColor41    contained '\<41\>'
+  syn match dircolorsColor42    contained '\<42\>'
+  syn match dircolorsColor43    contained '\<43\>'
+  syn match dircolorsColor44    contained '\<44\>'
+  syn match dircolorsColor45    contained '\<45\>'
+  syn match dircolorsColor46    contained '\<46\>'
+  syn match dircolorsColor47    contained '\<47\>'
+  syn match dircolorsColor48    contained '\<48\>'
+  syn match dircolorsColor49    contained '\<49\>'
+  syn match dircolorsColor50    contained '\<50\>'
+  syn match dircolorsColor51    contained '\<51\>'
+  syn match dircolorsColor52    contained '\<52\>'
+  syn match dircolorsColor53    contained '\<53\>'
+  syn match dircolorsColor54    contained '\<54\>'
+  syn match dircolorsColor55    contained '\<55\>'
+  syn match dircolorsColor56    contained '\<56\>'
+  syn match dircolorsColor57    contained '\<57\>'
+  syn match dircolorsColor58    contained '\<58\>'
+  syn match dircolorsColor59    contained '\<59\>'
+  syn match dircolorsColor60    contained '\<60\>'
+  syn match dircolorsColor61    contained '\<61\>'
+  syn match dircolorsColor62    contained '\<62\>'
+  syn match dircolorsColor63    contained '\<63\>'
+  syn match dircolorsColor64    contained '\<64\>'
+  syn match dircolorsColor65    contained '\<65\>'
+  syn match dircolorsColor66    contained '\<66\>'
+  syn match dircolorsColor67    contained '\<67\>'
+  syn match dircolorsColor68    contained '\<68\>'
+  syn match dircolorsColor69    contained '\<69\>'
+  syn match dircolorsColor70    contained '\<70\>'
+  syn match dircolorsColor71    contained '\<71\>'
+  syn match dircolorsColor72    contained '\<72\>'
+  syn match dircolorsColor73    contained '\<73\>'
+  syn match dircolorsColor74    contained '\<74\>'
+  syn match dircolorsColor75    contained '\<75\>'
+  syn match dircolorsColor76    contained '\<76\>'
+  syn match dircolorsColor77    contained '\<77\>'
+  syn match dircolorsColor78    contained '\<78\>'
+  syn match dircolorsColor79    contained '\<79\>'
+  syn match dircolorsColor80    contained '\<80\>'
+  syn match dircolorsColor81    contained '\<81\>'
+  syn match dircolorsColor82    contained '\<82\>'
+  syn match dircolorsColor83    contained '\<83\>'
+  syn match dircolorsColor84    contained '\<84\>'
+  syn match dircolorsColor85    contained '\<85\>'
+  syn match dircolorsColor86    contained '\<86\>'
+  syn match dircolorsColor87    contained '\<87\>'
+  syn match dircolorsColor88    contained '\<88\>'
+  syn match dircolorsColor89    contained '\<89\>'
+  syn match dircolorsColor90    contained '\<90\>'
+  syn match dircolorsColor91    contained '\<91\>'
+  syn match dircolorsColor92    contained '\<92\>'
+  syn match dircolorsColor93    contained '\<93\>'
+  syn match dircolorsColor94    contained '\<94\>'
+  syn match dircolorsColor95    contained '\<95\>'
+  syn match dircolorsColor96    contained '\<96\>'
+  syn match dircolorsColor97    contained '\<97\>'
+  syn match dircolorsColor98    contained '\<98\>'
+  syn match dircolorsColor99    contained '\<99\>'
+  syn match dircolorsColor100   contained '\<100\>'
+  syn match dircolorsColor101   contained '\<101\>'
+  syn match dircolorsColor102   contained '\<102\>'
+  syn match dircolorsColor103   contained '\<103\>'
+  syn match dircolorsColor104   contained '\<104\>'
+  syn match dircolorsColor105   contained '\<105\>'
+  syn match dircolorsColor106   contained '\<106\>'
+  syn match dircolorsColor107   contained '\<107\>'
+  syn match dircolorsColor108   contained '\<108\>'
+  syn match dircolorsColor109   contained '\<109\>'
+  syn match dircolorsColor110   contained '\<110\>'
+  syn match dircolorsColor111   contained '\<111\>'
+  syn match dircolorsColor112   contained '\<112\>'
+  syn match dircolorsColor113   contained '\<113\>'
+  syn match dircolorsColor114   contained '\<114\>'
+  syn match dircolorsColor115   contained '\<115\>'
+  syn match dircolorsColor116   contained '\<116\>'
+  syn match dircolorsColor117   contained '\<117\>'
+  syn match dircolorsColor118   contained '\<118\>'
+  syn match dircolorsColor119   contained '\<119\>'
+  syn match dircolorsColor120   contained '\<120\>'
+  syn match dircolorsColor121   contained '\<121\>'
+  syn match dircolorsColor122   contained '\<122\>'
+  syn match dircolorsColor123   contained '\<123\>'
+  syn match dircolorsColor124   contained '\<124\>'
+  syn match dircolorsColor125   contained '\<125\>'
+  syn match dircolorsColor126   contained '\<126\>'
+  syn match dircolorsColor127   contained '\<127\>'
+  syn match dircolorsColor128   contained '\<128\>'
+  syn match dircolorsColor129   contained '\<129\>'
+  syn match dircolorsColor130   contained '\<130\>'
+  syn match dircolorsColor131   contained '\<131\>'
+  syn match dircolorsColor132   contained '\<132\>'
+  syn match dircolorsColor133   contained '\<133\>'
+  syn match dircolorsColor134   contained '\<134\>'
+  syn match dircolorsColor135   contained '\<135\>'
+  syn match dircolorsColor136   contained '\<136\>'
+  syn match dircolorsColor137   contained '\<137\>'
+  syn match dircolorsColor138   contained '\<138\>'
+  syn match dircolorsColor139   contained '\<139\>'
+  syn match dircolorsColor140   contained '\<140\>'
+  syn match dircolorsColor141   contained '\<141\>'
+  syn match dircolorsColor142   contained '\<142\>'
+  syn match dircolorsColor143   contained '\<143\>'
+  syn match dircolorsColor144   contained '\<144\>'
+  syn match dircolorsColor145   contained '\<145\>'
+  syn match dircolorsColor146   contained '\<146\>'
+  syn match dircolorsColor147   contained '\<147\>'
+  syn match dircolorsColor148   contained '\<148\>'
+  syn match dircolorsColor149   contained '\<149\>'
+  syn match dircolorsColor150   contained '\<150\>'
+  syn match dircolorsColor151   contained '\<151\>'
+  syn match dircolorsColor152   contained '\<152\>'
+  syn match dircolorsColor153   contained '\<153\>'
+  syn match dircolorsColor154   contained '\<154\>'
+  syn match dircolorsColor155   contained '\<155\>'
+  syn match dircolorsColor156   contained '\<156\>'
+  syn match dircolorsColor157   contained '\<157\>'
+  syn match dircolorsColor158   contained '\<158\>'
+  syn match dircolorsColor159   contained '\<159\>'
+  syn match dircolorsColor160   contained '\<160\>'
+  syn match dircolorsColor161   contained '\<161\>'
+  syn match dircolorsColor162   contained '\<162\>'
+  syn match dircolorsColor163   contained '\<163\>'
+  syn match dircolorsColor164   contained '\<164\>'
+  syn match dircolorsColor165   contained '\<165\>'
+  syn match dircolorsColor166   contained '\<166\>'
+  syn match dircolorsColor167   contained '\<167\>'
+  syn match dircolorsColor168   contained '\<168\>'
+  syn match dircolorsColor169   contained '\<169\>'
+  syn match dircolorsColor170   contained '\<170\>'
+  syn match dircolorsColor171   contained '\<171\>'
+  syn match dircolorsColor172   contained '\<172\>'
+  syn match dircolorsColor173   contained '\<173\>'
+  syn match dircolorsColor174   contained '\<174\>'
+  syn match dircolorsColor175   contained '\<175\>'
+  syn match dircolorsColor176   contained '\<176\>'
+  syn match dircolorsColor177   contained '\<177\>'
+  syn match dircolorsColor178   contained '\<178\>'
+  syn match dircolorsColor179   contained '\<179\>'
+  syn match dircolorsColor180   contained '\<180\>'
+  syn match dircolorsColor181   contained '\<181\>'
+  syn match dircolorsColor182   contained '\<182\>'
+  syn match dircolorsColor183   contained '\<183\>'
+  syn match dircolorsColor184   contained '\<184\>'
+  syn match dircolorsColor185   contained '\<185\>'
+  syn match dircolorsColor186   contained '\<186\>'
+  syn match dircolorsColor187   contained '\<187\>'
+  syn match dircolorsColor188   contained '\<188\>'
+  syn match dircolorsColor189   contained '\<189\>'
+  syn match dircolorsColor190   contained '\<190\>'
+  syn match dircolorsColor191   contained '\<191\>'
+  syn match dircolorsColor192   contained '\<192\>'
+  syn match dircolorsColor193   contained '\<193\>'
+  syn match dircolorsColor194   contained '\<194\>'
+  syn match dircolorsColor195   contained '\<195\>'
+  syn match dircolorsColor196   contained '\<196\>'
+  syn match dircolorsColor197   contained '\<197\>'
+  syn match dircolorsColor198   contained '\<198\>'
+  syn match dircolorsColor199   contained '\<199\>'
+  syn match dircolorsColor200   contained '\<200\>'
+  syn match dircolorsColor201   contained '\<201\>'
+  syn match dircolorsColor202   contained '\<202\>'
+  syn match dircolorsColor203   contained '\<203\>'
+  syn match dircolorsColor204   contained '\<204\>'
+  syn match dircolorsColor205   contained '\<205\>'
+  syn match dircolorsColor206   contained '\<206\>'
+  syn match dircolorsColor207   contained '\<207\>'
+  syn match dircolorsColor208   contained '\<208\>'
+  syn match dircolorsColor209   contained '\<209\>'
+  syn match dircolorsColor210   contained '\<210\>'
+  syn match dircolorsColor211   contained '\<211\>'
+  syn match dircolorsColor212   contained '\<212\>'
+  syn match dircolorsColor213   contained '\<213\>'
+  syn match dircolorsColor214   contained '\<214\>'
+  syn match dircolorsColor215   contained '\<215\>'
+  syn match dircolorsColor216   contained '\<216\>'
+  syn match dircolorsColor217   contained '\<217\>'
+  syn match dircolorsColor218   contained '\<218\>'
+  syn match dircolorsColor219   contained '\<219\>'
+  syn match dircolorsColor220   contained '\<220\>'
+  syn match dircolorsColor221   contained '\<221\>'
+  syn match dircolorsColor222   contained '\<222\>'
+  syn match dircolorsColor223   contained '\<223\>'
+  syn match dircolorsColor224   contained '\<224\>'
+  syn match dircolorsColor225   contained '\<225\>'
+  syn match dircolorsColor226   contained '\<226\>'
+  syn match dircolorsColor227   contained '\<227\>'
+  syn match dircolorsColor228   contained '\<228\>'
+  syn match dircolorsColor229   contained '\<229\>'
+  syn match dircolorsColor230   contained '\<230\>'
+  syn match dircolorsColor231   contained '\<231\>'
+  syn match dircolorsColor232   contained '\<232\>'
+  syn match dircolorsColor233   contained '\<233\>'
+  syn match dircolorsColor234   contained '\<234\>'
+  syn match dircolorsColor235   contained '\<235\>'
+  syn match dircolorsColor236   contained '\<236\>'
+  syn match dircolorsColor237   contained '\<237\>'
+  syn match dircolorsColor238   contained '\<238\>'
+  syn match dircolorsColor239   contained '\<239\>'
+  syn match dircolorsColor240   contained '\<240\>'
+  syn match dircolorsColor241   contained '\<241\>'
+  syn match dircolorsColor242   contained '\<242\>'
+  syn match dircolorsColor243   contained '\<243\>'
+  syn match dircolorsColor244   contained '\<244\>'
+  syn match dircolorsColor245   contained '\<245\>'
+  syn match dircolorsColor246   contained '\<246\>'
+  syn match dircolorsColor247   contained '\<247\>'
+  syn match dircolorsColor248   contained '\<248\>'
+  syn match dircolorsColor249   contained '\<249\>'
+  syn match dircolorsColor250   contained '\<250\>'
+  syn match dircolorsColor251   contained '\<251\>'
+  syn match dircolorsColor252   contained '\<252\>'
+  syn match dircolorsColor253   contained '\<253\>'
+  syn match dircolorsColor254   contained '\<254\>'
+  syn match dircolorsColor255   contained '\<255\>'
+else
+  syn cluster dircolorsColors   contains=dircolorsNumber
+  syn match   dircolorsNumber   '\<\d\+\>'
+endif
+
+hi def link dircolorsTodo       Todo
+hi def link dircolorsComment    Comment
+hi def link dircolorsKeyword    Keyword
+hi def link dircolorsExtension  Keyword
+
+if &t_Co == 8 || &t_Co == 16
+  hi def      dircolorsBold       term=bold cterm=bold gui=bold
+  hi def      dircolorsUnderline  term=underline cterm=underline gui=underline
+  hi def link dircolorsBlink      Normal
+  hi def      dircolorsReverse    term=reverse cterm=reverse gui=reverse
+  hi def link dircolorsInvisible  Ignore
+  hi def      dircolorsBlack      ctermfg=Black guifg=Black
+  hi def      dircolorsRed        ctermfg=Red guifg=Red
+  hi def      dircolorsGreen      ctermfg=Green guifg=Green
+  hi def      dircolorsYellow     ctermfg=Yellow guifg=Yellow
+  hi def      dircolorsBlue       ctermfg=Blue guifg=Blue
+  hi def      dircolorsMagenta    ctermfg=Magenta guifg=Magenta
+  hi def      dircolorsCyan       ctermfg=Cyan guifg=Cyan
+  hi def      dircolorsWhite      ctermfg=White guifg=White
+  hi def      dircolorsBGBlack    ctermbg=Black ctermfg=White
+                                  \ guibg=Black guifg=White
+  hi def      dircolorsBGRed      ctermbg=DarkRed guibg=DarkRed
+  hi def      dircolorsBGGreen    ctermbg=DarkGreen guibg=DarkGreen
+  hi def      dircolorsBGYellow   ctermbg=DarkYellow guibg=DarkYellow
+  hi def      dircolorsBGBlue     ctermbg=DarkBlue guibg=DarkBlue
+  hi def      dircolorsBGMagenta  ctermbg=DarkMagenta guibg=DarkMagenta
+  hi def      dircolorsBGCyan     ctermbg=DarkCyan guibg=DarkCyan
+  hi def      dircolorsBGWhite    ctermbg=White ctermfg=Black
+                                  \ guibg=White guifg=Black
+elseif &t_Co == 256 || has("gui_running")
+  hi def    dircolorsColor0     ctermfg=0   guifg=Black
+  hi def    dircolorsColor1     ctermfg=1   guifg=DarkRed
+  hi def    dircolorsColor2     ctermfg=2   guifg=DarkGreen
+  hi def    dircolorsColor3     ctermfg=3   guifg=DarkYellow
+  hi def    dircolorsColor4     ctermfg=4   guifg=DarkBlue
+  hi def    dircolorsColor5     ctermfg=5   guifg=DarkMagenta
+  hi def    dircolorsColor6     ctermfg=6   guifg=DarkCyan
+  hi def    dircolorsColor7     ctermfg=7   guifg=Gray
+  hi def    dircolorsColor8     ctermfg=8   guifg=DarkGray
+  hi def    dircolorsColor9     ctermfg=9   guifg=Red
+  hi def    dircolorsColor10    ctermfg=10  guifg=Green
+  hi def    dircolorsColor11    ctermfg=11  guifg=Yellow
+  hi def    dircolorsColor12    ctermfg=12  guifg=Blue
+  hi def    dircolorsColor13    ctermfg=13  guifg=Magenta
+  hi def    dircolorsColor14    ctermfg=14  guifg=Cyan
+  hi def    dircolorsColor15    ctermfg=15  guifg=White
+  hi def    dircolorsColor16    ctermfg=16  guifg=#000000
+  hi def    dircolorsColor17    ctermfg=17  guifg=#00005f
+  hi def    dircolorsColor18    ctermfg=18  guifg=#000087
+  hi def    dircolorsColor19    ctermfg=19  guifg=#0000af
+  hi def    dircolorsColor20    ctermfg=20  guifg=#0000d7
+  hi def    dircolorsColor21    ctermfg=21  guifg=#0000ff
+  hi def    dircolorsColor22    ctermfg=22  guifg=#005f00
+  hi def    dircolorsColor23    ctermfg=23  guifg=#005f5f
+  hi def    dircolorsColor24    ctermfg=24  guifg=#005f87
+  hi def    dircolorsColor25    ctermfg=25  guifg=#005faf
+  hi def    dircolorsColor26    ctermfg=26  guifg=#005fd7
+  hi def    dircolorsColor27    ctermfg=27  guifg=#005fff
+  hi def    dircolorsColor28    ctermfg=28  guifg=#008700
+  hi def    dircolorsColor29    ctermfg=29  guifg=#00875f
+  hi def    dircolorsColor30    ctermfg=30  guifg=#008787
+  hi def    dircolorsColor31    ctermfg=31  guifg=#0087af
+  hi def    dircolorsColor32    ctermfg=32  guifg=#0087d7
+  hi def    dircolorsColor33    ctermfg=33  guifg=#0087ff
+  hi def    dircolorsColor34    ctermfg=34  guifg=#00af00
+  hi def    dircolorsColor35    ctermfg=35  guifg=#00af5f
+  hi def    dircolorsColor36    ctermfg=36  guifg=#00af87
+  hi def    dircolorsColor37    ctermfg=37  guifg=#00afaf
+  hi def    dircolorsColor38    ctermfg=38  guifg=#00afd7
+  hi def    dircolorsColor39    ctermfg=39  guifg=#00afff
+  hi def    dircolorsColor40    ctermfg=40  guifg=#00d700
+  hi def    dircolorsColor41    ctermfg=41  guifg=#00d75f
+  hi def    dircolorsColor42    ctermfg=42  guifg=#00d787
+  hi def    dircolorsColor43    ctermfg=43  guifg=#00d7af
+  hi def    dircolorsColor44    ctermfg=44  guifg=#00d7d7
+  hi def    dircolorsColor45    ctermfg=45  guifg=#00d7ff
+  hi def    dircolorsColor46    ctermfg=46  guifg=#00ff00
+  hi def    dircolorsColor47    ctermfg=47  guifg=#00ff5f
+  hi def    dircolorsColor48    ctermfg=48  guifg=#00ff87
+  hi def    dircolorsColor49    ctermfg=49  guifg=#00ffaf
+  hi def    dircolorsColor50    ctermfg=50  guifg=#00ffd7
+  hi def    dircolorsColor51    ctermfg=51  guifg=#00ffff
+  hi def    dircolorsColor52    ctermfg=52  guifg=#5f0000
+  hi def    dircolorsColor53    ctermfg=53  guifg=#5f005f
+  hi def    dircolorsColor54    ctermfg=54  guifg=#5f0087
+  hi def    dircolorsColor55    ctermfg=55  guifg=#5f00af
+  hi def    dircolorsColor56    ctermfg=56  guifg=#5f00d7
+  hi def    dircolorsColor57    ctermfg=57  guifg=#5f00ff
+  hi def    dircolorsColor58    ctermfg=58  guifg=#5f5f00
+  hi def    dircolorsColor59    ctermfg=59  guifg=#5f5f5f
+  hi def    dircolorsColor60    ctermfg=60  guifg=#5f5f87
+  hi def    dircolorsColor61    ctermfg=61  guifg=#5f5faf
+  hi def    dircolorsColor62    ctermfg=62  guifg=#5f5fd7
+  hi def    dircolorsColor63    ctermfg=63  guifg=#5f5fff
+  hi def    dircolorsColor64    ctermfg=64  guifg=#5f8700
+  hi def    dircolorsColor65    ctermfg=65  guifg=#5f875f
+  hi def    dircolorsColor66    ctermfg=66  guifg=#5f8787
+  hi def    dircolorsColor67    ctermfg=67  guifg=#5f87af
+  hi def    dircolorsColor68    ctermfg=68  guifg=#5f87d7
+  hi def    dircolorsColor69    ctermfg=69  guifg=#5f87ff
+  hi def    dircolorsColor70    ctermfg=70  guifg=#5faf00
+  hi def    dircolorsColor71    ctermfg=71  guifg=#5faf5f
+  hi def    dircolorsColor72    ctermfg=72  guifg=#5faf87
+  hi def    dircolorsColor73    ctermfg=73  guifg=#5fafaf
+  hi def    dircolorsColor74    ctermfg=74  guifg=#5fafd7
+  hi def    dircolorsColor75    ctermfg=75  guifg=#5fafff
+  hi def    dircolorsColor76    ctermfg=76  guifg=#5fd700
+  hi def    dircolorsColor77    ctermfg=77  guifg=#5fd75f
+  hi def    dircolorsColor78    ctermfg=78  guifg=#5fd787
+  hi def    dircolorsColor79    ctermfg=79  guifg=#5fd7af
+  hi def    dircolorsColor80    ctermfg=80  guifg=#5fd7d7
+  hi def    dircolorsColor81    ctermfg=81  guifg=#5fd7ff
+  hi def    dircolorsColor82    ctermfg=82  guifg=#5fff00
+  hi def    dircolorsColor83    ctermfg=83  guifg=#5fff5f
+  hi def    dircolorsColor84    ctermfg=84  guifg=#5fff87
+  hi def    dircolorsColor85    ctermfg=85  guifg=#5fffaf
+  hi def    dircolorsColor86    ctermfg=86  guifg=#5fffd7
+  hi def    dircolorsColor87    ctermfg=87  guifg=#5fffff
+  hi def    dircolorsColor88    ctermfg=88  guifg=#870000
+  hi def    dircolorsColor89    ctermfg=89  guifg=#87005f
+  hi def    dircolorsColor90    ctermfg=90  guifg=#870087
+  hi def    dircolorsColor91    ctermfg=91  guifg=#8700af
+  hi def    dircolorsColor92    ctermfg=92  guifg=#8700d7
+  hi def    dircolorsColor93    ctermfg=93  guifg=#8700ff
+  hi def    dircolorsColor94    ctermfg=94  guifg=#875f00
+  hi def    dircolorsColor95    ctermfg=95  guifg=#875f5f
+  hi def    dircolorsColor96    ctermfg=96  guifg=#875f87
+  hi def    dircolorsColor97    ctermfg=97  guifg=#875faf
+  hi def    dircolorsColor98    ctermfg=98  guifg=#875fd7
+  hi def    dircolorsColor99    ctermfg=99  guifg=#875fff
+  hi def    dircolorsColor100   ctermfg=100 guifg=#878700
+  hi def    dircolorsColor101   ctermfg=101 guifg=#87875f
+  hi def    dircolorsColor102   ctermfg=102 guifg=#878787
+  hi def    dircolorsColor103   ctermfg=103 guifg=#8787af
+  hi def    dircolorsColor104   ctermfg=104 guifg=#8787d7
+  hi def    dircolorsColor105   ctermfg=105 guifg=#8787ff
+  hi def    dircolorsColor106   ctermfg=106 guifg=#87af00
+  hi def    dircolorsColor107   ctermfg=107 guifg=#87af5f
+  hi def    dircolorsColor108   ctermfg=108 guifg=#87af87
+  hi def    dircolorsColor109   ctermfg=109 guifg=#87afaf
+  hi def    dircolorsColor110   ctermfg=110 guifg=#87afd7
+  hi def    dircolorsColor111   ctermfg=111 guifg=#87afff
+  hi def    dircolorsColor112   ctermfg=112 guifg=#87d700
+  hi def    dircolorsColor113   ctermfg=113 guifg=#87d75f
+  hi def    dircolorsColor114   ctermfg=114 guifg=#87d787
+  hi def    dircolorsColor115   ctermfg=115 guifg=#87d7af
+  hi def    dircolorsColor116   ctermfg=116 guifg=#87d7d7
+  hi def    dircolorsColor117   ctermfg=117 guifg=#87d7ff
+  hi def    dircolorsColor118   ctermfg=118 guifg=#87ff00
+  hi def    dircolorsColor119   ctermfg=119 guifg=#87ff5f
+  hi def    dircolorsColor120   ctermfg=120 guifg=#87ff87
+  hi def    dircolorsColor121   ctermfg=121 guifg=#87ffaf
+  hi def    dircolorsColor122   ctermfg=122 guifg=#87ffd7
+  hi def    dircolorsColor123   ctermfg=123 guifg=#87ffff
+  hi def    dircolorsColor124   ctermfg=124 guifg=#af0000
+  hi def    dircolorsColor125   ctermfg=125 guifg=#af005f
+  hi def    dircolorsColor126   ctermfg=126 guifg=#af0087
+  hi def    dircolorsColor127   ctermfg=127 guifg=#af00af
+  hi def    dircolorsColor128   ctermfg=128 guifg=#af00d7
+  hi def    dircolorsColor129   ctermfg=129 guifg=#af00ff
+  hi def    dircolorsColor130   ctermfg=130 guifg=#af5f00
+  hi def    dircolorsColor131   ctermfg=131 guifg=#af5f5f
+  hi def    dircolorsColor132   ctermfg=132 guifg=#af5f87
+  hi def    dircolorsColor133   ctermfg=133 guifg=#af5faf
+  hi def    dircolorsColor134   ctermfg=134 guifg=#af5fd7
+  hi def    dircolorsColor135   ctermfg=135 guifg=#af5fff
+  hi def    dircolorsColor136   ctermfg=136 guifg=#af8700
+  hi def    dircolorsColor137   ctermfg=137 guifg=#af875f
+  hi def    dircolorsColor138   ctermfg=138 guifg=#af8787
+  hi def    dircolorsColor139   ctermfg=139 guifg=#af87af
+  hi def    dircolorsColor140   ctermfg=140 guifg=#af87d7
+  hi def    dircolorsColor141   ctermfg=141 guifg=#af87ff
+  hi def    dircolorsColor142   ctermfg=142 guifg=#afaf00
+  hi def    dircolorsColor143   ctermfg=143 guifg=#afaf5f
+  hi def    dircolorsColor144   ctermfg=144 guifg=#afaf87
+  hi def    dircolorsColor145   ctermfg=145 guifg=#afafaf
+  hi def    dircolorsColor146   ctermfg=146 guifg=#afafd7
+  hi def    dircolorsColor147   ctermfg=147 guifg=#afafff
+  hi def    dircolorsColor148   ctermfg=148 guifg=#afd700
+  hi def    dircolorsColor149   ctermfg=149 guifg=#afd75f
+  hi def    dircolorsColor150   ctermfg=150 guifg=#afd787
+  hi def    dircolorsColor151   ctermfg=151 guifg=#afd7af
+  hi def    dircolorsColor152   ctermfg=152 guifg=#afd7d7
+  hi def    dircolorsColor153   ctermfg=153 guifg=#afd7ff
+  hi def    dircolorsColor154   ctermfg=154 guifg=#afff00
+  hi def    dircolorsColor155   ctermfg=155 guifg=#afff5f
+  hi def    dircolorsColor156   ctermfg=156 guifg=#afff87
+  hi def    dircolorsColor157   ctermfg=157 guifg=#afffaf
+  hi def    dircolorsColor158   ctermfg=158 guifg=#afffd7
+  hi def    dircolorsColor159   ctermfg=159 guifg=#afffff
+  hi def    dircolorsColor160   ctermfg=160 guifg=#d70000
+  hi def    dircolorsColor161   ctermfg=161 guifg=#d7005f
+  hi def    dircolorsColor162   ctermfg=162 guifg=#d70087
+  hi def    dircolorsColor163   ctermfg=163 guifg=#d700af
+  hi def    dircolorsColor164   ctermfg=164 guifg=#d700d7
+  hi def    dircolorsColor165   ctermfg=165 guifg=#d700ff
+  hi def    dircolorsColor166   ctermfg=166 guifg=#d75f00
+  hi def    dircolorsColor167   ctermfg=167 guifg=#d75f5f
+  hi def    dircolorsColor168   ctermfg=168 guifg=#d75f87
+  hi def    dircolorsColor169   ctermfg=169 guifg=#d75faf
+  hi def    dircolorsColor170   ctermfg=170 guifg=#d75fd7
+  hi def    dircolorsColor171   ctermfg=171 guifg=#d75fff
+  hi def    dircolorsColor172   ctermfg=172 guifg=#d78700
+  hi def    dircolorsColor173   ctermfg=173 guifg=#d7875f
+  hi def    dircolorsColor174   ctermfg=174 guifg=#d78787
+  hi def    dircolorsColor175   ctermfg=175 guifg=#d787af
+  hi def    dircolorsColor176   ctermfg=176 guifg=#d787d7
+  hi def    dircolorsColor177   ctermfg=177 guifg=#d787ff
+  hi def    dircolorsColor178   ctermfg=178 guifg=#d7af00
+  hi def    dircolorsColor179   ctermfg=179 guifg=#d7af5f
+  hi def    dircolorsColor180   ctermfg=180 guifg=#d7af87
+  hi def    dircolorsColor181   ctermfg=181 guifg=#d7afaf
+  hi def    dircolorsColor182   ctermfg=182 guifg=#d7afd7
+  hi def    dircolorsColor183   ctermfg=183 guifg=#d7afff
+  hi def    dircolorsColor184   ctermfg=184 guifg=#d7d700
+  hi def    dircolorsColor185   ctermfg=185 guifg=#d7d75f
+  hi def    dircolorsColor186   ctermfg=186 guifg=#d7d787
+  hi def    dircolorsColor187   ctermfg=187 guifg=#d7d7af
+  hi def    dircolorsColor188   ctermfg=188 guifg=#d7d7d7
+  hi def    dircolorsColor189   ctermfg=189 guifg=#d7d7ff
+  hi def    dircolorsColor190   ctermfg=190 guifg=#d7ff00
+  hi def    dircolorsColor191   ctermfg=191 guifg=#d7ff5f
+  hi def    dircolorsColor192   ctermfg=192 guifg=#d7ff87
+  hi def    dircolorsColor193   ctermfg=193 guifg=#d7ffaf
+  hi def    dircolorsColor194   ctermfg=194 guifg=#d7ffd7
+  hi def    dircolorsColor195   ctermfg=195 guifg=#d7ffff
+  hi def    dircolorsColor196   ctermfg=196 guifg=#ff0000
+  hi def    dircolorsColor197   ctermfg=197 guifg=#ff005f
+  hi def    dircolorsColor198   ctermfg=198 guifg=#ff0087
+  hi def    dircolorsColor199   ctermfg=199 guifg=#ff00af
+  hi def    dircolorsColor200   ctermfg=200 guifg=#ff00d7
+  hi def    dircolorsColor201   ctermfg=201 guifg=#ff00ff
+  hi def    dircolorsColor202   ctermfg=202 guifg=#ff5f00
+  hi def    dircolorsColor203   ctermfg=203 guifg=#ff5f5f
+  hi def    dircolorsColor204   ctermfg=204 guifg=#ff5f87
+  hi def    dircolorsColor205   ctermfg=205 guifg=#ff5faf
+  hi def    dircolorsColor206   ctermfg=206 guifg=#ff5fd7
+  hi def    dircolorsColor207   ctermfg=207 guifg=#ff5fff
+  hi def    dircolorsColor208   ctermfg=208 guifg=#ff8700
+  hi def    dircolorsColor209   ctermfg=209 guifg=#ff875f
+  hi def    dircolorsColor210   ctermfg=210 guifg=#ff8787
+  hi def    dircolorsColor211   ctermfg=211 guifg=#ff87af
+  hi def    dircolorsColor212   ctermfg=212 guifg=#ff87d7
+  hi def    dircolorsColor213   ctermfg=213 guifg=#ff87ff
+  hi def    dircolorsColor214   ctermfg=214 guifg=#ffaf00
+  hi def    dircolorsColor215   ctermfg=215 guifg=#ffaf5f
+  hi def    dircolorsColor216   ctermfg=216 guifg=#ffaf87
+  hi def    dircolorsColor217   ctermfg=217 guifg=#ffafaf
+  hi def    dircolorsColor218   ctermfg=218 guifg=#ffafd7
+  hi def    dircolorsColor219   ctermfg=219 guifg=#ffafff
+  hi def    dircolorsColor220   ctermfg=220 guifg=#ffd700
+  hi def    dircolorsColor221   ctermfg=221 guifg=#ffd75f
+  hi def    dircolorsColor222   ctermfg=222 guifg=#ffd787
+  hi def    dircolorsColor223   ctermfg=223 guifg=#ffd7af
+  hi def    dircolorsColor224   ctermfg=224 guifg=#ffd7d7
+  hi def    dircolorsColor225   ctermfg=225 guifg=#ffd7ff
+  hi def    dircolorsColor226   ctermfg=226 guifg=#ffff00
+  hi def    dircolorsColor227   ctermfg=227 guifg=#ffff5f
+  hi def    dircolorsColor228   ctermfg=228 guifg=#ffff87
+  hi def    dircolorsColor229   ctermfg=229 guifg=#ffffaf
+  hi def    dircolorsColor230   ctermfg=230 guifg=#ffffd7
+  hi def    dircolorsColor231   ctermfg=231 guifg=#ffffff
+  hi def    dircolorsColor232   ctermfg=232 guifg=#080808
+  hi def    dircolorsColor233   ctermfg=233 guifg=#121212
+  hi def    dircolorsColor234   ctermfg=234 guifg=#1c1c1c
+  hi def    dircolorsColor235   ctermfg=235 guifg=#262626
+  hi def    dircolorsColor236   ctermfg=236 guifg=#303030
+  hi def    dircolorsColor237   ctermfg=237 guifg=#3a3a3a
+  hi def    dircolorsColor238   ctermfg=238 guifg=#444444
+  hi def    dircolorsColor239   ctermfg=239 guifg=#4e4e4e
+  hi def    dircolorsColor240   ctermfg=240 guifg=#585858
+  hi def    dircolorsColor241   ctermfg=241 guifg=#626262
+  hi def    dircolorsColor242   ctermfg=242 guifg=#6c6c6c
+  hi def    dircolorsColor243   ctermfg=243 guifg=#767676
+  hi def    dircolorsColor244   ctermfg=244 guifg=#808080
+  hi def    dircolorsColor245   ctermfg=245 guifg=#8a8a8a
+  hi def    dircolorsColor246   ctermfg=246 guifg=#949494
+  hi def    dircolorsColor247   ctermfg=247 guifg=#9e9e9e
+  hi def    dircolorsColor248   ctermfg=248 guifg=#a8a8a8
+  hi def    dircolorsColor249   ctermfg=249 guifg=#b2b2b2
+  hi def    dircolorsColor250   ctermfg=250 guifg=#bcbcbc
+  hi def    dircolorsColor251   ctermfg=251 guifg=#c6c6c6
+  hi def    dircolorsColor252   ctermfg=252 guifg=#d0d0d0
+  hi def    dircolorsColor253   ctermfg=253 guifg=#dadada
+  hi def    dircolorsColor254   ctermfg=254 guifg=#e4e4e4
+  hi def    dircolorsColor255   ctermfg=255 guifg=#eeeeee
+else
+  hi def link dircolorsNumber     Number
+endif
+
+let b:current_syntax = "dircolors"
+
+let &cpo = s:cpo_save
+unlet s:cpo_save
--- /dev/null
+++ b/lib/vimfiles/syntax/diva.vim
@@ -1,0 +1,110 @@
+" Vim syntax file
+" Language:		SKILL for Diva
+" Maintainer:	Toby Schaffer <jtschaff@eos.ncsu.edu>
+" Last Change:	2001 May 09
+" Comments:		SKILL is a Lisp-like programming language for use in EDA
+"				tools from Cadence Design Systems. It allows you to have
+"				a programming environment within the Cadence environment
+"				that gives you access to the complete tool set and design
+"				database. These items are for Diva verification rules decks.
+
+" Don't remove any old syntax stuff hanging around! We need stuff
+" from skill.vim.
+if !exists("did_skill_syntax_inits")
+  if version < 600
+	so <sfile>:p:h/skill.vim
+  else
+    runtime! syntax/skill.vim
+  endif
+endif
+
+syn keyword divaDRCKeywords		area enc notch ovlp sep width
+syn keyword divaDRCKeywords		app diffNet length lengtha lengthb
+syn keyword divaDRCKeywords		notParallel only_perp opposite parallel
+syn keyword divaDRCKeywords		sameNet shielded with_perp
+syn keyword divaDRCKeywords		edge edgea edgeb fig figa figb
+syn keyword divaDRCKeywords		normalGrow squareGrow message raw
+syn keyword divaMeasKeywords	perimeter length bends_all bends_full
+syn keyword divaMeasKeywords	bends_part corners_all corners_full
+syn keyword divaMeasKeywords	corners_part angles_all angles_full
+syn keyword divaMeasKeywords	angles_part fig_count butting coincident
+syn keyword divaMeasKeywords	over not_over outside inside enclosing
+syn keyword divaMeasKeywords	figure one_net two_net three_net grounded
+syn keyword divaMeasKeywords	polarized limit keep ignore
+syn match divaCtrlFunctions		"(ivIf\>"hs=s+1
+syn match divaCtrlFunctions		"\<ivIf("he=e-1
+syn match divaCtrlFunctions		"(switch\>"hs=s+1
+syn match divaCtrlFunctions		"\<switch("he=e-1
+syn match divaCtrlFunctions		"(and\>"hs=s+1
+syn match divaCtrlFunctions		"\<and("he=e-1
+syn match divaCtrlFunctions		"(or\>"hs=s+1
+syn match divaCtrlFunctions		"\<or("he=e-1
+syn match divaCtrlFunctions		"(null\>"hs=s+1
+syn match divaCtrlFunctions		"\<null("he=e-1
+syn match divaExtFunctions		"(save\(Interconnect\|Property\|Parameter\|Recognition\)\>"hs=s+1
+syn match divaExtFunctions		"\<save\(Interconnect\|Property\|Parameter\|Recognition\)("he=e-1
+syn match divaExtFunctions		"(\(save\|measure\|attach\|multiLevel\|calculate\)Parasitic\>"hs=s+1
+syn match divaExtFunctions		"\<\(save\|measure\|attach\|multiLevel\|calculate\)Parasitic("he=e-1
+syn match divaExtFunctions		"(\(calculate\|measure\)Parameter\>"hs=s+1
+syn match divaExtFunctions		"\<\(calculate\|measure\)Parameter("he=e-1
+syn match divaExtFunctions		"(measure\(Resistance\|Fringe\)\>"hs=s+1
+syn match divaExtFunctions		"\<measure\(Resistance\|Fringe\)("he=e-1
+syn match divaExtFunctions		"(extract\(Device\|MOS\)\>"hs=s+1
+syn match divaExtFunctions		"\<extract\(Device\|MOS\)("he=e-1
+syn match divaDRCFunctions		"(checkAllLayers\>"hs=s+1
+syn match divaDRCFunctions		"\<checkAllLayers("he=e-1
+syn match divaDRCFunctions		"(checkLayer\>"hs=s+1
+syn match divaDRCFunctions		"\<checkLayer("he=e-1
+syn match divaDRCFunctions		"(drc\>"hs=s+1
+syn match divaDRCFunctions		"\<drc("he=e-1
+syn match divaDRCFunctions		"(drcAntenna\>"hs=s+1
+syn match divaDRCFunctions		"\<drcAntenna("he=e-1
+syn match divaFunctions			"(\(drcExtract\|lvs\)Rules\>"hs=s+1
+syn match divaFunctions			"\<\(drcExtract\|lvs\)Rules("he=e-1
+syn match divaLayerFunctions	"(saveDerived\>"hs=s+1
+syn match divaLayerFunctions	"\<saveDerived("he=e-1
+syn match divaLayerFunctions	"(copyGraphics\>"hs=s+1
+syn match divaLayerFunctions	"\<copyGraphics("he=e-1
+syn match divaChkFunctions		"(dubiousData\>"hs=s+1
+syn match divaChkFunctions		"\<dubiousData("he=e-1
+syn match divaChkFunctions		"(offGrid\>"hs=s+1
+syn match divaChkFunctions		"\<offGrid("he=e-1
+syn match divaLVSFunctions		"(compareDeviceProperty\>"hs=s+1
+syn match divaLVSFunctions		"\<compareDeviceProperty("he=e-1
+syn match divaLVSFunctions		"(ignoreTerminal\>"hs=s+1
+syn match divaLVSFunctions		"\<ignoreTerminal("he=e-1
+syn match divaLVSFunctions		"(parameterMatchType\>"hs=s+1
+syn match divaLVSFunctions		"\<parameterMatchType("he=e-1
+syn match divaLVSFunctions		"(\(permute\|prune\|remove\)Device\>"hs=s+1
+syn match divaLVSFunctions		"\<\(permute\|prune\|remove\)Device("he=e-1
+syn match divaGeomFunctions		"(geom\u\a\+\(45\|90\)\=\>"hs=s+1
+syn match divaGeomFunctions		"\<geom\u\a\+\(45\|90\)\=("he=e-1
+
+" Define the default highlighting.
+" For version 5.7 and earlier: only when not done already
+" For version 5.8 and later: only when an item doesn't have highlighting yet
+if version >= 508 || !exists("did_diva_syntax_inits")
+	if version < 508
+		let did_diva_syntax_inits = 1
+		command -nargs=+ HiLink hi link <args>
+	else
+		command -nargs=+ HiLink hi def link <args>
+	endif
+
+	HiLink divaDRCKeywords		Statement
+	HiLink divaMeasKeywords		Statement
+	HiLink divaCtrlFunctions	Conditional
+	HiLink divaExtFunctions		Function
+	HiLink divaDRCFunctions		Function
+	HiLink divaFunctions		Function
+	HiLink divaLayerFunctions	Function
+	HiLink divaChkFunctions		Function
+	HiLink divaLVSFunctions		Function
+	HiLink divaGeomFunctions	Function
+
+	delcommand HiLink
+endif
+
+let b:current_syntax = "diva"
+
+" vim:ts=4
--- /dev/null
+++ b/lib/vimfiles/syntax/django.vim
@@ -1,0 +1,93 @@
+" Vim syntax file
+" Language:	Django template
+" Maintainer:	Dave Hodder <dmh@dmh.org.uk>
+" Last Change:	2007 Apr 21
+
+" For version 5.x: Clear all syntax items
+" For version 6.x: Quit when a syntax file was already loaded
+if version < 600
+  syntax clear
+elseif exists("b:current_syntax")
+  finish
+endif
+
+syntax case match
+
+" Mark illegal characters
+syn match djangoError "%}\|}}\|#}"
+
+" Django template built-in tags and parameters
+" 'comment' doesn't appear here because it gets special treatment
+syn keyword djangoStatement contained and as block endblock by cycle debug else
+syn keyword djangoStatement contained extends filter endfilter firstof for
+syn keyword djangoStatement contained endfor if endif ifchanged endifchanged
+syn keyword djangoStatement contained ifequal endifequal ifnotequal
+syn keyword djangoStatement contained endifnotequal in include load not now or
+syn keyword djangoStatement contained parsed regroup reversed spaceless
+syn keyword djangoStatement contained endspaceless ssi templatetag openblock
+syn keyword djangoStatement contained closeblock openvariable closevariable
+syn keyword djangoStatement contained openbrace closebrace opencomment
+syn keyword djangoStatement contained closecomment widthratio url with endwith
+syn keyword djangoStatement contained get_current_language trans noop blocktrans
+syn keyword djangoStatement contained endblocktrans get_available_languages
+syn keyword djangoStatement contained get_current_language_bidi plural
+
+" Django templete built-in filters
+syn keyword djangoFilter contained add addslashes capfirst center cut date
+syn keyword djangoFilter contained default default_if_none dictsort
+syn keyword djangoFilter contained dictsortreversed divisibleby escape
+syn keyword djangoFilter contained filesizeformat first fix_ampersands
+syn keyword djangoFilter contained floatformat get_digit join length length_is
+syn keyword djangoFilter contained linebreaks linebreaksbr linenumbers ljust
+syn keyword djangoFilter contained lower make_list phone2numeric pluralize
+syn keyword djangoFilter contained pprint random removetags rjust slice slugify
+syn keyword djangoFilter contained stringformat striptags
+syn keyword djangoFilter contained time timesince timeuntil title
+syn keyword djangoFilter contained truncatewords unordered_list upper urlencode
+syn keyword djangoFilter contained urlize urlizetrunc wordcount wordwrap yesno
+
+" Keywords to highlight within comments
+syn keyword djangoTodo contained TODO FIXME XXX
+
+" Django template constants (always surrounded by double quotes)
+syn region djangoArgument contained start=/"/ skip=/\\"/ end=/"/
+
+" Mark illegal characters within tag and variables blocks
+syn match djangoTagError contained "#}\|{{\|[^%]}}\|[<>!&#]"
+syn match djangoVarError contained "#}\|{%\|%}\|[<>!&#%]"
+
+" Django template tag and variable blocks
+syn region djangoTagBlock start="{%" end="%}" contains=djangoStatement,djangoFilter,djangoArgument,djangoTagError display
+syn region djangoVarBlock start="{{" end="}}" contains=djangoFilter,djangoArgument,djangoVarError display
+
+" Django template 'comment' tag and comment block
+syn region djangoComment start="{%\s*comment\s*%}" end="{%\s*endcomment\s*%}" contains=djangoTodo
+syn region djangoComBlock start="{#" end="#}" contains=djangoTodo
+
+" Define the default highlighting.
+" For version 5.7 and earlier: only when not done already
+" For version 5.8 and later: only when an item doesn't have highlighting yet
+if version >= 508 || !exists("did_django_syn_inits")
+  if version < 508
+    let did_django_syn_inits = 1
+    command -nargs=+ HiLink hi link <args>
+  else
+    command -nargs=+ HiLink hi def link <args>
+  endif
+
+  HiLink djangoTagBlock PreProc
+  HiLink djangoVarBlock PreProc
+  HiLink djangoStatement Statement
+  HiLink djangoFilter Identifier
+  HiLink djangoArgument Constant
+  HiLink djangoTagError Error
+  HiLink djangoVarError Error
+  HiLink djangoError Error
+  HiLink djangoComment Comment
+  HiLink djangoComBlock Comment
+  HiLink djangoTodo Todo
+
+  delcommand HiLink
+endif
+
+let b:current_syntax = "django"
--- /dev/null
+++ b/lib/vimfiles/syntax/dns.vim
@@ -1,0 +1,5 @@
+" Vim syntax file
+" Language:     DNS/BIND Zone File
+
+" This has been replaced by the bindzone syntax
+:runtime! syntax/bindzone.vim
--- /dev/null
+++ b/lib/vimfiles/syntax/docbk.vim
@@ -1,0 +1,150 @@
+" Vim syntax file
+" Language:	DocBook
+" Maintainer:	Devin Weaver <vim@tritarget.com>
+" URL:		http://tritarget.com/pub/vim/syntax/docbk.vim
+" Last Change:	$Date: 2005/06/23 22:31:01 $
+" Version:	$Revision: 1.2 $
+" Thanks to Johannes Zellner <johannes@zellner.org> for the default to XML
+" suggestion.
+
+" REFERENCES:
+"   http://docbook.org/
+"   http://www.open-oasis.org/docbook/
+"
+
+" For version 5.x: Clear all syntax items
+" For version 6.x: Quit when a syntax file was already loaded
+if version < 600
+  syntax clear
+elseif exists("b:current_syntax")
+  finish
+endif
+
+" Auto detect added by Bram Moolenaar
+if !exists('b:docbk_type')
+  if expand('%:e') == "sgml"
+    let b:docbk_type = 'sgml'
+  else
+    let b:docbk_type = 'xml'
+  endif
+endif
+if 'xml' == b:docbk_type
+    doau Syntax xml
+    syn cluster xmlTagHook add=docbkKeyword
+    syn cluster xmlRegionHook add=docbkRegion,docbkTitle,docbkRemark,docbkCite
+    syn case match
+elseif 'sgml' == b:docbk_type
+    doau Syntax sgml
+    syn cluster sgmlTagHook add=docbkKeyword
+    syn cluster sgmlRegionHook add=docbkRegion,docbkTitle,docbkRemark,docbkCite
+    syn case ignore
+endif
+
+" <comment> has been removed and replace with <remark> in DocBook 4.0
+" <comment> kept for backwards compatability.
+syn keyword docbkKeyword abbrev abstract accel ackno acronym action contained
+syn keyword docbkKeyword address affiliation alt anchor answer appendix contained
+syn keyword docbkKeyword application area areaset areaspec arg artheader contained
+syn keyword docbkKeyword article articleinfo artpagenums attribution audiodata contained
+syn keyword docbkKeyword audioobject author authorblurb authorgroup contained
+syn keyword docbkKeyword authorinitials beginpage bibliodiv biblioentry contained
+syn keyword docbkKeyword bibliography bibliomisc bibliomixed bibliomset contained
+syn keyword docbkKeyword biblioset blockquote book bookbiblio bookinfo contained
+syn keyword docbkKeyword bridgehead callout calloutlist caption caution contained
+syn keyword docbkKeyword chapter citation citerefentry citetitle city contained
+syn keyword docbkKeyword classname cmdsynopsis co collab collabname contained
+syn keyword docbkKeyword colophon colspec command comment computeroutput contained
+syn keyword docbkKeyword confdates confgroup confnum confsponsor conftitle contained
+syn keyword docbkKeyword constant contractnum contractsponsor contrib contained
+syn keyword docbkKeyword copyright corpauthor corpname country database contained
+syn keyword docbkKeyword date dedication docinfo edition editor email contained
+syn keyword docbkKeyword emphasis entry entrytbl envar epigraph equation contained
+syn keyword docbkKeyword errorcode errorname errortype example fax figure contained
+syn keyword docbkKeyword filename firstname firstterm footnote footnoteref contained
+syn keyword docbkKeyword foreignphrase formalpara funcdef funcparams contained
+syn keyword docbkKeyword funcprototype funcsynopsis funcsynopsisinfo contained
+syn keyword docbkKeyword function glossary glossdef glossdiv glossentry contained
+syn keyword docbkKeyword glosslist glosssee glossseealso glossterm graphic contained
+syn keyword docbkKeyword graphicco group guibutton guiicon guilabel contained
+syn keyword docbkKeyword guimenu guimenuitem guisubmenu hardware contained
+syn keyword docbkKeyword highlights holder honorific imagedata imageobject contained
+syn keyword docbkKeyword imageobjectco important index indexdiv indexentry contained
+syn keyword docbkKeyword indexterm informalequation informalexample contained
+syn keyword docbkKeyword informalfigure informaltable inlineequation contained
+syn keyword docbkKeyword inlinegraphic inlinemediaobject interface contained
+syn keyword docbkKeyword interfacedefinition invpartnumber isbn issn contained
+syn keyword docbkKeyword issuenum itemizedlist itermset jobtitle keycap contained
+syn keyword docbkKeyword keycode keycombo keysym keyword keywordset label contained
+syn keyword docbkKeyword legalnotice lineage lineannotation link listitem contained
+syn keyword docbkKeyword literal literallayout lot lotentry manvolnum contained
+syn keyword docbkKeyword markup medialabel mediaobject mediaobjectco contained
+syn keyword docbkKeyword member menuchoice modespec mousebutton msg msgaud contained
+syn keyword docbkKeyword msgentry msgexplan msginfo msglevel msgmain contained
+syn keyword docbkKeyword msgorig msgrel msgset msgsub msgtext note contained
+syn keyword docbkKeyword objectinfo olink option optional orderedlist contained
+syn keyword docbkKeyword orgdiv orgname otheraddr othercredit othername contained
+syn keyword docbkKeyword pagenums para paramdef parameter part partintro contained
+syn keyword docbkKeyword phone phrase pob postcode preface primary contained
+syn keyword docbkKeyword primaryie printhistory procedure productname contained
+syn keyword docbkKeyword productnumber programlisting programlistingco contained
+syn keyword docbkKeyword prompt property pubdate publisher publishername contained
+syn keyword docbkKeyword pubsnumber qandadiv qandaentry qandaset question contained
+syn keyword docbkKeyword quote refclass refdescriptor refentry contained
+syn keyword docbkKeyword refentrytitle reference refmeta refmiscinfo contained
+syn keyword docbkKeyword refname refnamediv refpurpose refsect1 contained
+syn keyword docbkKeyword refsect1info refsect2 refsect2info refsect3 contained
+syn keyword docbkKeyword refsect3info refsynopsisdiv refsynopsisdivinfo contained
+syn keyword docbkKeyword releaseinfo remark replaceable returnvalue revhistory contained
+syn keyword docbkKeyword revision revnumber revremark row sbr screen contained
+syn keyword docbkKeyword screenco screeninfo screenshot secondary contained
+syn keyword docbkKeyword secondaryie sect1 sect1info sect2 sect2info sect3 contained
+syn keyword docbkKeyword sect3info sect4 sect4info sect5 sect5info section contained
+syn keyword docbkKeyword sectioninfo see seealso seealsoie seeie seg contained
+syn keyword docbkKeyword seglistitem segmentedlist segtitle seriesinfo contained
+syn keyword docbkKeyword seriesvolnums set setindex setinfo sgmltag contained
+syn keyword docbkKeyword shortaffil shortcut sidebar simpara simplelist contained
+syn keyword docbkKeyword simplesect spanspec state step street structfield contained
+syn keyword docbkKeyword structname subject subjectset subjectterm contained
+syn keyword docbkKeyword subscript substeps subtitle superscript surname contained
+syn keyword docbkKeyword symbol synopfragment synopfragmentref synopsis contained
+syn keyword docbkKeyword systemitem table tbody term tertiary tertiaryie contained
+syn keyword docbkKeyword textobject tfoot tgroup thead tip title contained
+syn keyword docbkKeyword titleabbrev toc tocback tocchap tocentry tocfront contained
+syn keyword docbkKeyword toclevel1 toclevel2 toclevel3 toclevel4 toclevel5 contained
+syn keyword docbkKeyword tocpart token trademark type ulink userinput contained
+syn keyword docbkKeyword varargs variablelist varlistentry varname contained
+syn keyword docbkKeyword videodata videoobject void volumenum warning contained
+syn keyword docbkKeyword wordasword xref year contained
+
+" Add special emphasis on some regions. Thanks to Rory Hunter <roryh@dcs.ed.ac.uk> for these ideas.
+syn region docbkRegion start="<emphasis>"lc=10 end="</emphasis>"me=e-11 contains=xmlRegion,xmlEntity,sgmlRegion,sgmlEntity keepend
+syn region docbkTitle  start="<title>"lc=7     end="</title>"me=e-8	contains=xmlRegion,xmlEntity,sgmlRegion,sgmlEntity keepend
+syn region docbkRemark start="<remark>"lc=8    end="</remark>"me=e-9	contains=xmlRegion,xmlEntity,sgmlRegion,sgmlEntity keepend
+syn region docbkRemark start="<comment>"lc=9  end="</comment>"me=e-10	contains=xmlRegion,xmlEntity,sgmlRegion,sgmlEntity keepend
+syn region docbkCite   start="<citation>"lc=10 end="</citation>"me=e-11 contains=xmlRegion,xmlEntity,sgmlRegion,sgmlEntity keepend
+
+" Define the default highlighting.
+" For version 5.7 and earlier: only when not done already
+" For version 5.8 and later: only when an item doesn't have highlighting yet
+if version >= 508 || !exists("did_docbk_syn_inits")
+  if version < 508
+    let did_docbk_syn_inits = 1
+    command -nargs=+ HiLink hi link <args>
+    hi DocbkBold term=bold cterm=bold gui=bold
+  else
+    command -nargs=+ HiLink hi def link <args>
+    hi def DocbkBold term=bold cterm=bold gui=bold
+  endif
+
+  HiLink docbkKeyword	Statement
+  HiLink docbkRegion	DocbkBold
+  HiLink docbkTitle	Title
+  HiLink docbkRemark	Comment
+  HiLink docbkCite	Constant
+
+  delcommand HiLink
+endif
+
+let b:current_syntax = "docbk"
+
+" vim: ts=8
--- /dev/null
+++ b/lib/vimfiles/syntax/docbksgml.vim
@@ -1,0 +1,7 @@
+" Vim syntax file
+" Language:	DocBook SGML
+" Maintainer:	Johannes Zellner <johannes@zellner.org>
+" Last Change:	Sam, 07 Sep 2002 17:20:46 CEST
+
+let b:docbk_type="sgml"
+runtime syntax/docbk.vim
--- /dev/null
+++ b/lib/vimfiles/syntax/docbkxml.vim
@@ -1,0 +1,7 @@
+" Vim syntax file
+" Language:	DocBook XML
+" Maintainer:	Johannes Zellner <johannes@zellner.org>
+" Last Change:	Sam, 07 Sep 2002 17:20:12 CEST
+
+let b:docbk_type="xml"
+runtime syntax/docbk.vim
--- /dev/null
+++ b/lib/vimfiles/syntax/dosbatch.vim
@@ -1,0 +1,158 @@
+" Vim syntax file
+" Language:	MSDOS batch file (with NT command extensions)
+" Maintainer:	Mike Williams <mrw@eandem.co.uk>
+" Filenames:    *.bat
+" Last Change:	16th March 2004
+" Web Page:     http://www.eandem.co.uk/mrw/vim
+"
+" Options Flags:
+" dosbatch_cmdextversion	- 1 = Windows NT, 2 = Windows 2000 [default]
+"
+
+" For version 5.x: Clear all syntax items
+" For version 6.x: Quit when a syntax file was already loaded
+if version < 600
+  syntax clear
+elseif exists("b:current_syntax")
+  finish
+endif
+
+" Set default highlighting to Win2k
+if !exists("dosbatch_cmdextversion")
+  let dosbatch_cmdextversion = 2
+endif
+
+" DOS bat files are case insensitive but case preserving!
+syn case ignore
+
+syn keyword dosbatchTodo contained	TODO
+
+" Dosbat keywords
+syn keyword dosbatchStatement	goto call exit
+syn keyword dosbatchConditional	if else
+syn keyword dosbatchRepeat	for
+
+" Some operators - first lot are case sensitive!
+syn case match
+syn keyword dosbatchOperator    EQU NEQ LSS LEQ GTR GEQ
+syn case ignore
+syn match dosbatchOperator      "\s[-+\*/%]\s"
+syn match dosbatchOperator      "="
+syn match dosbatchOperator      "[-+\*/%]="
+syn match dosbatchOperator      "\s\(&\||\|^\|<<\|>>\)=\=\s"
+syn match dosbatchIfOperator    "if\s\+\(\(not\)\=\s\+\)\=\(exist\|defined\|errorlevel\|cmdextversion\)\="lc=2
+
+" String - using "'s is a convenience rather than a requirement outside of FOR
+syn match dosbatchString	"\"[^"]*\"" contains=dosbatchVariable,dosBatchArgument,@dosbatchNumber
+syn match dosbatchString	"\<echo[^)>|]*"lc=4 contains=dosbatchVariable,dosbatchArgument,@dosbatchNumber
+syn match dosbatchEchoOperator  "\<echo\s\+\(on\|off\)\s*$"lc=4
+
+" For embedded commands
+syn match dosbatchCmd		"(\s*'[^']*'"lc=1 contains=dosbatchString,dosbatchVariable,dosBatchArgument,@dosbatchNumber,dosbatchImplicit,dosbatchStatement,dosbatchConditional,dosbatchRepeat,dosbatchOperator
+
+" Numbers - surround with ws to not include in dir and filenames
+syn match dosbatchInteger       "[[:space:]=(/:]\d\+"lc=1
+syn match dosbatchHex		"[[:space:]=(/:]0x\x\+"lc=1
+syn match dosbatchBinary	"[[:space:]=(/:]0b[01]\+"lc=1
+syn match dosbatchOctal		"[[:space:]=(/:]0\o\+"lc=1
+syn cluster dosbatchNumber      contains=dosbatchInteger,dosbatchHex,dosbatchBinary,dosbatchOctal
+
+" Command line switches
+syn match dosbatchSwitch	"/\(\a\+\|?\)"
+
+" Various special escaped char formats
+syn match dosbatchSpecialChar   "\^[&|()<>^]"
+syn match dosbatchSpecialChar   "\$[a-hl-npqstv_$+]"
+syn match dosbatchSpecialChar   "%%"
+
+" Environment variables
+syn match dosbatchIdentifier    contained "\s\h\w*\>"
+syn match dosbatchVariable	"%\h\w*%"
+syn match dosbatchVariable	"%\h\w*:\*\=[^=]*=[^%]*%"
+syn match dosbatchVariable	"%\h\w*:\~\d\+,\d\+%" contains=dosbatchInteger
+syn match dosbatchVariable	"!\h\w*!"
+syn match dosbatchVariable	"!\h\w*:\*\=[^=]*=[^%]*!"
+syn match dosbatchVariable	"!\h\w*:\~\d\+,\d\+!" contains=dosbatchInteger
+syn match dosbatchSet		"\s\h\w*[+-]\==\{-1}" contains=dosbatchIdentifier,dosbatchOperator
+
+" Args to bat files and for loops, etc
+syn match dosbatchArgument	"%\(\d\|\*\)"
+syn match dosbatchArgument	"%%[a-z]\>"
+if dosbatch_cmdextversion == 1
+  syn match dosbatchArgument	"%\~[fdpnxs]\+\(\($PATH:\)\=[a-z]\|\d\)\>"
+else
+  syn match dosbatchArgument	"%\~[fdpnxsatz]\+\(\($PATH:\)\=[a-z]\|\d\)\>"
+endif
+
+" Line labels
+syn match dosbatchLabel		"^\s*:\s*\h\w*\>"
+syn match dosbatchLabel		"\<\(goto\|call\)\s\+:\h\w*\>"lc=4
+syn match dosbatchLabel		"\<goto\s\+\h\w*\>"lc=4
+syn match dosbatchLabel		":\h\w*\>"
+
+" Comments - usual rem but also two colons as first non-space is an idiom
+syn match dosbatchComment	"^rem\($\|\s.*$\)"lc=3 contains=dosbatchTodo,@dosbatchNumber,dosbatchVariable,dosbatchArgument
+syn match dosbatchComment	"\srem\($\|\s.*$\)"lc=4 contains=dosbatchTodo,@dosbatchNumber,dosbatchVariable,dosbatchArgument
+syn match dosbatchComment	"\s*:\s*:.*$" contains=dosbatchTodo,@dosbatchNumber,dosbatchVariable,dosbatchArgument
+
+" Comments in ()'s - still to handle spaces before rem
+syn match dosbatchComment	"(rem[^)]*"lc=4 contains=dosbatchTodo,@dosbatchNumber,dosbatchVariable,dosbatchArgument
+
+syn keyword dosbatchImplicit    append assoc at attrib break cacls cd chcp chdir
+syn keyword dosbatchImplicit    chkdsk chkntfs cls cmd color comp compact convert copy
+syn keyword dosbatchImplicit    date del dir diskcomp diskcopy doskey echo endlocal
+syn keyword dosbatchImplicit    erase fc find findstr format ftype
+syn keyword dosbatchImplicit    graftabl help keyb label md mkdir mode more move
+syn keyword dosbatchImplicit    path pause popd print prompt pushd rd recover rem
+syn keyword dosbatchImplicit    ren rename replace restore rmdir set setlocal shift
+syn keyword dosbatchImplicit    sort start subst time title tree type ver verify
+syn keyword dosbatchImplicit    vol xcopy
+
+" Define the default highlighting.
+" For version 5.7 and earlier: only when not done already
+" For version 5.8 and later: only when an item doesn't have highlighting yet
+if version >= 508 || !exists("did_dosbatch_syntax_inits")
+  if version < 508
+    let did_dosbatch_syntax_inits = 1
+    command -nargs=+ HiLink hi link <args>
+  else
+    command -nargs=+ HiLink hi def link <args>
+  endif
+
+  HiLink dosbatchTodo		Todo
+
+  HiLink dosbatchStatement	Statement
+  HiLink dosbatchCommands	dosbatchStatement
+  HiLink dosbatchLabel		Label
+  HiLink dosbatchConditional	Conditional
+  HiLink dosbatchRepeat		Repeat
+
+  HiLink dosbatchOperator	Operator
+  HiLink dosbatchEchoOperator	dosbatchOperator
+  HiLink dosbatchIfOperator	dosbatchOperator
+
+  HiLink dosbatchArgument	Identifier
+  HiLink dosbatchIdentifier	Identifier
+  HiLink dosbatchVariable	dosbatchIdentifier
+
+  HiLink dosbatchSpecialChar	SpecialChar
+  HiLink dosbatchString		String
+  HiLink dosbatchNumber		Number
+  HiLink dosbatchInteger	dosbatchNumber
+  HiLink dosbatchHex		dosbatchNumber
+  HiLink dosbatchBinary		dosbatchNumber
+  HiLink dosbatchOctal		dosbatchNumber
+
+  HiLink dosbatchComment	Comment
+  HiLink dosbatchImplicit	Function
+
+  HiLink dosbatchSwitch		Special
+
+  HiLink dosbatchCmd		PreProc
+
+  delcommand HiLink
+endif
+
+let b:current_syntax = "dosbatch"
+
+" vim: ts=8
--- /dev/null
+++ b/lib/vimfiles/syntax/dosini.vim
@@ -1,0 +1,44 @@
+" Vim syntax file
+" Language:	Configuration File (ini file) for MSDOS/MS Windows
+" Version Info: @(#)dosini.vim 1.6 97/12/15 08:54:12
+" Author:       Sean M. McKee <mckee@misslink.net>
+" Maintainer:   Nima Talebi <nima@it.net.au>
+" Last Change:	Mon, 26 Jun 2006 22:07:28 +1000
+
+
+" For version 5.x: Clear all syntax items
+" For version 6.x: Quit when a syntax file was already loaded
+if version < 600
+  syntax clear
+elseif exists("b:current_syntax")
+  finish
+endif
+
+" shut case off
+syn case ignore
+
+syn match  dosiniLabel		"^.\{-}="
+syn region dosiniHeader		start="^\[" end="\]"
+syn match  dosiniComment	"^;.*$"
+
+" Define the default highlighting.
+" For version 5.7 and earlier: only when not done already
+" For version 5.8 and later: only when an item doesn't have highlighting yet
+if version >= 508 || !exists("did_dosini_syntax_inits")
+  if version < 508
+    let did_dosini_syntax_inits = 1
+    command -nargs=+ HiLink hi link <args>
+  else
+    command -nargs=+ HiLink hi def link <args>
+  endif
+
+	HiLink dosiniHeader	Special
+	HiLink dosiniComment	Comment
+	HiLink dosiniLabel	Type
+
+  delcommand HiLink
+endif
+
+let b:current_syntax = "dosini"
+
+" vim:ts=8
--- /dev/null
+++ b/lib/vimfiles/syntax/dot.vim
@@ -1,0 +1,110 @@
+" Vim syntax file
+" Language:     Dot
+" Filenames:    *.dot
+" Maintainer:   Markus Mottl  <markus.mottl@gmail.com>
+" URL:          http://www.ocaml.info/vim/syntax/dot.vim
+" Last Change:  2006 Feb 05
+"               2001 May 04 - initial version
+
+" For version 5.x: Clear all syntax items
+" For version 6.x: Quit when a syntax file was already loaded
+if version < 600
+  syntax clear
+elseif exists("b:current_syntax")
+  finish
+endif
+
+" Errors
+syn match    dotParErr     ")"
+syn match    dotBrackErr   "]"
+syn match    dotBraceErr   "}"
+
+" Enclosing delimiters
+syn region   dotEncl transparent matchgroup=dotParEncl start="(" matchgroup=dotParEncl end=")" contains=ALLBUT,dotParErr
+syn region   dotEncl transparent matchgroup=dotBrackEncl start="\[" matchgroup=dotBrackEncl end="\]" contains=ALLBUT,dotBrackErr
+syn region   dotEncl transparent matchgroup=dotBraceEncl start="{" matchgroup=dotBraceEncl end="}" contains=ALLBUT,dotBraceErr
+
+" Comments
+syn region   dotComment start="//" end="$" contains=dotComment,dotTodo
+syn region   dotComment start="/\*" end="\*/" contains=dotComment,dotTodo
+syn keyword  dotTodo contained TODO FIXME XXX
+
+" Strings
+syn region   dotString    start=+"+ skip=+\\\\\|\\"+ end=+"+
+
+" General keywords
+syn keyword  dotKeyword  digraph node edge subgraph
+
+" Graph attributes
+syn keyword  dotType center layers margin mclimit name nodesep nslimit
+syn keyword  dotType ordering page pagedir rank rankdir ranksep ratio
+syn keyword  dotType rotate size
+
+" Node attributes
+syn keyword  dotType distortion fillcolor fontcolor fontname fontsize
+syn keyword  dotType height layer orientation peripheries regular
+syn keyword  dotType shape shapefile sides skew width
+
+" Edge attributes
+syn keyword  dotType arrowhead arrowsize arrowtail constraint decorateP
+syn keyword  dotType dir headclip headlabel labelangle labeldistance
+syn keyword  dotType labelfontcolor labelfontname labelfontsize
+syn keyword  dotType minlen port_label_distance samehead sametail
+syn keyword  dotType tailclip taillabel weight
+
+" Shared attributes (graphs, nodes, edges)
+syn keyword  dotType color
+
+" Shared attributes (graphs and edges)
+syn keyword  dotType bgcolor label URL
+
+" Shared attributes (nodes and edges)
+syn keyword  dotType fontcolor fontname fontsize layer style
+
+" Special chars
+syn match    dotKeyChar  "="
+syn match    dotKeyChar  ";"
+syn match    dotKeyChar  "->"
+
+" Identifier
+syn match    dotIdentifier /\<\w\+\>/
+
+" Synchronization
+syn sync minlines=50
+syn sync maxlines=500
+
+" Define the default highlighting.
+" For version 5.7 and earlier: only when not done already
+" For version 5.8 and later: only when an item doesn't have highlighting yet
+if version >= 508 || !exists("did_dot_syntax_inits")
+  if version < 508
+    let did_dot_syntax_inits = 1
+    command -nargs=+ HiLink hi link <args>
+  else
+    command -nargs=+ HiLink hi def link <args>
+  endif
+
+  HiLink dotParErr	 Error
+  HiLink dotBraceErr	 Error
+  HiLink dotBrackErr	 Error
+
+  HiLink dotComment	 Comment
+  HiLink dotTodo	 Todo
+
+  HiLink dotParEncl	 Keyword
+  HiLink dotBrackEncl	 Keyword
+  HiLink dotBraceEncl	 Keyword
+
+  HiLink dotKeyword	 Keyword
+  HiLink dotType	 Type
+  HiLink dotKeyChar	 Keyword
+
+  HiLink dotString	 String
+  HiLink dotIdentifier	 Identifier
+
+  delcommand HiLink
+endif
+
+let b:current_syntax = "dot"
+
+" vim: ts=8
--- /dev/null
+++ b/lib/vimfiles/syntax/doxygen.vim
@@ -1,0 +1,592 @@
+" DoxyGen syntax hilighting extension for c/c++/idl/java
+" Language:     doxygen on top of c, cpp, idl, java
+" Maintainer:   Michael Geddes <vimmer@frog.wheelycreek.net>
+" Author:       Michael Geddes
+" Last Change:  April 2007
+" Version:      1.20
+"
+" Copyright 2004-2006 Michael Geddes
+" Please feel free to use, modify & distribute all or part of this script,
+" providing this copyright message remains.
+" I would appreciate being acknowledged in any derived scripts, and would
+" appreciate and welcome any updates, modifications or suggestions.
+
+" NOTE:  Comments welcome!
+"
+" There are two variables that control the syntax highlighting produced by this
+" script:
+" doxygen_enhanced_colour  - Use the (non-standard) original colours designed
+"                            for this highlighting.
+" doxygen_my_rendering     - Disable the HTML bold/italic/underline rendering.
+"
+" A brief description without '.' or '!' will cause the end comment
+" character to be marked as an error.  You can define the colour of this using
+" the highlight doxygenErrorComment.
+" A \link without an \endlink will cause an error highlight on the end-comment.
+" This is defined by doxygenLinkError
+"
+" The variable g:doxygen_codeword_font can be set to the guifont for marking \c
+" words - a 'typewriter' like font normally. Spaces must be escaped.  It can
+" also be set to any highlight attribute. Alternatively, a highlight for doxygenCodeWord
+" can be used to override it.
+"
+" By default, highlighting is done assumng you have the JAVADOC_AUTOBRIEF
+" setting turned on in your Doxygen configuration.  If you don't, you
+" can set the variable g:doxygen_javadoc_autobrief to 0 to have the
+" highlighting more accurately reflect the way Doxygen will interpret your
+" comments.
+"
+" Special thanks to:  Wu Yongwei, Toby Allsopp
+"
+
+if exists('b:suppress_doxygen')
+  unlet b:suppress_doxygen
+  finish
+endif
+
+if exists('b:current_syntax') && b:current_syntax =~ 'doxygen' && !exists('doxygen_debug_script')
+  finish
+endif
+
+let s:cpo_save = &cpo
+try
+  set cpo&vim
+
+  " Start of Doxygen syntax hilighting:
+  "
+
+  " C/C++ Style line comments
+  syn region doxygenComment start=+/\*\(\*/\)\@![*!]+  end=+\*/+ contains=doxygenSyncStart,doxygenStart,doxygenTODO keepend fold
+  syn region doxygenCommentL start=+//[/!]<\@!+me=e-1 end=+$+ contains=doxygenStartL keepend skipwhite skipnl nextgroup=doxygenComment2 fold
+  syn region doxygenCommentL start=+//[/!]<+me=e-2 end=+$+ contains=doxygenStartL keepend skipwhite skipnl fold
+  syn region doxygenCommentL start=+//@\ze[{}]+ end=+$+ contains=doxygenGroupDefine,doxygenGroupDefineSpecial fold
+
+  " Single line brief followed by multiline comment.
+  syn region doxygenComment2 start=+/\*\(\*/\)\@![*!]+ end=+\*/+ contained contains=doxygenSyncStart2,doxygenStart2,doxygenTODO keepend fold
+  " This helps with sync-ing as for some reason, syncing behaves differently to a normal region, and the start pattern does not get matched.
+  syn match doxygenSyncStart2 +[^*/]+ contained nextgroup=doxygenBody,doxygenPrev,doxygenStartSpecial,doxygenSkipComment,doxygenStartSkip2 skipwhite skipnl
+
+  " Skip empty lines at the start for when comments start on the 2nd/3rd line.
+  syn match doxygenStartSkip2 +^\s*\*[^/]+me=e-1 contained nextgroup=doxygenBody,doxygenStartSpecial,doxygenStartSkip skipwhite skipnl
+  syn match doxygenStartSkip2 +^\s*\*$+ contained nextgroup=doxygenBody,doxygenStartSpecial,,doxygenStartSkip skipwhite skipnl
+  syn match doxygenStart2 +/\*[*!]+ contained nextgroup=doxygenBody,doxygenPrev,doxygenStartSpecial,doxygenStartSkip2 skipwhite skipnl
+
+
+  " Match the Starting pattern (effectively creating the start of a BNF)
+  if !exists('g:doxygen_javadoc_autobrief') || g:doxygen_javadoc_autobrief
+    syn match doxygenStart +/\*[*!]+ contained nextgroup=doxygenBrief,doxygenPrev,doxygenFindBriefSpecial,doxygenStartSpecial,doxygenStartSkip,doxygenPage skipwhite skipnl
+    syn match doxygenStartL +//[/!]+ contained nextgroup=doxygenPrevL,doxygenBriefL,doxygenSpecial skipwhite
+    " Match the first sentence as a brief comment
+    if ! exists('g:doxygen_end_punctuation')
+      let g:doxygen_end_punctuation='[.]'
+    endif
+
+    exe 'syn region doxygenBrief contained start=+[\\@]\([npcbea]\>\|em\>\|ref\>\|link\>\|f\$\|[$\\&<>#]\)\|[^ \t\\@*]+ start=+\(^\s*\)\@<!\*/\@!+ start=+\<\k+ skip=+'.doxygen_end_punctuation.'\S\@=+ end=+'.doxygen_end_punctuation.'+ end=+\(\s*\(\n\s*\*\=\s*\)[@\\]\([npcbea]\>\|em\>\|ref\>\|link\>\|f\$\|[$\\&<>#]\)\@!\)\@=+ contains=doxygenSmallSpecial,doxygenContinueComment,doxygenBriefEndComment,doxygenFindBriefSpecial,doxygenSmallSpecial,@doxygenHtmlGroup,doxygenTODO,doxygenHyperLink,doxygenHashLink,@Spell  skipnl nextgroup=doxygenBody'
+
+    syn match doxygenBriefEndComment +\*/+ contained
+
+    exe 'syn region doxygenBriefL start=+@\k\@!\|[\\@]\([npcbea]\>\|em\>\|ref\>\|link\>\|f\$\|[$\\&<>#]\)\|[^ \t\\@]+ start=+\<+ skip=+'.doxygen_end_punctuation.'\S+ end=+'.doxygen_end_punctuation.'\|$+ contained contains=doxygenSmallSpecial,doxygenHyperLink,doxygenHashLink,@doxygenHtmlGroup,@Spell keepend'
+    syn match doxygenPrevL +<+ contained  nextgroup=doxygenBriefL,doxygenSpecial skipwhite
+  else
+    syn match doxygenStart +/\*[*!]+ contained nextgroup=doxygenBody,doxygenPrev,doxygenFindBriefSpecial,doxygenStartSpecial,doxygenStartSkip,doxygenPage skipwhite skipnl
+    syn match doxygenStartL +//[/!]+ contained nextgroup=doxygenPrevL,doxygenLine,doxygenSpecial skipwhite
+    syn region doxygenLine start=+@\k\@!\|[\\@]\([npcbea]\>\|em\>\|ref\>\|link\>\|f\$\|[$\\&<>#]\)\|[^ \t\\@<]+ start=+\<+ end='$' contained contains=doxygenSmallSpecial,doxygenHyperLink,doxygenHashLink,@doxygenHtmlGroup,@Spell keepend
+    syn match doxygenPrevL +<+ contained  nextgroup=doxygenLine,doxygenSpecial skipwhite
+
+  endif
+
+  " This helps with sync-ing as for some reason, syncing behaves differently to a normal region, and the start pattern does not get matched.
+  syn match doxygenSyncStart +\ze[^*/]+ contained nextgroup=doxygenBrief,doxygenPrev,doxygenStartSpecial,doxygenFindBriefSpecial,doxygenStartSkip,doxygenPage skipwhite skipnl
+
+  syn region doxygenBriefLine contained start=+\<\k+ end=+\(\n\s*\*\=\s*\([@\\]\([npcbea]\>\|em\>\|ref\>\|link\>\|f\$\|[$\\&<>#]\)\@!\)\|\s*$\)\@=+ contains=doxygenContinueComment,doxygenFindBriefSpecial,doxygenSmallSpecial,@doxygenHtmlGroup,doxygenTODO,doxygenHyperLink,doxygenHashLink  skipwhite keepend
+
+  " Match a '<' for applying a comment to the previous element.
+  syn match doxygenPrev +<+ contained nextgroup=doxygenBrief,doxygenBody,doxygenSpecial,doxygenStartSkip skipwhite
+
+if exists("c_comment_strings")
+  " These are anti-Doxygen comments.  If there are more than two asterisks or 3 '/'s
+  " then turn the comments back into normal C comments.
+  syn region cComment start="/\*\*\*" end="\*/" contains=@cCommentGroup,cCommentString,cCharacter,cNumbersCom,cSpaceError
+  syn region cCommentL start="////" skip="\\$" end="$" contains=@cCommentGroup,cComment2String,cCharacter,cNumbersCom,cSpaceError
+else
+  syn region cComment start="/\*\*\*" end="\*/" contains=@cCommentGroup,cSpaceError
+  syn region cCommentL start="////" skip="\\$" end="$" contains=@cCommentGroup,cSpaceError
+endif
+
+  " Special commands at the start of the area:  starting with '@' or '\'
+  syn region doxygenStartSpecial contained start=+[@\\]\([npcbea]\>\|em\>\|ref\>\|link\>\|f\$\|[$\\&<>#]\)\@!+ end=+$+ end=+\*/+me=s-1,he=s-1  contains=doxygenSpecial nextgroup=doxygenSkipComment skipnl keepend
+  syn match doxygenSkipComment contained +^\s*\*/\@!+ nextgroup=doxygenBrief,doxygenStartSpecial,doxygenFindBriefSpecial,doxygenPage skipwhite
+
+  "syn region doxygenBodyBit contained start=+$+
+
+  " The main body of a doxygen comment.
+  syn region doxygenBody contained start=+\(/\*[*!]\)\@<!<\|[^<]\|$+ matchgroup=doxygenEndComment end=+\*/+re=e-2,me=e-2 contains=doxygenContinueComment,doxygenTODO,doxygenSpecial,doxygenSmallSpecial,doxygenHyperLink,doxygenHashLink,@doxygenHtmlGroup,@Spell
+
+  " These allow the skipping of comment continuation '*' characters.
+  syn match doxygenContinueComment contained +^\s*\*/\@!\s*+
+
+  " Catch a Brief comment without punctuation - flag it as an error but
+  " make sure the end comment is picked up also.
+  syn match doxygenErrorComment contained +\*/+
+
+
+  " Skip empty lines at the start for when comments start on the 2nd/3rd line.
+  if !exists('g:doxygen_javadoc_autobrief') || g:doxygen_javadoc_autobrief
+    syn match doxygenStartSkip +^\s*\*[^/]+me=e-1 contained nextgroup=doxygenBrief,doxygenStartSpecial,doxygenFindBriefSpecial,doxygenStartSkip,doxygenPage skipwhite skipnl
+    syn match doxygenStartSkip +^\s*\*$+ contained nextgroup=doxygenBrief,doxygenStartSpecial,doxygenFindBriefSpecial,doxygenStartSkip,doxygenPage skipwhite skipnl
+  else
+    syn match doxygenStartSkip +^\s*\*[^/]+me=e-1 contained nextgroup=doxygenStartSpecial,doxygenFindBriefSpecial,doxygenStartSkip,doxygenPage,doxygenBody skipwhite skipnl
+    syn match doxygenStartSkip +^\s*\*$+ contained nextgroup=doxygenStartSpecial,doxygenFindBriefSpecial,doxygenStartSkip,doxygenPage,doxygenBody skipwhite skipnl
+  endif
+
+  " Match an [@\]brief so that it moves to body-mode.
+  "
+  "
+  " syn match doxygenBriefLine  contained
+  syn match doxygenBriefSpecial contained +[@\\]+ nextgroup=doxygenBriefWord skipwhite
+  syn region doxygenFindBriefSpecial start=+[@\\]brief\>+ end=+\(\n\s*\*\=\s*\([@\\]\([npcbea]\>\|em\>\|ref\>\|link\>\|f\$\|[$\\&<>#]\)\@!\)\|\s*$\)\@=+ keepend contains=doxygenBriefSpecial nextgroup=doxygenBody keepend skipwhite skipnl contained
+
+
+  " Create the single word matching special identifiers.
+
+  fun! s:DxyCreateSmallSpecial( kword, name )
+
+    let mx='[-:0-9A-Za-z_%=&+*/!~>|]\@<!\([-0-9A-Za-z_%=+*/!~>|#]\+[-0-9A-Za-z_%=+*/!~>|]\@!\|\\[\\<>&.]@\|[.,][0-9a-zA-Z_]\@=\|::\|([^)]*)\|&[0-9a-zA-Z]\{2,7};\)\+'
+    exe 'syn region doxygenSpecial'.a:name.'Word contained start=+'.a:kword.'+ end=+\(\_s\+'.mx.'\)\@<=[-a-zA-Z_0-9+*/^%|~!=&\\]\@!+ skipwhite contains=doxygenContinueComment,doxygen'.a:name.'Word'
+    exe 'syn match doxygen'.a:name.'Word contained "\_s\@<='.mx.'" contains=doxygenHtmlSpecial,@Spell keepend'
+  endfun
+  call s:DxyCreateSmallSpecial('p', 'Code')
+  call s:DxyCreateSmallSpecial('c', 'Code')
+  call s:DxyCreateSmallSpecial('b', 'Bold')
+  call s:DxyCreateSmallSpecial('e', 'Emphasised')
+  call s:DxyCreateSmallSpecial('em', 'Emphasised')
+  call s:DxyCreateSmallSpecial('a', 'Argument')
+  call s:DxyCreateSmallSpecial('ref', 'Ref')
+  delfun s:DxyCreateSmallSpecial
+
+  syn match doxygenSmallSpecial contained +[@\\]\(\<[npcbea]\>\|\<em\>\|\<ref\>\|\<link\>\|f\$\|[$\\&<>#]\)\@=+ nextgroup=doxygenOtherLink,doxygenHyperLink,doxygenHashLink,doxygenFormula,doxygenSymbol,doxygenSpecial.*Word
+
+  " Now for special characters
+  syn match doxygenSpecial contained +[@\\]\(\<[npcbea]\>\|\<em\>\|\<ref\|\<link\>\>\|\<f\$\|[$\\&<>#]\)\@!+ nextgroup=doxygenParam,doxygenRetval,doxygenBriefWord,doxygenBold,doxygenBOther,doxygenOther,doxygenOtherTODO,doxygenOtherWARN,doxygenOtherBUG,doxygenPage,doxygenGroupDefine,doxygenCodeRegion,doxygenVerbatimRegion,doxygenDotRegion
+  " doxygenOtherLink,doxygenSymbol,doxygenFormula,doxygenErrorSpecial,doxygenSpecial.*Word
+  "
+  syn match doxygenGroupDefine contained +@\@<=[{}]+
+  syn match doxygenGroupDefineSpecial contained +@\ze[{}]+
+
+  syn match doxygenErrorSpecial contained +\s+
+
+  " Match parameters and retvals (highlighting the first word as special).
+  syn match doxygenParamDirection contained "\v\[(\s*in>((]\s*\[|\s*,\s*)out>)=|out>((]\s*\[|\s*,\s*)in>)=)\]" nextgroup=doxygenParamName skipwhite
+  syn keyword doxygenParam contained param nextgroup=doxygenParamName,doxygenParamDirection skipwhite
+  syn match doxygenParamName contained +[A-Za-z0-9_:]\++ nextgroup=doxygenSpecialMultilineDesc skipwhite
+  syn keyword doxygenRetval contained retval throw exception nextgroup=doxygenParamName skipwhite
+
+  " Match one line identifiers.
+  syn keyword doxygenOther contained addindex anchor
+  \ dontinclude endhtmlonly endlatexonly showinitializer hideinitializer
+  \ example htmlonly image include ingroup internal latexonly line
+  \ overload relates relatesalso sa skip skipline
+  \ until verbinclude version addtogroup htmlinclude copydoc dotfile
+  \ xmlonly endxmlonly
+  \ nextgroup=doxygenSpecialOnelineDesc
+
+  syn region doxygenCodeRegion contained matchgroup=doxygenOther start=+\<code\>+ matchgroup=doxygenOther end=+[\\@]\@<=\<endcode\>+ contains=doxygenCodeRegionSpecial,doxygenContinueComment,doxygenErrorComment,@NoSpell
+  syn match doxygenCodeRegionSpecial contained +[\\@]\(endcode\>\)\@=+
+
+  syn region doxygenVerbatimRegion contained matchgroup=doxygenOther start=+\<verbatim\>+ matchgroup=doxygenOther end=+[\\@]\@<=\<endverbatim\>+ contains=doxygenVerbatimRegionSpecial,doxygenContinueComment,doxygenErrorComment,@NoSpell
+  syn match doxygenVerbatimRegionSpecial contained +[\\@]\(endverbatim\>\)\@=+
+
+  if exists('b:current_syntax') 
+    let b:doxygen_syntax_save=b:current_syntax
+    unlet b:current_syntax
+  endif
+
+  syn include @Dotx syntax/dot.vim
+
+  if exists('b:doxygen_syntax_save') 
+    let b:current_syntax=b:doxygen_syntax_save
+    unlet b:doxygen_syntax_save
+  else
+    unlet b:current_syntax
+  endif
+
+  syn region doxygenDotRegion contained matchgroup=doxygenOther start=+\<dot\>+ matchgroup=doxygenOther end=+[\\@]\@<=\<enddot\>+ contains=doxygenDotRegionSpecial,doxygenErrorComment,doxygenContinueComment,@NoSpell,@Dotx
+  syn match doxygenDotRegionSpecial contained +[\\@]\(enddot\>\)\@=+
+
+  " Match single line identifiers.
+  syn keyword doxygenBOther contained class enum file fn mainpage interface
+  \ namespace struct typedef union var def name
+  \ nextgroup=doxygenSpecialTypeOnelineDesc
+
+  syn keyword doxygenOther contained par nextgroup=doxygenHeaderLine
+  syn region doxygenHeaderLine start=+.+ end=+^+ contained skipwhite nextgroup=doxygenSpecialMultilineDesc
+
+  syn keyword doxygenOther contained arg author date deprecated li return returns see invariant note post pre remarks since test nextgroup=doxygenSpecialMultilineDesc
+  syn keyword doxygenOtherTODO contained todo attention nextgroup=doxygenSpecialMultilineDesc
+  syn keyword doxygenOtherWARN contained warning nextgroup=doxygenSpecialMultilineDesc
+  syn keyword doxygenOtherBUG contained bug nextgroup=doxygenSpecialMultilineDesc
+
+  " Handle \link, \endlink, highlighting the link-to and the link text bits separately.
+  syn region doxygenOtherLink matchgroup=doxygenOther start=+\<link\>+ end=+[\@]\@<=endlink\>+ contained contains=doxygenLinkWord,doxygenContinueComment,doxygenLinkError,doxygenEndlinkSpecial
+  syn match doxygenEndlinkSpecial contained +[\\@]\zeendlink\>+
+
+  syn match doxygenLinkWord "[_a-zA-Z:#()][_a-z0-9A-Z:#()]*\>" contained skipnl nextgroup=doxygenLinkRest,doxygenContinueLinkComment
+  syn match doxygenLinkRest +[^*@\\]\|\*/\@!\|[@\\]\(endlink\>\)\@!+ contained skipnl nextgroup=doxygenLinkRest,doxygenContinueLinkComment
+  syn match doxygenContinueLinkComment contained +^\s*\*\=[^/]+me=e-1 nextgroup=doxygenLinkRest
+  syn match doxygenLinkError "\*/" contained
+  " #Link hilighting.
+  syn match doxygenHashLink /\([a-zA-Z_][0-9a-zA-Z_]*\)\?#\(\.[0-9a-zA-Z_]\@=\|[a-zA-Z0-9_]\+\|::\|()\)\+/ contained contains=doxygenHashSpecial
+  syn match doxygenHashSpecial /#/ contained
+  syn match doxygenHyperLink /\(\s\|^\s*\*\?\)\@<=\(http\|https\|ftp\):\/\/[-0-9a-zA-Z_?&=+#%/.!':;@]\+/ contained
+
+  " Handle \page.  This does not use doxygenBrief.
+  syn match doxygenPage "[\\@]page\>"me=s+1 contained skipwhite nextgroup=doxygenPagePage
+  syn keyword doxygenPagePage page contained skipwhite nextgroup=doxygenPageIdent
+  syn region doxygenPageDesc  start=+.\++ end=+$+ contained skipwhite contains=doxygenSmallSpecial,@doxygenHtmlGroup keepend skipwhite skipnl nextgroup=doxygenBody
+  syn match doxygenPageIdent "\<[a-zA-Z_0-9]\+\>" contained nextgroup=doxygenPageDesc
+
+  " Handle section
+  syn keyword doxygenOther defgroup section subsection subsubsection weakgroup contained skipwhite nextgroup=doxygenSpecialIdent
+  syn region doxygenSpecialSectionDesc  start=+.\++ end=+$+ contained skipwhite contains=doxygenSmallSpecial,@doxygenHtmlGroup keepend skipwhite skipnl nextgroup=doxygenContinueComment
+  syn match doxygenSpecialIdent "\<[a-zA-Z_0-9]\+\>" contained nextgroup=doxygenSpecialSectionDesc
+
+  " Does the one-line description for the one-line type identifiers.
+  syn region doxygenSpecialTypeOnelineDesc  start=+.\++ end=+$+ contained skipwhite contains=doxygenSmallSpecial,@doxygenHtmlGroup keepend
+  syn region doxygenSpecialOnelineDesc  start=+.\++ end=+$+ contained skipwhite contains=doxygenSmallSpecial,@doxygenHtmlGroup keepend
+
+  " Handle the multiline description for the multiline type identifiers.
+  " Continue until an 'empty' line (can contain a '*' continuation) or until the
+  " next whole-line @ command \ command.
+  syn region doxygenSpecialMultilineDesc  start=+.\++ skip=+^\s*\(\*/\@!\s*\)\=\(\<\|[@\\]\<\([npcbea]\>\|em\>\|ref\|link\>\>\|f\$\|[$\\&<>#]\)\|[^ \t\\@*]\)+ end=+^+ contained contains=doxygenSpecialContinueComment,doxygenSmallSpecial,doxygenHyperLink,doxygenHashLink,@doxygenHtmlGroup,@Spell  skipwhite keepend
+  syn match doxygenSpecialContinueComment contained +^\s*\*/\@!\s*+ nextgroup=doxygenSpecial skipwhite
+
+  " Handle special cases  'bold' and 'group'
+  syn keyword doxygenBold contained bold nextgroup=doxygenSpecialHeading
+  syn keyword doxygenBriefWord contained brief nextgroup=doxygenBriefLine skipwhite
+  syn match doxygenSpecialHeading +.\++ contained skipwhite
+  syn keyword doxygenGroup contained group nextgroup=doxygenGroupName skipwhite
+  syn keyword doxygenGroupName contained +\k\++ nextgroup=doxygenSpecialOnelineDesc skipwhite
+
+  " Handle special symbol identifiers  @$, @\, @$ etc
+  syn match doxygenSymbol contained +[$\\&<>#n]+
+
+  " Simplistic handling of formula regions
+  syn region doxygenFormula contained matchgroup=doxygenFormulaEnds start=+f\$+ end=+[@\\]f\$+ contains=doxygenFormulaSpecial,doxygenFormulaOperator
+  syn match doxygenFormulaSpecial contained +[@\\]\(f[^$]\|[^f]\)+me=s+1 nextgroup=doxygenFormulaKeyword,doxygenFormulaEscaped
+  syn match doxygenFormulaEscaped contained "."
+  syn match doxygenFormulaKeyword contained  "[a-z]\+"
+  syn match doxygenFormulaOperator contained +[_^]+
+
+  syn region doxygenFormula contained matchgroup=doxygenFormulaEnds start=+f\[+ end=+[@\\]f]+ contains=doxygenFormulaSpecial,doxygenFormulaOperator,doxygenAtom
+  syn region doxygenAtom contained transparent matchgroup=doxygenFormulaOperator start=+{+ end=+}+ contains=doxygenAtom,doxygenFormulaSpecial,doxygenFormulaOperator
+
+  " Add TODO hilighting.
+  syn keyword doxygenTODO contained TODO README XXX FIXME
+
+  " Supported HTML subset.  Not perfect, but okay.
+  syn case ignore
+  syn region doxygenHtmlTag contained matchgroup=doxygenHtmlCh start=+\v\</=\ze([biuap]|em|strong|img|br|center|code|dfn|d[ldt]|hr|h[0-3]|li|[ou]l|pre|small|sub|sup|table|tt|var|caption|src|alt|longdesc|name|height|width|usemap|ismap|href|type)>+ skip=+\\<\|\<\k\+=\("[^"]*"\|'[^']*\)+ end=+>+ contains=doxygenHtmlCmd,doxygenContinueComment,doxygenHtmlVar
+  syn keyword doxygenHtmlCmd contained b i em strong u img a br p center code dfn dl dd dt hr h1 h2 h3 li ol ul pre small sub sup table tt var caption nextgroup=doxygenHtmlVar skipwhite
+  syn keyword doxygenHtmlVar contained src alt longdesc name height width usemap ismap href type nextgroup=doxygenHtmlEqu skipwhite
+  syn match doxygenHtmlEqu contained +=+ nextgroup=doxygenHtmlExpr skipwhite
+  syn match doxygenHtmlExpr contained +"\(\\.\|[^"]\)*"\|'\(\\.\|[^']\)*'+ nextgroup=doxygenHtmlVar skipwhite
+  syn case match
+  syn match doxygenHtmlSpecial contained "&\(copy\|quot\|[AEIOUYaeiouy]uml\|[AEIOUYaeiouy]acute\|[AEIOUaeiouy]grave\|[AEIOUaeiouy]circ\|[ANOano]tilde\|szlig\|[Aa]ring\|nbsp\|gt\|lt\|amp\);"
+
+  syn cluster doxygenHtmlGroup contains=doxygenHtmlCode,doxygenHtmlBold,doxygenHtmlUnderline,doxygenHtmlItalic,doxygenHtmlSpecial,doxygenHtmlTag,doxygenHtmlLink
+
+  syn cluster doxygenHtmlTop contains=@Spell,doxygenHtmlSpecial,doxygenHtmlTag,doxygenContinueComment
+  " Html Support
+  syn region doxygenHtmlLink contained start=+<[aA]\>\s*\(\n\s*\*\s*\)\=\(\(name\|href\)=\("[^"]*"\|'[^']*'\)\)\=\s*>+ end=+</[aA]>+me=e-4 contains=@doxygenHtmlTop
+  hi link doxygenHtmlLink Underlined
+
+  syn region doxygenHtmlBold contained start="\c<b\>" end="\c</b>"me=e-4 contains=@doxygenHtmlTop,doxygenHtmlBoldUnderline,doxygenHtmlBoldItalic,@Spell
+  syn region doxygenHtmlBold contained start="\c<strong\>" end="\c</strong>"me=e-9 contains=@doxygenHtmlTop,doxygenHtmlBoldUnderline,doxygenHtmlBoldItalic,@Spell
+  syn region doxygenHtmlBoldUnderline contained start="\c<u\>" end="\c</u>"me=e-4 contains=@doxygenHtmlTop,doxygenHtmlBoldUnderlineItalic,@Spell
+  syn region doxygenHtmlBoldItalic contained start="\c<i\>" end="\c</i>"me=e-4 contains=@doxygenHtmlTop,doxygenHtmlBoldItalicUnderline,@Spell
+  syn region doxygenHtmlBoldItalic contained start="\c<em\>" end="\c</em>"me=e-5 contains=@doxygenHtmlTop,doxygenHtmlBoldItalicUnderline,@Spell
+  syn region doxygenHtmlBoldUnderlineItalic contained start="\c<i\>" end="\c</i>"me=e-4 contains=@doxygenHtmlTop,@Spell
+  syn region doxygenHtmlBoldUnderlineItalic contained start="\c<em\>" end="\c</em>"me=e-5 contains=@doxygenHtmlTop,@Spell
+  syn region doxygenHtmlBoldItalicUnderline contained start="\c<u\>" end="\c</u>"me=e-4 contains=@doxygenHtmlTop,doxygenHtmlBoldUnderlineItalic,@Spell
+
+  syn region doxygenHtmlUnderline contained start="\c<u\>" end="\c</u>"me=e-4 contains=@doxygenHtmlTop,doxygenHtmlUnderlineBold,doxygenHtmlUnderlineItalic,@Spell
+  syn region doxygenHtmlUnderlineBold contained start="\c<b\>" end="\c</b>"me=e-4 contains=@doxygenHtmlTop,doxygenHtmlUnderlineBoldItalic,@Spell
+  syn region doxygenHtmlUnderlineBold contained start="\c<strong\>" end="\c</strong>"me=e-9 contains=@doxygenHtmlTop,doxygenHtmlUnderlineBoldItalic,@Spell
+  syn region doxygenHtmlUnderlineItalic contained start="\c<i\>" end="\c</i>"me=e-4 contains=@doxygenHtmlTop,htmUnderlineItalicBold,@Spell
+  syn region doxygenHtmlUnderlineItalic contained start="\c<em\>" end="\c</em>"me=e-5 contains=@doxygenHtmlTop,htmUnderlineItalicBold,@Spell
+  syn region doxygenHtmlUnderlineItalicBold contained start="\c<b\>" end="\c</b>"me=e-4 contains=@doxygenHtmlTop,@Spell
+  syn region doxygenHtmlUnderlineItalicBold contained start="\c<strong\>" end="\c</strong>"me=e-9 contains=@doxygenHtmlTop,@Spell
+  syn region doxygenHtmlUnderlineBoldItalic contained start="\c<i\>" end="\c</i>"me=e-4 contains=@doxygenHtmlTop,@Spell
+  syn region doxygenHtmlUnderlineBoldItalic contained start="\c<em\>" end="\c</em>"me=e-5 contains=@doxygenHtmlTop,@Spell
+
+  syn region doxygenHtmlItalic contained start="\c<i\>" end="\c</i>"me=e-4 contains=@doxygenHtmlTop,doxygenHtmlItalicBold,doxygenHtmlItalicUnderline,@Spell
+  syn region doxygenHtmlItalic contained start="\c<em\>" end="\c</em>"me=e-5 contains=@doxygenHtmlTop,@Spell
+  syn region doxygenHtmlItalicBold contained start="\c<b\>" end="\c</b>"me=e-4 contains=@doxygenHtmlTop,doxygenHtmlItalicBoldUnderline,@Spell
+  syn region doxygenHtmlItalicBold contained start="\c<strong\>" end="\c</strong>"me=e-9 contains=@doxygenHtmlTop,doxygenHtmlItalicBoldUnderline,@Spell
+  syn region doxygenHtmlItalicBoldUnderline contained start="\c<u\>" end="\c</u>"me=e-4 contains=@doxygenHtmlTop,@Spell
+  syn region doxygenHtmlItalicUnderline contained start="\c<u\>" end="\c</u>"me=e-4 contains=@doxygenHtmlTop,doxygenHtmlItalicUnderlineBold,@Spell
+  syn region doxygenHtmlItalicUnderlineBold contained start="\c<b\>" end="\c</b>"me=e-4 contains=@doxygenHtmlTop,@Spell
+  syn region doxygenHtmlItalicUnderlineBold contained start="\c<strong\>" end="\c</strong>"me=e-9 contains=@doxygenHtmlTop,@Spell
+
+  syn region doxygenHtmlCode contained start="\c<code\>" end="\c</code>"me=e-7 contains=@doxygenHtmlTop,@NoSpell
+
+  " Prevent the doxygen contained matches from leaking into the c/rc groups.
+  syn cluster cParenGroup add=doxygen.*
+  syn cluster cParenGroup remove=doxygenComment,doxygenCommentL
+  syn cluster cPreProcGroup add=doxygen.*
+  syn cluster cMultiGroup add=doxygen.*
+  syn cluster rcParenGroup add=doxygen.*
+  syn cluster rcParenGroup remove=doxygenComment,doxygenCommentL
+  syn cluster rcGroup add=doxygen.*
+
+  let s:my_syncolor=0
+  if !exists(':SynColor') 
+    command -nargs=+ SynColor hi def <args>
+    let s:my_syncolor=1
+  endif
+
+  let s:my_synlink=0
+  if !exists(':SynLink')
+    command -nargs=+ SynLink hi def link <args>
+    let s:my_synlink=1
+  endif
+
+  try
+    "let did_doxygen_syntax_inits = &background
+    hi doxygen_Dummy guifg=black
+
+    fun! s:Doxygen_Hilights_Base()
+      SynLink doxygenHtmlSpecial Special
+      SynLink doxygenHtmlVar Type
+      SynLink doxygenHtmlExpr String
+
+      SynLink doxygenSmallSpecial SpecialChar
+
+      SynLink doxygenSpecialCodeWord doxygenSmallSpecial
+      SynLink doxygenSpecialBoldWord doxygenSmallSpecial
+      SynLink doxygenSpecialEmphasisedWord doxygenSmallSpecial
+      SynLink doxygenSpecialArgumentWord doxygenSmallSpecial
+
+      " SynColor doxygenFormulaKeyword cterm=bold ctermfg=DarkMagenta guifg=DarkMagenta gui=bold
+      SynLink doxygenFormulaKeyword Keyword
+      "SynColor doxygenFormulaEscaped  ctermfg=DarkMagenta guifg=DarkMagenta gui=bold
+      SynLink doxygenFormulaEscaped Special
+      SynLink doxygenFormulaOperator Operator
+      SynLink doxygenFormula Statement
+      SynLink doxygenSymbol Constant
+      SynLink doxygenSpecial Special
+      SynLink doxygenFormulaSpecial Special
+      "SynColor doxygenFormulaSpecial ctermfg=DarkBlue guifg=DarkBlue
+    endfun
+    call s:Doxygen_Hilights_Base()
+
+    fun! s:Doxygen_Hilights()
+      " Pick a sensible default for 'codeword'.
+      let font=''
+      if exists('g:doxygen_codeword_font')
+        if g:doxygen_codeword_font !~ '\<\k\+='
+          let font='font='.g:doxygen_codeword_font
+        else
+          let font=g:doxygen_codeword_font
+        endif
+      else
+        " Try and pick a font (only some platforms have been tested).
+        if has('gui_running')
+          if has('gui_gtk2')
+            if &guifont == ''
+              let font="font='FreeSerif 12'"
+            else
+              let font="font='".substitute(&guifont, '^.\{-}\([0-9]\+\)$', 'FreeSerif \1','')."'"
+            endif
+
+          elseif has('gui_win32') || has('gui_win16') || has('gui_win95')
+
+            if exists('g:doxygen_use_bitsream_vera')  && g:doxygen_use_bitsream_vera
+              let font_base='Bitstream_Vera_Sans_Mono'
+            else
+              let font_base='Lucida_Console'
+            endif
+            if &guifont == ''
+              let font='font='.font_base.':h10'
+            else
+              let font='font='.matchstr(substitute(&guifont, '^[^:]*', font_base,''),'[^,]*')
+            endif
+          elseif has('gui_athena') || has('gui_gtk') || &guifont=~'^\(-[^-]\+\)\{14}'
+            if &guifont == ''
+              let font='font=-b&h-lucidatypewriter-medium-r-normal-*-*-140-*-*-m-*-iso8859-1'
+            else
+            " let font='font='.substitute(&guifont,'^\(-[^-]\+\)\{7}-\([0-9]\+\).*', '-b\&h-lucidatypewriter-medium-r-normal-*-*-\2-*-*-m-*-iso8859-1','')
+            " The above line works, but it is hard to expect the combination of
+            " the two fonts will look good.
+            endif
+          elseif has('gui_kde')
+            " let font='font=Bitstream\ Vera\ Sans\ Mono/12/-1/5/50/0/0/0/0/0'
+          endif
+        endif
+      endif
+      if font=='' | let font='gui=bold' | endif
+      exe 'SynColor doxygenCodeWord             term=bold cterm=bold '.font
+      if (exists('g:doxygen_enhanced_color') && g:doxygen_enhanced_color) || (exists('g:doxygen_enhanced_colour') && g:doxygen_enhanced_colour)
+        if &background=='light'
+          SynColor doxygenComment ctermfg=DarkRed guifg=DarkRed
+          SynColor doxygenBrief cterm=bold ctermfg=Cyan guifg=DarkBlue gui=bold
+          SynColor doxygenBody ctermfg=DarkBlue guifg=DarkBlue
+          SynColor doxygenSpecialTypeOnelineDesc cterm=bold ctermfg=DarkRed guifg=firebrick3 gui=bold
+          SynColor doxygenBOther cterm=bold ctermfg=DarkMagenta guifg=#aa50aa gui=bold
+          SynColor doxygenParam ctermfg=DarkGray guifg=#aa50aa
+          SynColor doxygenParamName cterm=italic ctermfg=DarkBlue guifg=DeepSkyBlue4 gui=italic,bold
+          SynColor doxygenSpecialOnelineDesc cterm=bold ctermfg=DarkCyan guifg=DodgerBlue3 gui=bold
+          SynColor doxygenSpecialHeading cterm=bold ctermfg=DarkBlue guifg=DeepSkyBlue4 gui=bold
+          SynColor doxygenPrev ctermfg=DarkGreen guifg=DarkGreen
+        else
+          SynColor doxygenComment ctermfg=LightRed guifg=LightRed
+          SynColor doxygenBrief cterm=bold ctermfg=Cyan ctermbg=darkgrey guifg=LightBlue gui=Bold,Italic
+          SynColor doxygenBody ctermfg=Cyan guifg=LightBlue
+          SynColor doxygenSpecialTypeOnelineDesc cterm=bold ctermfg=Red guifg=firebrick3 gui=bold
+          SynColor doxygenBOther cterm=bold ctermfg=Magenta guifg=#aa50aa gui=bold
+          SynColor doxygenParam ctermfg=LightGray guifg=LightGray
+          SynColor doxygenParamName cterm=italic ctermfg=LightBlue guifg=LightBlue gui=italic,bold
+          SynColor doxygenSpecialOnelineDesc cterm=bold ctermfg=LightCyan guifg=LightCyan gui=bold
+          SynColor doxygenSpecialHeading cterm=bold ctermfg=LightBlue guifg=LightBlue gui=bold
+          SynColor doxygenPrev ctermfg=LightGreen guifg=LightGreen
+        endif
+      else
+        SynLink doxygenComment SpecialComment
+        SynLink doxygenBrief Statement
+        SynLink doxygenBody Comment
+        SynLink doxygenSpecialTypeOnelineDesc Statement
+        SynLink doxygenBOther Constant
+        SynLink doxygenParam SpecialComment
+        SynLink doxygenParamName Underlined
+        SynLink doxygenSpecialOnelineDesc Statement
+        SynLink doxygenSpecialHeading Statement
+        SynLink doxygenPrev SpecialComment
+      endif
+    endfun
+
+    call s:Doxygen_Hilights()
+
+    " This is still a proposal, but won't do any harm.
+    aug doxygengroup
+    au!
+    au Syntax UserColor_reset nested call s:Doxygen_Hilights_Base()
+    au Syntax UserColor_{on,reset,enable} nested call s:Doxygen_Hilights()
+    aug END
+
+
+    SynLink doxygenBody                   Comment
+    SynLink doxygenLine                   doxygenBody
+    SynLink doxygenTODO                   Todo
+    SynLink doxygenOtherTODO              Todo
+    SynLink doxygenOtherWARN              Todo
+    SynLink doxygenOtherBUG               Todo
+
+    SynLink doxygenErrorSpecial           Error
+    SynLink doxygenErrorEnd               Error
+    SynLink doxygenErrorComment           Error
+    SynLink doxygenLinkError              Error
+    SynLink doxygenBriefSpecial           doxygenSpecial
+    SynLink doxygenHashSpecial            doxygenSpecial
+    SynLink doxygenGroupDefineSpecial     doxygenSpecial
+    SynLink doxygenEndlinkSpecial         doxygenSpecial
+    SynLink doxygenCodeRegionSpecial      doxygenSpecial
+    SynLink doxygenVerbatimRegionSpecial  doxygenSpecial
+    SynLink doxygenDotRegionSpecial       doxygenSpecial
+    SynLink doxygenGroupDefine            doxygenParam
+
+    SynLink doxygenSpecialMultilineDesc   doxygenSpecialOnelineDesc
+    SynLink doxygenFormulaEnds            doxygenSpecial
+    SynLink doxygenBold                   doxygenParam
+    SynLink doxygenBriefWord              doxygenParam
+    SynLink doxygenRetval                 doxygenParam
+    SynLink doxygenOther                  doxygenParam
+    SynLink doxygenStart                  doxygenComment
+    SynLink doxygenStart2                 doxygenStart
+    SynLink doxygenComment2               doxygenComment
+    SynLink doxygenCommentL               doxygenComment
+    SynLink doxygenContinueComment        doxygenComment
+    SynLink doxygenSpecialContinueComment doxygenComment
+    SynLink doxygenSkipComment            doxygenComment
+    SynLink doxygenEndComment             doxygenComment
+    SynLink doxygenStartL                 doxygenComment
+    SynLink doxygenBriefEndComment        doxygenComment
+    SynLink doxygenPrevL                  doxygenPrev
+    SynLink doxygenBriefL                 doxygenBrief
+    SynLink doxygenBriefLine              doxygenBrief
+    SynLink doxygenHeaderLine             doxygenSpecialHeading
+    SynLink doxygenStartSkip              doxygenContinueComment
+    SynLink doxygenLinkWord               doxygenParamName
+    SynLink doxygenLinkRest               doxygenSpecialMultilineDesc
+    SynLink doxygenHyperLink              doxygenLinkWord
+    SynLink doxygenHashLink               doxygenLinkWord
+
+    SynLink doxygenPage                   doxygenSpecial
+    SynLink doxygenPagePage               doxygenBOther
+    SynLink doxygenPageIdent              doxygenParamName
+    SynLink doxygenPageDesc               doxygenSpecialTypeOnelineDesc
+
+    SynLink doxygenSpecialIdent           doxygenPageIdent
+    SynLink doxygenSpecialSectionDesc     doxygenSpecialMultilineDesc
+
+    SynLink doxygenSpecialRefWord         doxygenOther
+    SynLink doxygenRefWord                doxygenPageIdent
+    SynLink doxygenContinueLinkComment    doxygenComment
+
+    SynLink doxygenHtmlCh                 Function
+    SynLink doxygenHtmlCmd                Statement
+    SynLink doxygenHtmlBoldItalicUnderline     doxygenHtmlBoldUnderlineItalic
+    SynLink doxygenHtmlUnderlineBold           doxygenHtmlBoldUnderline
+    SynLink doxygenHtmlUnderlineItalicBold     doxygenHtmlBoldUnderlineItalic
+    SynLink doxygenHtmlUnderlineBoldItalic     doxygenHtmlBoldUnderlineItalic
+    SynLink doxygenHtmlItalicUnderline         doxygenHtmlUnderlineItalic
+    SynLink doxygenHtmlItalicBold              doxygenHtmlBoldItalic
+    SynLink doxygenHtmlItalicBoldUnderline     doxygenHtmlBoldUnderlineItalic
+    SynLink doxygenHtmlItalicUnderlineBold     doxygenHtmlBoldUnderlineItalic
+    SynLink doxygenHtmlLink                    Underlined
+
+    SynLink doxygenParamDirection              StorageClass
+
+
+    if !exists("doxygen_my_rendering") && !exists("html_my_rendering")
+      SynColor doxygenBoldWord             term=bold cterm=bold gui=bold
+      SynColor doxygenEmphasisedWord       term=italic cterm=italic gui=italic
+      SynLink  doxygenArgumentWord         doxygenEmphasisedWord
+      SynLink  doxygenHtmlCode             doxygenCodeWord
+      SynLink  doxygenHtmlBold             doxygenBoldWord
+      SynColor doxygenHtmlBoldUnderline       term=bold,underline cterm=bold,underline gui=bold,underline
+      SynColor doxygenHtmlBoldItalic          term=bold,italic cterm=bold,italic gui=bold,italic
+      SynColor doxygenHtmlBoldUnderlineItalic term=bold,italic,underline cterm=bold,italic,underline gui=bold,italic,underline
+      SynColor doxygenHtmlUnderline        term=underline cterm=underline gui=underline
+      SynColor doxygenHtmlUnderlineItalic  term=italic,underline cterm=italic,underline gui=italic,underline
+      SynColor doxygenHtmlItalic           term=italic cterm=italic gui=italic
+    endif
+
+  finally
+    if s:my_synlink | delcommand SynLink | endif
+    if s:my_syncolor | delcommand SynColor | endif
+  endtry
+
+  if &syntax=='idl'
+    syn cluster idlCommentable add=doxygenComment,doxygenCommentL
+  endif
+
+  "syn sync clear
+  "syn sync maxlines=500
+  "syn sync minlines=50
+  syn sync match doxygenComment groupthere cComment "/\@<!/\*"
+  syn sync match doxygenSyncComment grouphere doxygenComment "/\@<!/\*[*!]"
+  "syn sync match doxygenSyncComment grouphere doxygenComment "/\*[*!]" contains=doxygenStart,doxygenTODO keepend
+  syn sync match doxygenSyncEndComment groupthere NONE "\*/"
+
+  if !exists('b:current_syntax')
+    let b:current_syntax = "doxygen"
+  else
+    let b:current_syntax = b:current_syntax.'.doxygen'
+  endif
+
+finally
+  let &cpo = s:cpo_save
+  unlet s:cpo_save
+endtry
+
+" vim:et sw=2 sts=2
--- /dev/null
+++ b/lib/vimfiles/syntax/dracula.vim
@@ -1,0 +1,85 @@
+" Vim syntax file
+" Language:	Dracula
+" Maintainer:	Scott Bordelon <slb@artisan.com>
+" Last change:  Wed Apr 25 18:50:01 PDT 2001
+" Extensions:   drac.*,*.drac,*.drc,*.lvs,*.lpe
+" Comment:      Dracula is an industry-standard language created by CADENCE (a
+"		company specializing in Electronics Design Automation), for
+"		the purposes of Design Rule Checking, Layout vs. Schematic
+"		verification, and Layout Parameter Extraction.
+
+" For version 5.x: Clear all syntax items
+" For version 6.x: Quit when a syntax file was already loaded
+if version < 600
+  syntax clear
+elseif exists("b:current_syntax")
+  finish
+endif
+
+" Ignore case
+syn case ignore
+
+" A bunch of useful Dracula keywords
+
+"syn match   draculaIdentifier
+
+syn keyword draculaStatement   indisk primary outdisk printfile system
+syn keyword draculaStatement   mode scale resolution listerror keepdata
+syn keyword draculaStatement   datatype by lt gt output label range touch
+syn keyword draculaStatement   inside outside within overlap outlib
+syn keyword draculaStatement   schematic model unit parset
+syn match   draculaStatement   "flag-\(non45\|acuteangle\|offgrid\)"
+syn match   draculaStatement   "text-pri-only"
+syn match   draculaStatement   "[=&]"
+syn match   draculaStatement   "\[[^,]*\]"
+syn match   draculastatement   "^ *\(sel\|width\|ext\|enc\|area\|shrink\|grow\|length\)"
+syn match   draculastatement   "^ *\(or\|not\|and\|select\|size\|connect\|sconnect\|int\)"
+syn match   draculastatement   "^ *\(softchk\|stamp\|element\|parasitic cap\|attribute cap\)"
+syn match   draculastatement   "^ *\(flagnon45\|lextract\|equation\|lpeselect\|lpechk\|attach\)"
+syn match   draculaStatement   "\(temporary\|connect\)-layer"
+syn match   draculaStatement   "program-dir"
+syn match   draculaStatement   "status-command"
+syn match   draculaStatement   "batch-queue"
+syn match   draculaStatement   "cnames-csen"
+syn match   draculaStatement   "filter-lay-opt"
+syn match   draculaStatement   "filter-sch-opt"
+syn match   draculaStatement   "power-node"
+syn match   draculaStatement   "ground-node"
+syn match   draculaStatement   "subckt-name"
+
+syn match   draculaType		"\*description"
+syn match   draculaType		"\*input-layer"
+syn match   draculaType		"\*operation"
+syn match   draculaType		"\*end"
+
+syn match   draculaComment ";.*"
+
+syn match   draculaPreProc "^#.*"
+
+"Modify the following as needed.  The trade-off is performance versus
+"functionality.
+syn sync lines=50
+
+" Define the default highlighting.
+" For version 5.7 and earlier: only when not done already
+" For version 5.8 and later: only when an item doesn't have highlighting yet
+if version >= 508 || !exists("did_dracula_syn_inits")
+  if version < 508
+    let did_dracula_syn_inits = 1
+    command -nargs=+ HiLink hi link <args>
+  else
+    command -nargs=+ HiLink hi def link <args>
+  endif
+
+  HiLink draculaIdentifier Identifier
+  HiLink draculaStatement  Statement
+  HiLink draculaType       Type
+  HiLink draculaComment    Comment
+  HiLink draculaPreProc    PreProc
+
+  delcommand HiLink
+endif
+
+let b:current_syntax = "dracula"
+
+" vim: ts=8
--- /dev/null
+++ b/lib/vimfiles/syntax/dsl.vim
@@ -1,0 +1,38 @@
+" Vim syntax file
+" Language:	DSSSL
+" Maintainer:	Johannes Zellner <johannes@zellner.org>
+" Last Change:	Tue, 27 Apr 2004 14:54:59 CEST
+" Filenames:	*.dsl
+" $Id: dsl.vim,v 1.1 2004/06/13 19:13:31 vimboss Exp $
+
+if exists("b:current_syntax") | finish | endif
+
+runtime syntax/xml.vim
+syn cluster xmlRegionHook add=dslRegion,dslComment
+syn cluster xmlCommentHook add=dslCond
+
+" EXAMPLE:
+"   <![ %output.html; [
+"     <!-- some comment -->
+"     (define html-manifest #f)
+"   ]]>
+"
+" NOTE: 'contains' the same as xmlRegion, except xmlTag / xmlEndTag
+syn region  dslCond matchgroup=dslCondDelim start="\[\_[^[]\+\[" end="]]" contains=xmlCdata,@xmlRegionCluster,xmlComment,xmlEntity,xmlProcessing,@xmlRegionHook
+
+" NOTE, that dslRegion and dslComment do both NOT have a 'contained'
+" argument, so this will also work in plain dsssl documents.
+
+syn region dslRegion matchgroup=Delimiter start=+(+ end=+)+ contains=dslRegion,dslString,dslComment
+syn match dslString +"\_[^"]*"+ contained
+syn match dslComment +;.*$+ contains=dslTodo
+syn keyword dslTodo contained TODO FIXME XXX display
+
+" The default highlighting.
+hi def link dslTodo		Todo
+hi def link dslString		String
+hi def link dslComment		Comment
+" compare the following with xmlCdataStart / xmlCdataEnd
+hi def link dslCondDelim	Type
+
+let b:current_syntax = "dsl"
--- /dev/null
+++ b/lib/vimfiles/syntax/dtd.vim
@@ -1,0 +1,181 @@
+" Vim syntax file
+" Language:	DTD (Document Type Definition for XML)
+" Maintainer:	Johannes Zellner <johannes@zellner.org>
+"		Author and previous maintainer:
+"		Daniel Amyot <damyot@site.uottawa.ca>
+" Last Change:	Tue, 27 Apr 2004 14:54:59 CEST
+" Filenames:	*.dtd
+"
+" REFERENCES:
+"   http://www.w3.org/TR/html40/
+"   http://www.w3.org/TR/NOTE-html-970421
+"
+" TODO:
+"   - improve synchronizing.
+
+if version < 600
+    syntax clear
+    let __dtd_cpo_save__ = &cpo
+    set cpo&
+else
+    if exists("b:current_syntax")
+	finish
+    endif
+    let s:dtd_cpo_save = &cpo
+    set cpo&vim
+endif
+
+if !exists("dtd_ignore_case")
+    " I prefer having the case takes into consideration.
+    syn case match
+else
+    syn case ignore
+endif
+
+
+" the following line makes the opening <! and
+" closing > highlighted using 'dtdFunction'.
+"
+" PROVIDES: @dtdTagHook
+"
+syn region dtdTag matchgroup=dtdFunction
+    \ start=+<!+ end=+>+ matchgroup=NONE
+    \ contains=dtdTag,dtdTagName,dtdError,dtdComment,dtdString,dtdAttrType,dtdAttrDef,dtdEnum,dtdParamEntityInst,dtdParamEntityDecl,dtdCard,@dtdTagHook
+
+if !exists("dtd_no_tag_errors")
+    " mark everything as an error which starts with a <!
+    " and is not overridden later. If this is annoying,
+    " it can be switched off by setting the variable
+    " dtd_no_tag_errors.
+    syn region dtdError contained start=+<!+lc=2 end=+>+
+endif
+
+" if this is a html like comment hightlight also
+" the opening <! and the closing > as Comment.
+syn region dtdComment		start=+<![ \t]*--+ end=+-->+ contains=dtdTodo,@Spell
+
+
+" proper DTD comment
+syn region dtdComment contained start=+--+ end=+--+ contains=dtdTodo,@Spell
+
+
+" Start tags (keywords). This is contained in dtdFunction.
+" Note that everything not contained here will be marked
+" as error.
+syn match dtdTagName contained +<!\(ATTLIST\|DOCTYPE\|ELEMENT\|ENTITY\|NOTATION\|SHORTREF\|USEMAP\|\[\)+lc=2,hs=s+2
+
+
+" wildcards and operators
+syn match  dtdCard contained "|"
+syn match  dtdCard contained ","
+" evenutally overridden by dtdEntity
+syn match  dtdCard contained "&"
+syn match  dtdCard contained "?"
+syn match  dtdCard contained "\*"
+syn match  dtdCard contained "+"
+
+" ...and finally, special cases.
+syn match  dtdCard      "ANY"
+syn match  dtdCard      "EMPTY"
+
+if !exists("dtd_no_param_entities")
+
+    " highlight parameter entity declarations
+    " and instances. Note that the closing `;'
+    " is optional.
+
+    " instances
+    syn region dtdParamEntityInst oneline matchgroup=dtdParamEntityPunct
+	\ start="%[-_a-zA-Z0-9.]\+"he=s+1,rs=s+1
+	\ skip=+[-_a-zA-Z0-9.]+
+	\ end=";\|\>"
+	\ matchgroup=NONE contains=dtdParamEntityPunct
+    syn match  dtdParamEntityPunct contained "\."
+
+    " declarations
+    " syn region dtdParamEntityDecl oneline matchgroup=dtdParamEntityDPunct start=+<!ENTITY % +lc=8 skip=+[-_a-zA-Z0-9.]+ matchgroup=NONE end="\>" contains=dtdParamEntityDPunct
+    syn match dtdParamEntityDecl +<!ENTITY % [-_a-zA-Z0-9.]*+lc=8 contains=dtdParamEntityDPunct
+    syn match  dtdParamEntityDPunct contained "%\|\."
+
+endif
+
+" &entities; compare with xml
+syn match   dtdEntity		      "&[^; \t]*;" contains=dtdEntityPunct
+syn match   dtdEntityPunct  contained "[&.;]"
+
+" Strings are between quotes
+syn region dtdString    start=+"+ skip=+\\\\\|\\"+  end=+"+ contains=dtdAttrDef,dtdAttrType,dtdEnum,dtdParamEntityInst,dtdEntity,dtdCard
+syn region dtdString    start=+'+ skip=+\\\\\|\\'+  end=+'+ contains=dtdAttrDef,dtdAttrType,dtdEnum,dtdParamEntityInst,dtdEntity,dtdCard
+
+" Enumeration of elements or data between parenthesis
+"
+" PROVIDES: @dtdEnumHook
+"
+syn region dtdEnum matchgroup=dtdType start="(" end=")" matchgroup=NONE contains=dtdEnum,dtdParamEntityInst,dtdCard,@dtdEnumHook
+
+"Attribute types
+syn keyword dtdAttrType NMTOKEN  ENTITIES  NMTOKENS  ID  CDATA
+syn keyword dtdAttrType IDREF  IDREFS
+" ENTITY has to treated special for not overriding <!ENTITY
+syn match   dtdAttrType +[^!]\<ENTITY+
+
+"Attribute Definitions
+syn match  dtdAttrDef   "#REQUIRED"
+syn match  dtdAttrDef   "#IMPLIED"
+syn match  dtdAttrDef   "#FIXED"
+
+syn case match
+" define some common keywords to mark TODO
+" and important sections inside comments.
+syn keyword dtdTodo contained TODO FIXME XXX
+
+syn sync lines=250
+
+" Define the default highlighting.
+" For version 5.7 and earlier: only when not done already
+" For version 5.8 and later: only when an item doesn't have highlighting yet
+if version >= 508 || !exists("did_dtd_syn_inits")
+    if version < 508
+	let did_dtd_syn_inits = 1
+	command -nargs=+ HiLink hi link <args>
+    else
+	command -nargs=+ HiLink hi def link <args>
+    endif
+
+    " The default highlighting.
+    HiLink dtdFunction		Function
+    HiLink dtdTag		Normal
+    HiLink dtdType		Type
+    HiLink dtdAttrType		dtdType
+    HiLink dtdAttrDef		dtdType
+    HiLink dtdConstant		Constant
+    HiLink dtdString		dtdConstant
+    HiLink dtdEnum		dtdConstant
+    HiLink dtdCard		dtdFunction
+
+    HiLink dtdEntity		Statement
+    HiLink dtdEntityPunct	dtdType
+    HiLink dtdParamEntityInst	dtdConstant
+    HiLink dtdParamEntityPunct	dtdType
+    HiLink dtdParamEntityDecl	dtdType
+    HiLink dtdParamEntityDPunct dtdComment
+
+    HiLink dtdComment		Comment
+    HiLink dtdTagName		Statement
+    HiLink dtdError		Error
+    HiLink dtdTodo		Todo
+
+    delcommand HiLink
+endif
+
+if version < 600
+    let &cpo = __dtd_cpo_save__
+    unlet __dtd_cpo_save__
+else
+    let &cpo = s:dtd_cpo_save
+    unlet s:dtd_cpo_save
+endif
+
+let b:current_syntax = "dtd"
+
+" vim: ts=8
--- /dev/null
+++ b/lib/vimfiles/syntax/dtml.vim
@@ -1,0 +1,225 @@
+" DTML syntax file
+" Language:			Zope's Dynamic Template Markup Language
+" Maintainer:	    Jean Jordaan <jean@upfrontsystems.co.za> (njj)
+" Last change:	    2001 Sep 02
+
+" These are used with Claudio Fleiner's html.vim in the standard distribution.
+"
+" Still very hackish. The 'dtml attributes' and 'dtml methods' have been
+" hacked out of the Zope Quick Reference in case someone finds something
+" sensible to do with them. I certainly haven't.
+
+" For version 5.x: Clear all syntax items
+" For version 6.x: Quit when a syntax file was already loaded
+if version < 600
+  syntax clear
+elseif exists("b:current_syntax")
+  finish
+endif
+
+" First load the HTML syntax
+if version < 600
+  source <sfile>:p:h/html.vim
+else
+  runtime! syntax/html.vim
+endif
+
+syn case match
+
+" This doesn't have any effect.  Does it need to be moved to above/
+" if !exists("main_syntax")
+"   let main_syntax = 'dtml'
+" endif
+
+" dtml attributes
+syn keyword dtmlAttribute ac_inherited_permissions access_debug_info contained
+syn keyword dtmlAttribute acquiredRolesAreUsedBy all_meta_types assume_children AUTH_TYPE contained
+syn keyword dtmlAttribute AUTHENTICATED_USER AUTHENTICATION_PATH BASE0 batch-end-index batch-size contained
+syn keyword dtmlAttribute batch-start-index bobobase_modification_time boundary branches contained
+syn keyword dtmlAttribute branches_expr capitalize cb_dataItems cb_dataValid cb_isCopyable contained
+syn keyword dtmlAttribute cb_isMoveable changeClassId classDefinedAndInheritedPermissions contained
+syn keyword dtmlAttribute classDefinedPermissions classInheritedPermissions collapse-all column contained
+syn keyword dtmlAttribute connected connectionIsValid CONTENT_LENGTH CONTENT_TYPE cook cookies contained
+syn keyword dtmlAttribute COPY count- createInObjectManager da_has_single_argument dav__allprop contained
+syn keyword dtmlAttribute dav__init dav__propnames dav__propstat dav__validate default contained
+syn keyword dtmlAttribute delClassAttr DELETE Destination DestinationURL digits discard contained
+syn keyword dtmlAttribute disposition document_src e encode enter etc expand-all expr File contained
+syn keyword dtmlAttribute filtered_manage_options filtered_meta_types first- fmt footer form contained
+syn keyword dtmlAttribute GATEWAY_INTERFACE get_local_roles get_local_roles_for_userid contained
+syn keyword dtmlAttribute get_request_var_or_attr get_size get_size get_valid_userids getAttribute contained
+syn keyword dtmlAttribute getAttributeNode getAttributes getChildNodes getClassAttr getContentType contained
+syn keyword dtmlAttribute getData getDocType getDocumentElement getElementsByTagName getFirstChild contained
+syn keyword dtmlAttribute getImplementation getLastChild getLength getName getNextSibling contained
+syn keyword dtmlAttribute getNodeName getNodeType getNodeValue getOwnerDocument getParentNode contained
+syn keyword dtmlAttribute getPreviousSibling getProperty getPropertyType getSize getSize getSize contained
+syn keyword dtmlAttribute get_size getTagName getUser getUserName getUserNames getUsers contained
+syn keyword dtmlAttribute has_local_roles hasChildNodes hasProperty HEAD header hexdigits HTML contained
+syn keyword dtmlAttribute html_quote HTMLFile id index_html index_objects indexes contained
+syn keyword dtmlAttribute inheritedAttribute items last- leave leave_another leaves letters LOCK contained
+syn keyword dtmlAttribute locked_in_version lower lowercase mailfrom mailhost mailhost_list mailto contained
+syn keyword dtmlAttribute manage manage_ methods manage_access manage_acquiredPermissions contained
+syn keyword dtmlAttribute manage_addConferaTopic manage_addDocument manage_addDTMLDocument contained
+syn keyword dtmlAttribute manage_addDTMLMethod manage_addFile manage_addFolder manage_addImage contained
+syn keyword dtmlAttribute manage_addLocalRoles manage_addMailHost manage_addPermission contained
+syn keyword dtmlAttribute manage_addPrincipiaFactory manage_addProduct manage_addProperty contained
+syn keyword dtmlAttribute manage_addUserFolder manage_addZClass manage_addZGadflyConnection contained
+syn keyword dtmlAttribute manage_addZGadflyConnectionForm manage_advanced manage_afterAdd contained
+syn keyword dtmlAttribute manage_afterClone manage_beforeDelete manage_changePermissions contained
+syn keyword dtmlAttribute manage_changeProperties manage_clone manage_CopyContainerFirstItem contained
+syn keyword dtmlAttribute manage_copyObjects manage_cutObjects manage_defined_roles contained
+syn keyword dtmlAttribute manage_delLocalRoles manage_delObjects manage_delProperties contained
+syn keyword dtmlAttribute manage_distribute manage_edit manage_editedDialog manage_editProperties contained
+syn keyword dtmlAttribute manage_editRoles manage_exportObject manage_FTPget manage_FTPlist contained
+syn keyword dtmlAttribute manage_FTPstat manage_get_product_readme__ manage_getPermissionMapping contained
+syn keyword dtmlAttribute manage_haveProxy manage_help manage_importObject manage_listLocalRoles contained
+syn keyword dtmlAttribute manage_options manage_pasteObjects manage_permission contained
+syn keyword dtmlAttribute manage_propertiesForm manage_proxy manage_renameObject manage_role contained
+syn keyword dtmlAttribute manage_setLocalRoles manage_setPermissionMapping contained
+syn keyword dtmlAttribute manage_subclassableClassNames manage_test manage_testForm contained
+syn keyword dtmlAttribute manage_undo_transactions manage_upload manage_users manage_workspace contained
+syn keyword dtmlAttribute management_interface mapping math max- mean- median- meta_type min- contained
+syn keyword dtmlAttribute MKCOL modified_in_version MOVE multiple name navigate_filter new_version contained
+syn keyword dtmlAttribute newline_to_br next next-batches next-sequence next-sequence-end-index contained
+syn keyword dtmlAttribute next-sequence-size next-sequence-start-index no manage_access None contained
+syn keyword dtmlAttribute nonempty normalize nowrap null Object Manager objectIds objectItems contained
+syn keyword dtmlAttribute objectMap objectValues octdigits only optional OPTIONS orphan overlap contained
+syn keyword dtmlAttribute PARENTS PATH_INFO PATH_TRANSLATED permission_settings contained
+syn keyword dtmlAttribute permissionMappingPossibleValues permissionsOfRole pi port contained
+syn keyword dtmlAttribute possible_permissions previous previous-batches previous-sequence contained
+syn keyword dtmlAttribute previous-sequence-end-index previous-sequence-size contained
+syn keyword dtmlAttribute previous-sequence-start-index PrincipiaFind PrincipiaSearchSource contained
+syn keyword dtmlAttribute propdict propertyIds propertyItems propertyLabel propertyMap propertyMap contained
+syn keyword dtmlAttribute propertyValues PROPFIND PROPPATCH PUT query_day query_month QUERY_STRING contained
+syn keyword dtmlAttribute query_year quoted_input quoted_report raise_standardErrorMessage random contained
+syn keyword dtmlAttribute read read_raw REMOTE_ADDR REMOTE_HOST REMOTE_IDENT REMOTE_USER REQUEST contained
+syn keyword dtmlAttribute REQUESTED_METHOD required RESPONSE reverse rolesOfPermission save schema contained
+syn keyword dtmlAttribute SCRIPT_NAME sequence-end sequence-even sequence-index contained
+syn keyword dtmlAttribute sequence-index-var- sequence-item sequence-key sequence-Letter contained
+syn keyword dtmlAttribute sequence-letter sequence-number sequence-odd sequence-query contained
+syn keyword dtmlAttribute sequence-roman sequence-Roman sequence-start sequence-step-end-index contained
+syn keyword dtmlAttribute sequence-step-size sequence-step-start-index sequence-var- SERVER_NAME contained
+syn keyword dtmlAttribute SERVER_PORT SERVER_PROTOCOL SERVER_SOFTWARE setClassAttr setName single contained
+syn keyword dtmlAttribute size skip_unauthorized smtphost sort spacify sql_quote SQLConnectionIDs contained
+syn keyword dtmlAttribute standard-deviation- standard-deviation-n- standard_html_footer contained
+syn keyword dtmlAttribute standard_html_header start String string subject SubTemplate superValues contained
+syn keyword dtmlAttribute tabs_path_info tag test_url_ text_content this thousands_commas title contained
+syn keyword dtmlAttribute title_and_id title_or_id total- tpURL tpValues TRACE translate tree-c contained
+syn keyword dtmlAttribute tree-colspan tree-e tree-item-expanded tree-item-url tree-level contained
+syn keyword dtmlAttribute tree-root-url tree-s tree-state type undoable_transactions UNLOCK contained
+syn keyword dtmlAttribute update_data upper uppercase url url_quote URLn user_names contained
+syn keyword dtmlAttribute userdefined_roles valid_property_id valid_roles validate_roles contained
+syn keyword dtmlAttribute validClipData validRoles values variance- variance-n- view_image_or_file contained
+syn keyword dtmlAttribute where whitespace whrandom xml_namespace zclass_candidate_view_actions contained
+syn keyword dtmlAttribute ZClassBaseClassNames ziconImage ZopeFind ZQueryIds contained
+
+syn keyword dtmlMethod abs absolute_url ac_inherited_permissions aCommon contained
+syn keyword dtmlMethod aCommonZ acos acquiredRolesAreUsedBy aDay addPropertySheet aMonth AMPM contained
+syn keyword dtmlMethod ampm AMPMMinutes appendChild appendData appendHeader asin atan atan2 contained
+syn keyword dtmlMethod atof atoi betavariate capatilize capwords catalog_object ceil center contained
+syn keyword dtmlMethod choice chr cloneNode COPY cos cosh count createInObjectManager contained
+syn keyword dtmlMethod createSQLInput cunifvariate Date DateTime Day day dayOfYear dd default contained
+syn keyword dtmlMethod DELETE deleteData delPropertySheet divmod document_id document_title dow contained
+syn keyword dtmlMethod earliestTime enter equalTo exp expireCookie expovariate fabs fCommon contained
+syn keyword dtmlMethod fCommonZ filtered_manage_options filtered_meta_types find float floor contained
+syn keyword dtmlMethod fmod frexp gamma gauss get get_local_roles_for_userid get_size getattr contained
+syn keyword dtmlMethod getAttribute getAttributeNode getClassAttr getDomains contained
+syn keyword dtmlMethod getElementsByTagName getHeader getitem getNamedItem getobject contained
+syn keyword dtmlMethod getObjectsInfo getpath getProperty getRoles getStatus getUser contained
+syn keyword dtmlMethod getUserName greaterThan greaterThanEqualTo h_12 h_24 has_key contained
+syn keyword dtmlMethod has_permission has_role hasattr hasFeature hash hasProperty HEAD hex contained
+syn keyword dtmlMethod hour hypot index index_html inheritedAttribute insertBefore insertData contained
+syn keyword dtmlMethod int isCurrentDay isCurrentHour isCurrentMinute isCurrentMonth contained
+syn keyword dtmlMethod isCurrentYear isFuture isLeadYear isPast item join latestTime ldexp contained
+syn keyword dtmlMethod leave leave_another len lessThan lessThanEqualTo ljust log log10 contained
+syn keyword dtmlMethod lognormvariate lower lstrip maketrans manage manage_access contained
+syn keyword dtmlMethod manage_acquiredPermissions manage_addColumn manage_addDocument contained
+syn keyword dtmlMethod manage_addDTMLDocument manage_addDTMLMethod manage_addFile contained
+syn keyword dtmlMethod manage_addFolder manage_addImage manage_addIndex manage_addLocalRoles contained
+syn keyword dtmlMethod manage_addMailHost manage_addPermission manage_addPrincipiaFactory contained
+syn keyword dtmlMethod manage_addProduct manage_addProperty manage_addPropertySheet contained
+syn keyword dtmlMethod manage_addUserFolder manage_addZCatalog manage_addZClass contained
+syn keyword dtmlMethod manage_addZGadflyConnection manage_addZGadflyConnectionForm contained
+syn keyword dtmlMethod manage_advanced manage_catalogClear manage_catalogFoundItems contained
+syn keyword dtmlMethod manage_catalogObject manage_catalogReindex manage_changePermissions contained
+syn keyword dtmlMethod manage_changeProperties manage_clone manage_CopyContainerFirstItem contained
+syn keyword dtmlMethod manage_copyObjects manage_createEditor manage_createView contained
+syn keyword dtmlMethod manage_cutObjects manage_defined_roles manage_delColumns contained
+syn keyword dtmlMethod manage_delIndexes manage_delLocalRoles manage_delObjects contained
+syn keyword dtmlMethod manage_delProperties manage_Discard__draft__ manage_distribute contained
+syn keyword dtmlMethod manage_edit manage_edit manage_editedDialog manage_editProperties contained
+syn keyword dtmlMethod manage_editRoles manage_exportObject manage_importObject contained
+syn keyword dtmlMethod manage_makeChanges manage_pasteObjects manage_permission contained
+syn keyword dtmlMethod manage_propertiesForm manage_proxy manage_renameObject manage_role contained
+syn keyword dtmlMethod manage_Save__draft__ manage_setLocalRoles manage_setPermissionMapping contained
+syn keyword dtmlMethod manage_test manage_testForm manage_uncatalogObject contained
+syn keyword dtmlMethod manage_undo_transactions manage_upload manage_users manage_workspace contained
+syn keyword dtmlMethod mange_createWizard max min minute MKCOL mm modf month Month MOVE contained
+syn keyword dtmlMethod namespace new_version nextObject normalvariate notEqualTo objectIds contained
+syn keyword dtmlMethod objectItems objectValues oct OPTIONS ord paretovariate parts pCommon contained
+syn keyword dtmlMethod pCommonZ pDay permissionsOfRole pMonth pow PreciseAMPM PreciseTime contained
+syn keyword dtmlMethod previousObject propertyInfo propertyLabel PROPFIND PROPPATCH PUT quit contained
+syn keyword dtmlMethod raise_standardErrorMessage randint random read read_raw redirect contained
+syn keyword dtmlMethod removeAttribute removeAttributeNode removeChild replace replaceChild contained
+syn keyword dtmlMethod replaceData rfc822 rfind rindex rjust rolesOfPermission round rstrip contained
+syn keyword dtmlMethod save searchResults second seed set setAttribute setAttributeNode setBase contained
+syn keyword dtmlMethod setCookie setHeader setStatus sin sinh split splitText sqrt str strip contained
+syn keyword dtmlMethod substringData superValues swapcase tabs_path_info tan tanh Time contained
+syn keyword dtmlMethod TimeMinutes timeTime timezone title title_and_id title_or_id toXML contained
+syn keyword dtmlMethod toZone uncatalog_object undoable_transactions uniform uniqueValuesFor contained
+syn keyword dtmlMethod update_data upper valid_property_id validate_roles vonmisesvariate contained
+syn keyword dtmlMethod weibullvariate year yy zfill ZopeFind contained
+
+" DTML tags
+syn keyword dtmlTagName var if elif else unless in with let call raise try except tag comment tree sqlvar sqltest sqlgroup sendmail mime transparent contained
+
+syn keyword dtmlEndTagName if unless in with let raise try tree sendmail transparent contained
+
+" Own additions
+syn keyword dtmlTODO    TODO FIXME		contained
+
+syn region dtmlComment start=+<dtml-comment>+ end=+</dtml-comment>+ contains=dtmlTODO
+
+" All dtmlTagNames are contained by dtmlIsTag.
+syn match dtmlIsTag	    "dtml-[A-Za-z]\+"    contains=dtmlTagName
+
+" 'var' tag entity syntax: &dtml-variableName;
+"       - with attributes: &dtml.attribute1[.attribute2]...-variableName;
+syn match dtmlSpecialChar "&dtml[.0-9A-Za-z_]\{-}-[0-9A-Za-z_.]\+;"
+
+" Redefine to allow inclusion of DTML within HTML strings.
+syn cluster htmlTop contains=@Spell,htmlTag,htmlEndTag,dtmlSpecialChar,htmlSpecialChar,htmlPreProc,htmlComment,htmlLink,javaScript,@htmlPreproc
+syn region htmlLink start="<a\>[^>]*href\>" end="</a>"me=e-4 contains=@Spell,htmlTag,htmlEndTag,dtmlSpecialChar,htmlSpecialChar,htmlPreProc,htmlComment,javaScript,@htmlPreproc
+syn region htmlHead start="<head\>" end="</head>"me=e-7 end="<body\>"me=e-5 end="<h[1-6]\>"me=e-3 contains=htmlTag,htmlEndTag,dtmlSpecialChar,htmlSpecialChar,htmlPreProc,htmlComment,htmlLink,htmlTitle,javaScript,cssStyle,@htmlPreproc
+syn region htmlTitle start="<title\>" end="</title>"me=e-8 contains=htmlTag,htmlEndTag,dtmlSpecialChar,htmlSpecialChar,htmlPreProc,htmlComment,javaScript,@htmlPreproc
+syn region  htmlString   contained start=+"+ end=+"+ contains=dtmlSpecialChar,htmlSpecialChar,javaScriptExpression,dtmlIsTag,dtmlAttribute,dtmlMethod,@htmlPreproc
+syn match   htmlTagN     contained +<\s*[-a-zA-Z0-9]\++hs=s+1 contains=htmlTagName,htmlSpecialTagName,dtmlIsTag,dtmlAttribute,dtmlMethod,@htmlTagNameCluster
+syn match   htmlTagN     contained +</\s*[-a-zA-Z0-9]\++hs=s+2 contains=htmlTagName,htmlSpecialTagName,dtmlIsTag,dtmlAttribute,dtmlMethod,@htmlTagNameCluster
+
+" Define the default highlighting.
+" For version 5.7 and earlier: only when not done already
+" For version 5.8 and later: only when an item doesn't have highlighting yet
+if version >= 508 || !exists("did_dtml_syntax_inits")
+  if version < 508
+    let did_dtml_syntax_inits = 1
+    command -nargs=+ HiLink hi link <args>
+  else
+    command -nargs=+ HiLink hi def link <args>
+  endif
+
+  HiLink dtmlIsTag			PreProc
+  HiLink dtmlAttribute		Identifier
+  HiLink dtmlMethod			Function
+  HiLink dtmlComment		Comment
+  HiLink dtmlTODO			Todo
+  HiLink dtmlSpecialChar    Special
+
+  delcommand HiLink
+endif
+
+let b:current_syntax = "dtml"
+
+" if main_syntax == 'dtml'
+"   unlet main_syntax
+" endif
+
+" vim: ts=4
--- /dev/null
+++ b/lib/vimfiles/syntax/dylan.vim
@@ -1,0 +1,109 @@
+" Vim syntax file
+" Language:	Dylan
+" Authors:	Justus Pendleton <justus@acm.org>
+"		Brent A. Fulgham <bfulgham@debian.org>
+" Last Change:	Fri Sep 29 13:45:55 PDT 2000
+"
+" This syntax file is based on the Haskell, Perl, Scheme, and C
+" syntax files.
+
+" Part 1:  Syntax definition
+" For version 5.x: Clear all syntax items
+" For version 6.x: Quit when a syntax file was already loaded
+if version < 600
+  syntax clear
+elseif exists("b:current_syntax")
+  finish
+endif
+
+syn case ignore
+
+if version < 600
+  set lisp
+else
+  setlocal lisp
+endif
+
+" Highlight special characters (those that have backslashes) differently
+syn match	dylanSpecial		display contained "\\\(x\x\+\|\o\{1,3}\|.\|$\)"
+
+" Keywords
+syn keyword	dylanBlock		afterwards begin block cleanup end
+syn keyword	dylanClassMods		abstract concrete primary inherited virtual
+syn keyword	dylanException		exception handler signal
+syn keyword	dylanParamDefs		method class function library macro interface
+syn keyword	dylanSimpleDefs		constant variable generic primary
+syn keyword	dylanOther		above below from by in instance local slot subclass then to
+syn keyword	dylanConditional	if when select case else elseif unless finally otherwise then
+syn keyword	dylanRepeat		begin for until while from to
+syn keyword	dylanStatement		define let
+syn keyword	dylanImport		use import export exclude rename create
+syn keyword	dylanMiscMods		open sealed domain singleton sideways inline functional
+
+" Matching rules for special forms
+syn match	dylanOperator		"\s[-!%&\*\+/=\?@\\^|~:]\+[-#!>%&:\*\+/=\?@\\^|~]*"
+syn match	dylanOperator		"\(\<[A-Z][a-zA-Z0-9_']*\.\)\=:[-!#$%&\*\+./=\?@\\^|~:]*"
+" Numbers
+syn match	dylanNumber		"\<[0-9]\+\>\|\<0[xX][0-9a-fA-F]\+\>\|\<0[oO][0-7]\+\>"
+syn match	dylanNumber		"\<[0-9]\+\.[0-9]\+\([eE][-+]\=[0-9]\+\)\=\>"
+" Booleans
+syn match	dylanBoolean		"#t\|#f"
+" Comments
+syn match	dylanComment		"//.*"
+syn region	dylanComment		start="/\*" end="\*/"
+" Strings
+syn region	dylanString		start=+"+ skip=+\\\\\|\\"+ end=+"+ contains=dySpecial
+syn match	dylanCharacter		"'[^\\]'"
+" Constants, classes, and variables
+syn match	dylanConstant		"$\<[a-zA-Z0-9\-]\+\>"
+syn match	dylanClass		"<\<[a-zA-Z0-9\-]\+\>>"
+syn match	dylanVariable		"\*\<[a-zA-Z0-9\-]\+\>\*"
+" Preconditions
+syn region	dylanPrecondit		start="^\s*#\s*\(if\>\|else\>\|endif\>\)" skip="\\$" end="$"
+
+" These appear at the top of files (usually).  I like to highlight the whole line
+" so that the definition stands out.  They should probably really be keywords, but they
+" don't generally appear in the middle of a line of code.
+syn region	dylanHeader	start="^[Mm]odule:" end="^$"
+
+" Define the default highlighting.
+" For version 5.7 and earlier: only when not done already
+" For version 5.8 and later: only when an item doesn't have highlighting yet
+if version >= 508 || !exists("did_dylan_syntax_inits")
+  if version < 508
+    let did_dylan_syntax_inits = 1
+    command -nargs=+ HiLink hi link <args>
+  else
+    command -nargs=+ HiLink hi def link <args>
+  endif
+
+  HiLink dylanBlock		PreProc
+  HiLink dylanBoolean		Boolean
+  HiLink dylanCharacter		Character
+  HiLink dylanClass		Structure
+  HiLink dylanClassMods		StorageClass
+  HiLink dylanComment		Comment
+  HiLink dylanConditional	Conditional
+  HiLink dylanConstant		Constant
+  HiLink dylanException		Exception
+  HiLink dylanHeader		Macro
+  HiLink dylanImport		Include
+  HiLink dylanLabel		Label
+  HiLink dylanMiscMods		StorageClass
+  HiLink dylanNumber		Number
+  HiLink dylanOther		Keyword
+  HiLink dylanOperator		Operator
+  HiLink dylanParamDefs		Keyword
+  HiLink dylanPrecondit		PreCondit
+  HiLink dylanRepeat		Repeat
+  HiLink dylanSimpleDefs	Keyword
+  HiLink dylanStatement		Macro
+  HiLink dylanString		String
+  HiLink dylanVariable		Identifier
+
+  delcommand HiLink
+endif
+
+let b:current_syntax = "dylan"
+
+" vim:ts=8
--- /dev/null
+++ b/lib/vimfiles/syntax/dylanintr.vim
@@ -1,0 +1,52 @@
+" Vim syntax file
+" Language:	Dylan
+" Authors:	Justus Pendleton <justus@acm.org>
+" Last Change:	Fri Sep 29 13:53:27 PDT 2000
+"
+
+" For version 5.x: Clear all syntax items
+" For version 6.x: Quit when a syntax file was already loaded
+if version < 600
+  syntax clear
+elseif exists("b:current_syntax")
+  finish
+endif
+
+syn case ignore
+
+syn region	dylanintrInfo		matchgroup=Statement start="^" end=":" oneline
+syn match	dylanintrInterface	"define interface"
+syn match	dylanintrClass		"<.*>"
+syn region	dylanintrType		start=+"+ skip=+\\\\\|\\"+ end=+"+
+
+syn region	dylanintrIncluded	contained start=+"+ skip=+\\\\\|\\"+ end=+"+
+syn match	dylanintrIncluded	contained "<[^>]*>"
+syn match	dylanintrInclude	"^\s*#\s*include\>\s*["<]" contains=intrIncluded
+
+"syn keyword intrMods pointer struct
+
+" Define the default highlighting.
+" For version 5.7 and earlier: only when not done already
+" For version 5.8 and later: only when an item doesn't have highlighting yet
+if version >= 508 || !exists("did_dylan_intr_syntax_inits")
+  if version < 508
+    let did_dylan_intr_syntax_inits = 1
+    command -nargs=+ HiLink hi link <args>
+  else
+    command -nargs=+ HiLink hi def link <args>
+  endif
+
+  HiLink dylanintrInfo		Special
+  HiLink dylanintrInterface	Operator
+  HiLink dylanintrMods		Type
+  HiLink dylanintrClass		StorageClass
+  HiLink dylanintrType		Type
+  HiLink dylanintrIncluded	String
+  HiLink dylanintrInclude	Include
+
+  delcommand HiLink
+endif
+
+let b:current_syntax = "dylanintr"
+
+" vim:ts=8
--- /dev/null
+++ b/lib/vimfiles/syntax/dylanlid.vim
@@ -1,0 +1,42 @@
+" Vim syntax file
+" Language:	Dylan Library Interface Files
+" Authors:	Justus Pendleton <justus@acm.org>
+"		Brent Fulgham <bfulgham@debian.org>
+" Last Change:	Fri Sep 29 13:50:20 PDT 2000
+"
+
+" For version 5.x: Clear all syntax items
+" For version 6.x: Quit when a syntax file was already loaded
+if version < 600
+  syntax clear
+elseif exists("b:current_syntax")
+  finish
+endif
+
+syn case ignore
+
+syn region	dylanlidInfo		matchgroup=Statement start="^" end=":" oneline
+syn region	dylanlidEntry		matchgroup=Statement start=":%" end="$" oneline
+
+syn sync	lines=50
+
+" Define the default highlighting.
+" For version 5.7 and earlier: only when not done already
+" For version 5.8 and later: only when an item doesn't have highlighting yet
+if version >= 508 || !exists("did_dylan_lid_syntax_inits")
+  if version < 508
+    let did_dylan_lid_syntax_inits = 1
+    command -nargs=+ HiLink hi link <args>
+  else
+    command -nargs=+ HiLink hi def link <args>
+  endif
+
+  HiLink dylanlidInfo		Type
+  HiLink dylanlidEntry		String
+
+  delcommand HiLink
+endif
+
+let b:current_syntax = "dylanlid"
+
+" vim:ts=8
--- /dev/null
+++ b/lib/vimfiles/syntax/ecd.vim
@@ -1,0 +1,56 @@
+" Vim syntax file
+" Language:	ecd (Embedix Component Description) files
+" Maintainer:	John Beppu <beppu@opensource.lineo.com>
+" URL:		http://opensource.lineo.com/~beppu/prose/ecd_vim.html
+" Last Change:	2001 Sep 27
+
+" An ECD file contains meta-data for packages in the Embedix Linux distro.
+" This syntax file was derived from apachestyle.vim
+" by Christian Hammers <ch@westend.com>
+
+" Quit when a syntax file was already loaded
+if version < 600
+  syntax clear
+elseif exists("b:current_syntax")
+  finish
+endif
+
+syn case ignore
+
+" specials
+syn match  ecdComment	"^\s*#.*"
+
+" options and values
+syn match  ecdAttr	"^\s*[a-zA-Z]\S*\s*[=].*$" contains=ecdAttrN,ecdAttrV
+syn match  ecdAttrN	contained "^.*="me=e-1
+syn match  ecdAttrV	contained "=.*$"ms=s+1
+
+" tags
+syn region ecdTag	start=+<+ end=+>+ contains=ecdTagN,ecdTagError
+syn match  ecdTagN	contained +<[/\s]*[-a-zA-Z0-9_]\++ms=s+1
+syn match  ecdTagError	contained "[^>]<"ms=s+1
+
+" Define the default highlighting.
+" For version 5.7 and earlier: only when not done already
+" For version 5.8 and later: only when an item doesn't have highlighting yet
+if version >= 508 || !exists("did_ecd_syn_inits")
+  if version < 508
+    let did_ecd_syn_inits = 1
+    command -nargs=+ HiLink hi link <args>
+  else
+    command -nargs=+ HiLink hi def link <args>
+  endif
+
+  HiLink ecdComment	Comment
+  HiLink ecdAttr	Type
+  HiLink ecdAttrN	Statement
+  HiLink ecdAttrV	Value
+  HiLink ecdTag		Function
+  HiLink ecdTagN	Statement
+  HiLink ecdTagError	Error
+
+  delcommand HiLink
+endif
+
+let b:current_syntax = "ecd"
+" vim: ts=8
--- /dev/null
+++ b/lib/vimfiles/syntax/edif.vim
@@ -1,0 +1,64 @@
+" Vim syntax file
+" Language:     EDIF (Electronic Design Interchange Format)
+" Maintainer:   Artem Zankovich <z_artem@hotbox.ru>
+" Last Change:  Oct 14, 2002
+"
+" Supported standarts are:
+"   ANSI/EIA Standard 548-1988 (EDIF Version 2 0 0)
+"   IEC 61690-1 (EDIF Version 3 0 0)
+"   IEC 61690-2 (EDIF Version 4 0 0)
+
+" Quit when a syntax file was already loaded
+if version < 600
+  syntax clear
+elseif exists("b:current_syntax")
+  finish
+endif
+
+if version >= 600
+ setlocal iskeyword=48-57,-,+,A-Z,a-z,_,&
+else
+ set iskeyword=A-Z,a-z,_,&
+endif
+
+syn region	edifList	matchgroup=Delimiter start="(" end=")" contains=edifList,edifKeyword,edifString,edifNumber
+
+" Strings
+syn match       edifInStringError    /%/ contained
+syn match       edifInString    /%\s*\d\+\s*%/ contained
+syn region      edifString      start=/"/ end=/"/ contains=edifInString,edifInStringError contained
+
+" Numbers
+syn match       edifNumber      "\<[-+]\=[0-9]\+\>"
+
+" Keywords
+syn match       edifKeyword     "(\@<=\s*[a-zA-Z&][a-zA-Z_0-9]*\>" contained
+
+syn match       edifError       ")"
+
+" synchronization
+if version < 600
+  syntax sync maxlines=250
+else
+  syntax sync fromstart
+endif
+
+" Define the default highlighting.
+if version >= 508 || !exists("did_edif_syntax_inits")
+  if version < 508
+    let did_edif_syntax_inits = 1
+    command -nargs=+ HiLink hi link <args>
+  else
+    command -nargs=+ HiLink hi def link <args>
+  endif
+
+  HiLink edifInString		SpecialChar
+  HiLink edifKeyword		Keyword
+  HiLink edifNumber		Number
+  HiLink edifInStringError	edifError
+  HiLink edifError		Error
+  HiLink edifString		String
+  delcommand HiLink
+endif
+
+let b:current_syntax = "edif"
--- /dev/null
+++ b/lib/vimfiles/syntax/eiffel.vim
@@ -1,0 +1,196 @@
+" Eiffel syntax file
+" Language:	Eiffel
+" Maintainer:	Reimer Behrends <behrends@cse.msu.edu>
+"		With much input from Jocelyn Fiat <fiat@eiffel.com>
+" See http://www.cse.msu.edu/~behrends/vim/ for the most current version.
+" Last Change:	2001 May 09
+
+" For version 5.x: Clear all syntax items
+" For version 6.x: Quit when a syntax file was already loaded
+if version < 600
+  syntax clear
+elseif exists("b:current_syntax")
+  finish
+endif
+
+" Option handling
+
+if exists("eiffel_ignore_case")
+  syn case ignore
+else
+  syn case match
+  if exists("eiffel_pedantic") || exists("eiffel_strict")
+    syn keyword eiffelError	current void result precursor none
+    syn keyword eiffelError	CURRENT VOID RESULT PRECURSOR None
+    syn keyword eiffelError	TRUE FALSE
+  endif
+  if exists("eiffel_pedantic")
+    syn keyword eiffelError	true false
+    syn match eiffelError	"\<[a-z_]\+[A-Z][a-zA_Z_]*\>"
+    syn match eiffelError	"\<[A-Z][a-z_]*[A-Z][a-zA-Z_]*\>"
+  endif
+  if exists("eiffel_lower_case_predef")
+    syn keyword eiffelPredefined current void result precursor
+  endif
+endif
+
+if exists("eiffel_hex_constants")
+  syn match  eiffelNumber	"\d[0-9a-fA-F]*[xX]"
+endif
+
+" Keyword definitions
+
+syn keyword eiffelTopStruct	indexing feature creation inherit
+syn match   eiffelTopStruct	"\<class\>"
+syn match   eiffelKeyword	"\<end\>"
+syn match   eiffelTopStruct	"^end\>\(\s*--\s\+class\s\+\<[A-Z][A-Z0-9_]*\>\)\=" contains=eiffelClassName
+syn match   eiffelBrackets	"[[\]]"
+syn match eiffelBracketError	"\]"
+syn region eiffelGeneric	transparent matchgroup=eiffelBrackets start="\[" end="\]" contains=ALLBUT,eiffelBracketError,eiffelGenericDecl,eiffelStringError,eiffelStringEscape,eiffelGenericCreate,eiffelTopStruct
+if exists("eiffel_ise")
+  syn match   eiffelCreate	"\<create\>"
+  syn match   eiffelTopStruct	contained "\<create\>"
+  syn match   eiffelGenericCreate  contained "\<create\>"
+  syn match   eiffelTopStruct	"^create\>"
+  syn region  eiffelGenericDecl	transparent matchgroup=eiffelBrackets contained start="\[" end="\]" contains=ALLBUT,eiffelCreate,eiffelTopStruct,eiffelGeneric,eiffelBracketError,eiffelStringEscape,eiffelStringError,eiffelBrackets
+  syn region  eiffelClassHeader	start="^class\>" end="$" contains=ALLBUT,eiffelCreate,eiffelGenericCreate,eiffelGeneric,eiffelStringEscape,eiffelStringError,eiffelBrackets
+endif
+syn keyword eiffelDeclaration	is do once deferred unique local
+syn keyword eiffelDeclaration	Unique
+syn keyword eiffelProperty	expanded obsolete separate frozen
+syn keyword eiffelProperty	prefix infix
+syn keyword eiffelInheritClause	rename redefine undefine select export as
+syn keyword eiffelAll		all
+syn keyword eiffelKeyword	external alias
+syn keyword eiffelStatement	if else elseif inspect
+syn keyword eiffelStatement	when then
+syn match   eiffelAssertion	"\<require\(\s\+else\)\=\>"
+syn match   eiffelAssertion	"\<ensure\(\s\+then\)\=\>"
+syn keyword eiffelAssertion	check
+syn keyword eiffelDebug		debug
+syn keyword eiffelStatement	from until loop
+syn keyword eiffelAssertion	variant
+syn match   eiffelAssertion	"\<invariant\>"
+syn match   eiffelTopStruct	"^invariant\>"
+syn keyword eiffelException	rescue retry
+
+syn keyword eiffelPredefined	Current Void Result Precursor
+
+" Operators
+syn match   eiffelOperator	"\<and\(\s\+then\)\=\>"
+syn match   eiffelOperator	"\<or\(\s\+else\)\=\>"
+syn keyword eiffelOperator	xor implies not
+syn keyword eiffelOperator	strip old
+syn keyword eiffelOperator	Strip
+syn match   eiffelOperator	"\$"
+syn match   eiffelCreation	"!"
+syn match   eiffelExport	"[{}]"
+syn match   eiffelArray		"<<"
+syn match   eiffelArray		">>"
+syn match   eiffelConstraint	"->"
+syn match   eiffelOperator	"[@#|&][^ \e\t\b%]*"
+
+" Special classes
+syn keyword eiffelAnchored	like
+syn keyword eiffelBitType	BIT
+
+" Constants
+if !exists("eiffel_pedantic")
+  syn keyword eiffelBool	true false
+endif
+syn keyword eiffelBool		True False
+syn region  eiffelString	start=+"+ skip=+%"+ end=+"+ contains=eiffelStringEscape,eiffelStringError
+syn match   eiffelStringEscape	contained "%[^/]"
+syn match   eiffelStringEscape	contained "%/\d\+/"
+syn match   eiffelStringEscape	contained "^[ \t]*%"
+syn match   eiffelStringEscape	contained "%[ \t]*$"
+syn match   eiffelStringError	contained "%/[^0-9]"
+syn match   eiffelStringError	contained "%/\d\+[^0-9/]"
+syn match   eiffelBadConstant	"'\(%[^/]\|%/\d\+/\|[^'%]\)\+'"
+syn match   eiffelBadConstant	"''"
+syn match   eiffelCharacter	"'\(%[^/]\|%/\d\+/\|[^'%]\)'" contains=eiffelStringEscape
+syn match   eiffelNumber	"-\=\<\d\+\(_\d\+\)*\>"
+syn match   eiffelNumber	"\<[01]\+[bB]\>"
+syn match   eiffelNumber	"-\=\<\d\+\(_\d\+\)*\.\(\d\+\(_\d\+\)*\)\=\([eE][-+]\=\d\+\(_\d\+\)*\)\="
+syn match   eiffelNumber	"-\=\.\d\+\(_\d\+\)*\([eE][-+]\=\d\+\(_\d\+\)*\)\="
+syn match   eiffelComment	"--.*" contains=eiffelTodo
+
+syn case match
+
+" Case sensitive stuff
+
+syn keyword eiffelTodo		contained TODO XXX FIXME
+syn match   eiffelClassName	"\<[A-Z][A-Z0-9_]*\>"
+
+" Catch mismatched parentheses
+syn match eiffelParenError	")"
+syn region eiffelParen		transparent start="(" end=")" contains=ALLBUT,eiffelParenError,eiffelStringError,eiffelStringEscape
+
+" Should suffice for even very long strings and expressions
+syn sync lines=40
+
+" Define the default highlighting.
+" For version 5.7 and earlier: only when not done already
+" For version 5.8 and later: only when an item doesn't have highlighting yet
+if version >= 508 || !exists("did_eiffel_syntax_inits")
+  if version < 508
+    let did_eiffel_syntax_inits = 1
+    command -nargs=+ HiLink hi link <args>
+  else
+    command -nargs=+ HiLink hi def link <args>
+  endif
+
+  HiLink eiffelKeyword		Statement
+  HiLink eiffelProperty		Statement
+  HiLink eiffelInheritClause	Statement
+  HiLink eiffelStatement	Statement
+  HiLink eiffelDeclaration	Statement
+  HiLink eiffelAssertion	Statement
+  HiLink eiffelDebug		Statement
+  HiLink eiffelException	Statement
+  HiLink eiffelGenericCreate	Statement
+
+
+  HiLink eiffelTopStruct	PreProc
+
+  HiLink eiffelAll		Special
+  HiLink eiffelAnchored		Special
+  HiLink eiffelBitType		Special
+
+
+  HiLink eiffelBool		Boolean
+  HiLink eiffelString		String
+  HiLink eiffelCharacter	Character
+  HiLink eiffelClassName	Type
+  HiLink eiffelNumber		Number
+
+  HiLink eiffelStringEscape	Special
+
+  HiLink eiffelOperator		Special
+  HiLink eiffelArray		Special
+  HiLink eiffelExport		Special
+  HiLink eiffelCreation		Special
+  HiLink eiffelBrackets		Special
+  HiLink eiffelGeneric		Special
+  HiLink eiffelGenericDecl	Special
+  HiLink eiffelConstraint	Special
+  HiLink eiffelCreate		Special
+
+  HiLink eiffelPredefined	Constant
+
+  HiLink eiffelComment		Comment
+
+  HiLink eiffelError		Error
+  HiLink eiffelBadConstant	Error
+  HiLink eiffelStringError	Error
+  HiLink eiffelParenError	Error
+  HiLink eiffelBracketError	Error
+
+  HiLink eiffelTodo		Todo
+
+  delcommand HiLink
+endif
+
+let b:current_syntax = "eiffel"
+
+" vim: ts=8
--- /dev/null
+++ b/lib/vimfiles/syntax/elf.vim
@@ -1,0 +1,95 @@
+" Vim syntax file
+" Language:    ELF
+" Maintainer:  Christian V. J. Br�ssow <cvjb@cvjb.de>
+" Last Change: Son 22 Jun 2003 20:43:14 CEST
+" Filenames:   *.ab,*.am
+" URL:	       http://www.cvjb.de/comp/vim/elf.vim
+" $Id: elf.vim,v 1.1 2004/06/13 19:52:27 vimboss Exp $
+"
+" ELF: Extensible Language Facility
+"      This is the Applix Inc., Macro and Builder programming language.
+"      It has nothing in common with the binary format called ELF.
+
+" For version 5.x: Clear all syntax items
+" For version 6.x: Quit when a syntax file was already loaded
+if version < 600
+	syntax clear
+elseif exists("b:current_syntax")
+	finish
+endif
+
+" Case does not matter
+syn case ignore
+
+" Environments
+syn region elfEnvironment transparent matchgroup=Special start="{" matchgroup=Special end="}" contains=ALLBUT,elfBraceError
+
+" Unmatched braces
+syn match elfBraceError "}"
+
+" All macros must have at least one of these definitions
+syn keyword elfSpecial endmacro
+syn region elfSpecial transparent matchgroup=Special start="^\(\(macro\)\|\(set\)\) \S\+$" matchgroup=Special end="^\(\(endmacro\)\|\(endset\)\)$" contains=ALLBUT,elfBraceError
+
+" Preprocessor Commands
+syn keyword elfPPCom define include
+
+" Some keywords
+syn keyword elfKeyword  false true null
+syn keyword elfKeyword	var format object function endfunction
+
+" Conditionals and loops
+syn keyword elfConditional if else case of endcase for to next while until return goto
+
+" All built-in elf macros end with an '@'
+syn match elfMacro "[0-9_A-Za-z]\+@"
+
+" Strings and characters
+syn region elfString start=+"+  skip=+\\\\\|\\"+  end=+"+
+
+" Numbers
+syn match elfNumber "-\=\<[0-9]*\.\=[0-9_]\>"
+
+" Comments
+syn region elfComment start="/\*"  end="\*/"
+syn match elfComment  "\'.*$"
+
+syn sync ccomment elfComment
+
+" Parenthesis
+syn match elfParens "[\[\]()]"
+
+" Punctuation
+syn match elfPunct "[,;]"
+
+" Define the default highlighting.
+" For version 5.7 and earlier: only when not done already
+" For version 5.8 and later: only when an item doesn't have highlighting yet
+if version >= 508 || !exists("did_elf_syn_inits")
+	if version < 508
+		let did_elf_syn_inits = 1
+		command -nargs=+ HiLink hi link <args>
+	else
+		command -nargs=+ HiLink hi def link <args>
+   endif
+
+  " The default methods for highlighting. Can be overridden later.
+  HiLink elfComment Comment
+  HiLink elfPPCom Include
+  HiLink elfKeyword Keyword
+  HiLink elfSpecial Special
+  HiLink elfEnvironment Special
+  HiLink elfBraceError Error
+  HiLink elfConditional Conditional
+  HiLink elfMacro Function
+  HiLink elfNumber Number
+  HiLink elfString String
+  HiLink elfParens Delimiter
+  HiLink elfPunct Delimiter
+
+  delcommand HiLink
+endif
+
+let b:current_syntax = "elf"
+
+" vim:ts=8:sw=4:nocindent:smartindent:
--- /dev/null
+++ b/lib/vimfiles/syntax/elinks.vim
@@ -1,0 +1,188 @@
+" Vim syntax file
+" Language:         elinks(1) configuration file
+" Maintainer:       Nikolai Weibull <now@bitwi.se>
+" Latest Revision:  2006-04-19
+
+if exists("b:current_syntax")
+  finish
+endif
+
+let s:cpo_save = &cpo
+set cpo&vim
+
+setlocal iskeyword=@,48-57,_,-
+
+syn keyword elinksTodo      contained TODO FIXME XXX NOTE
+
+syn region  elinksComment   display oneline start='#' end='$'
+                            \ contains=elinksTodo,@Spell
+
+syn match   elinksNumber    '\<\d\+\>'
+
+syn region  elinksString    start=+"+ skip=+\\\\\|\\"+ end=+"+
+                            \ contains=@elinksColor
+
+syn keyword elinksKeyword   set bind
+
+syn keyword elinksPrefix    bookmarks
+syn keyword elinksOptions   file_format
+
+syn keyword elinksPrefix    config
+syn keyword elinksOptions   comments indentation saving_style i18n
+                            \ saving_style_w show_template
+
+syn keyword elinksPrefix    connection ssl client_cert
+syn keyword elinksOptions   enable file cert_verify async_dns max_connections
+                            \ max_connections_to_host receive_timeout retries
+                            \ unrestartable_receive_timeout
+
+syn keyword elinksPrefix    cookies
+syn keyword elinksOptions   accept_policy max_age paranoid_security save resave
+
+syn keyword elinksPrefix    document browse accesskey forms images links
+syn keyword elinksPrefix    active_link colors search cache codepage colors
+syn keyword elinksPrefix    format memory download dump history global html
+syn keyword elinksPrefix    plain
+syn keyword elinksOptions   auto_follow priority auto_submit confirm_submit
+                            \ input_size show_formhist file_tags
+                            \ image_link_tagging image_link_prefix
+                            \ image_link_suffix show_as_links
+                            \ show_any_as_links background text enable_color
+                            \ bold invert underline color_dirs numbering
+                            \ use_tabindex number_keys_select_link
+                            \ wraparound case regex show_hit_top_bottom
+                            \ wraparound show_not_found margin_width refresh
+                            \ minimum_refresh_time scroll_margin scroll_step
+                            \ table_move_order size size cache_redirects
+                            \ ignore_cache_control assume force_assumed text
+                            \ background link vlink dirs allow_dark_on_black
+                            \ ensure_contrast use_document_colors directory
+                            \ set_original_time overwrite notify_bell
+                            \ codepage width enable max_items display_type
+                            \ write_interval keep_unhistory display_frames
+                            \ display_tables expand_table_columns display_subs
+                            \ display_sups link_display underline_links
+                            \ wrap_nbsp display_links compress_empty_lines
+
+syn keyword elinksPrefix    mime extension handler mailcap mimetypes type
+syn keyword elinksOptions   ask block program enable path ask description
+                            \ prioritize enable path default_type
+
+syn keyword elinksPrefix    protocol file cgi ftp proxy http bugs proxy
+syn keyword elinksPrefix    referer https proxy rewrite dumb smart
+syn keyword elinksOptions   path policy allow_special_files show_hidden_files
+                            \ try_encoding_extensions host anon_passwd
+                            \ use_pasv use_epsv accept_charset allow_blacklist
+                            \ broken_302_redirect post_no_keepalive http10
+                            \ host user passwd policy fake accept_language
+                            \ accept_ui_language trace user_agent host
+                            \ enable-dumb enable-smart
+
+syn keyword elinksPrefix    terminal
+syn keyword elinksOptions   type m11_hack utf_8_io restrict_852 block_cursor
+                            \ colors transparency underline charset
+
+syn keyword elinksPrefix    ui colors color mainmenu normal selected hotkey
+                            \ menu marked hotkey frame dialog generic
+                            \ frame scrollbar scrollbar-selected title text
+                            \ checkbox checkbox-label button button-selected
+                            \ field field-text meter shadow title title-bar
+                            \ title-text status status-bar status-text tabs
+                            \ unvisited normal loading separator searched mono
+syn keyword elinksOptions   text background
+
+syn keyword elinksPrefix    ui dialogs leds sessions tabs timer
+syn keyword elinksOptions   listbox_min_height shadows underline_hotkeys enable
+                            \ auto_save auto_restore auto_save_foldername
+                            \ homepage show_bar wraparound confirm_close
+                            \ enable duration action language show_status_bar
+                            \ show_title_bar startup_goto_dialog
+                            \ success_msgbox window_title
+
+syn keyword elinksOptions   secure_file_saving
+
+syn cluster elinksColor     contains=elinksColorBlack,elinksColorDarkRed,
+                            \ elinksColorDarkGreen,elinksColorDarkYellow,
+                            \ elinksColorDarkBlue,elinksColorDarkMagenta,
+                            \ elinksColorDarkCyan,elinksColorGray,
+                            \ elinksColorDarkGray,elinksColorRed,
+                            \ elinksColorGreen,elinksColorYellow,
+                            \ elinksColorBlue,elinksColorMagenta,
+                            \ elinksColorCyan,elinksColorWhite
+
+syn keyword elinksColorBlack        contained black
+syn keyword elinksColorDarkRed      contained darkred sandybrown maroon crimson
+                                    \ firebrick
+syn keyword elinksColorDarkGreen    contained darkgreen darkolivegreen
+                                    \ darkseagreen forestgreen
+                                    \ mediumspringgreen seagreen
+syn keyword elinksColorDarkYellow   contained brown blanchedalmond chocolate
+                                    \ darkorange darkgoldenrod orange rosybrown
+                                    \ saddlebrown peru olive olivedrab sienna
+syn keyword elinksColorDarkBlue     contained darkblue cadetblue cornflowerblue
+                                    \ darkslateblue deepskyblue midnightblue
+                                    \ royalblue steelblue navy
+syn keyword elinksColorDarkMagenta  contained darkmagenta mediumorchid
+                                    \ mediumpurple mediumslateblue slateblue
+                                    \ deeppink hotpink darkorchid orchid purple
+                                    \ indigo
+syn keyword elinksColorDarkCyan     contained darkcyan mediumaquamarine
+                                    \ mediumturquoise darkturquoise teal
+syn keyword elinksColorGray         contained silver dimgray lightslategray
+                                    \ slategray lightgrey burlywood plum tan
+                                    \ thistle
+syn keyword elinksColorDarkGray     contained gray darkgray darkslategray
+                                    \ darksalmon
+syn keyword elinksColorRed          contained red indianred orangered tomato
+                                    \ lightsalmon salmon coral lightcoral
+syn keyword elinksColorGreen        contained green greenyellow lawngreen
+                                    \ lightgreen lightseagreen limegreen
+                                    \ mediumseagreen springgreen yellowgreen
+                                    \ palegreen lime chartreuse
+syn keyword elinksColorYellow       contained yellow beige darkkhaki
+                                    \ lightgoldenrodyellow palegoldenrod gold
+                                    \ goldenrod khaki lightyellow
+syn keyword elinksColorBlue         contained blue aliceblue aqua aquamarine
+                                    \ azure dodgerblue lightblue lightskyblue
+                                    \ lightsteelblue mediumblue
+syn keyword elinksColorMagenta      contained magenta darkviolet blueviolet
+                                    \ lightpink mediumvioletred palevioletred
+                                    \ violet pink fuchsia
+syn keyword elinksColorCyan         contained cyan lightcyan powderblue skyblue
+                                    \ turquoise paleturquoise
+syn keyword elinksColorWhite        contained white antiquewhite floralwhite
+                                    \ ghostwhite navajowhite whitesmoke linen
+                                    \ lemonchiffon cornsilk lavender
+                                    \ lavenderblush seashell mistyrose ivory
+                                    \ papayawhip bisque gainsboro honeydew
+                                    \ mintcream moccasin oldlace peachpuff snow
+                                    \ wheat
+
+hi def link elinksTodo              Todo
+hi def link elinksComment           Comment
+hi def link elinksNumber            Number
+hi def link elinksString            String
+hi def link elinksKeyword           Keyword
+hi def link elinksPrefix            Identifier
+hi def link elinksOptions           Identifier
+hi def      elinksColorBlack        ctermfg=Black       guifg=Black
+hi def      elinksColorDarkRed      ctermfg=DarkRed     guifg=DarkRed
+hi def      elinksColorDarkGreen    ctermfg=DarkGreen   guifg=DarkGreen
+hi def      elinksColorDarkYellow   ctermfg=DarkYellow  guifg=DarkYellow
+hi def      elinksColorDarkBlue     ctermfg=DarkBlue    guifg=DarkBlue
+hi def      elinksColorDarkMagenta  ctermfg=DarkMagenta guifg=DarkMagenta
+hi def      elinksColorDarkCyan     ctermfg=DarkCyan    guifg=DarkCyan
+hi def      elinksColorGray         ctermfg=Gray        guifg=Gray
+hi def      elinksColorDarkGray     ctermfg=DarkGray    guifg=DarkGray
+hi def      elinksColorRed          ctermfg=Red         guifg=Red
+hi def      elinksColorGreen        ctermfg=Green       guifg=Green
+hi def      elinksColorYellow       ctermfg=Yellow      guifg=Yellow
+hi def      elinksColorBlue         ctermfg=Blue        guifg=Blue
+hi def      elinksColorMagenta      ctermfg=Magenta     guifg=Magenta
+hi def      elinksColorCyan         ctermfg=Cyan        guifg=Cyan
+hi def      elinksColorWhite        ctermfg=White       guifg=White
+
+let b:current_syntax = "elinks"
+
+let &cpo = s:cpo_save
+unlet s:cpo_save
--- /dev/null
+++ b/lib/vimfiles/syntax/elmfilt.vim
@@ -1,0 +1,70 @@
+" Vim syntax file
+" Language:	Elm Filter rules
+" Maintainer:	Dr. Charles E. Campbell, Jr. <NdrOchipS@PcampbellAfamily.Mbiz>
+" Last Change:	Sep 11, 2006
+" Version:	5
+" URL:	http://mysite.verizon.net/astronaut/vim/index.html#vimlinks_syntax
+
+" For version 5.x: Clear all syntax items
+" For version 6.x: Quit when a syntax file was already loaded
+if version < 600
+  syntax clear
+elseif exists("b:current_syntax")
+  finish
+endif
+
+syn cluster elmfiltIfGroup	contains=elmfiltCond,elmfiltOper,elmfiltOperKey,,elmfiltNumber,elmfiltOperKey
+
+syn match	elmfiltParenError	"[()]"
+syn match	elmfiltMatchError	"/"
+syn region	elmfiltIf	start="\<if\>" end="\<then\>"	contains=elmfiltParen,elmfiltParenError skipnl skipwhite nextgroup=elmfiltAction
+syn region	elmfiltParen	contained	matchgroup=Delimiter start="(" matchgroup=Delimiter end=")"	contains=elmfiltParen,@elmfiltIfGroup,elmfiltThenError
+syn region	elmfiltMatch	contained	matchgroup=Delimiter start="/" skip="\\/" matchgroup=Delimiter end="/"	skipnl skipwhite nextgroup=elmfiltOper,elmfiltOperKey
+syn match	elmfiltThenError	"\<then.*$"
+syn match	elmfiltComment	"^#.*$"		contains=@Spell
+
+syn keyword	elmfiltAction	contained	delete execute executec forward forwardc leave save savecopy skipnl skipwhite nextgroup=elmfiltString
+syn match	elmfiltArg	contained	"[^\\]%[&0-9dDhmrsSty&]"lc=1
+
+syn match	elmfiltOperKey	contained	"\<contains\>"			skipnl skipwhite nextgroup=elmfiltString
+syn match	elmfiltOperKey	contained	"\<matches\s"			nextgroup=elmfiltMatch,elmfiltSpaceError
+syn keyword	elmfiltCond	contained	cc bcc lines always subject sender from to lines received	skipnl skipwhite nextgroup=elmfiltString
+syn match	elmfiltNumber	contained	"\d\+"
+syn keyword	elmfiltOperKey	contained	and not				skipnl skipwhite nextgroup=elmfiltOper,elmfiltOperKey,elmfiltString
+syn match	elmfiltOper	contained	"\~"				skipnl skipwhite nextgroup=elmfiltMatch
+syn match	elmfiltOper	contained	"<=\|>=\|!=\|<\|<\|="		skipnl skipwhite nextgroup=elmfiltString,elmfiltCond,elmfiltOperKey
+syn region	elmfiltString	contained	start='"' skip='"\(\\\\\)*\\["%]' end='"'	contains=elmfiltArg skipnl skipwhite nextgroup=elmfiltOper,elmfiltOperKey,@Spell
+syn region	elmfiltString	contained	start="'" skip="'\(\\\\\)*\\['%]" end="'"	contains=elmfiltArg skipnl skipwhite nextgroup=elmfiltOper,elmfiltOperKey,@Spell
+syn match	elmfiltSpaceError	contained	"\s.*$"
+
+" Define the default highlighting.
+" For version 5.7 and earlier: only when not done already
+" For version 5.8 and later: only when an item doesn't have highlighting yet
+if version >= 508 || !exists("did_elmfilt_syntax_inits")
+  if version < 508
+    let did_elmfilt_syntax_inits = 1
+    command -nargs=+ HiLink hi link <args>
+  else
+    command -nargs=+ HiLink hi def link <args>
+  endif
+
+  HiLink elmfiltAction	Statement
+  HiLink elmfiltArg	Special
+  HiLink elmfiltComment	Comment
+  HiLink elmfiltCond	Statement
+  HiLink elmfiltIf	Statement
+  HiLink elmfiltMatch	Special
+  HiLink elmfiltMatchError	Error
+  HiLink elmfiltNumber	Number
+  HiLink elmfiltOper	Operator
+  HiLink elmfiltOperKey	Type
+  HiLink elmfiltParenError	Error
+  HiLink elmfiltSpaceError	Error
+  HiLink elmfiltString	String
+  HiLink elmfiltThenError	Error
+
+  delcommand HiLink
+endif
+
+let b:current_syntax = "elmfilt"
+" vim: ts=9
--- /dev/null
+++ b/lib/vimfiles/syntax/erlang.vim
@@ -1,0 +1,224 @@
+" Vim syntax file
+" Language:    erlang (ERicsson LANGuage)
+"	       http://www.erlang.se
+"	       http://www.erlang.org
+" Maintainer:  Kre�imir Mar�i� (Kresimir Marzic) <kmarzic@fly.srk.fer.hr>
+" Last update: Fri, 15-Feb-2002
+" Filenames:   .erl
+" URL:	       http://www.srk.fer.hr/~kmarzic/vim/syntax/erlang.vim
+
+
+" There are three sets of highlighting in here:
+" One is "erlang_characters", second is "erlang_functions" and third
+" is "erlang_keywords".
+" If you want to disable keywords highlighting, put in your .vimrc:
+"       let erlang_keywords=1
+" If you want to disable erlang BIF highlighting, put in your .vimrc
+" this:
+"       let erlang_functions=1
+" If you want to disable special characters highlighting, put in
+" your .vimrc:
+"       let erlang_characters=1
+
+
+" For version 5.x: Clear all syntax items
+" For version 6.x: Quit when a syntax file was already loaded
+if version < 600
+	syntax clear
+elseif exists ("b:current_syntax")
+	finish
+endif
+
+
+" Case sensitive
+syn case match
+
+
+if ! exists ("erlang_characters")
+	" Basic elements
+	syn match   erlangComment	   +%.*$+
+	syn match   erlangModifier	   "\~\a\|\\\a" contained
+	syn match   erlangSpecialCharacter ":\|_\|@\|\\\|\"\|\."
+	syn match   erlangSeparator	   "(\|)\|{\|}\|\[\|]\||\|||\|;\|,\|?\|->\|#" contained
+	syn region  erlangString	   start=+"+ skip=+\\"+ end=+"+ contains=erlangModifier
+	syn region  erlangAtom		   start=+'+ skip=+\\'+ end=+'+
+
+	" Operators
+	syn match   erlangOperator	   "+\|-\|\*\|\/"
+	syn keyword erlangOperator	   div rem or xor bor bxor bsl bsr
+	syn keyword erlangOperator	   and band not bnot
+	syn match   erlangOperator	   "==\|/=\|=:=\|=/=\|<\|=<\|>\|>="
+	syn match   erlangOperator	   "++\|--\|=\|!\|<-"
+
+	" Numbers
+	syn match   erlangNumberInteger    "[+-]\=\d\+" contains=erlangSeparator
+	syn match   erlangNumberFloat1	   "[+-]\=\d\+.\d\+" contains=erlangSeparator
+	syn match   erlangNumberFloat2	   "[+-]\=\d\+\(.\d\+\)\=[eE][+-]\=\d\+\(.\d\+\)\=" contains=erlangSeparator
+	syn match   erlangNumberFloat3	   "[+-]\=\d\+[#]\x\+" contains=erlangSeparator
+	syn match   erlangNumberFloat4	   "[+-]\=[eE][+-]\=\d\+" contains=erlangSeparator
+	syn match   erlangNumberHex	   "$\x\+" contains=erlangSeparator
+
+	" Ignore '_' and '-' in words
+	syn match   erlangWord		   "\w\+[_-]\+\w\+"
+
+	" Ignore numbers in words
+	syn match   erlangWord		   "\w\+\d\+\(\(.\d\+\)\=\(\w\+\)\=\)\="
+endif
+
+if ! exists ("erlang_functions")
+	" Functions call
+	syn match   erlangFCall      "\w\+\(\s\+\)\=[:@]\(\s\+\)\=\w\+" contains=ALLBUT,erlangFunction,erlangBIF,erlangWord
+
+	" build-in-functions (BIFs)
+	syn keyword erlangBIF	     abs alive apply atom_to_list
+	syn keyword erlangBIF	     binary_to_list binary_to_term
+	syn keyword erlangBIF	     concat_binary
+	syn keyword erlangBIF	     date disconnect_node
+	syn keyword erlangBIF	     element erase exit
+	syn keyword erlangBIF	     float float_to_list
+	syn keyword erlangBIF	     get get_keys group_leader
+	syn keyword erlangBIF	     halt hd
+	syn keyword erlangBIF	     integer_to_list is_alive
+	syn keyword erlangBIF	     length link list_to_atom list_to_binary
+	syn keyword erlangBIF	     list_to_float list_to_integer list_to_pid
+	syn keyword erlangBIF	     list_to_tuple load_module
+	syn keyword erlangBIF	     make_ref monitor_node
+	syn keyword erlangBIF	     node nodes now
+	syn keyword erlangBIF	     open_port
+	syn keyword erlangBIF	     pid_to_list process_flag
+	syn keyword erlangBIF	     process_info process put
+	syn keyword erlangBIF	     register registered round
+	syn keyword erlangBIF	     self setelement size spawn
+	syn keyword erlangBIF	     spawn_link split_binary statistics
+	syn keyword erlangBIF	     term_to_binary throw time tl trunc
+	syn keyword erlangBIF	     tuple_to_list
+	syn keyword erlangBIF	     unlink unregister
+	syn keyword erlangBIF	     whereis
+
+	" Other BIFs
+	syn keyword erlangBIF	     atom binary constant function integer
+	syn keyword erlangBIF	     list number pid ports port_close port_info
+	syn keyword erlangBIF	     reference record
+
+	" erlang:BIFs
+	syn keyword erlangBIF	     check_process_code delete_module
+	syn keyword erlangBIF	     get_cookie hash math module_loaded
+	syn keyword erlangBIF	     preloaded processes purge_module set_cookie
+	syn keyword erlangBIF	     set_node
+
+	" functions of math library
+	syn keyword erlangFunction   acos asin atan atan2 cos cosh exp
+	syn keyword erlangFunction   log log10 pi pow power sin sinh sqrt
+	syn keyword erlangFunction   tan tanh
+
+	" Other functions
+	syn keyword erlangFunction   call module_info parse_transform
+	syn keyword erlangFunction   undefined_function
+
+	" Modules
+	syn keyword erlangModule     error_handler
+endif
+
+if ! exists ("erlang_keywords")
+	" Constants and Directives
+	syn match   erlangDirective  "-compile\|-define\|-else\|-endif\|-export\|-file"
+	syn match   erlangDirective  "-ifdef\|-ifndef\|-import\|-include\|-include_lib"
+	syn match   erlangDirective  "-module\|-record\|-undef"
+
+	syn match   erlangConstant   "-author\|-copyright\|-doc"
+
+	" Keywords
+	syn keyword erlangKeyword    after begin case catch
+	syn keyword erlangKeyword    cond end fun if
+	syn keyword erlangKeyword    let of query receive
+	syn keyword erlangKeyword    when
+
+	" Processes
+	syn keyword erlangProcess    creation current_function dictionary
+	syn keyword erlangProcess    group_leader heap_size high initial_call
+	syn keyword erlangProcess    linked low memory_in_use message_queue
+	syn keyword erlangProcess    net_kernel node normal priority
+	syn keyword erlangProcess    reductions registered_name runnable
+	syn keyword erlangProcess    running stack_trace status timer
+	syn keyword erlangProcess    trap_exit waiting
+
+	" Ports
+	syn keyword erlangPort       command count_in count_out creation in
+	syn keyword erlangPort       in_format linked node out owner packeting
+
+	" Nodes
+	syn keyword erlangNode       atom_tables communicating creation
+	syn keyword erlangNode       current_gc current_reductions current_runtime
+	syn keyword erlangNode       current_wall_clock distribution_port
+	syn keyword erlangNode       entry_points error_handler friends
+	syn keyword erlangNode       garbage_collection magic_cookie magic_cookies
+	syn keyword erlangNode       module_table monitored_nodes name next_ref
+	syn keyword erlangNode       ports preloaded processes reductions
+	syn keyword erlangNode       ref_state registry runtime wall_clock
+
+	" Reserved
+	syn keyword erlangReserved   apply_lambda module_info module_lambdas
+	syn keyword erlangReserved   record record_index record_info
+
+	" Extras
+	syn keyword erlangExtra      badarg nocookie false fun true
+
+	" Signals
+	syn keyword erlangSignal     badsig kill killed exit normal
+endif
+
+
+
+" Define the default highlighting.
+" For version 5.7 and earlier: only when not done already
+" For version 5.8 and later: only when an item doesn't have highlighting yet
+if version >= 508 || !exists ("did_erlang_inits")
+	if version < 508
+		let did_erlang_inits = 1
+		command -nargs=+ HiLink hi link <args>
+	else
+		command -nargs=+ HiLink hi def link <args>
+	endif
+
+	" erlang_characters
+	HiLink erlangComment Comment
+	HiLink erlangSpecialCharacter Special
+	HiLink erlangSeparator Normal
+	HiLink erlangModifier Special
+	HiLink erlangOperator Operator
+	HiLink erlangString String
+	HiLink erlangAtom Type
+
+	HiLink erlangNumberInteger Number
+	HiLink erlangNumberFloat1 Float
+	HiLink erlangNumberFloat2 Float
+	HiLink erlangNumberFloat3 Float
+	HiLink erlangNumberFloat4 Float
+	HiLink erlangNumberHex Number
+
+	HiLink erlangWord Normal
+
+	" erlang_functions
+	HiLink erlangFCall Function
+	HiLink erlangBIF Function
+	HiLink erlangFunction Function
+	HiLink erlangModuleFunction Function
+
+	" erlang_keywords
+	HiLink erlangDirective Type
+	HiLink erlangConstant Type
+	HiLink erlangKeyword Keyword
+	HiLink erlangProcess Special
+	HiLink erlangPort Special
+	HiLink erlangNode Special
+	HiLink erlangReserved Statement
+	HiLink erlangExtra Statement
+	HiLink erlangSignal Statement
+
+	delcommand HiLink
+endif
+
+
+let b:current_syntax = "erlang"
+
+" eof
--- /dev/null
+++ b/lib/vimfiles/syntax/eruby.vim
@@ -1,0 +1,85 @@
+" Vim syntax file
+" Language:		eRuby
+" Maintainer:		Tim Pope <vimNOSPAM@tpope.info>
+" Info:			$Id: eruby.vim,v 1.18 2007/05/06 23:56:12 tpope Exp $
+" URL:			http://vim-ruby.rubyforge.org
+" Anon CVS:		See above site
+" Release Coordinator:	Doug Kearns <dougkearns@gmail.com>
+
+if exists("b:current_syntax")
+  finish
+endif
+
+if !exists("main_syntax")
+  let main_syntax = 'eruby'
+endif
+
+if !exists("g:eruby_default_subtype")
+  let g:eruby_default_subtype = "html"
+endif
+
+if !exists("b:eruby_subtype") && main_syntax == 'eruby'
+  let s:lines = getline(1)."\n".getline(2)."\n".getline(3)."\n".getline(4)."\n".getline(5)."\n".getline("$")
+  let b:eruby_subtype = matchstr(s:lines,'eruby_subtype=\zs\w\+')
+  if b:eruby_subtype == ''
+    let b:eruby_subtype = matchstr(substitute(expand("%:t"),'\c\%(\.erb\)\+$','',''),'\.\zs\w\+$')
+  endif
+  if b:eruby_subtype == 'rhtml'
+    let b:eruby_subtype = 'html'
+  elseif b:eruby_subtype == 'rb'
+    let b:eruby_subtype = 'ruby'
+  elseif b:eruby_subtype == 'yml'
+    let b:eruby_subtype = 'yaml'
+  elseif b:eruby_subtype == 'js'
+    let b:eruby_subtype = 'javascript'
+  elseif b:eruby_subtype == 'txt'
+    " Conventional; not a real file type
+    let b:eruby_subtype = 'text'
+  elseif b:eruby_subtype == ''
+    let b:eruby_subtype = g:eruby_default_subtype
+  endif
+endif
+
+if !exists("b:eruby_nest_level")
+  let b:eruby_nest_level = strlen(substitute(substitute(substitute(expand("%:t"),'@','','g'),'\c\.\%(erb\|rhtml\)\>','@','g'),'[^@]','','g'))
+endif
+if !b:eruby_nest_level
+  let b:eruby_nest_level = 1
+endif
+
+if exists("b:eruby_subtype") && b:eruby_subtype != ''
+  exe "runtime! syntax/".b:eruby_subtype.".vim"
+  unlet! b:current_syntax
+endif
+syn include @rubyTop syntax/ruby.vim
+
+syn cluster erubyRegions contains=erubyOneLiner,erubyBlock,erubyExpression,erubyComment
+
+exe 'syn region  erubyOneLiner   matchgroup=erubyDelimiter start="^%\{1,'.b:eruby_nest_level.'\}%\@!"    end="$"     contains=@rubyTop	     containedin=ALLBUT,@erbRegions keepend oneline'
+exe 'syn region  erubyBlock      matchgroup=erubyDelimiter start="<%\{1,'.b:eruby_nest_level.'\}%\@!-\=" end="-\=%>" contains=@rubyTop	     containedin=ALLBUT,@erbRegions'
+exe 'syn region  erubyExpression matchgroup=erubyDelimiter start="<%\{1,'.b:eruby_nest_level.'\}="       end="-\=%>" contains=@rubyTop	     containedin=ALLBUT,@erbRegions'
+exe 'syn region  erubyComment    matchgroup=erubyDelimiter start="<%\{1,'.b:eruby_nest_level.'\}#"       end="-\=%>" contains=rubyTodo,@Spell containedin=ALLBUT,@erbRegions keepend'
+
+" Define the default highlighting.
+" For version 5.7 and earlier: only when not done already
+" For version 5.8 and later: only when an item doesn't have highlighting yet
+if version >= 508 || !exists("did_eruby_syntax_inits")
+  if version < 508
+    let did_ruby_syntax_inits = 1
+    command -nargs=+ HiLink hi link <args>
+  else
+    command -nargs=+ HiLink hi def link <args>
+  endif
+
+  HiLink erubyDelimiter		Delimiter
+  HiLink erubyComment		Comment
+
+  delcommand HiLink
+endif
+let b:current_syntax = 'eruby'
+
+if main_syntax == 'eruby'
+  unlet main_syntax
+endif
+
+" vim: nowrap sw=2 sts=2 ts=8 ff=unix:
--- /dev/null
+++ b/lib/vimfiles/syntax/esmtprc.vim
@@ -1,0 +1,34 @@
+" Vim syntax file
+" Language:	Esmtp setup file (based on esmtp 0.5.0)
+" Maintainer:	Kornel Kielczewski <kornel@gazeta.pl>
+" Last Change:	16 Feb 2005
+
+" For version 5.x: Clear all syntax items
+" For version 6.x: Quit when a syntax file was already loaded
+if version < 600
+  syntax clear
+elseif exists("b:current_syntax")
+  finish
+endif
+
+"All options
+:syntax keyword	esmtprcOptions hostname username password starttls certificate_passphrase preconnect identity mda
+
+"All keywords
+:syntax keyword esmtprcIdentifier default enabled disabled required
+
+"We're trying to be smarer than /."*@.*/ :)
+:syntax match esmtprcAddress /[a-z0-9_.-]*[a-z0-9]\+@[a-z0-9_.-]*[a-z0-9]\+\.[a-z]\+/
+:syntax match esmtprcFulladd /[a-z0-9_.-]*[a-z0-9]\+\.[a-z]\+:[0-9]\+/
+ 
+"String..
+:syntax region esmtprcString start=/"/ end=/"/
+
+
+:highlight link esmtprcOptions		Label
+:highlight link esmtprcString 		String
+:highlight link esmtprcAddress		Type
+:highlight link esmtprcIdentifier 	Identifier
+:highlight link esmtprcFulladd		Include
+
+let b:current_syntax="esmtprc"
--- /dev/null
+++ b/lib/vimfiles/syntax/esqlc.vim
@@ -1,0 +1,75 @@
+" Vim syntax file
+" Language:	ESQL-C
+" Maintainer:	Jonathan A. George <jageorge@tel.gte.com>
+" Last Change:	2001 May 09
+
+" For version 5.x: Clear all syntax items
+" For version 6.x: Quit when a syntax file was already loaded
+if version < 600
+  syntax clear
+elseif exists("b:current_syntax")
+  finish
+endif
+
+" Read the C++ syntax to start with
+if version < 600
+  source <sfile>:p:h/cpp.vim
+else
+  runtime! syntax/cpp.vim
+endif
+
+" ESQL-C extentions
+
+syntax keyword esqlcPreProc	EXEC SQL INCLUDE
+
+syntax case ignore
+
+syntax keyword esqlcPreProc	begin end declare section database open execute
+syntax keyword esqlcPreProc	prepare fetch goto continue found sqlerror work
+
+syntax keyword esqlcKeyword	access add as asc by check cluster column
+syntax keyword esqlcKeyword	compress connect current decimal
+syntax keyword esqlcKeyword	desc exclusive file from group
+syntax keyword esqlcKeyword	having identified immediate increment index
+syntax keyword esqlcKeyword	initial into is level maxextents mode modify
+syntax keyword esqlcKeyword	nocompress nowait of offline on online start
+syntax keyword esqlcKeyword	successful synonym table then to trigger uid
+syntax keyword esqlcKeyword	unique user validate values view whenever
+syntax keyword esqlcKeyword	where with option order pctfree privileges
+syntax keyword esqlcKeyword	public resource row rowlabel rownum rows
+syntax keyword esqlcKeyword	session share size smallint
+
+syntax keyword esqlcOperator	not and or
+syntax keyword esqlcOperator	in any some all between exists
+syntax keyword esqlcOperator	like escape
+syntax keyword esqlcOperator	intersect minus
+syntax keyword esqlcOperator	prior distinct
+syntax keyword esqlcOperator	sysdate
+
+syntax keyword esqlcStatement	alter analyze audit comment commit create
+syntax keyword esqlcStatement	delete drop explain grant insert lock noaudit
+syntax keyword esqlcStatement	rename revoke rollback savepoint select set
+syntax keyword esqlcStatement	truncate update
+
+" Define the default highlighting.
+" For version 5.7 and earlier: only when not done already
+" For version 5.8 and later: only when an item doesn't have highlighting yet
+if version >= 508 || !exists("did_esqlc_syntax_inits")
+  if version < 508
+    let did_esqlc_syntax_inits = 1
+    command -nargs=+ HiLink hi link <args>
+  else
+    command -nargs=+ HiLink hi def link <args>
+  endif
+
+  HiLink esqlcOperator	Operator
+  HiLink esqlcStatement	Statement
+  HiLink esqlcKeyword	esqlcSpecial
+  HiLink esqlcSpecial	Special
+  HiLink esqlcPreProc	PreProc
+
+  delcommand HiLink
+endif
+
+let b:current_syntax = "esqlc"
+
--- /dev/null
+++ b/lib/vimfiles/syntax/esterel.vim
@@ -1,0 +1,84 @@
+" Vim syntax file
+" Language:			ESTEREL
+" Maintainer:		Maurizio Tranchero <maurizio.tranchero@polito.it> - <maurizio.tranchero@gmail.com>
+" Credits:			Luca Necchi	<luca.necchi@polito.it>
+" First Release:	Tue May 17 23:49:39 CEST 2005
+" Last Change:		Sat Apr 22 14:56:41 CEST 2006
+" Version:			0.5
+
+" For version 5.x: Clear all syntax items
+" For version 6.x: Quit when a syntax file was already loaded
+if version < 600
+  syntax clear
+elseif exists("b:current_syntax")
+  finish
+endif
+
+" case is significant
+syn case ignore
+" Esterel Regions
+syn region esterelModule					start=/module/		end=/end module/	contains=ALLBUT,esterelModule
+syn region esterelLoop						start=/loop/		end=/end loop/		contains=ALLBUT,esterelModule
+syn region esterelAbort						start=/abort/		end=/when/			contains=ALLBUT,esterelModule
+syn region esterelAbort						start=/weak abort/	end=/when/			contains=ALLBUT,esterelModule
+syn region esterelEvery						start=/every/		end=/end every/		contains=ALLBUT,esterelModule
+syn region esterelIf						start=/if/			end=/end if/		contains=ALLBUT,esterelModule
+syn region esterelConcurrent	transparent start=/\[/			end=/\]/			contains=ALLBUT,esterelModule
+syn region esterelIfThen					start=/if/			end=/then/			oneline
+" Esterel Keywords
+syn keyword esterelIO			input output inputoutput constant
+syn keyword esterelBoolean		and or not xor xnor nor nand
+syn keyword esterelExpressions	mod 
+syn keyword esterelStatement	nothing halt
+syn keyword esterelStatement	module signal sensor end
+syn keyword esterelStatement	every do loop abort weak
+syn keyword esterelStatement	emit present await
+syn keyword esterelStatement	pause when immediate
+syn keyword esterelStatement	if then else case
+syn keyword esterelStatement	var in  run  suspend
+syn keyword esterelStatement	repeat times combine with
+syn keyword esterelStatement	assert sustain
+" check what it is the following
+syn keyword esterelStatement	relation						
+syn keyword esterelFunctions	function procedure task
+syn keyword esterelSysCall		call trap exit exec
+" Esterel Types
+syn keyword esterelType integer float bolean
+" Esterel Comment
+syn match esterelComment	"%.*$"
+" Operators and special characters
+syn match esterelSpecial	":"
+syn match esterelSpecial	"<="
+syn match esterelSpecial	">="
+syn match esterelSpecial	";"
+syn match esterelOperator	"\["
+syn match esterelOperator	"\]"
+syn match esterelOperator	":="
+syn match esterelStatement	"\<\(if\|else\)\>"
+syn match esterelNone		"\<else\s\+if\>$"
+syn match esterelNone		"\<else\s\+if\>\s"
+
+" Class Linking
+if version >= 508 || !exists("did_esterel_syntax_inits")
+  if version < 508
+    let did_esterel_syntax_inits = 1
+    command -nargs=+ HiLink hi link <args>
+  else
+    command -nargs=+ HiLink hi def link <args>
+  endif
+
+	HiLink esterelStatement		Statement
+	HiLink esterelType			Type
+	HiLink esterelComment		Comment
+	HiLink esterelBoolean		Number
+	HiLink esterelExpressions	Number
+	HiLink esterelIO			String
+	HiLink esterelOperator		Type
+	HiLink esterelSysCall		Type
+	HiLink esterelFunctions		Type
+	HiLink esterelSpecial		Special
+
+  delcommand HiLink
+endif
+
+let b:current_syntax = "esterel"
--- /dev/null
+++ b/lib/vimfiles/syntax/eterm.vim
@@ -1,0 +1,429 @@
+" Vim syntax file
+" Language:         eterm(1) configuration file
+" Maintainer:       Nikolai Weibull <now@bitwi.se>
+" Latest Revision:  2006-04-21
+
+if exists("b:current_syntax")
+  finish
+endif
+
+let s:cpo_save = &cpo
+set cpo&vim
+
+syn keyword etermTodo             contained TODO FIXME XXX NOTE
+
+syn region  etermComment          display oneline start='^#' end='$'
+                                  \ contains=etermTodo,@Spell
+
+syn match   etermMagic            display '^<Eterm-[0-9.]\+>$'
+
+syn match   etermNumber           contained display '\<\(\d\+\|0x\x\{1,2}\)\>'
+
+syn region  etermString           contained display oneline start=+"+
+                                  \ skip=+\\"+ end=+"+
+
+syn keyword etermBoolean          contained on off true false yes no
+
+syn keyword etermPreProc          contained appname exec get put random version
+                                  \ include preproc
+
+syn keyword etermFunctions        contained copy exit kill nop paste save
+                                  \ scroll search spawn
+
+syn cluster etermGeneral          contains=etermComment,etermFunction,
+                                  \ etermPreProc
+
+syn keyword etermKeyMod           contained ctrl shift lock mod1 mod2 mod3 mod4
+                                  \ mod5 alt meta anymod
+syn keyword etermKeyMod           contained button1 button2 button3 button4
+                                  \ button5
+
+syn keyword etermColorOptions     contained video nextgroup=etermVideoOptions
+                                  \ skipwhite
+
+syn keyword etermVideoType        contained normal reverse
+
+syn keyword etermColorOptions     contained foreground background cursor
+                                  \ cursor_text pointer
+                                  \ nextgroup=etermColorType skipwhite
+
+syn keyword etermColorType        contained bd ul
+syn match   etermColorType        contained display '\<\%(\d\|1[0-5]\)'
+
+syn keyword etermColorOptions     contained color
+                                  \ nextgroup=etermColorNumber skipwhite
+
+syn keyword etermColorNumber      contained bd ul nextgroup=etermColorSpec
+                                  \ skipwhite
+syn match   etermColorNumber      contained display '\<\%(\d\|1[0-5]\)'
+                                  \ nextgroup=etermColorSpec skipwhite
+
+syn match   etermColorSpec        contained display '\S\+'
+
+syn region  etermColorContext     fold transparent matchgroup=etermContext
+                                  \ start='^\s*begin\s\+color\>'
+                                  \ end='^\s*end\>'
+                                  \ contains=@etermGeneral,etermColorOptions
+
+syn keyword etermAttrOptions      contained geometry nextgroup=etermGeometry
+                                  \ skipwhite
+
+syn match   etermGeometry         contained display '\d\+x\d++\d\++\d\+'
+
+syn keyword etermAttrOptions      contained scrollbar_type
+                                  \ nextgroup=etermScrollbarType skipwhite
+
+syn keyword etermScrollbarType    contained motif xterm next
+
+syn keyword etermAttrOptions      contained font nextgroup=etermFontType
+                                  \ skipwhite
+
+syn keyword etermFontType         contained bold nextgroup=etermFont skipwhite
+syn match   etermFontType         contained display '[0-5]' nextgroup=etermFont
+                                  \ skipwhite
+
+syn match   etermFont             contained display '\S\+'
+
+syn keyword etermFontType         contained default nextgroup=etermNumber
+                                  \ skipwhite
+
+syn keyword etermFontType         contained proportional nextgroup=etermBoolean
+                                  \ skipwhite
+
+syn keyword etermFontType         contained fx nextgroup=etermString skipwhite
+
+syn keyword etermAttrOptions      contained title name iconname
+                                  \ nextgroup=etermString skipwhite
+
+syn keyword etermAttrOptions      contained scrollbar_width desktop
+                                  \ nextgroup=etermNumber skipwhite
+
+syn region  etermAttrContext      fold transparent matchgroup=etermContext
+                                  \ start='^\s*begin\s\+attributes\>'
+                                  \ end='^\s*end\>'
+                                  \ contains=@etermGeneral,etermAttrOptions
+
+syn keyword etermIClassOptions    contained icon path nextgroup=etermString
+                                  \ skipwhite
+syn keyword etermIClassOptions    contained cache nextgroup=etermNumber
+                                  \ skipwhite
+syn keyword etermIClassOptions    contained anim nextgroup=etermNumber
+                                  \ skipwhite
+
+syn region  etermIClassContext    fold transparent matchgroup=etermContext
+                                  \ start='^\s*begin\s\+imageclasses\>'
+                                  \ end='^\s*end\>'
+                                  \ contains=@etermGeneral,etermImageContext,
+                                  \ etermIClassOptions
+
+syn keyword etermImageOptions     contained type nextgroup=etermImageType
+                                  \ skipwhite
+
+syn keyword etermImageTypes       contained background trough anchor up_arrow
+                                  \ left_arrow right_arrow menu menuitem
+                                  \ submenu button buttonbar down_arrow
+
+syn keyword etermImageOptions     contained mode nextgroup=etermImageModes
+                                  \ skipwhite
+
+syn keyword etermImageModes       contained image trans viewport auto solid
+                                  \ nextgroup=etermImageModesAllow skipwhite
+syn keyword etermImageModesAllow  contained allow nextgroup=etermImageModesR
+                                  \ skipwhite
+syn keyword etermImageModesR      contained image trans viewport auto solid
+
+syn keyword etermImageOptions     contained state nextgroup=etermImageState
+                                  \ skipwhite
+
+syn keyword etermImageState       contained normal selected clicked disabled
+
+syn keyword etermImageOptions     contained color nextgroup=etermImageColorFG
+                                  \ skipwhite
+
+syn keyword etermImageColorFG     contained '\S\+' nextgroup=etermImageColorBG
+                                  \ skipwhite
+
+syn keyword etermImageColorBG     contained '\S\+'
+
+syn keyword etermImageOptions     contained file nextgroup=etermString
+                                  \ skipwhite
+
+syn keyword etermImageOptions     contained geom nextgroup=etermImageGeom
+                                  \ skipwhite
+
+syn match   etermImageGeom        contained display
+                                  \ '\s\+\%(\d\+x\d\++\d\++\d\+\)\=:\%(\%(tie\|scale\|hscale\|vscale\|propscale\)d\=\)\='
+
+syn keyword etermImageOptions     contained cmod colormod
+                                  \ nextgroup=etermImageCmod skipwhite
+
+syn keyword etermImageCmod        contained image red green blue
+                                  \ nextgroup=etermImageBrightness skipwhite
+
+syn match   etermImageBrightness  contained display '\<\(\d\+\|0x\x\{1,2}\)\>'
+                                  \ nextgroup=etermImageContrast skipwhite
+
+syn match   etermImageContrast    contained display '\<\(\d\+\|0x\x\{1,2}\)\>'
+                                  \ nextgroup=etermImageGamma skipwhite
+
+syn match   etermImageGamma       contained display '\<\(\d\+\|0x\x\{1,2}\)\>'
+                                  \ nextgroup=etermImageGamma skipwhite
+
+syn region  etermImageOptions     contained display oneline
+                                  \ matchgroup=etermImageOptions
+                                  \ start='border\|bevel\%(\s\+\%(up\|down\)\)\|padding'
+                                  \ end='$' contains=etermNumber
+
+syn region  etermImageContext     contained fold transparent
+                                  \ matchgroup=etermContext
+                                  \ start='^\s*begin\s\+image\>'
+                                  \ end='^\s*end\>'
+                                  \ contains=@etermGeneral,etermImageOptions
+
+syn keyword etermMenuItemOptions  contained action
+                                  \ nextgroup=etermMenuItemAction skipwhite
+
+syn keyword etermMenuItemAction   contained string echo submenu script
+                                  \ nextgroup=etermString skipwhite
+
+syn keyword etermMenuItemAction   contained separator
+
+syn keyword etermMenuItemOptions  contained text rtext nextgroup=etermString
+                                  \ skipwhite
+
+syn region  etermMenuItemContext  contained fold transparent
+                                  \ matchgroup=etermContext
+                                  \ start='^\s*begin\s\+menuitem\>'
+                                  \ end='^\s*end\>'
+                                  \ contains=@etermGeneral,etermMenuItemOptions
+
+syn keyword etermMenuOptions      contained title nextgroup=etermString
+                                  \ skipwhite
+
+syn keyword etermMenuOptions      contained font_name nextgroup=etermFont
+                                  \ skipwhite
+
+syn match   etermMenuOptions      contained display '\<sep\>\|-'
+
+syn region  etermMenuContext      fold transparent matchgroup=etermContext
+                                  \ start='^\s*begin\s\+menu\>'
+                                  \ end='^\s*end\>'
+                                  \ contains=@etermGeneral,etermMenuOptions,
+                                  \ etermMenuItemContext
+
+syn keyword etermBind             contained bind nextgroup=etermBindMods
+                                  \ skipwhite
+
+syn keyword etermBindMods         contained ctrl shift lock mod1 mod2 mod3 mod4
+                                  \ mod5 alt meta anymod
+                                  \ nextgroup=etermBindMods skipwhite
+
+syn keyword etermBindTo           contained to nextgroup=etermBindType
+                                  \ skipwhite
+
+syn keyword etermBindType         contained string echo menu script
+                                  \ nextgroup=etermBindParam skipwhite
+
+syn match   etermBindParam        contained display '\S\+'
+
+syn region  etermActionsContext   fold transparent matchgroup=etermContext
+                                  \ start='^\s*begin\s\+actions\>'
+                                  \ end='^\s*end\>'
+                                  \ contains=@etermGeneral,etermActionsOptions
+
+syn keyword etermButtonOptions    contained font nextgroup=etermFont skipwhite
+syn keyword etermButtonOptions    contained visible nextgroup=etermBoolean
+                                  \ skipwhite
+syn keyword etermButtonOptions    contained dock nextgroup=etermDockOption
+                                  \ skipwhite
+
+syn keyword etermDockOption       contained top bottom no
+
+syn keyword etermButton           contained button nextgroup=etermButtonText
+                                  \ skipwhite
+
+syn region  etermButtonText       contained display oneline start=+"+
+                                  \ skip=+\\"+ end=+"+
+                                  \ nextgroup=etermButtonIcon skipwhite
+
+syn keyword etermButtonIcon       contained icon nextgroup=etermButtonIconFile
+                                  \ skipwhite
+
+syn keyword etermButtonIconFile   contained '\S\+' nextgroup=etermButtonAction
+                                  \ skipwhite
+
+syn keyword etermButtonAction     contained action nextgroup=etermBindType
+                                  \ skipwhite
+
+syn region  etermButtonContext    fold transparent matchgroup=etermContext
+                                  \ start='^\s*begin\s\+button_bar\>'
+                                  \ end='^\s*end\>'
+                                  \ contains=@etermGeneral,etermButtonOptions
+
+syn keyword etermMultiOptions     contained encoding nextgroup=etermEncoding
+                                  \ skipwhite
+
+syn keyword etermEncoding         eucj sjis euckr big5 gb
+syn match   etermEncoding         display 'iso-10646'
+
+syn keyword etermMultiOptions     contained font nextgroup=etermFontType
+                                  \ skipwhite
+
+syn region  etermMultiContext     fold transparent matchgroup=etermContext
+                                  \ start='^\s*begin\s\+multichar\>'
+                                  \ end='^\s*end\>'
+                                  \ contains=@etermGeneral,etermMultiOptions
+
+syn keyword etermXimOptions       contained input_method
+                                  \ nextgroup=etermInputMethod skipwhite
+
+syn match   etermInputMethod      contained display '\S+'
+
+syn keyword etermXimOptions       contained preedit_type
+                                  \ nextgroup=etermPreeditType skipwhite
+
+syn keyword etermPreeditType      contained OverTheSpot OffTheSpot Root
+
+syn region  etermXimContext       fold transparent matchgroup=etermContext
+                                  \ start='^\s*begin\s\+xim\>'
+                                  \ end='^\s*end\>'
+                                  \ contains=@etermGeneral,etermXimOptions
+
+syn keyword etermTogOptions       contained map_alert visual_bell login_shell
+                                  \ scrollbar utmp_logging meta8 iconic
+                                  \ no_input home_on_output home_on_input
+                                  \ scrollbar_floating scrollbar_right
+                                  \ scrollbar_popup borderless double_buffer
+                                  \ no_cursor pause xterm_select select_line
+                                  \ select_trailing_spaces report_as_keysyms
+                                  \ itrans immotile_trans buttonbar
+                                  \ resize_gravity nextgroup=etermBoolean
+                                  \ skipwhite
+
+syn region  etermTogContext       fold transparent matchgroup=etermContext
+                                  \ start='^\s*begin\s\+toggles\>'
+                                  \ end='^\s*end\>'
+                                  \ contains=@etermGeneral,etermTogOptions
+
+syn keyword etermKeyboardOptions  contained smallfont_key bigfont_key keysym
+                                  \ nextgroup=etermKeysym skipwhite
+
+syn keyword etermKeysym           contained '\S\+' nextgroup=etermString
+                                  \ skipwhite
+
+syn keyword etermKeyboardOptions  contained meta_mod alt_mod numlock_mod
+                                  \ nextgroup=etermNumber skipwhite
+
+syn keyword etermKeyboardOptions  contained greek app_keypad app_cursor
+                                  \ nextgroup=etermBoolean skipwhite
+
+syn region  etermKeyboardContext  fold transparent matchgroup=etermContext
+                                  \ start='^\s*begin\s\+keyboard\>'
+                                  \ end='^\s*end\>'
+                                  \ contains=@etermGeneral,etermKeyboardOptions
+
+syn keyword etermMiscOptions      contained print_pipe cut_chars finished_title
+                                  \ finished_text term_name exec
+                                  \ nextgroup=etermString skipwhite
+
+syn keyword etermMiscOptions      contained save_lines min_anchor_size
+                                  \ border_width line_space
+
+syn region  etermMiscContext      fold transparent matchgroup=etermContext
+                                  \ start='^\s*begin\s\+misc\>'
+                                  \ end='^\s*end\>'
+                                  \ contains=@etermGeneral,etermMiscOptions
+
+syn keyword etermEScreenOptions   contained url nextgroup=etermURL skipwhite
+
+syn match   etermURL              contained display
+                                  \ '\<\%(screen\|twin\)://\%([^@:/]\+\%(@[^:/]\+\%(:[^/]\+\)\=\)\=\)\=/\S\+'
+
+syn keyword etermEScreenOptions   contained firewall
+
+syn keyword etermEScreenOptions   contained delay nextgroup=etermNumber
+                                  \ skipwhite
+
+syn keyword etermEScreenOptions   contained bbar_font nextgroup=etermFont
+                                  \ skipwhite
+
+syn keyword etermEScreenOptions   contained bbar_dock nextgroup=etermDockOption
+                                  \ skipwhite
+
+syn region  etermEScreenContext   fold transparent matchgroup=etermContext
+                                  \ start='^\s*begin\s\+escreen\>'
+                                  \ end='^\s*end\>'
+                                  \ contains=@etermGeneral,etermEScreenOptions
+
+if exists("eterm_minlines")
+  let b:eterm_minlines = eterm_minlines
+else
+  let b:eterm_minlines = 50
+endif
+exec "syn sync minlines=" . b:eterm_minlines
+
+hi def link etermTodo             Todo
+hi def link etermComment          Comment
+hi def link etermMagic            PreProc
+hi def link etermNumber           Number
+hi def link etermString           String
+hi def link etermBoolean          Boolean
+hi def link etermPreProc          PreProc
+hi def link etermFunctions        Function
+hi def link etermKeyMod           Constant
+hi def link etermOption           Keyword
+hi def link etermColorOptions     etermOption
+hi def link etermColor            String
+hi def link etermVideoType        Type
+hi def link etermColorType        Type
+hi def link etermColorNumber      Number
+hi def link etermColorSpec        etermColor
+hi def link etermContext          Keyword
+hi def link etermAttrOptions      etermOption
+hi def link etermGeometry         String
+hi def link etermScrollbarType    Type
+hi def link etermFontType         Type
+hi def link etermIClassOptions    etermOption
+hi def link etermImageOptions     etermOption
+hi def link etermImageTypes       Type
+hi def link etermImageModes       Type
+hi def link etermImageModesAllow  Keyword
+hi def link etermImageModesR      Type
+hi def link etermImageState       Keyword
+hi def link etermImageColorFG     etermColor
+hi def link etermImageColorBG     etermColor
+hi def link etermImageGeom        String
+hi def link etermImageCmod        etermOption
+hi def link etermImageBrightness  Number
+hi def link etermImageContrast    Number
+hi def link etermImageGamma       Number
+hi def link etermMenuItemOptions  etermOption
+hi def link etermMenuItemAction   Keyword
+hi def link etermMenuOptions      etermOption
+hi def link etermBind             Keyword
+hi def link etermBindMods         Identifier
+hi def link etermBindTo           Keyword
+hi def link etermBindType         Type
+hi def link etermBindParam        String
+hi def link etermButtonOptions    etermOption
+hi def link etermDockOption       etermOption
+hi def link etermButtonText       String
+hi def link etermButtonIcon       String
+hi def link etermButtonIconFile   String
+hi def link etermButtonAction     Keyword
+hi def link etermMultiOptions     etermOption
+hi def link etermEncoding         Identifier
+hi def link etermXimOptions       etermOption
+hi def link etermInputMethod      Identifier
+hi def link etermPreeditType      Type
+hi def link etermTogOptions       etermOption
+hi def link etermKeyboardOptions  etermOption
+hi def link etermKeysym           Constant
+hi def link etermMiscOptions      etermOption
+hi def link etermEScreenOptions   etermOption
+hi def link etermURL              Identifier
+
+let b:current_syntax = "eterm"
+
+let &cpo = s:cpo_save
+unlet s:cpo_save
--- /dev/null
+++ b/lib/vimfiles/syntax/eviews.vim
@@ -1,0 +1,104 @@
+" Vim syntax file
+" Language:	Eviews (http://www.eviews.com)
+" Maintainer:	Vaidotas Zemlys <zemlys@gmail.com>
+" Last Change:  2006 Apr 30
+" Filenames:	*.prg
+" URL:	http://uosis.mif.vu.lt/~zemlys/vim-syntax/eviews.vim
+" For version 5.x: Clear all syntax items
+" For version 6.x: Quit when a syntax file was already loaded
+if version < 600
+  syntax clear
+elseif exists("b:current_syntax")
+  finish
+endif
+
+if version >= 600
+  setlocal iskeyword=@,48-57,_,.
+else
+  set iskeyword=@,48-57,_,.
+endif
+
+syn case match
+
+" Comment
+syn match eComment /\'.*/
+
+" Constant
+" string enclosed in double quotes
+syn region eString start=/"/ skip=/\\\\\|\\"/ end=/"/
+" number with no fractional part or exponent
+syn match eNumber /\d\+/
+" floating point number with integer and fractional parts and optional exponent
+syn match eFloat /\d\+\.\d*\([Ee][-+]\=\d\+\)\=/
+" floating point number with no integer part and optional exponent
+syn match eFloat /\.\d\+\([Ee][-+]\=\d\+\)\=/
+" floating point number with no fractional part and optional exponent
+syn match eFloat /\d\+[Ee][-+]\=\d\+/
+
+" Identifier
+" identifier with leading letter and optional following keyword characters
+syn match eIdentifier /\a\k*/
+
+" Eviews Programing Language
+syn keyword eProgLang  @date else endif @errorcount @evpath exitloop for if @isobject next poff pon return statusline step stop  @temppath then @time to @toc wend while  include call subroutine endsub and or
+
+" Eviews Objects, Views and Procedures
+syn keyword eOVP alpha coef equation graph group link logl matrix model pool rowvector sample scalar series sspace sym system table text valmap var vector
+
+
+" Standard Eviews Commands
+syn keyword eStdCmd 3sls add addassign addinit addtext align alpha append arch archtest area arlm arma arroots auto axis bar bdstest binary block boxplot boxplotby bplabel cause ccopy cd cdfplot cellipse censored cfetch checkderivs chow clabel cleartext close coef coefcov coint comment control copy cor correl correlsq count cov create cross data datelabel dates db dbcopy dbcreate dbdelete dbopen dbpack dbrebuild dbrename dbrepair decomp define delete derivs describe displayname do draw driconvert drop dtable ec edftest endog eqs equation errbar exclude exit expand fetch fill fiml fit forecast freeze freq frml garch genr gmm grads graph group hconvert hfetch hilo hist hlabel hpf impulse jbera kdensity kerfit label laglen legend line linefit link linkto load logit logl ls makecoint makederivs makeendog makefilter makegarch makegrads makegraph makegroup makelimits makemodel makeregs makeresids makesignals makestates makestats makesystem map matrix means merge metafile ml model msg name nnfit open options ordered output override pageappend pagecontract pagecopy pagecreate pagedelete pageload pagerename pagesave pageselect pagestack pagestruct pageunstack param pcomp pie pool predict print probit program qqplot qstats range read rename representations resample reset residcor residcov resids results rls rndint rndseed rowvector run sample save scalar scale scat scatmat scenario seas seasplot series set setbpelem setcell setcolwidth setconvert setelem setfillcolor setfont setformat setheight setindent setjust setline setlines setmerge settextcolor setwidth sheet show signalgraphs smooth smpl solve solveopt sort spec spike sspace statby statefinal stategraphs stateinit stats statusline stomna store structure sur svar sym system table template testadd testbtw testby testdrop testexog testfit testlags teststat text tic toc trace tramoseats tsls unlink update updatecoefs uroot usage valmap var vars vector wald wfcreate wfopen wfsave wfselect white wls workfile write wtsls x11 x12 xy xyline xypair 
+
+" Constant Identifier
+syn match eConstant /\!\k*/
+" String Identifier
+syn match eStringId /%\k*/
+" Command Identifier
+syn match eCommand /@\k*/
+
+" Special
+syn match eDelimiter /[,;:]/
+
+" Error
+syn region eRegion matchgroup=Delimiter start=/(/ matchgroup=Delimiter end=/)/ transparent contains=ALLBUT,rError,rBraceError,rCurlyError
+syn region eRegion matchgroup=Delimiter start=/{/ matchgroup=Delimiter end=/}/ transparent contains=ALLBUT,rError,rBraceError,rParenError
+syn region eRegion matchgroup=Delimiter start=/\[/ matchgroup=Delimiter end=/]/ transparent contains=ALLBUT,rError,rCurlyError,rParenError
+syn match eError      /[)\]}]/
+syn match eBraceError /[)}]/ contained
+syn match eCurlyError /[)\]]/ contained
+syn match eParenError /[\]}]/ contained
+
+" Define the default highlighting.
+" For version 5.7 and earlier: only when not done already
+" For version 5.8 and later: only when an item doesn't have highlighting yet
+if version >= 508 || !exists("did_r_syn_inits")
+  if version < 508
+    let did_r_syn_inits = 1
+    command -nargs=+ HiLink hi link <args>
+  else
+    command -nargs=+ HiLink hi def link <args>
+  endif
+  HiLink eComment     Comment
+  HiLink eConstant    Identifier
+  HiLink eStringId    Identifier
+  HiLink eCommand     Type
+  HiLink eString      String
+  HiLink eNumber      Number
+  HiLink eBoolean     Boolean
+  HiLink eFloat       Float
+  HiLink eConditional Conditional
+  HiLink eProgLang    Statement
+  HiLink eOVP	      Statement
+  HiLink eStdCmd      Statement
+  HiLink eIdentifier  Normal
+  HiLink eDelimiter   Delimiter
+  HiLink eError       Error
+  HiLink eBraceError  Error
+  HiLink eCurlyError  Error
+  HiLink eParenError  Error
+  delcommand HiLink
+endif
+
+let b:current_syntax="eviews"
+
+" vim: ts=8 sw=2
--- /dev/null
+++ b/lib/vimfiles/syntax/exim.vim
@@ -1,0 +1,117 @@
+" Vim syntax file
+" This is a GENERATED FILE. Please always refer to source file at the URI below.
+" Language: Exim configuration file exim.conf
+" Maintainer: David Ne\v{c}as (Yeti) <yeti@physics.muni.cz>
+" Last Change: 2002-10-15
+" URL: http://trific.ath.cx/Ftp/vim/syntax/exim.vim
+
+" Setup
+if version >= 600
+	if exists("b:current_syntax")
+		finish
+	endif
+else
+	syntax clear
+endif
+
+syn case match
+
+" Base constructs
+syn match eximComment "^\s*#.*$" contains=eximFixme
+syn match eximComment "\s#.*$" contains=eximFixme
+syn keyword eximFixme FIXME TODO XXX NOT contained
+syn keyword eximConstant true false yes no
+syn match eximNumber "\<\d\+[KM]\?\>"
+syn match eximNumber "\<0[xX]\x\+\>"
+syn match eximNumber "\<\d\+\(\.\d\{,3}\)\?\>"
+syn match eximTime "\<\(\d\+[wdhms]\)\+\>"
+syn match eximSpecialChar "\\[\\nrt]\|\\\o\{1,3}\|\\x\x\{1,2}"
+syn region eximMacroDefinition matchgroup=eximMacroName start="^[A-Z]\i*\s*=" end="$" skip="\\\s*$" transparent
+
+syn match eximDriverName "\<\(aliasfile\|appendfile\|autoreply\|domainlist\|forwardfile\|ipliteral\|iplookup\|lmtp\|localuser\|lookuphost\|pipe\|queryprogram\|smartuser\|smtp\)\>"
+syn match eximTransport "^\s*\i\+:"
+
+" Options
+syn keyword eximEnd end
+syn keyword eximKeyword accept_8bitmime accept_timeout admin_groups allow_mx_to_ip always_bcc auth_always_advertise auth_hosts auth_over_tls_hosts auto_thaw bi_command check_log_inodes check_log_space check_spool_inodes check_spool_space collapse_source_routes daemon_smtp_port daemon_smtp_service debug_level delay_warning delay_warning_condition deliver_load_max deliver_queue_load_max delivery_date_remove dns_again_means_nonexist dns_check_names dns_check_names_pattern dns_retrans dns_ipv4_lookup dns_retry envelope_to_remove errmsg_text errmsg_file errors_address errors_copy errors_reply_to exim_group exim_path exim_user extract_addresses_remove_arguments finduser_retries forbid_domain_literals freeze_tell_mailmaster gecos_name gecos_pattern headers_check_syntax headers_checks_fail headers_sender_verify headers_sender_verify_errmsg helo_accept_junk_hosts helo_strict_syntax helo_verify hold_domains host_accept_relay host_auth_accept_relay host_lookup host_reject host_reject_recipients hosts_treat_as_local ignore_errmsg_errors ignore_errmsg_errors_after ignore_fromline_hosts ignore_fromline_local keep_malformed kill_ip_options ldap_default_servers local_domains local_domains_include_host local_domains_include_host_literals local_from_check local_from_prefix local_from_suffix local_interfaces localhost_number locally_caseless log_all_parents log_arguments log_file_path log_incoming_port log_ip_options log_level log_queue_run_level log_received_recipients log_received_sender log_refused_recipients log_rewrites log_sender_on_delivery log_smtp_confirmation log_smtp_connections log_smtp_syntax_errors log_subject lookup_open_max max_username_length message_body_visible message_filter message_filter_directory_transport message_filter_directory2_transport message_filter_file_transport message_filter_group message_filter_pipe_transport message_filter_reply_transport message_filter_user message_id_header_text message_size_limit message_size_limit_count_recipients move_frozen_messages mysql_servers never_users nobody_group nobody_user percent_hack_domains perl_at_start perl_startup pgsql_servers pid_file_path preserve_message_logs primary_hostname print_topbitchars prod_requires_admin prohibition_message qualify_domain qualify_recipient queue_list_requires_admin queue_only queue_only_file queue_only_load queue_remote_domains queue_run_in_order queue_run_max queue_smtp_domains rbl_domains rbl_hosts rbl_log_headers rbl_log_rcpt_count rbl_reject_recipients rbl_warn_header received_header_text received_headers_max receiver_try_verify receiver_unqualified_hosts receiver_verify receiver_verify_addresses receiver_verify_hosts receiver_verify_senders recipients_max recipients_max_reject recipients_reject_except recipients_reject_except_senders refuse_ip_options relay_domains relay_domains_include_local_mx relay_match_host_or_sender remote_max_parallel remote_sort retry_data_expire retry_interval_max return_path_remove return_size_limit rfc1413_hosts rfc1413_query_timeout security sender_address_relay sender_address_relay_hosts sender_reject sender_reject_recipients sender_try_verify sender_unqualified_hosts sender_verify sender_verify_batch sender_verify_callback_domains sender_verify_callback_timeout sender_verify_fixup sender_verify_hosts sender_verify_hosts_callback sender_verify_max_retry_rate sender_verify_reject smtp_accept_keepalive smtp_accept_max smtp_accept_max_per_host smtp_accept_queue smtp_accept_queue_per_connection smtp_accept_reserve smtp_banner smtp_check_spool_space smtp_connect_backlog smtp_etrn_command smtp_etrn_hosts smtp_etrn_serialize smtp_expn_hosts smtp_load_reserve smtp_receive_timeout smtp_reserve_hosts smtp_verify split_spool_directory spool_directory strip_excess_angle_brackets strip_trailing_dot syslog_timestamp timeout_frozen_after timestamps_utc timezone tls_advertise_hosts tls_certificate tls_dhparam tls_host_accept_relay tls_hosts tls_log_cipher tls_log_peerdn tls_privatekey tls_verify_certificates tls_verify_ciphers tls_verify_hosts trusted_groups trusted_users unknown_login unknown_username untrusted_set_
\ No newline at end of file
+syn keyword eximKeyword no_accept_8bitmime no_allow_mx_to_ip no_always_bcc no_auth_always_advertise no_collapse_source_routes no_delivery_date_remove no_dns_check_names no_envelope_to_remove no_extract_addresses_remove_arguments no_forbid_domain_literals no_freeze_tell_mailmaster no_headers_check_syntax no_headers_checks_fail no_headers_sender_verify no_headers_sender_verify_errmsg no_helo_strict_syntax no_ignore_errmsg_errors no_ignore_fromline_local no_kill_ip_options no_local_domains_include_host no_local_domains_include_host_literals no_local_from_check no_locally_caseless no_log_all_parents no_log_arguments no_log_incoming_port no_log_ip_options no_log_received_recipients no_log_received_sender no_log_refused_recipients no_log_rewrites no_log_sender_on_delivery no_log_smtp_confirmation no_log_smtp_connections no_log_smtp_syntax_errors no_log_subject no_message_size_limit_count_recipients no_move_frozen_messages no_preserve_message_logs no_print_topbitchars no_prod_requires_admin no_queue_list_requires_admin no_queue_only no_rbl_log_headers no_rbl_log_rcpt_count no_rbl_reject_recipients no_receiver_try_verify no_receiver_verify no_recipients_max_reject no_refuse_ip_options no_relay_domains_include_local_mx no_relay_match_host_or_sender no_return_path_remove no_sender_try_verify no_sender_verify no_sender_verify_batch no_sender_verify_fixup no_sender_verify_reject no_smtp_accept_keepalive no_smtp_check_spool_space no_smtp_etrn_serialize no_smtp_verify no_split_spool_directory no_strip_excess_angle_brackets no_strip_trailing_dot no_syslog_timestamp no_timestamps_utc no_tls_log_cipher no_tls_log_peerdn no_untrusted_set_sender
+syn keyword eximKeyword not_accept_8bitmime not_allow_mx_to_ip not_always_bcc not_auth_always_advertise not_collapse_source_routes not_delivery_date_remove not_dns_check_names not_envelope_to_remove not_extract_addresses_remove_arguments not_forbid_domain_literals not_freeze_tell_mailmaster not_headers_check_syntax not_headers_checks_fail not_headers_sender_verify not_headers_sender_verify_errmsg not_helo_strict_syntax not_ignore_errmsg_errors not_ignore_fromline_local not_kill_ip_options not_local_domains_include_host not_local_domains_include_host_literals not_local_from_check not_locally_caseless not_log_all_parents not_log_arguments not_log_incoming_port not_log_ip_options not_log_received_recipients not_log_received_sender not_log_refused_recipients not_log_rewrites not_log_sender_on_delivery not_log_smtp_confirmation not_log_smtp_connections not_log_smtp_syntax_errors not_log_subject not_message_size_limit_count_recipients not_move_frozen_messages not_preserve_message_logs not_print_topbitchars not_prod_requires_admin not_queue_list_requires_admin not_queue_only not_rbl_log_headers not_rbl_log_rcpt_count not_rbl_reject_recipients not_receiver_try_verify not_receiver_verify not_recipients_max_reject not_refuse_ip_options not_relay_domains_include_local_mx not_relay_match_host_or_sender not_return_path_remove not_sender_try_verify not_sender_verify not_sender_verify_batch not_sender_verify_fixup not_sender_verify_reject not_smtp_accept_keepalive not_smtp_check_spool_space not_smtp_etrn_serialize not_smtp_verify not_split_spool_directory not_strip_excess_angle_brackets not_strip_trailing_dot not_syslog_timestamp not_timestamps_utc not_tls_log_cipher not_tls_log_peerdn not_untrusted_set_sender
+syn keyword eximKeyword body_only debug_print delivery_date_add driver envelope_to_add headers_add headers_only headers_remove headers_rewrite message_size_limit return_path return_path_add shadow_condition shadow_transport transport_filter
+syn keyword eximKeyword no_body_only no_delivery_date_add no_envelope_to_add no_headers_only no_return_path_add
+syn keyword eximKeyword not_body_only not_delivery_date_add not_envelope_to_add not_headers_only not_return_path_add
+syn keyword eximKeyword allow_fifo allow_symlink batch batch_max bsmtp bsmtp_helo check_group check_owner check_string create_directory create_file current_directory directory directory_mode escape_string file file_format file_must_exist from_hack group lock_fcntl_timeout lock_interval lock_retries lockfile_mode lockfile_timeout maildir_format maildir_retries maildir_tag mailstore_format mailstore_prefix mailstore_suffix mbx_format mode mode_fail_narrower notify_comsat prefix quota quota_filecount quota_is_inclusive quota_size_regex quota_warn_message quota_warn_threshold require_lockfile retry_use_local_part suffix use_crlf use_fcntl_lock use_lockfile use_mbx_lock user
+syn keyword eximKeyword no_allow_fifo no_allow_symlink no_bsmtp_helo no_check_group no_check_owner no_create_directory no_file_must_exist no_from_hack no_maildir_format no_mailstore_format no_mbx_format no_mode_fail_narrower no_notify_comsat no_quota_is_inclusive no_require_lockfile no_retry_use_local_part no_use_crlf no_use_fcntl_lock no_use_lockfile no_use_mbx_lock
+syn keyword eximKeyword not_allow_fifo not_allow_symlink not_bsmtp_helo not_check_group not_check_owner not_create_directory not_file_must_exist not_from_hack not_maildir_format not_mailstore_format not_mbx_format not_mode_fail_narrower not_notify_comsat not_quota_is_inclusive not_require_lockfile not_retry_use_local_part not_use_crlf not_use_fcntl_lock not_use_lockfile not_use_mbx_lock
+syn keyword eximKeyword bcc cc file file_expand file_optional from group headers initgroups log mode once once_file_size once_repeat reply_to return_message subject text to user
+syn keyword eximKeyword no_file_expand no_file_optional no_initgroups no_return_message
+syn keyword eximKeyword not_file_expand not_file_optional not_initgroups not_return_message
+syn keyword eximKeyword batch batch_max command group initgroups retry_use_local_part timeout user
+syn keyword eximKeyword no_initgroups
+syn keyword eximKeyword not_initgroups
+syn keyword eximKeyword allow_commands batch batch_max bsmtp bsmtp_helo check_string command current_directory environment escape_string freeze_exec_fail from_hack group home_directory ignore_status initgroups log_defer_output log_fail_output log_output max_output path pipe_as_creator prefix restrict_to_path retry_use_local_part return_fail_output return_output suffix temp_errors timeout umask use_crlf use_shell user
+syn keyword eximKeyword no_bsmtp_helo no_freeze_exec_fail no_from_hack no_ignore_status no_log_defer_output no_log_fail_output no_log_output no_pipe_as_creator no_restrict_to_path no_return_fail_output no_return_output no_use_crlf no_use_shell
+syn keyword eximKeyword not_bsmtp_helo not_freeze_exec_fail not_from_hack not_ignore_status not_log_defer_output not_log_fail_output not_log_output not_pipe_as_creator not_restrict_to_path not_return_fail_output not_return_output not_use_crlf not_use_shell
+syn keyword eximKeyword allow_localhost authenticate_hosts batch_max command_timeout connect_timeout data_timeout delay_after_cutoff dns_qualify_single dns_search_parents fallback_hosts final_timeout gethostbyname helo_data hosts hosts_avoid_tls hosts_require_tls hosts_override hosts_max_try hosts_randomize interface keepalive max_rcpt multi_domain mx_domains port protocol retry_include_ip_address serialize_hosts service size_addition tls_certificate tls_privatekey tls_verify_certificates tls_verify_ciphers
+syn keyword eximKeyword no_allow_localhost no_delay_after_cutoff no_dns_qualify_single no_dns_search_parents no_gethostbyname no_hosts_override no_hosts_randomize no_keepalive no_multi_domain no_retry_include_ip_address
+syn keyword eximKeyword not_allow_localhost not_delay_after_cutoff not_dns_qualify_single not_dns_search_parents not_gethostbyname not_hosts_override not_hosts_randomize not_keepalive not_multi_domain not_retry_include_ip_address
+syn keyword eximKeyword condition debug_print domains driver errors_to fail_verify fail_verify_recipient fail_verify_sender fallback_hosts group headers_add headers_remove initgroups local_parts more require_files senders transport unseen user verify verify_only verify_recipient verify_sender
+syn keyword eximKeyword no_fail_verify no_fail_verify_recipient no_fail_verify_sender no_initgroups no_more no_unseen no_verify no_verify_only no_verify_recipient no_verify_sender
+syn keyword eximKeyword not_fail_verify not_fail_verify_recipient not_fail_verify_sender not_initgroups not_more not_unseen not_verify not_verify_only not_verify_recipient not_verify_sender
+syn keyword eximKeyword current_directory expn home_directory new_director prefix prefix_optional suffix suffix_optional
+syn keyword eximKeyword no_expn no_prefix_optional no_suffix_optional
+syn keyword eximKeyword not_expn not_prefix_optional not_suffix_optional
+syn keyword eximKeyword check_ancestor directory_transport directory2_transport file_transport forbid_file forbid_include forbid_pipe freeze_missing_include hide_child_in_errmsg modemask one_time owners owngroups pipe_transport qualify_preserve_domain rewrite skip_syntax_errors syntax_errors_text syntax_errors_to
+syn keyword eximKeyword no_check_ancestor no_forbid_file no_forbid_include no_forbid_pipe no_freeze_missing_include no_hide_child_in_errmsg no_one_time no_qualify_preserve_domain no_rewrite no_skip_syntax_errors
+syn keyword eximKeyword not_check_ancestor not_forbid_file not_forbid_include not_forbid_pipe not_freeze_missing_include not_hide_child_in_errmsg not_one_time not_qualify_preserve_domain not_rewrite not_skip_syntax_errors
+syn keyword eximKeyword expand file forbid_special include_domain optional queries query search_type
+syn keyword eximKeyword no_expand no_forbid_special no_include_domain no_optional
+syn keyword eximKeyword not_expand not_forbid_special not_include_domain not_optional
+syn keyword eximKeyword allow_system_actions check_group check_local_user data file file_directory filter forbid_filter_existstest forbid_filter_logwrite forbid_filter_lookup forbid_filter_perl forbid_filter_reply ignore_eacces ignore_enotdir match_directory reply_transport seteuid
+syn keyword eximKeyword no_allow_system_actions no_check_local_user no_forbid_filter_reply no_forbid_filter_existstest no_forbid_filter_logwrite no_forbid_filter_lookup no_forbid_filter_perl no_forbid_filter_reply no_ignore_eacces no_ignore_enotdir no_seteuid
+syn keyword eximKeyword not_allow_system_actions not_check_local_user not_forbid_filter_reply not_forbid_filter_existstest not_forbid_filter_logwrite not_forbid_filter_lookup not_forbid_filter_perl not_forbid_filter_reply not_ignore_eacces not_ignore_enotdir not_seteuid
+syn keyword eximKeyword match_directory
+syn keyword eximKeyword directory_transport directory2_transport file_transport forbid_file forbid_pipe hide_child_in_errmsg new_address panic_expansion_fail pipe_transport qualify_preserve_domain rewrite
+syn keyword eximKeyword no_forbid_file no_forbid_pipe no_hide_child_in_errmsg no_panic_expansion_fail no_qualify_preserve_domain no_rewrite
+syn keyword eximKeyword not_forbid_file not_forbid_pipe not_hide_child_in_errmsg not_panic_expansion_fail not_qualify_preserve_domain not_rewrite
+syn keyword eximKeyword ignore_target_hosts pass_on_timeout self translate_ip_address
+syn keyword eximKeyword no_pass_on_timeout
+syn keyword eximKeyword not_pass_on_timeout
+syn keyword eximKeyword host_find_failed hosts_randomize modemask owners owngroups qualify_single route_file route_list route_queries route_query search_parents search_type
+syn keyword eximKeyword no_hosts_randomize no_qualify_single no_search_parents
+syn keyword eximKeyword not_hosts_randomize not_qualify_single not_search_parents
+syn keyword eximKeyword hosts optional port protocol query reroute response_pattern service timeout
+syn keyword eximKeyword no_optional
+syn keyword eximKeyword not_optional
+syn keyword eximKeyword check_secondary_mx gethostbyname mx_domains qualify_single rewrite_headers search_parents widen_domains
+syn keyword eximKeyword no_check_secondary_mx no_gethostbyname no_qualify_single no_search_parents
+syn keyword eximKeyword not_check_secondary_mx not_gethostbyname not_qualify_single not_search_parents
+syn keyword eximKeyword command command_group command_user current_directory timeout
+syn keyword eximKeyword driver public_name server_set_id server_mail_auth_condition
+syn keyword eximKeyword server_prompts server_condition client_send
+syn keyword eximKeyword server_secret client_name client_secret
+
+" Define the default highlighting
+if version >= 508 || !exists("did_exim_syntax_inits")
+	if version < 508
+		let did_exim_syntax_inits = 1
+		command -nargs=+ HiLink hi link <args>
+	else
+		command -nargs=+ HiLink hi def link <args>
+	endif
+
+	HiLink eximComment Comment
+	HiLink eximFixme Todo
+	HiLink eximEnd Keyword
+	HiLink eximNumber Number
+	HiLink eximDriverName Constant
+	HiLink eximConstant Constant
+	HiLink eximTime Constant
+	HiLink eximKeyword Type
+	HiLink eximSpecialChar Special
+	HiLink eximMacroName Preproc
+	HiLink eximTransport Identifier
+
+	delcommand HiLink
+endif
+
+let b:current_syntax = "exim"
--- /dev/null
+++ b/lib/vimfiles/syntax/expect.vim
@@ -1,0 +1,113 @@
+" Vim syntax file
+" Language:	Expect
+" Maintainer:	Ralph Jennings <knowbudy@oro.net>
+" Last Change:	2001 May 09
+
+" For version 5.x: Clear all syntax items
+" For version 6.x: Quit when a syntax file was already loaded
+if version < 600
+  syntax clear
+elseif exists("b:current_syntax")
+  finish
+endif
+
+" Reserved Expect variable prefixes.
+syn match   expectVariables "\$exp[a-zA-Z0-9_]*\|\$inter[a-zA-Z0-9_]*"
+syn match   expectVariables "\$spawn[a-zA-Z0-9_]*\|\$timeout[a-zA-Z0-9_]*"
+
+" Normal Expect variables.
+syn match   expectVariables "\$env([^)]*)"
+syn match   expectVariables "\$any_spawn_id\|\$argc\|\$argv\d*"
+syn match   expectVariables "\$user_spawn_id\|\$spawn_id\|\$timeout"
+
+" Expect variable arrays.
+syn match   expectVariables "\$\(expect\|interact\)_out([^)]*)"			contains=expectOutVar
+
+" User defined variables.
+syn match   expectVariables "\$[a-zA-Z_][a-zA-Z0-9_]*"
+
+" Reserved Expect command prefixes.
+syn match   expectCommand    "exp_[a-zA-Z0-9_]*"
+
+" Normal Expect commands.
+syn keyword expectStatement	close debug disconnect
+syn keyword expectStatement	exit exp_continue exp_internal exp_open
+syn keyword expectStatement	exp_pid exp_version
+syn keyword expectStatement	fork inter_return interpreter
+syn keyword expectStatement	log_file log_user match_max overlay
+syn keyword expectStatement	parity remove_nulls return
+syn keyword expectStatement	send send_error send_log send_user
+syn keyword expectStatement	sleep spawn strace stty system
+syn keyword expectStatement	timestamp trace trap wait
+
+" Tcl commands recognized and used by Expect.
+syn keyword expectCommand		proc
+syn keyword expectConditional	if else
+syn keyword expectRepeat		while for foreach
+
+" Expect commands with special arguments.
+syn keyword expectStatement	expect expect_after expect_background			nextgroup=expectExpectOpts
+syn keyword expectStatement	expect_before expect_user interact			nextgroup=expectExpectOpts
+
+syn match   expectSpecial contained  "\\."
+
+" Options for "expect", "expect_after", "expect_background",
+" "expect_before", "expect_user", and "interact".
+syn keyword expectExpectOpts	default eof full_buffer null return timeout
+
+syn keyword expectOutVar  contained  spawn_id seconds seconds_total
+syn keyword expectOutVar  contained  string start end buffer
+
+" Numbers (Tcl style).
+syn case ignore
+  syn match  expectNumber	"\<\d\+\(u\=l\=\|lu\|f\)\>"
+  "floating point number, with dot, optional exponent
+  syn match  expectNumber	"\<\d\+\.\d*\(e[-+]\=\d\+\)\=[fl]\=\>"
+  "floating point number, starting with a dot, optional exponent
+  syn match  expectNumber	"\.\d\+\(e[-+]\=\d\+\)\=[fl]\=\>"
+  "floating point number, without dot, with exponent
+  syn match  expectNumber	"\<\d\+e[-+]\=\d\+[fl]\=\>"
+  "hex number
+  syn match  expectNumber	"0x[0-9a-f]\+\(u\=l\=\|lu\)\>"
+  "syn match  expectIdentifier	"\<[a-z_][a-z0-9_]*\>"
+syn case match
+
+syn region  expectString	start=+"+  end=+"+  contains=expectVariables,expectSpecial
+
+" Are these really comments in Expect? (I never use it, so I'm just guessing).
+syn keyword expectTodo		contained TODO
+syn match   expectComment		"#.*$" contains=expectTodo
+
+" Define the default highlighting.
+" For version 5.7 and earlier: only when not done already
+" For version 5.8 and later: only when an item doesn't have highlighting yet
+if version >= 508 || !exists("did_expect_syntax_inits")
+  if version < 508
+    let did_expect_syntax_inits = 1
+    command -nargs=+ HiLink hi link <args>
+  else
+    command -nargs=+ HiLink hi def link <args>
+  endif
+
+  HiLink expectVariables	Special
+  HiLink expectCommand		Function
+  HiLink expectStatement	Statement
+  HiLink expectConditional	Conditional
+  HiLink expectRepeat		Repeat
+  HiLink expectExpectOpts	Keyword
+  HiLink expectOutVar		Special
+  HiLink expectSpecial		Special
+  HiLink expectNumber		Number
+
+  HiLink expectString		String
+
+  HiLink expectComment		Comment
+  HiLink expectTodo		Todo
+  "HiLink expectIdentifier	Identifier
+
+  delcommand HiLink
+endif
+
+let b:current_syntax = "expect"
+
+" vim: ts=8
--- /dev/null
+++ b/lib/vimfiles/syntax/exports.vim
@@ -1,0 +1,70 @@
+" Vim syntax file
+" Language:	exports
+" Maintainer:	Dr. Charles E. Campbell, Jr. <NdrOchipS@PcampbellAfamily.Mbiz>
+" Last Change:	Sep 06, 2005
+" Version:	4
+" Notes:		This file includes both SysV and BSD 'isms
+" URL:	http://mysite.verizon.net/astronaut/vim/index.html#vimlinks_syntax
+
+" For version 5.x: Clear all syntax items
+" For version 6.x: Quit when a syntax file was already loaded
+if version < 600
+  syntax clear
+elseif exists("b:current_syntax")
+  finish
+endif
+
+" Options: -word
+syn keyword exportsKeyOptions contained	alldirs	nohide	ro	wsync
+syn keyword exportsKeyOptions contained	kerb	o	rw
+syn match exportsOptError contained	"[a-z]\+"
+
+" Settings: word=
+syn keyword exportsKeySettings contained	access	anon	root	rw
+syn match exportsSetError contained	"[a-z]\+"
+
+" OptSet: -word=
+syn keyword exportsKeyOptSet contained	mapall	maproot	mask	network
+syn match exportsOptSetError contained	"[a-z]\+"
+
+" options and settings
+syn match exportsSettings	"[a-z]\+="  contains=exportsKeySettings,exportsSetError
+syn match exportsOptions	"-[a-z]\+"  contains=exportsKeyOptions,exportsOptError
+syn match exportsOptSet	"-[a-z]\+=" contains=exportsKeyOptSet,exportsOptSetError
+
+" Separators
+syn match exportsSeparator	"[,:]"
+
+" comments
+syn match exportsComment	"^\s*#.*$"	contains=@Spell
+
+" Define the default highlighting.
+" For version 5.7 and earlier: only when not done already
+" For version 5.8 and later: only when an item doesn't have highlighting yet
+if version >= 508 || !exists("did_exports_syntax_inits")
+  if version < 508
+    let did_exports_syntax_inits = 1
+    command -nargs=+ HiLink hi link <args>
+  else
+    command -nargs=+ HiLink hi def link <args>
+  endif
+
+  HiLink exportsKeyOptSet	exportsKeySettings
+  HiLink exportsOptSet	exportsSettings
+
+  HiLink exportsComment	Comment
+  HiLink exportsKeyOptions	Type
+  HiLink exportsKeySettings	Keyword
+  HiLink exportsOptions	Constant
+  HiLink exportsSeparator	Constant
+  HiLink exportsSettings	Constant
+
+  HiLink exportsOptError	Error
+  HiLink exportsOptSetError	Error
+  HiLink exportsSetError	Error
+
+  delcommand HiLink
+endif
+
+let b:current_syntax = "exports"
+" vim: ts=10
--- /dev/null
+++ b/lib/vimfiles/syntax/fasm.vim
@@ -1,0 +1,145 @@
+" Vim syntax file
+" Language:	Flat Assembler (FASM)
+" Maintainer:	Ron Aaron <ron@ronware.org>
+" Last Change:	2004 May 16
+" Vim URL:	http://www.vim.org/lang.html
+" FASM Home:	http://flatassembler.net/
+" FASM Version: 1.52
+
+if version < 600
+  syntax clear
+elseif exists("b:current_syntax")
+  finish
+endif
+
+setlocal iskeyword=a-z,A-Z,48-57,.,_
+setlocal isident=a-z,A-Z,48-57,.,_
+syn case ignore
+
+syn keyword fasmRegister	ah al ax bh bl bp bx ch cl cr0 cr1 cr2 cr3 cr4 cr5 cr6
+syn keyword fasmRegister	cr7 cs cx dh di dl dr0 dr1 dr2 dr3 dr4 dr5 dr6 dr7 ds dx
+syn keyword fasmRegister	eax ebp ebx ecx edi edx es esi esp fs gs mm0 mm1 mm2 mm3
+syn keyword fasmRegister	mm4 mm5 mm6 mm7 si sp ss st st0 st1 st2 st3 st4 st5 st6
+syn keyword fasmRegister	st7 tr0 tr1 tr2 tr3 tr4 tr5 tr6 tr7 xmm0 xmm1 xmm2 xmm3
+syn keyword fasmRegister	xmm4 xmm5 xmm6 xmm7
+syn keyword fasmAddressSizes 	byte dqword dword fword pword qword tword word
+syn keyword fasmDataDirectives 	db dd df dp dq dt du dw file rb rd rf rp rq rt rw
+syn keyword fasmInstr 	aaa aad aam aas adc add addpd addps addsd addss addsubpd
+syn keyword fasmInstr	addsubps and andnpd andnps andpd andps arpl bound bsf bsr
+syn keyword fasmInstr	bswap bt btc btr bts call cbw cdq clc cld clflush cli clts
+syn keyword fasmInstr	cmc cmova cmovae cmovb cmovbe cmovc cmove cmovg cmovge cmovl
+syn keyword fasmInstr	cmovle cmovna cmovnae cmovnb cmovnbe cmovnc cmovne cmovng
+syn keyword fasmInstr	cmovnge cmovnl cmovnle cmovno cmovnp cmovns cmovnz cmovo cmovp
+syn keyword fasmInstr	cmovpe cmovpo cmovs cmovz cmp cmpeqpd cmpeqps cmpeqsd cmpeqss
+syn keyword fasmInstr	cmplepd cmpleps cmplesd cmpless cmpltpd cmpltps cmpltsd cmpltss
+syn keyword fasmInstr	cmpneqpd cmpneqps cmpneqsd cmpneqss cmpnlepd cmpnleps cmpnlesd
+syn keyword fasmInstr	cmpnless cmpnltpd cmpnltps cmpnltsd cmpnltss cmpordpd cmpordps
+syn keyword fasmInstr	cmpordsd cmpordss cmppd cmpps cmps cmpsb cmpsd cmpss cmpsw
+syn keyword fasmInstr	cmpunordpd cmpunordps cmpunordsd cmpunordss cmpxchg cmpxchg8b
+syn keyword fasmInstr	comisd comiss cpuid cvtdq2pd cvtdq2ps cvtpd2dq cvtpd2pi cvtpd2ps
+syn keyword fasmInstr	cvtpi2pd cvtpi2ps cvtps2dq cvtps2pd cvtps2pi cvtsd2si cvtsd2ss
+syn keyword fasmInstr	cvtsi2sd cvtsi2ss cvtss2sd cvtss2si cvttpd2dq cvttpd2pi cvttps2dq
+syn keyword fasmInstr	cvttps2pi cvttsd2si cvttss2si cwd cwde daa das data dec div
+syn keyword fasmInstr	divpd divps divsd divss else emms end enter extrn f2xm1 fabs
+syn keyword fasmInstr	fadd faddp fbld fbstp fchs fclex fcmovb fcmovbe fcmove fcmovnb
+syn keyword fasmInstr	fcmovnbe fcmovne fcmovnu fcmovu fcom fcomi fcomip fcomp fcompp
+syn keyword fasmInstr	fcos fdecstp fdisi fdiv fdivp fdivr fdivrp femms feni ffree
+syn keyword fasmInstr	ffreep fiadd ficom ficomp fidiv fidivr fild fimul fincstp
+syn keyword fasmInstr	finit fist fistp fisttp fisub fisubr fld fld1 fldcw fldenv
+syn keyword fasmInstr	fldl2e fldl2t fldlg2 fldln2 fldpi fldz fmul fmulp fnclex fndisi
+syn keyword fasmInstr	fneni fninit fnop fnsave fnstcw fnstenv fnstsw fpatan fprem
+syn keyword fasmInstr	fprem1 fptan frndint frstor frstpm fsave fscale fsetpm fsin
+syn keyword fasmInstr	fsincos fsqrt fst fstcw fstenv fstp fstsw fsub fsubp fsubr
+syn keyword fasmInstr	fsubrp ftst fucom fucomi fucomip fucomp fucompp fwait fxam
+syn keyword fasmInstr	fxch fxrstor fxsave fxtract fyl2x fyl2xp1 haddpd haddps heap
+syn keyword fasmInstr	hlt hsubpd hsubps idiv if imul in inc ins insb insd insw int
+syn keyword fasmInstr	int3 into invd invlpg iret iretd iretw ja jae jb jbe jc jcxz
+syn keyword fasmInstr	je jecxz jg jge jl jle jmp jna jnae jnb jnbe jnc jne jng jnge
+syn keyword fasmInstr	jnl jnle jno jnp jns jnz jo jp jpe jpo js jz lahf lar lddqu
+syn keyword fasmInstr	ldmxcsr lds lea leave les lfence lfs lgdt lgs lidt lldt lmsw
+syn keyword fasmInstr	load loadall286 loadall386 lock lods lodsb lodsd lodsw loop
+syn keyword fasmInstr	loopd loope looped loopew loopne loopned loopnew loopnz loopnzd
+syn keyword fasmInstr	loopnzw loopw loopz loopzd loopzw lsl lss ltr maskmovdqu maskmovq
+syn keyword fasmInstr	maxpd maxps maxsd maxss mfence minpd minps minsd minss monitor
+syn keyword fasmInstr	mov movapd movaps movd movddup movdq2q movdqa movdqu movhlps
+syn keyword fasmInstr	movhpd movhps movlhps movlpd movlps movmskpd movmskps movntdq
+syn keyword fasmInstr	movnti movntpd movntps movntq movq movq2dq movs movsb movsd
+syn keyword fasmInstr	movshdup movsldup movss movsw movsx movupd movups movzx mul
+syn keyword fasmInstr	mulpd mulps mulsd mulss mwait neg nop not or org orpd orps
+syn keyword fasmInstr	out outs outsb outsd outsw packssdw packsswb packuswb paddb
+syn keyword fasmInstr	paddd paddq paddsb paddsw paddusb paddusw paddw pand pandn
+syn keyword fasmInstr	pause pavgb pavgusb pavgw pcmpeqb pcmpeqd pcmpeqw pcmpgtb
+syn keyword fasmInstr	pcmpgtd pcmpgtw pextrw pf2id pf2iw pfacc pfadd pfcmpeq pfcmpge
+syn keyword fasmInstr	pfcmpgt pfmax pfmin pfmul pfnacc pfpnacc pfrcp pfrcpit1 pfrcpit2
+syn keyword fasmInstr	pfrsqit1 pfrsqrt pfsub pfsubr pi2fd pi2fw pinsrw pmaddwd pmaxsw
+syn keyword fasmInstr	pmaxub pminsw pminub pmovmskb pmulhrw pmulhuw pmulhw pmullw
+syn keyword fasmInstr	pmuludq pop popa popad popaw popd popf popfd popfw popw por
+syn keyword fasmInstr	prefetch prefetchnta prefetcht0 prefetcht1 prefetcht2 prefetchw
+syn keyword fasmInstr	psadbw pshufd pshufhw pshuflw pshufw pslld pslldq psllq psllw
+syn keyword fasmInstr	psrad psraw psrld psrldq psrlq psrlw psubb psubd psubq psubsb
+syn keyword fasmInstr	psubsw psubusb psubusw psubw pswapd punpckhbw punpckhdq punpckhqdq
+syn keyword fasmInstr	punpckhwd punpcklbw punpckldq punpcklqdq punpcklwd push pusha
+syn keyword fasmInstr	pushad pushaw pushd pushf pushfd pushfw pushw pxor rcl rcpps
+syn keyword fasmInstr	rcpss rcr rdmsr rdpmc rdtsc rep repe repne repnz repz ret
+syn keyword fasmInstr	retd retf retfd retfw retn retnd retnw retw rol ror rsm rsqrtps
+syn keyword fasmInstr	rsqrtss sahf sal salc sar sbb scas scasb scasd scasw seta
+syn keyword fasmInstr	setae setalc setb setbe setc sete setg setge setl setle setna
+syn keyword fasmInstr	setnae setnb setnbe setnc setne setng setnge setnl setnle
+syn keyword fasmInstr	setno setnp setns setnz seto setp setpe setpo sets setz sfence
+syn keyword fasmInstr	sgdt shl shld shr shrd shufpd shufps sidt sldt smsw sqrtpd
+syn keyword fasmInstr	sqrtps sqrtsd sqrtss stc std sti stmxcsr store stos stosb
+syn keyword fasmInstr	stosd stosw str sub subpd subps subsd subss sysenter sysexit
+syn keyword fasmInstr	test ucomisd ucomiss ud2 unpckhpd unpckhps unpcklpd unpcklps
+syn keyword fasmInstr	verr verw wait wbinvd wrmsr xadd xchg xlat xlatb xor xorpd
+syn keyword fasmPreprocess 	common equ fix forward include local macro purge restore
+syn keyword fasmPreprocess	reverse struc
+syn keyword fasmDirective 	align binary code coff console discardable display dll
+syn keyword fasmDirective	elf entry executable export extern far fixups format gui
+syn keyword fasmDirective	import label ms mz native near notpageable pe public readable
+syn keyword fasmDirective	repeat resource section segment shareable stack times
+syn keyword fasmDirective	use16 use32 virtual wdm writeable
+syn keyword fasmOperator 	as at defined eq eqtype from mod on ptr rva used
+
+syn match	fasmNumericOperator	"[+-/*]"
+syn match	fasmLogicalOperator	"[=|&~<>]\|<=\|>=\|<>"
+" numbers
+syn match	fasmBinaryNumber	"\<[01]\+b\>"
+syn match	fasmHexNumber		"\<\d\x*h\>"
+syn match	fasmHexNumber		"\<\(0x\|$\)\x*\>"
+syn match	fasmFPUNumber		"\<\d\+\(\.\d*\)\=\(e[-+]\=\d*\)\=\>"
+syn match	fasmOctalNumber		"\<\(0\o\+o\=\|\o\+o\)\>"
+syn match	fasmDecimalNumber	"\<\(0\|[1-9]\d*\)\>"
+syn region	fasmComment		start=";" end="$"
+syn region	fasmString		start="\"" end="\"\|$"
+syn region	fasmString		start="'" end="'\|$"
+syn match	fasmSymbol		"[()|\[\]:]"
+syn match	fasmSpecial		"[#?%$,]"
+syn match	fasmLabel		"^\s*[^; \t]\+:"
+
+hi def link	fasmAddressSizes	type
+hi def link	fasmNumericOperator	fasmOperator
+hi def link	fasmLogicalOperator	fasmOperator
+
+hi def link	fasmBinaryNumber	fasmNumber
+hi def link	fasmHexNumber		fasmNumber
+hi def link	fasmFPUNumber		fasmNumber
+hi def link	fasmOctalNumber		fasmNumber
+hi def link	fasmDecimalNumber	fasmNumber
+
+hi def link	fasmSymbols		fasmRegister
+hi def link	fasmPreprocess		fasmDirective
+
+"  link to standard syn groups so the 'colorschemes' work:
+hi def link	fasmOperator operator
+hi def link	fasmComment  comment
+hi def link	fasmDirective	preproc
+hi def link	fasmRegister  type
+hi def link	fasmNumber   constant
+hi def link	fasmSymbol structure
+hi def link	fasmString  String
+hi def link	fasmSpecial	special
+hi def link	fasmInstr keyword
+hi def link	fasmLabel label
+hi def link	fasmPrefix preproc
+let b:current_syntax = "fasm"
+" vim: ts=8 sw=8 :
--- /dev/null
+++ b/lib/vimfiles/syntax/fdcc.vim
@@ -1,0 +1,114 @@
+" Vim syntax file
+" Language:	fdcc or locale files
+" Maintainer:	Dwayne Bailey <dwayne@translate.org.za>
+" Last Change:	2004 May 16
+" Remarks:      FDCC (Formal Definitions of Cultural Conventions) see ISO TR 14652
+
+" For version 5.x: Clear all syntax items
+" For version 6.x: Quit when a syntax file was already loaded
+if version < 600
+  syntax clear
+elseif exists("b:current_syntax")
+  finish
+endif
+
+syn sync minlines=150
+setlocal iskeyword+=-
+
+" Numbers
+syn match fdccNumber /[0-9]*/ contained
+
+" Unicode codings and strings
+syn match fdccUnicodeInValid /<[^<]*>/ contained
+syn match fdccUnicodeValid /<U[0-9A-F][0-9A-F][0-9A-F][0-9A-F]>/ contained
+syn region fdccString start=/"/ end=/"/ contains=fdccUnicodeInValid,fdccUnicodeValid
+
+" Valid LC_ Keywords
+syn keyword fdccKeyword escape_char comment_char
+syn keyword fdccKeywordIdentification title source address contact email tel fax language territory revision date category
+syn keyword fdccKeywordCtype copy space translit_start include translit_end outdigit class
+syn keyword fdccKeywordCollate copy script order_start order_end collating-symbol reorder-after reorder-end collating-element symbol-equivalence
+syn keyword fdccKeywordMonetary copy int_curr_symbol currency_symbol mon_decimal_point mon_thousands_sep mon_grouping positive_sign negative_sign int_frac_digits frac_digits p_cs_precedes p_sep_by_space n_cs_precedes n_sep_by_space p_sign_posn n_sign_posn int_p_cs_precedes int_p_sep_by_space int_n_cs_precedes int_n_sep_by_space  int_p_sign_posn int_n_sign_posn
+syn keyword fdccKeywordNumeric copy decimal_point thousands_sep grouping
+syn keyword fdccKeywordTime copy abday day abmon mon d_t_fmt d_fmt t_fmt am_pm t_fmt_ampm date_fmt era_d_fmt first_weekday first_workday week cal_direction time_zone era alt_digits era_d_t_fmt
+syn keyword fdccKeywordMessages copy yesexpr noexpr yesstr nostr
+syn keyword fdccKeywordPaper copy height width
+syn keyword fdccKeywordTelephone copy tel_int_fmt int_prefix tel_dom_fmt int_select
+syn keyword fdccKeywordMeasurement copy measurement
+syn keyword fdccKeywordName copy name_fmt name_gen name_mr name_mrs name_miss name_ms
+syn keyword fdccKeywordAddress copy postal_fmt country_name country_post country_ab2 country_ab3  country_num country_car  country_isbn lang_name lang_ab lang_term lang_lib
+
+" Comments
+syn keyword fdccTodo TODO FIXME contained
+syn match fdccVariable /%[a-zA-Z]/ contained
+syn match fdccComment /[#%].*/ contains=fdccTodo,fdccVariable
+
+" LC_ Groups
+syn region fdccBlank matchgroup=fdccLCIdentification start=/^LC_IDENTIFICATION$/ end=/^END LC_IDENTIFICATION$/ contains=fdccKeywordIdentification,fdccString,fdccComment
+syn region fdccBlank matchgroup=fdccLCCtype start=/^LC_CTYPE$/ end=/^END LC_CTYPE$/ contains=fdccKeywordCtype,fdccString,fdccComment,fdccUnicodeInValid,fdccUnicodeValid
+syn region fdccBlank matchgroup=fdccLCCollate start=/^LC_COLLATE$/ end=/^END LC_COLLATE$/ contains=fdccKeywordCollate,fdccString,fdccComment,fdccUnicodeInValid,fdccUnicodeValid
+syn region fdccBlank matchgroup=fdccLCMonetary start=/^LC_MONETARY$/ end=/^END LC_MONETARY$/ contains=fdccKeywordMonetary,fdccString,fdccComment,fdccNumber
+syn region fdccBlank matchgroup=fdccLCNumeric start=/^LC_NUMERIC$/ end=/^END LC_NUMERIC$/ contains=fdccKeywordNumeric,fdccString,fdccComment,fdccNumber
+syn region fdccBlank matchgroup=fdccLCTime start=/^LC_TIME$/ end=/^END LC_TIME$/ contains=fdccKeywordTime,fdccString,fdccComment,fdccNumber
+syn region fdccBlank matchgroup=fdccLCMessages start=/^LC_MESSAGES$/ end=/^END LC_MESSAGES$/ contains=fdccKeywordMessages,fdccString,fdccComment
+syn region fdccBlank matchgroup=fdccLCPaper start=/^LC_PAPER$/ end=/^END LC_PAPER$/ contains=fdccKeywordPaper,fdccString,fdccComment,fdccNumber
+syn region fdccBlank matchgroup=fdccLCTelephone start=/^LC_TELEPHONE$/ end=/^END LC_TELEPHONE$/ contains=fdccKeywordTelephone,fdccString,fdccComment
+syn region fdccBlank matchgroup=fdccLCMeasurement start=/^LC_MEASUREMENT$/ end=/^END LC_MEASUREMENT$/ contains=fdccKeywordMeasurement,fdccString,fdccComment,fdccNumber
+syn region fdccBlank matchgroup=fdccLCName start=/^LC_NAME$/ end=/^END LC_NAME$/ contains=fdccKeywordName,fdccString,fdccComment
+syn region fdccBlank matchgroup=fdccLCAddress start=/^LC_ADDRESS$/ end=/^END LC_ADDRESS$/ contains=fdccKeywordAddress,fdccString,fdccComment,fdccNumber
+
+
+" For version 5.7 and earlier: only when not done already
+" For version 5.8 and later: only when an item doesn't have highlighting yet
+if version >= 508 || !exists("did_fdcc_syn_inits")
+  if version < 508
+    let did_fdcc_syn_inits = 1
+    command -nargs=+ HiLink hi link <args>
+  else
+    command -nargs=+ HiLink hi def link <args>
+  endif
+
+  HiLink fdccBlank		 Blank
+
+  HiLink fdccTodo		 Todo
+  HiLink fdccComment		 Comment
+  HiLink fdccVariable		 Type
+
+  HiLink fdccLCIdentification	 Statement
+  HiLink fdccLCCtype		 Statement
+  HiLink fdccLCCollate		 Statement
+  HiLink fdccLCMonetary		 Statement
+  HiLink fdccLCNumeric		 Statement
+  HiLink fdccLCTime		 Statement
+  HiLink fdccLCMessages		 Statement
+  HiLink fdccLCPaper		 Statement
+  HiLink fdccLCTelephone	 Statement
+  HiLink fdccLCMeasurement	 Statement
+  HiLink fdccLCName		 Statement
+  HiLink fdccLCAddress		 Statement
+
+  HiLink fdccUnicodeInValid	 Error
+  HiLink fdccUnicodeValid	 String
+  HiLink fdccString		 String
+  HiLink fdccNumber		 Blank
+
+  HiLink fdccKeywordIdentification fdccKeyword
+  HiLink fdccKeywordCtype	   fdccKeyword
+  HiLink fdccKeywordCollate	   fdccKeyword
+  HiLink fdccKeywordMonetary	   fdccKeyword
+  HiLink fdccKeywordNumeric	   fdccKeyword
+  HiLink fdccKeywordTime	   fdccKeyword
+  HiLink fdccKeywordMessages	   fdccKeyword
+  HiLink fdccKeywordPaper	   fdccKeyword
+  HiLink fdccKeywordTelephone	   fdccKeyword
+  HiLink fdccKeywordMeasurement    fdccKeyword
+  HiLink fdccKeywordName	   fdccKeyword
+  HiLink fdccKeywordAddress	   fdccKeyword
+  HiLink fdccKeyword		   Identifier
+
+  delcommand HiLink
+endif
+
+let b:current_syntax = "fdcc"
+
+" vim: ts=8
--- /dev/null
+++ b/lib/vimfiles/syntax/fetchmail.vim
@@ -1,0 +1,75 @@
+" Vim syntax file
+" Language:         fetchmail(1) RC File
+" Maintainer:       Nikolai Weibull <now@bitwi.se>
+" Latest Revision:  2006-04-19
+
+if exists("b:current_syntax")
+  finish
+endif
+
+let s:cpo_save = &cpo
+set cpo&vim
+
+syn keyword fetchmailTodo       contained FIXME TODO XXX NOTE
+
+syn region  fetchmailComment    start='#' end='$' contains=fetchmailTodo,@Spell
+
+syn match   fetchmailNumber     display '\<\d\+\>'
+
+syn region  fetchmailString     start=+"+ skip=+\\\\\|\\"+ end=+"+
+                                \ contains=fetchmailStringEsc
+syn region  fetchmailString     start=+'+ skip=+\\\\\|\\'+ end=+'+
+                                \ contains=fetchmailStringEsc
+
+syn match   fetchmailStringEsc  contained '\\\([ntb]\|0\d*\|x\x\+\)'
+
+syn region  fetchmailKeyword    transparent matchgroup=fetchmailKeyword
+                                \ start='\<poll\|skip\|defaults\>'
+                                \ end='\<poll\|skip\|defaults\>'
+                                \ contains=ALLBUT,fetchmailOptions,fetchmailSet
+
+syn keyword fetchmailServerOpts contained via proto[col] local[domains] port
+                                \ auth[enticate] timeout envelope qvirtual aka
+                                \ interface monitor plugin plugout dns
+                                \ checkalias uidl interval netsec principal
+                                \ esmtpname esmtppassword
+                                \ sslcertck sslcertpath sslfingerprint
+syn match   fetchmailServerOpts contained '\<no\_s\+\(envelope\|dns\|checkalias\|uidl\)'
+
+syn keyword fetchmailUserOpts   contained user[name] is to pass[word] ssl
+                                \ sslcert sslkey sslproto folder smtphost
+                                \ fetchdomains smtpaddress smtpname antispam
+                                \ mda bsmtp preconnect postconnect keep flush
+                                \ fetchall rewrite stripcr forcecr pass8bits
+                                \ dropstatus dropdelivered mimedecode idle
+                                \ limit warnings batchlimit fetchlimit expunge
+                                \ tracepolls properties
+syn match   fetchmailUserOpts   contained '\<no\_s\+\(keep\|flush\|fetchall\|rewrite\|stripcr\|forcecr\|pass8bits\|dropstatus\|dropdelivered\|mimedecode\|noidle\)'
+
+syn keyword fetchmailSpecial    contained here there
+
+syn keyword fetchmailNoise      and with has wants options
+syn match   fetchmailNoise      display '[:;,]'
+
+syn keyword fetchmailSet        nextgroup=fetchmailOptions skipwhite skipnl set
+
+syn keyword fetchmailOptions    daemon postmaster bouncemail spambounce logfile
+                                \ idfile syslog nosyslog properties
+syn match   fetchmailOptions    '\<no\_s\+\(bouncemail\|spambounce\)'
+
+hi def link fetchmailComment    Comment
+hi def link fetchmailTodo       Todo
+hi def link fetchmailNumber     Number
+hi def link fetchmailString     String
+hi def link fetchmailStringEsc  SpecialChar
+hi def link fetchmailKeyword    Keyword
+hi def link fetchmailServerOpts Identifier
+hi def link fetchmailUserOpts   Identifier
+hi def link fetchmailSpecial    Special
+hi def link fetchmailSet        Keyword
+hi def link fetchmailOptions    Identifier
+
+let b:current_syntax = "fetchmail"
+
+let &cpo = s:cpo_save
+unlet s:cpo_save
--- /dev/null
+++ b/lib/vimfiles/syntax/fgl.vim
@@ -1,0 +1,147 @@
+" Vim syntax file
+" Language:	Informix 4GL
+" Maintainer:	Rafal M. Sulejman <rms@poczta.onet.pl>
+" Update:	26 Sep 2002
+" Changes:
+" - Dynamic 4GL/FourJs/4GL 7.30 pseudo comment directives (Julian Bridle)
+" - Conditionally allow case insensitive keywords (Julian Bridle)
+"
+
+" For version 5.x: Clear all syntax items
+" For version 6.x: Quit when a syntax file was already loaded
+if version < 600
+  syntax clear
+elseif exists("b:current_syntax")
+  finish
+endif
+
+if exists("fgl_ignore_case")
+  syntax case ignore
+else
+  syntax case match
+endif
+syn keyword fglKeyword ABORT ABS ABSOLUTE ACCEPT ACCESS ACOS ADD AFTER ALL
+syn keyword fglKeyword ALLOCATE ALTER AND ANSI ANY APPEND ARG_VAL ARRAY ARR_COUNT
+syn keyword fglKeyword ARR_CURR AS ASC ASCENDING ASCII ASIN AT ATAN ATAN2 ATTACH
+syn keyword fglKeyword ATTRIBUTE ATTRIBUTES AUDIT AUTHORIZATION AUTO AUTONEXT AVERAGE AVG
+syn keyword fglKeyword BEFORE BEGIN BETWEEN BLACK BLINK BLUE BOLD BORDER BOTH BOTTOM
+syn keyword fglKeyword BREAK BUFFERED BY BYTE
+syn keyword fglKeyword CALL CASCADE CASE CHAR CHARACTER CHARACTER_LENGTH CHAR_LENGTH
+syn keyword fglKeyword CHECK CLASS_ORIGIN CLEAR CLIPPED CLOSE CLUSTER COLOR
+syn keyword fglKeyword COLUMN COLUMNS COMMAND COMMENT COMMENTS COMMIT COMMITTED
+syn keyword fglKeyword COMPOSITES COMPRESS CONCURRENT CONNECT CONNECTION
+syn keyword fglKeyword CONNECTION_ALIAS CONSTRAINED CONSTRAINT CONSTRAINTS CONSTRUCT
+syn keyword fglKeyword CONTINUE CONTROL COS COUNT CREATE CURRENT CURSOR CYAN
+syn keyword fglKeyword DATA DATABASE DATASKIP DATE DATETIME DAY DBA DBINFO DBSERVERNAME
+syn keyword fglKeyword DEALLOCATE DEBUG DEC DECIMAL DECLARE DEFAULT DEFAULTS DEFER
+syn keyword fglKeyword DEFERRED DEFINE DELETE DELIMITER DELIMITERS DESC DESCENDING
+syn keyword fglKeyword DESCRIBE DESCRIPTOR DETACH DIAGNOSTICS DIM DIRTY DISABLED
+syn keyword fglKeyword DISCONNECT DISPLAY DISTINCT DISTRIBUTIONS DO DORMANT DOUBLE
+syn keyword fglKeyword DOWN DOWNSHIFT DROP
+syn keyword fglKeyword EACH ELIF ELSE ENABLED END ENTRY ERROR ERRORLOG ERR_GET
+syn keyword fglKeyword ERR_PRINT ERR_QUIT ESC ESCAPE EVERY EXCEPTION EXCLUSIVE
+syn keyword fglKeyword EXEC EXECUTE EXISTS EXIT EXP EXPLAIN EXPRESSION EXTEND EXTENT
+syn keyword fglKeyword EXTERN EXTERNAL
+syn keyword fglKeyword F1 F10 F11 F12 F13 F14 F15 F16 F17 F18 F19 F2 F20 F21 F22 F23
+syn keyword fglKeyword F24 F25 F26 F27 F28 F29 F3 F30 F31 F32 F33 F34 F35 F36 F37 F38
+syn keyword fglKeyword F39 F4 F40 F41 F42 F43 F44 F45 F46 F47 F48 F49 F5 F50 F51 F52
+syn keyword fglKeyword F53 F54 F55 F56 F57 F58 F59 F6 F60 F61 F62 F63 F64 F7 F8 F9
+syn keyword fglKeyword FALSE FETCH FGL_GETENV FGL_KEYVAL FGL_LASTKEY FIELD FIELD_TOUCHED
+syn keyword fglKeyword FILE FILLFACTOR FILTERING FINISH FIRST FLOAT FLUSH FOR
+syn keyword fglKeyword FOREACH FOREIGN FORM FORMAT FORMONLY FORTRAN FOUND FRACTION
+syn keyword fglKeyword FRAGMENT FREE FROM FUNCTION GET_FLDBUF GLOBAL GLOBALS GO GOTO
+syn keyword fglKeyword GRANT GREEN GROUP HAVING HEADER HELP HEX HIDE HIGH HOLD HOUR
+syn keyword fglKeyword IDATA IF ILENGTH IMMEDIATE IN INCLUDE INDEX INDEXES INDICATOR
+syn keyword fglKeyword INFIELD INIT INITIALIZE INPUT INSERT INSTRUCTIONS INT INTEGER
+syn keyword fglKeyword INTERRUPT INTERVAL INTO INT_FLAG INVISIBLE IS ISAM ISOLATION
+syn keyword fglKeyword ITYPE
+syn keyword fglKeyword KEY LABEL
+syn keyword fglKeyword LANGUAGE LAST LEADING LEFT LENGTH LET LIKE LINE
+syn keyword fglKeyword LINENO LINES LOAD LOCATE LOCK LOG LOG10 LOGN LONG LOW
+syn keyword fglKeyword MAGENTA MAIN MARGIN MATCHES MAX MDY MEDIUM MEMORY MENU MESSAGE
+syn keyword fglKeyword MESSAGE_LENGTH MESSAGE_TEXT MIN MINUTE MOD MODE MODIFY MODULE
+syn keyword fglKeyword MONEY MONTH MORE
+syn keyword fglKeyword NAME NCHAR NEED NEW NEXT NEXTPAGE NO NOCR NOENTRY NONE NORMAL
+syn keyword fglKeyword NOT NOTFOUND NULL NULLABLE NUMBER NUMERIC NUM_ARGS NVARCHAR
+syn keyword fglKeyword OCTET_LENGTH OF OFF OLD ON ONLY OPEN OPTIMIZATION OPTION OPTIONS
+syn keyword fglKeyword OR ORDER OTHERWISE OUTER OUTPUT
+syn keyword fglKeyword PAGE PAGENO PAUSE PDQPRIORITY PERCENT PICTURE PIPE POW PRECISION
+syn keyword fglKeyword PREPARE PREVIOUS PREVPAGE PRIMARY PRINT PRINTER PRIOR PRIVATE
+syn keyword fglKeyword PRIVILEGES PROCEDURE PROGRAM PROMPT PUBLIC PUT
+syn keyword fglKeyword QUIT QUIT_FLAG
+syn keyword fglKeyword RAISE RANGE READ READONLY REAL RECORD RECOVER RED REFERENCES
+syn keyword fglKeyword REFERENCING REGISTER RELATIVE REMAINDER REMOVE RENAME REOPTIMIZATION
+syn keyword fglKeyword REPEATABLE REPORT REQUIRED RESOLUTION RESOURCE RESTRICT
+syn keyword fglKeyword RESUME RETURN RETURNED_SQLSTATE RETURNING REVERSE REVOKE RIGHT
+syn keyword fglKeyword ROBIN ROLE ROLLBACK ROLLFORWARD ROOT ROUND ROW ROWID ROWIDS
+syn keyword fglKeyword ROWS ROW_COUNT RUN
+syn keyword fglKeyword SCALE SCHEMA SCREEN SCROLL SCR_LINE SECOND SECTION SELECT
+syn keyword fglKeyword SERIAL SERIALIZABLE SERVER_NAME SESSION SET SET_COUNT SHARE
+syn keyword fglKeyword SHORT SHOW SITENAME SIZE SIZEOF SKIP SLEEP SMALLFLOAT SMALLINT
+syn keyword fglKeyword SOME SPACE SPACES SQL SQLAWARN SQLCA SQLCODE SQLERRD SQLERRM
+syn keyword fglKeyword SQLERROR SQLERRP SQLSTATE SQLWARNING SQRT STABILITY START
+syn keyword fglKeyword STARTLOG STATIC STATISTICS STATUS STDEV STEP STOP STRING STRUCT
+syn keyword fglKeyword SUBCLASS_ORIGIN SUM SWITCH SYNONYM SYSTEM
+syn keyword fglKeyword SysBlobs SysChecks SysColAuth SysColDepend SysColumns
+syn keyword fglKeyword SysConstraints SysDefaults SysDepend SysDistrib SysFragAuth
+syn keyword fglKeyword SysFragments SysIndexes SysObjState SysOpClstr SysProcAuth
+syn keyword fglKeyword SysProcBody SysProcPlan SysProcedures SysReferences SysRoleAuth
+syn keyword fglKeyword SysSynTable SysSynonyms SysTabAuth SysTables SysTrigBody
+syn keyword fglKeyword SysTriggers SysUsers SysViews SysViolations
+syn keyword fglKeyword TAB TABLE TABLES TAN TEMP TEXT THEN THROUGH THRU TIME TO
+syn keyword fglKeyword TODAY TOP TOTAL TRACE TRAILER TRAILING TRANSACTION TRIGGER
+syn keyword fglKeyword TRIGGERS TRIM TRUE TRUNC TYPE TYPEDEF
+syn keyword fglKeyword UNCOMMITTED UNCONSTRAINED UNDERLINE UNION UNIQUE UNITS UNLOAD
+syn keyword fglKeyword UNLOCK UNSIGNED UP UPDATE UPSHIFT USER USING
+syn keyword fglKeyword VALIDATE VALUE VALUES VARCHAR VARIABLES VARIANCE VARYING
+syn keyword fglKeyword VERIFY VIEW VIOLATIONS
+syn keyword fglKeyword WAIT WAITING WARNING WEEKDAY WHEN WHENEVER WHERE WHILE WHITE
+syn keyword fglKeyword WINDOW WITH WITHOUT WORDWRAP WORK WRAP WRITE
+syn keyword fglKeyword YEAR YELLOW
+syn keyword fglKeyword ZEROFILL
+
+" Strings and characters:
+syn region fglString		start=+"+  skip=+\\\\\|\\"+  end=+"+
+syn region fglString		start=+'+  skip=+\\\\\|\\"+  end=+'+
+
+" Numbers:
+syn match fglNumber		"-\=\<[0-9]*\.\=[0-9_]\>"
+
+" Comments:
+syn region fglComment    start="{"  end="}"
+syn match fglComment	"--.*"
+syn match fglComment	"#.*"
+
+" Not a comment even though it looks like one (Dynamic 4GL/FourJs directive)
+syn match fglSpecial	"--#"
+syn match fglSpecial	"--@"
+
+syn sync ccomment fglComment
+
+" Define the default highlighting.
+" For version 5.7 and earlier: only when not done already
+" For version 5.8 and later: only when an item doesn't have highlighting yet
+if version >= 508 || !exists("did_fgl_syntax_inits")
+  if version < 508
+    let did_fgl_syntax_inits = 1
+    command -nargs=+ HiLink hi link <args>
+  else
+    command -nargs=+ HiLink hi def link <args>
+  endif
+
+  HiLink fglComment	Comment
+  "HiLink fglKeyword	fglSpecial
+  HiLink fglKeyword	fglStatement
+  HiLink fglNumber	Number
+  HiLink fglOperator	fglStatement
+  HiLink fglSpecial	Special
+  HiLink fglStatement	Statement
+  HiLink fglString	String
+  HiLink fglType	Type
+
+  delcommand HiLink
+endif
+
+let b:current_syntax = "fgl"
+
+" vim: ts=8
--- /dev/null
+++ b/lib/vimfiles/syntax/flexwiki.vim
@@ -1,0 +1,135 @@
+" Vim syntax file
+" Language:     FlexWiki, http://www.flexwiki.com/
+" Maintainer:   George V. Reilly  <george@reilly.org>
+" Home:         http://www.georgevreilly.com/vim/flexwiki/
+" Other Home:   http://www.vim.org/scripts/script.php?script_id=1529
+" Author:       George V. Reilly
+" Filenames:    *.wiki
+" Last Change: Wed Apr 26 11:00 PM 2006 P
+" Version:      0.3
+
+" Note: The horrible regexps were reverse-engineered from
+" FlexWikiCore\EngineSource\Formatter.cs, with help from the Regex Analyzer
+" in The Regulator, http://regulator.sourceforge.net/  .NET uses Perl-style
+" regexes, which use a different syntax than Vim (fewer \s).
+" The primary test case is FlexWiki\FormattingRules.wiki
+
+" Quit if syntax file is already loaded
+if version < 600
+    syntax clear
+elseif exists("b:current_syntax")
+    finish
+endif
+
+" A WikiWord (unqualifiedWikiName)
+syntax match  flexwikiWord          /\%(_\?\([A-Z]\{2,}[a-z0-9]\+[A-Za-z0-9]*\)\|\([A-Z][a-z0-9]\+[A-Za-z0-9]*[A-Z]\+[A-Za-z0-9]*\)\)/
+" A [bracketed wiki word]
+syntax match  flexwikiWord          /\[[[:alnum:]\s]\+\]/
+
+" text: "this is a link (optional tooltip)":http://www.microsoft.com
+" TODO: check URL syntax against RFC
+syntax match flexwikiLink           `\("[^"(]\+\((\([^)]\+\))\)\?":\)\?\(https\?\|ftp\|gopher\|telnet\|file\|notes\|ms-help\):\(\(\(//\)\|\(\\\\\)\)\+[A-Za-z0-9:#@%/;$~_?+-=.&\-\\\\]*\)`
+
+" text: *strong* 
+syntax match flexwikiBold           /\(^\|\W\)\zs\*\([^ ].\{-}\)\*/
+" '''bold'''
+syntax match flexwikiBold           /'''\([^'].\{-}\)'''/
+
+" text: _emphasis_
+syntax match flexwikiItalic         /\(^\|\W\)\zs_\([^ ].\{-}\)_/
+" ''italic''
+syntax match flexwikiItalic         /''\([^'].\{-}\)''/
+
+" ``deemphasis``
+syntax match flexwikiDeEmphasis     /``\([^`].\{-}\)``/
+
+" text: @code@ 
+syntax match flexwikiCode           /\(^\|\s\|(\|\[\)\zs@\([^@]\+\)@/
+
+"   text: -deleted text- 
+syntax match flexwikiDelText        /\(^\|\s\+\)\zs-\([^ <a ]\|[^ <img ]\|[^ -].*\)-/
+
+"   text: +inserted text+ 
+syntax match flexwikiInsText        /\(^\|\W\)\zs+\([^ ].\{-}\)+/
+
+"   text: ^superscript^ 
+syntax match flexwikiSuperScript    /\(^\|\W\)\zs^\([^ ].\{-}\)^/
+
+"   text: ~subscript~ 
+syntax match flexwikiSubScript      /\(^\|\W\)\zs\~\([^ ].\{-}\)\~/
+
+"   text: ??citation?? 
+syntax match flexwikiCitation       /\(^\|\W\)\zs??\([^ ].\{-}\)??/
+
+" Emoticons: must come after the Textilisms, as later rules take precedence
+" over earlier ones. This match is an approximation for the ~70 distinct
+" patterns that FlexWiki knows.
+syntax match flexwikiEmoticons      /\((.)\|:[()|$@]\|:-[DOPS()\]|$@]\|;)\|:'(\)/
+
+" Aggregate all the regular text highlighting into flexwikiText
+syntax cluster flexwikiText contains=flexwikiItalic,flexwikiBold,flexwikiCode,flexwikiDeEmphasis,flexwikiDelText,flexwikiInsText,flexwikiSuperScript,flexwikiSubScript,flexwikiCitation,flexwikiLink,flexwikiWord,flexwikiEmoticons
+
+" single-line WikiPropertys
+syntax match flexwikiSingleLineProperty /^:\?[A-Z_][_a-zA-Z0-9]\+:/
+
+" TODO: multi-line WikiPropertys
+
+" Header levels, 1-6
+syntax match flexwikiH1             /^!.*$/
+syntax match flexwikiH2             /^!!.*$/
+syntax match flexwikiH3             /^!!!.*$/
+syntax match flexwikiH4             /^!!!!.*$/
+syntax match flexwikiH5             /^!!!!!.*$/
+syntax match flexwikiH6             /^!!!!!!.*$/
+
+" <hr>, horizontal rule
+syntax match flexwikiHR             /^----.*$/
+
+" Formatting can be turned off by ""enclosing it in pairs of double quotes""
+syntax match flexwikiEscape         /"".\{-}""/
+
+" Tables. Each line starts and ends with '||'; each cell is separated by '||'
+syntax match flexwikiTable          /||/
+
+" Bulleted list items start with one or tabs, followed by whitespace, then '*'
+" Numeric  list items start with one or tabs, followed by whitespace, then '1.'
+" Eight spaces at the beginning of the line is equivalent to the leading tab.
+syntax match flexwikiList           /^\(\t\| \{8}\)\s*\(\*\|1\.\).*$/   contains=@flexwikiText
+
+" Treat all other lines that start with spaces as PRE-formatted text.
+syntax match flexwikiPre            /^[ \t]\+[^ \t*1].*$/
+
+
+" Link FlexWiki syntax items to colors
+hi def link flexwikiH1                    Title
+hi def link flexwikiH2                    flexwikiH1
+hi def link flexwikiH3                    flexwikiH2
+hi def link flexwikiH4                    flexwikiH3
+hi def link flexwikiH5                    flexwikiH4
+hi def link flexwikiH6                    flexwikiH5
+hi def link flexwikiHR                    flexwikiH6
+    
+hi def flexwikiBold                       term=bold cterm=bold gui=bold
+hi def flexwikiItalic                     term=italic cterm=italic gui=italic
+
+hi def link flexwikiCode                  Statement
+hi def link flexwikiWord                  Underlined
+
+hi def link flexwikiEscape                Todo
+hi def link flexwikiPre                   PreProc
+hi def link flexwikiLink                  Underlined
+hi def link flexwikiList                  Type
+hi def link flexwikiTable                 Type
+hi def link flexwikiEmoticons             Constant
+hi def link flexwikiDelText               Comment
+hi def link flexwikiDeEmphasis            Comment
+hi def link flexwikiInsText               Constant
+hi def link flexwikiSuperScript           Constant
+hi def link flexwikiSubScript             Constant
+hi def link flexwikiCitation              Constant
+
+hi def link flexwikiSingleLineProperty    Identifier
+
+let b:current_syntax="FlexWiki"
+
+" vim:tw=0:
--- /dev/null
+++ b/lib/vimfiles/syntax/focexec.vim
@@ -1,0 +1,101 @@
+" Vim syntax file
+" Language:	Focus Executable
+" Maintainer:	Rob Brady <robb@datatone.com>
+" Last Change:	$Date: 2004/06/13 15:38:04 $
+" URL:		http://www.datatone.com/~robb/vim/syntax/focexec.vim
+" $Revision: 1.1 $
+
+" this is a very simple syntax file - I will be improving it
+" one thing is how to do computes
+" I don't like that &vars and FUSE() functions highlight to the same color
+" I think some of these things should get different hilights -
+"  should MODIFY commands look different than TABLE?
+
+" For version 5.x: Clear all syntax items
+" For version 6.x: Quit when a syntax file was already loaded
+if version < 600
+  syntax clear
+elseif exists("b:current_syntax")
+  finish
+endif
+
+syn case match
+
+" A bunch of useful keywords
+syn keyword focexecTable	TABLE SUM BY ACROSS END PRINT HOLD LIST NOPRINT
+syn keyword focexecTable	SUBFOOT SUBHEAD HEADING FOOTING PAGE-BREAK AS
+syn keyword focexecTable	WHERE AND OR NOSPLIT FORMAT
+syn keyword focexecModify	MODIFY DATA ON FIXFORM PROMPT MATCH COMPUTE
+syn keyword focexecModify	GOTO CASE ENDCASE TYPE NOMATCH REJECT INCLUDE
+syn keyword focexecModify	CONTINUE FROM
+syn keyword focexecNormal	CHECK FILE CREATE EX SET IF FILEDEF DEFINE
+syn keyword focexecNormal	REBUILD IF RECORDLIMIT FI EQ JOIN
+syn keyword focexecJoin		IN TO
+syn keyword focexecFileDef	DISK
+syn keyword focexecSet		MSG ALL
+syn match   focexecDash		"-RUN"
+syn match   focexecDash		"-PROMPT"
+syn match   focexecDash		"-WINFORM"
+
+" String and Character constants
+syn region  focexecString1	start=+"+ end=+"+
+syn region  focexecString2	start=+'+ end=+'+
+
+"amper variables
+syn match   focexecAmperVar	"&&\=[A-Z_]\+"
+
+"fuse functions
+syn keyword focexecFuse GETUSER GETUSR WHOAMI FEXERR ASIS GETTOK UPCASE LOCASE
+syn keyword focexecFuse SUBSTR TODAY TODAYI POSIT HHMMSS BYTVAL EDAUT1 BITVAL
+syn keyword focexecFuse BITSON FGETENV FPUTENV HEXBYT SPAWN YM YMI JULDAT
+syn keyword focexecFuse JULDATI DOWK DOWKI DOWKLI CHGDAT CHGDATI FTOA ATODBL
+syn keyword focexecFuse SOUNDEX RJUST REVERSE PARAG OVRLAY LJUST CTRFLD CTRAN
+syn keyword focexecFuse CHKFMT ARGLEN GREGDT GREGDTI DTYMD DTYMDI DTDMY DTDMYI
+syn keyword focexecFuse DTYDM DTYDMI DTMYD DTMYDI DTDYM DTDYMI DAYMD DAYMDI
+syn keyword focexecFuse DAMDY DAMDYI DADMY DADMYI AYM AYMI AYMD AYMDI CHKPCK
+syn keyword focexecFuse IMOD FMOD DMOD PCKOUT EXP BAR SPELLNM SPELLNUM RTCIVP
+syn keyword focexecFuse PRDUNI PRDNOR RDNORM RDUNIF LCWORD ITOZ RLPHLD IBIPRO
+syn keyword focexecFuse IBIPRW IBIPRC IBIPRU IBIRCP PTHDAT ITOPACK ITONUM
+syn keyword focexecFuse DSMEXEC DSMEVAL DSMERRC MSMEXEC MSMEVAL MSMERRC EXTDXI
+syn keyword focexecFuse BAANHASH EDAYSI DTOG GTOD HSETPT HPART HTIME HNAME
+syn keyword focexecFuse HADD HDIFF HDATE HGETC HCNVRT HDTTM HMIDNT TEMPPATH
+syn keyword focexecFuse DATEADD DATEDIF DATEMOV DATECVT EURHLD EURXCH FINDFOC
+syn keyword focexecFuse FERRMES CNCTUSR CURRPATH USERPATH SYSTEM ASKYN
+syn keyword focexecFuse FUSEMENU POPEDIT POPFILE
+
+syn match   focexecNumber	"\<\d\+\>"
+syn match   focexecNumber	"\<\d\+\.\d*\>"
+
+syn match   focexecComment	"-\*.*"
+
+" Define the default highlighting.
+" For version 5.7 and earlier: only when not done already
+" For version 5.8 and later: only when an item doesn't have highlighting yet
+if version >= 508 || !exists("did_focexec_syntax_inits")
+  if version < 508
+    let did_focexec_syntax_inits = 1
+    command -nargs=+ HiLink hi link <args>
+  else
+    command -nargs=+ HiLink hi def link <args>
+  endif
+
+  HiLink focexecString1		String
+  HiLink focexecString2		String
+  HiLink focexecNumber		Number
+  HiLink focexecComment		Comment
+  HiLink focexecTable		Keyword
+  HiLink focexecModify		Keyword
+  HiLink focexecNormal		Keyword
+  HiLink focexecSet		Keyword
+  HiLink focexecDash		Keyword
+  HiLink focexecFileDef		Keyword
+  HiLink focexecJoin		Keyword
+  HiLink focexecAmperVar	Identifier
+  HiLink focexecFuse		Function
+
+  delcommand HiLink
+endif
+
+let b:current_syntax = "focexec"
+
+" vim: ts=8
--- /dev/null
+++ b/lib/vimfiles/syntax/form.vim
@@ -1,0 +1,101 @@
+" Vim syntax file
+" Language:	FORM
+" Maintainer:	Michael M. Tung <michael.tung@uni-mainz.de>
+" Last Change:	2001 May 10
+
+" First public release based on 'Symbolic Manipulation with FORM'
+" by J.A.M. Vermaseren, CAN, Netherlands, 1991.
+" This syntax file is still in development. Please send suggestions
+" to the maintainer.
+
+" For version 5.x: Clear all syntax items
+" For version 6.x: Quit when a syntax file was already loaded
+if version < 600
+  syntax clear
+elseif exists("b:current_syntax")
+  finish
+endif
+
+syn case ignore
+
+" A bunch of useful FORM keywords
+syn keyword formType		global local
+syn keyword formHeaderStatement	symbol symbols cfunction cfunctions
+syn keyword formHeaderStatement	function functions vector vectors
+syn keyword formHeaderStatement	set sets index indices
+syn keyword formHeaderStatement	dimension dimensions unittrace
+syn keyword formStatement	id identify drop skip
+syn keyword formStatement	write nwrite
+syn keyword formStatement	format print nprint load save
+syn keyword formStatement	bracket brackets
+syn keyword formStatement	multiply count match only discard
+syn keyword formStatement	trace4 traceN contract symmetrize antisymmetrize
+syn keyword formConditional	if else endif while
+syn keyword formConditional	repeat endrepeat label goto
+
+" some special functions
+syn keyword formStatement	g_ gi_ g5_ g6_ g7_ 5_ 6_ 7_
+syn keyword formStatement	e_ d_ delta_ theta_ sum_ sump_
+
+" pattern matching for keywords
+syn match   formComment		"^\ *\*.*$"
+syn match   formComment		"\;\ *\*.*$"
+syn region  formString		start=+"+  end=+"+
+syn region  formString		start=+'+  end=+'+
+syn match   formPreProc		"^\=\#[a-zA-z][a-zA-Z0-9]*\>"
+syn match   formNumber		"\<\d\+\>"
+syn match   formNumber		"\<\d\+\.\d*\>"
+syn match   formNumber		"\.\d\+\>"
+syn match   formNumber		"-\d" contains=Number
+syn match   formNumber		"-\.\d" contains=Number
+syn match   formNumber		"i_\+\>"
+syn match   formNumber		"fac_\+\>"
+syn match   formDirective	"^\=\.[a-zA-z][a-zA-Z0-9]*\>"
+
+" hi User Labels
+syn sync ccomment formComment minlines=10
+
+" Define the default highlighting.
+" For version 5.7 and earlier: only when not done already
+" For version 5.8 and later: only when an item doesn't have highlighting yet
+if version >= 508 || !exists("did_form_syn_inits")
+  if version < 508
+    let did_form_syn_inits = 1
+    command -nargs=+ HiLink hi link <args>
+  else
+    command -nargs=+ HiLink hi def link <args>
+  endif
+
+  HiLink formConditional	Conditional
+  HiLink formNumber		Number
+  HiLink formStatement		Statement
+  HiLink formComment		Comment
+  HiLink formPreProc		PreProc
+  HiLink formDirective		PreProc
+  HiLink formType		Type
+  HiLink formString		String
+
+  if !exists("form_enhanced_color")
+    HiLink formHeaderStatement	Statement
+  else
+  " enhanced color mode
+    HiLink formHeaderStatement	HeaderStatement
+    " dark and a light background for local types
+    if &background == "dark"
+      hi HeaderStatement term=underline ctermfg=LightGreen guifg=LightGreen gui=bold
+    else
+      hi HeaderStatement term=underline ctermfg=DarkGreen guifg=SeaGreen gui=bold
+    endif
+    " change slightly the default for dark gvim
+    if has("gui_running") && &background == "dark"
+      hi Conditional guifg=LightBlue gui=bold
+      hi Statement guifg=LightYellow
+    endif
+  endif
+
+  delcommand HiLink
+endif
+
+  let b:current_syntax = "form"
+
+" vim: ts=8
--- /dev/null
+++ b/lib/vimfiles/syntax/forth.vim
@@ -1,0 +1,240 @@
+" Vim syntax file
+" Language:    FORTH
+" Maintainer:  Christian V. J. Br�ssow <cvjb@cvjb.de>
+" Last Change: Di 06 Jul 2004 18:40:33 CEST
+" Filenames:   *.fs,*.ft
+" URL:         http://www.cvjb.de/comp/vim/forth.vim
+
+" $Id: forth.vim,v 1.2 2004/07/10 09:40:55 vimboss Exp $
+
+" The list of keywords is incomplete, compared with the offical ANS
+" wordlist. If you use this language, please improve it, and send me
+" the patches.
+
+" Many Thanks to...
+"
+" 2004-07-06:
+" Changed "syn sync ccomment maxlines=200" line: splitted it into two separate
+" lines.
+"
+" 2003-05-10:
+" Andrew Gaul <andrew at gaul.org> send me a patch for
+" forthOperators.
+"
+" 2003-04-03:
+" Ron Aaron <ronaharon at yahoo.com> made updates for an
+" improved Win32Forth support.
+"
+" 2002-04-22:
+" Charles Shattuck <charley at forth.org> helped me to settle up with the
+" binary and hex number highlighting.
+"
+" 2002-04-20:
+" Charles Shattuck <charley at forth.org> send me some code for correctly
+" highlighting char and [char] followed by an opening paren. He also added
+" some words for operators, conditionals, and definitions; and added the
+" highlighting for s" and c".
+"
+" 2000-03-28:
+" John Providenza <john at probo.com> made improvements for the
+" highlighting of strings, and added the code for highlighting hex numbers.
+"
+
+
+" For version 5.x: Clear all syntax items
+" For version 6.x: Quit when a syntax file was already loaded
+if version < 600
+    syntax clear
+elseif exists("b:current_syntax")
+    finish
+endif
+
+" Synchronization method
+syn sync ccomment
+syn sync maxlines=200
+
+" I use gforth, so I set this to case ignore
+syn case ignore
+
+" Some special, non-FORTH keywords
+syn keyword forthTodo contained TODO FIXME XXX
+syn match forthTodo contained 'Copyright\(\s([Cc])\)\=\(\s[0-9]\{2,4}\)\='
+
+" Characters allowed in keywords
+" I don't know if 128-255 are allowed in ANS-FORHT
+if version >= 600
+    setlocal iskeyword=!,@,33-35,%,$,38-64,A-Z,91-96,a-z,123-126,128-255
+else
+    set iskeyword=!,@,33-35,%,$,38-64,A-Z,91-96,a-z,123-126,128-255
+endif
+
+
+" Keywords
+
+" basic mathematical and logical operators
+syn keyword forthOperators + - * / MOD /MOD NEGATE ABS MIN MAX
+syn keyword forthOperators AND OR XOR NOT INVERT 2* 2/ 1+ 1- 2+ 2- 8*
+syn keyword forthOperators M+ */ */MOD M* UM* M*/ UM/MOD FM/MOD SM/REM
+syn keyword forthOperators D+ D- DNEGATE DABS DMIN DMAX
+syn keyword forthOperators F+ F- F* F/ FNEGATE FABS FMAX FMIN FLOOR FROUND
+syn keyword forthOperators F** FSQRT FEXP FEXPM1 FLN FLNP1 FLOG FALOG FSIN
+syn keyword forthOperators FCOS FSINCOS FTAN FASIN FACOS FATAN FATAN2 FSINH
+syn keyword forthOperators FCOSH FTANH FASINH FACOSH FATANH
+syn keyword forthOperators 0< 0<= 0<> 0= 0> 0>= < <= <> = > >=
+syn keyword forthOperators ?NEGATE ?DNEGATE
+
+" stack manipulations
+syn keyword forthStack DROP NIP DUP OVER TUCK SWAP ROT -ROT ?DUP PICK ROLL
+syn keyword forthStack 2DROP 2NIP 2DUP 2OVER 2TUCK 2SWAP 2ROT
+syn keyword forthStack 3DUP 4DUP
+syn keyword forthRStack >R R> R@ RDROP 2>R 2R> 2R@ 2RDROP
+syn keyword forthFStack FDROP FNIP FDUP FOVER FTUCK FSWAP FROT
+
+" stack pointer manipulations
+syn keyword forthSP SP@ SP! FP@ FP! RP@ RP! LP@ LP!
+
+" address operations
+syn keyword forthMemory @ ! +! C@ C! 2@ 2! F@ F! SF@ SF! DF@ DF!
+syn keyword forthAdrArith CHARS CHAR+ CELLS CELL+ CELL ALIGN ALIGNED FLOATS
+syn keyword forthAdrArith FLOAT+ FLOAT FALIGN FALIGNED SFLOATS SFLOAT+
+syn keyword forthAdrArith SFALIGN SFALIGNED DFLOATS DFLOAT+ DFALIGN DFALIGNED
+syn keyword forthAdrArith MAXALIGN MAXALIGNED CFALIGN CFALIGNED
+syn keyword forthAdrArith ADDRESS-UNIT-BITS ALLOT ALLOCATE HERE
+syn keyword forthMemBlks MOVE ERASE CMOVE CMOVE> FILL BLANK
+
+" conditionals
+syn keyword forthCond IF ELSE ENDIF THEN CASE OF ENDOF ENDCASE ?DUP-IF
+syn keyword forthCond ?DUP-0=-IF AHEAD CS-PICK CS-ROLL CATCH THROW WITHIN
+
+" iterations
+syn keyword forthLoop BEGIN WHILE REPEAT UNTIL AGAIN
+syn keyword forthLoop ?DO LOOP I J K +DO U+DO -DO U-DO DO +LOOP -LOOP
+syn keyword forthLoop UNLOOP LEAVE ?LEAVE EXIT DONE FOR NEXT
+
+" new words
+syn match forthColonDef '\<:m\?\s*[^ \t]\+\>'
+syn keyword forthEndOfColonDef ; ;M ;m
+syn keyword forthDefine CONSTANT 2CONSTANT FCONSTANT VARIABLE 2VARIABLE CREATE
+syn keyword forthDefine USER VALUE TO DEFER IS DOES> IMMEDIATE COMPILE-ONLY
+syn keyword forthDefine COMPILE RESTRICT INTERPRET POSTPONE EXECUTE LITERAL
+syn keyword forthDefine CREATE-INTERPRET/COMPILE INTERPRETATION> <INTERPRETATION
+syn keyword forthDefine COMPILATION> <COMPILATION ] LASTXT COMP' POSTPONE,
+syn keyword forthDefine FIND-NAME NAME>INT NAME?INT NAME>COMP NAME>STRING STATE
+syn keyword forthDefine C; CVARIABLE
+syn match forthDefine "\[COMP']"
+syn match forthDefine "'"
+syn match forthDefine '\<\[\>'
+syn match forthDefine "\[']"
+syn match forthDefine '\[COMPILE]'
+syn match forthClassDef '\<:class\s*[^ \t]\+\>'
+syn match forthObjectDef '\<:object\s*[^ \t]\+\>'
+syn keyword forthEndOfClassDef ';class'
+syn keyword forthEndOfObjectDef ';object'
+
+" debugging
+syn keyword forthDebug PRINTDEBUGDATA PRINTDEBUGLINE
+syn match forthDebug "\<\~\~\>"
+
+" Assembler
+syn keyword forthAssembler ASSEMBLER CODE END-CODE ;CODE FLUSH-ICACHE C,
+
+" basic character operations
+syn keyword forthCharOps (.) CHAR EXPECT FIND WORD TYPE -TRAILING EMIT KEY
+syn keyword forthCharOps KEY? TIB CR
+" recognize 'char (' or '[char] (' correctly, so it doesn't
+" highlight everything after the paren as a comment till a closing ')'
+syn match forthCharOps '\<char\s\S\s'
+syn match forthCharOps '\<\[char\]\s\S\s'
+syn region forthCharOps start=+."\s+ skip=+\\"+ end=+"+
+
+" char-number conversion
+syn keyword forthConversion <# # #> #S (NUMBER) (NUMBER?) CONVERT D>F D>S DIGIT
+syn keyword forthConversion DPL F>D HLD HOLD NUMBER S>D SIGN >NUMBER
+
+" interptreter, wordbook, compiler
+syn keyword forthForth (LOCAL) BYE COLD ABORT >BODY >NEXT >LINK CFA >VIEW HERE
+syn keyword forthForth PAD WORDS VIEW VIEW> N>LINK NAME> LINK> L>NAME FORGET
+syn keyword forthForth BODY>
+syn region forthForth start=+ABORT"\s+ skip=+\\"+ end=+"+
+
+" vocabularies
+syn keyword forthVocs ONLY FORTH ALSO ROOT SEAL VOCS ORDER CONTEXT #VOCS
+syn keyword forthVocs VOCABULARY DEFINITIONS
+
+" numbers
+syn keyword forthMath DECIMAL HEX BASE
+syn match forthInteger '\<-\=[0-9.]*[0-9.]\+\>'
+" recognize hex and binary numbers, the '$' and '%' notation is for gforth
+syn match forthInteger '\<\$\x*\x\+\>' " *1* --- dont't mess
+syn match forthInteger '\<\x*\d\x*\>'  " *2* --- this order!
+syn match forthInteger '\<%[0-1]*[0-1]\+\>'
+syn match forthFloat '\<-\=\d*[.]\=\d\+[Ee]\d\+\>'
+
+" Strings
+syn region forthString start=+\.*\"+ end=+"+ end=+$+
+" XXX
+syn region forthString start=+s\"+ end=+"+ end=+$+
+syn region forthString start=+c\"+ end=+"+ end=+$+
+
+" Comments
+syn match forthComment '\\\s.*$' contains=forthTodo
+syn region forthComment start='\\S\s' end='.*' contains=forthTodo
+syn match forthComment '\.(\s[^)]*)' contains=forthTodo
+syn region forthComment start='(\s' skip='\\)' end=')' contains=forthTodo
+syn region forthComment start='/\*' end='\*/' contains=forthTodo
+"syn match forthComment '(\s[^\-]*\-\-[^\-]*)' contains=forthTodo
+
+" Include files
+syn match forthInclude '^INCLUDE\s\+\k\+'
+syn match forthInclude '^fload\s\+'
+syn match forthInclude '^needs\s\+'
+
+" Define the default highlighting.
+" For version 5.7 and earlier: only when not done already
+" For version 5.8 and later: only when an item doesn't have highlighting yet
+if version >= 508 || !exists("did_forth_syn_inits")
+    if version < 508
+        let did_forth_syn_inits = 1
+        command -nargs=+ HiLink hi link <args>
+    else
+        command -nargs=+ HiLink hi def link <args>
+    endif
+
+    " The default methods for highlighting. Can be overriden later.
+    HiLink forthTodo Todo
+    HiLink forthOperators Operator
+    HiLink forthMath Number
+    HiLink forthInteger Number
+    HiLink forthFloat Float
+    HiLink forthStack Special
+    HiLink forthRstack Special
+    HiLink forthFStack Special
+    HiLink forthSP Special
+    HiLink forthMemory Function
+    HiLink forthAdrArith Function
+    HiLink forthMemBlks Function
+    HiLink forthCond Conditional
+    HiLink forthLoop Repeat
+    HiLink forthColonDef Define
+    HiLink forthEndOfColonDef Define
+    HiLink forthDefine Define
+    HiLink forthDebug Debug
+    HiLink forthAssembler Include
+    HiLink forthCharOps Character
+    HiLink forthConversion String
+    HiLink forthForth Statement
+    HiLink forthVocs Statement
+    HiLink forthString String
+    HiLink forthComment Comment
+    HiLink forthClassDef Define
+    HiLink forthEndOfClassDef Define
+    HiLink forthObjectDef Define
+    HiLink forthEndOfObjectDef Define
+    HiLink forthInclude Include
+
+    delcommand HiLink
+endif
+
+let b:current_syntax = "forth"
+
+" vim:ts=8:sw=4:nocindent:smartindent:
--- /dev/null
+++ b/lib/vimfiles/syntax/fortran.vim
@@ -1,0 +1,489 @@
+" Vim syntax file
+" Language:	Fortran95 (and Fortran90, Fortran77, F and elf90)
+" Version:	0.88
+" URL:		http://www.unb.ca/chem/ajit/syntax/fortran.vim
+" Last Change:	2006 Apr. 22
+" Maintainer:	Ajit J. Thakkar (ajit AT unb.ca); <http://www.unb.ca/chem/ajit/>
+" Usage:	Do :help fortran-syntax from Vim
+" Credits:
+"  Version 0.1 was based on the fortran 77 syntax file by Mario Eusebio and
+"  Preben Guldberg. Useful suggestions were made by: Andrej Panjkov,
+"  Bram Moolenaar, Thomas Olsen, Michael Sternberg, Christian Reile,
+"  Walter Dieudonn�, Alexander Wagner, Roman Bertle, Charles Rendleman,
+"  and Andrew Griffiths. For instructions on use, do :help fortran from vim
+
+" For version 5.x: Clear all syntax items
+" For version 6.x: Quit if a syntax file is already loaded
+if version < 600
+  syntax clear
+elseif exists("b:current_syntax")
+  finish
+endif
+
+" let b:fortran_dialect = fortran_dialect if set correctly by user
+if exists("fortran_dialect")
+  if fortran_dialect =~ '\<\(f\(9[05]\|77\)\|elf\|F\)\>'
+    let b:fortran_dialect = matchstr(fortran_dialect,'\<\(f\(9[05]\|77\)\|elf\|F\)\>')
+  else
+    echohl WarningMsg | echo "Unknown value of fortran_dialect" | echohl None
+    let b:fortran_dialect = "unknown"
+  endif
+else
+  let b:fortran_dialect = "unknown"
+endif
+
+" fortran_dialect not set or set incorrectly by user,
+if b:fortran_dialect == "unknown"
+  " set b:fortran_dialect from directive in first three lines of file
+  let b:fortran_retype = getline(1)." ".getline(2)." ".getline(3)
+  if b:fortran_retype =~ '\<fortran_dialect\s*=\s*F\>'
+    let b:fortran_dialect = "F"
+  elseif b:fortran_retype =~ '\<fortran_dialect\s*=\s*elf\>'
+    let b:fortran_dialect = "elf"
+  elseif b:fortran_retype =~ '\<fortran_dialect\s*=\s*f90\>'
+    let b:fortran_dialect = "f90"
+  elseif b:fortran_retype =~ '\<fortran_dialect\s*=\s*f95\>'
+    let b:fortran_dialect = "f95"
+  elseif b:fortran_retype =~ '\<fortran_dialect\s*=\s*f77\>'
+    let b:fortran_dialect = "f77"
+  else
+    " no directive found, so assume f95
+    let b:fortran_dialect = "f95"
+  endif
+  unlet b:fortran_retype
+endif
+
+" Choose between fixed and free source form if this hasn't been done yet
+if !exists("b:fortran_fixed_source")
+  if b:fortran_dialect == "elf" || b:fortran_dialect == "F"
+    " elf and F require free source form
+    let b:fortran_fixed_source = 0
+  elseif b:fortran_dialect == "f77"
+    " f77 requires fixed source form
+    let b:fortran_fixed_source = 1
+  elseif exists("fortran_free_source")
+    " User guarantees free source form for all f90 and f95 files
+    let b:fortran_fixed_source = 0
+  elseif exists("fortran_fixed_source")
+    " User guarantees fixed source form for all f90 and f95 files
+    let b:fortran_fixed_source = 1
+  else
+    " f90 and f95 allow both fixed and free source form.
+    " Assume fixed source form unless signs of free source form
+    " are detected in the first five columns of the first b:lmax lines.
+    " Detection becomes more accurate and time-consuming if more lines
+    " are checked. Increase the limit below if you keep lots of comments at
+    " the very top of each file and you have a fast computer.
+    let b:lmax = 250
+    if ( b:lmax > line("$") )
+      let b:lmax = line("$")
+    endif
+    let b:fortran_fixed_source = 1
+    let b:ln=1
+    while b:ln <= b:lmax
+      let b:test = strpart(getline(b:ln),0,5)
+      if b:test[0] !~ '[Cc*!#]' && b:test !~ '^ \+[!#]' && b:test =~ '[^ 0-9\t]'
+	let b:fortran_fixed_source = 0
+	break
+      endif
+      let b:ln = b:ln + 1
+    endwhile
+    unlet b:lmax b:ln b:test
+  endif
+endif
+
+syn case ignore
+
+if b:fortran_dialect !=? "f77"
+  if version >= 600
+    if b:fortran_fixed_source == 1
+      syn match fortranConstructName	"^\s\{6,}\zs\a\w*\ze\s*:"
+    else
+      syn match fortranConstructName	"^\s*\zs\a\w*\ze\s*:"
+    endif
+    if exists("fortran_more_precise")
+      syn match fortranConstructName "\(\<end\s*do\s\+\)\@<=\a\w*"
+      syn match fortranConstructName "\(\<end\s*if\s\+\)\@<=\a\w*"
+      syn match fortranConstructName "\(\<end\s*select\s\+\)\@<=\a\w*"
+    endif
+  else
+    if b:fortran_fixed_source == 1
+      syn match fortranConstructName	"^\s\{6,}\a\w*\s*:"
+    else
+      syn match fortranConstructName	"^\s*\a\w*\s*:"
+    endif
+  endif
+endif
+
+syn match   fortranUnitHeader	"\<end\>"
+
+syn match fortranType		"\<character\>"
+syn match fortranType		"\<complex\>"
+syn match fortranType		"\<integer\>"
+syn keyword fortranType		intrinsic
+syn match fortranType		"\<implicit\>"
+syn keyword fortranStructure	dimension
+syn keyword fortranStorageClass	parameter save
+syn match fortranUnitHeader	"\<subroutine\>"
+syn keyword fortranCall		call
+syn match fortranUnitHeader	"\<function\>"
+syn match fortranUnitHeader	"\<program\>"
+syn keyword fortranKeyword	return stop
+syn keyword fortranConditional	else then
+syn match fortranConditional	"\<if\>"
+syn match fortranRepeat		"\<do\>"
+
+syn keyword fortranTodo		contained todo fixme
+
+"Catch errors caused by too many right parentheses
+syn region fortranParen transparent start="(" end=")" contains=ALLBUT,fortranParenError,@fortranCommentGroup,cIncluded,@spell
+syn match  fortranParenError   ")"
+
+syn match fortranOperator	"\.\s*n\=eqv\s*\."
+syn match fortranOperator	"\.\s*\(and\|or\|not\)\s*\."
+syn match fortranOperator	"\(+\|-\|/\|\*\)"
+
+syn match fortranBoolean	"\.\s*\(true\|false\)\s*\."
+
+syn keyword fortranReadWrite	backspace close endfile inquire open print read rewind write
+
+"If tabs are allowed then the left margin checks do not work
+if exists("fortran_have_tabs")
+  syn match fortranTab		"\t"  transparent
+else
+  syn match fortranTab		"\t"
+endif
+
+syn keyword fortranIO		access blank direct exist file fmt form formatted iostat name named nextrec number opened rec recl sequential status unformatted unit
+
+syn keyword fortran66Intrinsic		alog alog10 amax0 amax1 amin0 amin1 amod cabs ccos cexp clog csin csqrt dabs dacos dasin datan datan2 dcos dcosh ddim dexp dint dlog dlog10 dmax1 dmin1 dmod dnint dsign dsin dsinh dsqrt dtan dtanh float iabs idim idint idnint ifix isign max0 max1 min0 min1 sngl
+
+" Intrinsics provided by some vendors
+syn keyword fortranExtraIntrinsic	algama cdabs cdcos cdexp cdlog cdsin cdsqrt cqabs cqcos cqexp cqlog cqsin cqsqrt dcmplx dconjg derf derfc dfloat dgamma dimag dlgama erf erfc gamma iqint qabs qacos qasin qatan qatan2 qcmplx qconjg qcos qcosh qdim qerf qerfc qexp qgamma qimag qlgama qlog qlog10 qmax1 qmin1 qmod qnint qsign qsin qsinh qsqrt qtan qtanh
+
+syn keyword fortran77Intrinsic	abs acos aimag aint anint asin atan atan2 char cmplx conjg cos cosh exp ichar index int log log10 max min nint sign sin sinh sqrt tan tanh
+syn match fortran77Intrinsic	"\<len\s*[(,]"me=s+3
+syn match fortran77Intrinsic	"\<real\s*("me=s+4
+syn match fortranType		"\<implicit\s\+real"
+syn match fortranType		"^\s*real\>"
+syn match fortran90Intrinsic	"\<logical\s*("me=s+7
+syn match fortranType		"\<implicit\s\+logical"
+syn match fortranType		"^\s*logical\>"
+
+"Numbers of various sorts
+" Integers
+syn match fortranNumber	display "\<\d\+\(_\a\w*\)\=\>"
+" floating point number, without a decimal point
+syn match fortranFloatNoDec	display	"\<\d\+[deq][-+]\=\d\+\(_\a\w*\)\=\>"
+" floating point number, starting with a decimal point
+syn match fortranFloatIniDec	display	"\.\d\+\([deq][-+]\=\d\+\)\=\(_\a\w*\)\=\>"
+" floating point number, no digits after decimal
+syn match fortranFloatEndDec	display	"\<\d\+\.\([deq][-+]\=\d\+\)\=\(_\a\w*\)\=\>"
+" floating point number, D or Q exponents
+syn match fortranFloatDExp	display	"\<\d\+\.\d\+\([dq][-+]\=\d\+\)\=\(_\a\w*\)\=\>"
+" floating point number
+syn match fortranFloat	display	"\<\d\+\.\d\+\(e[-+]\=\d\+\)\=\(_\a\w*\)\=\>"
+" Numbers in formats
+syn match fortranFormatSpec	display	"\d*f\d\+\.\d\+"
+syn match fortranFormatSpec	display	"\d*e[sn]\=\d\+\.\d\+\(e\d+\>\)\="
+syn match fortranFormatSpec	display	"\d*\(d\|q\|g\)\d\+\.\d\+\(e\d+\)\="
+syn match fortranFormatSpec	display	"\d\+x\>"
+" The next match cannot be used because it would pick up identifiers as well
+" syn match fortranFormatSpec	display	"\<\(a\|i\)\d\+"
+
+" Numbers as labels
+syn match fortranLabelNumber	display	"^\d\{1,5}\s"me=e-1
+syn match fortranLabelNumber	display	"^ \d\{1,4}\s"ms=s+1,me=e-1
+syn match fortranLabelNumber	display	"^  \d\{1,3}\s"ms=s+2,me=e-1
+syn match fortranLabelNumber	display	"^   \d\d\=\s"ms=s+3,me=e-1
+syn match fortranLabelNumber	display	"^    \d\s"ms=s+4,me=e-1
+
+if version >= 600 && exists("fortran_more_precise")
+  " Numbers as targets
+  syn match fortranTarget	display	"\(\<if\s*(.\+)\s*\)\@<=\(\d\+\s*,\s*\)\{2}\d\+\>"
+  syn match fortranTarget	display	"\(\<do\s\+\)\@<=\d\+\>"
+  syn match fortranTarget	display	"\(\<go\s*to\s*(\=\)\@<=\(\d\+\s*,\s*\)*\d\+\>"
+endif
+
+syn keyword fortranTypeEx	external
+syn keyword fortranIOEx		format
+syn keyword fortranKeywordEx	continue
+syn match fortranKeywordEx	"\<go\s*to\>"
+syn region fortranStringEx	start=+'+ end=+'+ contains=fortranContinueMark,fortranLeftMargin,fortranSerialNumber
+syn keyword fortran77IntrinsicEx	dim lge lgt lle llt mod
+syn keyword fortranKeywordOb	assign pause to
+
+if b:fortran_dialect != "f77"
+
+  syn match fortranType         "\<type\>"
+  syn keyword fortranType	none
+
+  syn keyword fortranStructure	private public intent optional
+  syn keyword fortranStructure	pointer target allocatable
+  syn keyword fortranStorageClass	in out
+  syn match fortranStorageClass	"\<kind\s*="me=s+4
+  syn match fortranStorageClass	"\<len\s*="me=s+3
+
+  syn match fortranUnitHeader	"\<module\>"
+  syn keyword fortranUnitHeader	use only contains
+  syn keyword fortranUnitHeader	result operator assignment
+  syn match fortranUnitHeader	"\<interface\>"
+  syn match fortranUnitHeader	"\<recursive\>"
+  syn keyword fortranKeyword	allocate deallocate nullify cycle exit
+  syn match fortranConditional	"\<select\>"
+  syn keyword fortranConditional	case default where elsewhere
+
+  syn match fortranOperator	"\(\(>\|<\)=\=\|==\|/=\|=\)"
+  syn match fortranOperator	"=>"
+
+  syn region fortranString	start=+"+ end=+"+	contains=fortranLeftMargin,fortranContinueMark,fortranSerialNumber
+  syn keyword fortranIO		pad position action delim readwrite
+  syn keyword fortranIO		eor advance nml
+
+  syn keyword fortran90Intrinsic	adjustl adjustr all allocated any associated bit_size btest ceiling count cshift date_and_time digits dot_product eoshift epsilon exponent floor fraction huge iand ibclr ibits ibset ieor ior ishft ishftc lbound len_trim matmul maxexponent maxloc maxval merge minexponent minloc minval modulo mvbits nearest pack precision present product radix random_number random_seed range repeat reshape rrspacing
+  syn keyword fortran90Intrinsic	scale scan selected_int_kind selected_real_kind set_exponent shape size spacing spread sum system_clock tiny transpose trim ubound unpack verify
+  syn match fortran90Intrinsic		"\<not\>\(\s*\.\)\@!"me=s+3
+  syn match fortran90Intrinsic	"\<kind\>\s*[(,]"me=s+4
+
+  syn match  fortranUnitHeader	"\<end\s*function"
+  syn match  fortranUnitHeader	"\<end\s*interface"
+  syn match  fortranUnitHeader	"\<end\s*module"
+  syn match  fortranUnitHeader	"\<end\s*program"
+  syn match  fortranUnitHeader	"\<end\s*subroutine"
+  syn match  fortranRepeat	"\<end\s*do"
+  syn match  fortranConditional	"\<end\s*where"
+  syn match  fortranConditional	"\<select\s*case"
+  syn match  fortranConditional	"\<end\s*select"
+  syn match  fortranType	"\<end\s*type"
+  syn match  fortranType	"\<in\s*out"
+
+  syn keyword fortranUnitHeaderEx	procedure
+  syn keyword fortranIOEx		namelist
+  syn keyword fortranConditionalEx	while
+  syn keyword fortran90IntrinsicEx	achar iachar transfer
+
+  syn keyword fortranInclude		include
+  syn keyword fortran90StorageClassR	sequence
+endif
+
+syn match   fortranConditional	"\<end\s*if"
+syn match   fortranIO		contains=fortranOperator "\<e\(nd\|rr\)\s*=\s*\d\+"
+syn match   fortranConditional	"\<else\s*if"
+
+syn keyword fortranUnitHeaderR	entry
+syn match fortranTypeR		display "double\s\+precision"
+syn match fortranTypeR		display "double\s\+complex"
+syn match fortranUnitHeaderR	display "block\s\+data"
+syn keyword fortranStorageClassR	common equivalence data
+syn keyword fortran77IntrinsicR	dble dprod
+syn match   fortran77OperatorR	"\.\s*[gl][et]\s*\."
+syn match   fortran77OperatorR	"\.\s*\(eq\|ne\)\s*\."
+
+if b:fortran_dialect == "f95" || b:fortran_dialect == "F"
+  syn keyword fortranRepeat		forall
+  syn match fortranRepeat		"\<end\s*forall"
+  syn keyword fortran95Intrinsic	null cpu_time
+  syn match fortranType			"\<elemental\>"
+  syn match fortranType			"\<pure\>"
+  if exists("fortran_more_precise")
+    syn match fortranConstructName "\(\<end\s*forall\s\+\)\@<=\a\w*\>"
+  endif
+endif
+
+syn cluster fortranCommentGroup contains=fortranTodo
+
+if (b:fortran_fixed_source == 1)
+  if !exists("fortran_have_tabs")
+    "Flag items beyond column 72
+    syn match fortranSerialNumber	excludenl "^.\{73,}$"lc=72
+    "Flag left margin errors
+    syn match fortranLabelError	"^.\{-,4}[^0-9 ]" contains=fortranTab
+    syn match fortranLabelError	"^.\{4}\d\S"
+  endif
+  syn match fortranComment		excludenl "^[!c*].*$" contains=@fortranCommentGroup
+  syn match fortranLeftMargin		transparent "^ \{5}"
+  syn match fortranContinueMark		display "^.\{5}\S"lc=5
+else
+  syn match fortranContinueMark		display "&"
+endif
+
+if b:fortran_dialect != "f77"
+  syn match fortranComment	excludenl "!.*$" contains=@fortranCommentGroup,@spell
+endif
+
+"cpp is often used with Fortran
+syn match	cPreProc		"^\s*#\s*\(define\|ifdef\)\>.*"
+syn match	cPreProc		"^\s*#\s*\(elif\|if\)\>.*"
+syn match	cPreProc		"^\s*#\s*\(ifndef\|undef\)\>.*"
+syn match	cPreCondit		"^\s*#\s*\(else\|endif\)\>.*"
+syn region	cIncluded	contained start=+"[^(]+ skip=+\\\\\|\\"+ end=+"+ contains=fortranLeftMargin,fortranContinueMark,fortranSerialNumber
+syn match	cIncluded		contained "<[^>]*>"
+syn match	cInclude		"^\s*#\s*include\>\s*["<]" contains=cIncluded
+
+"Synchronising limits assume that comment and continuation lines are not mixed
+if exists("fortran_fold") || exists("fortran_more_precise")
+  syn sync fromstart
+elseif (b:fortran_fixed_source == 0)
+  syn sync linecont "&" minlines=20
+else
+  syn sync minlines=20
+endif
+
+if version >= 600 && exists("fortran_fold")
+
+  if (b:fortran_fixed_source == 1)
+    syn region fortranProgram transparent fold keepend start="^\s*program\s\+\z(\a\w*\)" skip="^\([!c*]\|\s*#\).*$" excludenl end="\<end\s*\(program\(\s\+\z1\>\)\=\|$\)" contains=ALLBUT,fortranModule
+    syn region fortranModule transparent fold keepend start="^\s*module\s\+\(procedure\)\@!\z(\a\w*\)" skip="^\([!c*]\|\s*#\).*$" excludenl end="\<end\s*\(module\(\s\+\z1\>\)\=\|$\)" contains=ALLBUT,fortranProgram
+    syn region fortranFunction transparent fold keepend extend start="^\s*\(elemental \|pure \|recursive \)\=\s*\(\(\(real \|integer \|logical \|complex \|double \s*precision \)\s*\((\(\s*kind\s*=\)\=\s*\w\+\s*)\)\=\)\|type\s\+(\s*\w\+\s*) \|character \((\(\s*len\s*=\)\=\s*\d\+\s*)\|(\(\s*kind\s*=\)\=\s*\w\+\s*)\)\=\)\=\s*function\s\+\z(\a\w*\)" skip="^\([!c*]\|\s*#\).*$" excludenl end="\<end\s*\($\|function\(\s\+\z1\>\)\=\)" contains=ALLBUT,fortranProgram,fortranModule
+    syn region fortranSubroutine transparent fold keepend extend start="^\s*\(elemental \|pure \|recursive \)\=\s*subroutine\s\+\z(\a\w*\)" skip="^\([!c*]\|\s*#\).*$" excludenl end="\<end\s*\($\|subroutine\(\s\+\z1\>\)\=\)" contains=ALLBUT,fortranProgram,fortranModule
+    syn region fortranBlockData transparent fold keepend start="\<block\s*data\s\+\z(\a\w*\)" skip="^\([!c*]\|\s*#\).*$" excludenl end="\<end\s*\($\|block\s*data\(\s\+\z1\>\)\=\)" contains=ALLBUT,fortranProgram,fortranModule,fortranSubroutine,fortranFunction,fortran77Loop,fortranCase,fortran90Loop,fortranIfBlock
+    syn region fortranInterface transparent fold keepend extend start="^\s*interface\>" skip="^\([!c*]\|\s*#\).*$" excludenl end="\<end\s*interface\>" contains=ALLBUT,fortranProgram,fortranModule,fortran77Loop,fortranCase,fortran90Loop,fortranIfBlock
+  else
+    syn region fortranProgram transparent fold keepend start="^\s*program\s\+\z(\a\w*\)" skip="^\s*[!#].*$" excludenl end="\<end\s*\(program\(\s\+\z1\>\)\=\|$\)" contains=ALLBUT,fortranModule
+    syn region fortranModule transparent fold keepend start="^\s*module\s\+\(procedure\)\@!\z(\a\w*\)" skip="^\s*[!#].*$" excludenl end="\<end\s*\(module\(\s\+\z1\>\)\=\|$\)" contains=ALLBUT,fortranProgram
+    syn region fortranFunction transparent fold keepend extend start="^\s*\(elemental \|pure \|recursive \)\=\s*\(\(\(real \|integer \|logical \|complex \|double \s*precision \)\s*\((\(\s*kind\s*=\)\=\s*\w\+\s*)\)\=\)\|type\s\+(\s*\w\+\s*) \|character \((\(\s*len\s*=\)\=\s*\d\+\s*)\|(\(\s*kind\s*=\)\=\s*\w\+\s*)\)\=\)\=\s*function\s\+\z(\a\w*\)" skip="^\s*[!#].*$" excludenl end="\<end\s*\($\|function\(\s\+\z1\>\)\=\)" contains=ALLBUT,fortranProgram,fortranModule
+    syn region fortranSubroutine transparent fold keepend extend start="^\s*\(elemental \|pure \|recursive \)\=\s*subroutine\s\+\z(\a\w*\)" skip="^\s*[!#].*$" excludenl end="\<end\s*\($\|subroutine\(\s\+\z1\>\)\=\)" contains=ALLBUT,fortranProgram,fortranModule
+    syn region fortranBlockData transparent fold keepend start="\<block\s*data\s\+\z(\a\w*\)" skip="^\s*[!#].*$" excludenl end="\<end\s*\($\|block\s*data\(\s\+\z1\>\)\=\)" contains=ALLBUT,fortranProgram,fortranModule,fortranSubroutine,fortranFunction,fortran77Loop,fortranCase,fortran90Loop,fortranIfBlock
+    syn region fortranInterface transparent fold keepend extend start="^\s*interface\>" skip="^\s*[!#].*$" excludenl end="\<end\s*interface\>" contains=ALLBUT,fortranProgram,fortranModule,fortran77Loop,fortranCase,fortran90Loop,fortranIfBlock
+  endif
+
+  if exists("fortran_fold_conditionals")
+    if (b:fortran_fixed_source == 1)
+      syn region fortran77Loop transparent fold keepend start="\<do\s\+\z(\d\+\)" end="^\s*\z1\>" contains=ALLBUT,fortranUnitHeader,fortranStructure,fortranStorageClass,fortranType,fortranProgram,fortranModule,fortranSubroutine,fortranFunction,fortranBlockData
+      syn region fortran90Loop transparent fold keepend extend start="\(\<end\s\+\)\@<!\<do\(\s\+\a\|\s*$\)" skip="^\([!c*]\|\s*#\).*$" excludenl end="\<end\s*do\>" contains=ALLBUT,fortranUnitHeader,fortranStructure,fortranStorageClass,fortranType,fortranProgram,fortranModule,fortranSubroutine,fortranFunction,fortranBlockData
+      syn region fortranIfBlock transparent fold keepend extend start="\(\<e\(nd\|lse\)\s\+\)\@<!\<if\s*(.\+)\s*then\>" skip="^\([!c*]\|\s*#\).*$" end="\<end\s*if\>" contains=ALLBUT,fortranUnitHeader,fortranStructure,fortranStorageClass,fortranType,fortranProgram,fortranModule,fortranSubroutine,fortranFunction,fortranBlockData
+      syn region fortranCase transparent fold keepend extend start="\<select\s*case\>" skip="^\([!c*]\|\s*#\).*$" end="\<end\s*select\>" contains=ALLBUT,fortranUnitHeader,fortranStructure,fortranStorageClass,fortranType,fortranProgram,fortranModule,fortranSubroutine,fortranFunction,fortranBlockData
+    else
+      syn region fortran77Loop transparent fold keepend start="\<do\s\+\z(\d\+\)" end="^\s*\z1\>" contains=ALLBUT,fortranUnitHeader,fortranStructure,fortranStorageClass,fortranType,fortranProgram,fortranModule,fortranSubroutine,fortranFunction,fortranBlockData
+      syn region fortran90Loop transparent fold keepend extend start="\(\<end\s\+\)\@<!\<do\(\s\+\a\|\s*$\)" skip="^\s*[!#].*$" excludenl end="\<end\s*do\>" contains=ALLBUT,fortranUnitHeader,fortranStructure,fortranStorageClass,fortranType,fortranProgram,fortranModule,fortranSubroutine,fortranFunction,fortranBlockData
+      syn region fortranIfBlock transparent fold keepend extend start="\(\<e\(nd\|lse\)\s\+\)\@<!\<if\s*(.\+)\s*then\>" skip="^\s*[!#].*$" end="\<end\s*if\>" contains=ALLBUT,fortranUnitHeader,fortranStructure,fortranStorageClass,fortranType,fortranProgram,fortranModule,fortranSubroutine,fortranFunction,fortranBlockData
+      syn region fortranCase transparent fold keepend extend start="\<select\s*case\>" skip="^\s*[!#].*$" end="\<end\s*select\>" contains=ALLBUT,fortranUnitHeader,fortranStructure,fortranStorageClass,fortranType,fortranProgram,fortranModule,fortranSubroutine,fortranFunction,fortranBlockData
+    endif
+  endif
+
+  if exists("fortran_fold_multilinecomments")
+    if (b:fortran_fixed_source == 1)
+      syn match fortranMultiLineComments transparent fold "\(^[!c*].*\(\n\|\%$\)\)\{4,}" contains=ALLBUT,fortranMultiCommentLines
+    else
+      syn match fortranMultiLineComments transparent fold "\(^\s*!.*\(\n\|\%$\)\)\{4,}" contains=ALLBUT,fortranMultiCommentLines
+    endif
+  endif
+endif
+
+" Define the default highlighting.
+" For version 5.7 and earlier: only when not done already
+" For version 5.8 and later: only when an item doesn't have highlighting yet
+if version >= 508 || !exists("did_fortran_syn_inits")
+  if version < 508
+    let did_fortran_syn_inits = 1
+    command -nargs=+ HiLink hi link <args>
+  else
+    command -nargs=+ HiLink hi def link <args>
+  endif
+
+  " The default highlighting differs for each dialect.
+  " Transparent groups:
+  " fortranParen, fortranLeftMargin
+  " fortranProgram, fortranModule, fortranSubroutine, fortranFunction,
+  " fortranBlockData
+  " fortran77Loop, fortran90Loop, fortranIfBlock, fortranCase
+  " fortranMultiCommentLines
+  HiLink fortranKeyword 	Keyword
+  HiLink fortranConstructName	Identifier
+  HiLink fortranConditional	Conditional
+  HiLink fortranRepeat		Repeat
+  HiLink fortranTodo		Todo
+  HiLink fortranContinueMark	Todo
+  HiLink fortranString		String
+  HiLink fortranNumber		Number
+  HiLink fortranOperator	Operator
+  HiLink fortranBoolean		Boolean
+  HiLink fortranLabelError	Error
+  HiLink fortranObsolete	Todo
+  HiLink fortranType		Type
+  HiLink fortranStructure	Type
+  HiLink fortranStorageClass	StorageClass
+  HiLink fortranCall		fortranUnitHeader
+  HiLink fortranUnitHeader	fortranPreCondit
+  HiLink fortranReadWrite	Keyword
+  HiLink fortranIO		Keyword
+  HiLink fortran95Intrinsic	fortran90Intrinsic
+  HiLink fortran77Intrinsic	fortran90Intrinsic
+  HiLink fortran90Intrinsic	Function
+
+  if ( b:fortran_dialect == "elf" || b:fortran_dialect == "F" )
+    HiLink fortranKeywordOb	fortranObsolete
+    HiLink fortran66Intrinsic	fortranObsolete
+    HiLink fortran77IntrinsicR	fortranObsolete
+    HiLink fortranUnitHeaderR	fortranObsolete
+    HiLink fortranTypeR		fortranObsolete
+    HiLink fortranStorageClassR	fortranObsolete
+    HiLink fortran90StorageClassR	fortranObsolete
+    HiLink fortran77OperatorR	fortranObsolete
+    HiLink fortranInclude	fortranObsolete
+  else
+    HiLink fortranKeywordOb	fortranKeyword
+    HiLink fortran66Intrinsic	fortran90Intrinsic
+    HiLink fortran77IntrinsicR	fortran90Intrinsic
+    HiLink fortranUnitHeaderR	fortranPreCondit
+    HiLink fortranTypeR		fortranType
+    HiLink fortranStorageClassR	fortranStorageClass
+    HiLink fortran77OperatorR	fortranOperator
+    HiLink fortranInclude	Include
+    HiLink fortran90StorageClassR	fortranStorageClass
+  endif
+
+  if ( b:fortran_dialect == "F" )
+    HiLink fortranLabelNumber	fortranObsolete
+    HiLink fortranTarget	fortranObsolete
+    HiLink fortranFormatSpec	fortranObsolete
+    HiLink fortranFloatDExp	fortranObsolete
+    HiLink fortranFloatNoDec	fortranObsolete
+    HiLink fortranFloatIniDec	fortranObsolete
+    HiLink fortranFloatEndDec	fortranObsolete
+    HiLink fortranTypeEx	fortranObsolete
+    HiLink fortranIOEx		fortranObsolete
+    HiLink fortranKeywordEx	fortranObsolete
+    HiLink fortranStringEx	fortranObsolete
+    HiLink fortran77IntrinsicEx	fortranObsolete
+    HiLink fortranUnitHeaderEx	fortranObsolete
+    HiLink fortranConditionalEx	fortranObsolete
+    HiLink fortran90IntrinsicEx	fortranObsolete
+  else
+    HiLink fortranLabelNumber	Special
+    HiLink fortranTarget	Special
+    HiLink fortranFormatSpec	Identifier
+    HiLink fortranFloatDExp	fortranFloat
+    HiLink fortranFloatNoDec	fortranFloat
+    HiLink fortranFloatIniDec	fortranFloat
+    HiLink fortranFloatEndDec	fortranFloat
+    HiLink fortranTypeEx	fortranType
+    HiLink fortranIOEx		fortranIO
+    HiLink fortranKeywordEx	fortranKeyword
+    HiLink fortranStringEx	fortranString
+    HiLink fortran77IntrinsicEx	fortran90Intrinsic
+    HiLink fortranUnitHeaderEx	fortranUnitHeader
+    HiLink fortranConditionalEx	fortranConditional
+    HiLink fortran90IntrinsicEx	fortran90Intrinsic
+  endif
+
+  HiLink fortranFloat		Float
+  HiLink fortranPreCondit	PreCondit
+  HiLink fortranInclude		Include
+  HiLink cIncluded		fortranString
+  HiLink cInclude		Include
+  HiLink cPreProc		PreProc
+  HiLink cPreCondit		PreCondit
+  HiLink fortranParenError	Error
+  HiLink fortranComment		Comment
+  HiLink fortranSerialNumber	Todo
+  HiLink fortranTab		Error
+  " Vendor extensions
+  HiLink fortranExtraIntrinsic	Function
+
+  delcommand HiLink
+endif
+
+let b:current_syntax = "fortran"
+
+" vim: ts=8 tw=132
--- /dev/null
+++ b/lib/vimfiles/syntax/foxpro.vim
@@ -1,0 +1,727 @@
+" Vim syntax file
+" Filename:     foxpro.vim
+" Version:      1.0
+" Language:     FoxPro for DOS/UNIX v2.6
+" Maintainer:   Bill W. Smith, Jr. <donal@brewich.com>
+" Last Change:  15 May 2006
+
+"     This file replaces the FoxPro for DOS v2.x syntax file 
+" maintained by Powing Tse <powing@mcmug.org>
+" 
+" Change Log:	added support for FoxPro Codebook highlighting
+" 		corrected highlighting of comments that do NOT start in col 1
+" 		corrected highlighting of comments at end of line (&&)
+" 
+" 
+if version < 600
+    syntax clear
+elseif exists("b:current_syntax")
+    finish
+endif
+
+" FoxPro Codebook Naming Conventions
+syn match foxproCBConst "\<[c][A-Z][A-Za-z0-9_]*\>"
+syn match foxproCBVar "\<[lgrt][acndlmf][A-Z][A-Za-z0-9_]*\>"
+syn match foxproCBField "\<[a-z0-9]*\.[A-Za-z0-9_]*\>"
+" PROPER CodeBook field names start with the data type and do NOT have _
+syn match foxproCBField "\<[A-Za-z0-9]*\.[acndlm][A-Z][A-Za-z0-9]*\>"
+syn match foxproCBWin "\<w[rbcm][A-Z][A-Za-z0-9_]*\>"
+" CodeBook 2.0 defined objects as follows
+" This uses the hotkey from the screen builder as the second character
+syn match foxproCBObject "\<[lgr][bfthnkoli][A-Z][A-Za-z0-9_]*\>"
+" A later version added the following conventions for objects
+syn match foxproCBObject "\<box[A-Z][A-Za-z0-9_]*\>"
+syn match foxproCBObject "\<fld[A-Z][A-Za-z0-9_]*\>"
+syn match foxproCBObject "\<txt[A-Z][A-Za-z0-9_]*\>"
+syn match foxproCBObject "\<phb[A-Z][A-Za-z0-9_]*\>"
+syn match foxproCBObject "\<rdo[A-Z][A-Za-z0-9_]*\>"
+syn match foxproCBObject "\<chk[A-Z][A-Za-z0-9_]*\>"
+syn match foxproCBObject "\<pop[A-Z][A-Za-z0-9_]*\>"
+syn match foxproCBObject "\<lst[A-Z][A-Za-z0-9_]*\>"
+syn match foxproCBObject "\<inv[A-Z][A-Za-z0-9_]*\>"
+syn match foxproCBObject "\<mnu[A-Z][A-Za-z0-9_]*\>"
+
+syntax case ignore
+
+" Highlight special characters
+syn match foxproSpecial "^\s*!"
+syn match foxproSpecial "&"
+syn match foxproSpecial ";\s*$"
+syn match foxproSpecial "^\s*="
+syn match foxproSpecial "^\s*\\"
+syn match foxproSpecial "^\s*\\\\"
+syn match foxproSpecial "^\s*?"
+syn match foxproSpecial "^\s*??"
+syn match foxproSpecial "^\s*???"
+syn match foxproSpecial "\<m\>\."
+
+" @ Statements
+syn match foxproAtSymbol contained "^\s*@"
+syn match foxproAtCmd    contained "\<say\>\|\<get\>\|\<edit\>\|\<box\>\|\<clea\%[r]\>\|\<fill\>\|\<menu\>\|\<prom\%[pt]\>\|\<scro\%[ll]\>\|\<to\>"
+syn match foxproAtStart  transparent "^\s*@.*" contains=ALL
+
+" preprocessor directives
+syn match foxproPreProc "^\s*#\s*\(\<if\>\|\<elif\>\|\<else\>\|\<endi\%[f]\>\)"
+syn match foxproPreProc "^\s*#\s*\(\<defi\%[ne]\>\|\<unde\%[f]\>\)"
+syn match foxproPreProc "^\s*#\s*\<regi\%[on]\>"
+
+" Functions
+syn match foxproFunc "\<abs\>\s*("me=e-1
+syn match foxproFunc "\<acop\%[y]\>\s*("me=e-1
+syn match foxproFunc "\<acos\>\s*("me=e-1
+syn match foxproFunc "\<adel\>\s*("me=e-1
+syn match foxproFunc "\<adir\>\s*("me=e-1
+syn match foxproFunc "\<aele\%[ment]\>\s*("me=e-1
+syn match foxproFunc "\<afie\%[lds]\>\s*("me=e-1
+syn match foxproFunc "\<afon\%[t]\>\s*("me=e-1
+syn match foxproFunc "\<ains\>\s*("me=e-1
+syn match foxproFunc "\<alen\>\s*("me=e-1
+syn match foxproFunc "\<alia\%[s]\>\s*("me=e-1
+syn match foxproFunc "\<allt\%[rim]\>\s*("me=e-1
+syn match foxproFunc "\<ansi\%[tooem]\>\s*("me=e-1
+syn match foxproFunc "\<asc\>\s*("me=e-1
+syn match foxproFunc "\<asca\%[n]\>\s*("me=e-1
+syn match foxproFunc "\<asin\>\s*("me=e-1
+syn match foxproFunc "\<asor\%[t]\>\s*("me=e-1
+syn match foxproFunc "\<asub\%[script]\>\s*("me=e-1
+syn match foxproFunc "\<at\>\s*("me=e-1
+syn match foxproFunc "\<atan\>\s*("me=e-1
+syn match foxproFunc "\<atc\>\s*("me=e-1
+syn match foxproFunc "\<atcl\%[ine]\>\s*("me=e-1
+syn match foxproFunc "\<atli\%[ne]\>\s*("me=e-1
+syn match foxproFunc "\<atn2\>\s*("me=e-1
+syn match foxproFunc "\<bar\>\s*("me=e-1
+syn match foxproFunc "\<barc\%[ount]\>\s*("me=e-1
+syn match foxproFunc "\<barp\%[rompt]\>\s*("me=e-1
+syn match foxproFunc "\<betw\%[een]\>\s*("me=e-1
+syn match foxproFunc "\<bof\>\s*("me=e-1
+syn match foxproFunc "\<caps\%[lock]\>\s*("me=e-1
+syn match foxproFunc "\<cdow\>\s*("me=e-1
+syn match foxproFunc "\<cdx\>\s*("me=e-1
+syn match foxproFunc "\<ceil\%[ing]\>\s*("me=e-1
+syn match foxproFunc "\<chr\>\s*("me=e-1
+syn match foxproFunc "\<chrs\%[aw]\>\s*("me=e-1
+syn match foxproFunc "\<chrt\%[ran]\>\s*("me=e-1
+syn match foxproFunc "\<cmon\%[th]\>\s*("me=e-1
+syn match foxproFunc "\<cntb\%[ar]\>\s*("me=e-1
+syn match foxproFunc "\<cntp\%[ad]\>\s*("me=e-1
+syn match foxproFunc "\<col\>\s*("me=e-1
+syn match foxproFunc "\<cos\>\s*("me=e-1
+syn match foxproFunc "\<cpco\%[nvert]\>\s*("me=e-1
+syn match foxproFunc "\<cpcu\%[rrent]\>\s*("me=e-1
+syn match foxproFunc "\<cpdb\%[f]\>\s*("me=e-1
+syn match foxproFunc "\<ctod\>\s*("me=e-1
+syn match foxproFunc "\<curd\%[ir]\>\s*("me=e-1
+syn match foxproFunc "\<date\>\s*("me=e-1
+syn match foxproFunc "\<day\>\s*("me=e-1
+syn match foxproFunc "\<dbf\>\s*("me=e-1
+syn match foxproFunc "\<ddea\%[borttrans]\>\s*("me=e-1
+syn match foxproFunc "\<ddea\%[dvise]\>\s*("me=e-1
+syn match foxproFunc "\<ddee\%[nabled]\>\s*("me=e-1
+syn match foxproFunc "\<ddee\%[xecute]\>\s*("me=e-1
+syn match foxproFunc "\<ddei\%[nitiate]\>\s*("me=e-1
+syn match foxproFunc "\<ddel\%[asterror]\>\s*("me=e-1
+syn match foxproFunc "\<ddep\%[oke]\>\s*("me=e-1
+syn match foxproFunc "\<dder\%[equest]\>\s*("me=e-1
+syn match foxproFunc "\<ddes\%[etoption]\>\s*("me=e-1
+syn match foxproFunc "\<ddes\%[etservice]\>\s*("me=e-1
+syn match foxproFunc "\<ddes\%[ettopic]\>\s*("me=e-1
+syn match foxproFunc "\<ddet\%[erminate]\>\s*("me=e-1
+syn match foxproFunc "\<dele\%[ted]\>\s*("me=e-1
+syn match foxproFunc "\<desc\%[ending]\>\s*("me=e-1
+syn match foxproFunc "\<diff\%[erence]\>\s*("me=e-1
+syn match foxproFunc "\<disk\%[space]\>\s*("me=e-1
+syn match foxproFunc "\<dmy\>\s*("me=e-1
+syn match foxproFunc "\<dow\>\s*("me=e-1
+syn match foxproFunc "\<dtoc\>\s*("me=e-1
+syn match foxproFunc "\<dtor\>\s*("me=e-1
+syn match foxproFunc "\<dtos\>\s*("me=e-1
+syn match foxproFunc "\<empt\%[y]\>\s*("me=e-1
+syn match foxproFunc "\<eof\>\s*("me=e-1
+syn match foxproFunc "\<erro\%[r]\>\s*("me=e-1
+syn match foxproFunc "\<eval\%[uate]\>\s*("me=e-1
+syn match foxproFunc "\<exp\>\s*("me=e-1
+syn match foxproFunc "\<fchs\%[ize]\>\s*("me=e-1
+syn match foxproFunc "\<fclo\%[se]\>\s*("me=e-1
+syn match foxproFunc "\<fcou\%[nt]\>\s*("me=e-1
+syn match foxproFunc "\<fcre\%[ate]\>\s*("me=e-1
+syn match foxproFunc "\<fdat\%[e]\>\s*("me=e-1
+syn match foxproFunc "\<feof\>\s*("me=e-1
+syn match foxproFunc "\<ferr\%[or]\>\s*("me=e-1
+syn match foxproFunc "\<fflu\%[sh]\>\s*("me=e-1
+syn match foxproFunc "\<fget\%[s]\>\s*("me=e-1
+syn match foxproFunc "\<fiel\%[d]\>\s*("me=e-1
+syn match foxproFunc "\<file\>\s*("me=e-1
+syn match foxproFunc "\<filt\%[er]\>\s*("me=e-1
+syn match foxproFunc "\<fkla\%[bel]\>\s*("me=e-1
+syn match foxproFunc "\<fkma\%[x]\>\s*("me=e-1
+syn match foxproFunc "\<fldl\%[ist]\>\s*("me=e-1
+syn match foxproFunc "\<floc\%[k]\>\s*("me=e-1
+syn match foxproFunc "\<floo\%[r]\>\s*("me=e-1
+syn match foxproFunc "\<font\%[metric]\>\s*("me=e-1
+syn match foxproFunc "\<fope\%[n]\>\s*("me=e-1
+syn match foxproFunc "\<for\>\s*("me=e-1
+syn match foxproFunc "\<foun\%[d]\>\s*("me=e-1
+syn match foxproFunc "\<fput\%[s]\>\s*("me=e-1
+syn match foxproFunc "\<frea\%[d]\>\s*("me=e-1
+syn match foxproFunc "\<fsee\%[k]\>\s*("me=e-1
+syn match foxproFunc "\<fsiz\%[e]\>\s*("me=e-1
+syn match foxproFunc "\<ftim\%[e]\>\s*("me=e-1
+syn match foxproFunc "\<full\%[path]\>\s*("me=e-1
+syn match foxproFunc "\<fv\>\s*("me=e-1
+syn match foxproFunc "\<fwri\%[te]\>\s*("me=e-1
+syn match foxproFunc "\<getb\%[ar]\>\s*("me=e-1
+syn match foxproFunc "\<getd\%[ir]\>\s*("me=e-1
+syn match foxproFunc "\<gete\%[nv]\>\s*("me=e-1
+syn match foxproFunc "\<getf\%[ile]\>\s*("me=e-1
+syn match foxproFunc "\<getf\%[ont]\>\s*("me=e-1
+syn match foxproFunc "\<getp\%[ad]\>\s*("me=e-1
+syn match foxproFunc "\<gomo\%[nth]\>\s*("me=e-1
+syn match foxproFunc "\<head\%[er]\>\s*("me=e-1
+syn match foxproFunc "\<home\>\s*("me=e-1
+syn match foxproFunc "\<idxc\%[ollate]\>\s*("me=e-1
+syn match foxproFunc "\<iif\>\s*("me=e-1
+syn match foxproFunc "\<inke\%[y]\>\s*("me=e-1
+syn match foxproFunc "\<inli\%[st]\>\s*("me=e-1
+syn match foxproFunc "\<insm\%[ode]\>\s*("me=e-1
+syn match foxproFunc "\<int\>\s*("me=e-1
+syn match foxproFunc "\<isal\%[pha]\>\s*("me=e-1
+syn match foxproFunc "\<isbl\%[ank]\>\s*("me=e-1
+syn match foxproFunc "\<isco\%[lor]\>\s*("me=e-1
+syn match foxproFunc "\<isdi\%[git]\>\s*("me=e-1
+syn match foxproFunc "\<islo\%[wer]\>\s*("me=e-1
+syn match foxproFunc "\<isre\%[adonly]\>\s*("me=e-1
+syn match foxproFunc "\<isup\%[per]\>\s*("me=e-1
+syn match foxproFunc "\<key\>\s*("me=e-1
+syn match foxproFunc "\<keym\%[atch]\>\s*("me=e-1
+syn match foxproFunc "\<last\%[key]\>\s*("me=e-1
+syn match foxproFunc "\<left\>\s*("me=e-1
+syn match foxproFunc "\<len\>\s*("me=e-1
+syn match foxproFunc "\<like\>\s*("me=e-1
+syn match foxproFunc "\<line\%[no]\>\s*("me=e-1
+syn match foxproFunc "\<locf\%[ile]\>\s*("me=e-1
+syn match foxproFunc "\<lock\>\s*("me=e-1
+syn match foxproFunc "\<log\>\s*("me=e-1
+syn match foxproFunc "\<log1\%[0]\>\s*("me=e-1
+syn match foxproFunc "\<look\%[up]\>\s*("me=e-1
+syn match foxproFunc "\<lowe\%[r]\>\s*("me=e-1
+syn match foxproFunc "\<ltri\%[m]\>\s*("me=e-1
+syn match foxproFunc "\<lupd\%[ate]\>\s*("me=e-1
+syn match foxproFunc "\<max\>\s*("me=e-1
+syn match foxproFunc "\<mcol\>\s*("me=e-1
+syn match foxproFunc "\<mdow\%[n]\>\s*("me=e-1
+syn match foxproFunc "\<mdx\>\s*("me=e-1
+syn match foxproFunc "\<mdy\>\s*("me=e-1
+syn match foxproFunc "\<meml\%[ines]\>\s*("me=e-1
+syn match foxproFunc "\<memo\%[ry]\>\s*("me=e-1
+syn match foxproFunc "\<menu\>\s*("me=e-1
+syn match foxproFunc "\<mess\%[age]\>\s*("me=e-1
+syn match foxproFunc "\<min\>\s*("me=e-1
+syn match foxproFunc "\<mlin\%[e]\>\s*("me=e-1
+syn match foxproFunc "\<mod\>\s*("me=e-1
+syn match foxproFunc "\<mont\%[h]\>\s*("me=e-1
+syn match foxproFunc "\<mrkb\%[ar]\>\s*("me=e-1
+syn match foxproFunc "\<mrkp\%[ad]\>\s*("me=e-1
+syn match foxproFunc "\<mrow\>\s*("me=e-1
+syn match foxproFunc "\<mwin\%[dow]\>\s*("me=e-1
+syn match foxproFunc "\<ndx\>\s*("me=e-1
+syn match foxproFunc "\<norm\%[alize]\>\s*("me=e-1
+syn match foxproFunc "\<numl\%[ock]\>\s*("me=e-1
+syn match foxproFunc "\<objn\%[um]\>\s*("me=e-1
+syn match foxproFunc "\<objv\%[ar]\>\s*("me=e-1
+syn match foxproFunc "\<occu\%[rs]\>\s*("me=e-1
+syn match foxproFunc "\<oemt\%[oansi]\>\s*("me=e-1
+syn match foxproFunc "\<on\>\s*("me=e-1
+syn match foxproFunc "\<orde\%[r]\>\s*("me=e-1
+syn match foxproFunc "\<os\>\s*("me=e-1
+syn match foxproFunc "\<pad\>\s*("me=e-1
+syn match foxproFunc "\<padc\>\s*("me=e-1
+syn match foxproFunc "\<padl\>\s*("me=e-1
+syn match foxproFunc "\<padr\>\s*("me=e-1
+syn match foxproFunc "\<para\%[meters]\>\s*("me=e-1
+syn match foxproFunc "\<paym\%[ent]\>\s*("me=e-1
+syn match foxproFunc "\<pcol\>\s*("me=e-1
+syn match foxproFunc "\<pi\>\s*("me=e-1
+syn match foxproFunc "\<popu\%[p]\>\s*("me=e-1
+syn match foxproFunc "\<prin\%[tstatus]\>\s*("me=e-1
+syn match foxproFunc "\<prmb\%[ar]\>\s*("me=e-1
+syn match foxproFunc "\<prmp\%[ad]\>\s*("me=e-1
+syn match foxproFunc "\<prog\%[ram]\>\s*("me=e-1
+syn match foxproFunc "\<prom\%[pt]\>\s*("me=e-1
+syn match foxproFunc "\<prop\%[er]\>\s*("me=e-1
+syn match foxproFunc "\<prow\>\s*("me=e-1
+syn match foxproFunc "\<prti\%[nfo]\>\s*("me=e-1
+syn match foxproFunc "\<putf\%[ile]\>\s*("me=e-1
+syn match foxproFunc "\<pv\>\s*("me=e-1
+syn match foxproFunc "\<rand\>\s*("me=e-1
+syn match foxproFunc "\<rat\>\s*("me=e-1
+syn match foxproFunc "\<ratl\%[ine]\>\s*("me=e-1
+syn match foxproFunc "\<rdle\%[vel]\>\s*("me=e-1
+syn match foxproFunc "\<read\%[key]\>\s*("me=e-1
+syn match foxproFunc "\<recc\%[ount]\>\s*("me=e-1
+syn match foxproFunc "\<recn\%[o]\>\s*("me=e-1
+syn match foxproFunc "\<recs\%[ize]\>\s*("me=e-1
+syn match foxproFunc "\<rela\%[tion]\>\s*("me=e-1
+syn match foxproFunc "\<repl\%[icate]\>\s*("me=e-1
+syn match foxproFunc "\<rgbs\%[cheme]\>\s*("me=e-1
+syn match foxproFunc "\<righ\%[t]\>\s*("me=e-1
+syn match foxproFunc "\<rloc\%[k]\>\s*("me=e-1
+syn match foxproFunc "\<roun\%[d]\>\s*("me=e-1
+syn match foxproFunc "\<row\>\s*("me=e-1
+syn match foxproFunc "\<rtod\>\s*("me=e-1
+syn match foxproFunc "\<rtri\%[m]\>\s*("me=e-1
+syn match foxproFunc "\<sche\%[me]\>\s*("me=e-1
+syn match foxproFunc "\<scol\%[s]\>\s*("me=e-1
+syn match foxproFunc "\<seco\%[nds]\>\s*("me=e-1
+syn match foxproFunc "\<seek\>\s*("me=e-1
+syn match foxproFunc "\<sele\%[ct]\>\s*("me=e-1
+syn match foxproFunc "\<set\>\s*("me=e-1
+syn match foxproFunc "\<sign\>\s*("me=e-1
+syn match foxproFunc "\<sin\>\s*("me=e-1
+syn match foxproFunc "\<skpb\%[ar]\>\s*("me=e-1
+syn match foxproFunc "\<skpp\%[ad]\>\s*("me=e-1
+syn match foxproFunc "\<soun\%[dex]\>\s*("me=e-1
+syn match foxproFunc "\<spac\%[e]\>\s*("me=e-1
+syn match foxproFunc "\<sqrt\>\s*("me=e-1
+syn match foxproFunc "\<srow\%[s]\>\s*("me=e-1
+syn match foxproFunc "\<str\>\s*("me=e-1
+syn match foxproFunc "\<strt\%[ran]\>\s*("me=e-1
+syn match foxproFunc "\<stuf\%[f]\>\s*("me=e-1
+syn match foxproFunc "\<subs\%[tr]\>\s*("me=e-1
+syn match foxproFunc "\<sysm\%[etric]\>\s*("me=e-1
+syn match foxproFunc "\<sys\>\s*("me=e-1
+syn match foxproFunc "\<tag\>\s*("me=e-1
+syn match foxproFunc "\<tagc\%[ount]\>\s*("me=e-1
+syn match foxproFunc "\<tagn\%[o]\>\s*("me=e-1
+syn match foxproFunc "\<tan\>\s*("me=e-1
+syn match foxproFunc "\<targ\%[et]\>\s*("me=e-1
+syn match foxproFunc "\<time\>\s*("me=e-1
+syn match foxproFunc "\<tran\%[sform]\>\s*("me=e-1
+syn match foxproFunc "\<trim\>\s*("me=e-1
+syn match foxproFunc "\<txtw\%[idth]\>\s*("me=e-1
+syn match foxproFunc "\<type\>\s*("me=e-1
+syn match foxproFunc "\<uniq\%[ue]\>\s*("me=e-1
+syn match foxproFunc "\<upda\%[ted]\>\s*("me=e-1
+syn match foxproFunc "\<uppe\%[r]\>\s*("me=e-1
+syn match foxproFunc "\<used\>\s*("me=e-1
+syn match foxproFunc "\<val\>\s*("me=e-1
+syn match foxproFunc "\<varr\%[ead]\>\s*("me=e-1
+syn match foxproFunc "\<vers\%[ion]\>\s*("me=e-1
+syn match foxproFunc "\<wbor\%[der]\>\s*("me=e-1
+syn match foxproFunc "\<wchi\%[ld]\>\s*("me=e-1
+syn match foxproFunc "\<wcol\%[s]\>\s*("me=e-1
+syn match foxproFunc "\<wexi\%[st]\>\s*("me=e-1
+syn match foxproFunc "\<wfon\%[t]\>\s*("me=e-1
+syn match foxproFunc "\<wlas\%[t]\>\s*("me=e-1
+syn match foxproFunc "\<wlco\%[l]\>\s*("me=e-1
+syn match foxproFunc "\<wlro\%[w]\>\s*("me=e-1
+syn match foxproFunc "\<wmax\%[imum]\>\s*("me=e-1
+syn match foxproFunc "\<wmin\%[imum]\>\s*("me=e-1
+syn match foxproFunc "\<wont\%[op]\>\s*("me=e-1
+syn match foxproFunc "\<wout\%[put]\>\s*("me=e-1
+syn match foxproFunc "\<wpar\%[ent]\>\s*("me=e-1
+syn match foxproFunc "\<wrea\%[d]\>\s*("me=e-1
+syn match foxproFunc "\<wrow\%[s]\>\s*("me=e-1
+syn match foxproFunc "\<wtit\%[le]\>\s*("me=e-1
+syn match foxproFunc "\<wvis\%[ible]\>\s*("me=e-1
+syn match foxproFunc "\<year\>\s*("me=e-1
+
+" Commands
+syn match foxproCmd "^\s*\<acce\%[pt]\>"
+syn match foxproCmd "^\s*\<acti\%[vate]\>\s*\<menu\>"
+syn match foxproCmd "^\s*\<acti\%[vate]\>\s*\<popu\%[p]\>"
+syn match foxproCmd "^\s*\<acti\%[vate]\>\s*\<scre\%[en]\>"
+syn match foxproCmd "^\s*\<acti\%[vate]\>\s*\<wind\%[ow]\>"
+syn match foxproCmd "^\s*\<appe\%[nd]\>"
+syn match foxproCmd "^\s*\<appe\%[nd]\>\s*\<from\>"
+syn match foxproCmd "^\s*\<appe\%[nd]\>\s*\<from\>\s*\<arra\%[y]\>"
+syn match foxproCmd "^\s*\<appe\%[nd]\>\s*\<gene\%[ral]\>"
+syn match foxproCmd "^\s*\<appe\%[nd]\>\s*\<memo\>"
+syn match foxproCmd "^\s*\<assi\%[st]\>"
+syn match foxproCmd "^\s*\<aver\%[age]\>"
+syn match foxproCmd "^\s*\<blan\%[k]\>"
+syn match foxproCmd "^\s*\<brow\%[se]\>"
+syn match foxproCmd "^\s*\<buil\%[d]\>\s*\<app\>"
+syn match foxproCmd "^\s*\<buil\%[d]\>\s*\<exe\>"
+syn match foxproCmd "^\s*\<buil\%[d]\>\s*\<proj\%[ect]\>"
+syn match foxproCmd "^\s*\<calc\%[ulate]\>"
+syn match foxproCmd "^\s*\<call\>"
+syn match foxproCmd "^\s*\<canc\%[el]\>"
+syn match foxproCmd "^\s*\<chan\%[ge]\>"
+syn match foxproCmd "^\s*\<clea\%[r]\>"
+syn match foxproCmd "^\s*\<clos\%[e]\>"
+syn match foxproCmd "^\s*\<clos\%[e]\>\s*\<memo\>"
+syn match foxproCmd "^\s*\<comp\%[ile]\>"
+syn match foxproCmd "^\s*\<cont\%[inue]\>"
+syn match foxproCmd "^\s*\<copy\>\s*\<file\>"
+syn match foxproCmd "^\s*\<copy\>\s*\<inde\%[xes]\>"
+syn match foxproCmd "^\s*\<copy\>\s*\<memo\>"
+syn match foxproCmd "^\s*\<copy\>\s*\<stru\%[cture]\>"
+syn match foxproCmd "^\s*\<copy\>\s*\<stru\%[cture]\>\s*\<exte\%[nded]\>"
+syn match foxproCmd "^\s*\<copy\>\s*\<tag\>"
+syn match foxproCmd "^\s*\<copy\>\s*\<to\>"
+syn match foxproCmd "^\s*\<copy\>\s*\<to\>\s*\<arra\%[y]\>"
+syn match foxproCmd "^\s*\<coun\%[t]\>"
+syn match foxproCmd "^\s*\<crea\%[te]\>"
+syn match foxproCmd "^\s*\<crea\%[te]\>\s*\<colo\%[r]\>\s*\<set\>"
+syn match foxproCmd "^\s*\<crea\%[te]\>\s*\<curs\%[or]\>"
+syn match foxproCmd "^\s*\<crea\%[te]\>\s*\<from\>"
+syn match foxproCmd "^\s*\<crea\%[te]\>\s*\<labe\%[l]\>"
+syn match foxproCmd "^\s*\<crea\%[te]\>\s*\<menu\>"
+syn match foxproCmd "^\s*\<crea\%[te]\>\s*\<proj\%[ect]\>"
+syn match foxproCmd "^\s*\<crea\%[te]\>\s*\<quer\%[y]\>"
+syn match foxproCmd "^\s*\<crea\%[te]\>\s*\<repo\%[rt]\>"
+syn match foxproCmd "^\s*\<crea\%[te]\>\s*\<scre\%[en]\>"
+syn match foxproCmd "^\s*\<crea\%[te]\>\s*\<tabl\%[e]\>"
+syn match foxproCmd "^\s*\<crea\%[te]\>\s*\<view\>"
+syn match foxproCmd "^\s*\<dde\>"
+syn match foxproCmd "^\s*\<deac\%[tivate]\>\s*\<menu\>"
+syn match foxproCmd "^\s*\<deac\%[tivate]\>\s*\<popu\%[p]\>"
+syn match foxproCmd "^\s*\<deac\%[tivate]\>\s*\<wind\%[ow]\>"
+syn match foxproCmd "^\s*\<decl\%[are]\>"
+syn match foxproCmd "^\s*\<defi\%[ne]\>\s*\<bar\>"
+syn match foxproCmd "^\s*\<defi\%[ne]\>\s*\<box\>"
+syn match foxproCmd "^\s*\<defi\%[ne]\>\s*\<menu\>"
+syn match foxproCmd "^\s*\<defi\%[ne]\>\s*\<pad\>"
+syn match foxproCmd "^\s*\<defi\%[ne]\>\s*\<popu\%[p]\>"
+syn match foxproCmd "^\s*\<defi\%[ne]\>\s*\<wind\%[ow]\>"
+syn match foxproCmd "^\s*\<dele\%[te]\>"
+syn match foxproCmd "^\s*\<dele\%[te]\>\s*\<file\>"
+syn match foxproCmd "^\s*\<dele\%[te]\>\s*\<tag\>"
+syn match foxproCmd "^\s*\<dime\%[nsion]\>"
+syn match foxproCmd "^\s*\<dire\%[ctory]\>"
+syn match foxproCmd "^\s*\<disp\%[lay]\>"
+syn match foxproCmd "^\s*\<disp\%[lay]\>\s*\<file\%[s]\>"
+syn match foxproCmd "^\s*\<disp\%[lay]\>\s*\<memo\%[ry]\>"
+syn match foxproCmd "^\s*\<disp\%[lay]\>\s*\<stat\%[us]\>"
+syn match foxproCmd "^\s*\<disp\%[lay]\>\s*\<stru\%[cture]\>"
+syn match foxproCmd "^\s*\<do\>"
+syn match foxproCmd "^\s*\<edit\>"
+syn match foxproCmd "^\s*\<ejec\%[t]\>"
+syn match foxproCmd "^\s*\<ejec\%[t]\>\s*\<page\>"
+syn match foxproCmd "^\s*\<eras\%[e]\>"
+syn match foxproCmd "^\s*\<exit\>"
+syn match foxproCmd "^\s*\<expo\%[rt]\>"
+syn match foxproCmd "^\s*\<exte\%[rnal]\>"
+syn match foxproCmd "^\s*\<file\%[r]\>"
+syn match foxproCmd "^\s*\<find\>"
+syn match foxproCmd "^\s*\<flus\%[h]\>"
+syn match foxproCmd "^\s*\<func\%[tion]\>"
+syn match foxproCmd "^\s*\<gath\%[er]\>"
+syn match foxproCmd "^\s*\<gete\%[xpr]\>"
+syn match foxproCmd "^\s*\<go\>"
+syn match foxproCmd "^\s*\<goto\>"
+syn match foxproCmd "^\s*\<help\>"
+syn match foxproCmd "^\s*\<hide\>\s*\<menu\>"
+syn match foxproCmd "^\s*\<hide\>\s*\<popu\%[p]\>"
+syn match foxproCmd "^\s*\<hide\>\s*\<wind\%[ow]\>"
+syn match foxproCmd "^\s*\<impo\%[rt]\>"
+syn match foxproCmd "^\s*\<inde\%[x]\>"
+syn match foxproCmd "^\s*\<inpu\%[t]\>"
+syn match foxproCmd "^\s*\<inse\%[rt]\>"
+syn match foxproCmd "^\s*\<join\>"
+syn match foxproCmd "^\s*\<keyb\%[oard]\>"
+syn match foxproCmd "^\s*\<labe\%[l]\>"
+syn match foxproCmd "^\s*\<list\>"
+syn match foxproCmd "^\s*\<load\>"
+syn match foxproCmd "^\s*\<loca\%[te]\>"
+syn match foxproCmd "^\s*\<loop\>"
+syn match foxproCmd "^\s*\<menu\>"
+syn match foxproCmd "^\s*\<menu\>\s*\<to\>"
+syn match foxproCmd "^\s*\<modi\%[fy]\>\s*\<comm\%[and]\>"
+syn match foxproCmd "^\s*\<modi\%[fy]\>\s*\<file\>"
+syn match foxproCmd "^\s*\<modi\%[fy]\>\s*\<gene\%[ral]\>"
+syn match foxproCmd "^\s*\<modi\%[fy]\>\s*\<labe\%[l]\>"
+syn match foxproCmd "^\s*\<modi\%[fy]\>\s*\<memo\>"
+syn match foxproCmd "^\s*\<modi\%[fy]\>\s*\<menu\>"
+syn match foxproCmd "^\s*\<modi\%[fy]\>\s*\<proj\%[ect]\>"
+syn match foxproCmd "^\s*\<modi\%[fy]\>\s*\<quer\%[y]\>"
+syn match foxproCmd "^\s*\<modi\%[fy]\>\s*\<repo\%[rt]\>"
+syn match foxproCmd "^\s*\<modi\%[fy]\>\s*\<scre\%[en]\>"
+syn match foxproCmd "^\s*\<modi\%[fy]\>\s*\<stru\%[cture]\>"
+syn match foxproCmd "^\s*\<modi\%[fy]\>\s*\<wind\%[ow]\>"
+syn match foxproCmd "^\s*\<move\>\s*\<popu\%[p]\>"
+syn match foxproCmd "^\s*\<move\>\s*\<wind\%[ow]\>"
+syn match foxproCmd "^\s*\<note\>"
+syn match foxproCmd "^\s*\<on\>\s*\<apla\%[bout]\>"
+syn match foxproCmd "^\s*\<on\>\s*\<bar\>"
+syn match foxproCmd "^\s*\<on\>\s*\<erro\%[r]\>"
+syn match foxproCmd "^\s*\<on\>\s*\<esca\%[pe]\>"
+syn match foxproCmd "^\s*\<on\>\s*\<exit\>\s*\<bar\>"
+syn match foxproCmd "^\s*\<on\>\s*\<exit\>\s*\<menu\>"
+syn match foxproCmd "^\s*\<on\>\s*\<exit\>\s*\<pad\>"
+syn match foxproCmd "^\s*\<on\>\s*\<exit\>\s*\<popu\%[p]\>"
+syn match foxproCmd "^\s*\<on\>\s*\<key\>"
+syn match foxproCmd "^\s*\<on\>\s*\<key\>\s*\<=\>"
+syn match foxproCmd "^\s*\<on\>\s*\<key\>\s*\<labe\%[l]\>"
+syn match foxproCmd "^\s*\<on\>\s*\<mach\%[elp]\>"
+syn match foxproCmd "^\s*\<on\>\s*\<pad\>"
+syn match foxproCmd "^\s*\<on\>\s*\<page\>"
+syn match foxproCmd "^\s*\<on\>\s*\<read\%[error]\>"
+syn match foxproCmd "^\s*\<on\>\s*\<sele\%[ction]\>\s*\<bar\>"
+syn match foxproCmd "^\s*\<on\>\s*\<sele\%[ction]\>\s*\<menu\>"
+syn match foxproCmd "^\s*\<on\>\s*\<sele\%[ction]\>\s*\<pad\>"
+syn match foxproCmd "^\s*\<on\>\s*\<sele\%[ction]\>\s*\<popu\%[p]\>"
+syn match foxproCmd "^\s*\<on\>\s*\<shut\%[down]\>"
+syn match foxproCmd "^\s*\<pack\>"
+syn match foxproCmd "^\s*\<para\%[meters]\>"
+syn match foxproCmd "^\s*\<play\>\s*\<macr\%[o]\>"
+syn match foxproCmd "^\s*\<pop\>\s*\<key\>"
+syn match foxproCmd "^\s*\<pop\>\s*\<menu\>"
+syn match foxproCmd "^\s*\<pop\>\s*\<popu\%[p]\>"
+syn match foxproCmd "^\s*\<priv\%[ate]\>"
+syn match foxproCmd "^\s*\<proc\%[edure]\>"
+syn match foxproCmd "^\s*\<publ\%[ic]\>"
+syn match foxproCmd "^\s*\<push\>\s*\<key\>"
+syn match foxproCmd "^\s*\<push\>\s*\<menu\>"
+syn match foxproCmd "^\s*\<push\>\s*\<popu\%[p]\>"
+syn match foxproCmd "^\s*\<quit\>"
+syn match foxproCmd "^\s*\<read\>"
+syn match foxproCmd "^\s*\<read\>\s*\<menu\>"
+syn match foxproCmd "^\s*\<reca\%[ll]\>"
+syn match foxproCmd "^\s*\<rein\%[dex]\>"
+syn match foxproCmd "^\s*\<rele\%[ase]\>"
+syn match foxproCmd "^\s*\<rele\%[ase]\>\s*\<modu\%[le]\>"
+syn match foxproCmd "^\s*\<rena\%[me]\>"
+syn match foxproCmd "^\s*\<repl\%[ace]\>"
+syn match foxproCmd "^\s*\<repl\%[ace]\>\s*\<from\>\s*\<arra\%[y]\>"
+syn match foxproCmd "^\s*\<repo\%[rt]\>"
+syn match foxproCmd "^\s*\<rest\%[ore]\>\s*\<from\>"
+syn match foxproCmd "^\s*\<rest\%[ore]\>\s*\<macr\%[os]\>"
+syn match foxproCmd "^\s*\<rest\%[ore]\>\s*\<scre\%[en]\>"
+syn match foxproCmd "^\s*\<rest\%[ore]\>\s*\<wind\%[ow]\>"
+syn match foxproCmd "^\s*\<resu\%[me]\>"
+syn match foxproCmd "^\s*\<retr\%[y]\>"
+syn match foxproCmd "^\s*\<retu\%[rn]\>"
+syn match foxproCmd "^\s*\<run\>"
+syn match foxproCmd "^\s*\<run\>\s*\/n"
+syn match foxproCmd "^\s*\<runs\%[cript]\>"
+syn match foxproCmd "^\s*\<save\>\s*\<macr\%[os]\>"
+syn match foxproCmd "^\s*\<save\>\s*\<scre\%[en]\>"
+syn match foxproCmd "^\s*\<save\>\s*\<to\>"
+syn match foxproCmd "^\s*\<save\>\s*\<wind\%[ows]\>"
+syn match foxproCmd "^\s*\<scat\%[ter]\>"
+syn match foxproCmd "^\s*\<scro\%[ll]\>"
+syn match foxproCmd "^\s*\<seek\>"
+syn match foxproCmd "^\s*\<sele\%[ct]\>"
+syn match foxproCmd "^\s*\<set\>"
+syn match foxproCmd "^\s*\<set\>\s*\<alte\%[rnate]\>"
+syn match foxproCmd "^\s*\<set\>\s*\<ansi\>"
+syn match foxproCmd "^\s*\<set\>\s*\<apla\%[bout]\>"
+syn match foxproCmd "^\s*\<set\>\s*\<auto\%[save]\>"
+syn match foxproCmd "^\s*\<set\>\s*\<bell\>"
+syn match foxproCmd "^\s*\<set\>\s*\<blin\%[k]\>"
+syn match foxproCmd "^\s*\<set\>\s*\<bloc\%[ksize]\>"
+syn match foxproCmd "^\s*\<set\>\s*\<bord\%[er]\>"
+syn match foxproCmd "^\s*\<set\>\s*\<brst\%[atus]\>"
+syn match foxproCmd "^\s*\<set\>\s*\<carr\%[y]\>"
+syn match foxproCmd "^\s*\<set\>\s*\<cent\%[ury]\>"
+syn match foxproCmd "^\s*\<set\>\s*\<clea\%[r]\>"
+syn match foxproCmd "^\s*\<set\>\s*\<cloc\%[k]\>"
+syn match foxproCmd "^\s*\<set\>\s*\<coll\%[ate]\>"
+syn match foxproCmd "^\s*\<set\>\s*\<colo\%[r]\>\s*\<of\>"
+syn match foxproCmd "^\s*\<set\>\s*\<colo\%[r]\>\s*\<of\>\s*\<sche\%[me]\>"
+syn match foxproCmd "^\s*\<set\>\s*\<colo\%[r]\>\s*\<set\>"
+syn match foxproCmd "^\s*\<set\>\s*\<colo\%[r]\>\s*\<to\>"
+syn match foxproCmd "^\s*\<set\>\s*\<comp\%[atible]\>"
+syn match foxproCmd "^\s*\<set\>\s*\<conf\%[irm]\>"
+syn match foxproCmd "^\s*\<set\>\s*\<cons\%[ole]\>"
+syn match foxproCmd "^\s*\<set\>\s*\<curr\%[ency]\>"
+syn match foxproCmd "^\s*\<set\>\s*\<curs\%[or]\>"
+syn match foxproCmd "^\s*\<set\>\s*\<date\>"
+syn match foxproCmd "^\s*\<set\>\s*\<debu\%[g]\>"
+syn match foxproCmd "^\s*\<set\>\s*\<deci\%[mals]\>"
+syn match foxproCmd "^\s*\<set\>\s*\<defa\%[ult]\>"
+syn match foxproCmd "^\s*\<set\>\s*\<dele\%[ted]\>"
+syn match foxproCmd "^\s*\<set\>\s*\<deli\%[miters]\>"
+syn match foxproCmd "^\s*\<set\>\s*\<deve\%[lopment]\>"
+syn match foxproCmd "^\s*\<set\>\s*\<devi\%[ce]\>"
+syn match foxproCmd "^\s*\<set\>\s*\<disp\%[lay]\>"
+syn match foxproCmd "^\s*\<set\>\s*\<dohi\%[story]\>"
+syn match foxproCmd "^\s*\<set\>\s*\<echo\>"
+syn match foxproCmd "^\s*\<set\>\s*\<esca\%[pe]\>"
+syn match foxproCmd "^\s*\<set\>\s*\<exac\%[t]\>"
+syn match foxproCmd "^\s*\<set\>\s*\<excl\%[usive]\>"
+syn match foxproCmd "^\s*\<set\>\s*\<fiel\%[ds]\>"
+syn match foxproCmd "^\s*\<set\>\s*\<filt\%[er]\>"
+syn match foxproCmd "^\s*\<set\>\s*\<fixe\%[d]\>"
+syn match foxproCmd "^\s*\<set\>\s*\<form\%[at]\>"
+syn match foxproCmd "^\s*\<set\>\s*\<full\%[path]\>"
+syn match foxproCmd "^\s*\<set\>\s*\<func\%[tion]\>"
+syn match foxproCmd "^\s*\<set\>\s*\<head\%[ings]\>"
+syn match foxproCmd "^\s*\<set\>\s*\<help\>"
+syn match foxproCmd "^\s*\<set\>\s*\<help\%[filter]\>"
+syn match foxproCmd "^\s*\<set\>\s*\<hour\%[s]\>"
+syn match foxproCmd "^\s*\<set\>\s*\<inde\%[x]\>"
+syn match foxproCmd "^\s*\<set\>\s*\<inte\%[nsity]\>"
+syn match foxproCmd "^\s*\<set\>\s*\<key\>"
+syn match foxproCmd "^\s*\<set\>\s*\<keyc\%[omp]\>"
+syn match foxproCmd "^\s*\<set\>\s*\<libr\%[ary]\>"
+syn match foxproCmd "^\s*\<set\>\s*\<lock\>"
+syn match foxproCmd "^\s*\<set\>\s*\<loge\%[rrors]\>"
+syn match foxproCmd "^\s*\<set\>\s*\<macd\%[esktop]\>"
+syn match foxproCmd "^\s*\<set\>\s*\<mach\%[elp]\>"
+syn match foxproCmd "^\s*\<set\>\s*\<mack\%[ey]\>"
+syn match foxproCmd "^\s*\<set\>\s*\<marg\%[in]\>"
+syn match foxproCmd "^\s*\<set\>\s*\<mark\>\s*\<of\>"
+syn match foxproCmd "^\s*\<set\>\s*\<mark\>\s*\<to\>"
+syn match foxproCmd "^\s*\<set\>\s*\<memo\%[width]\>"
+syn match foxproCmd "^\s*\<set\>\s*\<mess\%[age]\>"
+syn match foxproCmd "^\s*\<set\>\s*\<mous\%[e]\>"
+syn match foxproCmd "^\s*\<set\>\s*\<mult\%[ilocks]\>"
+syn match foxproCmd "^\s*\<set\>\s*\<near\>"
+syn match foxproCmd "^\s*\<set\>\s*\<nocp\%[trans]\>"
+syn match foxproCmd "^\s*\<set\>\s*\<noti\%[fy]\>"
+syn match foxproCmd "^\s*\<set\>\s*\<odom\%[eter]\>"
+syn match foxproCmd "^\s*\<set\>\s*\<opti\%[mize]\>"
+syn match foxproCmd "^\s*\<set\>\s*\<orde\%[r]\>"
+syn match foxproCmd "^\s*\<set\>\s*\<pale\%[tte]\>"
+syn match foxproCmd "^\s*\<set\>\s*\<path\>"
+syn match foxproCmd "^\s*\<set\>\s*\<pdse\%[tup]\>"
+syn match foxproCmd "^\s*\<set\>\s*\<poin\%[t]\>"
+syn match foxproCmd "^\s*\<set\>\s*\<prin\%[ter]\>"
+syn match foxproCmd "^\s*\<set\>\s*\<proc\%[edure]\>"
+syn match foxproCmd "^\s*\<set\>\s*\<read\%[border]\>"
+syn match foxproCmd "^\s*\<set\>\s*\<refr\%[esh]\>"
+syn match foxproCmd "^\s*\<set\>\s*\<rela\%[tion]\>"
+syn match foxproCmd "^\s*\<set\>\s*\<rela\%[tion]\>\s*\<off\>"
+syn match foxproCmd "^\s*\<set\>\s*\<repr\%[ocess]\>"
+syn match foxproCmd "^\s*\<set\>\s*\<reso\%[urce]\>"
+syn match foxproCmd "^\s*\<set\>\s*\<safe\%[ty]\>"
+syn match foxproCmd "^\s*\<set\>\s*\<scor\%[eboard]\>"
+syn match foxproCmd "^\s*\<set\>\s*\<sepa\%[rator]\>"
+syn match foxproCmd "^\s*\<set\>\s*\<shad\%[ows]\>"
+syn match foxproCmd "^\s*\<set\>\s*\<skip\>"
+syn match foxproCmd "^\s*\<set\>\s*\<skip\>\s*\<of\>"
+syn match foxproCmd "^\s*\<set\>\s*\<spac\%[e]\>"
+syn match foxproCmd "^\s*\<set\>\s*\<stat\%[us]\>"
+syn match foxproCmd "^\s*\<set\>\s*\<stat\%[us]\>\s*\<bar\>"
+syn match foxproCmd "^\s*\<set\>\s*\<step\>"
+syn match foxproCmd "^\s*\<set\>\s*\<stic\%[ky]\>"
+syn match foxproCmd "^\s*\<set\>\s*\<sysm\%[enu]\>"
+syn match foxproCmd "^\s*\<set\>\s*\<talk\>"
+syn match foxproCmd "^\s*\<set\>\s*\<text\%[merge]\>"
+syn match foxproCmd "^\s*\<set\>\s*\<text\%[merge]\>\s*\<deli\%[miters]\>"
+syn match foxproCmd "^\s*\<set\>\s*\<topi\%[c]\>"
+syn match foxproCmd "^\s*\<set\>\s*\<trbe\%[tween]\>"
+syn match foxproCmd "^\s*\<set\>\s*\<type\%[ahead]\>"
+syn match foxproCmd "^\s*\<set\>\s*\<udfp\%[arms]\>"
+syn match foxproCmd "^\s*\<set\>\s*\<uniq\%[ue]\>"
+syn match foxproCmd "^\s*\<set\>\s*\<view\>"
+syn match foxproCmd "^\s*\<set\>\s*\<volu\%[me]\>"
+syn match foxproCmd "^\s*\<set\>\s*\<wind\%[ow]\>\s*\<of\>\s*\<memo\>"
+syn match foxproCmd "^\s*\<set\>\s*\<xcmd\%[file]\>"
+syn match foxproCmd "^\s*\<show\>\s*\<get\>"
+syn match foxproCmd "^\s*\<show\>\s*\<gets\>"
+syn match foxproCmd "^\s*\<show\>\s*\<menu\>"
+syn match foxproCmd "^\s*\<show\>\s*\<obje\%[ct]\>"
+syn match foxproCmd "^\s*\<show\>\s*\<popu\%[p]\>"
+syn match foxproCmd "^\s*\<show\>\s*\<wind\%[ow]\>"
+syn match foxproCmd "^\s*\<size\>\s*\<popu\%[p]\>"
+syn match foxproCmd "^\s*\<skip\>"
+syn match foxproCmd "^\s*\<sort\>"
+syn match foxproCmd "^\s*\<stor\%[e]\>"
+syn match foxproCmd "^\s*\<sum\>"
+syn match foxproCmd "^\s*\<susp\%[end]\>"
+syn match foxproCmd "^\s*\<tota\%[l]\>"
+syn match foxproCmd "^\s*\<type\>"
+syn match foxproCmd "^\s*\<unlo\%[ck]\>"
+syn match foxproCmd "^\s*\<upda\%[te]\>"
+syn match foxproCmd "^\s*\<use\>"
+syn match foxproCmd "^\s*\<wait\>"
+syn match foxproCmd "^\s*\<zap\>"
+syn match foxproCmd "^\s*\<zoom\>\s*\<wind\%[ow]\>"
+
+" Enclosed Block
+syn match foxproEnBlk "^\s*\<do\>\s*\<case\>"
+syn match foxproEnBlk "^\s*\<case\>"
+syn match foxproEnBlk "^\s*\<othe\%[rwise]\>"
+syn match foxproEnBlk "^\s*\<endc\%[ase]\>"
+syn match foxproEnBlk "^\s*\<do\>\s*\<whil\%[e]\>"
+syn match foxproEnBlk "^\s*\<endd\%[o]\>"
+syn match foxproEnBlk "^\s*\<for\>"
+syn match foxproEnBlk "^\s*\<endf\%[or]\>"
+syn match foxproEnBlk "^\s*\<next\>"
+syn match foxproEnBlk "^\s*\<if\>"
+syn match foxproEnBlk "^\s*\<else\>"
+syn match foxproEnBlk "^\s*\<endi\%[f]\>"
+syn match foxproEnBlk "^\s*\<prin\%[tjob]\>"
+syn match foxproEnBlk "^\s*\<endp\%[rintjob]\>"
+syn match foxproEnBlk "^\s*\<scan\>"
+syn match foxproEnBlk "^\s*\<ends\%[can]\>"
+syn match foxproEnBlk "^\s*\<text\>"
+syn match foxproEnBlk "^\s*\<endt\%[ext]\>"
+
+" System Variables
+syn keyword foxproSysVar _alignment _assist _beautify _box _calcmem _calcvalue
+syn keyword foxproSysVar _cliptext _curobj _dblclick _diarydate _dos _foxdoc
+syn keyword foxproSysVar _foxgraph _gengraph _genmenu _genpd _genscrn _genxtab
+syn keyword foxproSysVar _indent _lmargin _mac _mline _padvance _pageno _pbpage
+syn keyword foxproSysVar _pcolno _pcopies _pdriver _pdsetup _pecode _peject _pepage
+syn keyword foxproSysVar _plength _plineno _ploffset _ppitch _pquality _pretext
+syn keyword foxproSysVar _pscode _pspacing _pwait _rmargin _shell _spellchk
+syn keyword foxproSysVar _startup _tabs _tally _text _throttle _transport _unix
+syn keyword foxproSysVar _windows _wrap
+
+" Strings
+syn region foxproString start=+"+ end=+"+ oneline
+syn region foxproString start=+'+ end=+'+ oneline
+syn region foxproString start=+\[+ end=+\]+ oneline
+
+" Constants
+syn match foxproConst "\.t\."
+syn match foxproConst "\.f\."
+
+"integer number, or floating point number without a dot and with "f".
+syn match foxproNumber "\<[0-9]\+\>"
+"floating point number, with dot, optional exponent
+syn match foxproFloat  "\<[0-9]\+\.[0-9]*\(e[-+]\=[0-9]\+\)\=\>"
+"floating point number, starting with a dot, optional exponent
+syn match foxproFloat  "\.[0-9]\+\(e[-+]\=[0-9]\+\)\=\>"
+"floating point number, without dot, with exponent
+syn match foxproFloat  "\<[0-9]\+e[-+]\=[0-9]\+\>"
+
+syn match foxproComment "^\s*\*.*"
+syn match foxproComment "&&.*"
+
+"catch errors caused by wrong parenthesis
+syn region foxproParen transparent start='(' end=')' contains=ALLBUT,foxproParenErr
+syn match foxproParenErr ")"
+
+syn sync minlines=1 maxlines=3
+
+" Define the default highlighting.
+" For version 5.7 and earlier: only when not done already
+" For version 5.8 and later: only when an item doesn't have highlighting yet
+if version >= 508 || !exists("did_foxpro_syn_inits")
+    if version < 508
+	let did_foxpro_syn_inits = 1
+	command -nargs=+ HiLink hi link <args>
+    else
+	command -nargs=+ HiLink hi def link <args>
+    endif
+
+    HiLink foxproSpecial  Special
+    HiLink foxproAtSymbol Special
+    HiLink foxproAtCmd    Statement
+    HiLink foxproPreProc  PreProc
+    HiLink foxproFunc     Identifier
+    HiLink foxproCmd      Statement
+    HiLink foxproEnBlk    Type
+    HiLink foxproSysVar   String
+    HiLink foxproString   String
+    HiLink foxproConst    Constant
+    HiLink foxproNumber   Number
+    HiLink foxproFloat    Float
+    HiLink foxproComment  Comment
+    HiLink foxproParenErr Error
+    HiLink foxproCBConst  PreProc
+    HiLink foxproCBField  Special
+    HiLink foxproCBVar    Identifier
+    HiLink foxproCBWin    Special
+    HiLink foxproCBObject Identifier
+
+    delcommand HiLink
+endif
+
+let b:current_syntax = "foxpro"
--- /dev/null
+++ b/lib/vimfiles/syntax/framescript.vim
@@ -1,0 +1,491 @@
+" Vim syntax file
+" Language:         FrameScript v4.0
+" Maintainer:       Nikolai Weibull <now@bitwi.se>
+" Latest Revision:  2007-02-22
+
+if exists("b:current_syntax")
+  finish
+endif
+
+let s:cpo_save = &cpo
+set cpo&vim
+
+syn match   framescriptOperator
+      \ '[+*/%=-]\|[><]=\=\|#[&|]'
+
+syn keyword framescriptTodo
+      \ contained
+      \ TODO FIXME XXX NOTE
+
+syn cluster framescriptCommentGroup
+      \ contains=
+      \   framescriptTodo,
+      \   @Spell
+
+syn match   framescriptComment
+      \ display
+      \ contains=@framescriptCommentGroup
+      \ '//.*$'
+
+syn region  framescriptComment
+      \ contains=@framescriptCommentGroup
+      \ matchgroup=framescriptCommentStart
+      \ start='/\*'
+      \ end='\*/'
+
+syn case ignore
+
+syn match   framescriptInclude
+      \ display
+      \ contains=framescriptIncluded
+      \ "^\s*<#Include\>\s*'"
+
+syn region  framescriptIncluded
+      \ contained
+      \ display
+      \ start=+'+
+      \ skip=+\\\\\|\\'+
+      \ end=+'+
+
+syn match   framescriptNumbers
+      \ display
+      \ transparent
+      \ contains=
+      \   framescriptInteger,
+      \   framescriptReal,
+      \   framescriptMetric,
+      \   framescriptCharacter
+      \ '\<\d\|\.\d'
+
+syn keyword framescriptBoolean
+      \ True False
+
+syn match   framescriptInteger
+      \ contained
+      \ display
+      \ '\d\+\>'
+
+syn match   framescriptInteger
+      \ contained
+      \ display
+      \ '\x\+H\>'
+
+syn match   framescriptInteger
+      \ contained
+      \ display
+      \ '[01]\+B\>'
+
+syn match   framescriptReal
+      \ contained
+      \ display
+      \ '\d\+\.\d*\|\.\d\+\>'
+
+syn match   framescriptMetric
+      \ contained
+      \ display
+      \ '\%(\d\+\%(\.\d*\)\=\|\.\d\+\)\%(pts\|in\|"\|cm\|mm\|pica\)\>'
+
+syn match   framescriptCharacter
+      \ contained
+      \ display
+      \ '\d\+S\>'
+
+syn region  framescriptString
+      \ contains=framescriptStringSpecialChar,@Spell
+      \ start=+'+
+      \ skip=+\\\\\|\\'+
+      \ end=+'+
+
+syn match   framescriptStringSpecialChar
+      \ contained
+      \ display
+      \ "\\[\\']"
+
+syn keyword framescriptConstant
+      \ BackSlash
+      \ CharCR
+      \ CharLF
+      \ CharTAB
+      \ ClientDir
+      \ ClientName
+      \ FslVersionMajor
+      \ FslVersionMinor
+      \ InstallName
+      \ InstalledScriptList
+      \ MainScript
+      \ NULL
+      \ ObjEndOffset
+      \ ProductRevision
+      \ Quote
+      \ ThisScript
+
+syn keyword framescriptOperator
+      \ not
+      \ and
+      \ or
+
+syn keyword framescriptSessionVariables
+      \ ErrorCode
+      \ ErrorMsg
+      \ DeclareVarMode
+      \ PlatformEncodingMode
+
+syn keyword framescriptStructure
+      \ Event
+      \ EndEvent
+
+syn keyword framescriptStatement
+      \ Sub
+      \ EndSub
+      \ Run
+      \ Function
+      \ EndFunction
+      \ Set
+      \ Add
+      \ Apply
+      \ CallClient
+      \ Close
+      \ Copy
+      \ Cut
+      \ DialogBox
+      \ Delete
+      \ Demote
+      \ Display
+      \ DocCompare
+      \ Export
+      \ Find
+      \ LeaveLoop
+      \ LeaveScript
+      \ LeaveSub
+      \ LoopNext
+      \ Merge
+      \ MsgBox
+      \ Paste
+      \ PopClipboard
+      \ PushClipboard
+      \ Read
+      \ Replace
+      \ Return
+      \ Sort
+      \ Split
+
+syn keyword framescriptStatement
+      \ nextgroup=framescriptApplySubStatement skipwhite skipempty
+      \ Apply
+
+syn keyword framescriptApplySubStatement
+      \ contained
+      \ Pagelayout
+      \ TextProperties
+
+syn keyword framescriptStatement
+      \ nextgroup=framescriptClearSubStatement skipwhite skipempty
+      \ Clear
+
+syn keyword framescriptClearSubStatement
+      \ contained
+      \ ChangeBars
+      \ Text
+
+syn keyword framescriptStatement
+      \ nextgroup=framescriptCloseSubStatement skipwhite skipempty
+      \ Close
+
+syn keyword framescriptCloseSubStatement
+      \ contained
+      \ Book
+      \ Document
+      \ TextFile
+
+syn keyword framescriptStatement
+      \ nextgroup=framescriptExecSubStatement skipwhite skipempty
+      \ Exec
+
+syn keyword framescriptExecSubStatement
+      \ contained
+      \ Compile
+      \ Script
+      \ Wait
+
+syn keyword framescriptStatement
+      \ nextgroup=framescriptExecuteSubStatement skipwhite skipempty
+      \ Execute
+
+syn keyword framescriptExecuteSubStatement
+      \ contained
+      \ FrameCommand
+      \ Hypertext
+      \ StartUndoCheckPoint
+      \ EndUndoCheckPoint
+      \ ClearUndoHistory
+
+syn keyword framescriptStatement
+      \ nextgroup=framescriptGenerateSubStatement skipwhite skipempty
+      \ Generate
+
+syn keyword framescriptGenerateSubStatement
+      \ contained
+      \ Bookfile
+
+syn keyword framescriptStatement
+      \ nextgroup=framescriptGetSubStatement skipwhite skipempty
+      \ Get
+
+syn keyword framescriptGetSubStatement
+      \ contained
+      \ Member
+      \ Object
+      \ String
+      \ TextList
+      \ TextProperties
+
+syn keyword framescriptStatement
+      \ nextgroup=framescriptImportSubStatement skipwhite skipempty
+      \ Import
+
+syn keyword framescriptImportSubStatement
+      \ contained
+      \ File
+      \ Formats
+      \ ElementDefs
+
+syn keyword framescriptStatement
+      \ nextgroup=framescriptInstallSubStatement skipwhite skipempty
+      \ Install
+      \ Uninstall
+
+syn keyword framescriptInstallSubStatement
+      \ contained
+      \ ChangeBars
+      \ Text
+
+syn keyword framescriptStatement
+      \ nextgroup=framescriptNewSubStatement skipwhite skipempty
+      \ New
+
+syn keyword framescriptNewSubStatement
+      \ contained
+      \ AFrame
+      \ Footnote
+      \ Marker
+      \ TiApiClient
+      \ Variable
+      \ XRef
+      \ FormatChangeList
+      \ FormatRule
+      \ FmtRuleClause
+      \ Arc
+      \ Ellipse
+      \ Flow
+      \ Group
+      \ Inset
+      \ Line
+      \ Math
+      \ Polygon
+      \ Polyline
+      \ Rectangle
+      \ RoundRect
+      \ TextFrame
+      \ Textline
+      \ UnanchoredFrame
+      \ Command
+      \ Menu
+      \ MenuItemSeparator
+      \ Book
+      \ CharacterFormat
+      \ Color
+      \ ConditionFormat
+      \ ElementDef
+      \ FormatChangeList
+      \ MarkerType
+      \ MasterPage
+      \ ParagraphFormat
+      \ PgfFmt
+      \ ReferencePAge
+      \ RulingFormat
+      \ TableFormat
+      \ VariableFormat
+      \ XRefFormat
+      \ BodyPage
+      \ BookComponent
+      \ Paragraph
+      \ Element
+      \ Attribute
+      \ AttributeDef
+      \ AttributeList
+      \ AttributeDefList
+      \ ElementLoc
+      \ ElementRange
+      \ Table
+      \ TableRows
+      \ TableCols
+      \ Text
+      \ Integer
+      \ Real
+      \ Metric
+      \ String
+      \ Object
+      \ TextLoc
+      \ TextRange
+      \ IntList
+      \ UIntList
+      \ MetricList
+      \ StringList
+      \ PointList
+      \ TabList
+      \ PropertyList
+      \ LibVar
+      \ ScriptVar
+      \ SubVar
+      \ TextFile
+
+syn keyword framescriptStatement
+      \ nextgroup=framescriptOpenSubStatement skipwhite skipempty
+      \ Open
+
+syn keyword framescriptOpenSubStatement
+      \ contained
+      \ Document
+      \ Book
+      \ TextFile
+
+syn keyword framescriptStatement
+      \ nextgroup=framescriptPrintSubStatement skipwhite skipempty
+      \ Print
+
+syn keyword framescriptPrintSubStatement
+      \ contained
+      \ Document
+      \ Book
+
+syn keyword framescriptStatement
+      \ nextgroup=framescriptQuitSubStatement skipwhite skipempty
+      \ Quit
+
+syn keyword framescriptQuitSubStatement
+      \ contained
+      \ Session
+
+syn keyword framescriptStatement
+      \ nextgroup=framescriptRemoveSubStatement skipwhite skipempty
+      \ Remove
+
+syn keyword framescriptRemoveSubStatement
+      \ contained
+      \ Attribute
+      \ CommandObject
+
+syn keyword framescriptStatement
+      \ nextgroup=framescriptSaveSubStatement skipwhite skipempty
+      \ Save
+
+syn keyword framescriptSaveSubStatement
+      \ contained
+      \ Document
+      \ Book
+
+syn keyword framescriptStatement
+      \ nextgroup=framescriptSelectSubStatement skipwhite skipempty
+      \ Select
+
+syn keyword framescriptSelectSubStatement
+      \ contained
+      \ TableCells
+
+syn keyword framescriptStatement
+      \ nextgroup=framescriptStraddleSubStatement skipwhite skipempty
+      \ Straddle
+
+syn keyword framescriptStraddleSubStatement
+      \ contained
+      \ TableCells
+
+syn keyword framescriptStatement
+      \ nextgroup=framescriptUpdateSubStatement skipwhite skipempty
+      \ Update
+
+syn keyword framescriptUpdateSubStatement
+      \ contained
+      \ ReDisplay
+      \ Formatting
+      \ Hyphenating
+      \ ResetEquationsSettings
+      \ ResetRefFrames
+      \ RestartPgfNums
+      \ TextInset
+      \ Variables
+      \ XRefs
+      \ Book
+
+syn keyword framescriptStatement
+      \ nextgroup=framescriptWriteSubStatement skipwhite skipempty
+      \ Write
+
+syn keyword framescriptUpdateSubStatement
+      \ contained
+      \ Console
+      \ Display
+
+syn keyword framescriptRepeat
+      \ Loop
+      \ EndLoop
+
+syn keyword framescriptConditional
+      \ If
+      \ ElseIf
+      \ Else
+      \ EndIf
+
+syn keyword framescriptType
+      \ Local
+      \ GlobalVar
+
+let b:framescript_minlines = exists("framescript_minlines")
+                         \ ? framescript_minlines : 15
+exec "syn sync ccomment framescriptComment minlines=" . b:framescript_minlines
+
+hi def link framescriptTodo                 Todo
+hi def link framescriptComment              Comment
+hi def link framescriptCommentStart         framescriptComment
+hi def link framescriptInclude              Include
+hi def link framescriptIncluded             String
+hi def link framescriptBoolean              Boolean
+hi def link framescriptNumber               Number
+hi def link framescriptInteger              framescriptNumber
+hi def link framescriptReal                 framescriptNumber
+hi def link framescriptMetric               framescriptNumber
+hi def link framescriptCharacter            framescriptNumber
+hi def link framescriptString               String
+hi def link framescriptStringSpecialChar    SpecialChar
+hi def link framescriptConstant             Constant
+hi def link framescriptOperator             None
+hi def link framescriptSessionVariables     PreProc
+hi def link framescriptStructure            Structure
+hi def link framescriptStatement            Statement
+hi def link framescriptSubStatement         Type
+hi def link framescriptApplySubStatement    framescriptSubStatement
+hi def link framescriptClearSubStatement    framescriptSubStatement
+hi def link framescriptCloseSubStatement    framescriptSubStatement
+hi def link framescriptExecSubStatement     framescriptSubStatement
+hi def link framescriptExecuteSubStatement  framescriptSubStatement
+hi def link framescriptGenerateSubStatement framescriptSubStatement
+hi def link framescriptGetSubStatement      framescriptSubStatement
+hi def link framescriptImportSubStatement   framescriptSubStatement
+hi def link framescriptInstallSubStatement  framescriptSubStatement
+hi def link framescriptNewSubStatement      framescriptSubStatement
+hi def link framescriptOpenSubStatement     framescriptSubStatement
+hi def link framescriptPrintSubStatement    framescriptSubStatement
+hi def link framescriptQuitSubStatement     framescriptSubStatement
+hi def link framescriptRemoveSubStatement   framescriptSubStatement
+hi def link framescriptSaveSubStatement     framescriptSubStatement
+hi def link framescriptSelectSubStatement   framescriptSubStatement
+hi def link framescriptStraddleSubStatement framescriptSubStatement
+hi def link framescriptUpdateSubStatement   framescriptSubStatement
+hi def link framescriptRepeat               Repeat
+hi def link framescriptConditional          Conditional
+hi def link framescriptType                 Type
+
+let b:current_syntax = "framescript"
+
+let &cpo = s:cpo_save
+unlet s:cpo_save
--- /dev/null
+++ b/lib/vimfiles/syntax/freebasic.vim
@@ -1,0 +1,252 @@
+" Vim syntax file
+" Language:    FreeBasic
+" Maintainer:  Mark Manning <markem@airmail.net>
+" Updated:     10/22/2006
+"
+" Description:
+"
+"	Based originally on the work done by Allan Kelly <Allan.Kelly@ed.ac.uk>
+"	Updated by Mark Manning <markem@airmail.net>
+"	Applied FreeBasic support to the already excellent support
+"	for standard basic syntax (like QB).
+"
+"	First version based on Micro$soft QBASIC circa
+"	1989, as documented in 'Learn BASIC Now' by
+"	Halvorson&Rygmyr. Microsoft Press 1989.  This syntax file
+"	not a complete implementation yet.  Send suggestions to
+"	the maintainer.
+"
+"	Quit when a (custom) syntax file was already loaded (Taken from c.vim)
+"
+if exists("b:current_syntax")
+  finish
+endif
+"
+"	Be sure to turn on the "case ignore" since current versions
+"	of freebasic support both upper as well as lowercase
+"	letters. - MEM 10/1/2006
+"
+syn case ignore
+"
+"	This list of keywords is taken directly from the FreeBasic
+"	user's guide as presented by the FreeBasic online site.
+"
+syn keyword	freebasicArrays			ERASE LBOUND REDIM PRESERVE UBOUND
+
+syn keyword	freebasicBitManipulation	BIT BITRESET BITSET HIBYTE HIWORD LOBYTE LOWORD SHL SHR
+
+syn keyword	freebasicCompilerSwitches	DEFBYTE DEFDBL DEFINT DEFLNG DEFLNGINT DEFSHORT DEFSNG DEFSTR
+syn keyword	freebasicCompilerSwitches	DEFUBYTE DEFUINT DEFULNGINT DEFUSHORT
+syn match	freebasicCompilerSwitches	"\<option\s+\(BASE\|BYVAL\|DYNAMIC\|ESCAPE\|EXPLICIT\|NOKEYWORD\)\>"
+syn match	freebasicCompilerSwitches	"\<option\s+\(PRIVATE\|STATIC\)\>"
+
+syn region	freebasicConditional		start="\son\s+" skip=".*" end="gosub"
+syn region	freebasicConditional		start="\son\s+" skip=".*" end="goto"
+syn match	freebasicConditional		"\<select\s+case\>"
+syn keyword	freebasicConditional		if iif then case else elseif with
+
+syn match	freebasicConsole		"\<open\s+\(CONS\|ERR\|PIPE\|SCRN\)\>"
+syn keyword	freebasicConsole		BEEP CLS CSRLIN LOCATE PRINT POS SPC TAB VIEW WIDTH
+
+syn keyword	freebasicDataTypes		BYTE AS DIM CONST DOUBLE ENUM INTEGER LONG LONGINT SHARED SHORT STRING
+syn keyword	freebasicDataTypes		SINGLE TYPE UBYTE UINTEGER ULONGINT UNION UNSIGNED USHORT WSTRING ZSTRING
+
+syn keyword	freebasicDateTime		DATE DATEADD DATEDIFF DATEPART DATESERIAL DATEVALUE DAY HOUR MINUTE
+syn keyword	freebasicDateTime		MONTH MONTHNAME NOW SECOND SETDATE SETTIME TIME TIMESERIAL TIMEVALUE
+syn keyword	freebasicDateTime		TIMER YEAR WEEKDAY WEEKDAYNAME
+
+syn keyword	freebasicDebug			ASSERT STOP
+
+syn keyword	freebasicErrorHandling		ERR ERL ERROR LOCAL RESUME
+syn match	freebasicErrorHandling		"\<resume\s+next\>"
+syn match	freebasicErrorHandling		"\<on\s+error\>"
+
+syn match	freebasicFiles			"\<get\s+#\>"
+syn match	freebasicFiles			"\<input\s+#\>"
+syn match	freebasicFiles			"\<line\s+input\s+#\>"
+syn match	freebasicFiles			"\<put\s+#\>"
+syn keyword	freebasicFiles			ACCESS APPEND BINARY BLOAD BSAVE CLOSE EOF FREEFILE INPUT LOC
+syn keyword	freebasicFiles			LOCK LOF OPEN OUTPUT RANDOM RESET SEEK UNLOCK WRITE
+
+syn keyword	freebasicFunctions		ALIAS ANY BYREF BYVAL CALL CDECL CONSTRUCTOR DESTRUCTOR
+syn keyword	freebasicFunctions		DECLARE FUNCTION LIB OVERLOAD PASCAL STATIC SUB STDCALL
+syn keyword	freebasicFunctions		VA_ARG VA_FIRST VA_NEXT
+
+syn match	freebasicGraphics		"\<palette\s+get\>"
+syn keyword	freebasicGraphics		ALPHA CIRCLE CLS COLOR CUSTOM DRAW FLIP GET
+syn keyword	freebasicGraphics		IMAGECREATE IMAGEDESTROY LINE PAINT PALETTE PCOPY PMAP POINT
+syn keyword	freebasicGraphics		PRESET PSET PUT RGB RGBA SCREEN SCREENCOPY SCREENINFO SCREENLIST
+syn keyword	freebasicGraphics		SCREENLOCK SCREENPTR SCREENRES SCREENSET SCREENSYNC SCREENUNLOCK
+syn keyword	freebasicGraphics		TRANS USING VIEW WINDOW
+
+syn match	freebasicHardware		"\<open\s+com\>"
+syn keyword	freebasicHardware		INP OUT WAIT LPT LPOS LPRINT
+
+syn keyword	freebasicLogical		AND EQV IMP OR NOT XOR
+
+syn keyword	freebasicMath			ABS ACOS ASIN ATAN2 ATN COS EXP FIX INT LOG MOD RANDOMIZE
+syn keyword	freebasicMath			RND SGN SIN SQR TAN
+
+syn keyword	freebasicMemory			ALLOCATE CALLOCATE CLEAR DEALLOCATE FIELD FRE PEEK POKE REALLOCATE
+
+syn keyword	freebasicMisc			ASM DATA LET TO READ RESTORE SIZEOF SWAP OFFSETOF
+
+syn keyword	freebasicModularizing		CHAIN COMMON EXPORT EXTERN DYLIBFREE DYLIBLOAD DYLIBSYMBOL
+syn keyword	freebasicModularizing		PRIVATE PUBLIC
+
+syn keyword	freebasicMultithreading		MUTEXCREATE MUTEXDESTROY MUTEXLOCK MUTEXUNLOCK THREADCREATE THREADWAIT
+
+syn keyword	freebasicShell			CHDIR DIR COMMAND ENVIRON EXEC EXEPATH KILL NAME MKDIR RMDIR RUN
+
+syn keyword	freebasicEnviron		SHELL SYSTEM WINDOWTITLE POINTERS
+
+syn keyword	freebasicLoops			FOR LOOP WHILE WEND DO CONTINUE STEP UNTIL next
+
+syn match	freebasicInclude		"\<#\s*\(inclib\|include\)\>"
+syn match	freebasicInclude		"\<\$\s*include\>"
+
+syn keyword	freebasicPointer		PROCPTR PTR SADD STRPTR VARPTR
+
+syn keyword	freebasicPredefined		__DATE__ __FB_DOS__ __FB_LINUX__ __FB_MAIN__ __FB_MIN_VERSION__
+syn keyword	freebasicPredefined		__FB_SIGNATURE__ __FB_VERSION__ __FB_WIN32__ __FB_VER_MAJOR__
+syn keyword	freebasicPredefined		__FB_VER_MINOR__ __FB_VER_PATCH__ __FILE__ __FUNCTION__
+syn keyword	freebasicPredefined		__LINE__ __TIME__
+
+syn match	freebasicPreProcessor		"\<^#\s*\(define\|undef\)\>"
+syn match	freebasicPreProcessor		"\<^#\s*\(ifdef\|ifndef\|else\|elseif\|endif\|if\)\>"
+syn match	freebasicPreProcessor		"\<#\s*error\>"
+syn match	freebasicPreProcessor		"\<#\s*\(print\|dynamic\|static\)\>"
+syn keyword	freebasicPreProcessor		DEFINED ONCE
+
+syn keyword	freebasicProgramFlow		END EXIT GOSUB GOTO
+syn keyword	freebasicProgramFlow		IS RETURN SCOPE SLEEP
+
+syn keyword	freebasicString			INSTR LCASE LEFT LEN LSET LTRIM MID RIGHT RSET RTRIM
+syn keyword	freebasicString			SPACE STRING TRIM UCASE ASC BIN CHR CVD CVI CVL CVLONGINT
+syn keyword	freebasicString			CVS CVSHORT FORMAT HEX MKD MKI MKL MKLONGINT MKS MKSHORT
+syn keyword	freebasicString			OCT STR VAL VALLNG VALINT VALUINT VALULNG
+
+syn keyword	freebasicTypeCasting		CAST CBYTE CDBL CINT CLNG CLNGINT CPTR CSHORT CSIGN CSNG
+syn keyword	freebasicTypeCasting		CUBYTE CUINT CULNGINT CUNSG CURDIR CUSHORT
+
+syn match	freebasicUserInput		"\<line\s+input\>"
+syn keyword	freebasicUserInput		GETJOYSTICK GETKEY GETMOUSE INKEY INPUT MULTIKEY SETMOUSE
+"
+"	Do the Basic variables names first.  This is because it
+"	is the most inclusive of the tests.  Later on we change
+"	this so the identifiers are split up into the various
+"	types of identifiers like functions, basic commands and
+"	such. MEM 9/9/2006
+"
+syn match	freebasicIdentifier		"\<[a-zA-Z_][a-zA-Z0-9_]*\>"
+syn match	freebasicGenericFunction	"\<[a-zA-Z_][a-zA-Z0-9_]*\>\s*("me=e-1,he=e-1
+"
+"	Function list
+"
+syn keyword	freebasicTodo		contained TODO
+"
+"	Catch errors caused by wrong parenthesis
+"
+syn region	freebasicParen		transparent start='(' end=')' contains=ALLBUT,@freebasicParenGroup
+syn match	freebasicParenError	")"
+syn match	freebasicInParen	contained "[{}]"
+syn cluster	freebasicParenGroup	contains=freebasicParenError,freebasicSpecial,freebasicTodo,freebasicUserCont,freebasicUserLabel,freebasicBitField
+"
+"	Integer number, or floating point number without a dot and with "f".
+"
+syn region	freebasicHex		start="&h" end="\W"
+syn region	freebasicHexError	start="&h\x*[g-zG-Z]" end="\W"
+syn match	freebasicInteger	"\<\d\+\(u\=l\=\|lu\|f\)\>"
+"
+"	Floating point number, with dot, optional exponent
+"
+syn match	freebasicFloat		"\<\d\+\.\d*\(e[-+]\=\d\+\)\=[fl]\=\>"
+"
+"	Floating point number, starting with a dot, optional exponent
+"
+syn match	freebasicFloat		"\.\d\+\(e[-+]\=\d\+\)\=[fl]\=\>"
+"
+"	Floating point number, without dot, with exponent
+"
+syn match	freebasicFloat		"\<\d\+e[-+]\=\d\+[fl]\=\>"
+"
+"	Hex number
+"
+syn case match
+syn match	freebasicOctal		"\<0\o*\>"
+syn match	freebasicOctalError	"\<0\o*[89]"
+"
+"	String and Character contstants
+"
+syn region	freebasicString		start='"' end='"' contains=freebasicSpecial,freebasicTodo
+syn region	freebasicString		start="'" end="'" contains=freebasicSpecial,freebasicTodo
+"
+"	Comments
+"
+syn match	freebasicSpecial	contained "\\."
+syn region	freebasicComment	start="^rem" end="$" contains=freebasicSpecial,freebasicTodo
+syn region	freebasicComment	start=":\s*rem" end="$" contains=freebasicSpecial,freebasicTodo
+syn region	freebasicComment	start="\s*'" end="$" contains=freebasicSpecial,freebasicTodo
+syn region	freebasicComment	start="^'" end="$" contains=freebasicSpecial,freebasicTodo
+"
+"	Now do the comments and labels
+"
+syn match	freebasicLabel		"^\d"
+syn match	freebasicLabel		"\<^\w+:\>"
+syn region	freebasicLineNumber	start="^\d" end="\s"
+"
+"	Create the clusters
+"
+syn cluster	freebasicNumber		contains=freebasicHex,freebasicOctal,freebasicInteger,freebasicFloat
+syn cluster	freebasicError		contains=freebasicHexError,freebasicOctalError
+"
+"	Used with OPEN statement
+"
+syn match	freebasicFilenumber	"#\d\+"
+syn match	freebasicMathOperator	"[\+\-\=\|\*\/\>\<\%\()[\]]" contains=freebasicParen
+"
+"	The default methods for highlighting.  Can be overridden later
+"
+hi def link freebasicArrays		StorageClass
+hi def link freebasicBitManipulation	Operator
+hi def link freebasicCompilerSwitches	PreCondit
+hi def link freebasicConsole		Special
+hi def link freebasicDataTypes		Type
+hi def link freebasicDateTime		Type
+hi def link freebasicDebug		Special
+hi def link freebasicErrorHandling	Special
+hi def link freebasicFiles		Special
+hi def link freebasicFunctions		Function
+hi def link freebasicGraphics		Function
+hi def link freebasicHardware		Special
+hi def link freebasicLogical		Conditional
+hi def link freebasicMath		Function
+hi def link freebasicMemory		Function
+hi def link freebasicMisc		Special
+hi def link freebasicModularizing	Special
+hi def link freebasicMultithreading	Special
+hi def link freebasicShell		Special
+hi def link freebasicEnviron		Special
+hi def link freebasicPointer		Special
+hi def link freebasicPredefined		PreProc
+hi def link freebasicPreProcessor	PreProc
+hi def link freebasicProgramFlow	Statement
+hi def link freebasicString		String
+hi def link freebasicTypeCasting	Type
+hi def link freebasicUserInput		Statement
+hi def link freebasicComment		Comment
+hi def link freebasicConditional	Conditional
+hi def link freebasicError		Error
+hi def link freebasicIdentifier		Identifier
+hi def link freebasicInclude		Include
+hi def link freebasicGenericFunction	Function
+hi def link freebasicLabel		Label
+hi def link freebasicLineNumber		Label
+hi def link freebasicMathOperator	Operator
+hi def link freebasicNumber		Number
+hi def link freebasicSpecial		Special
+hi def link freebasicTodo		Todo
+
+let b:current_syntax = "freebasic"
+
+" vim: ts=8
--- /dev/null
+++ b/lib/vimfiles/syntax/fstab.vim
@@ -1,0 +1,248 @@
+" Vim syntax file
+" Language: fstab file
+" Maintaner: Radu Dineiu <radu.dineiu@gmail.com>
+" URL: http://ld.yi.org/vim/fstab.vim
+" Last Change: 2007 Apr 24
+" Version: 0.91
+"
+" Credits:
+"   David Necas (Yeti) <yeti@physics.muni.cz>
+"   Stefano Zacchiroli <zack@debian.org>
+"   Georgi Georgiev <chutz@gg3.net>
+"
+" Options:
+"   let fstab_unknown_fs_errors = 1
+"     highlight unknown filesystems as errors
+
+if version < 600
+	syntax clear
+elseif exists("b:current_syntax")
+	finish
+endif
+
+" General
+syn cluster fsGeneralCluster contains=fsComment
+syn match fsComment /\s*#.*/
+syn match fsOperator /[,=:]/
+
+" Device
+syn cluster fsDeviceCluster contains=fsOperator,fsDeviceKeyword,fsDeviceError
+syn match fsDeviceError /\%([^a-zA-Z0-9_\/#@:\.-]\|^\w\{-}\ze\W\)/ contained
+syn keyword fsDeviceKeyword contained none proc linproc tmpfs devpts sysfs usbfs
+syn keyword fsDeviceKeyword contained LABEL nextgroup=fsDeviceLabel
+syn keyword fsDeviceKeyword contained UUID nextgroup=fsDeviceUUID
+syn match fsDeviceKeyword contained /^[a-zA-Z0-9.\-]\+\ze:/
+syn match fsDeviceLabel contained /=[^ \t]\+/hs=s+1 contains=fsOperator
+syn match fsDeviceUUID contained /=[^ \t]\+/hs=s+1 contains=fsOperator
+
+" Mount Point
+syn cluster fsMountPointCluster contains=fsMountPointKeyword,fsMountPointError
+syn match fsMountPointError /\%([^ \ta-zA-Z0-9_\/#@\.-]\|\s\+\zs\w\{-}\ze\s\)/ contained
+syn keyword fsMountPointKeyword contained none swap
+
+" Type
+syn cluster fsTypeCluster contains=fsTypeKeyword,fsTypeUnknown
+syn match fsTypeUnknown /\s\+\zs\w\+/ contained
+syn keyword fsTypeKeyword contained adfs ados affs atfs audiofs auto autofs befs bfs cd9660 cfs cifs coda cramfs devfs devpts e2compr efs ext2 ext2fs ext3 fdesc ffs filecore hfs hpfs iso9660 jffs jffs2 jfs kernfs lfs linprocfs mfs minix msdos ncpfs nfs none ntfs null nwfs overlay ovlfs portal proc procfs ptyfs qnx4 reiserfs romfs shm smbfs std subfs swap sysfs sysv tcfs tmpfs udf ufs umap umsdos union usbfs userfs vfat vs3fs vxfs wrapfs wvfs xfs zisofs
+
+" Options
+" -------
+" Options: General
+syn cluster fsOptionsCluster contains=fsOperator,fsOptionsGeneral,fsOptionsKeywords,fsTypeUnknown
+syn match fsOptionsNumber /\d\+/
+syn match fsOptionsNumberOctal /[0-8]\+/
+syn match fsOptionsString /[a-zA-Z0-9_-]\+/
+syn keyword fsOptionsYesNo yes no
+syn cluster fsOptionsCheckCluster contains=fsOptionsExt2Check,fsOptionsFatCheck
+syn keyword fsOptionsSize 512 1024 2048
+syn keyword fsOptionsGeneral async atime auto bind current defaults dev devgid devmode devmtime devuid dirsync exec force fstab kudzu loop mand move noatime noauto noclusterr noclusterw nodev nodevmtime nodiratime noexec nomand nosuid nosymfollow nouser owner rbind rdonly remount ro rq rw suid suiddir supermount sw sync union update user users xx
+syn match fsOptionsGeneral /_netdev/
+
+" Options: adfs
+syn match fsOptionsKeywords contained /\<\%([ug]id\|o\%(wn\|th\)mask\)=/ nextgroup=fsOptionsNumber
+
+" Options: affs
+syn match fsOptionsKeywords contained /\<\%(set[ug]id\|mode\|reserved\)=/ nextgroup=fsOptionsNumber
+syn match fsOptionsKeywords contained /\<\%(prefix\|volume\|root\)=/ nextgroup=fsOptionsString
+syn match fsOptionsKeywords contained /\<bs=/ nextgroup=fsOptionsSize
+syn keyword fsOptionsKeywords contained protect usemp verbose
+
+" Options: cd9660
+syn keyword fsOptionsKeywords contained extatt gens norrip nostrictjoilet
+
+" Options: devpts
+" -- everything already defined
+
+" Options: ext2
+syn match fsOptionsKeywords contained /\<check=*/ nextgroup=@fsOptionsCheckCluster
+syn match fsOptionsKeywords contained /\<errors=/ nextgroup=fsOptionsExt2Errors
+syn match fsOptionsKeywords contained /\<\%(res[gu]id\|sb\)=/ nextgroup=fsOptionsNumber
+syn keyword fsOptionsExt2Check contained none normal strict
+syn keyword fsOptionsExt2Errors contained continue panic
+syn match fsOptionsExt2Errors contained /\<remount-ro\>/
+syn keyword fsOptionsKeywords contained acl bsddf minixdf debug grpid bsdgroups minixdf noacl nocheck nogrpid oldalloc orlov sysvgroups nouid32 nobh user_xattr nouser_xattr
+
+" Options: ext3
+syn match fsOptionsKeywords contained /\<journal=/ nextgroup=fsOptionsExt3Journal
+syn match fsOptionsKeywords contained /\<data=/ nextgroup=fsOptionsExt3Data
+syn match fsOptionsKeywords contained /\<commit=/ nextgroup=fsOptionsNumber
+syn keyword fsOptionsExt3Journal contained update inum
+syn keyword fsOptionsExt3Data contained journal ordered writeback
+syn keyword fsOptionsKeywords contained noload
+
+" Options: fat
+syn match fsOptionsKeywords contained /\<blocksize=/ nextgroup=fsOptionsSize
+syn match fsOptionsKeywords contained /\<\%([dfu]mask\|codepage\)=/ nextgroup=fsOptionsNumberOctal
+syn match fsOptionsKeywords contained /\%(cvf_\%(format\|option\)\|iocharset\)=/ nextgroup=fsOptionsString
+syn match fsOptionsKeywords contained /\<check=/ nextgroup=@fsOptionsCheckCluster
+syn match fsOptionsKeywords contained /\<conv=*/ nextgroup=fsOptionsConv
+syn match fsOptionsKeywords contained /\<fat=/ nextgroup=fsOptionsFatType
+syn match fsOptionsKeywords contained /\<dotsOK=/ nextgroup=fsOptionsYesNo
+syn keyword fsOptionsFatCheck contained r n s relaxed normal strict
+syn keyword fsOptionsConv contained b t a binary text auto
+syn keyword fsOptionsFatType contained 12 16 32
+syn keyword fsOptionsKeywords contained quiet sys_immutable showexec dots nodots
+
+" Options: hfs
+syn match fsOptionsKeywords contained /\<\%(creator|type\)=/ nextgroup=fsOptionsString
+syn match fsOptionsKeywords contained /\<\%(dir\|file\|\)_umask=/ nextgroup=fsOptionsNumberOctal
+syn match fsOptionsKeywords contained /\<\%(session\|part\)=/ nextgroup=fsOptionsNumber
+
+" Options: ffs
+syn keyword fsOptionsKeyWords contained softdep
+
+" Options: hpfs
+syn match fsOptionsKeywords contained /\<case=/ nextgroup=fsOptionsHpfsCase
+syn keyword fsOptionsHpfsCase contained lower asis
+
+" Options: iso9660
+syn match fsOptionsKeywords contained /\<map=/ nextgroup=fsOptionsIsoMap
+syn match fsOptionsKeywords contained /\<block=/ nextgroup=fsOptionsSize
+syn match fsOptionsKeywords contained /\<\%(session\|sbsector\)=/ nextgroup=fsOptionsNumber
+syn keyword fsOptionsIsoMap contained n o a normal off acorn
+syn keyword fsOptionsKeywords contained norock nojoilet unhide cruft
+syn keyword fsOptionsConv contained m mtext
+
+" Options: jfs
+syn keyword fsOptionsKeywords nointegrity integrity
+
+" Options: nfs
+syn match fsOptionsKeywords contained /\<\%(rsize\|wsize\|timeo\|retrans\|acregmin\|acregmax\|acdirmin\|acdirmax\|actimeo\|retry\|port\|mountport\|mounthost\|mountprog\|mountvers\|nfsprog\|nfsvers\|namelen\)=/ nextgroup=fsOptionsString
+syn keyword fsOptionsKeywords contained bg fg soft hard intr cto ac tcp udp lock nobg nofg nosoft nohard nointr noposix nocto noac notcp noudp nolock
+
+" Options: ntfs
+syn match fsOptionsKeywords contained /\<\%(posix=*\|uni_xlate=\)/ nextgroup=fsOptionsNumber
+syn keyword fsOptionsKeywords contained utf8
+
+" Options: proc
+" -- everything already defined
+
+" Options: reiserfs
+syn match fsOptionsKeywords contained /\<hash=/ nextgroup=fsOptionsReiserHash
+syn match fsOptionsKeywords contained /\<resize=/ nextgroup=fsOptionsNumber
+syn keyword fsOptionsReiserHash contained rupasov tea r5 detect
+syn keyword fsOptionsKeywords contained hashed_relocation noborder nolog notail no_unhashed_relocation replayonly
+
+" Options: subfs
+syn match fsOptionsKeywords contained /\<fs=/ nextgroup=fsOptionsString
+syn keyword fsOptionsKeywords contained procuid
+
+" Options: swap
+syn match fsOptionsKeywords contained /\<pri=/ nextgroup=fsOptionsNumber
+
+" Options: tmpfs
+syn match fsOptionsKeywords contained /\<nr_\%(blocks\|inodes\)=/ nextgroup=fsOptionsNumber
+
+" Options: udf
+syn match fsOptionsKeywords contained /\<\%(anchor\|partition\|lastblock\|fileset\|rootdir\)=/ nextgroup=fsOptionsString
+syn keyword fsOptionsKeywords contained unhide undelete strict novrs
+
+" Options: ufs
+syn match fsOptionsKeywords contained /\<ufstype=/ nextgroup=fsOptionsUfsType
+syn match fsOptionsKeywords contained /\<onerror=/ nextgroup=fsOptionsUfsError
+syn keyword fsOptionsUfsType contained old hp 44bsd sun sunx86 nextstep openstep
+syn match fsOptionsUfsType contained /\<nextstep-cd\>/
+syn keyword fsOptionsUfsError contained panic lock umount repair
+
+" Options: usbfs
+syn match fsOptionsKeywords contained /\<\%(dev\|bus\|list\)\%(id\|gid\)=/ nextgroup=fsOptionsNumber
+syn match fsOptionsKeywords contained /\<\%(dev\|bus\|list\)mode=/ nextgroup=fsOptionsNumberOctal
+
+" Options: vfat
+syn keyword fsOptionsKeywords contained nonumtail posix utf8
+syn match fsOptionsKeywords contained /shortname=/ nextgroup=fsOptionsVfatShortname
+syn keyword fsOptionsVfatShortname contained lower win95 winnt mixed
+
+" Options: xfs
+syn match fsOptionsKeywords contained /\%(biosize\|logbufs\|logbsize\|logdev\|rtdev\|sunit\|swidth\)=/ nextgroup=fsOptionsString
+syn keyword fsOptionsKeywords contained dmapi xdsm noalign noatime noquota norecovery osyncisdsync quota usrquota uqnoenforce grpquota gqnoenforce
+
+" Frequency / Pass No.
+syn cluster fsFreqPassCluster contains=fsFreqPassNumber,fsFreqPassError
+syn match fsFreqPassError /\s\+\zs\%(\D.*\|\S.*\|\d\+\s\+[^012]\)\ze/ contained
+syn match fsFreqPassNumber /\d\+\s\+[012]\s*/ contained
+
+" Groups
+syn match fsDevice /^\s*\zs.\{-1,}\s/me=e-1 nextgroup=fsMountPoint contains=@fsDeviceCluster,@fsGeneralCluster
+syn match fsMountPoint /\s\+.\{-}\s/me=e-1 nextgroup=fsType contains=@fsMountPointCluster,@fsGeneralCluster contained
+syn match fsType /\s\+.\{-}\s/me=e-1 nextgroup=fsOptions contains=@fsTypeCluster,@fsGeneralCluster contained
+syn match fsOptions /\s\+.\{-}\s/me=e-1 nextgroup=fsFreqPass contains=@fsOptionsCluster,@fsGeneralCluster contained
+syn match fsFreqPass /\s\+.\{-}$/ contains=@fsFreqPassCluster,@fsGeneralCluster contained
+
+" Whole line comments
+syn match fsCommentLine /^#.*$/
+
+if version >= 508 || !exists("did_config_syntax_inits")
+	if version < 508
+		let did_config_syntax_inits = 1
+		command! -nargs=+ HiLink hi link <args>
+	else
+		command! -nargs=+ HiLink hi def link <args>
+	endif
+
+	HiLink fsOperator Operator
+	HiLink fsComment Comment
+	HiLink fsCommentLine Comment
+
+	HiLink fsTypeKeyword Type
+	HiLink fsDeviceKeyword Identifier
+	HiLink fsDeviceLabel String
+	HiLink fsDeviceUUID String
+	HiLink fsFreqPassNumber Number
+
+	if exists('fstab_unknown_fs_errors') && fstab_unknown_fs_errors == 1
+		HiLink fsTypeUnknown Error
+	endif
+	HiLink fsDeviceError Error
+	HiLink fsMountPointError Error
+	HiLink fsMountPointKeyword Keyword
+	HiLink fsFreqPassError Error
+
+	HiLink fsOptionsGeneral Type
+	HiLink fsOptionsKeywords Keyword
+	HiLink fsOptionsNumber Number
+	HiLink fsOptionsNumberOctal Number
+	HiLink fsOptionsString String
+	HiLink fsOptionsSize Number
+	HiLink fsOptionsExt2Check String
+	HiLink fsOptionsExt2Errors String
+	HiLink fsOptionsExt3Journal String
+	HiLink fsOptionsExt3Data String
+	HiLink fsOptionsFatCheck String
+	HiLink fsOptionsConv String
+	HiLink fsOptionsFatType Number
+	HiLink fsOptionsYesNo String
+	HiLink fsOptionsHpfsCase String
+	HiLink fsOptionsIsoMap String
+	HiLink fsOptionsReiserHash String
+	HiLink fsOptionsUfsType String
+	HiLink fsOptionsUfsError String
+
+	HiLink fsOptionsVfatShortname String
+
+	delcommand HiLink
+endif
+
+let b:current_syntax = "fstab"
+
+" vim: ts=8 ft=vim
--- /dev/null
+++ b/lib/vimfiles/syntax/fvwm.vim
@@ -1,0 +1,617 @@
+" Vim syntax file
+" Language:		Fvwm{1,2} configuration file
+" Maintainer:		Gautam Iyer <gi1242@users.sourceforge.net>
+" Previous Maintainer:	Haakon Riiser <hakonrk@fys.uio.no>
+" Last Change:		Sat 04 Nov 2006 11:28:37 PM PST
+"
+" Thanks to David Necas (Yeti) for adding Fvwm 2.4 support.
+"
+" 2006-05-09 gi1242: Rewrote fvwm2 syntax completely. Also since fvwm1 is now
+" mostly obsolete, made the syntax file pick fvwm2 syntax by default.
+
+if exists("b:current_syntax")
+    finish
+endif
+
+" Fvwm configuration files are case insensitive
+syn case ignore
+
+" Identifiers in Fvwm can contain most characters, so we only
+" include the most common ones here.
+setlocal iskeyword=_,-,+,.,a-z,A-Z,48-57
+
+" Syntax items common to fvwm1 and fvwm2 config files
+syn cluster fvwmConstants	contains=fvwmEnvVar,fvwmNumber
+syn match   fvwmEnvVar		"\$\w\+"
+syn match   fvwmNumber		'\v<(\d+|0x[0-9a-f]+)>' 
+
+syn match   fvwmModConf		nextgroup=fvwmModArg	"\v^\s*\*\a+"
+syn region  fvwmModArg		contained contains=fvwmString,fvwmRGBValue
+				\ start='.' skip='\\$' end='$'
+
+syn region  fvwmString		contains=fvwmBackslash start='"'
+				\ matchgroup=fvwmBackslash skip='\v\\"' end='"'
+syn region  fvwmString		contains=fvwmBackslash start='`'
+				\ matchgroup=fvwmBackslash skip='\v\\`' end='`'
+syn region  fvwmString		contains=fvwmBackslash start="'"
+				\ matchgroup=fvwmBackslash skip="\v\\'" end="'"
+syn match   fvwmBackslash	contained '\\[^"'`]'
+
+syn match   fvwmRGBValue	"#\x\{3}"
+syn match   fvwmRGBValue	"#\x\{6}"
+syn match   fvwmRGBValue	"#\x\{9}"
+syn match   fvwmRGBValue	"#\x\{12}"
+syn match   fvwmRGBValue	"rgb:\x\{1,4}/\x\{1,4}/\x\{1,4}"
+
+syn region  fvwmComment		contains=@Spell start="^\s*#" skip='\\$' end='$'
+
+if (exists("b:fvwm_version") && b:fvwm_version == 1)
+	    \ || (exists("use_fvwm_1") && use_fvwm_1)
+
+    "
+    " Syntax highlighting for Fvwm1 files.
+    "
+
+    " Moved from common syntax items
+    syn match   fvwmModule	"\<Module\s\+\w\+"he=s+6
+    syn keyword fvwmExec	Exec
+    syn match   fvwmPath	"\<IconPath\s.*$"lc=8 contains=fvwmEnvVar
+    syn match   fvwmPath	"\<ModulePath\s.*$"lc=10 contains=fvwmEnvVar
+    syn match   fvwmPath	"\<PixmapPath\s.*$"lc=10 contains=fvwmEnvVar
+    syn match   fvwmKey		"\<Key\s\+\w\+"he=s+3
+
+    " fvwm1 specific items
+    syn match  fvwmEnvVar	"\$(\w\+)"
+    syn match  fvwmWhitespace	contained "\s\+"
+    syn region fvwmStyle	oneline keepend
+				\ contains=fvwmString,fvwmKeyword,fvwmWhiteSpace
+				\ matchgroup=fvwmFunction
+				\ start="^\s*Style\>"hs=e-5 end="$"
+
+    syn keyword fvwmFunction	AppsBackingStore AutoRaise BackingStore Beep
+				\ BoundaryWidth ButtonStyle CenterOnCirculate
+				\ CirculateDown CirculateHit CirculateSkip
+				\ CirculateSkipIcons CirculateUp ClickTime
+				\ ClickToFocus Close Cursor CursorMove
+				\ DecorateTransients Delete Desk DeskTopScale
+				\ DeskTopSize Destroy DontMoveOff
+				\ EdgeResistance EdgeScroll EndFunction
+				\ EndMenu EndPopup Focus Font Function
+				\ GotoPage HiBackColor HiForeColor Icon
+				\ IconBox IconFont Iconify IconPath Key
+				\ Lenience Lower Maximize MenuBackColor
+				\ MenuForeColor MenuStippleColor Module
+				\ ModulePath Mouse Move MWMBorders MWMButtons
+				\ MWMDecorHints MWMFunctionHints
+				\ MWMHintOverride MWMMenus NoBorder
+				\ NoBoundaryWidth Nop NoPPosition NoTitle
+				\ OpaqueMove OpaqueResize Pager PagerBackColor
+				\ PagerFont PagerForeColor PagingDefault
+				\ PixmapPath Popup Quit Raise RaiseLower
+				\ RandomPlacement Refresh Resize Restart
+				\ SaveUnders Scroll SloppyFocus SmartPlacement
+				\ StartsOnDesk StaysOnTop StdBackColor
+				\ StdForeColor Stick Sticky StickyBackColor
+				\ StickyForeColor StickyIcons
+				\ StubbornIconPlacement StubbornIcons
+				\ StubbornPlacement SuppressIcons Title
+				\ TogglePage Wait Warp WindowFont WindowList
+				\ WindowListSkip WindowsDesk WindowShade
+				\ XORvalue
+
+    " These keywords are only used after the "Style" command.  To avoid
+    " name collision with several commands, they are contained.
+    syn keyword fvwmKeyword	contained
+				\ BackColor BorderWidth BoundaryWidth Button
+				\ CirculateHit CirculateSkip Color DoubleClick
+				\ ForeColor Handles HandleWidth Icon IconTitle
+				\ NoBorder NoBoundaryWidth NoButton NoHandles
+				\ NoIcon NoIconTitle NoTitle Slippery
+				\ StartIconic StartNormal StartsAnyWhere
+				\ StartsOnDesk StaysOnTop StaysPut Sticky
+				\ Title WindowListHit WindowListSkip
+
+" elseif (exists("b:fvwm_version") && b:fvwm_version == 2)
+" 	    \ || (exists("use_fvwm_2") && use_fvwm_2)
+else
+
+    "
+    " Syntax highlighting for fvwm2 files.
+    "
+    syn match   fvwmEnvVar	"\${\w\+}"
+    syn match   fvwmEnvVar	"\$\[[^]]\+\]"
+    syn match   fvwmEnvVar	"\$[$0-9*]"
+
+    syn match   fvwmDef		contains=fvwmMenuString,fvwmWhitespace
+				\ '^\s*+\s*".\{-}"'
+    syn region  fvwmMenuString	contains=fvwmIcon,fvwmShortcutKey
+				\ start='^\s*+\s*\zs"' skip='\v\\\\|\\\"' end='"'
+    syn region	fvwmIcon	contained start='\v\%\%@!' end='%'
+    syn match   fvwmShortcutKey	contained "&."
+
+    syn keyword fvwmModuleName	FvwmAnimate FvwmAudio FvwmAuto FvwmBacker
+				\ FvwmBanner FvwmButtons FvwmCommandS
+				\ FvwmConsole FvwmCpp FvwmDebug FvwmDragWell
+				\ FvwmEvent FvwmForm FvwmGtk FvwmIconBox
+				\ FvwmIconMan FvwmIdent FvwmM4 FvwmPager
+				\ FvwmSave FvwmSaveDesk FvwmScript FvwmScroll
+				\ FvwmTaskBar FvwmWinList FvwmWharf
+    " Obsolete fvwmModuleName: FvwmTheme
+
+    syn keyword fvwmKeyword	AddToMenu ChangeMenuStyle CopyMenuStyle
+				\ DestroyMenu DestroyMenuStyle Menu
+				\ Popup TearMenuOff Title BugOpts BusyCursor
+				\ ClickTime ColorLimit ColormapFocus
+				\ DefaultColors DefaultColorset DefaultFont
+				\ DefaultIcon DefaultLayers Deschedule Emulate
+				\ EscapeFunc FakeClick FakeKeypress GlobalOpts
+				\ HilightColor HilightColorset IconFont
+				\ PrintInfo Repeat Schedule State WindowFont
+				\ XSync XSynchronize AnimatedMove
+				\ HideGeometryWindow Layer Lower Move
+				\ MoveToDesk MoveThreshold MoveToPage
+				\ MoveToScreen OpaqueMoveSize PlaceAgain Raise
+				\ RaiseLower ResizeMaximize ResizeMove
+				\ ResizeMoveMaximize RestackTransients
+				\ SetAnimation SnapAttraction SnapGrid
+				\ WindowsDesk XorPixmap XorValue CursorMove
+				\ FlipFocus Focus WarpToWindow Close Delete
+				\ Destroy Iconify Recapture RecaptureWindow
+				\ Refresh RefreshWindow Stick StickAcrossPages
+				\ StickAcrossDesks WindowShade
+				\ WindowShadeAnimate IgnoreModifiers
+				\ EdgeCommand EdgeLeaveCommand GnomeButton
+				\ Stroke StrokeFunc FocusStyle DestroyStyle
+				\ UpdateStyles AddToDecor BorderStyle
+				\ ChangeDecor DestroyDecor UpdateDecor
+				\ DesktopName DeskTopSize EdgeResistance
+				\ EdgeScroll EdgeThickness EwmhBaseStruts
+				\ EWMHNumberOfDesktops GotoDeskAndPage
+				\ GotoPage Scroll Xinerama
+				\ XineramaPrimaryScreen XineramaSls
+				\ XineramaSlsSize XineramaSlsScreens AddToFunc
+				\ Beep DestroyFunc Echo Exec ExecUseShell
+				\ Function Nop PipeRead Read SetEnv Silent
+				\ UnsetEnv Wait DestroyModuleConfig KillModule
+				\ Module ModuleSynchronous ModuleTimeout
+				\ SendToModule Quit QuitScreen QuitSession
+				\ Restart SaveSession SaveQuitSession KeepRc
+				\ NoWindow Break CleanupColorsets
+
+    " Conditional commands
+    syn keyword fvwmKeyword	nextgroup=fvwmCondition skipwhite
+				\ All Any Current Next None Pick PointerWindow
+				\ Prev ThisWindow
+    syn keyword fvwmKeyword	nextgroup=fvwmDirection skipwhite
+				\ Direction
+    syn keyword fvwmDirection	contained nextgroup=fvwmDirection skipwhite
+				\ FromPointer
+    syn keyword fvwmDirection	contained nextgroup=fvwmCondition skipwhite
+				\ North Northeast East Southeast South
+				\ Southwest West Northwest Center
+    syn region	fvwmCondition	contained contains=fvwmCondNames,fvwmString
+				\ matchgroup=fvwmKeyword start='(' skip=','
+				\ end=')'
+    syn keyword fvwmCondNames	contained
+				\ AcceptsFocus AnyScreen CirculateHit
+				\ CirculateHitIcon CirculateHitShaded Closable
+				\ CurrentDesk CurrentGlobalPage
+				\ CurrentGlobalPageAnyDesk CurrentPage
+				\ CurrentPageAnyDesk CurrentScreen FixedSize
+				\ Focused HasHandles HasPointer Iconic
+				\ Iconifiable Maximizable Maximized
+				\ Overlapped PlacedByButton3 PlacedByFvwm Raised
+				\ Shaded Sticky StickyAcrossDesks
+				\ StickyAcrossPages Transient Visible
+    syn keyword fvwmCondNames	contained skipwhite nextgroup=@fvwmConstants
+				\ State Layer
+
+    " Test
+    syn keyword fvwmKeyword	nextgroup=fvwmTCond skipwhite
+				\ Test
+    syn region	fvwmTCond	contained contains=fvwmTCNames,fvwmString
+				\ matchgroup=fvwmKeyword start='(' end=')'
+    syn keyword	fvwmTCNames	contained
+				\ Version EnvIsSet EnvMatch EdgeHasPointer
+				\ EdgeIsActive Start Init Restart Exit Quit
+				\ ToRestart True False F R W X I
+    
+    " TestRc
+    syn keyword fvwmKeyword	nextgroup=fvwmTRCond skipwhite
+				\ TestRc
+    syn region	fvwmTRCond	contained contains=fvwmTRNames,fvwmNumber
+				\ matchgroup=fvwmKeyword start='(' end=')'
+    syn keyword	fvwmTRNames	contained NoMatch Match Error Break
+
+    " Colorsets
+    syn keyword fvwmKeyword	nextgroup=fvwmCSArgs	skipwhite
+				\ ColorSet
+    syn region	fvwmCSArgs	contained transparent contains=fvwmCSNames,@fvwmConstants,fvwmString,fvwmRGBValue,fvwmGradient
+		\ start='.' skip='\\$' end='$'
+    syn keyword	fvwmCSNames	contained
+				\ fg Fore Foreground bg Back Background hi
+				\ Hilite Hilight sh Shade Shadow fgsh Pixmap
+				\ TiledPixmap AspectPixmap RootTransparent
+				\ Shape TiledShape AspectShape Tint fgTint
+				\ bgTint Alpha fgAlpha Dither IconTint
+				\ IconAlpha NoShape Plain Translucent
+    syn match	fvwmCSNames	contained	'\v<Transparent>'
+    syn match	fvwmGradient	contained	'\v<[HVDBSCRY]Gradient>'
+
+    " Styles
+    syn keyword fvwmKeyword	nextgroup=fvwmStyleArgs skipwhite
+				\ Style WindowStyle
+    syn region	fvwmStyleArgs	contained transparent contains=fvwmStyleNames,@fvwmConstants,fvwmString,fvwmRGBValue
+				\ start='.' skip='\\$' end='$'
+    syn keyword	fvwmStyleNames	contained
+				\ BorderWidth HandleWidth NoIcon Icon MiniIcon
+				\ IconBox IconGrid IconFill IconSize NoTitle
+				\ Title TitleAtBottom TitleAtLeft TitleAtRight
+				\ TitleAtTop LeftTitleRotatedCW
+				\ LeftTitleRotatedCCW RightTitleRotatedCCW
+				\ RightTitleRotatedCW TopTitleRotated
+				\ TopTitleNotRotated BottomTitleRotated
+				\ BottomTitleNotRotated UseTitleDecorRotation
+				\ StippledTitle StippledTitleOff
+				\ IndexedWindowName ExactWindowName
+				\ IndexedIconName ExactIconName Borders
+				\ NoHandles Handles WindowListSkip
+				\ WindowListHit CirculateSkip CirculateHit
+				\ CirculateSkipShaded CirculateHitShaded Layer
+				\ StaysOnTop StaysOnBottom StaysPut Sticky
+				\ Slippery StickyAcrossPages StickyAcrossDesks
+				\ StartIconic StartNormal Color ForeColor
+				\ BackColor Colorset HilightFore HilightBack
+				\ HilightColorset BorderColorset
+				\ HilightBorderColorset IconTitleColorset
+				\ HilightIconTitleColorset
+				\ IconBackgroundColorset IconTitleRelief
+				\ IconBackgroundRelief IconBackgroundPadding
+				\ Font IconFont StartsOnDesk StartsOnPage
+				\ StartsAnyWhere StartsOnScreen
+				\ ManualPlacementHonorsStartsOnPage
+				\ ManualPlacementIgnoresStartsOnPage
+				\ CaptureHonorsStartsOnPage
+				\ CaptureIgnoresStartsOnPage
+				\ RecaptureHonorsStartsOnPage
+				\ RecaptureIgnoresStartsOnPage
+				\ StartsOnPageIncludesTransients
+				\ StartsOnPageIgnoresTransients IconTitle
+				\ NoIconTitle MwmButtons FvwmButtons MwmBorder
+				\ FvwmBorder MwmDecor NoDecorHint MwmFunctions
+				\ NoFuncHint HintOverride NoOverride NoButton
+				\ Button ResizeHintOverride NoResizeOverride
+				\ OLDecor NoOLDecor GNOMEUseHints
+				\ GNOMEIgnoreHints StickyIcon SlipperyIcon
+				\ StickyAcrossPagesIcon StickyAcrossDesksIcon
+				\ ManualPlacement CascadePlacement
+				\ MinOverlapPlacement
+				\ MinOverlapPercentPlacement
+				\ TileManualPlacement TileCascadePlacement
+				\ CenterPlacement MinOverlapPlacementPenalties
+				\ MinOverlapPercentPlacementPenalties
+				\ DecorateTransient NakedTransient
+				\ DontRaiseTransient RaiseTransient
+				\ DontLowerTransient LowerTransient
+				\ DontStackTransientParent
+				\ StackTransientParent SkipMapping ShowMapping
+				\ ScatterWindowGroups KeepWindowGroupsOnDesk
+				\ UseDecor UseStyle NoPPosition UsePPosition
+				\ NoUSPosition UseUSPosition
+				\ NoTransientPPosition UseTransientPPosition
+				\ NoTransientUSPosition UseTransientUSPosition
+				\ NoIconPosition UseIconPosition Lenience
+				\ NoLenience ClickToFocus SloppyFocus
+				\ MouseFocus FocusFollowsMouse NeverFocus
+				\ ClickToFocusPassesClickOff
+				\ ClickToFocusPassesClick
+				\ ClickToFocusRaisesOff ClickToFocusRaises
+				\ MouseFocusClickRaises
+				\ MouseFocusClickRaisesOff GrabFocus
+				\ GrabFocusOff GrabFocusTransientOff
+				\ GrabFocusTransient FPFocusClickButtons
+				\ FPFocusClickModifiers
+				\ FPSortWindowlistByFocus FPClickRaisesFocused
+				\ FPClickDecorRaisesFocused
+				\ FPClickIconRaisesFocused
+				\ FPClickRaisesUnfocused
+				\ FPClickDecorRaisesUnfocused
+				\ FPClickIconRaisesUnfocused FPClickToFocus
+				\ FPClickDecorToFocus FPClickIconToFocus
+				\ FPEnterToFocus FPLeaveToUnfocus
+				\ FPFocusByProgram FPFocusByFunction
+				\ FPFocusByFunctionWarpPointer FPLenient
+				\ FPPassFocusClick FPPassRaiseClick
+				\ FPIgnoreFocusClickMotion
+				\ FPIgnoreRaiseClickMotion
+				\ FPAllowFocusClickFunction
+				\ FPAllowRaiseClickFunction FPGrabFocus
+				\ FPGrabFocusTransient FPOverrideGrabFocus
+				\ FPReleaseFocus FPReleaseFocusTransient
+				\ FPOverrideReleaseFocus StartsLowered
+				\ StartsRaised IgnoreRestack AllowRestack
+				\ FixedPosition VariablePosition
+				\ FixedUSPosition VariableUSPosition
+				\ FixedPPosition VariablePPosition FixedSize
+				\ VariableSize FixedUSSize VariableUSSize
+				\ FixedPSize VariablePSize Closable
+				\ Iconifiable Maximizable
+				\ AllowMaximizeFixedSize IconOverride
+				\ NoIconOverride NoActiveIconOverride
+				\ DepressableBorder FirmBorder MaxWindowSize
+				\ IconifyWindowGroups IconifyWindowGroupsOff
+				\ ResizeOpaque ResizeOutline BackingStore
+				\ BackingStoreOff BackingStoreWindowDefault
+				\ Opacity ParentalRelativity SaveUnder
+				\ SaveUnderOff WindowShadeShrinks
+				\ WindowShadeScrolls WindowShadeSteps
+				\ WindowShadeAlwaysLazy WindowShadeBusy
+				\ WindowShadeLazy EWMHDonateIcon
+				\ EWMHDontDonateIcon EWMHDonateMiniIcon
+				\ EWMHDontDonateMiniIcon EWMHMiniIconOverride
+				\ EWMHNoMiniIconOverride
+				\ EWMHUseStackingOrderHints
+				\ EWMHIgnoreStackingOrderHints
+				\ EWMHIgnoreStateHints EWMHUseStateHints
+				\ EWMHIgnoreStrutHints EWMHUseStrutHints
+				\ EWMHMaximizeIgnoreWorkingArea
+				\ EWMHMaximizeUseWorkingArea
+				\ EWMHMaximizeUseDynamicWorkingArea
+				\ EWMHPlacementIgnoreWorkingArea
+				\ EWMHPlacementUseWorkingArea
+				\ EWMHPlacementUseDynamicWorkingArea
+				\ MoveByProgramMethod Unmanaged State
+
+    " Cursor styles
+    syn keyword fvwmKeyword	nextgroup=fvwmCursorStyle skipwhite
+				\ CursorStyle
+    syn case match
+    syn keyword fvwmCursorStyle	contained
+				\ POSITION TITLE DEFAULT SYS MOVE RESIZE WAIT
+				\ MENU SELECT DESTROY TOP RIGHT BOTTOM LEFT
+				\ TOP_LEFT TOP_RIGHT BOTTOM_LEFT BOTTOM_RIGHT
+				\ TOP_EDGE RIGHT_EDGE BOTTOM_EDGE LEFT_EDGE
+				\ ROOT STROKE
+    syn case ignore
+
+    " Menu style
+    syn keyword fvwmKeyword	nextgroup=fvwmMStyleArgs skipwhite
+				\ MenuStyle
+    syn region	fvwmMStyleArgs	contained transparent contains=fvwmMStyleNames,@fvwmConstants,fvwmString,fvwmGradient,fvwmRGBValue
+				\ start='.' skip='\\$' end='$'
+    syn keyword	fvwmMStyleNames	contained
+				\ Fvwm Mwm Win BorderWidth Foreground
+				\ Background Greyed HilightBack HilightBackOff
+				\ ActiveFore ActiveForeOff MenuColorset
+				\ ActiveColorset GreyedColorset Hilight3DThick
+				\ Hilight3DThin Hilight3DOff
+				\ Hilight3DThickness Animation AnimationOff
+				\ Font MenuFace PopupDelay PopupOffset
+				\ TitleWarp TitleWarpOff TitleUnderlines0
+				\ TitleUnderlines1 TitleUnderlines2
+				\ SeparatorsLong SeparatorsShort
+				\ TrianglesSolid TrianglesRelief
+				\ PopupImmediately PopupDelayed
+				\ PopdownImmediately PopdownDelayed
+				\ PopupActiveArea DoubleClickTime SidePic
+				\ SideColor PopupAsRootMenu PopupAsSubmenu
+				\ PopupIgnore PopupClose RemoveSubmenus
+				\ HoldSubmenus SubmenusRight SubmenusLeft
+				\ SelectOnRelease ItemFormat
+				\ VerticalItemSpacing VerticalTitleSpacing
+				\ AutomaticHotkeys AutomaticHotkeysOff
+
+    " Button style
+    syn keyword fvwmKeyword	nextgroup=fvwmBNum	skipwhite
+				\ ButtonStyle AddButtonStyle
+    syn match	fvwmBNum	contained
+				\ nextgroup=fvwmBState,fvwmBStyleArgs skipwhite 
+				\ '\v<([0-9]|All|Left|Right|Reset)>'
+    syn keyword	fvwmBState	contained nextgroup=fvwmBStyleArgs skipwhite
+				\ ActiveUp ActiveDown InactiveUp InactiveDown
+				\ Active Inactive ToggledActiveUp
+				\ ToggledActiveDown ToggledInactiveUp
+				\ ToggledInactiveDown ToggledActive
+				\ ToggledInactive AllNormal AllToggled
+				\ AllActive AllInactive AllUp AllDown
+    syn region	fvwmBStyleArgs	contained contains=fvwmBStyleFlags,fvwmBStyleNames,fvwmGradient,fvwmRGBValue,@fvwmConstants,fvwmString
+				\ start='\S' skip='\\$' end='$'
+    syn keyword	fvwmBStyleNames	contained
+				\ Simple Default Solid Colorset Vector Pixmap
+				\ AdjustedPixmap ShrunkPixmap StretchedPixmap
+				\ TiledPixmap MiniIcon
+    syn keyword fvwmBStyleFlags	contained
+				\ Raised Sunk Flat UseTitleStyle
+				\ UseBorderStyle
+
+    " Border style
+    syn keyword fvwmKeyword	skipwhite nextgroup=fvwmBdState,fvwmBdStyleArgs
+				\ BorderStyle
+    syn keyword	fvwmBdState	contained skipwhite nextgroup=fvwmBdStyleArgs
+				\ Active Inactive
+    syn region	fvwmBdStyleArgs	contained contains=fvwmBdStyNames,fvwmBdStyFlags
+				\ start='\S' skip='\\$' end='$'
+    syn keyword	fvwmBdStyNames	contained
+				\ TiledPixmap Colorset
+    syn keyword	fvwmBdStyFlags	contained
+				\ HiddenHandles NoInset Raised Sunk Flat
+
+    " Title styles
+    syn keyword	fvwmKeyword	skipwhite nextgroup=fvwmTState,fvwmTStyleArgs
+				\ TitleStyle AddTitleStyle
+    syn keyword	fvwmTState	contained skipwhite nextgroup=fvwmTStyleArgs
+				\ ActiveUp ActiveDown InactiveUp InactiveDown
+				\ Active Inactive ToggledActiveUp
+				\ ToggledActiveDown ToggledInactiveUp
+				\ ToggledInactiveDown ToggledActive
+				\ ToggledInactive AllNormal AllToggled
+				\ AllActive AllInactive AllUp AllDown
+    syn region	fvwmTStyleArgs	contained contains=fvwmBStyleNames,fvwmTStyleNames,fvwmMPmapNames,fvwmTStyleFlags,fvwmGradient,fvwmRGBValue,@fvwmConstants
+				\ start='\S' skip='\\$' end='$'
+    syn keyword	fvwmTStyleNames	contained
+				\ MultiPixmap
+    syn keyword fvwmTStyleNames	contained
+				\ LeftJustified Centered RightJustified Height
+				\ MinHeight
+    syn keyword	fvwmMPmapNames	contained
+				\ Main LeftMain RightMain UnderText LeftOfText
+				\ RightOfText LeftEnd RightEnd Buttons
+				\ LeftButtons RightButtons
+    syn keyword	fvwmTStyleFlags	contained
+				\ Raised Flat Sunk
+
+    " Button state
+    syn keyword fvwmKeyword	nextgroup=fvwmBStateArgs
+				\ ButtonState
+    syn region	fvwmBStateArgs	contained contains=fvwmBStateTF,fvwmBStateNames
+				\ start='.' skip='\\$' end='$'
+    syn keyword	fvwmBStateNames	contained ActiveDown Inactive InactiveDown
+    syn keyword fvwmBStateTF	contained True False
+
+    " Paths
+    syn keyword fvwmKeyword	nextgroup=fvwmPath	skipwhite
+				\ IconPath ImagePath LocalePath PixmapPath
+				\ ModulePath 
+    syn match	fvwmPath	contained contains=fvwmEnvVar '\v.+$'
+
+    " Window list command
+    syn keyword fvwmKeyword	nextgroup=fvwmWLArgs skipwhite
+				\ WindowList
+    syn region	fvwmWLArgs	contained
+		\ contains=fvwmCondition,@fvwmConstants,fvwmString,fvwmWLOpts
+		\ start='.' skip='\\$' end='$'
+    syn keyword fvwmWLOpts	contained
+				\ Geometry NoGeometry NoGeometryWithInfo
+				\ NoDeskNum NoNumInDeskTitle
+				\ NoCurrentDeskTitle MaxLabelWidth width
+				\ TitleForAllDesks Function funcname Desk
+				\ desknum CurrentDesk NoIcons Icons OnlyIcons
+				\ NoNormal Normal OnlyNormal NoSticky Sticky
+				\ OnlySticky NoStickyAcrossPages
+				\ StickyAcrossPages OnlyStickyAcrossPages
+				\ NoStickyAcrossDesks StickyAcrossDesks
+				\ OnlyStickyAcrossDesks NoOnTop OnTop
+				\ OnlyOnTop NoOnBottom OnBottom OnlyOnBottom
+				\ Layer UseListSkip OnlyListSkip NoDeskSort
+				\ ReverseOrder CurrentAtEnd IconifiedAtEnd
+				\ UseIconName Alphabetic NotAlphabetic
+				\ SortByResource SortByClass NoHotkeys
+				\ SelectOnRelease
+
+    syn keyword fvwmSpecialFn	StartFunction InitFunction RestartFunction
+				\ ExitFunction SessionInitFunction
+				\ SessionRestartFunction SessionExitFunction
+				\ MissingSubmenuFunction WindowListFunc
+
+    syn keyword fvwmKeyword	skipwhite nextgroup=fvwmKeyWin,fvwmKeyName
+				\ Key PointerKey
+    syn region	fvwmKeyWin	contained skipwhite nextgroup=fvwmKeyName
+				\ start='(' end=')'
+    syn case match
+    syn match	fvwmKeyName	contained skipwhite nextgroup=fvwmKeyContext
+				\ '\v<([a-zA-Z0-9]|F\d+|KP_\d)>'
+    syn keyword fvwmKeyName	contained skipwhite nextgroup=fvwmKeyContext
+				\ BackSpace Begin Break Cancel Clear Delete
+				\ Down End Escape Execute Find Help Home
+				\ Insert KP_Add KP_Begin KP_Decimal KP_Delete
+				\ KP_Divide KP_Down KP_End KP_Enter KP_Equal
+				\ KP_Home KP_Insert KP_Left KP_Multiply
+				\ KP_Next KP_Page_Down KP_Page_Up KP_Prior
+				\ KP_Right KP_Separator KP_Space KP_Subtract
+				\ KP_Tab KP_Up Left Linefeed Menu Mode_switch
+				\ Next Num_Lock Page_Down Page_Up Pause Print
+				\ Prior Redo Return Right script_switch
+				\ Scroll_Lock Select Sys_Req Tab Undo Up space
+				\ exclam quotedbl numbersign dollar percent
+				\ ampersand apostrophe quoteright parenleft
+				\ parenright asterisk plus comma minus period
+				\ slash colon semicolon less equal greater
+				\ question at bracketleft backslash
+				\ bracketright asciicircum underscore grave
+				\ quoteleft braceleft bar braceright
+				\ asciitilde
+
+    syn match	fvwmKeyContext	contained skipwhite nextgroup=fvwmKeyMods
+				\ '\v<[][RWDTS_F<^>vI0-9AM-]+>'
+    syn match	fvwmKeyMods	contained '\v[NCSMLA1-5]+'
+    syn case ignore
+
+    syn keyword	fvwmKeyword	skipwhite nextgroup=fvwmMouseWin,fvwmMouseButton
+				\ Mouse
+    syn region	fvwmMouseWin	contained skipwhite nextgroup=fvwmMouseButton
+				\ start='(' end=')'
+    syn match	fvwmMouseButton	contained skipwhite nextgroup=fvwmKeyContext
+				\ '[0-5]'
+endif
+
+" Define syntax highlighting groups
+
+"
+" Common highlighting groups
+"
+hi def link fvwmComment		Comment
+hi def link fvwmEnvVar		Macro
+hi def link fvwmNumber		Number
+hi def link fvwmKeyword		Keyword
+hi def link fvwmPath		Constant
+hi def link fvwmModConf		Macro
+hi def link fvwmRGBValue	Constant
+hi def link fvwmString		String
+hi def link fvwmBackslash	SpecialChar
+
+
+"
+" Highlighting groups for fvwm1 specific items
+"
+hi def link fvwmExec		fvwmKeyword
+hi def link fvwmKey		fvwmKeyword
+hi def link fvwmModule		fvwmKeyword
+hi def link fvwmFunction	Function
+
+"
+" Highlighting groups for fvwm2 specific items
+"
+hi def link fvwmSpecialFn	Type
+hi def link fvwmCursorStyle	fvwmStyleNames
+hi def link fvwmStyleNames	Identifier
+hi def link fvwmMStyleNames	fvwmStyleNames
+hi def link fvwmCSNames		fvwmStyleNames
+hi def link fvwmGradient	fvwmStyleNames
+hi def link fvwmCondNames	fvwmStyleNames
+hi def link fvwmTCNames		fvwmStyleNames
+hi def link fvwmTRNames		fvwmStyleNames
+hi def link fvwmWLOpts		fvwmStyleNames
+
+hi def link fvwmBNum		Number
+hi def link fvwmBState		Type
+hi def link fvwmBStyleNames	fvwmStyleNames
+hi def link fvwmBStyleFlags	Special
+
+hi def link fvwmBStateTF	Constant
+hi def link fvwmBStateNames	fvwmStyleNames
+
+hi def link fvwmBdState		fvwmBState
+hi def link fvwmBdStyNames	fvwmStyleNames
+hi def link fvwmBdStyFlags	fvwmBStyleFlags
+
+hi def link fvwmTState		fvwmBState
+hi def link fvwmTStyleNames	fvwmStyleNames
+hi def link fvwmMPmapNames	fvwmBStyleFlags
+hi def link fvwmTStyleFlags	fvwmBStyleFlags
+
+hi def link fvwmDirection	fvwmBStyleFlags
+
+hi def link fvwmKeyWin		Constant
+hi def link fvwmMouseWin	fvwmKeyWin
+hi def link fvwmKeyName		Special
+hi def link fvwmKeyContext	fvwmKeyName
+hi def link fvwmKeyMods		fvwmKeyName
+hi def link fvwmMouseButton	fvwmKeyName
+
+hi def link fvwmMenuString	String
+hi def link fvwmIcon		Type
+hi def link fvwmShortcutKey	SpecialChar
+
+hi def link fvwmModuleName	Function
+
+let b:current_syntax = "fvwm"
--- /dev/null
+++ b/lib/vimfiles/syntax/fvwm2m4.vim
@@ -1,0 +1,43 @@
+" Vim syntax file
+" Language: FvwmM4 preprocessed Fvwm2 configuration files
+" Maintainer: David Ne\v{c}as (Yeti) <yeti@physics.muni.cz>
+" Last Change: 2002-06-02
+" URI: http://physics.muni.cz/~yeti/download/syntax/fvwmm4.vim
+
+" Setup
+if version >= 600
+  if exists('b:current_syntax')
+    finish
+  endif
+else
+  syntax clear
+endif
+
+" Let included files know they are included
+if !exists('main_syntax')
+  let main_syntax = 'fvwm2m4'
+endif
+
+" Include M4 syntax
+if version >= 600
+  runtime! syntax/m4.vim
+else
+  so <sfile>:p:h/m4.vim
+endif
+unlet b:current_syntax
+
+" Include Fvwm2 syntax (Fvwm1 doesn't have M4 preprocessor)
+if version >= 600
+  runtime! syntax/fvwm.vim
+else
+  so <sfile>:p:h/fvwm.vim
+endif
+unlet b:current_syntax
+
+" That's all!
+let b:current_syntax = 'fvwm2m4'
+
+if main_syntax == 'fvwm2m4'
+  unlet main_syntax
+endif
+
--- /dev/null
+++ b/lib/vimfiles/syntax/gdb.vim
@@ -1,0 +1,111 @@
+" Vim syntax file
+" Language:	GDB command files
+" Maintainer:	Claudio Fleiner <claudio@fleiner.com>
+" URL:		http://www.fleiner.com/vim/syntax/gdb.vim
+" Last Change:	2003 Jan 04
+
+" For version 5.x: Clear all syntax items
+" For version 6.x: Quit when a syntax file was already loaded
+if version < 600
+  syntax clear
+elseif exists("b:current_syntax")
+  finish
+endif
+
+syn keyword gdbInfo contained address architecture args breakpoints catch common copying dcache
+syn keyword gdbInfo contained display files float frame functions handle line
+syn keyword gdbInfo contained locals program registers scope set sharedlibrary signals
+syn keyword gdbInfo contained source sources stack symbol target terminal threads
+syn keyword gdbInfo contained syn keyword tracepoints types udot variables warranty watchpoints
+syn match gdbInfo contained "all-registers"
+
+
+syn keyword gdbStatement contained actions apply attach awatch backtrace break bt call catch cd clear collect commands
+syn keyword gdbStatement contained complete condition continue delete detach directory disable disassemble display down
+syn keyword gdbStatement contained echo else enable end file finish frame handle hbreak help if ignore
+syn keyword gdbStatement contained inspect jump kill list load maintenance make next nexti ni output overlay
+syn keyword gdbStatement contained passcount path print printf ptype pwd quit rbreak remote return run rwatch
+syn keyword gdbStatement contained search section set sharedlibrary shell show si signal source step stepi stepping
+syn keyword gdbStatement contained stop target tbreak tdump tfind thbreak thread tp trace tstart tstatus tstop
+syn keyword gdbStatement contained tty undisplay unset until up watch whatis where while ws x
+syn match gdbFuncDef "\<define\>.*"
+syn match gdbStatmentContainer "^\s*\S\+" contains=gdbStatement,gdbFuncDef
+syn match gdbStatement "^\s*info" nextgroup=gdbInfo skipwhite skipempty
+
+" some commonly used abreviations
+syn keyword gdbStatement c disp undisp disas p
+
+syn region gdbDocument matchgroup=gdbFuncDef start="\<document\>.*$" matchgroup=gdbFuncDef end="^end$"
+
+syn match gdbStatement "\<add-shared-symbol-files\>"
+syn match gdbStatement "\<add-symbol-file\>"
+syn match gdbStatement "\<core-file\>"
+syn match gdbStatement "\<dont-repeat\>"
+syn match gdbStatement "\<down-silently\>"
+syn match gdbStatement "\<exec-file\>"
+syn match gdbStatement "\<forward-search\>"
+syn match gdbStatement "\<reverse-search\>"
+syn match gdbStatement "\<save-tracepoints\>"
+syn match gdbStatement "\<select-frame\>"
+syn match gdbStatement "\<symbol-file\>"
+syn match gdbStatement "\<up-silently\>"
+syn match gdbStatement "\<while-stepping\>"
+
+syn keyword gdbSet annotate architecture args check complaints confirm editing endian
+syn keyword gdbSet environment gnutarget height history language listsize print prompt
+syn keyword gdbSet radix remotebaud remotebreak remotecache remotedebug remotedevice remotelogbase
+syn keyword gdbSet remotelogfile remotetimeout remotewritesize targetdebug variable verbose
+syn keyword gdbSet watchdog width write
+syn match gdbSet "\<auto-solib-add\>"
+syn match gdbSet "\<solib-absolute-prefix\>"
+syn match gdbSet "\<solib-search-path\>"
+syn match gdbSet "\<stop-on-solib-events\>"
+syn match gdbSet "\<symbol-reloading\>"
+syn match gdbSet "\<input-radix\>"
+syn match gdbSet "\<demangle-style\>"
+syn match gdbSet "\<output-radix\>"
+
+syn match gdbComment "^\s*#.*"
+
+syn match gdbVariable "\$\K\k*"
+
+" Strings and constants
+syn region  gdbString		start=+"+  skip=+\\\\\|\\"+  end=+"+
+syn match   gdbCharacter	"'[^']*'" contains=gdbSpecialChar,gdbSpecialCharError
+syn match   gdbCharacter	"'\\''" contains=gdbSpecialChar
+syn match   gdbCharacter	"'[^\\]'"
+syn match   gdbNumber		"\<[0-9_]\+\>"
+syn match   gdbNumber		"\<0x[0-9a-fA-F_]\+\>"
+
+
+if !exists("gdb_minlines")
+  let gdb_minlines = 10
+endif
+exec "syn sync ccomment gdbComment minlines=" . gdb_minlines
+
+" Define the default highlighting.
+" For version 5.7 and earlier: only when not done already
+" For version 5.8 and later: only when an item doesn't have highlighting yet
+if version >= 508 || !exists("did_gdb_syn_inits")
+  if version < 508
+    let did_gdb_syn_inits = 1
+    command -nargs=+ HiLink hi link <args>
+  else
+    command -nargs=+ HiLink hi def link <args>
+  endif
+  HiLink gdbFuncDef	Function
+  HiLink gdbComment	Comment
+  HiLink gdbStatement	Statement
+  HiLink gdbString	String
+  HiLink gdbCharacter	Character
+  HiLink gdbVariable	Identifier
+  HiLink gdbSet		Constant
+  HiLink gdbInfo	Type
+  HiLink gdbDocument	Special
+  HiLink gdbNumber	Number
+  delcommand HiLink
+endif
+
+let b:current_syntax = "gdb"
+
+" vim: ts=8
--- /dev/null
+++ b/lib/vimfiles/syntax/gdmo.vim
@@ -1,0 +1,96 @@
+" Vim syntax file
+" Language:	GDMO
+"		(ISO-10165-4; Guidelines for the Definition of Managed Object)
+" Maintainer:	Gyuman Kim <violino@dooly.modacom.co.kr>
+" URL:		http://dooly.modacom.co.kr/gdmo.vim
+" Last change:	2001 Sep 02
+
+" For version 5.x: Clear all syntax items
+" For version 6.x: Quit when a syntax file was already loaded
+if version < 600
+  syntax clear
+elseif exists("b:current_syntax")
+  finish
+endif
+
+" keyword definitions
+syn match   gdmoCategory      "MANAGED\s\+OBJECT\s\+CLASS"
+syn keyword gdmoCategory      NOTIFICATION ATTRIBUTE BEHAVIOUR PACKAGE ACTION
+syn match   gdmoCategory      "NAME\s\+BINDING"
+syn match   gdmoRelationship  "DERIVED\s\+FROM"
+syn match   gdmoRelationship  "SUPERIOR\s\+OBJECT\s\+CLASS"
+syn match   gdmoRelationship  "SUBORDINATE\s\+OBJECT\s\+CLASS"
+syn match   gdmoExtension     "AND\s\+SUBCLASSES"
+syn match   gdmoDefinition    "DEFINED\s\+AS"
+syn match   gdmoDefinition    "REGISTERED\s\+AS"
+syn match   gdmoExtension     "ORDER\s\+BY"
+syn match   gdmoReference     "WITH\s\+ATTRIBUTE"
+syn match   gdmoReference     "WITH\s\+INFORMATION\s\+SYNTAX"
+syn match   gdmoReference     "WITH\s\+REPLY\s\+SYNTAX"
+syn match   gdmoReference     "WITH\s\+ATTRIBUTE\s\+SYNTAX"
+syn match   gdmoExtension     "AND\s\+ATTRIBUTE\s\+IDS"
+syn match   gdmoExtension     "MATCHES\s\+FOR"
+syn match   gdmoReference     "CHARACTERIZED\s\+BY"
+syn match   gdmoReference     "CONDITIONAL\s\+PACKAGES"
+syn match   gdmoExtension     "PRESENT\s\+IF"
+syn match   gdmoExtension     "DEFAULT\s\+VALUE"
+syn match   gdmoExtension     "PERMITTED\s\+VALUES"
+syn match   gdmoExtension     "REQUIRED\s\+VALUES"
+syn match   gdmoExtension     "NAMED\s\+BY"
+syn keyword gdmoReference     ATTRIBUTES NOTIFICATIONS ACTIONS
+syn keyword gdmoExtension     DELETE CREATE
+syn keyword gdmoExtension     EQUALITY SUBSTRINGS ORDERING
+syn match   gdmoExtension     "REPLACE-WITH-DEFAULT"
+syn match   gdmoExtension     "GET"
+syn match   gdmoExtension     "GET-REPLACE"
+syn match   gdmoExtension     "ADD-REMOVE"
+syn match   gdmoExtension     "WITH-REFERENCE-OBJECT"
+syn match   gdmoExtension     "WITH-AUTOMATIC-INSTANCE-NAMING"
+syn match   gdmoExtension     "ONLY-IF-NO-CONTAINED-OBJECTS"
+
+
+" Strings and constants
+syn match   gdmoSpecial		contained "\\\d\d\d\|\\."
+syn region  gdmoString		start=+"+  skip=+\\\\\|\\"+  end=+"+  contains=gdmoSpecial
+syn match   gdmoCharacter	  "'[^\\]'"
+syn match   gdmoSpecialCharacter  "'\\.'"
+syn match   gdmoNumber		  "0[xX][0-9a-fA-F]\+\>"
+syn match   gdmoLineComment       "--.*"
+syn match   gdmoLineComment       "--.*--"
+
+syn match gdmoDefinition "^\s*[a-zA-Z][-a-zA-Z0-9_.\[\] \t{}]* *::="me=e-3
+syn match gdmoBraces     "[{}]"
+
+syn sync ccomment gdmoComment
+
+" Define the default highlighting.
+" For version 5.7 and earlier: only when not done already
+" For version 5.8 and later: only when an item doesn't have highlighting yet
+if version >= 508 || !exists("did_gdmo_syntax_inits")
+  if version < 508
+    let did_gdmo_syntax_inits = 1
+    command -nargs=+ HiLink hi link <args>
+  else
+    command -nargs=+ HiLink hi def link <args>
+  endif
+
+  HiLink gdmoCategory	      Structure
+  HiLink gdmoRelationship     Macro
+  HiLink gdmoDefinition       Statement
+  HiLink gdmoReference	      Type
+  HiLink gdmoExtension	      Operator
+  HiLink gdmoBraces	      Function
+  HiLink gdmoSpecial	      Special
+  HiLink gdmoString	      String
+  HiLink gdmoCharacter	      Character
+  HiLink gdmoSpecialCharacter gdmoSpecial
+  HiLink gdmoComment	      Comment
+  HiLink gdmoLineComment      gdmoComment
+  HiLink gdmoType	      Type
+
+  delcommand HiLink
+endif
+
+let b:current_syntax = "gdmo"
+
+" vim: ts=8
--- /dev/null
+++ b/lib/vimfiles/syntax/gedcom.vim
@@ -1,0 +1,66 @@
+" Vim syntax file
+" Language:	Gedcom
+" Maintainer:	Paul Johnson (pjcj@transeda.com)
+" Version 1.059 - 23rd December 1999
+
+" For version 5.x: Clear all syntax items
+" For version 6.x: Quit when a syntax file was already loaded
+if version < 600
+  syntax clear
+elseif exists("b:current_syntax")
+  finish
+endif
+
+syntax case match
+
+syntax keyword gedcom_record ABBR ADDR ADOP ADR1 ADR2 AFN AGE AGNC ALIA ANCE
+syntax keyword gedcom_record ANCI ANUL ASSO AUTH BAPL BAPM BARM BASM BIRT BLES
+syntax keyword gedcom_record BLOB BURI CALN CAST CAUS CENS CHAN CHAR CHIL CHR
+syntax keyword gedcom_record CHRA CITY CONC CONF CONL CONT COPR CORP CREM CTRY
+syntax keyword gedcom_record DATA DEAT DESC DESI DEST DIV DIVF DSCR EDUC EMIG
+syntax keyword gedcom_record ENDL ENGA EVEN FAM FAMC FAMF FAMS FCOM FILE FORM
+syntax keyword gedcom_record GEDC GIVN GRAD HEAD HUSB IDNO IMMI INDI LANG MARB
+syntax keyword gedcom_record MARC MARL MARR MARS MEDI NATI NATU NCHI NICK NMR
+syntax keyword gedcom_record NOTE NPFX NSFX OBJE OCCU ORDI ORDN PAGE PEDI PHON
+syntax keyword gedcom_record PLAC POST PROB PROP PUBL QUAY REFN RELA RELI REPO
+syntax keyword gedcom_record RESI RESN RETI RFN RIN ROLE SEX SLGC SLGS SOUR
+syntax keyword gedcom_record SPFX SSN STAE STAT SUBM SUBN SURN TEMP TEXT TIME
+syntax keyword gedcom_record TITL TRLR TYPE VERS WIFE WILL
+syntax keyword gedcom_record DATE nextgroup=gedcom_date
+syntax keyword gedcom_record NAME nextgroup=gedcom_name
+
+syntax case ignore
+
+syntax region gedcom_id start="@" end="@" oneline contains=gedcom_ii, gedcom_in
+syntax match gedcom_ii "\I\+" contained nextgroup=gedcom_in
+syntax match gedcom_in "\d\+" contained
+syntax region gedcom_name start="" end="$" skipwhite oneline contains=gedcom_cname, gedcom_surname contained
+syntax match gedcom_cname "\i\+" contained
+syntax match gedcom_surname "/\(\i\|\s\)*/" contained
+syntax match gedcom_date "\d\{1,2}\s\+\(jan\|feb\|mar\|apr\|may\|jun\|jul\|aug\|sep\|oct\|nov\|dec\)\s\+\d\+"
+syntax match gedcom_date ".*" contained
+
+" Define the default highlighting.
+" For version 5.7 and earlier: only when not done already
+" For version 5.8 and later: only when an item doesn't have highlighting yet
+if version >= 508 || !exists("did_gedcom_syntax_inits")
+  if version < 508
+    let did_gedcom_syntax_inits = 1
+    command -nargs=+ HiLink hi link <args>
+  else
+    command -nargs=+ HiLink hi def link <args>
+  endif
+
+  HiLink gedcom_record Statement
+  HiLink gedcom_id Comment
+  HiLink gedcom_ii PreProc
+  HiLink gedcom_in Type
+  HiLink gedcom_name PreProc
+  HiLink gedcom_cname Type
+  HiLink gedcom_surname Identifier
+  HiLink gedcom_date Constant
+
+  delcommand HiLink
+endif
+
+let b:current_syntax = "gedcom"
--- /dev/null
+++ b/lib/vimfiles/syntax/gkrellmrc.vim
@@ -1,0 +1,91 @@
+" Vim syntax file
+" This is a GENERATED FILE. Please always refer to source file at the URI below.
+" Language: gkrellm theme files `gkrellmrc'
+" Maintainer: David Ne\v{c}as (Yeti) <yeti@physics.muni.cz>
+" Last Change: 2003-04-30
+" URL: http://trific.ath.cx/Ftp/vim/syntax/gkrellmrc.vim
+
+" Setup
+if version >= 600
+	if exists("b:current_syntax")
+		finish
+	endif
+else
+	syntax clear
+endif
+
+if version >= 600
+	setlocal iskeyword=_,-,a-z,A-Z,48-57
+else
+	set iskeyword=_,-,a-z,A-Z,48-57
+endif
+
+syn case match
+
+" Base constructs
+syn match gkrellmrcComment "#.*$" contains=gkrellmrcFixme
+syn keyword gkrellmrcFixme FIXME TODO XXX NOT contained
+syn region gkrellmrcString start=+"+ skip=+\\\\\|\\"+ end=+"+ oneline
+syn match gkrellmrcNumber "^-\=\(\d\+\)\=\.\=\d\+"
+syn match gkrellmrcNumber "\W-\=\(\d\+\)\=\.\=\d\+"lc=1
+syn keyword gkrellmrcConstant none
+syn match gkrellmrcRGBColor "#\(\x\{12}\|\x\{9}\|\x\{6}\|\x\{3}\)\>"
+
+" Keywords
+syn keyword gkrellmrcBuiltinExt cpu_nice_color cpu_nice_grid_color krell_depth krell_expand krell_left_margin krell_right_margin krell_x_hot krell_yoff mem_krell_buffers_depth mem_krell_buffers_expand mem_krell_buffers_x_hot mem_krell_buffers_yoff mem_krell_cache_depth mem_krell_cache_expand mem_krell_cache_x_hot mem_krell_cache_yoff sensors_bg_volt timer_bg_timer
+syn keyword gkrellmrcGlobal allow_scaling author chart_width_ref theme_alternatives
+syn keyword gkrellmrcSetCmd set_image_border set_integer set_string
+syn keyword gkrellmrcGlobal bg_slider_meter_border bg_slider_panel_border
+syn keyword gkrellmrcGlobal frame_bottom_height frame_left_width frame_right_width frame_top_height frame_left_chart_overlap frame_right_chart_overlap frame_left_panel_overlap frame_right_panel_overlap frame_left_spacer_overlap frame_right_spacer_overlap spacer_overlap_off cap_images_off
+syn keyword gkrellmrcGlobal frame_bottom_border frame_left_border frame_right_border frame_top_border spacer_top_border spacer_bottom_border frame_left_chart_border frame_right_chart_border frame_left_panel_border frame_right_panel_border
+syn keyword gkrellmrcGlobal chart_in_color chart_in_color_grid chart_out_color chart_out_color_grid
+syn keyword gkrellmrcGlobal bg_separator_height bg_grid_mode
+syn keyword gkrellmrcGlobal rx_led_x rx_led_y tx_led_x tx_led_y
+syn keyword gkrellmrcGlobal decal_mail_frames decal_mail_delay
+syn keyword gkrellmrcGlobal decal_alarm_frames decal_warn_frames
+syn keyword gkrellmrcGlobal krell_slider_depth krell_slider_expand krell_slider_x_hot
+syn keyword gkrellmrcGlobal button_panel_border button_meter_border
+syn keyword gkrellmrcGlobal large_font normal_font small_font
+syn keyword gkrellmrcGlobal spacer_bottom_height spacer_top_height spacer_bottom_height_chart spacer_top_height_chart spacer_bottom_height_meter spacer_top_height_meter
+syn keyword gkrellmrcExpandMode left right bar-mode left-scaled right-scaled bar-mode-scaled
+syn keyword gkrellmrcMeterName apm cal clock fs host mail mem swap timer sensors uptime
+syn keyword gkrellmrcChartName cpu proc disk inet and net
+syn match gkrellmrcSpecialClassName "\*"
+syn keyword gkrellmrcStyleCmd StyleMeter StyleChart StylePanel
+syn keyword gkrellmrcStyleItem textcolor alt_textcolor font alt_font transparency border label_position margin margins left_margin right_margin top_margin bottom_margin krell_depth krell_yoff krell_x_hot krell_expand krell_left_margin krell_right_margin
+
+" Define the default highlighting
+if version >= 508 || !exists("did_gtkrc_syntax_inits")
+	if version < 508
+		let did_gtkrc_syntax_inits = 1
+		command -nargs=+ HiLink hi link <args>
+	else
+		command -nargs=+ HiLink hi def link <args>
+	endif
+
+	HiLink gkrellmrcComment Comment
+	HiLink gkrellmrcFixme Todo
+
+	HiLink gkrellmrcString gkrellmrcConstant
+	HiLink gkrellmrcNumber gkrellmrcConstant
+	HiLink gkrellmrcRGBColor gkrellmrcConstant
+	HiLink gkrellmrcExpandMode gkrellmrcConstant
+	HiLink gkrellmrcConstant Constant
+
+	HiLink gkrellmrcMeterName gkrellmrcClass
+	HiLink gkrellmrcChartName gkrellmrcClass
+	HiLink gkrellmrcSpecialClassName gkrellmrcClass
+	HiLink gkrellmrcClass Type
+
+	HiLink gkrellmrcGlobal gkrellmrcItem
+	HiLink gkrellmrcBuiltinExt gkrellmrcItem
+	HiLink gkrellmrcStyleItem gkrellmrcItem
+	HiLink gkrellmrcItem Function
+
+	HiLink gkrellmrcSetCmd Special
+	HiLink gkrellmrcStyleCmd Statement
+
+	delcommand HiLink
+endif
+
+let b:current_syntax = "gkrellmrc"
--- /dev/null
+++ b/lib/vimfiles/syntax/gnuplot.vim
@@ -1,0 +1,198 @@
+" Vim syntax file
+" Language:	gnuplot 3.8i.0
+" Maintainer:	John Hoelzel johnh51@users.sourceforge.net
+" Last Change:	Mon May 26 02:33:33 UTC 2003
+" Filenames:	*.gpi  *.gih   scripts: #!*gnuplot
+" URL:		http://johnh51.get.to/vim/syntax/gnuplot.vim
+"
+
+" thanks to "David Necas (Yeti)" <yeti@physics.muni.cz> for heads up - working on more changes .
+" *.gpi      = GnuPlot Input - what I use because there is no other guideline. jeh 11/2000
+" *.gih      = makes using cut/pasting from gnuplot.gih easier ...
+" #!*gnuplot = for Linux bash shell scripts of gnuplot commands.
+"	       emacs used a suffix of '<gp?>'
+" gnuplot demo files show no preference.
+" I will post mail and newsgroup comments on a standard suffix in 'URL' directory.
+
+" For version 5.x: Clear all syntax items
+" For version 6.x: Quit when a syntax file was already loaded
+if version < 600
+  syntax clear
+elseif exists("b:current_syntax")
+  finish
+endif
+
+" some shortened names to make demo files look clean... jeh. 11/2000
+" demos -> 3.8i ... jeh. 5/2003 - a work in progress...
+
+" commands
+
+syn keyword gnuplotStatement	cd call clear exit set unset plot splot help
+syn keyword gnuplotStatement	load pause quit fit rep[lot] if
+syn keyword gnuplotStatement	FIT_LIMIT FIT_MAXITER FIT_START_LAMBDA
+syn keyword gnuplotStatement	FIT_LAMBDA_FACTOR FIT_LOG FIT_SCRIPT
+syn keyword gnuplotStatement	print pwd reread reset save show test ! functions var
+syn keyword gnuplotConditional	if
+" if is cond + stmt - ok?
+
+" numbers fm c.vim
+
+"	integer number, or floating point number without a dot and with "f".
+syn case    ignore
+syn match   gnuplotNumber	"\<[0-9]\+\(u\=l\=\|lu\|f\)\>"
+"	floating point number, with dot, optional exponent
+syn match   gnuplotFloat	"\<[0-9]\+\.[0-9]*\(e[-+]\=[0-9]\+\)\=[fl]\=\>"
+"	floating point number, starting with a dot, optional exponent
+syn match   gnuplotFloat	"\.[0-9]\+\(e[-+]\=[0-9]\+\)\=[fl]\=\>"
+"	floating point number, without dot, with exponent
+syn match   gnuplotFloat	"\<[0-9]\+e[-+]\=[0-9]\+[fl]\=\>"
+"	hex number
+syn match   gnuplotNumber	"\<0x[0-9a-f]\+\(u\=l\=\|lu\)\>"
+syn case    match
+"	flag an octal number with wrong digits by not hilighting
+syn match   gnuplotOctalError	"\<0[0-7]*[89]"
+
+" plot args
+
+syn keyword gnuplotType		u[sing] tit[le] notit[le] wi[th] steps fs[teps]
+syn keyword gnuplotType		title notitle t
+syn keyword gnuplotType		with w
+syn keyword gnuplotType		li[nes] l
+" t - too much?  w - too much?  l - too much?
+syn keyword gnuplotType		linespoints via
+
+" funcs
+
+syn keyword gnuplotFunc		abs acos acosh arg asin asinh atan atanh atan2
+syn keyword gnuplotFunc		besj0 besj1 besy0 besy1
+syn keyword gnuplotFunc		ceil column cos cosh erf erfc exp floor gamma
+syn keyword gnuplotFunc		ibeta inverf igamma imag invnorm int lgamma
+syn keyword gnuplotFunc		log log10 norm rand real sgn sin sinh sqrt tan
+syn keyword gnuplotFunc		lambertw
+syn keyword gnuplotFunc		tanh valid
+syn keyword gnuplotFunc		tm_hour tm_mday tm_min tm_mon tm_sec
+syn keyword gnuplotFunc		tm_wday tm_yday tm_year
+
+" set vars
+
+syn keyword gnuplotType		xdata timefmt grid noytics ytics fs
+syn keyword gnuplotType		logscale time notime mxtics nomxtics style mcbtics
+syn keyword gnuplotType		nologscale
+syn keyword gnuplotType		axes x1y2 unique acs[plines]
+syn keyword gnuplotType		size origin multiplot xtics xr[ange] yr[ange] square nosquare ratio noratio
+syn keyword gnuplotType		binary matrix index every thru sm[ooth]
+syn keyword gnuplotType		all angles degrees radians
+syn keyword gnuplotType		arrow noarrow autoscale noautoscale arrowstyle
+" autoscale args = x y xy z t ymin ... - too much?
+" needs code to: using title vs autoscale t
+syn keyword gnuplotType		x y z zcb
+syn keyword gnuplotType		linear  cubicspline  bspline order level[s]
+syn keyword gnuplotType		auto disc[rete] incr[emental] from to head nohead
+syn keyword gnuplotType		graph base both nosurface table out[put] data
+syn keyword gnuplotType		bar border noborder boxwidth
+syn keyword gnuplotType		clabel noclabel clip noclip cntrp[aram]
+syn keyword gnuplotType		contour nocontour
+syn keyword gnuplotType		dgrid3d nodgrid3d dummy encoding format
+" set encoding args not included - yet.
+syn keyword gnuplotType		function grid nogrid hidden[3d] nohidden[3d] isosample[s] key nokey
+syn keyword gnuplotType		historysize nohistorysize
+syn keyword gnuplotType		defaults offset nooffset trianglepattern undefined noundefined altdiagonal bentover noaltdiagonal nobentover
+syn keyword gnuplotType		left right top bottom outside below samplen spacing width height box nobox linestyle ls linetype lt linewidth lw
+syn keyword gnuplotType		Left Right autotitles noautotitles enhanced noenhanced
+syn keyword gnuplotType		isosamples
+syn keyword gnuplotType		label nolabel logscale nolog[scale] missing center font locale
+syn keyword gnuplotType		mapping margin bmargin lmargin rmargin tmargin spherical cylindrical cartesian
+syn keyword gnuplotType		linestyle nolinestyle linetype lt linewidth lw pointtype pt pointsize ps
+syn keyword gnuplotType		mouse nomouse
+syn keyword gnuplotType		nooffsets data candlesticks financebars linespoints lp vector nosurface
+syn keyword gnuplotType		term[inal] linux aed767 aed512 gpic
+syn keyword gnuplotType		regis tek410x tek40 vttek kc-tek40xx
+syn keyword gnuplotType		km-tek40xx selanar bitgraph xlib x11 X11
+" x11 args
+syn keyword gnuplotType		aifm cgm dumb fig gif small large size nofontlist winword6 corel dxf emf
+syn keyword gnuplotType		hpgl
+" syn keyword gnuplotType	transparent hp2623a hp2648 hp500c pcl5				      why jeh
+syn keyword gnuplotType		hp2623a hp2648 hp500c pcl5
+syn match gnuplotType		"\<transparent\>"
+syn keyword gnuplotType		hpljii hpdj hppj imagen mif pbm png svg
+syn keyword gnuplotType		postscript enhanced_postscript qms table
+" postscript editing values?
+syn keyword gnuplotType		tgif tkcanvas epson-180dpi epson-60dpi
+syn keyword gnuplotType		epson-lx800 nec-cp6 okidata starc
+syn keyword gnuplotType		tandy-60dpi latex emtex pslatex pstex epslatex
+syn keyword gnuplotType		eepic tpic pstricks texdraw mf metafont mpost mp
+syn keyword gnuplotType		timestamp notimestamp
+syn keyword gnuplotType		variables version
+syn keyword gnuplotType		x2data y2data ydata zdata
+syn keyword gnuplotType		reverse writeback noreverse nowriteback
+syn keyword gnuplotType		axis mirror autofreq nomirror rotate autofreq norotate
+syn keyword gnuplotType		update
+syn keyword gnuplotType		multiplot nomultiplot mytics
+syn keyword gnuplotType		nomytics mztics nomztics mx2tics nomx2tics
+syn keyword gnuplotType		my2tics nomy2tics offsets origin output
+syn keyword gnuplotType		para[metric] nopara[metric] pointsize polar nopolar
+syn keyword gnuplotType		zrange x2range y2range rrange cbrange
+syn keyword gnuplotType		trange urange vrange sample[s] size
+syn keyword gnuplotType		bezier boxerrorbars boxes bargraph bar[s]
+syn keyword gnuplotType		boxxy[errorbars] csplines dots fsteps histeps impulses
+syn keyword gnuplotType		line[s] linesp[oints] points poiinttype sbezier splines steps
+" w lt lw ls	      = optional
+syn keyword gnuplotType		vectors xerr[orbars] xyerr[orbars] yerr[orbars] financebars candlesticks vector
+syn keyword gnuplotType		errorb[ars] surface
+syn keyword gnuplotType		filledcurve[s] pm3d   x1 x2 y1 y2 xy closed
+syn keyword gnuplotType		at pi front
+syn keyword gnuplotType		errorlines xerrorlines yerrorlines xyerrorlines
+syn keyword gnuplotType		tics ticslevel ticscale time timefmt view
+syn keyword gnuplotType		xdata xdtics noxdtics ydtics noydtics
+syn keyword gnuplotType		zdtics nozdtics x2dtics nox2dtics y2dtics noy2dtics
+syn keyword gnuplotType		xlab[el] ylab[el] zlab[el] cblab[el] x2label y2label xmtics
+syn keyword gnuplotType		xmtics noxmtics ymtics noymtics zmtics nozmtics
+syn keyword gnuplotType		x2mtics nox2mtics y2mtics noy2mtics
+syn keyword gnuplotType		cbdtics nocbdtics cbmtics nocbmtics cbtics nocbtics
+syn keyword gnuplotType		xtics noxtics ytics noytics
+syn keyword gnuplotType		ztics noztics x2tics nox2tics
+syn keyword gnuplotType		y2tics noy2tics zero nozero zeroaxis nozeroaxis
+syn keyword gnuplotType		xzeroaxis noxzeroaxis yzeroaxis noyzeroaxis
+syn keyword gnuplotType		x2zeroaxis nox2zeroaxis y2zeroaxis noy2zeroaxis
+syn keyword gnuplotType		angles one two fill empty solid pattern
+syn keyword gnuplotType		default
+syn keyword gnuplotType		scansautomatic flush b[egin] noftriangles implicit
+" b too much? - used in demo
+syn keyword gnuplotType		palette positive negative ps_allcF nops_allcF maxcolors
+syn keyword gnuplotType		push fontfile pop
+syn keyword gnuplotType		rgbformulae defined file color model gradient colornames
+syn keyword gnuplotType		RGB HSV CMY YIQ XYZ
+syn keyword gnuplotType		colorbox vertical horizontal user bdefault
+syn keyword gnuplotType		loadpath fontpath decimalsign in out
+
+" comments + strings
+syn region gnuplotComment	start="#" end="$"
+syn region gnuplotComment	start=+"+ skip=+\\"+ end=+"+
+syn region gnuplotComment	start=+'+	     end=+'+
+
+" Define the default highlighting.
+" For version 5.7 and earlier: only when not done already
+" For version 5.8 and later: only when an item doesn't have highlighting yet
+if version >= 508 || !exists("did_gnuplot_syntax_inits")
+  if version < 508
+    let did_gnuplot_syntax_inits = 1
+    command -nargs=+ HiLink hi link <args>
+  else
+    command -nargs=+ HiLink hi def link <args>
+  endif
+
+  HiLink gnuplotStatement	Statement
+  HiLink gnuplotConditional	Conditional
+  HiLink gnuplotNumber		Number
+  HiLink gnuplotFloat		Float
+  HiLink gnuplotOctalError	Error
+  HiLink gnuplotFunc		Type
+  HiLink gnuplotType		Type
+  HiLink gnuplotComment	Comment
+
+  delcommand HiLink
+endif
+
+let b:current_syntax = "gnuplot"
+
+" vim: ts=8
--- /dev/null
+++ b/lib/vimfiles/syntax/gp.vim
@@ -1,0 +1,82 @@
+" Vim syntax file
+" Language:	gp (version 2.2)
+" Maintainer:	Karim Belabas <Karim.Belabas@math.u-bordeaux.fr>
+" Last change:	2006 Apr 12
+" URL:		http://pari.math.u-bordeaux.fr
+
+if version < 600
+  syntax clear
+elseif exists("b:current_syntax")
+  finish
+endif
+
+" control statements
+syntax keyword gpStatement	break return next
+syntax keyword gpConditional	if
+syntax keyword gpRepeat		until while for fordiv forprime forstep forvec
+" storage class
+syntax keyword gpScope		local global
+" defaults
+syntax keyword gpInterfaceKey	colors compatible datadir debug debugfiles
+syntax keyword gpInterfaceKey	debugmem echo factor_add_primes format help
+syntax keyword gpInterfaceKey	histsize lines log logfile new_galois_format
+syntax keyword gpInterfaceKey	output parisize path prettyprinter primelimit
+syntax keyword gpInterfaceKey	prompt prompt_cont psfile realprecision secure
+syntax keyword gpInterfaceKey	seriesprecision simplify strictmatch TeXstyle timer
+
+syntax match   gpInterface	"^\s*\\[a-z].*"
+syntax keyword gpInterface	default
+syntax keyword gpInput		read input
+
+" functions
+syntax match gpFunRegion "^\s*[a-zA-Z][_a-zA-Z0-9]*(.*)\s*=\s*[^ \t=]"me=e-1 contains=gpFunction,gpArgs
+syntax match gpFunRegion "^\s*[a-zA-Z][_a-zA-Z0-9]*(.*)\s*=\s*$" contains=gpFunction,gpArgs
+syntax match gpArgs contained "[a-zA-Z][_a-zA-Z0-9]*"
+syntax match gpFunction contained "^\s*[a-zA-Z][_a-zA-Z0-9]*("me=e-1
+
+" String and Character constants
+" Highlight special (backslash'ed) characters differently
+syntax match  gpSpecial contained "\\[ent\\]"
+syntax region gpString  start=+"+ skip=+\\\\\|\\"+ end=+"+ contains=gpSpecial
+
+"comments
+syntax region gpComment	start="/\*"  end="\*/" contains=gpTodo
+syntax match  gpComment "\\\\.*" contains=gpTodo
+syntax keyword gpTodo contained	TODO
+syntax sync ccomment gpComment minlines=10
+
+"catch errors caused by wrong parenthesis
+syntax region gpParen		transparent start='(' end=')' contains=ALLBUT,gpParenError,gpTodo,gpFunction,gpArgs,gpSpecial
+syntax match gpParenError	")"
+syntax match gpInParen contained "[{}]"
+
+if version >= 508 || !exists("did_gp_syn_inits")
+  if version < 508
+    let did_gp_syn_inits = 1
+    command -nargs=+ HiLink hi link <args>
+  else
+    command -nargs=+ HiLink hi def link <args>
+  endif
+
+  HiLink gpConditional		Conditional
+  HiLink gpRepeat		Repeat
+  HiLink gpError		Error
+  HiLink gpParenError		gpError
+  HiLink gpInParen		gpError
+  HiLink gpStatement		Statement
+  HiLink gpString		String
+  HiLink gpComment		Comment
+  HiLink gpInterface		Type
+  HiLink gpInput		Type
+  HiLink gpInterfaceKey		Statement
+  HiLink gpFunction		Function
+  HiLink gpScope		Type
+  " contained ones
+  HiLink gpSpecial		Special
+  HiLink gpTodo			Todo
+  HiLink gpArgs			Type
+  delcommand HiLink
+endif
+
+let b:current_syntax = "gp"
+" vim: ts=8
--- /dev/null
+++ b/lib/vimfiles/syntax/gpg.vim
@@ -1,0 +1,105 @@
+" Vim syntax file
+" Language:         gpg(1) configuration file
+" Maintainer:       Nikolai Weibull <now@bitwi.se>
+" Latest Revision:  2007-05-06
+
+if exists("b:current_syntax")
+  finish
+endif
+
+let s:cpo_save = &cpo
+set cpo&vim
+
+setlocal iskeyword=@,48-57,-
+
+syn keyword gpgTodo     contained FIXME TODO XXX NOTE
+
+syn region  gpgComment  contained display oneline start='#' end='$'
+                        \ contains=gpgTodo,gpgID,@Spell
+
+syn match   gpgID       contained display '\<\(0x\)\=\x\{8,}\>'
+
+syn match   gpgBegin    display '^' skipwhite nextgroup=gpgComment,gpgOption,gpgCommand
+
+syn keyword gpgCommand  contained skipwhite nextgroup=gpgArg
+                        \ check-sigs decrypt decrypt-files delete-key
+                        \ delete-secret-and-public-key delete-secret-key
+                        \ edit-key encrypt-files export export-all
+                        \ export-ownertrust export-secret-keys
+                        \ export-secret-subkeys fast-import fingerprint
+                        \ gen-prime gen-random import import-ownertrust
+                        \ list-keys list-public-keys list-secret-keys
+                        \ list-sigs lsign-key nrsign-key print-md print-mds
+                        \ recv-keys search-keys send-keys sign-key verify
+                        \ verify-files
+syn keyword gpgCommand  contained skipwhite nextgroup=gpgArgError
+                        \ check-trustdb clearsign desig-revoke detach-sign
+                        \ encrypt gen-key gen-revoke help list-packets
+                        \ rebuild-keydb-caches sign store symmetric
+                        \ update-trustdb version warranty
+
+syn keyword gpgOption   contained skipwhite nextgroup=gpgArg
+                        \ attribute-fd cert-digest-algo charset cipher-algo
+                        \ command-fd comment completes-needed compress
+                        \ compress-algo debug default-cert-check-level
+                        \ default-key default-preference-list
+                        \ default-recipient digest-algo disable-cipher-algo
+                        \ disable-pubkey-algo encrypt-to exec-path
+                        \ export-options group homedir import-options
+                        \ keyring keyserver keyserver-options load-extension
+                        \ local-user logger-fd marginals-needed max-cert-depth
+                        \ notation-data options output override-session-key
+                        \ passphrase-fd personal-cipher-preferences
+                        \ personal-compress-preferences
+                        \ personal-digest-preferences photo-viewer
+                        \ recipient s2k-cipher-algo s2k-digest-algo s2k-mode
+                        \ secret-keyring set-filename set-policy-url status-fd
+                        \ trusted-key verify-options
+syn keyword gpgOption   contained skipwhite nextgroup=gpgArgError
+                        \ allow-freeform-uid allow-non-selfsigned-uid
+                        \ allow-secret-key-import always-trust
+                        \ armor ask-cert-expire ask-sig-expire
+                        \ auto-check-trustdb batch debug-all default-comment
+                        \ default-recipient-self dry-run emit-version
+                        \ emulate-md-encode-bug enable-special-filenames
+                        \ escape-from-lines expert fast-list-mode
+                        \ fixed-list-mode for-your-eyes-only
+                        \ force-mdc force-v3-sigs force-v4-certs
+                        \ gpg-agent-info ignore-crc-error ignore-mdc-error
+                        \ ignore-time-conflict ignore-valid-from interactive
+                        \ list-only lock-multiple lock-never lock-once
+                        \ merge-only no no-allow-non-selfsigned-uid
+                        \ no-armor no-ask-cert-expire no-ask-sig-expire
+                        \ no-auto-check-trustdb no-batch no-comment
+                        \ no-default-keyring no-default-recipient
+                        \ no-encrypt-to no-expensive-trust-checks
+                        \ no-expert no-for-your-eyes-only no-force-v3-sigs
+                        \ no-force-v4-certs no-greeting no-literal
+                        \ no-mdc-warning no-options no-permission-warning
+                        \ no-pgp2 no-pgp6 no-pgp7 no-random-seed-file
+                        \ no-secmem-warning no-show-notation no-show-photos
+                        \ no-show-policy-url no-sig-cache no-sig-create-check
+                        \ no-sk-comments no-tty no-utf8-strings no-verbose
+                        \ no-version not-dash-escaped openpgp pgp2
+                        \ pgp6 pgp7 preserve-permissions quiet rfc1991
+                        \ set-filesize show-keyring show-notation show-photos
+                        \ show-policy-url show-session-key simple-sk-checksum
+                        \ sk-comments skip-verify textmode throw-keyid
+                        \ try-all-secrets use-agent use-embedded-filename
+                        \ utf8-strings verbose with-colons with-fingerprint
+                        \ with-key-data yes
+
+syn match   gpgArg      contained display '\S\+\(\s\+\S\+\)*' contains=gpgID
+syn match   gpgArgError contained display '\S\+\(\s\+\S\+\)*'
+
+hi def link gpgComment  Comment
+hi def link gpgTodo     Todo
+hi def link gpgID       Number
+hi def link gpgOption   Keyword
+hi def link gpgCommand  Error
+hi def link gpgArgError Error
+
+let b:current_syntax = "gpg"
+
+let &cpo = s:cpo_save
+unlet s:cpo_save
--- /dev/null
+++ b/lib/vimfiles/syntax/grads.vim
@@ -1,0 +1,86 @@
+" Vim syntax file
+" Language:	grads (GrADS scripts)
+" Maintainer:	Stefan Fronzek (sfronzek at gmx dot net)
+" Last change: 13 Feb 2004
+
+" Grid Analysis and Display System (GrADS); http://grads.iges.org/grads
+" This syntax file defines highlighting for only very few features of
+" the GrADS scripting language.
+
+" For version 5.x: Clear all syntax items
+" For version 6.x: Quit when a syntax file was already loaded
+if version < 600
+  syntax clear
+elseif exists("b:current_syntax")
+  finish
+endif
+
+" GrADS is entirely case-insensitive.
+syn case ignore
+
+" The keywords
+
+syn keyword gradsStatement	if else endif break exit return
+syn keyword gradsStatement	while endwhile say prompt pull function
+syn keyword gradsStatement subwrd sublin substr read write close
+" String
+
+syn region gradsString		start=+'+ end=+'+
+
+" Integer number
+syn match  gradsNumber		"[+-]\=\<[0-9]\+\>"
+
+" Operator
+
+"syn keyword gradsOperator	| ! % & != >=
+"syn match gradsOperator		"[^\.]not[^a-zA-Z]"
+
+" Variables
+
+syn keyword gradsFixVariables	lat lon lev result rec rc
+syn match gradsglobalVariables	"_[a-zA-Z][a-zA-Z0-9]*"
+syn match gradsVariables		"[a-zA-Z][a-zA-Z0-9]*"
+syn match gradsConst		"#[A-Z][A-Z_]+"
+
+" Comments
+
+syn match gradsComment	"\*.*"
+
+" Typical Typos
+
+" for C programmers:
+" syn match gradsTypos	"=="
+" syn match gradsTypos	"!="
+
+" Define the default highlighting.
+" For version 5.7 and earlier: only when not done already
+" For version 5.8 and later: only when an item doesn't hgs highlighting+yet
+if version >= 508 || !exists("did_gs_syn_inits")
+  if version < 508
+	let did_gs_syn_inits = 1
+	command -nargs=+ HiLink hi link <args>
+  else
+	command -nargs=+ HiLink hi def link <args>
+  endif
+
+  HiLink gradsStatement		Statement
+
+  HiLink gradsString		String
+  HiLink gradsNumber		Number
+
+  HiLink gradsFixVariables	Special
+  HiLink gradsVariables		Identifier
+  HiLink gradsglobalVariables	Special
+  HiLink gradsConst		Special
+
+  HiLink gradsClassMethods	Function
+
+  HiLink gradsOperator		Operator
+  HiLink gradsComment		Comment
+
+  HiLink gradsTypos		Error
+
+  delcommand HiLink
+endif
+
+let b:current_syntax = "grads"
--- /dev/null
+++ b/lib/vimfiles/syntax/gretl.vim
@@ -1,0 +1,102 @@
+" Vim syntax file
+" Language:	gretl (http://gretl.sf.net)
+" Maintainer:	Vaidotas Zemlys <zemlys@gmail.com>
+" Last Change:  2006 Apr 30
+" Filenames:	*.inp *.gretl
+" URL:	http://uosis.mif.vu.lt/~zemlys/vim-syntax/gretl.vim
+" For version 5.x: Clear all syntax items
+" For version 6.x: Quit when a syntax file was already loaded
+
+if version < 600
+  syntax clear
+elseif exists("b:current_syntax")
+  finish
+endif
+
+if version >= 600
+  setlocal iskeyword=@,48-57,_,.
+else
+  set iskeyword=@,48-57,_,.
+endif
+
+syn case match
+
+" Constant
+" string enclosed in double quotes
+syn region gString start=/"/ skip=/\\\\\|\\"/ end=/"/
+" number with no fractional part or exponent
+syn match gNumber /\d\+/
+" floating point number with integer and fractional parts and optional exponent
+syn match gFloat /\d\+\.\d*\([Ee][-+]\=\d\+\)\=/
+" floating point number with no integer part and optional exponent
+syn match gFloat /\.\d\+\([Ee][-+]\=\d\+\)\=/
+" floating point number with no fractional part and optional exponent
+syn match gFloat /\d\+[Ee][-+]\=\d\+/
+
+" Gretl commands
+syn keyword gCommands add addobs addto adf append ar arch arma break boxplot chow coeffsum coint coint2 corc corr corrgm criteria critical cusum data delete diff else end endif endloop eqnprint equation estimate fcast fcasterr fit freq function funcerr garch genr gnuplot graph hausman hccm help hilu hsk hurst if import include info kpss label labels lad lags ldiff leverage lmtest logistic logit logs loop mahal meantest mle modeltab mpols multiply nls nulldata ols omit omitfrom open outfile panel pca pergm plot poisson pooled print printf probit pvalue pwe quit remember rename reset restrict rhodiff rmplot run runs scatters sdiff set setobs setmiss shell sim smpl spearman square store summary system tabprint testuhat tobit transpos tsls var varlist vartest vecm vif wls 
+
+"Gretl genr functions
+syn keyword gGenrFunc log exp sin cos tan atan diff ldiff sdiff mean sd min max sort int ln coeff abs rho sqrt sum nobs firstobs lastobs normal uniform stderr cum missing ok misszero corr vcv var sst cov median zeromiss pvalue critical obsnum mpow dnorm cnorm gamma lngamma resample hpfilt bkfilt fracdiff varnum isvector islist nelem 
+
+" Identifier
+" identifier with leading letter and optional following keyword characters
+syn match gIdentifier /\a\k*/
+
+"  Variable with leading $
+syn match gVariable /\$\k*/
+" Arrow
+syn match gArrow /<-/
+
+" Special
+syn match gDelimiter /[,;:]/
+
+" Error
+syn region gRegion matchgroup=Delimiter start=/(/ matchgroup=Delimiter end=/)/ transparent contains=ALLBUT,rError,rBraceError,rCurlyError,gBCstart,gBCend
+syn region gRegion matchgroup=Delimiter start=/{/ matchgroup=Delimiter end=/}/ transparent contains=ALLBUT,rError,rBraceError,rParenError
+syn region gRegion matchgroup=Delimiter start=/\[/ matchgroup=Delimiter end=/]/ transparent contains=ALLBUT,rError,rCurlyError,rParenError
+syn match gError      /[)\]}]/
+syn match gBraceError /[)}]/ contained
+syn match gCurlyError /[)\]]/ contained
+syn match gParenError /[\]}]/ contained
+
+" Comment
+syn match gComment /#.*/
+syn match gBCstart /(\*/
+syn match gBCend /\*)/
+
+syn region gBlockComment matchgroup=gCommentStart start="(\*" end="\*)"
+
+" Define the default highlighting.
+" For version 5.7 and earlier: only when not done already
+" For version 5.8 and later: only when an item doesn't have highlighting yet
+if version >= 508 || !exists("did_r_syn_inits")
+  if version < 508
+    let did_r_syn_inits = 1
+    command -nargs=+ HiLink hi link <args>
+  else
+    command -nargs=+ HiLink hi def link <args>
+  endif
+  HiLink gComment      Comment
+  HiLink gCommentStart Comment
+  HiLink gBlockComment Comment
+  HiLink gString       String
+  HiLink gNumber       Number
+  HiLink gBoolean      Boolean
+  HiLink gFloat        Float
+  HiLink gCommands     Repeat	
+  HiLink gGenrFunc     Type
+  HiLink gDelimiter    Delimiter
+  HiLink gError        Error
+  HiLink gBraceError   Error
+  HiLink gCurlyError   Error
+  HiLink gParenError   Error
+  HiLink gIdentifier   Normal
+  HiLink gVariable     Identifier
+  HiLink gArrow	       Repeat
+  delcommand HiLink
+endif
+
+let b:current_syntax="gretl"
+
+" vim: ts=8 sw=2
--- /dev/null
+++ b/lib/vimfiles/syntax/groff.vim
@@ -1,0 +1,10 @@
+" VIM syntax file
+" Language:	groff
+" Maintainer:	Alejandro L�pez-Valencia <dradul@yahoo.com>
+" URL:		http://dradul.tripod.com/vim
+" Last Change:	2003-05-08-12:41:13 GMT-5.
+
+" This uses the nroff.vim syntax file.
+let b:main_syntax = "nroff"
+let b:nroff_is_groff = 1
+runtime! syntax/nroff.vim
--- /dev/null
+++ b/lib/vimfiles/syntax/groovy.vim
@@ -1,0 +1,450 @@
+" Vim syntax file
+" Language:	Groovy
+" Maintainer:	Alessio Pace <billy.corgan@tiscali.it>
+" Version: 	0.1.9b
+" URL:	  http://www.vim.org/scripts/script.php?script_id=945	
+" Last Change:	6/4/2004
+
+" This is my very first vim script, I hope to have
+" done it the right way.
+" 
+" I must directly or indirectly thank the author of java.vim and ruby.vim:
+" I copied from them most of the stuff :-)
+"
+" Relies on html.vim
+
+" For version 5.x: Clear all syntax items
+" For version 6.x: Quit when a syntax file was already loaded
+"
+" HOWTO USE IT (INSTALL):
+" [groovy is still not recognized by vim! :-( ]
+"
+" 1) copy the file in the (global or user's $HOME/.vim/syntax/) syntax folder
+" 
+" 2) add this line to recognize groovy files by filename extension:
+"
+" au BufNewFile,BufRead *.groovy  setf groovy
+" in the global vim filetype.vim file or inside $HOME/.vim/filetype.vim
+"
+" 3) add this part to recognize by content groovy script (no extension needed :-)
+"
+"  if did_filetype()
+"    finish
+"  endif
+"  if getline(1) =~ '^#!.*[/\\]groovy\>'
+"    setf groovy
+"  endif
+"
+"  in the global scripts.vim file or in $HOME/.vim/scripts.vim
+" 
+" 4) open/write a .groovy file or a groovy script :-)
+"
+" Let me know if you like it or send me patches, so that I can improve it
+" when I have time
+
+" Quit when a syntax file was already loaded
+if !exists("main_syntax")
+  if version < 600
+    syntax clear
+  elseif exists("b:current_syntax")
+    finish
+  endif
+  " we define it here so that included files can test for it
+  let main_syntax='groovy'
+endif
+
+" don't use standard HiLink, it will not work with included syntax files
+if version < 508
+  command! -nargs=+ GroovyHiLink hi link <args>
+else
+  command! -nargs=+ GroovyHiLink hi def link <args>
+endif
+
+" ##########################
+" Java stuff taken from java.vim
+" some characters that cannot be in a groovy program (outside a string)
+" syn match groovyError "[\\@`]"
+"syn match groovyError "<<<\|\.\.\|=>\|<>\|||=\|&&=\|[^-]->\|\*\/"
+"syn match groovyOK "\.\.\."
+
+" keyword definitions
+syn keyword groovyExternal        native package
+syn match groovyExternal          "\<import\(\s\+static\>\)\?"
+syn keyword groovyError           goto const
+syn keyword groovyConditional     if else switch
+syn keyword groovyRepeat          while for do
+syn keyword groovyBoolean         true false
+syn keyword groovyConstant        null
+syn keyword groovyTypedef         this super
+syn keyword groovyOperator        new instanceof
+syn keyword groovyType            boolean char byte short int long float double
+syn keyword groovyType            void
+syn keyword groovyType		  Integer Double Date Boolean Float String Array Vector List
+syn keyword groovyStatement       return
+syn keyword groovyStorageClass    static synchronized transient volatile final strictfp serializable
+syn keyword groovyExceptions      throw try catch finally
+syn keyword groovyAssert          assert
+syn keyword groovyMethodDecl      synchronized throws
+syn keyword groovyClassDecl       extends implements interface
+" to differentiate the keyword class from MyClass.class we use a match here
+syn match   groovyTypedef         "\.\s*\<class\>"ms=s+1
+syn keyword groovyClassDecl         enum
+syn match   groovyClassDecl       "^class\>"
+syn match   groovyClassDecl       "[^.]\s*\<class\>"ms=s+1
+syn keyword groovyBranch          break continue nextgroup=groovyUserLabelRef skipwhite
+syn match   groovyUserLabelRef    "\k\+" contained
+syn keyword groovyScopeDecl       public protected private abstract
+
+
+if exists("groovy_highlight_groovy_lang_ids") || exists("groovy_highlight_groovy_lang") || exists("groovy_highlight_all")
+  " groovy.lang.*
+  syn keyword groovyLangClass  Closure MetaMethod GroovyObject
+  
+  syn match groovyJavaLangClass "\<System\>"
+  syn keyword groovyJavaLangClass  Cloneable Comparable Runnable Serializable Boolean Byte Class Object
+  syn keyword groovyJavaLangClass  Character CharSequence ClassLoader Compiler
+  " syn keyword groovyJavaLangClass  Integer Double Float Long 
+  syn keyword groovyJavaLangClass  InheritableThreadLocal Math Number Object Package Process
+  syn keyword groovyJavaLangClass  Runtime RuntimePermission InheritableThreadLocal
+  syn keyword groovyJavaLangClass  SecurityManager Short StrictMath StackTraceElement
+  syn keyword groovyJavaLangClass  StringBuffer Thread ThreadGroup
+  syn keyword groovyJavaLangClass  ThreadLocal Throwable Void ArithmeticException
+  syn keyword groovyJavaLangClass  ArrayIndexOutOfBoundsException AssertionError
+  syn keyword groovyJavaLangClass  ArrayStoreException ClassCastException
+  syn keyword groovyJavaLangClass  ClassNotFoundException
+  syn keyword groovyJavaLangClass  CloneNotSupportedException Exception
+  syn keyword groovyJavaLangClass  IllegalAccessException
+  syn keyword groovyJavaLangClass  IllegalArgumentException
+  syn keyword groovyJavaLangClass  IllegalMonitorStateException
+  syn keyword groovyJavaLangClass  IllegalStateException
+  syn keyword groovyJavaLangClass  IllegalThreadStateException
+  syn keyword groovyJavaLangClass  IndexOutOfBoundsException
+  syn keyword groovyJavaLangClass  InstantiationException InterruptedException
+  syn keyword groovyJavaLangClass  NegativeArraySizeException NoSuchFieldException
+  syn keyword groovyJavaLangClass  NoSuchMethodException NullPointerException
+  syn keyword groovyJavaLangClass  NumberFormatException RuntimeException
+  syn keyword groovyJavaLangClass  SecurityException StringIndexOutOfBoundsException
+  syn keyword groovyJavaLangClass  UnsupportedOperationException
+  syn keyword groovyJavaLangClass  AbstractMethodError ClassCircularityError
+  syn keyword groovyJavaLangClass  ClassFormatError Error ExceptionInInitializerError
+  syn keyword groovyJavaLangClass  IllegalAccessError InstantiationError
+  syn keyword groovyJavaLangClass  IncompatibleClassChangeError InternalError
+  syn keyword groovyJavaLangClass  LinkageError NoClassDefFoundError
+  syn keyword groovyJavaLangClass  NoSuchFieldError NoSuchMethodError
+  syn keyword groovyJavaLangClass  OutOfMemoryError StackOverflowError
+  syn keyword groovyJavaLangClass  ThreadDeath UnknownError UnsatisfiedLinkError
+  syn keyword groovyJavaLangClass  UnsupportedClassVersionError VerifyError
+  syn keyword groovyJavaLangClass  VirtualMachineError
+
+  syn keyword groovyJavaLangObject clone equals finalize getClass hashCode
+  syn keyword groovyJavaLangObject notify notifyAll toString wait
+
+  GroovyHiLink groovyLangClass                   groovyConstant
+  GroovyHiLink groovyJavaLangClass               groovyExternal
+  GroovyHiLink groovyJavaLangObject              groovyConstant
+  syn cluster groovyTop add=groovyJavaLangObject,groovyJavaLangClass,groovyLangClass
+  syn cluster groovyClasses add=groovyJavaLangClass,groovyLangClass
+endif
+
+
+" Groovy stuff
+syn match groovyOperator "\.\."
+syn match groovyOperator "<\{2,3}"
+syn match groovyOperator ">\{2,3}"
+syn match groovyOperator "->"
+syn match groovyExternal		'^#!.*[/\\]groovy\>'
+syn match groovyExceptions        "\<Exception\>\|\<[A-Z]\{1,}[a-zA-Z0-9]*Exception\>"
+
+" Groovy JDK stuff
+syn keyword groovyJDKBuiltin    as def in
+syn keyword groovyJDKOperOverl  div minus plus abs round power multiply 
+syn keyword groovyJDKMethods 	each call inject sort print println 
+syn keyword groovyJDKMethods    getAt putAt size push pop toList getText writeLine eachLine readLines
+syn keyword groovyJDKMethods    withReader withStream withWriter withPrintWriter write read leftShift 
+syn keyword groovyJDKMethods    withWriterAppend readBytes splitEachLine
+syn keyword groovyJDKMethods    newInputStream newOutputStream newPrintWriter newReader newWriter 
+syn keyword groovyJDKMethods    compareTo next previous isCase 
+syn keyword groovyJDKMethods    times step toInteger upto any collect dump every find findAll grep
+syn keyword groovyJDKMethods    inspect invokeMethods join 
+syn keyword groovyJDKMethods    getErr getIn getOut waitForOrKill
+syn keyword groovyJDKMethods    count tokenize asList flatten immutable intersect reverse reverseEach
+syn keyword groovyJDKMethods    subMap append asWritable eachByte eachLine eachFile 
+syn cluster groovyTop add=groovyJDKBuiltin,groovyJDKOperOverl,groovyJDKMethods
+
+" no useful I think, so I comment it..
+"if filereadable(expand("<sfile>:p:h")."/groovyid.vim")
+ " source <sfile>:p:h/groovyid.vim
+"endif
+
+if exists("groovy_space_errors")
+  if !exists("groovy_no_trail_space_error")
+    syn match   groovySpaceError  "\s\+$"
+  endif
+  if !exists("groovy_no_tab_space_error")
+    syn match   groovySpaceError  " \+\t"me=e-1
+  endif
+endif
+
+" it is a better case construct than java.vim to match groovy syntax
+syn region  groovyLabelRegion     transparent matchgroup=groovyLabel start="\<case\>" matchgroup=NONE end=":\|$" contains=groovyNumber,groovyString,groovyLangClass,groovyJavaLangClass
+syn match   groovyUserLabel       "^\s*[_$a-zA-Z][_$a-zA-Z0-9_]*\s*:"he=e-1 contains=groovyLabel
+syn keyword groovyLabel           default
+
+if !exists("groovy_allow_cpp_keywords")
+  syn keyword groovyError auto delete extern friend inline redeclared
+  syn keyword groovyError register signed sizeof struct template typedef union
+  syn keyword groovyError unsigned operator
+endif
+
+" The following cluster contains all groovy groups except the contained ones
+syn cluster groovyTop add=groovyExternal,groovyError,groovyError,groovyBranch,groovyLabelRegion,groovyLabel,groovyConditional,groovyRepeat,groovyBoolean,groovyConstant,groovyTypedef,groovyOperator,groovyType,groovyType,groovyStatement,groovyStorageClass,groovyAssert,groovyExceptions,groovyMethodDecl,groovyClassDecl,groovyClassDecl,groovyClassDecl,groovyScopeDecl,groovyError,groovyError2,groovyUserLabel,groovyLangObject
+
+
+" Comments
+syn keyword groovyTodo             contained TODO FIXME XXX
+if exists("groovy_comment_strings")
+  syn region  groovyCommentString    contained start=+"+ end=+"+ end=+$+ end=+\*/+me=s-1,he=s-1 contains=groovySpecial,groovyCommentStar,groovySpecialChar,@Spell
+  syn region  groovyComment2String   contained start=+"+  end=+$\|"+  contains=groovySpecial,groovySpecialChar,@Spell
+  syn match   groovyCommentCharacter contained "'\\[^']\{1,6\}'" contains=groovySpecialChar
+  syn match   groovyCommentCharacter contained "'\\''" contains=groovySpecialChar
+  syn match   groovyCommentCharacter contained "'[^\\]'"
+  syn cluster groovyCommentSpecial add=groovyCommentString,groovyCommentCharacter,groovyNumber
+  syn cluster groovyCommentSpecial2 add=groovyComment2String,groovyCommentCharacter,groovyNumber
+endif
+syn region  groovyComment          start="/\*"  end="\*/" contains=@groovyCommentSpecial,groovyTodo,@Spell
+syn match   groovyCommentStar      contained "^\s*\*[^/]"me=e-1
+syn match   groovyCommentStar      contained "^\s*\*$"
+syn match   groovyLineComment      "//.*" contains=@groovyCommentSpecial2,groovyTodo,@Spell
+syn match   groovyLineComment      "#.*" contains=@groovyCommentSpecial2,groovyTodo,@Spell
+GroovyHiLink groovyCommentString groovyString
+GroovyHiLink groovyComment2String groovyString
+GroovyHiLink groovyCommentCharacter groovyCharacter
+
+syn cluster groovyTop add=groovyComment,groovyLineComment
+
+if !exists("groovy_ignore_groovydoc") && main_syntax != 'jsp'
+  syntax case ignore
+  " syntax coloring for groovydoc comments (HTML)
+  " syntax include @groovyHtml <sfile>:p:h/html.vim
+   syntax include @groovyHtml runtime! syntax/html.vim
+  unlet b:current_syntax
+  syn region  groovyDocComment    start="/\*\*"  end="\*/" keepend contains=groovyCommentTitle,@groovyHtml,groovyDocTags,groovyTodo,@Spell
+  syn region  groovyCommentTitle  contained matchgroup=groovyDocComment start="/\*\*"   matchgroup=groovyCommentTitle keepend end="\.$" end="\.[ \t\r<&]"me=e-1 end="[^{]@"me=s-2,he=s-1 end="\*/"me=s-1,he=s-1 contains=@groovyHtml,groovyCommentStar,groovyTodo,@Spell,groovyDocTags
+
+  syn region groovyDocTags  contained start="{@\(link\|linkplain\|inherit[Dd]oc\|doc[rR]oot\|value\)" end="}"
+  syn match  groovyDocTags  contained "@\(see\|param\|exception\|throws\|since\)\s\+\S\+" contains=groovyDocParam
+  syn match  groovyDocParam contained "\s\S\+"
+  syn match  groovyDocTags  contained "@\(version\|author\|return\|deprecated\|serial\|serialField\|serialData\)\>"
+  syntax case match
+endif
+
+" match the special comment /**/
+syn match   groovyComment          "/\*\*/"
+
+" Strings and constants
+syn match   groovySpecialError     contained "\\."
+syn match   groovySpecialCharError contained "[^']"
+syn match   groovySpecialChar      contained "\\\([4-9]\d\|[0-3]\d\d\|[\"\\'ntbrf]\|u\x\{4\}\)"
+syn region  groovyString          start=+"+ end=+"+ end=+$+ contains=groovySpecialChar,groovySpecialError,@Spell,groovyELExpr
+syn region  groovyString          start=+'+ end=+'+ end=+$+ contains=groovySpecialChar,groovySpecialError,@Spell,groovyELExpr
+" syn region groovyELExpr start=+${+ end=+}+ keepend contained
+ syn match groovyELExpr /\${.\{-}}/ contained
+GroovyHiLink groovyELExpr Identifier
+
+" TODO: better matching. I am waiting to understand how it really works in groovy
+" syn region  groovyClosureParamsBraces          start=+|+ end=+|+ contains=groovyClosureParams
+" syn match groovyClosureParams	"[ a-zA-Z0-9_*]\+" contained
+" GroovyHiLink groovyClosureParams Identifier
+
+" next line disabled, it can cause a crash for a long line
+"syn match   groovyStringError      +"\([^"\\]\|\\.\)*$+
+
+" disabled: in groovy strings or characters are written the same
+" syn match   groovyCharacter        "'[^']*'" contains=groovySpecialChar,groovySpecialCharError
+" syn match   groovyCharacter        "'\\''" contains=groovySpecialChar
+" syn match   groovyCharacter        "'[^\\]'"
+syn match   groovyNumber           "\<\(0[0-7]*\|0[xX]\x\+\|\d\+\)[lL]\=\>"
+syn match   groovyNumber           "\(\<\d\+\.\d*\|\.\d\+\)\([eE][-+]\=\d\+\)\=[fFdD]\="
+syn match   groovyNumber           "\<\d\+[eE][-+]\=\d\+[fFdD]\=\>"
+syn match   groovyNumber           "\<\d\+\([eE][-+]\=\d\+\)\=[fFdD]\>"
+
+" unicode characters
+syn match   groovySpecial "\\u\d\{4\}"
+
+syn cluster groovyTop add=groovyString,groovyCharacter,groovyNumber,groovySpecial,groovyStringError
+
+if exists("groovy_highlight_functions")
+  if groovy_highlight_functions == "indent"
+    syn match  groovyFuncDef "^\(\t\| \{8\}\)[_$a-zA-Z][_$a-zA-Z0-9_. \[\]]*([^-+*/()]*)" contains=groovyScopeDecl,groovyType,groovyStorageClass,@groovyClasses
+    syn region groovyFuncDef start=+^\(\t\| \{8\}\)[$_a-zA-Z][$_a-zA-Z0-9_. \[\]]*([^-+*/()]*,\s*+ end=+)+ contains=groovyScopeDecl,groovyType,groovyStorageClass,@groovyClasses
+    syn match  groovyFuncDef "^  [$_a-zA-Z][$_a-zA-Z0-9_. \[\]]*([^-+*/()]*)" contains=groovyScopeDecl,groovyType,groovyStorageClass,@groovyClasses
+    syn region groovyFuncDef start=+^  [$_a-zA-Z][$_a-zA-Z0-9_. \[\]]*([^-+*/()]*,\s*+ end=+)+ contains=groovyScopeDecl,groovyType,groovyStorageClass,@groovyClasses
+  else
+    " This line catches method declarations at any indentation>0, but it assumes
+    " two things:
+    "   1. class names are always capitalized (ie: Button)
+    "   2. method names are never capitalized (except constructors, of course)
+    syn region groovyFuncDef start=+^\s\+\(\(public\|protected\|private\|static\|abstract\|final\|native\|synchronized\)\s\+\)*\(\(void\|boolean\|char\|byte\|short\|int\|long\|float\|double\|\([A-Za-z_][A-Za-z0-9_$]*\.\)*[A-Z][A-Za-z0-9_$]*\)\(<[^>]*>\)\=\(\[\]\)*\s\+[a-z][A-Za-z0-9_$]*\|[A-Z][A-Za-z0-9_$]*\)\s*([^0-9]+ end=+)+ contains=groovyScopeDecl,groovyType,groovyStorageClass,groovyComment,groovyLineComment,@groovyClasses
+  endif
+  syn match  groovyBraces  "[{}]"
+  syn cluster groovyTop add=groovyFuncDef,groovyBraces
+endif
+
+if exists("groovy_highlight_debug")
+
+  " Strings and constants
+  syn match   groovyDebugSpecial          contained "\\\d\d\d\|\\."
+  syn region  groovyDebugString           contained start=+"+  end=+"+  contains=groovyDebugSpecial
+  syn match   groovyDebugStringError      +"\([^"\\]\|\\.\)*$+
+  syn match   groovyDebugCharacter        contained "'[^\\]'"
+  syn match   groovyDebugSpecialCharacter contained "'\\.'"
+  syn match   groovyDebugSpecialCharacter contained "'\\''"
+  syn match   groovyDebugNumber           contained "\<\(0[0-7]*\|0[xX]\x\+\|\d\+\)[lL]\=\>"
+  syn match   groovyDebugNumber           contained "\(\<\d\+\.\d*\|\.\d\+\)\([eE][-+]\=\d\+\)\=[fFdD]\="
+  syn match   groovyDebugNumber           contained "\<\d\+[eE][-+]\=\d\+[fFdD]\=\>"
+  syn match   groovyDebugNumber           contained "\<\d\+\([eE][-+]\=\d\+\)\=[fFdD]\>"
+  syn keyword groovyDebugBoolean          contained true false
+  syn keyword groovyDebugType             contained null this super
+  syn region groovyDebugParen  start=+(+ end=+)+ contained contains=groovyDebug.*,groovyDebugParen
+
+  " to make this work you must define the highlighting for these groups
+  syn match groovyDebug "\<System\.\(out\|err\)\.print\(ln\)*\s*("me=e-1 contains=groovyDebug.* nextgroup=groovyDebugParen
+  syn match groovyDebug "\<p\s*("me=e-1 contains=groovyDebug.* nextgroup=groovyDebugParen
+  syn match groovyDebug "[A-Za-z][a-zA-Z0-9_]*\.printStackTrace\s*("me=e-1 contains=groovyDebug.* nextgroup=groovyDebugParen
+  syn match groovyDebug "\<trace[SL]\=\s*("me=e-1 contains=groovyDebug.* nextgroup=groovyDebugParen
+
+  syn cluster groovyTop add=groovyDebug
+
+  if version >= 508 || !exists("did_c_syn_inits")
+    GroovyHiLink groovyDebug                 Debug
+    GroovyHiLink groovyDebugString           DebugString
+    GroovyHiLink groovyDebugStringError      groovyError
+    GroovyHiLink groovyDebugType             DebugType
+    GroovyHiLink groovyDebugBoolean          DebugBoolean
+    GroovyHiLink groovyDebugNumber           Debug
+    GroovyHiLink groovyDebugSpecial          DebugSpecial
+    GroovyHiLink groovyDebugSpecialCharacter DebugSpecial
+    GroovyHiLink groovyDebugCharacter        DebugString
+    GroovyHiLink groovyDebugParen            Debug
+  
+    GroovyHiLink DebugString               String
+    GroovyHiLink DebugSpecial              Special
+    GroovyHiLink DebugBoolean              Boolean
+    GroovyHiLink DebugType                 Type
+  endif
+endif
+
+" Match all Exception classes 
+syn match groovyExceptions        "\<Exception\>\|\<[A-Z]\{1,}[a-zA-Z0-9]*Exception\>"
+
+
+if !exists("groovy_minlines")
+  let groovy_minlines = 10
+endif
+exec "syn sync ccomment groovyComment minlines=" . groovy_minlines
+
+
+" ################### 
+" Groovy stuff
+" syn match groovyOperator		"|[ ,a-zA-Z0-9_*]\+|"
+
+" All groovy valid tokens
+" syn match groovyTokens ";\|,\|<=>\|<>\|:\|:=\|>\|>=\|=\|==\|<\|<=\|!=\|/\|/=\|\.\.|\.\.\.\|\~=\|\~=="
+" syn match groovyTokens "\*=\|&\|&=\|\*\|->\|\~\|+\|-\|/\|?\|<<<\|>>>\|<<\|>>"
+
+" Must put explicit these ones because groovy.vim mark them as errors otherwise
+" syn match groovyTokens "<=>\|<>\|==\~"
+"syn cluster groovyTop add=groovyTokens
+
+" Mark these as operators
+
+" Hightlight brackets
+" syn match  groovyBraces		"[{}]"
+" syn match  groovyBraces		"[\[\]]"
+" syn match  groovyBraces		"[\|]"
+
+if exists("groovy_mark_braces_in_parens_as_errors")
+  syn match groovyInParen          contained "[{}]"
+  GroovyHiLink groovyInParen        groovyError
+  syn cluster groovyTop add=groovyInParen
+endif
+
+" catch errors caused by wrong parenthesis
+syn region  groovyParenT  transparent matchgroup=groovyParen  start="("  end=")" contains=@groovyTop,groovyParenT1
+syn region  groovyParenT1 transparent matchgroup=groovyParen1 start="(" end=")" contains=@groovyTop,groovyParenT2 contained
+syn region  groovyParenT2 transparent matchgroup=groovyParen2 start="(" end=")" contains=@groovyTop,groovyParenT  contained
+syn match   groovyParenError       ")"
+GroovyHiLink groovyParenError       groovyError
+
+" catch errors caused by wrong square parenthesis
+syn region  groovyParenT  transparent matchgroup=groovyParen  start="\["  end="\]" contains=@groovyTop,groovyParenT1
+syn region  groovyParenT1 transparent matchgroup=groovyParen1 start="\[" end="\]" contains=@groovyTop,groovyParenT2 contained
+syn region  groovyParenT2 transparent matchgroup=groovyParen2 start="\[" end="\]" contains=@groovyTop,groovyParenT  contained
+syn match   groovyParenError       "\]"
+
+" ###############################
+" java.vim default highlighting
+if version >= 508 || !exists("did_groovy_syn_inits")
+  if version < 508
+    let did_groovy_syn_inits = 1
+  endif
+  GroovyHiLink groovyFuncDef		Function
+  GroovyHiLink groovyBraces		Function
+  GroovyHiLink groovyBranch		Conditional
+  GroovyHiLink groovyUserLabelRef	groovyUserLabel
+  GroovyHiLink groovyLabel		Label
+  GroovyHiLink groovyUserLabel		Label
+  GroovyHiLink groovyConditional	Conditional
+  GroovyHiLink groovyRepeat		Repeat
+  GroovyHiLink groovyExceptions		Exception
+  GroovyHiLink groovyAssert 		Statement
+  GroovyHiLink groovyStorageClass	StorageClass
+  GroovyHiLink groovyMethodDecl		groovyStorageClass
+  GroovyHiLink groovyClassDecl		groovyStorageClass
+  GroovyHiLink groovyScopeDecl		groovyStorageClass
+  GroovyHiLink groovyBoolean		Boolean
+  GroovyHiLink groovySpecial		Special
+  GroovyHiLink groovySpecialError	Error
+  GroovyHiLink groovySpecialCharError	Error
+  GroovyHiLink groovyString		String
+  GroovyHiLink groovyCharacter		Character
+  GroovyHiLink groovySpecialChar	SpecialChar
+  GroovyHiLink groovyNumber		Number
+  GroovyHiLink groovyError		Error
+  GroovyHiLink groovyStringError	Error
+  GroovyHiLink groovyStatement		Statement
+  GroovyHiLink groovyOperator		Operator
+  GroovyHiLink groovyComment		Comment
+  GroovyHiLink groovyDocComment		Comment
+  GroovyHiLink groovyLineComment	Comment
+  GroovyHiLink groovyConstant		Constant
+  GroovyHiLink groovyTypedef		Typedef
+  GroovyHiLink groovyTodo		Todo
+  
+  GroovyHiLink groovyCommentTitle	SpecialComment
+  GroovyHiLink groovyDocTags		Special
+  GroovyHiLink groovyDocParam		Function
+  GroovyHiLink groovyCommentStar	groovyComment
+  
+  GroovyHiLink groovyType		Type
+  GroovyHiLink groovyExternal		Include
+  
+  GroovyHiLink htmlComment		Special
+  GroovyHiLink htmlCommentPart		Special
+  GroovyHiLink groovySpaceError		Error
+  GroovyHiLink groovyJDKBuiltin         Special
+  GroovyHiLink groovyJDKOperOverl       Operator
+  GroovyHiLink groovyJDKMethods         Function
+endif
+
+delcommand GroovyHiLink
+
+
+let b:current_syntax = "groovy"
+if main_syntax == 'groovy'
+  unlet main_syntax
+endif
+
+let b:spell_options="contained"
+
+" vim: ts=8
--- /dev/null
+++ b/lib/vimfiles/syntax/group.vim
@@ -1,0 +1,52 @@
+" Vim syntax file
+" Language:         group(5) user group file
+" Maintainer:       Nikolai Weibull <now@bitwi.se>
+" Latest Revision:  2006-04-19
+
+if exists("b:current_syntax")
+  finish
+endif
+
+let s:cpo_save = &cpo
+set cpo&vim
+
+syn match   groupBegin          display '^' nextgroup=groupName
+
+syn match   groupName           contained display '[a-z_][a-z0-9_-]\{0,15}'
+                                \ nextgroup=groupPasswordColon
+
+syn match   groupPasswordColon  contained display ':'
+                                \ nextgroup=groupPassword,groupShadow
+
+syn match   groupPassword       contained display '[^:]*'
+                                \ nextgroup=groupGIDColon
+
+syn match   groupShadow         contained display '[x*]' nextgroup=groupGIDColon
+
+syn match   groupGIDColon       contained display ':' nextgroup=groupGID
+
+syn match   groupGID            contained display '\d*'
+                                \ nextgroup=groupUserListColon
+
+syn match   groupUserListColon  contained display ':' nextgroup=groupUserList
+
+syn match   groupUserList       contained '[a-z_][a-z0-9_-]*'
+                                \ nextgroup=groupUserListSep
+
+syn match   groupUserListSep    contained display ',' nextgroup=groupUserList
+
+hi def link groupDelimiter      Normal
+hi def link groupName           Identifier
+hi def link groupPasswordColon  groupDelimiter
+hi def link groupPassword       Number
+hi def link groupShadow         Special
+hi def link groupGIDColon       groupDelimiter
+hi def link groupGID            Number
+hi def link groupUserListColon  groupDelimiter
+hi def link groupUserList       Identifier
+hi def link groupUserListSep    groupDelimiter
+
+let b:current_syntax = "group"
+
+let &cpo = s:cpo_save
+unlet s:cpo_save
--- /dev/null
+++ b/lib/vimfiles/syntax/grub.vim
@@ -1,0 +1,93 @@
+" Vim syntax file
+" Language:         grub(8) configuration file
+" Maintainer:       Nikolai Weibull <now@bitwi.se>
+" Latest Revision:  2006-04-19
+
+if exists("b:current_syntax")
+  finish
+endif
+
+let s:cpo_save = &cpo
+set cpo&vim
+
+syn keyword grubTodo          contained TODO FIXME XXX NOTE
+
+syn region  grubComment       display oneline start='^#' end='$'
+                              \ contains=grubTodo,@Spell
+
+syn match   grubDevice        display
+                              \ '(\([fh]d\d\|\d\+\|0x\x\+\)\(,\d\+\)\=\(,\l\)\=)'
+
+syn match   grubBlock         display '\(\d\+\)\=+\d\+\(,\(\d\+\)\=+\d\+\)*'
+
+syn match   grubNumbers       display '+\=\<\d\+\|0x\x\+\>'
+
+syn match   grubBegin         display '^'
+                              \ nextgroup=@grubCommands,grubComment skipwhite
+
+syn cluster grubCommands      contains=grubCommand,grubTitleCommand
+
+syn keyword grubCommand       contained default fallback hiddenmenu timeout
+
+syn keyword grubTitleCommand  contained title nextgroup=grubTitle skipwhite
+
+syn match   grubTitle         contained display '.*'
+
+syn keyword grubCommand       contained bootp color device dhcp hide ifconfig
+                              \ pager partnew parttype password rarp serial setkey
+                              \ terminal tftpserver unhide blocklist boot cat
+                              \ chainloader cmp configfile debug displayapm
+                              \ displaymem embed find fstest geometry halt help
+                              \ impsprobe initrd install ioprobe kernel lock
+                              \ makeactive map md5crypt module modulenounzip pause
+                              \ quit reboot read root rootnoverify savedefault setup
+                              \ testload testvbe uppermem vbeprobe
+
+syn keyword grubSpecial       saved
+
+syn match   grubBlink         display 'blink-'
+syn keyword grubBlack         black
+syn keyword grubBlue          blue
+syn keyword grubGreen         green
+syn keyword grubRed           red
+syn keyword grubMagenta       magenta
+syn keyword grubBrown         brown yellow
+syn keyword grubWhite         white
+syn match   grubLightGray     display 'light-gray'
+syn match   grubLightBlue     display 'light-blue'
+syn match   grubLightGreen    display 'light-green'
+syn match   grubLightCyan     display 'light-cyan'
+syn match   grubLightRed      display 'light-red'
+syn match   grubLightMagenta  display 'light-magenta'
+syn match   grubDarkGray      display 'dark-gray'
+
+hi def link grubComment       Comment
+hi def link grubTodo          Todo
+hi def link grubNumbers       Number
+hi def link grubDevice        Identifier
+hi def link grubBlock         Identifier
+hi def link grubCommand       Keyword
+hi def link grubTitleCommand  grubCommand
+hi def link grubTitle         String
+hi def link grubSpecial       Special
+
+hi def      grubBlink         cterm=inverse
+hi def      grubBlack         ctermfg=Black ctermbg=White guifg=Black guibg=White
+hi def      grubBlue          ctermfg=DarkBlue guifg=DarkBlue
+hi def      grubGreen         ctermfg=DarkGreen guifg=DarkGreen
+hi def      grubRed           ctermfg=DarkRed guifg=DarkRed
+hi def      grubMagenta       ctermfg=DarkMagenta guifg=DarkMagenta
+hi def      grubBrown         ctermfg=Brown guifg=Brown
+hi def      grubWhite         ctermfg=White ctermbg=Black guifg=White guibg=Black
+hi def      grubLightGray     ctermfg=LightGray guifg=LightGray
+hi def      grubLightBlue     ctermfg=LightBlue guifg=LightBlue
+hi def      grubLightGreen    ctermfg=LightGreen guifg=LightGreen
+hi def      grubLightCyan     ctermfg=LightCyan guifg=LightCyan
+hi def      grubLightRed      ctermfg=LightRed guifg=LightRed
+hi def      grubLightMagenta  ctermfg=LightMagenta guifg=LightMagenta
+hi def      grubDarkGray      ctermfg=DarkGray guifg=DarkGray
+
+let b:current_syntax = "grub"
+
+let &cpo = s:cpo_save
+unlet s:cpo_save
--- /dev/null
+++ b/lib/vimfiles/syntax/gsp.vim
@@ -1,0 +1,59 @@
+" Vim syntax file
+" Language:	GSP - GNU Server Pages (v. 0.86)
+" Created By:	Nathaniel Harward nharward@yahoo.com
+" Last Changed: Dec. 12, 2000
+" Filenames:    *.gsp
+" URL:		http://www.constructicon.com/~nharward/vim/syntax/gsp.vim
+
+" For version 5.x: Clear all syntax items
+" For version 6.x: Quit when a syntax file was already loaded
+if version < 600
+  syntax clear
+elseif exists("b:current_syntax")
+  finish
+endif
+
+if !exists("main_syntax")
+  let main_syntax = 'gsp'
+endif
+
+" Source HTML syntax
+if version < 600
+  source <sfile>:p:h/html.vim
+else
+  runtime! syntax/html.vim
+endif
+unlet b:current_syntax
+
+syn case match
+
+" Include Java syntax
+if version < 600
+  syn include @gspJava <sfile>:p:h/java.vim
+else
+  syn include @gspJava syntax/java.vim
+endif
+
+" Add <java> as an HTML tag name along with its args
+syn keyword htmlTagName contained java
+syn keyword htmlArg     contained type file page
+
+" Redefine some HTML things to include (and highlight) gspInLine code in
+" places where it's likely to be found
+syn region htmlString contained start=+"+ end=+"+ contains=htmlSpecialChar,javaScriptExpression,@htmlPreproc,gspInLine
+syn region htmlString contained start=+'+ end=+'+ contains=htmlSpecialChar,javaScriptExpression,@htmlPreproc,gspInLine
+syn match  htmlValue  contained "=[\t ]*[^'" \t>][^ \t>]*"hs=s+1 contains=javaScriptExpression,@htmlPreproc,gspInLine
+syn region htmlEndTag		start=+</+    end=+>+ contains=htmlTagN,htmlTagError,gspInLine
+syn region htmlTag		start=+<[^/]+ end=+>+ contains=htmlTagN,htmlString,htmlArg,htmlValue,htmlTagError,htmlEvent,htmlCssDefinition,@htmlPreproc,@htmlArgCluster,gspInLine
+syn match  htmlTagN   contained +<\s*[-a-zA-Z0-9]\++hs=s+1 contains=htmlTagName,htmlSpecialTagName,@htmlTagNameCluster,gspInLine
+syn match  htmlTagN   contained +</\s*[-a-zA-Z0-9]\++hs=s+2 contains=htmlTagName,htmlSpecialTagName,@htmlTagNameCluster,gspInLine
+
+" Define the GSP java code blocks
+syn region  gspJavaBlock start="<java\>[^>]*\>" end="</java>"me=e-7 contains=@gspJava,htmlTag
+syn region  gspInLine    matchgroup=htmlError start="`" end="`" contains=@gspJava
+
+let b:current_syntax = "gsp"
+
+if main_syntax == 'gsp'
+  unlet main_syntax
+endif
--- /dev/null
+++ b/lib/vimfiles/syntax/gtkrc.vim
@@ -1,0 +1,142 @@
+" Vim syntax file
+" This is a GENERATED FILE. Please always refer to source file at the URI below.
+" Language: Gtk+ theme files `gtkrc'
+" Maintainer: David Ne\v{c}as (Yeti) <yeti@physics.muni.cz>
+" Last Change: 2002-10-31
+" URL: http://trific.ath.cx/Ftp/vim/syntax/gtkrc.vim
+
+" Setup
+if version >= 600
+	if exists("b:current_syntax")
+		finish
+	endif
+else
+	syntax clear
+endif
+
+if version >= 600
+	setlocal iskeyword=_,-,a-z,A-Z,48-57
+else
+	set iskeyword=_,-,a-z,A-Z,48-57
+endif
+
+syn case match
+
+" Base constructs
+syn match gtkrcComment "#.*$" contains=gtkrcFixme
+syn keyword gtkrcFixme FIXME TODO XXX NOT contained
+syn region gtkrcACString start=+"+ skip=+\\\\\|\\"+ end=+"+ oneline contains=gtkrcWPathSpecial,gtkrcClassName,gtkrcClassNameGnome contained
+syn region gtkrcBString start=+"+ skip=+\\\\\|\\"+ end=+"+ oneline contains=gtkrcKeyMod contained
+syn region gtkrcString start=+"+ skip=+\\\\\|\\"+ end=+"+ contains=gtkrcStockName,gtkrcPathSpecial,gtkrcRGBColor
+syn match gtkrcPathSpecial "<parent>" contained
+syn match gtkrcWPathSpecial "[*?.]" contained
+syn match gtkrcNumber "^\(\d\+\)\=\.\=\d\+"
+syn match gtkrcNumber "\W\(\d\+\)\=\.\=\d\+"lc=1
+syn match gtkrcRGBColor "#\(\x\{12}\|\x\{9}\|\x\{6}\|\x\{3}\)" contained
+syn cluster gtkrcPRIVATE add=gtkrcFixme,gtkrcPathSpecial,gtkrcWPathSpecial,gtkrcRGBColor,gtkrcACString
+
+" Keywords
+syn keyword gtkrcInclude include
+syn keyword gtkrcPathSet module_path pixmap_path
+syn keyword gtkrcTop binding style
+syn keyword gtkrcTop widget widget_class nextgroup=gtkrcACString skipwhite
+syn keyword gtkrcTop class nextgroup=gtkrcACString skipwhite
+syn keyword gtkrcBind bind nextgroup=gtkrcBString skipwhite
+syn keyword gtkrcStateName NORMAL INSENSITIVE PRELIGHT ACTIVE SELECTED
+syn keyword gtkrcPriorityName HIGHEST RC APPLICATION GTK LOWEST
+syn keyword gtkrcPriorityName highest rc application gtk lowest
+syn keyword gtkrcTextDirName LTR RTL
+syn keyword gtkrcStyleKeyword fg bg fg_pixmap bg_pixmap bg_text base font font_name fontset stock text
+syn match gtkrcKeyMod "<\(alt\|ctrl\|control\|mod[1-5]\|release\|shft\|shift\)>" contained
+syn cluster gtkrcPRIVATE add=gtkrcKeyMod
+
+" Enums and engine words
+syn keyword gtkrcKeyword engine image
+syn keyword gtkrcImage arrow_direction border detail file gap_border gap_end_border gap_end_file gap_file gap_side gap_side gap_start_border gap_start_file orientation overlay_border overlay_file overlay_stretch recolorable shadow state stretch thickness
+syn keyword gtkrcConstant TRUE FALSE NONE IN OUT LEFT RIGHT TOP BOTTOM UP DOWN VERTICAL HORIZONTAL ETCHED_IN ETCHED_OUT
+syn keyword gtkrcFunction function nextgroup=gtkrcFunctionEq skipwhite
+syn match gtkrcFunctionEq "=" nextgroup=gtkrcFunctionName contained skipwhite
+syn keyword gtkrcFunctionName ARROW BOX BOX_GAP CHECK CROSS DIAMOND EXTENSION FLAT_BOX FOCUS HANDLE HLINE OPTION OVAL POLYGON RAMP SHADOW SHADOW_GAP SLIDER STRING TAB VLINE contained
+syn cluster gtkrcPRIVATE add=gtkrcFunctionName,gtkrcFunctionEq
+
+" Class names
+syn keyword gtkrcClassName GtkAccelLabel GtkAdjustment GtkAlignment GtkArrow GtkAspectFrame GtkBin GtkBox GtkButton GtkButtonBox GtkCList GtkCTree GtkCalendar GtkCheckButton GtkCheckMenuItem GtkColorSelection GtkColorSelectionDialog GtkCombo GtkContainer GtkCurve GtkData GtkDialog GtkDrawingArea GtkEditable GtkEntry GtkEventBox GtkFileSelection GtkFixed GtkFontSelection GtkFontSelectionDialog GtkFrame GtkGammaCurve GtkHBox GtkHButtonBox GtkHPaned GtkHRuler GtkHScale GtkHScrollbar GtkHSeparator GtkHandleBox GtkImage GtkImageMenuItem GtkInputDialog GtkInvisible GtkItem GtkItemFactory GtkLabel GtkLayout GtkList GtkListItem GtkMenu GtkMenuBar GtkMenuItem GtkMenuShell GtkMessageDialog GtkMisc GtkNotebook GtkObject GtkOptionMenu GtkPacker GtkPaned GtkPixmap GtkPlug GtkPreview GtkProgress GtkProgressBar GtkRadioButton GtkRadioMenuItem GtkRange GtkRuler GtkScale GtkScrollbar GtkScrolledWindow GtkSeparatorMenuItem GtkSocket GtkSpinButton GtkStatusbar GtkTable GtkTearoffMenuItem GtkText GtkTextBuffer GtkTextMark GtkTextTag GtkTextView GtkTipsQuery GtkToggleButton GtkToolbar GtkTooltips GtkTree GtkTreeView GtkTreeItem GtkVBox GtkVButtonBox GtkVPaned GtkVRuler GtkVScale GtkVScrollbar GtkVSeparator GtkViewport GtkWidget GtkWindow GtkWindowGroup contained
+syn keyword gtkrcClassName AccelLabel Adjustment Alignment Arrow AspectFrame Bin Box Button ButtonBox CList CTree Calendar CheckButton CheckMenuItem ColorSelection ColorSelectionDialog Combo Container Curve Data Dialog DrawingArea Editable Entry EventBox FileSelection Fixed FontSelection FontSelectionDialog Frame GammaCurve HBox HButtonBox HPaned HRuler HScale HScrollbar HSeparator HandleBox Image ImageMenuItem InputDialog Invisible Item ItemFactory Label Layout List ListItem Menu MenuBar MenuItem MenuShell MessageDialog Misc Notebook Object OptionMenu Packer Paned Pixmap Plug Preview Progress ProgressBar RadioButton RadioMenuItem Range Ruler Scale Scrollbar ScrolledWindow SeparatorMenuItem Socket SpinButton Statusbar Table TearoffMenuItem Text TextBuffer TextMark TextTag TextView TipsQuery ToggleButton Toolbar Tooltips Tree TreeView TreeItem VBox VButtonBox VPaned VRuler VScale VScrollbar VSeparator Viewport Widget Window WindowGroup contained
+syn keyword gtkrcClassNameGnome GnomeAbout GnomeAnimator GnomeApp GnomeAppBar GnomeCalculator GnomeCanvas GnomeCanvasEllipse GnomeCanvasGroup GnomeCanvasImage GnomeCanvasItem GnomeCanvasLine GnomeCanvasPolygon GnomeCanvasRE GnomeCanvasRect GnomeCanvasText GnomeCanvasWidget GnomeClient GnomeColorPicker GnomeDEntryEdit GnomeDateEdit GnomeDialog GnomeDock GnomeDockBand GnomeDockItem GnomeDockLayout GnomeDruid GnomeDruidPage GnomeDruidPageFinish GnomeDruidPageStandard GnomeDruidPageStart GnomeEntry GnomeFileEntry GnomeFontPicker GnomeFontSelector GnomeHRef GnomeIconEntry GnomeIconList GnomeIconSelection GnomeIconTextItem GnomeLess GnomeMDI GnomeMDIChild GnomeMDIGenericChild GnomeMessageBox GnomeNumberEntry GnomePaperSelector GnomePixmap GnomePixmapEntry GnomeProcBar GnomePropertyBox GnomeScores GnomeSpell GnomeStock GtkClock GtkDial GtkPixmapMenuItem GtkTed contained
+syn cluster gtkrcPRIVATE add=gtkrcClassName,gtkrcClassNameGnome
+
+" Stock item names
+syn keyword gtkrcStockName gtk-add gtk-apply gtk-bold gtk-cancel gtk-cdrom gtk-clear gtk-close gtk-convert gtk-copy gtk-cut gtk-delete gtk-dialog-error gtk-dialog-info gtk-dialog-question gtk-dialog-warning gtk-dnd gtk-dnd-multiple gtk-execute gtk-find gtk-find-and-replace gtk-floppy gtk-goto-bottom gtk-goto-first gtk-goto-last gtk-goto-top gtk-go-back gtk-go-down gtk-go-forward gtk-go-up gtk-help gtk-home gtk-index gtk-italic gtk-jump-to gtk-justify-center gtk-justify-fill gtk-justify-left gtk-justify-right gtk-missing-image gtk-new gtk-no gtk-ok gtk-open gtk-paste gtk-preferences gtk-print gtk-print-preview gtk-properties gtk-quit gtk-redo gtk-refresh gtk-remove gtk-revert-to-saved gtk-save gtk-save-as gtk-select-color gtk-select-font gtk-sort-ascending gtk-sort-descending gtk-spell-check gtk-stop gtk-strikethrough gtk-undelete gtk-underline gtk-undo gtk-yes gtk-zoom-100 gtk-zoom-fit gtk-zoom-in gtk-zoom-out contained
+syn cluster gtkrcPRIVATE add=gtkrcStockName
+
+" Gtk Settings
+syn keyword gtkrcSettingsName gtk-double-click-time gtk-cursor-blink gtk-cursor-blink-time gtk-split-cursor gtk-theme-name gtk-key-theme-name gtk-menu-bar-accel gtk-dnd-drag-threshold gtk-font-name gtk-color-palette gtk-entry-select-on-focus gtk-can-change-accels gtk-toolbar-style gtk-toolbar-icon-size
+syn cluster gtkrcPRIVATE add=gtkrcSettingsName
+
+" Catch errors caused by wrong parenthesization
+syn region gtkrcParen start='(' end=')' transparent contains=ALLBUT,gtkrcParenError,@gtkrcPRIVATE
+syn match gtkrcParenError ")"
+syn region gtkrcBrace start='{' end='}' transparent contains=ALLBUT,gtkrcBraceError,@gtkrcPRIVATE
+syn match gtkrcBraceError "}"
+syn region gtkrcBracket start='\[' end=']' transparent contains=ALLBUT,gtkrcBracketError,@gtkrcPRIVATE
+syn match gtkrcBracketError "]"
+
+" Synchronization
+syn sync minlines=50
+syn sync match gtkrcSyncClass groupthere NONE "^\s*class\>"
+
+" Define the default highlighting
+if version >= 508 || !exists("did_gtkrc_syntax_inits")
+	if version < 508
+		let did_gtkrc_syntax_inits = 1
+		command -nargs=+ HiLink hi link <args>
+	else
+		command -nargs=+ HiLink hi def link <args>
+	endif
+
+	HiLink gtkrcComment Comment
+	HiLink gtkrcFixme Todo
+
+	HiLink gtkrcInclude Preproc
+
+	HiLink gtkrcACString gtkrcString
+	HiLink gtkrcBString gtkrcString
+	HiLink gtkrcString String
+	HiLink gtkrcNumber Number
+	HiLink gtkrcStateName gtkrcConstant
+	HiLink gtkrcPriorityName gtkrcConstant
+	HiLink gtkrcTextDirName gtkrcConstant
+	HiLink gtkrcSettingsName Function
+	HiLink gtkrcStockName Function
+	HiLink gtkrcConstant Constant
+
+	HiLink gtkrcPathSpecial gtkrcSpecial
+	HiLink gtkrcWPathSpecial gtkrcSpecial
+	HiLink gtkrcRGBColor gtkrcSpecial
+	HiLink gtkrcKeyMod gtkrcSpecial
+	HiLink gtkrcSpecial Special
+
+	HiLink gtkrcTop gtkrcKeyword
+	HiLink gtkrcPathSet gtkrcKeyword
+	HiLink gtkrcStyleKeyword gtkrcKeyword
+	HiLink gtkrcFunction gtkrcKeyword
+	HiLink gtkrcBind gtkrcKeyword
+	HiLink gtkrcKeyword Keyword
+
+	HiLink gtkrcClassNameGnome gtkrcGtkClass
+	HiLink gtkrcClassName gtkrcGtkClass
+	HiLink gtkrcFunctionName gtkrcGtkClass
+	HiLink gtkrcGtkClass Type
+
+	HiLink gtkrcImage gtkrcOtherword
+	HiLink gtkrcOtherword Function
+
+	HiLink gtkrcParenError gtkrcError
+	HiLink gtkrcBraceError gtkrcError
+	HiLink gtkrcBracketError gtkrcError
+	HiLink gtkrcError Error
+
+	delcommand HiLink
+endif
+
+let b:current_syntax = "gtkrc"
--- /dev/null
+++ b/lib/vimfiles/syntax/hamster.vim
@@ -1,0 +1,382 @@
+" Vim syntax file
+" Language:    Hamster Scripting Language
+" Maintainer:  David Fishburn <fishburn@ianywhere.com>
+" Last Change: Sun Oct 24 2004 7:11:50 PM
+" Version:     2.0.6.0
+
+" Description: Hamster Classic
+" Hamster is a local server for news and mail. It's a windows-32-bit-program.
+" It allows the use of multiple news- and mailserver and combines them to one
+" mail- and newsserver for the news/mail-client. It load faster than a normal
+" newsreader because many threads can run simultaneous. It contains scorefile
+" for news and mail, a build-in script language, the GUI allows translation to
+" other languages, it can be used in a network and that's not all features...
+"
+" For version 6.x: Quit when a syntax file was already loaded
+if version < 600
+    syntax clear
+elseif exists("b:current_syntax")
+    finish
+endif
+
+syn case ignore
+
+syn keyword hamsterSpecial abs
+syn keyword hamsterSpecial artaddheader
+syn keyword hamsterSpecial artalloc
+syn keyword hamsterSpecial artdelheader
+syn keyword hamsterSpecial artfree
+syn keyword hamsterSpecial artgetbody
+syn keyword hamsterSpecial artgetheader
+syn keyword hamsterSpecial artgetheaders
+syn keyword hamsterSpecial artgettext
+syn keyword hamsterSpecial artheaderexists
+syn keyword hamsterSpecial artload
+syn keyword hamsterSpecial artsave
+syn keyword hamsterSpecial artsetbody
+syn keyword hamsterSpecial artsetheader
+syn keyword hamsterSpecial artsetheaders
+syn keyword hamsterSpecial artsettext
+syn keyword hamsterSpecial assert
+syn keyword hamsterSpecial atadd
+syn keyword hamsterSpecial atclear
+syn keyword hamsterSpecial atcount
+syn keyword hamsterSpecial ateverymins
+syn keyword hamsterSpecial atexecute
+syn keyword hamsterSpecial atfrom
+syn keyword hamsterSpecial atondays
+syn keyword hamsterSpecial atsubfunction
+syn keyword hamsterSpecial atuntil
+syn keyword hamsterSpecial beep
+syn keyword hamsterSpecial break
+syn keyword hamsterSpecial chr
+syn keyword hamsterSpecial clearxcounter
+syn keyword hamsterSpecial clipread
+syn keyword hamsterSpecial clipwrite
+syn keyword hamsterSpecial const
+syn keyword hamsterSpecial constenum
+syn keyword hamsterSpecial continue
+syn keyword hamsterSpecial copy
+syn keyword hamsterSpecial debug
+syn keyword hamsterSpecial dec
+syn keyword hamsterSpecial decodebase64
+syn keyword hamsterSpecial decodeqp
+syn keyword hamsterSpecial decodetime
+syn keyword hamsterSpecial decxcounter
+syn keyword hamsterSpecial delete
+syn keyword hamsterSpecial deletehostsentry
+syn keyword hamsterSpecial digest
+syn keyword hamsterSpecial dirchange
+syn keyword hamsterSpecial dircurrent
+syn keyword hamsterSpecial direxists
+syn keyword hamsterSpecial dirmake
+syn keyword hamsterSpecial dirremove
+syn keyword hamsterSpecial dirsystem
+syn keyword hamsterSpecial dirwindows
+syn keyword hamsterSpecial diskfreekb
+syn keyword hamsterSpecial dllcall
+syn keyword hamsterSpecial dllfree
+syn keyword hamsterSpecial dlllasterror
+syn keyword hamsterSpecial dllload
+syn keyword hamsterSpecial dump
+syn keyword hamsterSpecial encodetime
+syn keyword hamsterSpecial entercontext
+syn keyword hamsterSpecial errcatch
+syn keyword hamsterSpecial errline
+syn keyword hamsterSpecial errlineno
+syn keyword hamsterSpecial errmodule
+syn keyword hamsterSpecial errmsg
+syn keyword hamsterSpecial errnum
+syn keyword hamsterSpecial error
+syn keyword hamsterSpecial errsender
+syn keyword hamsterSpecial eval
+syn keyword hamsterSpecial eventclose
+syn keyword hamsterSpecial eventcreate
+syn keyword hamsterSpecial eventmultiplewait
+syn keyword hamsterSpecial eventpulse
+syn keyword hamsterSpecial eventreset
+syn keyword hamsterSpecial eventset
+syn keyword hamsterSpecial eventwait
+syn keyword hamsterSpecial execute
+syn keyword hamsterSpecial false
+syn keyword hamsterSpecial filecopy
+syn keyword hamsterSpecial filedelete
+syn keyword hamsterSpecial fileexists
+syn keyword hamsterSpecial filemove
+syn keyword hamsterSpecial filerename
+syn keyword hamsterSpecial filesize
+syn keyword hamsterSpecial filetime
+syn keyword hamsterSpecial getenv
+syn keyword hamsterSpecial getprocessidentifier
+syn keyword hamsterSpecial getuptimedays
+syn keyword hamsterSpecial getuptimehours
+syn keyword hamsterSpecial getuptimemins
+syn keyword hamsterSpecial getuptimesecs
+syn keyword hamsterSpecial gosub
+syn keyword hamsterSpecial goto
+syn keyword hamsterSpecial hex
+syn keyword hamsterSpecial icase
+syn keyword hamsterSpecial iif
+syn keyword hamsterSpecial inc
+syn keyword hamsterSpecial incxcounter
+syn keyword hamsterSpecial inidelete
+syn keyword hamsterSpecial inierasesection
+syn keyword hamsterSpecial iniread
+syn keyword hamsterSpecial iniwrite
+syn keyword hamsterSpecial inputbox
+syn keyword hamsterSpecial inputpw
+syn keyword hamsterSpecial int
+syn keyword hamsterSpecial isint
+syn keyword hamsterSpecial isstr
+syn keyword hamsterSpecial leavecontext
+syn keyword hamsterSpecial len
+syn keyword hamsterSpecial listadd
+syn keyword hamsterSpecial listalloc
+syn keyword hamsterSpecial listappend
+syn keyword hamsterSpecial listbox
+syn keyword hamsterSpecial listclear
+syn keyword hamsterSpecial listcount
+syn keyword hamsterSpecial listdelete
+syn keyword hamsterSpecial listdirs
+syn keyword hamsterSpecial listexists
+syn keyword hamsterSpecial listfiles
+syn keyword hamsterSpecial listfiles
+syn keyword hamsterSpecial listfree
+syn keyword hamsterSpecial listget
+syn keyword hamsterSpecial listgetkey
+syn keyword hamsterSpecial listgettag
+syn keyword hamsterSpecial listgettext
+syn keyword hamsterSpecial listindexof
+syn keyword hamsterSpecial listinsert
+syn keyword hamsterSpecial listload
+syn keyword hamsterSpecial listrasentries
+syn keyword hamsterSpecial listsave
+syn keyword hamsterSpecial listset
+syn keyword hamsterSpecial listsetkey
+syn keyword hamsterSpecial listsettag
+syn keyword hamsterSpecial listsettext
+syn keyword hamsterSpecial listsort
+syn keyword hamsterSpecial localhostaddr
+syn keyword hamsterSpecial localhostname
+syn keyword hamsterSpecial lookuphostaddr
+syn keyword hamsterSpecial lookuphostname
+syn keyword hamsterSpecial lowercase
+syn keyword hamsterSpecial memalloc
+syn keyword hamsterSpecial memforget
+syn keyword hamsterSpecial memfree
+syn keyword hamsterSpecial memgetint
+syn keyword hamsterSpecial memgetstr
+syn keyword hamsterSpecial memsetint
+syn keyword hamsterSpecial memsetstr
+syn keyword hamsterSpecial memsize
+syn keyword hamsterSpecial memvarptr
+syn keyword hamsterSpecial msgbox
+syn keyword hamsterSpecial ord
+syn keyword hamsterSpecial paramcount
+syn keyword hamsterSpecial paramstr
+syn keyword hamsterSpecial popupbox
+syn keyword hamsterSpecial pos
+syn keyword hamsterSpecial print
+syn keyword hamsterSpecial quit
+syn keyword hamsterSpecial random
+syn keyword hamsterSpecial randomize
+syn keyword hamsterSpecial rasdial
+syn keyword hamsterSpecial rasgetconnection
+syn keyword hamsterSpecial rasgetip
+syn keyword hamsterSpecial rashangup
+syn keyword hamsterSpecial rasisconnected
+syn keyword hamsterSpecial re_extract
+syn keyword hamsterSpecial re_match
+syn keyword hamsterSpecial re_parse
+syn keyword hamsterSpecial re_split
+syn keyword hamsterSpecial replace
+syn keyword hamsterSpecial return
+syn keyword hamsterSpecial runscript
+syn keyword hamsterSpecial scriptpriority
+syn keyword hamsterSpecial set
+syn keyword hamsterSpecial sethostsentry_byaddr
+syn keyword hamsterSpecial sethostsentry_byname
+syn keyword hamsterSpecial setxcounter
+syn keyword hamsterSpecial sgn
+syn keyword hamsterSpecial shell
+syn keyword hamsterSpecial sleep
+syn keyword hamsterSpecial stopthread
+syn keyword hamsterSpecial str
+syn keyword hamsterSpecial syserrormessage
+syn keyword hamsterSpecial testmailfilterline
+syn keyword hamsterSpecial testnewsfilterline
+syn keyword hamsterSpecial ticks
+syn keyword hamsterSpecial time
+syn keyword hamsterSpecial timegmt
+syn keyword hamsterSpecial trace
+syn keyword hamsterSpecial trim
+syn keyword hamsterSpecial true
+syn keyword hamsterSpecial uppercase
+syn keyword hamsterSpecial utf7toucs16
+syn keyword hamsterSpecial utf8toucs32
+syn keyword hamsterSpecial var
+syn keyword hamsterSpecial varset
+syn keyword hamsterSpecial warning
+syn keyword hamsterSpecial xcounter
+
+" common functions
+syn keyword hamsterFunction addlog
+syn keyword hamsterFunction decodemimeheaderstring
+syn keyword hamsterFunction decodetolocalcharset
+syn keyword hamsterFunction gettasksactive
+syn keyword hamsterFunction gettasksrun
+syn keyword hamsterFunction gettaskswait
+syn keyword hamsterFunction hamaddgroup
+syn keyword hamsterFunction hamaddlog
+syn keyword hamsterFunction hamaddpull
+syn keyword hamsterFunction hamartcount
+syn keyword hamsterFunction hamartdeletemid
+syn keyword hamsterFunction hamartdeletemidingroup
+syn keyword hamsterFunction hamartdeletenringroup
+syn keyword hamsterFunction hamartimport
+syn keyword hamsterFunction hamartlocatemid
+syn keyword hamsterFunction hamartlocatemidingroup
+syn keyword hamsterFunction hamartnomax
+syn keyword hamsterFunction hamartnomin
+syn keyword hamsterFunction hamarttext
+syn keyword hamsterFunction hamarttextexport
+syn keyword hamsterFunction hamchangepassword
+syn keyword hamsterFunction hamcheckpurge
+syn keyword hamsterFunction hamdelgroup
+syn keyword hamsterFunction hamdelpull
+syn keyword hamsterFunction hamdialogaddpull
+syn keyword hamsterFunction hamdialogeditdirs
+syn keyword hamsterFunction hamdialogmailkillfilelog
+syn keyword hamsterFunction hamdialognewskillfilelog
+syn keyword hamsterFunction hamdialogscripts
+syn keyword hamsterFunction hamenvelopefrom
+syn keyword hamsterFunction hamexepath
+syn keyword hamsterFunction hamfetchmail
+syn keyword hamsterFunction hamflush
+syn keyword hamsterFunction hamgetstatus
+syn keyword hamsterFunction hamgroupclose
+syn keyword hamsterFunction hamgroupcount
+syn keyword hamsterFunction hamgroupindex
+syn keyword hamsterFunction hamgroupname
+syn keyword hamsterFunction hamgroupnamebyhandle
+syn keyword hamsterFunction hamgroupopen
+syn keyword hamsterFunction hamgroupspath
+syn keyword hamsterFunction hamhscpath
+syn keyword hamsterFunction hamhsmpath
+syn keyword hamsterFunction hamimapserver
+syn keyword hamsterFunction hamisidle
+syn keyword hamsterFunction hamlogspath
+syn keyword hamsterFunction hammailexchange
+syn keyword hamsterFunction hammailpath
+syn keyword hamsterFunction hammailsoutpath
+syn keyword hamsterFunction hammainfqdn
+syn keyword hamsterFunction hammainwindow
+syn keyword hamsterFunction hammessage
+syn keyword hamsterFunction hammidfqdn
+syn keyword hamsterFunction hamnewmail
+syn keyword hamsterFunction hamnewserrpath
+syn keyword hamsterFunction hamnewsjobsadd
+syn keyword hamsterFunction hamnewsjobscheckactive
+syn keyword hamsterFunction hamnewsjobsclear
+syn keyword hamsterFunction hamnewsjobsdelete
+syn keyword hamsterFunction hamnewsjobsfeed
+syn keyword hamsterFunction hamnewsjobsgetcounter
+syn keyword hamsterFunction hamnewsjobsgetparam
+syn keyword hamsterFunction hamnewsjobsgetpriority
+syn keyword hamsterFunction hamnewsjobsgetserver
+syn keyword hamsterFunction hamnewsjobsgettype
+syn keyword hamsterFunction hamnewsjobspost
+syn keyword hamsterFunction hamnewsjobspostdef
+syn keyword hamsterFunction hamnewsjobspull
+syn keyword hamsterFunction hamnewsjobspulldef
+syn keyword hamsterFunction hamnewsjobssetpriority
+syn keyword hamsterFunction hamnewsjobsstart
+syn keyword hamsterFunction hamnewsoutpath
+syn keyword hamsterFunction hamnewspost
+syn keyword hamsterFunction hamnewspull
+syn keyword hamsterFunction hamnntpserver
+syn keyword hamsterFunction hampassreload
+syn keyword hamsterFunction hampath
+syn keyword hamsterFunction hampop3server
+syn keyword hamsterFunction hampostmaster
+syn keyword hamsterFunction hampurge
+syn keyword hamsterFunction hamrasdial
+syn keyword hamsterFunction hamrashangup
+syn keyword hamsterFunction hamrcpath
+syn keyword hamsterFunction hamrebuildgloballists
+syn keyword hamsterFunction hamrebuildhistory
+syn keyword hamsterFunction hamrecoserver
+syn keyword hamsterFunction hamreloadconfig
+syn keyword hamsterFunction hamreloadipaccess
+syn keyword hamsterFunction hamresetcounters
+syn keyword hamsterFunction hamrotatelog
+syn keyword hamsterFunction hamscorelist
+syn keyword hamsterFunction hamscoretest
+syn keyword hamsterFunction hamsendmail
+syn keyword hamsterFunction hamsendmailauth
+syn keyword hamsterFunction hamserverpath
+syn keyword hamsterFunction hamsetlogin
+syn keyword hamsterFunction hamshutdown
+syn keyword hamsterFunction hamsmtpserver
+syn keyword hamsterFunction hamstopalltasks
+syn keyword hamsterFunction hamthreadcount
+syn keyword hamsterFunction hamtrayicon
+syn keyword hamsterFunction hamusenetacc
+syn keyword hamsterFunction hamversion
+syn keyword hamsterFunction hamwaitidle
+syn keyword hamsterFunction raslasterror
+syn keyword hamsterFunction rfctimezone
+syn keyword hamsterFunction settasklimiter
+
+syn keyword hamsterStatement if
+syn keyword hamsterStatement else
+syn keyword hamsterStatement elseif
+syn keyword hamsterStatement endif
+syn keyword hamsterStatement do
+syn keyword hamsterStatement loop
+syn keyword hamsterStatement while
+syn keyword hamsterStatement endwhile
+syn keyword hamsterStatement repeat
+syn keyword hamsterStatement until
+syn keyword hamsterStatement for
+syn keyword hamsterStatement endfor
+syn keyword hamsterStatement sub
+syn keyword hamsterStatement endsub
+syn keyword hamsterStatement label
+
+
+" Strings and characters:
+syn region hamsterString	start=+"+    end=+"+ contains=@Spell
+syn region hamsterString	start=+'+    end=+'+ contains=@Spell
+
+" Numbers:
+syn match hamsterNumber		"-\=\<\d*\.\=[0-9_]\>"
+
+" Comments:
+syn region hamsterHashComment	start=/#/ end=/$/ contains=@Spell
+syn cluster hamsterComment	contains=hamsterHashComment
+syn sync ccomment hamsterHashComment
+
+" Define the default highlighting.
+" For version 5.7 and earlier: only when not done already
+" For version 5.8 and later: only when an item doesn't have highlighting yet
+if version >= 508 || !exists("did_hamster_syn_inits")
+    if version < 508
+        let did_hamster_syn_inits = 1
+        command -nargs=+ HiLink hi link <args>
+    else
+        command -nargs=+ HiLink hi def link <args>
+    endif
+
+    HiLink hamsterHashComment	Comment
+    HiLink hamsterSpecial	Special
+    HiLink hamsterStatement	Statement
+    HiLink hamsterString	String
+    HiLink hamsterFunction	Function
+
+    delcommand HiLink
+endif
+
+let b:current_syntax = "hamster"
+
+" vim:sw=4
--- /dev/null
+++ b/lib/vimfiles/syntax/haskell.vim
@@ -1,0 +1,193 @@
+" Vim syntax file
+" Language:		Haskell
+" Maintainer:		Haskell Cafe mailinglist <haskell-cafe@haskell.org>
+" Last Change:		2004 Feb 23
+" Original Author:	John Williams <jrw@pobox.com>
+"
+" Thanks to Ryan Crumley for suggestions and John Meacham for
+" pointing out bugs. Also thanks to Ian Lynagh and Donald Bruce Stewart
+" for providing the inspiration for the inclusion of the handling
+" of C preprocessor directives, and for pointing out a bug in the
+" end-of-line comment handling.
+"
+" Options-assign a value to these variables to turn the option on:
+"
+" hs_highlight_delimiters - Highlight delimiter characters--users
+"			    with a light-colored background will
+"			    probably want to turn this on.
+" hs_highlight_boolean - Treat True and False as keywords.
+" hs_highlight_types - Treat names of primitive types as keywords.
+" hs_highlight_more_types - Treat names of other common types as keywords.
+" hs_highlight_debug - Highlight names of debugging functions.
+" hs_allow_hash_operator - Don't highlight seemingly incorrect C
+"			   preprocessor directives but assume them to be
+"			   operators
+"
+" 2004 Feb 19: Added C preprocessor directive handling, corrected eol comments
+"	       cleaned away literate haskell support (should be entirely in
+"	       lhaskell.vim)
+" 2004 Feb 20: Cleaned up C preprocessor directive handling, fixed single \
+"	       in eol comment character class
+" 2004 Feb 23: Made the leading comments somewhat clearer where it comes
+"	       to attribution of work.
+
+" Remove any old syntax stuff hanging around
+if version < 600
+  syn clear
+elseif exists("b:current_syntax")
+  finish
+endif
+
+" (Qualified) identifiers (no default highlighting)
+syn match ConId "\(\<[A-Z][a-zA-Z0-9_']*\.\)\=\<[A-Z][a-zA-Z0-9_']*\>"
+syn match VarId "\(\<[A-Z][a-zA-Z0-9_']*\.\)\=\<[a-z][a-zA-Z0-9_']*\>"
+
+" Infix operators--most punctuation characters and any (qualified) identifier
+" enclosed in `backquotes`. An operator starting with : is a constructor,
+" others are variables (e.g. functions).
+syn match hsVarSym "\(\<[A-Z][a-zA-Z0-9_']*\.\)\=[-!#$%&\*\+/<=>\?@\\^|~.][-!#$%&\*\+/<=>\?@\\^|~:.]*"
+syn match hsConSym "\(\<[A-Z][a-zA-Z0-9_']*\.\)\=:[-!#$%&\*\+./<=>\?@\\^|~:]*"
+syn match hsVarSym "`\(\<[A-Z][a-zA-Z0-9_']*\.\)\=[a-z][a-zA-Z0-9_']*`"
+syn match hsConSym "`\(\<[A-Z][a-zA-Z0-9_']*\.\)\=[A-Z][a-zA-Z0-9_']*`"
+
+" Reserved symbols--cannot be overloaded.
+syn match hsDelimiter  "(\|)\|\[\|\]\|,\|;\|_\|{\|}"
+
+" Strings and constants
+syn match   hsSpecialChar	contained "\\\([0-9]\+\|o[0-7]\+\|x[0-9a-fA-F]\+\|[\"\\'&\\abfnrtv]\|^[A-Z^_\[\\\]]\)"
+syn match   hsSpecialChar	contained "\\\(NUL\|SOH\|STX\|ETX\|EOT\|ENQ\|ACK\|BEL\|BS\|HT\|LF\|VT\|FF\|CR\|SO\|SI\|DLE\|DC1\|DC2\|DC3\|DC4\|NAK\|SYN\|ETB\|CAN\|EM\|SUB\|ESC\|FS\|GS\|RS\|US\|SP\|DEL\)"
+syn match   hsSpecialCharError	contained "\\&\|'''\+"
+syn region  hsString		start=+"+  skip=+\\\\\|\\"+  end=+"+  contains=hsSpecialChar
+syn match   hsCharacter		"[^a-zA-Z0-9_']'\([^\\]\|\\[^']\+\|\\'\)'"lc=1 contains=hsSpecialChar,hsSpecialCharError
+syn match   hsCharacter		"^'\([^\\]\|\\[^']\+\|\\'\)'" contains=hsSpecialChar,hsSpecialCharError
+syn match   hsNumber		"\<[0-9]\+\>\|\<0[xX][0-9a-fA-F]\+\>\|\<0[oO][0-7]\+\>"
+syn match   hsFloat		"\<[0-9]\+\.[0-9]\+\([eE][-+]\=[0-9]\+\)\=\>"
+
+" Keyword definitions. These must be patters instead of keywords
+" because otherwise they would match as keywords at the start of a
+" "literate" comment (see lhs.vim).
+syn match hsModule		"\<module\>"
+syn match hsImport		"\<import\>.*"he=s+6 contains=hsImportMod
+syn match hsImportMod		contained "\<\(as\|qualified\|hiding\)\>"
+syn match hsInfix		"\<\(infix\|infixl\|infixr\)\>"
+syn match hsStructure		"\<\(class\|data\|deriving\|instance\|default\|where\)\>"
+syn match hsTypedef		"\<\(type\|newtype\)\>"
+syn match hsStatement		"\<\(do\|case\|of\|let\|in\)\>"
+syn match hsConditional		"\<\(if\|then\|else\)\>"
+
+" Not real keywords, but close.
+if exists("hs_highlight_boolean")
+  " Boolean constants from the standard prelude.
+  syn match hsBoolean "\<\(True\|False\)\>"
+endif
+if exists("hs_highlight_types")
+  " Primitive types from the standard prelude and libraries.
+  syn match hsType "\<\(Int\|Integer\|Char\|Bool\|Float\|Double\|IO\|Void\|Addr\|Array\|String\)\>"
+endif
+if exists("hs_highlight_more_types")
+  " Types from the standard prelude libraries.
+  syn match hsType "\<\(Maybe\|Either\|Ratio\|Complex\|Ordering\|IOError\|IOResult\|ExitCode\)\>"
+  syn match hsMaybe    "\<Nothing\>"
+  syn match hsExitCode "\<\(ExitSuccess\)\>"
+  syn match hsOrdering "\<\(GT\|LT\|EQ\)\>"
+endif
+if exists("hs_highlight_debug")
+  " Debugging functions from the standard prelude.
+  syn match hsDebug "\<\(undefined\|error\|trace\)\>"
+endif
+
+
+" Comments
+syn match   hsLineComment      "---*\([^-!#$%&\*\+./<=>\?@\\^|~].*\)\?$"
+syn region  hsBlockComment     start="{-"  end="-}" contains=hsBlockComment
+syn region  hsPragma	       start="{-#" end="#-}"
+
+" C Preprocessor directives. Shamelessly ripped from c.vim and trimmed
+" First, see whether to flag directive-like lines or not
+if (!exists("hs_allow_hash_operator"))
+    syn match	cError		display "^\s*\(%:\|#\).*$"
+endif
+" Accept %: for # (C99)
+syn region	cPreCondit	start="^\s*\(%:\|#\)\s*\(if\|ifdef\|ifndef\|elif\)\>" skip="\\$" end="$" end="//"me=s-1 contains=cComment,cCppString,cCommentError
+syn match	cPreCondit	display "^\s*\(%:\|#\)\s*\(else\|endif\)\>"
+syn region	cCppOut		start="^\s*\(%:\|#\)\s*if\s\+0\+\>" end=".\@=\|$" contains=cCppOut2
+syn region	cCppOut2	contained start="0" end="^\s*\(%:\|#\)\s*\(endif\>\|else\>\|elif\>\)" contains=cCppSkip
+syn region	cCppSkip	contained start="^\s*\(%:\|#\)\s*\(if\>\|ifdef\>\|ifndef\>\)" skip="\\$" end="^\s*\(%:\|#\)\s*endif\>" contains=cCppSkip
+syn region	cIncluded	display contained start=+"+ skip=+\\\\\|\\"+ end=+"+
+syn match	cIncluded	display contained "<[^>]*>"
+syn match	cInclude	display "^\s*\(%:\|#\)\s*include\>\s*["<]" contains=cIncluded
+syn cluster	cPreProcGroup	contains=cPreCondit,cIncluded,cInclude,cDefine,cCppOut,cCppOut2,cCppSkip,cCommentStartError
+syn region	cDefine		matchgroup=cPreCondit start="^\s*\(%:\|#\)\s*\(define\|undef\)\>" skip="\\$" end="$"
+syn region	cPreProc	matchgroup=cPreCondit start="^\s*\(%:\|#\)\s*\(pragma\>\|line\>\|warning\>\|warn\>\|error\>\)" skip="\\$" end="$" keepend
+
+syn region	cComment	matchgroup=cCommentStart start="/\*" end="\*/" contains=cCommentStartError,cSpaceError contained
+syntax match	cCommentError	display "\*/" contained
+syntax match	cCommentStartError display "/\*"me=e-1 contained
+syn region	cCppString	start=+L\="+ skip=+\\\\\|\\"\|\\$+ excludenl end=+"+ end='$' contains=cSpecial contained
+
+" Define the default highlighting.
+" For version 5.7 and earlier: only when not done already
+" For version 5.8 and later: only when an item doesn't have highlighting yet
+if version >= 508 || !exists("did_hs_syntax_inits")
+  if version < 508
+    let did_hs_syntax_inits = 1
+    command -nargs=+ HiLink hi link <args>
+  else
+    command -nargs=+ HiLink hi def link <args>
+  endif
+
+  HiLink hsModule			  hsStructure
+  HiLink hsImport			  Include
+  HiLink hsImportMod			  hsImport
+  HiLink hsInfix			  PreProc
+  HiLink hsStructure			  Structure
+  HiLink hsStatement			  Statement
+  HiLink hsConditional			  Conditional
+  HiLink hsSpecialChar			  SpecialChar
+  HiLink hsTypedef			  Typedef
+  HiLink hsVarSym			  hsOperator
+  HiLink hsConSym			  hsOperator
+  HiLink hsOperator			  Operator
+  if exists("hs_highlight_delimiters")
+    " Some people find this highlighting distracting.
+    HiLink hsDelimiter			  Delimiter
+  endif
+  HiLink hsSpecialCharError		  Error
+  HiLink hsString			  String
+  HiLink hsCharacter			  Character
+  HiLink hsNumber			  Number
+  HiLink hsFloat			  Float
+  HiLink hsConditional			  Conditional
+  HiLink hsLiterateComment		  hsComment
+  HiLink hsBlockComment		  hsComment
+  HiLink hsLineComment			  hsComment
+  HiLink hsComment			  Comment
+  HiLink hsPragma			  SpecialComment
+  HiLink hsBoolean			  Boolean
+  HiLink hsType			  Type
+  HiLink hsMaybe			  hsEnumConst
+  HiLink hsOrdering			  hsEnumConst
+  HiLink hsEnumConst			  Constant
+  HiLink hsDebug			  Debug
+
+  HiLink cCppString		hsString
+  HiLink cCommentStart		hsComment
+  HiLink cCommentError		hsError
+  HiLink cCommentStartError	hsError
+  HiLink cInclude		Include
+  HiLink cPreProc		PreProc
+  HiLink cDefine		Macro
+  HiLink cIncluded		hsString
+  HiLink cError			Error
+  HiLink cPreCondit		PreCondit
+  HiLink cComment		Comment
+  HiLink cCppSkip		cCppOut
+  HiLink cCppOut2		cCppOut
+  HiLink cCppOut		Comment
+
+  delcommand HiLink
+endif
+
+let b:current_syntax = "haskell"
+
+" Options for vi: ts=8 sw=2 sts=2 nowrap noexpandtab ft=vim
--- /dev/null
+++ b/lib/vimfiles/syntax/hb.vim
@@ -1,0 +1,97 @@
+" Vim syntax file
+" Language:	Hyper Builder
+" Maintainer:	Alejandro Forero Cuervo
+" URL:		http://bachue.com/hb/vim/syntax/hb.vim
+" Last Change:	2001 Sep 02
+
+" For version 5.x: Clear all syntax items
+" For version 6.x: Quit when a syntax file was already loaded
+if version < 600
+  syntax clear
+elseif exists("b:current_syntax")
+  finish
+endif
+
+" Read the HTML syntax to start with
+"syn include @HTMLStuff <sfile>:p:h/htmlhb.vim
+
+"this would be nice but we are supposed not to do it
+"set mps=<:>
+
+"syn region  HBhtmlString contained start=+"+ end=+"+ contains=htmlSpecialChar
+"syn region  HBhtmlString contained start=+'+ end=+'+ contains=htmlSpecialChar
+
+"syn match   htmlValue    contained "=[\t ]*[^'" \t>][^ \t>]*"
+
+syn match   htmlSpecialChar "&[^;]*;" contained
+
+syn match   HBhtmlTagSk  contained "[A-Za-z]*"
+
+syn match   HBhtmlTagS   contained "<\s*\(hb\s*\.\s*\(sec\|min\|hour\|day\|mon\|year\|input\|html\|time\|getcookie\|streql\|url-enc\)\|wall\s*\.\s*\(show\|info\|id\|new\|rm\|count\)\|auth\s*\.\s*\(chk\|add\|find\|user\)\|math\s*\.\s*exp\)\s*\([^.A-Za-z0-9]\|$\)" contains=HBhtmlTagSk transparent
+
+syn match   HBhtmlTagN   contained "[A-Za-z0-9\/\-]\+"
+
+syn match   HBhtmlTagB   contained "<\s*[A-Za-z0-9\/\-]\+\(\s*\.\s*[A-Za-z0-9\/\-]\+\)*" contains=HBhtmlTagS,HBhtmlTagN
+
+syn region  HBhtmlTag contained start=+<+ end=+>+ contains=HBhtmlTagB,HBDirectiveError
+
+syn match HBFileName ".*" contained
+
+syn match HBDirectiveKeyword	":\s*\(include\|lib\|set\|out\)\s\+" contained
+
+syn match HBDirectiveError	"^:.*$" contained
+
+"syn match HBDirectiveBlockEnd "^:\s*$" contained
+
+"syn match HBDirectiveOutHead "^:\s*out\s\+\S\+.*" contained contains=HBDirectiveKeyword,HBFileName
+
+"syn match HBDirectiveSetHead "^:\s*set\s\+\S\+.*" contained contains=HBDirectiveKeyword,HBFileName
+
+syn match HBInvalidLine "^.*$"
+
+syn match HBDirectiveInclude "^:\s*include\s\+\S\+.*$" contains=HBFileName,HBDirectiveKeyword
+
+syn match HBDirectiveLib "^:\s*lib\s\+\S\+.*$" contains=HBFileName,HBDirectiveKeyword
+
+syn region HBText matchgroup=HBDirectiveKeyword start=/^:\(set\|out\)\s*\S\+.*$/ end=/^:\s*$/ contains=HBDirectiveError,htmlSpecialChar,HBhtmlTag keepend
+
+"syn match HBLine "^:.*$" contains=HBDirectiveInclude,HBDirectiveLib,HBDirectiveError,HBDirectiveSet,HBDirectiveOut
+
+syn match HBComment "^#.*$"
+
+" Define the default highlighting.
+" For version 5.7 and earlier: only when not done already
+" For version 5.8 and later: only when an item doesn't have highlighting yet
+if version >= 508 || !exists("did_hb_syntax_inits")
+  if version < 508
+    let did_hb_syntax_inits = 1
+    command -nargs=+ HiLink hi link <args>
+  else
+    command -nargs=+ HiLink hi def link <args>
+  endif
+
+  HiLink HBhtmlString			 String
+  HiLink HBhtmlTagN			 Function
+  HiLink htmlSpecialChar		 String
+
+  HiLink HBInvalidLine Error
+  HiLink HBFoobar Comment
+  hi HBFileName guibg=lightgray guifg=black
+  HiLink HBDirectiveError Error
+  HiLink HBDirectiveBlockEnd HBDirectiveKeyword
+  hi HBDirectiveKeyword guibg=lightgray guifg=darkgreen
+  HiLink HBComment Comment
+  HiLink HBhtmlTagSk Statement
+
+  delcommand HiLink
+endif
+
+syn sync match Normal grouphere NONE "^:\s*$"
+syn sync match Normal grouphere NONE "^:\s*lib\s\+[^ \t]\+$"
+syn sync match Normal grouphere NONE "^:\s*include\s\+[^ \t]\+$"
+"syn sync match Block  grouphere HBDirectiveSet "^#:\s*set\s\+[^ \t]\+"
+"syn sync match Block  grouphere HBDirectiveOut "^#:\s*out\s\+[^ \t]\+"
+
+let b:current_syntax = "hb"
+
+" vim: ts=8
--- /dev/null
+++ b/lib/vimfiles/syntax/help.vim
@@ -1,0 +1,178 @@
+" Vim syntax file
+" Language:	Vim help file
+" Maintainer:	Bram Moolenaar (Bram@vim.org)
+" Last Change:	2006 May 13
+
+" Quit when a (custom) syntax file was already loaded
+if exists("b:current_syntax")
+  finish
+endif
+
+syn match helpHeadline		"^[-A-Z .]\+[ \t]\+\*"me=e-1
+syn match helpSectionDelim	"^=\{3,}.*===$"
+syn match helpSectionDelim	"^-\{3,}.*--$"
+syn region helpExample		matchgroup=helpIgnore start=" >$" start="^>$" end="^[^ \t]"me=e-1 end="^<"
+if has("ebcdic")
+  syn match helpHyperTextJump	"\\\@<!|[^"*|]\+|" contains=helpBar
+  syn match helpHyperTextEntry	"\*[^"*|]\+\*\s"he=e-1 contains=helpStar
+  syn match helpHyperTextEntry	"\*[^"*|]\+\*$" contains=helpStar
+else
+  syn match helpHyperTextJump	"\\\@<!|[#-)!+-~]\+|" contains=helpBar
+  syn match helpHyperTextEntry	"\*[#-)!+-~]\+\*\s"he=e-1 contains=helpStar
+  syn match helpHyperTextEntry	"\*[#-)!+-~]\+\*$" contains=helpStar
+endif
+syn match helpBar		contained "|"
+syn match helpStar		contained "\*"
+syn match helpNormal		"|.*====*|"
+syn match helpNormal		":|vim:|"	" for :help modeline
+syn match helpVim		"Vim version [0-9.a-z]\+"
+syn match helpVim		"VIM REFERENCE.*"
+syn match helpOption		"'[a-z]\{2,\}'"
+syn match helpOption		"'t_..'"
+syn match helpHeader		"\s*\zs.\{-}\ze\s\=\~$" nextgroup=helpIgnore
+syn match helpIgnore		"." contained
+syn keyword helpNote		note Note NOTE note: Note: NOTE: Notes Notes:
+syn match helpSpecial		"\<N\>"
+syn match helpSpecial		"\<N\.$"me=e-1
+syn match helpSpecial		"\<N\.\s"me=e-2
+syn match helpSpecial		"(N\>"ms=s+1
+syn match helpSpecial		"\[N]"
+" avoid highlighting N  N in help.txt
+syn match helpSpecial		"N  N"he=s+1
+syn match helpSpecial		"Nth"me=e-2
+syn match helpSpecial		"N-1"me=e-2
+syn match helpSpecial		"{[-a-zA-Z0-9'":%#=[\]<>.,]\+}"
+syn match helpSpecial		"{[-a-zA-Z0-9'"*+/:%#=[\]<>.,]\+}"
+syn match helpSpecial		"\s\[[-a-z^A-Z0-9_]\{2,}]"ms=s+1
+syn match helpSpecial		"<[-a-zA-Z0-9_]\+>"
+syn match helpSpecial		"<[SCM]-.>"
+syn match helpNormal		"<---*>"
+syn match helpSpecial		"\[range]"
+syn match helpSpecial		"\[line]"
+syn match helpSpecial		"\[count]"
+syn match helpSpecial		"\[offset]"
+syn match helpSpecial		"\[cmd]"
+syn match helpSpecial		"\[num]"
+syn match helpSpecial		"\[+num]"
+syn match helpSpecial		"\[-num]"
+syn match helpSpecial		"\[+cmd]"
+syn match helpSpecial		"\[++opt]"
+syn match helpSpecial		"\[arg]"
+syn match helpSpecial		"\[arguments]"
+syn match helpSpecial		"\[ident]"
+syn match helpSpecial		"\[addr]"
+syn match helpSpecial		"\[group]"
+syn match helpSpecial		"CTRL-."
+syn match helpSpecial		"CTRL-Break"
+syn match helpSpecial		"CTRL-PageUp"
+syn match helpSpecial		"CTRL-PageDown"
+syn match helpSpecial		"CTRL-Insert"
+syn match helpSpecial		"CTRL-Del"
+syn match helpSpecial		"CTRL-{char}"
+syn region helpNotVi		start="{Vi[: ]" start="{not" start="{only" end="}" contains=helpLeadBlank,helpHyperTextJump
+syn match helpLeadBlank		"^\s\+" contained
+
+" Highlight group items in their own color.
+syn match helpComment		"\t[* ]Comment\t\+[a-z].*"
+syn match helpConstant		"\t[* ]Constant\t\+[a-z].*"
+syn match helpString		"\t[* ]String\t\+[a-z].*"
+syn match helpCharacter		"\t[* ]Character\t\+[a-z].*"
+syn match helpNumber		"\t[* ]Number\t\+[a-z].*"
+syn match helpBoolean		"\t[* ]Boolean\t\+[a-z].*"
+syn match helpFloat		"\t[* ]Float\t\+[a-z].*"
+syn match helpIdentifier	"\t[* ]Identifier\t\+[a-z].*"
+syn match helpFunction		"\t[* ]Function\t\+[a-z].*"
+syn match helpStatement		"\t[* ]Statement\t\+[a-z].*"
+syn match helpConditional	"\t[* ]Conditional\t\+[a-z].*"
+syn match helpRepeat		"\t[* ]Repeat\t\+[a-z].*"
+syn match helpLabel		"\t[* ]Label\t\+[a-z].*"
+syn match helpOperator		"\t[* ]Operator\t\+["a-z].*"
+syn match helpKeyword		"\t[* ]Keyword\t\+[a-z].*"
+syn match helpException		"\t[* ]Exception\t\+[a-z].*"
+syn match helpPreProc		"\t[* ]PreProc\t\+[a-z].*"
+syn match helpInclude		"\t[* ]Include\t\+[a-z].*"
+syn match helpDefine		"\t[* ]Define\t\+[a-z].*"
+syn match helpMacro		"\t[* ]Macro\t\+[a-z].*"
+syn match helpPreCondit		"\t[* ]PreCondit\t\+[a-z].*"
+syn match helpType		"\t[* ]Type\t\+[a-z].*"
+syn match helpStorageClass	"\t[* ]StorageClass\t\+[a-z].*"
+syn match helpStructure		"\t[* ]Structure\t\+[a-z].*"
+syn match helpTypedef		"\t[* ]Typedef\t\+[Aa-z].*"
+syn match helpSpecial		"\t[* ]Special\t\+[a-z].*"
+syn match helpSpecialChar	"\t[* ]SpecialChar\t\+[a-z].*"
+syn match helpTag		"\t[* ]Tag\t\+[a-z].*"
+syn match helpDelimiter		"\t[* ]Delimiter\t\+[a-z].*"
+syn match helpSpecialComment	"\t[* ]SpecialComment\t\+[a-z].*"
+syn match helpDebug		"\t[* ]Debug\t\+[a-z].*"
+syn match helpUnderlined	"\t[* ]Underlined\t\+[a-z].*"
+syn match helpError		"\t[* ]Error\t\+[a-z].*"
+syn match helpTodo		"\t[* ]Todo\t\+[a-z].*"
+
+syn match helpURL `\v<(((https?|ftp|gopher)://|(mailto|file|news):)[^' 	<>"]+|(www|web|w3)[a-z0-9_-]*\.[a-z0-9._-]+\.[^' 	<>"]+)[a-zA-Z0-9/]`
+
+" Additionally load a language-specific syntax file "help_ab.vim".
+let s:i = match(expand("%"), '\.\a\ax$')
+if s:i > 0
+  exe "runtime syntax/help_" . strpart(expand("%"), s:i + 1, 2) . ".vim"
+endif
+
+syn sync minlines=40
+
+
+" Define the default highlighting.
+" Only used when an item doesn't have highlighting yet
+hi def link helpExampleStart	helpIgnore
+hi def link helpIgnore		Ignore
+hi def link helpHyperTextJump	Subtitle
+hi def link helpBar		Ignore
+hi def link helpStar		Ignore
+hi def link helpHyperTextEntry	String
+hi def link helpHeadline	Statement
+hi def link helpHeader		PreProc
+hi def link helpSectionDelim	PreProc
+hi def link helpVim		Identifier
+hi def link helpExample		Comment
+hi def link helpOption		Type
+hi def link helpNotVi		Special
+hi def link helpSpecial		Special
+hi def link helpNote		Todo
+hi def link Subtitle		Identifier
+
+hi def link helpComment		Comment
+hi def link helpConstant	Constant
+hi def link helpString		String
+hi def link helpCharacter	Character
+hi def link helpNumber		Number
+hi def link helpBoolean		Boolean
+hi def link helpFloat		Float
+hi def link helpIdentifier	Identifier
+hi def link helpFunction	Function
+hi def link helpStatement	Statement
+hi def link helpConditional	Conditional
+hi def link helpRepeat		Repeat
+hi def link helpLabel		Label
+hi def link helpOperator	Operator
+hi def link helpKeyword		Keyword
+hi def link helpException	Exception
+hi def link helpPreProc		PreProc
+hi def link helpInclude		Include
+hi def link helpDefine		Define
+hi def link helpMacro		Macro
+hi def link helpPreCondit	PreCondit
+hi def link helpType		Type
+hi def link helpStorageClass	StorageClass
+hi def link helpStructure	Structure
+hi def link helpTypedef		Typedef
+hi def link helpSpecialChar	SpecialChar
+hi def link helpTag		Tag
+hi def link helpDelimiter	Delimiter
+hi def link helpSpecialComment	SpecialComment
+hi def link helpDebug		Debug
+hi def link helpUnderlined	Underlined
+hi def link helpError		Error
+hi def link helpTodo		Todo
+hi def link helpURL		String
+
+let b:current_syntax = "help"
+
+" vim: ts=8 sw=2
--- /dev/null
+++ b/lib/vimfiles/syntax/hercules.vim
@@ -1,0 +1,133 @@
+" Vim syntax file
+" Language:	Hercules
+" Maintainer:	Dana Edwards <Dana_Edwards@avanticorp.com>
+" Extensions:   *.vc,*.ev,*.rs
+" Last change:  Nov. 9, 2001
+" Comment:      Hercules physical IC design verification software ensures
+"		that an IC's physical design matches its logical design and
+"		satisfies manufacturing rules.
+
+" For version 5.x: Clear all syntax items
+" For version 6.x: Quit when a syntax file was already loaded
+if version < 600
+  syntax clear
+elseif exists("b:current_syntax")
+  finish
+endif
+
+" Ignore case
+syn case ignore
+
+" Hercules runset sections
+syn keyword   herculesType	  header assign_property alias assign
+syn keyword   herculesType	  options preprocess_options
+syn keyword   herculesType	  explode_options technology_options
+syn keyword   herculesType	  drc_options database_options
+syn keyword   herculesType	  text_options lpe_options evaccess_options
+syn keyword   herculesType	  check_point compare_group environment
+syn keyword   herculesType	  grid_check include layer_stats load_group
+syn keyword   herculesType	  restart run_only self_intersect set snap
+syn keyword   herculesType	  system variable waiver
+
+" Hercules commands
+syn keyword   herculesStatement   attach_property boolean cell_extent
+syn keyword   herculesStatement   common_hierarchy connection_points
+syn keyword   herculesStatement   copy data_filter alternate delete
+syn keyword   herculesStatement   explode explode_all fill_pattern find_net
+syn keyword   herculesStatement   flatten
+syn keyword   herculesStatement   level negate polygon_features push
+syn keyword   herculesStatement   rectangles relocate remove_overlap reverse select
+syn keyword   herculesStatement   select_cell select_contains select_edge select_net size
+syn keyword   herculesStatement   text_polygon text_property vertex area cut
+syn keyword   herculesStatement   density enclose external inside_edge
+syn keyword   herculesStatement   internal notch vectorize center_to_center
+syn keyword   herculesStatement   length mask_align moscheck rescheck
+syn keyword   herculesStatement   analysis buildsub init_lpe_db capacitor
+syn keyword   herculesStatement   device gendev nmos pmos diode npn pnp
+syn keyword   herculesStatement   resistor set_param save_property
+syn keyword   herculesStatement   connect disconnect text  text_boolean
+syn keyword   herculesStatement   replace_text create_ports label graphics
+syn keyword   herculesStatement   save_netlist_database lpe_stats netlist
+syn keyword   herculesStatement   spice graphics_property graphics_netlist
+syn keyword   herculesStatement   write_milkyway multi_rule_enclose
+syn keyword   herculesStatement   if error_property equate compare
+syn keyword   herculesStatement   antenna_fix c_thru dev_connect_check
+syn keyword   herculesStatement   dev_net_count device_count net_filter
+syn keyword   herculesStatement   net_path_check ratio process_text_opens
+
+" Hercules keywords
+syn keyword   herculesStatement   black_box_file block compare_dir equivalence
+syn keyword   herculesStatement   format gdsin_dir group_dir group_dir_usage
+syn keyword   herculesStatement   inlib layout_path outlib output_format
+syn keyword   herculesStatement   output_layout_path schematic schematic_format
+syn keyword   herculesStatement   scheme_file output_block else
+syn keyword   herculesStatement   and or not xor andoverlap inside outside by to
+syn keyword   herculesStatement   with connected connected_all texted_with texted
+syn keyword   herculesStatement   by_property cutting edge_touch enclosing inside
+syn keyword   herculesStatement   inside_hole interact touching vertex
+
+" Hercules comments
+syn region    herculesComment		start="/\*" skip="/\*" end="\*/" contains=herculesTodo
+syn match     herculesComment		"//.*" contains=herculesTodo
+
+" Preprocessor directives
+syn match     herculesPreProc "^#.*"
+syn match     herculesPreProc "^@.*"
+syn match     herculesPreProc "macros"
+
+" Hercules COMMENT option
+syn match     herculesCmdCmnt "comment.*=.*"
+
+" Spacings, Resolutions, Ranges, Ratios, etc.
+syn match     herculesNumber	      "-\=\<[0-9]\+L\=\>\|0[xX][0-9]\+\>"
+
+" Parenthesis sanity checker
+syn region    herculesZone       matchgroup=Delimiter start="(" matchgroup=Delimiter end=")" transparent contains=ALLBUT,herculesError,herculesBraceError,herculesCurlyError
+syn region    herculesZone       matchgroup=Delimiter start="{" matchgroup=Delimiter end="}" transparent contains=ALLBUT,herculesError,herculesBraceError,herculesParenError
+syn region    herculesZone       matchgroup=Delimiter start="\[" matchgroup=Delimiter end="]" transparent contains=ALLBUT,herculesError,herculesCurlyError,herculesParenError
+syn match     herculesError      "[)\]}]"
+syn match     herculesBraceError "[)}]"  contained
+syn match     herculesCurlyError "[)\]]" contained
+syn match     herculesParenError "[\]}]" contained
+
+" Hercules output format
+"syn match  herculesOutput "([0-9].*)"
+"syn match  herculesOutput "([0-9].*\;.*)"
+syn match     herculesOutput "perm\s*=.*(.*)"
+syn match     herculesOutput "temp\s*=\s*"
+syn match     herculesOutput "error\s*=\s*(.*)"
+
+"Modify the following as needed.  The trade-off is performance versus functionality.
+syn sync      lines=100
+
+" Define the default highlighting.
+" For version 5.7 and earlier: only when not done already
+" For version 5.8 and later: only when an item doesn't have highlighting yet
+if version >= 508 || !exists("did_hercules_syntax_inits")
+  if version < 508
+    let did_hercules_syntax_inits = 1
+    " Default methods for highlighting.
+    command -nargs=+ HiLink hi link <args>
+  else
+    command -nargs=+ HiLink hi def link <args>
+  endif
+
+  HiLink herculesStatement  Statement
+  HiLink herculesType       Type
+  HiLink herculesComment    Comment
+  HiLink herculesPreProc    PreProc
+  HiLink herculesTodo       Todo
+  HiLink herculesOutput     Include
+  HiLink herculesCmdCmnt    Identifier
+  HiLink herculesNumber     Number
+  HiLink herculesBraceError herculesError
+  HiLink herculesCurlyError herculesError
+  HiLink herculesParenError herculesError
+  HiLink herculesError      Error
+
+  delcommand HiLink
+endif
+
+let b:current_syntax = "hercules"
+
+" vim: ts=8
--- /dev/null
+++ b/lib/vimfiles/syntax/hex.vim
@@ -1,0 +1,57 @@
+" Vim syntax file
+" Language:	Intel hex MCS51
+" Maintainer:	Sams Ricahrd <sams@ping.at>
+" Last Change:	2003 Apr 25
+
+" For version 5.x: Clear all syntax items
+" For version 6.x: Quit when a syntax file was already loaded
+if version < 600
+  syntax clear
+elseif exists("b:current_syntax")
+  finish
+endif
+
+syn case ignore
+
+" storage types
+
+syn match hexChecksum	"[0-9a-fA-F]\{2}$"
+syn match hexAdress  "^:[0-9a-fA-F]\{6}" contains=hexDataByteCount
+syn match hexRecType  "^:[0-9a-fA-F]\{8}" contains=hexAdress
+syn match hexDataByteCount  contained "^:[0-9a-fA-F]\{2}" contains=hexStart
+syn match hexStart contained "^:"
+syn match hexExtAdrRec "^:02000002[0-9a-fA-F]\{4}" contains=hexSpecRec
+syn match hexExtLinAdrRec "^:02000004[0-9a-fA-F]\{4}" contains=hexSpecRec
+syn match hexSpecRec contained "^:0[02]00000[124]" contains=hexStart
+syn match hexEOF "^:00000001" contains=hexStart
+
+syn case match
+
+" Define the default highlighting.
+" For version 5.7 and earlier: only when not done already
+" For version 5.8 and later: only when an item doesn't have highlighting yet
+if version >= 508 || !exists("did_hex_syntax_inits")
+  if version < 508
+    let did_hex_syntax_inits = 1
+    command -nargs=+ HiLink hi link <args>
+  else
+    command -nargs=+ HiLink hi def link <args>
+  endif
+
+  " The default methods for highlighting.  Can be overridden later
+  HiLink hexStart		SpecialKey
+  HiLink hexDataByteCount	Constant
+  HiLink hexAdress		Comment
+  HiLink hexRecType		WarningMsg
+  HiLink hexChecksum		Search
+  HiLink hexExtAdrRec		hexAdress
+  HiLink hexEOF			hexSpecRec
+  HiLink hexExtLinAdrRec	hexAdress
+  HiLink hexSpecRec		DiffAdd
+
+  delcommand HiLink
+endif
+
+let b:current_syntax = "hex"
+
+" vim: ts=8
--- /dev/null
+++ b/lib/vimfiles/syntax/hitest.vim
@@ -1,0 +1,149 @@
+" Vim syntax file
+" Language:	none; used to see highlighting
+" Maintainer:	Ronald Schild <rs@scutum.de>
+" Last Change:	2001 Sep 02
+" Version:	5.4n.1
+
+" To see your current highlight settings, do
+"    :so $VIMRUNTIME/syntax/hitest.vim
+
+" save global options and registers
+let s:hidden      = &hidden
+let s:lazyredraw  = &lazyredraw
+let s:more	  = &more
+let s:report      = &report
+let s:shortmess   = &shortmess
+let s:wrapscan    = &wrapscan
+let s:register_a  = @a
+let s:register_se = @/
+
+" set global options
+set hidden lazyredraw nomore report=99999 shortmess=aoOstTW wrapscan
+
+" print current highlight settings into register a
+redir @a
+highlight
+redir END
+
+" Open a new window if the current one isn't empty
+if line("$") != 1 || getline(1) != ""
+  new
+endif
+
+" edit temporary file
+edit Highlight\ test
+
+" set local options
+setlocal autoindent noexpandtab formatoptions=t shiftwidth=16 noswapfile tabstop=16
+let &textwidth=&columns
+
+" insert highlight settings
+% delete
+put a
+
+" remove the colored xxx items
+g/xxx /s///e
+
+" remove color settings (not needed here)
+global! /links to/ substitute /\s.*$//e
+
+" move linked groups to the end of file
+global /links to/ move $
+
+" move linked group names to the matching preferred groups
+% substitute /^\(\w\+\)\s*\(links to\)\s*\(\w\+\)$/\3\t\2 \1/e
+global /links to/ normal mz3ElD0#$p'zdd
+
+" delete empty lines
+global /^ *$/ delete
+
+" precede syntax command
+% substitute /^[^ ]*/syn keyword &\t&/
+
+" execute syntax commands
+syntax clear
+% yank a
+@a
+
+" remove syntax commands again
+% substitute /^syn keyword //
+
+" pretty formatting
+global /^/ exe "normal Wi\<CR>\t\eAA\ex"
+global /^\S/ join
+
+" find out first syntax highlighting
+let b:various = &highlight.',:Normal,:Cursor,:,'
+let b:i = 1
+while b:various =~ ':'.substitute(getline(b:i), '\s.*$', ',', '')
+   let b:i = b:i + 1
+   if b:i > line("$") | break | endif
+endwhile
+
+" insert headlines
+call append(0, "Highlighting groups for various occasions")
+call append(1, "-----------------------------------------")
+
+if b:i < line("$")-1
+   let b:synhead = "Syntax highlighting groups"
+   if exists("hitest_filetypes")
+      redir @a
+      let
+      redir END
+      let @a = substitute(@a, 'did_\(\w\+\)_syn\w*_inits\s*#1', ', \1', 'g')
+      let @a = substitute(@a, "\n\\w[^\n]*", '', 'g')
+      let @a = substitute(@a, "\n", '', 'g')
+      let @a = substitute(@a, '^,', '', 'g')
+      if @a != ""
+	 let b:synhead = b:synhead." - filetype"
+	 if @a =~ ','
+	    let b:synhead = b:synhead."s"
+	 endif
+	 let b:synhead = b:synhead.":".@a
+      endif
+   endif
+   call append(b:i+1, "")
+   call append(b:i+2, b:synhead)
+   call append(b:i+3, substitute(b:synhead, '.', '-', 'g'))
+endif
+
+" remove 'hls' highlighting
+nohlsearch
+normal 0
+
+" add autocommands to remove temporary file from buffer list
+aug highlighttest
+   au!
+   au BufUnload Highlight\ test if expand("<afile>") == "Highlight test"
+   au BufUnload Highlight\ test    bdelete! Highlight\ test
+   au BufUnload Highlight\ test endif
+   au VimLeavePre * if bufexists("Highlight test")
+   au VimLeavePre *    bdelete! Highlight\ test
+   au VimLeavePre * endif
+aug END
+
+" we don't want to save this temporary file
+set nomodified
+
+" the following trick avoids the "Press RETURN ..." prompt
+0 append
+.
+
+" restore global options and registers
+let &hidden      = s:hidden
+let &lazyredraw  = s:lazyredraw
+let &more	 = s:more
+let &report	 = s:report
+let &shortmess	 = s:shortmess
+let &wrapscan	 = s:wrapscan
+let @a		 = s:register_a
+
+" restore last search pattern
+call histdel("search", -1)
+let @/ = s:register_se
+
+" remove variables
+unlet s:hidden s:lazyredraw s:more s:report s:shortmess
+unlet s:wrapscan s:register_a s:register_se
+
+" vim: ts=8
--- /dev/null
+++ b/lib/vimfiles/syntax/hog.vim
@@ -1,0 +1,350 @@
+" Snort syntax file
+" Language:	  Snort Configuration File (see: http://www.snort.org)
+" Maintainer:	  Phil Wood, cornett@arpa.net
+" Last Change:	  $Date: 2004/06/13 17:41:17 $
+" Filenames:	  *.hog *.rules snort.conf vision.conf
+" URL:		  http://home.lanl.gov/cpw/vim/syntax/hog.vim
+" Snort Version:  1.8 By Martin Roesch (roesch@clark.net, www.snort.org)
+" TODO		  include all 1.8 syntax
+
+" For version 5.x: Clear all syntax items
+if version < 600
+   syntax clear
+elseif exists("b:current_syntax")
+" For version 6.x: Quit when a syntax file was already loaded
+   finish
+endif
+
+syn match  hogComment	+\s\#[^\-:.%#=*].*$+lc=1	contains=hogTodo,hogCommentString
+syn region hogCommentString contained oneline start='\S\s\+\#+'ms=s+1 end='\#'
+
+syn match   hogJunk "\<\a\+|\s\+$"
+syn match   hogNumber contained	"\<\d\+\>"
+syn region  hogText contained oneline start='\S' end=',' skipwhite
+syn region  hogTexts contained oneline start='\S' end=';' skipwhite
+
+" Environment Variables
+" =====================
+"syn match hogEnvvar contained	"[\!]\=\$\I\i*"
+"syn match hogEnvvar contained	"[\!]\=\${\I\i*}"
+syn match hogEnvvar contained	"\$\I\i*"
+syn match hogEnvvar contained	"[\!]\=\${\I\i*}"
+
+
+" String handling lifted from vim.vim written by Dr. Charles E. Campbell, Jr.
+" Try to catch strings, if nothing else matches (therefore it must precede the others!)
+" vmEscapeBrace handles ["]  []"] (ie. stays as string)
+syn region       hogEscapeBrace   oneline contained transparent     start="[^\\]\(\\\\\)*\[\^\=\]\=" skip="\\\\\|\\\]" end="\]"me=e-1
+syn match	 hogPatSep	  contained	   "\\[|()]"
+syn match	 hogNotPatSep	  contained	   "\\\\"
+syn region	 hogString	  oneline	   start=+[^:a-zA-Z\->!\\]"+hs=e+1 skip=+\\\\\|\\"+ end=+"\s*;+he=s-1		     contains=hogEscapeBrace,hogPatSep,hogNotPatSep oneline
+""syn region	   hogString	    oneline	     start=+[^:a-zA-Z>!\\]'+lc=1 skip=+\\\\\|\\'+ end=+'+		 contains=hogEscapeBrace,vimPatSep,hogNotPatSep
+"syn region	  hogString	   oneline	    start=+=!+lc=1   skip=+\\\\\|\\!+ end=+!+				contains=hogEscapeBrace,hogPatSep,hogNotPatSep
+"syn region	  hogString	   oneline	    start="=+"lc=1   skip="\\\\\|\\+" end="+"				contains=hogEscapeBrace,hogPatSep,hogNotPatSep
+"syn region	  hogString	   oneline	    start="[^\\]+\s*[^a-zA-Z0-9.]"lc=1 skip="\\\\\|\\+" end="+"		contains=hogEscapeBrace,hogPatSep,hogNotPatSep
+"syn region	  hogString	   oneline	    start="\s/\s*\A"lc=1 skip="\\\\\|\\+" end="/"			contains=hogEscapeBrace,hogPatSep,hogNotPatSep
+"syn match	  hogString	   contained	    +"[^"]*\\$+      skipnl nextgroup=hogStringCont
+"syn match	  hogStringCont    contained	    +\(\\\\\|.\)\{-}[^\\]"+
+
+
+" Beginners - Patterns that involve ^
+"
+syn match  hogLineComment	+^[ \t]*#.*$+	contains=hogTodo,hogCommentString,hogCommentTitle
+syn match  hogCommentTitle	'#\s*\u\a*\(\s\+\u\a*\)*:'ms=s+1 contained
+syn keyword hogTodo contained	TODO
+
+" Rule keywords
+syn match   hogARPCOpt contained "\d\+,\*,\*"
+syn match   hogARPCOpt contained "\d\+,\d\+,\*"
+syn match   hogARPCOpt contained "\d\+,\*,\d\+"
+syn match   hogARPCOpt contained "\d\+,\d\+,\d"
+syn match   hogATAGOpt contained "session"
+syn match   hogATAGOpt contained "host"
+syn match   hogATAGOpt contained "dst"
+syn match   hogATAGOpt contained "src"
+syn match   hogATAGOpt contained "seconds"
+syn match   hogATAGOpt contained "packets"
+syn match   hogATAGOpt contained "bytes"
+syn keyword hogARespOpt contained rst_snd rst_rcv rst_all skipwhite
+syn keyword hogARespOpt contained icmp_net icmp_host icmp_port icmp_all skipwhite
+syn keyword hogAReactOpt contained block warn msg skipwhite
+syn match   hogAReactOpt contained "proxy\d\+" skipwhite
+syn keyword hogAFOpt contained logto content_list skipwhite
+syn keyword hogAIPOptVal contained  eol nop ts sec lsrr lsrre satid ssrr rr skipwhite
+syn keyword hogARefGrps contained arachnids skipwhite
+syn keyword hogARefGrps contained bugtraq skipwhite
+syn keyword hogARefGrps contained cve skipwhite
+syn keyword hogSessionVal contained  printable all skipwhite
+syn match   hogAFlagOpt contained "[0FSRPAUfsrpau21]\+" skipwhite
+syn match   hogAFragOpt contained "[DRMdrm]\+" skipwhite
+"
+" Output syslog options
+" Facilities
+syn keyword hogSysFac contained LOG_AUTH LOG_AUTHPRIV LOG_DAEMON LOG_LOCAL0
+syn keyword hogSysFac contained LOG_LOCAL1 LOG_LOCAL2 LOG_LOCAL3 LOG_LOCAL4
+syn keyword hogSysFac contained LOG_LOCAL5 LOG_LOCAL6 LOG_LOCAL7 LOG_USER
+" Priorities
+syn keyword hogSysPri contained LOG_EMERG ALERT LOG_CRIT LOG_ERR
+syn keyword hogSysPri contained LOG_WARNING LOG_NOTICE LOG_INFO LOG_DEBUG
+" Options
+syn keyword hogSysOpt contained LOG_CONS LOG_NDELAY LOG_PERROR
+syn keyword hogSysOpt contained LOG_PID
+" RuleTypes
+syn keyword hogRuleType contained log pass alert activate dynamic
+
+" Output log_database arguments and parameters
+" Type of database followed by ,
+" syn keyword hogDBSQL contained mysql postgresql unixodbc
+" Parameters param=constant
+" are just various constants assigned to parameter names
+
+" Output log_database arguments and parameters
+" Type of database followed by ,
+syn keyword hogDBType contained alert log
+syn keyword hogDBSRV contained mysql postgresql unixodbc
+" Parameters param=constant
+" are just various constants assigned to parameter names
+syn keyword hogDBParam contained dbname host port user password sensor_name
+
+" Output xml arguments and parameters
+" xml args
+syn keyword hogXMLArg  contained log alert
+syn keyword hogXMLParam contained file protocol host port cert key ca server sanitize encoding detail
+"
+" hog rule handler '(.*)'
+syn region  hogAOpt contained oneline start="rpc" end=":"me=e-1 nextgroup=hogARPCOptGrp skipwhite
+syn region  hogARPCOptGrp contained oneline start="."hs=s+1 end=";"me=e-1 contains=hogARPCOpt skipwhite
+
+syn region  hogAOpt contained oneline start="tag" end=":"me=e-1 nextgroup=hogATAGOptGrp skipwhite
+syn region  hogATAGOptGrp contained oneline start="."hs=s+1 skip="," end=";"me=e-1 contains=hogATAGOpt,hogNumber skipwhite
+"
+syn region  hogAOpt contained oneline start="nocase\|sameip" end=";"me=e-1 skipwhite oneline keepend
+"
+syn region  hogAOpt contained start="resp" end=":"me=e-1 nextgroup=hogARespOpts skipwhite
+syn region  hogARespOpts contained oneline start="." end="[,;]" contains=hogARespOpt skipwhite nextgroup=hogARespOpts
+"
+syn region  hogAOpt contained start="react" end=":"me=e-1 nextgroup=hogAReactOpts skipwhite
+syn region  hogAReactOpts contained oneline start="." end="[,;]" contains=hogAReactOpt skipwhite nextgroup=hogAReactOpts
+
+syn region  hogAOpt contained oneline start="depth\|seq\|ttl\|ack\|icmp_seq\|activates\|activated_by\|dsize\|icode\|icmp_id\|count\|itype\|tos\|id\|offset" end=":"me=e-1 nextgroup=hogANOptGrp skipwhite
+syn region  hogANOptGrp contained oneline start="."hs=s+1 end=";"me=e-1 contains=hogNumber skipwhite oneline keepend
+
+syn region  hogAOpt contained oneline start="classtype" end=":"me=e-1 nextgroup=hogAFileGrp skipwhite
+
+syn region  hogAOpt contained oneline start="regex\|msg\|content" end=":"me=e-1 nextgroup=hogAStrGrp skipwhite
+"syn region  hogAStrGrp contained oneline start=+:\s*"+hs=s+1 skip="\\;" end=+"\s*;+he=s-1 contains=hogString skipwhite oneline keepend
+syn region  hogAStrGrp contained oneline start=+:\s*"\|:"+hs=s+1 skip="\\;" end=+"\s*;+he=s-1 contains=hogString skipwhite oneline keepend
+
+syn region  hogAOpt contained oneline start="logto\|content-list" end=":"me=e-1 nextgroup=hogAFileGrp skipwhite
+syn region  hogAFileGrp contained oneline start="."hs=s+1 end=";"me=e-1 contains=hogFileName skipwhite
+
+syn region  hogAOpt contained oneline start="reference" end=":"me=e-1 nextgroup=hogARefGrp skipwhite
+syn region  hogARefGrp contained oneline start="."hs=s+1 end=","me=e-1 contains=hogARefGrps nextgroup=hogARefName skipwhite
+syn region  hogARefName contained oneline start="."hs=s+1 end=";"me=e-1 contains=hogString,hogFileName,hogNumber skipwhite
+
+syn region  hogAOpt contained oneline start="flags" end=":"he=s-1 nextgroup=hogAFlagOpt skipwhite oneline keepend
+
+syn region  hogAOpt contained oneline start="fragbits" end=":"he=s-1 nextgroup=hogAFlagOpt skipwhite oneline keepend
+
+syn region  hogAOpt contained oneline start="ipopts" end=":"he=s-1 nextgroup=hogAIPOptVal skipwhite oneline keepend
+
+"syn region  hogAOpt contained oneline start="." end=":"he=s-1 contains=hogAFOpt nextgroup=hogFileName skipwhite
+
+syn region  hogAOpt contained oneline start="session" end=":"he=s-1 nextgroup=hogSessionVal skipwhite
+
+syn match   nothing  "$"
+syn region  hogRules oneline  contains=nothing start='$' end="$"
+syn region  hogRules oneline  contains=hogRule start='('ms=s+1 end=")\s*$" skipwhite
+syn region  hogRule  contained oneline start="." skip="\\;" end=";"he=s-1 contains=hogAOpts, skipwhite keepend
+"syn region  hogAOpts contained oneline start="." end="[;]"he=s-1 contains=hogAOpt skipwhite
+syn region  hogAOpts contained oneline start="." end="[;]"me=e-1 contains=hogAOpt skipwhite
+
+
+" ruletype command
+syn keyword hogRTypeStart skipwhite ruletype nextgroup=hogRuleName skipwhite
+syn region  hogRuleName  contained  start="." end="\s" contains=hogFileName  nextgroup=hogRTypeRegion
+" type ruletype sub type
+syn region hogRtypeRegion contained start="{" end="}" nextgroup=hogRTypeStart
+syn keyword hogRTypeStart skipwhite type nextgroup=hogRuleTypes skipwhite
+syn region  hogRuleTypes  contained  start="." end="\s" contains=hogRuleType nextgroup=hogOutStart
+
+
+" var command
+syn keyword hogVarStart skipwhite var nextgroup=hogVarIdent skipwhite
+syn region  hogVarIdent contained  start="."hs=e+1 end="\s\+"he=s-1 contains=hogEnvvar nextgroup=hogVarRegion skipwhite
+syn region  hogVarRegion  contained  oneline  start="." contains=hogIPaddr,hogEnvvar,hogNumber,hogString,hogFileName end="$"he=s-1 keepend skipwhite
+
+" config command
+syn keyword hogConfigStart config skipwhite nextgroup=hogConfigType
+syn match hogConfigType contained "\<classification\>" nextgroup=hogConfigTypeRegion skipwhite
+syn region  hogConfigTypeRegion contained oneline	start=":"ms=s+1 end="$" contains=hogNumber,hogText keepend skipwhite
+
+
+" include command
+syn keyword hogIncStart	include  skipwhite nextgroup=hogIncRegion
+syn region  hogIncRegion  contained  oneline  start="\>" contains=hogFileName,hogEnvvar end="$" keepend
+
+" preprocessor command
+" http_decode, minfrag, portscan[-ignorehosts]
+syn keyword hogPPrStart	preprocessor  skipwhite nextgroup=hogPPr
+syn match hogPPr   contained  "\<spade\>" nextgroup=hogPPrRegion skipwhite
+syn match hogPPr   contained  "\<spade-homenet\>" nextgroup=hogPPrRegion skipwhite
+syn match hogPPr   contained  "\<spade-threshlearn\>" nextgroup=hogPPrRegion skipwhite
+syn match hogPPr   contained  "\<spade-adapt\>" nextgroup=hogPPrRegion skipwhite
+syn match hogPPr   contained  "\<spade-adapt2\>" nextgroup=hogPPrRegion skipwhite
+syn match hogPPr   contained  "\<spade-adapt3\>" nextgroup=hogPPrRegion skipwhite
+syn match hogPPr   contained  "\<spade-survey\>" nextgroup=hogPPrRegion skipwhite
+syn match hogPPr   contained  "\<defrag\>" nextgroup=hogPPrRegion skipwhite
+syn match hogPPr   contained  "\<telnet_decode\>" nextgroup=hogPPrRegion skipwhite
+syn match hogPPr   contained  "\<rpc_decode\>" nextgroup=hogPPrRegion skipwhite
+syn match hogPPr   contained  "\<bo\>" nextgroup=hogPPrRegion skipwhite
+syn match hogPPr   contained  "\<stream\>" nextgroup=hogStreamRegion skipwhite
+syn match hogPPr   contained  "\<stream2\>" nextgroup=hogStreamRegion skipwhite
+syn match hogPPr   contained  "\<stream3\>" nextgroup=hogStreamRegion skipwhite
+syn match hogPPr   contained  "\<http_decode\>" nextgroup=hogPPrRegion skipwhite
+syn match hogPPr   contained  "\<minfrag\>" nextgroup=hogPPrRegion skipwhite
+syn match hogPPr     contained "\<portscan[-ignorehosts]*\>" nextgroup=hogPPrRegion skipwhite
+syn region  hogPPrRegion contained oneline	start="$" end="$" keepend
+syn region  hogPPrRegion contained oneline	start=":" end="$" contains=hogNumber,hogIPaddr,hogEnvvar,hogFileName keepend
+syn keyword hogStreamArgs contained timeout ports maxbytes
+syn region hogStreamRegion contained oneline start=":" end="$" contains=hogStreamArgs,hogNumber
+
+" output command
+syn keyword hogOutStart	output  nextgroup=hogOut skipwhite
+"
+" alert_syslog
+syn match hogOut   contained  "\<alert_syslog\>" nextgroup=hogSyslogRegion skipwhite
+syn region hogSyslogRegion  contained start=":" end="$" contains=hogSysFac,hogSysPri,hogSysOpt,hogEnvvar oneline skipwhite keepend
+"
+" alert_fast (full,smb,unixsock, and tcpdump)
+syn match hogOut   contained  "\<alert_fast\|alert_full\|alert_smb\|alert_unixsock\|log_tcpdump\>" nextgroup=hogLogFileRegion skipwhite
+syn region hogLogFileRegion  contained start=":" end="$" contains=hogFileName,hogEnvvar oneline skipwhite keepend
+"
+" database
+syn match hogOut  contained "\<database\>" nextgroup=hogDBTypes skipwhite
+syn region hogDBTypes contained start=":" end="," contains=hogDBType,hogEnvvar nextgroup=hogDBSRVs skipwhite
+syn region hogDBSRVs contained start="\s\+" end="," contains=hogDBSRV nextgroup=hogDBParams skipwhite
+syn region hogDBParams contained start="." end="="me=e-1 contains=hogDBParam  nextgroup=hogDBValues
+syn region hogDBValues contained start="." end="\>" contains=hogNumber,hogEnvvar,hogAscii nextgroup=hogDBParams oneline skipwhite
+syn match hogAscii contained "\<\a\+"
+"
+" log_tcpdump
+syn match hogOut   contained  "\<log_tcpdump\>" nextgroup=hogLogRegion skipwhite
+syn region  hogLogRegion  oneline	start=":" skipwhite end="$" contains=hogEnvvar,hogFileName keepend
+"
+" xml
+syn keyword hogXMLTrans contained http https tcp iap
+syn match hogOut     contained "\<xml\>" nextgroup=hogXMLRegion skipwhite
+syn region hogXMLRegion contained start=":" end="," contains=hogXMLArg,hogEnvvar nextgroup=hogXMLParams skipwhite
+"syn region hogXMLParams contained start="." end="="me=e-1 contains=hogXMLProto nextgroup=hogXMLProtos
+"syn region hogXMLProtos contained start="." end="\>" contains=hogXMLTrans nextgroup=hogXMLParams
+syn region hogXMLParams contained start="." end="="me=e-1 contains=hogXMLParam  nextgroup=hogXMLValue
+syn region hogXMLValue contained start="." end="\>" contains=hogNumber,hogIPaddr,hogEnvvar,hogAscii,hogFileName nextgroup=hogXMLParams oneline skipwhite keepend
+"
+" Filename
+syn match   hogFileName  contained "[-./[:alnum:]_~]\+"
+syn match   hogFileName  contained "[-./[:alnum:]_~]\+"
+" IP address
+syn match   hogIPaddr   "\<\d\{1,3}\.\d\{1,3}\.\d\{1,3}\.\d\{1,3}\>"
+syn match   hogIPaddr   "\<\d\{1,3}\.\d\{1,3}\.\d\{1,3}\.\d\{1,3}/\d\{1,2}\>"
+
+syn keyword hogProto	tcp TCP ICMP icmp udp UDP
+
+" hog alert address port pairs
+" hog IPaddresses
+syn match   hogIPaddrAndPort contained	"\<\d\{1,3}\.\d\{1,3}\.\d\{1,3}\.\d\{1,3}\>" skipwhite			nextgroup=hogPort
+syn match   hogIPaddrAndPort contained	"\<\d\{1,3}\.\d\{1,3}\.\d\{1,3}\.\d\{1,3}/\d\{1,2}\>" skipwhite		nextgroup=hogPort
+syn match   hogIPaddrAndPort contained "\<any\>" skipwhite nextgroup=hogPort
+syn match hogIPaddrAndPort contained	 "\$\I\i*" nextgroup=hogPort skipwhite
+syn match hogIPaddrAndPort contained     "\${\I\i*}" nextgroup=hogPort skipwhite
+"syn match   hogPort contained "[\!]\=[\:]\=\d\+L\=\>" skipwhite
+syn match   hogPort contained "[\:]\=\d\+\>"
+syn match   hogPort contained "[\!]\=\<any\>" skipwhite
+syn match   hogPort contained "[\!]\=\d\+L\=:\d\+L\=\>" skipwhite
+
+" action commands
+syn keyword hog7Functions activate skipwhite nextgroup=hogActRegion
+syn keyword hog7Functions dynamic skipwhite nextgroup=hogActRegion
+syn keyword hogActStart alert skipwhite nextgroup=hogActRegion
+syn keyword hogActStart log skipwhite nextgroup=hogActRegion
+syn keyword hogActStart pass skipwhite nextgroup=hogActRegion
+
+syn region hogActRegion contained oneline start="tcp\|TCP\|udp\|UDP\|icmp\|ICMP" end="\s\+"me=s-1 nextgroup=hogActSource oneline keepend skipwhite
+syn region hogActSource contained oneline contains=hogIPaddrAndPort start="\s\+"ms=e+1 end="->\|<>"me=e-2  oneline keepend skipwhite nextgroup=hogActDest
+syn region hogActDest contained oneline contains=hogIPaddrAndPort start="->\|<>" end="$"  oneline keepend
+syn region hogActDest contained oneline contains=hogIPaddrAndPort start="->\|<>" end="("me=e-1  oneline keepend skipwhite nextgroup=hogRules
+
+
+" ====================
+if version >= 508 || !exists("did_hog_syn_inits")
+  if version < 508
+    let did_hog_syn_inits = 1
+    command -nargs=+ HiLink hi link <args>
+  else
+    command -nargs=+ HiLink hi def link <args>
+  endif
+" The default methods for highlighting.  Can be overridden later
+  HiLink hogComment		Comment
+  HiLink hogLineComment		Comment
+  HiLink hogAscii		Constant
+  HiLink hogCommentString	Constant
+  HiLink hogFileName		Constant
+  HiLink hogIPaddr		Constant
+  HiLink hogNotPatSep		Constant
+  HiLink hogNumber		Constant
+  HiLink hogText		Constant
+  HiLink hogString		Constant
+  HiLink hogSysFac		Constant
+  HiLink hogSysOpt		Constant
+  HiLink hogSysPri		Constant
+"  HiLink hogAStrGrp		Error
+  HiLink hogJunk		Error
+  HiLink hogEnvvar		Identifier
+  HiLink hogIPaddrAndPort	Identifier
+  HiLink hogVarIdent		Identifier
+  HiLink hogATAGOpt		PreProc
+  HiLink hogAIPOptVal		PreProc
+  HiLink hogARespOpt		PreProc
+  HiLink hogAReactOpt		PreProc
+  HiLink hogAFlagOpt		PreProc
+  HiLink hogAFragOpt		PreProc
+  HiLink hogCommentTitle	PreProc
+  HiLink hogDBType		PreProc
+  HiLink hogDBSRV		PreProc
+  HiLink hogPort		PreProc
+  HiLink hogARefGrps		PreProc
+  HiLink hogSessionVal		PreProc
+  HiLink hogXMLArg		PreProc
+  HiLink hogARPCOpt		PreProc
+  HiLink hogPatSep		Special
+  HiLink hog7Functions		Statement
+  HiLink hogActStart		Statement
+  HiLink hogIncStart		Statement
+  HiLink hogConfigStart		Statement
+  HiLink hogOutStart		Statement
+  HiLink hogPPrStart		Statement
+  HiLink hogVarStart		Statement
+  HiLink hogRTypeStart		Statement
+  HiLink hogTodo		Todo
+  HiLink hogRuleType		Type
+  HiLink hogAFOpt		Type
+  HiLink hogANoVal		Type
+  HiLink hogAStrOpt		Type
+  HiLink hogANOpt		Type
+  HiLink hogAOpt		Type
+  HiLink hogDBParam		Type
+  HiLink hogStreamArgs		Type
+  HiLink hogOut			Type
+  HiLink hogPPr			Type
+  HiLink  hogConfigType		Type
+  HiLink hogActRegion		Type
+  HiLink hogProto		Type
+  HiLink hogXMLParam		Type
+  HiLink resp			Todo
+  HiLink cLabel			Label
+  delcommand HiLink
+endif
+
+let b:current_syntax = "hog"
+
+" hog: cpw=59
--- /dev/null
+++ b/lib/vimfiles/syntax/html.vim
@@ -1,0 +1,292 @@
+" Vim syntax file
+" Language:	HTML
+" Maintainer:	Claudio Fleiner <claudio@fleiner.com>
+" URL:		http://www.fleiner.com/vim/syntax/html.vim
+" Last Change:  2006 Jun 19
+
+" Please check :help html.vim for some comments and a description of the options
+
+" For version 5.x: Clear all syntax items
+" For version 6.x: Quit when a syntax file was already loaded
+if !exists("main_syntax")
+  if version < 600
+    syntax clear
+  elseif exists("b:current_syntax")
+    finish
+  endif
+  let main_syntax = 'html'
+endif
+
+" don't use standard HiLink, it will not work with included syntax files
+if version < 508
+  command! -nargs=+ HtmlHiLink hi link <args>
+else
+  command! -nargs=+ HtmlHiLink hi def link <args>
+endif
+
+syntax spell toplevel
+
+syn case ignore
+
+" mark illegal characters
+syn match htmlError "[<>&]"
+
+
+" tags
+syn region  htmlString   contained start=+"+ end=+"+ contains=htmlSpecialChar,javaScriptExpression,@htmlPreproc
+syn region  htmlString   contained start=+'+ end=+'+ contains=htmlSpecialChar,javaScriptExpression,@htmlPreproc
+syn match   htmlValue    contained "=[\t ]*[^'" \t>][^ \t>]*"hs=s+1   contains=javaScriptExpression,@htmlPreproc
+syn region  htmlEndTag             start=+</+      end=+>+ contains=htmlTagN,htmlTagError
+syn region  htmlTag                start=+<[^/]+   end=+>+ contains=htmlTagN,htmlString,htmlArg,htmlValue,htmlTagError,htmlEvent,htmlCssDefinition,@htmlPreproc,@htmlArgCluster
+syn match   htmlTagN     contained +<\s*[-a-zA-Z0-9]\++hs=s+1 contains=htmlTagName,htmlSpecialTagName,@htmlTagNameCluster
+syn match   htmlTagN     contained +</\s*[-a-zA-Z0-9]\++hs=s+2 contains=htmlTagName,htmlSpecialTagName,@htmlTagNameCluster
+syn match   htmlTagError contained "[^>]<"ms=s+1
+
+
+" tag names
+syn keyword htmlTagName contained address applet area a base basefont
+syn keyword htmlTagName contained big blockquote br caption center
+syn keyword htmlTagName contained cite code dd dfn dir div dl dt font
+syn keyword htmlTagName contained form hr html img
+syn keyword htmlTagName contained input isindex kbd li link map menu
+syn keyword htmlTagName contained meta ol option param pre p samp span
+syn keyword htmlTagName contained select small strike sub sup
+syn keyword htmlTagName contained table td textarea th tr tt ul var xmp
+syn match htmlTagName contained "\<\(b\|i\|u\|h[1-6]\|em\|strong\|head\|body\|title\)\>"
+
+" new html 4.0 tags
+syn keyword htmlTagName contained abbr acronym bdo button col label
+syn keyword htmlTagName contained colgroup del fieldset iframe ins legend
+syn keyword htmlTagName contained object optgroup q s tbody tfoot thead
+
+" legal arg names
+syn keyword htmlArg contained action
+syn keyword htmlArg contained align alink alt archive background bgcolor
+syn keyword htmlArg contained border bordercolor cellpadding
+syn keyword htmlArg contained cellspacing checked class clear code codebase color
+syn keyword htmlArg contained cols colspan content coords enctype face
+syn keyword htmlArg contained gutter height hspace id
+syn keyword htmlArg contained link lowsrc marginheight
+syn keyword htmlArg contained marginwidth maxlength method name prompt
+syn keyword htmlArg contained rel rev rows rowspan scrolling selected shape
+syn keyword htmlArg contained size src start target text type url
+syn keyword htmlArg contained usemap ismap valign value vlink vspace width wrap
+syn match   htmlArg contained "\<\(http-equiv\|href\|title\)="me=e-1
+
+" Netscape extensions
+syn keyword htmlTagName contained frame noframes frameset nobr blink
+syn keyword htmlTagName contained layer ilayer nolayer spacer
+syn keyword htmlArg     contained frameborder noresize pagex pagey above below
+syn keyword htmlArg     contained left top visibility clip id noshade
+syn match   htmlArg     contained "\<z-index\>"
+
+" Microsoft extensions
+syn keyword htmlTagName contained marquee
+
+" html 4.0 arg names
+syn match   htmlArg contained "\<\(accept-charset\|label\)\>"
+syn keyword htmlArg contained abbr accept accesskey axis char charoff charset
+syn keyword htmlArg contained cite classid codetype compact data datetime
+syn keyword htmlArg contained declare defer dir disabled for frame
+syn keyword htmlArg contained headers hreflang lang language longdesc
+syn keyword htmlArg contained multiple nohref nowrap object profile readonly
+syn keyword htmlArg contained rules scheme scope span standby style
+syn keyword htmlArg contained summary tabindex valuetype version
+
+" special characters
+syn match htmlSpecialChar "&#\=[0-9A-Za-z]\{1,8};"
+
+" Comments (the real ones or the old netscape ones)
+if exists("html_wrong_comments")
+  syn region htmlComment                start=+<!--+    end=+--\s*>+
+else
+  syn region htmlComment                start=+<!+      end=+>+   contains=htmlCommentPart,htmlCommentError
+  syn match  htmlCommentError contained "[^><!]"
+  syn region htmlCommentPart  contained start=+--+      end=+--\s*+  contains=@htmlPreProc
+endif
+syn region htmlComment                  start=+<!DOCTYPE+ keepend end=+>+
+
+" server-parsed commands
+syn region htmlPreProc start=+<!--#+ end=+-->+ contains=htmlPreStmt,htmlPreError,htmlPreAttr
+syn match htmlPreStmt contained "<!--#\(config\|echo\|exec\|fsize\|flastmod\|include\|printenv\|set\|if\|elif\|else\|endif\|geoguide\)\>"
+syn match htmlPreError contained "<!--#\S*"ms=s+4
+syn match htmlPreAttr contained "\w\+=[^"]\S\+" contains=htmlPreProcAttrError,htmlPreProcAttrName
+syn region htmlPreAttr contained start=+\w\+="+ skip=+\\\\\|\\"+ end=+"+ contains=htmlPreProcAttrName keepend
+syn match htmlPreProcAttrError contained "\w\+="he=e-1
+syn match htmlPreProcAttrName contained "\(expr\|errmsg\|sizefmt\|timefmt\|var\|cgi\|cmd\|file\|virtual\|value\)="he=e-1
+
+if !exists("html_no_rendering")
+  " rendering
+  syn cluster htmlTop contains=@Spell,htmlTag,htmlEndTag,htmlSpecialChar,htmlPreProc,htmlComment,htmlLink,javaScript,@htmlPreproc
+
+  syn region htmlBold start="<b\>" end="</b>"me=e-4 contains=@htmlTop,htmlBoldUnderline,htmlBoldItalic
+  syn region htmlBold start="<strong\>" end="</strong>"me=e-9 contains=@htmlTop,htmlBoldUnderline,htmlBoldItalic
+  syn region htmlBoldUnderline contained start="<u\>" end="</u>"me=e-4 contains=@htmlTop,htmlBoldUnderlineItalic
+  syn region htmlBoldItalic contained start="<i\>" end="</i>"me=e-4 contains=@htmlTop,htmlBoldItalicUnderline
+  syn region htmlBoldItalic contained start="<em\>" end="</em>"me=e-5 contains=@htmlTop,htmlBoldItalicUnderline
+  syn region htmlBoldUnderlineItalic contained start="<i\>" end="</i>"me=e-4 contains=@htmlTop
+  syn region htmlBoldUnderlineItalic contained start="<em\>" end="</em>"me=e-5 contains=@htmlTop
+  syn region htmlBoldItalicUnderline contained start="<u\>" end="</u>"me=e-4 contains=@htmlTop,htmlBoldUnderlineItalic
+
+  syn region htmlUnderline start="<u\>" end="</u>"me=e-4 contains=@htmlTop,htmlUnderlineBold,htmlUnderlineItalic
+  syn region htmlUnderlineBold contained start="<b\>" end="</b>"me=e-4 contains=@htmlTop,htmlUnderlineBoldItalic
+  syn region htmlUnderlineBold contained start="<strong\>" end="</strong>"me=e-9 contains=@htmlTop,htmlUnderlineBoldItalic
+  syn region htmlUnderlineItalic contained start="<i\>" end="</i>"me=e-4 contains=@htmlTop,htmlUnderlineItalicBold
+  syn region htmlUnderlineItalic contained start="<em\>" end="</em>"me=e-5 contains=@htmlTop,htmlUnderlineItalicBold
+  syn region htmlUnderlineItalicBold contained start="<b\>" end="</b>"me=e-4 contains=@htmlTop
+  syn region htmlUnderlineItalicBold contained start="<strong\>" end="</strong>"me=e-9 contains=@htmlTop
+  syn region htmlUnderlineBoldItalic contained start="<i\>" end="</i>"me=e-4 contains=@htmlTop
+  syn region htmlUnderlineBoldItalic contained start="<em\>" end="</em>"me=e-5 contains=@htmlTop
+
+  syn region htmlItalic start="<i\>" end="</i>"me=e-4 contains=@htmlTop,htmlItalicBold,htmlItalicUnderline
+  syn region htmlItalic start="<em\>" end="</em>"me=e-5 contains=@htmlTop
+  syn region htmlItalicBold contained start="<b\>" end="</b>"me=e-4 contains=@htmlTop,htmlItalicBoldUnderline
+  syn region htmlItalicBold contained start="<strong\>" end="</strong>"me=e-9 contains=@htmlTop,htmlItalicBoldUnderline
+  syn region htmlItalicBoldUnderline contained start="<u\>" end="</u>"me=e-4 contains=@htmlTop
+  syn region htmlItalicUnderline contained start="<u\>" end="</u>"me=e-4 contains=@htmlTop,htmlItalicUnderlineBold
+  syn region htmlItalicUnderlineBold contained start="<b\>" end="</b>"me=e-4 contains=@htmlTop
+  syn region htmlItalicUnderlineBold contained start="<strong\>" end="</strong>"me=e-9 contains=@htmlTop
+
+  syn region htmlLink start="<a\>\_[^>]*\<href\>" end="</a>"me=e-4 contains=@Spell,htmlTag,htmlEndTag,htmlSpecialChar,htmlPreProc,htmlComment,javaScript,@htmlPreproc
+  syn region htmlH1 start="<h1\>" end="</h1>"me=e-5 contains=@htmlTop
+  syn region htmlH2 start="<h2\>" end="</h2>"me=e-5 contains=@htmlTop
+  syn region htmlH3 start="<h3\>" end="</h3>"me=e-5 contains=@htmlTop
+  syn region htmlH4 start="<h4\>" end="</h4>"me=e-5 contains=@htmlTop
+  syn region htmlH5 start="<h5\>" end="</h5>"me=e-5 contains=@htmlTop
+  syn region htmlH6 start="<h6\>" end="</h6>"me=e-5 contains=@htmlTop
+  syn region htmlHead start="<head\>" end="</head>"me=e-7 end="<body\>"me=e-5 end="<h[1-6]\>"me=e-3 contains=htmlTag,htmlEndTag,htmlSpecialChar,htmlPreProc,htmlComment,htmlLink,htmlTitle,javaScript,cssStyle,@htmlPreproc
+  syn region htmlTitle start="<title\>" end="</title>"me=e-8 contains=htmlTag,htmlEndTag,htmlSpecialChar,htmlPreProc,htmlComment,javaScript,@htmlPreproc
+endif
+
+syn keyword htmlTagName         contained noscript
+syn keyword htmlSpecialTagName  contained script style
+if main_syntax != 'java' || exists("java_javascript")
+  " JAVA SCRIPT
+  syn include @htmlJavaScript syntax/javascript.vim
+  unlet b:current_syntax
+  syn region  javaScript start=+<script[^>]*>+ keepend end=+</script>+me=s-1 contains=@htmlJavaScript,htmlCssStyleComment,htmlScriptTag,@htmlPreproc
+  syn region  htmlScriptTag     contained start=+<script+ end=+>+       contains=htmlTagN,htmlString,htmlArg,htmlValue,htmlTagError,htmlEvent
+  HtmlHiLink htmlScriptTag htmlTag
+
+  " html events (i.e. arguments that include javascript commands)
+  if exists("html_extended_events")
+    syn region htmlEvent        contained start=+\<on\a\+\s*=[\t ]*'+ end=+'+ contains=htmlEventSQ
+    syn region htmlEvent        contained start=+\<on\a\+\s*=[\t ]*"+ end=+"+ contains=htmlEventDQ
+  else
+    syn region htmlEvent        contained start=+\<on\a\+\s*=[\t ]*'+ end=+'+ keepend contains=htmlEventSQ
+    syn region htmlEvent        contained start=+\<on\a\+\s*=[\t ]*"+ end=+"+ keepend contains=htmlEventDQ
+  endif
+  syn region htmlEventSQ        contained start=+'+ms=s+1 end=+'+me=s-1 contains=@htmlJavaScript
+  syn region htmlEventDQ        contained start=+"+ms=s+1 end=+"+me=s-1 contains=@htmlJavaScript
+  HtmlHiLink htmlEventSQ htmlEvent
+  HtmlHiLink htmlEventDQ htmlEvent
+
+  " a javascript expression is used as an arg value
+  syn region  javaScriptExpression contained start=+&{+ keepend end=+};+ contains=@htmlJavaScript,@htmlPreproc
+endif
+
+if main_syntax != 'java' || exists("java_vb")
+  " VB SCRIPT
+  syn include @htmlVbScript syntax/vb.vim
+  unlet b:current_syntax
+  syn region  javaScript start=+<script [^>]*language *=[^>]*vbscript[^>]*>+ keepend end=+</script>+me=s-1 contains=@htmlVbScript,htmlCssStyleComment,htmlScriptTag,@htmlPreproc
+endif
+
+syn cluster htmlJavaScript      add=@htmlPreproc
+
+if main_syntax != 'java' || exists("java_css")
+  " embedded style sheets
+  syn keyword htmlArg           contained media
+  syn include @htmlCss syntax/css.vim
+  unlet b:current_syntax
+  syn region cssStyle start=+<style+ keepend end=+</style>+ contains=@htmlCss,htmlTag,htmlEndTag,htmlCssStyleComment,@htmlPreproc
+  syn match htmlCssStyleComment contained "\(<!--\|-->\)"
+  syn region htmlCssDefinition matchgroup=htmlArg start='style="' keepend matchgroup=htmlString end='"' contains=css.*Attr,css.*Prop,cssComment,cssLength,cssColor,cssURL,cssImportant,cssError,cssString,@htmlPreproc
+  HtmlHiLink htmlStyleArg htmlString
+endif
+
+if main_syntax == "html"
+  " synchronizing (does not always work if a comment includes legal
+  " html tags, but doing it right would mean to always start
+  " at the first line, which is too slow)
+  syn sync match htmlHighlight groupthere NONE "<[/a-zA-Z]"
+  syn sync match htmlHighlight groupthere javaScript "<script"
+  syn sync match htmlHighlightSkip "^.*['\"].*$"
+  syn sync minlines=10
+endif
+
+" The default highlighting.
+if version >= 508 || !exists("did_html_syn_inits")
+  if version < 508
+    let did_html_syn_inits = 1
+  endif
+  HtmlHiLink htmlTag                     Function
+  HtmlHiLink htmlEndTag                  Identifier
+  HtmlHiLink htmlArg                     Type
+  HtmlHiLink htmlTagName                 htmlStatement
+  HtmlHiLink htmlSpecialTagName          Exception
+  HtmlHiLink htmlValue                     String
+  HtmlHiLink htmlSpecialChar             Special
+  
+  if !exists("html_no_rendering")
+    HtmlHiLink htmlH1                      Title
+    HtmlHiLink htmlH2                      htmlH1
+    HtmlHiLink htmlH3                      htmlH2
+    HtmlHiLink htmlH4                      htmlH3
+    HtmlHiLink htmlH5                      htmlH4
+    HtmlHiLink htmlH6                      htmlH5
+    HtmlHiLink htmlHead                    PreProc
+    HtmlHiLink htmlTitle                   Title
+    HtmlHiLink htmlBoldItalicUnderline     htmlBoldUnderlineItalic
+    HtmlHiLink htmlUnderlineBold           htmlBoldUnderline
+    HtmlHiLink htmlUnderlineItalicBold     htmlBoldUnderlineItalic
+    HtmlHiLink htmlUnderlineBoldItalic     htmlBoldUnderlineItalic
+    HtmlHiLink htmlItalicUnderline         htmlUnderlineItalic
+    HtmlHiLink htmlItalicBold              htmlBoldItalic
+    HtmlHiLink htmlItalicBoldUnderline     htmlBoldUnderlineItalic
+    HtmlHiLink htmlItalicUnderlineBold     htmlBoldUnderlineItalic
+    HtmlHiLink htmlLink                    Underlined
+    if !exists("html_my_rendering")
+      hi def htmlBold                term=bold cterm=bold gui=bold
+      hi def htmlBoldUnderline       term=bold,underline cterm=bold,underline gui=bold,underline
+      hi def htmlBoldItalic          term=bold,italic cterm=bold,italic gui=bold,italic
+      hi def htmlBoldUnderlineItalic term=bold,italic,underline cterm=bold,italic,underline gui=bold,italic,underline
+      hi def htmlUnderline           term=underline cterm=underline gui=underline
+      hi def htmlUnderlineItalic     term=italic,underline cterm=italic,underline gui=italic,underline
+      hi def htmlItalic              term=italic cterm=italic gui=italic
+    endif
+  endif
+  
+  HtmlHiLink htmlPreStmt            PreProc
+  HtmlHiLink htmlPreError           Error
+  HtmlHiLink htmlPreProc            PreProc
+  HtmlHiLink htmlPreAttr            String
+  HtmlHiLink htmlPreProcAttrName    PreProc
+  HtmlHiLink htmlPreProcAttrError   Error
+  HtmlHiLink htmlSpecial            Special
+  HtmlHiLink htmlSpecialChar        Special
+  HtmlHiLink htmlString             String
+  HtmlHiLink htmlStatement          Statement
+  HtmlHiLink htmlComment            Comment
+  HtmlHiLink htmlCommentPart        Comment
+  HtmlHiLink htmlValue              String
+  HtmlHiLink htmlCommentError       htmlError
+  HtmlHiLink htmlTagError           htmlError
+  HtmlHiLink htmlEvent              javaScript
+  HtmlHiLink htmlError              Error
+  
+  HtmlHiLink javaScript             Special
+  HtmlHiLink javaScriptExpression   javaScript
+  HtmlHiLink htmlCssStyleComment    Comment
+  HtmlHiLink htmlCssDefinition      Special
+endif
+
+delcommand HtmlHiLink
+
+let b:current_syntax = "html"
+
+if main_syntax == 'html'
+  unlet main_syntax
+endif
+
+" vim: ts=8
--- /dev/null
+++ b/lib/vimfiles/syntax/htmlcheetah.vim
@@ -1,0 +1,32 @@
+" Vim syntax file
+" Language:	HTML with Cheetah tags
+" Maintainer:	Max Ischenko <mfi@ukr.net>
+" Last Change: 2003-05-11
+
+" For version 5.x: Clear all syntax items
+" For version 6.x: Quit when a syntax file was already loaded
+if version < 600
+  syntax clear
+elseif exists("b:current_syntax")
+  finish
+endif
+
+if !exists("main_syntax")
+  let main_syntax = 'html'
+endif
+
+if version < 600
+  so <sfile>:p:h/cheetah.vim
+  so <sfile>:p:h/html.vim
+else
+  runtime! syntax/cheetah.vim
+  runtime! syntax/html.vim
+  unlet b:current_syntax
+endif
+
+syntax cluster htmlPreproc add=cheetahPlaceHolder
+syntax cluster htmlString add=cheetahPlaceHolder
+
+let b:current_syntax = "htmlcheetah"
+
+
--- /dev/null
+++ b/lib/vimfiles/syntax/htmldjango.vim
@@ -1,0 +1,34 @@
+" Vim syntax file
+" Language:	Django HTML template
+" Maintainer:	Dave Hodder <dmh@dmh.org.uk>
+" Last Change:	2007 Jan 26
+
+" For version 5.x: Clear all syntax items
+" For version 6.x: Quit when a syntax file was already loaded
+if version < 600
+  syntax clear
+elseif exists("b:current_syntax")
+  finish
+endif
+
+if !exists("main_syntax")
+  let main_syntax = 'html'
+endif
+
+if version < 600
+  so <sfile>:p:h/django.vim
+  so <sfile>:p:h/html.vim
+else
+  runtime! syntax/django.vim
+  runtime! syntax/html.vim
+  unlet b:current_syntax
+endif
+
+syn cluster djangoBlocks add=djangoTagBlock,djangoVarBlock,djangoComment,djangoComBlock
+
+syn region djangoTagBlock start="{%" end="%}" contains=djangoStatement,djangoFilter,djangoArgument,djangoTagError display containedin=ALLBUT,@djangoBlocks
+syn region djangoVarBlock start="{{" end="}}" contains=djangoFilter,djangoArgument,djangoVarError display containedin=ALLBUT,@djangoBlocks
+syn region djangoComment start="{%\s*comment\s*%}" end="{%\s*endcomment\s*%}" contains=djangoTodo containedin=ALLBUT,@djangoBlocks
+syn region djangoComBlock start="{#" end="#}" contains=djangoTodo containedin=ALLBUT,@djangoBlocks
+
+let b:current_syntax = "htmldjango"
--- /dev/null
+++ b/lib/vimfiles/syntax/htmlm4.vim
@@ -1,0 +1,41 @@
+" Vim syntax file
+" Language:	HTML and M4
+" Maintainer:	Claudio Fleiner <claudio@fleiner.com>
+" URL:		http://www.fleiner.com/vim/syntax/htmlm4.vim
+" Last Change:	2001 Apr 30
+
+" For version 5.x: Clear all syntax items
+" For version 6.x: Quit when a syntax file was already loaded
+if version < 600
+  syntax clear
+elseif exists("b:current_syntax")
+  finish
+endif
+
+" we define it here so that included files can test for it
+if !exists("main_syntax")
+  let main_syntax='htmlm4'
+endif
+
+if version < 600
+  so <sfile>:p:h/html.vim
+else
+  runtime! syntax/html.vim
+endif
+unlet b:current_syntax
+syn case match
+
+if version < 600
+  so <sfile>:p:h/m4.vim
+else
+  runtime! syntax/m4.vim
+endif
+unlet b:current_syntax
+syn cluster htmlPreproc add=@m4Top
+syn cluster m4StringContents add=htmlTag,htmlEndTag
+
+let b:current_syntax = "htmlm4"
+
+if main_syntax == 'htmlm4'
+  unlet main_syntax
+endif
--- /dev/null
+++ b/lib/vimfiles/syntax/htmlos.vim
@@ -1,0 +1,166 @@
+" Vim syntax file
+" Language:	HTML/OS by Aestiva
+" Maintainer:	Jason Rust <jrust@westmont.edu>
+" URL:		http://www.rustyparts.com/vim/syntax/htmlos.vim
+" Info:		http://www.rustyparts.com/scripts.php
+" Last Change:	2003 May 11
+"
+
+" For version 5.x: Clear all syntax items
+" For version 6.x: Quit when a syntax file was already loaded
+if version < 600
+  syntax clear
+elseif exists("b:current_syntax")
+  finish
+endif
+
+if !exists("main_syntax")
+  let main_syntax = 'htmlos'
+endif
+
+if version < 600
+  so <sfile>:p:h/html.vim
+else
+  runtime! syntax/html.vim
+  unlet b:current_syntax
+endif
+
+syn cluster htmlPreproc add=htmlosRegion
+
+syn case ignore
+
+" Function names
+syn keyword	htmlosFunctions	expand sleep getlink version system ascii getascii syslock sysunlock cr lf clean postprep listtorow split listtocol coltolist rowtolist tabletolist	contained
+syn keyword	htmlosFunctions	cut \display cutall cutx cutallx length reverse lower upper proper repeat left right middle trim trimleft trimright count countx locate locatex replace replacex replaceall replaceallx paste pasteleft pasteleftx pasteleftall pasteleftallx pasteright pasterightall pasterightallx chopleft chopleftx chopright choprightx format concat	contained
+syn keyword	htmlosFunctions	goto exitgoto	contained
+syn keyword	htmlosFunctions	layout cols rows row items getitem putitem switchitems gettable delrow delrows delcol delcols append  merge fillcol fillrow filltable pastetable getcol getrow fillindexcol insindexcol dups nodups maxtable mintable maxcol mincol maxrow minrow avetable avecol averow mediantable mediancol medianrow producttable productcol productrow sumtable sumcol sumrow sumsqrtable sumsqrcol sumsqrrow reversecols reverserows switchcols switchrows inscols insrows insfillcol sortcol reversesortcol sortcoln reversesortcoln sortrow sortrown reversesortrow reversesortrown getcoleq getcoleqn getcolnoteq getcolany getcolbegin getcolnotany getcolnotbegin getcolge getcolgt getcolle getcollt getcolgen getcolgtn getcollen getcoltn getcolend getcolnotend getrowend getrownotend getcolin getcolnotin getcolinbegin getcolnotinbegin getcolinend getcolnotinend getrowin getrownotin getrowinbegin getrownotinbegin getrowinend getrownotinend	contained
+syn keyword	htmlosFunctions	dbcreate dbadd dbedit dbdelete dbsearch dbsearchsort dbget dbgetsort dbstatus dbindex dbimport dbfill dbexport dbsort dbgetrec dbremove dbpurge dbfind dbfindsort dbunique dbcopy dbmove dbkill dbtransfer dbpoke dbsearchx dbgetx	contained
+syn keyword	htmlosFunctions	syshtmlosname sysstartname sysfixfile fileinfo filelist fileindex domainname page browser regdomain username usernum getenv httpheader copy file ts row sysls syscp sysmv sysmd sysrd filepush filepushlink dirname	contained
+syn keyword	htmlosFunctions	mail to address subject netmail netmailopen netmailclose mailfilelist netweb netwebresults webpush netsockopen netsockread netsockwrite netsockclose	contained
+syn keyword	htmlosFunctions today time systime now yesterday tomorrow getday getmonth getyear getminute getweekday getweeknum getyearday getdate gettime getamorpm gethour addhours addminutes adddays timebetween timetill timefrom datetill datefrom mixedtimebetween mixeddatetill mixedtimetill mixedtimefrom mixeddatefrom nextdaybyweekfromdate nextdaybyweekfromtoday nextdaybymonthfromdate nextdaybymonthfromtoday nextdaybyyearfromdate nextdaybyyearfromtoday offsetdaybyweekfromdate offsetdaybyweekfromtoday offsetdaybymonthfromdate offsetdaybymonthfromtoday	contained
+syn keyword	htmlosFunctions isprivate ispublic isfile isdir isblank iserror iserror iseven isodd istrue isfalse islogical istext istag isnumber isinteger isdate istableeq istableeqx istableeqn isfuture ispast istoday isweekday isweekend issamedate iseq isnoteq isge isle ismod10 isvalidstring	contained
+syn keyword	htmlosFunctions celtof celtokel ftocel ftokel keltocel keltof cmtoin intocm fttom mtoft fttomile miletoft kmtomile miletokm mtoyd ydtom galtoltr ltrtogal ltrtoqt qttoltr gtooz oztog kgtolb lbtokg mttoton tontomt	contained
+syn keyword	htmlosFunctions max min abs sign inverse square sqrt cube roundsig round ceiling roundup floor rounddown roundeven rounddowneven roundupeven roundodd roundupodd rounddownodd random factorial summand fibonacci remainder mod radians degrees cos sin tan cotan secant cosecant acos asin atan exp power power10 ln log10 log sinh cosh tanh	contained
+syn keyword	htmlosFunctions xmldelete xmldeletex xmldeleteattr xmldeleteattrx xmledit xmleditx xmleditvalue xmleditvaluex xmleditattr xmleditattrx xmlinsertbefore xmlinsertbeforex smlinsertafter xmlinsertafterx xmlinsertattr xmlinsertattrx smlget xmlgetx xmlgetvalue xmlgetvaluex xmlgetattrvalue xmlgetattrvaluex xmlgetrec xmlgetrecx xmlgetrecattrvalue xmlgetrecattrvaluex xmlchopleftbefore xmlchopleftbeforex xmlchoprightbefore xmlchoprightbeforex xmlchopleftafter xmlchopleftafterx xmlchoprightafter xmlchoprightafterx xmllocatebefore xmllocatebeforex xmllocateafter xmllocateafterx	contained
+
+" Type
+syn keyword	htmlosType	int str dol flt dat grp	contained
+
+" StorageClass
+syn keyword	htmlosStorageClass	locals	contained
+
+" Operator
+syn match	htmlosOperator	"[-=+/\*!]"	contained
+syn match	htmlosRelation	"[~]"	contained
+syn match	htmlosRelation	"[=~][&!]"	contained
+syn match	htmlosRelation	"[!=<>]="	contained
+syn match	htmlosRelation	"[<>]"	contained
+
+" Comment
+syn region	htmlosComment	start="#" end="/#"	contained
+
+" Conditional
+syn keyword	htmlosConditional	if then /if to else elif	contained
+syn keyword	htmlosConditional	and or nand nor xor not	contained
+" Repeat
+syn keyword	htmlosRepeat	while do /while for /for	contained
+
+" Keyword
+syn keyword	htmlosKeyword	name value step do rowname colname rownum	contained
+
+" Repeat
+syn keyword	htmlosLabel	case matched /case switch	contained
+
+" Statement
+syn keyword	htmlosStatement     break exit return continue	contained
+
+" Identifier
+syn match	htmlosIdentifier	"\h\w*[\.]*\w*"	contained
+
+" Special identifier
+syn match	htmlosSpecialIdentifier	"[\$@]"	contained
+
+" Define
+syn keyword	htmlosDefine	function overlay	contained
+
+" Boolean
+syn keyword	htmlosBoolean	true false	contained
+
+" String
+syn region	htmlosStringDouble	keepend matchgroup=None start=+"+ end=+"+ contained
+syn region	htmlosStringSingle	keepend matchgroup=None start=+'+ end=+'+ contained
+
+" Number
+syn match htmlosNumber	"-\=\<\d\+\>"	contained
+
+" Float
+syn match htmlosFloat	"\(-\=\<\d+\|-\=\)\.\d\+\>"	contained
+
+" Error
+syn match htmlosError	"ERROR"	contained
+
+" Parent
+syn match     htmlosParent       "[({[\]})]"     contained
+
+" Todo
+syn keyword	htmlosTodo TODO Todo todo	contained
+
+syn cluster	htmlosInside	contains=htmlosComment,htmlosFunctions,htmlosIdentifier,htmlosSpecialIdentifier,htmlosConditional,htmlosRepeat,htmlosLabel,htmlosStatement,htmlosOperator,htmlosRelation,htmlosStringSingle,htmlosStringDouble,htmlosNumber,htmlosFloat,htmlosError,htmlosKeyword,htmlosType,htmlosBoolean,htmlosParent
+
+syn cluster	htmlosTop	contains=@htmlosInside,htmlosDefine,htmlosError,htmlosStorageClass
+
+syn region	 htmlosRegion	keepend matchgroup=Delimiter start="<<" skip=+".\{-}?>.\{-}"\|'.\{-}?>.\{-}'\|/\*.\{-}?>.\{-}\*/+ end=">>" contains=@htmlosTop
+syn region	 htmlosRegion	keepend matchgroup=Delimiter start="\[\[" skip=+".\{-}?>.\{-}"\|'.\{-}?>.\{-}'\|/\*.\{-}?>.\{-}\*/+ end="\]\]" contains=@htmlosTop
+
+
+" sync
+if exists("htmlos_minlines")
+  exec "syn sync minlines=" . htmlos_minlines
+else
+  syn sync minlines=100
+endif
+
+" Define the default highlighting.
+" For version 5.7 and earlier: only when not done already
+" For version 5.8 and later: only when an item doesn't have highlighting yet
+if version >= 508 || !exists("did_htmlos_syn_inits")
+  if version < 508
+    let did_htmlos_syn_inits = 1
+    command -nargs=+ HiLink hi link <args>
+  else
+    command -nargs=+ HiLink hi def link <args>
+  endif
+
+  " The default methods for highlighting.  Can be overridden later
+  HiLink	 htmlosSpecialIdentifier	Operator
+  HiLink	 htmlosIdentifier	Identifier
+  HiLink	 htmlosStorageClass	StorageClass
+  HiLink	 htmlosComment	Comment
+  HiLink	 htmlosBoolean	Boolean
+  HiLink	 htmlosStringSingle	String
+  HiLink	 htmlosStringDouble	String
+  HiLink	 htmlosNumber	Number
+  HiLink	 htmlosFloat	Float
+  HiLink	 htmlosFunctions	Function
+  HiLink	 htmlosRepeat	Repeat
+  HiLink	 htmlosConditional	Conditional
+  HiLink	 htmlosLabel	Label
+  HiLink	 htmlosStatement	Statement
+  HiLink	 htmlosKeyword	Statement
+  HiLink	 htmlosType	Type
+  HiLink	 htmlosDefine	Define
+  HiLink	 htmlosParent	Delimiter
+  HiLink	 htmlosError	Error
+  HiLink	 htmlosTodo	Todo
+  HiLink	htmlosOperator	Operator
+  HiLink	htmlosRelation	Operator
+
+  delcommand HiLink
+endif
+let b:current_syntax = "htmlos"
+
+if main_syntax == 'htmlos'
+  unlet main_syntax
+endif
+
+" vim: ts=8 sw=2
--- /dev/null
+++ b/lib/vimfiles/syntax/ia64.vim
@@ -1,0 +1,311 @@
+" Vim syntax file
+" Language:     IA-64 (Itanium) assembly language
+" Maintainer:   Parth Malwankar <pmalwankar@yahoo.com>
+" URL:		http://www.geocities.com/pmalwankar (Home Page with link to my Vim page)
+"		http://www.geocities.com/pmalwankar/vim.htm (for VIM)
+" File Version: 0.7
+" Last Change:  2006 Sep 08
+
+" For version 5.x: Clear all syntax items
+" For version 6.x: Quit when a syntax file was already loaded
+if version < 600
+  syntax clear
+elseif exists("b:current_syntax")
+  finish
+endif
+
+
+"ignore case for assembly
+syn case ignore
+
+"  Identifier Keyword characters (defines \k)
+if version >= 600
+	setlocal iskeyword=@,48-57,#,$,.,:,?,@-@,_,~
+else
+	set iskeyword=@,48-57,#,$,.,:,?,@-@,_,~
+endif
+
+syn sync minlines=5
+
+" Read the MASM syntax to start with
+" This is needed as both IA-64 as well as IA-32 instructions are supported
+source <sfile>:p:h/masm.vim
+
+syn region ia64Comment start="//" end="$" contains=ia64Todo
+syn region ia64Comment start="/\*" end="\*/" contains=ia64Todo
+
+syn match ia64Identifier	"[a-zA-Z_$][a-zA-Z0-9_$]*"
+syn match ia64Directive		"\.[a-zA-Z_$][a-zA-Z_$.]\+"
+syn match ia64Label		"[a-zA-Z_$.][a-zA-Z0-9_$.]*\s\=:\>"he=e-1
+syn match ia64Label		"[a-zA-Z_$.][a-zA-Z0-9_$.]*\s\=::\>"he=e-2
+syn match ia64Label		"[a-zA-Z_$.][a-zA-Z0-9_$.]*\s\=#\>"he=e-1
+syn region ia64string		start=+L\="+ skip=+\\\\\|\\"+ end=+"+
+syn match ia64Octal		"0[0-7_]*\>"
+syn match ia64Binary		"0[bB][01_]*\>"
+syn match ia64Hex		"0[xX][0-9a-fA-F_]*\>"
+syn match ia64Decimal		"[1-9_][0-9_]*\>"
+syn match ia64Float		"[0-9_]*\.[0-9_]*\([eE][+-]\=[0-9_]*\)\=\>"
+
+"simple instructions
+syn keyword ia64opcode add adds addl addp4 alloc and andcm cover epc
+syn keyword ia64opcode fabs fand fandcm fc flushrs fneg fnegabs for
+syn keyword ia64opcode fpabs fpack fpneg fpnegabs fselect fand fabdcm
+syn keyword ia64opcode fc fwb fxor loadrs movl mux1 mux2 or padd4
+syn keyword ia64opcode pavgsub1 pavgsub2 popcnt psad1 pshl2 pshl4 pshladd2
+syn keyword ia64opcode pshradd2 psub4 rfi rsm rum shl shladd shladdp4
+syn keyword ia64opcode shrp ssm sub sum sync.i tak thash
+syn keyword ia64opcode tpa ttag xor
+
+"put to override these being recognized as floats. They are orignally from masm.vim
+"put here to avoid confusion with float
+syn match   ia64Directive       "\.186"
+syn match   ia64Directive       "\.286"
+syn match   ia64Directive       "\.286c"
+syn match   ia64Directive       "\.286p"
+syn match   ia64Directive       "\.287"
+syn match   ia64Directive       "\.386"
+syn match   ia64Directive       "\.386c"
+syn match   ia64Directive       "\.386p"
+syn match   ia64Directive       "\.387"
+syn match   ia64Directive       "\.486"
+syn match   ia64Directive       "\.486c"
+syn match   ia64Directive       "\.486p"
+syn match   ia64Directive       "\.8086"
+syn match   ia64Directive       "\.8087"
+
+
+
+"delimiters
+syn match ia64delimiter ";;"
+
+"operators
+syn match ia64operators "[\[\]()#,]"
+syn match ia64operators "\(+\|-\|=\)"
+
+"TODO
+syn match ia64Todo      "\(TODO\|XXX\|FIXME\|NOTE\)"
+
+"What follows is a long list of regular expressions for parsing the
+"ia64 instructions that use many completers
+
+"br
+syn match ia64opcode "br\(\(\.\(cond\|call\|ret\|ia\|cloop\|ctop\|cexit\|wtop\|wexit\)\)\=\(\.\(spnt\|dpnt\|sptk\|dptk\)\)\=\(\.few\|\.many\)\=\(\.clr\)\=\)\=\>"
+"break
+syn match ia64opcode "break\(\.[ibmfx]\)\=\>"
+"brp
+syn match ia64opcode "brp\(\.\(sptk\|dptk\|loop\|exit\)\)\(\.imp\)\=\>"
+syn match ia64opcode "brp\.ret\(\.\(sptk\|dptk\)\)\{1}\(\.imp\)\=\>"
+"bsw
+syn match ia64opcode "bsw\.[01]\>"
+"chk
+syn match ia64opcode "chk\.\(s\(\.[im]\)\=\)\>"
+syn match ia64opcode "chk\.a\.\(clr\|nc\)\>"
+"clrrrb
+syn match ia64opcode "clrrrb\(\.pr\)\=\>"
+"cmp/cmp4
+syn match ia64opcode "cmp4\=\.\(eq\|ne\|l[te]\|g[te]\|[lg]tu\|[lg]eu\)\(\.unc\)\=\>"
+syn match ia64opcode "cmp4\=\.\(eq\|[lgn]e\|[lg]t\)\.\(\(or\(\.andcm\|cm\)\=\)\|\(and\(\(\.or\)\=cm\)\=\)\)\>"
+"cmpxchg
+syn match ia64opcode "cmpxchg[1248]\.\(acq\|rel\)\(\.nt1\|\.nta\)\=\>"
+"czx
+syn match ia64opcode "czx[12]\.[lr]\>"
+"dep
+syn match ia64opcode "dep\(\.z\)\=\>"
+"extr
+syn match ia64opcode "extr\(\.u\)\=\>"
+"fadd
+syn match ia64opcode "fadd\(\.[sd]\)\=\(\.s[0-3]\)\=\>"
+"famax/famin
+syn match ia64opcode "fa\(max\|min\)\(\.s[0-3]\)\=\>"
+"fchkf/fmax/fmin
+syn match ia64opcode "f\(chkf\|max\|min\)\(\.s[0-3]\)\=\>"
+"fclass
+syn match ia64opcode "fclass\(\.n\=m\)\(\.unc\)\=\>"
+"fclrf/fpamax
+syn match ia64opcode "f\(clrf\|pamax\|pamin\)\(\.s[0-3]\)\=\>"
+"fcmp
+syn match ia64opcode "fcmp\.\(n\=[lg][te]\|n\=eq\|\(un\)\=ord\)\(\.unc\)\=\(\.s[0-3]\)\=\>"
+"fcvt/fcvt.xf/fcvt.xuf.pc.sf
+syn match ia64opcode "fcvt\.\(\(fxu\=\(\.trunc\)\=\(\.s[0-3]\)\=\)\|\(xf\|xuf\(\.[sd]\)\=\(\.s[0-3]\)\=\)\)\>"
+"fetchadd
+syn match ia64opcode "fetchadd[48]\.\(acq\|rel\)\(\.nt1\|\.nta\)\=\>"
+"fma/fmpy/fms
+syn match ia64opcode "fm\([as]\|py\)\(\.[sd]\)\=\(\.s[0-3]\)\=\>"
+"fmerge/fpmerge
+syn match ia64opcode "fp\=merge\.\(ns\|se\=\)\>"
+"fmix
+syn match ia64opcode "fmix\.\(lr\|[lr]\)\>"
+"fnma/fnorm/fnmpy
+syn match ia64opcode "fn\(ma\|mpy\|orm\)\(\.[sd]\)\=\(\.s[0-3]\)\=\>"
+"fpcmp
+syn match ia64opcode "fpcmp\.\(n\=[lg][te]\|n\=eq\|\(un\)\=ord\)\(\.s[0-3]\)\=\>"
+"fpcvt
+syn match ia64opcode "fpcvt\.fxu\=\(\(\.trunc\)\=\(\.s[0-3]\)\=\)\>"
+"fpma/fpmax/fpmin/fpmpy/fpms/fpnma/fpnmpy/fprcpa/fpsqrta
+syn match ia64opcode "fp\(max\=\|min\|n\=mpy\|ms\|nma\|rcpa\|sqrta\)\(\.s[0-3]\)\=\>"
+"frcpa/frsqrta
+syn match ia64opcode "fr\(cpa\|sqrta\)\(\.s[0-3]\)\=\>"
+"fsetc/famin/fchkf
+syn match ia64opcode "f\(setc\|amin\|chkf\)\(\.s[0-3]\)\=\>"
+"fsub
+syn match ia64opcode "fsub\(\.[sd]\)\=\(\.s[0-3]\)\=\>"
+"fswap
+syn match ia64opcode "fswap\(\.n[lr]\=\)\=\>"
+"fsxt
+syn match ia64opcode "fsxt\.[lr]\>"
+"getf
+syn match ia64opcode "getf\.\([sd]\|exp\|sig\)\>"
+"invala
+syn match ia64opcode "invala\(\.[ae]\)\=\>"
+"itc/itr
+syn match ia64opcode "it[cr]\.[id]\>"
+"ld
+syn match ia64opcode "ld[1248]\>\|ld[1248]\(\.\(sa\=\|a\|c\.\(nc\|clr\(\.acq\)\=\)\|acq\|bias\)\)\=\(\.nt[1a]\)\=\>"
+syn match ia64opcode "ld8\.fill\(\.nt[1a]\)\=\>"
+"ldf
+syn match ia64opcode "ldf[sde8]\(\(\.\(sa\=\|a\|c\.\(nc\|clr\)\)\)\=\(\.nt[1a]\)\=\)\=\>"
+syn match ia64opcode "ldf\.fill\(\.nt[1a]\)\=\>"
+"ldfp
+syn match ia64opcode "ldfp[sd8]\(\(\.\(sa\=\|a\|c\.\(nc\|clr\)\)\)\=\(\.nt[1a]\)\=\)\=\>"
+"lfetch
+syn match ia64opcode "lfetch\(\.fault\(\.excl\)\=\|\.excl\)\=\(\.nt[12a]\)\=\>"
+"mf
+syn match ia64opcode "mf\(\.a\)\=\>"
+"mix
+syn match ia64opcode "mix[124]\.[lr]\>"
+"mov
+syn match ia64opcode "mov\(\.[im]\)\=\>"
+syn match ia64opcode "mov\(\.ret\)\=\(\(\.sptk\|\.dptk\)\=\(\.imp\)\=\)\=\>"
+"nop
+syn match ia64opcode "nop\(\.[ibmfx]\)\=\>"
+"pack
+syn match ia64opcode "pack\(2\.[su]ss\|4\.sss\)\>"
+"padd //padd4 added to keywords
+syn match ia64opcode "padd[12]\(\.\(sss\|uus\|uuu\)\)\=\>"
+"pavg
+syn match ia64opcode "pavg[12]\(\.raz\)\=\>"
+"pcmp
+syn match ia64opcode "pcmp[124]\.\(eq\|gt\)\>"
+"pmax/pmin
+syn match ia64opcode "pm\(ax\|in\)\(\(1\.u\)\|2\)\>"
+"pmpy
+syn match ia64opcode "pmpy2\.[rl]\>"
+"pmpyshr
+syn match ia64opcode "pmpyshr2\(\.u\)\=\>"
+"probe
+syn match ia64opcode "probe\.[rw]\>"
+syn match ia64opcode "probe\.\(\(r\|w\|rw\)\.fault\)\>"
+"pshr
+syn match ia64opcode "pshr[24]\(\.u\)\=\>"
+"psub
+syn match ia64opcode "psub[12]\(\.\(sss\|uu[su]\)\)\=\>"
+"ptc
+syn match ia64opcode "ptc\.\(l\|e\|ga\=\)\>"
+"ptr
+syn match ia64opcode "ptr\.\(d\|i\)\>"
+"setf
+syn match ia64opcode "setf\.\(s\|d\|exp\|sig\)\>"
+"shr
+syn match ia64opcode "shr\(\.u\)\=\>"
+"srlz
+syn match ia64opcode "srlz\(\.[id]\)\>"
+"st
+syn match ia64opcode "st[1248]\(\.rel\)\=\(\.nta\)\=\>"
+syn match ia64opcode "st8\.spill\(\.nta\)\=\>"
+"stf
+syn match ia64opcode "stf[1248]\(\.nta\)\=\>"
+syn match ia64opcode "stf\.spill\(\.nta\)\=\>"
+"sxt
+syn match ia64opcode "sxt[124]\>"
+"tbit/tnat
+syn match ia64opcode "t\(bit\|nat\)\(\.nz\|\.z\)\=\(\.\(unc\|or\(\.andcm\|cm\)\=\|and\(\.orcm\|cm\)\=\)\)\=\>"
+"unpack
+syn match ia64opcode "unpack[124]\.[lh]\>"
+"xchq
+syn match ia64opcode "xchg[1248]\(\.nt[1a]\)\=\>"
+"xma/xmpy
+syn match ia64opcode "xm\(a\|py\)\.[lh]u\=\>"
+"zxt
+syn match ia64opcode "zxt[124]\>"
+
+
+"The regex for different ia64 registers are given below
+
+"limits the rXXX and fXXX and cr suffix in the range 0-127
+syn match ia64registers "\([fr]\|cr\)\([0-9]\|[1-9][0-9]\|1[0-1][0-9]\|12[0-7]\)\{1}\>"
+"branch ia64registers
+syn match ia64registers "b[0-7]\>"
+"predicate ia64registers
+syn match ia64registers "p\([0-9]\|[1-5][0-9]\|6[0-3]\)\>"
+"application ia64registers
+syn match ia64registers "ar\.\(fpsr\|mat\|unat\|rnat\|pfs\|bsp\|bspstore\|rsc\|lc\|ec\|ccv\|itc\|k[0-7]\)\>"
+"ia32 AR's
+syn match ia64registers "ar\.\(eflag\|fcr\|csd\|ssd\|cflg\|fsr\|fir\|fdr\)\>"
+"sp/gp/pr/pr.rot/rp
+syn keyword ia64registers sp gp pr pr.rot rp ip tp
+"in/out/local
+syn match ia64registers "\(in\|out\|loc\)\([0-9]\|[1-8][0-9]\|9[0-5]\)\>"
+"argument ia64registers
+syn match ia64registers "farg[0-7]\>"
+"return value ia64registers
+syn match ia64registers "fret[0-7]\>"
+"psr
+syn match ia64registers "psr\(\.\(l\|um\)\)\=\>"
+"cr
+syn match ia64registers "cr\.\(dcr\|itm\|iva\|pta\|ipsr\|isr\|ifa\|iip\|itir\|iipa\|ifs\|iim\|iha\|lid\|ivr\|tpr\|eoi\|irr[0-3]\|itv\|pmv\|lrr[01]\|cmcv\)\>"
+"Indirect registers
+syn match ia64registers "\(cpuid\|dbr\|ibr\|pkr\|pmc\|pmd\|rr\|itr\|dtr\)\>"
+"MUX permutations for 8-bit elements
+syn match ia64registers "\(@rev\|@mix\|@shuf\|@alt\|@brcst\)\>"
+"floating point classes
+syn match ia64registers "\(@nat\|@qnan\|@snan\|@pos\|@neg\|@zero\|@unorm\|@norm\|@inf\)\>"
+"link relocation operators
+syn match ia64registers "\(@\(\(\(gp\|sec\|seg\|image\)rel\)\|ltoff\|fptr\|ptloff\|ltv\|section\)\)\>"
+
+"Data allocation syntax
+syn match ia64data "data[1248]\(\(\(\.ua\)\=\(\.msb\|\.lsb\)\=\)\|\(\(\.msb\|\.lsb\)\=\(\.ua\)\=\)\)\=\>"
+syn match ia64data "real\([48]\|1[06]\)\(\(\(\.ua\)\=\(\.msb\|\.lsb\)\=\)\|\(\(\.msb\|\.lsb\)\=\(\.ua\)\=\)\)\=\>"
+syn match ia64data "stringz\=\(\(\(\.ua\)\=\(\.msb\|\.lsb\)\=\)\|\(\(\.msb\|\.lsb\)\=\(\.ua\)\=\)\)\=\>"
+
+" Define the default highlighting.
+" For version 5.7 and earlier: only when not done already
+" For version 5.8 and later: only when an item doesn't have highlighting yet
+if version >= 508 || !exists("did_ia64_syn_inits")
+	if version < 508
+		let did_ia64_syn_inits = 1
+		command -nargs=+ HiLink hi link <args>
+	else
+		command -nargs=+ HiLink hi def link <args>
+	endif
+
+	"put masm groups with our groups
+	HiLink masmOperator	ia64operator
+	HiLink masmDirective	ia64Directive
+	HiLink masmOpcode	ia64Opcode
+	HiLink masmIdentifier	ia64Identifier
+	HiLink masmFloat	ia64Float
+
+	"ia64 specific stuff
+	HiLink ia64Label	Define
+	HiLink ia64Comment	Comment
+	HiLink ia64Directive	Type
+	HiLink ia64opcode	Statement
+	HiLink ia64registers	Operator
+	HiLink ia64string	String
+	HiLink ia64Hex		Number
+	HiLink ia64Binary	Number
+	HiLink ia64Octal	Number
+	HiLink ia64Float	Float
+	HiLink ia64Decimal	Number
+	HiLink ia64Identifier	Identifier
+	HiLink ia64data		Type
+	HiLink ia64delimiter	Delimiter
+	HiLink ia64operator	Operator
+	HiLink ia64Todo		Todo
+
+	delcommand HiLink
+endif
+
+let b:current_syntax = "ia64"
+
+" vim: ts=8 sw=2
--- /dev/null
+++ b/lib/vimfiles/syntax/ibasic.vim
@@ -1,0 +1,176 @@
+" Vim syntax file
+" Language:	ibasic
+" Maintainer:	Mark Manning <markem@airmail.net>
+" Originator:	Allan Kelly <Allan.Kelly@ed.ac.uk>
+" Created:	10/1/2006
+" Updated:	10/21/2006
+" Description:  A vim file to handle the IBasic file format.
+" Notes:
+"	Updated by Mark Manning <markem@airmail.net>
+"	Applied IBasic support to the already excellent support for standard
+"	basic syntax (like QB).
+"
+"	First version based on Micro$soft QBASIC circa 1989, as documented in
+"	'Learn BASIC Now' by Halvorson&Rygmyr. Microsoft Press 1989.
+"	This syntax file not a complete implementation yet.
+"	Send suggestions to the maintainer.
+"
+"	This version is based upon the commands found in IBasic (www.pyxia.com).
+"	MEM 10/6/2006
+"
+"	Quit when a (custom) syntax file was already loaded (Taken from c.vim)
+"
+if exists("b:current_syntax")
+  finish
+endif
+"
+"	Be sure to turn on the "case ignore" since current versions of basic
+"	support both upper as well as lowercase letters.
+"
+syn case ignore
+"
+" A bunch of useful BASIC keywords
+"
+syn keyword ibasicStatement	beep bload bsave call absolute chain chdir circle
+syn keyword ibasicStatement	clear close cls color com common const data
+syn keyword ibasicStatement	loop draw end environ erase error exit field
+syn keyword ibasicStatement	files function get gosub goto
+syn keyword ibasicStatement	input input# ioctl key kill let line locate
+syn keyword ibasicStatement	lock unlock lprint using lset mkdir name
+syn keyword ibasicStatement	on error open option base out paint palette pcopy
+syn keyword ibasicStatement	pen play pmap poke preset print print# using pset
+syn keyword ibasicStatement	put randomize read redim reset restore resume
+syn keyword ibasicStatement	return rmdir rset run seek screen
+syn keyword ibasicStatement	shared shell sleep sound static stop strig sub
+syn keyword ibasicStatement	swap system timer troff tron type unlock
+syn keyword ibasicStatement	view wait width window write
+syn keyword ibasicStatement	date$ mid$ time$
+"
+"	Do the basic variables names first.  This is because it
+"	is the most inclusive of the tests.  Later on we change
+"	this so the identifiers are split up into the various
+"	types of identifiers like functions, basic commands and
+"	such. MEM 9/9/2006
+"
+syn match	ibasicIdentifier			"\<[a-zA-Z_][a-zA-Z0-9_]*\>"
+syn match	ibasicGenericFunction	"\<[a-zA-Z_][a-zA-Z0-9_]*\>\s*("me=e-1,he=e-1
+"
+"	Function list
+"
+syn keyword ibasicBuiltInFunction	abs asc atn cdbl cint clng cos csng csrlin cvd cvdmbf
+syn keyword ibasicBuiltInFunction	cvi cvl cvs cvsmbf eof erdev erl err exp fileattr
+syn keyword ibasicBuiltInFunction	fix fre freefile inp instr lbound len loc lof
+syn keyword ibasicBuiltInFunction	log lpos mod peek pen point pos rnd sadd screen seek
+syn keyword ibasicBuiltInFunction	setmem sgn sin spc sqr stick strig tab tan ubound
+syn keyword ibasicBuiltInFunction	val valptr valseg varptr varseg
+syn keyword ibasicBuiltInFunction	chr\$ command$ date$ environ$ erdev$ hex$ inkey$
+syn keyword ibasicBuiltInFunction	input$ ioctl$ lcases$ laft$ ltrim$ mid$ mkdmbf$ mkd$
+syn keyword ibasicBuiltInFunction	mki$ mkl$ mksmbf$ mks$ oct$ right$ rtrim$ space$
+syn keyword ibasicBuiltInFunction	str$ string$ time$ ucase$ varptr$
+syn keyword ibasicTodo contained	TODO
+syn cluster	ibasicFunctionCluster	contains=ibasicBuiltInFunction,ibasicGenericFunction
+
+syn keyword Conditional	if else then elseif endif select case endselect
+syn keyword Repeat	for do while next enddo endwhile wend
+
+syn keyword ibasicTypeSpecifier	single double defdbl defsng
+syn keyword ibasicTypeSpecifier	int integer uint uinteger int64 uint64 defint deflng
+syn keyword ibasicTypeSpecifier	byte char string istring defstr
+syn keyword ibasicDefine	dim def declare
+"
+"catch errors caused by wrong parenthesis
+"
+syn cluster	ibasicParenGroup	contains=ibasicParenError,ibasicIncluded,ibasicSpecial,ibasicTodo,ibasicUserCont,ibasicUserLabel,ibasicBitField
+syn region	ibasicParen		transparent start='(' end=')' contains=ALLBUT,@bParenGroup
+syn match	ibasicParenError	")"
+syn match	ibasicInParen	contained "[{}]"
+"
+"integer number, or floating point number without a dot and with "f".
+"
+syn region	ibasicHex		start="&h" end="\W"
+syn region	ibasicHexError	start="&h\x*[g-zG-Z]" end="\W"
+syn match	ibasicInteger	"\<\d\+\(u\=l\=\|lu\|f\)\>"
+"
+"floating point number, with dot, optional exponent
+"
+syn match	ibasicFloat		"\<\d\+\.\d*\(e[-+]\=\d\+\)\=[fl]\=\>"
+"
+"floating point number, starting with a dot, optional exponent
+"
+syn match	ibasicFloat		"\.\d\+\(e[-+]\=\d\+\)\=[fl]\=\>"
+"
+"floating point number, without dot, with exponent
+"
+syn match	ibasicFloat		"\<\d\+e[-+]\=\d\+[fl]\=\>"
+"
+"hex number
+"
+syn match	ibasicIdentifier	"\<[a-zA-Z_][a-zA-Z0-9_]*\>"
+syn match	ibasicFunction	"\<[a-zA-Z_][a-zA-Z0-9_]*\>\s*("me=e-1,he=e-1
+syn case match
+syn match	ibasicOctalError	"\<0\o*[89]"
+"
+" String and Character contstants
+"
+syn region	ibasicString		start='"' end='"' contains=ibasicSpecial,ibasicTodo
+syn region	ibasicString		start="'" end="'" contains=ibasicSpecial,ibasicTodo
+"
+"	Comments
+"
+syn match	ibasicSpecial	contained "\\."
+syn region  ibasicComment	start="^rem" end="$" contains=ibasicSpecial,ibasicTodo
+syn region  ibasicComment	start=":\s*rem" end="$" contains=ibasicSpecial,ibasicTodo
+syn region	ibasicComment	start="\s*'" end="$" contains=ibasicSpecial,ibasicTodo
+syn region	ibasicComment	start="^'" end="$" contains=ibasicSpecial,ibasicTodo
+"
+"	Now do the comments and labels
+"
+syn match	ibasicLabel		"^\d"
+syn region  ibasicLineNumber	start="^\d" end="\s"
+"
+"	Pre-compiler options : FreeBasic
+"
+syn region	ibasicPreCondit	start="^\s*#\s*\(if\>\|ifdef\>\|ifndef\>\|elif\>\|else\>\|endif\>\)" skip="\\$" end="$" contains=ibasicString,ibasicCharacter,ibasicNumber,ibasicCommentError,ibasicSpaceError
+syn match	ibasicInclude	"^\s*#\s*include\s*"
+"
+"	Create the clusters
+"
+syn cluster ibasicNumber contains=ibasicHex,ibasicInteger,ibasicFloat
+syn cluster	ibasicError	contains=ibasicHexError
+"
+"	Used with OPEN statement
+"
+syn match   ibasicFilenumber  "#\d\+"
+"
+"syn sync ccomment ibasicComment
+"
+syn match	ibasicMathOperator	"[\+\-\=\|\*\/\>\<\%\()[\]]" contains=ibasicParen
+"
+" The default methods for highlighting.  Can be overridden later
+"
+hi def link ibasicLabel			Label
+hi def link ibasicConditional		Conditional
+hi def link ibasicRepeat		Repeat
+hi def link ibasicHex			Number
+hi def link ibasicInteger		Number
+hi def link ibasicFloat			Number
+hi def link ibasicError			Error
+hi def link ibasicHexError		Error
+hi def link ibasicStatement		Statement
+hi def link ibasicString		String
+hi def link ibasicComment		Comment
+hi def link ibasicLineNumber		Comment
+hi def link ibasicSpecial		Special
+hi def link ibasicTodo			Todo
+hi def link ibasicGenericFunction	Function
+hi def link ibasicBuiltInFunction	Function
+hi def link ibasicTypeSpecifier		Type
+hi def link ibasicDefine		Type
+hi def link ibasicInclude		Include
+hi def link ibasicIdentifier		Identifier
+hi def link ibasicFilenumber		ibasicTypeSpecifier
+hi def link ibasicMathOperator		Operator
+
+let b:current_syntax = "ibasic"
+
+" vim: ts=8
--- /dev/null
+++ b/lib/vimfiles/syntax/icemenu.vim
@@ -1,0 +1,36 @@
+" Vim syntax file
+" Language:	Icewm Menu
+" Maintainer:	James Mahler <James.Mahler@gmail.com>
+" Last Change:	Fri Apr  1 15:13:48 EST 2005
+" Extensions:	~/.icewm/menu
+" Comment:	Icewm is a lightweight window manager.  This adds syntax
+"		highlighting when editing your user's menu file (~/.icewm/menu).
+
+" clear existing syntax
+if version < 600
+	syntax clear
+elseif exists("b:current_syntax")
+	finish
+endif
+
+" not case sensitive
+syntax case ignore
+
+" icons .xpm .png and .gif
+syntax match _icon /"\=\/.*\.xpm"\=/
+syntax match _icon /"\=\/.*\.png"\=/
+syntax match _icon /"\=\/.*\.gif"\=/
+syntax match _icon /"\-"/
+
+" separator
+syntax keyword _rules separator
+
+" prog and menu
+syntax keyword _ids menu prog
+
+" highlights
+highlight link _rules Underlined
+highlight link _ids Type
+highlight link _icon Special
+
+let b:current_syntax = "IceMenu"
--- /dev/null
+++ b/lib/vimfiles/syntax/icon.vim
@@ -1,0 +1,212 @@
+" Vim syntax file
+" Language:	Icon
+" Maintainer:	Wendell Turner <wendell@adsi-m4.com>
+" URL:		ftp://ftp.halcyon.com/pub/users/wturner/icon.vim
+" Last Change:	2003 May 11
+
+" For version 5.x: Clear all syntax items
+" For version 6.x: Quit when a syntax file was already loaded
+if version < 600
+  syntax clear
+elseif exists("b:current_syntax")
+  finish
+endif
+
+syn keyword  iconFunction   abs acos any args asin atan bal
+syn keyword  iconFunction   callout center char chdir close collect copy
+syn keyword  iconFunction   cos cset delay delete detab display dtor
+syn keyword  iconFunction   entab errorclear exit exp find flush function
+syn keyword  iconFunction   get getch getche getenv iand icom image
+syn keyword  iconFunction   insert integer ior ishift ixor kbhit key
+syn keyword  iconFunction   left list loadfunc log many map match
+syn keyword  iconFunction   member move name numeric open ord pop
+syn keyword  iconFunction   pos proc pull push put read reads
+syn keyword  iconFunction   real remove rename repl reverse right rtod
+syn keyword  iconFunction   runerr save seek seq set sin sort
+syn keyword  iconFunction   sortf sqrt stop string system tab table
+syn keyword  iconFunction   tan trim type upto variable where write writes
+
+" Keywords
+syn match iconKeyword "&allocated"
+syn match iconKeyword "&ascii"
+syn match iconKeyword "&clock"
+syn match iconKeyword "&collections"
+syn match iconKeyword "&cset"
+syn match iconKeyword "&current"
+syn match iconKeyword "&date"
+syn match iconKeyword "&dateline"
+syn match iconKeyword "&digits"
+syn match iconKeyword "&dump"
+syn match iconKeyword "&e"
+syn match iconKeyword "&error"
+syn match iconKeyword "&errornumber"
+syn match iconKeyword "&errortext"
+syn match iconKeyword "&errorvalue"
+syn match iconKeyword "&errout"
+syn match iconKeyword "&fail"
+syn match iconKeyword "&features"
+syn match iconKeyword "&file"
+syn match iconKeyword "&host"
+syn match iconKeyword "&input"
+syn match iconKeyword "&lcase"
+syn match iconKeyword "&letters"
+syn match iconKeyword "&level"
+syn match iconKeyword "&line"
+syn match iconKeyword "&main"
+syn match iconKeyword "&null"
+syn match iconKeyword "&output"
+syn match iconKeyword "&phi"
+syn match iconKeyword "&pi"
+syn match iconKeyword "&pos"
+syn match iconKeyword "&progname"
+syn match iconKeyword "&random"
+syn match iconKeyword "&regions"
+syn match iconKeyword "&source"
+syn match iconKeyword "&storage"
+syn match iconKeyword "&subject"
+syn match iconKeyword "&time"
+syn match iconKeyword "&trace"
+syn match iconKeyword "&ucase"
+syn match iconKeyword "&version"
+
+" Reserved words
+syn keyword iconReserved break by case create default do
+syn keyword iconReserved else end every fail if
+syn keyword iconReserved initial link next not of
+syn keyword iconReserved procedure repeat return suspend
+syn keyword iconReserved then to until while
+
+" Storage class reserved words
+syn keyword	iconStorageClass	global static local record
+
+syn keyword	iconTodo	contained TODO FIXME XXX BUG
+
+" String and Character constants
+" Highlight special characters (those which have a backslash) differently
+syn match iconSpecial contained "\\x\x\{2}\|\\\o\{3\}\|\\[bdeflnrtv\"\'\\]\|\\^c[a-zA-Z0-9]\|\\$"
+syn region	iconString	start=+"+ skip=+\\\\\|\\"+ end=+"+ contains=iconSpecial
+syn region	iconCset	start=+'+ skip=+\\\\\|\\'+ end=+'+ contains=iconSpecial
+syn match	iconCharacter	"'[^\\]'"
+
+" not sure about these
+"syn match	iconSpecialCharacter "'\\[bdeflnrtv]'"
+"syn match	iconSpecialCharacter "'\\\o\{3\}'"
+"syn match	iconSpecialCharacter "'\\x\x\{2}'"
+"syn match	iconSpecialCharacter "'\\^c\[a-zA-Z0-9]'"
+
+"when wanted, highlight trailing white space
+if exists("icon_space_errors")
+  syn match	iconSpaceError	"\s*$"
+  syn match	iconSpaceError	" \+\t"me=e-1
+endif
+
+"catch errors caused by wrong parenthesis
+syn cluster	iconParenGroup contains=iconParenError,iconIncluded,iconSpecial,iconTodo,iconUserCont,iconUserLabel,iconBitField
+
+syn region	iconParen	transparent start='(' end=')' contains=ALLBUT,@iconParenGroup
+syn match	iconParenError	")"
+syn match	iconInParen	contained "[{}]"
+
+
+syn case ignore
+
+"integer number, or floating point number without a dot
+syn match	iconNumber		"\<\d\+\>"
+
+"floating point number, with dot, optional exponent
+syn match	iconFloat		"\<\d\+\.\d*\(e[-+]\=\d\+\)\=\>"
+
+"floating point number, starting with a dot, optional exponent
+syn match	iconFloat		"\.\d\+\(e[-+]\=\d\+\)\=\>"
+
+"floating point number, without dot, with exponent
+syn match	iconFloat		"\<\d\+e[-+]\=\d\+\>"
+
+"radix number
+syn match	iconRadix		"\<\d\{1,2}[rR][a-zA-Z0-9]\+\>"
+
+
+" syn match iconIdentifier	"\<[a-z_][a-z0-9_]*\>"
+
+syn case match
+
+" Comment
+syn match	iconComment	"#.*" contains=iconTodo,iconSpaceError
+
+syn region	iconPreCondit start="^\s*$\s*\(if\>\|ifdef\>\|ifndef\>\|elif\>\|else\>\|endif\>\)" skip="\\$" end="$" contains=iconComment,iconString,iconCharacter,iconNumber,iconCommentError,iconSpaceError
+
+syn region	iconIncluded	contained start=+"+ skip=+\\\\\|\\"+ end=+"+
+syn match	iconIncluded	contained "<[^>]*>"
+syn match	iconInclude	"^\s*$\s*include\>\s*["<]" contains=iconIncluded
+"syn match iconLineSkip	"\\$"
+
+syn cluster	iconPreProcGroup contains=iconPreCondit,iconIncluded,iconInclude,iconDefine,iconInParen,iconUserLabel
+
+syn region	iconDefine	start="^\s*$\s*\(define\>\|undef\>\)" skip="\\$" end="$" contains=ALLBUT,@iconPreProcGroup
+
+"wt:syn region	iconPreProc "start="^\s*#\s*\(pragma\>\|line\>\|warning\>\|warn\>\|error\>\)" skip="\\$" "end="$" contains=ALLBUT,@iconPreProcGroup
+
+" Highlight User Labels
+
+" syn cluster	iconMultiGroup contains=iconIncluded,iconSpecial,iconTodo,iconUserCont,iconUserLabel,iconBitField
+
+if !exists("icon_minlines")
+  let icon_minlines = 15
+endif
+exec "syn sync ccomment iconComment minlines=" . icon_minlines
+
+" Define the default highlighting.
+
+" For version 5.7 and earlier: only when not done already
+" For version 5.8 and later: only when an item doesn't have highlighting
+if version >= 508 || !exists("did_icon_syn_inits")
+  if version < 508
+    let did_icon_syn_inits = 1
+    command -nargs=+ HiLink hi link <args>
+  else
+    command -nargs=+ HiLink hi def link <args>
+  endif
+
+  " The default methods for highlighting.  Can be overridden later
+
+  " HiLink iconSpecialCharacter	iconSpecial
+
+  HiLink iconOctalError		iconError
+  HiLink iconParenError		iconError
+  HiLink iconInParen		iconError
+  HiLink iconCommentError	iconError
+  HiLink iconSpaceError		iconError
+  HiLink iconCommentError	iconError
+  HiLink iconIncluded		iconString
+  HiLink iconCommentString	iconString
+  HiLink iconComment2String	iconString
+  HiLink iconCommentSkip	iconComment
+
+  HiLink iconUserLabel		Label
+  HiLink iconCharacter		Character
+  HiLink iconNumber			Number
+  HiLink iconRadix			Number
+  HiLink iconFloat			Float
+  HiLink iconInclude		Include
+  HiLink iconPreProc		PreProc
+  HiLink iconDefine			Macro
+  HiLink iconError			Error
+  HiLink iconStatement		Statement
+  HiLink iconPreCondit		PreCondit
+  HiLink iconString			String
+  HiLink iconCset			String
+  HiLink iconComment		Comment
+  HiLink iconSpecial		SpecialChar
+  HiLink iconTodo			Todo
+  HiLink iconStorageClass	StorageClass
+  HiLink iconFunction		Statement
+  HiLink iconReserved		Label
+  HiLink iconKeyword		Operator
+
+  "HiLink iconIdentifier	Identifier
+
+  delcommand HiLink
+endif
+
+let b:current_syntax = "icon"
+
--- /dev/null
+++ b/lib/vimfiles/syntax/idl.vim
@@ -1,0 +1,319 @@
+" Vim syntax file
+" Language:    IDL (Interface Description Language)
+" Created By:  Jody Goldberg
+" Maintainer:  Michael Geddes <vim@frog.wheelycreek.net>
+" Last Change:  Thu Apr 13 2006
+
+
+" This is an experiment.  IDL's structure is simple enough to permit a full
+" grammar based approach to rather than using a few heuristics.  The result
+" is large and somewhat repetative but seems to work.
+
+" There are some Microsoft extensions to idl files that are here.  Some of
+" them are disabled by defining idl_no_ms_extensions.
+"
+" The more complex of the extensions are disabled by defining idl_no_extensions.
+"
+" History:
+" 2.0: Michael's new version
+" 2.1: Support for Vim 7 spell (Anduin Withers)
+"      
+
+if exists("b:current_syntax")
+  finish
+endif
+
+if exists("idlsyntax_showerror")
+  syn match idlError +\S+ skipwhite skipempty nextgroup=idlError
+endif
+
+syn region idlCppQuote start='\<cpp_quote\s*(' end=')' contains=idlString
+
+" Misc basic
+syn match   idlId          contained "[a-zA-Z][a-zA-Z0-9_]*" skipwhite skipempty nextgroup=idlEnumComma,idlEnumNumber
+syn match   idlEnumComma   contained ","
+syn match   idlEnumNumber  contained "=" skipwhite skipempty nextgroup=idlString,idlLiteral
+syn match   idlSemiColon   contained ";"
+syn match   idlCommaArg    contained ","                      skipempty skipwhite nextgroup=idlSimpDecl
+syn region  idlArraySize1  contained start=:\[: end=:\]:      skipempty skipwhite nextgroup=idlArraySize1,idlError,idlSemiColon,idlCommaArg contains=idlArraySize1,idlLiteral
+syn match   idlSimpDecl    contained "[a-zA-Z][a-zA-Z0-9_]*"  skipempty skipwhite nextgroup=idlError,idlSemiColon,idlCommaArg,idlArraySize1
+syn region  idlString      contained start=+"+  skip=+\\\(\\\\\)*"+  end=+"+ contains=@Spell
+syn match   idlLiteral     contained "[1-9]\d*\(\.\d*\)\="
+syn match   idlLiteral     contained "0"
+syn match   idlLiteral     contained "\.\d\+"
+syn match   idlLiteral     contained "0x[0-9A-Fa-f]\+"
+syn match   idlLiteral     contained "0[0-7]\+"
+syn keyword idlLiteral     contained TRUE FALSE
+
+" Comments
+syn keyword idlTodo        contained TODO FIXME XXX
+syn region idlComment      start="/\*"  end="\*/" contains=idlTodo,@Spell
+syn match  idlComment      "//.*" contains=idlTodo,@Spell
+syn match  idlCommentError "\*/"
+
+" C style Preprocessor
+syn region idlIncluded    contained start=+"+  skip=+\\\(\\\\\)*"+  end=+"+
+syn match  idlIncluded    contained "<[^>]*>"
+syn match  idlInclude     "^[ \t]*#[ \t]*include\>[ \t]*["<]" contains=idlIncluded,idlString
+syn region idlPreCondit   start="^[ \t]*#[ \t]*\(if\>\|ifdef\>\|ifndef\>\|elif\>\|else\>\|endif\>\)"  skip="\\$"  end="$" contains=idlComment,idlCommentError
+syn region idlDefine      start="^[ \t]*#[ \t]*\(define\>\|undef\>\)" skip="\\$" end="$" contains=idlLiteral,idlString
+
+" Constants
+syn keyword idlConst    const                             skipempty skipwhite nextgroup=idlBaseType,idlBaseTypeInt
+
+" Attribute
+syn keyword idlROAttr   readonly                          skipempty skipwhite nextgroup=idlAttr
+syn keyword idlAttr     attribute                         skipempty skipwhite nextgroup=idlBaseTypeInt,idlBaseType
+
+" Types
+syn region  idlD4          contained start="<" end=">"    skipempty skipwhite nextgroup=idlSimpDecl contains=idlSeqType,idlBaseTypeInt,idlBaseType,idlLiteral
+syn keyword idlSeqType     contained sequence             skipempty skipwhite nextgroup=idlD4
+syn keyword idlBaseType    contained float double char boolean octet any skipempty skipwhite nextgroup=idlSimpDecl
+syn keyword idlBaseTypeInt contained short long           skipempty skipwhite nextgroup=idlSimpDecl
+syn keyword idlBaseType    contained unsigned             skipempty skipwhite nextgroup=idlBaseTypeInt
+syn region  idlD1          contained start="<" end=">"    skipempty skipwhite nextgroup=idlSimpDecl contains=idlString,idlLiteral
+syn keyword idlBaseType    contained string               skipempty skipwhite nextgroup=idlD1,idlSimpDecl
+syn match   idlBaseType    contained "[a-zA-Z0-9_]\+[ \t]*\(::[ \t]*[a-zA-Z0-9_]\+\)*"  skipempty skipwhite nextgroup=idlSimpDecl
+
+" Modules
+syn region  idlModuleContent contained start="{" end="}"  skipempty skipwhite nextgroup=idlError,idlSemiColon contains=idlUnion,idlStruct,idlEnum,idlInterface,idlComment,idlTypedef,idlConst,idlException,idlModule
+syn match   idlModuleName  contained "[a-zA-Z0-9_]\+"     skipempty skipwhite nextgroup=idlModuleContent,idlError,idlSemiColon
+syn keyword idlModule      module                         skipempty skipwhite nextgroup=idlModuleName
+
+" Interfaces
+syn cluster idlCommentable contains=idlComment
+syn cluster idlContentCluster contains=idlUnion,idlStruct,idlEnum,idlROAttr,idlAttr,idlOp,idlOneWayOp,idlException,idlConst,idlTypedef,idlAttributes,idlErrorSquareBracket,idlErrorBracket,idlInterfaceSections
+
+syn region  idlInterfaceContent contained start="{" end="}"   skipempty skipwhite nextgroup=idlError,idlSemiColon contains=@idlContentCluster,@idlCommentable
+syn match   idlInheritFrom2 contained ","                     skipempty skipwhite nextgroup=idlInheritFrom
+syn match   idlInheritFrom contained "[a-zA-Z0-9_]\+[ \t]*\(::[ \t]*[a-zA-Z0-9_]\+\)*" skipempty skipwhite nextgroup=idlInheritFrom2,idlInterfaceContent
+syn match   idlInherit contained ":"                            skipempty skipwhite nextgroup=idlInheritFrom
+syn match   idlInterfaceName contained "[a-zA-Z0-9_]\+"       skipempty skipwhite nextgroup=idlInterfaceContent,idlInherit,idlError,idlSemiColon
+syn keyword idlInterface     interface dispinterface          skipempty skipwhite nextgroup=idlInterfaceName
+syn keyword idlInterfaceSections contained properties methods skipempty skipwhite nextgroup=idlSectionColon,idlError
+syn match   idlSectionColon contained ":"
+
+
+syn match   idlLibraryName  contained  "[a-zA-Z0-9_]\+"       skipempty skipwhite nextgroup=idlLibraryContent,idlError,idlSemiColon
+syn keyword idlLibrary      library                           skipempty skipwhite nextgroup=idlLibraryName
+syn region  idlLibraryContent contained start="{" end="}"     skipempty skipwhite nextgroup=idlError,idlSemiColon contains=@idlCommentable,idlAttributes,idlErrorSquareBracket,idlErrorBracket,idlImportlib,idlCoclass,idlTypedef,idlInterface
+
+syn keyword idlImportlib contained importlib                  skipempty skipwhite nextgroup=idlStringArg
+syn region idlStringArg contained start="(" end=")"           contains=idlString nextgroup=idlError,idlSemiColon,idlErrorBrace,idlErrorSquareBracket
+
+syn keyword idlCoclass coclass contained                      skipempty skipwhite nextgroup=idlCoclassName
+syn match   idlCoclassName "[a-zA-Z0-9_]\+" contained         skipempty skipwhite nextgroup=idlCoclassDefinition,idlError,idlSemiColon
+
+syn region idlCoclassDefinition contained start="{" end="}"   contains=idlCoclassAttributes,idlInterface,idlErrorBracket,idlErrorSquareBracket skipempty skipwhite nextgroup=idlError,idlSemiColon
+syn region idlCoclassAttributes contained start=+\[+ end=+]+  skipempty skipwhite nextgroup=idlInterface contains=idlErrorBracket,idlErrorBrace,idlCoclassAttribute
+syn keyword idlCoclassAttribute contained default source
+"syn keyword idlInterface       interface                      skipempty skipwhite nextgroup=idlInterfaceStubName
+
+syn match idlImportString       +"\f\+"+                      skipempty skipwhite nextgroup=idlError,idlSemiColon
+syn keyword idlImport           import                        skipempty skipwhite nextgroup=idlImportString
+
+syn region  idlAttributes start="\[" end="\]"                 contains=idlAttribute,idlAttributeParam,idlErrorBracket,idlErrorBrace,idlComment
+syn keyword idlAttribute contained propput propget propputref id helpstring object uuid pointer_default
+if !exists('idl_no_ms_extensions')
+syn keyword idlAttribute contained nonextensible dual version aggregatable restricted hidden noncreatable oleautomation
+endif
+syn region idlAttributeParam contained start="(" end=")"      contains=idlString,idlUuid,idlLiteral,idlErrorBrace,idlErrorSquareBracket
+" skipwhite nextgroup=idlArraySize,idlParmList contains=idlArraySize,idlLiteral
+syn match idlErrorBrace contained "}"
+syn match idlErrorBracket contained ")"
+syn match idlErrorSquareBracket contained "\]"
+
+syn match idlUuid         contained +[0-9a-zA-Z]\{8}-\([0-9a-zA-Z]\{4}-\)\{3}[0-9a-zA-Z]\{12}+
+
+" Raises
+syn keyword idlRaises     contained raises               skipempty skipwhite nextgroup=idlRaises,idlContext,idlError,idlSemiColon
+
+" Context
+syn keyword idlContext    contained context              skipempty skipwhite nextgroup=idlRaises,idlContext,idlError,idlSemiColon
+
+" Operation
+syn match   idlParmList   contained ","                  skipempty skipwhite nextgroup=idlOpParms
+syn region  idlArraySize  contained start="\[" end="\]"  skipempty skipwhite nextgroup=idlArraySize,idlParmList contains=idlArraySize,idlLiteral
+syn match   idlParmName   contained "[a-zA-Z0-9_]\+"     skipempty skipwhite nextgroup=idlParmList,idlArraySize
+syn keyword idlParmInt    contained short long           skipempty skipwhite nextgroup=idlParmName
+syn keyword idlParmType   contained unsigned             skipempty skipwhite nextgroup=idlParmInt
+syn region  idlD3         contained start="<" end=">"    skipempty skipwhite nextgroup=idlParmName contains=idlString,idlLiteral
+syn keyword idlParmType   contained string               skipempty skipwhite nextgroup=idlD3,idlParmName
+syn keyword idlParmType   contained void float double char boolean octet any    skipempty skipwhite nextgroup=idlParmName
+syn match   idlParmType   contained "[a-zA-Z0-9_]\+[ \t]*\(::[ \t]*[a-zA-Z0-9_]\+\)*" skipempty skipwhite nextgroup=idlParmName
+syn keyword idlOpParms    contained in out inout         skipempty skipwhite nextgroup=idlParmType
+
+if !exists('idl_no_ms_extensions')
+syn keyword idlOpParms    contained retval optional      skipempty skipwhite nextgroup=idlParmType
+  syn match idlOpParms contained +\<\(iid_is\|defaultvalue\)\s*([^)]*)+ skipempty skipwhite nextgroup=idlParamType
+
+  syn keyword idlVariantType  contained BSTR VARIANT VARIANT_BOOL long short unsigned double CURRENCY DATE
+  syn region idlSafeArray contained matchgroup=idlVariantType start=+SAFEARRAY(\s*+ end=+)+ contains=idlVariantType
+endif
+
+syn region  idlOpContents contained start="(" end=")"    skipempty skipwhite nextgroup=idlRaises,idlContext,idlError,idlSemiColon contains=idlOpParms,idlSafeArray,idlVariantType,@idlCommentable
+syn match   idlOpName   contained "[a-zA-Z0-9_]\+"       skipempty skipwhite nextgroup=idlOpContents
+syn keyword idlOpInt    contained short long             skipempty skipwhite nextgroup=idlOpName
+syn region  idlD2       contained start="<" end=">"      skipempty skipwhite nextgroup=idlOpName contains=idlString,idlLiteral
+syn keyword idlOp       contained unsigned               skipempty skipwhite nextgroup=idlOpInt
+syn keyword idlOp       contained string                 skipempty skipwhite nextgroup=idlD2,idlOpName
+syn keyword idlOp       contained void float double char boolean octet any  skipempty skipwhite nextgroup=idlOpName
+syn match   idlOp       contained "[a-zA-Z0-9_]\+[ \t]*\(::[ \t]*[a-zA-Z0-9_]\+\)*" skipempty skipwhite nextgroup=idlOpName
+syn keyword idlOp       contained void                   skipempty skipwhite nextgroup=idlOpName
+syn keyword idlOneWayOp contained oneway                 skipempty skipwhite nextgroup=idOp
+
+" Enum
+syn region  idlEnumContents contained start="{" end="}"  skipempty skipwhite nextgroup=idlError,idlSemiColon,idlSimpDecl contains=idlId,idlAttributes,@idlCommentable
+syn match   idlEnumName contained "[a-zA-Z0-9_]\+"       skipempty skipwhite nextgroup=idlEnumContents
+syn keyword idlEnum     enum                             skipempty skipwhite nextgroup=idlEnumName,idlEnumContents
+
+" Typedef
+syn keyword idlTypedef typedef                          skipempty skipwhite nextgroup=idlTypedefOtherTypeQualifier,idlDefBaseType,idlDefBaseTypeInt,idlDefSeqType,idlDefv1Enum,idlDefEnum,idlDefOtherType,idlDefAttributes,idlError
+
+if !exists('idl_no_extensions')
+  syn keyword idlTypedefOtherTypeQualifier contained struct enum interface nextgroup=idlDefBaseType,idlDefBaseTypeInt,idlDefSeqType,idlDefv1Enum,idlDefEnum,idlDefOtherType,idlDefAttributes,idlError skipwhite
+
+  syn region  idlDefAttributes        contained start="\[" end="\]" contains=idlAttribute,idlAttributeParam,idlErrorBracket,idlErrorBrace skipempty skipwhite nextgroup=idlDefBaseType,idlDefBaseTypeInt,idlDefSeqType,idlDefv1Enum,idlDefEnum,idlDefOtherType,idlError
+
+  syn keyword idlDefBaseType      contained float double char boolean octet any  skipempty skipwhite nextgroup=idlTypedefDecl,idlError
+  syn keyword idlDefBaseTypeInt   contained short long                           skipempty skipwhite nextgroup=idlTypedefDecl,idlError
+  syn match idlDefOtherType       contained +\<\k\+\>+ skipempty                 nextgroup=idlTypedefDecl,idlError
+  " syn keyword idlDefSeqType     contained sequence                             skipempty skipwhite nextgroup=idlD4
+
+  " Enum typedef
+  syn keyword idlDefEnum          contained enum skipempty                       skipwhite nextgroup=idlDefEnumName,idlDefEnumContents
+  syn match   idlDefEnumName      contained "[a-zA-Z0-9_]\+"                     skipempty skipwhite nextgroup=idlDefEnumContents,idlTypedefDecl
+  syn region  idlDefEnumContents  contained start="{" end="}"                    skipempty skipwhite nextgroup=idlError,idlTypedefDecl contains=idlId,idlAttributes
+
+  syn match   idlTypedefDecl      contained "[a-zA-Z0-9_]\+"                     skipempty skipwhite nextgroup=idlError,idlSemiColon
+endif
+
+" Struct
+syn region  idlStructContent   contained start="{" end="}"   skipempty skipwhite nextgroup=idlError,idlSemiColon,idlSimpDecl contains=idlBaseType,idlBaseTypeInt,idlSeqType,@idlCommentable,idlEnum,idlUnion
+syn match   idlStructName      contained "[a-zA-Z0-9_]\+"    skipempty skipwhite nextgroup=idlStructContent
+syn keyword idlStruct          struct                        skipempty skipwhite nextgroup=idlStructName
+
+" Exception
+syn keyword idlException       exception                     skipempty skipwhite nextgroup=idlStructName
+
+" Union
+syn match   idlColon            contained ":"                skipempty skipwhite nextgroup=idlCase,idlSeqType,idlBaseType,idlBaseTypeInt
+syn region  idlCaseLabel        contained start="" skip="::" end=":"me=e-1 skipempty skipwhite nextgroup=idlColon contains=idlLiteral,idlString
+syn keyword idlCase             contained case               skipempty skipwhite nextgroup=idlCaseLabel
+syn keyword idlCase             contained default            skipempty skipwhite nextgroup=idlColon
+syn region  idlUnionContent     contained start="{" end="}"  skipempty skipwhite nextgroup=idlError,idlSemiColon,idlSimpDecl contains=idlCase
+syn region  idlSwitchType       contained start="(" end=")"  skipempty skipwhite nextgroup=idlUnionContent
+syn keyword idlUnionSwitch      contained switch             skipempty skipwhite nextgroup=idlSwitchType
+syn match   idlUnionName        contained "[a-zA-Z0-9_]\+"   skipempty skipwhite nextgroup=idlUnionSwitch
+syn keyword idlUnion            union                        skipempty skipwhite nextgroup=idlUnionName
+
+if !exists('idl_no_extensions')
+  syn sync match  idlInterfaceSync grouphere idlInterfaceContent "\<\(disp\)\=interface\>\s\+\k\+\s*:\s*\k\+\_s*{" skipempty skipwhite nextgroup=idlError,idlSemiColon contains=@idlContentCluster,@idlCommentable
+  syn sync maxlines=1000 minlines=100
+else
+  syn sync lines=200
+endif
+" syn sync fromstart
+
+if !exists("did_idl_syntax_inits")
+  let did_idl_syntax_inits = 1
+  " The default methods for highlighting.  Can be overridden later
+  command -nargs=+ HiLink hi def link <args>
+
+  HiLink idlInclude             Include
+  HiLink idlPreProc             PreProc
+  HiLink idlPreCondit           PreCondit
+  HiLink idlDefine              Macro
+  HiLink idlIncluded            String
+  HiLink idlString              String
+  HiLink idlComment             Comment
+  HiLink idlTodo                Todo
+  HiLink idlLiteral             Number
+  HiLink idlUuid                Number
+  HiLink idlType                Type
+  HiLink idlVariantType         idlType
+
+  HiLink idlModule              Keyword
+  HiLink idlInterface           Keyword
+  HiLink idlEnum                Keyword
+  HiLink idlStruct              Keyword
+  HiLink idlUnion               Keyword
+  HiLink idlTypedef             Keyword
+  HiLink idlException           Keyword
+  HiLink idlTypedefOtherTypeQualifier keyword
+
+  HiLink idlModuleName          Typedef
+  HiLink idlInterfaceName       Typedef
+  HiLink idlEnumName            Typedef
+  HiLink idlStructName          Typedef
+  HiLink idlUnionName           Typedef
+
+  HiLink idlBaseTypeInt         idlType
+  HiLink idlBaseType            idlType
+  HiLink idlSeqType             idlType
+  HiLink idlD1                  Paren
+  HiLink idlD2                  Paren
+  HiLink idlD3                  Paren
+  HiLink idlD4                  Paren
+  "HiLink idlArraySize          Paren
+  "HiLink idlArraySize1         Paren
+  HiLink idlModuleContent       Paren
+  HiLink idlUnionContent        Paren
+  HiLink idlStructContent       Paren
+  HiLink idlEnumContents        Paren
+  HiLink idlInterfaceContent    Paren
+
+  HiLink idlSimpDecl            Identifier
+  HiLink idlROAttr              StorageClass
+  HiLink idlAttr                Keyword
+  HiLink idlConst               StorageClass
+
+  HiLink idlOneWayOp            StorageClass
+  HiLink idlOp                  idlType
+  HiLink idlParmType            idlType
+  HiLink idlOpName              Function
+  HiLink idlOpParms             SpecialComment
+  HiLink idlParmName            Identifier
+  HiLink idlInheritFrom         Identifier
+  HiLink idlAttribute           SpecialComment
+
+  HiLink idlId                  Constant
+  "HiLink idlCase               Keyword
+  HiLink idlCaseLabel           Constant
+
+  HiLink idlErrorBracket        Error
+  HiLink idlErrorBrace          Error
+  HiLink idlErrorSquareBracket  Error
+
+  HiLink idlImport              Keyword
+  HiLink idlImportString        idlString
+  HiLink idlCoclassAttribute    StorageClass
+  HiLink idlLibrary             Keyword
+  HiLink idlImportlib           Keyword
+  HiLink idlCoclass             Keyword
+  HiLink idlLibraryName         Typedef
+  HiLink idlCoclassName         Typedef
+  " hi idlLibraryContent guifg=red
+  HiLink idlTypedefDecl         Typedef
+  HiLink idlDefEnum             Keyword
+  HiLink idlDefv1Enum           Keyword
+  HiLink idlDefEnumName         Typedef
+  HiLink idlDefEnumContents     Paren
+  HiLink idlDefBaseTypeInt      idlType
+  HiLink idlDefBaseType         idlType
+  HiLink idlDefSeqType          idlType
+  HiLink idlInterfaceSections   Label
+
+  if exists("idlsyntax_showerror")
+    if exists("idlsyntax_showerror_soft")
+      hi default idlError guibg=#d0ffd0
+    else
+      HiLink idlError Error
+    endif
+  endif
+  delcommand HiLink
+endif
+
+let b:current_syntax = "idl"
+
+" vim: sw=2 et
--- /dev/null
+++ b/lib/vimfiles/syntax/idlang.vim
@@ -1,0 +1,253 @@
+" Interactive Data Language syntax file (IDL, too  [:-)]
+" Maintainer: Aleksandar Jelenak <ajelenak AT yahoo.com>
+" Last change: 2003 Apr 25
+" Created by: Hermann Rochholz <Hermann.Rochholz AT gmx.de>
+
+" Remove any old syntax stuff hanging around
+" For version 5.x: Clear all syntax items
+" For version 6.x: Quit when a syntax file was already loaded
+if version < 600
+  syntax clear
+elseif exists("b:current_syntax")
+  finish
+endif
+
+syntax case ignore
+
+syn match idlangStatement "^\s*pro\s"
+syn match idlangStatement "^\s*function\s"
+syn keyword idlangStatement return continue mod do break
+syn keyword idlangStatement compile_opt forward_function goto
+syn keyword idlangStatement begin common end of
+syn keyword idlangStatement inherits on_ioerror begin
+
+syn keyword idlangConditional if else then for while case switch
+syn keyword idlangConditional endcase endelse endfor endswitch
+syn keyword idlangConditional endif endrep endwhile repeat until
+
+syn match idlangOperator "\ and\ "
+syn match idlangOperator "\ eq\ "
+syn match idlangOperator "\ ge\ "
+syn match idlangOperator "\ gt\ "
+syn match idlangOperator "\ le\ "
+syn match idlangOperator "\ lt\ "
+syn match idlangOperator "\ ne\ "
+syn match idlangOperator /\(\ \|(\)not\ /hs=e-3
+syn match idlangOperator "\ or\ "
+syn match idlangOperator "\ xor\ "
+
+syn keyword idlangStop stop pause
+
+syn match idlangStrucvar "\h\w*\(\.\h\w*\)\+"
+syn match idlangStrucvar "[),\]]\(\.\h\w*\)\+"hs=s+1
+
+syn match idlangSystem "\!\a\w*\(\.\w*\)\="
+
+syn match idlangKeyword "\([(,]\s*\(\$\_s*\)\=\)\@<=/\h\w*"
+syn match idlangKeyword "\([(,]\s*\(\$\_s*\)\=\)\@<=\h\w*\s*="
+
+syn keyword idlangTodo contained TODO
+
+syn region idlangString start=+"+ end=+"+
+syn region idlangString start=+'+ end=+'+
+
+syn match idlangPreCondit "^\s*@\w*\(\.\a\{3}\)\="
+
+syn match idlangRealNumber "\<\d\+\(\.\=\d*e[+-]\=\d\+\|\.\d*d\|\.\d*\|d\)"
+syn match idlangRealNumber "\.\d\+\(d\|e[+-]\=\d\+\)\="
+
+syn match idlangNumber "\<\.\@!\d\+\.\@!\(b\|u\|us\|s\|l\|ul\|ll\|ull\)\=\>"
+
+syn match  idlangComment "[\;].*$" contains=idlangTodo
+
+syn match idlangContinueLine "\$\s*\($\|;\)"he=s+1 contains=idlangComment
+syn match idlangContinueLine "&\s*\(\h\|;\)"he=s+1 contains=ALL
+
+syn match  idlangDblCommaError "\,\s*\,"
+
+" List of standard routines as of IDL version 5.4.
+syn match idlangRoutine "EOS_\a*"
+syn match idlangRoutine "HDF_\a*"
+syn match idlangRoutine "CDF_\a*"
+syn match idlangRoutine "NCDF_\a*"
+syn match idlangRoutine "QUERY_\a*"
+syn match idlangRoutine "\<MAX\s*("he=e-1
+syn match idlangRoutine "\<MIN\s*("he=e-1
+
+syn keyword idlangRoutine A_CORRELATE ABS ACOS ADAPT_HIST_EQUAL ALOG ALOG10
+syn keyword idlangRoutine AMOEBA ANNOTATE ARG_PRESENT ARRAY_EQUAL ARROW
+syn keyword idlangRoutine ASCII_TEMPLATE ASIN ASSOC ATAN AXIS BAR_PLOT
+syn keyword idlangRoutine BESELI BESELJ BESELK BESELY BETA BILINEAR BIN_DATE
+syn keyword idlangRoutine BINARY_TEMPLATE BINDGEN BINOMIAL BLAS_AXPY BLK_CON
+syn keyword idlangRoutine BOX_CURSOR BREAK BREAKPOINT BROYDEN BYTARR BYTE
+syn keyword idlangRoutine BYTEORDER BYTSCL C_CORRELATE CALDAT CALENDAR
+syn keyword idlangRoutine CALL_EXTERNAL CALL_FUNCTION CALL_METHOD
+syn keyword idlangRoutine CALL_PROCEDURE CATCH CD CEIL CHEBYSHEV CHECK_MATH
+syn keyword idlangRoutine CHISQR_CVF CHISQR_PDF CHOLDC CHOLSOL CINDGEN
+syn keyword idlangRoutine CIR_3PNT CLOSE CLUST_WTS CLUSTER COLOR_CONVERT
+syn keyword idlangRoutine COLOR_QUAN COLORMAP_APPLICABLE COMFIT COMMON
+syn keyword idlangRoutine COMPLEX COMPLEXARR COMPLEXROUND
+syn keyword idlangRoutine COMPUTE_MESH_NORMALS COND CONGRID CONJ
+syn keyword idlangRoutine CONSTRAINED_MIN CONTOUR CONVERT_COORD CONVOL
+syn keyword idlangRoutine COORD2TO3 CORRELATE COS COSH CRAMER CREATE_STRUCT
+syn keyword idlangRoutine CREATE_VIEW CROSSP CRVLENGTH CT_LUMINANCE CTI_TEST
+syn keyword idlangRoutine CURSOR CURVEFIT CV_COORD CVTTOBM CW_ANIMATE
+syn keyword idlangRoutine CW_ANIMATE_GETP CW_ANIMATE_LOAD CW_ANIMATE_RUN
+syn keyword idlangRoutine CW_ARCBALL CW_BGROUP CW_CLR_INDEX CW_COLORSEL
+syn keyword idlangRoutine CW_DEFROI CW_FIELD CW_FILESEL CW_FORM CW_FSLIDER
+syn keyword idlangRoutine CW_LIGHT_EDITOR CW_LIGHT_EDITOR_GET
+syn keyword idlangRoutine CW_LIGHT_EDITOR_SET CW_ORIENT CW_PALETTE_EDITOR
+syn keyword idlangRoutine CW_PALETTE_EDITOR_GET CW_PALETTE_EDITOR_SET
+syn keyword idlangRoutine CW_PDMENU CW_RGBSLIDER CW_TMPL CW_ZOOM DBLARR
+syn keyword idlangRoutine DCINDGEN DCOMPLEX DCOMPLEXARR DEFINE_KEY DEFROI
+syn keyword idlangRoutine DEFSYSV DELETE_SYMBOL DELLOG DELVAR DERIV DERIVSIG
+syn keyword idlangRoutine DETERM DEVICE DFPMIN DIALOG_MESSAGE
+syn keyword idlangRoutine DIALOG_PICKFILE DIALOG_PRINTERSETUP
+syn keyword idlangRoutine DIALOG_PRINTJOB DIALOG_READ_IMAGE
+syn keyword idlangRoutine DIALOG_WRITE_IMAGE DIGITAL_FILTER DILATE DINDGEN
+syn keyword idlangRoutine DISSOLVE DIST DLM_LOAD DLM_REGISTER
+syn keyword idlangRoutine DO_APPLE_SCRIPT DOC_LIBRARY DOUBLE DRAW_ROI EFONT
+syn keyword idlangRoutine EIGENQL EIGENVEC ELMHES EMPTY ENABLE_SYSRTN EOF
+syn keyword idlangRoutine ERASE ERODE ERRORF ERRPLOT EXECUTE EXIT EXP EXPAND
+syn keyword idlangRoutine EXPAND_PATH EXPINT EXTRAC EXTRACT_SLICE F_CVF
+syn keyword idlangRoutine F_PDF FACTORIAL FFT FILE_CHMOD FILE_DELETE
+syn keyword idlangRoutine FILE_EXPAND_PATH FILE_MKDIR FILE_TEST FILE_WHICH
+syn keyword idlangRoutine FILEPATH FINDFILE FINDGEN FINITE FIX FLICK FLOAT
+syn keyword idlangRoutine FLOOR FLOW3 FLTARR FLUSH FOR FORMAT_AXIS_VALUES
+syn keyword idlangRoutine FORWARD_FUNCTION FREE_LUN FSTAT FULSTR FUNCT
+syn keyword idlangRoutine FV_TEST FX_ROOT FZ_ROOTS GAMMA GAMMA_CT
+syn keyword idlangRoutine GAUSS_CVF GAUSS_PDF GAUSS2DFIT GAUSSFIT GAUSSINT
+syn keyword idlangRoutine GET_DRIVE_LIST GET_KBRD GET_LUN GET_SCREEN_SIZE
+syn keyword idlangRoutine GET_SYMBOL GETENV GOTO GRID_TPS GRID3 GS_ITER
+syn keyword idlangRoutine H_EQ_CT H_EQ_INT HANNING HEAP_GC HELP HILBERT
+syn keyword idlangRoutine HIST_2D HIST_EQUAL HISTOGRAM HLS HOUGH HQR HSV
+syn keyword idlangRoutine IBETA IDENTITY IDL_Container IDLanROI
+syn keyword idlangRoutine IDLanROIGroup IDLffDICOM IDLffDXF IDLffLanguageCat
+syn keyword idlangRoutine IDLffShape IDLgrAxis IDLgrBuffer IDLgrClipboard
+syn keyword idlangRoutine IDLgrColorbar IDLgrContour IDLgrFont IDLgrImage
+syn keyword idlangRoutine IDLgrLegend IDLgrLight IDLgrModel IDLgrMPEG
+syn keyword idlangRoutine IDLgrPalette IDLgrPattern IDLgrPlot IDLgrPolygon
+syn keyword idlangRoutine IDLgrPolyline IDLgrPrinter IDLgrROI IDLgrROIGroup
+syn keyword idlangRoutine IDLgrScene IDLgrSurface IDLgrSymbol
+syn keyword idlangRoutine IDLgrTessellator IDLgrText IDLgrView
+syn keyword idlangRoutine IDLgrViewgroup IDLgrVolume IDLgrVRML IDLgrWindow
+syn keyword idlangRoutine IGAMMA IMAGE_CONT IMAGE_STATISTICS IMAGINARY
+syn keyword idlangRoutine INDGEN INT_2D INT_3D INT_TABULATED INTARR INTERPOL
+syn keyword idlangRoutine INTERPOLATE INVERT IOCTL ISHFT ISOCONTOUR
+syn keyword idlangRoutine ISOSURFACE JOURNAL JULDAY KEYWORD_SET KRIG2D
+syn keyword idlangRoutine KURTOSIS KW_TEST L64INDGEN LABEL_DATE LABEL_REGION
+syn keyword idlangRoutine LADFIT LAGUERRE LEEFILT LEGENDRE LINBCG LINDGEN
+syn keyword idlangRoutine LINFIT LINKIMAGE LIVE_CONTOUR LIVE_CONTROL
+syn keyword idlangRoutine LIVE_DESTROY LIVE_EXPORT LIVE_IMAGE LIVE_INFO
+syn keyword idlangRoutine LIVE_LINE LIVE_LOAD LIVE_OPLOT LIVE_PLOT
+syn keyword idlangRoutine LIVE_PRINT LIVE_RECT LIVE_STYLE LIVE_SURFACE
+syn keyword idlangRoutine LIVE_TEXT LJLCT LL_ARC_DISTANCE LMFIT LMGR LNGAMMA
+syn keyword idlangRoutine LNP_TEST LOADCT LOCALE_GET LON64ARR LONARR LONG
+syn keyword idlangRoutine LONG64 LSODE LU_COMPLEX LUDC LUMPROVE LUSOL
+syn keyword idlangRoutine M_CORRELATE MACHAR MAKE_ARRAY MAKE_DLL MAP_2POINTS
+syn keyword idlangRoutine MAP_CONTINENTS MAP_GRID MAP_IMAGE MAP_PATCH
+syn keyword idlangRoutine MAP_PROJ_INFO MAP_SET MATRIX_MULTIPLY MD_TEST MEAN
+syn keyword idlangRoutine MEANABSDEV MEDIAN MEMORY MESH_CLIP MESH_DECIMATE
+syn keyword idlangRoutine MESH_ISSOLID MESH_MERGE MESH_NUMTRIANGLES MESH_OBJ
+syn keyword idlangRoutine MESH_SMOOTH MESH_SURFACEAREA MESH_VALIDATE
+syn keyword idlangRoutine MESH_VOLUME MESSAGE MIN_CURVE_SURF MK_HTML_HELP
+syn keyword idlangRoutine MODIFYCT MOMENT MORPH_CLOSE MORPH_DISTANCE
+syn keyword idlangRoutine MORPH_GRADIENT MORPH_HITORMISS MORPH_OPEN
+syn keyword idlangRoutine MORPH_THIN MORPH_TOPHAT MPEG_CLOSE MPEG_OPEN
+syn keyword idlangRoutine MPEG_PUT MPEG_SAVE MSG_CAT_CLOSE MSG_CAT_COMPILE
+syn keyword idlangRoutine MSG_CAT_OPEN MULTI N_ELEMENTS N_PARAMS N_TAGS
+syn keyword idlangRoutine NEWTON NORM OBJ_CLASS OBJ_DESTROY OBJ_ISA OBJ_NEW
+syn keyword idlangRoutine OBJ_VALID OBJARR ON_ERROR ON_IOERROR ONLINE_HELP
+syn keyword idlangRoutine OPEN OPENR OPENW OPLOT OPLOTERR P_CORRELATE
+syn keyword idlangRoutine PARTICLE_TRACE PCOMP PLOT PLOT_3DBOX PLOT_FIELD
+syn keyword idlangRoutine PLOTERR PLOTS PNT_LINE POINT_LUN POLAR_CONTOUR
+syn keyword idlangRoutine POLAR_SURFACE POLY POLY_2D POLY_AREA POLY_FIT
+syn keyword idlangRoutine POLYFILL POLYFILLV POLYSHADE POLYWARP POPD POWELL
+syn keyword idlangRoutine PRIMES PRINT PRINTF PRINTD PROFILE PROFILER
+syn keyword idlangRoutine PROFILES PROJECT_VOL PS_SHOW_FONTS PSAFM PSEUDO
+syn keyword idlangRoutine PTR_FREE PTR_NEW PTR_VALID PTRARR PUSHD QROMB
+syn keyword idlangRoutine QROMO QSIMP R_CORRELATE R_TEST RADON RANDOMN
+syn keyword idlangRoutine RANDOMU RANKS RDPIX READ READF READ_ASCII
+syn keyword idlangRoutine READ_BINARY READ_BMP READ_DICOM READ_IMAGE
+syn keyword idlangRoutine READ_INTERFILE READ_JPEG READ_PICT READ_PNG
+syn keyword idlangRoutine READ_PPM READ_SPR READ_SRF READ_SYLK READ_TIFF
+syn keyword idlangRoutine READ_WAV READ_WAVE READ_X11_BITMAP READ_XWD READS
+syn keyword idlangRoutine READU REBIN RECALL_COMMANDS RECON3 REDUCE_COLORS
+syn keyword idlangRoutine REFORM REGRESS REPLICATE REPLICATE_INPLACE
+syn keyword idlangRoutine RESOLVE_ALL RESOLVE_ROUTINE RESTORE RETALL RETURN
+syn keyword idlangRoutine REVERSE REWIND RK4 ROBERTS ROT ROTATE ROUND
+syn keyword idlangRoutine ROUTINE_INFO RS_TEST S_TEST SAVE SAVGOL SCALE3
+syn keyword idlangRoutine SCALE3D SEARCH2D SEARCH3D SET_PLOT SET_SHADING
+syn keyword idlangRoutine SET_SYMBOL SETENV SETLOG SETUP_KEYS SFIT
+syn keyword idlangRoutine SHADE_SURF SHADE_SURF_IRR SHADE_VOLUME SHIFT SHOW3
+syn keyword idlangRoutine SHOWFONT SIN SINDGEN SINH SIZE SKEWNESS SKIPF
+syn keyword idlangRoutine SLICER3 SLIDE_IMAGE SMOOTH SOBEL SOCKET SORT SPAWN
+syn keyword idlangRoutine SPH_4PNT SPH_SCAT SPHER_HARM SPL_INIT SPL_INTERP
+syn keyword idlangRoutine SPLINE SPLINE_P SPRSAB SPRSAX SPRSIN SPRSTP SQRT
+syn keyword idlangRoutine STANDARDIZE STDDEV STOP STRARR STRCMP STRCOMPRESS
+syn keyword idlangRoutine STREAMLINE STREGEX STRETCH STRING STRJOIN STRLEN
+syn keyword idlangRoutine STRLOWCASE STRMATCH STRMESSAGE STRMID STRPOS
+syn keyword idlangRoutine STRPUT STRSPLIT STRTRIM STRUCT_ASSIGN STRUCT_HIDE
+syn keyword idlangRoutine STRUPCASE SURFACE SURFR SVDC SVDFIT SVSOL
+syn keyword idlangRoutine SWAP_ENDIAN SWITCH SYSTIME T_CVF T_PDF T3D
+syn keyword idlangRoutine TAG_NAMES TAN TANH TAPRD TAPWRT TEK_COLOR
+syn keyword idlangRoutine TEMPORARY TETRA_CLIP TETRA_SURFACE TETRA_VOLUME
+syn keyword idlangRoutine THIN THREED TIME_TEST2 TIMEGEN TM_TEST TOTAL TRACE
+syn keyword idlangRoutine TRANSPOSE TRI_SURF TRIANGULATE TRIGRID TRIQL
+syn keyword idlangRoutine TRIRED TRISOL TRNLOG TS_COEF TS_DIFF TS_FCAST
+syn keyword idlangRoutine TS_SMOOTH TV TVCRS TVLCT TVRD TVSCL UINDGEN UINT
+syn keyword idlangRoutine UINTARR UL64INDGEN ULINDGEN ULON64ARR ULONARR
+syn keyword idlangRoutine ULONG ULONG64 UNIQ USERSYM VALUE_LOCATE VARIANCE
+syn keyword idlangRoutine VAX_FLOAT VECTOR_FIELD VEL VELOVECT VERT_T3D VOIGT
+syn keyword idlangRoutine VORONOI VOXEL_PROJ WAIT WARP_TRI WATERSHED WDELETE
+syn keyword idlangRoutine WEOF WF_DRAW WHERE WIDGET_BASE WIDGET_BUTTON
+syn keyword idlangRoutine WIDGET_CONTROL WIDGET_DRAW WIDGET_DROPLIST
+syn keyword idlangRoutine WIDGET_EVENT WIDGET_INFO WIDGET_LABEL WIDGET_LIST
+syn keyword idlangRoutine WIDGET_SLIDER WIDGET_TABLE WIDGET_TEXT WINDOW
+syn keyword idlangRoutine WRITE_BMP WRITE_IMAGE WRITE_JPEG WRITE_NRIF
+syn keyword idlangRoutine WRITE_PICT WRITE_PNG WRITE_PPM WRITE_SPR WRITE_SRF
+syn keyword idlangRoutine WRITE_SYLK WRITE_TIFF WRITE_WAV WRITE_WAVE WRITEU
+syn keyword idlangRoutine WSET WSHOW WTN WV_APPLET WV_CW_WAVELET WV_CWT
+syn keyword idlangRoutine WV_DENOISE WV_DWT WV_FN_COIFLET WV_FN_DAUBECHIES
+syn keyword idlangRoutine WV_FN_GAUSSIAN WV_FN_HAAR WV_FN_MORLET WV_FN_PAUL
+syn keyword idlangRoutine WV_FN_SYMLET WV_IMPORT_DATA WV_IMPORT_WAVELET
+syn keyword idlangRoutine WV_PLOT3D_WPS WV_PLOT_MULTIRES WV_PWT
+syn keyword idlangRoutine WV_TOOL_DENOISE XBM_EDIT XDISPLAYFILE XDXF XFONT
+syn keyword idlangRoutine XINTERANIMATE XLOADCT XMANAGER XMNG_TMPL XMTOOL
+syn keyword idlangRoutine XOBJVIEW XPALETTE XPCOLOR XPLOT3D XREGISTERED XROI
+syn keyword idlangRoutine XSQ_TEST XSURFACE XVAREDIT XVOLUME XVOLUME_ROTATE
+syn keyword idlangRoutine XVOLUME_WRITE_IMAGE XYOUTS ZOOM ZOOM_24
+
+" Define the default highlighting.
+" For version 5.7 and earlier: only when not done already
+" For version 5.8 and later: only when an item doesn't have highlighting yet
+if version >= 508 || !exists("did_idlang_syn_inits")
+  if version < 508
+    let did_idlang_syn_inits = 1
+    command -nargs=+ HiLink hi link <args>
+else
+    command -nargs=+ HiLink hi def link <args>
+endif
+
+  HiLink idlangConditional	Conditional
+  HiLink idlangRoutine	Type
+  HiLink idlangStatement	Statement
+  HiLink idlangContinueLine	Todo
+  HiLink idlangRealNumber	Float
+  HiLink idlangNumber	Number
+  HiLink idlangString	String
+  HiLink idlangOperator	Operator
+  HiLink idlangComment	Comment
+  HiLink idlangTodo	Todo
+  HiLink idlangPreCondit	Identifier
+  HiLink idlangDblCommaError	Error
+  HiLink idlangStop	Error
+  HiLink idlangStrucvar	PreProc
+  HiLink idlangSystem	Identifier
+  HiLink idlangKeyword	Special
+
+  delcommand HiLink
+endif
+
+let b:current_syntax = "idlang"
+" vim: ts=18
--- /dev/null
+++ b/lib/vimfiles/syntax/indent.vim
@@ -1,0 +1,151 @@
+" Vim syntax file
+" Language:         indent(1) configuration file
+" Maintainer:       Nikolai Weibull <now@bitwi.se>
+" Latest Revision:  2007-05-10
+"   indent_is_bsd:  If exists, will change somewhat to match BSD implementation
+"
+" TODO: is the deny-all (a la lilo.vim nice or no?)...
+"       irritating to be wrong to the last char...
+"       would be sweet if right until one char fails
+
+if exists("b:current_syntax")
+  finish
+endif
+
+let s:cpo_save = &cpo
+set cpo&vim
+
+setlocal iskeyword=@,48-57,-,+,_
+
+syn match   indentError   '\S\+'
+
+syn keyword indentTodo    contained TODO FIXME XXX NOTE
+
+syn region  indentComment start='/\*' end='\*/'
+                          \ contains=indentTodo,@Spell
+syn region  indentComment start='//' skip='\\$' end='$'
+                          \ contains=indentTodo,@Spell
+
+if !exists("indent_is_bsd")
+  syn match indentOptions '-i\|--indentation-level'
+                        \ nextgroup=indentNumber skipwhite skipempty
+endif
+syn match   indentOptions '-\%(bli\|c\%([bl]i\|[dip]\)\=\|di\=\|ip\=\|lc\=\|pp\=i\|sbi\|ts\|-\%(brace-indent\|comment-indentation\|case-brace-indentation\|declaration-comment-column\|continuation-indentation\|case-indentation\|else-endif-column\|line-comments-indentation\|declaration-indentation\|indent-level\|parameter-indentation\|line-length\|comment-line-length\|paren-indentation\|preprocessor-indentation\|struct-brace-indentation\|tab-size\)\)'
+                        \ nextgroup=indentNumber skipwhite skipempty
+
+syn match   indentNumber  display contained '\d\+\>'
+
+syn match   indentOptions '-T'
+                        \ nextgroup=indentIdent skipwhite skipempty
+
+syn match   indentIdent   display contained '\h\w*\>'
+
+syn keyword indentOptions -bacc --blank-lines-after-ifdefs
+                        \ -bad --blank-lines-after-declarations
+                        \ -badp --blank-lines-after-procedure-declarations
+                        \ -bap --blank-lines-after-procedures
+                        \ -bbb --blank-lines-before-block-comments
+                        \ -bbo --break-before-boolean-operator
+                        \ -bc --blank-lines-after-commas
+                        \ -bfda --break-function-decl-args
+                        \ -bfde --break-function-decl-args-end
+                        \ -bl --braces-after-if-line
+                        \ -blf --braces-after-func-def-line
+                        \ -bls --braces-after-struct-decl-line
+                        \ -br --braces-on-if-line
+                        \ -brf --braces-on-func-def-line
+                        \ -brs --braces-on-struct-decl-line
+                        \ -bs --Bill-Shannon --blank-before-sizeof
+                        \ -c++ --c-plus-plus
+                        \ -cdb --comment-delimiters-on-blank-lines
+                        \ -cdw --cuddle-do-while
+                        \ -ce --cuddle-else
+                        \ -cs --space-after-cast
+                        \ -dj --left-justify-declarations
+                        \ -eei --extra-expression-indentation
+                        \ -fc1 --format-first-column-comments
+                        \ -fca --format-all-comments
+                        \ -gnu --gnu-style
+                        \ -h --help --usage
+                        \ -hnl --honour-newlines
+                        \ -kr --k-and-r-style --kernighan-and-ritchie --kernighan-and-ritchie-style
+                        \ -lp --continue-at-parentheses
+                        \ -lps --leave-preprocessor-space
+                        \ -nbacc --no-blank-lines-after-ifdefs
+                        \ -nbad --no-blank-lines-after-declarations
+                        \ -nbadp --no-blank-lines-after-procedure-declarations
+                        \ -nbap --no-blank-lines-after-procedures
+                        \ -nbbb --no-blank-lines-before-block-comments
+                        \ -nbbo --break-after-boolean-operator
+                        \ -nbc --no-blank-lines-after-commas
+                        \ -nbfda --dont-break-function-decl-args
+                        \ -nbfde --dont-break-function-decl-args-end
+                        \ -nbs --no-Bill-Shannon --no-blank-before-sizeof
+                        \ -ncdb --no-comment-delimiters-on-blank-lines
+                        \ -ncdw --dont-cuddle-do-while
+                        \ -nce --dont-cuddle-else
+                        \ -ncs --no-space-after-casts
+                        \ -ndj --dont-left-justify-declarations
+                        \ -neei --no-extra-expression-indentation
+                        \ -nfc1 --dont-format-first-column-comments
+                        \ -nfca --dont-format-comments
+                        \ -nhnl --ignore-newlines
+                        \ -nip --dont-indent-parameters --no-parameter-indentation
+                        \ -nlp --dont-line-up-parentheses
+                        \ -nlps --remove-preprocessor-space
+                        \ -npcs --no-space-after-function-call-names
+                        \ -npmt
+                        \ -npro --ignore-profile
+                        \ -nprs --no-space-after-parentheses
+                        \ -npsl --dont-break-procedure-type
+                        \ -nsaf --no-space-after-for
+                        \ -nsai --no-space-after-if
+                        \ -nsaw --no-space-after-while
+                        \ -nsc --dont-star-comments
+                        \ -nsob --leave-optional-blank-lines
+                        \ -nss --dont-space-special-semicolon
+                        \ -nut --no-tabs
+                        \ -nv --no-verbosity
+                        \ -o --output
+                        \ -o --output-file
+                        \ -orig --berkeley --berkeley-style --original --original-style
+                        \ -pcs --space-after-procedure-calls
+                        \ -pmt --preserve-mtime
+                        \ -prs --space-after-parentheses
+                        \ -psl --procnames-start-lines
+                        \ -saf --space-after-for
+                        \ -sai --space-after-if
+                        \ -saw --space-after-while
+                        \ -sc --start-left-side-of-comments
+                        \ -sob --swallow-optional-blank-lines
+                        \ -ss --space-special-semicolon
+                        \ -st --standard-output
+                        \ -ut --use-tabs
+                        \ -v --verbose
+                        \ -version --version
+
+if exists("indent_is_bsd")
+  syn keyword indentOptions -ip -ei -nei
+endif
+
+if exists("c_minlines")
+  let b:c_minlines = c_minlines
+else
+  if !exists("c_no_if0")
+    let b:c_minlines = 50       " #if 0 constructs can be long
+  else
+    let b:c_minlines = 15       " mostly for () constructs
+  endif
+endif
+
+hi def link indentError   Error
+hi def link indentComment Comment
+hi def link indentTodo    Todo
+hi def link indentOptions Keyword
+hi def link indentNumber  Number
+hi def link indentIdent   Identifier
+
+let b:current_syntax = "indent"
+
+let &cpo = s:cpo_save
+unlet s:cpo_save
--- /dev/null
+++ b/lib/vimfiles/syntax/inform.vim
@@ -1,0 +1,408 @@
+" Vim syntax file
+" Language:     Inform
+" Maintainer:   Stephen Thomas (stephen@gowarthomas.com)
+" URL:		http://www.gowarthomas.com/informvim
+" Last Change:  2006 April 20
+
+" Quit when a syntax file was already loaded
+if version < 600
+  syntax clear
+elseif exists("b:current_syntax")
+  finish
+endif
+
+" A bunch of useful Inform keywords.  First, case insensitive stuff
+
+syn case ignore
+
+syn keyword informDefine Constant
+
+syn keyword informType Array Attribute Class Nearby
+syn keyword informType Object Property String Routine
+syn match   informType "\<Global\>"
+
+syn keyword informInclude Import Include Link Replace System_file
+
+syn keyword informPreCondit End Endif Ifdef Ifndef Iftrue Iffalse Ifv3 Ifv5
+syn keyword informPreCondit Ifnot
+
+syn keyword informPreProc Abbreviate Default Fake_action Lowstring
+syn keyword informPreProc Message Release Serial Statusline Stub Switches
+syn keyword informPreProc Trace Zcharacter
+
+syn region  informGlobalRegion matchgroup=informType start="\<Global\>" matchgroup=NONE skip=+!.*$\|".*"\|'.*'+ end=";" contains=ALLBUT,informGramPreProc,informPredicate,informGrammar,informAsm,informAsmObsolete
+
+syn keyword informGramPreProc contained Verb Extend
+
+if !exists("inform_highlight_simple")
+  syn keyword informLibAttrib absent animate clothing concealed container
+  syn keyword informLibAttrib door edible enterable female general light
+  syn keyword informLibAttrib lockable locked male moved neuter on open
+  syn keyword informLibAttrib openable pluralname proper scenery scored
+  syn keyword informLibAttrib static supporter switchable talkable
+  syn keyword informLibAttrib visited workflag worn
+  syn match informLibAttrib "\<transparent\>"
+
+  syn keyword informLibProp e_to se_to s_to sw_to w_to nw_to n_to ne_to
+  syn keyword informLibProp u_to d_to in_to out_to before after life
+  syn keyword informLibProp door_to with_key door_dir invent plural
+  syn keyword informLibProp add_to_scope list_together react_before
+  syn keyword informLibProp react_after grammar orders initial when_open
+  syn keyword informLibProp when_closed when_on when_off description
+  syn keyword informLibProp describe article cant_go found_in time_left
+  syn keyword informLibProp number time_out daemon each_turn capacity
+  syn keyword informLibProp name short_name short_name_indef parse_name
+  syn keyword informLibProp articles inside_description
+  if !exists("inform_highlight_old")
+    syn keyword informLibProp compass_look before_implicit
+    syn keyword informLibProp ext_initialise ext_messages
+  endif
+
+  syn keyword informLibObj e_obj se_obj s_obj sw_obj w_obj nw_obj n_obj
+  syn keyword informLibObj ne_obj u_obj d_obj in_obj out_obj compass
+  syn keyword informLibObj thedark selfobj player location second actor
+  syn keyword informLibObj noun
+  if !exists("inform_highlight_old")
+    syn keyword informLibObj LibraryExtensions
+  endif
+
+  syn keyword informLibRoutine Achieved AfterRoutines AddToScope
+  syn keyword informLibRoutine AllowPushDir Banner ChangeDefault
+  syn keyword informLibRoutine ChangePlayer CommonAncestor DictionaryLookup
+  syn keyword informLibRoutine DisplayStatus DoMenu DrawStatusLine
+  syn keyword informLibRoutine EnglishNumber HasLightSource GetGNAOfObject
+  syn keyword informLibRoutine IndirectlyContains IsSeeThrough Locale
+  syn keyword informLibRoutine LoopOverScope LTI_Insert MoveFloatingObjects
+  syn keyword informLibRoutine NextWord NextWordStopped NounDomain
+  syn keyword informLibRoutine ObjectIsUntouchable OffersLight ParseToken
+  syn keyword informLibRoutine PlaceInScope PlayerTo PrintShortName
+  syn keyword informLibRoutine PronounNotice ScopeWithin SetPronoun SetTime
+  syn keyword informLibRoutine StartDaemon StartTimer StopDaemon StopTimer
+  syn keyword informLibRoutine TestScope TryNumber UnsignedCompare
+  syn keyword informLibRoutine WordAddress WordInProperty WordLength
+  syn keyword informLibRoutine WriteListFrom YesOrNo ZRegion RunRoutines
+  syn keyword informLibRoutine AfterLife AfterPrompt Amusing BeforeParsing
+  syn keyword informLibRoutine ChooseObjects DarkToDark DeathMessage
+  syn keyword informLibRoutine GamePostRoutine GamePreRoutine Initialise
+  syn keyword informLibRoutine InScope LookRoutine NewRoom ParseNoun
+  syn keyword informLibRoutine ParseNumber ParserError PrintRank PrintVerb
+  syn keyword informLibRoutine PrintTaskName TimePasses UnknownVerb
+  if exists("inform_highlight_glulx")
+     syn keyword informLibRoutine  IdentifyGlkObject HandleGlkEvent
+     syn keyword informLibRoutine  InitGlkWindow
+  endif
+  if !exists("inform_highlight_old")
+     syn keyword informLibRoutine  KeyCharPrimitive KeyDelay ClearScreen
+     syn keyword informLibRoutine  MoveCursor MainWindow StatusLineHeight
+     syn keyword informLibRoutine  ScreenWidth ScreenHeight SetColour
+     syn keyword informLibRoutine  DecimalNumber PrintToBuffer Length
+     syn keyword informLibRoutine  UpperCase LowerCase PrintCapitalised
+     syn keyword informLibRoutine  Cap Centre
+     if exists("inform_highlight_glulx")
+	syn keyword informLibRoutine  PrintAnything PrintAnyToArray
+     endif
+  endif
+
+  syn keyword informLibAction  Quit Restart Restore Verify Save
+  syn keyword informLibAction  ScriptOn ScriptOff Pronouns Score
+  syn keyword informLibAction  Fullscore LMode1 LMode2 LMode3
+  syn keyword informLibAction  NotifyOn NotifyOff Version Places
+  syn keyword informLibAction  Objects TraceOn TraceOff TraceLevel
+  syn keyword informLibAction  ActionsOn ActionsOff RoutinesOn
+  syn keyword informLibAction  RoutinesOff TimersOn TimersOff
+  syn keyword informLibAction  CommandsOn CommandsOff CommandsRead
+  syn keyword informLibAction  Predictable XPurloin XAbstract XTree
+  syn keyword informLibAction  Scope Goto Gonear Inv InvTall InvWide
+  syn keyword informLibAction  Take Drop Remove PutOn Insert Transfer
+  syn keyword informLibAction  Empty Enter Exit GetOff Go Goin Look
+  syn keyword informLibAction  Examine Search Give Show Unlock Lock
+  syn keyword informLibAction  SwitchOn SwitchOff Open Close Disrobe
+  syn keyword informLibAction  Wear Eat Yes No Burn Pray Wake
+  syn keyword informLibAction  WakeOther Consult Kiss Think Smell
+  syn keyword informLibAction  Listen Taste Touch Dig Cut Jump
+  syn keyword informLibAction  JumpOver Tie Drink Fill Sorry Strong
+  syn keyword informLibAction  Mild Attack Swim Swing Blow Rub Set
+  syn keyword informLibAction  SetTo WaveHands Wave Pull Push PushDir
+  syn keyword informLibAction  Turn Squeeze LookUnder ThrowAt Tell
+  syn keyword informLibAction  Answer Buy Ask AskFor Sing Climb Wait
+  syn keyword informLibAction  Sleep LetGo Receive ThrownAt Order
+  syn keyword informLibAction  TheSame PluralFound Miscellany Prompt
+  syn keyword informLibAction  ChangesOn ChangesOff Showverb Showobj
+  syn keyword informLibAction  EmptyT VagueGo
+  if exists("inform_highlight_glulx")
+     syn keyword informLibAction  GlkList
+  endif
+
+  syn keyword informLibVariable keep_silent deadflag action special_number
+  syn keyword informLibVariable consult_from consult_words etype verb_num
+  syn keyword informLibVariable verb_word the_time real_location c_style
+  syn keyword informLibVariable parser_one parser_two listing_together wn
+  syn keyword informLibVariable parser_action scope_stage scope_reason
+  syn keyword informLibVariable action_to_be menu_item item_name item_width
+  syn keyword informLibVariable lm_o lm_n inventory_style task_scores
+  syn keyword informLibVariable inventory_stage
+
+  syn keyword informLibConst AMUSING_PROVIDED DEBUG Headline MAX_CARRIED
+  syn keyword informLibConst MAX_SCORE MAX_TIMERS NO_PLACES NUMBER_TASKS
+  syn keyword informLibConst OBJECT_SCORE ROOM_SCORE SACK_OBJECT Story
+  syn keyword informLibConst TASKS_PROVIDED WITHOUT_DIRECTIONS
+  syn keyword informLibConst NEWLINE_BIT INDENT_BIT FULLINV_BIT ENGLISH_BIT
+  syn keyword informLibConst RECURSE_BIT ALWAYS_BIT TERSE_BIT PARTINV_BIT
+  syn keyword informLibConst DEFART_BIT WORKFLAG_BIT ISARE_BIT CONCEAL_BIT
+  syn keyword informLibConst PARSING_REASON TALKING_REASON EACHTURN_REASON
+  syn keyword informLibConst REACT_BEFORE_REASON REACT_AFTER_REASON
+  syn keyword informLibConst TESTSCOPE_REASON LOOPOVERSCOPE_REASON
+  syn keyword informLibConst STUCK_PE UPTO_PE NUMBER_PE CANTSEE_PE TOOLIT_PE
+  syn keyword informLibConst NOTHELD_PE MULTI_PE MMULTI_PE VAGUE_PE EXCEPT_PE
+  syn keyword informLibConst ANIMA_PE VERB_PE SCENERY_PE ITGONE_PE
+  syn keyword informLibConst JUNKAFTER_PE TOOFEW_PE NOTHING_PE ASKSCOPE_PE
+  if !exists("inform_highlight_old")
+     syn keyword informLibConst WORDSIZE TARGET_ZCODE TARGET_GLULX
+     syn keyword informLibConst LIBRARY_PARSER LIBRARY_VERBLIB LIBRARY_GRAMMAR
+     syn keyword informLibConst LIBRARY_ENGLISH NO_SCORE START_MOVE
+     syn keyword informLibConst CLR_DEFAULT CLR_BLACK CLR_RED CLR_GREEN
+     syn keyword informLibConst CLR_YELLOW CLR_BLUE CLR_MAGENTA CLR_CYAN
+     syn keyword informLibConst CLR_WHITE CLR_PURPLE CLR_AZURE
+     syn keyword informLibConst WIN_ALL WIN_MAIN WIN_STATUS
+  endif
+endif
+
+" Now the case sensitive stuff.
+
+syntax case match
+
+syn keyword informSysFunc child children elder indirect parent random
+syn keyword informSysFunc sibling younger youngest metaclass
+if exists("inform_highlight_glulx")
+  syn keyword informSysFunc glk
+endif
+
+syn keyword informSysConst adjectives_table actions_table classes_table
+syn keyword informSysConst identifiers_table preactions_table version_number
+syn keyword informSysConst largest_object strings_offset code_offset
+syn keyword informSysConst dict_par1 dict_par2 dict_par3
+syn keyword informSysConst actual_largest_object static_memory_offset
+syn keyword informSysConst array_names_offset readable_memory_offset
+syn keyword informSysConst cpv__start cpv__end ipv__start ipv__end
+syn keyword informSysConst array__start array__end lowest_attribute_number
+syn keyword informSysConst highest_attribute_number attribute_names_array
+syn keyword informSysConst lowest_property_number highest_property_number
+syn keyword informSysConst property_names_array lowest_action_number
+syn keyword informSysConst highest_action_number action_names_array
+syn keyword informSysConst lowest_fake_action_number highest_fake_action_number
+syn keyword informSysConst fake_action_names_array lowest_routine_number
+syn keyword informSysConst highest_routine_number routines_array
+syn keyword informSysConst routine_names_array routine_flags_array
+syn keyword informSysConst lowest_global_number highest_global_number globals_array
+syn keyword informSysConst global_names_array global_flags_array
+syn keyword informSysConst lowest_array_number highest_array_number arrays_array
+syn keyword informSysConst array_names_array array_flags_array lowest_constant_number
+syn keyword informSysConst highest_constant_number constants_array constant_names_array
+syn keyword informSysConst lowest_class_number highest_class_number class_objects_array
+syn keyword informSysConst lowest_object_number highest_object_number
+if !exists("inform_highlight_old")
+  syn keyword informSysConst sys_statusline_flag
+endif
+
+syn keyword informConditional default else if switch
+
+syn keyword informRepeat break continue do for objectloop until while
+
+syn keyword informStatement box font give inversion jump move new_line
+syn keyword informStatement print print_ret quit read remove restore return
+syn keyword informStatement rfalse rtrue save spaces string style
+
+syn keyword informOperator roman reverse bold underline fixed on off to
+syn keyword informOperator near from
+
+syn keyword informKeyword dictionary symbols objects verbs assembly
+syn keyword informKeyword expressions lines tokens linker on off alias long
+syn keyword informKeyword additive score time string table
+syn keyword informKeyword with private has class error fatalerror
+syn keyword informKeyword warning self
+if !exists("inform_highlight_old")
+  syn keyword informKeyword buffer
+endif
+
+syn keyword informMetaAttrib remaining create destroy recreate copy call
+syn keyword informMetaAttrib print_to_array
+
+syn keyword informPredicate has hasnt in notin ofclass or
+syn keyword informPredicate provides
+
+syn keyword informGrammar contained noun held multi multiheld multiexcept
+syn keyword informGrammar contained multiinside creature special number
+syn keyword informGrammar contained scope topic reverse meta only replace
+syn keyword informGrammar contained first last
+
+syn keyword informKeywordObsolete contained initial data initstr
+
+syn keyword informTodo contained TODO
+
+" Assembly language mnemonics must be preceded by a '@'.
+
+syn match informAsmContainer "@\s*\k*" contains=informAsm,informAsmObsolete
+
+if exists("inform_highlight_glulx")
+  syn keyword informAsm contained nop add sub mul div mod neg bitand bitor
+  syn keyword informAsm contained bitxor bitnot shiftl sshiftr ushiftr jump jz
+  syn keyword informAsm contained jnz jeq jne jlt jge jgt jle jltu jgeu jgtu
+  syn keyword informAsm contained jleu call return catch throw tailcall copy
+  syn keyword informAsm contained copys copyb sexs sexb aload aloads aloadb
+  syn keyword informAsm contained aloadbit astore astores astoreb astorebit
+  syn keyword informAsm contained stkcount stkpeek stkswap stkroll stkcopy
+  syn keyword informAsm contained streamchar streamnum streamstr gestalt
+  syn keyword informAsm contained debugtrap getmemsize setmemsize jumpabs
+  syn keyword informAsm contained random setrandom quit verify restart save
+  syn keyword informAsm contained restore saveundo restoreundo protect glk
+  syn keyword informAsm contained getstringtbl setstringtbl getiosys setiosys
+  syn keyword informAsm contained linearsearch binarysearch linkedsearch
+  syn keyword informAsm contained callf callfi callfii callfiii
+else
+  syn keyword informAsm contained je jl jg dec_chk inc_chk jin test or and
+  syn keyword informAsm contained test_attr set_attr clear_attr store
+  syn keyword informAsm contained insert_obj loadw loadb get_prop
+  syn keyword informAsm contained get_prop_addr get_next_prop add sub mul div
+  syn keyword informAsm contained mod call storew storeb put_prop sread
+  syn keyword informAsm contained print_num random push pull
+  syn keyword informAsm contained split_window set_window output_stream
+  syn keyword informAsm contained input_stream sound_effect jz get_sibling
+  syn keyword informAsm contained get_child get_parent get_prop_len inc dec
+  syn keyword informAsm contained remove_obj print_obj ret jump
+  syn keyword informAsm contained load not rtrue rfalse print
+  syn keyword informAsm contained print_ret nop save restore restart
+  syn keyword informAsm contained ret_popped pop quit new_line show_status
+  syn keyword informAsm contained verify call_2s call_vs aread call_vs2
+  syn keyword informAsm contained erase_window erase_line set_cursor get_cursor
+  syn keyword informAsm contained set_text_style buffer_mode read_char
+  syn keyword informAsm contained scan_table call_1s call_2n set_colour throw
+  syn keyword informAsm contained call_vn call_vn2 tokenise encode_text
+  syn keyword informAsm contained copy_table print_table check_arg_count
+  syn keyword informAsm contained call_1n catch piracy log_shift art_shift
+  syn keyword informAsm contained set_font save_undo restore_undo draw_picture
+  syn keyword informAsm contained picture_data erase_picture set_margins
+  syn keyword informAsm contained move_window window_size window_style
+  syn keyword informAsm contained get_wind_prop scroll_window pop_stack
+  syn keyword informAsm contained read_mouse mouse_window push_stack
+  syn keyword informAsm contained put_wind_prop print_form make_menu
+  syn keyword informAsm contained picture_table
+  if !exists("inform_highlight_old")
+     syn keyword informAsm contained check_unicode print_unicode
+  endif
+  syn keyword informAsmObsolete contained print_paddr print_addr print_char
+endif
+
+" Handling for different versions of VIM.
+
+if version >= 600
+  setlocal iskeyword+=$
+  command -nargs=+ SynDisplay syntax <args> display
+else
+  set iskeyword+=$
+  command -nargs=+ SynDisplay syntax <args>
+endif
+
+" Grammar sections.
+
+syn region informGrammarSection matchgroup=informGramPreProc start="\<Verb\|Extend\>" skip=+".*"+ end=";"he=e-1 contains=ALLBUT,informAsm
+
+" Special character forms.
+
+SynDisplay match informBadAccent contained "@[^{[:digit:]]\D"
+SynDisplay match informBadAccent contained "@{[^}]*}"
+SynDisplay match informAccent contained "@:[aouAOUeiyEI]"
+SynDisplay match informAccent contained "@'[aeiouyAEIOUY]"
+SynDisplay match informAccent contained "@`[aeiouAEIOU]"
+SynDisplay match informAccent contained "@\^[aeiouAEIOU]"
+SynDisplay match informAccent contained "@\~[anoANO]"
+SynDisplay match informAccent contained "@/[oO]"
+SynDisplay match informAccent contained "@ss\|@<<\|@>>\|@oa\|@oA\|@ae\|@AE\|@cc\|@cC"
+SynDisplay match informAccent contained "@th\|@et\|@Th\|@Et\|@LL\|@oe\|@OE\|@!!\|@??"
+SynDisplay match informAccent contained "@{\x\{1,4}}"
+SynDisplay match informBadStrUnicode contained "@@\D"
+SynDisplay match informStringUnicode contained "@@\d\+"
+SynDisplay match informStringCode contained "@\d\d"
+
+" String and Character constants.  Ordering is important here.
+syn region informString start=+"+ skip=+\\\\+ end=+"+ contains=informAccent,informStringUnicode,informStringCode,informBadAccent,informBadStrUnicode
+syn region informDictString start="'" end="'" contains=informAccent,informBadAccent
+SynDisplay match informBadDictString "''"
+SynDisplay match informDictString "'''"
+
+" Integer numbers: decimal, hexadecimal and binary.
+SynDisplay match informNumber "\<\d\+\>"
+SynDisplay match informNumber "\<\$\x\+\>"
+SynDisplay match informNumber "\<\$\$[01]\+\>"
+
+" Comments
+syn match informComment "!.*" contains=informTodo
+
+" Syncronization
+syn sync match informSyncStringEnd grouphere NONE /"[;,]\s*$/
+syn sync match informSyncRoutineEnd grouphere NONE /][;,]\s*$/
+syn sync match informSyncCommentEnd grouphere NONE /^\s*!.*$/
+syn sync match informSyncRoutine groupthere informGrammarSection "\<Verb\|Extend\>"
+syn sync maxlines=500
+
+delcommand SynDisplay
+
+" The default highlighting.
+if version >= 508 || !exists("did_inform_syn_inits")
+  if version < 508
+    let did_inform_syn_inits = 1
+    command -nargs=+ HiLink hi link <args>
+  else
+    command -nargs=+ HiLink hi def link <args>
+  endif
+
+  HiLink informDefine		Define
+  HiLink informType		Type
+  HiLink informInclude		Include
+  HiLink informPreCondit	PreCondit
+  HiLink informPreProc		PreProc
+  HiLink informGramPreProc	PreProc
+  HiLink informAsm		Special
+  if !exists("inform_suppress_obsolete")
+    HiLink informAsmObsolete		informError
+    HiLink informKeywordObsolete	informError
+  else
+    HiLink informAsmObsolete		Special
+    HiLink informKeywordObsolete	Keyword
+  endif
+  HiLink informPredicate	Operator
+  HiLink informSysFunc		Identifier
+  HiLink informSysConst		Identifier
+  HiLink informConditional	Conditional
+  HiLink informRepeat		Repeat
+  HiLink informStatement	Statement
+  HiLink informOperator		Operator
+  HiLink informKeyword		Keyword
+  HiLink informGrammar		Keyword
+  HiLink informDictString	String
+  HiLink informNumber		Number
+  HiLink informError		Error
+  HiLink informString		String
+  HiLink informComment		Comment
+  HiLink informAccent		Special
+  HiLink informStringUnicode	Special
+  HiLink informStringCode	Special
+  HiLink informTodo		Todo
+  if !exists("inform_highlight_simple")
+    HiLink informLibAttrib	Identifier
+    HiLink informLibProp	Identifier
+    HiLink informLibObj		Identifier
+    HiLink informLibRoutine	Identifier
+    HiLink informLibVariable	Identifier
+    HiLink informLibConst	Identifier
+    HiLink informLibAction	Identifier
+  endif
+  HiLink informBadDictString	informError
+  HiLink informBadAccent	informError
+  HiLink informBadStrUnicode	informError
+
+  delcommand HiLink
+endif
+
+let b:current_syntax = "inform"
+
+" vim: ts=8
--- /dev/null
+++ b/lib/vimfiles/syntax/initex.vim
@@ -1,0 +1,376 @@
+" Vim syntax file
+" Language:         TeX (core definition)
+" Maintainer:       Nikolai Weibull <now@bitwi.se>
+" Latest Revision:  2006-04-19
+
+if exists("b:current_syntax")
+  finish
+endif
+
+let s:cpo_save = &cpo
+set cpo&vim
+
+" This follows the grouping (sort of) found at
+" http://www.tug.org/utilities/plain/cseq.html#top-fam
+
+syn keyword initexTodo                          TODO FIXME XXX NOTE
+
+syn match initexComment                         display contains=initexTodo
+      \ '\\\@<!\%(\\\\\)*\zs%.*$'
+
+syn match   initexDimension                     display contains=@NoSpell
+      \ '[+-]\=\s*\%(\d\+\%([.,]\d*\)\=\|[.,]\d\+\)\s*\%(true\)\=\s*\%(p[tc]\|in\|bp\|c[mc]\|m[mu]\|dd\|sp\|e[mx]\)\>'
+
+syn cluster initexBox
+      \ contains=initexBoxCommand,initexBoxInternalQuantity,
+      \ initexBoxParameterDimen,initexBoxParameterInteger,
+      \ initexBoxParameterToken
+
+syn cluster initexCharacter
+      \ contains=initexCharacterCommand,initexCharacterInternalQuantity,
+      \ initexCharacterParameterInteger
+
+syn cluster initexDebugging
+      \ contains=initexDebuggingCommand,initexDebuggingParameterInteger,
+      \ initexDebuggingParameterToken
+
+syn cluster initexFileIO
+      \ contains=initexFileIOCommand,initexFileIOInternalQuantity,
+      \ initexFileIOParameterToken
+
+syn cluster initexFonts
+      \ contains=initexFontsCommand,initexFontsInternalQuantity
+
+syn cluster initexGlue
+      \ contains=initexGlueCommand,initexGlueDerivedCommand
+
+syn cluster initexHyphenation
+      \ contains=initexHyphenationCommand,initexHyphenationDerivedCommand,
+      \ initexHyphenationInternalQuantity,initexHyphenationParameterInteger
+
+syn cluster initexInserts
+      \ contains=initexInsertsCommand,initexInsertsParameterDimen,
+      \ initexInsertsParameterGlue,initexInsertsParameterInteger
+
+syn cluster initexJob
+      \ contains=initexJobCommand,initexJobInternalQuantity,
+      \ initexJobParameterInteger
+
+syn cluster initexKern
+      \ contains=initexKernCommand,initexKernInternalQuantity
+
+syn cluster initexLogic
+      \ contains=initexLogicCommand
+
+syn cluster initexMacro
+      \ contains=initexMacroCommand,initexMacroDerivedCommand,
+      \ initexMacroParameterInteger
+
+syn cluster initexMarks
+      \ contains=initexMarksCommand
+
+syn cluster initexMath
+      \ contains=initexMathCommand,initexMathDerivedCommand,
+      \ initexMathInternalQuantity,initexMathParameterDimen,
+      \ initexMathParameterGlue,initexMathParameterInteger,
+      \ initexMathParameterMuglue,initexMathParameterToken
+
+syn cluster initexPage
+      \ contains=initexPageInternalQuantity,initexPageParameterDimen,
+      \ initexPageParameterGlue
+
+syn cluster initexParagraph
+      \ contains=initexParagraphCommand,initexParagraphInternalQuantity,
+      \ initexParagraphParameterDimen,initexParagraphParameterGlue,
+      \ initexParagraphParameterInteger,initexParagraphParameterToken
+
+syn cluster initexPenalties
+      \ contains=initexPenaltiesCommand,initexPenaltiesInternalQuantity,
+      \ initexPenaltiesParameterInteger
+
+syn cluster initexRegisters
+      \ contains=initexRegistersCommand,initexRegistersInternalQuantity
+
+syn cluster initexTables
+      \ contains=initexTablesCommand,initexTablesParameterGlue,
+      \ initexTablesParameterToken
+
+syn cluster initexCommand
+      \ contains=initexBoxCommand,initexCharacterCommand,
+      \ initexDebuggingCommand,initexFileIOCommand,
+      \ initexFontsCommand,initexGlueCommand,
+      \ initexHyphenationCommand,initexInsertsCommand,
+      \ initexJobCommand,initexKernCommand,initexLogicCommand,
+      \ initexMacroCommand,initexMarksCommand,initexMathCommand,
+      \ initexParagraphCommand,initexPenaltiesCommand,initexRegistersCommand,
+      \ initexTablesCommand
+
+syn match   initexBoxCommand                    display contains=@NoSpell
+      \ '\\\%([hv]\=box\|[cx]\=leaders\|copy\|[hv]rule\|lastbox\|setbox\|un[hv]\%(box\|copy\)\|vtop\)\>'
+syn match   initexCharacterCommand              display contains=@NoSpell
+      \ '\\\%([] ]\|\%(^^M\|accent\|char\|\%(lower\|upper\)case\|number\|romannumeral\|string\)\>\)'
+syn match   initexDebuggingCommand              display contains=@NoSpell
+      \ '\\\%(\%(batch\|\%(non\|error\)stop\|scroll\)mode\|\%(err\)\=message\|meaning\|show\%(box\%(breadth\|depth\)\=\|lists\|the\)\)\>'
+syn match   initexFileIOCommand                 display contains=@NoSpell
+      \ '\\\%(\%(close\|open\)\%(in\|out\)\|endinput\|immediate\|input\|read\|shipout\|special\|write\)\>'
+syn match   initexFontsCommand                  display contains=@NoSpell
+      \ '\\\%(/\|fontname\)\>'
+syn match   initexGlueCommand                   display contains=@NoSpell
+      \ '\\\%([hv]\|un\)skip\>'
+syn match   initexHyphenationCommand            display contains=@NoSpell
+      \ '\\\%(discretionary\|hyphenation\|patterns\|setlanguage\)\>'
+syn match   initexInsertsCommand                display contains=@NoSpell
+      \ '\\\%(insert\|split\%(bot\|first\)mark\|vsplit\)\>'
+syn match   initexJobCommand                    display contains=@NoSpell
+      \ '\\\%(dump\|end\|jobname\)\>'
+syn match   initexKernCommand                   display contains=@NoSpell
+      \ '\\\%(kern\|lower\|move\%(left\|right\)\|raise\|unkern\)\>'
+syn match   initexLogicCommand                  display contains=@NoSpell
+      \ '\\\%(else\|fi\|if[a-zA-Z@]\+\|or\)\>'
+"      \ '\\\%(else\|fi\|if\%(case\|cat\|dim\|eof\|false\|[hv]box\|[hmv]mode\|inner\|num\|odd\|true\|void\|x\)\=\|or\)\>'
+syn match   initexMacroCommand                  display contains=@NoSpell
+      \ '\\\%(after\%(assignment\|group\)\|\%(begin\|end\)group\|\%(end\)\=csname\|e\=def\|expandafter\|futurelet\|global\|let\|long\|noexpand\|outer\|relax\|the\)\>'
+syn match   initexMarksCommand                  display contains=@NoSpell
+      \ '\\\%(bot\|first\|top\)\=mark\>'
+syn match   initexMathCommand                   display contains=@NoSpell
+      \ '\\\%(abovewithdelims\|delimiter\|display\%(limits\|style\)\|l\=eqno\|left\|\%(no\)\=limits\|math\%(accent\|bin\|char\|choice\|close\|code\|inner\|op\|open\|ord\|punct\|rel\)\|mkern\|mskip\|muskipdef\|nonscript\|\%(over\|under\)line\|radical\|right\|\%(\%(script\)\{1,2}\|text\)style\|vcenter\)\>'
+syn match   initexParagraphCommand              display contains=@NoSpell
+      \ '\\\%(ignorespaces\|indent\|no\%(boundary\|indent\)\|par\|vadjust\)\>'
+syn match   initexPenaltiesCommand              display contains=@NoSpell
+      \ '\\\%(un\)\=penalty\>'
+syn match   initexRegistersCommand              display contains=@NoSpell
+      \ '\\\%(advance\|\%(count\|dimen\|skip\|toks\)def\|divide\|multiply\)\>'
+syn match   initexTablesCommand                 display contains=@NoSpell
+      \ '\\\%(cr\|crcr\|[hv]align\|noalign\|omit\|span\)\>'
+
+syn cluster initexDerivedCommand
+      \ contains=initexGlueDerivedCommand,initexHyphenationDerivedCommand,
+      \ initexMacroDerivedCommand,initexMathDerivedCommand
+
+syn match   initexGlueDerivedCommand            display contains=@NoSpell
+      \ '\\\%([hv]fil\%(l\|neg\)\=\|[hv]ss\)\>'
+syn match   initexHyphenationDerivedCommand     display contains=@NoSpell
+      \ '\\-'
+syn match   initexMacroDerivedCommand           display contains=@NoSpell
+      \ '\\[gx]def\>'
+syn match   initexMathDerivedCommand            display contains=@NoSpell
+      \ '\\\%(above\|atop\%(withdelims\)\=\|mathchardef\|over\|overwithdelims\)\>'
+
+syn cluster initexInternalQuantity
+      \ contains=initexBoxInternalQuantity,initexCharacterInternalQuantity,
+      \ initexFileIOInternalQuantity,initexFontsInternalQuantity,
+      \ initexHyphenationInternalQuantity,initexJobInternalQuantity,
+      \ initexKernInternalQuantity,initexMathInternalQuantity,
+      \ initexPageInternalQuantity,initexParagraphInternalQuantity,
+      \ initexPenaltiesInternalQuantity,initexRegistersInternalQuantity
+
+syn match   initexBoxInternalQuantity           display contains=@NoSpell
+      \ '\\\%(badness\|dp\|ht\|prevdepth\|wd\)\>'
+syn match   initexCharacterInternalQuantity     display contains=@NoSpell
+      \ '\\\%(catcode\|chardef\|\%([ul]c\|sf\)code\)\>'
+syn match   initexFileIOInternalQuantity        display contains=@NoSpell
+      \ '\\inputlineno\>'
+syn match   initexFontsInternalQuantity         display contains=@NoSpell
+      \ '\\\%(font\%(dimen\)\=\|nullfont\)\>'
+syn match   initexHyphenationInternalQuantity   display contains=@NoSpell
+      \ '\\hyphenchar\>'
+syn match   initexJobInternalQuantity           display contains=@NoSpell
+      \ '\\deadcycles\>'
+syn match   initexKernInternalQuantity          display contains=@NoSpell
+      \ '\\lastkern\>'
+syn match   initexMathInternalQuantity          display contains=@NoSpell
+      \ '\\\%(delcode\|mathcode\|muskip\|\%(\%(script\)\{1,2}\|text\)font\|skewchar\)\>'
+syn match   initexPageInternalQuantity          display contains=@NoSpell
+      \ '\\page\%(depth\|fil\{1,3}stretch\|goal\|shrink\|stretch\|total\)\>'
+syn match   initexParagraphInternalQuantity     display contains=@NoSpell
+      \ '\\\%(prevgraf\|spacefactor\)\>'
+syn match   initexPenaltiesInternalQuantity     display contains=@NoSpell
+      \ '\\lastpenalty\>'
+syn match   initexRegistersInternalQuantity     display contains=@NoSpell
+      \ '\\\%(count\|dimen\|skip\|toks\)\d\+\>'
+
+syn cluster initexParameterDimen
+      \ contains=initexBoxParameterDimen,initexInsertsParameterDimen,
+      \ initexMathParameterDimen,initexPageParameterDimen,
+      \ initexParagraphParameterDimen
+
+syn match   initexBoxParameterDimen             display contains=@NoSpell
+      \ '\\\%(boxmaxdepth\|[hv]fuzz\|overfullrule\)\>'
+syn match   initexInsertsParameterDimen         display contains=@NoSpell
+      \ '\\splitmaxdepth\>'
+syn match   initexMathParameterDimen            display contains=@NoSpell
+      \ '\\\%(delimitershortfall\|display\%(indent\|width\)\|mathsurround\|nulldelimiterspace\|predisplaysize\|scriptspace\)\>'
+syn match   initexPageParameterDimen            display contains=@NoSpell
+      \ '\\\%([hv]offset\|maxdepth\|vsize\)\>'
+syn match   initexParagraphParameterDimen       display contains=@NoSpell
+      \ '\\\%(emergencystretch\|\%(hang\|par\)indent\|hsize\|lineskiplimit\)\>'
+
+syn cluster initexParameterGlue
+      \ contains=initexInsertsParameterGlue,initexMathParameterGlue,
+      \ initexPageParameterGlue,initexParagraphParameterGlue,
+      \ initexTablesParameterGlue
+
+syn match   initexInsertsParameterGlue          display contains=@NoSpell
+      \ '\\splittopskip\>'
+syn match   initexMathParameterGlue             display contains=@NoSpell
+      \ '\\\%(above\|below\)display\%(short\)\=skip\>'
+syn match   initexPageParameterGlue             display contains=@NoSpell
+      \ '\\topskip\>'
+syn match   initexParagraphParameterGlue        display contains=@NoSpell
+      \ '\\\%(baseline\|left\|line\|par\%(fill\)\=\|right\|x\=space\)skip\>'
+syn match   initexTablesParameterGlue           display contains=@NoSpell
+      \ '\\tabskip\>'
+
+syn cluster initexParameterInteger
+      \ contains=initexBoxParameterInteger,initexCharacterParameterInteger,
+      \ initexDebuggingParameterInteger,initexHyphenationParameterInteger,
+      \ initexInsertsParameterInteger,initexJobParameterInteger,
+      \ initexMacroParameterInteger,initexMathParameterInteger,
+      \ initexParagraphParameterInteger,initexPenaltiesParameterInteger,
+
+syn match   initexBoxParameterInteger           display contains=@NoSpell
+      \ '\\[hv]badness\>'
+syn match   initexCharacterParameterInteger     display contains=@NoSpell
+      \ '\\\%(\%(endline\|escape\|newline\)char\)\>'
+syn match   initexDebuggingParameterInteger     display contains=@NoSpell
+      \ '\\\%(errorcontextlines\|pausing\|tracing\%(commands\|lostchars\|macros\|online\|output\|pages\|paragraphs\|restores|stats\)\)\>'
+syn match   initexHyphenationParameterInteger   display contains=@NoSpell
+      \ '\\\%(defaulthyphenchar\|language\|\%(left\|right\)hyphenmin\|uchyph\)\>'
+syn match   initexInsertsParameterInteger       display contains=@NoSpell
+      \ '\\\%(holdinginserts\)\>'
+syn match   initexJobParameterInteger           display contains=@NoSpell
+      \ '\\\%(day\|mag\|maxdeadcycles\|month\|time\|year\)\>'
+syn match   initexMacroParameterInteger         display contains=@NoSpell
+      \ '\\globaldefs\>'
+syn match   initexMathParameterInteger          display contains=@NoSpell
+      \ '\\\%(binoppenalty\|defaultskewchar\|delimiterfactor\|displaywidowpenalty\|fam\|\%(post\|pre\)displaypenalty\|relpenalty\)\>'
+syn match   initexParagraphParameterInteger     display contains=@NoSpell
+      \ '\\\%(\%(adj\|\%(double\|final\)hyphen\)demerits\|looseness\|\%(pre\)\=tolerance\)\>'
+syn match   initexPenaltiesParameterInteger     display contains=@NoSpell
+      \ '\\\%(broken\|club\|exhyphen\|floating\|hyphen\|interline\|line\|output\|widow\)penalty\>'
+
+syn cluster initexParameterMuglue
+      \ contains=initexMathParameterMuglue
+
+syn match   initexMathParameterMuglue           display contains=@NoSpell
+      \ '\\\%(med\|thick\|thin\)muskip\>'
+
+syn cluster initexParameterDimen
+      \ contains=initexBoxParameterToken,initexDebuggingParameterToken,
+      \ initexFileIOParameterToken,initexMathParameterToken,
+      \ initexParagraphParameterToken,initexTablesParameterToken
+
+syn match   initexBoxParameterToken             display contains=@NoSpell
+      \ '\\every[hv]box\>'
+syn match   initexDebuggingParameterToken       display contains=@NoSpell
+      \ '\\errhelp\>'
+syn match   initexFileIOParameterToken          display contains=@NoSpell
+      \ '\\output\>'
+syn match   initexMathParameterToken            display contains=@NoSpell
+      \ '\\every\%(display\|math\)\>'
+syn match   initexParagraphParameterToken       display contains=@NoSpell
+      \ '\\everypar\>'
+syn match   initexTablesParameterToken          display contains=@NoSpell
+      \ '\\everycr\>'
+
+
+hi def link initexCharacter                     Character
+hi def link initexNumber                        Number
+
+hi def link initexIdentifier                    Identifier
+
+hi def link initexStatement                     Statement
+hi def link initexConditional                   Conditional
+
+hi def link initexPreProc                       PreProc
+hi def link initexMacro                         Macro
+
+hi def link initexType                          Type
+
+hi def link initexDebug                         Debug
+
+hi def link initexTodo                          Todo
+hi def link initexComment                       Comment
+hi def link initexDimension                     initexNumber
+
+hi def link initexCommand                       initexStatement
+hi def link initexBoxCommand                    initexCommand
+hi def link initexCharacterCommand              initexCharacter
+hi def link initexDebuggingCommand              initexDebug
+hi def link initexFileIOCommand                 initexCommand
+hi def link initexFontsCommand                  initexType
+hi def link initexGlueCommand                   initexCommand
+hi def link initexHyphenationCommand            initexCommand
+hi def link initexInsertsCommand                initexCommand
+hi def link initexJobCommand                    initexPreProc
+hi def link initexKernCommand                   initexCommand
+hi def link initexLogicCommand                  initexConditional
+hi def link initexMacroCommand                  initexMacro
+hi def link initexMarksCommand                  initexCommand
+hi def link initexMathCommand                   initexCommand
+hi def link initexParagraphCommand              initexCommand
+hi def link initexPenaltiesCommand              initexCommand
+hi def link initexRegistersCommand              initexCommand
+hi def link initexTablesCommand                 initexCommand
+
+hi def link initexDerivedCommand                initexStatement
+hi def link initexGlueDerivedCommand            initexDerivedCommand
+hi def link initexHyphenationDerivedCommand     initexDerivedCommand
+hi def link initexMacroDerivedCommand           initexDerivedCommand
+hi def link initexMathDerivedCommand            initexDerivedCommand
+
+hi def link initexInternalQuantity              initexIdentifier
+hi def link initexBoxInternalQuantity           initexInternalQuantity
+hi def link initexCharacterInternalQuantity     initexInternalQuantity
+hi def link initexFileIOInternalQuantity        initexInternalQuantity
+hi def link initexFontsInternalQuantity         initexInternalQuantity
+hi def link initexHyphenationInternalQuantity   initexInternalQuantity
+hi def link initexJobInternalQuantity           initexInternalQuantity
+hi def link initexKernInternalQuantity          initexInternalQuantity
+hi def link initexMathInternalQuantity          initexInternalQuantity
+hi def link initexPageInternalQuantity          initexInternalQuantity
+hi def link initexParagraphInternalQuantity     initexInternalQuantity
+hi def link initexPenaltiesInternalQuantity     initexInternalQuantity
+hi def link initexRegistersInternalQuantity     initexInternalQuantity
+
+hi def link initexParameterDimen                initexNumber
+hi def link initexBoxParameterDimen             initexParameterDimen
+hi def link initexInsertsParameterDimen         initexParameterDimen
+hi def link initexMathParameterDimen            initexParameterDimen
+hi def link initexPageParameterDimen            initexParameterDimen
+hi def link initexParagraphParameterDimen       initexParameterDimen
+
+hi def link initexParameterGlue                 initexNumber
+hi def link initexInsertsParameterGlue          initexParameterGlue
+hi def link initexMathParameterGlue             initexParameterGlue
+hi def link initexPageParameterGlue             initexParameterGlue
+hi def link initexParagraphParameterGlue        initexParameterGlue
+hi def link initexTablesParameterGlue           initexParameterGlue
+
+hi def link initexParameterInteger              initexNumber
+hi def link initexBoxParameterInteger           initexParameterInteger
+hi def link initexCharacterParameterInteger     initexParameterInteger
+hi def link initexDebuggingParameterInteger     initexParameterInteger
+hi def link initexHyphenationParameterInteger   initexParameterInteger
+hi def link initexInsertsParameterInteger       initexParameterInteger
+hi def link initexJobParameterInteger           initexParameterInteger
+hi def link initexMacroParameterInteger         initexParameterInteger
+hi def link initexMathParameterInteger          initexParameterInteger
+hi def link initexParagraphParameterInteger     initexParameterInteger
+hi def link initexPenaltiesParameterInteger     initexParameterInteger
+
+hi def link initexParameterMuglue               initexNumber
+hi def link initexMathParameterMuglue           initexParameterMuglue
+
+hi def link initexParameterToken                initexIdentifier
+hi def link initexBoxParameterToken             initexParameterToken
+hi def link initexDebuggingParameterToken       initexParameterToken
+hi def link initexFileIOParameterToken          initexParameterToken
+hi def link initexMathParameterToken            initexParameterToken
+hi def link initexParagraphParameterToken       initexParameterToken
+hi def link initexTablesParameterToken          initexParameterToken
+
+let b:current_syntax = "initex"
+
+let &cpo = s:cpo_save
+unlet s:cpo_save
--- /dev/null
+++ b/lib/vimfiles/syntax/initng.vim
@@ -1,0 +1,91 @@
+" Vim syntax file
+" Language:	initng .i files
+" Maintainer:	Elan Ruusam�e <glen@pld-linux.org>
+" URL:		http://glen.alkohol.ee/pld/initng/
+" License:	GPL v2
+" Version:	0.13
+" Last Change:	$Date: 2007/05/05 17:17:40 $
+"
+" Syntax highlighting for initng .i files. Inherits from sh.vim and adds
+" in the hiliting to start/stop {} blocks. Requires vim 6.3 or later.
+
+if &compatible || v:version < 603
+	finish
+endif
+
+if exists("b:current_syntax")
+	finish
+endif
+
+syn case match
+
+let is_bash = 1
+unlet! b:current_syntax
+syn include @shTop syntax/sh.vim
+
+syn region	initngService			matchgroup=initngServiceHeader start="^\s*\(service\|virtual\|daemon\|class\|cron\)\s\+\(\(\w\|[-/*]\)\+\(\s\+:\s\+\(\w\|[-/*]\)\+\)\?\)\s\+{" end="}" contains=@initngServiceCluster
+syn cluster initngServiceCluster	contains=initngComment,initngAction,initngServiceOption,initngServiceHeader,initngDelim,initngVariable
+
+syn region	initngAction			matchgroup=initngActionHeader start="^\s*\(script start\|script stop\|script run\)\s*=\s*{" end="}" contains=@initngActionCluster
+syn cluster initngActionCluster		contains=@shTop
+
+syn match	initngDelim				/[{}]/	contained
+
+syn region	initngString			start=/"/ end=/"/ skip=/\\"/
+
+" option = value
+syn match	initngServiceOption		/.\+\s*=.\+;/ contains=initngServiceKeywords,initngSubstMacro contained
+" option without value
+syn match	initngServiceOption		/\w\+;/ contains=initngServiceKeywords,initngSubstMacro contained
+
+" options with value
+syn keyword	initngServiceKeywords	also_stop need use nice setuid contained
+syn keyword	initngServiceKeywords	delay chdir suid sgid start_pause env_file env_parse pid_file pidfile contained
+syn keyword	initngServiceKeywords	pid_of up_when_pid_set stdout stderr syncron just_before contained
+syn keyword	initngServiceKeywords	provide lockfile daemon_stops_badly contained
+syn match	initngServiceKeywords	/\(script\|exec\(_args\)\?\) \(start\|stop\|daemon\)/ contained
+syn match	initngServiceKeywords	/env\s\+\w\+/ contained
+
+" rlimits
+syn keyword	initngServiceKeywords	rlimit_cpu_hard rlimit_core_soft contained
+
+" single options
+syn keyword	initngServiceKeywords	last respawn network_provider require_network require_file critical forks contained
+" cron options
+syn keyword	initngServiceKeywords	hourly contained
+syn match	initngVariable			/\${\?\w\+\}\?/
+
+" Substituted @foo@ macros:
+" ==========
+syn match	initngSubstMacro		/@[^@]\+@/	contained
+syn cluster initngActionCluster		add=initngSubstMacro
+syn cluster shCommandSubList		add=initngSubstMacro
+
+" Comments:
+" ==========
+syn cluster	initngCommentGroup		contains=initngTodo,@Spell
+syn keyword	initngTodo				TODO FIXME XXX contained
+syn match	initngComment			/#.*$/ contains=@initngCommentGroup
+
+" install_service #macros
+" TODO: syntax check for ifd-endd pairs
+" ==========
+syn region	initngDefine			start="^#\(endd\|elsed\|exec\|ifd\|endexec\|endd\)\>" skip="\\$" end="$" end="#"me=s-1
+syn cluster shCommentGroup			add=initngDefine
+syn cluster initngCommentGroup		add=initngDefine
+
+hi def link	initngComment			Comment
+hi def link initngTodo				Todo
+
+hi def link	initngString			String
+hi def link initngServiceKeywords	Define
+
+hi def link	initngServiceHeader		Keyword
+hi def link	initngActionHeader		Type
+hi def link initngDelim				Delimiter
+
+hi def link	initngVariable			PreProc
+hi def link	initngSubstMacro		Comment
+hi def link	initngDefine			Macro
+
+let b:current_syntax = "initng"
--- /dev/null
+++ b/lib/vimfiles/syntax/inittab.vim
@@ -1,0 +1,75 @@
+" Vim syntax file
+" This is a GENERATED FILE. Please always refer to source file at the URI below.
+" Language: SysV-compatible init process control file `inittab'
+" Maintainer: David Ne\v{c}as (Yeti) <yeti@physics.muni.cz>
+" Last Change: 2002-09-13
+" URL: http://physics.muni.cz/~yeti/download/syntax/inittab.vim
+
+" Setup
+if version >= 600
+  if exists("b:current_syntax")
+    finish
+  endif
+else
+  syntax clear
+endif
+
+syn case match
+
+" Base constructs
+syn match inittabError "[^:]\+:"me=e-1 contained
+syn match inittabError "[^:]\+$" contained
+syn match inittabComment "^[#:].*$" contains=inittabFixme
+syn match inittabComment "#.*$" contained contains=inittabFixme
+syn keyword inittabFixme FIXME TODO XXX NOT
+
+" Shell
+syn region inittabShString start=+"+ end=+"+ skip=+\\\\\|\\\"+ contained
+syn region inittabShString start=+'+ end=+'+ contained
+syn match inittabShOption "\s[-+][[:alnum:]]\+"ms=s+1 contained
+syn match inittabShOption "\s--[:alnum:][-[:alnum:]]*"ms=s+1 contained
+syn match inittabShCommand "/\S\+" contained
+syn cluster inittabSh add=inittabShOption,inittabShString,inittabShCommand
+
+" Keywords
+syn keyword inittabActionName respawn wait once boot bootwait off ondemand sysinit powerwait powerfail powerokwait powerfailnow ctrlaltdel kbrequest initdefault contained
+
+" Line parser
+syn match inittabId "^[[:alnum:]~]\{1,4}" nextgroup=inittabColonRunLevels,inittabError
+syn match inittabColonRunLevels ":" contained nextgroup=inittabRunLevels,inittabColonAction,inittabError
+syn match inittabRunLevels "[0-6A-Ca-cSs]\+" contained nextgroup=inittabColonAction,inittabError
+syn match inittabColonAction ":" contained nextgroup=inittabAction,inittabError
+syn match inittabAction "\w\+" contained nextgroup=inittabColonProcess,inittabError contains=inittabActionName
+syn match inittabColonProcess ":" contained nextgroup=inittabProcessPlus,inittabProcess,inittabError
+syn match inittabProcessPlus "+" contained nextgroup=inittabProcess,inittabError
+syn region inittabProcess start="/" end="$" transparent oneline contained contains=@inittabSh,inittabComment
+
+" Define the default highlighting
+if version >= 508 || !exists("did_inittab_syntax_inits")
+  if version < 508
+    let did_inittab_syntax_inits = 1
+    command -nargs=+ HiLink hi link <args>
+  else
+    command -nargs=+ HiLink hi def link <args>
+  endif
+
+  HiLink inittabComment Comment
+  HiLink inittabFixme Todo
+  HiLink inittabActionName Type
+  HiLink inittabError Error
+  HiLink inittabId Identifier
+  HiLink inittabRunLevels Special
+
+  HiLink inittabColonProcess inittabColon
+  HiLink inittabColonAction inittabColon
+  HiLink inittabColonRunLevels inittabColon
+  HiLink inittabColon PreProc
+
+  HiLink inittabShString String
+  HiLink inittabShOption Special
+  HiLink inittabShCommand Statement
+
+  delcommand HiLink
+endif
+
+let b:current_syntax = "inittab"
--- /dev/null
+++ b/lib/vimfiles/syntax/ipfilter.vim
@@ -1,0 +1,57 @@
+" ipfilter syntax file
+" Language: ipfilter configuration file
+" Maintainer: Hendrik Scholz <hendrik@scholz.net>
+" Last Change: 2005 Jan 27
+"
+" http://www.wormulon.net/files/misc/ipfilter.vim
+"
+" This will also work for OpenBSD pf but there might be some tags that are
+" not correctly identified.
+" Please send comments to hendrik@scholz.net
+
+" For version 5.x: Clear all syntax items
+" For version 6.x: Quit when a syntax file was already loaded
+if version < 600
+  syntax clear
+elseif exists("b:current_syntax")
+  finish
+endif
+
+" Comment
+syn match	IPFComment	/#.*$/	contains=ipfTodo
+syn keyword	IPFTodo		TODO XXX FIXME contained
+
+syn keyword IPFActionBlock	block
+syn keyword IPFActionPass	pass
+syn keyword	IPFProto	tcp udp icmp
+syn keyword	IPFSpecial	quick log first
+" how could we use keyword for words with '-' ?
+syn match	IPFSpecial	/return-rst/
+syn match	IPFSpecial	/dup-to/
+"syn match	IPFSpecial	/icmp-type unreach/
+syn keyword IPFAny		all any
+syn match	IPFIPv4		/\d\{1,3}\.\d\{1,3}\.\d\{1,3}\.\d\{1,3}/
+syn match	IPFNetmask	/\/\d\+/
+
+" service name constants
+syn keyword IPFService	auth bgp domain finger ftp http https ident
+syn keyword IPFService	imap irc isakmp kerberos mail nameserver nfs
+syn keyword IPFService	nntp ntp pop3 portmap pptp rpcbind rsync smtp
+syn keyword IPFService	snmp snmptrap socks ssh sunrpc syslog telnet
+syn keyword IPFService	tftp www
+
+" Comment
+hi def link IPFComment	Comment
+hi def link IPFTodo		Todo
+
+hi def link IPFService	Constant
+
+hi def link IPFAction	Type
+hi def link ipfActionBlock	String
+hi def link ipfActionPass	Type
+hi def link IPFSpecial	Statement
+hi def link IPFIPv4		Label
+hi def link IPFNetmask	String
+hi def link IPFAny		Statement
+hi def link IPFProto	Identifier
+
--- /dev/null
+++ b/lib/vimfiles/syntax/ishd.vim
@@ -1,0 +1,422 @@
+" Vim syntax file
+" Language:	InstallShield Script
+" Maintainer:	Robert M. Cortopassi <cortopar@mindspring.com>
+" Last Change:	2001 May 09
+
+" For version 5.x: Clear all syntax items
+" For version 6.x: Quit when a syntax file was already loaded
+if version < 600
+  syntax clear
+elseif exists("b:current_syntax")
+  finish
+endif
+
+syn keyword ishdStatement abort begin case default downto else end
+syn keyword ishdStatement endif endfor endwhile endswitch endprogram exit elseif
+syn keyword ishdStatement error for function goto if
+syn keyword ishdStatement program prototype return repeat string step switch
+syn keyword ishdStatement struct then to typedef until while
+
+syn keyword ishdType BOOL BYREF CHAR GDI HWND INT KERNEL LIST LONG
+syn keyword ishdType NUMBER POINTER SHORT STRING USER
+
+syn keyword ishdConstant _MAX_LENGTH _MAX_STRING
+syn keyword ishdConstant AFTER ALLCONTENTS ALLCONTROLS APPEND ASKDESTPATH
+syn keyword ishdConstant ASKOPTIONS ASKPATH ASKTEXT BATCH_INSTALL BACK
+syn keyword ishdConstant BACKBUTTON BACKGROUND BACKGROUNDCAPTION BADPATH
+syn keyword ishdConstant BADTAGFILE BASEMEMORY BEFORE BILLBOARD BINARY
+syn keyword ishdConstant BITMAP256COLORS BITMAPFADE BITMAPICON BK_BLUE BK_GREEN
+syn keyword ishdConstant BK_MAGENTA BK_MAGENTA1 BK_ORANGE BK_PINK BK_RED
+syn keyword ishdConstant BK_SMOOTH BK_SOLIDBLACK  BK_SOLIDBLUE BK_SOLIDGREEN
+syn keyword ishdConstant BK_SOLIDMAGENTA BK_SOLIDORANGE BK_SOLIDPINK BK_SOLIDRED
+syn keyword ishdConstant BK_SOLIDWHITE BK_SOLIDYELLOW BK_YELLOW BLACK BLUE
+syn keyword ishdConstant BOOTUPDRIVE BUTTON_CHECKED BUTTON_ENTER BUTTON_UNCHECKED
+syn keyword ishdConstant BUTTON_UNKNOWN CMDLINE COMMONFILES CANCEL CANCELBUTTON
+syn keyword ishdConstant CC_ERR_FILEFORMATERROR CC_ERR_FILEREADERROR
+syn keyword ishdConstant CC_ERR_NOCOMPONENTLIST CC_ERR_OUTOFMEMORY CDROM
+syn keyword ishdConstant CDROM_DRIVE CENTERED CHANGEDIR CHECKBOX CHECKBOX95
+syn keyword ishdConstant CHECKLINE CHECKMARK CMD_CLOSE CMD_MAXIMIZE CMD_MINIMIZE
+syn keyword ishdConstant CMD_PUSHDOWN CMD_RESTORE COLORMODE256 COLORS
+syn keyword ishdConstant COMBOBOX_ENTER COMBOBOX_SELECT COMMAND COMMANDEX
+syn keyword ishdConstant COMMON COMP_DONE COMP_ERR_CREATEDIR
+syn keyword ishdConstant COMP_ERR_DESTCONFLICT COMP_ERR_FILENOTINLIB
+syn keyword ishdConstant COMP_ERR_FILESIZE COMP_ERR_FILETOOLARGE
+syn keyword ishdConstant COMP_ERR_HEADER COMP_ERR_INCOMPATIBLE
+syn keyword ishdConstant COMP_ERR_INTPUTNOTCOMPRESSED COMP_ERR_INVALIDLIST
+syn keyword ishdConstant COMP_ERR_LAUNCHSERVER COMP_ERR_MEMORY
+syn keyword ishdConstant COMP_ERR_NODISKSPACE COMP_ERR_OPENINPUT
+syn keyword ishdConstant COMP_ERR_OPENOUTPUT COMP_ERR_OPTIONS
+syn keyword ishdConstant COMP_ERR_OUTPUTNOTCOMPRESSED COMP_ERR_SPLIT
+syn keyword ishdConstant COMP_ERR_TARGET COMP_ERR_TARGETREADONLY COMP_ERR_WRITE
+syn keyword ishdConstant COMP_INFO_ATTRIBUTE COMP_INFO_COMPSIZE COMP_INFO_DATE
+syn keyword ishdConstant COMP_INFO_INVALIDATEPASSWORD COMP_INFO_ORIGSIZE
+syn keyword ishdConstant COMP_INFO_SETPASSWORD COMP_INFO_TIME
+syn keyword ishdConstant COMP_INFO_VERSIONLS COMP_INFO_VERSIONMS COMP_NORMAL
+syn keyword ishdConstant COMP_UPDATE_DATE COMP_UPDATE_DATE_NEWER
+syn keyword ishdConstant COMP_UPDATE_SAME COMP_UPDATE_VERSION COMPACT
+syn keyword ishdConstant COMPARE_DATE COMPARE_SIZE COMPARE_VERSION
+syn keyword ishdConstant COMPONENT_FIELD_CDROM_FOLDER
+syn keyword ishdConstant COMPONENT_FIELD_DESCRIPTION COMPONENT_FIELD_DESTINATION
+syn keyword ishdConstant COMPONENT_FIELD_DISPLAYNAME COMPONENT_FIELD_FILENEED
+syn keyword ishdConstant COMPONENT_FIELD_FTPLOCATION
+syn keyword ishdConstant COMPONENT_FIELD_HTTPLOCATION COMPONENT_FIELD_MISC
+syn keyword ishdConstant COMPONENT_FIELD_OVERWRITE COMPONENT_FIELD_PASSWORD
+syn keyword ishdConstant COMPONENT_FIELD_SELECTED COMPONENT_FIELD_SIZE
+syn keyword ishdConstant COMPONENT_FIELD_STATUS COMPONENT_FIELD_VISIBLE
+syn keyword ishdConstant COMPONENT_FILEINFO_COMPRESSED
+syn keyword ishdConstant COMPONENT_FILEINFO_COMPRESSENGINE
+syn keyword ishdConstant COMPONENT_FILEINFO_LANGUAGECOMPONENT_FILEINFO_OS
+syn keyword ishdConstant COMPONENT_FILEINFO_POTENTIALLYLOCKED
+syn keyword ishdConstant COMPONENT_FILEINFO_SELFREGISTERING
+syn keyword ishdConstant COMPONENT_FILEINFO_SHARED COMPONENT_INFO_ATTRIBUTE
+syn keyword ishdConstant COMPONENT_INFO_COMPSIZE COMPONENT_INFO_DATE
+syn keyword ishdConstant COMPONENT_INFO_DATE_EX_EX COMPONENT_INFO_LANGUAGE
+syn keyword ishdConstant COMPONENT_INFO_ORIGSIZE COMPONENT_INFO_OS
+syn keyword ishdConstant COMPONENT_INFO_TIME COMPONENT_INFO_VERSIONLS
+syn keyword ishdConstant COMPONENT_INFO_VERSIONMS COMPONENT_INFO_VERSIONSTR
+syn keyword ishdConstant COMPONENT_VALUE_ALWAYSOVERWRITE
+syn keyword ishdConstant COMPONENT_VALUE_CRITICAL
+syn keyword ishdConstant COMPONENT_VALUE_HIGHLYRECOMMENDED
+syn keyword ishdConstant COMPONENT_FILEINFO_LANGUAGE COMPONENT_FILEINFO_OS
+syn keyword ishdConstant COMPONENT_VALUE_NEVEROVERWRITE
+syn keyword ishdConstant COMPONENT_VALUE_NEWERDATE COMPONENT_VALUE_NEWERVERSION
+syn keyword ishdConstant COMPONENT_VALUE_OLDERDATE COMPONENT_VALUE_OLDERVERSION
+syn keyword ishdConstant COMPONENT_VALUE_SAMEORNEWDATE
+syn keyword ishdConstant COMPONENT_VALUE_SAMEORNEWERVERSION
+syn keyword ishdConstant COMPONENT_VALUE_STANDARD COMPONENT_VIEW_CHANGE
+syn keyword ishdConstant COMPONENT_INFO_DATE_EX COMPONENT_VIEW_CHILDVIEW
+syn keyword ishdConstant COMPONENT_VIEW_COMPONENT COMPONENT_VIEW_DESCRIPTION
+syn keyword ishdConstant COMPONENT_VIEW_MEDIA COMPONENT_VIEW_PARENTVIEW
+syn keyword ishdConstant COMPONENT_VIEW_SIZEAVAIL COMPONENT_VIEW_SIZETOTAL
+syn keyword ishdConstant COMPONENT_VIEW_TARGETLOCATION COMPRESSHIGH COMPRESSLOW
+syn keyword ishdConstant COMPRESSMED COMPRESSNONE CONTIGUOUS CONTINUE
+syn keyword ishdConstant COPY_ERR_CREATEDIR COPY_ERR_NODISKSPACE
+syn keyword ishdConstant COPY_ERR_OPENINPUT COPY_ERR_OPENOUTPUT
+syn keyword ishdConstant COPY_ERR_TARGETREADONLY COPY_ERR_MEMORY
+syn keyword ishdConstant CORECOMPONENTHANDLING CPU CUSTOM DATA_COMPONENT
+syn keyword ishdConstant DATA_LIST DATA_NUMBER DATA_STRING DATE DEFAULT
+syn keyword ishdConstant DEFWINDOWMODE DELETE_EOF DIALOG DIALOGCACHE
+syn keyword ishdConstant DIALOGTHINFONT DIR_WRITEABLE DIRECTORY DISABLE DISK
+syn keyword ishdConstant DISK_FREESPACE DISK_TOTALSPACE DISKID DLG_ASK_OPTIONS
+syn keyword ishdConstant DLG_ASK_PATH DLG_ASK_TEXT DLG_ASK_YESNO DLG_CANCEL
+syn keyword ishdConstant DLG_CDIR DLG_CDIR_MSG DLG_CENTERED DLG_CLOSE
+syn keyword ishdConstant DLG_DIR_DIRECTORY DLG_DIR_FILE DLG_ENTER_DISK DLG_ERR
+syn keyword ishdConstant DLG_ERR_ALREADY_EXISTS DLG_ERR_ENDDLG DLG_INFO_ALTIMAGE
+syn keyword ishdConstant DLG_INFO_CHECKMETHOD DLG_INFO_CHECKSELECTION
+syn keyword ishdConstant DLG_INFO_ENABLEIMAGE DLG_INFO_KUNITS
+syn keyword ishdConstant DLG_INFO_USEDECIMAL DLG_INIT DLG_MSG_ALL
+syn keyword ishdConstant DLG_MSG_INFORMATION DLG_MSG_NOT_HAND DLG_MSG_SEVERE
+syn keyword ishdConstant DLG_MSG_STANDARD DLG_MSG_WARNING DLG_OK DLG_STATUS
+syn keyword ishdConstant DLG_USER_CAPTION DRIVE DRIVEOPEN DLG_DIR_DRIVE
+syn keyword ishdConstant EDITBOX_CHANGE EFF_BOXSTRIPE EFF_FADE EFF_HORZREVEAL
+syn keyword ishdConstant EFF_HORZSTRIPE EFF_NONE EFF_REVEAL EFF_VERTSTRIPE
+syn keyword ishdConstant ENABLE END_OF_FILE END_OF_LIST ENHANCED ENTERDISK
+syn keyword ishdConstant ENTERDISK_ERRMSG ENTERDISKBEEP ENVSPACE EQUALS
+syn keyword ishdConstant ERR_BADPATH ERR_BADTAGFILE ERR_BOX_BADPATH
+syn keyword ishdConstant ERR_BOX_BADTAGFILE ERR_BOX_DISKID ERR_BOX_DRIVEOPEN
+syn keyword ishdConstant ERR_BOX_EXIT ERR_BOX_HELP ERR_BOX_NOSPACE ERR_BOX_PAUSE
+syn keyword ishdConstant ERR_BOX_READONLY ERR_DISKID ERR_DRIVEOPEN
+syn keyword ishdConstant EXCLUDE_SUBDIR EXCLUSIVE EXISTS EXIT EXTENDEDMEMORY
+syn keyword ishdConstant EXTENSION_ONLY ERRORFILENAME FADE_IN FADE_OUT
+syn keyword ishdConstant FAILIFEXISTS FALSE FDRIVE_NUM FEEDBACK FEEDBACK_FULL
+syn keyword ishdConstant FEEDBACK_OPERATION FEEDBACK_SPACE FILE_ATTR_ARCHIVED
+syn keyword ishdConstant FILE_ATTR_DIRECTORY FILE_ATTR_HIDDEN FILE_ATTR_NORMAL
+syn keyword ishdConstant FILE_ATTR_READONLY FILE_ATTR_SYSTEM FILE_ATTRIBUTE
+syn keyword ishdConstant FILE_BIN_CUR FILE_BIN_END FILE_BIN_START FILE_DATE
+syn keyword ishdConstant FILE_EXISTS FILE_INSTALLED FILE_INVALID FILE_IS_LOCKED
+syn keyword ishdConstant FILE_LINE_LENGTH FILE_LOCKED FILE_MODE_APPEND
+syn keyword ishdConstant FILE_MODE_BINARY FILE_MODE_BINARYREADONLY
+syn keyword ishdConstant FILE_MODE_NORMAL FILE_NO_VERSION FILE_NOT_FOUND
+syn keyword ishdConstant FILE_RD_ONLY FILE_SIZE FILE_SRC_EQUAL FILE_SRC_OLD
+syn keyword ishdConstant FILE_TIME FILE_WRITEABLE FILENAME FILENAME_ONLY
+syn keyword ishdConstant FINISHBUTTON FIXED_DRIVE FONT_TITLE FREEENVSPACE
+syn keyword ishdConstant FS_CREATEDIR FS_DISKONEREQUIRED FS_DONE FS_FILENOTINLIB
+syn keyword ishdConstant FS_GENERROR FS_INCORRECTDISK FS_LAUNCHPROCESS
+syn keyword ishdConstant FS_OPERROR FS_OUTOFSPACE FS_PACKAGING FS_RESETREQUIRED
+syn keyword ishdConstant FS_TARGETREADONLY FS_TONEXTDISK FULL FULLSCREEN
+syn keyword ishdConstant FULLSCREENSIZE FULLWINDOWMODE FOLDER_DESKTOP
+syn keyword ishdConstant FOLDER_PROGRAMS FOLDER_STARTMENU FOLDER_STARTUP
+syn keyword ishdConstant GREATER_THAN GREEN HELP HKEY_CLASSES_ROOT
+syn keyword ishdConstant HKEY_CURRENT_CONFIG HKEY_CURRENT_USER HKEY_DYN_DATA
+syn keyword ishdConstant HKEY_LOCAL_MACHINE HKEY_PERFORMANCE_DATA HKEY_USERS
+syn keyword ishdConstant HOURGLASS HWND_DESKTOP HWND_INSTALL IGNORE_READONLY
+syn keyword ishdConstant INCLUDE_SUBDIR INDVFILESTATUS INFO INFO_DESCRIPTION
+syn keyword ishdConstant INFO_IMAGE INFO_MISC INFO_SIZE INFO_SUBCOMPONENT
+syn keyword ishdConstant INFO_VISIBLE INFORMATION INVALID_LIST IS_186 IS_286
+syn keyword ishdConstant IS_386 IS_486 IS_8514A IS_86 IS_ALPHA IS_CDROM IS_CGA
+syn keyword ishdConstant IS_DOS IS_EGA IS_FIXED IS_FOLDER IS_ITEM ISLANG_ALL
+syn keyword ishdConstant ISLANG_ARABIC ISLANG_ARABIC_SAUDIARABIA
+syn keyword ishdConstant ISLANG_ARABIC_IRAQ ISLANG_ARABIC_EGYPT
+syn keyword ishdConstant ISLANG_ARABIC_LIBYA ISLANG_ARABIC_ALGERIA
+syn keyword ishdConstant ISLANG_ARABIC_MOROCCO ISLANG_ARABIC_TUNISIA
+syn keyword ishdConstant ISLANG_ARABIC_OMAN ISLANG_ARABIC_YEMEN
+syn keyword ishdConstant ISLANG_ARABIC_SYRIA ISLANG_ARABIC_JORDAN
+syn keyword ishdConstant ISLANG_ARABIC_LEBANON ISLANG_ARABIC_KUWAIT
+syn keyword ishdConstant ISLANG_ARABIC_UAE ISLANG_ARABIC_BAHRAIN
+syn keyword ishdConstant ISLANG_ARABIC_QATAR ISLANG_AFRIKAANS
+syn keyword ishdConstant ISLANG_AFRIKAANS_STANDARD ISLANG_ALBANIAN
+syn keyword ishdConstant ISLANG_ENGLISH_TRINIDAD ISLANG_ALBANIAN_STANDARD
+syn keyword ishdConstant ISLANG_BASQUE ISLANG_BASQUE_STANDARD ISLANG_BULGARIAN
+syn keyword ishdConstant ISLANG_BULGARIAN_STANDARD ISLANG_BELARUSIAN
+syn keyword ishdConstant ISLANG_BELARUSIAN_STANDARD ISLANG_CATALAN
+syn keyword ishdConstant ISLANG_CATALAN_STANDARD ISLANG_CHINESE
+syn keyword ishdConstant ISLANG_CHINESE_TAIWAN ISLANG_CHINESE_PRC
+syn keyword ishdConstant ISLANG_SPANISH_PUERTORICO ISLANG_CHINESE_HONGKONG
+syn keyword ishdConstant ISLANG_CHINESE_SINGAPORE ISLANG_CROATIAN
+syn keyword ishdConstant ISLANG_CROATIAN_STANDARD ISLANG_CZECH
+syn keyword ishdConstant ISLANG_CZECH_STANDARD ISLANG_DANISH
+syn keyword ishdConstant ISLANG_DANISH_STANDARD ISLANG_DUTCH
+syn keyword ishdConstant ISLANG_DUTCH_STANDARD ISLANG_DUTCH_BELGIAN
+syn keyword ishdConstant ISLANG_ENGLISH ISLANG_ENGLISH_BELIZE
+syn keyword ishdConstant ISLANG_ENGLISH_UNITEDSTATES
+syn keyword ishdConstant ISLANG_ENGLISH_UNITEDKINGDOM ISLANG_ENGLISH_AUSTRALIAN
+syn keyword ishdConstant ISLANG_ENGLISH_CANADIAN ISLANG_ENGLISH_NEWZEALAND
+syn keyword ishdConstant ISLANG_ENGLISH_IRELAND ISLANG_ENGLISH_SOUTHAFRICA
+syn keyword ishdConstant ISLANG_ENGLISH_JAMAICA ISLANG_ENGLISH_CARIBBEAN
+syn keyword ishdConstant ISLANG_ESTONIAN ISLANG_ESTONIAN_STANDARD
+syn keyword ishdConstant ISLANG_FAEROESE ISLANG_FAEROESE_STANDARD ISLANG_FARSI
+syn keyword ishdConstant ISLANG_FINNISH ISLANG_FINNISH_STANDARD ISLANG_FRENCH
+syn keyword ishdConstant ISLANG_FRENCH_STANDARD ISLANG_FRENCH_BELGIAN
+syn keyword ishdConstant ISLANG_FRENCH_CANADIAN ISLANG_FRENCH_SWISS
+syn keyword ishdConstant ISLANG_FRENCH_LUXEMBOURG ISLANG_FARSI_STANDARD
+syn keyword ishdConstant ISLANG_GERMAN ISLANG_GERMAN_STANDARD
+syn keyword ishdConstant ISLANG_GERMAN_SWISS ISLANG_GERMAN_AUSTRIAN
+syn keyword ishdConstant ISLANG_GERMAN_LUXEMBOURG ISLANG_GERMAN_LIECHTENSTEIN
+syn keyword ishdConstant ISLANG_GREEK ISLANG_GREEK_STANDARD ISLANG_HEBREW
+syn keyword ishdConstant ISLANG_HEBREW_STANDARD ISLANG_HUNGARIAN
+syn keyword ishdConstant ISLANG_HUNGARIAN_STANDARD ISLANG_ICELANDIC
+syn keyword ishdConstant ISLANG_ICELANDIC_STANDARD ISLANG_INDONESIAN
+syn keyword ishdConstant ISLANG_INDONESIAN_STANDARD ISLANG_ITALIAN
+syn keyword ishdConstant ISLANG_ITALIAN_STANDARD ISLANG_ITALIAN_SWISS
+syn keyword ishdConstant ISLANG_JAPANESE ISLANG_JAPANESE_STANDARD ISLANG_KOREAN
+syn keyword ishdConstant ISLANG_KOREAN_STANDARD  ISLANG_KOREAN_JOHAB
+syn keyword ishdConstant ISLANG_LATVIAN ISLANG_LATVIAN_STANDARD
+syn keyword ishdConstant ISLANG_LITHUANIAN ISLANG_LITHUANIAN_STANDARD
+syn keyword ishdConstant ISLANG_NORWEGIAN ISLANG_NORWEGIAN_BOKMAL
+syn keyword ishdConstant ISLANG_NORWEGIAN_NYNORSK ISLANG_POLISH
+syn keyword ishdConstant ISLANG_POLISH_STANDARD ISLANG_PORTUGUESE
+syn keyword ishdConstant ISLANG_PORTUGUESE_BRAZILIAN ISLANG_PORTUGUESE_STANDARD
+syn keyword ishdConstant ISLANG_ROMANIAN ISLANG_ROMANIAN_STANDARD ISLANG_RUSSIAN
+syn keyword ishdConstant ISLANG_RUSSIAN_STANDARD ISLANG_SLOVAK
+syn keyword ishdConstant ISLANG_SLOVAK_STANDARD ISLANG_SLOVENIAN
+syn keyword ishdConstant ISLANG_SLOVENIAN_STANDARD ISLANG_SERBIAN
+syn keyword ishdConstant ISLANG_SERBIAN_LATIN ISLANG_SERBIAN_CYRILLIC
+syn keyword ishdConstant ISLANG_SPANISH ISLANG_SPANISH_ARGENTINA
+syn keyword ishdConstant ISLANG_SPANISH_BOLIVIA ISLANG_SPANISH_CHILE
+syn keyword ishdConstant ISLANG_SPANISH_COLOMBIA ISLANG_SPANISH_COSTARICA
+syn keyword ishdConstant ISLANG_SPANISH_DOMINICANREPUBLIC ISLANG_SPANISH_ECUADOR
+syn keyword ishdConstant ISLANG_SPANISH_ELSALVADOR ISLANG_SPANISH_GUATEMALA
+syn keyword ishdConstant ISLANG_SPANISH_HONDURAS ISLANG_SPANISH_MEXICAN
+syn keyword ishdConstant ISLANG_THAI_STANDARD ISLANG_SPANISH_MODERNSORT
+syn keyword ishdConstant ISLANG_SPANISH_NICARAGUA ISLANG_SPANISH_PANAMA
+syn keyword ishdConstant ISLANG_SPANISH_PARAGUAY ISLANG_SPANISH_PERU
+syn keyword ishdConstant IISLANG_SPANISH_PUERTORICO
+syn keyword ishdConstant ISLANG_SPANISH_TRADITIONALSORT ISLANG_SPANISH_VENEZUELA
+syn keyword ishdConstant ISLANG_SPANISH_URUGUAY ISLANG_SWEDISH
+syn keyword ishdConstant ISLANG_SWEDISH_FINLAND ISLANG_SWEDISH_STANDARD
+syn keyword ishdConstant ISLANG_THAI ISLANG_THA_STANDARDI ISLANG_TURKISH
+syn keyword ishdConstant ISLANG_TURKISH_STANDARD ISLANG_UKRAINIAN
+syn keyword ishdConstant ISLANG_UKRAINIAN_STANDARD ISLANG_VIETNAMESE
+syn keyword ishdConstant ISLANG_VIETNAMESE_STANDARD IS_MIPS IS_MONO IS_OS2
+syn keyword ishdConstant ISOSL_ALL ISOSL_WIN31 ISOSL_WIN95 ISOSL_NT351
+syn keyword ishdConstant ISOSL_NT351_ALPHA ISOSL_NT351_MIPS ISOSL_NT351_PPC
+syn keyword ishdConstant ISOSL_NT40 ISOSL_NT40_ALPHA ISOSL_NT40_MIPS
+syn keyword ishdConstant ISOSL_NT40_PPC IS_PENTIUM IS_POWERPC IS_RAMDRIVE
+syn keyword ishdConstant IS_REMOTE IS_REMOVABLE IS_SVGA IS_UNKNOWN IS_UVGA
+syn keyword ishdConstant IS_VALID_PATH IS_VGA IS_WIN32S IS_WINDOWS IS_WINDOWS95
+syn keyword ishdConstant IS_WINDOWSNT IS_WINOS2 IS_XVGA ISTYPE INFOFILENAME
+syn keyword ishdConstant ISRES ISUSER ISVERSION LANGUAGE LANGUAGE_DRV LESS_THAN
+syn keyword ishdConstant LINE_NUMBER LISTBOX_ENTER LISTBOX_SELECT LISTFIRST
+syn keyword ishdConstant LISTLAST LISTNEXT LISTPREV LOCKEDFILE LOGGING
+syn keyword ishdConstant LOWER_LEFT LOWER_RIGHT LIST_NULL MAGENTA MAINCAPTION
+syn keyword ishdConstant MATH_COPROCESSOR MAX_STRING MENU METAFILE MMEDIA_AVI
+syn keyword ishdConstant MMEDIA_MIDI MMEDIA_PLAYASYNCH MMEDIA_PLAYCONTINUOUS
+syn keyword ishdConstant MMEDIA_PLAYSYNCH MMEDIA_STOP MMEDIA_WAVE MOUSE
+syn keyword ishdConstant MOUSE_DRV MEDIA MODE NETWORK NETWORK_DRV NEXT
+syn keyword ishdConstant NEXTBUTTON NO NO_SUBDIR NO_WRITE_ACCESS NONCONTIGUOUS
+syn keyword ishdConstant NONEXCLUSIVE NORMAL NORMALMODE NOSET NOTEXISTS NOTRESET
+syn keyword ishdConstant NOWAIT NULL NUMBERLIST OFF OK ON ONLYDIR OS OSMAJOR
+syn keyword ishdConstant OSMINOR OTHER_FAILURE OUT_OF_DISK_SPACE PARALLEL
+syn keyword ishdConstant PARTIAL PATH PATH_EXISTS PAUSE PERSONAL PROFSTRING
+syn keyword ishdConstant PROGMAN PROGRAMFILES RAM_DRIVE REAL RECORDMODE RED
+syn keyword ishdConstant REGDB_APPPATH REGDB_APPPATH_DEFAULT REGDB_BINARY
+syn keyword ishdConstant REGDB_ERR_CONNECTIONEXISTS REGDB_ERR_CORRUPTEDREGISTRY
+syn keyword ishdConstant REGDB_ERR_FILECLOSE REGDB_ERR_FILENOTFOUND
+syn keyword ishdConstant REGDB_ERR_FILEOPEN REGDB_ERR_FILEREAD
+syn keyword ishdConstant REGDB_ERR_INITIALIZATION REGDB_ERR_INVALIDFORMAT
+syn keyword ishdConstant REGDB_ERR_INVALIDHANDLE REGDB_ERR_INVALIDNAME
+syn keyword ishdConstant REGDB_ERR_INVALIDPLATFORM REGDB_ERR_OUTOFMEMORY
+syn keyword ishdConstant REGDB_ERR_REGISTRY REGDB_KEYS REGDB_NAMES REGDB_NUMBER
+syn keyword ishdConstant REGDB_STRING REGDB_STRING_EXPAND REGDB_STRING_MULTI
+syn keyword ishdConstant REGDB_UNINSTALL_NAME REGKEY_CLASSES_ROOT
+syn keyword ishdConstant REGKEY_CURRENT_USER REGKEY_LOCAL_MACHINE REGKEY_USERS
+syn keyword ishdConstant REMOTE_DRIVE REMOVE REMOVEABLE_DRIVE REPLACE
+syn keyword ishdConstant REPLACE_ITEM RESET RESTART ROOT ROTATE RUN_MAXIMIZED
+syn keyword ishdConstant RUN_MINIMIZED RUN_SEPARATEMEMORY SELECTFOLDER
+syn keyword ishdConstant SELFREGISTER SELFREGISTERBATCH SELFREGISTRATIONPROCESS
+syn keyword ishdConstant SERIAL SET SETUPTYPE SETUPTYPE_INFO_DESCRIPTION
+syn keyword ishdConstant SETUPTYPE_INFO_DISPLAYNAME SEVERE SHARE SHAREDFILE
+syn keyword ishdConstant SHELL_OBJECT_FOLDER SILENTMODE SPLITCOMPRESS SPLITCOPY
+syn keyword ishdConstant SRCTARGETDIR STANDARD STATUS STATUS95 STATUSBAR
+syn keyword ishdConstant STATUSDLG STATUSEX STATUSOLD STRINGLIST STYLE_BOLD
+syn keyword ishdConstant STYLE_ITALIC STYLE_NORMAL STYLE_SHADOW STYLE_UNDERLINE
+syn keyword ishdConstant SW_HIDE SW_MAXIMIZE SW_MINIMIZE SW_NORMAL SW_RESTORE
+syn keyword ishdConstant SW_SHOW SW_SHOWMAXIMIZED SW_SHOWMINIMIZED
+syn keyword ishdConstant SW_SHOWMINNOACTIVE SW_SHOWNA SW_SHOWNOACTIVATE
+syn keyword ishdConstant SW_SHOWNORMAL SYS_BOOTMACHINE SYS_BOOTWIN
+syn keyword ishdConstant SYS_BOOTWIN_INSTALL SYS_RESTART SYS_SHUTDOWN SYS_TODOS
+syn keyword ishdConstant SELECTED_LANGUAGE SHELL_OBJECT_LANGUAGE SRCDIR SRCDISK
+syn keyword ishdConstant SUPPORTDIR TEXT TILED TIME TRUE TYPICAL TARGETDIR
+syn keyword ishdConstant TARGETDISK UPPER_LEFT UPPER_RIGHT USER_ADMINISTRATOR
+syn keyword ishdConstant UNINST VALID_PATH VARIABLE_LEFT VARIABLE_UNDEFINED
+syn keyword ishdConstant VER_DLL_NOT_FOUND VER_UPDATE_ALWAYS VER_UPDATE_COND
+syn keyword ishdConstant VERSION VIDEO VOLUMELABEL WAIT WARNING WELCOME WHITE
+syn keyword ishdConstant WIN32SINSTALLED WIN32SMAJOR WIN32SMINOR WINDOWS_SHARED
+syn keyword ishdConstant WINMAJOR WINMINOR WINDIR WINDISK WINSYSDIR WINSYSDISK
+syn keyword ishdConstant XCOPY_DATETIME YELLOW YES
+
+syn keyword ishdFunction AskDestPath AskOptions AskPath AskText AskYesNo
+syn keyword ishdFunction AppCommand AddProfString AddFolderIcon BatchAdd
+syn keyword ishdFunction BatchDeleteEx BatchFileLoad BatchFileSave BatchFind
+syn keyword ishdFunction BatchGetFileName BatchMoveEx BatchSetFileName
+syn keyword ishdFunction ComponentDialog ComponentAddItem
+syn keyword ishdFunction ComponentCompareSizeRequired ComponentDialog
+syn keyword ishdFunction ComponentError ComponentFileEnum ComponentFileInfo
+syn keyword ishdFunction ComponentFilterLanguage ComponentFilterOS
+syn keyword ishdFunction ComponentGetData ComponentGetItemSize
+syn keyword ishdFunction ComponentInitialize ComponentIsItemSelected
+syn keyword ishdFunction ComponentListItems ComponentMoveData
+syn keyword ishdFunction ComponentSelectItem ComponentSetData ComponentSetTarget
+syn keyword ishdFunction ComponentSetupTypeEnum ComponentSetupTypeGetData
+syn keyword ishdFunction ComponentSetupTypeSet ComponentTotalSize
+syn keyword ishdFunction ComponentValidate ConfigAdd ConfigDelete ConfigFileLoad
+syn keyword ishdFunction ConfigFileSave ConfigFind ConfigGetFileName
+syn keyword ishdFunction ConfigGetInt ConfigMove ConfigSetFileName ConfigSetInt
+syn keyword ishdFunction CmdGetHwndDlg CtrlClear CtrlDir CtrlGetCurSel
+syn keyword ishdFunction CtrlGetMLEText CtrlGetMultCurSel CtrlGetState
+syn keyword ishdFunction CtrlGetSubCommand CtrlGetText CtrlPGroups
+syn keyword ishdFunction CtrlSelectText CtrlSetCurSel CtrlSetFont CtrlSetList
+syn keyword ishdFunction CtrlSetMLEText CtrlSetMultCurSel CtrlSetState
+syn keyword ishdFunction CtrlSetText CallDLLFx ChangeDirectory CloseFile
+syn keyword ishdFunction CopyFile CreateDir CreateFile CreateRegistrySet
+syn keyword ishdFunction CommitSharedFiles CreateProgramFolder
+syn keyword ishdFunction CreateShellObjects CopyBytes DefineDialog Delay
+syn keyword ishdFunction DeleteDir DeleteFile Do DoInstall DeinstallSetReference
+syn keyword ishdFunction DeinstallStart DialogSetInfo DeleteFolderIcon
+syn keyword ishdFunction DeleteProgramFolder Disable EzBatchAddPath
+syn keyword ishdFunction EzBatchAddString ExBatchReplace EnterDisk
+syn keyword ishdFunction EzConfigAddDriver EzConfigAddString EzConfigGetValue
+syn keyword ishdFunction EzConfigSetValue EndDialog EzDefineDialog ExistsDir
+syn keyword ishdFunction ExistsDisk ExitProgMan Enable EzBatchReplace
+syn keyword ishdFunction FileCompare FileDeleteLine FileGrep FileInsertLine
+syn keyword ishdFunction FindAllDirs FindAllFiles FindFile FindWindow
+syn keyword ishdFunction GetFileInfo GetLine GetFont GetDiskSpace GetEnvVar
+syn keyword ishdFunction GetExtents GetMemFree GetMode GetSystemInfo
+syn keyword ishdFunction GetValidDrivesList GetWindowHandle GetProfInt
+syn keyword ishdFunction GetProfString GetFolderNameList GetGroupNameList
+syn keyword ishdFunction GetItemNameList GetDir GetDisk HIWORD Handler Is
+syn keyword ishdFunction ISCompareServicePack InstallationInfo LOWORD LaunchApp
+syn keyword ishdFunction LaunchAppAndWait ListAddItem ListAddString ListCount
+syn keyword ishdFunction ListCreate ListCurrentItem ListCurrentString
+syn keyword ishdFunction ListDeleteItem ListDeleteString ListDestroy
+syn keyword ishdFunction ListFindItem ListFindString ListGetFirstItem
+syn keyword ishdFunction ListGetFirstString ListGetNextItem ListGetNextString
+syn keyword ishdFunction ListReadFromFile ListSetCurrentItem
+syn keyword ishdFunction ListSetCurrentString ListSetIndex ListWriteToFile
+syn keyword ishdFunction LongPathFromShortPath LongPathToQuote
+syn keyword ishdFunction LongPathToShortPath MessageBox MessageBeep NumToStr
+syn keyword ishdFunction OpenFile OpenFileMode PathAdd PathDelete PathFind
+syn keyword ishdFunction PathGet PathMove PathSet ProgDefGroupType ParsePath
+syn keyword ishdFunction PlaceBitmap PlaceWindow PlayMMedia QueryProgGroup
+syn keyword ishdFunction QueryProgItem QueryShellMgr RebootDialog ReleaseDialog
+syn keyword ishdFunction ReadBytes RenameFile ReplaceProfString ReloadProgGroup
+syn keyword ishdFunction ReplaceFolderIcon RGB RegDBConnectRegistry
+syn keyword ishdFunction RegDBCreateKeyEx RegDBDeleteKey RegDBDeleteValue
+syn keyword ishdFunction RegDBDisConnectRegistry RegDBGetAppInfo RegDBGetItem
+syn keyword ishdFunction RegDBGetKeyValueEx RegDBKeyExist RegDBQueryKey
+syn keyword ishdFunction RegDBSetAppInfo RegDBSetDefaultRoot RegDBSetItem
+syn keyword ishdFunction RegDBSetKeyValueEx SeekBytes SelectDir SetFileInfo
+syn keyword ishdFunction SelectDir SelectFolder SetupType SprintfBox SdSetupType
+syn keyword ishdFunction SdSetupTypeEx SdMakeName SilentReadData SilentWriteData
+syn keyword ishdFunction SendMessage Sprintf System SdAskDestPath SdAskOptions
+syn keyword ishdFunction SdAskOptionsList SdBitmap SdComponentDialog
+syn keyword ishdFunction SdComponentDialog2 SdComponentDialogAdv SdComponentMult
+syn keyword ishdFunction SdConfirmNewDir SdConfirmRegistration SdDisplayTopics
+syn keyword ishdFunction SdFinish SdFinishReboot SdInit SdLicense SdMakeName
+syn keyword ishdFunction SdOptionsButtons SdProductName SdRegisterUser
+syn keyword ishdFunction SdRegisterUserEx SdSelectFolder SdSetupType
+syn keyword ishdFunction SdSetupTypeEx SdShowAnyDialog SdShowDlgEdit1
+syn keyword ishdFunction SdShowDlgEdit2 SdShowDlgEdit3 SdShowFileMods
+syn keyword ishdFunction SdShowInfoList SdShowMsg SdStartCopy SdWelcome
+syn keyword ishdFunction SelectFolder ShowGroup ShowProgamFolder SetColor
+syn keyword ishdFunction SetDialogTitle SetDisplayEffect SetErrorMsg
+syn keyword ishdFunction SetErrorTitle SetFont SetStatusWindow SetTitle
+syn keyword ishdFunction SizeWindow StatusUpdate StrCompare StrFind StrGetTokens
+syn keyword ishdFunction StrLength StrRemoveLastSlash StrSub StrToLower StrToNum
+syn keyword ishdFunction StrToUpper ShowProgramFolder UnUseDLL UseDLL VarRestore
+syn keyword ishdFunction VarSave VerUpdateFile VerCompare VerFindFileVersion
+syn keyword ishdFunction VerGetFileVersion VerSearchAndUpdateFile VerUpdateFile
+syn keyword ishdFunction Welcome WaitOnDialog WriteBytes WriteLine
+syn keyword ishdFunction WriteProfString XCopyFile
+
+syn keyword ishdTodo contained TODO
+
+"integer number, or floating point number without a dot.
+syn match  ishdNumber		"\<\d\+\>"
+"floating point number, with dot
+syn match  ishdNumber		"\<\d\+\.\d*\>"
+"floating point number, starting with a dot
+syn match  ishdNumber		"\.\d\+\>"
+
+" String constants
+syn region  ishdString	start=+"+  skip=+\\\\\|\\"+  end=+"+
+
+syn region  ishdComment	start="//" end="$" contains=ishdTodo
+syn region  ishdComment	start="/\*"   end="\*/" contains=ishdTodo
+
+" Pre-processor commands
+syn region	ishdPreCondit	start="^\s*#\s*\(if\>\|ifdef\>\|ifndef\>\|elif\>\|else\>\|endif\>\)" skip="\\$" end="$" contains=ishdComment,ishdString
+if !exists("ishd_no_if0")
+  syn region	ishdHashIf0	start="^\s*#\s*if\s\+0\>" end=".\|$" contains=ishdHashIf0End
+  syn region	ishdHashIf0End	contained start="0" end="^\s*#\s*\(endif\>\|else\>\|elif\>\)" contains=ishdHashIf0Skip
+  syn region	ishdHashIf0Skip	contained start="^\s*#\s*\(if\>\|ifdef\>\|ifndef\>\)" skip="\\$" end="^\s*#\s*endif\>" contains=ishdHashIf0Skip
+endif
+syn region	ishdIncluded	contained start=+"+ skip=+\\\\\|\\"+ end=+"+
+syn match	ishdInclude	+^\s*#\s*include\>\s*"+ contains=ishdIncluded
+syn cluster	ishdPreProcGroup	contains=ishdPreCondit,ishdIncluded,ishdInclude,ishdDefine,ishdHashIf0,ishdHashIf0End,ishdHashIf0Skip,ishdNumber
+syn region	ishdDefine		start="^\s*#\s*\(define\|undef\)\>" end="$" contains=ALLBUT,@ishdPreProcGroup
+
+" Define the default highlighting.
+" For version 5.7 and earlier: only when not done already
+" For version 5.8 and later: only when an item doesn't have highlighting yet
+if version >= 508 || !exists("did_is_syntax_inits")
+  if version < 508
+    let did_is_syntax_inits = 1
+    command -nargs=+ HiLink hi link <args>
+  else
+    command -nargs=+ HiLink hi def link <args>
+  endif
+
+  HiLink ishdNumber	    Number
+  HiLink ishdError	    Error
+  HiLink ishdStatement	    Statement
+  HiLink ishdString	    String
+  HiLink ishdComment	    Comment
+  HiLink ishdTodo	    Todo
+  HiLink ishdFunction	    Identifier
+  HiLink ishdConstant	    PreProc
+  HiLink ishdType	    Type
+  HiLink ishdInclude	    Include
+  HiLink ishdDefine	    Macro
+  HiLink ishdIncluded	    String
+  HiLink ishdPreCondit	    PreCondit
+  HiLink ishdHashIf0Skip   ishdHashIf0
+  HiLink ishdHashIf0End    ishdHashIf0
+  HiLink ishdHashIf0	    Comment
+
+  delcommand HiLink
+endif
+
+let b:current_syntax = "ishd"
+
+" vim: ts=8
--- /dev/null
+++ b/lib/vimfiles/syntax/iss.vim
@@ -1,0 +1,149 @@
+" Vim syntax file
+" Language:             Inno Setup File (iss file) and My InnoSetup extension
+" Maintainer:           Jason Mills (jmills@cs.mun.ca)
+" Previous Maintainer:  Dominique St�phan (dominique@mggen.com)
+" Last Change:          2004 Dec 14
+"
+" Todo:
+"  - The paramter String: is matched as flag string (because of case ignore).
+"  - Pascal scripting syntax is not recognized.
+"  - Embedded double quotes confuse string matches. e.g. "asfd""asfa"
+
+" For version 5.x: Clear all syntax items
+" For version 6.x: Quit when a syntax file was already loaded
+if version < 600
+  syntax clear
+elseif exists("b:current_syntax")
+  finish
+endif
+
+" shut case off
+syn case ignore
+
+" Preprocessor
+syn region issPreProc start="^\s*#" end="$"
+
+" Section
+syn region issSection	start="\[" end="\]"
+
+" Label in the [Setup] Section
+syn match  issDirective	"^[^=]\+="
+
+" URL
+syn match  issURL	"http[s]\=:\/\/.*$"
+
+" Parameters used for any section.
+" syn match  issParam"[^: ]\+:"
+syn match  issParam	"Name:"
+syn match  issParam	"MinVersion:\|OnlyBelowVersion:\|Languages:"
+syn match  issParam	"Source:\|DestDir:\|DestName:\|CopyMode:"
+syn match  issParam	"Attribs:\|Permissions:\|FontInstall:\|Flags:"
+syn match  issParam	"FileName:\|Parameters:\|WorkingDir:\|HotKey:\|Comment:"
+syn match  issParam	"IconFilename:\|IconIndex:"
+syn match  issParam	"Section:\|Key:\|String:"
+syn match  issParam	"Root:\|SubKey:\|ValueType:\|ValueName:\|ValueData:"
+syn match  issParam	"RunOnceId:"
+syn match  issParam	"Type:\|Excludes:"
+syn match  issParam	"Components:\|Description:\|GroupDescription:\|Types:\|ExtraDiskSpaceRequired:"
+syn match  issParam	"StatusMsg:\|RunOnceId:\|Tasks:"
+syn match  issParam	"MessagesFile:\|LicenseFile:\|InfoBeforeFile:\|InfoAfterFile:"
+
+syn match  issComment	"^\s*;.*$"
+
+" folder constant
+syn match  issFolder	"{[^{]*}"
+
+" string
+syn region issString	start=+"+ end=+"+ contains=issFolder
+
+" [Dirs]
+syn keyword issDirsFlags deleteafterinstall uninsalwaysuninstall uninsneveruninstall
+
+" [Files]
+syn keyword issFilesCopyMode normal onlyifdoesntexist alwaysoverwrite alwaysskipifsameorolder dontcopy
+syn keyword issFilesAttribs readonly hidden system
+syn keyword issFilesPermissions full modify readexec
+syn keyword issFilesFlags allowunsafefiles comparetimestampalso confirmoverwrite deleteafterinstall
+syn keyword issFilesFlags dontcopy dontverifychecksum external fontisnttruetype ignoreversion 
+syn keyword issFilesFlags isreadme onlyifdestfileexists onlyifdoesntexist overwritereadonly 
+syn keyword issFilesFlags promptifolder recursesubdirs regserver regtypelib restartreplace
+syn keyword issFilesFlags sharedfile skipifsourcedoesntexist sortfilesbyextension touch 
+syn keyword issFilesFlags uninsremovereadonly uninsrestartdelete uninsneveruninstall
+syn keyword issFilesFlags replacesameversion nocompression noencryption noregerror
+
+
+" [Icons]
+syn keyword issIconsFlags closeonexit createonlyiffileexists dontcloseonexit 
+syn keyword issIconsFlags runmaximized runminimized uninsneveruninstall useapppaths
+
+" [INI]
+syn keyword issINIFlags createkeyifdoesntexist uninsdeleteentry uninsdeletesection uninsdeletesectionifempty
+
+" [Registry]
+syn keyword issRegRootKey   HKCR HKCU HKLM HKU HKCC
+syn keyword issRegValueType none string expandsz multisz dword binary
+syn keyword issRegFlags createvalueifdoesntexist deletekey deletevalue dontcreatekey 
+syn keyword issRegFlags preservestringtype noerror uninsclearvalue 
+syn keyword issRegFlags uninsdeletekey uninsdeletekeyifempty uninsdeletevalue
+
+" [Run] and [UninstallRun]
+syn keyword issRunFlags hidewizard nowait postinstall runhidden runmaximized
+syn keyword issRunFlags runminimized shellexec skipifdoesntexist skipifnotsilent 
+syn keyword issRunFlags skipifsilent unchecked waituntilidle
+
+" [Types]
+syn keyword issTypesFlags iscustom
+
+" [Components]
+syn keyword issComponentsFlags dontinheritcheck exclusive fixed restart disablenouninstallwarning
+
+" [UninstallDelete] and [InstallDelete]
+syn keyword issInstallDeleteType files filesandordirs dirifempty
+
+" [Tasks]
+syn keyword issTasksFlags checkedonce dontinheritcheck exclusive restart unchecked 
+
+
+" Define the default highlighting.
+" For version 5.7 and earlier: only when not done already
+" For version 5.8 and later: only when an item doesn't have highlighting yet
+if version >= 508 || !exists("did_iss_syntax_inits")
+  if version < 508
+    let did_iss_syntax_inits = 1
+    command -nargs=+ HiLink hi link <args>
+  else
+    command -nargs=+ HiLink hi def link <args>
+  endif
+
+   " The default methods for highlighting.  Can be overridden later
+   HiLink issSection	Special
+   HiLink issComment	Comment
+   HiLink issDirective	Type
+   HiLink issParam	Type
+   HiLink issFolder	Special
+   HiLink issString	String
+   HiLink issURL	Include
+   HiLink issPreProc	PreProc 
+
+   HiLink issDirsFlags		Keyword
+   HiLink issFilesCopyMode	Keyword
+   HiLink issFilesAttribs	Keyword
+   HiLink issFilesPermissions	Keyword
+   HiLink issFilesFlags		Keyword
+   HiLink issIconsFlags		Keyword
+   HiLink issINIFlags		Keyword
+   HiLink issRegRootKey		Keyword
+   HiLink issRegValueType	Keyword
+   HiLink issRegFlags		Keyword
+   HiLink issRunFlags		Keyword
+   HiLink issTypesFlags		Keyword
+   HiLink issComponentsFlags	Keyword
+   HiLink issInstallDeleteType	Keyword
+   HiLink issTasksFlags		Keyword
+
+  delcommand HiLink
+endif
+
+let b:current_syntax = "iss"
+
+" vim:ts=8
--- /dev/null
+++ b/lib/vimfiles/syntax/ist.vim
@@ -1,0 +1,70 @@
+" Vim syntax file
+" Language:	Makeindex style file, *.ist
+" Maintainer:	Peter Meszaros <pmeszaros@effice.hu>
+" Last Change:	May 4, 2001
+
+" For version 5.x: Clear all syntax items
+" For version 6.x: Quit when a syntax file was already loaded
+if version < 600
+  syntax clear
+elseif exists("b:current_syntax")
+  finish
+endif
+
+if version >= 600
+  setlocal iskeyword=$,@,48-57,_
+else
+  set iskeyword=$,@,48-57,_
+endif
+
+syn case ignore
+syn keyword IstInpSpec  actual  arg_close arg_open encap       escape
+syn keyword IstInpSpec  keyword level     quote    range_close range_open
+syn keyword IstInpSpec  page_compositor
+
+syn keyword IstOutSpec	preamble	 postamble	  setpage_prefix   setpage_suffix   group_skip
+syn keyword IstOutSpec	headings_flag	 heading_prefix   heading_suffix
+syn keyword IstOutSpec	lethead_flag	 lethead_prefix   lethead_suffix
+syn keyword IstOutSpec	symhead_positive symhead_negative numhead_positive numhead_negative
+syn keyword IstOutSpec	item_0		 item_1		  item_2	   item_01
+syn keyword IstOutSpec	item_x1		 item_12	  item_x2
+syn keyword IstOutSpec	delim_0		 delim_1	  delim_2
+syn keyword IstOutSpec	delim_n		 delim_r	  delim_t
+syn keyword IstOutSpec	encap_prefix	 encap_infix	  encap_suffix
+syn keyword IstOutSpec	line_max	 indent_space	  indent_length
+syn keyword IstOutSpec	suffix_2p	 suffix_3p	  suffix_mp
+
+syn region  IstString	   matchgroup=IstDoubleQuote start=+"+ skip=+\\"+ end=+"+ contains=IstSpecial
+syn match   IstCharacter   "'.'"
+syn match   IstNumber	   "\d\+"
+syn match   IstComment	   "^[\t ]*%.*$"	 contains=IstTodo
+syn match   IstSpecial	   "\\\\\|{\|}\|#\|\\n"  contained
+syn match   IstTodo	   "DEBUG\|TODO"	 contained
+
+" Define the default highlighting.
+" For version 5.7 and earlier: only when not done already
+" For version 5.8 and later: only when an item doesn't have highlighting yet
+if version >= 508 || !exists("did_dummy_syn_inits")
+  if version < 508
+    let did_dummy_syn_inits = 1
+    command -nargs=+ HiLink hi link <args>
+  else
+    command -nargs=+ HiLink hi def link <args>
+  endif
+
+  HiLink IstInpSpec	Type
+  HiLink IstOutSpec	Identifier
+  HiLink IstString	String
+  HiLink IstNumber	Number
+  HiLink IstComment	Comment
+  HiLink IstTodo	Todo
+  HiLink IstSpecial	Special
+  HiLink IstDoubleQuote	Label
+  HiLink IstCharacter	Label
+
+  delcommand HiLink
+endif
+
+let b:current_syntax = "ist"
+
+" vim: ts=8 sw=2
--- /dev/null
+++ b/lib/vimfiles/syntax/jal.vim
@@ -1,0 +1,249 @@
+" Vim syntax file
+" Language:	JAL
+" Version: 0.1
+" Last Change:	2003 May 11
+" Maintainer:  Mark Gross <mark@thegnar.org>
+" This is a syntax definition for the JAL language.
+" It is based on the Source Forge compiler source code.
+" https://sourceforge.net/projects/jal/
+"
+" TODO test.
+
+" For version 5.x: Clear all syntax items
+" For version 6.x: Quit when a syntax file was already loaded
+if version < 600
+  syntax clear
+elseif exists("b:current_syntax")
+  finish
+endif
+
+syn case ignore
+syn sync lines=250
+
+syn keyword picTodo NOTE TODO XXX contained
+
+syn match picIdentifier "[a-z_$][a-z0-9_$]*"
+syn match picLabel      "^[A-Z_$][A-Z0-9_$]*"
+syn match picLabel      "^[A-Z_$][A-Z0-9_$]*:"me=e-1
+
+syn match picASCII      "A\='.'"
+syn match picBinary     "B'[0-1]\+'"
+syn match picDecimal    "D'\d\+'"
+syn match picDecimal    "\d\+"
+syn match picHexadecimal "0x\x\+"
+syn match picHexadecimal "H'\x\+'"
+syn match picHexadecimal "[0-9]\x*h"
+syn match picOctal      "O'[0-7]\o*'"
+
+syn match picComment    ";.*" contains=picTodo
+
+syn region picString    start=+"+ end=+"+
+
+syn keyword picRegister indf tmr0 pcl status fsr port_a port_b port_c port_d port_e x84_eedata x84_eeadr pclath intcon
+syn keyword picRegister f877_tmr1l   f877_tmr1h   f877_t1con   f877_t2con   f877_ccpr1l  f877_ccpr1h  f877_ccp1con
+syn keyword picRegister f877_pir1    f877_pir2    f877_pie1    f877_adcon1  f877_adcon0  f877_pr2     f877_adresl  f877_adresh
+syn keyword picRegister f877_eeadr   f877_eedath  f877_eeadrh  f877_eedata  f877_eecon1  f877_eecon2  f628_EECON2
+syn keyword picRegister f877_rcsta   f877_txsta   f877_spbrg   f877_txreg   f877_rcreg   f628_EEDATA  f628_EEADR   f628_EECON1
+
+" Register --- bits
+" STATUS
+syn keyword picRegisterPart status_c status_dc status_z status_pd
+syn keyword picRegisterPart status_to status_rp0 status_rp1 status_irp
+
+" pins
+syn keyword picRegisterPart pin_a0 pin_a1 pin_a2 pin_a3 pin_a4 pin_a5
+syn keyword picRegisterPart pin_b0 pin_b1 pin_b2 pin_b3 pin_b4 pin_b5 pin_b6 pin_b7
+syn keyword picRegisterPart pin_c0 pin_c1 pin_c2 pin_c3 pin_c4 pin_c5 pin_c6 pin_c7
+syn keyword picRegisterPart pin_d0 pin_d1 pin_d2 pin_d3 pin_d4 pin_d5 pin_d6 pin_d7
+syn keyword picRegisterPart pin_e0 pin_e1 pin_e2
+
+syn keyword picPortDir port_a_direction  port_b_direction  port_c_direction  port_d_direction  port_e_direction
+
+syn match picPinDir "pin_a[012345]_direction"
+syn match picPinDir "pin_b[01234567]_direction"
+syn match picPinDir "pin_c[01234567]_direction"
+syn match picPinDir "pin_d[01234567]_direction"
+syn match picPinDir "pin_e[012]_direction"
+
+
+" INTCON
+syn keyword picRegisterPart intcon_gie intcon_eeie intcon_peie intcon_t0ie intcon_inte
+syn keyword picRegisterPart intcon_rbie intcon_t0if intcon_intf intcon_rbif
+
+" TIMER
+syn keyword picRegisterPart t1ckps1 t1ckps0 t1oscen t1sync tmr1cs tmr1on tmr1ie tmr1if
+
+"cpp bits
+syn keyword picRegisterPart ccp1x ccp1y
+
+" adcon bits
+syn keyword picRegisterPart adcon0_go adcon0_ch0 adcon0_ch1 adcon0_ch2
+
+" EECON
+syn keyword picRegisterPart  eecon1_rd eecon1_wr eecon1_wren eecon1_wrerr eecon1_eepgd
+syn keyword picRegisterPart f628_eecon1_rd f628_eecon1_wr f628_eecon1_wren f628_eecon1_wrerr
+
+" usart
+syn keyword picRegisterPart tx9 txen sync brgh tx9d
+syn keyword picRegisterPart spen rx9 cren ferr oerr rx9d
+syn keyword picRegisterPart TXIF RCIF
+
+" OpCodes...
+syn keyword picOpcode addlw andlw call clrwdt goto iorlw movlw option retfie retlw return sleep sublw tris
+syn keyword picOpcode xorlw addwf andwf clrf clrw comf decf decfsz incf incfsz retiw iorwf movf movwf nop
+syn keyword picOpcode rlf rrf subwf swapf xorwf bcf bsf btfsc btfss skpz skpnz setz clrz skpc skpnc setc clrc
+syn keyword picOpcode skpdc skpndc setdc clrdc movfw tstf bank page HPAGE mullw mulwf cpfseq cpfsgt cpfslt banka bankb
+
+
+syn keyword jalBoolean		true false
+syn keyword jalBoolean		off on
+syn keyword jalBit		high low
+syn keyword jalConstant		Input Output all_input all_output
+syn keyword jalConditional	if else then elsif end if
+syn keyword jalLabel		goto
+syn keyword jalRepeat		for while forever loop
+syn keyword jalStatement	procedure function
+syn keyword jalStatement	return end volatile const var
+syn keyword jalType		bit byte
+
+syn keyword jalModifier		interrupt assembler asm put get
+syn keyword jalStatement	out in is begin at
+syn keyword jalDirective	pragma jump_table target target_clock target_chip name error test assert
+syn keyword jalPredefined       hs xt rc lp internal 16c84 16f84 16f877 sx18 sx28 12c509a 12c508
+syn keyword jalPredefined       12ce674 16f628 18f252 18f242 18f442 18f452 12f629 12f675 16f88
+syn keyword jalPredefined	16f876 16f873 sx_12 sx18 sx28 pic_12 pic_14 pic_16
+
+syn keyword jalDirective chip osc clock  fuses  cpu watchdog powerup protection
+
+syn keyword jalFunction		bank_0 bank_1 bank_2 bank_3 bank_4 bank_5 bank_6 bank_7 trisa trisb trisc trisd trise
+syn keyword jalFunction		_trisa_flush _trisb_flush _trisc_flush _trisd_flush _trise_flush
+
+syn keyword jalPIC		local idle_loop
+
+syn region  jalAsm		matchgroup=jalAsmKey start="\<assembler\>" end="\<end assembler\>" contains=jalComment,jalPreProc,jalLabel,picIdentifier, picLabel,picASCII,picDecimal,picHexadecimal,picOctal,picComment,picString,picRegister,picRigisterPart,picOpcode,picDirective,jalPIC
+syn region  jalAsm		matchgroup=jalAsmKey start="\<asm\>" end=/$/ contains=jalComment,jalPreProc,jalLabel,picIdentifier, picLabel,picASCII,picDecimal,picHexadecimal,picOctal,picComment,picString,picRegister,picRigisterPart,picOpcode,picDirective,jalPIC
+
+syn region  jalPsudoVars matchgroup=jalPsudoVarsKey start="\<'put\>" end="/<is/>"  contains=jalComment
+
+syn match  jalStringEscape	contained "#[12][0-9]\=[0-9]\="
+syn match   jalIdentifier		"\<[a-zA-Z_][a-zA-Z0-9_]*\>"
+syn match   jalSymbolOperator		"[+\-/*=]"
+syn match   jalSymbolOperator		"!"
+syn match   jalSymbolOperator		"<"
+syn match   jalSymbolOperator		">"
+syn match   jalSymbolOperator		"<="
+syn match   jalSymbolOperator		">="
+syn match   jalSymbolOperator		"!="
+syn match   jalSymbolOperator		"=="
+syn match   jalSymbolOperator		"<<"
+syn match   jalSymbolOperator		">>"
+syn match   jalSymbolOperator		"|"
+syn match   jalSymbolOperator		"&"
+syn match   jalSymbolOperator		"%"
+syn match   jalSymbolOperator		"?"
+syn match   jalSymbolOperator		"[()]"
+syn match   jalSymbolOperator		"[\^.]"
+syn match   jalLabel			"[\^]*:"
+
+syn match  jalNumber		"-\=\<\d[0-9_]\+\>"
+syn match  jalHexNumber		"0x[0-9A-Fa-f_]\+\>"
+syn match  jalBinNumber		"0b[01_]\+\>"
+
+" String
+"wrong strings
+syn region  jalStringError matchgroup=jalStringError start=+"+ end=+"+ end=+$+ contains=jalStringEscape
+
+"right strings
+syn region  jalString matchgroup=jalString start=+'+ end=+'+ oneline contains=jalStringEscape
+" To see the start and end of strings:
+syn region  jalString matchgroup=jalString start=+"+ end=+"+ oneline contains=jalStringEscapeGPC
+
+syn keyword jalTodo contained	TODO
+syn region jalComment		start=/-- /  end=/$/ oneline contains=jalTodo
+syn region jalComment		start=/--\t/  end=/$/ oneline contains=jalTodo
+syn match  jalComment		/--\_$/
+syn region jalPreProc		start="include"  end=/$/ contains=JalComment,jalToDo
+
+
+if exists("jal_no_tabs")
+	syn match jalShowTab "\t"
+endif
+
+
+" Define the default highlighting.
+" For version 5.7 and earlier: only when not done already
+" For version 5.8 and later: only when an item doesn't have highlighting yet
+if version >= 508 || !exists("did_jal_syn_inits")
+if version < 508
+  let did_jal_syn_inits = 1
+  command -nargs=+ HiLink hi link <args>
+else
+  command -nargs=+ HiLink hi def link <args>
+endif
+
+  HiLink jalAcces		jalStatement
+  HiLink jalBoolean		Boolean
+  HiLink jalBit			Boolean
+  HiLink jalComment		Comment
+  HiLink jalConditional		Conditional
+  HiLink jalConstant		Constant
+  HiLink jalDelimiter		Identifier
+  HiLink jalDirective		PreProc
+  HiLink jalException		Exception
+  HiLink jalFloat		Float
+  HiLink jalFunction		Function
+  HiLink jalPsudoVarsKey	Function
+  HiLink jalLabel		Label
+  HiLink jalMatrixDelimiter	Identifier
+  HiLink jalModifier		Type
+  HiLink jalNumber		Number
+  HiLink jalBinNumber		Number
+  HiLink jalHexNumber		Number
+  HiLink jalOperator		Operator
+  HiLink jalPredefined		Constant
+  HiLink jalPreProc		PreProc
+  HiLink jalRepeat		Repeat
+  HiLink jalStatement		Statement
+  HiLink jalString		String
+  HiLink jalStringEscape	Special
+  HiLink jalStringEscapeGPC	Special
+  HiLink jalStringError		Error
+  HiLink jalStruct		jalStatement
+  HiLink jalSymbolOperator	jalOperator
+  HiLink jalTodo		Todo
+  HiLink jalType		Type
+  HiLink jalUnclassified	Statement
+  HiLink jalAsm			Assembler
+  HiLink jalError		Error
+  HiLink jalAsmKey		Statement
+  HiLink jalPIC			Statement
+
+  HiLink jalShowTab		Error
+
+  HiLink picTodo		Todo
+  HiLink picComment		Comment
+  HiLink picDirective		Statement
+  HiLink picLabel		Label
+  HiLink picString		String
+
+  HiLink picOpcode		Keyword
+  HiLink picRegister		Structure
+  HiLink picRegisterPart	Special
+  HiLink picPinDir		SPecial
+  HiLink picPortDir		SPecial
+
+  HiLink picASCII		String
+  HiLink picBinary		Number
+  HiLink picDecimal		Number
+  HiLink picHexadecimal		Number
+  HiLink picOctal		Number
+
+  HiLink picIdentifier		Identifier
+
+  delcommand HiLink
+endif
+
+
+let b:current_syntax = "jal"
+
+" vim: ts=8 sw=2
--- /dev/null
+++ b/lib/vimfiles/syntax/jam.vim
@@ -1,0 +1,252 @@
+" Vim syntax file
+" Language:	JAM
+" Maintainer:	Ralf Lemke (ralflemk@t-online.de)
+" Last change:	09-10-2000
+
+" For version 5.x: Clear all syntax items
+" For version 6.x: Quit when a syntax file was already loaded
+if version < 600
+  syntax clear
+elseif exists("b:current_syntax")
+  finish
+endif
+
+if version >= 600
+  setlocal iskeyword=@,48-57,_,-
+else
+  set iskeyword=@,48-57,_,-
+endif
+
+" A bunch of useful jam keywords
+syn keyword	jamStatement	break call dbms flush global include msg parms proc public receive return send unload vars
+syn keyword	jamConditional	if else
+syn keyword	jamRepeat	for while next step
+
+syn keyword	jamTodo		contained TODO FIXME XXX
+syn keyword	jamDBState1	alias binary catquery close close_all_connections column_names connection continue continue_bottom continue_down continue_top continue_up
+syn keyword	jamDBState2	     cursor declare engine execute format occur onentry onerror onexit sql start store unique with
+syn keyword	jamSQLState1	all alter and any avg between by count create current data database delete distinct drop exists fetch from grant group
+syn keyword	jamSQLState2	having index insert into like load max min of open order revoke rollback runstats select set show stop sum synonym table to union update values view where bundle
+
+syn keyword     jamLibFunc1     dm_bin_create_occur dm_bin_delete_occur dm_bin_get_dlength dm_bin_get_occur dm_bin_length dm_bin_max_occur dm_bin_set_dlength dm_convert_empty dm_cursor_connection dm_cursor_consistent dm_cursor_engine dm_dbi_init dm_dbms dm_dbms_noexp dm_disable_styles dm_enable_styles dm_exec_sql dm_expand dm_free_sql_info dm_gen_change_execute_using dm_gen_change_select_from dm_gen_change_select_group_by dm_gen_change_select_having dm_gen_change_select_list dm_gen_change_select_order_by dm_gen_change_select_suffix dm_gen_change_select_where dm_gen_get_tv_alias dm_gen_sql_info
+
+syn keyword     jamLibFunc2     dm_get_db_conn_handle dm_get_db_cursor_handle dm_get_driver_option dm_getdbitext dm_init dm_is_connection dm_is_cursor dm_is_engine dm_odb_preserves_cursor dm_reset dm_set_driver_option dm_set_max_fetches dm_set_max_rows_per_fetch dm_set_tm_clear_fast dm_val_relative sm_adjust_area sm_allget sm_amt_format sm_e_amt_format sm_i_amt_format sm_n_amt_format sm_o_amt_format sm_append_bundle_data sm_append_bundle_done sm_append_bundle_item sm_d_at_cur sm_l_at_cur sm_r_at_cur sm_mw_attach_drawing_func sm_mwn_attach_drawing_func sm_mwe_attach_drawing_func sm_xm_attach_drawing_func sm_xmn_attach_drawing_func sm_xme_attach_drawing_func sm_backtab sm_bel sm_bi_comparesm_bi_copy sm_bi_initialize sm_bkrect sm_c_off sm_c_on sm_c_vis sm_calc sm_cancel sm_ckdigit sm_cl_all_mdts sm_cl_unprot sm_clear_array sm_n_clear_array sm_1clear_array sm_n_1clear_array sm_close_window sm_com_load_picture sm_com_QueryInterface sm_com_result sm_com_result_msg sm_com_set_handler sm_copyarray sm_n_copyarray sm_create_bundle
+
+syn keyword     jamLibFunc3     sm_d_msg_line sm_dblval sm_e_dblval sm_i_dblval sm_n_dblval sm_o_dblval sm_dd_able sm_dde_client_connect_cold sm_dde_client_connect_hot sm_dde_client_connect_warm sm_dde_client_disconnect sm_dde_client_off sm_dde_client_on sm_dde_client_paste_link_cold sm_dde_client_paste_link_hot sm_dde_client_paste_link_warm sm_dde_client_request sm_dde_execute sm_dde_install_notify sm_dde_poke sm_dde_server_off sm_dde_server_on sm_delay_cursor sm_deselect sm_dicname sm_disp_off sm_dlength sm_e_dlength sm_i_dlength sm_n_dlength sm_o_dlength sm_do_uinstalls sm_i_doccur sm_o_doccur sm_drawingarea sm_xm_drawingarea sm_dtofield sm_e_dtofield sm_i_dtofield sm_n_dtofield sm_o_dtofield sm_femsg sm_ferr_reset sm_fi_path sm_file_copy sm_file_exists sm_file_move sm_file_remove sm_fi_open sm_fi_path sm_filebox sm_filetypes sm_fio_a2f sm_fio_close sm_fio_editor sm_fio_error sm_fio_error_set sm_fio_f2a sm_fio_getc sm_fio_gets sm_fio_handle sm_fio_open sm_fio_putc sm_fio_puts sm_fio_rewind sm_flush sm_d_form sm_l_form
+
+syn keyword     jamLibFunc4     sm_r_form sm_formlist sm_fptr sm_e_fptr sm_i_fptr sm_n_fptr sm_o_fptr sm_fqui_msg sm_fquiet_err sm_free_bundle sm_ftog sm_e_ftog sm_i_ftog sm_n_ftog sm_o_ftog sm_fval sm_e_fval sm_i_fval sm_n_fval sm_o_fval sm_i_get_bi_data sm_o_get_bi_data sm_get_bundle_data sm_get_bundle_item_count sm_get_bundle_occur_count sm_get_next_bundle_name sm_i_get_tv_bi_data sm_o_get_tv_bi_data sm_getfield sm_e_getfield sm_i_getfield sm_n_getfield sm_o_getfield sm_getkey sm_gofield sm_e_gofield sm_i_gofield sm_n_gofield sm_o_gofield sm_gtof sm_gval sm_i_gtof sm_n_gval sm_hlp_by_name sm_home sm_inimsg sm_initcrt sm_jinitcrt sm_jxinitcrt sm_input sm_inquire sm_install sm_intval sm_e_intval sm_i_intval sm_n_intval sm_o_intval sm_i_ioccur sm_o_ioccur sm_is_bundle sm_is_no sm_e_is_no sm_i_is_no sm_n_is_no sm_o_is_no sm_is_yes sm_e_is_yes sm_i_is_yes sm_n_is_yes sm_o_is_yes sm_isabort sm_iset sm_issv sm_itofield sm_e_itofield sm_i_itofield sm_n_itofield sm_o_itofield sm_jclose sm_jfilebox sm_jform sm_djplcall sm_jplcall
+
+syn keyword     jamLibFunc5     sm_sjplcall sm_jplpublic sm_jplunload sm_jtop sm_jwindow sm_key_integer sm_keyfilter sm_keyhit sm_keyinit sm_n_keyinit sm_keylabel sm_keyoption sm_l_close sm_l_open sm_l_open_syslib sm_last sm_launch sm_h_ldb_fld_get sm_n_ldb_fld_get sm_h_ldb_n_fld_get sm_n_ldb_n_fld_get sm_h_ldb_fld_store sm_n_ldb_fld_store sm_h_ldb_n_fld_store sm_n_ldb_n_fld_store sm_ldb_get_active sm_ldb_get_inactive sm_ldb_get_next_active sm_ldb_get_next_inactive sm_ldb_getfield sm_i_ldb_getfield sm_n_ldb_getfield sm_o_ldb_getfield sm_ldb_h_getfield sm_i_ldb_h_getfield sm_n_ldb_h_getfield sm_o_ldb_h_getfield sm_ldb_handle sm_ldb_init sm_ldb_is_loaded sm_ldb_load sm_ldb_name sm_ldb_next_handle sm_ldb_pop sm_ldb_push sm_ldb_putfield sm_i_ldb_putfield sm_n_ldb_putfield sm_o_ldb_putfield sm_ldb_h_putfield sm_i_ldb_h_putfield sm_n_ldb_h_putfield sm_o_ldb_h_putfield sm_ldb_state_get sm_ldb_h_state_get sm_ldb_state_set sm_ldb_h_state_set sm_ldb_unload sm_ldb_h_unload sm_leave sm_list_objects_count sm_list_objects_end sm_list_objects_next
+
+syn keyword     jamLibFunc6     sm_list_objects_start sm_lngval sm_e_lngval sm_i_lngval sm_n_lngval sm_o_lngval sm_load_screen sm_log sm_lstore sm_ltofield sm_e_ltofield sm_i_ltofield sm_n_ltofield sm_o_ltofield sm_m_flush sm_menu_bar_error sm_menu_change sm_menu_create sm_menu_delete sm_menu_get_int sm_menu_get_str sm_menu_install sm_menu_remove sm_message_box sm_mncrinit6 sm_mnitem_change sm_n_mnitem_change sm_mnitem_create sm_n_mnitem_create sm_mnitem_delete sm_n_mnitem_delete sm_mnitem_get_int sm_n_mnitem_get_int sm_mnitem_get_str sm_n_mnitem_get_str sm_mnscript_load sm_mnscript_unload sm_ms_inquire sm_msg sm_msg_del sm_msg_get sm_msg_read sm_d_msg_read sm_n_msg_read sm_msgfind sm_mts_CreateInstance sm_mts_CreateProperty sm_mts_CreatePropertyGroup sm_mts_DisableCommit sm_mts_EnableCommit sm_mts_GetPropertyValue sm_mts_IsCallerInRole sm_mts_IsInTransaction sm_mts_IsSecurityEnabled sm_mts_PutPropertyValue sm_mts_SetAbort sm_mts_SetComplete sm_mus_time sm_mw_get_client_wnd sm_mw_get_cmd_show sm_mw_get_frame_wnd sm_mw_get_instance
+
+syn keyword     jamLibFunc7     sm_mw_get_prev_instance sm_mw_PrintScreen sm_next_sync sm_nl sm_null sm_e_null sm_i_null sm_n_null sm_o_null sm_obj_call sm_obj_copy sm_obj_copy_id sm_obj_create sm_obj_delete sm_obj_delete_id sm_obj_get_property sm_obj_onerror sm_obj_set_property sm_obj_sort sm_obj_sort_auto sm_occur_no sm_off_gofield sm_e_off_gofield sm_i_off_gofield sm_n_off_gofield sm_o_off_gofield sm_option sm_optmnu_id sm_pinquire sm_popup_at_cur sm_prop_error sm_prop_get_int sm_prop_get_str sm_prop_get_dbl sm_prop_get_x_int sm_prop_get_x_str sm_prop_get_x_dbl sm_prop_get_m_int sm_prop_get_m_str sm_prop_get_m_dbl sm_prop_id sm_prop_name_to_id sm_prop_set_int sm_prop_set_str sm_prop_set_dbl sm_prop_set_x_int sm_prop_set_x_str sm_prop_set_x_dbl sm_prop_set_m_int sm_prop_set_m_str sm_prop_set_m_dbl sm_pset sm_putfield sm_e_putfield sm_i_putfield sm_n_putfield sm_o_putfield sm_raise_exception sm_receive sm_receive_args sm_rescreen sm_resetcrt sm_jresetcrt sm_jxresetcrt sm_resize sm_restore_data sm_return sm_return_args sm_rmformlist sm_rs_data
+
+syn keyword     jamLibFunc8     sm_rw_error_message sm_rw_play_metafile sm_rw_runreport sm_s_val sm_save_data sm_sdtime sm_select sm_send sm_set_help sm_setbkstat sm_setsibling sm_setstatus sm_sh_off sm_shell sm_shrink_to_fit sm_slib_error sm_slib_install sm_slib_load sm_soption sm_strip_amt_ptr sm_e_strip_amt_ptr sm_i_strip_amt_ptr sm_n_strip_amt_ptr sm_o_strip_amt_ptr sm_sv_data sm_sv_free sm_svscreen sm_tab sm_tm_clear sm_tm_clear_model_events sm_tm_command sm_tm_command_emsgset sm_tm_command_errset sm_tm_continuation_validity sm_tm_dbi_checker sm_tm_error sm_tm_errorlog sm_tm_event sm_tm_event_name sm_tm_failure_message sm_tm_handling sm_tm_inquire sm_tm_iset sm_tm_msg_count_error sm_tm_msg_emsg sm_tm_msg_error sm_tm_old_bi_context sm_tm_pcopy sm_tm_pinquire sm_tm_pop_model_event sm_tm_pset sm_tm_push_model_event sm_tmpnam sm_tp_exec sm_tp_free_arg_buf sm_tp_gen_insert sm_tp_gen_sel_return sm_tp_gen_sel_where sm_tp_gen_val_link sm_tp_gen_val_return sm_tp_get_svc_alias sm_tp_get_tux_callid sm_translatecoords sm_tst_all_mdts
+
+syn keyword     jamLibFunc9     sm_udtime sm_ungetkey sm_unload_screen sm_unsvscreen sm_upd_select sm_validate sm_n_validate sm_vinit sm_n_vinit sm_wcount sm_wdeselect sm_web_get_cookie sm_web_invoke_url sm_web_log_error sm_web_save_global sm_web_set_cookie sm_web_unsave_all_globals sm_web_unsave_global sm_mw_widget sm_mwe_widget sm_mwn_widget sm_xm_widget sm_xme_widget sm_xmn_widget sm_win_shrink sm_d_window sm_d_at_cur sm_l_window sm_l_at_cur sm_r_window sm_r_at_cur sm_winsize sm_wrotate sm_wselect sm_n_wselect sm_ww_length sm_n_ww_length sm_ww_read sm_n_ww_read sm_ww_write sm_n_ww_write sm_xlate_table sm_xm_get_base_window sm_xm_get_display
+
+syn keyword     jamVariable1    SM_SCCS_ID SM_ENTERTERM SM_MALLOC SM_CANCEL SM_BADTERM SM_FNUM SM_DZERO SM_EXPONENT SM_INVDATE SM_MATHERR SM_FRMDATA SM_NOFORM SM_FRMERR SM_BADKEY SM_DUPKEY SM_ERROR SM_SP1 SM_SP2 SM_RENTRY SM_MUSTFILL SM_AFOVRFLW SM_TOO_FEW_DIGITS  SM_CKDIGIT SM_HITANY SM_NOHELP SM_MAXHELP SM_OUTRANGE SM_ENTERTERM1 SM_SYSDATE SM_DATFRM SM_DATCLR SM_DATINV SM_KSDATA SM_KSERR SM_KSNONE SM_KSMORE SM_DAYA1 SM_DAYA2 SM_DAYA3 SM_DAYA4 SM_DAYA5 SM_DAYA6 SM_DAYA7 SM_DAYL1 SM_DAYL2 SM_DAYL3 SM_DAYL4 SM_DAYL5 SM_DAYL6 SM_DAYL7 SM_MNSCR_LOAD SM_MENU_INSTALL SM_INSTDEFSCRL SM_INSTSCROLL SM_MOREDATA SM_READY SM_WAIT SM_YES SM_NO SM_NOTEMP SM_FRMHELP SM_FILVER SM_ONLYONE SM_WMSMOVE SM_WMSSIZE SM_WMSOFF SM_LPRINT SM_FMODE SM_NOFILE SM_NOSECTN SM_FFORMAT SM_FREAD SM_RX1 SM_RX2 SM_RX3 SM_TABLOOK SM_MISKET SM_ILLKET SM_ILLBRA SM_MISDBLKET SM_ILLDBLKET SM_ILLDBLBRA SM_ILL_RIGHT SM_ILLELSE SM_NUMBER SM_EOT SM_BREAK SM_NOARGS SM_BIGVAR SM_EXCESS SM_EOL SM_FILEIO SM_FOR SM_RCURLY SM_NONAME SM_1JPL_ERR SM_2JPL_ERR SM_3JPL_ERR
+
+syn keyword     jamVariable2    SM_JPLATCH SM_FORMAT SM_DESTINATION SM_ORAND SM_ORATOR SM_ILL_LEFT SM_MISSPARENS SM_ILLCLOSE_COMM SM_FUNCTION SM_EQUALS SM_MISMATCH SM_QUOTE SM_SYNTAX SM_NEXT SM_VERB_UNKNOWN SM_JPLFORM SM_NOT_LOADED SM_GA_FLG SM_GA_CHAR SM_GA_ARG SM_GA_DIG SM_NOFUNC SM_BADPROTO SM_JPLPUBLIC SM_NOCOMPILE SM_NULLEDIT SM_RP_NULL SM_DBI_NOT_INST SM_NOTJY SM_MAXLIB SM_FL_FLLIB SM_TPI_NOT_INST SM_RW_NOT_INST SM_MONA1 SM_MONA2 SM_MONA3 SM_MONA4 SM_MONA5 SM_MONA6 SM_MONA7 SM_MONA8 SM_MONA9 SM_MONA10 SM_MONA11 SM_MONA12 SM_MONL1 SM_MONL2 SM_MONL3 SM_MONL4 SM_MONL5 SM_MONL6 SM_MONL7 SM_MONL8 SM_MONL9 SM_MONL10 SM_MONL11 SM_MONL12 SM_AM SM_PM SM_0DEF_DTIME SM_1DEF_DTIME SM_2DEF_DTIME SM_3DEF_DTIME SM_4DEF_DTIME SM_5DEF_DTIME SM_6DEF_DTIME SM_7DEF_DTIME SM_8DEF_DTIME SM_9DEF_DTIME SM_CALC_DATE SM_BAD_DIGIT SM_BAD_YN SM_BAD_ALPHA SM_BAD_NUM SM_BAD_ALPHNUM SM_DECIMAL SM_1STATS SM_VERNO SM_DIG_ERR SM_YN_ERR SM_LET_ERR SM_NUM_ERR SM_ANUM_ERR SM_REXP_ERR SM_POSN_ERR SM_FBX_OPEN SM_FBX_WINDOW SM_FBX_SIBLING SM_OPENDIR
+
+syn keyword     jamVariable3    SM_GETFILES SM_CHDIR SM_GETCWD SM_UNCLOSED_COMM SM_MB_OKLABEL SM_MB_CANCELLABEL SM_MB_YESLABEL SM_MB_NOLABEL SM_MB_RETRYLABEL SM_MB_IGNORELABEL SM_MB_ABORTLABEL SM_MB_HELPLABEL SM_MB_STOP SM_MB_QUESTION SM_MB_WARNING SM_MB_INFORMATION SM_MB_YESALLLABEL SM_0MN_CURRDEF SM_1MN_CURRDEF SM_2MN_CURRDEF SM_0DEF_CURR SM_1DEF_CURR SM_2DEF_CURR SM_3DEF_CURR SM_4DEF_CURR SM_5DEF_CURR SM_6DEF_CURR SM_7DEF_CURR SM_8DEF_CURR SM_9DEF_CURR SM_SEND_SYNTAX SM_SEND_ITEM SM_SEND_INVALID_BUNDLE SM_RECEIVE_SYNTAX SM_RECEIVE_ITEM_NUMBER SM_RECEIVE_OVERFLOW SM_RECEIVE_ITEM SM_SYNCH_RECEIVE SM_EXEC_FAIL SM_DYNA_HELP_NOT_AVAIL SM_DLL_LOAD_ERR SM_DLL_UNRESOLVED SM_DLL_VERSION_ERR SM_DLL_OPTION_ERR SM_DEMOERR SM_MB_OKALLLABEL SM_MB_NOALLLABEL SM_BADPROP SM_BETWEEN SM_ATLEAST SM_ATMOST SM_PR_ERROR SM_PR_OBJID SM_PR_OBJECT SM_PR_ITEM SM_PR_PROP SM_PR_PROP_ITEM SM_PR_PROP_VAL SM_PR_CONVERT SM_PR_OBJ_TYPE SM_PR_RANGE SM_PR_NO_SET SM_PR_BYND_SCRN SM_PR_WW_SCROLL SM_PR_NO_SYNC SM_PR_TOO_BIG SM_PR_BAD_MASK SM_EXEC_MEM_ERR
+
+syn keyword     jamVariable4    SM_EXEC_NO_PROG SM_PR_NO_KEYSTRUCT SM_REOPEN_AS_SLIB SM_REOPEN_THE_SLIB SM_ERRLIB SM_WARNLIB SM_LIB_DOWNGRADE SM_OLDER SM_NEWER SM_UPGRADE SM_LIB_READONLY SM_LOPEN_ERR SM_LOPEN_WARN SM_MLOPEN_CREAT SM_MLOPEN_INIT SM_LIB_ERR SM_LIB_ISOLATE SM_LIB_NO_ERR SM_LIB_REC_ERR SM_LIB_FATAL_ERR SM_LIB_LERR_FILE SM_LIB_LERR_NOTLIB SM_LIB_LERR_BADVERS SM_LIB_LERR_FORMAT SM_LIB_LERR_BADCM SM_LIB_LERR_LOCK SM_LIB_LERR_RESERVED SM_LIB_LERR_READONLY SM_LIB_LERR_NOENTRY SM_LIB_LERR_BUSY SM_LIB_LERR_ROVERS SM_LIB_LERR_DEFAULT SM_LIB_BADCM SM_LIB_LERR_NEW SM_STANDALONE_MODE SM_FEATURE_RESTRICT FM_CH_LOST FM_JPL_PROMPT FM_YR4 FM_YR2 FM_MON FM_MON2 FM_DATE FM_DATE2 FM_HOUR FM_HOUR2 FM_MIN FM_MIN2 FM_SEC FM_SEC2 FM_YRDAY FM_AMPM FM_DAYA FM_DAYL FM_MONA FM_MONL FM_0MN_DEF_DT FM_1MN_DEF_DT FM_2MN_DEF_DT FM_DAY JM_QTERMINATE JM_HITSPACE JM_HITACK JM_NOJWIN UT_MEMERR UT_P_OPT UT_V_OPT UT_E_BINOPT UT_NO_INPUT UT_SECLONG UT_1FNAME UT_SLINE UT_FILE UT_ERROR UT_WARNING UT_MISSEQ UT_VOPT UT_M2_DESCR
+
+syn keyword     jamVariable5    UT_M2_PROGNAME UT_M2_USAGE UT_M2_O_OPT UT_M2_COM UT_M2_BADTAG UT_M2_MSSQUOT UT_M2_AFTRQUOT UT_M2_DUPSECT UT_M2_BADUCLSS UT_M2_USECPRFX UT_M2_MPTYUSCT UT_M2_DUPMSGTG UT_M2_TOOLONG UT_M2_LONG UT_K2_DESCR UT_K2_PROGNAME UT_K2_USAGE UT_K2_MNEM UT_K2_NKEYDEF UT_K2_DUPKEY UT_K2_NOTFOUND UT_K2_1FNAME UT_K2_VOPT UT_K2_EXCHAR UT_V2_DESCR UT_V2_PROGNAME UT_V2_USAGE UT_V2_SLINE UT_V2_SEQUAL UT_V2_SVARNAME UT_V2_SNAME UT_V2_VOPT UT_V2_1REQ UT_CB_DESCR UT_CB_PROGNAME UT_CB_USAGE UT_CB_VOPT UT_CB_MIEXT UT_CB_AEXT UT_CB_UNKNOWN UT_CB_ISCHEME UT_CB_BKFGS UT_CB_ABGS UT_CB_REC UT_CB_GUI UT_CB_CONT UT_CB_CONTFG UT_CB_AFILE UT_CB_LEFT_QUOTE UT_CB_NO_EQUAL UT_CB_EXTRA_EQ UT_CB_BAD_LHS UT_CB_BAD_RHS UT_CB_BAD_QUOTED UT_CB_FILE UT_CB_FILE_LINE UT_CB_DUP_ALIAS UT_CB_LINE_LOOP UT_CB_BAD_STYLE UT_CB_DUP_STYLE UT_CB_NO_SECT UT_CB_DUP_SCHEME DM_ERROR DM_NODATABASE DM_NOTLOGGEDON DM_ALREADY_ON DM_ARGS_NEEDED DM_LOGON_DENIED DM_BAD_ARGS DM_BAD_CMD DM_NO_MORE_ROWS DM_ABORTED DM_NO_CURSOR DM_MANY_CURSORS DM_KEYWORD
+
+syn keyword     jamVariable6    DM_INVALID_DATE DM_COMMIT DM_ROLLBACK DM_PARSE_ERROR DM_BIND_COUNT DM_BIND_VAR DM_DESC_COL DM_FETCH DM_NO_NAME DM_END_OF_PROC DM_NOCONNECTION DM_NOTSUPPORTED DM_TRAN_PEND DM_NO_TRANSACTION DM_ALREADY_INIT DM_INIT_ERROR DM_MAX_DEPTH DM_NO_PARENT DM_NO_CHILD DM_MODALITY_NOT_FOUND DM_NATIVE_NO_SUPPORT DM_NATIVE_CANCEL DM_TM_ALREADY DM_TM_IN_PROGRESS DM_TM_CLOSE_ERROR DM_TM_BAD_MODE DM_TM_BAD_CLOSE_ACTION DM_TM_INTERNAL DM_TM_MODEL_INTERNAL DM_TM_NO_ROOT DM_TM_NO_TRANSACTION DM_TM_INITIAL_MODE DM_TM_PARENT_NAME DM_TM_BAD_MEMBER DM_TM_FLD_NAM_LEN DM_TM_NO_PARENT DM_TM_BAD_REQUEST DM_TM_CANNOT_GEN_SQL DM_TM_CANNOT_EXEC_SQL DM_TM_DBI_ERROR DM_TM_DISCARD_ALL DM_TM_DISCARD_LATEST DM_TM_CALL_ERROR DM_TM_CALL_TYPE DM_TM_HOOK_MODEL DM_TM_ROOT_NAME DM_TM_TV_INVALID DM_TM_COL_NOT_FOUND DM_TM_BAD_LINK DM_TM_HOOK_MODEL_ERROR DM_TM_ONE_ROW DM_TM_SOME_ROWS DM_TM_GENERAL DM_TM_NO_HOOK DM_TM_NOSET DM_TM_TBLNAME DM_TM_PRIMARY_KEY DM_TM_INCOMPLETE_KEY DM_TM_CMD_MODE DM_TM_NO_SUCH_CMD DM_TM_NO_SUCH_SCOPE
+
+syn keyword     jamVariable7    DM_TM_NO_SUCH_TV DM_TM_EVENT_LOOP DM_TM_UNSUPPORTED DM_TM_NO_MODEL DM_TM_SYNCH_SV DM_TM_WRONG_FORM  DM_TM_VC_FIELD DM_TM_VC_DATE DM_TM_VC_TYPE DM_TM_BAD_CONTINUE DM_JDB_OUT_OF_MEMORY DM_JDB_DUPTABLEALIAS DM_JDB_DUPCURSORNAME DM_JDB_NODB DM_JDB_BINDCOUNT DM_JDB_NO_MORE_ROWS DM_JDB_AMBIGUOUS_COLUMN_REF DM_JDB_UNRESOLVED_COLUMN_REF DM_JDB_TABLE_READ_WRITE_CONFLICT DM_JDB_SYNTAX_ERROR DM_JDB_DUP_COLUMN_ASSIGNMENT DM_JDB_NO_MSG_FILE DM_JDB_NO_MSG DM_JDB_NOT_IMPLEMENTED DM_JDB_AGGREGATE_NOT_ALLOWED DM_JDB_TYPE_MISMATCH DM_JDB_NO_CURRENT_ROW DM_JDB_DB_CORRUPT DM_JDB_BUF_OVERFLOW DM_JDB_FILE_IO_ERR DM_JDB_BAD_HANDLE DM_JDB_DUP_TNAME DM_JDB_INVALID_TABLE_OP DM_JDB_TABLE_NOT_FOUND DM_JDB_CONVERSION_FAILED DM_JDB_INVALID_COLUMN_LIST DM_JDB_TABLE_OPEN DM_JDB_BAD_INPUT DM_JDB_DATATYPE_OVERFLOW DM_JDB_DATABASE_EXISTS DM_JDB_DATABASE_OPEN DM_JDB_DUP_CNAME DM_JDB_TMPDATABASE_ERR DM_JDB_INVALID_VALUES_COUNT DM_JDB_INVALID_COLUMN_COUNT DM_JDB_MAX_RECLEN_EXCEEDED DM_JDB_END_OF_GROUP
+
+syn keyword     jamVariable8    TP_EXC_INVALID_CLIENT_COMMAND  TP_EXC_INVALID_CLIENT_OPTION  TP_EXC_INVALID_COMMAND TP_EXC_INVALID_COMMAND_SYNTAX TP_EXC_INVALID_CONNECTION TP_EXC_INVALID_CONTEXT TP_EXC_INVALID_FORWARD TP_EXC_INVALID_JAM_VARIABLE_REF  TP_EXC_INVALID_MONITOR_COMMAND TP_EXC_INVALID_MONITOR_OPTION TP_EXC_INVALID_OPTION TP_EXC_INVALID_OPTION_VALUE  TP_EXC_INVALID_SERVER_COMMAND TP_EXC_INVALID_SERVER_OPTION TP_EXC_INVALID_SERVICE TP_EXC_INVALID_TRANSACTION TP_EXC_JIF_ACCESS_FAILED TP_EXC_JIF_LOWER_VERSION TP_EXC_LOGFILE_ERROR TP_EXC_MONITOR_ERROR TP_EXC_NO_OUTSIDE_TRANSACTION TP_EXC_NO_OUTSTANDING_CALLS TP_EXC_NO_OUTSTANDING_MESSAGE TP_EXC_NO_SERVICES_ADVERTISED TP_EXC_NO_SIGNALS TP_EXC_NONTRANSACTIONAL_SERVICE TP_EXC_NONTRANSACTIONAL_ACTION TP_EXC_OUT_OF_MEMORY TP_EXC_POSTING_FAILED TP_EXC_PERMISSION_DENIED  TP_EXC_REQUEST_LIMIT TP_EXC_ROLLBACK_COMMITTED  TP_EXC_ROLLBACK_FAILED TP_EXC_SERVICE_FAILED TP_EXC_SERVICE_NOT_IN_JIF  TP_EXC_SERVICE_PROTOCOL_ERROR  TP_EXC_SUBSCRIPTION_LIMIT
+
+syn keyword     jamVariable9    TP_EXC_SUBSCRIPTION_MATCH TP_EXC_SVC_ADVERTISE_LIMIT TP_EXC_SVC_WORK_OUTSTANDING TP_EXC_SVCROUTINE_MISSING TP_EXC_SVRINIT_WORK_OUTSTANDING TP_EXC_TIMEOUT TP_EXC_TRANSACTION_LIMIT TP_EXC_UNLOAD_FAILED TP_EXC_UNSUPPORTED_BUFFER TP_EXC_UNSUPPORTED_BUF_W_SUBT TP_EXC_USER_ABORT TP_EXC_WORK_OUTSTANDING TP_EXC_XA_CLOSE_FAILED TP_EXC_XA_OPEN_FAILED TP_EXC_QUEUE_BAD_MSGID TP_EXC_QUEUE_BAD_NAMESPACE TP_EXC_QUEUE_BAD_QUEUE TP_EXC_QUEUE_CANT_START_TRAN TP_EXC_QUEUE_FULL TP_EXC_QUEUE_MSG_IN_USE TP_EXC_QUEUE_NO_MSG TP_EXC_QUEUE_NOT_IN_QSPACE TP_EXC_QUEUE_RSRC_NOT_OPEN TP_EXC_QUEUE_SPACE_NOT_IN_JIF TP_EXC_QUEUE_TRAN_ABORTED TP_EXC_QUEUE_TRAN_ABSENT TP_EXC_QUEUE_UNEXPECTED TP_EXC_DCE_LOGIN_REQUIRED TP_EXC_ENC_CELL_NAME_REQUIRED TP_EXC_ENC_CONN_INFO_DIFFS TP_EXC_ENC_SVC_REGISTRY_ERROR TP_INVALID_START_ROUTINE TP_JIF_NOT_FOUND TP_JIF_OPEN_ERROR TP_NO_JIF TP_NO_MONITORS_ERROR TP_NO_SESSIONS_ERROR TP_NO_START_ROUTINE TP_ADV_SERVICE TP_ADV_SERVICE_IN_GROUP  TP_PRE_SVCHDL_WINOPEN_FAILED
+
+syn keyword     jamVariable10   PV_YES PV_NO TRUE FALSE TM_TRAN_NAME
+
+" jamCommentGroup allows adding matches for special things in comments
+syn cluster	jamCommentGroup	contains=jamTodo
+
+" String and Character constants
+" Highlight special characters (those which have a backslash) differently
+syn match	jamSpecial	contained "\\\(x\x\+\|\o\{1,3}\|.\|$\)"
+if !exists("c_no_utf")
+  syn match	jamSpecial	contained "\\\(u\x\{4}\|U\x\{8}\)"
+endif
+if exists("c_no_cformat")
+  syn region	jamString		start=+L\="+ skip=+\\\\\|\\"+ end=+"+ contains=cSpecial
+else
+  syn match	jamFormat		"%\(\d\+\$\)\=[-+' #0*]*\(\d*\|\*\|\*\d\+\$\)\(\.\(\d*\|\*\|\*\d\+\$\)\)\=\([hlL]\|ll\)\=\([diuoxXfeEgGcCsSpn]\|\[\^\=.[^]]*\]\)" contained
+  syn match	jamFormat		"%%" contained
+  syn region	jamString		start=+L\="+ skip=+\\\\\|\\"+ end=+"+ contains=cSpecial,cFormat
+  hi link jamFormat jamSpecial
+endif
+syn match	jamCharacter	"L\='[^\\]'"
+syn match	jamCharacter	"L'[^']*'" contains=jamSpecial
+syn match	jamSpecialError	"L\='\\[^'\"?\\abfnrtv]'"
+syn match	jamSpecialCharacter "L\='\\['\"?\\abfnrtv]'"
+syn match	jamSpecialCharacter "L\='\\\o\{1,3}'"
+syn match	jamSpecialCharacter "'\\x\x\{1,2}'"
+syn match	jamSpecialCharacter "L'\\x\x\+'"
+
+"catch errors caused by wrong parenthesis and brackets
+syn cluster	jamParenGroup	contains=jamParenError,jamIncluded,jamSpecial,@jamCommentGroup,jamUserCont,jamUserLabel,jamBitField,jamCommentSkip,jamOctalZero,jamCppOut,jamCppOut2,jamCppSkip,jamFormat,jamNumber,jamFloat,jamOctal,jamOctalError,jamNumbersCom
+
+syn region	jamParen		transparent start='(' end=')' contains=ALLBUT,@jamParenGroup,jamErrInBracket
+syn match	jamParenError	"[\])]"
+syn match	jamErrInParen	contained "[\]{}]"
+syn region	jamBracket	transparent start='\[' end=']' contains=ALLBUT,@jamParenGroup,jamErrInParen
+syn match	jamErrInBracket	contained "[);{}]"
+
+"integer number, or floating point number without a dot and with "f".
+syn case ignore
+syn match	jamNumbers	transparent "\<\d\|\,\d" contains=jamNumber,jamFloat,jamOctalError,jamOctal
+" Same, but without octal error (for comments)
+syn match	jamNumbersCom	contained transparent "\<\d\|\,\d" contains=jamNumber,jamFloat,jamOctal
+syn match	jamNumber		contained "\d\+\(u\=l\{0,2}\|ll\=u\)\>"
+"hex number
+syn match	jamNumber		contained "0x\x\+\(u\=l\{0,2}\|ll\=u\)\>"
+" Flag the first zero of an octal number as something special
+syn match	jamOctal		contained "0\o\+\(u\=l\{0,2}\|ll\=u\)\>" contains=cOctalZero
+syn match	jamOctalZero	contained "\<0"
+syn match	jamFloat		contained "\d\+f"
+"floating point number, with dot, optional exponent
+syn match	jamFloat		contained "\d\+\,\d*\(e[-+]\=\d\+\)\=[fl]\="
+"floating point number, starting with a dot, optional exponent
+syn match	jamFloat		contained "\,\d\+\(e[-+]\=\d\+\)\=[fl]\=\>"
+"floating point number, without dot, with exponent
+syn match	jamFloat		contained "\d\+e[-+]\=\d\+[fl]\=\>"
+" flag an octal number with wrong digits
+syn match	jamOctalError	contained "0\o*[89]\d*"
+syn case match
+
+syntax match	jamOperator1	"\#\#"
+syntax match	jamOperator6	"/"
+syntax match	jamOperator2	"+"
+syntax match	jamOperator3	"*"
+syntax match	jamOperator4	"-"
+syntax match	jamOperator5	"|"
+syntax match	jamOperator6	"/"
+syntax match	jamOperator7	"&"
+syntax match	jamOperator8	":"
+syntax match	jamOperator9	"<"
+syntax match	jamOperator10	">"
+syntax match	jamOperator11	"!"
+syntax match	jamOperator12	"%"
+syntax match	jamOperator13	"^"
+syntax match	jamOperator14	"@"
+
+syntax match	jamCommentL	"//"
+
+if exists("jam_comment_strings")
+  " A comment can contain jamString, jamCharacter and jamNumber.
+  " But a "*/" inside a jamString in a jamComment DOES end the comment!  So we
+  " need to use a special type of jamString: jamCommentString, which also ends on
+  " "*/", and sees a "*" at the start of the line as comment again.
+  " Unfortunately this doesn't very well work for // type of comments :-(
+  syntax match	jamCommentSkip	contained "^\s*\*\($\|\s\+\)"
+  syntax region jamCommentString	contained start=+L\="+ skip=+\\\\\|\\"+ end=+"+ end=+\*/+me=s-1 contains=jamSpecial,jamCommentSkip
+  syntax region jamComment2String	contained start=+L\="+ skip=+\\\\\|\\"+ end=+"+ end="$" contains=jamSpecial
+  syntax region  jamCommentL	start="//" skip="\\$" end="$" keepend contains=@jamCommentGroup,jamComment2String,jamCharacter,jamNumbersCom,jamSpaceError
+  syntax region  jamCommentL2		  start="^#\|^\s\+\#" skip="\\$" end="$" keepend contains=@jamCommentGroup,jamComment2String,jamCharacter,jamNumbersCom,jamSpaceError
+  syntax region jamComment	start="/\*" end="\*/" contains=@jamCommentGroup,jamCommentString,jamCharacter,jamNumbersCom,jamSpaceError
+else
+  syn region	jamCommentL	start="//" skip="\\$" end="$" keepend contains=@jamCommentGroup,jamSpaceError
+  syn region	jamCommentL2      start="^\#\|^\s\+\#" skip="\\$" end="$" keepend contains=@jamCommentGroup,jamSpaceError
+  syn region	jamComment	start="/\*" end="\*/" contains=@jamCommentGroup,jamSpaceError
+endif
+
+" keep a // comment separately, it terminates a preproc. conditional
+syntax match	jamCommentError	"\*/"
+
+syntax match    jamOperator3Error   "*/"
+
+" Define the default highlighting.
+" For version 5.7 and earlier: only when not done already
+" For version 5.8 and later: only when an item doesn't have highlighting yet
+if version >= 508 || !exists("did_jam_syn_inits")
+  if version < 508
+    let did_jam_syn_inits = 1
+    command -nargs=+ HiLink hi link <args>
+  else
+    command -nargs=+ HiLink hi def link <args>
+  endif
+
+    HiLink jamCommentL		jamComment
+    HiLink jamCommentL2		jamComment
+    HiLink jamOperator3Error	jamError
+    HiLink jamConditional	Conditional
+    HiLink jamRepeat		Repeat
+    HiLink jamCharacter		Character
+    HiLink jamSpecialCharacter	jamSpecial
+    HiLink jamNumber		Number
+    HiLink jamParenError	jamError
+    HiLink jamErrInParen	jamError
+    HiLink jamErrInBracket	jamError
+    HiLink jamCommentError	jamError
+    HiLink jamSpaceError	jamError
+    HiLink jamSpecialError	jamError
+    HiLink jamOperator1		jamOperator
+    HiLink jamOperator2		jamOperator
+    HiLink jamOperator3		jamOperator
+    HiLink jamOperator4		jamOperator
+    HiLink jamOperator5		jamOperator
+    HiLink jamOperator6		jamOperator
+    HiLink jamOperator7		jamOperator
+    HiLink jamOperator8		jamOperator
+    HiLink jamOperator9		jamOperator
+    HiLink jamOperator10	jamOperator
+    HiLink jamOperator11	jamOperator
+    HiLink jamOperator12	jamOperator
+    HiLink jamOperator13	jamOperator
+    HiLink jamOperator14	jamOperator
+    HiLink jamError		Error
+    HiLink jamStatement		Statement
+    HiLink jamPreCondit		PreCondit
+    HiLink jamCommentError	jamError
+    HiLink jamCommentString	jamString
+    HiLink jamComment2String	jamString
+    HiLink jamCommentSkip	jamComment
+    HiLink jamString		String
+    HiLink jamComment		Comment
+    HiLink jamSpecial		SpecialChar
+    HiLink jamTodo		Todo
+    HiLink jamCppSkip		jamCppOut
+    HiLink jamCppOut2		jamCppOut
+    HiLink jamCppOut		Comment
+    HiLink jamDBState1		Identifier
+    HiLink jamDBState2		Identifier
+    HiLink jamSQLState1		jamSQL
+    HiLink jamSQLState2		jamSQL
+    HiLink jamLibFunc1		jamLibFunc
+    HiLink jamLibFunc2		jamLibFunc
+    HiLink jamLibFunc3		jamLibFunc
+    HiLink jamLibFunc4		jamLibFunc
+    HiLink jamLibFunc5		jamLibFunc
+    HiLink jamLibFunc6		jamLibFunc
+    HiLink jamLibFunc7		jamLibFunc
+    HiLink jamLibFunc8		jamLibFunc
+    HiLink jamLibFunc9		jamLibFunc
+    HiLink jamVariable1		jamVariablen
+    HiLink jamVariable2		jamVariablen
+    HiLink jamVariable3		jamVariablen
+    HiLink jamVariable4		jamVariablen
+    HiLink jamVariable5		jamVariablen
+    HiLink jamVariable6		jamVariablen
+    HiLink jamVariable7		jamVariablen
+    HiLink jamVariable8		jamVariablen
+    HiLink jamVariable9		jamVariablen
+    HiLink jamVariable10	jamVariablen
+    HiLink jamVariablen		Constant
+    HiLink jamSQL		Type
+    HiLink jamLibFunc		PreProc
+    HiLink jamOperator		Special
+
+    delcommand HiLink
+endif
+
+let b:current_syntax = "jam"
+
+" vim: ts=8
--- /dev/null
+++ b/lib/vimfiles/syntax/jargon.vim
@@ -1,0 +1,36 @@
+" Vim syntax file
+" Language:	Jargon File
+" Maintainer:	<rms@poczta.onet.pl>
+" Last Change:	2001 May 26
+"
+" For version 5.x: Clear all syntax items
+" For version 6.x: Quit when a syntax file was already loaded
+if version < 600
+	syntax clear
+elseif exists("b:current_syntax")
+	finish
+endif
+
+syn match jargonChaptTitle	/:[^:]*:/
+syn match jargonEmailAddr	/[^<@ ^I]*@[^ ^I>]*/
+syn match jargonUrl	 +\(http\|ftp\)://[^\t )"]*+
+syn match jargonMark	/{[^}]*}/
+
+" Define the default highlighting.
+" For version 5.7 and earlier: only when not done already
+" For version 5.8 and later: only when an item doesn't have highlighting yet
+if version >= 508 || !exists("did_jargon_syntax_inits")
+	if version < 508
+		let did_jargon_syntax_inits = 1
+		command -nargs=+ HiLink hi link <args>
+	else
+		command -nargs=+ HiLink hi def link <args>
+	endif
+	HiLink jargonChaptTitle	Title
+	HiLink jargonEmailAddr	 Comment
+	HiLink jargonUrl	 Comment
+	HiLink jargonMark	Label
+	delcommand HiLink
+endif
+
+let b:current_syntax = "jargon"
--- /dev/null
+++ b/lib/vimfiles/syntax/java.vim
@@ -1,0 +1,343 @@
+" Vim syntax file
+" Language:     Java
+" Maintainer:   Claudio Fleiner <claudio@fleiner.com>
+" URL:		http://www.fleiner.com/vim/syntax/java.vim
+" Last Change:  2006 Apr 30
+
+" Please check :help java.vim for comments on some of the options available.
+
+" Quit when a syntax file was already loaded
+if !exists("main_syntax")
+  if version < 600
+    syntax clear
+  elseif exists("b:current_syntax")
+    finish
+  endif
+  " we define it here so that included files can test for it
+  let main_syntax='java'
+endif
+
+" don't use standard HiLink, it will not work with included syntax files
+if version < 508
+  command! -nargs=+ JavaHiLink hi link <args>
+else
+  command! -nargs=+ JavaHiLink hi def link <args>
+endif
+
+" some characters that cannot be in a java program (outside a string)
+syn match javaError "[\\@`]"
+syn match javaError "<<<\|\.\.\|=>\|<>\|||=\|&&=\|[^-]->\|\*\/"
+syn match javaOK "\.\.\."
+
+" use separate name so that it can be deleted in javacc.vim
+syn match   javaError2 "#\|=<"
+JavaHiLink javaError2 javaError
+
+
+
+" keyword definitions
+syn keyword javaExternal	native package
+syn match javaExternal		"\<import\>\(\s\+static\>\)\?"
+syn keyword javaError		goto const
+syn keyword javaConditional	if else switch
+syn keyword javaRepeat		while for do
+syn keyword javaBoolean		true false
+syn keyword javaConstant	null
+syn keyword javaTypedef		this super
+syn keyword javaOperator	new instanceof
+syn keyword javaType		boolean char byte short int long float double
+syn keyword javaType		void
+syn keyword javaStatement	return
+syn keyword javaStorageClass	static synchronized transient volatile final strictfp serializable
+syn keyword javaExceptions	throw try catch finally
+syn keyword javaAssert		assert
+syn keyword javaMethodDecl	synchronized throws
+syn keyword javaClassDecl	extends implements interface
+" to differentiate the keyword class from MyClass.class we use a match here
+syn match   javaTypedef		"\.\s*\<class\>"ms=s+1
+syn keyword javaClassDecl	enum
+syn match   javaClassDecl	"^class\>"
+syn match   javaClassDecl	"[^.]\s*\<class\>"ms=s+1
+syn match   javaAnnotation      "@[_$a-zA-Z][_$a-zA-Z0-9_]*\>"
+syn match   javaClassDecl       "@interface\>"
+syn keyword javaBranch		break continue nextgroup=javaUserLabelRef skipwhite
+syn match   javaUserLabelRef	"\k\+" contained
+syn match   javaVarArg		"\.\.\."
+syn keyword javaScopeDecl	public protected private abstract
+
+if exists("java_highlight_java_lang_ids")
+  let java_highlight_all=1
+endif
+if exists("java_highlight_all")  || exists("java_highlight_java")  || exists("java_highlight_java_lang")
+  " java.lang.*
+  syn match javaLangClass "\<System\>"
+  syn keyword javaR_JavaLang NegativeArraySizeException ArrayStoreException IllegalStateException RuntimeException IndexOutOfBoundsException UnsupportedOperationException ArrayIndexOutOfBoundsException ArithmeticException ClassCastException EnumConstantNotPresentException StringIndexOutOfBoundsException IllegalArgumentException IllegalMonitorStateException IllegalThreadStateException NumberFormatException NullPointerException TypeNotPresentException SecurityException
+  syn cluster javaTop add=javaR_JavaLang
+  syn cluster javaClasses add=javaR_JavaLang
+  JavaHiLink javaR_JavaLang javaR_Java
+  syn keyword javaC_JavaLang Process RuntimePermission StringKeySet CharacterData01 Class ThreadLocal ThreadLocalMap CharacterData0E Package Character StringCoding Long ProcessImpl ProcessEnvironment Short AssertionStatusDirectives 1PackageInfoProxy UnicodeBlock InheritableThreadLocal AbstractStringBuilder StringEnvironment ClassLoader ConditionalSpecialCasing CharacterDataPrivateUse StringBuffer StringDecoder Entry StringEntry WrappedHook StringBuilder StrictMath State ThreadGroup Runtime CharacterData02 MethodArray Object CharacterDataUndefined Integer Gate Boolean Enum Variable Subset StringEncoder Void Terminator CharsetSD IntegerCache CharacterCache Byte CharsetSE Thread SystemClassLoaderAction CharacterDataLatin1 StringValues StackTraceElement Shutdown ShortCache String ConverterSD ByteCache Lock EnclosingMethodInfo Math Float Value Double SecurityManager LongCache ProcessBuilder StringEntrySet Compiler Number UNIXProcess ConverterSE ExternalData CaseInsensitiveComparator CharacterData00 NativeLibrary
+  syn cluster javaTop add=javaC_JavaLang
+  syn cluster javaClasses add=javaC_JavaLang
+  JavaHiLink javaC_JavaLang javaC_Java
+  syn keyword javaE_JavaLang IncompatibleClassChangeError InternalError UnknownError ClassCircularityError AssertionError ThreadDeath IllegalAccessError NoClassDefFoundError ClassFormatError UnsupportedClassVersionError NoSuchFieldError VerifyError ExceptionInInitializerError InstantiationError LinkageError NoSuchMethodError Error UnsatisfiedLinkError StackOverflowError AbstractMethodError VirtualMachineError OutOfMemoryError
+  syn cluster javaTop add=javaE_JavaLang
+  syn cluster javaClasses add=javaE_JavaLang
+  JavaHiLink javaE_JavaLang javaE_Java
+  syn keyword javaX_JavaLang CloneNotSupportedException Exception NoSuchMethodException IllegalAccessException NoSuchFieldException Throwable InterruptedException ClassNotFoundException InstantiationException
+  syn cluster javaTop add=javaX_JavaLang
+  syn cluster javaClasses add=javaX_JavaLang
+  JavaHiLink javaX_JavaLang javaX_Java
+
+  JavaHiLink javaR_Java javaR_
+  JavaHiLink javaC_Java javaC_
+  JavaHiLink javaE_Java javaE_
+  JavaHiLink javaX_Java javaX_
+  JavaHiLink javaX_		     javaExceptions
+  JavaHiLink javaR_		     javaExceptions
+  JavaHiLink javaE_		     javaExceptions
+  JavaHiLink javaC_		     javaConstant
+
+  syn keyword javaLangObject clone equals finalize getClass hashCode
+  syn keyword javaLangObject notify notifyAll toString wait
+  JavaHiLink javaLangObject		     javaConstant
+  syn cluster javaTop add=javaLangObject
+endif
+
+if filereadable(expand("<sfile>:p:h")."/javaid.vim")
+  source <sfile>:p:h/javaid.vim
+endif
+
+if exists("java_space_errors")
+  if !exists("java_no_trail_space_error")
+    syn match   javaSpaceError  "\s\+$"
+  endif
+  if !exists("java_no_tab_space_error")
+    syn match   javaSpaceError  " \+\t"me=e-1
+  endif
+endif
+
+syn region  javaLabelRegion     transparent matchgroup=javaLabel start="\<case\>" matchgroup=NONE end=":" contains=javaNumber,javaCharacter
+syn match   javaUserLabel       "^\s*[_$a-zA-Z][_$a-zA-Z0-9_]*\s*:"he=e-1 contains=javaLabel
+syn keyword javaLabel		default
+
+if !exists("java_allow_cpp_keywords")
+  syn keyword javaError auto delete extern friend inline redeclared
+  syn keyword javaError register signed sizeof struct template typedef union
+  syn keyword javaError unsigned operator
+endif
+
+" The following cluster contains all java groups except the contained ones
+syn cluster javaTop add=javaExternal,javaError,javaError,javaBranch,javaLabelRegion,javaLabel,javaConditional,javaRepeat,javaBoolean,javaConstant,javaTypedef,javaOperator,javaType,javaType,javaStatement,javaStorageClass,javaAssert,javaExceptions,javaMethodDecl,javaClassDecl,javaClassDecl,javaClassDecl,javaScopeDecl,javaError,javaError2,javaUserLabel,javaLangObject,javaAnnotation,javaVarArg
+
+
+" Comments
+syn keyword javaTodo		 contained TODO FIXME XXX
+if exists("java_comment_strings")
+  syn region  javaCommentString    contained start=+"+ end=+"+ end=+$+ end=+\*/+me=s-1,he=s-1 contains=javaSpecial,javaCommentStar,javaSpecialChar,@Spell
+  syn region  javaComment2String   contained start=+"+  end=+$\|"+  contains=javaSpecial,javaSpecialChar,@Spell
+  syn match   javaCommentCharacter contained "'\\[^']\{1,6\}'" contains=javaSpecialChar
+  syn match   javaCommentCharacter contained "'\\''" contains=javaSpecialChar
+  syn match   javaCommentCharacter contained "'[^\\]'"
+  syn cluster javaCommentSpecial add=javaCommentString,javaCommentCharacter,javaNumber
+  syn cluster javaCommentSpecial2 add=javaComment2String,javaCommentCharacter,javaNumber
+endif
+syn region  javaComment		 start="/\*"  end="\*/" contains=@javaCommentSpecial,javaTodo,@Spell
+syn match   javaCommentStar      contained "^\s*\*[^/]"me=e-1
+syn match   javaCommentStar      contained "^\s*\*$"
+syn match   javaLineComment      "//.*" contains=@javaCommentSpecial2,javaTodo,@Spell
+JavaHiLink javaCommentString javaString
+JavaHiLink javaComment2String javaString
+JavaHiLink javaCommentCharacter javaCharacter
+
+syn cluster javaTop add=javaComment,javaLineComment
+
+if !exists("java_ignore_javadoc") && main_syntax != 'jsp'
+  syntax case ignore
+  " syntax coloring for javadoc comments (HTML)
+  syntax include @javaHtml <sfile>:p:h/html.vim
+  unlet b:current_syntax
+  syn region  javaDocComment    start="/\*\*"  end="\*/" keepend contains=javaCommentTitle,@javaHtml,javaDocTags,javaDocSeeTag,javaTodo,@Spell
+  syn region  javaCommentTitle  contained matchgroup=javaDocComment start="/\*\*"   matchgroup=javaCommentTitle keepend end="\.$" end="\.[ \t\r<&]"me=e-1 end="[^{]@"me=s-2,he=s-1 end="\*/"me=s-1,he=s-1 contains=@javaHtml,javaCommentStar,javaTodo,@Spell,javaDocTags,javaDocSeeTag
+
+  syn region javaDocTags         contained start="{@\(link\|linkplain\|inherit[Dd]oc\|doc[rR]oot\|value\)" end="}"
+  syn match  javaDocTags         contained "@\(param\|exception\|throws\|since\)\s\+\S\+" contains=javaDocParam
+  syn match  javaDocParam        contained "\s\S\+"
+  syn match  javaDocTags         contained "@\(version\|author\|return\|deprecated\|serial\|serialField\|serialData\)\>"
+  syn region javaDocSeeTag       contained matchgroup=javaDocTags start="@see\s\+" matchgroup=NONE end="\_."re=e-1 contains=javaDocSeeTagParam
+  syn match  javaDocSeeTagParam  contained @"\_[^"]\+"\|<a\s\+\_.\{-}</a>\|\(\k\|\.\)*\(#\k\+\((\_[^)]\+)\)\=\)\=@ extend
+  syntax case match
+endif
+
+" match the special comment /**/
+syn match   javaComment		 "/\*\*/"
+
+" Strings and constants
+syn match   javaSpecialError     contained "\\."
+syn match   javaSpecialCharError contained "[^']"
+syn match   javaSpecialChar      contained "\\\([4-9]\d\|[0-3]\d\d\|[\"\\'ntbrf]\|u\x\{4\}\)"
+syn region  javaString		start=+"+ end=+"+ end=+$+ contains=javaSpecialChar,javaSpecialError,@Spell
+" next line disabled, it can cause a crash for a long line
+"syn match   javaStringError	  +"\([^"\\]\|\\.\)*$+
+syn match   javaCharacter	 "'[^']*'" contains=javaSpecialChar,javaSpecialCharError
+syn match   javaCharacter	 "'\\''" contains=javaSpecialChar
+syn match   javaCharacter	 "'[^\\]'"
+syn match   javaNumber		 "\<\(0[0-7]*\|0[xX]\x\+\|\d\+\)[lL]\=\>"
+syn match   javaNumber		 "\(\<\d\+\.\d*\|\.\d\+\)\([eE][-+]\=\d\+\)\=[fFdD]\="
+syn match   javaNumber		 "\<\d\+[eE][-+]\=\d\+[fFdD]\=\>"
+syn match   javaNumber		 "\<\d\+\([eE][-+]\=\d\+\)\=[fFdD]\>"
+
+" unicode characters
+syn match   javaSpecial "\\u\d\{4\}"
+
+syn cluster javaTop add=javaString,javaCharacter,javaNumber,javaSpecial,javaStringError
+
+if exists("java_highlight_functions")
+  if java_highlight_functions == "indent"
+    syn match  javaFuncDef "^\(\t\| \{8\}\)[_$a-zA-Z][_$a-zA-Z0-9_. \[\]]*([^-+*/()]*)" contains=javaScopeDecl,javaType,javaStorageClass,@javaClasses
+    syn region javaFuncDef start=+^\(\t\| \{8\}\)[$_a-zA-Z][$_a-zA-Z0-9_. \[\]]*([^-+*/()]*,\s*+ end=+)+ contains=javaScopeDecl,javaType,javaStorageClass,@javaClasses
+    syn match  javaFuncDef "^  [$_a-zA-Z][$_a-zA-Z0-9_. \[\]]*([^-+*/()]*)" contains=javaScopeDecl,javaType,javaStorageClass,@javaClasses
+    syn region javaFuncDef start=+^  [$_a-zA-Z][$_a-zA-Z0-9_. \[\]]*([^-+*/()]*,\s*+ end=+)+ contains=javaScopeDecl,javaType,javaStorageClass,@javaClasses
+  else
+    " This line catches method declarations at any indentation>0, but it assumes
+    " two things:
+    "   1. class names are always capitalized (ie: Button)
+    "   2. method names are never capitalized (except constructors, of course)
+    syn region javaFuncDef start=+^\s\+\(\(public\|protected\|private\|static\|abstract\|final\|native\|synchronized\)\s\+\)*\(\(void\|boolean\|char\|byte\|short\|int\|long\|float\|double\|\([A-Za-z_][A-Za-z0-9_$]*\.\)*[A-Z][A-Za-z0-9_$]*\)\(<[^>]*>\)\=\(\[\]\)*\s\+[a-z][A-Za-z0-9_$]*\|[A-Z][A-Za-z0-9_$]*\)\s*([^0-9]+ end=+)+ contains=javaScopeDecl,javaType,javaStorageClass,javaComment,javaLineComment,@javaClasses
+  endif
+  syn match  javaBraces  "[{}]"
+  syn cluster javaTop add=javaFuncDef,javaBraces
+endif
+
+if exists("java_highlight_debug")
+
+  " Strings and constants
+  syn match   javaDebugSpecial		contained "\\\d\d\d\|\\."
+  syn region  javaDebugString		contained start=+"+  end=+"+  contains=javaDebugSpecial
+  syn match   javaDebugStringError      +"\([^"\\]\|\\.\)*$+
+  syn match   javaDebugCharacter	contained "'[^\\]'"
+  syn match   javaDebugSpecialCharacter contained "'\\.'"
+  syn match   javaDebugSpecialCharacter contained "'\\''"
+  syn match   javaDebugNumber		contained "\<\(0[0-7]*\|0[xX]\x\+\|\d\+\)[lL]\=\>"
+  syn match   javaDebugNumber		contained "\(\<\d\+\.\d*\|\.\d\+\)\([eE][-+]\=\d\+\)\=[fFdD]\="
+  syn match   javaDebugNumber		contained "\<\d\+[eE][-+]\=\d\+[fFdD]\=\>"
+  syn match   javaDebugNumber		contained "\<\d\+\([eE][-+]\=\d\+\)\=[fFdD]\>"
+  syn keyword javaDebugBoolean		contained true false
+  syn keyword javaDebugType		contained null this super
+  syn region javaDebugParen  start=+(+ end=+)+ contained contains=javaDebug.*,javaDebugParen
+
+  " to make this work you must define the highlighting for these groups
+  syn match javaDebug "\<System\.\(out\|err\)\.print\(ln\)*\s*("me=e-1 contains=javaDebug.* nextgroup=javaDebugParen
+  syn match javaDebug "\<p\s*("me=e-1 contains=javaDebug.* nextgroup=javaDebugParen
+  syn match javaDebug "[A-Za-z][a-zA-Z0-9_]*\.printStackTrace\s*("me=e-1 contains=javaDebug.* nextgroup=javaDebugParen
+  syn match javaDebug "\<trace[SL]\=\s*("me=e-1 contains=javaDebug.* nextgroup=javaDebugParen
+
+  syn cluster javaTop add=javaDebug
+
+  if version >= 508 || !exists("did_c_syn_inits")
+    JavaHiLink javaDebug		 Debug
+    JavaHiLink javaDebugString		 DebugString
+    JavaHiLink javaDebugStringError	 javaError
+    JavaHiLink javaDebugType		 DebugType
+    JavaHiLink javaDebugBoolean		 DebugBoolean
+    JavaHiLink javaDebugNumber		 Debug
+    JavaHiLink javaDebugSpecial		 DebugSpecial
+    JavaHiLink javaDebugSpecialCharacter DebugSpecial
+    JavaHiLink javaDebugCharacter	 DebugString
+    JavaHiLink javaDebugParen		 Debug
+
+    JavaHiLink DebugString		 String
+    JavaHiLink DebugSpecial		 Special
+    JavaHiLink DebugBoolean		 Boolean
+    JavaHiLink DebugType		 Type
+  endif
+endif
+
+if exists("java_mark_braces_in_parens_as_errors")
+  syn match javaInParen		 contained "[{}]"
+  JavaHiLink javaInParen	javaError
+  syn cluster javaTop add=javaInParen
+endif
+
+" catch errors caused by wrong parenthesis
+syn region  javaParenT  transparent matchgroup=javaParen  start="("  end=")" contains=@javaTop,javaParenT1
+syn region  javaParenT1 transparent matchgroup=javaParen1 start="(" end=")" contains=@javaTop,javaParenT2 contained
+syn region  javaParenT2 transparent matchgroup=javaParen2 start="(" end=")" contains=@javaTop,javaParenT  contained
+syn match   javaParenError       ")"
+" catch errors caused by wrong square parenthesis
+syn region  javaParenT  transparent matchgroup=javaParen  start="\["  end="\]" contains=@javaTop,javaParenT1
+syn region  javaParenT1 transparent matchgroup=javaParen1 start="\[" end="\]" contains=@javaTop,javaParenT2 contained
+syn region  javaParenT2 transparent matchgroup=javaParen2 start="\[" end="\]" contains=@javaTop,javaParenT  contained
+syn match   javaParenError       "\]"
+
+JavaHiLink javaParenError       javaError
+
+if !exists("java_minlines")
+  let java_minlines = 10
+endif
+exec "syn sync ccomment javaComment minlines=" . java_minlines
+
+" The default highlighting.
+if version >= 508 || !exists("did_java_syn_inits")
+  if version < 508
+    let did_java_syn_inits = 1
+  endif
+  JavaHiLink javaFuncDef		Function
+  JavaHiLink javaVarArg                 Function
+  JavaHiLink javaBraces			Function
+  JavaHiLink javaBranch			Conditional
+  JavaHiLink javaUserLabelRef		javaUserLabel
+  JavaHiLink javaLabel			Label
+  JavaHiLink javaUserLabel		Label
+  JavaHiLink javaConditional		Conditional
+  JavaHiLink javaRepeat			Repeat
+  JavaHiLink javaExceptions		Exception
+  JavaHiLink javaAssert			Statement
+  JavaHiLink javaStorageClass		StorageClass
+  JavaHiLink javaMethodDecl		javaStorageClass
+  JavaHiLink javaClassDecl		javaStorageClass
+  JavaHiLink javaScopeDecl		javaStorageClass
+  JavaHiLink javaBoolean		Boolean
+  JavaHiLink javaSpecial		Special
+  JavaHiLink javaSpecialError		Error
+  JavaHiLink javaSpecialCharError	Error
+  JavaHiLink javaString			String
+  JavaHiLink javaCharacter		Character
+  JavaHiLink javaSpecialChar		SpecialChar
+  JavaHiLink javaNumber			Number
+  JavaHiLink javaError			Error
+  JavaHiLink javaStringError		Error
+  JavaHiLink javaStatement		Statement
+  JavaHiLink javaOperator		Operator
+  JavaHiLink javaComment		Comment
+  JavaHiLink javaDocComment		Comment
+  JavaHiLink javaLineComment		Comment
+  JavaHiLink javaConstant		Constant
+  JavaHiLink javaTypedef		Typedef
+  JavaHiLink javaTodo			Todo
+  JavaHiLink javaAnnotation             PreProc
+
+  JavaHiLink javaCommentTitle		SpecialComment
+  JavaHiLink javaDocTags		Special
+  JavaHiLink javaDocParam		Function
+  JavaHiLink javaDocSeeTagParam		Function
+  JavaHiLink javaCommentStar		javaComment
+
+  JavaHiLink javaType			Type
+  JavaHiLink javaExternal		Include
+
+  JavaHiLink htmlComment		Special
+  JavaHiLink htmlCommentPart		Special
+  JavaHiLink javaSpaceError		Error
+endif
+
+delcommand JavaHiLink
+
+let b:current_syntax = "java"
+
+if main_syntax == 'java'
+  unlet main_syntax
+endif
+
+let b:spell_options="contained"
+
+" vim: ts=8
--- /dev/null
+++ b/lib/vimfiles/syntax/javacc.vim
@@ -1,0 +1,77 @@
+" Vim syntax file
+" Language:	JavaCC, a Java Compiler Compiler written by JavaSoft
+" Maintainer:	Claudio Fleiner <claudio@fleiner.com>
+" URL:		http://www.fleiner.com/vim/syntax/javacc.vim
+" Last Change:	2001 Jun 20
+
+" Uses java.vim, and adds a few special things for JavaCC Parser files.
+" Those files usually have the extension  *.jj
+
+" For version 5.x: Clear all syntax items
+" For version 6.x: Quit when a syntax file was already loaded
+if version < 600
+  syntax clear
+elseif exists("b:current_syntax")
+  finish
+endif
+
+" source the java.vim file
+if version < 600
+  source <sfile>:p:h/java.vim
+else
+  runtime! syntax/java.vim
+endif
+unlet b:current_syntax
+
+"remove catching errors caused by wrong parenthesis (does not work in javacc
+"files) (first define them in case they have not been defined in java)
+syn match	javaParen "--"
+syn match	javaParenError "--"
+syn match	javaInParen "--"
+syn match	javaError2 "--"
+syn clear	javaParen
+syn clear	javaParenError
+syn clear	javaInParen
+syn clear	javaError2
+
+" remove function definitions (they look different) (first define in
+" in case it was not defined in java.vim)
+"syn match javaFuncDef "--"
+syn clear javaFuncDef
+syn match javaFuncDef "[$_a-zA-Z][$_a-zA-Z0-9_. \[\]]*([^-+*/()]*)[ \t]*:" contains=javaType
+
+syn keyword javaccPackages options DEBUG_PARSER DEBUG_LOOKAHEAD DEBUG_TOKEN_MANAGER
+syn keyword javaccPackages COMMON_TOKEN_ACTION IGNORE_CASE CHOICE_AMBIGUITY_CHECK
+syn keyword javaccPackages OTHER_AMBIGUITY_CHECK STATIC LOOKAHEAD ERROR_REPORTING
+syn keyword javaccPackages USER_TOKEN_MANAGER  USER_CHAR_STREAM JAVA_UNICODE_ESCAPE
+syn keyword javaccPackages UNICODE_INPUT
+syn match javaccPackages "PARSER_END([^)]*)"
+syn match javaccPackages "PARSER_BEGIN([^)]*)"
+syn match javaccSpecToken "<EOF>"
+" the dot is necessary as otherwise it will be matched as a keyword.
+syn match javaccSpecToken ".LOOKAHEAD("ms=s+1,me=e-1
+syn match javaccToken "<[^> \t]*>"
+syn keyword javaccActionToken TOKEN SKIP MORE SPECIAL_TOKEN
+syn keyword javaccError DEBUG IGNORE_IN_BNF
+
+" Define the default highlighting.
+" For version 5.7 and earlier: only when not done already
+" For version 5.8 and later: only when an item doesn't have highlighting yet
+if version >= 508 || !exists("did_css_syn_inits")
+  if version < 508
+    let did_css_syn_inits = 1
+    command -nargs=+ HiLink hi link <args>
+  else
+    command -nargs=+ HiLink hi def link <args>
+  endif
+  HiLink javaccSpecToken Statement
+  HiLink javaccActionToken Type
+  HiLink javaccPackages javaScopeDecl
+  HiLink javaccToken String
+  HiLink javaccError Error
+  delcommand HiLink
+endif
+
+let b:current_syntax = "javacc"
+
+" vim: ts=8
--- /dev/null
+++ b/lib/vimfiles/syntax/javascript.vim
@@ -1,0 +1,137 @@
+" Vim syntax file
+" Language:	JavaScript
+" Maintainer:	Claudio Fleiner <claudio@fleiner.com>
+" Updaters:	Scott Shattuck (ss) <ss@technicalpursuit.com>
+" URL:		http://www.fleiner.com/vim/syntax/javascript.vim
+" Changes:	(ss) added keywords, reserved words, and other identifiers
+"		(ss) repaired several quoting and grouping glitches
+"		(ss) fixed regex parsing issue with multiple qualifiers [gi]
+"		(ss) additional factoring of keywords, globals, and members
+" Last Change:	2006 Jun 19
+
+" For version 5.x: Clear all syntax items
+" For version 6.x: Quit when a syntax file was already loaded
+" tuning parameters:
+" unlet javaScript_fold
+
+if !exists("main_syntax")
+  if version < 600
+    syntax clear
+  elseif exists("b:current_syntax")
+    finish
+  endif
+  let main_syntax = 'javascript'
+endif
+
+" Drop fold if it set but vim doesn't support it.
+if version < 600 && exists("javaScript_fold")
+  unlet javaScript_fold
+endif
+
+syn case ignore
+
+
+syn keyword javaScriptCommentTodo      TODO FIXME XXX TBD contained
+syn match   javaScriptLineComment      "\/\/.*" contains=@Spell,javaScriptCommentTodo
+syn match   javaScriptCommentSkip      "^[ \t]*\*\($\|[ \t]\+\)"
+syn region  javaScriptComment	       start="/\*"  end="\*/" contains=@Spell,javaScriptCommentTodo
+syn match   javaScriptSpecial	       "\\\d\d\d\|\\."
+syn region  javaScriptStringD	       start=+"+  skip=+\\\\\|\\"+  end=+"\|$+  contains=javaScriptSpecial,@htmlPreproc
+syn region  javaScriptStringS	       start=+'+  skip=+\\\\\|\\'+  end=+'\|$+  contains=javaScriptSpecial,@htmlPreproc
+
+syn match   javaScriptSpecialCharacter "'\\.'"
+syn match   javaScriptNumber	       "-\=\<\d\+L\=\>\|0[xX][0-9a-fA-F]\+\>"
+syn region  javaScriptRegexpString     start=+/[^/*]+me=e-1 skip=+\\\\\|\\/+ end=+/[gi]\{0,2\}\s*$+ end=+/[gi]\{0,2\}\s*[;.,)\]}]+me=e-1 contains=@htmlPreproc oneline
+
+syn keyword javaScriptConditional	if else switch
+syn keyword javaScriptRepeat		while for do in
+syn keyword javaScriptBranch		break continue
+syn keyword javaScriptOperator		new delete instanceof typeof
+syn keyword javaScriptType		Array Boolean Date Function Number Object String RegExp
+syn keyword javaScriptStatement		return with
+syn keyword javaScriptBoolean		true false
+syn keyword javaScriptNull		null undefined
+syn keyword javaScriptIdentifier	arguments this var
+syn keyword javaScriptLabel		case default
+syn keyword javaScriptException		try catch finally throw
+syn keyword javaScriptMessage		alert confirm prompt status
+syn keyword javaScriptGlobal		self window top parent
+syn keyword javaScriptMember		document event location 
+syn keyword javaScriptDeprecated	escape unescape
+syn keyword javaScriptReserved		abstract boolean byte char class const debugger double enum export extends final float goto implements import int interface long native package private protected public short static super synchronized throws transient volatile 
+
+if exists("javaScript_fold")
+    syn match	javaScriptFunction      "\<function\>"
+    syn region	javaScriptFunctionFold	start="\<function\>.*[^};]$" end="^\z1}.*$" transparent fold keepend
+
+    syn sync match javaScriptSync	grouphere javaScriptFunctionFold "\<function\>"
+    syn sync match javaScriptSync	grouphere NONE "^}"
+
+    setlocal foldmethod=syntax
+    setlocal foldtext=getline(v:foldstart)
+else
+    syn keyword	javaScriptFunction      function
+    syn match	javaScriptBraces	   "[{}\[\]]"
+    syn match	javaScriptParens	   "[()]"
+endif
+
+syn sync fromstart
+syn sync maxlines=100
+
+if main_syntax == "javascript"
+  syn sync ccomment javaScriptComment
+endif
+
+" Define the default highlighting.
+" For version 5.7 and earlier: only when not done already
+" For version 5.8 and later: only when an item doesn't have highlighting yet
+if version >= 508 || !exists("did_javascript_syn_inits")
+  if version < 508
+    let did_javascript_syn_inits = 1
+    command -nargs=+ HiLink hi link <args>
+  else
+    command -nargs=+ HiLink hi def link <args>
+  endif
+  HiLink javaScriptComment		Comment
+  HiLink javaScriptLineComment		Comment
+  HiLink javaScriptCommentTodo		Todo
+  HiLink javaScriptSpecial		Special
+  HiLink javaScriptStringS		String
+  HiLink javaScriptStringD		String
+  HiLink javaScriptCharacter		Character
+  HiLink javaScriptSpecialCharacter	javaScriptSpecial
+  HiLink javaScriptNumber		javaScriptValue
+  HiLink javaScriptConditional		Conditional
+  HiLink javaScriptRepeat		Repeat
+  HiLink javaScriptBranch		Conditional
+  HiLink javaScriptOperator		Operator
+  HiLink javaScriptType			Type
+  HiLink javaScriptStatement		Statement
+  HiLink javaScriptFunction		Function
+  HiLink javaScriptBraces		Function
+  HiLink javaScriptError		Error
+  HiLink javaScrParenError		javaScriptError
+  HiLink javaScriptNull			Keyword
+  HiLink javaScriptBoolean		Boolean
+  HiLink javaScriptRegexpString		String
+
+  HiLink javaScriptIdentifier		Identifier
+  HiLink javaScriptLabel		Label
+  HiLink javaScriptException		Exception
+  HiLink javaScriptMessage		Keyword
+  HiLink javaScriptGlobal		Keyword
+  HiLink javaScriptMember		Keyword
+  HiLink javaScriptDeprecated		Exception 
+  HiLink javaScriptReserved		Keyword
+  HiLink javaScriptDebug		Debug
+  HiLink javaScriptConstant		Label
+
+  delcommand HiLink
+endif
+
+let b:current_syntax = "javascript"
+if main_syntax == 'javascript'
+  unlet main_syntax
+endif
+
+" vim: ts=8
--- /dev/null
+++ b/lib/vimfiles/syntax/jess.vim
@@ -1,0 +1,161 @@
+" Vim syntax file
+" Language:	Jess
+" Maintainer:	Paul Baleme <pbaleme@mail.com>
+" Last change:	September 14, 2000
+" Based on lisp.vim by : Dr. Charles E. Campbell, Jr.
+
+" For version 5.x: Clear all syntax items
+" For version 6.x: Quit when a syntax file was already loaded
+if version < 600
+  syntax clear
+elseif exists("b:current_syntax")
+  finish
+endif
+
+if version < 600
+  set iskeyword=42,43,45,47-58,60-62,64-90,97-122,_
+else
+  setlocal iskeyword=42,43,45,47-58,60-62,64-90,97-122,_
+endif
+
+" Lists
+syn match	jessSymbol	![^()'`,"; \t]\+!	contained
+syn match	jessBarSymbol	!|..\{-}|!		contained
+syn region	jessList matchgroup=Delimiter start="(" skip="|.\{-}|" matchgroup=Delimiter end=")" contains=jessAtom,jessBQList,jessConcat,jessDeclaration,jessList,jessNumber,jessSymbol,jessSpecial,jessFunc,jessKey,jessAtomMark,jessString,jessComment,jessBarSymbol,jessAtomBarSymbol,jessVar
+syn region	jessBQList	matchgroup=PreProc   start="`("	skip="|.\{-}|" matchgroup=PreProc   end=")" contains=jessAtom,jessBQList,jessConcat,jessDeclaration,jessList,jessNumber,jessSpecial,jessSymbol,jessFunc,jessKey,jessVar,jessAtomMark,jessString,jessComment,jessBarSymbol,jessAtomBarSymbol
+
+" Atoms
+syn match	jessAtomMark	"'"
+syn match	jessAtom	"'("me=e-1	contains=jessAtomMark	nextgroup=jessAtomList
+syn match	jessAtom	"'[^ \t()]\+"	contains=jessAtomMark
+syn match	jessAtomBarSymbol	!'|..\{-}|!	contains=jessAtomMark
+syn region	jessAtom	start=+'"+	skip=+\\"+ end=+"+
+syn region	jessAtomList	matchgroup=Special start="("	skip="|.\{-}|" matchgroup=Special end=")"	contained contains=jessAtomList,jessAtomNmbr0,jessString,jessComment,jessAtomBarSymbol
+syn match	jessAtomNmbr	"\<[0-9]\+"			contained
+
+" Standard jess Functions and Macros
+syn keyword jessFunc    *   +   **	-   /   <   >   <=  >=  <>  =
+syn keyword jessFunc    long	    longp
+syn keyword jessFunc    abs	    agenda	      and
+syn keyword jessFunc    assert	    assert-string       bag
+syn keyword jessFunc    batch	    bind	      bit-and
+syn keyword jessFunc    bit-not	    bit-or	      bload
+syn keyword jessFunc    bsave	    build	      call
+syn keyword jessFunc    clear	    clear-storage       close
+syn keyword jessFunc    complement$     context	      count-query-results
+syn keyword jessFunc    create$
+syn keyword jessFunc    delete$	    div
+syn keyword jessFunc    do-backward-chaining	      e
+syn keyword jessFunc    engine	    eq	      eq*
+syn keyword jessFunc    eval	    evenp	      exit
+syn keyword jessFunc    exp	    explode$	      external-addressp
+syn keyword jessFunc    fact-slot-value facts	      fetch
+syn keyword jessFunc    first$	    float	      floatp
+syn keyword jessFunc    foreach	    format	      gensym*
+syn keyword jessFunc    get	    get-fact-duplication
+syn keyword jessFunc    get-member	    get-multithreaded-io
+syn keyword jessFunc    get-reset-globals	      get-salience-evaluation
+syn keyword jessFunc    halt	    if	      implode$
+syn keyword jessFunc    import	    insert$	      integer
+syn keyword jessFunc    integerp	    intersection$       jess-version-number
+syn keyword jessFunc    jess-version-string	      length$
+syn keyword jessFunc    lexemep	    list-function$      load-facts
+syn keyword jessFunc    load-function   load-package	      log
+syn keyword jessFunc    log10	    lowcase	      matches
+syn keyword jessFunc    max	    member$	      min
+syn keyword jessFunc    mod	    modify	      multifieldp
+syn keyword jessFunc    neq	    new	      not
+syn keyword jessFunc    nth$	    numberp	      oddp
+syn keyword jessFunc    open	    or	      pi
+syn keyword jessFunc    ppdeffunction   ppdefglobal	      ddpefrule
+syn keyword jessFunc    printout	    random	      read
+syn keyword jessFunc    readline	    replace$	      reset
+syn keyword jessFunc    rest$	    retract	      retract-string
+syn keyword jessFunc    return	    round	      rules
+syn keyword jessFunc    run	    run-query	      run-until-halt
+syn keyword jessFunc    save-facts	    set	      set-fact-duplication
+syn keyword jessFunc    set-factory     set-member	      set-multithreaded-io
+syn keyword jessFunc    set-node-index-hash	      set-reset-globals
+syn keyword jessFunc    set-salience-evaluation	      set-strategy
+syn keyword jessFunc    setgen	    show-deffacts       show-deftemplates
+syn keyword jessFunc    show-jess-listeners	      socket
+syn keyword jessFunc    sqrt	    store	      str-cat
+syn keyword jessFunc    str-compare     str-index	      str-length
+syn keyword jessFunc    stringp	    sub-string	      subseq$
+syn keyword jessFunc    subsetp	    sym-cat	      symbolp
+syn keyword jessFunc    system	    throw	      time
+syn keyword jessFunc    try	    undefadvice	      undefinstance
+syn keyword jessFunc    undefrule	    union$	      unwatch
+syn keyword jessFunc    upcase	    view	      watch
+syn keyword jessFunc    while
+syn match   jessFunc	"\<c[ad]\+r\>"
+
+" jess Keywords (modifiers)
+syn keyword jessKey	    defglobal	  deffunction	    defrule
+syn keyword jessKey	    deffacts
+syn keyword jessKey	    defadvice	  defclass	    definstance
+
+" Standard jess Variables
+syn region	jessVar	start="?"	end="[^a-zA-Z0-9]"me=e-1
+
+" Strings
+syn region	jessString	start=+"+	skip=+\\"+ end=+"+
+
+" Shared with Declarations, Macros, Functions
+"syn keyword	jessDeclaration
+
+syn match	jessNumber	"[0-9]\+"
+
+syn match	jessSpecial	"\*[a-zA-Z_][a-zA-Z_0-9-]*\*"
+syn match	jessSpecial	!#|[^()'`,"; \t]\+|#!
+syn match	jessSpecial	!#x[0-9a-fA-F]\+!
+syn match	jessSpecial	!#o[0-7]\+!
+syn match	jessSpecial	!#b[01]\+!
+syn match	jessSpecial	!#\\[ -\~]!
+syn match	jessSpecial	!#[':][^()'`,"; \t]\+!
+syn match	jessSpecial	!#([^()'`,"; \t]\+)!
+
+syn match	jessConcat	"\s\.\s"
+syntax match	jessParenError	")"
+
+" Comments
+syn match	jessComment	";.*$"
+
+" synchronization
+syn sync lines=100
+
+" Define the default highlighting.
+" For version 5.7 and earlier: only when not done already
+" For version 5.8 and later: only when an item doesn't have highlighting yet
+if version >= 508 || !exists("did_jess_syntax_inits")
+  if version < 508
+    let did_jess_syntax_inits = 1
+    command -nargs=+ HiLink hi link <args>
+  else
+    command -nargs=+ HiLink hi def link <args>
+  endif
+
+  HiLink jessAtomNmbr	jessNumber
+  HiLink jessAtomMark	jessMark
+
+  HiLink jessAtom		Identifier
+  HiLink jessAtomBarSymbol	Special
+  HiLink jessBarSymbol	Special
+  HiLink jessComment	Comment
+  HiLink jessConcat	Statement
+  HiLink jessDeclaration	Statement
+  HiLink jessFunc		Statement
+  HiLink jessKey		Type
+  HiLink jessMark		Delimiter
+  HiLink jessNumber	Number
+  HiLink jessParenError	Error
+  HiLink jessSpecial	Type
+  HiLink jessString	String
+  HiLink jessVar		Identifier
+
+  delcommand HiLink
+endif
+
+let b:current_syntax = "jess"
+
+" vim: ts=18
--- /dev/null
+++ b/lib/vimfiles/syntax/jgraph.vim
@@ -1,0 +1,58 @@
+" Vim syntax file
+" Language:	jgraph (graph plotting utility)
+" Maintainer:	Jonas Munsin jmunsin@iki.fi
+" Last Change:	2003 May 04
+" this syntax file is not yet complete
+
+
+" For version 5.x: Clear all syntax items
+" For version 6.x: Quit when a syntax file was already loaded
+if version < 600
+  syntax clear
+elseif exists("b:current_syntax")
+  finish
+endif
+
+syn case match
+
+" comments
+syn region	jgraphComment	start="(\* " end=" \*)"
+
+syn keyword	jgraphCmd	newcurve newgraph marktype
+syn keyword	jgraphType	xaxis yaxis
+
+syn keyword	jgraphType	circle box diamond triangle x cross ellipse
+syn keyword	jgraphType	xbar ybar text postscript eps none general
+
+syn keyword	jgraphType	solid dotted dashed longdash dotdash dodotdash
+syn keyword	jgraphType	dotdotdashdash pts
+
+"integer number, or floating point number without a dot. - or no -
+syn match  jgraphNumber		 "\<-\=\d\+\>"
+"floating point number, with dot - or no -
+syn match  jgraphNumber		 "\<-\=\d\+\.\d*\>"
+"floating point number, starting with a dot - or no -
+syn match  jgraphNumber		 "\-\=\.\d\+\>"
+
+
+" Define the default highlighting.
+" For version 5.7 and earlier: only when not done already
+" For version 5.8 and later: only when an item doesn't have highlighting yet
+if version >= 508 || !exists("did_jgraph_syn_inits")
+  if version < 508
+    let did_jgraph_syn_inits = 1
+    command -nargs=+ HiLink hi link <args>
+  else
+    command -nargs=+ HiLink hi def link <args>
+  endif
+
+  HiLink jgraphComment	Comment
+  HiLink jgraphCmd	Identifier
+  HiLink jgraphType	Type
+  HiLink jgraphNumber	Number
+
+  delcommand HiLink
+endif
+
+
+let b:current_syntax = "jgraph"
--- /dev/null
+++ b/lib/vimfiles/syntax/jproperties.vim
@@ -1,0 +1,148 @@
+" Vim syntax file
+" Language:	Java Properties resource file (*.properties[_*])
+" Maintainer:	Simon Baldwin <simonb@sco.com>
+" Last change:	26th Mar 2000
+
+" =============================================================================
+
+" Optional and tuning variables:
+
+" jproperties_lines
+" -----------------
+"   Set a value for the sync block that we use to find long continuation lines
+"   in properties; the value is already large - if you have larger continuation
+"   sets you may need to increase it further - if not, and you find editing is
+"   slow, reduce the value of jproperties_lines.
+if !exists("jproperties_lines")
+	let jproperties_lines = 256
+endif
+
+" jproperties_strict_syntax
+" -------------------------
+"   Most properties files assign values with "id=value" or "id:value".  But,
+"   strictly, the Java properties parser also allows "id value", "id", and
+"   even more bizarrely "=value", ":value", " value", and so on.  These latter
+"   ones, however, are rarely used, if ever, and handling them in the high-
+"   lighting can obscure errors in the more normal forms.  So, in practice
+"   we take special efforts to pick out only "id=value" and "id:value" forms
+"   by default.  If you want strict compliance, set jproperties_strict_syntax
+"   to non-zero (and good luck).
+if !exists("jproperties_strict_syntax")
+	let jproperties_strict_syntax = 0
+endif
+
+" jproperties_show_messages
+" -------------------------
+"   If this properties file contains messages for use with MessageFormat,
+"   setting a non-zero value will highlight them.  Messages are of the form
+"   "{...}".  Highlighting doesn't go to the pains of picking apart what is
+"   in the format itself - just the basics for now.
+if !exists("jproperties_show_messages")
+	let jproperties_show_messages = 0
+endif
+
+" =============================================================================
+
+" For version 5.x: Clear all syntax items
+" For version 6.x: Quit when a syntax file was already loaded
+if version < 600
+  syntax clear
+elseif exists("b:current_syntax")
+  finish
+endif
+
+" switch case sensitivity off
+syn case ignore
+
+" set the block
+exec "syn sync lines=" . jproperties_lines
+
+" switch between 'normal' and 'strict' syntax
+if jproperties_strict_syntax != 0
+
+	" an assignment is pretty much any non-empty line at this point,
+	" trying to not think about continuation lines
+	syn match   jpropertiesAssignment	"^\s*[^[:space:]]\+.*$" contains=jpropertiesIdentifier
+
+	" an identifier is anything not a space character, pretty much; it's
+	" followed by = or :, or space or tab.  Or end-of-line.
+	syn match   jpropertiesIdentifier	"[^=:[:space:]]*" contained nextgroup=jpropertiesDelimiter
+
+	" treat the delimiter specially to get colours right
+	syn match   jpropertiesDelimiter	"\s*[=:[:space:]]\s*" contained nextgroup=jpropertiesString
+
+	" catch the bizarre case of no identifier; a special case of delimiter
+	syn match   jpropertiesEmptyIdentifier	"^\s*[=:]\s*" nextgroup=jpropertiesString
+else
+
+	" here an assignment is id=value or id:value, and we conveniently
+	" ignore continuation lines for the present
+	syn match   jpropertiesAssignment	"^\s*[^=:[:space:]]\+\s*[=:].*$" contains=jpropertiesIdentifier
+
+	" an identifier is anything not a space character, pretty much; it's
+	" always followed by = or :, and we find it in an assignment
+	syn match   jpropertiesIdentifier	"[^=:[:space:]]\+" contained nextgroup=jpropertiesDelimiter
+
+	" treat the delimiter specially to get colours right; this time the
+	" delimiter must contain = or :
+	syn match   jpropertiesDelimiter	"\s*[=:]\s*" contained nextgroup=jpropertiesString
+endif
+
+" a definition is all up to the last non-\-terminated line; strictly, Java
+" properties tend to ignore leading whitespace on all lines of a multi-line
+" definition, but we don't look for that here (because it's a major hassle)
+syn region  jpropertiesString		start="" skip="\\$" end="$" contained contains=jpropertiesSpecialChar,jpropertiesError,jpropertiesSpecial
+
+" {...} is a Java Message formatter - add a minimal recognition of these
+" if required
+if jproperties_show_messages != 0
+	syn match   jpropertiesSpecial		"{[^}]*}\{-1,\}" contained
+	syn match   jpropertiesSpecial		"'{" contained
+	syn match   jpropertiesSpecial		"''" contained
+endif
+
+" \uABCD are unicode special characters
+syn match   jpropertiesSpecialChar	"\\u\x\{1,4}" contained
+
+" ...and \u not followed by a hex digit is an error, though the properties
+" file parser won't issue an error on it, just set something wacky like zero
+syn match   jpropertiesError		"\\u\X\{1,4}" contained
+syn match   jpropertiesError		"\\u$"me=e-1 contained
+
+" other things of note are the \t,r,n,\, and the \ preceding line end
+syn match   jpropertiesSpecial		"\\[trn\\]" contained
+syn match   jpropertiesSpecial		"\\\s" contained
+syn match   jpropertiesSpecial		"\\$" contained
+
+" comments begin with # or !, and persist to end of line; put here since
+" they may have been caught by patterns above us
+syn match   jpropertiesComment		"^\s*[#!].*$" contains=jpropertiesTODO
+syn keyword jpropertiesTodo		TODO FIXME XXX contained
+
+" Define the default highlighting.
+" For version 5.7 and earlier: only when not done already
+" For version 5.8 and later: only when an item doesn't have highlighting yet
+if version >= 508 || !exists("did_jproperties_syntax_inits")
+  if version < 508
+    let did_jproperties_syntax_inits = 1
+    command -nargs=+ HiLink hi link <args>
+  else
+    command -nargs=+ HiLink hi def link <args>
+  endif
+
+	HiLink jpropertiesComment	Comment
+	HiLink jpropertiesTodo		Todo
+	HiLink jpropertiesIdentifier	Identifier
+	HiLink jpropertiesString	String
+	HiLink jpropertiesExtendString	String
+	HiLink jpropertiesCharacter	Character
+	HiLink jpropertiesSpecial	Special
+	HiLink jpropertiesSpecialChar	SpecialChar
+	HiLink jpropertiesError	Error
+
+  delcommand HiLink
+endif
+
+let b:current_syntax = "jproperties"
+
+" vim:ts=8
--- /dev/null
+++ b/lib/vimfiles/syntax/jsp.vim
@@ -1,0 +1,84 @@
+" Vim syntax file
+" Language:	JSP (Java Server Pages)
+" Maintainer:	Rafael Garcia-Suarez <rgarciasuarez@free.fr>
+" URL:		http://rgarciasuarez.free.fr/vim/syntax/jsp.vim
+" Last change:	2004 Feb 02
+" Credits : Patch by Darren Greaves (recognizes <jsp:...> tags)
+"	    Patch by Thomas Kimpton (recognizes jspExpr inside HTML tags)
+
+" For version 5.x: Clear all syntax items
+" For version 6.x: Quit when a syntax file was already loaded
+if version < 600
+  syntax clear
+elseif exists("b:current_syntax")
+  finish
+endif
+
+if !exists("main_syntax")
+  let main_syntax = 'jsp'
+endif
+
+" Source HTML syntax
+if version < 600
+  source <sfile>:p:h/html.vim
+else
+  runtime! syntax/html.vim
+endif
+unlet b:current_syntax
+
+" Next syntax items are case-sensitive
+syn case match
+
+" Include Java syntax
+syn include @jspJava <sfile>:p:h/java.vim
+
+syn region jspScriptlet matchgroup=jspTag start=/<%/  keepend end=/%>/ contains=@jspJava
+syn region jspComment			  start=/<%--/	      end=/--%>/
+syn region jspDecl	matchgroup=jspTag start=/<%!/ keepend end=/%>/ contains=@jspJava
+syn region jspExpr	matchgroup=jspTag start=/<%=/ keepend end=/%>/ contains=@jspJava
+syn region jspDirective			  start=/<%@/	      end=/%>/ contains=htmlString,jspDirName,jspDirArg
+
+syn keyword jspDirName contained include page taglib
+syn keyword jspDirArg contained file uri prefix language extends import session buffer autoFlush
+syn keyword jspDirArg contained isThreadSafe info errorPage contentType isErrorPage
+syn region jspCommand			  start=/<jsp:/ start=/<\/jsp:/ keepend end=/>/ end=/\/>/ contains=htmlString,jspCommandName,jspCommandArg
+syn keyword jspCommandName contained include forward getProperty plugin setProperty useBean param params fallback
+syn keyword jspCommandArg contained id scope class type beanName page flush name value property
+syn keyword jspCommandArg contained code codebase name archive align height
+syn keyword jspCommandArg contained width hspace vspace jreversion nspluginurl iepluginurl
+
+" Redefine htmlTag so that it can contain jspExpr
+syn region htmlTag start=+<[^/%]+ end=+>+ contains=htmlTagN,htmlString,htmlArg,htmlValue,htmlTagError,htmlEvent,htmlCssDefinition,@htmlPreproc,@htmlArgCluster,jspExpr
+
+" Define the default highlighting.
+" For version 5.7 and earlier: only when not done already
+" For version 5.8 and later: only when an item doesn't have highlighting yet
+if version >= 508 || !exists("did_jsp_syn_inits")
+  if version < 508
+    let did_jsp_syn_inits = 1
+    command -nargs=+ HiLink hi link <args>
+  else
+    command -nargs=+ HiLink hi def link <args>
+  endif
+  " java.vim has redefined htmlComment highlighting
+  HiLink htmlComment	 Comment
+  HiLink htmlCommentPart Comment
+  " Be consistent with html highlight settings
+  HiLink jspComment	 htmlComment
+  HiLink jspTag		 htmlTag
+  HiLink jspDirective	 jspTag
+  HiLink jspDirName	 htmlTagName
+  HiLink jspDirArg	 htmlArg
+  HiLink jspCommand	 jspTag
+  HiLink jspCommandName  htmlTagName
+  HiLink jspCommandArg	 htmlArg
+  delcommand HiLink
+endif
+
+if main_syntax == 'jsp'
+  unlet main_syntax
+endif
+
+let b:current_syntax = "jsp"
+
+" vim: ts=8
--- /dev/null
+++ b/lib/vimfiles/syntax/kconfig.vim
@@ -1,0 +1,736 @@
+" Vim syntax file
+" Maintainer:       Nikolai Weibull <now@bitwi.se>
+" Latest Revision:  2006-04-14
+
+if exists("b:current_syntax")
+  finish
+endif
+
+let s:cpo_save = &cpo
+set cpo&vim
+
+if exists("g:kconfig_syntax_heavy")
+
+syn match   kconfigBegin              '^' nextgroup=kconfigKeyword
+                                      \ skipwhite
+
+syn keyword kconfigTodo               contained TODO FIXME XXX NOTE
+
+syn match   kconfigComment            display '#.*$' contains=kconfigTodo
+
+syn keyword kconfigKeyword            config nextgroup=kconfigSymbol
+                                      \ skipwhite
+
+syn keyword kconfigKeyword            menuconfig nextgroup=kconfigSymbol
+                                      \ skipwhite
+
+syn keyword kconfigKeyword            comment menu mainmenu
+                                      \ nextgroup=kconfigKeywordPrompt
+                                      \ skipwhite
+
+syn keyword kconfigKeyword            choice
+                                      \ nextgroup=@kconfigConfigOptions
+                                      \ skipwhite skipnl
+
+syn keyword kconfigKeyword            endmenu endchoice
+
+syn keyword kconfigPreProc            source
+                                      \ nextgroup=kconfigPath
+                                      \ skipwhite
+
+" TODO: This is a hack.  The who .*Expr stuff should really be generated so
+" that we can reuse it for various nextgroups.
+syn keyword kconfigConditional        if endif
+                                      \ nextgroup=@kconfigConfigOptionIfExpr
+                                      \ skipwhite
+
+syn match   kconfigKeywordPrompt      '"[^"\\]*\%(\\.[^"\\]*\)*"'
+                                      \ contained
+                                      \ nextgroup=@kconfigConfigOptions
+                                      \ skipwhite skipnl
+
+syn match   kconfigPath               '"[^"\\]*\%(\\.[^"\\]*\)*"\|\S\+'
+                                      \ contained
+
+syn match   kconfigSymbol             '\<\k\+\>'
+                                      \ contained
+                                      \ nextgroup=@kconfigConfigOptions
+                                      \ skipwhite skipnl
+
+" FIXME: There is – probably – no reason to cluster these instead of just
+" defining them in the same group.
+syn cluster kconfigConfigOptions      contains=kconfigTypeDefinition,
+                                      \        kconfigInputPrompt,
+                                      \        kconfigDefaultValue,
+                                      \        kconfigDependencies,
+                                      \        kconfigReverseDependencies,
+                                      \        kconfigNumericalRanges,
+                                      \        kconfigHelpText,
+                                      \        kconfigDefBool,
+                                      \        kconfigOptional
+
+syn keyword kconfigTypeDefinition     bool boolean tristate string hex int
+                                      \ contained
+                                      \ nextgroup=kconfigTypeDefPrompt,
+                                      \           @kconfigConfigOptions
+                                      \ skipwhite skipnl
+
+syn match   kconfigTypeDefPrompt      '"[^"\\]*\%(\\.[^"\\]*\)*"'
+                                      \ contained
+                                      \ nextgroup=kconfigConfigOptionIf,
+                                      \           @kconfigConfigOptions
+                                      \ skipwhite skipnl
+
+syn match   kconfigTypeDefPrompt      "'[^'\\]*\%(\\.[^'\\]*\)*'"
+                                      \ contained
+                                      \ nextgroup=kconfigConfigOptionIf,
+                                      \           @kconfigConfigOptions
+                                      \ skipwhite skipnl
+
+syn keyword kconfigInputPrompt        prompt
+                                      \ contained
+                                      \ nextgroup=kconfigPromptPrompt
+                                      \ skipwhite
+
+syn match   kconfigPromptPrompt       '"[^"\\]*\%(\\.[^"\\]*\)*"'
+                                      \ contained
+                                      \ nextgroup=kconfigConfigOptionIf,
+                                      \           @kconfigConfigOptions
+                                      \ skipwhite skipnl
+
+syn match   kconfigPromptPrompt       "'[^'\\]*\%(\\.[^'\\]*\)*'"
+                                      \ contained
+                                      \ nextgroup=kconfigConfigOptionIf,
+                                      \           @kconfigConfigOptions
+                                      \ skipwhite skipnl
+
+syn keyword   kconfigDefaultValue     default
+                                      \ contained
+                                      \ nextgroup=@kconfigConfigOptionExpr
+                                      \ skipwhite
+
+syn match   kconfigDependencies       'depends on\|requires'
+                                      \ contained
+                                      \ nextgroup=@kconfigConfigOptionIfExpr
+                                      \ skipwhite
+
+syn keyword kconfigReverseDependencies select
+                                      \ contained
+                                      \ nextgroup=@kconfigRevDepSymbol
+                                      \ skipwhite
+
+syn cluster kconfigRevDepSymbol       contains=kconfigRevDepCSymbol,
+                                      \        kconfigRevDepNCSymbol
+
+syn match   kconfigRevDepCSymbol      '"[^"\\]*\%(\\.[^"\\]*\)*"'
+                                      \ contained
+                                      \ nextgroup=kconfigConfigOptionIf,
+                                      \           @kconfigConfigOptions
+                                      \ skipwhite skipnl
+
+syn match   kconfigRevDepCSymbol      "'[^'\\]*\%(\\.[^'\\]*\)*'"
+                                      \ contained
+                                      \ nextgroup=kconfigConfigOptionIf,
+                                      \           @kconfigConfigOptions
+                                      \ skipwhite skipnl
+
+syn match   kconfigRevDepNCSymbol     '\<\k\+\>'
+                                      \ contained
+                                      \ nextgroup=kconfigConfigOptionIf,
+                                      \           @kconfigConfigOptions
+                                      \ skipwhite skipnl
+
+syn keyword kconfigNumericalRanges    range
+                                      \ contained
+                                      \ nextgroup=@kconfigRangeSymbol
+                                      \ skipwhite
+
+syn cluster kconfigRangeSymbol        contains=kconfigRangeCSymbol,
+                                      \        kconfigRangeNCSymbol
+
+syn match   kconfigRangeCSymbol       '"[^"\\]*\%(\\.[^"\\]*\)*"'
+                                      \ contained
+                                      \ nextgroup=@kconfigRangeSymbol2
+                                      \ skipwhite skipnl
+
+syn match   kconfigRangeCSymbol       "'[^'\\]*\%(\\.[^'\\]*\)*'"
+                                      \ contained
+                                      \ nextgroup=@kconfigRangeSymbol2
+                                      \ skipwhite skipnl
+
+syn match   kconfigRangeNCSymbol      '\<\k\+\>'
+                                      \ contained
+                                      \ nextgroup=@kconfigRangeSymbol2
+                                      \ skipwhite skipnl
+
+syn cluster kconfigRangeSymbol2       contains=kconfigRangeCSymbol2,
+                                      \        kconfigRangeNCSymbol2
+
+syn match   kconfigRangeCSymbol2      "'[^'\\]*\%(\\.[^'\\]*\)*'"
+                                      \ contained
+                                      \ nextgroup=kconfigConfigOptionIf,
+                                      \           @kconfigConfigOptions
+                                      \ skipwhite skipnl
+
+syn match   kconfigRangeNCSymbol2     '\<\k\+\>'
+                                      \ contained
+                                      \ nextgroup=kconfigConfigOptionIf,
+                                      \           @kconfigConfigOptions
+                                      \ skipwhite skipnl
+
+syn region  kconfigHelpText           contained
+      \ matchgroup=kconfigConfigOption
+      \ start='\%(help\|---help---\)\ze\s*\n\z(\s\+\)'
+      \ skip='^$'
+      \ end='^\z1\@!'
+      \ nextgroup=@kconfigConfigOptions
+      \ skipwhite skipnl
+
+" XXX: Undocumented
+syn keyword kconfigDefBool            def_bool
+                                      \ contained
+                                      \ nextgroup=@kconfigDefBoolSymbol
+                                      \ skipwhite
+
+syn cluster kconfigDefBoolSymbol      contains=kconfigDefBoolCSymbol,
+                                      \        kconfigDefBoolNCSymbol
+
+syn match   kconfigDefBoolCSymbol     '"[^"\\]*\%(\\.[^"\\]*\)*"'
+                                      \ contained
+                                      \ nextgroup=kconfigConfigOptionIf,
+                                      \           @kconfigConfigOptions
+                                      \ skipwhite skipnl
+
+syn match   kconfigDefBoolCSymbol     "'[^'\\]*\%(\\.[^'\\]*\)*'"
+                                      \ contained
+                                      \ nextgroup=kconfigConfigOptionIf,
+                                      \           @kconfigConfigOptions
+                                      \ skipwhite skipnl
+
+syn match   kconfigDefBoolNCSymbol    '\<\k\+\>'
+                                      \ contained
+                                      \ nextgroup=kconfigConfigOptionIf,
+                                      \           @kconfigConfigOptions
+                                      \ skipwhite skipnl
+
+" XXX: This is actually only a valid option for “choice”, but treating it
+" specially would require a lot of extra groups.
+syn keyword kconfigOptional           optional
+                                      \ contained
+                                      \ nextgroup=@kconfigConfigOptions
+                                      \ skipwhite skipnl
+
+syn keyword kconfigConfigOptionIf     if
+                                      \ contained
+                                      \ nextgroup=@kconfigConfigOptionIfExpr
+                                      \ skipwhite
+
+syn cluster kconfigConfigOptionIfExpr contains=@kconfigConfOptIfExprSym,
+                                      \        kconfigConfOptIfExprNeg,
+                                      \        kconfigConfOptIfExprGroup
+
+syn cluster kconfigConfOptIfExprSym   contains=kconfigConfOptIfExprCSym,
+                                      \        kconfigConfOptIfExprNCSym
+
+syn match   kconfigConfOptIfExprCSym  '"[^"\\]*\%(\\.[^"\\]*\)*"'
+                                      \ contained
+                                      \ nextgroup=@kconfigConfigOptions,
+                                      \           kconfigConfOptIfExprAnd,
+                                      \           kconfigConfOptIfExprOr,
+                                      \           kconfigConfOptIfExprEq,
+                                      \           kconfigConfOptIfExprNEq
+                                      \ skipwhite skipnl
+
+syn match   kconfigConfOptIfExprCSym  "'[^'\\]*\%(\\.[^'\\]*\)*'"
+                                      \ contained
+                                      \ nextgroup=@kconfigConfigOptions,
+                                      \           kconfigConfOptIfExprAnd,
+                                      \           kconfigConfOptIfExprOr,
+                                      \           kconfigConfOptIfExprEq,
+                                      \           kconfigConfOptIfExprNEq
+                                      \ skipwhite skipnl
+
+syn match   kconfigConfOptIfExprNCSym '\<\k\+\>'
+                                      \ contained
+                                      \ nextgroup=@kconfigConfigOptions,
+                                      \           kconfigConfOptIfExprAnd,
+                                      \           kconfigConfOptIfExprOr,
+                                      \           kconfigConfOptIfExprEq,
+                                      \           kconfigConfOptIfExprNEq
+                                      \ skipwhite skipnl
+
+syn cluster kconfigConfOptIfExprSym2  contains=kconfigConfOptIfExprCSym2,
+                                      \        kconfigConfOptIfExprNCSym2
+
+syn match   kconfigConfOptIfExprEq    '='
+                                      \ contained
+                                      \ nextgroup=@kconfigConfOptIfExprSym2
+                                      \ skipwhite
+
+syn match   kconfigConfOptIfExprNEq   '!='
+                                      \ contained
+                                      \ nextgroup=@kconfigConfOptIfExprSym2
+                                      \ skipwhite
+
+syn match   kconfigConfOptIfExprCSym2 "'[^'\\]*\%(\\.[^'\\]*\)*'"
+                                      \ contained
+                                      \ nextgroup=@kconfigConfigOptions,
+                                      \           kconfigConfOptIfExprAnd,
+                                      \           kconfigConfOptIfExprOr
+                                      \ skipwhite skipnl
+
+syn match   kconfigConfOptIfExprNCSym2 '\<\k\+\>'
+                                      \ contained
+                                      \ nextgroup=@kconfigConfigOptions,
+                                      \           kconfigConfOptIfExprAnd,
+                                      \           kconfigConfOptIfExprOr
+                                      \ skipwhite skipnl
+
+syn match   kconfigConfOptIfExprNeg   '!'
+                                      \ contained
+                                      \ nextgroup=@kconfigConfigOptionIfExpr
+                                      \ skipwhite
+
+syn match   kconfigConfOptIfExprAnd   '&&'
+                                      \ contained
+                                      \ nextgroup=@kconfigConfigOptionIfExpr
+                                      \ skipwhite
+
+syn match   kconfigConfOptIfExprOr    '||'
+                                      \ contained
+                                      \ nextgroup=@kconfigConfigOptionIfExpr
+                                      \ skipwhite
+
+syn match   kconfigConfOptIfExprGroup '('
+                                      \ contained
+                                      \ nextgroup=@kconfigConfigOptionIfGExp
+                                      \ skipwhite
+
+" TODO: hm, this kind of recursion doesn't work right.  We need another set of
+" expressions that have kconfigConfigOPtionIfGExp as nextgroup and a matcher
+" for '(' that sets it all off.
+syn cluster kconfigConfigOptionIfGExp contains=@kconfigConfOptIfGExpSym,
+                                      \        kconfigConfOptIfGExpNeg,
+                                      \        kconfigConfOptIfExprGroup
+
+syn cluster kconfigConfOptIfGExpSym   contains=kconfigConfOptIfGExpCSym,
+                                      \        kconfigConfOptIfGExpNCSym
+
+syn match   kconfigConfOptIfGExpCSym  '"[^"\\]*\%(\\.[^"\\]*\)*"'
+                                      \ contained
+                                      \ nextgroup=@kconfigConfigIf,
+                                      \           kconfigConfOptIfGExpAnd,
+                                      \           kconfigConfOptIfGExpOr,
+                                      \           kconfigConfOptIfGExpEq,
+                                      \           kconfigConfOptIfGExpNEq
+                                      \ skipwhite skipnl
+
+syn match   kconfigConfOptIfGExpCSym  "'[^'\\]*\%(\\.[^'\\]*\)*'"
+                                      \ contained
+                                      \ nextgroup=@kconfigConfigIf,
+                                      \           kconfigConfOptIfGExpAnd,
+                                      \           kconfigConfOptIfGExpOr,
+                                      \           kconfigConfOptIfGExpEq,
+                                      \           kconfigConfOptIfGExpNEq
+                                      \ skipwhite skipnl
+
+syn match   kconfigConfOptIfGExpNCSym '\<\k\+\>'
+                                      \ contained
+                                      \ nextgroup=kconfigConfOptIfExprGrpE,
+                                      \           kconfigConfOptIfGExpAnd,
+                                      \           kconfigConfOptIfGExpOr,
+                                      \           kconfigConfOptIfGExpEq,
+                                      \           kconfigConfOptIfGExpNEq
+                                      \ skipwhite skipnl
+
+syn cluster kconfigConfOptIfGExpSym2  contains=kconfigConfOptIfGExpCSym2,
+                                      \        kconfigConfOptIfGExpNCSym2
+
+syn match   kconfigConfOptIfGExpEq    '='
+                                      \ contained
+                                      \ nextgroup=@kconfigConfOptIfGExpSym2
+                                      \ skipwhite
+
+syn match   kconfigConfOptIfGExpNEq   '!='
+                                      \ contained
+                                      \ nextgroup=@kconfigConfOptIfGExpSym2
+                                      \ skipwhite
+
+syn match   kconfigConfOptIfGExpCSym2 '"[^"\\]*\%(\\.[^"\\]*\)*"'
+                                      \ contained
+                                      \ nextgroup=kconfigConfOptIfExprGrpE,
+                                      \           kconfigConfOptIfGExpAnd,
+                                      \           kconfigConfOptIfGExpOr
+                                      \ skipwhite skipnl
+
+syn match   kconfigConfOptIfGExpCSym2 "'[^'\\]*\%(\\.[^'\\]*\)*'"
+                                      \ contained
+                                      \ nextgroup=kconfigConfOptIfExprGrpE,
+                                      \           kconfigConfOptIfGExpAnd,
+                                      \           kconfigConfOptIfGExpOr
+                                      \ skipwhite skipnl
+
+syn match   kconfigConfOptIfGExpNCSym2 '\<\k\+\>'
+                                      \ contained
+                                      \ nextgroup=kconfigConfOptIfExprGrpE,
+                                      \           kconfigConfOptIfGExpAnd,
+                                      \           kconfigConfOptIfGExpOr
+                                      \ skipwhite skipnl
+
+syn match   kconfigConfOptIfGExpNeg   '!'
+                                      \ contained
+                                      \ nextgroup=@kconfigConfigOptionIfGExp
+                                      \ skipwhite
+
+syn match   kconfigConfOptIfGExpAnd   '&&'
+                                      \ contained
+                                      \ nextgroup=@kconfigConfigOptionIfGExp
+                                      \ skipwhite
+
+syn match   kconfigConfOptIfGExpOr    '||'
+                                      \ contained
+                                      \ nextgroup=@kconfigConfigOptionIfGExp
+                                      \ skipwhite
+
+syn match   kconfigConfOptIfExprGrpE  ')'
+                                      \ contained
+                                      \ nextgroup=@kconfigConfigOptions,
+                                      \           kconfigConfOptIfExprAnd,
+                                      \           kconfigConfOptIfExprOr
+                                      \ skipwhite skipnl
+
+
+syn cluster kconfigConfigOptionExpr   contains=@kconfigConfOptExprSym,
+                                      \        kconfigConfOptExprNeg,
+                                      \        kconfigConfOptExprGroup
+
+syn cluster kconfigConfOptExprSym     contains=kconfigConfOptExprCSym,
+                                      \        kconfigConfOptExprNCSym
+
+syn match   kconfigConfOptExprCSym    '"[^"\\]*\%(\\.[^"\\]*\)*"'
+                                      \ contained
+                                      \ nextgroup=kconfigConfigOptionIf,
+                                      \           kconfigConfOptExprAnd,
+                                      \           kconfigConfOptExprOr,
+                                      \           kconfigConfOptExprEq,
+                                      \           kconfigConfOptExprNEq,
+                                      \           @kconfigConfigOptions
+                                      \ skipwhite skipnl
+
+syn match   kconfigConfOptExprCSym    "'[^'\\]*\%(\\.[^'\\]*\)*'"
+                                      \ contained
+                                      \ nextgroup=kconfigConfigOptionIf,
+                                      \           kconfigConfOptExprAnd,
+                                      \           kconfigConfOptExprOr,
+                                      \           kconfigConfOptExprEq,
+                                      \           kconfigConfOptExprNEq,
+                                      \           @kconfigConfigOptions
+                                      \ skipwhite skipnl
+
+syn match   kconfigConfOptExprNCSym   '\<\k\+\>'
+                                      \ contained
+                                      \ nextgroup=kconfigConfigOptionIf,
+                                      \           kconfigConfOptExprAnd,
+                                      \           kconfigConfOptExprOr,
+                                      \           kconfigConfOptExprEq,
+                                      \           kconfigConfOptExprNEq,
+                                      \           @kconfigConfigOptions
+                                      \ skipwhite skipnl
+
+syn cluster kconfigConfOptExprSym2    contains=kconfigConfOptExprCSym2,
+                                      \        kconfigConfOptExprNCSym2
+
+syn match   kconfigConfOptExprEq      '='
+                                      \ contained
+                                      \ nextgroup=@kconfigConfOptExprSym2
+                                      \ skipwhite
+
+syn match   kconfigConfOptExprNEq     '!='
+                                      \ contained
+                                      \ nextgroup=@kconfigConfOptExprSym2
+                                      \ skipwhite
+
+syn match   kconfigConfOptExprCSym2   '"[^"\\]*\%(\\.[^"\\]*\)*"'
+                                      \ contained
+                                      \ nextgroup=kconfigConfigOptionIf,
+                                      \           kconfigConfOptExprAnd,
+                                      \           kconfigConfOptExprOr,
+                                      \           @kconfigConfigOptions
+                                      \ skipwhite skipnl
+
+syn match   kconfigConfOptExprCSym2   "'[^'\\]*\%(\\.[^'\\]*\)*'"
+                                      \ contained
+                                      \ nextgroup=kconfigConfigOptionIf,
+                                      \           kconfigConfOptExprAnd,
+                                      \           kconfigConfOptExprOr,
+                                      \           @kconfigConfigOptions
+                                      \ skipwhite skipnl
+
+syn match   kconfigConfOptExprNCSym2  '\<\k\+\>'
+                                      \ contained
+                                      \ nextgroup=kconfigConfigOptionIf,
+                                      \           kconfigConfOptExprAnd,
+                                      \           kconfigConfOptExprOr,
+                                      \           @kconfigConfigOptions
+                                      \ skipwhite skipnl
+
+syn match   kconfigConfOptExprNeg     '!'
+                                      \ contained
+                                      \ nextgroup=@kconfigConfigOptionExpr
+                                      \ skipwhite
+
+syn match   kconfigConfOptExprAnd     '&&'
+                                      \ contained
+                                      \ nextgroup=@kconfigConfigOptionExpr
+                                      \ skipwhite
+
+syn match   kconfigConfOptExprOr      '||'
+                                      \ contained
+                                      \ nextgroup=@kconfigConfigOptionExpr
+                                      \ skipwhite
+
+syn match   kconfigConfOptExprGroup   '('
+                                      \ contained
+                                      \ nextgroup=@kconfigConfigOptionGExp
+                                      \ skipwhite
+
+syn cluster kconfigConfigOptionGExp   contains=@kconfigConfOptGExpSym,
+                                      \        kconfigConfOptGExpNeg,
+                                      \        kconfigConfOptGExpGroup
+
+syn cluster kconfigConfOptGExpSym     contains=kconfigConfOptGExpCSym,
+                                      \        kconfigConfOptGExpNCSym
+
+syn match   kconfigConfOptGExpCSym    '"[^"\\]*\%(\\.[^"\\]*\)*"'
+                                      \ contained
+                                      \ nextgroup=kconfigConfOptExprGrpE,
+                                      \           kconfigConfOptGExpAnd,
+                                      \           kconfigConfOptGExpOr,
+                                      \           kconfigConfOptGExpEq,
+                                      \           kconfigConfOptGExpNEq
+                                      \ skipwhite skipnl
+
+syn match   kconfigConfOptGExpCSym    "'[^'\\]*\%(\\.[^'\\]*\)*'"
+                                      \ contained
+                                      \ nextgroup=kconfigConfOptExprGrpE,
+                                      \           kconfigConfOptGExpAnd,
+                                      \           kconfigConfOptGExpOr,
+                                      \           kconfigConfOptGExpEq,
+                                      \           kconfigConfOptGExpNEq
+                                      \ skipwhite skipnl
+
+syn match   kconfigConfOptGExpNCSym   '\<\k\+\>'
+                                      \ contained
+                                      \ nextgroup=kconfigConfOptExprGrpE,
+                                      \           kconfigConfOptGExpAnd,
+                                      \           kconfigConfOptGExpOr,
+                                      \           kconfigConfOptGExpEq,
+                                      \           kconfigConfOptGExpNEq
+                                      \ skipwhite skipnl
+
+syn cluster kconfigConfOptGExpSym2    contains=kconfigConfOptGExpCSym2,
+                                      \        kconfigConfOptGExpNCSym2
+
+syn match   kconfigConfOptGExpEq      '='
+                                      \ contained
+                                      \ nextgroup=@kconfigConfOptGExpSym2
+                                      \ skipwhite
+
+syn match   kconfigConfOptGExpNEq     '!='
+                                      \ contained
+                                      \ nextgroup=@kconfigConfOptGExpSym2
+                                      \ skipwhite
+
+syn match   kconfigConfOptGExpCSym2   '"[^"\\]*\%(\\.[^"\\]*\)*"'
+                                      \ contained
+                                      \ nextgroup=kconfigConfOptExprGrpE,
+                                      \           kconfigConfOptGExpAnd,
+                                      \           kconfigConfOptGExpOr
+                                      \ skipwhite skipnl
+
+syn match   kconfigConfOptGExpCSym2   "'[^'\\]*\%(\\.[^'\\]*\)*'"
+                                      \ contained
+                                      \ nextgroup=kconfigConfOptExprGrpE,
+                                      \           kconfigConfOptGExpAnd,
+                                      \           kconfigConfOptGExpOr
+                                      \ skipwhite skipnl
+
+syn match   kconfigConfOptGExpNCSym2  '\<\k\+\>'
+                                      \ contained
+                                      \ nextgroup=kconfigConfOptExprGrpE,
+                                      \           kconfigConfOptGExpAnd,
+                                      \           kconfigConfOptGExpOr
+                                      \ skipwhite skipnl
+
+syn match   kconfigConfOptGExpNeg     '!'
+                                      \ contained
+                                      \ nextgroup=@kconfigConfigOptionGExp
+                                      \ skipwhite
+
+syn match   kconfigConfOptGExpAnd     '&&'
+                                      \ contained
+                                      \ nextgroup=@kconfigConfigOptionGExp
+                                      \ skipwhite
+
+syn match   kconfigConfOptGExpOr      '||'
+                                      \ contained
+                                      \ nextgroup=@kconfigConfigOptionGExp
+                                      \ skipwhite
+
+syn match   kconfigConfOptExprGrpE    ')'
+                                      \ contained
+                                      \ nextgroup=kconfigConfigOptionIf,
+                                      \           kconfigConfOptExprAnd,
+                                      \           kconfigConfOptExprOr
+                                      \ skipwhite skipnl
+
+syn sync minlines=50
+
+hi def link kconfigTodo                 Todo
+hi def link kconfigComment              Comment
+hi def link kconfigKeyword              Keyword
+hi def link kconfigPreProc              PreProc
+hi def link kconfigConditional          Conditional
+hi def link kconfigPrompt               String
+hi def link kconfigKeywordPrompt        kconfigPrompt
+hi def link kconfigPath                 String
+hi def link kconfigSymbol               String
+hi def link kconfigConstantSymbol       Constant
+hi def link kconfigConfigOption         Type
+hi def link kconfigTypeDefinition       kconfigConfigOption
+hi def link kconfigTypeDefPrompt        kconfigPrompt
+hi def link kconfigInputPrompt          kconfigConfigOption
+hi def link kconfigPromptPrompt         kconfigPrompt
+hi def link kconfigDefaultValue         kconfigConfigOption
+hi def link kconfigDependencies         kconfigConfigOption
+hi def link kconfigReverseDependencies  kconfigConfigOption
+hi def link kconfigRevDepCSymbol        kconfigConstantSymbol
+hi def link kconfigRevDepNCSymbol       kconfigSymbol
+hi def link kconfigNumericalRanges      kconfigConfigOption
+hi def link kconfigRangeCSymbol         kconfigConstantSymbol
+hi def link kconfigRangeNCSymbol        kconfigSymbol
+hi def link kconfigRangeCSymbol2        kconfigConstantSymbol
+hi def link kconfigRangeNCSymbol2       kconfigSymbol
+hi def link kconfigHelpText             Normal
+hi def link kconfigDefBool              kconfigConfigOption
+hi def link kconfigDefBoolCSymbol       kconfigConstantSymbol
+hi def link kconfigDefBoolNCSymbol      kconfigSymbol
+hi def link kconfigOptional             kconfigConfigOption
+hi def link kconfigConfigOptionIf       Conditional
+hi def link kconfigConfOptIfExprCSym    kconfigConstantSymbol
+hi def link kconfigConfOptIfExprNCSym   kconfigSymbol
+hi def link kconfigOperator             Operator
+hi def link kconfigConfOptIfExprEq      kconfigOperator
+hi def link kconfigConfOptIfExprNEq     kconfigOperator
+hi def link kconfigConfOptIfExprCSym2   kconfigConstantSymbol
+hi def link kconfigConfOptIfExprNCSym2  kconfigSymbol
+hi def link kconfigConfOptIfExprNeg     kconfigOperator
+hi def link kconfigConfOptIfExprAnd     kconfigOperator
+hi def link kconfigConfOptIfExprOr      kconfigOperator
+hi def link kconfigDelimiter            Delimiter
+hi def link kconfigConfOptIfExprGroup   kconfigDelimiter
+hi def link kconfigConfOptIfGExpCSym    kconfigConstantSymbol
+hi def link kconfigConfOptIfGExpNCSym   kconfigSymbol
+hi def link kconfigConfOptIfGExpEq      kconfigOperator
+hi def link kconfigConfOptIfGExpNEq     kconfigOperator
+hi def link kconfigConfOptIfGExpCSym2   kconfigConstantSymbol
+hi def link kconfigConfOptIfGExpNCSym2  kconfigSymbol
+hi def link kconfigConfOptIfGExpNeg     kconfigOperator
+hi def link kconfigConfOptIfGExpAnd     kconfigOperator
+hi def link kconfigConfOptIfGExpOr      kconfigOperator
+hi def link kconfigConfOptIfExprGrpE    kconfigDelimiter
+hi def link kconfigConfOptExprCSym      kconfigConstantSymbol
+hi def link kconfigConfOptExprNCSym     kconfigSymbol
+hi def link kconfigConfOptExprEq        kconfigOperator
+hi def link kconfigConfOptExprNEq       kconfigOperator
+hi def link kconfigConfOptExprCSym2     kconfigConstantSymbol
+hi def link kconfigConfOptExprNCSym2    kconfigSymbol
+hi def link kconfigConfOptExprNeg       kconfigOperator
+hi def link kconfigConfOptExprAnd       kconfigOperator
+hi def link kconfigConfOptExprOr        kconfigOperator
+hi def link kconfigConfOptExprGroup     kconfigDelimiter
+hi def link kconfigConfOptGExpCSym      kconfigConstantSymbol
+hi def link kconfigConfOptGExpNCSym     kconfigSymbol
+hi def link kconfigConfOptGExpEq        kconfigOperator
+hi def link kconfigConfOptGExpNEq       kconfigOperator
+hi def link kconfigConfOptGExpCSym2     kconfigConstantSymbol
+hi def link kconfigConfOptGExpNCSym2    kconfigSymbol
+hi def link kconfigConfOptGExpNeg       kconfigOperator
+hi def link kconfigConfOptGExpAnd       kconfigOperator
+hi def link kconfigConfOptGExpOr        kconfigOperator
+hi def link kconfigConfOptExprGrpE      kconfigConfOptIfExprGroup
+
+else
+
+syn keyword kconfigTodo               contained TODO FIXME XXX NOTE
+
+syn match   kconfigComment            display '#.*$' contains=kconfigTodo
+
+syn keyword kconfigKeyword            config menuconfig comment menu mainmenu
+
+syn keyword kconfigConditional        choice endchoice if endif
+
+syn keyword kconfigPreProc            source
+                                      \ nextgroup=kconfigPath
+                                      \ skipwhite
+
+syn keyword kconfigTriState           y m n
+
+syn match   kconfigSpecialChar        contained '\\.'
+syn match   kconfigSpecialChar        '\\$'
+
+syn region  kconfigPath               matchgroup=kconfigPath
+                                      \ start=+"+ skip=+\\\\\|\\\"+ end=+"+
+                                      \ contains=kconfigSpecialChar
+
+syn region  kconfigPath               matchgroup=kconfigPath
+                                      \ start=+'+ skip=+\\\\\|\\\'+ end=+'+
+                                      \ contains=kconfigSpecialChar
+
+syn match   kconfigPath               '\S\+'
+                                      \ contained
+
+syn region  kconfigString             matchgroup=kconfigString
+                                      \ start=+"+ skip=+\\\\\|\\\"+ end=+"+
+                                      \ contains=kconfigSpecialChar
+
+syn region  kconfigString             matchgroup=kconfigString
+                                      \ start=+'+ skip=+\\\\\|\\\'+ end=+'+
+                                      \ contains=kconfigSpecialChar
+
+syn keyword kconfigType               bool boolean tristate string hex int
+
+syn keyword kconfigOption             prompt default requires select range
+                                      \ optional
+syn match   kconfigOption             'depends\%( on\)\='
+
+syn keyword kconfigMacro              def_bool def_tristate
+
+syn region  kconfigHelpText
+      \ matchgroup=kconfigOption
+      \ start='\%(help\|---help---\)\ze\s*\n\z(\s\+\)'
+      \ skip='^$'
+      \ end='^\z1\@!'
+
+syn sync    match kconfigSyncHelp     grouphere kconfigHelpText 'help\|---help---'
+
+hi def link kconfigTodo         Todo
+hi def link kconfigComment      Comment
+hi def link kconfigKeyword      Keyword
+hi def link kconfigConditional  Conditional
+hi def link kconfigPreProc      PreProc
+hi def link kconfigTriState     Boolean
+hi def link kconfigSpecialChar  SpecialChar
+hi def link kconfigPath         String
+hi def link kconfigString       String
+hi def link kconfigType         Type
+hi def link kconfigOption       Identifier
+hi def link kconfigHelpText     Normal
+hi def link kconfigmacro        Macro
+
+endif
+
+let b:current_syntax = "kconfig"
+
+let &cpo = s:cpo_save
+unlet s:cpo_save
--- /dev/null
+++ b/lib/vimfiles/syntax/kix.vim
@@ -1,0 +1,182 @@
+" Vim syntax file
+" Language:	KixTart 95, Kix2001 Windows script language http://kixtart.org/
+" Maintainer:	Richard Howarth <rhowarth@sgb.co.uk>
+" Last Change:	2003 May 11
+" URL:		http://www.howsoft.demon.co.uk/
+
+" KixTart files identified by *.kix extension.
+
+" Amendment History:
+" 26 April 2001: RMH
+"    Removed development comments from distro version
+"    Renamed "Kix*" to "kix*" for consistancy
+"    Changes made in preperation for VIM version 5.8/6.00
+
+" TODO:
+"	Handle arrays highlighting
+"	Handle object highlighting
+" The next two may not be possible:
+"	Work out how to error too many "(", i.e. (() should be an error.
+"	Similarly, "if" without "endif" and similar constructs should error.
+
+" Clear legacy syntax rules for version 5.x, exit if already processed for version 6+
+if version < 600
+	syn clear
+elseif exists("b:current_syntax")
+	finish
+endif
+
+syn case match
+syn keyword kixTODO		TODO FIX XXX contained
+
+" Case insensitive language.
+syn case ignore
+
+" Kix statements
+syn match   kixStatement	"?"
+syn keyword kixStatement	beep big break
+syn keyword kixStatement	call cd cls color cookie1 copy
+syn keyword kixStatement	del dim display
+syn keyword kixStatement	exit
+syn keyword kixStatement	flushkb
+syn keyword kixStatement	get gets global go gosub goto
+syn keyword kixStatement	md
+syn keyword kixStatement	password play
+syn keyword kixStatement	quit
+syn keyword kixStatement	rd return run
+syn keyword kixStatement	set setl setm settime shell sleep small
+syn keyword kixStatement	use
+
+" Kix2001
+syn keyword kixStatement	debug function endfunction redim
+
+" Simple variables
+syn match   kixNotVar		"\$\$\|@@\|%%" transparent contains=NONE
+syn match   kixLocalVar		"\$\w\+"
+syn match   kixMacro		"@\w\+"
+syn match   kixEnvVar		"%\w\+"
+
+" Destination labels
+syn match   kixLabel		":\w\+\>"
+
+" Identify strings, trap unterminated strings
+syn match   kixStringError      +".*\|'.*+
+syn region  kixDoubleString	oneline start=+"+ skip=+\\\\\|\\"+ end=+"+ contains=kixLocalVar,kixMacro,kixEnvVar,kixNotVar
+syn region  kixSingleString	oneline start=+'+ skip=+\\\\\|\\'+ end=+'+ contains=kixLocalVar,kixMacro,kixEnvVar,kixNotVar
+
+" Operators
+syn match   kixOperator		"+\|-\|\*\|/\|=\|&\||"
+syn keyword kixOperator		and or
+" Kix2001
+syn match   kixOperator		"=="
+syn keyword kixOperator		not
+
+" Numeric constants
+syn match   kixInteger		"-\=\<\d\+\>" contains=NONE
+syn match   kixFloat		"-\=\.\d\+\>\|-\=\<\d\+\.\d\+\>" contains=NONE
+
+" Hex numeric constants
+syn match   kixHex		"\&\x\+\>" contains=NONE
+
+" Other contants
+" Kix2001
+syn keyword kixConstant		on off
+
+" Comments
+syn match   kixComment		";.*$" contains=kixTODO
+
+" Trap unmatched parenthesis
+syn match   kixParenCloseError	")"
+syn region  kixParen		oneline transparent start="(" end=")" contains=ALLBUT,kixParenCloseError
+
+" Functions (Builtin + UDF)
+syn match   kixFunction		"\w\+("he=e-1,me=e-1 contains=ALL
+
+" Trap unmatched brackets
+syn match   kixBrackCloseError	"\]"
+syn region  kixBrack		transparent start="\[" end="\]" contains=ALLBUT,kixBrackCloseError
+
+" Clusters for ALLBUT shorthand
+syn cluster kixIfBut		contains=kixIfError,kixSelectOK,kixDoOK,kixWhileOK,kixForEachOK,kixForNextOK
+syn cluster kixSelectBut	contains=kixSelectError,kixIfOK,kixDoOK,kixWhileOK,kixForEachOK,kixForNextOK
+syn cluster kixDoBut		contains=kixDoError,kixSelectOK,kixIfOK,kixWhileOK,kixForEachOK,kixForNextOK
+syn cluster kixWhileBut		contains=kixWhileError,kixSelectOK,kixIfOK,kixDoOK,kixForEachOK,kixForNextOK
+syn cluster kixForEachBut	contains=kixForEachError,kixSelectOK,kixIfOK,kixDoOK,kixForNextOK,kixWhileOK
+syn cluster kixForNextBut	contains=kixForNextError,kixSelectOK,kixIfOK,kixDoOK,kixForEachOK,kixWhileOK
+" Condtional construct errors.
+syn match   kixIfError		"\<if\>\|\<else\>\|\<endif\>"
+syn match   kixIfOK		contained "\<if\>\|\<else\>\|\<endif\>"
+syn region  kixIf		transparent matchgroup=kixIfOK start="\<if\>" end="\<endif\>" contains=ALLBUT,@kixIfBut
+syn match   kixSelectError	"\<select\>\|\<case\>\|\<endselect\>"
+syn match   kixSelectOK		contained "\<select\>\|\<case\>\|\<endselect\>"
+syn region  kixSelect		transparent matchgroup=kixSelectOK start="\<select\>" end="\<endselect\>" contains=ALLBUT,@kixSelectBut
+
+" Program control constructs.
+syn match   kixDoError		"\<do\>\|\<until\>"
+syn match   kixDoOK		contained "\<do\>\|\<until\>"
+syn region  kixDo		transparent matchgroup=kixDoOK start="\<do\>" end="\<until\>" contains=ALLBUT,@kixDoBut
+syn match   kixWhileError	"\<while\>\|\<loop\>"
+syn match   kixWhileOK		contained "\<while\>\|\<loop\>"
+syn region  kixWhile		transparent matchgroup=kixWhileOK start="\<while\>" end="\<loop\>" contains=ALLBUT,@kixWhileBut
+syn match   kixForNextError	"\<for\>\|\<to\>\|\<step\>\|\<next\>"
+syn match   kixForNextOK	contained "\<for\>\|\<to\>\|\<step\>\|\<next\>"
+syn region  kixForNext		transparent matchgroup=kixForNextOK start="\<for\>" end="\<next\>" contains=ALLBUT,@kixForBut
+syn match   kixForEachError	"\<for each\>\|\<in\>\|\<next\>"
+syn match   kixForEachOK	contained "\<for each\>\|\<in\>\|\<next\>"
+syn region  kixForEach		transparent matchgroup=kixForEachOK start="\<for each\>" end="\<next\>" contains=ALLBUT,@kixForEachBut
+
+" Expressions
+syn match   kixExpression	"<\|>\|<=\|>=\|<>"
+
+
+" Default highlighting.
+" Version < 5.8 set default highlight if file not already processed.
+" Version >= 5.8 set default highlight only if it doesn't already have a value.
+if version > 508 || !exists("did_kix_syn_inits")
+	if version < 508
+		let did_kix_syn_inits=1
+		command -nargs=+ HiLink hi link <args>
+	else
+		command -nargs=+ HiLink hi def link <args>
+	endif
+
+	HiLink kixDoubleString		String
+	HiLink kixSingleString		String
+	HiLink kixStatement		Statement
+	HiLink kixRepeat		Repeat
+	HiLink kixComment		Comment
+	HiLink kixBuiltin		Function
+	HiLink kixLocalVar		Special
+	HiLink kixMacro			Special
+	HiLink kixEnvVar		Special
+	HiLink kixLabel			Type
+	HiLink kixFunction		Function
+	HiLink kixInteger		Number
+	HiLink kixHex			Number
+	HiLink kixFloat			Number
+	HiLink kixOperator		Operator
+	HiLink kixExpression		Operator
+
+	HiLink kixParenCloseError	Error
+	HiLink kixBrackCloseError	Error
+	HiLink kixStringError		Error
+
+	HiLink kixWhileError		Error
+	HiLink kixWhileOK		Conditional
+	HiLink kixDoError		Error
+	HiLink kixDoOK			Conditional
+	HiLink kixIfError		Error
+	HiLink kixIfOK			Conditional
+	HiLink kixSelectError		Error
+	HiLink kixSelectOK		Conditional
+	HiLink kixForNextError		Error
+	HiLink kixForNextOK		Conditional
+	HiLink kixForEachError		Error
+	HiLink kixForEachOK		Conditional
+
+	delcommand HiLink
+endif
+
+let b:current_syntax = "kix"
+
+" vim: ts=8 sw=2
--- /dev/null
+++ b/lib/vimfiles/syntax/kscript.vim
@@ -1,0 +1,70 @@
+" Vim syntax file
+" Language:	kscript
+" Maintainer:	Thomas Capricelli <orzel@yalbi.com>
+" URL:		http://aquila.rezel.enst.fr/thomas/vim/kscript.vim
+" CVS:		$Id: kscript.vim,v 1.1 2004/06/13 17:40:02 vimboss Exp $
+
+" For version 5.x: Clear all syntax items
+" For version 6.x: Quit when a syntax file was already loaded
+if version < 600
+  syntax clear
+elseif exists("b:current_syntax")
+  finish
+endif
+
+syn keyword	kscriptPreCondit	import from
+
+syn keyword	kscriptHardCoded	print println connect length arg mid upper lower isEmpty toInt toFloat findApplication
+syn keyword	kscriptConditional	if else switch
+syn keyword	kscriptRepeat		while for do foreach
+syn keyword	kscriptExceptions	emit catch raise try signal
+syn keyword	kscriptFunction		class struct enum
+syn keyword	kscriptConst		FALSE TRUE false true
+syn keyword	kscriptStatement	return delete
+syn keyword	kscriptLabel		case default
+syn keyword	kscriptStorageClass	const
+syn keyword	kscriptType		in out inout var
+
+syn keyword	kscriptTodo		contained TODO FIXME XXX
+
+syn region	kscriptComment		start="/\*" end="\*/" contains=kscriptTodo
+syn match	kscriptComment		"//.*" contains=kscriptTodo
+syn match	kscriptComment		"#.*$" contains=kscriptTodo
+
+syn region	kscriptString		start=+'+  end=+'+ skip=+\\\\\|\\'+
+syn region	kscriptString		start=+"+  end=+"+ skip=+\\\\\|\\"+
+syn region	kscriptString		start=+"""+  end=+"""+
+syn region	kscriptString		start=+'''+  end=+'''+
+
+" Define the default highlighting.
+" For version 5.7 and earlier: only when not done already
+" For version 5.8 and later: only when an item doesn't have highlighting yet
+if version >= 508 || !exists("did_kscript_syntax_inits")
+  if version < 508
+    let did_kscript_syntax_inits = 1
+    command -nargs=+ HiLink hi link <args>
+  else
+    command -nargs=+ HiLink hi def link <args>
+  endif
+
+  HiLink kscriptConditional		Conditional
+  HiLink kscriptRepeat			Repeat
+  HiLink kscriptExceptions		Statement
+  HiLink kscriptFunction		Function
+  HiLink kscriptConst			Constant
+  HiLink kscriptStatement		Statement
+  HiLink kscriptLabel			Label
+  HiLink kscriptStorageClass		StorageClass
+  HiLink kscriptType			Type
+  HiLink kscriptTodo			Todo
+  HiLink kscriptComment		Comment
+  HiLink kscriptString			String
+  HiLink kscriptPreCondit		PreCondit
+  HiLink kscriptHardCoded		Statement
+
+  delcommand HiLink
+endif
+
+let b:current_syntax = "kscript"
+
+" vim: ts=8
--- /dev/null
+++ b/lib/vimfiles/syntax/kwt.vim
@@ -1,0 +1,87 @@
+" Vim syntax file
+" Language:	kimwitu++
+" Maintainer:	Michael Piefel <piefel@informatik.hu-berlin.de>
+" Last Change:	2 May 2001
+
+" For version 5.x: Clear all syntax items
+" For version 6.x: Quit when a syntax file was already loaded
+if version < 600
+    syntax clear
+elseif exists("b:current_syntax")
+    finish
+endif
+
+" Read the C++ syntax to start with
+if version < 600
+  source <sfile>:p:h/cpp.vim
+else
+  runtime! syntax/cpp.vim
+  unlet b:current_syntax
+endif
+
+" kimwitu++ extentions
+
+" Don't stop at eol, messes around with CPP mode, but gives line spanning
+" strings in unparse rules
+syn region cCppString		start=+"+ skip=+\\\\\|\\"+ end=+"+ contains=cSpecial,cFormat
+syn keyword cType		integer real casestring nocasestring voidptr list
+syn keyword cType		uview rview uview_enum rview_enum
+
+" avoid unparsing rule sth:view being scanned as label
+syn clear   cUserCont
+syn match   cUserCont		"^\s*\I\i*\s*:$" contains=cUserLabel contained
+syn match   cUserCont		";\s*\I\i*\s*:$" contains=cUserLabel contained
+syn match   cUserCont		"^\s*\I\i*\s*:[^:]"me=e-1 contains=cUserLabel contained
+syn match   cUserCont		";\s*\I\i*\s*:[^:]"me=e-1 contains=cUserLabel contained
+
+" highlight phylum decls
+syn match   kwtPhylum		"^\I\i*:$"
+syn match   kwtPhylum		"^\I\i*\s*{\s*\(!\|\I\)\i*\s*}\s*:$"
+
+syn keyword kwtStatement	with foreach afterforeach provided
+syn match kwtDecl		"%\(uviewvar\|rviewvar\)"
+syn match kwtDecl		"^%\(uview\|rview\|ctor\|dtor\|base\|storageclass\|list\|attr\|member\|option\)"
+syn match kwtOption		"no-csgio\|no-unparse\|no-rewrite\|no-printdot\|no-hashtables\|smart-pointer\|weak-pointer"
+syn match kwtSep		"^%}$"
+syn match kwtSep		"^%{\(\s\+\I\i*\)*$"
+syn match kwtCast		"\<phylum_cast\s*<"me=e-1
+syn match kwtCast		"\<phylum_cast\s*$"
+
+
+" match views, remove paren error in brackets
+syn clear cErrInBracket
+syn match cErrInBracket		contained ")"
+syn match kwtViews		"\(\[\|<\)\@<=[ [:alnum:]_]\{-}:"
+
+" match rule bodies
+syn region kwtUnpBody		transparent keepend extend fold start="->\s*\[" start="^\s*\[" skip="\$\@<!{\_.\{-}\$\@<!}" end="\s]\s\=;\=$" end="^]\s\=;\=$" end="}]\s\=;\=$"
+syn region kwtRewBody		transparent keepend extend fold start="->\s*<" start="^\s*<" end="\s>\s\=;\=$" end="^>\s\=;\=$"
+
+" Define the default highlighting.
+" For version 5.7 and earlier: only when not done already
+" For version 5.8 and later: only when an item doesn't have highlighting yet
+if version >= 508 || !exists("did_kwt_syn_inits")
+    if version < 508
+	let did_kwt_syn_inits = 1
+	command -nargs=+ HiLink hi link <args>
+    else
+	command -nargs=+ HiLink hi def link <args>
+    endif
+
+    HiLink kwtStatement	cppStatement
+    HiLink kwtDecl	cppStatement
+    HiLink kwtCast	cppStatement
+    HiLink kwtSep	Delimiter
+    HiLink kwtViews	Label
+    HiLink kwtPhylum	Type
+    HiLink kwtOption	PreProc
+    "HiLink cText	Comment
+
+    delcommand HiLink
+endif
+
+syn sync lines=300
+
+let b:current_syntax = "kwt"
+
+" vim: ts=8
--- /dev/null
+++ b/lib/vimfiles/syntax/lace.vim
@@ -1,0 +1,135 @@
+" Vim syntax file
+" Language:		lace
+" Maintainer:	Jocelyn Fiat <utilities@eiffel.com>
+" Last Change:	2001 May 09
+
+" Copyright Interactive Software Engineering, 1998
+" You are free to use this file as you please, but
+" if you make a change or improvement you must send
+" it to the maintainer at <utilities@eiffel.com>
+
+
+" For version 5.x: Clear all syntax items
+" For version 6.x: Quit when a syntax file was already loaded
+if version < 600
+  syntax clear
+elseif exists("b:current_syntax")
+  finish
+endif
+
+" LACE is case insensitive, but the style guide lines are not.
+
+if !exists("lace_case_insensitive")
+	syn case match
+else
+	syn case ignore
+endif
+
+" A bunch of useful LACE keywords
+syn keyword laceTopStruct		system root default option visible cluster
+syn keyword laceTopStruct		external generate end
+syn keyword laceOptionClause	collect assertion debug optimize trace
+syn keyword laceOptionClause	profile inline precompiled multithreaded
+syn keyword laceOptionClause	exception_trace dead_code_removal
+syn keyword laceOptionClause	array_optimization
+syn keyword laceOptionClause	inlining_size inlining
+syn keyword laceOptionClause	console_application dynamic_runtime
+syn keyword laceOptionClause	line_generation
+syn keyword laceOptionMark		yes no all
+syn keyword laceOptionMark		require ensure invariant loop check
+syn keyword laceClusterProp		use include exclude
+syn keyword laceAdaptClassName	adapt ignore rename as
+syn keyword laceAdaptClassName	creation export visible
+syn keyword laceExternal		include_path object makefile
+
+" Operators
+syn match   laceOperator		"\$"
+syn match   laceBrackets		"[[\]]"
+syn match   laceExport			"[{}]"
+
+" Constants
+syn keyword laceBool		true false
+syn keyword laceBool		True False
+syn region  laceString		start=+"+ skip=+%"+ end=+"+ contains=laceEscape,laceStringError
+syn match   laceEscape		contained "%[^/]"
+syn match   laceEscape		contained "%/\d\+/"
+syn match   laceEscape		contained "^[ \t]*%"
+syn match   laceEscape		contained "%[ \t]*$"
+syn match   laceStringError	contained "%/[^0-9]"
+syn match   laceStringError	contained "%/\d\+[^0-9/]"
+syn match   laceStringError	"'\(%[^/]\|%/\d\+/\|[^'%]\)\+'"
+syn match   laceCharacter	"'\(%[^/]\|%/\d\+/\|[^'%]\)'" contains=laceEscape
+syn match   laceNumber		"-\=\<\d\+\(_\d\+\)*\>"
+syn match   laceNumber		"\<[01]\+[bB]\>"
+syn match   laceNumber		"-\=\<\d\+\(_\d\+\)*\.\(\d\+\(_\d\+\)*\)\=\([eE][-+]\=\d\+\(_\d\+\)*\)\="
+syn match   laceNumber		"-\=\.\d\+\(_\d\+\)*\([eE][-+]\=\d\+\(_\d\+\)*\)\="
+syn match   laceComment		"--.*" contains=laceTodo
+
+
+syn case match
+
+" Case sensitive stuff
+
+syn keyword laceTodo		TODO XXX FIXME
+syn match	laceClassName	"\<[A-Z][A-Z0-9_]*\>"
+syn match	laceCluster		"[a-zA-Z][a-zA-Z0-9_]*\s*:"
+syn match	laceCluster		"[a-zA-Z][a-zA-Z0-9_]*\s*(\s*[a-zA-Z][a-zA-Z0-9_]*\s*)\s*:"
+
+" Catch mismatched parentheses
+syn match laceParenError	")"
+syn match laceBracketError	"\]"
+syn region laceGeneric		transparent matchgroup=laceBrackets start="\[" end="\]" contains=ALLBUT,laceBracketError
+syn region laceParen		transparent start="(" end=")" contains=ALLBUT,laceParenError
+
+" Should suffice for even very long strings and expressions
+syn sync lines=40
+
+" Define the default highlighting.
+" For version 5.7 and earlier: only when not done already
+" For version 5.8 and later: only when an item doesn't have highlighting yet
+if version >= 508 || !exists("did_lace_syntax_inits")
+  if version < 508
+    let did_lace_syntax_inits = 1
+    command -nargs=+ HiLink hi link <args>
+  else
+    command -nargs=+ HiLink hi def link <args>
+  endif
+
+  HiLink laceTopStruct			PreProc
+
+  HiLink laceOptionClause		Statement
+  HiLink laceOptionMark			Constant
+  HiLink laceClusterProp		Label
+  HiLink laceAdaptClassName		Label
+  HiLink laceExternal			Statement
+  HiLink laceCluster			ModeMsg
+
+  HiLink laceEscape				Special
+
+  HiLink laceBool				Boolean
+  HiLink laceString				String
+  HiLink laceCharacter			Character
+  HiLink laceClassName			Type
+  HiLink laceNumber				Number
+
+  HiLink laceOperator			Special
+  HiLink laceArray				Special
+  HiLink laceExport				Special
+  HiLink laceCreation			Special
+  HiLink laceBrackets			Special
+  HiLink laceConstraint			Special
+
+  HiLink laceComment			Comment
+
+  HiLink laceError				Error
+  HiLink laceStringError		Error
+  HiLink laceParenError			Error
+  HiLink laceBracketError		Error
+  HiLink laceTodo				Todo
+
+  delcommand HiLink
+endif
+
+let b:current_syntax = "lace"
+
+" vim: ts=4
--- /dev/null
+++ b/lib/vimfiles/syntax/latte.vim
@@ -1,0 +1,98 @@
+" Vim syntax file
+" Language:	Latte
+" Maintainer:	Nick Moffitt, <nick@zork.net>
+" Last Change:	14 June, 2000
+"
+" Notes:
+" I based this on the TeX and Scheme syntax files (but mostly scheme).
+" See http://www.latte.org for info on the language.
+
+" For version 5.x: Clear all syntax items
+" For version 6.x: Quit when a syntax file was already loaded
+if version < 600
+  syntax clear
+elseif exists("b:current_syntax")
+  finish
+endif
+
+syn match latteError "[{}\\]"
+syn match latteOther "\\{"
+syn match latteOther "\\}"
+syn match latteOther "\\\\"
+
+if version < 600
+  set iskeyword=33,43,45,48-57,63,65-90,95,97-122,_
+else
+  setlocal iskeyword=33,43,45,48-57,63,65-90,95,97-122,_
+endif
+
+syn region latteVar matchgroup=SpecialChar start=!\\[A-Za-z_]!rs=s+1 end=![^A-Za-z0-9?!+_-]!me=e-1 contains=ALLBUT,latteNumber,latteOther
+syn region latteVar matchgroup=SpecialChar start=!\\[=\&][A-Za-z_]!rs=s+2 end=![^A-Za-z0-9?!+_-]!me=e-1 contains=ALLBUT,latteNumber,latteOther
+syn region latteString	start=+\\"+ skip=+\\\\"+ end=+\\"+
+
+syn region latteGroup	matchgroup=Delimiter start="{" skip="\\[{}]" matchgroup=Delimiter end="}" contains=ALLBUT,latteSyntax
+
+syn region latteUnquote matchgroup=Delimiter start="\\,{" skip="\\[{}]" matchgroup=Delimiter end="}" contains=ALLBUT,latteSyntax
+syn region latteSplice matchgroup=Delimiter start="\\,@{" skip="\\[{}]" matchgroup=Delimiter end="}" contains=ALLBUT,latteSyntax
+syn region latteQuote matchgroup=Delimiter start="\\'{" skip="\\[{}]" matchgroup=Delimiter end="}"
+syn region latteQuote matchgroup=Delimiter start="\\`{" skip="\\[{}]" matchgroup=Delimiter end="}" contains=latteUnquote,latteSplice
+
+syn match  latteOperator   '\\/'
+syn match  latteOperator   '='
+
+syn match  latteComment	"\\;.*$"
+
+" This was gathered by slurping in the index.
+
+syn keyword latteSyntax __FILE__ __latte-version__ contained
+syn keyword latteSyntax _bal-tag _pre _tag add and append apply back contained
+syn keyword latteSyntax caar cadr car cdar cddr cdr ceil compose contained
+syn keyword latteSyntax concat cons def defmacro divide downcase contained
+syn keyword latteSyntax empty? equal? error explode file-contents contained
+syn keyword latteSyntax floor foreach front funcall ge?  getenv contained
+syn keyword latteSyntax greater-equal? greater? group group? gt? html contained
+syn keyword latteSyntax if include lambda le? length less-equal? contained
+syn keyword latteSyntax less? let lmap load-file load-library lt?  macro contained
+syn keyword latteSyntax member?  modulo multiply not nth operator? contained
+syn keyword latteSyntax or ordinary quote process-output push-back contained
+syn keyword latteSyntax push-front quasiquote quote random rdc reverse contained
+syn keyword latteSyntax set!  snoc splicing unquote strict-html4 contained
+syn keyword latteSyntax string-append string-ge?  string-greater-equal? contained
+syn keyword latteSyntax string-greater?  string-gt?  string-le? contained
+syn keyword latteSyntax string-less-equal?  string-less?  string-lt? contained
+syn keyword latteSyntax string?  subseq substr subtract  contained
+syn keyword latteSyntax upcase useless warn while zero?  contained
+
+
+" If it's good enough for scheme...
+
+syn sync match matchPlace grouphere NONE "^[^ \t]"
+" ... i.e. synchronize on a line that starts at the left margin
+
+" Define the default highlighting.
+" For version 5.7 and earlier: only when not done already
+" For version 5.8 and later: only when an item doesn't have highlighting yet
+if version >= 508 || !exists("did_latte_syntax_inits")
+  if version < 508
+    let did_latte_syntax_inits = 1
+    command -nargs=+ HiLink hi link <args>
+  else
+    command -nargs=+ HiLink hi def link <args>
+  endif
+
+  HiLink latteSyntax		Statement
+  HiLink latteVar			Function
+
+  HiLink latteString		String
+  HiLink latteQuote			String
+
+  HiLink latteDelimiter		Delimiter
+  HiLink latteOperator		Operator
+
+  HiLink latteComment		Comment
+  HiLink latteError			Error
+
+  delcommand HiLink
+endif
+
+let b:current_syntax = "latte"
--- /dev/null
+++ b/lib/vimfiles/syntax/ld.vim
@@ -1,0 +1,81 @@
+" Vim syntax file
+" Language:         ld(1) script
+" Maintainer:       Nikolai Weibull <now@bitwi.se>
+" Latest Revision:  2006-04-19
+
+if exists("b:current_syntax")
+  finish
+endif
+
+let s:cpo_save = &cpo
+set cpo&vim
+
+syn keyword ldTodo          contained TODO FIXME XXX NOTE
+
+syn region  ldComment       start='/\*' end='\*/' contains=ldTodo,@Spell
+
+syn region  ldFileName      start=+"+ end=+"+
+
+syn keyword ldPreProc       SECTIONS MEMORY OVERLAY PHDRS VERSION INCLUDE
+syn match   ldPreProc       '\<VERS_\d\+\.\d\+'
+
+syn keyword ldFunction      ABSOLUTE ADDR ALIGN BLOCK DATA_SEGMENT_ALIGN
+                            \ DATA_SEGMENT_END DATA_SEGMENT_RELRO_END DEFINED
+                            \ LOADADDR MAX MIN NEXT SIZEOF SIZEOF_HEADERS
+                            \ sizeof_headers
+
+syn keyword ldKeyword       ENTRY INPUT GROUP OUTPUT
+                            \ SEARCH_DIR STARTUP OUTPUT_FORMAT TARGET
+                            \ ASSERT EXTERN FORCE_COMMON_ALLOCATION
+                            \ INHIBIT_COMMON_ALLOCATION NOCROSSREFS OUTPUT_ARCH
+                            \ PROVIDE EXCLUDE_FILE SORT KEEP FILL
+                            \ CREATE_OBJECT_SYMBOLS CONSTRUCTORS SUBALIGN
+                            \ FILEHDR AT __asm__ ABSOLUTE
+
+syn keyword ldDataType      BYTE SHORT LONG QUAD SQUAD
+syn keyword ldOutputType    NOLOAD DSECT COPY INFO OVERLAY
+syn keyword ldPTType        PT_NULL PT_LOAD PT_DYNAMIC PT_INTERP
+                            \ PT_NOTE PT_SHLIB PT_PHDR
+
+syn keyword ldSpecial       COMMON
+syn match   ldSpecial       '/DISCARD/'
+
+syn keyword ldIdentifier    ORIGIN LENGTH
+
+syn match   ldSpecSections  '\.'
+syn match   ldSections      '\.\S\+'
+syn match   ldSpecSections  '\.\%(text\|data\|bss\|symver\)\>'
+
+syn match   ldNumber        display '\<0[xX]\x\+\>'
+syn match   ldNumber        display '\d\+[KM]\>' contains=ldNumberMult
+syn match   ldNumberMult    display '[KM]\>'
+syn match   ldOctal         contained display '\<0\o\+\>'
+                            \ contains=ldOctalZero
+syn match   ldOctalZero     contained display '\<0'
+syn match   ldOctalError    contained display '\<0\o*[89]\d*\>'
+
+
+hi def link ldTodo          Todo
+hi def link ldComment       Comment
+hi def link ldFileName      String
+hi def link ldPreProc       PreProc
+hi def link ldFunction      Identifier
+hi def link ldKeyword       Keyword
+hi def link ldType          Type
+hi def link ldDataType      ldType
+hi def link ldOutputType    ldType
+hi def link ldPTType        ldType
+hi def link ldSpecial       Special
+hi def link ldIdentifier    Identifier
+hi def link ldSections      Constant
+hi def link ldSpecSections  Special
+hi def link ldNumber        Number
+hi def link ldNumberMult    PreProc
+hi def link ldOctal         ldNumber
+hi def link ldOctalZero     PreProc
+hi def link ldOctalError    Error
+
+let b:current_syntax = "ld"
+
+let &cpo = s:cpo_save
+unlet s:cpo_save
--- /dev/null
+++ b/lib/vimfiles/syntax/ldapconf.vim
@@ -1,0 +1,338 @@
+" Vim syntax file
+" Language:         ldap.conf(5) configuration file.
+" Maintainer:       Nikolai Weibull <now@bitwi.se>
+" Latest Revision:  2006-12-11
+
+if exists("b:current_syntax")
+  finish
+endif
+
+let s:cpo_save = &cpo
+set cpo&vim
+
+syn keyword ldapconfTodo          contained TODO FIXME XXX NOTE
+
+syn region  ldapconfComment       display oneline start='^\s*#' end='$'
+      \                           contains=ldapconfTodo,
+      \                                    @Spell
+
+syn match   ldapconfBegin         display '^'
+      \                           nextgroup=ldapconfOption,
+      \                                     ldapconfDeprOption,
+      \                                     ldapconfComment
+
+syn case    ignore
+
+syn keyword ldapconfOption        contained URI 
+      \                           nextgroup=ldapconfURI
+      \                           skipwhite
+
+syn keyword ldapconfOption        contained
+      \                           BASE
+      \                           BINDDN
+      \                           nextgroup=ldapconfDNAttrType
+      \                           skipwhite
+
+syn keyword ldapconfDeprOption    contained 
+      \                           HOST
+      \                           nextgroup=ldapconfHost
+      \                           skipwhite
+
+syn keyword ldapconfDeprOption    contained
+      \                           PORT
+      \                           nextgroup=ldapconfPort
+      \                           skipwhite
+
+syn keyword ldapconfOption        contained
+      \                           REFERRALS
+      \                           nextgroup=ldapconfBoolean
+      \                           skipwhite
+
+syn keyword ldapconfOption        contained
+      \                           SIZELIMIT
+      \                           TIMELIMIT
+      \                           nextgroup=ldapconfInteger
+      \                           skipwhite
+
+syn keyword ldapconfOption        contained
+      \                           DEREF
+      \                           nextgroup=ldapconfDerefWhen
+      \                           skipwhite
+
+syn keyword ldapconfOption        contained
+      \                           SASL_MECH
+      \                           nextgroup=ldapconfSASLMechanism
+      \                           skipwhite
+
+syn keyword ldapconfOption        contained
+      \                           SASL_REALM
+      \                           nextgroup=ldapconfSASLRealm
+      \                           skipwhite
+
+syn keyword ldapconfOption        contained
+      \                           SASL_AUTHCID
+      \                           SASL_AUTHZID
+      \                           nextgroup=ldapconfSASLAuthID
+      \                           skipwhite
+
+syn keyword ldapconfOption        contained
+      \                           SASL_SECPROPS
+      \                           nextgroup=ldapconfSASLSecProps
+      \                           skipwhite
+
+syn keyword ldapconfOption        contained
+      \                           TLS_CACERT
+      \                           TLS_CERT
+      \                           TLS_KEY
+      \                           TLS_RANDFILE
+      \                           nextgroup=ldapconfFilename
+      \                           skipwhite
+
+syn keyword ldapconfOption        contained
+      \                           TLS_CACERTDIR
+      \                           nextgroup=ldapconfPath
+      \                           skipwhite
+
+syn keyword ldapconfOption        contained
+      \                           TLS_CIPHER_SUITE
+      \                           nextgroup=@ldapconfTLSCipher
+      \                           skipwhite
+
+syn keyword ldapconfOption        contained
+      \                           TLS_REQCERT
+      \                           nextgroup=ldapconfTLSCertCheck
+      \                           skipwhite
+
+syn keyword ldapconfOption        contained
+      \                           TLS_CRLCHECK
+      \                           nextgroup=ldapconfTLSCRLCheck
+      \                           skipwhite
+
+syn case    match
+
+syn match   ldapconfURI           contained display
+      \                           'ldaps\=://[^[:space:]:]\+\%(:\d\+\)\='
+      \                           nextgroup=ldapconfURI
+      \                           skipwhite
+
+" LDAP Distinguished Names are defined in Section 3 of RFC 2253:
+" http://www.ietf.org/rfc/rfc2253.txt.
+syn match   ldapconfDNAttrType    contained display
+      \                           '\a[a-zA-Z0-9-]\+\|\d\+\%(\.\d\+\)*'
+      \                           nextgroup=ldapconfDNAttrTypeEq
+
+syn match   ldapconfDNAttrTypeEq  contained display
+      \                           '='
+      \                           nextgroup=ldapconfDNAttrValue
+
+syn match   ldapconfDNAttrValue   contained display
+      \                           '\%([^,=+<>#;\\"]\|\\\%([,=+<>#;\\"]\|\x\x\)\)*\|#\%(\x\x\)\+\|"\%([^\\"]\|\\\%([,=+<>#;\\"]\|\x\x\)\)*"'
+      \                           nextgroup=ldapconfDNSeparator
+
+syn match   ldapconfDNSeparator   contained display
+      \                           '[+,]'
+      \                           nextgroup=ldapconfDNAttrType
+
+syn match   ldapconfHost          contained display
+      \                           '[^[:space:]:]\+\%(:\d\+\)\='
+      \                           nextgroup=ldapconfHost
+      \                           skipwhite
+
+syn match   ldapconfPort          contained display
+      \                           '\d\+'
+
+syn keyword ldapconfBoolean       contained
+      \                           on
+      \                           true
+      \                           yes
+      \                           off
+      \                           false
+      \                           no
+
+syn match   ldapconfInteger       contained display
+      \                           '\d\+'
+
+syn keyword ldapconfDerefWhen     contained
+      \                           never
+      \                           searching
+      \                           finding
+      \                           always
+
+" Taken from http://www.iana.org/assignments/sasl-mechanisms.
+syn keyword ldapconfSASLMechanism contained
+      \                           KERBEROS_V4
+      \                           GSSAPI
+      \                           SKEY
+      \                           EXTERNAL
+      \                           ANONYMOUS
+      \                           OTP
+      \                           PLAIN
+      \                           SECURID
+      \                           NTLM
+      \                           NMAS_LOGIN
+      \                           NMAS_AUTHEN
+      \                           KERBEROS_V5
+
+syn match   ldapconfSASLMechanism contained display
+      \                           'CRAM-MD5\|GSS-SPNEGO\|DIGEST-MD5\|9798-[UM]-\%(RSA-SHA1-ENC\|\%(EC\)\=DSA-SHA1\)\|NMAS-SAMBA-AUTH'
+
+" TODO: I have been unable to find a definition for a SASL realm,
+" authentication identity, and proxy authorization identity.
+syn match   ldapconfSASLRealm     contained display
+      \                           '\S\+'
+
+syn match   ldapconfSASLAuthID    contained display
+      \                           '\S\+'
+
+syn keyword ldapconfSASLSecProps  contained
+      \                           none
+      \                           noplain
+      \                           noactive
+      \                           nodict
+      \                           noanonymous
+      \                           forwardsec
+      \                           passcred
+      \                           nextgroup=ldapconfSASLSecPSep
+
+syn keyword ldapconfSASLSecProps  contained
+      \                           minssf
+      \                           maxssf
+      \                           maxbufsize
+      \                           nextgroup=ldapconfSASLSecPEq
+
+syn match   ldapconfSASLSecPEq    contained display
+      \                           '='
+      \                           nextgroup=ldapconfSASLSecFactor
+
+syn match   ldapconfSASLSecFactor contained display
+      \                           '\d\+'
+      \                           nextgroup=ldapconfSASLSecPSep
+
+syn match   ldapconfSASLSecPSep   contained display
+      \                           ','
+      \                           nextgroup=ldapconfSASLSecProps
+
+syn match   ldapconfFilename      contained display
+      \                           '.\+'
+
+syn match   ldapconfPath          contained display
+      \                           '.\+'
+
+" Defined in openssl-ciphers(1).
+" TODO: Should we include the stuff under CIPHER SUITE NAMES?
+syn cluster ldapconfTLSCipher     contains=ldapconfTLSCipherOp,
+      \                                    ldapconfTLSCipherName,
+      \                                    ldapconfTLSCipherSort
+
+syn match   ldapconfTLSCipherOp   contained display
+      \                           '[+!-]'
+      \                           nextgroup=ldapconfTLSCipherName
+
+syn keyword ldapconfTLSCipherName contained
+      \                           DEFAULT
+      \                           COMPLEMENTOFDEFAULT
+      \                           ALL
+      \                           COMPLEMENTOFALL
+      \                           HIGH
+      \                           MEDIUM
+      \                           LOW
+      \                           EXP
+      \                           EXPORT
+      \                           EXPORT40
+      \                           EXPORT56
+      \                           eNULL
+      \                           NULL
+      \                           aNULL
+      \                           kRSA
+      \                           RSA
+      \                           kEDH
+      \                           kDHr
+      \                           kDHd
+      \                           aRSA
+      \                           aDSS
+      \                           DSS
+      \                           aDH
+      \                           kFZA
+      \                           aFZA
+      \                           eFZA
+      \                           FZA
+      \                           TLSv1
+      \                           SSLv3
+      \                           SSLv2
+      \                           DH
+      \                           ADH
+      \                           AES
+      \                           3DES
+      \                           DES
+      \                           RC4
+      \                           RC2
+      \                           IDEA
+      \                           MD5
+      \                           SHA1
+      \                           SHA
+      \                           Camellia
+      \                           nextgroup=ldapconfTLSCipherSep
+
+syn match   ldapconfTLSCipherSort contained display
+      \                           '@STRENGTH'
+      \                           nextgroup=ldapconfTLSCipherSep
+
+syn match   ldapconfTLSCipherSep  contained display
+      \                           '[:, ]'
+      \                           nextgroup=@ldapconfTLSCipher
+
+syn keyword ldapconfTLSCertCheck  contained
+      \                           never
+      \                           allow
+      \                           try
+      \                           demand
+      \                           hard
+
+syn keyword ldapconfTLSCRLCheck   contained
+      \                           none
+      \                           peer
+      \                           all
+
+hi def link ldapconfTodo          Todo
+hi def link ldapconfComment       Comment
+hi def link ldapconfOption        Keyword
+hi def link ldapconfDeprOption    Error
+hi def link ldapconfString        String
+hi def link ldapconfURI           ldapconfString
+hi def link ldapconfDNAttrType    Identifier
+hi def link ldapconfOperator      Operator
+hi def link ldapconfEq            ldapconfOperator
+hi def link ldapconfDNAttrTypeEq  ldapconfEq
+hi def link ldapconfValue         ldapconfString
+hi def link ldapconfDNAttrValue   ldapconfValue
+hi def link ldapconfSeparator     ldapconfOperator
+hi def link ldapconfDNSeparator   ldapconfSeparator
+hi def link ldapconfHost          ldapconfURI
+hi def link ldapconfNumber        Number
+hi def link ldapconfPort          ldapconfNumber
+hi def link ldapconfBoolean       Boolean
+hi def link ldapconfInteger       ldapconfNumber
+hi def link ldapconfType          Type
+hi def link ldapconfDerefWhen     ldapconfType
+hi def link ldapconfDefine        Define
+hi def link ldapconfSASLMechanism ldapconfDefine
+hi def link ldapconfSASLRealm     ldapconfURI
+hi def link ldapconfSASLAuthID    ldapconfValue
+hi def link ldapconfSASLSecProps  ldapconfType
+hi def link ldapconfSASLSecPEq    ldapconfEq
+hi def link ldapconfSASLSecFactor ldapconfNumber
+hi def link ldapconfSASLSecPSep   ldapconfSeparator
+hi def link ldapconfFilename      ldapconfString
+hi def link ldapconfPath          ldapconfFilename
+hi def link ldapconfTLSCipherOp   ldapconfOperator
+hi def link ldapconfTLSCipherName ldapconfDefine
+hi def link ldapconfSpecial       Special
+hi def link ldapconfTLSCipherSort ldapconfSpecial
+hi def link ldapconfTLSCipherSep  ldapconfSeparator
+hi def link ldapconfTLSCertCheck  ldapconfType
+hi def link ldapconfTLSCRLCheck   ldapconfType
+
+let b:current_syntax = "ldapconf"
+
+let &cpo = s:cpo_save
+unlet s:cpo_save
--- /dev/null
+++ b/lib/vimfiles/syntax/ldif.vim
@@ -1,0 +1,43 @@
+" Vim syntax file
+" Language:	LDAP LDIF
+" Maintainer:	Zak Johnson <zakj@nox.cx>
+" Last Change:	2003-12-30
+
+if version < 600
+  syntax clear
+elseif exists("b:current_syntax")
+  finish
+endif
+
+syn sync minlines=10 linebreaks=1
+
+syn match ldifAttribute /^[^ #][^:]*/ contains=ldifOption display
+syn match ldifOption /;[^:]\+/ contained contains=ldifPunctuation display
+syn match ldifPunctuation /;/ contained display
+
+syn region ldifStringValue matchgroup=ldifPunctuation start=/: /  end=/\_$/ skip=/\n /
+syn region ldifBase64Value matchgroup=ldifPunctuation start=/:: / end=/\_$/ skip=/\n /
+syn region ldifFileValue   matchgroup=ldifPunctuation start=/:< / end=/\_$/ skip=/\n /
+
+syn region ldifComment start=/^#/ end=/\_$/ skip=/\n /
+
+if version >= 508 || !exists("did_ldif_syn_inits")
+  if version < 508
+    let did_ldif_syn_inits = 1
+    command -nargs=+ HiLink hi link <args>
+  else
+    command -nargs=+ HiLink hi def link <args>
+  endif
+
+  HiLink ldifAttribute		Type
+  HiLink ldifOption		Identifier
+  HiLink ldifPunctuation	Normal
+  HiLink ldifStringValue	String
+  HiLink ldifBase64Value	Special
+  HiLink ldifFileValue		Special
+  HiLink ldifComment		Comment
+
+  delcommand HiLink
+endif
+
+let b:current_syntax = "ldif"
--- /dev/null
+++ b/lib/vimfiles/syntax/lex.vim
@@ -1,0 +1,100 @@
+" Vim syntax file
+" Language:	Lex
+" Maintainer:	Dr. Charles E. Campbell, Jr. <NdrOchipS@PcampbellAfamily.Mbiz>
+" Last Change:	Sep 06, 2005
+" Version:	7
+" URL:	http://mysite.verizon.net/astronaut/vim/index.html#vimlinks_syntax
+"
+" Option:
+"   lex_uses_cpp : if this variable exists, then C++ is loaded rather than C
+
+" For version 5.x: Clear all syntax items
+" For version 6.x: Quit when a syntax file was already loaded
+if version < 600
+  syntax clear
+elseif exists("b:current_syntax")
+  finish
+endif
+
+" Read the C syntax to start with
+if version >= 600
+  if exists("lex_uses_cpp")
+    runtime! syntax/cpp.vim
+  else
+    runtime! syntax/c.vim
+  endif
+  unlet b:current_syntax
+else
+  if exists("lex_uses_cpp")
+    so <sfile>:p:h/cpp.vim
+  else
+    so <sfile>:p:h/c.vim
+  endif
+endif
+
+" --- ========= ---
+" --- Lex stuff ---
+" --- ========= ---
+
+"I'd prefer to use lex.* , but it doesn't handle forward definitions yet
+syn cluster lexListGroup		contains=lexAbbrvBlock,lexAbbrv,lexAbbrv,lexAbbrvRegExp,lexInclude,lexPatBlock,lexPat,lexBrace,lexPatString,lexPatTag,lexPatTag,lexPatComment,lexPatCodeLine,lexMorePat,lexPatSep,lexSlashQuote,lexPatCode,cInParen,cUserLabel,cOctalZero,cCppSkip,cErrInBracket,cErrInParen,cOctalError,cCppOut2,cCommentStartError,cParenError
+syn cluster lexListPatCodeGroup	contains=lexAbbrvBlock,lexAbbrv,lexAbbrv,lexAbbrvRegExp,lexInclude,lexPatBlock,lexPat,lexBrace,lexPatTag,lexPatTag,lexPatComment,lexPatCodeLine,lexMorePat,lexPatSep,lexSlashQuote,cInParen,cUserLabel,cOctalZero,cCppSkip,cErrInBracket,cErrInParen,cOctalError,cCppOut2,cCommentStartError,cParenError
+
+" Abbreviations Section
+syn region lexAbbrvBlock	start="^\(\h\+\s\|%{\)" end="^\ze%%$"	skipnl	nextgroup=lexPatBlock contains=lexAbbrv,lexInclude,lexAbbrvComment,lexStartState
+syn match  lexAbbrv		"^\I\i*\s"me=e-1			skipwhite	contained nextgroup=lexAbbrvRegExp
+syn match  lexAbbrv		"^%[sx]"					contained
+syn match  lexAbbrvRegExp	"\s\S.*$"lc=1				contained nextgroup=lexAbbrv,lexInclude
+syn region lexInclude	matchgroup=lexSep	start="^%{" end="%}"	contained	contains=ALLBUT,@lexListGroup
+syn region lexAbbrvComment	start="^\s\+/\*"	end="\*/"			contains=@Spell
+syn region lexStartState	matchgroup=lexAbbrv	start="^%\a\+"	end="$"			contained
+
+"%% : Patterns {Actions}
+syn region lexPatBlock	matchgroup=Todo	start="^%%$" matchgroup=Todo end="^%%$"	skipnl skipwhite contains=lexPat,lexPatTag,lexPatComment
+syn region lexPat		start=+\S+ skip="\\\\\|\\."	end="\s"me=e-1	contained nextgroup=lexMorePat,lexPatSep contains=lexPatString,lexSlashQuote,lexBrace
+syn region lexBrace	start="\[" skip=+\\\\\|\\+		end="]"		contained
+syn region lexPatString	matchgroup=String start=+"+	skip=+\\\\\|\\"+	matchgroup=String end=+"+	contained
+syn match  lexPatTag	"^<\I\i*\(,\I\i*\)*>*"			contained nextgroup=lexPat,lexPatTag,lexMorePat,lexPatSep
+syn match  lexPatTag	+^<\I\i*\(,\I\i*\)*>*\(\\\\\)*\\"+		contained nextgroup=lexPat,lexPatTag,lexMorePat,lexPatSep
+syn region lexPatComment	start="^\s*/\*" end="\*/"		skipnl	contained contains=cTodo skipwhite nextgroup=lexPatComment,lexPat,@Spell
+syn match  lexPatCodeLine	".*$"					contained contains=ALLBUT,@lexListGroup
+syn match  lexMorePat	"\s*|\s*$"			skipnl	contained nextgroup=lexPat,lexPatTag,lexPatComment
+syn match  lexPatSep	"\s\+"					contained nextgroup=lexMorePat,lexPatCode,lexPatCodeLine
+syn match  lexSlashQuote	+\(\\\\\)*\\"+				contained
+syn region lexPatCode matchgroup=Delimiter start="{" matchgroup=Delimiter end="}"	skipnl contained contains=ALLBUT,@lexListPatCodeGroup
+
+syn keyword lexCFunctions	BEGIN	input	unput	woutput	yyleng	yylook	yytext
+syn keyword lexCFunctions	ECHO	output	winput	wunput	yyless	yymore	yywrap
+
+" <c.vim> includes several ALLBUTs; these have to be treated so as to exclude lex* groups
+syn cluster cParenGroup	add=lex.*
+syn cluster cDefineGroup	add=lex.*
+syn cluster cPreProcGroup	add=lex.*
+syn cluster cMultiGroup	add=lex.*
+
+" Synchronization
+syn sync clear
+syn sync minlines=300
+syn sync match lexSyncPat	grouphere  lexPatBlock	"^%[a-zA-Z]"
+syn sync match lexSyncPat	groupthere lexPatBlock	"^<$"
+syn sync match lexSyncPat	groupthere lexPatBlock	"^%%$"
+
+" The default highlighting.
+hi def link lexSlashQuote	lexPat
+hi def link lexBrace	lexPat
+hi def link lexAbbrvComment	lexPatComment
+
+hi def link lexAbbrvRegExp	Macro
+hi def link lexAbbrv	SpecialChar
+hi def link lexCFunctions	Function
+hi def link lexMorePat	SpecialChar
+hi def link lexPatComment	Comment
+hi def link lexPat		Function
+hi def link lexPatString	Function
+hi def link lexPatTag	Special
+hi def link lexSep		Delimiter
+hi def link lexStartState	Statement
+
+let b:current_syntax = "lex"
+
+" vim:ts=10
--- /dev/null
+++ b/lib/vimfiles/syntax/lftp.vim
@@ -1,0 +1,152 @@
+" Vim syntax file
+" Language:         lftp(1) configuration file
+" Maintainer:       Nikolai Weibull <now@bitwi.se>
+" Latest Revision:  2006-04-19
+
+if exists("b:current_syntax")
+  finish
+endif
+
+let s:cpo_save = &cpo
+set cpo&vim
+
+setlocal iskeyword=@,48-57,-
+
+syn region  lftpComment         display oneline start='#' end='$'
+                                \ contains=lftpTodo,@Spell
+
+syn keyword lftpTodo            contained TODO FIXME XXX NOTE
+
+syn region  lftpString          contained display
+                                \ start=+"+ skip=+\\$\|\\"+ end=+"+ end=+$+
+
+syn match   lftpNumber          contained display '\<\d\+\(\.\d\+\)\=\>'
+
+syn keyword lftpBoolean         contained yes no on off true false
+
+syn keyword lftpInterval        contained infinity inf never forever
+syn match   lftpInterval        contained '\<\(\d\+\(\.\d\+\)\=[dhms]\)\+\>'
+
+syn keyword lftpKeywords        alias anon at bookmark cache cat cd chmod close
+                                \ cls command debug du echo exit fg find get
+                                \ get1 glob help history jobs kill lcd lftp
+                                \ lpwd ls mget mirror mkdir module more mput
+                                \ mrm mv nlist open pget put pwd queue quote
+                                \ reget recls rels renlist repeat reput rm
+                                \ rmdir scache site source suspend user version
+                                \ wait zcat zmore
+
+syn region  lftpSet             matchgroup=lftpKeywords
+                                \ start="set" end=";" end="$"
+                                \ contains=lftpString,lftpNumber,lftpBoolean,
+                                \ lftpInterval,lftpSettingsPrefix,lftpSettings
+syn match   lftpSettingsPrefix  contained '\<\%(bmk\|cache\|cmd\|color\|dns\):'
+syn match   lftpSettingsPrefix  contained '\<\%(file\|fish\|ftp\|hftp\):'
+syn match   lftpSettingsPrefix  contained '\<\%(http\|https\|mirror\|module\):'
+syn match   lftpSettingsPrefix  contained '\<\%(net\|sftp\|ssl\|xfer\):'
+" bmk:
+syn keyword lftpSettings        contained save-p[asswords]
+" cache:
+syn keyword lftpSettings        contained cache-em[pty-listings] en[able]
+                                \ exp[ire] siz[e]
+" cmd:
+syn keyword lftpSettings        contained at[-exit] cls-c[ompletion-default]
+                                \ cls-d[efault] cs[h-history]
+                                \ default-p[rotocol] default-t[itle]
+syn keyword lftpSettings        contained fai[l-exit] in[teractive]
+                                \ lo[ng-running] ls[-default] mo[ve-background]
+                                \ prom[pt]
+                                \ rem[ote-completion]
+                                \ save-c[wd-history] save-r[l-history]
+                                \ set-t[erm-status] statu[s-interval]
+                                \ te[rm-status] verb[ose] verify-h[ost]
+                                \ verify-path verify-path[-cached]
+" color:
+syn keyword lftpSettings        contained dir[-colors] use-c[olor]
+" dns:
+syn keyword lftpSettings        contained S[RV-query] cache-en[able]
+                                \ cache-ex[pire] cache-s[ize]
+                                \ fat[al-timeout] o[rder] use-fo[rk]
+" file:
+syn keyword lftpSettings        contained ch[arset]
+" fish:
+syn keyword lftpSettings        contained connect[-program] sh[ell]
+" ftp:
+syn keyword lftpSettings        contained acct anon-p[ass] anon-u[ser]
+                                \ au[to-sync-mode] b[ind-data-socket]
+                                \ ch[arset] cli[ent] dev[ice-prefix]
+                                \ fi[x-pasv-address] fxp-f[orce]
+                                \ fxp-p[assive-source] h[ome] la[ng]
+                                \ list-e[mpty-ok] list-o[ptions]
+                                \ nop[-interval] pas[sive-mode]
+                                \ port-i[pv4] port-r[ange] prox[y]
+                                \ rest-l[ist] rest-s[tor]
+                                \ retry-530 retry-530[-anonymous]
+                                \ sit[e-group] skey-a[llow]
+                                \ skey-f[orce] ssl-allow
+                                \ ssl-allow[-anonymous] ssl-au[th]
+                                \ ssl-f[orce] ssl-protect-d[ata]
+                                \ ssl-protect-l[ist] stat-[interval]
+                                \ sy[nc-mode] timez[one] use-a[bor]
+                                \ use-fe[at] use-fx[p] use-hf[tp]
+                                \ use-mdtm use-mdtm[-overloaded]
+                                \ use-ml[sd] use-p[ret] use-q[uit]
+                                \ use-site-c[hmod] use-site-i[dle]
+                                \ use-site-u[time] use-siz[e]
+                                \ use-st[at] use-te[lnet-iac]
+                                \ verify-a[ddress] verify-p[ort]
+                                \ w[eb-mode]
+" hftp:
+syn keyword lftpSettings        contained w[eb-mode] cache prox[y]
+                                \ use-au[thorization] use-he[ad] use-ty[pe]
+" http:
+syn keyword lftpSettings        contained accept accept-c[harset]
+                                \ accept-l[anguage] cache coo[kie]
+                                \ pos[t-content-type] prox[y]
+                                \ put-c[ontent-type] put-m[ethod] ref[erer]
+                                \ set-c[ookies] user[-agent]
+" https:
+syn keyword lftpSettings        contained prox[y]
+" mirror:
+syn keyword lftpSettings        contained exc[lude-regex] o[rder]
+                                \ parallel-d[irectories]
+                                \ parallel-t[ransfer-count] use-p[get-n]
+" module:
+syn keyword lftpSettings        contained pat[h]
+" net:
+syn keyword lftpSettings        contained connection-l[imit]
+                                \ connection-t[akeover] id[le] limit-m[ax]
+                                \ limit-r[ate] limit-total-m[ax]
+                                \ limit-total-r[ate] max-ret[ries] no-[proxy]
+                                \ pe[rsist-retries] reconnect-interval-b[ase]
+                                \ reconnect-interval-ma[x]
+                                \ reconnect-interval-mu[ltiplier]
+                                \ socket-bind-ipv4 socket-bind-ipv6
+                                \ socket-bu[ffer] socket-m[axseg] timeo[ut]
+" sftp:
+syn keyword lftpSettings        contained connect[-program]
+                                \ max-p[ackets-in-flight] prot[ocol-version]
+                                \ ser[ver-program] size-r[ead] size-w[rite]
+" ssl:
+syn keyword lftpSettings        contained ca-f[ile] ca-p[ath] ce[rt-file]
+                                \ crl-f[ile] crl-p[ath] k[ey-file]
+                                \ verify-c[ertificate]
+" xfer:
+syn keyword lftpSettings        contained clo[bber] dis[k-full-fatal]
+                                \ eta-p[eriod] eta-t[erse] mak[e-backup]
+                                \ max-red[irections] ra[te-period]
+
+hi def link lftpComment         Comment
+hi def link lftpTodo            Todo
+hi def link lftpString          String
+hi def link lftpNumber          Number
+hi def link lftpBoolean         Boolean
+hi def link lftpInterval        Number
+hi def link lftpKeywords        Keyword
+hi def link lftpSettingsPrefix  PreProc
+hi def link lftpSettings        Type
+
+let b:current_syntax = "lftp"
+
+let &cpo = s:cpo_save
+unlet s:cpo_save
--- /dev/null
+++ b/lib/vimfiles/syntax/lhaskell.vim
@@ -1,0 +1,139 @@
+" Vim syntax file
+" Language:		Haskell with literate comments, Bird style,
+"			TeX style and plain text surrounding
+"			\begin{code} \end{code} blocks
+" Maintainer:		Haskell Cafe mailinglist <haskell-cafe@haskell.org>
+" Original Author:	Arthur van Leeuwen <arthurvl@cs.uu.nl>
+" Last Change:		2004 Aug 31
+" Version:		1.01
+"
+" Thanks to Ian Lynagh for thoughtful comments on initial versions and
+" for the inspiration for writing this in the first place.
+"
+" This style guesses as to the type of markup used in a literate haskell
+" file and will highlight (La)TeX markup if it finds any
+" This behaviour can be overridden, both glabally and locally using
+" the lhs_markup variable or b:lhs_markup variable respectively.
+"
+" lhs_markup	    must be set to either  tex	or  none  to indicate that
+"		    you always want (La)TeX highlighting or no highlighting
+"		    must not be set to let the highlighting be guessed
+" b:lhs_markup	    must be set to eiterh  tex	or  none  to indicate that
+"		    you want (La)TeX highlighting or no highlighting for
+"		    this particular buffer
+"		    must not be set to let the highlighting be guessed
+"
+"
+" 2004 February 18: New version, based on Ian Lynagh's TeX guessing
+"		    lhaskell.vim, cweb.vim, tex.vim, sh.vim and fortran.vim
+" 2004 February 20: Cleaned up the guessing and overriding a bit
+" 2004 February 23: Cleaned up syntax highlighting for \begin{code} and
+"		    \end{code}, added some clarification to the attributions
+"
+
+
+" For version 5.x: Clear all syntax items
+" For version 6.x: Quit when a syntax file was already loaded
+if version < 600
+  syntax clear
+elseif exists("b:current_syntax")
+  finish
+endif
+
+" First off, see if we can inherit a user preference for lhs_markup
+if !exists("b:lhs_markup")
+    if exists("lhs_markup")
+	if lhs_markup =~ '\<\%(tex\|none\)\>'
+	    let b:lhs_markup = matchstr(lhs_markup,'\<\%(tex\|none\)\>')
+	else
+	    echohl WarningMsg | echo "Unknown value of lhs_markup" | echohl None
+	    let b:lhs_markup = "unknown"
+	endif
+    else
+	let b:lhs_markup = "unknown"
+    endif
+else
+    if b:lhs_markup !~ '\<\%(tex\|none\)\>'
+	let b:lhs_markup = "unknown"
+    endif
+endif
+
+" Remember where the cursor is, and go to upperleft
+let s:oldline=line(".")
+let s:oldcolumn=col(".")
+call cursor(1,1)
+
+" If no user preference, scan buffer for our guess of the markup to
+" highlight. We only differentiate between TeX and plain markup, where
+" plain is not highlighted. The heuristic for finding TeX markup is if
+" one of the following occurs anywhere in the file:
+"   - \documentclass
+"   - \begin{env}       (for env != code)
+"   - \part, \chapter, \section, \subsection, \subsubsection, etc
+if b:lhs_markup == "unknown"
+    if search('%\|\\documentclass\|\\begin{\(code}\)\@!\|\\\(sub\)*section\|\\chapter|\\part','W') != 0
+	let b:lhs_markup = "tex"
+    else
+	let b:lhs_markup = "plain"
+    endif
+endif
+
+" If user wants us to highlight TeX syntax, read it.
+if b:lhs_markup == "tex"
+    if version < 600
+	source <sfile>:p:h/tex.vim
+	set isk+=_
+    else
+	runtime! syntax/tex.vim
+	unlet b:current_syntax
+	" Tex.vim removes "_" from 'iskeyword', but we need it for Haskell.
+	setlocal isk+=_
+    endif
+endif
+
+" Literate Haskell is Haskell in between text, so at least read Haskell
+" highlighting
+if version < 600
+    syntax include @haskellTop <sfile>:p:h/haskell.vim
+else
+    syntax include @haskellTop syntax/haskell.vim
+endif
+
+syntax region lhsHaskellBirdTrack start="^>" end="\%(^[^>]\)\@=" contains=@haskellTop,lhsBirdTrack
+syntax region lhsHaskellBeginEndBlock start="^\\begin{code}\s*$" matchgroup=NONE end="\%(^\\end{code}.*$\)\@=" contains=@haskellTop,@beginCode
+
+syntax match lhsBirdTrack "^>" contained
+
+syntax match beginCodeBegin "^\\begin" nextgroup=beginCodeCode contained
+syntax region beginCodeCode  matchgroup=texDelimiter start="{" end="}"
+syntax cluster beginCode    contains=beginCodeBegin,beginCodeCode
+
+" Define the default highlighting.
+" For version 5.7 and earlier: only when not done already
+" For version 5.8 and later: only when an item doesn't have highlighting yet
+if version >= 508 || !exists("did_tex_syntax_inits")
+  if version < 508
+    let did_tex_syntax_inits = 1
+    command -nargs=+ HiLink hi link <args>
+  else
+    command -nargs=+ HiLink hi def link <args>
+  endif
+
+  HiLink lhsBirdTrack Comment
+
+  HiLink beginCodeBegin	      texCmdName
+  HiLink beginCodeCode	      texSection
+
+  delcommand HiLink
+endif
+
+" Restore cursor to original position, as it may have been disturbed
+" by the searches in our guessing code
+call cursor (s:oldline, s:oldcolumn)
+
+unlet s:oldline
+unlet s:oldcolumn
+
+let b:current_syntax = "lhaskell"
+
+" vim: ts=8
--- /dev/null
+++ b/lib/vimfiles/syntax/libao.vim
@@ -1,0 +1,27 @@
+" Vim syntax file
+" Language:         libao.conf(5) configuration file
+" Maintainer:       Nikolai Weibull <now@bitwi.se>
+" Latest Revision:  2006-04-19
+
+if exists("b:current_syntax")
+  finish
+endif
+
+let s:cpo_save = &cpo
+set cpo&vim
+
+syn keyword libaoTodo     contained TODO FIXME XXX NOTE
+
+syn region  libaoComment  display oneline start='^\s*#' end='$'
+                          \ contains=libaoTodo,@Spell
+
+syn keyword libaoKeyword  default_driver
+
+hi def link libaoTodo     Todo
+hi def link libaoComment  Comment
+hi def link libaoKeyword  Keyword
+
+let b:current_syntax = "libao"
+
+let &cpo = s:cpo_save
+unlet s:cpo_save
--- /dev/null
+++ b/lib/vimfiles/syntax/lifelines.vim
@@ -1,0 +1,160 @@
+" Vim syntax file
+" Language:	LifeLines (v 3.0.50) http://lifelines.sourceforge.net
+" Maintainer:	Patrick Texier <p.texier@genindre.org>
+" Location:	http://www.genindre.org/ftp/lifelines/lifelines.vim
+" Last Change:	2005 Dec 22.
+
+" option to highlight error obsolete statements
+" add the following line to your .vimrc file or here :
+" (level2 is for baptism)
+
+" let lifelines_deprecated=1
+" let lifelines_deprecated_level2=1
+
+" For version 5.x: Clear all syntax items
+" For version 6.x: Quit when a syntax file was already loaded
+
+if version < 600
+  syntax clear
+elseif exists("b:current_syntax")
+  finish
+endif
+
+" A bunch of useful lifelines keywords 3.0.50
+
+syn keyword	lifelinesStatement		set
+syn keyword	lifelinesUser			getindi geindiset getfam getint getstr choosechild
+syn keyword	lifelinesUser			chooseindi choosespouse choosesubset menuchoose
+syn keyword	lifelinesUser			choosefam 
+syn keyword	lifelinesProc			proc func return call
+syn keyword	lifelinesInclude		include
+syn keyword	lifelinesDef			global
+syn keyword	lifelinesConditional	if else elsif switch
+syn keyword	lifelinesRepeat			continue break while
+syn keyword	lifelinesLogical		and or not eq ne lt gt le ge strcmp eqstr nestr
+syn keyword	lifelinesArithm			add sub mul div mod exp neg incr decr
+syn keyword lifelinesArithm			cos sin tan arccos arcsin arctan
+syn keyword lifelinesArithm			deg2dms dms2deg spdist
+syn keyword	lifelinesIndi			name fullname surname givens trimname birth
+syn keyword	lifelinesIndi			death burial
+syn keyword	lifelinesIndi			father mother nextsib prevsib sex male female
+syn keyword	lifelinesIndi			pn nspouses nfamilies parents title key
+syn keyword	lifelinesIndi			soundex inode root indi firstindi nextindi
+syn keyword	lifelinesIndi			previndi spouses families forindi indiset
+syn keyword	lifelinesIndi			addtoset deletefromset  union intersect
+syn keyword	lifelinesIndi			difference parentset childset spouseset siblingset
+syn keyword	lifelinesIndi			ancestorset descendentset descendantset uniqueset
+syn keyword	lifelinesIndi			namesort keysort valuesort genindiset getindiset
+syn keyword	lifelinesIndi			forindiset lastindi writeindi
+syn keyword	lifelinesIndi			inset
+syn keyword	lifelinesFam			marriage husband wife nchildren firstchild
+syn keyword	lifelinesFam			lastchild fnode fam firstfam nextfam lastfam
+syn keyword	lifelinesFam			prevfam children forfam writefam
+syn keyword lifelinesFam			fathers mothers Parents
+syn keyword	lifelinesList			list empty length enqueue dequeue requeue
+syn keyword	lifelinesList			push pop setel getel forlist inlist dup clear
+syn keyword	lifelinesTable			table insert lookup
+syn keyword	lifelinesGedcom			xref tag value parent child sibling savenode
+syn keyword	lifelinesGedcom			fornodes traverse createnode addnode 
+syn keyword lifelinesGedcom			detachnode foreven fornotes forothr forsour
+syn keyword	lifelinesGedcom			reference dereference getrecord
+syn keyword	lifelinesFunct			date place year long short gettoday dayformat
+syn keyword	lifelinesFunct			monthformat dateformat extractdate eraformat
+syn keyword	lifelinesFunct			complexdate complexformat complexpic datepic
+syn keyword	lifelinesFunct			extractnames extractplaces extracttokens lower
+syn keyword lifelinesFunct			yearformat
+syn keyword	lifelinesFunct			upper capitalize trim rjustify 
+syn keyword lifelinesFunct			concat strconcat strlen substring index
+syn keyword lifelinesFunct			titlecase gettext
+syn keyword	lifelinesFunct			d card ord alpha roman strsoundex strtoint
+syn keyword	lifelinesFunct			atoi linemode pagemod col row pos pageout nl
+syn keyword	lifelinesFunct			sp qt newfile outfile copyfile print lock unlock test
+syn keyword	lifelinesFunct			database version system stddate program
+syn keyword	lifelinesFunct			pvalue pagemode level extractdatestr debug
+syn keyword	lifelinesFunct			f float int free getcol getproperty heapused
+syn keyword lifelinesFunct			sort rsort
+syn keyword lifelinesFunct			deleteel
+syn keyword lifelinesFunct			bytecode convertcode setlocale
+
+" option to highlight error obsolete statements
+" please read ll-reportmanual
+
+if exists("lifelines_deprecated")
+	syn keyword lifelinesError			getintmsg getindimsg getstrmsg
+	syn keyword	lifelinesError			gengedcom gengedcomstrong gengedcomweak deletenode
+	syn keyword lifelinesError			save strsave
+	syn keyword	lifelinesError			lengthset
+else
+	syn keyword lifelinesUser			getintmsg getindimsg getstrmsg
+	syn keyword	lifelinesGedcom			gengedcom gengedcomstrong gengedcomweak deletenode
+	syn keyword lifelinesFunct			save strsave
+	syn keyword	lifelinesIndi			lengthset
+endif
+if exists("lifelines_deprecated_level2")
+	syn keyword	lifelinesError			baptism
+else
+	syn keyword	lifelinesIndi			baptism
+endif
+
+syn region	lifelinesString		start=+L\="+ skip=+\\\\\|\\"+ end=+"+ contains=lifelinesSpecial
+
+syn match	lifelinesSpecial		"\\\(\\\|\(n\|t\)\)" contained
+
+syn region	lifelinesComment	start="/\*"  end="\*/" 
+
+" integers
+syn match	lifelinesNumber		"-\=\<\d\+\>"
+"floats, with dot
+syn match	lifelinesNumber		"-\=\<\d\+\.\d*\>"
+"floats, starting with a dot
+syn match	lifelinesNumber		"-\=\.\d\+\>"
+
+"catch errors caused by wrong parenthesis
+"adapted from original c.vim written by Bram Moolenaar
+
+syn cluster	lifelinesParenGroup	contains=lifelinesParenError
+syn region	lifelinesParen		transparent start='(' end=')' contains=ALLBUT,@lifelinesParenGroup
+syn match	lifelinesParenError	")"
+syn match	lifelinesErrInParen	contained "[{}]"
+
+" Define the default highlighting.
+" For version 5.7 and earlier: only when not done already
+" For version 5.8 and later: only when an item doesn't have highlighting yet
+
+if version >= 508 || !exists("did_lifelines_syn_inits")
+  if version < 508
+    let did_lifelines_syn_inits = 1
+    command -nargs=+ HiLink hi link <args>
+  else
+    command -nargs=+ HiLink hi def link <args>
+  endif
+
+  HiLink lifelinesConditional	Conditional
+  HiLink lifelinesArithm		Operator
+  HiLink lifelinesLogical		Conditional
+  HiLink lifelinesInclude		Include
+  HiLink lifelinesComment		Comment
+  HiLink lifelinesStatement		Statement
+  HiLink lifelinesUser			Statement
+  HiLink lifelinesFunct			Statement
+  HiLink lifelinesTable			Statement
+  HiLink lifelinesGedcom		Statement
+  HiLink lifelinesList			Statement
+  HiLink lifelinesRepeat		Repeat
+  HiLink lifelinesFam			Statement
+  HiLink lifelinesIndi			Statement
+  HiLink lifelinesProc			Statement
+  HiLink lifelinesDef			Statement
+  HiLink lifelinesString		String
+  HiLink lifelinesSpecial		Special
+  HiLink lifelinesNumber		Number
+  HiLink lifelinesParenError	Error
+  HiLink lifelinesErrInParen	Error
+  HiLink lifelinesError			Error
+
+  delcommand HiLink
+endif
+
+let b:current_syntax = "lifelines"
+
+" vim: ts=8
--- /dev/null
+++ b/lib/vimfiles/syntax/lilo.vim
@@ -1,0 +1,194 @@
+" Vim syntax file
+" This is a GENERATED FILE. Please always refer to source file at the URI below.
+" Language: lilo configuration (lilo.conf)
+" Maintainer: David Ne\v{c}as (Yeti) <yeti@physics.muni.cz>
+" Last Change: 2004-07-20
+" URL: http://trific.ath.cx/Ftp/vim/syntax/lilo.vim
+
+
+" Setup
+if version >= 600
+  if exists("b:current_syntax")
+    finish
+  endif
+else
+  syntax clear
+endif
+
+if version >= 600
+  command -nargs=1 SetIsk setlocal iskeyword=<args>
+else
+  command -nargs=1 SetIsk set iskeyword=<args>
+endif
+SetIsk @,48-57,.,-,_
+delcommand SetIsk
+
+syn case ignore
+
+" Base constructs
+syn match liloError "\S\+"
+syn match liloComment "#.*$"
+syn match liloEnviron "\$\w\+" contained
+syn match liloEnviron "\${[^}]\+}" contained
+syn match liloDecNumber "\d\+" contained
+syn match liloHexNumber "0[xX]\x\+" contained
+syn match liloDecNumberP "\d\+p\=" contained
+syn match liloSpecial contained "\\\(\"\|\\\|$\)"
+syn region liloString start=+"+ skip=+\\\\\|\\"+ end=+"+ contained contains=liloSpecial,liloEnviron
+syn match liloLabel :[^ "]\+: contained contains=liloSpecial,liloEnviron
+syn region liloPath start=+[$/]+ skip=+\\\\\|\\ \|\\$"+ end=+ \|$+ contained contains=liloSpecial,liloEnviron
+syn match liloDecNumberList "\(\d\|,\)\+" contained contains=liloDecNumber
+syn match liloDecNumberPList "\(\d\|[,p]\)\+" contained contains=liloDecNumberP,liloDecNumber
+syn region liloAnything start=+[^[:space:]#]+ skip=+\\\\\|\\ \|\\$+ end=+ \|$+ contained contains=liloSpecial,liloEnviron,liloString
+
+" Path
+syn keyword liloOption backup bitmap boot disktab force-backup keytable map message nextgroup=liloEqPath,liloEqPathComment,liloError skipwhite skipempty
+syn keyword liloKernelOpt initrd root nextgroup=liloEqPath,liloEqPathComment,liloError skipwhite skipempty
+syn keyword liloImageOpt path loader table nextgroup=liloEqPath,liloEqPathComment,liloError skipwhite skipempty
+syn keyword liloDiskOpt partition nextgroup=liloEqPath,liloEqPathComment,liloError skipwhite skipempty
+
+" Other
+syn keyword liloOption menu-scheme raid-extra-boot serial install nextgroup=liloEqAnything,liloEqAnythingComment,liloError skipwhite skipempty
+syn keyword liloOption bios-passes-dl nextgroup=liloEqAnything,liloEqAnythingComment,liloError skipwhite skipempty
+syn keyword liloOption default label alias wmdefault nextgroup=liloEqLabelString,liloEqLabelStringComment,liloError skipwhite skipempty
+syn keyword liloKernelOpt ramdisk nextgroup=liloEqAnything,liloEqAnythingComment,liloError skipwhite skipempty
+syn keyword liloImageOpt password range nextgroup=liloEqAnything,liloEqAnythingComment,liloError skipwhite skipempty
+syn keyword liloDiskOpt set type nextgroup=liloEqAnything,liloEqAnythingComment,liloError skipwhite skipempty
+
+" Symbolic
+syn keyword liloKernelOpt vga nextgroup=liloEqVga,liloEqVgaComment,liloError skipwhite skipempty
+
+" Number
+syn keyword liloOption delay timeout verbose nextgroup=liloEqDecNumber,liloEqDecNumberComment,liloError skipwhite skipempty
+syn keyword liloDiskOpt sectors heads cylinders start nextgroup=liloEqDecNumber,liloEqDecNumberComment,liloError skipwhite skipempty
+
+" String
+syn keyword liloOption menu-title nextgroup=liloEqString,liloEqStringComment,liloError skipwhite skipempty
+syn keyword liloKernelOpt append nextgroup=liloEqString,liloEqStringComment,liloError skipwhite skipempty
+syn keyword liloImageOpt fallback literal nextgroup=liloEqString,liloEqStringComment,liloError skipwhite skipempty
+
+" Hex number
+syn keyword liloImageOpt map-drive to boot-as nextgroup=liloEqHexNumber,liloEqHexNumberComment,liloError skipwhite skipempty
+syn keyword liloDiskOpt bios normal hidden nextgroup=liloEqNumber,liloEqNumberComment,liloError skipwhite skipempty
+
+" Number list
+syn keyword liloOption bmp-colors nextgroup=liloEqNumberList,liloEqNumberListComment,liloError skipwhite skipempty
+
+" Number list, some of the numbers followed by p
+syn keyword liloOption bmp-table bmp-timer nextgroup=liloEqDecNumberPList,liloEqDecNumberPListComment,liloError skipwhite skipempty
+
+" Flag
+syn keyword liloOption compact fix-table geometric ignore-table lba32 linear mandatory nowarn prompt
+syn keyword liloOption bmp-retain el-torito-bootable-CD large-memory suppress-boot-time-BIOS-data
+syn keyword liloKernelOpt read-only read-write
+syn keyword liloImageOpt bypass lock mandatory optional restricted single-key unsafe
+syn keyword liloImageOpt master-boot wmwarn wmdisable
+syn keyword liloDiskOpt change activate deactivate inaccessible reset
+
+" Image
+syn keyword liloImage image other nextgroup=liloEqPath,liloEqPathComment,liloError skipwhite skipempty
+syn keyword liloDisk disk nextgroup=liloEqPath,liloEqPathComment,liloError skipwhite skipempty
+syn keyword liloChRules change-rules
+
+" Vga keywords
+syn keyword liloVgaKeyword ask ext extended normal contained
+
+" Comment followed by equal sign and ...
+syn match liloEqPathComment "#.*$" contained nextgroup=liloEqPath,liloEqPathComment,liloError skipwhite skipempty
+syn match liloEqVgaComment "#.*$" contained nextgroup=liloEqVga,liloEqVgaComment,liloError skipwhite skipempty
+syn match liloEqNumberComment "#.*$" contained nextgroup=liloEqNumber,liloEqNumberComment,liloError skipwhite skipempty
+syn match liloEqDecNumberComment "#.*$" contained nextgroup=liloEqDecNumber,liloEqDecNumberComment,liloError skipwhite skipempty
+syn match liloEqHexNumberComment "#.*$" contained nextgroup=liloEqHexNumber,liloEqHexNumberComment,liloError skipwhite skipempty
+syn match liloEqStringComment "#.*$" contained nextgroup=liloEqString,liloEqStringComment,liloError skipwhite skipempty
+syn match liloEqLabelStringComment "#.*$" contained nextgroup=liloEqLabelString,liloEqLabelStringComment,liloError skipwhite skipempty
+syn match liloEqNumberListComment "#.*$" contained nextgroup=liloEqNumberList,liloEqNumberListComment,liloError skipwhite skipempty
+syn match liloEqDecNumberPListComment "#.*$" contained nextgroup=liloEqDecNumberPList,liloEqDecNumberPListComment,liloError skipwhite skipempty
+syn match liloEqAnythingComment "#.*$" contained nextgroup=liloEqAnything,liloEqAnythingComment,liloError skipwhite skipempty
+
+" Equal sign followed by ...
+syn match liloEqPath "=" contained nextgroup=liloPath,liloPathComment,liloError skipwhite skipempty
+syn match liloEqVga "=" contained nextgroup=liloVgaKeyword,liloHexNumber,liloDecNumber,liloVgaComment,liloError skipwhite skipempty
+syn match liloEqNumber "=" contained nextgroup=liloDecNumber,liloHexNumber,liloNumberComment,liloError skipwhite skipempty
+syn match liloEqDecNumber "=" contained nextgroup=liloDecNumber,liloDecNumberComment,liloError skipwhite skipempty
+syn match liloEqHexNumber "=" contained nextgroup=liloHexNumber,liloHexNumberComment,liloError skipwhite skipempty
+syn match liloEqString "=" contained nextgroup=liloString,liloStringComment,liloError skipwhite skipempty
+syn match liloEqLabelString "=" contained nextgroup=liloString,liloLabel,liloLabelStringComment,liloError skipwhite skipempty
+syn match liloEqNumberList "=" contained nextgroup=liloDecNumberList,liloDecNumberListComment,liloError skipwhite skipempty
+syn match liloEqDecNumberPList "=" contained nextgroup=liloDecNumberPList,liloDecNumberPListComment,liloError skipwhite skipempty
+syn match liloEqAnything "=" contained nextgroup=liloAnything,liloAnythingComment,liloError skipwhite skipempty
+
+" Comment followed by ...
+syn match liloPathComment "#.*$" contained nextgroup=liloPath,liloPathComment,liloError skipwhite skipempty
+syn match liloVgaComment "#.*$" contained nextgroup=liloVgaKeyword,liloHexNumber,liloVgaComment,liloError skipwhite skipempty
+syn match liloNumberComment "#.*$" contained nextgroup=liloDecNumber,liloHexNumber,liloNumberComment,liloError skipwhite skipempty
+syn match liloDecNumberComment "#.*$" contained nextgroup=liloDecNumber,liloDecNumberComment,liloError skipwhite skipempty
+syn match liloHexNumberComment "#.*$" contained nextgroup=liloHexNumber,liloHexNumberComment,liloError skipwhite skipempty
+syn match liloStringComment "#.*$" contained nextgroup=liloString,liloStringComment,liloError skipwhite skipempty
+syn match liloLabelStringComment "#.*$" contained nextgroup=liloString,liloLabel,liloLabelStringComment,liloError skipwhite skipempty
+syn match liloDecNumberListComment "#.*$" contained nextgroup=liloDecNumberList,liloDecNumberListComment,liloError skipwhite skipempty
+syn match liloDecNumberPListComment "#.*$" contained nextgroup=liloDecNumberPList,liloDecNumberPListComment,liloError skipwhite skipempty
+syn match liloAnythingComment "#.*$" contained nextgroup=liloAnything,liloAnythingComment,liloError skipwhite skipempty
+
+" Define the default highlighting
+if version >= 508 || !exists("did_lilo_syntax_inits")
+  if version < 508
+    let did_lilo_syntax_inits = 1
+    command -nargs=+ HiLink hi link <args>
+  else
+    command -nargs=+ HiLink hi def link <args>
+  endif
+
+  HiLink liloEqPath             liloEquals
+  HiLink liloEqWord             liloEquals
+  HiLink liloEqVga              liloEquals
+  HiLink liloEqDecNumber        liloEquals
+  HiLink liloEqHexNumber        liloEquals
+  HiLink liloEqNumber           liloEquals
+  HiLink liloEqString           liloEquals
+  HiLink liloEqAnything         liloEquals
+  HiLink liloEquals             Special
+
+  HiLink liloError              Error
+
+  HiLink liloEqPathComment      liloComment
+  HiLink liloEqVgaComment       liloComment
+  HiLink liloEqDecNumberComment liloComment
+  HiLink liloEqHexNumberComment liloComment
+  HiLink liloEqStringComment    liloComment
+  HiLink liloEqAnythingComment  liloComment
+  HiLink liloPathComment        liloComment
+  HiLink liloVgaComment         liloComment
+  HiLink liloDecNumberComment   liloComment
+  HiLink liloHexNumberComment   liloComment
+  HiLink liloNumberComment      liloComment
+  HiLink liloStringComment      liloComment
+  HiLink liloAnythingComment    liloComment
+  HiLink liloComment            Comment
+
+  HiLink liloDiskOpt            liloOption
+  HiLink liloKernelOpt          liloOption
+  HiLink liloImageOpt           liloOption
+  HiLink liloOption             Keyword
+
+  HiLink liloDecNumber          liloNumber
+  HiLink liloHexNumber          liloNumber
+  HiLink liloDecNumberP         liloNumber
+  HiLink liloNumber             Number
+  HiLink liloString             String
+  HiLink liloPath               Constant
+
+  HiLink liloSpecial            Special
+  HiLink liloLabel              Title
+  HiLink liloDecNumberList      Special
+  HiLink liloDecNumberPList     Special
+  HiLink liloAnything           Normal
+  HiLink liloEnviron            Identifier
+  HiLink liloVgaKeyword         Identifier
+  HiLink liloImage              Type
+  HiLink liloChRules            Preproc
+  HiLink liloDisk               Preproc
+
+  delcommand HiLink
+endif
+
+let b:current_syntax = "lilo"
--- /dev/null
+++ b/lib/vimfiles/syntax/limits.vim
@@ -1,0 +1,44 @@
+" Vim syntax file
+" Language:         limits(5) configuration file
+" Maintainer:       Nikolai Weibull <now@bitwi.se>
+" Latest Revision:  2006-04-19
+
+if exists("b:current_syntax")
+  finish
+endif
+
+let s:cpo_save = &cpo
+set cpo&vim
+
+syn keyword limitsTodo    contained TODO FIXME XXX NOTE
+
+syn region  limitsComment display oneline start='^\s*#' end='$'
+                          \ contains=limitsTodo,@Spell
+
+syn match   limitsBegin   display '^'
+                          \ nextgroup=limitsUser,limitsDefault,limitsComment
+                          \ skipwhite
+
+syn match   limitsUser    contained '[^ \t#*]\+'
+                          \ nextgroup=limitsLimit,limitsDeLimit skipwhite
+
+syn match   limitsDefault contained '*'
+                          \ nextgroup=limitsLimit,limitsDeLimit skipwhite
+
+syn match   limitsLimit   contained '[ACDFMNRSTUKLP]' nextgroup=limitsNumber
+syn match   limitsDeLimit contained '-'
+
+syn match   limitsNumber  contained '\d\+\>' nextgroup=limitsLimit skipwhite
+
+hi def link limitsTodo    Todo
+hi def link limitsComment Comment
+hi def link limitsUser    Keyword
+hi def link limitsDefault Macro
+hi def link limitsLimit   Identifier
+hi def link limitsDeLimit Special
+hi def link limitsNumber  Number
+
+let b:current_syntax = "limits"
+
+let &cpo = s:cpo_save
+unlet s:cpo_save
--- /dev/null
+++ b/lib/vimfiles/syntax/lisp.vim
@@ -1,0 +1,543 @@
+" Vim syntax file
+" Language:    Lisp
+" Maintainer:  Dr. Charles E. Campbell, Jr. <NdrOchipS@PcampbellAfamily.Mbiz>
+" Last Change: Apr 12, 2007
+" Version:     19
+" URL:	       http://mysite.verizon.net/astronaut/vim/index.html#vimlinks_syntax
+"
+"  Thanks to F Xavier Noria for a list of 978 Common Lisp symbols
+"  taken from the HyperSpec
+
+" ---------------------------------------------------------------------
+"  Load Once: {{{1
+" For vim-version 5.x: Clear all syntax items
+" For vim-version 6.x: Quit when a syntax file was already loaded
+if version < 600
+  syntax clear
+elseif exists("b:current_syntax")
+  finish
+endif
+
+if version >= 600
+ setlocal iskeyword=42,43,45,47-58,60-62,64-90,97-122,_
+else
+ set iskeyword=42,43,45,47-58,60-62,64-90,97-122,_
+endif
+
+" ---------------------------------------------------------------------
+" Clusters: {{{1
+syn cluster			 lispAtomCluster		  contains=lispAtomBarSymbol,lispAtomList,lispAtomNmbr0,lispComment,lispDecl,lispFunc,lispLeadWhite
+syn cluster			 lispBaseListCluster		  contains=lispAtom,lispAtomBarSymbol,lispAtomMark,lispBQList,lispBarSymbol,lispComment,lispConcat,lispDecl,lispFunc,lispKey,lispList,lispNumber,lispSpecial,lispSymbol,lispVar,lispLeadWhite
+if exists("g:lisp_instring")
+ syn cluster			 lispListCluster		  contains=@lispBaseListCluster,lispString,lispInString,lispInStringString
+else
+ syn cluster			 lispListCluster		  contains=@lispBaseListCluster,lispString
+endif
+
+syn case ignore
+
+" ---------------------------------------------------------------------
+" Lists: {{{1
+syn match			 lispSymbol			  contained			   ![^()'`,"; \t]\+!
+syn match			 lispBarSymbol			  contained			   !|..\{-}|!
+if exists("g:lisp_rainbow") && g:lisp_rainbow != 0
+ syn region lispParen0           matchgroup=hlLevel0 start="`\=(" end=")" skip="|.\{-}|" contains=@lispListCluster,lispParen1 
+ syn region lispParen1 contained matchgroup=hlLevel1 start="`\=(" end=")" skip="|.\{-}|" contains=@lispListCluster,lispParen2 
+ syn region lispParen2 contained matchgroup=hlLevel2 start="`\=(" end=")" skip="|.\{-}|" contains=@lispListCluster,lispParen3 
+ syn region lispParen3 contained matchgroup=hlLevel3 start="`\=(" end=")" skip="|.\{-}|" contains=@lispListCluster,lispParen4 
+ syn region lispParen4 contained matchgroup=hlLevel4 start="`\=(" end=")" skip="|.\{-}|" contains=@lispListCluster,lispParen5 
+ syn region lispParen5 contained matchgroup=hlLevel5 start="`\=(" end=")" skip="|.\{-}|" contains=@lispListCluster,lispParen6 
+ syn region lispParen6 contained matchgroup=hlLevel6 start="`\=(" end=")" skip="|.\{-}|" contains=@lispListCluster,lispParen7 
+ syn region lispParen7 contained matchgroup=hlLevel7 start="`\=(" end=")" skip="|.\{-}|" contains=@lispListCluster,lispParen8 
+ syn region lispParen8 contained matchgroup=hlLevel8 start="`\=(" end=")" skip="|.\{-}|" contains=@lispListCluster,lispParen9 
+ syn region lispParen9 contained matchgroup=hlLevel9 start="`\=(" end=")" skip="|.\{-}|" contains=@lispListCluster,lispParen0
+else
+ syn region			 lispList			  matchgroup=Delimiter start="("   skip="|.\{-}|"			    matchgroup=Delimiter end=")"	contains=@lispListCluster
+ syn region			 lispBQList			  matchgroup=PreProc   start="`("  skip="|.\{-}|"		    matchgroup=PreProc   end=")"		contains=@lispListCluster
+endif
+
+" ---------------------------------------------------------------------
+" Atoms: {{{1
+syn match			 lispAtomMark			  "'"
+syn match			 lispAtom			  "'("me=e-1			   contains=lispAtomMark	    nextgroup=lispAtomList
+syn match			 lispAtom			  "'[^ \t()]\+"			   contains=lispAtomMark
+syn match			 lispAtomBarSymbol		  !'|..\{-}|!			   contains=lispAtomMark
+syn region			 lispAtom			  start=+'"+			   skip=+\\"+ end=+"+
+syn region			 lispAtomList			  contained			   matchgroup=Special start="("	    skip="|.\{-}|" matchgroup=Special end=")"			      contains=@lispAtomCluster,lispString
+syn match			 lispAtomNmbr			  contained			   "\<\d\+"
+syn match			 lispLeadWhite			  contained			   "^\s\+"
+
+" ---------------------------------------------------------------------
+" Standard Lisp Functions and Macros: {{{1
+syn keyword lispFunc		 *				  find-method			   pprint-indent
+syn keyword lispFunc		 **				  find-package			   pprint-linear
+syn keyword lispFunc		 ***				  find-restart			   pprint-logical-block
+syn keyword lispFunc		 +				  find-symbol			   pprint-newline
+syn keyword lispFunc		 ++				  finish-output			   pprint-pop
+syn keyword lispFunc		 +++				  first				   pprint-tab
+syn keyword lispFunc		 -				  fixnum			   pprint-tabular
+syn keyword lispFunc		 /				  flet				   prin1
+syn keyword lispFunc		 //				  float				   prin1-to-string
+syn keyword lispFunc		 ///				  float-digits			   princ
+syn keyword lispFunc		 /=				  float-precision		   princ-to-string
+syn keyword lispFunc		 1+				  float-radix			   print
+syn keyword lispFunc		 1-				  float-sign			   print-not-readable
+syn keyword lispFunc		 <				  floating-point-inexact	   print-not-readable-object
+syn keyword lispFunc		 <=				  floating-point-invalid-operation print-object
+syn keyword lispFunc		 =				  floating-point-overflow	   print-unreadable-object
+syn keyword lispFunc		 >				  floating-point-underflow	   probe-file
+syn keyword lispFunc		 >=				  floatp			   proclaim
+syn keyword lispFunc		 abort				  floor				   prog
+syn keyword lispFunc		 abs				  fmakunbound			   prog*
+syn keyword lispFunc		 access				  force-output			   prog1
+syn keyword lispFunc		 acons				  format			   prog2
+syn keyword lispFunc		 acos				  formatter			   progn
+syn keyword lispFunc		 acosh				  fourth			   program-error
+syn keyword lispFunc		 add-method			  fresh-line			   progv
+syn keyword lispFunc		 adjoin				  fround			   provide
+syn keyword lispFunc		 adjust-array			  ftruncate			   psetf
+syn keyword lispFunc		 adjustable-array-p		  ftype				   psetq
+syn keyword lispFunc		 allocate-instance		  funcall			   push
+syn keyword lispFunc		 alpha-char-p			  function			   pushnew
+syn keyword lispFunc		 alphanumericp			  function-keywords		   putprop
+syn keyword lispFunc		 and				  function-lambda-expression	   quote
+syn keyword lispFunc		 append				  functionp			   random
+syn keyword lispFunc		 apply				  gbitp				   random-state
+syn keyword lispFunc		 applyhook			  gcd				   random-state-p
+syn keyword lispFunc		 apropos			  generic-function		   rassoc
+syn keyword lispFunc		 apropos-list			  gensym			   rassoc-if
+syn keyword lispFunc		 aref				  gentemp			   rassoc-if-not
+syn keyword lispFunc		 arithmetic-error		  get				   ratio
+syn keyword lispFunc		 arithmetic-error-operands	  get-decoded-time		   rational
+syn keyword lispFunc		 arithmetic-error-operation	  get-dispatch-macro-character	   rationalize
+syn keyword lispFunc		 array				  get-internal-real-time	   rationalp
+syn keyword lispFunc		 array-dimension		  get-internal-run-time		   read
+syn keyword lispFunc		 array-dimension-limit		  get-macro-character		   read-byte
+syn keyword lispFunc		 array-dimensions		  get-output-stream-string	   read-char
+syn keyword lispFunc		 array-displacement		  get-properties		   read-char-no-hang
+syn keyword lispFunc		 array-element-type		  get-setf-expansion		   read-delimited-list
+syn keyword lispFunc		 array-has-fill-pointer-p	  get-setf-method		   read-eval-print
+syn keyword lispFunc		 array-in-bounds-p		  get-universal-time		   read-from-string
+syn keyword lispFunc		 array-rank			  getf				   read-line
+syn keyword lispFunc		 array-rank-limit		  gethash			   read-preserving-whitespace
+syn keyword lispFunc		 array-row-major-index		  go				   read-sequence
+syn keyword lispFunc		 array-total-size		  graphic-char-p		   reader-error
+syn keyword lispFunc		 array-total-size-limit		  handler-bind			   readtable
+syn keyword lispFunc		 arrayp				  handler-case			   readtable-case
+syn keyword lispFunc		 ash				  hash-table			   readtablep
+syn keyword lispFunc		 asin				  hash-table-count		   real
+syn keyword lispFunc		 asinh				  hash-table-p			   realp
+syn keyword lispFunc		 assert				  hash-table-rehash-size	   realpart
+syn keyword lispFunc		 assoc				  hash-table-rehash-threshold	   reduce
+syn keyword lispFunc		 assoc-if			  hash-table-size		   reinitialize-instance
+syn keyword lispFunc		 assoc-if-not			  hash-table-test		   rem
+syn keyword lispFunc		 atan				  host-namestring		   remf
+syn keyword lispFunc		 atanh				  identity			   remhash
+syn keyword lispFunc		 atom				  if				   remove
+syn keyword lispFunc		 base-char			  if-exists			   remove-duplicates
+syn keyword lispFunc		 base-string			  ignorable			   remove-if
+syn keyword lispFunc		 bignum				  ignore			   remove-if-not
+syn keyword lispFunc		 bit				  ignore-errors			   remove-method
+syn keyword lispFunc		 bit-and			  imagpart			   remprop
+syn keyword lispFunc		 bit-andc1			  import			   rename-file
+syn keyword lispFunc		 bit-andc2			  in-package			   rename-package
+syn keyword lispFunc		 bit-eqv			  in-package			   replace
+syn keyword lispFunc		 bit-ior			  incf				   require
+syn keyword lispFunc		 bit-nand			  initialize-instance		   rest
+syn keyword lispFunc		 bit-nor			  inline			   restart
+syn keyword lispFunc		 bit-not			  input-stream-p		   restart-bind
+syn keyword lispFunc		 bit-orc1			  inspect			   restart-case
+syn keyword lispFunc		 bit-orc2			  int-char			   restart-name
+syn keyword lispFunc		 bit-vector			  integer			   return
+syn keyword lispFunc		 bit-vector-p			  integer-decode-float		   return-from
+syn keyword lispFunc		 bit-xor			  integer-length		   revappend
+syn keyword lispFunc		 block				  integerp			   reverse
+syn keyword lispFunc		 boole				  interactive-stream-p		   room
+syn keyword lispFunc		 boole-1			  intern			   rotatef
+syn keyword lispFunc		 boole-2			  internal-time-units-per-second   round
+syn keyword lispFunc		 boole-and			  intersection			   row-major-aref
+syn keyword lispFunc		 boole-andc1			  invalid-method-error		   rplaca
+syn keyword lispFunc		 boole-andc2			  invoke-debugger		   rplacd
+syn keyword lispFunc		 boole-c1			  invoke-restart		   safety
+syn keyword lispFunc		 boole-c2			  invoke-restart-interactively	   satisfies
+syn keyword lispFunc		 boole-clr			  isqrt				   sbit
+syn keyword lispFunc		 boole-eqv			  keyword			   scale-float
+syn keyword lispFunc		 boole-ior			  keywordp			   schar
+syn keyword lispFunc		 boole-nand			  labels			   search
+syn keyword lispFunc		 boole-nor			  lambda			   second
+syn keyword lispFunc		 boole-orc1			  lambda-list-keywords		   sequence
+syn keyword lispFunc		 boole-orc2			  lambda-parameters-limit	   serious-condition
+syn keyword lispFunc		 boole-set			  last				   set
+syn keyword lispFunc		 boole-xor			  lcm				   set-char-bit
+syn keyword lispFunc		 boolean			  ldb				   set-difference
+syn keyword lispFunc		 both-case-p			  ldb-test			   set-dispatch-macro-character
+syn keyword lispFunc		 boundp				  ldiff				   set-exclusive-or
+syn keyword lispFunc		 break				  least-negative-double-float	   set-macro-character
+syn keyword lispFunc		 broadcast-stream		  least-negative-long-float	   set-pprint-dispatch
+syn keyword lispFunc		 broadcast-stream-streams	  least-negative-normalized-double-float			    set-syntax-from-char
+syn keyword lispFunc		 built-in-class			  least-negative-normalized-long-float				    setf
+syn keyword lispFunc		 butlast			  least-negative-normalized-short-float				    setq
+syn keyword lispFunc		 byte				  least-negative-normalized-single-float			    seventh
+syn keyword lispFunc		 byte-position			  least-negative-short-float	   shadow
+syn keyword lispFunc		 byte-size			  least-negative-single-float	   shadowing-import
+syn keyword lispFunc		 call-arguments-limit		  least-positive-double-float	   shared-initialize
+syn keyword lispFunc		 call-method			  least-positive-long-float	   shiftf
+syn keyword lispFunc		 call-next-method		  least-positive-normalized-double-float			    short-float
+syn keyword lispFunc		 capitalize			  least-positive-normalized-long-float				    short-float-epsilon
+syn keyword lispFunc		 car				  least-positive-normalized-short-float				    short-float-negative-epsilon
+syn keyword lispFunc		 case				  least-positive-normalized-single-float			    short-site-name
+syn keyword lispFunc		 catch				  least-positive-short-float	   signal
+syn keyword lispFunc		 ccase				  least-positive-single-float	   signed-byte
+syn keyword lispFunc		 cdr				  length			   signum
+syn keyword lispFunc		 ceiling			  let				   simle-condition
+syn keyword lispFunc		 cell-error			  let*				   simple-array
+syn keyword lispFunc		 cell-error-name		  lisp				   simple-base-string
+syn keyword lispFunc		 cerror				  lisp-implementation-type	   simple-bit-vector
+syn keyword lispFunc		 change-class			  lisp-implementation-version	   simple-bit-vector-p
+syn keyword lispFunc		 char				  list				   simple-condition-format-arguments
+syn keyword lispFunc		 char-bit			  list*				   simple-condition-format-control
+syn keyword lispFunc		 char-bits			  list-all-packages		   simple-error
+syn keyword lispFunc		 char-bits-limit		  list-length			   simple-string
+syn keyword lispFunc		 char-code			  listen			   simple-string-p
+syn keyword lispFunc		 char-code-limit		  listp				   simple-type-error
+syn keyword lispFunc		 char-control-bit		  load				   simple-vector
+syn keyword lispFunc		 char-downcase			  load-logical-pathname-translations				    simple-vector-p
+syn keyword lispFunc		 char-equal			  load-time-value		   simple-warning
+syn keyword lispFunc		 char-font			  locally			   sin
+syn keyword lispFunc		 char-font-limit		  log				   single-flaot-epsilon
+syn keyword lispFunc		 char-greaterp			  logand			   single-float
+syn keyword lispFunc		 char-hyper-bit			  logandc1			   single-float-epsilon
+syn keyword lispFunc		 char-int			  logandc2			   single-float-negative-epsilon
+syn keyword lispFunc		 char-lessp			  logbitp			   sinh
+syn keyword lispFunc		 char-meta-bit			  logcount			   sixth
+syn keyword lispFunc		 char-name			  logeqv			   sleep
+syn keyword lispFunc		 char-not-equal			  logical-pathname		   slot-boundp
+syn keyword lispFunc		 char-not-greaterp		  logical-pathname-translations	   slot-exists-p
+syn keyword lispFunc		 char-not-lessp			  logior			   slot-makunbound
+syn keyword lispFunc		 char-super-bit			  lognand			   slot-missing
+syn keyword lispFunc		 char-upcase			  lognor			   slot-unbound
+syn keyword lispFunc		 char/=				  lognot			   slot-value
+syn keyword lispFunc		 char<				  logorc1			   software-type
+syn keyword lispFunc		 char<=				  logorc2			   software-version
+syn keyword lispFunc		 char=				  logtest			   some
+syn keyword lispFunc		 char>				  logxor			   sort
+syn keyword lispFunc		 char>=				  long-float			   space
+syn keyword lispFunc		 character			  long-float-epsilon		   special
+syn keyword lispFunc		 characterp			  long-float-negative-epsilon	   special-form-p
+syn keyword lispFunc		 check-type			  long-site-name		   special-operator-p
+syn keyword lispFunc		 cis				  loop				   speed
+syn keyword lispFunc		 class				  loop-finish			   sqrt
+syn keyword lispFunc		 class-name			  lower-case-p			   stable-sort
+syn keyword lispFunc		 class-of			  machine-instance		   standard
+syn keyword lispFunc		 clear-input			  machine-type			   standard-char
+syn keyword lispFunc		 clear-output			  machine-version		   standard-char-p
+syn keyword lispFunc		 close				  macro-function		   standard-class
+syn keyword lispFunc		 clrhash			  macroexpand			   standard-generic-function
+syn keyword lispFunc		 code-char			  macroexpand-1			   standard-method
+syn keyword lispFunc		 coerce				  macroexpand-l			   standard-object
+syn keyword lispFunc		 commonp			  macrolet			   step
+syn keyword lispFunc		 compilation-speed		  make-array			   storage-condition
+syn keyword lispFunc		 compile			  make-array			   store-value
+syn keyword lispFunc		 compile-file			  make-broadcast-stream		   stream
+syn keyword lispFunc		 compile-file-pathname		  make-char			   stream-element-type
+syn keyword lispFunc		 compiled-function		  make-concatenated-stream	   stream-error
+syn keyword lispFunc		 compiled-function-p		  make-condition		   stream-error-stream
+syn keyword lispFunc		 compiler-let			  make-dispatch-macro-character	   stream-external-format
+syn keyword lispFunc		 compiler-macro			  make-echo-stream		   streamp
+syn keyword lispFunc		 compiler-macro-function	  make-hash-table		   streamup
+syn keyword lispFunc		 complement			  make-instance			   string
+syn keyword lispFunc		 complex			  make-instances-obsolete	   string-capitalize
+syn keyword lispFunc		 complexp			  make-list			   string-char
+syn keyword lispFunc		 compute-applicable-methods	  make-load-form		   string-char-p
+syn keyword lispFunc		 compute-restarts		  make-load-form-saving-slots	   string-downcase
+syn keyword lispFunc		 concatenate			  make-method			   string-equal
+syn keyword lispFunc		 concatenated-stream		  make-package			   string-greaterp
+syn keyword lispFunc		 concatenated-stream-streams	  make-pathname			   string-left-trim
+syn keyword lispFunc		 cond				  make-random-state		   string-lessp
+syn keyword lispFunc		 condition			  make-sequence			   string-not-equal
+syn keyword lispFunc		 conjugate			  make-string			   string-not-greaterp
+syn keyword lispFunc		 cons				  make-string-input-stream	   string-not-lessp
+syn keyword lispFunc		 consp				  make-string-output-stream	   string-right-strim
+syn keyword lispFunc		 constantly			  make-symbol			   string-right-trim
+syn keyword lispFunc		 constantp			  make-synonym-stream		   string-stream
+syn keyword lispFunc		 continue			  make-two-way-stream		   string-trim
+syn keyword lispFunc		 control-error			  makunbound			   string-upcase
+syn keyword lispFunc		 copy-alist			  map				   string/=
+syn keyword lispFunc		 copy-list			  map-into			   string<
+syn keyword lispFunc		 copy-pprint-dispatch		  mapc				   string<=
+syn keyword lispFunc		 copy-readtable			  mapcan			   string=
+syn keyword lispFunc		 copy-seq			  mapcar			   string>
+syn keyword lispFunc		 copy-structure			  mapcon			   string>=
+syn keyword lispFunc		 copy-symbol			  maphash			   stringp
+syn keyword lispFunc		 copy-tree			  mapl				   structure
+syn keyword lispFunc		 cos				  maplist			   structure-class
+syn keyword lispFunc		 cosh				  mask-field			   structure-object
+syn keyword lispFunc		 count				  max				   style-warning
+syn keyword lispFunc		 count-if			  member			   sublim
+syn keyword lispFunc		 count-if-not			  member-if			   sublis
+syn keyword lispFunc		 ctypecase			  member-if-not			   subseq
+syn keyword lispFunc		 debug				  merge				   subsetp
+syn keyword lispFunc		 decf				  merge-pathname		   subst
+syn keyword lispFunc		 declaim			  merge-pathnames		   subst-if
+syn keyword lispFunc		 declaration			  method			   subst-if-not
+syn keyword lispFunc		 declare			  method-combination		   substitute
+syn keyword lispFunc		 decode-float			  method-combination-error	   substitute-if
+syn keyword lispFunc		 decode-universal-time		  method-qualifiers		   substitute-if-not
+syn keyword lispFunc		 defclass			  min				   subtypep
+syn keyword lispFunc		 defconstant			  minusp			   svref
+syn keyword lispFunc		 defgeneric			  mismatch			   sxhash
+syn keyword lispFunc		 define-compiler-macro		  mod				   symbol
+syn keyword lispFunc		 define-condition		  most-negative-double-float	   symbol-function
+syn keyword lispFunc		 define-method-combination	  most-negative-fixnum		   symbol-macrolet
+syn keyword lispFunc		 define-modify-macro		  most-negative-long-float	   symbol-name
+syn keyword lispFunc		 define-setf-expander		  most-negative-short-float	   symbol-package
+syn keyword lispFunc		 define-setf-method		  most-negative-single-float	   symbol-plist
+syn keyword lispFunc		 define-symbol-macro		  most-positive-double-float	   symbol-value
+syn keyword lispFunc		 defmacro			  most-positive-fixnum		   symbolp
+syn keyword lispFunc		 defmethod			  most-positive-long-float	   synonym-stream
+syn keyword lispFunc		 defpackage			  most-positive-short-float	   synonym-stream-symbol
+syn keyword lispFunc		 defparameter			  most-positive-single-float	   sys
+syn keyword lispFunc		 defsetf			  muffle-warning		   system
+syn keyword lispFunc		 defstruct			  multiple-value-bind		   t
+syn keyword lispFunc		 deftype			  multiple-value-call		   tagbody
+syn keyword lispFunc		 defun				  multiple-value-list		   tailp
+syn keyword lispFunc		 defvar				  multiple-value-prog1		   tan
+syn keyword lispFunc		 delete				  multiple-value-seteq		   tanh
+syn keyword lispFunc		 delete-duplicates		  multiple-value-setq		   tenth
+syn keyword lispFunc		 delete-file			  multiple-values-limit		   terpri
+syn keyword lispFunc		 delete-if			  name-char			   the
+syn keyword lispFunc		 delete-if-not			  namestring			   third
+syn keyword lispFunc		 delete-package			  nbutlast			   throw
+syn keyword lispFunc		 denominator			  nconc				   time
+syn keyword lispFunc		 deposit-field			  next-method-p			   trace
+syn keyword lispFunc		 describe			  nil				   translate-logical-pathname
+syn keyword lispFunc		 describe-object		  nintersection			   translate-pathname
+syn keyword lispFunc		 destructuring-bind		  ninth				   tree-equal
+syn keyword lispFunc		 digit-char			  no-applicable-method		   truename
+syn keyword lispFunc		 digit-char-p			  no-next-method		   truncase
+syn keyword lispFunc		 directory			  not				   truncate
+syn keyword lispFunc		 directory-namestring		  notany			   two-way-stream
+syn keyword lispFunc		 disassemble			  notevery			   two-way-stream-input-stream
+syn keyword lispFunc		 division-by-zero		  notinline			   two-way-stream-output-stream
+syn keyword lispFunc		 do				  nreconc			   type
+syn keyword lispFunc		 do*				  nreverse			   type-error
+syn keyword lispFunc		 do-all-symbols			  nset-difference		   type-error-datum
+syn keyword lispFunc		 do-exeternal-symbols		  nset-exclusive-or		   type-error-expected-type
+syn keyword lispFunc		 do-external-symbols		  nstring			   type-of
+syn keyword lispFunc		 do-symbols			  nstring-capitalize		   typecase
+syn keyword lispFunc		 documentation			  nstring-downcase		   typep
+syn keyword lispFunc		 dolist				  nstring-upcase		   unbound-slot
+syn keyword lispFunc		 dotimes			  nsublis			   unbound-slot-instance
+syn keyword lispFunc		 double-float			  nsubst			   unbound-variable
+syn keyword lispFunc		 double-float-epsilon		  nsubst-if			   undefined-function
+syn keyword lispFunc		 double-float-negative-epsilon	  nsubst-if-not			   unexport
+syn keyword lispFunc		 dpb				  nsubstitute			   unintern
+syn keyword lispFunc		 dribble			  nsubstitute-if		   union
+syn keyword lispFunc		 dynamic-extent			  nsubstitute-if-not		   unless
+syn keyword lispFunc		 ecase				  nth				   unread
+syn keyword lispFunc		 echo-stream			  nth-value			   unread-char
+syn keyword lispFunc		 echo-stream-input-stream	  nthcdr			   unsigned-byte
+syn keyword lispFunc		 echo-stream-output-stream	  null				   untrace
+syn keyword lispFunc		 ed				  number			   unuse-package
+syn keyword lispFunc		 eighth				  numberp			   unwind-protect
+syn keyword lispFunc		 elt				  numerator			   update-instance-for-different-class
+syn keyword lispFunc		 encode-universal-time		  nunion			   update-instance-for-redefined-class
+syn keyword lispFunc		 end-of-file			  oddp				   upgraded-array-element-type
+syn keyword lispFunc		 endp				  open				   upgraded-complex-part-type
+syn keyword lispFunc		 enough-namestring		  open-stream-p			   upper-case-p
+syn keyword lispFunc		 ensure-directories-exist	  optimize			   use-package
+syn keyword lispFunc		 ensure-generic-function	  or				   use-value
+syn keyword lispFunc		 eq				  otherwise			   user
+syn keyword lispFunc		 eql				  output-stream-p		   user-homedir-pathname
+syn keyword lispFunc		 equal				  package			   values
+syn keyword lispFunc		 equalp				  package-error			   values-list
+syn keyword lispFunc		 error				  package-error-package		   vector
+syn keyword lispFunc		 etypecase			  package-name			   vector-pop
+syn keyword lispFunc		 eval				  package-nicknames		   vector-push
+syn keyword lispFunc		 eval-when			  package-shadowing-symbols	   vector-push-extend
+syn keyword lispFunc		 evalhook			  package-use-list		   vectorp
+syn keyword lispFunc		 evenp				  package-used-by-list		   warn
+syn keyword lispFunc		 every				  packagep			   warning
+syn keyword lispFunc		 exp				  pairlis			   when
+syn keyword lispFunc		 export				  parse-error			   wild-pathname-p
+syn keyword lispFunc		 expt				  parse-integer			   with-accessors
+syn keyword lispFunc		 extended-char			  parse-namestring		   with-compilation-unit
+syn keyword lispFunc		 fboundp			  pathname			   with-condition-restarts
+syn keyword lispFunc		 fceiling			  pathname-device		   with-hash-table-iterator
+syn keyword lispFunc		 fdefinition			  pathname-directory		   with-input-from-string
+syn keyword lispFunc		 ffloor				  pathname-host			   with-open-file
+syn keyword lispFunc		 fifth				  pathname-match-p		   with-open-stream
+syn keyword lispFunc		 file-author			  pathname-name			   with-output-to-string
+syn keyword lispFunc		 file-error			  pathname-type			   with-package-iterator
+syn keyword lispFunc		 file-error-pathname		  pathname-version		   with-simple-restart
+syn keyword lispFunc		 file-length			  pathnamep			   with-slots
+syn keyword lispFunc		 file-namestring		  peek-char			   with-standard-io-syntax
+syn keyword lispFunc		 file-position			  phase				   write
+syn keyword lispFunc		 file-stream			  pi				   write-byte
+syn keyword lispFunc		 file-string-length		  plusp				   write-char
+syn keyword lispFunc		 file-write-date		  pop				   write-line
+syn keyword lispFunc		 fill				  position			   write-sequence
+syn keyword lispFunc		 fill-pointer			  position-if			   write-string
+syn keyword lispFunc		 find				  position-if-not		   write-to-string
+syn keyword lispFunc		 find-all-symbols		  pprint			   y-or-n-p
+syn keyword lispFunc		 find-class			  pprint-dispatch		   yes-or-no-p
+syn keyword lispFunc		 find-if			  pprint-exit-if-list-exhausted	   zerop
+syn keyword lispFunc		 find-if-not			  pprint-fill
+
+syn match   lispFunc		 "\<c[ad]\+r\>"
+
+" ---------------------------------------------------------------------
+" Lisp Keywords (modifiers): {{{1
+syn keyword lispKey		 :abort				  :from-end			   :overwrite
+syn keyword lispKey		 :adjustable			  :gensym			   :predicate
+syn keyword lispKey		 :append			  :host				   :preserve-whitespace
+syn keyword lispKey		 :array				  :if-does-not-exist		   :pretty
+syn keyword lispKey		 :base				  :if-exists			   :print
+syn keyword lispKey		 :case				  :include			   :print-function
+syn keyword lispKey		 :circle			  :index			   :probe
+syn keyword lispKey		 :conc-name			  :inherited			   :radix
+syn keyword lispKey		 :constructor			  :initial-contents		   :read-only
+syn keyword lispKey		 :copier			  :initial-element		   :rehash-size
+syn keyword lispKey		 :count				  :initial-offset		   :rehash-threshold
+syn keyword lispKey		 :create			  :initial-value		   :rename
+syn keyword lispKey		 :default			  :input			   :rename-and-delete
+syn keyword lispKey		 :defaults			  :internal			   :size
+syn keyword lispKey		 :device			  :io				   :start
+syn keyword lispKey		 :direction			  :junk-allowed			   :start1
+syn keyword lispKey		 :directory			  :key				   :start2
+syn keyword lispKey		 :displaced-index-offset	  :length			   :stream
+syn keyword lispKey		 :displaced-to			  :level			   :supersede
+syn keyword lispKey		 :element-type			  :name				   :test
+syn keyword lispKey		 :end				  :named			   :test-not
+syn keyword lispKey		 :end1				  :new-version			   :type
+syn keyword lispKey		 :end2				  :nicknames			   :use
+syn keyword lispKey		 :error				  :output			   :verbose
+syn keyword lispKey		 :escape			  :output-file			   :version
+syn keyword lispKey		 :external
+
+" ---------------------------------------------------------------------
+" Standard Lisp Variables: {{{1
+syn keyword lispVar		 *applyhook*			  *load-pathname*		   *print-pprint-dispatch*
+syn keyword lispVar		 *break-on-signals*		  *load-print*			   *print-pprint-dispatch*
+syn keyword lispVar		 *break-on-signals*		  *load-truename*		   *print-pretty*
+syn keyword lispVar		 *break-on-warnings*		  *load-verbose*		   *print-radix*
+syn keyword lispVar		 *compile-file-pathname*	  *macroexpand-hook*		   *print-readably*
+syn keyword lispVar		 *compile-file-pathname*	  *modules*			   *print-right-margin*
+syn keyword lispVar		 *compile-file-truename*	  *package*			   *print-right-margin*
+syn keyword lispVar		 *compile-file-truename*	  *print-array*			   *query-io*
+syn keyword lispVar		 *compile-print*		  *print-base*			   *random-state*
+syn keyword lispVar		 *compile-verbose*		  *print-case*			   *read-base*
+syn keyword lispVar		 *compile-verbose*		  *print-circle*		   *read-default-float-format*
+syn keyword lispVar		 *debug-io*			  *print-escape*		   *read-eval*
+syn keyword lispVar		 *debugger-hook*		  *print-gensym*		   *read-suppress*
+syn keyword lispVar		 *default-pathname-defaults*	  *print-length*		   *readtable*
+syn keyword lispVar		 *error-output*			  *print-level*			   *standard-input*
+syn keyword lispVar		 *evalhook*			  *print-lines*			   *standard-output*
+syn keyword lispVar		 *features*			  *print-miser-width*		   *terminal-io*
+syn keyword lispVar		 *gensym-counter*		  *print-miser-width*		   *trace-output*
+
+" ---------------------------------------------------------------------
+" Strings: {{{1
+syn region			 lispString			  start=+"+ skip=+\\\\\|\\"+ end=+"+	contains=@Spell
+if exists("g:lisp_instring")
+ syn region			 lispInString			  keepend matchgroup=Delimiter start=+"(+rs=s+1 skip=+|.\{-}|+ matchgroup=Delimiter end=+)"+ contains=@lispBaseListCluster,lispInStringString
+ syn region			 lispInStringString		  start=+\\"+ skip=+\\\\+ end=+\\"+ contained
+endif
+
+" ---------------------------------------------------------------------
+" Shared with Xlisp, Declarations, Macros, Functions: {{{1
+syn keyword lispDecl		 defmacro			  do-all-symbols		   labels
+syn keyword lispDecl		 defsetf			  do-external-symbols		   let
+syn keyword lispDecl		 deftype			  do-symbols			   locally
+syn keyword lispDecl		 defun				  dotimes			   macrolet
+syn keyword lispDecl		 do*				  flet				   multiple-value-bind
+
+" ---------------------------------------------------------------------
+" Numbers: supporting integers and floating point numbers {{{1
+syn match lispNumber		 "-\=\(\.\d\+\|\d\+\(\.\d*\)\=\)\(e[-+]\=\d\+\)\="
+
+syn match lispSpecial		 "\*\w[a-z_0-9-]*\*"
+syn match lispSpecial		 !#|[^()'`,"; \t]\+|#!
+syn match lispSpecial		 !#x\x\+!
+syn match lispSpecial		 !#o\o\+!
+syn match lispSpecial		 !#b[01]\+!
+syn match lispSpecial		 !#\\[ -}\~]!
+syn match lispSpecial		 !#[':][^()'`,"; \t]\+!
+syn match lispSpecial		 !#([^()'`,"; \t]\+)!
+syn match lispSpecial		 !#\\\%(Space\|Newline\|Tab\|Page\|Rubout\|Linefeed\|Return\|Backspace\)!
+
+syn match lispConcat		 "\s\.\s"
+syn match lispParenError	 ")"
+
+" ---------------------------------------------------------------------
+" Comments: {{{1
+syn cluster lispCommentGroup	 contains=lispTodo,@Spell
+syn match   lispComment		 ";.*$"				  contains=@lispCommentGroup
+syn region  lispCommentRegion	 start="#|" end="|#"		  contains=lispCommentRegion,@lispCommentGroup
+syn keyword lispTodo		 contained			  combak			   combak:			    todo			     todo:
+
+" ---------------------------------------------------------------------
+" Synchronization: {{{1
+syn sync lines=100
+
+" ---------------------------------------------------------------------
+" Define Highlighting: {{{1
+" For version 5.7 and earlier: only when not done already
+" For version 5.8 and later: only when an item doesn't have highlighting yet
+if version >= 508
+  command -nargs=+ HiLink hi def link <args>
+
+  HiLink lispCommentRegion	 lispComment
+  HiLink lispAtomNmbr		 lispNumber
+  HiLink lispAtomMark		 lispMark
+  HiLink lispInStringString	 lispString
+
+  HiLink lispAtom		 Identifier
+  HiLink lispAtomBarSymbol	 Special
+  HiLink lispBarSymbol		 Special
+  HiLink lispComment		 Comment
+  HiLink lispConcat		 Statement
+  HiLink lispDecl		 Statement
+  HiLink lispFunc		 Statement
+  HiLink lispKey		 Type
+  HiLink lispMark		 Delimiter
+  HiLink lispNumber		 Number
+  HiLink lispParenError		 Error
+  HiLink lispSpecial		 Type
+  HiLink lispString		 String
+  HiLink lispTodo		 Todo
+  HiLink lispVar		 Statement
+
+  if exists("g:lisp_rainbow") && g:lisp_rainbow != 0
+   if &bg == "dark"
+    hi def hlLevel0 ctermfg=red         guifg=red1
+    hi def hlLevel1 ctermfg=yellow      guifg=orange1      
+    hi def hlLevel2 ctermfg=green       guifg=yellow1      
+    hi def hlLevel3 ctermfg=cyan        guifg=greenyellow  
+    hi def hlLevel4 ctermfg=magenta     guifg=green1       
+    hi def hlLevel5 ctermfg=red         guifg=springgreen1 
+    hi def hlLevel6 ctermfg=yellow      guifg=cyan1        
+    hi def hlLevel7 ctermfg=green       guifg=slateblue1   
+    hi def hlLevel8 ctermfg=cyan        guifg=magenta1     
+    hi def hlLevel9 ctermfg=magenta     guifg=purple1
+   else
+    hi def hlLevel0 ctermfg=red         guifg=red3
+    hi def hlLevel1 ctermfg=darkyellow  guifg=orangered3
+    hi def hlLevel2 ctermfg=darkgreen   guifg=orange2
+    hi def hlLevel3 ctermfg=blue        guifg=yellow3
+    hi def hlLevel4 ctermfg=darkmagenta guifg=olivedrab4
+    hi def hlLevel5 ctermfg=red         guifg=green4
+    hi def hlLevel6 ctermfg=darkyellow  guifg=paleturquoise3
+    hi def hlLevel7 ctermfg=darkgreen   guifg=deepskyblue4
+    hi def hlLevel8 ctermfg=blue        guifg=darkslateblue
+    hi def hlLevel9 ctermfg=darkmagenta guifg=darkviolet
+   endif
+  endif
+
+  delcommand HiLink
+endif
+
+let b:current_syntax = "lisp"
+
+" ---------------------------------------------------------------------
+" vim: ts=8 nowrap fdm=marker
--- /dev/null
+++ b/lib/vimfiles/syntax/lite.vim
@@ -1,0 +1,181 @@
+" Vim syntax file
+" Language:	lite
+" Maintainer:	Lutz Eymers <ixtab@polzin.com>
+" URL:		http://www.isp.de/data/lite.vim
+" Email:	Subject: send syntax_vim.tgz
+" Last Change:	2001 Mai 01
+"
+" Options	lite_sql_query = 1 for SQL syntax highligthing inside strings
+"		lite_minlines = x     to sync at least x lines backwards
+
+" For version 5.x: Clear all syntax items
+" For version 6.x: Quit when a syntax file was already loaded
+if version < 600
+  syntax clear
+elseif exists("b:current_syntax")
+  finish
+endif
+
+if !exists("main_syntax")
+  let main_syntax = 'lite'
+endif
+
+if main_syntax == 'lite'
+  if exists("lite_sql_query")
+    if lite_sql_query == 1
+      syn include @liteSql <sfile>:p:h/sql.vim
+      unlet b:current_syntax
+    endif
+  endif
+endif
+
+if main_syntax == 'msql'
+  if exists("msql_sql_query")
+    if msql_sql_query == 1
+      syn include @liteSql <sfile>:p:h/sql.vim
+      unlet b:current_syntax
+    endif
+  endif
+endif
+
+syn cluster liteSql remove=sqlString,sqlComment
+
+syn case match
+
+" Internal Variables
+syn keyword liteIntVar ERRMSG contained
+
+" Comment
+syn region liteComment		start="/\*" end="\*/" contains=liteTodo
+
+" Function names
+syn keyword liteFunctions  echo printf fprintf open close read
+syn keyword liteFunctions  readln readtok
+syn keyword liteFunctions  split strseg chop tr sub substr
+syn keyword liteFunctions  test unlink umask chmod mkdir chdir rmdir
+syn keyword liteFunctions  rename truncate link symlink stat
+syn keyword liteFunctions  sleep system getpid getppid kill
+syn keyword liteFunctions  time ctime time2unixtime unixtime2year
+syn keyword liteFunctions  unixtime2year unixtime2month unixtime2day
+syn keyword liteFunctions  unixtime2hour unixtime2min unixtime2sec
+syn keyword liteFunctions  strftime
+syn keyword liteFunctions  getpwnam getpwuid
+syn keyword liteFunctions  gethostbyname gethostbyaddress
+syn keyword liteFunctions  urlEncode setContentType includeFile
+syn keyword liteFunctions  msqlConnect msqlClose msqlSelectDB
+syn keyword liteFunctions  msqlQuery msqlStoreResult msqlFreeResult
+syn keyword liteFunctions  msqlFetchRow msqlDataSeek msqlListDBs
+syn keyword liteFunctions  msqlListTables msqlInitFieldList msqlListField
+syn keyword liteFunctions  msqlFieldSeek msqlNumRows msqlEncode
+syn keyword liteFunctions  exit fatal typeof
+syn keyword liteFunctions  crypt addHttpHeader
+
+" Conditional
+syn keyword liteConditional  if else
+
+" Repeat
+syn keyword liteRepeat  while
+
+" Operator
+syn keyword liteStatement  break return continue
+
+" Operator
+syn match liteOperator  "[-+=#*]"
+syn match liteOperator  "/[^*]"me=e-1
+syn match liteOperator  "\$"
+syn match liteRelation  "&&"
+syn match liteRelation  "||"
+syn match liteRelation  "[!=<>]="
+syn match liteRelation  "[<>]"
+
+" Identifier
+syn match  liteIdentifier "$\h\w*" contains=liteIntVar,liteOperator
+syn match  liteGlobalIdentifier "@\h\w*" contains=liteIntVar
+
+" Include
+syn keyword liteInclude  load
+
+" Define
+syn keyword liteDefine  funct
+
+" Type
+syn keyword liteType  int uint char real
+
+" String
+syn region liteString  keepend matchgroup=None start=+"+  skip=+\\\\\|\\"+  end=+"+ contains=liteIdentifier,liteSpecialChar,@liteSql
+
+" Number
+syn match liteNumber  "-\=\<\d\+\>"
+
+" Float
+syn match liteFloat  "\(-\=\<\d+\|-\=\)\.\d\+\>"
+
+" SpecialChar
+syn match liteSpecialChar "\\[abcfnrtv\\]" contained
+
+syn match liteParentError "[)}\]]"
+
+" Todo
+syn keyword liteTodo TODO Todo todo contained
+
+" dont syn #!...
+syn match liteExec "^#!.*$"
+
+" Parents
+syn cluster liteInside contains=liteComment,liteFunctions,liteIdentifier,liteGlobalIdentifier,liteConditional,liteRepeat,liteStatement,liteOperator,liteRelation,liteType,liteString,liteNumber,liteFloat,liteParent
+
+syn region liteParent matchgroup=Delimiter start="(" end=")" contains=@liteInside
+syn region liteParent matchgroup=Delimiter start="{" end="}" contains=@liteInside
+syn region liteParent matchgroup=Delimiter start="\[" end="\]" contains=@liteInside
+
+" sync
+if main_syntax == 'lite'
+  if exists("lite_minlines")
+    exec "syn sync minlines=" . lite_minlines
+  else
+    syn sync minlines=100
+  endif
+endif
+
+" Define the default highlighting.
+" For version 5.7 and earlier: only when not done already
+" For version 5.8 and later: only when an item doesn't have highlighting yet
+if version >= 508 || !exists("did_lite_syn_inits")
+  if version < 508
+    let did_lite_syn_inits = 1
+    command -nargs=+ HiLink hi link <args>
+  else
+    command -nargs=+ HiLink hi def link <args>
+  endif
+
+  HiLink liteComment		Comment
+  HiLink liteString		String
+  HiLink liteNumber		Number
+  HiLink liteFloat		Float
+  HiLink liteIdentifier	Identifier
+  HiLink liteGlobalIdentifier	Identifier
+  HiLink liteIntVar		Identifier
+  HiLink liteFunctions		Function
+  HiLink liteRepeat		Repeat
+  HiLink liteConditional	Conditional
+  HiLink liteStatement		Statement
+  HiLink liteType		Type
+  HiLink liteInclude		Include
+  HiLink liteDefine		Define
+  HiLink liteSpecialChar	SpecialChar
+  HiLink liteParentError	liteError
+  HiLink liteError		Error
+  HiLink liteTodo		Todo
+  HiLink liteOperator		Operator
+  HiLink liteRelation		Operator
+
+  delcommand HiLink
+endif
+
+let b:current_syntax = "lite"
+
+if main_syntax == 'lite'
+  unlet main_syntax
+endif
+
+" vim: ts=8
--- /dev/null
+++ b/lib/vimfiles/syntax/litestep.vim
@@ -1,0 +1,269 @@
+" Vim syntax file
+" Language:         LiteStep RC file
+" Maintainer:       Nikolai Weibull <now@bitwi.se>
+" Latest Revision:  2007-02-22
+
+if exists("b:current_syntax")
+  finish
+endif
+
+let s:cpo_save = &cpo
+set cpo&vim
+
+syn keyword litestepTodo
+      \ contained
+      \ TODO FIXME XXX NOTE
+
+syn match   litestepComment
+      \ contained display contains=litestepTodo,@Spell
+      \ ';.*$'
+
+syn case ignore
+
+syn cluster litestepBeginnings
+      \ contains=
+      \   litestepComment,
+      \   litestepPreProc,
+      \   litestepMultiCommandStart,
+      \   litestepBangCommandStart,
+      \   litestepGenericDirective
+
+syn match   litestepGenericDirective
+      \ contained display
+      \ '\<\h\w\+\>'
+
+syn match   litestepBeginning
+      \ nextgroup=@litestepBeginnings skipwhite
+      \ '^'
+
+syn keyword litestepPreProc
+      \ contained
+      \ Include
+      \ If
+      \ ElseIf
+      \ Else
+      \ EndIf
+
+syn cluster litestepMultiCommands
+      \ contains=
+      \   litestepMultiCommand
+
+syn match   litestepMultiCommandStart
+      \ nextgroup=@litestepMultiCommands
+      \ '\*'
+
+syn match   litestepMultiCommand
+      \ contained display
+      \ '\<\h\w\+\>'
+
+syn cluster litestepVariables
+      \ contains=
+      \   litestepBuiltinFolderVariable,
+      \   litestepBuiltinConditionalVariable,
+      \   litestepBuiltinResourceVariable,
+      \   litestepBuiltinGUIDFolderMappingVariable,
+      \   litestepVariable
+
+syn region litestepVariableExpansion
+      \ display oneline transparent
+      \ contains=
+      \   @litestepVariables,
+      \   litestepNumber,
+      \   litestepMathOperator
+      \ matchgroup=litestepVariableExpansion
+      \ start='\$'
+      \ end='\$'
+
+syn match litestepNumber
+      \ display
+      \ '\<\d\+\>'
+
+syn region litestepString
+      \ display oneline contains=litestepVariableExpansion
+      \ start=+"+ end=+"+
+
+" TODO: unsure about this one.
+syn region litestepSubValue
+      \ display oneline contains=litestepVariableExpansion
+      \ start=+'+ end=+'+
+
+syn keyword litestepBoolean
+      \ true
+      \ false
+
+"syn keyword litestepLine
+"      \ ?
+
+"syn match   litestepColor
+"      \ display
+"      \ '\<\x\+\>'
+
+syn match   litestepRelationalOperator
+      \ display
+      \ '=\|<[>=]\=\|>=\='
+
+syn keyword litestepLogicalOperator
+      \ and
+      \ or
+      \ not
+
+syn match   litestepMathOperator
+      \ contained display
+      \ '[+*/-]'
+
+syn keyword litestepBuiltinDirective
+      \ LoadModule
+      \ LSNoStartup
+      \ LSAutoHideModules
+      \ LSNoShellWarning
+      \ LSSetAsShell
+      \ LSUseSystemDDE
+      \ LSDisableTrayService
+      \ LSImageFolder
+      \ ThemeAuthor
+      \ ThemeName
+
+syn keyword litestepDeprecatedBuiltinDirective
+      \ LSLogLevel
+      \ LSLogFile
+
+syn match   litestepVariable
+      \ contained display
+      \ '\<\h\w\+\>'
+
+syn keyword litestepBuiltinFolderVariable
+      \ contained
+      \ AdminToolsDir
+      \ CommonAdminToolsDir
+      \ CommonDesktopDir
+      \ CommonFavorites
+      \ CommonPrograms
+      \ CommonStartMenu
+      \ CommonStartup
+      \ Cookies
+      \ Desktop
+      \ DesktopDir
+      \ DocumentsDir
+      \ Favorites
+      \ Fonts
+      \ History
+      \ Internet
+      \ InternetCache
+      \ LitestepDir
+      \ Nethood
+      \ Printhood
+      \ Programs
+      \ QuickLaunch
+      \ Recent
+      \ Sendto
+      \ Startmenu
+      \ Startup
+      \ Templates
+      \ WinDir
+      \ LitestepDir
+
+syn keyword litestepBuiltinConditionalVariable
+      \ contained
+      \ Win2000
+      \ Win95
+      \ Win98
+      \ Win9X
+      \ WinME
+      \ WinNT
+      \ WinNT4
+      \ WinXP
+
+syn keyword litestepBuiltinResourceVariable
+      \ contained
+      \ CompileDate
+      \ ResolutionX
+      \ ResolutionY
+      \ UserName
+
+syn keyword litestepBuiltinGUIDFolderMappingVariable
+      \ contained
+      \ AdminTools
+      \ BitBucket
+      \ Controls
+      \ Dialup
+      \ Documents
+      \ Drives
+      \ Network
+      \ NetworkAndDialup
+      \ Printers
+      \ Scheduled
+
+syn cluster litestepBangs
+      \ contains=
+      \   litestepBuiltinBang,
+      \   litestepBang
+
+syn match   litestepBangStart
+      \ nextgroup=@litestepBangs
+      \ '!'
+
+syn match   litestepBang
+      \ contained display
+      \ '\<\h\w\+\>'
+
+syn keyword litestepBuiltinBang
+      \ contained
+      \ About
+      \ Alert
+      \ CascadeWindows
+      \ Confirm
+      \ Execute
+      \ Gather
+      \ HideModules
+      \ LogOff
+      \ MinimizeWindows
+      \ None
+      \ Quit
+      \ Recycle
+      \ Refresh
+      \ Reload
+      \ ReloadModule
+      \ RestoreWindows
+      \ Run
+      \ ShowModules
+      \ Shutdown
+      \ Switchuser
+      \ TileWindowsH
+      \ TileWindowsV
+      \ ToggleModules
+      \ UnloadModule
+
+hi def link litestepTodo                              Todo
+hi def link litestepComment                           Comment
+hi def link litestepDirective                         Keyword
+hi def link litestepGenericDirective                  litestepDirective
+hi def link litestepPreProc                           PreProc
+hi def link litestepMultiCommandStart                 litestepPreProc
+hi def link litestepMultiCommand                      litestepDirective
+hi def link litestepDelimiter                         Delimiter
+hi def link litestepVariableExpansion                 litestepDelimiter
+hi def link litestepNumber                            Number
+hi def link litestepString                            String
+hi def link litestepSubValue                          litestepString
+hi def link litestepBoolean                           Boolean
+"hi def link litestepLine 
+"hi def link litestepColor                             Type
+hi def link litestepOperator                          Operator
+hi def link litestepRelationalOperator                litestepOperator
+hi def link litestepLogicalOperator                   litestepOperator
+hi def link litestepMathOperator                      litestepOperator
+hi def link litestepBuiltinDirective                  litestepDirective
+hi def link litestepDeprecatedBuiltinDirective        Error
+hi def link litestepVariable                          Identifier
+hi def link litestepBuiltinFolderVariable             Identifier
+hi def link litestepBuiltinConditionalVariable        Identifier
+hi def link litestepBuiltinResourceVariable           Identifier
+hi def link litestepBuiltinGUIDFolderMappingVariable  Identifier
+hi def link litestepBangStart                         litestepPreProc
+hi def link litestepBang                              litestepDirective
+hi def link litestepBuiltinBang                       litestepBang
+
+let b:current_syntax = "litestep"
+
+let &cpo = s:cpo_save
+unlet s:cpo_save
--- /dev/null
+++ b/lib/vimfiles/syntax/loginaccess.vim
@@ -1,0 +1,96 @@
+" Vim syntax file
+" Language:         login.access(5) configuration file
+" Maintainer:       Nikolai Weibull <now@bitwi.se>
+" Latest Revision:  2006-04-19
+
+if exists("b:current_syntax")
+  finish
+endif
+
+let s:cpo_save = &cpo
+set cpo&vim
+
+syn keyword loginaccessTodo           contained TODO FIXME XXX NOTE
+
+syn region  loginaccessComment        display oneline start='^#' end='$'
+                                      \ contains=loginaccessTodo,@Spell
+
+syn match   loginaccessBegin          display '^'
+                                      \ nextgroup=loginaccessPermission,
+                                      \ loginaccessComment skipwhite
+
+syn match   loginaccessPermission     contained display '[^#]'
+                                      \ contains=loginaccessPermError
+                                      \ nextgroup=loginaccessUserSep
+
+syn match   loginaccessPermError      contained display '[^+-]'
+
+syn match   loginaccessUserSep        contained display ':'
+                                      \ nextgroup=loginaccessUsers,
+                                      \ loginaccessAllUsers,
+                                      \ loginaccessExceptUsers
+
+syn match   loginaccessUsers          contained display '[^, \t:]\+'
+                                      \ nextgroup=loginaccessUserIntSep,
+                                      \ loginaccessOriginSep
+
+syn match   loginaccessAllUsers       contained display '\<ALL\>'
+                                      \ nextgroup=loginaccessUserIntSep,
+                                      \ loginaccessOriginSep
+
+syn match   loginaccessLocalUsers     contained display '\<LOCAL\>'
+                                      \ nextgroup=loginaccessUserIntSep,
+                                      \ loginaccessOriginSep
+
+syn match   loginaccessExceptUsers    contained display '\<EXCEPT\>'
+                                      \ nextgroup=loginaccessUserIntSep,
+                                      \ loginaccessOriginSep
+
+syn match   loginaccessUserIntSep     contained display '[, \t]'
+                                      \ nextgroup=loginaccessUsers,
+                                      \ loginaccessAllUsers,
+                                      \ loginaccessExceptUsers
+
+syn match   loginaccessOriginSep      contained display ':'
+                                      \ nextgroup=loginaccessOrigins,
+                                      \ loginaccessAllOrigins,
+                                      \ loginaccessExceptOrigins
+
+syn match   loginaccessOrigins        contained display '[^, \t]\+'
+                                      \ nextgroup=loginaccessOriginIntSep
+
+syn match   loginaccessAllOrigins     contained display '\<ALL\>'
+                                      \ nextgroup=loginaccessOriginIntSep
+
+syn match   loginaccessLocalOrigins   contained display '\<LOCAL\>'
+                                      \ nextgroup=loginaccessOriginIntSep
+
+syn match   loginaccessExceptOrigins  contained display '\<EXCEPT\>'
+                                      \ nextgroup=loginaccessOriginIntSep
+
+syn match   loginaccessOriginIntSep   contained display '[, \t]'
+                                      \ nextgroup=loginaccessOrigins,
+                                      \ loginaccessAllOrigins,
+                                      \ loginaccessExceptOrigins
+
+hi def link loginaccessTodo           Todo
+hi def link loginaccessComment        Comment
+hi def link loginaccessPermission     Type
+hi def link loginaccessPermError      Error
+hi def link loginaccessUserSep        Delimiter
+hi def link loginaccessUsers          Identifier
+hi def link loginaccessAllUsers       Macro
+hi def link loginaccessLocalUsers     Macro
+hi def link loginaccessExceptUsers    Operator
+hi def link loginaccessUserIntSep     loginaccessUserSep
+hi def link loginaccessOriginSep      loginaccessUserSep
+hi def link loginaccessOrigins        Identifier
+hi def link loginaccessAllOrigins     Macro
+hi def link loginaccessLocalOrigins   Macro
+hi def link loginaccessExceptOrigins  loginaccessExceptUsers
+hi def link loginaccessOriginIntSep   loginaccessUserSep
+
+let b:current_syntax = "loginaccess"
+
+let &cpo = s:cpo_save
+unlet s:cpo_save
--- /dev/null
+++ b/lib/vimfiles/syntax/logindefs.vim
@@ -1,0 +1,94 @@
+" Vim syntax file
+" Language:         login.defs(5) configuration file
+" Maintainer:       Nikolai Weibull <now@bitwi.se>
+" Latest Revision:  2006-04-19
+
+if exists("b:current_syntax")
+  finish
+endif
+
+let s:cpo_save = &cpo
+set cpo&vim
+
+syn keyword logindefsTodo       contained TODO FIXME XXX NOTE
+
+syn region  logindefsComment    display oneline start='^\s*#' end='$'
+                                \ contains=logindefsTodo,@Spell
+
+syn match   logindefsString     contained '[[:graph:]]\+'
+
+syn match   logindefsPath       contained '[[:graph:]]\+'
+
+syn match   logindefsPaths      contained '[[:graph:]]\+'
+                                \ nextgroup=logindefsPathDelim
+
+syn match   logindefsPathDelim  contained ':' nextgroup=logindefsPaths
+
+syn keyword logindefsBoolean    contained yes no
+
+syn match   logindefsDecimal    contained '\<\d\+\>'
+
+syn match   logindefsOctal      contained display '\<0\o\+\>'
+                                \ contains=logindefsOctalZero
+syn match   logindefsOctalZero  contained display '\<0'
+syn match   logindefsOctalError contained display '\<0\o*[89]\d*\>'
+
+syn match   logindefsHex        contained display '\<0x\x\+\>'
+
+syn cluster logindefsNumber     contains=logindefsDecimal,logindefsOctal,
+                                \ logindefsOctalError,logindefsHex
+
+syn match   logindefsBegin      display '^'
+                                \ nextgroup=logindefsKeyword,logindefsComment
+                                \ skipwhite
+
+syn keyword logindefsKeyword    contained CHFN_AUTH CLOSE_SESSIONS CREATE_HOME
+                                \ DEFAULT_HOME FAILLOG_ENAB LASTLOG_ENAB
+                                \ LOG_OK_LOGINS LOG_UNKFAIL_ENAB MAIL_CHECK_ENAB
+                                \ MD5_CRYPT_ENAB OBSCURE_CHECKS_ENAB
+                                \ PASS_ALWAYS_WARN PORTTIME_CHECKS_ENAB
+                                \ QUOTAS_ENAB SU_WHEEL_ONLY SYSLOG_SG_ENAB
+                                \ SYSLOG_SU_ENAB USERGROUPS_ENAB
+                                \ nextgroup=logindefsBoolean skipwhite
+
+syn keyword logindefsKeyword    contained CHFN_RESTRICT CONSOLE CONSOLE_GROUPS
+                                \ ENV_TZ ENV_HZ FAKE_SHELL SU_NAME LOGIN_STRING
+                                \ NOLOGIN_STR TTYGROUP USERDEL_CMD
+                                \ nextgroup=logindefsString skipwhite
+
+syn keyword logindefsKeyword    contained ENVIRON_FILE FTMP_FILE HUSHLOGIN_FILE
+                                \ ISSUE_FILE MAIL_DIR MAIL_FILE NOLOGINS_FILE
+                                \ NOLOGINS_FILE TTYTYPE_FILE QMAIL_DIR
+                                \ SULOG_FILE
+                                \ nextgroup=logindefsPath skipwhite
+
+syn keyword logindefsKeyword    contained CRACKLIB_DICTPATH ENV_PATH
+                                \ ENV_ROOTPATH ENV_SUPATH MOTD_FILE
+                                \ nextgroup=logindefsPaths skipwhite
+
+syn keyword logindefsKeyword    contained ERASECHAR FAIL_DELAY GETPASS_ASTERISKS
+                                \ GID_MAX GID_MIN KILLCHAR LOGIN_RETRIES
+                                \ LOGIN_TIMEOUT PASS_CHANGE_TRIES PASS_MAX_DAYS
+                                \ PASS_MAX_LEN PASS_MIN_DAYS PASS_MIN_LEN
+                                \ PASS_WARN_AGE TTYPERM UID_MAX UID_MIN ULIMIT
+                                \ UMASK
+                                \ nextgroup=@logindefsNumber skipwhite
+
+hi def link logindefsTodo       Todo
+hi def link logindefsComment    Comment
+hi def link logindefsString     String
+hi def link logindefsPath       String
+hi def link logindefsPaths      logindefsPath
+hi def link logindefsPathDelim  Delimiter
+hi def link logindefsBoolean    Boolean
+hi def link logindefsDecimal    Number
+hi def link logindefsOctal      Number
+hi def link logindefsOctalZero  PreProc
+hi def link logindefsOctalError Error
+hi def link logindefsHex        Number
+hi def link logindefsKeyword    Keyword
+
+let b:current_syntax = "logindefs"
+
+let &cpo = s:cpo_save
+unlet s:cpo_save
--- /dev/null
+++ b/lib/vimfiles/syntax/logtalk.vim
@@ -1,0 +1,392 @@
+" Vim syntax file
+"
+" Language:	Logtalk
+" Maintainer:	Paulo Moura <pmoura@logtalk.org>
+" Last Change:	February 24, 2006
+
+
+" Quit when a syntax file was already loaded:
+
+if version < 600
+	syntax clear
+elseif exists("b:current_syntax")
+	finish
+endif
+
+
+" Logtalk is case sensitive:
+
+syn case match
+
+
+" Logtalk variables
+
+syn match   logtalkVariable		"\<\(\u\|_\)\(\w\)*\>"
+
+
+" Logtalk clause functor
+
+syn match	logtalkOperator		":-"
+
+
+" Logtalk quoted atoms and strings
+
+syn region	logtalkString		start=+"+	skip=+\\"+	end=+"+
+syn region	logtalkAtom		start=+'+	skip=+\\'+	end=+'+
+
+
+" Logtalk message sending operators
+
+syn match	logtalkOperator		"::"
+syn match	logtalkOperator		"\^\^"
+
+
+" Logtalk external call
+
+syn region	logtalkExtCall		matchgroup=logtalkExtCallTag		start="{"		matchgroup=logtalkExtCallTag		end="}"		contains=ALL
+
+
+" Logtalk opening entity directives
+
+syn region	logtalkOpenEntityDir	matchgroup=logtalkOpenEntityDirTag	start=":- object("	matchgroup=logtalkOpenEntityDirTag	end=")\."	contains=logtalkEntity,logtalkVariable,logtalkNumber,logtalkOperator,logtalkEntityRel
+syn region	logtalkOpenEntityDir	matchgroup=logtalkOpenEntityDirTag	start=":- protocol("	matchgroup=logtalkOpenEntityDirTag	end=")\."	contains=logtalkEntity,logtalkVariable,logtalkNumber,logtalkOperator,logtalkEntityRel
+syn region	logtalkOpenEntityDir	matchgroup=logtalkOpenEntityDirTag	start=":- category("	matchgroup=logtalkOpenEntityDirTag	end=")\."	contains=logtalkEntity,logtalkVariable,logtalkNumber,logtalkOperator,logtalkEntityRel
+
+
+" Logtalk closing entity directives
+
+syn match	logtalkCloseEntityDir	":- end_object\."
+syn match	logtalkCloseEntityDir	":- end_protocol\."
+syn match	logtalkCloseEntityDir	":- end_category\."
+
+
+" Logtalk entity relations
+
+syn region	logtalkEntityRel	matchgroup=logtalkEntityRelTag	start="instantiates("	matchgroup=logtalkEntityRelTag	end=")"		contains=logtalkEntity,logtalkVariable,logtalkNumber,logtalkOperator	contained
+syn region	logtalkEntityRel	matchgroup=logtalkEntityRelTag	start="specializes("	matchgroup=logtalkEntityRelTag	end=")"		contains=logtalkEntity,logtalkVariable,logtalkNumber,logtalkOperator	contained
+syn region	logtalkEntityRel	matchgroup=logtalkEntityRelTag	start="extends("	matchgroup=logtalkEntityRelTag	end=")"		contains=logtalkEntity,logtalkVariable,logtalkNumber,logtalkOperator	contained
+syn region	logtalkEntityRel	matchgroup=logtalkEntityRelTag	start="imports("	matchgroup=logtalkEntityRelTag	end=")"		contains=logtalkEntity,logtalkVariable,logtalkNumber,logtalkOperator	contained
+syn region	logtalkEntityRel	matchgroup=logtalkEntityRelTag	start="implements("	matchgroup=logtalkEntityRelTag	end=")"		contains=logtalkEntity,logtalkVariable,logtalkNumber,logtalkOperator	contained
+
+
+" Logtalk directives
+
+syn region	logtalkDir		matchgroup=logtalkDirTag	start=":- alias("		matchgroup=logtalkDirTag	end=")\."	contains=ALL
+syn region	logtalkDir		matchgroup=logtalkDirTag	start=":- encoding("	matchgroup=logtalkDirTag	end=")\."	contains=ALL
+syn region	logtalkDir		matchgroup=logtalkDirTag	start=":- initialization("	matchgroup=logtalkDirTag	end=")\."	contains=ALL
+syn region	logtalkDir		matchgroup=logtalkDirTag	start=":- info("		matchgroup=logtalkDirTag	end=")\."	contains=ALL
+syn region	logtalkDir		matchgroup=logtalkDirTag	start=":- mode("		matchgroup=logtalkDirTag	end=")\."	contains=logtalkOperator, logtalkAtom
+syn region	logtalkDir		matchgroup=logtalkDirTag	start=":- dynamic("		matchgroup=logtalkDirTag	end=")\."	contains=ALL
+syn match	logtalkDirTag		":- dynamic\."
+syn region	logtalkDir		matchgroup=logtalkDirTag	start=":- discontiguous("	matchgroup=logtalkDirTag	end=")\."	contains=ALL
+syn region	logtalkDir		matchgroup=logtalkDirTag	start=":- multifile("		matchgroup=logtalkDirTag	end=")\."	contains=ALL
+syn region	logtalkDir		matchgroup=logtalkDirTag	start=":- public("		matchgroup=logtalkDirTag	end=")\."	contains=ALL
+syn region	logtalkDir		matchgroup=logtalkDirTag	start=":- protected("		matchgroup=logtalkDirTag	end=")\."	contains=ALL
+syn region	logtalkDir		matchgroup=logtalkDirTag	start=":- private("		matchgroup=logtalkDirTag	end=")\."	contains=ALL
+syn region	logtalkDir		matchgroup=logtalkDirTag	start=":- metapredicate("	matchgroup=logtalkDirTag	end=")\."	contains=ALL
+syn region	logtalkDir		matchgroup=logtalkDirTag	start=":- op("			matchgroup=logtalkDirTag	end=")\."	contains=ALL
+syn region	logtalkDir		matchgroup=logtalkDirTag	start=":- calls("		matchgroup=logtalkDirTag	end=")\."	contains=ALL
+syn region	logtalkDir		matchgroup=logtalkDirTag	start=":- uses("		matchgroup=logtalkDirTag	end=")\."	contains=ALL
+
+
+" Module directives
+
+syn region	logtalkDir		matchgroup=logtalkDirTag	start=":- module("		matchgroup=logtalkDirTag	end=")\."	contains=ALL
+syn region	logtalkDir		matchgroup=logtalkDirTag	start=":- export("		matchgroup=logtalkDirTag	end=")\."	contains=ALL
+syn region	logtalkDir		matchgroup=logtalkDirTag	start=":- meta_predicate("		matchgroup=logtalkDirTag	end=")\."	contains=ALL
+syn region	logtalkDir		matchgroup=logtalkDirTag	start=":- use_module("		matchgroup=logtalkDirTag	end=")\."	contains=ALL
+
+
+" Logtalk built-in predicates
+
+syn match	logtalkBuiltIn		"\<\(abolish\|c\(reate\|urrent\)\)_\(object\|protocol\|category\)\ze("
+
+syn match	logtalkBuiltIn		"\<\(object\|protocol\|category\)_property\ze("
+
+syn match	logtalkBuiltIn		"\<extends_\(object\|protocol\)\ze("
+syn match	logtalkBuiltIn		"\<imp\(orts_category\|lements_protocol\)\ze("
+syn match	logtalkBuiltIn		"\<\(instantiates\|specializes\)_class\ze("
+
+syn match	logtalkBuiltIn		"\<\(abolish\|define\)_events\ze("
+syn match	logtalkBuiltIn		"\<current_event\ze("
+
+syn match	logtalkBuiltIn		"\<\(current\|set\)_logtalk_flag\ze("
+
+syn match	logtalkBuiltIn		"\<logtalk_\(compile\|l\(ibrary_path\|oad\)\)\ze("
+
+syn match	logtalkBuiltIn		"\<\(for\|retract\)all\ze("
+
+
+" Logtalk built-in methods
+
+syn match	logtalkBuiltInMethod	"\<parameter\ze("
+syn match	logtalkBuiltInMethod	"\<se\(lf\|nder\)\ze("
+syn match	logtalkBuiltInMethod	"\<this\ze("
+
+syn match	logtalkBuiltInMethod	"\<current_predicate\ze("
+syn match	logtalkBuiltInMethod	"\<predicate_property\ze("
+
+syn match	logtalkBuiltInMethod	"\<a\(bolish\|ssert\(a\|z\)\)\ze("
+syn match	logtalkBuiltInMethod	"\<clause\ze("
+syn match	logtalkBuiltInMethod	"\<retract\(all\)\?\ze("
+
+syn match	logtalkBuiltInMethod	"\<\(bag\|set\)of\ze("
+syn match	logtalkBuiltInMethod	"\<f\(ind\|or\)all\ze("
+
+syn match	logtalkBuiltInMethod	"\<before\ze("
+syn match	logtalkBuiltInMethod	"\<after\ze("
+
+syn match	logtalkBuiltInMethod	"\<expand_term\ze("
+syn match	logtalkBuiltInMethod	"\<term_expansion\ze("
+syn match	logtalkBuiltInMethod	"\<phrase\ze("
+
+
+" Mode operators
+
+syn match	logtalkOperator		"?"
+syn match	logtalkOperator		"@"
+
+
+" Control constructs
+
+syn match	logtalkKeyword		"\<true\>"
+syn match	logtalkKeyword		"\<fail\>"
+syn match	logtalkKeyword		"\<ca\(ll\|tch\)\ze("
+syn match	logtalkOperator		"!"
+" syn match	logtalkOperator		","
+syn match	logtalkOperator		";"
+syn match	logtalkOperator		"-->"
+syn match	logtalkOperator		"->"
+syn match	logtalkKeyword		"\<throw\ze("
+
+
+" Term unification
+
+syn match	logtalkOperator		"="
+syn match	logtalkKeyword		"\<unify_with_occurs_check\ze("
+syn match	logtalkOperator		"\\="
+
+
+" Term testing
+
+syn match	logtalkKeyword		"\<var\ze("
+syn match	logtalkKeyword		"\<atom\(ic\)\?\ze("
+syn match	logtalkKeyword		"\<integer\ze("
+syn match	logtalkKeyword		"\<float\ze("
+syn match	logtalkKeyword		"\<compound\ze("
+syn match	logtalkKeyword		"\<n\(onvar\|umber\)\ze("
+
+
+" Term comparison
+
+syn match	logtalkOperator		"@=<"
+syn match	logtalkOperator		"=="
+syn match	logtalkOperator		"\\=="
+syn match	logtalkOperator		"@<"
+syn match	logtalkOperator		"@>"
+syn match	logtalkOperator		"@>="
+
+
+" Term creation and decomposition
+
+syn match	logtalkKeyword		"\<functor\ze("
+syn match	logtalkKeyword		"\<arg\ze("
+syn match	logtalkOperator		"=\.\."
+syn match	logtalkKeyword		"\<copy_term\ze("
+
+
+" Arithemtic evaluation
+
+syn match	logtalkOperator		"\<is\>"
+
+
+" Arithemtic comparison
+
+syn match	logtalkOperator		"=:="
+syn match	logtalkOperator		"=\\="
+syn match	logtalkOperator		"<"
+syn match	logtalkOperator		"=<"
+syn match	logtalkOperator		">"
+syn match	logtalkOperator		">="
+
+
+" Stream selection and control
+
+syn match	logtalkKeyword		"\<\(current\|set\)_\(in\|out\)put\ze("
+syn match	logtalkKeyword		"\<open\ze("
+syn match	logtalkKeyword		"\<close\ze("
+syn match	logtalkKeyword		"\<flush_output\ze("
+syn match	logtalkKeyword		"\<flush_output\>"
+syn match	logtalkKeyword		"\<stream_property\ze("
+syn match	logtalkKeyword		"\<at_end_of_stream\ze("
+syn match	logtalkKeyword		"\<at_end_of_stream\>"
+syn match	logtalkKeyword		"\<set_stream_position\ze("
+
+
+" Character and byte input/output
+
+syn match	logtalkKeyword		"\<\(get\|p\(eek\|ut\)\)_\(c\(har\|ode\)\|byte\)\ze("
+syn match	logtalkKeyword		"\<nl\ze("
+syn match	logtalkKeyword		"\<nl\>"
+
+
+" Term input/output
+
+syn match	logtalkKeyword		"\<read\(_term\)\?\ze("
+syn match	logtalkKeyword		"\<write\(q\|_\(canonical\|term\)\)\?\ze("
+syn match	logtalkKeyword		"\<\(current_\)\?op\ze("
+syn match	logtalkKeyword		"\<\(current\)\?char_conversion\ze("
+
+
+" Logic and control
+
+syn match	logtalkOperator		"\\+"
+syn match	logtalkKeyword		"\<once\ze("
+syn match	logtalkKeyword		"\<repeat\>"
+
+
+" Atomic term processing
+
+syn match	logtalkKeyword		"\<atom_\(length\|c\(hars\|o\(ncat\|des\)\)\)\ze("
+syn match	logtalkKeyword		"\<sub_atom\ze("
+syn match	logtalkKeyword		"\<char_code\ze("
+syn match	logtalkKeyword		"\<number_\(c\(hars\|odes\)\)\ze("
+
+
+" Implementation defined hooks functions
+
+syn match	logtalkKeyword		"\<\(current\|set\)_prolog_flag\ze("
+syn match	logtalkKeyword		"\<halt\ze("
+syn match	logtalkKeyword		"\<halt\>"
+
+
+" Evaluable functors
+
+syn match	logtalkOperator		"+"
+syn match	logtalkOperator		"-"
+syn match	logtalkOperator		"\*"
+syn match	logtalkOperator		"//"
+syn match	logtalkOperator		"/"
+syn match	logtalkKeyword		"\<r\(ound\|em\)\ze("
+syn match	logtalkKeyword		"\<rem\>"
+syn match	logtalkKeyword		"\<mod\ze("
+syn match	logtalkKeyword		"\<mod\>"
+syn match	logtalkKeyword		"\<abs\ze("
+syn match	logtalkKeyword		"\<sign\ze("
+syn match	logtalkKeyword		"\<flo\(or\|at\(_\(integer\|fractional\)_part\)\?\)\ze("
+syn match	logtalkKeyword		"\<truncate\ze("
+syn match	logtalkKeyword		"\<ceiling\ze("
+
+
+" Other arithemtic functors
+
+syn match	logtalkOperator		"\*\*"
+syn match	logtalkKeyword		"\<s\(in\|qrt\)\ze("
+syn match	logtalkKeyword		"\<cos\ze("
+syn match	logtalkKeyword		"\<atan\ze("
+syn match	logtalkKeyword		"\<exp\ze("
+syn match	logtalkKeyword		"\<log\ze("
+
+
+" Bitwise functors
+
+syn match	logtalkOperator		">>"
+syn match	logtalkOperator		"<<"
+syn match	logtalkOperator		"/\\"
+syn match	logtalkOperator		"\\/"
+syn match	logtalkOperator		"\\"
+
+
+" Logtalk list operator
+
+syn match	logtalkOperator		"|"
+
+
+" Logtalk numbers 
+
+syn match	logtalkNumber		"\<\d\+\>"
+syn match	logtalkNumber		"\<\d\+\.\d\+\>"
+syn match	logtalkNumber		"\<\d\+[eE][-+]\=\d\+\>"
+syn match	logtalkNumber		"\<\d\+\.\d\+[eE][-+]\=\d\+\>"
+syn match	logtalkNumber		"\<0'.\>"
+syn match	logtalkNumber		"\<0b[0-1]\+\>"
+syn match	logtalkNumber		"\<0o\o\+\>"
+syn match	logtalkNumber		"\<0x\x\+\>"
+
+
+" Logtalk end-of-clause
+
+syn match	logtalkOperator		"\."
+
+
+" Logtalk comments
+
+syn region	logtalkBlockComment	start="/\*"	end="\*/"	fold
+syn match	logtalkLineComment	"%.*"
+
+
+" Logtalk entity folding
+
+syn region logtalkEntity transparent fold keepend start=":- object(" end=":- end_object\." contains=ALL
+syn region logtalkEntity transparent fold keepend start=":- protocol(" end=":- end_protocol\." contains=ALL
+syn region logtalkEntity transparent fold keepend start=":- category(" end=":- end_category\." contains=ALL
+
+
+syn sync ccomment logtalkBlockComment maxlines=50
+
+
+" Define the default highlighting.
+" For version 5.7 and earlier: only when not done already
+" For version 5.8 and later: only when an item doesn't have highlighting yet
+
+if version >= 508 || !exists("did_logtalk_syn_inits")
+	if version < 508
+		let did_logtalk_syn_inits = 1
+		command -nargs=+ HiLink hi link <args>
+	else
+		command -nargs=+ HiLink hi def link <args>
+	endif
+	
+	HiLink	logtalkBlockComment	Comment
+	HiLink	logtalkLineComment	Comment
+
+	HiLink	logtalkOpenEntityDir	Normal
+	HiLink	logtalkOpenEntityDirTag	PreProc
+
+	HiLink	logtalkEntity		Normal
+
+	HiLink	logtalkEntityRel	Normal
+	HiLink	logtalkEntityRelTag	PreProc
+
+	HiLink	logtalkCloseEntityDir	PreProc
+
+	HiLink	logtalkDir		Normal
+	HiLink	logtalkDirTag		PreProc
+
+	HiLink	logtalkAtom		String
+	HiLink	logtalkString		String
+
+	HiLink	logtalkNumber		Number
+
+	HiLink	logtalkKeyword		Keyword
+
+	HiLink	logtalkBuiltIn		Keyword
+	HiLink	logtalkBuiltInMethod	Keyword
+
+	HiLink	logtalkOperator		Operator
+
+	HiLink	logtalkExtCall		Normal
+	HiLink	logtalkExtCallTag	Operator
+
+	HiLink	logtalkVariable		Identifier
+
+	delcommand HiLink
+
+endif
+
+
+let b:current_syntax = "logtalk"
+
+setlocal ts=4
+setlocal fdm=syntax
+setlocal fdc=2
--- /dev/null
+++ b/lib/vimfiles/syntax/lotos.vim
@@ -1,0 +1,82 @@
+" Vim syntax file
+" Language:	LOTOS (Language Of Temporal Ordering Specifications, IS8807)
+" Maintainer:	Daniel Amyot <damyot@csi.uottawa.ca>
+" Last Change:	Wed Aug 19 1998
+" URL:		http://lotos.csi.uottawa.ca/~damyot/vim/lotos.vim
+" This file is an adaptation of pascal.vim by Mario Eusebio
+" I'm not sure I understand all of the syntax highlight language,
+" but this file seems to do the job for standard LOTOS.
+
+" For version 5.x: Clear all syntax items
+" For version 6.x: Quit when a syntax file was already loaded
+if version < 600
+  syntax clear
+elseif exists("b:current_syntax")
+  finish
+endif
+
+syn case ignore
+
+"Comments in LOTOS are between (* and *)
+syn region lotosComment	start="(\*"  end="\*)" contains=lotosTodo
+
+"Operators [], [...], >>, ->, |||, |[...]|, ||, ;, !, ?, :, =, ,, :=
+syn match  lotosDelimiter       "[][]"
+syn match  lotosDelimiter	">>"
+syn match  lotosDelimiter	"->"
+syn match  lotosDelimiter	"\[>"
+syn match  lotosDelimiter	"[|;!?:=,]"
+
+"Regular keywords
+syn keyword lotosStatement	specification endspec process endproc
+syn keyword lotosStatement	where behaviour behavior
+syn keyword lotosStatement      any let par accept choice hide of in
+syn keyword lotosStatement	i stop exit noexit
+
+"Operators from the Abstract Data Types in IS8807
+syn keyword lotosOperator	eq ne succ and or xor implies iff
+syn keyword lotosOperator	not true false
+syn keyword lotosOperator	Insert Remove IsIn NotIn Union Ints
+syn keyword lotosOperator	Minus Includes IsSubsetOf
+syn keyword lotosOperator	lt le ge gt 0
+
+"Sorts in IS8807
+syn keyword lotosSort		Boolean Bool FBoolean FBool Element
+syn keyword lotosSort		Set String NaturalNumber Nat HexString
+syn keyword lotosSort		HexDigit DecString DecDigit
+syn keyword lotosSort		OctString OctDigit BitString Bit
+syn keyword lotosSort		Octet OctetString
+
+"Keywords for ADTs
+syn keyword lotosType	type endtype library endlib sorts formalsorts
+syn keyword lotosType	eqns formaleqns opns formalopns forall ofsort is
+syn keyword lotosType   for renamedby actualizedby sortnames opnnames
+syn keyword lotosType   using
+
+syn sync lines=250
+
+" Define the default highlighting.
+" For version 5.7 and earlier: only when not done already
+" For version 5.8 and later: only when an item doesn't have highlighting yet
+if version >= 508 || !exists("did_lotos_syntax_inits")
+  if version < 508
+    let did_lotos_syntax_inits = 1
+    command -nargs=+ HiLink hi link <args>
+  else
+    command -nargs=+ HiLink hi def link <args>
+  endif
+
+  HiLink lotosStatement		Statement
+  HiLink lotosProcess		Label
+  HiLink lotosOperator		Operator
+  HiLink lotosSort		Function
+  HiLink lotosType		Type
+  HiLink lotosComment		Comment
+  HiLink lotosDelimiter		String
+
+  delcommand HiLink
+endif
+
+let b:current_syntax = "lotos"
+
+" vim: ts=8
--- /dev/null
+++ b/lib/vimfiles/syntax/lout.vim
@@ -1,0 +1,139 @@
+" Vim syntax file
+" Language:    Lout
+" Maintainer:  Christian V. J. Br�ssow <cvjb@cvjb.de>
+" Last Change: Son 22 Jun 2003 20:43:26 CEST
+" Filenames:   *.lout,*.lt
+" URL:			http://www.cvjb.de/comp/vim/lout.vim
+" $Id: lout.vim,v 1.1 2004/06/13 17:52:18 vimboss Exp $
+"
+" Lout: Basser Lout document formatting system.
+
+" For version 5.x: Clear all syntax items
+" For version 6.x: Quit when a syntax file was already loaded
+if version < 600
+	syntax clear
+elseif exists("b:current_syntax")
+	finish
+endif
+
+" Lout is case sensitive
+syn case match
+
+" Synchronization, I know it is a huge number, but normal texts can be
+" _very_ long ;-)
+syn sync lines=1000
+
+" Characters allowed in keywords
+" I don't know if 128-255 are allowed in ANS-FORHT
+if version >= 600
+	setlocal iskeyword=@,48-57,.,@-@,_,192-255
+else
+	set iskeyword=@,48-57,.,@-@,_,192-255
+endif
+
+" Some special keywords
+syn keyword loutTodo contained TODO lout Lout LOUT
+syn keyword loutDefine def macro
+
+" Some big structures
+syn keyword loutKeyword @Begin @End @Figure @Tab
+syn keyword loutKeyword @Book @Doc @Document @Report
+syn keyword loutKeyword @Introduction @Abstract @Appendix
+syn keyword loutKeyword @Chapter @Section @BeginSections @EndSections
+
+" All kind of Lout keywords
+syn match loutFunction '\<@[^ \t{}]\+\>'
+
+" Braces -- Don`t edit these lines!
+syn match loutMBraces '[{}]'
+syn match loutIBraces '[{}]'
+syn match loutBBrace '[{}]'
+syn match loutBIBraces '[{}]'
+syn match loutHeads '[{}]'
+
+" Unmatched braces.
+syn match loutBraceError '}'
+
+" End of multi-line definitions, like @Document, @Report and @Book.
+syn match loutEOmlDef '^//$'
+
+" Grouping of parameters and objects.
+syn region loutObject transparent matchgroup=Delimiter start='{' matchgroup=Delimiter end='}' contains=ALLBUT,loutBraceError
+
+" The NULL object has a special meaning
+syn keyword loutNULL {}
+
+" Comments
+syn region loutComment start='\#' end='$' contains=loutTodo
+
+" Double quotes
+syn region loutSpecial start=+"+ skip=+\\\\\|\\"+ end=+"+
+
+" ISO-LATIN-1 characters created with @Char, or Adobe symbols
+" created with @Sym
+syn match loutSymbols '@\(\(Char\)\|\(Sym\)\)\s\+[A-Za-z]\+'
+
+" Include files
+syn match loutInclude '@IncludeGraphic\s\+\k\+'
+syn region loutInclude start='@\(\(SysInclude\)\|\(IncludeGraphic\)\|\(Include\)\)\s*{' end='}'
+
+" Tags
+syn match loutTag '@\(\(Tag\)\|\(PageMark\)\|\(PageOf\)\|\(NumberOf\)\)\s\+\k\+'
+syn region loutTag start='@Tag\s*{' end='}'
+
+" Equations
+syn match loutMath '@Eq\s\+\k\+'
+syn region loutMath matchgroup=loutMBraces start='@Eq\s*{' matchgroup=loutMBraces end='}' contains=ALLBUT,loutBraceError
+"
+" Fonts
+syn match loutItalic '@I\s\+\k\+'
+syn region loutItalic matchgroup=loutIBraces start='@I\s*{' matchgroup=loutIBraces end='}' contains=ALLBUT,loutBraceError
+syn match loutBold '@B\s\+\k\+'
+syn region loutBold matchgroup=loutBBraces start='@B\s*{' matchgroup=loutBBraces end='}' contains=ALLBUT,loutBraceError
+syn match loutBoldItalic '@BI\s\+\k\+'
+syn region loutBoldItalic matchgroup=loutBIBraces start='@BI\s*{' matchgroup=loutBIBraces end='}' contains=ALLBUT,loutBraceError
+syn region loutHeadings matchgroup=loutHeads start='@\(\(Title\)\|\(Caption\)\)\s*{' matchgroup=loutHeads end='}' contains=ALLBUT,loutBraceError
+
+" Define the default highlighting.
+" For version 5.7 and earlier: only when not done already
+" For version 5.8 and later: only when an item doesn't have highlighting yet
+if version >= 508 || !exists("did_lout_syn_inits")
+	if version < 508
+		let did_lout_syn_inits = 1
+		command -nargs=+ HiLink hi link <args>
+	else
+		command -nargs=+ HiLink hi def link <args>
+	endif
+
+	" The default methods for highlighting. Can be overrriden later.
+	HiLink loutTodo Todo
+	HiLink loutDefine Define
+	HiLink loutEOmlDef Define
+	HiLink loutFunction Function
+	HiLink loutBraceError Error
+	HiLink loutNULL Special
+	HiLink loutComment Comment
+	HiLink loutSpecial Special
+	HiLink loutSymbols Character
+	HiLink loutInclude Include
+	HiLink loutKeyword Keyword
+	HiLink loutTag Tag
+	HiLink loutMath Number
+
+	" HiLink Not really needed here, but I think it is more consistent.
+	HiLink loutMBraces loutMath
+	hi loutItalic term=italic cterm=italic gui=italic
+	HiLink loutIBraces loutItalic
+	hi loutBold term=bold cterm=bold gui=bold
+	HiLink loutBBraces loutBold
+	hi loutBoldItalic term=bold,italic cterm=bold,italic gui=bold,italic
+	HiLink loutBIBraces loutBoldItalic
+	hi loutHeadings term=bold cterm=bold guifg=indianred
+	HiLink loutHeads loutHeadings
+
+	delcommand HiLink
+endif
+
+let b:current_syntax = "lout"
+
+" vim:ts=8:sw=4:nocindent:smartindent:
--- /dev/null
+++ b/lib/vimfiles/syntax/lpc.vim
@@ -1,0 +1,455 @@
+" Vim syntax file
+" Language:	LPC
+" Maintainer:	Shizhu Pan <poet@mudbuilder.net>
+" URL:		http://poet.tomud.com/pub/lpc.vim.bz2
+" Last Change:	2003 May 11
+" Comments:	If you are using Vim 6.2 or later, see :h lpc.vim for
+"		file type recognizing, if not, you had to use modeline.
+
+
+" Nodule: This is the start nodule. {{{1
+
+" For version 5.x: Clear all syntax items
+" For version 6.x: Quit when a syntax file was already loaded
+if version < 600
+  syntax clear
+elseif exists("b:current_syntax")
+  finish
+endif
+
+" Nodule: Keywords {{{1
+
+" LPC keywords
+" keywords should always be highlighted so "contained" is not used.
+syn cluster	lpcKeywdGrp	contains=lpcConditional,lpcLabel,lpcOperator,lpcRepeat,lpcStatement,lpcModifier,lpcReserved
+
+syn keyword	lpcConditional	if else switch
+syn keyword	lpcLabel	case default
+syn keyword	lpcOperator	catch efun in inherit
+syn keyword	lpcRepeat	do for foreach while
+syn keyword	lpcStatement	break continue return
+
+syn match	lpcEfunError	/efun[^:]/ display
+
+" Illegal to use keyword as function
+" It's not working, maybe in the next version.
+syn keyword	lpcKeywdError	contained if for foreach return switch while
+
+" These are keywords only because they take lvalue or type as parameter,
+" so these keywords should only be used as function but cannot be names of
+" user-defined functions.
+syn keyword	lpcKeywdFunc	new parse_command sscanf time_expression
+
+" Nodule: Type and modifiers {{{1
+
+" Type names list.
+
+" Special types
+syn keyword	lpcType		void mixed unknown
+" Scalar/Value types.
+syn keyword	lpcType		int float string
+" Pointer types.
+syn keyword	lpcType		array buffer class function mapping object
+" Other types.
+if exists("lpc_compat_32")
+    syn keyword     lpcType	    closure status funcall
+else
+    syn keyword     lpcError	    closure status
+    syn keyword     lpcType	    multiset
+endif
+
+" Type modifier.
+syn keyword	lpcModifier	nomask private public
+syn keyword	lpcModifier	varargs virtual
+
+" sensible modifiers
+if exists("lpc_pre_v22")
+    syn keyword	lpcReserved	nosave protected ref
+    syn keyword	lpcModifier	static
+else
+    syn keyword	lpcError	static
+    syn keyword	lpcModifier	nosave protected ref
+endif
+
+" Nodule: Applies {{{1
+
+" Match a function declaration or function pointer
+syn match	lpcApplyDecl	excludenl /->\h\w*(/me=e-1 contains=lpcApplies transparent display
+
+" We should note that in func_spec.c the efun definition syntax is so
+" complicated that I use such a long regular expression to describe.
+syn match	lpcLongDecl	excludenl /\(\s\|\*\)\h\+\s\h\+(/me=e-1 contains=@lpcEfunGroup,lpcType,@lpcKeywdGrp transparent display
+
+" this is form for all functions
+" ->foo() form had been excluded
+syn match	lpcFuncDecl	excludenl /\h\w*(/me=e-1 contains=lpcApplies,@lpcEfunGroup,lpcKeywdError transparent display
+
+" The (: :) parenthesis or $() forms a function pointer
+syn match	lpcFuncName	/(:\s*\h\+\s*:)/me=e-1 contains=lpcApplies,@lpcEfunGroup transparent display contained
+syn match	lpcFuncName	/(:\s*\h\+,/ contains=lpcApplies,@lpcEfunGroup transparent display contained
+syn match	lpcFuncName	/\$(\h\+)/ contains=lpcApplies,@lpcEfunGroup transparent display contained
+
+" Applies list.
+"       system applies
+syn keyword     lpcApplies      contained __INIT clean_up create destructor heart_beat id init move_or_destruct reset
+"       interactive
+syn keyword     lpcApplies      contained catch_tell logon net_dead process_input receive_message receive_snoop telnet_suboption terminal_type window_size write_prompt
+"       master applies
+syn keyword     lpcApplies      contained author_file compile_object connect crash creator_file domain_file epilog error_handler flag get_bb_uid get_root_uid get_save_file_name log_error make_path_absolute object_name preload privs_file retrieve_ed_setup save_ed_setup slow_shutdown
+syn keyword     lpcApplies      contained valid_asm valid_bind valid_compile_to_c valid_database valid_hide valid_link valid_object valid_override valid_read valid_save_binary valid_seteuid valid_shadow valid_socket valid_write
+"       parsing
+syn keyword     lpcApplies      contained inventory_accessible inventory_visible is_living parse_command_adjectiv_id_list parse_command_adjective_id_list parse_command_all_word parse_command_id_list parse_command_plural_id_list parse_command_prepos_list parse_command_users parse_get_environment parse_get_first_inventory parse_get_next_inventory parser_error_message
+
+
+" Nodule: Efuns {{{1
+
+syn cluster	lpcEfunGroup	contains=lpc_efuns,lpcOldEfuns,lpcNewEfuns,lpcKeywdFunc
+
+" Compat32 efuns
+if exists("lpc_compat_32")
+    syn keyword lpc_efuns	contained closurep heart_beat_info m_delete m_values m_indices query_once_interactive strstr
+else
+    syn match   lpcErrFunc	/#`\h\w*/
+    " Shell compatible first line comment.
+    syn region	lpcCommentFunc	start=/^#!/ end=/$/
+endif
+
+" pre-v22 efuns which are removed in newer versions.
+syn keyword     lpcOldEfuns     contained tail dump_socket_status
+
+" new efuns after v22 should be added here!
+syn keyword     lpcNewEfuns     contained socket_status
+
+" LPC efuns list.
+" DEBUG efuns Not included.
+" New efuns should NOT be added to this list, see v22 efuns above.
+" Efuns list {{{2
+syn keyword     lpc_efuns       contained acos add_action all_inventory all_previous_objects allocate allocate_buffer allocate_mapping apply arrayp asin atan author_stats
+syn keyword     lpc_efuns       contained bind break_string bufferp
+syn keyword     lpc_efuns       contained cache_stats call_other call_out call_out_info call_stack capitalize catch ceil check_memory children classp clear_bit clone_object clonep command commands copy cos cp crc32 crypt ctime
+syn keyword     lpc_efuns       contained db_close db_commit db_connect db_exec db_fetch db_rollback db_status debug_info debugmalloc debug_message deep_inherit_list deep_inventory destruct disable_commands disable_wizard domain_stats dumpallobj dump_file_descriptors dump_prog
+syn keyword     lpc_efuns       contained each ed ed_cmd ed_start enable_commands enable_wizard environment error errorp eval_cost evaluate exec exp explode export_uid external_start
+syn keyword     lpc_efuns       contained fetch_variable file_length file_name file_size filter filter_array filter_mapping find_call_out find_living find_object find_player first_inventory floatp floor flush_messages function_exists function_owner function_profile functionp functions
+syn keyword     lpc_efuns       contained generate_source get_char get_config get_dir geteuid getuid
+syn keyword     lpc_efuns       contained heart_beats
+syn keyword     lpc_efuns       contained id_matrix implode in_edit in_input inherit_list inherits input_to interactive intp
+syn keyword     lpc_efuns       contained keys
+syn keyword     lpc_efuns       contained link living livings load_object localtime log log10 lookat_rotate lower_case lpc_info
+syn keyword     lpc_efuns       contained malloc_check malloc_debug malloc_status map map_array map_delete map_mapping mapp master match_path max_eval_cost member_array memory_info memory_summary message mkdir moncontrol move_object mud_status
+syn keyword     lpc_efuns       contained named_livings network_stats next_bit next_inventory notify_fail nullp
+syn keyword     lpc_efuns       contained objectp objects oldcrypt opcprof origin
+syn keyword     lpc_efuns       contained parse_add_rule parse_add_synonym parse_command parse_dump parse_init parse_my_rules parse_refresh parse_remove parse_sentence pluralize pointerp pow present previous_object printf process_string process_value program_info
+syn keyword     lpc_efuns       contained query_ed_mode query_heart_beat query_host_name query_idle query_ip_name query_ip_number query_ip_port query_load_average query_notify_fail query_privs query_replaced_program query_shadowing query_snoop query_snooping query_verb
+syn keyword     lpc_efuns       contained random read_buffer read_bytes read_file receive reclaim_objects refs regexp reg_assoc reload_object remove_action remove_call_out remove_interactive remove_shadow rename repeat_string replace_program replace_string replaceable reset_eval_cost resolve restore_object restore_variable rm rmdir rotate_x rotate_y rotate_z rusage
+syn keyword     lpc_efuns       contained save_object save_variable say scale set_author set_bit set_eval_limit set_heart_beat set_hide set_light set_living_name set_malloc_mask set_privs set_reset set_this_player set_this_user seteuid shadow shallow_inherit_list shout shutdown sin sizeof snoop socket_accept socket_acquire socket_address socket_bind socket_close socket_connect socket_create socket_error socket_listen socket_release socket_write sort_array sprintf sqrt stat store_variable strcmp stringp strlen strsrch
+syn keyword     lpc_efuns       contained tan tell_object tell_room terminal_colour test_bit this_interactive this_object this_player this_user throw time to_float to_int trace traceprefix translate typeof
+syn keyword     lpc_efuns       contained undefinedp unique_array unique_mapping upper_case uptime userp users
+syn keyword     lpc_efuns       contained values variables virtualp
+syn keyword     lpc_efuns       contained wizardp write write_buffer write_bytes write_file
+
+" Nodule: Constants {{{1
+
+" LPC Constants.
+" like keywords, constants are always highlighted, be careful to choose only
+" the constants we used to add to this list.
+syn keyword     lpcConstant     __ARCH__ __COMPILER__ __DIR__ __FILE__ __OPTIMIZATION__ __PORT__ __VERSION__
+"       Defines in options.h are all predefined in LPC sources surrounding by
+"       two underscores. Do we need to include all of that?
+syn keyword     lpcConstant     __SAVE_EXTENSION__ __HEARTBEAT_INTERVAL__
+"       from the documentation we know that these constants remains only for
+"       backward compatibility and should not be used any more.
+syn keyword     lpcConstant     HAS_ED HAS_PRINTF HAS_RUSAGE HAS_DEBUG_LEVEL
+syn keyword     lpcConstant     MUD_NAME F__THIS_OBJECT
+
+" Nodule: Todo for this file.  {{{1
+
+" TODO : need to check for LPC4 syntax and other series of LPC besides
+" v22, b21 and l32, if you had a good idea, contact me at poet@mudbuilder.net
+" and I will be appreciated about that.
+
+" Notes about some FAQ:
+"
+" About variables : We adopts the same behavior for C because almost all the
+" LPC programmers are also C programmers, so we don't need separate settings
+" for C and LPC. That is the reason why I don't change variables like
+" "c_no_utf"s to "lpc_no_utf"s.
+"
+" Copy : Some of the following seems to be copied from c.vim but not quite
+" the same in details because the syntax for C and LPC is different.
+"
+" Color scheme : this syntax file had been thouroughly tested to work well
+" for all of the dark-backgrounded color schemes Vim has provided officially,
+" and it should be quite Ok for all of the bright-backgrounded color schemes,
+" of course it works best for the color scheme that I am using, download it
+" from http://poet.tomud.com/pub/ps_color.vim.bz2 if you want to try it.
+"
+
+" Nodule: String and Character {{{1
+
+
+" String and Character constants
+" Highlight special characters (those which have a backslash) differently
+syn match	lpcSpecial	display contained "\\\(x\x\+\|\o\{1,3}\|.\|$\)"
+if !exists("c_no_utf")
+  syn match	lpcSpecial	display contained "\\\(u\x\{4}\|U\x\{8}\)"
+endif
+
+" LPC version of sprintf() format,
+syn match	lpcFormat	display "%\(\d\+\)\=[-+ |=#@:.]*\(\d\+\)\=\('\I\+'\|'\I*\\'\I*'\)\=[OsdicoxXf]" contained
+syn match	lpcFormat	display "%%" contained
+syn region	lpcString	start=+L\="+ skip=+\\\\\|\\"+ end=+"+ contains=lpcSpecial,lpcFormat
+" lpcCppString: same as lpcString, but ends at end of line
+syn region	lpcCppString	start=+L\="+ skip=+\\\\\|\\"\|\\$+ excludenl end=+"+ end='$' contains=lpcSpecial,lpcFormat
+
+" LPC preprocessor for the text formatting short cuts
+" Thanks to Dr. Charles E. Campbell <cec@gryphon.gsfc.nasa.gov>
+"	he suggests the best way to do this.
+syn region	lpcTextString	start=/@\z(\h\w*\)$/ end=/^\z1/ contains=lpcSpecial
+syn region	lpcArrayString	start=/@@\z(\h\w*\)$/ end=/^\z1/ contains=lpcSpecial
+
+" Character
+syn match	lpcCharacter	"L\='[^\\]'"
+syn match	lpcCharacter	"L'[^']*'" contains=lpcSpecial
+syn match	lpcSpecialError	"L\='\\[^'\"?\\abefnrtv]'"
+syn match	lpcSpecialCharacter "L\='\\['\"?\\abefnrtv]'"
+syn match	lpcSpecialCharacter display "L\='\\\o\{1,3}'"
+syn match	lpcSpecialCharacter display "'\\x\x\{1,2}'"
+syn match	lpcSpecialCharacter display "L'\\x\x\+'"
+
+" Nodule: White space {{{1
+
+" when wanted, highlight trailing white space
+if exists("c_space_errors")
+  if !exists("c_no_trail_space_error")
+    syn match	lpcSpaceError	display excludenl "\s\+$"
+  endif
+  if !exists("c_no_tab_space_error")
+    syn match	lpcSpaceError	display " \+\t"me=e-1
+  endif
+endif
+
+" Nodule: Parenthesis and brackets {{{1
+
+" catch errors caused by wrong parenthesis and brackets
+syn cluster	lpcParenGroup	contains=lpcParenError,lpcIncluded,lpcSpecial,lpcCommentSkip,lpcCommentString,lpcComment2String,@lpcCommentGroup,lpcCommentStartError,lpcUserCont,lpcUserLabel,lpcBitField,lpcCommentSkip,lpcOctalZero,lpcCppOut,lpcCppOut2,lpcCppSkip,lpcFormat,lpcNumber,lpcFloat,lpcOctal,lpcOctalError,lpcNumbersCom
+syn region	lpcParen	transparent start='(' end=')' contains=ALLBUT,@lpcParenGroup,lpcCppParen,lpcErrInBracket,lpcCppBracket,lpcCppString,@lpcEfunGroup,lpcApplies,lpcKeywdError
+" lpcCppParen: same as lpcParen but ends at end-of-line; used in lpcDefine
+syn region	lpcCppParen	transparent start='(' skip='\\$' excludenl end=')' end='$' contained contains=ALLBUT,@lpcParenGroup,lpcErrInBracket,lpcParen,lpcBracket,lpcString,@lpcEfunGroup,lpcApplies,lpcKeywdError
+syn match	lpcParenError	display ")"
+syn match	lpcParenError	display "\]"
+" for LPC:
+" Here we should consider the array ({ }) parenthesis and mapping ([ ])
+" parenthesis and multiset (< >) parenthesis.
+syn match	lpcErrInParen	display contained "[^^]{"ms=s+1
+syn match	lpcErrInParen	display contained "\(}\|\]\)[^)]"me=e-1
+syn region	lpcBracket	transparent start='\[' end=']' contains=ALLBUT,@lpcParenGroup,lpcErrInParen,lpcCppParen,lpcCppBracket,lpcCppString,@lpcEfunGroup,lpcApplies,lpcFuncName,lpcKeywdError
+" lpcCppBracket: same as lpcParen but ends at end-of-line; used in lpcDefine
+syn region	lpcCppBracket	transparent start='\[' skip='\\$' excludenl end=']' end='$' contained contains=ALLBUT,@lpcParenGroup,lpcErrInParen,lpcParen,lpcBracket,lpcString,@lpcEfunGroup,lpcApplies,lpcFuncName,lpcKeywdError
+syn match	lpcErrInBracket	display contained "[);{}]"
+
+" Nodule: Numbers {{{1
+
+" integer number, or floating point number without a dot and with "f".
+syn case ignore
+syn match	lpcNumbers	display transparent "\<\d\|\.\d" contains=lpcNumber,lpcFloat,lpcOctalError,lpcOctal
+" Same, but without octal error (for comments)
+syn match	lpcNumbersCom	display contained transparent "\<\d\|\.\d" contains=lpcNumber,lpcFloat,lpcOctal
+syn match	lpcNumber	display contained "\d\+\(u\=l\{0,2}\|ll\=u\)\>"
+" hex number
+syn match	lpcNumber	display contained "0x\x\+\(u\=l\{0,2}\|ll\=u\)\>"
+" Flag the first zero of an octal number as something special
+syn match	lpcOctal	display contained "0\o\+\(u\=l\{0,2}\|ll\=u\)\>" contains=lpcOctalZero
+syn match	lpcOctalZero	display contained "\<0"
+syn match	lpcFloat	display contained "\d\+f"
+" floating point number, with dot, optional exponent
+syn match	lpcFloat	display contained "\d\+\.\d*\(e[-+]\=\d\+\)\=[fl]\="
+" floating point number, starting with a dot, optional exponent
+syn match	lpcFloat	display contained "\.\d\+\(e[-+]\=\d\+\)\=[fl]\=\>"
+" floating point number, without dot, with exponent
+syn match	lpcFloat	display contained "\d\+e[-+]\=\d\+[fl]\=\>"
+" flag an octal number with wrong digits
+syn match	lpcOctalError	display contained "0\o*[89]\d*"
+syn case match
+
+" Nodule: Comment string {{{1
+
+" lpcCommentGroup allows adding matches for special things in comments
+syn keyword	lpcTodo		contained TODO FIXME XXX
+syn cluster	lpcCommentGroup	contains=lpcTodo
+
+if exists("c_comment_strings")
+  " A comment can contain lpcString, lpcCharacter and lpcNumber.
+  syntax match	lpcCommentSkip	contained "^\s*\*\($\|\s\+\)"
+  syntax region lpcCommentString	contained start=+L\=\\\@<!"+ skip=+\\\\\|\\"+ end=+"+ end=+\*/+me=s-1 contains=lpcSpecial,lpcCommentSkip
+  syntax region lpcComment2String	contained start=+L\=\\\@<!"+ skip=+\\\\\|\\"+ end=+"+ end="$" contains=lpcSpecial
+  syntax region  lpcCommentL	start="//" skip="\\$" end="$" keepend contains=@lpcCommentGroup,lpcComment2String,lpcCharacter,lpcNumbersCom,lpcSpaceError
+  syntax region lpcComment	matchgroup=lpcCommentStart start="/\*" matchgroup=NONE end="\*/" contains=@lpcCommentGroup,lpcCommentStartError,lpcCommentString,lpcCharacter,lpcNumbersCom,lpcSpaceError
+else
+  syn region	lpcCommentL	start="//" skip="\\$" end="$" keepend contains=@lpcCommentGroup,lpcSpaceError
+  syn region	lpcComment	matchgroup=lpcCommentStart start="/\*" matchgroup=NONE end="\*/" contains=@lpcCommentGroup,lpcCommentStartError,lpcSpaceError
+endif
+" keep a // comment separately, it terminates a preproc. conditional
+syntax match	lpcCommentError	display "\*/"
+syntax match	lpcCommentStartError display "/\*"me=e-1 contained
+
+" Nodule: Pre-processor {{{1
+
+syn region	lpcPreCondit	start="^\s*#\s*\(if\|ifdef\|ifndef\|elif\)\>" skip="\\$" end="$" end="//"me=s-1 contains=lpcComment,lpcCppString,lpcCharacter,lpcCppParen,lpcParenError,lpcNumbers,lpcCommentError,lpcSpaceError
+syn match	lpcPreCondit	display "^\s*#\s*\(else\|endif\)\>"
+if !exists("c_no_if0")
+  syn region	lpcCppOut		start="^\s*#\s*if\s\+0\+\>" end=".\|$" contains=lpcCppOut2
+  syn region	lpcCppOut2	contained start="0" end="^\s*#\s*\(endif\>\|else\>\|elif\>\)" contains=lpcSpaceError,lpcCppSkip
+  syn region	lpcCppSkip	contained start="^\s*#\s*\(if\>\|ifdef\>\|ifndef\>\)" skip="\\$" end="^\s*#\s*endif\>" contains=lpcSpaceError,lpcCppSkip
+endif
+syn region	lpcIncluded	display contained start=+"+ skip=+\\\\\|\\"+ end=+"+
+syn match	lpcIncluded	display contained "<[^>]*>"
+syn match	lpcInclude	display "^\s*#\s*include\>\s*["<]" contains=lpcIncluded
+syn match lpcLineSkip	"\\$"
+syn cluster	lpcPreProcGroup	contains=lpcPreCondit,lpcIncluded,lpcInclude,lpcDefine,lpcErrInParen,lpcErrInBracket,lpcUserLabel,lpcSpecial,lpcOctalZero,lpcCppOut,lpcCppOut2,lpcCppSkip,lpcFormat,lpcNumber,lpcFloat,lpcOctal,lpcOctalError,lpcNumbersCom,lpcString,lpcCommentSkip,lpcCommentString,lpcComment2String,@lpcCommentGroup,lpcCommentStartError,lpcParen,lpcBracket,lpcMulti,lpcKeywdError
+syn region	lpcDefine	start="^\s*#\s*\(define\|undef\)\>" skip="\\$" end="$" end="//"me=s-1 contains=ALLBUT,@lpcPreProcGroup
+
+if exists("lpc_pre_v22")
+    syn region	lpcPreProc	start="^\s*#\s*\(pragma\>\|echo\>\)" skip="\\$" end="$" keepend contains=ALLBUT,@lpcPreProcGroup
+else
+    syn region	lpcPreProc	start="^\s*#\s*\(pragma\>\|echo\>\|warn\>\|error\>\)" skip="\\$" end="$" keepend contains=ALLBUT,@lpcPreProcGroup
+endif
+
+" Nodule: User labels {{{1
+
+" Highlight Labels
+" User labels in LPC is not allowed, only "case x" and "default" is supported
+syn cluster	lpcMultiGroup	contains=lpcIncluded,lpcSpecial,lpcCommentSkip,lpcCommentString,lpcComment2String,@lpcCommentGroup,lpcCommentStartError,lpcUserCont,lpcUserLabel,lpcBitField,lpcOctalZero,lpcCppOut,lpcCppOut2,lpcCppSkip,lpcFormat,lpcNumber,lpcFloat,lpcOctal,lpcOctalError,lpcNumbersCom,lpcCppParen,lpcCppBracket,lpcCppString,lpcKeywdError
+syn region	lpcMulti		transparent start='\(case\|default\|public\|protected\|private\)' skip='::' end=':' contains=ALLBUT,@lpcMultiGroup
+
+syn cluster	lpcLabelGroup	contains=lpcUserLabel
+syn match	lpcUserCont	display "^\s*lpc:$" contains=@lpcLabelGroup
+
+" Don't want to match anything
+syn match	lpcUserLabel	display "lpc" contained
+
+" Nodule: Initializations {{{1
+
+if exists("c_minlines")
+  let b:c_minlines = c_minlines
+else
+  if !exists("c_no_if0")
+    let b:c_minlines = 50	" #if 0 constructs can be long
+  else
+    let b:c_minlines = 15	" mostly for () constructs
+  endif
+endif
+exec "syn sync ccomment lpcComment minlines=" . b:c_minlines
+
+" Make sure these options take place since we no longer depend on file type
+" plugin for C
+setlocal cindent
+setlocal fo-=t fo+=croql
+setlocal comments=sO:*\ -,mO:*\ \ ,exO:*/,s1:/*,mb:*,ex:*/,://
+set cpo-=C
+
+" Win32 can filter files in the browse dialog
+if has("gui_win32") && !exists("b:browsefilter")
+    let b:browsefilter = "LPC Source Files (*.c *.d *.h)\t*.c;*.d;*.h\n" .
+	\ "LPC Data Files (*.scr *.o *.dat)\t*.scr;*.o;*.dat\n" .
+	\ "Text Documentation (*.txt)\t*.txt\n" .
+	\ "All Files (*.*)\t*.*\n"
+endif
+
+" Nodule: Highlight links {{{1
+
+" Define the default highlighting.
+" For version 5.7 and earlier: only when not done already
+" For version 5.8 and later: only when an item doesn't have highlighting yet
+if version >= 508 || !exists("did_lpc_syn_inits")
+  if version < 508
+    let did_lpc_syn_inits = 1
+    command -nargs=+ HiLink hi link <args>
+  else
+    command -nargs=+ HiLink hi def link <args>
+  endif
+
+  HiLink lpcModifier		lpcStorageClass
+
+  HiLink lpcQuotedFmt		lpcFormat
+  HiLink lpcFormat		lpcSpecial
+  HiLink lpcCppString		lpcString	" Cpp means
+						" C Pre-Processor
+  HiLink lpcCommentL		lpcComment
+  HiLink lpcCommentStart	lpcComment
+  HiLink lpcUserLabel		lpcLabel
+  HiLink lpcSpecialCharacter	lpcSpecial
+  HiLink lpcOctal		lpcPreProc
+  HiLink lpcOctalZero		lpcSpecial  " LPC will treat octal numbers
+					    " as decimals, programmers should
+					    " be aware of that.
+  HiLink lpcEfunError		lpcError
+  HiLink lpcKeywdError		lpcError
+  HiLink lpcOctalError		lpcError
+  HiLink lpcParenError		lpcError
+  HiLink lpcErrInParen		lpcError
+  HiLink lpcErrInBracket	lpcError
+  HiLink lpcCommentError	lpcError
+  HiLink lpcCommentStartError	lpcError
+  HiLink lpcSpaceError		lpcError
+  HiLink lpcSpecialError	lpcError
+  HiLink lpcErrFunc		lpcError
+
+  if exists("lpc_pre_v22")
+      HiLink lpcOldEfuns	lpc_efuns
+      HiLink lpcNewEfuns	lpcError
+  else
+      HiLink lpcOldEfuns	lpcReserved
+      HiLink lpcNewEfuns	lpc_efuns
+  endif
+  HiLink lpc_efuns		lpcFunction
+
+  HiLink lpcReserved		lpcPreProc
+  HiLink lpcTextString		lpcString   " This should be preprocessors, but
+  HiLink lpcArrayString		lpcPreProc  " let's make some difference
+					    " between text and array
+
+  HiLink lpcIncluded		lpcString
+  HiLink lpcCommentString	lpcString
+  HiLink lpcComment2String	lpcString
+  HiLink lpcCommentSkip		lpcComment
+  HiLink lpcCommentFunc		lpcComment
+
+  HiLink lpcCppSkip		lpcCppOut
+  HiLink lpcCppOut2		lpcCppOut
+  HiLink lpcCppOut		lpcComment
+
+  " Standard type below
+  HiLink lpcApplies		Special
+  HiLink lpcCharacter		Character
+  HiLink lpcComment		Comment
+  HiLink lpcConditional		Conditional
+  HiLink lpcConstant		Constant
+  HiLink lpcDefine		Macro
+  HiLink lpcError		Error
+  HiLink lpcFloat		Float
+  HiLink lpcFunction		Function
+  HiLink lpcIdentifier		Identifier
+  HiLink lpcInclude		Include
+  HiLink lpcLabel		Label
+  HiLink lpcNumber		Number
+  HiLink lpcOperator		Operator
+  HiLink lpcPreCondit		PreCondit
+  HiLink lpcPreProc		PreProc
+  HiLink lpcRepeat		Repeat
+  HiLink lpcStatement		Statement
+  HiLink lpcStorageClass	StorageClass
+  HiLink lpcString		String
+  HiLink lpcStructure		Structure
+  HiLink lpcSpecial		LineNr
+  HiLink lpcTodo		Todo
+  HiLink lpcType		Type
+
+  delcommand HiLink
+endif
+
+" Nodule: This is the end nodule. {{{1
+
+let b:current_syntax = "lpc"
+
+" vim:ts=8:nosta:sw=2:ai:si:
+" vim600:set fdm=marker: }}}1
--- /dev/null
+++ b/lib/vimfiles/syntax/lprolog.vim
@@ -1,0 +1,137 @@
+" Vim syntax file
+" Language:     LambdaProlog (Teyjus)
+" Filenames:    *.mod *.sig
+" Maintainer:   Markus Mottl  <markus.mottl@gmail.com>
+" URL:          http://www.ocaml.info/vim/syntax/lprolog.vim
+" Last Change:  2006 Feb 05
+"               2001 Apr 26 - Upgraded for new Vim version
+"               2000 Jun  5 - Initial release
+
+" For version 5.x: Clear all syntax items
+" For version 6.x: Quit when a syntax file was already loaded
+if version < 600
+  syntax clear
+elseif exists("b:current_syntax")
+  finish
+endif
+
+" Lambda Prolog is case sensitive.
+syn case match
+
+syn match   lprologBrackErr    "\]"
+syn match   lprologParenErr    ")"
+
+syn cluster lprologContained contains=lprologTodo,lprologModuleName,lprologTypeNames,lprologTypeName
+
+" Enclosing delimiters
+syn region  lprologEncl transparent matchgroup=lprologKeyword start="(" matchgroup=lprologKeyword end=")" contains=ALLBUT,@lprologContained,lprologParenErr
+syn region  lprologEncl transparent matchgroup=lprologKeyword start="\[" matchgroup=lprologKeyword end="\]" contains=ALLBUT,@lprologContained,lprologBrackErr
+
+" General identifiers
+syn match   lprologIdentifier  "\<\(\w\|[-+*/\\^<>=`'~?@#$&!_]\)*\>"
+syn match   lprologVariable    "\<\(\u\|_\)\(\w\|[-+*/\\^<>=`'~?@#$&!]\)*\>"
+
+syn match   lprologOperator  "/"
+
+" Comments
+syn region  lprologComment  start="/\*" end="\*/" contains=lprologComment,lprologTodo
+syn region  lprologComment  start="%" end="$" contains=lprologTodo
+syn keyword lprologTodo  contained TODO FIXME XXX
+
+syn match   lprologInteger  "\<\d\+\>"
+syn match   lprologReal     "\<\(\d\+\)\=\.\d+\>"
+syn region  lprologString   start=+"+ skip=+\\\\\|\\"+ end=+"+
+
+" Clause definitions
+syn region  lprologClause start="^\w\+" end=":-\|\."
+
+" Modules
+syn region  lprologModule matchgroup=lprologKeyword start="^\<module\>" matchgroup=lprologKeyword end="\."
+
+" Types
+syn match   lprologKeyword "^\<type\>" skipwhite nextgroup=lprologTypeNames
+syn region  lprologTypeNames matchgroup=lprologBraceErr start="\<\w\+\>" matchgroup=lprologKeyword end="\." contained contains=lprologTypeName,lprologOperator
+syn match   lprologTypeName "\<\w\+\>" contained
+
+" Keywords
+syn keyword lprologKeyword  end import accumulate accum_sig
+syn keyword lprologKeyword  local localkind closed sig
+syn keyword lprologKeyword  kind exportdef useonly
+syn keyword lprologKeyword  infixl infixr infix prefix
+syn keyword lprologKeyword  prefixr postfix postfixl
+
+syn keyword lprologSpecial  pi sigma is true fail halt stop not
+
+" Operators
+syn match   lprologSpecial ":-"
+syn match   lprologSpecial "->"
+syn match   lprologSpecial "=>"
+syn match   lprologSpecial "\\"
+syn match   lprologSpecial "!"
+
+syn match   lprologSpecial ","
+syn match   lprologSpecial ";"
+syn match   lprologSpecial "&"
+
+syn match   lprologOperator "+"
+syn match   lprologOperator "-"
+syn match   lprologOperator "*"
+syn match   lprologOperator "\~"
+syn match   lprologOperator "\^"
+syn match   lprologOperator "<"
+syn match   lprologOperator ">"
+syn match   lprologOperator "=<"
+syn match   lprologOperator ">="
+syn match   lprologOperator "::"
+syn match   lprologOperator "="
+
+syn match   lprologOperator "\."
+syn match   lprologOperator ":"
+syn match   lprologOperator "|"
+
+syn match   lprologCommentErr  "\*/"
+
+syn sync minlines=50
+syn sync maxlines=500
+
+
+" Define the default highlighting.
+" For version 5.7 and earlier: only when not done already
+" For version 5.8 and later: only when an item doesn't have highlighting yet
+if version >= 508 || !exists("did_lprolog_syntax_inits")
+  if version < 508
+    let did_lprolog_syntax_inits = 1
+    command -nargs=+ HiLink hi link <args>
+  else
+    command -nargs=+ HiLink hi def link <args>
+  endif
+
+  HiLink lprologComment     Comment
+  HiLink lprologTodo	    Todo
+
+  HiLink lprologKeyword     Keyword
+  HiLink lprologSpecial     Special
+  HiLink lprologOperator    Operator
+  HiLink lprologIdentifier  Normal
+
+  HiLink lprologInteger     Number
+  HiLink lprologReal	    Number
+  HiLink lprologString	    String
+
+  HiLink lprologCommentErr  Error
+  HiLink lprologBrackErr    Error
+  HiLink lprologParenErr    Error
+
+  HiLink lprologModuleName  Special
+  HiLink lprologTypeName    Identifier
+
+  HiLink lprologVariable    Keyword
+  HiLink lprologAtom	    Normal
+  HiLink lprologClause	    Type
+
+  delcommand HiLink
+endif
+
+let b:current_syntax = "lprolog"
+
+" vim: ts=8
--- /dev/null
+++ b/lib/vimfiles/syntax/lscript.vim
@@ -1,0 +1,213 @@
+" Vim syntax file
+" Language:	LotusScript
+" Maintainer:	Taryn East (taryneast@hotmail.com)
+" Last Change:	2003 May 11
+
+" This is a rough  amalgamation of the visual basic syntax file, and the UltraEdit
+" and Textpad syntax highlighters.
+" It's not too brilliant given that a) I've never written a syntax.vim file before
+" and b) I'm not so crash hot at LotusScript either. If you see any problems
+" feel free to email me with them.
+
+" For version 5.x: Clear all syntax items
+" For version 6.x: Quit when a syntax file was already loaded
+if version < 600
+  syntax clear
+elseif exists("b:current_syntax")
+  finish
+endif
+
+" LotusScript is case insensitive
+syn case ignore
+
+" These are Notes thingies that had an equivalent in the vb highlighter
+" or I was already familiar with them
+syn keyword lscriptStatement ActivateApp As And Base Beep Call Case ChDir ChDrive Class
+syn keyword lscriptStatement Const Dim Declare DefCur DefDbl DefInt DefLng DefSng DefStr
+syn keyword lscriptStatement DefVar Do Else %Else ElseIf %ElseIf End %End Erase Event Exit
+syn keyword lscriptStatement Explicit FileCopy FALSE For ForAll Function Get GoTo GoSub
+syn keyword lscriptStatement If %If In Is Kill Let List Lock Loop MkDir
+syn keyword lscriptStatement Name Next New NoCase NoPitch Not Nothing NULL
+syn keyword lscriptStatement On Option Or PI Pitch Preserve Private Public
+syn keyword lscriptStatement Property Public Put
+syn keyword lscriptStatement Randomize ReDim Reset Resume Return RmDir
+syn keyword lscriptStatement Select SendKeys SetFileAttr Set Static Sub Then To TRUE
+syn keyword lscriptStatement Type Unlock Until While WEnd With Write XOr
+
+syn keyword lscriptDatatype Array Currency Double Integer Long Single String String$ Variant
+
+syn keyword lscriptNotesType Field Button Navigator
+syn keyword lscriptNotesType NotesACL NotesACLEntry NotesAgent NotesDatabase NotesDateRange
+syn keyword lscriptNotesType NotesDateTime NotesDbDirectory NotesDocument
+syn keyword lscriptNotesType NotesDocumentCollection NotesEmbeddedObject NotesForm
+syn keyword lscriptNotesType NotesInternational NotesItem NotesLog NotesName NotesNewsLetter
+syn keyword lscriptNotesType NotesMIMEEntry NotesOutline NotesOutlineEntry NotesRegistration
+syn keyword lscriptNotesType NotesReplication NotesRichTextItem NotesRichTextParagraphStyle
+syn keyword lscriptNotesType NotesRichTextStyle NotesRichTextTab
+syn keyword lscriptNotesType NotesSession NotesTimer NotesView NotesViewColumn NotesViewEntry
+syn keyword lscriptNotesType NotesViewEntryCollection NotesViewNavigator NotesUIDatabase
+syn keyword lscriptNotesType NotesUIDocument NotesUIView NotesUIWorkspace
+
+syn keyword lscriptNotesConst ACLLEVEL_AUTHOR ACLLEVEL_DEPOSITOR ACLLEVEL_DESIGNER
+syn keyword lscriptNotesConst ACLLEVEL_EDITOR ACLLEVEL_MANAGER ACLLEVEL_NOACCESS
+syn keyword lscriptNotesConst ACLLEVEL_READER ACLTYPE_MIXED_GROUP ACLTYPE_PERSON
+syn keyword lscriptNotesConst ACLTYPE_PERSON_GROUP ACLTYPE_SERVER ACLTYPE_SERVER_GROUP
+syn keyword lscriptNotesConst ACLTYPE_UNSPECIFIED ACTIONCD ALIGN_CENTER
+syn keyword lscriptNotesConst ALIGN_FULL ALIGN_LEFT ALIGN_NOWRAP ALIGN_RIGHT
+syn keyword lscriptNotesConst ASSISTANTINFO ATTACHMENT AUTHORS COLOR_BLACK
+syn keyword lscriptNotesConst COLOR_BLUE COLOR_CYAN COLOR_DARK_BLUE COLOR_DARK_CYAN
+syn keyword lscriptNotesConst COLOR_DARK_GREEN COLOR_DARK_MAGENTA COLOR_DARK_RED
+syn keyword lscriptNotesConst COLOR_DARK_YELLOW COLOR_GRAY COLOR_GREEN COLOR_LIGHT_GRAY
+syn keyword lscriptNotesConst COLOR_MAGENTA COLOR_RED COLOR_WHITE COLOR_YELLOW
+syn keyword lscriptNotesConst DATABASE DATETIMES DB_REPLICATION_PRIORITY_HIGH
+syn keyword lscriptNotesConst DB_REPLICATION_PRIORITY_LOW DB_REPLICATION_PRIORITY_MED
+syn keyword lscriptNotesConst DB_REPLICATION_PRIORITY_NOTSET EFFECTS_EMBOSS
+syn keyword lscriptNotesConst EFFECTS_EXTRUDE EFFECTS_NONE EFFECTS_SHADOW
+syn keyword lscriptNotesConst EFFECTS_SUBSCRIPT EFFECTS_SUPERSCRIPT EMBED_ATTACHMENT
+syn keyword lscriptNotesConst EMBED_OBJECT EMBED_OBJECTLINK EMBEDDEDOBJECT ERRORITEM
+syn keyword lscriptNotesConst EV_ALARM EV_COMM EV_MAIL EV_MISC EV_REPLICA EV_RESOURCE
+syn keyword lscriptNotesConst EV_SECURITY EV_SERVER EV_UNKNOWN EV_UPDATE FONT_COURIER
+syn keyword lscriptNotesConst FONT_HELV FONT_ROMAN FORMULA FT_DATABASE FT_DATE_ASC
+syn keyword lscriptNotesConst FT_DATE_DES FT_FILESYSTEM FT_FUZZY FT_SCORES FT_STEMS
+syn keyword lscriptNotesConst FT_THESAURUS HTML ICON ID_CERTIFIER ID_FLAT
+syn keyword lscriptNotesConst ID_HIERARCHICAL LSOBJECT MIME_PART NAMES NOTESLINKS
+syn keyword lscriptNotesConst NOTEREFS NOTES_DESKTOP_CLIENT NOTES_FULL_CLIENT
+syn keyword lscriptNotesConst NOTES_LIMITED_CLIENT NUMBERS OTHEROBJECT
+syn keyword lscriptNotesConst OUTLINE_CLASS_DATABASE OUTLINE_CLASS_DOCUMENT
+syn keyword lscriptNotesConst OUTLINE_CLASS_FOLDER OUTLINE_CLASS_FORM
+syn keyword lscriptNotesConst OUTLINE_CLASS_FRAMESET OUTLINE_CLASS_NAVIGATOR
+syn keyword lscriptNotesConst OUTLINE_CLASS_PAGE OUTLINE_CLASS_UNKNOWN
+syn keyword lscriptNotesConst OUTLINE_CLASS_VIEW OUTLINE_OTHER_FOLDERS_TYPE
+syn keyword lscriptNotesConst OUTLINE_OTHER_UNKNOWN_TYPE OUTLINE_OTHER_VIEWS_TYPE
+syn keyword lscriptNotesConst OUTLINE_TYPE_ACTION OUTLINE_TYPE_NAMEDELEMENT
+syn keyword lscriptNotesConst OUTLINE_TYPE_NOTELINK OUTLINE_TYPE_URL PAGINATE_BEFORE
+syn keyword lscriptNotesConst PAGINATE_DEFAULT PAGINATE_KEEP_TOGETHER
+syn keyword lscriptNotesConst PAGINATE_KEEP_WITH_NEXT PICKLIST_CUSTOM PICKLIST_NAMES
+syn keyword lscriptNotesConst PICKLIST_RESOURCES PICKLIST_ROOMS PROMPT_OK PROMPT_OKCANCELCOMBO
+syn keyword lscriptNotesConst PROMPT_OKCANCELEDIT PROMPT_OKCANCELEDITCOMBO PROMPT_OKCANCELLIST
+syn keyword lscriptNotesConst PROMPT_OKCANCELLISTMULT PROMPT_PASSWORD PROMPT_YESNO
+syn keyword lscriptNotesConst PROMPT_YESNOCANCEL QUERYCD READERS REPLICA_CANDIDATE
+syn keyword lscriptNotesConst RICHTEXT RULER_ONE_CENTIMETER RULER_ONE_INCH SEV_FAILURE
+syn keyword lscriptNotesConst SEV_FATAL SEV_NORMAL SEV_WARNING1 SEV_WARNING2
+syn keyword lscriptNotesConst SIGNATURE SPACING_DOUBLE SPACING_ONE_POINT_50
+syn keyword lscriptNotesConst SPACING_SINGLE STYLE_NO_CHANGE TAB_CENTER TAB_DECIMAL
+syn keyword lscriptNotesConst TAB_LEFT TAB_RIGHT TARGET_ALL_DOCS TARGET_ALL_DOCS_IN_VIEW
+syn keyword lscriptNotesConst TARGET_NEW_DOCS TARGET_NEW_OR_MODIFIED_DOCS TARGET_NONE
+syn keyword lscriptNotesConst TARGET_RUN_ONCE TARGET_SELECTED_DOCS TARGET_UNREAD_DOCS_IN_VIEW
+syn keyword lscriptNotesConst TEMPLATE TEMPLATE_CANDIDATE TEXT TRIGGER_AFTER_MAIL_DELIVERY
+syn keyword lscriptNotesConst TRIGGER_BEFORE_MAIL_DELIVERY TRIGGER_DOC_PASTED
+syn keyword lscriptNotesConst TRIGGER_DOC_UPDATE TRIGGER_MANUAL TRIGGER_NONE
+syn keyword lscriptNotesConst TRIGGER_SCHEDULED UNAVAILABLE UNKNOWN USERDATA
+syn keyword lscriptNotesConst USERID VC_ALIGN_CENTER VC_ALIGN_LEFT VC_ALIGN_RIGHT
+syn keyword lscriptNotesConst VC_ATTR_PARENS VC_ATTR_PUNCTUATED VC_ATTR_PERCENT
+syn keyword lscriptNotesConst VC_FMT_ALWAYS VC_FMT_CURRENCY VC_FMT_DATE VC_FMT_DATETIME
+syn keyword lscriptNotesConst VC_FMT_FIXED VC_FMT_GENERAL VC_FMT_HM VC_FMT_HMS
+syn keyword lscriptNotesConst VC_FMT_MD VC_FMT_NEVER VC_FMT_SCIENTIFIC
+syn keyword lscriptNotesConst VC_FMT_SOMETIMES VC_FMT_TIME VC_FMT_TODAYTIME VC_FMT_YM
+syn keyword lscriptNotesConst VC_FMT_YMD VC_FMT_Y4M VC_FONT_BOLD VC_FONT_ITALIC
+syn keyword lscriptNotesConst VC_FONT_STRIKEOUT VC_FONT_UNDERLINE VC_SEP_COMMA
+syn keyword lscriptNotesConst VC_SEP_NEWLINE VC_SEP_SEMICOLON VC_SEP_SPACE
+syn keyword lscriptNotesConst VIEWMAPDATA VIEWMAPLAYOUT VW_SPACING_DOUBLE
+syn keyword lscriptNotesConst VW_SPACING_ONE_POINT_25 VW_SPACING_ONE_POINT_50
+syn keyword lscriptNotesConst VW_SPACING_ONE_POINT_75 VW_SPACING_SINGLE
+
+syn keyword lscriptFunction Abs Asc Atn Atn2 ACos ASin
+syn keyword lscriptFunction CCur CDat CDbl Chr Chr$ CInt CLng Command Command$
+syn keyword lscriptFunction Cos CSng CStr
+syn keyword lscriptFunction CurDir CurDir$ CVar Date Date$ DateNumber DateSerial DateValue
+syn keyword lscriptFunction Day Dir Dir$ Environ$ Environ EOF Error Error$ Evaluate Exp
+syn keyword lscriptFunction FileAttr FileDateTime FileLen Fix Format Format$ FreeFile
+syn keyword lscriptFunction GetFileAttr GetThreadInfo Hex Hex$ Hour
+syn keyword lscriptFunction IMESetMode IMEStatus Input Input$ InputB InputB$
+syn keyword lscriptFunction InputBP InputBP$ InputBox InputBox$ InStr InStrB InStrBP InstrC
+syn keyword lscriptFunction IsA IsArray IsDate IsElement IsList IsNumeric
+syn keyword lscriptFunction IsObject IsResponse IsScalar IsUnknown LCase LCase$
+syn keyword lscriptFunction Left Left$ LeftB LeftB$ LeftC
+syn keyword lscriptFunction LeftBP LeftBP$ Len LenB LenBP LenC Loc LOF Log
+syn keyword lscriptFunction LSet LTrim LTrim$ MessageBox Mid Mid$ MidB MidB$ MidC
+syn keyword lscriptFunction Minute Month Now Oct Oct$ Responses Right Right$
+syn keyword lscriptFunction RightB RightB$ RightBP RightBP$ RightC Round Rnd RSet RTrim RTrim$
+syn keyword lscriptFunction Second Seek Sgn Shell Sin Sleep Space Space$ Spc Sqr Str Str$
+syn keyword lscriptFunction StrConv StrLeft StrleftBack StrRight StrRightBack
+syn keyword lscriptFunction StrCompare Tab Tan Time Time$ TimeNumber Timer
+syn keyword lscriptFunction TimeValue Trim Trim$ Today TypeName UCase UCase$
+syn keyword lscriptFunction UniversalID Val Weekday Year
+
+syn keyword lscriptMethods AppendToTextList ArrayAppend ArrayReplace ArrayGetIndex
+syn keyword lscriptMethods Append Bind Close
+"syn keyword lscriptMethods Contains
+syn keyword lscriptMethods CopyToDatabase CopyAllItems Count CurrentDatabase Delete Execute
+syn keyword lscriptMethods GetAllDocumentsByKey GetDatabase GetDocumentByKey
+syn keyword lscriptMethods GetDocumentByUNID GetFirstDocument GetFirstItem
+syn keyword lscriptMethods GetItems GetItemValue GetNthDocument GetView
+syn keyword lscriptMethods IsEmpty IsNull %Include Items
+syn keyword lscriptMethods Line LBound LoadMsgText Open Print
+syn keyword lscriptMethods RaiseEvent ReplaceItemValue Remove RemoveItem Responses
+syn keyword lscriptMethods Save Stop UBound UnprocessedDocuments Write
+
+syn keyword lscriptEvents Compare OnError
+
+"*************************************************************************************
+"These are Notes thingies that I'm not sure how to classify as they had no vb equivalent
+" At a wild guess I'd put them as Functions...
+" if anyone sees something really out of place... tell me!
+
+syn keyword lscriptFunction Access Alias Any Bin Bin$ Binary ByVal
+syn keyword lscriptFunction CodeLock CodeLockCheck CodeUnlock CreateLock
+syn keyword lscriptFunction CurDrive CurDrive$ DataType DestroyLock Eqv
+syn keyword lscriptFunction Erl Err Fraction From FromFunction FullTrim
+syn keyword lscriptFunction Imp Int Lib Like ListTag LMBCS LSServer Me
+syn keyword lscriptFunction Mod MsgDescription MsgText Output Published
+syn keyword lscriptFunction Random Read Shared Step UChr UChr$ Uni Unicode
+syn keyword lscriptFunction Until Use UseLSX UString UString$ Width Yield
+
+
+syn keyword lscriptTodo contained	TODO
+
+"integer number, or floating point number without a dot.
+syn match  lscriptNumber		"\<\d\+\>"
+"floating point number, with dot
+syn match  lscriptNumber		"\<\d\+\.\d*\>"
+"floating point number, starting with a dot
+syn match  lscriptNumber		"\.\d\+\>"
+
+" String and Character constants
+syn region  lscriptString		start=+"+  end=+"+
+syn region  lscriptComment		start="REM" end="$" contains=lscriptTodo
+syn region  lscriptComment		start="'"   end="$" contains=lscriptTodo
+syn region  lscriptLineNumber	start="^\d" end="\s"
+syn match   lscriptTypeSpecifier	"[a-zA-Z0-9][\$%&!#]"ms=s+1
+
+" Define the default highlighting.
+" For version 5.7 and earlier: only when not done already
+" For version 5.8 and later: only when an item doesn't have highlighting yet
+if version >= 508 || !exists("did_lscript_syntax_inits")
+  if version < 508
+    let did_lscript_syntax_inits = 1
+    command -nargs=+ HiLink hi link <args>
+  else
+    command -nargs=+ HiLink hi def link <args>
+  endif
+
+  hi lscriptNotesType	term=underline ctermfg=DarkGreen guifg=SeaGreen gui=bold
+
+  HiLink lscriptNotesConst	lscriptNotesType
+  HiLink lscriptLineNumber	Comment
+  HiLink lscriptDatatype	Type
+  HiLink lscriptNumber		Number
+  HiLink lscriptError		Error
+  HiLink lscriptStatement	Statement
+  HiLink lscriptString		String
+  HiLink lscriptComment		Comment
+  HiLink lscriptTodo		Todo
+  HiLink lscriptFunction	Identifier
+  HiLink lscriptMethods		PreProc
+  HiLink lscriptEvents		Special
+  HiLink lscriptTypeSpecifier	Type
+
+  delcommand HiLink
+endif
+
+let b:current_syntax = "lscript"
+
+" vim: ts=8
--- /dev/null
+++ b/lib/vimfiles/syntax/lss.vim
@@ -1,0 +1,133 @@
+" Vim syntax file
+" Language:	Lynx 2.7.1 style file
+" Maintainer:	Scott Bigham <dsb@killerbunnies.org>
+" Last Change:	2004 Oct 06
+
+" For version 5.x: Clear all syntax items
+" For version 6.x: Quit when a syntax file was already loaded
+if version < 600
+  syntax clear
+elseif exists("b:current_syntax")
+  finish
+endif
+
+" This setup is probably atypical for a syntax highlighting file, because
+" most of it is not really intended to be overrideable.  Instead, the
+" highlighting is supposed to correspond to the highlighting specified by
+" the .lss file entries themselves; ie. the "bold" keyword should be bold,
+" the "red" keyword should be red, and so forth.  The exceptions to this
+" are comments, of course, and the initial keyword identifying the affected
+" element, which will inherit the usual Identifier highlighting.
+
+syn match lssElement "^[^:]\+" nextgroup=lssMono
+
+syn match lssMono ":[^:]\+" contained nextgroup=lssFgColor contains=lssReverse,lssUnderline,lssBold,lssStandout
+
+syn keyword	lssBold		bold		contained
+syn keyword	lssReverse	reverse		contained
+syn keyword	lssUnderline	underline	contained
+syn keyword	lssStandout	standout	contained
+
+syn match lssFgColor ":[^:]\+" contained nextgroup=lssBgColor contains=lssRedFg,lssBlueFg,lssGreenFg,lssBrownFg,lssMagentaFg,lssCyanFg,lssLightgrayFg,lssGrayFg,lssBrightredFg,lssBrightgreenFg,lssYellowFg,lssBrightblueFg,lssBrightmagentaFg,lssBrightcyanFg
+
+syn case ignore
+syn keyword	lssRedFg		red		contained
+syn keyword	lssBlueFg		blue		contained
+syn keyword	lssGreenFg		green		contained
+syn keyword	lssBrownFg		brown		contained
+syn keyword	lssMagentaFg		magenta		contained
+syn keyword	lssCyanFg		cyan		contained
+syn keyword	lssLightgrayFg		lightgray	contained
+syn keyword	lssGrayFg		gray		contained
+syn keyword	lssBrightredFg		brightred	contained
+syn keyword	lssBrightgreenFg	brightgreen	contained
+syn keyword	lssYellowFg		yellow		contained
+syn keyword	lssBrightblueFg		brightblue	contained
+syn keyword	lssBrightmagentaFg	brightmagenta	contained
+syn keyword	lssBrightcyanFg		brightcyan	contained
+syn case match
+
+syn match lssBgColor ":[^:]\+" contained contains=lssRedBg,lssBlueBg,lssGreenBg,lssBrownBg,lssMagentaBg,lssCyanBg,lssLightgrayBg,lssGrayBg,lssBrightredBg,lssBrightgreenBg,lssYellowBg,lssBrightblueBg,lssBrightmagentaBg,lssBrightcyanBg,lssWhiteBg
+
+syn case ignore
+syn keyword	lssRedBg		red		contained
+syn keyword	lssBlueBg		blue		contained
+syn keyword	lssGreenBg		green		contained
+syn keyword	lssBrownBg		brown		contained
+syn keyword	lssMagentaBg		magenta		contained
+syn keyword	lssCyanBg		cyan		contained
+syn keyword	lssLightgrayBg		lightgray	contained
+syn keyword	lssGrayBg		gray		contained
+syn keyword	lssBrightredBg		brightred	contained
+syn keyword	lssBrightgreenBg	brightgreen	contained
+syn keyword	lssYellowBg		yellow		contained
+syn keyword	lssBrightblueBg		brightblue	contained
+syn keyword	lssBrightmagentaBg	brightmagenta	contained
+syn keyword	lssBrightcyanBg		brightcyan	contained
+syn keyword	lssWhiteBg		white		contained
+syn case match
+
+syn match lssComment "#.*$"
+
+" Define the default highlighting.
+" For version 5.7 and earlier: only when not done already
+" For version 5.8 and later: only when an item doesn't have highlighting yet
+if version >= 508 || !exists("did_lss_syntax_inits")
+  if version < 508
+    let did_lss_syntax_inits = 1
+  endif
+
+  hi def link lssComment Comment
+  hi def link lssElement Identifier
+
+  hi def lssBold		term=bold cterm=bold
+  hi def lssReverse		term=reverse cterm=reverse
+  hi def lssUnderline		term=underline cterm=underline
+  hi def lssStandout		term=standout cterm=standout
+
+  hi def lssRedFg		ctermfg=red
+  hi def lssBlueFg		ctermfg=blue
+  hi def lssGreenFg		ctermfg=green
+  hi def lssBrownFg		ctermfg=brown
+  hi def lssMagentaFg		ctermfg=magenta
+  hi def lssCyanFg		ctermfg=cyan
+  hi def lssGrayFg		ctermfg=gray
+  if $COLORTERM == "rxvt"
+    " On rxvt's, bright colors are activated by setting the bold attribute.
+    hi def lssLightgrayFg	ctermfg=gray cterm=bold
+    hi def lssBrightredFg	ctermfg=red cterm=bold
+    hi def lssBrightgreenFg	ctermfg=green cterm=bold
+    hi def lssYellowFg		ctermfg=yellow cterm=bold
+    hi def lssBrightblueFg	ctermfg=blue cterm=bold
+    hi def lssBrightmagentaFg	ctermfg=magenta cterm=bold
+    hi def lssBrightcyanFg	ctermfg=cyan cterm=bold
+  else
+    hi def lssLightgrayFg	ctermfg=lightgray
+    hi def lssBrightredFg	ctermfg=lightred
+    hi def lssBrightgreenFg	ctermfg=lightgreen
+    hi def lssYellowFg		ctermfg=yellow
+    hi def lssBrightblueFg	ctermfg=lightblue
+    hi def lssBrightmagentaFg	ctermfg=lightmagenta
+    hi def lssBrightcyanFg	ctermfg=lightcyan
+  endif
+
+  hi def lssRedBg		ctermbg=red
+  hi def lssBlueBg		ctermbg=blue
+  hi def lssGreenBg		ctermbg=green
+  hi def lssBrownBg		ctermbg=brown
+  hi def lssMagentaBg		ctermbg=magenta
+  hi def lssCyanBg		ctermbg=cyan
+  hi def lssLightgrayBg		ctermbg=lightgray
+  hi def lssGrayBg		ctermbg=gray
+  hi def lssBrightredBg		ctermbg=lightred
+  hi def lssBrightgreenBg	ctermbg=lightgreen
+  hi def lssYellowBg		ctermbg=yellow
+  hi def lssBrightblueBg	ctermbg=lightblue
+  hi def lssBrightmagentaBg	ctermbg=lightmagenta
+  hi def lssBrightcyanBg	ctermbg=lightcyan
+  hi def lssWhiteBg		ctermbg=white ctermfg=black
+endif
+
+let b:current_syntax = "lss"
+
+" vim: ts=8
--- /dev/null
+++ b/lib/vimfiles/syntax/lua.vim
@@ -1,0 +1,304 @@
+" Vim syntax file
+" Language:	Lua 4.0, Lua 5.0 and Lua 5.1
+" Maintainer:	Marcus Aurelius Farias <marcus.cf 'at' bol com br>
+" First Author:	Carlos Augusto Teixeira Mendes <cmendes 'at' inf puc-rio br>
+" Last Change:	2006 Aug 10
+" Options:	lua_version = 4 or 5
+"		lua_subversion = 0 (4.0, 5.0) or 1 (5.1)
+"		default 5.1
+
+" For version 5.x: Clear all syntax items
+" For version 6.x: Quit when a syntax file was already loaded
+if version < 600
+  syntax clear
+elseif exists("b:current_syntax")
+  finish
+endif
+
+if !exists("lua_version")
+  " Default is lua 5.1
+  let lua_version = 5
+  let lua_subversion = 1
+elseif !exists("lua_subversion")
+  " lua_version exists, but lua_subversion doesn't. So, set it to 0
+  let lua_subversion = 0
+endif
+
+syn case match
+
+" syncing method
+syn sync minlines=100
+
+" Comments
+syn keyword luaTodo             contained TODO FIXME XXX
+syn match   luaComment          "--.*$" contains=luaTodo,@Spell
+if lua_version == 5 && lua_subversion == 0
+  syn region  luaComment        matchgroup=luaComment start="--\[\[" end="\]\]" contains=luaTodo,luaInnerComment,@Spell
+  syn region  luaInnerComment   contained transparent start="\[\[" end="\]\]"
+elseif lua_version > 5 || (lua_version == 5 && lua_subversion >= 1)
+  " Comments in Lua 5.1: --[[ ... ]], [=[ ... ]=], [===[ ... ]===], etc.
+  syn region  luaComment        matchgroup=luaComment start="--\[\z(=*\)\[" end="\]\z1\]" contains=luaTodo,@Spell
+endif
+
+" First line may start with #!
+syn match luaComment "\%^#!.*"
+
+" catch errors caused by wrong parenthesis and wrong curly brackets or
+" keywords placed outside their respective blocks
+
+syn region luaParen transparent start='(' end=')' contains=ALLBUT,luaError,luaTodo,luaSpecial,luaCond,luaCondElseif,luaCondEnd,luaCondStart,luaBlock,luaRepeatBlock,luaRepeat,luaStatement
+syn match  luaError ")"
+syn match  luaError "}"
+syn match  luaError "\<\%(end\|else\|elseif\|then\|until\|in\)\>"
+
+" Function declaration
+syn region luaFunctionBlock transparent matchgroup=luaFunction start="\<function\>" end="\<end\>" contains=ALLBUT,luaTodo,luaSpecial,luaCond,luaCondElseif,luaCondEnd,luaRepeat
+
+" if then else elseif end
+syn keyword luaCond contained else
+
+" then ... end
+syn region luaCondEnd contained transparent matchgroup=luaCond start="\<then\>" end="\<end\>" contains=ALLBUT,luaTodo,luaSpecial,luaRepeat
+
+" elseif ... then
+syn region luaCondElseif contained transparent matchgroup=luaCond start="\<elseif\>" end="\<then\>" contains=ALLBUT,luaTodo,luaSpecial,luaCond,luaCondElseif,luaCondEnd,luaRepeat
+
+" if ... then
+syn region luaCondStart transparent matchgroup=luaCond start="\<if\>" end="\<then\>"me=e-4 contains=ALLBUT,luaTodo,luaSpecial,luaCond,luaCondElseif,luaCondEnd,luaRepeat nextgroup=luaCondEnd skipwhite skipempty
+
+" do ... end
+syn region luaBlock transparent matchgroup=luaStatement start="\<do\>" end="\<end\>" contains=ALLBUT,luaTodo,luaSpecial,luaCond,luaCondElseif,luaCondEnd,luaRepeat
+
+" repeat ... until
+syn region luaRepeatBlock transparent matchgroup=luaRepeat start="\<repeat\>" end="\<until\>" contains=ALLBUT,luaTodo,luaSpecial,luaCond,luaCondElseif,luaCondEnd,luaRepeat
+
+" while ... do
+syn region luaRepeatBlock transparent matchgroup=luaRepeat start="\<while\>" end="\<do\>"me=e-2 contains=ALLBUT,luaTodo,luaSpecial,luaCond,luaCondElseif,luaCondEnd,luaRepeat nextgroup=luaBlock skipwhite skipempty
+
+" for ... do and for ... in ... do
+syn region luaRepeatBlock transparent matchgroup=luaRepeat start="\<for\>" end="\<do\>"me=e-2 contains=ALLBUT,luaTodo,luaSpecial,luaCond,luaCondElseif,luaCondEnd nextgroup=luaBlock skipwhite skipempty
+
+" Following 'else' example. This is another item to those
+" contains=ALLBUT,... because only the 'for' luaRepeatBlock contains it.
+syn keyword luaRepeat contained in
+
+" other keywords
+syn keyword luaStatement return local break
+syn keyword luaOperator  and or not
+syn keyword luaConstant  nil
+if lua_version > 4
+  syn keyword luaConstant true false
+endif
+
+" Strings
+if lua_version < 5
+  syn match  luaSpecial contained "\\[\\abfnrtv\'\"]\|\\\d\{,3}"
+elseif lua_version == 5 && lua_subversion == 0
+  syn match  luaSpecial contained "\\[\\abfnrtv\'\"[\]]\|\\\d\{,3}"
+  syn region luaString2 matchgroup=luaString start=+\[\[+ end=+\]\]+ contains=luaString2,@Spell
+elseif lua_version > 5 || (lua_version == 5 && lua_subversion >= 1)
+  syn match  luaSpecial contained "\\[\\abfnrtv\'\"]\|\\\d\{,3}"
+  syn region luaString2 matchgroup=luaString start="\[\z(=*\)\[" end="\]\z1\]" contains=@Spell
+endif
+syn region luaString  start=+'+ end=+'+ skip=+\\\\\|\\'+ contains=luaSpecial,@Spell
+syn region luaString  start=+"+ end=+"+ skip=+\\\\\|\\"+ contains=luaSpecial,@Spell
+
+" integer number
+syn match luaNumber "\<\d\+\>"
+" floating point number, with dot, optional exponent
+syn match luaFloat  "\<\d\+\.\d*\%(e[-+]\=\d\+\)\=\>"
+" floating point number, starting with a dot, optional exponent
+syn match luaFloat  "\.\d\+\%(e[-+]\=\d\+\)\=\>"
+" floating point number, without dot, with exponent
+syn match luaFloat  "\<\d\+e[-+]\=\d\+\>"
+
+" hex numbers
+if lua_version > 5 || (lua_version == 5 && lua_subversion >= 1)
+  syn match luaNumber "\<0x\x\+\>"
+endif
+
+" tables
+syn region  luaTableBlock transparent matchgroup=luaTable start="{" end="}" contains=ALLBUT,luaTodo,luaSpecial,luaCond,luaCondElseif,luaCondEnd,luaCondStart,luaBlock,luaRepeatBlock,luaRepeat,luaStatement
+
+syn keyword luaFunc assert collectgarbage dofile error next
+syn keyword luaFunc print rawget rawset tonumber tostring type _VERSION
+
+if lua_version == 4
+  syn keyword luaFunc _ALERT _ERRORMESSAGE gcinfo
+  syn keyword luaFunc call copytagmethods dostring
+  syn keyword luaFunc foreach foreachi getglobal getn
+  syn keyword luaFunc gettagmethod globals newtag
+  syn keyword luaFunc setglobal settag settagmethod sort
+  syn keyword luaFunc tag tinsert tremove
+  syn keyword luaFunc _INPUT _OUTPUT _STDIN _STDOUT _STDERR
+  syn keyword luaFunc openfile closefile flush seek
+  syn keyword luaFunc setlocale execute remove rename tmpname
+  syn keyword luaFunc getenv date clock exit
+  syn keyword luaFunc readfrom writeto appendto read write
+  syn keyword luaFunc PI abs sin cos tan asin
+  syn keyword luaFunc acos atan atan2 ceil floor
+  syn keyword luaFunc mod frexp ldexp sqrt min max log
+  syn keyword luaFunc log10 exp deg rad random
+  syn keyword luaFunc randomseed strlen strsub strlower strupper
+  syn keyword luaFunc strchar strrep ascii strbyte
+  syn keyword luaFunc format strfind gsub
+  syn keyword luaFunc getinfo getlocal setlocal setcallhook setlinehook
+elseif lua_version == 5
+  " Not sure if all these functions need to be highlighted...
+  syn keyword luaFunc _G getfenv getmetatable ipairs loadfile
+  syn keyword luaFunc loadstring pairs pcall rawequal
+  syn keyword luaFunc require setfenv setmetatable unpack xpcall
+  if lua_subversion == 0
+    syn keyword luaFunc gcinfo loadlib LUA_PATH _LOADED _REQUIREDNAME
+  elseif lua_subversion == 1
+    syn keyword luaFunc load module select
+    syn match luaFunc /package\.cpath/
+    syn match luaFunc /package\.loaded/
+    syn match luaFunc /package\.loadlib/
+    syn match luaFunc /package\.path/
+    syn match luaFunc /package\.preload/
+    syn match luaFunc /package\.seeall/
+    syn match luaFunc /coroutine\.running/
+  endif
+  syn match   luaFunc /coroutine\.create/
+  syn match   luaFunc /coroutine\.resume/
+  syn match   luaFunc /coroutine\.status/
+  syn match   luaFunc /coroutine\.wrap/
+  syn match   luaFunc /coroutine\.yield/
+  syn match   luaFunc /string\.byte/
+  syn match   luaFunc /string\.char/
+  syn match   luaFunc /string\.dump/
+  syn match   luaFunc /string\.find/
+  syn match   luaFunc /string\.len/
+  syn match   luaFunc /string\.lower/
+  syn match   luaFunc /string\.rep/
+  syn match   luaFunc /string\.sub/
+  syn match   luaFunc /string\.upper/
+  syn match   luaFunc /string\.format/
+  syn match   luaFunc /string\.gsub/
+  if lua_subversion == 0
+    syn match luaFunc /string\.gfind/
+    syn match luaFunc /table\.getn/
+    syn match luaFunc /table\.setn/
+    syn match luaFunc /table\.foreach/
+    syn match luaFunc /table\.foreachi/
+  elseif lua_subversion == 1
+    syn match luaFunc /string\.gmatch/
+    syn match luaFunc /string\.match/
+    syn match luaFunc /string\.reverse/
+    syn match luaFunc /table\.maxn/
+  endif
+  syn match   luaFunc /table\.concat/
+  syn match   luaFunc /table\.sort/
+  syn match   luaFunc /table\.insert/
+  syn match   luaFunc /table\.remove/
+  syn match   luaFunc /math\.abs/
+  syn match   luaFunc /math\.acos/
+  syn match   luaFunc /math\.asin/
+  syn match   luaFunc /math\.atan/
+  syn match   luaFunc /math\.atan2/
+  syn match   luaFunc /math\.ceil/
+  syn match   luaFunc /math\.sin/
+  syn match   luaFunc /math\.cos/
+  syn match   luaFunc /math\.tan/
+  syn match   luaFunc /math\.deg/
+  syn match   luaFunc /math\.exp/
+  syn match   luaFunc /math\.floor/
+  syn match   luaFunc /math\.log/
+  syn match   luaFunc /math\.log10/
+  syn match   luaFunc /math\.max/
+  syn match   luaFunc /math\.min/
+  if lua_subversion == 0
+    syn match luaFunc /math\.mod/
+  elseif lua_subversion == 1
+    syn match luaFunc /math\.fmod/
+    syn match luaFunc /math\.modf/
+    syn match luaFunc /math\.cosh/
+    syn match luaFunc /math\.sinh/
+    syn match luaFunc /math\.tanh/
+  endif
+  syn match   luaFunc /math\.pow/
+  syn match   luaFunc /math\.rad/
+  syn match   luaFunc /math\.sqrt/
+  syn match   luaFunc /math\.frexp/
+  syn match   luaFunc /math\.ldexp/
+  syn match   luaFunc /math\.random/
+  syn match   luaFunc /math\.randomseed/
+  syn match   luaFunc /math\.pi/
+  syn match   luaFunc /io\.stdin/
+  syn match   luaFunc /io\.stdout/
+  syn match   luaFunc /io\.stderr/
+  syn match   luaFunc /io\.close/
+  syn match   luaFunc /io\.flush/
+  syn match   luaFunc /io\.input/
+  syn match   luaFunc /io\.lines/
+  syn match   luaFunc /io\.open/
+  syn match   luaFunc /io\.output/
+  syn match   luaFunc /io\.popen/
+  syn match   luaFunc /io\.read/
+  syn match   luaFunc /io\.tmpfile/
+  syn match   luaFunc /io\.type/
+  syn match   luaFunc /io\.write/
+  syn match   luaFunc /os\.clock/
+  syn match   luaFunc /os\.date/
+  syn match   luaFunc /os\.difftime/
+  syn match   luaFunc /os\.execute/
+  syn match   luaFunc /os\.exit/
+  syn match   luaFunc /os\.getenv/
+  syn match   luaFunc /os\.remove/
+  syn match   luaFunc /os\.rename/
+  syn match   luaFunc /os\.setlocale/
+  syn match   luaFunc /os\.time/
+  syn match   luaFunc /os\.tmpname/
+  syn match   luaFunc /debug\.debug/
+  syn match   luaFunc /debug\.gethook/
+  syn match   luaFunc /debug\.getinfo/
+  syn match   luaFunc /debug\.getlocal/
+  syn match   luaFunc /debug\.getupvalue/
+  syn match   luaFunc /debug\.setlocal/
+  syn match   luaFunc /debug\.setupvalue/
+  syn match   luaFunc /debug\.sethook/
+  syn match   luaFunc /debug\.traceback/
+  if lua_subversion == 1
+    syn match luaFunc /debug\.getfenv/
+    syn match luaFunc /debug\.getmetatable/
+    syn match luaFunc /debug\.getregistry/
+    syn match luaFunc /debug\.setfenv/
+    syn match luaFunc /debug\.setmetatable/
+  endif
+endif
+
+" Define the default highlighting.
+" For version 5.7 and earlier: only when not done already
+" For version 5.8 and later: only when an item doesn't have highlighting yet
+if version >= 508 || !exists("did_lua_syntax_inits")
+  if version < 508
+    let did_lua_syntax_inits = 1
+    command -nargs=+ HiLink hi link <args>
+  else
+    command -nargs=+ HiLink hi def link <args>
+  endif
+
+  HiLink luaStatement		Statement
+  HiLink luaRepeat		Repeat
+  HiLink luaString		String
+  HiLink luaString2		String
+  HiLink luaNumber		Number
+  HiLink luaFloat		Float
+  HiLink luaOperator		Operator
+  HiLink luaConstant		Constant
+  HiLink luaCond		Conditional
+  HiLink luaFunction		Function
+  HiLink luaComment		Comment
+  HiLink luaTodo		Todo
+  HiLink luaTable		Structure
+  HiLink luaError		Error
+  HiLink luaSpecial		SpecialChar
+  HiLink luaFunc		Identifier
+
+  delcommand HiLink
+endif
+
+let b:current_syntax = "lua"
+
+" vim: et ts=8
--- /dev/null
+++ b/lib/vimfiles/syntax/lynx.vim
@@ -1,0 +1,94 @@
+" Vim syntax file
+" Language:	Lynx configuration file (lynx.cfg)
+" Maintainer:	Doug Kearns <dougkearns@gmail.com>
+" URL:		http://gus.gscit.monash.edu.au/~djkea2/vim/syntax/lynx.vim
+" Last Change:	2007 Mar 20
+
+" Lynx 2.8.5
+
+if exists("b:current_syntax")
+  finish
+endif
+
+let s:cpo_save = &cpo
+set cpo&vim
+
+syn match   lynxLeadingWS  "^\s*" transparent nextgroup=lynxOption
+
+syn match   lynxComment    "\(^\|\s\+\)#.*$" contains=lynxTodo
+
+syn keyword lynxTodo	   TODO NOTE FIXME XXX contained
+
+syn match   lynxDelimiter  ":" contained nextgroup=lynxBoolean,lynxNumber
+
+syn case ignore
+syn keyword lynxBoolean    TRUE FALSE contained
+syn case match
+
+syn match   lynxNumber	   "-\=\<\d\+\>" contained
+
+syn case ignore
+syn keyword lynxOption ACCEPT_ALL_COOKIES ALERTSECS ALWAYS_RESUBMIT_POSTS ALWAYS_TRUSTED_EXEC ASSUME_CHARSET
+		     \ ASSUMED_COLOR ASSUMED_DOC_CHARSET_CHOICE ASSUME_LOCAL_CHARSET ASSUME_UNREC_CHARSET AUTO_UNCACHE_DIRLISTS
+		     \ BIBP_BIBHOST BIBP_GLOBAL_SERVER BLOCK_MULTI_BOOKMARKS BOLD_H1 BOLD_HEADERS
+		     \ BOLD_NAME_ANCHORS CASE_SENSITIVE_ALWAYS_ON CHARACTER_SET CHARSETS_DIRECTORY CHARSET_SWITCH_RULES
+		     \ CHECKMAIL COLLAPSE_BR_TAGS COLOR CONNECT_TIMEOUT COOKIE_ACCEPT_DOMAINS
+		     \ COOKIE_FILE COOKIE_LOOSE_INVALID_DOMAINS COOKIE_QUERY_INVALID_DOMAINS COOKIE_REJECT_DOMAINS COOKIE_SAVE_FILE
+		     \ COOKIE_STRICT_INVALID_DOMAINS CSO_PROXY CSWING_PATH DEBUGSECS DEFAULT_BOOKMARK_FILE
+		     \ DEFAULT_CACHE_SIZE DEFAULT_EDITOR DEFAULT_INDEX_FILE DEFAULT_KEYPAD_MODE DEFAULT_KEYPAD_MODE_IS_NUMBERS_AS_ARROWS
+		     \ DEFAULT_USER_MODE DEFAULT_VIRTUAL_MEMORY_SIZE DIRED_MENU DISPLAY_CHARSET_CHOICE DOWNLOADER
+		     \ EMACS_KEYS_ALWAYS_ON ENABLE_LYNXRC ENABLE_SCROLLBACK EXTERNAL FINGER_PROXY
+		     \ FOCUS_WINDOW FORCE_8BIT_TOUPPER FORCE_COOKIE_PROMPT FORCE_EMPTY_HREFLESS_A FORCE_SSL_COOKIES_SECURE
+		     \ FORCE_SSL_PROMPT FORMS_OPTIONS FTP_PASSIVE FTP_PROXY GLOBAL_EXTENSION_MAP
+		     \ GLOBAL_MAILCAP GOPHER_PROXY GOTOBUFFER HELPFILE HIDDEN_LINK_MARKER
+		     \ HISTORICAL_COMMENTS HTMLSRC_ATTRNAME_XFORM HTMLSRC_TAGNAME_XFORM HTTP_PROXY HTTPS_PROXY
+		     \ INCLUDE INFOSECS JUMPBUFFER JUMPFILE JUMP_PROMPT
+		     \ JUSTIFY JUSTIFY_MAX_VOID_PERCENT KEYBOARD_LAYOUT KEYMAP LEFTARROW_IN_TEXTFIELD_PROMPT
+		     \ LIST_FORMAT LIST_NEWS_DATES LIST_NEWS_NUMBERS LOCAL_DOMAIN LOCALE_CHARSET
+		     \ LOCAL_EXECUTION_LINKS_ALWAYS_ON LOCAL_EXECUTION_LINKS_ON_BUT_NOT_REMOTE LOCALHOST_ALIAS LYNXCGI_DOCUMENT_ROOT LYNXCGI_ENVIRONMENT
+		     \ LYNX_HOST_NAME LYNX_SIG_FILE MAIL_ADRS MAIL_SYSTEM_ERROR_LOGGING MAKE_LINKS_FOR_ALL_IMAGES
+		     \ MAKE_PSEUDO_ALTS_FOR_INLINES MESSAGESECS MINIMAL_COMMENTS MULTI_BOOKMARK_SUPPORT NCR_IN_BOOKMARKS
+		     \ NEWS_CHUNK_SIZE NEWS_MAX_CHUNK NEWS_POSTING NEWSPOST_PROXY NEWS_PROXY
+		     \ NEWSREPLY_PROXY NNTP_PROXY NNTPSERVER NO_DOT_FILES NO_FILE_REFERER
+		     \ NO_FORCED_CORE_DUMP NO_FROM_HEADER NO_ISMAP_IF_USEMAP NONRESTARTING_SIGWINCH NO_PROXY
+		     \ NO_REFERER_HEADER NO_TABLE_CENTER NUMBER_FIELDS_ON_LEFT NUMBER_LINKS_ON_LEFT OUTGOING_MAIL_CHARSET
+		     \ PARTIAL PARTIAL_THRES PERSISTENT_COOKIES PERSONAL_EXTENSION_MAP PERSONAL_MAILCAP
+		     \ PREFERRED_CHARSET PREFERRED_LANGUAGE PREPEND_BASE_TO_SOURCE PREPEND_CHARSET_TO_SOURCE PRETTYSRC
+		     \ PRETTYSRC_SPEC PRETTYSRC_VIEW_NO_ANCHOR_NUMBERING PRINTER QUIT_DEFAULT_YES REFERER_WITH_QUERY
+		     \ REPLAYSECS REUSE_TEMPFILES RULE RULESFILE SAVE_SPACE
+		     \ SCAN_FOR_BURIED_NEWS_REFS SCREEN_SIZE SCROLLBAR SCROLLBAR_ARROW SEEK_FRAG_AREA_IN_CUR
+		     \ SEEK_FRAG_MAP_IN_CUR SET_COOKIES SHOW_CURSOR SHOW_KB_NAME SHOW_KB_RATE
+		     \ SNEWSPOST_PROXY SNEWS_PROXY SNEWSREPLY_PROXY SOFT_DQUOTES SOURCE_CACHE
+		     \ SOURCE_CACHE_FOR_ABORTED STARTFILE STRIP_DOTDOT_URLS SUBSTITUTE_UNDERSCORES SUFFIX
+		     \ SUFFIX_ORDER SYSTEM_EDITOR SYSTEM_MAIL SYSTEM_MAIL_FLAGS TAGSOUP
+		     \ TEXTFIELDS_NEED_ACTIVATION TIMEOUT TRIM_INPUT_FIELDS TRUSTED_EXEC TRUSTED_LYNXCGI
+		     \ UNDERLINE_LINKS UPLOADER URL_DOMAIN_PREFIXES URL_DOMAIN_SUFFIXES USE_FIXED_RECORDS
+		     \ USE_MOUSE USE_SELECT_POPUPS VERBOSE_IMAGES VIEWER VI_KEYS_ALWAYS_ON
+		     \ WAIS_PROXY XLOADIMAGE_COMMAND contained nextgroup=lynxDelimiter
+syn keyword lynxOption BZIP2_PATH CHMOD_PATH COMPRESS_PATH COPY_PATH GZIP_PATH
+		     \ INSTALL_PATH MKDIR_PATH MV_PATH RLOGIN_PATH RMDIR_PATH
+		     \ RM_PATH TAR_PATH TELNET_PATH TN3270_PATH TOUCH_PATH
+		     \ UNCOMPRESS_PATH UNZIP_PATH UUDECODE_PATH ZCAT_PATH ZIP_PATH contained nextgroup=lynxDelimiter
+syn case match
+
+" NOTE: set this if you want the cfg2html.pl formatting directives to be highlighted
+if exists("lynx_formatting_directives")
+  syn match lynxFormatDir  "^\.\(h1\|h2\)\s.*$"
+  syn match lynxFormatDir  "^\.\(ex\|nf\)\(\s\+\d\+\)\=$"
+  syn match lynxFormatDir  "^\.fi$"
+endif
+
+hi def link lynxBoolean		Boolean
+hi def link lynxComment		Comment
+hi def link lynxDelimiter	Special
+hi def link lynxFormatDir	Special
+hi def link lynxNumber		Number
+hi def link lynxOption		Identifier
+hi def link lynxTodo		Todo
+
+let b:current_syntax = "lynx"
+
+let &cpo = s:cpo_save
+unlet s:cpo_save
+
+" vim: ts=8
--- /dev/null
+++ b/lib/vimfiles/syntax/m4.vim
@@ -1,0 +1,73 @@
+" Vim syntax file
+" Language:		M4
+" Maintainer:	Claudio Fleiner (claudio@fleiner.com)
+" URL:			http://www.fleiner.com/vim/syntax/m4.vim
+" Last Change:	2005 Jan 15
+
+" This file will highlight user function calls if they use only
+" capital letters and have at least one argument (i.e. the '('
+" must be there). Let me know if this is a problem.
+
+" For version 5.x: Clear all syntax items
+" For version 6.x: Quit when a syntax file was already loaded
+if !exists("main_syntax")
+  if version < 600
+    syntax clear
+  elseif exists("b:current_syntax")
+  finish
+endif
+" we define it here so that included files can test for it
+  let main_syntax='m4'
+endif
+
+" define the m4 syntax
+syn match  m4Variable contained "\$\d\+"
+syn match  m4Special  contained "$[@*#]"
+syn match  m4Comment  "\<\(m4_\)\=dnl\>.*" contains=SpellErrors
+syn match  m4Constants "\<\(m4_\)\=__file__"
+syn match  m4Constants "\<\(m4_\)\=__line__"
+syn keyword m4Constants divnum sysval m4_divnum m4_sysval
+syn region m4Paren    matchgroup=m4Delimiter start="(" end=")" contained contains=@m4Top
+syn region m4Command  matchgroup=m4Function  start="\<\(m4_\)\=\(define\|defn\|pushdef\)(" end=")" contains=@m4Top
+syn region m4Command  matchgroup=m4Preproc   start="\<\(m4_\)\=\(include\|sinclude\)("he=e-1 end=")" contains=@m4Top
+syn region m4Command  matchgroup=m4Statement start="\<\(m4_\)\=\(syscmd\|esyscmd\|ifdef\|ifelse\|indir\|builtin\|shift\|errprint\|m4exit\|changecom\|changequote\|changeword\|m4wrap\|debugfile\|divert\|undivert\)("he=e-1 end=")" contains=@m4Top
+syn region m4Command  matchgroup=m4builtin start="\<\(m4_\)\=\(len\|index\|regexp\|substr\|translit\|patsubst\|format\|incr\|decr\|eval\|maketemp\)("he=e-1 end=")" contains=@m4Top
+syn keyword m4Statement divert undivert
+syn region m4Command  matchgroup=m4Type      start="\<\(m4_\)\=\(undefine\|popdef\)("he=e-1 end=")" contains=@m4Top
+syn region m4Function matchgroup=m4Type      start="\<[_A-Z][_A-Z0-9]*("he=e-1 end=")" contains=@m4Top
+syn region m4String   start="`" end="'" contained contains=@m4Top,@m4StringContents,SpellErrors
+syn cluster m4Top     contains=m4Comment,m4Constants,m4Special,m4Variable,m4String,m4Paren,m4Command,m4Statement,m4Function
+
+" Define the default highlighting.
+" For version 5.7 and earlier: only when not done already
+" For version 5.8 and later: only when an item doesn't have highlighting yet
+if version >= 508 || !exists("did_m4_syn_inits")
+  if version < 508
+    let did_m4_syn_inits = 1
+    command -nargs=+ HiLink hi link <args>
+  else
+    command -nargs=+ HiLink hi def link <args>
+  endif
+  HiLink m4Delimiter Delimiter
+  HiLink m4Comment   Comment
+  HiLink m4Function  Function
+  HiLink m4Keyword   Keyword
+  HiLink m4Special   Special
+  HiLink m4String    String
+  HiLink m4Statement Statement
+  HiLink m4Preproc   PreProc
+  HiLink m4Type      Type
+  HiLink m4Special   Special
+  HiLink m4Variable  Special
+  HiLink m4Constants Constant
+  HiLink m4Builtin   Statement
+  delcommand HiLink
+endif
+
+let b:current_syntax = "m4"
+
+if main_syntax == 'm4'
+  unlet main_syntax
+endif
+
+" vim: ts=4
--- /dev/null
+++ b/lib/vimfiles/syntax/mail.vim
@@ -1,0 +1,96 @@
+" Vim syntax file
+" Language:		Mail file
+" Previous Maintainer:	Felix von Leitner <leitner@math.fu-berlin.de>
+" Maintainer:		Gautam Iyer <gautam@math.uchicago.edu>
+" Last Change:		Wed 01 Jun 2005 02:11:07 PM CDT
+
+" Quit when a syntax file was already loaded
+if exists("b:current_syntax")
+  finish
+endif
+
+" The mail header is recognized starting with a "keyword:" line and ending
+" with an empty line or other line that can't be in the header. All lines of
+" the header are highlighted. Headers of quoted messages (quoted with >) are
+" also highlighted.
+
+" Syntax clusters
+syn cluster mailHeaderFields	contains=mailHeaderKey,mailSubject,mailHeaderEmail,@mailLinks
+syn cluster mailLinks		contains=mailURL,mailEmail
+syn cluster mailQuoteExps	contains=mailQuoteExp1,mailQuoteExp2,mailQuoteExp3,mailQuoteExp4,mailQuoteExp5,mailQuoteExp6
+
+syn case match
+" For "From " matching case is required. The "From " is not matched in quoted
+" emails
+" According to RFC 2822 any printable ASCII character can appear in a field
+" name, except ':'.
+syn region	mailHeader	contains=@mailHeaderFields,@NoSpell start="^From " skip="^\s" end="\v^[!-9;-~]*([^!-~]|$)"me=s-1
+syn match	mailHeaderKey	contained contains=mailEmail,@NoSpell "^From\s.*$"
+
+syn case ignore
+" Nothing else depends on case. Headers in properly quoted (with "> " or ">")
+" emails are matched
+syn region	mailHeader	keepend contains=@mailHeaderFields,@mailQuoteExps,@NoSpell start="^\z(\(> \?\)*\)\v(newsgroups|from|((in-)?reply-)?to|b?cc|subject|return-path|received|date|replied):" skip="^\z1\s" end="\v^\z1[!-9;-~]*([^!-~]|$)"me=s-1 end="\v^\z1@!"me=s-1 end="\v^\z1(\> ?)+"me=s-1
+
+syn region	mailHeaderKey	contained contains=mailHeaderEmail,mailEmail,@mailQuoteExps,@NoSpell start="\v(^(\> ?)*)@<=(to|b?cc):" skip=",$" end="$"
+syn match	mailHeaderKey	contained contains=mailHeaderEmail,mailEmail,@NoSpell "\v(^(\> ?)*)@<=(from|reply-to):.*$"
+syn match	mailHeaderKey	contained contains=@NoSpell "\v(^(\> ?)*)@<=date:"
+syn match	mailSubject	contained "\v^subject:.*$"
+syn match	mailSubject	contained contains=@NoSpell "\v(^(\> ?)+)@<=subject:.*$"
+
+" Anything in the header between < and > is an email address
+syn match	mailHeaderEmail	contained contains=@NoSpell "<.\{-}>"
+
+" Mail Signatures. (Begin with "-- ", end with change in quote level)
+syn region	mailSignature	keepend contains=@mailLinks,@mailQuoteExps start="^--\s$" end="^$" end="^\(> \?\)\+"me=s-1
+syn region	mailSignature	keepend contains=@mailLinks,@mailQuoteExps,@NoSpell start="^\z(\(> \?\)\+\)--\s$" end="^\z1$" end="^\z1\@!"me=s-1 end="^\z1\(> \?\)\+"me=s-1
+
+" URLs start with a known protocol or www,web,w3.
+syn match mailURL contains=@NoSpell `\v<(((https?|ftp|gopher)://|(mailto|file|news):)[^' 	<>"]+|(www|web|w3)[a-z0-9_-]*\.[a-z0-9._-]+\.[^' 	<>"]+)[a-z0-9/]`
+syn match mailEmail contains=@NoSpell "\v[_=a-z\./+0-9-]+\@[a-z0-9._-]+\a{2}"
+
+" Make sure quote markers in regions (header / signature) have correct color
+syn match mailQuoteExp1	contained "\v^(\> ?)"
+syn match mailQuoteExp2	contained "\v^(\> ?){2}"
+syn match mailQuoteExp3	contained "\v^(\> ?){3}"
+syn match mailQuoteExp4	contained "\v^(\> ?){4}"
+syn match mailQuoteExp5	contained "\v^(\> ?){5}"
+syn match mailQuoteExp6	contained "\v^(\> ?){6}"
+
+" Even and odd quoted lines. order is imporant here!
+syn match mailQuoted1	contains=mailHeader,@mailLinks,mailSignature,@NoSpell "^\([a-z]\+>\|[]|}>]\).*$"
+syn match mailQuoted2	contains=mailHeader,@mailLinks,mailSignature,@NoSpell "^\(\([a-z]\+>\|[]|}>]\)[ \t]*\)\{2}.*$"
+syn match mailQuoted3	contains=mailHeader,@mailLinks,mailSignature,@NoSpell "^\(\([a-z]\+>\|[]|}>]\)[ \t]*\)\{3}.*$"
+syn match mailQuoted4	contains=mailHeader,@mailLinks,mailSignature,@NoSpell "^\(\([a-z]\+>\|[]|}>]\)[ \t]*\)\{4}.*$"
+syn match mailQuoted5	contains=mailHeader,@mailLinks,mailSignature,@NoSpell "^\(\([a-z]\+>\|[]|}>]\)[ \t]*\)\{5}.*$"
+syn match mailQuoted6	contains=mailHeader,@mailLinks,mailSignature,@NoSpell "^\(\([a-z]\+>\|[]|}>]\)[ \t]*\)\{6}.*$"
+
+" Need to sync on the header. Assume we can do that within 100 lines
+if exists("mail_minlines")
+    exec "syn sync minlines=" . mail_minlines
+else
+    syn sync minlines=100
+endif
+
+" Define the default highlighting.
+hi def link mailHeader		Statement
+hi def link mailHeaderKey	Type
+hi def link mailSignature	PreProc
+hi def link mailHeaderEmail	mailEmail
+hi def link mailEmail		Special
+hi def link mailURL		String
+hi def link mailSubject		LineNR
+hi def link mailQuoted1		Comment
+hi def link mailQuoted3		mailQuoted1
+hi def link mailQuoted5		mailQuoted1
+hi def link mailQuoted2		Identifier
+hi def link mailQuoted4		mailQuoted2
+hi def link mailQuoted6		mailQuoted2
+hi def link mailQuoteExp1	mailQuoted1
+hi def link mailQuoteExp2	mailQuoted2
+hi def link mailQuoteExp3	mailQuoted3
+hi def link mailQuoteExp4	mailQuoted4
+hi def link mailQuoteExp5	mailQuoted5
+hi def link mailQuoteExp6	mailQuoted6
+
+let b:current_syntax = "mail"
--- /dev/null
+++ b/lib/vimfiles/syntax/mailaliases.vim
@@ -1,0 +1,71 @@
+" Vim syntax file
+" Language:         aliases(5) local alias database file
+" Maintainer:       Nikolai Weibull <nikolai@bitwi.se>
+" Latest Revision:  2006-01-14
+
+if exists("b:current_syntax")
+  finish
+endif
+
+let s:cpo_save = &cpo
+set cpo&vim
+
+syn keyword mailaliasesTodo         contained TODO FIXME XXX NOTE
+
+syn region  mailaliasesComment      display oneline start='^\s*#' end='$'
+                                    \ contains=mailaliasesTodo,@Spell
+
+syn match   mailaliasesBegin        display '^'
+                                    \ nextgroup=mailaliasesName,
+                                    \ mailaliasesComment
+
+syn match   mailaliasesName         contained '[0-9A-Za-z_-]\+'
+                                    \ nextgroup=mailaliasesColon
+
+syn region  mailaliasesName         contained oneline start=+"+
+                                    \ skip=+\\\\\|\\"+ end=+"+
+                                    \ nextgroup=mailaliasesColon
+
+syn match   mailaliasesColon        contained ':'
+                                    \ nextgroup=@mailaliasesValue
+                                    \ skipwhite skipnl
+
+syn cluster mailaliasesValue        contains=mailaliasesValueAddress,
+                                    \ mailaliasesValueFile,
+                                    \ mailaliasesValueCommand,
+                                    \ mailaliasesValueInclude
+
+syn match   mailaliasesValueAddress contained '[^ \t/|,]\+'
+                                    \ nextgroup=mailaliasesValueSep
+                                    \ skipwhite skipnl
+
+syn match   mailaliasesValueFile    contained '/[^,]*'
+                                    \ nextgroup=mailaliasesValueSep
+                                    \ skipwhite skipnl
+
+syn match   mailaliasesValueCommand contained '|[^,]*'
+                                    \ nextgroup=mailaliasesValueSep
+                                    \ skipwhite skipnl
+
+syn match   mailaliasesValueInclude contained ':include:[^,]*'
+                                    \ nextgroup=mailaliasesValueSep
+                                    \ skipwhite skipnl
+
+syn match   mailaliasesValueSep     contained ','
+                                    \ nextgroup=@mailaliasesValue
+                                    \ skipwhite skipnl
+
+hi def link mailaliasesTodo         Todo
+hi def link mailaliasesComment      Comment
+hi def link mailaliasesName         Identifier
+hi def link mailaliasesColon        Delimiter
+hi def link mailaliasesValueAddress String
+hi def link mailaliasesValueFile    String
+hi def link mailaliasesValueCommand String
+hi def link mailaliasesValueInclude PreProc
+hi def link mailaliasesValueSep     Delimiter
+
+let b:current_syntax = "mailaliases"
+
+let &cpo = s:cpo_save
+unlet s:cpo_save
--- /dev/null
+++ b/lib/vimfiles/syntax/mailcap.vim
@@ -1,0 +1,54 @@
+" Vim syntax file
+" Language:	Mailcap configuration file
+" Maintainer:	Doug Kearns <djkea2@gus.gscit.monash.edu.au>
+" Last Change:	2004 Nov 27
+" URL:		http://gus.gscit.monash.edu.au/~djkea2/vim/syntax/mailcap.vim
+
+" For version 5.x: Clear all syntax items
+" For version 6.x: Quit when a syntax file was already loaded
+if version < 600
+  syntax clear
+elseif exists("b:current_syntax")
+  finish
+endif
+
+syn match  mailcapComment	"^#.*"
+
+syn region mailcapString	start=+"+ end=+"+ contains=mailcapSpecial oneline
+
+syn match  mailcapDelimiter	"\\\@<!;"
+
+syn match  mailcapSpecial	"\\\@<!%[nstF]"
+syn match  mailcapSpecial	"\\\@<!%{[^}]*}"
+
+syn case ignore
+syn match  mailcapFlag		"\(=\s*\)\@<!\<\(needsterminal\|copiousoutput\|x-\w\+\)\>"
+syn match  mailcapFieldname	"\<\(compose\|composetyped\|print\|edit\|test\|x11-bitmap\|nametemplate\|textualnewlines\|description\|x-\w+\)\>\ze\s*="
+syn match  mailcapTypeField	"^\(text\|image\|audio\|video\|application\|message\|multipart\|model\|x-[[:graph:]]\+\)\(/\(\*\|[[:graph:]]\+\)\)\=\ze\s*;"
+syn case match
+
+" Define the default highlighting.
+" For version 5.7 and earlier: only when not done already
+" For version 5.8 and later: only when an item doesn't have highlighting yet
+if version >= 508 || !exists("did_mailcap_syntax_inits")
+  if version < 508
+    let did_mailcap_syntax_inits = 1
+    command -nargs=+ HiLink hi link <args>
+  else
+    command -nargs=+ HiLink hi def link <args>
+  endif
+
+  HiLink mailcapComment		Comment
+  HiLink mailcapDelimiter	Delimiter
+  HiLink mailcapFlag		Statement
+  HiLink mailcapFieldname	Statement
+  HiLink mailcapSpecial		Identifier
+  HiLink mailcapTypeField	Type
+  HiLink mailcapString		String
+
+  delcommand HiLink
+endif
+
+let b:current_syntax = "mailcap"
+
+" vim: tabstop=8
--- /dev/null
+++ b/lib/vimfiles/syntax/make.vim
@@ -1,0 +1,137 @@
+" Vim syntax file
+" Language:	Makefile
+" Maintainer:	Claudio Fleiner <claudio@fleiner.com>
+" URL:		http://www.fleiner.com/vim/syntax/make.vim
+" Last Change:	2007 Apr 30
+
+" For version 5.x: Clear all syntax items
+" For version 6.x: Quit when a syntax file was already loaded
+if version < 600
+  syntax clear
+elseif exists("b:current_syntax")
+  finish
+endif
+
+" some special characters
+syn match makeSpecial	"^\s*[@+-]\+"
+syn match makeNextLine	"\\\n\s*"
+
+" some directives
+syn match makePreCondit	"^ *\(ifeq\>\|else\>\|endif\>\|ifneq\>\|ifdef\>\|ifndef\>\)"
+syn match makeInclude	"^ *[-s]\=include"
+syn match makeStatement	"^ *vpath"
+syn match makeExport    "^ *\(export\|unexport\)\>"
+syn match makeOverride	"^ *override"
+hi link makeOverride makeStatement
+hi link makeExport makeStatement
+
+" Koehler: catch unmatched define/endef keywords.  endef only matches it is by itself on a line
+syn region makeDefine start="^\s*define\s" end="^\s*endef\s*$" contains=makeStatement,makeIdent,makePreCondit,makeDefine
+
+" Microsoft Makefile specials
+syn case ignore
+syn match makeInclude	"^! *include"
+syn match makePreCondit "! *\(cmdswitches\|error\|message\|include\|if\|ifdef\|ifndef\|else\|elseif\|else if\|else\s*ifdef\|else\s*ifndef\|endif\|undef\)\>"
+syn case match
+
+" identifiers
+syn region makeIdent	start="\$(" skip="\\)\|\\\\" end=")" contains=makeStatement,makeIdent,makeSString,makeDString
+syn region makeIdent	start="\${" skip="\\}\|\\\\" end="}" contains=makeStatement,makeIdent,makeSString,makeDString
+syn match makeIdent	"\$\$\w*"
+syn match makeIdent	"\$[^({]"
+syn match makeIdent	"^ *\a\w*\s*[:+?!*]="me=e-2
+syn match makeIdent	"^ *\a\w*\s*="me=e-1
+syn match makeIdent	"%"
+
+" Makefile.in variables
+syn match makeConfig "@[A-Za-z0-9_]\+@"
+
+" make targets
+" syn match makeSpecTarget	"^\.\(SUFFIXES\|PHONY\|DEFAULT\|PRECIOUS\|IGNORE\|SILENT\|EXPORT_ALL_VARIABLES\|KEEP_STATE\|LIBPATTERNS\|NOTPARALLEL\|DELETE_ON_ERROR\|INTERMEDIATE\|POSIX\|SECONDARY\)\>"
+syn match makeImplicit		"^\.[A-Za-z0-9_./\t -]\+\s*:[^=]"me=e-2 nextgroup=makeSource
+syn match makeImplicit		"^\.[A-Za-z0-9_./\t -]\+\s*:$"me=e-1 nextgroup=makeSource
+
+syn region makeTarget	transparent matchgroup=makeTarget start="^[A-Za-z0-9_./$()%-][A-Za-z0-9_./\t $()%-]*:\{1,2}[^:=]"rs=e-1 end=";"re=e-1,me=e-1 end="[^\\]$" keepend contains=makeIdent,makeSpecTarget,makeNextLine skipnl nextGroup=makeCommands
+syn match makeTarget		"^[A-Za-z0-9_./$()%*@-][A-Za-z0-9_./\t $()%*@-]*::\=\s*$" contains=makeIdent,makeSpecTarget skipnl nextgroup=makeCommands,makeCommandError
+
+syn region makeSpecTarget	transparent matchgroup=makeSpecTarget start="^\.\(SUFFIXES\|PHONY\|DEFAULT\|PRECIOUS\|IGNORE\|SILENT\|EXPORT_ALL_VARIABLES\|KEEP_STATE\|LIBPATTERNS\|NOTPARALLEL\|DELETE_ON_ERROR\|INTERMEDIATE\|POSIX\|SECONDARY\)\>\s*:\{1,2}[^:=]"rs=e-1 end="[^\\]$" keepend contains=makeIdent,makeSpecTarget,makeNextLine skipnl nextGroup=makeCommands
+syn match makeSpecTarget		"^\.\(SUFFIXES\|PHONY\|DEFAULT\|PRECIOUS\|IGNORE\|SILENT\|EXPORT_ALL_VARIABLES\|KEEP_STATE\|LIBPATTERNS\|NOTPARALLEL\|DELETE_ON_ERROR\|INTERMEDIATE\|POSIX\|SECONDARY\)\>\s*::\=\s*$" contains=makeIdent skipnl nextgroup=makeCommands,makeCommandError
+
+syn match makeCommandError "^\s\+\S.*" contained
+syn region makeCommands start=";"hs=s+1 start="^\t" end="^[^\t#]"me=e-1,re=e-1 end="^$" contained contains=makeCmdNextLine,makeSpecial,makeComment,makeIdent,makePreCondit,makeDefine,makeDString,makeSString nextgroup=makeCommandError
+syn match makeCmdNextLine	"\\\n."he=e-1 contained
+
+
+" Statements / Functions (GNU make)
+syn match makeStatement contained "(\(subst\|addprefix\|addsuffix\|basename\|call\|dir\|error\|eval\|filter-out\|filter\|findstring\|firstword\|foreach\|if\|join\|notdir\|origin\|patsubst\|shell\|sort\|strip\|suffix\|warning\|wildcard\|word\|wordlist\|words\)\>"ms=s+1
+
+" Comment
+if exists("make_microsoft")
+   syn match  makeComment "#.*" contains=@Spell,makeTodo
+elseif !exists("make_no_comments")
+   syn region  makeComment	start="#" end="^$" end="[^\\]$" keepend contains=@Spell,makeTodo
+   syn match   makeComment	"#$" contains=@Spell
+endif
+syn keyword makeTodo TODO FIXME XXX contained
+
+" match escaped quotes and any other escaped character
+" except for $, as a backslash in front of a $ does
+" not make it a standard character, but instead it will
+" still act as the beginning of a variable
+" The escaped char is not highlightet currently
+syn match makeEscapedChar	"\\[^$]"
+
+
+syn region  makeDString start=+\(\\\)\@<!"+  skip=+\\.+  end=+"+  contains=makeIdent
+syn region  makeSString start=+\(\\\)\@<!'+  skip=+\\.+  end=+'+  contains=makeIdent
+syn region  makeBString start=+\(\\\)\@<!`+  skip=+\\.+  end=+`+  contains=makeIdent,makeSString,makeDString,makeNextLine
+
+" Syncing
+syn sync minlines=20 maxlines=200
+
+" Sync on Make command block region: When searching backwards hits a line that
+" can't be a command or a comment, use makeCommands if it looks like a target,
+" NONE otherwise.
+syn sync match makeCommandSync groupthere NONE "^[^\t#]"
+syn sync match makeCommandSync groupthere makeCommands "^[A-Za-z0-9_./$()%-][A-Za-z0-9_./\t $()%-]*:\{1,2}[^:=]"
+syn sync match makeCommandSync groupthere makeCommands "^[A-Za-z0-9_./$()%-][A-Za-z0-9_./\t $()%-]*:\{1,2}\s*$"
+
+" Define the default highlighting.
+" For version 5.7 and earlier: only when not done already
+" For version 5.8 and later: only when an item doesn't have highlighting yet
+if version >= 508 || !exists("did_make_syn_inits")
+  if version < 508
+    let did_make_syn_inits = 1
+    command -nargs=+ HiLink hi link <args>
+  else
+    command -nargs=+ HiLink hi def link <args>
+  endif
+
+  HiLink makeNextLine		makeSpecial
+  HiLink makeCmdNextLine	makeSpecial
+  HiLink makeSpecTarget		Statement
+  if !exists("make_no_commands")
+    HiLink makeCommands		Number
+  endif
+  HiLink makeImplicit		Function
+  HiLink makeTarget		Function
+  HiLink makeInclude		Include
+  HiLink makePreCondit		PreCondit
+  HiLink makeStatement		Statement
+  HiLink makeIdent		Identifier
+  HiLink makeSpecial		Special
+  HiLink makeComment		Comment
+  HiLink makeDString		String
+  HiLink makeSString		String
+  HiLink makeBString		Function
+  HiLink makeError		Error
+  HiLink makeTodo		Todo
+  HiLink makeDefine		Define
+  HiLink makeCommandError	Error
+  HiLink makeConfig		PreCondit
+  delcommand HiLink
+endif
+
+let b:current_syntax = "make"
+
+" vim: ts=8
--- /dev/null
+++ b/lib/vimfiles/syntax/man.vim
@@ -1,0 +1,67 @@
+" Vim syntax file
+" Language:	Man page
+" Maintainer:	Nam SungHyun <namsh@kldp.org>
+" Previous Maintainer:	Gautam H. Mudunuri <gmudunur@informatica.com>
+" Version Info:
+" Last Change:	2004 May 16
+
+" Additional highlighting by Johannes Tanzler <johannes.tanzler@aon.at>:
+"	* manSubHeading
+"	* manSynopsis (only for sections 2 and 3)
+
+" For version 5.x: Clear all syntax items
+" For version 6.x: Quit when a syntax file was already loaded
+if version < 600
+  syntax clear
+elseif exists("b:current_syntax")
+  finish
+endif
+
+" Get the CTRL-H syntax to handle backspaced text
+if version >= 600
+  runtime! syntax/ctrlh.vim
+else
+  source <sfile>:p:h/ctrlh.vim
+endif
+
+syn case ignore
+syn match  manReference       "\f\+([1-9][a-z]\=)"
+syn match  manTitle	      "^\f\+([0-9]\+[a-z]\=).*"
+syn match  manSectionHeading  "^[a-z][a-z ]*[a-z]$"
+syn match  manSubHeading      "^\s\{3\}[a-z][a-z ]*[a-z]$"
+syn match  manOptionDesc      "^\s*[+-][a-z0-9]\S*"
+syn match  manLongOptionDesc  "^\s*--[a-z0-9-]\S*"
+" syn match  manHistory		"^[a-z].*last change.*$"
+
+if getline(1) =~ '^[a-zA-Z_]\+([23])'
+  syntax include @cCode <sfile>:p:h/c.vim
+  syn match manCFuncDefinition  display "\<\h\w*\>\s*("me=e-1 contained
+  syn region manSynopsis start="^SYNOPSIS"hs=s+8 end="^\u\+\s*$"he=e-12 keepend contains=manSectionHeading,@cCode,manCFuncDefinition
+endif
+
+
+" Define the default highlighting.
+" For version 5.7 and earlier: only when not done already
+" For version 5.8 and later: only when an item doesn't have highlighting yet
+if version >= 508 || !exists("did_man_syn_inits")
+  if version < 508
+    let did_man_syn_inits = 1
+    command -nargs=+ HiLink hi link <args>
+  else
+    command -nargs=+ HiLink hi def link <args>
+  endif
+
+  HiLink manTitle	    Title
+  HiLink manSectionHeading  Statement
+  HiLink manOptionDesc	    Constant
+  HiLink manLongOptionDesc  Constant
+  HiLink manReference	    PreProc
+  HiLink manSubHeading      Function
+  HiLink manCFuncDefinition Function
+
+  delcommand HiLink
+endif
+
+let b:current_syntax = "man"
+
+" vim:ts=8 sts=2 sw=2:
--- /dev/null
+++ b/lib/vimfiles/syntax/manconf.vim
@@ -1,0 +1,117 @@
+" Vim syntax file
+" Language:         man.conf(5) - man configuration file
+" Maintainer:       Nikolai Weibull <now@bitwi.se>
+" Latest Revision:  2006-04-19
+
+if exists("b:current_syntax")
+  finish
+endif
+
+let s:cpo_save = &cpo
+set cpo&vim
+
+syn keyword manconfTodo         contained TODO FIXME XXX NOTE
+
+syn region  manconfComment      display oneline start='^#' end='$'
+                                \ contains=manconfTodo,@Spell
+
+if !has("win32") && $OSTYPE =~   'bsd'
+  syn match   manconfBegin      display '^'
+                                \ nextgroup=manconfKeyword,manconfSection,
+                                \ manconfComment skipwhite
+
+  syn keyword manconfKeyword    contained _build _crunch
+                                \ nextgroup=manconfExtCmd skipwhite
+
+  syn keyword manconfKeyword    contained _suffix
+                                \ nextgroup=manconfExt skipwhite
+
+  syn keyword manconfKeyword    contained _crunch
+
+  syn keyword manconfKeyword    contained _subdir _version _whatdb
+                                \ nextgroup=manconfPaths skipwhite
+
+  syn match   manconfExtCmd     contained display '\.\S\+'
+                                \ nextgroup=manconfPaths skipwhite
+
+  syn match   manconfSection    contained '[^#_ \t]\S*'
+                                \ nextgroup=manconfPaths skipwhite
+
+  syn keyword manconfSection    contained _default
+                                \ nextgroup=manconfPaths skipwhite
+
+  syn match   manconfPaths      contained display '\S\+'
+                                \ nextgroup=manconfPaths skipwhite
+
+  syn match   manconfExt        contained display '\.\S\+'
+
+  hi def link manconfExtCmd     Type
+  hi def link manconfSection    Identifier
+  hi def link manconfPaths      String
+else
+  syn match   manconfBegin      display '^'
+                                \ nextgroup=manconfBoolean,manconfKeyword,
+                                \ manconfDecompress,manconfComment skipwhite
+
+  syn keyword manconfBoolean    contained FSSTND FHS NOAUTOPATH NOCACHE
+
+  syn keyword manconfKeyword    contained MANBIN
+                                \ nextgroup=manconfPath skipwhite
+
+  syn keyword manconfKeyword    contained MANPATH MANPATH_MAP
+                                \ nextgroup=manconfFirstPath skipwhite
+
+  syn keyword manconfKeyword    contained APROPOS WHATIS TROFF NROFF JNROFF EQN
+                                \ NEQN JNEQN TBL COL REFER PIC VGRIND GRAP
+                                \ PAGER BROWSER HTMLPAGER CMP CAT COMPRESS
+                                \ DECOMPRESS MANDEFOPTIONS
+                                \ nextgroup=manconfCommand skipwhite
+
+  syn keyword manconfKeyword    contained COMPRESS_EXT
+                                \ nextgroup=manconfExt skipwhite
+
+  syn keyword manconfKeyword    contained MANSECT
+                                \ nextgroup=manconfManSect skipwhite
+
+  syn match   manconfPath       contained display '\S\+'
+
+  syn match   manconfFirstPath  contained display '\S\+'
+                                \ nextgroup=manconfSecondPath skipwhite
+
+  syn match   manconfSecondPath contained display '\S\+'
+
+  syn match   manconfCommand    contained display '\%(/[^/ \t]\+\)\+'
+                                \ nextgroup=manconfCommandOpt skipwhite
+
+  syn match   manconfCommandOpt contained display '\S\+'
+                                \ nextgroup=manconfCommandOpt skipwhite
+
+  syn match   manconfExt        contained display '\.\S\+'
+
+  syn match   manconfManSect    contained '[^:]\+' nextgroup=manconfManSectSep
+
+  syn match   manconfManSectSep contained ':' nextgroup=manconfManSect
+
+  syn match   manconfDecompress contained '\.\S\+'
+                                \ nextgroup=manconfCommand skipwhite
+
+  hi def link manconfBoolean    Boolean
+  hi def link manconfPath       String
+  hi def link manconfFirstPath  manconfPath
+  hi def link manconfSecondPath manconfPath
+  hi def link manconfCommand    String
+  hi def link manconfCommandOpt Special
+  hi def link manconfManSect    Identifier
+  hi def link manconfManSectSep Delimiter
+  hi def link manconfDecompress Type
+endif
+
+hi def link manconfTodo         Todo
+hi def link manconfComment      Comment
+hi def link manconfKeyword      Keyword
+hi def link manconfExt          Type
+
+let b:current_syntax = "manconf"
+
+let &cpo = s:cpo_save
+unlet s:cpo_save
--- /dev/null
+++ b/lib/vimfiles/syntax/manual.vim
@@ -1,0 +1,25 @@
+" Vim syntax support file
+" Maintainer:	Bram Moolenaar <Bram@vim.org>
+" Last Change:	2001 Jun 04
+
+" This file is used for ":syntax manual".
+" It installs the Syntax autocommands, but no the FileType autocommands.
+
+if !has("syntax")
+  finish
+endif
+
+" Load the Syntax autocommands and set the default methods for highlighting.
+if !exists("syntax_on")
+  so <sfile>:p:h/synload.vim
+endif
+
+let syntax_manual = 1
+
+" Remove the connection between FileType and Syntax autocommands.
+silent! au! syntaxset FileType
+
+" If the GUI is already running, may still need to install the FileType menu.
+if has("gui_running") && !exists("did_install_syntax_menu")
+  source $VIMRUNTIME/menu.vim
+endif
--- /dev/null
+++ b/lib/vimfiles/syntax/maple.vim
@@ -1,0 +1,631 @@
+" Vim syntax file
+" Language:	Maple V (based on release 4)
+" Maintainer:	Dr. Charles E. Campbell, Jr. <NdrOchipS@PcampbellAfamily.Mbiz>
+" Last Change:	Sep 11, 2006
+" Version:	9
+" URL:	http://mysite.verizon.net/astronaut/vim/index.html#vimlinks_syntax
+"
+" Package Function Selection: {{{1
+" Because there are a lot of packages, and because of the potential for namespace
+" clashes, this version of <maple.vim> needs the user to select which, if any,
+" package functions should be highlighted.  Select your packages and put into your
+" <.vimrc> none or more of the lines following let ...=1 lines:
+"
+"   if exists("mvpkg_all")
+"    ...
+"   endif
+"
+" *OR* let mvpkg_all=1
+
+" This syntax file contains all the keywords and top-level packages of Maple 9.5
+" but only the contents of packages of Maple V Release 4, and the top-level
+" routines of Release 4.  <Jacques Carette - carette@mcmaster.ca>
+
+" For version 5.x: Clear all syntax items
+" For version 6.x: Quit when a syntax file was already loaded
+if version < 600
+  syntax clear
+elseif exists("b:current_syntax")
+  finish
+endif
+
+" Iskeyword Effects: {{{1
+if version < 600
+  set iskeyword=$,48-57,_,a-z,@-Z
+else
+  setlocal iskeyword=$,48-57,_,a-z,@-Z
+endif
+
+" Package Selection: {{{1
+" allow user to simply select all packages for highlighting
+if exists("mvpkg_all")
+  let mv_DEtools    = 1
+  let mv_Galois     = 1
+  let mv_GaussInt   = 1
+  let mv_LREtools   = 1
+  let mv_combinat   = 1
+  let mv_combstruct = 1
+  let mv_difforms   = 1
+  let mv_finance    = 1
+  let mv_genfunc    = 1
+  let mv_geometry   = 1
+  let mv_grobner    = 1
+  let mv_group      = 1
+  let mv_inttrans   = 1
+  let mv_liesymm    = 1
+  let mv_linalg     = 1
+  let mv_logic      = 1
+  let mv_networks   = 1
+  let mv_numapprox  = 1
+  let mv_numtheory  = 1
+  let mv_orthopoly  = 1
+  let mv_padic      = 1
+  let mv_plots      = 1
+  let mv_plottools  = 1
+  let mv_powseries  = 1
+  let mv_process    = 1
+  let mv_simplex    = 1
+  let mv_stats      = 1
+  let mv_student    = 1
+  let mv_sumtools   = 1
+  let mv_tensor     = 1
+  let mv_totorder   = 1
+endif
+
+" Parenthesis/curly/brace sanity checker: {{{1
+syn case match
+
+" parenthesis/curly/brace sanity checker
+syn region mvZone	matchgroup=Delimiter start="(" matchgroup=Delimiter end=")" transparent contains=ALLBUT,mvError,mvBraceError,mvCurlyError
+syn region mvZone	matchgroup=Delimiter start="{" matchgroup=Delimiter end="}" transparent contains=ALLBUT,mvError,mvBraceError,mvParenError
+syn region mvZone	matchgroup=Delimiter start="\[" matchgroup=Delimiter end="]" transparent contains=ALLBUT,mvError,mvCurlyError,mvParenError
+syn match  mvError		"[)\]}]"
+syn match  mvBraceError	"[)}]"	contained
+syn match  mvCurlyError	"[)\]]"	contained
+syn match  mvParenError	"[\]}]"	contained
+syn match  mvComma		"[,;:]"
+syn match  mvSemiError	"[;:]"	contained
+syn match  mvDcolon		"::"
+
+" Maple Packages, updated for Maple 9.5
+syn keyword mvPackage	algcurves	ArrayTools	Cache	codegen
+syn keyword mvPackage	CodeGeneration	CodeTools	combinat	combstruct
+syn keyword mvPackage	ContextMenu	CurveFitting	DEtools	diffalg
+syn keyword mvPackage	difforms	DiscreteTransforms	Domains	ExternalCalling
+syn keyword mvPackage	FileTools	finance	GaussInt	genfunc
+syn keyword mvPackage	geom3d	geometry	gfun	Groebner
+syn keyword mvPackage	group	hashmset	IntegerRelations	inttrans
+syn keyword mvPackage	LargeExpressions	LibraryTools	liesymm	linalg
+syn keyword mvPackage	LinearAlgebra	LinearFunctionalSystems	LinearOperators
+syn keyword mvPackage	ListTools	Logic	LREtools	Maplets
+syn keyword mvPackage	MathematicalFunctions	MathML	Matlab
+syn keyword mvPackage	MatrixPolynomialAlgebra	MmaTranslator	networks
+syn keyword mvPackage	numapprox	numtheory	Optimization	OreTools
+syn keyword mvPackage	Ore_algebra	OrthogonalSeries	orthopoly	padic
+syn keyword mvPackage	PDEtools	plots	plottools	PolynomialIdeals
+syn keyword mvPackage	PolynomialTools	powseries	process	QDifferenceEquations
+syn keyword mvPackage	RandomTools	RationalNormalForms	RealDomain	RootFinding
+syn keyword mvPackage	ScientificConstants	ScientificErrorAnalysis	simplex
+syn keyword mvPackage	Slode	SNAP	Sockets	SoftwareMetrics
+syn keyword mvPackage	SolveTools	Spread	stats	StringTools
+syn keyword mvPackage	Student	student	sumtools	SumTools
+syn keyword mvPackage	tensor	TypeTools	Units	VariationalCalculus
+syn keyword mvPackage	VectorCalculus	Worksheet	XMLTools
+
+" Language Support: {{{1
+syn keyword mvTodo	contained	COMBAK	FIXME	TODO	XXX
+if exists("g:mapleversion") && g:mapleversion < 9
+ syn region  mvString	start=+`+ skip=+``+ end=+`+	keepend	contains=mvTodo,@Spell
+ syn region  mvString	start=+"+ skip=+""+ end=+"+	keepend	contains=@Spell
+ syn region  mvDelayEval	start=+'+ end=+'+	keepend contains=ALLBUT,mvError,mvBraceError,mvCurlyError,mvParenError,mvSemiError
+ syn match   mvVarAssign	"[a-zA-Z_][a-zA-Z_0-9]*[ \t]*:=" contains=mvAssign
+ syn match   mvAssign	":="	contained
+else
+ syn region  mvName		start=+`+ skip=+``+ end=+`+	keepend	contains=mvTodo
+ syn region  mvString	start=+"+ skip=+""+ end=+"+	keepend	contains=@Spell
+ syn region  mvDelayEval	start=+'+ end=+'+	keepend contains=ALLBUT,mvError,mvBraceError,mvCurlyError,mvParenError
+ syn match   mvDelim		"[;:]"	display
+ syn match   mvAssign	":="
+endif
+
+" Lower-Priority Operators: {{{1
+syn match mvOper	"\."
+
+" Number handling: {{{1
+syn match mvNumber	"\<\d\+"		" integer
+ syn match mvNumber	"[-+]\=\.\d\+"		" . integer
+syn match mvNumber	"\<\d\+\.\d\+"		" integer . integer
+syn match mvNumber	"\<\d\+\."		" integer .
+syn match mvNumber	"\<\d\+\.\."	contains=mvRange	" integer ..
+
+syn match mvNumber	"\<\d\+e[-+]\=\d\+"		" integer e [-+] integer
+syn match mvNumber	"[-+]\=\.\d\+e[-+]\=\d\+"	" . integer e [-+] integer
+syn match mvNumber	"\<\d\+\.\d*e[-+]\=\d\+"	" integer . [integer] e [-+] integer
+
+syn match mvNumber	"[-+]\d\+"		" integer
+syn match mvNumber	"[-+]\d\+\.\d\+"		" integer . integer
+syn match mvNumber	"[-+]\d\+\."		" integer .
+syn match mvNumber	"[-+]\d\+\.\."	contains=mvRange	" integer ..
+
+syn match mvNumber	"[-+]\d\+e[-+]\=\d\+"	" integer e [-+] integer
+syn match mvNumber	"[-+]\d\+\.\d*e[-+]\=\d\+"	" integer . [integer] e [-+] integer
+
+syn match mvRange	"\.\."
+
+" Operators: {{{1
+syn keyword mvOper	and not or xor implies union intersect subset minus mod
+syn match   mvOper	"<>\|[<>]=\|[<>]\|="
+syn match   mvOper	"&+\|&-\|&\*\|&\/\|&"
+syn match   mvError	"\.\.\."
+
+" MapleV Statements: ? statement {{{1
+
+" MapleV Statements: ? statement
+" Split into booleans, conditionals, operators, repeat-logic, etc
+syn keyword mvBool	true	false	FAIL
+syn keyword mvCond	elif	else	fi	if	then
+
+syn keyword mvRepeat	by	for	in	to
+syn keyword mvRepeat	do	from	od	while
+
+syn keyword mvSpecial	NULL
+syn match   mvSpecial	"\[\]\|{}"
+
+if exists("g:mapleversion") && g:mapleversion < 9
+ syn keyword mvStatement	Order	fail	options	read	save
+ syn keyword mvStatement	break	local	point	remember	stop
+ syn keyword mvStatement	done	mod	proc	restart	with
+ syn keyword mvStatement	end	mods	quit	return
+ syn keyword mvStatement	error	next
+else
+ syn keyword mvStatement	option	options	read	save
+ syn keyword mvStatement	break	local	remember	stop
+ syn keyword mvStatement	done	mod	proc	restart
+ syn keyword mvStatement	end	mods	quit	return
+ syn keyword mvStatement	error	next	try	catch
+ syn keyword mvStatement	finally	assuming	global	export
+ syn keyword mvStatement	module	description	use
+endif
+
+" Builtin Constants: ? constants {{{1
+syn keyword mvConstant	Catalan	I	gamma	infinity
+syn keyword mvConstant	Pi
+
+" Comments:  DEBUG, if in a comment, is specially highlighted. {{{1
+syn keyword mvDebug	contained	DEBUG
+syn cluster mvCommentGroup	contains=mvTodo,mvDebug,@Spell
+syn match mvComment "#.*$"	contains=@mvCommentGroup
+
+" Basic Library Functions: ? index[function]
+syn keyword mvLibrary $	@	@@	ERROR
+syn keyword mvLibrary AFactor	KelvinHer	arctan	factor	log	rhs
+syn keyword mvLibrary AFactors	KelvinKei	arctanh	factors	log10	root
+syn keyword mvLibrary AiryAi	KelvinKer	argument	fclose	lprint	roots
+syn keyword mvLibrary AiryBi	LambertW	array	feof	map	round
+syn keyword mvLibrary AngerJ	Lcm	assign	fflush	map2	rsolve
+syn keyword mvLibrary Berlekamp	LegendreE	assigned	filepos	match	savelib
+syn keyword mvLibrary BesselI	LegendreEc	asspar	fixdiv	matrix	scanf
+syn keyword mvLibrary BesselJ	LegendreEc1	assume	float	max	searchtext
+syn keyword mvLibrary BesselK	LegendreF	asubs	floor	maximize	sec
+syn keyword mvLibrary BesselY	LegendreKc	asympt	fnormal	maxnorm	sech
+syn keyword mvLibrary Beta	LegendreKc1	attribute	fopen	maxorder	select
+syn keyword mvLibrary C	LegendrePi	bernstein	forget	member	seq
+syn keyword mvLibrary Chi	LegendrePic	branches	fortran	min	series
+syn keyword mvLibrary Ci	LegendrePic1	bspline	fprintf	minimize	setattribute
+syn keyword mvLibrary CompSeq	Li	cat	frac	minpoly	shake
+syn keyword mvLibrary Content	Linsolve	ceil	freeze	modp	showprofile
+syn keyword mvLibrary D	MOLS	chrem	fremove	modp1	showtime
+syn keyword mvLibrary DESol	Maple_floats	close	frontend	modp2	sign
+syn keyword mvLibrary Det	MeijerG	close	fscanf	modpol	signum
+syn keyword mvLibrary Diff	Norm	coeff	fsolve	mods	simplify
+syn keyword mvLibrary Dirac	Normal	coeffs	galois	msolve	sin
+syn keyword mvLibrary DistDeg	Nullspace	coeftayl	gc	mtaylor	singular
+syn keyword mvLibrary Divide	Power	collect	gcd	mul	sinh
+syn keyword mvLibrary Ei	Powmod	combine	gcdex	nextprime	sinterp
+syn keyword mvLibrary Eigenvals	Prem	commutat	genpoly	nops	solve
+syn keyword mvLibrary EllipticCE	Primfield	comparray	harmonic	norm	sort
+syn keyword mvLibrary EllipticCK	Primitive	compoly	has	normal	sparse
+syn keyword mvLibrary EllipticCPi	Primpart	conjugate	hasfun	numboccur	spline
+syn keyword mvLibrary EllipticE	ProbSplit	content	hasoption	numer	split
+syn keyword mvLibrary EllipticF	Product	convergs	hastype	op	splits
+syn keyword mvLibrary EllipticK	Psi	convert	heap	open	sprem
+syn keyword mvLibrary EllipticModulus	Quo	coords	history	optimize	sprintf
+syn keyword mvLibrary EllipticNome	RESol	copy	hypergeom	order	sqrfree
+syn keyword mvLibrary EllipticPi	Randpoly	cos	iFFT	parse	sqrt
+syn keyword mvLibrary Eval	Randprime	cosh	icontent	pclose	sscanf
+syn keyword mvLibrary Expand	Ratrecon	cost	identity	pclose	ssystem
+syn keyword mvLibrary FFT	Re	cot	igcd	pdesolve	stack
+syn keyword mvLibrary Factor	Rem	coth	igcdex	piecewise	sturm
+syn keyword mvLibrary Factors	Resultant	csc	ilcm	plot	sturmseq
+syn keyword mvLibrary FresnelC	RootOf	csch	ilog	plot3d	subs
+syn keyword mvLibrary FresnelS	Roots	csgn	ilog10	plotsetup	subsop
+syn keyword mvLibrary Fresnelf	SPrem	dawson	implicitdiff	pochhammer	substring
+syn keyword mvLibrary Fresnelg	Searchtext	define	indets	pointto	sum
+syn keyword mvLibrary Frobenius	Shi	degree	index	poisson	surd
+syn keyword mvLibrary GAMMA	Si	denom	indexed	polar	symmdiff
+syn keyword mvLibrary GaussAGM	Smith	depends	indices	polylog	symmetric
+syn keyword mvLibrary Gaussejord	Sqrfree	diagonal	inifcn	polynom	system
+syn keyword mvLibrary Gausselim	Ssi	diff	ininame	powmod	table
+syn keyword mvLibrary Gcd	StruveH	dilog	initialize	prem	tan
+syn keyword mvLibrary Gcdex	StruveL	dinterp	insert	prevprime	tanh
+syn keyword mvLibrary HankelH1	Sum	disassemble	int	primpart	testeq
+syn keyword mvLibrary HankelH2	Svd	discont	interface	print	testfloat
+syn keyword mvLibrary Heaviside	TEXT	discrim	interp	printf	thaw
+syn keyword mvLibrary Hermite	Trace	dismantle	invfunc	procbody	thiele
+syn keyword mvLibrary Im	WeberE	divide	invztrans	procmake	time
+syn keyword mvLibrary Indep	WeierstrassP	dsolve	iostatus	product	translate
+syn keyword mvLibrary Interp	WeierstrassPPrime	eliminate	iperfpow	proot	traperror
+syn keyword mvLibrary Inverse	WeierstrassSigma	ellipsoid	iquo	property	trigsubs
+syn keyword mvLibrary Irreduc	WeierstrassZeta	entries	iratrecon	protect	trunc
+syn keyword mvLibrary Issimilar	Zeta	eqn	irem	psqrt	type
+syn keyword mvLibrary JacobiAM	abs	erf	iroot	quo	typematch
+syn keyword mvLibrary JacobiCD	add	erfc	irreduc	radnormal	unames
+syn keyword mvLibrary JacobiCN	addcoords	eulermac	iscont	radsimp	unapply
+syn keyword mvLibrary JacobiCS	addressof	eval	isdifferentiable	rand	unassign
+syn keyword mvLibrary JacobiDC	algebraic	evala	isolate	randomize	unload
+syn keyword mvLibrary JacobiDN	algsubs	evalapply	ispoly	randpoly	unprotect
+syn keyword mvLibrary JacobiDS	alias	evalb	isqrfree	range	updatesR4
+syn keyword mvLibrary JacobiNC	allvalues	evalc	isqrt	rationalize	userinfo
+syn keyword mvLibrary JacobiND	anames	evalf	issqr	ratrecon	value
+syn keyword mvLibrary JacobiNS	antisymm	evalfint	latex	readbytes	vector
+syn keyword mvLibrary JacobiSC	applyop	evalgf	lattice	readdata	verify
+syn keyword mvLibrary JacobiSD	arccos	evalhf	lcm	readlib	whattype
+syn keyword mvLibrary JacobiSN	arccosh	evalm	lcoeff	readline	with
+syn keyword mvLibrary JacobiTheta1	arccot	evaln	leadterm	readstat	writebytes
+syn keyword mvLibrary JacobiTheta2	arccoth	evalr	length	realroot	writedata
+syn keyword mvLibrary JacobiTheta3	arccsc	exp	lexorder	recipoly	writeline
+syn keyword mvLibrary JacobiTheta4	arccsch	expand	lhs	rem	writestat
+syn keyword mvLibrary JacobiZeta	arcsec	expandoff	limit	remove	writeto
+syn keyword mvLibrary KelvinBei	arcsech	expandon	ln	residue	zip
+syn keyword mvLibrary KelvinBer	arcsin	extract	lnGAMMA	resultant	ztrans
+syn keyword mvLibrary KelvinHei	arcsinh
+
+
+" ==  PACKAGES  ======================================================= {{{1
+" Note: highlighting of package functions is now user-selectable by package.
+
+" Package: DEtools     differential equations tools {{{2
+if exists("mv_DEtools")
+  syn keyword mvPkg_DEtools	DEnormal	Dchangevar	autonomous	dfieldplot	reduceOrder	untranslate
+  syn keyword mvPkg_DEtools	DEplot	PDEchangecoords	convertAlg	indicialeq	regularsp	varparam
+  syn keyword mvPkg_DEtools	DEplot3d	PDEplot	convertsys	phaseportrait	translate
+endif
+
+" Package: Domains: create domains of computation {{{2
+if exists("mv_Domains")
+endif
+
+" Package: GF: Galois Fields {{{2
+if exists("mv_GF")
+  syn keyword mvPkg_Galois	galois
+endif
+
+" Package: GaussInt: Gaussian Integers {{{2
+if exists("mv_GaussInt")
+  syn keyword mvPkg_GaussInt	GIbasis	GIfactor	GIissqr	GInorm	GIquadres	GIsmith
+  syn keyword mvPkg_GaussInt	GIchrem	GIfactors	GIlcm	GInormal	GIquo	GIsqrfree
+  syn keyword mvPkg_GaussInt	GIdivisor	GIgcd	GImcmbine	GIorder	GIrem	GIsqrt
+  syn keyword mvPkg_GaussInt	GIfacpoly	GIgcdex	GInearest	GIphi	GIroots	GIunitnormal
+  syn keyword mvPkg_GaussInt	GIfacset	GIhermite	GInodiv	GIprime	GIsieve
+endif
+
+" Package: LREtools: manipulate linear recurrence relations {{{2
+if exists("mv_LREtools")
+  syn keyword mvPkg_LREtools	REcontent	REprimpart	REtodelta	delta	hypergeomsols	ratpolysols
+  syn keyword mvPkg_LREtools	REcreate	REreduceorder	REtoproc	dispersion	polysols	shift
+  syn keyword mvPkg_LREtools	REplot	REtoDE	constcoeffsol
+endif
+
+" Package: combinat: combinatorial functions {{{2
+if exists("mv_combinat")
+  syn keyword mvPkg_combinat	Chi	composition	graycode	numbcomb	permute	randperm
+  syn keyword mvPkg_combinat	bell	conjpart	inttovec	numbcomp	powerset	stirling1
+  syn keyword mvPkg_combinat	binomial	decodepart	lastpart	numbpart	prevpart	stirling2
+  syn keyword mvPkg_combinat	cartprod	encodepart	multinomial	numbperm	randcomb	subsets
+  syn keyword mvPkg_combinat	character	fibonacci	nextpart	partition	randpart	vectoint
+  syn keyword mvPkg_combinat	choose	firstpart
+endif
+
+" Package: combstruct: combinatorial structures {{{2
+if exists("mv_combstruct")
+  syn keyword mvPkg_combstruct	allstructs	draw	iterstructs	options	specification	structures
+  syn keyword mvPkg_combstruct	count	finished	nextstruct
+endif
+
+" Package: difforms: differential forms {{{2
+if exists("mv_difforms")
+  syn keyword mvPkg_difforms	const	defform	formpart	parity	scalarpart	wdegree
+  syn keyword mvPkg_difforms	d	form	mixpar	scalar	simpform	wedge
+endif
+
+" Package: finance: financial mathematics {{{2
+if exists("mv_finance")
+  syn keyword mvPkg_finance	amortization	cashflows	futurevalue	growingperpetuity	mv_finance	presentvalue
+  syn keyword mvPkg_finance	annuity	effectiverate	growingannuity	levelcoupon	perpetuity	yieldtomaturity
+  syn keyword mvPkg_finance	blackscholes
+endif
+
+" Package: genfunc: rational generating functions {{{2
+if exists("mv_genfunc")
+  syn keyword mvPkg_genfunc	rgf_charseq	rgf_expand	rgf_hybrid	rgf_pfrac	rgf_sequence	rgf_term
+  syn keyword mvPkg_genfunc	rgf_encode	rgf_findrecur	rgf_norm	rgf_relate	rgf_simp	termscale
+endif
+
+" Package: geometry: Euclidean geometry {{{2
+if exists("mv_geometry")
+  syn keyword mvPkg_geometry	circle	dsegment	hyperbola	parabola	segment	triangle
+  syn keyword mvPkg_geometry	conic	ellipse	line	point	square
+endif
+
+" Package: grobner: Grobner bases {{{2
+if exists("mv_grobner")
+  syn keyword mvPkg_grobner	finduni	gbasis	leadmon	normalf	solvable	spoly
+  syn keyword mvPkg_grobner	finite	gsolve
+endif
+
+" Package: group: permutation and finitely-presented groups {{{2
+if exists("mv_group")
+  syn keyword mvPkg_group	DerivedS	areconjugate	cosets	grouporder	issubgroup	permrep
+  syn keyword mvPkg_group	LCS	center	cosrep	inter	mulperms	pres
+  syn keyword mvPkg_group	NormalClosure	centralizer	derived	invperm	normalizer	subgrel
+  syn keyword mvPkg_group	RandElement	convert	grelgroup	isabelian	orbit	type
+  syn keyword mvPkg_group	Sylow	core	groupmember	isnormal	permgroup
+endif
+
+" Package: inttrans: integral transforms {{{2
+if exists("mv_inttrans")
+  syn keyword mvPkg_inttrans	addtable	fouriercos	hankel	invfourier	invlaplace	mellin
+  syn keyword mvPkg_inttrans	fourier	fouriersin	hilbert	invhilbert	laplace
+endif
+
+" Package: liesymm: Lie symmetries {{{2
+if exists("mv_liesymm")
+  syn keyword mvPkg_liesymm	&^	TD	depvars	getform	mixpar	vfix
+  syn keyword mvPkg_liesymm	&mod	annul	determine	hasclosure	prolong	wcollect
+  syn keyword mvPkg_liesymm	Eta	autosimp	dvalue	hook	reduce	wdegree
+  syn keyword mvPkg_liesymm	Lie	close	extvars	indepvars	setup	wedgeset
+  syn keyword mvPkg_liesymm	Lrank	d	getcoeff	makeforms	translate	wsubs
+endif
+
+" Package: linalg: Linear algebra {{{2
+if exists("mv_linalg")
+  syn keyword mvPkg_linalg	GramSchmidt	coldim	equal	indexfunc	mulcol	singval
+  syn keyword mvPkg_linalg	JordanBlock	colspace	exponential	innerprod	multiply	smith
+  syn keyword mvPkg_linalg	LUdecomp	colspan	extend	intbasis	norm	stack
+  syn keyword mvPkg_linalg	QRdecomp	companion	ffgausselim	inverse	normalize	submatrix
+  syn keyword mvPkg_linalg	addcol	cond	fibonacci	ismith	orthog	subvector
+  syn keyword mvPkg_linalg	addrow	copyinto	forwardsub	issimilar	permanent	sumbasis
+  syn keyword mvPkg_linalg	adjoint	crossprod	frobenius	iszero	pivot	swapcol
+  syn keyword mvPkg_linalg	angle	curl	gausselim	jacobian	potential	swaprow
+  syn keyword mvPkg_linalg	augment	definite	gaussjord	jordan	randmatrix	sylvester
+  syn keyword mvPkg_linalg	backsub	delcols	geneqns	kernel	randvector	toeplitz
+  syn keyword mvPkg_linalg	band	delrows	genmatrix	laplacian	rank	trace
+  syn keyword mvPkg_linalg	basis	det	grad	leastsqrs	references	transpose
+  syn keyword mvPkg_linalg	bezout	diag	hadamard	linsolve	row	vandermonde
+  syn keyword mvPkg_linalg	blockmatrix	diverge	hermite	matadd	rowdim	vecpotent
+  syn keyword mvPkg_linalg	charmat	dotprod	hessian	matrix	rowspace	vectdim
+  syn keyword mvPkg_linalg	charpoly	eigenval	hilbert	minor	rowspan	vector
+  syn keyword mvPkg_linalg	cholesky	eigenvect	htranspose	minpoly	scalarmul	wronskian
+  syn keyword mvPkg_linalg	col	entermatrix	ihermite
+endif
+
+" Package: logic: Boolean logic {{{2
+if exists("mv_logic")
+  syn keyword mvPkg_logic	MOD2	bsimp	distrib	environ	randbool	tautology
+  syn keyword mvPkg_logic	bequal	canon	dual	frominert	satisfy	toinert
+endif
+
+" Package: networks: graph networks {{{2
+if exists("mv_networks")
+  syn keyword mvPkg_networks	acycpoly	connect	dinic	graph	mincut	show
+  syn keyword mvPkg_networks	addedge	connectivity	djspantree	graphical	mindegree	shrink
+  syn keyword mvPkg_networks	addvertex	contract	dodecahedron	gsimp	neighbors	span
+  syn keyword mvPkg_networks	adjacency	countcuts	draw	gunion	new	spanpoly
+  syn keyword mvPkg_networks	allpairs	counttrees	duplicate	head	octahedron	spantree
+  syn keyword mvPkg_networks	ancestor	cube	edges	icosahedron	outdegree	tail
+  syn keyword mvPkg_networks	arrivals	cycle	ends	incidence	path	tetrahedron
+  syn keyword mvPkg_networks	bicomponents	cyclebase	eweight	incident	petersen	tuttepoly
+  syn keyword mvPkg_networks	charpoly	daughter	flow	indegree	random	vdegree
+  syn keyword mvPkg_networks	chrompoly	degreeseq	flowpoly	induce	rank	vertices
+  syn keyword mvPkg_networks	complement	delete	fundcyc	isplanar	rankpoly	void
+  syn keyword mvPkg_networks	complete	departures	getlabel	maxdegree	shortpathtree	vweight
+  syn keyword mvPkg_networks	components	diameter	girth
+endif
+
+" Package: numapprox: numerical approximation {{{2
+if exists("mv_numapprox")
+  syn keyword mvPkg_numapprox	chebdeg	chebsort	fnorm	laurent	minimax	remez
+  syn keyword mvPkg_numapprox	chebmult	chebyshev	hornerform	laurent	pade	taylor
+  syn keyword mvPkg_numapprox	chebpade	confracform	infnorm	minimax
+endif
+
+" Package: numtheory: number theory {{{2
+if exists("mv_numtheory")
+  syn keyword mvPkg_numtheory	B	cyclotomic	invcfrac	mcombine	nthconver	primroot
+  syn keyword mvPkg_numtheory	F	divisors	invphi	mersenne	nthdenom	quadres
+  syn keyword mvPkg_numtheory	GIgcd	euler	isolve	minkowski	nthnumer	rootsunity
+  syn keyword mvPkg_numtheory	J	factorEQ	isprime	mipolys	nthpow	safeprime
+  syn keyword mvPkg_numtheory	L	factorset	issqrfree	mlog	order	sigma
+  syn keyword mvPkg_numtheory	M	fermat	ithprime	mobius	pdexpand	sq2factor
+  syn keyword mvPkg_numtheory	bernoulli	ifactor	jacobi	mroot	phi	sum2sqr
+  syn keyword mvPkg_numtheory	bigomega	ifactors	kronecker	msqrt	pprimroot	tau
+  syn keyword mvPkg_numtheory	cfrac	imagunit	lambda	nearestp	prevprime	thue
+  syn keyword mvPkg_numtheory	cfracpol	index	legendre	nextprime
+endif
+
+" Package: orthopoly: orthogonal polynomials {{{2
+if exists("mv_orthopoly")
+  syn keyword mvPkg_orthopoly	G	H	L	P	T	U
+endif
+
+" Package: padic: p-adic numbers {{{2
+if exists("mv_padic")
+  syn keyword mvPkg_padic	evalp	function	orderp	ratvaluep	rootp	valuep
+  syn keyword mvPkg_padic	expansion	lcoeffp	ordp
+endif
+
+" Package: plots: graphics package {{{2
+if exists("mv_plots")
+  syn keyword mvPkg_plots	animate	coordplot3d	gradplot3d	listplot3d	polarplot	setoptions3d
+  syn keyword mvPkg_plots	animate3d	cylinderplot	implicitplot	loglogplot	polygonplot	spacecurve
+  syn keyword mvPkg_plots	changecoords	densityplot	implicitplot3d	logplot	polygonplot3d	sparsematrixplot
+  syn keyword mvPkg_plots	complexplot	display	inequal	matrixplot	polyhedraplot	sphereplot
+  syn keyword mvPkg_plots	complexplot3d	display3d	listcontplot	odeplot	replot	surfdata
+  syn keyword mvPkg_plots	conformal	fieldplot	listcontplot3d	pareto	rootlocus	textplot
+  syn keyword mvPkg_plots	contourplot	fieldplot3d	listdensityplot	pointplot	semilogplot	textplot3d
+  syn keyword mvPkg_plots	contourplot3d	gradplot	listplot	pointplot3d	setoptions	tubeplot
+  syn keyword mvPkg_plots	coordplot
+endif
+
+" Package: plottools: basic graphical objects {{{2
+if exists("mv_plottools")
+  syn keyword mvPkg_plottools	arc	curve	dodecahedron	hyperbola	pieslice	semitorus
+  syn keyword mvPkg_plottools	arrow	cutin	ellipse	icosahedron	point	sphere
+  syn keyword mvPkg_plottools	circle	cutout	ellipticArc	line	polygon	tetrahedron
+  syn keyword mvPkg_plottools	cone	cylinder	hemisphere	octahedron	rectangle	torus
+  syn keyword mvPkg_plottools	cuboid	disk	hexahedron
+endif
+
+" Package: powseries: formal power series {{{2
+if exists("mv_powseries")
+  syn keyword mvPkg_powseries	compose	multiply	powcreate	powlog	powsolve	reversion
+  syn keyword mvPkg_powseries	evalpow	negative	powdiff	powpoly	powsqrt	subtract
+  syn keyword mvPkg_powseries	inverse	powadd	powexp	powseries	quotient	tpsform
+  syn keyword mvPkg_powseries	multconst	powcos	powint	powsin
+endif
+
+" Package: process: (Unix)-multi-processing {{{2
+if exists("mv_process")
+  syn keyword mvPkg_process	block	fork	pclose	pipe	popen	wait
+  syn keyword mvPkg_process	exec	kill
+endif
+
+" Package: simplex: linear optimization {{{2
+if exists("mv_simplex")
+  syn keyword mvPkg_simplex	NONNEGATIVE	cterm	dual	maximize	pivoteqn	setup
+  syn keyword mvPkg_simplex	basis	define_zero	equality	minimize	pivotvar	standardize
+  syn keyword mvPkg_simplex	convexhull	display	feasible	pivot	ratio
+endif
+
+" Package: stats: statistics {{{2
+if exists("mv_stats")
+  syn keyword mvPkg_stats	anova	describe	fit	random	statevalf	statplots
+endif
+
+" Package: student: student calculus {{{2
+if exists("mv_student")
+  syn keyword mvPkg_student	D	Product	distance	isolate	middlesum	rightsum
+  syn keyword mvPkg_student	Diff	Sum	equate	leftbox	midpoint	showtangent
+  syn keyword mvPkg_student	Doubleint	Tripleint	extrema	leftsum	minimize	simpson
+  syn keyword mvPkg_student	Int	changevar	integrand	makeproc	minimize	slope
+  syn keyword mvPkg_student	Limit	combine	intercept	maximize	powsubs	trapezoid
+  syn keyword mvPkg_student	Lineint	completesquare	intparts	middlebox	rightbox	value
+  syn keyword mvPkg_student	Point
+endif
+
+" Package: sumtools: indefinite and definite sums {{{2
+if exists("mv_sumtools")
+  syn keyword mvPkg_sumtools	Hypersum	extended_gosper	hyperrecursion	hyperterm	sumrecursion	sumtohyper
+  syn keyword mvPkg_sumtools	Sumtohyper	gosper	hypersum	simpcomb
+endif
+
+" Package: tensor: tensor computations and General Relativity {{{2
+if exists("mv_tensor")
+  syn keyword mvPkg_tensor	Christoffel1	Riemann	connexF	display_allGR	get_compts	partial_diff
+  syn keyword mvPkg_tensor	Christoffel2	RiemannF	contract	dual	get_rank	permute_indices
+  syn keyword mvPkg_tensor	Einstein	Weyl	convertNP	entermetric	invars	petrov
+  syn keyword mvPkg_tensor	Jacobian	act	cov_diff	exterior_diff	invert	prod
+  syn keyword mvPkg_tensor	Killing_eqns	antisymmetrize	create	exterior_prod	lin_com	raise
+  syn keyword mvPkg_tensor	Levi_Civita	change_basis	d1metric	frame	lower	symmetrize
+  syn keyword mvPkg_tensor	Lie_diff	commutator	d2metric	geodesic_eqns	npcurve	tensorsGR
+  syn keyword mvPkg_tensor	Ricci	compare	directional_diff	get_char	npspin	transform
+  syn keyword mvPkg_tensor	Ricciscalar	conj	displayGR
+endif
+
+" Package: totorder: total orders on names {{{2
+if exists("mv_totorder")
+  syn keyword mvPkg_totorder	forget	init	ordering	tassume	tis
+endif
+" =====================================================================
+
+" Highlighting: Define the default highlighting. {{{1
+" For version 5.7 and earlier: only when not done already
+" For version 5.8 and later: only when an item doesn't have highlighting yet
+if version >= 508 || !exists("did_maplev_syntax_inits")
+  if version < 508
+    let did_maplev_syntax_inits = 1
+    command -nargs=+ HiLink hi link <args>
+  else
+    command -nargs=+ HiLink hi def link <args>
+  endif
+
+  " Maple->Maple Links {{{2
+  HiLink mvBraceError	mvError
+  HiLink mvCurlyError	mvError
+  HiLink mvDebug		mvTodo
+  HiLink mvParenError	mvError
+  HiLink mvPkg_DEtools	mvPkgFunc
+  HiLink mvPkg_Galois	mvPkgFunc
+  HiLink mvPkg_GaussInt	mvPkgFunc
+  HiLink mvPkg_LREtools	mvPkgFunc
+  HiLink mvPkg_combinat	mvPkgFunc
+  HiLink mvPkg_combstruct	mvPkgFunc
+  HiLink mvPkg_difforms	mvPkgFunc
+  HiLink mvPkg_finance	mvPkgFunc
+  HiLink mvPkg_genfunc	mvPkgFunc
+  HiLink mvPkg_geometry	mvPkgFunc
+  HiLink mvPkg_grobner	mvPkgFunc
+  HiLink mvPkg_group	mvPkgFunc
+  HiLink mvPkg_inttrans	mvPkgFunc
+  HiLink mvPkg_liesymm	mvPkgFunc
+  HiLink mvPkg_linalg	mvPkgFunc
+  HiLink mvPkg_logic	mvPkgFunc
+  HiLink mvPkg_networks	mvPkgFunc
+  HiLink mvPkg_numapprox	mvPkgFunc
+  HiLink mvPkg_numtheory	mvPkgFunc
+  HiLink mvPkg_orthopoly	mvPkgFunc
+  HiLink mvPkg_padic	mvPkgFunc
+  HiLink mvPkg_plots	mvPkgFunc
+  HiLink mvPkg_plottools	mvPkgFunc
+  HiLink mvPkg_powseries	mvPkgFunc
+  HiLink mvPkg_process	mvPkgFunc
+  HiLink mvPkg_simplex	mvPkgFunc
+  HiLink mvPkg_stats	mvPkgFunc
+  HiLink mvPkg_student	mvPkgFunc
+  HiLink mvPkg_sumtools	mvPkgFunc
+  HiLink mvPkg_tensor	mvPkgFunc
+  HiLink mvPkg_totorder	mvPkgFunc
+  HiLink mvRange		mvOper
+  HiLink mvSemiError	mvError
+  HiLink mvDelim		Delimiter
+
+  " Maple->Standard Links {{{2
+  HiLink mvAssign		Delimiter
+  HiLink mvBool		Boolean
+  HiLink mvComma		Delimiter
+  HiLink mvComment		Comment
+  HiLink mvCond		Conditional
+  HiLink mvConstant		Number
+  HiLink mvDelayEval	Label
+  HiLink mvDcolon		Delimiter
+  HiLink mvError		Error
+  HiLink mvLibrary		Statement
+  HiLink mvNumber		Number
+  HiLink mvOper		Operator
+  HiLink mvAssign		Delimiter
+  HiLink mvPackage		Type
+  HiLink mvPkgFunc		Function
+  HiLink mvPktOption	Special
+  HiLink mvRepeat		Repeat
+  HiLink mvSpecial		Special
+  HiLink mvStatement	Statement
+  HiLink mvName		String
+  HiLink mvString		String
+  HiLink mvTodo		Todo
+
+  delcommand HiLink
+endif
+
+" Current Syntax: {{{1
+let b:current_syntax = "maple"
+" vim: ts=20 fdm=marker
--- /dev/null
+++ b/lib/vimfiles/syntax/masm.vim
@@ -1,0 +1,343 @@
+" Vim syntax file
+" Language:	Microsoft Macro Assembler (80x86)
+" Orig Author:	Rob Brady <robb@datatone.com>
+" Maintainer:	Wu Yongwei <wuyongwei@gmail.com>
+" Last Change:	$Date: 2007/04/21 13:20:15 $
+" $Revision: 1.44 $
+
+" For version 5.x: Clear all syntax items
+" For version 6.x: Quit when a syntax file was already loaded
+if version < 600
+  syntax clear
+elseif exists("b:current_syntax")
+  finish
+endif
+
+syn case ignore
+
+
+syn match masmIdentifier	"[@a-z_$?][@a-z0-9_$?]*"
+syn match masmLabel		"^\s*[@a-z_$?][@a-z0-9_$?]*:"he=e-1
+
+syn match masmDecimal		"[-+]\?\d\+[dt]\?"
+syn match masmBinary		"[-+]\?[0-1]\+[by]"  "put this before hex or 0bfh dies!
+syn match masmOctal		"[-+]\?[0-7]\+[oq]"
+syn match masmHexadecimal	"[-+]\?[0-9]\x*h"
+syn match masmFloatRaw		"[-+]\?[0-9]\x*r"
+syn match masmFloat		"[-+]\?\d\+\.\(\d*\(E[-+]\?\d\+\)\?\)\?"
+
+syn match masmComment		";.*" contains=@Spell
+syn region masmComment		start=+COMMENT\s*\z(\S\)+ end=+\z1.*+ contains=@Spell
+syn region masmString		start=+'+ end=+'+ oneline contains=@Spell
+syn region masmString		start=+"+ end=+"+ oneline contains=@Spell
+
+syn region masmTitleArea	start=+\<TITLE\s+lc=5 start=+\<SUBTITLE\s+lc=8 start=+\<SUBTTL\s+lc=6 end=+$+ end=+;+me=e-1 contains=masmTitle
+syn region masmTextArea		start=+\<NAME\s+lc=4 start=+\<INCLUDE\s+lc=7 start=+\<INCLUDELIB\s+lc=10 end=+$+ end=+;+me=e-1 contains=masmText
+syn match masmTitle		"[^\t ;]\([^;]*[^\t ;]\)\?" contained contains=@Spell
+syn match masmText		"[^\t ;]\([^;]*[^\t ;]\)\?" contained
+
+syn region masmOptionOpt	start=+\<OPTION\s+lc=6 end=+$+ end=+;+me=e-1 contains=masmOption
+syn region masmContextOpt	start=+\<PUSHCONTEXT\s+lc=11 start=+\<POPCONTEXT\s+lc=10 end=+$+ end=+;+me=e-1 contains=masmOption
+syn region masmModelOpt		start=+\.MODEL\s+lc=6 end=+$+ end=+;+me=e-1 contains=masmOption,masmType
+syn region masmSegmentOpt	start=+\<SEGMENT\s+lc=7 end=+$+ end=+;+me=e-1 contains=masmOption,masmString
+syn region masmProcOpt		start=+\<PROC\s+lc=4 end=+$+ end=+;+me=e-1 contains=masmOption,masmType,masmRegister,masmIdentifier
+syn region masmAssumeOpt	start=+\<ASSUME\s+lc=6 end=+$+ end=+;+me=e-1 contains=masmOption,masmOperator,masmType,masmRegister,masmIdentifier
+syn region masmExpression	start=+\.IF\s+lc=3 start=+\.WHILE\s+lc=6 start=+\.UNTIL\s+lc=6 start=+\<IF\s+lc=2 start=+\<IF2\s+lc=3 start=+\<ELSEIF\s+lc=6 start=+\<ELSEIF2\s+lc=7 start=+\<REPEAT\s+lc=6 start=+\<WHILE\s+lc=5 end=+$+ end=+;+me=e-1 contains=masmType,masmOperator,masmRegister,masmIdentifier,masmDecimal,masmBinary,masmHexadecimal,masmFloatRaw,masmString
+
+syn keyword masmOption		TINY SMALL COMPACT MEDIUM LARGE HUGE contained
+syn keyword masmOption		NEARSTACK FARSTACK contained
+syn keyword masmOption		PUBLIC PRIVATE STACK COMMON MEMORY AT contained
+syn keyword masmOption		BYTE WORD DWORD PARA PAGE contained
+syn keyword masmOption		USE16 USE32 FLAT contained
+syn keyword masmOption		INFO READ WRITE EXECUTE SHARED contained
+syn keyword masmOption		NOPAGE NOCACHE DISCARD contained
+syn keyword masmOption		READONLY USES FRAME contained
+syn keyword masmOption		CASEMAP DOTNAME NODOTNAME EMULATOR contained
+syn keyword masmOption		NOEMULATOR EPILOGUE EXPR16 EXPR32 contained
+syn keyword masmOption		LANGUAGE LJMP NOLJMP M510 NOM510 contained
+syn keyword masmOption		NOKEYWORD NOSIGNEXTEND OFFSET contained
+syn keyword masmOption		OLDMACROS NOOLDMACROS OLDSTRUCTS contained
+syn keyword masmOption		NOOLDSTRUCTS PROC PROLOGUE READONLY contained
+syn keyword masmOption		NOREADONLY SCOPED NOSCOPED SEGMENT contained
+syn keyword masmOption		SETIF2 contained
+syn keyword masmOption		ABS ALL ASSUMES CPU ERROR EXPORT contained
+syn keyword masmOption		FORCEFRAME LISTING LOADDS NONE contained
+syn keyword masmOption		NONUNIQUE NOTHING OS_DOS RADIX REQ contained
+syn keyword masmType		STDCALL SYSCALL C BASIC FORTRAN PASCAL
+syn keyword masmType		PTR NEAR FAR NEAR16 FAR16 NEAR32 FAR32
+syn keyword masmType		REAL4 REAL8 REAL10 BYTE SBYTE TBYTE
+syn keyword masmType		WORD DWORD QWORD FWORD SWORD SDWORD
+syn keyword masmOperator	AND NOT OR SHL SHR XOR MOD DUP
+syn keyword masmOperator	EQ GE GT LE LT NE
+syn keyword masmOperator	LROFFSET SEG LENGTH LENGTHOF SIZE SIZEOF
+syn keyword masmOperator	CODEPTR DATAPTR FAR NEAR SHORT THIS TYPE
+syn keyword masmOperator	HIGH HIGHWORD LOW LOWWORD OPATTR MASK WIDTH
+syn match   masmOperator	"OFFSET\(\sFLAT:\)\?"
+syn match   masmOperator	".TYPE\>"
+syn match   masmOperator	"CARRY?"
+syn match   masmOperator	"OVERFLOW?"
+syn match   masmOperator	"PARITY?"
+syn match   masmOperator	"SIGN?"
+syn match   masmOperator	"ZERO?"
+syn keyword masmDirective	ALIAS ASSUME CATSTR COMM DB DD DF DOSSEG DQ DT
+syn keyword masmDirective	DW ECHO ELSE ELSEIF ELSEIF1 ELSEIF2 ELSEIFB
+syn keyword masmDirective	ELSEIFDEF ELSEIFDIF ELSEIFDIFI ELSEIFE
+syn keyword masmDirective	ELSEIFIDN ELSEIFIDNI ELSEIFNB ELSEIFNDEF END
+syn keyword masmDirective	ENDIF ENDM ENDP ENDS EQU EVEN EXITM EXTERN
+syn keyword masmDirective	EXTERNDEF EXTRN FOR FORC GOTO GROUP IF IF1 IF2
+syn keyword masmDirective	IFB IFDEF IFDIF IFDIFI IFE IFIDN IFIDNI IFNB
+syn keyword masmDirective	IFNDEF INCLUDE INCLUDELIB INSTR INVOKE IRP
+syn keyword masmDirective	IRPC LABEL LOCAL MACRO NAME OPTION ORG PAGE
+syn keyword masmDirective	POPCONTEXT PROC PROTO PUBLIC PURGE PUSHCONTEXT
+syn keyword masmDirective	RECORD REPEAT REPT SEGMENT SIZESTR STRUC
+syn keyword masmDirective	STRUCT SUBSTR SUBTITLE SUBTTL TEXTEQU TITLE
+syn keyword masmDirective	TYPEDEF UNION WHILE
+syn match   masmDirective	"\.8086\>"
+syn match   masmDirective	"\.8087\>"
+syn match   masmDirective	"\.NO87\>"
+syn match   masmDirective	"\.186\>"
+syn match   masmDirective	"\.286\>"
+syn match   masmDirective	"\.286C\>"
+syn match   masmDirective	"\.286P\>"
+syn match   masmDirective	"\.287\>"
+syn match   masmDirective	"\.386\>"
+syn match   masmDirective	"\.386C\>"
+syn match   masmDirective	"\.386P\>"
+syn match   masmDirective	"\.387\>"
+syn match   masmDirective	"\.486\>"
+syn match   masmDirective	"\.486P\>"
+syn match   masmDirective	"\.586\>"
+syn match   masmDirective	"\.586P\>"
+syn match   masmDirective	"\.686\>"
+syn match   masmDirective	"\.686P\>"
+syn match   masmDirective	"\.K3D\>"
+syn match   masmDirective	"\.MMX\>"
+syn match   masmDirective	"\.XMM\>"
+syn match   masmDirective	"\.ALPHA\>"
+syn match   masmDirective	"\.DOSSEG\>"
+syn match   masmDirective	"\.SEQ\>"
+syn match   masmDirective	"\.CODE\>"
+syn match   masmDirective	"\.CONST\>"
+syn match   masmDirective	"\.DATA\>"
+syn match   masmDirective	"\.DATA?"
+syn match   masmDirective	"\.EXIT\>"
+syn match   masmDirective	"\.FARDATA\>"
+syn match   masmDirective	"\.FARDATA?"
+syn match   masmDirective	"\.MODEL\>"
+syn match   masmDirective	"\.STACK\>"
+syn match   masmDirective	"\.STARTUP\>"
+syn match   masmDirective	"\.IF\>"
+syn match   masmDirective	"\.ELSE\>"
+syn match   masmDirective	"\.ELSEIF\>"
+syn match   masmDirective	"\.ENDIF\>"
+syn match   masmDirective	"\.REPEAT\>"
+syn match   masmDirective	"\.UNTIL\>"
+syn match   masmDirective	"\.UNTILCXZ\>"
+syn match   masmDirective	"\.WHILE\>"
+syn match   masmDirective	"\.ENDW\>"
+syn match   masmDirective	"\.BREAK\>"
+syn match   masmDirective	"\.CONTINUE\>"
+syn match   masmDirective	"\.ERR\>"
+syn match   masmDirective	"\.ERR1\>"
+syn match   masmDirective	"\.ERR2\>"
+syn match   masmDirective	"\.ERRB\>"
+syn match   masmDirective	"\.ERRDEF\>"
+syn match   masmDirective	"\.ERRDIF\>"
+syn match   masmDirective	"\.ERRDIFI\>"
+syn match   masmDirective	"\.ERRE\>"
+syn match   masmDirective	"\.ERRIDN\>"
+syn match   masmDirective	"\.ERRIDNI\>"
+syn match   masmDirective	"\.ERRNB\>"
+syn match   masmDirective	"\.ERRNDEF\>"
+syn match   masmDirective	"\.ERRNZ\>"
+syn match   masmDirective	"\.LALL\>"
+syn match   masmDirective	"\.SALL\>"
+syn match   masmDirective	"\.XALL\>"
+syn match   masmDirective	"\.LFCOND\>"
+syn match   masmDirective	"\.SFCOND\>"
+syn match   masmDirective	"\.TFCOND\>"
+syn match   masmDirective	"\.CREF\>"
+syn match   masmDirective	"\.NOCREF\>"
+syn match   masmDirective	"\.XCREF\>"
+syn match   masmDirective	"\.LIST\>"
+syn match   masmDirective	"\.NOLIST\>"
+syn match   masmDirective	"\.XLIST\>"
+syn match   masmDirective	"\.LISTALL\>"
+syn match   masmDirective	"\.LISTIF\>"
+syn match   masmDirective	"\.NOLISTIF\>"
+syn match   masmDirective	"\.LISTMACRO\>"
+syn match   masmDirective	"\.NOLISTMACRO\>"
+syn match   masmDirective	"\.LISTMACROALL\>"
+syn match   masmDirective	"\.FPO\>"
+syn match   masmDirective	"\.RADIX\>"
+syn match   masmDirective	"\.SAFESEH\>"
+syn match   masmDirective	"%OUT\>"
+syn match   masmDirective	"ALIGN\>"
+syn match   masmOption		"ALIGN([0-9]\+)"
+
+syn keyword masmRegister	AX BX CX DX SI DI BP SP
+syn keyword masmRegister	CS DS SS ES FS GS
+syn keyword masmRegister	AH BH CH DH AL BL CL DL
+syn keyword masmRegister	EAX EBX ECX EDX ESI EDI EBP ESP
+syn keyword masmRegister	CR0 CR2 CR3 CR4
+syn keyword masmRegister	DR0 DR1 DR2 DR3 DR6 DR7
+syn keyword masmRegister	TR3 TR4 TR5 TR6 TR7
+syn match   masmRegister	"ST([0-7])"
+
+
+" Instruction prefixes
+syn keyword masmOpcode		LOCK REP REPE REPNE REPNZ REPZ
+
+" 8086/8088 opcodes
+syn keyword masmOpcode		AAA AAD AAM AAS ADC ADD AND CALL CBW CLC CLD
+syn keyword masmOpcode		CLI CMC CMP CMPS CMPSB CMPSW CWD DAA DAS DEC
+syn keyword masmOpcode		DIV ESC HLT IDIV IMUL IN INC INT INTO IRET
+syn keyword masmOpcode		JCXZ JMP LAHF LDS LEA LES LODS LODSB LODSW
+syn keyword masmOpcode		LOOP LOOPE LOOPEW LOOPNE LOOPNEW LOOPNZ
+syn keyword masmOpcode		LOOPNZW LOOPW LOOPZ LOOPZW MOV MOVS MOVSB
+syn keyword masmOpcode		MOVSW MUL NEG NOP NOT OR OUT POP POPF PUSH
+syn keyword masmOpcode		PUSHF RCL RCR RET RETF RETN ROL ROR SAHF SAL
+syn keyword masmOpcode		SAR SBB SCAS SCASB SCASW SHL SHR STC STD STI
+syn keyword masmOpcode		STOS STOSB STOSW SUB TEST WAIT XCHG XLAT XLATB
+syn keyword masmOpcode		XOR
+syn match   masmOpcode	      "J\(P[EO]\|\(N\?\([ABGL]E\?\|[CEOPSZ]\)\)\)\>"
+
+" 80186 opcodes
+syn keyword masmOpcode		BOUND ENTER INS INSB INSW LEAVE OUTS OUTSB
+syn keyword masmOpcode		OUTSW POPA PUSHA PUSHW
+
+" 80286 opcodes
+syn keyword masmOpcode		ARPL LAR LSL SGDT SIDT SLDT SMSW STR VERR VERW
+
+" 80286/80386 privileged opcodes
+syn keyword masmOpcode		CLTS LGDT LIDT LLDT LMSW LTR
+
+" 80386 opcodes
+syn keyword masmOpcode		BSF BSR BT BTC BTR BTS CDQ CMPSD CWDE INSD
+syn keyword masmOpcode		IRETD IRETDF IRETF JECXZ LFS LGS LODSD LOOPD
+syn keyword masmOpcode		LOOPED LOOPNED LOOPNZD LOOPZD LSS MOVSD MOVSX
+syn keyword masmOpcode		MOVZX OUTSD POPAD POPFD PUSHAD PUSHD PUSHFD
+syn keyword masmOpcode		SCASD SHLD SHRD STOSD
+syn match   masmOpcode	    "SET\(P[EO]\|\(N\?\([ABGL]E\?\|[CEOPSZ]\)\)\)\>"
+
+" 80486 opcodes
+syn keyword masmOpcode		BSWAP CMPXCHG INVD INVLPG WBINVD XADD
+
+" Floating-point opcodes as of 487
+syn keyword masmOpFloat		F2XM1 FABS FADD FADDP FBLD FBSTP FCHS FCLEX
+syn keyword masmOpFloat		FNCLEX FCOM FCOMP FCOMPP FCOS FDECSTP FDISI
+syn keyword masmOpFloat		FNDISI FDIV FDIVP FDIVR FDIVRP FENI FNENI
+syn keyword masmOpFloat		FFREE FIADD FICOM FICOMP FIDIV FIDIVR FILD
+syn keyword masmOpFloat		FIMUL FINCSTP FINIT FNINIT FIST FISTP FISUB
+syn keyword masmOpFloat		FISUBR FLD FLDCW FLDENV FLDLG2 FLDLN2 FLDL2E
+syn keyword masmOpFloat		FLDL2T FLDPI FLDZ FLD1 FMUL FMULP FNOP FPATAN
+syn keyword masmOpFloat		FPREM FPREM1 FPTAN FRNDINT FRSTOR FSAVE FNSAVE
+syn keyword masmOpFloat		FSCALE FSETPM FSIN FSINCOS FSQRT FST FSTCW
+syn keyword masmOpFloat		FNSTCW FSTENV FNSTENV FSTP FSTSW FNSTSW FSUB
+syn keyword masmOpFloat		FSUBP FSUBR FSUBRP FTST FUCOM FUCOMP FUCOMPP
+syn keyword masmOpFloat		FWAIT FXAM FXCH FXTRACT FYL2X FYL2XP1
+
+" Floating-point opcodes in Pentium and later processors
+syn keyword masmOpFloat		FCMOVE FCMOVNE FCMOVB FCMOVBE FCMOVNB FCMOVNBE
+syn keyword masmOpFloat		FCMOVU FCMOVNU FCOMI FUCOMI FCOMIP FUCOMIP
+syn keyword masmOpFloat		FXSAVE FXRSTOR
+
+" MMX opcodes (Pentium w/ MMX, Pentium II, and later)
+syn keyword masmOpcode		MOVD MOVQ PACKSSWB PACKSSDW PACKUSWB
+syn keyword masmOpcode		PUNPCKHBW PUNPCKHWD PUNPCKHDQ
+syn keyword masmOpcode		PUNPCKLBW PUNPCKLWD PUNPCKLDQ
+syn keyword masmOpcode		PADDB PADDW PADDD PADDSB PADDSW PADDUSB PADDUSW
+syn keyword masmOpcode		PSUBB PSUBW PSUBD PSUBSB PSUBSW PSUBUSB PSUBUSW
+syn keyword masmOpcode		PMULHW PMULLW PMADDWD
+syn keyword masmOpcode		PCMPEQB PCMPEQW PCMPEQD PCMPGTB PCMPGTW PCMPGTD
+syn keyword masmOpcode		PAND PANDN POR PXOR
+syn keyword masmOpcode		PSLLW PSLLD PSLLQ PSRLW PSRLD PSRLQ PSRAW PSRAD
+syn keyword masmOpcode		EMMS
+
+" SSE opcodes (Pentium III and later)
+syn keyword masmOpcode		MOVAPS MOVUPS MOVHPS MOVHLPS MOVLPS MOVLHPS
+syn keyword masmOpcode		MOVMSKPS MOVSS
+syn keyword masmOpcode		ADDPS ADDSS SUBPS SUBSS MULPS MULSS DIVPS DIVSS
+syn keyword masmOpcode		RCPPS RCPSS SQRTPS SQRTSS RSQRTPS RSQRTSS
+syn keyword masmOpcode		MAXPS MAXSS MINPS MINSS
+syn keyword masmOpcode		CMPPS CMPSS COMISS UCOMISS
+syn keyword masmOpcode		ANDPS ANDNPS ORPS XORPS
+syn keyword masmOpcode		SHUFPS UNPCKHPS UNPCKLPS
+syn keyword masmOpcode		CVTPI2PS CVTSI2SS CVTPS2PI CVTTPS2PI
+syn keyword masmOpcode		CVTSS2SI CVTTSS2SI
+syn keyword masmOpcode		LDMXCSR STMXCSR
+syn keyword masmOpcode		PAVGB PAVGW PEXTRW PINSRW PMAXUB PMAXSW
+syn keyword masmOpcode		PMINUB PMINSW PMOVMSKB PMULHUW PSADBW PSHUFW
+syn keyword masmOpcode		MASKMOVQ MOVNTQ MOVNTPS SFENCE
+syn keyword masmOpcode		PREFETCHT0 PREFETCHT1 PREFETCHT2 PREFETCHNTA
+
+" SSE2 opcodes (Pentium 4 and later)
+syn keyword masmOpcode		MOVAPD MOVUPD MOVHPD MOVLPD MOVMSKPD MOVSD
+syn keyword masmOpcode		ADDPD ADDSD SUBPD SUBSD MULPD MULSD DIVPD DIVSD
+syn keyword masmOpcode		SQRTPD SQRTSD MAXPD MAXSD MINPD MINSD
+syn keyword masmOpcode		ANDPD ANDNPD ORPD XORPD
+syn keyword masmOpcode		CMPPD CMPSD COMISD UCOMISD
+syn keyword masmOpcode		SHUFPD UNPCKHPD UNPCKLPD
+syn keyword masmOpcode		CVTPD2PI CVTTPD2PI CVTPI2PD CVTPD2DQ
+syn keyword masmOpcode		CVTTPD2DQ CVTDQ2PD CVTPS2PD CVTPD2PS
+syn keyword masmOpcode		CVTSS2SD CVTSD2SS CVTSD2SI CVTTSD2SI CVTSI2SD
+syn keyword masmOpcode		CVTDQ2PS CVTPS2DQ CVTTPS2DQ
+syn keyword masmOpcode		MOVDQA MOVDQU MOVQ2DQ MOVDQ2Q PMULUDQ
+syn keyword masmOpcode		PADDQ PSUBQ PSHUFLW PSHUFHW PSHUFD
+syn keyword masmOpcode		PSLLDQ PSRLDQ PUNPCKHQDQ PUNPCKLQDQ
+syn keyword masmOpcode		CLFLUSH LFENCE MFENCE PAUSE MASKMOVDQU
+syn keyword masmOpcode		MOVNTPD MOVNTDQ MOVNTI
+
+" SSE3 opcodes (Pentium 4 w/ Hyper-Threading and later)
+syn keyword masmOpcode		FISTTP LDDQU ADDSUBPS ADDSUBPD
+syn keyword masmOpcode		HADDPS HSUBPS HADDPD HSUBPD
+syn keyword masmOpcode		MOVSHDUP MOVSLDUP MOVDDUP MONITOR MWAIT
+
+" Other opcodes in Pentium and later processors
+syn keyword masmOpcode		CMPXCHG8B CPUID UD2
+syn keyword masmOpcode		RSM RDMSR WRMSR RDPMC RDTSC SYSENTER SYSEXIT
+syn match   masmOpcode	   "CMOV\(P[EO]\|\(N\?\([ABGL]E\?\|[CEOPSZ]\)\)\)\>"
+
+
+" Define the default highlighting.
+" For version 5.7 and earlier: only when not done already
+" For version 5.8 and later: only when an item doesn't have highlighting yet
+if version >= 508 || !exists("did_masm_syntax_inits")
+  if version < 508
+    let did_masm_syntax_inits = 1
+    command -nargs=+ HiLink hi link <args>
+  else
+    command -nargs=+ HiLink hi def link <args>
+  endif
+
+  " The default methods for highlighting.  Can be overridden later
+  HiLink masmLabel	PreProc
+  HiLink masmComment	Comment
+  HiLink masmDirective	Statement
+  HiLink masmType	Type
+  HiLink masmOperator	Type
+  HiLink masmOption	Special
+  HiLink masmRegister	Special
+  HiLink masmString	String
+  HiLink masmText	String
+  HiLink masmTitle	Title
+  HiLink masmOpcode	Statement
+  HiLink masmOpFloat	Statement
+
+  HiLink masmHexadecimal Number
+  HiLink masmDecimal	Number
+  HiLink masmOctal	Number
+  HiLink masmBinary	Number
+  HiLink masmFloatRaw	Number
+  HiLink masmFloat	Number
+
+  HiLink masmIdentifier Identifier
+
+  syntax sync minlines=50
+
+  delcommand HiLink
+endif
+
+let b:current_syntax = "masm"
+
+" vim: ts=8
--- /dev/null
+++ b/lib/vimfiles/syntax/mason.vim
@@ -1,0 +1,99 @@
+" Vim syntax file
+" Language:    Mason (Perl embedded in HTML)
+" Maintainer:  Andrew Smith <andrewdsmith@yahoo.com>
+" Last change: 2003 May 11
+" URL:	       http://www.masonhq.com/editors/mason.vim
+"
+" This seems to work satisfactorily with html.vim and perl.vim for version 5.5.
+" Please mail any fixes or improvements to the above address. Things that need
+" doing include:
+"
+"  - Add match for component names in <& &> blocks.
+"  - Add match for component names in <%def> and <%method> block delimiters.
+"  - Fix <%text> blocks to show HTML tags but ignore Mason tags.
+"
+
+" Clear previous syntax settings unless this is v6 or above, in which case just
+" exit without doing anything.
+"
+if version < 600
+	syn clear
+elseif exists("b:current_syntax")
+	finish
+endif
+
+" The HTML syntax file included below uses this variable.
+"
+if !exists("main_syntax")
+	let main_syntax = 'mason'
+endif
+
+" First pull in the HTML syntax.
+"
+if version < 600
+	so <sfile>:p:h/html.vim
+else
+	runtime! syntax/html.vim
+	unlet b:current_syntax
+endif
+
+syn cluster htmlPreproc add=@masonTop
+
+" Now pull in the Perl syntax.
+"
+if version < 600
+	syn include @perlTop <sfile>:p:h/perl.vim
+else
+	syn include @perlTop syntax/perl.vim
+endif
+
+" It's hard to reduce down to the correct sub-set of Perl to highlight in some
+" of these cases so I've taken the safe option of just using perlTop in all of
+" them. If you have any suggestions, please let me know.
+"
+syn region masonLine matchgroup=Delimiter start="^%" end="$" contains=@perlTop
+syn region masonExpr matchgroup=Delimiter start="<%" end="%>" contains=@perlTop
+syn region masonPerl matchgroup=Delimiter start="<%perl>" end="</%perl>" contains=@perlTop
+syn region masonComp keepend matchgroup=Delimiter start="<&" end="&>" contains=@perlTop
+
+syn region masonArgs matchgroup=Delimiter start="<%args>" end="</%args>" contains=@perlTop
+
+syn region masonInit matchgroup=Delimiter start="<%init>" end="</%init>" contains=@perlTop
+syn region masonCleanup matchgroup=Delimiter start="<%cleanup>" end="</%cleanup>" contains=@perlTop
+syn region masonOnce matchgroup=Delimiter start="<%once>" end="</%once>" contains=@perlTop
+syn region masonShared matchgroup=Delimiter start="<%shared>" end="</%shared>" contains=@perlTop
+
+syn region masonDef matchgroup=Delimiter start="<%def[^>]*>" end="</%def>" contains=@htmlTop
+syn region masonMethod matchgroup=Delimiter start="<%method[^>]*>" end="</%method>" contains=@htmlTop
+
+syn region masonFlags matchgroup=Delimiter start="<%flags>" end="</%flags>" contains=@perlTop
+syn region masonAttr matchgroup=Delimiter start="<%attr>" end="</%attr>" contains=@perlTop
+
+syn region masonFilter matchgroup=Delimiter start="<%filter>" end="</%filter>" contains=@perlTop
+
+syn region masonDoc matchgroup=Delimiter start="<%doc>" end="</%doc>"
+syn region masonText matchgroup=Delimiter start="<%text>" end="</%text>"
+
+syn cluster masonTop contains=masonLine,masonExpr,masonPerl,masonComp,masonArgs,masonInit,masonCleanup,masonOnce,masonShared,masonDef,masonMethod,masonFlags,masonAttr,masonFilter,masonDoc,masonText
+
+" Set up default highlighting. Almost all of this is done in the included
+" syntax files.
+"
+if version >= 508 || !exists("did_mason_syn_inits")
+	if version < 508
+		let did_mason_syn_inits = 1
+		com -nargs=+ HiLink hi link <args>
+	else
+		com -nargs=+ HiLink hi def link <args>
+	endif
+
+	HiLink masonDoc Comment
+
+	delc HiLink
+endif
+
+let b:current_syntax = "mason"
+
+if main_syntax == 'mason'
+	unlet main_syntax
+endif
--- /dev/null
+++ b/lib/vimfiles/syntax/master.vim
@@ -1,0 +1,50 @@
+" Vim syntax file
+" Language:	Focus Master File
+" Maintainer:	Rob Brady <robb@datatone.com>
+" Last Change:	$Date: 2004/06/13 15:54:03 $
+" URL: http://www.datatone.com/~robb/vim/syntax/master.vim
+" $Revision: 1.1 $
+
+" this is a very simple syntax file - I will be improving it
+" add entire DEFINE syntax
+
+" For version 5.x: Clear all syntax items
+" For version 6.x: Quit when a syntax file was already loaded
+if version < 600
+  syntax clear
+elseif exists("b:current_syntax")
+  finish
+endif
+
+syn case match
+
+" A bunch of useful keywords
+syn keyword masterKeyword	FILENAME SUFFIX SEGNAME SEGTYPE PARENT FIELDNAME
+syn keyword masterKeyword	FIELD ALIAS USAGE INDEX MISSING ON
+syn keyword masterKeyword	FORMAT CRFILE CRKEY
+syn keyword masterDefine	DEFINE DECODE EDIT
+syn region  masterString	start=+"+  end=+"+
+syn region  masterString	start=+'+  end=+'+
+syn match   masterComment	"\$.*"
+
+" Define the default highlighting.
+" For version 5.7 and earlier: only when not done already
+" For version 5.8 and later: only when an item doesn't have highlighting yet
+if version >= 508 || !exists("did_master_syntax_inits")
+  if version < 508
+    let did_master_syntax_inits = 1
+    command -nargs=+ HiLink hi link <args>
+  else
+    command -nargs=+ HiLink hi def link <args>
+  endif
+
+  HiLink masterKeyword Keyword
+  HiLink masterComment Comment
+  HiLink masterString  String
+
+  delcommand HiLink
+endif
+
+let b:current_syntax = "master"
+
+" vim: ts=8
--- /dev/null
+++ b/lib/vimfiles/syntax/matlab.vim
@@ -1,0 +1,109 @@
+" Vim syntax file
+" Language:	Matlab
+" Maintainer:	Preben 'Peppe' Guldberg <peppe-vim@wielders.org>
+"		Original author: Mario Eusebio
+" Last Change:	30 May 2003
+
+" For version 5.x: Clear all syntax items
+" For version 6.x: Quit when a syntax file was already loaded
+if version < 600
+  syntax clear
+elseif exists("b:current_syntax")
+  finish
+endif
+
+syn keyword matlabStatement		return
+syn keyword matlabLabel			case switch
+syn keyword matlabConditional		else elseif end if otherwise
+syn keyword matlabRepeat		do for while
+
+syn keyword matlabTodo			contained  TODO
+
+" If you do not want these operators lit, uncommment them and the "hi link" below
+syn match matlabArithmeticOperator	"[-+]"
+syn match matlabArithmeticOperator	"\.\=[*/\\^]"
+syn match matlabRelationalOperator	"[=~]="
+syn match matlabRelationalOperator	"[<>]=\="
+syn match matlabLogicalOperator		"[&|~]"
+
+syn match matlabLineContinuation	"\.\{3}"
+
+"syn match matlabIdentifier		"\<\a\w*\>"
+
+" String
+syn region matlabString			start=+'+ end=+'+	oneline
+
+" If you don't like tabs
+syn match matlabTab			"\t"
+
+" Standard numbers
+syn match matlabNumber		"\<\d\+[ij]\=\>"
+" floating point number, with dot, optional exponent
+syn match matlabFloat		"\<\d\+\(\.\d*\)\=\([edED][-+]\=\d\+\)\=[ij]\=\>"
+" floating point number, starting with a dot, optional exponent
+syn match matlabFloat		"\.\d\+\([edED][-+]\=\d\+\)\=[ij]\=\>"
+
+" Transpose character and delimiters: Either use just [...] or (...) aswell
+syn match matlabDelimiter		"[][]"
+"syn match matlabDelimiter		"[][()]"
+syn match matlabTransposeOperator	"[])a-zA-Z0-9.]'"lc=1
+
+syn match matlabSemicolon		";"
+
+syn match matlabComment			"%.*$"	contains=matlabTodo,matlabTab
+
+syn keyword matlabOperator		break zeros default margin round ones rand
+syn keyword matlabOperator		ceil floor size clear zeros eye mean std cov
+
+syn keyword matlabFunction		error eval function
+
+syn keyword matlabImplicit		abs acos atan asin cos cosh exp log prod sum
+syn keyword matlabImplicit		log10 max min sign sin sqrt tan reshape
+
+syn match matlabError	"-\=\<\d\+\.\d\+\.[^*/\\^]"
+syn match matlabError	"-\=\<\d\+\.\d\+[eEdD][-+]\=\d\+\.\([^*/\\^]\)"
+
+" Define the default highlighting.
+" For version 5.7 and earlier: only when not done already
+" For version 5.8 and later: only when an item doesn't have highlighting yet
+if version >= 508 || !exists("did_matlab_syntax_inits")
+  if version < 508
+    let did_matlab_syntax_inits = 1
+    command -nargs=+ HiLink hi link <args>
+  else
+    command -nargs=+ HiLink hi def link <args>
+  endif
+
+  HiLink matlabTransposeOperator	matlabOperator
+  HiLink matlabOperator		Operator
+  HiLink matlabLineContinuation	Special
+  HiLink matlabLabel			Label
+  HiLink matlabConditional		Conditional
+  HiLink matlabRepeat			Repeat
+  HiLink matlabTodo			Todo
+  HiLink matlabString			String
+  HiLink matlabDelimiter		Identifier
+  HiLink matlabTransposeOther		Identifier
+  HiLink matlabNumber			Number
+  HiLink matlabFloat			Float
+  HiLink matlabFunction		Function
+  HiLink matlabError			Error
+  HiLink matlabImplicit		matlabStatement
+  HiLink matlabStatement		Statement
+  HiLink matlabSemicolon		SpecialChar
+  HiLink matlabComment			Comment
+
+  HiLink matlabArithmeticOperator	matlabOperator
+  HiLink matlabRelationalOperator	matlabOperator
+  HiLink matlabLogicalOperator		matlabOperator
+
+"optional highlighting
+  "HiLink matlabIdentifier		Identifier
+  "HiLink matlabTab			Error
+
+  delcommand HiLink
+endif
+
+let b:current_syntax = "matlab"
+
+"EOF	vim: ts=8 noet tw=100 sw=8 sts=0
--- /dev/null
+++ b/lib/vimfiles/syntax/maxima.vim
@@ -1,0 +1,274 @@
+" Vim syntax file
+" Language:	Maxima (symbolic algebra program)
+" Maintainer:	Robert Dodier (robert.dodier@gmail.com)
+" Last Change:	April 6, 2006
+" Version:	1
+" Adapted mostly from xmath.vim
+" Number formats adapted from r.vim
+"
+" For version 5.x: Clear all syntax items
+" For version 6.x: Quit when a syntax file was already loaded
+if version < 600
+  syntax clear
+elseif exists("b:current_syntax")
+  finish
+endif
+
+syn sync lines=1000
+
+" parenthesis sanity checker
+syn region maximaZone	matchgroup=Delimiter start="(" matchgroup=Delimiter end=")" transparent contains=ALLBUT,maximaError,maximaBraceError,maximaCurlyError
+syn region maximaZone	matchgroup=Delimiter start="{" matchgroup=Delimiter end="}" transparent contains=ALLBUT,maximaError,maximaBraceError,maximaParenError
+syn region maximaZone	matchgroup=Delimiter start="\[" matchgroup=Delimiter end="]" transparent contains=ALLBUT,maximaError,maximaCurlyError,maximaParenError
+syn match  maximaError	"[)\]}]"
+syn match  maximaBraceError	"[)}]"	contained
+syn match  maximaCurlyError	"[)\]]"	contained
+syn match  maximaParenError	"[\]}]"	contained
+syn match  maximaComma	"[\[\](),;]"
+syn match  maximaComma	"\.\.\.$"
+
+" A bunch of useful maxima keywords
+syn keyword maximaConditional	if then else elseif and or not
+syn keyword maximaRepeat	do for thru
+
+" ---------------------- BEGIN LIST OF ALL FUNCTIONS (EXCEPT KEYWORDS)  ----------------------
+syn keyword maximaFunc abasep  abs  absboxchar  absint  acos  acosh  acot  acoth  acsc  
+syn keyword maximaFunc acsch  activate  activecontexts  addcol  additive  addrow  adim  
+syn keyword maximaFunc adjoint  af  aform  airy  algebraic  algepsilon  algexact  algsys  
+syn keyword maximaFunc alg_type  alias  aliases  allbut  all_dotsimp_denoms  allroots  allsym  
+syn keyword maximaFunc alphabetic  antid  antidiff  antisymmetric  append  appendfile  
+syn keyword maximaFunc apply  apply1  apply2  applyb1  apropos  args  array  arrayapply  
+syn keyword maximaFunc arrayinfo  arraymake  arrays  asec  asech  asin  asinh  askexp  
+syn keyword maximaFunc askinteger  asksign  assoc  assoc_legendre_p  assoc_legendre_q  assume  
+syn keyword maximaFunc assume_pos  assume_pos_pred  assumescalar  asymbol  asympa  at  atan  
+syn keyword maximaFunc atan2  atanh  atensimp  atom  atomgrad  atrig1  atvalue  augcoefmatrix  
+syn keyword maximaFunc av  backsubst  backtrace  bashindices  batch  batchload  bc2  bdvac  
+syn keyword maximaFunc berlefact  bern  bernpoly  bessel  besselexpand  bessel_i  bessel_j  
+syn keyword maximaFunc bessel_k  bessel_y  beta  bezout  bffac  bfhzeta  bfloat  bfloatp  
+syn keyword maximaFunc bfpsi  bfpsi0  bftorat  bftrunc  bfzeta  bimetric  binomial  block  
+syn keyword maximaFunc bothcoef  box  boxchar  break  breakup  bug_report  build_info  buildq  
+syn keyword maximaFunc burn  cabs  canform  canten  carg  cartan  catch  cauchysum  cbffac  
+syn keyword maximaFunc cdisplay  cf  cfdisrep  cfexpand  cflength  cframe_flag  cgeodesic  
+syn keyword maximaFunc changename  changevar  charpoly  checkdiv  check_overlaps  christof  
+syn keyword maximaFunc clear_rules  closefile  closeps  cmetric  cnonmet_flag  coeff  
+syn keyword maximaFunc coefmatrix  cograd  col  collapse  columnvector  combine  commutative  
+syn keyword maximaFunc comp2pui  compfile  compile  compile_file  components  concan  concat  
+syn keyword maximaFunc conj  conjugate  conmetderiv  cons  constant  constantp  cont2part  
+syn keyword maximaFunc content  context  contexts  contortion  contract  contragrad  coord  
+syn keyword maximaFunc copylist  copymatrix  cos  cosh  cosnpiflag  cot  coth  covdiff  
+syn keyword maximaFunc covect  create_list  csc  csch  csetup  ctaylor  ctaypov  ctaypt  
+syn keyword maximaFunc ctayswitch  ctayvar  ct_coords  ct_coordsys  ctorsion_flag  ctransform  
+syn keyword maximaFunc ctrgsimp  current_let_rule_package  dblint  deactivate  debugmode  
+syn keyword maximaFunc declare  declare_translated  declare_weight  decsym  
+syn keyword maximaFunc default_let_rule_package  defcon  define  define_variable  defint  
+syn keyword maximaFunc defmatch  defrule  deftaylor  del  delete  deleten  delta  demo  
+syn keyword maximaFunc demoivre  denom  dependencies  depends  derivabbrev  derivdegree  
+syn keyword maximaFunc derivlist  derivsubst  describe  desolve  determinant  detout  
+syn keyword maximaFunc diagmatrix  diagmatrixp  diagmetric  diff  dim  dimension  direct  
+syn keyword maximaFunc disolate  disp  dispcon  dispflag  dispform  dispfun  display  
+syn keyword maximaFunc display2d  display_format_internal  disprule  dispterms  distrib  
+syn keyword maximaFunc divide  divsum  doallmxops  domain  domxexpt  domxmxops  domxnctimes  
+syn keyword maximaFunc dontfactor  doscmxops  doscmxplus  dot0nscsimp  dot0simp  dot1simp  
+syn keyword maximaFunc dotassoc  dotconstrules  dotdistrib  dotexptsimp  dotident  dotscrules  
+syn keyword maximaFunc dotsimp  dpart  dscalar  %e  echelon  %edispflag  eigenvalues  
+syn keyword maximaFunc eigenvectors  eighth  einstein  eivals  eivects  ele2comp  
+syn keyword maximaFunc ele2polynome  ele2pui  elem  eliminate  elliptic_e  elliptic_ec  
+syn keyword maximaFunc elliptic_eu  elliptic_f  elliptic_kc  elliptic_pi  ematrix  %emode  
+syn keyword maximaFunc endcons  entermatrix  entertensor  entier  %enumer  equal  equalp  erf  
+syn keyword maximaFunc erfflag  errcatch  error  errormsg  error_size  error_syms  
+syn keyword maximaFunc %e_to_numlog  euler  ev  eval  evenp  every  evflag  evfun  evundiff  
+syn keyword maximaFunc example  exp  expand  expandwrt  expandwrt_denom  expandwrt_factored  
+syn keyword maximaFunc explose  expon  exponentialize  expop  express  expt  exptdispflag  
+syn keyword maximaFunc exptisolate  exptsubst  extdiff  extract_linear_equations  ezgcd  
+syn keyword maximaFunc facexpand  factcomb  factlim  factor  factorflag  factorial  factorout  
+syn keyword maximaFunc factorsum  facts  false  fast_central_elements  fast_linsolve  
+syn keyword maximaFunc fasttimes  fb  feature  featurep  features  fft  fib  fibtophi  fifth  
+syn keyword maximaFunc filename_merge  file_search  file_search_demo  file_search_lisp  
+syn keyword maximaFunc file_search_maxima  file_type  fillarray  findde  first  fix  flatten  
+syn keyword maximaFunc flipflag  float  float2bf  floatnump  flush  flush1deriv  flushd  
+syn keyword maximaFunc flushnd  forget  fortindent  fortran  fortspaces  fourcos  fourexpand  
+syn keyword maximaFunc fourier  fourint  fourintcos  fourintsin  foursimp  foursin  fourth  
+syn keyword maximaFunc fpprec  fpprintprec  frame_bracket  freeof  fullmap  fullmapl  
+syn keyword maximaFunc fullratsimp  fullratsubst  funcsolve  functions  fundef  funmake  funp  
+syn keyword maximaFunc gamma  %gamma  gammalim  gauss  gcd  gcdex  gcfactor  gdet  genfact  
+syn keyword maximaFunc genindex  genmatrix  gensumnum  get  getchar  gfactor  gfactorsum  
+syn keyword maximaFunc globalsolve  go  gradef  gradefs  gramschmidt  grind  grobner_basis  
+syn keyword maximaFunc gschmit  hach  halfangles  hermite  hipow  hodge  horner  i0  i1  
+syn keyword maximaFunc *read-base*  ic1  ic2  icc1  icc2  ic_convert  ichr1  ichr2  icounter  
+syn keyword maximaFunc icurvature  ident  idiff  idim  idummy  idummyx  ieqn  ieqnprint  ifb  
+syn keyword maximaFunc ifc1  ifc2  ifg  ifgi  ifr  iframe_bracket_form  iframes  ifri  ift  
+syn keyword maximaFunc igeodesic_coords  igeowedge_flag  ikt1  ikt2  ilt  imagpart  imetric  
+syn keyword maximaFunc inchar  indexed_tensor  indices  inf  %inf  infeval  infinity  infix  
+syn keyword maximaFunc inflag  infolists  init_atensor  init_ctensor  inm  inmc1  inmc2  
+syn keyword maximaFunc innerproduct  in_netmath  inpart  inprod  inrt  integerp  integrate  
+syn keyword maximaFunc integrate_use_rootsof  integration_constant_counter  interpolate  
+syn keyword maximaFunc intfaclim  intopois  intosum  intpolabs  intpolerror  intpolrel  
+syn keyword maximaFunc invariant1  invariant2  inverse_jacobi_cd  inverse_jacobi_cn  
+syn keyword maximaFunc inverse_jacobi_cs  inverse_jacobi_dc  inverse_jacobi_dn  
+syn keyword maximaFunc inverse_jacobi_ds  inverse_jacobi_nc  inverse_jacobi_nd  
+syn keyword maximaFunc inverse_jacobi_ns  inverse_jacobi_sc  inverse_jacobi_sd  
+syn keyword maximaFunc inverse_jacobi_sn  invert  is  ishow  isolate  isolate_wrt_times  
+syn keyword maximaFunc isqrt  itr  j0  j1  jacobi  jacobi_cd  jacobi_cn  jacobi_cs  jacobi_dc  
+syn keyword maximaFunc jacobi_dn  jacobi_ds  jacobi_nc  jacobi_nd  jacobi_ns  jacobi_sc  
+syn keyword maximaFunc jacobi_sd  jacobi_sn  jn  kdels  kdelta  keepfloat  kill  killcontext  
+syn keyword maximaFunc kinvariant  kostka  kt  labels  lambda  laplace  lassociative  last  
+syn keyword maximaFunc lc2kdt  lc_l  lcm  lc_u  ldefint  ldisp  ldisplay  leinstein  length  
+syn keyword maximaFunc let  letrat  let_rule_packages  letrules  letsimp  levi_civita  lfg  
+syn keyword maximaFunc lfreeof  lg  lgtreillis  lhospitallim  lhs  liediff  limit  limsubst  
+syn keyword maximaFunc linear  linechar  linel  linenum  linsolve  linsolve_params  
+syn keyword maximaFunc linsolvewarn  listarith  listarray  listconstvars  listdummyvars  
+syn keyword maximaFunc list_nc_monomials  listoftens  listofvars  listp  lmxchar  load  
+syn keyword maximaFunc loadfile  loadprint  local  log  logabs  logarc  logconcoeffp  
+syn keyword maximaFunc logcontract  logexpand  lognegint  lognumer  logsimp  lopow  
+syn keyword maximaFunc lorentz_gauge  lpart  lratsubst  lriem  lriemann  lsum  ltreillis  
+syn keyword maximaFunc m1pbranch  macroexpansion  mainvar  make_array  makebox  makefact  
+syn keyword maximaFunc makegamma  makelist  make_random_state  make_transform  map  mapatom  
+syn keyword maximaFunc maperror  maplist  matchdeclare  matchfix  matrix  matrix_element_add  
+syn keyword maximaFunc matrix_element_mult  matrix_element_transpose  matrixmap  matrixp  
+syn keyword maximaFunc mattrace  max  maxapplydepth  maxapplyheight  maxnegex  maxposex  
+syn keyword maximaFunc maxtayorder  member  min  %minf  minfactorial  minor  mod  
+syn keyword maximaFunc mode_check_errorp  mode_checkp  mode_check_warnp  mode_declare  
+syn keyword maximaFunc mode_identity  modulus  mon2schur  mono  monomial_dimensions  
+syn keyword maximaFunc multi_elem  multinomial  multi_orbit  multiplicative  multiplicities  
+syn keyword maximaFunc multi_pui  multsym  multthru  myoptions  nc_degree  ncexpt  ncharpoly  
+syn keyword maximaFunc negdistrib  negsumdispflag  newcontext  newdet  newton  niceindices  
+syn keyword maximaFunc niceindicespref  ninth  nm  nmc  noeval  nolabels  nonmetricity  
+syn keyword maximaFunc nonscalar  nonscalarp  noun  noundisp  nounify  nouns  np  npi  
+syn keyword maximaFunc nptetrad  nroots  nterms  ntermst  nthroot  ntrig  num  numberp  numer  
+syn keyword maximaFunc numerval  numfactor  nusum  obase  oddp  ode2  op  openplot_curves  
+syn keyword maximaFunc operatorp  opproperties  opsubst  optimize  optimprefix  optionset
+syn keyword maximaFunc orbit  ordergreat  ordergreatp  orderless  orderlessp  outative  
+syn keyword maximaFunc outchar  outermap  outofpois  packagefile  pade  part  part2cont  
+syn keyword maximaFunc partfrac  partition  partpol  partswitch  permanent  permut  petrov  
+syn keyword maximaFunc pfeformat  pi  pickapart  piece  playback  plog  plot2d  plot2d_ps  
+syn keyword maximaFunc plot3d  plot_options  poisdiff  poisexpt  poisint  poislim  poismap  
+syn keyword maximaFunc poisplus  poissimp  poisson  poissubst  poistimes  poistrim  polarform  
+syn keyword maximaFunc polartorect  polynome2ele  posfun  potential  powerdisp  powers  
+syn keyword maximaFunc powerseries  pred  prederror  primep  print  printpois  printprops  
+syn keyword maximaFunc prodhack  prodrac  product  programmode  prompt  properties  props  
+syn keyword maximaFunc propvars  pscom  psdraw_curve  psexpand  psi  pui  pui2comp  pui2ele  
+syn keyword maximaFunc pui2polynome  pui_direct  puireduc  put  qput  qq  quad_qag  quad_qagi  
+syn keyword maximaFunc quad_qags  quad_qawc  quad_qawf  quad_qawo  quad_qaws  quanc8  quit  
+syn keyword maximaFunc qunit  quotient  radcan  radexpand  radsubstflag  random  rank  
+syn keyword maximaFunc rassociative  rat  ratalgdenom  ratchristof  ratcoef  ratdenom  
+syn keyword maximaFunc ratdenomdivide  ratdiff  ratdisrep  rateinstein  ratepsilon  ratexpand  
+syn keyword maximaFunc ratfac  ratmx  ratnumer  ratnump  ratp  ratprint  ratriemann  ratsimp  
+syn keyword maximaFunc ratsimpexpons  ratsubst  ratvars  ratweight  ratweights  ratweyl  
+syn keyword maximaFunc ratwtlvl  read  readonly  realonly  realpart  realroots  rearray  
+syn keyword maximaFunc rectform  recttopolar  rediff  refcheck  rem  remainder  remarray  
+syn keyword maximaFunc rembox  remcomps  remcon  remcoord  remfun  remfunction  remlet  
+syn keyword maximaFunc remove  remrule  remsym  remvalue  rename  reset  residue  resolvante  
+syn keyword maximaFunc resolvante_alternee1  resolvante_bipartite  resolvante_diedrale  
+syn keyword maximaFunc resolvante_klein  resolvante_klein3  resolvante_produit_sym  
+syn keyword maximaFunc resolvante_unitaire  resolvante_vierer  rest  resultant  return  
+syn keyword maximaFunc reveal  reverse  revert  revert2  rhs  ric  ricci  riem  riemann  
+syn keyword maximaFunc rinvariant  risch  rmxchar  rncombine  %rnum_list  romberg  rombergabs  
+syn keyword maximaFunc rombergit  rombergmin  rombergtol  room  rootsconmode  rootscontract  
+syn keyword maximaFunc rootsepsilon  round  row  run_testsuite  save  savedef  savefactors  
+syn keyword maximaFunc scalarmatrixp  scalarp  scalefactors  scanmap  schur2comp  sconcat  
+syn keyword maximaFunc scsimp  scurvature  sec  sech  second  setcheck  setcheckbreak  
+syn keyword maximaFunc setelmx  set_plot_option  set_random_state  setup_autoload  
+syn keyword maximaFunc set_up_dot_simplifications  setval  seventh  sf  show  showcomps  
+syn keyword maximaFunc showratvars  showtime  sign  signum  similaritytransform  simpsum  
+syn keyword maximaFunc simtran  sin  sinh  sinnpiflag  sixth  solve  solvedecomposes  
+syn keyword maximaFunc solveexplicit  solvefactors  solve_inconsistent_error  solvenullwarn  
+syn keyword maximaFunc solveradcan  solvetrigwarn  somrac  sort  sparse  spherical_bessel_j  
+syn keyword maximaFunc spherical_bessel_y  spherical_hankel1  spherical_hankel2  
+syn keyword maximaFunc spherical_harmonic  splice  sqfr  sqrt  sqrtdispflag  sstatus  
+syn keyword maximaFunc stardisp  status  string  stringout  sublis  sublis_apply_lambda  
+syn keyword maximaFunc sublist  submatrix  subst  substinpart  substpart  subvarp  sum  
+syn keyword maximaFunc sumcontract  sumexpand  sumhack  sumsplitfact  supcontext  symbolp  
+syn keyword maximaFunc symmetric  symmetricp  system  tan  tanh  taylor  taylordepth  
+syn keyword maximaFunc taylorinfo  taylor_logexpand  taylor_order_coefficients  taylorp  
+syn keyword maximaFunc taylor_simplifier  taylor_truncate_polynomials  taytorat  tcl_output  
+syn keyword maximaFunc tcontract  tellrat  tellsimp  tellsimpafter  tensorkill  tentex  tenth  
+syn keyword maximaFunc tex  %th  third  throw  time  timer  timer_devalue  timer_info  
+syn keyword maximaFunc tldefint  tlimit  tlimswitch  todd_coxeter  to_lisp  totaldisrep  
+syn keyword maximaFunc totalfourier  totient  tpartpol  tr  trace  trace_options  
+syn keyword maximaFunc transcompile  translate  translate_file  transpose  transrun  
+syn keyword maximaFunc tr_array_as_ref  tr_bound_function_applyp  treillis  treinat  
+syn keyword maximaFunc tr_file_tty_messagesp  tr_float_can_branch_complex  
+syn keyword maximaFunc tr_function_call_default  triangularize  trigexpand  trigexpandplus  
+syn keyword maximaFunc trigexpandtimes  triginverses  trigrat  trigreduce  trigsign  trigsimp  
+syn keyword maximaFunc tr_numer  tr_optimize_max_loop  tr_semicompile  tr_state_vars  true  
+syn keyword maximaFunc trunc  truncate  tr_warn_bad_function_calls  tr_warn_fexpr  
+syn keyword maximaFunc tr_warnings_get  tr_warn_meval  tr_warn_mode  tr_warn_undeclared  
+syn keyword maximaFunc tr_warn_undefined_variable  tr_windy  ttyoff  ueivects  ufg  ug  
+syn keyword maximaFunc ultraspherical  undiff  uniteigenvectors  unitvector  unknown  unorder  
+syn keyword maximaFunc unsum  untellrat  untimer  untrace  uric  uricci  uriem  uriemann  
+syn keyword maximaFunc use_fast_arrays  uvect  values  vect_cross  vectorpotential  
+syn keyword maximaFunc vectorsimp  verb  verbify  verbose  weyl  with_stdout  writefile  
+syn keyword maximaFunc xgraph_curves  xthru  zerobern  zeroequiv  zeromatrix  zeta  zeta%pi
+syn match maximaOp "[\*\/\+\-\#\!\~\^\=\:\<\>\@]"
+" ---------------------- END LIST OF ALL FUNCTIONS (EXCEPT KEYWORDS)  ----------------------
+
+
+syn case match
+
+" Labels (supports maxima's goto)
+syn match   maximaLabel	 "^\s*<[a-zA-Z_][a-zA-Z0-9%_]*>"
+
+" String and Character constants
+" Highlight special characters (those which have a backslash) differently
+syn match   maximaSpecial	contained "\\\d\d\d\|\\."
+syn region  maximaString	start=+"+  skip=+\\\\\|\\"+  end=+"+ contains=maximaSpecial
+syn match   maximaCharacter	"'[^\\]'"
+syn match   maximaSpecialChar	"'\\.'"
+
+" number with no fractional part or exponent
+syn match maximaNumber /\<\d\+\>/
+" floating point number with integer and fractional parts and optional exponent
+syn match maximaFloat /\<\d\+\.\d*\([BbDdEeSs][-+]\=\d\+\)\=\>/
+" floating point number with no integer part and optional exponent
+syn match maximaFloat /\<\.\d\+\([BbDdEeSs][-+]\=\d\+\)\=\>/
+" floating point number with no fractional part and optional exponent
+syn match maximaFloat /\<\d\+[BbDdEeSs][-+]\=\d\+\>/
+
+" Comments:
+" maxima supports /* ... */ (like C)
+syn keyword maximaTodo contained	TODO Todo DEBUG
+syn region  maximaCommentBlock	start="/\*" end="\*/"	contains=maximaString,maximaTodo
+
+" synchronizing
+syn sync match maximaSyncComment	grouphere maximaCommentBlock "/*"
+syn sync match maximaSyncComment	groupthere NONE "*/"
+
+" Define the default highlighting.
+" For version 5.7 and earlier: only when not done already
+" For version 5.8 and later: only when an item doesn't have highlighting yet
+if version >= 508 || !exists("did_maxima_syntax_inits")
+  if version < 508
+    let did_maxima_syntax_inits = 1
+    command -nargs=+ HiLink hi link <args>
+  else
+    command -nargs=+ HiLink hi def link <args>
+  endif
+
+  HiLink maximaBraceError	maximaError
+  HiLink maximaCmd	maximaStatement
+  HiLink maximaCurlyError	maximaError
+  HiLink maximaFuncCmd	maximaStatement
+  HiLink maximaParenError	maximaError
+
+  " The default methods for highlighting.  Can be overridden later
+  HiLink maximaCharacter	Character
+  HiLink maximaComma	Function
+  HiLink maximaCommentBlock	Comment
+  HiLink maximaConditional	Conditional
+  HiLink maximaError	Error
+  HiLink maximaFunc	Delimiter
+  HiLink maximaOp                 Delimiter
+  HiLink maximaLabel	PreProc
+  HiLink maximaNumber	Number
+  HiLink maximaFloat	Float
+  HiLink maximaRepeat	Repeat
+  HiLink maximaSpecial	Type
+  HiLink maximaSpecialChar	SpecialChar
+  HiLink maximaStatement	Statement
+  HiLink maximaString	String
+  HiLink maximaTodo	Todo
+
+  delcommand HiLink
+endif
+
+let b:current_syntax = "maxima"
--- /dev/null
+++ b/lib/vimfiles/syntax/mel.vim
@@ -1,0 +1,121 @@
+" Vim syntax file
+" Language:	MEL (Maya Extension Language)
+" Maintainer:	Robert Minsk <egbert@centropolisfx.com>
+" Last Change:	May 27 1999
+" Based on:	Bram Moolenaar <Bram@vim.org> C syntax file
+
+" For version 5.x: Clear all syntax items
+" For version 6.x: Quit when a syntax file was already loaded
+if version < 600
+  syntax clear
+elseif exists("b:current_syntax")
+  finish
+endif
+
+" when wanted, highlight trailing white space and spaces before tabs
+if exists("mel_space_errors")
+  sy match	melSpaceError	"\s\+$"
+  sy match	melSpaceError	" \+\t"me=e-1
+endif
+
+" A bunch of usefull MEL keyworks
+sy keyword	melBoolean	true false yes no on off
+
+sy keyword	melFunction	proc
+sy match	melIdentifier	"\$\(\a\|_\)\w*"
+
+sy keyword	melStatement	break continue return
+sy keyword	melConditional	if else switch
+sy keyword	melRepeat	while for do in
+sy keyword	melLabel	case default
+sy keyword	melOperator	size eval env exists whatIs
+sy keyword	melKeyword	alias
+sy keyword	melException	catch error warning
+
+sy keyword	melInclude	source
+
+sy keyword	melType		int float string vector matrix
+sy keyword	melStorageClass	global
+
+sy keyword	melDebug	trace
+
+sy keyword	melTodo		contained TODO FIXME XXX
+
+" MEL data types
+sy match	melCharSpecial	contained "\\[ntr\\"]"
+sy match	melCharError	contained "\\[^ntr\\"]"
+
+sy region	melString	start=+"+ skip=+\\"+ end=+"+ contains=melCharSpecial,melCharError
+
+sy case ignore
+sy match	melInteger	"\<\d\+\(e[-+]\=\d\+\)\=\>"
+sy match	melFloat	"\<\d\+\(e[-+]\=\d\+\)\=f\>"
+sy match	melFloat	"\<\d\+\.\d*\(e[-+]\=\d\+\)\=f\=\>"
+sy match	melFloat	"\.\d\+\(e[-+]\=\d\+\)\=f\=\>"
+sy case match
+
+sy match	melCommaSemi	contained "[,;]"
+sy region	melMatrixVector	start=/<</ end=/>>/ contains=melInteger,melFloat,melIdentifier,melCommaSemi
+
+sy cluster	melGroup	contains=melFunction,melStatement,melConditional,melLabel,melKeyword,melStorageClass,melTODO,melCharSpecial,melCharError,melCommaSemi
+
+" catch errors caused by wrong parenthesis
+sy region	melParen	transparent start='(' end=')' contains=ALLBUT,@melGroup,melParenError,melInParen
+sy match	melParenError	")"
+sy match	melInParen	contained "[{}]"
+
+" comments
+sy region	melComment	start="/\*" end="\*/" contains=melTodo,melSpaceError
+sy match	melComment	"//.*" contains=melTodo,melSpaceError
+sy match	melCommentError "\*/"
+
+sy region	melQuestionColon matchgroup=melConditional transparent start='?' end=':' contains=ALLBUT,@melGroup
+
+if !exists("mel_minlines")
+  let mel_minlines=15
+endif
+exec "sy sync ccomment melComment minlines=" . mel_minlines
+
+" Define the default highlighting.
+" For version 5.7 and earlier: only when not done already
+" For version 5.8 and later: only when an item doesn't have highlighting yet
+if version >= 508 || !exists("did_mel_syntax_inits")
+  if version < 508
+    let did_mel_syntax_inits = 1
+    command -nargs=+ HiLink hi link <args>
+  else
+    command -nargs=+ HiLink hi def link <args>
+  endif
+
+  HiLink melBoolean	Boolean
+  HiLink melFunction	Function
+  HiLink melIdentifier	Identifier
+  HiLink melStatement	Statement
+  HiLink melConditional Conditional
+  HiLink melRepeat	Repeat
+  HiLink melLabel	Label
+  HiLink melOperator	Operator
+  HiLink melKeyword	Keyword
+  HiLink melException	Exception
+  HiLink melInclude	Include
+  HiLink melType	Type
+  HiLink melStorageClass StorageClass
+  HiLink melDebug	Debug
+  HiLink melTodo	Todo
+  HiLink melCharSpecial SpecialChar
+  HiLink melString	String
+  HiLink melInteger	Number
+  HiLink melFloat	Float
+  HiLink melMatrixVector Float
+  HiLink melComment	Comment
+  HiLink melError	Error
+  HiLink melSpaceError	melError
+  HiLink melCharError	melError
+  HiLink melParenError	melError
+  HiLink melInParen	melError
+  HiLink melCommentError melError
+
+  delcommand HiLink
+endif
+
+let b:current_syntax = "mel"
--- /dev/null
+++ b/lib/vimfiles/syntax/messages.vim
@@ -1,0 +1,59 @@
+" Vim syntax file
+" Language:         /var/log/messages file
+" Maintainer:       Yakov Lerner <iler.ml@gmail.com>
+" Latest Revision:  2006-06-19
+
+if exists("b:current_syntax")
+  finish
+endif
+
+let s:cpo_save = &cpo
+set cpo&vim
+
+syn match   messagesBegin       display '^' nextgroup=messagesDate
+
+syn match   messagesDate        contained display '\a\a\a [ 0-9]\d *'
+                                \ nextgroup=messagesHour
+
+syn match   messagesHour        contained display '\d\d:\d\d:\d\d\s*'
+                                \ nextgroup=messagesHost
+
+syn match   messagesHost        contained display '\S*\s*'
+                                \ nextgroup=messagesLabel
+
+syn match   messagesLabel       contained display '\s*[^:]*:\s*'
+                                \ nextgroup=messagesText contains=messagesKernel,messagesPID
+
+syn match   messagesPID         contained display '\[\zs\d\+\ze\]'
+
+syn match   messagesKernel      contained display 'kernel:'
+
+
+syn match   messagesIP          '\d\+\.\d\+\.\d\+\.\d\+'
+
+syn match   messagesURL         '\w\+://\S\+'
+
+syn match   messagesText        contained display '.*'
+                                \ contains=messagesNumber,messagesIP,messagesURL,messagesError
+
+syn match   messagesNumber      contained '0x[0-9a-fA-F]*\|\[<[0-9a-f]\+>\]\|\<\d[0-9a-fA-F]*'
+
+syn match   messagesError       contained '\c.*\<\(FATAL\|ERROR\|ERRORS\|FAILED\|FAILURE\).*'
+
+
+hi def link messagesDate        Constant
+hi def link messagesHour        Type
+hi def link messagesHost        Identifier
+hi def link messagesLabel       Operator
+hi def link messagesPID         Constant
+hi def link messagesKernel      Special
+hi def link messagesError       ErrorMsg
+hi def link messagesIP          Constant
+hi def link messagesURL         Underlined
+hi def link messagesText        Normal
+hi def link messagesNumber      Number
+
+let b:current_syntax = "messages"
+
+let &cpo = s:cpo_save
+unlet s:cpo_save
--- /dev/null
+++ b/lib/vimfiles/syntax/mf.vim
@@ -1,0 +1,197 @@
+" Vim syntax file
+" Language:	Metafont
+" Maintainer:	Andreas Scherer <andreas.scherer@pobox.com>
+" Last Change:	April 25, 2001
+
+" For version 5.x: Clear all syntax items
+" For version 6.x: Quit when a syntax file was already loaded
+if version < 600
+  syn clear
+elseif exists("b:current_syntax")
+  finish
+endif
+
+" Metafont 'primitives' as defined in chapter 25 of 'The METAFONTbook'
+" Page 210: 'boolean expressions'
+syn keyword mfBoolExp true false known unknown odd charexists not and or
+
+" Page 210: 'numeric expression'
+syn keyword mfNumExp normaldeviate length ASCII oct hex angle turningnumber
+syn keyword mfNumExp totalweight directiontime xpart ypart xxpart xypart
+syn keyword mfNumExp yxpart yypart sqrt sind cosd mlog mexp floor
+syn keyword mfNumExp uniformdeviate
+
+" Page 211: 'internal quantities'
+syn keyword mfInternal tracingtitles tracingequations tracingcapsules
+syn keyword mfInternal tracingchoices tracingspecs tracingpens
+syn keyword mfInternal tracingcommands tracingrestores tracingmacros
+syn keyword mfInternal tracingedges tracingoutput tracingonline tracingstats
+syn keyword mfInternal pausing showstopping fontmaking proofing
+syn keyword mfInternal turningcheck warningcheck smoothing autorounding
+syn keyword mfInternal granularity fillin year month day time
+syn keyword mfInternal charcode charext charwd charht chardp charic
+syn keyword mfInternal chardx chardy designsize hppp vppp xoffset yoffset
+syn keyword mfInternal boundarychar
+
+" Page 212: 'pair expressions'
+syn keyword mfPairExp point of precontrol postcontrol penoffset rotated
+syn keyword mfPairExp scaled shifted slanted transformed xscaled yscaled
+syn keyword mfPairExp zscaled
+
+" Page 213: 'path expressions'
+syn keyword mfPathExp makepath reverse subpath curl tension atleast
+syn keyword mfPathExp controls cycle
+
+" Page 214: 'pen expressions'
+syn keyword mfPenExp nullpen pencircle makepen
+
+" Page 214: 'picutre expressions'
+syn keyword mfPicExp nullpicture
+
+" Page 214: 'string expressions'
+syn keyword mfStringExp jobname readstring str char decimal substring
+
+" Page 217: 'commands and statements'
+syn keyword mfCommand end dump save interim newinternal randomseed let
+syn keyword mfCommand delimiters outer everyjob show showvariable showtoken
+syn keyword mfCommand showdependencies showstats message errmessage errhelp
+syn keyword mfCommand batchmode nonstopmode scrollmode errorstopmode
+syn keyword mfCommand addto also contour doublepath withpen withweight cull
+syn keyword mfCommand keeping dropping display inwindow openwindow at from to
+syn keyword mfCommand shipout special numspecial
+
+" Page 56: 'types'
+syn keyword mfType boolean numeric pair path pen picture string transform
+
+" Page 155: 'grouping'
+syn keyword mfStatement begingroup endgroup
+
+" Page 165: 'definitions'
+syn keyword mfDefinition enddef def expr suffix text primary secondary
+syn keyword mfDefinition tertiary vardef primarydef secondarydef tertiarydef
+
+" Page 169: 'conditions and loops'
+syn keyword mfCondition if fi else elseif endfor for forsuffixes forever
+syn keyword mfCondition step until exitif
+
+" Other primitives listed in the index
+syn keyword mfPrimitive charlist endinput expandafter extensible
+syn keyword mfPrimitive fontdimen headerbyte inner input intersectiontimes
+syn keyword mfPrimitive kern ligtable quote scantokens skipto
+
+" Keywords defined by plain.mf (defined on pp.262-278)
+if !exists("plain_mf_macros")
+  let plain_mf_macros = 1 " Set this to '0' if your source gets too colourful
+			  " metapost.vim does so to turn off Metafont macros
+endif
+if plain_mf_macros
+  syn keyword mfMacro abs addto_currentpicture aspect_ratio base_name
+  syn keyword mfMacro base_version beginchar blacker blankpicture bot bye byte
+  syn keyword mfMacro capsule_def ceiling change_width clear_pen_memory clearit
+  syn keyword mfMacro clearpen clearxy counterclockwise culldraw cullit
+  syn keyword mfMacro currentpen currentpen_path currentpicture
+  syn keyword mfMacro currenttransform currentwindow cutdraw cutoff d decr
+  syn keyword mfMacro define_blacker_pixels define_corrected_pixels
+  syn keyword mfMacro define_good_x_pixels define_good_y_pixels
+  syn keyword mfMacro define_horizontal_corrected_pixels define_pixels
+  syn keyword mfMacro define_whole_blacker_pixels define_whole_pixels
+  syn keyword mfMacro define_whole_vertical_blacker_pixels
+  syn keyword mfMacro define_whole_vertical_pixels dir direction directionpoint
+  syn keyword mfMacro displaying ditto div dotprod down downto draw drawdot
+  syn keyword mfMacro endchar eps epsilon extra_beginchar extra_endchar
+  syn keyword mfMacro extra_setup erase exitunless fill filldraw fix_units flex
+  syn keyword mfMacro font_coding_scheme font_extra_space font_identifier
+  syn keyword mfMacro font_normal_shrink font_normal_space font_normal_stretch
+  syn keyword mfMacro font_quad font_setup font_size font_slant font_x_height
+  syn keyword mfMacro fullcircle generate gfcorners gobble gobbled grayfont h
+  syn keyword mfMacro halfcircle hide hround identity image_rules incr infinity
+  syn keyword mfMacro interact interpath intersectionpoint inverse italcorr
+  syn keyword mfMacro join_radius killtext labelfont labels left lft localfont
+  syn keyword mfMacro loggingall lowres lowres_fix mag magstep makebox makegrid
+  syn keyword mfMacro makelabel maketicks max min mod mode mode_def mode_name
+  syn keyword mfMacro mode_setup nodisplays notransforms number_of_modes numtok
+  syn keyword mfMacro o_correction openit origin pen_bot pen_lft pen_rt pen_top
+  syn keyword mfMacro penlabels penpos penrazor penspeck pensquare penstroke
+  syn keyword mfMacro pickup pixels_per_inch proof proofoffset proofrule
+  syn keyword mfMacro proofrulethickness quartercircle range reflectedabout
+  syn keyword mfMacro relax right rotatedabout rotatedaround round rt rulepen
+  syn keyword mfMacro savepen screenchars screen_rows screen_cols screenrule
+  syn keyword mfMacro screenstrokes shipit showit slantfont smode smoke softjoin
+  syn keyword mfMacro solve stop superellipse takepower tensepath titlefont
+  syn keyword mfMacro tolerance top tracingall tracingnone undraw undrawdot
+  syn keyword mfMacro unfill unfilldraw unitpixel unitsquare unitvector up upto
+  syn keyword mfMacro vround w whatever
+endif
+
+" Some other basic macro names, e.g., from cmbase, logo, etc.
+if !exists("other_mf_macros")
+  let other_mf_macros = 1 " Set this to '0' if your code gets too colourful
+			  " metapost.vim does so to turn off Metafont macros
+endif
+if other_mf_macros
+  syn keyword mfMacro beginlogochar
+endif
+
+" Numeric tokens
+syn match mfNumeric	"[-]\=\d\+"
+syn match mfNumeric	"[-]\=\.\d\+"
+syn match mfNumeric	"[-]\=\d\+\.\d\+"
+
+" Metafont lengths
+syn match mfLength	"\<\(bp\|cc\|cm\|dd\|in\|mm\|pc\|pt\)\>"
+syn match mfLength	"\<[-]\=\d\+\(bp\|cc\|cm\|dd\|in\|mm\|pc\|pt\)\#\=\>"
+syn match mfLength	"\<[-]\=\.\d\+\(bp\|cc\|cm\|dd\|in\|mm\|pc\|pt\)\#\=\>"
+syn match mfLength	"\<[-]\=\d\+\.\d\+\(bp\|cc\|cm\|dd\|in\|mm\|pc\|pt\)\#\=\>"
+
+" Metafont coordinates and points
+syn match mfCoord	"\<[xy]\d\+\>"
+syn match mfPoint	"\<z\d\+\>"
+
+" String constants
+syn region mfString	start=+"+ end=+"+
+
+" Comments:
+syn match mfComment	"%.*$"
+
+" synchronizing
+syn sync maxlines=50
+
+" Define the default highlighting
+" For version 5.7 and earlier: only when not done already
+" For version 5.8 and later: only when an item doesn't have highlighting yet
+if version >= 508 || !exists("did_mf_syntax_inits")
+  if version < 508
+    let did_mf_syntax_inits = 1
+    command -nargs=+ HiLink hi link <args>
+  else
+    command -nargs=+ HiLink hi def link <args>
+  endif
+
+  HiLink mfBoolExp	Statement
+  HiLink mfNumExp	Statement
+  HiLink mfInternal	Identifier
+  HiLink mfPairExp	Statement
+  HiLink mfPathExp	Statement
+  HiLink mfPenExp	Statement
+  HiLink mfPicExp	Statement
+  HiLink mfStringExp	Statement
+  HiLink mfCommand	Statement
+  HiLink mfType	Type
+  HiLink mfStatement	Statement
+  HiLink mfDefinition	Statement
+  HiLink mfCondition	Conditional
+  HiLink mfPrimitive	Statement
+  HiLink mfMacro	Macro
+  HiLink mfCoord	Identifier
+  HiLink mfPoint	Identifier
+  HiLink mfNumeric	Number
+  HiLink mfLength	Number
+  HiLink mfComment	Comment
+  HiLink mfString	String
+
+  delcommand HiLink
+endif
+
+let b:current_syntax = "mf"
+
+" vim: ts=8
--- /dev/null
+++ b/lib/vimfiles/syntax/mgl.vim
@@ -1,0 +1,128 @@
+" Vim syntax file
+" Language:	MGL
+" Version: 1.0
+" Last Change:	2006 Feb 21
+" Maintainer:  Gero Kuhlmann <gero@gkminix.han.de>
+"
+" $Id: mgl.vim,v 1.1 2006/02/21 22:08:20 vimboss Exp $
+"
+if version < 600
+  syntax clear
+elseif exists("b:current_syntax")
+  finish
+endif
+
+
+syn sync lines=250
+
+syn keyword mglBoolean		true false
+syn keyword mglConditional	if else then
+syn keyword mglConstant		nil
+syn keyword mglPredefined	maxint
+syn keyword mglLabel		case goto label
+syn keyword mglOperator		to downto in of with
+syn keyword mglOperator		and not or xor div mod
+syn keyword mglRepeat		do for repeat while to until
+syn keyword mglStatement	procedure function break continue return restart
+syn keyword mglStatement	program begin end const var type
+syn keyword mglStruct		record
+syn keyword mglType		integer string char boolean char ipaddr array
+
+
+" String
+if !exists("mgl_one_line_string")
+  syn region  mglString matchgroup=mglString start=+'+ end=+'+ contains=mglStringEscape
+  syn region  mglString matchgroup=mglString start=+"+ end=+"+ contains=mglStringEscapeGPC
+else
+  "wrong strings
+  syn region  mglStringError matchgroup=mglStringError start=+'+ end=+'+ end=+$+ contains=mglStringEscape
+  syn region  mglStringError matchgroup=mglStringError start=+"+ end=+"+ end=+$+ contains=mglStringEscapeGPC
+  "right strings
+  syn region  mglString matchgroup=mglString start=+'+ end=+'+ oneline contains=mglStringEscape
+  syn region  mglString matchgroup=mglString start=+"+ end=+"+ oneline contains=mglStringEscapeGPC
+end
+syn match   mglStringEscape	contained "''"
+syn match   mglStringEscapeGPC	contained '""'
+
+
+if exists("mgl_symbol_operator")
+  syn match   mglSymbolOperator		"[+\-/*=\%]"
+  syn match   mglSymbolOperator		"[<>]=\="
+  syn match   mglSymbolOperator		"<>"
+  syn match   mglSymbolOperator		":="
+  syn match   mglSymbolOperator		"[()]"
+  syn match   mglSymbolOperator		"\.\."
+  syn match   mglMatrixDelimiter	"(."
+  syn match   mglMatrixDelimiter	".)"
+  syn match   mglMatrixDelimiter	"[][]"
+endif
+
+syn match  mglNumber	"-\=\<\d\+\>"
+syn match  mglHexNumber	"\$[0-9a-fA-F]\+\>"
+syn match  mglCharacter	"\#[0-9]\+\>"
+syn match  mglIpAddr	"[0-9]\+\.[0-9]\+\.[0-9]\+\.[0-9]\+\>"
+
+syn region mglComment	start="(\*"  end="\*)"
+syn region mglComment	start="{"  end="}"
+syn region mglComment	start="//"  end="$"
+
+if !exists("mgl_no_functions")
+  syn keyword mglFunction	dispose new
+  syn keyword mglFunction	get load print select
+  syn keyword mglFunction	odd pred succ
+  syn keyword mglFunction	chr ord abs sqr
+  syn keyword mglFunction	exit
+  syn keyword mglOperator	at timeout
+endif
+
+
+syn region mglPreProc	start="(\*\$"  end="\*)"
+syn region mglPreProc	start="{\$"  end="}"
+
+syn keyword mglException	try except raise
+syn keyword mglPredefined	exception
+
+
+" Define the default highlighting.
+" For version 5.7 and earlier: only when not done already
+" For version 5.8 and later: only when an item doesn't have highlighting yet
+if version >= 508 || !exists("did_mgl_syn_inits")
+  if version < 508
+    let did_mgl_syn_inits = 1
+    command -nargs=+ HiLink hi link <args>
+  else
+    command -nargs=+ HiLink hi def link <args>
+  endif
+
+  HiLink mglBoolean		Boolean
+  HiLink mglComment		Comment
+  HiLink mglConditional		Conditional
+  HiLink mglConstant		Constant
+  HiLink mglException		Exception
+  HiLink mglFunction		Function
+  HiLink mglLabel		Label
+  HiLink mglMatrixDelimiter	Identifier
+  HiLink mglNumber		Number
+  HiLink mglHexNumber		Number
+  HiLink mglCharacter		Number
+  HiLink mglIpAddr		Number
+  HiLink mglOperator		Operator
+  HiLink mglPredefined		mglFunction
+  HiLink mglPreProc		PreProc
+  HiLink mglRepeat		Repeat
+  HiLink mglStatement		Statement
+  HiLink mglString		String
+  HiLink mglStringEscape	Special
+  HiLink mglStringEscapeGPC	Special
+  HiLink mglStringError		Error
+  HiLink mglStruct		mglStatement
+  HiLink mglSymbolOperator	mglOperator
+  HiLink mglType		Type
+
+  delcommand HiLink
+endif
+
+
+let b:current_syntax = "mgl"
+
+" vim: ts=8 sw=2
--- /dev/null
+++ b/lib/vimfiles/syntax/mgp.vim
@@ -1,0 +1,83 @@
+" Vim syntax file
+" Language:     mgp - MaGic Point
+" Maintainer:   Gerfried Fuchs <alfie@ist.org>
+" Filenames:    *.mgp
+" Last Change:  25 Apr 2001
+" URL:		http://alfie.ist.org/vim/syntax/mgp.vim
+"
+" Comments are very welcome - but please make sure that you are commenting on
+" the latest version of this file.
+" SPAM is _NOT_ welcome - be ready to be reported!
+
+
+" For version 5.x: Clear all syntax items
+" For version 6.x: Quit when a syntax file was already loaded
+if version < 600
+  syn clear
+elseif exists("b:current_syntax")
+  finish
+endif
+
+
+syn match mgpLineSkip "\\$"
+
+" all the commands that are currently recognized
+syn keyword mgpCommand contained size fore back bgrad left leftfill center
+syn keyword mgpCommand contained right shrink lcutin rcutin cont xfont vfont
+syn keyword mgpCommand contained tfont tmfont tfont0 bar image newimage
+syn keyword mgpCommand contained prefix icon bimage default tab vgap hgap
+syn keyword mgpCommand contained pause mark again system filter endfilter
+syn keyword mgpCommand contained vfcap tfdir deffont font embed endembed
+syn keyword mgpCommand contained noop pcache include
+
+" charset is not yet supported :-)
+" syn keyword mgpCommand contained charset
+
+syn region mgpFile     contained start=+"+ skip=+\\\\\|\\"+ end=+"+
+syn match mgpValue     contained "\d\+"
+syn match mgpSize      contained "\d\+x\d\+"
+syn match mgpLine      +^%.*$+ contains=mgpCommand,mgpFile,mgpSize,mgpValue
+
+" Comments
+syn match mgpPercent   +^%%.*$+
+syn match mgpHash      +^#.*$+
+
+" these only work alone
+syn match mgpPage      +^%page$+
+syn match mgpNoDefault +^%nodefault$+
+
+
+" Define the default highlighting.
+" For version 5.7 and earlier: only when not done already
+" For version 5.8 and later: only when an item doesn't have highlighting yet
+if version >= 508 || !exists("did_mgp_syn_inits")
+  let did_mgp_syn_inits = 1
+  if version < 508
+    let did_mgp_syn_inits = 1
+    command -nargs=+ HiLink hi link <args>
+  else
+    command -nargs=+ HiLink hi def link <args>
+  endif
+
+  HiLink mgpLineSkip	Special
+
+  HiLink mgpHash	mgpComment
+  HiLink mgpPercent	mgpComment
+  HiLink mgpComment	Comment
+
+  HiLink mgpCommand	Identifier
+
+  HiLink mgpLine	Type
+
+  HiLink mgpFile	String
+  HiLink mgpSize	Number
+  HiLink mgpValue	Number
+
+  HiLink mgpPage	mgpDefine
+  HiLink mgpNoDefault	mgpDefine
+  HiLink mgpDefine	Define
+
+  delcommand HiLink
+endif
+
+let b:current_syntax = "mgp"
--- /dev/null
+++ b/lib/vimfiles/syntax/mib.vim
@@ -1,0 +1,77 @@
+" Vim syntax file
+" Language:	Vim syntax file for SNMPv1 and SNMPv2 MIB and SMI files
+" Author:	David Pascoe <pascoedj@spamcop.net>
+" Written:	Wed Jan 28 14:37:23 GMT--8:00 1998
+" Last Changed:	Thu Feb 27 10:18:16 WST 2003
+
+" For version 5.x: Clear all syntax items
+" For version 6.x: Quit when a syntax file was already loaded
+if version < 600
+  syntax clear
+elseif exists("b:current_syntax")
+  finish
+endif
+
+if version >= 600
+  setlocal iskeyword=@,48-57,_,128-167,224-235,-,:,=
+else
+  set iskeyword=@,48-57,_,128-167,224-235,-,:,=
+endif
+
+syn keyword mibImplicit ACCESS ANY AUGMENTS BEGIN BIT BITS BOOLEAN CHOICE
+syn keyword mibImplicit COMPONENTS CONTACT-INFO DEFINITIONS DEFVAL
+syn keyword mibImplicit DESCRIPTION DISPLAY-HINT END ENTERPRISE EXTERNAL FALSE
+syn keyword mibImplicit FROM GROUP IMPLICIT IMPLIED IMPORTS INDEX
+syn keyword mibImplicit LAST-UPDATED MANDATORY-GROUPS MAX-ACCESS
+syn keyword mibImplicit MIN-ACCESS MODULE MODULE-COMPLIANCE MODULE-IDENTITY
+syn keyword mibImplicit NOTIFICATION-GROUP NOTIFICATION-TYPE NOTIFICATIONS
+syn keyword mibImplicit NULL OBJECT-GROUP OBJECT-IDENTITY OBJECT-TYPE
+syn keyword mibImplicit OBJECTS OF OPTIONAL ORGANIZATION REFERENCE
+syn keyword mibImplicit REVISION SEQUENCE SET SIZE STATUS SYNTAX
+syn keyword mibImplicit TEXTUAL-CONVENTION TRAP-TYPE TRUE UNITS VARIABLES
+syn keyword mibImplicit WRITE-SYNTAX ::=
+syn keyword mibValue accessible-for-notify current DisplayString
+syn keyword mibValue deprecated mandatory not-accessible obsolete optional
+syn keyword mibValue read-create read-only read-write write-only INTEGER
+syn keyword mibValue Counter Gauge IpAddress OCTET STRING experimental mib-2
+syn keyword mibValue TimeTicks RowStatus TruthValue UInteger32 snmpModules
+syn keyword mibValue Integer32 Counter32 TestAndIncr TimeStamp InstancePointer
+syn keyword mibValue OBJECT IDENTIFIER Gauge32 AutonomousType Counter64
+syn keyword mibValue PhysAddress TimeInterval MacAddress StorageType RowPointer
+syn keyword mibValue TDomain TAddress ifIndex
+
+" Epilogue SMI extensions
+syn keyword mibEpilogue FORCE-INCLUDE EXCLUDE cookie get-function set-function
+syn keyword mibEpilogue test-function get-function-async set-function-async
+syn keyword mibEpilogue test-function-async next-function next-function-async
+syn keyword mibEpilogue leaf-name
+syn keyword mibEpilogue DEFAULT contained
+
+syn match  mibComment		"\ *--.*$"
+syn match  mibNumber		"\<['0-9a-fA-FhH]*\>"
+syn region mibDescription start="\"" end="\"" contains=DEFAULT
+
+" Define the default highlighting.
+" For version 5.7 and earlier: only when not done already
+" For version 5.8 and later: only when an item doesn't have highlighting yet
+if version >= 508 || !exists("did_mib_syn_inits")
+  if version < 508
+    let did_mib_syn_inits = 1
+    command -nargs=+ HiLink hi link <args>
+  else
+    command -nargs=+ HiLink hi def link <args>
+  endif
+
+  HiLink mibImplicit	     Statement
+  HiLink mibComment	     Comment
+  HiLink mibConstants	     String
+  HiLink mibNumber	     Number
+  HiLink mibDescription      Identifier
+  HiLink mibEpilogue	     SpecialChar
+  HiLink mibValue	     Structure
+  delcommand HiLink
+endif
+
+let b:current_syntax = "mib"
+
+" vim: ts=8
--- /dev/null
+++ b/lib/vimfiles/syntax/mma.vim
@@ -1,0 +1,325 @@
+" Vim syntax file
+" Language:     Mathematica
+" Maintainer:   steve layland <layland@wolfram.com>
+" Last Change:  Thu May 19 21:36:04 CDT 2005
+" Source:       http://members.wri.com/layland/vim/syntax/mma.vim
+"               http://vim.sourceforge.net/scripts/script.php?script_id=1273
+" Id:           $Id: mma.vim,v 1.4 2006/04/14 20:40:38 vimboss Exp $
+" NOTE:
+" 
+" Empty .m files will automatically be presumed as Matlab files
+" unless you have the following in your .vimrc:
+"
+"       let filetype_m="mma"
+"
+" I also recommend setting the default 'Comment' hilighting to something
+" other than the color used for 'Function', since both are plentiful in
+" most mathematica files, and they are often the same color (when using 
+" background=dark).
+"
+" Credits:
+" o  Original Mathematica syntax version written by
+"    Wolfgang Waltenberger <wwalten@ben.tuwien.ac.at>
+" o  Some ideas like the CommentStar,CommentTitle were adapted
+"    from the Java vim syntax file by Claudio Fleiner.  Thanks!
+" o  Everything else written by steve <layland@wolfram.com>
+"
+" Bugs: 
+" o  Vim 6.1 didn't really have support for character classes 
+"    of other named character classes.  For example, [\a\d]
+"    didn't work.  Therefore, a lot of this code uses explicit
+"    character classes instead: [0-9a-zA-Z] 
+"
+" TODO:
+"   folding
+"   fix nesting
+"   finish populating popular symbols
+
+if version < 600
+	syntax clear
+elseif exists("b:current_syntax")
+    finish
+endif
+
+" Group Definitions:
+syntax cluster mmaNotes contains=mmaTodo,mmaFixme
+syntax cluster mmaComments contains=mmaComment,mmaFunctionComment,mmaItem,mmaFunctionTitle,mmaCommentStar
+syntax cluster mmaCommentStrings contains=mmaLooseQuote,mmaCommentString,mmaUnicode
+syntax cluster mmaStrings contains=@mmaCommentStrings,mmaString
+syntax cluster mmaTop contains=mmaOperator,mmaGenericFunction,mmaPureFunction,mmaVariable
+
+" Predefined Constants:
+"   to list all predefined Symbols would be too insane...
+"   it's probably smarter to define a select few, and get the rest from
+"   context if absolutely necessary.
+"   TODO - populate this with other often used Symbols
+
+" standard fixed symbols:
+syntax keyword mmaVariable True False None Automatic All Null C General
+
+" mathematical constants:
+syntax keyword mmaVariable Pi I E Infinity ComplexInfinity Indeterminate GoldenRatio EulerGamma Degree Catalan Khinchin Glaisher 
+
+" stream data / atomic heads:
+syntax keyword mmaVariable Byte Character Expression Number Real String Word EndOfFile Integer Symbol
+
+" sets:
+syntax keyword mmaVariable Integers Complexes Reals Booleans Rationals
+
+" character classes:
+syntax keyword mmaPattern DigitCharacter LetterCharacter WhitespaceCharacter WordCharacter EndOfString StartOfString EndOfLine StartOfLine WordBoundary
+
+" SelectionMove directions/units:
+syntax keyword mmaVariable Next Previous After Before Character Word Expression TextLine CellContents Cell CellGroup EvaluationCell ButtonCell GeneratedCell Notebook
+syntax keyword mmaVariable CellTags CellStyle CellLabel
+
+" TableForm positions:
+syntax keyword mmaVariable Above Below Left Right
+
+" colors:
+syntax keyword mmaVariable Black Blue Brown Cyan Gray Green Magenta Orange Pink Purple Red White Yellow
+
+" function attributes
+syntax keyword mmaVariable Protected Listable OneIdentity Orderless Flat Constant NumericFunction Locked ReadProtected HoldFirst HoldRest HoldAll HoldAllComplete SequenceHold NHoldFirst NHoldRest NHoldAll Temporary Stub 
+
+" Comment Sections:
+"   this:
+"   :that:
+syntax match mmaItem "\%(^[( |*\t]*\)\@<=\%(:\+\|\w\)\w\+\%( \w\+\)\{0,3}:" contained contains=@mmaNotes
+
+" Comment Keywords:
+syntax keyword mmaTodo TODO NOTE HEY contained
+syntax match mmaTodo "X\{3,}" contained
+syntax keyword mmaFixme FIX[ME] FIXTHIS BROKEN contained
+syntax match mmaFixme "BUG\%( *\#\=[0-9]\+\)\=" contained
+" yay pirates...
+syntax match mmaFixme "\%(Y\=A\+R\+G\+\|GRR\+\|CR\+A\+P\+\)\%(!\+\)\=" contained
+
+" EmPHAsis:
+" this unnecessary, but whatever :)
+syntax match mmaemPHAsis "\%(^\|\s\)\([_/]\)[a-zA-Z0-9]\+\%([- \t':]\+[a-zA-Z0-9]\+\)*\1\%(\s\|$\)" contained contains=mmaemPHAsis
+syntax match mmaemPHAsis "\%(^\|\s\)(\@<!\*[a-zA-Z0-9]\+\%([- \t':]\+[a-zA-Z0-9]\+\)*)\@!\*\%(\s\|$\)" contained contains=mmaemPHAsis
+
+" Regular Comments:
+"   (* *)
+"   allow nesting (* (* *) *) even though the frontend
+"   won't always like it.
+syntax region mmaComment start=+(\*+ end=+\*)+ skipempty contains=@mmaNotes,mmaItem,@mmaCommentStrings,mmaemPHAsis,mmaComment
+
+" Function Comments:
+"   just like a normal comment except the first sentance is Special ala Java
+"   (** *)
+"   TODO - fix this for nesting, or not...
+syntax region mmaFunctionComment start="(\*\*\+" end="\*\+)" contains=@mmaNotes,mmaItem,mmaFunctionTitle,@mmaCommentStrings,mmaemPHAsis,mmaComment
+syntax region mmaFunctionTitle contained matchgroup=mmaFunctionComment start="\%((\*\*[ *]*\)" matchgroup=mmaFunctionTitle keepend end=".[.!-]\=\s*$" end="[.!-][ \t\r<&]"me=e-1 end="\%(\*\+)\)\@=" contained contains=@mmaNotes,mmaItem,mmaCommentStar
+
+" catch remaining (**********)'s
+syntax match mmaComment "(\*\*\+)"
+" catch preceding *
+syntax match mmaCommentStar "^\s*\*\+" contained
+
+" Variables:
+"   Dollar sign variables
+syntax match mmaVariable "\$\a\+[0-9a-zA-Z$]*"
+
+"   Preceding and Following Contexts
+syntax match mmaVariable "`[a-zA-Z$]\+[0-9a-zA-Z$]*" contains=mmaVariable
+syntax match mmaVariable "[a-zA-Z$]\+[0-9a-zA-Z$]*`" contains=mmaVariable
+
+" Strings:
+"   "string"
+"   'string' is not accepted (until literal strings are supported!)
+syntax region mmaString start=+\\\@<!"+ skip=+\\\@<!\\\%(\\\\\)*"+ end=+"+
+syntax region mmaCommentString oneline start=+\\\@<!"+ skip=+\\\@<!\\\%(\\\\\)*"+ end=+"+ contained
+
+
+" Patterns:
+"   Each pattern marker below can be Blank[] (_), BlankSequence[] (__)
+"   or BlankNullSequence[] (___).  Most examples below can also be 
+"   combined, for example Pattern tests with Default values.
+"   
+"   _Head                   Anonymous patterns
+"   name_Head 
+"   name:(_Head|_Head2)     Named patterns
+"    
+"   _Head : val
+"   name:_Head:val          Default values
+"
+"   _Head?testQ, 
+"   _Head?(test[#]&)        Pattern tests
+"
+"   name_Head/;test[name]   Conditionals
+"   
+"   _Head:.                 Predefined Default
+"
+"   .. ...                  Pattern Repeat
+   
+syntax match mmaPatternError "\%(_\{4,}\|)\s*&\s*)\@!\)" contained
+
+"pattern name:
+syntax match mmaPattern "[A-Za-z0-9`]\+\s*:\+[=>]\@!" contains=mmaOperator
+"pattern default:
+syntax match mmaPattern ": *[^ ,]\+[\], ]\@=" contains=@mmaCommentStrings,@mmaTop,mmaOperator
+"pattern head/test:
+syntax match mmaPattern "[A-Za-z0-9`]*_\+\%(\a\+\)\=\%(?([^)]\+)\|?[^\]},]\+\)\=" contains=@mmaTop,@mmaCommentStrings,mmaPatternError
+
+" Operators:
+"   /: ^= ^:=   UpValue
+"   /;          Conditional
+"   := =        DownValue
+"   == === ||
+"   != =!= &&   Logic
+"   >= <= < >
+"   += -= *=
+"   /= ++ --    Math
+"   ^* 
+"   -> :>       Rules
+"   @@ @@@      Apply
+"   /@ //@      Map
+"   /. //.      Replace
+"   // @        Function application
+"   <> ~~       String/Pattern join
+"   ~           infix operator
+"   . :         Pattern operators
+syntax match mmaOperator "\%(@\{1,3}\|//[.@]\=\)"
+syntax match mmaOperator "\%(/[;:@.]\=\|\^\=:\==\)"
+syntax match mmaOperator "\%([-:=]\=>\|<=\=\)"
+"syntax match mmaOperator "\%(++\=\|--\=\|[/+-*]=\|[^*]\)"
+syntax match mmaOperator "[*+=^.:?-]"
+syntax match mmaOperator "\%(\~\~\=\)"
+syntax match mmaOperator "\%(=\{2,3}\|=\=!=\|||\=\|&&\|!\)" contains=ALLBUT,mmaPureFunction
+
+" Symbol Tags:
+"   "SymbolName::item"
+"syntax match mmaSymbol "`\=[a-zA-Z$]\+[0-9a-zA-Z$]*\%(`\%([a-zA-Z$]\+[0-9a-zA-Z$]*\)\=\)*" contained
+syntax match mmaMessage "`\=\([a-zA-Z$]\+[0-9a-zA-Z$]*\)\%(`\%([a-zA-Z$]\+[0-9a-zA-Z$]*\)\=\)*::\a\+" contains=mmaMessageType
+syntax match mmaMessageType "::\a\+"hs=s+2 contained
+
+" Pure Functions:
+syntax match mmaPureFunction "#\%(#\|\d\+\)\="
+syntax match mmaPureFunction "&"
+
+" Named Functions:
+" Since everything is pretty much a function, get this straight 
+" from context
+syntax match mmaGenericFunction "[A-Za-z0-9`]\+\s*\%([@[]\|/:\|/\=/@\)\@=" contains=mmaOperator
+syntax match mmaGenericFunction "\~\s*[^~]\+\s*\~"hs=s+1,he=e-1 contains=mmaOperator,mmaBoring
+syntax match mmaGenericFunction "//\s*[A-Za-z0-9`]\+"hs=s+2 contains=mmaOperator
+
+" Numbers:
+syntax match mmaNumber "\<\%(\d\+\.\=\d*\|\d*\.\=\d\+\)\>"
+syntax match mmaNumber "`\d\+\%(\d\@!\.\|\>\)"
+
+" Special Characters:
+"   \[Name]     named character
+"   \ooo        octal
+"   \.xx        2 digit hex
+"   \:xxxx      4 digit hex (multibyte unicode)
+syntax match mmaUnicode "\\\[\w\+\d*\]"
+syntax match mmaUnicode "\\\%(\x\{3}\|\.\x\{2}\|:\x\{4}\)"
+
+" Syntax Errors:
+syntax match mmaError "\*)" containedin=ALLBUT,@mmaComments,@mmaStrings
+syntax match mmaError "\%([/]{3,}\|[&:|+*?~-]\{3,}\|[.=]\{4,}\|_\@<=\.\{2,}\|`\{2,}\)" containedin=ALLBUT,@mmaComments,@mmaStrings
+
+" Punctuation:
+" things that shouldn't really be highlighted, or highlighted 
+" in they're own group if you _really_ want. :)
+"  ( ) { }
+" TODO - use Delimiter group?
+syntax match mmaBoring "[(){}]" contained
+
+" ------------------------------------
+"    future explorations...
+" ------------------------------------
+" Function Arguments:
+"   anything between brackets []
+"   (fold)
+"syntax region mmaArgument start="\[" end="\]" containedin=ALLBUT,@mmaComments,@mmaStrings transparent fold
+
+" Lists:
+"   (fold)
+"syntax region mmaLists start="{" end="}" containedin=ALLBUT,@mmaComments,@mmaStrings transparent fold
+
+" Regions:
+"   (fold)
+"syntax region mmaRegion start="(\*\+[^<]*<!--[^>]*\*\+)" end="--> \*)" containedin=ALLBUT,@mmaStrings transparent fold keepend
+
+" show fold text
+set commentstring='(*%s*)'
+"set foldtext=MmaFoldText()
+
+"function MmaFoldText()
+"    let line = getline(v:foldstart)
+"    
+"    let lines = v:foldend-v:foldstart+1
+"    
+"    let sub = substitute(line, '(\*\+|\*\+)|[-*_]\+', '', 'g')
+"
+"    if match(line, '(\*') != -1
+"        let lines = lines.' line comment'
+"    else
+"        let lines = lines.' lines'
+"    endif
+"
+"    return v:folddashes.' '.lines.' '.sub
+"endf
+    
+"this is slow for computing folds, but it does so accurately
+syntax sync fromstart
+
+" but this seems to do alright for non fold syntax coloring.
+" for folding, however, it doesn't get the nesting right.
+" TODO - find sync group for multiline modules? ick...
+
+" sync multi line comments
+"syntax sync match syncComments groupthere NONE "\*)"
+"syntax sync match syncComments groupthere mmaComment "(\*"
+
+"set foldmethod=syntax
+"set foldnestmax=1
+"set foldminlines=15
+
+if version >= 508 || !exists("did_mma_syn_inits")
+	if version < 508
+		let did_mma_syn_inits = 1
+		command -nargs=+ HiLink hi link <args>
+	else
+		command -nargs=+ HiLink hi def link <args>
+	endif
+
+    " NOTE - the following links are not guaranteed to 
+    " look good under all colorschemes.  You might need to 
+    " :so $VIMRUNTIME/syntax/hitest.vim and tweak these to
+    " look good in yours
+
+
+    HiLink mmaComment           Comment
+    HiLink mmaCommentStar       Comment
+    HiLink mmaFunctionComment   Comment
+    HiLink mmaLooseQuote        Comment
+	HiLink mmaGenericFunction   Function
+	HiLink mmaVariable          Identifier
+"    HiLink mmaSymbol            Identifier
+	HiLink mmaOperator          Operator
+    HiLink mmaPatternOp         Operator
+	HiLink mmaPureFunction      Operator
+	HiLink mmaString            String
+    HiLink mmaCommentString     String
+	HiLink mmaUnicode           String
+	HiLink mmaMessage           Type
+    HiLink mmaNumber            Type
+	HiLink mmaPattern           Type
+	HiLink mmaError             Error
+	HiLink mmaFixme             Error
+    HiLink mmaPatternError      Error
+    HiLink mmaTodo              Todo
+    HiLink mmaemPHAsis          Special
+    HiLink mmaFunctionTitle     Special
+    HiLink mmaMessageType       Special
+    HiLink mmaItem              Preproc
+
+	delcommand HiLink
+endif
+
+let b:current_syntax = "mma"
--- /dev/null
+++ b/lib/vimfiles/syntax/mmix.vim
@@ -1,0 +1,162 @@
+" Vim syntax file
+" Language:	MMIX
+" Maintainer:	Dirk H�sken, <huesken@informatik.uni-tuebingen.de>
+" Last Change:	Wed Apr 24 01:18:52 CEST 2002
+" Filenames:	*.mms
+" URL: http://homepages.uni-tuebingen.de/student/dirk.huesken/vim/syntax/mmix.vim
+
+" Limitations:	Comments must start with either % or //
+"		(preferrably %, Knuth-Style)
+
+if version < 600
+  syntax clear
+elseif exists("b:current_syntax")
+  finish
+endif
+
+syn case ignore
+
+" MMIX data types
+syn keyword mmixType	byte wyde tetra octa
+
+" different literals...
+syn match decNumber		"[0-9]*"
+syn match octNumber		"0[0-7][0-7]\+"
+syn match hexNumber		"#[0-9a-fA-F]\+"
+syn region mmixString		start=+"+ skip=+\\"+ end=+"+
+syn match mmixChar		"'.'"
+
+" ...and more special MMIX stuff
+syn match mmixAt		"@"
+syn keyword mmixSegments	Data_Segment Pool_Segment Stack_Segment
+
+syn match mmixIdentifier	"[a-z_][a-z0-9_]*"
+
+" labels (for branches etc)
+syn match mmixLabel		"^[a-z0-9_:][a-z0-9_]*"
+syn match mmixLabel		"[0-9][HBF]"
+
+" pseudo-operations
+syn keyword mmixPseudo		is loc greg
+
+" comments
+syn match mmixComment		"%.*"
+syn match mmixComment		"//.*"
+syn match mmixComment		"^\*.*"
+
+
+syn keyword mmixOpcode	trap fcmp fun feql fadd fix fsub fixu
+syn keyword mmixOpcode	fmul fcmpe fune feqle fdiv fsqrt frem fint
+
+syn keyword mmixOpcode	floti flotui sfloti sflotui i
+syn keyword mmixOpcode	muli mului divi divui
+syn keyword mmixOpcode	addi addui subi subui
+syn keyword mmixOpcode	2addui 4addui 8addui 16addui
+syn keyword mmixOpcode	cmpi cmpui negi negui
+syn keyword mmixOpcode	sli slui sri srui
+syn keyword mmixOpcode	bnb bzb bpb bodb
+syn keyword mmixOpcode	bnnb bnzb bnpb bevb
+syn keyword mmixOpcode	pbnb pbzb pbpb pbodb
+syn keyword mmixOpcode	pbnnb pbnzb pbnpb pbevb
+syn keyword mmixOpcode	csni cszi cspi csodi
+syn keyword mmixOpcode	csnni csnzi csnpi csevi
+syn keyword mmixOpcode	zsni zszi zspi zsodi
+syn keyword mmixOpcode	zsnni zsnzi zsnpi zsevi
+syn keyword mmixOpcode	ldbi ldbui ldwi ldwui
+syn keyword mmixOpcode	ldti ldtui ldoi ldoui
+syn keyword mmixOpcode	ldsfi ldhti cswapi ldunci
+syn keyword mmixOpcode	ldvtsi preldi pregoi goi
+syn keyword mmixOpcode	stbi stbui stwi stwui
+syn keyword mmixOpcode	stti sttui stoi stoui
+syn keyword mmixOpcode	stsfi sthti stcoi stunci
+syn keyword mmixOpcode	syncdi presti syncidi pushgoi
+syn keyword mmixOpcode	ori orni nori xori
+syn keyword mmixOpcode	andi andni nandi nxori
+syn keyword mmixOpcode	bdifi wdifi tdifi odifi
+syn keyword mmixOpcode	muxi saddi mori mxori
+syn keyword mmixOpcode	muli mului divi divui
+
+syn keyword mmixOpcode	flot flotu sflot sflotu
+syn keyword mmixOpcode	mul mulu div divu
+syn keyword mmixOpcode	add addu sub subu
+syn keyword mmixOpcode	2addu 4addu 8addu 16addu
+syn keyword mmixOpcode	cmp cmpu neg negu
+syn keyword mmixOpcode	sl slu sr sru
+syn keyword mmixOpcode	bn bz bp bod
+syn keyword mmixOpcode	bnn bnz bnp bev
+syn keyword mmixOpcode	pbn pbz pbp pbod
+syn keyword mmixOpcode	pbnn pbnz pbnp pbev
+syn keyword mmixOpcode	csn csz csp csod
+syn keyword mmixOpcode	csnn csnz csnp csev
+syn keyword mmixOpcode	zsn zsz zsp zsod
+syn keyword mmixOpcode	zsnn zsnz zsnp zsev
+syn keyword mmixOpcode	ldb ldbu ldw ldwu
+syn keyword mmixOpcode	ldt ldtu ldo ldou
+syn keyword mmixOpcode	ldsf ldht cswap ldunc
+syn keyword mmixOpcode	ldvts preld prego go
+syn keyword mmixOpcode	stb stbu stw stwu
+syn keyword mmixOpcode	stt sttu sto stou
+syn keyword mmixOpcode	stsf stht stco stunc
+syn keyword mmixOpcode	syncd prest syncid pushgo
+syn keyword mmixOpcode	or orn nor xor
+syn keyword mmixOpcode	and andn nand nxor
+syn keyword mmixOpcode	bdif wdif tdif odif
+syn keyword mmixOpcode	mux sadd mor mxor
+
+syn keyword mmixOpcode	seth setmh setml setl inch incmh incml incl
+syn keyword mmixOpcode	orh ormh orml orl andh andmh andml andnl
+syn keyword mmixOpcode	jmp pushj geta put
+syn keyword mmixOpcode	pop resume save unsave sync swym get trip
+syn keyword mmixOpcode	set lda
+
+" switch back to being case sensitive
+syn case match
+
+" general-purpose and special-purpose registers
+syn match mmixRegister		"$[0-9]*"
+syn match mmixRegister		"r[A-Z]"
+syn keyword mmixRegister	rBB rTT rWW rXX rYY rZZ
+
+" Define the default highlighting.
+" For version 5.7 and earlier: only when not done already
+" For version 5.8 and later: only when an item doesn't have highlighting yet
+if version >= 508 || !exists("did_mmix_syntax_inits")
+  if version < 508
+    let did_mmix_syntax_inits = 1
+    command -nargs=+ HiLink hi link <args>
+  else
+    command -nargs=+ HiLink hi def link <args>
+  endif
+
+  " The default methods for highlighting.  Can be overridden later
+  HiLink mmixAt		Type
+  HiLink mmixPseudo	Type
+  HiLink mmixRegister	Special
+  HiLink mmixSegments	Type
+
+  HiLink mmixLabel	Special
+  HiLink mmixComment	Comment
+  HiLink mmixOpcode	Keyword
+
+  HiLink hexNumber	Number
+  HiLink decNumber	Number
+  HiLink octNumber	Number
+
+  HiLink mmixString	String
+  HiLink mmixChar	String
+
+  HiLink mmixType	Type
+  HiLink mmixIdentifier	Normal
+  HiLink mmixSpecialComment Comment
+
+  " My default color overrides:
+  " hi mmixSpecialComment ctermfg=red
+  "hi mmixLabel ctermfg=lightcyan
+  " hi mmixType ctermbg=black ctermfg=brown
+
+  delcommand HiLink
+endif
+
+let b:current_syntax = "mmix"
+
+" vim: ts=8
--- /dev/null
+++ b/lib/vimfiles/syntax/modconf.vim
@@ -1,0 +1,44 @@
+" Vim syntax file
+" Language:         modules.conf(5) configuration file
+" Maintainer:       Nikolai Weibull <now@bitwi.se>
+" Latest Revision:  2006-04-19
+
+if exists("b:current_syntax")
+  finish
+endif
+
+setlocal iskeyword=@,48-57,-
+
+let s:cpo_save = &cpo
+set cpo&vim
+
+syn keyword modconfTodo         FIXME TODO XXX NOTE
+
+syn region  modconfComment      start='#' skip='\\$' end='$'
+                                \ contains=modconfTodo,@Spell
+
+syn keyword modconfConditional  if else elseif endif
+
+syn keyword modconfPreProc      alias define include keep prune
+                                \ post-install post-remove pre-install
+                                \ pre-remove persistdir
+
+syn keyword modconfKeyword      add above below install options probe probeall
+                                \ remove
+
+syn keyword modconfIdentifier   depfile insmod_opt path generic_stringfile
+                                \ pcimapfile isapnpmapfile usbmapfile
+                                \ parportmapfile ieee1394mapfile pnpbiosmapfile
+syn match   modconfIdentifier   'path\[[^]]\+\]'
+
+hi def link modconfTodo         Todo
+hi def link modconfComment      Comment
+hi def link modconfConditional  Conditional
+hi def link modconfPreProc      PreProc
+hi def link modconfKeyword      Keyword
+hi def link modconfIdentifier   Identifier
+
+let b:current_syntax = "modconf"
+
+let &cpo = s:cpo_save
+unlet s:cpo_save
--- /dev/null
+++ b/lib/vimfiles/syntax/model.vim
@@ -1,0 +1,44 @@
+" Vim syntax file
+" Language:	Model
+" Maintainer:	Bram Moolenaar <Bram@vim.org>
+" Last Change:	2005 Jun 20
+
+" very basic things only (based on the vgrindefs file).
+" If you use this language, please improve it, and send me the patches!
+
+" Quit when a (custom) syntax file was already loaded
+if exists("b:current_syntax")
+  finish
+endif
+
+" A bunch of keywords
+syn keyword modelKeyword abs and array boolean by case cdnl char copied dispose
+syn keyword modelKeyword div do dynamic else elsif end entry external FALSE false
+syn keyword modelKeyword fi file for formal fortran global if iff ift in integer include
+syn keyword modelKeyword inline is lbnd max min mod new NIL nil noresult not notin od of
+syn keyword modelKeyword or procedure public read readln readonly record recursive rem rep
+syn keyword modelKeyword repeat res result return set space string subscript such then TRUE
+syn keyword modelKeyword true type ubnd union until varies while width
+
+" Special keywords
+syn keyword modelBlock beginproc endproc
+
+" Comments
+syn region modelComment start="\$" end="\$" end="$"
+
+" Strings
+syn region modelString start=+"+ end=+"+
+
+" Character constant (is this right?)
+syn match modelString "'."
+
+" Define the default highlighting.
+" Only used when an item doesn't have highlighting yet
+hi def link modelKeyword	Statement
+hi def link modelBlock		PreProc
+hi def link modelComment	Comment
+hi def link modelString		String
+
+let b:current_syntax = "model"
+
+" vim: ts=8 sw=2
--- /dev/null
+++ b/lib/vimfiles/syntax/modsim3.vim
@@ -1,0 +1,109 @@
+" Vim syntax file
+" Language:	Modsim III, by compuware corporation (www.compuware.com)
+" Maintainer:	Philipp Jocham <flip@sbox.tu-graz.ac.at>
+" Extension:	*.mod
+" Last Change:	2001 May 10
+"
+" 2001 March 24:
+"  - Modsim III is a registered trademark from compuware corporation
+"  - made compatible with Vim 6.0
+"
+" 1999 Apr 22 : Changed modsim3Literal from region to match
+"
+" very basic things only (based on the modula2 and c files).
+
+if version < 600
+  " Remove any old syntax stuff hanging around
+  syn clear
+elseif exists("b:current_syntax")
+  finish
+endif
+
+
+" syn case match " case sensitiv match is default
+
+" A bunch of keywords
+syn keyword modsim3Keyword ACTID ALL AND AS ASK
+syn keyword modsim3Keyword BY CALL CASE CLASS CONST DIV
+syn keyword modsim3Keyword DOWNTO DURATION ELSE ELSIF EXIT FALSE FIXED FOR
+syn keyword modsim3Keyword FOREACH FORWARD IF IN INHERITED INOUT
+syn keyword modsim3Keyword INTERRUPT LOOP
+syn keyword modsim3Keyword MOD MONITOR NEWVALUE
+syn keyword modsim3Keyword NONMODSIM NOT OBJECT OF ON OR ORIGINAL OTHERWISE OUT
+syn keyword modsim3Keyword OVERRIDE PRIVATE PROTO REPEAT
+syn keyword modsim3Keyword RETURN REVERSED SELF STRERR TELL
+syn keyword modsim3Keyword TERMINATE THISMETHOD TO TRUE TYPE UNTIL VALUE VAR
+syn keyword modsim3Keyword WAIT WAITFOR WHEN WHILE WITH
+
+" Builtin functions and procedures
+syn keyword modsim3Builtin ABS ACTIVATE ADDMONITOR CAP CHARTOSTR CHR CLONE
+syn keyword modsim3Builtin DEACTIVATE DEC DISPOSE FLOAT GETMONITOR HIGH INC
+syn keyword modsim3Builtin INPUT INSERT INTTOSTR ISANCESTOR LOW LOWER MAX MAXOF
+syn keyword modsim3Builtin MIN MINOF NEW OBJTYPEID OBJTYPENAME OBJVARID ODD
+syn keyword modsim3Builtin ONERROR ONEXIT ORD OUTPUT POSITION PRINT REALTOSTR
+syn keyword modsim3Builtin REPLACE REMOVEMONITOR ROUND SCHAR SIZEOF SPRINT
+syn keyword modsim3Builtin STRLEN STRTOCHAR STRTOINT STRTOREAL SUBSTR TRUNC
+syn keyword modsim3Builtin UPDATEVALUE UPPER VAL
+
+syn keyword modsim3BuiltinNoParen HALT TRACE
+
+" Special keywords
+syn keyword modsim3Block PROCEDURE METHOD MODULE MAIN DEFINITION IMPLEMENTATION
+syn keyword modsim3Block BEGIN END
+
+syn keyword modsim3Include IMPORT FROM
+
+syn keyword modsim3Type ANYARRAY ANYOBJ ANYREC ARRAY BOOLEAN CHAR INTEGER
+syn keyword modsim3Type LMONITORED LRMONITORED NILARRAY NILOBJ NILREC REAL
+syn keyword modsim3Type RECORD RMONITOR RMONITORED STRING
+
+" catch errros cause by wrong parenthesis
+" slight problem with "( *)" or "(* )". Hints?
+syn region modsim3Paren	transparent start='(' end=')' contains=ALLBUT,modsim3ParenError
+syn match modsim3ParenError ")"
+
+" Comments
+syn region modsim3Comment1 start="{" end="}" contains=modsim3Comment1,modsim3Comment2
+syn region modsim3Comment2 start="(\*" end="\*)" contains=modsim3Comment1,modsim3Comment2
+" highlighting is wrong for constructs like "{  (*  }  *)",
+" which are allowed in Modsim III, but
+" I think something like that shouldn't be used anyway.
+
+" Strings
+syn region modsim3String start=+"+ end=+"+
+
+" Literals
+"syn region modsim3Literal start=+'+ end=+'+
+syn match modsim3Literal "'[^']'\|''''"
+
+" Define the default highlighting.
+" For version 5.7 and earlier: only when not done already
+" For version 5.8 and later: only when an item doesn't have highlighting yet
+if version >= 508 || !exists("did_modsim3_syntax_inits")
+  if version < 508
+    let did_modsim3_syntax_inits = 1
+    command -nargs=+ HiLink hi link <args>
+  else
+    command -nargs=+ HiLink hi def link <args>
+  endif
+
+  " The default methods for highlighting.  Can be overridden later
+  HiLink modsim3Keyword	Statement
+  HiLink modsim3Block		Statement
+  HiLink modsim3Comment1	Comment
+  HiLink modsim3Comment2	Comment
+  HiLink modsim3String		String
+  HiLink modsim3Literal	Character
+  HiLink modsim3Include	Statement
+  HiLink modsim3Type		Type
+  HiLink modsim3ParenError	Error
+  HiLink modsim3Builtin	Function
+  HiLink modsim3BuiltinNoParen	Function
+
+  delcommand HiLink
+endif
+
+let b:current_syntax = "modsim3"
+
+" vim: ts=8 sw=2
+
--- /dev/null
+++ b/lib/vimfiles/syntax/modula2.vim
@@ -1,0 +1,86 @@
+" Vim syntax file
+" Language:	Modula 2
+" Maintainer:	pf@artcom0.north.de (Peter Funk)
+"   based on original work of Bram Moolenaar <Bram@vim.org>
+" Last Change:	2001 May 09
+
+" For version 5.x: Clear all syntax items
+" For version 6.x: Quit when a syntax file was already loaded
+if version < 600
+  syntax clear
+elseif exists("b:current_syntax")
+  finish
+endif
+
+" Don't ignore case (Modula-2 is case significant). This is the default in vim
+
+" Especially emphasize headers of procedures and modules:
+syn region modula2Header matchgroup=modula2Header start="PROCEDURE " end="(" contains=modula2Ident oneline
+syn region modula2Header matchgroup=modula2Header start="MODULE " end=";" contains=modula2Ident oneline
+syn region modula2Header matchgroup=modula2Header start="BEGIN (\*" end="\*)" contains=modula2Ident oneline
+syn region modula2Header matchgroup=modula2Header start="END " end=";" contains=modula2Ident oneline
+syn region modula2Keyword start="END" end=";" contains=ALLBUT,modula2Ident oneline
+
+" Some very important keywords which should be emphasized more than others:
+syn keyword modula2AttKeyword CONST EXIT HALT RETURN TYPE VAR
+" All other keywords in alphabetical order:
+syn keyword modula2Keyword AND ARRAY BY CASE DEFINITION DIV DO ELSE
+syn keyword modula2Keyword ELSIF EXPORT FOR FROM IF IMPLEMENTATION IMPORT
+syn keyword modula2Keyword IN LOOP MOD NOT OF OR POINTER QUALIFIED RECORD
+syn keyword modula2Keyword SET THEN TO UNTIL WHILE WITH
+
+syn keyword modula2Type ADDRESS BITSET BOOLEAN CARDINAL CHAR INTEGER REAL WORD
+syn keyword modula2StdFunc ABS CAP CHR DEC EXCL INC INCL ORD SIZE TSIZE VAL
+syn keyword modula2StdConst FALSE NIL TRUE
+" The following may be discussed, since NEW and DISPOSE are some kind of
+" special builtin macro functions:
+syn keyword modula2StdFunc NEW DISPOSE
+" The following types are added later on and may be missing from older
+" Modula-2 Compilers (they are at least missing from the original report
+" by N.Wirth from March 1980 ;-)  Highlighting should apply nevertheless:
+syn keyword modula2Type BYTE LONGCARD LONGINT LONGREAL PROC SHORTCARD SHORTINT
+" same note applies to min and max, which were also added later to m2:
+syn keyword modula2StdFunc MAX MIN
+" The underscore was originally disallowed in m2 ids, it was also added later:
+syn match   modula2Ident " [A-Z,a-z][A-Z,a-z,0-9,_]*" contained
+
+" Comments may be nested in Modula-2:
+syn region modula2Comment start="(\*" end="\*)" contains=modula2Comment,modula2Todo
+syn keyword modula2Todo	contained TODO FIXME XXX
+
+" Strings
+syn region modula2String start=+"+ end=+"+
+syn region modula2String start="'" end="'"
+syn region modula2Set start="{" end="}"
+
+" Define the default highlighting.
+" For version 5.7 and earlier: only when not done already
+" For version 5.8 and later: only when an item doesn't have highlighting yet
+if version >= 508 || !exists("did_modula2_syntax_inits")
+  if version < 508
+    let did_modula2_syntax_inits = 1
+    command -nargs=+ HiLink hi link <args>
+  else
+    command -nargs=+ HiLink hi def link <args>
+  endif
+
+  HiLink modula2Ident		Identifier
+  HiLink modula2StdConst	Boolean
+  HiLink modula2Type		Identifier
+  HiLink modula2StdFunc		Identifier
+  HiLink modula2Header		Type
+  HiLink modula2Keyword		Statement
+  HiLink modula2AttKeyword	PreProc
+  HiLink modula2Comment		Comment
+  " The following is just a matter of taste (you want to try this instead):
+  " hi modula2Comment term=bold ctermfg=DarkBlue guifg=Blue gui=bold
+  HiLink modula2Todo		Todo
+  HiLink modula2String		String
+  HiLink modula2Set		String
+
+  delcommand HiLink
+endif
+
+let b:current_syntax = "modula2"
+
+" vim: ts=8
--- /dev/null
+++ b/lib/vimfiles/syntax/modula3.vim
@@ -1,0 +1,72 @@
+" Vim syntax file
+" Language:	Modula-3
+" Maintainer:	Timo Pedersen <dat97tpe@ludat.lth.se>
+" Last Change:	2001 May 10
+
+" Basic things only...
+" Based on the modula 2 syntax file
+
+" For version 5.x: Clear all syntax items
+" For version 6.x: Quit when a syntax file was already loaded
+if version < 600
+  syntax clear
+elseif exists("b:current_syntax")
+  finish
+endif
+
+" Modula-3 is case-sensitive
+" syn case ignore
+
+" Modula-3 keywords
+syn keyword modula3Keyword ABS ADDRES ADR ADRSIZE AND ANY
+syn keyword modula3Keyword ARRAY AS BITS BITSIZE BOOLEAN BRANDED BY BYTESIZE
+syn keyword modula3Keyword CARDINAL CASE CEILING CHAR CONST DEC DEFINITION
+syn keyword modula3Keyword DISPOSE DIV
+syn keyword modula3Keyword EVAL EXIT EXCEPT EXCEPTION
+syn keyword modula3Keyword EXIT EXPORTS EXTENDED FALSE FINALLY FIRST FLOAT
+syn keyword modula3Keyword FLOOR FROM GENERIC IMPORT
+syn keyword modula3Keyword IN INC INTEGER ISTYPE LAST LOCK
+syn keyword modula3Keyword LONGREAL LOOPHOLE MAX METHOD MIN MOD MUTEX
+syn keyword modula3Keyword NARROW NEW NIL NOT NULL NUMBER OF OR ORD RAISE
+syn keyword modula3Keyword RAISES READONLY REAL RECORD REF REFANY
+syn keyword modula3Keyword RETURN ROOT
+syn keyword modula3Keyword ROUND SET SUBARRAY TEXT TRUE TRUNC TRY TYPE
+syn keyword modula3Keyword TYPECASE TYPECODE UNSAFE UNTRACED VAL VALUE VAR WITH
+
+" Special keywords, block delimiters etc
+syn keyword modula3Block PROCEDURE FUNCTION MODULE INTERFACE REPEAT THEN
+syn keyword modula3Block BEGIN END OBJECT METHODS OVERRIDES RECORD REVEAL
+syn keyword modula3Block WHILE UNTIL DO TO IF FOR ELSIF ELSE LOOP
+
+" Comments
+syn region modula3Comment start="(\*" end="\*)"
+
+" Strings
+syn region modula3String start=+"+ end=+"+
+syn region modula3String start=+'+ end=+'+
+
+" Define the default highlighting.
+" For version 5.7 and earlier: only when not done already
+" For version 5.8 and later: only when an item doesn't have highlighting yet
+if version >= 508 || !exists("did_modula3_syntax_inits")
+  if version < 508
+    let did_modula3_syntax_inits = 1
+    command -nargs=+ HiLink hi link <args>
+  else
+    command -nargs=+ HiLink hi def link <args>
+  endif
+
+  " The default methods for highlighting.  Can be overridden later
+  HiLink modula3Keyword	Statement
+  HiLink modula3Block		PreProc
+  HiLink modula3Comment	Comment
+  HiLink modula3String		String
+
+  delcommand HiLink
+endif
+
+let b:current_syntax = "modula3"
+
+"I prefer to use this...
+"set ai
+"vim: ts=8
--- /dev/null
+++ b/lib/vimfiles/syntax/monk.vim
@@ -1,0 +1,228 @@
+" Vim syntax file
+" Language: Monk (See-Beyond Technologies)
+" Maintainer: Mike Litherland <litherm@ccf.org>
+" Last Change: March 6, 2002
+
+" This syntax file is good enough for my needs, but others
+" may desire more features.  Suggestions and bug reports
+" are solicited by the author (above).
+
+" Originally based on the Scheme syntax file by:
+
+" Maintainer:	Dirk van Deun <dvandeun@poboxes.com>
+" Last Change:	April 30, 1998
+
+" In fact it's almost identical. :)
+
+" The original author's notes:
+" This script incorrectly recognizes some junk input as numerals:
+" parsing the complete system of Scheme numerals using the pattern
+" language is practically impossible: I did a lax approximation.
+
+" Initializing:
+
+" For version 5.x: Clear all syntax items
+" For version 6.x: Quit when a syntax file was already loaded
+if version < 600
+  syntax clear
+elseif exists("b:current_syntax")
+  finish
+endif
+
+syn case ignore
+
+" Fascist highlighting: everything that doesn't fit the rules is an error...
+
+syn match	monkError	oneline    ![^ \t()";]*!
+syn match	monkError	oneline    ")"
+
+" Quoted and backquoted stuff
+
+syn region monkQuoted matchgroup=Delimiter start="['`]" end=![ \t()";]!me=e-1 contains=ALLBUT,monkStruc,monkSyntax,monkFunc
+
+syn region monkQuoted matchgroup=Delimiter start="['`](" matchgroup=Delimiter end=")" contains=ALLBUT,monkStruc,monkSyntax,monkFunc
+syn region monkQuoted matchgroup=Delimiter start="['`]#(" matchgroup=Delimiter end=")" contains=ALLBUT,monkStruc,monkSyntax,monkFunc
+
+syn region monkStrucRestricted matchgroup=Delimiter start="(" matchgroup=Delimiter end=")" contains=ALLBUT,monkStruc,monkSyntax,monkFunc
+syn region monkStrucRestricted matchgroup=Delimiter start="#(" matchgroup=Delimiter end=")" contains=ALLBUT,monkStruc,monkSyntax,monkFunc
+
+syn region monkUnquote matchgroup=Delimiter start="," end=![ \t()";]!me=e-1 contains=ALLBUT,monkStruc,monkSyntax,monkFunc
+syn region monkUnquote matchgroup=Delimiter start=",@" end=![ \t()";]!me=e-1 contains=ALLBUT,monkStruc,monkSyntax,monkFunc
+
+syn region monkUnquote matchgroup=Delimiter start=",(" end=")" contains=ALLBUT,monkStruc,monkSyntax,monkFunc
+syn region monkUnquote matchgroup=Delimiter start=",@(" end=")" contains=ALLBUT,monkStruc,monkSyntax,monkFunc
+
+syn region monkUnquote matchgroup=Delimiter start=",#(" end=")" contains=ALLBUT,monkStruc,monkSyntax,monkFunc
+syn region monkUnquote matchgroup=Delimiter start=",@#(" end=")" contains=ALLBUT,monkStruc,monkSyntax,monkFunc
+
+" R5RS Scheme Functions and Syntax:
+
+if version < 600
+  set iskeyword=33,35-39,42-58,60-90,94,95,97-122,126,_
+else
+  setlocal iskeyword=33,35-39,42-58,60-90,94,95,97-122,126,_
+endif
+
+syn keyword monkSyntax lambda and or if cond case define let let* letrec
+syn keyword monkSyntax begin do delay set! else =>
+syn keyword monkSyntax quote quasiquote unquote unquote-splicing
+syn keyword monkSyntax define-syntax let-syntax letrec-syntax syntax-rules
+
+syn keyword monkFunc not boolean? eq? eqv? equal? pair? cons car cdr set-car!
+syn keyword monkFunc set-cdr! caar cadr cdar cddr caaar caadr cadar caddr
+syn keyword monkFunc cdaar cdadr cddar cdddr caaaar caaadr caadar caaddr
+syn keyword monkFunc cadaar cadadr caddar cadddr cdaaar cdaadr cdadar cdaddr
+syn keyword monkFunc cddaar cddadr cdddar cddddr null? list? list length
+syn keyword monkFunc append reverse list-ref memq memv member assq assv assoc
+syn keyword monkFunc symbol? symbol->string string->symbol number? complex?
+syn keyword monkFunc real? rational? integer? exact? inexact? = < > <= >=
+syn keyword monkFunc zero? positive? negative? odd? even? max min + * - / abs
+syn keyword monkFunc quotient remainder modulo gcd lcm numerator denominator
+syn keyword monkFunc floor ceiling truncate round rationalize exp log sin cos
+syn keyword monkFunc tan asin acos atan sqrt expt make-rectangular make-polar
+syn keyword monkFunc real-part imag-part magnitude angle exact->inexact
+syn keyword monkFunc inexact->exact number->string string->number char=?
+syn keyword monkFunc char-ci=? char<? char-ci<? char>? char-ci>? char<=?
+syn keyword monkFunc char-ci<=? char>=? char-ci>=? char-alphabetic? char?
+syn keyword monkFunc char-numeric? char-whitespace? char-upper-case?
+syn keyword monkFunc char-lower-case?
+syn keyword monkFunc char->integer integer->char char-upcase char-downcase
+syn keyword monkFunc string? make-string string string-length string-ref
+syn keyword monkFunc string-set! string=? string-ci=? string<? string-ci<?
+syn keyword monkFunc string>? string-ci>? string<=? string-ci<=? string>=?
+syn keyword monkFunc string-ci>=? substring string-append vector? make-vector
+syn keyword monkFunc vector vector-length vector-ref vector-set! procedure?
+syn keyword monkFunc apply map for-each call-with-current-continuation
+syn keyword monkFunc call-with-input-file call-with-output-file input-port?
+syn keyword monkFunc output-port? current-input-port current-output-port
+syn keyword monkFunc open-input-file open-output-file close-input-port
+syn keyword monkFunc close-output-port eof-object? read read-char peek-char
+syn keyword monkFunc write display newline write-char call/cc
+syn keyword monkFunc list-tail string->list list->string string-copy
+syn keyword monkFunc string-fill! vector->list list->vector vector-fill!
+syn keyword monkFunc force with-input-from-file with-output-to-file
+syn keyword monkFunc char-ready? load transcript-on transcript-off eval
+syn keyword monkFunc dynamic-wind port? values call-with-values
+syn keyword monkFunc monk-report-environment null-environment
+syn keyword monkFunc interaction-environment
+
+" Keywords specific to STC's implementation
+
+syn keyword monkFunc $event-clear $event-parse $event->string $make-event-map
+syn keyword monkFunc $resolve-event-definition change-pattern copy copy-strip
+syn keyword monkFunc count-data-children count-map-children count-rep data-map
+syn keyword monkFunc duplicate duplicate-strip file-check file-lookup get
+syn keyword monkFunc insert list-lookup node-has-data? not-verify path?
+syn keyword monkFunc path-defined-as-repeating? path-nodeclear path-nodedepth
+syn keyword monkFunc path-nodename path-nodeparentname path->string path-valid?
+syn keyword monkFunc regex string->path timestamp uniqueid verify
+
+" Keywords from the Monk function library (from e*Gate 4.1 programmers ref)
+syn keyword monkFunc allcap? capitalize char-punctuation? char-substitute
+syn keyword monkFunc char-to-char conv count-used-children degc->degf
+syn keyword monkFunc diff-two-dates display-error empty-string? fail_id
+syn keyword monkFunc fail_id_if fail_translation fail_translation_if
+syn keyword monkFunc find-get-after find-get-before get-timestamp julian-date?
+syn keyword monkFunc julian->standard leap-year? map-string not-empty-string?
+syn keyword monkFunc standard-date? standard->julian string-begins-with?
+syn keyword monkFunc string-contains? string-ends-with? string-search-from-left
+syn keyword monkFunc string-search-from-right string->ssn strip-punct
+syn keyword monkFunc strip-string substring=? symbol-table-get symbol-table-put
+syn keyword monkFunc trim-string-left trim-string-right valid-decimal?
+syn keyword monkFunc valid-integer? verify-type
+
+" Writing out the complete description of Scheme numerals without
+" using variables is a day's work for a trained secretary...
+" This is a useful lax approximation:
+
+syn match	monkNumber	oneline    "[-#+0-9.][-#+/0-9a-f@i.boxesfdl]*"
+syn match	monkError	oneline    ![-#+0-9.][-#+/0-9a-f@i.boxesfdl]*[^-#+/0-9a-f@i.boxesfdl \t()";][^ \t()";]*!
+
+syn match	monkOther	oneline    ![+-][ \t()";]!me=e-1
+syn match	monkOther	oneline    ![+-]$!
+" ... so that a single + or -, inside a quoted context, would not be
+" interpreted as a number (outside such contexts, it's a monkFunc)
+
+syn match	monkDelimiter	oneline    !\.[ \t()";]!me=e-1
+syn match	monkDelimiter	oneline    !\.$!
+" ... and a single dot is not a number but a delimiter
+
+" Simple literals:
+
+syn match	monkBoolean	oneline    "#[tf]"
+syn match	monkError	oneline    !#[tf][^ \t()";]\+!
+
+syn match	monkChar	oneline    "#\\"
+syn match	monkChar	oneline    "#\\."
+syn match	monkError	oneline    !#\\.[^ \t()";]\+!
+syn match	monkChar	oneline    "#\\space"
+syn match	monkError	oneline    !#\\space[^ \t()";]\+!
+syn match	monkChar	oneline    "#\\newline"
+syn match	monkError	oneline    !#\\newline[^ \t()";]\+!
+
+" This keeps all other stuff unhighlighted, except *stuff* and <stuff>:
+
+syn match	monkOther	oneline    ,[a-z!$%&*/:<=>?^_~][-a-z!$%&*/:<=>?^_~0-9+.@]*,
+syn match	monkError	oneline    ,[a-z!$%&*/:<=>?^_~][-a-z!$%&*/:<=>?^_~0-9+.@]*[^-a-z!$%&*/:<=>?^_~0-9+.@ \t()";]\+[^ \t()";]*,
+
+syn match	monkOther	oneline    "\.\.\."
+syn match	monkError	oneline    !\.\.\.[^ \t()";]\+!
+" ... a special identifier
+
+syn match	monkConstant	oneline    ,\*[-a-z!$%&*/:<=>?^_~0-9+.@]*\*[ \t()";],me=e-1
+syn match	monkConstant	oneline    ,\*[-a-z!$%&*/:<=>?^_~0-9+.@]*\*$,
+syn match	monkError	oneline    ,\*[-a-z!$%&*/:<=>?^_~0-9+.@]*\*[^-a-z!$%&*/:<=>?^_~0-9+.@ \t()";]\+[^ \t()";]*,
+
+syn match	monkConstant	oneline    ,<[-a-z!$%&*/:<=>?^_~0-9+.@]*>[ \t()";],me=e-1
+syn match	monkConstant	oneline    ,<[-a-z!$%&*/:<=>?^_~0-9+.@]*>$,
+syn match	monkError	oneline    ,<[-a-z!$%&*/:<=>?^_~0-9+.@]*>[^-a-z!$%&*/:<=>?^_~0-9+.@ \t()";]\+[^ \t()";]*,
+
+" Monk input and output structures
+syn match	monkSyntax	oneline    "\(\~input\|\[I\]->\)[^ \t]*"
+syn match	monkFunc	oneline    "\(\~output\|\[O\]->\)[^ \t]*"
+
+" Non-quoted lists, and strings:
+
+syn region monkStruc matchgroup=Delimiter start="(" matchgroup=Delimiter end=")" contains=ALL
+syn region monkStruc matchgroup=Delimiter start="#(" matchgroup=Delimiter end=")" contains=ALL
+
+syn region	monkString	start=+"+  skip=+\\[\\"]+ end=+"+
+
+" Comments:
+
+syn match	monkComment	";.*$"
+
+" Synchronization and the wrapping up...
+
+syn sync match matchPlace grouphere NONE "^[^ \t]"
+" ... i.e. synchronize on a line that starts at the left margin
+
+" Define the default highlighting.
+" For version 5.7 and earlier: only when not done already
+" For version 5.8 and later: only when an item doesn't have highlighting yet
+if version >= 508 || !exists("did_monk_syntax_inits")
+  if version < 508
+    let did_monk_syntax_inits = 1
+    command -nargs=+ HiLink hi link <args>
+  else
+    command -nargs=+ HiLink hi def link <args>
+  endif
+
+  HiLink monkSyntax		Statement
+  HiLink monkFunc		Function
+
+  HiLink monkString		String
+  HiLink monkChar		Character
+  HiLink monkNumber		Number
+  HiLink monkBoolean		Boolean
+
+  HiLink monkDelimiter	Delimiter
+  HiLink monkConstant	Constant
+
+  HiLink monkComment		Comment
+  HiLink monkError		Error
+
+  delcommand HiLink
+endif
+
+let b:current_syntax = "monk"
--- /dev/null
+++ b/lib/vimfiles/syntax/moo.vim
@@ -1,0 +1,173 @@
+" Vim syntax file
+" Language:	MOO
+" Maintainer:	Timo Frenay <timo@frenay.net>
+" Last Change:	2001 Oct 06
+" Note:		Requires Vim 6.0 or above
+
+" Quit when a syntax file was already loaded
+if version < 600 || exists("b:current_syntax")
+  finish
+endif
+
+" Initializations
+syn case ignore
+
+" C-style comments
+syn match mooUncommentedError display ~\*/~
+syn match mooCStyleCommentError display ~/\ze\*~ contained
+syn region mooCStyleComment matchgroup=mooComment start=~/\*~ end=~\*/~ contains=mooCStyleCommentError
+
+" Statements
+if exists("moo_extended_cstyle_comments")
+  syn match mooIdentifier display ~\%(\%(/\*.\{-}\*/\s*\)*\)\@>\<\h\w*\>~ contained transparent contains=mooCStyleComment,@mooKeyword,mooType,mooVariable
+else
+  syn match mooIdentifier display ~\<\h\w*\>~ contained transparent contains=@mooKeyword,mooType,mooVariable
+endif
+syn keyword mooStatement break continue else elseif endfor endfork endif endtry endwhile finally for if try
+syn keyword mooStatement except fork while nextgroup=mooIdentifier skipwhite
+syn keyword mooStatement return nextgroup=mooString skipwhite
+
+" Operators
+syn keyword mooOperatorIn in
+
+" Error constants
+syn keyword mooAny ANY
+syn keyword mooErrorConstant E_ARGS E_INVARG E_DIV E_FLOAT E_INVIND E_MAXREC E_NACC E_NONE E_PERM E_PROPNF E_QUOTA E_RANGE E_RECMOVE E_TYPE E_VARNF E_VERBNF
+
+" Builtin variables
+syn match mooType display ~\<\%(ERR\|FLOAT\|INT\|LIST\|NUM\|OBJ\|STR\)\>~
+syn match mooVariable display ~\<\%(args\%(tr\)\=\|caller\|dobj\%(str\)\=\|iobj\%(str\)\=\|player\|prepstr\|this\|verb\)\>~
+
+" Strings
+syn match mooStringError display ~[^\t -[\]-~]~ contained
+syn match mooStringSpecialChar display ~\\["\\]~ contained
+if !exists("moo_no_regexp")
+  " Regular expressions
+  syn match mooRegexp display ~%%~ contained containedin=mooString,mooRegexpParentheses transparent contains=NONE
+  syn region mooRegexpParentheses display matchgroup=mooRegexpOr start=~%(~ skip=~%%~ end=~%)~ contained containedin=mooString,mooRegexpParentheses transparent oneline
+  syn match mooRegexpOr display ~%|~ contained containedin=mooString,mooRegexpParentheses
+endif
+if !exists("moo_no_pronoun_sub")
+  " Pronoun substitutions
+  syn match mooPronounSub display ~%%~ contained containedin=mooString transparent contains=NONE
+  syn match mooPronounSub display ~%[#dilnopqrst]~ contained containedin=mooString
+  syn match mooPronounSub display ~%\[#[dilnt]\]~ contained containedin=mooString
+  syn match mooPronounSub display ~%(\h\w*)~ contained containedin=mooString
+  syn match mooPronounSub display ~%\[[dilnt]\h\w*\]~ contained containedin=mooString
+  syn match mooPronounSub display ~%<\%([dilnt]:\)\=\a\+>~ contained containedin=mooString
+endif
+if exists("moo_unmatched_quotes")
+  syn region mooString matchgroup=mooStringError start=~"~ end=~$~ contains=@mooStringContents keepend
+  syn region mooString start=~"~ skip=~\\.~ end=~"~ contains=@mooStringContents oneline keepend
+else
+  syn region mooString start=~"~ skip=~\\.~ end=~"\|$~ contains=@mooStringContents keepend
+endif
+
+" Numbers and object numbers
+syn match mooNumber display ~\%(\%(\<\d\+\)\=\.\d\+\|\<\d\+\)\%(e[+\-]\=\d\+\)\=\>~
+syn match mooObject display ~#-\=\d\+\>~
+
+" Properties and verbs
+if exists("moo_builtin_properties")
+  "Builtin properties
+  syn keyword mooBuiltinProperty contents f location name owner programmer r w wizard contained containedin=mooPropRef
+endif
+if exists("moo_extended_cstyle_comments")
+  syn match mooPropRef display ~\.\s*\%(\%(/\*.\{-}\*/\s*\)*\)\@>\h\w*\>~ transparent contains=mooCStyleComment,@mooKeyword
+  syn match mooVerbRef display ~:\s*\%(\%(/\*.\{-}\*/\s*\)*\)\@>\h\w*\>~ transparent contains=mooCStyleComment,@mooKeyword
+else
+  syn match mooPropRef display ~\.\s*\h\w*\>~ transparent contains=@mooKeyword
+  syn match mooVerbRef display ~:\s*\h\w*\>~ transparent contains=@mooKeyword
+endif
+
+" Builtin functions, core properties and core verbs
+if exists("moo_extended_cstyle_comments")
+  syn match mooBuiltinFunction display ~\<\h\w*\s*\%(\%(/\*.\{-}\*/\s*\)*\)\@>\ze(~ contains=mooCStyleComment
+  syn match mooCorePropOrVerb display ~\$\s*\%(\%(/\*.\{-}\*/\s*\)*\)\@>\%(in\>\)\@!\h\w*\>~ contains=mooCStyleComment,@mooKeyword
+else
+  syn match mooBuiltinFunction display ~\<\h\w*\s*\ze(~ contains=NONE
+  syn match mooCorePropOrVerb display ~\$\s*\%(in\>\)\@!\h\w*\>~ contains=@mooKeyword
+endif
+if exists("moo_unknown_builtin_functions")
+  syn match mooUnknownBuiltinFunction ~\<\h\w*\>~ contained containedin=mooBuiltinFunction contains=mooKnownBuiltinFunction
+  " Known builtin functions as of version 1.8.1 of the server
+  " Add your own extensions to this group if you like
+  syn keyword mooKnownBuiltinFunction abs acos add_property add_verb asin atan binary_hash boot_player buffered_output_length callers caller_perms call_function ceil children chparent clear_property connected_players connected_seconds connection_name connection_option connection_options cos cosh create crypt ctime db_disk_size decode_binary delete_property delete_verb disassemble dump_database encode_binary equal eval exp floatstr floor flush_input force_input function_info idle_seconds index is_clear_property is_member is_player kill_task length listappend listdelete listen listeners listinsert listset log log10 match max max_object memory_usage min move notify object_bytes open_network_connection output_delimiters parent pass players properties property_info queued_tasks queue_info raise random read recycle renumber reset_max_object resume rindex rmatch seconds_left server_log server_version setadd setremove set_connection_option set_player_flag set_property_info set_task_perms set_verb_args set_verb_code set_verb_info shutdown sin sinh sqrt strcmp string_hash strsub substitute suspend tan tanh task_id task_stack ticks_left time tofloat toint toliteral tonum toobj tostr trunc typeof unlisten valid value_bytes value_hash verbs verb_args verb_code verb_info contained
+endif
+
+"�Enclosed expressions
+syn match mooUnenclosedError display ~[')\]|}]~
+syn match mooParenthesesError display ~[';\]|}]~ contained
+syn region mooParentheses start=~(~ end=~)~ transparent contains=@mooEnclosedContents,mooParenthesesError
+syn match mooBracketsError display ~[');|}]~ contained
+syn region mooBrackets start=~\[~ end=~\]~ transparent contains=@mooEnclosedContents,mooBracketsError
+syn match mooBracesError display ~[');\]|]~ contained
+syn region mooBraces start=~{~ end=~}~ transparent contains=@mooEnclosedContents,mooBracesError
+syn match mooQuestionError display ~[');\]}]~ contained
+syn region mooQuestion start=~?~ end=~|~ transparent contains=@mooEnclosedContents,mooQuestionError
+syn match mooCatchError display ~[);\]|}]~ contained
+syn region mooCatch matchgroup=mooExclamation start=~`~ end=~'~ transparent contains=@mooEnclosedContents,mooCatchError,mooExclamation
+if exists("moo_extended_cstyle_comments")
+  syn match mooExclamation display ~[\t !%&(*+,\-/<=>?@[^`{|]\@<!\s*\%(\%(/\*.\{-}\*/\s*\)*\)\@>!=\@!~ contained contains=mooCStyleComment
+else
+  syn match mooExclamation display ~[\t !%&(*+,\-/<=>?@[^`{|]\@<!\s*!=\@!~ contained
+endif
+
+" Comments
+syn match mooCommentSpecialChar display ~\\["\\]~ contained transparent contains=NONE
+syn match mooComment ~[\t !%&*+,\-/<=>?@^|]\@<!\s*"\([^\"]\|\\.\)*"\s*;~ contains=mooStringError,mooCommentSpecialChar
+
+" Non-code
+syn region mooNonCode start=~^\s*@\<~ end=~$~
+syn match mooNonCode display ~^\.$~
+syn match mooNonCode display ~^\s*\d\+:~he=e-1
+
+" Overriding matches
+syn match mooRangeOperator display ~\.\.~ transparent contains=NONE
+syn match mooOrOperator display ~||~ transparent contains=NONE
+if exists("moo_extended_cstyle_comments")
+  syn match mooScattering ~[,{]\@<=\s*\%(\%(/\*.\{-}\*/\s*\)*\)\@>?~ transparent contains=mooCStyleComment
+else
+  syn match mooScattering ~[,{]\@<=\s*?~ transparent contains=NONE
+endif
+
+" Clusters
+syn cluster mooKeyword contains=mooStatement,mooOperatorIn,mooAny,mooErrorConstant
+syn cluster mooStringContents contains=mooStringError,mooStringSpecialChar
+syn cluster mooEnclosedContents contains=TOP,mooUnenclosedError,mooComment,mooNonCode
+
+" Define the default highlighting.
+hi def link mooUncommentedError Error
+hi def link mooCStyleCommentError Error
+hi def link mooCStyleComment Comment
+hi def link mooStatement Statement
+hi def link mooOperatorIn Operator
+hi def link mooAny Constant " link this to Keyword if you want
+hi def link mooErrorConstant Constant
+hi def link mooType Type
+hi def link mooVariable Type
+hi def link mooStringError Error
+hi def link mooStringSpecialChar SpecialChar
+hi def link mooRegexpOr SpecialChar
+hi def link mooPronounSub SpecialChar
+hi def link mooString String
+hi def link mooNumber Number
+hi def link mooObject Number
+hi def link mooBuiltinProperty Type
+hi def link mooBuiltinFunction Function
+hi def link mooUnknownBuiltinFunction Error
+hi def link mooKnownBuiltinFunction Function
+hi def link mooCorePropOrVerb Identifier
+hi def link mooUnenclosedError Error
+hi def link mooParenthesesError Error
+hi def link mooBracketsError Error
+hi def link mooBracesError Error
+hi def link mooQuestionError Error
+hi def link mooCatchError Error
+hi def link mooExclamation Exception
+hi def link mooComment Comment
+hi def link mooNonCode PreProc
+
+let b:current_syntax = "moo"
+
+" vim: ts=8
--- /dev/null
+++ b/lib/vimfiles/syntax/mp.vim
@@ -1,0 +1,132 @@
+" Vim syntax file
+" Language:	MetaPost
+" Maintainer:	Andreas Scherer <andreas.scherer@pobox.com>
+" Last Change:	April 30, 2001
+
+" For version 5.x: Clear all syntax items
+" For version 6.x: Quit when a syntax file was already loaded
+if version < 600
+  syn clear
+elseif exists("b:current_syntax")
+  finish
+endif
+
+let plain_mf_macros = 0 " plain.mf has no special meaning for MetaPost
+let other_mf_macros = 0 " cmbase.mf, logo.mf, ... neither
+
+" Read the Metafont syntax to start with
+if version < 600
+  source <sfile>:p:h/mf.vim
+else
+  runtime! syntax/mf.vim
+endif
+
+" MetaPost has TeX inserts for typeset labels
+" verbatimtex, btex, and etex will be treated as keywords
+syn match mpTeXbegin "\(verbatimtex\|btex\)"
+syn match mpTeXend "etex"
+syn region mpTeXinsert start="\(verbatimtex\|btex\)"hs=e+1 end="etex"he=s-1 contains=mpTeXbegin,mpTeXend keepend
+
+" MetaPost primitives not found in Metafont
+syn keyword mpInternal bluepart clip color dashed fontsize greenpart infont
+syn keyword mpInternal linecap linejoin llcorner lrcorner miterlimit mpxbreak
+syn keyword mpInternal prologues redpart setbounds tracinglostchars
+syn keyword mpInternal truecorners ulcorner urcorner withcolor
+
+" Metafont primitives not found in MetaPost
+syn keyword notDefined autorounding chardx chardy fillin granularity hppp
+syn keyword notDefined proofing smoothing tracingedges tracingpens
+syn keyword notDefined turningcheck vppp xoffset yoffset
+
+" Keywords defined by plain.mp
+if !exists("plain_mp_macros")
+  let plain_mp_macros = 1 " Set this to '0' if your source gets too colourful
+endif
+if plain_mp_macros
+  syn keyword mpMacro ahangle ahlength background bbox bboxmargin beginfig
+  syn keyword mpMacro beveled black blue buildcycle butt center cutafter
+  syn keyword mpMacro cutbefore cuttings dashpattern defaultfont defaultpen
+  syn keyword mpMacro defaultscale dotlabel dotlabels drawarrow drawdblarrow
+  syn keyword mpMacro drawoptions endfig evenly extra_beginfig extra_endfig
+  syn keyword mpMacro green label labeloffset mitered red rounded squared
+  syn keyword mpMacro thelabel white base_name base_version
+  syn keyword mpMacro upto downto exitunless relax gobble gobbled
+  syn keyword mpMacro interact loggingall tracingall tracingnone
+  syn keyword mpMacro eps epsilon infinity right left up down origin
+  syn keyword mpMacro quartercircle halfcircle fullcircle unitsquare identity
+  syn keyword mpMacro blankpicture withdots ditto EOF pensquare penrazor
+  syn keyword mpMacro penspeck whatever abs round ceiling byte dir unitvector
+  syn keyword mpMacro inverse counterclockwise tensepath mod div dotprod
+  syn keyword mpMacro takepower direction directionpoint intersectionpoint
+  syn keyword mpMacro softjoin incr decr reflectedabout rotatedaround
+  syn keyword mpMacro rotatedabout min max flex superellipse interpath
+  syn keyword mpMacro magstep currentpen currentpen_path currentpicture
+  syn keyword mpMacro fill draw filldraw drawdot unfill undraw unfilldraw
+  syn keyword mpMacro undrawdot erase cutdraw image pickup numeric_pickup
+  syn keyword mpMacro pen_lft pen_rt pen_top pen_bot savepen clearpen
+  syn keyword mpMacro clear_pen_memory lft rt top bot ulft urt llft lrt
+  syn keyword mpMacro penpos penstroke arrowhead makelabel labels penlabel
+  syn keyword mpMacro range numtok thru clearxy clearit clearpen pickup
+  syn keyword mpMacro shipit bye hide stop solve
+endif
+
+" Keywords defined by mfplain.mp
+if !exists("mfplain_mp_macros")
+  let mfplain_mp_macros = 0 " Set this to '1' to include these macro names
+endif
+if mfplain_mp_macros
+  syn keyword mpMacro beginchar blacker capsule_def change_width
+  syn keyword mpMacro define_blacker_pixels define_corrected_pixels
+  syn keyword mpMacro define_good_x_pixels define_good_y_pixels
+  syn keyword mpMacro define_horizontal_corrected_pixels
+  syn keyword mpMacro define_pixels define_whole_blacker_pixels
+  syn keyword mpMacro define_whole_vertical_blacker_pixels
+  syn keyword mpMacro define_whole_vertical_pixels endchar
+  syn keyword mpMacro extra_beginchar extra_endchar extra_setup
+  syn keyword mpMacro font_coding_scheme font_extra_space font_identifier
+  syn keyword mpMacro font_normal_shrink font_normal_space
+  syn keyword mpMacro font_normal_stretch font_quad font_size
+  syn keyword mpMacro font_slant font_x_height italcorr labelfont
+  syn keyword mpMacro makebox makegrid maketicks mode_def mode_setup
+  syn keyword mpMacro o_correction proofrule proofrulethickness rulepen smode
+
+  " plus some no-ops, also from mfplain.mp
+  syn keyword mpMacro cullit currenttransform gfcorners grayfont hround
+  syn keyword mpMacro imagerules lowres_fix nodisplays notransforms openit
+  syn keyword mpMacro proofoffset screenchars screenrule screenstrokes
+  syn keyword mpMacro showit slantfont titlefont unitpixel vround
+endif
+
+" Keywords defined by other macro packages, e.g., boxes.mp
+if !exists("other_mp_macros")
+  let other_mp_macros = 1 " Set this to '0' if your source gets too colourful
+endif
+if other_mp_macros
+  syn keyword mpMacro circmargin defaultdx defaultdy
+  syn keyword mpMacro boxit boxjoin bpath circleit drawboxed drawboxes
+  syn keyword mpMacro drawunboxed fixpos fixsize pic
+endif
+
+" Define the default highlighting
+" For version 5.7 and earlier: only when not done already
+" For version 5.8 and later: only when an item doesn't have highlighting yet
+if version >= 508 || !exists("did_mp_syntax_inits")
+  if version < 508
+    let did_mp_syntax_inits = 1
+    command -nargs=+ HiLink hi link <args>
+  else
+    command -nargs=+ HiLink hi def link <args>
+  endif
+
+  HiLink mpTeXinsert	String
+  HiLink mpTeXbegin	Statement
+  HiLink mpTeXend	Statement
+  HiLink mpInternal	mfInternal
+  HiLink mpMacro	Macro
+
+  delcommand HiLink
+endif
+
+let b:current_syntax = "mp"
+
+" vim: ts=8
--- /dev/null
+++ b/lib/vimfiles/syntax/mplayerconf.vim
@@ -1,0 +1,83 @@
+" Vim syntax file
+" Language:         mplayer(1) configuration file
+" Maintainer:       Nikolai Weibull <now@bitwi.se>
+" Latest Revision:  2006-04-19
+
+if exists("b:current_syntax")
+  finish
+endif
+
+let s:cpo_save = &cpo
+set cpo&vim
+
+setlocal iskeyword=@,48-57,-
+
+syn keyword mplayerconfTodo     contained TODO FIXME XXX NOTE
+
+syn region mplayerconfComment   display oneline start='#' end='$'
+                                \ contains=mplayerconfTodo,@Spell
+
+syn keyword mplayerconfPreProc  include
+
+syn keyword mplayerconfBoolean  yes no
+
+syn match   mplayerconfNumber   '\<\d\+\>'
+
+syn keyword mplayerconfOption   hardframedrop nomouseinput bandwidth dumpstream
+                                \ rtsp-stream-over-tcp tv overlapsub
+                                \ sub-bg-alpha subfont-outline unicode format
+                                \ vo edl cookies fps zrfd af-adv nosound
+                                \ audio-density passlogfile vobsuboutindex autoq
+                                \ autosync benchmark colorkey nocolorkey edlout
+                                \ enqueue fixed-vo framedrop h identify input
+                                \ lircconf list-options loop menu menu-cfg
+                                \ menu-root nojoystick nolirc nortc playlist
+                                \ quiet really-quiet shuffle skin slave
+                                \ softsleep speed sstep use-stdin aid alang
+                                \ audio-demuxer audiofile audiofile-cache
+                                \ cdrom-device cache cdda channels chapter
+                                \ cookies-file demuxer dumpaudio dumpfile
+                                \ dumpvideo dvbin dvd-device dvdangle forceidx
+                                \ frames hr-mp3-seek idx ipv4-only-proxy
+                                \ loadidx mc mf ni nobps noextbased
+                                \ passwd prefer-ipv4 prefer-ipv6 rawaudio
+                                \ rawvideo saveidx sb srate ss tskeepbroken
+                                \ tsprog tsprobe user user-agent vid vivo
+                                \ dumpjacosub dumpmicrodvdsub dumpmpsub dumpsami
+                                \ dumpsrtsub dumpsub ffactor flip-hebrew font
+                                \ forcedsubsonly fribidi-charset ifo noautosub
+                                \ osdlevel sid slang spuaa spualign spugauss
+                                \ sub sub-bg-color sub-demuxer sub-fuzziness
+                                \ sub-no-text-pp subalign subcc subcp subdelay
+                                \ subfile subfont-autoscale subfont-blur
+                                \ subfont-encoding subfont-osd-scale
+                                \ subfont-text-scale subfps subpos subwidth
+                                \ utf8 vobsub vobsubid abs ao aofile aop delay
+                                \ mixer nowaveheader aa bpp brightness contrast
+                                \ dfbopts display double dr dxr2 fb fbmode
+                                \ fbmodeconfig forcexv fs fsmode-dontuse fstype
+                                \ geometry guiwid hue jpeg monitor-dotclock
+                                \ monitor-hfreq monitor-vfreq monitoraspect
+                                \ nograbpointer nokeepaspect noxv ontop panscan
+                                \ rootwin saturation screenw stop-xscreensaver
+                                \ vm vsync wid xineramascreen z zrbw zrcrop
+                                \ zrdev zrhelp zrnorm zrquality zrvdec zrxdoff
+                                \ ac af afm aspect flip lavdopts noaspect
+                                \ noslices novideo oldpp pp pphelp ssf stereo
+                                \ sws vc vfm x xvidopts xy y zoom vf vop
+                                \ audio-delay audio-preload endpos ffourcc
+                                \ include info noautoexpand noskip o oac of
+                                \ ofps ovc skiplimit v vobsubout vobsuboutid
+                                \ lameopts lavcopts nuvopts xvidencopts
+
+hi def link mplayerconfTodo     Todo
+hi def link mplayerconfComment  Comment
+hi def link mplayerconfPreProc  PreProc
+hi def link mplayerconfBoolean  Boolean
+hi def link mplayerconfNumber   Number
+hi def link mplayerconfOption   Keyword
+
+let b:current_syntax = "mplayerconf"
+
+let &cpo = s:cpo_save
+unlet s:cpo_save
--- /dev/null
+++ b/lib/vimfiles/syntax/mrxvtrc.vim
@@ -1,0 +1,277 @@
+" Created	: Wed 26 Apr 2006 01:20:53 AM CDT
+" Modified	: Mon 20 Nov 2006 12:14:16 AM PST
+" Author	: Gautam Iyer <gi1242@users.sourceforge.net>
+" Description	: Vim syntax file for mrxvtrc (for mrxvt-0.5.0 and up)
+
+" Quit when a syntax file was already loaded
+if exists("b:current_syntax")
+  finish
+endif
+
+syn case match
+
+" Errors
+syn match	mrxvtrcError	contained	'\v\S+'
+
+" Comments
+syn match	mrxvtrcComment	contains=@Spell '^\s*[!#].*$'
+syn match	mrxvtrcComment	'\v^\s*[#!]\s*\w+[.*]\w+.*:.*'
+
+"
+" Options.
+"
+syn match	mrxvtrcClass	'\v^\s*\w+[.*]'
+	    \ nextgroup=mrxvtrcOptions,mrxvtrcProfile,@mrxvtrcPOpts,mrxvtrcError
+
+" Boolean options
+syn keyword	mrxvtrcOptions	contained nextgroup=mrxvtrcBColon,mrxvtrcError
+				\ highlightTabOnBell syncTabTitle hideTabbar
+				\ autohideTabbar bottomTabbar hideButtons
+				\ syncTabIcon veryBoldFont maximized
+				\ fullscreen reverseVideo loginShell
+				\ jumpScroll scrollBar scrollbarRight
+				\ scrollbarFloating scrollTtyOutputInhibit
+				\ scrollTtyKeypress scrollWithBuffer
+				\ transparentForce transparentScrollbar
+				\ transparentMenubar transparentTabbar
+				\ tabUsePixmap utmpInhibit visualBell mapAlert
+				\ meta8 mouseWheelScrollPage multibyte_cursor
+				\ tripleclickwords showMenu xft xftNomFont
+				\ xftSlowOutput xftAntialias xftHinting
+				\ xftAutoHint xftGlobalAdvance cmdAllTabs
+				\ protectSecondary thai borderLess
+				\ overrideRedirect broadcast
+				\ smartResize smoothResize pointerBlank
+				\ cursorBlink noSysConfig disableMacros
+				\ linuxHomeEndKey sessionMgt
+syn match	mrxvtrcOptions	contained nextgroup=mrxvtrcBColon,mrxvtrcError
+				\ '\v<transparent>'
+syn match	mrxvtrcBColon	contained skipwhite
+				\ nextgroup=mrxvtrcBoolVal,mrxvtrcError ':'
+syn case ignore
+syn keyword	mrxvtrcBoolVal	contained skipwhite nextgroup=mrxvtrcError
+				\ 0 1 yes no on off true false
+syn case match
+
+" Color options
+syn keyword	mrxvtrcOptions	contained nextgroup=mrxvtrcCColon,mrxvtrcError
+				\ ufBackground textShadow tabForeground
+				\ itabForeground tabBackground itabBackground
+				\ scrollColor troughColor highlightColor
+				\ cursorColor cursorColor2 pointerColor
+				\ borderColor tintColor
+syn match	mrxvtrcOptions	contained nextgroup=mrxvtrcCColon,mrxvtrcError
+				\ '\v<color([0-9]|1[0-5]|BD|UL|RV)>'
+syn match	mrxvtrcCColon	contained skipwhite
+				\ nextgroup=mrxvtrcColorVal ':'
+syn match	mrxvtrcColorVal	contained skipwhite nextgroup=mrxvtrcError
+				\ '\v#[0-9a-fA-F]{6}'
+
+" Numeric options
+syn keyword	mrxvtrcOptions	contained nextgroup=mrxvtrcNColon,mrxvtrcError
+				\ maxTabWidth minVisibleTabs
+				\ scrollbarThickness xftmSize xftSize desktop
+				\ externalBorder internalBorder lineSpace
+				\ pointerBlankDelay cursorBlinkInterval
+				\ shading backgroundFade bgRefreshInterval
+				\ fading focusDelay opacity opacityDegree
+				\ xftPSize
+syn match	mrxvtrcNColon	contained skipwhite
+				\ nextgroup=mrxvtrcNumVal,mrxvtrcError ':'
+syn match	mrxvtrcNumVal	contained skipwhite nextgroup=mrxvtrcError
+				\ '\v[+-]?<(0[0-7]+|\d+|0x[0-9a-f]+)>'
+
+" String options
+syn keyword	mrxvtrcOptions	contained nextgroup=mrxvtrcSColon,mrxvtrcError
+				\ tabTitle termName title clientName iconName
+				\ bellCommand backspaceKey deleteKey
+				\ printPipe cutChars answerbackString
+				\ smClientID geometry path boldFont xftFont
+				\ xftmFont xftPFont inputMethod
+				\ greektoggle_key menu menubarPixmap
+				\ scrollbarPixmap tabbarPixmap appIcon
+				\ multichar_encoding initProfileList
+				\ winTitleFormat
+syn match	mrxvtrcOptions	contained nextgroup=mrxvtrcSColon,mrxvtrcError
+				\ '\v<m?font[1-5]?>'
+syn match	mrxvtrcSColon	contained skipwhite nextgroup=mrxvtrcStrVal ':'
+syn match	mrxvtrcStrVal	contained '\v\S.*'
+
+" Profile options
+syn cluster	mrxvtrcPOpts	contains=mrxvtrcPSOpts,mrxvtrcPCOpts,mrxvtrcPNOpts
+syn match	mrxvtrcProfile	contained nextgroup=@mrxvtrcPOpts,mrxvtrcError
+				\ '\vprofile\d+\.'
+syn keyword	mrxvtrcPSOpts	contained nextgroup=mrxvtrcSColon,mrxvtrcError
+				\ tabTitle command holdExitText holdExitTitle
+				\ Pixmap workingDirectory titleFormat
+syn keyword	mrxvtrcPCOpts	contained nextgroup=mrxvtrcCColon,mrxvtrcError
+				\ background foreground
+syn keyword	mrxvtrcPNOpts	contained nextgroup=mrxvtrcNColon,mrxvtrcError
+				\ holdExit saveLines
+
+" scrollbarStyle
+syn match	mrxvtrcOptions	contained skipwhite
+				\ nextgroup=mrxvtrcSBstyle,mrxvtrcError
+				\ '\v<scrollbarStyle:'
+syn keyword	mrxvtrcSBstyle	contained skipwhite nextgroup=mrxvtrcError
+				\ plain xterm rxvt next sgi
+
+" scrollbarAlign
+syn match	mrxvtrcOptions	contained skipwhite
+				\ nextgroup=mrxvtrcSBalign,mrxvtrcError
+				\ '\v<scrollbarAlign:'
+syn keyword	mrxvtrcSBalign	contained skipwhite nextgroup=mrxvtrcError
+				\ top bottom
+
+" textShadowMode
+syn match	mrxvtrcOptions	contained skipwhite
+				\ nextgroup=mrxvtrcTSmode,mrxvtrcError
+				\ '\v<textShadowMode:'
+syn keyword	mrxvtrcTSmode	contained skipwhite nextgroup=mrxvtrcError
+				\ none top bottom left right topleft topright
+				\ botleft botright
+
+" greek_keyboard
+syn match	mrxvtrcOptions	contained skipwhite
+				\ nextgroup=mrxvtrcGrkKbd,mrxvtrcError
+				\ '\v<greek_keyboard:'
+syn keyword	mrxvtrcGrkKbd	contained skipwhite nextgroup=mrxvtrcError
+				\ iso ibm
+
+" xftWeight
+syn match	mrxvtrcOptions	contained skipwhite
+				\ nextgroup=mrxvtrcXftWt,mrxvtrcError
+				\ '\v<(xftWeight|xftBoldWeight):'
+syn keyword	mrxvtrcXftWt	contained skipwhite nextgroup=mrxvtrcError
+				\ light medium demibold bold black
+
+" xftSlant
+syn match	mrxvtrcOptions	contained skipwhite
+				\ nextgroup=mrxvtrcXftSl,mrxvtrcError
+				\ '\v<xftSlant:'
+syn keyword	mrxvtrcXftSl	contained skipwhite nextgroup=mrxvtrcError
+				\ roman italic oblique
+
+" xftWidth
+syn match	mrxvtrcOptions	contained skipwhite
+				\ nextgroup=mrxvtrcXftWd,mrxvtrcError
+				\ '\v<xftWidth:'
+syn keyword	mrxvtrcXftWd	contained skipwhite nextgroup=mrxvtrcError
+				\ ultracondensed ultraexpanded
+				\ condensed expanded normal
+
+" xftRGBA
+syn match	mrxvtrcOptions	contained skipwhite
+				\ nextgroup=mrxvtrcXftHt,mrxvtrcError
+				\ '\v<xftRGBA:'
+syn keyword	mrxvtrcXftHt	contained skipwhite nextgroup=mrxvtrcError
+				\ rgb bgr vrgb vbgr none
+
+" preeditType
+syn match	mrxvtrcOptions	contained skipwhite
+				\ nextgroup=mrxvtrcPedit,mrxvtrcError
+				\ '\v<preeditType:'
+syn keyword	mrxvtrcPedit	contained skipwhite nextgroup=mrxvtrcError
+				\ OverTheSpot OffTheSpot Root
+
+" modifier
+syn match	mrxvtrcOptions	contained skipwhite
+				\ nextgroup=mrxvtrcMod,mrxvtrcError
+				\ '\v<modifier:'
+syn keyword	mrxvtrcMod	contained skipwhite nextgroup=mrxvtrcError
+				\ alt meta hyper super mod1 mod2 mod3 mod4 mod5
+
+" selectStyle
+syn match	mrxvtrcOptions	contained skipwhite
+				\ nextgroup=mrxvtrcSelSty,mrxvtrcError
+				\ '\v<selectStyle:'
+syn keyword	mrxvtrcSelSty	contained skipwhite nextgroup=mrxvtrcError
+				\ old oldword
+
+
+"
+" Macros
+"
+syn keyword	mrxvtrcOptions	contained nextgroup=mrxvtrcKey,mrxvtrcError
+				\ macro
+syn case ignore
+syn match	mrxvtrcKey	contained skipwhite
+			    \ nextgroup=mrxvtrcMacro,mrxvtrcError
+			    \ '\v\.((primary|add|ctrl|alt|meta|shift)\+)*\w+:'
+syn case match
+
+" Macros without arguments
+syn keyword	mrxvtrcMacro	contained skipwhite nextgroup=mrxvtrcError
+				\ Dummy Copy Paste ToggleVeryBold
+				\ ToggleTransparency ToggleBroadcast
+				\ ToggleHold SetTitle ToggleMacros
+				\ ToggleFullscreen
+
+" Macros with a string argument
+syn keyword	mrxvtrcMacro	contained skipwhite nextgroup=mrxvtrcStrVal
+				\ Esc Str Exec Scroll PrintScreen SaveConfig
+
+" Macros with a numeric argument
+syn keyword	mrxvtrcMacro	contained skipwhite
+				\ nextgroup=mrxvtrcNumVal,mrxvtrcError
+				\ Close GotoTab MoveTab ResizeFont
+
+" NewTab macro
+syn keyword	mrxvtrcMacro	contained skipwhite
+				\ nextgroup=mrxvtrcTitle,mrxvtrcShell,mrxvtrcCmd
+				\ NewTab
+syn region	mrxvtrcTitle	contained oneline skipwhite
+				\ nextgroup=mrxvtrcShell,mrxvtrcCmd
+				\ start='"' end='"'
+syn match	mrxvtrcShell	contained nextgroup=mrxvtrcCmd '!' 
+syn match	mrxvtrcCmd	contained '\v[^!" \t].*'
+
+" ToggleSubwin macro
+syn keyword	mrxvtrcMacro	contained skipwhite
+				\ nextgroup=mrxvtrcSubwin,mrxvtrcError
+				\ ToggleSubwin
+syn match	mrxvtrcSubwin	contained skipwhite nextgroup=mrxvtrcError
+				\ '\v[-+]?[bmst]>'
+
+"
+" Highlighting groups
+"
+hi def link mrxvtrcError	Error
+hi def link mrxvtrcComment	Comment
+
+hi def link mrxvtrcClass	Statement
+hi def link mrxvtrcOptions	mrxvtrcClass
+hi def link mrxvtrcBColon	mrxvtrcClass
+hi def link mrxvtrcCColon	mrxvtrcClass
+hi def link mrxvtrcNColon	mrxvtrcClass
+hi def link mrxvtrcSColon	mrxvtrcClass
+hi def link mrxvtrcProfile	mrxvtrcClass
+hi def link mrxvtrcPSOpts	mrxvtrcClass
+hi def link mrxvtrcPCOpts	mrxvtrcClass
+hi def link mrxvtrcPNOpts	mrxvtrcClass
+
+hi def link mrxvtrcBoolVal	Boolean
+hi def link mrxvtrcStrVal	String
+hi def link mrxvtrcColorVal	Constant
+hi def link mrxvtrcNumVal	Number
+
+hi def link mrxvtrcSBstyle	mrxvtrcStrVal
+hi def link mrxvtrcSBalign	mrxvtrcStrVal
+hi def link mrxvtrcTSmode	mrxvtrcStrVal
+hi def link mrxvtrcGrkKbd	mrxvtrcStrVal
+hi def link mrxvtrcXftWt	mrxvtrcStrVal
+hi def link mrxvtrcXftSl	mrxvtrcStrVal
+hi def link mrxvtrcXftWd	mrxvtrcStrVal
+hi def link mrxvtrcXftHt	mrxvtrcStrVal
+hi def link mrxvtrcPedit	mrxvtrcStrVal
+hi def link mrxvtrcMod		mrxvtrcStrVal
+hi def link mrxvtrcSelSty	mrxvtrcStrVal
+
+hi def link mrxvtrcMacro	Identifier
+hi def link mrxvtrcKey		mrxvtrcClass
+hi def link mrxvtrcTitle	mrxvtrcStrVal
+hi def link mrxvtrcShell	Special
+hi def link mrxvtrcCmd		PreProc
+hi def link mrxvtrcSubwin	mrxvtrcStrVal
+
+let b:current_syntax = "mrxvtrc"
--- /dev/null
+++ b/lib/vimfiles/syntax/msidl.vim
@@ -1,0 +1,92 @@
+" Vim syntax file
+" Language:     MS IDL (Microsoft dialect of Interface Description Language)
+" Maintainer:   Vadim Zeitlin <vadim@wxwindows.org>
+" Last Change:  2003 May 11
+
+" For version 5.x: Clear all syntax items
+" For version 6.x: Quit when a syntax file was already loaded
+if version < 600
+  syntax clear
+elseif exists("b:current_syntax")
+  finish
+endif
+
+" Misc basic
+syn match   msidlId		"[a-zA-Z][a-zA-Z0-9_]*"
+syn match   msidlUUID		"{\?[[:xdigit:]]\{8}-\([[:xdigit:]]\{4}-\)\{3}[[:xdigit:]]\{12}}\?"
+syn region  msidlString		start=/"/  skip=/\\\(\\\\\)*"/	end=/"/
+syn match   msidlLiteral	"\d\+\(\.\d*\)\="
+syn match   msidlLiteral	"\.\d\+"
+syn match   msidlSpecial	contained "[]\[{}:]"
+
+" Comments
+syn keyword msidlTodo		contained TODO FIXME XXX
+syn region  msidlComment	start="/\*"  end="\*/" contains=msidlTodo
+syn match   msidlComment	"//.*" contains=msidlTodo
+syn match   msidlCommentError	"\*/"
+
+" C style Preprocessor
+syn region  msidlIncluded	contained start=+"+  skip=+\\\(\\\\\)*"+  end=+"+
+syn match   msidlIncluded	contained "<[^>]*>"
+syn match   msidlInclude	"^[ \t]*#[ \t]*include\>[ \t]*["<]" contains=msidlIncluded,msidlString
+syn region  msidlPreCondit	start="^[ \t]*#[ \t]*\(if\>\|ifdef\>\|ifndef\>\|elif\>\|else\>\|endif\>\)"  skip="\\$"	end="$" contains=msidlComment,msidlCommentError
+syn region  msidlDefine		start="^[ \t]*#[ \t]*\(define\>\|undef\>\)" skip="\\$" end="$" contains=msidlLiteral, msidlString
+
+" Attributes
+syn keyword msidlAttribute      contained in out propget propput propputref retval
+syn keyword msidlAttribute      contained aggregatable appobject binadable coclass control custom default defaultbind defaultcollelem defaultvalue defaultvtable dispinterface displaybind dual entry helpcontext helpfile helpstring helpstringdll hidden id immediatebind lcid library licensed nonbrowsable noncreatable nonextensible oleautomation optional object public readonly requestedit restricted source string uidefault usesgetlasterror vararg version
+syn match   msidlAttribute      /uuid(.*)/he=s+4 contains=msidlUUID
+syn match   msidlAttribute      /helpstring(.*)/he=s+10 contains=msidlString
+syn region  msidlAttributes     start="\[" end="]" keepend contains=msidlSpecial,msidlString,msidlAttribute,msidlComment,msidlCommentError
+
+" Keywords
+syn keyword msidlEnum		enum
+syn keyword msidlImport		import importlib
+syn keyword msidlStruct		interface library coclass
+syn keyword msidlTypedef	typedef
+
+" Types
+syn keyword msidlStandardType   byte char double float hyper int long short void wchar_t
+syn keyword msidlStandardType   BOOL BSTR HRESULT VARIANT VARIANT_BOOL
+syn region  msidlSafeArray      start="SAFEARRAY(" end=")" contains=msidlStandardType
+
+syn sync lines=50
+
+" Define the default highlighting.
+" For version 5.7 and earlier: only when not done already
+" For version 5.8 and later: only when an item doesn't have highlighting yet
+if version >= 508 || !exists("did_msidl_syntax_inits")
+  if version < 508
+    let did_msidl_syntax_inits = 1
+    command -nargs=+ HiLink hi link <args>
+  else
+    command -nargs=+ HiLink hi def link <args>
+  endif
+
+  HiLink msidlInclude		Include
+  HiLink msidlPreProc		PreProc
+  HiLink msidlPreCondit		PreCondit
+  HiLink msidlDefine		Macro
+  HiLink msidlIncluded		String
+  HiLink msidlString		String
+  HiLink msidlComment		Comment
+  HiLink msidlTodo		Todo
+  HiLink msidlSpecial		SpecialChar
+  HiLink msidlLiteral		Number
+  HiLink msidlUUID		Number
+
+  HiLink msidlImport		Include
+  HiLink msidlEnum		StorageClass
+  HiLink msidlStruct		Structure
+  HiLink msidlTypedef		Typedef
+  HiLink msidlAttribute		StorageClass
+
+  HiLink msidlStandardType	Type
+  HiLink msidlSafeArray		Type
+
+  delcommand HiLink
+endif
+
+let b:current_syntax = "msidl"
+
+" vi: set ts=8 sw=4:
--- /dev/null
+++ b/lib/vimfiles/syntax/msql.vim
@@ -1,0 +1,100 @@
+" Vim syntax file
+" Language:	msql
+" Maintainer:	Lutz Eymers <ixtab@polzin.com>
+" URL:		http://www.isp.de/data/msql.vim
+" Email:	Subject: send syntax_vim.tgz
+" Last Change:	2001 May 10
+"
+" Options	msql_sql_query = 1 for SQL syntax highligthing inside strings
+"		msql_minlines = x     to sync at least x lines backwards
+
+" For version 5.x: Clear all syntax items
+" For version 6.x: Quit when a syntax file was already loaded
+if version < 600
+  syntax clear
+elseif exists("b:current_syntax")
+  finish
+endif
+
+if !exists("main_syntax")
+  let main_syntax = 'msql'
+endif
+
+if version < 600
+  so <sfile>:p:h/html.vim
+else
+  runtime! syntax/html.vim
+  unlet b:current_syntax
+endif
+
+syn cluster htmlPreproc add=msqlRegion
+
+syn case match
+
+" Internal Variables
+syn keyword msqlIntVar ERRMSG contained
+
+" Env Variables
+syn keyword msqlEnvVar SERVER_SOFTWARE SERVER_NAME SERVER_URL GATEWAY_INTERFACE contained
+syn keyword msqlEnvVar SERVER_PROTOCOL SERVER_PORT REQUEST_METHOD PATH_INFO  contained
+syn keyword msqlEnvVar PATH_TRANSLATED SCRIPT_NAME QUERY_STRING REMOTE_HOST contained
+syn keyword msqlEnvVar REMOTE_ADDR AUTH_TYPE REMOTE_USER CONTEN_TYPE  contained
+syn keyword msqlEnvVar CONTENT_LENGTH HTTPS HTTPS_KEYSIZE HTTPS_SECRETKEYSIZE  contained
+syn keyword msqlEnvVar HTTP_ACCECT HTTP_USER_AGENT HTTP_IF_MODIFIED_SINCE  contained
+syn keyword msqlEnvVar HTTP_FROM HTTP_REFERER contained
+
+" Inlclude lLite
+syn include @msqlLite <sfile>:p:h/lite.vim
+
+" Msql Region
+syn region msqlRegion matchgroup=Delimiter start="<!$" start="<![^!->D]" end=">" contains=@msqlLite,msql.*
+
+" sync
+if exists("msql_minlines")
+  exec "syn sync minlines=" . msql_minlines
+else
+  syn sync minlines=100
+endif
+
+" Define the default highlighting.
+" For version 5.7 and earlier: only when not done already
+" For version 5.8 and later: only when an item doesn't have highlighting yet
+if version >= 508 || !exists("did_msql_syn_inits")
+  if version < 508
+    let did_msql_syn_inits = 1
+    command -nargs=+ HiLink hi link <args>
+  else
+    command -nargs=+ HiLink hi def link <args>
+  endif
+
+  HiLink msqlComment		Comment
+  HiLink msqlString		String
+  HiLink msqlNumber		Number
+  HiLink msqlFloat		Float
+  HiLink msqlIdentifier	Identifier
+  HiLink msqlGlobalIdentifier	Identifier
+  HiLink msqlIntVar		Identifier
+  HiLink msqlEnvVar		Identifier
+  HiLink msqlFunctions		Function
+  HiLink msqlRepeat		Repeat
+  HiLink msqlConditional	Conditional
+  HiLink msqlStatement		Statement
+  HiLink msqlType		Type
+  HiLink msqlInclude		Include
+  HiLink msqlDefine		Define
+  HiLink msqlSpecialChar	SpecialChar
+  HiLink msqlParentError	Error
+  HiLink msqlTodo		Todo
+  HiLink msqlOperator		Operator
+  HiLink msqlRelation		Operator
+
+  delcommand HiLink
+endif
+
+let b:current_syntax = "msql"
+
+if main_syntax == 'msql'
+  unlet main_syntax
+endif
+
+" vim: ts=8
--- /dev/null
+++ b/lib/vimfiles/syntax/mupad.vim
@@ -1,0 +1,295 @@
+" Vim syntax file
+" Language:    MuPAD source
+" Maintainer:  Dave Silvia <dsilvia@mchsi.com>
+" Filenames:   *.mu
+" Date:        6/30/2004
+
+
+" For version 5.x: Clear all syntax items
+" For version 6.x: Quit when a syntax file was already loaded
+if version < 600
+  syntax clear
+elseif exists("b:current_syntax")
+  finish
+endif
+
+" Set default highlighting to Win2k
+if !exists("mupad_cmdextversion")
+  let mupad_cmdextversion = 2
+endif
+
+syn case match
+
+syn match mupadComment	"//\p*$"
+syn region mupadComment	start="/\*"	end="\*/"
+
+syn region mupadString	start="\""	skip=/\\"/	end="\""
+
+syn match mupadOperator		"(\|)\|:=\|::\|:\|;"
+" boolean
+syn keyword mupadOperator	and	or	not	xor
+syn match mupadOperator		"==>\|\<=\>"
+
+" Informational
+syn keyword mupadSpecial		FILEPATH	NOTEBOOKFILE	NOTEBOOKPATH
+" Set-able, e.g., DIGITS:=10
+syn keyword mupadSpecial		DIGITS		HISTORY		LEVEL
+syn keyword mupadSpecial		MAXLEVEL	MAXDEPTH	ORDER
+syn keyword mupadSpecial		TEXTWIDTH
+" Set-able, e.g., PRETTYPRINT:=TRUE
+syn keyword mupadSpecial		PRETTYPRINT
+" Set-able, e.g., LIBPATH:="C:\\MuPAD Pro\\mylibdir" or LIBPATH:="/usr/MuPAD Pro/mylibdir"
+syn keyword mupadSpecial		LIBPATH		PACKAGEPATH
+syn keyword mupadSpecial		READPATH	TESTPATH	WRITEPATH
+" Symbols and Constants
+syn keyword mupadDefine		FAIL		NIL
+syn keyword mupadDefine		TRUE		FALSE		UNKNOWN
+syn keyword mupadDefine		complexInfinity		infinity
+syn keyword mupadDefine		C_	CATALAN	E	EULER	I	PI	Q_	R_
+syn keyword mupadDefine		RD_INF	RD_NINF	undefined	unit	universe	Z_
+" print() directives
+syn keyword mupadDefine		Unquoted	NoNL	KeepOrder	Typeset
+" domain specifics
+syn keyword mupadStatement	domain	begin	end_domain	end
+syn keyword mupadIdentifier	inherits	category	axiom	info	doc interface
+" basic programming statements
+syn keyword mupadStatement	proc	begin	end_proc
+syn keyword mupadUnderlined	name	local	option	save
+syn keyword mupadConditional	if	then	elif	else	end_if
+syn keyword mupadConditional	case	of	do	break	end_case
+syn keyword mupadRepeat		for	do	next	break	end_for
+syn keyword mupadRepeat		while	do	next break end_while
+syn keyword mupadRepeat		repeat	next break until	end_repeat
+" domain packages/libraries
+syn keyword mupadType			detools	import	linalg	numeric	numlib	plot	polylib
+syn match mupadType				'\<DOM_\w*\>'
+
+"syn keyword mupadFunction	contains
+" Functions dealing with prime numbers
+syn keyword mupadFunction	phi	invphi	mersenne	nextprime	numprimedivisors
+syn keyword mupadFunction	pollard	prevprime	primedivisors
+" Functions operating on Lists, Matrices, Sets, ...
+syn keyword mupadFunction	array	_index
+" Evaluation
+syn keyword mupadFunction	float contains
+" stdlib
+syn keyword mupadFunction	_exprseq	_invert	_lazy_and	_lazy_or	_negate
+syn keyword mupadFunction	_stmtseq	_invert	intersect	minus		union
+syn keyword mupadFunction	Ci	D	Ei	O	Re	Im	RootOf	Si
+syn keyword mupadFunction	Simplify
+syn keyword mupadFunction	abs	airyAi	airyBi	alias	unalias	anames	append
+syn keyword mupadFunction	arcsin	arccos	arctan	arccsc	arcsec	arccot
+syn keyword mupadFunction	arcsinh	arccosh	arctanh	arccsch	arcsech	arccoth
+syn keyword mupadFunction	arg	args	array	assert	assign	assignElements
+syn keyword mupadFunction	assume	assuming	asympt	bernoulli
+syn keyword mupadFunction	besselI	besselJ	besselK	besselY	beta	binomial	bool
+syn keyword mupadFunction	bytes	card
+syn keyword mupadFunction	ceil	floor	round	trunc
+syn keyword mupadFunction	coeff	coerce	collect	combine	copyClosure
+syn keyword mupadFunction	conjugate	content	context	contfrac
+syn keyword mupadFunction	debug	degree	degreevec	delete	_delete	denom
+syn keyword mupadFunction	densematrix	diff	dilog	dirac	discont	div	_div
+syn keyword mupadFunction	divide	domtype	doprint	erf	erfc	error	eval	evalassign
+syn keyword mupadFunction	evalp	exp	expand	export	unexport	expose	expr
+syn keyword mupadFunction	expr2text	external	extnops	extop	extsubsop
+syn keyword mupadFunction	fact	fact2	factor	fclose	finput	fname	fopen	fprint
+syn keyword mupadFunction	fread	ftextinput	readbitmap	readdata	pathname
+syn keyword mupadFunction	protocol	read	readbytes	write	writebytes
+syn keyword mupadFunction	float	frac	frame	_frame	frandom	freeze	unfreeze
+syn keyword mupadFunction	funcenv	gamma	gcd	gcdex	genident	genpoly
+syn keyword mupadFunction	getpid	getprop	ground	has	hastype	heaviside	help
+syn keyword mupadFunction	history	hold	hull	hypergeom	icontent	id
+syn keyword mupadFunction	ifactor	igamma	igcd	igcdex	ilcm	in	_in
+syn keyword mupadFunction	indets	indexval	info	input	int	int2text
+syn keyword mupadFunction	interpolate	interval	irreducible	is
+syn keyword mupadFunction	isprime	isqrt	iszero	ithprime	kummerU	lambertW
+syn keyword mupadFunction	last	lasterror	lcm	lcoeff	ldegree	length
+syn keyword mupadFunction	level	lhs	rhs	limit	linsolve	lllint
+syn keyword mupadFunction	lmonomial	ln	loadmod	loadproc	log	lterm
+syn keyword mupadFunction	match	map	mapcoeffs	maprat	matrix	max	min
+syn keyword mupadFunction	mod	modp	mods	monomials	multcoeffs	new
+syn keyword mupadFunction	newDomain	_next	nextprime	nops
+syn keyword mupadFunction	norm	normal	nterms	nthcoeff	nthmonomial	nthterm
+syn keyword mupadFunction	null	numer	ode	op	operator	package
+syn keyword mupadFunction	pade	partfrac	patchlevel	pdivide
+syn keyword mupadFunction	piecewise	plot	plotfunc2d	plotfunc3d
+syn keyword mupadFunction	poly	poly2list	polylog	powermod	print
+syn keyword mupadFunction	product	protect	psi	quit	_quit	radsimp	random	rationalize
+syn keyword mupadFunction	rec	rectform	register	reset	return	revert
+syn keyword mupadFunction	rewrite	select	series	setuserinfo	share	sign	signIm
+syn keyword mupadFunction	simplify
+syn keyword mupadFunction	sin	cos	tan	csc	sec	cot
+syn keyword mupadFunction	sinh	cosh	tanh	csch	sech	coth
+syn keyword mupadFunction	slot	solve
+syn keyword mupadFunction	pdesolve	matlinsolve	matlinsolveLU	toeplitzSolve
+syn keyword mupadFunction	vandermondeSolve	fsolve	odesolve	odesolve2
+syn keyword mupadFunction	polyroots	polysysroots	odesolveGeometric
+syn keyword mupadFunction	realroot	realroots	mroots	lincongruence
+syn keyword mupadFunction	msqrts
+syn keyword mupadFunction	sort	split	sqrt	strmatch	strprint
+syn keyword mupadFunction	subs	subset	subsex	subsop	substring	sum
+syn keyword mupadFunction	surd	sysname	sysorder	system	table	taylor	tbl2text
+syn keyword mupadFunction	tcoeff	testargs	testeq	testtype	text2expr
+syn keyword mupadFunction	text2int	text2list	text2tbl	rtime	time
+syn keyword mupadFunction	traperror	type	unassume	unit	universe
+syn keyword mupadFunction	unloadmod	unprotect	userinfo	val	version
+syn keyword mupadFunction	warning	whittakerM	whittakerW	zeta	zip
+
+" graphics  plot::
+syn keyword mupadFunction	getDefault	setDefault	copy	modify	Arc2d	Arrow2d
+syn keyword mupadFunction	Arrow3d	Bars2d	Bars3d	Box	Boxplot	Circle2d	Circle3d
+syn keyword mupadFunction	Cone	Conformal	Curve2d	Curve3d	Cylinder	Cylindrical
+syn keyword mupadFunction	Density	Ellipse2d	Function2d	Function3d	Hatch
+syn keyword mupadFunction	Histogram2d	HOrbital	Implicit2d	Implicit3d
+syn keyword mupadFunction	Inequality	Iteration	Line2d	Line3d	Lsys	Matrixplot
+syn keyword mupadFunction	MuPADCube	Ode2d	Ode3d	Parallelogram2d	Parallelogram3d
+syn keyword mupadFunction	Piechart2d	Piechart3d	Point2d	Point3d	Polar
+syn keyword mupadFunction	Polygon2d	Polygon3d	Raster	Rectangle	Sphere
+syn keyword mupadFunction	Ellipsoid	Spherical	Sum	Surface	SurfaceSet
+syn keyword mupadFunction	SurfaceSTL	Tetrahedron	Hexahedron	Octahedron
+syn keyword mupadFunction	Dodecahedron	Icosahedron	Text2d	Text3d	Tube	Turtle
+syn keyword mupadFunction	VectorField2d	XRotate	ZRotate	Canvas	CoordinateSystem2d
+syn keyword mupadFunction	CoordinateSystem3d	Group2d	Group3d	Scene2d	Scene3d	ClippingBox
+syn keyword mupadFunction	Rotate2d	Rotate3d	Scale2d	Scale3d	Transform2d
+syn keyword mupadFunction	Transform3d	Translate2d	Translate3d	AmbientLight
+syn keyword mupadFunction	Camera	DistantLight	PointLight	SpotLight
+
+" graphics Attributes
+" graphics  Output Attributes
+syn keyword mupadIdentifier	OutputFile	OutputOptions
+" graphics  Defining Attributes
+syn keyword mupadIdentifier	Angle	AngleRange	AngleBegin	AngleEnd
+syn keyword mupadIdentifier	Area	Axis	AxisX	AxisY	AxisZ	Base	Top
+syn keyword mupadIdentifier	BaseX	TopX	BaseY	TopY	BaseZ	TopZ
+syn keyword mupadIdentifier	BaseRadius	TopRadius	Cells
+syn keyword mupadIdentifier	Center	CenterX	CenterY	CenterZ
+syn keyword mupadIdentifier	Closed	ColorData	CommandList	Contours	CoordinateType
+syn keyword mupadIdentifier	Data	DensityData	DensityFunction	From	To
+syn keyword mupadIdentifier	FromX	ToX	FromY	ToY	FromZ	ToZ
+syn keyword mupadIdentifier	Function	FunctionX	FunctionY	FunctionZ
+syn keyword mupadIdentifier	Function1	Function2	Baseline
+syn keyword mupadIdentifier	Generations	RotationAngle	IterationRules	StartRule StepLength
+syn keyword mupadIdentifier	TurtleRules	Ground	Heights	Moves	Inequalities
+syn keyword mupadIdentifier	InputFile	Iterations	StartingPoint
+syn keyword mupadIdentifier	LineColorFunction	FillColorFunction
+syn keyword mupadIdentifier	Matrix2d	Matrix3d
+syn keyword mupadIdentifier	MeshList	MeshListType	MeshListNormals
+syn keyword mupadIdentifier	MagneticQuantumNumber	MomentumQuantumNumber	PrincipalQuantumNumber
+syn keyword mupadIdentifier	Name	Normal	NormalX	NormalY	NormalZ
+syn keyword mupadIdentifier	ParameterName	ParameterBegin	ParameterEnd	ParameterRange
+syn keyword mupadIdentifier	Points2d	Points3d	Radius	RadiusFunction
+syn keyword mupadIdentifier	Position	PositionX	PositionY	PositionZ
+syn keyword mupadIdentifier	Scale	ScaleX	ScaleY	ScaleZ Shift	ShiftX	ShiftY	ShiftZ
+syn keyword mupadIdentifier	SemiAxes	SemiAxisX	SemiAxisY	SemiAxisZ
+syn keyword mupadIdentifier	Tangent1	Tangent1X	Tangent1Y	Tangent1Z
+syn keyword mupadIdentifier	Tangent2	Tangent2X	Tangent2Y	Tangent2Z
+syn keyword mupadIdentifier	Text	TextOrientation	TextRotation
+syn keyword mupadIdentifier	UName	URange	UMin	UMax	VName	VRange	VMin	VMax
+syn keyword mupadIdentifier	XName	XRange	XMin	XMax	YName	YRange	YMin	YMax
+syn keyword mupadIdentifier	ZName	ZRange	ZMin	ZMax	ViewingBox
+syn keyword mupadIdentifier	ViewingBoxXMin	ViewingBoxXMax	ViewingBoxXRange
+syn keyword mupadIdentifier	ViewingBoxYMin	ViewingBoxYMax	ViewingBoxYRange
+syn keyword mupadIdentifier	ViewingBoxZMin	ViewingBoxZMax	ViewingBoxZRange
+syn keyword mupadIdentifier	Visible
+" graphics  Axis Attributes
+syn keyword mupadIdentifier	Axes	AxesInFront	AxesLineColor	AxesLineWidth
+syn keyword mupadIdentifier	AxesOrigin	AxesOriginX	AxesOriginY	AxesOriginZ
+syn keyword mupadIdentifier	AxesTips	AxesTitleAlignment
+syn keyword mupadIdentifier	AxesTitleAlignmentX	AxesTitleAlignmentY	AxesTitleAlignmentZ
+syn keyword mupadIdentifier	AxesTitles	XAxisTitle	YAxisTitle	ZAxisTitle
+syn keyword mupadIdentifier	AxesVisible	XAxisVisible	YAxisVisible	ZAxisVisible
+syn keyword mupadIdentifier	YAxisTitleOrientation
+" graphics  Tick Marks Attributes
+syn keyword mupadIdentifier	TicksAnchor	XTicksAnchor	YTicksAnchor	ZTicksAnchor
+syn keyword mupadIdentifier	TicksAt	XTicksAt	YTicksAt	ZTicksAt
+syn keyword mupadIdentifier	TicksBetween	XTicksBetween	YTicksBetween	ZTicksBetween
+syn keyword mupadIdentifier	TicksDistance	XTicksDistance	YTicksDistance	ZTicksDistance
+syn keyword mupadIdentifier	TicksNumber	XTicksNumber	YTicksNumber	ZTicksNumber
+syn keyword mupadIdentifier	TicksVisible	XTicksVisible	YTicksVisible	ZTicksVisible
+syn keyword mupadIdentifier	TicksLength	TicksLabelStyle
+syn keyword mupadIdentifier	XTicksLabelStyle	YTicksLabelStyle	ZTicksLabelStyle
+syn keyword mupadIdentifier	TicksLabelsVisible
+syn keyword mupadIdentifier	XTicksLabelsVisible	YTicksLabelsVisible	ZTicksLabelsVisible
+" graphics  Grid Lines Attributes
+syn keyword mupadIdentifier	GridInFront	GridLineColor	SubgridLineColor
+syn keyword mupadIdentifier	GridLineStyle	SubgridLineStyle GridLineWidth	SubgridLineWidth
+syn keyword mupadIdentifier	GridVisible	XGridVisible	YGridVisible	ZGridVisible
+syn keyword mupadIdentifier	SubgridVisible	XSubgridVisible	YSubgridVisible	ZSubgridVisible
+" graphics  Animation Attributes
+syn keyword mupadIdentifier	Frames	TimeRange	TimeBegin	TimeEnd
+syn keyword mupadIdentifier	VisibleAfter	VisibleBefore	VisibleFromTo
+syn keyword mupadIdentifier	VisibleAfterEnd	VisibleBeforeBegin
+" graphics  Annotation Attributes
+syn keyword mupadIdentifier	Footer	Header	FooterAlignment	HeaderAlignment
+syn keyword mupadIdentifier	HorizontalAlignment	TitleAlignment	VerticalAlignment
+syn keyword mupadIdentifier	Legend	LegendEntry	LegendText
+syn keyword mupadIdentifier	LegendAlignment	LegendPlacement	LegendVisible
+syn keyword mupadIdentifier	Title	Titles
+syn keyword mupadIdentifier	TitlePosition	TitlePositionX	TitlePositionY	TitlePositionZ
+" graphics  Layout Attributes
+syn keyword mupadIdentifier	Bottom	Left	Height	Width	Layout	Rows	Columns
+syn keyword mupadIdentifier	Margin	BottomMargin	TopMargin	LeftMargin	RightMargin
+syn keyword mupadIdentifier	OutputUnits	Spacing
+" graphics  Calculation Attributes
+syn keyword mupadIdentifier	AdaptiveMesh	DiscontinuitySearch	Mesh	SubMesh
+syn keyword mupadIdentifier	UMesh	USubMesh	VMesh	VSubMesh
+syn keyword mupadIdentifier	XMesh	XSubMesh	YMesh	YSubMesh	Zmesh
+" graphics  Camera and Lights Attributes
+syn keyword mupadIdentifier	CameraCoordinates	CameraDirection
+syn keyword mupadIdentifier	CameraDirectionX	CameraDirectionY	CameraDirectionZ
+syn keyword mupadIdentifier	FocalPoint	FocalPointX	FocalPointY	FocalPointZ
+syn keyword mupadIdentifier	LightColor	Lighting	LightIntensity	OrthogonalProjection
+syn keyword mupadIdentifier	SpotAngle	ViewingAngle
+syn keyword mupadIdentifier	Target	TargetX	TargetY	TargetZ
+" graphics  Presentation Style and Fonts Attributes
+syn keyword mupadIdentifier	ArrowLength
+syn keyword mupadIdentifier	AxesTitleFont	FooterFont	HeaderFont	LegendFont
+syn keyword mupadIdentifier	TextFont	TicksLabelFont	TitleFont
+syn keyword mupadIdentifier	BackgroundColor	BackgroundColor2	BackgroundStyle
+syn keyword mupadIdentifier	BackgroundTransparent	Billboarding	BorderColor	BorderWidth
+syn keyword mupadIdentifier	BoxCenters	BoxWidths	DrawMode Gap	XGap	YGap
+syn keyword mupadIdentifier	Notched	NotchWidth	Scaling	YXRatio	ZXRatio
+syn keyword mupadIdentifier	VerticalAsymptotesVisible	VerticalAsymptotesStyle
+syn keyword mupadIdentifier	VerticalAsymptotesColor	VerticalAsymptotesWidth
+" graphics  Line Style Attributes
+syn keyword mupadIdentifier	LineColor	LineColor2	LineColorType	LineStyle
+syn keyword mupadIdentifier	LinesVisible	ULinesVisible	VLinesVisible	XLinesVisible
+syn keyword mupadIdentifier	YLinesVisible	LineWidth	MeshVisible
+" graphics  Point Style Attributes
+syn keyword mupadIdentifier	PointColor	PointSize	PointStyle	PointsVisible
+" graphics  Surface Style Attributes
+syn keyword mupadIdentifier	BarStyle	Shadows	Color	Colors	FillColor	FillColor2
+syn keyword mupadIdentifier	FillColorTrue	FillColorFalse	FillColorUnknown	FillColorType
+syn keyword mupadIdentifier	Filled	FillPattern	FillPatterns	FillStyle
+syn keyword mupadIdentifier	InterpolationStyle	Shading	UseNormals
+" graphics  Arrow Style Attributes
+syn keyword mupadIdentifier	TipAngle	TipLength	TipStyle	TubeDiameter
+syn keyword mupadIdentifier	Tubular
+" graphics  meta-documentation Attributes
+syn keyword mupadIdentifier	objectGroupsListed
+
+if version >= 508 || !exists("did_mupad_syntax_inits")
+  if version < 508
+    let did_mupad_syntax_inits = 1
+    command -nargs=+ HiLink hi link <args>
+  else
+    command -nargs=+ HiLink hi def link <args>
+  endif
+
+  HiLink mupadComment		Comment
+  HiLink mupadString		String
+  HiLink mupadOperator		Operator
+  HiLink mupadSpecial		Special
+  HiLink mupadStatement		Statement
+  HiLink mupadUnderlined	Underlined
+  HiLink mupadConditional	Conditional
+  HiLink mupadRepeat		Repeat
+  HiLink mupadFunction		Function
+  HiLink mupadType		Type
+  HiLink mupadDefine		Define
+  HiLink mupadIdentifier	Identifier
+
+  delcommand HiLink
+endif
+
+" TODO  More comprehensive listing.
--- /dev/null
+++ b/lib/vimfiles/syntax/mush.vim
@@ -1,0 +1,227 @@
+" MUSHcode syntax file
+" Maintainer: Rick Bird <nveid@nveid.com>
+" Based on vim Syntax file by: Bek Oberin <gossamer@tertius.net.au>
+" Last Updated: Fri Nov 04 20:28:15 2005
+"
+" For version 5.x: Clear all syntax items
+" For version 6.x: Quit when a syntax file was already loaded
+if version < 600
+  syntax clear
+elseif exists("b:current_syntax")
+  finish
+endif
+
+
+" regular mush functions
+
+syntax keyword mushFunction contained @@ abs accent accname acos add after align
+syntax keyword mushFunction contained allof alphamax alphamin and andflags
+syntax keyword mushFunction contained andlflags andlpowers andpowers ansi aposs art
+syntax keyword mushFunction contained asin atan atan2 atrlock attrcnt band baseconv
+syntax keyword mushFunction contained beep before blank2tilde bnand bnot bor bound
+syntax keyword mushFunction contained brackets break bxor cand cansee capstr case
+syntax keyword mushFunction contained caseall cat ceil center checkpass children
+syntax keyword mushFunction contained chr clone cmds cnetpost comp con config conn
+syntax keyword mushFunction contained controls convsecs convtime convutcsecs cor
+syntax keyword mushFunction contained cos create ctime ctu dec decrypt default
+syntax keyword mushFunction contained delete die dig digest dist2d dist3d div
+syntax keyword mushFunction contained division divscope doing downdiv dynhelp e
+syntax keyword mushFunction contained edefault edit element elements elist elock
+syntax keyword mushFunction contained emit empire empower encrypt endtag entrances
+syntax keyword mushFunction contained eq escape etimefmt eval exit exp extract fdiv
+syntax keyword mushFunction contained filter filterbool findable first firstof
+syntax keyword mushFunction contained flags flip floor floordiv fmod fold
+syntax keyword mushFunction contained folderstats followers following foreach
+syntax keyword mushFunction contained fraction fullname functions get get_eval grab
+syntax keyword mushFunction contained graball grep grepi gt gte hasattr hasattrp
+syntax keyword mushFunction contained hasattrpval hasattrval hasdivpower hasflag
+syntax keyword mushFunction contained haspower haspowergroup hastype height hidden
+syntax keyword mushFunction contained home host hostname html idle idlesecs
+syntax keyword mushFunction contained idle_average idle_times idle_total if ifelse
+syntax keyword mushFunction contained ilev iname inc index indiv indivall insert
+syntax keyword mushFunction contained inum ipaddr isdaylight isdbref isint isnum
+syntax keyword mushFunction contained isword itemize items iter itext last lattr
+syntax keyword mushFunction contained lcon lcstr ldelete ldivisions left lemit
+syntax keyword mushFunction contained level lexits lflags link list lit ljust lmath
+syntax keyword mushFunction contained ln lnum loc localize locate lock loctree log
+syntax keyword mushFunction contained lparent lplayers lports lpos lsearch lsearchr
+syntax keyword mushFunction contained lstats lt lte lthings lvcon lvexits lvplayers
+syntax keyword mushFunction contained lvthings lwho mail maildstats mailfrom
+syntax keyword mushFunction contained mailfstats mailstats mailstatus mailsubject
+syntax keyword mushFunction contained mailtime map match matchall max mean median
+syntax keyword mushFunction contained member merge mid min mix mod modulo modulus
+syntax keyword mushFunction contained money mtime mudname mul munge mwho name nand
+syntax keyword mushFunction contained nattr ncon nearby neq nexits next nor not
+syntax keyword mushFunction contained nplayers nsemit nslemit nsoemit nspemit
+syntax keyword mushFunction contained nsremit nszemit nthings null num nvcon
+syntax keyword mushFunction contained nvexits nvplayers nvthings obj objeval objid
+syntax keyword mushFunction contained objmem oemit ooref open or ord orflags
+syntax keyword mushFunction contained orlflags orlpowers orpowers owner parent
+syntax keyword mushFunction contained parse pcreate pemit pi pickrand playermem
+syntax keyword mushFunction contained pmatch poll ports pos poss power powergroups
+syntax keyword mushFunction contained powers powover program prompt pueblo quitprog
+syntax keyword mushFunction contained quota r rand randword recv regedit regeditall
+syntax keyword mushFunction contained regeditalli regediti regmatch regmatchi
+syntax keyword mushFunction contained regrab regraball regraballi regrabi regrep
+syntax keyword mushFunction contained regrepi remainder remit remove repeat replace
+syntax keyword mushFunction contained rest restarts restarttime reswitch
+syntax keyword mushFunction contained reswitchall reswitchalli reswitchi reverse
+syntax keyword mushFunction contained revwords right rjust rloc rnum room root
+syntax keyword mushFunction contained round s scan scramble search secs secure sent
+syntax keyword mushFunction contained set setdiff setinter setq setr setunion sha0
+syntax keyword mushFunction contained shl shr shuffle sign signal sin sort sortby
+syntax keyword mushFunction contained soundex soundlike soundslike space spellnum
+syntax keyword mushFunction contained splice sql sqlescape sqrt squish ssl
+syntax keyword mushFunction contained starttime stats stddev step strcat strinsert
+syntax keyword mushFunction contained stripaccents stripansi strlen strmatch
+syntax keyword mushFunction contained strreplace sub subj switch switchall t table
+syntax keyword mushFunction contained tag tagwrap tan tel terminfo textfile
+syntax keyword mushFunction contained tilde2blank time timefmt timestring tr
+syntax keyword mushFunction contained trigger trim trimpenn trimtiny trunc type u
+syntax keyword mushFunction contained ucstr udefault ufun uldefault ulocal updiv
+syntax keyword mushFunction contained utctime v vadd val valid vcross vdim vdot
+syntax keyword mushFunction contained version visible vmag vmax vmin vmul vsub
+syntax keyword mushFunction contained vtattr vtcount vtcreate vtdestroy vtlcon
+syntax keyword mushFunction contained vtloc vtlocate vtmaster vtname vtref vttel
+syntax keyword mushFunction contained vunit wait where width wipe wordpos words
+syntax keyword mushFunction contained wrap xcon xexits xget xor xplayers xthings
+syntax keyword mushFunction contained xvcon xvexits xvplayers xvthings zemit zfun
+syntax keyword mushFunction contained zmwho zone zwho
+
+" only highligh functions when they have an in-bracket immediately after
+syntax match mushFunctionBrackets  "\i*(" contains=mushFunction
+"
+" regular mush commands
+syntax keyword mushAtCommandList contained @ALLHALT @ALLQUOTA @ASSERT @ATRCHOWN @ATRLOCK @ATTRIBUTE @BOOT 
+syntax keyword mushAtCommandList contained @BREAK @CEMIT @CHANNEL @CHAT @CHOWN @CHOWNALL @CHZONE @CHZONEALL 
+syntax keyword mushAtCommandList contained @CLOCK @CLONE @COBJ @COMMAND @CONFIG @CPATTR @CREATE @CRPLOG @DBCK
+syntax keyword mushAtCommandList contained @DECOMPILE @DESTROY @DIG @DISABLE @DIVISION @DOING @DOLIST @DRAIN 
+syntax keyword mushAtCommandList contained @DUMP @EDIT @ELOCK @EMIT @EMPOWER @ENABLE @ENTRANCES @EUNLOCK @FIND 
+syntax keyword mushAtCommandList contained @FIRSTEXIT @FLAG @FORCE @FUNCTION @EDIT @GREP @HALT @HIDE @HOOK @KICK 
+syntax keyword mushAtCommandList contained @LEMIT @LEVEL @LINK @LIST @LISTMOTD @LOCK @LOG @LOGWIPE @LSET @MAIL @MALIAS 
+syntax keyword mushAtCommandList contained @MAP @MOTD @MVATTR @NAME @NEWPASSWORD @NOTIFY @NSCEMIT @NSEMIT @NSLEMIT 
+syntax keyword mushAtCommandList contained @NSOEMIT @NSPEMIT @NSPEMIT @NSREMIT @NSZEMIT @NUKE @OEMIT @OPEN @PARENT @PASSWORD
+syntax keyword mushAtCommandList contained @PCREATE @PEMIT @POLL @POOR @POWERLEVEL @PROGRAM @PROMPT @PS @PURGE @QUOTA 
+syntax keyword mushAtCommandList contained @READCACHE @RECYCLE @REJECTMOTD @REMIT @RESTART @SCAN @SEARCH @SELECT @SET 
+syntax keyword mushAtCommandList contained @SHUTDOWN @SITELOCK @SNOOP @SQL @SQUOTA @STATS @SWITCH @SWEEP @SWITCH @TELEPORT 
+syntax keyword mushAtCommandList contained @TRIGGER @ULOCK @UNDESTROY @UNLINK @UNLOCK @UNRECYCLE @UPTIME @UUNLOCK @VERB 
+syntax keyword mushAtCommandList contained @VERSION @WAIT @WALL @WARNINGS @WCHECK @WHEREIS @WIPE @ZCLONE @ZEMIT
+syntax match mushCommand  "@\i\I*" contains=mushAtCommandList
+
+
+syntax keyword mushCommand AHELP ANEWS ATTRIB_SET BRIEF BRIEF BUY CHANGES DESERT
+syntax keyword mushCommand DISMISS DROP EMPTY ENTER EXAMINE FOLLOW GET GIVE GOTO 
+syntax keyword mushCommand HELP HUH_COMMAND INVENTORY INVENTORY LOOK LEAVE LOOK
+syntax keyword mushCommand GOTO NEWS PAGE PAGE POSE RULES SAY SCORE SEMIPOSE 
+syntax keyword mushCommand SPECIALNEWS TAKE TEACH THINK UNFOLLOW USE WHISPER WHISPER
+syntax keyword mushCommand WARN_ON_MISSING WHISPER WITH
+
+syntax match mushSpecial     "\*\|!\|=\|-\|\\\|+"
+syntax match mushSpecial2 contained     "\*"
+
+syn region    mushString         start=+L\="+ skip=+\\\\\|\\"+ end=+"+ contains=mushSpecial,mushSpecial2,@Spell
+
+
+syntax match mushIdentifier   "&[^ ]\+"
+
+syntax match mushVariable   "%r\|%t\|%cr\|%[A-Za-z0-9]\+\|%#\|##\|here"
+
+" numbers
+syntax match mushNumber	+[0-9]\++
+
+" A comment line starts with a or # or " at the start of the line
+" or an @@
+syntax keyword mushTodo contained	TODO FIXME XXX
+syntax cluster mushCommentGroup contains=mushTodo
+syntax match	mushComment	"^\s*@@.*$"	contains=mushTodo
+syntax match mushComment "^#[^define|^ifdef|^else|^pragma|^ifndef|^echo|^elif|^undef|^warning].*$" contains=mushTodo
+syntax match mushComment "^#$" contains=mushTodo
+syntax region mushComment        matchgroup=mushCommentStart start="/@@" end="@@/" contains=@mushCommentGroup,mushCommentStartError,mushCommentString,@Spell
+syntax region mushCommentString  contained start=+L\=\\\@<!"+ skip=+\\\\\|\\"+ end=+"+ end=+@@/+me=s-1 contains=mushCommentSkip
+syntax match  mushCommentSkip    contained "^\s*@@\($\|\s\+\)"
+
+
+syntax match mushCommentStartError display "/@@"me=e-1 contained
+
+" syntax match	mushComment	+^".*$+	contains=mushTodo
+" Work on this one
+" syntax match	mushComment	+^#.*$+	contains=mushTodo
+
+syn region      mushPreCondit      start="^\s*\(%:\|#\)\s*\(if\|ifdef\|ifndef\|elif\)\>" skip="\\$" end="$" end="//"me=s-1 contains=mushComment
+syn match       mushPreCondit      display "^\s*\(%:\|#\)\s*\(else\|endif\)\>"
+
+syn cluster     mushPreProcGroup   contains=mushPreCondit,mushIncluded,mushInclude,mushDefine,mushSpecial,mushString,mushCommentSkip,mushCommentString,@mushCommentGroup,mushCommentStartError
+
+syn region      mushIncluded       display contained start=+"+ skip=+\\\\\|\\"+ end=+"+
+syn match       mushIncluded       display contained "<[^>]*>"
+syn match       mushInclude        display "^\s*\(%:\|#\)\s*include\>\s*["<]" contains=mushIncluded
+syn region	mushDefine		start="^\s*\(%:\|#\)\s*\(define\|undef\)\>" skip="\\$" end="$" end="//"me=s-1 contains=ALLBUT,@mushPreProcGroup,@Spell
+syn region	mushPreProc	start="^\s*\(%:\|#\)\s*\(pragma\>\|line\>\|warning\>\|warn\>\|error\>\)" skip="\\$" end="$" keepend contains=ALLBUT,@mushPreProcGroup
+
+
+syntax region	mushFuncBoundaries start="\[" end="\]" contains=mushFunction,mushFlag,mushAttributes,mushNumber,mushCommand,mushVariable,mushSpecial2
+
+" FLAGS
+syntax keyword mushFlag PLAYER ABODE BUILDER CHOWN_OK DARK FLOATING
+syntax keyword mushFlag GOING HAVEN INHERIT JUMP_OK KEY LINK_OK MONITOR
+syntax keyword mushFlag NOSPOOF OPAQUE QUIET STICKY TRACE UNFINDABLE VISUAL
+syntax keyword mushFlag WIZARD PARENT_OK ZONE AUDIBLE CONNECTED DESTROY_OK
+syntax keyword mushFlag ENTER_OK HALTED IMMORTAL LIGHT MYOPIC PUPPET TERSE
+syntax keyword mushFlag ROBOT SAFE TRANSPARENT VERBOSE CONTROL_OK COMMANDS
+
+syntax keyword mushAttribute aahear aclone aconnect adesc adfail adisconnect
+syntax keyword mushAttribute adrop aefail aenter afail agfail ahear akill
+syntax keyword mushAttribute aleave alfail alias amhear amove apay arfail
+syntax keyword mushAttribute asucc atfail atport aufail ause away charges
+syntax keyword mushAttribute cost desc dfail drop ealias efail enter fail
+syntax keyword mushAttribute filter forwardlist gfail idesc idle infilter
+syntax keyword mushAttribute inprefix kill lalias last lastsite leave lfail
+syntax keyword mushAttribute listen move odesc odfail odrop oefail oenter
+syntax keyword mushAttribute ofail ogfail okill oleave olfail omove opay
+syntax keyword mushAttribute orfail osucc otfail otport oufail ouse oxenter
+syntax keyword mushAttribute oxleave oxtport pay prefix reject rfail runout
+syntax keyword mushAttribute semaphore sex startup succ tfail tport ufail
+syntax keyword mushAttribute use va vb vc vd ve vf vg vh vi vj vk vl vm vn
+syntax keyword mushAttribute vo vp vq vr vs vt vu vv vw vx vy vz
+
+
+if version >= 508 || !exists("did_mush_syntax_inits")
+  if version < 508
+    let did_mush_syntax_inits = 1
+    command -nargs=+ HiLink hi link <args>
+  else
+    command -nargs=+ HiLink hi def link <args>
+  endif
+
+  " The default methods for highlighting.  Can be overridden later
+  HiLink mushAttribute  Constant
+  HiLink mushCommand    Function
+  HiLink mushNumber     Number
+  HiLink mushSetting    PreProc
+  HiLink mushFunction   Statement
+  HiLink mushVariable   Identifier
+  HiLink mushSpecial    Special
+  HiLink mushTodo       Todo
+  HiLink mushFlag       Special
+  HiLink mushIdentifier Identifier
+  HiLink mushDefine     Macro
+  HiLink mushPreProc    PreProc
+  HiLink mushPreProcGroup PreProc 
+  HiLink mushPreCondit PreCondit
+  HiLink mushIncluded cString
+  HiLink  mushInclude Include
+
+
+
+" Comments
+  HiLink mushCommentStart mushComment
+  HiLink mushComment    Comment
+  HiLink mushCommentString mushString
+
+
+  delcommand HiLink
+endif
+
+let b:current_syntax = "mush"
+
+" mush: ts=17
--- /dev/null
+++ b/lib/vimfiles/syntax/muttrc.vim
@@ -1,0 +1,567 @@
+" Vim syntax file
+" Language:	Mutt setup files
+" Original:	Preben 'Peppe' Guldberg <peppe-vim@wielders.org>
+" Maintainer:	Kyle Wheeler <kyle-muttrc.vim@memoryhole.net>
+" Last Change:	5 Mar 2007
+
+" This file covers mutt version 1.5.14 (and most of CVS HEAD)
+" Included are also a few features from 1.4.2.1
+
+" For version 5.x: Clear all syntax items
+" For version 6.x: Quit when a syntax file was already loaded
+if version < 600
+  syntax clear
+elseif exists("b:current_syntax")
+  finish
+endif
+
+" Set the keyword characters
+if version < 600
+  set isk=@,48-57,_,-
+else
+  setlocal isk=@,48-57,_,-
+endif
+
+syn match muttrcComment		"^# .*$" contains=@Spell
+syn match muttrcComment		"^#[^ ].*$"
+syn match muttrcComment		"^#$"
+syn match muttrcComment		"[^\\]#.*$"lc=1
+
+" Escape sequences (back-tick and pipe goes here too)
+syn match muttrcEscape		+\\[#tnr"'Cc ]+
+syn match muttrcEscape		+[`|]+
+
+" The variables takes the following arguments
+syn match  muttrcString		"=\s*[^ #"'`]\+"lc=1 contains=muttrcEscape
+syn region muttrcString		start=+"+ms=e skip=+\\"+ end=+"+ contains=muttrcEscape,muttrcSet,muttrcUnset,muttrcReset,muttrcToggle,muttrcCommand,muttrcAction
+syn region muttrcString		start=+'+ms=e skip=+\\'+ end=+'+ contains=muttrcEscape,muttrcSet,muttrcUnset,muttrcReset,muttrcToggle,muttrcCommand,muttrcAction
+
+syn region muttrcShellString	matchgroup=muttrcEscape keepend start=+`+ skip=+\\`+ end=+`+ contains=muttrcVarStr,muttrcVarBool,muttrcVarQuad,muttrcVarNum,muttrcCommand,muttrcSet
+
+syn match  muttrcRXChars	contained /[^\\][][.*?+]\+/hs=s+1
+syn match  muttrcRXChars	contained /[][|()][.*?+]*/
+syn match  muttrcRXChars	contained /'^/ms=s+1
+syn match  muttrcRXChars	contained /$'/me=e-1
+syn match  muttrcRXChars	contained /\\/
+" Why does muttrcRXString2 work with one \ when muttrcRXString requires two?
+syn region muttrcRXString	contained start=+'+ skip=+\\'+ end=+'+ contains=muttrcRXChars
+syn region muttrcRXString	contained start=+"+ skip=+\\"+ end=+"+ contains=muttrcRXChars
+syn region muttrcRXString2	contained start=+'+ skip=+\'+ end=+'+ contains=muttrcRXChars
+syn region muttrcRXString2	contained start=+"+ skip=+\"+ end=+"+ contains=muttrcRXChars
+
+syn region muttrcRXPat		contained start=+'+ skip=+\\'+ end=+'\s*+ keepend skipwhite contains=muttrcRXString nextgroup=muttrcRXPat
+syn region muttrcRXPat		contained start=+"+ skip=+\\"+ end=+"\s*+ keepend skipwhite contains=muttrcRXString nextgroup=muttrcRXPat
+syn match muttrcRXPat		contained /[^-'"#!]\S\+\%(\s\|$\)/ skipwhite contains=muttrcRXChars nextgroup=muttrcRXPat
+syn match muttrcRXDef 		contained "-rx\s\+" skipwhite nextgroup=muttrcRXPat
+
+syn match muttrcSpecial		+\(['"]\)!\1+
+
+" Numbers and Quadoptions may be surrounded by " or '
+syn match muttrcNumber		/=\s*\d\+/lc=1
+syn match muttrcNumber		/=\s*"\d\+"/lc=1
+syn match muttrcNumber		/=\s*'\d\+'/lc=1
+syn match muttrcQuadopt		+=\s*\%(ask-\)\=\%(yes\|no\)+lc=1
+syn match muttrcQuadopt		+=\s*"\%(ask-\)\=\%(yes\|no\)"+lc=1
+syn match muttrcQuadopt		+=\s*'\%(ask-\)\=\%(yes\|no\)'+lc=1
+
+" Now catch some email addresses and headers (purified version from mail.vim)
+syn match muttrcEmail		"[a-zA-Z0-9._-]\+@[a-zA-Z0-9./-]\+"
+syn match muttrcHeader		"\<\%(From\|To\|C[Cc]\|B[Cc][Cc]\|Reply-To\|Subject\|Return-Path\|Received\|Date\|Replied\|Attach\)\>:\="
+
+syn match   muttrcKeySpecial	contained +\%(\\[Cc'"]\|\^\|\\[01]\d\{2}\)+
+syn match   muttrcKey		contained "\S\+"			contains=muttrcKeySpecial,muttrcKeyName
+syn region  muttrcKey		contained start=+"+ skip=+\\\\\|\\"+ end=+"+	contains=muttrcKeySpecial,muttrcKeyName
+syn region  muttrcKey		contained start=+'+ skip=+\\\\\|\\'+ end=+'+	contains=muttrcKeySpecial,muttrcKeyName
+syn match   muttrcKeyName	contained "\<f\%(\d\|10\)\>"
+syn match   muttrcKeyName	contained "\\[trne]"
+syn match   muttrcKeyName	contained "\c<\%(BackSpace\|Delete\|Down\|End\|Enter\|Esc\|Home\|Insert\|Left\|PageDown\|PageUp\|Return\|Right\|Space\|Tab\|Up\)>"
+
+syn keyword muttrcVarBool	contained allow_8bit allow_ansi arrow_cursor ascii_chars askbcc
+syn keyword muttrcVarBool	contained askcc attach_split auto_tag autoedit beep beep_new
+syn keyword muttrcVarBool	contained bounce_delivered braille_friendly check_new collapse_unread
+syn keyword muttrcVarBool	contained confirmappend confirmcreate crypt_autoencrypt crypt_autopgp
+syn keyword muttrcVarBool	contained crypt_autosign crypt_autosmime crypt_replyencrypt
+syn keyword muttrcVarBool	contained crypt_replysign crypt_replysignencrypted crypt_timestamp
+syn keyword muttrcVarBool	contained crypt_use_gpgme delete_untag digest_collapse duplicate_threads
+syn keyword muttrcVarBool	contained edit_hdrs edit_headers encode_from envelope_from fast_reply
+syn keyword muttrcVarBool	contained fcc_attach fcc_clear followup_to force_name forw_decode
+syn keyword muttrcVarBool	contained forw_decrypt forw_quote forward_decode forward_decrypt
+syn keyword muttrcVarBool	contained forward_quote hdrs header help hidden_host hide_limited
+syn keyword muttrcVarBool	contained hide_missing hide_thread_subject hide_top_limited
+syn keyword muttrcVarBool	contained hide_top_missing ignore_list_reply_to imap_check_subscribed
+syn keyword muttrcVarBool	contained imap_list_subscribed imap_passive imap_peek imap_servernoise
+syn keyword muttrcVarBool	contained implicit_autoview include_onlyfirst keep_flagged
+syn keyword muttrcVarBool	contained mailcap_sanitize maildir_header_cache_verify maildir_trash
+syn keyword muttrcVarBool	contained mark_old markers menu_move_off menu_scroll meta_key
+syn keyword muttrcVarBool	contained metoo mh_purge mime_forward_decode narrow_tree pager_stop
+syn keyword muttrcVarBool	contained pgp_auto_decode pgp_auto_traditional pgp_autoencrypt
+syn keyword muttrcVarBool	contained pgp_autoinline pgp_autosign pgp_check_exit
+syn keyword muttrcVarBool	contained pgp_create_traditional pgp_ignore_subkeys pgp_long_ids
+syn keyword muttrcVarBool	contained pgp_replyencrypt pgp_replyinline pgp_replysign
+syn keyword muttrcVarBool	contained pgp_replysignencrypted pgp_retainable_sigs pgp_show_unusable
+syn keyword muttrcVarBool	contained pgp_strict_enc pgp_use_gpg_agent pipe_decode pipe_split
+syn keyword muttrcVarBool	contained pop_auth_try_all pop_last print_decode print_split
+syn keyword muttrcVarBool	contained prompt_after read_only reply_self resolve reverse_alias
+syn keyword muttrcVarBool	contained reverse_name reverse_realname rfc2047_parameters save_address
+syn keyword muttrcVarBool	contained save_empty save_name score sig_dashes sig_on_top
+syn keyword muttrcVarBool	contained smart_wrap smime_ask_cert_label smime_decrypt_use_default_key
+syn keyword muttrcVarBool	contained smime_is_default sort_re ssl_force_tls ssl_use_sslv2
+syn keyword muttrcVarBool	contained ssl_use_sslv3 ssl_use_tlsv1 ssl_usesystemcerts status_on_top
+syn keyword muttrcVarBool	contained strict_mime strict_threads suspend text_flowed thorough_search
+syn keyword muttrcVarBool	contained thread_received tilde uncollapse_jump use_8bitmime
+syn keyword muttrcVarBool	contained use_domain use_envelope_from use_from use_idn use_ipv6
+syn keyword muttrcVarBool	contained user_agent wait_key weed wrap_search write_bcc
+
+syn keyword muttrcVarBool	contained noallow_8bit noallow_ansi noarrow_cursor noascii_chars noaskbcc
+syn keyword muttrcVarBool	contained noaskcc noattach_split noauto_tag noautoedit nobeep nobeep_new
+syn keyword muttrcVarBool	contained nobounce_delivered nobraille_friendly nocheck_new nocollapse_unread
+syn keyword muttrcVarBool	contained noconfirmappend noconfirmcreate nocrypt_autoencrypt nocrypt_autopgp
+syn keyword muttrcVarBool	contained nocrypt_autosign nocrypt_autosmime nocrypt_replyencrypt
+syn keyword muttrcVarBool	contained nocrypt_replysign nocrypt_replysignencrypted nocrypt_timestamp
+syn keyword muttrcVarBool	contained nocrypt_use_gpgme nodelete_untag nodigest_collapse noduplicate_threads
+syn keyword muttrcVarBool	contained noedit_hdrs noedit_headers noencode_from noenvelope_from nofast_reply
+syn keyword muttrcVarBool	contained nofcc_attach nofcc_clear nofollowup_to noforce_name noforw_decode
+syn keyword muttrcVarBool	contained noforw_decrypt noforw_quote noforward_decode noforward_decrypt
+syn keyword muttrcVarBool	contained noforward_quote nohdrs noheader nohelp nohidden_host nohide_limited
+syn keyword muttrcVarBool	contained nohide_missing nohide_thread_subject nohide_top_limited
+syn keyword muttrcVarBool	contained nohide_top_missing noignore_list_reply_to noimap_check_subscribed
+syn keyword muttrcVarBool	contained noimap_list_subscribed noimap_passive noimap_peek noimap_servernoise
+syn keyword muttrcVarBool	contained noimplicit_autoview noinclude_onlyfirst nokeep_flagged
+syn keyword muttrcVarBool	contained nomailcap_sanitize nomaildir_header_cache_verify nomaildir_trash
+syn keyword muttrcVarBool	contained nomark_old nomarkers nomenu_move_off nomenu_scroll nometa_key
+syn keyword muttrcVarBool	contained nometoo nomh_purge nomime_forward_decode nonarrow_tree nopager_stop
+syn keyword muttrcVarBool	contained nopgp_auto_decode nopgp_auto_traditional nopgp_autoencrypt
+syn keyword muttrcVarBool	contained nopgp_autoinline nopgp_autosign nopgp_check_exit
+syn keyword muttrcVarBool	contained nopgp_create_traditional nopgp_ignore_subkeys nopgp_long_ids
+syn keyword muttrcVarBool	contained nopgp_replyencrypt nopgp_replyinline nopgp_replysign
+syn keyword muttrcVarBool	contained nopgp_replysignencrypted nopgp_retainable_sigs nopgp_show_unusable
+syn keyword muttrcVarBool	contained nopgp_strict_enc nopgp_use_gpg_agent nopipe_decode nopipe_split
+syn keyword muttrcVarBool	contained nopop_auth_try_all nopop_last noprint_decode noprint_split
+syn keyword muttrcVarBool	contained noprompt_after noread_only noreply_self noresolve noreverse_alias
+syn keyword muttrcVarBool	contained noreverse_name noreverse_realname norfc2047_parameters nosave_address
+syn keyword muttrcVarBool	contained nosave_empty nosave_name noscore nosig_dashes nosig_on_top
+syn keyword muttrcVarBool	contained nosmart_wrap nosmime_ask_cert_label nosmime_decrypt_use_default_key
+syn keyword muttrcVarBool	contained nosmime_is_default nosort_re nossl_force_tls nossl_use_sslv2
+syn keyword muttrcVarBool	contained nossl_use_sslv3 nossl_use_tlsv1 nossl_usesystemcerts nostatus_on_top
+syn keyword muttrcVarBool	contained nostrict_threads nosuspend notext_flowed nothorough_search
+syn keyword muttrcVarBool	contained nothread_received notilde nouncollapse_jump nouse_8bitmime
+syn keyword muttrcVarBool	contained nouse_domain nouse_envelope_from nouse_from nouse_idn nouse_ipv6
+syn keyword muttrcVarBool	contained nouser_agent nowait_key noweed nowrap_search nowrite_bcc
+
+syn keyword muttrcVarBool	contained invallow_8bit invallow_ansi invarrow_cursor invascii_chars invaskbcc
+syn keyword muttrcVarBool	contained invaskcc invattach_split invauto_tag invautoedit invbeep invbeep_new
+syn keyword muttrcVarBool	contained invbounce_delivered invbraille_friendly invcheck_new invcollapse_unread
+syn keyword muttrcVarBool	contained invconfirmappend invconfirmcreate invcrypt_autoencrypt invcrypt_autopgp
+syn keyword muttrcVarBool	contained invcrypt_autosign invcrypt_autosmime invcrypt_replyencrypt
+syn keyword muttrcVarBool	contained invcrypt_replysign invcrypt_replysignencrypted invcrypt_timestamp
+syn keyword muttrcVarBool	contained invcrypt_use_gpgme invdelete_untag invdigest_collapse invduplicate_threads
+syn keyword muttrcVarBool	contained invedit_hdrs invedit_headers invencode_from invenvelope_from invfast_reply
+syn keyword muttrcVarBool	contained invfcc_attach invfcc_clear invfollowup_to invforce_name invforw_decode
+syn keyword muttrcVarBool	contained invforw_decrypt invforw_quote invforward_decode invforward_decrypt
+syn keyword muttrcVarBool	contained invforward_quote invhdrs invheader invhelp invhidden_host invhide_limited
+syn keyword muttrcVarBool	contained invhide_missing invhide_thread_subject invhide_top_limited
+syn keyword muttrcVarBool	contained invhide_top_missing invignore_list_reply_to invimap_check_subscribed
+syn keyword muttrcVarBool	contained invimap_list_subscribed invimap_passive invimap_peek invimap_servernoise
+syn keyword muttrcVarBool	contained invimplicit_autoview invinclude_onlyfirst invkeep_flagged
+syn keyword muttrcVarBool	contained invmailcap_sanitize invmaildir_header_cache_verify invmaildir_trash
+syn keyword muttrcVarBool	contained invmark_old invmarkers invmenu_move_off invmenu_scroll invmeta_key
+syn keyword muttrcVarBool	contained invmetoo invmh_purge invmime_forward_decode invnarrow_tree invpager_stop
+syn keyword muttrcVarBool	contained invpgp_auto_decode invpgp_auto_traditional invpgp_autoencrypt
+syn keyword muttrcVarBool	contained invpgp_autoinline invpgp_autosign invpgp_check_exit
+syn keyword muttrcVarBool	contained invpgp_create_traditional invpgp_ignore_subkeys invpgp_long_ids
+syn keyword muttrcVarBool	contained invpgp_replyencrypt invpgp_replyinline invpgp_replysign
+syn keyword muttrcVarBool	contained invpgp_replysignencrypted invpgp_retainable_sigs invpgp_show_unusable
+syn keyword muttrcVarBool	contained invpgp_strict_enc invpgp_use_gpg_agent invpipe_decode invpipe_split
+syn keyword muttrcVarBool	contained invpop_auth_try_all invpop_last invprint_decode invprint_split
+syn keyword muttrcVarBool	contained invprompt_after invread_only invreply_self invresolve invreverse_alias
+syn keyword muttrcVarBool	contained invreverse_name invreverse_realname invrfc2047_parameters invsave_address
+syn keyword muttrcVarBool	contained invsave_empty invsave_name invscore invsig_dashes invsig_on_top
+syn keyword muttrcVarBool	contained invsmart_wrap invsmime_ask_cert_label invsmime_decrypt_use_default_key
+syn keyword muttrcVarBool	contained invsmime_is_default invsort_re invssl_force_tls invssl_use_sslv2
+syn keyword muttrcVarBool	contained invssl_use_sslv3 invssl_use_tlsv1 invssl_usesystemcerts invstatus_on_top
+syn keyword muttrcVarBool	contained invstrict_threads invsuspend invtext_flowed invthorough_search
+syn keyword muttrcVarBool	contained invthread_received invtilde invuncollapse_jump invuse_8bitmime
+syn keyword muttrcVarBool	contained invuse_domain invuse_envelope_from invuse_from invuse_idn invuse_ipv6
+syn keyword muttrcVarBool	contained invuser_agent invwait_key invweed invwrap_search invwrite_bcc
+
+syn keyword muttrcVarQuad	contained abort_nosubject abort_unmodified bounce copy
+syn keyword muttrcVarQuad	contained crypt_verify_sig delete forward_edit honor_followup_to
+syn keyword muttrcVarQuad	contained include mime_forward mime_forward_rest mime_fwd move
+syn keyword muttrcVarQuad	contained pgp_mime_auto pgp_verify_sig pop_delete pop_reconnect
+syn keyword muttrcVarQuad	contained postpone print quit recall reply_to ssl_starttls
+
+syn keyword muttrcVarQuad	contained noabort_nosubject noabort_unmodified nobounce nocopy
+syn keyword muttrcVarQuad	contained nocrypt_verify_sig nodelete noforward_edit nohonor_followup_to
+syn keyword muttrcVarQuad	contained noinclude nomime_forward nomime_forward_rest nomime_fwd nomove
+syn keyword muttrcVarQuad	contained nopgp_mime_auto nopgp_verify_sig nopop_delete nopop_reconnect
+syn keyword muttrcVarQuad	contained nopostpone noprint noquit norecall noreply_to nossl_starttls
+
+syn keyword muttrcVarQuad	contained invabort_nosubject invabort_unmodified invbounce invcopy
+syn keyword muttrcVarQuad	contained invcrypt_verify_sig invdelete invforward_edit invhonor_followup_to
+syn keyword muttrcVarQuad	contained invinclude invmime_forward invmime_forward_rest invmime_fwd invmove
+syn keyword muttrcVarQuad	contained invpgp_mime_auto invpgp_verify_sig invpop_delete invpop_reconnect
+syn keyword muttrcVarQuad	contained invpostpone invprint invquit invrecall invreply_to invssl_starttls
+
+syn keyword muttrcVarNum	contained connect_timeout history imap_keepalive mail_check menu_context net_inc
+syn keyword muttrcVarNum	contained pager_context pager_index_lines pgp_timeout pop_checkinterval read_inc
+syn keyword muttrcVarNum	contained save_history score_threshold_delete score_threshold_flag
+syn keyword muttrcVarNum	contained score_threshold_read sendmail_wait sleep_time smime_timeout
+syn keyword muttrcVarNum	contained ssl_min_dh_prime_bits timeout wrap wrapmargin write_inc
+
+syn match muttrcVarStr		contained 'my_[a-zA-Z0-9_]\+'
+syn keyword muttrcVarStr	contained alias_file alias_format assumed_charset attach_format attach_sep attribution
+syn keyword muttrcVarStr	contained certificate_file charset compose_format config_charset content_type
+syn keyword muttrcVarStr	contained date_format default_hook display_filter dotlock_program dsn_notify
+syn keyword muttrcVarStr	contained dsn_return editor entropy_file envelope_from_address escape folder
+syn keyword muttrcVarStr	contained folder_format forw_format forward_format from gecos_mask hdr_format
+syn keyword muttrcVarStr	contained header_cache header_cache_pagesize history_file hostname imap_authenticators
+syn keyword muttrcVarStr	contained imap_delim_chars imap_headers imap_home_namespace imap_idle imap_login imap_pass
+syn keyword muttrcVarStr	contained imap_user indent_str indent_string index_format ispell locale mailcap_path
+syn keyword muttrcVarStr	contained mask mbox mbox_type message_format message_cachedir mh_seq_flagged mh_seq_replied
+syn keyword muttrcVarStr	contained mh_seq_unseen mix_entry_format mixmaster msg_format pager pager_format
+syn keyword muttrcVarStr	contained pgp_clearsign_command pgp_decode_command pgp_decrypt_command
+syn keyword muttrcVarStr	contained pgp_encrypt_only_command pgp_encrypt_sign_command pgp_entry_format
+syn keyword muttrcVarStr	contained pgp_export_command pgp_getkeys_command pgp_good_sign pgp_import_command
+syn keyword muttrcVarStr	contained pgp_list_pubring_command pgp_list_secring_command pgp_mime_signature_filename
+syn keyword muttrcVarStr	contained pgp_mime_signature_description pgp_sign_as
+syn keyword muttrcVarStr	contained pgp_sign_command pgp_sort_keys pgp_verify_command pgp_verify_key_command
+syn keyword muttrcVarStr	contained pipe_sep pop_authenticators pop_host pop_pass pop_user post_indent_str
+syn keyword muttrcVarStr	contained post_indent_string postponed preconnect print_cmd print_command
+syn keyword muttrcVarStr	contained query_command quote_regexp realname record reply_regexp send_charset
+syn keyword muttrcVarStr	contained sendmail shell signature simple_search smileys smime_ca_location
+syn keyword muttrcVarStr	contained smime_certificates smime_decrypt_command smime_default_key
+syn keyword muttrcVarStr	contained smime_encrypt_command smime_encrypt_with smime_get_cert_command
+syn keyword muttrcVarStr	contained smime_get_cert_email_command smime_get_signer_cert_command
+syn keyword muttrcVarStr	contained smime_import_cert_command smime_keys smime_pk7out_command smime_sign_as
+syn keyword muttrcVarStr	contained smime_sign_command smime_sign_opaque_command smime_verify_command
+syn keyword muttrcVarStr	contained smime_verify_opaque_command smtp_url smtp_authenticators sort sort_alias sort_aux
+syn keyword muttrcVarStr	contained sort_browser spam_separator spoolfile ssl_ca_certificates_file ssl_client_cert
+syn keyword muttrcVarStr	contained status_chars status_format tmpdir to_chars tunnel visual
+
+" Present in 1.4.2.1 (pgp_create_traditional was a bool then)
+syn keyword muttrcVarBool	contained imap_force_ssl imap_force_ssl noinvimap_force_ssl
+"syn keyword muttrcVarQuad	contained pgp_create_traditional nopgp_create_traditional invpgp_create_traditional
+syn keyword muttrcVarStr	contained alternates
+
+syn keyword muttrcMenu		contained alias attach browser compose editor index pager postpone pgp mix query generic
+syn match muttrcMenuList "\S\+" contained contains=muttrcMenu
+syn match muttrcMenuCommas /,/ contained
+
+syn keyword muttrcCommand	auto_view alternative_order charset-hook exec unalternative_order
+syn keyword muttrcCommand	hdr_order iconv-hook ignore mailboxes my_hdr unmailboxes
+syn keyword muttrcCommand	pgp-hook push score source unauto_view unhdr_order
+syn keyword muttrcCommand	unignore unmono unmy_hdr unscore
+syn keyword muttrcCommand	mime_lookup unmime_lookup spam ungroup
+syn keyword muttrcCommand	nospam unalternative_order
+
+syn keyword muttrcHooks		contained account-hook charset-hook iconv-hook message-hook folder-hook mbox-hook save-hook fcc-hook fcc-save-hook send-hook send2-hook reply-hook crypt-hook
+syn keyword muttrcUnhook	contained unhook
+syn region muttrcUnhookLine	keepend start=+^\s*unhook\s+ skip=+\\$+ end=+$+ contains=muttrcUnhook,muttrcHooks,muttrcUnHighlightSpace,muttrcComment
+
+syn match muttrcAttachmentsMimeType contained "[*a-z0-9_-]\+/[*a-z0-9._-]\+\s*" skipwhite nextgroup=muttrcAttachmentsMimeType
+syn match muttrcAttachmentsFlag contained "[+-]\%([AI]\|inline\|attachment\)\s\+" skipwhite nextgroup=muttrcAttachmentsMimeType
+syn match muttrcAttachmentsLine "^\s*\%(un\)\?attachments\s\+" skipwhite nextgroup=muttrcAttachmentsFlag
+
+syn match muttrcUnHighlightSpace contained "\%(\s\+\|\\$\)"
+
+syn keyword muttrcListsKeyword	contained lists unlists
+syn region muttrcListsLine	keepend start=+^\s*\%(un\)\?lists\s+ skip=+\\$+ end=+$+ contains=muttrcListsKeyword,muttrcRXPat,muttrcGroupDef,muttrcUnHighlightSpace,muttrcComment
+
+syn keyword muttrcSubscribeKeyword	contained subscribe unsubscribe
+syn region muttrcSubscribeLine 	keepend start=+^\s*\%(un\)\?subscribe\s+ skip=+\\$+ end=+$+ contains=muttrcSubscribeKeyword,muttrcRXPat,muttrcGroupDef,muttrcUnHighlightSpace,muttrcComment
+
+syn keyword muttrcAlternateKeyword contained alternates unalternates
+syn region muttrcAlternatesLine keepend start=+^\s*\%(un\)\?alternates\s+ skip=+\\$+ end=+$+ contains=muttrcAlternateKeyword,muttrcGroupDef,muttrcRXPat,muttrcUnHighlightSpace,muttrcComment
+
+syn match muttrcVariable	"\$[a-zA-Z_-]\+"
+
+syn match muttrcBadAction	contained "[^<>]\+" contains=muttrcEmail
+syn match muttrcFunction	contained "\<\%(attach\|bounce\|copy\|delete\|display\|flag\|forward\|parent\|pipe\|postpone\|print\|recall\|resent\|save\|send\|tag\|undelete\)-message\>"
+syn match muttrcFunction	contained "\<\%(delete\|next\|previous\|read\|tag\|undelete\)-thread\>"
+syn match muttrcFunction	contained "\<\%(backward\|capitalize\|downcase\|forward\|kill\|upcase\)-word\>"
+syn match muttrcFunction	contained "\<\%(delete\|filter\|first\|last\|next\|pipe\|previous\|print\|save\|select\|tag\|undelete\)-entry\>"
+syn match muttrcFunction	contained "\<attach-\%(file\|key\)\>"
+syn match muttrcFunction	contained "\<change-\%(dir\|folder\|folder-readonly\)\>"
+syn match muttrcFunction	contained "\<check-\%(new\|traditional-pgp\)\>"
+syn match muttrcFunction	contained "\<current-\%(bottom\|middle\|top\)\>"
+syn match muttrcFunction	contained "\<decode-\%(copy\|save\)\>"
+syn match muttrcFunction	contained "\<delete-\%(char\|pattern\|subthread\)\>"
+syn match muttrcFunction	contained "\<display-\%(address\|toggle-weed\)\>"
+syn match muttrcFunction	contained "\<edit\%(-\%(bcc\|cc\|description\|encoding\|fcc\|file\|from\|headers\|mime\|reply-to\|subject\|to\|type\)\)\?\>"
+syn match muttrcFunction	contained "\<enter-\%(command\|mask\)\>"
+syn match muttrcFunction	contained "\<half-\%(up\|down\)\>"
+syn match muttrcFunction	contained "\<history-\%(up\|down\)\>"
+syn match muttrcFunction	contained "\<kill-\%(eol\|eow\|line\)\>"
+syn match muttrcFunction	contained "\<next-\%(line\|new\|page\|subthread\|undeleted\|unread\)\>"
+syn match muttrcFunction	contained "\<previous-\%(line\|new\|page\|subthread\|undeleted\|unread\)\>"
+syn match muttrcFunction	contained "\<search\%(-\%(next\|opposite\|reverse\|toggle\)\)\?\>"
+syn match muttrcFunction	contained "\<show-\%(limit\|version\)\>"
+syn match muttrcFunction	contained "\<sort-\%(mailbox\|reverse\)\>"
+syn match muttrcFunction	contained "\<tag-\%(pattern\|prefix\%(-cond\)\?\)\>"
+syn match muttrcFunction	contained "\<toggle-\%(mailboxes\|new\|quoted\|subscribed\|unlink\|write\)\>"
+syn match muttrcFunction	contained "\<undelete-\%(pattern\|subthread\)\>"
+syn match muttrcFunction	contained "\<collapse-\%(parts\|thread\|all\)\>"
+syn match muttrcFunction	contained "\<view-\%(attach\|attachments\|file\|mailcap\|name\|text\)\>"
+syn match muttrcFunction	contained "\<\%(backspace\|backward-char\|bol\|bottom\|bottom-page\|buffy-cycle\|clear-flag\|complete\%(-query\)\?\|copy-file\|create-alias\|detach-file\|eol\|exit\|extract-keys\|\%(imap-\)\?fetch-mail\|forget-passphrase\|forward-char\|group-reply\|help\|ispell\|jump\|limit\|list-reply\|mail\|mail-key\|mark-as-new\|middle-page\|new-mime\|noop\|pgp-menu\|query\|query-append\|quit\|quote-char\|read-subthread\|redraw-screen\|refresh\|rename-file\|reply\|select-new\|set-flag\|shell-escape\|skip-quoted\|sort\|subscribe\|sync-mailbox\|top\|top-page\|transpose-chars\|unsubscribe\|untag-pattern\|verify-key\|what-key\|write-fcc\)\>"
+syn match muttrcAction		contained "<[^>]\{-}>" contains=muttrcBadAction,muttrcFunction,muttrcKeyName
+
+syn keyword muttrcSet		set     skipwhite nextgroup=muttrcVar.*
+syn keyword muttrcUnset		unset   skipwhite nextgroup=muttrcVar.*
+syn keyword muttrcReset		reset   skipwhite nextgroup=muttrcVar.*
+syn keyword muttrcToggle	toggle  skipwhite nextgroup=muttrcVar.*
+
+" First, functions that take regular expressions:
+syn match  muttrcRXHookNot	contained /!\s*/ skipwhite nextgroup=muttrcRXString
+syn match  muttrcRXHooks	/^\s*\%(account\|folder\)-hook\s\+/ skipwhite nextgroup=muttrcRXHookNot,muttrcRXString
+
+" Now, functions that take patterns
+syn match muttrcPatHookNot	contained /!\s*/ skipwhite nextgroup=muttrcPattern
+syn match muttrcPatHooks	/^\s*\%(message\|mbox\|save\|fcc\%(-save\)\?\|send2\?\|reply\|crypt\)-hook\s\+/ nextgroup=muttrcPatHookNot,muttrcPattern
+
+syn match muttrcBindFunction	contained /\S\+\%(\s\|$\)/ skipwhite contains=muttrcFunction
+syn match muttrcBindFunctionNL	contained /\s*\\$/ skipwhite skipnl nextgroup=muttrcBindFunction,muttrcBindFunctionNL
+syn match muttrcBindKey		contained /\S\+/ skipwhite contains=muttrcKey nextgroup=muttrcBindFunction,muttrcBindFunctionNL
+syn match muttrcBindKeyNL	contained /\s*\\$/ skipwhite skipnl nextgroup=muttrcBindKey,muttrcBindKeyNL
+syn match muttrcBindMenuList	contained /\S\+/ skipwhite contains=muttrcMenu,muttrcMenuCommas nextgroup=muttrcBindKey,muttrcBindKeyNL
+syn match muttrcBindMenuListNL	contained /\s*\\$/ skipwhite skipnl nextgroup=muttrcBindMenuList,muttrcBindMenuListNL
+syn match muttrcBind		/^\s*bind\s\?/ skipwhite nextgroup=muttrcBindMenuList,muttrcBindMenuListNL
+
+syn region muttrcMacroDescr	contained keepend skipwhite start=+\s*\S+ms=e skip=+\\ + end=+ \|$+me=s
+syn region muttrcMacroDescr	contained keepend skipwhite start=+'+ms=e skip=+\\'+ end=+'+me=s
+syn region muttrcMacroDescr	contained keepend skipwhite start=+"+ms=e skip=+\\"+ end=+"+me=s
+syn match muttrcMacroDescrNL	contained /\s*\\$/ skipwhite skipnl nextgroup=muttrcMacroDescr,muttrcMacroDescrNL
+syn region muttrcMacroBody	contained skipwhite start="\S" skip='\\ \|\\$' end=' \|$' contains=muttrcEscape,muttrcSet,muttrcUnset,muttrcReset,muttrcToggle,muttrcCommand,muttrcAction nextgroup=muttrcMacroDescr,muttrcMacroDescrNL
+syn region muttrcMacroBody matchgroup=Type contained skipwhite start=+'+ms=e skip=+\\'+ end=+'+me=s contains=muttrcEscape,muttrcSet,muttrcUnset,muttrcReset,muttrcToggle,muttrcCommand,muttrcAction nextgroup=muttrcMacroDescr,muttrcMacroDescrNL
+syn region muttrcMacroBody matchgroup=Type contained skipwhite start=+"+ms=e skip=+\\"+ end=+"+me=s contains=muttrcEscape,muttrcSet,muttrcUnset,muttrcReset,muttrcToggle,muttrcCommand,muttrcAction nextgroup=muttrcMacroDescr,muttrcMacroDescrNL
+syn match muttrcMacroBodyNL	contained /\s*\\$/ skipwhite skipnl nextgroup=muttrcMacroBody,muttrcMacroBodyNL
+syn match muttrcMacroKey	contained /\S\+/ skipwhite contains=muttrcKey nextgroup=muttrcMacroBody,muttrcMacroBodyNL
+syn match muttrcMacroKeyNL	contained /\s*\\$/ skipwhite skipnl nextgroup=muttrcMacroKey,muttrcMacroKeyNL
+syn match muttrcMacroMenuList	contained /\S\+/ skipwhite contains=muttrcMenu,muttrcMenuCommas nextgroup=muttrcMacroKey,muttrcMacroKeyNL
+syn match muttrcMacroMenuListNL	contained /\s*\\$/ skipwhite skipnl nextgroup=muttrcMacroMenuList,muttrcMacroMenuListNL
+syn match muttrcMacro		/^\s*macro\s\?/	skipwhite nextgroup=muttrcMacroMenuList,muttrcMacroMenuListNL
+
+syn match muttrcAddrContent	contained "[a-zA-Z0-9._-]\+@[a-zA-Z0-9./-]\+\s*" skipwhite contains=muttrcEmail nextgroup=muttrcAddrContent
+syn region muttrcAddrContent	contained start=+'+ end=+'\s*+ skip=+\\'+ skipwhite contains=muttrcEmail nextgroup=muttrcAddrContent
+syn region muttrcAddrContent	contained start=+"+ end=+"\s*+ skip=+\\"+ skipwhite contains=muttrcEmail nextgroup=muttrcAddrContent
+syn match muttrcAddrDef 	contained "-addr\s\+" skipwhite nextgroup=muttrcAddrContent
+
+syn match muttrcGroupFlag	contained "-group"
+syn region muttrcGroupDef	contained start="-group\s\+" skip="\\$" end="\s" skipwhite keepend contains=muttrcGroupFlag,muttrcUnHighlightSpace
+
+syn keyword muttrcGroupKeyword	contained group ungroup
+syn region muttrcGroupLine	keepend start=+^\s*\%(un\)\?group\s+ skip=+\\$+ end=+$+ contains=muttrcGroupKeyword,muttrcGroupDef,muttrcAddrDef,muttrcRXDef,muttrcUnHighlightSpace,muttrcComment
+
+syn match muttrcAliasGroupName	contained /\w\+/ skipwhite nextgroup=muttrcAliasGroupDef,muttrcAliasKey,muttrcAliasNL
+syn match muttrcAliasGroupDefNL	contained /\s*\\$/ skipwhite skipnl nextgroup=muttrcAliasGroupName,muttrcAliasGroupDefNL
+syn match muttrcAliasGroupDef	contained /\s*-group/ skipwhite nextgroup=muttrcAliasGroupName,muttrcAliasGroupDefNL contains=muttrcGroupFlag
+syn match muttrcAliasComma	contained /,/ skipwhite nextgroup=muttrcAliasEmail,muttrcAliasEncEmail,muttrcAliasNameNoParens,muttrcAliasENNL
+syn match muttrcAliasEmail	contained /\S\+@\S\+/ contains=muttrcEmail nextgroup=muttrcAliasName,muttrcAliasNameNL skipwhite
+syn match muttrcAliasEncEmail	contained /<[^>]\+>/ contains=muttrcEmail nextgroup=muttrcAliasComma
+syn match muttrcAliasEncEmailNL	contained /\s*\\$/ skipwhite skipnl nextgroup=muttrcAliasEncEmail,muttrcAliasEncEmailNL
+syn match muttrcAliasNameNoParens contained /[^<(@]\+\s\+/ nextgroup=muttrcAliasEncEmail,muttrcAliasEncEmailNL
+syn region muttrcAliasName	contained matchgroup=Type start=/(/ end=/)/ skipwhite
+syn match muttrcAliasNameNL	contained /\s*\\$/ skipwhite skipnl nextgroup=muttrcAliasName,muttrcAliasNameNL
+syn match muttrcAliasENNL	contained /\s*\\$/ skipwhite skipnl nextgroup=muttrcAliasEmail,muttrcAliasEncEmail,muttrcAliasNameNoParens,muttrcAliasENNL
+syn match muttrcAliasKey	contained /\s*[^- \t]\S\+/ skipwhite nextgroup=muttrcAliasEmail,muttrcAliasEncEmail,muttrcAliasNameNoParens,muttrcAliasENNL
+syn match muttrcAliasNL		contained /\s*\\$/ skipwhite skipnl nextgroup=muttrcAliasGroupDef,muttrcAliasKey,muttrcAliasNL
+syn match muttrcAlias		/^\s*alias\s/ skipwhite nextgroup=muttrcAliasGroupDef,muttrcAliasKey,muttrcAliasNL
+
+syn match muttrcUnAliasKey	contained "\s*\w\+\s*" skipwhite nextgroup=muttrcUnAliasKey,muttrcUnAliasNL
+syn match muttrcUnAliasNL	contained /\s*\\$/ skipwhite skipnl nextgroup=muttrcUnAliasKey,muttrcUnAliasNL
+syn match muttrcUnAlias		/^\s*unalias\s\?/ nextgroup=muttrcUnAliasKey,muttrcUnAliasNL
+
+syn match muttrcSimplePat contained "!\?\^\?[~][ADEFgGklNOpPQRSTuUvV=$]"
+syn match muttrcSimplePat contained "!\?\^\?[~][mnXz]\s\+\%([<>-][0-9]\+\|[0-9]\+[-][0-9]*\)"
+syn match muttrcSimplePat contained "!\?\^\?[~][dr]\s\+\%(\%(-\?[0-9]\{1,2}\%(/[0-9]\{1,2}\%(/[0-9]\{2}\%([0-9]\{2}\)\?\)\?\)\?\%([+*-][0-9]\+[ymwd]\)*\)\|\%(\%([0-9]\{1,2}\%(/[0-9]\{1,2}\%(/[0-9]\{2}\%([0-9]\{2}\)\?\)\?\)\?\%([+*-][0-9]\+[ymwd]\)*\)-\%([0-9]\{1,2}\%(/[0-9]\{1,2}\%(/[0-9]\{2}\%([0-9]\{2}\)\?\)\?\)\?\%([+*-][0-9]\+[ymwd]\)\?\)\?\)\|\%([<>=][0-9]\+[ymwd]\)\)"
+syn match muttrcSimplePat contained "!\?\^\?[~][bBcCefhHiLstxy]\s\+" nextgroup=muttrcSimplePatRXContainer
+syn match muttrcSimplePat contained "!\?\^\?[%][bBcCefhHiLstxy]\s\+" nextgroup=muttrcSimplePatString
+syn match muttrcSimplePat contained "!\?\^\?[=][bh]\s\+" nextgroup=muttrcSimplePatString
+"syn match muttrcSimplePat contained /"[^~=%][^"]*/ contains=muttrcRXPat
+"syn match muttrcSimplePat contained /'[^~=%][^']*/ contains=muttrcRXPat
+syn match muttrcSimplePatString contained /[a-zA-Z0-9]\+/
+syn region muttrcSimplePatString contained keepend start=+"+ end=+"+ skip=+\\"+
+syn region muttrcSimplePatString contained keepend start=+'+ end=+'+ skip=+\\'+
+syn region muttrcSimplePatRXContainer contained keepend start=+"+ end=+"+ skip=+\\"+ contains=muttrcRXPat
+syn region muttrcSimplePatRXContainer contained keepend start=+'+ end=+'+ skip=+\\'+ contains=muttrcRXPat
+syn match muttrcSimplePatRXContainer contained /\S\+/ contains=muttrcRXPat
+syn match muttrcSimplePatMetas contained /[(|)]/
+
+syn region muttrcPattern contained keepend start=+"+ skip=+\\"+ end=+"+ contains=muttrcPatternInner
+syn region muttrcPattern contained keepend start=+'+ skip=+\\'+ end=+'+ contains=muttrcPatternInner
+syn match muttrcPattern contained "[~][A-Za-z]" contains=muttrcSimplePat
+syn region muttrcPatternInner contained keepend start=+"[~=%!(^]+ms=s+1 skip=+\\"+ end=+"+me=e-1 contains=muttrcSimplePat,muttrcUnHighlightSpace,muttrcSimplePatMetas
+syn region muttrcPatternInner contained keepend start=+'[~=%!(^]+ms=s+1 skip=+\\'+ end=+'+me=e-1 contains=muttrcSimplePat,muttrcUnHighlightSpace,muttrcSimplePatMetas
+
+" Colour definitions takes object, foreground and background arguments (regexps excluded).
+syn match muttrcColorMatchCount	contained "[0-9]\+"
+syn match muttrcColorMatchCountNL contained skipwhite skipnl "\s*\\$" nextgroup=muttrcColorMatchCount,muttrcColorMatchCountNL
+syn region muttrcColorRXPat	contained start=+\s*'+ skip=+\\'+ end=+'\s*+ keepend skipwhite contains=muttrcRXString2 nextgroup=muttrcColorMatchCount,muttrcColorMatchCountNL
+syn region muttrcColorRXPat	contained start=+\s*"+ skip=+\\"+ end=+"\s*+ keepend skipwhite contains=muttrcRXString2 nextgroup=muttrcColorMatchCount,muttrcColorMatchCountNL
+syn keyword muttrcColorField	contained attachment body bold error hdrdefault header index indicator markers message normal quoted search signature status tilde tree underline
+syn match   muttrcColorField	contained "\<quoted\d\=\>"
+syn keyword muttrcColor	contained black blue cyan default green magenta red white yellow
+syn keyword muttrcColor	contained brightblack brightblue brightcyan brightdefault brightgreen brightmagenta brightred brightwhite brightyellow
+syn match   muttrcColor	contained "\<\%(bright\)\=color\d\{1,2}\>"
+" Now for the structure of the color line
+syn match muttrcColorRXNL	contained skipnl "\s*\\$" nextgroup=muttrcColorRXPat,muttrcColorRXNL
+syn match muttrcColorBG 	contained /\s*[$]\?\w\+/ contains=muttrcColor,muttrcVariable,muttrcUnHighlightSpace nextgroup=muttrcColorRXPat,muttrcColorRXNL
+syn match muttrcColorBGNL	contained skipnl "\s*\\$" nextgroup=muttrcColorBG,muttrcColorBGNL
+syn match muttrcColorFG 	contained /\s*[$]\?\w\+/ contains=muttrcColor,muttrcVariable,muttrcUnHighlightSpace nextgroup=muttrcColorBG,muttrcColorBGNL
+syn match muttrcColorFGNL	contained skipnl "\s*\\$" nextgroup=muttrcColorFG,muttrcColorFGNL
+syn match muttrcColorContext 	contained /\s*[$]\?\w\+/ contains=muttrcColorField,muttrcVariable,muttrcUnHighlightSpace nextgroup=muttrcColorFG,muttrcColorFGNL
+syn match muttrcColorNL 	contained skipnl "\s*\\$" nextgroup=muttrcColorContext,muttrcColorNL
+syn match muttrcColorKeyword	contained /^\s*color\s\+/ nextgroup=muttrcColorContext,muttrcColorNL
+syn region muttrcColorLine keepend start=/^\s*color\s\+\%(index\)\@!/ skip=+\\$+ end=+$+ contains=muttrcColorKeyword,muttrcComment,muttrcUnHighlightSpace
+" Now for the structure of the color index line
+syn match muttrcPatternNL	contained skipnl "\s*\\$" nextgroup=muttrcPattern,muttrcPatternNL
+syn match muttrcColorBGI	contained /\s*[$]\?\w\+\s*/ contains=muttrcColor,muttrcVariable,muttrcUnHighlightSpace nextgroup=muttrcPattern,muttrcPatternNL
+syn match muttrcColorBGNLI	contained skipnl "\s*\\$" nextgroup=muttrcColorBGI,muttrcColorBGNLI
+syn match muttrcColorFGI	contained /\s*[$]\?\w\+/ contains=muttrcColor,muttrcVariable,muttrcUnHighlightSpace nextgroup=muttrcColorBGI,muttrcColorBGNLI
+syn match muttrcColorFGNLI	contained skipnl "\s*\\$" nextgroup=muttrcColorFGI,muttrcColorFGNLI
+syn match muttrcColorContextI	contained /\s*index/ contains=muttrcUnHighlightSpace nextgroup=muttrcColorFGI,muttrcColorFGNLI
+syn match muttrcColorNLI	contained skipnl "\s*\\$" nextgroup=muttrcColorContextI,muttrcColorNLI
+syn match muttrcColorKeywordI	contained /^\s*color\s\+/ nextgroup=muttrcColorContextI,muttrcColorNLI
+syn region muttrcColorLine keepend start=/^\s*color\s\+index/ skip=+\\$+ end=+$+ contains=muttrcColorKeywordI,muttrcComment,muttrcUnHighlightSpace
+" And now color's brother:
+syn region muttrcUnColorPatterns contained skipwhite start=+\s*'+ end=+'+ skip=+\\'+ contains=muttrcPattern nextgroup=muttrcUnColorPatterns,muttrcUnColorPatNL
+syn region muttrcUnColorPatterns contained skipwhite start=+\s*"+ end=+"+ skip=+\\"+ contains=muttrcPattern nextgroup=muttrcUnColorPatterns,muttrcUnColorPatNL
+syn match muttrcUnColorPatterns contained skipwhite /\s*[^'"\s]\S\*/ contains=muttrcPattern nextgroup=muttrcUnColorPatterns,muttrcUnColorPatNL
+syn match muttrcUnColorPatNL	contained skipwhite skipnl /\s*\\$/ nextgroup=muttrcUnColorPatterns,muttrcUnColorPatNL
+syn match muttrcUnColorAll	contained skipwhite /[*]/
+syn match muttrcUnColorAPNL	contained skipwhite skipnl /\s*\\$/ nextgroup=muttrcUnColorPatterns,muttrcUnColorAll,muttrcUnColorAPNL
+syn match muttrcUnColorIndex	contained skipwhite /\s*index\s\+/ nextgroup=muttrcUnColorPatterns,muttrcUnColorAll,muttrcUnColorAPNL
+syn match muttrcUnColorIndexNL	contained skipwhite skipnl /\s*\\$/ nextgroup=muttrcUnColorIndex,muttrcUnColorIndexNL
+syn match muttrcUnColorKeyword	contained skipwhite /^\s*uncolor\s\+/ nextgroup=muttrcUnColorIndex,muttrcUnColorIndexNL
+syn region muttrcUnColorLine keepend start=+^\s*uncolor\s+ skip=+\\$+ end=+$+ contains=muttrcUnColorKeyword,muttrcComment,muttrcUnHighlightSpace
+
+" Mono are almost like color (ojects inherited from color)
+syn keyword muttrcMonoAttrib	contained bold none normal reverse standout underline
+syn keyword muttrcMono		contained mono		skipwhite nextgroup=muttrcColorField
+syn match   muttrcMonoLine	"^\s*mono\s\+\S\+"	skipwhite nextgroup=muttrcMonoAttrib contains=muttrcMono
+
+" Define the default highlighting.
+" For version 5.7 and earlier: only when not done already
+" For version 5.8 and later: only when an item doesn't have highlighting yet
+if version >= 508 || !exists("did_muttrc_syntax_inits")
+  if version < 508
+    let did_muttrc_syntax_inits = 1
+    command -nargs=+ HiLink hi link <args>
+  else
+    command -nargs=+ HiLink hi def link <args>
+  endif
+
+  HiLink muttrcComment		Comment
+  HiLink muttrcEscape		SpecialChar
+  HiLink muttrcRXChars		SpecialChar
+  HiLink muttrcString		String
+  HiLink muttrcRXString		String
+  HiLink muttrcRXString2	String
+  HiLink muttrcSpecial		Special
+  HiLink muttrcHooks		Type
+  HiLink muttrcGroupFlag	Type
+  HiLink muttrcGroupDef		Macro
+  HiLink muttrcAddrDef		muttrcGroupFlag
+  HiLink muttrcRXDef		muttrcGroupFlag
+  HiLink muttrcRXPat		String
+  HiLink muttrcAliasGroupName	Macro
+  HiLink muttrcAliasKey	Identifier
+  HiLink muttrcUnAliasKey	Identifier
+  HiLink muttrcAliasEncEmail	Identifier
+  HiLink muttrcAliasParens	Type
+  HiLink muttrcNumber		Number
+  HiLink muttrcQuadopt		Boolean
+  HiLink muttrcEmail		Special
+  HiLink muttrcVariable		Special
+  HiLink muttrcHeader		Type
+  HiLink muttrcKeySpecial	SpecialChar
+  HiLink muttrcKey		Type
+  HiLink muttrcKeyName		SpecialChar
+  HiLink muttrcVarBool		Identifier
+  HiLink muttrcVarQuad		Identifier
+  HiLink muttrcVarNum		Identifier
+  HiLink muttrcVarStr		Identifier
+  HiLink muttrcMenu		Identifier
+  HiLink muttrcCommand		Keyword
+  HiLink muttrcSet		Keyword
+  HiLink muttrcUnset		muttrcCommand
+  HiLink muttrcReset		muttrcCommand
+  HiLink muttrcToggle		muttrcCommand
+  HiLink muttrcBind		muttrcCommand
+  HiLink muttrcMacro		muttrcCommand
+  HiLink muttrcMacroDescr	String
+  HiLink muttrcAlias		muttrcCommand
+  HiLink muttrcUnAlias		muttrcCommand
+  HiLink muttrcUnhook		muttrcCommand
+  HiLink muttrcUnhookLine	Error
+  HiLink muttrcAction		Macro
+  HiLink muttrcBadAction	Error
+  HiLink muttrcBindFunction	Error
+  HiLink muttrcBindMenuList	Error
+  HiLink muttrcFunction		Macro
+  HiLink muttrcGroupKeyword	muttrcCommand
+  HiLink muttrcGroupLine	Error
+  HiLink muttrcSubscribeKeyword	muttrcCommand
+  HiLink muttrcSubscribeLine	Error
+  HiLink muttrcListsKeyword	muttrcCommand
+  HiLink muttrcListsLine	Error
+  HiLink muttrcAlternateKeyword	muttrcCommand
+  HiLink muttrcAlternatesLine	Error
+  HiLink muttrcAttachmentsLine	muttrcCommand
+  HiLink muttrcAttachmentsFlag	Type
+  HiLink muttrcAttachmentsMimeType	String
+  HiLink muttrcColorLine	Error
+  HiLink muttrcColorContext	Error
+  HiLink muttrcColorContextI	Identifier
+  HiLink muttrcColorKeyword	muttrcCommand
+  HiLink muttrcColorKeywordI	muttrcColorKeyword
+  HiLink muttrcColorField	Identifier
+  HiLink muttrcColor		Type
+  HiLink muttrcColorFG		Error
+  HiLink muttrcColorFGI		Error
+  HiLink muttrcColorBG		Error
+  HiLink muttrcColorBGI		Error
+  HiLink muttrcMonoAttrib	muttrcColor
+  HiLink muttrcMono		muttrcCommand
+  HiLink muttrcSimplePat	Identifier
+  HiLink muttrcSimplePatString	Macro
+  HiLink muttrcSimplePatMetas	Special
+  HiLink muttrcPattern		Type
+  HiLink muttrcPatternInner	Error
+  HiLink muttrcUnColorLine	Error
+  HiLink muttrcUnColorKeyword	muttrcCommand
+  HiLink muttrcUnColorIndex	Identifier
+  HiLink muttrcShellString	muttrcEscape
+  HiLink muttrcRXHooks		muttrcCommand
+  HiLink muttrcRXHookNot	Type
+  HiLink muttrcPatHooks		muttrcCommand
+  HiLink muttrcPatHookNot	Type
+
+  HiLink muttrcBindFunctionNL	SpecialChar
+  HiLink muttrcBindKeyNL	SpecialChar
+  HiLink muttrcBindMenuListNL	SpecialChar
+  HiLink muttrcMacroDescrNL	SpecialChar
+  HiLink muttrcMacroBodyNL	SpecialChar
+  HiLink muttrcMacroKeyNL	SpecialChar
+  HiLink muttrcMacroMenuListNL	SpecialChar
+  HiLink muttrcColorMatchCountNL SpecialChar
+  HiLink muttrcColorNL		SpecialChar
+  HiLink muttrcColorRXNL	SpecialChar
+  HiLink muttrcColorBGNL	SpecialChar
+  HiLink muttrcColorFGNL	SpecialChar
+  HiLink muttrcAliasNameNL	SpecialChar
+  HiLink muttrcAliasENNL	SpecialChar
+  HiLink muttrcAliasNL		SpecialChar
+  HiLink muttrcUnAliasNL	SpecialChar
+  HiLink muttrcAliasGroupDefNL	SpecialChar
+  HiLink muttrcAliasEncEmailNL	SpecialChar
+  HiLink muttrcPatternNL	SpecialChar
+  HiLink muttrcUnColorPatNL	SpecialChar
+  HiLink muttrcUnColorAPNL	SpecialChar
+  HiLink muttrcUnColorIndexNL	SpecialChar
+
+  delcommand HiLink
+endif
+
+let b:current_syntax = "muttrc"
+
+"EOF	vim: ts=8 noet tw=100 sw=8 sts=0
--- /dev/null
+++ b/lib/vimfiles/syntax/mysql.vim
@@ -1,0 +1,297 @@
+" Vim syntax file
+" Language:     mysql
+" Maintainer:   Kenneth J. Pronovici <pronovic@ieee.org>
+" Last Change:  $Date: 2007/05/05 18:25:59 $
+" Filenames:    *.mysql
+" URL:		ftp://cedar-solutions.com/software/mysql.vim
+" Note:		The definitions below are taken from the mysql user manual as of April 2002, for version 3.23
+
+" For version 5.x: Clear all syntax items
+" For version 6.x: Quit when a syntax file was already loaded
+if version < 600
+  syntax clear
+elseif exists("b:current_syntax")
+  finish
+endif
+
+" Always ignore case
+syn case ignore
+
+" General keywords which don't fall into other categories
+syn keyword mysqlKeyword	 action add after aggregate all alter as asc auto_increment avg avg_row_length
+syn keyword mysqlKeyword	 both by
+syn keyword mysqlKeyword	 cascade change character check checksum column columns comment constraint create cross
+syn keyword mysqlKeyword	 current_date current_time current_timestamp
+syn keyword mysqlKeyword	 data database databases day day_hour day_minute day_second
+syn keyword mysqlKeyword	 default delayed delay_key_write delete desc describe distinct distinctrow drop
+syn keyword mysqlKeyword	 enclosed escape escaped explain
+syn keyword mysqlKeyword	 fields file first flush for foreign from full function
+syn keyword mysqlKeyword	 global grant grants group
+syn keyword mysqlKeyword	 having heap high_priority hosts hour hour_minute hour_second
+syn keyword mysqlKeyword	 identified ignore index infile inner insert insert_id into isam
+syn keyword mysqlKeyword	 join
+syn keyword mysqlKeyword	 key keys kill last_insert_id leading left limit lines load local lock logs long
+syn keyword mysqlKeyword	 low_priority
+syn keyword mysqlKeyword	 match max_rows middleint min_rows minute minute_second modify month myisam
+syn keyword mysqlKeyword	 natural no
+syn keyword mysqlKeyword	 on optimize option optionally order outer outfile
+syn keyword mysqlKeyword	 pack_keys partial password primary privileges procedure process processlist
+syn keyword mysqlKeyword	 read references reload rename replace restrict returns revoke row rows
+syn keyword mysqlKeyword	 second select show shutdown soname sql_big_result sql_big_selects sql_big_tables sql_log_off
+syn keyword mysqlKeyword	 sql_log_update sql_low_priority_updates sql_select_limit sql_small_result sql_warnings starting
+syn keyword mysqlKeyword	 status straight_join string
+syn keyword mysqlKeyword	 table tables temporary terminated to trailing type
+syn keyword mysqlKeyword	 unique unlock unsigned update usage use using
+syn keyword mysqlKeyword	 values varbinary variables varying
+syn keyword mysqlKeyword	 where with write
+syn keyword mysqlKeyword	 year_month
+syn keyword mysqlKeyword	 zerofill
+
+" Special values
+syn keyword mysqlSpecial	 false null true
+
+" Strings (single- and double-quote)
+syn region mysqlString		 start=+"+  skip=+\\\\\|\\"+  end=+"+
+syn region mysqlString		 start=+'+  skip=+\\\\\|\\'+  end=+'+
+
+" Numbers and hexidecimal values
+syn match mysqlNumber		 "-\=\<[0-9]*\>"
+syn match mysqlNumber		 "-\=\<[0-9]*\.[0-9]*\>"
+syn match mysqlNumber		 "-\=\<[0-9]*e[+-]\=[0-9]*\>"
+syn match mysqlNumber		 "-\=\<[0-9]*\.[0-9]*e[+-]\=[0-9]*\>"
+syn match mysqlNumber		 "\<0x[abcdefABCDEF0-9]*\>"
+
+" User variables
+syn match mysqlVariable		 "@\a*[A-Za-z0-9]*[._]*[A-Za-z0-9]*"
+
+" Comments (c-style, mysql-style and modified sql-style)
+syn region mysqlComment		 start="/\*"  end="\*/"
+syn match mysqlComment		 "#.*"
+syn match mysqlComment		 "-- .*"
+syn sync ccomment mysqlComment
+
+" Column types
+"
+" This gets a bit ugly.  There are two different problems we have to
+" deal with.
+"
+" The first problem is that some keywoards like 'float' can be used
+" both with and without specifiers, i.e. 'float', 'float(1)' and
+" 'float(@var)' are all valid.  We have to account for this and we
+" also have to make sure that garbage like floatn or float_(1) is not
+" highlighted.
+"
+" The second problem is that some of these keywords are included in
+" function names.  For instance, year() is part of the name of the
+" dayofyear() function, and the dec keyword (no parenthesis) is part of
+" the name of the decode() function.
+
+syn keyword mysqlType		 tinyint smallint mediumint int integer bigint
+syn keyword mysqlType		 date datetime time bit bool
+syn keyword mysqlType		 tinytext mediumtext longtext text
+syn keyword mysqlType		 tinyblob mediumblob longblob blob
+syn region mysqlType		 start="float\W" end="."me=s-1
+syn region mysqlType		 start="float$" end="."me=s-1
+syn region mysqlType		 start="float(" end=")" contains=mysqlNumber,mysqlVariable
+syn region mysqlType		 start="double\W" end="."me=s-1
+syn region mysqlType		 start="double$" end="."me=s-1
+syn region mysqlType		 start="double(" end=")" contains=mysqlNumber,mysqlVariable
+syn region mysqlType		 start="double precision\W" end="."me=s-1
+syn region mysqlType		 start="double precision$" end="."me=s-1
+syn region mysqlType		 start="double precision(" end=")" contains=mysqlNumber,mysqlVariable
+syn region mysqlType		 start="real\W" end="."me=s-1
+syn region mysqlType		 start="real$" end="."me=s-1
+syn region mysqlType		 start="real(" end=")" contains=mysqlNumber,mysqlVariable
+syn region mysqlType		 start="numeric(" end=")" contains=mysqlNumber,mysqlVariable
+syn region mysqlType		 start="dec\W" end="."me=s-1
+syn region mysqlType		 start="dec$" end="."me=s-1
+syn region mysqlType		 start="dec(" end=")" contains=mysqlNumber,mysqlVariable
+syn region mysqlType		 start="decimal\W" end="."me=s-1
+syn region mysqlType		 start="decimal$" end="."me=s-1
+syn region mysqlType		 start="decimal(" end=")" contains=mysqlNumber,mysqlVariable
+syn region mysqlType		 start="\Wtimestamp\W" end="."me=s-1
+syn region mysqlType		 start="\Wtimestamp$" end="."me=s-1
+syn region mysqlType		 start="\Wtimestamp(" end=")" contains=mysqlNumber,mysqlVariable
+syn region mysqlType		 start="^timestamp\W" end="."me=s-1
+syn region mysqlType		 start="^timestamp$" end="."me=s-1
+syn region mysqlType		 start="^timestamp(" end=")" contains=mysqlNumber,mysqlVariable
+syn region mysqlType		 start="\Wyear(" end=")" contains=mysqlNumber,mysqlVariable
+syn region mysqlType		 start="^year(" end=")" contains=mysqlNumber,mysqlVariable
+syn region mysqlType		 start="char(" end=")" contains=mysqlNumber,mysqlVariable
+syn region mysqlType		 start="varchar(" end=")" contains=mysqlNumber,mysqlVariable
+syn region mysqlType		 start="enum(" end=")" contains=mysqlString,mysqlVariable
+syn region mysqlType		 start="\Wset(" end=")" contains=mysqlString,mysqlVariable
+syn region mysqlType		 start="^set(" end=")" contains=mysqlString,mysqlVariable
+
+" Logical, string and  numeric operators
+syn keyword mysqlOperator	 between not and or is in like regexp rlike binary exists
+syn region mysqlOperator	 start="isnull(" end=")" contains=ALL
+syn region mysqlOperator	 start="coalesce(" end=")" contains=ALL
+syn region mysqlOperator	 start="interval(" end=")" contains=ALL
+
+" Control flow functions
+syn keyword mysqlFlow		 case when then else end
+syn region mysqlFlow		 start="ifnull("   end=")"  contains=ALL
+syn region mysqlFlow		 start="nullif("   end=")"  contains=ALL
+syn region mysqlFlow		 start="if("	   end=")"  contains=ALL
+
+" General Functions
+"
+" I'm leery of just defining keywords for functions, since according to the MySQL manual:
+"
+"     Function names do not clash with table or column names. For example, ABS is a
+"     valid column name. The only restriction is that for a function call, no spaces
+"     are allowed between the function name and the `(' that follows it.
+"
+" This means that if I want to highlight function names properly, I have to use a
+" region to define them, not just a keyword.  This will probably cause the syntax file
+" to load more slowly, but at least it will be 'correct'.
+
+syn region mysqlFunction	 start="abs(" end=")" contains=ALL
+syn region mysqlFunction	 start="acos(" end=")" contains=ALL
+syn region mysqlFunction	 start="adddate(" end=")" contains=ALL
+syn region mysqlFunction	 start="ascii(" end=")" contains=ALL
+syn region mysqlFunction	 start="asin(" end=")" contains=ALL
+syn region mysqlFunction	 start="atan(" end=")" contains=ALL
+syn region mysqlFunction	 start="atan2(" end=")" contains=ALL
+syn region mysqlFunction	 start="benchmark(" end=")" contains=ALL
+syn region mysqlFunction	 start="bin(" end=")" contains=ALL
+syn region mysqlFunction	 start="bit_and(" end=")" contains=ALL
+syn region mysqlFunction	 start="bit_count(" end=")" contains=ALL
+syn region mysqlFunction	 start="bit_or(" end=")" contains=ALL
+syn region mysqlFunction	 start="ceiling(" end=")" contains=ALL
+syn region mysqlFunction	 start="character_length(" end=")" contains=ALL
+syn region mysqlFunction	 start="char_length(" end=")" contains=ALL
+syn region mysqlFunction	 start="concat(" end=")" contains=ALL
+syn region mysqlFunction	 start="concat_ws(" end=")" contains=ALL
+syn region mysqlFunction	 start="connection_id(" end=")" contains=ALL
+syn region mysqlFunction	 start="conv(" end=")" contains=ALL
+syn region mysqlFunction	 start="cos(" end=")" contains=ALL
+syn region mysqlFunction	 start="cot(" end=")" contains=ALL
+syn region mysqlFunction	 start="count(" end=")" contains=ALL
+syn region mysqlFunction	 start="curdate(" end=")" contains=ALL
+syn region mysqlFunction	 start="curtime(" end=")" contains=ALL
+syn region mysqlFunction	 start="date_add(" end=")" contains=ALL
+syn region mysqlFunction	 start="date_format(" end=")" contains=ALL
+syn region mysqlFunction	 start="date_sub(" end=")" contains=ALL
+syn region mysqlFunction	 start="dayname(" end=")" contains=ALL
+syn region mysqlFunction	 start="dayofmonth(" end=")" contains=ALL
+syn region mysqlFunction	 start="dayofweek(" end=")" contains=ALL
+syn region mysqlFunction	 start="dayofyear(" end=")" contains=ALL
+syn region mysqlFunction	 start="decode(" end=")" contains=ALL
+syn region mysqlFunction	 start="degrees(" end=")" contains=ALL
+syn region mysqlFunction	 start="elt(" end=")" contains=ALL
+syn region mysqlFunction	 start="encode(" end=")" contains=ALL
+syn region mysqlFunction	 start="encrypt(" end=")" contains=ALL
+syn region mysqlFunction	 start="exp(" end=")" contains=ALL
+syn region mysqlFunction	 start="export_set(" end=")" contains=ALL
+syn region mysqlFunction	 start="extract(" end=")" contains=ALL
+syn region mysqlFunction	 start="field(" end=")" contains=ALL
+syn region mysqlFunction	 start="find_in_set(" end=")" contains=ALL
+syn region mysqlFunction	 start="floor(" end=")" contains=ALL
+syn region mysqlFunction	 start="format(" end=")" contains=ALL
+syn region mysqlFunction	 start="from_days(" end=")" contains=ALL
+syn region mysqlFunction	 start="from_unixtime(" end=")" contains=ALL
+syn region mysqlFunction	 start="get_lock(" end=")" contains=ALL
+syn region mysqlFunction	 start="greatest(" end=")" contains=ALL
+syn region mysqlFunction	 start="group_unique_users(" end=")" contains=ALL
+syn region mysqlFunction	 start="hex(" end=")" contains=ALL
+syn region mysqlFunction	 start="inet_aton(" end=")" contains=ALL
+syn region mysqlFunction	 start="inet_ntoa(" end=")" contains=ALL
+syn region mysqlFunction	 start="instr(" end=")" contains=ALL
+syn region mysqlFunction	 start="lcase(" end=")" contains=ALL
+syn region mysqlFunction	 start="least(" end=")" contains=ALL
+syn region mysqlFunction	 start="length(" end=")" contains=ALL
+syn region mysqlFunction	 start="load_file(" end=")" contains=ALL
+syn region mysqlFunction	 start="locate(" end=")" contains=ALL
+syn region mysqlFunction	 start="log(" end=")" contains=ALL
+syn region mysqlFunction	 start="log10(" end=")" contains=ALL
+syn region mysqlFunction	 start="lower(" end=")" contains=ALL
+syn region mysqlFunction	 start="lpad(" end=")" contains=ALL
+syn region mysqlFunction	 start="ltrim(" end=")" contains=ALL
+syn region mysqlFunction	 start="make_set(" end=")" contains=ALL
+syn region mysqlFunction	 start="master_pos_wait(" end=")" contains=ALL
+syn region mysqlFunction	 start="max(" end=")" contains=ALL
+syn region mysqlFunction	 start="md5(" end=")" contains=ALL
+syn region mysqlFunction	 start="mid(" end=")" contains=ALL
+syn region mysqlFunction	 start="min(" end=")" contains=ALL
+syn region mysqlFunction	 start="mod(" end=")" contains=ALL
+syn region mysqlFunction	 start="monthname(" end=")" contains=ALL
+syn region mysqlFunction	 start="now(" end=")" contains=ALL
+syn region mysqlFunction	 start="oct(" end=")" contains=ALL
+syn region mysqlFunction	 start="octet_length(" end=")" contains=ALL
+syn region mysqlFunction	 start="ord(" end=")" contains=ALL
+syn region mysqlFunction	 start="period_add(" end=")" contains=ALL
+syn region mysqlFunction	 start="period_diff(" end=")" contains=ALL
+syn region mysqlFunction	 start="pi(" end=")" contains=ALL
+syn region mysqlFunction	 start="position(" end=")" contains=ALL
+syn region mysqlFunction	 start="pow(" end=")" contains=ALL
+syn region mysqlFunction	 start="power(" end=")" contains=ALL
+syn region mysqlFunction	 start="quarter(" end=")" contains=ALL
+syn region mysqlFunction	 start="radians(" end=")" contains=ALL
+syn region mysqlFunction	 start="rand(" end=")" contains=ALL
+syn region mysqlFunction	 start="release_lock(" end=")" contains=ALL
+syn region mysqlFunction	 start="repeat(" end=")" contains=ALL
+syn region mysqlFunction	 start="reverse(" end=")" contains=ALL
+syn region mysqlFunction	 start="round(" end=")" contains=ALL
+syn region mysqlFunction	 start="rpad(" end=")" contains=ALL
+syn region mysqlFunction	 start="rtrim(" end=")" contains=ALL
+syn region mysqlFunction	 start="sec_to_time(" end=")" contains=ALL
+syn region mysqlFunction	 start="session_user(" end=")" contains=ALL
+syn region mysqlFunction	 start="sign(" end=")" contains=ALL
+syn region mysqlFunction	 start="sin(" end=")" contains=ALL
+syn region mysqlFunction	 start="soundex(" end=")" contains=ALL
+syn region mysqlFunction	 start="space(" end=")" contains=ALL
+syn region mysqlFunction	 start="sqrt(" end=")" contains=ALL
+syn region mysqlFunction	 start="std(" end=")" contains=ALL
+syn region mysqlFunction	 start="stddev(" end=")" contains=ALL
+syn region mysqlFunction	 start="strcmp(" end=")" contains=ALL
+syn region mysqlFunction	 start="subdate(" end=")" contains=ALL
+syn region mysqlFunction	 start="substring(" end=")" contains=ALL
+syn region mysqlFunction	 start="substring_index(" end=")" contains=ALL
+syn region mysqlFunction	 start="subtime(" end=")" contains=ALL
+syn region mysqlFunction	 start="sum(" end=")" contains=ALL
+syn region mysqlFunction	 start="sysdate(" end=")" contains=ALL
+syn region mysqlFunction	 start="system_user(" end=")" contains=ALL
+syn region mysqlFunction	 start="tan(" end=")" contains=ALL
+syn region mysqlFunction	 start="time_format(" end=")" contains=ALL
+syn region mysqlFunction	 start="time_to_sec(" end=")" contains=ALL
+syn region mysqlFunction	 start="to_days(" end=")" contains=ALL
+syn region mysqlFunction	 start="trim(" end=")" contains=ALL
+syn region mysqlFunction	 start="ucase(" end=")" contains=ALL
+syn region mysqlFunction	 start="unique_users(" end=")" contains=ALL
+syn region mysqlFunction	 start="unix_timestamp(" end=")" contains=ALL
+syn region mysqlFunction	 start="upper(" end=")" contains=ALL
+syn region mysqlFunction	 start="user(" end=")" contains=ALL
+syn region mysqlFunction	 start="version(" end=")" contains=ALL
+syn region mysqlFunction	 start="week(" end=")" contains=ALL
+syn region mysqlFunction	 start="weekday(" end=")" contains=ALL
+syn region mysqlFunction	 start="yearweek(" end=")" contains=ALL
+
+" Define the default highlighting.
+" For version 5.7 and earlier: only when not done already
+" For version 5.8 and later: only when an item doesn't have highlighting yet
+if version >= 508 || !exists("did_mysql_syn_inits")
+  if version < 508
+    let did_mysql_syn_inits = 1
+    command -nargs=+ HiLink hi link <args>
+  else
+    command -nargs=+ HiLink hi def link <args>
+  endif
+
+  HiLink mysqlKeyword		 Statement
+  HiLink mysqlSpecial		 Special
+  HiLink mysqlString		 String
+  HiLink mysqlNumber		 Number
+  HiLink mysqlVariable		 Identifier
+  HiLink mysqlComment		 Comment
+  HiLink mysqlType		 Type
+  HiLink mysqlOperator		 Statement
+  HiLink mysqlFlow		 Statement
+  HiLink mysqlFunction		 Function
+
+  delcommand HiLink
+endif
+
+let b:current_syntax = "mysql"
+
--- /dev/null
+++ b/lib/vimfiles/syntax/named.vim
@@ -1,0 +1,248 @@
+" Vim syntax file
+" Language:	BIND configuration file
+" Maintainer:	Nick Hibma <nick@van-laarhoven.org>
+" Last change:	2007-01-30
+" Filenames:	named.conf, rndc.conf
+" Location:	http://www.van-laarhoven.org/vim/syntax/named.vim
+"
+" Previously maintained by glory hump <rnd@web-drive.ru> and updated by Marcin
+" Dalecki.
+"
+" This file could do with a lot of improvements, so comments are welcome.
+" Please submit the named.conf (segment) with any comments.
+"
+" For version 5.x: Clear all syntax items
+" For version 6.x: Quit when a syntax file was already loaded
+if version < 600
+  syntax clear
+elseif exists("b:current_syntax")
+  finish
+endif
+
+syn case match
+
+if version >= 600
+  setlocal iskeyword=.,-,48-58,A-Z,a-z,_
+else
+  set iskeyword=.,-,48-58,A-Z,a-z,_
+endif
+
+if version >= 600
+  syn sync match namedSync grouphere NONE "^(zone|controls|acl|key)"
+endif
+
+let s:save_cpo = &cpo
+set cpo-=C
+
+" BIND configuration file
+
+syn match	namedComment	"//.*"
+syn match	namedComment	"#.*"
+syn region	namedComment	start="/\*" end="\*/"
+syn region	namedString	start=/"/ end=/"/ contained
+" --- omitted trailing semicolon
+syn match	namedError	/[^;{#]$/
+
+" --- top-level keywords
+
+syn keyword	namedInclude	include nextgroup=namedString skipwhite
+syn keyword	namedKeyword	acl key nextgroup=namedIntIdent skipwhite
+syn keyword	namedKeyword	server nextgroup=namedIdentifier skipwhite
+syn keyword	namedKeyword	controls nextgroup=namedSection skipwhite
+syn keyword	namedKeyword	trusted-keys nextgroup=namedIntSection skipwhite
+syn keyword	namedKeyword	logging nextgroup=namedLogSection skipwhite
+syn keyword	namedKeyword	options nextgroup=namedOptSection skipwhite
+syn keyword	namedKeyword	zone nextgroup=namedZoneString skipwhite
+
+" --- Identifier: name of following { ... } Section
+syn match	namedIdentifier	contained /\k\+/ nextgroup=namedSection skipwhite
+" --- IntIdent: name of following IntSection
+syn match	namedIntIdent	contained /"\=\k\+"\=/ nextgroup=namedIntSection skipwhite
+
+" --- Section: { ... } clause
+syn region	namedSection	contained start=+{+ end=+};+ contains=namedSection,namedIntKeyword
+
+" --- IntSection: section that does not contain other sections
+syn region	namedIntSection	contained start=+{+ end=+}+ contains=namedIntKeyword,namedError
+
+" --- IntKeyword: keywords contained within `{ ... }' sections only
+" + these keywords are contained within `key' and `acl' sections
+syn keyword	namedIntKeyword	contained key algorithm
+syn keyword	namedIntKeyword	contained secret nextgroup=namedString skipwhite
+
+" + these keywords are contained within `server' section only
+syn keyword	namedIntKeyword	contained bogus support-ixfr nextgroup=namedBool,namedNotBool skipwhite
+syn keyword	namedIntKeyword	contained transfers nextgroup=namedNumber,namedNotNumber skipwhite
+syn keyword	namedIntKeyword	contained transfer-format
+syn keyword	namedIntKeyword	contained keys nextgroup=namedIntSection skipwhite
+
+" + these keywords are contained within `controls' section only
+syn keyword	namedIntKeyword	contained inet nextgroup=namedIPaddr,namedIPerror skipwhite
+syn keyword	namedIntKeyword	contained unix nextgroup=namedString skipwhite
+syn keyword	namedIntKeyword	contained port perm owner group nextgroup=namedNumber,namedNotNumber skipwhite
+syn keyword	namedIntKeyword	contained allow nextgroup=namedIntSection skipwhite
+
+" + these keywords are contained within `update-policy' section only
+syn keyword	namedIntKeyword	contained grant nextgroup=namedString skipwhite
+syn keyword	namedIntKeyword	contained name self subdomain wildcard nextgroup=namedString skipwhite
+syn keyword	namedIntKeyword	TXT A PTR NS SOA A6 CNAME MX ANY skipwhite
+
+" --- options
+syn region	namedOptSection	contained start=+{+ end=+};+ contains=namedOption,namedCNOption,namedComment,namedParenError
+
+syn keyword	namedOption	contained version directory
+\		nextgroup=namedString skipwhite
+syn keyword	namedOption	contained named-xfer dump-file pid-file
+\		nextgroup=namedString skipwhite
+syn keyword	namedOption	contained mem-statistics-file statistics-file
+\		nextgroup=namedString skipwhite
+syn keyword	namedOption	contained auth-nxdomain deallocate-on-exit
+\		nextgroup=namedBool,namedNotBool skipwhite
+syn keyword	namedOption	contained dialup fake-iquery fetch-glue
+\		nextgroup=namedBool,namedNotBool skipwhite
+syn keyword	namedOption	contained has-old-clients host-statistics
+\		nextgroup=namedBool,namedNotBool skipwhite
+syn keyword	namedOption	contained maintain-ixfr-base multiple-cnames
+\		nextgroup=namedBool,namedNotBool skipwhite
+syn keyword	namedOption	contained notify recursion rfc2308-type1
+\		nextgroup=namedBool,namedNotBool skipwhite
+syn keyword	namedOption	contained use-id-pool treat-cr-as-space
+\		nextgroup=namedBool,namedNotBool skipwhite
+syn keyword	namedOption	contained also-notify forwarders
+\		nextgroup=namedIPlist skipwhite
+syn keyword	namedOption	contained forward check-names
+syn keyword	namedOption	contained allow-query allow-transfer allow-recursion
+\		nextgroup=namedAML skipwhite
+syn keyword	namedOption	contained blackhole listen-on
+\		nextgroup=namedIntSection skipwhite
+syn keyword	namedOption	contained lame-ttl max-transfer-time-in
+\		nextgroup=namedNumber,namedNotNumber skipwhite
+syn keyword	namedOption	contained max-ncache-ttl min-roots
+\		nextgroup=namedNumber,namedNotNumber skipwhite
+syn keyword	namedOption	contained serial-queries transfers-in
+\		nextgroup=namedNumber,namedNotNumber skipwhite
+syn keyword	namedOption	contained transfers-out transfers-per-ns
+syn keyword	namedOption	contained transfer-format
+syn keyword	namedOption	contained transfer-source
+\		nextgroup=namedIPaddr,namedIPerror skipwhite
+syn keyword	namedOption	contained max-ixfr-log-size
+\		nextgroup=namedNumber,namedNotNumber skipwhite
+syn keyword	namedOption	contained coresize datasize files stacksize
+syn keyword	namedOption	contained cleaning-interval interface-interval statistics-interval heartbeat-interval
+\		nextgroup=namedNumber,namedNotNumber skipwhite
+syn keyword	namedOption	contained topology sortlist rrset-order
+\		nextgroup=namedIntSection skipwhite
+
+syn match	namedOption	contained /\<query-source\s\+.*;/he=s+12 contains=namedQSKeywords
+syn keyword	namedQSKeywords	contained address port
+syn match	namedCNOption	contained /\<check-names\s\+.*;/he=s+11 contains=namedCNKeywords
+syn keyword	namedCNKeywords	contained fail warn ignore master slave response
+
+" --- logging facilities
+syn region	namedLogSection	contained start=+{+ end=+};+ contains=namedLogOption
+syn keyword	namedLogOption	contained channel nextgroup=namedIntIdent skipwhite
+syn keyword	namedLogOption	contained category nextgroup=namedIntIdent skipwhite
+syn keyword	namedIntKeyword	contained syslog null versions size severity
+syn keyword	namedIntKeyword	contained file nextgroup=namedString skipwhite
+syn keyword	namedIntKeyword	contained print-category print-severity print-time nextgroup=namedBool,namedNotBool skipwhite
+
+" --- zone section
+syn region	namedZoneString	contained oneline start=+"+ end=+"+ skipwhite
+\		contains=namedDomain,namedIllegalDom
+\		nextgroup=namedZoneClass,namedZoneSection
+syn keyword	namedZoneClass	contained in hs hesiod chaos
+\		IN HS HESIOD CHAOS
+\		nextgroup=namedZoneSection skipwhite
+
+syn region	namedZoneSection	contained start=+{+ end=+};+ contains=namedZoneOpt,namedCNOption,namedComment,namedMasters,namedParenError
+syn keyword	namedZoneOpt	contained file ixfr-base
+\		nextgroup=namedString skipwhite
+syn keyword	namedZoneOpt	contained notify dialup
+\		nextgroup=namedBool,namedNotBool skipwhite
+syn keyword	namedZoneOpt	contained pubkey forward
+syn keyword	namedZoneOpt	contained max-transfer-time-in
+\		nextgroup=namedNumber,namedNotNumber skipwhite
+syn keyword	namedZoneOpt	contained type nextgroup=namedZoneType skipwhite
+syn keyword	namedZoneType	contained master slave stub forward hint
+
+syn keyword	namedZoneOpt	contained masters forwarders
+\		nextgroup=namedIPlist skipwhite
+syn region	namedIPlist	contained start=+{+ end=+};+ contains=namedIPaddr,namedIPerror,namedParenError,namedComment
+syn keyword	namedZoneOpt	contained allow-update allow-query allow-transfer
+\		nextgroup=namedAML skipwhite
+syn keyword	namedZoneOpt	contained update-policy
+\		nextgroup=namedIntSection skipwhite
+
+" --- boolean parameter
+syn match	namedNotBool	contained "[^ 	;]\+"
+syn keyword	namedBool	contained yes no true false 1 0
+
+" --- number parameter
+syn match	namedNotNumber	contained "[^ 	0-9;]\+"
+syn match	namedNumber	contained "\d\+"
+
+" --- address match list
+syn region	namedAML	contained start=+{+ end=+};+ contains=namedParenError,namedComment,namedString
+
+" --- IPs & Domains
+syn match	namedIPaddr	contained /\<[0-9]\{1,3}\(\.[0-9]\{1,3}\)\{3};/he=e-1
+syn match	namedDomain	contained /\<[0-9A-Za-z][-0-9A-Za-z.]\+\>/ nextgroup=namedSpareDot
+syn match	namedDomain	contained /"\."/ms=s+1,me=e-1
+syn match	namedSpareDot	contained /\./
+
+" --- syntax errors
+syn match	namedIllegalDom	contained /"\S*[^-A-Za-z0-9.[:space:]]\S*"/ms=s+1,me=e-1
+syn match	namedIPerror	contained /\<\S*[^0-9.[:space:];]\S*/
+syn match	namedEParenError	contained +{+
+syn match	namedParenError	+}\([^;]\|$\)+
+
+" Define the default highlighting.
+" For version 5.7 and earlier: only when not done already
+" For version 5.8 and later: only when an item doesn't have highlighting yet
+if version >= 508 || !exists("did_named_syn_inits")
+  if version < 508
+    let did_named_syn_inits = 1
+    command -nargs=+ HiLink hi link <args>
+  else
+    command -nargs=+ HiLink hi def link <args>
+  endif
+
+  HiLink namedComment	Comment
+  HiLink namedInclude	Include
+  HiLink namedKeyword	Keyword
+  HiLink namedIntKeyword	Keyword
+  HiLink namedIdentifier	Identifier
+  HiLink namedIntIdent	Identifier
+
+  HiLink namedString	String
+  HiLink namedBool	Type
+  HiLink namedNotBool	Error
+  HiLink namedNumber	Number
+  HiLink namedNotNumber	Error
+
+  HiLink namedOption	namedKeyword
+  HiLink namedLogOption	namedKeyword
+  HiLink namedCNOption	namedKeyword
+  HiLink namedQSKeywords	Type
+  HiLink namedCNKeywords	Type
+  HiLink namedLogCategory	Type
+  HiLink namedIPaddr	Number
+  HiLink namedDomain	Identifier
+  HiLink namedZoneOpt	namedKeyword
+  HiLink namedZoneType	Type
+  HiLink namedParenError	Error
+  HiLink namedEParenError	Error
+  HiLink namedIllegalDom	Error
+  HiLink namedIPerror	Error
+  HiLink namedSpareDot	Error
+  HiLink namedError	Error
+
+  delcommand HiLink
+endif
+
+let &cpo = s:save_cpo
+unlet s:save_cpo
+
+let b:current_syntax = "named"
+
+" vim: ts=17
--- /dev/null
+++ b/lib/vimfiles/syntax/nanorc.vim
@@ -1,0 +1,243 @@
+" Vim syntax file
+" Language:         nanorc(5) - GNU nano configuration file
+" Maintainer:       Nikolai Weibull <now@bitwi.se>
+" Latest Revision:  2006-04-19
+
+if exists("b:current_syntax")
+  finish
+endif
+
+let s:cpo_save = &cpo
+set cpo&vim
+
+syn keyword nanorcTodo          contained TODO FIXME XXX NOTE
+
+syn region  nanorcComment       display oneline start='^\s*#' end='$'
+                                \ contains=nanorcTodo,@Spell
+
+syn match   nanorcBegin         display '^'
+                                \ nextgroup=nanorcKeyword,nanorcComment
+                                \ skipwhite
+
+syn keyword nanorcKeyword       contained set unset
+                                \ nextgroup=nanorcBoolOption,
+                                \ nanorcStringOption,nanorcNumberOption
+                                \ skipwhite
+
+syn keyword nanorcKeyword       contained syntax
+                                \ nextgroup=nanorcSynGroupName skipwhite
+
+syn keyword nanorcKeyword       contained color
+                                \ nextgroup=@nanorcFGColor skipwhite
+
+syn keyword nanorcBoolOption    contained autoindent backup const cut
+                                \ historylog morespace mouse multibuffer
+                                \ noconvert nofollow nohelp nowrap preserve
+                                \ rebinddelete regexp smarthome smooth suspend
+                                \ tempfile view
+
+syn keyword nanorcStringOption  contained backupdir brackets operatingdir
+                                \ punct quotestr speller whitespace
+                                \ nextgroup=nanorcString skipwhite
+
+syn keyword nanorcNumberOption  contained fill tabsize
+                                \ nextgroup=nanorcNumber skipwhite
+
+syn region  nanorcSynGroupName  contained display oneline start=+"+
+                                \ end=+"\ze\%([[:blank:]]\|$\)+
+                                \ nextgroup=nanorcRegexes skipwhite
+
+syn match   nanorcString        contained display '".*"'
+
+syn region  nanorcRegexes       contained display oneline start=+"+
+                                \ end=+"\ze\%([[:blank:]]\|$\)+
+                                \ nextgroup=nanorcRegexes skipwhite
+
+syn match   nanorcNumber        contained display '[+-]\=\<\d\+\>'
+
+syn cluster nanorcFGColor       contains=nanorcFGWhite,nanorcFGBlack,
+                                \ nanorcFGRed,nanorcFGBlue,nanorcFGGreen,
+                                \ nanorcFGYellow,nanorcFGMagenta,nanorcFGCyan,
+                                \ nanorcFGBWhite,nanorcFGBBlack,nanorcFGBRed,
+                                \ nanorcFGBBlue,nanorcFGBGreen,nanorcFGBYellow,
+                                \ nanorcFGBMagenta,nanorcFGBCyan
+
+syn keyword nanorcFGWhite       contained white
+                                \ nextgroup=@nanorcFGSpec skipwhite
+
+syn keyword nanorcFGBlack       contained black
+                                \ nextgroup=@nanorcFGSpec skipwhite
+
+syn keyword nanorcFGRed         contained red
+                                \ nextgroup=@nanorcFGSpec skipwhite
+
+syn keyword nanorcFGBlue        contained blue
+                                \ nextgroup=@nanorcFGSpec skipwhite
+
+syn keyword nanorcFGGreen       contained green
+                                \ nextgroup=@nanorcFGSpec skipwhite
+
+syn keyword nanorcFGYellow      contained yellow
+                                \ nextgroup=@nanorcFGSpec skipwhite
+
+syn keyword nanorcFGMagenta     contained magenta
+                                \ nextgroup=@nanorcFGSpec skipwhite
+
+syn keyword nanorcFGCyan        contained cyan
+                                \ nextgroup=@nanorcFGSpec skipwhite
+
+syn keyword nanorcFGBWhite      contained brightwhite
+                                \ nextgroup=@nanorcFGSpec skipwhite
+
+syn keyword nanorcFGBBlack      contained brightblack
+                                \ nextgroup=@nanorcFGSpec skipwhite
+
+syn keyword nanorcFGBRed        contained brightred
+                                \ nextgroup=@nanorcFGSpec skipwhite
+
+syn keyword nanorcFGBBlue       contained brightblue
+                                \ nextgroup=@nanorcFGSpec skipwhite
+
+syn keyword nanorcFGBGreen      contained brightgreen
+                                \ nextgroup=@nanorcFGSpec skipwhite
+
+syn keyword nanorcFGBYellow     contained brightyellow
+                                \ nextgroup=@nanorcFGSpec skipwhite
+
+syn keyword nanorcFGBMagenta    contained brightmagenta
+                                \ nextgroup=@nanorcFGSpec skipwhite
+
+syn keyword nanorcFGBCyan       contained brightcyan
+                                \ nextgroup=@nanorcFGSpec skipwhite
+
+syn cluster nanorcBGColor       contains=nanorcBGWhite,nanorcBGBlack,
+                                \ nanorcBGRed,nanorcBGBlue,nanorcBGGreen,
+                                \ nanorcBGYellow,nanorcBGMagenta,nanorcBGCyan,
+                                \ nanorcBGBWhite,nanorcBGBBlack,nanorcBGBRed,
+                                \ nanorcBGBBlue,nanorcBGBGreen,nanorcBGBYellow,
+                                \ nanorcBGBMagenta,nanorcBGBCyan
+
+syn keyword nanorcBGWhite       contained white
+                                \ nextgroup=@nanorcBGSpec skipwhite
+
+syn keyword nanorcBGBlack       contained black
+                                \ nextgroup=@nanorcBGSpec skipwhite
+
+syn keyword nanorcBGRed         contained red
+                                \ nextgroup=@nanorcBGSpec skipwhite
+
+syn keyword nanorcBGBlue        contained blue
+                                \ nextgroup=@nanorcBGSpec skipwhite
+
+syn keyword nanorcBGGreen       contained green
+                                \ nextgroup=@nanorcBGSpec skipwhite
+
+syn keyword nanorcBGYellow      contained yellow
+                                \ nextgroup=@nanorcBGSpec skipwhite
+
+syn keyword nanorcBGMagenta     contained magenta
+                                \ nextgroup=@nanorcBGSpec skipwhite
+
+syn keyword nanorcBGCyan        contained cyan
+                                \ nextgroup=@nanorcBGSpec skipwhite
+
+syn keyword nanorcBGBWhite      contained brightwhite
+                                \ nextgroup=@nanorcBGSpec skipwhite
+
+syn keyword nanorcBGBBlack      contained brightblack
+                                \ nextgroup=@nanorcBGSpec skipwhite
+
+syn keyword nanorcBGBRed        contained brightred
+                                \ nextgroup=@nanorcBGSpec skipwhite
+
+syn keyword nanorcBGBBlue       contained brightblue
+                                \ nextgroup=@nanorcBGSpec skipwhite
+
+syn keyword nanorcBGBGreen      contained brightgreen
+                                \ nextgroup=@nanorcBGSpec skipwhite
+
+syn keyword nanorcBGBYellow     contained brightyellow
+                                \ nextgroup=@nanorcBGSpec skipwhite
+
+syn keyword nanorcBGBMagenta    contained brightmagenta
+                                \ nextgroup=@nanorcBGSpec skipwhite
+
+syn keyword nanorcBGBCyan       contained brightcyan
+                                \ nextgroup=@nanorcBGSpec skipwhite
+
+syn match   nanorcBGColorSep    contained ',' nextgroup=@nanorcBGColor
+
+syn cluster nanorcFGSpec        contains=nanorcBGColorSep,nanorcRegexes,
+                                \ nanorcStartRegion
+
+syn cluster nanorcBGSpec        contains=nanorcRegexes,nanorcStartRegion
+
+syn keyword nanorcStartRegion   contained start nextgroup=nanorcStartRegionEq
+
+syn match   nanorcStartRegionEq contained '=' nextgroup=nanorcRegion
+
+syn region  nanorcRegion        contained display oneline start=+"+
+                                \ end=+"\ze\%([[:blank:]]\|$\)+
+                                \ nextgroup=nanorcEndRegion skipwhite
+
+syn keyword nanorcEndRegion     contained end nextgroup=nanorcStartRegionEq
+
+syn match   nanorcEndRegionEq   contained '=' nextgroup=nanorcRegex
+
+syn region  nanorcRegex         contained display oneline start=+"+
+                                \ end=+"\ze\%([[:blank:]]\|$\)+
+
+hi def link nanorcTodo          Todo
+hi def link nanorcComment       Comment
+hi def link nanorcKeyword       Keyword
+hi def link nanorcBoolOption    Identifier
+hi def link nanorcStringOption  Identifier
+hi def link nanorcNumberOption  Identifier
+hi def link nanorcSynGroupName  String
+hi def link nanorcString        String
+hi def link nanorcRegexes       nanorcString
+hi def link nanorcNumber        Number
+hi def      nanorcFGWhite       ctermfg=Gray guifg=Gray
+hi def      nanorcFGBlack       ctermfg=Black guifg=Black
+hi def      nanorcFGRed         ctermfg=DarkRed guifg=DarkRed
+hi def      nanorcFGBlue        ctermfg=DarkBlue guifg=DarkBlue
+hi def      nanorcFGGreen       ctermfg=DarkGreen guifg=DarkGreen
+hi def      nanorcFGYellow      ctermfg=Brown guifg=Brown
+hi def      nanorcFGMagenta     ctermfg=DarkMagenta guifg=DarkMagenta
+hi def      nanorcFGCyan        ctermfg=DarkCyan guifg=DarkCyan
+hi def      nanorcFGBWhite      ctermfg=White guifg=White
+hi def      nanorcFGBBlack      ctermfg=DarkGray guifg=DarkGray
+hi def      nanorcFGBRed        ctermfg=Red guifg=Red
+hi def      nanorcFGBBlue       ctermfg=Blue guifg=Blue
+hi def      nanorcFGBGreen      ctermfg=Green guifg=Green
+hi def      nanorcFGBYellow     ctermfg=Yellow guifg=Yellow
+hi def      nanorcFGBMagenta    ctermfg=Magenta guifg=Magenta
+hi def      nanorcFGBCyan       ctermfg=Cyan guifg=Cyan
+hi def link nanorcBGColorSep    Normal
+hi def      nanorcBGWhite       ctermbg=Gray guibg=Gray
+hi def      nanorcBGBlack       ctermbg=Black guibg=Black
+hi def      nanorcBGRed         ctermbg=DarkRed guibg=DarkRed
+hi def      nanorcBGBlue        ctermbg=DarkBlue guibg=DarkBlue
+hi def      nanorcBGGreen       ctermbg=DarkGreen guibg=DarkGreen
+hi def      nanorcBGYellow      ctermbg=Brown guibg=Brown
+hi def      nanorcBGMagenta     ctermbg=DarkMagenta guibg=DarkMagenta
+hi def      nanorcBGCyan        ctermbg=DarkCyan guibg=DarkCyan
+hi def      nanorcBGBWhite      ctermbg=White guibg=White
+hi def      nanorcBGBBlack      ctermbg=DarkGray guibg=DarkGray
+hi def      nanorcBGBRed        ctermbg=Red guibg=Red
+hi def      nanorcBGBBlue       ctermbg=Blue guibg=Blue
+hi def      nanorcBGBGreen      ctermbg=Green guibg=Green
+hi def      nanorcBGBYellow     ctermbg=Yellow guibg=Yellow
+hi def      nanorcBGBMagenta    ctermbg=Magenta guibg=Magenta
+hi def      nanorcBGBCyan       ctermbg=Cyan guibg=Cyan
+hi def link nanorcStartRegion   Type
+hi def link nanorcStartRegionEq Operator
+hi def link nanorcRegion        nanorcString
+hi def link nanorcEndRegion     Type
+hi def link nanorcEndRegionEq   Operator
+hi def link nanorcRegex         nanoRegexes
+
+let b:current_syntax = "nanorc"
+
+let &cpo = s:cpo_save
+unlet s:cpo_save
--- /dev/null
+++ b/lib/vimfiles/syntax/nasm.vim
@@ -1,0 +1,522 @@
+" Vim syntax file
+" Language:	NASM - The Netwide Assembler (v0.98)
+" Maintainer:	Manuel M.H. Stol	<mmh.stol@gmx.net>
+" Last Change:	2003 May 11
+" Vim URL:	http://www.vim.org/lang.html
+" NASM Home:	http://www.cryogen.com/Nasm/
+
+
+
+" Setup Syntax:
+"  Clear old syntax settings
+if version < 600
+  syn clear
+elseif exists("b:current_syntax")
+  finish
+endif
+"  Assembler syntax is case insensetive
+syn case ignore
+
+
+
+" Vim search and movement commands on identifers
+if version < 600
+  "  Comments at start of a line inside which to skip search for indentifiers
+  set comments=:;
+  "  Identifier Keyword characters (defines \k)
+  set iskeyword=@,48-57,#,$,.,?,@-@,_,~
+else
+  "  Comments at start of a line inside which to skip search for indentifiers
+  setlocal comments=:;
+  "  Identifier Keyword characters (defines \k)
+  setlocal iskeyword=@,48-57,#,$,.,?,@-@,_,~
+endif
+
+
+
+" Comments:
+syn region  nasmComment		start=";" keepend end="$" contains=@nasmGrpInComments
+syn region  nasmSpecialComment	start=";\*\*\*" keepend end="$"
+syn keyword nasmInCommentTodo	contained TODO FIXME XXX[XXXXX]
+syn cluster nasmGrpInComments	contains=nasmInCommentTodo
+syn cluster nasmGrpComments	contains=@nasmGrpInComments,nasmComment,nasmSpecialComment
+
+
+
+" Label Identifiers:
+"  in NASM: 'Everything is a Label'
+"  Definition Label = label defined by %[i]define or %[i]assign
+"  Identifier Label = label defined as first non-keyword on a line or %[i]macro
+syn match   nasmLabelError	"$\=\(\d\+\K\|[#\.@]\|\$\$\k\)\k*\>"
+syn match   nasmLabel		"\<\(\h\|[?@]\)\k*\>"
+syn match   nasmLabel		"[\$\~]\(\h\|[?@]\)\k*\>"lc=1
+"  Labels starting with one or two '.' are special
+syn match   nasmLocalLabel	"\<\.\(\w\|[#$?@~]\)\k*\>"
+syn match   nasmLocalLabel	"\<\$\.\(\w\|[#$?@~]\)\k*\>"ms=s+1
+if !exists("nasm_no_warn")
+  syn match  nasmLabelWarn	"\<\~\=\$\=[_\.][_\.\~]*\>"
+endif
+if exists("nasm_loose_syntax")
+  syn match   nasmSpecialLabel	"\<\.\.@\k\+\>"
+  syn match   nasmSpecialLabel	"\<\$\.\.@\k\+\>"ms=s+1
+  if !exists("nasm_no_warn")
+    syn match   nasmLabelWarn	"\<\$\=\.\.@\(\d\|[#$\.~]\)\k*\>"
+  endif
+  " disallow use of nasm internal label format
+  syn match   nasmLabelError	"\<\$\=\.\.@\d\+\.\k*\>"
+else
+  syn match   nasmSpecialLabel	"\<\.\.@\(\h\|[?@]\)\k*\>"
+  syn match   nasmSpecialLabel	"\<\$\.\.@\(\h\|[?@]\)\k*\>"ms=s+1
+endif
+"  Labels can be dereferenced with '$' to destinguish them from reserved words
+syn match   nasmLabelError	"\<\$\K\k*\s*:"
+syn match   nasmLabelError	"^\s*\$\K\k*\>"
+syn match   nasmLabelError	"\<\~\s*\(\k*\s*:\|\$\=\.\k*\)"
+
+
+
+" Constants:
+syn match   nasmStringError	+["']+
+syn match   nasmString		+\("[^"]\{-}"\|'[^']\{-}'\)+
+syn match   nasmBinNumber	"\<[0-1]\+b\>"
+syn match   nasmBinNumber	"\<\~[0-1]\+b\>"lc=1
+syn match   nasmOctNumber	"\<\o\+q\>"
+syn match   nasmOctNumber	"\<\~\o\+q\>"lc=1
+syn match   nasmDecNumber	"\<\d\+\>"
+syn match   nasmDecNumber	"\<\~\d\+\>"lc=1
+syn match   nasmHexNumber	"\<\(\d\x*h\|0x\x\+\|\$\d\x*\)\>"
+syn match   nasmHexNumber	"\<\~\(\d\x*h\|0x\x\+\|\$\d\x*\)\>"lc=1
+syn match   nasmFltNumber	"\<\d\+\.\d*\(e[+-]\=\d\+\)\=\>"
+syn keyword nasmFltNumber	Inf Infinity Indefinite NaN SNaN QNaN
+syn match   nasmNumberError	"\<\~\s*\d\+\.\d*\(e[+-]\=\d\+\)\=\>"
+
+
+
+" Netwide Assembler Storage Directives:
+"  Storage types
+syn keyword nasmTypeError	DF EXTRN FWORD RESF TBYTE
+syn keyword nasmType		FAR NEAR SHORT
+syn keyword nasmType		BYTE WORD DWORD QWORD DQWORD HWORD DHWORD TWORD
+syn keyword nasmType		CDECL FASTCALL NONE PASCAL STDCALL
+syn keyword nasmStorage		DB DW DD DQ DDQ DT
+syn keyword nasmStorage		RESB RESW RESD RESQ RESDQ REST
+syn keyword nasmStorage		EXTERN GLOBAL COMMON
+"  Structured storage types
+syn match   nasmTypeError	"\<\(AT\|I\=\(END\)\=\(STRUCT\=\|UNION\)\|I\=END\)\>"
+syn match   nasmStructureLabel	contained "\<\(AT\|I\=\(END\)\=\(STRUCT\=\|UNION\)\|I\=END\)\>"
+"   structures cannot be nested (yet) -> use: 'keepend' and 're='
+syn cluster nasmGrpCntnStruc	contains=ALLBUT,@nasmGrpInComments,nasmMacroDef,@nasmGrpInMacros,@nasmGrpInPreCondits,nasmStructureDef,@nasmGrpInStrucs
+syn region  nasmStructureDef	transparent matchgroup=nasmStructure keepend start="^\s*STRUCT\>"hs=e-5 end="^\s*ENDSTRUCT\>"re=e-9 contains=@nasmGrpCntnStruc
+syn region  nasmStructureDef	transparent matchgroup=nasmStructure keepend start="^\s*STRUC\>"hs=e-4  end="^\s*ENDSTRUC\>"re=e-8  contains=@nasmGrpCntnStruc
+syn region  nasmStructureDef	transparent matchgroup=nasmStructure keepend start="\<ISTRUCT\=\>" end="\<IEND\(STRUCT\=\)\=\>" contains=@nasmGrpCntnStruc,nasmInStructure
+"   union types are not part of nasm (yet)
+"syn region  nasmStructureDef	transparent matchgroup=nasmStructure keepend start="^\s*UNION\>"hs=e-4 end="^\s*ENDUNION\>"re=e-8 contains=@nasmGrpCntnStruc
+"syn region  nasmStructureDef	transparent matchgroup=nasmStructure keepend start="\<IUNION\>" end="\<IEND\(UNION\)\=\>" contains=@nasmGrpCntnStruc,nasmInStructure
+syn match   nasmInStructure	contained "^\s*AT\>"hs=e-1
+syn cluster nasmGrpInStrucs	contains=nasmStructure,nasmInStructure,nasmStructureLabel
+
+
+
+" PreProcessor Instructions:
+" NAsm PreProcs start with %, but % is not a character
+syn match   nasmPreProcError	"%{\=\(%\=\k\+\|%%\+\k*\|[+-]\=\d\+\)}\="
+if exists("nasm_loose_syntax")
+  syn cluster nasmGrpNxtCtx	contains=nasmStructureLabel,nasmLabel,nasmLocalLabel,nasmSpecialLabel,nasmLabelError,nasmPreProcError
+else
+  syn cluster nasmGrpNxtCtx	contains=nasmStructureLabel,nasmLabel,nasmLabelError,nasmPreProcError
+endif
+
+"  Multi-line macro
+syn cluster nasmGrpCntnMacro	contains=ALLBUT,@nasmGrpInComments,nasmStructureDef,@nasmGrpInStrucs,nasmMacroDef,@nasmGrpPreCondits,nasmMemReference,nasmInMacPreCondit,nasmInMacStrucDef
+syn region  nasmMacroDef	matchgroup=nasmMacro keepend start="^\s*%macro\>"hs=e-5 start="^\s*%imacro\>"hs=e-6 end="^\s*%endmacro\>"re=e-9 contains=@nasmGrpCntnMacro,nasmInMacStrucDef
+if exists("nasm_loose_syntax")
+  syn match  nasmInMacLabel	contained "%\(%\k\+\>\|{%\k\+}\)"
+  syn match  nasmInMacLabel	contained "%\($\+\(\w\|[#\.?@~]\)\k*\>\|{$\+\(\w\|[#\.?@~]\)\k*}\)"
+  syn match  nasmInMacPreProc	contained "^\s*%\(push\|repl\)\>"hs=e-4 skipwhite nextgroup=nasmStructureLabel,nasmLabel,nasmInMacParam,nasmLocalLabel,nasmSpecialLabel,nasmLabelError,nasmPreProcError
+  if !exists("nasm_no_warn")
+    syn match nasmInMacLblWarn	contained "%\(%[$\.]\k*\>\|{%[$\.]\k*}\)"
+    syn match nasmInMacLblWarn	contained "%\($\+\(\d\|[#\.@~]\)\k*\|{\$\+\(\d\|[#\.@~]\)\k*}\)"
+    hi link nasmInMacCatLabel	nasmInMacLblWarn
+  else
+    hi link nasmInMacCatLabel	nasmInMacLabel
+  endif
+else
+  syn match  nasmInMacLabel	contained "%\(%\(\w\|[#?@~]\)\k*\>\|{%\(\w\|[#?@~]\)\k*}\)"
+  syn match  nasmInMacLabel	contained "%\($\+\(\h\|[?@]\)\k*\>\|{$\+\(\h\|[?@]\)\k*}\)"
+  hi link nasmInMacCatLabel	nasmLabelError
+endif
+syn match   nasmInMacCatLabel	contained "\d\K\k*"lc=1
+syn match   nasmInMacLabel	contained "\d}\k\+"lc=2
+if !exists("nasm_no_warn")
+  syn match  nasmInMacLblWarn	contained "%\(\($\+\|%\)[_~][._~]*\>\|{\($\+\|%\)[_~][._~]*}\)"
+endif
+syn match   nasmInMacPreProc	contained "^\s*%pop\>"hs=e-3
+syn match   nasmInMacPreProc	contained "^\s*%\(push\|repl\)\>"hs=e-4 skipwhite nextgroup=@nasmGrpNxtCtx
+"   structures cannot be nested (yet) -> use: 'keepend' and 're='
+syn region  nasmInMacStrucDef	contained transparent matchgroup=nasmStructure keepend start="^\s*STRUCT\>"hs=e-5 end="^\s*ENDSTRUCT\>"re=e-9 contains=@nasmGrpCntnMacro
+syn region  nasmInMacStrucDef	contained transparent matchgroup=nasmStructure keepend start="^\s*STRUC\>"hs=e-4  end="^\s*ENDSTRUC\>"re=e-8  contains=@nasmGrpCntnMacro
+syn region  nasmInMacStrucDef	contained transparent matchgroup=nasmStructure keepend start="\<ISTRUCT\=\>" end="\<IEND\(STRUCT\=\)\=\>" contains=@nasmGrpCntnMacro,nasmInStructure
+"   union types are not part of nasm (yet)
+"syn region  nasmInMacStrucDef	contained transparent matchgroup=nasmStructure keepend start="^\s*UNION\>"hs=e-4 end="^\s*ENDUNION\>"re=e-8 contains=@nasmGrpCntnMacro
+"syn region  nasmInMacStrucDef	contained transparent matchgroup=nasmStructure keepend start="\<IUNION\>" end="\<IEND\(UNION\)\=\>" contains=@nasmGrpCntnMacro,nasmInStructure
+syn region  nasmInMacPreConDef	contained transparent matchgroup=nasmInMacPreCondit start="^\s*%ifnidni\>"hs=e-7 start="^\s*%if\(idni\|n\(ctx\|def\|idn\|num\|str\)\)\>"hs=e-6 start="^\s*%if\(ctx\|def\|idn\|nid\|num\|str\)\>"hs=e-5 start="^\s*%ifid\>"hs=e-4 start="^\s*%if\>"hs=e-2 end="%endif\>" contains=@nasmGrpCntnMacro,nasmInMacPreCondit,nasmInPreCondit
+syn match   nasmInMacPreCondit	contained transparent "ctx\s"lc=3 skipwhite nextgroup=@nasmGrpNxtCtx
+syn match   nasmInMacPreCondit	contained "^\s*%elifctx\>"hs=e-7 skipwhite nextgroup=@nasmGrpNxtCtx
+syn match   nasmInMacPreCondit	contained "^\s*%elifnctx\>"hs=e-8 skipwhite nextgroup=@nasmGrpNxtCtx
+syn match   nasmInMacParamNum	contained "\<\d\+\.list\>"me=e-5
+syn match   nasmInMacParamNum	contained "\<\d\+\.nolist\>"me=e-7
+syn match   nasmInMacDirective	contained "\.\(no\)\=list\>"
+syn match   nasmInMacMacro	contained transparent "macro\s"lc=5 skipwhite nextgroup=nasmStructureLabel
+syn match   nasmInMacMacro	contained "^\s*%rotate\>"hs=e-6
+syn match   nasmInMacParam	contained "%\([+-]\=\d\+\|{[+-]\=\d\+}\)"
+"   nasm conditional macro operands/arguments
+"   Todo: check feasebility; add too nasmGrpInMacros, etc.
+"syn match   nasmInMacCond	contained "\<\(N\=\([ABGL]E\=\|[CEOSZ]\)\|P[EO]\=\)\>"
+syn cluster nasmGrpInMacros	contains=nasmMacro,nasmInMacMacro,nasmInMacParam,nasmInMacParamNum,nasmInMacDirective,nasmInMacLabel,nasmInMacLblWarn,nasmInMacMemRef,nasmInMacPreConDef,nasmInMacPreCondit,nasmInMacPreProc,nasmInMacStrucDef
+
+"   Context pre-procs that are better used inside a macro
+if exists("nasm_ctx_outside_macro")
+  syn region nasmPreConditDef	transparent matchgroup=nasmCtxPreCondit start="^\s*%ifnctx\>"hs=e-6 start="^\s*%ifctx\>"hs=e-5 end="%endif\>" contains=@nasmGrpCntnPreCon
+  syn match  nasmCtxPreProc	"^\s*%pop\>"hs=e-3
+  if exists("nasm_loose_syntax")
+    syn match   nasmCtxLocLabel	"%$\+\(\w\|[#\.?@~]\)\k*\>"
+  else
+    syn match   nasmCtxLocLabel	"%$\+\(\h\|[?@]\)\k*\>"
+  endif
+  syn match nasmCtxPreProc	"^\s*%\(push\|repl\)\>"hs=e-4 skipwhite nextgroup=@nasmGrpNxtCtx
+  syn match nasmCtxPreCondit	contained transparent "ctx\s"lc=3 skipwhite nextgroup=@nasmGrpNxtCtx
+  syn match nasmCtxPreCondit	contained "^\s*%elifctx\>"hs=e-7 skipwhite nextgroup=@nasmGrpNxtCtx
+  syn match nasmCtxPreCondit	contained "^\s*%elifnctx\>"hs=e-8 skipwhite nextgroup=@nasmGrpNxtCtx
+  if exists("nasm_no_warn")
+    hi link nasmCtxPreCondit	nasmPreCondit
+    hi link nasmCtxPreProc	nasmPreProc
+    hi link nasmCtxLocLabel	nasmLocalLabel
+  else
+    hi link nasmCtxPreCondit	nasmPreProcWarn
+    hi link nasmCtxPreProc	nasmPreProcWarn
+    hi link nasmCtxLocLabel	nasmLabelWarn
+  endif
+endif
+
+"  Conditional assembly
+syn cluster nasmGrpCntnPreCon	contains=ALLBUT,@nasmGrpInComments,@nasmGrpInMacros,@nasmGrpInStrucs
+syn region  nasmPreConditDef	transparent matchgroup=nasmPreCondit start="^\s*%ifnidni\>"hs=e-7 start="^\s*%if\(idni\|n\(def\|idn\|num\|str\)\)\>"hs=e-6 start="^\s*%if\(def\|idn\|nid\|num\|str\)\>"hs=e-5 start="^\s*%ifid\>"hs=e-4 start="^\s*%if\>"hs=e-2 end="%endif\>" contains=@nasmGrpCntnPreCon
+syn match   nasmInPreCondit	contained "^\s*%el\(if\|se\)\>"hs=e-4
+syn match   nasmInPreCondit	contained "^\s*%elifid\>"hs=e-6
+syn match   nasmInPreCondit	contained "^\s*%elif\(def\|idn\|nid\|num\|str\)\>"hs=e-7
+syn match   nasmInPreCondit	contained "^\s*%elif\(n\(def\|idn\|num\|str\)\|idni\)\>"hs=e-8
+syn match   nasmInPreCondit	contained "^\s*%elifnidni\>"hs=e-9
+syn cluster nasmGrpInPreCondits	contains=nasmPreCondit,nasmInPreCondit,nasmCtxPreCondit
+syn cluster nasmGrpPreCondits	contains=nasmPreConditDef,@nasmGrpInPreCondits,nasmCtxPreProc,nasmCtxLocLabel
+
+"  Other pre-processor statements
+syn match   nasmPreProc		"^\s*%rep\>"hs=e-3
+syn match   nasmPreProc		"^\s*%line\>"hs=e-4
+syn match   nasmPreProc		"^\s*%\(clear\|error\)\>"hs=e-5
+syn match   nasmPreProc		"^\s*%endrep\>"hs=e-6
+syn match   nasmPreProc		"^\s*%exitrep\>"hs=e-7
+syn match   nasmDefine		"^\s*%undef\>"hs=e-5
+syn match   nasmDefine		"^\s*%\(assign\|define\)\>"hs=e-6
+syn match   nasmDefine		"^\s*%i\(assign\|define\)\>"hs=e-7
+syn match   nasmInclude		"^\s*%include\>"hs=e-7
+
+"  Multiple pre-processor instructions on single line detection (obsolete)
+"syn match   nasmPreProcError	+^\s*\([^\t "%';][^"%';]*\|[^\t "';][^"%';]\+\)%\a\+\>+
+syn cluster nasmGrpPreProcs	contains=nasmMacroDef,@nasmGrpInMacros,@nasmGrpPreCondits,nasmPreProc,nasmDefine,nasmInclude,nasmPreProcWarn,nasmPreProcError
+
+
+
+" Register Identifiers:
+"  Register operands:
+syn match   nasmGen08Register	"\<[A-D][HL]\>"
+syn match   nasmGen16Register	"\<\([A-D]X\|[DS]I\|[BS]P\)\>"
+syn match   nasmGen32Register	"\<E\([A-D]X\|[DS]I\|[BS]P\)\>"
+syn match   nasmSegRegister	"\<[C-GS]S\>"
+syn match   nasmSpcRegister	"\<E\=IP\>"
+syn match   nasmFpuRegister	"\<ST\o\>"
+syn match   nasmMmxRegister	"\<MM\o\>"
+syn match   nasmSseRegister	"\<XMM\o\>"
+syn match   nasmCtrlRegister	"\<CR\o\>"
+syn match   nasmDebugRegister	"\<DR\o\>"
+syn match   nasmTestRegister	"\<TR\o\>"
+syn match   nasmRegisterError	"\<\(CR[15-9]\|DR[4-58-9]\|TR[0-28-9]\)\>"
+syn match   nasmRegisterError	"\<X\=MM[8-9]\>"
+syn match   nasmRegisterError	"\<ST\((\d)\|[8-9]\>\)"
+syn match   nasmRegisterError	"\<E\([A-D][HL]\|[C-GS]S\)\>"
+"  Memory reference operand (address):
+syn match   nasmMemRefError	"[\[\]]"
+syn cluster nasmGrpCntnMemRef	contains=ALLBUT,@nasmGrpComments,@nasmGrpPreProcs,@nasmGrpInStrucs,nasmMemReference,nasmMemRefError
+syn match   nasmInMacMemRef	contained "\[[^;\[\]]\{-}\]" contains=@nasmGrpCntnMemRef,nasmPreProcError,nasmInMacLabel,nasmInMacLblWarn,nasmInMacParam
+syn match   nasmMemReference	"\[[^;\[\]]\{-}\]" contains=@nasmGrpCntnMemRef,nasmPreProcError,nasmCtxLocLabel
+
+
+
+" Netwide Assembler Directives:
+"  Compilation constants
+syn keyword nasmConstant	__BITS__ __DATE__ __FILE__ __FORMAT__ __LINE__
+syn keyword nasmConstant	__NASM_MAJOR__ __NASM_MINOR__ __NASM_VERSION__
+syn keyword nasmConstant	__TIME__
+"  Instruction modifiers
+syn match   nasmInstructnError	"\<TO\>"
+syn match   nasmInstrModifier	"\(^\|:\)\s*[C-GS]S\>"ms=e-1
+syn keyword nasmInstrModifier	A16 A32 O16 O32
+syn match   nasmInstrModifier	"\<F\(ADD\|MUL\|\(DIV\|SUB\)R\=\)\s\+TO\>"lc=5,ms=e-1
+"   the 'to' keyword is not allowed for fpu-pop instructions (yet)
+"syn match   nasmInstrModifier	"\<F\(ADD\|MUL\|\(DIV\|SUB\)R\=\)P\s\+TO\>"lc=6,ms=e-1
+"  NAsm directives
+syn keyword nasmRepeat		TIMES
+syn keyword nasmDirective	ALIGN[B] INCBIN EQU NOSPLIT SPLIT
+syn keyword nasmDirective	ABSOLUTE BITS SECTION SEGMENT
+syn keyword nasmDirective	ENDSECTION ENDSEGMENT
+syn keyword nasmDirective	__SECT__
+"  Macro created standard directives: (requires %include)
+syn case match
+syn keyword nasmStdDirective	ENDPROC EPILOGUE LOCALS PROC PROLOGUE USES
+syn keyword nasmStdDirective	ENDIF ELSE ELIF ELSIF IF
+"syn keyword nasmStdDirective	BREAK CASE DEFAULT ENDSWITCH SWITCH
+"syn keyword nasmStdDirective	CASE OF ENDCASE
+syn keyword nasmStdDirective	DO ENDFOR ENDWHILE FOR REPEAT UNTIL WHILE EXIT
+syn case ignore
+"  Format specific directives: (all formats)
+"  (excluded: extension directives to section, global, common and extern)
+syn keyword nasmFmtDirective	ORG
+syn keyword nasmFmtDirective	EXPORT IMPORT GROUP UPPERCASE SEG WRT
+syn keyword nasmFmtDirective	LIBRARY
+syn case match
+syn keyword nasmFmtDirective	_GLOBAL_OFFSET_TABLE_ __GLOBAL_OFFSET_TABLE_
+syn keyword nasmFmtDirective	..start ..got ..gotoff ..gotpc ..plt ..sym
+syn case ignore
+
+
+
+" Standard Instructions:
+syn match   nasmInstructnError	"\<\(F\=CMOV\|SET\)N\=\a\{0,2}\>"
+syn keyword nasmInstructnError	CMPS MOVS LCS LODS STOS XLAT
+syn match   nasmStdInstruction	"\<MOV\>"
+syn match   nasmInstructnError	"\<MOV\s[^,;[]*\<CS\>\s*[^:]"he=e-1
+syn match   nasmStdInstruction	"\<\(CMOV\|J\|SET\)\(N\=\([ABGL]E\=\|[CEOSZ]\)\|P[EO]\=\)\>"
+syn match   nasmStdInstruction	"\<POP\>"
+syn keyword nasmStdInstruction	AAA AAD AAM AAS ADC ADD AND
+syn keyword nasmStdInstruction	BOUND BSF BSR BSWAP BT[C] BTR BTS
+syn keyword nasmStdInstruction	CALL CBW CDQ CLC CLD CMC CMP CMPSB CMPSD CMPSW
+syn keyword nasmStdInstruction	CMPXCHG CMPXCHG8B CPUID CWD[E]
+syn keyword nasmStdInstruction	DAA DAS DEC DIV ENTER
+syn keyword nasmStdInstruction	IDIV IMUL INC INT[O] IRET[D] IRETW
+syn keyword nasmStdInstruction	JCXZ JECXZ JMP
+syn keyword nasmStdInstruction	LAHF LDS LEA LEAVE LES LFS LGS LODSB LODSD
+syn keyword nasmStdInstruction	LODSW LOOP[E] LOOPNE LOOPNZ LOOPZ LSS
+syn keyword nasmStdInstruction	MOVSB MOVSD MOVSW MOVSX MOVZX MUL NEG NOP NOT
+syn keyword nasmStdInstruction	OR POPA[D] POPAW POPF[D] POPFW
+syn keyword nasmStdInstruction	PUSH[AD] PUSHAW PUSHF[D] PUSHFW
+syn keyword nasmStdInstruction	RCL RCR RETF RET[N] ROL ROR
+syn keyword nasmStdInstruction	SAHF SAL SAR SBB SCASB SCASD SCASW
+syn keyword nasmStdInstruction	SHL[D] SHR[D] STC STD STOSB STOSD STOSW SUB
+syn keyword nasmStdInstruction	TEST XADD XCHG XLATB XOR
+
+
+" System Instructions: (usually privileged)
+"  Verification of pointer parameters
+syn keyword nasmSysInstruction	ARPL LAR LSL VERR VERW
+"  Addressing descriptor tables
+syn keyword nasmSysInstruction	LLDT SLDT LGDT SGDT
+"  Multitasking
+syn keyword nasmSysInstruction	LTR STR
+"  Coprocessing and Multiprocessing (requires fpu and multiple cpu's resp.)
+syn keyword nasmSysInstruction	CLTS LOCK WAIT
+"  Input and Output
+syn keyword nasmInstructnError	INS OUTS
+syn keyword nasmSysInstruction	IN INSB INSW INSD OUT OUTSB OUTSB OUTSW OUTSD
+"  Interrupt control
+syn keyword nasmSysInstruction	CLI STI LIDT SIDT
+"  System control
+syn match   nasmSysInstruction	"\<MOV\s[^;]\{-}\<CR\o\>"me=s+3
+syn keyword nasmSysInstruction	HLT INVD LMSW
+syn keyword nasmSseInstruction	PREFETCHT0 PREFETCHT1 PREFETCHT2 PREFETCHNTA
+syn keyword nasmSseInstruction	RSM SFENCE SMSW SYSENTER SYSEXIT UD2 WBINVD
+"  TLB (Translation Lookahead Buffer) testing
+syn match   nasmSysInstruction	"\<MOV\s[^;]\{-}\<TR\o\>"me=s+3
+syn keyword nasmSysInstruction	INVLPG
+
+" Debugging Instructions: (privileged)
+syn match   nasmDbgInstruction	"\<MOV\s[^;]\{-}\<DR\o\>"me=s+3
+syn keyword nasmDbgInstruction	INT1 INT3 RDMSR RDTSC RDPMC WRMSR
+
+
+" Floating Point Instructions: (requires FPU)
+syn match   nasmFpuInstruction	"\<FCMOVN\=\([AB]E\=\|[CEPUZ]\)\>"
+syn keyword nasmFpuInstruction	F2XM1 FABS FADD[P] FBLD FBSTP
+syn keyword nasmFpuInstruction	FCHS FCLEX FCOM[IP] FCOMP[P] FCOS
+syn keyword nasmFpuInstruction	FDECSTP FDISI FDIV[P] FDIVR[P] FENI FFREE
+syn keyword nasmFpuInstruction	FIADD FICOM[P] FIDIV[R] FILD
+syn keyword nasmFpuInstruction	FIMUL FINCSTP FINIT FIST[P] FISUB[R]
+syn keyword nasmFpuInstruction	FLD[1] FLDCW FLDENV FLDL2E FLDL2T FLDLG2
+syn keyword nasmFpuInstruction	FLDLN2 FLDPI FLDZ FMUL[P]
+syn keyword nasmFpuInstruction	FNCLEX FNDISI FNENI FNINIT FNOP FNSAVE
+syn keyword nasmFpuInstruction	FNSTCW FNSTENV FNSTSW FNSTSW
+syn keyword nasmFpuInstruction	FPATAN FPREM[1] FPTAN FRNDINT FRSTOR
+syn keyword nasmFpuInstruction	FSAVE FSCALE FSETPM FSIN FSINCOS FSQRT
+syn keyword nasmFpuInstruction	FSTCW FSTENV FST[P] FSTSW FSUB[P] FSUBR[P]
+syn keyword nasmFpuInstruction	FTST FUCOM[IP] FUCOMP[P]
+syn keyword nasmFpuInstruction	FXAM FXCH FXTRACT FYL2X FYL2XP1
+
+
+" Multi Media Xtension Packed Instructions: (requires MMX unit)
+"  Standard MMX instructions: (requires MMX1 unit)
+syn match   nasmInstructnError	"\<P\(ADD\|SUB\)U\=S\=[DQ]\=\>"
+syn match   nasmInstructnError	"\<PCMP\a\{0,2}[BDWQ]\=\>"
+syn keyword nasmMmxInstruction	EMMS MOVD MOVQ
+syn keyword nasmMmxInstruction	PACKSSDW PACKSSWB PACKUSWB PADDB PADDD PADDW
+syn keyword nasmMmxInstruction	PADDSB PADDSW PADDUSB PADDUSW PAND[N]
+syn keyword nasmMmxInstruction	PCMPEQB PCMPEQD PCMPEQW PCMPGTB PCMPGTD PCMPGTW
+syn keyword nasmMmxInstruction	PMACHRIW PMADDWD PMULHW PMULLW POR
+syn keyword nasmMmxInstruction	PSLLD PSLLQ PSLLW PSRAD PSRAW PSRLD PSRLQ PSRLW
+syn keyword nasmMmxInstruction	PSUBB PSUBD PSUBW PSUBSB PSUBSW PSUBUSB PSUBUSW
+syn keyword nasmMmxInstruction	PUNPCKHBW PUNPCKHDQ PUNPCKHWD
+syn keyword nasmMmxInstruction	PUNPCKLBW PUNPCKLDQ PUNPCKLWD PXOR
+"  Extended MMX instructions: (requires MMX2/SSE unit)
+syn keyword nasmMmxInstruction	MASKMOVQ MOVNTQ
+syn keyword nasmMmxInstruction	PAVGB PAVGW PEXTRW PINSRW PMAXSW PMAXUB
+syn keyword nasmMmxInstruction	PMINSW PMINUB PMOVMSKB PMULHUW PSADBW PSHUFW
+
+
+" Streaming SIMD Extension Packed Instructions: (requires SSE unit)
+syn match   nasmInstructnError	"\<CMP\a\{1,5}[PS]S\>"
+syn match   nasmSseInstruction	"\<CMP\(N\=\(EQ\|L[ET]\)\|\(UN\)\=ORD\)\=[PS]S\>"
+syn keyword nasmSseInstruction	ADDPS ADDSS ANDNPS ANDPS
+syn keyword nasmSseInstruction	COMISS CVTPI2PS CVTPS2PI
+syn keyword nasmSseInstruction	CVTSI2SS CVTSS2SI CVTTPS2PI CVTTSS2SI
+syn keyword nasmSseInstruction	DIVPS DIVSS FXRSTOR FXSAVE LDMXCSR
+syn keyword nasmSseInstruction	MAXPS MAXSS MINPS MINSS MOVAPS MOVHLPS MOVHPS
+syn keyword nasmSseInstruction	MOVLHPS MOVLPS MOVMSKPS MOVNTPS MOVSS MOVUPS
+syn keyword nasmSseInstruction	MULPS MULSS
+syn keyword nasmSseInstruction	ORPS RCPPS RCPSS RSQRTPS RSQRTSS
+syn keyword nasmSseInstruction	SHUFPS SQRTPS SQRTSS STMXCSR SUBPS SUBSS
+syn keyword nasmSseInstruction	UCOMISS UNPCKHPS UNPCKLPS XORPS
+
+
+" Three Dimensional Now Packed Instructions: (requires 3DNow! unit)
+syn keyword nasmNowInstruction	FEMMS PAVGUSB PF2ID PFACC PFADD PFCMPEQ PFCMPGE
+syn keyword nasmNowInstruction	PFCMPGT PFMAX PFMIN PFMUL PFRCP PFRCPIT1
+syn keyword nasmNowInstruction	PFRCPIT2 PFRSQIT1 PFRSQRT PFSUB[R] PI2FD
+syn keyword nasmNowInstruction	PMULHRWA PREFETCH[W]
+
+
+" Vendor Specific Instructions:
+"  Cyrix instructions (requires Cyrix processor)
+syn keyword nasmCrxInstruction	PADDSIW PAVEB PDISTIB PMAGW PMULHRW[C] PMULHRIW
+syn keyword nasmCrxInstruction	PMVGEZB PMVLZB PMVNZB PMVZB PSUBSIW
+syn keyword nasmCrxInstruction	RDSHR RSDC RSLDT SMINT SMINTOLD SVDC SVLDT SVTS
+syn keyword nasmCrxInstruction	WRSHR
+"  AMD instructions (requires AMD processor)
+syn keyword nasmAmdInstruction	SYSCALL SYSRET
+
+
+" Undocumented Instructions:
+syn match   nasmUndInstruction	"\<POP\s[^;]*\<CS\>"me=s+3
+syn keyword nasmUndInstruction	CMPXCHG486 IBTS ICEBP INT01 INT03 LOADALL
+syn keyword nasmUndInstruction	LOADALL286 LOADALL386 SALC SMI UD1 UMOV XBTS
+
+
+
+" Synchronize Syntax:
+syn sync clear
+syn sync minlines=50		"for multiple region nesting
+syn sync match  nasmSync	grouphere nasmMacroDef "^\s*%i\=macro\>"me=s-1
+syn sync match	nasmSync	grouphere NONE	       "^\s*%endmacro\>"
+
+
+" Define the default highlighting.
+" For version 5.7 and earlier: only when not done already
+" For version 5.8 and later  : only when an item doesn't have highlighting yet
+if version >= 508 || !exists("did_nasm_syntax_inits")
+  if version < 508
+    let did_nasm_syntax_inits = 1
+    command -nargs=+ HiLink hi link <args>
+  else
+    command -nargs=+ HiLink hi def link <args>
+  endif
+
+  " Sub Links:
+  HiLink nasmInMacDirective	nasmDirective
+  HiLink nasmInMacLabel		nasmLocalLabel
+  HiLink nasmInMacLblWarn	nasmLabelWarn
+  HiLink nasmInMacMacro		nasmMacro
+  HiLink nasmInMacParam		nasmMacro
+  HiLink nasmInMacParamNum	nasmDecNumber
+  HiLink nasmInMacPreCondit	nasmPreCondit
+  HiLink nasmInMacPreProc	nasmPreProc
+  HiLink nasmInPreCondit	nasmPreCondit
+  HiLink nasmInStructure	nasmStructure
+  HiLink nasmStructureLabel	nasmStructure
+
+  " Comment Group:
+  HiLink nasmComment		Comment
+  HiLink nasmSpecialComment	SpecialComment
+  HiLink nasmInCommentTodo	Todo
+
+  " Constant Group:
+  HiLink nasmString		String
+  HiLink nasmStringError	Error
+  HiLink nasmBinNumber		Number
+  HiLink nasmOctNumber		Number
+  HiLink nasmDecNumber		Number
+  HiLink nasmHexNumber		Number
+  HiLink nasmFltNumber		Float
+  HiLink nasmNumberError	Error
+
+  " Identifier Group:
+  HiLink nasmLabel		Identifier
+  HiLink nasmLocalLabel		Identifier
+  HiLink nasmSpecialLabel	Special
+  HiLink nasmLabelError		Error
+  HiLink nasmLabelWarn		Todo
+
+  " PreProc Group:
+  HiLink nasmPreProc		PreProc
+  HiLink nasmDefine		Define
+  HiLink nasmInclude		Include
+  HiLink nasmMacro		Macro
+  HiLink nasmPreCondit		PreCondit
+  HiLink nasmPreProcError	Error
+  HiLink nasmPreProcWarn	Todo
+
+  " Type Group:
+  HiLink nasmType		Type
+  HiLink nasmStorage		StorageClass
+  HiLink nasmStructure		Structure
+  HiLink nasmTypeError		Error
+
+  " Directive Group:
+  HiLink nasmConstant		Constant
+  HiLink nasmInstrModifier	Operator
+  HiLink nasmRepeat		Repeat
+  HiLink nasmDirective		Keyword
+  HiLink nasmStdDirective	Operator
+  HiLink nasmFmtDirective	Keyword
+
+  " Register Group:
+  HiLink nasmCtrlRegister	Special
+  HiLink nasmDebugRegister	Debug
+  HiLink nasmTestRegister	Special
+  HiLink nasmRegisterError	Error
+  HiLink nasmMemRefError	Error
+
+  " Instruction Group:
+  HiLink nasmStdInstruction	Statement
+  HiLink nasmSysInstruction	Statement
+  HiLink nasmDbgInstruction	Debug
+  HiLink nasmFpuInstruction	Statement
+  HiLink nasmMmxInstruction	Statement
+  HiLink nasmSseInstruction	Statement
+  HiLink nasmNowInstruction	Statement
+  HiLink nasmAmdInstruction	Special
+  HiLink nasmCrxInstruction	Special
+  HiLink nasmUndInstruction	Todo
+  HiLink nasmInstructnError	Error
+
+  delcommand HiLink
+endif
+
+let b:current_syntax = "nasm"
+
+" vim:ts=8 sw=4
--- /dev/null
+++ b/lib/vimfiles/syntax/nastran.vim
@@ -1,0 +1,193 @@
+" Vim syntax file
+" Language: NASTRAN input/DMAP
+" Maintainer: Tom Kowalski <trk@schaefferas.com>
+" Last change: April 27, 2001
+"  Thanks to the authors and maintainers of fortran.vim.
+"		Since DMAP shares some traits with fortran, this syntax file
+"		is based on the fortran.vim syntax file.
+"----------------------------------------------------------------------
+" Remove any old syntax stuff hanging around
+"syn clear
+if version < 600
+  syntax clear
+elseif exists("b:current_syntax")
+  finish
+endif
+" DMAP is not case dependent
+syn case ignore
+"
+"--------------------DMAP SYNTAX---------------------------------------
+"
+" -------Executive Modules and Statements
+"
+syn keyword nastranDmapexecmod	       call dbview delete end equiv equivx exit
+syn keyword nastranDmapexecmod	       file message purge purgex return subdmap
+syn keyword nastranDmapType	       type
+syn keyword nastranDmapLabel  go to goto
+syn keyword nastranDmapRepeat  if else elseif endif then
+syn keyword nastranDmapRepeat  do while
+syn region nastranDmapString  start=+"+ end=+"+ oneline
+syn region nastranDmapString  start=+'+ end=+'+ oneline
+" If you don't like initial tabs in dmap (or at all)
+"syn match nastranDmapIniTab  "^\t.*$"
+"syn match nastranDmapTab   "\t"
+
+" Any integer
+syn match nastranDmapNumber  "-\=\<[0-9]\+\>"
+" floating point number, with dot, optional exponent
+syn match nastranDmapFloat  "\<[0-9]\+\.[0-9]*\([edED][-+]\=[0-9]\+\)\=\>"
+" floating point number, starting with a dot, optional exponent
+syn match nastranDmapFloat  "\.[0-9]\+\([edED][-+]\=[0-9]\+\)\=\>"
+" floating point number, without dot, with exponent
+syn match nastranDmapFloat  "\<[0-9]\+[edED][-+]\=[0-9]\+\>"
+
+syn match nastranDmapLogical "\(true\|false\)"
+
+syn match nastranDmapPreCondit  "^#define\>"
+syn match nastranDmapPreCondit  "^#include\>"
+"
+" -------Comments may be contained in another line.
+"
+syn match nastranDmapComment "^[\$].*$"
+syn match nastranDmapComment "\$.*$"
+syn match nastranDmapComment "^[\$].*$" contained
+syn match nastranDmapComment "\$.*$"  contained
+" Treat all past 72nd column as a comment. Do not work with tabs!
+" Breaks down when 72-73rd column is in another match (eg number or keyword)
+syn match  nastranDmapComment  "^.\{-72}.*$"lc=72 contained
+
+"
+" -------Utility Modules
+"
+syn keyword nastranDmapUtilmod	       append copy dbc dbdict dbdir dmin drms1
+syn keyword nastranDmapUtilmod	       dtiin eltprt ifp ifp1 inputt2 inputt4 lamx
+syn keyword nastranDmapUtilmod	       matgen matgpr matmod matpch matprn matprt
+syn keyword nastranDmapUtilmod	       modtrl mtrxin ofp output2 output4 param
+syn keyword nastranDmapUtilmod	       paraml paramr prtparam pvt scalar
+syn keyword nastranDmapUtilmod	       seqp setval tabedit tabprt tabpt vec vecplot
+syn keyword nastranDmapUtilmod	       xsort
+"
+" -------Matrix Modules
+"
+syn keyword nastranDmapMatmod	       add add5 cead dcmp decomp diagonal fbs merge
+syn keyword nastranDmapMatmod	       mpyad norm read reigl smpyad solve solvit
+syn keyword nastranDmapMatmod	       trnsp umerge umerge1 upartn dmiin partn
+syn region  nastranDmapMatmod	       start=+^ *[Dd][Mm][Ii]+ end=+[\/]+
+"
+" -------Implicit Functions
+"
+syn keyword nastranDmapImplicit abs acos acosh andl asin asinh atan atan2
+syn keyword nastranDmapImplicit atanh atanh2 char clen clock cmplx concat1
+syn keyword nastranDmapImplicit concat2 concat3 conjg cos cosh dble diagoff
+syn keyword nastranDmapImplicit diagon dim dlablank dlxblank dprod eqvl exp
+syn keyword nastranDmapImplicit getdiag getsys ichar imag impl index indexstr
+syn keyword nastranDmapImplicit int itol leq lge lgt lle llt lne log log10
+syn keyword nastranDmapImplicit logx ltoi mcgetsys mcputsys max min mod neqvl
+syn keyword nastranDmapImplicit nint noop normal notl numeq numge numgt numle
+syn keyword nastranDmapImplicit numlt numne orl pi precison putdiag putsys
+syn keyword nastranDmapImplicit rand rdiagon real rtimtogo setcore sign sin
+syn keyword nastranDmapImplicit sinh sngl sprod sqrt substrin tan tanh
+syn keyword nastranDmapImplicit timetogo wlen xorl
+"
+"
+"--------------------INPUT FILE SYNTAX---------------------------------------
+"
+"
+" -------Nastran Statement
+"
+syn keyword nastranNastranCard		 nastran
+"
+" -------The File Management Section (FMS)
+"
+syn region nastranFMSCard start=+^ *[Aa][Cc][Qq][Uu][Ii]+ end=+$+  oneline
+syn region nastranFMSCard start=+^ *[Aa][Ss][Ss][Ii][Gg]+ end=+$+  oneline
+syn region nastranFMSCard start=+^ *[Cc][oO][Nn][Nn][Ee]+ end=+$+  oneline
+syn region nastranFMSCard start=+^ *[Dd][Bb][Cc][Ll][Ee]+ end=+$+  oneline
+syn region nastranFMSCard start=+^ *[Dd][Bb][Dd][Ii][Cc]+ end=+$+  oneline
+syn region nastranFMSCard start=+^ *[Dd][Bb][Dd][Ii][Rr]+ end=+$+  oneline
+syn region nastranFMSCard start=+^ *[Dd][Bb][Ff][Ii][Xx]+ end=+$+  oneline
+syn region nastranFMSCard start=+^ *[Dd][Bb][Ll][Oo][Aa]+ end=+$+  oneline
+syn region nastranFMSCard start=+^ *[Dd][Bb][Ll][Oo][Cc]+ end=+$+  oneline
+syn region nastranFMSCard start=+^ *[Dd][Bb][Ss][Ee][Tt]+ end=+$+  oneline
+syn region nastranFMSCard start=+^ *[Dd][Bb][Uu][Nn][Ll]+ end=+$+  oneline
+syn region nastranFMSCard start=+^ *[Dd][Bb][Uu][Pp][Dd]+ end=+$+  oneline
+syn region nastranFMSCard start=+^ *[Dd][Ee][Ff][Ii][Nn]+ end=+$+  oneline
+syn region nastranFMSCard start=+^ *[Ee][Nn][Dd][Jj][Oo]+ end=+$+  oneline
+syn region nastranFMSCard start=+^ *[Ee][Xx][Pp][Aa][Nn]+ end=+$+  oneline
+syn region nastranFMSCard start=+^ *[Ii][Nn][Cc][Ll][Uu]+ end=+$+  oneline
+syn region nastranFMSCard start=+^ *[Ii][Nn][Ii][Tt]+ end=+$+  oneline
+syn region nastranFMSCard start=+^ *[Pp][Rr][Oo][Jj]+ end=+$+  oneline
+syn region nastranFMSCard start=+^ *[Rr][Ee][Ss][Tt]+ end=+$+  oneline
+syn match   nastranDmapUtilmod	   "^ *[Rr][Ee][Ss][Tt][Aa].*,.*," contains=nastranDmapComment
+"
+" -------Executive Control Section
+"
+syn region nastranECSCard start=+^ *[Aa][Ll][Tt][Ee][Rr]+ end=+$+  oneline
+syn region nastranECSCard start=+^ *[Aa][Pp][Pp]+ end=+$+  oneline
+syn region nastranECSCard start=+^ *[Cc][Oo][Mm][Pp][Ii]+ end=+$+  oneline
+syn region nastranECSCard start=+^ *[Dd][Ii][Aa][Gg] + end=+$+  oneline
+syn region nastranECSCard start=+^ *[Ee][Cc][Hh][Oo]+ end=+$+  oneline
+syn region nastranECSCard start=+^ *[Ee][Nn][Dd][Aa][Ll]+ end=+$+  oneline
+syn region nastranECSCard start=+^ *[Ii][Dd]+ end=+$+  oneline
+syn region nastranECSCard start=+^ *[Ii][Nn][Cc][Ll][Uu]+ end=+$+  oneline
+syn region nastranECSCard start=+^ *[Ll][Ii][Nn][Kk]+ end=+$+  oneline
+syn region nastranECSCard start=+^ *[Mm][Aa][Ll][Tt][Ee]+ end=+$+  oneline
+syn region nastranECSCard start=+^ *[Ss][Oo][Ll] + end=+$+  oneline
+syn region nastranECSCard start=+^ *[Tt][Ii][Mm][Ee]+ end=+$+  oneline
+"
+" -------Delimiters
+"
+syn match nastranDelimiter "[Cc][Ee][Nn][Dd]" contained
+syn match nastranDelimiter "[Bb][Ee][Gg][Ii][Nn]" contained
+syn match nastranDelimiter " *[Bb][Uu][Ll][Kk]" contained
+syn match nastranDelimiter "[Ee][Nn][Dd] *[dD][Aa][Tt][Aa]" contained
+"
+" -------Case Control section
+"
+syn region nastranCC start=+^ *[Cc][Ee][Nn][Dd]+ end=+^ *[Bb][Ee][Gg][Ii][Nn]+ contains=nastranDelimiter,nastranBulkData,nastranDmapComment
+
+"
+" -------Bulk Data section
+"
+syn region nastranBulkData start=+ *[Bb][Uu][Ll][Kk] *$+ end=+^ [Ee][Nn][Dd] *[Dd]+ contains=nastranDelimiter,nastranDmapComment
+"
+" -------The following cards may appear in multiple sections of the file
+"
+syn keyword nastranUtilCard ECHOON ECHOOFF INCLUDE PARAM
+
+
+if version >= 508 || !exists("did_nastran_syntax_inits")
+  if version < 508
+     let did_nastran_syntax_inits = 1
+     command -nargs=+ HiLink hi link <args>
+  else
+     command -nargs=+ HiLink hi link <args>
+  endif
+  " The default methods for highlighting.  Can be overridden later
+  HiLink nastranDmapexecmod	     Statement
+  HiLink nastranDmapType	     Type
+  HiLink nastranDmapPreCondit	     Error
+  HiLink nastranDmapUtilmod	     PreProc
+  HiLink nastranDmapMatmod	     nastranDmapUtilmod
+  HiLink nastranDmapString	     String
+  HiLink nastranDmapNumber	     Constant
+  HiLink nastranDmapFloat	     nastranDmapNumber
+  HiLink nastranDmapInitTab	     nastranDmapNumber
+  HiLink nastranDmapTab		     nastranDmapNumber
+  HiLink nastranDmapLogical	     nastranDmapExecmod
+  HiLink nastranDmapImplicit	     Identifier
+  HiLink nastranDmapComment	     Comment
+  HiLink nastranDmapRepeat	     nastranDmapexecmod
+  HiLink nastranNastranCard	     nastranDmapPreCondit
+  HiLink nastranECSCard		     nastranDmapUtilmod
+  HiLink nastranFMSCard		     nastranNastranCard
+  HiLink nastranCC		     nastranDmapexecmod
+  HiLink nastranDelimiter	     Special
+  HiLink nastranBulkData	     nastranDmapType
+  HiLink nastranUtilCard	     nastranDmapexecmod
+  delcommand HiLink
+endif
+
+let b:current_syntax = "nastran"
+
+"EOF vim: ts=8 noet tw=120 sw=8 sts=0
--- /dev/null
+++ b/lib/vimfiles/syntax/natural.vim
@@ -1,0 +1,205 @@
+" Vim syntax file
+"
+" Language:		NATURAL
+" Version:		2.0.26.17
+" Maintainer:	Marko Leipert <vim@mleipert.de>
+" Last Changed:	2002-02-28 09:50:36
+" Support:		http://www.winconsole.de/vim/syntax.html
+
+" For version 5.x: Clear all syntax items
+" For version 6.x: Quit when this syntax file was already loaded
+if v:version < 600
+	syntax clear
+	set iskeyword+=-,*,#,+,_,/
+elseif exists("b:current_syntax")
+	finish
+else
+	setlocal iskeyword+=-,*,#,+,_,/
+endif
+
+" NATURAL is case insensitive
+syntax case ignore
+
+" preprocessor
+syn keyword naturalInclude		include nextgroup=naturalObjName skipwhite
+
+" define data
+syn keyword naturalKeyword		define data end-define
+syn keyword naturalKeyword		independent global parameter local redefine view
+syn keyword naturalKeyword		const[ant] init initial
+
+" loops
+syn keyword naturalLoop			read end-read end-work find end-find histogram end-histogram
+syn keyword naturalLoop			end-all sort end-sort sorted descending ascending
+syn keyword naturalRepeat		repeat end-repeat while until for step end-for
+syn keyword naturalKeyword		in file with field starting from ending at thru by isn where
+syn keyword naturalError		on error end-error
+syn keyword naturalKeyword		accept reject end-enddata number unique retain as release
+syn keyword naturalKeyword		start end-start break end-break physical page top sequence
+syn keyword naturalKeyword		end-toppage end-endpage end-endfile before processing
+syn keyword naturalKeyword		end-before
+
+" conditionals
+syn keyword naturalConditional	if then else end-if end-norec
+syn keyword naturalConditional	decide end-decide value when condition none any
+
+" assignment / calculation
+syn keyword naturalKeyword		reset assign move left right justified compress to into edited
+syn keyword naturalKeyword		add subtract multiply divide compute name
+syn keyword naturalKeyword		all giving remainder rounded leaving space
+syn keyword naturalKeyword		examine full replace giving separate delimiter modified
+syn keyword naturalKeyword		suspend identical suppress
+
+" program flow
+syn keyword naturalFlow			callnat fetch return enter escape bottom top stack formatted
+syn keyword naturalFlow			command call
+syn keyword naturalflow			end-subroutine routine
+
+" file operations
+syn keyword naturalKeyword		update store get delete end transaction work once close
+
+" other keywords
+syn keyword naturalKeyword		first every of no record[s] found ignore immediate
+syn keyword naturalKeyword		set settime key control stop terminate
+
+" in-/output
+syn keyword naturalKeyword		write display input reinput notitle nohdr map newpage mark
+syn keyword naturalKeyword		alarm text help eject index
+syn keyword naturalKeyword		format printer skip lines
+
+" functions
+syn keyword naturalKeyword		abs atn cos exp frac int log sgn sin sqrt tan val old
+
+" report mode keywords
+syn keyword naturalRMKeyword	same loop obtain indexed do doend
+
+" Subroutine name
+syn keyword	naturalFlow			perform subroutine nextgroup=naturalFunction skipwhite
+syn match	naturalFunction		"\<[a-z][-_a-z0-9]*\>"
+
+syn keyword	naturalFlow			using nextgroup=naturalKeyword,naturalObjName skipwhite
+syn match	naturalObjName		"\<[a-z][-_a-z0-9]\{,7}\>"
+
+" Labels
+syn match	naturalLabel		"\<[+#a-z][-_#a-z0-9]*\."
+syn match	naturalRef			"\<[+#a-z][-_#a-z0-9]*\>\.\<[+#a-z][*]\=[-_#a-z0-9]*\>"
+
+" System variables
+syn match	naturalSysVar		"\<\*[a-z][-a-z0-9]*\>"
+
+"integer number, or floating point number without a dot.
+syn match	naturalNumber		"\<-\=\d\+\>"
+"floating point number, with dot
+syn match	naturalNumber		"\<-\=\d\+\.\d\+\>"
+"floating point number, starting with a dot
+syn match	naturalNumber		"\.\d\+"
+
+" Formats in write statement
+syn match	naturalFormat		"\<\d\+[TX]\>"
+
+" String and Character contstants
+syn match	naturalString		"H'\x\+'"
+syn region  naturalString		start=+"+ end=+"+
+syn region	naturalString		start=+'+ end=+'+
+
+" Type definition
+syn match	naturalAttribute	"\<[-a-z][a-z]=[-a-z0-9_\.,]\+\>"
+syn match	naturalType			contained "\<[ABINP]\d\+\(,\d\+\)\=\>"
+syn match	naturalType			contained "\<[CL]\>"
+
+" "TODO" / other comments
+syn keyword naturalTodo			contained todo test
+syn match	naturalCommentMark	contained "[a-z][^ \t/:|]*\(\s[^ \t/:'"|]\+\)*:\s"he=e-1
+
+" comments
+syn region	naturalComment		start="/\*" end="$" contains=naturalTodo,naturalLineRef,naturalCommentMark
+syn region	naturalComment		start="^\*[\ \*]" end="$" contains=naturalTodo,naturalLineRef,naturalCommentMark
+syn region	naturalComment		start="^\d\{4} \*[\ \*]"lc=5 end="$" contains=naturalTodo,naturalLineRef,naturalCommentMark
+syn match	naturalComment		"^*$"
+syn match	naturalComment		"^\d\{4} \*$"lc=5
+" /* is legal syntax in parentheses e.g. "#ident(label./*)"
+syn region	naturalPComment		contained start="/\*\s*[^),]"  end="$" contains=naturalTodo,naturalLineRef,naturalCommentMark
+
+" operators
+syn keyword	naturalOperator		and or not eq ne gt lt ge le mask scan
+
+" constants
+syn keyword naturalBoolean		true false
+
+syn match	naturalLineNo		"^\d\{4}"
+
+" identifiers
+syn match	naturalIdent		"\<[+#a-z][-_#a-z0-9]*\>[^\.']"me=e-1
+syn match	naturalIdent		"\<[+#a-z][-_#a-z0-9]*$"
+syn match	naturalLegalIdent	"[+#a-z][-_#a-z0-9]*/[-_#a-z0-9]*"
+
+" parentheses
+syn region  naturalPar			matchgroup=naturalParGui start="(" end=")" contains=naturalLabel,naturalRef,naturalOperator,@naturalConstant,naturalType,naturalSysVar,naturalPar,naturalLineNo,naturalPComment
+syn match	naturalLineRef		"(\d\{4})"
+
+" build syntax groups
+syntax cluster naturalConstant	contains=naturalString,naturalNumber,naturalAttribute,naturalBoolean
+
+" folding
+if v:version >= 600
+	set foldignore=*
+endif
+
+
+if v:version >= 508 || !exists("did_natural_syntax_inits")
+	if v:version < 508
+		let did_natural_syntax_inits = 1
+		command -nargs=+ HiLink hi link <args>
+	else
+		command -nargs=+ HiLink hi def link <args>
+	endif
+	" The default methods for highlighting.  Can be overridden later
+
+	" Constants
+	HiLink naturalFormat		Constant
+	HiLink naturalAttribute		Constant
+	HiLink naturalNumber		Number
+	HiLink naturalString		String
+	HiLink naturalBoolean		Boolean
+
+	" All kinds of keywords
+	HiLink naturalConditional	Conditional
+	HiLink naturalRepeat		Repeat
+	HiLink naturalLoop			Repeat
+	HiLink naturalFlow			Keyword
+	HiLink naturalError			Keyword
+	HiLink naturalKeyword		Keyword
+	HiLink naturalOperator		Operator
+	HiLink naturalParGui		Operator
+
+	" Labels
+	HiLink naturalLabel			Label
+	HiLink naturalRefLabel		Label
+
+	" Comments
+	HiLink naturalPComment		Comment
+	HiLink naturalComment		Comment
+	HiLink naturalTodo			Todo
+	HiLink naturalCommentMark	PreProc
+
+	HiLink naturalInclude		Include
+	HiLink naturalSysVar		Identifier
+	HiLink naturalLineNo		LineNr
+	HiLink naturalLineRef		Error
+	HiLink naturalSpecial		Special
+	HiLink naturalComKey		Todo
+
+	" illegal things
+	HiLink naturalRMKeyword		Error
+	HiLink naturalLegalIdent	Error
+
+	HiLink naturalType			Type
+	HiLink naturalFunction		Function
+	HiLink naturalObjName		Function
+
+	delcommand HiLink
+endif
+
+let b:current_syntax = "natural"
+
+" vim:set ts=4 sw=4 noet ft=vim list:
--- /dev/null
+++ b/lib/vimfiles/syntax/ncf.vim
@@ -1,0 +1,258 @@
+" Vim syntax file
+" Language:     Novell "NCF" Batch File
+" Maintainer:   Jonathan J. Miner <miner@doit.wisc.edu>
+" Last Change:	Tue, 04 Sep 2001 16:20:33 CDT
+" $Id: ncf.vim,v 1.1 2004/06/13 16:31:58 vimboss Exp $
+
+" Remove any old syntax stuff hanging around
+if version < 600
+    syn clear
+elseif exists("b:current_syntax")
+    finish
+endif
+
+syn case ignore
+
+syn keyword ncfCommands		mount load unload
+syn keyword ncfBoolean		on off
+syn keyword ncfCommands		set nextgroup=ncfSetCommands
+syn keyword ncfTimeTypes	Reference Primary Secondary Single
+syn match ncfLoad       "\(unl\|l\)oad .*"lc=4 contains=ALLBUT,Error
+syn match ncfMount      "mount .*"lc=5 contains=ALLBUT,Error
+
+syn match ncfComment    "^\ *rem.*$"
+syn match ncfComment    "^\ *;.*$"
+syn match ncfComment    "^\ *#.*$"
+
+syn match ncfSearchPath "search \(add\|del\) " nextgroup=ncfPath
+syn match ncfPath       "\<[^: ]\+:\([A-Za-z0-9._]\|\\\)*\>"
+syn match ncfServerName "^file server name .*$"
+syn match ncfIPXNet     "^ipx internal net"
+
+" String
+syn region ncfString    start=+"+  end=+"+
+syn match ncfContString "= \(\(\.\{0,1}\(OU=\|O=\)\{0,1}[A-Z_]\+\)\+;\{0,1}\)\+"lc=2
+
+syn match ncfHexNumber  "\<\d\(\d\+\|[A-F]\+\)*\>"
+syn match ncfNumber     "\<\d\+\.\{0,1}\d*\>"
+syn match ncfIPAddr     "\d\{1,3}\.\d\{1,3}\.\d\{1,3}\.\d\{1,3}"
+syn match ncfTime       "\(+|=\)\{0,1}\d\{1,2}:\d\{1,2}:\d\{1,2}"
+syn match ncfDSTTime    "([^ ]\+ [^ ]\+ \(FIRST\|LAST\)\s*\d\{1,2}:\d\{1,2}:\d\{1,2} \(AM\|PM\))"
+syn match ncfTimeZone   "[A-Z]\{3}\d[A-Z]\{3}"
+
+syn match ncfLogins     "^\([Dd]is\|[Ee]n\)able login[s]*"
+syn match ncfScript     "[^ ]*\.ncf"
+
+"  SET Commands that take a Number following
+syn match ncfSetCommandsNum "\(Alert Message Nodes\)\s*="
+syn match ncfSetCommandsNum "\(Auto Restart After Abend\)\s*="
+syn match ncfSetCommandsNum "\(Auto Restart After Abend Delay Time\)\s*="
+syn match ncfSetCommandsNum "\(Compression Daily Check Starting Hour\)\s*="
+syn match ncfSetCommandsNum "\(Compression Daily Check Stop Hour\)\s*="
+syn match ncfSetCommandsNum "\(Concurrent Remirror Requests\)\s*="
+syn match ncfSetCommandsNum "\(Convert Compressed to Uncompressed Option\)\s*="
+syn match ncfSetCommandsNum "\(Days Untouched Before Compression\)\s*="
+syn match ncfSetCommandsNum "\(Decompress Free Space Warning Interval\)\s*="
+syn match ncfSetCommandsNum "\(Decompress Percent Disk Space Free to Allow Commit\)\s*="
+syn match ncfSetCommandsNum "\(Deleted Files Compression Option\)\s*="
+syn match ncfSetCommandsNum "\(Directory Cache Allocation Wait Time\)\s*="
+syn match ncfSetCommandsNum "\(Enable IPX Checksums\)\s*="
+syn match ncfSetCommandsNum "\(Garbage Collection Interval\)\s*="
+syn match ncfSetCommandsNum "\(IPX NetBIOS Replication Option\)\s*="
+syn match ncfSetCommandsNum "\(Maximum Concurrent Compressions\)\s*="
+syn match ncfSetCommandsNum "\(Maximum Concurrent Directory Cache Writes\)\s*="
+syn match ncfSetCommandsNum "\(Maximum Concurrent Disk Cache Writes\)\s*="
+syn match ncfSetCommandsNum "\(Maximum Directory Cache Buffers\)\s*="
+syn match ncfSetCommandsNum "\(Maximum Extended Attributes per File or Path\)\s*="
+syn match ncfSetCommandsNum "\(Maximum File Locks\)\s*="
+syn match ncfSetCommandsNum "\(Maximum File Locks Per Connection\)\s*="
+syn match ncfSetCommandsNum "\(Maximum Interrupt Events\)\s*="
+syn match ncfSetCommandsNum "\(Maximum Number of Directory Handles\)\s*="
+syn match ncfSetCommandsNum "\(Maximum Number of Internal Directory Handles\)\s*="
+syn match ncfSetCommandsNum "\(Maximum Outstanding NCP Searches\)\s*="
+syn match ncfSetCommandsNum "\(Maximum Packet Receive Buffers\)\s*="
+syn match ncfSetCommandsNum "\(Maximum Physical Receive Packet Size\)\s*="
+syn match ncfSetCommandsNum "\(Maximum Record Locks\)\s*="
+syn match ncfSetCommandsNum "\(Maximum Record Locks Per Connection\)\s*="
+syn match ncfSetCommandsNum "\(Maximum Service Processes\)\s*="
+syn match ncfSetCommandsNum "\(Maximum Subdirectory Tree Depth\)\s*="
+syn match ncfSetCommandsNum "\(Maximum Transactions\)\s*="
+syn match ncfSetCommandsNum "\(Minimum Compression Percentage Gain\)\s*="
+syn match ncfSetCommandsNum "\(Minimum Directory Cache Buffers\)\s*="
+syn match ncfSetCommandsNum "\(Minimum File Cache Buffers\)\s*="
+syn match ncfSetCommandsNum "\(Minimum File Cache Report Threshold\)\s*="
+syn match ncfSetCommandsNum "\(Minimum Free Memory for Garbage Collection\)\s*="
+syn match ncfSetCommandsNum "\(Minimum Packet Receive Buffers\)\s*="
+syn match ncfSetCommandsNum "\(Minimum Service Processes\)\s*="
+syn match ncfSetCommandsNum "\(NCP Packet Signature Option\)\s*="
+syn match ncfSetCommandsNum "\(NDS Backlink Interval\)\s*="
+syn match ncfSetCommandsNum "\(NDS Client NCP Retries\)\s*="
+syn match ncfSetCommandsNum "\(NDS External Reference Life Span\)\s*="
+syn match ncfSetCommandsNum "\(NDS Inactivity Synchronization Interval\)\s*="
+syn match ncfSetCommandsNum "\(NDS Janitor Interval\)\s*="
+syn match ncfSetCommandsNum "\(New Service Process Wait Time\)\s*="
+syn match ncfSetCommandsNum "\(Number of Frees for Garbage Collection\)\s*="
+syn match ncfSetCommandsNum "\(Number of Watchdog Packets\)\s*="
+syn match ncfSetCommandsNum "\(Pseudo Preemption Count\)\s*="
+syn match ncfSetCommandsNum "\(Read Ahead LRU Sitting Time Threshold\)\s*="
+syn match ncfSetCommandsNum "\(Remirror Block Size\)\s*="
+syn match ncfSetCommandsNum "\(Reserved Buffers Below 16 Meg\)\s*="
+syn match ncfSetCommandsNum "\(Server Log File Overflow Size\)\s*="
+syn match ncfSetCommandsNum "\(Server Log File State\)\s*="
+syn match ncfSetCommandsNum "\(SMP Polling Count\)\s*="
+syn match ncfSetCommandsNum "\(SMP Stack Size\)\s*="
+syn match ncfSetCommandsNum "\(TIMESYNC Polling Count\)\s*="
+syn match ncfSetCommandsNum "\(TIMESYNC Polling Interval\)\s*="
+syn match ncfSetCommandsNum "\(TIMESYNC Synchronization Radius\)\s*="
+syn match ncfSetCommandsNum "\(TIMESYNC Write Value\)\s*="
+syn match ncfSetCommandsNum "\(Volume Log File Overflow Size\)\s*="
+syn match ncfSetCommandsNum "\(Volume Log File State\)\s*="
+syn match ncfSetCommandsNum "\(Volume Low Warning Reset Threshold\)\s*="
+syn match ncfSetCommandsNum "\(Volume Low Warning Threshold\)\s*="
+syn match ncfSetCommandsNum "\(Volume TTS Log File Overflow Size\)\s*="
+syn match ncfSetCommandsNum "\(Volume TTS Log File State\)\s*="
+syn match ncfSetCommandsNum "\(Worker Thread Execute In a Row Count\)\s*="
+
+" SET Commands that take a Boolean (ON/OFF)
+
+syn match ncfSetCommandsBool "\(Alloc Memory Check Flag\)\s*="
+syn match ncfSetCommandsBool "\(Allow Audit Passwords\)\s*="
+syn match ncfSetCommandsBool "\(Allow Change to Client Rights\)\s*="
+syn match ncfSetCommandsBool "\(Allow Deletion of Active Directories\)\s*="
+syn match ncfSetCommandsBool "\(Allow Invalid Pointers\)\s*="
+syn match ncfSetCommandsBool "\(Allow LIP\)\s*="
+syn match ncfSetCommandsBool "\(Allow Unencrypted Passwords\)\s*="
+syn match ncfSetCommandsBool "\(Allow Unowned Files To Be Extended\)\s*="
+syn match ncfSetCommandsBool "\(Auto Register Memory Above 16 Megabytes\)\s*="
+syn match ncfSetCommandsBool "\(Auto TTS Backout Flag\)\s*="
+syn match ncfSetCommandsBool "\(Automatically Repair Bad Volumes\)\s*="
+syn match ncfSetCommandsBool "\(Check Equivalent to Me\)\s*="
+syn match ncfSetCommandsBool "\(Command Line Prompt Default Choice\)\s*="
+syn match ncfSetCommandsBool "\(Console Display Watchdog Logouts\)\s*="
+syn match ncfSetCommandsBool "\(Daylight Savings Time Status\)\s*="
+syn match ncfSetCommandsBool "\(Developer Option\)\s*="
+syn match ncfSetCommandsBool "\(Display Incomplete IPX Packet Alerts\)\s*="
+syn match ncfSetCommandsBool "\(Display Lost Interrupt Alerts\)\s*="
+syn match ncfSetCommandsBool "\(Display NCP Bad Component Warnings\)\s*="
+syn match ncfSetCommandsBool "\(Display NCP Bad Length Warnings\)\s*="
+syn match ncfSetCommandsBool "\(Display Old API Names\)\s*="
+syn match ncfSetCommandsBool "\(Display Relinquish Control Alerts\)\s*="
+syn match ncfSetCommandsBool "\(Display Spurious Interrupt Alerts\)\s*="
+syn match ncfSetCommandsBool "\(Enable Deadlock Detection\)\s*="
+syn match ncfSetCommandsBool "\(Enable Disk Read After Write Verify\)\s*="
+syn match ncfSetCommandsBool "\(Enable File Compression\)\s*="
+syn match ncfSetCommandsBool "\(Enable IO Handicap Attribute\)\s*="
+syn match ncfSetCommandsBool "\(Enable SECURE.NCF\)\s*="
+syn match ncfSetCommandsBool "\(Fast Volume Mounts\)\s*="
+syn match ncfSetCommandsBool "\(Global Pseudo Preemption\)\s*="
+syn match ncfSetCommandsBool "\(Halt System on Invalid Parameters\)\s*="
+syn match ncfSetCommandsBool "\(Ignore Disk Geometry\)\s*="
+syn match ncfSetCommandsBool "\(Immediate Purge of Deleted Files\)\s*="
+syn match ncfSetCommandsBool "\(NCP File Commit\)\s*="
+syn match ncfSetCommandsBool "\(NDS Trace File Length to Zero\)\s*="
+syn match ncfSetCommandsBool "\(NDS Trace to File\)\s*="
+syn match ncfSetCommandsBool "\(NDS Trace to Screen\)\s*="
+syn match ncfSetCommandsBool "\(New Time With Daylight Savings Time Status\)\s*="
+syn match ncfSetCommandsBool "\(Read Ahead Enabled\)\s*="
+syn match ncfSetCommandsBool "\(Read Fault Emulation\)\s*="
+syn match ncfSetCommandsBool "\(Read Fault Notification\)\s*="
+syn match ncfSetCommandsBool "\(Reject NCP Packets with Bad Components\)\s*="
+syn match ncfSetCommandsBool "\(Reject NCP Packets with Bad Lengths\)\s*="
+syn match ncfSetCommandsBool "\(Replace Console Prompt with Server Name\)\s*="
+syn match ncfSetCommandsBool "\(Reply to Get Nearest Server\)\s*="
+syn match ncfSetCommandsBool "\(SMP Developer Option\)\s*="
+syn match ncfSetCommandsBool "\(SMP Flush Processor Cache\)\s*="
+syn match ncfSetCommandsBool "\(SMP Intrusive Abend Mode\)\s*="
+syn match ncfSetCommandsBool "\(SMP Memory Protection\)\s*="
+syn match ncfSetCommandsBool "\(Sound Bell for Alerts\)\s*="
+syn match ncfSetCommandsBool "\(TIMESYNC Configured Sources\)\s*="
+syn match ncfSetCommandsBool "\(TIMESYNC Directory Tree Mode\)\s*="
+syn match ncfSetCommandsBool "\(TIMESYNC Hardware Clock\)\s*="
+syn match ncfSetCommandsBool "\(TIMESYNC RESET\)\s*="
+syn match ncfSetCommandsBool "\(TIMESYNC Restart Flag\)\s*="
+syn match ncfSetCommandsBool "\(TIMESYNC Service Advertising\)\s*="
+syn match ncfSetCommandsBool "\(TIMESYNC Write Parameters\)\s*="
+syn match ncfSetCommandsBool "\(TTS Abort Dump Flag\)\s*="
+syn match ncfSetCommandsBool "\(Upgrade Low Priority Threads\)\s*="
+syn match ncfSetCommandsBool "\(Volume Low Warn All Users\)\s*="
+syn match ncfSetCommandsBool "\(Write Fault Emulation\)\s*="
+syn match ncfSetCommandsBool "\(Write Fault Notification\)\s*="
+
+" Set Commands that take a "string" -- NOT QUOTED
+
+syn match ncfSetCommandsStr "\(Default Time Server Type\)\s*="
+syn match ncfSetCommandsStr "\(SMP NetWare Kernel Mode\)\s*="
+syn match ncfSetCommandsStr "\(Time Zone\)\s*="
+syn match ncfSetCommandsStr "\(TIMESYNC ADD Time Source\)\s*="
+syn match ncfSetCommandsStr "\(TIMESYNC REMOVE Time Source\)\s*="
+syn match ncfSetCommandsStr "\(TIMESYNC Time Source\)\s*="
+syn match ncfSetCommandsStr "\(TIMESYNC Type\)\s*="
+
+" SET Commands that take a "Time"
+
+syn match ncfSetCommandsTime "\(Command Line Prompt Time Out\)\s*="
+syn match ncfSetCommandsTime "\(Delay Before First Watchdog Packet\)\s*="
+syn match ncfSetCommandsTime "\(Delay Between Watchdog Packets\)\s*="
+syn match ncfSetCommandsTime "\(Directory Cache Buffer NonReferenced Delay\)\s*="
+syn match ncfSetCommandsTime "\(Dirty Directory Cache Delay Time\)\s*="
+syn match ncfSetCommandsTime "\(Dirty Disk Cache Delay Time\)\s*="
+syn match ncfSetCommandsTime "\(File Delete Wait Time\)\s*="
+syn match ncfSetCommandsTime "\(Minimum File Delete Wait Time\)\s*="
+syn match ncfSetCommandsTime "\(Mirrored Devices Are Out of Sync Message Frequency\)\s*="
+syn match ncfSetCommandsTime "\(New Packet Receive Buffer Wait Time\)\s*="
+syn match ncfSetCommandsTime "\(TTS Backout File Truncation Wait Time\)\s*="
+syn match ncfSetCommandsTime "\(TTS UnWritten Cache Wait Time\)\s*="
+syn match ncfSetCommandsTime "\(Turbo FAT Re-Use Wait Time\)\s*="
+syn match ncfSetCommandsTime "\(Daylight Savings Time Offset\)\s*="
+
+syn match ncfSetCommandsTimeDate "\(End of Daylight Savings Time\)\s*="
+syn match ncfSetCommandsTimeDate "\(Start of Daylight Savings Time\)\s*="
+
+syn match ncfSetCommandsBindCon "\(Bindery Context\)\s*=" nextgroup=ncfContString
+
+syn cluster ncfSetCommands contains=ncfSetCommandsNum,ncfSetCommandsBool,ncfSetCommandsStr,ncfSetCommandsTime,ncfSetCommandsTimeDate,ncfSetCommandsBindCon
+
+
+if exists("ncf_highlight_unknowns")
+    syn match Error "[^ \t]*" contains=ALL
+endif
+
+if version >= 508 || !exists("did_ncf_syntax_inits")
+    if version < 508
+	let did_ncf_syntax_inits = 1
+	command -nargs=+ HiLink hi link <args>
+    else
+	command -nargs=+ HiLink hi def link <args>
+    endif
+
+    " The default methods for highlighting.  Can be overridden later
+    HiLink ncfCommands		Statement
+    HiLink ncfSetCommands	ncfCommands
+    HiLink ncfLogins		ncfCommands
+    HiLink ncfString		String
+    HiLink ncfContString	ncfString
+    HiLink ncfComment		Comment
+    HiLink ncfImplicit		Type
+    HiLink ncfBoolean		Boolean
+    HiLink ncfScript		Identifier
+    HiLink ncfNumber		Number
+    HiLink ncfIPAddr		ncfNumber
+    HiLink ncfHexNumber		ncfNumber
+    HiLink ncfTime		ncfNumber
+    HiLink ncfDSTTime		ncfNumber
+    HiLink ncfPath		Constant
+    HiLink ncfServerName	Special
+    HiLink ncfIPXNet		ncfServerName
+    HiLink ncfTimeTypes		Constant
+    HiLink ncfSetCommandsNum	   ncfSetCommands
+    HiLink ncfSetCommandsBool	   ncfSetCommands
+    HiLink ncfSetCommandsStr	   ncfSetCommands
+    HiLink ncfSetCommandsTime	   ncfSetCommands
+    HiLink ncfSetCommandsTimeDate  ncfSetCommands
+    HiLink ncfSetCommandsBindCon   ncfSetCommands
+
+    delcommand HiLink
+
+endif
+
+let b:current_syntax = "ncf"
--- /dev/null
+++ b/lib/vimfiles/syntax/netrc.vim
@@ -1,0 +1,51 @@
+" Vim syntax file
+" Language:         netrc(5) configuration file
+" Maintainer:       Nikolai Weibull <now@bitwi.se>
+" Latest Revision:  2006-04-19
+
+if exists("b:current_syntax")
+  finish
+endif
+
+let s:cpo_save = &cpo
+set cpo&vim
+
+syn keyword netrcKeyword    machine nextgroup=netrcMachine skipwhite skipnl
+syn keyword netrcKeyword    login nextgroup=netrcLogin,netrcSpecial
+                            \ skipwhite skipnl
+syn keyword netrcKeyword    password nextgroup=netrcPassword skipwhite skipnl
+syn keyword netrcKeyword    default
+syn keyword netrcKeyword    macdef nextgroup=netrcInit,netrcMacroName
+                            \ skipwhite skipnl
+syn region  netrcMacro      contained start='.' end='^$'
+
+syn match   netrcMachine    contained display '\S\+'
+syn match   netrcMachine    contained display '"[^\\"]*\(\\.[^\\"]*\)*"'
+syn match   netrcLogin      contained display '\S\+'
+syn match   netrcLogin      contained display '"[^\\"]*\(\\.[^\\"]*\)*"'
+syn match   netrcPassword   contained display '\S\+'
+syn match   netrcPassword   contained display '"[^\\"]*\(\\.[^\\"]*\)*"'
+syn match   netrcMacroName  contained display '\S\+' nextgroup=netrcMacro
+                            \ skipwhite skipnl
+syn match   netrcMacroName  contained display '"[^\\"]*\(\\.[^\\"]*\)*"'
+                            \ nextgroup=netrcMacro skipwhite skipnl
+
+syn keyword netrcSpecial    contained anonymous
+syn match   netrcInit       contained '\<init$' nextgroup=netrcMacro
+                            \ skipwhite skipnl
+
+syn sync fromstart
+
+hi def link netrcKeyword    Keyword
+hi def link netrcMacro      PreProc
+hi def link netrcMachine    Identifier
+hi def link netrcLogin      String
+hi def link netrcPassword   String
+hi def link netrcMacroName  String
+hi def link netrcSpecial    Special
+hi def link netrcInit       Special
+
+let b:current_syntax = "netrc"
+
+let &cpo = s:cpo_save
+unlet s:cpo_save
--- /dev/null
+++ b/lib/vimfiles/syntax/netrw.vim
@@ -1,0 +1,71 @@
+" Language   : Netrw Remote-Directory Listing Syntax
+" Maintainer : Charles E. Campbell, Jr.
+" Last change: Nov 27, 2006
+" Version    : 9
+" ---------------------------------------------------------------------
+
+" Syntax Clearing: {{{1
+if version < 600
+ syntax clear
+elseif exists("b:current_syntax")
+ finish
+endif
+
+" ---------------------------------------------------------------------
+" Directory List Syntax Highlighting: {{{1
+syn cluster NetrwGroup contains=netrwHide,netrwSortBy,netrwSortSeq,netrwQuickHelp,netrwVersion
+
+syn match  netrwSpecial		"\%(\S\+ \)*\S\+[*|=]\ze\%(\s\{2,}\|$\)" contains=netrwClassify
+syn match  netrwDir		"\.\{1,2}/"			contains=netrwClassify
+syn match  netrwDir		"\%(\S\+ \)*\S\+/"		contains=netrwClassify
+syn match  netrwDir		"^\S*/"				contains=netrwClassify
+syn match  netrwSizeDate	"\<\d\+\s\d\{1,2}/\d\{1,2}/\d\{4}\s"	contains=netrwDateSep skipwhite nextgroup=netrwTime
+syn match  netrwSymLink		"\%(\S\+ \)*\S\+@\ze\%(\s\{2,}\|$\)"  contains=netrwClassify
+syn match  netrwExe		"\%(\S\+ \)*\S\+\*\ze\%(\s\{2,}\|$\)" contains=netrwClassify,netrwTreeIgnore
+syn match  netrwTreeIgnore contained "^\%(| \)*"
+
+syn match  netrwClassify	"[*=|@/]\ze\%(\s\{2,}\|$\)"	contained
+syn match  netrwDateSep		"/"				contained
+syn match  netrwTime		"\d\{1,2}:\d\{2}:\d\{2}"	contained contains=netrwTimeSep
+syn match  netrwTimeSep		":"
+
+syn match  netrwComment		'".*\%(\t\|$\)'			contains=@NetrwGroup
+syn match  netrwHide		'^"\s*\(Hid\|Show\)ing:'	skipwhite nextgroup=netrwHidePat
+syn match  netrwSlash		"/"				contained
+syn match  netrwHidePat		"[^,]\+"			contained skipwhite nextgroup=netrwHideSep
+syn match  netrwHideSep		","				contained transparent skipwhite nextgroup=netrwHidePat
+syn match  netrwSortBy		"Sorted by"			contained transparent skipwhite nextgroup=netrwList
+syn match  netrwSortSeq		"Sort sequence:"		contained transparent skipwhite nextgroup=netrwList
+syn match  netrwList		".*$"				contained contains=netrwComma
+syn match  netrwComma		","				contained
+syn region netrwQuickHelp	matchgroup=Comment start="Quick Help:\s\+" end="$" contains=netrwHelpCmd keepend contained
+syn match  netrwHelpCmd		"\S\ze:"			contained skipwhite nextgroup=netrwCmdSep
+syn match  netrwCmdSep		":"				contained nextgroup=netrwCmdNote
+syn match  netrwCmdNote		".\{-}\ze  "			contained
+syn match  netrwVersion		"(netrw.*)"			contained
+
+" ---------------------------------------------------------------------
+" Highlighting Links: {{{1
+if !exists("did_drchip_dbg_syntax")
+ let did_drchip_netrwlist_syntax= 1
+ hi link netrwClassify	Function
+ hi link netrwCmdSep	Delimiter
+ hi link netrwComment	Comment
+ hi link netrwDir	Directory
+ hi link netrwHelpCmd	Function
+ hi link netrwHidePat	Statement
+ hi link netrwList	Statement
+ hi link netrwVersion	Identifier
+ hi link netrwSymLink	Special
+ hi link netrwExe	PreProc
+ hi link netrwDateSep	Delimiter
+
+ hi link netrwTimeSep	netrwDateSep
+ hi link netrwComma	netrwComment
+ hi link netrwHide	netrwComment
+endif
+
+" Current Syntax: {{{1
+let   b:current_syntax = "netrwlist"
+" ---------------------------------------------------------------------
+" vim: ts=8 fdm=marker
--- /dev/null
+++ b/lib/vimfiles/syntax/nosyntax.vim
@@ -1,0 +1,30 @@
+" Vim syntax support file
+" Maintainer:	Bram Moolenaar <Bram@vim.org>
+" Last Change:	2006 Apr 16
+
+" This file is used for ":syntax off".
+" It removes the autocommands and stops highlighting for all buffers.
+
+if !has("syntax")
+  finish
+endif
+
+" Remove all autocommands for the Syntax event.  This also avoids that
+" "syntax=foo" in a modeline triggers the SynSet() function of synload.vim.
+au! Syntax
+
+" remove all syntax autocommands and remove the syntax for each buffer
+augroup syntaxset
+  au!
+  au BufEnter * syn clear
+  au BufEnter * if exists("b:current_syntax") | unlet b:current_syntax | endif
+  doautoall syntaxset BufEnter *
+  au!
+augroup END
+
+if exists("syntax_on")
+  unlet syntax_on
+endif
+if exists("syntax_manual")
+  unlet syntax_manual
+endif
--- /dev/null
+++ b/lib/vimfiles/syntax/nqc.vim
@@ -1,0 +1,378 @@
+" Vim syntax file
+" Language:	NQC - Not Quite C, for LEGO mindstorms
+"		NQC homepage: http://www.enteract.com/~dbaum/nqc/
+" Maintainer:	Stefan Scherer <stefan@enotes.de>
+" Last Change:	2001 May 10
+" URL:		http://www.enotes.de/twiki/pub/Home/LegoMindstorms/nqc.vim
+" Filenames:	.nqc
+
+" For version 5.x: Clear all syntax items
+" For version 6.x: Quit when a syntax file was already loaded
+if version < 600
+  syntax clear
+elseif exists("b:current_syntax")
+  finish
+endif
+
+" Statements
+syn keyword	nqcStatement	break return continue start stop abs sign
+syn keyword     nqcStatement	sub task
+syn keyword     nqcLabel	case default
+syn keyword	nqcConditional	if else switch
+syn keyword	nqcRepeat	while for do until repeat
+
+" Scout and RCX2
+syn keyword	nqcEvents	acquire catch monitor
+
+" types and classes
+syn keyword	nqcType		int true false void
+syn keyword	nqcStorageClass	asm const inline
+
+
+
+" Sensors --------------------------------------------
+" Input Sensors
+syn keyword     nqcConstant	SENSOR_1 SENSOR_2 SENSOR_3
+
+" Types for SetSensorType()
+syn keyword     nqcConstant	SENSOR_TYPE_TOUCH SENSOR_TYPE_TEMPERATURE
+syn keyword     nqcConstant	SENSOR_TYPE_LIGHT SENSOR_TYPE_ROTATION
+syn keyword     nqcConstant	SENSOR_LIGHT SENSOR_TOUCH
+
+" Modes for SetSensorMode()
+syn keyword     nqcConstant	SENSOR_MODE_RAW SENSOR_MODE_BOOL
+syn keyword     nqcConstant	SENSOR_MODE_EDGE SENSOR_MODE_PULSE
+syn keyword     nqcConstant	SENSOR_MODE_PERCENT SENSOR_MODE_CELSIUS
+syn keyword     nqcConstant	SENSOR_MODE_FAHRENHEIT SENSOR_MODE_ROTATION
+
+" Sensor configurations for SetSensor()
+syn keyword     nqcConstant	SENSOR_TOUCH SENSOR_LIGHT SENSOR_ROTATION
+syn keyword     nqcConstant	SENSOR_CELSIUS SENSOR_FAHRENHEIT SENSOR_PULSE
+syn keyword     nqcConstant	SENSOR_EDGE
+
+" Functions - All
+syn keyword	nqcFunction	ClearSensor
+syn keyword	nqcFunction	SensorValue SensorType
+
+" Functions - RCX
+syn keyword	nqcFunction	SetSensor SetSensorType
+syn keyword	nqcFunction	SensorValueBool
+
+" Functions - RCX, CyberMaster
+syn keyword	nqcFunction	SetSensorMode SensorMode
+
+" Functions - RCX, Scout
+syn keyword	nqcFunction	SensorValueRaw
+
+" Functions - Scout
+syn keyword	nqcFunction	SetSensorLowerLimit SetSensorUpperLimit
+syn keyword	nqcFunction	SetSensorHysteresis CalibrateSensor
+
+
+" Outputs --------------------------------------------
+" Outputs for On(), Off(), etc.
+syn keyword     nqcConstant	OUT_A OUT_B OUT_C
+
+" Modes for SetOutput()
+syn keyword     nqcConstant	OUT_ON OUT_OFF OUT_FLOAT
+
+" Directions for SetDirection()
+syn keyword     nqcConstant	OUT_FWD OUT_REV OUT_TOGGLE
+
+" Output power for SetPower()
+syn keyword     nqcConstant	OUT_LOW OUT_HALF OUT_FULL
+
+" Functions - All
+syn keyword	nqcFunction	SetOutput SetDirection SetPower OutputStatus
+syn keyword	nqcFunction	On Off Float Fwd Rev Toggle
+syn keyword	nqcFunction	OnFwd OnRev OnFor
+
+" Functions - RXC2, Scout
+syn keyword	nqcFunction	SetGlobalOutput SetGlobalDirection SetMaxPower
+syn keyword	nqcFunction	GlobalOutputStatus
+
+
+" Sound ----------------------------------------------
+" Sounds for PlaySound()
+syn keyword     nqcConstant	SOUND_CLICK SOUND_DOUBLE_BEEP SOUND_DOWN
+syn keyword     nqcConstant	SOUND_UP SOUND_LOW_BEEP SOUND_FAST_UP
+
+" Functions - All
+syn keyword	nqcFunction	PlaySound PlayTone
+
+" Functions - RCX2, Scout
+syn keyword	nqcFunction	MuteSound UnmuteSound ClearSound
+syn keyword	nqcFunction	SelectSounds
+
+
+" LCD ------------------------------------------------
+" Modes for SelectDisplay()
+syn keyword     nqcConstant	DISPLAY_WATCH DISPLAY_SENSOR_1 DISPLAY_SENSOR_2
+syn keyword     nqcConstant	DISPLAY_SENSOR_3 DISPLAY_OUT_A DISPLAY_OUT_B
+syn keyword     nqcConstant	DISPLAY_OUT_C
+" RCX2
+syn keyword     nqcConstant	DISPLAY_USER
+
+" Functions - RCX
+syn keyword	nqcFunction	SelectDisplay
+" Functions - RCX2
+syn keyword	nqcFunction	SetUserDisplay
+
+
+" Communication --------------------------------------
+" Messages - RCX, Scout ------------------------------
+" Tx power level for SetTxPower()
+syn keyword     nqcConstant	TX_POWER_LO TX_POWER_HI
+
+" Functions - RCX, Scout
+syn keyword	nqcFunction	Message ClearMessage SendMessage SetTxPower
+
+" Serial - RCX2 --------------------------------------
+" for SetSerialComm()
+syn keyword     nqcConstant	SERIAL_COMM_DEFAULT SERIAL_COMM_4800
+syn keyword     nqcConstant	SERIAL_COMM_DUTY25 SERIAL_COMM_76KHZ
+
+" for SetSerialPacket()
+syn keyword     nqcConstant	SERIAL_PACKET_DEFAULT SERIAL_PACKET_PREAMBLE
+syn keyword     nqcConstant	SERIAL_PACKET_NEGATED SERIAL_PACKET_CHECKSUM
+syn keyword     nqcConstant	SERIAL_PACKET_RCX
+
+" Functions - RCX2
+syn keyword	nqcFunction	SetSerialComm SetSerialPacket SetSerialData
+syn keyword	nqcFunction	SerialData SendSerial
+
+" VLL - Scout ----------------------------------------
+" Functions - Scout
+syn keyword	nqcFunction	SendVLL
+
+
+" Timers ---------------------------------------------
+" Functions - All
+syn keyword	nqcFunction	ClearTimer Timer
+
+" Functions - RCX2
+syn keyword	nqcFunction	SetTimer FastTimer
+
+
+" Counters -------------------------------------------
+" Functions - RCX2, Scout
+syn keyword	nqcFunction	ClearCounter IncCounter DecCounter Counter
+
+
+" Access Control -------------------------------------
+syn keyword     nqcConstant	ACQUIRE_OUT_A ACQUIRE_OUT_B ACQUIRE_OUT_C
+syn keyword     nqcConstant	ACQUIRE_SOUND
+" RCX2 only
+syn keyword     nqcConstant	ACQUIRE_USER_1 ACQUIRE_USER_2 ACQUIRE_USER_3
+syn keyword     nqcConstant	ACQUIRE_USER_4
+
+" Functions - RCX2, Scout
+syn keyword	nqcFunction	SetPriority
+
+
+" Events ---------------------------------------------
+" RCX2 Events
+syn keyword     nqcConstant	EVENT_TYPE_PRESSED EVENT_TYPE_RELEASED
+syn keyword     nqcConstant	EVENT_TYPE_PULSE EVENT_TYPE_EDGE
+syn keyword     nqcConstant	EVENT_TYPE_FAST_CHANGE EVENT_TYPE_LOW
+syn keyword     nqcConstant	EVENT_TYPE_NORMAL EVENT_TYPE_HIGH
+syn keyword     nqcConstant	EVENT_TYPE_CLICK EVENT_TYPE_DOUBLECLICK
+syn keyword     nqcConstant	EVENT_TYPE_MESSAGE
+
+" Scout Events
+syn keyword     nqcConstant	EVENT_1_PRESSED EVENT_1_RELEASED
+syn keyword     nqcConstant	EVENT_2_PRESSED EVENT_2_RELEASED
+syn keyword     nqcConstant	EVENT_LIGHT_HIGH EVENT_LIGHT_NORMAL
+syn keyword     nqcConstant	EVENT_LIGHT_LOW EVENT_LIGHT_CLICK
+syn keyword     nqcConstant	EVENT_LIGHT_DOUBLECLICK EVENT_COUNTER_0
+syn keyword     nqcConstant	EVENT_COUNTER_1 EVENT_TIMER_0 EVENT_TIMER_1
+syn keyword     nqcConstant	EVENT_TIMER_2 EVENT_MESSAGE
+
+" Functions - RCX2, Scout
+syn keyword	nqcFunction	ActiveEvents Event
+
+" Functions - RCX2
+syn keyword	nqcFunction	CurrentEvents
+syn keyword	nqcFunction	SetEvent ClearEvent ClearAllEvents EventState
+syn keyword	nqcFunction	CalibrateEvent SetUpperLimit UpperLimit
+syn keyword	nqcFunction	SetLowerLimit LowerLimit SetHysteresis
+syn keyword	nqcFunction	Hysteresis
+syn keyword	nqcFunction	SetClickTime ClickTime SetClickCounter
+syn keyword	nqcFunction	ClickCounter
+
+" Functions - Scout
+syn keyword	nqcFunction	SetSensorClickTime SetCounterLimit
+syn keyword	nqcFunction	SetTimerLimit
+
+
+" Data Logging ---------------------------------------
+" Functions - RCX
+syn keyword	nqcFunction	CreateDatalog AddToDatalog
+syn keyword	nqcFunction	UploadDatalog
+
+
+" General Features -----------------------------------
+" Functions - All
+syn keyword	nqcFunction	Wait StopAllTasks Random
+syn keyword	nqcFunction	SetSleepTime SleepNow
+
+" Functions - RCX
+syn keyword	nqcFunction	Program Watch SetWatch
+
+" Functions - RCX2
+syn keyword	nqcFunction	SetRandomSeed SelectProgram
+syn keyword	nqcFunction	BatteryLevel FirmwareVersion
+
+" Functions - Scout
+" Parameters for SetLight()
+syn keyword     nqcConstant	LIGHT_ON LIGHT_OFF
+syn keyword	nqcFunction	SetScoutRules ScoutRules SetScoutMode
+syn keyword	nqcFunction	SetEventFeedback EventFeedback SetLight
+
+" additional CyberMaster defines
+syn keyword     nqcConstant	OUT_L OUT_R OUT_X
+syn keyword     nqcConstant	SENSOR_L SENSOR_M SENSOR_R
+" Functions - CyberMaster
+syn keyword	nqcFunction	Drive OnWait OnWaitDifferent
+syn keyword	nqcFunction	ClearTachoCounter TachoCount TachoSpeed
+syn keyword	nqcFunction	ExternalMotorRunning AGC
+
+
+
+" nqcCommentGroup allows adding matches for special things in comments
+syn keyword	nqcTodo		contained TODO FIXME XXX
+syn cluster	nqcCommentGroup	contains=nqcTodo
+
+"when wanted, highlight trailing white space
+if exists("nqc_space_errors")
+  if !exists("nqc_no_trail_space_error")
+    syn match	nqcSpaceError	display excludenl "\s\+$"
+  endif
+  if !exists("nqc_no_tab_space_error")
+    syn match	nqcSpaceError	display " \+\t"me=e-1
+  endif
+endif
+
+"catch errors caused by wrong parenthesis and brackets
+syn cluster	nqcParenGroup	contains=nqcParenError,nqcIncluded,nqcCommentSkip,@nqcCommentGroup,nqcCommentStartError,nqcCommentSkip,nqcCppOut,nqcCppOut2,nqcCppSkip,nqcNumber,nqcFloat,nqcNumbers
+if exists("nqc_no_bracket_error")
+  syn region	nqcParen	transparent start='(' end=')' contains=ALLBUT,@nqcParenGroup,nqcCppParen
+  " nqcCppParen: same as nqcParen but ends at end-of-line; used in nqcDefine
+  syn region	nqcCppParen	transparent start='(' skip='\\$' excludenl end=')' end='$' contained contains=ALLBUT,@nqcParenGroup,nqcParen
+  syn match	nqcParenError	display ")"
+  syn match	nqcErrInParen	display contained "[{}]"
+else
+  syn region	nqcParen		transparent start='(' end=')' contains=ALLBUT,@nqcParenGroup,nqcCppParen,nqcErrInBracket,nqcCppBracket
+  " nqcCppParen: same as nqcParen but ends at end-of-line; used in nqcDefine
+  syn region	nqcCppParen	transparent start='(' skip='\\$' excludenl end=')' end='$' contained contains=ALLBUT,@nqcParenGroup,nqcErrInBracket,nqcParen,nqcBracket
+  syn match	nqcParenError	display "[\])]"
+  syn match	nqcErrInParen	display contained "[\]{}]"
+  syn region	nqcBracket	transparent start='\[' end=']' contains=ALLBUT,@nqcParenGroup,nqcErrInParen,nqcCppParen,nqcCppBracket
+  " nqcCppBracket: same as nqcParen but ends at end-of-line; used in nqcDefine
+  syn region	nqcCppBracket	transparent start='\[' skip='\\$' excludenl end=']' end='$' contained contains=ALLBUT,@nqcParenGroup,nqcErrInParen,nqcParen,nqcBracket
+  syn match	nqcErrInBracket	display contained "[);{}]"
+endif
+
+"integer number, or floating point number without a dot and with "f".
+syn case ignore
+syn match	nqcNumbers	display transparent "\<\d\|\.\d" contains=nqcNumber,nqcFloat
+" Same, but without octal error (for comments)
+syn match	nqcNumber	display contained "\d\+\(u\=l\{0,2}\|ll\=u\)\>"
+"hex number
+syn match	nqcNumber	display contained "0x\x\+\(u\=l\{0,2}\|ll\=u\)\>"
+" Flag the first zero of an octal number as something special
+syn match	nqcFloat	display contained "\d\+f"
+"floating point number, with dot, optional exponent
+syn match	nqcFloat	display contained "\d\+\.\d*\(e[-+]\=\d\+\)\=[fl]\="
+"floating point number, starting with a dot, optional exponent
+syn match	nqcFloat	display contained "\.\d\+\(e[-+]\=\d\+\)\=[fl]\=\>"
+"floating point number, without dot, with exponent
+syn match	nqcFloat	display contained "\d\+e[-+]\=\d\+[fl]\=\>"
+" flag an octal number with wrong digits
+syn case match
+
+syn region	nqcCommentL	start="//" skip="\\$" end="$" keepend contains=@nqcCommentGroup,nqcSpaceError
+syn region	nqcComment	matchgroup=nqcCommentStart start="/\*" matchgroup=NONE end="\*/" contains=@nqcCommentGroup,nqcCommentStartError,nqcSpaceError
+
+" keep a // comment separately, it terminates a preproc. conditional
+syntax match	nqcCommentError	display "\*/"
+syntax match	nqcCommentStartError display "/\*" contained
+
+
+
+
+
+syn region	nqcPreCondit	start="^\s*#\s*\(if\|ifdef\|ifndef\|elif\)\>" skip="\\$" end="$" end="//"me=s-1 contains=nqcComment,nqcCharacter,nqcCppParen,nqcParenError,nqcNumbers,nqcCommentError,nqcSpaceError
+syn match	nqcPreCondit	display "^\s*#\s*\(else\|endif\)\>"
+if !exists("nqc_no_if0")
+  syn region	nqcCppOut		start="^\s*#\s*if\s\+0\>" end=".\|$" contains=nqcCppOut2
+  syn region	nqcCppOut2	contained start="0" end="^\s*#\s*\(endif\>\|else\>\|elif\>\)" contains=nqcSpaceError,nqcCppSkip
+  syn region	nqcCppSkip	contained start="^\s*#\s*\(if\>\|ifdef\>\|ifndef\>\)" skip="\\$" end="^\s*#\s*endif\>" contains=nqcSpaceError,nqcCppSkip
+endif
+syn region	nqcIncluded	display contained start=+"+ skip=+\\\\\|\\"+ end=+"+
+syn match	nqcInclude	display "^\s*#\s*include\>\s*["]" contains=nqcIncluded
+"syn match nqcLineSkip	"\\$"
+syn cluster	nqcPreProcGroup	contains=nqcPreCondit,nqcIncluded,nqcInclude,nqcDefine,nqcErrInParen,nqcErrInBracket,nqcCppOut,nqcCppOut2,nqcCppSkip,nqcNumber,nqcFloat,nqcNumbers,nqcCommentSkip,@nqcCommentGroup,nqcCommentStartError,nqcParen,nqcBracket
+syn region	nqcDefine	start="^\s*#\s*\(define\|undef\)\>" skip="\\$" end="$" contains=ALLBUT,@nqcPreProcGroup
+syn region	nqcPreProc	start="^\s*#\s*\(pragma\>\)" skip="\\$" end="$" keepend contains=ALLBUT,@nqcPreProcGroup
+
+if !exists("nqc_minlines")
+  if !exists("nqc_no_if0")
+    let nqc_minlines = 50	    " #if 0 constructs can be long
+  else
+    let nqc_minlines = 15	    " mostly for () constructs
+  endif
+endif
+exec "syn sync ccomment nqcComment minlines=" . nqc_minlines
+
+" Define the default highlighting.
+" For version 5.7 and earlier: only when not done already
+" For version 5.8 and later: only when an item doesn't have highlighting yet
+if version >= 508 || !exists("did_nqc_syn_inits")
+  if version < 508
+    let did_nqc_syn_inits = 1
+    command -nargs=+ HiLink hi link <args>
+  else
+    command -nargs=+ HiLink hi def link <args>
+  endif
+
+  " The default methods for highlighting.  Can be overridden later
+  HiLink nqcLabel		Label
+  HiLink nqcConditional		Conditional
+  HiLink nqcRepeat		Repeat
+  HiLink nqcCharacter		Character
+  HiLink nqcNumber		Number
+  HiLink nqcFloat		Float
+  HiLink nqcFunction		Function
+  HiLink nqcParenError		nqcError
+  HiLink nqcErrInParen		nqcError
+  HiLink nqcErrInBracket	nqcError
+  HiLink nqcCommentL		nqcComment
+  HiLink nqcCommentStart	nqcComment
+  HiLink nqcCommentError	nqcError
+  HiLink nqcCommentStartError	nqcError
+  HiLink nqcSpaceError		nqcError
+  HiLink nqcStorageClass	StorageClass
+  HiLink nqcInclude		Include
+  HiLink nqcPreProc		PreProc
+  HiLink nqcDefine		Macro
+  HiLink nqcIncluded		String
+  HiLink nqcError		Error
+  HiLink nqcStatement		Statement
+  HiLink nqcEvents		Statement
+  HiLink nqcPreCondit		PreCondit
+  HiLink nqcType		Type
+  HiLink nqcConstant		Constant
+  HiLink nqcCommentSkip		nqcComment
+  HiLink nqcComment		Comment
+  HiLink nqcTodo		Todo
+  HiLink nqcCppSkip		nqcCppOut
+  HiLink nqcCppOut2		nqcCppOut
+  HiLink nqcCppOut		Comment
+
+  delcommand HiLink
+endif
+
+let b:current_syntax = "nqc"
+
+" vim: ts=8
--- /dev/null
+++ b/lib/vimfiles/syntax/nroff.vim
@@ -1,0 +1,259 @@
+" VIM syntax file
+" Language:	nroff/groff
+" Maintainer:	Alejandro L�pez-Valencia <dradul@yahoo.com>
+" URL:		http://dradul.tripod.com/vim
+" Last Change:	2006 Apr 14
+"
+" {{{1 Acknowledgements
+"
+" ACKNOWLEDGEMENTS:
+"
+" My thanks to J�r�me Pl�t <Jerome.Plut@ens.fr>, who was the
+" creator and maintainer of this syntax file for several years.
+" May I be as good at it as he has been.
+"
+" {{{1 Todo
+"
+" TODO:
+"
+" * Write syntax highlighting files for the preprocessors,
+"	and integrate with nroff.vim.
+"
+"
+" {{{1 Start syntax highlighting.
+"
+" For version 5.x: Clear all syntax items
+" For version 6.x: Quit when a syntax file was already loaded
+"
+if version < 600
+	syntax clear
+elseif exists("b:current_syntax")
+	finish
+endif
+
+"
+" {{{1 plugin settings...
+"
+" {{{2 enable spacing error highlighting
+"
+if exists("nroff_space_errors")
+	syn match nroffError /\s\+$/
+	syn match nroffSpaceError /[.,:;!?]\s\{2,}/
+endif
+"
+"
+" {{{1 Special file settings
+"
+" {{{2  ms exdented paragraphs are not in the default paragraphs list.
+"
+setlocal paragraphs+=XP
+"
+" {{{2 Activate navigation to preporcessor sections.
+"
+if exists("b:preprocs_as_sections")
+	setlocal sections=EQTSPS[\ G1GS
+endif
+
+" {{{1 Escape sequences
+" ------------------------------------------------------------
+
+syn match nroffEscChar /\\[CN]/ nextgroup=nroffEscCharArg
+syn match nroffEscape /\\[*fgmnYV]/ nextgroup=nroffEscRegPar,nroffEscRegArg
+syn match nroffEscape /\\s[+-]\=/ nextgroup=nroffSize
+syn match nroffEscape /\\[$AbDhlLRvxXZ]/ nextgroup=nroffEscPar,nroffEscArg
+
+syn match nroffEscRegArg /./ contained
+syn match nroffEscRegArg2 /../ contained
+syn match nroffEscRegPar /(/ contained nextgroup=nroffEscRegArg2
+syn match nroffEscArg /./ contained
+syn match nroffEscArg2 /../ contained
+syn match nroffEscPar /(/ contained nextgroup=nroffEscArg2
+syn match nroffSize /\((\d\)\=\d/ contained
+
+syn region nroffEscCharArg start=/'/ end=/'/ contained
+syn region nroffEscArg start=/'/ end=/'/ contained contains=nroffEscape,@nroffSpecial
+
+if exists("b:nroff_is_groff")
+	syn region nroffEscRegArg matchgroup=nroffEscape start=/\[/ end=/\]/ contained oneline
+	syn region nroffSize matchgroup=nroffEscape start=/\[/ end=/\]/ contained
+endif
+
+syn match nroffEscape /\\[adprtu{}]/
+syn match nroffEscape /\\$/
+syn match nroffEscape /\\\$[@*]/
+
+" {{{1 Strings and special characters
+" ------------------------------------------------------------
+
+syn match nroffSpecialChar /\\[\\eE?!-]/
+syn match nroffSpace "\\[&%~|^0)/,]"
+syn match nroffSpecialChar /\\(../
+
+if exists("b:nroff_is_groff")
+	syn match nroffSpecialChar /\\\[[^]]*]/
+	syn region nroffPreserve  matchgroup=nroffSpecialChar start=/\\?/ end=/\\?/ oneline
+endif
+
+syn region nroffPreserve matchgroup=nroffSpecialChar start=/\\!/ end=/$/ oneline
+
+syn cluster nroffSpecial contains=nroffSpecialChar,nroffSpace
+
+
+syn region nroffString start=/"/ end=/"/ skip=/\\$/ contains=nroffEscape,@nroffSpecial contained
+syn region nroffString start=/'/ end=/'/ skip=/\\$/ contains=nroffEscape,@nroffSpecial contained
+
+
+" {{{1 Numbers and units
+" ------------------------------------------------------------
+syn match nroffNumBlock /[0-9.]\a\=/ contained contains=nroffNumber
+syn match nroffNumber /\d\+\(\.\d*\)\=/ contained nextgroup=nroffUnit,nroffBadChar
+syn match nroffNumber /\.\d\+)/ contained nextgroup=nroffUnit,nroffBadChar
+syn match nroffBadChar /./ contained
+syn match nroffUnit /[icpPszmnvMu]/ contained
+
+
+" {{{1 Requests
+" ------------------------------------------------------------
+
+" Requests begin with . or ' at the beginning of a line, or
+" after .if or .ie.
+
+syn match nroffReqLeader /^[.']/	nextgroup=nroffReqName skipwhite
+syn match nroffReqLeader /[.']/	contained nextgroup=nroffReqName skipwhite
+
+if exists("b:nroff_is_groff")
+"
+" GNU troff allows long request names
+"
+	syn match nroffReqName /[^\t \\\[?]\+/ contained nextgroup=nroffReqArg
+else
+	syn match nroffReqName /[^\t \\\[?]\{1,2}/ contained nextgroup=nroffReqArg
+endif
+
+syn region nroffReqArg start=/\S/ skip=/\\$/ end=/$/ contained contains=nroffEscape,@nroffSpecial,nroffString,nroffError,nroffSpaceError,nroffNumBlock,nroffComment
+
+" {{{2 Conditional: .if .ie .el
+syn match nroffReqName /\(if\|ie\)/ contained nextgroup=nroffCond skipwhite
+syn match nroffReqName /el/ contained nextgroup=nroffReqLeader skipwhite
+syn match nroffCond /\S\+/ contained nextgroup=nroffReqLeader skipwhite
+
+" {{{2 String definition: .ds .as
+syn match nroffReqname /[da]s/ contained nextgroup=nroffDefIdent skipwhite
+syn match nroffDefIdent /\S\+/ contained nextgroup=nroffDefinition skipwhite
+syn region nroffDefinition matchgroup=nroffSpecialChar start=/"/ matchgroup=NONE end=/\\"/me=e-2 skip=/\\$/ start=/\S/ end=/$/ contained contains=nroffDefSpecial
+syn match nroffDefSpecial /\\$/ contained
+syn match nroffDefSpecial /\\\((.\)\=./ contained
+
+if exists("b:nroff_is_groff")
+	syn match nroffDefSpecial /\\\[[^]]*]/ contained
+endif
+
+" {{{2 Macro definition: .de .am, also diversion: .di
+syn match nroffReqName /\(d[ei]\|am\)/ contained nextgroup=nroffIdent skipwhite
+syn match nroffIdent /[^[?( \t]\+/ contained
+if exists("b:nroff_is_groff")
+	syn match nroffReqName /als/ contained nextgroup=nroffIdent skipwhite
+endif
+
+" {{{2 Register definition: .rn .rr
+syn match nroffReqName /[rn]r/ contained nextgroup=nroffIdent skipwhite
+if exists("b:nroff_is_groff")
+	syn match nroffReqName /\(rnn\|aln\)/ contained nextgroup=nroffIdent skipwhite
+endif
+
+
+" {{{1 eqn/tbl/pic
+" ------------------------------------------------------------
+" <jp>
+" XXX: write proper syntax highlight for eqn / tbl / pic ?
+" <jp />
+
+syn region nroffEquation start=/^\.\s*EQ\>/ end=/^\.\s*EN\>/
+syn region nroffTable start=/^\.\s*TS\>/ end=/^\.\s*TE\>/
+syn region nroffPicture start=/^\.\s*PS\>/ end=/^\.\s*PE\>/
+syn region nroffRefer start=/^\.\s*\[\>/ end=/^\.\s*\]\>/
+syn region nroffGrap start=/^\.\s*G1\>/ end=/^\.\s*G2\>/
+syn region nroffGremlin start=/^\.\s*GS\>/ end=/^\.\s*GE|GF\>/
+
+" {{{1 Comments
+" ------------------------------------------------------------
+
+syn region nroffIgnore start=/^[.']\s*ig/ end=/^['.]\s*\./
+syn match nroffComment /\(^[.']\s*\)\=\\".*/ contains=nroffTodo
+syn match nroffComment /^'''.*/  contains=nroffTodo
+
+if exists("b:nroff_is_groff")
+	syn match nroffComment "\\#.*$" contains=nroffTodo
+endif
+
+syn keyword nroffTodo TODO XXX FIXME contained
+
+" {{{1 Hilighting
+" ------------------------------------------------------------
+"
+
+"
+" Define the default highlighting.
+" For version 5.7 and earlier: only when not done already
+" For version 5.8 and later: only when an item doesn't have highlighting yet
+"
+if version >= 508 || !exists("did_nroff_syn_inits")
+
+	if version < 508
+		let did_nroff_syn_inits = 1
+		command -nargs=+ HiLink hi link <args>
+	else
+		command -nargs=+ HiLink hi def link <args>
+	endif
+
+	HiLink nroffEscChar nroffSpecialChar
+	HiLink nroffEscCharAr nroffSpecialChar
+	HiLink nroffSpecialChar SpecialChar
+	HiLink nroffSpace Delimiter
+
+	HiLink nroffEscRegArg2 nroffEscRegArg
+	HiLink nroffEscRegArg nroffIdent
+
+	HiLink nroffEscArg2 nroffEscArg
+	HiLink nroffEscPar nroffEscape
+
+	HiLink nroffEscRegPar nroffEscape
+	HiLink nroffEscArg nroffEscape
+	HiLink nroffSize nroffEscape
+	HiLink nroffEscape Preproc
+
+	HiLink nroffIgnore Comment
+	HiLink nroffComment Comment
+	HiLink nroffTodo Todo
+
+	HiLink nroffReqLeader nroffRequest
+	HiLink nroffReqName nroffRequest
+	HiLink nroffRequest Statement
+	HiLink nroffCond PreCondit
+	HiLink nroffDefIdent nroffIdent
+	HiLink nroffIdent Identifier
+
+	HiLink nroffEquation PreProc
+	HiLink nroffTable PreProc
+	HiLink nroffPicture PreProc
+	HiLink nroffRefer PreProc
+	HiLink nroffGrap PreProc
+	HiLink nroffGremlin PreProc
+
+	HiLink nroffNumber Number
+	HiLink nroffBadChar nroffError
+	HiLink nroffSpaceError nroffError
+	HiLink nroffError Error
+
+	HiLink nroffPreserve String
+	HiLink nroffString String
+	HiLink nroffDefinition String
+	HiLink nroffDefSpecial Special
+
+	delcommand HiLink
+
+endif
+
+let b:current_syntax = "nroff"
+
+" vim600: set fdm=marker fdl=2:
--- /dev/null
+++ b/lib/vimfiles/syntax/nsis.vim
@@ -1,0 +1,271 @@
+" Vim syntax file
+" Language:	NSIS script, for version of NSIS 1.91 and later
+" Maintainer:	Alex Jakushev <Alex.Jakushev@kemek.lt>
+" Last Change:	2004 May 12
+
+" For version 5.x: Clear all syntax items
+" For version 6.x: Quit when a syntax file was already loaded
+if version < 600
+  syntax clear
+elseif exists("b:current_syntax")
+  finish
+endif
+
+syn case ignore
+
+
+"COMMENTS
+syn keyword nsisTodo	todo attention note fixme readme
+syn region nsisComment	start=";"  end="$" contains=nsisTodo
+syn region nsisComment	start="#"  end="$" contains=nsisTodo
+
+"LABELS
+syn match nsisLocalLabel	"\a\S\{-}:"
+syn match nsisGlobalLabel	"\.\S\{-1,}:"
+
+"PREPROCESSOR
+syn match nsisPreprocSubst	"${.\{-}}"
+syn match nsisDefine		"!define\>"
+syn match nsisDefine		"!undef\>"
+syn match nsisPreCondit		"!ifdef\>"
+syn match nsisPreCondit		"!ifndef\>"
+syn match nsisPreCondit		"!endif\>"
+syn match nsisPreCondit		"!else\>"
+syn match nsisMacro		"!macro\>"
+syn match nsisMacro		"!macroend\>"
+syn match nsisMacro		"!insertmacro\>"
+
+"COMPILER UTILITY
+syn match nsisInclude		"!include\>"
+syn match nsisSystem		"!cd\>"
+syn match nsisSystem		"!system\>"
+syn match nsisSystem		"!packhdr\>"
+
+"VARIABLES
+syn match nsisUserVar		"$\d"
+syn match nsisUserVar		"$R\d"
+syn match nsisSysVar		"$INSTDIR"
+syn match nsisSysVar		"$OUTDIR"
+syn match nsisSysVar		"$CMDLINE"
+syn match nsisSysVar		"$PROGRAMFILES"
+syn match nsisSysVar		"$DESKTOP"
+syn match nsisSysVar		"$EXEDIR"
+syn match nsisSysVar		"$WINDIR"
+syn match nsisSysVar		"$SYSDIR"
+syn match nsisSysVar		"$TEMP"
+syn match nsisSysVar		"$STARTMENU"
+syn match nsisSysVar		"$SMPROGRAMS"
+syn match nsisSysVar		"$SMSTARTUP"
+syn match nsisSysVar		"$QUICKLAUNCH"
+syn match nsisSysVar		"$HWNDPARENT"
+syn match nsisSysVar		"$\\r"
+syn match nsisSysVar		"$\\n"
+syn match nsisSysVar		"$\$"
+
+"STRINGS
+syn region nsisString	start=/"/ skip=/'\|`/ end=/"/ contains=nsisPreprocSubst,nsisUserVar,nsisSysVar,nsisRegistry
+syn region nsisString	start=/'/ skip=/"\|`/ end=/'/ contains=nsisPreprocSubst,nsisUserVar,nsisSysVar,nsisRegistry
+syn region nsisString	start=/`/ skip=/"\|'/ end=/`/ contains=nsisPreprocSubst,nsisUserVar,nsisSysVar,nsisRegistry
+
+"CONSTANTS
+syn keyword nsisBoolean		true false on off
+
+syn keyword nsisAttribOptions	hide show nevershow auto force try ifnewer normal silent silentlog
+syn keyword nsisAttribOptions	smooth colored SET CUR END RO none listonly textonly both current all
+syn keyword nsisAttribOptions	zlib bzip2 lzma
+
+syn match nsisAttribOptions	'\/NOCUSTOM'
+syn match nsisAttribOptions	'\/CUSTOMSTRING'
+syn match nsisAttribOptions	'\/COMPONENTSONLYONCUSTOM'
+syn match nsisAttribOptions	'\/windows'
+syn match nsisAttribOptions	'\/r'
+syn match nsisAttribOptions	'\/oname'
+syn match nsisAttribOptions	'\/REBOOTOK'
+syn match nsisAttribOptions	'\/SILENT'
+syn match nsisAttribOptions	'\/FILESONLY'
+syn match nsisAttribOptions	'\/SHORT'
+
+syn keyword nsisExecShell	SW_SHOWNORMAL SW_SHOWMAXIMIZED SW_SHOWMINIMIZED
+
+syn keyword nsisRegistry	HKCR HKLM HKCU HKU HKCC HKDD HKPD
+syn keyword nsisRegistry	HKEY_CLASSES_ROOT HKEY_LOCAL_MACHINE HKEY_CURRENT_USER HKEY_USERS
+syn keyword nsisRegistry	HKEY_CURRENT_CONFIG HKEY_DYN_DATA HKEY_PERFORMANCE_DATA
+
+syn keyword nsisFileAttrib	NORMAL ARCHIVE HIDDEN OFFLINE READONLY SYSTEM TEMPORARY
+syn keyword nsisFileAttrib	FILE_ATTRIBUTE_NORMAL FILE_ATTRIBUTE_ARCHIVE FILE_ATTRIBUTE_HIDDEN
+syn keyword nsisFileAttrib	FILE_ATTRIBUTE_OFFLINE FILE_ATTRIBUTE_READONLY FILE_ATTRIBUTE_SYSTEM
+syn keyword nsisFileAttrib	FILE_ATTRIBUTE_TEMPORARY
+
+syn keyword nsisMessageBox	MB_OK MB_OKCANCEL MB_ABORTRETRYIGNORE MB_RETRYCANCEL MB_YESNO MB_YESNOCANCEL
+syn keyword nsisMessageBox	MB_ICONEXCLAMATION MB_ICONINFORMATION MB_ICONQUESTION MB_ICONSTOP
+syn keyword nsisMessageBox	MB_TOPMOST MB_SETFOREGROUND MB_RIGHT
+syn keyword nsisMessageBox	MB_DEFBUTTON1 MB_DEFBUTTON2 MB_DEFBUTTON3 MB_DEFBUTTON4
+syn keyword nsisMessageBox	IDABORT IDCANCEL IDIGNORE IDNO IDOK IDRETRY IDYES
+
+syn match nsisNumber		"\<[^0]\d*\>"
+syn match nsisNumber		"\<0x\x\+\>"
+syn match nsisNumber		"\<0\o*\>"
+
+
+"INSTALLER ATTRIBUTES - General installer configuration
+syn keyword nsisAttribute	OutFile Name Caption SubCaption BrandingText Icon
+syn keyword nsisAttribute	WindowIcon BGGradient SilentInstall SilentUnInstall
+syn keyword nsisAttribute	CRCCheck MiscButtonText InstallButtonText FileErrorText
+
+"INSTALLER ATTRIBUTES - Install directory configuration
+syn keyword nsisAttribute	InstallDir InstallDirRegKey
+
+"INSTALLER ATTRIBUTES - License page configuration
+syn keyword nsisAttribute	LicenseText LicenseData
+
+"INSTALLER ATTRIBUTES - Component page configuration
+syn keyword nsisAttribute	ComponentText InstType EnabledBitmap DisabledBitmap SpaceTexts
+
+"INSTALLER ATTRIBUTES - Directory page configuration
+syn keyword nsisAttribute	DirShow DirText AllowRootDirInstall
+
+"INSTALLER ATTRIBUTES - Install page configuration
+syn keyword nsisAttribute	InstallColors InstProgressFlags AutoCloseWindow
+syn keyword nsisAttribute	ShowInstDetails DetailsButtonText CompletedText
+
+"INSTALLER ATTRIBUTES - Uninstall configuration
+syn keyword nsisAttribute	UninstallText UninstallIcon UninstallCaption
+syn keyword nsisAttribute	UninstallSubCaption ShowUninstDetails UninstallButtonText
+
+"COMPILER ATTRIBUTES
+syn keyword nsisCompiler	SetOverwrite SetCompress SetCompressor SetDatablockOptimize SetDateSave
+
+
+"FUNCTIONS - general purpose
+syn keyword nsisInstruction	SetOutPath File Exec ExecWait ExecShell
+syn keyword nsisInstruction	Rename Delete RMDir
+
+"FUNCTIONS - registry & ini
+syn keyword nsisInstruction	WriteRegStr WriteRegExpandStr WriteRegDWORD WriteRegBin
+syn keyword nsisInstruction	WriteINIStr ReadRegStr ReadRegDWORD ReadINIStr ReadEnvStr
+syn keyword nsisInstruction	ExpandEnvStrings DeleteRegValue DeleteRegKey EnumRegKey
+syn keyword nsisInstruction	EnumRegValue DeleteINISec DeleteINIStr
+
+"FUNCTIONS - general purpose, advanced
+syn keyword nsisInstruction	CreateDirectory CopyFiles SetFileAttributes CreateShortCut
+syn keyword nsisInstruction	GetFullPathName SearchPath GetTempFileName CallInstDLL
+syn keyword nsisInstruction	RegDLL UnRegDLL GetDLLVersion GetDLLVersionLocal
+syn keyword nsisInstruction	GetFileTime GetFileTimeLocal
+
+"FUNCTIONS - Branching, flow control, error checking, user interaction, etc instructions
+syn keyword nsisInstruction	Goto Call Return IfErrors ClearErrors SetErrors FindWindow
+syn keyword nsisInstruction	SendMessage IsWindow IfFileExists MessageBox StrCmp
+syn keyword nsisInstruction	IntCmp IntCmpU Abort Quit GetFunctionAddress GetLabelAddress
+syn keyword nsisInstruction	GetCurrentAddress
+
+"FUNCTIONS - File and directory i/o instructions
+syn keyword nsisInstruction	FindFirst FindNext FindClose FileOpen FileClose FileRead
+syn keyword nsisInstruction	FileWrite FileReadByte FileWriteByte FileSeek
+
+"FUNCTIONS - Misc instructions
+syn keyword nsisInstruction	SetDetailsView SetDetailsPrint SetAutoClose DetailPrint
+syn keyword nsisInstruction	Sleep BringToFront HideWindow SetShellVarContext
+
+"FUNCTIONS - String manipulation support
+syn keyword nsisInstruction	StrCpy StrLen
+
+"FUNCTIONS - Stack support
+syn keyword nsisInstruction	Push Pop Exch
+
+"FUNCTIONS - Integer manipulation support
+syn keyword nsisInstruction	IntOp IntFmt
+
+"FUNCTIONS - Rebooting support
+syn keyword nsisInstruction	Reboot IfRebootFlag SetRebootFlag
+
+"FUNCTIONS - Uninstaller instructions
+syn keyword nsisInstruction	WriteUninstaller
+
+"FUNCTIONS - Install logging instructions
+syn keyword nsisInstruction	LogSet LogText
+
+"FUNCTIONS - Section management instructions
+syn keyword nsisInstruction	SectionSetFlags SectionGetFlags SectionSetText
+syn keyword nsisInstruction	SectionGetText
+
+
+"SPECIAL FUNCTIONS - install
+syn match nsisCallback		"\.onInit"
+syn match nsisCallback		"\.onUserAbort"
+syn match nsisCallback		"\.onInstSuccess"
+syn match nsisCallback		"\.onInstFailed"
+syn match nsisCallback		"\.onVerifyInstDir"
+syn match nsisCallback		"\.onNextPage"
+syn match nsisCallback		"\.onPrevPage"
+syn match nsisCallback		"\.onSelChange"
+
+"SPECIAL FUNCTIONS - uninstall
+syn match nsisCallback		"un\.onInit"
+syn match nsisCallback		"un\.onUserAbort"
+syn match nsisCallback		"un\.onInstSuccess"
+syn match nsisCallback		"un\.onInstFailed"
+syn match nsisCallback		"un\.onVerifyInstDir"
+syn match nsisCallback		"un\.onNextPage"
+
+
+"STATEMENTS - sections
+syn keyword nsisStatement	Section SectionIn SectionEnd SectionDivider
+syn keyword nsisStatement	AddSize
+
+"STATEMENTS - functions
+syn keyword nsisStatement	Function FunctionEnd
+
+"STATEMENTS - pages
+syn keyword nsisStatement	Page UninstPage PageEx PageExEnc PageCallbacks
+
+
+"ERROR
+syn keyword nsisError		UninstallExeName
+
+
+" Define the default highlighting.
+" For version 5.7 and earlier: only when not done already
+" For version 5.8 and later: only when an item doesn't have highlighting yet
+if version >= 508 || !exists("did_nsis_syn_inits")
+
+  if version < 508
+    let did_nsys_syn_inits = 1
+    command -nargs=+ HiLink hi link <args>
+  else
+    command -nargs=+ HiLink hi def link <args>
+  endif
+
+
+  HiLink nsisInstruction		Function
+  HiLink nsisComment			Comment
+  HiLink nsisLocalLabel			Label
+  HiLink nsisGlobalLabel		Label
+  HiLink nsisStatement			Statement
+  HiLink nsisString			String
+  HiLink nsisBoolean			Boolean
+  HiLink nsisAttribOptions		Constant
+  HiLink nsisExecShell			Constant
+  HiLink nsisFileAttrib			Constant
+  HiLink nsisMessageBox			Constant
+  HiLink nsisRegistry			Identifier
+  HiLink nsisNumber			Number
+  HiLink nsisError			Error
+  HiLink nsisUserVar			Identifier
+  HiLink nsisSysVar			Identifier
+  HiLink nsisAttribute			Type
+  HiLink nsisCompiler			Type
+  HiLink nsisTodo			Todo
+  HiLink nsisCallback			Operator
+  " preprocessor commands
+  HiLink nsisPreprocSubst		PreProc
+  HiLink nsisDefine			Define
+  HiLink nsisMacro			Macro
+  HiLink nsisPreCondit			PreCondit
+  HiLink nsisInclude			Include
+  HiLink nsisSystem			PreProc
+
+  delcommand HiLink
+endif
+
+let b:current_syntax = "nsis"
+
--- /dev/null
+++ b/lib/vimfiles/syntax/objc.vim
@@ -1,0 +1,110 @@
+" Vim syntax file
+" Language:	    Objective C
+" Maintainer:	    Kazunobu Kuriyama <kazunobu.kuriyama@nifty.com>
+" Ex-maintainer:    Anthony Hodsdon <ahodsdon@fastmail.fm>
+" First Author:	    Valentino Kyriakides <1kyriaki@informatik.uni-hamburg.de>
+" Last Change:	    2007 Feb 21
+
+" For version 5.x: Clear all syntax items
+" For version 6.x: Quit when a syntax file was already loaded
+if version < 600
+  syntax clear
+elseif exists("b:current_syntax")
+  finish
+endif
+
+if &filetype != 'objcpp'
+  " Read the C syntax to start with
+  if version < 600
+    source <sfile>:p:h/c.vim
+  else
+    runtime! syntax/c.vim
+  endif
+endif
+
+" Objective C extentions follow below
+"
+" NOTE: Objective C is abbreviated to ObjC/objc
+" and uses *.h, *.m as file extensions!
+
+
+" ObjC keywords, types, type qualifiers etc.
+syn keyword objcStatement	self super _cmd
+syn keyword objcType		id Class SEL IMP BOOL
+syn keyword objcTypeModifier	bycopy in out inout oneway
+syn keyword objcConstant	nil Nil
+
+" Match the ObjC #import directive (like C's #include)
+syn region objcImported display contained start=+"+  skip=+\\\\\|\\"+  end=+"+
+syn match  objcImported display contained "<[-_0-9a-zA-Z.\/]*>"
+syn match  objcImport display "^\s*\(%:\|#\)\s*import\>\s*["<]" contains=objcImported
+
+" Match the important ObjC directives
+syn match  objcScopeDecl    "@public\|@private\|@protected"
+syn match  objcDirective    "@interface\|@implementation"
+syn match  objcDirective    "@class\|@end\|@defs"
+syn match  objcDirective    "@encode\|@protocol\|@selector"
+syn match  objcDirective    "@try\|@catch\|@finally\|@throw\|@synchronized"
+
+" Match the ObjC method types
+"
+" NOTE: here I match only the indicators, this looks
+" much nicer and reduces cluttering color highlightings.
+" However, if you prefer full method declaration matching
+" append .* at the end of the next two patterns!
+"
+syn match objcInstMethod    "^\s*-\s*"
+syn match objcFactMethod    "^\s*+\s*"
+
+" To distinguish from a header inclusion from a protocol list.
+syn match objcProtocol display "<[_a-zA-Z][_a-zA-Z0-9]*>" contains=objcType,cType,Type
+
+
+" To distinguish labels from the keyword for a method's parameter.
+syn region objcKeyForMethodParam display
+    \ start="^\s*[_a-zA-Z][_a-zA-Z0-9]*\s*:\s*("
+    \ end=")\s*[_a-zA-Z][_a-zA-Z0-9]*"
+    \ contains=objcType,objcTypeModifier,cType,cStructure,cStorageClass,Type
+
+" Objective-C Constant Strings
+syn match objcSpecial display "%@" contained
+syn region objcString start=+\(@"\|"\)+ skip=+\\\\\|\\"+ end=+"+ contains=cFormat,cSpecial,objcSpecial
+
+" Objective-C Message Expressions
+syn region objcMessage display start="\[" end="\]" contains=objcMessage,objcStatement,objcType,objcTypeModifier,objcString,objcConstant,objcDirective,cType,cStructure,cStorageClass,cString,cCharacter,cSpecialCharacter,cNumbers,cConstant,cOperator,cComment,cCommentL,Type
+
+syn cluster cParenGroup add=objcMessage
+syn cluster cPreProcGroup add=objcMessage
+
+" Define the default highlighting.
+" For version 5.7 and earlier: only when not done already
+" For version 5.8 and later: only when an item doesn't have highlighting yet
+if version >= 508 || !exists("did_objc_syntax_inits")
+  if version < 508
+    let did_objc_syntax_inits = 1
+    command -nargs=+ HiLink hi link <args>
+  else
+    command -nargs=+ HiLink hi def link <args>
+  endif
+
+  HiLink objcImport		Include
+  HiLink objcImported		cString
+  HiLink objcTypeModifier	objcType
+  HiLink objcType		Type
+  HiLink objcScopeDecl		Statement
+  HiLink objcInstMethod		Function
+  HiLink objcFactMethod		Function
+  HiLink objcStatement		Statement
+  HiLink objcDirective		Statement
+  HiLink objcKeyForMethodParam	None
+  HiLink objcString		cString
+  HiLink objcSpecial		Special
+  HiLink objcProtocol		None
+  HiLink objcConstant		cConstant
+
+  delcommand HiLink
+endif
+
+let b:current_syntax = "objc"
+
+" vim: ts=8
--- /dev/null
+++ b/lib/vimfiles/syntax/objcpp.vim
@@ -1,0 +1,31 @@
+" Vim syntax file
+" Language:     ObjC++
+" Maintainer:   Anthony Hodsdon <ahodsdon@fastmail.fm>
+" Last change:  2003 Apr 25
+
+" For version 5.x: Clear all syntax items
+" For version 6.x: Quit when a syntax file was already loaded
+if version < 600
+   syntax clear
+elseif exists("b:current_syntax")
+   finish
+endif
+
+" Read in C++ and ObjC syntax files
+if version < 600
+   so <sfile>:p:h/cpp.vim
+   so <sflie>:p:h/objc.vim
+else
+   runtime! syntax/cpp.vim
+   unlet b:current_syntax
+   runtime! syntax/objc.vim
+endif
+
+" Note that we already have a region for method calls ( [objc_class method] )
+" by way of cBracket.
+syn region objCFunc start="^\s*[-+]"  end="$"  contains=ALLBUT,cErrInParen,cErrInBracket
+
+syn keyword objCppNonStructure    class template namespace transparent contained
+syn keyword objCppNonStatement    new delete friend using transparent contained
+
+let b:current_syntax = "objcpp"
--- /dev/null
+++ b/lib/vimfiles/syntax/ocaml.vim
@@ -1,0 +1,327 @@
+" Vim syntax file
+" Language:     OCaml
+" Filenames:    *.ml *.mli *.mll *.mly
+" Maintainers:  Markus Mottl      <markus.mottl@gmail.com>
+"               Karl-Heinz Sylla  <Karl-Heinz.Sylla@gmd.de>
+"               Issac Trotts      <ijtrotts@ucdavis.edu>
+" URL:          http://www.ocaml.info/vim/syntax/ocaml.vim
+" Last Change:  2007 Apr 13 - Added highlighting of nativeints (MM)
+"               2006 Oct 09 - More highlighting improvements to numbers (MM)
+"               2006 Sep 19 - Improved highlighting of numbers (Florent Monnier)
+
+" A minor patch was applied to the official version so that object/end
+" can be distinguished from begin/end, which is used for indentation,
+" and folding. (David Baelde)
+
+" For version 5.x: Clear all syntax items
+" For version 6.x: Quit when a syntax file was already loaded
+if version < 600
+  syntax clear
+elseif exists("b:current_syntax") && b:current_syntax == "ocaml"
+  finish
+endif
+
+" OCaml is case sensitive.
+syn case match
+
+" Script headers highlighted like comments
+syn match    ocamlComment   "^#!.*"
+
+" Scripting directives
+syn match    ocamlScript "^#\<\(quit\|labels\|warnings\|directory\|cd\|load\|use\|install_printer\|remove_printer\|require\|thread\|trace\|untrace\|untrace_all\|print_depth\|print_length\)\>"
+
+" Script headers highlighted like comments
+syn match    ocamlComment      "^#!.*"
+
+" lowercase identifier - the standard way to match
+syn match    ocamlLCIdentifier /\<\(\l\|_\)\(\w\|'\)*\>/
+
+syn match    ocamlKeyChar    "|"
+
+" Errors
+syn match    ocamlBraceErr   "}"
+syn match    ocamlBrackErr   "\]"
+syn match    ocamlParenErr   ")"
+syn match    ocamlArrErr     "|]"
+
+syn match    ocamlCommentErr "\*)"
+
+syn match    ocamlCountErr   "\<downto\>"
+syn match    ocamlCountErr   "\<to\>"
+
+if !exists("ocaml_revised")
+  syn match    ocamlDoErr      "\<do\>"
+endif
+
+syn match    ocamlDoneErr    "\<done\>"
+syn match    ocamlThenErr    "\<then\>"
+
+" Error-highlighting of "end" without synchronization:
+" as keyword or as error (default)
+if exists("ocaml_noend_error")
+  syn match    ocamlKeyword    "\<end\>"
+else
+  syn match    ocamlEndErr     "\<end\>"
+endif
+
+" Some convenient clusters
+syn cluster  ocamlAllErrs contains=ocamlBraceErr,ocamlBrackErr,ocamlParenErr,ocamlCommentErr,ocamlCountErr,ocamlDoErr,ocamlDoneErr,ocamlEndErr,ocamlThenErr
+
+syn cluster  ocamlAENoParen contains=ocamlBraceErr,ocamlBrackErr,ocamlCommentErr,ocamlCountErr,ocamlDoErr,ocamlDoneErr,ocamlEndErr,ocamlThenErr
+
+syn cluster  ocamlContained contains=ocamlTodo,ocamlPreDef,ocamlModParam,ocamlModParam1,ocamlPreMPRestr,ocamlMPRestr,ocamlMPRestr1,ocamlMPRestr2,ocamlMPRestr3,ocamlModRHS,ocamlFuncWith,ocamlFuncStruct,ocamlModTypeRestr,ocamlModTRWith,ocamlWith,ocamlWithRest,ocamlModType,ocamlFullMod
+
+
+" Enclosing delimiters
+syn region   ocamlEncl transparent matchgroup=ocamlKeyword start="(" matchgroup=ocamlKeyword end=")" contains=ALLBUT,@ocamlContained,ocamlParenErr
+syn region   ocamlEncl transparent matchgroup=ocamlKeyword start="{" matchgroup=ocamlKeyword end="}"  contains=ALLBUT,@ocamlContained,ocamlBraceErr
+syn region   ocamlEncl transparent matchgroup=ocamlKeyword start="\[" matchgroup=ocamlKeyword end="\]" contains=ALLBUT,@ocamlContained,ocamlBrackErr
+syn region   ocamlEncl transparent matchgroup=ocamlKeyword start="\[|" matchgroup=ocamlKeyword end="|\]" contains=ALLBUT,@ocamlContained,ocamlArrErr
+
+
+" Comments
+syn region   ocamlComment start="(\*" end="\*)" contains=ocamlComment,ocamlTodo
+syn keyword  ocamlTodo contained TODO FIXME XXX NOTE
+
+
+" Objects
+syn region   ocamlEnd matchgroup=ocamlObject start="\<object\>" matchgroup=ocamlObject end="\<end\>" contains=ALLBUT,@ocamlContained,ocamlEndErr
+
+
+" Blocks
+if !exists("ocaml_revised")
+  syn region   ocamlEnd matchgroup=ocamlKeyword start="\<begin\>" matchgroup=ocamlKeyword end="\<end\>" contains=ALLBUT,@ocamlContained,ocamlEndErr
+endif
+
+
+" "for"
+syn region   ocamlNone matchgroup=ocamlKeyword start="\<for\>" matchgroup=ocamlKeyword end="\<\(to\|downto\)\>" contains=ALLBUT,@ocamlContained,ocamlCountErr
+
+
+" "do"
+if !exists("ocaml_revised")
+  syn region   ocamlDo matchgroup=ocamlKeyword start="\<do\>" matchgroup=ocamlKeyword end="\<done\>" contains=ALLBUT,@ocamlContained,ocamlDoneErr
+endif
+
+" "if"
+syn region   ocamlNone matchgroup=ocamlKeyword start="\<if\>" matchgroup=ocamlKeyword end="\<then\>" contains=ALLBUT,@ocamlContained,ocamlThenErr
+
+
+"" Modules
+
+" "struct"
+syn region   ocamlStruct matchgroup=ocamlModule start="\<struct\>" matchgroup=ocamlModule end="\<end\>" contains=ALLBUT,@ocamlContained,ocamlEndErr
+
+" "sig"
+syn region   ocamlSig matchgroup=ocamlModule start="\<sig\>" matchgroup=ocamlModule end="\<end\>" contains=ALLBUT,@ocamlContained,ocamlEndErr,ocamlModule
+syn region   ocamlModSpec matchgroup=ocamlKeyword start="\<module\>" matchgroup=ocamlModule end="\<\u\(\w\|'\)*\>" contained contains=@ocamlAllErrs,ocamlComment skipwhite skipempty nextgroup=ocamlModTRWith,ocamlMPRestr
+
+" "open"
+syn region   ocamlNone matchgroup=ocamlKeyword start="\<open\>" matchgroup=ocamlModule end="\<\u\(\w\|'\)*\(\.\u\(\w\|'\)*\)*\>" contains=@ocamlAllErrs,ocamlComment
+
+" "include"
+syn match    ocamlKeyword "\<include\>" skipwhite skipempty nextgroup=ocamlModParam,ocamlFullMod
+
+" "module" - somewhat complicated stuff ;-)
+syn region   ocamlModule matchgroup=ocamlKeyword start="\<module\>" matchgroup=ocamlModule end="\<\u\(\w\|'\)*\>" contains=@ocamlAllErrs,ocamlComment skipwhite skipempty nextgroup=ocamlPreDef
+syn region   ocamlPreDef start="."me=e-1 matchgroup=ocamlKeyword end="\l\|="me=e-1 contained contains=@ocamlAllErrs,ocamlComment,ocamlModParam,ocamlModTypeRestr,ocamlModTRWith nextgroup=ocamlModPreRHS
+syn region   ocamlModParam start="([^*]" end=")" contained contains=@ocamlAENoParen,ocamlModParam1
+syn match    ocamlModParam1 "\<\u\(\w\|'\)*\>" contained skipwhite skipempty nextgroup=ocamlPreMPRestr
+
+syn region   ocamlPreMPRestr start="."me=e-1 end=")"me=e-1 contained contains=@ocamlAllErrs,ocamlComment,ocamlMPRestr,ocamlModTypeRestr
+
+syn region   ocamlMPRestr start=":" end="."me=e-1 contained contains=@ocamlComment skipwhite skipempty nextgroup=ocamlMPRestr1,ocamlMPRestr2,ocamlMPRestr3
+syn region   ocamlMPRestr1 matchgroup=ocamlModule start="\ssig\s\=" matchgroup=ocamlModule end="\<end\>" contained contains=ALLBUT,@ocamlContained,ocamlEndErr,ocamlModule
+syn region   ocamlMPRestr2 start="\sfunctor\(\s\|(\)\="me=e-1 matchgroup=ocamlKeyword end="->" contained contains=@ocamlAllErrs,ocamlComment,ocamlModParam skipwhite skipempty nextgroup=ocamlFuncWith,ocamlMPRestr2
+syn match    ocamlMPRestr3 "\w\(\w\|'\)*\(\.\w\(\w\|'\)*\)*" contained
+syn match    ocamlModPreRHS "=" contained skipwhite skipempty nextgroup=ocamlModParam,ocamlFullMod
+syn region   ocamlModRHS start="." end=".\w\|([^*]"me=e-2 contained contains=ocamlComment skipwhite skipempty nextgroup=ocamlModParam,ocamlFullMod
+syn match    ocamlFullMod "\<\u\(\w\|'\)*\(\.\u\(\w\|'\)*\)*" contained skipwhite skipempty nextgroup=ocamlFuncWith
+
+syn region   ocamlFuncWith start="([^*]"me=e-1 end=")" contained contains=ocamlComment,ocamlWith,ocamlFuncStruct skipwhite skipempty nextgroup=ocamlFuncWith
+syn region   ocamlFuncStruct matchgroup=ocamlModule start="[^a-zA-Z]struct\>"hs=s+1 matchgroup=ocamlModule end="\<end\>" contains=ALLBUT,@ocamlContained,ocamlEndErr
+
+syn match    ocamlModTypeRestr "\<\w\(\w\|'\)*\(\.\w\(\w\|'\)*\)*\>" contained
+syn region   ocamlModTRWith start=":\s*("hs=s+1 end=")" contained contains=@ocamlAENoParen,ocamlWith
+syn match    ocamlWith "\<\(\u\(\w\|'\)*\.\)*\w\(\w\|'\)*\>" contained skipwhite skipempty nextgroup=ocamlWithRest
+syn region   ocamlWithRest start="[^)]" end=")"me=e-1 contained contains=ALLBUT,@ocamlContained
+
+" "module type"
+syn region   ocamlKeyword start="\<module\>\s*\<type\>" matchgroup=ocamlModule end="\<\w\(\w\|'\)*\>" contains=ocamlComment skipwhite skipempty nextgroup=ocamlMTDef
+syn match    ocamlMTDef "=\s*\w\(\w\|'\)*\>"hs=s+1,me=s
+
+syn keyword  ocamlKeyword  and as assert class
+syn keyword  ocamlKeyword  constraint else
+syn keyword  ocamlKeyword  exception external fun
+
+syn keyword  ocamlKeyword  in inherit initializer
+syn keyword  ocamlKeyword  land lazy let match
+syn keyword  ocamlKeyword  method mutable new of
+syn keyword  ocamlKeyword  parser private raise rec
+syn keyword  ocamlKeyword  try type
+syn keyword  ocamlKeyword  val virtual when while with
+
+if exists("ocaml_revised")
+  syn keyword  ocamlKeyword  do value
+  syn keyword  ocamlBoolean  True False
+else
+  syn keyword  ocamlKeyword  function
+  syn keyword  ocamlBoolean  true false
+  syn match    ocamlKeyChar  "!"
+endif
+
+syn keyword  ocamlType     array bool char exn float format format4
+syn keyword  ocamlType     int int32 int64 lazy_t list nativeint option
+syn keyword  ocamlType     string unit
+
+syn keyword  ocamlOperator asr lor lsl lsr lxor mod not
+
+syn match    ocamlConstructor  "(\s*)"
+syn match    ocamlConstructor  "\[\s*\]"
+syn match    ocamlConstructor  "\[|\s*>|]"
+syn match    ocamlConstructor  "\[<\s*>\]"
+syn match    ocamlConstructor  "\u\(\w\|'\)*\>"
+
+" Polymorphic variants
+syn match    ocamlConstructor  "`\w\(\w\|'\)*\>"
+
+" Module prefix
+syn match    ocamlModPath      "\u\(\w\|'\)*\."he=e-1
+
+syn match    ocamlCharacter    "'\\\d\d\d'\|'\\[\'ntbr]'\|'.'"
+syn match    ocamlCharErr      "'\\\d\d'\|'\\\d'"
+syn match    ocamlCharErr      "'\\[^\'ntbr]'"
+syn region   ocamlString       start=+"+ skip=+\\\\\|\\"+ end=+"+
+
+syn match    ocamlFunDef       "->"
+syn match    ocamlRefAssign    ":="
+syn match    ocamlTopStop      ";;"
+syn match    ocamlOperator     "\^"
+syn match    ocamlOperator     "::"
+
+syn match    ocamlOperator     "&&"
+syn match    ocamlOperator     "<"
+syn match    ocamlOperator     ">"
+syn match    ocamlAnyVar       "\<_\>"
+syn match    ocamlKeyChar      "|[^\]]"me=e-1
+syn match    ocamlKeyChar      ";"
+syn match    ocamlKeyChar      "\~"
+syn match    ocamlKeyChar      "?"
+syn match    ocamlKeyChar      "\*"
+syn match    ocamlKeyChar      "="
+
+if exists("ocaml_revised")
+  syn match    ocamlErr        "<-"
+else
+  syn match    ocamlOperator   "<-"
+endif
+
+syn match    ocamlNumber        "\<-\=\d\(_\|\d\)*[l|L|n]\?\>"
+syn match    ocamlNumber        "\<-\=0[x|X]\(\x\|_\)\+[l|L|n]\?\>"
+syn match    ocamlNumber        "\<-\=0[o|O]\(\o\|_\)\+[l|L|n]\?\>"
+syn match    ocamlNumber        "\<-\=0[b|B]\([01]\|_\)\+[l|L|n]\?\>"
+syn match    ocamlFloat         "\<-\=\d\(_\|\d\)*\.\(_\|\d\)*\([eE][-+]\=\d\(_\|\d\)*\)\=\>"
+
+" Labels
+syn match    ocamlLabel        "\~\(\l\|_\)\(\w\|'\)*"lc=1
+syn match    ocamlLabel        "?\(\l\|_\)\(\w\|'\)*"lc=1
+syn region   ocamlLabel transparent matchgroup=ocamlLabel start="?(\(\l\|_\)\(\w\|'\)*"lc=2 end=")"me=e-1 contains=ALLBUT,@ocamlContained,ocamlParenErr
+
+
+" Synchronization
+syn sync minlines=50
+syn sync maxlines=500
+
+if !exists("ocaml_revised")
+  syn sync match ocamlDoSync      grouphere  ocamlDo      "\<do\>"
+  syn sync match ocamlDoSync      groupthere ocamlDo      "\<done\>"
+endif
+
+if exists("ocaml_revised")
+  syn sync match ocamlEndSync     grouphere  ocamlEnd     "\<\(object\)\>"
+else
+  syn sync match ocamlEndSync     grouphere  ocamlEnd     "\<\(begin\|object\)\>"
+endif
+
+syn sync match ocamlEndSync     groupthere ocamlEnd     "\<end\>"
+syn sync match ocamlStructSync  grouphere  ocamlStruct  "\<struct\>"
+syn sync match ocamlStructSync  groupthere ocamlStruct  "\<end\>"
+syn sync match ocamlSigSync     grouphere  ocamlSig     "\<sig\>"
+syn sync match ocamlSigSync     groupthere ocamlSig     "\<end\>"
+
+" Define the default highlighting.
+" For version 5.7 and earlier: only when not done already
+" For version 5.8 and later: only when an item doesn't have highlighting yet
+if version >= 508 || !exists("did_ocaml_syntax_inits")
+  if version < 508
+    let did_ocaml_syntax_inits = 1
+    command -nargs=+ HiLink hi link <args>
+  else
+    command -nargs=+ HiLink hi def link <args>
+  endif
+
+  HiLink ocamlBraceErr	   Error
+  HiLink ocamlBrackErr	   Error
+  HiLink ocamlParenErr	   Error
+  HiLink ocamlArrErr	   Error
+
+  HiLink ocamlCommentErr   Error
+
+  HiLink ocamlCountErr	   Error
+  HiLink ocamlDoErr	   Error
+  HiLink ocamlDoneErr	   Error
+  HiLink ocamlEndErr	   Error
+  HiLink ocamlThenErr	   Error
+
+  HiLink ocamlCharErr	   Error
+
+  HiLink ocamlErr	   Error
+
+  HiLink ocamlComment	   Comment
+
+  HiLink ocamlModPath	   Include
+  HiLink ocamlObject	   Include
+  HiLink ocamlModule	   Include
+  HiLink ocamlModParam1    Include
+  HiLink ocamlModType	   Include
+  HiLink ocamlMPRestr3	   Include
+  HiLink ocamlFullMod	   Include
+  HiLink ocamlModTypeRestr Include
+  HiLink ocamlWith	   Include
+  HiLink ocamlMTDef	   Include
+
+  HiLink ocamlScript	   Include
+
+  HiLink ocamlConstructor  Constant
+
+  HiLink ocamlModPreRHS    Keyword
+  HiLink ocamlMPRestr2	   Keyword
+  HiLink ocamlKeyword	   Keyword
+  HiLink ocamlMethod	   Include
+  HiLink ocamlFunDef	   Keyword
+  HiLink ocamlRefAssign    Keyword
+  HiLink ocamlKeyChar	   Keyword
+  HiLink ocamlAnyVar	   Keyword
+  HiLink ocamlTopStop	   Keyword
+  HiLink ocamlOperator	   Keyword
+
+  HiLink ocamlBoolean	   Boolean
+  HiLink ocamlCharacter    Character
+  HiLink ocamlNumber	   Number
+  HiLink ocamlFloat	   Float
+  HiLink ocamlString	   String
+
+  HiLink ocamlLabel	   Identifier
+
+  HiLink ocamlType	   Type
+
+  HiLink ocamlTodo	   Todo
+
+  HiLink ocamlEncl	   Keyword
+
+  delcommand HiLink
+endif
+
+let b:current_syntax = "ocaml"
+
+" vim: ts=8
--- /dev/null
+++ b/lib/vimfiles/syntax/occam.vim
@@ -1,0 +1,126 @@
+" Vim syntax file
+" Language:	occam
+" Copyright:	Fred Barnes <frmb2@kent.ac.uk>, Mario Schweigler <ms44@kent.ac.uk>
+" Maintainer:	Mario Schweigler <ms44@kent.ac.uk>
+" Last Change:	24 May 2003
+
+if version < 600
+  syntax clear
+elseif exists("b:current_syntax")
+  finish
+endif
+
+"{{{  Settings
+" Set shift width for indent
+setlocal shiftwidth=2
+" Set the tab key size to two spaces
+setlocal softtabstop=2
+" Let tab keys always be expanded to spaces
+setlocal expandtab
+
+" Dots are valid in occam identifiers
+setlocal iskeyword+=.
+"}}}
+
+syn case match
+
+syn keyword occamType		BYTE BOOL INT INT16 INT32 INT64 REAL32 REAL64 ANY
+syn keyword occamType		CHAN DATA OF TYPE TIMER INITIAL VAL PORT MOBILE PLACED
+syn keyword occamType		PROCESSOR PACKED RECORD PROTOCOL SHARED ROUND TRUNC
+
+syn keyword occamStructure	SEQ PAR IF ALT PRI FORKING PLACE AT
+
+syn keyword occamKeyword	PROC IS TRUE FALSE SIZE RECURSIVE REC
+syn keyword occamKeyword	RETYPES RESHAPES STEP FROM FOR RESCHEDULE STOP SKIP FORK
+syn keyword occamKeyword	FUNCTION VALOF RESULT ELSE CLONE CLAIM
+syn keyword occamBoolean	TRUE FALSE
+syn keyword occamRepeat		WHILE
+syn keyword occamConditional	CASE
+syn keyword occamConstant	MOSTNEG MOSTPOS
+
+syn match occamBrackets		/\[\|\]/
+syn match occamParantheses	/(\|)/
+
+syn keyword occamOperator	AFTER TIMES MINUS PLUS INITIAL REM AND OR XOR NOT
+syn keyword occamOperator	BITAND BITOR BITNOT BYTESIN OFFSETOF
+
+syn match occamOperator		/::\|:=\|?\|!/
+syn match occamOperator		/<\|>\|+\|-\|\*\|\/\|\\\|=\|\~/
+syn match occamOperator		/@\|\$\$\|%\|&&\|<&\|&>\|<\]\|\[>\|\^/
+
+syn match occamSpecialChar	/\M**\|*'\|*"\|*#\(\[0-9A-F\]\+\)/ contained
+syn match occamChar		/\M\L\='\[^*\]'/
+syn match occamChar		/L'[^']*'/ contains=occamSpecialChar
+
+syn case ignore
+syn match occamTodo		/\<todo\>:\=/ contained
+syn match occamNote		/\<note\>:\=/ contained
+syn case match
+syn keyword occamNote		NOT contained
+
+syn match occamComment		/--.*/ contains=occamCommentTitle,occamTodo,occamNote
+syn match occamCommentTitle	/--\s*\u\a*\(\s\+\u\a*\)*:/hs=s+2 contained contains=occamTodo,occamNote
+syn match occamCommentTitle	/--\s*KROC-LIBRARY\(\.so\|\.a\)\=\s*$/hs=s+2 contained
+syn match occamCommentTitle	/--\s*\(KROC-OPTIONS:\|RUN-PARAMETERS:\)/hs=s+2 contained
+
+syn match occamIdentifier	/\<[A-Z.][A-Z.0-9]*\>/
+syn match occamFunction		/\<[A-Za-z.][A-Za-z0-9.]*\>/ contained
+
+syn match occamPPIdentifier	/##.\{-}\>/
+
+syn region occamString		start=/"/ skip=/\M*"/ end=/"/ contains=occamSpecialChar
+syn region occamCharString	start=/'/ end=/'/ contains=occamSpecialChar
+
+syn match occamNumber		/\<\d\+\(\.\d\+\(E\(+\|-\)\d\+\)\=\)\=/
+syn match occamNumber		/-\d\+\(\.\d\+\(E\(+\|-\)\d\+\)\=\)\=/
+syn match occamNumber		/#\(\d\|[A-F]\)\+/
+syn match occamNumber		/-#\(\d\|[A-F]\)\+/
+
+syn keyword occamCDString	SHARED EXTERNAL DEFINED NOALIAS NOUSAGE NOT contained
+syn keyword occamCDString	FILE LINE PROCESS.PRIORITY OCCAM2.5 contained
+syn keyword occamCDString	USER.DEFINED.OPERATORS INITIAL.DECL MOBILES contained
+syn keyword occamCDString	BLOCKING.SYSCALLS VERSION NEED.QUAD.ALIGNMENT contained
+syn keyword occamCDString	TARGET.CANONICAL TARGET.CPU TARGET.OS TARGET.VENDOR contained
+syn keyword occamCDString	TRUE FALSE AND OR contained
+syn match occamCDString		/<\|>\|=\|(\|)/ contained
+
+syn region occamCDirective	start=/#\(USE\|INCLUDE\|PRAGMA\|DEFINE\|UNDEFINE\|UNDEF\|IF\|ELIF\|ELSE\|ENDIF\|WARNING\|ERROR\|RELAX\)\>/ end=/$/ contains=occamString,occamComment,occamCDString
+
+if version >= 508 || !exists("did_occam_syn_inits")
+  if version < 508
+    let did_occam_syntax_inits = 1
+    command -nargs=+ HiLink hi link <args>
+  else
+    command -nargs=+ HiLink hi def link <args>
+  endif
+
+  HiLink occamType Type
+  HiLink occamKeyword Keyword
+  HiLink occamComment Comment
+  HiLink occamCommentTitle PreProc
+  HiLink occamTodo Todo
+  HiLink occamNote Todo
+  HiLink occamString String
+  HiLink occamCharString String
+  HiLink occamNumber Number
+  HiLink occamCDirective PreProc
+  HiLink occamCDString String
+  HiLink occamPPIdentifier PreProc
+  HiLink occamBoolean Boolean
+  HiLink occamSpecialChar SpecialChar
+  HiLink occamChar Character
+  HiLink occamStructure Structure
+  HiLink occamIdentifier Identifier
+  HiLink occamConstant Constant
+  HiLink occamOperator Operator
+  HiLink occamFunction Ignore
+  HiLink occamRepeat Repeat
+  HiLink occamConditional Conditional
+  HiLink occamBrackets Type
+  HiLink occamParantheses Delimiter
+
+  delcommand HiLink
+endif
+
+let b:current_syntax = "occam"
+
--- /dev/null
+++ b/lib/vimfiles/syntax/omnimark.vim
@@ -1,0 +1,123 @@
+" Vim syntax file
+" Language:	Omnimark
+" Maintainer:	Paul Terray <mailto:terray@4dconcept.fr>
+" Last Change:	11 Oct 2000
+
+" For version 5.x: Clear all syntax items
+" For version 6.x: Quit when a syntax file was already loaded
+if version < 600
+  syntax clear
+elseif exists("b:current_syntax")
+  finish
+endif
+
+if version < 600
+  set iskeyword=@,48-57,_,128-167,224-235,-
+else
+  setlocal iskeyword=@,48-57,_,128-167,224-235,-
+endif
+
+syn keyword omnimarkKeywords	ACTIVATE AGAIN
+syn keyword omnimarkKeywords	CATCH CLEAR CLOSE COPY COPY-CLEAR CROSS-TRANSLATE
+syn keyword omnimarkKeywords	DEACTIVATE DECLARE DECREMENT DEFINE DISCARD DIVIDE DO DOCUMENT-END DOCUMENT-START DONE DTD-START
+syn keyword omnimarkKeywords	ELEMENT ELSE ESCAPE EXIT
+syn keyword omnimarkKeywords	FAIL FIND FIND-END FIND-START FORMAT
+syn keyword omnimarkKeywords	GROUP
+syn keyword omnimarkKeywords	HALT HALT-EVERYTHING
+syn keyword omnimarkKeywords	IGNORE IMPLIED INCLUDE INCLUDE-END INCLUDE-START INCREMENT INPUT
+syn keyword omnimarkKeywords	JOIN
+syn keyword omnimarkKeywords	LINE-END LINE-START LOG LOOKAHEAD
+syn keyword omnimarkKeywords	MACRO
+syn keyword omnimarkKeywords	MACRO-END MARKED-SECTION MARKUP-COMMENT MARKUP-ERROR MARKUP-PARSER MASK MATCH MINUS MODULO
+syn keyword omnimarkKeywords	NEW NEWLINE NEXT
+syn keyword omnimarkKeywords	OPEN OUTPUT OUTPUT-TO OVER
+syn keyword omnimarkKeywords	PROCESS PROCESS-END PROCESS-START PROCESSING-INSTRUCTION PROLOG-END PROLOG-IN-ERROR PUT
+syn keyword omnimarkKeywords	REMOVE REOPEN REPEAT RESET RETHROW RETURN
+syn keyword omnimarkKeywords	WHEN WHITE-SPACE
+syn keyword omnimarkKeywords	SAVE SAVE-CLEAR SCAN SELECT SET SGML SGML-COMMENT SGML-DECLARATION-END SGML-DTD SGML-DTDS SGML-ERROR SGML-IN SGML-OUT SGML-PARSE SGML-PARSER SHIFT SUBMIT SUCCEED SUPPRESS
+syn keyword omnimarkKeywords	SYSTEM-CALL
+syn keyword omnimarkKeywords	TEST-SYSTEM THROW TO TRANSLATE
+syn keyword omnimarkKeywords	UC UL UNLESS UP-TRANSLATE
+syn keyword omnimarkKeywords	XML-PARSE
+
+syn keyword omnimarkCommands	ACTIVE AFTER ANCESTOR AND ANOTHER ARG AS ATTACHED ATTRIBUTE ATTRIBUTES
+syn keyword omnimarkCommands	BASE BEFORE BINARY BINARY-INPUT BINARY-MODE BINARY-OUTPUT BREAK-WIDTH BUFFER BY
+syn keyword omnimarkCommands	CASE CHILDREN CLOSED COMPILED-DATE COMPLEMENT CONREF CONTENT CONTEXT-TRANSLATE COUNTER CREATED CREATING CREATOR CURRENT
+syn keyword omnimarkCommands	DATA-ATTRIBUTE DATA-ATTRIBUTES DATA-CONTENT DATA-LETTERS DATE DECLARED-CONREF DECLARED-CURRENT DECLARED-DEFAULTED DECLARED-FIXED DECLARED-IMPLIED DECLARED-REQUIRED
+syn keyword omnimarkCommands	DEFAULT-ENTITY DEFAULTED DEFAULTING DELIMITER DIFFERENCE DIRECTORY DOCTYPE DOCUMENT DOCUMENT-ELEMENT DOMAIN-FREE DOWN-TRANSLATE DTD DTD-END DTDS
+syn keyword omnimarkCommands	ELEMENTS ELSEWHERE EMPTY ENTITIES ENTITY EPILOG-START EQUAL EXCEPT EXISTS EXTERNAL EXTERNAL-DATA-ENTITY EXTERNAL-ENTITY EXTERNAL-FUNCTION EXTERNAL-OUTPUT-FUNCTION
+syn keyword omnimarkCommands	EXTERNAL-TEXT-ENTITY
+syn keyword omnimarkCommands	FALSE FILE FUNCTION FUNCTION-LIBRARY
+syn keyword omnimarkCommands	GENERAL GLOBAL GREATER-EQUAL GREATER-THAN GROUPS
+syn keyword omnimarkCommands	HAS HASNT HERALDED-NAMES
+syn keyword omnimarkCommands	ID ID-CHECKING IDREF IDREFS IN IN-LIBRARY INCLUSION INITIAL INITIAL-SIZE INSERTION-BREAK INSTANCE INTERNAL INVALID-DATA IS ISNT ITEM
+syn keyword omnimarkCommands	KEY KEYED
+syn keyword omnimarkCommands	LAST LASTMOST LC LENGTH LESS-EQUAL LESS-THAN LETTERS LIBRARY LITERAL LOCAL
+syn keyword omnimarkCommands	MATCHES MIXED MODIFIABLE
+syn keyword omnimarkCommands	NAME NAME-LETTERS NAMECASE NAMED NAMES NDATA-ENTITY NEGATE NESTED-REFERENTS NMTOKEN NMTOKENS NO NO-DEFAULT-IO NON-CDATA NON-IMPLIED NON-SDATA NOT NOTATION NUMBER-OF NUMBERS
+syn keyword omnimarkCommands	NUTOKEN NUTOKENS
+syn keyword omnimarkCommands	OCCURRENCE OF OPAQUE OPTIONAL OR
+syn keyword omnimarkCommands	PARAMETER PARENT PAST PATTERN PLUS PREPARENT PREVIOUS PROPER PUBLIC
+syn keyword omnimarkCommands	READ-ONLY READABLE REFERENT REFERENTS REFERENTS-ALLOWED REFERENTS-DISPLAYED REFERENTS-NOT-ALLOWED REMAINDER REPEATED REPLACEMENT-BREAK REVERSED
+syn keyword omnimarkCommands	SILENT-REFERENT SIZE SKIP SOURCE SPECIFIED STATUS STREAM SUBDOC-ENTITY SUBDOCUMENT SUBDOCUMENTS SUBELEMENT SWITCH SYMBOL SYSTEM
+syn keyword omnimarkCommands	TEXT-MODE THIS TIMES TOKEN TRUE
+syn keyword omnimarkCommands	UNANCHORED UNATTACHED UNION USEMAP USING
+syn keyword omnimarkCommands	VALUE VALUED VARIABLE
+syn keyword omnimarkCommands	WITH WRITABLE
+syn keyword omnimarkCommands	XML XML-DTD XML-DTDS
+syn keyword omnimarkCommands	YES
+syn keyword omnimarkCommands	#ADDITIONAL-INFO #APPINFO #CAPACITY #CHARSET #CLASS #COMMAND-LINE-NAMES #CONSOLE #CURRENT-INPUT #CURRENT-OUTPUT #DATA #DOCTYPE #DOCUMENT #DTD #EMPTY #ERROR #ERROR-CODE
+syn keyword omnimarkCommands	#FILE-NAME #FIRST #GROUP #IMPLIED #ITEM #LANGUAGE-VERSION #LAST #LIBPATH #LIBRARY #LIBVALUE #LINE-NUMBER #MAIN-INPUT #MAIN-OUTPUT #MARKUP-ERROR-COUNT #MARKUP-ERROR-TOTAL
+syn keyword omnimarkCommands	#MARKUP-PARSER #MARKUP-WARNING-COUNT #MARKUP-WARNING-TOTAL #MESSAGE #NONE #OUTPUT #PLATFORM-INFO #PROCESS-INPUT #PROCESS-OUTPUT #RECOVERY-INFO #SGML #SGML-ERROR-COUNT
+syn keyword omnimarkCommands	#SGML-ERROR-TOTAL #SGML-WARNING-COUNT #SGML-WARNING-TOTAL #SUPPRESS #SYNTAX #!
+
+syn keyword omnimarkPatterns	ANY ANY-TEXT
+syn keyword omnimarkPatterns	BLANK
+syn keyword omnimarkPatterns	CDATA CDATA-ENTITY CONTENT-END CONTENT-START
+syn keyword omnimarkPatterns	DIGIT
+syn keyword omnimarkPatterns	LETTER
+syn keyword omnimarkPatterns	NUMBER
+syn keyword omnimarkPatterns	PCDATA
+syn keyword omnimarkPatterns	RCDATA
+syn keyword omnimarkPatterns	SDATA SDATA-ENTITY SPACE
+syn keyword omnimarkPatterns	TEXT
+syn keyword omnimarkPatterns	VALUE-END VALUE-START
+syn keyword omnimarkPatterns	WORD-END WORD-START
+
+syn region  omnimarkComment	start=";" end="$"
+
+" strings
+syn region  omnimarkString		matchgroup=Normal start=+'+  end=+'+ skip=+%'+ contains=omnimarkEscape
+syn region  omnimarkString		matchgroup=Normal start=+"+  end=+"+ skip=+%"+ contains=omnimarkEscape
+syn match  omnimarkEscape contained +%.+
+syn match  omnimarkEscape contained +%[0-9][0-9]#+
+
+"syn sync maxlines=100
+syn sync minlines=2000
+
+" Define the default highlighting.
+" For version 5.7 and earlier: only when not done already
+" For version 5.8 and later: only when an item doesn't have highlighting yet
+if version >= 508 || !exists("did_omnimark_syntax_inits")
+  if version < 508
+    let did_omnimark_syntax_inits = 1
+    command -nargs=+ HiLink hi link <args>
+  else
+    command -nargs=+ HiLink hi def link <args>
+  endif
+
+  HiLink omnimarkCommands		Statement
+  HiLink omnimarkKeywords		Identifier
+  HiLink omnimarkString		String
+  HiLink omnimarkPatterns		Macro
+"  HiLink omnimarkNumber			Number
+  HiLink omnimarkComment		Comment
+  HiLink omnimarkEscape		Special
+
+  delcommand HiLink
+endif
+
+let b:current_syntax = "omnimark"
+
+" vim: ts=8
+
--- /dev/null
+++ b/lib/vimfiles/syntax/openroad.vim
@@ -1,0 +1,266 @@
+" Vim syntax file
+" Language:		CA-OpenROAD
+" Maintainer:	Luis Moreno <lmoreno@eresmas.net>
+" Last change:	2001 Jun 12
+
+" For version 5.x: Clear all syntax items
+" For version 6.x: Quit when a syntax file was already loaded
+"
+if version < 600
+	syntax clear
+elseif exists("b:current_syntax")
+	finish
+endif
+
+syntax case ignore
+
+" Keywords
+"
+syntax keyword openroadKeyword	ABORT ALL ALTER AND ANY AS ASC AT AVG BEGIN
+syntax keyword openroadKeyword	BETWEEN BY BYREF CALL CALLFRAME CALLPROC CASE
+syntax keyword openroadKeyword	CLEAR CLOSE COMMIT CONNECT CONTINUE COPY COUNT
+syntax keyword openroadKeyword	CREATE CURRENT DBEVENT DECLARE DEFAULT DELETE
+syntax keyword openroadKeyword	DELETEROW DESC DIRECT DISCONNECT DISTINCT DO
+syntax keyword openroadKeyword	DROP ELSE ELSEIF END ENDCASE ENDDECLARE ENDFOR
+syntax keyword openroadKeyword	ENDIF ENDLOOP ENDWHILE ESCAPE EXECUTE EXISTS
+syntax keyword openroadKeyword	EXIT FETCH FIELD FOR FROM GOTOFRAME GRANT GROUP
+syntax keyword openroadKeyword	HAVING IF IMMEDIATE IN INDEX INITIALISE
+syntax keyword openroadKeyword	INITIALIZE INQUIRE_INGRES INQUIRE_SQL INSERT
+syntax keyword openroadKeyword	INSERTROW INSTALLATION INTEGRITY INTO KEY LIKE
+syntax keyword openroadKeyword	LINK MAX MESSAGE METHOD MIN MODE MODIFY NEXT
+syntax keyword openroadKeyword	NOECHO NOT NULL OF ON OPEN OPENFRAME OR ORDER
+syntax keyword openroadKeyword	PERMIT PROCEDURE PROMPT QUALIFICATION RAISE
+syntax keyword openroadKeyword	REGISTER RELOCATE REMOVE REPEAT REPEATED RESUME
+syntax keyword openroadKeyword	RETURN RETURNING REVOKE ROLE ROLLBACK RULE SAVE
+syntax keyword openroadKeyword	SAVEPOINT SELECT SET SLEEP SOME SUM SYSTEM TABLE
+syntax keyword openroadKeyword	THEN TO TRANSACTION UNION UNIQUE UNTIL UPDATE
+syntax keyword openroadKeyword	VALUES VIEW WHERE WHILE WITH WORK
+
+syntax keyword openroadTodo contained	TODO
+
+" Catch errors caused by wrong parenthesis
+"
+syntax cluster	openroadParenGroup	contains=openroadParenError,openroadTodo
+syntax region	openroadParen		transparent start='(' end=')' contains=ALLBUT,@openroadParenGroup
+syntax match	openroadParenError	")"
+highlight link	openroadParenError	cError
+
+" Numbers
+"
+syntax match	openroadNumber		"\<[0-9]\+\>"
+
+" String
+"
+syntax region	openroadString		start=+'+  end=+'+
+
+" Operators, Data Types and Functions
+"
+syntax match	openroadOperator	/[\+\-\*\/=\<\>;\(\)]/
+
+syntax keyword	openroadType		ARRAY BYTE CHAR DATE DECIMAL FLOAT FLOAT4
+syntax keyword	openroadType		FLOAT8 INT1 INT2 INT4 INTEGER INTEGER1
+syntax keyword	openroadType		INTEGER2 INTEGER4 MONEY OBJECT_KEY
+syntax keyword	openroadType		SECURITY_LABEL SMALLINT TABLE_KEY VARCHAR
+
+syntax keyword	openroadFunc		IFNULL
+
+" System Classes
+"
+syntax keyword	openroadClass	ACTIVEFIELD ANALOGFIELD APPFLAG APPSOURCE
+syntax keyword	openroadClass	ARRAYOBJECT ATTRIBUTEOBJECT BARFIELD
+syntax keyword	openroadClass	BITMAPOBJECT BOXTRIM BREAKSPEC BUTTONFIELD
+syntax keyword	openroadClass	CELLATTRIBUTE CHOICEBITMAP CHOICEDETAIL
+syntax keyword	openroadClass	CHOICEFIELD CHOICEITEM CHOICELIST CLASS
+syntax keyword	openroadClass	CLASSSOURCE COLUMNCROSS COLUMNFIELD
+syntax keyword	openroadClass	COMPOSITEFIELD COMPSOURCE CONTROLBUTTON
+syntax keyword	openroadClass	CROSSTABLE CURSORBITMAP CURSOROBJECT DATASTREAM
+syntax keyword	openroadClass	DATEOBJECT DBEVENTOBJECT DBSESSIONOBJECT
+syntax keyword	openroadClass	DISPLAYFORM DYNEXPR ELLIPSESHAPE ENTRYFIELD
+syntax keyword	openroadClass	ENUMFIELD EVENT EXTOBJECT EXTOBJFIELD
+syntax keyword	openroadClass	FIELDOBJECT FLEXIBLEFORM FLOATOBJECT FORMFIELD
+syntax keyword	openroadClass	FRAMEEXEC FRAMEFORM FRAMESOURCE FREETRIM
+syntax keyword	openroadClass	GHOSTEXEC GHOSTSOURCE IMAGEFIELD IMAGETRIM
+syntax keyword	openroadClass	INTEGEROBJECT LISTFIELD LISTVIEWCOLATTR
+syntax keyword	openroadClass	LISTVIEWFIELD LONGBYTEOBJECT LONGVCHAROBJECT
+syntax keyword	openroadClass	MATRIXFIELD MENUBAR MENUBUTTON MENUFIELD
+syntax keyword	openroadClass	MENUGROUP MENUITEM MENULIST MENUSEPARATOR
+syntax keyword	openroadClass	MENUSTACK MENUTOGGLE METHODEXEC METHODOBJECT
+syntax keyword	openroadClass	MONEYOBJECT OBJECT OPTIONFIELD OPTIONMENU
+syntax keyword	openroadClass	PALETTEFIELD POPUPBUTTON PROC4GLSOURCE PROCEXEC
+syntax keyword	openroadClass	PROCHANDLE QUERYCOL QUERYOBJECT QUERYPARM
+syntax keyword	openroadClass	QUERYTABLE RADIOFIELD RECTANGLESHAPE ROWCROSS
+syntax keyword	openroadClass	SCALARFIELD SCOPE SCROLLBARFIELD SEGMENTSHAPE
+syntax keyword	openroadClass	SESSIONOBJECT SHAPEFIELD SLIDERFIELD SQLSELECT
+syntax keyword	openroadClass	STACKFIELD STRINGOBJECT SUBFORM TABBAR
+syntax keyword	openroadClass	TABFIELD TABFOLDER TABLEFIELD TABPAGE
+syntax keyword	openroadClass	TOGGLEFIELD TREE TREENODE TREEVIEWFIELD
+syntax keyword	openroadClass	USERCLASSOBJECT USEROBJECT VIEWPORTFIELD
+
+" System Events
+"
+syntax keyword	openroadEvent	CHILDCLICK CHILDCLICKPOINT CHILDCOLLAPSED
+syntax keyword	openroadEvent	CHILDDETAILS CHILDDOUBLECLICK CHILDDRAGBOX
+syntax keyword	openroadEvent	CHILDDRAGSEGMENT CHILDENTRY CHILDEXIT
+syntax keyword	openroadEvent	CHILDEXPANDED CHILDHEADERCLICK CHILDMOVED
+syntax keyword	openroadEvent	CHILDPROPERTIES CHILDRESIZED CHILDSCROLL
+syntax keyword	openroadEvent	CHILDSELECT CHILDSELECTIONCHANGED CHILDSETVALUE
+syntax keyword	openroadEvent	CHILDUNSELECT CHILDVALIDATE CLICK CLICKPOINT
+syntax keyword	openroadEvent	COLLAPSED DBEVENT DETAILS DOUBLECLICK DRAGBOX
+syntax keyword	openroadEvent	DRAGSEGMENT ENTRY EXIT EXPANDED EXTCLASSEVENT
+syntax keyword	openroadEvent	FRAMEACTIVATE FRAMEDEACTIVATE HEADERCLICK
+syntax keyword	openroadEvent	INSERTROW LABELCHANGED MOVED PAGEACTIVATED
+syntax keyword	openroadEvent	PAGECHANGED PAGEDEACTIVATED PROPERTIES RESIZED
+syntax keyword	openroadEvent	SCROLL SELECT SELECTIONCHANGED SETVALUE
+syntax keyword	openroadEvent	TERMINATE UNSELECT USEREVENT VALIDATE
+syntax keyword	openroadEvent	WINDOWCLOSE WINDOWICON WINDOWMOVED WINDOWRESIZED
+syntax keyword	openroadEvent	WINDOWVISIBLE
+
+" System Constants
+"
+syntax keyword	openroadConst	BF_BMP BF_GIF BF_SUNRASTER BF_TIFF
+syntax keyword	openroadConst	BF_WINDOWCURSOR BF_WINDOWICON BF_XBM
+syntax keyword	openroadConst	CC_BACKGROUND CC_BLACK CC_BLUE CC_BROWN CC_CYAN
+syntax keyword	openroadConst	CC_DEFAULT_1 CC_DEFAULT_10 CC_DEFAULT_11
+syntax keyword	openroadConst	CC_DEFAULT_12 CC_DEFAULT_13 CC_DEFAULT_14
+syntax keyword	openroadConst	CC_DEFAULT_15 CC_DEFAULT_16 CC_DEFAULT_17
+syntax keyword	openroadConst	CC_DEFAULT_18 CC_DEFAULT_19 CC_DEFAULT_2
+syntax keyword	openroadConst	CC_DEFAULT_20 CC_DEFAULT_21 CC_DEFAULT_22
+syntax keyword	openroadConst	CC_DEFAULT_23 CC_DEFAULT_24 CC_DEFAULT_25
+syntax keyword	openroadConst	CC_DEFAULT_26 CC_DEFAULT_27 CC_DEFAULT_28
+syntax keyword	openroadConst	CC_DEFAULT_29 CC_DEFAULT_3 CC_DEFAULT_30
+syntax keyword	openroadConst	CC_DEFAULT_4 CC_DEFAULT_5 CC_DEFAULT_6
+syntax keyword	openroadConst	CC_DEFAULT_7 CC_DEFAULT_8 CC_DEFAULT_9
+syntax keyword	openroadConst	CC_FOREGROUND CC_GRAY CC_GREEN CC_LIGHT_BLUE
+syntax keyword	openroadConst	CC_LIGHT_BROWN	CC_LIGHT_CYAN CC_LIGHT_GRAY
+syntax keyword	openroadConst	CC_LIGHT_GREEN CC_LIGHT_ORANGE CC_LIGHT_PINK
+syntax keyword	openroadConst	CC_LIGHT_PURPLE CC_LIGHT_RED CC_LIGHT_YELLOW
+syntax keyword	openroadConst	CC_MAGENTA CC_ORANGE CC_PALE_BLUE CC_PALE_BROWN
+syntax keyword	openroadConst	CC_PALE_CYAN CC_PALE_GRAY CC_PALE_GREEN
+syntax keyword	openroadConst	CC_PALE_ORANGE CC_PALE_PINK CC_PALE_PURPLE
+syntax keyword	openroadConst	CC_PALE_RED CC_PALE_YELLOW CC_PINK CC_PURPLE
+syntax keyword	openroadConst	CC_RED CC_SYS_ACTIVEBORDER CC_SYS_ACTIVECAPTION
+syntax keyword	openroadConst	CC_SYS_APPWORKSPACE CC_SYS_BACKGROUND
+syntax keyword	openroadConst	CC_SYS_BTNFACE CC_SYS_BTNSHADOW CC_SYS_BTNTEXT
+syntax keyword	openroadConst	CC_SYS_CAPTIONTEXT CC_SYS_GRAYTEXT
+syntax keyword	openroadConst	CC_SYS_HIGHLIGHT CC_SYS_HIGHLIGHTTEXT
+syntax keyword	openroadConst	CC_SYS_INACTIVEBORDER CC_SYS_INACTIVECAPTION
+syntax keyword	openroadConst	CC_SYS_INACTIVECAPTIONTEXT CC_SYS_MENU
+syntax keyword	openroadConst	CC_SYS_MENUTEXT CC_SYS_SCROLLBAR CC_SYS_SHADOW
+syntax keyword	openroadConst	CC_SYS_WINDOW CC_SYS_WINDOWFRAME
+syntax keyword	openroadConst	CC_SYS_WINDOWTEXT CC_WHITE CC_YELLOW
+syntax keyword	openroadConst	CL_INVALIDVALUE CP_BOTH CP_COLUMNS CP_NONE
+syntax keyword	openroadConst	CP_ROWS CS_CLOSED CS_CURRENT CS_NOCURRENT
+syntax keyword	openroadConst	CS_NO_MORE_ROWS CS_OPEN CS_OPEN_CACHED DC_BW
+syntax keyword	openroadConst	DC_COLOR DP_AUTOSIZE_FIELD DP_CLIP_IMAGE
+syntax keyword	openroadConst	DP_SCALE_IMAGE_H DP_SCALE_IMAGE_HW
+syntax keyword	openroadConst	DP_SCALE_IMAGE_W DS_CONNECTED DS_DISABLED
+syntax keyword	openroadConst	DS_DISCONNECTED DS_INGRES_DBMS DS_NO_DBMS
+syntax keyword	openroadConst	DS_ORACLE_DBMS DS_SQLSERVER_DBMS DV_NULL
+syntax keyword	openroadConst	DV_STRING DV_SYSTEM EH_NEXT_HANDLER EH_RESUME
+syntax keyword	openroadConst	EH_RETRY EP_INTERACTIVE EP_NONE EP_OUTPUT
+syntax keyword	openroadConst	ER_FAIL ER_NAMEEXISTS ER_OK ER_OUTOFRANGE
+syntax keyword	openroadConst	ER_ROWNOTFOUND ER_USER1 ER_USER10 ER_USER2
+syntax keyword	openroadConst	ER_USER3 ER_USER4 ER_USER5 ER_USER6 ER_USER7
+syntax keyword	openroadConst	ER_USER8 ER_USER9 FALSE FA_BOTTOMCENTER
+syntax keyword	openroadConst	FA_BOTTOMLEFT FA_BOTTOMRIGHT FA_CENTER
+syntax keyword	openroadConst	FA_CENTERLEFT FA_CENTERRIGHT FA_DEFAULT FA_NONE
+syntax keyword	openroadConst	FA_TOPCENTER FA_TOPLEFT FA_TOPRIGHT
+syntax keyword	openroadConst	FB_CHANGEABLE FB_CLICKPOINT FB_DIMMED FB_DRAGBOX
+syntax keyword	openroadConst	FB_DRAGSEGMENT FB_FLEXIBLE FB_INVISIBLE
+syntax keyword	openroadConst	FB_LANDABLE FB_MARKABLE FB_RESIZEABLE
+syntax keyword	openroadConst	FB_VIEWABLE FB_VISIBLE FC_LOWER FC_NONE FC_UPPER
+syntax keyword	openroadConst	FM_QUERY FM_READ FM_UPDATE FM_USER1 FM_USER2
+syntax keyword	openroadConst	FM_USER3 FO_DEFAULT FO_HORIZONTAL FO_VERTICAL
+syntax keyword	openroadConst	FP_BITMAP FP_CLEAR FP_CROSSHATCH FP_DARKSHADE
+syntax keyword	openroadConst	FP_DEFAULT FP_HORIZONTAL FP_LIGHTSHADE FP_SHADE
+syntax keyword	openroadConst	FP_SOLID FP_VERTICAL FT_NOTSETVALUE FT_SETVALUE
+syntax keyword	openroadConst	FT_TABTO FT_TAKEFOCUS GF_BOTTOM GF_DEFAULT
+syntax keyword	openroadConst	GF_LEFT GF_RIGHT GF_TOP HC_DOUBLEQUOTE
+syntax keyword	openroadConst	HC_FORMFEED HC_NEWLINE HC_QUOTE HC_SPACE HC_TAB
+syntax keyword	openroadConst	HV_CONTENTS HV_CONTEXT HV_HELPONHELP HV_KEY
+syntax keyword	openroadConst	HV_QUIT LS_3D LS_DASH LS_DASHDOT LS_DASHDOTDOT
+syntax keyword	openroadConst	LS_DEFAULT LS_DOT LS_SOLID LW_DEFAULT
+syntax keyword	openroadConst	LW_EXTRATHIN LW_MAXIMUM LW_MIDDLE LW_MINIMUM
+syntax keyword	openroadConst	LW_NOLINE LW_THICK LW_THIN LW_VERYTHICK
+syntax keyword	openroadConst	LW_VERYTHIN MB_DISABLED MB_ENABLED MB_INVISIBLE
+syntax keyword	openroadConst	MB_MOVEABLE MT_ERROR MT_INFO MT_NONE MT_WARNING
+syntax keyword	openroadConst	OP_APPEND OP_NONE OS3D OS_DEFAULT OS_SHADOW
+syntax keyword	openroadConst	OS_SOLID PU_CANCEL PU_OK QS_ACTIVE QS_INACTIVE
+syntax keyword	openroadConst	QS_SETCOL QY_ARRAY QY_CACHE QY_CURSOR QY_DIRECT
+syntax keyword	openroadConst	RC_CHILDSELECTED RC_DOWN RC_END RC_FIELDFREED
+syntax keyword	openroadConst	RC_FIELDORPHANED RC_GROUPSELECT RC_HOME RC_LEFT
+syntax keyword	openroadConst	RC_MODECHANGED RC_MOUSECLICK RC_MOUSEDRAG
+syntax keyword	openroadConst	RC_NEXT RC_NOTAPPLICABLE RC_PAGEDOWN RC_PAGEUP
+syntax keyword	openroadConst	RC_PARENTSELECTED RC_PREVIOUS RC_PROGRAM
+syntax keyword	openroadConst	RC_RESUME RC_RETURN RC_RIGHT RC_ROWDELETED
+syntax keyword	openroadConst	RC_ROWINSERTED RC_ROWSALLDELETED RC_SELECT
+syntax keyword	openroadConst	RC_TFSCROLL RC_TOGGLESELECT RC_UP RS_CHANGED
+syntax keyword	openroadConst	RS_DELETED RS_NEW RS_UNCHANGED RS_UNDEFINED
+syntax keyword	openroadConst	SK_CLOSE SK_COPY SK_CUT SK_DELETE SK_DETAILS
+syntax keyword	openroadConst	SK_DUPLICATE SK_FIND SK_GO SK_HELP SK_NEXT
+syntax keyword	openroadConst	SK_NONE SK_PASTE SK_PROPS SK_QUIT SK_REDO
+syntax keyword	openroadConst	SK_SAVE SK_TFDELETEALLROWS SK_TFDELETEROW
+syntax keyword	openroadConst	SK_TFFIND SK_TFINSERTROW SK_UNDO SP_APPSTARTING
+syntax keyword	openroadConst	SP_ARROW SP_CROSS SP_IBEAM SP_ICON SP_NO
+syntax keyword	openroadConst	SP_SIZE SP_SIZENESW SP_SIZENS SP_SIZENWSE
+syntax keyword	openroadConst	SP_SIZEWE SP_UPARROW SP_WAIT SY_NT SY_OS2
+syntax keyword	openroadConst	SY_UNIX SY_VMS SY_WIN95 TF_COURIER TF_HELVETICA
+syntax keyword	openroadConst	TF_LUCIDA TF_MENUDEFAULT TF_NEWCENTURY TF_SYSTEM
+syntax keyword	openroadConst	TF_TIMESROMAN TRUE UE_DATAERROR UE_EXITED
+syntax keyword	openroadConst	UE_NOTACTIVE UE_PURGED UE_RESUMED UE_UNKNOWN
+syntax keyword	openroadConst	WI_MOTIF WI_MSWIN32 WI_MSWINDOWS WI_NONE WI_PM
+syntax keyword	openroadConst	WP_FLOATING WP_INTERACTIVE WP_PARENTCENTERED
+syntax keyword	openroadConst	WP_PARENTRELATIVE WP_SCREENCENTERED
+syntax keyword	openroadConst	WP_SCREENRELATIVE WV_ICON WV_INVISIBLE
+syntax keyword	openroadConst	WV_UNREALIZED WV_VISIBLE
+
+" System Variables
+"
+syntax keyword	openroadVar		CurFrame CurProcedure CurMethod CurObject
+
+" Identifiers
+"
+syntax match	openroadIdent	/[a-zA-Z_][a-zA-Z_]*![a-zA-Z_][a-zA-Z_]*/
+
+" Comments
+"
+if exists("openroad_comment_strings")
+	syntax match openroadCommentSkip	contained "^\s*\*\($\|\s\+\)"
+	syntax region openroadCommentString	contained start=+"+ skip=+\\\\\|\\"+ end=+"+ end="$"
+	syntax region openroadComment		start="/\*" end="\*/" contains=openroadCommentString,openroadCharacter,openroadNumber
+	syntax match openroadComment		"//.*" contains=openroadComment2String,openroadCharacter,openroadNumber
+else
+	syn region openroadComment			start="/\*" end="\*/"
+	syn match openroadComment			"//.*"
+endif
+
+" Define the default highlighting.
+" For version 5.7 and earlier: only when not done already
+" For version 5.8 and later: only when an item doesn't have highlighting yet
+"
+if version >= 508 || !exists("did_openroad_syntax_inits")
+	if version < 508
+		let did_openroad_syntax_inits = 1
+		command -nargs=+ HiLink hi link <args>
+	else
+		command -nargs=+ HiLink hi def link <args>
+	endif
+
+	HiLink openroadKeyword	Statement
+	HiLink openroadNumber	Number
+	HiLink openroadString	String
+	HiLink openroadComment	Comment
+	HiLink openroadOperator	Operator
+	HiLink openroadType		Type
+	HiLink openroadFunc		Special
+	HiLink openroadClass	Type
+	HiLink openroadEvent	Statement
+	HiLink openroadConst	Constant
+	HiLink openroadVar		Identifier
+	HiLink openroadIdent	Identifier
+	HiLink openroadTodo		Todo
+
+	delcommand HiLink
+endif
+
+let b:current_syntax = "openroad"
--- /dev/null
+++ b/lib/vimfiles/syntax/opl.vim
@@ -1,0 +1,96 @@
+" Vim syntax file
+" Language:	OPL
+" Maintainer:	Czo <Olivier.Sirol@lip6.fr>
+" $Id: opl.vim,v 1.1 2004/06/13 17:34:11 vimboss Exp $
+
+" Open Psion Language... (EPOC16/EPOC32)
+
+" For version 5.x: Clear all syntax items
+" For version 6.x: Quit when a syntax file was already loaded
+if version < 600
+  syntax clear
+elseif exists("b:current_syntax")
+  finish
+endif
+
+" case is not significant
+syn case ignore
+
+" A bunch of useful OPL keywords
+syn keyword OPLStatement proc endp abs acos addr adjustalloc alert alloc app
+syn keyword OPLStatement append appendsprite asc asin at atan back beep
+syn keyword OPLStatement begintrans bookmark break busy byref cache
+syn keyword OPLStatement cachehdr cacherec cachetidy call cancel caption
+syn keyword OPLStatement changesprite chr$ clearflags close closesprite cls
+syn keyword OPLStatement cmd$ committrans compact compress const continue
+syn keyword OPLStatement copy cos count create createsprite cursor
+syn keyword OPLStatement datetosecs datim$ day dayname$ days daystodate
+syn keyword OPLStatement dbuttons dcheckbox dchoice ddate declare dedit
+syn keyword OPLStatement deditmulti defaultwin deg delete dfile dfloat
+syn keyword OPLStatement dialog diaminit diampos dinit dir$ dlong do dow
+syn keyword OPLStatement dposition drawsprite dtext dtime dxinput edit else
+syn keyword OPLStatement elseif enda endif endv endwh entersend entersend0
+syn keyword OPLStatement eof erase err err$ errx$ escape eval exist exp ext
+syn keyword OPLStatement external find findfield findlib first fix$ flags
+syn keyword OPLStatement flt font freealloc gat gborder gbox gbutton
+syn keyword OPLStatement gcircle gclock gclose gcls gcolor gcopy gcreate
+syn keyword OPLStatement gcreatebit gdrawobject gellipse gen$ get get$
+syn keyword OPLStatement getcmd$ getdoc$ getevent getevent32 geteventa32
+syn keyword OPLStatement geteventc getlibh gfill gfont ggmode ggrey gheight
+syn keyword OPLStatement gidentity ginfo ginfo32 ginvert giprint glineby
+syn keyword OPLStatement glineto gloadbit gloadfont global gmove gorder
+syn keyword OPLStatement goriginx goriginy goto gotomark gpatt gpeekline
+syn keyword OPLStatement gpoly gprint gprintb gprintclip grank gsavebit
+syn keyword OPLStatement gscroll gsetpenwidth gsetwin gstyle gtmode gtwidth
+syn keyword OPLStatement gunloadfont gupdate guse gvisible gwidth gx
+syn keyword OPLStatement gxborder gxprint gy hex$ hour iabs icon if include
+syn keyword OPLStatement input insert int intf intrans key key$ keya keyc
+syn keyword OPLStatement killmark kmod last lclose left$ len lenalloc
+syn keyword OPLStatement linklib ln loadlib loadm loc local lock log lopen
+syn keyword OPLStatement lower$ lprint max mcard mcasc mean menu mid$ min
+syn keyword OPLStatement minit minute mkdir modify month month$ mpopup
+syn keyword OPLStatement newobj newobjh next notes num$ odbinfo off onerr
+syn keyword OPLStatement open openr opx os parse$ path pause peek pi
+syn keyword OPLStatement pointerfilter poke pos position possprite print
+syn keyword OPLStatement put rad raise randomize realloc recsize rename
+syn keyword OPLStatement rept$ return right$ rmdir rnd rollback sci$ screen
+syn keyword OPLStatement screeninfo second secstodate send setdoc setflags
+syn keyword OPLStatement setname setpath sin space sqr statuswin
+syn keyword OPLStatement statwininfo std stop style sum tan testevent trap
+syn keyword OPLStatement type uadd unloadlib unloadm until update upper$
+syn keyword OPLStatement use usr usr$ usub val var vector week while year
+" syn keyword OPLStatement rem
+
+
+syn match  OPLNumber		"\<\d\+\>"
+syn match  OPLNumber		"\<\d\+\.\d*\>"
+syn match  OPLNumber		"\.\d\+\>"
+
+syn region  OPLString		start=+"+   end=+"+
+syn region  OPLComment		start="REM[\t ]" end="$"
+syn match   OPLMathsOperator    "-\|=\|[:<>+\*^/\\]"
+
+" Define the default highlighting.
+" For version 5.7 and earlier: only when not done already
+" For version 5.8 and later: only when an item doesn't have highlighting yet
+if version >= 508 || !exists("did_OPL_syntax_inits")
+  if version < 508
+    let did_OPL_syntax_inits = 1
+    command -nargs=+ HiLink hi link <args>
+  else
+    command -nargs=+ HiLink hi def link <args>
+  endif
+
+  HiLink OPLStatement		Statement
+  HiLink OPLNumber		Number
+  HiLink OPLString		String
+  HiLink OPLComment		Comment
+  HiLink OPLMathsOperator	Conditional
+"  HiLink OPLError		Error
+
+  delcommand HiLink
+endif
+
+let b:current_syntax = "opl"
+
+" vim: ts=8
--- /dev/null
+++ b/lib/vimfiles/syntax/ora.vim
@@ -1,0 +1,478 @@
+" Vim syntax file
+" Language:	Oracle config files (.ora) (Oracle 8i, ver. 8.1.5)
+" Maintainer:	Sandor Kopanyi <sandor.kopanyi@mailbox.hu>
+" Url:		<->
+" Last Change:	2003 May 11
+
+" * the keywords are listed by file (sqlnet.ora, listener.ora, etc.)
+" * the parathesis-checking is made at the beginning for all keywords
+" * possible values are listed also
+" * there are some overlappings (e.g. METHOD is mentioned both for
+"   sqlnet-ora and tnsnames.ora; since will not cause(?) problems
+"   is easier to follow separately each file's keywords)
+
+" Remove any old syntax stuff hanging around, if needed
+if version < 600
+  syn clear
+elseif exists("b:current_syntax")
+  finish
+endif
+
+if !exists("main_syntax")
+  let main_syntax = 'ora'
+endif
+
+syn case ignore
+
+"comments
+syn match oraComment "\#.*"
+
+" catch errors caused by wrong parenthesis
+syn region  oraParen transparent start="(" end=")" contains=@oraAll,oraParen
+syn match   oraParenError ")"
+
+" strings
+syn region  oraString start=+"+ end=+"+
+
+"common .ora staff
+
+"common protocol parameters
+syn keyword oraKeywordGroup   ADDRESS ADDRESS_LIST
+syn keyword oraKeywordGroup   DESCRIPTION_LIST DESCRIPTION
+"all protocols
+syn keyword oraKeyword	      PROTOCOL
+syn keyword oraValue	      ipc tcp nmp
+"Bequeath
+syn keyword oraKeyword	      PROGRAM ARGV0 ARGS
+"IPC
+syn keyword oraKeyword	      KEY
+"Named Pipes
+syn keyword oraKeyword	      SERVER PIPE
+"LU6.2
+syn keyword oraKeyword	      LU_NAME LLU LOCAL_LU LLU_NAME LOCAL_LU_NAME
+syn keyword oraKeyword	      MODE MDN
+syn keyword oraKeyword	      PLU PARTNER_LU_NAME PLU_LA PARTNER_LU_LOCAL_ALIAS
+syn keyword oraKeyword	      TP_NAME TPN
+"SPX
+syn keyword oraKeyword	      SERVICE
+"TCP/IP and TCP/IP with SSL
+syn keyword oraKeyword	      HOST PORT
+
+"misc. keywords I've met but didn't find in manual (maybe they are deprecated?)
+syn keyword oraKeywordGroup COMMUNITY_LIST
+syn keyword oraKeyword	    COMMUNITY NAME DEFAULT_ZONE
+syn keyword oraValue	    tcpcom
+
+"common values
+syn keyword oraValue	    yes no on off true false null all none ok
+"word 'world' is used a lot...
+syn keyword oraModifier       world
+
+"misc. common keywords
+syn keyword oraKeyword      TRACE_DIRECTORY TRACE_LEVEL TRACE_FILE
+
+
+"sqlnet.ora
+syn keyword oraKeywordPref  NAMES NAMESCTL
+syn keyword oraKeywordPref  OSS SOURCE SQLNET TNSPING
+syn keyword oraKeyword      AUTOMATIC_IPC BEQUEATH_DETACH DAEMON TRACE_MASK
+syn keyword oraKeyword      DISABLE_OOB
+syn keyword oraKeyword      LOG_DIRECTORY_CLIENT LOG_DIRECTORY_SERVER
+syn keyword oraKeyword      LOG_FILE_CLIENT LOG_FILE_SERVER
+syn keyword oraKeyword      DCE PREFIX DEFAULT_DOMAIN DIRECTORY_PATH
+syn keyword oraKeyword      INITIAL_RETRY_TIMEOUT MAX_OPEN_CONNECTIONS
+syn keyword oraKeyword      MESSAGE_POOL_START_SIZE NIS META_MAP
+syn keyword oraKeyword      PASSWORD PREFERRED_SERVERS REQUEST_RETRIES
+syn keyword oraKeyword      INTERNAL_ENCRYPT_PASSWORD INTERNAL_USE
+syn keyword oraKeyword      NO_INITIAL_SERVER NOCONFIRM
+syn keyword oraKeyword      SERVER_PASSWORD TRACE_UNIQUE MY_WALLET
+syn keyword oraKeyword      LOCATION DIRECTORY METHOD METHOD_DATA
+syn keyword oraKeyword      SQLNET_ADDRESS
+syn keyword oraKeyword      AUTHENTICATION_SERVICES
+syn keyword oraKeyword      AUTHENTICATION_KERBEROS5_SERVICE
+syn keyword oraKeyword      AUTHENTICATION_GSSAPI_SERVICE
+syn keyword oraKeyword      CLIENT_REGISTRATION
+syn keyword oraKeyword      CRYPTO_CHECKSUM_CLIENT CRYPTO_CHECKSUM_SERVER
+syn keyword oraKeyword      CRYPTO_CHECKSUM_TYPES_CLIENT CRYPTO_CHECKSUM_TYPES_SERVER
+syn keyword oraKeyword      CRYPTO_SEED
+syn keyword oraKeyword      ENCRYPTION_CLIENT ENCRYPTION_SERVER
+syn keyword oraKeyword      ENCRYPTION_TYPES_CLIENT ENCRYPTION_TYPES_SERVER
+syn keyword oraKeyword      EXPIRE_TIME
+syn keyword oraKeyword      IDENTIX_FINGERPRINT_DATABASE IDENTIX_FINGERPRINT_DATABASE_USER
+syn keyword oraKeyword      IDENTIX_FINGERPRINT_DATABASE_PASSWORD IDENTIX_FINGERPRINT_METHOD
+syn keyword oraKeyword      KERBEROS5_CC_NAME KERBEROS5_CLOCKSKEW KERBEROS5_CONF
+syn keyword oraKeyword      KERBEROS5_KEYTAB KERBEROS5_REALMS
+syn keyword oraKeyword      RADIUS_ALTERNATE RADIUS_ALTERNATE_PORT RADIUS_ALTERNATE_RETRIES
+syn keyword oraKeyword      RADIUS_AUTHENTICATION_TIMEOUT RADIUS_AUTHENTICATION
+syn keyword oraKeyword      RADIUS_AUTHENTICATION_INTERFACE RADIUS_AUTHENTICATION_PORT
+syn keyword oraKeyword      RADIUS_AUTHENTICATION_RETRIES RADIUS_AUTHENTICATION_TIMEOUT
+syn keyword oraKeyword      RADIUS_CHALLENGE_RESPONSE RADIUS_SECRET RADIUS_SEND_ACCOUNTING
+syn keyword oraKeyword      SSL_CLIENT_AUTHENTICATION SSL_CIPHER_SUITES SSL_VERSION
+syn keyword oraKeyword      TRACE_DIRECTORY_CLIENT TRACE_DIRECTORY_SERVER
+syn keyword oraKeyword      TRACE_FILE_CLIENT TRACE_FILE_SERVER
+syn keyword oraKeyword      TRACE_LEVEL_CLIENT TRACE_LEVEL_SERVER
+syn keyword oraKeyword      TRACE_UNIQUE_CLIENT
+syn keyword oraKeyword      USE_CMAN USE_DEDICATED_SERVER
+syn keyword oraValue	    user admin support
+syn keyword oraValue	    accept accepted reject rejected requested required
+syn keyword oraValue	    md5 rc4_40 rc4_56 rc4_128 des des_40
+syn keyword oraValue	    tnsnames onames hostname dce nis novell
+syn keyword oraValue	    file oracle
+syn keyword oraValue	    oss
+syn keyword oraValue	    beq nds nts kerberos5 securid cybersafe identix dcegssapi radius
+syn keyword oraValue	    undetermined
+
+"tnsnames.ora
+syn keyword oraKeywordGroup CONNECT_DATA FAILOVER_MODE
+syn keyword oraKeyword      FAILOVER LOAD_BALANCE SOURCE_ROUTE TYPE_OF_SERVICE
+syn keyword oraKeyword      BACKUP TYPE METHOD GLOBAL_NAME HS
+syn keyword oraKeyword      INSTANCE_NAME RDB_DATABASE SDU SERVER
+syn keyword oraKeyword      SERVICE_NAME SERVICE_NAMES SID
+syn keyword oraKeyword      HANDLER_NAME EXTPROC_CONNECTION_DATA
+syn keyword oraValue	    session select basic preconnect dedicated shared
+
+"listener.ora
+syn keyword oraKeywordGroup SID_LIST SID_DESC PRESPAWN_LIST PRESPAWN_DESC
+syn match   oraKeywordGroup "SID_LIST_\w*"
+syn keyword oraKeyword      PROTOCOL_STACK PRESENTATION SESSION
+syn keyword oraKeyword      GLOBAL_DBNAME ORACLE_HOME PROGRAM SID_NAME
+syn keyword oraKeyword      PRESPAWN_MAX POOL_SIZE TIMEOUT
+syn match   oraKeyword      "CONNECT_TIMEOUT_\w*"
+syn match   oraKeyword      "LOG_DIRECTORY_\w*"
+syn match   oraKeyword      "LOG_FILE_\w*"
+syn match   oraKeyword      "PASSWORDS_\w*"
+syn match   oraKeyword      "STARTUP_WAIT_TIME_\w*"
+syn match   oraKeyword      "STARTUP_WAITTIME_\w*"
+syn match   oraKeyword      "TRACE_DIRECTORY_\w*"
+syn match   oraKeyword      "TRACE_FILE_\w*"
+syn match   oraKeyword      "TRACE_LEVEL_\w*"
+syn match   oraKeyword      "USE_PLUG_AND_PLAY_\w*"
+syn keyword oraValue	    ttc giop ns raw
+
+"names.ora
+syn keyword oraKeywordGroup ADDRESSES ADMIN_REGION
+syn keyword oraKeywordGroup DEFAULT_FORWARDERS FORWARDER_LIST FORWARDER
+syn keyword oraKeywordGroup DOMAIN_HINTS HINT_DESC HINT_LIST
+syn keyword oraKeywordGroup DOMAINS DOMAIN_LIST DOMAIN
+syn keyword oraKeywordPref  NAMES
+syn keyword oraKeyword      EXPIRE REFRESH REGION RETRY USERID VERSION
+syn keyword oraKeyword      AUTHORITY_REQUIRED CONNECT_TIMEOUT
+syn keyword oraKeyword      AUTO_REFRESH_EXPIRE AUTO_REFRESH_RETRY
+syn keyword oraKeyword      CACHE_CHECKPOINT_FILE CACHE_CHECKPOINT_INTERVAL
+syn keyword oraKeyword      CONFIG_CHECKPOINT_FILE DEFAULT_FORWARDERS_ONLY
+syn keyword oraKeyword      HINT FORWARDING_AVAILABLE FORWARDING_DESIRED
+syn keyword oraKeyword      KEEP_DB_OPEN
+syn keyword oraKeyword      LOG_DIRECTORY LOG_FILE LOG_STATS_INTERVAL LOG_UNIQUE
+syn keyword oraKeyword      MAX_OPEN_CONNECTIONS MAX_REFORWARDS
+syn keyword oraKeyword      MESSAGE_POOL_START_SIZE
+syn keyword oraKeyword      NO_MODIFY_REQUESTS NO_REGION_DATABASE
+syn keyword oraKeyword      PASSWORD REGION_CHECKPOINT_FILE
+syn keyword oraKeyword      RESET_STATS_INTERVAL SAVE_CONFIG_ON_STOP
+syn keyword oraKeyword      SERVER_NAME TRACE_FUNC TRACE_UNIQUE
+
+"cman.ora
+syn keyword oraKeywordGroup   CMAN CMAN_ADMIN CMAN_PROFILE PARAMETER_LIST
+syn keyword oraKeywordGroup   CMAN_RULES RULES_LIST RULE
+syn keyword oraKeyword	      ANSWER_TIMEOUT AUTHENTICATION_LEVEL LOG_LEVEL
+syn keyword oraKeyword	      MAX_FREELIST_BUFFERS MAXIMUM_CONNECT_DATA MAXIMUM_RELAYS
+syn keyword oraKeyword	      RELAY_STATISTICS SHOW_TNS_INFO TRACING
+syn keyword oraKeyword	      USE_ASYNC_CALL SRC DST SRV ACT
+
+"protocol.ora
+syn match oraKeyword	      "\w*\.EXCLUDED_NODES"
+syn match oraKeyword	      "\w*\.INVITED_NODES"
+syn match oraKeyword	      "\w*\.VALIDNODE_CHECKING"
+syn keyword oraKeyword	      TCP NODELAY
+
+
+
+
+"---------------------------------------
+"init.ora
+
+"common values
+syn keyword oraValue	      nested_loops merge hash unlimited
+
+"init params
+syn keyword oraKeyword	      O7_DICTIONARY_ACCESSIBILITY ALWAYS_ANTI_JOIN ALWAYS_SEMI_JOIN
+syn keyword oraKeyword	      AQ_TM_PROCESSES ARCH_IO_SLAVES AUDIT_FILE_DEST AUDIT_TRAIL
+syn keyword oraKeyword	      BACKGROUND_CORE_DUMP BACKGROUND_DUMP_DEST
+syn keyword oraKeyword	      BACKUP_TAPE_IO_SLAVES BITMAP_MERGE_AREA_SIZE
+syn keyword oraKeyword	      BLANK_TRIMMING BUFFER_POOL_KEEP BUFFER_POOL_RECYCLE
+syn keyword oraKeyword	      COMMIT_POINT_STRENGTH COMPATIBLE CONTROL_FILE_RECORD_KEEP_TIME
+syn keyword oraKeyword	      CONTROL_FILES CORE_DUMP_DEST CPU_COUNT
+syn keyword oraKeyword	      CREATE_BITMAP_AREA_SIZE CURSOR_SPACE_FOR_TIME
+syn keyword oraKeyword	      DB_BLOCK_BUFFERS DB_BLOCK_CHECKING DB_BLOCK_CHECKSUM
+syn keyword oraKeyword	      DB_BLOCK_LRU_LATCHES DB_BLOCK_MAX_DIRTY_TARGET
+syn keyword oraKeyword	      DB_BLOCK_SIZE DB_DOMAIN
+syn keyword oraKeyword	      DB_FILE_DIRECT_IO_COUNT DB_FILE_MULTIBLOCK_READ_COUNT
+syn keyword oraKeyword	      DB_FILE_NAME_CONVERT DB_FILE_SIMULTANEOUS_WRITES
+syn keyword oraKeyword	      DB_FILES DB_NAME DB_WRITER_PROCESSES
+syn keyword oraKeyword	      DBLINK_ENCRYPT_LOGIN DBWR_IO_SLAVES
+syn keyword oraKeyword	      DELAYED_LOGGING_BLOCK_CLEANOUTS DISCRETE_TRANSACTIONS_ENABLED
+syn keyword oraKeyword	      DISK_ASYNCH_IO DISTRIBUTED_TRANSACTIONS
+syn keyword oraKeyword	      DML_LOCKS ENQUEUE_RESOURCES ENT_DOMAIN_NAME EVENT
+syn keyword oraKeyword	      FAST_START_IO_TARGET FAST_START_PARALLEL_ROLLBACK
+syn keyword oraKeyword	      FIXED_DATE FREEZE_DB_FOR_FAST_INSTANCE_RECOVERY
+syn keyword oraKeyword	      GC_DEFER_TIME GC_FILES_TO_LOCKS GC_RELEASABLE_LOCKS GC_ROLLBACK_LOCKS
+syn keyword oraKeyword	      GLOBAL_NAMES HASH_AREA_SIZE
+syn keyword oraKeyword	      HASH_JOIN_ENABLED HASH_MULTIBLOCK_IO_COUNT
+syn keyword oraKeyword	      HI_SHARED_MEMORY_ADDRESS HS_AUTOREGISTER
+syn keyword oraKeyword	      IFILE
+syn keyword oraKeyword	      INSTANCE_GROUPS INSTANCE_NAME INSTANCE_NUMBER
+syn keyword oraKeyword	      JAVA_POOL_SIZE JOB_QUEUE_INTERVAL JOB_QUEUE_PROCESSES LARGE_POOL_SIZE
+syn keyword oraKeyword	      LICENSE_MAX_SESSIONS LICENSE_MAX_USERS LICENSE_SESSIONS_WARNING
+syn keyword oraKeyword	      LM_LOCKS LM_PROCS LM_RESS
+syn keyword oraKeyword	      LOCAL_LISTENER LOCK_NAME_SPACE LOCK_SGA LOCK_SGA_AREAS
+syn keyword oraKeyword	      LOG_ARCHIVE_BUFFER_SIZE LOG_ARCHIVE_BUFFERS LOG_ARCHIVE_DEST
+syn match   oraKeyword	      "LOG_ARCHIVE_DEST_\(1\|2\|3\|4\|5\)"
+syn match   oraKeyword	      "LOG_ARCHIVE_DEST_STATE_\(1\|2\|3\|4\|5\)"
+syn keyword oraKeyword	      LOG_ARCHIVE_DUPLEX_DEST LOG_ARCHIVE_FORMAT LOG_ARCHIVE_MAX_PROCESSES
+syn keyword oraKeyword	      LOG_ARCHIVE_MIN_SUCCEED_DEST LOG_ARCHIVE_START
+syn keyword oraKeyword	      LOG_BUFFER LOG_CHECKPOINT_INTERVAL LOG_CHECKPOINT_TIMEOUT
+syn keyword oraKeyword	      LOG_CHECKPOINTS_TO_ALERT LOG_FILE_NAME_CONVERT
+syn keyword oraKeyword	      MAX_COMMIT_PROPAGATION_DELAY MAX_DUMP_FILE_SIZE
+syn keyword oraKeyword	      MAX_ENABLED_ROLES MAX_ROLLBACK_SEGMENTS
+syn keyword oraKeyword	      MTS_DISPATCHERS MTS_MAX_DISPATCHERS MTS_MAX_SERVERS MTS_SERVERS
+syn keyword oraKeyword	      NLS_CALENDAR NLS_COMP NLS_CURRENCY NLS_DATE_FORMAT
+syn keyword oraKeyword	      NLS_DATE_LANGUAGE NLS_DUAL_CURRENCY NLS_ISO_CURRENCY NLS_LANGUAGE
+syn keyword oraKeyword	      NLS_NUMERIC_CHARACTERS NLS_SORT NLS_TERRITORY
+syn keyword oraKeyword	      OBJECT_CACHE_MAX_SIZE_PERCENT OBJECT_CACHE_OPTIMAL_SIZE
+syn keyword oraKeyword	      OPEN_CURSORS OPEN_LINKS OPEN_LINKS_PER_INSTANCE
+syn keyword oraKeyword	      OPS_ADMINISTRATION_GROUP
+syn keyword oraKeyword	      OPTIMIZER_FEATURES_ENABLE OPTIMIZER_INDEX_CACHING
+syn keyword oraKeyword	      OPTIMIZER_INDEX_COST_ADJ OPTIMIZER_MAX_PERMUTATIONS
+syn keyword oraKeyword	      OPTIMIZER_MODE OPTIMIZER_PERCENT_PARALLEL
+syn keyword oraKeyword	      OPTIMIZER_SEARCH_LIMIT
+syn keyword oraKeyword	      ORACLE_TRACE_COLLECTION_NAME ORACLE_TRACE_COLLECTION_PATH
+syn keyword oraKeyword	      ORACLE_TRACE_COLLECTION_SIZE ORACLE_TRACE_ENABLE
+syn keyword oraKeyword	      ORACLE_TRACE_FACILITY_NAME ORACLE_TRACE_FACILITY_PATH
+syn keyword oraKeyword	      OS_AUTHENT_PREFIX OS_ROLES
+syn keyword oraKeyword	      PARALLEL_ADAPTIVE_MULTI_USER PARALLEL_AUTOMATIC_TUNING
+syn keyword oraKeyword	      PARALLEL_BROADCAST_ENABLED PARALLEL_EXECUTION_MESSAGE_SIZE
+syn keyword oraKeyword	      PARALLEL_INSTANCE_GROUP PARALLEL_MAX_SERVERS
+syn keyword oraKeyword	      PARALLEL_MIN_PERCENT PARALLEL_MIN_SERVERS
+syn keyword oraKeyword	      PARALLEL_SERVER PARALLEL_SERVER_INSTANCES PARALLEL_THREADS_PER_CPU
+syn keyword oraKeyword	      PARTITION_VIEW_ENABLED PLSQL_V2_COMPATIBILITY
+syn keyword oraKeyword	      PRE_PAGE_SGA PROCESSES
+syn keyword oraKeyword	      QUERY_REWRITE_ENABLED QUERY_REWRITE_INTEGRITY
+syn keyword oraKeyword	      RDBMS_SERVER_DN READ_ONLY_OPEN_DELAYED RECOVERY_PARALLELISM
+syn keyword oraKeyword	      REMOTE_DEPENDENCIES_MODE REMOTE_LOGIN_PASSWORDFILE
+syn keyword oraKeyword	      REMOTE_OS_AUTHENT REMOTE_OS_ROLES
+syn keyword oraKeyword	      REPLICATION_DEPENDENCY_TRACKING
+syn keyword oraKeyword	      RESOURCE_LIMIT RESOURCE_MANAGER_PLAN
+syn keyword oraKeyword	      ROLLBACK_SEGMENTS ROW_LOCKING SERIAL _REUSE SERVICE_NAMES
+syn keyword oraKeyword	      SESSION_CACHED_CURSORS SESSION_MAX_OPEN_FILES SESSIONS
+syn keyword oraKeyword	      SHADOW_CORE_DUMP
+syn keyword oraKeyword	      SHARED_MEMORY_ADDRESS SHARED_POOL_RESERVED_SIZE SHARED_POOL_SIZE
+syn keyword oraKeyword	      SORT_AREA_RETAINED_SIZE SORT_AREA_SIZE SORT_MULTIBLOCK_READ_COUNT
+syn keyword oraKeyword	      SQL92_SECURITY SQL_TRACE STANDBY_ARCHIVE_DEST
+syn keyword oraKeyword	      STAR_TRANSFORMATION_ENABLED TAPE_ASYNCH_IO THREAD
+syn keyword oraKeyword	      TIMED_OS_STATISTICS TIMED_STATISTICS
+syn keyword oraKeyword	      TRANSACTION_AUDITING TRANSACTIONS TRANSACTIONS_PER_ROLLBACK_SEGMENT
+syn keyword oraKeyword	      USE_INDIRECT_DATA_BUFFERS USER_DUMP_DEST
+syn keyword oraKeyword	      UTL_FILE_DIR
+syn keyword oraKeywordObs     ALLOW_PARTIAL_SN_RESULTS B_TREE_BITMAP_PLANS
+syn keyword oraKeywordObs     BACKUP_DISK_IO_SLAVES CACHE_SIZE_THRESHOLD
+syn keyword oraKeywordObs     CCF_IO_SIZE CLEANUP_ROLLBACK_ENTRIES
+syn keyword oraKeywordObs     CLOSE_CACHED_OPEN_CURSORS COMPATIBLE_NO_RECOVERY
+syn keyword oraKeywordObs     COMPLEX_VIEW_MERGING
+syn keyword oraKeywordObs     DB_BLOCK_CHECKPOINT_BATCH DB_BLOCK_LRU_EXTENDED_STATISTICS
+syn keyword oraKeywordObs     DB_BLOCK_LRU_STATISTICS
+syn keyword oraKeywordObs     DISTRIBUTED_LOCK_TIMEOUT DISTRIBUTED_RECOVERY_CONNECTION_HOLD_TIME
+syn keyword oraKeywordObs     FAST_FULL_SCAN_ENABLED GC_LATCHES GC_LCK_PROCS
+syn keyword oraKeywordObs     LARGE_POOL_MIN_ALLOC LGWR_IO_SLAVES
+syn keyword oraKeywordObs     LOG_BLOCK_CHECKSUM LOG_FILES
+syn keyword oraKeywordObs     LOG_SIMULTANEOUS_COPIES LOG_SMALL_ENTRY_MAX_SIZE
+syn keyword oraKeywordObs     MAX_TRANSACTION_BRANCHES
+syn keyword oraKeywordObs     MTS_LISTENER_ADDRESS MTS_MULTIPLE_LISTENERS
+syn keyword oraKeywordObs     MTS_RATE_LOG_SIZE MTS_RATE_SCALE MTS_SERVICE
+syn keyword oraKeywordObs     OGMS_HOME OPS_ADMIN_GROUP
+syn keyword oraKeywordObs     PARALLEL_DEFAULT_MAX_INSTANCES PARALLEL_MIN_MESSAGE_POOL
+syn keyword oraKeywordObs     PARALLEL_SERVER_IDLE_TIME PARALLEL_TRANSACTION_RESOURCE_TIMEOUT
+syn keyword oraKeywordObs     PUSH_JOIN_PREDICATE REDUCE_ALARM ROW_CACHE_CURSORS
+syn keyword oraKeywordObs     SEQUENCE_CACHE_ENTRIES SEQUENCE_CACHE_HASH_BUCKETS
+syn keyword oraKeywordObs     SHARED_POOL_RESERVED_MIN_ALLOC
+syn keyword oraKeywordObs     SORT_DIRECT_WRITES SORT_READ_FAC SORT_SPACEMAP_SIZE
+syn keyword oraKeywordObs     SORT_WRITE_BUFFER_SIZE SORT_WRITE_BUFFERS
+syn keyword oraKeywordObs     SPIN_COUNT TEMPORARY_TABLE_LOCKS USE_ISM
+syn keyword oraValue	      db os full partial mandatory optional reopen enable defer
+syn keyword oraValue	      always default intent disable dml plsql temp_disable
+syn match   oravalue	      "Arabic Hijrah"
+syn match   oravalue	      "English Hijrah"
+syn match   oravalue	      "Gregorian"
+syn match   oravalue	      "Japanese Imperial"
+syn match   oravalue	      "Persian"
+syn match   oravalue	      "ROC Official"
+syn match   oravalue	      "Thai Buddha"
+syn match   oravalue	      "8.0.0"
+syn match   oravalue	      "8.0.3"
+syn match   oravalue	      "8.0.4"
+syn match   oravalue	      "8.1.3"
+syn match oraModifier	      "archived log"
+syn match oraModifier	      "backup corruption"
+syn match oraModifier	      "backup datafile"
+syn match oraModifier	      "backup piece  "
+syn match oraModifier	      "backup redo log"
+syn match oraModifier	      "backup set"
+syn match oraModifier	      "copy corruption"
+syn match oraModifier	      "datafile copy"
+syn match oraModifier	      "deleted object"
+syn match oraModifier	      "loghistory"
+syn match oraModifier	      "offline range"
+
+"undocumented init params
+"up to 7.2 (inclusive)
+syn keyword oraKeywordUndObs  _latch_spin_count _trace_instance_termination
+syn keyword oraKeywordUndObs  _wakeup_timeout _lgwr_async_write
+"7.3
+syn keyword oraKeywordUndObs  _standby_lock_space_name _enable_dba_locking
+"8.0.5
+syn keyword oraKeywordUnd     _NUMA_instance_mapping _NUMA_pool_size
+syn keyword oraKeywordUnd     _advanced_dss_features _affinity_on _all_shared_dblinks
+syn keyword oraKeywordUnd     _allocate_creation_order _allow_resetlogs_corruption
+syn keyword oraKeywordUnd     _always_star_transformation _bump_highwater_mark_count
+syn keyword oraKeywordUnd     _column_elimination_off _controlfile_enqueue_timeout
+syn keyword oraKeywordUnd     _corrupt_blocks_on_stuck_recovery _corrupted_rollback_segments
+syn keyword oraKeywordUnd     _cr_deadtime _cursor_db_buffers_pinned
+syn keyword oraKeywordUnd     _db_block_cache_clone _db_block_cache_map _db_block_cache_protect
+syn keyword oraKeywordUnd     _db_block_hash_buckets _db_block_hi_priority_batch_size
+syn keyword oraKeywordUnd     _db_block_max_cr_dba _db_block_max_scan_cnt
+syn keyword oraKeywordUnd     _db_block_med_priority_batch_size _db_block_no_idle_writes
+syn keyword oraKeywordUnd     _db_block_write_batch _db_handles _db_handles_cached
+syn keyword oraKeywordUnd     _db_large_dirty_queue _db_no_mount_lock
+syn keyword oraKeywordUnd     _db_writer_histogram_statistics _db_writer_scan_depth
+syn keyword oraKeywordUnd     _db_writer_scan_depth_decrement _db_writer_scan_depth_increment
+syn keyword oraKeywordUnd     _disable_incremental_checkpoints
+syn keyword oraKeywordUnd     _disable_latch_free_SCN_writes_via_32cas
+syn keyword oraKeywordUnd     _disable_latch_free_SCN_writes_via_64cas
+syn keyword oraKeywordUnd     _disable_logging _disable_ntlog_events
+syn keyword oraKeywordUnd     _dss_cache_flush _dynamic_stats_threshold
+syn keyword oraKeywordUnd     _enable_cscn_caching _enable_default_affinity
+syn keyword oraKeywordUnd     _enqueue_debug_multi_instance _enqueue_hash
+syn keyword oraKeywordUnd     _enqueue_hash_chain_latches _enqueue_locks
+syn keyword oraKeywordUnd     _fifth_spare_parameter _first_spare_parameter _fourth_spare_parameter
+syn keyword oraKeywordUnd     _gc_class_locks _groupby_nopushdown_cut_ratio
+syn keyword oraKeywordUnd     _idl_conventional_index_maintenance _ignore_failed_escalates
+syn keyword oraKeywordUnd     _init_sql_file
+syn keyword oraKeywordUnd     _io_slaves_disabled _ioslave_batch_count _ioslave_issue_count
+syn keyword oraKeywordUnd     _kgl_bucket_count _kgl_latch_count _kgl_multi_instance_invalidation
+syn keyword oraKeywordUnd     _kgl_multi_instance_lock _kgl_multi_instance_pin
+syn keyword oraKeywordUnd     _latch_miss_stat_sid _latch_recovery_alignment _latch_wait_posting
+syn keyword oraKeywordUnd     _lm_ast_option _lm_direct_sends _lm_dlmd_procs _lm_domains _lm_groups
+syn keyword oraKeywordUnd     _lm_non_fault_tolerant _lm_send_buffers _lm_statistics _lm_xids
+syn keyword oraKeywordUnd     _log_blocks_during_backup _log_buffers_debug _log_checkpoint_recovery_check
+syn keyword oraKeywordUnd     _log_debug_multi_instance _log_entry_prebuild_threshold _log_io_size
+syn keyword oraKeywordUnd     _log_space_errors
+syn keyword oraKeywordUnd     _max_exponential_sleep _max_sleep_holding_latch
+syn keyword oraKeywordUnd     _messages _minimum_giga_scn _mts_load_constants _nested_loop_fudge
+syn keyword oraKeywordUnd     _no_objects _no_or_expansion
+syn keyword oraKeywordUnd     _number_cached_attributes _offline_rollback_segments _open_files_limit
+syn keyword oraKeywordUnd     _optimizer_undo_changes
+syn keyword oraKeywordUnd     _oracle_trace_events _oracle_trace_facility_version
+syn keyword oraKeywordUnd     _ordered_nested_loop _parallel_server_sleep_time
+syn keyword oraKeywordUnd     _passwordfile_enqueue_timeout _pdml_slaves_diff_part
+syn keyword oraKeywordUnd     _plsql_dump_buffer_events _predicate_elimination_enabled
+syn keyword oraKeywordUnd     _project_view_columns
+syn keyword oraKeywordUnd     _px_broadcast_fudge_factor _px_broadcast_trace _px_dop_limit_degree
+syn keyword oraKeywordUnd     _px_dop_limit_threshold _px_kxfr_granule_allocation _px_kxib_tracing
+syn keyword oraKeywordUnd     _release_insert_threshold _reuse_index_loop
+syn keyword oraKeywordUnd     _rollback_segment_count _rollback_segment_initial
+syn keyword oraKeywordUnd     _row_cache_buffer_size _row_cache_instance_locks
+syn keyword oraKeywordUnd     _save_escalates _scn_scheme
+syn keyword oraKeywordUnd     _second_spare_parameter _session_idle_bit_latches
+syn keyword oraKeywordUnd     _shared_session_sort_fetch_buffer _single_process
+syn keyword oraKeywordUnd     _small_table_threshold _sql_connect_capability_override
+syn keyword oraKeywordUnd     _sql_connect_capability_table
+syn keyword oraKeywordUnd     _test_param_1 _test_param_2 _test_param_3
+syn keyword oraKeywordUnd     _third_spare_parameter _tq_dump_period
+syn keyword oraKeywordUnd     _trace_archive_dest _trace_archive_start _trace_block_size
+syn keyword oraKeywordUnd     _trace_buffers_per_process _trace_enabled _trace_events
+syn keyword oraKeywordUnd     _trace_file_size _trace_files_public _trace_flushing _trace_write_batch_size
+syn keyword oraKeywordUnd     _upconvert_from_ast _use_vector_post _wait_for_sync _walk_insert_threshold
+"dunno which version; may be 8.1.x, may be obsoleted
+syn keyword oraKeywordUndObs  _arch_io_slaves _average_dirties_half_life _b_tree_bitmap_plans
+syn keyword oraKeywordUndObs  _backup_disk_io_slaves _backup_io_pool_size
+syn keyword oraKeywordUndObs  _cleanup_rollback_entries _close_cached_open_cursors
+syn keyword oraKeywordUndObs  _compatible_no_recovery _complex_view_merging
+syn keyword oraKeywordUndObs  _cpu_to_io _cr_server
+syn keyword oraKeywordUndObs  _db_aging_cool_count _db_aging_freeze_cr _db_aging_hot_criteria
+syn keyword oraKeywordUndObs  _db_aging_stay_count _db_aging_touch_time
+syn keyword oraKeywordUndObs  _db_percent_hot_default _db_percent_hot_keep _db_percent_hot_recycle
+syn keyword oraKeywordUndObs  _db_writer_chunk_writes _db_writer_max_writes
+syn keyword oraKeywordUndObs  _dbwr_async_io _dbwr_tracing
+syn keyword oraKeywordUndObs  _defer_multiple_waiters _discrete_transaction_enabled
+syn keyword oraKeywordUndObs  _distributed_lock_timeout _distributed_recovery _distribited_recovery_
+syn keyword oraKeywordUndObs  _domain_index_batch_size _domain_index_dml_batch_size
+syn keyword oraKeywordUndObs  _enable_NUMA_optimization _enable_block_level_transaction_recovery
+syn keyword oraKeywordUndObs  _enable_list_io _enable_multiple_sampling
+syn keyword oraKeywordUndObs  _fairness_treshold _fast_full_scan_enabled _foreground_locks
+syn keyword oraKeywordUndObs  _full_pwise_join_enabled _gc_latches _gc_lck_procs
+syn keyword oraKeywordUndObs  _high_server_treshold _index_prefetch_factor _kcl_debug
+syn keyword oraKeywordUndObs  _kkfi_trace _large_pool_min_alloc _lazy_freelist_close _left_nested_loops_random
+syn keyword oraKeywordUndObs  _lgwr_async_io _lgwr_io_slaves _lock_sga_areas
+syn keyword oraKeywordUndObs  _log_archive_buffer_size _log_archive_buffers _log_simultaneous_copies
+syn keyword oraKeywordUndObs  _low_server_treshold _max_transaction_branches
+syn keyword oraKeywordUndObs  _mts_rate_log_size _mts_rate_scale
+syn keyword oraKeywordUndObs  _mview_cost_rewrite _mview_rewrite_2
+syn keyword oraKeywordUndObs  _ncmb_readahead_enabled _ncmb_readahead_tracing
+syn keyword oraKeywordUndObs  _ogms_home
+syn keyword oraKeywordUndObs  _parallel_adaptive_max_users _parallel_default_max_instances
+syn keyword oraKeywordUndObs  _parallel_execution_message_align _parallel_fake_class_pct
+syn keyword oraKeywordUndObs  _parallel_load_bal_unit _parallel_load_balancing
+syn keyword oraKeywordUndObs  _parallel_min_message_pool _parallel_recovery_stopat
+syn keyword oraKeywordUndObs  _parallel_server_idle_time _parallelism_cost_fudge_factor
+syn keyword oraKeywordUndObs  _partial_pwise_join_enabled _pdml_separate_gim _push_join_predicate
+syn keyword oraKeywordUndObs  _px_granule_size _px_index_sampling _px_load_publish_interval
+syn keyword oraKeywordUndObs  _px_max_granules_per_slave _px_min_granules_per_slave _px_no_stealing
+syn keyword oraKeywordUndObs  _row_cache_cursors _serial_direct_read _shared_pool_reserved_min_alloc
+syn keyword oraKeywordUndObs  _sort_space_for_write_buffers _spin_count _system_trig_enabled
+syn keyword oraKeywordUndObs  _trace_buffer_flushes _trace_cr_buffer_creates _trace_multi_block_reads
+syn keyword oraKeywordUndObs  _transaction_recovery_servers _use_ism _yield_check_interval
+
+
+syn cluster oraAll add=oraKeyword,oraKeywordGroup,oraKeywordPref,oraKeywordObs,oraKeywordUnd,oraKeywordUndObs
+syn cluster oraAll add=oraValue,oraModifier,oraString,oraSpecial,oraComment
+
+"==============================================================================
+" highlighting
+
+" For version 5.7 and earlier: only when not done already
+" For version 5.8 and later: only when an item doesn't have highlighting yet
+if version >= 508 || !exists("did_ora_syn_inits")
+
+  if version < 508
+    let did_ora_syn_inits = 1
+    command -nargs=+ HiLink hi link <args>
+  else
+    command -nargs=+ HiLink hi def link <args>
+  endif
+
+  HiLink oraKeyword	  Statement		"usual keywords
+  HiLink oraKeywordGroup  Type			"keywords which group other keywords
+  HiLink oraKeywordPref   oraKeywordGroup	"keywords which act as prefixes
+  HiLink oraKeywordObs	  Todo			"obsolete keywords
+  HiLink oraKeywordUnd	  PreProc		"undocumented keywords
+  HiLink oraKeywordUndObs oraKeywordObs		"undocumented obsolete keywords
+  HiLink oraValue	  Identifier		"values, like true or false
+  HiLink oraModifier	  oraValue		"modifies values
+  HiLink oraString	  String		"strings
+
+  HiLink oraSpecial	  Special		"special characters
+  HiLink oraError	  Error			"errors
+  HiLink oraParenError	  oraError		"errors caused by mismatching parantheses
+
+  HiLink oraComment	  Comment		"comments
+
+  delcommand HiLink
+endif
+
+
+
+let b:current_syntax = "ora"
+
+if main_syntax == 'ora'
+  unlet main_syntax
+endif
+
+" vim: ts=8
--- /dev/null
+++ b/lib/vimfiles/syntax/pamconf.vim
@@ -1,0 +1,118 @@
+" Vim syntax file
+" Language:         pam(8) configuration file
+" Maintainer:       Nikolai Weibull <now@bitwi.se>
+" Latest Revision:  2006-04-19
+
+
+if exists("b:current_syntax")
+  finish
+endif
+
+let s:cpo_save = &cpo
+set cpo&vim
+
+syn match   pamconfService          '^[[:graph:]]\+'
+                                    \ nextgroup=pamconfType,
+                                    \ pamconfServiceLineCont skipwhite
+
+syn keyword pamconfTodo             contained TODO FIXME XXX NOTE
+
+syn region  pamconfComment          display oneline start='#' end='$'
+                                    \ contains=pamconfTodo,@Spell
+
+syn match   pamconfServiceLineCont  contained '\\$'
+                                    \ nextgroup=pamconfType,
+                                    \ pamconfServiceLineCont skipwhite skipnl
+
+syn keyword pamconfType             account auth password session
+                                    \ nextgroup=pamconfControl,
+                                    \ pamconfTypeLineCont skipwhite
+
+syn match   pamconfTypeLineCont     contained '\\$'
+                                    \ nextgroup=pamconfControl,
+                                    \ pamconfTypeLineCont skipwhite skipnl
+
+syn keyword pamconfControl          contained requisite required sufficient
+                                    \ optional
+                                    \ nextgroup=pamconfMPath,
+                                    \ pamconfControlLineContH skipwhite
+
+syn match   pamconfControlBegin     '\[' nextgroup=pamconfControlValues,
+                                    \ pamconfControlLineCont skipwhite
+
+syn match   pamconfControlLineCont  contained '\\$'
+                                    \ nextgroup=pamconfControlValues,
+                                    \ pamconfControlLineCont skipwhite skipnl
+
+syn keyword pamconfControlValues    contained success open_err symbol_err
+                                    \ service_err system_err buf_err
+                                    \ perm_denied auth_err cred_insufficient
+                                    \ authinfo_unavail user_unknown maxtries
+                                    \ new_authtok_reqd acct_expired session_err
+                                    \ cred_unavail cred_expired cred_err
+                                    \ no_module_data conv_err authtok_err
+                                    \ authtok_recover_err authtok_lock_busy
+                                    \ authtok_disable_aging try_again ignore
+                                    \ abort authtok_expired module_unknown
+                                    \ bad_item and default
+                                    \ nextgroup=pamconfControlValueEq
+
+syn match   pamconfControlValueEq   contained '=' nextgroup=pamconfControlAction
+
+syn match   pamconfControlActionN   contained '\d\+\>'
+                                    \ nextgroup=pamconfControlValues,
+                                    \ pamconfControlLineCont,pamconfControlEnd
+                                    \ skipwhite
+syn keyword pamconfControlAction    contained ignore bad die ok done reset
+                                    \ nextgroup=pamconfControlValues,
+                                    \ pamconfControlLineCont,pamconfControlEnd
+                                    \ skipwhite
+
+syn match   pamconfControlEnd       contained '\]'
+                                    \ nextgroup=pamconfMPath,
+                                    \ pamconfControlLineContH skipwhite
+
+syn match   pamconfControlLineContH contained '\\$'
+                                    \ nextgroup=pamconfMPath,
+                                    \ pamconfControlLineContH skipwhite skipnl
+
+syn match   pamconfMPath            contained '\S\+'
+                                    \ nextgroup=pamconfMPathLineCont,
+                                    \ pamconfArgs skipwhite
+
+syn match   pamconfArgs             contained '\S\+'
+                                    \ nextgroup=pamconfArgsLineCont,
+                                    \ pamconfArgs skipwhite
+
+syn match   pamconfMPathLineCont    contained '\\$'
+                                    \ nextgroup=pamconfMPathLineCont,
+                                    \ pamconfArgs skipwhite skipnl
+
+syn match   pamconfArgsLineCont     contained '\\$'
+                                    \ nextgroup=pamconfArgsLineCont,
+                                    \ pamconfArgs skipwhite skipnl
+
+hi def link pamconfTodo             Todo
+hi def link pamconfComment          Comment
+hi def link pamconfService          Statement
+hi def link pamconfServiceLineCont  Special
+hi def link pamconfType             Type
+hi def link pamconfTypeLineCont     pamconfServiceLineCont
+hi def link pamconfControl          Macro
+hi def link pamconfControlBegin     Delimiter
+hi def link pamconfControlLineContH pamconfServiceLineCont
+hi def link pamconfControlLineCont  pamconfServiceLineCont
+hi def link pamconfControlValues    Identifier
+hi def link pamconfControlValueEq   Operator
+hi def link pamconfControlActionN   Number
+hi def link pamconfControlAction    Identifier
+hi def link pamconfControlEnd       Delimiter
+hi def link pamconfMPath            String
+hi def link pamconfMPathLineCont    pamconfServiceLineCont
+hi def link pamconfArgs             Normal
+hi def link pamconfArgsLineCont     pamconfServiceLineCont
+
+let b:current_syntax = "pamconf"
+
+let &cpo = s:cpo_save
+unlet s:cpo_save
--- /dev/null
+++ b/lib/vimfiles/syntax/papp.vim
@@ -1,0 +1,92 @@
+" Vim syntax file for the "papp" file format (_p_erl _app_lication)
+"
+" Language:	papp
+" Maintainer:	Marc Lehmann <pcg@goof.com>
+" Last Change:	2003 May 11
+" Filenames:    *.papp *.pxml *.pxsl
+" URL:		http://papp.plan9.de/
+
+" You can set the "papp_include_html" variable so that html will be
+" rendered as such inside phtml sections (in case you actually put html
+" there - papp does not require that). Also, rendering html tends to keep
+" the clutter high on the screen - mixing three languages is difficult
+" enough(!). PS: it is also slow.
+
+" pod is, btw, allowed everywhere, which is actually wrong :(
+
+" For version 5.x: Clear all syntax items
+" For version 6.x: Quit when a syntax file was already loaded
+if version < 600
+  syntax clear
+elseif exists("b:current_syntax")
+  finish
+endif
+
+" source is basically xml, with included html (this is common) and perl bits
+if version < 600
+  so <sfile>:p:h/xml.vim
+else
+  runtime! syntax/xml.vim
+endif
+unlet b:current_syntax
+
+if exists("papp_include_html")
+  if version < 600
+    syn include @PAppHtml <sfile>:p:h/html.vim
+  else
+    syn include @PAppHtml syntax/html.vim
+  endif
+  unlet b:current_syntax
+endif
+
+if version < 600
+  syn include @PAppPerl <sfile>:p:h/perl.vim
+else
+  syn include @PAppPerl syntax/perl.vim
+endif
+
+if v:version >= 600
+   syn cluster xmlFoldCluster add=papp_perl,papp_xperl,papp_phtml,papp_pxml,papp_perlPOD
+endif
+
+" preprocessor commands
+syn region papp_prep matchgroup=papp_prep start="^#\s*\(if\|elsif\)" end="$" keepend contains=@perlExpr contained
+syn match papp_prep /^#\s*\(else\|endif\|??\).*$/ contained
+" translation entries
+syn region papp_gettext start=/__"/ end=/"/ contained contains=@papp_perlInterpDQ
+syn cluster PAppHtml add=papp_gettext,papp_prep
+
+" add special, paired xperl, perl and phtml tags
+syn region papp_perl  matchgroup=xmlTag start="<perl>"  end="</perl>"  contains=papp_CDATAp,@PAppPerl keepend
+syn region papp_xperl matchgroup=xmlTag start="<xperl>" end="</xperl>" contains=papp_CDATAp,@PAppPerl keepend
+syn region papp_phtml matchgroup=xmlTag start="<phtml>" end="</phtml>" contains=papp_CDATAh,papp_ph_perl,papp_ph_html,papp_ph_hint,@PAppHtml keepend
+syn region papp_pxml  matchgroup=xmlTag start="<pxml>"	end="</pxml>"  contains=papp_CDATAx,papp_ph_perl,papp_ph_xml,papp_ph_xint	     keepend
+syn region papp_perlPOD start="^=[a-z]" end="^=cut" contains=@Pod,perlTodo keepend
+
+" cdata sections
+syn region papp_CDATAp matchgroup=xmlCdataDecl start="<!\[CDATA\[" end="\]\]>" contains=@PAppPerl					 contained keepend
+syn region papp_CDATAh matchgroup=xmlCdataDecl start="<!\[CDATA\[" end="\]\]>" contains=papp_ph_perl,papp_ph_html,papp_ph_hint,@PAppHtml contained keepend
+syn region papp_CDATAx matchgroup=xmlCdataDecl start="<!\[CDATA\[" end="\]\]>" contains=papp_ph_perl,papp_ph_xml,papp_ph_xint		 contained keepend
+
+syn region papp_ph_perl matchgroup=Delimiter start="<[:?]" end="[:?]>"me=e-2 nextgroup=papp_ph_html contains=@PAppPerl		     contained keepend
+syn region papp_ph_html matchgroup=Delimiter start=":>"    end="<[:?]"me=e-2 nextgroup=papp_ph_perl contains=@PAppHtml		     contained keepend
+syn region papp_ph_hint matchgroup=Delimiter start="?>"    end="<[:?]"me=e-2 nextgroup=papp_ph_perl contains=@perlInterpDQ,@PAppHtml contained keepend
+syn region papp_ph_xml	matchgroup=Delimiter start=":>"    end="<[:?]"me=e-2 nextgroup=papp_ph_perl contains=			     contained keepend
+syn region papp_ph_xint matchgroup=Delimiter start="?>"    end="<[:?]"me=e-2 nextgroup=papp_ph_perl contains=@perlInterpDQ	     contained keepend
+
+" synchronization is horrors!
+syn sync clear
+syn sync match pappSync grouphere papp_CDATAh "</\(perl\|xperl\|phtml\|macro\|module\)>"
+syn sync match pappSync grouphere papp_CDATAh "^# *\(if\|elsif\|else\|endif\)"
+syn sync match pappSync grouphere papp_CDATAh "</\(tr\|td\|table\|hr\|h1\|h2\|h3\)>"
+syn sync match pappSync grouphere NONE	      "</\=\(module\|state\|macro\)>"
+
+syn sync maxlines=300
+syn sync minlines=5
+
+" The default highlighting.
+
+hi def link papp_prep		preCondit
+hi def link papp_gettext	String
+
+let b:current_syntax = "papp"
--- /dev/null
+++ b/lib/vimfiles/syntax/pascal.vim
@@ -1,0 +1,373 @@
+" Vim syntax file
+" Language:	Pascal
+" Version: 2.8
+" Last Change:	2004/10/17 17:47:30
+" Maintainer:  Xavier Cr�gut <xavier.cregut@enseeiht.fr>
+" Previous Maintainer:	Mario Eusebio <bio@dq.fct.unl.pt>
+
+" Contributors: Tim Chase <tchase@csc.com>,
+"	Stas Grabois <stsi@vtrails.com>,
+"	Mazen NEIFER <mazen.neifer.2001@supaero.fr>,
+"	Klaus Hast <Klaus.Hast@arcor.net>,
+"	Austin Ziegler <austin@halostatue.ca>,
+"	Markus Koenig <markus@stber-koenig.de>
+
+" For version 5.x: Clear all syntax items
+" For version 6.x: Quit when a syntax file was already loaded
+if version < 600
+  syntax clear
+elseif exists("b:current_syntax")
+  finish
+endif
+
+
+syn case ignore
+syn sync lines=250
+
+syn keyword pascalBoolean	true false
+syn keyword pascalConditional	if else then
+syn keyword pascalConstant	nil maxint
+syn keyword pascalLabel		case goto label
+syn keyword pascalOperator	and div downto in mod not of or packed with
+syn keyword pascalRepeat	do for do repeat while to until
+syn keyword pascalStatement	procedure function
+syn keyword pascalStatement	program begin end const var type
+syn keyword pascalStruct	record
+syn keyword pascalType		array boolean char integer file pointer real set
+syn keyword pascalType		string text variant
+
+
+    " 20011222az: Added new items.
+syn keyword pascalTodo contained	TODO FIXME XXX DEBUG NOTE
+
+    " 20010723az: When wanted, highlight the trailing whitespace -- this is
+    " based on c_space_errors; to enable, use "pascal_space_errors".
+if exists("pascal_space_errors")
+    if !exists("pascal_no_trail_space_error")
+        syn match pascalSpaceError "\s\+$"
+    endif
+    if !exists("pascal_no_tab_space_error")
+        syn match pascalSpaceError " \+\t"me=e-1
+    endif
+endif
+
+
+
+" String
+if !exists("pascal_one_line_string")
+  syn region  pascalString matchgroup=pascalString start=+'+ end=+'+ contains=pascalStringEscape
+  if exists("pascal_gpc")
+    syn region  pascalString matchgroup=pascalString start=+"+ end=+"+ contains=pascalStringEscapeGPC
+  else
+    syn region  pascalStringError matchgroup=pascalStringError start=+"+ end=+"+ contains=pascalStringEscape
+  endif
+else
+  "wrong strings
+  syn region  pascalStringError matchgroup=pascalStringError start=+'+ end=+'+ end=+$+ contains=pascalStringEscape
+  if exists("pascal_gpc")
+    syn region  pascalStringError matchgroup=pascalStringError start=+"+ end=+"+ end=+$+ contains=pascalStringEscapeGPC
+  else
+    syn region  pascalStringError matchgroup=pascalStringError start=+"+ end=+"+ end=+$+ contains=pascalStringEscape
+  endif
+
+  "right strings
+  syn region  pascalString matchgroup=pascalString start=+'+ end=+'+ oneline contains=pascalStringEscape
+  " To see the start and end of strings:
+  " syn region  pascalString matchgroup=pascalStringError start=+'+ end=+'+ oneline contains=pascalStringEscape
+  if exists("pascal_gpc")
+    syn region  pascalString matchgroup=pascalString start=+"+ end=+"+ oneline contains=pascalStringEscapeGPC
+  else
+    syn region  pascalStringError matchgroup=pascalStringError start=+"+ end=+"+ oneline contains=pascalStringEscape
+  endif
+end
+syn match   pascalStringEscape		contained "''"
+syn match   pascalStringEscapeGPC	contained '""'
+
+
+" syn match   pascalIdentifier		"\<[a-zA-Z_][a-zA-Z0-9_]*\>"
+
+
+if exists("pascal_symbol_operator")
+  syn match   pascalSymbolOperator      "[+\-/*=]"
+  syn match   pascalSymbolOperator      "[<>]=\="
+  syn match   pascalSymbolOperator      "<>"
+  syn match   pascalSymbolOperator      ":="
+  syn match   pascalSymbolOperator      "[()]"
+  syn match   pascalSymbolOperator      "\.\."
+  syn match   pascalSymbolOperator       "[\^.]"
+  syn match   pascalMatrixDelimiter	"[][]"
+  "if you prefer you can highlight the range
+  "syn match  pascalMatrixDelimiter	"[\d\+\.\.\d\+]"
+endif
+
+syn match  pascalNumber		"-\=\<\d\+\>"
+syn match  pascalFloat		"-\=\<\d\+\.\d\+\>"
+syn match  pascalFloat		"-\=\<\d\+\.\d\+[eE]-\=\d\+\>"
+syn match  pascalHexNumber	"\$[0-9a-fA-F]\+\>"
+
+if exists("pascal_no_tabs")
+  syn match pascalShowTab "\t"
+endif
+
+syn region pascalComment	start="(\*\|{"  end="\*)\|}" contains=pascalTodo,pascalSpaceError
+
+
+if !exists("pascal_no_functions")
+  " array functions
+  syn keyword pascalFunction	pack unpack
+
+  " memory function
+  syn keyword pascalFunction	Dispose New
+
+  " math functions
+  syn keyword pascalFunction	Abs Arctan Cos Exp Ln Sin Sqr Sqrt
+
+  " file functions
+  syn keyword pascalFunction	Eof Eoln Write Writeln
+  syn keyword pascalPredefined	Input Output
+
+  if exists("pascal_traditional")
+    " These functions do not seem to be defined in Turbo Pascal
+    syn keyword pascalFunction	Get Page Put 
+  endif
+
+  " ordinal functions
+  syn keyword pascalFunction	Odd Pred Succ
+
+  " transfert functions
+  syn keyword pascalFunction	Chr Ord Round Trunc
+endif
+
+
+if !exists("pascal_traditional")
+
+  syn keyword pascalStatement	constructor destructor implementation inherited
+  syn keyword pascalStatement	interface unit uses
+  syn keyword pascalModifier	absolute assembler external far forward inline
+  syn keyword pascalModifier	interrupt near virtual 
+  syn keyword pascalAcces	private public 
+  syn keyword pascalStruct	object 
+  syn keyword pascalOperator	shl shr xor
+
+  syn region pascalPreProc	start="(\*\$"  end="\*)" contains=pascalTodo
+  syn region pascalPreProc	start="{\$"  end="}"
+
+  syn region  pascalAsm		matchgroup=pascalAsmKey start="\<asm\>" end="\<end\>" contains=pascalComment,pascalPreProc
+
+  syn keyword pascalType	ShortInt LongInt Byte Word
+  syn keyword pascalType	ByteBool WordBool LongBool
+  syn keyword pascalType	Cardinal LongWord
+  syn keyword pascalType	Single Double Extended Comp
+  syn keyword pascalType	PChar
+
+
+  if !exists ("pascal_fpc")
+    syn keyword pascalPredefined	Result
+  endif
+
+  if exists("pascal_fpc")
+    syn region pascalComment        start="//" end="$" contains=pascalTodo,pascalSpaceError
+    syn keyword pascalStatement	fail otherwise operator
+    syn keyword pascalDirective	popstack
+    syn keyword pascalPredefined self
+    syn keyword pascalType	ShortString AnsiString WideString
+  endif
+
+  if exists("pascal_gpc")
+    syn keyword pascalType	SmallInt
+    syn keyword pascalType	AnsiChar
+    syn keyword pascalType	PAnsiChar
+  endif
+
+  if exists("pascal_delphi")
+    syn region pascalComment	start="//"  end="$" contains=pascalTodo,pascalSpaceError
+    syn keyword pascalType	SmallInt Int64
+    syn keyword pascalType	Real48 Currency
+    syn keyword pascalType	AnsiChar WideChar
+    syn keyword pascalType	ShortString AnsiString WideString
+    syn keyword pascalType	PAnsiChar PWideChar
+    syn match  pascalFloat	"-\=\<\d\+\.\d\+[dD]-\=\d\+\>"
+    syn match  pascalStringEscape	contained "#[12][0-9]\=[0-9]\="
+    syn keyword pascalStruct	class dispinterface
+    syn keyword pascalException	try except raise at on finally
+    syn keyword pascalStatement	out
+    syn keyword pascalStatement	library package 
+    syn keyword pascalStatement	initialization finalization uses exports
+    syn keyword pascalStatement	property out resourcestring threadvar
+    syn keyword pascalModifier	contains
+    syn keyword pascalModifier	overridden reintroduce abstract
+    syn keyword pascalModifier	override export dynamic name message
+    syn keyword pascalModifier	dispid index stored default nodefault readonly
+    syn keyword pascalModifier	writeonly implements overload requires resident
+    syn keyword pascalAcces	protected published automated
+    syn keyword pascalDirective	register pascal cvar cdecl stdcall safecall
+    syn keyword pascalOperator	as is
+  endif
+
+  if exists("pascal_no_functions")
+    "syn keyword pascalModifier	read write
+    "may confuse with Read and Write functions.  Not easy to handle.
+  else
+    " control flow functions
+    syn keyword pascalFunction	Break Continue Exit Halt RunError
+
+    " ordinal functions
+    syn keyword pascalFunction	Dec Inc High Low
+
+    " math functions
+    syn keyword pascalFunction	Frac Int Pi
+
+    " string functions
+    syn keyword pascalFunction	Concat Copy Delete Insert Length Pos Str Val
+
+    " memory function
+    syn keyword pascalFunction	FreeMem GetMem MaxAvail MemAvail
+
+    " pointer and address functions
+    syn keyword pascalFunction	Addr Assigned CSeg DSeg Ofs Ptr Seg SPtr SSeg
+
+    " misc functions
+    syn keyword pascalFunction	Exclude FillChar Hi Include Lo Move ParamCount
+    syn keyword pascalFunction	ParamStr Random Randomize SizeOf Swap TypeOf
+    syn keyword pascalFunction	UpCase
+
+    " predefined variables
+    syn keyword pascalPredefined ErrorAddr ExitCode ExitProc FileMode FreeList
+    syn keyword pascalPredefined FreeZero HeapEnd HeapError HeapOrg HeapPtr
+    syn keyword pascalPredefined InOutRes OvrCodeList OvrDebugPtr OvrDosHandle
+    syn keyword pascalPredefined OvrEmsHandle OvrHeapEnd OvrHeapOrg OvrHeapPtr
+    syn keyword pascalPredefined OvrHeapSize OvrLoadList PrefixSeg RandSeed
+    syn keyword pascalPredefined SaveInt00 SaveInt02 SaveInt1B SaveInt21
+    syn keyword pascalPredefined SaveInt23 SaveInt24 SaveInt34 SaveInt35
+    syn keyword pascalPredefined SaveInt36 SaveInt37 SaveInt38 SaveInt39
+    syn keyword pascalPredefined SaveInt3A SaveInt3B SaveInt3C SaveInt3D
+    syn keyword pascalPredefined SaveInt3E SaveInt3F SaveInt75 SegA000 SegB000
+    syn keyword pascalPredefined SegB800 SelectorInc StackLimit Test8087
+
+    " file functions
+    syn keyword pascalFunction	Append Assign BlockRead BlockWrite ChDir Close
+    syn keyword pascalFunction	Erase FilePos FileSize Flush GetDir IOResult
+    syn keyword pascalFunction	MkDir Read Readln Rename Reset Rewrite RmDir
+    syn keyword pascalFunction	Seek SeekEof SeekEoln SetTextBuf Truncate
+
+    " crt unit
+    syn keyword pascalFunction	AssignCrt ClrEol ClrScr Delay DelLine GotoXY
+    syn keyword pascalFunction	HighVideo InsLine KeyPressed LowVideo NormVideo
+    syn keyword pascalFunction	NoSound ReadKey Sound TextBackground TextColor
+    syn keyword pascalFunction	TextMode WhereX WhereY Window
+    syn keyword pascalPredefined CheckBreak CheckEOF CheckSnow DirectVideo
+    syn keyword pascalPredefined LastMode TextAttr WindMin WindMax
+    syn keyword pascalFunction BigCursor CursorOff CursorOn
+    syn keyword pascalConstant Black Blue Green Cyan Red Magenta Brown
+    syn keyword pascalConstant LightGray DarkGray LightBlue LightGreen
+    syn keyword pascalConstant LightCyan LightRed LightMagenta Yellow White
+    syn keyword pascalConstant Blink ScreenWidth ScreenHeight bw40
+    syn keyword pascalConstant co40 bw80 co80 mono
+    syn keyword pascalPredefined TextChar 
+
+    " DOS unit
+    syn keyword pascalFunction	AddDisk DiskFree DiskSize DosExitCode DosVersion
+    syn keyword pascalFunction	EnvCount EnvStr Exec Expand FindClose FindFirst
+    syn keyword pascalFunction	FindNext FSearch FSplit GetCBreak GetDate
+    syn keyword pascalFunction	GetEnv GetFAttr GetFTime GetIntVec GetTime
+    syn keyword pascalFunction	GetVerify Intr Keep MSDos PackTime SetCBreak
+    syn keyword pascalFunction	SetDate SetFAttr SetFTime SetIntVec SetTime
+    syn keyword pascalFunction	SetVerify SwapVectors UnPackTime
+    syn keyword pascalConstant	FCarry FParity FAuxiliary FZero FSign FOverflow
+    syn keyword pascalConstant	Hidden Sysfile VolumeId Directory Archive
+    syn keyword pascalConstant	AnyFile fmClosed fmInput fmOutput fmInout
+    syn keyword pascalConstant	TextRecNameLength TextRecBufSize
+    syn keyword pascalType	ComStr PathStr DirStr NameStr ExtStr SearchRec
+    syn keyword pascalType	FileRec TextBuf TextRec Registers DateTime
+    syn keyword pascalPredefined DosError
+
+    "Graph Unit
+    syn keyword pascalFunction	Arc Bar Bar3D Circle ClearDevice ClearViewPort
+    syn keyword pascalFunction	CloseGraph DetectGraph DrawPoly Ellipse
+    syn keyword pascalFunction	FillEllipse FillPoly FloodFill GetArcCoords
+    syn keyword pascalFunction	GetAspectRatio GetBkColor GetColor
+    syn keyword pascalFunction	GetDefaultPalette GetDriverName GetFillPattern
+    syn keyword pascalFunction	GetFillSettings GetGraphMode GetImage
+    syn keyword pascalFunction	GetLineSettings GetMaxColor GetMaxMode GetMaxX
+    syn keyword pascalFunction	GetMaxY GetModeName GetModeRange GetPalette
+    syn keyword pascalFunction	GetPaletteSize GetPixel GetTextSettings
+    syn keyword pascalFunction	GetViewSettings GetX GetY GraphDefaults
+    syn keyword pascalFunction	GraphErrorMsg GraphResult ImageSize InitGraph
+    syn keyword pascalFunction	InstallUserDriver InstallUserFont Line LineRel
+    syn keyword pascalFunction	LineTo MoveRel MoveTo OutText OutTextXY
+    syn keyword pascalFunction	PieSlice PutImage PutPixel Rectangle
+    syn keyword pascalFunction	RegisterBGIDriver RegisterBGIFont
+    syn keyword pascalFunction	RestoreCRTMode Sector SetActivePage
+    syn keyword pascalFunction	SetAllPallette SetAspectRatio SetBkColor
+    syn keyword pascalFunction	SetColor SetFillPattern SetFillStyle
+    syn keyword pascalFunction	SetGraphBufSize SetGraphMode SetLineStyle
+    syn keyword pascalFunction	SetPalette SetRGBPalette SetTextJustify
+    syn keyword pascalFunction	SetTextStyle SetUserCharSize SetViewPort
+    syn keyword pascalFunction	SetVisualPage SetWriteMode TextHeight TextWidth
+    syn keyword pascalType	ArcCoordsType FillPatternType FillSettingsType
+    syn keyword pascalType	LineSettingsType PaletteType PointType
+    syn keyword pascalType	TextSettingsType ViewPortType
+
+    " string functions
+    syn keyword pascalFunction	StrAlloc StrBufSize StrCat StrComp StrCopy
+    syn keyword pascalFunction	StrDispose StrECopy StrEnd StrFmt StrIComp
+    syn keyword pascalFunction	StrLCat StrLComp StrLCopy StrLen StrLFmt
+    syn keyword pascalFunction	StrLIComp StrLower StrMove StrNew StrPas
+    syn keyword pascalFunction	StrPCopy StrPLCopy StrPos StrRScan StrScan
+    syn keyword pascalFunction	StrUpper
+  endif
+
+endif
+
+" Define the default highlighting.
+" For version 5.7 and earlier: only when not done already
+" For version 5.8 and later: only when an item doesn't have highlighting yet
+if version >= 508 || !exists("did_pascal_syn_inits")
+  if version < 508
+    let did_pascal_syn_inits = 1
+    command -nargs=+ HiLink hi link <args>
+  else
+    command -nargs=+ HiLink hi def link <args>
+  endif
+
+  HiLink pascalAcces		pascalStatement
+  HiLink pascalBoolean		Boolean
+  HiLink pascalComment		Comment
+  HiLink pascalConditional	Conditional
+  HiLink pascalConstant		Constant
+  HiLink pascalDelimiter	Identifier
+  HiLink pascalDirective	pascalStatement
+  HiLink pascalException	Exception
+  HiLink pascalFloat		Float
+  HiLink pascalFunction		Function
+  HiLink pascalLabel		Label
+  HiLink pascalMatrixDelimiter	Identifier
+  HiLink pascalModifier		Type
+  HiLink pascalNumber		Number
+  HiLink pascalOperator		Operator
+  HiLink pascalPredefined	pascalStatement
+  HiLink pascalPreProc		PreProc
+  HiLink pascalRepeat		Repeat
+  HiLink pascalSpaceError	Error
+  HiLink pascalStatement	Statement
+  HiLink pascalString		String
+  HiLink pascalStringEscape	Special
+  HiLink pascalStringEscapeGPC	Special
+  HiLink pascalStringError	Error
+  HiLink pascalStruct		pascalStatement
+  HiLink pascalSymbolOperator	pascalOperator
+  HiLink pascalTodo		Todo
+  HiLink pascalType		Type
+  HiLink pascalUnclassified	pascalStatement
+  "  HiLink pascalAsm		Assembler
+  HiLink pascalError		Error
+  HiLink pascalAsmKey		pascalStatement
+  HiLink pascalShowTab		Error
+
+  delcommand HiLink
+endif
+
+
+let b:current_syntax = "pascal"
+
+" vim: ts=8 sw=2
--- /dev/null
+++ b/lib/vimfiles/syntax/passwd.vim
@@ -1,0 +1,71 @@
+" Vim syntax file
+" Language:         passwd(5) password file
+" Maintainer:       Nikolai Weibull <now@bitwi.se>
+" Latest Revision:  2006-10-03
+
+if exists("b:current_syntax")
+  finish
+endif
+
+let s:cpo_save = &cpo
+set cpo&vim
+
+syn match   passwdBegin         display '^' nextgroup=passwdAccount
+
+syn match   passwdAccount       contained display '[^:]\+'
+                                \ nextgroup=passwdPasswordColon
+
+syn match   passwdPasswordColon contained display ':'
+                                \ nextgroup=passwdPassword,passwdShadow
+
+syn match   passwdPassword      contained display '[^:]\+'
+                                \ nextgroup=passwdUIDColon
+
+syn match   passwdShadow        contained display '[x*!]'
+                                \ nextgroup=passwdUIDColon
+
+syn match   passwdUIDColon      contained display ':' nextgroup=passwdUID
+
+syn match   passwdUID           contained display '\d\{0,10}'
+                                \ nextgroup=passwdGIDColon
+
+syn match   passwdGIDColon      contained display ':' nextgroup=passwdGID
+
+syn match   passwdGID           contained display '\d\{0,10}'
+                                \ nextgroup=passwdGecosColon
+
+syn match   passwdGecosColon    contained display ':' nextgroup=passwdGecos
+
+syn match   passwdGecos         contained display '[^:]*'
+                                \ nextgroup=passwdDirColon
+
+syn match   passwdDirColon      contained display ':' nextgroup=passwdDir
+
+syn match   passwdDir           contained display '/[^:]*'
+                                \ nextgroup=passwdShellColon
+
+syn match   passwdShellColon    contained display ':'
+                                \ nextgroup=passwdShell
+
+syn match   passwdShell         contained display '.*'
+
+hi def link passwdColon         Normal
+hi def link passwdAccount       Identifier
+hi def link passwdPasswordColon passwdColon
+hi def link passwdPassword      Number
+hi def link passwdShadow        Special
+hi def link passwdUIDColon      passwdColon
+hi def link passwdUID           Number
+hi def link passwdGIDColon      passwdColon
+hi def link passwdGID           Number
+hi def link passwdGecosColon    passwdColon
+hi def link passwdGecos         Comment
+hi def link passwdDirColon      passwdColon
+hi def link passwdDir           Type
+hi def link passwdShellColon    passwdColon
+hi def link passwdShell         Operator
+
+let b:current_syntax = "passwd"
+
+let &cpo = s:cpo_save
+unlet s:cpo_save
--- /dev/null
+++ b/lib/vimfiles/syntax/pcap.vim
@@ -1,0 +1,65 @@
+" Vim syntax file
+" Config file:	printcap
+" Maintainer:	Lennart Schultz <Lennart.Schultz@ecmwf.int> (defunct)
+"		Modified by Bram
+" Last Change:	2003 May 11
+
+" For version 5.x: Clear all syntax items
+" For version 6.x: Quit when a syntax file was already loaded
+if version < 600
+  syntax clear
+elseif exists("b:current_syntax")
+  finish
+endif
+
+"define keywords
+if version < 600
+  set isk=@,46-57,_,-,#,=,192-255
+else
+  setlocal isk=@,46-57,_,-,#,=,192-255
+endif
+
+"first all the bad guys
+syn match pcapBad '^.\+$'	       "define any line as bad
+syn match pcapBadword '\k\+' contained "define any sequence of keywords as bad
+syn match pcapBadword ':' contained    "define any single : as bad
+syn match pcapBadword '\\' contained   "define any single \ as bad
+"then the good boys
+" Boolean keywords
+syn match pcapKeyword contained ':\(fo\|hl\|ic\|rs\|rw\|sb\|sc\|sf\|sh\)'
+" Numeric Keywords
+syn match pcapKeyword contained ':\(br\|du\|fc\|fs\|mx\|pc\|pl\|pw\|px\|py\|xc\|xs\)#\d\+'
+" String Keywords
+syn match pcapKeyword contained ':\(af\|cf\|df\|ff\|gf\|if\|lf\|lo\|lp\|nd\|nf\|of\|rf\|rg\|rm\|rp\|sd\|st\|tf\|tr\|vf\)=\k*'
+" allow continuation
+syn match pcapEnd ':\\$' contained
+"
+syn match pcapDefineLast '^\s.\+$' contains=pcapBadword,pcapKeyword
+syn match pcapDefine '^\s.\+$' contains=pcapBadword,pcapKeyword,pcapEnd
+syn match pcapHeader '^\k[^|]\+\(|\k[^|]\+\)*:\\$'
+syn match pcapComment "#.*$"
+
+syn sync minlines=50
+
+
+" Define the default highlighting.
+" For version 5.7 and earlier: only when not done already
+" For version 5.8 and later: only when an item doesn't have highlighting yet
+if version >= 508 || !exists("did_pcap_syntax_inits")
+  if version < 508
+    let did_pcap_syntax_inits = 1
+    command -nargs=+ HiLink hi link <args>
+  else
+    command -nargs=+ HiLink hi def link <args>
+  endif
+
+  HiLink pcapBad WarningMsg
+  HiLink pcapBadword WarningMsg
+  HiLink pcapComment Comment
+
+  delcommand HiLink
+endif
+
+let b:current_syntax = "pcap"
+
+" vim: ts=8
--- /dev/null
+++ b/lib/vimfiles/syntax/pccts.vim
@@ -1,0 +1,106 @@
+" Vim syntax file
+" Language:	PCCTS
+" Maintainer:	Scott Bigham <dsb@killerbunnies.org>
+" Last Change:	10 Aug 1999
+
+" For version 5.x: Clear all syntax items
+" For version 6.x: Quit when a syntax file was already loaded
+if version < 600
+  syntax clear
+elseif exists("b:current_syntax")
+  finish
+endif
+
+" Read the C++ syntax to start with
+if version < 600
+  syn include @cppTopLevel <sfile>:p:h/cpp.vim
+else
+  syn include @cppTopLevel syntax/cpp.vim
+endif
+
+syn region pcctsAction matchgroup=pcctsDelim start="<<" end=">>?\=" contains=@cppTopLevel,pcctsRuleRef
+
+syn region pcctsArgBlock matchgroup=pcctsDelim start="\(>\s*\)\=\[" end="\]" contains=@cppTopLevel,pcctsRuleRef
+
+syn region pcctsString start=+"+ skip=+\\\\\|\\"+ end=+"+ contains=pcctsSpecialChar
+syn match  pcctsSpecialChar "\\\\\|\\\"" contained
+
+syn region pcctsComment start="/\*" end="\*/" contains=cTodo
+syn match  pcctsComment "//.*$" contains=cTodo
+
+syn region pcctsDirective start="^\s*#header\s\+<<" end=">>" contains=pcctsAction keepend
+syn match  pcctsDirective "^\s*#parser\>.*$" contains=pcctsString,pcctsComment
+syn match  pcctsDirective "^\s*#tokdefs\>.*$" contains=pcctsString,pcctsComment
+syn match  pcctsDirective "^\s*#token\>.*$" contains=pcctsString,pcctsAction,pcctsTokenName,pcctsComment
+syn region pcctsDirective start="^\s*#tokclass\s\+[A-Z]\i*\s\+{" end="}" contains=pcctsString,pcctsTokenName
+syn match  pcctsDirective "^\s*#lexclass\>.*$" contains=pcctsTokenName
+syn region pcctsDirective start="^\s*#errclass\s\+[^{]\+\s\+{" end="}" contains=pcctsString,pcctsTokenName
+syn match pcctsDirective "^\s*#pred\>.*$" contains=pcctsTokenName,pcctsAction
+
+syn cluster pcctsInRule contains=pcctsString,pcctsRuleName,pcctsTokenName,pcctsAction,pcctsArgBlock,pcctsSubRule,pcctsLabel,pcctsComment
+
+syn region pcctsRule start="\<[a-z][A-Za-z0-9_]*\>\(\s*\[[^]]*\]\)\=\(\s*>\s*\[[^]]*\]\)\=\s*:" end=";" contains=@pcctsInRule
+
+syn region pcctsSubRule matchgroup=pcctsDelim start="(" end=")\(+\|\*\|?\(\s*=>\)\=\)\=" contains=@pcctsInRule contained
+syn region pcctsSubRule matchgroup=pcctsDelim start="{" end="}" contains=@pcctsInRule contained
+
+syn match pcctsRuleName  "\<[a-z]\i*\>" contained
+syn match pcctsTokenName "\<[A-Z]\i*\>" contained
+
+syn match pcctsLabel "\<\I\i*:\I\i*" contained contains=pcctsLabelHack,pcctsRuleName,pcctsTokenName
+syn match pcctsLabel "\<\I\i*:\"\([^\\]\|\\.\)*\"" contained contains=pcctsLabelHack,pcctsString
+syn match pcctsLabelHack "\<\I\i*:" contained
+
+syn match pcctsRuleRef "\$\I\i*\>" contained
+syn match pcctsRuleRef "\$\d\+\(\.\d\+\)\>" contained
+
+syn keyword pcctsClass     class   nextgroup=pcctsClassName skipwhite
+syn match   pcctsClassName "\<\I\i*\>" contained nextgroup=pcctsClassBlock skipwhite skipnl
+syn region pcctsClassBlock start="{" end="}" contained contains=pcctsRule,pcctsComment,pcctsDirective,pcctsAction,pcctsException,pcctsExceptionHandler
+
+syn keyword pcctsException exception nextgroup=pcctsExceptionRuleRef skipwhite
+syn match pcctsExceptionRuleRef "\[\I\i*\]" contained contains=pcctsExceptionID
+syn match pcctsExceptionID "\I\i*" contained
+syn keyword pcctsExceptionHandler	catch default
+syn keyword pcctsExceptionHandler	NoViableAlt NoSemViableAlt
+syn keyword pcctsExceptionHandler	MismatchedToken
+
+syn sync clear
+syn sync match pcctsSyncAction grouphere pcctsAction "<<"
+syn sync match pcctsSyncAction "<<\([^>]\|>[^>]\)*>>"
+syn sync match pcctsSyncRule grouphere pcctsRule "\<[a-z][A-Za-z0-9_]*\>\s*\[[^]]*\]\s*:"
+syn sync match pcctsSyncRule grouphere pcctsRule "\<[a-z][A-Za-z0-9_]*\>\(\s*\[[^]]*\]\)\=\s*>\s*\[[^]]*\]\s*:"
+
+" Define the default highlighting.
+" For version 5.7 and earlier: only when not done already
+" For version 5.8 and later: only when an item doesn't have highlighting yet
+if version >= 508 || !exists("did_pccts_syntax_inits")
+  if version < 508
+    let did_pccts_syntax_inits = 1
+    command -nargs=+ HiLink hi link <args>
+  else
+    command -nargs=+ HiLink hi def link <args>
+  endif
+
+  HiLink pcctsDelim		Special
+  HiLink pcctsTokenName		Identifier
+  HiLink pcctsRuleName		Statement
+  HiLink pcctsLabelHack		Label
+  HiLink pcctsDirective		PreProc
+  HiLink pcctsString		String
+  HiLink pcctsComment		Comment
+  HiLink pcctsClass		Statement
+  HiLink pcctsClassName		Identifier
+  HiLink pcctsException		Statement
+  HiLink pcctsExceptionHandler	Keyword
+  HiLink pcctsExceptionRuleRef	pcctsDelim
+  HiLink pcctsExceptionID	Identifier
+  HiLink pcctsRuleRef		Identifier
+  HiLink pcctsSpecialChar	SpecialChar
+
+  delcommand HiLink
+endif
+
+let b:current_syntax = "pccts"
+
+" vim: ts=8
--- /dev/null
+++ b/lib/vimfiles/syntax/perl.vim
@@ -1,0 +1,562 @@
+" Vim syntax file
+" Language:	Perl
+" Maintainer:	Nick Hibma <nick@van-laarhoven.org>
+" Last Change:	2006 November 23
+" Location:	http://www.van-laarhoven.org/vim/syntax/perl.vim
+"
+" Please download most recent version first before mailing
+" any comments.
+" See also the file perl.vim.regression.pl to check whether your
+" modifications work in the most odd cases
+" http://www.van-laarhoven.org/vim/syntax/perl.vim.regression.pl
+"
+" Original version: Sonia Heimann <niania@netsurf.org>
+" Thanks to many people for their contribution.
+
+" The following parameters are available for tuning the
+" perl syntax highlighting, with defaults given:
+"
+" unlet perl_include_pod
+" unlet perl_want_scope_in_variables
+" unlet perl_extended_vars
+" unlet perl_string_as_statement
+" unlet perl_no_sync_on_sub
+" unlet perl_no_sync_on_global_var
+" let perl_sync_dist = 100
+" unlet perl_fold
+" unlet perl_fold_blocks
+" let perl_nofold_packages = 1
+" let perl_nofold_subs = 1
+
+" Remove any old syntax stuff that was loaded (5.x) or quit when a syntax file
+" was already loaded (6.x).
+if version < 600
+  syntax clear
+elseif exists("b:current_syntax")
+  finish
+endif
+
+" Unset perl_fold if it set but vim doesn't support it.
+if version < 600 && exists("perl_fold")
+  unlet perl_fold
+endif
+
+
+" POD starts with ^=<word> and ends with ^=cut
+
+if exists("perl_include_pod")
+  " Include a while extra syntax file
+  syn include @Pod syntax/pod.vim
+  unlet b:current_syntax
+  if exists("perl_fold")
+    syn region perlPOD start="^=[a-z]" end="^=cut" contains=@Pod,@Spell,perlTodo keepend fold
+    syn region perlPOD start="^=cut" end="^=cut" contains=perlTodo keepend fold
+  else
+    syn region perlPOD start="^=[a-z]" end="^=cut" contains=@Pod,@Spell,perlTodo keepend
+    syn region perlPOD start="^=cut" end="^=cut" contains=perlTodo keepend
+  endif
+else
+  " Use only the bare minimum of rules
+  if exists("perl_fold")
+    syn region perlPOD start="^=[a-z]" end="^=cut" fold
+  else
+    syn region perlPOD start="^=[a-z]" end="^=cut"
+  endif
+endif
+
+
+" All keywords
+"
+if exists("perl_fold") && exists("perl_fold_blocks")
+  syn match perlConditional		"\<if\>"
+  syn match perlConditional		"\<elsif\>"
+  syn match perlConditional		"\<unless\>"
+  syn match perlConditional		"\<else\>" nextgroup=perlElseIfError skipwhite skipnl skipempty
+else
+  syn keyword perlConditional		if elsif unless
+  syn keyword perlConditional		else nextgroup=perlElseIfError skipwhite skipnl skipempty
+endif
+syn keyword perlConditional		switch eq ne gt lt ge le cmp not and or xor err
+if exists("perl_fold") && exists("perl_fold_blocks")
+  syn match perlRepeat			"\<while\>"
+  syn match perlRepeat			"\<for\>"
+  syn match perlRepeat			"\<foreach\>"
+  syn match perlRepeat			"\<do\>"
+  syn match perlRepeat			"\<until\>"
+  syn match perlRepeat			"\<continue\>"
+else
+  syn keyword perlRepeat		while for foreach do until continue
+endif
+syn keyword perlOperator		defined undef and or not bless ref
+if exists("perl_fold")
+  " if BEGIN/END would be a keyword the perlBEGINENDFold does not work
+  syn match perlControl			"\<BEGIN\|CHECK\|INIT\|END\>" contained
+else
+  syn keyword perlControl		BEGIN END CHECK INIT
+endif
+
+syn keyword perlStatementStorage	my local our
+syn keyword perlStatementControl	goto return last next redo
+syn keyword perlStatementScalar		chomp chop chr crypt index lc lcfirst length ord pack reverse rindex sprintf substr uc ucfirst
+syn keyword perlStatementRegexp		pos quotemeta split study
+syn keyword perlStatementNumeric	abs atan2 cos exp hex int log oct rand sin sqrt srand
+syn keyword perlStatementList		splice unshift shift push pop split join reverse grep map sort unpack
+syn keyword perlStatementHash		each exists keys values tie tied untie
+syn keyword perlStatementIOfunc		carp confess croak dbmclose dbmopen die syscall
+syn keyword perlStatementFiledesc	binmode close closedir eof fileno getc lstat print printf readdir readline readpipe rewinddir select stat tell telldir write nextgroup=perlFiledescStatementNocomma skipwhite
+syn keyword perlStatementFiledesc	fcntl flock ioctl open opendir read seek seekdir sysopen sysread sysseek syswrite truncate nextgroup=perlFiledescStatementComma skipwhite
+syn keyword perlStatementVector		pack vec
+syn keyword perlStatementFiles		chdir chmod chown chroot glob link mkdir readlink rename rmdir symlink umask unlink utime
+syn match   perlStatementFiles		"-[rwxoRWXOezsfdlpSbctugkTBMAC]\>"
+syn keyword perlStatementFlow		caller die dump eval exit wantarray
+syn keyword perlStatementInclude	require
+syn match   perlStatementInclude	"\<\(use\|no\)\s\+\(\(integer\|strict\|lib\|sigtrap\|subs\|vars\|warnings\|utf8\|byte\|base\|fields\)\>\)\="
+syn keyword perlStatementScope		import
+syn keyword perlStatementProc		alarm exec fork getpgrp getppid getpriority kill pipe setpgrp setpriority sleep system times wait waitpid
+syn keyword perlStatementSocket		accept bind connect getpeername getsockname getsockopt listen recv send setsockopt shutdown socket socketpair
+syn keyword perlStatementIPC		msgctl msgget msgrcv msgsnd semctl semget semop shmctl shmget shmread shmwrite
+syn keyword perlStatementNetwork	endhostent endnetent endprotoent endservent gethostbyaddr gethostbyname gethostent getnetbyaddr getnetbyname getnetent getprotobyname getprotobynumber getprotoent getservbyname getservbyport getservent sethostent setnetent setprotoent setservent
+syn keyword perlStatementPword		getpwuid getpwnam getpwent setpwent endpwent getgrent getgrgid getlogin getgrnam setgrent endgrent
+syn keyword perlStatementTime		gmtime localtime time times
+
+syn keyword perlStatementMisc		warn formline reset scalar delete prototype lock
+syn keyword perlStatementNew		new
+
+syn keyword perlTodo			TODO TBD FIXME XXX contained
+
+" Perl Identifiers.
+"
+" Should be cleaned up to better handle identifiers in particular situations
+" (in hash keys for example)
+"
+" Plain identifiers: $foo, @foo, $#foo, %foo, &foo and dereferences $$foo, @$foo, etc.
+" We do not process complex things such as @{${"foo"}}. Too complicated, and
+" too slow. And what is after the -> is *not* considered as part of the
+" variable - there again, too complicated and too slow.
+
+" Special variables first ($^A, ...) and ($|, $', ...)
+syn match  perlVarPlain		 "$^[ADEFHILMOPSTWX]\="
+syn match  perlVarPlain		 "$[\\\"\[\]'&`+*.,;=%~!?@#$<>(-]"
+syn match  perlVarPlain		 "$\(0\|[1-9][0-9]*\)"
+" Same as above, but avoids confusion in $::foo (equivalent to $main::foo)
+syn match  perlVarPlain		 "$:[^:]"
+" These variables are not recognized within matches.
+syn match  perlVarNotInMatches	 "$[|)]"
+" This variable is not recognized within matches delimited by m//.
+syn match  perlVarSlash		 "$/"
+
+" And plain identifiers
+syn match  perlPackageRef	 "\(\h\w*\)\=\(::\|'\)\I"me=e-1 contained
+
+" To highlight packages in variables as a scope reference - i.e. in $pack::var,
+" pack:: is a scope, just set "perl_want_scope_in_variables"
+" If you *want* complex things like @{${"foo"}} to be processed,
+" just set the variable "perl_extended_vars"...
+
+" FIXME value between {} should be marked as string. is treated as such by Perl.
+" At the moment it is marked as something greyish instead of read. Probably todo
+" with transparency. Or maybe we should handle the bare word in that case. or make it into
+
+if exists("perl_want_scope_in_variables")
+  syn match  perlVarPlain	"\\\=\([@$]\|\$#\)\$*\(\I\i*\)\=\(\(::\|'\)\I\i*\)*\>" contains=perlPackageRef nextgroup=perlVarMember,perlVarSimpleMember,perlMethod
+  syn match  perlVarPlain2	"\\\=%\$*\(\I\i*\)\=\(\(::\|'\)\I\i*\)*\>" contains=perlPackageRef nextgroup=perlVarMember,perlVarSimpleMember,perlMethod
+  syn match  perlFunctionName	"\\\=&\$*\(\I\i*\)\=\(\(::\|'\)\I\i*\)*\>" contains=perlPackageRef nextgroup=perlVarMember,perlVarSimpleMember
+else
+  syn match  perlVarPlain	"\\\=\([@$]\|\$#\)\$*\(\I\i*\)\=\(\(::\|'\)\I\i*\)*\>" nextgroup=perlVarMember,perlVarSimpleMember,perlMethod
+  syn match  perlVarPlain2	"\\\=%\$*\(\I\i*\)\=\(\(::\|'\)\I\i*\)*\>" nextgroup=perlVarMember,perlVarSimpleMember,perlMethod
+  syn match  perlFunctionName	"\\\=&\$*\(\I\i*\)\=\(\(::\|'\)\I\i*\)*\>" nextgroup=perlVarMember,perlVarSimpleMember
+endif
+
+if exists("perl_extended_vars")
+  syn cluster perlExpr		contains=perlStatementScalar,perlStatementRegexp,perlStatementNumeric,perlStatementList,perlStatementHash,perlStatementFiles,perlStatementTime,perlStatementMisc,perlVarPlain,perlVarPlain2,perlVarNotInMatches,perlVarSlash,perlVarBlock,perlShellCommand,perlFloat,perlNumber,perlStringUnexpanded,perlString,perlQQ
+  syn region perlVarBlock	matchgroup=perlVarPlain start="\($#\|[@%$]\)\$*{" skip="\\}" end="}" contains=@perlExpr nextgroup=perlVarMember,perlVarSimpleMember
+  syn region perlVarBlock	matchgroup=perlVarPlain start="&\$*{" skip="\\}" end="}" contains=@perlExpr
+  syn match  perlVarPlain	"\\\=\(\$#\|[@%&$]\)\$*{\I\i*}" nextgroup=perlVarMember,perlVarSimpleMember
+  syn region perlVarMember	matchgroup=perlVarPlain start="\(->\)\={" skip="\\}" end="}" contained contains=@perlExpr nextgroup=perlVarMember,perlVarSimpleMember
+  syn match  perlVarSimpleMember	"\(->\)\={\I\i*}" nextgroup=perlVarMember,perlVarSimpleMember contains=perlVarSimpleMemberName contained
+  syn match  perlVarSimpleMemberName	"\I\i*" contained
+  syn region perlVarMember	matchgroup=perlVarPlain start="\(->\)\=\[" skip="\\]" end="]" contained contains=@perlExpr nextgroup=perlVarMember,perlVarSimpleMember
+  syn match  perlMethod		"\(->\)\I\i*" contained
+endif
+
+" File Descriptors
+syn match  perlFiledescRead	"[<]\h\w\+[>]"
+
+syn match  perlFiledescStatementComma	"(\=\s*\u\w*\s*,"me=e-1 transparent contained contains=perlFiledescStatement
+syn match  perlFiledescStatementNocomma "(\=\s*\u\w*\s*[^, \t]"me=e-1 transparent contained contains=perlFiledescStatement
+
+syn match  perlFiledescStatement	"\u\w*" contained
+
+" Special characters in strings and matches
+syn match  perlSpecialString	"\\\(\d\+\|[xX]\x\+\|c\u\|.\)" contained
+syn match  perlSpecialStringU	"\\['\\]" contained
+syn match  perlSpecialMatch	"{\d\+\(,\(\d\+\)\=\)\=}" contained
+syn match  perlSpecialMatch	"\[\(\]\|-\)\=[^\[\]]*\(\[\|\-\)\=\]" contained
+syn match  perlSpecialMatch	"[+*()?.]" contained
+syn match  perlSpecialMatch	"(?[#:=!]" contained
+syn match  perlSpecialMatch	"(?[imsx]\+)" contained
+" FIXME the line below does not work. It should mark end of line and
+" begin of line as perlSpecial.
+" syn match perlSpecialBEOM    "^\^\|\$$" contained
+
+" Possible errors
+"
+" Highlight lines with only whitespace (only in blank delimited here documents) as errors
+syn match  perlNotEmptyLine	"^\s\+$" contained
+" Highlight '} else if (...) {', it should be '} else { if (...) { ' or
+" '} elsif (...) {'.
+"syn keyword perlElseIfError	if contained
+
+" Variable interpolation
+"
+" These items are interpolated inside "" strings and similar constructs.
+syn cluster perlInterpDQ	contains=perlSpecialString,perlVarPlain,perlVarNotInMatches,perlVarSlash,perlVarBlock
+" These items are interpolated inside '' strings and similar constructs.
+syn cluster perlInterpSQ	contains=perlSpecialStringU
+" These items are interpolated inside m// matches and s/// substitutions.
+syn cluster perlInterpSlash	contains=perlSpecialString,perlSpecialMatch,perlVarPlain,perlVarBlock,perlSpecialBEOM
+" These items are interpolated inside m## matches and s### substitutions.
+syn cluster perlInterpMatch	contains=@perlInterpSlash,perlVarSlash
+
+" Shell commands
+syn region  perlShellCommand	matchgroup=perlMatchStartEnd start="`" end="`" contains=@perlInterpDQ
+
+" Constants
+"
+" Numbers
+syn match  perlNumber	"[-+]\=\(\<\d[[:digit:]_]*L\=\>\|0[xX]\x[[:xdigit:]_]*\>\)"
+syn match  perlFloat	"[-+]\=\<\d[[:digit:]_]*[eE][\-+]\=\d\+"
+syn match  perlFloat	"[-+]\=\<\d[[:digit:]_]*\.[[:digit:]_]*\([eE][\-+]\=\d\+\)\="
+syn match  perlFloat	"[-+]\=\<\.[[:digit:]_]\+\([eE][\-+]\=\d\+\)\="
+
+
+" Simple version of searches and matches
+" caters for m//, m##, m{} and m[] (and the !/ variant)
+syn region perlMatch	matchgroup=perlMatchStartEnd start=+[m!]/+ end=+/[cgimosx]*+ contains=@perlInterpSlash
+syn region perlMatch	matchgroup=perlMatchStartEnd start=+[m!]#+ end=+#[cgimosx]*+ contains=@perlInterpMatch
+syn region perlMatch	matchgroup=perlMatchStartEnd start=+[m!]{+ end=+}[cgimosx]*+ contains=@perlInterpMatch
+syn region perlMatch	matchgroup=perlMatchStartEnd start=+[m!]\[+ end=+\][cgimosx]*+ contains=@perlInterpMatch
+
+" A special case for m!!x which allows for comments and extra whitespace in the pattern
+syn region perlMatch	matchgroup=perlMatchStartEnd start=+[m!]!+ end=+![cgimosx]*+ contains=@perlInterpSlash,perlComment
+
+" Below some hacks to recognise the // variant. This is virtually impossible to catch in all
+" cases as the / is used in so many other ways, but these should be the most obvious ones.
+syn region perlMatch	matchgroup=perlMatchStartEnd start=+^split /+lc=5 start=+[^$@%]\<split /+lc=6 start=+^while /+lc=5 start=+[^$@%]\<while /+lc=6 start=+^if /+lc=2 start=+[^$@%]\<if /+lc=3 start=+[!=]\~\s*/+lc=2 start=+[(~]/+lc=1 start=+\.\./+lc=2 start=+\s/[^= \t0-9$@%]+lc=1,me=e-1,rs=e-1 start=+^/+ skip=+\\/+ end=+/[cgimosx]*+ contains=@perlInterpSlash
+
+
+" Substitutions
+" caters for s///, s### and s[][]
+" perlMatch is the first part, perlSubstitution* is the substitution part
+syn region perlMatch	matchgroup=perlMatchStartEnd start=+\<s'+  end=+'+me=e-1 contains=@perlInterpSQ nextgroup=perlSubstitutionSQ
+syn region perlMatch	matchgroup=perlMatchStartEnd start=+\<s"+  end=+"+me=e-1 contains=@perlInterpMatch nextgroup=perlSubstitutionDQ
+syn region perlMatch	matchgroup=perlMatchStartEnd start=+\<s/+  end=+/+me=e-1 contains=@perlInterpSlash nextgroup=perlSubstitutionSlash
+syn region perlMatch	matchgroup=perlMatchStartEnd start=+\<s#+  end=+#+me=e-1 contains=@perlInterpMatch nextgroup=perlSubstitutionHash
+syn region perlMatch	matchgroup=perlMatchStartEnd start=+\<s\[+ end=+\]+ contains=@perlInterpMatch nextgroup=perlSubstitutionBracket skipwhite skipempty skipnl
+syn region perlMatch	matchgroup=perlMatchStartEnd start=+\<s{+ end=+}+ contains=@perlInterpMatch nextgroup=perlSubstitutionCurly skipwhite skipempty skipnl
+syn region perlSubstitutionSQ		matchgroup=perlMatchStartEnd start=+'+  end=+'[ecgimosx]*+ contained contains=@perlInterpSQ
+syn region perlSubstitutionDQ		matchgroup=perlMatchStartEnd start=+"+  end=+"[ecgimosx]*+ contained contains=@perlInterpDQ
+syn region perlSubstitutionSlash	matchgroup=perlMatchStartEnd start=+/+  end=+/[ecgimosx]*+ contained contains=@perlInterpDQ
+syn region perlSubstitutionHash		matchgroup=perlMatchStartEnd start=+#+  end=+#[ecgimosx]*+ contained contains=@perlInterpDQ
+syn region perlSubstitutionBracket	matchgroup=perlMatchStartEnd start=+\[+ end=+\][ecgimosx]*+ contained contains=@perlInterpDQ
+syn region perlSubstitutionCurly	matchgroup=perlMatchStartEnd start=+{+  end=+}[ecgimosx]*+ contained contains=@perlInterpDQ
+
+" A special case for m!!x which allows for comments and extra whitespace in the pattern
+syn region perlMatch	matchgroup=perlMatchStartEnd start=+\<s!+ end=+!+me=e-1 contains=@perlInterpSlash,perlComment nextgroup=perlSubstitutionPling
+syn region perlSubstitutionPling	matchgroup=perlMatchStartEnd start=+!+ end=+![ecgimosx]*+ contained contains=@perlInterpDQ
+
+" Substitutions
+" caters for tr///, tr### and tr[][]
+" perlMatch is the first part, perlTranslation* is the second, translator part.
+syn region perlMatch	matchgroup=perlMatchStartEnd start=+\<\(tr\|y\)'+ end=+'+me=e-1 contains=@perlInterpSQ nextgroup=perlTranslationSQ
+syn region perlMatch	matchgroup=perlMatchStartEnd start=+\<\(tr\|y\)"+ end=+"+me=e-1 contains=@perlInterpSQ nextgroup=perlTranslationDQ
+syn region perlMatch	matchgroup=perlMatchStartEnd start=+\<\(tr\|y\)/+ end=+/+me=e-1 contains=@perlInterpSQ nextgroup=perlTranslationSlash
+syn region perlMatch	matchgroup=perlMatchStartEnd start=+\<\(tr\|y\)#+ end=+#+me=e-1 contains=@perlInterpSQ nextgroup=perlTranslationHash
+syn region perlMatch	matchgroup=perlMatchStartEnd start=+\<\(tr\|y\)\[+ end=+\]+ contains=@perlInterpSQ nextgroup=perlTranslationBracket skipwhite skipempty skipnl
+syn region perlMatch	matchgroup=perlMatchStartEnd start=+\<\(tr\|y\){+ end=+}+ contains=@perlInterpSQ nextgroup=perlTranslationCurly skipwhite skipempty skipnl
+syn region perlTranslationSQ		matchgroup=perlMatchStartEnd start=+'+ end=+'[cds]*+ contained
+syn region perlTranslationDQ		matchgroup=perlMatchStartEnd start=+"+ end=+"[cds]*+ contained
+syn region perlTranslationSlash		matchgroup=perlMatchStartEnd start=+/+ end=+/[cds]*+ contained
+syn region perlTranslationHash		matchgroup=perlMatchStartEnd start=+#+ end=+#[cds]*+ contained
+syn region perlTranslationBracket	matchgroup=perlMatchStartEnd start=+\[+ end=+\][cds]*+ contained
+syn region perlTranslationCurly		matchgroup=perlMatchStartEnd start=+{+ end=+}[cds]*+ contained
+
+
+" The => operator forces a bareword to the left of it to be interpreted as
+" a string
+syn match  perlString "\<\I\i*\s*=>"me=e-2
+
+" Strings and q, qq, qw and qr expressions
+
+" Brackets in qq()
+syn region perlBrackets	start=+(+ end=+)+ contained transparent contains=perlBrackets,@perlStringSQ
+
+syn region perlStringUnexpanded	matchgroup=perlStringStartEnd start="'" end="'" contains=@perlInterpSQ
+syn region perlString		matchgroup=perlStringStartEnd start=+"+  end=+"+ contains=@perlInterpDQ
+syn region perlQQ		matchgroup=perlStringStartEnd start=+\<q#+ end=+#+ contains=@perlInterpSQ
+syn region perlQQ		matchgroup=perlStringStartEnd start=+\<q|+ end=+|+ contains=@perlInterpSQ
+syn region perlQQ		matchgroup=perlStringStartEnd start=+\<q(+ end=+)+ contains=@perlInterpSQ,perlBrackets
+syn region perlQQ		matchgroup=perlStringStartEnd start=+\<q{+ end=+}+ contains=@perlInterpSQ
+syn region perlQQ		matchgroup=perlStringStartEnd start=+\<q/+ end=+/+ contains=@perlInterpSQ
+syn region perlQQ		matchgroup=perlStringStartEnd start=+\<q[qx]#+ end=+#+ contains=@perlInterpDQ
+syn region perlQQ		matchgroup=perlStringStartEnd start=+\<q[qx]|+ end=+|+ contains=@perlInterpDQ
+syn region perlQQ		matchgroup=perlStringStartEnd start=+\<q[qx](+ end=+)+ contains=@perlInterpDQ,perlBrackets
+syn region perlQQ		matchgroup=perlStringStartEnd start=+\<q[qx]{+ end=+}+ contains=@perlInterpDQ
+syn region perlQQ		matchgroup=perlStringStartEnd start=+\<q[qx]/+ end=+/+ contains=@perlInterpDQ
+syn region perlQQ		matchgroup=perlStringStartEnd start=+\<qw#+  end=+#+ contains=@perlInterpSQ
+syn region perlQQ		matchgroup=perlStringStartEnd start=+\<qw|+  end=+|+ contains=@perlInterpSQ
+syn region perlQQ		matchgroup=perlStringStartEnd start=+\<qw(+  end=+)+ contains=@perlInterpSQ,perlBrackets
+syn region perlQQ		matchgroup=perlStringStartEnd start=+\<qw{+  end=+}+ contains=@perlInterpSQ
+syn region perlQQ		matchgroup=perlStringStartEnd start=+\<qw/+  end=+/+ contains=@perlInterpSQ
+syn region perlQQ		matchgroup=perlStringStartEnd start=+\<qr#+  end=+#[imosx]*+ contains=@perlInterpMatch
+syn region perlQQ		matchgroup=perlStringStartEnd start=+\<qr|+  end=+|[imosx]*+ contains=@perlInterpMatch
+syn region perlQQ		matchgroup=perlStringStartEnd start=+\<qr(+  end=+)[imosx]*+ contains=@perlInterpMatch
+syn region perlQQ		matchgroup=perlStringStartEnd start=+\<qr{+  end=+}[imosx]*+ contains=@perlInterpMatch
+syn region perlQQ		matchgroup=perlStringStartEnd start=+\<qr/+  end=+/[imosx]*+ contains=@perlInterpSlash
+
+" Constructs such as print <<EOF [...] EOF, 'here' documents
+"
+if version >= 600
+  " XXX Any statements after the identifier are in perlString colour (i.e.
+  " 'if $a' in 'print <<EOF if $a').
+  if exists("perl_fold")
+    syn region perlHereDoc	matchgroup=perlStringStartEnd start=+<<\z(\I\i*\).*+    end=+^\z1$+ contains=@perlInterpDQ fold
+    syn region perlHereDoc	matchgroup=perlStringStartEnd start=+<<\s*"\z(.\{-}\)"+ end=+^\z1$+ contains=@perlInterpDQ fold
+    syn region perlHereDoc	matchgroup=perlStringStartEnd start=+<<\s*'\z(.\{-}\)'+ end=+^\z1$+ contains=@perlInterpSQ fold
+    syn region perlHereDoc	matchgroup=perlStringStartEnd start=+<<\s*""+           end=+^$+    contains=@perlInterpDQ,perlNotEmptyLine fold
+    syn region perlHereDoc	matchgroup=perlStringStartEnd start=+<<\s*''+           end=+^$+    contains=@perlInterpSQ,perlNotEmptyLine fold
+    syn region perlAutoload	matchgroup=perlStringStartEnd start=+<<['"]\z(END_\(SUB\|OF_FUNC\|OF_AUTOLOAD\)\)['"]+ end=+^\z1$+ contains=ALL fold
+  else
+    syn region perlHereDoc	matchgroup=perlStringStartEnd start=+<<\z(\I\i*\)+      end=+^\z1$+ contains=@perlInterpDQ
+    syn region perlHereDoc	matchgroup=perlStringStartEnd start=+<<\s*"\z(.\{-}\)"+ end=+^\z1$+ contains=@perlInterpDQ
+    syn region perlHereDoc	matchgroup=perlStringStartEnd start=+<<\s*'\z(.\{-}\)'+ end=+^\z1$+ contains=@perlInterpSQ
+    syn region perlHereDoc	matchgroup=perlStringStartEnd start=+<<\s*""+           end=+^$+    contains=@perlInterpDQ,perlNotEmptyLine
+    syn region perlHereDoc	matchgroup=perlStringStartEnd start=+<<\s*''+           end=+^$+    contains=@perlInterpSQ,perlNotEmptyLine
+    syn region perlAutoload	matchgroup=perlStringStartEnd start=+<<\(['"]\|\)\z(END_\(SUB\|OF_FUNC\|OF_AUTOLOAD\)\)\1+ end=+^\z1$+ contains=ALL
+  endif
+else
+  syn match perlUntilEOFStart	"<<EOF.*"lc=5 nextgroup=perlUntilEOFDQ skipnl transparent
+  syn match perlUntilEOFStart	"<<\s*\"EOF\".*" nextgroup=perlUntilEOFDQ skipnl transparent
+  syn match perlUntilEOFStart	"<<\s*'EOF'.*" nextgroup=perlUntilEOFSQ skipnl transparent
+  syn match perlUntilEOFStart	"<<\s*\"\".*" nextgroup=perlUntilEmptyDQ skipnl transparent
+  syn match perlUntilEOFStart	"<<\s*''.*" nextgroup=perlUntilEmptySQ skipnl transparent
+  syn region perlUntilEOFDQ	matchgroup=perlStringStartEnd start=++ end="^EOF$" contains=@perlInterpDQ contained
+  syn region perlUntilEOFSQ	matchgroup=perlStringStartEnd start=++ end="^EOF$" contains=@perlInterpSQ contained
+  syn region perlUntilEmptySQ	matchgroup=perlStringStartEnd start=++ end="^$" contains=@perlInterpDQ,perlNotEmptyLine contained
+  syn region perlUntilEmptyDQ	matchgroup=perlStringStartEnd start=++ end="^$" contains=@perlInterpSQ,perlNotEmptyLine contained
+  syn match perlHereIdentifier	"<<EOF"
+  syn region perlAutoload	matchgroup=perlStringStartEnd start=+<<\(['"]\|\)\(END_\(SUB\|OF_FUNC\|OF_AUTOLOAD\)\)\1+ end=+^\(END_\(SUB\|OF_FUNC\|OF_AUTOLOAD\)\)$+ contains=ALL
+endif
+
+
+" Class declarations
+"
+syn match  perlPackageDecl	"^\s*\<package\s\+\S\+" contains=perlStatementPackage
+syn keyword perlStatementPackage	package contained
+
+" Functions
+"       sub [name] [(prototype)] {
+"
+syn region perlFunction		start="\s*\<sub\>" end="[;{]"he=e-1 contains=perlStatementSub,perlFunctionPrototype,perlFunctionPRef,perlFunctionName,perlComment
+syn keyword perlStatementSub	sub contained
+
+syn match  perlFunctionPrototype	"([^)]*)" contained
+if exists("perl_want_scope_in_variables")
+   syn match  perlFunctionPRef	"\h\w*::" contained
+   syn match  perlFunctionName	"\h\w*[^:]" contained
+else
+   syn match  perlFunctionName	"\h[[:alnum:]_:]*" contained
+endif
+
+" All other # are comments, except ^#!
+syn match  perlComment		"#.*" contains=perlTodo
+syn match  perlSharpBang	"^#!.*"
+
+" Formats
+syn region perlFormat		matchgroup=perlStatementIOFunc start="^\s*\<format\s\+\k\+\s*=\s*$"rs=s+6 end="^\s*\.\s*$" contains=perlFormatName,perlFormatField,perlVarPlain,perlVarPlain2
+syn match  perlFormatName	"format\s\+\k\+\s*="lc=7,me=e-1 contained
+syn match  perlFormatField	"[@^][|<>~]\+\(\.\.\.\)\=" contained
+syn match  perlFormatField	"[@^]#[#.]*" contained
+syn match  perlFormatField	"@\*" contained
+syn match  perlFormatField	"@[^A-Za-z_|<>~#*]"me=e-1 contained
+syn match  perlFormatField	"@$" contained
+
+" __END__ and __DATA__ clauses
+if exists("perl_fold")
+  syntax region perlDATA		start="^__\(DATA\|END\)__$" skip="." end="." contains=perlPOD,@perlDATA fold
+else
+  syntax region perlDATA		start="^__\(DATA\|END\)__$" skip="." end="." contains=perlPOD,@perlDATA
+endif
+
+
+"
+" Folding
+
+if exists("perl_fold")
+  if !exists("perl_nofold_packages")
+    syn region perlPackageFold start="^package \S\+;\s*\(#.*\)\=$" end="^1;\s*\(#.*\)\=$" end="\n\+package"me=s-1 transparent fold keepend
+  endif
+  if !exists("perl_nofold_subs")
+    syn region perlSubFold     start="^\z(\s*\)\<sub\>.*[^};]$" end="^\z1}\s*\(#.*\)\=$" transparent fold keepend
+    syn region perlSubFold start="^\z(\s*\)\<\(BEGIN\|END\|CHECK\|INIT\)\>.*[^};]$" end="^\z1}\s*$" transparent fold keepend
+  endif
+
+  if exists("perl_fold_blocks")
+    syn region perlBlockFold start="^\z(\s*\)\(if\|elsif\|unless\|for\|while\|until\)\s*(.*)\(\s*{\)\=\s*\(#.*\)\=$" start="^\z(\s*\)foreach\s*\(\(my\|our\)\=\s*\S\+\s*\)\=(.*)\(\s*{\)\=\s*\(#.*\)\=$" end="^\z1}\s*;\=\(#.*\)\=$" transparent fold keepend
+    syn region perlBlockFold start="^\z(\s*\)\(do\|else\)\(\s*{\)\=\s*\(#.*\)\=$" end="^\z1}\s*while" end="^\z1}\s*;\=\(#.*\)\=$" transparent fold keepend
+  endif
+
+  setlocal foldmethod=syntax
+  syn sync fromstart
+else
+  " fromstart above seems to set minlines even if perl_fold is not set.
+  syn sync minlines=0
+endif
+
+
+if version >= 508 || !exists("did_perl_syn_inits")
+  if version < 508
+    let did_perl_syn_inits = 1
+    command -nargs=+ HiLink hi link <args>
+  else
+    command -nargs=+ HiLink hi def link <args>
+  endif
+
+  " The default highlighting.
+  HiLink perlSharpBang		PreProc
+  HiLink perlControl		PreProc
+  HiLink perlInclude		Include
+  HiLink perlSpecial		Special
+  HiLink perlString		String
+  HiLink perlCharacter		Character
+  HiLink perlNumber		Number
+  HiLink perlFloat		Float
+  HiLink perlType		Type
+  HiLink perlIdentifier		Identifier
+  HiLink perlLabel		Label
+  HiLink perlStatement		Statement
+  HiLink perlConditional	Conditional
+  HiLink perlRepeat		Repeat
+  HiLink perlOperator		Operator
+  HiLink perlFunction		Function
+  HiLink perlFunctionPrototype	perlFunction
+  HiLink perlComment		Comment
+  HiLink perlTodo		Todo
+  if exists("perl_string_as_statement")
+    HiLink perlStringStartEnd	perlStatement
+  else
+    HiLink perlStringStartEnd	perlString
+  endif
+  HiLink perlList		perlStatement
+  HiLink perlMisc		perlStatement
+  HiLink perlVarPlain		perlIdentifier
+  HiLink perlVarPlain2		perlIdentifier
+  HiLink perlFiledescRead	perlIdentifier
+  HiLink perlFiledescStatement	perlIdentifier
+  HiLink perlVarSimpleMember	perlIdentifier
+  HiLink perlVarSimpleMemberName perlString
+  HiLink perlVarNotInMatches	perlIdentifier
+  HiLink perlVarSlash		perlIdentifier
+  HiLink perlQQ			perlString
+  if version >= 600
+    HiLink perlHereDoc		perlString
+  else
+    HiLink perlHereIdentifier	perlStringStartEnd
+    HiLink perlUntilEOFDQ	perlString
+    HiLink perlUntilEOFSQ	perlString
+    HiLink perlUntilEmptyDQ	perlString
+    HiLink perlUntilEmptySQ	perlString
+    HiLink perlUntilEOF		perlString
+  endif
+  HiLink perlStringUnexpanded	perlString
+  HiLink perlSubstitutionSQ	perlString
+  HiLink perlSubstitutionDQ	perlString
+  HiLink perlSubstitutionSlash	perlString
+  HiLink perlSubstitutionHash	perlString
+  HiLink perlSubstitutionBracket perlString
+  HiLink perlSubstitutionCurly 	perlString
+  HiLink perlSubstitutionPling	perlString
+  HiLink perlTranslationSlash	perlString
+  HiLink perlTranslationHash	perlString
+  HiLink perlTranslationBracket	perlString
+  HiLink perlTranslationCurly	perlString
+  HiLink perlMatch		perlString
+  HiLink perlMatchStartEnd	perlStatement
+  HiLink perlFormatName		perlIdentifier
+  HiLink perlFormatField	perlString
+  HiLink perlPackageDecl	perlType
+  HiLink perlStorageClass	perlType
+  HiLink perlPackageRef		perlType
+  HiLink perlStatementPackage	perlStatement
+  HiLink perlStatementSub	perlStatement
+  HiLink perlStatementStorage	perlStatement
+  HiLink perlStatementControl	perlStatement
+  HiLink perlStatementScalar	perlStatement
+  HiLink perlStatementRegexp	perlStatement
+  HiLink perlStatementNumeric	perlStatement
+  HiLink perlStatementList	perlStatement
+  HiLink perlStatementHash	perlStatement
+  HiLink perlStatementIOfunc	perlStatement
+  HiLink perlStatementFiledesc	perlStatement
+  HiLink perlStatementVector	perlStatement
+  HiLink perlStatementFiles	perlStatement
+  HiLink perlStatementFlow	perlStatement
+  HiLink perlStatementScope	perlStatement
+  HiLink perlStatementInclude	perlStatement
+  HiLink perlStatementProc	perlStatement
+  HiLink perlStatementSocket	perlStatement
+  HiLink perlStatementIPC	perlStatement
+  HiLink perlStatementNetwork	perlStatement
+  HiLink perlStatementPword	perlStatement
+  HiLink perlStatementTime	perlStatement
+  HiLink perlStatementMisc	perlStatement
+  HiLink perlStatementNew	perlStatement
+  HiLink perlFunctionName	perlIdentifier
+  HiLink perlMethod		perlIdentifier
+  HiLink perlFunctionPRef	perlType
+  HiLink perlPOD		perlComment
+  HiLink perlShellCommand	perlString
+  HiLink perlSpecialAscii	perlSpecial
+  HiLink perlSpecialDollar	perlSpecial
+  HiLink perlSpecialString	perlSpecial
+  HiLink perlSpecialStringU	perlSpecial
+  HiLink perlSpecialMatch	perlSpecial
+  HiLink perlSpecialBEOM	perlSpecial
+  HiLink perlDATA		perlComment
+
+  HiLink perlBrackets		Error
+
+  " Possible errors
+  HiLink perlNotEmptyLine	Error
+  HiLink perlElseIfError	Error
+
+  delcommand HiLink
+endif
+
+" Syncing to speed up processing
+"
+if !exists("perl_no_sync_on_sub")
+  syn sync match perlSync	grouphere NONE "^\s*\<package\s"
+  syn sync match perlSync	grouphere perlFunction "^\s*\<sub\s"
+  syn sync match perlSync	grouphere NONE "^}"
+endif
+
+if !exists("perl_no_sync_on_global_var")
+  syn sync match perlSync	grouphere NONE "^$\I[[:alnum:]_:]+\s*=\s*{"
+  syn sync match perlSync	grouphere NONE "^[@%]\I[[:alnum:]_:]+\s*=\s*("
+endif
+
+if exists("perl_sync_dist")
+  execute "syn sync maxlines=" . perl_sync_dist
+else
+  syn sync maxlines=100
+endif
+
+syn sync match perlSyncPOD	grouphere perlPOD "^=pod"
+syn sync match perlSyncPOD	grouphere perlPOD "^=head"
+syn sync match perlSyncPOD	grouphere perlPOD "^=item"
+syn sync match perlSyncPOD	grouphere NONE "^=cut"
+
+let b:current_syntax = "perl"
+
+" vim: ts=8
--- /dev/null
+++ b/lib/vimfiles/syntax/pf.vim
@@ -1,0 +1,75 @@
+" pf syntax file
+" Language:	OpenBSD packet filter configuration (pf.conf)
+" Maintainer:	Camiel Dobbelaar <cd@sentia.nl>
+" Last Change:	2003 May 27
+
+" For version 5.x: Clear all syntax items
+" For version 6.x: Quit when a syntax file was already loaded
+if version < 600
+  syntax clear
+elseif exists("b:current_syntax")
+  finish
+endif
+
+setlocal foldmethod=syntax
+syn sync fromstart
+
+syn cluster	pfNotLS		contains=pfComment,pfTodo,pfVarAssign
+syn keyword	pfCmd		altq anchor antispoof binat nat pass
+syn keyword	pfCmd		queue rdr scrub table set
+syn keyword	pfService	auth bgp domain finger ftp http https ident
+syn keyword	pfService	imap irc isakmp kerberos mail nameserver nfs
+syn keyword	pfService	nntp ntp pop3 portmap pptp rpcbind rsync smtp
+syn keyword	pfService	snmp snmptrap socks ssh sunrpc syslog telnet
+syn keyword	pfService	tftp www
+syn keyword	pfTodo		TODO XXX contained
+syn keyword	pfWildAddr	all any
+syn match	pfCmd		/block\s/
+syn match	pfComment	/#.*$/ contains=pfTodo
+syn match	pfCont		/\\$/
+syn match	pfErrClose	/}/
+syn match	pfIPv4		/\d\{1,3}\.\d\{1,3}\.\d\{1,3}\.\d\{1,3}/
+syn match	pfIPv6		/[a-fA-F0-9:]*::[a-fA-F0-9:.]*/
+syn match	pfIPv6		/[a-fA-F0-9:]\+:[a-fA-F0-9:]\+:[a-fA-F0-9:.]\+/
+syn match	pfNetmask	/\/\d\+/
+syn match	pfNum		/[a-zA-Z0-9_:.]\@<!\d\+[a-zA-Z0-9_:.]\@!/
+syn match	pfTable		/<\s*[a-zA-Z][a-zA-Z0-9_]*\s*>/
+syn match	pfVar		/$[a-zA-Z][a-zA-Z0-9_]*/
+syn match	pfVarAssign	/^\s*[a-zA-Z][a-zA-Z0-9_]*\s*=/me=e-1
+syn region	pfFold1		start=/^#\{1}>/ end=/^#\{1,3}>/me=s-1 transparent fold
+syn region	pfFold2		start=/^#\{2}>/ end=/^#\{2,3}>/me=s-1 transparent fold
+syn region	pfFold3		start=/^#\{3}>/ end=/^#\{3}>/me=s-1 transparent fold
+syn region	pfList		start=/{/ end=/}/ transparent contains=ALLBUT,pfErrClose,@pfNotLS
+syn region	pfString	start=/"/ end=/"/ transparent contains=ALLBUT,pfString,@pfNotLS
+syn region	pfString	start=/'/ end=/'/ transparent contains=ALLBUT,pfString,@pfNotLS
+
+" Define the default highlighting.
+" For version 5.7 and earlier: only when not done already
+" For version 5.8 and later: only when an item doesn't have highlighting yet
+if version >= 508 || !exists("did_c_syn_inits")
+  if version < 508
+    let did_c_syn_inits = 1
+    command -nargs=+ HiLink hi link <args>
+  else
+    command -nargs=+ HiLink hi def link <args>
+  endif
+
+  HiLink pfCmd		Statement
+  HiLink pfComment	Comment
+  HiLink pfCont		Statement
+  HiLink pfErrClose	Error
+  HiLink pfIPv4		Type
+  HiLink pfIPv6		Type
+  HiLink pfNetmask	Constant
+  HiLink pfNum		Constant
+  HiLink pfService	Constant
+  HiLink pfTable	Identifier
+  HiLink pfTodo		Todo
+  HiLink pfVar		Identifier
+  HiLink pfVarAssign	Identifier
+  HiLink pfWildAddr	Type
+
+  delcommand HiLink
+endif
+
+let b:current_syntax = "pf"
--- /dev/null
+++ b/lib/vimfiles/syntax/pfmain.vim
@@ -1,0 +1,1114 @@
+" Vim syntax file
+" Language:	Postfix main.cf configuration
+" Maintainer:	KELEMEN Peter <Peter dot Kelemen at cern dot ch>
+" Last Change:	2006 Apr 15
+" Version:	0.20
+" URL:		http://cern.ch/fuji/vim/syntax/pfmain.vim
+" Comment:	Based on Postfix 2.3.x defaults.
+
+if version < 600
+	syntax clear
+elseif exists("b:current_syntax")
+	finish
+endif
+
+if version >= 600
+	setlocal iskeyword=@,48-57,_,-
+else
+	set iskeyword=@,48-57,_,-
+endif
+
+syntax case match
+syntax sync minlines=1
+
+syntax keyword pfmainConf 2bounce_notice_recipient
+syntax keyword pfmainConf access_map_reject_code
+syntax keyword pfmainConf address_verify_default_transport
+syntax keyword pfmainConf address_verify_local_transport
+syntax keyword pfmainConf address_verify_map
+syntax keyword pfmainConf address_verify_negative_cache
+syntax keyword pfmainConf address_verify_negative_expire_time
+syntax keyword pfmainConf address_verify_negative_refresh_time
+syntax keyword pfmainConf address_verify_poll_count
+syntax keyword pfmainConf address_verify_poll_delay
+syntax keyword pfmainConf address_verify_positive_expire_time
+syntax keyword pfmainConf address_verify_positive_refresh_time
+syntax keyword pfmainConf address_verify_relay_transport
+syntax keyword pfmainConf address_verify_relayhost
+syntax keyword pfmainConf address_verify_sender
+syntax keyword pfmainConf address_verify_sender_dependent_relayhost_maps
+syntax keyword pfmainConf address_verify_service_name
+syntax keyword pfmainConf address_verify_transport_maps
+syntax keyword pfmainConf address_verify_virtual_transport
+syntax keyword pfmainConf alias_database
+syntax keyword pfmainConf alias_maps
+syntax keyword pfmainConf allow_mail_to_commands
+syntax keyword pfmainConf allow_mail_to_files
+syntax keyword pfmainConf allow_min_user
+syntax keyword pfmainConf allow_percent_hack
+syntax keyword pfmainConf allow_untrusted_routing
+syntax keyword pfmainConf alternate_config_directories
+syntax keyword pfmainConf always_bcc
+syntax keyword pfmainConf anvil_rate_time_unit
+syntax keyword pfmainConf anvil_status_update_time
+syntax keyword pfmainConf append_at_myorigin
+syntax keyword pfmainConf append_dot_mydomain
+syntax keyword pfmainConf application_event_drain_time
+syntax keyword pfmainConf authorized_flush_users
+syntax keyword pfmainConf authorized_mailq_users
+syntax keyword pfmainConf authorized_submit_users
+syntax keyword pfmainConf backwards_bounce_logfile_compatibility
+syntax keyword pfmainConf berkeley_db_create_buffer_size
+syntax keyword pfmainConf berkeley_db_read_buffer_size
+syntax keyword pfmainConf best_mx_transport
+syntax keyword pfmainConf biff
+syntax keyword pfmainConf body_checks
+syntax keyword pfmainConf body_checks_size_limit
+syntax keyword pfmainConf bounce_notice_recipient
+syntax keyword pfmainConf bounce_queue_lifetime
+syntax keyword pfmainConf bounce_service_name
+syntax keyword pfmainConf bounce_size_limit
+syntax keyword pfmainConf bounce_template_file
+syntax keyword pfmainConf broken_sasl_auth_clients
+syntax keyword pfmainConf canonical_classes
+syntax keyword pfmainConf canonical_maps
+syntax keyword pfmainConf cleanup_service_name
+syntax keyword pfmainConf command_directory
+syntax keyword pfmainConf command_execution_directory
+syntax keyword pfmainConf command_expansion_filter
+syntax keyword pfmainConf command_time_limit
+syntax keyword pfmainConf config_directory
+syntax keyword pfmainConf connection_cache_protocol_timeout
+syntax keyword pfmainConf connection_cache_service_name
+syntax keyword pfmainConf connection_cache_status_update_time
+syntax keyword pfmainConf connection_cache_ttl_limit
+syntax keyword pfmainConf content_filter
+syntax keyword pfmainConf daemon_directory
+syntax keyword pfmainConf daemon_timeout
+syntax keyword pfmainConf debug_peer_level
+syntax keyword pfmainConf debug_peer_list
+syntax keyword pfmainConf default_database_type
+syntax keyword pfmainConf default_delivery_slot_cost
+syntax keyword pfmainConf default_delivery_slot_discount
+syntax keyword pfmainConf default_delivery_slot_loan
+syntax keyword pfmainConf default_destination_concurrency_limit
+syntax keyword pfmainConf default_destination_recipient_limit
+syntax keyword pfmainConf default_extra_recipient_limit
+syntax keyword pfmainConf default_minimum_delivery_slots
+syntax keyword pfmainConf default_privs
+syntax keyword pfmainConf default_process_limit
+syntax keyword pfmainConf default_rbl_reply
+syntax keyword pfmainConf default_recipient_limit
+syntax keyword pfmainConf default_transport
+syntax keyword pfmainConf default_verp_delimiters
+syntax keyword pfmainConf defer_code
+syntax keyword pfmainConf defer_service_name
+syntax keyword pfmainConf defer_transports
+syntax keyword pfmainConf delay_logging_resolution_limit
+syntax keyword pfmainConf delay_notice_recipient
+syntax keyword pfmainConf delay_warning_time
+syntax keyword pfmainConf deliver_lock_attempts
+syntax keyword pfmainConf deliver_lock_delay
+syntax keyword pfmainConf disable_dns_lookups
+syntax keyword pfmainConf disable_mime_input_processing
+syntax keyword pfmainConf disable_mime_output_conversion
+syntax keyword pfmainConf disable_verp_bounces
+syntax keyword pfmainConf disable_vrfy_command
+syntax keyword pfmainConf dont_remove
+syntax keyword pfmainConf double_bounce_sender
+syntax keyword pfmainConf duplicate_filter_limit
+syntax keyword pfmainConf empty_address_recipient
+syntax keyword pfmainConf enable_original_recipient
+syntax keyword pfmainConf error_notice_recipient
+syntax keyword pfmainConf error_service_name
+syntax keyword pfmainConf execution_directory_expansion_filter
+syntax keyword pfmainConf expand_owner_alias
+syntax keyword pfmainConf export_environment
+syntax keyword pfmainConf fallback_transport
+syntax keyword pfmainConf fallback_transport_maps
+syntax keyword pfmainConf fast_flush_domains
+syntax keyword pfmainConf fast_flush_purge_time
+syntax keyword pfmainConf fast_flush_refresh_time
+syntax keyword pfmainConf fault_injection_code
+syntax keyword pfmainConf flush_service_name
+syntax keyword pfmainConf fork_attempts
+syntax keyword pfmainConf fork_delay
+syntax keyword pfmainConf forward_expansion_filter
+syntax keyword pfmainConf forward_path
+syntax keyword pfmainConf frozen_delivered_to
+syntax keyword pfmainConf hash_queue_depth
+syntax keyword pfmainConf hash_queue_names
+syntax keyword pfmainConf header_address_token_limit
+syntax keyword pfmainConf header_checks
+syntax keyword pfmainConf header_size_limit
+syntax keyword pfmainConf helpful_warnings
+syntax keyword pfmainConf home_mailbox
+syntax keyword pfmainConf hopcount_limit
+syntax keyword pfmainConf html_directory
+syntax keyword pfmainConf ignore_mx_lookup_error
+syntax keyword pfmainConf import_environment
+syntax keyword pfmainConf in_flow_delay
+syntax keyword pfmainConf inet_interfaces
+syntax keyword pfmainConf inet_protocols
+syntax keyword pfmainConf initial_destination_concurrency
+syntax keyword pfmainConf invalid_hostname_reject_code
+syntax keyword pfmainConf ipc_idle
+syntax keyword pfmainConf ipc_timeout
+syntax keyword pfmainConf ipc_ttl
+syntax keyword pfmainConf line_length_limit
+syntax keyword pfmainConf lmtp_bind_address
+syntax keyword pfmainConf lmtp_bind_address6
+syntax keyword pfmainConf lmtp_cname_overrides_servername
+syntax keyword pfmainConf lmtp_connect_timeout
+syntax keyword pfmainConf lmtp_connection_cache_destinations
+syntax keyword pfmainConf lmtp_connection_cache_on_demand
+syntax keyword pfmainConf lmtp_connection_cache_time_limit
+syntax keyword pfmainConf lmtp_connection_reuse_time_limit
+syntax keyword pfmainConf lmtp_data_done_timeout
+syntax keyword pfmainConf lmtp_data_init_timeout
+syntax keyword pfmainConf lmtp_data_xfer_timeout
+syntax keyword pfmainConf lmtp_defer_if_no_mx_address_found
+syntax keyword pfmainConf lmtp_destination_concurrency_limit
+syntax keyword pfmainConf lmtp_destination_recipient_limit
+syntax keyword pfmainConf lmtp_discard_lhlo_keyword_address_maps
+syntax keyword pfmainConf lmtp_discard_lhlo_keywords
+syntax keyword pfmainConf lmtp_enforce_tls
+syntax keyword pfmainConf lmtp_generic_maps
+syntax keyword pfmainConf lmtp_host_lookup
+syntax keyword pfmainConf lmtp_lhlo_name
+syntax keyword pfmainConf lmtp_lhlo_timeout
+syntax keyword pfmainConf lmtp_line_length_limit
+syntax keyword pfmainConf lmtp_mail_timeout
+syntax keyword pfmainConf lmtp_mx_address_limit
+syntax keyword pfmainConf lmtp_mx_session_limit
+syntax keyword pfmainConf lmtp_pix_workaround_delay_time
+syntax keyword pfmainConf lmtp_pix_workaround_threshold_time
+syntax keyword pfmainConf lmtp_quit_timeout
+syntax keyword pfmainConf lmtp_quote_rfc821_envelope
+syntax keyword pfmainConf lmtp_randomize_addresses
+syntax keyword pfmainConf lmtp_rcpt_timeout
+syntax keyword pfmainConf lmtp_rset_timeout
+syntax keyword pfmainConf lmtp_sasl_auth_enable
+syntax keyword pfmainConf lmtp_sasl_mechanism_filter
+syntax keyword pfmainConf lmtp_sasl_password_maps
+syntax keyword pfmainConf lmtp_sasl_path
+syntax keyword pfmainConf lmtp_sasl_security_options
+syntax keyword pfmainConf lmtp_sasl_tls_security_options
+syntax keyword pfmainConf lmtp_sasl_tls_verified_security_options
+syntax keyword pfmainConf lmtp_sasl_type
+syntax keyword pfmainConf lmtp_send_xforward_command
+syntax keyword pfmainConf lmtp_sender_dependent_authentication
+syntax keyword pfmainConf lmtp_skip_5xx_greeting
+syntax keyword pfmainConf lmtp_starttls_timeout
+syntax keyword pfmainConf lmtp_tcp_port
+syntax keyword pfmainConf lmtp_tls_enforce_peername
+syntax keyword pfmainConf lmtp_tls_note_starttls_offer
+syntax keyword pfmainConf lmtp_tls_per_site
+syntax keyword pfmainConf lmtp_tls_scert_verifydepth
+syntax keyword pfmainConf lmtp_use_tls
+syntax keyword pfmainConf lmtp_xforward_timeout
+syntax keyword pfmainConf local_command_shell
+syntax keyword pfmainConf local_destination_concurrency_limit
+syntax keyword pfmainConf local_destination_recipient_limit
+syntax keyword pfmainConf local_header_rewrite_clients
+syntax keyword pfmainConf local_recipient_maps
+syntax keyword pfmainConf local_transport
+syntax keyword pfmainConf luser_relay
+syntax keyword pfmainConf mail_name
+syntax keyword pfmainConf mail_owner
+syntax keyword pfmainConf mail_release_date
+syntax keyword pfmainConf mail_spool_directory
+syntax keyword pfmainConf mail_version
+syntax keyword pfmainConf mailbox_command
+syntax keyword pfmainConf mailbox_command_maps
+syntax keyword pfmainConf mailbox_delivery_lock
+syntax keyword pfmainConf mailbox_size_limit
+syntax keyword pfmainConf mailbox_transport
+syntax keyword pfmainConf mailbox_transport_maps
+syntax keyword pfmainConf mailq_path
+syntax keyword pfmainConf manpage_directory
+syntax keyword pfmainConf maps_rbl_domains
+syntax keyword pfmainConf maps_rbl_reject_code
+syntax keyword pfmainConf masquerade_classes
+syntax keyword pfmainConf masquerade_domains
+syntax keyword pfmainConf masquerade_exceptions
+syntax keyword pfmainConf max_idle
+syntax keyword pfmainConf max_use
+syntax keyword pfmainConf maximal_backoff_time
+syntax keyword pfmainConf maximal_queue_lifetime
+syntax keyword pfmainConf message_reject_characters
+syntax keyword pfmainConf message_size_limit
+syntax keyword pfmainConf message_strip_characters
+syntax keyword pfmainConf mime_boundary_length_limit
+syntax keyword pfmainConf mime_header_checks
+syntax keyword pfmainConf mime_nesting_limit
+syntax keyword pfmainConf minimal_backoff_time
+syntax keyword pfmainConf multi_recipient_bounce_reject_code
+syntax keyword pfmainConf mydestination
+syntax keyword pfmainConf mydomain
+syntax keyword pfmainConf myhostname
+syntax keyword pfmainConf mynetworks
+syntax keyword pfmainConf mynetworks_style
+syntax keyword pfmainConf myorigin
+syntax keyword pfmainConf nested_header_checks
+syntax keyword pfmainConf newaliases_path
+syntax keyword pfmainConf non_fqdn_reject_code
+syntax keyword pfmainConf notify_classes
+syntax keyword pfmainConf owner_request_special
+syntax keyword pfmainConf parent_domain_matches_subdomains
+syntax keyword pfmainConf permit_mx_backup_networks
+syntax keyword pfmainConf pickup_service_name
+syntax keyword pfmainConf plaintext_reject_code
+syntax keyword pfmainConf prepend_delivered_header
+syntax keyword pfmainConf process_id_directory
+syntax keyword pfmainConf propagate_unmatched_extensions
+syntax keyword pfmainConf proxy_interfaces
+syntax keyword pfmainConf proxy_read_maps
+syntax keyword pfmainConf qmgr_clog_warn_time
+syntax keyword pfmainConf qmgr_fudge_factor
+syntax keyword pfmainConf qmgr_message_active_limit
+syntax keyword pfmainConf qmgr_message_recipient_limit
+syntax keyword pfmainConf qmgr_message_recipient_minimum
+syntax keyword pfmainConf qmqpd_authorized_clients
+syntax keyword pfmainConf qmqpd_error_delay
+syntax keyword pfmainConf qmqpd_timeout
+syntax keyword pfmainConf queue_directory
+syntax keyword pfmainConf queue_file_attribute_count_limit
+syntax keyword pfmainConf queue_minfree
+syntax keyword pfmainConf queue_run_delay
+syntax keyword pfmainConf queue_service_name
+syntax keyword pfmainConf rbl_reply_maps
+syntax keyword pfmainConf readme_directory
+syntax keyword pfmainConf receive_override_options
+syntax keyword pfmainConf recipient_bcc_maps
+syntax keyword pfmainConf recipient_canonical_classes
+syntax keyword pfmainConf recipient_canonical_maps
+syntax keyword pfmainConf recipient_delimiter
+syntax keyword pfmainConf reject_code
+syntax keyword pfmainConf relay_clientcerts
+syntax keyword pfmainConf relay_destination_concurrency_limit
+syntax keyword pfmainConf relay_destination_recipient_limit
+syntax keyword pfmainConf relay_domains
+syntax keyword pfmainConf relay_domains_reject_code
+syntax keyword pfmainConf relay_recipient_maps
+syntax keyword pfmainConf relay_transport
+syntax keyword pfmainConf relayhost
+syntax keyword pfmainConf relocated_maps
+syntax keyword pfmainConf remote_header_rewrite_domain
+syntax keyword pfmainConf require_home_directory
+syntax keyword pfmainConf resolve_dequoted_address
+syntax keyword pfmainConf resolve_null_domain
+syntax keyword pfmainConf resolve_numeric_domain
+syntax keyword pfmainConf rewrite_service_name
+syntax keyword pfmainConf sample_directory
+syntax keyword pfmainConf sender_bcc_maps
+syntax keyword pfmainConf sender_canonical_classes
+syntax keyword pfmainConf sender_canonical_maps
+syntax keyword pfmainConf sender_dependent_relayhost_maps
+syntax keyword pfmainConf sendmail_path
+syntax keyword pfmainConf service_throttle_time
+syntax keyword pfmainConf setgid_group
+syntax keyword pfmainConf show_user_unknown_table_name
+syntax keyword pfmainConf showq_service_name
+syntax keyword pfmainConf smtp_always_send_ehlo
+syntax keyword pfmainConf smtp_bind_address
+syntax keyword pfmainConf smtp_bind_address6
+syntax keyword pfmainConf smtp_cname_overrides_servername
+syntax keyword pfmainConf smtp_connect_timeout
+syntax keyword pfmainConf smtp_connection_cache_destinations
+syntax keyword pfmainConf smtp_connection_cache_on_demand
+syntax keyword pfmainConf smtp_connection_cache_time_limit
+syntax keyword pfmainConf smtp_connection_reuse_time_limit
+syntax keyword pfmainConf smtp_data_done_timeout
+syntax keyword pfmainConf smtp_data_init_timeout
+syntax keyword pfmainConf smtp_data_xfer_timeout
+syntax keyword pfmainConf smtp_defer_if_no_mx_address_found
+syntax keyword pfmainConf smtp_destination_concurrency_limit
+syntax keyword pfmainConf smtp_destination_recipient_limit
+syntax keyword pfmainConf smtp_discard_ehlo_keyword_address_maps
+syntax keyword pfmainConf smtp_discard_ehlo_keywords
+syntax keyword pfmainConf smtp_enforce_tls
+syntax keyword pfmainConf smtp_fallback_relay
+syntax keyword pfmainConf smtp_generic_maps
+syntax keyword pfmainConf smtp_helo_name
+syntax keyword pfmainConf smtp_helo_timeout
+syntax keyword pfmainConf smtp_host_lookup
+syntax keyword pfmainConf smtp_line_length_limit
+syntax keyword pfmainConf smtp_mail_timeout
+syntax keyword pfmainConf smtp_mx_address_limit
+syntax keyword pfmainConf smtp_mx_session_limit
+syntax keyword pfmainConf smtp_never_send_ehlo
+syntax keyword pfmainConf smtp_pix_workaround_delay_time
+syntax keyword pfmainConf smtp_pix_workaround_threshold_time
+syntax keyword pfmainConf smtp_quit_timeout
+syntax keyword pfmainConf smtp_quote_rfc821_envelope
+syntax keyword pfmainConf smtp_randomize_addresses
+syntax keyword pfmainConf smtp_rcpt_timeout
+syntax keyword pfmainConf smtp_rset_timeout
+syntax keyword pfmainConf smtp_sasl_auth_enable
+syntax keyword pfmainConf smtp_sasl_mechanism_filter
+syntax keyword pfmainConf smtp_sasl_password_maps
+syntax keyword pfmainConf smtp_sasl_path
+syntax keyword pfmainConf smtp_sasl_security_options
+syntax keyword pfmainConf smtp_sasl_tls_security_options
+syntax keyword pfmainConf smtp_sasl_tls_verified_security_options
+syntax keyword pfmainConf smtp_sasl_type
+syntax keyword pfmainConf smtp_send_xforward_command
+syntax keyword pfmainConf smtp_sender_dependent_authentication
+syntax keyword pfmainConf smtp_skip_5xx_greeting
+syntax keyword pfmainConf smtp_skip_quit_response
+syntax keyword pfmainConf smtp_starttls_timeout
+syntax keyword pfmainConf smtp_tls_CAfile
+syntax keyword pfmainConf smtp_tls_CApath
+syntax keyword pfmainConf smtp_tls_cert_file
+syntax keyword pfmainConf smtp_tls_cipherlist
+syntax keyword pfmainConf smtp_tls_dcert_file
+syntax keyword pfmainConf smtp_tls_dkey_file
+syntax keyword pfmainConf smtp_tls_enforce_peername
+syntax keyword pfmainConf smtp_tls_key_file
+syntax keyword pfmainConf smtp_tls_loglevel
+syntax keyword pfmainConf smtp_tls_note_starttls_offer
+syntax keyword pfmainConf smtp_tls_per_site
+syntax keyword pfmainConf smtp_tls_scert_verifydepth
+syntax keyword pfmainConf smtp_tls_session_cache_database
+syntax keyword pfmainConf smtp_tls_session_cache_timeout
+syntax keyword pfmainConf smtp_use_tls
+syntax keyword pfmainConf smtp_xforward_timeout
+syntax keyword pfmainConf smtpd_authorized_verp_clients
+syntax keyword pfmainConf smtpd_authorized_xclient_hosts
+syntax keyword pfmainConf smtpd_authorized_xforward_hosts
+syntax keyword pfmainConf smtpd_banner
+syntax keyword pfmainConf smtpd_client_connection_count_limit
+syntax keyword pfmainConf smtpd_client_connection_rate_limit
+syntax keyword pfmainConf smtpd_client_event_limit_exceptions
+syntax keyword pfmainConf smtpd_client_message_rate_limit
+syntax keyword pfmainConf smtpd_client_new_tls_session_rate_limit
+syntax keyword pfmainConf smtpd_client_recipient_rate_limit
+syntax keyword pfmainConf smtpd_client_restrictions
+syntax keyword pfmainConf smtpd_data_restrictions
+syntax keyword pfmainConf smtpd_delay_open_until_valid_rcpt
+syntax keyword pfmainConf smtpd_delay_reject
+syntax keyword pfmainConf smtpd_discard_ehlo_keyword_address_maps
+syntax keyword pfmainConf smtpd_discard_ehlo_keywords
+syntax keyword pfmainConf smtpd_end_of_data_restrictions
+syntax keyword pfmainConf smtpd_enforce_tls
+syntax keyword pfmainConf smtpd_error_sleep_time
+syntax keyword pfmainConf smtpd_etrn_restrictions
+syntax keyword pfmainConf smtpd_expansion_filter
+syntax keyword pfmainConf smtpd_forbidden_commands
+syntax keyword pfmainConf smtpd_hard_error_limit
+syntax keyword pfmainConf smtpd_helo_required
+syntax keyword pfmainConf smtpd_helo_restrictions
+syntax keyword pfmainConf smtpd_history_flush_threshold
+syntax keyword pfmainConf smtpd_junk_command_limit
+syntax keyword pfmainConf smtpd_noop_commands
+syntax keyword pfmainConf smtpd_null_access_lookup_key
+syntax keyword pfmainConf smtpd_peername_lookup
+syntax keyword pfmainConf smtpd_policy_service_max_idle
+syntax keyword pfmainConf smtpd_policy_service_max_ttl
+syntax keyword pfmainConf smtpd_policy_service_timeout
+syntax keyword pfmainConf smtpd_proxy_ehlo
+syntax keyword pfmainConf smtpd_proxy_filter
+syntax keyword pfmainConf smtpd_proxy_timeout
+syntax keyword pfmainConf smtpd_recipient_limit
+syntax keyword pfmainConf smtpd_recipient_overshoot_limit
+syntax keyword pfmainConf smtpd_recipient_restrictions
+syntax keyword pfmainConf smtpd_reject_unlisted_recipient
+syntax keyword pfmainConf smtpd_reject_unlisted_sender
+syntax keyword pfmainConf smtpd_restriction_classes
+syntax keyword pfmainConf smtpd_sasl_auth_enable
+syntax keyword pfmainConf smtpd_sasl_authenticated_header
+syntax keyword pfmainConf smtpd_sasl_exceptions_networks
+syntax keyword pfmainConf smtpd_sasl_local_domain
+syntax keyword pfmainConf smtpd_sasl_path
+syntax keyword pfmainConf smtpd_sasl_security_options
+syntax keyword pfmainConf smtpd_sasl_tls_security_options
+syntax keyword pfmainConf smtpd_sasl_type
+syntax keyword pfmainConf smtpd_sender_login_maps
+syntax keyword pfmainConf smtpd_sender_restrictions
+syntax keyword pfmainConf smtpd_soft_error_limit
+syntax keyword pfmainConf smtpd_starttls_timeout
+syntax keyword pfmainConf smtpd_timeout
+syntax keyword pfmainConf smtpd_tls_CAfile
+syntax keyword pfmainConf smtpd_tls_CApath
+syntax keyword pfmainConf smtpd_tls_ask_ccert
+syntax keyword pfmainConf smtpd_tls_auth_only
+syntax keyword pfmainConf smtpd_tls_ccert_verifydepth
+syntax keyword pfmainConf smtpd_tls_cert_file
+syntax keyword pfmainConf smtpd_tls_cipherlist
+syntax keyword pfmainConf smtpd_tls_dcert_file
+syntax keyword pfmainConf smtpd_tls_dh1024_param_file
+syntax keyword pfmainConf smtpd_tls_dh512_param_file
+syntax keyword pfmainConf smtpd_tls_dkey_file
+syntax keyword pfmainConf smtpd_tls_key_file
+syntax keyword pfmainConf smtpd_tls_loglevel
+syntax keyword pfmainConf smtpd_tls_received_header
+syntax keyword pfmainConf smtpd_tls_req_ccert
+syntax keyword pfmainConf smtpd_tls_session_cache_database
+syntax keyword pfmainConf smtpd_tls_session_cache_timeout
+syntax keyword pfmainConf smtpd_tls_wrappermode
+syntax keyword pfmainConf smtpd_use_tls
+syntax keyword pfmainConf soft_bounce
+syntax keyword pfmainConf stale_lock_time
+syntax keyword pfmainConf strict_7bit_headers
+syntax keyword pfmainConf strict_8bitmime
+syntax keyword pfmainConf strict_8bitmime_body
+syntax keyword pfmainConf strict_mime_encoding_domain
+syntax keyword pfmainConf strict_rfc821_envelopes
+syntax keyword pfmainConf sun_mailtool_compatibility
+syntax keyword pfmainConf swap_bangpath
+syntax keyword pfmainConf syslog_facility
+syntax keyword pfmainConf syslog_name
+syntax keyword pfmainConf tls_daemon_random_bytes
+syntax keyword pfmainConf tls_random_bytes
+syntax keyword pfmainConf tls_random_exchange_name
+syntax keyword pfmainConf tls_random_prng_update_period
+syntax keyword pfmainConf tls_random_reseed_period
+syntax keyword pfmainConf tls_random_source
+syntax keyword pfmainConf trace_service_name
+syntax keyword pfmainConf transport_maps
+syntax keyword pfmainConf transport_retry_time
+syntax keyword pfmainConf trigger_timeout
+syntax keyword pfmainConf undisclosed_recipients_header
+syntax keyword pfmainConf unknown_address_reject_code
+syntax keyword pfmainConf unknown_client_reject_code
+syntax keyword pfmainConf unknown_hostname_reject_code
+syntax keyword pfmainConf unknown_local_recipient_reject_code
+syntax keyword pfmainConf unknown_relay_recipient_reject_code
+syntax keyword pfmainConf unknown_virtual_alias_reject_code
+syntax keyword pfmainConf unknown_virtual_mailbox_reject_code
+syntax keyword pfmainConf unverified_recipient_reject_code
+syntax keyword pfmainConf unverified_sender_reject_code
+syntax keyword pfmainConf verp_delimiter_filter
+syntax keyword pfmainConf virtual_alias_domains
+syntax keyword pfmainConf virtual_alias_expansion_limit
+syntax keyword pfmainConf virtual_alias_maps
+syntax keyword pfmainConf virtual_alias_recursion_limit
+syntax keyword pfmainConf virtual_destination_concurrency_limit
+syntax keyword pfmainConf virtual_destination_recipient_limit
+syntax keyword pfmainConf virtual_gid_maps
+syntax keyword pfmainConf virtual_mailbox_base
+syntax keyword pfmainConf virtual_mailbox_domains
+syntax keyword pfmainConf virtual_mailbox_limit
+syntax keyword pfmainConf virtual_mailbox_lock
+syntax keyword pfmainConf virtual_mailbox_maps
+syntax keyword pfmainConf virtual_minimum_uid
+syntax keyword pfmainConf virtual_transport
+syntax keyword pfmainConf virtual_uid_maps
+syntax match pfmainRef "$\<2bounce_notice_recipient\>"
+syntax match pfmainRef "$\<access_map_reject_code\>"
+syntax match pfmainRef "$\<address_verify_default_transport\>"
+syntax match pfmainRef "$\<address_verify_local_transport\>"
+syntax match pfmainRef "$\<address_verify_map\>"
+syntax match pfmainRef "$\<address_verify_negative_cache\>"
+syntax match pfmainRef "$\<address_verify_negative_expire_time\>"
+syntax match pfmainRef "$\<address_verify_negative_refresh_time\>"
+syntax match pfmainRef "$\<address_verify_poll_count\>"
+syntax match pfmainRef "$\<address_verify_poll_delay\>"
+syntax match pfmainRef "$\<address_verify_positive_expire_time\>"
+syntax match pfmainRef "$\<address_verify_positive_refresh_time\>"
+syntax match pfmainRef "$\<address_verify_relay_transport\>"
+syntax match pfmainRef "$\<address_verify_relayhost\>"
+syntax match pfmainRef "$\<address_verify_sender\>"
+syntax match pfmainRef "$\<address_verify_sender_dependent_relayhost_maps\>"
+syntax match pfmainRef "$\<address_verify_service_name\>"
+syntax match pfmainRef "$\<address_verify_transport_maps\>"
+syntax match pfmainRef "$\<address_verify_virtual_transport\>"
+syntax match pfmainRef "$\<alias_database\>"
+syntax match pfmainRef "$\<alias_maps\>"
+syntax match pfmainRef "$\<allow_mail_to_commands\>"
+syntax match pfmainRef "$\<allow_mail_to_files\>"
+syntax match pfmainRef "$\<allow_min_user\>"
+syntax match pfmainRef "$\<allow_percent_hack\>"
+syntax match pfmainRef "$\<allow_untrusted_routing\>"
+syntax match pfmainRef "$\<alternate_config_directories\>"
+syntax match pfmainRef "$\<always_bcc\>"
+syntax match pfmainRef "$\<anvil_rate_time_unit\>"
+syntax match pfmainRef "$\<anvil_status_update_time\>"
+syntax match pfmainRef "$\<append_at_myorigin\>"
+syntax match pfmainRef "$\<append_dot_mydomain\>"
+syntax match pfmainRef "$\<application_event_drain_time\>"
+syntax match pfmainRef "$\<authorized_flush_users\>"
+syntax match pfmainRef "$\<authorized_mailq_users\>"
+syntax match pfmainRef "$\<authorized_submit_users\>"
+syntax match pfmainRef "$\<backwards_bounce_logfile_compatibility\>"
+syntax match pfmainRef "$\<berkeley_db_create_buffer_size\>"
+syntax match pfmainRef "$\<berkeley_db_read_buffer_size\>"
+syntax match pfmainRef "$\<best_mx_transport\>"
+syntax match pfmainRef "$\<biff\>"
+syntax match pfmainRef "$\<body_checks\>"
+syntax match pfmainRef "$\<body_checks_size_limit\>"
+syntax match pfmainRef "$\<bounce_notice_recipient\>"
+syntax match pfmainRef "$\<bounce_queue_lifetime\>"
+syntax match pfmainRef "$\<bounce_service_name\>"
+syntax match pfmainRef "$\<bounce_size_limit\>"
+syntax match pfmainRef "$\<bounce_template_file\>"
+syntax match pfmainRef "$\<broken_sasl_auth_clients\>"
+syntax match pfmainRef "$\<canonical_classes\>"
+syntax match pfmainRef "$\<canonical_maps\>"
+syntax match pfmainRef "$\<cleanup_service_name\>"
+syntax match pfmainRef "$\<command_directory\>"
+syntax match pfmainRef "$\<command_execution_directory\>"
+syntax match pfmainRef "$\<command_expansion_filter\>"
+syntax match pfmainRef "$\<command_time_limit\>"
+syntax match pfmainRef "$\<config_directory\>"
+syntax match pfmainRef "$\<connection_cache_protocol_timeout\>"
+syntax match pfmainRef "$\<connection_cache_service_name\>"
+syntax match pfmainRef "$\<connection_cache_status_update_time\>"
+syntax match pfmainRef "$\<connection_cache_ttl_limit\>"
+syntax match pfmainRef "$\<content_filter\>"
+syntax match pfmainRef "$\<daemon_directory\>"
+syntax match pfmainRef "$\<daemon_timeout\>"
+syntax match pfmainRef "$\<debug_peer_level\>"
+syntax match pfmainRef "$\<debug_peer_list\>"
+syntax match pfmainRef "$\<default_database_type\>"
+syntax match pfmainRef "$\<default_delivery_slot_cost\>"
+syntax match pfmainRef "$\<default_delivery_slot_discount\>"
+syntax match pfmainRef "$\<default_delivery_slot_loan\>"
+syntax match pfmainRef "$\<default_destination_concurrency_limit\>"
+syntax match pfmainRef "$\<default_destination_recipient_limit\>"
+syntax match pfmainRef "$\<default_extra_recipient_limit\>"
+syntax match pfmainRef "$\<default_minimum_delivery_slots\>"
+syntax match pfmainRef "$\<default_privs\>"
+syntax match pfmainRef "$\<default_process_limit\>"
+syntax match pfmainRef "$\<default_rbl_reply\>"
+syntax match pfmainRef "$\<default_recipient_limit\>"
+syntax match pfmainRef "$\<default_transport\>"
+syntax match pfmainRef "$\<default_verp_delimiters\>"
+syntax match pfmainRef "$\<defer_code\>"
+syntax match pfmainRef "$\<defer_service_name\>"
+syntax match pfmainRef "$\<defer_transports\>"
+syntax match pfmainRef "$\<delay_logging_resolution_limit\>"
+syntax match pfmainRef "$\<delay_notice_recipient\>"
+syntax match pfmainRef "$\<delay_warning_time\>"
+syntax match pfmainRef "$\<deliver_lock_attempts\>"
+syntax match pfmainRef "$\<deliver_lock_delay\>"
+syntax match pfmainRef "$\<disable_dns_lookups\>"
+syntax match pfmainRef "$\<disable_mime_input_processing\>"
+syntax match pfmainRef "$\<disable_mime_output_conversion\>"
+syntax match pfmainRef "$\<disable_verp_bounces\>"
+syntax match pfmainRef "$\<disable_vrfy_command\>"
+syntax match pfmainRef "$\<dont_remove\>"
+syntax match pfmainRef "$\<double_bounce_sender\>"
+syntax match pfmainRef "$\<duplicate_filter_limit\>"
+syntax match pfmainRef "$\<empty_address_recipient\>"
+syntax match pfmainRef "$\<enable_original_recipient\>"
+syntax match pfmainRef "$\<error_notice_recipient\>"
+syntax match pfmainRef "$\<error_service_name\>"
+syntax match pfmainRef "$\<execution_directory_expansion_filter\>"
+syntax match pfmainRef "$\<expand_owner_alias\>"
+syntax match pfmainRef "$\<export_environment\>"
+syntax match pfmainRef "$\<fallback_transport\>"
+syntax match pfmainRef "$\<fallback_transport_maps\>"
+syntax match pfmainRef "$\<fast_flush_domains\>"
+syntax match pfmainRef "$\<fast_flush_purge_time\>"
+syntax match pfmainRef "$\<fast_flush_refresh_time\>"
+syntax match pfmainRef "$\<fault_injection_code\>"
+syntax match pfmainRef "$\<flush_service_name\>"
+syntax match pfmainRef "$\<fork_attempts\>"
+syntax match pfmainRef "$\<fork_delay\>"
+syntax match pfmainRef "$\<forward_expansion_filter\>"
+syntax match pfmainRef "$\<forward_path\>"
+syntax match pfmainRef "$\<frozen_delivered_to\>"
+syntax match pfmainRef "$\<hash_queue_depth\>"
+syntax match pfmainRef "$\<hash_queue_names\>"
+syntax match pfmainRef "$\<header_address_token_limit\>"
+syntax match pfmainRef "$\<header_checks\>"
+syntax match pfmainRef "$\<header_size_limit\>"
+syntax match pfmainRef "$\<helpful_warnings\>"
+syntax match pfmainRef "$\<home_mailbox\>"
+syntax match pfmainRef "$\<hopcount_limit\>"
+syntax match pfmainRef "$\<html_directory\>"
+syntax match pfmainRef "$\<ignore_mx_lookup_error\>"
+syntax match pfmainRef "$\<import_environment\>"
+syntax match pfmainRef "$\<in_flow_delay\>"
+syntax match pfmainRef "$\<inet_interfaces\>"
+syntax match pfmainRef "$\<inet_protocols\>"
+syntax match pfmainRef "$\<initial_destination_concurrency\>"
+syntax match pfmainRef "$\<invalid_hostname_reject_code\>"
+syntax match pfmainRef "$\<ipc_idle\>"
+syntax match pfmainRef "$\<ipc_timeout\>"
+syntax match pfmainRef "$\<ipc_ttl\>"
+syntax match pfmainRef "$\<line_length_limit\>"
+syntax match pfmainRef "$\<lmtp_bind_address\>"
+syntax match pfmainRef "$\<lmtp_bind_address6\>"
+syntax match pfmainRef "$\<lmtp_cname_overrides_servername\>"
+syntax match pfmainRef "$\<lmtp_connect_timeout\>"
+syntax match pfmainRef "$\<lmtp_connection_cache_destinations\>"
+syntax match pfmainRef "$\<lmtp_connection_cache_on_demand\>"
+syntax match pfmainRef "$\<lmtp_connection_cache_time_limit\>"
+syntax match pfmainRef "$\<lmtp_connection_reuse_time_limit\>"
+syntax match pfmainRef "$\<lmtp_data_done_timeout\>"
+syntax match pfmainRef "$\<lmtp_data_init_timeout\>"
+syntax match pfmainRef "$\<lmtp_data_xfer_timeout\>"
+syntax match pfmainRef "$\<lmtp_defer_if_no_mx_address_found\>"
+syntax match pfmainRef "$\<lmtp_destination_concurrency_limit\>"
+syntax match pfmainRef "$\<lmtp_destination_recipient_limit\>"
+syntax match pfmainRef "$\<lmtp_discard_lhlo_keyword_address_maps\>"
+syntax match pfmainRef "$\<lmtp_discard_lhlo_keywords\>"
+syntax match pfmainRef "$\<lmtp_enforce_tls\>"
+syntax match pfmainRef "$\<lmtp_generic_maps\>"
+syntax match pfmainRef "$\<lmtp_host_lookup\>"
+syntax match pfmainRef "$\<lmtp_lhlo_name\>"
+syntax match pfmainRef "$\<lmtp_lhlo_timeout\>"
+syntax match pfmainRef "$\<lmtp_line_length_limit\>"
+syntax match pfmainRef "$\<lmtp_mail_timeout\>"
+syntax match pfmainRef "$\<lmtp_mx_address_limit\>"
+syntax match pfmainRef "$\<lmtp_mx_session_limit\>"
+syntax match pfmainRef "$\<lmtp_pix_workaround_delay_time\>"
+syntax match pfmainRef "$\<lmtp_pix_workaround_threshold_time\>"
+syntax match pfmainRef "$\<lmtp_quit_timeout\>"
+syntax match pfmainRef "$\<lmtp_quote_rfc821_envelope\>"
+syntax match pfmainRef "$\<lmtp_randomize_addresses\>"
+syntax match pfmainRef "$\<lmtp_rcpt_timeout\>"
+syntax match pfmainRef "$\<lmtp_rset_timeout\>"
+syntax match pfmainRef "$\<lmtp_sasl_auth_enable\>"
+syntax match pfmainRef "$\<lmtp_sasl_mechanism_filter\>"
+syntax match pfmainRef "$\<lmtp_sasl_password_maps\>"
+syntax match pfmainRef "$\<lmtp_sasl_path\>"
+syntax match pfmainRef "$\<lmtp_sasl_security_options\>"
+syntax match pfmainRef "$\<lmtp_sasl_tls_security_options\>"
+syntax match pfmainRef "$\<lmtp_sasl_tls_verified_security_options\>"
+syntax match pfmainRef "$\<lmtp_sasl_type\>"
+syntax match pfmainRef "$\<lmtp_send_xforward_command\>"
+syntax match pfmainRef "$\<lmtp_sender_dependent_authentication\>"
+syntax match pfmainRef "$\<lmtp_skip_5xx_greeting\>"
+syntax match pfmainRef "$\<lmtp_starttls_timeout\>"
+syntax match pfmainRef "$\<lmtp_tcp_port\>"
+syntax match pfmainRef "$\<lmtp_tls_enforce_peername\>"
+syntax match pfmainRef "$\<lmtp_tls_note_starttls_offer\>"
+syntax match pfmainRef "$\<lmtp_tls_per_site\>"
+syntax match pfmainRef "$\<lmtp_tls_scert_verifydepth\>"
+syntax match pfmainRef "$\<lmtp_use_tls\>"
+syntax match pfmainRef "$\<lmtp_xforward_timeout\>"
+syntax match pfmainRef "$\<local_command_shell\>"
+syntax match pfmainRef "$\<local_destination_concurrency_limit\>"
+syntax match pfmainRef "$\<local_destination_recipient_limit\>"
+syntax match pfmainRef "$\<local_header_rewrite_clients\>"
+syntax match pfmainRef "$\<local_recipient_maps\>"
+syntax match pfmainRef "$\<local_transport\>"
+syntax match pfmainRef "$\<luser_relay\>"
+syntax match pfmainRef "$\<mail_name\>"
+syntax match pfmainRef "$\<mail_owner\>"
+syntax match pfmainRef "$\<mail_release_date\>"
+syntax match pfmainRef "$\<mail_spool_directory\>"
+syntax match pfmainRef "$\<mail_version\>"
+syntax match pfmainRef "$\<mailbox_command\>"
+syntax match pfmainRef "$\<mailbox_command_maps\>"
+syntax match pfmainRef "$\<mailbox_delivery_lock\>"
+syntax match pfmainRef "$\<mailbox_size_limit\>"
+syntax match pfmainRef "$\<mailbox_transport\>"
+syntax match pfmainRef "$\<mailbox_transport_maps\>"
+syntax match pfmainRef "$\<mailq_path\>"
+syntax match pfmainRef "$\<manpage_directory\>"
+syntax match pfmainRef "$\<maps_rbl_domains\>"
+syntax match pfmainRef "$\<maps_rbl_reject_code\>"
+syntax match pfmainRef "$\<masquerade_classes\>"
+syntax match pfmainRef "$\<masquerade_domains\>"
+syntax match pfmainRef "$\<masquerade_exceptions\>"
+syntax match pfmainRef "$\<max_idle\>"
+syntax match pfmainRef "$\<max_use\>"
+syntax match pfmainRef "$\<maximal_backoff_time\>"
+syntax match pfmainRef "$\<maximal_queue_lifetime\>"
+syntax match pfmainRef "$\<message_reject_characters\>"
+syntax match pfmainRef "$\<message_size_limit\>"
+syntax match pfmainRef "$\<message_strip_characters\>"
+syntax match pfmainRef "$\<mime_boundary_length_limit\>"
+syntax match pfmainRef "$\<mime_header_checks\>"
+syntax match pfmainRef "$\<mime_nesting_limit\>"
+syntax match pfmainRef "$\<minimal_backoff_time\>"
+syntax match pfmainRef "$\<multi_recipient_bounce_reject_code\>"
+syntax match pfmainRef "$\<mydestination\>"
+syntax match pfmainRef "$\<mydomain\>"
+syntax match pfmainRef "$\<myhostname\>"
+syntax match pfmainRef "$\<mynetworks\>"
+syntax match pfmainRef "$\<mynetworks_style\>"
+syntax match pfmainRef "$\<myorigin\>"
+syntax match pfmainRef "$\<nested_header_checks\>"
+syntax match pfmainRef "$\<newaliases_path\>"
+syntax match pfmainRef "$\<non_fqdn_reject_code\>"
+syntax match pfmainRef "$\<notify_classes\>"
+syntax match pfmainRef "$\<owner_request_special\>"
+syntax match pfmainRef "$\<parent_domain_matches_subdomains\>"
+syntax match pfmainRef "$\<permit_mx_backup_networks\>"
+syntax match pfmainRef "$\<pickup_service_name\>"
+syntax match pfmainRef "$\<plaintext_reject_code\>"
+syntax match pfmainRef "$\<prepend_delivered_header\>"
+syntax match pfmainRef "$\<process_id_directory\>"
+syntax match pfmainRef "$\<propagate_unmatched_extensions\>"
+syntax match pfmainRef "$\<proxy_interfaces\>"
+syntax match pfmainRef "$\<proxy_read_maps\>"
+syntax match pfmainRef "$\<qmgr_clog_warn_time\>"
+syntax match pfmainRef "$\<qmgr_fudge_factor\>"
+syntax match pfmainRef "$\<qmgr_message_active_limit\>"
+syntax match pfmainRef "$\<qmgr_message_recipient_limit\>"
+syntax match pfmainRef "$\<qmgr_message_recipient_minimum\>"
+syntax match pfmainRef "$\<qmqpd_authorized_clients\>"
+syntax match pfmainRef "$\<qmqpd_error_delay\>"
+syntax match pfmainRef "$\<qmqpd_timeout\>"
+syntax match pfmainRef "$\<queue_directory\>"
+syntax match pfmainRef "$\<queue_file_attribute_count_limit\>"
+syntax match pfmainRef "$\<queue_minfree\>"
+syntax match pfmainRef "$\<queue_run_delay\>"
+syntax match pfmainRef "$\<queue_service_name\>"
+syntax match pfmainRef "$\<rbl_reply_maps\>"
+syntax match pfmainRef "$\<readme_directory\>"
+syntax match pfmainRef "$\<receive_override_options\>"
+syntax match pfmainRef "$\<recipient_bcc_maps\>"
+syntax match pfmainRef "$\<recipient_canonical_classes\>"
+syntax match pfmainRef "$\<recipient_canonical_maps\>"
+syntax match pfmainRef "$\<recipient_delimiter\>"
+syntax match pfmainRef "$\<reject_code\>"
+syntax match pfmainRef "$\<relay_clientcerts\>"
+syntax match pfmainRef "$\<relay_destination_concurrency_limit\>"
+syntax match pfmainRef "$\<relay_destination_recipient_limit\>"
+syntax match pfmainRef "$\<relay_domains\>"
+syntax match pfmainRef "$\<relay_domains_reject_code\>"
+syntax match pfmainRef "$\<relay_recipient_maps\>"
+syntax match pfmainRef "$\<relay_transport\>"
+syntax match pfmainRef "$\<relayhost\>"
+syntax match pfmainRef "$\<relocated_maps\>"
+syntax match pfmainRef "$\<remote_header_rewrite_domain\>"
+syntax match pfmainRef "$\<require_home_directory\>"
+syntax match pfmainRef "$\<resolve_dequoted_address\>"
+syntax match pfmainRef "$\<resolve_null_domain\>"
+syntax match pfmainRef "$\<resolve_numeric_domain\>"
+syntax match pfmainRef "$\<rewrite_service_name\>"
+syntax match pfmainRef "$\<sample_directory\>"
+syntax match pfmainRef "$\<sender_bcc_maps\>"
+syntax match pfmainRef "$\<sender_canonical_classes\>"
+syntax match pfmainRef "$\<sender_canonical_maps\>"
+syntax match pfmainRef "$\<sender_dependent_relayhost_maps\>"
+syntax match pfmainRef "$\<sendmail_path\>"
+syntax match pfmainRef "$\<service_throttle_time\>"
+syntax match pfmainRef "$\<setgid_group\>"
+syntax match pfmainRef "$\<show_user_unknown_table_name\>"
+syntax match pfmainRef "$\<showq_service_name\>"
+syntax match pfmainRef "$\<smtp_always_send_ehlo\>"
+syntax match pfmainRef "$\<smtp_bind_address\>"
+syntax match pfmainRef "$\<smtp_bind_address6\>"
+syntax match pfmainRef "$\<smtp_cname_overrides_servername\>"
+syntax match pfmainRef "$\<smtp_connect_timeout\>"
+syntax match pfmainRef "$\<smtp_connection_cache_destinations\>"
+syntax match pfmainRef "$\<smtp_connection_cache_on_demand\>"
+syntax match pfmainRef "$\<smtp_connection_cache_time_limit\>"
+syntax match pfmainRef "$\<smtp_connection_reuse_time_limit\>"
+syntax match pfmainRef "$\<smtp_data_done_timeout\>"
+syntax match pfmainRef "$\<smtp_data_init_timeout\>"
+syntax match pfmainRef "$\<smtp_data_xfer_timeout\>"
+syntax match pfmainRef "$\<smtp_defer_if_no_mx_address_found\>"
+syntax match pfmainRef "$\<smtp_destination_concurrency_limit\>"
+syntax match pfmainRef "$\<smtp_destination_recipient_limit\>"
+syntax match pfmainRef "$\<smtp_discard_ehlo_keyword_address_maps\>"
+syntax match pfmainRef "$\<smtp_discard_ehlo_keywords\>"
+syntax match pfmainRef "$\<smtp_enforce_tls\>"
+syntax match pfmainRef "$\<smtp_fallback_relay\>"
+syntax match pfmainRef "$\<smtp_generic_maps\>"
+syntax match pfmainRef "$\<smtp_helo_name\>"
+syntax match pfmainRef "$\<smtp_helo_timeout\>"
+syntax match pfmainRef "$\<smtp_host_lookup\>"
+syntax match pfmainRef "$\<smtp_line_length_limit\>"
+syntax match pfmainRef "$\<smtp_mail_timeout\>"
+syntax match pfmainRef "$\<smtp_mx_address_limit\>"
+syntax match pfmainRef "$\<smtp_mx_session_limit\>"
+syntax match pfmainRef "$\<smtp_never_send_ehlo\>"
+syntax match pfmainRef "$\<smtp_pix_workaround_delay_time\>"
+syntax match pfmainRef "$\<smtp_pix_workaround_threshold_time\>"
+syntax match pfmainRef "$\<smtp_quit_timeout\>"
+syntax match pfmainRef "$\<smtp_quote_rfc821_envelope\>"
+syntax match pfmainRef "$\<smtp_randomize_addresses\>"
+syntax match pfmainRef "$\<smtp_rcpt_timeout\>"
+syntax match pfmainRef "$\<smtp_rset_timeout\>"
+syntax match pfmainRef "$\<smtp_sasl_auth_enable\>"
+syntax match pfmainRef "$\<smtp_sasl_mechanism_filter\>"
+syntax match pfmainRef "$\<smtp_sasl_password_maps\>"
+syntax match pfmainRef "$\<smtp_sasl_path\>"
+syntax match pfmainRef "$\<smtp_sasl_security_options\>"
+syntax match pfmainRef "$\<smtp_sasl_tls_security_options\>"
+syntax match pfmainRef "$\<smtp_sasl_tls_verified_security_options\>"
+syntax match pfmainRef "$\<smtp_sasl_type\>"
+syntax match pfmainRef "$\<smtp_send_xforward_command\>"
+syntax match pfmainRef "$\<smtp_sender_dependent_authentication\>"
+syntax match pfmainRef "$\<smtp_skip_5xx_greeting\>"
+syntax match pfmainRef "$\<smtp_skip_quit_response\>"
+syntax match pfmainRef "$\<smtp_starttls_timeout\>"
+syntax match pfmainRef "$\<smtp_tls_CAfile\>"
+syntax match pfmainRef "$\<smtp_tls_CApath\>"
+syntax match pfmainRef "$\<smtp_tls_cert_file\>"
+syntax match pfmainRef "$\<smtp_tls_cipherlist\>"
+syntax match pfmainRef "$\<smtp_tls_dcert_file\>"
+syntax match pfmainRef "$\<smtp_tls_dkey_file\>"
+syntax match pfmainRef "$\<smtp_tls_enforce_peername\>"
+syntax match pfmainRef "$\<smtp_tls_key_file\>"
+syntax match pfmainRef "$\<smtp_tls_loglevel\>"
+syntax match pfmainRef "$\<smtp_tls_note_starttls_offer\>"
+syntax match pfmainRef "$\<smtp_tls_per_site\>"
+syntax match pfmainRef "$\<smtp_tls_scert_verifydepth\>"
+syntax match pfmainRef "$\<smtp_tls_session_cache_database\>"
+syntax match pfmainRef "$\<smtp_tls_session_cache_timeout\>"
+syntax match pfmainRef "$\<smtp_use_tls\>"
+syntax match pfmainRef "$\<smtp_xforward_timeout\>"
+syntax match pfmainRef "$\<smtpd_authorized_verp_clients\>"
+syntax match pfmainRef "$\<smtpd_authorized_xclient_hosts\>"
+syntax match pfmainRef "$\<smtpd_authorized_xforward_hosts\>"
+syntax match pfmainRef "$\<smtpd_banner\>"
+syntax match pfmainRef "$\<smtpd_client_connection_count_limit\>"
+syntax match pfmainRef "$\<smtpd_client_connection_rate_limit\>"
+syntax match pfmainRef "$\<smtpd_client_event_limit_exceptions\>"
+syntax match pfmainRef "$\<smtpd_client_message_rate_limit\>"
+syntax match pfmainRef "$\<smtpd_client_new_tls_session_rate_limit\>"
+syntax match pfmainRef "$\<smtpd_client_recipient_rate_limit\>"
+syntax match pfmainRef "$\<smtpd_client_restrictions\>"
+syntax match pfmainRef "$\<smtpd_data_restrictions\>"
+syntax match pfmainRef "$\<smtpd_delay_open_until_valid_rcpt\>"
+syntax match pfmainRef "$\<smtpd_delay_reject\>"
+syntax match pfmainRef "$\<smtpd_discard_ehlo_keyword_address_maps\>"
+syntax match pfmainRef "$\<smtpd_discard_ehlo_keywords\>"
+syntax match pfmainRef "$\<smtpd_end_of_data_restrictions\>"
+syntax match pfmainRef "$\<smtpd_enforce_tls\>"
+syntax match pfmainRef "$\<smtpd_error_sleep_time\>"
+syntax match pfmainRef "$\<smtpd_etrn_restrictions\>"
+syntax match pfmainRef "$\<smtpd_expansion_filter\>"
+syntax match pfmainRef "$\<smtpd_forbidden_commands\>"
+syntax match pfmainRef "$\<smtpd_hard_error_limit\>"
+syntax match pfmainRef "$\<smtpd_helo_required\>"
+syntax match pfmainRef "$\<smtpd_helo_restrictions\>"
+syntax match pfmainRef "$\<smtpd_history_flush_threshold\>"
+syntax match pfmainRef "$\<smtpd_junk_command_limit\>"
+syntax match pfmainRef "$\<smtpd_noop_commands\>"
+syntax match pfmainRef "$\<smtpd_null_access_lookup_key\>"
+syntax match pfmainRef "$\<smtpd_peername_lookup\>"
+syntax match pfmainRef "$\<smtpd_policy_service_max_idle\>"
+syntax match pfmainRef "$\<smtpd_policy_service_max_ttl\>"
+syntax match pfmainRef "$\<smtpd_policy_service_timeout\>"
+syntax match pfmainRef "$\<smtpd_proxy_ehlo\>"
+syntax match pfmainRef "$\<smtpd_proxy_filter\>"
+syntax match pfmainRef "$\<smtpd_proxy_timeout\>"
+syntax match pfmainRef "$\<smtpd_recipient_limit\>"
+syntax match pfmainRef "$\<smtpd_recipient_overshoot_limit\>"
+syntax match pfmainRef "$\<smtpd_recipient_restrictions\>"
+syntax match pfmainRef "$\<smtpd_reject_unlisted_recipient\>"
+syntax match pfmainRef "$\<smtpd_reject_unlisted_sender\>"
+syntax match pfmainRef "$\<smtpd_restriction_classes\>"
+syntax match pfmainRef "$\<smtpd_sasl_auth_enable\>"
+syntax match pfmainRef "$\<smtpd_sasl_authenticated_header\>"
+syntax match pfmainRef "$\<smtpd_sasl_exceptions_networks\>"
+syntax match pfmainRef "$\<smtpd_sasl_local_domain\>"
+syntax match pfmainRef "$\<smtpd_sasl_path\>"
+syntax match pfmainRef "$\<smtpd_sasl_security_options\>"
+syntax match pfmainRef "$\<smtpd_sasl_tls_security_options\>"
+syntax match pfmainRef "$\<smtpd_sasl_type\>"
+syntax match pfmainRef "$\<smtpd_sender_login_maps\>"
+syntax match pfmainRef "$\<smtpd_sender_restrictions\>"
+syntax match pfmainRef "$\<smtpd_soft_error_limit\>"
+syntax match pfmainRef "$\<smtpd_starttls_timeout\>"
+syntax match pfmainRef "$\<smtpd_timeout\>"
+syntax match pfmainRef "$\<smtpd_tls_CAfile\>"
+syntax match pfmainRef "$\<smtpd_tls_CApath\>"
+syntax match pfmainRef "$\<smtpd_tls_ask_ccert\>"
+syntax match pfmainRef "$\<smtpd_tls_auth_only\>"
+syntax match pfmainRef "$\<smtpd_tls_ccert_verifydepth\>"
+syntax match pfmainRef "$\<smtpd_tls_cert_file\>"
+syntax match pfmainRef "$\<smtpd_tls_cipherlist\>"
+syntax match pfmainRef "$\<smtpd_tls_dcert_file\>"
+syntax match pfmainRef "$\<smtpd_tls_dh1024_param_file\>"
+syntax match pfmainRef "$\<smtpd_tls_dh512_param_file\>"
+syntax match pfmainRef "$\<smtpd_tls_dkey_file\>"
+syntax match pfmainRef "$\<smtpd_tls_key_file\>"
+syntax match pfmainRef "$\<smtpd_tls_loglevel\>"
+syntax match pfmainRef "$\<smtpd_tls_received_header\>"
+syntax match pfmainRef "$\<smtpd_tls_req_ccert\>"
+syntax match pfmainRef "$\<smtpd_tls_session_cache_database\>"
+syntax match pfmainRef "$\<smtpd_tls_session_cache_timeout\>"
+syntax match pfmainRef "$\<smtpd_tls_wrappermode\>"
+syntax match pfmainRef "$\<smtpd_use_tls\>"
+syntax match pfmainRef "$\<soft_bounce\>"
+syntax match pfmainRef "$\<stale_lock_time\>"
+syntax match pfmainRef "$\<strict_7bit_headers\>"
+syntax match pfmainRef "$\<strict_8bitmime\>"
+syntax match pfmainRef "$\<strict_8bitmime_body\>"
+syntax match pfmainRef "$\<strict_mime_encoding_domain\>"
+syntax match pfmainRef "$\<strict_rfc821_envelopes\>"
+syntax match pfmainRef "$\<sun_mailtool_compatibility\>"
+syntax match pfmainRef "$\<swap_bangpath\>"
+syntax match pfmainRef "$\<syslog_facility\>"
+syntax match pfmainRef "$\<syslog_name\>"
+syntax match pfmainRef "$\<tls_daemon_random_bytes\>"
+syntax match pfmainRef "$\<tls_random_bytes\>"
+syntax match pfmainRef "$\<tls_random_exchange_name\>"
+syntax match pfmainRef "$\<tls_random_prng_update_period\>"
+syntax match pfmainRef "$\<tls_random_reseed_period\>"
+syntax match pfmainRef "$\<tls_random_source\>"
+syntax match pfmainRef "$\<trace_service_name\>"
+syntax match pfmainRef "$\<transport_maps\>"
+syntax match pfmainRef "$\<transport_retry_time\>"
+syntax match pfmainRef "$\<trigger_timeout\>"
+syntax match pfmainRef "$\<undisclosed_recipients_header\>"
+syntax match pfmainRef "$\<unknown_address_reject_code\>"
+syntax match pfmainRef "$\<unknown_client_reject_code\>"
+syntax match pfmainRef "$\<unknown_hostname_reject_code\>"
+syntax match pfmainRef "$\<unknown_local_recipient_reject_code\>"
+syntax match pfmainRef "$\<unknown_relay_recipient_reject_code\>"
+syntax match pfmainRef "$\<unknown_virtual_alias_reject_code\>"
+syntax match pfmainRef "$\<unknown_virtual_mailbox_reject_code\>"
+syntax match pfmainRef "$\<unverified_recipient_reject_code\>"
+syntax match pfmainRef "$\<unverified_sender_reject_code\>"
+syntax match pfmainRef "$\<verp_delimiter_filter\>"
+syntax match pfmainRef "$\<virtual_alias_domains\>"
+syntax match pfmainRef "$\<virtual_alias_expansion_limit\>"
+syntax match pfmainRef "$\<virtual_alias_maps\>"
+syntax match pfmainRef "$\<virtual_alias_recursion_limit\>"
+syntax match pfmainRef "$\<virtual_destination_concurrency_limit\>"
+syntax match pfmainRef "$\<virtual_destination_recipient_limit\>"
+syntax match pfmainRef "$\<virtual_gid_maps\>"
+syntax match pfmainRef "$\<virtual_mailbox_base\>"
+syntax match pfmainRef "$\<virtual_mailbox_domains\>"
+syntax match pfmainRef "$\<virtual_mailbox_limit\>"
+syntax match pfmainRef "$\<virtual_mailbox_lock\>"
+syntax match pfmainRef "$\<virtual_mailbox_maps\>"
+syntax match pfmainRef "$\<virtual_minimum_uid\>"
+syntax match pfmainRef "$\<virtual_transport\>"
+syntax match pfmainRef "$\<virtual_uid_maps\>"
+syntax keyword pfmainWord all
+syntax keyword pfmainWord check_address_map
+syntax keyword pfmainWord check_ccert_access
+syntax keyword pfmainWord check_client_access
+syntax keyword pfmainWord check_etrn_access
+syntax keyword pfmainWord check_helo_access
+syntax keyword pfmainWord check_helo_mx_access
+syntax keyword pfmainWord check_helo_ns_access
+syntax keyword pfmainWord check_policy_service
+syntax keyword pfmainWord check_recipient_access
+syntax keyword pfmainWord check_recipient_maps
+syntax keyword pfmainWord check_recipient_mx_access
+syntax keyword pfmainWord check_recipient_ns_access
+syntax keyword pfmainWord check_relay_domains
+syntax keyword pfmainWord check_sender_access
+syntax keyword pfmainWord check_sender_mx_access
+syntax keyword pfmainWord check_sender_ns_access
+syntax keyword pfmainWord class
+syntax keyword pfmainWord defer_if_permit
+syntax keyword pfmainWord defer_if_reject
+syntax keyword pfmainWord dns
+syntax keyword pfmainWord envelope_recipient
+syntax keyword pfmainWord envelope_sender
+syntax keyword pfmainWord header_recipient
+syntax keyword pfmainWord header_sender
+syntax keyword pfmainWord host
+syntax keyword pfmainWord ipv4
+syntax keyword pfmainWord ipv6
+syntax keyword pfmainWord native
+syntax keyword pfmainWord permit
+syntax keyword pfmainWord permit_auth_destination
+syntax keyword pfmainWord permit_inet_interfaces
+syntax keyword pfmainWord permit_mx_backup
+syntax keyword pfmainWord permit_mynetworks
+syntax keyword pfmainWord permit_naked_ip_address
+syntax keyword pfmainWord permit_sasl_authenticated
+syntax keyword pfmainWord permit_tls_all_clientcerts
+syntax keyword pfmainWord permit_tls_clientcerts
+syntax keyword pfmainWord reject
+syntax keyword pfmainWord reject_invalid_helo_hostname
+syntax keyword pfmainWord reject_invalid_hostname
+syntax keyword pfmainWord reject_maps_rbl
+syntax keyword pfmainWord reject_multi_recipient_bounce
+syntax keyword pfmainWord reject_non_fqdn_helo_hostname
+syntax keyword pfmainWord reject_non_fqdn_hostname
+syntax keyword pfmainWord reject_non_fqdn_recipient
+syntax keyword pfmainWord reject_non_fqdn_sender
+syntax keyword pfmainWord reject_plaintext_session
+syntax keyword pfmainWord reject_rbl
+syntax keyword pfmainWord reject_rbl_client
+syntax keyword pfmainWord reject_rhsbl_client
+syntax keyword pfmainWord reject_rhsbl_helo
+syntax keyword pfmainWord reject_rhsbl_recipient
+syntax keyword pfmainWord reject_rhsbl_sender
+syntax keyword pfmainWord reject_sender_login_mismatch
+syntax keyword pfmainWord reject_unauth_destination
+syntax keyword pfmainWord reject_unauth_pipelining
+syntax keyword pfmainWord reject_unknown_address
+syntax keyword pfmainWord reject_unknown_client
+syntax keyword pfmainWord reject_unknown_client_hostname
+syntax keyword pfmainWord reject_unknown_forward_client_hostname
+syntax keyword pfmainWord reject_unknown_helo_hostname
+syntax keyword pfmainWord reject_unknown_hostname
+syntax keyword pfmainWord reject_unknown_recipient_domain
+syntax keyword pfmainWord reject_unknown_reverse_client_hostname
+syntax keyword pfmainWord reject_unknown_sender_domain
+syntax keyword pfmainWord reject_unlisted_recipient
+syntax keyword pfmainWord reject_unlisted_sender
+syntax keyword pfmainWord reject_unverified_recipient
+syntax keyword pfmainWord reject_unverified_sender
+syntax keyword pfmainWord sleep
+syntax keyword pfmainWord smtpd_access_maps
+syntax keyword pfmainWord subnet
+syntax keyword pfmainWord warn_if_reject
+
+syntax keyword pfmainDict	btree cidr environ hash nis pcre proxy regexp sdbm sdbm static tcp unix
+syntax keyword pfmainQueueDir	incoming active deferred corrupt hold
+syntax keyword pfmainTransport	smtp lmtp unix local relay uucp virtual
+syntax keyword pfmainLock	fcntl flock dotlock
+syntax keyword pfmainAnswer	yes no
+
+syntax match pfmainComment	"#.*$"
+syntax match pfmainNumber	"\<\d\+\>"
+syntax match pfmainTime		"\<\d\+[hmsd]\>"
+syntax match pfmainIP		"\<\d\{1,3}\.\d\{1,3}\.\d\{1,3}\.\d\{1,3}\>"
+syntax match pfmainVariable	"\$\w\+" contains=pfmainRef
+
+syntax match pfmainSpecial	"\<alias\>"
+syntax match pfmainSpecial	"\<canonical\>"
+syntax match pfmainSpecial	"\<command\>"
+syntax match pfmainSpecial	"\<file\>"
+syntax match pfmainSpecial	"\<forward\>"
+syntax match pfmainSpecial	"\<noanonymous\>"
+syntax match pfmainSpecial	"\<noplaintext\>"
+syntax match pfmainSpecial	"\<resource\>"
+syntax match pfmainSpecial	"\<software\>"
+
+syntax match pfmainSpecial	"\<bounce\>"
+syntax match pfmainSpecial	"\<cleanup\>"
+syntax match pfmainSpecial	"\<cyrus\>"
+syntax match pfmainSpecial	"\<defer\>"
+syntax match pfmainSpecial	"\<error\>"
+syntax match pfmainSpecial	"\<flush\>"
+syntax match pfmainSpecial	"\<pickup\>"
+syntax match pfmainSpecial	"\<postdrop\>"
+syntax match pfmainSpecial	"\<qmgr\>"
+syntax match pfmainSpecial	"\<rewrite\>"
+syntax match pfmainSpecial	"\<scache\>"
+syntax match pfmainSpecial	"\<showq\>"
+syntax match pfmainSpecial	"\<trace\>"
+syntax match pfmainSpecial	"\<verify\>"
+
+if version >= 508 || !exists("pfmain_syntax_init")
+	if version < 508
+		let pfmain_syntax_init = 1
+		command -nargs=+ HiLink hi link <args>
+	else
+		command -nargs=+ HiLink hi def link <args>
+	endif
+
+	HiLink pfmainConf	Statement
+	HiLink pfmainRef	PreProc
+	HiLink pfmainWord	identifier
+
+	HiLink pfmainDict	Type
+	HiLink pfmainQueueDir	Constant
+	HiLink pfmainTransport	Constant
+	HiLink pfmainLock	Constant
+	HiLink pfmainAnswer	Constant
+
+	HiLink pfmainComment	Comment
+	HiLink pfmainNumber	Number
+	HiLink pfmainTime	Number
+	HiLink pfmainIP		Number
+	HiLink pfmainVariable	Error
+	HiLink pfmainSpecial	Special
+
+	delcommand HiLink
+endif
+
+let b:current_syntax = "pfmain"
+
+" vim: ts=8 sw=2
--- /dev/null
+++ b/lib/vimfiles/syntax/php.vim
@@ -1,0 +1,649 @@
+" Vim syntax file
+" Language: php PHP 3/4/5
+" Maintainer: Peter Hodge <toomuchphp-vim@yahoo.com>
+" Last Change:  June 9, 2006
+" URL: http://www.vim.org/scripts/script.php?script_id=1571
+"
+" Former Maintainer:  Debian VIM Maintainers <pkg-vim-maintainers@lists.alioth.debian.org>
+" Former URL: http://svn.debian.org/wsvn/pkg-vim/trunk/runtime/syntax/php.vim?op=file&rev=0&sc=0
+"
+" Note: If you are using a colour terminal with dark background, you will probably find
+"       the 'elflord' colorscheme is much better for PHP's syntax than the default
+"       colourscheme, because elflord's colours will better highlight the break-points
+"       (Statements) in your code.
+"
+" Options:  php_sql_query = 1  for SQL syntax highlighting inside strings
+"           php_htmlInStrings = 1  for HTML syntax highlighting inside strings
+"           php_baselib = 1  for highlighting baselib functions
+"           php_asp_tags = 1  for highlighting ASP-style short tags
+"           php_parent_error_close = 1  for highlighting parent error ] or )
+"           php_parent_error_open = 1  for skipping an php end tag, if there exists an open ( or [ without a closing one
+"           php_oldStyle = 1  for using old colorstyle
+"           php_noShortTags = 1  don't sync <? ?> as php
+"           php_folding = 1  for folding classes and functions
+"           php_folding = 2  for folding all { } regions
+"           php_sync_method = x
+"                             x=-1 to sync by search ( default )
+"                             x>0 to sync at least x lines backwards
+"                             x=0 to sync from start
+"
+"       Added by Peter Hodge On June 9, 2006:
+"           php_special_functions = 1|0 to highlight functions with abnormal behaviour
+"           php_alt_comparisons = 1|0 to highlight comparison operators in an alternate colour
+"           php_alt_assignByReference = 1|0 to highlight '= &' in an alternate colour
+"
+"           Note: these all default to 1 (On), so you would set them to '0' to turn them off.
+"                 E.g., in your .vimrc or _vimrc file:
+"                   let php_special_functions = 0
+"                   let php_alt_comparisons = 0
+"                   let php_alt_assignByReference = 0
+"                 Unletting these variables will revert back to their default (On).
+"
+"
+" Note:
+" Setting php_folding=1 will match a closing } by comparing the indent
+" before the class or function keyword with the indent of a matching }.
+" Setting php_folding=2 will match all of pairs of {,} ( see known
+" bugs ii )
+
+" Known Bugs:
+"  - setting  php_parent_error_close  on  and  php_parent_error_open  off
+"    has these two leaks:
+"     i) A closing ) or ] inside a string match to the last open ( or [
+"        before the string, when the the closing ) or ] is on the same line
+"        where the string started. In this case a following ) or ] after
+"        the string would be highlighted as an error, what is incorrect.
+"    ii) Same problem if you are setting php_folding = 2 with a closing
+"        } inside an string on the first line of this string.
+"
+"  - A double-quoted string like this:
+"      "$foo->someVar->someOtherVar->bar"
+"    will highight '->someOtherVar->bar' as though they will be parsed
+"    as object member variables, but PHP only recognizes the first
+"    object member variable ($foo->someVar).
+"
+"
+
+" For version 5.x: Clear all syntax items
+" For version 6.x: Quit when a syntax file was already loaded
+if version < 600
+  syntax clear
+elseif exists("b:current_syntax")
+  finish
+endif
+
+if !exists("main_syntax")
+  let main_syntax = 'php'
+endif
+
+if version < 600
+  unlet! php_folding
+  if exists("php_sync_method") && !php_sync_method
+    let php_sync_method=-1
+  endif
+  so <sfile>:p:h/html.vim
+else
+  runtime syntax/html.vim
+  unlet b:current_syntax
+endif
+
+" accept old options
+if !exists("php_sync_method")
+  if exists("php_minlines")
+    let php_sync_method=php_minlines
+  else
+    let php_sync_method=-1
+  endif
+endif
+
+if exists("php_parentError") && !exists("php_parent_error_open") && !exists("php_parent_error_close")
+  let php_parent_error_close=1
+  let php_parent_error_open=1
+endif
+
+syn cluster htmlPreproc add=phpRegion,phpRegionAsp,phpRegionSc
+
+if version < 600
+  syn include @sqlTop <sfile>:p:h/sql.vim
+else
+  syn include @sqlTop syntax/sql.vim
+endif
+syn sync clear
+unlet b:current_syntax
+syn cluster sqlTop remove=sqlString,sqlComment
+if exists( "php_sql_query")
+  syn cluster phpAddStrings contains=@sqlTop
+endif
+
+if exists( "php_htmlInStrings")
+  syn cluster phpAddStrings add=@htmlTop
+endif
+
+syn case match
+
+" Env Variables
+syn keyword phpEnvVar GATEWAY_INTERFACE SERVER_NAME SERVER_SOFTWARE SERVER_PROTOCOL REQUEST_METHOD QUERY_STRING DOCUMENT_ROOT HTTP_ACCEPT HTTP_ACCEPT_CHARSET HTTP_ENCODING HTTP_ACCEPT_LANGUAGE HTTP_CONNECTION HTTP_HOST HTTP_REFERER HTTP_USER_AGENT REMOTE_ADDR REMOTE_PORT SCRIPT_FILENAME SERVER_ADMIN SERVER_PORT SERVER_SIGNATURE PATH_TRANSLATED SCRIPT_NAME REQUEST_URI contained
+
+" Internal Variables
+syn keyword phpIntVar GLOBALS PHP_ERRMSG PHP_SELF HTTP_GET_VARS HTTP_POST_VARS HTTP_COOKIE_VARS HTTP_POST_FILES HTTP_ENV_VARS HTTP_SERVER_VARS HTTP_SESSION_VARS HTTP_RAW_POST_DATA HTTP_STATE_VARS _GET _POST _COOKIE _FILES _SERVER _ENV _SERVER _REQUEST _SESSION  contained
+
+" Constants
+syn keyword phpCoreConstant PHP_VERSION PHP_OS DEFAULT_INCLUDE_PATH PEAR_INSTALL_DIR PEAR_EXTENSION_DIR PHP_EXTENSION_DIR PHP_BINDIR PHP_LIBDIR PHP_DATADIR PHP_SYSCONFDIR PHP_LOCALSTATEDIR PHP_CONFIG_FILE_PATH PHP_OUTPUT_HANDLER_START PHP_OUTPUT_HANDLER_CONT PHP_OUTPUT_HANDLER_END E_ERROR E_WARNING E_PARSE E_NOTICE E_CORE_ERROR E_CORE_WARNING E_COMPILE_ERROR E_COMPILE_WARNING E_USER_ERROR E_USER_WARNING E_USER_NOTICE E_ALL  contained
+
+syn case ignore
+
+syn keyword phpConstant  __LINE__ __FILE__ __FUNCTION__ __METHOD__ __CLASS__  contained
+
+
+" Function and Methods ripped from php_manual_de.tar.gz Jan 2003
+syn keyword phpFunctions  apache_child_terminate apache_get_modules apache_get_version apache_getenv apache_lookup_uri apache_note apache_request_headers apache_response_headers apache_setenv ascii2ebcdic ebcdic2ascii getallheaders virtual contained
+syn keyword phpFunctions  array_change_key_case array_chunk array_combine array_count_values array_diff_assoc array_diff_uassoc array_diff array_fill array_filter array_flip array_intersect_assoc array_intersect array_key_exists array_keys array_map array_merge_recursive array_merge array_multisort array_pad array_pop array_push array_rand array_reduce array_reverse array_search array_shift array_slice array_splice array_sum array_udiff_assoc array_udiff_uassoc array_udiff array_unique array_unshift array_values array_walk array arsort asort compact count current each end extract in_array key krsort ksort list natcasesort natsort next pos prev range reset rsort shuffle sizeof sort uasort uksort usort contained
+syn keyword phpFunctions  aspell_check aspell_new aspell_suggest  contained
+syn keyword phpFunctions  bcadd bccomp bcdiv bcmod bcmul bcpow bcpowmod bcscale bcsqrt bcsub  contained
+syn keyword phpFunctions  bzclose bzcompress bzdecompress bzerrno bzerror bzerrstr bzflush bzopen bzread bzwrite  contained
+syn keyword phpFunctions  cal_days_in_month cal_from_jd cal_info cal_to_jd easter_date easter_days frenchtojd gregoriantojd jddayofweek jdmonthname jdtofrench jdtogregorian jdtojewish jdtojulian jdtounix jewishtojd juliantojd unixtojd  contained
+syn keyword phpFunctions  ccvs_add ccvs_auth ccvs_command ccvs_count ccvs_delete ccvs_done ccvs_init ccvs_lookup ccvs_new ccvs_report ccvs_return ccvs_reverse ccvs_sale ccvs_status ccvs_textvalue ccvs_void contained
+syn keyword phpFunctions  call_user_method_array call_user_method class_exists get_class_methods get_class_vars get_class get_declared_classes get_object_vars get_parent_class is_a is_subclass_of method_exists contained
+syn keyword phpFunctions  com VARIANT com_addref com_get com_invoke com_isenum com_load_typelib com_load com_propget com_propput com_propset com_release com_set  contained
+syn keyword phpFunctions  cpdf_add_annotation cpdf_add_outline cpdf_arc cpdf_begin_text cpdf_circle cpdf_clip cpdf_close cpdf_closepath_fill_stroke cpdf_closepath_stroke cpdf_closepath cpdf_continue_text cpdf_curveto cpdf_end_text cpdf_fill_stroke cpdf_fill cpdf_finalize_page cpdf_finalize cpdf_global_set_document_limits cpdf_import_jpeg cpdf_lineto cpdf_moveto cpdf_newpath cpdf_open cpdf_output_buffer cpdf_page_init cpdf_place_inline_image cpdf_rect cpdf_restore cpdf_rlineto cpdf_rmoveto cpdf_rotate_text cpdf_rotate cpdf_save_to_file cpdf_save cpdf_scale cpdf_set_action_url cpdf_set_char_spacing cpdf_set_creator cpdf_set_current_page cpdf_set_font_directories cpdf_set_font_map_file cpdf_set_font cpdf_set_horiz_scaling cpdf_set_keywords cpdf_set_leading cpdf_set_page_animation cpdf_set_subject cpdf_set_text_matrix cpdf_set_text_pos cpdf_set_text_rendering cpdf_set_text_rise cpdf_set_title cpdf_set_viewer_preferences cpdf_set_word_spacing cpdf_setdash cpdf_setflat cpdf_setgray_fill cpdf_setgray_stroke cpdf_setgray cpdf_setlinecap cpdf_setlinejoin cpdf_setlinewidth cpdf_setmiterlimit cpdf_setrgbcolor_fill cpdf_setrgbcolor_stroke cpdf_setrgbcolor cpdf_show_xy cpdf_show cpdf_stringwidth cpdf_stroke cpdf_text cpdf_translate  contained
+syn keyword phpFunctions  crack_check crack_closedict crack_getlastmessage crack_opendict contained
+syn keyword phpFunctions  ctype_alnum ctype_alpha ctype_cntrl ctype_digit ctype_graph ctype_lower ctype_print ctype_punct ctype_space ctype_upper ctype_xdigit  contained
+syn keyword phpFunctions  curl_close curl_errno curl_error curl_exec curl_getinfo curl_init curl_multi_add_handle curl_multi_close curl_multi_exec curl_multi_getcontent curl_multi_info_read curl_multi_init curl_multi_remove_handle curl_multi_select curl_setopt curl_version contained
+syn keyword phpFunctions  cybercash_base64_decode cybercash_base64_encode cybercash_decr cybercash_encr contained
+syn keyword phpFunctions  cyrus_authenticate cyrus_bind cyrus_close cyrus_connect cyrus_query cyrus_unbind  contained
+syn keyword phpFunctions  checkdate date getdate gettimeofday gmdate gmmktime gmstrftime localtime microtime mktime strftime strtotime time contained
+syn keyword phpFunctions  dba_close dba_delete dba_exists dba_fetch dba_firstkey dba_handlers dba_insert dba_key_split dba_list dba_nextkey dba_open dba_optimize dba_popen dba_replace dba_sync  contained
+syn keyword phpFunctions  dbase_add_record dbase_close dbase_create dbase_delete_record dbase_get_header_info dbase_get_record_with_names dbase_get_record dbase_numfields dbase_numrecords dbase_open dbase_pack dbase_replace_record  contained
+syn keyword phpFunctions  dblist dbmclose dbmdelete dbmexists dbmfetch dbmfirstkey dbminsert dbmnextkey dbmopen dbmreplace  contained
+syn keyword phpFunctions  dbplus_add dbplus_aql dbplus_chdir dbplus_close dbplus_curr dbplus_errcode dbplus_errno dbplus_find dbplus_first dbplus_flush dbplus_freealllocks dbplus_freelock dbplus_freerlocks dbplus_getlock dbplus_getunique dbplus_info dbplus_last dbplus_lockrel dbplus_next dbplus_open dbplus_prev dbplus_rchperm dbplus_rcreate dbplus_rcrtexact dbplus_rcrtlike dbplus_resolve dbplus_restorepos dbplus_rkeys dbplus_ropen dbplus_rquery dbplus_rrename dbplus_rsecindex dbplus_runlink dbplus_rzap dbplus_savepos dbplus_setindex dbplus_setindexbynumber dbplus_sql dbplus_tcl dbplus_tremove dbplus_undo dbplus_undoprepare dbplus_unlockrel dbplus_unselect dbplus_update dbplus_xlockrel dbplus_xunlockrel contained
+syn keyword phpFunctions  dbx_close dbx_compare dbx_connect dbx_error dbx_escape_string dbx_fetch_row dbx_query dbx_sort  contained
+syn keyword phpFunctions  dio_close dio_fcntl dio_open dio_read dio_seek dio_stat dio_tcsetattr dio_truncate dio_write  contained
+syn keyword phpFunctions  chdir chroot dir closedir getcwd opendir readdir rewinddir scandir  contained
+syn keyword phpFunctions  domxml_new_doc domxml_open_file domxml_open_mem domxml_version domxml_xmltree domxml_xslt_stylesheet_doc domxml_xslt_stylesheet_file domxml_xslt_stylesheet xpath_eval_expression xpath_eval xpath_new_context xptr_eval xptr_new_context contained
+syn keyword phpMethods  name specified value create_attribute create_cdata_section create_comment create_element_ns create_element create_entity_reference create_processing_instruction create_text_node doctype document_element dump_file dump_mem get_element_by_id get_elements_by_tagname html_dump_mem xinclude entities internal_subset name notations public_id system_id get_attribute_node get_attribute get_elements_by_tagname has_attribute remove_attribute set_attribute tagname add_namespace append_child append_sibling attributes child_nodes clone_node dump_node first_child get_content has_attributes has_child_nodes insert_before is_blank_node last_child next_sibling node_name node_type node_value owner_document parent_node prefix previous_sibling remove_child replace_child replace_node set_content set_name set_namespace unlink_node data target process result_dump_file result_dump_mem contained
+syn keyword phpFunctions  dotnet_load contained
+syn keyword phpFunctions  debug_backtrace debug_print_backtrace error_log error_reporting restore_error_handler set_error_handler trigger_error user_error  contained
+syn keyword phpFunctions  escapeshellarg escapeshellcmd exec passthru proc_close proc_get_status proc_nice proc_open proc_terminate shell_exec system contained
+syn keyword phpFunctions  fam_cancel_monitor fam_close fam_monitor_collection fam_monitor_directory fam_monitor_file fam_next_event fam_open fam_pending fam_resume_monitor fam_suspend_monitor contained
+syn keyword phpFunctions  fbsql_affected_rows fbsql_autocommit fbsql_change_user fbsql_close fbsql_commit fbsql_connect fbsql_create_blob fbsql_create_clob fbsql_create_db fbsql_data_seek fbsql_database_password fbsql_database fbsql_db_query fbsql_db_status fbsql_drop_db fbsql_errno fbsql_error fbsql_fetch_array fbsql_fetch_assoc fbsql_fetch_field fbsql_fetch_lengths fbsql_fetch_object fbsql_fetch_row fbsql_field_flags fbsql_field_len fbsql_field_name fbsql_field_seek fbsql_field_table fbsql_field_type fbsql_free_result fbsql_get_autostart_info fbsql_hostname fbsql_insert_id fbsql_list_dbs fbsql_list_fields fbsql_list_tables fbsql_next_result fbsql_num_fields fbsql_num_rows fbsql_password fbsql_pconnect fbsql_query fbsql_read_blob fbsql_read_clob fbsql_result fbsql_rollback fbsql_select_db fbsql_set_lob_mode fbsql_set_transaction fbsql_start_db fbsql_stop_db fbsql_tablename fbsql_username fbsql_warnings  contained
+syn keyword phpFunctions  fdf_add_doc_javascript fdf_add_template fdf_close fdf_create fdf_enum_values fdf_errno fdf_error fdf_get_ap fdf_get_attachment fdf_get_encoding fdf_get_file fdf_get_flags fdf_get_opt fdf_get_status fdf_get_value fdf_get_version fdf_header fdf_next_field_name fdf_open_string fdf_open fdf_remove_item fdf_save_string fdf_save fdf_set_ap fdf_set_encoding fdf_set_file fdf_set_flags fdf_set_javascript_action fdf_set_opt fdf_set_status fdf_set_submit_form_action fdf_set_target_frame fdf_set_value fdf_set_version  contained
+syn keyword phpFunctions  filepro_fieldcount filepro_fieldname filepro_fieldtype filepro_fieldwidth filepro_retrieve filepro_rowcount filepro contained
+syn keyword phpFunctions  basename chgrp chmod chown clearstatcache copy delete dirname disk_free_space disk_total_space diskfreespace fclose feof fflush fgetc fgetcsv fgets fgetss file_exists file_get_contents file_put_contents file fileatime filectime filegroup fileinode filemtime fileowner fileperms filesize filetype flock fnmatch fopen fpassthru fputs fread fscanf fseek fstat ftell ftruncate fwrite glob is_dir is_executable is_file is_link is_readable is_uploaded_file is_writable is_writeable link linkinfo lstat mkdir move_uploaded_file parse_ini_file pathinfo pclose popen readfile readlink realpath rename rewind rmdir set_file_buffer stat symlink tempnam tmpfile touch umask unlink  contained
+syn keyword phpFunctions  fribidi_log2vis contained
+syn keyword phpFunctions  ftp_alloc ftp_cdup ftp_chdir ftp_chmod ftp_close ftp_connect ftp_delete ftp_exec ftp_fget ftp_fput ftp_get_option ftp_get ftp_login ftp_mdtm ftp_mkdir ftp_nb_continue ftp_nb_fget ftp_nb_fput ftp_nb_get ftp_nb_put ftp_nlist ftp_pasv ftp_put ftp_pwd ftp_quit ftp_raw ftp_rawlist ftp_rename ftp_rmdir ftp_set_option ftp_site ftp_size ftp_ssl_connect ftp_systype  contained
+syn keyword phpFunctions  call_user_func_array call_user_func create_function func_get_arg func_get_args func_num_args function_exists get_defined_functions register_shutdown_function register_tick_function unregister_tick_function contained
+syn keyword phpFunctions  bind_textdomain_codeset bindtextdomain dcgettext dcngettext dgettext dngettext gettext ngettext textdomain  contained
+syn keyword phpFunctions  gmp_abs gmp_add gmp_and gmp_clrbit gmp_cmp gmp_com gmp_div_q gmp_div_qr gmp_div_r gmp_div gmp_divexact gmp_fact gmp_gcd gmp_gcdext gmp_hamdist gmp_init gmp_intval gmp_invert gmp_jacobi gmp_legendre gmp_mod gmp_mul gmp_neg gmp_or gmp_perfect_square gmp_popcount gmp_pow gmp_powm gmp_prob_prime gmp_random gmp_scan0 gmp_scan1 gmp_setbit gmp_sign gmp_sqrt gmp_sqrtrem gmp_sqrtrm gmp_strval gmp_sub gmp_xor  contained
+syn keyword phpFunctions  header headers_list headers_sent setcookie  contained
+syn keyword phpFunctions  hw_api_attribute hwapi_hgcsp hw_api_content hw_api_object contained
+syn keyword phpMethods  key langdepvalue value values checkin checkout children mimetype read content copy dbstat dcstat dstanchors dstofsrcanchors count reason find ftstat hwstat identify info insert insertanchor insertcollection insertdocument link lock move assign attreditable count insert remove title value object objectbyanchor parents description type remove replace setcommitedversion srcanchors srcsofdst unlock user userlist contained
+syn keyword phpFunctions  hw_Array2Objrec hw_changeobject hw_Children hw_ChildrenObj hw_Close hw_Connect hw_connection_info hw_cp hw_Deleteobject hw_DocByAnchor hw_DocByAnchorObj hw_Document_Attributes hw_Document_BodyTag hw_Document_Content hw_Document_SetContent hw_Document_Size hw_dummy hw_EditText hw_Error hw_ErrorMsg hw_Free_Document hw_GetAnchors hw_GetAnchorsObj hw_GetAndLock hw_GetChildColl hw_GetChildCollObj hw_GetChildDocColl hw_GetChildDocCollObj hw_GetObject hw_GetObjectByQuery hw_GetObjectByQueryColl hw_GetObjectByQueryCollObj hw_GetObjectByQueryObj hw_GetParents hw_GetParentsObj hw_getrellink hw_GetRemote hw_getremotechildren hw_GetSrcByDestObj hw_GetText hw_getusername hw_Identify hw_InCollections hw_Info hw_InsColl hw_InsDoc hw_insertanchors hw_InsertDocument hw_InsertObject hw_mapid hw_Modifyobject hw_mv hw_New_Document hw_objrec2array hw_Output_Document hw_pConnect hw_PipeDocument hw_Root hw_setlinkroot hw_stat hw_Unlock hw_Who contained
+syn keyword phpFunctions  ibase_add_user ibase_affected_rows ibase_blob_add ibase_blob_cancel ibase_blob_close ibase_blob_create ibase_blob_echo ibase_blob_get ibase_blob_import ibase_blob_info ibase_blob_open ibase_close ibase_commit_ret ibase_commit ibase_connect ibase_delete_user ibase_drop_db ibase_errcode ibase_errmsg ibase_execute ibase_fetch_assoc ibase_fetch_object ibase_fetch_row ibase_field_info ibase_free_event_handler ibase_free_query ibase_free_result ibase_gen_id ibase_modify_user ibase_name_result ibase_num_fields ibase_num_params ibase_param_info ibase_pconnect ibase_prepare ibase_query ibase_rollback_ret ibase_rollback ibase_set_event_handler ibase_timefmt ibase_trans ibase_wait_event  contained
+syn keyword phpFunctions  iconv_get_encoding iconv_mime_decode_headers iconv_mime_decode iconv_mime_encode iconv_set_encoding iconv_strlen iconv_strpos iconv_strrpos iconv_substr iconv ob_iconv_handler contained
+syn keyword phpFunctions  ifx_affected_rows ifx_blobinfile_mode ifx_byteasvarchar ifx_close ifx_connect ifx_copy_blob ifx_create_blob ifx_create_char ifx_do ifx_error ifx_errormsg ifx_fetch_row ifx_fieldproperties ifx_fieldtypes ifx_free_blob ifx_free_char ifx_free_result ifx_get_blob ifx_get_char ifx_getsqlca ifx_htmltbl_result ifx_nullformat ifx_num_fields ifx_num_rows ifx_pconnect ifx_prepare ifx_query ifx_textasvarchar ifx_update_blob ifx_update_char ifxus_close_slob ifxus_create_slob ifxus_free_slob ifxus_open_slob ifxus_read_slob ifxus_seek_slob ifxus_tell_slob ifxus_write_slob  contained
+syn keyword phpFunctions  exif_imagetype exif_read_data exif_thumbnail gd_info getimagesize image_type_to_mime_type image2wbmp imagealphablending imageantialias imagearc imagechar imagecharup imagecolorallocate imagecolorallocatealpha imagecolorat imagecolorclosest imagecolorclosestalpha imagecolorclosesthwb imagecolordeallocate imagecolorexact imagecolorexactalpha imagecolormatch imagecolorresolve imagecolorresolvealpha imagecolorset imagecolorsforindex imagecolorstotal imagecolortransparent imagecopy imagecopymerge imagecopymergegray imagecopyresampled imagecopyresized imagecreate imagecreatefromgd2 imagecreatefromgd2part imagecreatefromgd imagecreatefromgif imagecreatefromjpeg imagecreatefrompng imagecreatefromstring imagecreatefromwbmp imagecreatefromxbm imagecreatefromxpm imagecreatetruecolor imagedashedline imagedestroy imageellipse imagefill imagefilledarc imagefilledellipse imagefilledpolygon imagefilledrectangle imagefilltoborder imagefontheight imagefontwidth imageftbbox imagefttext imagegammacorrect imagegd2 imagegd imagegif imageinterlace imageistruecolor imagejpeg imageline imageloadfont imagepalettecopy imagepng imagepolygon imagepsbbox imagepscopyfont imagepsencodefont imagepsextendfont imagepsfreefont imagepsloadfont imagepsslantfont imagepstext imagerectangle imagerotate imagesavealpha imagesetbrush imagesetpixel imagesetstyle imagesetthickness imagesettile imagestring imagestringup imagesx imagesy imagetruecolortopalette imagettfbbox imagettftext imagetypes imagewbmp iptcembed iptcparse jpeg2wbmp png2wbmp read_exif_data contained
+syn keyword phpFunctions  imap_8bit imap_alerts imap_append imap_base64 imap_binary imap_body imap_bodystruct imap_check imap_clearflag_full imap_close imap_createmailbox imap_delete imap_deletemailbox imap_errors imap_expunge imap_fetch_overview imap_fetchbody imap_fetchheader imap_fetchstructure imap_get_quota imap_get_quotaroot imap_getacl imap_getmailboxes imap_getsubscribed imap_header imap_headerinfo imap_headers imap_last_error imap_list imap_listmailbox imap_listscan imap_listsubscribed imap_lsub imap_mail_compose imap_mail_copy imap_mail_move imap_mail imap_mailboxmsginfo imap_mime_header_decode imap_msgno imap_num_msg imap_num_recent imap_open imap_ping imap_qprint imap_renamemailbox imap_reopen imap_rfc822_parse_adrlist imap_rfc822_parse_headers imap_rfc822_write_address imap_scanmailbox imap_search imap_set_quota imap_setacl imap_setflag_full imap_sort imap_status imap_subscribe imap_thread imap_timeout imap_uid imap_undelete imap_unsubscribe imap_utf7_decode imap_utf7_encode imap_utf8  contained
+syn keyword phpFunctions  assert_options assert dl extension_loaded get_cfg_var get_current_user get_defined_constants get_extension_funcs get_include_path get_included_files get_loaded_extensions get_magic_quotes_gpc get_magic_quotes_runtime get_required_files getenv getlastmod getmygid getmyinode getmypid getmyuid getopt getrusage ini_alter ini_get_all ini_get ini_restore ini_set main memory_get_usage php_ini_scanned_files php_logo_guid php_sapi_name php_uname phpcredits phpinfo phpversion putenv restore_include_path set_include_path set_magic_quotes_runtime set_time_limit version_compare zend_logo_guid zend_version contained
+syn keyword phpFunctions  ingres_autocommit ingres_close ingres_commit ingres_connect ingres_fetch_array ingres_fetch_object ingres_fetch_row ingres_field_length ingres_field_name ingres_field_nullable ingres_field_precision ingres_field_scale ingres_field_type ingres_num_fields ingres_num_rows ingres_pconnect ingres_query ingres_rollback  contained
+syn keyword phpFunctions  ircg_channel_mode ircg_disconnect ircg_fetch_error_msg ircg_get_username ircg_html_encode ircg_ignore_add ircg_ignore_del ircg_is_conn_alive ircg_join ircg_kick ircg_lookup_format_messages ircg_msg ircg_nick ircg_nickname_escape ircg_nickname_unescape ircg_notice ircg_part ircg_pconnect ircg_register_format_messages ircg_set_current ircg_set_file ircg_set_on_die ircg_topic ircg_whois  contained
+syn keyword phpFunctions  java_last_exception_clear java_last_exception_get contained
+syn keyword phpFunctions  ldap_8859_to_t61 ldap_add ldap_bind ldap_close ldap_compare ldap_connect ldap_count_entries ldap_delete ldap_dn2ufn ldap_err2str ldap_errno ldap_error ldap_explode_dn ldap_first_attribute ldap_first_entry ldap_first_reference ldap_free_result ldap_get_attributes ldap_get_dn ldap_get_entries ldap_get_option ldap_get_values_len ldap_get_values ldap_list ldap_mod_add ldap_mod_del ldap_mod_replace ldap_modify ldap_next_attribute ldap_next_entry ldap_next_reference ldap_parse_reference ldap_parse_result ldap_read ldap_rename ldap_search ldap_set_option ldap_set_rebind_proc ldap_sort ldap_start_tls ldap_t61_to_8859 ldap_unbind  contained
+syn keyword phpFunctions  lzf_compress lzf_decompress lzf_optimized_for contained
+syn keyword phpFunctions  ezmlm_hash mail contained
+syn keyword phpFunctions  mailparse_determine_best_xfer_encoding mailparse_msg_create mailparse_msg_extract_part_file mailparse_msg_extract_part mailparse_msg_free mailparse_msg_get_part_data mailparse_msg_get_part mailparse_msg_get_structure mailparse_msg_parse_file mailparse_msg_parse mailparse_rfc822_parse_addresses mailparse_stream_encode mailparse_uudecode_all contained
+syn keyword phpFunctions  abs acos acosh asin asinh atan2 atan atanh base_convert bindec ceil cos cosh decbin dechex decoct deg2rad exp expm1 floor fmod getrandmax hexdec hypot is_finite is_infinite is_nan lcg_value log10 log1p log max min mt_getrandmax mt_rand mt_srand octdec pi pow rad2deg rand round sin sinh sqrt srand tan tanh  contained
+syn keyword phpFunctions  mb_convert_case mb_convert_encoding mb_convert_kana mb_convert_variables mb_decode_mimeheader mb_decode_numericentity mb_detect_encoding mb_detect_order mb_encode_mimeheader mb_encode_numericentity mb_ereg_match mb_ereg_replace mb_ereg_search_getpos mb_ereg_search_getregs mb_ereg_search_init mb_ereg_search_pos mb_ereg_search_regs mb_ereg_search_setpos mb_ereg_search mb_ereg mb_eregi_replace mb_eregi mb_get_info mb_http_input mb_http_output mb_internal_encoding mb_language mb_output_handler mb_parse_str mb_preferred_mime_name mb_regex_encoding mb_regex_set_options mb_send_mail mb_split mb_strcut mb_strimwidth mb_strlen mb_strpos mb_strrpos mb_strtolower mb_strtoupper mb_strwidth mb_substitute_character mb_substr_count mb_substr  contained
+syn keyword phpFunctions  mcal_append_event mcal_close mcal_create_calendar mcal_date_compare mcal_date_valid mcal_day_of_week mcal_day_of_year mcal_days_in_month mcal_delete_calendar mcal_delete_event mcal_event_add_attribute mcal_event_init mcal_event_set_alarm mcal_event_set_category mcal_event_set_class mcal_event_set_description mcal_event_set_end mcal_event_set_recur_daily mcal_event_set_recur_monthly_mday mcal_event_set_recur_monthly_wday mcal_event_set_recur_none mcal_event_set_recur_weekly mcal_event_set_recur_yearly mcal_event_set_start mcal_event_set_title mcal_expunge mcal_fetch_current_stream_event mcal_fetch_event mcal_is_leap_year mcal_list_alarms mcal_list_events mcal_next_recurrence mcal_open mcal_popen mcal_rename_calendar mcal_reopen mcal_snooze mcal_store_event mcal_time_valid mcal_week_of_year contained
+syn keyword phpFunctions  mcrypt_cbc mcrypt_cfb mcrypt_create_iv mcrypt_decrypt mcrypt_ecb mcrypt_enc_get_algorithms_name mcrypt_enc_get_block_size mcrypt_enc_get_iv_size mcrypt_enc_get_key_size mcrypt_enc_get_modes_name mcrypt_enc_get_supported_key_sizes mcrypt_enc_is_block_algorithm_mode mcrypt_enc_is_block_algorithm mcrypt_enc_is_block_mode mcrypt_enc_self_test mcrypt_encrypt mcrypt_generic_deinit mcrypt_generic_end mcrypt_generic_init mcrypt_generic mcrypt_get_block_size mcrypt_get_cipher_name mcrypt_get_iv_size mcrypt_get_key_size mcrypt_list_algorithms mcrypt_list_modes mcrypt_module_close mcrypt_module_get_algo_block_size mcrypt_module_get_algo_key_size mcrypt_module_get_supported_key_sizes mcrypt_module_is_block_algorithm_mode mcrypt_module_is_block_algorithm mcrypt_module_is_block_mode mcrypt_module_open mcrypt_module_self_test mcrypt_ofb mdecrypt_generic  contained
+syn keyword phpFunctions  mcve_adduser mcve_adduserarg mcve_bt mcve_checkstatus mcve_chkpwd mcve_chngpwd mcve_completeauthorizations mcve_connect mcve_connectionerror mcve_deleteresponse mcve_deletetrans mcve_deleteusersetup mcve_deluser mcve_destroyconn mcve_destroyengine mcve_disableuser mcve_edituser mcve_enableuser mcve_force mcve_getcell mcve_getcellbynum mcve_getcommadelimited mcve_getheader mcve_getuserarg mcve_getuserparam mcve_gft mcve_gl mcve_gut mcve_initconn mcve_initengine mcve_initusersetup mcve_iscommadelimited mcve_liststats mcve_listusers mcve_maxconntimeout mcve_monitor mcve_numcolumns mcve_numrows mcve_override mcve_parsecommadelimited mcve_ping mcve_preauth mcve_preauthcompletion mcve_qc mcve_responseparam mcve_return mcve_returncode mcve_returnstatus mcve_sale mcve_setblocking mcve_setdropfile mcve_setip mcve_setssl_files mcve_setssl mcve_settimeout mcve_settle mcve_text_avs mcve_text_code mcve_text_cv mcve_transactionauth mcve_transactionavs mcve_transactionbatch mcve_transactioncv mcve_transactionid mcve_transactionitem mcve_transactionssent mcve_transactiontext mcve_transinqueue mcve_transnew mcve_transparam mcve_transsend mcve_ub mcve_uwait mcve_verifyconnection mcve_verifysslcert mcve_void  contained
+syn keyword phpFunctions  mhash_count mhash_get_block_size mhash_get_hash_name mhash_keygen_s2k mhash contained
+syn keyword phpFunctions  mime_content_type contained
+syn keyword phpFunctions  ming_setcubicthreshold ming_setscale ming_useswfversion SWFAction SWFBitmap swfbutton_keypress SWFbutton SWFDisplayItem SWFFill SWFFont SWFGradient SWFMorph SWFMovie SWFShape SWFSprite SWFText SWFTextField contained
+syn keyword phpMethods  getHeight getWidth addAction addShape setAction setdown setHit setOver setUp addColor move moveTo multColor remove Rotate rotateTo scale scaleTo setDepth setName setRatio skewX skewXTo skewY skewYTo moveTo rotateTo scaleTo skewXTo skewYTo getwidth addEntry getshape1 getshape2 add nextframe output remove save setbackground setdimension setframes setrate streammp3 addFill drawCurve drawCurveTo drawLine drawLineTo movePen movePenTo setLeftFill setLine setRightFill add nextframe remove setframes addString getWidth moveTo setColor setFont setHeight setSpacing addstring align setbounds setcolor setFont setHeight setindentation setLeftMargin setLineSpacing setMargins setname setrightMargin contained
+syn keyword phpFunctions  connection_aborted connection_status connection_timeout constant define defined die eval exit get_browser highlight_file highlight_string ignore_user_abort pack show_source sleep uniqid unpack usleep contained
+syn keyword phpFunctions  udm_add_search_limit udm_alloc_agent udm_api_version udm_cat_list udm_cat_path udm_check_charset udm_check_stored udm_clear_search_limits udm_close_stored udm_crc32 udm_errno udm_error udm_find udm_free_agent udm_free_ispell_data udm_free_res udm_get_doc_count udm_get_res_field udm_get_res_param udm_load_ispell_data udm_open_stored udm_set_agent_param contained
+syn keyword phpFunctions  msession_connect msession_count msession_create msession_destroy msession_disconnect msession_find msession_get_array msession_get msession_getdata msession_inc msession_list msession_listvar msession_lock msession_plugin msession_randstr msession_set_array msession_set msession_setdata msession_timeout msession_uniq msession_unlock  contained
+syn keyword phpFunctions  msql_affected_rows msql_close msql_connect msql_create_db msql_createdb msql_data_seek msql_dbname msql_drop_db msql_dropdb msql_error msql_fetch_array msql_fetch_field msql_fetch_object msql_fetch_row msql_field_seek msql_fieldflags msql_fieldlen msql_fieldname msql_fieldtable msql_fieldtype msql_free_result msql_freeresult msql_list_dbs msql_list_fields msql_list_tables msql_listdbs msql_listfields msql_listtables msql_num_fields msql_num_rows msql_numfields msql_numrows msql_pconnect msql_query msql_regcase msql_result msql_select_db msql_selectdb msql_tablename msql  contained
+syn keyword phpFunctions  mssql_bind mssql_close mssql_connect mssql_data_seek mssql_execute mssql_fetch_array mssql_fetch_assoc mssql_fetch_batch mssql_fetch_field mssql_fetch_object mssql_fetch_row mssql_field_length mssql_field_name mssql_field_seek mssql_field_type mssql_free_result mssql_free_statement mssql_get_last_message mssql_guid_string mssql_init mssql_min_error_severity mssql_min_message_severity mssql_next_result mssql_num_fields mssql_num_rows mssql_pconnect mssql_query mssql_result mssql_rows_affected mssql_select_db  contained
+syn keyword phpFunctions  muscat_close muscat_get muscat_give muscat_setup_net muscat_setup contained
+syn keyword phpFunctions  mysql_affected_rows mysql_change_user mysql_client_encoding mysql_close mysql_connect mysql_create_db mysql_data_seek mysql_db_name mysql_db_query mysql_drop_db mysql_errno mysql_error mysql_escape_string mysql_fetch_array mysql_fetch_assoc mysql_fetch_field mysql_fetch_lengths mysql_fetch_object mysql_fetch_row mysql_field_flags mysql_field_len mysql_field_name mysql_field_seek mysql_field_table mysql_field_type mysql_free_result mysql_get_client_info mysql_get_host_info mysql_get_proto_info mysql_get_server_info mysql_info mysql_insert_id mysql_list_dbs mysql_list_fields mysql_list_processes mysql_list_tables mysql_num_fields mysql_num_rows mysql_pconnect mysql_ping mysql_query mysql_real_escape_string mysql_result mysql_select_db mysql_stat mysql_tablename mysql_thread_id mysql_unbuffered_query  contained
+syn keyword phpFunctions  mysqli_affected_rows mysqli_autocommit mysqli_bind_param mysqli_bind_result mysqli_change_user mysqli_character_set_name mysqli_close mysqli_commit mysqli_connect mysqli_data_seek mysqli_debug mysqli_disable_reads_from_master mysqli_disable_rpl_parse mysqli_dump_debug_info mysqli_enable_reads_from_master mysqli_enable_rpl_parse mysqli_errno mysqli_error mysqli_execute mysqli_fetch_array mysqli_fetch_assoc mysqli_fetch_field_direct mysqli_fetch_field mysqli_fetch_fields mysqli_fetch_lengths mysqli_fetch_object mysqli_fetch_row mysqli_fetch mysqli_field_count mysqli_field_seek mysqli_field_tell mysqli_free_result mysqli_get_client_info mysqli_get_host_info mysqli_get_proto_info mysqli_get_server_info mysqli_get_server_version mysqli_info mysqli_init mysqli_insert_id mysqli_kill mysqli_master_query mysqli_num_fields mysqli_num_rows mysqli_options mysqli_param_count mysqli_ping mysqli_prepare_result mysqli_prepare mysqli_profiler mysqli_query mysqli_read_query_result mysqli_real_connect mysqli_real_escape_string mysqli_real_query mysqli_reload mysqli_rollback mysqli_rpl_parse_enabled mysqli_rpl_probe mysqli_rpl_query_type mysqli_select_db mysqli_send_long_data mysqli_send_query mysqli_slave_query mysqli_ssl_set mysqli_stat mysqli_stmt_affected_rows mysqli_stmt_close mysqli_stmt_errno mysqli_stmt_error mysqli_stmt_store_result mysqli_store_result mysqli_thread_id mysqli_thread_safe mysqli_use_result mysqli_warning_count  contained
+syn keyword phpFunctions  ncurses_addch ncurses_addchnstr ncurses_addchstr ncurses_addnstr ncurses_addstr ncurses_assume_default_colors ncurses_attroff ncurses_attron ncurses_attrset ncurses_baudrate ncurses_beep ncurses_bkgd ncurses_bkgdset ncurses_border ncurses_bottom_panel ncurses_can_change_color ncurses_cbreak ncurses_clear ncurses_clrtobot ncurses_clrtoeol ncurses_color_content ncurses_color_set ncurses_curs_set ncurses_def_prog_mode ncurses_def_shell_mode ncurses_define_key ncurses_del_panel ncurses_delay_output ncurses_delch ncurses_deleteln ncurses_delwin ncurses_doupdate ncurses_echo ncurses_echochar ncurses_end ncurses_erase ncurses_erasechar ncurses_filter ncurses_flash ncurses_flushinp ncurses_getch ncurses_getmaxyx ncurses_getmouse ncurses_getyx ncurses_halfdelay ncurses_has_colors ncurses_has_ic ncurses_has_il ncurses_has_key ncurses_hide_panel ncurses_hline ncurses_inch ncurses_init_color ncurses_init_pair ncurses_init ncurses_insch ncurses_insdelln ncurses_insertln ncurses_insstr ncurses_instr ncurses_isendwin ncurses_keyok ncurses_keypad ncurses_killchar ncurses_longname ncurses_meta ncurses_mouse_trafo ncurses_mouseinterval ncurses_mousemask ncurses_move_panel ncurses_move ncurses_mvaddch ncurses_mvaddchnstr ncurses_mvaddchstr ncurses_mvaddnstr ncurses_mvaddstr ncurses_mvcur ncurses_mvdelch ncurses_mvgetch ncurses_mvhline ncurses_mvinch ncurses_mvvline ncurses_mvwaddstr ncurses_napms ncurses_new_panel ncurses_newpad ncurses_newwin ncurses_nl ncurses_nocbreak ncurses_noecho ncurses_nonl ncurses_noqiflush ncurses_noraw ncurses_pair_content ncurses_panel_above ncurses_panel_below ncurses_panel_window ncurses_pnoutrefresh ncurses_prefresh ncurses_putp ncurses_qiflush ncurses_raw ncurses_refresh ncurses_replace_panel ncurses_reset_prog_mode ncurses_reset_shell_mode ncurses_resetty ncurses_savetty ncurses_scr_dump ncurses_scr_init ncurses_scr_restore ncurses_scr_set ncurses_scrl ncurses_show_panel ncurses_slk_attr ncurses_slk_attroff ncurses_slk_attron ncurses_slk_attrset ncurses_slk_clear ncurses_slk_color ncurses_slk_init ncurses_slk_noutrefresh ncurses_slk_refresh ncurses_slk_restore ncurses_slk_set ncurses_slk_touch ncurses_standend ncurses_standout ncurses_start_color ncurses_termattrs ncurses_termname ncurses_timeout ncurses_top_panel ncurses_typeahead ncurses_ungetch ncurses_ungetmouse ncurses_update_panels ncurses_use_default_colors ncurses_use_env ncurses_use_extended_names ncurses_vidattr ncurses_vline ncurses_waddch ncurses_waddstr ncurses_wattroff ncurses_wattron ncurses_wattrset ncurses_wborder ncurses_wclear ncurses_wcolor_set ncurses_werase ncurses_wgetch ncurses_whline ncurses_wmouse_trafo ncurses_wmove ncurses_wnoutrefresh ncurses_wrefresh ncurses_wstandend ncurses_wstandout ncurses_wvline contained
+syn keyword phpFunctions  checkdnsrr closelog debugger_off debugger_on define_syslog_variables dns_check_record dns_get_mx dns_get_record fsockopen gethostbyaddr gethostbyname gethostbynamel getmxrr getprotobyname getprotobynumber getservbyname getservbyport ip2long long2ip openlog pfsockopen socket_get_status socket_set_blocking socket_set_timeout syslog contained
+syn keyword phpFunctions  yp_all yp_cat yp_err_string yp_errno yp_first yp_get_default_domain yp_master yp_match yp_next yp_order contained
+syn keyword phpFunctions  notes_body notes_copy_db notes_create_db notes_create_note notes_drop_db notes_find_note notes_header_info notes_list_msgs notes_mark_read notes_mark_unread notes_nav_create notes_search notes_unread notes_version contained
+syn keyword phpFunctions  nsapi_request_headers nsapi_response_headers nsapi_virtual  contained
+syn keyword phpFunctions  aggregate_info aggregate_methods_by_list aggregate_methods_by_regexp aggregate_methods aggregate_properties_by_list aggregate_properties_by_regexp aggregate_properties aggregate aggregation_info deaggregate  contained
+syn keyword phpFunctions  ocibindbyname ocicancel ocicloselob ocicollappend ocicollassign ocicollassignelem ocicollgetelem ocicollmax ocicollsize ocicolltrim ocicolumnisnull ocicolumnname ocicolumnprecision ocicolumnscale ocicolumnsize ocicolumntype ocicolumntyperaw ocicommit ocidefinebyname ocierror ociexecute ocifetch ocifetchinto ocifetchstatement ocifreecollection ocifreecursor ocifreedesc ocifreestatement ociinternaldebug ociloadlob ocilogoff ocilogon ocinewcollection ocinewcursor ocinewdescriptor ocinlogon ocinumcols ociparse ociplogon ociresult ocirollback ocirowcount ocisavelob ocisavelobfile ociserverversion ocisetprefetch ocistatementtype ociwritelobtofile ociwritetemporarylob contained
+syn keyword phpFunctions  odbc_autocommit odbc_binmode odbc_close_all odbc_close odbc_columnprivileges odbc_columns odbc_commit odbc_connect odbc_cursor odbc_data_source odbc_do odbc_error odbc_errormsg odbc_exec odbc_execute odbc_fetch_array odbc_fetch_into odbc_fetch_object odbc_fetch_row odbc_field_len odbc_field_name odbc_field_num odbc_field_precision odbc_field_scale odbc_field_type odbc_foreignkeys odbc_free_result odbc_gettypeinfo odbc_longreadlen odbc_next_result odbc_num_fields odbc_num_rows odbc_pconnect odbc_prepare odbc_primarykeys odbc_procedurecolumns odbc_procedures odbc_result_all odbc_result odbc_rollback odbc_setoption odbc_specialcolumns odbc_statistics odbc_tableprivileges odbc_tables  contained
+syn keyword phpFunctions  openssl_csr_export_to_file openssl_csr_export openssl_csr_new openssl_csr_sign openssl_error_string openssl_free_key openssl_get_privatekey openssl_get_publickey openssl_open openssl_pkcs7_decrypt openssl_pkcs7_encrypt openssl_pkcs7_sign openssl_pkcs7_verify openssl_pkey_export_to_file openssl_pkey_export openssl_pkey_get_private openssl_pkey_get_public openssl_pkey_new openssl_private_decrypt openssl_private_encrypt openssl_public_decrypt openssl_public_encrypt openssl_seal openssl_sign openssl_verify openssl_x509_check_private_key openssl_x509_checkpurpose openssl_x509_export_to_file openssl_x509_export openssl_x509_free openssl_x509_parse openssl_x509_read contained
+syn keyword phpFunctions  ora_bind ora_close ora_columnname ora_columnsize ora_columntype ora_commit ora_commitoff ora_commiton ora_do ora_error ora_errorcode ora_exec ora_fetch_into ora_fetch ora_getcolumn ora_logoff ora_logon ora_numcols ora_numrows ora_open ora_parse ora_plogon ora_rollback  contained
+syn keyword phpFunctions  flush ob_clean ob_end_clean ob_end_flush ob_flush ob_get_clean ob_get_contents ob_get_flush ob_get_length ob_get_level ob_get_status ob_gzhandler ob_implicit_flush ob_list_handlers ob_start output_add_rewrite_var output_reset_rewrite_vars  contained
+syn keyword phpFunctions  overload  contained
+syn keyword phpFunctions  ovrimos_close ovrimos_commit ovrimos_connect ovrimos_cursor ovrimos_exec ovrimos_execute ovrimos_fetch_into ovrimos_fetch_row ovrimos_field_len ovrimos_field_name ovrimos_field_num ovrimos_field_type ovrimos_free_result ovrimos_longreadlen ovrimos_num_fields ovrimos_num_rows ovrimos_prepare ovrimos_result_all ovrimos_result ovrimos_rollback  contained
+syn keyword phpFunctions  pcntl_exec pcntl_fork pcntl_signal pcntl_waitpid pcntl_wexitstatus pcntl_wifexited pcntl_wifsignaled pcntl_wifstopped pcntl_wstopsig pcntl_wtermsig contained
+syn keyword phpFunctions  preg_grep preg_match_all preg_match preg_quote preg_replace_callback preg_replace preg_split  contained
+syn keyword phpFunctions  pdf_add_annotation pdf_add_bookmark pdf_add_launchlink pdf_add_locallink pdf_add_note pdf_add_outline pdf_add_pdflink pdf_add_thumbnail pdf_add_weblink pdf_arc pdf_arcn pdf_attach_file pdf_begin_page pdf_begin_pattern pdf_begin_template pdf_circle pdf_clip pdf_close_image pdf_close_pdi_page pdf_close_pdi pdf_close pdf_closepath_fill_stroke pdf_closepath_stroke pdf_closepath pdf_concat pdf_continue_text pdf_curveto pdf_delete pdf_end_page pdf_end_pattern pdf_end_template pdf_endpath pdf_fill_stroke pdf_fill pdf_findfont pdf_get_buffer pdf_get_font pdf_get_fontname pdf_get_fontsize pdf_get_image_height pdf_get_image_width pdf_get_majorversion pdf_get_minorversion pdf_get_parameter pdf_get_pdi_parameter pdf_get_pdi_value pdf_get_value pdf_initgraphics pdf_lineto pdf_makespotcolor pdf_moveto pdf_new pdf_open_CCITT pdf_open_file pdf_open_gif pdf_open_image_file pdf_open_image pdf_open_jpeg pdf_open_memory_image pdf_open_pdi_page pdf_open_pdi pdf_open_png pdf_open_tiff pdf_open pdf_place_image pdf_place_pdi_page pdf_rect pdf_restore pdf_rotate pdf_save pdf_scale pdf_set_border_color pdf_set_border_dash pdf_set_border_style pdf_set_char_spacing pdf_set_duration pdf_set_font pdf_set_horiz_scaling pdf_set_info_author pdf_set_info_creator pdf_set_info_keywords pdf_set_info_subject pdf_set_info_title pdf_set_info pdf_set_leading pdf_set_parameter pdf_set_text_matrix pdf_set_text_pos pdf_set_text_rendering pdf_set_text_rise pdf_set_value pdf_set_word_spacing pdf_setcolor pdf_setdash pdf_setflat pdf_setfont pdf_setgray_fill pdf_setgray_stroke pdf_setgray pdf_setlinecap pdf_setlinejoin pdf_setlinewidth pdf_setmatrix pdf_setmiterlimit pdf_setpolydash pdf_setrgbcolor_fill pdf_setrgbcolor_stroke pdf_setrgbcolor pdf_show_boxed pdf_show_xy pdf_show pdf_skew pdf_stringwidth pdf_stroke pdf_translate contained
+syn keyword phpFunctions  pfpro_cleanup pfpro_init pfpro_process_raw pfpro_process pfpro_version  contained
+syn keyword phpFunctions  pg_affected_rows pg_cancel_query pg_client_encoding pg_close pg_connect pg_connection_busy pg_connection_reset pg_connection_status pg_convert pg_copy_from pg_copy_to pg_dbname pg_delete pg_end_copy pg_escape_bytea pg_escape_string pg_fetch_all pg_fetch_array pg_fetch_assoc pg_fetch_object pg_fetch_result pg_fetch_row pg_field_is_null pg_field_name pg_field_num pg_field_prtlen pg_field_size pg_field_type pg_free_result pg_get_notify pg_get_pid pg_get_result pg_host pg_insert pg_last_error pg_last_notice pg_last_oid pg_lo_close pg_lo_create pg_lo_export pg_lo_import pg_lo_open pg_lo_read_all pg_lo_read pg_lo_seek pg_lo_tell pg_lo_unlink pg_lo_write pg_meta_data pg_num_fields pg_num_rows pg_options pg_pconnect pg_ping pg_port pg_put_line pg_query pg_result_error pg_result_seek pg_result_status pg_select pg_send_query pg_set_client_encoding pg_trace pg_tty pg_unescape_bytea pg_untrace pg_update  contained
+syn keyword phpFunctions  posix_ctermid posix_get_last_error posix_getcwd posix_getegid posix_geteuid posix_getgid posix_getgrgid posix_getgrnam posix_getgroups posix_getlogin posix_getpgid posix_getpgrp posix_getpid posix_getppid posix_getpwnam posix_getpwuid posix_getrlimit posix_getsid posix_getuid posix_isatty posix_kill posix_mkfifo posix_setegid posix_seteuid posix_setgid posix_setpgid posix_setsid posix_setuid posix_strerror posix_times posix_ttyname posix_uname contained
+syn keyword phpFunctions  printer_abort printer_close printer_create_brush printer_create_dc printer_create_font printer_create_pen printer_delete_brush printer_delete_dc printer_delete_font printer_delete_pen printer_draw_bmp printer_draw_chord printer_draw_elipse printer_draw_line printer_draw_pie printer_draw_rectangle printer_draw_roundrect printer_draw_text printer_end_doc printer_end_page printer_get_option printer_list printer_logical_fontheight printer_open printer_select_brush printer_select_font printer_select_pen printer_set_option printer_start_doc printer_start_page printer_write contained
+syn keyword phpFunctions  pspell_add_to_personal pspell_add_to_session pspell_check pspell_clear_session pspell_config_create pspell_config_ignore pspell_config_mode pspell_config_personal pspell_config_repl pspell_config_runtogether pspell_config_save_repl pspell_new_config pspell_new_personal pspell_new pspell_save_wordlist pspell_store_replacement pspell_suggest contained
+syn keyword phpFunctions  qdom_error qdom_tree  contained
+syn keyword phpFunctions  readline_add_history readline_clear_history readline_completion_function readline_info readline_list_history readline_read_history readline_write_history readline  contained
+syn keyword phpFunctions  recode_file recode_string recode  contained
+syn keyword phpFunctions  ereg_replace ereg eregi_replace eregi split spliti sql_regcase  contained
+syn keyword phpFunctions  ftok msg_get_queue msg_receive msg_remove_queue msg_send msg_set_queue msg_stat_queue sem_acquire sem_get sem_release sem_remove shm_attach shm_detach shm_get_var shm_put_var shm_remove_var shm_remove  contained
+syn keyword phpFunctions  sesam_affected_rows sesam_commit sesam_connect sesam_diagnostic sesam_disconnect sesam_errormsg sesam_execimm sesam_fetch_array sesam_fetch_result sesam_fetch_row sesam_field_array sesam_field_name sesam_free_result sesam_num_fields sesam_query sesam_rollback sesam_seek_row sesam_settransaction contained
+syn keyword phpFunctions  session_cache_expire session_cache_limiter session_decode session_destroy session_encode session_get_cookie_params session_id session_is_registered session_module_name session_name session_regenerate_id session_register session_save_path session_set_cookie_params session_set_save_handler session_start session_unregister session_unset session_write_close contained
+syn keyword phpFunctions  shmop_close shmop_delete shmop_open shmop_read shmop_size shmop_write contained
+syn keyword phpFunctions  snmp_get_quick_print snmp_set_quick_print snmpget snmprealwalk snmpset snmpwalk snmpwalkoid contained
+syn keyword phpFunctions  socket_accept socket_bind socket_clear_error socket_close socket_connect socket_create_listen socket_create_pair socket_create socket_get_option socket_getpeername socket_getsockname socket_iovec_add socket_iovec_alloc socket_iovec_delete socket_iovec_fetch socket_iovec_free socket_iovec_set socket_last_error socket_listen socket_read socket_readv socket_recv socket_recvfrom socket_recvmsg socket_select socket_send socket_sendmsg socket_sendto socket_set_block socket_set_nonblock socket_set_option socket_shutdown socket_strerror socket_write socket_writev contained
+syn keyword phpFunctions  sqlite_array_query sqlite_busy_timeout sqlite_changes sqlite_close sqlite_column sqlite_create_aggregate sqlite_create_function sqlite_current sqlite_error_string sqlite_escape_string sqlite_fetch_array sqlite_fetch_single sqlite_fetch_string sqlite_field_name sqlite_has_more sqlite_last_error sqlite_last_insert_rowid sqlite_libencoding sqlite_libversion sqlite_next sqlite_num_fields sqlite_num_rows sqlite_open sqlite_popen sqlite_query sqlite_rewind sqlite_seek sqlite_udf_decode_binary sqlite_udf_encode_binary sqlite_unbuffered_query  contained
+syn keyword phpFunctions  stream_context_create stream_context_get_options stream_context_set_option stream_context_set_params stream_copy_to_stream stream_filter_append stream_filter_prepend stream_filter_register stream_get_contents stream_get_filters stream_get_line stream_get_meta_data stream_get_transports stream_get_wrappers stream_register_wrapper stream_select stream_set_blocking stream_set_timeout stream_set_write_buffer stream_socket_accept stream_socket_client stream_socket_get_name stream_socket_recvfrom stream_socket_sendto stream_socket_server stream_wrapper_register contained
+syn keyword phpFunctions  addcslashes addslashes bin2hex chop chr chunk_split convert_cyr_string count_chars crc32 crypt explode fprintf get_html_translation_table hebrev hebrevc html_entity_decode htmlentities htmlspecialchars implode join levenshtein localeconv ltrim md5_file md5 metaphone money_format nl_langinfo nl2br number_format ord parse_str print printf quoted_printable_decode quotemeta rtrim setlocale sha1_file sha1 similar_text soundex sprintf sscanf str_ireplace str_pad str_repeat str_replace str_rot13 str_shuffle str_split str_word_count strcasecmp strchr strcmp strcoll strcspn strip_tags stripcslashes stripos stripslashes stristr strlen strnatcasecmp strnatcmp strncasecmp strncmp strpos strrchr strrev strripos strrpos strspn strstr strtok strtolower strtoupper strtr substr_compare substr_count substr_replace substr trim ucfirst ucwords vprintf vsprintf wordwrap contained
+syn keyword phpFunctions  swf_actiongeturl swf_actiongotoframe swf_actiongotolabel swf_actionnextframe swf_actionplay swf_actionprevframe swf_actionsettarget swf_actionstop swf_actiontogglequality swf_actionwaitforframe swf_addbuttonrecord swf_addcolor swf_closefile swf_definebitmap swf_definefont swf_defineline swf_definepoly swf_definerect swf_definetext swf_endbutton swf_enddoaction swf_endshape swf_endsymbol swf_fontsize swf_fontslant swf_fonttracking swf_getbitmapinfo swf_getfontinfo swf_getframe swf_labelframe swf_lookat swf_modifyobject swf_mulcolor swf_nextid swf_oncondition swf_openfile swf_ortho2 swf_ortho swf_perspective swf_placeobject swf_polarview swf_popmatrix swf_posround swf_pushmatrix swf_removeobject swf_rotate swf_scale swf_setfont swf_setframe swf_shapearc swf_shapecurveto3 swf_shapecurveto swf_shapefillbitmapclip swf_shapefillbitmaptile swf_shapefilloff swf_shapefillsolid swf_shapelinesolid swf_shapelineto swf_shapemoveto swf_showframe swf_startbutton swf_startdoaction swf_startshape swf_startsymbol swf_textwidth swf_translate swf_viewport contained
+syn keyword phpFunctions  sybase_affected_rows sybase_close sybase_connect sybase_data_seek sybase_deadlock_retry_count sybase_fetch_array sybase_fetch_assoc sybase_fetch_field sybase_fetch_object sybase_fetch_row sybase_field_seek sybase_free_result sybase_get_last_message sybase_min_client_severity sybase_min_error_severity sybase_min_message_severity sybase_min_server_severity sybase_num_fields sybase_num_rows sybase_pconnect sybase_query sybase_result sybase_select_db sybase_set_message_handler sybase_unbuffered_query contained
+syn keyword phpFunctions  tidy_access_count tidy_clean_repair tidy_config_count tidy_diagnose tidy_error_count tidy_get_body tidy_get_config tidy_get_error_buffer tidy_get_head tidy_get_html_ver tidy_get_html tidy_get_output tidy_get_release tidy_get_root tidy_get_status tidy_getopt tidy_is_xhtml tidy_load_config tidy_parse_file tidy_parse_string tidy_repair_file tidy_repair_string tidy_reset_config tidy_save_config tidy_set_encoding tidy_setopt tidy_warning_count  contained
+syn keyword phpMethods  attributes children get_attr get_nodes has_children has_siblings is_asp is_comment is_html is_jsp is_jste is_text is_xhtml is_xml next prev tidy_node contained
+syn keyword phpFunctions  token_get_all token_name  contained
+syn keyword phpFunctions  base64_decode base64_encode get_meta_tags http_build_query parse_url rawurldecode rawurlencode urldecode urlencode  contained
+syn keyword phpFunctions  doubleval empty floatval get_defined_vars get_resource_type gettype import_request_variables intval is_array is_bool is_callable is_double is_float is_int is_integer is_long is_null is_numeric is_object is_real is_resource is_scalar is_string isset print_r serialize settype strval unserialize unset var_dump var_export contained
+syn keyword phpFunctions  vpopmail_add_alias_domain_ex vpopmail_add_alias_domain vpopmail_add_domain_ex vpopmail_add_domain vpopmail_add_user vpopmail_alias_add vpopmail_alias_del_domain vpopmail_alias_del vpopmail_alias_get_all vpopmail_alias_get vpopmail_auth_user vpopmail_del_domain_ex vpopmail_del_domain vpopmail_del_user vpopmail_error vpopmail_passwd vpopmail_set_user_quota  contained
+syn keyword phpFunctions  w32api_deftype w32api_init_dtype w32api_invoke_function w32api_register_function w32api_set_call_method contained
+syn keyword phpFunctions  wddx_add_vars wddx_deserialize wddx_packet_end wddx_packet_start wddx_serialize_value wddx_serialize_vars contained
+syn keyword phpFunctions  utf8_decode utf8_encode xml_error_string xml_get_current_byte_index xml_get_current_column_number xml_get_current_line_number xml_get_error_code xml_parse_into_struct xml_parse xml_parser_create_ns xml_parser_create xml_parser_free xml_parser_get_option xml_parser_set_option xml_set_character_data_handler xml_set_default_handler xml_set_element_handler xml_set_end_namespace_decl_handler xml_set_external_entity_ref_handler xml_set_notation_decl_handler xml_set_object xml_set_processing_instruction_handler xml_set_start_namespace_decl_handler xml_set_unparsed_entity_decl_handler contained
+syn keyword phpFunctions  xmlrpc_decode_request xmlrpc_decode xmlrpc_encode_request xmlrpc_encode xmlrpc_get_type xmlrpc_parse_method_descriptions xmlrpc_server_add_introspection_data xmlrpc_server_call_method xmlrpc_server_create xmlrpc_server_destroy xmlrpc_server_register_introspection_callback xmlrpc_server_register_method xmlrpc_set_type  contained
+syn keyword phpFunctions  xslt_create xslt_errno xslt_error xslt_free xslt_output_process xslt_set_base xslt_set_encoding xslt_set_error_handler xslt_set_log xslt_set_sax_handler xslt_set_sax_handlers xslt_set_scheme_handler xslt_set_scheme_handlers contained
+syn keyword phpFunctions  yaz_addinfo yaz_ccl_conf yaz_ccl_parse yaz_close yaz_connect yaz_database yaz_element yaz_errno yaz_error yaz_es_result yaz_get_option yaz_hits yaz_itemorder yaz_present yaz_range yaz_record yaz_scan_result yaz_scan yaz_schema yaz_search yaz_set_option yaz_sort yaz_syntax yaz_wait contained
+syn keyword phpFunctions  zip_close zip_entry_close zip_entry_compressedsize zip_entry_compressionmethod zip_entry_filesize zip_entry_name zip_entry_open zip_entry_read zip_open zip_read  contained
+syn keyword phpFunctions  gzclose gzcompress gzdeflate gzencode gzeof gzfile gzgetc gzgets gzgetss gzinflate gzopen gzpassthru gzputs gzread gzrewind gzseek gztell gzuncompress gzwrite readgzfile zlib_get_coding_type  contained
+
+if exists( "php_baselib" )
+  syn keyword phpMethods  query next_record num_rows affected_rows nf f p np num_fields haltmsg seek link_id query_id metadata table_names nextid connect halt free register unregister is_registered delete url purl self_url pself_url hidden_session add_query padd_query reimport_get_vars reimport_post_vars reimport_cookie_vars set_container set_tokenname release_token put_headers get_id get_id put_id freeze thaw gc reimport_any_vars start url purl login_if is_authenticated auth_preauth auth_loginform auth_validatelogin auth_refreshlogin auth_registerform auth_doregister start check have_perm permsum perm_invalid contained
+  syn keyword phpFunctions  page_open page_close sess_load sess_save  contained
+endif
+
+" Conditional
+syn keyword phpConditional  declare else enddeclare endswitch elseif endif if switch  contained
+
+" Repeat
+syn keyword phpRepeat as do endfor endforeach endwhile for foreach while  contained
+
+" Repeat
+syn keyword phpLabel  case default switch contained
+
+" Statement
+syn keyword phpStatement  return break continue exit  contained
+
+" Keyword
+syn keyword phpKeyword  var const contained
+
+" Type
+syn keyword phpType bool[ean] int[eger] real double float string array object NULL  contained
+
+" Structure
+syn keyword phpStructure  extends implements instanceof parent self contained
+
+" Operator
+syn match phpOperator "[-=+%^&|*!.~?:]" contained display
+syn match phpOperator "[-+*/%^&|.]="  contained display
+syn match phpOperator "/[^*/]"me=e-1  contained display
+syn match phpOperator "\$"  contained display
+syn match phpOperator "&&\|\<and\>" contained display
+syn match phpOperator "||\|\<x\=or\>" contained display
+syn match phpRelation "[!=<>]=" contained display
+syn match phpRelation "[<>]"  contained display
+syn match phpMemberSelector "->"  contained display
+syn match phpVarSelector  "\$"  contained display
+
+" Identifier
+syn match phpIdentifier "$\h\w*"  contained contains=phpEnvVar,phpIntVar,phpVarSelector display
+syn match phpIdentifierSimply "${\h\w*}"  contains=phpOperator,phpParent  contained display
+syn region  phpIdentifierComplex  matchgroup=phpParent start="{\$"rs=e-1 end="}"  contains=phpIdentifier,phpMemberSelector,phpVarSelector,phpIdentifierComplexP contained extend
+syn region  phpIdentifierComplexP matchgroup=phpParent start="\[" end="]" contains=@phpClInside contained
+
+" Methoden
+syn match phpMethodsVar "->\h\w*" contained contains=phpMethods,phpMemberSelector display
+
+" Include
+syn keyword phpInclude  include require include_once require_once contained
+
+" Peter Hodge - added 'clone' keyword
+" Define
+syn keyword phpDefine new clone contained
+
+" Boolean
+syn keyword phpBoolean  true false  contained
+
+" Number
+syn match phpNumber "-\=\<\d\+\>" contained display
+syn match phpNumber "\<0x\x\{1,8}\>"  contained display
+
+" Float
+syn match phpFloat  "\(-\=\<\d+\|-\=\)\.\d\+\>" contained display
+
+" SpecialChar
+syn match phpSpecialChar  "\\[abcfnrtyv\\]" contained display
+syn match phpSpecialChar  "\\\d\{3}"  contained contains=phpOctalError display
+syn match phpSpecialChar  "\\x\x\{2}" contained display
+
+" Error
+syn match phpOctalError "[89]"  contained display
+if exists("php_parent_error_close")
+  syn match phpParentError  "[)\]}]"  contained display
+endif
+
+" Todo
+syn keyword phpTodo todo fixme xxx  contained
+
+" Comment
+if exists("php_parent_error_open")
+  syn region  phpComment  start="/\*" end="\*/" contained contains=phpTodo
+else
+  syn region  phpComment  start="/\*" end="\*/" contained contains=phpTodo extend
+endif
+if version >= 600
+  syn match phpComment  "#.\{-}\(?>\|$\)\@="  contained contains=phpTodo
+  syn match phpComment  "//.\{-}\(?>\|$\)\@=" contained contains=phpTodo
+else
+  syn match phpComment  "#.\{-}$" contained contains=phpTodo
+  syn match phpComment  "#.\{-}?>"me=e-2  contained contains=phpTodo
+  syn match phpComment  "//.\{-}$"  contained contains=phpTodo
+  syn match phpComment  "//.\{-}?>"me=e-2 contained contains=phpTodo
+endif
+
+" String
+if exists("php_parent_error_open")
+  syn region  phpStringDouble matchgroup=None start=+"+ skip=+\\\\\|\\"+ end=+"+  contains=@phpAddStrings,phpIdentifier,phpSpecialChar,phpIdentifierSimply,phpIdentifierComplex contained keepend
+  syn region  phpBacktick matchgroup=None start=+`+ skip=+\\\\\|\\"+ end=+`+  contains=@phpAddStrings,phpIdentifier,phpSpecialChar,phpIdentifierSimply,phpIdentifierComplex contained keepend
+  syn region  phpStringSingle matchgroup=None start=+'+ skip=+\\\\\|\\'+ end=+'+  contains=@phpAddStrings contained keepend
+else
+  syn region  phpStringDouble matchgroup=None start=+"+ skip=+\\\\\|\\"+ end=+"+  contains=@phpAddStrings,phpIdentifier,phpSpecialChar,phpIdentifierSimply,phpIdentifierComplex contained extend keepend
+  syn region  phpBacktick matchgroup=None start=+`+ skip=+\\\\\|\\"+ end=+`+  contains=@phpAddStrings,phpIdentifier,phpSpecialChar,phpIdentifierSimply,phpIdentifierComplex contained extend keepend
+  syn region  phpStringSingle matchgroup=None start=+'+ skip=+\\\\\|\\'+ end=+'+  contains=@phpAddStrings contained keepend extend
+endif
+
+" HereDoc
+if version >= 600
+  syn case match
+  syn region  phpHereDoc  matchgroup=Delimiter start="\(<<<\)\@<=\z(\I\i*\)$" end="^\z1\(;\=$\)\@=" contained contains=phpIdentifier,phpIdentifierSimply,phpIdentifierComplex,phpSpecialChar,phpMethodsVar keepend extend
+" including HTML,JavaScript,SQL even if not enabled via options
+  syn region  phpHereDoc  matchgroup=Delimiter start="\(<<<\)\@<=\z(\(\I\i*\)\=\(html\)\c\(\i*\)\)$" end="^\z1\(;\=$\)\@="  contained contains=@htmlTop,phpIdentifier,phpIdentifierSimply,phpIdentifierComplex,phpSpecialChar,phpMethodsVar keepend extend
+  syn region  phpHereDoc  matchgroup=Delimiter start="\(<<<\)\@<=\z(\(\I\i*\)\=\(sql\)\c\(\i*\)\)$" end="^\z1\(;\=$\)\@=" contained contains=@sqlTop,phpIdentifier,phpIdentifierSimply,phpIdentifierComplex,phpSpecialChar,phpMethodsVar keepend extend
+  syn region  phpHereDoc  matchgroup=Delimiter start="\(<<<\)\@<=\z(\(\I\i*\)\=\(javascript\)\c\(\i*\)\)$" end="^\z1\(;\=$\)\@="  contained contains=@htmlJavascript,phpIdentifierSimply,phpIdentifier,phpIdentifierComplex,phpSpecialChar,phpMethodsVar keepend extend
+  syn case ignore
+endif
+
+" Parent
+if exists("php_parent_error_close") || exists("php_parent_error_open")
+  syn match phpParent "[{}]"  contained
+  syn region  phpParent matchgroup=Delimiter start="(" end=")"  contained contains=@phpClInside transparent
+  syn region  phpParent matchgroup=Delimiter start="\[" end="\]"  contained contains=@phpClInside transparent
+  if !exists("php_parent_error_close")
+    syn match phpParent "[\])]" contained
+  endif
+else
+  syn match phpParent "[({[\]})]" contained
+endif
+
+syn cluster phpClConst  contains=phpFunctions,phpIdentifier,phpConditional,phpRepeat,phpStatement,phpOperator,phpRelation,phpStringSingle,phpStringDouble,phpBacktick,phpNumber,phpFloat,phpKeyword,phpType,phpBoolean,phpStructure,phpMethodsVar,phpConstant,phpCoreConstant,phpException
+syn cluster phpClInside contains=@phpClConst,phpComment,phpLabel,phpParent,phpParentError,phpInclude,phpHereDoc
+syn cluster phpClFunction contains=@phpClInside,phpDefine,phpParentError,phpStorageClass
+syn cluster phpClTop  contains=@phpClFunction,phpFoldFunction,phpFoldClass,phpFoldInterface,phpFoldTry,phpFoldCatch
+
+" Php Region
+if exists("php_parent_error_open")
+  if exists("php_noShortTags")
+    syn region   phpRegion  matchgroup=Delimiter start="<?php" end="?>" contains=@phpClTop
+  else
+    syn region   phpRegion  matchgroup=Delimiter start="<?\(php\)\=" end="?>" contains=@phpClTop
+  endif
+  syn region   phpRegionSc  matchgroup=Delimiter start=+<script language="php">+ end=+</script>+  contains=@phpClTop
+  if exists("php_asp_tags")
+    syn region   phpRegionAsp matchgroup=Delimiter start="<%\(=\)\=" end="%>" contains=@phpClTop
+  endif
+else
+  if exists("php_noShortTags")
+    syn region   phpRegion  matchgroup=Delimiter start="<?php" end="?>" contains=@phpClTop keepend
+  else
+    syn region   phpRegion  matchgroup=Delimiter start="<?\(php\)\=" end="?>" contains=@phpClTop keepend
+  endif
+  syn region   phpRegionSc  matchgroup=Delimiter start=+<script language="php">+ end=+</script>+  contains=@phpClTop keepend
+  if exists("php_asp_tags")
+    syn region   phpRegionAsp matchgroup=Delimiter start="<%\(=\)\=" end="%>" contains=@phpClTop keepend
+  endif
+endif
+
+" Fold
+if exists("php_folding") && php_folding==1
+" match one line constructs here and skip them at folding
+  syn keyword phpSCKeyword  abstract final private protected public static  contained
+  syn keyword phpFCKeyword  function  contained
+  syn keyword phpStorageClass global  contained
+  syn match phpDefine "\(\s\|^\)\(abstract\s\+\|final\s\+\|private\s\+\|protected\s\+\|public\s\+\|static\s\+\)*function\(\s\+.*[;}]\)\@="  contained contains=phpSCKeyword
+  syn match phpStructure  "\(\s\|^\)\(abstract\s\+\|final\s\+\)*class\(\s\+.*}\)\@="  contained
+  syn match phpStructure  "\(\s\|^\)interface\(\s\+.*}\)\@="  contained
+  syn match phpException  "\(\s\|^\)try\(\s\+.*}\)\@="  contained
+  syn match phpException  "\(\s\|^\)catch\(\s\+.*}\)\@="  contained
+
+  set foldmethod=syntax
+  syn region  phpFoldHtmlInside matchgroup=Delimiter start="?>" end="<?\(php\)\=" contained transparent contains=@htmlTop
+  syn region  phpFoldFunction matchgroup=Storageclass start="^\z(\s*\)\(abstract\s\+\|final\s\+\|private\s\+\|protected\s\+\|public\s\+\|static\s\+\)*function\s\([^};]*$\)\@="rs=e-9 matchgroup=Delimiter end="^\z1}" contains=@phpClFunction,phpFoldHtmlInside,phpFCKeyword contained transparent fold extend
+  syn region  phpFoldFunction matchgroup=Define start="^function\s\([^};]*$\)\@=" matchgroup=Delimiter end="^}" contains=@phpClFunction,phpFoldHtmlInside contained transparent fold extend
+  syn region  phpFoldClass  matchgroup=Structure start="^\z(\s*\)\(abstract\s\+\|final\s\+\)*class\s\+\([^}]*$\)\@=" matchgroup=Delimiter end="^\z1}" contains=@phpClFunction,phpFoldFunction,phpSCKeyword contained transparent fold extend
+  syn region  phpFoldInterface  matchgroup=Structure start="^\z(\s*\)interface\s\+\([^}]*$\)\@=" matchgroup=Delimiter end="^\z1}" contains=@phpClFunction,phpFoldFunction contained transparent fold extend
+  syn region  phpFoldCatch  matchgroup=Exception start="^\z(\s*\)catch\s\+\([^}]*$\)\@=" matchgroup=Delimiter end="^\z1}" contains=@phpClFunction,phpFoldFunction contained transparent fold extend
+  syn region  phpFoldTry  matchgroup=Exception start="^\z(\s*\)try\s\+\([^}]*$\)\@=" matchgroup=Delimiter end="^\z1}" contains=@phpClFunction,phpFoldFunction contained transparent fold extend
+elseif exists("php_folding") && php_folding==2
+  syn keyword phpDefine function  contained
+  syn keyword phpStructure  abstract class interface  contained
+  syn keyword phpException  catch throw try contained
+  syn keyword phpStorageClass final global private protected public static  contained
+
+  set foldmethod=syntax
+  syn region  phpFoldHtmlInside matchgroup=Delimiter start="?>" end="<?\(php\)\=" contained transparent contains=@htmlTop
+  syn region  phpParent matchgroup=Delimiter start="{" end="}"  contained contains=@phpClFunction,phpFoldHtmlInside transparent fold
+else
+  syn keyword phpDefine function  contained
+  syn keyword phpStructure  abstract class interface  contained
+  syn keyword phpException  catch throw try contained
+  syn keyword phpStorageClass final global private protected public static  contained
+endif
+
+" ================================================================
+" Peter Hodge - June 9, 2006
+" Some of these changes (highlighting isset/unset/echo etc) are not so
+" critical, but they make things more colourful. :-)
+
+" corrected highlighting for an escaped '\$' inside a double-quoted string
+syn match phpSpecialChar  "\\\$"  contained display
+
+" highlight object variables inside strings
+syn match phpMethodsVar "->\h\w*" contained contains=phpMethods,phpMemberSelector display containedin=phpStringDouble
+
+" highlight constant E_STRICT
+syntax case match
+syntax keyword phpCoreConstant E_STRICT contained
+syntax case ignore
+
+" different syntax highlighting for 'echo', 'print', 'switch', 'die' and 'list' keywords
+" to better indicate what they are.
+syntax keyword phpDefine echo print contained
+syntax keyword phpStructure list contained
+syntax keyword phpConditional switch contained
+syntax keyword phpStatement die contained
+
+" Highlighting for PHP5's user-definable magic class methods
+syntax keyword phpSpecialFunction containedin=ALLBUT,phpComment,phpStringDouble,phpStringSingle,phpIdentifier
+  \ __construct __destruct __call __toString __sleep __wakeup __set __get __unset __isset __clone __set_state
+" Highlighting for __autoload slightly different from line above
+syntax keyword phpSpecialFunction containedin=ALLBUT,phpComment,phpStringDouble,phpStringSingle,phpIdentifier,phpMethodsVar
+  \ __autoload
+highlight link phpSpecialFunction phpOperator
+
+" Highlighting for PHP5's built-in classes
+" - built-in classes harvested from get_declared_classes() in 5.1.4
+syntax keyword phpClasses containedin=ALLBUT,phpComment,phpStringDouble,phpStringSingle,phpIdentifier,phpMethodsVar
+  \ stdClass __PHP_Incomplete_Class php_user_filter Directory ArrayObject
+  \ Exception ErrorException LogicException BadFunctionCallException BadMethodCallException DomainException
+  \ RecursiveIteratorIterator IteratorIterator FilterIterator RecursiveFilterIterator ParentIterator LimitIterator
+  \ CachingIterator RecursiveCachingIterator NoRewindIterator AppendIterator InfiniteIterator EmptyIterator
+  \ ArrayIterator RecursiveArrayIterator DirectoryIterator RecursiveDirectoryIterator
+  \ InvalidArgumentException LengthException OutOfRangeException RuntimeException OutOfBoundsException
+  \ OverflowException RangeException UnderflowException UnexpectedValueException
+  \ PDO PDOException PDOStatement PDORow
+  \ Reflection ReflectionFunction ReflectionParameter ReflectionMethod ReflectionClass
+  \ ReflectionObject ReflectionProperty ReflectionExtension ReflectionException
+  \ SplFileInfo SplFileObject SplTempFileObject SplObjectStorage
+  \ XMLWriter LibXMLError XMLReader SimpleXMLElement SimpleXMLIterator
+  \ DOMException DOMStringList DOMNameList DOMDomError DOMErrorHandler
+  \ DOMImplementation DOMImplementationList DOMImplementationSource
+  \ DOMNode DOMNameSpaceNode DOMDocumentFragment DOMDocument DOMNodeList DOMNamedNodeMap
+  \ DOMCharacterData DOMAttr DOMElement DOMText DOMComment DOMTypeinfo DOMUserDataHandler
+  \ DOMLocator DOMConfiguration DOMCdataSection DOMDocumentType DOMNotation DOMEntity
+  \ DOMEntityReference DOMProcessingInstruction DOMStringExtend DOMXPath
+highlight link phpClasses phpFunctions
+
+" Highlighting for PHP5's built-in interfaces
+" - built-in classes harvested from get_declared_interfaces() in 5.1.4
+syntax keyword phpInterfaces containedin=ALLBUT,phpComment,phpStringDouble,phpStringSingle,phpIdentifier,phpMethodsVar
+  \ Iterator IteratorAggregate RecursiveIterator OuterIterator SeekableIterator
+  \ Traversable ArrayAccess Serializable Countable SplObserver SplSubject Reflector
+highlight link phpInterfaces phpConstant
+
+" option defaults:
+if ! exists('php_special_functions')
+    let php_special_functions = 1
+endif
+if ! exists('php_alt_comparisons')
+    let php_alt_comparisons = 1
+endif
+if ! exists('php_alt_assignByReference')
+    let php_alt_assignByReference = 1
+endif
+
+if php_special_functions
+    " Highlighting for PHP built-in functions which exhibit special behaviours
+    " - isset()/unset()/empty() are not real functions.
+    " - compact()/extract() directly manipulate variables in the local scope where
+    "   regular functions would not be able to.
+    " - eval() is the token 'make_your_code_twice_as_complex()' function for PHP.
+    " - user_error()/trigger_error() can be overloaded by set_error_handler and also
+    "   have the capacity to terminate your script when type is E_USER_ERROR.
+    syntax keyword phpSpecialFunction containedin=ALLBUT,phpComment,phpStringDouble,phpStringSingle
+  \ user_error trigger_error isset unset eval extract compact empty
+endif
+
+if php_alt_assignByReference
+    " special highlighting for '=&' operator
+    syntax match phpAssignByRef /=\s*&/ containedin=ALLBUT,phpComment,phpStringDouble,phpStringSingle
+    highlight link phpAssignByRef Type
+endif
+
+if php_alt_comparisons
+  " highlight comparison operators differently
+  syntax match phpComparison "\v[=!]\=\=?" contained containedin=phpRegion
+  syntax match phpComparison "\v[=<>-]@<![<>]\=?[<>]@!" contained containedin=phpRegion
+
+  " highlight the 'instanceof' operator as a comparison operator rather than a structure
+  syntax case ignore
+  syntax keyword phpComparison instanceof contained containedin=phpRegion
+
+  hi link phpComparison Statement
+endif
+
+" ================================================================
+
+" Sync
+if php_sync_method==-1
+  if exists("php_noShortTags")
+    syn sync match phpRegionSync grouphere phpRegion "^\s*<?php\s*$"
+  else
+    syn sync match phpRegionSync grouphere phpRegion "^\s*<?\(php\)\=\s*$"
+  endif
+  syn sync match phpRegionSync grouphere phpRegionSc +^\s*<script language="php">\s*$+
+  if exists("php_asp_tags")
+    syn sync match phpRegionSync grouphere phpRegionAsp "^\s*<%\(=\)\=\s*$"
+  endif
+  syn sync match phpRegionSync grouphere NONE "^\s*?>\s*$"
+  syn sync match phpRegionSync grouphere NONE "^\s*%>\s*$"
+  syn sync match phpRegionSync grouphere phpRegion "function\s.*(.*\$"
+  "syn sync match phpRegionSync grouphere NONE "/\i*>\s*$"
+elseif php_sync_method>0
+  exec "syn sync minlines=" . php_sync_method
+else
+  exec "syn sync fromstart"
+endif
+
+" Define the default highlighting.
+" For version 5.7 and earlier: only when not done already
+" For version 5.8 and later: only when an item doesn't have highlighting yet
+if version >= 508 || !exists("did_php_syn_inits")
+  if version < 508
+    let did_php_syn_inits = 1
+    command -nargs=+ HiLink hi link <args>
+  else
+    command -nargs=+ HiLink hi def link <args>
+  endif
+
+  HiLink   phpConstant  Constant
+  HiLink   phpCoreConstant  Constant
+  HiLink   phpComment Comment
+  HiLink   phpException Exception
+  HiLink   phpBoolean Boolean
+  HiLink   phpStorageClass  StorageClass
+  HiLink   phpSCKeyword StorageClass
+  HiLink   phpFCKeyword Define
+  HiLink   phpStructure Structure
+  HiLink   phpStringSingle  String
+  HiLink   phpStringDouble  String
+  HiLink   phpBacktick  String
+  HiLink   phpNumber  Number
+  HiLink   phpFloat Float
+  HiLink   phpMethods Function
+  HiLink   phpFunctions Function
+  HiLink   phpBaselib Function
+  HiLink   phpRepeat  Repeat
+  HiLink   phpConditional Conditional
+  HiLink   phpLabel Label
+  HiLink   phpStatement Statement
+  HiLink   phpKeyword Statement
+  HiLink   phpType  Type
+  HiLink   phpInclude Include
+  HiLink   phpDefine  Define
+  HiLink   phpSpecialChar SpecialChar
+  HiLink   phpParent  Delimiter
+  HiLink   phpIdentifierConst Delimiter
+  HiLink   phpParentError Error
+  HiLink   phpOctalError  Error
+  HiLink   phpTodo  Todo
+  HiLink   phpMemberSelector  Structure
+  if exists("php_oldStyle")
+  hi  phpIntVar guifg=Red ctermfg=DarkRed
+  hi  phpEnvVar guifg=Red ctermfg=DarkRed
+  hi  phpOperator guifg=SeaGreen ctermfg=DarkGreen
+  hi  phpVarSelector guifg=SeaGreen ctermfg=DarkGreen
+  hi  phpRelation guifg=SeaGreen ctermfg=DarkGreen
+  hi  phpIdentifier guifg=DarkGray ctermfg=Brown
+  hi  phpIdentifierSimply guifg=DarkGray ctermfg=Brown
+  else
+  HiLink  phpIntVar Identifier
+  HiLink  phpEnvVar Identifier
+  HiLink  phpOperator Operator
+  HiLink  phpVarSelector  Operator
+  HiLink  phpRelation Operator
+  HiLink  phpIdentifier Identifier
+  HiLink  phpIdentifierSimply Identifier
+  endif
+
+  delcommand HiLink
+endif
+
+let b:current_syntax = "php"
+
+if main_syntax == 'php'
+  unlet main_syntax
+endif
+
+" vim: ts=8 sts=2 sw=2 expandtab
--- /dev/null
+++ b/lib/vimfiles/syntax/phtml.vim
@@ -1,0 +1,244 @@
+" Vim syntax file
+" Language:	phtml PHP 2.0
+" Maintainer:	Lutz Eymers <ixtab@polzin.com>
+" URL:		http://www.isp.de/data/phtml.vim
+" Email:	Subject: send syntax_vim.tgz
+" Last change:	2003 May 11
+"
+" Options	phtml_sql_query = 1 for SQL syntax highligthing inside strings
+"		phtml_minlines = x     to sync at least x lines backwards
+
+" For version 5.x: Clear all syntax items
+" For version 6.x: Quit when a syntax file was already loaded
+if version < 600
+  syntax clear
+elseif exists("b:current_syntax")
+  finish
+endif
+
+if !exists("main_syntax")
+  let main_syntax = 'phtml'
+endif
+
+if version < 600
+  so <sfile>:p:h/html.vim
+else
+  runtime! syntax/html.vim
+  unlet b:current_syntax
+endif
+
+syn cluster htmlPreproc add=phtmlRegionInsideHtmlTags
+
+if exists( "phtml_sql_query")
+  if phtml_sql_query == 1
+    syn include @phtmlSql <sfile>:p:h/sql.vim
+    unlet b:current_syntax
+  endif
+endif
+syn cluster phtmlSql remove=sqlString,sqlComment
+
+syn case match
+
+" Env Variables
+syn keyword phtmlEnvVar SERVER_SOFTWARE SERVER_NAME SERVER_URL GATEWAY_INTERFACE   contained
+syn keyword phtmlEnvVar SERVER_PROTOCOL SERVER_PORT REQUEST_METHOD PATH_INFO  contained
+syn keyword phtmlEnvVar PATH_TRANSLATED SCRIPT_NAME QUERY_STRING REMOTE_HOST contained
+syn keyword phtmlEnvVar REMOTE_ADDR AUTH_TYPE REMOTE_USER CONTEN_TYPE  contained
+syn keyword phtmlEnvVar CONTENT_LENGTH HTTPS HTTPS_KEYSIZE HTTPS_SECRETKEYSIZE  contained
+syn keyword phtmlEnvVar HTTP_ACCECT HTTP_USER_AGENT HTTP_IF_MODIFIED_SINCE  contained
+syn keyword phtmlEnvVar HTTP_FROM HTTP_REFERER contained
+syn keyword phtmlEnvVar PHP_SELF contained
+
+syn case ignore
+
+" Internal Variables
+syn keyword phtmlIntVar phperrmsg php_self contained
+
+" Comment
+syn region phtmlComment		start="/\*" end="\*/"  contained contains=phtmlTodo
+
+" Function names
+syn keyword phtmlFunctions  Abs Ada_Close Ada_Connect Ada_Exec Ada_FetchRow contained
+syn keyword phtmlFunctions  Ada_FieldName Ada_FieldNum Ada_FieldType contained
+syn keyword phtmlFunctions  Ada_FreeResult Ada_NumFields Ada_NumRows Ada_Result contained
+syn keyword phtmlFunctions  Ada_ResultAll AddSlashes ASort BinDec Ceil ChDir contained
+syn keyword phtmlFunctions  AdaGrp ChMod ChOwn Chop Chr ClearStack ClearStatCache contained
+syn keyword phtmlFunctions  closeDir CloseLog Cos Count Crypt Date dbList  contained
+syn keyword phtmlFunctions  dbmClose dbmDelete dbmExists dbmFetch dbmFirstKey contained
+syn keyword phtmlFunctions  dbmInsert dbmNextKey dbmOpen dbmReplace DecBin DecHex contained
+syn keyword phtmlFunctions  DecOct doubleval Echo End ereg eregi ereg_replace contained
+syn keyword phtmlFunctions  eregi_replace EscapeShellCmd Eval Exec Exit Exp contained
+syn keyword phtmlFunctions  fclose feof fgets fgetss File fileAtime fileCtime contained
+syn keyword phtmlFunctions  fileGroup fileInode fileMtime fileOwner filePerms contained
+syn keyword phtmlFunctions  fileSize fileType Floor Flush fopen fputs FPassThru contained
+syn keyword phtmlFunctions  fseek fsockopen ftell getAccDir GetEnv getHostByName contained
+syn keyword phtmlFunctions  getHostByAddr GetImageSize getLastAcess contained
+syn keyword phtmlFunctions  getLastbrowser getLastEmail getLastHost getLastMod contained
+syn keyword phtmlFunctions  getLastref getLogDir getMyInode getMyPid getMyUid contained
+syn keyword phtmlFunctions  getRandMax getStartLogging getToday getTotal GetType contained
+syn keyword phtmlFunctions  gmDate Header HexDec HtmlSpecialChars ImageArc contained
+syn keyword phtmlFunctions  ImageChar ImageCharUp IamgeColorAllocate  contained
+syn keyword phtmlFunctions  ImageColorTransparent ImageCopyResized ImageCreate contained
+syn keyword phtmlFunctions  ImageCreateFromGif ImageDestroy ImageFill contained
+syn keyword phtmlFunctions  ImageFilledPolygon ImageFilledRectangle contained
+syn keyword phtmlFunctions  ImageFillToBorder ImageGif ImageInterlace ImageLine contained
+syn keyword phtmlFunctions  ImagePolygon ImageRectangle ImageSetPixel  contained
+syn keyword phtmlFunctions  ImageString ImageStringUp ImageSX ImageSY Include contained
+syn keyword phtmlFunctions  InitSyslog intval IsSet Key Link LinkInfo Log Log10 contained
+syn keyword phtmlFunctions  LosAs Mail Max Md5 mi_Close mi_Connect mi_DBname contained
+syn keyword phtmlFunctions  mi_Exec mi_FieldName mi_FieldNum mi_NumFields contained
+syn keyword phtmlFunctions  mi_NumRows mi_Result Microtime Min MkDir MkTime msql contained
+syn keyword phtmlFunctions  msql_connect msql_CreateDB msql_dbName msql_DropDB contained
+syn keyword phtmlFunctions  msqlFieldFlags msql_FieldLen msql_FieldName contained
+syn keyword phtmlFunctions  msql_FieldType msql_FreeResult msql_ListDBs contained
+syn keyword phtmlFunctions  msql_Listfields msql_ListTables msql_NumFields contained
+syn keyword phtmlFunctions  msql_NumRows msql_RegCase msql_Result msql_TableName contained
+syn keyword phtmlFunctions  mysql mysql_affected_rows mysql_close mysql_connect contained
+syn keyword phtmlFunctions  mysql_CreateDB mysql_dbName mysqlDropDB  contained
+syn keyword phtmlFunctions  mysql_FieldFlags mysql_FieldLen mysql_FieldName contained
+syn keyword phtmlFunctions  mysql_FieldType mysql_FreeResult mysql_insert_id contained
+syn keyword phtmlFunctions  mysql_listDBs mysql_Listfields mysql_ListTables contained
+syn keyword phtmlFunctions  mysql_NumFields mysql_NumRows mysql_Result  contained
+syn keyword phtmlFunctions  mysql_TableName Next OctDec openDir OpenLog  contained
+syn keyword phtmlFunctions  Ora_Bind Ora_Close Ora_Commit Ora_CommitOff contained
+syn keyword phtmlFunctions  Ora_CommitOn Ora_Exec Ora_Fetch Ora_GetColumn contained
+syn keyword phtmlFunctions  Ora_Logoff Ora_Logon Ora_Parse Ora_Rollback Ord  contained
+syn keyword phtmlFunctions  Parse_str PassThru pclose pg_Close pg_Connect contained
+syn keyword phtmlFunctions  pg_DBname pg_ErrorMessage pg_Exec pg_FieldName contained
+syn keyword phtmlFunctions  pg_FieldPrtLen pg_FieldNum pg_FieldSize  contained
+syn keyword phtmlFunctions  pg_FieldType pg_FreeResult pg_GetLastOid pg_Host contained
+syn keyword phtmlFunctions  pg_NumFields pg_NumRows pg_Options pg_Port  contained
+syn keyword phtmlFunctions  pg_Result pg_tty phpInfo phpVersion popen pos pow contained
+syn keyword phtmlFunctions  Prev PutEnv QuoteMeta Rand readDir ReadFile ReadLink contained
+syn keyword phtmlFunctions  reg_Match reg_replace reg_Search Rename Reset return  contained
+syn keyword phtmlFunctions  rewind rewindDir RmDir rSort SetCookie SetErrorReporting contained
+syn keyword phtmlFunctions  SetLogging SetShowInfo SetType shl shr Sin Sleep contained
+syn keyword phtmlFunctions  Solid_Close Solid_Connect Solid_Exec Solid_FetchRow contained
+syn keyword phtmlFunctions  Solid_FieldName Solid_FieldNum Solid_FreeResult  contained
+syn keyword phtmlFunctions  Solid_NumFields Solid_NumRows Solid_Result Sort contained
+syn keyword phtmlFunctions  Spundtex Sprintf Sqrt Srand strchr strtr  contained
+syn keyword phtmlFunctions  StripSlashes strlen strchr strstr strtok strtolower contained
+syn keyword phtmlFunctions  strtoupper strval substr sybSQL_CheckConnect contained
+syn keyword phtmlFunctions  sybSQL_DBUSE sybSQL_Connect sybSQL_Exit contained
+syn keyword phtmlFunctions  sybSQL_Fieldname sybSQL_GetField sybSQL_IsRow  contained
+syn keyword phtmlFunctions  sybSQL_NextRow sybSQL_NumFields sybSQL_NumRows contained
+syn keyword phtmlFunctions  sybSQL_Query sybSQL_Result sybSQL_Result sybSQL_Seek contained
+syn keyword phtmlFunctions  Symlink syslog System Tan TempNam Time Umask UniqId contained
+syn keyword phtmlFunctions  Unlink Unset UrlDecode UrlEncode USleep Virtual contained
+syn keyword phtmlFunctions  SecureVar contained
+
+" Conditional
+syn keyword phtmlConditional  if else elseif endif switch endswitch contained
+
+" Repeat
+syn keyword phtmlRepeat  while endwhile contained
+
+" Repeat
+syn keyword phtmlLabel  case default contained
+
+" Statement
+syn keyword phtmlStatement  break return continue exit contained
+
+" Operator
+syn match phtmlOperator  "[-=+%^&|*!]" contained
+syn match phtmlOperator  "[-+*/%^&|]=" contained
+syn match phtmlOperator  "/[^*]"me=e-1 contained
+syn match phtmlOperator  "\$" contained
+syn match phtmlRelation  "&&" contained
+syn match phtmlRelation  "||" contained
+syn match phtmlRelation  "[!=<>]=" contained
+syn match phtmlRelation  "[<>]" contained
+
+" Identifier
+syn match  phtmlIdentifier "$\h\w*" contained contains=phtmlEnvVar,phtmlIntVar,phtmlOperator
+
+
+" Include
+syn keyword phtmlInclude  include contained
+
+" Definesag
+syn keyword phtmlDefine  Function contained
+
+" String
+syn region phtmlString keepend matchgroup=None start=+"+ skip=+\\\\\|\\"+  end=+"+ contains=phtmlIdentifier,phtmlSpecialChar,@phtmlSql contained
+
+" Number
+syn match phtmlNumber  "-\=\<\d\+\>" contained
+
+" Float
+syn match phtmlFloat  "\(-\=\<\d+\|-\=\)\.\d\+\>" contained
+
+" SpecialChar
+syn match phtmlSpecialChar "\\[abcfnrtyv\\]" contained
+syn match phtmlSpecialChar "\\\d\{3}" contained contains=phtmlOctalError
+syn match phtmlSpecialChar "\\x[0-9a-fA-F]\{2}" contained
+
+syn match phtmlOctalError "[89]" contained
+
+
+syn match phtmlParentError "[)}\]]" contained
+
+" Todo
+syn keyword phtmlTodo TODO Todo todo contained
+
+" Parents
+syn cluster phtmlInside contains=phtmlComment,phtmlFunctions,phtmlIdentifier,phtmlConditional,phtmlRepeat,phtmlLabel,phtmlStatement,phtmlOperator,phtmlRelation,phtmlString,phtmlNumber,phtmlFloat,phtmlSpecialChar,phtmlParent,phtmlParentError,phtmlInclude
+
+syn cluster phtmlTop contains=@phtmlInside,phtmlInclude,phtmlDefine,phtmlParentError,phtmlTodo
+syn region phtmlParent	matchgroup=Delimiter start="(" end=")" contained contains=@phtmlInside
+syn region phtmlParent	matchgroup=Delimiter start="{" end="}" contained contains=@phtmlInside
+syn region phtmlParent	matchgroup=Delimiter start="\[" end="\]" contained contains=@phtmlInside
+
+syn region phtmlRegion keepend matchgroup=Delimiter start="<?" skip=+(.*>.*)\|".\{-}>.\{-}"\|/\*.\{-}>.\{-}\*/+ end=">" contains=@phtmlTop
+syn region phtmlRegionInsideHtmlTags keepend matchgroup=Delimiter start="<?" skip=+(.*>.*)\|/\*.\{-}>.\{-}\*/+ end=">" contains=@phtmlTop contained
+
+" sync
+if exists("phtml_minlines")
+  exec "syn sync minlines=" . phtml_minlines
+else
+  syn sync minlines=100
+endif
+
+" Define the default highlighting.
+" For version 5.7 and earlier: only when not done already
+" For version 5.8 and later: only when an item doesn't have highlighting yet
+if version >= 508 || !exists("did_phtml_syn_inits")
+  if version < 508
+    let did_phtml_syn_inits = 1
+    command -nargs=+ HiLink hi link <args>
+  else
+    command -nargs=+ HiLink hi def link <args>
+  endif
+
+  HiLink phtmlComment		Comment
+  HiLink phtmlString		String
+  HiLink phtmlNumber		Number
+  HiLink phtmlFloat		Float
+  HiLink phtmlIdentifier	Identifier
+  HiLink phtmlIntVar		Identifier
+  HiLink phtmlEnvVar		Identifier
+  HiLink phtmlFunctions		Function
+  HiLink phtmlRepeat		Repeat
+  HiLink phtmlConditional	Conditional
+  HiLink phtmlLabel		Label
+  HiLink phtmlStatement		Statement
+  HiLink phtmlType		Type
+  HiLink phtmlInclude		Include
+  HiLink phtmlDefine		Define
+  HiLink phtmlSpecialChar	SpecialChar
+  HiLink phtmlParentError	Error
+  HiLink phtmlOctalError	Error
+  HiLink phtmlTodo		Todo
+  HiLink phtmlOperator		Operator
+  HiLink phtmlRelation		Operator
+
+  delcommand HiLink
+endif
+
+let b:current_syntax = "phtml"
+
+if main_syntax == 'phtml'
+  unlet main_syntax
+endif
+
+" vim: ts=8
--- /dev/null
+++ b/lib/vimfiles/syntax/pic.vim
@@ -1,0 +1,127 @@
+" Vim syntax file
+" Language:     PIC16F84 Assembler (Microchip's microcontroller)
+" Maintainer:   Aleksandar Veselinovic <aleksa@cs.cmu.com>
+" Last Change:  2003 May 11
+" URL:		http://galeb.etf.bg.ac.yu/~alexa/vim/syntax/pic.vim
+" Revision:     1.01
+
+" For version 5.x: Clear all syntax items
+" For version 6.x: Quit when a syntax file was already loaded
+if version < 600
+  syntax clear
+elseif exists("b:current_syntax")
+  finish
+endif
+
+syn case match
+syn keyword picTodo NOTE TODO XXX contained
+
+syn case ignore
+
+syn match picIdentifier "[a-z_$][a-z0-9_$]*"
+syn match picLabel      "^[A-Z_$][A-Z0-9_$]*"
+syn match picLabel      "^[A-Z_$][A-Z0-9_$]*:"me=e-1
+
+syn match picASCII      "A\='.'"
+syn match picBinary     "B'[0-1]\+'"
+syn match picDecimal    "D'\d\+'"
+syn match picDecimal    "\d\+"
+syn match picHexadecimal "0x\x\+"
+syn match picHexadecimal "H'\x\+'"
+syn match picHexadecimal "[0-9]\x*h"
+syn match picOctal      "O'[0-7]\o*'"
+
+
+syn match picComment    ";.*" contains=picTodo
+
+syn region picString    start=+"+ end=+"+
+
+syn keyword picRegister		INDF TMR0 PCL STATUS FSR PORTA PORTB
+syn keyword picRegister		EEDATA EEADR PCLATH INTCON INDF OPTION_REG PCL
+syn keyword picRegister		FSR TRISA TRISB EECON1 EECON2 INTCON OPTION
+
+
+" Register --- bits
+
+" STATUS
+syn keyword picRegisterPart     IRP RP1 RP0 TO PD Z DC C
+
+" PORTA
+syn keyword picRegisterPart     T0CKI
+syn match   picRegisterPart     "RA[0-4]"
+
+" PORTB
+syn keyword picRegisterPart     INT
+syn match   picRegisterPart     "RB[0-7]"
+
+" INTCON
+syn keyword picRegisterPart     GIE EEIE T0IE INTE RBIE T0IF INTF RBIF
+
+" OPTION
+syn keyword picRegisterPart     RBPU INTEDG T0CS T0SE PSA PS2 PS1 PS0
+
+" EECON2
+syn keyword picRegisterPart     EEIF WRERR WREN WR RD
+
+" INTCON
+syn keyword picRegisterPart     GIE EEIE T0IE INTE RBIE T0IF INTF RBIF
+
+
+" OpCodes...
+syn keyword picOpcode  ADDWF ANDWF CLRF CLRW COMF DECF DECFSZ INCF INCFSZ
+syn keyword picOpcode  IORWF MOVF MOVWF NOP RLF RRF SUBWF SWAPF XORWF
+syn keyword picOpcode  BCF BSF BTFSC BTFSS
+syn keyword picOpcode  ADDLW ANDLW CALL CLRWDT GOTO IORLW MOVLW RETFIE
+syn keyword picOpcode  RETLW RETURN SLEEP SUBLW XORLW
+syn keyword picOpcode  GOTO
+
+
+" Directives
+syn keyword picDirective __BADRAM BANKISEL BANKSEL CBLOCK CODE __CONFIG
+syn keyword picDirective CONSTANT DATA DB DE DT DW ELSE END ENDC
+syn keyword picDirective ENDIF ENDM ENDW EQU ERROR ERRORLEVEL EXITM EXPAND
+syn keyword picDirective EXTERN FILL GLOBAL IDATA __IDLOCS IF IFDEF IFNDEF
+syn keyword picDirective INCLUDE LIST LOCAL MACRO __MAXRAM MESSG NOEXPAND
+syn keyword picDirective NOLIST ORG PAGE PAGESEL PROCESSOR RADIX RES SET
+syn keyword picDirective SPACE SUBTITLE TITLE UDATA UDATA_OVR UDATA_SHR
+syn keyword picDirective VARIABLE WHILE INCLUDE
+syn match picDirective   "#\=UNDEFINE"
+syn match picDirective   "#\=INCLUDE"
+syn match picDirective   "#\=DEFINE"
+
+
+" Define the default highlighting.
+" For version 5.7 and earlier: only when not done already
+" For version 5.8 and later: only when an item doesn't have highlighting yet
+if version >= 508 || !exists("did_pic16f84_syntax_inits")
+  if version < 508
+    let did_pic16f84_syntax_inits = 1
+    command -nargs=+ HiLink hi link <args>
+  else
+    command -nargs=+ HiLink hi def link <args>
+  endif
+
+  HiLink picTodo		Todo
+  HiLink picComment		Comment
+  HiLink picDirective		Statement
+  HiLink picLabel		Label
+  HiLink picString		String
+
+ "HiLink picOpcode		Keyword
+ "HiLink picRegister		Structure
+ "HiLink picRegisterPart	Special
+
+  HiLink picASCII		String
+  HiLink picBinary		Number
+  HiLink picDecimal		Number
+  HiLink picHexadecimal		Number
+  HiLink picOctal		Number
+
+  HiLink picIdentifier		Identifier
+
+  delcommand HiLink
+endif
+
+let b:current_syntax = "pic"
+
+" vim: ts=8
--- /dev/null
+++ b/lib/vimfiles/syntax/pike.vim
@@ -1,0 +1,155 @@
+" Vim syntax file
+" Language:	Pike
+" Maintainer:	Francesco Chemolli <kinkie@kame.usr.dsi.unimi.it>
+" Last Change:	2001 May 10
+
+" For version 5.x: Clear all syntax items
+" For version 6.x: Quit when a syntax file was already loaded
+if version < 600
+  syntax clear
+elseif exists("b:current_syntax")
+  finish
+endif
+
+" A bunch of useful C keywords
+syn keyword pikeStatement	goto break return continue
+syn keyword pikeLabel		case default
+syn keyword pikeConditional	if else switch
+syn keyword pikeRepeat		while for foreach do
+syn keyword pikeStatement	gauge destruct lambda inherit import typeof
+syn keyword pikeException	catch
+syn keyword pikeType		inline nomask private protected public static
+
+
+syn keyword pikeTodo contained	TODO FIXME XXX
+
+" String and Character constants
+" Highlight special characters (those which have a backslash) differently
+syn match pikeSpecial contained	"\\[0-7][0-7][0-7]\=\|\\."
+syn region pikeString		start=+"+ skip=+\\\\\|\\"+ end=+"+ contains=pikeSpecial
+syn match pikeCharacter		"'[^\\]'"
+syn match pikeSpecialCharacter	"'\\.'"
+syn match pikeSpecialCharacter	"'\\[0-7][0-7]'"
+syn match pikeSpecialCharacter	"'\\[0-7][0-7][0-7]'"
+
+" Compound data types
+syn region pikeCompoundType start='({' contains=pikeString,pikeCompoundType,pikeNumber,pikeFloat end='})'
+syn region pikeCompoundType start='(\[' contains=pikeString,pikeCompoundType,pikeNumber,pikeFloat end='\])'
+syn region pikeCompoundType start='(<' contains=pikeString,pikeCompoundType,pikeNumber,pikeFloat end='>)'
+
+"catch errors caused by wrong parenthesis
+syn region pikeParen		transparent start='([^{[<(]' end=')' contains=ALLBUT,pikeParenError,pikeIncluded,pikeSpecial,pikeTodo,pikeUserLabel,pikeBitField
+syn match pikeParenError		")"
+syn match pikeInParen contained	"[^(][{}][^)]"
+
+"integer number, or floating point number without a dot and with "f".
+syn case ignore
+syn match pikeNumber		"\<\d\+\(u\=l\=\|lu\|f\)\>"
+"floating point number, with dot, optional exponent
+syn match pikeFloat		"\<\d\+\.\d*\(e[-+]\=\d\+\)\=[fl]\=\>"
+"floating point number, starting with a dot, optional exponent
+syn match pikeFloat		"\.\d\+\(e[-+]\=\d\+\)\=[fl]\=\>"
+"floating point number, without dot, with exponent
+syn match pikeFloat		"\<\d\+e[-+]\=\d\+[fl]\=\>"
+"hex number
+syn match pikeNumber		"\<0x[0-9a-f]\+\(u\=l\=\|lu\)\>"
+"syn match pikeIdentifier	"\<[a-z_][a-z0-9_]*\>"
+syn case match
+" flag an octal number with wrong digits
+syn match pikeOctalError		"\<0[0-7]*[89]"
+
+if exists("c_comment_strings")
+  " A comment can contain pikeString, pikeCharacter and pikeNumber.
+  " But a "*/" inside a pikeString in a pikeComment DOES end the comment!  So we
+  " need to use a special type of pikeString: pikeCommentString, which also ends on
+  " "*/", and sees a "*" at the start of the line as comment again.
+  " Unfortunately this doesn't very well work for // type of comments :-(
+  syntax match pikeCommentSkip	contained "^\s*\*\($\|\s\+\)"
+  syntax region pikeCommentString	contained start=+"+ skip=+\\\\\|\\"+ end=+"+ end=+\*/+me=s-1 contains=pikeSpecial,pikeCommentSkip
+  syntax region pikeComment2String	contained start=+"+ skip=+\\\\\|\\"+ end=+"+ end="$" contains=pikeSpecial
+  syntax region pikeComment	start="/\*" end="\*/" contains=pikeTodo,pikeCommentString,pikeCharacter,pikeNumber,pikeFloat
+  syntax match  pikeComment	"//.*" contains=pikeTodo,pikeComment2String,pikeCharacter,pikeNumber
+  syntax match  pikeComment	"#\!.*" contains=pikeTodo,pikeComment2String,pikeCharacter,pikeNumber
+else
+  syn region pikeComment		start="/\*" end="\*/" contains=pikeTodo
+  syn match pikeComment		"//.*" contains=pikeTodo
+  syn match pikeComment		"#!.*" contains=pikeTodo
+endif
+syntax match pikeCommentError	"\*/"
+
+syn keyword pikeOperator	sizeof
+syn keyword pikeType		int string void float mapping array multiset mixed
+syn keyword pikeType		program object function
+
+syn region pikePreCondit	start="^\s*#\s*\(if\>\|ifdef\>\|ifndef\>\|elif\>\|else\>\|endif\>\)" skip="\\$" end="$" contains=pikeComment,pikeString,pikeCharacter,pikeNumber,pikeCommentError
+syn region pikeIncluded contained start=+"+ skip=+\\\\\|\\"+ end=+"+
+syn match pikeIncluded contained "<[^>]*>"
+syn match pikeInclude		"^\s*#\s*include\>\s*["<]" contains=pikeIncluded
+"syn match pikeLineSkip	"\\$"
+syn region pikeDefine		start="^\s*#\s*\(define\>\|undef\>\)" skip="\\$" end="$" contains=ALLBUT,pikePreCondit,pikeIncluded,pikeInclude,pikeDefine,pikeInParen
+syn region pikePreProc		start="^\s*#\s*\(pragma\>\|line\>\|warning\>\|warn\>\|error\>\)" skip="\\$" end="$" contains=ALLBUT,pikePreCondit,pikeIncluded,pikeInclude,pikeDefine,pikeInParen
+
+" Highlight User Labels
+syn region	pikeMulti		transparent start='?' end=':' contains=ALLBUT,pikeIncluded,pikeSpecial,pikeTodo,pikeUserLabel,pikeBitField
+" Avoid matching foo::bar() in C++ by requiring that the next char is not ':'
+syn match	pikeUserLabel	"^\s*\I\i*\s*:$"
+syn match	pikeUserLabel	";\s*\I\i*\s*:$"ms=s+1
+syn match	pikeUserLabel	"^\s*\I\i*\s*:[^:]"me=e-1
+syn match	pikeUserLabel	";\s*\I\i*\s*:[^:]"ms=s+1,me=e-1
+
+" Avoid recognizing most bitfields as labels
+syn match	pikeBitField	"^\s*\I\i*\s*:\s*[1-9]"me=e-1
+syn match	pikeBitField	";\s*\I\i*\s*:\s*[1-9]"me=e-1
+
+syn sync ccomment pikeComment minlines=10
+
+" Define the default highlighting.
+" For version 5.7 and earlier: only when not done already
+" For version 5.8 and later: only when an item doesn't have highlighting yet
+if version >= 508 || !exists("did_pike_syntax_inits")
+  if version < 508
+    let did_pike_syntax_inits = 1
+    command -nargs=+ HiLink hi link <args>
+  else
+    command -nargs=+ HiLink hi def link <args>
+  endif
+
+  HiLink pikeLabel		Label
+  HiLink pikeUserLabel		Label
+  HiLink pikeConditional	Conditional
+  HiLink pikeRepeat		Repeat
+  HiLink pikeCharacter		Character
+  HiLink pikeSpecialCharacter pikeSpecial
+  HiLink pikeNumber		Number
+  HiLink pikeFloat		Float
+  HiLink pikeOctalError		pikeError
+  HiLink pikeParenError		pikeError
+  HiLink pikeInParen		pikeError
+  HiLink pikeCommentError	pikeError
+  HiLink pikeOperator		Operator
+  HiLink pikeInclude		Include
+  HiLink pikePreProc		PreProc
+  HiLink pikeDefine		Macro
+  HiLink pikeIncluded		pikeString
+  HiLink pikeError		Error
+  HiLink pikeStatement		Statement
+  HiLink pikePreCondit		PreCondit
+  HiLink pikeType		Type
+  HiLink pikeCommentError	pikeError
+  HiLink pikeCommentString	pikeString
+  HiLink pikeComment2String	pikeString
+  HiLink pikeCommentSkip	pikeComment
+  HiLink pikeString		String
+  HiLink pikeComment		Comment
+  HiLink pikeSpecial		SpecialChar
+  HiLink pikeTodo		Todo
+  HiLink pikeException		pikeStatement
+  HiLink pikeCompoundType	Constant
+  "HiLink pikeIdentifier	Identifier
+
+  delcommand HiLink
+endif
+
+let b:current_syntax = "pike"
+
+" vim: ts=8
--- /dev/null
+++ b/lib/vimfiles/syntax/pilrc.vim
@@ -1,0 +1,148 @@
+" Vim syntax file
+" Language:	pilrc - a resource compiler for Palm OS development
+" Maintainer:	Brian Schau <brian@schau.com>
+" Last change:	2003 May 11
+" Available on:	http://www.schau.com/pilrcvim/pilrc.vim
+
+" Remove any old syntax
+if version < 600
+	syn clear
+elseif exists("b:current_syntax")
+	finish
+endif
+
+syn case ignore
+
+" Notes: TRANSPARENT, FONT and FONT ID are defined in the specials
+"	 section below.   Beware of the order of the specials!
+"	 Look in the syntax.txt and usr_27.txt files in vim\vim{version}\doc
+"	 directory for regexps etc.
+
+" Keywords - basic
+syn keyword pilrcKeyword ALERT APPLICATION APPLICATIONICONNAME AREA
+syn keyword pilrcKeyword BITMAP BITMAPCOLOR BITMAPCOLOR16 BITMAPCOLOR16K
+syn keyword pilrcKeyword BITMAPFAMILY BITMAPFAMILYEX BITMAPFAMILYSPECIAL
+syn keyword pilrcKeyword BITMAPGREY BITMAPGREY16 BITMAPSCREENFAMILY
+syn keyword pilrcKeyword BOOTSCREENFAMILY BUTTON BUTTONS BYTELIST
+syn keyword pilrcKeyword CATEGORIES CHECKBOX COUNTRYLOCALISATION
+syn keyword pilrcKeyword DATA
+syn keyword pilrcKeyword FEATURE FIELD FONTINDEX FORM FORMBITMAP
+syn keyword pilrcKeyword GADGET GENERATEHEADER
+syn keyword pilrcKeyword GRAFFITIINPUTAREA GRAFFITISTATEINDICATOR
+syn keyword pilrcKeyword HEX
+syn keyword pilrcKeyword ICON ICONFAMILY ICONFAMILYEX INTEGER
+syn keyword pilrcKeyword KEYBOARD
+syn keyword pilrcKeyword LABEL LAUNCHERCATEGORY LIST LONGWORDLIST
+syn keyword pilrcKeyword MENU MENUITEM MESSAGE  MIDI
+syn keyword pilrcKeyword PALETTETABLE POPUPLIST POPUPTRIGGER
+syn keyword pilrcKeyword PULLDOWN PUSHBUTTON
+syn keyword pilrcKeyword REPEATBUTTON RESETAUTOID
+syn keyword pilrcKeyword SCROLLBAR SELECTORTRIGGER SLIDER SMALLICON
+syn keyword pilrcKeyword SMALLICONFAMILY SMALLICONFAMILYEX STRING STRINGTABLE
+syn keyword pilrcKeyword TABLE TITLE TRANSLATION TRAP
+syn keyword pilrcKeyword VERSION
+syn keyword pilrcKeyword WORDLIST
+
+" Types
+syn keyword pilrcType AT AUTOSHIFT
+syn keyword pilrcType BACKGROUNDID BITMAPID BOLDFRAME BPP
+syn keyword pilrcType CHECKED COLORTABLE COLUMNS COLUMNWIDTHS COMPRESS
+syn keyword pilrcType COMPRESSBEST COMPRESSPACKBITS COMPRESSRLE COMPRESSSCANLINE
+syn keyword pilrcType CONFIRMATION COUNTRY CREATOR CURRENCYDECIMALPLACES
+syn keyword pilrcType CURRENCYNAME CURRENCYSYMBOL CURRENCYUNIQUESYMBOL
+syn keyword pilrcType DATEFORMAT DAYLIGHTSAVINGS DEFAULTBTNID DEFAULTBUTTON
+syn keyword pilrcType DENSITY DISABLED DYNAMICSIZE
+syn keyword pilrcType EDITABLE ENTRY ERROR EXTENDED
+syn keyword pilrcType FEEDBACK FILE FONTID FORCECOMPRESS FRAME
+syn keyword pilrcType GRAFFITI GRAPHICAL GROUP
+syn keyword pilrcType HASSCROLLBAR HELPID
+syn keyword pilrcType ID INDEX INFORMATION
+syn keyword pilrcType KEYDOWNCHR KEYDOWNKEYCODE KEYDOWNMODIFIERS
+syn keyword pilrcType LANGUAGE LEFTALIGN LEFTANCHOR LONGDATEFORMAT
+syn keyword pilrcType MAX MAXCHARS MEASUREMENTSYSTEM MENUID MIN LOCALE
+syn keyword pilrcType MINUTESWESTOFGMT MODAL MULTIPLELINES
+syn keyword pilrcType NAME NOCOLORTABLE NOCOMPRESS NOFRAME NONEDITABLE
+syn keyword pilrcType NONEXTENDED NONUSABLE NOSAVEBEHIND NUMBER NUMBERFORMAT
+syn keyword pilrcType NUMERIC
+syn keyword pilrcType PAGESIZE
+syn keyword pilrcType RECTFRAME RIGHTALIGN RIGHTANCHOR ROWS
+syn keyword pilrcType SAVEBEHIND SEARCH SCREEN SELECTEDBITMAPID SINGLELINE
+syn keyword pilrcType THUMBID TRANSPARENTINDEX TIMEFORMAT
+syn keyword pilrcType UNDERLINED USABLE
+syn keyword pilrcType VALUE VERTICAL VISIBLEITEMS
+syn keyword pilrcType WARNING WEEKSTARTDAY
+
+" Country
+syn keyword pilrcCountry Australia Austria Belgium Brazil Canada Denmark
+syn keyword pilrcCountry Finland France Germany HongKong Iceland Indian
+syn keyword pilrcCountry Indonesia Ireland Italy Japan Korea Luxembourg Malaysia
+syn keyword pilrcCountry Mexico Netherlands NewZealand Norway Philippines
+syn keyword pilrcCountry RepChina Singapore Spain Sweden Switzerland Thailand
+syn keyword pilrcCountry Taiwan UnitedKingdom UnitedStates
+
+" Language
+syn keyword pilrcLanguage English French German Italian Japanese Spanish
+
+" String
+syn match pilrcString "\"[^"]*\""
+
+" Number
+syn match pilrcNumber "\<0x\x\+\>"
+syn match pilrcNumber "\<\d\+\>"
+
+" Comment
+syn region pilrcComment start="/\*" end="\*/"
+syn region pilrcComment start="//" end="$"
+
+" Constants
+syn keyword pilrcConstant AUTO AUTOID BOTTOM CENTER PREVBOTTOM PREVHEIGHT
+syn keyword pilrcConstant PREVLEFT PREVRIGHT PREVTOP PREVWIDTH RIGHT
+syn keyword pilrcConstant SEPARATOR
+
+" Identifier
+syn match pilrcIdentifier "\<\h\w*\>"
+
+" Specials
+syn match pilrcType "\<FONT\>"
+syn match pilrcKeyword "\<FONT\>\s*\<ID\>"
+syn match pilrcType "\<TRANSPARENT\>"
+
+" Function
+syn keyword pilrcFunction BEGIN END
+
+" Include
+syn match pilrcInclude "\#include"
+syn match pilrcInclude "\#define"
+syn keyword pilrcInclude equ
+syn keyword pilrcInclude package
+syn region pilrcInclude start="public class" end="}"
+
+syn sync ccomment pilrcComment
+
+if version >= 508 || !exists("did_pilrc_syntax_inits")
+	if version < 508
+		command -nargs=+ HiLink hi link <args>
+	else
+		command -nargs=+ HiLink hi def link <args>
+	endif
+
+	let did_pilrc_syntax_inits = 1
+
+	" The default methods for highlighting
+	HiLink pilrcKeyword		Statement
+	HiLink pilrcType		Type
+	HiLink pilrcError		Error
+	HiLink pilrcCountry		SpecialChar
+	HiLink pilrcLanguage		SpecialChar
+	HiLink pilrcString		SpecialChar
+	HiLink pilrcNumber		Number
+	HiLink pilrcComment		Comment
+	HiLink pilrcConstant		Constant
+	HiLink pilrcFunction		Function
+	HiLink pilrcInclude		SpecialChar
+	HiLink pilrcIdentifier		Number
+
+	delcommand HiLink
+endif
+
+let b:current_syntax = "pilrc"
--- /dev/null
+++ b/lib/vimfiles/syntax/pine.vim
@@ -1,0 +1,372 @@
+" Vim syntax file
+" Language:	Pine (email program) run commands
+" Maintainer:	David Pascoe <pascoedj@spamcop.net>
+" Last Change:	Thu Feb 27 10:18:48 WST 2003, update for pine 4.53
+
+" For version 5.x: Clear all syntax items
+" For version 6.x: Quit when a syntax file was already loaded
+if version < 600
+  syntax clear
+elseif exists("b:current_syntax")
+  finish
+endif
+
+if version >= 600
+  setlocal iskeyword=@,48-57,_,128-167,224-235,-,
+else
+  set iskeyword=@,48-57,_,128-167,224-235,-,
+endif
+
+syn keyword pineConfig addrbook-sort-rule
+syn keyword pineConfig address-book
+syn keyword pineConfig addressbook-formats
+syn keyword pineConfig alt-addresses
+syn keyword pineConfig bugs-additional-data
+syn keyword pineConfig bugs-address
+syn keyword pineConfig bugs-fullname
+syn keyword pineConfig character-set
+syn keyword pineConfig color-style
+syn keyword pineConfig compose-mime
+syn keyword pineConfig composer-wrap-column
+syn keyword pineConfig current-indexline-style
+syn keyword pineConfig cursor-style
+syn keyword pineConfig customized-hdrs
+syn keyword pineConfig debug-memory
+syn keyword pineConfig default-composer-hdrs
+syn keyword pineConfig default-fcc
+syn keyword pineConfig default-saved-msg-folder
+syn keyword pineConfig disable-these-authenticators
+syn keyword pineConfig disable-these-drivers
+syn keyword pineConfig display-filters
+syn keyword pineConfig download-command
+syn keyword pineConfig download-command-prefix
+syn keyword pineConfig editor
+syn keyword pineConfig elm-style-save
+syn keyword pineConfig empty-header-message
+syn keyword pineConfig fcc-name-rule
+syn keyword pineConfig feature-level
+syn keyword pineConfig feature-list
+syn keyword pineConfig file-directory
+syn keyword pineConfig folder-collections
+syn keyword pineConfig folder-extension
+syn keyword pineConfig folder-sort-rule
+syn keyword pineConfig font-char-set
+syn keyword pineConfig font-name
+syn keyword pineConfig font-size
+syn keyword pineConfig font-style
+syn keyword pineConfig forced-abook-entry
+syn keyword pineConfig form-letter-folder
+syn keyword pineConfig global-address-book
+syn keyword pineConfig goto-default-rule
+syn keyword pineConfig header-in-reply
+syn keyword pineConfig image-viewer
+syn keyword pineConfig inbox-path
+syn keyword pineConfig incoming-archive-folders
+syn keyword pineConfig incoming-folders
+syn keyword pineConfig incoming-startup-rule
+syn keyword pineConfig index-answered-background-color
+syn keyword pineConfig index-answered-foreground-color
+syn keyword pineConfig index-deleted-background-color
+syn keyword pineConfig index-deleted-foreground-color
+syn keyword pineConfig index-format
+syn keyword pineConfig index-important-background-color
+syn keyword pineConfig index-important-foreground-color
+syn keyword pineConfig index-new-background-color
+syn keyword pineConfig index-new-foreground-color
+syn keyword pineConfig index-recent-background-color
+syn keyword pineConfig index-recent-foreground-color
+syn keyword pineConfig index-to-me-background-color
+syn keyword pineConfig index-to-me-foreground-color
+syn keyword pineConfig index-unseen-background-color
+syn keyword pineConfig index-unseen-foreground-color
+syn keyword pineConfig initial-keystroke-list
+syn keyword pineConfig kblock-passwd-count
+syn keyword pineConfig keylabel-background-color
+syn keyword pineConfig keylabel-foreground-color
+syn keyword pineConfig keyname-background-color
+syn keyword pineConfig keyname-foreground-color
+syn keyword pineConfig last-time-prune-questioned
+syn keyword pineConfig last-version-used
+syn keyword pineConfig ldap-servers
+syn keyword pineConfig literal-signature
+syn keyword pineConfig local-address
+syn keyword pineConfig local-fullname
+syn keyword pineConfig mail-check-interval
+syn keyword pineConfig mail-directory
+syn keyword pineConfig mailcap-search-path
+syn keyword pineConfig mimetype-search-path
+syn keyword pineConfig new-version-threshold
+syn keyword pineConfig news-active-file-path
+syn keyword pineConfig news-collections
+syn keyword pineConfig news-spool-directory
+syn keyword pineConfig newsrc-path
+syn keyword pineConfig nntp-server
+syn keyword pineConfig normal-background-color
+syn keyword pineConfig normal-foreground-color
+syn keyword pineConfig old-style-reply
+syn keyword pineConfig operating-dir
+syn keyword pineConfig patterns
+syn keyword pineConfig patterns-filters
+syn keyword pineConfig patterns-filters2
+syn keyword pineConfig patterns-indexcolors
+syn keyword pineConfig patterns-other
+syn keyword pineConfig patterns-roles
+syn keyword pineConfig patterns-scores
+syn keyword pineConfig patterns-scores2
+syn keyword pineConfig personal-name
+syn keyword pineConfig personal-print-category
+syn keyword pineConfig personal-print-command
+syn keyword pineConfig postponed-folder
+syn keyword pineConfig print-font-char-set
+syn keyword pineConfig print-font-name
+syn keyword pineConfig print-font-size
+syn keyword pineConfig print-font-style
+syn keyword pineConfig printer
+syn keyword pineConfig prompt-background-color
+syn keyword pineConfig prompt-foreground-color
+syn keyword pineConfig pruned-folders
+syn keyword pineConfig pruning-rule
+syn keyword pineConfig quote1-background-color
+syn keyword pineConfig quote1-foreground-color
+syn keyword pineConfig quote2-background-color
+syn keyword pineConfig quote2-foreground-color
+syn keyword pineConfig quote3-background-color
+syn keyword pineConfig quote3-foreground-color
+syn keyword pineConfig read-message-folder
+syn keyword pineConfig remote-abook-history
+syn keyword pineConfig remote-abook-metafile
+syn keyword pineConfig remote-abook-validity
+syn keyword pineConfig reply-indent-string
+syn keyword pineConfig reply-leadin
+syn keyword pineConfig reverse-background-color
+syn keyword pineConfig reverse-foreground-color
+syn keyword pineConfig rsh-command
+syn keyword pineConfig rsh-open-timeout
+syn keyword pineConfig rsh-path
+syn keyword pineConfig save-by-sender
+syn keyword pineConfig saved-msg-name-rule
+syn keyword pineConfig scroll-margin
+syn keyword pineConfig selectable-item-background-color
+syn keyword pineConfig selectable-item-foreground-color
+syn keyword pineConfig sending-filters
+syn keyword pineConfig sendmail-path
+syn keyword pineConfig show-all-characters
+syn keyword pineConfig signature-file
+syn keyword pineConfig smtp-server
+syn keyword pineConfig sort-key
+syn keyword pineConfig speller
+syn keyword pineConfig ssh-command
+syn keyword pineConfig ssh-open-timeout
+syn keyword pineConfig ssh-path
+syn keyword pineConfig standard-printer
+syn keyword pineConfig status-background-color
+syn keyword pineConfig status-foreground-color
+syn keyword pineConfig status-message-delay
+syn keyword pineConfig suggest-address
+syn keyword pineConfig suggest-fullname
+syn keyword pineConfig tcp-open-timeout
+syn keyword pineConfig tcp-query-timeout
+syn keyword pineConfig tcp-read-warning-timeout
+syn keyword pineConfig tcp-write-warning-timeout
+syn keyword pineConfig threading-display-style
+syn keyword pineConfig threading-expanded-character
+syn keyword pineConfig threading-index-style
+syn keyword pineConfig threading-indicator-character
+syn keyword pineConfig threading-lastreply-character
+syn keyword pineConfig title-background-color
+syn keyword pineConfig title-foreground-color
+syn keyword pineConfig titlebar-color-style
+syn keyword pineConfig upload-command
+syn keyword pineConfig upload-command-prefix
+syn keyword pineConfig url-viewers
+syn keyword pineConfig use-only-domain-name
+syn keyword pineConfig user-domain
+syn keyword pineConfig user-id
+syn keyword pineConfig user-id
+syn keyword pineConfig user-input-timeout
+syn keyword pineConfig viewer-hdr-colors
+syn keyword pineConfig viewer-hdrs
+syn keyword pineConfig viewer-overlap
+syn keyword pineConfig window-position
+
+syn keyword pineOption allow-changing-from
+syn keyword pineOption allow-talk
+syn keyword pineOption alternate-compose-menu
+syn keyword pineOption assume-slow-link
+syn keyword pineOption auto-move-read-msgs
+syn keyword pineOption auto-open-next-unread
+syn keyword pineOption auto-unzoom-after-apply
+syn keyword pineOption auto-zoom-after-select
+syn keyword pineOption cache-remote-pinerc
+syn keyword pineOption check-newmail-when-quitting
+syn keyword pineOption combined-addrbook-display
+syn keyword pineOption combined-folder-display
+syn keyword pineOption combined-subdirectory-display
+syn keyword pineOption compose-cut-from-cursor
+syn keyword pineOption compose-maps-delete-key-to-ctrl-d
+syn keyword pineOption compose-rejects-unqualified-addrs
+syn keyword pineOption compose-send-offers-first-filter
+syn keyword pineOption compose-sets-newsgroup-without-confirm
+syn keyword pineOption confirm-role-even-for-default
+syn keyword pineOption continue-tab-without-confirm
+syn keyword pineOption delete-skips-deleted
+syn keyword pineOption disable-2022-jp-conversions
+syn keyword pineOption disable-busy-alarm
+syn keyword pineOption disable-charset-conversions
+syn keyword pineOption disable-config-cmd
+syn keyword pineOption disable-keyboard-lock-cmd
+syn keyword pineOption disable-keymenu
+syn keyword pineOption disable-password-caching
+syn keyword pineOption disable-password-cmd
+syn keyword pineOption disable-pipes-in-sigs
+syn keyword pineOption disable-pipes-in-templates
+syn keyword pineOption disable-roles-setup-cmd
+syn keyword pineOption disable-roles-sig-edit
+syn keyword pineOption disable-roles-template-edit
+syn keyword pineOption disable-sender
+syn keyword pineOption disable-shared-namespaces
+syn keyword pineOption disable-signature-edit-cmd
+syn keyword pineOption disable-take-last-comma-first
+syn keyword pineOption enable-8bit-esmtp-negotiation
+syn keyword pineOption enable-8bit-nntp-posting
+syn keyword pineOption enable-aggregate-command-set
+syn keyword pineOption enable-alternate-editor-cmd
+syn keyword pineOption enable-alternate-editor-implicitly
+syn keyword pineOption enable-arrow-navigation
+syn keyword pineOption enable-arrow-navigation-relaxed
+syn keyword pineOption enable-background-sending
+syn keyword pineOption enable-bounce-cmd
+syn keyword pineOption enable-cruise-mode
+syn keyword pineOption enable-cruise-mode-delete
+syn keyword pineOption enable-delivery-status-notification
+syn keyword pineOption enable-dot-files
+syn keyword pineOption enable-dot-folders
+syn keyword pineOption enable-exit-via-lessthan-command
+syn keyword pineOption enable-fast-recent-test
+syn keyword pineOption enable-flag-cmd
+syn keyword pineOption enable-flag-screen-implicitly
+syn keyword pineOption enable-full-header-and-text
+syn keyword pineOption enable-full-header-cmd
+syn keyword pineOption enable-goto-in-file-browser
+syn keyword pineOption enable-incoming-folders
+syn keyword pineOption enable-jump-shortcut
+syn keyword pineOption enable-lame-list-mode
+syn keyword pineOption enable-mail-check-cue
+syn keyword pineOption enable-mailcap-param-substitution
+syn keyword pineOption enable-mouse-in-xterm
+syn keyword pineOption enable-msg-view-addresses
+syn keyword pineOption enable-msg-view-attachments
+syn keyword pineOption enable-msg-view-forced-arrows
+syn keyword pineOption enable-msg-view-urls
+syn keyword pineOption enable-msg-view-web-hostnames
+syn keyword pineOption enable-newmail-in-xterm-icon
+syn keyword pineOption enable-partial-match-lists
+syn keyword pineOption enable-print-via-y-command
+syn keyword pineOption enable-reply-indent-string-editing
+syn keyword pineOption enable-rules-under-take
+syn keyword pineOption enable-search-and-replace
+syn keyword pineOption enable-sigdashes
+syn keyword pineOption enable-suspend
+syn keyword pineOption enable-tab-completion
+syn keyword pineOption enable-take-export
+syn keyword pineOption enable-tray-icon
+syn keyword pineOption enable-unix-pipe-cmd
+syn keyword pineOption enable-verbose-smtp-posting
+syn keyword pineOption expanded-view-of-addressbooks
+syn keyword pineOption expanded-view-of-distribution-lists
+syn keyword pineOption expanded-view-of-folders
+syn keyword pineOption expose-hidden-config
+syn keyword pineOption expunge-only-manually
+syn keyword pineOption expunge-without-confirm
+syn keyword pineOption expunge-without-confirm-everywhere
+syn keyword pineOption fcc-on-bounce
+syn keyword pineOption fcc-only-without-confirm
+syn keyword pineOption fcc-without-attachments
+syn keyword pineOption include-attachments-in-reply
+syn keyword pineOption include-header-in-reply
+syn keyword pineOption include-text-in-reply
+syn keyword pineOption ldap-result-to-addrbook-add
+syn keyword pineOption mark-fcc-seen
+syn keyword pineOption mark-for-cc
+syn keyword pineOption news-approximates-new-status
+syn keyword pineOption news-deletes-across-groups
+syn keyword pineOption news-offers-catchup-on-close
+syn keyword pineOption news-post-without-validation
+syn keyword pineOption news-read-in-newsrc-order
+syn keyword pineOption next-thread-without-confirm
+syn keyword pineOption old-growth
+syn keyword pineOption pass-control-characters-as-is
+syn keyword pineOption prefer-plain-text
+syn keyword pineOption preserve-start-stop-characters
+syn keyword pineOption print-formfeed-between-messages
+syn keyword pineOption print-includes-from-line
+syn keyword pineOption print-index-enabled
+syn keyword pineOption print-offers-custom-cmd-prompt
+syn keyword pineOption quell-attachment-extra-prompt
+syn keyword pineOption quell-berkeley-format-timezone
+syn keyword pineOption quell-content-id
+syn keyword pineOption quell-dead-letter-on-cancel
+syn keyword pineOption quell-empty-directories
+syn keyword pineOption quell-extra-post-prompt
+syn keyword pineOption quell-folder-internal-msg
+syn keyword pineOption quell-imap-envelope-update
+syn keyword pineOption quell-lock-failure-warnings
+syn keyword pineOption quell-maildomain-warning
+syn keyword pineOption quell-news-envelope-update
+syn keyword pineOption quell-partial-fetching
+syn keyword pineOption quell-ssl-largeblocks
+syn keyword pineOption quell-status-message-beeping
+syn keyword pineOption quell-timezone-comment-when-sending
+syn keyword pineOption quell-user-lookup-in-passwd-file
+syn keyword pineOption quit-without-confirm
+syn keyword pineOption reply-always-uses-reply-to
+syn keyword pineOption save-aggregates-copy-sequence
+syn keyword pineOption save-will-advance
+syn keyword pineOption save-will-not-delete
+syn keyword pineOption save-will-quote-leading-froms
+syn keyword pineOption scramble-message-id
+syn keyword pineOption select-without-confirm
+syn keyword pineOption selectable-item-nobold
+syn keyword pineOption separate-folder-and-directory-entries
+syn keyword pineOption show-cursor
+syn keyword pineOption show-plain-text-internally
+syn keyword pineOption show-selected-in-boldface
+syn keyword pineOption signature-at-bottom
+syn keyword pineOption single-column-folder-list
+syn keyword pineOption slash-collapses-entire-thread
+syn keyword pineOption spell-check-before-sending
+syn keyword pineOption store-window-position-in-config
+syn keyword pineOption strip-from-sigdashes-on-reply
+syn keyword pineOption tab-visits-next-new-message-only
+syn keyword pineOption termdef-takes-precedence
+syn keyword pineOption thread-index-shows-important-color
+syn keyword pineOption try-alternative-authentication-driver-first
+syn keyword pineOption unselect-will-not-advance
+syn keyword pineOption use-current-dir
+syn keyword pineOption use-function-keys
+syn keyword pineOption use-sender-not-x-sender
+syn keyword pineOption use-subshell-for-suspend
+syn keyword pineOption vertical-folder-list
+
+syn match  pineComment  "^#.*$"
+
+" Define the default highlighting.
+" For version 5.7 and earlier: only when not done already
+" For version 5.8 and later: only when an item doesn't have highlighting yet
+if version >= 508 || !exists("did_pine_syn_inits")
+  if version < 508
+    let did_pine_syn_inits = 1
+    command -nargs=+ HiLink hi link <args>
+  else
+    command -nargs=+ HiLink hi def link <args>
+  endif
+
+  HiLink pineConfig	Type
+  HiLink pineComment	Comment
+  HiLink pineOption	Macro
+  delcommand HiLink
+endif
+
+let b:current_syntax = "pine"
+
+" vim: ts=8
--- /dev/null
+++ b/lib/vimfiles/syntax/pinfo.vim
@@ -1,0 +1,110 @@
+" Vim syntax file
+" Language:         pinfo(1) configuration file
+" Maintainer:       Nikolai Weibull <now@bitwi.se>
+" Latest Revision:  2006-04-19
+
+if exists("b:current_syntax")
+  finish
+endif
+
+let s:cpo_save = &cpo
+set cpo&vim
+
+setlocal iskeyword=@,48-57,_,-
+
+syn case ignore
+
+syn keyword pinfoTodo             contained FIXME TODO XXX NOTE
+
+syn region  pinfoComment          start='^#' end='$' contains=pinfoTodo,@Spell
+
+syn keyword pinfoOptions          MANUAL CUT-MAN-HEADERS CUT-EMPTY-MAN-LINES
+                                  \ RAW-FILENAME APROPOS
+                                  \ DONT-HANDLE-WITHOUT-TAG-TABLE HTTPVIEWER
+                                  \ FTPVIEWER MAILEDITOR PRINTUTILITY MANLINKS
+                                  \ INFOPATH MAN-OPTIONS STDERR-REDIRECTION
+                                  \ LONG-MANUAL-LINKS FILTER-0xB7
+                                  \ QUIT-CONFIRMATION QUIT-CONFIRM-DEFAULT
+                                  \ CLEAR-SCREEN-AT-EXIT CALL-READLINE-HISTORY
+                                  \ HIGHLIGHTREGEXP SAFE-USER SAFE-GROUP
+
+syn keyword pinfoColors           COL_NORMAL COL_TOPLINE COL_BOTTOMLINE
+                                  \ COL_MENU COL_MENUSELECTED COL_NOTE
+                                  \ COL_NOTESELECTED COL_URL COL_URLSELECTED
+                                  \ COL_INFOHIGHLIGHT COL_MANUALBOLD
+                                  \ COL_MANUALITALIC COL_SEARCHHIGHLIGHT
+
+syn keyword pinfoColorDefault     COLOR_DEFAULT
+syn keyword pinfoColorBold        BOLD
+syn keyword pinfoColorNoBold      NO_BOLD
+syn keyword pinfoColorBlink       BLINK
+syn keyword pinfoColorNoBlink     NO_BLINK
+syn keyword pinfoColorBlack       COLOR_BLACK
+syn keyword pinfoColorRed         COLOR_RED
+syn keyword pinfoColorGreen       COLOR_GREEN
+syn keyword pinfoColorYellow      COLOR_YELLOW
+syn keyword pinfoColorBlue        COLOR_BLUE
+syn keyword pinfoColorMagenta     COLOR_MAGENTA
+syn keyword pinfoColorCyan        COLOR_CYAN
+syn keyword pinfoColorWhite       COLOR_WHITE
+
+syn keyword pinfoKeys             KEY_TOTALSEARCH_1 KEY_TOTALSEARCH_2
+                                  \ KEY_SEARCH_1 KEY_SEARCH_2
+                                  \ KEY_SEARCH_AGAIN_1 KEY_SEARCH_AGAIN_2
+                                  \ KEY_GOTO_1 KEY_GOTO_2 KEY_PREVNODE_1
+                                  \ KEY_PREVNODE_2 KEY_NEXTNODE_1
+                                  \ KEY_NEXTNODE_2 KEY_UP_1 KEY_UP_2 KEY_END_1
+                                  \ KEY_END_2 KEY_PGDN_1 KEY_PGDN_2
+                                  \ KEY_PGDN_AUTO_1 KEY_PGDN_AUTO_2 KEY_HOME_1
+                                  \ KEY_HOME_2 KEY_PGUP_1 KEY_PGUP_2
+                                  \ KEY_PGUP_AUTO_1 KEY_PGUP_AUTO_2 KEY_DOWN_1
+                                  \ KEY_DOWN_2 KEY_TOP_1 KEY_TOP_2 KEY_BACK_1
+                                  \ KEY_BACK_2 KEY_FOLLOWLINK_1
+                                  \ KEY_FOLLOWLINK_2 KEY_REFRESH_1
+                                  \ KEY_REFRESH_2 KEY_SHELLFEED_1
+                                  \ KEY_SHELLFEED_2 KEY_QUIT_1 KEY_QUIT_2
+                                  \ KEY_GOLINE_1 KEY_GOLINE_2 KEY_PRINT_1
+                                  \ KEY_PRINT_2 KEY_DIRPAGE_1 KEY_DIRPAGE_2
+                                  \ KEY_TWODOWN_1 KEY_TWODOWN_2 KEY_TWOUP_1
+                                  \ KEY_TWOUP_2
+
+syn keyword pinfoSpecialKeys      KEY_BREAK KEY_DOWN KEY_UP KEY_LEFT KEY_RIGHT
+                                  \ KEY_DOWN KEY_HOME KEY_BACKSPACE KEY_NPAGE
+                                  \ KEY_PPAGE KEY_END KEY_IC KEY_DC
+syn region  pinfoSpecialKeys      matchgroup=pinfoSpecialKeys transparent
+                                  \ start=+KEY_\%(F\|CTRL\|ALT\)(+ end=+)+
+syn region  pinfoSimpleKey        start=+'+ skip=+\\'+ end=+'+
+                                  \ contains=pinfoSimpleKeyEscape
+syn match   pinfoSimpleKeyEscape  +\\[\\nt']+
+syn match   pinfoKeycode          '\<\d\+\>'
+
+syn keyword pinfoConstants        TRUE FALSE YES NO
+
+hi def link pinfoTodo             Todo
+hi def link pinfoComment          Comment
+hi def link pinfoOptions          Keyword
+hi def link pinfoColors           Keyword
+hi def link pinfoColorDefault     Normal
+hi def link pinfoSpecialKeys      SpecialChar
+hi def link pinfoSimpleKey        String
+hi def link pinfoSimpleKeyEscape  SpecialChar
+hi def link pinfoKeycode          Number
+hi def link pinfoConstants        Constant
+hi def link pinfoKeys             Keyword
+hi def      pinfoColorBold        cterm=bold
+hi def      pinfoColorNoBold      cterm=none
+hi def      pinfoColorBlink       cterm=inverse
+hi def      pinfoColorNoBlink     cterm=none
+hi def      pinfoColorBlack       ctermfg=Black       guifg=Black
+hi def      pinfoColorRed         ctermfg=DarkRed     guifg=DarkRed
+hi def      pinfoColorGreen       ctermfg=DarkGreen   guifg=DarkGreen
+hi def      pinfoColorYellow      ctermfg=DarkYellow  guifg=DarkYellow
+hi def      pinfoColorBlue        ctermfg=DarkBlue    guifg=DarkBlue
+hi def      pinfoColorMagenta     ctermfg=DarkMagenta guifg=DarkMagenta
+hi def      pinfoColorCyan        ctermfg=DarkCyan    guifg=DarkCyan
+hi def      pinfoColorWhite       ctermfg=LightGray   guifg=LightGray
+
+let b:current_syntax = "pinfo"
+
+let &cpo = s:cpo_save
+unlet s:cpo_save
--- /dev/null
+++ b/lib/vimfiles/syntax/plaintex.vim
@@ -1,0 +1,170 @@
+" Vim syntax file
+" Language:         TeX (plain.tex format)
+" Maintainer:       Nikolai Weibull <now@bitwi.se>
+" Latest Revision:  2006-10-26
+
+if exists("b:current_syntax")
+  finish
+endif
+
+let s:cpo_save = &cpo
+set cpo&vim
+
+syn match   plaintexControlSequence         display contains=@NoSpell
+      \ '\\[a-zA-Z@]\+'
+
+runtime! syntax/initex.vim
+unlet b:current_syntax
+
+syn match   plaintexComment                 display
+      \ contains=ALLBUT,initexComment,plaintexComment
+      \ '^\s*%[CDM].*$'
+
+if exists("g:plaintex_delimiters")
+  syn match   plaintexDelimiter             display '[][{}]'
+endif
+
+syn match   plaintexRepeat                  display contains=@NoSpell
+      \ '\\\%(loop\|repeat\)\>'
+
+syn match   plaintexCommand                 display contains=@NoSpell
+      \ '\\\%(plainoutput\|TeX\)\>'
+syn match   plaintexBoxCommand              display contains=@NoSpell
+      \ '\\\%(null\|strut\)\>'
+syn match   plaintexDebuggingCommand        display contains=@NoSpell
+      \ '\\\%(showhyphens\|tracingall\|wlog\)\>'
+syn match   plaintexFontsCommand            display contains=@NoSpell
+      \ '\\\%(bf\|\%(five\|seven\)\%(bf\|i\|rm\|sy\)\|it\|oldstyle\|rm\|sl\|ten\%(bf\|ex\|it\=\|rm\|sl\|sy\|tt\)\|tt\)\>'
+syn match   plaintexGlueCommand             display contains=@NoSpell
+      \ '\\\%(\%(big\|en\|med\|\%(no\|off\)interline\|small\)skip\|\%(center\|left\|right\)\=line\|\%(dot\|\%(left\|right\)arrow\)fill\|[hv]glue\|[lr]lap\|q\=quad\|space\|topglue\)\>'
+syn match   plaintexInsertsCommand          display contains=@NoSpell
+      \ '\\\%(\%(end\|top\)insert\|v\=footnote\)\>'
+syn match   plaintexJobCommand              display contains=@NoSpell
+      \ '\\\%(bye\|fmt\%(name\|version\)\)\>'
+syn match   plaintexInsertsCommand          display contains=@NoSpell
+      \ '\\\%(mid\|page\)insert\>'
+syn match   plaintexKernCommand             display contains=@NoSpell
+      \ '\\\%(en\|\%(neg\)\=thin\)space\>'
+syn match   plaintexMacroCommand            display contains=@NoSpell
+      \ '\\\%(active\|[be]group\|empty\)\>'
+syn match   plaintexPageCommand             display contains=@NoSpell
+      \ '\\\%(\%(super\)\=eject\|nopagenumbers\|\%(normal\|ragged\)bottom\)\>'
+syn match   plaintexParagraphCommand        display contains=@NoSpell
+      \ '\\\%(endgraf\|\%(non\)\=frenchspacing\|hang\|item\%(item\)\=\|narrower\|normalbaselines\|obey\%(lines\|spaces\)\|openup\|proclaim\|\%(tt\)\=raggedright\|textindent\)\>'
+syn match   plaintexPenaltiesCommand        display contains=@NoSpell
+      \ '\\\%(allow\|big\|fil\|good\|med\|no\|small\)\=break\>'
+syn match   plaintexRegistersCommand        display contains=@NoSpell
+      \ '\\\%(advancepageno\|new\%(box\|count\|dimen\|fam\|help\|if\|insert\|language\|muskip\|read\|skip\|toks\|write\)\)\>'
+syn match   plaintexTablesCommand           display contains=@NoSpell
+      \ '&\|\\+\|\\\%(cleartabs\|endline\|hidewidth\|ialign\|multispan\|settabs\|tabalign\)\>'
+
+if !exists("g:plaintex_no_math")
+  syn region  plaintexMath                  matchgroup=plaintexMath
+      \ contains=@plaintexMath,@NoSpell
+      \ start='\$' skip='\\\\\|\\\$' end='\$'
+  syn region  plaintexMath                  matchgroup=plaintexMath
+      \ contains=@plaintexMath,@NoSpell keepend
+      \ start='\$\$' skip='\\\\\|\\\$' end='\$\$'
+endif
+
+" Keep this after plaintexMath, as we don’t want math mode started at a \$.
+syn match   plaintexCharacterCommand        display contains=@NoSpell
+      \ /\\\%(["#$%&'.=^_`~]\|``\|''\|-\{2,3}\|[?!]`\|^^L\|\~\|\%(a[ae]\|A[AE]\|acute\|[cdHoOPStuvijlL]\|copyright\|d\=dag\|folio\|ldotp\|[lr]q\|oe\|OE\|slash\|ss\|underbar\)\>\)/
+
+syn cluster plaintexMath
+      \ contains=plaintexMathCommand,plaintexMathBoxCommand,
+      \ plaintexMathCharacterCommand,plaintexMathDelimiter,
+      \ plaintexMathFontsCommand,plaintexMathLetter,plaintexMathSymbol,
+      \ plaintexMathFunction,plaintexMathOperator,plaintexMathPunctuation,
+      \ plaintexMathRelation
+
+syn match   plaintexMathCommand             display contains=@NoSpell contained
+      \ '\\\%([!*,;>{}|_^]\|\%([aA]rrowvert\|[bB]ig\%(g[lmr]\=\|r\)\=\|\%(border\|p\)\=matrix\|displaylines\|\%(down\|up\)bracefill\|eqalign\%(no\)\|leqalignno\|[lr]moustache\|mathpalette\|root\|s[bp]\|skew\|sqrt\)\>\)'
+syn match   plaintexMathBoxCommand          display contains=@NoSpell contained
+      \ '\\\%([hv]\=phantom\|mathstrut\|smash\)\>'
+syn match   plaintexMathCharacterCommand    display contains=@NoSpell contained
+      \ '\\\%(b\|bar\|breve\|check\|d\=dots\=\|grave\|hat\|[lv]dots\|tilde\|vec\|wide\%(hat\|tilde\)\)\>'
+syn match   plaintexMathDelimiter           display contains=@NoSpell contained
+      \ '\\\%(brace\%(vert\)\=\|brack\|cases\|choose\|[lr]\%(angle\|brace\|brack\|ceil\|floor\|group\)\|over\%(brace\|\%(left\|right\)arrow\)\|underbrace\)\>'
+syn match   plaintexMathFontsCommand        display contains=@NoSpell contained
+      \ '\\\%(\%(bf\|it\|sl\|tt\)fam\|cal\|mit\)\>'
+syn match   plaintexMathLetter              display contains=@NoSpell contained
+      \ '\\\%(aleph\|alpha\|beta\|chi\|[dD]elta\|ell\|epsilon\|eta\|[gG]amma\|[ij]math\|iota\|kappa\|[lL]ambda\|[mn]u\|[oO]mega\|[pP][hs]\=i\|rho\|[sS]igma\|tau\|[tT]heta\|[uU]psilon\|var\%(epsilon\|ph\=i\|rho\|sigma\|theta\)\|[xX]i\|zeta\)\>'
+syn match   plaintexMathSymbol              display contains=@NoSpell contained
+      \ '\\\%(angle\|backslash\|bot\|clubsuit\|emptyset\|epsilon\|exists\|flat\|forall\|hbar\|heartsuit\|Im\|infty\|int\|lnot\|nabla\|natural\|neg\|pmod\|prime\|Re\|sharp\|smallint\|spadesuit\|surd\|top\|triangle\%(left\|right\)\=\|vdash\|wp\)\>'
+syn match   plaintexMathFunction            display contains=@NoSpell contained
+      \ '\\\%(arc\%(cos\|sin\|tan\)\|arg\|\%(cos\|sin\|tan\)h\=\|coth\=\|csc\|de[gt]\|dim\|exp\|gcd\|hom\|inf\|ker\|lo\=g\|lim\%(inf\|sup\)\=\|ln\|max\|min\|Pr\|sec\|sup\)\>'
+syn match   plaintexMathOperator            display contains=@NoSpell contained
+      \ '\\\%(amalg\|ast\|big\%(c[au]p\|circ\|o\%(dot\|plus\|times\|sqcup\)\|triangle\%(down\|up\)\|uplus\|vee\|wedge\|bmod\|bullet\)\|c[au]p\|cdot[ps]\=\|circ\|coprod\|d\=dagger\|diamond\%(suit\)\=\|div\|land\|lor\|mp\|o\%(dot\|int\|minus\|plus\|slash\|times\)pm\|prod\|setminus\|sqc[au]p\|sqsu[bp]seteq\|star\|su[bp]set\%(eq\)\=\|sum\|times\|uplus\|vee\|wedge\|wr\)\>'
+syn match   plaintexMathPunctuation         display contains=@NoSpell contained
+      \ '\\\%(colon\)\>'
+syn match   plaintexMathRelation            display contains=@NoSpell contained
+      \ '\\\%(approx\|asymp\|bowtie\|buildrel\|cong\|dashv\|doteq\|[dD]ownarrow\|equiv\|frown\|geq\=\|gets\|gg\|hook\%(left\|right\)arrow\|iff\|in\|leq\=\|[lL]eftarrow\|\%(left\|right\)harpoon\%(down\|up\)\|[lL]eftrightarrow\|ll\|[lL]ongleftrightarrow\|longmapsto\|[lL]ongrightarrow\|mapsto\|mid\|models\|[ns][ew]arrow\|neq\=\|ni\|not\%(in\)\=\|owns\|parallel\|perp\|prec\%(eq\)\=\|propto\|[rR]ightarrow\|rightleftharpoons\|sim\%(eq\)\=\|smile\|succ\%(eq\)\=\|to\|[uU]parrow\|[uU]pdownarrow\|[vV]ert\)\>'
+
+syn match   plaintexParameterDimen          display contains=@NoSpell
+      \ '\\maxdimen\>'
+syn match   plaintexMathParameterDimen      display contains=@NoSpell
+      \ '\\jot\>'
+syn match   plaintexParagraphParameterGlue  display contains=@NoSpell
+      \ '\\\%(\%(big\|med\|small\)skipamount\|normalbaselineskip\|normallineskip\%(limit\)\=\)\>'
+
+syn match   plaintexFontParameterInteger    display contains=@NoSpell
+      \ '\\magstep\%(half\)\=\>'
+syn match   plaintexJobParameterInteger     display contains=@NoSpell
+      \ '\\magnification\>'
+syn match   plaintexPageParameterInteger    display contains=@NoSpell
+      \ '\\pageno\>'
+
+syn match   plaintexPageParameterToken      display contains=@NoSpell
+      \ '\\\%(foot\|head\)line\>'
+
+hi def link plaintexOperator                Operator
+
+hi def link plaintexDelimiter               Delimiter
+
+hi def link plaintexControlSequence         Identifier
+hi def link plaintexComment                 Comment
+hi def link plaintexInclude                 Include
+hi def link plaintexRepeat                  Repeat
+
+hi def link plaintexCommand                 initexCommand
+hi def link plaintexBoxCommand              plaintexCommand
+hi def link plaintexCharacterCommand        initexCharacterCommand
+hi def link plaintexDebuggingCommand        initexDebuggingCommand
+hi def link plaintexFontsCommand            initexFontsCommand
+hi def link plaintexGlueCommand             plaintexCommand
+hi def link plaintexInsertsCommand          plaintexCommand
+hi def link plaintexJobCommand              initexJobCommand
+hi def link plaintexKernCommand             plaintexCommand
+hi def link plaintexMacroCommand            initexMacroCommand
+hi def link plaintexPageCommand             plaintexCommand
+hi def link plaintexParagraphCommand        plaintexCommand
+hi def link plaintexPenaltiesCommand        plaintexCommand
+hi def link plaintexRegistersCommand        plaintexCommand
+hi def link plaintexTablesCommand           plaintexCommand
+
+hi def link plaintexMath                    String
+hi def link plaintexMathCommand             plaintexCommand
+hi def link plaintexMathBoxCommand          plaintexBoxCommand
+hi def link plaintexMathCharacterCommand    plaintexCharacterCommand
+hi def link plaintexMathDelimiter           plaintexDelimiter
+hi def link plaintexMathFontsCommand        plaintexFontsCommand
+hi def link plaintexMathLetter              plaintexMathCharacterCommand
+hi def link plaintexMathSymbol              plaintexMathLetter
+hi def link plaintexMathFunction            Function
+hi def link plaintexMathOperator            plaintexOperator
+hi def link plaintexMathPunctuation         plaintexCharacterCommand
+hi def link plaintexMathRelation            plaintexOperator
+
+hi def link plaintexParameterDimen          initexParameterDimen
+hi def link plaintexMathParameterDimen      initexMathParameterDimen
+hi def link plaintexParagraphParameterGlue  initexParagraphParameterGlue
+hi def link plaintexFontParameterInteger    initexFontParameterInteger
+hi def link plaintexJobParameterInteger     initexJobParameterInteger
+hi def link plaintexPageParameterInteger    initexPageParameterInteger
+hi def link plaintexPageParameterToken      initexParameterToken
+
+let b:current_syntax = "plaintex"
+
+let &cpo = s:cpo_save
+unlet s:cpo_save
--- /dev/null
+++ b/lib/vimfiles/syntax/plm.vim
@@ -1,0 +1,147 @@
+" Vim syntax file
+" Language:	PL/M
+" Maintainer:	Philippe Coulonges <cphil@cphil.net>
+" Last change:	2003 May 11
+
+" For version 5.x: Clear all syntax items
+" For version 6.x: Quit when a syntax file was already loaded
+if version < 600
+  syntax clear
+elseif exists("b:current_syntax")
+  finish
+endif
+
+" PL/M is a case insensitive language
+syn case ignore
+
+syn keyword plmTodo contained	TODO FIXME XXX
+
+" String
+syn region  plmString		start=+'+  end=+'+
+
+syn match   plmOperator		"[@=\+\-\*\/\<\>]"
+
+syn match   plmIdentifier	"\<[a-zA-Z_][a-zA-Z0-9_]*\>"
+
+syn match   plmDelimiter	"[();,]"
+
+syn region  plmPreProc		start="^\s*\$\s*" skip="\\$" end="$"
+
+" FIXME : No Number support for floats, as I'm working on an embedded
+" project that doesn't use any.
+syn match   plmNumber		"-\=\<\d\+\>"
+syn match   plmNumber		"\<[0-9a-fA-F]*[hH]*\>"
+
+" If you don't like tabs
+"syn match plmShowTab "\t"
+"syn match plmShowTabc "\t"
+
+"when wanted, highlight trailing white space
+if exists("c_space_errors")
+  syn match	plmSpaceError	"\s*$"
+  syn match	plmSpaceError	" \+\t"me=e-1
+endif
+
+"
+  " Use the same control variable as C language for I believe
+  " users will want the same behavior
+if exists("c_comment_strings")
+  " FIXME : don't work fine with c_comment_strings set,
+  "	    which I don't care as I don't use
+
+  " A comment can contain plmString, plmCharacter and plmNumber.
+  " But a "*/" inside a plmString in a plmComment DOES end the comment!  So we
+  " need to use a special type of plmString: plmCommentString, which also ends on
+  " "*/", and sees a "*" at the start of the line as comment again.
+  syntax match	plmCommentSkip	contained "^\s*\*\($\|\s\+\)"
+  syntax region plmCommentString	contained start=+"+ skip=+\\\\\|\\"+ end=+"+ end=+\*/+me=s-1 contains=plmSpecial,plmCommentSkip
+  syntax region plmComment2String	contained start=+"+ skip=+\\\\\|\\"+ end=+"+ end="$" contains=plmSpecial
+  syntax region plmComment	start="/\*" end="\*/" contains=plmTodo,plmCommentString,plmCharacter,plmNumber,plmFloat,plmSpaceError
+  syntax match  plmComment	"//.*" contains=plmTodo,plmComment2String,plmCharacter,plmNumber,plmSpaceError
+else
+  syn region	plmComment	start="/\*" end="\*/" contains=plmTodo,plmSpaceError
+  syn match	plmComment	"//.*" contains=plmTodo,plmSpaceError
+endif
+
+syntax match	plmCommentError	"\*/"
+
+syn keyword plmReserved	ADDRESS AND AT BASED BY BYTE CALL CASE
+syn keyword plmReserved DATA DECLARE DISABLE DO DWORD
+syn keyword plmReserved	ELSE ENABLE END EOF EXTERNAL
+syn keyword plmReserved GO GOTO HALT IF INITIAL INTEGER INTERRUPT
+syn keyword plmReserved LABEL LITERALLY MINUS MOD NOT OR
+syn keyword plmReserved PLUS POINTER PROCEDURE PUBLIC
+syn keyword plmReserved REAL REENTRANT RETURN SELECTOR STRUCTURE
+syn keyword plmReserved THEN TO WHILE WORD XOR
+syn keyword plm386Reserved CHARINT HWORD LONGINT OFFSET QWORD SHORTINT
+
+syn keyword plmBuiltIn ABS ADJUSTRPL BLOCKINPUT BLOCKINWORD BLOCKOUTPUT
+syn keyword plmBuiltIn BLOCKOUTWORD BUILPTR CARRY CAUSEINTERRUPT CMPB
+syn keyword plmBuiltIn CMPW DEC DOUBLE FINDB FINDRB FINDRW FINDW FIX
+syn keyword plmBuiltIn FLAGS FLOAT GETREALERROR HIGH IABS INITREALMATHUNIT
+syn keyword plmBuiltIn INPUT INT INWORD LAST LOCKSET LENGTH LOW MOVB MOVE
+syn keyword plmBuiltIn MOVRB MOVRW MOVW NIL OUTPUT OUTWORD RESTOREREALSTATUS
+syn keyword plmBuiltIn ROL ROR SAL SAVEREALSTATUS SCL SCR SELECTOROF SETB
+syn keyword plmBuiltIn SETREALMODE SETW SHL SHR SIGN SIGNED SIZE SKIPB
+syn keyword plmBuiltIn SKIPRB SKIPRW SKIPW STACKBASE STACKPTR TIME SIZE
+syn keyword plmBuiltIn UNSIGN XLAT ZERO
+syn keyword plm386BuiltIn INTERRUPT SETINTERRUPT
+syn keyword plm286BuiltIn CLEARTASKSWITCHEDFLAG GETACCESSRIGHTS
+syn keyword plm286BuiltIn GETSEGMENTLIMIT LOCALTABLE MACHINESTATUS
+syn keyword plm286BuiltIn OFFSETOF PARITY RESTOREGLOBALTABLE
+syn keyword plm286BuiltIn RESTOREINTERRUPTTABLE SAVEGLOBALTABLE
+syn keyword plm286BuiltIn SAVEINTERRUPTTABLE SEGMENTREADABLE
+syn keyword plm286BuiltIn SEGMENTWRITABLE TASKREGISTER WAITFORINTERRUPT
+syn keyword plm386BuiltIn CONTROLREGISTER DEBUGREGISTER FINDHW
+syn keyword plm386BuiltIn FINDRHW INHWORD MOVBIT MOVRBIT MOVHW MOVRHW
+syn keyword plm386BuiltIn OUTHWORD SCANBIT SCANRBIT SETHW SHLD SHRD
+syn keyword plm386BuiltIn SKIPHW SKIPRHW TESTREGISTER
+syn keyword plm386w16BuiltIn BLOCKINDWORD BLOCKOUTDWORD CMPD FINDD
+syn keyword plm386w16BuiltIn FINDRD INDWORD MOVD MOVRD OUTDWORD
+syn keyword plm386w16BuiltIn SETD SKIPD SKIPRD
+
+syn sync lines=50
+
+" Define the default highlighting.
+" For version 5.7 and earlier: only when not done already
+" For version 5.8 and later: only when an item doesn't have highlighting yet
+if version >= 508 || !exists("did_plm_syntax_inits")
+  if version < 508
+    let did_plm_syntax_inits = 1
+    command -nargs=+ HiLink hi link <args>
+  else
+    command -nargs=+ HiLink hi def link <args>
+  endif
+
+ " The default methods for highlighting.  Can be overridden later
+"  HiLink plmLabel			Label
+"  HiLink plmConditional		Conditional
+"  HiLink plmRepeat			Repeat
+  HiLink plmTodo			Todo
+  HiLink plmNumber			Number
+  HiLink plmOperator			Operator
+  HiLink plmDelimiter			Operator
+  "HiLink plmShowTab			Error
+  "HiLink plmShowTabc			Error
+  HiLink plmIdentifier			Identifier
+  HiLink plmBuiltIn			Statement
+  HiLink plm286BuiltIn			Statement
+  HiLink plm386BuiltIn			Statement
+  HiLink plm386w16BuiltIn		Statement
+  HiLink plmReserved			Statement
+  HiLink plm386Reserved			Statement
+  HiLink plmPreProc			PreProc
+  HiLink plmCommentError		plmError
+  HiLink plmCommentString		plmString
+  HiLink plmComment2String		plmString
+  HiLink plmCommentSkip			plmComment
+  HiLink plmString			String
+  HiLink plmComment			Comment
+
+  delcommand HiLink
+endif
+
+let b:current_syntax = "plm"
+
+" vim: ts=8 sw=2
+
--- /dev/null
+++ b/lib/vimfiles/syntax/plp.vim
@@ -1,0 +1,45 @@
+" Vim syntax file
+" Language:	PLP (Perl in HTML)
+" Maintainer:	Juerd <juerd@juerd.nl>
+" Last Change:	2003 Apr 25
+" Cloned From:	aspperl.vim
+
+" Add to filetype.vim the following line (without quote sign):
+" au BufNewFile,BufRead *.plp setf plp
+
+" For version 5.x: Clear all syntax items
+" For version 6.x: Quit when a syntax file was already loaded
+if version < 600
+  syntax clear
+elseif exists("b:current_syntax")
+  finish
+endif
+
+if !exists("main_syntax")
+  let main_syntax = 'perlscript'
+endif
+
+if version < 600
+  so <sfile>:p:h/html.vim
+  syn include @PLPperl <sfile>:p:h/perl.vim
+else
+  runtime! syntax/html.vim
+  unlet b:current_syntax
+  syn include @PLPperl syntax/perl.vim
+endif
+
+syn cluster htmlPreproc add=PLPperlblock
+
+syn keyword perlControl PLP_END
+syn keyword perlStatementInclude include Include
+syn keyword perlStatementFiles ReadFile WriteFile Counter
+syn keyword perlStatementScalar Entity AutoURL DecodeURI EncodeURI
+
+syn cluster PLPperlcode contains=perlStatement.*,perlFunction,perlOperator,perlVarPlain,perlVarNotInMatches,perlShellCommand,perlFloat,perlNumber,perlStringUnexpanded,perlString,perlQQ,perlControl,perlConditional,perlRepeat,perlComment,perlPOD,perlHereDoc,perlPackageDecl,perlElseIfError,perlFiledescRead,perlMatch
+
+syn region  PLPperlblock keepend matchgroup=Delimiter start=+<:=\=+ end=+:>+ transparent contains=@PLPperlcode
+
+syn region  PLPinclude keepend matchgroup=Delimiter start=+<(+ end=+)>+
+
+let b:current_syntax = "plp"
+
--- /dev/null
+++ b/lib/vimfiles/syntax/plsql.vim
@@ -1,0 +1,277 @@
+" Vim syntax file
+" Language: Oracle Procedureal SQL (PL/SQL)
+" Maintainer: Jeff Lanzarotta (jefflanzarotta at yahoo dot com)
+" Original Maintainer: C. Laurence Gonsalves (clgonsal@kami.com)
+" URL: http://lanzarotta.tripod.com/vim/syntax/plsql.vim.zip
+" Last Change: September 18, 2002
+" History: Geoff Evans & Bill Pribyl (bill at plnet dot org)
+"		Added 9i keywords.
+"	   Austin Ziegler (austin at halostatue dot ca)
+"		Added 8i+ features.
+"
+" For version 5.x, clear all syntax items.
+" For version 6.x, quit when a syntax file was already loaded.
+if version < 600
+  syntax clear
+elseif exists("b:current_syntax")
+  finish
+endif
+
+" Todo.
+syn keyword plsqlTodo TODO FIXME XXX DEBUG NOTE
+syn cluster plsqlCommentGroup contains=plsqlTodo
+
+syn case ignore
+
+syn match   plsqlGarbage "[^ \t()]"
+syn match   plsqlIdentifier "[a-z][a-z0-9$_#]*"
+syn match   plsqlHostIdentifier ":[a-z][a-z0-9$_#]*"
+
+" When wanted, highlight the trailing whitespace.
+if exists("c_space_errors")
+  if !exists("c_no_trail_space_error")
+    syn match plsqlSpaceError "\s\+$"
+  endif
+
+  if !exists("c_no_tab_space_error")
+    syn match plsqlSpaceError " \+\t"me=e-1
+  endif
+endif
+
+" Symbols.
+syn match   plsqlSymbol "\(;\|,\|\.\)"
+
+" Operators.
+syn match   plsqlOperator "\(+\|-\|\*\|/\|=\|<\|>\|@\|\*\*\|!=\|\~=\)"
+syn match   plsqlOperator "\(^=\|<=\|>=\|:=\|=>\|\.\.\|||\|<<\|>>\|\"\)"
+
+" Some of Oracle's SQL keywords.
+syn keyword plsqlSQLKeyword ABORT ACCESS ACCESSED ADD AFTER ALL ALTER AND ANY
+syn keyword plsqlSQLKeyword AS ASC ATTRIBUTE AUDIT AUTHORIZATION AVG BASE_TABLE
+syn keyword plsqlSQLKeyword BEFORE BETWEEN BY CASCADE CAST CHECK CLUSTER
+syn keyword plsqlSQLKeyword CLUSTERS COLAUTH COLUMN COMMENT COMPRESS CONNECT
+syn keyword plsqlSQLKeyword CONSTRAINT CRASH CREATE CURRENT DATA DATABASE
+syn keyword plsqlSQLKeyword DATA_BASE DBA DEFAULT DELAY DELETE DESC DISTINCT
+syn keyword plsqlSQLKeyword DROP DUAL ELSE EXCLUSIVE EXISTS EXTENDS EXTRACT
+syn keyword plsqlSQLKeyword FILE FORCE FOREIGN FROM GRANT GROUP HAVING HEAP
+syn keyword plsqlSQLKeyword IDENTIFIED IDENTIFIER IMMEDIATE IN INCLUDING
+syn keyword plsqlSQLKeyword INCREMENT INDEX INDEXES INITIAL INSERT INSTEAD
+syn keyword plsqlSQLKeyword INTERSECT INTO INVALIDATE IS ISOLATION KEY LIBRARY
+syn keyword plsqlSQLKeyword LIKE LOCK MAXEXTENTS MINUS MODE MODIFY MULTISET
+syn keyword plsqlSQLKeyword NESTED NOAUDIT NOCOMPRESS NOT NOWAIT OF OFF OFFLINE
+syn keyword plsqlSQLKeyword ON ONLINE OPERATOR OPTION OR ORDER ORGANIZATION
+syn keyword plsqlSQLKeyword PCTFREE PRIMARY PRIOR PRIVATE PRIVILEGES PUBLIC
+syn keyword plsqlSQLKeyword QUOTA RELEASE RENAME REPLACE RESOURCE REVOKE ROLLBACK
+syn keyword plsqlSQLKeyword ROW ROWLABEL ROWS SCHEMA SELECT SEPARATE SESSION SET
+syn keyword plsqlSQLKeyword SHARE SIZE SPACE START STORE SUCCESSFUL SYNONYM
+syn keyword plsqlSQLKeyword SYSDATE TABLE TABLES TABLESPACE TEMPORARY TO TREAT
+syn keyword plsqlSQLKeyword TRIGGER TRUNCATE UID UNION UNIQUE UNLIMITED UPDATE
+syn keyword plsqlSQLKeyword USE USER VALIDATE VALUES VIEW WHENEVER WHERE WITH
+
+" PL/SQL's own keywords.
+syn keyword plsqlKeyword AGENT AND ANY ARRAY ASSIGN AS AT AUTHID BEGIN BODY BY
+syn keyword plsqlKeyword BULK C CASE CHAR_BASE CHARSETFORM CHARSETID CLOSE
+syn keyword plsqlKeyword COLLECT CONSTANT CONSTRUCTOR CONTEXT CURRVAL DECLARE
+syn keyword plsqlKeyword DVOID EXCEPTION EXCEPTION_INIT EXECUTE EXIT FETCH
+syn keyword plsqlKeyword FINAL FUNCTION GOTO HASH IMMEDIATE IN INDICATOR
+syn keyword plsqlKeyword INSTANTIABLE IS JAVA LANGUAGE LIBRARY MAP MAXLEN
+syn keyword plsqlKeyword MEMBER NAME NEW NOCOPY NUMBER_BASE OBJECT OCICOLL
+syn keyword plsqlKeyword OCIDATE OCIDATETIME OCILOBLOCATOR OCINUMBER OCIRAW
+syn keyword plsqlKeyword OCISTRING OF OPAQUE OPEN OR ORDER OTHERS OUT
+syn keyword plsqlKeyword OVERRIDING PACKAGE PARALLEL_ENABLE PARAMETERS
+syn keyword plsqlKeyword PARTITION PIPELINED PRAGMA PROCEDURE RAISE RANGE REF
+syn keyword plsqlKeyword RESULT RETURN REVERSE ROWTYPE SB1 SELF SHORT SIZE_T
+syn keyword plsqlKeyword SQL SQLCODE SQLERRM STATIC STRUCT SUBTYPE TDO THEN
+syn keyword plsqlKeyword TABLE TIMEZONE_ABBR TIMEZONE_HOUR TIMEZONE_MINUTE
+syn keyword plsqlKeyword TIMEZONE_REGION TYPE UNDER UNSIGNED USING VARIANCE
+syn keyword plsqlKeyword VARRAY VARYING WHEN WRITE
+syn match   plsqlKeyword "\<END\>"
+syn match   plsqlKeyword "\.COUNT\>"hs=s+1
+syn match   plsqlKeyword "\.EXISTS\>"hs=s+1
+syn match   plsqlKeyword "\.FIRST\>"hs=s+1
+syn match   plsqlKeyword "\.LAST\>"hs=s+1
+syn match   plsqlKeyword "\.DELETE\>"hs=s+1
+syn match   plsqlKeyword "\.PREV\>"hs=s+1
+syn match   plsqlKeyword "\.NEXT\>"hs=s+1
+
+" PL/SQL functions.
+syn keyword plsqlFunction ABS ACOS ADD_MONTHS ASCII ASCIISTR ASIN ATAN ATAN2
+syn keyword plsqlFunction BFILENAME BITAND CEIL CHARTOROWID CHR COALESCE
+syn keyword plsqlFunction COMMIT COMMIT_CM COMPOSE CONCAT  CONVERT  COS COSH
+syn keyword plsqlFunction COUNT CUBE CURRENT_DATE CURRENT_TIME CURRENT_TIMESTAMP
+syn keyword plsqlFunction DBTIMEZONE DECODE DECOMPOSE DEREF DUMP EMPTY_BLOB
+syn keyword plsqlFunction EMPTY_CLOB EXISTS EXP FLOOR FROM_TZ GETBND GLB
+syn keyword plsqlFunction GREATEST GREATEST_LB GROUPING HEXTORAW  INITCAP
+syn keyword plsqlFunction INSTR INSTR2 INSTR4 INSTRB INSTRC ISNCHAR LAST_DAY
+syn keyword plsqlFunction LEAST LEAST_UB LENGTH LENGTH2 LENGTH4 LENGTHB LENGTHC
+syn keyword plsqlFunction LN LOCALTIME LOCALTIMESTAMP LOG LOWER LPAD
+syn keyword plsqlFunction LTRIM LUB MAKE_REF MAX MIN MOD MONTHS_BETWEEN
+syn keyword plsqlFunction NCHARTOROWID NCHR NEW_TIME NEXT_DAY NHEXTORAW
+syn keyword plsqlFunction NLS_CHARSET_DECL_LEN NLS_CHARSET_ID NLS_CHARSET_NAME
+syn keyword plsqlFunction NLS_INITCAP NLS_LOWER NLSSORT NLS_UPPER NULLFN NULLIF
+syn keyword plsqlFunction NUMTODSINTERVAL NUMTOYMINTERVAL NVL POWER
+syn keyword plsqlFunction RAISE_APPLICATION_ERROR RAWTOHEX RAWTONHEX REF
+syn keyword plsqlFunction REFTOHEX REPLACE ROLLBACK_NR ROLLBACK_SV ROLLUP ROUND
+syn keyword plsqlFunction ROWIDTOCHAR ROWIDTONCHAR ROWLABEL RPAD RTRIM
+syn keyword plsqlFunction SAVEPOINT SESSIONTIMEZONE SETBND SET_TRANSACTION_USE
+syn keyword plsqlFunction SIGN SIN SINH SOUNDEX SQLCODE SQLERRM SQRT STDDEV
+syn keyword plsqlFunction SUBSTR SUBSTR2 SUBSTR4 SUBSTRB SUBSTRC SUM
+syn keyword plsqlFunction SYS_AT_TIME_ZONE SYS_CONTEXT SYSDATE SYS_EXTRACT_UTC
+syn keyword plsqlFunction SYS_GUID SYS_LITERALTODATE SYS_LITERALTODSINTERVAL
+syn keyword plsqlFunction SYS_LITERALTOTIME SYS_LITERALTOTIMESTAMP
+syn keyword plsqlFunction SYS_LITERALTOTZTIME SYS_LITERALTOTZTIMESTAMP
+syn keyword plsqlFunction SYS_LITERALTOYMINTERVAL SYS_OVER__DD SYS_OVER__DI
+syn keyword plsqlFunction SYS_OVER__ID SYS_OVER_IID SYS_OVER_IIT
+syn keyword plsqlFunction SYS_OVER__IT SYS_OVER__TI SYS_OVER__TT
+syn keyword plsqlFunction SYSTIMESTAMP TAN TANH TO_ANYLOB TO_BLOB TO_CHAR
+syn keyword plsqlFunction TO_CLOB TO_DATE TO_DSINTERVAL TO_LABEL TO_MULTI_BYTE
+syn keyword plsqlFunction TO_NCHAR TO_NCLOB TO_NUMBER TO_RAW TO_SINGLE_BYTE
+syn keyword plsqlFunction TO_TIME TO_TIMESTAMP TO_TIMESTAMP_TZ TO_TIME_TZ
+syn keyword plsqlFunction TO_YMINTERVAL TRANSLATE TREAT TRIM TRUNC TZ_OFFSET UID
+syn keyword plsqlFunction UNISTR UPPER UROWID USER USERENV VALUE VARIANCE
+syn keyword plsqlFunction VSIZE WORK XOR
+syn match   plsqlFunction "\<SYS\$LOB_REPLICATION\>"
+
+" PL/SQL Exceptions
+syn keyword plsqlException ACCESS_INTO_NULL CASE_NOT_FOUND COLLECTION_IS_NULL
+syn keyword plsqlException CURSOR_ALREADY_OPEN DUP_VAL_ON_INDEX INVALID_CURSOR
+syn keyword plsqlException INVALID_NUMBER LOGIN_DENIED NO_DATA_FOUND
+syn keyword plsqlException NOT_LOGGED_ON PROGRAM_ERROR ROWTYPE_MISMATCH
+syn keyword plsqlException SELF_IS_NULL STORAGE_ERROR SUBSCRIPT_BEYOND_COUNT
+syn keyword plsqlException SUBSCRIPT_OUTSIDE_LIMIT SYS_INVALID_ROWID
+syn keyword plsqlException TIMEOUT_ON_RESOURCE TOO_MANY_ROWS VALUE_ERROR
+syn keyword plsqlException ZERO_DIVIDE
+
+" Oracle Pseudo Colums.
+syn keyword plsqlPseudo CURRVAL LEVEL NEXTVAL ROWID ROWNUM
+
+if exists("plsql_highlight_triggers")
+  syn keyword plsqlTrigger INSERTING UPDATING DELETING
+endif
+
+" Conditionals.
+syn keyword plsqlConditional ELSIF ELSE IF
+syn match   plsqlConditional "\<END\s\+IF\>"
+
+" Loops.
+syn keyword plsqlRepeat FOR LOOP WHILE FORALL
+syn match   plsqlRepeat "\<END\s\+LOOP\>"
+
+" Various types of comments.
+if exists("c_comment_strings")
+  syntax match plsqlCommentSkip contained "^\s*\*\($\|\s\+\)"
+  syntax region plsqlCommentString contained start=+L\="+ skip=+\\\\\|\\"+ end=+"+ end=+\*/+me=s-1 contains=plsqlCommentSkip
+  syntax region plsqlComment2String contained start=+L\="+ skip=+\\\\\|\\"+ end=+"+ end="$"
+  syntax region plsqlCommentL start="--" skip="\\$" end="$" keepend contains=@plsqlCommentGroup,plsqlComment2String,plsqlCharLiteral,plsqlBooleanLiteral,plsqlNumbersCom,plsqlSpaceError
+  syntax region plsqlComment start="/\*" end="\*/" contains=@plsqlCommentGroup,plsqlComment2String,plsqlCharLiteral,plsqlBooleanLiteral,plsqlNumbersCom,plsqlSpaceError
+else
+  syntax region plsqlCommentL start="--" skip="\\$" end="$" keepend contains=@plsqlCommentGroup,plsqlSpaceError
+  syntax region plsqlComment start="/\*" end="\*/" contains=@plsqlCommentGroup,plsqlSpaceError
+endif
+
+syn sync ccomment plsqlComment
+syn sync ccomment plsqlCommentL
+
+" To catch unterminated string literals.
+syn match   plsqlStringError "'.*$"
+
+" Various types of literals.
+syn match   plsqlNumbers transparent "\<[+-]\=\d\|[+-]\=\.\d" contains=plsqlIntLiteral,plsqlFloatLiteral
+syn match   plsqlNumbersCom contained transparent "\<[+-]\=\d\|[+-]\=\.\d" contains=plsqlIntLiteral,plsqlFloatLiteral
+syn match   plsqlIntLiteral contained "[+-]\=\d\+"
+syn match   plsqlFloatLiteral contained "[+-]\=\d\+\.\d*"
+syn match   plsqlFloatLiteral contained "[+-]\=\d*\.\d*"
+syn match   plsqlCharLiteral    "'[^']'"
+syn match   plsqlStringLiteral  "'\([^']\|''\)*'"
+syn keyword plsqlBooleanLiteral TRUE FALSE NULL
+
+" The built-in types.
+syn keyword plsqlStorage ANYDATA ANYTYPE BFILE BINARY_INTEGER BLOB BOOLEAN
+syn keyword plsqlStorage BYTE CHAR CHARACTER CLOB CURSOR DATE DAY DEC DECIMAL
+syn keyword plsqlStorage DOUBLE DSINTERVAL_UNCONSTRAINED FLOAT HOUR
+syn keyword plsqlStorage INT INTEGER INTERVAL LOB LONG MINUTE
+syn keyword plsqlStorage MLSLABEL MONTH NATURAL NATURALN NCHAR NCHAR_CS NCLOB
+syn keyword plsqlStorage NUMBER NUMERIC NVARCHAR PLS_INT PLS_INTEGER
+syn keyword plsqlStorage POSITIVE POSITIVEN PRECISION RAW REAL RECORD
+syn keyword plsqlStorage SECOND SIGNTYPE SMALLINT STRING SYS_REFCURSOR TABLE TIME
+syn keyword plsqlStorage TIMESTAMP TIMESTAMP_UNCONSTRAINED
+syn keyword plsqlStorage TIMESTAMP_TZ_UNCONSTRAINED
+syn keyword plsqlStorage TIMESTAMP_LTZ_UNCONSTRAINED UROWID VARCHAR
+syn keyword plsqlStorage VARCHAR2 YEAR YMINTERVAL_UNCONSTRAINED ZONE
+
+" A type-attribute is really a type.
+syn match plsqlTypeAttribute  "%\(TYPE\|ROWTYPE\)\>"
+
+" All other attributes.
+syn match plsqlAttribute "%\(BULK_EXCEPTIONS\|BULK_ROWCOUNT\|ISOPEN\|FOUND\|NOTFOUND\|ROWCOUNT\)\>"
+
+" This'll catch mis-matched close-parens.
+syn cluster plsqlParenGroup contains=plsqlParenError,@plsqlCommentGroup,plsqlCommentSkip,plsqlIntLiteral,plsqlFloatLiteral,plsqlNumbersCom
+if exists("c_no_bracket_error")
+  syn region plsqlParen transparent start='(' end=')' contains=ALLBUT,@plsqlParenGroup
+  syn match plsqlParenError ")"
+  syn match plsqlErrInParen contained "[{}]"
+else
+  syn region plsqlParen transparent start='(' end=')' contains=ALLBUT,@plsqlParenGroup,plsqlErrInBracket
+  syn match plsqlParenError "[\])]"
+  syn match plsqlErrInParen contained "[{}]"
+  syn region plsqlBracket transparent start='\[' end=']' contains=ALLBUT,@plsqlParenGroup,plsqlErrInParen
+  syn match plsqlErrInBracket contained "[);{}]"
+endif
+
+" Syntax Synchronizing
+syn sync minlines=10 maxlines=100
+
+" Define the default highlighting.
+" For version 5.x and earlier, only when not done already.
+" For version 5.8 and later, only when an item doesn't have highlighting yet.
+if version >= 508 || !exists("did_plsql_syn_inits")
+  if version < 508
+    let did_plsql_syn_inits = 1
+    command -nargs=+ HiLink hi link <args>
+  else
+    command -nargs=+ HiLink hi def link <args>
+  endif
+
+  HiLink plsqlAttribute		Macro
+  HiLink plsqlBlockError	Error
+  HiLink plsqlBooleanLiteral	Boolean
+  HiLink plsqlCharLiteral	Character
+  HiLink plsqlComment		Comment
+  HiLink plsqlCommentL		Comment
+  HiLink plsqlConditional	Conditional
+  HiLink plsqlError		Error
+  HiLink plsqlErrInBracket	Error
+  HiLink plsqlErrInBlock	Error
+  HiLink plsqlErrInParen	Error
+  HiLink plsqlException		Function
+  HiLink plsqlFloatLiteral	Float
+  HiLink plsqlFunction		Function
+  HiLink plsqlGarbage		Error
+  HiLink plsqlHostIdentifier	Label
+  HiLink plsqlIdentifier	Normal
+  HiLink plsqlIntLiteral	Number
+  HiLink plsqlOperator		Operator
+  HiLink plsqlParen		Normal
+  HiLink plsqlParenError	Error
+  HiLink plsqlSpaceError	Error
+  HiLink plsqlPseudo		PreProc
+  HiLink plsqlKeyword		Keyword
+  HiLink plsqlRepeat		Repeat
+  HiLink plsqlStorage		StorageClass
+  HiLink plsqlSQLKeyword	Function
+  HiLink plsqlStringError	Error
+  HiLink plsqlStringLiteral	String
+  HiLink plsqlCommentString	String
+  HiLink plsqlComment2String	String
+  HiLink plsqlSymbol		Normal
+  HiLink plsqlTrigger		Function
+  HiLink plsqlTypeAttribute	StorageClass
+  HiLink plsqlTodo		Todo
+
+  delcommand HiLink
+endif
+
+let b:current_syntax = "plsql"
+
+" vim: ts=8 sw=2
--- /dev/null
+++ b/lib/vimfiles/syntax/po.vim
@@ -1,0 +1,123 @@
+" Vim syntax file
+" Language:	po (gettext)
+" Maintainer:	Dwayne Bailey <dwayne@translate.org.za>
+" Last Change:	2004 Nov 13
+
+" For version 5.x: Clear all syntax items
+" For version 6.x: Quit when a syntax file was already loaded
+if version < 600
+  syntax clear
+elseif exists("b:current_syntax")
+  finish
+endif
+
+syn sync minlines=10
+
+" Identifiers
+syn match  poStatementMsgidplural "^msgid_plural" contained
+syn match  poPluralCaseN "[0-9]" contained
+syn match  poStatementMsgstr "^msgstr\(\[[0-9]\]\)" contains=poPluralCaseN
+
+" Simple HTML and XML highlighting
+syn match  poHtml "<[^<>]\+>" contains=poHtmlTranslatables
+syn match  poHtmlNot +"<[^<]\+>"+ms=s+1,me=e-1
+syn region poHtmlTranslatables start=+alt=\\"+ms=e-1 end=+\\"+ contained
+
+" Translation blocks
+syn region     poMsgID	matchgroup=poStatementMsgid start=+^msgid "+rs=e-1 matchgroup=poStringID end=+^msgstr\(\|\[[\]0\[]\]\) "+me=s-1 contains=poStringID,poStatementMsgidplural,poStatementMsgid
+syn region     poMsgSTR	matchgroup=poStatementMsgstr start=+^msgstr\(\|\[[\]0\[]\]\) "+rs=e-1 matchgroup=poStringSTR end=+\n\n+me=s-1 contains=poStringSTR,poStatementMsgstr
+syn region poStringID	start=+"+ skip=+\\\\\|\\"+ end=+"+ contained 
+                            \ contains=poSpecial,poFormat,poCommentKDE,poPluralKDE,poKDEdesktopFile,poHtml,poAccelerator,poHtmlNot,poVariable
+syn region poStringSTR	start=+"+ skip=+\\\\\|\\"+ end=+"+ contained 
+                            \ contains=poSpecial,poFormat,poHeaderItem,poCommentKDEError,poHeaderUndefined,poPluralKDEError,poMsguniqError,poKDEdesktopFile,poHtml,poAccelerator,poHtmlNot,poVariable
+
+" Header and Copyright
+syn match     poHeaderItem "\(Project-Id-Version\|Report-Msgid-Bugs-To\|POT-Creation-Date\|PO-Revision-Date\|Last-Translator\|Language-Team\|MIME-Version\|Content-Type\|Content-Transfer-Encoding\|Plural-Forms\|X-Generator\): " contained
+syn match     poHeaderUndefined "\(PACKAGE VERSION\|YEAR-MO-DA HO:MI+ZONE\|FULL NAME <EMAIL@ADDRESS>\|LANGUAGE <LL@li.org>\|text/plain; charset=CHARSET\|ENCODING\)" contained
+syn match     poCopyrightUnset "SOME DESCRIPTIVE TITLE\|FIRST AUTHOR <EMAIL@ADDRESS>, YEAR\|Copyright (C) YEAR Free Software Foundation, Inc\|YEAR THE PACKAGE\'S COPYRIGHT HOLDER\|PACKAGE" contained
+
+" Translation comment block including: translator comment, automatic coments, flags and locations
+syn match     poComment "^#.*$"
+syn keyword   poFlagFuzzy fuzzy contained
+syn match     poCommentTranslator "^# .*$" contains=poCopyrightUnset
+syn match     poCommentAutomatic "^#\..*$" 
+syn match     poCommentSources	"^#:.*$"
+syn match     poCommentFlags "^#,.*$" contains=poFlagFuzzy
+
+" Translations (also includes header fields as they appear in a translation msgstr)
+syn region poCommentKDE	  start=+"_: +ms=s+1 end="\\n" end="\"\n^msgstr"me=s-1 contained
+syn region poCommentKDEError  start=+"\(\|\s\+\)_:+ms=s+1 end="\\n" end=+"\n\n+me=s-1 contained
+syn match  poPluralKDE   +"_n: +ms=s+1 contained
+syn region poPluralKDEError   start=+"\(\|\s\+\)_n:+ms=s+1 end="\"\n\n"me=s-1 contained
+syn match  poSpecial	contained "\\\(x\x\+\|\o\{1,3}\|.\|$\)"
+syn match  poFormat	"%\(\d\+\$\)\=[-+' #0*]*\(\d*\|\*\|\*\d\+\$\)\(\.\(\d*\|\*\|\*\d\+\$\)\)\=\([hlL]\|ll\)\=\([diuoxXfeEgGcCsSpn]\|\[\^\=.[^]]*\]\)" contained
+syn match  poFormat	"%%" contained
+
+" msguniq and msgcat conflicts
+syn region poMsguniqError matchgroup=poMsguniqErrorMarkers  start="#-#-#-#-#"  end='#\("\n"\|\)-\("\n"\|\)#\("\n"\|\)-\("\n"\|\)#\("\n"\|\)-\("\n"\|\)#\("\n"\|\)-\("\n"\|\)#\("\n"\|\)\\n' contained
+
+" Obsolete messages
+syn match poObsolete "^#\~.*$" 
+
+" KDE Name= handling
+syn match poKDEdesktopFile "\"\(Name\|Comment\|GenericName\|Description\|Keywords\|About\)="ms=s+1,me=e-1
+
+" Accelerator keys - this messes up if the preceding or following char is a multibyte unicode char
+syn match poAccelerator  contained "[^&_~][&_~]\(\a\|\d\)[^:]"ms=s+1,me=e-1 
+
+" Variables simple
+syn match poVariable contained "%\d"
+
+" Define the default highlighting.
+" For version 5.7 and earlier: only when not done already
+" For version 5.8 and later: only when an item doesn't have highlighting yet
+if version >= 508 || !exists("did_po_syn_inits")
+  if version < 508
+    let did_po_syn_inits = 1
+    command -nargs=+ HiLink hi link <args>
+  else
+    command -nargs=+ HiLink hi def link <args>
+  endif
+
+  HiLink poCommentSources    PreProc
+  HiLink poComment	     Comment
+  HiLink poCommentAutomatic  Comment
+  HiLink poCommentTranslator Comment
+  HiLink poCommentFlags      Special
+  HiLink poCopyrightUnset    Todo
+  HiLink poFlagFuzzy         Todo
+  HiLink poObsolete         Comment
+
+  HiLink poStatementMsgid   Statement
+  HiLink poStatementMsgstr  Statement
+  HiLink poStatementMsgidplural  Statement
+  HiLink poPluralCaseN      Constant
+
+  HiLink poStringID	    String
+  HiLink poStringSTR	    String
+  HiLink poCommentKDE       Comment
+  HiLink poCommentKDEError  Error
+  HiLink poPluralKDE        Comment
+  HiLink poPluralKDEError   Error
+  HiLink poHeaderItem       Identifier
+  HiLink poHeaderUndefined  Todo
+  HiLink poKDEdesktopFile   Identifier
+
+  HiLink poHtml              Identifier
+  HiLink poHtmlNot           String
+  HiLink poHtmlTranslatables String
+
+  HiLink poFormat	    poSpecial
+  HiLink poSpecial	    Special
+  HiLink poAccelerator       Special
+  HiLink poVariable          Special
+
+  HiLink poMsguniqError        Special
+  HiLink poMsguniqErrorMarkers Comment
+
+  delcommand HiLink
+endif
+
+let b:current_syntax = "po"
+
+" vim:set ts=8 sts=2 sw=2 noet:
--- /dev/null
+++ b/lib/vimfiles/syntax/pod.vim
@@ -1,0 +1,88 @@
+" Vim syntax file
+" Language:	Perl POD format
+" Maintainer:	Scott Bigham <dsb@killerbunnies.org>
+" Last Change:	2007 Jan 21
+
+" To add embedded POD documentation highlighting to your syntax file, add
+" the commands:
+"
+"   syn include @Pod <sfile>:p:h/pod.vim
+"   syn region myPOD start="^=pod" start="^=head" end="^=cut" keepend contained contains=@Pod
+"
+" and add myPod to the contains= list of some existing region, probably a
+" comment.  The "keepend" flag is needed because "=cut" is matched as a
+" pattern in its own right.
+
+
+" Remove any old syntax stuff hanging around (this is suppressed
+" automatically by ":syn include" if necessary).
+" For version 5.x: Clear all syntax items
+" For version 6.x: Quit when a syntax file was already loaded
+if version < 600
+  syntax clear
+elseif exists("b:current_syntax")
+  finish
+endif
+
+" POD commands
+syn match podCommand	"^=head[1234]"	nextgroup=podCmdText contains=@NoSpell
+syn match podCommand	"^=item"	nextgroup=podCmdText contains=@NoSpell
+syn match podCommand	"^=over"	nextgroup=podOverIndent skipwhite contains=@NoSpell
+syn match podCommand	"^=back" contains=@NoSpell
+syn match podCommand	"^=cut" contains=@NoSpell
+syn match podCommand	"^=pod" contains=@NoSpell
+syn match podCommand	"^=for"		nextgroup=podForKeywd skipwhite contains=@NoSpell
+syn match podCommand	"^=begin"	nextgroup=podForKeywd skipwhite contains=@NoSpell
+syn match podCommand	"^=end"		nextgroup=podForKeywd skipwhite contains=@NoSpell
+
+" Text of a =head1, =head2 or =item command
+syn match podCmdText	".*$" contained contains=podFormat,@NoSpell
+
+" Indent amount of =over command
+syn match podOverIndent	"\d\+" contained contains=@NoSpell
+
+" Formatter identifier keyword for =for, =begin and =end commands
+syn match podForKeywd	"\S\+" contained contains=@NoSpell
+
+" An indented line, to be displayed verbatim
+syn match podVerbatimLine	"^\s.*$" contains=@NoSpell
+
+" Inline textual items handled specially by POD
+syn match podSpecial	"\(\<\|&\)\I\i*\(::\I\i*\)*([^)]*)" contains=@NoSpell
+syn match podSpecial	"[$@%]\I\i*\(::\I\i*\)*\>" contains=@NoSpell
+
+" Special formatting sequences
+syn region podFormat	start="[IBSCLFX]<[^<]"me=e-1 end=">" oneline contains=podFormat,@NoSpell
+syn region podFormat	start="[IBSCLFX]<<\s" end="\s>>" oneline contains=podFormat,@NoSpell
+syn match  podFormat	"Z<>"
+syn match  podFormat	"E<\(\d\+\|\I\i*\)>" contains=podEscape,podEscape2,@NoSpell
+syn match  podEscape	"\I\i*>"me=e-1 contained contains=@NoSpell
+syn match  podEscape2	"\d\+>"me=e-1 contained contains=@NoSpell
+
+" Define the default highlighting.
+" For version 5.7 and earlier: only when not done already
+" For version 5.8 and later: only when an item doesn't have highlighting yet
+if version >= 508 || !exists("did_pod_syntax_inits")
+  if version < 508
+    let did_pod_syntax_inits = 1
+    command -nargs=+ HiLink hi link <args>
+  else
+    command -nargs=+ HiLink hi def link <args>
+  endif
+
+  HiLink podCommand		Statement
+  HiLink podCmdText		String
+  HiLink podOverIndent		Number
+  HiLink podForKeywd		Identifier
+  HiLink podFormat		Identifier
+  HiLink podVerbatimLine	PreProc
+  HiLink podSpecial		Identifier
+  HiLink podEscape		String
+  HiLink podEscape2		Number
+
+  delcommand HiLink
+endif
+
+let b:current_syntax = "pod"
+
+" vim: ts=8
--- /dev/null
+++ b/lib/vimfiles/syntax/postscr.vim
@@ -1,0 +1,783 @@
+" Vim syntax file
+" Language:     PostScript - all Levels, selectable
+" Maintainer:   Mike Williams <mrw@eandem.co.uk>
+" Filenames:    *.ps,*.eps
+" Last Change:  27th June 2002
+" URL:		http://www.eandem.co.uk/mrw/vim
+"
+" Options Flags:
+" postscr_level			- language level to use for highligting (1, 2, or 3)
+" postscr_display		- include display PS operators
+" postscr_ghostscript		- include GS extensions
+" postscr_fonts			- highlight standard font names (a lot for PS 3)
+" postscr_encodings		- highlight encoding names (there are a lot)
+" postscr_andornot_binary	- highlight and, or, and not as binary operators (not logical)
+"
+" For version 5.x: Clear all syntax items
+" For version 6.x: Quit when a syntax file was already loaded
+if version < 600
+  syntax clear
+elseif exists("b:current_syntax")
+  finish
+endif
+
+" PostScript is case sensitive
+syn case match
+
+" Keyword characters - all 7-bit ASCII bar PS delimiters and ws
+if version >= 600
+  setlocal iskeyword=33-127,^(,^),^<,^>,^[,^],^{,^},^/,^%
+else
+  set iskeyword=33-127,^(,^),^<,^>,^[,^],^{,^},^/,^%
+endif
+
+" Yer trusty old TODO highlghter!
+syn keyword postscrTodo contained  TODO
+
+" Comment
+syn match postscrComment	"%.*$" contains=postscrTodo
+" DSC comment start line (NB: defines DSC level, not PS level!)
+syn match  postscrDSCComment    "^%!PS-Adobe-\d\+\.\d\+\s*.*$"
+" DSC comment line (no check on possible comments - another language!)
+syn match  postscrDSCComment    "^%%\u\+.*$" contains=@postscrString,@postscrNumber
+" DSC continuation line (no check that previous line is DSC comment)
+syn match  postscrDSCComment    "^%%+ *.*$" contains=@postscrString,@postscrNumber
+
+" Names
+syn match postscrName		"\k\+"
+
+" Identifiers
+syn match postscrIdentifierError "/\{1,2}[[:space:]\[\]{}]"me=e-1
+syn match postscrIdentifier     "/\{1,2}\k\+" contains=postscrConstant,postscrBoolean,postscrCustConstant
+
+" Numbers
+syn case ignore
+" In file hex data - usually complete lines
+syn match postscrHex		"^[[:xdigit:]][[:xdigit:][:space:]]*$"
+"syn match postscrHex		 "\<\x\{2,}\>"
+" Integers
+syn match postscrInteger	"\<[+-]\=\d\+\>"
+" Radix
+syn match postscrRadix		"\d\+#\x\+\>"
+" Reals - upper and lower case e is allowed
+syn match postscrFloat		"[+-]\=\d\+\.\>"
+syn match postscrFloat		"[+-]\=\d\+\.\d*\(e[+-]\=\d\+\)\=\>"
+syn match postscrFloat		"[+-]\=\.\d\+\(e[+-]\=\d\+\)\=\>"
+syn match postscrFloat		"[+-]\=\d\+e[+-]\=\d\+\>"
+syn cluster postscrNumber	contains=postscrInteger,postscrRadix,postscrFloat
+syn case match
+
+" Escaped characters
+syn match postscrSpecialChar    contained "\\[nrtbf\\()]"
+syn match postscrSpecialCharError contained "\\[^nrtbf\\()]"he=e-1
+" Escaped octal characters
+syn match postscrSpecialChar    contained "\\\o\{1,3}"
+
+" Strings
+" ASCII strings
+syn region postscrASCIIString   start=+(+ end=+)+ skip=+([^)]*)+ contains=postscrSpecialChar,postscrSpecialCharError
+" Hex strings
+syn match postscrHexCharError   contained "[^<>[:xdigit:][:space:]]"
+syn region postscrHexString     start=+<\($\|[^<]\)+ end=+>+ contains=postscrHexCharError
+syn match postscrHexString      "<>"
+" ASCII85 strings
+syn match postscrASCII85CharError contained "[^<>\~!-uz[:space:]]"
+syn region postscrASCII85String start=+<\~+ end=+\~>+ contains=postscrASCII85CharError
+syn cluster postscrString       contains=postscrASCIIString,postscrHexString,postscrASCII85String
+
+
+" Set default highlighting to level 2 - most common at the moment
+if !exists("postscr_level")
+  let postscr_level = 2
+endif
+
+
+" PS level 1 operators - common to all levels (well ...)
+
+" Stack operators
+syn keyword postscrOperator     pop exch dup copy index roll clear count mark cleartomark counttomark
+
+" Math operators
+syn keyword postscrMathOperator add div idiv mod mul sub abs neg ceiling floor round truncate sqrt atan cos
+syn keyword postscrMathOperator sin exp ln log rand srand rrand
+
+" Array operators
+syn match postscrOperator       "[\[\]{}]"
+syn keyword postscrOperator     array length get put getinterval putinterval astore aload copy
+syn keyword postscrRepeat       forall
+
+" Dictionary operators
+syn keyword postscrOperator     dict maxlength begin end def load store known where currentdict
+syn keyword postscrOperator     countdictstack dictstack cleardictstack internaldict
+syn keyword postscrConstant     $error systemdict userdict statusdict errordict
+
+" String operators
+syn keyword postscrOperator     string anchorsearch search token
+
+" Logic operators
+syn keyword postscrLogicalOperator eq ne ge gt le lt and not or
+if exists("postscr_andornot_binaryop")
+  syn keyword postscrBinaryOperator and or not
+else
+  syn keyword postscrLogicalOperator and not or
+endif
+syn keyword postscrBinaryOperator xor bitshift
+syn keyword postscrBoolean      true false
+
+" PS Type names
+syn keyword postscrConstant     arraytype booleantype conditiontype dicttype filetype fonttype gstatetype
+syn keyword postscrConstant     integertype locktype marktype nametype nulltype operatortype
+syn keyword postscrConstant     packedarraytype realtype savetype stringtype
+
+" Control operators
+syn keyword postscrConditional  if ifelse
+syn keyword postscrRepeat       for repeat loop
+syn keyword postscrOperator     exec exit stop stopped countexecstack execstack quit
+syn keyword postscrProcedure    start
+
+" Object operators
+syn keyword postscrOperator     type cvlit cvx xcheck executeonly noaccess readonly rcheck wcheck cvi cvn cvr
+syn keyword postscrOperator     cvrs cvs
+
+" File operators
+syn keyword postscrOperator     file closefile read write readhexstring writehexstring readstring writestring
+syn keyword postscrOperator     bytesavailable flush flushfile resetfile status run currentfile print
+syn keyword postscrOperator     stack pstack readline deletefile setfileposition fileposition renamefile
+syn keyword postscrRepeat       filenameforall
+syn keyword postscrProcedure    = ==
+
+" VM operators
+syn keyword postscrOperator     save restore
+
+" Misc operators
+syn keyword postscrOperator     bind null usertime executive echo realtime
+syn keyword postscrConstant     product revision serialnumber version
+syn keyword postscrProcedure    prompt
+
+" GState operators
+syn keyword postscrOperator     gsave grestore grestoreall initgraphics setlinewidth setlinecap currentgray
+syn keyword postscrOperator     currentlinejoin setmiterlimit currentmiterlimit setdash currentdash setgray
+syn keyword postscrOperator     sethsbcolor currenthsbcolor setrgbcolor currentrgbcolor currentlinewidth
+syn keyword postscrOperator     currentlinecap setlinejoin setcmykcolor currentcmykcolor
+
+" Device gstate operators
+syn keyword postscrOperator     setscreen currentscreen settransfer currenttransfer setflat currentflat
+syn keyword postscrOperator     currentblackgeneration setblackgeneration setundercolorremoval
+syn keyword postscrOperator     setcolorscreen currentcolorscreen setcolortransfer currentcolortransfer
+syn keyword postscrOperator     currentundercolorremoval
+
+" Matrix operators
+syn keyword postscrOperator     matrix initmatrix identmatrix defaultmatrix currentmatrix setmatrix translate
+syn keyword postscrOperator     concat concatmatrix transform dtransform itransform idtransform invertmatrix
+syn keyword postscrOperator     scale rotate
+
+" Path operators
+syn keyword postscrOperator     newpath currentpoint moveto rmoveto lineto rlineto arc arcn arcto curveto
+syn keyword postscrOperator     closepath flattenpath reversepath strokepath charpath clippath pathbbox
+syn keyword postscrOperator     initclip clip eoclip rcurveto
+syn keyword postscrRepeat       pathforall
+
+" Painting operators
+syn keyword postscrOperator     erasepage fill eofill stroke image imagemask colorimage
+
+" Device operators
+syn keyword postscrOperator     showpage copypage nulldevice
+
+" Character operators
+syn keyword postscrProcedure    findfont
+syn keyword postscrConstant     FontDirectory ISOLatin1Encoding StandardEncoding
+syn keyword postscrOperator     definefont scalefont makefont setfont currentfont show ashow
+syn keyword postscrOperator     stringwidth kshow setcachedevice
+syn keyword postscrOperator     setcharwidth widthshow awidthshow findencoding cshow rootfont setcachedevice2
+
+" Interpreter operators
+syn keyword postscrOperator     vmstatus cachestatus setcachelimit
+
+" PS constants
+syn keyword postscrConstant     contained Gray Red Green Blue All None DeviceGray DeviceRGB
+
+" PS Filters
+syn keyword postscrConstant     contained ASCIIHexDecode ASCIIHexEncode ASCII85Decode ASCII85Encode LZWDecode
+syn keyword postscrConstant     contained RunLengthDecode RunLengthEncode SubFileDecode NullEncode
+syn keyword postscrConstant     contained GIFDecode PNGDecode LZWEncode
+
+" PS JPEG filter dictionary entries
+syn keyword postscrConstant     contained DCTEncode DCTDecode Colors HSamples VSamples QuantTables QFactor
+syn keyword postscrConstant     contained HuffTables ColorTransform
+
+" PS CCITT filter dictionary entries
+syn keyword postscrConstant     contained CCITTFaxEncode CCITTFaxDecode Uncompressed K EndOfLine
+syn keyword postscrConstant     contained Columns Rows EndOfBlock Blacks1 DamagedRowsBeforeError
+syn keyword postscrConstant     contained EncodedByteAlign
+
+" PS Form dictionary entries
+syn keyword postscrConstant     contained FormType XUID BBox Matrix PaintProc Implementation
+
+" PS Errors
+syn keyword postscrProcedure    handleerror
+syn keyword postscrConstant     contained  configurationerror dictfull dictstackunderflow dictstackoverflow
+syn keyword postscrConstant     contained  execstackoverflow interrupt invalidaccess
+syn keyword postscrConstant     contained  invalidcontext invalidexit invalidfileaccess invalidfont
+syn keyword postscrConstant     contained  invalidid invalidrestore ioerror limitcheck nocurrentpoint
+syn keyword postscrConstant     contained  rangecheck stackoverflow stackunderflow syntaxerror timeout
+syn keyword postscrConstant     contained  typecheck undefined undefinedfilename undefinedresource
+syn keyword postscrConstant     contained  undefinedresult unmatchedmark unregistered VMerror
+
+if exists("postscr_fonts")
+" Font names
+  syn keyword postscrConstant   contained Symbol Times-Roman Times-Italic Times-Bold Times-BoldItalic
+  syn keyword postscrConstant   contained Helvetica Helvetica-Oblique Helvetica-Bold Helvetica-BoldOblique
+  syn keyword postscrConstant   contained Courier Courier-Oblique Courier-Bold Courier-BoldOblique
+endif
+
+
+if exists("postscr_display")
+" Display PS only operators
+  syn keyword postscrOperator   currentcontext fork join detach lock monitor condition wait notify yield
+  syn keyword postscrOperator   viewclip eoviewclip rectviewclip initviewclip viewclippath deviceinfo
+  syn keyword postscrOperator   sethalftonephase currenthalftonephase wtranslation defineusername
+endif
+
+" PS Character encoding names
+if exists("postscr_encodings")
+" Common encoding names
+  syn keyword postscrConstant   contained .notdef
+
+" Standard and ISO encoding names
+  syn keyword postscrConstant   contained space exclam quotedbl numbersign dollar percent ampersand quoteright
+  syn keyword postscrConstant   contained parenleft parenright asterisk plus comma hyphen period slash zero
+  syn keyword postscrConstant   contained one two three four five six seven eight nine colon semicolon less
+  syn keyword postscrConstant   contained equal greater question at
+  syn keyword postscrConstant   contained bracketleft backslash bracketright asciicircum underscore quoteleft
+  syn keyword postscrConstant   contained braceleft bar braceright asciitilde
+  syn keyword postscrConstant   contained exclamdown cent sterling fraction yen florin section currency
+  syn keyword postscrConstant   contained quotesingle quotedblleft guillemotleft guilsinglleft guilsinglright
+  syn keyword postscrConstant   contained fi fl endash dagger daggerdbl periodcentered paragraph bullet
+  syn keyword postscrConstant   contained quotesinglbase quotedblbase quotedblright guillemotright ellipsis
+  syn keyword postscrConstant   contained perthousand questiondown grave acute circumflex tilde macron breve
+  syn keyword postscrConstant   contained dotaccent dieresis ring cedilla hungarumlaut ogonek caron emdash
+  syn keyword postscrConstant   contained AE ordfeminine Lslash Oslash OE ordmasculine ae dotlessi lslash
+  syn keyword postscrConstant   contained oslash oe germandbls
+" The following are valid names, but are used as short procedure names in generated PS!
+" a b c d e f g h i j k l m n o p q r s t u v w x y z
+" A B C D E F G H I J K L M N O P Q R S T U V W X Y Z
+
+" Symbol encoding names
+  syn keyword postscrConstant   contained universal existential suchthat asteriskmath minus
+  syn keyword postscrConstant   contained congruent Alpha Beta Chi Delta Epsilon Phi Gamma Eta Iota theta1
+  syn keyword postscrConstant   contained Kappa Lambda Mu Nu Omicron Pi Theta Rho Sigma Tau Upsilon sigma1
+  syn keyword postscrConstant   contained Omega Xi Psi Zeta therefore perpendicular
+  syn keyword postscrConstant   contained radicalex alpha beta chi delta epsilon phi gamma eta iota phi1
+  syn keyword postscrConstant   contained kappa lambda mu nu omicron pi theta rho sigma tau upsilon omega1
+  syn keyword postscrConstant   contained Upsilon1 minute lessequal infinity club diamond heart spade
+  syn keyword postscrConstant   contained arrowboth arrowleft arrowup arrowright arrowdown degree plusminus
+  syn keyword postscrConstant   contained second greaterequal multiply proportional partialdiff divide
+  syn keyword postscrConstant   contained notequal equivalence approxequal arrowvertex arrowhorizex
+  syn keyword postscrConstant   contained aleph Ifraktur Rfraktur weierstrass circlemultiply circleplus
+  syn keyword postscrConstant   contained emptyset intersection union propersuperset reflexsuperset notsubset
+  syn keyword postscrConstant   contained propersubset reflexsubset element notelement angle gradient
+  syn keyword postscrConstant   contained registerserif copyrightserif trademarkserif radical dotmath
+  syn keyword postscrConstant   contained logicalnot logicaland logicalor arrowdblboth arrowdblleft arrowdblup
+  syn keyword postscrConstant   contained arrowdblright arrowdbldown omega xi psi zeta similar carriagereturn
+  syn keyword postscrConstant   contained lozenge angleleft registersans copyrightsans trademarksans summation
+  syn keyword postscrConstant   contained parenlefttp parenleftex parenleftbt bracketlefttp bracketleftex
+  syn keyword postscrConstant   contained bracketleftbt bracelefttp braceleftmid braceleftbt braceex euro
+  syn keyword postscrConstant   contained angleright integral integraltp integralex integralbt parenrighttp
+  syn keyword postscrConstant   contained parenrightex parenrightbt bracketrighttp bracketrightex
+  syn keyword postscrConstant   contained bracketrightbt bracerighttp bracerightmid bracerightbt
+
+" ISO Latin1 encoding names
+  syn keyword postscrConstant   contained brokenbar copyright registered twosuperior threesuperior
+  syn keyword postscrConstant   contained onesuperior onequarter onehalf threequarters
+  syn keyword postscrConstant   contained Agrave Aacute Acircumflex Atilde Adieresis Aring Ccedilla Egrave
+  syn keyword postscrConstant   contained Eacute Ecircumflex Edieresis Igrave Iacute Icircumflex Idieresis
+  syn keyword postscrConstant   contained Eth Ntilde Ograve Oacute Ocircumflex Otilde Odieresis Ugrave Uacute
+  syn keyword postscrConstant   contained Ucircumflex Udieresis Yacute Thorn
+  syn keyword postscrConstant   contained agrave aacute acircumflex atilde adieresis aring ccedilla egrave
+  syn keyword postscrConstant   contained eacute ecircumflex edieresis igrave iacute icircumflex idieresis
+  syn keyword postscrConstant   contained eth ntilde ograve oacute ocircumflex otilde odieresis ugrave uacute
+  syn keyword postscrConstant   contained ucircumflex udieresis yacute thorn ydieresis
+  syn keyword postscrConstant   contained zcaron exclamsmall Hungarumlautsmall dollaroldstyle dollarsuperior
+  syn keyword postscrConstant   contained ampersandsmall Acutesmall parenleftsuperior parenrightsuperior
+  syn keyword postscrConstant   contained twodotenleader onedotenleader zerooldstyle oneoldstyle twooldstyle
+  syn keyword postscrConstant   contained threeoldstyle fouroldstyle fiveoldstyle sixoldstyle sevenoldstyle
+  syn keyword postscrConstant   contained eightoldstyle nineoldstyle commasuperior
+  syn keyword postscrConstant   contained threequartersemdash periodsuperior questionsmall asuperior bsuperior
+  syn keyword postscrConstant   contained centsuperior dsuperior esuperior isuperior lsuperior msuperior
+  syn keyword postscrConstant   contained nsuperior osuperior rsuperior ssuperior tsuperior ff ffi ffl
+  syn keyword postscrConstant   contained parenleftinferior parenrightinferior Circumflexsmall hyphensuperior
+  syn keyword postscrConstant   contained Gravesmall Asmall Bsmall Csmall Dsmall Esmall Fsmall Gsmall Hsmall
+  syn keyword postscrConstant   contained Ismall Jsmall Ksmall Lsmall Msmall Nsmall Osmall Psmall Qsmall
+  syn keyword postscrConstant   contained Rsmall Ssmall Tsmall Usmall Vsmall Wsmall Xsmall Ysmall Zsmall
+  syn keyword postscrConstant   contained colonmonetary onefitted rupiah Tildesmall exclamdownsmall
+  syn keyword postscrConstant   contained centoldstyle Lslashsmall Scaronsmall Zcaronsmall Dieresissmall
+  syn keyword postscrConstant   contained Brevesmall Caronsmall Dotaccentsmall Macronsmall figuredash
+  syn keyword postscrConstant   contained hypheninferior Ogoneksmall Ringsmall Cedillasmall questiondownsmall
+  syn keyword postscrConstant   contained oneeighth threeeighths fiveeighths seveneighths onethird twothirds
+  syn keyword postscrConstant   contained zerosuperior foursuperior fivesuperior sixsuperior sevensuperior
+  syn keyword postscrConstant   contained eightsuperior ninesuperior zeroinferior oneinferior twoinferior
+  syn keyword postscrConstant   contained threeinferior fourinferior fiveinferior sixinferior seveninferior
+  syn keyword postscrConstant   contained eightinferior nineinferior centinferior dollarinferior periodinferior
+  syn keyword postscrConstant   contained commainferior Agravesmall Aacutesmall Acircumflexsmall
+  syn keyword postscrConstant   contained Atildesmall Adieresissmall Aringsmall AEsmall Ccedillasmall
+  syn keyword postscrConstant   contained Egravesmall Eacutesmall Ecircumflexsmall Edieresissmall Igravesmall
+  syn keyword postscrConstant   contained Iacutesmall Icircumflexsmall Idieresissmall Ethsmall Ntildesmall
+  syn keyword postscrConstant   contained Ogravesmall Oacutesmall Ocircumflexsmall Otildesmall Odieresissmall
+  syn keyword postscrConstant   contained OEsmall Oslashsmall Ugravesmall Uacutesmall Ucircumflexsmall
+  syn keyword postscrConstant   contained Udieresissmall Yacutesmall Thornsmall Ydieresissmall Black Bold Book
+  syn keyword postscrConstant   contained Light Medium Regular Roman Semibold
+
+" Sundry standard and expert encoding names
+  syn keyword postscrConstant   contained trademark Scaron Ydieresis Zcaron scaron softhyphen overscore
+  syn keyword postscrConstant   contained graybox Sacute Tcaron Zacute sacute tcaron zacute Aogonek Scedilla
+  syn keyword postscrConstant   contained Zdotaccent aogonek scedilla Lcaron lcaron zdotaccent Racute Abreve
+  syn keyword postscrConstant   contained Lacute Cacute Ccaron Eogonek Ecaron Dcaron Dcroat Nacute Ncaron
+  syn keyword postscrConstant   contained Ohungarumlaut Rcaron Uring Uhungarumlaut Tcommaaccent racute abreve
+  syn keyword postscrConstant   contained lacute cacute ccaron eogonek ecaron dcaron dcroat nacute ncaron
+  syn keyword postscrConstant   contained ohungarumlaut rcaron uring uhungarumlaut tcommaaccent Gbreve
+  syn keyword postscrConstant   contained Idotaccent gbreve blank apple
+endif
+
+
+" By default level 3 includes all level 2 operators
+if postscr_level == 2 || postscr_level == 3
+" Dictionary operators
+  syn match postscrOperator     "\(<<\|>>\)"
+  syn keyword postscrOperator   undef
+  syn keyword postscrConstant   globaldict shareddict
+
+" Device operators
+  syn keyword postscrOperator   setpagedevice currentpagedevice
+
+" Path operators
+  syn keyword postscrOperator   rectclip setbbox uappend ucache upath ustrokepath arct
+
+" Painting operators
+  syn keyword postscrOperator   rectfill rectstroke ufill ueofill ustroke
+
+" Array operators
+  syn keyword postscrOperator   currentpacking setpacking packedarray
+
+" Misc operators
+  syn keyword postscrOperator   languagelevel
+
+" Insideness operators
+  syn keyword postscrOperator   infill ineofill instroke inufill inueofill inustroke
+
+" GState operators
+  syn keyword postscrOperator   gstate setgstate currentgstate setcolor
+  syn keyword postscrOperator   setcolorspace currentcolorspace setstrokeadjust currentstrokeadjust
+  syn keyword postscrOperator   currentcolor
+
+" Device gstate operators
+  syn keyword postscrOperator   sethalftone currenthalftone setoverprint currentoverprint
+  syn keyword postscrOperator   setcolorrendering currentcolorrendering
+
+" Character operators
+  syn keyword postscrConstant   GlobalFontDirectory SharedFontDirectory
+  syn keyword postscrOperator   glyphshow selectfont
+  syn keyword postscrOperator   addglyph undefinefont xshow xyshow yshow
+
+" Pattern operators
+  syn keyword postscrOperator   makepattern setpattern execform
+
+" Resource operators
+  syn keyword postscrOperator   defineresource undefineresource findresource resourcestatus
+  syn keyword postscrRepeat     resourceforall
+
+" File operators
+  syn keyword postscrOperator   filter printobject writeobject setobjectformat currentobjectformat
+
+" VM operators
+  syn keyword postscrOperator   currentshared setshared defineuserobject execuserobject undefineuserobject
+  syn keyword postscrOperator   gcheck scheck startjob currentglobal setglobal
+  syn keyword postscrConstant   UserObjects
+
+" Interpreter operators
+  syn keyword postscrOperator   setucacheparams setvmthreshold ucachestatus setsystemparams
+  syn keyword postscrOperator   setuserparams currentuserparams setcacheparams currentcacheparams
+  syn keyword postscrOperator   currentdevparams setdevparams vmreclaim currentsystemparams
+
+" PS2 constants
+  syn keyword postscrConstant   contained DeviceCMYK Pattern Indexed Separation Cyan Magenta Yellow Black
+  syn keyword postscrConstant   contained CIEBasedA CIEBasedABC CIEBasedDEF CIEBasedDEFG
+
+" PS2 $error dictionary entries
+  syn keyword postscrConstant   contained newerror errorname command errorinfo ostack estack dstack
+  syn keyword postscrConstant   contained recordstacks binary
+
+" PS2 Category dictionary
+  syn keyword postscrConstant   contained DefineResource UndefineResource FindResource ResourceStatus
+  syn keyword postscrConstant   contained ResourceForAll Category InstanceType ResourceFileName
+
+" PS2 Category names
+  syn keyword postscrConstant   contained Font Encoding Form Pattern ProcSet ColorSpace Halftone
+  syn keyword postscrConstant   contained ColorRendering Filter ColorSpaceFamily Emulator IODevice
+  syn keyword postscrConstant   contained ColorRenderingType FMapType FontType FormType HalftoneType
+  syn keyword postscrConstant   contained ImageType PatternType Category Generic
+
+" PS2 pagedevice dictionary entries
+  syn keyword postscrConstant   contained PageSize MediaColor MediaWeight MediaType InputAttributes ManualFeed
+  syn keyword postscrConstant   contained OutputType OutputAttributes NumCopies Collate Duplex Tumble
+  syn keyword postscrConstant   contained Separations HWResolution Margins NegativePrint MirrorPrint
+  syn keyword postscrConstant   contained CutMedia AdvanceMedia AdvanceDistance ImagingBBox
+  syn keyword postscrConstant   contained Policies Install BeginPage EndPage PolicyNotFound PolicyReport
+  syn keyword postscrConstant   contained ManualSize OutputFaceUp Jog
+  syn keyword postscrConstant   contained Bind BindDetails Booklet BookletDetails CollateDetails
+  syn keyword postscrConstant   contained DeviceRenderingInfo ExitJamRecovery Fold FoldDetails Laminate
+  syn keyword postscrConstant   contained ManualFeedTimeout Orientation OutputPage
+  syn keyword postscrConstant   contained PostRenderingEnhance PostRenderingEnhanceDetails
+  syn keyword postscrConstant   contained PreRenderingEnhance PreRenderingEnhanceDetails
+  syn keyword postscrConstant   contained Signature SlipSheet Staple StapleDetails Trim
+  syn keyword postscrConstant   contained ProofSet REValue PrintQuality ValuesPerColorComponent AntiAlias
+
+" PS2 PDL resource entries
+  syn keyword postscrConstant   contained Selector LanguageFamily LanguageVersion
+
+" PS2 halftone dictionary entries
+  syn keyword postscrConstant   contained HalftoneType HalftoneName
+  syn keyword postscrConstant   contained AccurateScreens ActualAngle Xsquare Ysquare AccurateFrequency
+  syn keyword postscrConstant   contained Frequency SpotFunction Angle Width Height Thresholds
+  syn keyword postscrConstant   contained RedFrequency RedSpotFunction RedAngle RedWidth RedHeight
+  syn keyword postscrConstant   contained GreenFrequency GreenSpotFunction GreenAngle GreenWidth GreenHeight
+  syn keyword postscrConstant   contained BlueFrequency BlueSpotFunction BlueAngle BlueWidth BlueHeight
+  syn keyword postscrConstant   contained GrayFrequency GrayAngle GraySpotFunction GrayWidth GrayHeight
+  syn keyword postscrConstant   contained GrayThresholds BlueThresholds GreenThresholds RedThresholds
+  syn keyword postscrConstant   contained TransferFunction
+
+" PS2 CSR dictionaries
+  syn keyword postscrConstant   contained RangeA DecodeA MatrixA RangeABC DecodeABC MatrixABC BlackPoint
+  syn keyword postscrConstant   contained RangeLMN DecodeLMN MatrixLMN WhitePoint RangeDEF DecodeDEF RangeHIJ
+  syn keyword postscrConstant   contained RangeDEFG DecodeDEFG RangeHIJK Table
+
+" PS2 CRD dictionaries
+  syn keyword postscrConstant   contained ColorRenderingType EncodeLMB EncodeABC RangePQR MatrixPQR
+  syn keyword postscrConstant   contained AbsoluteColorimetric RelativeColorimetric Saturation Perceptual
+  syn keyword postscrConstant   contained TransformPQR RenderTable
+
+" PS2 Pattern dictionary
+  syn keyword postscrConstant   contained PatternType PaintType TilingType XStep YStep
+
+" PS2 Image dictionary
+  syn keyword postscrConstant   contained ImageType ImageMatrix MultipleDataSources DataSource
+  syn keyword postscrConstant   contained BitsPerComponent Decode Interpolate
+
+" PS2 Font dictionaries
+  syn keyword postscrConstant   contained FontType FontMatrix FontName FontInfo LanguageLevel WMode Encoding
+  syn keyword postscrConstant   contained UniqueID StrokeWidth Metrics Metrics2 CDevProc CharStrings Private
+  syn keyword postscrConstant   contained FullName Notice version ItalicAngle isFixedPitch UnderlinePosition
+  syn keyword postscrConstant   contained FMapType Encoding FDepVector PrefEnc EscChar ShiftOut ShiftIn
+  syn keyword postscrConstant   contained WeightVector Blend $Blend CIDFontType sfnts CIDSystemInfo CodeMap
+  syn keyword postscrConstant   contained CMap CIDFontName CIDSystemInfo UIDBase CIDDevProc CIDCount
+  syn keyword postscrConstant   contained CIDMapOffset FDArray FDBytes GDBytes GlyphData GlyphDictionary
+  syn keyword postscrConstant   contained SDBytes SubrMapOffset SubrCount BuildGlyph CIDMap FID MIDVector
+  syn keyword postscrConstant   contained Ordering Registry Supplement CMapName CMapVersion UIDOffset
+  syn keyword postscrConstant   contained SubsVector UnderlineThickness FamilyName FontBBox CurMID
+  syn keyword postscrConstant   contained Weight
+
+" PS2 User paramters
+  syn keyword postscrConstant   contained MaxFontItem MinFontCompress MaxUPathItem MaxFormItem MaxPatternItem
+  syn keyword postscrConstant   contained MaxScreenItem MaxOpStack MaxDictStack MaxExecStack MaxLocalVM
+  syn keyword postscrConstant   contained VMReclaim VMThreshold
+
+" PS2 System paramters
+  syn keyword postscrConstant   contained SystemParamsPassword StartJobPassword BuildTime ByteOrder RealFormat
+  syn keyword postscrConstant   contained MaxFontCache CurFontCache MaxOutlineCache CurOutlineCache
+  syn keyword postscrConstant   contained MaxUPathCache CurUPathCache MaxFormCache CurFormCache
+  syn keyword postscrConstant   contained MaxPatternCache CurPatternCache MaxScreenStorage CurScreenStorage
+  syn keyword postscrConstant   contained MaxDisplayList CurDisplayList
+
+" PS2 LZW Filters
+  syn keyword postscrConstant   contained Predictor
+
+" Paper Size operators
+  syn keyword postscrOperator   letter lettersmall legal ledger 11x17 a4 a3 a4small b5 note
+
+" Paper Tray operators
+  syn keyword postscrOperator   lettertray legaltray ledgertray a3tray a4tray b5tray 11x17tray
+
+" SCC compatibility operators
+  syn keyword postscrOperator   sccbatch sccinteractive setsccbatch setsccinteractive
+
+" Page duplexing operators
+  syn keyword postscrOperator   duplexmode firstside newsheet setduplexmode settumble tumble
+
+" Device compatability operators
+  syn keyword postscrOperator   devdismount devformat devmount devstatus
+  syn keyword postscrRepeat     devforall
+
+" Imagesetter compatability operators
+  syn keyword postscrOperator   accuratescreens checkscreen pagemargin pageparams setaccuratescreens setpage
+  syn keyword postscrOperator   setpagemargin setpageparams
+
+" Misc compatability operators
+  syn keyword postscrOperator   appletalktype buildtime byteorder checkpassword defaulttimeouts diskonline
+  syn keyword postscrOperator   diskstatus manualfeed manualfeedtimeout margins mirrorprint pagecount
+  syn keyword postscrOperator   pagestackorder printername processcolors sethardwareiomode setjobtimeout
+  syn keyword postscrOperator   setpagestockorder setprintername setresolution doprinterrors dostartpage
+  syn keyword postscrOperator   hardwareiomode initializedisk jobname jobtimeout ramsize realformat resolution
+  syn keyword postscrOperator   setdefaulttimeouts setdoprinterrors setdostartpage setdosysstart
+  syn keyword postscrOperator   setuserdiskpercent softwareiomode userdiskpercent waittimeout
+  syn keyword postscrOperator   setsoftwareiomode dosysstart emulate setmargins setmirrorprint
+
+endif " PS2 highlighting
+
+if postscr_level == 3
+" Shading operators
+  syn keyword postscrOperator   setsmoothness currentsmoothness shfill
+
+" Clip operators
+  syn keyword postscrOperator   clipsave cliprestore
+
+" Pagedevive operators
+  syn keyword postscrOperator   setpage setpageparams
+
+" Device gstate operators
+  syn keyword postscrOperator   findcolorrendering
+
+" Font operators
+  syn keyword postscrOperator   composefont
+
+" PS LL3 Output device resource entries
+  syn keyword postscrConstant   contained DeviceN TrappingDetailsType
+
+" PS LL3 pagdevice dictionary entries
+  syn keyword postscrConstant   contained DeferredMediaSelection ImageShift InsertSheet LeadingEdge MaxSeparations
+  syn keyword postscrConstant   contained MediaClass MediaPosition OutputDevice PageDeviceName PageOffset ProcessColorModel
+  syn keyword postscrConstant   contained RollFedMedia SeparationColorNames SeparationOrder Trapping TrappingDetails
+  syn keyword postscrConstant   contained TraySwitch UseCIEColor
+  syn keyword postscrConstant   contained ColorantDetails ColorantName ColorantType NeutralDensity TrappingOrder
+  syn keyword postscrConstant   contained ColorantSetName
+
+" PS LL3 trapping dictionary entries
+  syn keyword postscrConstant   contained BlackColorLimit BlackDensityLimit BlackWidth ColorantZoneDetails
+  syn keyword postscrConstant   contained SlidingTrapLimit StepLimit TrapColorScaling TrapSetName TrapWidth
+  syn keyword postscrConstant   contained ImageResolution ImageToObjectTrapping ImageTrapPlacement
+  syn keyword postscrConstant   contained StepLimit TrapColorScaling Enabled ImageInternalTrapping
+
+" PS LL3 filters and entries
+  syn keyword postscrConstant   contained ReusableStreamDecode CloseSource CloseTarget UnitSize LowBitFirst
+  syn keyword postscrConstant   contained FlateEncode FlateDecode DecodeParams Intent AsyncRead
+
+" PS LL3 halftone dictionary entries
+  syn keyword postscrConstant   contained Height2 Width2
+
+" PS LL3 function dictionary entries
+  syn keyword postscrConstant   contained FunctionType Domain Range Order BitsPerSample Encode Size C0 C1 N
+  syn keyword postscrConstant   contained Functions Bounds
+
+" PS LL3 image dictionary entries
+  syn keyword postscrConstant   contained InterleaveType MaskDict DataDict MaskColor
+
+" PS LL3 Pattern and shading dictionary entries
+  syn keyword postscrConstant   contained Shading ShadingType Background ColorSpace Coords Extend Function
+  syn keyword postscrConstant   contained VerticesPerRow BitsPerCoordinate BitsPerFlag
+
+" PS LL3 image dictionary entries
+  syn keyword postscrConstant   contained XOrigin YOrigin UnpaintedPath PixelCopy
+
+" PS LL3 colorrendering procedures
+  syn keyword postscrProcedure  GetHalftoneName GetPageDeviceName GetSubstituteCRD
+
+" PS LL3 CIDInit procedures
+  syn keyword postscrProcedure  beginbfchar beginbfrange begincidchar begincidrange begincmap begincodespacerange
+  syn keyword postscrProcedure  beginnotdefchar beginnotdefrange beginrearrangedfont beginusematrix
+  syn keyword postscrProcedure  endbfchar endbfrange endcidchar endcidrange endcmap endcodespacerange
+  syn keyword postscrProcedure  endnotdefchar endnotdefrange endrearrangedfont endusematrix
+  syn keyword postscrProcedure  StartData usefont usecmp
+
+" PS LL3 Trapping procedures
+  syn keyword postscrProcedure  settrapparams currenttrapparams settrapzone
+
+" PS LL3 BitmapFontInit procedures
+  syn keyword postscrProcedure  removeall removeglyphs
+
+" PS LL3 Font names
+  if exists("postscr_fonts")
+    syn keyword postscrConstant contained AlbertusMT AlbertusMT-Italic AlbertusMT-Light Apple-Chancery Apple-ChanceryCE
+    syn keyword postscrConstant contained AntiqueOlive-Roman AntiqueOlive-Italic AntiqueOlive-Bold AntiqueOlive-Compact
+    syn keyword postscrConstant contained AntiqueOliveCE-Roman AntiqueOliveCE-Italic AntiqueOliveCE-Bold AntiqueOliveCE-Compact
+    syn keyword postscrConstant contained ArialMT Arial-ItalicMT Arial-LightMT Arial-BoldMT Arial-BoldItalicMT
+    syn keyword postscrConstant contained ArialCE ArialCE-Italic ArialCE-Light ArialCE-Bold ArialCE-BoldItalic
+    syn keyword postscrConstant contained AvantGarde-Book AvantGarde-BookOblique AvantGarde-Demi AvantGarde-DemiOblique
+    syn keyword postscrConstant contained AvantGardeCE-Book AvantGardeCE-BookOblique AvantGardeCE-Demi AvantGardeCE-DemiOblique
+    syn keyword postscrConstant contained Bodoni Bodoni-Italic Bodoni-Bold Bodoni-BoldItalic Bodoni-Poster Bodoni-PosterCompressed
+    syn keyword postscrConstant contained BodoniCE BodoniCE-Italic BodoniCE-Bold BodoniCE-BoldItalic BodoniCE-Poster BodoniCE-PosterCompressed
+    syn keyword postscrConstant contained Bookman-Light Bookman-LightItalic Bookman-Demi Bookman-DemiItalic
+    syn keyword postscrConstant contained BookmanCE-Light BookmanCE-LightItalic BookmanCE-Demi BookmanCE-DemiItalic
+    syn keyword postscrConstant contained Carta Chicago ChicagoCE Clarendon Clarendon-Light Clarendon-Bold
+    syn keyword postscrConstant contained ClarendonCE ClarendonCE-Light ClarendonCE-Bold CooperBlack CooperBlack-Italic
+    syn keyword postscrConstant contained Copperplate-ThirtyTwoBC CopperPlate-ThirtyThreeBC Coronet-Regular CoronetCE-Regular
+    syn keyword postscrConstant contained CourierCE CourierCE-Oblique CourierCE-Bold CourierCE-BoldOblique
+    syn keyword postscrConstant contained Eurostile Eurostile-Bold Eurostile-ExtendedTwo Eurostile-BoldExtendedTwo
+    syn keyword postscrConstant contained Eurostile EurostileCE-Bold EurostileCE-ExtendedTwo EurostileCE-BoldExtendedTwo
+    syn keyword postscrConstant contained Geneva GenevaCE GillSans GillSans-Italic GillSans-Bold GillSans-BoldItalic GillSans-BoldCondensed
+    syn keyword postscrConstant contained GillSans-Light GillSans-LightItalic GillSans-ExtraBold
+    syn keyword postscrConstant contained GillSansCE-Roman GillSansCE-Italic GillSansCE-Bold GillSansCE-BoldItalic GillSansCE-BoldCondensed
+    syn keyword postscrConstant contained GillSansCE-Light GillSansCE-LightItalic GillSansCE-ExtraBold
+    syn keyword postscrConstant contained Goudy Goudy-Italic Goudy-Bold Goudy-BoldItalic Goudy-ExtraBould
+    syn keyword postscrConstant contained HelveticaCE HelveticaCE-Oblique HelveticaCE-Bold HelveticaCE-BoldOblique
+    syn keyword postscrConstant contained Helvetica-Condensed Helvetica-Condensed-Oblique Helvetica-Condensed-Bold Helvetica-Condensed-BoldObl
+    syn keyword postscrConstant contained HelveticaCE-Condensed HelveticaCE-Condensed-Oblique HelveticaCE-Condensed-Bold
+    syn keyword postscrConstant contained HelveticaCE-Condensed-BoldObl Helvetica-Narrow Helvetica-Narrow-Oblique Helvetica-Narrow-Bold
+    syn keyword postscrConstant contained Helvetica-Narrow-BoldOblique HelveticaCE-Narrow HelveticaCE-Narrow-Oblique HelveticaCE-Narrow-Bold
+    syn keyword postscrConstant contained HelveticaCE-Narrow-BoldOblique HoeflerText-Regular HoeflerText-Italic HoeflerText-Black
+    syn keyword postscrConstant contained HoeflerText-BlackItalic HoeflerText-Ornaments HoeflerTextCE-Regular HoeflerTextCE-Italic
+    syn keyword postscrConstant contained HoeflerTextCE-Black HoeflerTextCE-BlackItalic
+    syn keyword postscrConstant contained JoannaMT JoannaMT-Italic JoannaMT-Bold JoannaMT-BoldItalic
+    syn keyword postscrConstant contained JoannaMTCE JoannaMTCE-Italic JoannaMTCE-Bold JoannaMTCE-BoldItalic
+    syn keyword postscrConstant contained LetterGothic LetterGothic-Slanted LetterGothic-Bold LetterGothic-BoldSlanted
+    syn keyword postscrConstant contained LetterGothicCE LetterGothicCE-Slanted LetterGothicCE-Bold LetterGothicCE-BoldSlanted
+    syn keyword postscrConstant contained LubalinGraph-Book LubalinGraph-BookOblique LubalinGraph-Demi LubalinGraph-DemiOblique
+    syn keyword postscrConstant contained LubalinGraphCE-Book LubalinGraphCE-BookOblique LubalinGraphCE-Demi LubalinGraphCE-DemiOblique
+    syn keyword postscrConstant contained Marigold Monaco MonacoCE MonaLisa-Recut Oxford Symbol Tekton
+    syn keyword postscrConstant contained NewCennturySchlbk-Roman NewCenturySchlbk-Italic NewCenturySchlbk-Bold NewCenturySchlbk-BoldItalic
+    syn keyword postscrConstant contained NewCenturySchlbkCE-Roman NewCenturySchlbkCE-Italic NewCenturySchlbkCE-Bold
+    syn keyword postscrConstant contained NewCenturySchlbkCE-BoldItalic NewYork NewYorkCE
+    syn keyword postscrConstant contained Optima Optima-Italic Optima-Bold Optima-BoldItalic
+    syn keyword postscrConstant contained OptimaCE OptimaCE-Italic OptimaCE-Bold OptimaCE-BoldItalic
+    syn keyword postscrConstant contained Palatino-Roman Palatino-Italic Palatino-Bold Palatino-BoldItalic
+    syn keyword postscrConstant contained PalatinoCE-Roman PalatinoCE-Italic PalatinoCE-Bold PalatinoCE-BoldItalic
+    syn keyword postscrConstant contained StempelGaramond-Roman StempelGaramond-Italic StempelGaramond-Bold StempelGaramond-BoldItalic
+    syn keyword postscrConstant contained StempelGaramondCE-Roman StempelGaramondCE-Italic StempelGaramondCE-Bold StempelGaramondCE-BoldItalic
+    syn keyword postscrConstant contained TimesCE-Roman TimesCE-Italic TimesCE-Bold TimesCE-BoldItalic
+    syn keyword postscrConstant contained TimesNewRomanPSMT TimesNewRomanPS-ItalicMT TimesNewRomanPS-BoldMT TimesNewRomanPS-BoldItalicMT
+    syn keyword postscrConstant contained TimesNewRomanCE TimesNewRomanCE-Italic TimesNewRomanCE-Bold TimesNewRomanCE-BoldItalic
+    syn keyword postscrConstant contained Univers Univers-Oblique Univers-Bold Univers-BoldOblique
+    syn keyword postscrConstant contained UniversCE-Medium UniversCE-Oblique UniversCE-Bold UniversCE-BoldOblique
+    syn keyword postscrConstant contained Univers-Light Univers-LightOblique UniversCE-Light UniversCE-LightOblique
+    syn keyword postscrConstant contained Univers-Condensed Univers-CondensedOblique Univers-CondensedBold Univers-CondensedBoldOblique
+    syn keyword postscrConstant contained UniversCE-Condensed UniversCE-CondensedOblique UniversCE-CondensedBold UniversCE-CondensedBoldOblique
+    syn keyword postscrConstant contained Univers-Extended Univers-ExtendedObl Univers-BoldExt Univers-BoldExtObl
+    syn keyword postscrConstant contained UniversCE-Extended UniversCE-ExtendedObl UniversCE-BoldExt UniversCE-BoldExtObl
+    syn keyword postscrConstant contained Wingdings-Regular ZapfChancery-MediumItalic ZapfChanceryCE-MediumItalic ZapfDingBats
+  endif " Font names
+
+endif " PS LL3 highlighting
+
+
+if exists("postscr_ghostscript")
+  " GS gstate operators
+  syn keyword postscrOperator   .setaccuratecurves .currentaccuratecurves .setclipoutside
+  syn keyword postscrOperator   .setdashadapt .currentdashadapt .setdefaultmatrix .setdotlength
+  syn keyword postscrOperator   .currentdotlength .setfilladjust2 .currentfilladjust2
+  syn keyword postscrOperator   .currentclipoutside .setcurvejoin .currentcurvejoin
+  syn keyword postscrOperator   .setblendmode .currentblendmode .setopacityalpha .currentopacityalpha .setshapealpha .currentshapealpha
+  syn keyword postscrOperator   .setlimitclamp .currentlimitclamp .setoverprintmode .currentoverprintmode
+
+  " GS path operators
+  syn keyword postscrOperator   .dashpath .rectappend
+
+  " GS painting operators
+  syn keyword postscrOperator   .setrasterop .currentrasterop .setsourcetransparent
+  syn keyword postscrOperator   .settexturetransparent .currenttexturetransparent
+  syn keyword postscrOperator   .currentsourcetransparent
+
+  " GS character operators
+  syn keyword postscrOperator   .charboxpath .type1execchar %Type1BuildChar %Type1BuildGlyph
+
+  " GS mathematical operators
+  syn keyword postscrMathOperator arccos arcsin
+
+  " GS dictionary operators
+  syn keyword postscrOperator   .dicttomark .forceput .forceundef .knownget .setmaxlength
+
+  " GS byte and string operators
+  syn keyword postscrOperator   .type1encrypt .type1decrypt
+  syn keyword postscrOperator   .bytestring .namestring .stringmatch
+
+  " GS relational operators (seem like math ones to me!)
+  syn keyword postscrMathOperator max min
+
+  " GS file operators
+  syn keyword postscrOperator   findlibfile unread writeppmfile
+  syn keyword postscrOperator   .filename .fileposition .peekstring .unread
+
+  " GS vm operators
+  syn keyword postscrOperator   .forgetsave
+
+  " GS device operators
+  syn keyword postscrOperator   copydevice .getdevice makeimagedevice makewordimagedevice copyscanlines
+  syn keyword postscrOperator   setdevice currentdevice getdeviceprops putdeviceprops flushpage
+  syn keyword postscrOperator   finddevice findprotodevice .getbitsrect
+
+  " GS misc operators
+  syn keyword postscrOperator   getenv .makeoperator .setdebug .oserrno .oserror .execn
+
+  " GS rendering stack operators
+  syn keyword postscrOperator   .begintransparencygroup .discardtransparencygroup .endtransparencygroup
+  syn keyword postscrOperator   .begintransparencymask .discardtransparencymask .endtransparencymask .inittransparencymask
+  syn keyword postscrOperator   .settextknockout .currenttextknockout
+
+  " GS filters
+  syn keyword postscrConstant   contained BCPEncode BCPDecode eexecEncode eexecDecode PCXDecode
+  syn keyword postscrConstant   contained PixelDifferenceEncode PixelDifferenceDecode
+  syn keyword postscrConstant   contained PNGPredictorDecode TBCPEncode TBCPDecode zlibEncode
+  syn keyword postscrConstant   contained zlibDecode PNGPredictorEncode PFBDecode
+  syn keyword postscrConstant   contained MD5Encode
+
+  " GS filter keys
+  syn keyword postscrConstant   contained InitialCodeLength FirstBitLowOrder BlockData DecodedByteAlign
+
+  " GS device parameters
+  syn keyword postscrConstant   contained BitsPerPixel .HWMargins HWSize Name GrayValues
+  syn keyword postscrConstant   contained ColorValues TextAlphaBits GraphicsAlphaBits BufferSpace
+  syn keyword postscrConstant   contained OpenOutputFile PageCount BandHeight BandWidth BandBufferSpace
+  syn keyword postscrConstant   contained ViewerPreProcess GreenValues BlueValues OutputFile
+  syn keyword postscrConstant   contained MaxBitmap RedValues
+
+endif " GhostScript highlighting
+
+" Define the default highlighting.
+" For version 5.7 and earlier: only when not done already
+" For version 5.8 and later: only when an item doesn't have highlighting yet
+if version >= 508 || !exists("did_postscr_syntax_inits")
+  if version < 508
+    let did_postscr_syntax_inits = 1
+    command -nargs=+ HiLink hi link <args>
+  else
+    command -nargs=+ HiLink hi def link <args>
+  endif
+
+  HiLink postscrComment		Comment
+
+  HiLink postscrConstant	Constant
+  HiLink postscrString		String
+  HiLink postscrASCIIString	postscrString
+  HiLink postscrHexString	postscrString
+  HiLink postscrASCII85String	postscrString
+  HiLink postscrNumber		Number
+  HiLink postscrInteger		postscrNumber
+  HiLink postscrHex		postscrNumber
+  HiLink postscrRadix		postscrNumber
+  HiLink postscrFloat		Float
+  HiLink postscrBoolean		Boolean
+
+  HiLink postscrIdentifier	Identifier
+  HiLink postscrProcedure	Function
+
+  HiLink postscrName		Statement
+  HiLink postscrConditional	Conditional
+  HiLink postscrRepeat		Repeat
+  HiLink postscrOperator	Operator
+  HiLink postscrMathOperator	postscrOperator
+  HiLink postscrLogicalOperator postscrOperator
+  HiLink postscrBinaryOperator	postscrOperator
+
+  HiLink postscrDSCComment	SpecialComment
+  HiLink postscrSpecialChar	SpecialChar
+
+  HiLink postscrTodo		Todo
+
+  HiLink postscrError		Error
+  HiLink postscrSpecialCharError postscrError
+  HiLink postscrASCII85CharError postscrError
+  HiLink postscrHexCharError	postscrError
+  HiLink postscrIdentifierError postscrError
+
+  delcommand HiLink
+endif
+
+let b:current_syntax = "postscr"
+
+" vim: ts=8
--- /dev/null
+++ b/lib/vimfiles/syntax/pov.vim
@@ -1,0 +1,144 @@
+" Vim syntax file
+" This is a GENERATED FILE. Please always refer to source file at the URI below.
+" Language: PoV-Ray(tm) 3.5 Scene Description Language
+" Maintainer: David Ne\v{c}as (Yeti) <yeti@physics.muni.cz>
+" Last Change: 2003 Apr 25
+" URL: http://physics.muni.cz/~yeti/download/syntax/pov.vim
+" Required Vim Version: 6.0
+
+" Setup
+if version >= 600
+  " Quit when a syntax file was already loaded
+  if exists("b:current_syntax")
+    finish
+  endif
+else
+  " Croak when an old Vim is sourcing us.
+  echo "Sorry, but this syntax file relies on Vim 6 features.  Either upgrade Vim or use a version of " . expand("<sfile>:t:r") . " syntax file appropriate for Vim " . version/100 . "." . version %100 . "."
+  finish
+endif
+
+syn case match
+
+" Top level stuff
+syn keyword povCommands global_settings
+syn keyword povObjects array atmosphere background bicubic_patch blob box camera component cone cubic cylinder disc fog height_field isosurface julia_fractal lathe light_group light_source mesh mesh2 object parametric pattern photons plane poly polygon prism quadric quartic rainbow sky_sphere smooth_triangle sor sphere sphere_sweep spline superellipsoid text torus triangle
+syn keyword povCSG clipped_by composite contained_by difference intersection merge union
+syn keyword povAppearance interior material media texture interior_texture texture_list
+syn keyword povGlobalSettings ambient_light assumed_gamma charset hf_gray_16 irid_wavelength max_intersections max_trace_level number_of_waves radiosity noise_generator
+syn keyword povTransform inverse matrix rotate scale translate transform
+
+" Descriptors
+syn keyword povDescriptors finish normal pigment uv_mapping uv_vectors vertex_vectors
+syn keyword povDescriptors adc_bailout always_sample brightness count error_bound distance_maximum gray_threshold load_file low_error_factor max_sample media minimum_reuse nearest_count normal pretrace_end pretrace_start recursion_limit save_file
+syn keyword povDescriptors color colour gray rgb rgbt rgbf rgbft red green blue
+syn keyword povDescriptors bump_map color_map colour_map image_map material_map pigment_map quick_color quick_colour normal_map texture_map image_pattern pigment_pattern
+syn keyword povDescriptors ambient brilliance conserve_energy crand diffuse fresnel irid metallic phong phong_size refraction reflection reflection_exponent roughness specular
+syn keyword povDescriptors cylinder fisheye omnimax orthographic panoramic perspective spherical ultra_wide_angle
+syn keyword povDescriptors agate average brick boxed bozo bumps cells checker crackle cylindrical dents facets function gradient granite hexagon julia leopard magnet mandel marble onion planar quilted radial ripples slope spherical spiral1 spiral2 spotted tiles tiles2 toroidal waves wood wrinkles
+syn keyword povDescriptors density_file
+syn keyword povDescriptors area_light shadowless spotlight parallel
+syn keyword povDescriptors absorption confidence density emission intervals ratio samples scattering variance
+syn keyword povDescriptors distance fog_alt fog_offset fog_type turb_depth
+syn keyword povDescriptors b_spline bezier_spline cubic_spline evaluate face_indices form linear_spline max_gradient natural_spline normal_indices normal_vectors quadratic_spline uv_indices
+syn keyword povDescriptors target
+
+" Modifiers
+syn keyword povModifiers caustics dispersion dispersion_samples fade_color fade_colour fade_distance fade_power ior
+syn keyword povModifiers bounded_by double_illuminate hierarchy hollow no_shadow open smooth sturm threshold water_level
+syn keyword povModifiers hypercomplex max_iteration precision quaternion slice
+syn keyword povModifiers conic_sweep linear_sweep
+syn keyword povModifiers flatness type u_steps v_steps
+syn keyword povModifiers aa_level aa_threshold adaptive falloff jitter looks_like media_attenuation media_interaction method point_at radius tightness
+syn keyword povModifiers angle aperture blur_samples confidence direction focal_point h_angle location look_at right sky up v_angle variance
+syn keyword povModifiers all bump_size filter interpolate map_type once slope_map transmit use_alpha use_color use_colour use_index
+syn keyword povModifiers black_hole agate_turb brick_size control0 control1 cubic_wave density_map flip frequency interpolate inverse lambda metric mortar octaves offset omega phase poly_wave ramp_wave repeat scallop_wave sine_wave size strength triangle_wave thickness turbulence turb_depth type warp
+syn keyword povModifiers eccentricity extinction
+syn keyword povModifiers arc_angle falloff_angle width
+syn keyword povModifiers accuracy all_intersections altitude autostop circular collect coords cutaway_textures dist_exp expand_thresholds exponent exterior gather global_lights major_radius max_trace no_bump_scale no_image no_reflection orient orientation pass_through precompute projected_through range_divider solid spacing split_union tolerance
+
+" Words not marked `reserved' in documentation, but...
+syn keyword povBMPType alpha gif iff jpeg pgm png pot ppm sys tga tiff contained
+syn keyword povFontType ttf contained
+syn keyword povDensityType df3 contained
+syn keyword povCharset ascii utf8 contained
+
+" Math functions on floats, vectors and strings
+syn keyword povFunctions abs acos acosh asc asin asinh atan atan2 atanh ceil cos cosh defined degrees dimensions dimension_size div exp file_exists floor int internal ln log max min mod pow radians rand seed select sin sinh sqrt strcmp strlen tan tanh val vdot vlength vstr vturbulence
+syn keyword povFunctions min_extent max_extent trace vcross vrotate vaxis_rotate vnormalize vturbulence
+syn keyword povFunctions chr concat substr str strupr strlwr
+syn keyword povJuliaFunctions acosh asinh atan cosh cube pwr reciprocal sinh sqr tanh
+
+" Specialities
+syn keyword povConsts clock clock_delta clock_on final_clock final_frame frame_number initial_clock initial_frame image_width image_height false no off on pi t true u v version x y yes z
+syn match povDotItem "\.\@<=\(blue\|green\|filter\|red\|transmit\|t\|u\|v\|x\|y\|z\)\>" display
+
+" Comments
+syn region povComment start="/\*" end="\*/" contains=povTodo,povComment
+syn match povComment "//.*" contains=povTodo
+syn match povCommentError "\*/"
+syn sync ccomment povComment
+syn sync minlines=50
+syn keyword povTodo TODO FIXME XXX NOT contained
+syn cluster povPRIVATE add=povTodo
+
+" Language directives
+syn match povConditionalDir "#\s*\(else\|end\|if\|ifdef\|ifndef\|switch\|while\)\>"
+syn match povLabelDir "#\s*\(break\|case\|default\|range\)\>"
+syn match povDeclareDir "#\s*\(declare\|default\|local\|macro\|undef\|version\)\>"
+syn match povIncludeDir "#\s*include\>"
+syn match povFileDir "#\s*\(fclose\|fopen\|read\|write\)\>"
+syn match povMessageDir "#\s*\(debug\|error\|render\|statistics\|warning\)\>"
+syn region povFileOpen start="#\s*fopen\>" skip=+"[^"]*"+ matchgroup=povOpenType end="\<\(read\|write\|append\)\>" contains=ALLBUT,PovParenError,PovBraceError,@PovPRIVATE transparent keepend
+
+" Literal strings
+syn match povSpecialChar "\\\d\d\d\|\\." contained
+syn region povString start=+"+ skip=+\\\\\|\\"+ end=+"+ contains=povSpecialChar oneline
+syn cluster povPRIVATE add=povSpecialChar
+
+" Catch errors caused by wrong parenthesization
+syn region povParen start='(' end=')' contains=ALLBUT,povParenError,@povPRIVATE transparent
+syn match povParenError ")"
+syn region povBrace start='{' end='}' contains=ALLBUT,povBraceError,@povPRIVATE transparent
+syn match povBraceError "}"
+
+" Numbers
+syn match povNumber "\(^\|\W\)\@<=[+-]\=\(\d\+\)\=\.\=\d\+\([eE][+-]\=\d\+\)\="
+
+" Define the default highlighting
+hi def link povComment Comment
+hi def link povTodo Todo
+hi def link povNumber Number
+hi def link povString String
+hi def link povFileOpen Constant
+hi def link povConsts Constant
+hi def link povDotItem Constant
+hi def link povBMPType povSpecial
+hi def link povCharset povSpecial
+hi def link povDensityType povSpecial
+hi def link povFontType povSpecial
+hi def link povOpenType povSpecial
+hi def link povSpecialChar povSpecial
+hi def link povSpecial Special
+hi def link povConditionalDir PreProc
+hi def link povLabelDir PreProc
+hi def link povDeclareDir Define
+hi def link povIncludeDir Include
+hi def link povFileDir PreProc
+hi def link povMessageDir Debug
+hi def link povAppearance povDescriptors
+hi def link povObjects povDescriptors
+hi def link povGlobalSettings povDescriptors
+hi def link povDescriptors Type
+hi def link povJuliaFunctions PovFunctions
+hi def link povModifiers povFunctions
+hi def link povFunctions Function
+hi def link povCommands Operator
+hi def link povTransform Operator
+hi def link povCSG Operator
+hi def link povParenError povError
+hi def link povBraceError povError
+hi def link povCommentError povError
+hi def link povError Error
+
+let b:current_syntax = "pov"
--- /dev/null
+++ b/lib/vimfiles/syntax/povini.vim
@@ -1,0 +1,62 @@
+" Vim syntax file
+" This is a GENERATED FILE. Please always refer to source file at the URI below.
+" Language: PoV-Ray(tm) 3.5 configuration/initialization files
+" Maintainer: David Ne\v{c}as (Yeti) <yeti@physics.muni.cz>
+" Last Change: 2002-06-01
+" URL: http://physics.muni.cz/~yeti/download/syntax/povini.vim
+" Required Vim Version: 6.0
+
+" Setup
+if version >= 600
+  " Quit when a syntax file was already loaded
+  if exists("b:current_syntax")
+    finish
+  endif
+else
+  " Croak when an old Vim is sourcing us.
+  echo "Sorry, but this syntax file relies on Vim 6 features.  Either upgrade Vim or usea version of " . expand("<sfile>:t:r") . " syntax file appropriate for Vim " . version/100 . "." . version %100 . "."
+  finish
+endif
+
+syn case ignore
+
+" Syntax
+syn match poviniInclude "^\s*[^[+-;]\S*\s*$" contains=poviniSection
+syn match poviniLabel "^.\{-1,}\ze=" transparent contains=poviniKeyword nextgroup=poviniBool,poviniNumber
+syn keyword poviniBool On Off True False Yes No
+syn match poviniNumber "\<\d*\.\=\d\+\>"
+syn keyword poviniKeyword Clock Initial_Frame Final_Frame Initial_Clock Final_Clock Subset_Start_Frame Subset_End_Frame Cyclic_Animation Field_Render Odd_Field
+syn keyword poviniKeyword Width Height Start_Column Start_Row End_Column End_Row Test_Abort Test_Abort_Count Continue_Trace Create_Ini
+syn keyword poviniKeyword Display Video_Mode Palette Display_Gamma Pause_When_Done Verbose Draw_Vistas Preview_Start_Size Preview_End_Size
+syn keyword poviniKeyword Output_to_File Output_File_Type Output_Alpha Bits_Per_Color Output_File_Name Buffer_Output Buffer_Size
+syn keyword poviniKeyword Histogram_Type Histogram_Grid_Size Histogram_Name
+syn keyword poviniKeyword Input_File_Name Include_Header Library_Path Version
+syn keyword poviniKeyword Debug_Console Fatal_Console Render_Console Statistic_Console Warning_Console All_Console Debug_File Fatal_File Render_File Statistic_File Warning_File All_File Warning_Level
+syn keyword poviniKeyword Quality Radiosity Bounding Bounding_Threshold Light_Buffer Vista_Buffer Remove_Bounds Split_Unions Antialias Sampling_Method Antialias_Threshold Jitter Jitter_Amount Antialias_Depth
+syn keyword poviniKeyword Pre_Scene_Return Pre_Frame_Return Post_Scene_Return Post_Frame_Return User_Abort_Return Fatal_Error_Return
+syn match poviniShellOut "^\s*\(Pre_Scene_Command\|Pre_Frame_Command\|Post_Scene_Command\|Post_Frame_Command\|User_Abort_Command\|Fatal_Error_Command\)\>" nextgroup=poviniShellOutEq skipwhite
+syn match poviniShellOutEq "=" nextgroup=poviniShellOutRHS skipwhite contained
+syn match poviniShellOutRHS "[^;]\+" skipwhite contained contains=poviniShellOutSpecial
+syn match poviniShellOutSpecial "%[osnkhw%]" contained
+syn keyword poviniDeclare Declare
+syn match poviniComment ";.*$"
+syn match poviniOption "^\s*[+-]\S*"
+syn match poviniIncludeLabel "^\s*Include_INI\s*=" nextgroup=poviniIncludedFile skipwhite
+syn match poviniIncludedFile "[^;]\+" contains=poviniSection contained
+syn region poviniSection start="\[" end="\]"
+
+" Define the default highlighting
+hi def link poviniSection Special
+hi def link poviniComment Comment
+hi def link poviniDeclare poviniKeyword
+hi def link poviniShellOut poviniKeyword
+hi def link poviniIncludeLabel poviniKeyword
+hi def link poviniKeyword Type
+hi def link poviniShellOutSpecial Special
+hi def link poviniIncludedFile poviniInclude
+hi def link poviniInclude Include
+hi def link poviniOption Keyword
+hi def link poviniBool Constant
+hi def link poviniNumber Number
+
+let b:current_syntax = "povini"
--- /dev/null
+++ b/lib/vimfiles/syntax/ppd.vim
@@ -1,0 +1,48 @@
+" Vim syntax file
+" Language:	PPD (PostScript printer description) file
+" Maintainer:	Bjoern Jacke <bjacke@suse.de>
+" Last Change:	2001-10-06
+
+" For version 5.x: Clear all syntax items
+" For version 6.x: Quit when a syntax file was already loaded
+if version < 600
+  syntax clear
+elseif exists("b:current_syntax")
+  finish
+endif
+
+
+syn match	ppdComment	"^\*%.*"
+syn match	ppdDef		"\*[a-zA-Z0-9]\+"
+syn match	ppdDefine	"\*[a-zA-Z0-9\-_]\+:"
+syn match	ppdUI		"\*[a-zA-Z]*\(Open\|Close\)UI"
+syn match	ppdUIGroup	"\*[a-zA-Z]*\(Open\|Close\)Group"
+syn match	ppdGUIText	"/.*:"
+syn match	ppdContraints	"^*UIConstraints:"
+
+" Define the default highlighting.
+" For version 5.7 and earlier: only when not done already
+" For version 5.8 and later: only when an item doesn't have highlighting yet
+if version >= 508 || !exists("did_ahdl_syn_inits")
+  if version < 508
+    let did_ahdl_syn_inits = 1
+    command -nargs=+ HiLink hi link <args>
+  else
+    command -nargs=+ HiLink hi def link <args>
+  endif
+
+
+  HiLink ppdComment		Comment
+  HiLink ppdDefine		Statement
+  HiLink ppdUI			Function
+  HiLink ppdUIGroup		Function
+  HiLink ppdDef			String
+  HiLink ppdGUIText		Type
+  HiLink ppdContraints		Special
+
+  delcommand HiLink
+endif
+
+let b:current_syntax = "ppd"
+
+" vim: ts=8
--- /dev/null
+++ b/lib/vimfiles/syntax/ppwiz.vim
@@ -1,0 +1,97 @@
+" Vim syntax file
+" Language:     PPWizard (preprocessor by Dennis Bareis)
+" Maintainer:   Stefan Schwarzer <s.schwarzer@ndh.net>
+" URL:			http://www.ndh.net/home/sschwarzer/download/ppwiz.vim
+" Last Change:  2003 May 11
+" Filename:     ppwiz.vim
+
+" Remove old syntax stuff
+" For version 5.x: Clear all syntax items
+" For version 6.x: Quit when a syntax file was already loaded
+if version < 600
+  syntax clear
+elseif exists("b:current_syntax")
+  finish
+endif
+
+syn case ignore
+
+if !exists("ppwiz_highlight_defs")
+    let ppwiz_highlight_defs = 1
+endif
+
+if !exists("ppwiz_with_html")
+    let ppwiz_with_html = 1
+endif
+
+" comments
+syn match   ppwizComment  "^;.*$"
+syn match   ppwizComment  ";;.*$"
+" HTML
+if ppwiz_with_html > 0
+    syn region ppwizHTML  start="<" end=">" contains=ppwizArg,ppwizMacro
+    syn match  ppwizHTML  "\&\w\+;"
+endif
+" define, evaluate etc.
+if ppwiz_highlight_defs == 1
+    syn match  ppwizDef   "^\s*\#\S\+\s\+\S\+" contains=ALL
+    syn match  ppwizDef   "^\s*\#\(if\|else\|endif\)" contains=ALL
+    syn match  ppwizDef   "^\s*\#\({\|break\|continue\|}\)" contains=ALL
+" elseif ppwiz_highlight_defs == 2
+"     syn region ppwizDef   start="^\s*\#" end="[^\\]$" end="^$" keepend contains=ALL
+else
+    syn region ppwizDef   start="^\s*\#" end="[^\\]$" end="^$" keepend contains=ppwizCont
+endif
+syn match   ppwizError    "\s.\\$"
+syn match   ppwizCont     "\s\([+\-%]\|\)\\$"
+" macros to execute
+syn region  ppwizMacro    start="<\$" end=">" contains=@ppwizArgVal,ppwizCont
+" macro arguments
+syn region  ppwizArg      start="{" end="}" contains=ppwizEqual,ppwizString
+syn match   ppwizEqual    "=" contained
+syn match   ppwizOperator "<>\|=\|<\|>" contained
+" standard variables (builtin)
+syn region  ppwizStdVar   start="<?[^?]" end=">" contains=@ppwizArgVal
+" Rexx variables
+syn region  ppwizRexxVar  start="<??" end=">" contains=@ppwizArgVal
+" Constants
+syn region  ppwizString   start=+"+ end=+"+ contained contains=ppwizMacro,ppwizArg,ppwizHTML,ppwizCont,ppwizStdVar,ppwizRexxVar
+syn region  ppwizString   start=+'+ end=+'+ contained contains=ppwizMacro,ppwizArg,ppwizHTML,ppwizCont,ppwizStdVar,ppwizRexxVar
+syn match   ppwizInteger  "\d\+" contained
+
+" Clusters
+syn cluster ppwizArgVal add=ppwizString,ppwizInteger
+
+" Define the default highlighting.
+" For version 5.7 and earlier: only when not done already
+" For version 5.8 and later: only when an item doesn't have highlighting yet
+if version >= 508 || !exists("did_ppwiz_syn_inits")
+    if version < 508
+		let did_ppwiz_syn_inits = 1
+		command -nargs=+ HiLink hi link <args>
+	else
+		command -nargs=+ HiLink hi def link <args>
+    endif
+
+    HiLink ppwizSpecial  Special
+    HiLink ppwizEqual    ppwizSpecial
+    HiLink ppwizOperator ppwizSpecial
+    HiLink ppwizComment  Comment
+    HiLink ppwizDef      PreProc
+    HiLink ppwizMacro    Statement
+    HiLink ppwizArg      Identifier
+    HiLink ppwizStdVar   Identifier
+    HiLink ppwizRexxVar  Identifier
+    HiLink ppwizString   Constant
+    HiLink ppwizInteger  Constant
+    HiLink ppwizCont     ppwizSpecial
+    HiLink ppwizError    Error
+    HiLink ppwizHTML     Type
+
+    delcommand HiLink
+endif
+
+let b:current_syntax = "ppwiz"
+
+" vim: ts=4
+
--- /dev/null
+++ b/lib/vimfiles/syntax/prescribe.vim
@@ -1,0 +1,69 @@
+" Vim syntax file
+" Language:	Kyocera PreScribe2e
+" Maintainer:	Klaus Muth <klaus@hampft.de>
+" URL:          http://www.hampft.de/vim/syntax/prescribe.vim
+" Last Change:	2005 Mar 04
+
+" For version 5.x: Clear all syntax items
+" For version 6.x: Quit when a syntax file was already loaded
+if version < 600
+  syntax clear
+elseif exists("b:current_syntax")
+  finish
+endif
+
+syn match   prescribeSpecial	"!R!"
+
+" all prescribe commands
+syn keyword prescribeStatement	ALTF AMCR ARC ASFN ASTK BARC BLK BOX CALL 
+syn keyword prescribeStatement	CASS CIR CLIP CLPR CLSP COPY CPTH CSET CSTK
+syn keyword prescribeStatement	CTXT DAF DAM DAP DELF DELM DPAT DRP DRPA DUPX
+syn keyword prescribeStatement	DXPG DXSD DZP ENDD ENDM ENDR EPL EPRM EXIT
+syn keyword prescribeStatement	FDIR FILL FLAT FLST FONT FPAT FRPO FSET FTMD
+syn keyword prescribeStatement	GPAT ICCD INTL JOG LDFC MAP MCRO MDAT MID
+syn keyword prescribeStatement	MLST MRP MRPA MSTK MTYP MZP NEWP PAGE PARC PAT
+syn keyword prescribeStatement	PCRP PCZP PDIR RDRP PDZP PELP PIE PMRA PMRP PMZP
+syn keyword prescribeStatement	PRBX PRRC PSRC PXPL RDMP RES RSL RGST RPCS RPF
+syn keyword prescribeStatement	RPG RPP RPU RTTX RTXT RVCD RVRD SBM SCAP SCCS
+syn keyword prescribeStatement	SCF SCG SCP SCPI SCRC SCS SCU SDP SEM SETF SFA
+syn keyword prescribeStatement	SFNT SIMG SIR SLJN SLM SLPI SLPP SLS  SMLT SPD
+syn keyword prescribeStatement	SPL SPLT SPO SPSZ SPW SRM SRO SROP SSTK STAT STRK
+syn keyword prescribeStatement	SULP SVCP TATR TEXT TPRS UNIT UOM WIDE WRED XPAT
+syn match   prescribeStatement	"\<ALTB\s\+[ACDEGRST]\>"
+syn match   prescribeStatement	"\<CPPY\s\+[DE]\>"
+syn match   prescribeStatement	"\<EMCR\s\+[DE]\>"
+syn match   prescribeStatement	"\<FRPO\s\+INIT\>"
+syn match   prescribeStatement	"\<JOB[DLOPST]\>"
+syn match   prescribeStatement	"\<LDFC\s\+[CFS]\>"
+syn match   prescribeStatement	"\<RWER\s\+[DFILRSTW]\>"
+
+syn match   prescribeCSETArg	"[0-9]\{1,3}[A-Z]"
+syn match   prescribeFRPOArg	"[A-Z][0-9]\{1,2}"
+syn match   prescribeNumber	"[0-9]\+"
+syn region  prescribeString	start=+'+ end=+'+ skip=+\\'+
+syn region  prescribeComment	start=+CMNT+ end=+;+
+
+" Define the default highlighting.
+" For version 5.7 and earlier: only when not done already
+" For version 5.8 and later: only when an item doesn't have highlighting yet
+if version >= 508 || !exists("did_prescribe_syn_inits")
+  if version < 508
+    let did_prescribe_syn_inits = 1
+    command -nargs=+ HiLink hi link <args>
+  else
+    command -nargs=+ HiLink hi def link <args>
+  endif
+
+  HiLink prescribeSpecial		PreProc
+  HiLink prescribeStatement		Statement
+  HiLink prescribeNumber		Number
+  HiLink prescribeCSETArg		String
+  HiLink prescribeFRPOArg		String
+  HiLink prescribeComment		Comment
+
+  delcommand HiLink
+endif
+
+let b:current_syntax = "prescribe"
+
+" vim: ts=8
--- /dev/null
+++ b/lib/vimfiles/syntax/privoxy.vim
@@ -1,0 +1,71 @@
+" Vim syntax file
+" Language:	Privoxy actions file
+" Maintainer:	Doug Kearns <dougkearns@gmail.com>
+" URL:		http://gus.gscit.monash.edu.au/~djkea2/vim/syntax/privoxy.vim
+" Last Change:	2007 Mar 30
+
+" Privoxy 3.0.6
+
+if exists("b:current_syntax")
+  finish
+endif
+
+let s:cpo_save = &cpo
+set cpo&vim
+
+setlocal iskeyword=@,48-57,_,-
+
+syn keyword privoxyTodo		 contained TODO FIXME XXX NOTE
+syn match   privoxyComment "#.*" contains=privoxyTodo,@Spell
+
+syn region privoxyActionLine matchgroup=privoxyActionLineDelimiter start="^\s*\zs{" end="}\ze\s*$"
+	\ contains=privoxyEnabledPrefix,privoxyDisabledPrefix
+
+syn match privoxyEnabledPrefix	"\%(^\|\s\|{\)\@<=+\l\@=" nextgroup=privoxyAction,privoxyFilterAction contained
+syn match privoxyDisabledPrefix "\%(^\|\s\|{\)\@<=-\l\@=" nextgroup=privoxyAction,privoxyFilterAction contained
+
+syn match privoxyAction "\%(add-header\|block\|content-type-overwrite\|crunch-client-header\|crunch-if-none-match\)\>" contained
+syn match privoxyAction "\%(crunch-incoming-cookies\|crunch-outgoing-cookies\|crunch-server-header\|deanimate-gifs\)\>" contained
+syn match privoxyAction "\%(downgrade-http-version\|fast-redirects\|filter-client-headers\|filter-server-headers\)\>" contained
+syn match privoxyAction "\%(filter\|force-text-mode\|handle-as-empty-document\|handle-as-image\)\>" contained
+syn match privoxyAction "\%(hide-accept-language\|hide-content-disposition\|hide-forwarded-for-headers\)\>" contained
+syn match privoxyAction "\%(hide-from-header\|hide-if-modified-since\|hide-referrer\|hide-user-agent\|inspect-jpegs\)\>" contained
+syn match privoxyAction "\%(kill-popups\|limit-connect\|overwrite-last-modified\|prevent-compression\|redirect\)\>" contained
+syn match privoxyAction "\%(send-vanilla-wafer\|send-wafer\|session-cookies-only\|set-image-blocker\)\>" contained
+syn match privoxyAction "\%(treat-forbidden-connects-like-blocks\)\>"
+
+syn match privoxyFilterAction "filter{[^}]*}" contained contains=privoxyFilterArg,privoxyActionBraces
+syn match privoxyActionBraces "[{}]" contained
+syn keyword privoxyFilterArg js-annoyances js-events html-annoyances content-cookies refresh-tags unsolicited-popups all-popups
+	\ img-reorder banners-by-size banners-by-link webbugs tiny-textforms jumping-windows frameset-borders demoronizer
+	\ shockwave-flash quicktime-kioskmode fun crude-parental ie-exploits site-specifics no-ping google yahoo msn blogspot
+	\ x-httpd-php-to-html html-to-xml xml-to-html hide-tor-exit-notation contained
+
+" Alternative spellings
+syn match privoxyAction "\%(kill-popup\|hide-referer\|prevent-keeping-cookies\)\>" contained
+
+" Pre-3.0 compatibility
+syn match privoxyAction "\%(no-cookie-read\|no-cookie-set\|prevent-reading-cookies\|prevent-setting-cookies\)\>" contained
+syn match privoxyAction "\%(downgrade\|hide-forwarded\|hide-from\|image\|image-blocker\|no-compression\)\>" contained
+syn match privoxyAction "\%(no-cookies-keep\|no-cookies-read\|no-cookies-set\|no-popups\|vanilla-wafer\|wafer\)\>" contained
+
+syn match privoxySetting "\<for-privoxy-version\>"
+
+syn match privoxyHeader "^\s*\zs{{\%(alias\|settings\)}}\ze\s*$"
+
+hi def link privoxyAction		Identifier
+hi def link privoxyFilterAction		Identifier
+hi def link privoxyActionLineDelimiter	Delimiter
+hi def link privoxyDisabledPrefix	SpecialChar
+hi def link privoxyEnabledPrefix	SpecialChar
+hi def link privoxyHeader		PreProc
+hi def link privoxySetting		Identifier
+hi def link privoxyFilterArg		Constant
+
+hi def link privoxyComment		Comment
+hi def link privoxyTodo			Todo
+
+let b:current_syntax = "privoxy"
+
+let &cpo = s:cpo_save
+unlet s:cpo_save
--- /dev/null
+++ b/lib/vimfiles/syntax/procmail.vim
@@ -1,0 +1,67 @@
+" Vim syntax file
+" Language:	Procmail definition file
+" Maintainer:	Melchior FRANZ <mfranz@aon.at>
+" Last Change:	2003 Aug 14
+" Author:	Sonia Heimann
+
+" For version 5.x: Clear all syntax items
+" For version 6.x: Quit when a syntax file was already loaded
+if version < 600
+  syntax clear
+elseif exists("b:current_syntax")
+  finish
+endif
+
+syn match   procmailComment      "#.*$" contains=procmailTodo
+syn keyword   procmailTodo      contained Todo TBD
+
+syn region  procmailString       start=+"+  skip=+\\"+  end=+"+
+syn region  procmailString       start=+'+  skip=+\\'+  end=+'+
+
+syn region procmailVarDeclRegion start="^\s*[a-zA-Z0-9_]\+\s*="hs=e-1 skip=+\\$+ end=+$+ contains=procmailVar,procmailVarDecl,procmailString
+syn match procmailVarDecl contained "^\s*[a-zA-Z0-9_]\+"
+syn match procmailVar "$[a-zA-Z0-9_]\+"
+
+syn match procmailCondition contained "^\s*\*.*"
+
+syn match procmailActionFolder contained "^\s*[-_a-zA-Z0-9/]\+"
+syn match procmailActionVariable contained "^\s*$[a-zA-Z_]\+"
+syn region procmailActionForward start=+^\s*!+ skip=+\\$+ end=+$+
+syn region procmailActionPipe start=+^\s*|+ skip=+\\$+ end=+$+
+syn region procmailActionNested start=+^\s*{+ end=+^\s*}+ contains=procmailRecipe,procmailComment,procmailVarDeclRegion
+
+syn region procmailRecipe start=+^\s*:.*$+ end=+^\s*\($\|}\)+me=e-1 contains=procmailComment,procmailCondition,procmailActionFolder,procmailActionVariable,procmailActionForward,procmailActionPipe,procmailActionNested,procmailVarDeclRegion
+
+" Define the default highlighting.
+" For version 5.7 and earlier: only when not done already
+" For version 5.8 and later: only when an item doesn't have highlighting yet
+if version >= 508 || !exists("did_procmail_syntax_inits")
+  if version < 508
+    let did_procmail_syntax_inits = 1
+    command -nargs=+ HiLink hi link <args>
+  else
+    command -nargs=+ HiLink hi def link <args>
+  endif
+
+  HiLink procmailComment Comment
+  HiLink procmailTodo    Todo
+
+  HiLink procmailRecipe   Statement
+  "HiLink procmailCondition   Statement
+
+  HiLink procmailActionFolder	procmailAction
+  HiLink procmailActionVariable procmailAction
+  HiLink procmailActionForward	procmailAction
+  HiLink procmailActionPipe	procmailAction
+  HiLink procmailAction		Function
+  HiLink procmailVar		Identifier
+  HiLink procmailVarDecl	Identifier
+
+  HiLink procmailString String
+
+  delcommand HiLink
+endif
+
+let b:current_syntax = "procmail"
+
+" vim: ts=8
--- /dev/null
+++ b/lib/vimfiles/syntax/progress.vim
@@ -1,0 +1,231 @@
+" Vim syntax file
+" Language:		Progress 4GL
+" Filename extensions:	*.p (collides with Pascal),
+"			*.i (collides with assembler)
+"			*.w (collides with cweb)
+" Maintainer:		Philip Uren		<philuSPAX@ieee.org> Remove "SPAX" spam block
+" Contributors:         Chris Ruprecht		<chrup@mac.com> (Chris, where are you now?)
+"			Mikhail Kuperblum	<mikhail@whasup.com>
+"			John Florian		<jflorian@voyager.net>
+" Last Change:		Wed Apr 12 08:55:35 EST 2006
+" $Id: progress.vim,v 1.3 2006/04/12 21:48:47 vimboss Exp $
+
+" For version 5.x: Clear all syntax items
+" For version 6.x: Quit when a syntax file was already loaded
+if version < 600
+	syntax clear
+elseif exists("b:current_syntax")
+	finish
+endif
+
+if version >= 600
+  setlocal iskeyword=@,48-57,_,-,!,#,$,%
+else
+  set iskeyword=@,48-57,_,-,!,#,$,%
+endif
+
+" The Progress editor doesn't cope with tabs very well.
+set expandtab
+
+syn case ignore
+
+" Progress Blocks of code and mismatched "end." errors.
+syn match	ProgressEndError	"\<end\>"
+syn region	ProgressDoBlock		transparent matchgroup=ProgressDo start="\<do\>" matchgroup=ProgressDo end="\<end\>" contains=ALLBUT,ProgressProcedure,ProgressFunction
+syn region	ProgressForBlock	transparent matchgroup=ProgressFor start="\<for\>" matchgroup=ProgressFor end="\<end\>" contains=ALLBUT,ProgressProcedure,ProgressFunction
+syn region	ProgressRepeatBlock	transparent matchgroup=ProgressRepeat start="\<repeat\>" matchgroup=ProgressRepeat end="\<end\>" contains=ALLBUT,ProgressProcedure,ProgressFunction
+syn region	ProgressCaseBlock	transparent matchgroup=ProgressCase start="\<case\>" matchgroup=ProgressCase end="\<end\scase\>\|\<end\>" contains=ALLBUT,ProgressProcedure,ProgressFunction
+
+" These are Progress reserved words,
+" and they could go in ProgressReserved,
+" but I found it more helpful to highlight them in a different color.
+syn keyword	ProgressConditional	if else then when otherwise
+syn keyword	ProgressFor		each where
+
+" Make those TODO and debugging notes stand out!
+syn keyword	ProgressTodo		contained	TODO BUG FIX
+syn keyword	ProgressDebug		contained	DEBUG
+syn keyword	ProgressDebug		debugger
+syn match  	ProgressTodo            contained	"NEED[S]*\s\s*WORK"
+
+" If you like to highlight the whole line of
+" the start and end of procedures
+" to make the whole block of code stand out:
+syn match	ProgressProcedure	"^\s*procedure.*"
+syn match	ProgressProcedure	"^\s*end\s\s*procedure.*"
+syn match	ProgressFunction	"^\s*function.*"
+syn match	ProgressFunction	"^\s*end\s\s*function.*"
+" ... otherwise use this:
+" syn keyword ProgressFunction	procedure function
+
+syn keyword	ProgressReserved	accum[ulate] active-window add alias all alter ambig[uous] analyz[e] and any apply as asc[ending] assign at attr[-space]
+syn keyword	ProgressReserved	authorization auto-ret[urn] avail[able] back[ground] before-h[ide] begins bell between blank break btos by call can-do can-find
+syn keyword	ProgressReserved	center[ed] character check chr clear clipboard col colon color col[umn] column-lab[el] col[umns] compiler connected control count-of
+syn keyword	ProgressReserved	cpstream create ctos current current-changed current-lang[uage] current-window current_date curs[or] database dataservers
+syn keyword	ProgressReserved	dbcodepage dbcollation dbname dbrest[rictions] dbtaskid dbtype dbvers[ion] dde deblank debug-list debugger decimal decimals declare
+syn keyword	ProgressReserved	def default default-noxl[ate] default-window def[ine] delete delimiter desc[ending] dict[ionary] disable discon[nect] disp
+syn keyword	ProgressReserved	disp[lay] distinct dos down drop editing enable encode entry error-stat[us] escape etime except exclusive
+syn keyword	ProgressReserved	exclusive[-lock] exclusive-web-us[er] exists export false fetch field field[s] file-info[rmation] fill find find-case-sensitive
+syn keyword	ProgressReserved	find-global find-next-occurrence find-prev-occurrence find-select find-wrap-around first first-of focus font form form[at]
+syn keyword	ProgressReserved	fram[e] frame-col frame-db frame-down frame-field frame-file frame-inde[x] frame-line frame-name frame-row frame-val[ue]
+syn keyword	ProgressReserved	from from-c[hars] from-p[ixels] gateway[s] get-byte get-codepage[s] get-coll[ations] get-key-val[ue] getbyte global go-on
+syn keyword	ProgressReserved	go-pend[ing] grant graphic-e[dge] group having header help hide import in index indicator input input-o[utput] insert
+syn keyword	ProgressReserved	integer into is is-attr[-space] join kblabel key-code key-func[tion] key-label keycode keyfunc[tion] keylabel keys keyword label
+syn keyword	ProgressReserved	last last-even[t] last-key last-of lastkey ldbname leave library like line-count[er] listi[ng] locked lookup machine-class
+syn keyword	ProgressReserved	map member message message-lines mouse mpe new next next-prompt no no-attr[-space] no-error no-f[ill] no-help no-hide no-label[s]
+syn keyword	ProgressReserved	no-lock no-map no-mes[sage] no-pause no-prefe[tch] no-undo no-val[idate] no-wait not null num-ali[ases] num-dbs num-entries
+syn keyword	ProgressReserved	of off old on open opsys option or os-append os-command os-copy os-create-dir os-delete os-dir os-drive[s] os-error os-rename
+syn keyword	ProgressReserved	os2 os400 output overlay page page-bot[tom] page-num[ber] page-top param[eter] pause pdbname persist[ent] pixels
+syn keyword	ProgressReserved	preproc[ess] privileges proc-ha[ndle] proc-st[atus] process program-name Progress prompt prompt[-for] promsgs propath provers[ion]
+syn keyword	ProgressReserved	put put-byte put-key-val[ue] putbyte query query-tuning quit r-index rcode-informatio[n] readkey recid record-len[gth] rect[angle]
+syn keyword	ProgressReserved	release reposition retain retry return return-val[ue] revert revoke run save schema screen screen-io screen-lines
+syn keyword	ProgressReserved	scroll sdbname search seek select self session set setuser[id] share[-lock] shared show-stat[s] skip some space status stream
+syn keyword	ProgressReserved	stream-io string-xref system-dialog table term term[inal] text text-cursor text-seg[-growth] this-procedure time title
+syn keyword	ProgressReserved	to today top-only trans trans[action] trigger triggers trim true underl[ine] undo unform[atted] union unique unix up update
+syn keyword	ProgressReserved	use-index use-revvideo use-underline user user[id] using v6frame value values variable view view-as vms wait-for web-con[text]
+syn keyword	ProgressReserved	window window-maxim[ized] window-minim[ized] window-normal with work-tab[le] workfile write xcode xref yes _cbit
+syn keyword	ProgressReserved	_control _list _memory _msg _pcontrol _serial[-num] _trace 
+
+" Strings. Handles embedded quotes.
+" Note that, for some reason, Progress doesn't use the backslash, "\"
+" as the escape character; it uses tilde, "~".
+syn region	ProgressString		matchgroup=ProgressQuote	start=+"+ end=+"+	skip=+\~'\|\~\~+
+syn region	ProgressString		matchgroup=ProgressQuote	start=+'+ end=+'+	skip=+\~'\|\~\~+
+
+syn match	ProgressIdentifier	"\<[a-zA-Z_%#]+\>()"
+
+" syn match	ProgressDelimiter	"()"
+
+syn match	ProgressMatrixDelimiter	"[][]"
+" If you prefer you can highlight the range
+"syn match	ProgressMatrixDelimiter	"[\d\+\.\.\d\+]"
+
+syn match	ProgressNumber		"\<\-\=\d\+\(u\=l\=\|lu\|f\)\>"
+syn match	ProgressByte		"\$[0-9a-fA-F]\+"
+
+" More values: Logicals, and Progress's unknown value, ?.
+syn match	ProgressNumber		"?"
+syn keyword	ProgressNumber		true false yes no
+
+" If you don't like tabs:
+syn match	ProgressShowTab		"\t"
+
+" If you don't like white space on the end of lines:
+" syn match	ProgressSpaceError	"\s\+$"
+
+syn region	ProgressComment		start="/\*" end="\*/" contains=ProgressComment,ProgressTodo,ProgressDebug
+syn region	ProgressInclude		start="^[ 	]*[{][^&]" end="[}]" contains=ProgressPreProc,ProgressOperator,ProgressString,ProgressComment
+syn region	ProgressPreProc		start="&" end="\>" contained
+
+" This next line works reasonably well.
+" syn match	ProgressOperator        "[!;|)(:.><+*=-]"
+"
+" Progress allows a '-' to be part of an identifier.  To be considered
+" the subtraction/negation operation operator it needs a non-word
+" character on either side.  Also valid are cases where the minus
+" operation appears at the beginning or end of a line.
+" This next line trips up on "no-undo" etc.
+" syn match	ProgressOperator	"[!;|)(:.><+*=]\|\W-\W\|^-\W\|\W-$"
+syn match	ProgressOperator	"[!;|)(:.><+*=]\|\s-\s\|^-\s\|\s-$"
+
+syn keyword	ProgressOperator	<= <> >= abs[olute] accelerator across add-first add-last advise alert-box allow-replication ansi-only anywhere append appl-alert[-boxes] application as-cursor ask-overwrite
+syn keyword	ProgressOperator	attach[ment] auto-end-key auto-endkey auto-go auto-ind[ent] auto-resize auto-z[ap] available-formats ave[rage] avg backward[s] base-key batch[-mode] bgc[olor] binary
+syn keyword	ProgressOperator	bind-where block-iteration-display border-bottom border-bottom-ch[ars] border-bottom-pi[xels] border-left border-left-char[s] border-left-pixe[ls] border-right border-right-cha[rs]
+syn keyword	ProgressOperator	border-right-pix[els] border-t[op] border-t[op-chars] border-top-pixel[s] both bottom box box-select[able] browse browse-header buffer buffer-chars buffer-lines
+syn keyword	ProgressOperator	button button[s] byte cache cache-size can-query can-set cancel-break cancel-button caps careful-paint case-sensitive cdecl char[acter] character_length charset
+syn keyword	ProgressOperator	checked choose clear-select[ion] close code codepage codepage-convert col-of colon-align[ed] color-table column-bgc[olor] column-dcolor column-fgc[olor] column-font
+syn keyword	ProgressOperator	column-label-bgc[olor] column-label-dcolor column-label-fgc[olor] column-label-font column-of column-pfc[olor] column-sc[rolling] combo-box command compile complete
+syn keyword	ProgressOperator	connect constrained contents context context-pop[up] control-containe[r] c[ontrol-form] convert-to-offse[t] convert count cpcase cpcoll cpint[ernal] cplog
+syn keyword	ProgressOperator	cpprint cprcodein cprcodeout cpterm crc-val[ue] c[reate-control] create-result-list-entry create-test-file current-column current-environm[ent] current-iteration
+syn keyword	ProgressOperator	current-result-row current-row-modified current-value cursor-char cursor-line cursor-offset data-entry-retur[n] data-t[ype] date date-f[ormat] day db-references
+syn keyword	ProgressOperator	dcolor dde-error dde-i[d] dde-item dde-name dde-topic debu[g] dec[imal] default-b[utton] default-extensio[n] defer-lob-fetch define defined delete-char delete-current-row
+syn keyword	ProgressOperator	delete-line delete-selected-row delete-selected-rows deselect-focused-row deselect-rows deselect-selected-row d[esign-mode] dialog-box dialog-help dir disabled display-message
+syn keyword	ProgressOperator	display-t[ype] double drag-enabled drop-down drop-down-list dump dynamic echo edge edge[-chars] edge-p[ixels] editor empty end-key endkey entered eq error error-col[umn]
+syn keyword	ProgressOperator	error-row event-t[ype] event[s] exclusive-id execute exp expand extended extent external extract fetch-selected-row fgc[olor] file file-name file-off[set] file-type
+syn keyword	ProgressOperator	filename fill-in filled filters first-child first-column first-proc[edure] first-tab-i[tem] fixed-only float focused-row font-based-layout font-table force-file
+syn keyword	ProgressOperator	fore[ground] form-input forward[s] frame-spa[cing] frame-x frame-y frequency from-cur[rent] full-height full-height-char[s] full-height-pixe[ls] full-pathn[ame]
+syn keyword	ProgressOperator	full-width full-width[-chars] full-width-pixel[s] ge get get-blue[-value] g[et-char-property] get-double get-dynamic get-file get-float get-green[-value]
+syn keyword	ProgressOperator	get-iteration get-license get-long get-message get-number get-pointer-value get-red[-value] get-repositioned-row get-selected-wid[get] get-short get-signature get-size
+syn keyword	ProgressOperator	get-string get-tab-item get-text-height get-text-height-char[s] get-text-height-pixe[ls] get-text-width get-text-width-c[hars] get-text-width-pixel[s] get-unsigned-short
+syn keyword	ProgressOperator	grayed grid-factor-horizont[al] grid-factor-vert[ical] grid-set grid-snap grid-unit-height grid-unit-height-cha[rs] grid-unit-height-pix[els] grid-unit-width grid-unit-width-char[s]
+syn keyword	ProgressOperator	grid-unit-width-pixe[ls] grid-visible gt handle height height[-chars] height-p[ixels] help-con[text] helpfile-n[ame] hidden hint hori[zontal] hwnd image image-down
+syn keyword	ProgressOperator	image-insensitive image-size image-size-c[hars] image-size-pixel[s] image-up immediate-display index-hint indexed-reposition info[rmation] init init[ial] initial-dir
+syn keyword	ProgressOperator	initial-filter initiate inner inner-chars inner-lines insert-b[acktab] insert-file insert-row insert-string insert-t[ab] int[eger] internal-entries is-lead-byte
+syn keyword	ProgressOperator	is-row-selected is-selected item items-per-row join-by-sqldb keep-frame-z-ord[er] keep-messages keep-tab-order key keyword-all label-bgc[olor] label-dc[olor] label-fgc[olor]
+syn keyword	ProgressOperator	label-font label-pfc[olor] labels language[s] large large-to-small last-child last-tab-i[tem] last-proce[dure] lc le leading left left-align[ed] left-trim length
+syn keyword	ProgressOperator	line list-events list-items list-query-attrs list-set-attrs list-widgets load l[oad-control] load-icon load-image load-image-down load-image-insensitive load-image-up
+syn keyword	ProgressOperator	load-mouse-point[er] load-small-icon log logical lookahead lower lt manual-highlight margin-extra margin-height margin-height-ch[ars] margin-height-pi[xels] margin-width
+syn keyword	ProgressOperator	margin-width-cha[rs] margin-width-pix[els] matches max max-chars max-data-guess max-height max-height[-chars] max-height-pixel[s] max-rows max-size max-val[ue] max-width
+syn keyword	ProgressOperator	max-width[-chars] max-width-p[ixels] maximize max[imum] memory menu menu-bar menu-item menu-k[ey] menu-m[ouse] menubar message-area message-area-font message-line
+syn keyword	ProgressOperator	min min-height min-height[-chars] min-height-pixel[s] min-size min-val[ue] min-width min-width[-chars] min-width-p[ixels] min[imum] mod modified mod[ulo] month mouse-p[ointer]
+syn keyword	ProgressOperator	movable move-after-tab-i[tem] move-before-tab-[item] move-col[umn] move-to-b[ottom] move-to-eof move-to-t[op] multiple multiple-key multitasking-interval must-exist
+syn keyword	ProgressOperator	name native ne new-row next-col[umn] next-sibling next-tab-ite[m] next-value no-apply no-assign no-bind-where no-box no-column-scroll[ing] no-convert no-current-value
+syn keyword	ProgressOperator	no-debug no-drag no-echo no-index-hint no-join-by-sqldb no-lookahead no-row-markers no-scrolling no-separate-connection no-separators no-und[erline] no-word-wrap
+syn keyword	ProgressOperator	none num-but[tons] num-col[umns] num-copies num-formats num-items num-iterations num-lines num-locked-colum[ns] num-messages num-results num-selected num-selected-rows
+syn keyword	ProgressOperator	num-selected-widgets num-tabs num-to-retain numeric numeric-f[ormat] octet_length ok ok-cancel on-frame[-border] ordered-join ordinal orientation os-getenv outer
+syn keyword	ProgressOperator	outer-join override owner page-size page-wid[th] paged parent partial-key pascal pathname pfc[olor] pinnable pixels-per-colum[n] pixels-per-row popup-m[enu] popup-o[nly]
+syn keyword	ProgressOperator	position precision presel[ect] prev prev-col[umn] prev-sibling prev-tab-i[tem] primary printer-control-handle printer-setup private-d[ata] profiler Progress-s[ource]
+syn keyword	ProgressOperator	publish put-double put-float put-long put-short put-string put-unsigned-short query-off-end question radio-buttons radio-set random raw raw-transfer read-file read-only
+syn keyword	ProgressOperator	real recursive refresh refreshable replace replace-selection-text replication-create replication-delete replication-write request resiza[ble] resize retry-cancel
+syn keyword	ProgressOperator	return-ins[erted] return-to-start-di[r] reverse-from right right-align[ed] right-trim round row row-ma[rkers] row-of rowid rule rule-row rule-y save-as save-file
+syn keyword	ProgressOperator	screen-val[ue] scroll-bars scroll-delta scroll-horiz-value scroll-offset scroll-to-current-row scroll-to-i[tem] scroll-to-selected-row scroll-vert-value scrollable
+syn keyword	ProgressOperator	scrollbar-horizo[ntal] scrollbar-vertic[al] scrolled-row-positio[n] scrolling se-check-pools se-enable-of[f] se-enable-on se-num-pools se-use-messa[ge] section select-focused-row
+syn keyword	ProgressOperator	select-next-row select-prev-row select-repositioned-row select-row selectable selected selected-items selection-end selection-list selection-start selection-text
+syn keyword	ProgressOperator	send sensitive separate-connection separators set-blue[-value] set-break set-cell-focus set-contents set-dynamic set-green[-value] set-leakpoint set-pointer-valu[e]
+syn keyword	ProgressOperator	s[et-property] set-red[-value] set-repositioned-row set-selection set-size set-wait[-state] side-lab side-lab[e] side-lab[el] side-label-handl[e] side-lab[els] silent
+syn keyword	ProgressOperator	simple single size size-c[hars] size-p[ixels] slider smallint sort source source-procedure sql sqrt start status-area status-area-font status-bar stdcall stenciled stop stoppe[d]
+syn keyword	ProgressOperator	stored-proc[edure] string sub-ave[rage] sub-count sub-max[imum] sub-me[nu] sub-menu-help sub-min[imum] sub-total subscribe subst[itute] substr[ing] subtype sum super suppress-warning[s]
+syn keyword	ProgressOperator	system-alert-box[es] system-help tab-position tabbable target target-procedure temp-dir[ectory] temp-table terminate text-selected three-d through thru tic-marks time-source title-bgc[olor]
+syn keyword	ProgressOperator	title-dc[olor] title-fgc[olor] title-fo[nt] to-rowid toggle-box tool-bar top topic total trailing trunc[ate] type unbuff[ered] unique-id unload unsubscribe upper use use-dic[t-exps]
+syn keyword	ProgressOperator	use-filename use-text v6display valid-event valid-handle validate validate-condition validate-message var[iable] vert[ical] virtual-height virtual-height-c[hars]
+syn keyword	ProgressOperator	virtual-height-pixel[s] virtual-width virtual-width-ch[ars] virtual-width-pi[xels] visible wait warning weekday widget widget-e[nter] widget-h[andle] widget-l[eave]
+syn keyword	ProgressOperator	widget-pool width width[-chars] width-p[ixels] window-name window-sta[te] window-sys[tem] word-wrap x-of y-of year yes-no yes-no-cancel _dcm
+
+syn keyword	ProgressType		char[acter] int[eger] format
+syn keyword	ProgressType		var[iable] log[ical] da[te]
+
+syn sync lines=800
+
+" Define the default highlighting.
+" For version 5.7 and earlier: only when not done already
+" For version 5.8 and later: only when an item doesn't have highlighting yet
+if version >= 508 || !exists("did_progress_syntax_inits")
+  if version < 508
+	let did_progress_syntax_inits = 1
+	command -nargs=+ HiLink hi link <args>
+  else
+	command -nargs=+ HiLink hi def link <args>
+  endif
+
+  " The default methods for highlighting. Can be overridden later.
+  HiLink ProgressByte			Number
+  HiLink ProgressCase			Repeat
+  HiLink ProgressComment		Comment
+  HiLink ProgressConditional		Conditional
+  HiLink ProgressDebug			Debug
+  HiLink ProgressDo			Repeat
+  HiLink ProgressEndError		Error
+  HiLink ProgressFor			Repeat
+  HiLink ProgressFunction		Procedure
+  HiLink ProgressIdentifier		Identifier
+  HiLink ProgressInclude		Include
+  HiLink ProgressMatrixDelimiter	Identifier
+  HiLink ProgressNumber			Number
+  HiLink ProgressOperator		Operator
+  HiLink ProgressPreProc		PreProc
+  HiLink ProgressProcedure		Procedure
+  HiLink ProgressQuote			Delimiter
+  HiLink ProgressRepeat			Repeat
+  HiLink ProgressReserved		Statement
+  HiLink ProgressSpaceError		Error
+  HiLink ProgressString			String
+  HiLink ProgressTodo			Todo
+  HiLink ProgressType			Statement
+  HiLink ProgressShowTab		Error
+
+  delcommand HiLink
+endif
+
+let b:current_syntax = "progress"
+
+" vim: ts=8 sw=8
--- /dev/null
+++ b/lib/vimfiles/syntax/prolog.vim
@@ -1,0 +1,119 @@
+" Vim syntax file
+" Language:    PROLOG
+" Maintainers: Thomas Koehler <jean-luc@picard.franken.de>
+" Last Change: 2005 Mar 14
+" URL:	       http://gott-gehabt/800_wer_wir_sind/thomas/Homepage/Computer/vim/syntax/prolog.vim
+
+" There are two sets of highlighting in here:
+" If the "prolog_highlighting_clean" variable exists, it is rather sparse.
+" Otherwise you get more highlighting.
+
+" Quit when a syntax file was already loaded
+if version < 600
+   syntax clear
+elseif exists("b:current_syntax")
+  finish
+endif
+
+" Prolog is case sensitive.
+syn case match
+
+" Very simple highlighting for comments, clause heads and
+" character codes.  It respects prolog strings and atoms.
+
+syn region   prologCComment	start=+/\*+ end=+\*/+
+syn match    prologComment	+%.*+
+
+syn keyword  prologKeyword	module meta_predicate multifile dynamic
+syn match    prologCharCode	+0'\\\=.+
+syn region   prologString	start=+"+ skip=+\\"+ end=+"+
+syn region   prologAtom		start=+'+ skip=+\\'+ end=+'+
+syn region   prologClauseHead   start=+^[a-z][^(]*(+ skip=+\.[^			    ]+ end=+:-\|\.$\|\.[	]\|-->+
+
+if !exists("prolog_highlighting_clean")
+
+  " some keywords
+  " some common predicates are also highlighted as keywords
+  " is there a better solution?
+  syn keyword prologKeyword   abolish current_output  peek_code
+  syn keyword prologKeyword   append  current_predicate       put_byte
+  syn keyword prologKeyword   arg     current_prolog_flag     put_char
+  syn keyword prologKeyword   asserta fail    put_code
+  syn keyword prologKeyword   assertz findall read
+  syn keyword prologKeyword   at_end_of_stream	      float   read_term
+  syn keyword prologKeyword   atom    flush_output    repeat
+  syn keyword prologKeyword   atom_chars      functor retract
+  syn keyword prologKeyword   atom_codes      get_byte	      set_input
+  syn keyword prologKeyword   atom_concat     get_char	      set_output
+  syn keyword prologKeyword   atom_length     get_code	      set_prolog_flag
+  syn keyword prologKeyword   atomic  halt    set_stream_position
+  syn keyword prologKeyword   bagof   integer setof
+  syn keyword prologKeyword   call    is      stream_property
+  syn keyword prologKeyword   catch   nl      sub_atom
+  syn keyword prologKeyword   char_code       nonvar  throw
+  syn keyword prologKeyword   char_conversion number  true
+  syn keyword prologKeyword   clause  number_chars    unify_with_occurs_check
+  syn keyword prologKeyword   close   number_codes    var
+  syn keyword prologKeyword   compound	      once    write
+  syn keyword prologKeyword   copy_term       op      write_canonical
+  syn keyword prologKeyword   current_char_conversion open    write_term
+  syn keyword prologKeyword   current_input   peek_byte       writeq
+  syn keyword prologKeyword   current_op      peek_char
+
+  syn match   prologOperator "=\\=\|=:=\|\\==\|=<\|==\|>=\|\\=\|\\+\|<\|>\|="
+  syn match   prologAsIs     "===\|\\===\|<=\|=>"
+
+  syn match   prologNumber	      "\<[0123456789]*\>"
+  syn match   prologCommentError      "\*/"
+  syn match   prologSpecialCharacter  ";"
+  syn match   prologSpecialCharacter  "!"
+  syn match   prologQuestion	      "?-.*\."	contains=prologNumber
+
+
+endif
+
+syn sync maxlines=50
+
+
+" Define the default highlighting.
+" For version 5.7 and earlier: only when not done already
+" For version 5.8 and later: only when an item doesn't have highlighting yet
+if version >= 508 || !exists("did_prolog_syn_inits")
+  if version < 508
+    let did_prolog_syn_inits = 1
+    command -nargs=+ HiLink hi link <args>
+  else
+    command -nargs=+ HiLink hi def link <args>
+  endif
+
+  " The default highlighting.
+  HiLink prologComment		Comment
+  HiLink prologCComment		Comment
+  HiLink prologCharCode		Special
+
+  if exists ("prolog_highlighting_clean")
+
+    HiLink prologKeyword	Statement
+    HiLink prologClauseHead	Statement
+
+  else
+
+    HiLink prologKeyword	Keyword
+    HiLink prologClauseHead	Constant
+    HiLink prologQuestion	PreProc
+    HiLink prologSpecialCharacter Special
+    HiLink prologNumber		Number
+    HiLink prologAsIs		Normal
+    HiLink prologCommentError	Error
+    HiLink prologAtom		String
+    HiLink prologString		String
+    HiLink prologOperator	Operator
+
+  endif
+
+  delcommand HiLink
+endif
+
+let b:current_syntax = "prolog"
+
+" vim: ts=8
--- /dev/null
+++ b/lib/vimfiles/syntax/protocols.vim
@@ -1,0 +1,44 @@
+" Vim syntax file
+" Language:         protocols(5) - Internet protocols definition file
+" Maintainer:       Nikolai Weibull <now@bitwi.se>
+" Latest Revision:  2006-04-19
+
+if exists("b:current_syntax")
+  finish
+endif
+
+let s:cpo_save = &cpo
+set cpo&vim
+
+syn match   protocolsBegin    display '^'
+                              \ nextgroup=protocolsName,protocolsComment
+
+syn match   protocolsName     contained display '[[:graph:]]\+'
+                              \ nextgroup=protocolsPort skipwhite
+
+syn match   protocolsPort     contained display '\d\+'
+                              \ nextgroup=protocolsAliases,protocolsComment
+                              \ skipwhite
+
+syn match   protocolsAliases  contained display '\S\+'
+                              \ nextgroup=protocolsAliases,protocolsComment
+                              \ skipwhite
+
+syn keyword protocolsTodo     contained TODO FIXME XXX NOTE
+
+syn region  protocolsComment  display oneline start='#' end='$'
+                              \ contains=protocolsTodo,@Spell
+
+hi def link protocolsTodo      Todo
+hi def link protocolsComment   Comment
+hi def link protocolsName      Identifier
+hi def link protocolsPort      Number
+hi def link protocolsPPDiv     Delimiter
+hi def link protocolsPPDivDepr Error
+hi def link protocolsProtocol  Type
+hi def link protocolsAliases   Macro
+
+let b:current_syntax = "protocols"
+
+let &cpo = s:cpo_save
+unlet s:cpo_save
--- /dev/null
+++ b/lib/vimfiles/syntax/psf.vim
@@ -1,0 +1,103 @@
+" Vim syntax file
+" Language:	Software Distributor product specification file
+"		(POSIX 1387.2-1995).
+" Maintainer:	Rex Barzee <rex_barzee@hp.com>
+" Last change:	25 Apr 2001
+
+if version < 600
+  " Remove any old syntax stuff hanging around
+  syn clear
+elseif exists("b:current_syntax")
+  finish
+endif
+
+" Product specification files are case sensitive
+syn case match
+
+syn keyword psfObject bundle category control_file depot distribution
+syn keyword psfObject end file fileset host installed_software media
+syn keyword psfObject product root subproduct vendor
+
+syn match  psfUnquotString +[^"# 	][^#]*+ contained
+syn region psfQuotString   start=+"+ skip=+\\"+ end=+"+ contained
+
+syn match  psfObjTag    "\<[-_+A-Z0-9a-z]\+\(\.[-_+A-Z0-9a-z]\+\)*" contained
+syn match  psfAttAbbrev ",\<\(fa\|fr\|[aclqrv]\)\(<\|>\|<=\|>=\|=\|==\)[^,]\+" contained
+syn match  psfObjTags   "\<[-_+A-Z0-9a-z]\+\(\.[-_+A-Z0-9a-z]\+\)*\(\s\+\<[-_+A-Z0-9a-z]\+\(\.[-_+A-Z0-9a-z]\+\)*\)*" contained
+
+syn match  psfNumber    "\<\d\+\>" contained
+syn match  psfFloat     "\<\d\+\>\(\.\<\d\+\>\)*" contained
+
+syn match  psfLongDate  "\<\d\d\d\d\d\d\d\d\d\d\d\d\.\d\d\>" contained
+
+syn keyword psfState    available configured corrupt installed transient contained
+syn keyword psfPState   applied committed superseded contained
+
+syn keyword psfBoolean  false true contained
+
+
+"Some of the attributes covered by attUnquotString and attQuotString:
+" architecture category_tag control_directory copyright
+" create_date description directory file_permissions install_source
+" install_type location machine_type mod_date number os_name os_release
+" os_version pose_as_os_name pose_as_os_release readme revision
+" share_link title vendor_tag
+syn region psfAttUnquotString matchgroup=psfAttrib start=~^\s*[^# 	]\+\s\+[^#" 	]~rs=e-1 contains=psfUnquotString,psfComment end=~$~ keepend oneline
+
+syn region psfAttQuotString matchgroup=psfAttrib start=~^\s*[^# 	]\+\s\+"~rs=e-1 contains=psfQuotString,psfComment skip=~\\"~ matchgroup=psfQuotString end=~"~ keepend
+
+
+" These regions are defined in attempt to do syntax checking for some
+" of the attributes.
+syn region psfAttTag matchgroup=psfAttrib start="^\s*tag\s\+" contains=psfObjTag,psfComment end="$" keepend oneline
+
+syn region psfAttSpec matchgroup=psfAttrib start="^\s*\(ancestor\|applied_patches\|applied_to\|contents\|corequisites\|exrequisites\|prerequisites\|software_spec\|supersedes\|superseded_by\)\s\+" contains=psfObjTag,psfAttAbbrev,psfComment end="$" keepend
+
+syn region psfAttTags matchgroup=psfAttrib start="^\s*all_filesets\s\+" contains=psfObjTags,psfComment end="$" keepend
+
+syn region psfAttNumber matchgroup=psfAttrib start="^\s*\(compressed_size\|instance_id\|media_sequence_number\|sequence_number\|size\)\s\+" contains=psfNumber,psfComment end="$" keepend oneline
+
+syn region psfAttTime matchgroup=psfAttrib start="^\s*\(create_time\|ctime\|mod_time\|mtime\|timestamp\)\s\+" contains=psfNumber,psfComment end="$" keepend oneline
+
+syn region psfAttFloat matchgroup=psfAttrib start="^\s*\(data_model_revision\|layout_version\)\s\+" contains=psfFloat,psfComment end="$" keepend oneline
+
+syn region psfAttLongDate matchgroup=psfAttrib start="^\s*install_date\s\+" contains=psfLongDate,psfComment end="$" keepend oneline
+
+syn region psfAttState matchgroup=psfAttrib start="^\s*\(state\)\s\+" contains=psfState,psfComment end="$" keepend oneline
+
+syn region psfAttPState matchgroup=psfAttrib start="^\s*\(patch_state\)\s\+" contains=psfPState,psfComment end="$" keepend oneline
+
+syn region psfAttBoolean matchgroup=psfAttrib start="^\s*\(is_kernel\|is_locatable\|is_patch\|is_protected\|is_reboot\|is_reference\|is_secure\|is_sparse\)\s\+" contains=psfBoolean,psfComment end="$" keepend oneline
+
+syn match  psfComment "#.*$"
+
+
+" Define the default highlighting.
+" For version 5.7 and earlier: only when not done already
+" For version 5.8 and later: only when an item doesn't have highlighting yet
+if version >= 508 || !exists("did_psf_syntax_inits")
+  if version < 508
+    let did_psf_syntax_inits = 1
+    command -nargs=+ HiLink hi link <args>
+  else
+    command -nargs=+ HiLink hi def link <args>
+  endif
+
+  HiLink psfObject       Statement
+  HiLink psfAttrib       Type
+  HiLink psfQuotString   String
+  HiLink psfObjTag       Identifier
+  HiLink psfAttAbbrev    PreProc
+  HiLink psfObjTags      Identifier
+
+  HiLink psfComment      Comment
+
+  delcommand HiLink
+endif
+
+" Long descriptions and copyrights confuse the syntax highlighting, so
+" force vim to backup at least 100 lines before the top visible line
+" looking for a sync location.
+syn sync lines=100
+
+let b:current_syntax = "psf"
--- /dev/null
+++ b/lib/vimfiles/syntax/ptcap.vim
@@ -1,0 +1,107 @@
+" Vim syntax file
+" Language:	printcap/termcap database
+" Maintainer:	Haakon Riiser <hakonrk@fys.uio.no>
+" URL:		http://folk.uio.no/hakonrk/vim/syntax/ptcap.vim
+" Last Change:	2001 May 15
+
+" For version 5.x: Clear all syntax items
+" For version 6.x: Quit when a syntax file was already loaded
+if version < 600
+    syn clear
+elseif exists("b:current_syntax")
+    finish
+endif
+
+" Since I only highlight based on the structure of the databases, not
+" specific keywords, case sensitivity isn't required
+syn case ignore
+
+" Since everything that is not caught by the syntax patterns is assumed
+" to be an error, we start parsing 20 lines up, unless something else
+" is specified
+if exists("ptcap_minlines")
+    exe "syn sync lines=".ptcap_minlines
+else
+    syn sync lines=20
+endif
+
+" Highlight everything that isn't caught by the rules as errors,
+" except blank lines
+syn match ptcapError	    "^.*\S.*$"
+
+syn match ptcapLeadBlank    "^\s\+" contained
+
+" `:' and `|' are delimiters for fields and names, and should not be
+" highlighted.	Hence, they are linked to `NONE'
+syn match ptcapDelimiter    "[:|]" contained
+
+" Escaped characters receive special highlighting
+syn match ptcapEscapedChar  "\\." contained
+syn match ptcapEscapedChar  "\^." contained
+syn match ptcapEscapedChar  "\\\o\{3}" contained
+
+" A backslash at the end of a line will suppress the newline
+syn match ptcapLineCont	    "\\$" contained
+
+" A number follows the same rules as an integer in C
+syn match ptcapNumber	    "#\(+\|-\)\=\d\+"lc=1 contained
+syn match ptcapNumberError  "#\d*[^[:digit:]:\\]"lc=1 contained
+syn match ptcapNumber	    "#0x\x\{1,8}"lc=1 contained
+syn match ptcapNumberError  "#0x\X"me=e-1,lc=1 contained
+syn match ptcapNumberError  "#0x\x\{9}"lc=1 contained
+syn match ptcapNumberError  "#0x\x*[^[:xdigit:]:\\]"lc=1 contained
+
+" The `@' operator clears a flag (i.e., sets it to zero)
+" The `#' operator assigns a following number to the flag
+" The `=' operator assigns a string to the preceding flag
+syn match ptcapOperator	    "[@#=]" contained
+
+" Some terminal capabilites have special names like `#5' and `@1', and we
+" need special rules to match these properly
+syn match ptcapSpecialCap   "\W[#@]\d" contains=ptcapDelimiter contained
+
+" If editing a termcap file, an entry in the database is terminated by
+" a (non-escaped) newline.  Otherwise, it is terminated by a line which
+" does not start with a colon (:)
+if exists("b:ptcap_type") && b:ptcap_type[0] == 't'
+    syn region ptcapEntry   start="^\s*[^[:space:]:]" end="[^\\]\(\\\\\)*$" end="^$" contains=ptcapNames,ptcapField,ptcapLeadBlank keepend
+else
+    syn region ptcapEntry   start="^\s*[^[:space:]:]"me=e-1 end="^\s*[^[:space:]:#]"me=e-1 contains=ptcapNames,ptcapField,ptcapLeadBlank,ptcapComment
+endif
+syn region ptcapNames	    start="^\s*[^[:space:]:]" skip="[^\\]\(\\\\\)*\\:" end=":"me=e-1 contains=ptcapDelimiter,ptcapEscapedChar,ptcapLineCont,ptcapLeadBlank,ptcapComment keepend contained
+syn region ptcapField	    start=":" skip="[^\\]\(\\\\\)*\\$" end="[^\\]\(\\\\\)*:"me=e-1 end="$" contains=ptcapDelimiter,ptcapString,ptcapNumber,ptcapNumberError,ptcapOperator,ptcapLineCont,ptcapSpecialCap,ptcapLeadBlank,ptcapComment keepend contained
+syn region ptcapString	    matchgroup=ptcapOperator start="=" skip="[^\\]\(\\\\\)*\\:" matchgroup=ptcapDelimiter end=":"me=e-1 matchgroup=NONE end="[^\\]\(\\\\\)*[^\\]$" end="^$" contains=ptcapEscapedChar,ptcapLineCont keepend contained
+syn region ptcapComment	    start="^\s*#" end="$" contains=ptcapLeadBlank
+
+if version >= 508 || !exists("did_ptcap_syntax_inits")
+    if version < 508
+	let did_ptcap_syntax_inits = 1
+	command -nargs=+ HiLink hi link <args>
+    else
+	command -nargs=+ HiLink hi def link <args>
+    endif
+
+    HiLink ptcapComment		Comment
+    HiLink ptcapDelimiter	Delimiter
+    " The highlighting of "ptcapEntry" should always be overridden by
+    " its contents, so I use Todo highlighting to indicate that there
+    " is work to be done with the syntax file if you can see it :-)
+    HiLink ptcapEntry		Todo
+    HiLink ptcapError		Error
+    HiLink ptcapEscapedChar	SpecialChar
+    HiLink ptcapField		Type
+    HiLink ptcapLeadBlank	NONE
+    HiLink ptcapLineCont	Special
+    HiLink ptcapNames		Label
+    HiLink ptcapNumber		NONE
+    HiLink ptcapNumberError	Error
+    HiLink ptcapOperator	Operator
+    HiLink ptcapSpecialCap	Type
+    HiLink ptcapString		NONE
+
+    delcommand HiLink
+endif
+
+let b:current_syntax = "ptcap"
+
+" vim: sts=4 sw=4 ts=8
--- /dev/null
+++ b/lib/vimfiles/syntax/purifylog.vim
@@ -1,0 +1,119 @@
+" Vim syntax file
+" Language:	purify log files
+" Maintainer:	Gautam H. Mudunuri <gmudunur@informatica.com>
+" Last Change:	2003 May 11
+
+" For version 5.x: Clear all syntax items
+" For version 6.x: Quit when a syntax file was already loaded
+if version < 600
+  syntax clear
+elseif exists("b:current_syntax")
+  finish
+endif
+
+" Purify header
+syn match purifyLogHeader      "^\*\*\*\*.*$"
+
+" Informational messages
+syn match purifyLogFIU "^FIU:.*$"
+syn match purifyLogMAF "^MAF:.*$"
+syn match purifyLogMIU "^MIU:.*$"
+syn match purifyLogSIG "^SIG:.*$"
+syn match purifyLogWPF "^WPF:.*$"
+syn match purifyLogWPM "^WPM:.*$"
+syn match purifyLogWPN "^WPN:.*$"
+syn match purifyLogWPR "^WPR:.*$"
+syn match purifyLogWPW "^WPW:.*$"
+syn match purifyLogWPX "^WPX:.*$"
+
+" Warning messages
+syn match purifyLogABR "^ABR:.*$"
+syn match purifyLogBSR "^BSR:.*$"
+syn match purifyLogBSW "^BSW:.*$"
+syn match purifyLogFMR "^FMR:.*$"
+syn match purifyLogMLK "^MLK:.*$"
+syn match purifyLogMSE "^MSE:.*$"
+syn match purifyLogPAR "^PAR:.*$"
+syn match purifyLogPLK "^PLK:.*$"
+syn match purifyLogSBR "^SBR:.*$"
+syn match purifyLogSOF "^SOF:.*$"
+syn match purifyLogUMC "^UMC:.*$"
+syn match purifyLogUMR "^UMR:.*$"
+
+" Corrupting messages
+syn match purifyLogABW "^ABW:.*$"
+syn match purifyLogBRK "^BRK:.*$"
+syn match purifyLogFMW "^FMW:.*$"
+syn match purifyLogFNH "^FNH:.*$"
+syn match purifyLogFUM "^FUM:.*$"
+syn match purifyLogMRE "^MRE:.*$"
+syn match purifyLogSBW "^SBW:.*$"
+
+" Fatal messages
+syn match purifyLogCOR "^COR:.*$"
+syn match purifyLogNPR "^NPR:.*$"
+syn match purifyLogNPW "^NPW:.*$"
+syn match purifyLogZPR "^ZPR:.*$"
+syn match purifyLogZPW "^ZPW:.*$"
+
+" Define the default highlighting.
+" For version 5.7 and earlier: only when not done already
+" For version 5.8 and later: only when an item doesn't have highlighting yet
+if version >= 508 || !exists("did_purifyLog_syntax_inits")
+  if version < 508
+    let did_purifyLog_syntax_inits = 1
+    command -nargs=+ HiLink hi link <args>
+  else
+    command -nargs=+ HiLink hi def link <args>
+  endif
+
+	HiLink purifyLogFIU purifyLogInformational
+	HiLink purifyLogMAF purifyLogInformational
+	HiLink purifyLogMIU purifyLogInformational
+	HiLink purifyLogSIG purifyLogInformational
+	HiLink purifyLogWPF purifyLogInformational
+	HiLink purifyLogWPM purifyLogInformational
+	HiLink purifyLogWPN purifyLogInformational
+	HiLink purifyLogWPR purifyLogInformational
+	HiLink purifyLogWPW purifyLogInformational
+	HiLink purifyLogWPX purifyLogInformational
+
+	HiLink purifyLogABR purifyLogWarning
+	HiLink purifyLogBSR purifyLogWarning
+	HiLink purifyLogBSW purifyLogWarning
+	HiLink purifyLogFMR purifyLogWarning
+	HiLink purifyLogMLK purifyLogWarning
+	HiLink purifyLogMSE purifyLogWarning
+	HiLink purifyLogPAR purifyLogWarning
+	HiLink purifyLogPLK purifyLogWarning
+	HiLink purifyLogSBR purifyLogWarning
+	HiLink purifyLogSOF purifyLogWarning
+	HiLink purifyLogUMC purifyLogWarning
+	HiLink purifyLogUMR purifyLogWarning
+
+	HiLink purifyLogABW purifyLogCorrupting
+	HiLink purifyLogBRK purifyLogCorrupting
+	HiLink purifyLogFMW purifyLogCorrupting
+	HiLink purifyLogFNH purifyLogCorrupting
+	HiLink purifyLogFUM purifyLogCorrupting
+	HiLink purifyLogMRE purifyLogCorrupting
+	HiLink purifyLogSBW purifyLogCorrupting
+
+	HiLink purifyLogCOR purifyLogFatal
+	HiLink purifyLogNPR purifyLogFatal
+	HiLink purifyLogNPW purifyLogFatal
+	HiLink purifyLogZPR purifyLogFatal
+	HiLink purifyLogZPW purifyLogFatal
+
+	HiLink purifyLogHeader		Comment
+	HiLink purifyLogInformational	PreProc
+	HiLink purifyLogWarning		Type
+	HiLink purifyLogCorrupting	Error
+	HiLink purifyLogFatal		Error
+
+	delcommand HiLink
+endif
+
+let b:current_syntax = "purifylog"
+
+" vim:ts=8
--- /dev/null
+++ b/lib/vimfiles/syntax/pyrex.vim
@@ -1,0 +1,67 @@
+" Vim syntax file
+" Language:	Pyrex
+" Maintainer:	Marco Barisione <marco.bari@people.it>
+" URL:		http://marcobari.altervista.org/pyrex_vim.html
+" Last Change:	2004 May 16
+
+" For version 5.x: Clear all syntax items
+" For version 6.x: Quit when a syntax file was already loaded
+if version < 600
+  syntax clear
+elseif exists("b:current_syntax")
+  finish
+endif
+
+" Read the Python syntax to start with
+if version < 600
+  so <sfile>:p:h/python.vim
+else
+  runtime! syntax/python.vim
+  unlet b:current_syntax
+endif
+
+" Pyrex extentions
+syn keyword pyrexStatement      cdef typedef ctypedef sizeof
+syn keyword pyrexType		int long short float double char object void
+syn keyword pyrexType		signed unsigned
+syn keyword pyrexStructure	struct union enum
+syn keyword pyrexPrecondit	include cimport
+syn keyword pyrexAccess		public private property readonly extern
+" If someome wants Python's built-ins highlighted probably he
+" also wants Pyrex's built-ins highlighted
+if exists("python_highlight_builtins") || exists("pyrex_highlight_builtins")
+    syn keyword pyrexBuiltin    NULL
+endif
+
+" This deletes "from" from the keywords and re-adds it as a
+" match with lower priority than pyrexForFrom
+syn clear   pythonPreCondit
+syn keyword pythonPreCondit     import
+syn match   pythonPreCondit     "from"
+
+" With "for[^:]*\zsfrom" VIM does not match "for" anymore, so
+" I used the slower "\@<=" form
+syn match   pyrexForFrom        "\(for[^:]*\)\@<=from"
+
+" Default highlighting
+if version >= 508 || !exists("did_pyrex_syntax_inits")
+  if version < 508
+    let did_pyrex_syntax_inits = 1
+    command -nargs=+ HiLink hi link <args>
+  else
+    command -nargs=+ HiLink hi def link <args>
+  endif
+  HiLink pyrexStatement		Statement
+  HiLink pyrexType		Type
+  HiLink pyrexStructure		Structure
+  HiLink pyrexPrecondit		PreCondit
+  HiLink pyrexAccess		pyrexStatement
+  if exists("python_highlight_builtins") || exists("pyrex_highlight_builtins")
+      HiLink pyrexBuiltin	Function
+  endif
+  HiLink pyrexForFrom		Statement
+
+  delcommand HiLink
+endif
+
+let b:current_syntax = "pyrex"
--- /dev/null
+++ b/lib/vimfiles/syntax/python.vim
@@ -1,0 +1,181 @@
+" Vim syntax file
+" Language:	Python
+" Maintainer:	Neil Schemenauer <nas@python.ca>
+" Updated:	2006-10-15
+"		Added Python 2.4 features 2006 May 4 (Dmitry Vasiliev)
+"
+" Options to control Python syntax highlighting:
+"
+" For highlighted numbers:
+"
+"    let python_highlight_numbers = 1
+"
+" For highlighted builtin functions:
+"
+"    let python_highlight_builtins = 1
+"
+" For highlighted standard exceptions:
+"
+"    let python_highlight_exceptions = 1
+"
+" Highlight erroneous whitespace:
+"
+"    let python_highlight_space_errors = 1
+"
+" If you want all possible Python highlighting (the same as setting the
+" preceding options):
+"
+"    let python_highlight_all = 1
+"
+
+" For version 5.x: Clear all syntax items
+" For version 6.x: Quit when a syntax file was already loaded
+if version < 600
+  syntax clear
+elseif exists("b:current_syntax")
+  finish
+endif
+
+
+syn keyword pythonStatement	break continue del
+syn keyword pythonStatement	except exec finally
+syn keyword pythonStatement	pass print raise
+syn keyword pythonStatement	return try with
+syn keyword pythonStatement	global assert
+syn keyword pythonStatement	lambda yield
+syn keyword pythonStatement	def class nextgroup=pythonFunction skipwhite
+syn match   pythonFunction	"[a-zA-Z_][a-zA-Z0-9_]*" contained
+syn keyword pythonRepeat	for while
+syn keyword pythonConditional	if elif else
+syn keyword pythonOperator	and in is not or
+" AS will be a keyword in Python 3
+syn keyword pythonPreCondit	import from as
+syn match   pythonComment	"#.*$" contains=pythonTodo,@Spell
+syn keyword pythonTodo		TODO FIXME XXX contained
+
+" Decorators (new in Python 2.4)
+syn match   pythonDecorator	"@" display nextgroup=pythonFunction skipwhite
+
+" strings
+syn region pythonString		matchgroup=Normal start=+[uU]\='+ end=+'+ skip=+\\\\\|\\'+ contains=pythonEscape,@Spell
+syn region pythonString		matchgroup=Normal start=+[uU]\="+ end=+"+ skip=+\\\\\|\\"+ contains=pythonEscape,@Spell
+syn region pythonString		matchgroup=Normal start=+[uU]\="""+ end=+"""+ contains=pythonEscape,@Spell
+syn region pythonString		matchgroup=Normal start=+[uU]\='''+ end=+'''+ contains=pythonEscape,@Spell
+syn region pythonRawString	matchgroup=Normal start=+[uU]\=[rR]'+ end=+'+ skip=+\\\\\|\\'+ contains=@Spell
+syn region pythonRawString	matchgroup=Normal start=+[uU]\=[rR]"+ end=+"+ skip=+\\\\\|\\"+ contains=@Spell
+syn region pythonRawString	matchgroup=Normal start=+[uU]\=[rR]"""+ end=+"""+ contains=@Spell
+syn region pythonRawString	matchgroup=Normal start=+[uU]\=[rR]'''+ end=+'''+ contains=@Spell
+syn match  pythonEscape		+\\[abfnrtv'"\\]+ contained
+syn match  pythonEscape		"\\\o\{1,3}" contained
+syn match  pythonEscape		"\\x\x\{2}" contained
+syn match  pythonEscape		"\(\\u\x\{4}\|\\U\x\{8}\)" contained
+syn match  pythonEscape		"\\$"
+
+if exists("python_highlight_all")
+  let python_highlight_numbers = 1
+  let python_highlight_builtins = 1
+  let python_highlight_exceptions = 1
+  let python_highlight_space_errors = 1
+endif
+
+if exists("python_highlight_numbers")
+  " numbers (including longs and complex)
+  syn match   pythonNumber	"\<0x\x\+[Ll]\=\>"
+  syn match   pythonNumber	"\<\d\+[LljJ]\=\>"
+  syn match   pythonNumber	"\.\d\+\([eE][+-]\=\d\+\)\=[jJ]\=\>"
+  syn match   pythonNumber	"\<\d\+\.\([eE][+-]\=\d\+\)\=[jJ]\=\>"
+  syn match   pythonNumber	"\<\d\+\.\d\+\([eE][+-]\=\d\+\)\=[jJ]\=\>"
+endif
+
+if exists("python_highlight_builtins")
+  " builtin functions, types and objects, not really part of the syntax
+  syn keyword pythonBuiltin	True False bool enumerate set frozenset help
+  syn keyword pythonBuiltin	reversed sorted sum
+  syn keyword pythonBuiltin	Ellipsis None NotImplemented __import__ abs
+  syn keyword pythonBuiltin	apply buffer callable chr classmethod cmp
+  syn keyword pythonBuiltin	coerce compile complex delattr dict dir divmod
+  syn keyword pythonBuiltin	eval execfile file filter float getattr globals
+  syn keyword pythonBuiltin	hasattr hash hex id input int intern isinstance
+  syn keyword pythonBuiltin	issubclass iter len list locals long map max
+  syn keyword pythonBuiltin	min object oct open ord pow property range
+  syn keyword pythonBuiltin	raw_input reduce reload repr round setattr
+  syn keyword pythonBuiltin	slice staticmethod str super tuple type unichr
+  syn keyword pythonBuiltin	unicode vars xrange zip
+endif
+
+if exists("python_highlight_exceptions")
+  " builtin exceptions and warnings
+  syn keyword pythonException	ArithmeticError AssertionError AttributeError
+  syn keyword pythonException	DeprecationWarning EOFError EnvironmentError
+  syn keyword pythonException	Exception FloatingPointError IOError
+  syn keyword pythonException	ImportError IndentationError IndexError
+  syn keyword pythonException	KeyError KeyboardInterrupt LookupError
+  syn keyword pythonException	MemoryError NameError NotImplementedError
+  syn keyword pythonException	OSError OverflowError OverflowWarning
+  syn keyword pythonException	ReferenceError RuntimeError RuntimeWarning
+  syn keyword pythonException	StandardError StopIteration SyntaxError
+  syn keyword pythonException	SyntaxWarning SystemError SystemExit TabError
+  syn keyword pythonException	TypeError UnboundLocalError UnicodeError
+  syn keyword pythonException	UnicodeEncodeError UnicodeDecodeError
+  syn keyword pythonException	UnicodeTranslateError
+  syn keyword pythonException	UserWarning ValueError Warning WindowsError
+  syn keyword pythonException	ZeroDivisionError
+endif
+
+if exists("python_highlight_space_errors")
+  " trailing whitespace
+  syn match   pythonSpaceError   display excludenl "\S\s\+$"ms=s+1
+  " mixed tabs and spaces
+  syn match   pythonSpaceError   display " \+\t"
+  syn match   pythonSpaceError   display "\t\+ "
+endif
+
+" This is fast but code inside triple quoted strings screws it up. It
+" is impossible to fix because the only way to know if you are inside a
+" triple quoted string is to start from the beginning of the file. If
+" you have a fast machine you can try uncommenting the "sync minlines"
+" and commenting out the rest.
+syn sync match pythonSync grouphere NONE "):$"
+syn sync maxlines=200
+"syn sync minlines=2000
+
+if version >= 508 || !exists("did_python_syn_inits")
+  if version <= 508
+    let did_python_syn_inits = 1
+    command -nargs=+ HiLink hi link <args>
+  else
+    command -nargs=+ HiLink hi def link <args>
+  endif
+
+  " The default methods for highlighting.  Can be overridden later
+  HiLink pythonStatement	Statement
+  HiLink pythonFunction		Function
+  HiLink pythonConditional	Conditional
+  HiLink pythonRepeat		Repeat
+  HiLink pythonString		String
+  HiLink pythonRawString	String
+  HiLink pythonEscape		Special
+  HiLink pythonOperator		Operator
+  HiLink pythonPreCondit	PreCondit
+  HiLink pythonComment		Comment
+  HiLink pythonTodo		Todo
+  HiLink pythonDecorator	Define
+  if exists("python_highlight_numbers")
+    HiLink pythonNumber	Number
+  endif
+  if exists("python_highlight_builtins")
+    HiLink pythonBuiltin	Function
+  endif
+  if exists("python_highlight_exceptions")
+    HiLink pythonException	Exception
+  endif
+  if exists("python_highlight_space_errors")
+    HiLink pythonSpaceError	Error
+  endif
+
+  delcommand HiLink
+endif
+
+let b:current_syntax = "python"
+
+" vim: ts=8
--- /dev/null
+++ b/lib/vimfiles/syntax/qf.vim
@@ -1,0 +1,24 @@
+" Vim syntax file
+" Language:	Quickfix window
+" Maintainer:	Bram Moolenaar <Bram@vim.org>
+" Last change:	2001 Jan 15
+
+" Quit when a syntax file was already loaded
+if exists("b:current_syntax")
+  finish
+endif
+
+" A bunch of useful C keywords
+syn match	qfFileName	"^[^|]*" nextgroup=qfSeparator
+syn match	qfSeparator	"|" nextgroup=qfLineNr contained
+syn match	qfLineNr	"[^|]*" contained contains=qfError
+syn match	qfError		"error" contained
+
+" The default highlighting.
+hi def link qfFileName	Directory
+hi def link qfLineNr	LineNr
+hi def link qfError	Error
+
+let b:current_syntax = "qf"
+
+" vim: ts=8
--- /dev/null
+++ b/lib/vimfiles/syntax/quake.vim
@@ -1,0 +1,170 @@
+" Vim syntax file
+" Language:         Quake[1-3] configuration file
+" Maintainer:       Nikolai Weibull <now@bitwi.se>
+" Latest Revision:  2006-04-19
+"               quake_is_quake1 - the syntax is to be used for quake1 configs
+"               quake_is_quake2 - the syntax is to be used for quake2 configs
+"               quake_is_quake3 - the syntax is to be used for quake3 configs
+" Credits:          Tomasz Kalkosinski wrote the original quake3Colors stuff
+
+if exists("b:current_syntax")
+  finish
+endif
+
+let s:cpo_save = &cpo
+set cpo&vim
+
+setlocal iskeyword=@,48-57,+,-,_
+
+syn keyword quakeTodo         contained TODO FIXME XXX NOTE
+
+syn region  quakeComment      display oneline start='//' end='$' end=';'
+                              \ keepend contains=quakeTodo,@Spell
+
+syn region  quakeString       display oneline start=+"+ skip=+\\\\\|\\"+
+                              \ end=+"\|$+ contains=quakeNumbers,
+                              \ @quakeCommands,@quake3Colors
+
+syn case ignore
+
+syn match quakeNumbers        display transparent '\<-\=\d\|\.\d'
+                              \ contains=quakeNumber,quakeFloat,
+                              \ quakeOctalError,quakeOctal
+syn match quakeNumber         contained display '\d\+\>'
+syn match quakeFloat          contained display '\d\+\.\d*'
+syn match quakeFloat          contained display '\.\d\+\>'
+
+if exists("quake_is_quake1") || exists("quake_is_quake2")
+  syn match quakeOctal        contained display '0\o\+\>'
+                              \ contains=quakeOctalZero
+  syn match quakeOctalZero    contained display '\<0'
+  syn match quakeOctalError   contained display '0\o*[89]\d*'
+endif
+
+syn cluster quakeCommands     contains=quakeCommand,quake1Command,
+                              \ quake12Command,Quake2Command,Quake23Command,
+                              \ Quake3Command
+
+syn keyword quakeCommand      +attack +back +forward +left +lookdown +lookup
+syn keyword quakeCommand      +mlook +movedown +moveleft +moveright +moveup
+syn keyword quakeCommand      +right +speed +strafe -attack -back bind
+syn keyword quakeCommand      bindlist centerview clear connect cvarlist dir
+syn keyword quakeCommand      disconnect dumpuser echo error exec -forward
+syn keyword quakeCommand      god heartbeat joy_advancedupdate kick kill
+syn keyword quakeCommand      killserver -left -lookdown -lookup map
+syn keyword quakeCommand      messagemode messagemode2 -mlook modellist
+syn keyword quakeCommand      -movedown -moveleft -moveright -moveup play
+syn keyword quakeCommand      quit rcon reconnect record -right say say_team
+syn keyword quakeCommand      screenshot serverinfo serverrecord serverstop
+syn keyword quakeCommand      set sizedown sizeup snd_restart soundinfo
+syn keyword quakeCommand      soundlist -speed spmap status -strafe stopsound
+syn keyword quakeCommand      toggleconsole unbind unbindall userinfo pause
+syn keyword quakeCommand      vid_restart viewpos wait weapnext weapprev
+
+if exists("quake_is_quake1")
+  syn keyword quake1Command   sv
+endif
+
+if exists("quake_is_quake1") || exists("quake_is_quake2")
+  syn keyword quake12Command  +klook alias cd impulse link load save
+  syn keyword quake12Command  timerefresh changing info loading
+  syn keyword quake12Command  pingservers playerlist players score
+endif
+
+if exists("quake_is_quake2")
+  syn keyword quake2Command   cmd demomap +use condump download drop gamemap
+  syn keyword quake2Command   give gun_model setmaster sky sv_maplist wave
+  syn keyword quake2Command   cmdlist gameversiona gun_next gun_prev invdrop
+  syn keyword quake2Command   inven invnext invnextp invnextw invprev
+  syn keyword quake2Command   invprevp invprevw invuse menu_addressbook
+  syn keyword quake2Command   menu_credits menu_dmoptions menu_game
+  syn keyword quake2Command   menu_joinserver menu_keys menu_loadgame
+  syn keyword quake2Command   menu_main menu_multiplayer menu_options
+  syn keyword quake2Command   menu_playerconfig menu_quit menu_savegame
+  syn keyword quake2Command   menu_startserver menu_video
+  syn keyword quake2Command   notarget precache prog togglechat vid_front
+  syn keyword quake2Command   weaplast
+endif
+
+if exists("quake_is_quake2") || exists("quake_is_quake3")
+  syn keyword quake23Command  imagelist modellist path z_stats
+endif
+
+if exists("quake_is_quake3")
+  syn keyword quake3Command   +info +scores +zoom addbot arena banClient
+  syn keyword quake3Command   banUser callteamvote callvote changeVectors
+  syn keyword quake3Command   cinematic clientinfo clientkick cmd cmdlist
+  syn keyword quake3Command   condump configstrings crash cvar_restart devmap
+  syn keyword quake3Command   fdir follow freeze fs_openedList Fs_pureList
+  syn keyword quake3Command   Fs_referencedList gfxinfo globalservers
+  syn keyword quake3Command   hunk_stats in_restart -info levelshot
+  syn keyword quake3Command   loaddeferred localservers map_restart mem_info
+  syn keyword quake3Command   messagemode3 messagemode4 midiinfo model music
+  syn keyword quake3Command   modelist net_restart nextframe nextskin noclip
+  syn keyword quake3Command   notarget ping prevframe prevskin reset restart
+  syn keyword quake3Command   s_disable_a3d s_enable_a3d s_info s_list s_stop
+  syn keyword quake3Command   scanservers -scores screenshotJPEG sectorlist
+  syn keyword quake3Command   serverstatus seta setenv sets setu setviewpos
+  syn keyword quake3Command   shaderlist showip skinlist spdevmap startOribt
+  syn keyword quake3Command   stats stopdemo stoprecord systeminfo togglemenu
+  syn keyword quake3Command   tcmd team teamtask teamvote tell tell_attacker
+  syn keyword quake3Command   tell_target testgun testmodel testshader toggle
+  syn keyword quake3Command   touchFile vminfo vmprofile vmtest vosay
+  syn keyword quake3Command   vosay_team vote votell vsay vsay_team vstr
+  syn keyword quake3Command   vtaunt vtell vtell_attacker vtell_target weapon
+  syn keyword quake3Command   writeconfig -zoom
+  syn match   quake3Command   display "\<[+-]button\(\d\|1[0-4]\)\>"
+endif
+
+if exists("quake_is_quake3")
+  syn cluster quake3Colors    contains=quake3Red,quake3Green,quake3Yellow,
+                              \ quake3Blue,quake3Cyan,quake3Purple,quake3White,
+                              \ quake3Orange,quake3Grey,quake3Black,quake3Shadow
+
+  syn region quake3Red        contained start=+\^1+hs=e+1 end=+[$^"\n]+he=e-1
+  syn region quake3Green      contained start=+\^2+hs=e+1 end=+[$^"\n]+he=e-1
+  syn region quake3Yellow     contained start=+\^3+hs=e+1 end=+[$^"\n]+he=e-1
+  syn region quake3Blue       contained start=+\^4+hs=e+1 end=+[$^"\n]+he=e-1
+  syn region quake3Cyan       contained start=+\^5+hs=e+1 end=+[$^"\n]+he=e-1
+  syn region quake3Purple     contained start=+\^6+hs=e+1 end=+[$^"\n]+he=e-1
+  syn region quake3White      contained start=+\^7+hs=e+1 end=+[$^"\n]+he=e-1
+  syn region quake3Orange     contained start=+\^8+hs=e+1 end=+[$^\"\n]+he=e-1
+  syn region quake3Grey       contained start=+\^9+hs=e+1 end=+[$^"\n]+he=e-1
+  syn region quake3Black      contained start=+\^0+hs=e+1 end=+[$^"\n]+he=e-1
+  syn region quake3Shadow     contained start=+\^[Xx]+hs=e+1 end=+[$^"\n]+he=e-1
+endif
+
+hi def link quakeComment      Comment
+hi def link quakeTodo         Todo
+hi def link quakeString       String
+hi def link quakeNumber       Number
+hi def link quakeOctal        Number
+hi def link quakeOctalZero    PreProc
+hi def link quakeFloat        Number
+hi def link quakeOctalError   Error
+hi def link quakeCommand      quakeCommands
+hi def link quake1Command     quakeCommands
+hi def link quake12Command    quakeCommands
+hi def link quake2Command     quakeCommands
+hi def link quake23Command    quakeCommands
+hi def link quake3Command     quakeCommands
+hi def link quakeCommands     Keyword
+
+if exists("quake_is_quake3")
+  hi quake3Red                ctermfg=Red         guifg=Red
+  hi quake3Green              ctermfg=Green       guifg=Green
+  hi quake3Yellow             ctermfg=Yellow      guifg=Yellow
+  hi quake3Blue               ctermfg=Blue        guifg=Blue
+  hi quake3Cyan               ctermfg=Cyan        guifg=Cyan
+  hi quake3Purple             ctermfg=DarkMagenta guifg=Purple
+  hi quake3White              ctermfg=White       guifg=White
+  hi quake3Black              ctermfg=Black       guifg=Black
+  hi quake3Orange             ctermfg=Brown       guifg=Orange
+  hi quake3Grey               ctermfg=LightGrey   guifg=LightGrey
+  hi quake3Shadow             cterm=underline     gui=underline
+endif
+
+let b:current_syntax = "quake"
+
+let &cpo = s:cpo_save
+unlet s:cpo_save
--- /dev/null
+++ b/lib/vimfiles/syntax/r.vim
@@ -1,0 +1,111 @@
+" Vim syntax file
+" Language:	R (GNU S)
+" Maintainer:	Vaidotas Zemlys <zemlys@gmail.com>
+" Last Change:  2006 Apr 30
+" Filenames:	*.R *.Rout *.r *.Rhistory *.Rt *.Rout.save *.Rout.fail
+" URL:		http://uosis.mif.vu.lt/~zemlys/vim-syntax/r.vim
+
+" First maintainer Tom Payne <tom@tompayne.org>
+" Modified to make syntax less colourful and added the highlighting of
+" R assignment arrow
+
+" For version 5.x: Clear all syntax items
+" For version 6.x: Quit when a syntax file was already loaded
+if version < 600
+  syntax clear
+elseif exists("b:current_syntax")
+  finish
+endif
+
+if version >= 600
+  setlocal iskeyword=@,48-57,_,.
+else
+  set iskeyword=@,48-57,_,.
+endif
+
+syn case match
+
+" Comment
+syn match rComment /\#.*/
+
+" Constant
+" string enclosed in double quotes
+syn region rString start=/"/ skip=/\\\\\|\\"/ end=/"/
+" string enclosed in single quotes
+syn region rString start=/'/ skip=/\\\\\|\\'/ end=/'/
+" number with no fractional part or exponent
+syn match rNumber /\d\+/
+" floating point number with integer and fractional parts and optional exponent
+syn match rFloat /\d\+\.\d*\([Ee][-+]\=\d\+\)\=/
+" floating point number with no integer part and optional exponent
+syn match rFloat /\.\d\+\([Ee][-+]\=\d\+\)\=/
+" floating point number with no fractional part and optional exponent
+syn match rFloat /\d\+[Ee][-+]\=\d\+/
+
+" Identifier
+" identifier with leading letter and optional following keyword characters
+syn match rIdentifier /\a\k*/
+" identifier with leading period, one or more digits, and at least one non-digit keyword character
+syn match rIdentifier /\.\d*\K\k*/
+
+" Statement
+syn keyword rStatement   break next return
+syn keyword rConditional if else
+syn keyword rRepeat      for in repeat while
+
+" Constant
+syn keyword rConstant LETTERS letters month.ab month.name pi
+syn keyword rConstant NULL
+syn keyword rBoolean  FALSE TRUE
+syn keyword rNumber   NA
+syn match rArrow /<\{1,2}-/
+
+" Type
+syn keyword rType array category character complex double function integer list logical matrix numeric vector data.frame 
+
+" Special
+syn match rDelimiter /[,;:]/
+
+" Error
+syn region rRegion matchgroup=Delimiter start=/(/ matchgroup=Delimiter end=/)/ transparent contains=ALLBUT,rError,rBraceError,rCurlyError
+syn region rRegion matchgroup=Delimiter start=/{/ matchgroup=Delimiter end=/}/ transparent contains=ALLBUT,rError,rBraceError,rParenError
+syn region rRegion matchgroup=Delimiter start=/\[/ matchgroup=Delimiter end=/]/ transparent contains=ALLBUT,rError,rCurlyError,rParenError
+syn match rError      /[)\]}]/
+syn match rBraceError /[)}]/ contained
+syn match rCurlyError /[)\]]/ contained
+syn match rParenError /[\]}]/ contained
+
+" Define the default highlighting.
+" For version 5.7 and earlier: only when not done already
+" For version 5.8 and later: only when an item doesn't have highlighting yet
+if version >= 508 || !exists("did_r_syn_inits")
+  if version < 508
+    let did_r_syn_inits = 1
+    command -nargs=+ HiLink hi link <args>
+  else
+    command -nargs=+ HiLink hi def link <args>
+  endif
+  HiLink rComment     Comment
+  HiLink rConstant    Constant
+  HiLink rString      String
+  HiLink rNumber      Number
+  HiLink rBoolean     Boolean
+  HiLink rFloat       Float
+  HiLink rStatement   Statement
+  HiLink rConditional Conditional
+  HiLink rRepeat      Repeat
+  HiLink rIdentifier  Normal
+  HiLink rArrow	      Statement	
+  HiLink rType        Type
+  HiLink rDelimiter   Delimiter
+  HiLink rError       Error
+  HiLink rBraceError  Error
+  HiLink rCurlyError  Error
+  HiLink rParenError  Error
+  delcommand HiLink
+endif
+
+let b:current_syntax="r"
+
+" vim: ts=8 sw=2
+
--- /dev/null
+++ b/lib/vimfiles/syntax/racc.vim
@@ -1,0 +1,142 @@
+" Vim default file
+" Language:         Racc input file
+" Maintainer:       Nikolai Weibull <now@bitwi.se>
+" Latest Revision:  2006-07-09
+
+if exists("b:current_syntax")
+  finish
+endif
+
+let s:cpo_save = &cpo
+set cpo&vim
+
+syn keyword raccTodo        contained TODO FIXME XXX NOTE
+
+syn region  raccComment     start='/\*' end='\*/'
+                            \ contains=raccTodo,@Spell
+syn region  raccComment     display oneline start='#' end='$'
+                            \ contains=raccTodo,@Spell
+
+syn region  raccClass       transparent matchgroup=raccKeyword
+                            \ start='\<class\>' end='\<rule\>'he=e-4
+                            \ contains=raccComment,raccPrecedence,
+                            \ raccTokenDecl,raccExpect,raccOptions,raccConvert,
+                            \ raccStart,
+
+syn region  raccPrecedence  transparent matchgroup=raccKeyword
+                            \ start='\<prechigh\>' end='\<preclow\>'
+                            \ contains=raccComment,raccPrecSpec
+
+syn keyword raccPrecSpec    contained nonassoc left right
+                            \ nextgroup=raccPrecToken,raccPrecString skipwhite
+                            \ skipnl
+
+syn match   raccPrecToken   contained '\<\u[A-Z0-9]*\>'
+                            \ nextgroup=raccPrecToken,raccPrecString skipwhite
+                            \ skipnl
+
+syn region  raccPrecString  matchgroup=raccPrecString start=+"+
+                            \ skip=+\\\\\|\\"+ end=+"+
+                            \ contains=raccSpecial
+                            \ nextgroup=raccPrecToken,raccPrecString skipwhite
+                            \ skipnl
+syn region  raccPrecString  matchgroup=raccPrecString start=+'+
+                            \ skip=+\\\\\|\\'+ end=+'+ contains=raccSpecial
+                            \ nextgroup=raccPrecToken,raccPrecString skipwhite
+                            \ skipnl
+
+syn keyword raccTokenDecl   contained token
+                            \ nextgroup=raccTokenR skipwhite skipnl
+
+syn match   raccTokenR      contained '\<\u[A-Z0-9]*\>'
+                            \ nextgroup=raccTokenR skipwhite skipnl
+
+syn keyword raccExpect      contained expect
+                            \ nextgroup=raccNumber skipwhite skipnl
+
+syn match   raccNumber      contained '\<\d\+\>'
+
+syn keyword raccOptions     contained options
+                            \ nextgroup=raccOptionsR skipwhite skipnl
+
+syn keyword raccOptionsR    contained omit_action_call result_var
+                            \ nextgroup=raccOptionsR skipwhite skipnl
+
+syn region  raccConvert     transparent contained matchgroup=raccKeyword
+                            \ start='\<convert\>' end='\<end\>'
+                            \ contains=raccComment,raccConvToken skipwhite
+                            \ skipnl
+
+syn match   raccConvToken   contained '\<\u[A-Z0-9]*\>'
+                            \ nextgroup=raccString skipwhite skipnl
+
+syn keyword raccStart       contained start
+                            \ nextgroup=raccTargetS skipwhite skipnl
+
+syn match   raccTargetS     contained '\<\l[a-z0-9]*\>'
+
+syn match   raccSpecial     contained '\\["'\\]'
+
+syn region  raccString      start=+"+ skip=+\\\\\|\\"+ end=+"+
+                            \ contains=raccSpecial
+syn region  raccString      start=+'+ skip=+\\\\\|\\'+ end=+'+
+                            \ contains=raccSpecial
+
+syn region  raccRules       transparent matchgroup=raccKeyword start='\<rule\>'
+                            \ end='\<end\>' contains=raccComment,raccString,
+                            \ raccNumber,raccToken,raccTarget,raccDelimiter,
+                            \ raccAction
+
+syn match   raccTarget      contained '\<\l[a-z0-9]*\>'
+
+syn match   raccDelimiter   contained '[:|]'
+
+syn match   raccToken       contained '\<\u[A-Z0-9]*\>'
+
+syn include @raccRuby       syntax/ruby.vim
+
+syn region  raccAction      transparent matchgroup=raccDelimiter
+                            \ start='{' end='}' contains=@raccRuby
+
+syn region  raccHeader      transparent matchgroup=raccPreProc
+                            \ start='^---- header.*' end='^----'he=e-4
+                            \ contains=@raccRuby
+
+syn region  raccInner       transparent matchgroup=raccPreProc
+                            \ start='^---- inner.*' end='^----'he=e-4
+                            \ contains=@raccRuby
+
+syn region  raccFooter      transparent matchgroup=raccPreProc
+                            \ start='^---- footer.*' end='^----'he=e-4
+                            \ contains=@raccRuby
+
+syn sync    match raccSyncHeader    grouphere raccHeader '^---- header'
+syn sync    match raccSyncInner     grouphere raccInner '^---- inner'
+syn sync    match raccSyncFooter    grouphere raccFooter '^---- footer'
+
+hi def link raccTodo        Todo
+hi def link raccComment     Comment
+hi def link raccPrecSpec    Type
+hi def link raccPrecToken   raccToken
+hi def link raccPrecString  raccString
+hi def link raccTokenDecl   Keyword
+hi def link raccToken       Identifier
+hi def link raccTokenR      raccToken
+hi def link raccExpect      Keyword
+hi def link raccNumber      Number
+hi def link raccOptions     Keyword
+hi def link raccOptionsR    Identifier
+hi def link raccConvToken   raccToken
+hi def link raccStart       Keyword
+hi def link raccTargetS     Type
+hi def link raccSpecial     special
+hi def link raccString      String
+hi def link raccTarget      Type
+hi def link raccDelimiter   Delimiter
+hi def link raccPreProc     PreProc
+hi def link raccKeyword     Keyword
+
+let b:current_syntax = "racc"
+
+let &cpo = s:cpo_save
+unlet s:cpo_save
--- /dev/null
+++ b/lib/vimfiles/syntax/radiance.vim
@@ -1,0 +1,159 @@
+" Vim syntax file
+" Language:     Radiance Scene Description
+" Maintainer:   Georg Mischler <schorsch@schorsch.com>
+" Last change:  26. April. 2001
+
+" Radiance is a lighting simulation software package written
+" by Gregory Ward-Larson ("the computer artist formerly known
+" as Greg Ward"), then at LBNL.
+"
+" http://radsite.lbl.gov/radiance/HOME.html
+"
+" Of course, there is also information available about it
+" from http://www.schorsch.com/
+
+
+" We take a minimalist approach here, highlighting just the
+" essential properties of each object, its type and ID, as well as
+" comments, external command names and the null-modifier "void".
+
+
+" For version 5.x: Clear all syntax items
+" For version 6.x: Quit when a syntax file was already loaded
+if version < 600
+  syntax clear
+elseif exists("b:current_syntax")
+  finish
+endif
+
+" all printing characters except '#' and '!' are valid in names.
+if version >= 600
+  setlocal iskeyword=\",$-~
+else
+  set iskeyword=\",$-~
+endif
+
+" The null-modifier
+syn keyword radianceKeyword void
+
+" The different kinds of scene description object types
+" Reference types
+syn keyword radianceExtraType contained alias instance
+" Surface types
+syn keyword radianceSurfType contained ring polygon sphere bubble
+syn keyword radianceSurfType contained cone cup cylinder tube source
+" Emitting material types
+syn keyword radianceLightType contained light glow illum spotlight
+" Material types
+syn keyword radianceMatType contained mirror mist prism1 prism2
+syn keyword radianceMatType contained metal plastic trans
+syn keyword radianceMatType contained metal2 plastic2 trans2
+syn keyword radianceMatType contained metfunc plasfunc transfunc
+syn keyword radianceMatType contained metdata plasdata transdata
+syn keyword radianceMatType contained dielectric interface glass
+syn keyword radianceMatType contained BRTDfunc antimatter
+" Pattern modifier types
+syn keyword radiancePatType contained colorfunc brightfunc
+syn keyword radiancePatType contained colordata colorpict brightdata
+syn keyword radiancePatType contained colortext brighttext
+" Texture modifier types
+syn keyword radianceTexType contained texfunc texdata
+" Mixture types
+syn keyword radianceMixType contained mixfunc mixdata mixpict mixtext
+
+
+" Each type name is followed by an ID.
+" This doesn't work correctly if the id is one of the type names of the
+" same class (which is legal for radiance), in which case the id will get
+" type color as well, and the int count (or alias reference) gets id color.
+
+syn region radianceID start="\<alias\>"      end="\<\k*\>" contains=radianceExtraType
+syn region radianceID start="\<instance\>"   end="\<\k*\>" contains=radianceExtraType
+
+syn region radianceID start="\<source\>"     end="\<\k*\>" contains=radianceSurfType
+syn region radianceID start="\<ring\>"	     end="\<\k*\>" contains=radianceSurfType
+syn region radianceID start="\<polygon\>"    end="\<\k*\>" contains=radianceSurfType
+syn region radianceID start="\<sphere\>"     end="\<\k*\>" contains=radianceSurfType
+syn region radianceID start="\<bubble\>"     end="\<\k*\>" contains=radianceSurfType
+syn region radianceID start="\<cone\>"	     end="\<\k*\>" contains=radianceSurfType
+syn region radianceID start="\<cup\>"	     end="\<\k*\>" contains=radianceSurfType
+syn region radianceID start="\<cylinder\>"   end="\<\k*\>" contains=radianceSurfType
+syn region radianceID start="\<tube\>"	     end="\<\k*\>" contains=radianceSurfType
+
+syn region radianceID start="\<light\>"      end="\<\k*\>" contains=radianceLightType
+syn region radianceID start="\<glow\>"	     end="\<\k*\>" contains=radianceLightType
+syn region radianceID start="\<illum\>"      end="\<\k*\>" contains=radianceLightType
+syn region radianceID start="\<spotlight\>"  end="\<\k*\>" contains=radianceLightType
+
+syn region radianceID start="\<mirror\>"     end="\<\k*\>" contains=radianceMatType
+syn region radianceID start="\<mist\>"	     end="\<\k*\>" contains=radianceMatType
+syn region radianceID start="\<prism1\>"     end="\<\k*\>" contains=radianceMatType
+syn region radianceID start="\<prism2\>"     end="\<\k*\>" contains=radianceMatType
+syn region radianceID start="\<metal\>"      end="\<\k*\>" contains=radianceMatType
+syn region radianceID start="\<plastic\>"    end="\<\k*\>" contains=radianceMatType
+syn region radianceID start="\<trans\>"      end="\<\k*\>" contains=radianceMatType
+syn region radianceID start="\<metal2\>"     end="\<\k*\>" contains=radianceMatType
+syn region radianceID start="\<plastic2\>"   end="\<\k*\>" contains=radianceMatType
+syn region radianceID start="\<trans2\>"     end="\<\k*\>" contains=radianceMatType
+syn region radianceID start="\<metfunc\>"    end="\<\k*\>" contains=radianceMatType
+syn region radianceID start="\<plasfunc\>"   end="\<\k*\>" contains=radianceMatType
+syn region radianceID start="\<transfunc\>"  end="\<\k*\>" contains=radianceMatType
+syn region radianceID start="\<metdata\>"    end="\<\k*\>" contains=radianceMatType
+syn region radianceID start="\<plasdata\>"   end="\<\k*\>" contains=radianceMatType
+syn region radianceID start="\<transdata\>"  end="\<\k*\>" contains=radianceMatType
+syn region radianceID start="\<dielectric\>" end="\<\k*\>" contains=radianceMatType
+syn region radianceID start="\<interface\>"  end="\<\k*\>" contains=radianceMatType
+syn region radianceID start="\<glass\>"      end="\<\k*\>" contains=radianceMatType
+syn region radianceID start="\<BRTDfunc\>"   end="\<\k*\>" contains=radianceMatType
+syn region radianceID start="\<antimatter\>" end="\<\k*\>" contains=radianceMatType
+
+syn region radianceID start="\<colorfunc\>"  end="\<\k*\>" contains=radiancePatType
+syn region radianceID start="\<brightfunc\>" end="\<\k*\>" contains=radiancePatType
+syn region radianceID start="\<colordata\>"  end="\<\k*\>" contains=radiancePatType
+syn region radianceID start="\<brightdata\>" end="\<\k*\>" contains=radiancePatType
+syn region radianceID start="\<colorpict\>"  end="\<\k*\>" contains=radiancePatType
+syn region radianceID start="\<colortext\>"  end="\<\k*\>" contains=radiancePatType
+syn region radianceID start="\<brighttext\>" end="\<\k*\>" contains=radiancePatType
+
+syn region radianceID start="\<texfunc\>"    end="\<\k*\>" contains=radianceTexType
+syn region radianceID start="\<texdata\>"    end="\<\k*\>" contains=radianceTexType
+
+syn region radianceID start="\<mixfunc\>"    end="\<\k*\>" contains=radianceMixType
+syn region radianceID start="\<mixdata\>"    end="\<\k*\>" contains=radianceMixType
+syn region radianceID start="\<mixtext\>"    end="\<\k*\>" contains=radianceMixType
+
+" external commands (generators, xform et al.)
+syn match radianceCommand "^\s*!\s*[^\s]\+\>"
+
+" The usual suspects
+syn keyword radianceTodo contained TODO XXX
+syn match radianceComment "#.*$" contains=radianceTodo
+
+" Define the default highlighting.
+" For version 5.7 and earlier: only when not done already
+" For version 5.8 and later: only when an item doesn't have highlighting yet
+if version >= 508 || !exists("did_radiance_syn_inits")
+  if version < 508
+    let did_radiance_syn_inits = 1
+    command -nargs=+ HiLink hi link <args>
+  else
+    command -nargs=+ HiLink hi def link <args>
+  endif
+  HiLink radianceKeyword	Keyword
+  HiLink radianceExtraType	Type
+  HiLink radianceSurfType	Type
+  HiLink radianceLightType	Type
+  HiLink radianceMatType	Type
+  HiLink radiancePatType	Type
+  HiLink radianceTexType	Type
+  HiLink radianceMixType	Type
+  HiLink radianceComment	Comment
+  HiLink radianceCommand	Function
+  HiLink radianceID		String
+  HiLink radianceTodo		Todo
+  delcommand HiLink
+endif
+
+let b:current_syntax = "radiance"
+
+" vim: ts=8 sw=2
--- /dev/null
+++ b/lib/vimfiles/syntax/ratpoison.vim
@@ -1,0 +1,272 @@
+" Vim syntax file
+" Language:	Ratpoison configuration/commands file ( /etc/ratpoisonrc ~/.ratpoisonrc )
+" Maintainer:	Doug Kearns <djkea2@gus.gscit.monash.edu.au>
+" URL:		http://gus.gscit.monash.edu.au/~djkea2/vim/syntax/ratpoison.vim
+" Last Change:	2005 Oct 06
+
+" For version 5.x: Clear all syntax items
+" For version 6.x: Quit when a syntax file was already loaded
+if version < 600
+  syntax clear
+elseif exists("b:current_syntax")
+  finish
+endif
+
+syn match   ratpoisonComment	"^\s*#.*$"		contains=ratpoisonTodo
+
+syn keyword ratpoisonTodo	TODO NOTE FIXME XXX	contained
+
+syn case ignore
+syn keyword ratpoisonBooleanArg	on off			contained
+syn case match
+
+syn keyword ratpoisonCommandArg abort addhook alias banish chdir		contained
+syn keyword ratpoisonCommandArg clrunmanaged cnext colon compat cother		contained
+syn keyword ratpoisonCommandArg cprev curframe dedicate definekey delete	contained
+syn keyword ratpoisonCommandArg delkmap describekey echo escape exec		contained
+syn keyword ratpoisonCommandArg fdump focus focusdown focuslast focusleft	contained
+syn keyword ratpoisonCommandArg focusprev focusright focusup frestore fselect	contained
+syn keyword ratpoisonCommandArg gdelete getenv getsel gmerge gmove		contained
+syn keyword ratpoisonCommandArg gnew gnewbg gnext gprev gravity			contained
+syn keyword ratpoisonCommandArg groups gselect help hsplit inext		contained
+syn keyword ratpoisonCommandArg info iother iprev kill lastmsg			contained
+syn keyword ratpoisonCommandArg license link listhook meta msgwait		contained
+syn keyword ratpoisonCommandArg newkmap newwm next nextscreen number		contained
+syn keyword ratpoisonCommandArg only other prev prevscreen prompt		contained
+syn keyword ratpoisonCommandArg putsel quit ratclick rathold ratrelwarp		contained
+syn keyword ratpoisonCommandArg ratwarp readkey redisplay redo remhook		contained
+syn keyword ratpoisonCommandArg remove resize restart rudeness sdump		contained
+syn keyword ratpoisonCommandArg select set setenv sfdump shrink			contained
+syn keyword ratpoisonCommandArg source sselect startup_message time title	contained
+syn keyword ratpoisonCommandArg tmpwm unalias undefinekey undo unmanage		contained
+syn keyword ratpoisonCommandArg unsetenv verbexec version vsplit warp		contained
+syn keyword ratpoisonCommandArg windows						contained
+
+syn match   ratpoisonGravityArg "\<\(n\|north\)\>"	contained
+syn match   ratpoisonGravityArg "\<\(nw\|northwest\)\>"	contained
+syn match   ratpoisonGravityArg "\<\(ne\|northeast\)\>"	contained
+syn match   ratpoisonGravityArg "\<\(w\|west\)\>"	contained
+syn match   ratpoisonGravityArg "\<\(c\|center\)\>"	contained
+syn match   ratpoisonGravityArg "\<\(e\|east\)\>"	contained
+syn match   ratpoisonGravityArg "\<\(s\|south\)\>"	contained
+syn match   ratpoisonGravityArg "\<\(sw\|southwest\)\>"	contained
+syn match   ratpoisonGravityArg "\<\(se\|southeast\)\>"	contained
+syn case match
+
+syn match   ratpoisonKeySeqArg  "\<\([CMASH]\(-[CMASH]\)\{,4}-\)\=\(F[1-9][0-9]\=\|\(\a\|\d\)\)\>" contained nextgroup=ratpoisonCommandArg skipwhite
+
+syn match   ratpoisonKeySeqArg  "\<\([CMASH]\(-[CMASH]\)\{,4}-\)\=\(space\|exclam\|quotedbl\)\>" contained nextgroup=ratpoisonCommandArg skipwhite
+syn match   ratpoisonKeySeqArg  "\<\([CMASH]\(-[CMASH]\)\{,4}-\)\=\(numbersign\|dollar\|percent\|ampersand\)\>" contained nextgroup=ratpoisonCommandArg skipwhite
+syn match   ratpoisonKeySeqArg  "\<\([CMASH]\(-[CMASH]\)\{,4}-\)\=\(apostrophe\|quoteright\|parenleft\)\>" contained nextgroup=ratpoisonCommandArg skipwhite
+syn match   ratpoisonKeySeqArg  "\<\([CMASH]\(-[CMASH]\)\{,4}-\)\=\(parenright\|asterisk\|plus\|comma\)\>" contained nextgroup=ratpoisonCommandArg skipwhite
+syn match   ratpoisonKeySeqArg  "\<\([CMASH]\(-[CMASH]\)\{,4}-\)\=\(minus\|period\|slash\|colon\|semicolon\)\>" contained nextgroup=ratpoisonCommandArg skipwhite
+syn match   ratpoisonKeySeqArg  "\<\([CMASH]\(-[CMASH]\)\{,4}-\)\=\(less\|equal\|greater\|question\|at\)\>" contained nextgroup=ratpoisonCommandArg skipwhite
+syn match   ratpoisonKeySeqArg  "\<\([CMASH]\(-[CMASH]\)\{,4}-\)\=\(bracketleft\|backslash\|bracketright\)\>" contained nextgroup=ratpoisonCommandArg skipwhite
+syn match   ratpoisonKeySeqArg  "\<\([CMASH]\(-[CMASH]\)\{,4}-\)\=\(asciicircum\|underscore\|grave\)\>" contained nextgroup=ratpoisonCommandArg skipwhite
+syn match   ratpoisonKeySeqArg  "\<\([CMASH]\(-[CMASH]\)\{,4}-\)\=\(quoteleft\|braceleft\|bar\|braceright\)\>" contained nextgroup=ratpoisonCommandArg skipwhite
+syn match   ratpoisonKeySeqArg  "\<\([CMASH]\(-[CMASH]\)\{,4}-\)\=\(asciitilde\)\>" contained nextgroup=ratpoisonCommandArg skipwhite
+
+syn match   ratpoisonKeySeqArg  "\<\([CMASH]\(-[CMASH]\)\{,4}-\)\=\(BackSpace\|Tab\|Linefeed\|Clear\)\>" contained nextgroup=ratpoisonCommandArg skipwhite
+syn match   ratpoisonKeySeqArg  "\<\([CMASH]\(-[CMASH]\)\{,4}-\)\=\(Return\|Pause\|Scroll_Lock\)\>" contained nextgroup=ratpoisonCommandArg skipwhite
+syn match   ratpoisonKeySeqArg  "\<\([CMASH]\(-[CMASH]\)\{,4}-\)\=\(Sys_Req\|Escape\|Delete\)\>" contained nextgroup=ratpoisonCommandArg skipwhite
+
+syn match   ratpoisonKeySeqArg  "\<\([CMASH]\(-[CMASH]\)\{,4}-\)\=\(Home\|Left\|Up\|Right\|Down\|Prior\)\>" contained nextgroup=ratpoisonCommandArg skipwhite
+syn match   ratpoisonKeySeqArg  "\<\([CMASH]\(-[CMASH]\)\{,4}-\)\=\(Page_Up\|Next\|Page_Down\|End\|Begin\)\>" contained nextgroup=ratpoisonCommandArg skipwhite
+
+syn match   ratpoisonKeySeqArg  "\<\([CMASH]\(-[CMASH]\)\{,4}-\)\=\(Select\|Print\|Execute\|Insert\|Undo\)\>" contained nextgroup=ratpoisonCommandArg skipwhite
+syn match   ratpoisonKeySeqArg  "\<\([CMASH]\(-[CMASH]\)\{,4}-\)\=\(Redo\|Menu\|Find\|Cancel\|Help\)\>" contained nextgroup=ratpoisonCommandArg skipwhite
+syn match   ratpoisonKeySeqArg  "\<\([CMASH]\(-[CMASH]\)\{,4}-\)\=\(Break\|Mode_switch\|script_switch\|Num_Lock\)\>" contained nextgroup=ratpoisonCommandArg skipwhite
+
+syn match   ratpoisonKeySeqArg  "\<\([CMASH]\(-[CMASH]\)\{,4}-\)\=KP_\(Space\|Tab\|Enter\|F[1234]\)\>" contained nextgroup=ratpoisonCommandArg skipwhite
+syn match   ratpoisonKeySeqArg  "\<\([CMASH]\(-[CMASH]\)\{,4}-\)\=KP_\(Home\|Left\|Up\|Right\|Down\)\>" contained nextgroup=ratpoisonCommandArg skipwhite
+syn match   ratpoisonKeySeqArg  "\<\([CMASH]\(-[CMASH]\)\{,4}-\)\=KP_\(Prior\|Page_Up\|Next\|Page_Down\)\>" contained nextgroup=ratpoisonCommandArg skipwhite
+syn match   ratpoisonKeySeqArg  "\<\([CMASH]\(-[CMASH]\)\{,4}-\)\=KP_\(End\|Begin\|Insert\|Delete\)\>" contained nextgroup=ratpoisonCommandArg skipwhite
+syn match   ratpoisonKeySeqArg  "\<\([CMASH]\(-[CMASH]\)\{,4}-\)\=KP_\(Equal\|Multiply\|Add\|Separator\)\>" contained nextgroup=ratpoisonCommandArg skipwhite
+syn match   ratpoisonKeySeqArg  "\<\([CMASH]\(-[CMASH]\)\{,4}-\)\=KP_\(Subtract\|Decimal\|Divide\|\d\)\>" contained nextgroup=ratpoisonCommandArg skipwhite
+
+syn match   ratpoisonHookArg    "\<\(key\|switchwin\|switchframe\|switchgroup\|quit\|restart\)\>" contained
+
+syn match   ratpoisonNumberArg  "\<\d\+\>"	contained nextgroup=ratpoisonNumberArg skipwhite
+
+syn keyword ratpoisonSetArg	barborder	contained nextgroup=ratpoisonNumberArg
+syn keyword ratpoisonSetArg	bargravity	contained nextgroup=ratpoisonGravityArg
+syn keyword ratpoisonSetArg	barpadding	contained nextgroup=ratpoisonNumberArg
+syn keyword ratpoisonSetArg	bgcolor
+syn keyword ratpoisonSetArg	border		contained nextgroup=ratpoisonNumberArg
+syn keyword ratpoisonSetArg	fgcolor
+syn keyword ratpoisonSetArg	font
+syn keyword ratpoisonSetArg	framesels
+syn keyword ratpoisonSetArg	inputwidth	contained nextgroup=ratpoisonNumberArg
+syn keyword ratpoisonSetArg	maxsizegravity	contained nextgroup=ratpoisonGravityArg
+syn keyword ratpoisonSetArg	padding		contained nextgroup=ratpoisonNumberArg
+syn keyword ratpoisonSetArg	resizeunit	contained nextgroup=ratpoisonNumberArg
+syn keyword ratpoisonSetArg	transgravity	contained nextgroup=ratpoisonGravityArg
+syn keyword ratpoisonSetArg	waitcursor	contained nextgroup=ratpoisonNumberArg
+syn keyword ratpoisonSetArg	winfmt		contained nextgroup=ratpoisonWinFmtArg
+syn keyword ratpoisonSetArg	wingravity	contained nextgroup=ratpoisonGravityArg
+syn keyword ratpoisonSetArg	winliststyle	contained nextgroup=ratpoisonWinListArg
+syn keyword ratpoisonSetArg	winname		contained nextgroup=ratpoisonWinNameArg
+
+syn match   ratpoisonWinFmtArg  "%[nstacil]"			contained nextgroup=ratpoisonWinFmtArg skipwhite
+
+syn match   ratpoisonWinListArg "\<\(row\|column\)\>"		contained
+
+syn match   ratpoisonWinNameArg "\<\(name\|title\|class\)\>"	contained
+
+syn match   ratpoisonDefCommand		"^\s*set\s*"			nextgroup=ratpoisonSetArg
+syn match   ratpoisonDefCommand		"^\s*defbarborder\s*"		nextgroup=ratpoisonNumberArg
+syn match   ratpoisonDefCommand		"^\s*defbargravity\s*"		nextgroup=ratpoisonGravityArg
+syn match   ratpoisonDefCommand		"^\s*defbarpadding\s*"		nextgroup=ratpoisonNumberArg
+syn match   ratpoisonDefCommand		"^\s*defbgcolor\s*"
+syn match   ratpoisonDefCommand		"^\s*defborder\s*"		nextgroup=ratpoisonNumberArg
+syn match   ratpoisonDefCommand		"^\s*deffgcolor\s*"
+syn match   ratpoisonDefCommand		"^\s*deffont\s*"
+syn match   ratpoisonDefCommand		"^\s*defframesels\s*"
+syn match   ratpoisonDefCommand		"^\s*definputwidth\s*"		nextgroup=ratpoisonNumberArg
+syn match   ratpoisonDefCommand		"^\s*defmaxsizegravity\s*"	nextgroup=ratpoisonGravityArg
+syn match   ratpoisonDefCommand		"^\s*defpadding\s*"		nextgroup=ratpoisonNumberArg
+syn match   ratpoisonDefCommand		"^\s*defresizeunit\s*"		nextgroup=ratpoisonNumberArg
+syn match   ratpoisonDefCommand		"^\s*deftransgravity\s*"	nextgroup=ratpoisonGravityArg
+syn match   ratpoisonDefCommand		"^\s*defwaitcursor\s*"		nextgroup=ratpoisonNumberArg
+syn match   ratpoisonDefCommand		"^\s*defwinfmt\s*"		nextgroup=ratpoisonWinFmtArg
+syn match   ratpoisonDefCommand		"^\s*defwingravity\s*"		nextgroup=ratpoisonGravityArg
+syn match   ratpoisonDefCommand		"^\s*defwinliststyle\s*"	nextgroup=ratpoisonWinListArg
+syn match   ratpoisonDefCommand		"^\s*defwinname\s*"		nextgroup=ratpoisonWinNameArg
+syn match   ratpoisonDefCommand		"^\s*msgwait\s*"		nextgroup=ratpoisonNumberArg
+
+syn match   ratpoisonStringCommand	"^\s*\zsaddhook\ze\s*"		nextgroup=ratpoisonHookArg
+syn match   ratpoisonStringCommand	"^\s*\zsalias\ze\s*"
+syn match   ratpoisonStringCommand	"^\s*\zsbind\ze\s*"		nextgroup=ratpoisonKeySeqArg
+syn match   ratpoisonStringCommand	"^\s*\zschdir\ze\s*"
+syn match   ratpoisonStringCommand	"^\s*\zscolon\ze\s*"		nextgroup=ratpoisonCommandArg
+syn match   ratpoisonStringCommand	"^\s*\zsdedicate\ze\s*"		nextgroup=ratpoisonNumberArg
+syn match   ratpoisonStringCommand	"^\s*\zsdefinekey\ze\s*"
+syn match   ratpoisonStringCommand	"^\s*\zsdelkmap\ze\s*"
+syn match   ratpoisonStringCommand	"^\s*\zsdescribekey\ze\s*"
+syn match   ratpoisonStringCommand	"^\s*\zsecho\ze\s*"
+syn match   ratpoisonStringCommand	"^\s*\zsescape\ze\s*"		nextgroup=ratpoisonKeySeqArg
+syn match   ratpoisonStringCommand	"^\s*\zsexec\ze\s*"
+syn match   ratpoisonStringCommand	"^\s*\zsfdump\ze\s*"
+syn match   ratpoisonStringCommand	"^\s*\zsfrestore\ze\s*"
+syn match   ratpoisonStringCommand	"^\s*\zsgdelete\ze\s*"
+syn match   ratpoisonStringCommand	"^\s*\zsgetenv\ze\s*"
+syn match   ratpoisonStringCommand	"^\s*\zsgravity\ze\s*"		nextgroup=ratpoisonGravityArg
+syn match   ratpoisonStringCommand	"^\s*\zsgselect\ze\s*"
+syn match   ratpoisonStringCommand	"^\s*\zslink\ze\s*"		nextgroup=ratpoisonKeySeqArg
+syn match   ratpoisonStringCommand	"^\s*\zslisthook\ze\s*"		nextgroup=ratpoisonHookArg
+syn match   ratpoisonStringCommand	"^\s*\zsnewkmap\ze\s*"
+syn match   ratpoisonStringCommand	"^\s*\zsnewwm\ze\s*"
+syn match   ratpoisonStringCommand	"^\s*\zsnumber\ze\s*"		nextgroup=ratpoisonNumberArg
+syn match   ratpoisonStringCommand	"^\s*\zsprompt\ze\s*"
+syn match   ratpoisonStringCommand	"^\s*\zsratwarp\ze\s*"
+syn match   ratpoisonStringCommand	"^\s*\zsratrelwarp\ze\s*"
+syn match   ratpoisonStringCommand	"^\s*\zsratclick\ze\s*"
+syn match   ratpoisonStringCommand	"^\s*\zsrathold\ze\s*"
+syn match   ratpoisonStringCommand	"^\s*\zsreadkey\ze\s*"
+syn match   ratpoisonStringCommand	"^\s*\zsremhook\ze\s*"		nextgroup=ratpoisonHookArg
+syn match   ratpoisonStringCommand	"^\s*\zsresize\ze\s*"		nextgroup=ratpoisonNumberArg
+syn match   ratpoisonStringCommand	"^\s*\zsrudeness\ze\s*"		nextgroup=ratpoisonNumberArg
+syn match   ratpoisonStringCommand	"^\s*\zsselect\ze\s*"		nextgroup=ratpoisonNumberArg
+syn match   ratpoisonStringCommand	"^\s*\zssetenv\ze\s*"
+syn match   ratpoisonStringCommand	"^\s*\zssource\ze\s*"
+syn match   ratpoisonStringCommand	"^\s*\zssselect\ze\s*"
+syn match   ratpoisonStringCommand	"^\s*\zsstartup_message\ze\s*"	nextgroup=ratpoisonBooleanArg
+syn match   ratpoisonStringCommand	"^\s*\zstitle\ze\s*"
+syn match   ratpoisonStringCommand	"^\s*\zstmpwm\ze\s*"
+syn match   ratpoisonStringCommand	"^\s*\zsunalias\ze\s*"
+syn match   ratpoisonStringCommand	"^\s*\zsunbind\ze\s*"		nextgroup=ratpoisonKeySeqArg
+syn match   ratpoisonStringCommand	"^\s*\zsundefinekey\ze\s*"
+syn match   ratpoisonStringCommand	"^\s*\zsunmanage\ze\s*"
+syn match   ratpoisonStringCommand	"^\s*\zsunsetenv\ze\s*"
+syn match   ratpoisonStringCommand	"^\s*\zsverbexec\ze\s*"
+syn match   ratpoisonStringCommand	"^\s*\zswarp\ze\s*"		nextgroup=ratpoisonBooleanArg
+
+syn match   ratpoisonVoidCommand	"^\s*\zsabort\ze\s*$"
+syn match   ratpoisonVoidCommand	"^\s*\zsbanish\ze\s*$"
+syn match   ratpoisonVoidCommand	"^\s*\zsclrunmanaged\ze\s*$"
+syn match   ratpoisonVoidCommand	"^\s*\zscnext\ze\s*$"
+syn match   ratpoisonVoidCommand	"^\s*\zscompat\ze\s*$"
+syn match   ratpoisonVoidCommand	"^\s*\zscother\ze\s*$"
+syn match   ratpoisonVoidCommand	"^\s*\zscprev\ze\s*$"
+syn match   ratpoisonVoidCommand	"^\s*\zscurframe\ze\s*$"
+syn match   ratpoisonVoidCommand	"^\s*\zsdelete\ze\s*$"
+syn match   ratpoisonVoidCommand	"^\s*\zsfocusdown\ze\s*$"
+syn match   ratpoisonVoidCommand	"^\s*\zsfocuslast\ze\s*$"
+syn match   ratpoisonVoidCommand	"^\s*\zsfocusleft\ze\s*$"
+syn match   ratpoisonVoidCommand	"^\s*\zsfocusprev\ze\s*$"
+syn match   ratpoisonVoidCommand	"^\s*\zsfocusright\ze\s*$"
+syn match   ratpoisonVoidCommand	"^\s*\zsfocusup\ze\s*$"
+syn match   ratpoisonVoidCommand	"^\s*\zsfocus\ze\s*$"
+syn match   ratpoisonVoidCommand	"^\s*\zsfselect\ze\s*$"
+syn match   ratpoisonVoidCommand	"^\s*\zsgetsel\ze\s*$"
+syn match   ratpoisonVoidCommand	"^\s*\zsgmerge\ze\s*$"
+syn match   ratpoisonVoidCommand	"^\s*\zsgmove\ze\s*$"
+syn match   ratpoisonVoidCommand	"^\s*\zsgnewbg\ze\s*$"
+syn match   ratpoisonVoidCommand	"^\s*\zsgnew\ze\s*$"
+syn match   ratpoisonVoidCommand	"^\s*\zsgnext\ze\s*$"
+syn match   ratpoisonVoidCommand	"^\s*\zsgprev\ze\s*$"
+syn match   ratpoisonVoidCommand	"^\s*\zsgroups\ze\s*$"
+syn match   ratpoisonVoidCommand	"^\s*\zshelp\ze\s*$"
+syn match   ratpoisonVoidCommand	"^\s*\zshsplit\ze\s*$"
+syn match   ratpoisonVoidCommand	"^\s*\zsinext\ze\s*$"
+syn match   ratpoisonVoidCommand	"^\s*\zsinfo\ze\s*$"
+syn match   ratpoisonVoidCommand	"^\s*\zsiother\ze\s*$"
+syn match   ratpoisonVoidCommand	"^\s*\zsiprev\ze\s*$"
+syn match   ratpoisonVoidCommand	"^\s*\zskill\ze\s*$"
+syn match   ratpoisonVoidCommand	"^\s*\zslastmsg\ze\s*$"
+syn match   ratpoisonVoidCommand	"^\s*\zslicense\ze\s*$"
+syn match   ratpoisonVoidCommand	"^\s*\zsmeta\ze\s*$"
+syn match   ratpoisonVoidCommand	"^\s*\zsnextscreen\ze\s*$"
+syn match   ratpoisonVoidCommand	"^\s*\zsnext\ze\s*$"
+syn match   ratpoisonVoidCommand	"^\s*\zsonly\ze\s*$"
+syn match   ratpoisonVoidCommand	"^\s*\zsother\ze\s*$"
+syn match   ratpoisonVoidCommand	"^\s*\zsprevscreen\ze\s*$"
+syn match   ratpoisonVoidCommand	"^\s*\zsprev\ze\s*$"
+syn match   ratpoisonVoidCommand	"^\s*\zsputsel\ze\s*$"
+syn match   ratpoisonVoidCommand	"^\s*\zsquit\ze\s*$"
+syn match   ratpoisonVoidCommand	"^\s*\zsredisplay\ze\s*$"
+syn match   ratpoisonVoidCommand	"^\s*\zsredo\ze\s*$"
+syn match   ratpoisonVoidCommand	"^\s*\zsremove\ze\s*$"
+syn match   ratpoisonVoidCommand	"^\s*\zsrestart\ze\s*$"
+syn match   ratpoisonVoidCommand	"^\s*\zssdump\ze\s*$"
+syn match   ratpoisonVoidCommand	"^\s*\zssfdump\ze\s*$"
+syn match   ratpoisonVoidCommand	"^\s*\zsshrink\ze\s*$"
+syn match   ratpoisonVoidCommand	"^\s*\zssplit\ze\s*$"
+syn match   ratpoisonVoidCommand	"^\s*\zstime\ze\s*$"
+syn match   ratpoisonVoidCommand	"^\s*\zsundo\ze\s*$"
+syn match   ratpoisonVoidCommand	"^\s*\zsversion\ze\s*$"
+syn match   ratpoisonVoidCommand	"^\s*\zsvsplit\ze\s*$"
+syn match   ratpoisonVoidCommand	"^\s*\zswindows\ze\s*$"
+
+" Define the default highlighting.
+" For version 5.7 and earlier: only when not done already
+" For version 5.8 and later: only when an item doesn't have highlighting yet
+if version >= 508 || !exists("did_ratpoison_syn_inits")
+  if version < 508
+    let did_ratpoison_syn_inits = 1
+    command -nargs=+ HiLink hi link <args>
+  else
+    command -nargs=+ HiLink hi def link <args>
+  endif
+
+  HiLink ratpoisonBooleanArg	Boolean
+  HiLink ratpoisonCommandArg	Keyword
+  HiLink ratpoisonComment	Comment
+  HiLink ratpoisonDefCommand	Identifier
+  HiLink ratpoisonGravityArg	Constant
+  HiLink ratpoisonKeySeqArg	Special
+  HiLink ratpoisonNumberArg	Number
+  HiLink ratpoisonSetArg	Keyword
+  HiLink ratpoisonStringCommand	Identifier
+  HiLink ratpoisonTodo		Todo
+  HiLink ratpoisonVoidCommand	Identifier
+  HiLink ratpoisonWinFmtArg	Special
+  HiLink ratpoisonWinNameArg	Constant
+  HiLink ratpoisonWinListArg	Constant
+
+  delcommand HiLink
+endif
+
+let b:current_syntax = "ratpoison"
+
+" vim: ts=8
--- /dev/null
+++ b/lib/vimfiles/syntax/rc.vim
@@ -1,0 +1,200 @@
+" Vim syntax file
+" Language:	M$ Resource files (*.rc)
+" Maintainer:	Heiko Erhardt <Heiko.Erhardt@munich.netsurf.de>
+" Last Change:	2001 May 09
+
+" This file is based on the c.vim
+
+" For version 5.x: Clear all syntax items
+" For version 6.x: Quit when a syntax file was already loaded
+if version < 600
+  syntax clear
+elseif exists("b:current_syntax")
+  finish
+endif
+
+" Common RC keywords
+syn keyword rcLanguage LANGUAGE
+
+syn keyword rcMainObject TEXTINCLUDE VERSIONINFO BITMAP ICON CURSOR CURSOR
+syn keyword rcMainObject MENU ACCELERATORS TOOLBAR DIALOG
+syn keyword rcMainObject STRINGTABLE MESSAGETABLE RCDATA DLGINIT DESIGNINFO
+
+syn keyword rcSubObject POPUP MENUITEM SEPARATOR
+syn keyword rcSubObject CONTROL LTEXT CTEXT EDITTEXT
+syn keyword rcSubObject BUTTON PUSHBUTTON DEFPUSHBUTTON GROUPBOX LISTBOX COMBOBOX
+syn keyword rcSubObject FILEVERSION PRODUCTVERSION FILEFLAGSMASK FILEFLAGS FILEOS
+syn keyword rcSubObject FILETYPE FILESUBTYPE
+
+syn keyword rcCaptionParam CAPTION
+syn keyword rcParam CHARACTERISTICS CLASS STYLE EXSTYLE VERSION FONT
+
+syn keyword rcStatement BEGIN END BLOCK VALUE
+
+syn keyword rcCommonAttribute PRELOAD LOADONCALL FIXED MOVEABLE DISCARDABLE PURE IMPURE
+
+syn keyword rcAttribute WS_OVERLAPPED WS_POPUP WS_CHILD WS_MINIMIZE WS_VISIBLE WS_DISABLED WS_CLIPSIBLINGS
+syn keyword rcAttribute WS_CLIPCHILDREN WS_MAXIMIZE WS_CAPTION WS_BORDER WS_DLGFRAME WS_VSCROLL WS_HSCROLL
+syn keyword rcAttribute WS_SYSMENU WS_THICKFRAME WS_GROUP WS_TABSTOP WS_MINIMIZEBOX WS_MAXIMIZEBOX WS_TILED
+syn keyword rcAttribute WS_ICONIC WS_SIZEBOX WS_TILEDWINDOW WS_OVERLAPPEDWINDOW WS_POPUPWINDOW WS_CHILDWINDOW
+syn keyword rcAttribute WS_EX_DLGMODALFRAME WS_EX_NOPARENTNOTIFY WS_EX_TOPMOST WS_EX_ACCEPTFILES
+syn keyword rcAttribute WS_EX_TRANSPARENT WS_EX_MDICHILD WS_EX_TOOLWINDOW WS_EX_WINDOWEDGE WS_EX_CLIENTEDGE
+syn keyword rcAttribute WS_EX_CONTEXTHELP WS_EX_RIGHT WS_EX_LEFT WS_EX_RTLREADING WS_EX_LTRREADING
+syn keyword rcAttribute WS_EX_LEFTSCROLLBAR WS_EX_RIGHTSCROLLBAR WS_EX_CONTROLPARENT WS_EX_STATICEDGE
+syn keyword rcAttribute WS_EX_APPWINDOW WS_EX_OVERLAPPEDWINDOW WS_EX_PALETTEWINDOW
+syn keyword rcAttribute ES_LEFT ES_CENTER ES_RIGHT ES_MULTILINE ES_UPPERCASE ES_LOWERCASE ES_PASSWORD
+syn keyword rcAttribute ES_AUTOVSCROLL ES_AUTOHSCROLL ES_NOHIDESEL ES_OEMCONVERT ES_READONLY ES_WANTRETURN
+syn keyword rcAttribute ES_NUMBER
+syn keyword rcAttribute BS_PUSHBUTTON BS_DEFPUSHBUTTON BS_CHECKBOX BS_AUTOCHECKBOX BS_RADIOBUTTON BS_3STATE
+syn keyword rcAttribute BS_AUTO3STATE BS_GROUPBOX BS_USERBUTTON BS_AUTORADIOBUTTON BS_OWNERDRAW BS_LEFTTEXT
+syn keyword rcAttribute BS_TEXT BS_ICON BS_BITMAP BS_LEFT BS_RIGHT BS_CENTER BS_TOP BS_BOTTOM BS_VCENTER
+syn keyword rcAttribute BS_PUSHLIKE BS_MULTILINE BS_NOTIFY BS_FLAT BS_RIGHTBUTTON
+syn keyword rcAttribute SS_LEFT SS_CENTER SS_RIGHT SS_ICON SS_BLACKRECT SS_GRAYRECT SS_WHITERECT
+syn keyword rcAttribute SS_BLACKFRAME SS_GRAYFRAME SS_WHITEFRAME SS_USERITEM SS_SIMPLE SS_LEFTNOWORDWRAP
+syn keyword rcAttribute SS_OWNERDRAW SS_BITMAP SS_ENHMETAFILE SS_ETCHEDHORZ SS_ETCHEDVERT SS_ETCHEDFRAME
+syn keyword rcAttribute SS_TYPEMASK SS_NOPREFIX SS_NOTIFY SS_CENTERIMAGE SS_RIGHTJUST SS_REALSIZEIMAGE
+syn keyword rcAttribute SS_SUNKEN SS_ENDELLIPSIS SS_PATHELLIPSIS SS_WORDELLIPSIS SS_ELLIPSISMASK
+syn keyword rcAttribute DS_ABSALIGN DS_SYSMODAL DS_LOCALEDIT DS_SETFONT DS_MODALFRAME DS_NOIDLEMSG
+syn keyword rcAttribute DS_SETFOREGROUND DS_3DLOOK DS_FIXEDSYS DS_NOFAILCREATE DS_CONTROL DS_CENTER
+syn keyword rcAttribute DS_CENTERMOUSE DS_CONTEXTHELP
+syn keyword rcAttribute LBS_NOTIFY LBS_SORT LBS_NOREDRAW LBS_MULTIPLESEL LBS_OWNERDRAWFIXED
+syn keyword rcAttribute LBS_OWNERDRAWVARIABLE LBS_HASSTRINGS LBS_USETABSTOPS LBS_NOINTEGRALHEIGHT
+syn keyword rcAttribute LBS_MULTICOLUMN LBS_WANTKEYBOARDINPUT LBS_EXTENDEDSEL LBS_DISABLENOSCROLL
+syn keyword rcAttribute LBS_NODATA LBS_NOSEL LBS_STANDARD
+syn keyword rcAttribute CBS_SIMPLE CBS_DROPDOWN CBS_DROPDOWNLIST CBS_OWNERDRAWFIXED CBS_OWNERDRAWVARIABLE
+syn keyword rcAttribute CBS_AUTOHSCROLL CBS_OEMCONVERT CBS_SORT CBS_HASSTRINGS CBS_NOINTEGRALHEIGHT
+syn keyword rcAttribute CBS_DISABLENOSCROLL CBS_UPPERCASE CBS_LOWERCASE
+syn keyword rcAttribute SBS_HORZ SBS_VERT SBS_TOPALIGN SBS_LEFTALIGN SBS_BOTTOMALIGN SBS_RIGHTALIGN
+syn keyword rcAttribute SBS_SIZEBOXTOPLEFTALIGN SBS_SIZEBOXBOTTOMRIGHTALIGN SBS_SIZEBOX SBS_SIZEGRIP
+syn keyword rcAttribute CCS_TOP CCS_NOMOVEY CCS_BOTTOM CCS_NORESIZE CCS_NOPARENTALIGN CCS_ADJUSTABLE
+syn keyword rcAttribute CCS_NODIVIDER
+syn keyword rcAttribute LVS_ICON LVS_REPORT LVS_SMALLICON LVS_LIST LVS_TYPEMASK LVS_SINGLESEL LVS_SHOWSELALWAYS
+syn keyword rcAttribute LVS_SORTASCENDING LVS_SORTDESCENDING LVS_SHAREIMAGELISTS LVS_NOLABELWRAP
+syn keyword rcAttribute LVS_EDITLABELS LVS_OWNERDATA LVS_NOSCROLL LVS_TYPESTYLEMASK  LVS_ALIGNTOP LVS_ALIGNLEFT
+syn keyword rcAttribute LVS_ALIGNMASK LVS_OWNERDRAWFIXED LVS_NOCOLUMNHEADER LVS_NOSORTHEADER LVS_AUTOARRANGE
+syn keyword rcAttribute TVS_HASBUTTONS TVS_HASLINES TVS_LINESATROOT TVS_EDITLABELS TVS_DISABLEDRAGDROP
+syn keyword rcAttribute TVS_SHOWSELALWAYS
+syn keyword rcAttribute TCS_FORCEICONLEFT TCS_FORCELABELLEFT TCS_TABS TCS_BUTTONS TCS_SINGLELINE TCS_MULTILINE
+syn keyword rcAttribute TCS_RIGHTJUSTIFY TCS_FIXEDWIDTH TCS_RAGGEDRIGHT TCS_FOCUSONBUTTONDOWN
+syn keyword rcAttribute TCS_OWNERDRAWFIXED TCS_TOOLTIPS TCS_FOCUSNEVER
+syn keyword rcAttribute ACS_CENTER ACS_TRANSPARENT ACS_AUTOPLAY
+syn keyword rcStdId IDI_APPLICATION IDI_HAND IDI_QUESTION IDI_EXCLAMATION IDI_ASTERISK IDI_WINLOGO IDI_WINLOGO
+syn keyword rcStdId IDI_WARNING IDI_ERROR IDI_INFORMATION
+syn keyword rcStdId IDCANCEL IDABORT IDRETRY IDIGNORE IDYES IDNO IDCLOSE IDHELP IDC_STATIC
+
+" Common RC keywords
+
+" Common RC keywords
+syn keyword rcTodo contained	TODO FIXME XXX
+
+" String and Character constants
+" Highlight special characters (those which have a backslash) differently
+syn match rcSpecial contained	"\\[0-7][0-7][0-7]\=\|\\."
+syn region rcString		start=+"+ skip=+\\\\\|\\"+ end=+"+ contains=rcSpecial
+syn match rcCharacter		"'[^\\]'"
+syn match rcSpecialCharacter	"'\\.'"
+syn match rcSpecialCharacter	"'\\[0-7][0-7]'"
+syn match rcSpecialCharacter	"'\\[0-7][0-7][0-7]'"
+
+"catch errors caused by wrong parenthesis
+syn region rcParen		transparent start='(' end=')' contains=ALLBUT,rcParenError,rcIncluded,rcSpecial,rcTodo
+syn match rcParenError		")"
+syn match rcInParen contained	"[{}]"
+
+"integer number, or floating point number without a dot and with "f".
+syn case ignore
+syn match rcNumber		"\<\d\+\(u\=l\=\|lu\|f\)\>"
+"floating point number, with dot, optional exponent
+syn match rcFloat		"\<\d\+\.\d*\(e[-+]\=\d\+\)\=[fl]\=\>"
+"floating point number, starting with a dot, optional exponent
+syn match rcFloat		"\.\d\+\(e[-+]\=\d\+\)\=[fl]\=\>"
+"floating point number, without dot, with exponent
+syn match rcFloat		"\<\d\+e[-+]\=\d\+[fl]\=\>"
+"hex number
+syn match rcNumber		"\<0x[0-9a-f]\+\(u\=l\=\|lu\)\>"
+"syn match rcIdentifier	"\<[a-z_][a-z0-9_]*\>"
+syn case match
+" flag an octal number with wrong digits
+syn match rcOctalError		"\<0[0-7]*[89]"
+
+if exists("rc_comment_strings")
+  " A comment can contain rcString, rcCharacter and rcNumber.
+  " But a "*/" inside a rcString in a rcComment DOES end the comment!  So we
+  " need to use a special type of rcString: rcCommentString, which also ends on
+  " "*/", and sees a "*" at the start of the line as comment again.
+  " Unfortunately this doesn't very well work for // type of comments :-(
+  syntax match rcCommentSkip	contained "^\s*\*\($\|\s\+\)"
+  syntax region rcCommentString	contained start=+"+ skip=+\\\\\|\\"+ end=+"+ end=+\*/+me=s-1 contains=rcSpecial,rcCommentSkip
+  syntax region rcComment2String	contained start=+"+ skip=+\\\\\|\\"+ end=+"+ end="$" contains=rcSpecial
+  syntax region rcComment	start="/\*" end="\*/" contains=rcTodo,rcCommentString,rcCharacter,rcNumber,rcFloat
+  syntax match  rcComment	"//.*" contains=rcTodo,rcComment2String,rcCharacter,rcNumber
+else
+  syn region rcComment		start="/\*" end="\*/" contains=rcTodo
+  syn match rcComment		"//.*" contains=rcTodo
+endif
+syntax match rcCommentError	"\*/"
+
+syn region rcPreCondit	start="^\s*#\s*\(if\>\|ifdef\>\|ifndef\>\|elif\>\|else\>\|endif\>\)" skip="\\$" end="$" contains=rcComment,rcString,rcCharacter,rcNumber,rcCommentError
+syn region rcIncluded contained start=+"+ skip=+\\\\\|\\"+ end=+"+
+syn match rcIncluded contained "<[^>]*>"
+syn match rcInclude		"^\s*#\s*include\>\s*["<]" contains=rcIncluded
+"syn match rcLineSkip	"\\$"
+syn region rcDefine		start="^\s*#\s*\(define\>\|undef\>\)" skip="\\$" end="$" contains=ALLBUT,rcPreCondit,rcIncluded,rcInclude,rcDefine,rcInParen
+syn region rcPreProc		start="^\s*#\s*\(pragma\>\|line\>\|warning\>\|warn\>\|error\>\)" skip="\\$" end="$" contains=ALLBUT,rcPreCondit,rcIncluded,rcInclude,rcDefine,rcInParen
+
+syn sync ccomment rcComment minlines=10
+
+" Define the default highlighting.
+" For version 5.7 and earlier: only when not done already
+" For version 5.8 and later: only when an item doesn't have highlighting yet
+if version >= 508 || !exists("did_rc_syntax_inits")
+  if version < 508
+    let did_rc_syntax_inits = 1
+    command -nargs=+ HiLink hi link <args>
+  else
+    command -nargs=+ HiLink hi def link <args>
+  endif
+
+  HiLink rcCharacter	Character
+  HiLink rcSpecialCharacter rcSpecial
+  HiLink rcNumber	Number
+  HiLink rcFloat	Float
+  HiLink rcOctalError	rcError
+  HiLink rcParenError	rcError
+  HiLink rcInParen	rcError
+  HiLink rcCommentError	rcError
+  HiLink rcInclude	Include
+  HiLink rcPreProc	PreProc
+  HiLink rcDefine	Macro
+  HiLink rcIncluded	rcString
+  HiLink rcError	Error
+  HiLink rcPreCondit	PreCondit
+  HiLink rcCommentString rcString
+  HiLink rcComment2String rcString
+  HiLink rcCommentSkip	rcComment
+  HiLink rcString	String
+  HiLink rcComment	Comment
+  HiLink rcSpecial	SpecialChar
+  HiLink rcTodo	Todo
+
+  HiLink rcAttribute	rcCommonAttribute
+  HiLink rcStdId	rcStatement
+  HiLink rcStatement	Statement
+
+  " Default color overrides
+  hi def rcLanguage	term=reverse ctermbg=Red ctermfg=Yellow guibg=Red guifg=Yellow
+  hi def rcMainObject	term=underline ctermfg=Blue guifg=Blue
+  hi def rcSubObject	ctermfg=Green guifg=Green
+  hi def rcCaptionParam	term=underline ctermfg=DarkGreen guifg=Green
+  hi def rcParam	ctermfg=DarkGreen guifg=DarkGreen
+  hi def rcStatement	ctermfg=DarkGreen guifg=DarkGreen
+  hi def rcCommonAttribute	ctermfg=Brown guifg=Brown
+
+  "HiLink rcIdentifier	Identifier
+
+  delcommand HiLink
+endif
+
+let b:current_syntax = "rc"
+
+" vim: ts=8
--- /dev/null
+++ b/lib/vimfiles/syntax/rcs.vim
@@ -1,0 +1,76 @@
+" Vim syntax file
+" Language:     RCS file
+" Maintainer:   Dmitry Vasiliev <dima at hlabs dot spb dot ru>
+" URL:          http://www.hlabs.spb.ru/vim/rcs.vim
+" Revision:     $Id: rcs.vim,v 1.2 2006/03/27 16:41:00 vimboss Exp $
+" Filenames:    *,v
+" Version:      1.11
+
+" Options:
+"   rcs_folding = 1   For folding strings
+
+" For version 5.x: Clear all syntax items.
+" For version 6.x: Quit when a syntax file was already loaded.
+if version < 600
+  syntax clear
+elseif exists("b:current_syntax")
+  finish
+endif
+
+" RCS file must end with a newline.
+syn match rcsEOFError   ".\%$" containedin=ALL
+
+" Keywords.
+syn keyword rcsKeyword  head branch access symbols locks strict
+syn keyword rcsKeyword  comment expand date author state branches
+syn keyword rcsKeyword  next desc log
+syn keyword rcsKeyword  text nextgroup=rcsTextStr skipwhite skipempty
+
+" Revision numbers and dates.
+syn match rcsNumber "\<[0-9.]\+\>" display
+
+" Strings.
+if exists("rcs_folding") && has("folding")
+  " Folded strings.
+  syn region rcsString  matchgroup=rcsString start="@" end="@" skip="@@" fold contains=rcsSpecial
+  syn region rcsTextStr matchgroup=rcsTextStr start="@" end="@" skip="@@" fold contained contains=rcsSpecial,rcsDiffLines
+else
+  syn region rcsString  matchgroup=rcsString start="@" end="@" skip="@@" contains=rcsSpecial
+  syn region rcsTextStr matchgroup=rcsTextStr start="@" end="@" skip="@@" contained contains=rcsSpecial,rcsDiffLines
+endif
+syn match rcsSpecial    "@@" contained
+syn match rcsDiffLines  "[da]\d\+ \d\+$" contained
+
+" Synchronization.
+syn sync clear
+if exists("rcs_folding") && has("folding")
+  syn sync fromstart
+else
+  " We have incorrect folding if following sync patterns is turned on.
+  syn sync match rcsSync    grouphere rcsString "[0-9.]\+\(\s\|\n\)\+log\(\s\|\n\)\+@"me=e-1
+  syn sync match rcsSync    grouphere rcsTextStr "@\(\s\|\n\)\+text\(\s\|\n\)\+@"me=e-1
+endif
+
+" Define the default highlighting.
+" For version 5.7 and earlier: only when not done already.
+" For version 5.8 and later: only when an item doesn't have highlighting yet.
+if version >= 508 || !exists("did_rcs_syn_inits")
+  if version <= 508
+    let did_rcs_syn_inits = 1
+    command -nargs=+ HiLink hi link <args>
+  else
+    command -nargs=+ HiLink hi def link <args>
+  endif
+
+  HiLink rcsKeyword     Keyword
+  HiLink rcsNumber      Identifier
+  HiLink rcsString      String
+  HiLink rcsTextStr     String
+  HiLink rcsSpecial     Special
+  HiLink rcsDiffLines   Special
+  HiLink rcsEOFError    Error
+
+  delcommand HiLink
+endif
+
+let b:current_syntax = "rcs"
--- /dev/null
+++ b/lib/vimfiles/syntax/rcslog.vim
@@ -1,0 +1,38 @@
+" Vim syntax file
+" Language:	RCS log output
+" Maintainer:	Joe Karthauser <joe@freebsd.org>
+" Last Change:	2001 May 09
+
+" For version 5.x: Clear all syntax items
+" For version 6.x: Quit when a syntax file was already loaded
+if version < 600
+  syntax clear
+elseif exists("b:current_syntax")
+  finish
+endif
+
+syn match rcslogRevision	"^revision.*$"
+syn match rcslogFile		"^RCS file:.*"
+syn match rcslogDate		"^date: .*$"
+
+" Define the default highlighting.
+" For version 5.7 and earlier: only when not done already
+" For version 5.8 and later: only when an item doesn't have highlighting yet
+if version >= 508 || !exists("did_rcslog_syntax_inits")
+  if version < 508
+    let did_rcslog_syntax_inits = 1
+    command -nargs=+ HiLink hi link <args>
+  else
+    command -nargs=+ HiLink hi def link <args>
+  endif
+
+  HiLink rcslogFile		Type
+  HiLink rcslogRevision	Constant
+  HiLink rcslogDate		Identifier
+
+  delcommand HiLink
+endif
+
+let b:current_syntax = "rcslog"
+
+" vim: ts=8
--- /dev/null
+++ b/lib/vimfiles/syntax/readline.vim
@@ -1,0 +1,175 @@
+" Vim syntax file
+" Language:         readline(3) configuration file
+" Maintainer:       Nikolai Weibull <now@bitwi.se>
+" Latest Revision:  2006-04-19
+"   readline_has_bash - if defined add support for bash specific
+"                       settings/functions
+
+if exists("b:current_syntax")
+  finish
+endif
+
+let s:cpo_save = &cpo
+set cpo&vim
+
+setlocal iskeyword=@,48-57,-
+
+syn keyword readlineTodo        contained TODO FIXME XXX NOTE
+
+syn region  readlineComment     display oneline start='^\s*#' end='$'
+                                \ contains=readlineTodo,@Spell
+
+syn match   readlineString      '^\s*[A-Za-z-]\+:'me=e-1 contains=readlineKeys
+syn region  readlineString      display oneline start=+"+ skip=+\\\\\|\\"+
+                                \ end=+"+ contains=readlineKeysTwo
+
+syn case ignore
+syn keyword readlineKeys        contained Control Meta Del Esc Escape LFD
+                                \ Newline Ret Return Rubout Space Spc Tab
+syn case match
+
+syn match   readlineKeysTwo     contained display
+                                \ +\\\([CM]-\|[e\\"'abdfnrtv]\|\o\{3}\|x\x\{3}\)+
+
+syn match   readlineKeymaps     contained display
+                                \ 'emacs\(-standard\|-meta\|-ctlx\)\='
+syn match   readlineKeymaps     contained display
+                                \ 'vi\(-move\|-command\|-insert\)\='
+
+syn keyword readlineBellStyles  contained audible visible none
+
+syn match   readlineNumber      contained display '\<\d\+\>'
+
+syn case ignore
+syn keyword readlineBoolean     contained on off
+syn case match
+
+syn keyword readlineIfOps       contained mode term
+
+syn region  readlineConditional display oneline transparent
+                                \ matchgroup=readlineConditional
+                                \ start='^\s*$if' end="$"
+                                \ contains=readlineIfOps,readlineKeymaps
+syn match   readlineConditional display '^\s*$\(else\|endif\)\>'
+
+syn match   readlineInclude     display '^\s*$include\>'
+
+syn region  readlineSet         display oneline transparent
+                                \ matchgroup=readlineKeyword start='^\s*set\>'
+                                \ end="$"me=e-1 contains=readlineNumber,
+                                \ readlineBoolean,readlineKeymaps,
+                                \ readlineBellStyles,readlineSettings
+
+syn keyword readlineSettings    contained bell-style comment-begin
+                                \ completion-ignore-case completion-query-items
+                                \ convert-meta disable-completion editing-mode
+                                \ enable-keypad expand-tilde
+                                \ horizontal-scroll-mode mark-directories
+                                \ keymap mark-modified-lines meta-flag
+                                \ input-meta output-meta
+                                \ print-completions-horizontally
+                                \ show-all-if-ambiguous visible-stats
+                                \ prefer-visible-bell blink-matching-paren
+                                \ match-hidden-files history-preserve-point
+                                \ isearch-terminators
+
+syn region  readlineBinding     display oneline transparent
+                                \ matchgroup=readlineKeyword start=':' end='$'
+                                \ contains=readlineKeys,readlineFunctions
+
+syn keyword readlineFunctions   contained display
+                                \ beginning-of-line end-of-line forward-char
+                                \ backward-char forward-word backward-word
+                                \ clear-screen redraw-current-line
+                                \ accept-line previous-history
+                                \ next-history beginning-of-history
+                                \ end-of-history reverse-search-history
+                                \ forward-search-history
+                                \ non-incremental-reverse-search-history
+                                \ non-incremental-forward-search-history
+                                \ history-search-forward
+                                \ history-search-backward
+                                \ yank-nth-arg yank-last-arg
+                                \ delete-char backward-delete-char
+                                \ forward-backward-delete-char quoted-insert
+                                \ tab-insert self-insert transpose-chars
+                                \ transpose-words upcase-word downcase-word
+                                \ capitalize-word overwrite-mode kill-line
+                                \ backward-kill-line unix-line-discard
+                                \ kill-whole-line kill-word backward-kill-word
+                                \ unix-word-rubout unix-filename-rubout
+                                \ delete-horizontal-space kill-region
+                                \ copy-region-as-kill copy-backward-word
+                                \ copy-forward-word yank yank-pop
+                                \ digit-argument universal-argument complete
+                                \ possible-completions insert-completions
+                                \ menu-complete delete-char-or-list
+                                \ start-kbd-macro end-kbd-macro
+                                \ call-last-kbd-macro re-read-init-file
+                                \ abort do-uppercase-version prefix-meta
+                                \ undo revert-line tilde-expand set-mark
+                                \ exchange-point-and-mark character-search
+                                \ character-search-backward insert-comment
+                                \ dump-functions dump-variables dump-macros
+                                \ emacs-editing-mode vi-editing-mode
+                                \ vi-complete vi-char-search vi-redo
+                                \ vi-search vi-arg-digit vi-append-eol
+                                \ vi-prev-word vi-change-to vi-delete-to
+                                \ vi-end-word vi-fetch-history vi-insert-beg
+                                \ vi-search-again vi-put vi-replace
+                                \ vi-subst vi-yank-to vi-first-print
+                                \ vi-yank-arg vi-goto-mark vi-append-mode
+                                \ vi-insertion-mode prev-history vi-set-mark
+                                \ vi-search-again vi-put vi-change-char
+                                \ vi-subst vi-delete vi-yank-to
+                                \ vi-column vi-change-case vi-overstrike
+                                \ vi-overstrike-delete do-lowercase-version
+                                \ delete-char-or-list tty-status
+                                \ arrow-key-prefix vi-back-to-indent vi-bword
+                                \ vi-bWord vi-eword vi-eWord vi-fword vi-fWord
+                                \ vi-next-word
+
+if exists("readline_has_bash")
+  syn keyword readlineFunctions contained
+                                \ shell-expand-line history-expand-line
+                                \ magic-space alias-expand-line
+                                \ history-and-alias-expand-line
+                                \ insert-last-argument operate-and-get-next
+                                \ forward-backward-delete-char
+                                \ delete-char-or-list complete-filename
+                                \ possible-filename-completions
+                                \ complete-username
+                                \ possible-username-completions
+                                \ complete-variable
+                                \ possible-variable-completions
+                                \ complete-hostname
+                                \ possible-hostname-completions
+                                \ complete-command
+                                \ possible-command-completions
+                                \ dynamic-complete-history
+                                \ complete-into-braces
+                                \ glob-expand-word glob-list-expansions
+                                \ display-shell-version glob-complete-word
+                                \ edit-and-execute-command
+endif
+
+hi def link readlineComment     Comment
+hi def link readlineTodo        Todo
+hi def link readlineString      String
+hi def link readlineKeys        SpecialChar
+hi def link readlineKeysTwo     SpecialChar
+hi def link readlineKeymaps     Constant
+hi def link readlineBellStyles  Constant
+hi def link readlineNumber      Number
+hi def link readlineBoolean     Boolean
+hi def link readlineIfOps       Type
+hi def link readlineConditional Conditional
+hi def link readlineInclude     Include
+hi def link readlineKeyword     Keyword
+hi def link readlineSettings    Type
+hi def link readlineFunctions   Type
+
+let b:current_syntax = "readline"
+
+let &cpo = s:cpo_save
+unlet s:cpo_save
--- /dev/null
+++ b/lib/vimfiles/syntax/rebol.vim
@@ -1,0 +1,216 @@
+" Vim syntax file
+" Language:	Rebol
+" Maintainer:	Mike Williams <mrw@eandem.co.uk>
+" Filenames:	*.r
+" Last Change:	27th June 2002
+" URL:		http://www.eandem.co.uk/mrw/vim
+"
+
+" For version 5.x: Clear all syntax items
+" For version 6.x: Quit when a syntax file was already loaded
+if version < 600
+  syntax clear
+elseif exists("b:current_syntax")
+  finish
+endif
+
+" Rebol is case insensitive
+syn case ignore
+
+" As per current users documentation
+if version < 600
+  set isk=@,48-57,?,!,.,',+,-,*,&,\|,=,_,~
+else
+  setlocal isk=@,48-57,?,!,.,',+,-,*,&,\|,=,_,~
+endif
+
+" Yer TODO highlighter
+syn keyword	rebolTodo	contained TODO
+
+" Comments
+syn match       rebolComment    ";.*$" contains=rebolTodo
+
+" Words
+syn match       rebolWord       "\a\k*"
+syn match       rebolWordPath   "[^[:space:]]/[^[:space]]"ms=s+1,me=e-1
+
+" Booleans
+syn keyword     rebolBoolean    true false on off yes no
+
+" Values
+" Integers
+syn match       rebolInteger    "\<[+-]\=\d\+\('\d*\)*\>"
+" Decimals
+syn match       rebolDecimal    "[+-]\=\(\d\+\('\d*\)*\)\=[,.]\d*\(e[+-]\=\d\+\)\="
+syn match       rebolDecimal    "[+-]\=\d\+\('\d*\)*\(e[+-]\=\d\+\)\="
+" Time
+syn match       rebolTime       "[+-]\=\(\d\+\('\d*\)*\:\)\{1,2}\d\+\('\d*\)*\([.,]\d\+\)\=\([AP]M\)\=\>"
+syn match       rebolTime       "[+-]\=:\d\+\([.,]\d*\)\=\([AP]M\)\=\>"
+" Dates
+" DD-MMM-YY & YYYY format
+syn match       rebolDate       "\d\{1,2}\([/-]\)\(Jan\|Feb\|Mar\|Apr\|May\|Jun\|Jul\|Aug\|Sep\|Oct\|Nov\|Dec\)\1\(\d\{2}\)\{1,2}\>"
+" DD-month-YY & YYYY format
+syn match       rebolDate       "\d\{1,2}\([/-]\)\(January\|February\|March\|April\|May\|June\|July\|August\|September\|October\|November\|December\)\1\(\d\{2}\)\{1,2}\>"
+" DD-MM-YY & YY format
+syn match       rebolDate       "\d\{1,2}\([/-]\)\d\{1,2}\1\(\d\{2}\)\{1,2}\>"
+" YYYY-MM-YY format
+syn match       rebolDate       "\d\{4}-\d\{1,2}-\d\{1,2}\>"
+" DD.MM.YYYY format
+syn match       rebolDate       "\d\{1,2}\.\d\{1,2}\.\d\{4}\>"
+" Money
+syn match       rebolMoney      "\a*\$\d\+\('\d*\)*\([,.]\d\+\)\="
+" Strings
+syn region      rebolString     oneline start=+"+ skip=+^"+ end=+"+ contains=rebolSpecialCharacter
+syn region      rebolString     start=+[^#]{+ end=+}+ skip=+{[^}]*}+ contains=rebolSpecialCharacter
+" Binary
+syn region      rebolBinary     start=+\d*#{+ end=+}+ contains=rebolComment
+" Email
+syn match       rebolEmail      "\<\k\+@\(\k\+\.\)*\k\+\>"
+" File
+syn match       rebolFile       "%\(\k\+/\)*\k\+[/]\=" contains=rebolSpecialCharacter
+syn region      rebolFile       oneline start=+%"+ end=+"+ contains=rebolSpecialCharacter
+" URLs
+syn match	rebolURL	"http://\k\+\(\.\k\+\)*\(:\d\+\)\=\(/\(\k\+/\)*\(\k\+\)\=\)*"
+syn match	rebolURL	"file://\k\+\(\.\k\+\)*/\(\k\+/\)*\k\+"
+syn match	rebolURL	"ftp://\(\k\+:\k\+@\)\=\k\+\(\.\k\+\)*\(:\d\+\)\=/\(\k\+/\)*\k\+"
+syn match	rebolURL	"mailto:\k\+\(\.\k\+\)*@\k\+\(\.\k\+\)*"
+" Issues
+syn match	rebolIssue	"#\(\d\+-\)*\d\+"
+" Tuples
+syn match	rebolTuple	"\(\d\+\.\)\{2,}"
+
+" Characters
+syn match       rebolSpecialCharacter contained "\^[^[:space:][]"
+syn match       rebolSpecialCharacter contained "%\d\+"
+
+
+" Operators
+" Math operators
+syn match       rebolMathOperator  "\(\*\{1,2}\|+\|-\|/\{1,2}\)"
+syn keyword     rebolMathFunction  abs absolute add arccosine arcsine arctangent cosine
+syn keyword     rebolMathFunction  divide exp log-10 log-2 log-e max maximum min
+syn keyword     rebolMathFunction  minimum multiply negate power random remainder sine
+syn keyword     rebolMathFunction  square-root subtract tangent
+" Binary operators
+syn keyword     rebolBinaryOperator complement and or xor ~
+" Logic operators
+syn match       rebolLogicOperator "[<>=]=\="
+syn match       rebolLogicOperator "<>"
+syn keyword     rebolLogicOperator not
+syn keyword     rebolLogicFunction all any
+syn keyword     rebolLogicFunction head? tail?
+syn keyword     rebolLogicFunction negative? positive? zero? even? odd?
+syn keyword     rebolLogicFunction binary? block? char? date? decimal? email? empty?
+syn keyword     rebolLogicFunction file? found? function? integer? issue? logic? money?
+syn keyword     rebolLogicFunction native? none? object? paren? path? port? series?
+syn keyword     rebolLogicFunction string? time? tuple? url? word?
+syn keyword     rebolLogicFunction exists? input? same? value?
+
+" Datatypes
+syn keyword     rebolType       binary! block! char! date! decimal! email! file!
+syn keyword     rebolType       function! integer! issue! logic! money! native!
+syn keyword     rebolType       none! object! paren! path! port! string! time!
+syn keyword     rebolType       tuple! url! word!
+syn keyword     rebolTypeFunction type?
+
+" Control statements
+syn keyword     rebolStatement  break catch exit halt reduce return shield
+syn keyword     rebolConditional if else
+syn keyword     rebolRepeat     for forall foreach forskip loop repeat while until do
+
+" Series statements
+syn keyword     rebolStatement  change clear copy fifth find first format fourth free
+syn keyword     rebolStatement  func function head insert last match next parse past
+syn keyword     rebolStatement  pick remove second select skip sort tail third trim length?
+
+" Context
+syn keyword     rebolStatement  alias bind use
+
+" Object
+syn keyword     rebolStatement  import make make-object rebol info?
+
+" I/O statements
+syn keyword     rebolStatement  delete echo form format import input load mold prin
+syn keyword     rebolStatement  print probe read save secure send write
+syn keyword     rebolOperator   size? modified?
+
+" Debug statement
+syn keyword     rebolStatement  help probe trace
+
+" Misc statements
+syn keyword     rebolStatement  func function free
+
+" Constants
+syn keyword     rebolConstant   none
+
+
+" Define the default highlighting.
+" For version 5.7 and earlier: only when not done already
+" For version 5.8 and later: only when an item doesn't have highlighting yet
+if version >= 508 || !exists("did_rebol_syntax_inits")
+  if version < 508
+    let did_rebol_syntax_inits = 1
+    command -nargs=+ HiLink hi link <args>
+  else
+    command -nargs=+ HiLink hi def link <args>
+  endif
+
+  HiLink rebolTodo     Todo
+
+  HiLink rebolStatement Statement
+  HiLink rebolLabel	Label
+  HiLink rebolConditional Conditional
+  HiLink rebolRepeat	Repeat
+
+  HiLink rebolOperator	Operator
+  HiLink rebolLogicOperator rebolOperator
+  HiLink rebolLogicFunction rebolLogicOperator
+  HiLink rebolMathOperator rebolOperator
+  HiLink rebolMathFunction rebolMathOperator
+  HiLink rebolBinaryOperator rebolOperator
+  HiLink rebolBinaryFunction rebolBinaryOperator
+
+  HiLink rebolType     Type
+  HiLink rebolTypeFunction rebolOperator
+
+  HiLink rebolWord     Identifier
+  HiLink rebolWordPath rebolWord
+  HiLink rebolFunction	Function
+
+  HiLink rebolCharacter Character
+  HiLink rebolSpecialCharacter SpecialChar
+  HiLink rebolString	String
+
+  HiLink rebolNumber   Number
+  HiLink rebolInteger  rebolNumber
+  HiLink rebolDecimal  rebolNumber
+  HiLink rebolTime     rebolNumber
+  HiLink rebolDate     rebolNumber
+  HiLink rebolMoney    rebolNumber
+  HiLink rebolBinary   rebolNumber
+  HiLink rebolEmail    rebolString
+  HiLink rebolFile     rebolString
+  HiLink rebolURL      rebolString
+  HiLink rebolIssue    rebolNumber
+  HiLink rebolTuple    rebolNumber
+  HiLink rebolFloat    Float
+  HiLink rebolBoolean  Boolean
+
+  HiLink rebolConstant Constant
+
+  HiLink rebolComment	Comment
+
+  HiLink rebolError	Error
+
+  delcommand HiLink
+endif
+
+if exists("my_rebol_file")
+  if file_readable(expand(my_rebol_file))
+    execute "source " . my_rebol_file
+  endif
+endif
+
+let b:current_syntax = "rebol"
+
+" vim: ts=8
--- /dev/null
+++ b/lib/vimfiles/syntax/registry.vim
@@ -1,0 +1,114 @@
+" Vim syntax file
+" Language:	Windows Registry export with regedit (*.reg)
+" Maintainer:	Dominique St�phan (dominique@mggen.com)
+" URL: http://www.mggen.com/vim/syntax/registry.zip
+" Last change:	2004 Apr 23
+
+" clear any unwanted syntax defs
+" For version 5.x: Clear all syntax items
+" For version 6.x: Quit when a syntax file was already loaded
+if version < 600
+  syntax clear
+elseif exists("b:current_syntax")
+  finish
+endif
+
+" shut case off
+syn case ignore
+
+" Head of regedit .reg files, it's REGEDIT4 on Win9#/NT
+syn match registryHead		"^REGEDIT[0-9]*$"
+
+" Comment
+syn match  registryComment	"^;.*$"
+
+" Registry Key constant
+syn keyword registryHKEY	HKEY_LOCAL_MACHINE HKEY_CLASSES_ROOT HKEY_CURRENT_USER
+syn keyword registryHKEY	HKEY_USERS HKEY_CURRENT_CONFIG HKEY_DYN_DATA
+" Registry Key shortcuts
+syn keyword registryHKEY	HKLM HKCR HKCU HKU HKCC HKDD
+
+" Some values often found in the registry
+" GUID (Global Unique IDentifier)
+syn match   registryGUID	"{[0-9A-Fa-f]\{8}\-[0-9A-Fa-f]\{4}\-[0-9A-Fa-f]\{4}\-[0-9A-Fa-f]\{4}\-[0-9A-Fa-f]\{12}}" contains=registrySpecial
+
+" Disk
+" syn match   registryDisk	"[a-zA-Z]:\\\\"
+
+" Special and Separator characters
+syn match   registrySpecial	"\\"
+syn match   registrySpecial	"\\\\"
+syn match   registrySpecial	"\\\""
+syn match   registrySpecial	"\."
+syn match   registrySpecial	","
+syn match   registrySpecial	"\/"
+syn match   registrySpecial	":"
+syn match   registrySpecial	"-"
+
+" String
+syn match   registryString	"\".*\"" contains=registryGUID,registrySpecial
+
+" Path
+syn region  registryPath		start="\[" end="\]" contains=registryHKEY,registryGUID,registrySpecial
+
+" Path to remove
+" like preceding path but with a "-" at begin
+syn region registryRemove	start="\[\-" end="\]" contains=registryHKEY,registryGUID,registrySpecial
+
+" Subkey
+syn match  registrySubKey		"^\".*\"="
+" Default value
+syn match  registrySubKey		"^\@="
+
+" Numbers
+
+" Hex or Binary
+" The format can be precised between () :
+" 0    REG_NONE
+" 1    REG_SZ
+" 2    REG_EXPAND_SZ
+" 3    REG_BINARY
+" 4    REG_DWORD, REG_DWORD_LITTLE_ENDIAN
+" 5    REG_DWORD_BIG_ENDIAN
+" 6    REG_LINK
+" 7    REG_MULTI_SZ
+" 8    REG_RESOURCE_LIST
+" 9    REG_FULL_RESOURCE_DESCRIPTOR
+" 10   REG_RESOURCE_REQUIREMENTS_LIST
+" The value can take several lines, if \ ends the line
+" The limit to 999 matches is arbitrary, it avoids Vim crashing on a very long
+" line of hex values that ends in a comma.
+"syn match registryHex		"hex\(([0-9]\{0,2})\)\=:\([0-9a-fA-F]\{2},\)\{0,999}\([0-9a-fA-F]\{2}\|\\\)$" contains=registrySpecial
+syn match registryHex		"hex\(([0-9]\{0,2})\)\=:\([0-9a-fA-F]\{2},\)*\([0-9a-fA-F]\{2}\|\\\)$" contains=registrySpecial
+syn match registryHex		"^\s*\([0-9a-fA-F]\{2},\)\{0,999}\([0-9a-fA-F]\{2}\|\\\)$" contains=registrySpecial
+" Dword (32 bits)
+syn match registryDword		"dword:[0-9a-fA-F]\{8}$" contains=registrySpecial
+
+if version >= 508 || !exists("did_registry_syntax_inits")
+  if version < 508
+    let did_registry_syntax_inits = 1
+    command -nargs=+ HiLink hi link <args>
+  else
+    command -nargs=+ HiLink hi def link <args>
+  endif
+
+" The default methods for highlighting.  Can be overridden later
+   HiLink registryComment	Comment
+   HiLink registryHead		Constant
+   HiLink registryHKEY		Constant
+   HiLink registryPath		Special
+   HiLink registryRemove	PreProc
+   HiLink registryGUID		Identifier
+   HiLink registrySpecial	Special
+   HiLink registrySubKey	Type
+   HiLink registryString	String
+   HiLink registryHex		Number
+   HiLink registryDword		Number
+
+   delcommand HiLink
+endif
+
+
+let b:current_syntax = "registry"
+
+" vim:ts=8
--- /dev/null
+++ b/lib/vimfiles/syntax/remind.vim
@@ -1,0 +1,69 @@
+" Vim syntax file
+" Language:	Remind
+" Maintainer:	Davide Alberani <alberanid@libero.it>
+" Last Change:	10 May 2006
+" Version:	0.3
+" URL:		http://erlug.linux.it/~da/vim/syntax/remind.vim
+"
+" remind is a sophisticated reminder service; you can download remind from:
+" http://www.roaringpenguin.com/penguin/open_source_remind.php
+
+if version < 600
+  syntax clear
+elseif exists("b:current_syntax")
+  finish
+endif
+
+" shut case off
+syn case ignore
+
+syn keyword remindCommands	REM OMIT SET FSET UNSET
+syn keyword remindExpiry	UNTIL SCANFROM SCAN WARN SCHED
+syn keyword remindTag		PRIORITY TAG
+syn keyword remindTimed		AT DURATION
+syn keyword remindMove		ONCE SKIP BEFORE AFTER
+syn keyword remindSpecial	INCLUDE INC BANNER PUSH-OMIT-CONTEXT PUSH CLEAR-OMIT-CONTEXT CLEAR POP-OMIT-CONTEXT POP
+syn keyword remindRun		MSG MSF RUN CAL SATISFY SPECIAL PS PSFILE SHADE MOON
+syn keyword remindConditional	IF ELSE ENDIF IFTRIG
+syn match remindComment		"#.*$"
+syn region remindString		start=+'+ end=+'+ skip=+\\\\\|\\'+ oneline
+syn region remindString		start=+"+ end=+"+ skip=+\\\\\|\\"+ oneline
+syn keyword remindDebug		DEBUG DUMPVARS DUMP ERRMSG FLUSH PRESERVE
+syn match remindVar		"\$[_a-zA-Z][_a-zA-Z0-9]*"
+syn match remindSubst		"%[^ ]"
+syn match remindAdvanceNumber	"\(\*\|+\|-\|++\|--\)[0-9]\+"
+" This will match trailing whitespaces that seem to break rem2ps.
+" Courtesy of Michael Dunn.
+syn match remindWarning		display excludenl "\S\s\+$"ms=s+1
+
+
+if version >= 508 || !exists("did_remind_syn_inits")
+  if version < 508
+    let did_remind_syn_inits = 1
+    command -nargs=+ HiLink hi link <args>
+  else
+    command -nargs=+ HiLink hi def link <args>
+  endif
+
+  HiLink remindCommands		Function
+  HiLink remindExpiry		Repeat
+  HiLink remindTag		Label
+  HiLink remindTimed		Statement
+  HiLink remindMove		Statement
+  HiLink remindSpecial		Include
+  HiLink remindRun		Function
+  HiLink remindConditional	Conditional
+  HiLink remindComment		Comment
+  HiLink remindString		String
+  HiLink remindDebug		Debug
+  HiLink remindVar		Identifier
+  HiLink remindSubst		Constant
+  HiLink remindAdvanceNumber	Number
+  HiLink remindWarning		Error
+
+  delcommand HiLink
+endif
+
+let b:current_syntax = "remind"
+
+" vim: ts=8 sw=2
--- /dev/null
+++ b/lib/vimfiles/syntax/resolv.vim
@@ -1,0 +1,88 @@
+" Vim syntax file
+" Language: resolver configuration file
+" Maintainer: David Ne\v{c}as (Yeti) <yeti@physics.muni.cz>
+" Original Maintaner: Radu Dineiu <littledragon@altern.org>
+" License: This file can be redistribued and/or modified under the same terms
+"   as Vim itself.
+" URL: http://trific.ath.cx/Ftp/vim/syntax/resolv.vim
+" Last Change: 2006-04-16
+
+if version < 600
+	syntax clear
+elseif exists("b:current_syntax")
+	finish
+endif
+
+" Errors, comments and operators
+syn match resolvError /./
+syn match resolvComment /\s*[#;].*$/
+syn match resolvOperator /[\/:]/ contained
+
+" IP
+syn cluster resolvIPCluster contains=resolvIPError,resolvIPSpecial
+syn match resolvIPError /\%(\d\{4,}\|25[6-9]\|2[6-9]\d\|[3-9]\d\{2}\)[\.0-9]*/ contained
+syn match resolvIPSpecial /\%(127\.\d\{1,3}\.\d\{1,3}\.\d\{1,3}\)/ contained
+
+" General
+syn match resolvIP contained /\%(\d\{1,4}\.\)\{3}\d\{1,4}/ contains=@resolvIPCluster
+syn match resolvIPNetmask contained /\%(\d\{1,4}\.\)\{3}\d\{1,4}\%(\/\%(\%(\d\{1,4}\.\)\{,3}\d\{1,4}\)\)\?/ contains=resolvOperator,@resolvIPCluster
+syn match resolvHostname contained /\w\{-}\.[-0-9A-Za-z_\.]*/
+
+" Particular
+syn match resolvIPNameserver contained /\%(\%(\d\{1,4}\.\)\{3}\d\{1,4}\%(\s\|$\)\)\+/ contains=@resolvIPCluster
+syn match resolvHostnameSearch contained /\%(\%([-0-9A-Za-z_]\+\.\)*[-0-9A-Za-z_]\+\.\?\%(\s\|$\)\)\+/
+syn match resolvIPNetmaskSortList contained /\%(\%(\d\{1,4}\.\)\{3}\d\{1,4}\%(\/\%(\%(\d\{1,4}\.\)\{,3}\d\{1,4}\)\)\?\%(\s\|$\)\)\+/ contains=resolvOperator,@resolvIPCluster
+
+" Identifiers
+syn match resolvNameserver /^\s*nameserver\>/ nextgroup=resolvIPNameserver skipwhite
+syn match resolvLwserver /^\s*lwserver\>/ nextgroup=resolvIPNameserver skipwhite
+syn match resolvDomain /^\s*domain\>/ nextgroup=resolvHostname skipwhite
+syn match resolvSearch /^\s*search\>/ nextgroup=resolvHostnameSearch skipwhite
+syn match resolvSortList /^\s*sortlist\>/ nextgroup=resolvIPNetmaskSortList skipwhite
+syn match resolvOptions /^\s*options\>/ nextgroup=resolvOption skipwhite
+
+" Options
+" FIXME: The manual page and the source code do not exactly agree on the set
+" of allowed options
+syn match resolvOption /\<\%(debug\|no_tld_query\|rotate\|no-check-names\|inet6\)\>/ contained nextgroup=resolvOption skipwhite
+syn match resolvOption /\<\%(ndots\|timeout\|attempts\):\d\+\>/ contained contains=resolvOperator nextgroup=resolvOption skipwhite
+
+" Additional errors
+syn match resolvError /^search .\{257,}/
+
+if version >= 508 || !exists("did_config_syntax_inits")
+	if version < 508
+		let did_config_syntax_inits = 1
+		command! -nargs=+ HiLink hi link <args>
+	else
+		command! -nargs=+ HiLink hi def link <args>
+	endif
+
+	HiLink resolvIP Number
+	HiLink resolvIPNetmask Number
+	HiLink resolvHostname String
+	HiLink resolvOption String
+
+	HiLink resolvIPNameserver Number
+	HiLink resolvHostnameSearch String
+	HiLink resolvIPNetmaskSortList Number
+
+	HiLink resolvNameServer Identifier
+	HiLink resolvLwserver Identifier
+	HiLink resolvDomain Identifier
+	HiLink resolvSearch Identifier
+	HiLink resolvSortList Identifier
+	HiLink resolvOptions Identifier
+
+	HiLink resolvComment Comment
+	HiLink resolvOperator Operator
+	HiLink resolvError Error
+	HiLink resolvIPError Error
+	HiLink resolvIPSpecial Special
+
+	delcommand HiLink
+endif
+
+let b:current_syntax = "resolv"
+
+" vim: ts=8 ft=vim
--- /dev/null
+++ b/lib/vimfiles/syntax/rexx.vim
@@ -1,0 +1,206 @@
+" Vim syntax file
+" Language:	Rexx
+" Maintainer:	Thomas Geulig <geulig@nentec.de>
+" Last Change:  2005 Dez  9, added some <http://www.ooRexx.org>-coloring,
+"                            line comments, do *over*, messages, directives,
+"                            highlighting classes, methods, routines and requires
+"               Rony G. Flatscher <rony.flatscher@wu-wien.ac.at>
+"
+" URL:		http://www.geulig.de/vim/rexx.vim
+"
+" Special Thanks to Dan Sharp <dwsharp@hotmail.com> and Rony G. Flatscher
+" <Rony.Flatscher@wu-wien.ac.at> for comments and additions
+
+" For version 5.x: Clear all syntax items
+" For version 6.x: Quit when a syntax file was already loaded
+if version < 600
+  syntax clear
+elseif exists("b:current_syntax")
+  finish
+endif
+
+syn case ignore
+
+" add to valid identifier chars
+setlocal iskeyword+=.
+setlocal iskeyword+=!
+setlocal iskeyword+=?
+
+" ---rgf, position important: must be before comments etc. !
+syn match rexxOperator "[-=|\/\\\+\*\[\],;<>&\~]"
+
+syn match rexxIdentifier        "\<[a-zA-Z\!\?_]\([a-zA-Z0-9._?!]\)*\>"
+syn match rexxEnvironmentSymbol "\<\.\+\([a-zA-Z0-9._?!]\)*\>"
+
+
+" A Keyword is the first symbol in a clause.  A clause begins at the start
+" of a line or after a semicolon.  THEN, ELSE, OTHERWISE, and colons are always
+" followed by an implied semicolon.
+syn match rexxClause "\(^\|;\|:\|then \|else \|otherwise \)\s*\w\+" contains=ALLBUT,rexxParse2,rexxRaise2
+
+
+" Considered keywords when used together in a phrase and begin a clause
+syn match rexxParse "\<parse\s*\(\(upper\|lower\|caseless\)\s*\)\=\(arg\|linein\|pull\|source\|var\|\<value\>\|version\)\>"
+syn match rexxParse2 "\<with\>" contained containedin=rexxParse
+
+
+syn match rexxKeyword contained "\<numeric \(digits\|form \(scientific\|engineering\|value\)\|fuzz\)\>"
+syn match rexxKeyword contained "\<\(address\|trace\)\( value\)\=\>"
+syn match rexxKeyword contained "\<procedure\(\s*expose\)\=\>"
+syn match rexxKeyword contained "\<do\>\(\s*forever\)\=\>"
+syn match rexxKeyword contained "\<use\>\s*\<arg\>"
+
+" Another keyword phrase, separated to aid highlighting in rexxFunction
+syn match rexxKeyword contained "\<signal\(\s*\(on\|off\)\s*\(any\|error\|failure\|halt\|lostdigits\|nomethod\|nostring\|notready\|novalue\|syntax\|user\s*\k*\)\(\s\+name\)\=\)\=\>"
+syn match rexxKeyword2 contained "\<call\(\s*\(on\|off\)\s*\(any\|error\|failure\|halt\|notready\|user\s*\k*\)\(\s\+name\)\=\)\=\>"
+
+
+" Considered keywords when they begin a clause
+syn match rexxKeyword contained "\<\(arg\|do\|drop\|end\|exit\|expose\|forward\|if\|interpret\|iterate\|leave\|nop\)\>"
+syn match rexxKeyword contained "\<\(options\|pull\|push\|queue\|raise\|reply\|return\|say\|select\|trace\)\>"
+
+" Conditional phrases
+syn match rexxConditional  "\(^\s*\| \)\(to\|by\|for\|until\|while\|then\|when\|otherwise\|else\|over\)\( \|\s*$\)"
+syn match rexxConditional contained "\<\(to\|by\|for\|until\|while\|then\|when\|otherwise\|else\|over\)\>"
+
+" must be after Conditional phrases!
+syn match rexxKeyword ".*\<\(then\|else\)\s*\<do\>"
+
+" Raise statement
+syn match rexxRaise "\(^\|;\|:\)\s\+\<raise\>\s*\<\(propagate\|error\|failure\|syntax\|user\)\>\="
+syn match rexxRaise2 "\<\(additional\|array\|description\|exit\|return\)\>" contained containedin=rexxRaise
+
+" Forward statement keywords
+syn match rexxForward  "\(^\|;\|:\)\<forward\>\s*"
+syn match rexxForward2 "\<\(arguments\|array\|continue\|message\|class\|to\)\>" contained containedin=rexxForward
+
+" Functions/Procedures
+syn match rexxFunction	"\<\w*\(/\*\s*\*/\)*("me=e-1 contains=rexxComment,rexxConditional,rexxKeyword,rexxIdentifier
+syn match rexxFunction 	"\<\<[a-zA-Z\!\?_]\([a-zA-Z0-9._?!]\)*\>("me=e-1
+syn match rexxFunction	"\<call\s\+\k\+\>"  contains=rexxKeyword2
+syn match rexxFunction "[()]"
+
+" String constants
+syn region rexxString	  start=+"+ skip=+""+ end=+"\(x\|b\)\=+ oneline
+syn region rexxString	  start=+'+ skip=+''+ end=+'\(x\|b\)\=+ oneline
+
+" Catch errors caused by wrong parenthesis
+syn region rexxParen transparent start='(' end=')' contains=ALLBUT,rexxParenError,rexxTodo,rexxLabel,rexxKeyword
+syn match rexxParenError	 ")"
+syn match rexxInParen		"[\\[\\]{}]"
+
+" Comments
+syn region rexxComment		start="/\*" end="\*/" contains=rexxTodo,rexxComment
+syn match  rexxCommentError	"\*/"
+syn match  rexxLineComment       /--.*/
+
+syn keyword rexxTodo contained	TODO FIXME XXX
+
+
+" ooRexx messages
+syn region rexxMessageOperator start="\(\~\|\~\~\)" end="\(\S\|\s\)"me=e-1
+syn match rexxMessage "\(\~\|\~\~\)\s*\<\.*[a-zA-Z]\([a-zA-Z0-9._?!]\)*\>" contains=rexxMessageOperator
+
+" Highlight User Labels
+syn match rexxLabel		 "^\s*\k*\s*:"me=e-1
+
+syn match rexxLineContinue ",\ze\s*\(--.*\|\/\*.*\)*$"
+" the following is necessary, otherwise three consecutive dashes will cause it to highlight the first one
+syn match rexxLineContinue "-\ze\(\s+--.*\|\s*\/\*.*\)*$"
+
+" Special Variables
+syn keyword rexxSpecialVariable  sigl rc result self super
+
+" Constants
+syn keyword rexxConst .true .false .nil
+
+" ooRexx builtin classes, first define dot to be o.k. in keywords
+syn keyword rexxBuiltinClass .object .class .method .message
+syn keyword rexxBuiltinClass .monitor .alarm
+syn keyword rexxBuiltinClass .stem .stream .string
+syn keyword rexxBuiltinClass .mutablebuffer
+syn keyword rexxBuiltinClass .array .list .queue .directory .table .set
+syn keyword rexxBuiltinClass .relation .bag .supplier .regularExpressions
+
+" Windows-only classes
+syn keyword rexxBuiltinClass .OLEObject .MenuObject .WindowsClipboard .WindowsEventLog
+syn keyword rexxBuiltinClass .WindowsManager .WindowObject .WindowsProgramManager
+
+
+" ooRexx directives, ---rgf location important, otherwise directives in top of
+" file not matched!
+syn region rexxClass    start="::\s*class\s*"ms=e+1    end="\ze\(\s\|;\|$\)"
+syn region rexxMethod   start="::\s*method\s*"ms=e+1   end="\ze\(\s\|;\|$\)"
+syn region rexxRequires start="::\s*requires\s*"ms=e+1 end="\ze\(\s\|;\|$\)"
+syn region rexxRoutine  start="::\s*routine\s*"ms=e+1  end="\ze\(\s\|;\|$\)"
+
+syn region rexxDirective start="\(^\|;\)\s*::\s*\w\+"  end="\($\|;\)" contains=rexxString,rexxComment,rexxLineComment,rexxClass,rexxMethod,rexxRoutine,rexxRequires keepend
+
+
+
+if !exists("rexx_minlines")
+"  let rexx_minlines = 10
+  let rexx_minlines = 500
+endif
+exec "syn sync ccomment rexxComment minlines=" . rexx_minlines
+
+" Define the default highlighting.
+" For version 5.7 and earlier: only when not done already
+" For version 5.8 and later: only when an item doesn't have highlighting yet
+if version >= 508 || !exists("did_rexx_syn_inits")
+  if version < 508
+    let did_rexx_syn_inits = 1
+    command -nargs=+ HiLink hi link <args>
+  else
+    command -nargs=+ HiLink hi def link <args>
+  endif
+
+  HiLink rexxLabel		Function
+  HiLink rexxCharacter		Character
+  HiLink rexxParenError		rexxError
+  HiLink rexxInParen		rexxError
+  HiLink rexxCommentError	rexxError
+  HiLink rexxError		Error
+  HiLink rexxKeyword		Statement
+  HiLink rexxKeyword2		rexxKeyword
+  HiLink rexxFunction		Function
+  HiLink rexxString		String
+  HiLink rexxComment		Comment
+  HiLink rexxTodo		Todo
+  HiLink rexxSpecialVariable	Special
+  HiLink rexxConditional	rexxKeyword
+
+  HiLink rexxOperator		Operator
+  HiLink rexxMessageOperator	rexxOperator
+  HiLink rexxLineComment	RexxComment
+
+  HiLink rexxLineContinue	WildMenu
+
+  HiLink rexxDirective		rexxKeyword
+  HiLink rexxClass              Type
+  HiLink rexxMethod             rexxFunction
+  HiLink rexxRequires           Include
+  HiLink rexxRoutine            rexxFunction
+
+  HiLink rexxConst		Constant
+  HiLink rexxTypeSpecifier	Type
+  HiLink rexxBuiltinClass	rexxTypeSpecifier
+
+  HiLink rexxEnvironmentSymbol  rexxConst
+  HiLink rexxMessage		rexxFunction
+
+  HiLink rexxParse              rexxKeyword
+  HiLink rexxParse2             rexxParse
+
+  HiLink rexxRaise              rexxKeyword
+  HiLink rexxRaise2             rexxRaise
+
+  HiLink rexxForward            rexxKeyword
+  HiLink rexxForward2           rexxForward
+
+  delcommand HiLink
+endif
+
+let b:current_syntax = "rexx"
+
+"vim: ts=8
--- /dev/null
+++ b/lib/vimfiles/syntax/rhelp.vim
@@ -1,0 +1,155 @@
+" Vim syntax file
+" Language:    R Help File
+" Maintainer:  Johannes Ranke <jranke@uni-bremen.de>
+" Last Change: 2006 Apr 24
+" Version:     0.7
+" SVN:		   $Id: rhelp.vim,v 1.4 2006/04/24 19:33:52 vimboss Exp $
+" Remarks:     - Now includes R syntax highlighting in the appropriate
+"                sections if an r.vim file is in the same directory or in the
+"                default debian location.
+"              - There is no Latex markup in equations
+
+" Version Clears: {{{1
+" For version 5.x: Clear all syntax items
+" For version 6.x and 7.x: Quit when a syntax file was already loaded
+if version < 600 
+  syntax clear
+elseif exists("b:current_syntax")
+  finish
+endif 
+
+syn case match
+
+" R help identifiers {{{
+syn region rhelpIdentifier matchgroup=rhelpSection	start="\\name{" end="}" 
+syn region rhelpIdentifier matchgroup=rhelpSection	start="\\alias{" end="}" 
+syn region rhelpIdentifier matchgroup=rhelpSection	start="\\pkg{" end="}" 
+syn region rhelpIdentifier matchgroup=rhelpSection	start="\\item{" end="}" contained contains=rhelpDots
+syn region rhelpIdentifier matchgroup=rhelpSection start="\\method{" end=/}/ contained
+
+" Highlighting of R code using an existing r.vim syntax file if available {{{1
+syn include @R syntax/r.vim
+syn match rhelpDots		"\\dots" containedin=@R
+syn region rhelpRcode matchgroup=Delimiter start="\\examples{" matchgroup=Delimiter transparent end=/}/ contains=@R,rhelpSection
+syn region rhelpRcode matchgroup=Delimiter start="\\usage{" matchgroup=Delimiter transparent end=/}/ contains=@R,rhelpIdentifier,rhelpS4method
+syn region rhelpRcode matchgroup=Delimiter start="\\synopsis{" matchgroup=Delimiter transparent end=/}/ contains=@R
+syn region rhelpRcode matchgroup=Delimiter start="\\special{" matchgroup=Delimiter transparent end=/}/ contains=@R contained
+syn region rhelpRcode matchgroup=Delimiter start="\\code{" matchgroup=Delimiter transparent end=/}/ contains=@R,rhelpLink contained
+syn region rhelpS4method matchgroup=Delimiter start="\\S4method{.*}(" matchgroup=Delimiter transparent end=/)/ contains=@R,rhelpDots contained
+
+" Strings {{{1
+syn region rhelpString start=/"/ end=/"/ 
+
+" Special characters  ( \$ \& \% \# \{ \} \_) {{{1
+syn match rhelpSpecialChar        "\\[$&%#{}_]"
+
+" Special Delimiters {{{1
+syn match rhelpDelimiter		"\\cr"
+syn match rhelpDelimiter		"\\tab "
+
+" Keywords {{{1
+syn match rhelpKeyword	"\\R"
+syn match rhelpKeyword	"\\ldots"
+syn match rhelpKeyword  "--"
+syn match rhelpKeyword  "---"
+syn match rhelpKeyword  "<"
+syn match rhelpKeyword  ">"
+
+" Links {{{1
+syn region rhelpLink matchgroup=rhelpSection start="\\link{" end="}" contained keepend
+syn region rhelpLink matchgroup=rhelpSection start="\\link\[.*\]{" end="}" contained keepend
+syn region rhelpLink matchgroup=rhelpSection start="\\linkS4class{" end="}" contained keepend
+
+" Type Styles {{{1
+syn match rhelpType		"\\emph\>"
+syn match rhelpType		"\\strong\>"
+syn match rhelpType		"\\bold\>"
+syn match rhelpType		"\\sQuote\>"
+syn match rhelpType		"\\dQuote\>"
+syn match rhelpType		"\\preformatted\>"
+syn match rhelpType		"\\kbd\>"
+syn match rhelpType		"\\samp\>"
+syn match rhelpType		"\\eqn\>"
+syn match rhelpType		"\\deqn\>"
+syn match rhelpType		"\\file\>"
+syn match rhelpType		"\\email\>"
+syn match rhelpType		"\\url\>"
+syn match rhelpType		"\\var\>"
+syn match rhelpType		"\\env\>"
+syn match rhelpType		"\\option\>"
+syn match rhelpType		"\\command\>"
+syn match rhelpType		"\\dfn\>"
+syn match rhelpType		"\\cite\>"
+syn match rhelpType		"\\acronym\>"
+
+" rhelp sections {{{1
+syn match rhelpSection		"\\encoding\>"
+syn match rhelpSection		"\\title\>"
+syn match rhelpSection		"\\description\>"
+syn match rhelpSection		"\\concept\>"
+syn match rhelpSection		"\\arguments\>"
+syn match rhelpSection		"\\details\>"
+syn match rhelpSection		"\\value\>"
+syn match rhelpSection		"\\references\>"
+syn match rhelpSection		"\\note\>"
+syn match rhelpSection		"\\author\>"
+syn match rhelpSection		"\\seealso\>"
+syn match rhelpSection		"\\keyword\>"
+syn match rhelpSection		"\\docType\>"
+syn match rhelpSection		"\\format\>"
+syn match rhelpSection		"\\source\>"
+syn match rhelpSection     "\\itemize\>"
+syn match rhelpSection     "\\describe\>"
+syn match rhelpSection     "\\enumerate\>"
+syn match rhelpSection     "\\item "
+syn match rhelpSection     "\\item$"
+syn match rhelpSection		"\\tabular{[lcr]*}"
+syn match rhelpSection		"\\dontrun\>"
+syn match rhelpSection		"\\dontshow\>"
+syn match rhelpSection		"\\testonly\>"
+
+" Freely named Sections {{{1
+syn region rhelpFreesec matchgroup=Delimiter start="\\section{" matchgroup=Delimiter transparent end=/}/ 
+
+" R help file comments {{{1
+syn match rhelpComment /%.*$/ contained 
+
+" Error {{{1
+syn region rhelpRegion matchgroup=Delimiter start=/(/ matchgroup=Delimiter end=/)/ transparent contains=ALLBUT,rhelpError,rhelpBraceError,rhelpCurlyError
+syn region rhelpRegion matchgroup=Delimiter start=/{/ matchgroup=Delimiter end=/}/ transparent contains=ALLBUT,rhelpError,rhelpBraceError,rhelpParenError
+syn region rhelpRegion matchgroup=Delimiter start=/\[/ matchgroup=Delimiter end=/]/ transparent contains=ALLBUT,rhelpError,rhelpCurlyError,rhelpParenError
+syn match rhelpError      /[)\]}]/
+syn match rhelpBraceError /[)}]/ contained
+syn match rhelpCurlyError /[)\]]/ contained
+syn match rhelpParenError /[\]}]/ contained
+
+" Define the default highlighting {{{1
+" For version 5.7 and earlier: only when not done already
+" For version 5.8 and later: only when an item doesn't have highlighting yet
+if version >= 508 || !exists("did_rhelp_syntax_inits")
+  if version < 508
+    let did_rhelp_syntax_inits = 1
+    command -nargs=+ HiLink hi link <args>
+  else
+    command -nargs=+ HiLink hi def link <args>
+  endif
+  HiLink rhelpIdentifier  Identifier
+  HiLink rhelpString      String
+  HiLink rhelpKeyword     Keyword
+  HiLink rhelpDots        Keyword
+  HiLink rhelpLink        Underlined
+  HiLink rhelpType	      Type
+  HiLink rhelpSection     PreCondit
+  HiLink rhelpError       Error
+  HiLink rhelpBraceError  Error
+  HiLink rhelpCurlyError  Error
+  HiLink rhelpParenError  Error
+  HiLink rhelpDelimiter   Delimiter
+  HiLink rhelpComment     Comment
+  HiLink rhelpRComment    Comment
+  HiLink rhelpSpecialChar SpecialChar
+  delcommand HiLink
+endif 
+
+let   b:current_syntax = "rhelp"
+" vim: foldmethod=marker:
--- /dev/null
+++ b/lib/vimfiles/syntax/rib.vim
@@ -1,0 +1,73 @@
+" Vim syntax file
+" Language:	Renderman Interface Bytestream
+" Maintainer:	Andrew Bromage <ajb@spamcop.net>
+" Last Change:	2003 May 11
+"
+
+" Remove any old syntax stuff hanging around
+if version < 600
+  syn clear
+elseif exists("b:current_syntax")
+  finish
+endif
+
+syn case match
+
+" Comments
+syn match   ribLineComment      "#.*$"
+syn match   ribStructureComment "##.*$"
+
+syn case ignore
+syn match   ribCommand	       /[A-Z][a-zA-Z]*/
+syn case match
+
+syn region  ribString	       start=/"/ skip=/\\"/ end=/"/
+
+syn match   ribStructure	"[A-Z][a-zA-Z]*Begin\>\|[A-Z][a-zA-Z]*End"
+syn region  ribSectionFold	start="FrameBegin" end="FrameEnd" fold transparent keepend extend
+syn region  ribSectionFold	start="WorldBegin" end="WorldEnd" fold transparent keepend extend
+syn region  ribSectionFold	start="TransformBegin" end="TransformEnd" fold transparent keepend extend
+syn region  ribSectionFold	start="AttributeBegin" end="AttributeEnd" fold transparent keepend extend
+syn region  ribSectionFold	start="MotionBegin" end="MotionEnd" fold transparent keepend extend
+syn region  ribSectionFold	start="SolidBegin" end="SolidEnd" fold transparent keepend extend
+syn region  ribSectionFold	start="ObjectBegin" end="ObjectEnd" fold transparent keepend extend
+
+syn sync    fromstart
+
+"integer number, or floating point number without a dot and with "f".
+syn case ignore
+syn match	ribNumbers	  display transparent "[-]\=\<\d\|\.\d" contains=ribNumber,ribFloat
+syn match	ribNumber	  display contained "[-]\=\d\+\>"
+"floating point number, with dot, optional exponent
+syn match	ribFloat	  display contained "[-]\=\d\+\.\d*\(e[-+]\=\d\+\)\="
+"floating point number, starting with a dot, optional exponent
+syn match	ribFloat	  display contained "[-]\=\.\d\+\(e[-+]\=\d\+\)\=\>"
+"floating point number, without dot, with exponent
+syn match	ribFloat	  display contained "[-]\=\d\+e[-+]\d\+\>"
+syn case match
+
+if version >= 508 || !exists("did_rib_syntax_inits")
+  if version < 508
+    let did_rib_syntax_inits = 1
+    command -nargs=+ HiLink hi link <args>
+  else
+    command -nargs=+ HiLink hi def link <args>
+  endif
+
+  HiLink ribStructure		Structure
+  HiLink ribCommand		Statement
+
+  HiLink ribStructureComment	SpecialComment
+  HiLink ribLineComment		Comment
+
+  HiLink ribString		String
+  HiLink ribNumber		Number
+  HiLink ribFloat		Float
+
+  delcommand HiLink
+end
+
+
+let b:current_syntax = "rib"
+
+" Options for vi: ts=8 sw=2 sts=2 nowrap noexpandtab ft=vim
--- /dev/null
+++ b/lib/vimfiles/syntax/rnc.vim
@@ -1,0 +1,68 @@
+" Vim syntax file
+" Language:         Relax NG compact syntax
+" Maintainer:       Nikolai Weibull <now@bitwi.se>
+" Latest Revision:  2006-04-19
+
+if exists("b:current_syntax")
+  finish
+endif
+
+let s:cpo_save = &cpo
+set cpo&vim
+
+setlocal iskeyword=@,48-57,_,-,.
+
+syn keyword rncTodo         contained TODO FIXME XXX NOTE
+
+syn region  rncComment      display oneline start='^\s*#' end='$'
+                            \ contains=rncTodo,@Spell
+
+syn match   rncOperator     display '[-|,&+?*~]'
+syn match   rncOperator     display '\%(|&\)\=='
+syn match   rncOperator     display '>>'
+
+syn match   rncNamespace    display '\<\k\+:'
+
+syn match   rncQuoted       display '\\\k\+\>'
+
+syn match   rncSpecial      display '\\x{\x\+}'
+
+syn region rncAnnotation    transparent start='\[' end='\]'
+                            \ contains=ALLBUT,rncComment,rncTodo
+
+syn region  rncLiteral      display oneline start=+"+ end=+"+
+                            \ contains=rncSpecial
+syn region  rncLiteral      display oneline start=+'+ end=+'+
+syn region  rncLiteral      display oneline start=+"""+ end=+"""+
+                            \ contains=rncSpecial
+syn region  rncLiteral      display oneline start=+'''+ end=+'''+
+
+syn match   rncDelimiter    display '[{},()]'
+
+syn keyword rncKeyword      datatypes default div empty external grammar
+syn keyword rncKeyword      include inherit list mixed name namespace
+syn keyword rncKeyword      notAllowed parent start string text token
+
+syn match   rncIdentifier   display '\k\+\_s*\%(=\|&=\||=\)\@='
+                            \ nextgroup=rncOperator
+syn keyword rncKeyword      element attribute
+                            \ nextgroup=rncIdName skipwhite skipempty
+syn match   rncIdName       contained '\k\+'
+
+hi def link rncTodo         Todo
+hi def link rncComment      Comment
+hi def link rncOperator     Operator
+hi def link rncNamespace    Identifier
+hi def link rncQuoted       Special
+hi def link rncSpecial      SpecialChar
+hi def link rncAnnotation   Special
+hi def link rncLiteral      String
+hi def link rncDelimiter    Delimiter
+hi def link rncKeyword      Keyword
+hi def link rncIdentifier   Identifier
+hi def link rncIdName       Identifier
+
+let b:current_syntax = "rnc"
+
+let &cpo = s:cpo_save
+unlet s:cpo_save
--- /dev/null
+++ b/lib/vimfiles/syntax/rnoweb.vim
@@ -1,0 +1,56 @@
+" Vim syntax file
+" Language:    R noweb Files
+" Maintainer:  Johannes Ranke <jranke@uni-bremen.de>
+" Last Change: 2007 M�r 30
+" Version:     0.8
+" SVN:	       $Id: rnoweb.vim,v 1.3 2007/05/05 17:55:31 vimboss Exp $
+" Remarks:     - This file is inspired by the proposal of 
+"				 Fernando Henrique Ferraz Pereira da Rosa <feferraz@ime.usp.br>
+"			     http://www.ime.usp.br/~feferraz/en/sweavevim.html
+"
+
+" Version Clears: {{{1
+" For version 5.x: Clear all syntax items
+" For version 6.x and 7.x: Quit when a syntax file was already loaded
+if version < 600 
+  syntax clear
+elseif exists("b:current_syntax")
+  finish
+endif 
+
+syn case match
+
+" Extension of Tex clusters {{{1
+runtime syntax/tex.vim
+unlet b:current_syntax
+
+syn cluster texMatchGroup add=@rnoweb
+syn cluster texEnvGroup add=@rnoweb
+syn cluster texFoldGroup add=@rnoweb
+syn cluster texDocGroup		add=@rnoweb
+syn cluster texPartGroup		add=@rnoweb
+syn cluster texChapterGroup		add=@rnoweb
+syn cluster texSectionGroup		add=@rnoweb
+syn cluster texSubSectionGroup		add=@rnoweb
+syn cluster texSubSubSectionGroup	add=@rnoweb
+syn cluster texParaGroup		add=@rnoweb
+
+" Highlighting of R code using an existing r.vim syntax file if available {{{1
+syn include @rnowebR syntax/r.vim
+syn region rnowebChunk matchgroup=rnowebDelimiter start="^<<.*>>=" matchgroup=rnowebDelimiter end="^@" contains=@rnowebR,rnowebChunkReference,rnowebChunk fold keepend
+syn match rnowebChunkReference "^<<.*>>$" contained
+syn region rnowebSexpr matchgroup=Delimiter start="\\Sexpr{" matchgroup=Delimiter end="}" contains=@rnowebR
+
+" Sweave options command {{{1
+syn region rnowebSweaveopts matchgroup=Delimiter start="\\SweaveOpts{" matchgroup=Delimiter end="}"
+
+" rnoweb Cluster {{{1
+syn cluster rnoweb contains=rnowebChunk,rnowebChunkReference,rnowebDelimiter,rnowebSexpr,rnowebSweaveopts
+
+" Highlighting {{{1
+hi def link rnowebDelimiter	Delimiter
+hi def link rnowebSweaveOpts Statement
+hi def link rnowebChunkReference Delimiter
+
+let   b:current_syntax = "rnoweb"
+" vim: foldmethod=marker:
--- /dev/null
+++ b/lib/vimfiles/syntax/robots.vim
@@ -1,0 +1,69 @@
+" Vim syntax file
+" Language:	"Robots.txt" files
+" Robots.txt files indicate to WWW robots which parts of a web site should not be accessed.
+" Maintainer:	Dominique St�phan (dominique@mggen.com)
+" URL: http://www.mggen.com/vim/syntax/robots.zip
+" Last change:	2001 May 09
+
+" For version 5.x: Clear all syntax items
+" For version 6.x: Quit when a syntax file was already loaded
+if version < 600
+    syntax clear
+elseif exists("b:current_syntax")
+    finish
+endif
+
+
+" shut case off
+syn case ignore
+
+" Comment
+syn match  robotsComment	"#.*$" contains=robotsUrl,robotsMail,robotsString
+
+" Star * (means all spiders)
+syn match  robotsStar		"\*"
+
+" :
+syn match  robotsDelimiter	":"
+
+
+" The keywords
+" User-agent
+syn match  robotsAgent		"^[Uu][Ss][Ee][Rr]\-[Aa][Gg][Ee][Nn][Tt]"
+" Disallow
+syn match  robotsDisallow	"^[Dd][Ii][Ss][Aa][Ll][Ll][Oo][Ww]"
+
+" Disallow: or User-Agent: and the rest of the line before an eventual comment
+synt match robotsLine		"\(^[Uu][Ss][Ee][Rr]\-[Aa][Gg][Ee][Nn][Tt]\|^[Dd][Ii][Ss][Aa][Ll][Ll][Oo][Ww]\):[^#]*"	contains=robotsAgent,robotsDisallow,robotsStar,robotsDelimiter
+
+" Some frequent things in comments
+syn match  robotsUrl		"http[s]\=://\S*"
+syn match  robotsMail		"\S*@\S*"
+syn region robotsString		start=+L\="+ skip=+\\\\\|\\"+ end=+"+
+
+if version >= 508 || !exists("did_robos_syntax_inits")
+  if version < 508
+    let did_robots_syntax_inits = 1
+    command -nargs=+ HiLink hi link <args>
+  else
+    command -nargs=+ HiLink hi def link <args>
+  endif
+
+  HiLink robotsComment		Comment
+  HiLink robotsAgent		Type
+  HiLink robotsDisallow		Statement
+  HiLink robotsLine		Special
+  HiLink robotsStar		Operator
+  HiLink robotsDelimiter	Delimiter
+  HiLink robotsUrl		String
+  HiLink robotsMail		String
+  HiLink robotsString		String
+
+  delcommand HiLink
+endif
+
+
+let b:current_syntax = "robots"
+
+" vim: ts=8 sw=2
+
--- /dev/null
+++ b/lib/vimfiles/syntax/rpcgen.vim
@@ -1,0 +1,63 @@
+" Vim syntax file
+" Language:	rpcgen
+" Maintainer:	Dr. Charles E. Campbell, Jr. <NdrOchipS@PcampbellAfamily.Mbiz>
+" Last Change:	Sep 06, 2005
+" Version:	8
+" URL:	http://mysite.verizon.net/astronaut/vim/index.html#vimlinks_syntax
+
+" For version 5.x: Clear all syntax items
+" For version 6.x: Quit when a syntax file was already loaded
+if version < 600
+  syntax clear
+elseif exists("b:current_syntax")
+  finish
+endif
+
+" Read the C syntax to start with
+if version < 600
+  source <sfile>:p:h/c.vim
+else
+  runtime! syntax/c.vim
+endif
+
+syn keyword rpcProgram	program				skipnl skipwhite nextgroup=rpcProgName
+syn match   rpcProgName	contained	"\<\i\I*\>"	skipnl skipwhite nextgroup=rpcProgZone
+syn region  rpcProgZone	contained	matchgroup=Delimiter start="{" matchgroup=Delimiter end="}\s*=\s*\(\d\+\|0x[23]\x\{7}\)\s*;"me=e-1 contains=rpcVersion,cComment,rpcProgNmbrErr
+syn keyword rpcVersion	contained	version		skipnl skipwhite nextgroup=rpcVersName
+syn match   rpcVersName	contained	"\<\i\I*\>"	skipnl skipwhite nextgroup=rpcVersZone
+syn region  rpcVersZone	contained	matchgroup=Delimiter start="{" matchgroup=Delimiter end="}\s*=\s*\d\+\s*;"me=e-1 contains=cType,cStructure,cStorageClass,rpcDecl,rpcProcNmbr,cComment
+syn keyword rpcDecl	contained	string
+syn match   rpcProcNmbr	contained	"=\s*\d\+;"me=e-1
+syn match   rpcProgNmbrErr contained	"=\s*0x[^23]\x*"ms=s+1
+syn match   rpcPassThru			"^\s*%.*$"
+
+" Define the default highlighting.
+" For version 5.7 and earlier: only when not done already
+" For version 5.8 and later: only when an item doesn't have highlighting yet
+if version >= 508 || !exists("did_rpcgen_syntax_inits")
+  if version < 508
+    let did_rpcgen_syntax_inits = 1
+    command -nargs=+ HiLink hi link <args>
+  else
+    command -nargs=+ HiLink hi def link <args>
+  endif
+
+  HiLink rpcProgName	rpcName
+  HiLink rpcProgram	rpcStatement
+  HiLink rpcVersName	rpcName
+  HiLink rpcVersion	rpcStatement
+
+  HiLink rpcDecl	cType
+  HiLink rpcPassThru	cComment
+
+  HiLink rpcName	Special
+  HiLink rpcProcNmbr	Delimiter
+  HiLink rpcProgNmbrErr	Error
+  HiLink rpcStatement	Statement
+
+  delcommand HiLink
+endif
+
+let b:current_syntax = "rpcgen"
+
+" vim: ts=8
--- /dev/null
+++ b/lib/vimfiles/syntax/rpl.vim
@@ -1,0 +1,491 @@
+" Vim syntax file
+" Language:	RPL/2
+" Version:	0.15.15 against RPL/2 version 4.00pre7i
+" Last Change:	2003 august 24
+" Maintainer:	Jo�l BERTRAND <rpl2@free.fr>
+" URL:		http://www.makalis.fr/~bertrand/rpl2/download/vim/indent/rpl.vim
+" Credits:	Nothing
+
+" For version 5.x: Clear all syntax items
+" For version 6.x: Quit when a syntax file was already loaded
+if version < 600
+  syntax clear
+elseif exists("b:current_syntax")
+  finish
+endif
+
+" Keyword characters (not used)
+" set iskeyword=33-127
+
+" Case sensitive
+syntax case match
+
+" Constants
+syntax match rplConstant	   "\(^\|\s\+\)\(e\|i\)\ze\($\|\s\+\)"
+
+" Any binary number
+syntax match rplBinaryError	   "\(^\|\s\+\)#\s*\S\+b\ze"
+syntax match rplBinary		   "\(^\|\s\+\)#\s*[01]\+b\ze\($\|\s\+\)"
+syntax match rplOctalError	   "\(^\|\s\+\)#\s*\S\+o\ze"
+syntax match rplOctal		   "\(^\|\s\+\)#\s*\o\+o\ze\($\|\s\+\)"
+syntax match rplDecimalError	   "\(^\|\s\+\)#\s*\S\+d\ze"
+syntax match rplDecimal		   "\(^\|\s\+\)#\s*\d\+d\ze\($\|\s\+\)"
+syntax match rplHexadecimalError   "\(^\|\s\+\)#\s*\S\+h\ze"
+syntax match rplHexadecimal	   "\(^\|\s\+\)#\s*\x\+h\ze\($\|\s\+\)"
+
+" Case unsensitive
+syntax case ignore
+
+syntax match rplControl		   "\(^\|\s\+\)abort\ze\($\|\s\+\)"
+syntax match rplControl		   "\(^\|\s\+\)kill\ze\($\|\s\+\)"
+syntax match rplControl		   "\(^\|\s\+\)cont\ze\($\|\s\+\)"
+syntax match rplControl		   "\(^\|\s\+\)halt\ze\($\|\s\+\)"
+syntax match rplControl		   "\(^\|\s\+\)cmlf\ze\($\|\s\+\)"
+syntax match rplControl		   "\(^\|\s\+\)sst\ze\($\|\s\+\)"
+
+syntax match rplConstant	   "\(^\|\s\+\)pi\ze\($\|\s\+\)"
+
+syntax match rplStatement	   "\(^\|\s\+\)return\ze\($\|\s\+\)"
+syntax match rplStatement	   "\(^\|\s\+\)last\ze\($\|\s\+\)"
+syntax match rplStatement	   "\(^\|\s\+\)syzeval\ze\($\|\s\+\)"
+syntax match rplStatement	   "\(^\|\s\+\)wait\ze\($\|\s\+\)"
+syntax match rplStatement	   "\(^\|\s\+\)type\ze\($\|\s\+\)"
+syntax match rplStatement	   "\(^\|\s\+\)kind\ze\($\|\s\+\)"
+syntax match rplStatement	   "\(^\|\s\+\)eval\ze\($\|\s\+\)"
+syntax match rplStatement	   "\(^\|\s\+\)use\ze\($\|\s\+\)"
+syntax match rplStatement	   "\(^\|\s\+\)remove\ze\($\|\s\+\)"
+syntax match rplStatement	   "\(^\|\s\+\)external\ze\($\|\s\+\)"
+syntax match rplStatement	   "\(^\|\s\+\)dup\([2n]\|\)\ze\($\|\s\+\)"
+syntax match rplStatement	   "\(^\|\s\+\)drop\([2n]\|\)\ze\($\|\s\+\)"
+syntax match rplStatement	   "\(^\|\s\+\)depth\ze\($\|\s\+\)"
+syntax match rplStatement	   "\(^\|\s\+\)roll\(d\|\)\ze\($\|\s\+\)"
+syntax match rplStatement	   "\(^\|\s\+\)pick\ze\($\|\s\+\)"
+syntax match rplStatement	   "\(^\|\s\+\)rot\ze\($\|\s\+\)"
+syntax match rplStatement	   "\(^\|\s\+\)swap\ze\($\|\s\+\)"
+syntax match rplStatement	   "\(^\|\s\+\)over\ze\($\|\s\+\)"
+syntax match rplStatement	   "\(^\|\s\+\)clear\ze\($\|\s\+\)"
+syntax match rplStatement	   "\(^\|\s\+\)warranty\ze\($\|\s\+\)"
+syntax match rplStatement	   "\(^\|\s\+\)copyright\ze\($\|\s\+\)"
+syntax match rplStatement	   "\(^\|\s\+\)convert\ze\($\|\s\+\)"
+syntax match rplStatement	   "\(^\|\s\+\)date\ze\($\|\s\+\)"
+syntax match rplStatement	   "\(^\|\s\+\)time\ze\($\|\s\+\)"
+syntax match rplStatement	   "\(^\|\s\+\)mem\ze\($\|\s\+\)"
+syntax match rplStatement	   "\(^\|\s\+\)clmf\ze\($\|\s\+\)"
+syntax match rplStatement	   "\(^\|\s\+\)->num\ze\($\|\s\+\)"
+syntax match rplStatement	   "\(^\|\s\+\)help\ze\($\|\s\+\)"
+
+syntax match rplStorage		   "\(^\|\s\+\)get\(i\|r\|c\|\)\ze\($\|\s\+\)"
+syntax match rplStorage		   "\(^\|\s\+\)put\(i\|r\|c\|\)\ze\($\|\s\+\)"
+syntax match rplStorage		   "\(^\|\s\+\)rcl\ze\($\|\s\+\)"
+syntax match rplStorage		   "\(^\|\s\+\)purge\ze\($\|\s\+\)"
+syntax match rplStorage		   "\(^\|\s\+\)sinv\ze\($\|\s\+\)"
+syntax match rplStorage		   "\(^\|\s\+\)sneg\ze\($\|\s\+\)"
+syntax match rplStorage		   "\(^\|\s\+\)sconj\ze\($\|\s\+\)"
+syntax match rplStorage		   "\(^\|\s\+\)steq\ze\($\|\s\+\)"
+syntax match rplStorage		   "\(^\|\s\+\)rceq\ze\($\|\s\+\)"
+syntax match rplStorage		   "\(^\|\s\+\)vars\ze\($\|\s\+\)"
+syntax match rplStorage		   "\(^\|\s\+\)clusr\ze\($\|\s\+\)"
+syntax match rplStorage		   "\(^\|\s\+\)sto\([+-/\*]\|\)\ze\($\|\s\+\)"
+
+syntax match rplAlgConditional	   "\(^\|\s\+\)ift\(e\|\)\ze\($\|\s\+\)"
+
+syntax match rplOperator	   "\(^\|\s\+\)and\ze\($\|\s\+\)"
+syntax match rplOperator	   "\(^\|\s\+\)\(x\|\)or\ze\($\|\s\+\)"
+syntax match rplOperator	   "\(^\|\s\+\)not\ze\($\|\s\+\)"
+syntax match rplOperator	   "\(^\|\s\+\)same\ze\($\|\s\+\)"
+syntax match rplOperator	   "\(^\|\s\+\)==\ze\($\|\s\+\)"
+syntax match rplOperator	   "\(^\|\s\+\)<=\ze\($\|\s\+\)"
+syntax match rplOperator	   "\(^\|\s\+\)=<\ze\($\|\s\+\)"
+syntax match rplOperator	   "\(^\|\s\+\)=>\ze\($\|\s\+\)"
+syntax match rplOperator	   "\(^\|\s\+\)>=\ze\($\|\s\+\)"
+syntax match rplOperator	   "\(^\|\s\+\)<>\ze\($\|\s\+\)"
+syntax match rplOperator	   "\(^\|\s\+\)>\ze\($\|\s\+\)"
+syntax match rplOperator	   "\(^\|\s\+\)<\ze\($\|\s\+\)"
+syntax match rplOperator	   "\(^\|\s\+\)[+-]\ze\($\|\s\+\)"
+syntax match rplOperator	   "\(^\|\s\+\)[/\*]\ze\($\|\s\+\)"
+syntax match rplOperator	   "\(^\|\s\+\)\^\ze\($\|\s\+\)"
+syntax match rplOperator	   "\(^\|\s\+\)\*\*\ze\($\|\s\+\)"
+
+syntax match rplBoolean		   "\(^\|\s\+\)true\ze\($\|\s\+\)"
+syntax match rplBoolean		   "\(^\|\s\+\)false\ze\($\|\s\+\)"
+
+syntax match rplReadWrite	   "\(^\|\s\+\)store\ze\($\|\s\+\)"
+syntax match rplReadWrite	   "\(^\|\s\+\)recall\ze\($\|\s\+\)"
+syntax match rplReadWrite	   "\(^\|\s\+\)\(\|wf\|un\)lock\ze\($\|\s\+\)"
+syntax match rplReadWrite	   "\(^\|\s\+\)open\ze\($\|\s\+\)"
+syntax match rplReadWrite	   "\(^\|\s\+\)close\ze\($\|\s\+\)"
+syntax match rplReadWrite	   "\(^\|\s\+\)delete\ze\($\|\s\+\)"
+syntax match rplReadWrite	   "\(^\|\s\+\)create\ze\($\|\s\+\)"
+syntax match rplReadWrite	   "\(^\|\s\+\)format\ze\($\|\s\+\)"
+syntax match rplReadWrite	   "\(^\|\s\+\)rewind\ze\($\|\s\+\)"
+syntax match rplReadWrite	   "\(^\|\s\+\)backspace\ze\($\|\s\+\)"
+syntax match rplReadWrite	   "\(^\|\s\+\)\(\|re\)write\ze\($\|\s\+\)"
+syntax match rplReadWrite	   "\(^\|\s\+\)read\ze\($\|\s\+\)"
+syntax match rplReadWrite	   "\(^\|\s\+\)inquire\ze\($\|\s\+\)"
+syntax match rplReadWrite	   "\(^\|\s\+\)sync\ze\($\|\s\+\)"
+syntax match rplReadWrite	   "\(^\|\s\+\)append\ze\($\|\s\+\)"
+syntax match rplReadWrite	   "\(^\|\s\+\)suppress\ze\($\|\s\+\)"
+syntax match rplReadWrite	   "\(^\|\s\+\)seek\ze\($\|\s\+\)"
+syntax match rplReadWrite	   "\(^\|\s\+\)pr\(1\|int\|st\|stc\|lcd\|var\|usr\|md\)\ze\($\|\s\+\)"
+syntax match rplReadWrite	   "\(^\|\s\+\)paper\ze\($\|\s\+\)"
+syntax match rplReadWrite	   "\(^\|\s\+\)cr\($\|\s\+\)"
+syntax match rplReadWrite	   "\(^\|\s\+\)erase\ze\($\|\s\+\)"
+syntax match rplReadWrite	   "\(^\|\s\+\)disp\ze\($\|\s\+\)"
+syntax match rplReadWrite	   "\(^\|\s\+\)input\ze\($\|\s\+\)"
+syntax match rplReadWrite	   "\(^\|\s\+\)prompt\ze\($\|\s\+\)"
+syntax match rplReadWrite	   "\(^\|\s\+\)key\ze\($\|\s\+\)"
+syntax match rplReadWrite	   "\(^\|\s\+\)cllcd\ze\($\|\s\+\)"
+syntax match rplReadWrite	   "\(^\|\s\+\)\(\|re\)draw\ze\($\|\s\+\)"
+syntax match rplReadWrite	   "\(^\|\s\+\)drax\ze\($\|\s\+\)"
+syntax match rplReadWrite	   "\(^\|\s\+\)indep\ze\($\|\s\+\)"
+syntax match rplReadWrite	   "\(^\|\s\+\)depnd\ze\($\|\s\+\)"
+syntax match rplReadWrite	   "\(^\|\s\+\)res\ze\($\|\s\+\)"
+syntax match rplReadWrite	   "\(^\|\s\+\)axes\ze\($\|\s\+\)"
+syntax match rplReadWrite	   "\(^\|\s\+\)label\ze\($\|\s\+\)"
+syntax match rplReadWrite	   "\(^\|\s\+\)pmin\ze\($\|\s\+\)"
+syntax match rplReadWrite	   "\(^\|\s\+\)pmax\ze\($\|\s\+\)"
+syntax match rplReadWrite	   "\(^\|\s\+\)centr\ze\($\|\s\+\)"
+syntax match rplReadWrite	   "\(^\|\s\+\)persist\ze\($\|\s\+\)"
+syntax match rplReadWrite	   "\(^\|\s\+\)title\ze\($\|\s\+\)"
+syntax match rplReadWrite	   "\(^\|\s\+\)\(slice\|auto\|log\|\)scale\ze\($\|\s\+\)"
+syntax match rplReadWrite	   "\(^\|\s\+\)eyept\ze\($\|\s\+\)"
+syntax match rplReadWrite	   "\(^\|\s\+\)\(p\|s\)par\ze\($\|\s\+\)"
+syntax match rplReadWrite	   "\(^\|\s\+\)function\ze\($\|\s\+\)"
+syntax match rplReadWrite	   "\(^\|\s\+\)polar\ze\($\|\s\+\)"
+syntax match rplReadWrite	   "\(^\|\s\+\)scatter\ze\($\|\s\+\)"
+syntax match rplReadWrite	   "\(^\|\s\+\)plotter\ze\($\|\s\+\)"
+syntax match rplReadWrite	   "\(^\|\s\+\)wireframe\ze\($\|\s\+\)"
+syntax match rplReadWrite	   "\(^\|\s\+\)parametric\ze\($\|\s\+\)"
+syntax match rplReadWrite	   "\(^\|\s\+\)slice\ze\($\|\s\+\)"
+syntax match rplReadWrite	   "\(^\|\s\+\)\*w\ze\($\|\s\+\)"
+syntax match rplReadWrite	   "\(^\|\s\+\)\*h\ze\($\|\s\+\)"
+syntax match rplReadWrite	   "\(^\|\s\+\)\*d\ze\($\|\s\+\)"
+syntax match rplReadWrite	   "\(^\|\s\+\)\*s\ze\($\|\s\+\)"
+syntax match rplReadWrite	   "\(^\|\s\+\)->lcd\ze\($\|\s\+\)"
+syntax match rplReadWrite	   "\(^\|\s\+\)lcd->\ze\($\|\s\+\)"
+syntax match rplReadWrite	   "\(^\|\s\+\)edit\ze\($\|\s\+\)"
+syntax match rplReadWrite	   "\(^\|\s\+\)visit\ze\($\|\s\+\)"
+
+syntax match rplIntrinsic	   "\(^\|\s\+\)abs\ze\($\|\s\+\)"
+syntax match rplIntrinsic	   "\(^\|\s\+\)arg\ze\($\|\s\+\)"
+syntax match rplIntrinsic	   "\(^\|\s\+\)conj\ze\($\|\s\+\)"
+syntax match rplIntrinsic	   "\(^\|\s\+\)re\ze\($\|\s\+\)"
+syntax match rplIntrinsic	   "\(^\|\s\+\)im\ze\($\|\s\+\)"
+syntax match rplIntrinsic	   "\(^\|\s\+\)mant\ze\($\|\s\+\)"
+syntax match rplIntrinsic	   "\(^\|\s\+\)xpon\ze\($\|\s\+\)"
+syntax match rplIntrinsic	   "\(^\|\s\+\)ceil\ze\($\|\s\+\)"
+syntax match rplIntrinsic	   "\(^\|\s\+\)fact\ze\($\|\s\+\)"
+syntax match rplIntrinsic	   "\(^\|\s\+\)fp\ze\($\|\s\+\)"
+syntax match rplIntrinsic	   "\(^\|\s\+\)floor\ze\($\|\s\+\)"
+syntax match rplIntrinsic	   "\(^\|\s\+\)inv\ze\($\|\s\+\)"
+syntax match rplIntrinsic	   "\(^\|\s\+\)ip\ze\($\|\s\+\)"
+syntax match rplIntrinsic	   "\(^\|\s\+\)max\ze\($\|\s\+\)"
+syntax match rplIntrinsic	   "\(^\|\s\+\)min\ze\($\|\s\+\)"
+syntax match rplIntrinsic	   "\(^\|\s\+\)mod\ze\($\|\s\+\)"
+syntax match rplIntrinsic	   "\(^\|\s\+\)neg\ze\($\|\s\+\)"
+syntax match rplIntrinsic	   "\(^\|\s\+\)relax\ze\($\|\s\+\)"
+syntax match rplIntrinsic	   "\(^\|\s\+\)sign\ze\($\|\s\+\)"
+syntax match rplIntrinsic	   "\(^\|\s\+\)sq\(\|rt\)\ze\($\|\s\+\)"
+syntax match rplIntrinsic	   "\(^\|\s\+\)xroot\ze\($\|\s\+\)"
+syntax match rplIntrinsic	   "\(^\|\s\+\)cos\ze\($\|\s\+\)"
+syntax match rplIntrinsic	   "\(^\|\s\+\)sin\ze\($\|\s\+\)"
+syntax match rplIntrinsic	   "\(^\|\s\+\)tan\ze\($\|\s\+\)"
+syntax match rplIntrinsic	   "\(^\|\s\+\)tg\ze\($\|\s\+\)"
+syntax match rplIntrinsic	   "\(^\|\s\+\)a\(\|rc\)cos\ze\($\|\s\+\)"
+syntax match rplIntrinsic	   "\(^\|\s\+\)a\(\|rc\)sin\ze\($\|\s\+\)"
+syntax match rplIntrinsic	   "\(^\|\s\+\)atan\ze\($\|\s\+\)"
+syntax match rplIntrinsic	   "\(^\|\s\+\)arctg\ze\($\|\s\+\)"
+syntax match rplIntrinsic	   "\(^\|\s\+\)\(\|a\)cosh\ze\($\|\s\+\)"
+syntax match rplIntrinsic	   "\(^\|\s\+\)\(\|a\)sinh\ze\($\|\s\+\)"
+syntax match rplIntrinsic	   "\(^\|\s\+\)\(\|a\)tanh\ze\($\|\s\+\)"
+syntax match rplIntrinsic	   "\(^\|\s\+\)\(\|arg\)th\ze\($\|\s\+\)"
+syntax match rplIntrinsic	   "\(^\|\s\+\)arg[cst]h\ze\($\|\s\+\)"
+syntax match rplIntrinsic	   "\(^\|\s\+\)\(\|a\)log\ze\($\|\s\+\)"
+syntax match rplIntrinsic	   "\(^\|\s\+\)ln\(\|1\)\ze\($\|\s\+\)"
+syntax match rplIntrinsic	   "\(^\|\s\+\)exp\(\|m\)\ze\($\|\s\+\)"
+syntax match rplIntrinsic	   "\(^\|\s\+\)trn\ze\($\|\s\+\)"
+syntax match rplIntrinsic	   "\(^\|\s\+\)con\ze\($\|\s\+\)"
+syntax match rplIntrinsic	   "\(^\|\s\+\)idn\ze\($\|\s\+\)"
+syntax match rplIntrinsic	   "\(^\|\s\+\)rdm\ze\($\|\s\+\)"
+syntax match rplIntrinsic	   "\(^\|\s\+\)rsd\ze\($\|\s\+\)"
+syntax match rplIntrinsic	   "\(^\|\s\+\)cnrm\ze\($\|\s\+\)"
+syntax match rplIntrinsic	   "\(^\|\s\+\)cross\ze\($\|\s\+\)"
+syntax match rplIntrinsic	   "\(^\|\s\+\)d[eo]t\ze\($\|\s\+\)"
+syntax match rplIntrinsic	   "\(^\|\s\+\)[cr]swp\ze\($\|\s\+\)"
+syntax match rplIntrinsic	   "\(^\|\s\+\)rci\(j\|\)\ze\($\|\s\+\)"
+syntax match rplIntrinsic	   "\(^\|\s\+\)\(in\|de\)cr\ze\($\|\s\+\)"
+syntax match rplIntrinsic	   "\(^\|\s\+\)bessel\ze\($\|\s\+\)"
+
+syntax match rplIntrinsic	   "\(^\|\s\+\)\(\|g\)egvl\ze\($\|\s\+\)"
+syntax match rplIntrinsic	   "\(^\|\s\+\)\(\|g\)\(\|l\|r\)egv\ze\($\|\s\+\)"
+syntax match rplIntrinsic	   "\(^\|\s\+\)rnrm\ze\($\|\s\+\)"
+syntax match rplIntrinsic	   "\(^\|\s\+\)\(std\|fix\|sci\|eng\)\ze\($\|\s\+\)"
+syntax match rplIntrinsic	   "\(^\|\s\+\)\(rad\|deg\)\ze\($\|\s\+\)"
+syntax match rplIntrinsic	   "\(^\|\s\+\)\(\|n\)rand\ze\($\|\s\+\)"
+syntax match rplIntrinsic	   "\(^\|\s\+\)rdz\ze\($\|\s\+\)"
+syntax match rplIntrinsic	   "\(^\|\s\+\)\(\|i\)fft\ze\($\|\s\+\)"
+syntax match rplIntrinsic	   "\(^\|\s\+\)\(dec\|bin\|oct\|hex\)\ze\($\|\s\+\)"
+syntax match rplIntrinsic	   "\(^\|\s\+\)rclf\ze\($\|\s\+\)"
+syntax match rplIntrinsic	   "\(^\|\s\+\)stof\ze\($\|\s\+\)"
+syntax match rplIntrinsic	   "\(^\|\s\+\)[cs]f\ze\($\|\s\+\)"
+syntax match rplIntrinsic	   "\(^\|\s\+\)chr\ze\($\|\s\+\)"
+syntax match rplIntrinsic	   "\(^\|\s\+\)num\ze\($\|\s\+\)"
+syntax match rplIntrinsic	   "\(^\|\s\+\)pos\ze\($\|\s\+\)"
+syntax match rplIntrinsic	   "\(^\|\s\+\)sub\ze\($\|\s\+\)"
+syntax match rplIntrinsic	   "\(^\|\s\+\)size\ze\($\|\s\+\)"
+syntax match rplIntrinsic	   "\(^\|\s\+\)\(st\|rc\)ws\ze\($\|\s\+\)"
+syntax match rplIntrinsic	   "\(^\|\s\+\)\(r\|s\)\(r\|l\)\(\|b\)\ze\($\|\s\+\)"
+syntax match rplIntrinsic	   "\(^\|\s\+\)as\(r\|l\)\ze\($\|\s\+\)"
+syntax match rplIntrinsic	   "\(^\|\s\+\)\(int\|der\)\ze\($\|\s\+\)"
+syntax match rplIntrinsic	   "\(^\|\s\+\)stos\ze\($\|\s\+\)"
+syntax match rplIntrinsic	   "\(^\|\s\+\)\(\|r\)cls\ze\($\|\s\+\)"
+syntax match rplIntrinsic	   "\(^\|\s\+\)drws\ze\($\|\s\+\)"
+syntax match rplIntrinsic	   "\(^\|\s\+\)scls\ze\($\|\s\+\)"
+syntax match rplIntrinsic	   "\(^\|\s\+\)ns\ze\($\|\s\+\)"
+syntax match rplIntrinsic	   "\(^\|\s\+\)tot\ze\($\|\s\+\)"
+syntax match rplIntrinsic	   "\(^\|\s\+\)mean\ze\($\|\s\+\)"
+syntax match rplIntrinsic	   "\(^\|\s\+\)\(\|p\)sdev\ze\($\|\s\+\)"
+syntax match rplIntrinsic	   "\(^\|\s\+\)\(\|p\)var\ze\($\|\s\+\)"
+syntax match rplIntrinsic	   "\(^\|\s\+\)maxs\ze\($\|\s\+\)"
+syntax match rplIntrinsic	   "\(^\|\s\+\)mins\ze\($\|\s\+\)"
+syntax match rplIntrinsic	   "\(^\|\s\+\)\(\|p\)cov\ze\($\|\s\+\)"
+syntax match rplIntrinsic	   "\(^\|\s\+\)cols\ze\($\|\s\+\)"
+syntax match rplIntrinsic	   "\(^\|\s\+\)s\(x\(\|y\|2\)\|y\(\|2\)\)\ze\($\|\s\+\)"
+syntax match rplIntrinsic	   "\(^\|\s\+\)\(x\|y\)col\ze\($\|\s\+\)"
+syntax match rplIntrinsic	   "\(^\|\s\+\)corr\ze\($\|\s\+\)"
+syntax match rplIntrinsic	   "\(^\|\s\+\)utp[cfnt]\ze\($\|\s\+\)"
+syntax match rplIntrinsic	   "\(^\|\s\+\)comb\ze\($\|\s\+\)"
+syntax match rplIntrinsic	   "\(^\|\s\+\)perm\ze\($\|\s\+\)"
+syntax match rplIntrinsic	   "\(^\|\s\+\)\(\|p\)lu\ze\($\|\s\+\)"
+syntax match rplIntrinsic	   "\(^\|\s\+\)[lu]chol\ze\($\|\s\+\)"
+syntax match rplIntrinsic	   "\(^\|\s\+\)schur\ze\($\|\s\+\)"
+syntax match rplIntrinsic	   "\(^\|\s\+\)%\ze\($\|\s\+\)"
+syntax match rplIntrinsic	   "\(^\|\s\+\)%ch\ze\($\|\s\+\)"
+syntax match rplIntrinsic	   "\(^\|\s\+\)%t\ze\($\|\s\+\)"
+syntax match rplIntrinsic	   "\(^\|\s\+\)hms->\ze\($\|\s\+\)"
+syntax match rplIntrinsic	   "\(^\|\s\+\)->hms\ze\($\|\s\+\)"
+syntax match rplIntrinsic	   "\(^\|\s\+\)hms+\ze\($\|\s\+\)"
+syntax match rplIntrinsic	   "\(^\|\s\+\)hms-\ze\($\|\s\+\)"
+syntax match rplIntrinsic	   "\(^\|\s\+\)d->r\ze\($\|\s\+\)"
+syntax match rplIntrinsic	   "\(^\|\s\+\)r->d\ze\($\|\s\+\)"
+syntax match rplIntrinsic	   "\(^\|\s\+\)b->r\ze\($\|\s\+\)"
+syntax match rplIntrinsic	   "\(^\|\s\+\)r->b\ze\($\|\s\+\)"
+syntax match rplIntrinsic	   "\(^\|\s\+\)c->r\ze\($\|\s\+\)"
+syntax match rplIntrinsic	   "\(^\|\s\+\)r->c\ze\($\|\s\+\)"
+syntax match rplIntrinsic	   "\(^\|\s\+\)r->p\ze\($\|\s\+\)"
+syntax match rplIntrinsic	   "\(^\|\s\+\)p->r\ze\($\|\s\+\)"
+syntax match rplIntrinsic	   "\(^\|\s\+\)str->\ze\($\|\s\+\)"
+syntax match rplIntrinsic	   "\(^\|\s\+\)->str\ze\($\|\s\+\)"
+syntax match rplIntrinsic	   "\(^\|\s\+\)array->\ze\($\|\s\+\)"
+syntax match rplIntrinsic	   "\(^\|\s\+\)->array\ze\($\|\s\+\)"
+syntax match rplIntrinsic	   "\(^\|\s\+\)list->\ze\($\|\s\+\)"
+syntax match rplIntrinsic	   "\(^\|\s\+\)->list\ze\($\|\s\+\)"
+syntax match rplIntrinsic	   "\(^\|\s\+\)s+\ze\($\|\s\+\)"
+syntax match rplIntrinsic	   "\(^\|\s\+\)s-\ze\($\|\s\+\)"
+syntax match rplIntrinsic	   "\(^\|\s\+\)col-\ze\($\|\s\+\)"
+syntax match rplIntrinsic	   "\(^\|\s\+\)col+\ze\($\|\s\+\)"
+syntax match rplIntrinsic	   "\(^\|\s\+\)row-\ze\($\|\s\+\)"
+syntax match rplIntrinsic	   "\(^\|\s\+\)row+\ze\($\|\s\+\)"
+syntax match rplIntrinsic	   "\(^\|\s\+\)->q\ze\($\|\s\+\)"
+
+syntax match rplObsolete	   "\(^\|\s\+\)arry->\ze\($\|\s\+\)"hs=e-5
+syntax match rplObsolete	   "\(^\|\s\+\)->arry\ze\($\|\s\+\)"hs=e-5
+
+" Conditional structures
+syntax match rplConditionalError   "\(^\|\s\+\)case\ze\($\|\s\+\)"hs=e-3
+syntax match rplConditionalError   "\(^\|\s\+\)then\ze\($\|\s\+\)"hs=e-3
+syntax match rplConditionalError   "\(^\|\s\+\)else\ze\($\|\s\+\)"hs=e-3
+syntax match rplConditionalError   "\(^\|\s\+\)elseif\ze\($\|\s\+\)"hs=e-5
+syntax match rplConditionalError   "\(^\|\s\+\)end\ze\($\|\s\+\)"hs=e-2
+syntax match rplConditionalError   "\(^\|\s\+\)\(step\|next\)\ze\($\|\s\+\)"hs=e-3
+syntax match rplConditionalError   "\(^\|\s\+\)until\ze\($\|\s\+\)"hs=e-4
+syntax match rplConditionalError   "\(^\|\s\+\)repeat\ze\($\|\s\+\)"hs=e-5
+syntax match rplConditionalError   "\(^\|\s\+\)default\ze\($\|\s\+\)"hs=e-6
+
+" FOR/(CYCLE)/(EXIT)/NEXT
+" FOR/(CYCLE)/(EXIT)/STEP
+" START/(CYCLE)/(EXIT)/NEXT
+" START/(CYCLE)/(EXIT)/STEP
+syntax match rplCycle              "\(^\|\s\+\)\(cycle\|exit\)\ze\($\|\s\+\)"
+syntax region rplForNext matchgroup=rplRepeat start="\(^\|\s\+\)\(for\|start\)\ze\($\|\s\+\)" end="\(^\|\s\+\)\(next\|step\)\ze\($\|\s\+\)" contains=ALL keepend extend
+
+" ELSEIF/END
+syntax region rplElseifEnd matchgroup=rplConditional start="\(^\|\s\+\)elseif\ze\($\|\s\+\)" end="\(^\|\s\+\)end\ze\($\|\s\+\)" contained contains=ALLBUT,rplElseEnd keepend
+
+" ELSE/END
+syntax region rplElseEnd matchgroup=rplConditional start="\(^\|\s\+\)else\ze\($\|\s\+\)" end="\(^\|\s\+\)end\ze\($\|\s\+\)" contained contains=ALLBUT,rplElseEnd,rplThenEnd,rplElseifEnd keepend
+
+" THEN/END
+syntax region rplThenEnd matchgroup=rplConditional start="\(^\|\s\+\)then\ze\($\|\s\+\)" end="\(^\|\s\+\)end\ze\($\|\s\+\)" contained containedin=rplIfEnd contains=ALLBUT,rplThenEnd keepend
+
+" IF/END
+syntax region rplIfEnd matchgroup=rplConditional start="\(^\|\s\+\)if\(err\|\)\ze\($\|\s\+\)" end="\(^\|\s\+\)end\ze\($\|\s\+\)" contains=ALLBUT,rplElseEnd,rplElseifEnd keepend extend
+" if end is accepted !
+" select end too !
+
+" CASE/THEN
+syntax region rplCaseThen matchgroup=rplConditional start="\(^\|\s\+\)case\ze\($\|\s\+\)" end="\(^\|\s\+\)then\ze\($\|\s\+\)" contains=ALLBUT,rplCaseThen,rplCaseEnd,rplThenEnd keepend extend contained containedin=rplCaseEnd
+
+" CASE/END
+syntax region rplCaseEnd matchgroup=rplConditional start="\(^\|\s\+\)case\ze\($\|\s\+\)" end="\(^\|\s\+\)end\ze\($\|\s\+\)" contains=ALLBUT,rplCaseEnd,rplThenEnd,rplElseEnd keepend extend contained containedin=rplSelectEnd
+
+" DEFAULT/END
+syntax region rplDefaultEnd matchgroup=rplConditional start="\(^\|\s\+\)default\ze\($\|\s\+\)" end="\(^\|\s\+\)end\ze\($\|\s\+\)" contains=ALLBUT,rplDefaultEnd keepend contained containedin=rplSelectEnd
+
+" SELECT/END
+syntax region rplSelectEnd matchgroup=rplConditional start="\(^\|\s\+\)select\ze\($\|\s\+\)" end="\(^\|\s\+\)end\ze\($\|\s\+\)" contains=ALLBUT,rplThenEnd keepend extend
+" select end is accepted !
+
+" DO/UNTIL/END
+syntax region rplUntilEnd matchgroup=rplConditional start="\(^\|\s\+\)until\ze\($\|\s\+\)" end="\(^\|\s\+\)\zsend\ze\($\|\s\+\)" contains=ALLBUT,rplUntilEnd contained containedin=rplDoUntil extend keepend
+syntax region rplDoUntil matchgroup=rplConditional start="\(^\|\s\+\)do\ze\($\|\s\+\)" end="\(^\|\s\+\)until\ze\($\|\s\+\)" contains=ALL keepend extend
+
+" WHILE/REPEAT/END
+syntax region rplRepeatEnd matchgroup=rplConditional start="\(^\|\s\+\)repeat\ze\($\|\s\+\)" end="\(^\|\s\+\)\zsend\ze\($\|\s\+\)" contains=ALLBUT,rplRepeatEnd contained containedin=rplWhileRepeat extend keepend
+syntax region rplWhileRepeat matchgroup=rplConditional start="\(^\|\s\+\)while\ze\($\|\s\+\)" end="\(^\|\s\+\)repeat\ze\($\|\s\+\)" contains=ALL keepend extend
+
+" Comments
+syntax match rplCommentError "\*/"
+syntax region rplCommentString contained start=+"+ end=+"+ end=+\*/+me=s-1
+syntax region rplCommentLine start="\(^\|\s\+\)//\ze" skip="\\$" end="$" contains=NONE keepend extend
+syntax region rplComment start="\(^\|\s\+\)/\*\ze" end="\*/" contains=rplCommentString keepend extend
+
+" Catch errors caused by too many right parentheses
+syntax region rplParen transparent start="(" end=")" contains=ALLBUT,rplParenError,rplComplex,rplIncluded keepend extend
+syntax match rplParenError ")"
+
+" Subroutines
+" Catch errors caused by too many right '>>'
+syntax match rplSubError "\(^\|\s\+\)>>\ze\($\|\s\+\)"hs=e-1
+syntax region rplSub matchgroup=rplSubDelimitor start="\(^\|\s\+\)<<\ze\($\|\s\+\)" end="\(^\|\s\+\)>>\ze\($\|\s\+\)" contains=ALLBUT,rplSubError,rplIncluded,rplDefaultEnd,rplStorageSub keepend extend
+
+" Expressions
+syntax region rplExpr start="\(^\|\s\+\)'" end="'\ze\($\|\s\+\)" contains=rplParen,rplParenError
+
+" Local variables
+syntax match rplStorageError "\(^\|\s\+\)->\ze\($\|\s\+\)"hs=e-1
+syntax region rplStorageSub matchgroup=rplStorage start="\(^\|\s\+\)<<\ze\($\|\s\+\)" end="\(^\|\s\+\)>>\ze\($\|\s\+\)" contains=ALLBUT,rplSubError,rplIncluded,rplDefaultEnd,rplStorageExpr contained containedin=rplLocalStorage keepend extend
+syntax region rplStorageExpr matchgroup=rplStorage start="\(^\|\s\+\)'" end="'\ze\($\|\s\+\)" contains=rplParen,rplParenError extend contained containedin=rplLocalStorage
+syntax region rplLocalStorage matchgroup=rplStorage start="\(^\|\s\+\)->\ze\($\|\s\+\)" end="\(^\|\s\+\)\(<<\ze\($\|\s\+\)\|'\)" contains=rplStorageSub,rplStorageExpr,rplComment,rplCommentLine keepend extend
+
+" Catch errors caused by too many right brackets
+syntax match rplArrayError "\]"
+syntax match rplArray "\]" contained containedin=rplArray
+syntax region rplArray matchgroup=rplArray start="\[" end="\]" contains=ALLBUT,rplArrayError keepend extend
+
+" Catch errors caused by too many right '}'
+syntax match rplListError "}"
+syntax match rplList "}" contained containedin=rplList
+syntax region rplList matchgroup=rplList start="{" end="}" contains=ALLBUT,rplListError,rplIncluded keepend extend
+
+" cpp is used by RPL/2
+syntax match rplPreProc   "\_^#\s*\(define\|undef\)\>"
+syntax match rplPreProc   "\_^#\s*\(warning\|error\)\>"
+syntax match rplPreCondit "\_^#\s*\(if\|ifdef\|ifndef\|elif\|else\|endif\)\>"
+syntax match rplIncluded contained "\<<\s*\S*\s*>\>"
+syntax match rplInclude   "\_^#\s*include\>\s*["<]" contains=rplIncluded,rplString
+"syntax match rplExecPath  "\%^\_^#!\s*\S*"
+syntax match rplExecPath  "\%^\_^#!\p*\_$"
+
+" Any integer
+syntax match rplInteger    "\(^\|\s\+\)[-+]\=\d\+\ze\($\|\s\+\)"
+
+" Floating point number
+" [S][ip].[fp]
+syntax match rplFloat       "\(^\|\s\+\)[-+]\=\(\d*\)\=[\.,]\(\d*\)\=\ze\($\|\s\+\)" contains=ALLBUT,rplPoint,rplSign
+" [S]ip[.fp]E[S]exp
+syntax match rplFloat       "\(^\|\s\+\)[-+]\=\d\+\([\.,]\d*\)\=[eE]\([-+]\)\=\d\+\ze\($\|\s\+\)" contains=ALLBUT,rplPoint,rplSign
+" [S].fpE[S]exp
+syntax match rplFloat       "\(^\|\s\+\)[-+]\=\(\d*\)\=[\.,]\d\+[eE]\([-+]\)\=\d\+\ze\($\|\s\+\)" contains=ALLBUT,rplPoint,rplSign
+syntax match rplPoint      "\<[\.,]\>"
+syntax match rplSign       "\<[+-]\>"
+
+" Complex number
+" (x,y)
+syntax match rplComplex    "\(^\|\s\+\)([-+]\=\(\d*\)\=\.\=\d*\([eE][-+]\=\d\+\)\=\s*,\s*[-+]\=\(\d*\)\=\.\=\d*\([eE][-+]\=\d\+\)\=)\ze\($\|\s\+\)"
+" (x.y)
+syntax match rplComplex    "\(^\|\s\+\)([-+]\=\(\d*\)\=,\=\d*\([eE][-+]\=\d\+\)\=\s*\.\s*[-+]\=\(\d*\)\=,\=\d*\([eE][-+]\=\d\+\)\=)\ze\($\|\s\+\)"
+
+" Strings
+syntax match rplStringGuilles       "\\\""
+syntax match rplStringAntislash     "\\\\"
+syntax region rplString start=+\(^\|\s\+\)"+ end=+"\ze\($\|\s\+\)+ contains=rplStringGuilles,rplStringAntislash
+
+syntax match rplTab "\t"  transparent
+
+" Define the default highlighting.
+" For version 5.7 and earlier: only when not done already
+" For version 5.8 and later: only when an item doesn't have highlighting yet
+if version >= 508 || !exists("did_rpl_syntax_inits")
+  if version < 508
+    let did_rpl_syntax_inits = 1
+    command -nargs=+ HiLink highlight link <args>
+  else
+    command -nargs=+ HiLink highlight default link <args>
+  endif
+
+  " The default highlighting.
+
+  HiLink rplControl		Statement
+  HiLink rplStatement		Statement
+  HiLink rplAlgConditional	Conditional
+  HiLink rplConditional		Repeat
+  HiLink rplConditionalError	Error
+  HiLink rplRepeat		Repeat
+  HiLink rplCycle		Repeat
+  HiLink rplUntil		Repeat
+  HiLink rplIntrinsic		Special
+  HiLink rplStorage		StorageClass
+  HiLink rplStorageExpr		StorageClass
+  HiLink rplStorageError	Error
+  HiLink rplReadWrite		rplIntrinsic
+
+  HiLink rplOperator		Operator
+
+  HiLink rplList		Special
+  HiLink rplArray		Special
+  HiLink rplConstant		Identifier
+  HiLink rplExpr		Type
+
+  HiLink rplString		String
+  HiLink rplStringGuilles	String
+  HiLink rplStringAntislash	String
+
+  HiLink rplBinary		Boolean
+  HiLink rplOctal		Boolean
+  HiLink rplDecimal		Boolean
+  HiLink rplHexadecimal		Boolean
+  HiLink rplInteger		Number
+  HiLink rplFloat		Float
+  HiLink rplComplex		Float
+  HiLink rplBoolean		Identifier
+
+  HiLink rplObsolete		Todo
+
+  HiLink rplPreCondit		PreCondit
+  HiLink rplInclude		Include
+  HiLink rplIncluded		rplString
+  HiLink rplInclude		Include
+  HiLink rplExecPath		Include
+  HiLink rplPreProc		PreProc
+  HiLink rplComment		Comment
+  HiLink rplCommentLine		Comment
+  HiLink rplCommentString	Comment
+  HiLink rplSubDelimitor	rplStorage
+  HiLink rplCommentError	Error
+  HiLink rplParenError		Error
+  HiLink rplSubError		Error
+  HiLink rplArrayError		Error
+  HiLink rplListError		Error
+  HiLink rplTab			Error
+  HiLink rplBinaryError		Error
+  HiLink rplOctalError		Error
+  HiLink rplDecimalError	Error
+  HiLink rplHexadecimalError	Error
+
+  delcommand HiLink
+endif
+
+let b:current_syntax = "rpl"
+
+" vim: ts=8 tw=132
--- /dev/null
+++ b/lib/vimfiles/syntax/rst.vim
@@ -1,0 +1,178 @@
+" Vim syntax file
+" Language:         reStructuredText documentation format
+" Maintainer:       Nikolai Weibull <now@bitwi.se>
+" Latest Revision:  2006-07-04
+
+if exists("b:current_syntax")
+  finish
+endif
+
+let s:cpo_save = &cpo
+set cpo&vim
+
+syn case ignore
+
+" FIXME: The problem with these two is that Vim doesn’t seem to like
+" matching across line boundaries.
+"
+" syn match   rstSections /^.*\n[=`:.'"~^_*+#-]\+$/
+
+" syn match   rstTransition  /^\s*[=`:.'"~^_*+#-]\{4,}\s*$/
+
+syn cluster rstCruft                contains=rstEmphasis,rstStrongEmphasis,
+      \ rstInterpretedText,rstInlineLiteral,rstSubstitutionReference,
+      \ rstInlineInternalTargets,rstFootnoteReference,rstHyperlinkReference
+
+syn region  rstLiteralBlock         matchgroup=rstDelimiter
+      \ start='::\_s*\n\ze\z(\s\+\)' skip='^$' end='^\z1\@!'
+      \ contains=@NoSpell
+
+syn region  rstQuotedLiteralBlock   matchgroup=rstDelimiter
+      \ start="::\_s*\n\ze\z([!\"#$%&'()*+,-./:;<=>?@[\]^_`{|}~]\)"
+      \ end='^\z1\@!' contains=@NoSpell
+
+syn region  rstDoctestBlock         oneline display matchgroup=rstDelimiter
+      \ start='^>>>\s' end='^$'
+
+syn region  rstTable                transparent start='^\n\s*+[-=+]\+' end='^$'
+      \ contains=rstTableLines,@rstCruft
+syn match   rstTableLines           contained display '|\|+\%(=\+\|-\+\)\='
+
+syn region  rstSimpleTable          transparent
+      \ start='^\n\%(\s*\)\@>\%(\%(=\+\)\@>\%(\s\+\)\@>\)\%(\%(\%(=\+\)\@>\%(\s*\)\@>\)\+\)\@>$'
+      \ end='^$'
+      \ contains=rstSimpleTableLines,@rstCruft
+syn match   rstSimpleTableLines     contained display
+      \ '^\%(\s*\)\@>\%(\%(=\+\)\@>\%(\s\+\)\@>\)\%(\%(\%(=\+\)\@>\%(\s*\)\@>\)\+\)\@>$'
+syn match   rstSimpleTableLines     contained display
+      \ '^\%(\s*\)\@>\%(\%(-\+\)\@>\%(\s\+\)\@>\)\%(\%(\%(-\+\)\@>\%(\s*\)\@>\)\+\)\@>$'
+
+syn cluster rstDirectives           contains=rstFootnote,rstCitation,
+      \ rstHyperlinkTarget,rstExDirective
+
+syn match   rstExplicitMarkup       '^\.\.\_s'
+      \ nextgroup=@rstDirectives,rstComment,rstSubstitutionDefinition
+
+let s:ReferenceName = '[[:alnum:]]\+\%([_.-][[:alnum:]]\+\)*'
+
+syn keyword     rstTodo             contained FIXME TODO XXX NOTE
+
+execute 'syn region rstComment contained' .
+      \ ' start=/.*/'
+      \ ' end=/^\s\@!/ contains=rstTodo'
+
+execute 'syn region rstFootnote contained matchgroup=rstDirective' .
+      \ ' start=+\[\%(\d\+\|#\%(' . s:ReferenceName . '\)\=\|\*\)\]\_s+' .
+      \ ' skip=+^$+' .
+      \ ' end=+^\s\@!+ contains=@rstCruft,@NoSpell'
+
+execute 'syn region rstCitation contained matchgroup=rstDirective' .
+      \ ' start=+\[' . s:ReferenceName . '\]\_s+' .
+      \ ' skip=+^$+' .
+      \ ' end=+^\s\@!+ contains=@rstCruft,@NoSpell'
+
+syn region rstHyperlinkTarget contained matchgroup=rstDirective
+      \ start='_\%(_\|[^:\\]*\%(\\.[^:\\]*\)*\):\_s' skip=+^$+ end=+^\s\@!+
+
+syn region rstHyperlinkTarget contained matchgroup=rstDirective
+      \ start='_`[^`\\]*\%(\\.[^`\\]*\)*`:\_s' skip=+^$+ end=+^\s\@!+
+
+syn region rstHyperlinkTarget matchgroup=rstDirective
+      \ start=+^__\_s+ skip=+^$+ end=+^\s\@!+
+
+execute 'syn region rstExDirective contained matchgroup=rstDirective' .
+      \ ' start=+' . s:ReferenceName . '::\_s+' .
+      \ ' skip=+^$+' .
+      \ ' end=+^\s\@!+ contains=@rstCruft'
+
+execute 'syn match rstSubstitutionDefinition contained' .
+      \ ' /|' . s:ReferenceName . '|\_s\+/ nextgroup=@rstDirectives'
+
+function! s:DefineOneInlineMarkup(name, start, middle, end, char_left, char_right)
+  execute 'syn region rst' . a:name .
+        \ ' start=+' . a:char_left . '\zs' . a:start .
+        \ '\ze[^[:space:]' . a:char_right . a:start[strlen(a:start) - 1] . ']+' .
+        \ a:middle .
+        \ ' end=+\S' . a:end . '\ze\%($\|\s\|[''")\]}>/:.,;!?\\-]\)+'
+endfunction
+
+function! s:DefineInlineMarkup(name, start, middle, end)
+  let middle = a:middle != "" ?
+        \ (' skip=+\\\\\|\\' . a:middle . '+') :
+        \ ""
+
+  call s:DefineOneInlineMarkup(a:name, a:start, middle, a:end, "'", "'")
+  call s:DefineOneInlineMarkup(a:name, a:start, middle, a:end, '"', '"') 
+  call s:DefineOneInlineMarkup(a:name, a:start, middle, a:end, '(', ')') 
+  call s:DefineOneInlineMarkup(a:name, a:start, middle, a:end, '\[', '\]') 
+  call s:DefineOneInlineMarkup(a:name, a:start, middle, a:end, '{', '}') 
+  call s:DefineOneInlineMarkup(a:name, a:start, middle, a:end, '<', '>') 
+
+  call s:DefineOneInlineMarkup(a:name, a:start, middle, a:end, '\%(^\|\s\|[/:]\)', '')
+
+  execute 'syn match rst' . a:name .
+        \ ' +\%(^\|\s\|[''"([{</:]\)\zs' . a:start .
+        \ '[^[:space:]' . a:start[strlen(a:start) - 1] . ']'
+        \ a:end . '\ze\%($\|\s\|[''")\]}>/:.,;!?\\-]\)+'
+
+  execute 'hi def link rst' . a:name . 'Delimiter' . ' rst' . a:name
+endfunction
+
+call s:DefineInlineMarkup('Emphasis', '\*', '\*', '\*')
+call s:DefineInlineMarkup('StrongEmphasis', '\*\*', '\*', '\*\*')
+call s:DefineInlineMarkup('InterpretedTextOrHyperlinkReference', '`', '`', '`_\{0,2}')
+call s:DefineInlineMarkup('InlineLiteral', '``', "", '``')
+call s:DefineInlineMarkup('SubstitutionReference', '|', '|', '|_\{0,2}')
+call s:DefineInlineMarkup('InlineInternalTargets', '_`', '`', '`')
+
+" TODO: Can’t remember why these two can’t be defined like the ones above.
+execute 'syn match rstFootnoteReference contains=@NoSpell' .
+      \ ' +\[\%(\d\+\|#\%(' . s:ReferenceName . '\)\=\|\*\)\]_+'
+
+execute 'syn match rstCitationReference contains=@NoSpell' .
+      \ ' +\[' . s:ReferenceName . '\]_\ze\%($\|\s\|[''")\]}>/:.,;!?\\-]\)+'
+
+execute 'syn match rstHyperlinkReference' .
+      \ ' /\<' . s:ReferenceName . '__\=\ze\%($\|\s\|[''")\]}>/:.,;!?\\-]\)/'
+
+syn match   rstStandaloneHyperlink  contains=@NoSpell
+      \ "\<\%(\%(\%(https\=\|file\|ftp\|gopher\)://\|\%(mailto\|news\):\)[^[:space:]'\"<>]\+\|www[[:alnum:]_-]*\.[[:alnum:]_-]\+\.[^[:space:]'\"<>]\+\)[[:alnum:]/]"
+
+" TODO: Use better syncing.  I don’t know the specifics of syncing well enough,
+" though.
+syn sync minlines=50
+
+hi def link rstTodo                         Todo
+hi def link rstComment                      Comment
+"hi def link rstSections                     Type
+"hi def link rstTransition                   Type
+hi def link rstLiteralBlock                 String
+hi def link rstQuotedLiteralBlock           String
+hi def link rstDoctestBlock                 PreProc
+hi def link rstTableLines                   rstDelimiter
+hi def link rstSimpleTableLines             rstTableLines
+hi def link rstExplicitMarkup               rstDirective
+hi def link rstDirective                    Keyword
+hi def link rstFootnote                     String
+hi def link rstCitation                     String
+hi def link rstHyperlinkTarget              String
+hi def link rstExDirective                  String
+hi def link rstSubstitutionDefinition       rstDirective
+hi def link rstDelimiter                    Delimiter
+" TODO: I dunno...
+hi def      rstEmphasis                     term=italic cterm=italic gui=italic
+hi def link rstStrongEmphasis               Special
+"term=bold cterm=bold gui=bold
+hi def link rstInterpretedTextOrHyperlinkReference  Identifier
+hi def link rstInlineLiteral                String
+hi def link rstSubstitutionReference        PreProc
+hi def link rstInlineInternalTargets        Identifier
+hi def link rstFootnoteReference            Identifier
+hi def link rstCitationReference            Identifier
+hi def link rstHyperLinkReference           Identifier
+hi def link rstStandaloneHyperlink          Identifier
+
+let b:current_syntax = "rst"
+
+let &cpo = s:cpo_save
+unlet s:cpo_save
--- /dev/null
+++ b/lib/vimfiles/syntax/rtf.vim
@@ -1,0 +1,88 @@
+" Vim syntax file
+" Language:	Rich Text Format
+"		"*.rtf" files
+"
+" The Rich Text Format (RTF) Specification is a method of encoding formatted
+" text and graphics for easy transfer between applications.
+" .hlp (windows help files) use compiled rtf files
+" rtf documentation at http://night.primate.wisc.edu/software/RTF/
+"
+" Maintainer:	Dominique St�phan (dominique@mggen.com)
+" URL: http://www.mggen.com/vim/syntax/rtf.zip
+" Last change:	2001 Mai 02
+
+" TODO: render underline, italic, bold
+
+" For version 5.x: Clear all syntax items
+" For version 6.x: Quit when a syntax file was already loaded
+if version < 600
+  syntax clear
+elseif exists("b:current_syntax")
+  finish
+endif
+
+" case on (all controls must be lower case)
+syn case match
+
+" Control Words
+syn match rtfControlWord	"\\[a-z]\+[\-]\=[0-9]*"
+
+" New Control Words (not in the 1987 specifications)
+syn match rtfNewControlWord	"\\\*\\[a-z]\+[\-]\=[0-9]*"
+
+" Control Symbol : any \ plus a non alpha symbol, *, \, { and } and '
+syn match rtfControlSymbol	"\\[^a-zA-Z\*\{\}\\']"
+
+" { } and \ are special characters, to use them
+" we add a backslash \
+syn match rtfCharacter		"\\\\"
+syn match rtfCharacter		"\\{"
+syn match rtfCharacter		"\\}"
+" Escaped characters (for 8 bytes characters upper than 127)
+syn match rtfCharacter		"\\'[A-Za-z0-9][A-Za-z0-9]"
+" Unicode
+syn match rtfUnicodeCharacter	"\\u[0-9][0-9]*"
+
+" Color values, we will put this value in Red, Green or Blue
+syn match rtfRed		"\\red[0-9][0-9]*"
+syn match rtfGreen		"\\green[0-9][0-9]*"
+syn match rtfBlue		"\\blue[0-9][0-9]*"
+
+" Some stuff for help files
+syn match rtfFootNote "[#$K+]{\\footnote.*}" contains=rtfControlWord,rtfNewControlWord
+
+" Define the default highlighting.
+" For version 5.7 and earlier: only when not done already
+" For version 5.8 and later: only when an item doesn't have highlighting yet
+if version >= 508 || !exists("did_rtf_syntax_inits")
+  if version < 508
+    let did_rtf_syntax_inits = 1
+    command -nargs=+ HiLink hi link <args>
+  else
+    command -nargs=+ HiLink hi def link <args>
+  endif
+
+
+   HiLink rtfControlWord		Statement
+   HiLink rtfNewControlWord	Special
+   HiLink rtfControlSymbol	Constant
+   HiLink rtfCharacter		Character
+   HiLink rtfUnicodeCharacter	SpecialChar
+   HiLink rtfFootNote		Comment
+
+   " Define colors for the syntax file
+   hi rtfRed	      term=underline cterm=underline ctermfg=DarkRed gui=underline guifg=DarkRed
+   hi rtfGreen	      term=underline cterm=underline ctermfg=DarkGreen gui=underline guifg=DarkGreen
+   hi rtfBlue	      term=underline cterm=underline ctermfg=DarkBlue gui=underline guifg=DarkBlue
+
+   HiLink rtfRed	rtfRed
+   HiLink rtfGreen	rtfGreen
+   HiLink rtfBlue	rtfBlue
+
+  delcommand HiLink
+endif
+
+
+let b:current_syntax = "rtf"
+
+" vim:ts=8
--- /dev/null
+++ b/lib/vimfiles/syntax/ruby.vim
@@ -1,0 +1,324 @@
+" Vim syntax file
+" Language:		Ruby
+" Maintainer:		Doug Kearns <dougkearns@gmail.com>
+" Info:			$Id: ruby.vim,v 1.134 2007/05/06 17:55:04 tpope Exp $
+" URL:			http://vim-ruby.rubyforge.org
+" Anon CVS:		See above site
+" Release Coordinator:	Doug Kearns <dougkearns@gmail.com>
+" ----------------------------------------------------------------------------
+"
+" Previous Maintainer:	Mirko Nasato
+" Thanks to perl.vim authors, and to Reimer Behrends. :-) (MN)
+" ----------------------------------------------------------------------------
+
+if exists("b:current_syntax")
+  finish
+endif
+
+if has("folding") && exists("ruby_fold")
+  setlocal foldmethod=syntax
+endif
+
+if exists("ruby_space_errors")
+  if !exists("ruby_no_trail_space_error")
+    syn match rubySpaceError display excludenl "\s\+$"
+  endif
+  if !exists("ruby_no_tab_space_error")
+    syn match rubySpaceError display " \+\t"me=e-1
+  endif
+endif
+
+" Operators
+if exists("ruby_operators")
+  syn match  rubyOperator	 "\%([~!^&|*/%+-]\|\%(class\s*\)\@<!<<\|<=>\|<=\|\%(<\|\<class\s\+\u\w*\s*\)\@<!<[^<]\@=\|===\|==\|=\~\|>>\|>=\|=\@<!>\|\*\*\|\.\.\.\|\.\.\|::\)"
+  syn match  rubyPseudoOperator  "\%(-=\|/=\|\*\*=\|\*=\|&&=\|&=\|&&\|||=\||=\|||\|%=\|+=\|!\~\|!=\)"
+  syn region rubyBracketOperator matchgroup=rubyOperator start="\%([_[:lower:]]\w*[?!=]\=\|[})]\)\@<=\[\s*" end="\s*]" contains=TOP
+endif
+
+" Expression Substitution and Backslash Notation
+syn match rubyEscape	"\\\\\|\\[abefnrstv]\|\\\o\{1,3}\|\\x\x\{1,2}"							 contained display
+syn match rubyEscape	"\%(\\M-\\C-\|\\C-\\M-\|\\M-\\c\|\\c\\M-\|\\c\|\\C-\|\\M-\)\%(\\\o\{1,3}\|\\x\x\{1,2}\|\\\=\S\)" contained display
+
+syn region rubyInterpolation	      matchgroup=rubyInterpolationDelimiter start="#{" end="}" contained contains=TOP
+syn match  rubyInterpolation	      "#\%(\$\|@@\=\)\w\+"    display contained  contains=rubyInterpolationDelimiter,rubyInstanceVariable,rubyClassVariable,rubyGlobalVariable,rubyPredefinedVariable
+syn match  rubyInterpolationDelimiter "#\ze\%(\$\|@@\=\)\w\+" display contained
+syn match  rubyInterpolation	      "#\$\%(-\w\|\W\)"       display contained  contains=rubyInterpolationDelimiter,rubyPredefinedVariable,rubyInvalidVariable
+syn match  rubyInterpolationDelimiter "#\ze\$\%(-\w\|\W\)"    display contained
+syn region rubyNoInterpolation	      start="\\#{" end="}"    contained
+syn match  rubyNoInterpolation	      "\\#{"		      display contained
+syn match  rubyNoInterpolation	      "\\#\%(\$\|@@\=\)\w\+"  display contained
+syn match  rubyNoInterpolation	      "\\#\$\W"               display contained
+
+syn match rubyDelimEscape	"\\[(<{\[)>}\]]" transparent display contained contains=NONE
+
+syn region rubyNestedParentheses	start="("	end=")"		skip="\\\\\|\\)"	transparent contained contains=@rubyStringSpecial,rubyNestedParentheses,rubyDelimEscape
+syn region rubyNestedCurlyBraces	start="{"	end="}"		skip="\\\\\|\\}"	transparent contained contains=@rubyStringSpecial,rubyNestedCurlyBraces,rubyDelimEscape
+syn region rubyNestedAngleBrackets	start="<"	end=">"		skip="\\\\\|\\>"	transparent contained contains=@rubyStringSpecial,rubyNestedAngleBrackets,rubyDelimEscape
+if exists("ruby_operators")
+  syn region rubyNestedSquareBrackets	start="\["	end="\]"	skip="\\\\\|\\\]"	transparent contained contains=@rubyStringSpecial,rubyNestedSquareBrackets,rubyDelimEscape
+else
+  syn region rubyNestedSquareBrackets	start="\["	end="\]"	skip="\\\\\|\\\]"	transparent containedin=rubyArrayLiteral contained contains=@rubyStringSpecial,rubyNestedSquareBrackets,rubyDelimEscape
+endif
+
+syn cluster rubyStringSpecial		contains=rubyInterpolation,rubyNoInterpolation,rubyEscape
+syn cluster rubyExtendedStringSpecial	contains=@rubyStringSpecial,rubyNestedParentheses,rubyNestedCurlyBraces,rubyNestedAngleBrackets,rubyNestedSquareBrackets
+
+" Numbers and ASCII Codes
+syn match rubyASCIICode	"\%(\w\|[]})\"'/]\)\@<!\%(?\%(\\M-\\C-\|\\C-\\M-\|\\M-\\c\|\\c\\M-\|\\c\|\\C-\|\\M-\)\=\%(\\\o\{1,3}\|\\x\x\{1,2}\|\\\=\S\)\)"
+syn match rubyInteger	"\<0[xX]\x\+\%(_\x\+\)*\>"								display
+syn match rubyInteger	"\<\%(0[dD]\)\=\%(0\|[1-9]\d*\%(_\d\+\)*\)\>"						display
+syn match rubyInteger	"\<0[oO]\=\o\+\%(_\o\+\)*\>"								display
+syn match rubyInteger	"\<0[bB][01]\+\%(_[01]\+\)*\>"								display
+syn match rubyFloat	"\<\%(0\|[1-9]\d*\%(_\d\+\)*\)\.\d\+\%(_\d\+\)*\>"					display
+syn match rubyFloat	"\<\%(0\|[1-9]\d*\%(_\d\+\)*\)\%(\.\d\+\%(_\d\+\)*\)\=\%([eE][-+]\=\d\+\%(_\d\+\)*\)\>"	display
+
+" Identifiers
+syn match rubyLocalVariableOrMethod "\<[_[:lower:]][_[:alnum:]]*[?!=]\=" contains=NONE display transparent
+syn match rubyBlockArgument	    "&[_[:lower:]][_[:alnum:]]"		 contains=NONE display transparent
+
+syn match  rubyConstant			"\%(\%([.@$]\@<!\.\)\@<!\<\|::\)\_s*\zs\u\w*\%(\>\|::\)\@=\%(\s*(\)\@!"
+syn match  rubyClassVariable		"@@\h\w*" display
+syn match  rubyInstanceVariable		"@\h\w*"  display
+syn match  rubyGlobalVariable		"$\%(\h\w*\|-.\)"
+syn match  rubySymbol			"[]})\"':]\@<!:\%(\^\|\~\|<<\|<=>\|<=\|<\|===\|==\|=\~\|>>\|>=\|>\||\|-@\|-\|/\|\[]=\|\[]\|\*\*\|\*\|&\|%\|+@\|+\|`\)"
+syn match  rubySymbol			"[]})\"':]\@<!:\$\%(-.\|[`~<=>_,;:!?/.'"@$*\&+0]\)"
+syn match  rubySymbol			"[]})\"':]\@<!:\%(\$\|@@\=\)\=\h\w*"
+syn match  rubySymbol			"[]})\"':]\@<!:\h\w*[?!=]\="
+syn region rubySymbol			start="[]})\"':]\@<!:\"" end="\"" skip="\\\\\|\\\""
+syn region rubySymbol			start="[]})\"':]\@<!:\"" end="\"" skip="\\\\\|\\\"" contains=@rubyStringSpecial fold
+
+syn match  rubyBlockParameter		"\h\w*" contained
+syn region rubyBlockParameterList	start="\%(\%(\<do\>\|{\)\s*\)\@<=|" end="|" oneline display contains=rubyBlockParameter
+
+syn match rubyInvalidVariable    "$[^ A-Za-z-]"
+syn match rubyPredefinedVariable #$[!$&"'*+,./0:;<=>?@\`~1-9]#
+syn match rubyPredefinedVariable "$_\>"											   display
+syn match rubyPredefinedVariable "$-[0FIKadilpvw]\>"									   display
+syn match rubyPredefinedVariable "$\%(deferr\|defout\|stderr\|stdin\|stdout\)\>"					   display
+syn match rubyPredefinedVariable "$\%(DEBUG\|FILENAME\|KCODE\|LOADED_FEATURES\|LOAD_PATH\|PROGRAM_NAME\|SAFE\|VERBOSE\)\>" display
+syn match rubyPredefinedConstant "\%(\%(\.\@<!\.\)\@<!\|::\)\_s*\zs\%(MatchingData\|ARGF\|ARGV\|ENV\)\>\%(\s*(\)\@!"
+syn match rubyPredefinedConstant "\%(\%(\.\@<!\.\)\@<!\|::\)\_s*\zs\%(DATA\|FALSE\|NIL\|RUBY_PLATFORM\|RUBY_RELEASE_DATE\)\>\%(\s*(\)\@!"
+syn match rubyPredefinedConstant "\%(\%(\.\@<!\.\)\@<!\|::\)\_s*\zs\%(RUBY_VERSION\|STDERR\|STDIN\|STDOUT\|TOPLEVEL_BINDING\|TRUE\)\>\%(\s*(\)\@!"
+"Obsolete Global Constants
+"syn match rubyPredefinedConstant "\%(::\)\=\zs\%(PLATFORM\|RELEASE_DATE\|VERSION\)\>"
+"syn match rubyPredefinedConstant "\%(::\)\=\zs\%(NotImplementError\)\>"
+
+" Normal Regular Expression
+syn region rubyRegexp matchgroup=rubyRegexpDelimiter start="\%(\%(^\|\<\%(and\|or\|while\|until\|unless\|if\|elsif\|when\|not\|then\|else\)\|[;\~=!|&(,[>]\)\s*\)\@<=/" end="/[iomxneus]*" skip="\\\\\|\\/" contains=@rubyStringSpecial fold
+syn region rubyRegexp matchgroup=rubyRegexpDelimiter start="\%(\<\%(split\|scan\|gsub\|sub\)\s*\)\@<=/" end="/[iomxneus]*" skip="\\\\\|\\/" contains=@rubyStringSpecial fold
+
+" Normal String and Shell Command Output
+syn region rubyString matchgroup=rubyStringDelimiter start="\"" end="\"" skip="\\\\\|\\\"" contains=@rubyStringSpecial fold
+syn region rubyString matchgroup=rubyStringDelimiter start="'"	end="'"  skip="\\\\\|\\'"			       fold
+syn region rubyString matchgroup=rubyStringDelimiter start="`"	end="`"  skip="\\\\\|\\`"  contains=@rubyStringSpecial fold
+
+" Generalized Regular Expression
+syn region rubyRegexp matchgroup=rubyRegexpDelimiter start="%r\z([~`!@#$%^&*_\-+=|\:;"',.?/]\)"	end="\z1[iomxneus]*" skip="\\\\\|\\\z1" contains=@rubyStringSpecial fold
+syn region rubyRegexp matchgroup=rubyRegexpDelimiter start="%r{"				end="}[iomxneus]*"	 skip="\\\\\|\\}"   contains=@rubyStringSpecial,rubyNestedCurlyBraces,rubyDelimEscape fold
+syn region rubyRegexp matchgroup=rubyRegexpDelimiter start="%r<"				end=">[iomxneus]*"	 skip="\\\\\|\\>"   contains=@rubyStringSpecial,rubyNestedAngleBrackets,rubyDelimEscape fold
+syn region rubyRegexp matchgroup=rubyRegexpDelimiter start="%r\["				end="\][iomxneus]*"	 skip="\\\\\|\\\]"  contains=@rubyStringSpecial,rubyNestedSquareBrackets,rubyDelimEscape fold
+syn region rubyRegexp matchgroup=rubyRegexpDelimiter start="%r("				end=")[iomxneus]*"	 skip="\\\\\|\\)"   contains=@rubyStringSpecial,rubyNestedParentheses,rubyDelimEscape fold
+
+" Generalized Single Quoted String, Symbol and Array of Strings
+syn region rubyString matchgroup=rubyStringDelimiter start="%[qw]\z([~`!@#$%^&*_\-+=|\:;"',.?/]\)"  end="\z1" skip="\\\\\|\\\z1" fold
+syn region rubyString matchgroup=rubyStringDelimiter start="%[qw]{"				    end="}"   skip="\\\\\|\\}"	 fold	contains=rubyNestedCurlyBraces,rubyDelimEscape
+syn region rubyString matchgroup=rubyStringDelimiter start="%[qw]<"				    end=">"   skip="\\\\\|\\>"	 fold	contains=rubyNestedAngleBrackets,rubyDelimEscape
+syn region rubyString matchgroup=rubyStringDelimiter start="%[qw]\["				    end="\]"  skip="\\\\\|\\\]"	 fold	contains=rubyNestedSquareBrackets,rubyDelimEscape
+syn region rubyString matchgroup=rubyStringDelimiter start="%[qw]("				    end=")"   skip="\\\\\|\\)"	 fold	contains=rubyNestedParentheses,rubyDelimEscape
+syn region rubySymbol				     start="%[s]\z([~`!@#$%^&*_\-+=|\:;"',.?/]\)"   end="\z1" skip="\\\\\|\\\z1" fold
+syn region rubySymbol				     start="%[s]{"				    end="}"   skip="\\\\\|\\}"	 fold	contains=rubyNestedCurlyBraces,rubyDelimEscape
+syn region rubySymbol				     start="%[s]<"				    end=">"   skip="\\\\\|\\>"	 fold	contains=rubyNestedAngleBrackets,rubyDelimEscape
+syn region rubySymbol				     start="%[s]\["				    end="\]"  skip="\\\\\|\\\]"	 fold	contains=rubyNestedSquareBrackets,rubyDelimEscape
+syn region rubySymbol				     start="%[s]("				    end=")"   skip="\\\\\|\\)"	 fold	contains=rubyNestedParentheses,rubyDelimEscape
+
+" Generalized Double Quoted String and Array of Strings and Shell Command Output
+" Note: %= is not matched here as the beginning of a double quoted string
+syn region rubyString matchgroup=rubyStringDelimiter start="%\z([~`!@#$%^&*_\-+|\:;"',.?/]\)"	    end="\z1" skip="\\\\\|\\\z1" contains=@rubyStringSpecial fold
+syn region rubyString matchgroup=rubyStringDelimiter start="%[QWx]\z([~`!@#$%^&*_\-+=|\:;"',.?/]\)" end="\z1" skip="\\\\\|\\\z1" contains=@rubyStringSpecial fold
+syn region rubyString matchgroup=rubyStringDelimiter start="%[QWx]\={"				    end="}"   skip="\\\\\|\\}"	 contains=@rubyStringSpecial,rubyNestedCurlyBraces,rubyDelimEscape fold
+syn region rubyString matchgroup=rubyStringDelimiter start="%[QWx]\=<"				    end=">"   skip="\\\\\|\\>"	 contains=@rubyStringSpecial,rubyNestedAngleBrackets,rubyDelimEscape fold
+syn region rubyString matchgroup=rubyStringDelimiter start="%[QWx]\=\["				    end="\]"  skip="\\\\\|\\\]"	 contains=@rubyStringSpecial,rubyNestedSquareBrackets,rubyDelimEscape fold
+syn region rubyString matchgroup=rubyStringDelimiter start="%[QWx]\=("				    end=")"   skip="\\\\\|\\)"	 contains=@rubyStringSpecial,rubyNestedParentheses,rubyDelimEscape fold
+
+" Here Document
+syn region rubyHeredocStart matchgroup=rubyStringDelimiter start=+\%(\%(class\s*\|\%([]})"'.]\|::\)\)\_s*\|\w\)\@<!<<-\=\zs\%(\h\w*\)+   end=+$+ oneline contains=TOP
+syn region rubyHeredocStart matchgroup=rubyStringDelimiter start=+\%(\%(class\s*\|\%([]})"'.]\|::\)\)\_s*\|\w\)\@<!<<-\=\zs"\%([^"]*\)"+ end=+$+ oneline contains=TOP
+syn region rubyHeredocStart matchgroup=rubyStringDelimiter start=+\%(\%(class\s*\|\%([]})"'.]\|::\)\)\_s*\|\w\)\@<!<<-\=\zs'\%([^']*\)'+ end=+$+ oneline contains=TOP
+syn region rubyHeredocStart matchgroup=rubyStringDelimiter start=+\%(\%(class\s*\|\%([]})"'.]\|::\)\)\_s*\|\w\)\@<!<<-\=\zs`\%([^`]*\)`+ end=+$+ oneline contains=TOP
+
+syn region rubyString start=+\%(\%(class\s*\|\%([]})"'.]\|::\)\)\_s*\|\w\)\@<!<<\z(\h\w*\)\ze+hs=s+2    matchgroup=rubyStringDelimiter end=+^\z1$+ contains=rubyHeredocStart,@rubyStringSpecial fold keepend
+syn region rubyString start=+\%(\%(class\s*\|\%([]})"'.]\|::\)\)\_s*\|\w\)\@<!<<"\z([^"]*\)"\ze+hs=s+2  matchgroup=rubyStringDelimiter end=+^\z1$+ contains=rubyHeredocStart,@rubyStringSpecial fold keepend
+syn region rubyString start=+\%(\%(class\s*\|\%([]})"'.]\|::\)\)\_s*\|\w\)\@<!<<'\z([^']*\)'\ze+hs=s+2  matchgroup=rubyStringDelimiter end=+^\z1$+ contains=rubyHeredocStart		      fold keepend
+syn region rubyString start=+\%(\%(class\s*\|\%([]})"'.]\|::\)\)\_s*\|\w\)\@<!<<`\z([^`]*\)`\ze+hs=s+2  matchgroup=rubyStringDelimiter end=+^\z1$+ contains=rubyHeredocStart,@rubyStringSpecial fold keepend
+
+syn region rubyString start=+\%(\%(class\s*\|\%([]}).]\|::\)\)\_s*\|\w\)\@<!<<-\z(\h\w*\)\ze+hs=s+3    matchgroup=rubyStringDelimiter end=+^\s*\zs\z1$+ contains=rubyHeredocStart,@rubyStringSpecial fold keepend
+syn region rubyString start=+\%(\%(class\s*\|\%([]}).]\|::\)\)\_s*\|\w\)\@<!<<-"\z([^"]*\)"\ze+hs=s+3  matchgroup=rubyStringDelimiter end=+^\s*\zs\z1$+ contains=rubyHeredocStart,@rubyStringSpecial fold keepend
+syn region rubyString start=+\%(\%(class\s*\|\%([]}).]\|::\)\)\_s*\|\w\)\@<!<<-'\z([^']*\)'\ze+hs=s+3  matchgroup=rubyStringDelimiter end=+^\s*\zs\z1$+ contains=rubyHeredocStart		     fold keepend
+syn region rubyString start=+\%(\%(class\s*\|\%([]}).]\|::\)\)\_s*\|\w\)\@<!<<-`\z([^`]*\)`\ze+hs=s+3  matchgroup=rubyStringDelimiter end=+^\s*\zs\z1$+ contains=rubyHeredocStart,@rubyStringSpecial fold keepend
+
+if exists('main_syntax') && main_syntax == 'eruby'
+  let b:ruby_no_expensive = 1
+end
+
+syn match  rubyAliasDeclaration    "[^[:space:];#.()]\+"  contained contains=rubySymbol,rubyGlobalVariable,rubyPredefinedVariable nextgroup=rubyAliasDeclaration2 skipwhite
+syn match  rubyAliasDeclaration2   "[^[:space:];#.()]\+"  contained contains=rubySymbol,rubyGlobalVariable,rubyPredefinedVariable
+syn match  rubyMethodDeclaration   "[^[:space:];#(]\+"	  contained contains=rubyConstant,rubyBoolean,rubyPseudoVariable,rubyInstanceVariable,rubyClassVariable,rubyGlobalVariable
+syn match  rubyClassDeclaration    "[^[:space:];#<]\+"	  contained contains=rubyConstant
+syn match  rubyModuleDeclaration   "[^[:space:];#]\+"	  contained contains=rubyConstant
+syn match  rubyFunction "\<[_[:alpha:]][_[:alnum:]]*[?!=]\=[[:alnum:].:?!=]\@!" contained containedin=rubyMethodDeclaration
+syn match  rubyFunction "\%(\s\|^\)\@<=[_[:alpha:]][_[:alnum:]]*[?!=]\=\%(\s\|$\)\@=" contained containedin=rubyAliasDeclaration,rubyAliasDeclaration2
+syn match  rubyFunction "\%([[:space:].]\|^\)\@<=\%(\[\]=\=\|\*\*\|[+-]@\=\|[*/%|&^~]\|<<\|>>\|[<>]=\=\|<=>\|===\|==\|=\~\|`\)\%([[:space:];#(]\|$\)\@=" contained containedin=rubyAliasDeclaration,rubyAliasDeclaration2,rubyMethodDeclaration
+
+" Expensive Mode - match 'end' with the appropriate opening keyword for syntax
+" based folding and special highlighting of module/class/method definitions
+if !exists("b:ruby_no_expensive") && !exists("ruby_no_expensive")
+  syn match  rubyDefine "\<alias\>"		nextgroup=rubyAliasDeclaration	skipwhite skipnl
+  syn match  rubyDefine "\<def\>"		nextgroup=rubyMethodDeclaration skipwhite skipnl
+  syn match  rubyClass	"\<class\>"		nextgroup=rubyClassDeclaration	skipwhite skipnl
+  syn match  rubyModule "\<module\>"		nextgroup=rubyModuleDeclaration skipwhite skipnl
+  syn region rubyBlock start="\<def\>"		matchgroup=rubyDefine end="\%(\<def\_s\+\)\@<!\<end\>" contains=TOP fold
+  syn region rubyBlock start="\<class\>"	matchgroup=rubyClass  end="\<end\>" contains=TOP fold
+  syn region rubyBlock start="\<module\>"	matchgroup=rubyModule end="\<end\>" contains=TOP fold
+
+  " modifiers
+  syn match  rubyConditionalModifier "\<\%(if\|unless\)\>"   display
+  syn match  rubyRepeatModifier	     "\<\%(while\|until\)\>" display
+
+  syn region rubyDoBlock matchgroup=rubyControl start="\<do\>" end="\<end\>" contains=TOP fold
+  " curly bracket block or hash literal
+  syn region rubyCurlyBlock   start="{" end="}" contains=TOP fold
+  syn region rubyArrayLiteral matchgroup=rubyArrayDelimiter start="\%(\w\|[\]})]\)\@<!\[" end="]" contains=TOP fold
+
+  " statements without 'do'
+  syn region rubyBlockExpression       matchgroup=rubyControl	  start="\<begin\>" end="\<end\>" contains=TOP fold
+  syn region rubyCaseExpression	       matchgroup=rubyConditional start="\<case\>"  end="\<end\>" contains=TOP fold
+  syn region rubyConditionalExpression matchgroup=rubyConditional start="\%(\%(^\|\.\.\.\=\|[{:,;([<>~\*/%&^|+=-]\|\%(\<[_[:lower:]][_[:alnum:]]*\)\@<![!?]\)\s*\)\@<=\%(if\|unless\)\>" end="\<end\>" contains=TOP fold
+
+  syn keyword rubyConditional then else when  contained containedin=rubyCaseExpression
+  syn keyword rubyConditional then else elsif contained containedin=rubyConditionalExpression
+
+  " statements with optional 'do'
+  syn region rubyOptionalDoLine   matchgroup=rubyRepeat start="\<for\>" start="\%(\%(^\|\.\.\.\=\|[{:,;([<>~\*/%&^|+-]\|\%(\<[_[:lower:]][_[:alnum:]]*\)\@<![!=?]\)\s*\)\@<=\<\%(until\|while\)\>" matchgroup=rubyOptionalDo end="\%(\<do\>\)" end="\ze\%(;\|$\)" oneline contains=TOP
+  syn region rubyRepeatExpression start="\<for\>" start="\%(\%(^\|\.\.\.\=\|[{:,;([<>~\*/%&^|+-]\|\%(\<[_[:lower:]][_[:alnum:]]*\)\@<![!=?]\)\s*\)\@<=\<\%(until\|while\)\>" matchgroup=rubyRepeat end="\<end\>" contains=TOP nextgroup=rubyOptionalDoLine fold
+
+  if !exists("ruby_minlines")
+    let ruby_minlines = 50
+  endif
+  exec "syn sync minlines=" . ruby_minlines
+
+else
+  syn match   rubyControl "\<def\>"	nextgroup=rubyMethodDeclaration skipwhite skipnl
+  syn match   rubyControl "\<class\>"	nextgroup=rubyClassDeclaration	skipwhite skipnl
+  syn match   rubyControl "\<module\>"	nextgroup=rubyModuleDeclaration skipwhite skipnl
+  syn keyword rubyControl case begin do for if unless while until else elsif then when end
+  syn keyword rubyKeyword alias
+endif
+
+" Keywords
+" Note: the following keywords have already been defined:
+" begin case class def do end for if module unless until while
+syn keyword rubyControl		and break ensure in next not or redo rescue retry return
+syn match   rubyOperator	"\<defined?" display
+syn keyword rubyKeyword		super undef yield
+syn keyword rubyBoolean		true false
+syn keyword rubyPseudoVariable	nil self __FILE__ __LINE__
+syn keyword rubyBeginEnd	BEGIN END
+
+" Special Methods
+if !exists("ruby_no_special_methods")
+  syn keyword rubyAccess    public protected private
+  syn keyword rubyAttribute attr attr_accessor attr_reader attr_writer
+  syn match   rubyControl   "\<\%(exit!\|\%(abort\|at_exit\|exit\|fork\|loop\|trap\)\>\)"
+  syn keyword rubyEval	    eval class_eval instance_eval module_eval
+  syn keyword rubyException raise fail catch throw
+  syn keyword rubyInclude   autoload extend include load require
+  syn keyword rubyKeyword   callcc caller lambda proc
+endif
+
+" Comments and Documentation
+syn match   rubySharpBang     "\%^#!.*" display
+syn keyword rubyTodo	      FIXME NOTE TODO OPTIMIZE XXX contained
+syn match   rubyComment       "#.*" contains=rubySharpBang,rubySpaceError,rubyTodo,@Spell
+if !exists("ruby_no_comment_fold")
+  syn region rubyMultilineComment start="\%(\%(^\s*#.*\n\)\@<!\%(^\s*#.*\n\)\)\%(\(^\s*#.*\n\)\{1,}\)\@=" end="\%(^\s*#.*\n\)\@<=\%(^\s*#.*\n\)\%(^\s*#\)\@!" contains=rubyComment transparent fold keepend
+  syn region rubyDocumentation	  start="^=begin\ze\%(\s.*\)\=$" end="^=end\s*$" contains=rubySpaceError,rubyTodo,@Spell fold
+else
+  syn region rubyDocumentation	  start="^=begin\s*$" end="^=end\s*$" contains=rubySpaceError,rubyTodo,@Spell
+endif
+
+" Note: this is a hack to prevent 'keywords' being highlighted as such when called as methods with an explicit receiver
+syn match rubyKeywordAsMethod "\%(\%(\.\@<!\.\)\|::\)\_s*\%(alias\|and\|begin\|break\|case\|class\|def\|defined\|do\|else\)\>"			transparent contains=NONE
+syn match rubyKeywordAsMethod "\%(\%(\.\@<!\.\)\|::\)\_s*\%(elsif\|end\|ensure\|false\|for\|if\|in\|module\|next\|nil\)\>"			transparent contains=NONE
+syn match rubyKeywordAsMethod "\%(\%(\.\@<!\.\)\|::\)\_s*\%(not\|or\|redo\|rescue\|retry\|return\|self\|super\|then\|true\)\>"			transparent contains=NONE
+syn match rubyKeywordAsMethod "\%(\%(\.\@<!\.\)\|::\)\_s*\%(undef\|unless\|until\|when\|while\|yield\|BEGIN\|END\|__FILE__\|__LINE__\)\>"	transparent contains=NONE
+
+syn match rubyKeywordAsMethod "\%(\%(\.\@<!\.\)\|::\)\_s*\%(abort\|at_exit\|attr\|attr_accessor\|attr_reader\)\>"	transparent contains=NONE
+syn match rubyKeywordAsMethod "\%(\%(\.\@<!\.\)\|::\)\_s*\%(attr_writer\|autoload\|callcc\|catch\|caller\)\>"		transparent contains=NONE
+syn match rubyKeywordAsMethod "\%(\%(\.\@<!\.\)\|::\)\_s*\%(eval\|class_eval\|instance_eval\|module_eval\|exit\)\>"	transparent contains=NONE
+syn match rubyKeywordAsMethod "\%(\%(\.\@<!\.\)\|::\)\_s*\%(extend\|fail\|fork\|include\|lambda\)\>"			transparent contains=NONE
+syn match rubyKeywordAsMethod "\%(\%(\.\@<!\.\)\|::\)\_s*\%(load\|loop\|private\|proc\|protected\)\>"			transparent contains=NONE
+syn match rubyKeywordAsMethod "\%(\%(\.\@<!\.\)\|::\)\_s*\%(public\|require\|raise\|throw\|trap\)\>"			transparent contains=NONE
+
+" __END__ Directive
+syn region rubyData matchgroup=rubyDataDirective start="^__END__$" end="\%$" fold
+
+hi def link rubyClass			rubyDefine
+hi def link rubyModule			rubyDefine
+hi def link rubyDefine			Define
+hi def link rubyFunction		Function
+hi def link rubyConditional		Conditional
+hi def link rubyConditionalModifier	rubyConditional
+hi def link rubyRepeat			Repeat
+hi def link rubyRepeatModifier		rubyRepeat
+hi def link rubyOptionalDo		rubyRepeat
+hi def link rubyControl			Statement
+hi def link rubyInclude			Include
+hi def link rubyInteger			Number
+hi def link rubyASCIICode		Character
+hi def link rubyFloat			Float
+hi def link rubyBoolean			Boolean
+hi def link rubyException		Exception
+if !exists("ruby_no_identifiers")
+  hi def link rubyIdentifier		Identifier
+else
+  hi def link rubyIdentifier		NONE
+endif
+hi def link rubyClassVariable		rubyIdentifier
+hi def link rubyConstant		Type
+hi def link rubyGlobalVariable		rubyIdentifier
+hi def link rubyBlockParameter		rubyIdentifier
+hi def link rubyInstanceVariable	rubyIdentifier
+hi def link rubyPredefinedIdentifier	rubyIdentifier
+hi def link rubyPredefinedConstant	rubyPredefinedIdentifier
+hi def link rubyPredefinedVariable	rubyPredefinedIdentifier
+hi def link rubySymbol			Constant
+hi def link rubyKeyword			Keyword
+hi def link rubyOperator		Operator
+hi def link rubyPseudoOperator		rubyOperator
+hi def link rubyBeginEnd		Statement
+hi def link rubyAccess			Statement
+hi def link rubyAttribute		Statement
+hi def link rubyEval			Statement
+hi def link rubyPseudoVariable		Constant
+
+hi def link rubyComment			Comment
+hi def link rubyData			Comment
+hi def link rubyDataDirective		Delimiter
+hi def link rubyDocumentation		Comment
+hi def link rubyEscape			Special
+hi def link rubyInterpolationDelimiter	Delimiter
+hi def link rubyNoInterpolation		rubyString
+hi def link rubySharpBang		PreProc
+hi def link rubyRegexpDelimiter		rubyStringDelimiter
+hi def link rubyStringDelimiter		Delimiter
+hi def link rubyRegexp			rubyString
+hi def link rubyString			String
+hi def link rubyTodo			Todo
+
+hi def link rubyInvalidVariable		Error
+hi def link rubyError			Error
+hi def link rubySpaceError		rubyError
+
+let b:current_syntax = "ruby"
+
+" vim: nowrap sw=2 sts=2 ts=8 noet ff=unix:
--- /dev/null
+++ b/lib/vimfiles/syntax/samba.vim
@@ -1,0 +1,129 @@
+" Vim syntax file
+" Language:	samba configuration files (smb.conf)
+" Maintainer:	Rafael Garcia-Suarez <rgarciasuarez@free.fr>
+" URL:		http://rgarciasuarez.free.fr/vim/syntax/samba.vim
+" Last change:	2004 September 21
+
+" Don't forget to run your config file through testparm(1)!
+
+" For version 5.x: Clear all syntax items
+" For version 6.x: Quit when a syntax file was already loaded
+if version < 600
+  syntax clear
+elseif exists("b:current_syntax")
+  finish
+endif
+
+syn case ignore
+
+syn match sambaParameter /^[a-zA-Z \t]\+=/ contains=sambaKeyword
+syn match sambaSection /^\s*\[[a-zA-Z0-9_\-.$ ]\+\]/
+syn match sambaMacro /%[SPugUGHvhmLMNpRdaITD]/
+syn match sambaMacro /%$([a-zA-Z0-9_]\+)/
+syn match sambaComment /^\s*[;#].*/
+syn match sambaContinue /\\$/
+syn keyword sambaBoolean true false yes no
+
+" Keywords for Samba 2.0.5a
+syn keyword sambaKeyword contained account acl action add address admin aliases
+syn keyword sambaKeyword contained allow alternate always announce anonymous
+syn keyword sambaKeyword contained archive as auto available bind blocking
+syn keyword sambaKeyword contained bmpx break browsable browse browseable ca
+syn keyword sambaKeyword contained cache case casesignames cert certDir
+syn keyword sambaKeyword contained certFile change char character chars chat
+syn keyword sambaKeyword contained ciphers client clientcert code coding
+syn keyword sambaKeyword contained command comment compatibility config
+syn keyword sambaKeyword contained connections contention controller copy
+syn keyword sambaKeyword contained create deadtime debug debuglevel default
+syn keyword sambaKeyword contained delete deny descend dfree dir directory
+syn keyword sambaKeyword contained disk dns domain domains dont dos dot drive
+syn keyword sambaKeyword contained driver encrypt encrypted equiv exec fake
+syn keyword sambaKeyword contained file files filetime filetimes filter follow
+syn keyword sambaKeyword contained force fstype getwd group groups guest
+syn keyword sambaKeyword contained hidden hide home homedir hosts include
+syn keyword sambaKeyword contained interfaces interval invalid keepalive
+syn keyword sambaKeyword contained kernel key ldap length level level2 limit
+syn keyword sambaKeyword contained links list lm load local location lock
+syn keyword sambaKeyword contained locking locks log logon logons logs lppause
+syn keyword sambaKeyword contained lpq lpresume lprm machine magic mangle
+syn keyword sambaKeyword contained mangled mangling map mask master max mem
+syn keyword sambaKeyword contained message min mode modes mux name names
+syn keyword sambaKeyword contained netbios nis notify nt null offset ok ole
+syn keyword sambaKeyword contained only open oplock oplocks options order os
+syn keyword sambaKeyword contained output packet page panic passwd password
+syn keyword sambaKeyword contained passwords path permissions pipe port
+syn keyword sambaKeyword contained postexec postscript prediction preexec
+syn keyword sambaKeyword contained prefered preferred preload preserve print
+syn keyword sambaKeyword contained printable printcap printer printers
+syn keyword sambaKeyword contained printing program protocol proxy public
+syn keyword sambaKeyword contained queuepause queueresume raw read readonly
+syn keyword sambaKeyword contained realname remote require resign resolution
+syn keyword sambaKeyword contained resolve restrict revalidate rhosts root
+syn keyword sambaKeyword contained script security sensitive server servercert
+syn keyword sambaKeyword contained service services set share shared short
+syn keyword sambaKeyword contained size smb smbrun socket space ssl stack stat
+syn keyword sambaKeyword contained status strict string strip suffix support
+syn keyword sambaKeyword contained symlinks sync syslog system time timeout
+syn keyword sambaKeyword contained times timestamp to trusted ttl unix update
+syn keyword sambaKeyword contained use user username users valid version veto
+syn keyword sambaKeyword contained volume wait wide wins workgroup writable
+syn keyword sambaKeyword contained write writeable xmit
+
+" New keywords for Samba 2.0.6
+syn keyword sambaKeyword contained hook hires pid uid close rootpreexec
+
+" New keywords for Samba 2.0.7
+syn keyword sambaKeyword contained utmp wtmp hostname consolidate
+syn keyword sambaKeyword contained inherit source environment
+
+" New keywords for Samba 2.2.0
+syn keyword sambaKeyword contained addprinter auth browsing deleteprinter
+syn keyword sambaKeyword contained enhanced enumports filemode gid host jobs
+syn keyword sambaKeyword contained lanman msdfs object os2 posix processes
+syn keyword sambaKeyword contained scope separator shell show smbd template
+syn keyword sambaKeyword contained total vfs winbind wizard
+
+" New keywords for Samba 2.2.1
+syn keyword sambaKeyword contained large obey pam readwrite restrictions
+syn keyword sambaKeyword contained unreadable
+
+" New keywords for Samba 2.2.2 - 2.2.4
+syn keyword sambaKeyword contained acls allocate bytes count csc devmode
+syn keyword sambaKeyword contained disable dn egd entropy enum extensions mmap
+syn keyword sambaKeyword contained policy spin spoolss
+
+" Since Samba 3.0.2
+syn keyword sambaKeyword contained abort afs algorithmic backend
+syn keyword sambaKeyword contained charset cups defer display
+syn keyword sambaKeyword contained enable idmap kerberos lookups
+syn keyword sambaKeyword contained methods modules nested NIS ntlm NTLMv2
+syn keyword sambaKeyword contained objects paranoid partners passdb
+syn keyword sambaKeyword contained plaintext prefix primary private
+syn keyword sambaKeyword contained profile quota realm replication
+syn keyword sambaKeyword contained reported rid schannel sendfile sharing
+syn keyword sambaKeyword contained shutdown signing special spnego
+syn keyword sambaKeyword contained store unknown unwriteable
+
+" Define the default highlighting.
+" For version 5.7 and earlier: only when not done already
+" For version 5.8 and later: only when an item doesn't have highlighting yet
+if version >= 508 || !exists("did_samba_syn_inits")
+  if version < 508
+    let did_samba_syn_inits = 1
+    command -nargs=+ HiLink hi link <args>
+  else
+    command -nargs=+ HiLink hi def link <args>
+  endif
+  HiLink sambaParameter Normal
+  HiLink sambaKeyword   Type
+  HiLink sambaSection   Statement
+  HiLink sambaMacro     PreProc
+  HiLink sambaComment   Comment
+  HiLink sambaContinue  Operator
+  HiLink sambaBoolean   Constant
+  delcommand HiLink
+endif
+
+let b:current_syntax = "samba"
+
+" vim: ts=8
--- /dev/null
+++ b/lib/vimfiles/syntax/sas.vim
@@ -1,0 +1,236 @@
+" Vim syntax file
+" Language:	SAS
+" Maintainer:	James Kidd <james.kidd@covance.com>
+" Last Change:	02 Jun 2003
+"		Added highlighting for additional keywords and such;
+"		Attempted to match SAS default syntax colors;
+"		Changed syncing so it doesn't lose colors on large blocks;
+"		Much thanks to Bob Heckel for knowledgeable tweaking.
+"  For version 5.x: Clear all syntax items
+"  For version 6.x: Quit when a syntax file was already loaded
+if version < 600
+   syntax clear
+elseif exists("b:current_syntax")
+   finish
+endif
+
+syn case ignore
+
+syn region sasString	start=+"+  skip=+\\\\\|\\"+  end=+"+
+syn region sasString	start=+'+  skip=+\\\\\|\\"+  end=+'+
+
+" Want region from 'cards;' to ';' to be captured (Bob Heckel)
+syn region sasCards	start="^\s*CARDS.*" end="^\s*;\s*$"
+syn region sasCards	start="^\s*DATALINES.*" end="^\s*;\s*$"
+
+syn match sasNumber	"-\=\<\d*\.\=[0-9_]\>"
+
+syn region sasComment	start="/\*"  end="\*/" contains=sasTodo
+" Ignore misleading //JCL SYNTAX... (Bob Heckel)
+syn region sasComment	start="[^/][^/]/\*"  end="\*/" contains=sasTodo
+
+" Allow highlighting of embedded TODOs (Bob Heckel)
+syn match sasComment	"^\s*\*.*;" contains=sasTodo
+
+" Allow highlighting of embedded TODOs (Bob Heckel)
+syn match sasComment	";\s*\*.*;"hs=s+1 contains=sasTodo
+
+" Handle macro comments too (Bob Heckel).
+syn match sasComment	"^\s*%*\*.*;" contains=sasTodo
+
+" This line defines macro variables in code.  HiLink at end of file
+" defines the color scheme. Begin region with ampersand and end with
+" any non-word character offset by -1; put ampersand in the skip list
+" just in case it is used to concatenate macro variable values.
+
+" Thanks to ronald h�llwarth for this fix to an intra-versioning
+" problem with this little feature
+
+if version < 600
+   syn region sasMacroVar	start="\&" skip="[_&]" end="\W"he=e-1
+else		 " for the older Vim's just do it their way ...
+   syn region sasMacroVar	start="&" skip="[_&]" end="\W"he=e-1
+endif
+
+
+" I dont think specific PROCs need to be listed if use this line (Bob Heckel).
+syn match sasProc		"^\s*PROC \w\+"
+syn keyword sasStep		RUN QUIT DATA
+
+
+" Base SAS Procs - version 8.1
+
+syn keyword sasConditional	DO ELSE END IF THEN UNTIL WHILE
+
+syn keyword sasStatement	ABORT ARRAY ATTRIB BY CALL CARDS CARDS4 CATNAME
+syn keyword sasStatement	CONTINUE DATALINES DATALINES4 DELETE DISPLAY
+syn keyword sasStatement	DM DROP ENDSAS ERROR FILE FILENAME FOOTNOTE
+syn keyword sasStatement	FORMAT GOTO INFILE INFORMAT INPUT KEEP
+syn keyword sasStatement	LABEL LEAVE LENGTH LIBNAME LINK LIST LOSTCARD
+syn keyword sasStatement	MERGE MISSING MODIFY OPTIONS OUTPUT PAGE
+syn keyword sasStatement	PUT REDIRECT REMOVE RENAME REPLACE RETAIN
+syn keyword sasStatement	RETURN SELECT SET SKIP STARTSAS STOP TITLE
+syn keyword sasStatement	UPDATE WAITSAS WHERE WINDOW X SYSTASK
+
+" Keywords that are used in Proc SQL
+" I left them as statements because SAS's enhanced editor highlights
+" them the same as normal statements used in data steps (Jim Kidd)
+
+syn keyword sasStatement	ADD AND ALTER AS CASCADE CHECK CREATE
+syn keyword sasStatement	DELETE DESCRIBE DISTINCT DROP FOREIGN
+syn keyword sasStatement	FROM GROUP HAVING INDEX INSERT INTO IN
+syn keyword sasStatement	KEY LIKE MESSAGE MODIFY MSGTYPE NOT
+syn keyword sasStatement	NULL ON OR ORDER PRIMARY REFERENCES
+syn keyword sasStatement	RESET RESTRICT SELECT SET TABLE
+syn keyword sasStatement	UNIQUE UPDATE VALIDATE VIEW WHERE
+
+
+syn match sasStatement	"FOOTNOTE\d" "TITLE\d"
+
+syn match sasMacro	"%BQUOTE" "%NRBQUOTE" "%CMPRES" "%QCMPRES"
+syn match sasMacro	"%COMPSTOR" "%DATATYP" "%DISPLAY" "%DO"
+syn match sasMacro	"%ELSE" "%END" "%EVAL" "%GLOBAL"
+syn match sasMacro	"%GOTO" "%IF" "%INDEX" "%INPUT"
+syn match sasMacro	"%KEYDEF" "%LABEL" "%LEFT" "%LENGTH"
+syn match sasMacro	"%LET" "%LOCAL" "%LOWCASE" "%MACRO"
+syn match sasMacro	"%MEND" "%NRBQUOTE" "%NRQUOTE" "%NRSTR"
+syn match sasMacro	"%PUT" "%QCMPRES" "%QLEFT" "%QLOWCASE"
+syn match sasMacro	"%QSCAN" "%QSUBSTR" "%QSYSFUNC" "%QTRIM"
+syn match sasMacro	"%QUOTE" "%QUPCASE" "%SCAN" "%STR"
+syn match sasMacro	"%SUBSTR" "%SUPERQ" "%SYSCALL" "%SYSEVALF"
+syn match sasMacro	"%SYSEXEC" "%SYSFUNC" "%SYSGET" "%SYSLPUT"
+syn match sasMacro	"%SYSPROD" "%SYSRC" "%SYSRPUT" "%THEN"
+syn match sasMacro	"%TO" "%TRIM" "%UNQUOTE" "%UNTIL"
+syn match sasMacro	"%UPCASE" "%VERIFY" "%WHILE" "%WINDOW"
+
+" SAS Functions
+
+syn keyword sasFunction	ABS ADDR AIRY ARCOS ARSIN ATAN ATTRC ATTRN
+syn keyword sasFunction	BAND BETAINV BLSHIFT BNOT BOR BRSHIFT BXOR
+syn keyword sasFunction	BYTE CDF CEIL CEXIST CINV CLOSE CNONCT COLLATE
+syn keyword sasFunction	COMPBL COMPOUND COMPRESS COS COSH CSS CUROBS
+syn keyword sasFunction	CV DACCDB DACCDBSL DACCSL DACCSYD DACCTAB
+syn keyword sasFunction	DAIRY DATE DATEJUL DATEPART DATETIME DAY
+syn keyword sasFunction	DCLOSE DEPDB DEPDBSL DEPDBSL DEPSL DEPSL
+syn keyword sasFunction	DEPSYD DEPSYD DEPTAB DEPTAB DEQUOTE DHMS
+syn keyword sasFunction	DIF DIGAMMA DIM DINFO DNUM DOPEN DOPTNAME
+syn keyword sasFunction	DOPTNUM DREAD DROPNOTE DSNAME ERF ERFC EXIST
+syn keyword sasFunction	EXP FAPPEND FCLOSE FCOL FDELETE FETCH FETCHOBS
+syn keyword sasFunction	FEXIST FGET FILEEXIST FILENAME FILEREF FINFO
+syn keyword sasFunction	FINV FIPNAME FIPNAMEL FIPSTATE FLOOR FNONCT
+syn keyword sasFunction	FNOTE FOPEN FOPTNAME FOPTNUM FPOINT FPOS
+syn keyword sasFunction	FPUT FREAD FREWIND FRLEN FSEP FUZZ FWRITE
+syn keyword sasFunction	GAMINV GAMMA GETOPTION GETVARC GETVARN HBOUND
+syn keyword sasFunction	HMS HOSTHELP HOUR IBESSEL INDEX INDEXC
+syn keyword sasFunction	INDEXW INPUT INPUTC INPUTN INT INTCK INTNX
+syn keyword sasFunction	INTRR IRR JBESSEL JULDATE KURTOSIS LAG LBOUND
+syn keyword sasFunction	LEFT LENGTH LGAMMA LIBNAME LIBREF LOG LOG10
+syn keyword sasFunction	LOG2 LOGPDF LOGPMF LOGSDF LOWCASE MAX MDY
+syn keyword sasFunction	MEAN MIN MINUTE MOD MONTH MOPEN MORT N
+syn keyword sasFunction	NETPV NMISS NORMAL NOTE NPV OPEN ORDINAL
+syn keyword sasFunction	PATHNAME PDF PEEK PEEKC PMF POINT POISSON POKE
+syn keyword sasFunction	PROBBETA PROBBNML PROBCHI PROBF PROBGAM
+syn keyword sasFunction	PROBHYPR PROBIT PROBNEGB PROBNORM PROBT PUT
+syn keyword sasFunction	PUTC PUTN QTR QUOTE RANBIN RANCAU RANEXP
+syn keyword sasFunction	RANGAM RANGE RANK RANNOR RANPOI RANTBL RANTRI
+syn keyword sasFunction	RANUNI REPEAT RESOLVE REVERSE REWIND RIGHT
+syn keyword sasFunction	ROUND SAVING SCAN SDF SECOND SIGN SIN SINH
+syn keyword sasFunction	SKEWNESS SOUNDEX SPEDIS SQRT STD STDERR STFIPS
+syn keyword sasFunction	STNAME STNAMEL SUBSTR SUM SYMGET SYSGET SYSMSG
+syn keyword sasFunction	SYSPROD SYSRC SYSTEM TAN TANH TIME TIMEPART
+syn keyword sasFunction	TINV TNONCT TODAY TRANSLATE TRANWRD TRIGAMMA
+syn keyword sasFunction	TRIM TRIMN TRUNC UNIFORM UPCASE USS VAR
+syn keyword sasFunction	VARFMT VARINFMT VARLABEL VARLEN VARNAME
+syn keyword sasFunction	VARNUM VARRAY VARRAYX VARTYPE VERIFY VFORMAT
+syn keyword sasFunction	VFORMATD VFORMATDX VFORMATN VFORMATNX VFORMATW
+syn keyword sasFunction	VFORMATWX VFORMATX VINARRAY VINARRAYX VINFORMAT
+syn keyword sasFunction	VINFORMATD VINFORMATDX VINFORMATN VINFORMATNX
+syn keyword sasFunction	VINFORMATW VINFORMATWX VINFORMATX VLABEL
+syn keyword sasFunction	VLABELX VLENGTH VLENGTHX VNAME VNAMEX VTYPE
+syn keyword sasFunction	VTYPEX WEEKDAY YEAR YYQ ZIPFIPS ZIPNAME ZIPNAMEL
+syn keyword sasFunction	ZIPSTATE
+
+" Handy settings for using vim with log files
+syn keyword sasLogMsg	NOTE
+syn keyword sasWarnMsg	WARNING
+syn keyword sasErrMsg	ERROR
+
+" Always contained in a comment (Bob Heckel)
+syn keyword sasTodo	TODO TBD FIXME contained
+
+" These don't fit anywhere else (Bob Heckel).
+syn match sasUnderscore	"_NULL_"
+syn match sasUnderscore	"_INFILE_"
+syn match sasUnderscore	"_N_"
+syn match sasUnderscore	"_WEBOUT_"
+syn match sasUnderscore	"_NUMERIC_"
+syn match sasUnderscore	"_CHARACTER_"
+syn match sasUnderscore	"_ALL_"
+
+" End of SAS Functions
+
+"  Define the default highlighting.
+"  For version 5.7 and earlier: only when not done already
+"  For version 5.8 and later: only when an item doesn't have highlighting yet
+
+if version >= 508 || !exists("did_sas_syntax_inits")
+   if version < 508
+      let did_sas_syntax_inits = 1
+      command -nargs=+ HiLink hi link <args>
+   else
+      command -nargs=+ HiLink hi def link <args>
+   endif
+
+   " Default sas enhanced editor color syntax
+	hi sComment	term=bold cterm=NONE ctermfg=Green ctermbg=Black gui=NONE guifg=DarkGreen guibg=White
+	hi sCard	term=bold cterm=NONE ctermfg=Black ctermbg=Yellow gui=NONE guifg=Black guibg=LightYellow
+	hi sDate_Time	term=NONE cterm=bold ctermfg=Green ctermbg=Black gui=bold guifg=SeaGreen guibg=White
+	hi sKeyword	term=NONE cterm=NONE ctermfg=Blue  ctermbg=Black gui=NONE guifg=Blue guibg=White
+	hi sFmtInfmt	term=NONE cterm=NONE ctermfg=LightGreen ctermbg=Black gui=NONE guifg=SeaGreen guibg=White
+	hi sString	term=NONE cterm=NONE ctermfg=Magenta ctermbg=Black gui=NONE guifg=Purple guibg=White
+	hi sText	term=NONE cterm=NONE ctermfg=White ctermbg=Black gui=bold guifg=Black guibg=White
+	hi sNumber	term=NONE cterm=bold ctermfg=Green ctermbg=Black gui=bold guifg=SeaGreen guibg=White
+	hi sProc	term=NONE cterm=bold ctermfg=Blue ctermbg=Black gui=bold guifg=Navy guibg=White
+	hi sSection	term=NONE cterm=bold ctermfg=Blue ctermbg=Black gui=bold guifg=Navy guibg=White
+	hi mDefine	term=NONE cterm=bold ctermfg=White ctermbg=Black gui=bold guifg=Black guibg=White
+	hi mKeyword	term=NONE cterm=NONE ctermfg=Blue ctermbg=Black gui=NONE guifg=Blue guibg=White
+	hi mReference	term=NONE cterm=bold ctermfg=White ctermbg=Black gui=bold guifg=Blue guibg=White
+	hi mSection	term=NONE cterm=NONE ctermfg=Blue ctermbg=Black gui=bold guifg=Navy guibg=White
+	hi mText	term=NONE cterm=NONE ctermfg=White ctermbg=Black gui=bold guifg=Black guibg=White
+
+" Colors that closely match SAS log colors for default color scheme
+	hi lError	term=NONE cterm=NONE ctermfg=Red ctermbg=Black gui=none guifg=Red guibg=White
+	hi lWarning	term=NONE cterm=NONE ctermfg=Green ctermbg=Black gui=none guifg=Green guibg=White
+	hi lNote	term=NONE cterm=NONE ctermfg=Cyan ctermbg=Black gui=none guifg=Blue guibg=White
+
+
+   " Special hilighting for the SAS proc section
+
+	HiLink	sasComment	sComment
+	HiLink	sasConditional	sKeyword
+	HiLink	sasStep		sSection
+	HiLink	sasFunction	sKeyword
+	HiLink	sasMacro	mKeyword
+	HiLink	sasMacroVar	NonText
+	HiLink	sasNumber	sNumber
+	HiLink	sasStatement	sKeyword
+	HiLink	sasString	sString
+	HiLink	sasProc		sProc
+   " (Bob Heckel)
+	HiLink	sasTodo		Todo
+	HiLink	sasErrMsg	lError
+	HiLink	sasWarnMsg	lWarning
+	HiLink	sasLogMsg	lNote
+	HiLink	sasCards	sCard
+  " (Bob Heckel)
+	HiLink	sasUnderscore	PreProc
+	delcommand HiLink
+endif
+
+" Syncronize from beginning to keep large blocks from losing
+" syntax coloring while moving through code.
+syn sync fromstart
+
+let b:current_syntax = "sas"
+
+" vim: ts=8
--- /dev/null
+++ b/lib/vimfiles/syntax/sather.vim
@@ -1,0 +1,105 @@
+" Vim syntax file
+" Language:	Sather/pSather
+" Maintainer:	Claudio Fleiner <claudio@fleiner.com>
+" URL:		http://www.fleiner.com/vim/syntax/sather.vim
+" Last Change:	2003 May 11
+
+" Sather is a OO-language developped at the International Computer Science
+" Institute (ICSI) in Berkeley, CA. pSather is a parallel extension to Sather.
+" Homepage: http://www.icsi.berkeley.edu/~sather
+" Sather files use .sa as suffix
+
+" For version 5.x: Clear all syntax items
+" For version 6.x: Quit when a syntax file was already loaded
+if version < 600
+  syntax clear
+elseif exists("b:current_syntax")
+  finish
+endif
+
+" keyword definitions
+syn keyword satherExternal	 extern
+syn keyword satherBranch	 break continue
+syn keyword satherLabel		 when then
+syn keyword satherConditional	 if else elsif end case typecase assert with
+syn match satherConditional	 "near$"
+syn match satherConditional	 "far$"
+syn match satherConditional	 "near *[^(]"he=e-1
+syn match satherConditional	 "far *[^(]"he=e-1
+syn keyword satherSynchronize	 lock guard sync
+syn keyword satherRepeat	 loop parloop do
+syn match satherRepeat		 "while!"
+syn match satherRepeat		 "break!"
+syn match satherRepeat		 "until!"
+syn keyword satherBoolValue	 true false
+syn keyword satherValue		 self here cluster
+syn keyword satherOperator	 new "== != & ^ | && ||
+syn keyword satherOperator	 and or not
+syn match satherOperator	 "[#!]"
+syn match satherOperator	 ":-"
+syn keyword satherType		 void attr where
+syn match satherType	       "near *("he=e-1
+syn match satherType	       "far *("he=e-1
+syn keyword satherStatement	 return
+syn keyword satherStorageClass	 static const
+syn keyword satherExceptions	 try raise catch
+syn keyword satherMethodDecl	 is pre post
+syn keyword satherClassDecl	 abstract value class include
+syn keyword satherScopeDecl	 public private readonly
+
+
+syn match   satherSpecial	    contained "\\\d\d\d\|\\."
+syn region  satherString	    start=+"+  skip=+\\\\\|\\"+  end=+"+  contains=satherSpecial
+syn match   satherCharacter	    "'[^\\]'"
+syn match   satherSpecialCharacter  "'\\.'"
+syn match   satherNumber	  "-\=\<\d\+L\=\>\|0[xX][0-9a-fA-F]\+\>"
+syn match   satherCommentSkip	  contained "^\s*\*\($\|\s\+\)"
+syn region  satherComment2String  contained start=+"+  skip=+\\\\\|\\"+  end=+$\|"+  contains=satherSpecial
+syn match   satherComment	  "--.*" contains=satherComment2String,satherCharacter,satherNumber
+
+
+syn sync ccomment satherComment
+
+" Define the default highlighting.
+" For version 5.7 and earlier: only when not done already
+" For version 5.8 and later: only when an item doesn't have highlighting yet
+if version >= 508 || !exists("did_sather_syn_inits")
+  if version < 508
+    let did_sather_syn_inits = 1
+    command -nargs=+ HiLink hi link <args>
+  else
+    command -nargs=+ HiLink hi def link <args>
+  endif
+
+  HiLink satherBranch		satherStatement
+  HiLink satherLabel		satherStatement
+  HiLink satherConditional	satherStatement
+  HiLink satherSynchronize	satherStatement
+  HiLink satherRepeat		satherStatement
+  HiLink satherExceptions	satherStatement
+  HiLink satherStorageClass	satherDeclarative
+  HiLink satherMethodDecl	satherDeclarative
+  HiLink satherClassDecl	satherDeclarative
+  HiLink satherScopeDecl	satherDeclarative
+  HiLink satherBoolValue	satherValue
+  HiLink satherSpecial		satherValue
+  HiLink satherString		satherValue
+  HiLink satherCharacter	satherValue
+  HiLink satherSpecialCharacter satherValue
+  HiLink satherNumber		satherValue
+  HiLink satherStatement	Statement
+  HiLink satherOperator		Statement
+  HiLink satherComment		Comment
+  HiLink satherType		Type
+  HiLink satherValue		String
+  HiLink satherString		String
+  HiLink satherSpecial		String
+  HiLink satherCharacter	String
+  HiLink satherDeclarative	Type
+  HiLink satherExternal		PreCondit
+  delcommand HiLink
+endif
+
+let b:current_syntax = "sather"
+
+" vim: ts=8
--- /dev/null
+++ b/lib/vimfiles/syntax/scheme.vim
@@ -1,0 +1,306 @@
+" Vim syntax file
+" Language:	Scheme (R5RS)
+" Last Change:	Nov 28, 2004
+" Maintainer:	Sergey Khorev <sergey.khorev@gmail.com>
+" Original author:	Dirk van Deun <dirk@igwe.vub.ac.be>
+
+" This script incorrectly recognizes some junk input as numerals:
+" parsing the complete system of Scheme numerals using the pattern
+" language is practically impossible: I did a lax approximation.
+ 
+" MzScheme extensions can be activated with setting is_mzscheme variable
+
+" Suggestions and bug reports are solicited by the author.
+
+" Initializing:
+
+" For version 5.x: Clear all syntax items
+" For version 6.x: Quit when a syntax file was already loaded
+if version < 600
+  syntax clear
+elseif exists("b:current_syntax")
+  finish
+endif
+
+syn case ignore
+
+" Fascist highlighting: everything that doesn't fit the rules is an error...
+
+syn match	schemeError	oneline    ![^ \t()\[\]";]*!
+syn match	schemeError	oneline    ")"
+
+" Quoted and backquoted stuff
+
+syn region schemeQuoted matchgroup=Delimiter start="['`]" end=![ \t()\[\]";]!me=e-1 contains=ALLBUT,schemeStruc,schemeSyntax,schemeFunc
+
+syn region schemeQuoted matchgroup=Delimiter start="['`](" matchgroup=Delimiter end=")" contains=ALLBUT,schemeStruc,schemeSyntax,schemeFunc
+syn region schemeQuoted matchgroup=Delimiter start="['`]#(" matchgroup=Delimiter end=")" contains=ALLBUT,schemeStruc,schemeSyntax,schemeFunc
+
+syn region schemeStrucRestricted matchgroup=Delimiter start="(" matchgroup=Delimiter end=")" contains=ALLBUT,schemeStruc,schemeSyntax,schemeFunc
+syn region schemeStrucRestricted matchgroup=Delimiter start="#(" matchgroup=Delimiter end=")" contains=ALLBUT,schemeStruc,schemeSyntax,schemeFunc
+
+" Popular Scheme extension:
+" using [] as well as ()
+syn region schemeStrucRestricted matchgroup=Delimiter start="\[" matchgroup=Delimiter end="\]" contains=ALLBUT,schemeStruc,schemeSyntax,schemeFunc
+syn region schemeStrucRestricted matchgroup=Delimiter start="#\[" matchgroup=Delimiter end="\]" contains=ALLBUT,schemeStruc,schemeSyntax,schemeFunc
+
+syn region schemeUnquote matchgroup=Delimiter start="," end=![ \t\[\]()";]!me=e-1 contains=ALLBUT,schemeStruc,schemeSyntax,schemeFunc
+syn region schemeUnquote matchgroup=Delimiter start=",@" end=![ \t\[\]()";]!me=e-1 contains=ALLBUT,schemeStruc,schemeSyntax,schemeFunc
+
+syn region schemeUnquote matchgroup=Delimiter start=",(" end=")" contains=ALL
+syn region schemeUnquote matchgroup=Delimiter start=",@(" end=")" contains=ALL
+
+syn region schemeUnquote matchgroup=Delimiter start=",#(" end=")" contains=ALLBUT,schemeStruc,schemeSyntax,schemeFunc
+syn region schemeUnquote matchgroup=Delimiter start=",@#(" end=")" contains=ALLBUT,schemeStruc,schemeSyntax,schemeFunc
+
+syn region schemeUnquote matchgroup=Delimiter start=",\[" end="\]" contains=ALL
+syn region schemeUnquote matchgroup=Delimiter start=",@\[" end="\]" contains=ALL
+
+syn region schemeUnquote matchgroup=Delimiter start=",#\[" end="\]" contains=ALLBUT,schemeStruc,schemeSyntax,schemeFunc
+syn region schemeUnquote matchgroup=Delimiter start=",@#\[" end="\]" contains=ALLBUT,schemeStruc,schemeSyntax,schemeFunc
+
+" R5RS Scheme Functions and Syntax:
+
+if version < 600
+  set iskeyword=33,35-39,42-58,60-90,94,95,97-122,126,_
+else
+  setlocal iskeyword=33,35-39,42-58,60-90,94,95,97-122,126,_
+endif
+
+syn keyword schemeSyntax lambda and or if cond case define let let* letrec
+syn keyword schemeSyntax begin do delay set! else =>
+syn keyword schemeSyntax quote quasiquote unquote unquote-splicing
+syn keyword schemeSyntax define-syntax let-syntax letrec-syntax syntax-rules
+
+syn keyword schemeFunc not boolean? eq? eqv? equal? pair? cons car cdr set-car!
+syn keyword schemeFunc set-cdr! caar cadr cdar cddr caaar caadr cadar caddr
+syn keyword schemeFunc cdaar cdadr cddar cdddr caaaar caaadr caadar caaddr
+syn keyword schemeFunc cadaar cadadr caddar cadddr cdaaar cdaadr cdadar cdaddr
+syn keyword schemeFunc cddaar cddadr cdddar cddddr null? list? list length
+syn keyword schemeFunc append reverse list-ref memq memv member assq assv assoc
+syn keyword schemeFunc symbol? symbol->string string->symbol number? complex?
+syn keyword schemeFunc real? rational? integer? exact? inexact? = < > <= >=
+syn keyword schemeFunc zero? positive? negative? odd? even? max min + * - / abs
+syn keyword schemeFunc quotient remainder modulo gcd lcm numerator denominator
+syn keyword schemeFunc floor ceiling truncate round rationalize exp log sin cos
+syn keyword schemeFunc tan asin acos atan sqrt expt make-rectangular make-polar
+syn keyword schemeFunc real-part imag-part magnitude angle exact->inexact
+syn keyword schemeFunc inexact->exact number->string string->number char=?
+syn keyword schemeFunc char-ci=? char<? char-ci<? char>? char-ci>? char<=?
+syn keyword schemeFunc char-ci<=? char>=? char-ci>=? char-alphabetic? char?
+syn keyword schemeFunc char-numeric? char-whitespace? char-upper-case?
+syn keyword schemeFunc char-lower-case?
+syn keyword schemeFunc char->integer integer->char char-upcase char-downcase
+syn keyword schemeFunc string? make-string string string-length string-ref
+syn keyword schemeFunc string-set! string=? string-ci=? string<? string-ci<?
+syn keyword schemeFunc string>? string-ci>? string<=? string-ci<=? string>=?
+syn keyword schemeFunc string-ci>=? substring string-append vector? make-vector
+syn keyword schemeFunc vector vector-length vector-ref vector-set! procedure?
+syn keyword schemeFunc apply map for-each call-with-current-continuation
+syn keyword schemeFunc call-with-input-file call-with-output-file input-port?
+syn keyword schemeFunc output-port? current-input-port current-output-port
+syn keyword schemeFunc open-input-file open-output-file close-input-port
+syn keyword schemeFunc close-output-port eof-object? read read-char peek-char
+syn keyword schemeFunc write display newline write-char call/cc
+syn keyword schemeFunc list-tail string->list list->string string-copy
+syn keyword schemeFunc string-fill! vector->list list->vector vector-fill!
+syn keyword schemeFunc force with-input-from-file with-output-to-file
+syn keyword schemeFunc char-ready? load transcript-on transcript-off eval
+syn keyword schemeFunc dynamic-wind port? values call-with-values
+syn keyword schemeFunc scheme-report-environment null-environment
+syn keyword schemeFunc interaction-environment
+
+" ... so that a single + or -, inside a quoted context, would not be
+" interpreted as a number (outside such contexts, it's a schemeFunc)
+
+syn match	schemeDelimiter	oneline    !\.[ \t\[\]()";]!me=e-1
+syn match	schemeDelimiter	oneline    !\.$!
+" ... and a single dot is not a number but a delimiter
+
+" This keeps all other stuff unhighlighted, except *stuff* and <stuff>:
+
+syn match	schemeOther	oneline    ,[a-z!$%&*/:<=>?^_~+@#%-][-a-z!$%&*/:<=>?^_~0-9+.@#%]*,
+syn match	schemeError	oneline    ,[a-z!$%&*/:<=>?^_~+@#%-][-a-z!$%&*/:<=>?^_~0-9+.@#%]*[^-a-z!$%&*/:<=>?^_~0-9+.@ \t\[\]()";]\+[^ \t\[\]()";]*,
+
+syn match	schemeOther	oneline    "\.\.\."
+syn match	schemeError	oneline    !\.\.\.[^ \t\[\]()";]\+!
+" ... a special identifier
+
+syn match	schemeConstant	oneline    ,\*[-a-z!$%&*/:<=>?^_~0-9+.@]*\*[ \t\[\]()";],me=e-1
+syn match	schemeConstant	oneline    ,\*[-a-z!$%&*/:<=>?^_~0-9+.@]*\*$,
+syn match	schemeError	oneline    ,\*[-a-z!$%&*/:<=>?^_~0-9+.@]*\*[^-a-z!$%&*/:<=>?^_~0-9+.@ \t\[\]()";]\+[^ \t\[\]()";]*,
+
+syn match	schemeConstant	oneline    ,<[-a-z!$%&*/:<=>?^_~0-9+.@]*>[ \t\[\]()";],me=e-1
+syn match	schemeConstant	oneline    ,<[-a-z!$%&*/:<=>?^_~0-9+.@]*>$,
+syn match	schemeError	oneline    ,<[-a-z!$%&*/:<=>?^_~0-9+.@]*>[^-a-z!$%&*/:<=>?^_~0-9+.@ \t\[\]()";]\+[^ \t\[\]()";]*,
+
+" Non-quoted lists, and strings:
+
+syn region schemeStruc matchgroup=Delimiter start="(" matchgroup=Delimiter end=")" contains=ALL
+syn region schemeStruc matchgroup=Delimiter start="#(" matchgroup=Delimiter end=")" contains=ALL
+
+syn region schemeStruc matchgroup=Delimiter start="\[" matchgroup=Delimiter end="\]" contains=ALL
+syn region schemeStruc matchgroup=Delimiter start="#\[" matchgroup=Delimiter end="\]" contains=ALL
+
+" Simple literals:
+syn region schemeString start=+\%(\\\)\@<!"+ skip=+\\[\\"]+ end=+"+
+
+" Comments:
+
+syn match	schemeComment	";.*$"
+
+
+" Writing out the complete description of Scheme numerals without
+" using variables is a day's work for a trained secretary...
+
+syn match	schemeOther	oneline    ![+-][ \t\[\]()";]!me=e-1
+syn match	schemeOther	oneline    ![+-]$!
+"
+" This is a useful lax approximation:
+syn match	schemeNumber	oneline    "[-#+0-9.][-#+/0-9a-f@i.boxesfdl]*"
+syn match	schemeError	oneline    ![-#+0-9.][-#+/0-9a-f@i.boxesfdl]*[^-#+/0-9a-f@i.boxesfdl \t\[\]()";][^ \t\[\]()";]*!
+
+syn match	schemeBoolean	oneline    "#[tf]"
+syn match	schemeError	oneline    !#[tf][^ \t\[\]()";]\+!
+
+syn match	schemeChar	oneline    "#\\"
+syn match	schemeChar	oneline    "#\\."
+syn match       schemeError	oneline    !#\\.[^ \t\[\]()";]\+!
+syn match	schemeChar	oneline    "#\\space"
+syn match	schemeError	oneline    !#\\space[^ \t\[\]()";]\+!
+syn match	schemeChar	oneline    "#\\newline"
+syn match	schemeError	oneline    !#\\newline[^ \t\[\]()";]\+!
+
+if exists("b:is_mzscheme") || exists("is_mzscheme")
+    " MzScheme extensions
+    " multiline comment
+    syn region	schemeComment start="#|" end="|#"
+
+    " #%xxx are the special MzScheme identifiers
+    syn match schemeOther oneline    "#%[-a-z!$%&*/:<=>?^_~0-9+.@#%]\+"
+    " anything limited by |'s is identifier
+    syn match schemeOther oneline    "|[^|]\+|"
+
+    syn match	schemeChar	oneline    "#\\\%(return\|tab\)"
+
+    " Modules require stmt
+    syn keyword schemeExtSyntax module require dynamic-require lib prefix all-except prefix-all-except rename
+    " modules provide stmt
+    syn keyword schemeExtSyntax provide struct all-from all-from-except all-defined all-defined-except
+    " Other from MzScheme
+    syn keyword schemeExtSyntax with-handlers when unless instantiate define-struct case-lambda syntax-case
+    syn keyword schemeExtSyntax free-identifier=? bound-identifier=? module-identifier=? syntax-object->datum
+    syn keyword schemeExtSyntax datum->syntax-object
+    syn keyword schemeExtSyntax let-values let*-values letrec-values set!-values fluid-let parameterize begin0
+    syn keyword schemeExtSyntax error raise opt-lambda define-values unit unit/sig define-signature 
+    syn keyword schemeExtSyntax invoke-unit/sig define-values/invoke-unit/sig compound-unit/sig import export
+    syn keyword schemeExtSyntax link syntax quasisyntax unsyntax with-syntax
+
+    syn keyword schemeExtFunc format system-type current-extension-compiler current-extension-linker
+    syn keyword schemeExtFunc use-standard-linker use-standard-compiler
+    syn keyword schemeExtFunc find-executable-path append-object-suffix append-extension-suffix
+    syn keyword schemeExtFunc current-library-collection-paths current-extension-compiler-flags make-parameter
+    syn keyword schemeExtFunc current-directory build-path normalize-path current-extension-linker-flags
+    syn keyword schemeExtFunc file-exists? directory-exists? delete-directory/files delete-directory delete-file
+    syn keyword schemeExtFunc system compile-file system-library-subpath getenv putenv current-standard-link-libraries
+    syn keyword schemeExtFunc remove* file-size find-files fold-files directory-list shell-execute split-path
+    syn keyword schemeExtFunc current-error-port process/ports process printf fprintf open-input-string open-output-string
+    syn keyword schemeExtFunc get-output-string
+    " exceptions
+    syn keyword schemeExtFunc exn exn:application:arity exn:application:continuation exn:application:fprintf:mismatch
+    syn keyword schemeExtFunc exn:application:mismatch exn:application:type exn:application:mismatch exn:break exn:i/o:filesystem exn:i/o:port
+    syn keyword schemeExtFunc exn:i/o:port:closed exn:i/o:tcp exn:i/o:udp exn:misc exn:misc:application exn:misc:unsupported exn:module exn:read
+    syn keyword schemeExtFunc exn:read:non-char exn:special-comment exn:syntax exn:thread exn:user exn:variable exn:application:mismatch
+    syn keyword schemeExtFunc exn? exn:application:arity? exn:application:continuation? exn:application:fprintf:mismatch? exn:application:mismatch?
+    syn keyword schemeExtFunc exn:application:type? exn:application:mismatch? exn:break? exn:i/o:filesystem? exn:i/o:port? exn:i/o:port:closed?
+    syn keyword schemeExtFunc exn:i/o:tcp? exn:i/o:udp? exn:misc? exn:misc:application? exn:misc:unsupported? exn:module? exn:read? exn:read:non-char?
+    syn keyword schemeExtFunc exn:special-comment? exn:syntax? exn:thread? exn:user? exn:variable? exn:application:mismatch?
+    " Command-line parsing
+    syn keyword schemeExtFunc command-line current-command-line-arguments once-any help-labels multi once-each 
+
+    " syntax quoting, unquoting and quasiquotation
+    syn region schemeUnquote matchgroup=Delimiter start="#," end=![ \t\[\]()";]!me=e-1 contains=ALL
+    syn region schemeUnquote matchgroup=Delimiter start="#,@" end=![ \t\[\]()";]!me=e-1 contains=ALL
+    syn region schemeUnquote matchgroup=Delimiter start="#,(" end=")" contains=ALL
+    syn region schemeUnquote matchgroup=Delimiter start="#,@(" end=")" contains=ALL
+    syn region schemeUnquote matchgroup=Delimiter start="#,\[" end="\]" contains=ALL
+    syn region schemeUnquote matchgroup=Delimiter start="#,@\[" end="\]" contains=ALL
+    syn region schemeQuoted matchgroup=Delimiter start="#['`]" end=![ \t()\[\]";]!me=e-1 contains=ALL
+    syn region schemeQuoted matchgroup=Delimiter start="#['`](" matchgroup=Delimiter end=")" contains=ALL
+endif
+
+
+if exists("b:is_chicken") || exists("is_chicken")
+    " multiline comment
+    syntax region schemeMultilineComment start=/#|/ end=/|#/ contains=schemeMultilineComment
+
+    syn match schemeOther oneline    "##[-a-z!$%&*/:<=>?^_~0-9+.@#%]\+"
+    syn match schemeExtSyntax oneline    "#:[-a-z!$%&*/:<=>?^_~0-9+.@#%]\+"
+
+    syn keyword schemeExtSyntax unit uses declare hide foreign-declare foreign-parse foreign-parse/spec
+    syn keyword schemeExtSyntax foreign-lambda foreign-lambda* define-external define-macro load-library
+    syn keyword schemeExtSyntax let-values let*-values letrec-values ->string require-extension
+    syn keyword schemeExtSyntax let-optionals let-optionals* define-foreign-variable define-record
+    syn keyword schemeExtSyntax pointer tag-pointer tagged-pointer? define-foreign-type
+    syn keyword schemeExtSyntax require require-for-syntax cond-expand and-let* receive argc+argv
+    syn keyword schemeExtSyntax fixnum? fx= fx> fx< fx>= fx<= fxmin fxmax
+    syn keyword schemeExtFunc ##core#inline ##sys#error ##sys#update-errno
+
+    " here-string
+    syn region schemeString start=+#<<\s*\z(.*\)+ end=+^\z1$+
+ 
+    if filereadable(expand("<sfile>:p:h")."/cpp.vim")
+	unlet! b:current_syntax
+	syn include @ChickenC <sfile>:p:h/cpp.vim
+	syn region ChickenC matchgroup=schemeOther start=+(\@<=foreign-declare "+ end=+")\@=+ contains=@ChickenC
+	syn region ChickenC matchgroup=schemeComment start=+foreign-declare\s*#<<\z(.*\)$+hs=s+15 end=+^\z1$+ contains=@ChickenC
+	syn region ChickenC matchgroup=schemeOther start=+(\@<=foreign-parse "+ end=+")\@=+ contains=@ChickenC
+	syn region ChickenC matchgroup=schemeComment start=+foreign-parse\s*#<<\z(.*\)$+hs=s+13 end=+^\z1$+ contains=@ChickenC
+	syn region ChickenC matchgroup=schemeOther start=+(\@<=foreign-parse/spec "+ end=+")\@=+ contains=@ChickenC
+	syn region ChickenC matchgroup=schemeComment start=+foreign-parse/spec\s*#<<\z(.*\)$+hs=s+18 end=+^\z1$+ contains=@ChickenC
+	syn region ChickenC matchgroup=schemeComment start=+#>+ end=+<#+ contains=@ChickenC
+	syn region ChickenC matchgroup=schemeComment start=+#>?+ end=+<#+ contains=@ChickenC
+	syn region ChickenC matchgroup=schemeComment start=+#>!+ end=+<#+ contains=@ChickenC
+	syn region ChickenC matchgroup=schemeComment start=+#>\$+ end=+<#+ contains=@ChickenC
+	syn region ChickenC matchgroup=schemeComment start=+#>%+ end=+<#+ contains=@ChickenC
+    endif
+
+endif
+
+" Synchronization and the wrapping up...
+
+syn sync match matchPlace grouphere NONE "^[^ \t]"
+" ... i.e. synchronize on a line that starts at the left margin
+
+" Define the default highlighting.
+" For version 5.7 and earlier: only when not done already
+" For version 5.8 and later: only when an item doesn't have highlighting yet
+if version >= 508 || !exists("did_scheme_syntax_inits")
+  if version < 508
+    let did_scheme_syntax_inits = 1
+    command -nargs=+ HiLink hi link <args>
+  else
+    command -nargs=+ HiLink hi def link <args>
+  endif
+
+  HiLink schemeSyntax		Statement
+  HiLink schemeFunc		Function
+
+  HiLink schemeString		String
+  HiLink schemeChar		Character
+  HiLink schemeNumber		Number
+  HiLink schemeBoolean		Boolean
+
+  HiLink schemeDelimiter	Delimiter
+  HiLink schemeConstant		Constant
+
+  HiLink schemeComment		Comment
+  HiLink schemeMultilineComment	Comment
+  HiLink schemeError		Error
+
+  HiLink schemeExtSyntax	Type
+  HiLink schemeExtFunc		PreProc
+  delcommand HiLink
+endif
+
+let b:current_syntax = "scheme"
--- /dev/null
+++ b/lib/vimfiles/syntax/scilab.vim
@@ -1,0 +1,115 @@
+"
+" Vim syntax file
+" Language   :	Scilab
+" Maintainer :	Benoit Hamelin
+" File type  :	*.sci (see :help filetype)
+" History
+"	28jan2002	benoith		0.1		Creation.  Adapted from matlab.vim.
+"	04feb2002	benoith		0.5		Fixed bugs with constant highlighting.
+"
+
+
+" For version 5.x: Clear all syntax items
+" For version 6.x: Quit when a syntax file was already loaded
+if version < 600
+  syntax clear
+elseif exists("b:current_syntax")
+  finish
+endif
+
+
+" Reserved words.
+syn keyword scilabStatement			abort clear clearglobal end exit global mode predef quit resume
+syn keyword scilabStatement			return
+syn keyword scilabFunction			function endfunction funptr
+syn keyword scilabPredicate			null iserror isglobal
+syn keyword scilabKeyword			typename
+syn keyword scilabDebug				debug pause what where whereami whereis who whos
+syn keyword scilabRepeat			for while break
+syn keyword scilabConditional		if then else elseif
+syn keyword scilabMultiplex			select case
+
+" Reserved constants.
+syn match scilabConstant			"\(%\)[0-9A-Za-z?!#$]\+"
+syn match scilabBoolean				"\(%\)[FTft]\>"
+
+" Delimiters and operators.
+syn match scilabDelimiter			"[][;,()]"
+syn match scilabComparison			"[=~]="
+syn match scilabComparison			"[<>]=\="
+syn match scilabComparison			"<>"
+syn match scilabLogical				"[&|~]"
+syn match scilabAssignment			"="
+syn match scilabArithmetic			"[+-]"
+syn match scilabArithmetic			"\.\=[*/\\]\.\="
+syn match scilabArithmetic			"\.\=^"
+syn match scilabRange				":"
+syn match scilabMlistAccess			"\."
+
+syn match scilabLineContinuation	"\.\{2,}"
+
+syn match scilabTransposition		"[])a-zA-Z0-9?!_#$.]'"lc=1
+
+" Comments and tools.
+syn keyword scilabTodo				TODO todo FIXME fixme TBD tbd	contained
+syn match scilabComment				"//.*$"	contains=scilabTodo
+
+" Constants.
+syn match scilabNumber				"[0-9]\+\(\.[0-9]*\)\=\([DEde][+-]\=[0-9]\+\)\="
+syn match scilabNumber				"\.[0-9]\+\([DEde][+-]\=[0-9]\+\)\="
+syn region scilabString				start=+'+ skip=+''+ end=+'+		oneline
+syn region scilabString				start=+"+ end=+"+				oneline
+
+" Identifiers.
+syn match scilabIdentifier			"\<[A-Za-z?!_#$][A-Za-z0-9?!_#$]*\>"
+syn match scilabOverload			"%[A-Za-z0-9?!_#$]\+_[A-Za-z0-9?!_#$]\+"
+
+
+" Define the default highlighting.
+" For version 5.7 and earlier: only when not done already
+" For version 5.8 and later: only when an item doesn't have highlighting yet
+if version >= 508 || !exists("did_scilab_syntax_inits")
+	if version < 508
+		let did_scilab_syntax_inits = 1
+		command -nargs=+ HiLink hi link <args>
+	else
+		command -nargs=+ HiLink hi def link <args>
+	endif
+
+	HiLink	scilabStatement				Statement
+	HiLink	scilabFunction				Keyword
+	HiLink	scilabPredicate				Keyword
+	HiLink	scilabKeyword				Keyword
+	HiLink	scilabDebug					Debug
+	HiLink	scilabRepeat				Repeat
+	HiLink	scilabConditional			Conditional
+	HiLink	scilabMultiplex				Conditional
+
+	HiLink	scilabConstant				Constant
+	HiLink	scilabBoolean				Boolean
+
+	HiLink	scilabDelimiter				Delimiter
+	HiLink	scilabMlistAccess			Delimiter
+	HiLink	scilabComparison			Operator
+	HiLink	scilabLogical				Operator
+	HiLink	scilabAssignment			Operator
+	HiLink	scilabArithmetic			Operator
+	HiLink	scilabRange					Operator
+	HiLink	scilabLineContinuation		Underlined
+	HiLink	scilabTransposition			Operator
+
+	HiLink	scilabTodo					Todo
+	HiLink	scilabComment				Comment
+
+	HiLink	scilabNumber				Number
+	HiLink	scilabString				String
+
+	HiLink	scilabIdentifier			Identifier
+	HiLink	scilabOverload				Special
+
+	delcommand HiLink
+endif
+
+let b:current_syntax = "scilab"
+
+"EOF	vim: ts=4 noet tw=100 sw=4 sts=0
--- /dev/null
+++ b/lib/vimfiles/syntax/screen.vim
@@ -1,0 +1,81 @@
+" Vim syntax file
+" Language:         screen(1) configuration file
+" Maintainer:       Nikolai Weibull <now@bitwi.se>
+" Latest Revision:  2006-04-19
+
+if exists("b:current_syntax")
+  finish
+endif
+
+let s:cpo_save = &cpo
+set cpo&vim
+
+syn match   screenEscape    '\\.'
+
+syn keyword screenTodo      contained TODO FIXME XXX NOTE
+
+syn region  screenComment   display oneline start='#' end='$'
+                            \ contains=screenTodo,@Spell
+
+syn region  screenString    display oneline start=+"+ skip=+\\"+ end=+"+
+                            \ contains=screenVariable,screenSpecial
+
+syn region  screenLiteral   display oneline start=+'+ skip=+\\'+ end=+'+
+
+syn match   screenVariable  contained display '$\(\h\w*\|{\h\w*}\)'
+
+syn keyword screenBoolean   on off
+
+syn match   screenNumbers   display '\<\d\+\>'
+
+syn match   screenSpecials  contained
+                            \ '%\([%aAdDhlmMstuwWyY?:{]\|[0-9]*n\|0?cC\)'
+
+syn keyword screenCommands  acladd aclchg acldel aclgrp aclumask activity
+                            \ addacl allpartial at attrcolor autodetach
+                            \ bell_msg bind bindkey bufferfile caption chacl
+                            \ chdir clear colon command compacthist console
+                            \ copy copy_regcrlf debug detach digraph dinfo
+                            \ crlf displays dumptermcap echo exec fit focus
+                            \ height help history info kill lastmsg license
+                            \ lockscreen markkeys meta msgminwait msgwait
+                            \ multiuser nethack next nonblock number only
+                            \ other partial_state password paste pastefont
+                            \ pow_break pow_detach_msg prev printcmd process
+                            \ quit readbuf readreg redisplay register
+                            \ remove removebuf reset resize screen select
+                            \ sessionname setenv shelltitle silencewait
+                            \ verbose sleep sorendition split startup_message
+                            \ stuff su suspend time title umask version wall
+                            \ width writebuf xoff xon defmode hardstatus
+                            \ altscreen break breaktype copy_reg defbreaktype
+                            \ defencoding deflog encoding eval ignorecase
+                            \ ins_reg maxwin partial pow_detach setsid source
+                            \ unsetenv windowlist windows defautonuke autonuke
+                            \ defbce bce defc1 c1 defcharset charset defescape
+                            \ escape defflow flow defkanji kanji deflogin
+                            \ login defmonitor monitor defhstatus hstatus
+                            \ defobuflimit obuflimit defscrollback scrollback
+                            \ defshell shell defsilence silence defslowpaste
+                            \ slowpaste defutf8 utf8 defwrap wrap defwritelock
+                            \ writelock defzombie zombie defgr gr hardcopy
+                            \ hardcopy_append hardcopydir hardstatus log
+                            \ logfile login logtstamp mapdefault mapnotnext
+                            \ maptimeout term termcap terminfo termcapinfo
+                            \ vbell vbell_msg vbellwait
+
+hi def link screenEscape    Special
+hi def link screenComment   Comment
+hi def link screenTodo      Todo
+hi def link screenString    String
+hi def link screenLiteral   String
+hi def link screenVariable  Identifier
+hi def link screenBoolean   Boolean
+hi def link screenNumbers   Number
+hi def link screenSpecials  Special
+hi def link screenCommands  Keyword
+
+let b:current_syntax = "screen"
+
+let &cpo = s:cpo_save
+unlet s:cpo_save
--- /dev/null
+++ b/lib/vimfiles/syntax/sd.vim
@@ -1,0 +1,75 @@
+" Language: streaming descriptor file
+" Maintainer: Puria Nafisi Azizi (pna) <pna@netstudent.polito.it>
+" License: This file can be redistribued and/or modified under the same terms
+"   as Vim itself.
+" URL: http://netstudent.polito.it/vim_syntax/
+" Last Change: 2006-09-27
+
+if version < 600
+        syntax clear
+elseif exists("b:current_syntax")
+        finish
+endif
+
+" Always ignore case
+syn case ignore
+
+" Comments
+syn match sdComment /\s*[#;].*$/
+
+" IP Adresses
+syn cluster sdIPCluster contains=sdIPError,sdIPSpecial
+syn match sdIPError /\%(\d\{4,}\|25[6-9]\|2[6-9]\d\|[3-9]\d\{2}\)[\.0-9]*/ contained
+syn match sdIPSpecial /\%(127\.\d\{1,3}\.\d\{1,3}\.\d\{1,3}\)/ contained
+syn match sdIP contained /\%(\d\{1,4}\.\)\{3}\d\{1,4}/ contains=@sdIPCluster
+
+" Statements
+syn keyword sdStatement AGGREGATE AUDIO_CHANNELS 
+syn keyword sdStatement BYTE_PER_PCKT BIT_PER_SAMPLE BITRATE
+syn keyword sdStatement CLOCK_RATE CODING_TYPE CREATOR
+syn match sdStatement /^\s*CODING_TYPE\>/ nextgroup=sdCoding skipwhite
+syn match sdStatement /^\s*ENCODING_NAME\>/ nextgroup=sdEncoding skipwhite
+syn keyword sdStatement FILE_NAME FRAME_LEN FRAME_RATE FORCE_FRAME_RATE
+syn keyword sdStatement LICENSE 
+syn match sdStatement /^\s*MEDIA_SOURCE\>/ nextgroup=sdSource skipwhite
+syn match sdStatement /^\s*MULTICAST\>/ nextgroup=sdIP skipwhite
+syn keyword sdStatement PAYLOAD_TYPE PKT_LEN PRIORITY
+syn keyword sdStatement SAMPLE_RATE
+syn keyword sdStatement TITLE TWIN
+syn keyword sdStatement VERIFY
+
+" Known Options
+syn keyword sdEncoding H26L MPV MP2T MP4V-ES
+syn keyword sdCoding FRAME SAMPLE
+syn keyword sdSource STORED LIVE
+
+"Specials
+syn keyword sdSpecial TRUE FALSE NULL
+syn keyword sdDelimiter STREAM STREAM_END
+syn match sdError /^search .\{257,}/
+
+if version >= 508 || !exists("did_config_syntax_inits")
+        if version < 508
+                let did_config_syntax_inits = 1
+                command! -nargs=+ HiLink hi link <args>
+        else
+                command! -nargs=+ HiLink hi def link <args>
+        endif
+
+        HiLink sdIP Number
+		  HiLink sdHostname Type
+        HiLink sdEncoding Identifier
+        HiLink sdCoding Identifier
+        HiLink sdSource Identifier
+        HiLink sdComment Comment
+        HiLink sdIPError Error
+        HiLink sdError Error
+        HiLink sdStatement Statement
+        HiLink sdIPSpecial Special
+        HiLink sdSpecial Special
+		  HiLink sdDelimiter Delimiter
+
+        delcommand HiLink
+endif
+
+let b:current_syntax = "sd"
--- /dev/null
+++ b/lib/vimfiles/syntax/sdl.vim
@@ -1,0 +1,167 @@
+" Vim syntax file
+" Language:	SDL
+" Maintainer:	Michael Piefel <piefel@informatik.hu-berlin.de>
+" Last Change:	2 May 2001
+
+" For version 5.x: Clear all syntax items
+" For version 6.x: Quit when a syntax file was already loaded
+if version < 600
+    syntax clear
+elseif exists("b:current_syntax")
+    finish
+endif
+
+if !exists("sdl_2000")
+    syntax case ignore
+endif
+
+" A bunch of useful SDL keywords
+syn keyword sdlStatement	task else nextstate
+syn keyword sdlStatement	in out with from interface
+syn keyword sdlStatement	to via env and use
+syn keyword sdlStatement	process procedure block system service type
+syn keyword sdlStatement	endprocess endprocedure endblock endsystem
+syn keyword sdlStatement	package endpackage connection endconnection
+syn keyword sdlStatement	channel endchannel connect
+syn keyword sdlStatement	synonym dcl signal gate timer signallist signalset
+syn keyword sdlStatement	create output set reset call
+syn keyword sdlStatement	operators literals
+syn keyword sdlStatement	active alternative any as atleast constants
+syn keyword sdlStatement	default endalternative endmacro endoperator
+syn keyword sdlStatement	endselect endsubstructure external
+syn keyword sdlStatement	if then fi for import macro macrodefinition
+syn keyword sdlStatement	macroid mod nameclass nodelay not operator or
+syn keyword sdlStatement	parent provided referenced rem
+syn keyword sdlStatement	select spelling substructure xor
+syn keyword sdlNewState		state endstate
+syn keyword sdlInput		input start stop return none save priority
+syn keyword sdlConditional	decision enddecision join
+syn keyword sdlVirtual		virtual redefined finalized adding inherits
+syn keyword sdlExported		remote exported export
+
+if !exists("sdl_no_96")
+    syn keyword sdlStatement	all axioms constant endgenerator endrefinement endservice
+    syn keyword sdlStatement	error fpar generator literal map noequality ordering
+    syn keyword sdlStatement	refinement returns revealed reverse service signalroute
+    syn keyword sdlStatement	view viewed
+    syn keyword sdlExported	imported
+endif
+
+if exists("sdl_2000")
+    syn keyword sdlStatement	abstract aggregation association break choice composition
+    syn keyword sdlStatement	continue endmethod handle method
+    syn keyword sdlStatement	ordered private protected public
+    syn keyword sdlException	exceptionhandler endexceptionhandler onexception
+    syn keyword sdlException	catch new raise
+    " The same in uppercase
+    syn keyword sdlStatement	TASK ELSE NEXTSTATE
+    syn keyword sdlStatement	IN OUT WITH FROM INTERFACE
+    syn keyword sdlStatement	TO VIA ENV AND USE
+    syn keyword sdlStatement	PROCESS PROCEDURE BLOCK SYSTEM SERVICE TYPE
+    syn keyword sdlStatement	ENDPROCESS ENDPROCEDURE ENDBLOCK ENDSYSTEM
+    syn keyword sdlStatement	PACKAGE ENDPACKAGE CONNECTION ENDCONNECTION
+    syn keyword sdlStatement	CHANNEL ENDCHANNEL CONNECT
+    syn keyword sdlStatement	SYNONYM DCL SIGNAL GATE TIMER SIGNALLIST SIGNALSET
+    syn keyword sdlStatement	CREATE OUTPUT SET RESET CALL
+    syn keyword sdlStatement	OPERATORS LITERALS
+    syn keyword sdlStatement	ACTIVE ALTERNATIVE ANY AS ATLEAST CONSTANTS
+    syn keyword sdlStatement	DEFAULT ENDALTERNATIVE ENDMACRO ENDOPERATOR
+    syn keyword sdlStatement	ENDSELECT ENDSUBSTRUCTURE EXTERNAL
+    syn keyword sdlStatement	IF THEN FI FOR IMPORT MACRO MACRODEFINITION
+    syn keyword sdlStatement	MACROID MOD NAMECLASS NODELAY NOT OPERATOR OR
+    syn keyword sdlStatement	PARENT PROVIDED REFERENCED REM
+    syn keyword sdlStatement	SELECT SPELLING SUBSTRUCTURE XOR
+    syn keyword sdlNewState	STATE ENDSTATE
+    syn keyword sdlInput	INPUT START STOP RETURN NONE SAVE PRIORITY
+    syn keyword sdlConditional	DECISION ENDDECISION JOIN
+    syn keyword sdlVirtual	VIRTUAL REDEFINED FINALIZED ADDING INHERITS
+    syn keyword sdlExported	REMOTE EXPORTED EXPORT
+
+    syn keyword sdlStatement	ABSTRACT AGGREGATION ASSOCIATION BREAK CHOICE COMPOSITION
+    syn keyword sdlStatement	CONTINUE ENDMETHOD ENDOBJECT ENDVALUE HANDLE METHOD OBJECT
+    syn keyword sdlStatement	ORDERED PRIVATE PROTECTED PUBLIC
+    syn keyword sdlException	EXCEPTIONHANDLER ENDEXCEPTIONHANDLER ONEXCEPTION
+    syn keyword sdlException	CATCH NEW RAISE
+endif
+
+" String and Character contstants
+" Highlight special characters (those which have a backslash) differently
+syn match   sdlSpecial		contained "\\\d\d\d\|\\."
+syn region  sdlString		start=+"+  skip=+\\\\\|\\"+  end=+"+  contains=cSpecial
+syn region  sdlString		start=+'+  skip=+''+  end=+'+
+
+" No, this doesn't happen, I just wanted to scare you. SDL really allows all
+" these characters for identifiers; fortunately, keywords manage without them.
+" set iskeyword=@,48-57,_,192-214,216-246,248-255,-
+
+syn region sdlComment		start="/\*"  end="\*/"
+syn region sdlComment		start="comment"  end=";"
+syn region sdlComment		start="--" end="--\|$"
+syn match  sdlCommentError	"\*/"
+
+syn keyword sdlOperator		present
+syn keyword sdlType		integer real natural duration pid boolean time
+syn keyword sdlType		character charstring ia5string
+syn keyword sdlType		self now sender offspring
+syn keyword sdlStructure	asntype endasntype syntype endsyntype struct
+
+if !exists("sdl_no_96")
+    syn keyword sdlStructure	newtype endnewtype
+endif
+
+if exists("sdl_2000")
+    syn keyword sdlStructure	object endobject value endvalue
+    " The same in uppercase
+    syn keyword sdlStructure	OBJECT ENDOBJECT VALUE ENDVALUE
+    syn keyword sdlOperator	PRESENT
+    syn keyword sdlType		INTEGER NATURAL DURATION PID BOOLEAN TIME
+    syn keyword sdlType		CHARSTRING IA5STRING
+    syn keyword sdlType		SELF NOW SENDER OFFSPRING
+    syn keyword sdlStructure	ASNTYPE ENDASNTYPE SYNTYPE ENDSYNTYPE STRUCT
+endif
+
+" ASN.1 in SDL
+syn case match
+syn keyword sdlType		SET OF BOOLEAN INTEGER REAL BIT OCTET
+syn keyword sdlType		SEQUENCE CHOICE
+syn keyword sdlType		STRING OBJECT IDENTIFIER NULL
+
+syn sync ccomment sdlComment
+
+" Define the default highlighting.
+" For version 5.7 and earlier: only when not done already
+" For version 5.8 and later: only when an item doesn't have highlighting yet
+if version >= 508 || !exists("did_sdl_syn_inits")
+    if version < 508
+	let did_sdl_syn_inits = 1
+	command -nargs=+ HiLink hi link <args>
+	command -nargs=+ Hi     hi <args>
+    else
+	command -nargs=+ HiLink hi def link <args>
+	command -nargs=+ Hi     hi def <args>
+    endif
+
+    HiLink  sdlException	Label
+    HiLink  sdlConditional	sdlStatement
+    HiLink  sdlVirtual		sdlStatement
+    HiLink  sdlExported		sdlFlag
+    HiLink  sdlCommentError	sdlError
+    HiLink  sdlOperator		Operator
+    HiLink  sdlStructure	sdlType
+    Hi	    sdlStatement	term=bold ctermfg=4 guifg=Blue
+    Hi	    sdlFlag		term=bold ctermfg=4 guifg=Blue gui=italic
+    Hi	    sdlNewState		term=italic ctermfg=2 guifg=Magenta gui=underline
+    Hi	    sdlInput		term=bold guifg=Red
+    HiLink  sdlType		Type
+    HiLink  sdlString		String
+    HiLink  sdlComment		Comment
+    HiLink  sdlSpecial		Special
+    HiLink  sdlError		Error
+
+    delcommand HiLink
+    delcommand Hi
+endif
+
+let b:current_syntax = "sdl"
+
+" vim: ts=8
--- /dev/null
+++ b/lib/vimfiles/syntax/sed.vim
@@ -1,0 +1,122 @@
+" Vim syntax file
+" Language:	sed
+" Maintainer:	Haakon Riiser <hakonrk@fys.uio.no>
+" URL:		http://folk.uio.no/hakonrk/vim/syntax/sed.vim
+" Last Change:	2005 Dec 15
+
+" For version 5.x: Clear all syntax items
+" For version 6.x: Quit when a syntax file was already loaded
+if version < 600
+    syn clear
+elseif exists("b:current_syntax")
+    finish
+endif
+
+syn match sedError	"\S"
+
+syn match sedWhitespace "\s\+" contained
+syn match sedSemicolon	";"
+syn match sedAddress	"[[:digit:]$]"
+syn match sedAddress	"\d\+\~\d\+"
+syn region sedAddress   matchgroup=Special start="[{,;]\s*/\(\\/\)\="lc=1 skip="[^\\]\(\\\\\)*\\/" end="/I\=" contains=sedTab,sedRegexpMeta
+syn region sedAddress   matchgroup=Special start="^\s*/\(\\/\)\=" skip="[^\\]\(\\\\\)*\\/" end="/I\=" contains=sedTab,sedRegexpMeta
+syn match sedComment	"^\s*#.*$"
+syn match sedFunction	"[dDgGhHlnNpPqQx=]\s*\($\|;\)" contains=sedSemicolon,sedWhitespace
+syn match sedLabel	":[^;]*"
+syn match sedLineCont	"^\(\\\\\)*\\$" contained
+syn match sedLineCont	"[^\\]\(\\\\\)*\\$"ms=e contained
+syn match sedSpecial	"[{},!]"
+if exists("highlight_sedtabs")
+    syn match sedTab	"\t" contained
+endif
+
+" Append/Change/Insert
+syn region sedACI	matchgroup=sedFunction start="[aci]\\$" matchgroup=NONE end="^.*$" contains=sedLineCont,sedTab
+
+syn region sedBranch	matchgroup=sedFunction start="[bt]" matchgroup=sedSemicolon end=";\|$" contains=sedWhitespace
+syn region sedRW	matchgroup=sedFunction start="[rw]" matchgroup=sedSemicolon end=";\|$" contains=sedWhitespace
+
+" Substitution/transform with various delimiters
+syn region sedFlagwrite	    matchgroup=sedFlag start="w" matchgroup=sedSemicolon end=";\|$" contains=sedWhitespace contained
+syn match sedFlag	    "[[:digit:]gpI]*w\=" contains=sedFlagwrite contained
+syn match sedRegexpMeta	    "[.*^$]" contained
+syn match sedRegexpMeta	    "\\." contains=sedTab contained
+syn match sedRegexpMeta	    "\[.\{-}\]" contains=sedTab contained
+syn match sedRegexpMeta	    "\\{\d\*,\d*\\}" contained
+syn match sedRegexpMeta	    "\\(.\{-}\\)" contains=sedTab contained
+syn match sedReplaceMeta    "&\|\\\($\|.\)" contains=sedTab contained
+
+" Metacharacters: $ * . \ ^ [ ~
+" @ is used as delimiter and treated on its own below
+let __at = char2nr("@")
+let __sed_i = char2nr(" ")
+if has("ebcdic")
+    let __sed_last = 255
+else
+    let __sed_last = 126
+endif
+let __sed_metacharacters = '$*.\^[~'
+while __sed_i <= __sed_last
+    let __sed_delimiter = escape(nr2char(__sed_i), __sed_metacharacters)
+	if __sed_i != __at
+	    exe 'syn region sedAddress matchgroup=Special start=@\\'.__sed_delimiter.'\(\\'.__sed_delimiter.'\)\=@ skip=@[^\\]\(\\\\\)*\\'.__sed_delimiter.'@ end=@'.__sed_delimiter.'I\=@ contains=sedTab'
+	    exe 'syn region sedRegexp'.__sed_i  'matchgroup=Special start=@'.__sed_delimiter.'\(\\\\\|\\'.__sed_delimiter.'\)*@ skip=@[^\\'.__sed_delimiter.']\(\\\\\)*\\'.__sed_delimiter.'@ end=@'.__sed_delimiter.'@me=e-1 contains=sedTab,sedRegexpMeta keepend contained nextgroup=sedReplacement'.__sed_i
+	    exe 'syn region sedReplacement'.__sed_i 'matchgroup=Special start=@'.__sed_delimiter.'\(\\\\\|\\'.__sed_delimiter.'\)*@ skip=@[^\\'.__sed_delimiter.']\(\\\\\)*\\'.__sed_delimiter.'@ end=@'.__sed_delimiter.'@ contains=sedTab,sedReplaceMeta keepend contained nextgroup=sedFlag'
+	endif
+    let __sed_i = __sed_i + 1
+endwhile
+syn region sedAddress matchgroup=Special start=+\\@\(\\@\)\=+ skip=+[^\\]\(\\\\\)*\\@+ end=+@I\=+ contains=sedTab,sedRegexpMeta
+syn region sedRegexp64 matchgroup=Special start=+@\(\\\\\|\\@\)*+ skip=+[^\\@]\(\\\\\)*\\@+ end=+@+me=e-1 contains=sedTab,sedRegexpMeta keepend contained nextgroup=sedReplacement64
+syn region sedReplacement64 matchgroup=Special start=+@\(\\\\\|\\@\)*+ skip=+[^\\@]\(\\\\\)*\\@+ end=+@+ contains=sedTab,sedReplaceMeta keepend contained nextgroup=sedFlag
+
+" Since the syntax for the substituion command is very similar to the
+" syntax for the transform command, I use the same pattern matching
+" for both commands.  There is one problem -- the transform command
+" (y) does not allow any flags.  To save memory, I ignore this problem.
+syn match sedST	"[sy]" nextgroup=sedRegexp\d\+
+
+if version >= 508 || !exists("did_sed_syntax_inits")
+    if version < 508
+	let did_sed_syntax_inits = 1
+	command -nargs=+ HiLink hi link <args>
+    else
+	command -nargs=+ HiLink hi def link <args>
+    endif
+
+    HiLink sedAddress		Macro
+    HiLink sedACI		NONE
+    HiLink sedBranch		Label
+    HiLink sedComment		Comment
+    HiLink sedDelete		Function
+    HiLink sedError		Error
+    HiLink sedFlag		Type
+    HiLink sedFlagwrite		Constant
+    HiLink sedFunction		Function
+    HiLink sedLabel		Label
+    HiLink sedLineCont		Special
+    HiLink sedPutHoldspc	Function
+    HiLink sedReplaceMeta	Special
+    HiLink sedRegexpMeta	Special
+    HiLink sedRW		Constant
+    HiLink sedSemicolon		Special
+    HiLink sedST		Function
+    HiLink sedSpecial		Special
+    HiLink sedWhitespace	NONE
+    if exists("highlight_sedtabs")
+	HiLink sedTab		Todo
+    endif
+    let __sed_i = 32
+    while __sed_i <= 126
+	exe "HiLink sedRegexp".__sed_i		"Macro"
+	exe "HiLink sedReplacement".__sed_i	"NONE"
+	let __sed_i = __sed_i + 1
+    endwhile
+
+    delcommand HiLink
+endif
+
+unlet __sed_i __sed_delimiter __sed_metacharacters
+
+let b:current_syntax = "sed"
+
+" vim: sts=4 sw=4 ts=8
--- /dev/null
+++ b/lib/vimfiles/syntax/sendpr.vim
@@ -1,0 +1,32 @@
+" Vim syntax file
+" Language: FreeBSD send-pr file
+" Maintainer: Hendrik Scholz <hendrik@scholz.net>
+" Last Change: 2002 Mar 21
+"
+" http://raisdorf.net/files/misc/send-pr.vim
+
+" For version 5.x: Clear all syntax items
+" For version 6.x: Quit when a syntax file was already loaded
+if version < 600
+  syntax clear
+elseif exists("b:current_syntax")
+  finish
+endif
+
+syn match sendprComment /^SEND-PR:/
+" email address
+syn match sendprType /<[a-zA-Z0-9\-\_\.]*@[a-zA-Z0-9\-\_\.]*>/
+" ^> lines
+syn match sendprString /^>[a-zA-Z\-]*:/
+syn region sendprLabel start="\[" end="\]"
+syn match sendprString /^To:/
+syn match sendprString /^From:/
+syn match sendprString /^Reply-To:/
+syn match sendprString /^Cc:/
+syn match sendprString /^X-send-pr-version:/
+syn match sendprString /^X-GNATS-Notify:/
+
+hi def link sendprComment   Comment
+hi def link sendprType      Type
+hi def link sendprString    String
+hi def link sendprLabel     Label
--- /dev/null
+++ b/lib/vimfiles/syntax/sensors.vim
@@ -1,0 +1,52 @@
+" Vim syntax file
+" Language:         sensors.conf(5) - libsensors configuration file
+" Maintainer:       Nikolai Weibull <now@bitwi.se>
+" Latest Revision:  2006-04-19
+
+if exists("b:current_syntax")
+  finish
+endif
+
+let s:cpo_save = &cpo
+set cpo&vim
+
+syn keyword sensorsTodo         contained TODO FIXME XXX NOTE
+
+syn region  sensorsComment      display oneline start='#' end='$'
+                                \ contains=sensorsTodo,@Spell
+
+
+syn keyword sensorsKeyword      bus chip label compute ignore set
+
+syn region  sensorsName         display oneline
+                                \ start=+"+ skip=+\\\\\|\\"+ end=+"+
+                                \ contains=sensorsNameSpecial
+syn match   sensorsName         display '\w\+'
+
+syn match   sensorsNameSpecial  display '\\["\\rnt]'
+
+syn match   sensorsLineContinue '\\$'
+
+syn match   sensorsNumber       display '\d*.\d\+\>'
+
+syn match   sensorsRealWorld    display '@'
+
+syn match   sensorsOperator     display '[+*/-]'
+
+syn match   sensorsDelimiter    display '[()]'
+
+hi def link sensorsTodo         Todo
+hi def link sensorsComment      Comment
+hi def link sensorsKeyword      Keyword
+hi def link sensorsName         String
+hi def link sensorsNameSpecial  SpecialChar
+hi def link sensorsLineContinue Special
+hi def link sensorsNumber       Number
+hi def link sensorsRealWorld    Identifier
+hi def link sensorsOperator     Normal
+hi def link sensorsDelimiter    Normal
+
+let b:current_syntax = "sensors"
+
+let &cpo = s:cpo_save
+unlet s:cpo_save
--- /dev/null
+++ b/lib/vimfiles/syntax/services.vim
@@ -1,0 +1,54 @@
+" Vim syntax file
+" Language:         services(5) - Internet network services list
+" Maintainer:       Nikolai Weibull <now@bitwi.se>
+" Latest Revision:  2006-04-19
+
+if exists("b:current_syntax")
+  finish
+endif
+
+let s:cpo_save = &cpo
+set cpo&vim
+
+syn match   servicesBegin     display '^'
+                              \ nextgroup=servicesName,servicesComment
+
+syn match   servicesName      contained display '[[:graph:]]\+'
+                              \ nextgroup=servicesPort skipwhite
+
+syn match   servicesPort      contained display '\d\+'
+                              \ nextgroup=servicesPPDiv,servicesPPDivDepr
+                              \ skipwhite
+
+syn match   servicesPPDiv     contained display '/'
+                              \ nextgroup=servicesProtocol skipwhite
+
+syn match   servicesPPDivDepr contained display ','
+                              \ nextgroup=servicesProtocol skipwhite
+
+syn match   servicesProtocol  contained display '\S\+'
+                              \ nextgroup=servicesAliases,servicesComment
+                              \ skipwhite
+
+syn match   servicesAliases   contained display '\S\+'
+                              \ nextgroup=servicesAliases,servicesComment
+                              \ skipwhite
+
+syn keyword servicesTodo      contained TODO FIXME XXX NOTE
+
+syn region  servicesComment   display oneline start='#' end='$'
+                              \ contains=servicesTodo,@Spell
+
+hi def link servicesTodo      Todo
+hi def link servicesComment   Comment
+hi def link servicesName      Identifier
+hi def link servicesPort      Number
+hi def link servicesPPDiv     Delimiter
+hi def link servicesPPDivDepr Error
+hi def link servicesProtocol  Type
+hi def link servicesAliases   Macro
+
+let b:current_syntax = "services"
+
+let &cpo = s:cpo_save
+unlet s:cpo_save
--- /dev/null
+++ b/lib/vimfiles/syntax/setserial.vim
@@ -1,0 +1,120 @@
+" Vim syntax file
+" Language:         setserial(8) configuration file
+" Maintainer:       Nikolai Weibull <now@bitwi.se>
+" Latest Revision:  2006-04-19
+
+if exists("b:current_syntax")
+  finish
+endif
+
+let s:cpo_save = &cpo
+set cpo&vim
+
+syn match   setserialBegin      display '^'
+                                \ nextgroup=setserialDevice,setserialComment
+                                \ skipwhite
+
+syn match   setserialDevice     contained display '\%(/[^ \t/]*\)\+'
+                                \ nextgroup=setserialParameter skipwhite
+
+syn keyword setserialParameter  contained port irq baud_base divisor
+                                \ close_delay closing_wait rx_trigger
+                                \ tx_trigger flow_off flow_on rx_timeout
+                                \ nextgroup=setserialNumber skipwhite
+
+syn keyword setserialParameter  contained uart
+                                \ nextgroup=setserialUARTType skipwhite
+
+syn keyword setserialParameter  contained autoconfig auto_irq skip_test
+                                \ spd_hi spd_vhi spd_shi spd_warp spd_cust
+                                \ spd_normal sak fourport session_lockout
+                                \ pgrp_lockout hup_notify split_termios
+                                \ callout_nohup low_latency
+                                \ nextgroup=setserialParameter skipwhite
+
+syn match   setserialParameter  contained display
+                                \ '\^\%(auto_irq\|skip_test\|sak\|fourport\)'
+                                \ contains=setserialNegation
+                                \ nextgroup=setserialParameter skipwhite
+
+syn match   setserialParameter  contained display
+                                \ '\^\%(session_lockout\|pgrp_lockout\)'
+                                \ contains=setserialNegation
+                                \ nextgroup=setserialParameter skipwhite
+
+syn match   setserialParameter  contained display
+                                \ '\^\%(hup_notify\|split_termios\)'
+                                \ contains=setserialNegation
+                                \ nextgroup=setserialParameter skipwhite
+
+syn match   setserialParameter  contained display
+                                \ '\^\%(callout_nohup\|low_latency\)'
+                                \ contains=setserialNegation
+                                \ nextgroup=setserialParameter skipwhite
+
+syn keyword setserialParameter  contained set_multiport
+                                \ nextgroup=setserialMultiport skipwhite
+
+syn match   setserialNumber     contained display '\<\d\+\>'
+                                \ nextgroup=setserialParameter skipwhite
+syn match   setserialNumber     contained display '0x\x\+'
+                                \ nextgroup=setserialParameter skipwhite
+
+syn keyword setserialUARTType   contained none
+
+syn match   setserialUARTType   contained display
+                                \ '8250\|16[4789]50\|16550A\=\|16650\%(V2\)\='
+                                \ nextgroup=setserialParameter skipwhite
+
+syn match   setserialUARTType   contained display '166[59]4'
+                                \ nextgroup=setserialParameter skipwhite
+
+syn match   setserialNegation   contained display '\^'
+
+syn match   setserialMultiport  contained '\<port\d\+\>'
+                                \ nextgroup=setserialPort skipwhite
+
+syn match   setserialPort       contained display '\<\d\+\>'
+                                \ nextgroup=setserialMask skipwhite
+syn match   setserialPort       contained display '0x\x\+'
+                                \ nextgroup=setserialMask skipwhite
+
+syn match   setserialMask       contained '\<mask\d\+\>'
+                                \ nextgroup=setserialBitMask skipwhite
+
+syn match   setserialBitMask    contained display '\<\d\+\>'
+                                \ nextgroup=setserialMatch skipwhite
+syn match   setserialBitMask    contained display '0x\x\+'
+                                \ nextgroup=setserialMatch skipwhite
+
+syn match   setserialMatch      contained '\<match\d\+\>'
+                                \ nextgroup=setserialMatchBits skipwhite
+
+syn match   setserialMatchBits  contained display '\<\d\+\>'
+                                \ nextgroup=setserialMultiport skipwhite
+syn match   setserialMatchBits  contained display '0x\x\+'
+                                \ nextgroup=setserialMultiport skipwhite
+
+syn keyword setserialTodo       contained TODO FIXME XXX NOTE
+
+syn region  setserialComment    display oneline start='^\s*#' end='$'
+                                \ contains=setserialTodo,@Spell
+
+hi def link setserialTodo       Todo
+hi def link setserialComment    Comment
+hi def link setserialDevice     Normal
+hi def link setserialParameter  Identifier
+hi def link setserialNumber     Number
+hi def link setserialUARTType   Type
+hi def link setserialNegation   Operator
+hi def link setserialMultiport  Type
+hi def link setserialPort       setserialNumber
+hi def link setserialMask       Type
+hi def link setserialBitMask    setserialNumber
+hi def link setserialMatch      Type
+hi def link setserialMatchBits  setserialNumber
+
+let b:current_syntax = "setserial"
+
+let &cpo = s:cpo_save
+unlet s:cpo_save
--- /dev/null
+++ b/lib/vimfiles/syntax/sgml.vim
@@ -1,0 +1,337 @@
+" Vim syntax file
+" Language:	SGML
+" Maintainer:	Johannes Zellner <johannes@zellner.org>
+" Last Change:	Tue, 27 Apr 2004 15:05:21 CEST
+" Filenames:	*.sgml,*.sgm
+" $Id: sgml.vim,v 1.1 2004/06/13 17:52:57 vimboss Exp $
+
+" For version 5.x: Clear all syntax items
+" For version 6.x: Quit when a syntax file was already loaded
+if version < 600
+  syntax clear
+elseif exists("b:current_syntax")
+  finish
+endif
+
+let s:sgml_cpo_save = &cpo
+set cpo&vim
+
+syn case match
+
+" mark illegal characters
+syn match sgmlError "[<&]"
+
+
+" unicode numbers:
+" provide different highlithing for unicode characters
+" inside strings and in plain text (character data).
+"
+" EXAMPLE:
+"
+" \u4e88
+"
+syn match   sgmlUnicodeNumberAttr    +\\u\x\{4}+ contained contains=sgmlUnicodeSpecifierAttr
+syn match   sgmlUnicodeSpecifierAttr +\\u+ contained
+syn match   sgmlUnicodeNumberData    +\\u\x\{4}+ contained contains=sgmlUnicodeSpecifierData
+syn match   sgmlUnicodeSpecifierData +\\u+ contained
+
+
+" strings inside character data or comments
+"
+syn region  sgmlString contained start=+"+ skip=+\\\\\|\\"+ end=+"+ contains=sgmlEntity,sgmlUnicodeNumberAttr display
+syn region  sgmlString contained start=+'+ skip=+\\\\\|\\'+ end=+'+ contains=sgmlEntity,sgmlUnicodeNumberAttr display
+
+" punctuation (within attributes) e.g. <tag sgml:foo.attribute ...>
+"						^   ^
+syn match   sgmlAttribPunct +[:.]+ contained display
+
+
+" no highlighting for sgmlEqual (sgmlEqual has no highlighting group)
+syn match   sgmlEqual +=+
+
+
+" attribute, everything before the '='
+"
+" PROVIDES: @sgmlAttribHook
+"
+" EXAMPLE:
+"
+" <tag foo.attribute = "value">
+"      ^^^^^^^^^^^^^
+"
+syn match   sgmlAttrib
+    \ +[^-'"<]\@<=\<[a-zA-Z0-9.:]\+\>\([^'">]\@=\|$\)+
+    \ contained
+    \ contains=sgmlAttribPunct,@sgmlAttribHook
+    \ display
+
+
+" UNQUOTED value (not including the '=' -- sgmlEqual)
+"
+" PROVIDES: @sgmlValueHook
+"
+" EXAMPLE:
+"
+" <tag foo.attribute = value>
+"		       ^^^^^
+"
+syn match   sgmlValue
+    \ +[^"' =/!?<>][^ =/!?<>]*+
+    \ contained
+    \ contains=sgmlEntity,sgmlUnicodeNumberAttr,@sgmlValueHook
+    \ display
+
+
+" QUOTED value (not including the '=' -- sgmlEqual)
+"
+" PROVIDES: @sgmlValueHook
+"
+" EXAMPLE:
+"
+" <tag foo.attribute = "value">
+"		       ^^^^^^^
+" <tag foo.attribute = 'value'>
+"		       ^^^^^^^
+"
+syn region  sgmlValue contained start=+"+ skip=+\\\\\|\\"+ end=+"+
+	    \ contains=sgmlEntity,sgmlUnicodeNumberAttr,@sgmlValueHook
+syn region  sgmlValue contained start=+'+ skip=+\\\\\|\\'+ end=+'+
+	    \ contains=sgmlEntity,sgmlUnicodeNumberAttr,@sgmlValueHook
+
+
+" value, everything after (and including) the '='
+" no highlighting!
+"
+" EXAMPLE:
+"
+" <tag foo.attribute = "value">
+"		     ^^^^^^^^^
+" <tag foo.attribute = value>
+"		     ^^^^^^^
+"
+syn match   sgmlEqualValue
+    \ +=\s*[^ =/!?<>]\++
+    \ contained
+    \ contains=sgmlEqual,sgmlString,sgmlValue
+    \ display
+
+
+" start tag
+" use matchgroup=sgmlTag to skip over the leading '<'
+" see also sgmlEmptyTag below.
+"
+" PROVIDES: @sgmlTagHook
+"
+syn region   sgmlTag
+    \ matchgroup=sgmlTag start=+<[^ /!?"']\@=+
+    \ matchgroup=sgmlTag end=+>+
+    \ contained
+    \ contains=sgmlError,sgmlAttrib,sgmlEqualValue,@sgmlTagHook
+
+
+" tag content for empty tags. This is the same as sgmlTag
+" above, except the `matchgroup=sgmlEndTag for highlighting
+" the end '/>' differently.
+"
+" PROVIDES: @sgmlTagHook
+"
+syn region   sgmlEmptyTag
+    \ matchgroup=sgmlTag start=+<[^ /!?"']\@=+
+    \ matchgroup=sgmlEndTag end=+/>+
+    \ contained
+    \ contains=sgmlError,sgmlAttrib,sgmlEqualValue,@sgmlTagHook
+
+
+" end tag
+" highlight everything but not the trailing '>' which
+" was already highlighted by the containing sgmlRegion.
+"
+" PROVIDES: @sgmlTagHook
+" (should we provide a separate @sgmlEndTagHook ?)
+"
+syn match   sgmlEndTag
+    \ +</[^ /!?>"']\+>+
+    \ contained
+    \ contains=@sgmlTagHook
+
+
+" [-- SGML SPECIFIC --]
+
+" SGML specific
+" tag content for abbreviated regions
+"
+" PROVIDES: @sgmlTagHook
+"
+syn region   sgmlAbbrTag
+    \ matchgroup=sgmlTag start=+<[^ /!?"']\@=+
+    \ matchgroup=sgmlTag end=+/+
+    \ contained
+    \ contains=sgmlError,sgmlAttrib,sgmlEqualValue,@sgmlTagHook
+
+
+" SGML specific
+" just highlight the trailing '/'
+syn match   sgmlAbbrEndTag +/+
+
+
+" SGML specific
+" abbreviated regions
+"
+" No highlighing, highlighing is done by contained elements.
+"
+" PROVIDES: @sgmlRegionHook
+"
+" EXAMPLE:
+"
+" <bold/Im Anfang war das Wort/
+"
+syn match   sgmlAbbrRegion
+    \ +<[^/!?>"']\+/\_[^/]\+/+
+    \ contains=sgmlAbbrTag,sgmlAbbrEndTag,sgmlCdata,sgmlComment,sgmlEntity,sgmlUnicodeNumberData,@sgmlRegionHook
+
+" [-- END OF SGML SPECIFIC --]
+
+
+" real (non-empty) elements. We cannot do syntax folding
+" as in xml, because end tags may be optional in sgml depending
+" on the dtd.
+" No highlighing, highlighing is done by contained elements.
+"
+" PROVIDES: @sgmlRegionHook
+"
+" EXAMPLE:
+"
+" <tag id="whoops">
+"   <!-- comment -->
+"   <another.tag></another.tag>
+"   <another.tag/>
+"   some data
+" </tag>
+"
+" SGML specific:
+" compared to xmlRegion:
+"   - removed folding
+"   - added a single '/'in the start pattern
+"
+syn region   sgmlRegion
+    \ start=+<\z([^ /!?>"']\+\)\(\(\_[^/>]*[^/!?]>\)\|>\)+
+    \ end=+</\z1>+
+    \ contains=sgmlTag,sgmlEndTag,sgmlCdata,@sgmlRegionCluster,sgmlComment,sgmlEntity,sgmlUnicodeNumberData,@sgmlRegionHook
+    \ keepend
+    \ extend
+
+
+" empty tags. Just a container, no highlighting.
+" Compare this with sgmlTag.
+"
+" EXAMPLE:
+"
+" <tag id="lola"/>
+"
+" TODO use sgmlEmptyTag intead of sgmlTag
+syn match    sgmlEmptyRegion
+    \ +<[^ /!?>"']\(\_[^"'<>]\|"\_[^"]*"\|'\_[^']*'\)*/>+
+    \ contains=sgmlEmptyTag
+
+
+" cluster which contains the above two elements
+syn cluster sgmlRegionCluster contains=sgmlRegion,sgmlEmptyRegion,sgmlAbbrRegion
+
+
+" &entities; compare with dtd
+syn match   sgmlEntity		       "&[^; \t]*;" contains=sgmlEntityPunct
+syn match   sgmlEntityPunct  contained "[&.;]"
+
+
+" The real comments (this implements the comments as defined by sgml,
+" but not all sgml pages actually conform to it. Errors are flagged.
+syn region  sgmlComment                start=+<!+        end=+>+ contains=sgmlCommentPart,sgmlString,sgmlCommentError,sgmlTodo
+syn keyword sgmlTodo         contained TODO FIXME XXX display
+syn match   sgmlCommentError contained "[^><!]"
+syn region  sgmlCommentPart  contained start=+--+        end=+--+
+
+
+" CData sections
+"
+" PROVIDES: @sgmlCdataHook
+"
+syn region    sgmlCdata
+    \ start=+<!\[CDATA\[+
+    \ end=+]]>+
+    \ contains=sgmlCdataStart,sgmlCdataEnd,@sgmlCdataHook
+    \ keepend
+    \ extend
+" using the following line instead leads to corrupt folding at CDATA regions
+" syn match    sgmlCdata      +<!\[CDATA\[\_.\{-}]]>+  contains=sgmlCdataStart,sgmlCdataEnd,@sgmlCdataHook
+syn match    sgmlCdataStart +<!\[CDATA\[+  contained contains=sgmlCdataCdata
+syn keyword  sgmlCdataCdata CDATA          contained
+syn match    sgmlCdataEnd   +]]>+          contained
+
+
+" Processing instructions
+" This allows "?>" inside strings -- good idea?
+syn region  sgmlProcessing matchgroup=sgmlProcessingDelim start="<?" end="?>" contains=sgmlAttrib,sgmlEqualValue
+
+
+" DTD -- we use dtd.vim here
+syn region  sgmlDocType matchgroup=sgmlDocTypeDecl start="\c<!DOCTYPE"he=s+2,rs=s+2 end=">" contains=sgmlDocTypeKeyword,sgmlInlineDTD,sgmlString
+syn keyword sgmlDocTypeKeyword contained DOCTYPE PUBLIC SYSTEM
+syn region  sgmlInlineDTD contained start="\[" end="]" contains=@sgmlDTD
+syn include @sgmlDTD <sfile>:p:h/dtd.vim
+
+
+" synchronizing
+" TODO !!! to be improved !!!
+
+syn sync match sgmlSyncDT grouphere  sgmlDocType +\_.\(<!DOCTYPE\)\@=+
+" syn sync match sgmlSyncDT groupthere  NONE       +]>+
+
+syn sync match sgmlSync grouphere   sgmlRegion  +\_.\(<[^ /!?>"']\+\)\@=+
+" syn sync match sgmlSync grouphere  sgmlRegion "<[^ /!?>"']*>"
+syn sync match sgmlSync groupthere  sgmlRegion  +</[^ /!?>"']\+>+
+
+syn sync minlines=100
+
+
+" The default highlighting.
+hi def link sgmlTodo			Todo
+hi def link sgmlTag			Function
+hi def link sgmlEndTag			Identifier
+" SGML specifig
+hi def link sgmlAbbrEndTag		Identifier
+hi def link sgmlEmptyTag		Function
+hi def link sgmlEntity			Statement
+hi def link sgmlEntityPunct		Type
+
+hi def link sgmlAttribPunct		Comment
+hi def link sgmlAttrib			Type
+
+hi def link sgmlValue			String
+hi def link sgmlString			String
+hi def link sgmlComment			Comment
+hi def link sgmlCommentPart		Comment
+hi def link sgmlCommentError		Error
+hi def link sgmlError			Error
+
+hi def link sgmlProcessingDelim		Comment
+hi def link sgmlProcessing		Type
+
+hi def link sgmlCdata			String
+hi def link sgmlCdataCdata		Statement
+hi def link sgmlCdataStart		Type
+hi def link sgmlCdataEnd		Type
+
+hi def link sgmlDocTypeDecl		Function
+hi def link sgmlDocTypeKeyword		Statement
+hi def link sgmlInlineDTD		Function
+hi def link sgmlUnicodeNumberAttr	Number
+hi def link sgmlUnicodeSpecifierAttr	SpecialChar
+hi def link sgmlUnicodeNumberData	Number
+hi def link sgmlUnicodeSpecifierData	SpecialChar
+
+let b:current_syntax = "sgml"
+
+let &cpo = s:sgml_cpo_save
+unlet s:sgml_cpo_save
+
+" vim: ts=8
--- /dev/null
+++ b/lib/vimfiles/syntax/sgmldecl.vim
@@ -1,0 +1,79 @@
+" Vim syntax file
+" Language:	SGML (SGML Declaration <!SGML ...>)
+" Last Change: jueves, 28 de diciembre de 2000, 13:51:44 CLST
+" Maintainer: "Daniel A. Molina W." <sickd@linux-chile.org>
+" You can modify and maintain this file, in other case send comments
+" the maintainer email address.
+
+" For version 5.x: Clear all syntax items
+" For version 6.x: Quit when a syntax file was already loaded
+if version < 600
+  syntax clear
+elseif exists("b:current_syntax")
+  finish
+endif
+
+syn case ignore
+
+syn region	sgmldeclDeclBlock	transparent start=+<!SGML+ end=+>+
+syn region	sgmldeclTagBlock	transparent start=+<+ end=+>+
+					\ contains=ALLBUT,
+					\ @sgmlTagError,@sgmlErrInTag
+syn region	sgmldeclComment		contained start=+--+ end=+--+
+
+syn keyword	sgmldeclDeclKeys	SGML CHARSET CAPACITY SCOPE SYNTAX
+					\ FEATURES
+
+syn keyword	sgmldeclTypes		BASESET DESCSET DOCUMENT NAMING DELIM
+					\ NAMES QUANTITY SHUNCHAR DOCTYPE
+					\ ELEMENT ENTITY ATTLIST NOTATION
+					\ TYPE
+
+syn keyword	sgmldeclStatem		CONTROLS FUNCTION NAMECASE MINIMIZE
+					\ LINK OTHER APPINFO REF ENTITIES
+
+syn keyword sgmldeclVariables	TOTALCAP GRPCAP ENTCAP DATATAG OMITTAG RANK
+					\ SIMPLE IMPLICIT EXPLICIT CONCUR SUBDOC FORMAL ATTCAP
+					\ ATTCHCAP AVGRPCAP ELEMCAP ENTCHCAP IDCAP IDREFCAP
+					\ SHORTTAG
+
+syn match	sgmldeclNConst		contained +[0-9]\++
+
+syn region	sgmldeclString		contained start=+"+ end=+"+
+
+syn keyword	sgmldeclBool		YES NO
+
+syn keyword	sgmldeclSpecial		SHORTREF SGMLREF UNUSED NONE GENERAL
+					\ SEEALSO ANY
+
+syn sync lines=250
+
+
+" Define the default highlighting.
+" For version 5.7 and earlier: only when not done already
+" For version 5.8 and later: only when an item doesn't have highlighting yet
+if version >= 508 || !exists("did_sgmldecl_syntax_init")
+  if version < 508
+    let did_sgmldecl_syntax_init = 1
+    command -nargs=+ HiLink hi link <args>
+  else
+    command -nargs=+ HiLink hi def link <args>
+  endif
+
+      HiLink	sgmldeclDeclKeys	Keyword
+      HiLink	sgmldeclTypes		Type
+      HiLink	sgmldeclConst		Constant
+      HiLink	sgmldeclNConst		Constant
+      HiLink	sgmldeclString		String
+      HiLink	sgmldeclDeclBlock	Normal
+      HiLink	sgmldeclBool		Boolean
+      HiLink	sgmldeclSpecial		Special
+      HiLink	sgmldeclComment		Comment
+      HiLink	sgmldeclStatem		Statement
+	  HiLink	sgmldeclVariables	Type
+
+  delcommand HiLink
+endif
+
+let b:current_syntax = "sgmldecl"
+" vim:set tw=78 ts=4:
--- /dev/null
+++ b/lib/vimfiles/syntax/sgmllnx.vim
@@ -1,0 +1,68 @@
+" Vim syntax file
+" Language:	SGML-linuxdoc (supported by old sgmltools-1.x)
+"		(for more information, visit www.sgmltools.org)
+" Maintainer:	Nam SungHyun <namsh@kldp.org>
+" Last Change:	2001 Apr 26
+
+" For version 5.x: Clear all syntax items
+" For version 6.x: Quit when a syntax file was already loaded
+if version < 600
+  syntax clear
+elseif exists("b:current_syntax")
+  finish
+endif
+
+syn case ignore
+
+" tags
+syn region sgmllnxEndTag	start=+</+    end=+>+	contains=sgmllnxTagN,sgmllnxTagError
+syn region sgmllnxTag	start=+<[^/]+ end=+>+	contains=sgmllnxTagN,sgmllnxTagError
+syn match  sgmllnxTagN	contained +<\s*[-a-zA-Z0-9]\++ms=s+1	contains=sgmllnxTagName
+syn match  sgmllnxTagN	contained +</\s*[-a-zA-Z0-9]\++ms=s+2	contains=sgmllnxTagName
+
+syn region sgmllnxTag2	start=+<\s*[a-zA-Z]\+/+ keepend end=+/+	contains=sgmllnxTagN2
+syn match  sgmllnxTagN2	contained +/.*/+ms=s+1,me=e-1
+
+syn region sgmllnxSpecial	oneline start="&" end=";"
+
+" tag names
+syn keyword sgmllnxTagName contained article author date toc title sect verb
+syn keyword sgmllnxTagName contained abstract tscreen p itemize item enum
+syn keyword sgmllnxTagName contained descrip quote htmlurl code ref
+syn keyword sgmllnxTagName contained tt tag bf
+syn match   sgmllnxTagName contained "sect\d\+"
+
+" Comments
+syn region sgmllnxComment start=+<!--+ end=+-->+
+syn region sgmllnxDocType start=+<!doctype+ end=+>+
+
+" Define the default highlighting.
+" For version 5.7 and earlier: only when not done already
+" For version 5.8 and later: only when an item doesn't have highlighting yet
+if version >= 508 || !exists("did_sgmllnx_syn_inits")
+  if version < 508
+    let did_sgmllnx_syn_inits = 1
+    command -nargs=+ HiLink hi link <args>
+  else
+    command -nargs=+ HiLink hi def link <args>
+  endif
+
+  HiLink sgmllnxTag2	    Function
+  HiLink sgmllnxTagN2	    Function
+  HiLink sgmllnxTag	    Special
+  HiLink sgmllnxEndTag	    Special
+  HiLink sgmllnxParen	    Special
+  HiLink sgmllnxEntity	    Type
+  HiLink sgmllnxDocEnt	    Type
+  HiLink sgmllnxTagName	    Statement
+  HiLink sgmllnxComment	    Comment
+  HiLink sgmllnxSpecial	    Special
+  HiLink sgmllnxDocType	    PreProc
+  HiLink sgmllnxTagError    Error
+
+  delcommand HiLink
+endif
+
+let b:current_syntax = "sgmllnx"
+
+" vim:set tw=78 ts=8 sts=2 sw=2 noet:
--- /dev/null
+++ b/lib/vimfiles/syntax/sh.vim
@@ -1,0 +1,564 @@
+" Vim syntax file
+" Language:		shell (sh) Korn shell (ksh) bash (sh)
+" Maintainer:		Dr. Charles E. Campbell, Jr.  <NdrOchipS@PcampbellAfamily.Mbiz>
+" Previous Maintainer:	Lennart Schultz <Lennart.Schultz@ecmwf.int>
+" Last Change:		Dec 12, 2006
+" Version:		89
+" URL:		http://mysite.verizon.net/astronaut/vim/index.html#vimlinks_syntax
+"
+" Using the following VIM variables: {{{1
+" g:is_bash		if none of the previous three variables are
+"		defined, then if g:is_bash is set enhance with
+"		bash syntax highlighting
+" g:is_kornshell	if neither b:is_kornshell or b:is_bash is
+"		defined, then if g:is_kornshell is set
+"		enhance with kornshell/POSIX syntax highlighting
+" g:is_posix                    this variable is the same as g:is_kornshell
+" g:sh_fold_enabled	if non-zero, syntax folding is enabled
+" g:sh_minlines		sets up syn sync minlines (dflt: 200)
+" g:sh_maxlines		sets up syn sync maxlines (dflt: 2x sh_minlines)
+"
+" This file includes many ideas from �ric Brunet (eric.brunet@ens.fr)
+
+" For version 5.x: Clear all syntax items {{{1
+" For version 6.x: Quit when a syntax file was already loaded
+if version < 600
+  syntax clear
+elseif exists("b:current_syntax")
+  finish
+endif
+
+" handling /bin/sh with is_kornshell/is_sh {{{1
+" b:is_sh is set when "#! /bin/sh" is found;
+" However, it often is just a masquerade by bash (typically Linux)
+" or kornshell (typically workstations with Posix "sh").
+" So, when the user sets "is_bash" or "is_kornshell",
+" a b:is_sh is converted into b:is_bash/b:is_kornshell,
+" respectively.
+if !exists("b:is_kornshell") && !exists("b:is_bash")
+  if exists("g:is_posix") && !exists("g:is_kornshell")
+   let g:is_kornshell= g:is_posix
+  endif
+  if exists("g:is_kornshell")
+    let b:is_kornshell= 1
+    if exists("b:is_sh")
+      unlet b:is_sh
+    endif
+  elseif exists("g:is_bash")
+    let b:is_bash= 1
+    if exists("b:is_sh")
+      unlet b:is_sh
+    endif
+  else
+    let b:is_sh= 1
+  endif
+endif
+
+" set up default g:sh_fold_enabled {{{1
+if !exists("g:sh_fold_enabled")
+ let g:sh_fold_enabled= 0
+elseif g:sh_fold_enabled != 0 && !has("folding")
+ let g:sh_fold_enabled= 0
+ echomsg "Ignoring g:sh_fold_enabled=".g:sh_fold_enabled."; need to re-compile vim for +fold support"
+endif
+if g:sh_fold_enabled && &fdm == "manual"
+ set fdm=syntax
+endif
+
+" sh syntax is case sensitive {{{1
+syn case match
+
+" Clusters: contains=@... clusters {{{1
+"==================================
+syn cluster shCaseEsacList	contains=shCaseStart,shCase,shCaseBar,shCaseIn,shComment,shDeref,shDerefSimple,shCaseCommandSub,shCaseExSingleQuote,shCaseSingleQuote,shCaseDoubleQuote,shCtrlSeq
+syn cluster shCaseList	contains=@shCommandSubList,shCaseEsac,shColon,shCommandSub,shCommandSub,shComment,shDo,shEcho,shExpr,shFor,shHereDoc,shIf,shRedir,shSetList,shSource,shStatement,shVariable,shCtrlSeq
+syn cluster shColonList	contains=@shCaseList
+syn cluster shCommandSubList	contains=shArithmetic,shDeref,shDerefSimple,shNumber,shOperator,shPosnParm,shExSingleQuote,shSingleQuote,shDoubleQuote,shStatement,shVariable,shSubSh,shAlias,shTest,shCtrlSeq
+syn cluster shCurlyList	contains=shNumber,shComma,shDeref,shDerefSimple,shDerefSpecial
+syn cluster shDblQuoteList	contains=shCommandSub,shDeref,shDerefSimple,shPosnParm,shExSingleQuote,shCtrlSeq,shSpecial
+syn cluster shDerefList	contains=shDeref,shDerefSimple,shDerefVar,shDerefSpecial,shDerefWordError,shDerefPPS
+syn cluster shDerefVarList	contains=shDerefOp,shDerefVarArray,shDerefOpError
+syn cluster shEchoList	contains=shArithmetic,shCommandSub,shDeref,shDerefSimple,shExpr,shExSingleQuote,shSingleQuote,shDoubleQuote,shCtrlSeq
+syn cluster shExprList1	contains=shCharClass,shNumber,shOperator,shExSingleQuote,shSingleQuote,shDoubleQuote,shExpr,shDblBrace,shDeref,shDerefSimple,shCtrlSeq
+syn cluster shExprList2	contains=@shExprList1,@shCaseList,shTest
+syn cluster shFunctionList	contains=@shCommandSubList,shCaseEsac,shColon,shCommandSub,shCommandSub,shComment,shDo,shEcho,shExpr,shFor,shHereDoc,shIf,shRedir,shSetList,shSource,shStatement,shVariable,shOperator,shFunctionStart,shCtrlSeq
+if exists("b:is_kornshell") || exists("b:is_bash")
+ syn cluster shFunctionList	add=shDblBrace,shDblParen
+endif
+syn cluster shHereBeginList	contains=@shCommandSubList
+syn cluster shHereList	contains=shBeginHere,shHerePayload
+syn cluster shHereListDQ	contains=shBeginHere,@shDblQuoteList,shHerePayload
+syn cluster shIdList	contains=shCommandSub,shWrapLineOperator,shIdWhiteSpace,shDeref,shDerefSimple,shRedir,shExSingleQuote,shSingleQuote,shDoubleQuote,shExpr,shCtrlSeq
+syn cluster shLoopList	contains=@shCaseList,shTestOpr,shExpr,shDblBrace,shConditional,shCaseEsac,shTest
+syn cluster shSubShList	contains=@shCaseList,shOperator
+syn cluster shTestList	contains=shCharClass,shComment,shCommandSub,shDeref,shDerefSimple,shDoubleQuote,shExpr,shExpr,shNumber,shOperator,shExSingleQuote,shSingleQuote,shTestOpr,shTest,shCtrlSeq
+
+
+" Echo: {{{1
+" ====
+" This one is needed INSIDE a CommandSub, so that `echo bla` be correct
+syn region shEcho matchgroup=shStatement start="\<echo\>"  skip="\\$" matchgroup=shOperator end="$" matchgroup=NONE end="[<>;&|()]"me=e-1 end="\d[<>]"me=e-2 end="#"me=e-1 contains=@shEchoList
+syn region shEcho matchgroup=shStatement start="\<print\>" skip="\\$" matchgroup=shOperator end="$" matchgroup=NONE end="[<>;&|()]"me=e-1 end="\d[<>]"me=e-2 end="#"me=e-1 contains=@shEchoList
+
+" This must be after the strings, so that bla \" be correct
+syn region shEmbeddedEcho contained matchgroup=shStatement start="\<print\>" skip="\\$" matchgroup=shOperator end="$" matchgroup=NONE end="[<>;&|`)]"me=e-1 end="\d[<>]"me=e-2 end="#"me=e-1 contains=shNumber,shExSingleQuote,shSingleQuote,shDeref,shDerefSimple,shSpecialVar,shOperator,shDoubleQuote,shCharClass,shCtrlSeq
+
+" Alias: {{{1
+" =====
+if exists("b:is_kornshell") || exists("b:is_bash")
+ syn match shStatement "\<alias\>"
+ syn region shAlias matchgroup=shStatement start="\<alias\>\s\+\(\w\+\)\@=" skip="\\$" end="\>\|`"
+ syn region shAlias matchgroup=shStatement start="\<alias\>\s\+\(\w\+=\)\@=" skip="\\$" end="="
+endif
+
+" Error Codes: {{{1
+" ============
+syn match   shDoError "\<done\>"
+syn match   shIfError "\<fi\>"
+syn match   shInError "\<in\>"
+syn match   shCaseError ";;"
+syn match   shEsacError "\<esac\>"
+syn match   shCurlyError "}"
+syn match   shParenError ")"
+if exists("b:is_kornshell")
+ syn match     shDTestError "]]"
+endif
+syn match     shTestError "]"
+
+" Options Interceptor: {{{1
+" ====================
+syn match   shOption  "\s[\-+][a-zA-Z0-9]\+\>"ms=s+1
+syn match   shOption  "\s--[^ \t$`'"|]\+"ms=s+1
+
+" File Redirection Highlighted As Operators: {{{1
+"===========================================
+syn match      shRedir	"\d\=>\(&[-0-9]\)\="
+syn match      shRedir	"\d\=>>-\="
+syn match      shRedir	"\d\=<\(&[-0-9]\)\="
+syn match      shRedir	"\d<<-\="
+
+" Operators: {{{1
+" ==========
+syn match   shOperator	"<<\|>>"		contained
+syn match   shOperator	"[!&;|]"
+syn match   shOperator	"\[[[^:]\|\]]"
+syn match   shOperator	"!\=="		skipwhite nextgroup=shPattern
+syn match   shPattern	"\<\S\+\())\)\@="	contained contains=shExSingleQuote,shSingleQuote,shDoubleQuote,shDeref
+
+" Subshells: {{{1
+" ==========
+syn region shExpr  transparent matchgroup=shExprRegion  start="{" end="}"	contains=@shExprList2
+syn region shSubSh transparent matchgroup=shSubShRegion start="(" end=")"	contains=@shSubShList
+
+" Tests: {{{1
+"=======
+"syn region  shExpr transparent matchgroup=shRange start="\[" skip=+\\\\\|\\$+ end="\]" contains=@shTestList
+syn region shExpr	matchgroup=shRange start="\[" skip=+\\\\\|\\$+ end="\]" contains=@shTestList
+syn region shTest	transparent matchgroup=shStatement start="\<test\>" skip=+\\\\\|\\$+ matchgroup=NONE end="[;&|]"me=e-1 end="$" contains=@shExprList1
+syn match  shTestOpr	contained	"<=\|>=\|!=\|==\|-.\>\|-\(nt\|ot\|ef\|eq\|ne\|lt\|le\|gt\|ge\)\>\|[!<>]"
+syn match  shTestOpr	contained	'=' skipwhite nextgroup=shTestDoubleQuote,shTestSingleQuote,shTestPattern
+syn match  shTestPattern	contained	'\w\+'
+syn match  shTestDoubleQuote	contained	'"[^"]*"'
+syn match  shTestSingleQuote	contained	'\\.'
+syn match  shTestSingleQuote	contained	"'[^']*'"
+if exists("b:is_kornshell") || exists("b:is_bash")
+ syn region  shDblBrace matchgroup=Delimiter start="\[\[" skip=+\\\\\|\\$+ end="\]\]"	contains=@shTestList
+ syn region  shDblParen matchgroup=Delimiter start="((" skip=+\\\\\|\\$+ end="))"	contains=@shTestList
+endif
+
+" Character Class In Range: {{{1
+" =========================
+syn match   shCharClass	contained	"\[:\(backspace\|escape\|return\|xdigit\|alnum\|alpha\|blank\|cntrl\|digit\|graph\|lower\|print\|punct\|space\|upper\|tab\):\]"
+
+" Loops: do, if, while, until {{{1
+" ======
+if g:sh_fold_enabled
+ syn region shDo	fold transparent matchgroup=shConditional start="\<do\>" matchgroup=shConditional end="\<done\>" contains=@shLoopList
+ syn region shIf	fold transparent matchgroup=shConditional start="\<if\>" matchgroup=shConditional end="\<;\_s*then\>" end="\<fi\>"   contains=@shLoopList,shDblBrace,shDblParen,shFunctionKey
+ syn region shFor	fold matchgroup=shLoop start="\<for\>" end="\<in\>" end="\<do\>"me=e-2	contains=@shLoopList,shDblParen skipwhite nextgroup=shCurlyIn
+else
+ syn region shDo	transparent matchgroup=shConditional start="\<do\>" matchgroup=shConditional end="\<done\>" contains=@shLoopList
+ syn region shIf	transparent matchgroup=shConditional start="\<if\>" matchgroup=shConditional end="\<;\_s*then\>" end="\<fi\>"   contains=@shLoopList,shDblBrace,shDblParen,shFunctionKey
+ syn region shFor	matchgroup=shLoop start="\<for\>" end="\<in\>" end="\<do\>"me=e-2	contains=@shLoopList,shDblParen skipwhite nextgroup=shCurlyIn
+endif
+if exists("b:is_kornshell") || exists("b:is_bash")
+ syn cluster shCaseList add=shRepeat
+ syn region shRepeat   matchgroup=shLoop   start="\<while\>" end="\<in\>" end="\<do\>"me=e-2	contains=@shLoopList,shDblParen,shDblBrace
+ syn region shRepeat   matchgroup=shLoop   start="\<until\>" end="\<in\>" end="\<do\>"me=e-2	contains=@shLoopList,shDblParen,shDblBrace
+ syn region shCaseEsac matchgroup=shConditional start="\<select\>" matchgroup=shConditional end="\<in\>" end="\<do\>" contains=@shLoopList
+else
+ syn region shRepeat   matchgroup=shLoop   start="\<while\>" end="\<do\>"me=e-2		contains=@shLoopList
+ syn region shRepeat   matchgroup=shLoop   start="\<until\>" end="\<do\>"me=e-2		contains=@shLoopList
+endif
+syn region shCurlyIn   contained	matchgroup=Delimiter start="{" end="}" contains=@shCurlyList
+syn match  shComma     contained	","
+
+" Case: case...esac {{{1
+" ====
+syn match   shCaseBar	contained skipwhite "[^|"`'()]\{-}|"hs=e		nextgroup=shCase,shCaseStart,shCaseBar,shComment,shCaseExSingleQuote,shCaseSingleQuote,shCaseDoubleQuote
+syn match   shCaseStart	contained skipwhite skipnl "("			nextgroup=shCase,shCaseBar
+syn region  shCase	contained skipwhite skipnl matchgroup=shSnglCase start="\([^#$()'" \t]\|\\.\)\{-})"ms=s,hs=e  end=";;" end="esac"me=s-1 contains=@shCaseList nextgroup=shCaseStart,shCase,shComment
+if g:sh_fold_enabled
+ syn region  shCaseEsac	fold matchgroup=shConditional start="\<case\>" end="\<esac\>"	contains=@shCaseEsacList
+else
+ syn region  shCaseEsac	matchgroup=shConditional start="\<case\>" end="\<esac\>"	contains=@shCaseEsacList
+endif
+syn keyword shCaseIn	contained skipwhite skipnl in			nextgroup=shCase,shCaseStart,shCaseBar,shComment,shCaseExSingleQuote,shCaseSingleQuote,shCaseDoubleQuote
+if exists("b:is_bash")
+ syn region  shCaseExSingleQuote	matchgroup=shOperator start=+\$'+ skip=+\\\\\|\\.+ end=+'+	contains=shStringSpecial,shSpecial	skipwhite skipnl nextgroup=shCaseBar	contained
+else
+ syn region  shCaseExSingleQuote	matchgroup=Error start=+\$'+ skip=+\\\\\|\\.+ end=+'+	contains=shStringSpecial	skipwhite skipnl nextgroup=shCaseBar	contained
+endif
+syn region  shCaseSingleQuote	matchgroup=shOperator start=+'+ end=+'+		contains=shStringSpecial		skipwhite skipnl nextgroup=shCaseBar	contained
+syn region  shCaseDoubleQuote	matchgroup=shOperator start=+"+ skip=+\\\\\|\\.+ end=+"+	contains=@shDblQuoteList,shStringSpecial	skipwhite skipnl nextgroup=shCaseBar	contained
+syn region  shCaseCommandSub	start=+`+ skip=+\\\\\|\\.+ end=+`+		contains=@shCommandSubList		skipwhite skipnl nextgroup=shCaseBar	contained
+
+" Misc: {{{1
+"======
+syn match   shWrapLineOperator "\\$"
+syn region  shCommandSub   start="`" skip="\\\\\|\\." end="`" contains=@shCommandSubList
+
+" $() and $(()): {{{1
+" $(..) is not supported by sh (Bourne shell).  However, apparently
+" some systems (HP?) have as their /bin/sh a (link to) Korn shell
+" (ie. Posix compliant shell).  /bin/ksh should work for those
+" systems too, however, so the following syntax will flag $(..) as
+" an Error under /bin/sh.  By consensus of vimdev'ers!
+if exists("b:is_kornshell") || exists("b:is_bash")
+ syn region shCommandSub matchgroup=shCmdSubRegion start="\$("  skip='\\\\\|\\.' end=")"  contains=@shCommandSubList
+ syn region shArithmetic matchgroup=shArithRegion  start="\$((" skip='\\\\\|\\.' end="))" contains=@shCommandSubList
+ syn match  shSkipInitWS contained	"^\s\+"
+else
+ syn region shCommandSub matchgroup=Error start="\$(" end=")" contains=@shCommandSubList
+endif
+
+if exists("b:is_bash")
+ syn cluster shCommandSubList add=bashSpecialVariables,bashStatement
+ syn cluster shCaseList add=bashAdminStatement,bashStatement
+ syn keyword bashSpecialVariables contained BASH BASH_ENV BASH_VERSINFO BASH_VERSION CDPATH DIRSTACK EUID FCEDIT FIGNORE GLOBIGNORE GROUPS HISTCMD HISTCONTROL HISTFILE HISTFILESIZE HISTIGNORE HISTSIZE HOME HOSTFILE HOSTNAME HOSTTYPE IFS IGNOREEOF INPUTRC LANG LC_ALL LC_COLLATE LC_MESSAGES LINENO MACHTYPE MAIL MAILCHECK MAILPATH OLDPWD OPTARG OPTERR OPTIND OSTYPE PATH PIPESTATUS PPID PROMPT_COMMAND PS1 PS2 PS3 PS4 PWD RANDOM REPLY SECONDS SHELLOPTS SHLVL TIMEFORMAT TIMEOUT UID auto_resume histchars
+ syn keyword bashStatement chmod clear complete du egrep expr fgrep find gnufind gnugrep grep install less ls mkdir mv rm rmdir rpm sed sleep sort strip tail touch
+ syn keyword bashAdminStatement daemon killall killproc nice reload restart start status stop
+endif
+
+if exists("b:is_kornshell")
+ syn cluster shCommandSubList add=kshSpecialVariables,kshStatement
+ syn cluster shCaseList add=kshStatement
+ syn keyword kshSpecialVariables contained CDPATH COLUMNS EDITOR ENV ERRNO FCEDIT FPATH HISTFILE HISTSIZE HOME IFS LINENO LINES MAIL MAILCHECK MAILPATH OLDPWD OPTARG OPTIND PATH PPID PS1 PS2 PS3 PS4 PWD RANDOM REPLY SECONDS SHELL TMOUT VISUAL
+ syn keyword kshStatement cat chmod clear cp du egrep expr fgrep find grep install killall less ls mkdir mv nice printenv rm rmdir sed sort strip stty tail touch tput
+endif
+
+syn match   shSource	"^\.\s"
+syn match   shSource	"\s\.\s"
+syn region  shColon	start="^\s*:" end="$\|" end="#"me=e-1 contains=@shColonList
+
+" String And Character Constants: {{{1
+"================================
+syn match   shNumber	"-\=\<\d\+\>#\="
+syn match   shCtrlSeq	"\\\d\d\d\|\\[abcfnrtv0]"		contained
+if exists("b:is_bash")
+ syn match   shSpecial	"\\\o\o\o\|\\x\x\x\|\\c.\|\\[abefnrtv]"	contained
+endif
+if exists("b:is_bash")
+ syn region  shExSingleQuote	matchgroup=shOperator start=+\$'+ skip=+\\\\\|\\.+ end=+'+	contains=shStringSpecial,shSpecial
+else
+ syn region  shExSingleQuote	matchGroup=Error start=+\$'+ skip=+\\\\\|\\.+ end=+'+	contains=shStringSpecial
+endif
+syn region  shSingleQuote	matchgroup=shOperator start=+'+ end=+'+		contains=shStringSpecial,@Spell
+syn region  shDoubleQuote	matchgroup=shOperator start=+"+ skip=+\\"+ end=+"+	contains=@shDblQuoteList,shStringSpecial,@Spell
+syn match   shStringSpecial	"[^[:print:]]"	contained
+syn match   shStringSpecial	"\%(\\\\\)*\\[\\"'`$()#]"
+syn match   shSpecial	"[^\\]\zs\%(\\\\\)*\\[\\"'`$()#]"
+syn match   shSpecial	"^\%(\\\\\)*\\[\\"'`$()#]"
+
+" Comments: {{{1
+"==========
+syn cluster    shCommentGroup	contains=shTodo,@Spell
+syn keyword    shTodo	contained	COMBAK FIXME TODO XXX
+syn match      shComment	"^\s*\zs#.*$"	contains=@shCommentGroup
+syn match      shComment	"#.*$"	contains=@shCommentGroup
+
+" Here Documents: {{{1
+" =========================================
+if version < 600
+ syn region shHereDoc matchgroup=shRedir start="<<\s*\**END[a-zA-Z_0-9]*\**"  matchgroup=shRedir end="^END[a-zA-Z_0-9]*$" contains=@shDblQuoteList
+ syn region shHereDoc matchgroup=shRedir start="<<-\s*\**END[a-zA-Z_0-9]*\**" matchgroup=shRedir end="^\s*END[a-zA-Z_0-9]*$" contains=@shDblQuoteList
+ syn region shHereDoc matchgroup=shRedir start="<<\s*\**EOF\**"	matchgroup=shRedir	end="^EOF$"	contains=@shDblQuoteList
+ syn region shHereDoc matchgroup=shRedir start="<<-\s*\**EOF\**" matchgroup=shRedir	end="^\s*EOF$"	contains=@shDblQuoteList
+ syn region shHereDoc matchgroup=shRedir start="<<\s*\**\.\**"	matchgroup=shRedir	end="^\.$"	contains=@shDblQuoteList
+ syn region shHereDoc matchgroup=shRedir start="<<-\s*\**\.\**"	matchgroup=shRedir	end="^\s*\.$"	contains=@shDblQuoteList
+
+elseif g:sh_fold_enabled
+ syn region shHereDoc matchgroup=shRedir fold start="<<\s*\z(\S*\)"		matchgroup=shRedir end="^\z1\s*$"	contains=@shDblQuoteList
+ syn region shHereDoc matchgroup=shRedir fold start="<<\s*\"\z(\S*\)\""		matchgroup=shRedir end="^\z1\s*$"
+ syn region shHereDoc matchgroup=shRedir fold start="<<\s*'\z(\S*\)'"		matchgroup=shRedir end="^\z1\s*$"
+ syn region shHereDoc matchgroup=shRedir fold start="<<-\s*\z(\S*\)"		matchgroup=shRedir end="^\s*\z1\s*$"	contains=@shDblQuoteList
+ syn region shHereDoc matchgroup=shRedir fold start="<<-\s*\"\z(\S*\)\""		matchgroup=shRedir end="^\s*\z1\s*$"
+ syn region shHereDoc matchgroup=shRedir fold start="<<-\s*'\z(\S*\)'"		matchgroup=shRedir end="^\s*\z1\s*$"
+ syn region shHereDoc matchgroup=shRedir fold start="<<\s*\\\_$\_s*\z(\S*\)"		matchgroup=shRedir end="^\z1\s*$"
+ syn region shHereDoc matchgroup=shRedir fold start="<<\s*\\\_$\_s*\"\z(\S*\)\""	matchgroup=shRedir end="^\z1\s*$"
+ syn region shHereDoc matchgroup=shRedir fold start="<<-\s*\\\_$\_s*'\z(\S*\)'"		matchgroup=shRedir end="^\s*\z1\s*$"
+ syn region shHereDoc matchgroup=shRedir fold start="<<-\s*\\\_$\_s*\z(\S*\)"		matchgroup=shRedir end="^\s*\z1\s*$"
+ syn region shHereDoc matchgroup=shRedir fold start="<<-\s*\\\_$\_s*\"\z(\S*\)\""	matchgroup=shRedir end="^\s*\z1\s*$"
+ syn region shHereDoc matchgroup=shRedir fold start="<<\s*\\\_$\_s*'\z(\S*\)'"		matchgroup=shRedir end="^\z1\s*$"
+ syn region shHereDoc matchgroup=shRedir fold start="<<\\\z(\S*\)"		matchgroup=shRedir end="^\z1\s*$"
+
+else
+ syn region shHereDoc matchgroup=shRedir start="<<\s*\\\=\z(\S*\)"	matchgroup=shRedir end="^\z1\s*$"    contains=@shDblQuoteList
+ syn region shHereDoc matchgroup=shRedir start="<<\s*\"\z(\S*\)\""	matchgroup=shRedir end="^\z1\s*$"
+ syn region shHereDoc matchgroup=shRedir start="<<-\s*\z(\S*\)"		matchgroup=shRedir end="^\s*\z1\s*$" contains=@shDblQuoteList
+ syn region shHereDoc matchgroup=shRedir start="<<-\s*'\z(\S*\)'"	matchgroup=shRedir end="^\s*\z1\s*$"
+ syn region shHereDoc matchgroup=shRedir start="<<\s*'\z(\S*\)'"	matchgroup=shRedir end="^\z1\s*$"
+ syn region shHereDoc matchgroup=shRedir start="<<-\s*\"\z(\S*\)\""	matchgroup=shRedir end="^\s*\z1\s*$"
+ syn region shHereDoc matchgroup=shRedir start="<<\s*\\\_$\_s*\z(\S*\)"	matchgroup=shRedir end="^\z1\s*$"
+ syn region shHereDoc matchgroup=shRedir start="<<-\s*\\\_$\_s*\z(\S*\)"	matchgroup=shRedir end="^\s*\z1\s*$"
+ syn region shHereDoc matchgroup=shRedir start="<<-\s*\\\_$\_s*'\z(\S*\)'"	matchgroup=shRedir end="^\s*\z1\s*$"
+ syn region shHereDoc matchgroup=shRedir start="<<\s*\\\_$\_s*'\z(\S*\)'"	matchgroup=shRedir end="^\z1\s*$"
+ syn region shHereDoc matchgroup=shRedir start="<<\s*\\\_$\_s*\"\z(\S*\)\""	matchgroup=shRedir end="^\z1\s*$"
+ syn region shHereDoc matchgroup=shRedir start="<<-\s*\\\_$\_s*\"\z(\S*\)\""	matchgroup=shRedir end="^\s*\z1\s*$"
+ syn region shHereDoc matchgroup=shRedir start="<<\\\z(\S*\)"		matchgroup=shRedir end="^\z1\s*$"
+endif
+
+" Here Strings: {{{1
+" =============
+if exists("b:is_bash")
+ syn match shRedir "<<<"
+endif
+
+" Identifiers: {{{1
+"=============
+syn match  shVariable "\<\([bwglsav]:\)\=[a-zA-Z0-9.!@_%+,]*\ze="	nextgroup=shSetIdentifier
+syn match  shIdWhiteSpace  contained	"\s"
+syn match  shSetIdentifier contained	"="	nextgroup=shPattern,shDeref,shDerefSimple,shDoubleQuote,shSingleQuote,shExSingleQuote
+if exists("b:is_bash")
+  syn region shSetList matchgroup=shSet start="\<\(declare\|typeset\|local\|export\|unset\)\>\ze[^/]" end="$"	matchgroup=shOperator end="\ze[|);&]"me=e-1 matchgroup=NONE end="#\|="me=e-1 contains=@shIdList
+  syn region shSetList matchgroup=shSet start="\<set\>[^/]"me=e-1 end="$" end="\\ze[|)]"		matchgroup=shOperator end="\ze[|);&]"me=e-1 matchgroup=NONE end="[#=]"me=e-1 contains=@shIdList
+  syn match  shSet "\<\(declare\|typeset\|local\|export\|set\|unset\)\>"
+elseif exists("b:is_kornshell")
+  syn region shSetList matchgroup=shSet start="\<\(typeset\|export\|unset\)\>\ze[^/]" end="$"		matchgroup=shOperator end="\ze[|);&]"me=e-1 matchgroup=NONE end="[#=]"me=e-1 contains=@shIdList
+  syn region shSetList matchgroup=shSet start="\<set\>\ze[^/]" end="$\|\ze[})]"			matchgroup=shOperator end="\ze[|);&]"me=e-1 matchgroup=NONE end="[#=]"me=e-1 contains=@shIdList
+  syn match  shSet "\<\(typeset\|set\|export\|unset\)\>"
+else
+  syn region shSetList matchgroup=shSet start="\<\(set\|export\|unset\)\>\ze[^/]" end="$\|\ze[|)]"	matchgroup=shOperator end="\ze[|);&]" matchgroup=NONE end="[#=]"me=e-1 contains=@shIdList
+  syn match  shStatement "\<\(set\|export\|unset\)\>"
+endif
+
+" Functions: {{{1
+syn keyword shFunctionKey function	skipwhite skipnl nextgroup=shFunctionTwo
+" COMBAK -- look at bash09.  function foo() (line#35) is folding 38 lines.  Not being terminated properly
+"syn match   shFunctionStart	"{"	contained
+if g:sh_fold_enabled
+ syn region shFunctionOne transparent fold	start="^\s*\h\w*\s*()\_s*\ze{"    matchgroup=shFunctionStart end="}"	contains=@shFunctionList			skipwhite skipnl nextgroup=shFunctionStart
+ syn region shFunctionTwo transparent fold	start="\h\w*\s*\%(()\)\=\_s*\ze{" matchgroup=shFunctionStart end="}"	contains=shFunctionKey,@shFunctionList contained	skipwhite skipnl nextgroup=shFunctionStart
+else
+ syn region shFunctionOne transparent	start="^\s*\h\w*\s*()\_s*\ze{"    matchgroup=shFunctionStart end="}"	contains=@shFunctionList
+ syn region shFunctionTwo transparent	start="\h\w*\s*\%(()\)\=\_s*\ze{" matchgroup=shFunctionStart end="}"	contains=shFunctionKey,@shFunctionList contained
+endif
+
+" Parameter Dereferencing: {{{1
+" ========================
+syn match  shDerefSimple	"\$\%(\h\w*\|\d\)"
+syn region shDeref	matchgroup=PreProc start="\${" end="}"	contains=@shDerefList,shDerefVarArray
+syn match  shDerefWordError	"[^}$[]"	contained
+syn match  shDerefSimple	"\$[-#*@!?]"
+syn match  shDerefSimple	"\$\$"
+if exists("b:is_bash") || exists("b:is_kornshell")
+ syn region shDeref	matchgroup=PreProc start="\${##\=" end="}"	contains=@shDerefList
+endif
+
+" bash: ${!prefix*} and ${#parameter}: {{{1
+" ====================================
+if exists("b:is_bash")
+ syn region shDeref	matchgroup=PreProc start="\${!" end="\*\=}"	contains=@shDerefList,shDerefOp
+ syn match  shDerefVar	contained	"{\@<=!\w\+"		nextgroup=@shDerefVarList
+endif
+
+syn match  shDerefSpecial	contained	"{\@<=[-*@?0]"		nextgroup=shDerefOp,shDerefOpError
+syn match  shDerefSpecial	contained	"\({[#!]\)\@<=[[:alnum:]*@_]\+"	nextgroup=@shDerefVarList,shDerefOp
+syn match  shDerefVar	contained	"{\@<=\w\+"		nextgroup=@shDerefVarList
+
+" sh ksh bash : ${var[... ]...}  array reference: {{{1
+syn region  shDerefVarArray   contained	matchgroup=shDeref start="\[" end="]"	contains=@shCommandSubList nextgroup=shDerefOp,shDerefOpError
+
+" Special ${parameter OPERATOR word} handling: {{{1
+" sh ksh bash : ${parameter:-word}    word is default value
+" sh ksh bash : ${parameter:=word}    assign word as default value
+" sh ksh bash : ${parameter:?word}    display word if parameter is null
+" sh ksh bash : ${parameter:+word}    use word if parameter is not null, otherwise nothing
+"    ksh bash : ${parameter#pattern}  remove small left  pattern
+"    ksh bash : ${parameter##pattern} remove large left  pattern
+"    ksh bash : ${parameter%pattern}  remove small right pattern
+"    ksh bash : ${parameter%%pattern} remove large right pattern
+syn cluster shDerefPatternList	contains=shDerefPattern,shDerefString
+syn match shDerefOpError	contained	":[[:punct:]]"
+syn match  shDerefOp	contained	":\=[-=?]"	nextgroup=@shDerefPatternList
+syn match  shDerefOp	contained	":\=+"	nextgroup=@shDerefPatternList
+if exists("b:is_bash") || exists("b:is_kornshell")
+ syn match  shDerefOp	contained	"#\{1,2}"	nextgroup=@shDerefPatternList
+ syn match  shDerefOp	contained	"%\{1,2}"	nextgroup=@shDerefPatternList
+ syn match  shDerefPattern	contained	"[^{}]\+"	contains=shDeref,shDerefSimple,shDerefPattern,shDerefString,shCommandSub,shDerefEscape nextgroup=shDerefPattern
+ syn region shDerefPattern	contained	start="{" end="}"	contains=shDeref,shDerefSimple,shDerefString,shCommandSub nextgroup=shDerefPattern
+ syn match  shDerefEscape	contained	'\%(\\\\\)*\\.'
+endif
+syn region shDerefString	contained	matchgroup=shOperator start=+'+ end=+'+		contains=shStringSpecial
+syn region shDerefString	contained	matchgroup=shOperator start=+"+ skip=+\\"+ end=+"+	contains=@shDblQuoteList,shStringSpecial
+syn match  shDerefString	contained	"\\["']"
+
+if exists("b:is_bash")
+ " bash : ${parameter:offset}
+ " bash : ${parameter:offset:length}
+ syn region shDerefOp	contained	start=":[$[:alnum:]_]"me=e-1 end=":"me=e-1 end="}"me=e-1 contains=@shCommandSubList nextgroup=shDerefPOL
+ syn match  shDerefPOL	contained	":[^}]\+"	contains=@shCommandSubList
+
+ " bash : ${parameter//pattern/string}
+ " bash : ${parameter//pattern}
+ syn match  shDerefPPS	contained	'/\{1,2}'	nextgroup=shDerefPPSleft
+ syn region shDerefPPSleft	contained	start='.'	skip=@\%(\\\)\/@ matchgroup=shDerefOp end='/' end='\ze}' nextgroup=shDerefPPSright contains=@shCommandSubList
+ syn region shDerefPPSright	contained	start='.'	end='\ze}'	contains=@shCommandSubList
+endif
+
+" Useful sh Keywords: {{{1
+" ===================
+syn keyword shStatement break cd chdir continue eval exec exit kill newgrp pwd read readonly return shift test trap ulimit umask wait
+syn keyword shConditional contained elif else then
+syn keyword shCondError elif else then
+
+" Useful ksh Keywords: {{{1
+" ====================
+if exists("b:is_kornshell") || exists("b:is_bash")
+ syn keyword shStatement autoload bg false fc fg functions getopts hash history integer jobs let nohup print printf r stop suspend time times true type unalias whence
+
+" Useful bash Keywords: {{{1
+" =====================
+ if exists("b:is_bash")
+  syn keyword shStatement bind builtin dirs disown enable help local logout popd pushd shopt source
+ else
+  syn keyword shStatement login newgrp
+ endif
+endif
+
+" Synchronization: {{{1
+" ================
+if !exists("sh_minlines")
+  let sh_minlines = 200
+endif
+if !exists("sh_maxlines")
+  let sh_maxlines = 2 * sh_minlines
+endif
+exec "syn sync minlines=" . sh_minlines . " maxlines=" . sh_maxlines
+syn sync match shCaseEsacSync	grouphere	shCaseEsac	"\<case\>"
+syn sync match shCaseEsacSync	groupthere	shCaseEsac	"\<esac\>"
+syn sync match shDoSync	grouphere	shDo	"\<do\>"
+syn sync match shDoSync	groupthere	shDo	"\<done\>"
+syn sync match shForSync	grouphere	shFor	"\<for\>"
+syn sync match shForSync	groupthere	shFor	"\<in\>"
+syn sync match shIfSync	grouphere	shIf	"\<if\>"
+syn sync match shIfSync	groupthere	shIf	"\<fi\>"
+syn sync match shUntilSync	grouphere	shRepeat	"\<until\>"
+syn sync match shWhileSync	grouphere	shRepeat	"\<while\>"
+
+" Default Highlighting: {{{1
+" =====================
+hi def link shArithRegion	shShellVariables
+hi def link shBeginHere	shRedir
+hi def link shCaseBar	shConditional
+hi def link shCaseCommandSub	shCommandSub
+hi def link shCaseDoubleQuote	shDoubleQuote
+hi def link shCaseIn	shConditional
+hi def link shCaseSingleQuote	shSingleQuote
+hi def link shCaseStart	shConditional
+hi def link shCmdSubRegion	shShellVariables
+hi def link shColon	shStatement
+hi def link shDerefOp	shOperator
+hi def link shDerefPOL	shDerefOp
+hi def link shDerefPPS	shDerefOp
+hi def link shDeref	shShellVariables
+hi def link shDerefSimple	shDeref
+hi def link shDerefSpecial	shDeref
+hi def link shDerefString	shDoubleQuote
+hi def link shDerefVar	shDeref
+hi def link shDoubleQuote	shString
+hi def link shEcho	shString
+hi def link shEmbeddedEcho	shString
+hi def link shExSingleQuote	shSingleQuote
+hi def link shFunctionStart	Delimiter
+hi def link shHereDoc	shString
+hi def link shHerePayload	shHereDoc
+hi def link shLoop	shStatement
+hi def link shOption	shCommandSub
+hi def link shPattern	shString
+hi def link shPosnParm	shShellVariables
+hi def link shRange	shOperator
+hi def link shRedir	shOperator
+hi def link shSingleQuote	shString
+hi def link shSource	shOperator
+hi def link shStringSpecial	shSpecial
+hi def link shSubShRegion	shOperator
+hi def link shTestOpr	shConditional
+hi def link shTestPattern	shString
+hi def link shTestDoubleQuote	shString
+hi def link shTestSingleQuote	shString
+hi def link shVariable	shSetList
+hi def link shWrapLineOperator	shOperator
+
+if exists("b:is_bash")
+  hi def link bashAdminStatement	shStatement
+  hi def link bashSpecialVariables	shShellVariables
+  hi def link bashStatement		shStatement
+  hi def link shFunctionParen		Delimiter
+  hi def link shFunctionDelim		Delimiter
+endif
+if exists("b:is_kornshell")
+  hi def link kshSpecialVariables	shShellVariables
+  hi def link kshStatement		shStatement
+  hi def link shFunctionParen		Delimiter
+endif
+
+hi def link shCaseError		Error
+hi def link shCondError		Error
+hi def link shCurlyError		Error
+hi def link shDerefError		Error
+hi def link shDerefOpError		Error
+hi def link shDerefWordError		Error
+hi def link shDoError		Error
+hi def link shEsacError		Error
+hi def link shIfError		Error
+hi def link shInError		Error
+hi def link shParenError		Error
+hi def link shTestError		Error
+if exists("b:is_kornshell")
+  hi def link shDTestError		Error
+endif
+
+hi def link shArithmetic		Special
+hi def link shCharClass		Identifier
+hi def link shSnglCase		Statement
+hi def link shCommandSub		Special
+hi def link shComment		Comment
+hi def link shConditional		Conditional
+hi def link shCtrlSeq		Special
+hi def link shExprRegion		Delimiter
+hi def link shFunctionKey		Function
+hi def link shFunctionName		Function
+hi def link shNumber		Number
+hi def link shOperator		Operator
+hi def link shRepeat		Repeat
+hi def link shSet		Statement
+hi def link shSetList		Identifier
+hi def link shShellVariables		PreProc
+hi def link shSpecial		Special
+hi def link shStatement		Statement
+hi def link shString		String
+hi def link shTodo		Todo
+hi def link shAlias		Identifier
+
+" Set Current Syntax: {{{1
+" ===================
+if exists("b:is_bash")
+ let b:current_syntax = "bash"
+elseif exists("b:is_kornshell")
+ let b:current_syntax = "ksh"
+else
+ let b:current_syntax = "sh"
+endif
+
+" vim: ts=16 fdm=marker
--- /dev/null
+++ b/lib/vimfiles/syntax/sicad.vim
@@ -1,0 +1,413 @@
+" Vim syntax file
+" Language:     SiCAD (procedure language)
+" Maintainer:   Zsolt Branyiczky <zbranyiczky@lmark.mgx.hu>
+" Last Change:  2003 May 11
+" URL:		http://lmark.mgx.hu:81/download/vim/sicad.vim
+
+" For version 5.x: Clear all syntax items
+" For version 6.x: Quit when a syntax file was already loaded
+if version < 600
+  syntax clear
+elseif exists("b:current_syntax")
+  finish
+endif
+
+" use SQL highlighting after 'sql' command
+if version >= 600
+  syn include @SQL syntax/sql.vim
+else
+  syn include @SQL <sfile>:p:h/sql.vim
+endif
+unlet b:current_syntax
+
+" spaces are used in (auto)indents since sicad hates tabulator characters
+if version >= 600
+  setlocal expandtab
+else
+  set expandtab
+endif
+
+" ignore case
+syn case ignore
+
+" most important commands - not listed by ausku
+syn keyword sicadStatement define
+syn keyword sicadStatement dialog
+syn keyword sicadStatement do
+syn keyword sicadStatement dop contained
+syn keyword sicadStatement end
+syn keyword sicadStatement enddo
+syn keyword sicadStatement endp
+syn keyword sicadStatement erroff
+syn keyword sicadStatement erron
+syn keyword sicadStatement exitp
+syn keyword sicadGoto      goto contained
+syn keyword sicadStatement hh
+syn keyword sicadStatement if
+syn keyword sicadStatement in
+syn keyword sicadStatement msgsup
+syn keyword sicadStatement out
+syn keyword sicadStatement padd
+syn keyword sicadStatement parbeg
+syn keyword sicadStatement parend
+syn keyword sicadStatement pdoc
+syn keyword sicadStatement pprot
+syn keyword sicadStatement procd
+syn keyword sicadStatement procn
+syn keyword sicadStatement psav
+syn keyword sicadStatement psel
+syn keyword sicadStatement psymb
+syn keyword sicadStatement ptrace
+syn keyword sicadStatement ptstat
+syn keyword sicadStatement set
+syn keyword sicadStatement sql contained
+syn keyword sicadStatement step
+syn keyword sicadStatement sys
+syn keyword sicadStatement ww
+
+" functions
+syn match sicadStatement "\<atan("me=e-1
+syn match sicadStatement "\<atan2("me=e-1
+syn match sicadStatement "\<cos("me=e-1
+syn match sicadStatement "\<dist("me=e-1
+syn match sicadStatement "\<exp("me=e-1
+syn match sicadStatement "\<log("me=e-1
+syn match sicadStatement "\<log10("me=e-1
+syn match sicadStatement "\<sin("me=e-1
+syn match sicadStatement "\<sqrt("me=e-1
+syn match sicadStatement "\<tanh("me=e-1
+syn match sicadStatement "\<x("me=e-1
+syn match sicadStatement "\<y("me=e-1
+syn match sicadStatement "\<v("me=e-1
+syn match sicadStatement "\<x%g\=p[0-9]\{1,2}\>"me=s+1
+syn match sicadStatement "\<y%g\=p[0-9]\{1,2}\>"me=s+1
+
+" logical operators
+syn match sicadOperator "\.and\."
+syn match sicadOperator "\.ne\."
+syn match sicadOperator "\.not\."
+syn match sicadOperator "\.eq\."
+syn match sicadOperator "\.ge\."
+syn match sicadOperator "\.gt\."
+syn match sicadOperator "\.le\."
+syn match sicadOperator "\.lt\."
+syn match sicadOperator "\.or\."
+syn match sicadOperator "\.eqv\."
+syn match sicadOperator "\.neqv\."
+
+" variable name
+syn match sicadIdentifier "%g\=[irpt][0-9]\{1,2}\>"
+syn match sicadIdentifier "%g\=l[0-9]\>"
+syn match sicadIdentifier "%g\=[irptl]("me=e-1
+syn match sicadIdentifier "%error\>"
+syn match sicadIdentifier "%nsel\>"
+syn match sicadIdentifier "%nvar\>"
+syn match sicadIdentifier "%scl\>"
+syn match sicadIdentifier "%wd\>"
+syn match sicadIdentifier "\$[irt][0-9]\{1,2}\>" contained
+
+" label
+syn match sicadLabel1 "^ *\.[a-z][a-z0-9]\{0,7} \+[^ ]"me=e-1
+syn match sicadLabel1 "^ *\.[a-z][a-z0-9]\{0,7}\*"me=e-1
+syn match sicadLabel2 "\<goto \.\=[a-z][a-z0-9]\{0,7}\>" contains=sicadGoto
+syn match sicadLabel2 "\<goto\.[a-z][a-z0-9]\{0,7}\>" contains=sicadGoto
+
+" boolean
+syn match sicadBoolean "\.[ft]\."
+" integer without sign
+syn match sicadNumber "\<[0-9]\+\>"
+" floating point number, with dot, optional exponent
+syn match sicadFloat "\<[0-9]\+\.[0-9]*\(e[-+]\=[0-9]\+\)\=\>"
+" floating point number, starting with a dot, optional exponent
+syn match sicadFloat "\.[0-9]\+\(e[-+]\=[0-9]\+\)\=\>"
+" floating point number, without dot, with exponent
+syn match sicadFloat "\<[0-9]\+e[-+]\=[0-9]\+\>"
+
+" without this extraString definition a ' ;  ' could stop the comment
+syn region sicadString_ transparent start=+'+ end=+'+ oneline contained
+" string
+syn region sicadString start=+'+ end=+'+ oneline
+
+" comments - nasty ones in sicad
+
+" - ' *  blabla' or ' *  blabla;'
+syn region sicadComment start="^ *\*" skip='\\ *$' end=";"me=e-1 end="$" contains=sicadString_
+" - ' .LABEL03 *  blabla' or ' .LABEL03 *  blabla;'
+syn region sicadComment start="^ *\.[a-z][a-z0-9]\{0,7} *\*" skip='\\ *$' end=";"me=e-1 end="$" contains=sicadLabel1,sicadString_
+" - '; * blabla' or '; * blabla;'
+syn region sicadComment start="; *\*"ms=s+1 skip='\\ *$' end=";"me=e-1 end="$" contains=sicadString_
+" - comments between docbeg and docend
+syn region sicadComment matchgroup=sicadStatement start="\<docbeg\>" end="\<docend\>"
+
+" catch \ at the end of line
+syn match sicadLineCont "\\ *$"
+
+" parameters in dop block - for the time being it is not used
+"syn match sicadParameter " [a-z][a-z0-9]*[=:]"me=e-1 contained
+" dop block - for the time being it is not used
+syn region sicadDopBlock transparent matchgroup=sicadStatement start='\<dop\>' skip='\\ *$' end=';'me=e-1 end='$' contains=ALL
+
+" sql block - new highlighting mode is used (see syn include)
+syn region sicadSqlBlock transparent matchgroup=sicadStatement start='\<sql\>' skip='\\ *$' end=';'me=e-1 end='$' contains=@SQL,sicadIdentifier,sicadLineCont
+
+" synchronizing
+syn sync clear  " clear sync used in sql.vim
+syn sync match sicadSyncComment groupthere NONE "\<docend\>"
+syn sync match sicadSyncComment grouphere sicadComment "\<docbeg\>"
+" next line must be examined too
+syn sync linecont "\\ *$"
+
+" catch error caused by tabulator key
+syn match sicadError "\t"
+" catch errors caused by wrong parenthesis
+"syn region sicadParen transparent start='(' end=')' contains=ALLBUT,sicadParenError
+syn region sicadParen transparent start='(' skip='\\ *$' end=')' end='$' contains=ALLBUT,sicadParenError
+syn match sicadParenError ')'
+"syn region sicadApostrophe transparent start=+'+ end=+'+ contains=ALLBUT,sicadApostropheError
+"syn match sicadApostropheError +'+
+" not closed apostrophe
+"syn region sicadError start=+'+ end=+$+ contains=ALLBUT,sicadApostropheError
+"syn match sicadApostropheError +'[^']*$+me=s+1 contained
+
+" SICAD keywords
+syn keyword sicadStatement abst add addsim adrin aib
+syn keyword sicadStatement aibzsn aidump aifgeo aisbrk alknam
+syn keyword sicadStatement alknr alksav alksel alktrc alopen
+syn keyword sicadStatement ansbo aractiv ararea arareao ararsfs
+syn keyword sicadStatement arbuffer archeck arcomv arcont arconv
+syn keyword sicadStatement arcopy arcopyo arcorr arcreate arerror
+syn keyword sicadStatement areval arflfm arflop arfrast argbkey
+syn keyword sicadStatement argenf argraph argrapho arinters arkompfl
+syn keyword sicadStatement arlasso arlcopy arlgraph arline arlining
+syn keyword sicadStatement arlisly armakea armemo arnext aroverl
+syn keyword sicadStatement arovers arparkmd arpars arrefp arselect
+syn keyword sicadStatement arset arstruct arunify arupdate arvector
+syn keyword sicadStatement arveinfl arvflfl arvoroni ausku basis
+syn keyword sicadStatement basisaus basisdar basisnr bebos befl
+syn keyword sicadStatement befla befli befls beo beorta
+syn keyword sicadStatement beortn bep bepan bepap bepola
+syn keyword sicadStatement bepoln bepsn bepsp ber berili
+syn keyword sicadStatement berk bewz bkl bli bma
+syn keyword sicadStatement bmakt bmakts bmbm bmerk bmerw
+syn keyword sicadStatement bmerws bminit bmk bmorth bmos
+syn keyword sicadStatement bmoss bmpar bmsl bmsum bmsums
+syn keyword sicadStatement bmver bmvero bmw bo bta
+syn keyword sicadStatement buffer bvl bw bza bzap
+syn keyword sicadStatement bzd bzgera bzorth cat catel
+syn keyword sicadStatement cdbdiff ce cgmparam close closesim
+syn keyword sicadStatement comgener comp comp conclose conclose coninfo
+syn keyword sicadStatement conopen conread contour conwrite cop
+syn keyword sicadStatement copar coparp coparp2 copel cr
+syn keyword sicadStatement cs cstat cursor d da
+syn keyword sicadStatement dal dasp dasps dataout dcol
+syn keyword sicadStatement dd defsr del delel deskrdef
+syn keyword sicadStatement df dfn dfns dfpos dfr
+syn keyword sicadStatement dgd dgm dgp dgr dh
+syn keyword sicadStatement diag diaus dir disbsd dkl
+syn keyword sicadStatement dktx dkur dlgfix dlgfre dma
+syn keyword sicadStatement dprio dr druse dsel dskinfo
+syn keyword sicadStatement dsr dv dve eba ebd
+syn keyword sicadStatement ebdmod ebs edbsdbin edbssnin edbsvtin
+syn keyword sicadStatement edt egaus egdef egdefs eglist
+syn keyword sicadStatement egloe egloenp egloes egxx eib
+syn keyword sicadStatement ekur ekuradd elel elpos epg
+syn keyword sicadStatement esau esauadd esek eta etap
+syn keyword sicadStatement etav feparam ficonv filse fl
+syn keyword sicadStatement fli flin flini flinit flins
+syn keyword sicadStatement flkor fln flnli flop flout
+syn keyword sicadStatement flowert flparam flraster flsy flsyd
+syn keyword sicadStatement flsym flsyms flsymt fmtatt fmtdia
+syn keyword sicadStatement fmtlib fpg gbadddb gbaim gbanrs
+syn keyword sicadStatement gbatw gbau gbaudit gbclosp gbcredic
+syn keyword sicadStatement gbcreem gbcreld gbcresdb gbcretd gbde
+syn keyword sicadStatement gbdeldb gbdeldic gbdelem gbdelld gbdelref
+syn keyword sicadStatement gbdeltd gbdisdb gbdisem gbdisld gbdistd
+syn keyword sicadStatement gbebn gbemau gbepsv gbgetdet gbgetes
+syn keyword sicadStatement gbgetmas gbgqel gbgqelr gbgqsa gbgrant
+syn keyword sicadStatement gbimpdic gbler gblerb gblerf gbles
+syn keyword sicadStatement gblocdic gbmgmg gbmntdb gbmoddb gbnam
+syn keyword sicadStatement gbneu gbopenp gbpoly gbpos gbpruef
+syn keyword sicadStatement gbpruefg gbps gbqgel gbqgsa gbrefdic
+syn keyword sicadStatement gbreftab gbreldic gbresem gbrevoke gbsav
+syn keyword sicadStatement gbsbef gbsddk gbsicu gbsrt gbss
+syn keyword sicadStatement gbstat gbsysp gbszau gbubp gbueb
+syn keyword sicadStatement gbunmdb gbuseem gbw gbweg gbwieh
+syn keyword sicadStatement gbzt gelp gera getvar hgw
+syn keyword sicadStatement hpg hr0 hra hrar icclchan
+syn keyword sicadStatement iccrecon icdescon icfree icgetcon icgtresp
+syn keyword sicadStatement icopchan icputcon icreacon icreqd icreqnw
+syn keyword sicadStatement icreqw icrespd icresrve icwricon imsget
+syn keyword sicadStatement imsgqel imsmget imsplot imsprint inchk
+syn keyword sicadStatement inf infd inst kbml kbmls
+syn keyword sicadStatement kbmm kbmms kbmt kbmtdps kbmts
+syn keyword sicadStatement khboe khbol khdob khe khetap
+syn keyword sicadStatement khfrw khktk khlang khld khmfrp
+syn keyword sicadStatement khmks khms khpd khpfeil khpl
+syn keyword sicadStatement khprofil khrand khsa khsabs khsaph
+syn keyword sicadStatement khsd khsdl khse khskbz khsna
+syn keyword sicadStatement khsnum khsob khspos khsvph khtrn
+syn keyword sicadStatement khver khzpe khzpl kib kldat
+syn keyword sicadStatement klleg klsch klsym klvert kmpg
+syn keyword sicadStatement kmtlage kmtp kmtps kodef kodefp
+syn keyword sicadStatement kodefs kok kokp kolae kom
+syn keyword sicadStatement kontly kopar koparp kopg kosy
+syn keyword sicadStatement kp kr krsek krtclose krtopen
+syn keyword sicadStatement ktk lad lae laesel language
+syn keyword sicadStatement lasso lbdes lcs ldesk ldesks
+syn keyword sicadStatement le leak leattdes leba lebas
+syn keyword sicadStatement lebaznp lebd lebm lebv lebvaus
+syn keyword sicadStatement lebvlist lede ledel ledepo ledepol
+syn keyword sicadStatement ledepos leder ledist ledm lee
+syn keyword sicadStatement leeins lees lege lekr lekrend
+syn keyword sicadStatement lekwa lekwas lel lelh lell
+syn keyword sicadStatement lelp lem lena lend lenm
+syn keyword sicadStatement lep lepe lepee lepko lepl
+syn keyword sicadStatement lepmko lepmkop lepos leposm leqs
+syn keyword sicadStatement leqsl leqssp leqsv leqsvov les
+syn keyword sicadStatement lesch lesr less lestd let
+syn keyword sicadStatement letaum letl lev levm levtm
+syn keyword sicadStatement levtp levtr lew lewm lexx
+syn keyword sicadStatement lfs li lining lldes lmode
+syn keyword sicadStatement loedk loepkt lop lose loses
+syn keyword sicadStatement lp lppg lppruef lr ls
+syn keyword sicadStatement lsop lsta lstat ly lyaus
+syn keyword sicadStatement lz lza lzae lzbz lze
+syn keyword sicadStatement lznr lzo lzpos ma ma0
+syn keyword sicadStatement ma1 mad map mapoly mcarp
+syn keyword sicadStatement mccfr mccgr mcclr mccrf mcdf
+syn keyword sicadStatement mcdma mcdr mcdrp mcdve mcebd
+syn keyword sicadStatement mcgse mcinfo mcldrp md me
+syn keyword sicadStatement mefd mefds minmax mipg ml
+syn keyword sicadStatement mmcmdme mmdbf mmdellb mmdir mmdome
+syn keyword sicadStatement mmfsb mminfolb mmlapp mmlbf mmlistlb
+syn keyword sicadStatement mmloadcm mmmsg mmreadlb mmsetlb mmshowcm
+syn keyword sicadStatement mmstatme mnp mpo mr mra
+syn keyword sicadStatement ms msav msgout msgsnd msp
+syn keyword sicadStatement mspf mtd nasel ncomp new
+syn keyword sicadStatement nlist nlistlt nlistly nlistnp nlistpo
+syn keyword sicadStatement np npa npdes npe npem
+syn keyword sicadStatement npinfa npruef npsat npss npssa
+syn keyword sicadStatement ntz oa oan odel odf
+syn keyword sicadStatement odfx oj oja ojaddsk ojaed
+syn keyword sicadStatement ojaeds ojaef ojaefs ojaen ojak
+syn keyword sicadStatement ojaks ojakt ojakz ojalm ojatkis
+syn keyword sicadStatement ojatt ojatw ojbsel ojcasel ojckon
+syn keyword sicadStatement ojde ojdtl ojeb ojebd ojel
+syn keyword sicadStatement ojelpas ojesb ojesbd ojex ojezge
+syn keyword sicadStatement ojko ojlb ojloe ojlsb ojmerk
+syn keyword sicadStatement ojmos ojnam ojpda ojpoly ojprae
+syn keyword sicadStatement ojs ojsak ojsort ojstrukt ojsub
+syn keyword sicadStatement ojtdef ojvek ojx old oldd
+syn keyword sicadStatement op opa opa1 open opensim
+syn keyword sicadStatement opnbsd orth osanz ot otp
+syn keyword sicadStatement otrefp param paranf pas passw
+syn keyword sicadStatement pcatchf pda pdadd pg pg0
+syn keyword sicadStatement pgauf pgaufsel pgb pgko pgm
+syn keyword sicadStatement pgr pgvs pily pkpg plot
+syn keyword sicadStatement plotf plotfr pmap pmdata pmdi
+syn keyword sicadStatement pmdp pmeb pmep pminfo pmlb
+syn keyword sicadStatement pmli pmlp pmmod pnrver poa
+syn keyword sicadStatement pos posa posaus post printfr
+syn keyword sicadStatement protect prs prssy prsym ps
+syn keyword sicadStatement psadd psclose psopen psparam psprw
+syn keyword sicadStatement psres psstat psw pswr qualif
+syn keyword sicadStatement rahmen raster rasterd rbbackup rbchang2
+syn keyword sicadStatement rbchange rbcmd rbcoldst rbcolor rbcopy
+syn keyword sicadStatement rbcut rbcut2 rbdbcl rbdbload rbdbop
+syn keyword sicadStatement rbdbwin rbdefs rbedit rbfdel rbfill
+syn keyword sicadStatement rbfill2 rbfload rbfload2 rbfnew rbfnew2
+syn keyword sicadStatement rbfpar rbfree rbg rbgetcol rbgetdst
+syn keyword sicadStatement rbinfo rbpaste rbpixel rbrstore rbsnap
+syn keyword sicadStatement rbsta rbtile rbtrpix rbvtor rcol
+syn keyword sicadStatement rd rdchange re reb rebmod
+syn keyword sicadStatement refunc ren renel rk rkpos
+syn keyword sicadStatement rohr rohrpos rpr rr rr0
+syn keyword sicadStatement rra rrar rs samtosdb sav
+syn keyword sicadStatement savd savesim savx scol scopy
+syn keyword sicadStatement scopye sdbtosam sddk sdwr se
+syn keyword sicadStatement selaus selpos seman semi sesch
+syn keyword sicadStatement setscl setvar sfclntpf sfconn sffetchf
+syn keyword sicadStatement sffpropi sfftypi sfqugeoc sfquwhcl sfself
+syn keyword sicadStatement sfstat sftest sge sid sie
+syn keyword sicadStatement sig sigp skk skks sn
+syn keyword sicadStatement sn21 snpa snpar snparp snparps
+syn keyword sicadStatement snpars snpas snpd snpi snpkor
+syn keyword sicadStatement snpl snpm sob sob0 sobloe
+syn keyword sicadStatement sobs sof sop split spr
+syn keyword sicadStatement sqdadd sqdlad sqdold sqdsav
+syn keyword sicadStatement sr sres srt sset stat
+syn keyword sicadStatement stdtxt string strukt strupru suinfl
+syn keyword sicadStatement suinflk suinfls supo supo1 sva
+syn keyword sicadStatement svr sy sya syly sysout
+syn keyword sicadStatement syu syux taa tabeg tabl
+syn keyword sicadStatement tabm tam tanr tapg tapos
+syn keyword sicadStatement tarkd tas tase tb tbadd
+syn keyword sicadStatement tbd tbext tbget tbint tbout
+syn keyword sicadStatement tbput tbsat tbsel tbstr tcaux
+syn keyword sicadStatement tccable tcchkrep tccomm tccond tcdbg
+syn keyword sicadStatement tcgbnr tcgrpos tcinit tclconv tcmodel
+syn keyword sicadStatement tcnwe tcpairs tcpath tcrect tcrmdli
+syn keyword sicadStatement tcscheme tcschmap tcse tcselc tcstar
+syn keyword sicadStatement tcstrman tcsubnet tcsymbol tctable tcthrcab
+syn keyword sicadStatement tctrans tctst tdb tdbdel tdbget
+syn keyword sicadStatement tdblist tdbput tgmod titel tmoff
+syn keyword sicadStatement tmon tp tpa tps tpta
+syn keyword sicadStatement tra trans transkdo transopt transpro
+syn keyword sicadStatement triangle trm trpg trrkd trs
+syn keyword sicadStatement ts tsa tx txa txchk
+syn keyword sicadStatement txcng txju txl txp txpv
+syn keyword sicadStatement txtcmp txv txz uckon uiinfo
+syn keyword sicadStatement uistatus umdk umdk1 umdka umge
+syn keyword sicadStatement umges umr verbo verflli verif
+syn keyword sicadStatement verly versinfo vfg vpactive vpcenter
+syn keyword sicadStatement vpcreate vpdelete vpinfo vpmodify vpscroll
+syn keyword sicadStatement vpsta wabsym wzmerk zdrhf zdrhfn
+syn keyword sicadStatement zdrhfw zdrhfwn zefp zfl zflaus
+syn keyword sicadStatement zka zlel zlels zortf zortfn
+syn keyword sicadStatement zortfw zortfwn zortp zortpn zparb
+syn keyword sicadStatement zparbn zparf zparfn zparfw zparfwn
+syn keyword sicadStatement zparp zparpn zwinkp zwinkpn
+
+" Define the default highlighting.
+" For version 5.7 and earlier: only when not done already
+" For version 5.8 and later: only when an item doesn't have highlighting yet
+if version >= 508 || !exists("did_sicad_syntax_inits")
+
+  if version < 508
+    let did_sicad_syntax_inits = 1
+    command -nargs=+ HiLink hi link <args>
+  else
+    command -nargs=+ HiLink hi def link <args>
+  endif
+
+  HiLink sicadLabel PreProc
+  HiLink sicadLabel1 sicadLabel
+  HiLink sicadLabel2 sicadLabel
+  HiLink sicadConditional Conditional
+  HiLink sicadBoolean Boolean
+  HiLink sicadNumber Number
+  HiLink sicadFloat Float
+  HiLink sicadOperator Operator
+  HiLink sicadStatement Statement
+  HiLink sicadParameter sicadStatement
+  HiLink sicadGoto sicadStatement
+  HiLink sicadLineCont sicadStatement
+  HiLink sicadString String
+  HiLink sicadComment Comment
+  HiLink sicadSpecial Special
+  HiLink sicadIdentifier Type
+"  HiLink sicadIdentifier Identifier
+  HiLink sicadError Error
+  HiLink sicadParenError sicadError
+  HiLink sicadApostropheError sicadError
+  HiLink sicadStringError sicadError
+  HiLink sicadCommentError sicadError
+"  HiLink sqlStatement Special  " modified highlight group in sql.vim
+
+  delcommand HiLink
+
+endif
+
+let b:current_syntax = "sicad"
+
+" vim: ts=8 sw=2
--- /dev/null
+++ b/lib/vimfiles/syntax/sieve.vim
@@ -1,0 +1,55 @@
+" Vim syntax file
+" Language:         Sieve filtering language input file
+" Maintainer:       Nikolai Weibull <now@bitwi.se>
+" Latest Revision:  2006-04-19
+
+if exists("b:current_syntax")
+  finish
+endif
+
+let s:cpo_save = &cpo
+set cpo&vim
+
+syn keyword sieveTodo         contained TODO FIXME XXX NOTE
+
+syn region  sieveComment      start='/\*' end='\*/' contains=sieveTodo,@Spell
+syn region  sieveComment      display oneline start='#' end='$'
+                              \ contains=sieveTodo,@Spell
+
+syn case ignore
+
+syn match   sieveTag          display ':\h\w*'
+
+syn match   sieveNumber       display '\<\d\+[KMG]\=\>'
+
+syn match   sieveSpecial      display '\\["\\]'
+
+syn region  sieveString       start=+"+ skip=+\\\\\|\\"+ end=+"+
+                              \ contains=sieveSpecial
+syn region  sieveString       start='text:' end='\n.\n'
+
+syn keyword sieveConditional  if elsif else
+syn keyword sieveTest         address allof anyof envelope exists false header
+                              \ not size true
+syn keyword sievePreProc      require stop
+syn keyword sieveAction       reject fileinto redirect keep discard
+syn match   sieveKeyword      '\<\h\w*\>'
+
+syn case match
+
+hi def link sieveTodo        Todo
+hi def link sieveComment     Comment
+hi def link sieveTag         Type
+hi def link sieveNumber      Number
+hi def link sieveSpecial     Special
+hi def link sieveString      String
+hi def link sieveConditional Conditional
+hi def link sieveTest        Keyword
+hi def link sievePreProc     PreProc
+hi def link sieveAction      Keyword
+hi def link sieveKeyword     Keyword
+
+let b:current_syntax = "sieve"
+
+let &cpo = s:cpo_save
+unlet s:cpo_save
--- /dev/null
+++ b/lib/vimfiles/syntax/simula.vim
@@ -1,0 +1,99 @@
+" Vim syntax file
+" Language:	Simula
+" Maintainer:	Haakon Riiser <hakonrk@fys.uio.no>
+" URL:		http://folk.uio.no/hakonrk/vim/syntax/simula.vim
+" Last Change:	2001 May 15
+
+" For version 5.x: Clear all syntax items
+" For version 6.x: Quit when a syntax file was already loaded
+if version < 600
+    syn clear
+elseif exists("b:current_syntax")
+    finish
+endif
+
+" No case sensitivity in Simula
+syn case	ignore
+
+syn match	simulaComment		"^%.*$" contains=simulaTodo
+syn region	simulaComment		start="!\|\<comment\>" end=";" contains=simulaTodo
+
+" Text between the keyword 'end' and either a semicolon or one of the
+" keywords 'end', 'else', 'when' or 'otherwise' is also a comment
+syn region	simulaComment		start="\<end\>"lc=3 matchgroup=Statement end=";\|\<\(end\|else\|when\|otherwise\)\>"
+
+syn match	simulaCharError		"'.\{-2,}'"
+syn match	simulaCharacter		"'.'"
+syn match	simulaCharacter		"'!\d\{-}!'" contains=simulaSpecialChar
+syn match	simulaString		'".\{-}"' contains=simulaSpecialChar,simulaTodo
+
+syn keyword	simulaBoolean		true false
+syn keyword	simulaCompound		begin end
+syn keyword	simulaConditional	else if otherwise then until when
+syn keyword	simulaConstant		none notext
+syn keyword	simulaFunction		procedure
+syn keyword	simulaOperator		eq eqv ge gt imp in is le lt ne new not qua
+syn keyword	simulaRepeat		while for
+syn keyword	simulaReserved		activate after at before delay go goto label prior reactivate switch to
+syn keyword	simulaStatement		do inner inspect step this
+syn keyword	simulaStorageClass	external hidden name protected value
+syn keyword	simulaStructure		class
+syn keyword	simulaType		array boolean character integer long real short text virtual
+syn match	simulaAssigned		"\<\h\w*\s*\((.*)\)\=\s*:\(=\|-\)"me=e-2
+syn match	simulaOperator		"[&:=<>+\-*/]"
+syn match	simulaOperator		"\<and\(\s\+then\)\=\>"
+syn match	simulaOperator		"\<or\(\s\+else\)\=\>"
+syn match	simulaReferenceType	"\<ref\s*(.\{-})"
+syn match	simulaSemicolon		";"
+syn match	simulaSpecial		"[(),.]"
+syn match	simulaSpecialCharErr	"!\d\{-4,}!" contained
+syn match	simulaSpecialCharErr	"!!" contained
+syn match	simulaSpecialChar	"!\d\{-}!" contains=simulaSpecialCharErr contained
+syn match	simulaTodo		"xxx\+" contained
+
+" Integer number (or float without `.')
+syn match	simulaNumber		"-\=\<\d\+\>"
+" Real with optional exponent
+syn match	simulaReal		"-\=\<\d\+\(\.\d\+\)\=\(&&\=[+-]\=\d\+\)\=\>"
+" Real starting with a `.', optional exponent
+syn match	simulaReal		"-\=\.\d\+\(&&\=[+-]\=\d\+\)\=\>"
+
+if version >= 508 || !exists("did_simula_syntax_inits")
+    if version < 508
+	let did_simula_syntax_inits = 1
+	command -nargs=+ HiLink hi link <args>
+    else
+	command -nargs=+ HiLink hi def link <args>
+    endif
+
+    HiLink simulaAssigned		Identifier
+    HiLink simulaBoolean		Boolean
+    HiLink simulaCharacter		Character
+    HiLink simulaCharError		Error
+    HiLink simulaComment		Comment
+    HiLink simulaCompound		Statement
+    HiLink simulaConditional		Conditional
+    HiLink simulaConstant		Constant
+    HiLink simulaFunction		Function
+    HiLink simulaNumber			Number
+    HiLink simulaOperator		Operator
+    HiLink simulaReal			Float
+    HiLink simulaReferenceType		Type
+    HiLink simulaRepeat			Repeat
+    HiLink simulaReserved		Error
+    HiLink simulaSemicolon		Statement
+    HiLink simulaSpecial		Special
+    HiLink simulaSpecialChar		SpecialChar
+    HiLink simulaSpecialCharErr		Error
+    HiLink simulaStatement		Statement
+    HiLink simulaStorageClass		StorageClass
+    HiLink simulaString			String
+    HiLink simulaStructure		Structure
+    HiLink simulaTodo			Todo
+    HiLink simulaType			Type
+
+    delcommand HiLink
+endif
+
+let b:current_syntax = "simula"
+" vim: sts=4 sw=4 ts=8
--- /dev/null
+++ b/lib/vimfiles/syntax/sinda.vim
@@ -1,0 +1,146 @@
+" Vim syntax file
+" Language:     sinda85, sinda/fluint input file
+" Maintainer:   Adrian Nagle, anagle@ball.com
+" Last Change:  2003 May 11
+" Filenames:    *.sin
+" URL:		http://www.naglenet.org/vim/syntax/sinda.vim
+" MAIN URL:     http://www.naglenet.org/vim/
+
+
+
+" For version 5.x: Clear all syntax items
+" For version 6.x: Quit when a syntax file was already loaded
+if version < 600
+  syntax clear
+elseif exists("b:current_syntax")
+  finish
+endif
+
+
+
+" Ignore case
+syn case ignore
+
+
+
+"
+"
+" Begin syntax definitions for sinda input and output files.
+"
+
+" Force free-form fortran format
+let fortran_free_source=1
+
+" Load FORTRAN syntax file
+if version < 600
+  source <sfile>:p:h/fortran.vim
+else
+  runtime! syntax/fortran.vim
+endif
+unlet b:current_syntax
+
+
+
+" Define keywords for SINDA
+syn keyword sindaMacro    BUILD BUILDF DEBON DEBOFF DEFMOD FSTART FSTOP
+
+syn keyword sindaOptions  TITLE PPSAVE RSI RSO OUTPUT SAVE QMAP USER1 USER2
+syn keyword sindaOptions  MODEL PPOUT NOLIST MLINE NODEBUG DIRECTORIES
+syn keyword sindaOptions  DOUBLEPR
+
+syn keyword sindaRoutine  FORWRD FWDBCK STDSTL FASTIC
+
+syn keyword sindaControl  ABSZRO ACCELX ACCELY ACCELZ ARLXCA ATMPCA
+syn keyword sindaControl  BACKUP CSGFAC DRLXCA DTIMEH DTIMEI DTIMEL
+syn keyword sindaControl  DTIMES DTMPCA EBALNA EBALSA EXTLIM ITEROT
+syn keyword sindaControl  ITERXT ITHOLD NLOOPS NLOOPT OUTPUT OPEITR
+syn keyword sindaControl  PATMOS SIGMA TIMEO TIMEND UID
+
+syn keyword sindaSubRoutine  ASKERS ADARIN ADDARY ADDMOD ARINDV
+syn keyword sindaSubRoutine  RYINV ARYMPY ARYSUB ARYTRN BAROC
+syn keyword sindaSubRoutine  BELACC BNDDRV BNDGET CHENNB CHGFLD
+syn keyword sindaSubRoutine  CHGLMP CHGSUC CHGVOL CHKCHL CHKCHP
+syn keyword sindaSubRoutine  CNSTAB COMBAL COMPLQ COMPRS CONTRN
+syn keyword sindaSubRoutine  CPRINT CRASH CRVINT CRYTRN CSIFLX
+syn keyword sindaSubRoutine  CVTEMP D11CYL C11DAI D11DIM D11MCY
+syn keyword sindaSubRoutine  D11MDA D11MDI D11MDT D12CYL D12MCY
+syn keyword sindaSubRoutine  D12MDA D1D1DA D1D1IM D1D1WM D1D2DA
+syn keyword sindaSubRoutine  D1D2WM D1DEG1 D1DEG2 D1DG1I D1IMD1
+syn keyword sindaSubRoutine  D1IMIM D1IMWM D1M1DA D1M2MD D1M2WM
+syn keyword sindaSubRoutine  D1MDG1 D1MDG2 D2D1WM D1DEG1 D2DEG2
+syn keyword sindaSubRoutine  D2D2
+
+syn keyword sindaIdentifier  BIV CAL DIM DIV DPM DPV DTV GEN PER PIV PIM
+syn keyword sindaIdentifier  SIM SIV SPM SPV TVS TVD
+
+
+
+" Define matches for SINDA
+syn match  sindaFortran     "^F[0-9 ]"me=e-1
+syn match  sindaMotran      "^M[0-9 ]"me=e-1
+
+syn match  sindaComment     "^C.*$"
+syn match  sindaComment     "^R.*$"
+syn match  sindaComment     "\$.*$"
+
+syn match  sindaHeader      "^header[^,]*"
+
+syn match  sindaIncludeFile "include \+[^ ]\+"hs=s+8 contains=fortranInclude
+
+syn match  sindaMacro       "^PSTART"
+syn match  sindaMacro       "^PSTOP"
+syn match  sindaMacro       "^FAC"
+
+syn match  sindaInteger     "-\=\<[0-9]*\>"
+syn match  sindaFloat       "-\=\<[0-9]*\.[0-9]*"
+syn match  sindaScientific  "-\=\<[0-9]*\.[0-9]*E[-+]\=[0-9]\+\>"
+
+syn match  sindaEndData		 "^END OF DATA"
+
+if exists("thermal_todo")
+  execute 'syn match  sindaTodo ' . '"^'.thermal_todo.'.*$"'
+else
+  syn match  sindaTodo     "^?.*$"
+endif
+
+
+
+" Define the default highlighting
+" For version 5.7 and earlier: only when not done already
+" For version 5.8 and later: only when an item doesn't have highlighting yet
+if version >= 508 || !exists("did_sinda_syntax_inits")
+  if version < 508
+    let did_sinda_syntax_inits = 1
+    command -nargs=+ HiLink hi link <args>
+  else
+    command -nargs=+ HiLink hi def link <args>
+  endif
+
+  HiLink sindaMacro		Macro
+  HiLink sindaOptions		Special
+  HiLink sindaRoutine		Type
+  HiLink sindaControl		Special
+  HiLink sindaSubRoutine	Function
+  HiLink sindaIdentifier	Identifier
+
+  HiLink sindaFortran		PreProc
+  HiLink sindaMotran		PreProc
+
+  HiLink sindaComment		Comment
+  HiLink sindaHeader		Typedef
+  HiLink sindaIncludeFile	Type
+  HiLink sindaInteger		Number
+  HiLink sindaFloat		Float
+  HiLink sindaScientific	Float
+
+  HiLink sindaEndData		Macro
+
+  HiLink sindaTodo		Todo
+
+  delcommand HiLink
+endif
+
+
+let b:current_syntax = "sinda"
+
+" vim: ts=8 sw=2
--- /dev/null
+++ b/lib/vimfiles/syntax/sindacmp.vim
@@ -1,0 +1,74 @@
+" Vim syntax file
+" Language:     sinda85, sinda/fluint compare file
+" Maintainer:   Adrian Nagle, anagle@ball.com
+" Last Change:  2003 May 11
+" Filenames:    *.cmp
+" URL:		http://www.naglenet.org/vim/syntax/sindacmp.vim
+" MAIN URL:     http://www.naglenet.org/vim/
+
+
+
+" For version 5.x: Clear all syntax items
+" For version 6.x: Quit when a syntax file was already loaded
+if version < 600
+  syntax clear
+elseif exists("b:current_syntax")
+  finish
+endif
+
+
+
+" Ignore case
+syn case ignore
+
+
+
+"
+" Begin syntax definitions for compare files.
+"
+
+" Define keywords for sinda compare (sincomp)
+syn keyword sindacmpUnit     celsius fahrenheit
+
+
+
+" Define matches for sinda compare (sincomp)
+syn match  sindacmpTitle       "Steady State Temperature Comparison"
+
+syn match  sindacmpLabel       "File  [1-6] is"
+
+syn match  sindacmpHeader      "^ *Node\( *File  \d\)* *Node Description"
+
+syn match  sindacmpInteger     "^ *-\=\<[0-9]*\>"
+syn match  sindacmpFloat       "-\=\<[0-9]*\.[0-9]*"
+
+
+
+" Define the default highlighting
+" For version 5.7 and earlier: only when not done already
+" For version 5.8 and later: only when an item doesn't have highlighting yet
+if version >= 508 || !exists("did_sindacmp_syntax_inits")
+  if version < 508
+    let did_sindacmp_syntax_inits = 1
+    command -nargs=+ HiLink hi link <args>
+  else
+    command -nargs=+ HiLink hi def link <args>
+  endif
+
+  HiLink sindacmpTitle		     Type
+  HiLink sindacmpUnit		     PreProc
+
+  HiLink sindacmpLabel		     Statement
+
+  HiLink sindacmpHeader		     sindaHeader
+
+  HiLink sindacmpInteger	     Number
+  HiLink sindacmpFloat		     Special
+
+  delcommand HiLink
+endif
+
+
+let b:current_syntax = "sindacmp"
+
+" vim: ts=8 sw=2
--- /dev/null
+++ b/lib/vimfiles/syntax/sindaout.vim
@@ -1,0 +1,100 @@
+" Vim syntax file
+" Language:     sinda85, sinda/fluint output file
+" Maintainer:   Adrian Nagle, anagle@ball.com
+" Last Change:  2003 May 11
+" Filenames:    *.out
+" URL:		http://www.naglenet.org/vim/syntax/sindaout.vim
+" MAIN URL:     http://www.naglenet.org/vim/
+
+
+
+" For version 5.x: Clear all syntax items
+" For version 6.x: Quit when a syntax file was already loaded
+if version < 600
+  syntax clear
+elseif exists("b:current_syntax")
+  finish
+endif
+
+
+
+" Ignore case
+syn case match
+
+
+
+" Load SINDA syntax file
+if version < 600
+  source <sfile>:p:h/sinda.vim
+else
+  runtime! syntax/sinda.vim
+endif
+unlet b:current_syntax
+
+
+
+"
+"
+" Begin syntax definitions for sinda output files.
+"
+
+" Define keywords for sinda output
+syn case match
+
+syn keyword sindaoutPos       ON SI
+syn keyword sindaoutNeg       OFF ENG
+
+
+
+" Define matches for sinda output
+syn match sindaoutFile	       ": \w*\.TAK"hs=s+2
+
+syn match sindaoutInteger      "T\=[0-9]*\>"ms=s+1
+
+syn match sindaoutSectionDelim "[-<>]\{4,}" contains=sindaoutSectionTitle
+syn match sindaoutSectionDelim ":\=\.\{4,}:\=" contains=sindaoutSectionTitle
+syn match sindaoutSectionTitle "[-<:] \w[0-9A-Za-z_() ]\+ [->:]"hs=s+1,me=e-1
+
+syn match sindaoutHeaderDelim  "=\{5,}"
+syn match sindaoutHeaderDelim  "|\{5,}"
+syn match sindaoutHeaderDelim  "+\{5,}"
+
+syn match sindaoutLabel		"Input File:" contains=sindaoutFile
+syn match sindaoutLabel		"Begin Solution: Routine"
+
+syn match sindaoutError		"<<< Error >>>"
+
+
+" Define the default highlighting
+" For version 5.7 and earlier: only when not done already
+" For version 5.8 and later: only when an item doesn't have highlighting yet
+if version >= 508 || !exists("did_sindaout_syntax_inits")
+  if version < 508
+    let did_sindaout_syntax_inits = 1
+    command -nargs=+ HiLink hi link <args>
+  else
+    command -nargs=+ HiLink hi def link <args>
+  endif
+
+  hi sindaHeaderDelim  ctermfg=Black ctermbg=Green	       guifg=Black guibg=Green
+
+  HiLink sindaoutPos		     Statement
+  HiLink sindaoutNeg		     PreProc
+  HiLink sindaoutTitle		     Type
+  HiLink sindaoutFile		     sindaIncludeFile
+  HiLink sindaoutInteger	     sindaInteger
+
+  HiLink sindaoutSectionDelim	      Delimiter
+  HiLink sindaoutSectionTitle	     Exception
+  HiLink sindaoutHeaderDelim	     SpecialComment
+  HiLink sindaoutLabel		     Identifier
+
+  HiLink sindaoutError		     Error
+
+  delcommand HiLink
+endif
+
+
+let b:current_syntax = "sindaout"
+
+" vim: ts=8 sw=2
--- /dev/null
+++ b/lib/vimfiles/syntax/sisu.vim
@@ -1,0 +1,171 @@
+"%% SiSU Vim syntax file
+" SiSU Maintainer: Ralph Amissah <ralph@amissah.com>
+" SiSU Markup:     SiSU (sisu-0.38)
+" (originally looked at Ruby Vim by Mirko Nasato)
+" Last Update:	   2006 Jul 22
+
+if version < 600
+  syntax clear
+elseif exists("b:current_syntax")
+  finish
+else
+endif
+"% 11 Errors?
+syn match sisu_error contains=sisu_link,sisu_error_wspace "<![^ei]\S\+!>"
+"% 10 Markers: Endnote Identifiers, Pagebreaks etc.: 
+if !exists("sisu_no_identifiers")
+  syn match   sisu_mark_endnote                      "\~^"
+  syn match   sisu_contain       contains=@NoSpell   "</\?sub>"
+  syn match   sisu_break         contains=@NoSpell   "<br>\|<br />"
+  syn match   sisu_control       contains=@NoSpell   "<p>\|</p>\|<p />\|<:p[bn]>"
+  syn match   sisu_html                              "<center>\|</center>"
+  syn match   sisu_marktail                          "[~-]#"
+  syn match   sisu_html          contains=@NoSpell   "<td>\|<td \|<tr>\|</td>\|</tr>\|<table>\|<table \|</table>"
+  syn match   sisu_control                           "\""
+  syn match   sisu_underline                         "\(^\| \)_[a-zA-Z0-9]\+_\([ .,]\|$\)"
+  syn match   sisu_number        contains=@NoSpell   "[0-9a-f]\{32\}\|[0-9a-f]\{64\}"
+  syn match   sisu_link          contains=@NoSpell   "\(https\?://\|\.\.\/\)\S\+"
+  "metaverse specific
+  syn match   sisu_ocn           contains=@NoSpell   "<\~\d\+;\w\d\+;\w\d\+>"
+  syn match   sisu_marktail                          "<\~#>"
+  syn match   sisu_markpara      contains=@NoSpell   "<:i[12]>"
+  syn match   sisu_link                              " \*\~\S\+"
+  syn match   sisu_action                            "^<:insert\d\+>"
+  syn match   sisu_contain                           "<:e>"
+endif
+"% 9 URLs Numbers: and ASCII Codes
+syn match   sisu_number                              "\<\(0x\x\+\|0b[01]\+\|0\o\+\|0\.\d\+\|0\|[1-9][\.0-9_]*\)\>"
+syn match   sisu_number                              "?\(\\M-\\C-\|\\c\|\\C-\|\\M-\)\=\(\\\o\{3}\|\\x\x\{2}\|\\\=\w\)"
+"% 8 Tuned Error - is error if not already matched
+syn match sisu_error             contains=sisu_error "[\~/\*!_]{\|}[\~/\*!_]"
+syn match sisu_error             contains=sisu_error "<a href\|</a>]"
+"% 7 Simple Enclosed Markup:
+" Simple Markup:
+"%   url/link
+syn region sisu_link contains=sisu_error,sisu_error_wspace matchgroup=sisu_action start="^<<\s*|[a-zA-Z0-9^._-]\+|@|[a-zA-Z0-9^._-]\+|"rs=s+2 end="$"
+"%   header
+syn region sisu_header_content contains=sisu_error,sisu_error_wspace,sisu_content_alt,sisu_link,sisu_linked,sisu_break matchgroup=sisu_header start="^0\~\(\S\+\|[^-]\)" end="$"
+syn region sisu_header_content contains=sisu_error,sisu_error_wspace,sisu_content_alt,sisu_link,sisu_linked,sisu_break matchgroup=sisu_header start="^0\~\(tags\?\|date\)\s\+"rs=e-1 end="\n$"
+syn region sisu_header_content contains=sisu_error,sisu_error_wspace,sisu_content_alt,sisu_link,sisu_linked,sisu_break matchgroup=sisu_header start="^@\S\+:[+-]\?\s"rs=e-1 end="$"
+syn region sisu_header_content contains=sisu_error,sisu_error_wspace,sisu_content_alt,sisu_link,sisu_linked,sisu_break matchgroup=sisu_header start="^@\(tags\?\|date\):\s\+"rs=e-1 end="\n$"
+"%   headings
+syn region sisu_heading contains=sisu_mark_endnote,sisu_content_endnote,sisu_marktail,sisu_strikeout,sisu_number,sisu_control,sisu_identifier,sisu_ocn,sisu_error,sisu_error_wspace matchgroup=sisu_structure start="^\([1-8]\|:\?[A-C]\)\~\(\S\+\|[^-]\)" end="$"
+"%   grouped text
+syn region sisu_content_alt contains=sisu_strikeout,sisu_number,sisu_control,sisu_identifier,sisu_error matchgroup=sisu_contain start="table{.\+" end="}table"
+syn region sisu_content_alt contains=sisu_strikeout,sisu_number,sisu_control,sisu_identifier,sisu_error matchgroup=sisu_contain start="{t\~h}" end="$$"
+syn region sisu_content_alt contains=sisu_mark_endnote,sisu_content_endnote,sisu_link,sisu_mark,sisu_strikeout,sisu_number,sisu_control,sisu_identifier,sisu_error matchgroup=sisu_contain start="^\(alt\|group\|poem\){" end="^}\(alt\|group\|poem\)"
+syn region sisu_content_alt contains=sisu_error matchgroup=sisu_contain start="^code{" end="^}code"
+"%   endnotes
+syn region sisu_content_endnote contains=sisu_link,sisu_strikeout,sisu_underline,sisu_number,sisu_control,sisu_identifier,sisu_error,sisu_error_wspace,sisu_mark,sisu_break matchgroup=sisu_mark_endnote start="\~{[*+]*" end="}\~" skip="\n"
+syn region sisu_content_endnote contains=sisu_link,sisu_strikeout,sisu_underline,sisu_number,sisu_control,sisu_identifier,sisu_error,sisu_error_wspace,sisu_mark,sisu_break matchgroup=sisu_mark_endnote start="\~\[[*+]*" end="\]\~" skip="\n"
+syn region sisu_content_endnote contains=sisu_strikeout,sisu_number,sisu_control,sisu_link,sisu_identifier,sisu_error,sisu_error_wspace,sisu_mark,sisu_break matchgroup=sisu_mark_endnote start="\^\~" end="\n\n"
+"%   images
+syn region sisu_linked contains=sisu_fontface,sisu_strikeout,sisu_number,sisu_control,sisu_identifier,sisu_error matchgroup=sisu_link start="{" end="}\(\(https\?://\|\.\./\)\S\+\|image\)" oneline
+"%   some line operations
+syn region sisu_control contains=sisu_strikeout,sisu_identifier,sisu_content_endnote,sisu_mark_endnote,sisu_error,sisu_error_wspace matchgroup=sisu_control start="\(\(^\| \)!_ \|<:b>\)" end="$"
+syn region sisu_normal contains=sisu_strikeout,sisu_identifier,sisu_content_endnote,sisu_mark_endnote,sisu_link,sisu_linked,sisu_error,sisu_error_wspace matchgroup=sisu_markpara start="^_\([12*]\|[12]\*\) " end="$"
+syn region sisu_normal contains=sisu_strikeout,sisu_identifier,sisu_content_endnote,sisu_mark_endnote,sisu_link,sisu_linked,sisu_error,sisu_error_wspace matchgroup=sisu_markpara start="^\(#[ 1]\|_# \)" end="$"
+syn region sisu_comment matchgroup=sisu_comment start="^%\{1,2\} " end="$"
+"%   font face curly brackets
+syn region sisu_control contains=sisu_strikeout,sisu_number,sisu_control,sisu_identifier,sisu_error matchgroup=sisu_fontface start="\*{" end="}\*"
+syn region sisu_control contains=sisu_strikeout,sisu_number,sisu_control,sisu_identifier,sisu_error matchgroup=sisu_fontface start="!{" end="}!"
+syn region sisu_underline contains=sisu_strikeout,sisu_number,sisu_control,sisu_identifier,sisu_error matchgroup=sisu_fontface start="_{" end="}_"
+syn region sisu_identifier contains=sisu_strikeout,sisu_number,sisu_control,sisu_identifier,sisu_error matchgroup=sisu_fontface start="/{" end="}/"
+syn region sisu_underline contains=sisu_strikeout,sisu_number,sisu_control,sisu_identifier,sisu_error matchgroup=sisu_fontface start="+{" end="}+"
+syn region sisu_identifier contains=sisu_strikeout,sisu_number,sisu_control,sisu_identifier,sisu_error matchgroup=sisu_fontface start="\^{" end="}\^"
+syn region sisu_identifier contains=sisu_strikeout,sisu_number,sisu_control,sisu_identifier,sisu_error matchgroup=sisu_fontface start=",{" end="},"
+syn region sisu_strikeout contains=sisu_error matchgroup=sisu_fontface start="-{" end="}-" 
+syn region sisu_html contains=sisu_error contains=sisu_strikeout matchgroup=sisu_contain start="<a href=\".\{-}\">" end="</a>" oneline
+"%   single words bold italicise etc. "workon
+syn region sisu_control contains=sisu_error matchgroup=sisu_control start="\([ (]\|^\)\*[^\|{\n\~\\]"hs=e-1 end="\*"he=e-0 skip="[a-zA-Z0-9']" oneline
+syn region sisu_identifier contains=sisu_error matchgroup=sisu_content_alt start="\([ ]\|^\)/[^{ \|\n\\]"hs=e-1 end="/\[ \.\]" skip="[a-zA-Z0-9']" oneline
+"%   misc
+syn region sisu_identifier contains=sisu_error matchgroup=sisu_fontface start="\^[^ {\|\n\\]"rs=s+1 end="\^[ ,.;:'})\\\n]" skip="[a-zA-Z0-9']" oneline
+"%   metaverse html (flagged as errors for filetype sisu)
+syn region sisu_control contains=sisu_strikeout,sisu_number,sisu_control,sisu_identifier,sisu_error,sisu_mark matchgroup=sisu_html start="<b>" end="</b>" skip="\n" oneline
+syn region sisu_control contains=sisu_strikeout,sisu_number,sisu_control,sisu_identifier,sisu_error,sisu_mark matchgroup=sisu_html start="<em>" end="</em>" skip="\n" oneline
+syn region sisu_content_alt contains=sisu_strikeout,sisu_number,sisu_control,sisu_identifier,sisu_error,sisu_mark matchgroup=sisu_html start="<i>" end="</i>" skip="\n" oneline
+syn region sisu_content_alt contains=sisu_strikeout,sisu_number,sisu_control,sisu_identifier,sisu_error,sisu_mark matchgroup=sisu_html start="<u>" end="</u>" skip="\n" oneline
+syn region sisu_identifier contains=sisu_strikeout,sisu_number,sisu_control,sisu_identifier,sisu_error,sisu_mark matchgroup=sisu_html start="<ins>" end="</ins>" skip="\\\\\|\\'" oneline
+syn region sisu_identifier contains=sisu_error matchgroup=sisu_html start="<del>" end="</del>" oneline
+"%   metaverse <:>
+syn region sisu_content_alt contains=sisu_strikeout,sisu_number,sisu_control,sisu_identifier,sisu_error matchgroup=sisu_contain start="<:Table.\{-}>" end="<:Table[-_]end>"
+syn region sisu_content_alt contains=sisu_error matchgroup=sisu_contain start="<:code>" end="<:code[-_]end>"
+syn region sisu_content_alt contains=sisu_mark_endnote,sisu_content_endnote,sisu_link,sisu_mark,sisu_strikeout,sisu_number,sisu_control,sisu_identifier,sisu_error matchgroup=sisu_contain start="<:alt>" end="<:alt[-_]end>"
+syn region sisu_content_alt contains=sisu_mark_endnote,sisu_content_endnote,sisu_link,sisu_mark,sisu_strikeout,sisu_number,sisu_control,sisu_identifier,sisu_error matchgroup=sisu_contain start="<:poem>" end="<:poem[-_]end>"
+"% 6 Expensive Mode
+" Expensive Mode:
+if !exists("sisu_no_expensive")
+else " not Expensive
+  syn region  sisu_content_alt  matchgroup=sisu_control start="^\s*def\s" matchgroup=NONE end="[?!]\|\>" skip="\.\|\(::\)" oneline
+endif " Expensive?
+"% 5 Headers: and Headings (Document Instructions)
+syn match sisu_control contains=sisu_error,sisu_error_wspace "4\~! \S\+"
+syn region  sisu_markpara contains=sisu_error,sisu_error_wspace start="^=begin" end="^=end.*$"
+"% 4 Errors?
+syn match sisu_error_wspace contains=sisu_error_wspace "^\s\+"
+syn match sisu_error_wspace contains=sisu_error_wspace "\s\s\+"
+syn match sisu_error_wspace contains=sisu_error_wspace  " \s*$"
+syn match sisu_error contains=sisu_error,sisu_error_wspace "[^ (}]https\?:\S\+"
+syn match sisu_error contains=sisu_error_wspace "\t\+"
+syn match sisu_error contains=sisu_error "https\?:\S\+[}><]"
+syn match sisu_error contains=sisu_error "\([!*/_\+,^]\){\([^(\}\1)]\)\{-}\n\n"
+syn match sisu_error contains=sisu_error "^[\-\~]{[^{]\{-}\n\n"
+syn match sisu_error contains=sisu_error "\s\+.{{"
+syn match sisu_error contains=sisu_error "^\~\s*$"
+syn match sisu_error contains=sisu_error "^[0-9]\~\s*$"
+syn match sisu_error contains=sisu_error "^[0-9]\~\S\+\s*$"
+syn match sisu_error contains=sisu_error "[^{]\~\^[^ \)]"
+syn match sisu_error contains=sisu_error "\~\^\s\+\.\s*"
+syn match sisu_error contains=sisu_error "{\~^\S\+"
+syn match sisu_error contains=sisu_error "[_/\*!^]{[ .,:;?><]*}[_/\*!^]"
+syn match sisu_error contains=sisu_error "[^ (\"'(\[][_/\*!]{\|}[_/\*!][a-zA-Z0-9)\]\"']"
+syn match sisu_error contains=sisu_error "<dir>"
+"errors for filetype sisu, though not error in 'metaverse':
+syn match sisu_error contains=sisu_error,sisu_match,sisu_strikeout,sisu_contain,sisu_content_alt,sisu_mark,sisu_break,sisu_number "<[a-zA-Z\/]\+>"
+syn match sisu_error  "/\?<\([biu]\)>[^(</\1>)]\{-}\n\n"
+"% 3 Error Exceptions?
+syn match sisu_control "\n\n" "contains=ALL
+syn match sisu_control " //"
+syn match sisu_error  "%{"
+syn match sisu_error "<br>https\?:\S\+\|https\?:\S\+<br>"
+syn match sisu_error "[><]https\?:\S\+\|https\?:\S\+[><]"
+"% 2 Definitions - Define the default highlighting.
+if version >= 508 || !exists("did_sisu_syntax_inits")
+  if version < 508
+    let did_sisu_syntax_inits = 1
+    command -nargs=+ HiLink hi link <args>
+  else
+    command -nargs=+ HiLink hi def link <args>
+  endif
+"% 1 Defined
+  HiLink sisu_normal          Normal
+  HiLink sisu_header          PreProc
+  HiLink sisu_header_content  Statement
+  HiLink sisu_heading         Title
+  HiLink sisu_structure       Operator
+  HiLink sisu_contain         Include
+  HiLink sisu_mark_endnote    Include
+  HiLink sisu_link            NonText
+  HiLink sisu_linked          String
+  HiLink sisu_fontface        Include
+  HiLink sisu_strikeout       DiffDelete
+  HiLink sisu_content_alt     Special
+  HiLink sisu_content_endnote Special
+  HiLink sisu_control         Define
+  HiLink sisu_ocn             Include
+  HiLink sisu_number          Number
+  HiLink sisu_identifier      Function
+  HiLink sisu_underline       Underlined
+  HiLink sisu_markpara        Include
+  HiLink sisu_marktail        Include
+  HiLink sisu_mark            Identifier
+  HiLink sisu_break           Structure
+  HiLink sisu_html            Type
+  HiLink sisu_action          Identifier
+  HiLink sisu_comment         Comment
+  HiLink sisu_error_wspace    Error
+  HiLink sisu_error           Error
+  delcommand HiLink
+endif
+let b:current_syntax = "sisu"
--- /dev/null
+++ b/lib/vimfiles/syntax/skill.vim
@@ -1,0 +1,562 @@
+" Vim syntax file
+" Language:		SKILL
+" Maintainer:	Toby Schaffer <jtschaff@eos.ncsu.edu>
+" Last Change:	2003 May 11
+" Comments:		SKILL is a Lisp-like programming language for use in EDA
+"				tools from Cadence Design Systems. It allows you to have
+"				a programming environment within the Cadence environment
+"				that gives you access to the complete tool set and design
+"				database. This file also defines syntax highlighting for
+"				certain Design Framework II interface functions.
+
+" For version 5.x: Clear all syntax items
+" For version 6.x: Quit when a syntax file was already loaded
+if version < 600
+  syntax clear
+elseif exists("b:current_syntax")
+  finish
+endif
+
+syn keyword skillConstants			t nil unbound
+
+" enumerate all the SKILL reserved words/functions
+syn match skillFunction     "(abs\>"hs=s+1
+syn match skillFunction     "\<abs("he=e-1
+syn match skillFunction     "(a\=cos\>"hs=s+1
+syn match skillFunction     "\<a\=cos("he=e-1
+syn match skillFunction     "(add1\>"hs=s+1
+syn match skillFunction     "\<add1("he=e-1
+syn match skillFunction     "(addDefstructClass\>"hs=s+1
+syn match skillFunction     "\<addDefstructClass("he=e-1
+syn match skillFunction     "(alias\>"hs=s+1
+syn match skillFunction     "\<alias("he=e-1
+syn match skillFunction     "(alphalessp\>"hs=s+1
+syn match skillFunction     "\<alphalessp("he=e-1
+syn match skillFunction     "(alphaNumCmp\>"hs=s+1
+syn match skillFunction     "\<alphaNumCmp("he=e-1
+syn match skillFunction     "(append1\=\>"hs=s+1
+syn match skillFunction     "\<append1\=("he=e-1
+syn match skillFunction     "(apply\>"hs=s+1
+syn match skillFunction     "\<apply("he=e-1
+syn match skillFunction     "(arrayp\>"hs=s+1
+syn match skillFunction     "\<arrayp("he=e-1
+syn match skillFunction     "(arrayref\>"hs=s+1
+syn match skillFunction     "\<arrayref("he=e-1
+syn match skillFunction     "(a\=sin\>"hs=s+1
+syn match skillFunction     "\<a\=sin("he=e-1
+syn match skillFunction     "(assoc\>"hs=s+1
+syn match skillFunction     "\<assoc("he=e-1
+syn match skillFunction     "(ass[qv]\>"hs=s+1
+syn match skillFunction     "\<ass[qv]("he=e-1
+syn match skillFunction     "(a\=tan\>"hs=s+1
+syn match skillFunction     "\<a\=tan("he=e-1
+syn match skillFunction     "(ato[fim]\>"hs=s+1
+syn match skillFunction     "\<ato[fim]("he=e-1
+syn match skillFunction     "(bcdp\>"hs=s+1
+syn match skillFunction     "\<bcdp("he=e-1
+syn match skillKeywords     "(begin\>"hs=s+1
+syn match skillKeywords     "\<begin("he=e-1
+syn match skillFunction     "(booleanp\>"hs=s+1
+syn match skillFunction     "\<booleanp("he=e-1
+syn match skillFunction     "(boundp\>"hs=s+1
+syn match skillFunction     "\<boundp("he=e-1
+syn match skillFunction     "(buildString\>"hs=s+1
+syn match skillFunction     "\<buildString("he=e-1
+syn match skillFunction     "(c[ad]{1,3}r\>"hs=s+1
+syn match skillFunction     "\<c[ad]{1,3}r("he=e-1
+syn match skillConditional  "(caseq\=\>"hs=s+1
+syn match skillConditional  "\<caseq\=("he=e-1
+syn match skillFunction     "(ceiling\>"hs=s+1
+syn match skillFunction     "\<ceiling("he=e-1
+syn match skillFunction     "(changeWorkingDir\>"hs=s+1
+syn match skillFunction     "\<changeWorkingDir("he=e-1
+syn match skillFunction     "(charToInt\>"hs=s+1
+syn match skillFunction     "\<charToInt("he=e-1
+syn match skillFunction     "(clearExitProcs\>"hs=s+1
+syn match skillFunction     "\<clearExitProcs("he=e-1
+syn match skillFunction     "(close\>"hs=s+1
+syn match skillFunction     "\<close("he=e-1
+syn match skillFunction     "(compareTime\>"hs=s+1
+syn match skillFunction     "\<compareTime("he=e-1
+syn match skillFunction     "(compress\>"hs=s+1
+syn match skillFunction     "\<compress("he=e-1
+syn match skillFunction     "(concat\>"hs=s+1
+syn match skillFunction     "\<concat("he=e-1
+syn match skillConditional  "(cond\>"hs=s+1
+syn match skillConditional  "\<cond("he=e-1
+syn match skillFunction     "(cons\>"hs=s+1
+syn match skillFunction     "\<cons("he=e-1
+syn match skillFunction     "(copy\>"hs=s+1
+syn match skillFunction     "\<copy("he=e-1
+syn match skillFunction     "(copyDefstructDeep\>"hs=s+1
+syn match skillFunction     "\<copyDefstructDeep("he=e-1
+syn match skillFunction     "(createDir\>"hs=s+1
+syn match skillFunction     "\<createDir("he=e-1
+syn match skillFunction     "(csh\>"hs=s+1
+syn match skillFunction     "\<csh("he=e-1
+syn match skillKeywords     "(declare\>"hs=s+1
+syn match skillKeywords     "\<declare("he=e-1
+syn match skillKeywords     "(declare\(N\|SQN\)\=Lambda\>"hs=s+1
+syn match skillKeywords     "\<declare\(N\|SQN\)\=Lambda("he=e-1
+syn match skillKeywords     "(defmacro\>"hs=s+1
+syn match skillKeywords     "\<defmacro("he=e-1
+syn match skillKeywords     "(defprop\>"hs=s+1
+syn match skillKeywords     "\<defprop("he=e-1
+syn match skillKeywords     "(defstruct\>"hs=s+1
+syn match skillKeywords     "\<defstruct("he=e-1
+syn match skillFunction     "(defstructp\>"hs=s+1
+syn match skillFunction     "\<defstructp("he=e-1
+syn match skillKeywords     "(defun\>"hs=s+1
+syn match skillKeywords     "\<defun("he=e-1
+syn match skillKeywords     "(defUserInitProc\>"hs=s+1
+syn match skillKeywords     "\<defUserInitProc("he=e-1
+syn match skillKeywords     "(defvar\>"hs=s+1
+syn match skillKeywords     "\<defvar("he=e-1
+syn match skillFunction     "(delete\(Dir\|File\)\>"hs=s+1
+syn match skillKeywords     "\<delete\(Dir\|File\)("he=e-1
+syn match skillFunction     "(display\>"hs=s+1
+syn match skillFunction     "\<display("he=e-1
+syn match skillFunction     "(drain\>"hs=s+1
+syn match skillFunction     "\<drain("he=e-1
+syn match skillFunction     "(dtpr\>"hs=s+1
+syn match skillFunction     "\<dtpr("he=e-1
+syn match skillFunction     "(ed\(i\|l\|it\)\=\>"hs=s+1
+syn match skillFunction     "\<ed\(i\|l\|it\)\=("he=e-1
+syn match skillFunction     "(envobj\>"hs=s+1
+syn match skillFunction     "\<envobj("he=e-1
+syn match skillFunction     "(equal\>"hs=s+1
+syn match skillFunction     "\<equal("he=e-1
+syn match skillFunction     "(eqv\=\>"hs=s+1
+syn match skillFunction     "\<eqv\=("he=e-1
+syn match skillFunction     "(err\>"hs=s+1
+syn match skillFunction     "\<err("he=e-1
+syn match skillFunction     "(error\>"hs=s+1
+syn match skillFunction     "\<error("he=e-1
+syn match skillFunction     "(errset\>"hs=s+1
+syn match skillFunction     "\<errset("he=e-1
+syn match skillFunction     "(errsetstring\>"hs=s+1
+syn match skillFunction     "\<errsetstring("he=e-1
+syn match skillFunction     "(eval\>"hs=s+1
+syn match skillFunction     "\<eval("he=e-1
+syn match skillFunction     "(evalstring\>"hs=s+1
+syn match skillFunction     "\<evalstring("he=e-1
+syn match skillFunction     "(evenp\>"hs=s+1
+syn match skillFunction     "\<evenp("he=e-1
+syn match skillFunction     "(exists\>"hs=s+1
+syn match skillFunction     "\<exists("he=e-1
+syn match skillFunction     "(exit\>"hs=s+1
+syn match skillFunction     "\<exit("he=e-1
+syn match skillFunction     "(exp\>"hs=s+1
+syn match skillFunction     "\<exp("he=e-1
+syn match skillFunction     "(expandMacro\>"hs=s+1
+syn match skillFunction     "\<expandMacro("he=e-1
+syn match skillFunction     "(file\(Length\|Seek\|Tell\|TimeModified\)\>"hs=s+1
+syn match skillFunction     "\<file\(Length\|Seek\|Tell\|TimeModified\)("he=e-1
+syn match skillFunction     "(fixp\=\>"hs=s+1
+syn match skillFunction     "\<fixp\=("he=e-1
+syn match skillFunction     "(floatp\=\>"hs=s+1
+syn match skillFunction     "\<floatp\=("he=e-1
+syn match skillFunction     "(floor\>"hs=s+1
+syn match skillFunction     "\<floor("he=e-1
+syn match skillRepeat       "(for\(all\|each\)\=\>"hs=s+1
+syn match skillRepeat       "\<for\(all\|each\)\=("he=e-1
+syn match skillFunction     "([fs]\=printf\>"hs=s+1
+syn match skillFunction     "\<[fs]\=printf("he=e-1
+syn match skillFunction     "(f\=scanf\>"hs=s+1
+syn match skillFunction     "\<f\=scanf("he=e-1
+syn match skillFunction     "(funobj\>"hs=s+1
+syn match skillFunction     "\<funobj("he=e-1
+syn match skillFunction     "(gc\>"hs=s+1
+syn match skillFunction     "\<gc("he=e-1
+syn match skillFunction     "(gensym\>"hs=s+1
+syn match skillFunction     "\<gensym("he=e-1
+syn match skillFunction     "(get\(_pname\|_string\)\=\>"hs=s+1
+syn match skillFunction     "\<get\(_pname\|_string\)\=("he=e-1
+syn match skillFunction     "(getc\(har\)\=\>"hs=s+1
+syn match skillFunction     "\<getc\(har\)\=("he=e-1
+syn match skillFunction     "(getCurrentTime\>"hs=s+1
+syn match skillFunction     "\<getCurrentTime("he=e-1
+syn match skillFunction     "(getd\>"hs=s+1
+syn match skillFunction     "\<getd("he=e-1
+syn match skillFunction     "(getDirFiles\>"hs=s+1
+syn match skillFunction     "\<getDirFiles("he=e-1
+syn match skillFunction     "(getFnWriteProtect\>"hs=s+1
+syn match skillFunction     "\<getFnWriteProtect("he=e-1
+syn match skillFunction     "(getRunType\>"hs=s+1
+syn match skillFunction     "\<getRunType("he=e-1
+syn match skillFunction     "(getInstallPath\>"hs=s+1
+syn match skillFunction     "\<getInstallPath("he=e-1
+syn match skillFunction     "(getqq\=\>"hs=s+1
+syn match skillFunction     "\<getqq\=("he=e-1
+syn match skillFunction     "(gets\>"hs=s+1
+syn match skillFunction     "\<gets("he=e-1
+syn match skillFunction     "(getShellEnvVar\>"hs=s+1
+syn match skillFunction     "\<getShellEnvVar("he=e-1
+syn match skillFunction     "(getSkill\(Path\|Version\)\>"hs=s+1
+syn match skillFunction     "\<getSkill\(Path\|Version\)("he=e-1
+syn match skillFunction     "(getVarWriteProtect\>"hs=s+1
+syn match skillFunction     "\<getVarWriteProtect("he=e-1
+syn match skillFunction     "(getVersion\>"hs=s+1
+syn match skillFunction     "\<getVersion("he=e-1
+syn match skillFunction     "(getWarn\>"hs=s+1
+syn match skillFunction     "\<getWarn("he=e-1
+syn match skillFunction     "(getWorkingDir\>"hs=s+1
+syn match skillFunction     "\<getWorkingDir("he=e-1
+syn match skillRepeat       "(go\>"hs=s+1
+syn match skillRepeat       "\<go("he=e-1
+syn match skillConditional  "(if\>"hs=s+1
+syn match skillConditional  "\<if("he=e-1
+syn keyword skillConditional then else
+syn match skillFunction     "(index\>"hs=s+1
+syn match skillFunction     "\<index("he=e-1
+syn match skillFunction     "(infile\>"hs=s+1
+syn match skillFunction     "\<infile("he=e-1
+syn match skillFunction     "(inportp\>"hs=s+1
+syn match skillFunction     "\<inportp("he=e-1
+syn match skillFunction     "(in\(Scheme\|Skill\)\>"hs=s+1
+syn match skillFunction     "\<in\(Scheme\|Skill\)("he=e-1
+syn match skillFunction     "(instring\>"hs=s+1
+syn match skillFunction     "\<instring("he=e-1
+syn match skillFunction     "(integerp\>"hs=s+1
+syn match skillFunction     "\<integerp("he=e-1
+syn match skillFunction     "(intToChar\>"hs=s+1
+syn match skillFunction     "\<intToChar("he=e-1
+syn match skillFunction     "(is\(Callable\|Dir\|Executable\|File\|FileEncrypted\|FileName\|Link\|Macro\|Writable\)\>"hs=s+1
+syn match skillFunction     "\<is\(Callable\|Dir\|Executable\|File\|FileEncrypted\|FileName\|Link\|Macro\|Writable\)("he=e-1
+syn match skillKeywords     "(n\=lambda\>"hs=s+1
+syn match skillKeywords     "\<n\=lambda("he=e-1
+syn match skillKeywords     "(last\>"hs=s+1
+syn match skillKeywords     "\<last("he=e-1
+syn match skillFunction     "(lconc\>"hs=s+1
+syn match skillFunction     "\<lconc("he=e-1
+syn match skillFunction     "(length\>"hs=s+1
+syn match skillFunction     "\<length("he=e-1
+syn match skillKeywords     "(let\>"hs=s+1
+syn match skillKeywords     "\<let("he=e-1
+syn match skillFunction     "(lineread\(string\)\=\>"hs=s+1
+syn match skillFunction     "\<lineread\(string\)\=("he=e-1
+syn match skillKeywords     "(list\>"hs=s+1
+syn match skillKeywords     "\<list("he=e-1
+syn match skillFunction     "(listp\>"hs=s+1
+syn match skillFunction     "\<listp("he=e-1
+syn match skillFunction     "(listToVector\>"hs=s+1
+syn match skillFunction     "\<listToVector("he=e-1
+syn match skillFunction     "(loadi\=\>"hs=s+1
+syn match skillFunction     "\<loadi\=("he=e-1
+syn match skillFunction     "(loadstring\>"hs=s+1
+syn match skillFunction     "\<loadstring("he=e-1
+syn match skillFunction     "(log\>"hs=s+1
+syn match skillFunction     "\<log("he=e-1
+syn match skillFunction     "(lowerCase\>"hs=s+1
+syn match skillFunction     "\<lowerCase("he=e-1
+syn match skillFunction     "(makeTable\>"hs=s+1
+syn match skillFunction     "\<makeTable("he=e-1
+syn match skillFunction     "(makeTempFileName\>"hs=s+1
+syn match skillFunction     "\<makeTempFileName("he=e-1
+syn match skillFunction     "(makeVector\>"hs=s+1
+syn match skillFunction     "\<makeVector("he=e-1
+syn match skillFunction     "(map\(c\|can\|car\|list\)\>"hs=s+1
+syn match skillFunction     "\<map\(c\|can\|car\|list\)("he=e-1
+syn match skillFunction     "(max\>"hs=s+1
+syn match skillFunction     "\<max("he=e-1
+syn match skillFunction     "(measureTime\>"hs=s+1
+syn match skillFunction     "\<measureTime("he=e-1
+syn match skillFunction     "(member\>"hs=s+1
+syn match skillFunction     "\<member("he=e-1
+syn match skillFunction     "(mem[qv]\>"hs=s+1
+syn match skillFunction     "\<mem[qv]("he=e-1
+syn match skillFunction     "(min\>"hs=s+1
+syn match skillFunction     "\<min("he=e-1
+syn match skillFunction     "(minusp\>"hs=s+1
+syn match skillFunction     "\<minusp("he=e-1
+syn match skillFunction     "(mod\(ulo\)\=\>"hs=s+1
+syn match skillFunction     "\<mod\(ulo\)\=("he=e-1
+syn match skillKeywords     "([mn]\=procedure\>"hs=s+1
+syn match skillKeywords     "\<[mn]\=procedure("he=e-1
+syn match skillFunction     "(ncon[cs]\>"hs=s+1
+syn match skillFunction     "\<ncon[cs]("he=e-1
+syn match skillFunction     "(needNCells\>"hs=s+1
+syn match skillFunction     "\<needNCells("he=e-1
+syn match skillFunction     "(negativep\>"hs=s+1
+syn match skillFunction     "\<negativep("he=e-1
+syn match skillFunction     "(neq\(ual\)\=\>"hs=s+1
+syn match skillFunction     "\<neq\(ual\)\=("he=e-1
+syn match skillFunction     "(newline\>"hs=s+1
+syn match skillFunction     "\<newline("he=e-1
+syn match skillFunction     "(nindex\>"hs=s+1
+syn match skillFunction     "\<nindex("he=e-1
+syn match skillFunction     "(not\>"hs=s+1
+syn match skillFunction     "\<not("he=e-1
+syn match skillFunction     "(nth\(cdr\|elem\)\=\>"hs=s+1
+syn match skillFunction     "\<nth\(cdr\|elem\)\=("he=e-1
+syn match skillFunction     "(null\>"hs=s+1
+syn match skillFunction     "\<null("he=e-1
+syn match skillFunction     "(numberp\>"hs=s+1
+syn match skillFunction     "\<numberp("he=e-1
+syn match skillFunction     "(numOpenFiles\>"hs=s+1
+syn match skillFunction     "\<numOpenFiles("he=e-1
+syn match skillFunction     "(oddp\>"hs=s+1
+syn match skillFunction     "\<oddp("he=e-1
+syn match skillFunction     "(onep\>"hs=s+1
+syn match skillFunction     "\<onep("he=e-1
+syn match skillFunction     "(otherp\>"hs=s+1
+syn match skillFunction     "\<otherp("he=e-1
+syn match skillFunction     "(outfile\>"hs=s+1
+syn match skillFunction     "\<outfile("he=e-1
+syn match skillFunction     "(outportp\>"hs=s+1
+syn match skillFunction     "\<outportp("he=e-1
+syn match skillFunction     "(pairp\>"hs=s+1
+syn match skillFunction     "\<pairp("he=e-1
+syn match skillFunction     "(parseString\>"hs=s+1
+syn match skillFunction     "\<parseString("he=e-1
+syn match skillFunction     "(plist\>"hs=s+1
+syn match skillFunction     "\<plist("he=e-1
+syn match skillFunction     "(plusp\>"hs=s+1
+syn match skillFunction     "\<plusp("he=e-1
+syn match skillFunction     "(portp\>"hs=s+1
+syn match skillFunction     "\<portp("he=e-1
+syn match skillFunction     "(p\=print\>"hs=s+1
+syn match skillFunction     "\<p\=print("he=e-1
+syn match skillFunction     "(prependInstallPath\>"hs=s+1
+syn match skillFunction     "\<prependInstallPath("he=e-1
+syn match skillFunction     "(printl\(ev\|n\)\>"hs=s+1
+syn match skillFunction     "\<printl\(ev\|n\)("he=e-1
+syn match skillFunction     "(procedurep\>"hs=s+1
+syn match skillFunction     "\<procedurep("he=e-1
+syn match skillKeywords     "(prog[12n]\=\>"hs=s+1
+syn match skillKeywords     "\<prog[12n]\=("he=e-1
+syn match skillFunction     "(putd\>"hs=s+1
+syn match skillFunction     "\<putd("he=e-1
+syn match skillFunction     "(putpropq\{,2}\>"hs=s+1
+syn match skillFunction     "\<putpropq\{,2}("he=e-1
+syn match skillFunction     "(random\>"hs=s+1
+syn match skillFunction     "\<random("he=e-1
+syn match skillFunction     "(read\>"hs=s+1
+syn match skillFunction     "\<read("he=e-1
+syn match skillFunction     "(readString\>"hs=s+1
+syn match skillFunction     "\<readString("he=e-1
+syn match skillFunction     "(readTable\>"hs=s+1
+syn match skillFunction     "\<readTable("he=e-1
+syn match skillFunction     "(realp\>"hs=s+1
+syn match skillFunction     "\<realp("he=e-1
+syn match skillFunction     "(regExit\(After\|Before\)\>"hs=s+1
+syn match skillFunction     "\<regExit\(After\|Before\)("he=e-1
+syn match skillFunction     "(remainder\>"hs=s+1
+syn match skillFunction     "\<remainder("he=e-1
+syn match skillFunction     "(remdq\=\>"hs=s+1
+syn match skillFunction     "\<remdq\=("he=e-1
+syn match skillFunction     "(remExitProc\>"hs=s+1
+syn match skillFunction     "\<remExitProc("he=e-1
+syn match skillFunction     "(remove\>"hs=s+1
+syn match skillFunction     "\<remove("he=e-1
+syn match skillFunction     "(remprop\>"hs=s+1
+syn match skillFunction     "\<remprop("he=e-1
+syn match skillFunction     "(remq\>"hs=s+1
+syn match skillFunction     "\<remq("he=e-1
+syn match skillKeywords     "(return\>"hs=s+1
+syn match skillKeywords     "\<return("he=e-1
+syn match skillFunction     "(reverse\>"hs=s+1
+syn match skillFunction     "\<reverse("he=e-1
+syn match skillFunction     "(rexCompile\>"hs=s+1
+syn match skillFunction     "\<rexCompile("he=e-1
+syn match skillFunction     "(rexExecute\>"hs=s+1
+syn match skillFunction     "\<rexExecute("he=e-1
+syn match skillFunction     "(rexMagic\>"hs=s+1
+syn match skillFunction     "\<rexMagic("he=e-1
+syn match skillFunction     "(rexMatchAssocList\>"hs=s+1
+syn match skillFunction     "\<rexMatchAssocList("he=e-1
+syn match skillFunction     "(rexMatchList\>"hs=s+1
+syn match skillFunction     "\<rexMatchList("he=e-1
+syn match skillFunction     "(rexMatchp\>"hs=s+1
+syn match skillFunction     "\<rexMatchp("he=e-1
+syn match skillFunction     "(rexReplace\>"hs=s+1
+syn match skillFunction     "\<rexReplace("he=e-1
+syn match skillFunction     "(rexSubstitute\>"hs=s+1
+syn match skillFunction     "\<rexSubstitute("he=e-1
+syn match skillFunction     "(rindex\>"hs=s+1
+syn match skillFunction     "\<rindex("he=e-1
+syn match skillFunction     "(round\>"hs=s+1
+syn match skillFunction     "\<round("he=e-1
+syn match skillFunction     "(rplac[ad]\>"hs=s+1
+syn match skillFunction     "\<rplac[ad]("he=e-1
+syn match skillFunction     "(schemeTopLevelEnv\>"hs=s+1
+syn match skillFunction     "\<schemeTopLevelEnv("he=e-1
+syn match skillFunction     "(set\>"hs=s+1
+syn match skillFunction     "\<set("he=e-1
+syn match skillFunction     "(setarray\>"hs=s+1
+syn match skillFunction     "\<setarray("he=e-1
+syn match skillFunction     "(setc[ad]r\>"hs=s+1
+syn match skillFunction     "\<setc[ad]r("he=e-1
+syn match skillFunction     "(setFnWriteProtect\>"hs=s+1
+syn match skillFunction     "\<setFnWriteProtect("he=e-1
+syn match skillFunction     "(setof\>"hs=s+1
+syn match skillFunction     "\<setof("he=e-1
+syn match skillFunction     "(setplist\>"hs=s+1
+syn match skillFunction     "\<setplist("he=e-1
+syn match skillFunction     "(setq\>"hs=s+1
+syn match skillFunction     "\<setq("he=e-1
+syn match skillFunction     "(setShellEnvVar\>"hs=s+1
+syn match skillFunction     "\<setShellEnvVar("he=e-1
+syn match skillFunction     "(setSkillPath\>"hs=s+1
+syn match skillFunction     "\<setSkillPath("he=e-1
+syn match skillFunction     "(setVarWriteProtect\>"hs=s+1
+syn match skillFunction     "\<setVarWriteProtect("he=e-1
+syn match skillFunction     "(sh\(ell\)\=\>"hs=s+1
+syn match skillFunction     "\<sh\(ell\)\=("he=e-1
+syn match skillFunction     "(simplifyFilename\>"hs=s+1
+syn match skillFunction     "\<simplifyFilename("he=e-1
+syn match skillFunction     "(sort\(car\)\=\>"hs=s+1
+syn match skillFunction     "\<sort\(car\)\=("he=e-1
+syn match skillFunction     "(sqrt\>"hs=s+1
+syn match skillFunction     "\<sqrt("he=e-1
+syn match skillFunction     "(srandom\>"hs=s+1
+syn match skillFunction     "\<srandom("he=e-1
+syn match skillFunction     "(sstatus\>"hs=s+1
+syn match skillFunction     "\<sstatus("he=e-1
+syn match skillFunction     "(strn\=cat\>"hs=s+1
+syn match skillFunction     "\<strn\=cat("he=e-1
+syn match skillFunction     "(strn\=cmp\>"hs=s+1
+syn match skillFunction     "\<strn\=cmp("he=e-1
+syn match skillFunction     "(stringp\>"hs=s+1
+syn match skillFunction     "\<stringp("he=e-1
+syn match skillFunction     "(stringTo\(Function\|Symbol\|Time\)\>"hs=s+1
+syn match skillFunction     "\<stringTo\(Function\|Symbol\|Time\)("he=e-1
+syn match skillFunction     "(strlen\>"hs=s+1
+syn match skillFunction     "\<strlen("he=e-1
+syn match skillFunction     "(sub1\>"hs=s+1
+syn match skillFunction     "\<sub1("he=e-1
+syn match skillFunction     "(subst\>"hs=s+1
+syn match skillFunction     "\<subst("he=e-1
+syn match skillFunction     "(substring\>"hs=s+1
+syn match skillFunction     "\<substring("he=e-1
+syn match skillFunction     "(sxtd\>"hs=s+1
+syn match skillFunction     "\<sxtd("he=e-1
+syn match skillFunction     "(symbolp\>"hs=s+1
+syn match skillFunction     "\<symbolp("he=e-1
+syn match skillFunction     "(symbolToString\>"hs=s+1
+syn match skillFunction     "\<symbolToString("he=e-1
+syn match skillFunction     "(symeval\>"hs=s+1
+syn match skillFunction     "\<symeval("he=e-1
+syn match skillFunction     "(symstrp\>"hs=s+1
+syn match skillFunction     "\<symstrp("he=e-1
+syn match skillFunction     "(system\>"hs=s+1
+syn match skillFunction     "\<system("he=e-1
+syn match skillFunction     "(tablep\>"hs=s+1
+syn match skillFunction     "\<tablep("he=e-1
+syn match skillFunction     "(tableToList\>"hs=s+1
+syn match skillFunction     "\<tableToList("he=e-1
+syn match skillFunction     "(tailp\>"hs=s+1
+syn match skillFunction     "\<tailp("he=e-1
+syn match skillFunction     "(tconc\>"hs=s+1
+syn match skillFunction     "\<tconc("he=e-1
+syn match skillFunction     "(timeToString\>"hs=s+1
+syn match skillFunction     "\<timeToString("he=e-1
+syn match skillFunction     "(timeToTm\>"hs=s+1
+syn match skillFunction     "\<timeToTm("he=e-1
+syn match skillFunction     "(tmToTime\>"hs=s+1
+syn match skillFunction     "\<tmToTime("he=e-1
+syn match skillFunction     "(truncate\>"hs=s+1
+syn match skillFunction     "\<truncate("he=e-1
+syn match skillFunction     "(typep\=\>"hs=s+1
+syn match skillFunction     "\<typep\=("he=e-1
+syn match skillFunction     "(unalias\>"hs=s+1
+syn match skillFunction     "\<unalias("he=e-1
+syn match skillConditional  "(unless\>"hs=s+1
+syn match skillConditional  "\<unless("he=e-1
+syn match skillFunction     "(upperCase\>"hs=s+1
+syn match skillFunction     "\<upperCase("he=e-1
+syn match skillFunction     "(vector\(ToList\)\=\>"hs=s+1
+syn match skillFunction     "\<vector\(ToList\)\=("he=e-1
+syn match skillFunction     "(warn\>"hs=s+1
+syn match skillFunction     "\<warn("he=e-1
+syn match skillConditional  "(when\>"hs=s+1
+syn match skillConditional  "\<when("he=e-1
+syn match skillRepeat       "(while\>"hs=s+1
+syn match skillRepeat       "\<while("he=e-1
+syn match skillFunction     "(write\>"hs=s+1
+syn match skillFunction     "\<write("he=e-1
+syn match skillFunction     "(writeTable\>"hs=s+1
+syn match skillFunction     "\<writeTable("he=e-1
+syn match skillFunction     "(xcons\>"hs=s+1
+syn match skillFunction     "\<xcons("he=e-1
+syn match skillFunction     "(zerop\>"hs=s+1
+syn match skillFunction     "\<zerop("he=e-1
+syn match skillFunction     "(zxtd\>"hs=s+1
+syn match skillFunction     "\<zxtd("he=e-1
+
+" DFII procedural interface routines
+
+" CDF functions
+syn match skillcdfFunctions			"(cdf\u\a\+\>"hs=s+1
+syn match skillcdfFunctions			"\<cdf\u\a\+("he=e-1
+" graphic editor functions
+syn match skillgeFunctions			"(ge\u\a\+\>"hs=s+1
+syn match skillgeFunctions			"\<ge\u\a\+("he=e-1
+" human interface functions
+syn match skillhiFunctions			"(hi\u\a\+\>"hs=s+1
+syn match skillhiFunctions			"\<hi\u\a\+("he=e-1
+" layout editor functions
+syn match skillleFunctions			"(le\u\a\+\>"hs=s+1
+syn match skillleFunctions			"\<le\u\a\+("he=e-1
+" database|design editor|design flow functions
+syn match skilldbefFunctions		"(d[bef]\u\a\+\>"hs=s+1
+syn match skilldbefFunctions		"\<d[bef]\u\a\+("he=e-1
+" design management & design data services functions
+syn match skillddFunctions			"(dd[s]\=\u\a\+\>"hs=s+1
+syn match skillddFunctions			"\<dd[s]\=\u\a\+("he=e-1
+" parameterized cell functions
+syn match skillpcFunctions			"(pc\u\a\+\>"hs=s+1
+syn match skillpcFunctions			"\<pc\u\a\+("he=e-1
+" tech file functions
+syn match skilltechFunctions		"(\(tech\|tc\)\u\a\+\>"hs=s+1
+syn match skilltechFunctions		"\<\(tech\|tc\)\u\a\+("he=e-1
+
+" strings
+syn region skillString				start=+"+ skip=+\\"+ end=+"+
+
+syn keyword skillTodo contained		TODO FIXME XXX
+syn keyword skillNote contained		NOTE IMPORTANT
+
+" comments are either C-style or begin with a semicolon
+syn region skillComment				start="/\*" end="\*/" contains=skillTodo,skillNote
+syn match skillComment				";.*" contains=skillTodo,skillNote
+syn match skillCommentError			"\*/"
+
+syn sync ccomment skillComment minlines=10
+
+" Define the default highlighting.
+" For version 5.7 and earlier: only when not done already
+" For version 5.8 and later: only when an item doesn't have highlighting yet
+if version >= 508 || !exists("did_skill_syntax_inits")
+  if version < 508
+    let did_skill_syntax_inits = 1
+    command -nargs=+ HiLink hi link <args>
+  else
+    command -nargs=+ HiLink hi def link <args>
+  endif
+
+	HiLink skillcdfFunctions	Function
+	HiLink skillgeFunctions		Function
+	HiLink skillhiFunctions		Function
+	HiLink skillleFunctions		Function
+	HiLink skilldbefFunctions	Function
+	HiLink skillddFunctions		Function
+	HiLink skillpcFunctions		Function
+	HiLink skilltechFunctions	Function
+	HiLink skillConstants		Constant
+	HiLink skillFunction		Function
+	HiLink skillKeywords		Statement
+	HiLink skillConditional		Conditional
+	HiLink skillRepeat			Repeat
+	HiLink skillString			String
+	HiLink skillTodo			Todo
+	HiLink skillNote			Todo
+	HiLink skillComment			Comment
+	HiLink skillCommentError	Error
+
+	delcommand HiLink
+endif
+
+let b:current_syntax = "skill"
+
+" vim: ts=4
--- /dev/null
+++ b/lib/vimfiles/syntax/sl.vim
@@ -1,0 +1,120 @@
+" Vim syntax file
+" Language:	Renderman shader language
+" Maintainer:	Dan Piponi <dan@tanelorn.demon.co.uk>
+" Last Change:	2001 May 09
+
+" For version 5.x: Clear all syntax items
+" For version 6.x: Quit when a syntax file was already loaded
+if version < 600
+  syntax clear
+elseif exists("b:current_syntax")
+  finish
+endif
+
+" A bunch of useful Renderman keywords including special
+" RenderMan control structures
+syn keyword slStatement	break return continue
+syn keyword slConditional	if else
+syn keyword slRepeat		while for
+syn keyword slRepeat		illuminance illuminate solar
+
+syn keyword slTodo contained	TODO FIXME XXX
+
+" String and Character constants
+" Highlight special characters (those which have a backslash) differently
+syn match slSpecial contained	"\\[0-9][0-9][0-9]\|\\."
+syn region slString		start=+"+ skip=+\\\\\|\\"+ end=+"+ contains=slSpecial
+syn match slCharacter		"'[^\\]'"
+syn match slSpecialCharacter	"'\\.'"
+syn match slSpecialCharacter	"'\\[0-9][0-9]'"
+syn match slSpecialCharacter	"'\\[0-9][0-9][0-9]'"
+
+"catch errors caused by wrong parenthesis
+syn region slParen		transparent start='(' end=')' contains=ALLBUT,slParenError,slIncluded,slSpecial,slTodo,slUserLabel
+syn match slParenError		")"
+syn match slInParen contained	"[{}]"
+
+"integer number, or floating point number without a dot and with "f".
+syn case ignore
+syn match slNumber		"\<[0-9]\+\(u\=l\=\|lu\|f\)\>"
+"floating point number, with dot, optional exponent
+syn match slFloat		"\<[0-9]\+\.[0-9]*\(e[-+]\=[0-9]\+\)\=[fl]\=\>"
+"floating point number, starting with a dot, optional exponent
+syn match slFloat		"\.[0-9]\+\(e[-+]\=[0-9]\+\)\=[fl]\=\>"
+"floating point number, without dot, with exponent
+syn match slFloat		"\<[0-9]\+e[-+]\=[0-9]\+[fl]\=\>"
+"hex number
+syn match slNumber		"\<0x[0-9a-f]\+\(u\=l\=\|lu\)\>"
+"syn match slIdentifier	"\<[a-z_][a-z0-9_]*\>"
+syn case match
+
+if exists("sl_comment_strings")
+  " A comment can contain slString, slCharacter and slNumber.
+  " But a "*/" inside a slString in a slComment DOES end the comment!  So we
+  " need to use a special type of slString: slCommentString, which also ends on
+  " "*/", and sees a "*" at the start of the line as comment again.
+  " Unfortunately this doesn't very well work for // type of comments :-(
+  syntax match slCommentSkip	contained "^\s*\*\($\|\s\+\)"
+  syntax region slCommentString	contained start=+"+ skip=+\\\\\|\\"+ end=+"+ end=+\*/+me=s-1 contains=slSpecial,slCommentSkip
+  syntax region slComment2String	contained start=+"+ skip=+\\\\\|\\"+ end=+"+ end="$" contains=slSpecial
+  syntax region slComment	start="/\*" end="\*/" contains=slTodo,slCommentString,slCharacter,slNumber
+else
+  syn region slComment		start="/\*" end="\*/" contains=slTodo
+endif
+syntax match slCommentError	"\*/"
+
+syn keyword slOperator	sizeof
+syn keyword slType		float point color string vector normal matrix void
+syn keyword slStorageClass	varying uniform extern
+syn keyword slStorageClass	light surface volume displacement transformation imager
+syn keyword slVariable	Cs Os P dPdu dPdv N Ng u v du dv s t
+syn keyword slVariable L Cl Ol E I ncomps time Ci Oi
+syn keyword slVariable Ps alpha
+syn keyword slVariable dtime dPdtime
+
+syn sync ccomment slComment minlines=10
+
+" Define the default highlighting.
+" For version 5.7 and earlier: only when not done already
+" For version 5.8 and later: only when an item doesn't have highlighting yet
+if version >= 508 || !exists("did_sl_syntax_inits")
+  if version < 508
+    let did_sl_syntax_inits = 1
+    command -nargs=+ HiLink hi link <args>
+  else
+    command -nargs=+ HiLink hi def link <args>
+  endif
+
+  HiLink slLabel	Label
+  HiLink slUserLabel	Label
+  HiLink slConditional	Conditional
+  HiLink slRepeat	Repeat
+  HiLink slCharacter	Character
+  HiLink slSpecialCharacter slSpecial
+  HiLink slNumber	Number
+  HiLink slFloat	Float
+  HiLink slParenError	slError
+  HiLink slInParen	slError
+  HiLink slCommentError	slError
+  HiLink slOperator	Operator
+  HiLink slStorageClass	StorageClass
+  HiLink slError	Error
+  HiLink slStatement	Statement
+  HiLink slType		Type
+  HiLink slCommentError	slError
+  HiLink slCommentString slString
+  HiLink slComment2String slString
+  HiLink slCommentSkip	slComment
+  HiLink slString	String
+  HiLink slComment	Comment
+  HiLink slSpecial	SpecialChar
+  HiLink slTodo	Todo
+  HiLink slVariable	Identifier
+  "HiLink slIdentifier	Identifier
+
+  delcommand HiLink
+endif
+
+let b:current_syntax = "sl"
+
+" vim: ts=8
--- /dev/null
+++ b/lib/vimfiles/syntax/slang.vim
@@ -1,0 +1,102 @@
+" Vim syntax file
+" Language:	S-Lang
+" Maintainer:	Jan Hlavacek <lahvak@math.ohio-state.edu>
+" Last Change:	980216
+
+" For version 5.x: Clear all syntax items
+" For version 6.x: Quit when a syntax file was already loaded
+if version < 600
+  syntax clear
+elseif exists("b:current_syntax")
+  finish
+endif
+
+syn keyword slangStatement	break return continue EXECUTE_ERROR_BLOCK
+syn match slangStatement	"\<X_USER_BLOCK[0-4]\>"
+syn keyword slangLabel		case
+syn keyword slangConditional	!if if else switch
+syn keyword slangRepeat		while for _for loop do forever
+syn keyword slangDefinition	define typedef variable struct
+syn keyword slangOperator	or and andelse orelse shr shl xor not
+syn keyword slangBlock		EXIT_BLOCK ERROR_BLOCK
+syn match slangBlock		"\<USER_BLOCK[0-4]\>"
+syn keyword slangConstant	NULL
+syn keyword slangType		Integer_Type Double_Type Complex_Type String_Type Struct_Type Ref_Type Null_Type Array_Type DataType_Type
+
+syn match slangOctal		"\<0\d\+\>" contains=slangOctalError
+syn match slangOctalError	"[89]\+" contained
+syn match slangHex		"\<0[xX][0-9A-Fa-f]*\>"
+syn match slangDecimal		"\<[1-9]\d*\>"
+syn match slangFloat		"\<\d\+\."
+syn match slangFloat		"\<\d\+\.\d\+\([Ee][-+]\=\d\+\)\=\>"
+syn match slangFloat		"\<\d\+\.[Ee][-+]\=\d\+\>"
+syn match slangFloat		"\<\d\+[Ee][-+]\=\d\+\>"
+syn match slangFloat		"\.\d\+\([Ee][-+]\=\d\+\)\=\>"
+syn match slangImaginary	"\.\d\+\([Ee][-+]\=\d*\)\=[ij]\>"
+syn match slangImaginary	"\<\d\+\(\.\d*\)\=\([Ee][-+]\=\d\+\)\=[ij]\>"
+
+syn region slangString oneline start='"' end='"' skip='\\"'
+syn match slangCharacter	"'[^\\]'"
+syn match slangCharacter	"'\\.'"
+syn match slangCharacter	"'\\[0-7]\{1,3}'"
+syn match slangCharacter	"'\\d\d\{1,3}'"
+syn match slangCharacter	"'\\x[0-7a-fA-F]\{1,2}'"
+
+syn match slangDelim		"[][{};:,]"
+syn match slangOperator		"[-%+/&*=<>|!~^@]"
+
+"catch errors caused by wrong parenthesis
+syn region slangParen	matchgroup=slangDelim transparent start='(' end=')' contains=ALLBUT,slangParenError
+syn match slangParenError	")"
+
+syn match slangComment		"%.*$"
+syn keyword slangOperator	sizeof
+
+syn region slangPreCondit start="^\s*#\s*\(ifdef\>\|ifndef\>\|iftrue\>\|ifnfalse\>\|iffalse\>\|ifntrue\>\|if\$\|ifn\$\|\|elif\>\|else\>\|endif\>\)" skip="\\$" end="$" contains=cComment,slangString,slangCharacter,slangNumber
+
+" Define the default highlighting.
+" For version 5.7 and earlier: only when not done already
+" For version 5.8 and later: only when an item doesn't have highlighting yet
+if version >= 508 || !exists("did_slang_syntax_inits")
+  if version < 508
+    let did_slang_syntax_inits = 1
+    command -nargs=+ HiLink hi link <args>
+  else
+    command -nargs=+ HiLink hi def link <args>
+  endif
+
+  HiLink slangDefinition	Type
+  HiLink slangBlock		slangDefinition
+  HiLink slangLabel		Label
+  HiLink slangConditional	Conditional
+  HiLink slangRepeat		Repeat
+  HiLink slangCharacter	Character
+  HiLink slangFloat		Float
+  HiLink slangImaginary	Float
+  HiLink slangDecimal		slangNumber
+  HiLink slangOctal		slangNumber
+  HiLink slangHex		slangNumber
+  HiLink slangNumber		Number
+  HiLink slangParenError	Error
+  HiLink slangOctalError	Error
+  HiLink slangOperator		Operator
+  HiLink slangStructure	Structure
+  HiLink slangInclude		Include
+  HiLink slangPreCondit	PreCondit
+  HiLink slangError		Error
+  HiLink slangStatement	Statement
+  HiLink slangType		Type
+  HiLink slangString		String
+  HiLink slangConstant		Constant
+  HiLink slangRangeArray	slangConstant
+  HiLink slangComment		Comment
+  HiLink slangSpecial		SpecialChar
+  HiLink slangTodo		Todo
+  HiLink slangDelim		Delimiter
+
+  delcommand HiLink
+endif
+
+let b:current_syntax = "slang"
+
+" vim: ts=8
--- /dev/null
+++ b/lib/vimfiles/syntax/slice.vim
@@ -1,0 +1,90 @@
+" Vim syntax file
+" Language:	Slice (ZeroC's Specification Language for Ice)
+" Maintainer:	Morel Bodin <slice06@nym.hush.com>
+" Last Change:	2005 Dec 03
+
+" For version 5.x: Clear all syntax items
+" For version 6.x: Quit when a syntax file was already loaded
+if version < 600
+  syntax clear
+elseif exists("b:current_syntax")
+  finish
+endif
+
+" The Slice keywords
+
+syn keyword sliceType	    bool byte double float int long short string void
+syn keyword sliceQualifier  const extends idempotent implements local nonmutating out throws
+syn keyword sliceConstruct  class enum exception dictionary interface module LocalObject Object sequence struct
+syn keyword sliceQualifier  const extends idempotent implements local nonmutating out throws
+syn keyword sliceBoolean    false true
+
+" Include directives
+syn match   sliceIncluded   display contained "<[^>]*>"
+syn match   sliceInclude    display "^\s*#\s*include\>\s*["<]" contains=sliceIncluded
+
+" Double-include guards
+syn region  sliceGuard      start="^#\(define\|ifndef\|endif\)" end="$"
+
+" Strings and characters
+syn region sliceString		start=+"+  end=+"+
+
+" Numbers (shamelessly ripped from c.vim, only slightly modified)
+"integer number, or floating point number without a dot and with "f".
+syn case ignore
+syn match   sliceNumbers    display transparent "\<\d\|\.\d" contains=sliceNumber,sliceFloat,sliceOctal
+syn match   sliceNumber     display contained "\d\+"
+"hex number
+syn match   sliceNumber     display contained "0x\x\+\(u\=l\{0,2}\|ll\=u\)\>"
+" Flag the first zero of an octal number as something special
+syn match   sliceOctal      display contained "0\o\+\(u\=l\{0,2}\|ll\=u\)\>" contains=sliceOctalZero
+syn match   sliceOctalZero  display contained "\<0"
+syn match   sliceFloat      display contained "\d\+f"
+"floating point number, with dot, optional exponent
+syn match   sliceFloat      display contained "\d\+\.\d*\(e[-+]\=\d\+\)\=[fl]\="
+"floating point number, starting with a dot, optional exponent
+syn match   sliceFloat      display contained "\.\d\+\(e[-+]\=\d\+\)\=[fl]\=\>"
+"floating point number, without dot, with exponent
+syn match   sliceFloat      display contained "\d\+e[-+]\=\d\+[fl]\=\>"
+" flag an octal number with wrong digits
+syn case match
+
+
+" Comments
+syn region sliceComment    start="/\*"  end="\*/"
+syn match sliceComment	"//.*"
+
+syn sync ccomment sliceComment
+
+" Define the default highlighting.
+" For version 5.7 and earlier: only when not done already
+" For version 5.8 and later: only when an item doesn't have highlighting yet
+if version >= 508 || !exists("did_slice_syn_inits")
+  if version < 508
+    let did_slice_syn_inits = 1
+    command -nargs=+ HiLink hi link <args>
+  else
+    command -nargs=+ HiLink hi def link <args>
+  endif
+
+  HiLink sliceComment	Comment
+  HiLink sliceConstruct	Keyword
+  HiLink sliceType	Type
+  HiLink sliceString	String
+  HiLink sliceIncluded	String
+  HiLink sliceQualifier	Keyword
+  HiLink sliceInclude	Include
+  HiLink sliceGuard	PreProc
+  HiLink sliceBoolean	Boolean
+  HiLink sliceFloat	Number
+  HiLink sliceNumber	Number
+  HiLink sliceOctal	Number
+  HiLink sliceOctalZero	Special
+  HiLink sliceNumberError Special
+
+  delcommand HiLink
+endif
+
+let b:current_syntax = "slice"
+
+" vim: ts=8
--- /dev/null
+++ b/lib/vimfiles/syntax/slpconf.vim
@@ -1,0 +1,273 @@
+" Vim syntax file
+" Language:         RFC 2614 - An API for Service Location configuration file
+" Maintainer:       Nikolai Weibull <now@bitwi.se>
+" Latest Revision:  2006-04-19
+
+if exists("b:current_syntax")
+  finish
+endif
+
+let s:cpo_save = &cpo
+set cpo&vim
+
+syn keyword slpconfTodo         contained TODO FIXME XXX NOTE
+
+syn region  slpconfComment      display oneline start='^[#;]' end='$'
+                                \ contains=slpconfTodo,@Spell
+
+syn match   slpconfBegin        display '^'
+                                \ nextgroup=slpconfTag,
+                                \ slpconfComment skipwhite
+
+syn keyword slpconfTag          contained net
+                                \ nextgroup=slpconfNetTagDot
+
+syn match   slpconfNetTagDot    contained display '.'
+                                \ nextgroup=slpconfNetTag
+
+syn keyword slpconfNetTag       contained slp
+                                \ nextgroup=slpconfNetSlpTagdot
+
+syn match   slpconfNetSlpTagDot contained display '.'
+                                \ nextgroup=slpconfNetSlpTag
+
+syn keyword slpconfNetSlpTag    contained isDA traceDATraffic traceMsg
+                                \ traceDrop traceReg isBroadcastOnly
+                                \ passiveDADetection securityEnabled
+                                \ nextgroup=slpconfBooleanEq,slpconfBooleanHome
+                                \ skipwhite
+
+syn match   slpconfBooleanHome  contained display
+                                \ '\.\d\{1,3}\%(\.\d\{1,3}\)\{3}'
+                                \ nextgroup=slpconfBooleanEq skipwhite
+
+syn match   slpconfBooleanEq    contained display '='
+                                \ nextgroup=slpconfBoolean skipwhite
+
+syn keyword slpconfBoolean      contained true false TRUE FALSE
+
+syn keyword slpconfNetSlpTag    contained DAHeartBeat multicastTTL
+                                \ DAActiveDiscoveryInterval
+                                \ multicastMaximumWait multicastTimeouts
+                                \ randomWaitBound MTU maxResults
+                                \ nextgroup=slpconfIntegerEq,slpconfIntegerHome
+                                \ skipwhite
+
+syn match   slpconfIntegerHome  contained display
+                                \ '\.\d\{1,3}\%(\.\d\{1,3}\)\{3}'
+                                \ nextgroup=slpconfIntegerEq skipwhite
+
+syn match   slpconfIntegerEq    contained display '='
+                                \ nextgroup=slpconfInteger skipwhite
+
+syn match   slpconfInteger      contained display '\<\d\+\>'
+
+syn keyword slpconfNetSlpTag    contained DAAttributes SAAttributes
+                                \ nextgroup=slpconfAttrEq,slpconfAttrHome
+                                \ skipwhite
+
+syn match   slpconfAttrHome     contained display
+                                \ '\.\d\{1,3}\%(\.\d\{1,3}\)\{3}'
+                                \ nextgroup=slpconfAttrEq skipwhite
+
+syn match   slpconfAttrEq       contained display '='
+                                \ nextgroup=slpconfAttrBegin skipwhite
+
+syn match   slpconfAttrBegin    contained display '('
+                                \ nextgroup=slpconfAttrTag skipwhite
+
+syn match   slpconfAttrTag      contained display
+                                \ '[^* \t_(),\\!<=>~[:cntrl:]]\+'
+                                \ nextgroup=slpconfAttrTagEq skipwhite
+
+syn match   slpconfAttrTagEq    contained display '='
+                                \ nextgroup=@slpconfAttrValue skipwhite
+
+syn cluster slpconfAttrValueCon contains=slpconfAttrValueSep,slpconfAttrEnd
+
+syn cluster slpconfAttrValue    contains=slpconfAttrIValue,slpconfAttrSValue,
+                                \ slpconfAttrBValue,slpconfAttrSSValue
+
+syn match   slpconfAttrSValue   contained display '[^ (),\\!<=>~[:cntrl:]]\+'
+                                \ nextgroup=@slpconfAttrValueCon skipwhite
+
+syn match   slpconfAttrSSValue  contained display '\\FF\%(\\\x\x\)\+'
+                                \ nextgroup=@slpconfAttrValueCon skipwhite
+
+syn match   slpconfAttrIValue   contained display '[-]\=\d\+\>'
+                                \ nextgroup=@slpconfAttrValueCon skipwhite
+
+syn keyword slpconfAttrBValue   contained true false
+                                \ nextgroup=@slpconfAttrValueCon skipwhite
+
+syn match   slpconfAttrValueSep contained display ','
+                                \ nextgroup=@slpconfAttrValue skipwhite
+
+syn match   slpconfAttrEnd      contained display ')'
+                                \ nextgroup=slpconfAttrSep skipwhite
+
+syn match   slpconfAttrSep      contained display ','
+                                \ nextgroup=slpconfAttrBegin skipwhite
+
+syn keyword slpconfNetSlpTag    contained useScopes typeHint
+                                \ nextgroup=slpconfStringsEq,slpconfStringsHome
+                                \ skipwhite
+
+syn match   slpconfStringsHome  contained display
+                                \ '\.\d\{1,3}\%(\.\d\{1,3}\)\{3}'
+                                \ nextgroup=slpconfStringsEq skipwhite
+
+syn match   slpconfStringsEq    contained display '='
+                                \ nextgroup=slpconfStrings skipwhite
+
+syn match   slpconfStrings      contained display
+                                \ '\%([[:digit:][:alpha:]]\|[!-+./:-@[-`{-~-]\|\\\x\x\)\+'
+                                \ nextgroup=slpconfStringsSep skipwhite
+
+syn match   slpconfStringsSep   contained display ','
+                                \ nextgroup=slpconfStrings skipwhite
+
+syn keyword slpconfNetSlpTag    contained DAAddresses
+                                \ nextgroup=slpconfAddressesEq,slpconfAddrsHome
+                                \ skipwhite
+
+syn match   slpconfAddrsHome    contained display
+                                \ '\.\d\{1,3}\%(\.\d\{1,3}\)\{3}'
+                                \ nextgroup=slpconfAddressesEq skipwhite
+
+syn match   slpconfAddressesEq  contained display '='
+                                \ nextgroup=@slpconfAddresses skipwhite
+
+syn cluster slpconfAddresses    contains=slpconfFQDNs,slpconfHostnumbers
+
+syn match   slpconfFQDNs        contained display
+                                \ '\a[[:alnum:]-]*[[:alnum:]]\|\a'
+                                \ nextgroup=slpconfAddressesSep skipwhite
+
+syn match   slpconfHostnumbers  contained display
+                                \ '\d\{1,3}\%(\.\d\{1,3}\)\{3}'
+                                \ nextgroup=slpconfAddressesSep skipwhite
+
+syn match   slpconfAddressesSep contained display ','
+                                \ nextgroup=@slpconfAddresses skipwhite
+
+syn keyword slpconfNetSlpTag    contained serializedRegURL
+                                \ nextgroup=slpconfStringEq,slpconfStringHome
+                                \ skipwhite
+
+syn match   slpconfStringHome   contained display
+                                \ '\.\d\{1,3}\%(\.\d\{1,3}\)\{3}'
+                                \ nextgroup=slpconfStringEq skipwhite
+
+syn match   slpconfStringEq     contained display '='
+                                \ nextgroup=slpconfString skipwhite
+
+syn match   slpconfString       contained display
+                                \ '\%([!-+./:-@[-`{-~-]\|\\\x\x\)\+\|[[:digit:][:alpha:]]'
+
+syn keyword slpconfNetSlpTag    contained multicastTimeouts DADiscoveryTimeouts
+                                \ datagramTimeouts
+                                \ nextgroup=slpconfIntegersEq,
+                                \ slpconfIntegersHome skipwhite
+
+syn match   slpconfIntegersHome contained display
+                                \ '\.\d\{1,3}\%(\.\d\{1,3}\)\{3}'
+                                \ nextgroup=slpconfIntegersEq skipwhite
+
+syn match   slpconfIntegersEq   contained display '='
+                                \ nextgroup=slpconfIntegers skipwhite
+
+syn match   slpconfIntegers     contained display '\<\d\+\>'
+                                \ nextgroup=slpconfIntegersSep skipwhite
+
+syn match   slpconfIntegersSep  contained display ','
+                                \ nextgroup=slpconfIntegers skipwhite
+
+syn keyword slpconfNetSlpTag    contained interfaces
+                                \ nextgroup=slpconfHostnumsEq,
+                                \ slpconfHostnumsHome skipwhite
+
+syn match   slpconfHostnumsHome contained display
+                                \ '\.\d\{1,3}\%(\.\d\{1,3}\)\{3}'
+                                \ nextgroup=slpconfHostnumsEq skipwhite
+
+syn match   slpconfHostnumsEq   contained display '='
+                                \ nextgroup=slpconfOHostnumbers skipwhite
+
+syn match   slpconfOHostnumbers contained display
+                                \ '\d\{1,3}\%(\.\d\{1,3}\)\{3}'
+                                \ nextgroup=slpconfHostnumsSep skipwhite
+
+syn match   slpconfHostnumsSep  contained display ','
+                                \ nextgroup=slpconfOHostnumbers skipwhite
+
+syn keyword slpconfNetSlpTag    contained locale
+                                \ nextgroup=slpconfLocaleEq,slpconfLocaleHome
+                                \ skipwhite
+
+syn match   slpconfLocaleHome   contained display
+                                \ '\.\d\{1,3}\%(\.\d\{1,3}\)\{3}'
+                                \ nextgroup=slpconfLocaleEq skipwhite
+
+syn match   slpconfLocaleEq     contained display '='
+                                \ nextgroup=slpconfLocale skipwhite
+
+syn match   slpconfLocale       contained display '\a\{1,8}\%(-\a\{1,8}\)\='
+
+hi def link slpconfTodo         Todo
+hi def link slpconfComment      Comment
+hi def link slpconfTag          Identifier
+hi def link slpconfDelimiter    Delimiter
+hi def link slpconfNetTagDot    slpconfDelimiter
+hi def link slpconfNetTag       slpconfTag
+hi def link slpconfNetSlpTagDot slpconfNetTagDot
+hi def link slpconfNetSlpTag    slpconfTag
+hi def link slpconfHome         Special
+hi def link slpconfBooleanHome  slpconfHome
+hi def link slpconfEq           Operator
+hi def link slpconfBooleanEq    slpconfEq
+hi def link slpconfBoolean      Boolean
+hi def link slpconfIntegerHome  slpconfHome
+hi def link slpconfIntegerEq    slpconfEq
+hi def link slpconfInteger      Number
+hi def link slpconfAttrHome     slpconfHome
+hi def link slpconfAttrEq       slpconfEq
+hi def link slpconfAttrBegin    slpconfDelimiter
+hi def link slpconfAttrTag      slpconfTag
+hi def link slpconfAttrTagEq    slpconfEq
+hi def link slpconfAttrIValue   slpconfInteger
+hi def link slpconfAttrSValue   slpconfString
+hi def link slpconfAttrBValue   slpconfBoolean
+hi def link slpconfAttrSSValue  slpconfString
+hi def link slpconfSeparator    slpconfDelimiter
+hi def link slpconfAttrValueSep slpconfSeparator
+hi def link slpconfAttrEnd      slpconfAttrBegin
+hi def link slpconfAttrSep      slpconfSeparator
+hi def link slpconfStringsHome  slpconfHome
+hi def link slpconfStringsEq    slpconfEq
+hi def link slpconfStrings      slpconfString
+hi def link slpconfStringsSep   slpconfSeparator
+hi def link slpconfAddrsHome    slpconfHome
+hi def link slpconfAddressesEq  slpconfEq
+hi def link slpconfFQDNs        String
+hi def link slpconfHostnumbers  Number
+hi def link slpconfAddressesSep slpconfSeparator
+hi def link slpconfStringHome   slpconfHome
+hi def link slpconfStringEq     slpconfEq
+hi def link slpconfString       String
+hi def link slpconfIntegersHome slpconfHome
+hi def link slpconfIntegersEq   slpconfEq
+hi def link slpconfIntegers     slpconfInteger
+hi def link slpconfIntegersSep  slpconfSeparator
+hi def link slpconfHostnumsHome slpconfHome
+hi def link slpconfHostnumsEq   slpconfEq
+hi def link slpconfOHostnumbers slpconfHostnumbers
+hi def link slpconfHostnumsSep  slpconfSeparator
+hi def link slpconfLocaleHome   slpconfHome
+hi def link slpconfLocaleEq     slpconfEq
+hi def link slpconfLocale       slpconfString
+
+let b:current_syntax = "slpconf"
+
+let &cpo = s:cpo_save
+unlet s:cpo_save
--- /dev/null
+++ b/lib/vimfiles/syntax/slpreg.vim
@@ -1,0 +1,122 @@
+" Vim syntax file
+" Language:         RFC 2614 - An API for Service Location registration file
+" Maintainer:       Nikolai Weibull <now@bitwi.se>
+" Latest Revision:  2006-04-19
+
+if exists("b:current_syntax")
+  finish
+endif
+
+let s:cpo_save = &cpo
+set cpo&vim
+
+syn keyword slpregTodo          contained TODO FIXME XXX NOTE
+
+syn region  slpregComment       display oneline start='^[#;]' end='$'
+                                \ contains=slpregTodo,@Spell
+
+syn match   slpregBegin         display '^'
+                                \ nextgroup=slpregServiceURL,
+                                \ slpregComment
+
+syn match   slpregServiceURL    contained display 'service:'
+                                \ nextgroup=slpregServiceType
+
+syn match   slpregServiceType   contained display '\a[[:alpha:][:digit:]+-]*\%(\.\a[[:alpha:][:digit:]+-]*\)\=\%(:\a[[:alpha:][:digit:]+-]*\)\='
+                                \ nextgroup=slpregServiceSAPCol
+
+syn match   slpregServiceSAPCol contained display ':'
+                                \ nextgroup=slpregSAP
+
+syn match   slpregSAP           contained '[^,]\+'
+                                \ nextgroup=slpregLangSep
+"syn match   slpregSAP           contained display '\%(//\%(\%([[:alpha:][:digit:]$-_.~!*\'(),+;&=]*@\)\=\%([[:alnum:]][[:alnum:]-]*[[:alnum:]]\|[[:alnum:]]\.\)*\%(\a[[:alnum:]-]*[[:alnum:]]\|\a\)\%(:\d\+\)\=\)\=\|/at/\%([[:alpha:][:digit:]$-_.~]\|\\\x\x\)\{1,31}:\%([[:alpha:][:digit:]$-_.~]\|\\\x\x\)\{1,31}\%([[:alpha:][:digit:]$-_.~]\|\\\x\x\)\{1,31}\|/ipx/\x\{8}:\x\{12}:\x\{4}\)\%(/\%([[:alpha:][:digit:]$-_.~!*\'()+;?:@&=+]\|\\\x\x\)*\)*\%(;[^()\\!<=>~[:cntrl:]* \t_]\+\%(=[^()\\!<=>~[:cntrl:] ]\+\)\=\)*'
+
+syn match   slpregLangSep       contained display ','
+                                \ nextgroup=slpregLang
+
+syn match   slpregLang          contained display '\a\{1,8}\%(-\a\{1,8\}\)\='
+                                \ nextgroup=slpregLTimeSep
+
+syn match   slpregLTimeSep      contained display ','
+                                \ nextgroup=slpregLTime
+
+syn match   slpregLTime         contained display '\d\{1,5}'
+                                \ nextgroup=slpregType,slpregUNewline
+
+syn match   slpregType          contained display '\a[[:alpha:][:digit:]+-]*'
+                                \ nextgroup=slpregUNewLine
+
+syn match   slpregUNewLine      contained '\s*\n'
+                                \ nextgroup=slpregScopes,slpregAttrList skipnl
+
+syn keyword slpregScopes        contained scopes
+                                \ nextgroup=slpregScopesEq
+
+syn match   slpregScopesEq      contained '=' nextgroup=slpregScopeName
+
+syn match   slpregScopeName     contained '[^(),\\!<=>[:cntrl:];*+ ]\+'
+                                \ nextgroup=slpregScopeNameSep,
+                                \ slpregScopeNewline
+
+syn match   slpregScopeNameSep  contained ','
+                                \ nextgroup=slpregScopeName
+
+syn match   slpregScopeNewline  contained '\s*\n'
+                                \ nextgroup=slpregAttribute skipnl
+
+syn match   slpregAttribute     contained '[^(),\\!<=>[:cntrl:]* \t_]\+'
+                                \ nextgroup=slpregAttributeEq,
+                                \ slpregScopeNewline
+
+syn match   slpregAttributeEq   contained '='
+                                \ nextgroup=@slpregAttrValue
+
+syn cluster slpregAttrValueCon  contains=slpregAttribute,slpregAttrValueSep
+
+syn cluster slpregAttrValue     contains=slpregAttrIValue,slpregAttrSValue,
+                                \ slpregAttrBValue,slpregAttrSSValue
+
+syn match   slpregAttrSValue    contained display '[^(),\\!<=>~[:cntrl:]]\+'
+                                \ nextgroup=@slpregAttrValueCon skipwhite skipnl
+
+syn match   slpregAttrSSValue   contained display '\\FF\%(\\\x\x\)\+'
+                                \ nextgroup=@slpregAttrValueCon skipwhite skipnl
+
+syn match   slpregAttrIValue    contained display '[-]\=\d\+\>'
+                                \ nextgroup=@slpregAttrValueCon skipwhite skipnl
+
+syn keyword slpregAttrBValue    contained true false
+                                \ nextgroup=@slpregAttrValueCon skipwhite skipnl
+
+syn match   slpregAttrValueSep  contained display ','
+                                \ nextgroup=@slpregAttrValue skipwhite skipnl
+
+hi def link slpregTodo          Todo
+hi def link slpregComment       Comment
+hi def link slpregServiceURL    Type
+hi def link slpregServiceType   slpregServiceURL
+hi def link slpregServiceSAPCol slpregServiceURL
+hi def link slpregSAP           slpregServiceURL
+hi def link slpregDelimiter     Delimiter
+hi def link slpregLangSep       slpregDelimiter
+hi def link slpregLang          String
+hi def link slpregLTimeSep      slpregDelimiter
+hi def link slpregLTime         Number
+hi def link slpregType          Type
+hi def link slpregScopes        Identifier
+hi def link slpregScopesEq      Operator
+hi def link slpregScopeName     String
+hi def link slpregScopeNameSep  slpregDelimiter
+hi def link slpregAttribute     Identifier
+hi def link slpregAttributeEq   Operator
+hi def link slpregAttrSValue    String
+hi def link slpregAttrSSValue   slpregAttrSValue
+hi def link slpregAttrIValue    Number
+hi def link slpregAttrBValue    Boolean
+hi def link slpregAttrValueSep  slpregDelimiter
+
+let b:current_syntax = "slpreg"
+
+let &cpo = s:cpo_save
+unlet s:cpo_save
--- /dev/null
+++ b/lib/vimfiles/syntax/slpspi.vim
@@ -1,0 +1,39 @@
+" Vim syntax file
+" Language:         RFC 2614 - An API for Service Location SPI file
+" Maintainer:       Nikolai Weibull <now@bitwi.se>
+" Latest Revision:  2006-04-19
+
+if exists("b:current_syntax")
+  finish
+endif
+
+let s:cpo_save = &cpo
+set cpo&vim
+
+syn keyword slpspiTodo          contained TODO FIXME XXX NOTE
+
+syn region  slpspiComment       display oneline start='^[#;]' end='$'
+                                \ contains=slpspiTodo,@Spell
+
+syn match   slpspiBegin         display '^'
+                                \ nextgroup=slpspiKeyType,
+                                \ slpspiComment skipwhite
+
+syn keyword slpspiKeyType       contained PRIVATE PUBLIC
+                                \ nextgroup=slpspiString skipwhite
+
+syn match   slpspiString        contained '\S\+'
+                                \ nextgroup=slpspiKeyFile skipwhite
+
+syn match   slpspiKeyFile       contained '\S\+'
+
+hi def link slpspiTodo          Todo
+hi def link slpspiComment       Comment
+hi def link slpspiKeyType       Type
+hi def link slpspiString        Identifier
+hi def link slpspiKeyFile       String
+
+let b:current_syntax = "slpspi"
+
+let &cpo = s:cpo_save
+unlet s:cpo_save
--- /dev/null
+++ b/lib/vimfiles/syntax/slrnrc.vim
@@ -1,0 +1,194 @@
+" Vim syntax file
+" Language:	Slrn setup file (based on slrn 0.9.8.1)
+" Maintainer:	Preben 'Peppe' Guldberg <peppe-vim@wielders.org>
+" Last Change:	23 April 2006
+
+" For version 5.x: Clear all syntax items
+" For version 6.x: Quit when a syntax file was already loaded
+if version < 600
+  syntax clear
+elseif exists("b:current_syntax")
+  finish
+endif
+
+syn keyword slrnrcTodo		contained Todo
+
+" In some places whitespace is illegal
+syn match slrnrcSpaceError	contained "\s"
+
+syn match slrnrcNumber		contained "-\=\<\d\+\>"
+syn match slrnrcNumber		contained +'[^']\+'+
+
+syn match slrnrcSpecKey		contained +\(\\[er"']\|\^[^'"]\|\\\o\o\o\)+
+
+syn match  slrnrcKey		contained "\S\+"	contains=slrnrcSpecKey
+syn region slrnrcKey		contained start=+"+ skip=+\\"+ end=+"+ oneline contains=slrnrcSpecKey
+syn region slrnrcKey		contained start=+'+ skip=+\\'+ end=+'+ oneline contains=slrnrcSpecKey
+
+syn match slrnrcSpecChar	contained +'+
+syn match slrnrcSpecChar	contained +\\[n"]+
+syn match slrnrcSpecChar	contained "%[dfmnrs%]"
+
+syn match  slrnrcString		contained /[^ \t%"']\+/	contains=slrnrcSpecChar
+syn region slrnrcString		contained start=+"+ skip=+\\"+ end=+"+ oneline contains=slrnrcSpecChar
+
+syn match slrnSlangPreCondit	"^#\s*ifn\=\(def\>\|false\>\|true\>\|\$\)"
+syn match slrnSlangPreCondit	"^#\s*e\(lif\|lse\|ndif\)\>"
+
+syn match slrnrcComment		"%.*$"	contains=slrnrcTodo
+
+syn keyword  slrnrcVarInt	contained abort_unmodified_edits article_window_page_overlap auto_mark_article_as_read beep broken_xref broken_xref cc_followup check_new_groups
+syn keyword  slrnrcVarInt	contained color_by_score confirm_actions custom_sort_by_threads display_cursor_bar drop_bogus_groups editor_uses_mime_charset emphasized_text_mask
+syn keyword  slrnrcVarInt	contained emphasized_text_mode fold_headers fold_headers followup_strip_signature force_authentication force_authentication generate_date_header
+syn keyword  slrnrcVarInt	contained generate_email_from generate_email_from generate_message_id grouplens_port hide_pgpsignature hide_quotes hide_signature
+syn keyword  slrnrcVarInt	contained hide_verbatim_marks hide_verbatim_text highlight_unread_subjects highlight_urls ignore_signature kill_score lines_per_update
+syn keyword  slrnrcVarInt	contained mail_editor_is_mua max_low_score max_queued_groups min_high_score mouse netiquette_warnings new_subject_breaks_threads no_autosave
+syn keyword  slrnrcVarInt	contained no_backups prefer_head process_verbatim_marks query_next_article query_next_group query_read_group_cutoff read_active reject_long_lines
+syn keyword  slrnrcVarInt	contained scroll_by_page show_article show_thread_subject simulate_graphic_chars smart_quote sorting_method spoiler_char spoiler_char
+syn keyword  slrnrcVarInt	contained spoiler_display_mode spoiler_display_mode spool_check_up_on_nov spool_check_up_on_nov uncollapse_threads unsubscribe_new_groups use_blink
+syn keyword  slrnrcVarInt	contained use_color use_flow_control use_grouplens use_grouplens use_header_numbers use_inews use_inews use_localtime use_metamail use_mime use_mime
+syn keyword  slrnrcVarInt	contained use_recommended_msg_id use_slrnpull use_slrnpull use_tilde use_tmpdir use_uudeview use_uudeview warn_followup_to wrap_flags wrap_method
+syn keyword  slrnrcVarInt	contained write_newsrc_flags
+
+" Listed for removal
+syn keyword  slrnrcVarInt	contained author_display display_author_realname display_score group_dsc_start_column process_verbatum_marks prompt_next_group query_reconnect
+syn keyword  slrnrcVarInt	contained show_descriptions use_xgtitle
+
+" Match as a "string" too
+syn region  slrnrcVarIntStr	contained matchgroup=slrnrcVarInt start=+"+ end=+"+ oneline contains=slrnrcVarInt,slrnrcSpaceError
+
+syn keyword slrnrcVarStr	contained Xbrowser art_help_line art_status_line cansecret_file cc_post_string charset custom_headers custom_sort_order decode_directory
+syn keyword slrnrcVarStr	contained editor_command failed_posts_file followup_custom_headers followup_date_format followup_string followupto_string group_help_line
+syn keyword slrnrcVarStr	contained group_status_line grouplens_host grouplens_pseudoname header_help_line header_status_line hostname inews_program macro_directory
+syn keyword slrnrcVarStr	contained mail_editor_command metamail_command mime_charset non_Xbrowser organization overview_date_format post_editor_command post_object
+syn keyword slrnrcVarStr	contained postpone_directory printer_name quote_string realname reply_custom_headers reply_string replyto save_directory save_posts save_replies
+syn keyword slrnrcVarStr	contained score_editor_command scorefile sendmail_command server_object signature signoff_string spool_active_file spool_activetimes_file
+syn keyword slrnrcVarStr	contained spool_inn_root spool_newsgroups_file spool_nov_file spool_nov_root spool_overviewfmt_file spool_root supersedes_custom_headers
+syn keyword slrnrcVarStr	contained top_status_line username
+
+" Listed for removal
+syn keyword slrnrcVarStr	contained followup cc_followup_string
+
+" Match as a "string" too
+syn region  slrnrcVarStrStr	contained matchgroup=slrnrcVarStr start=+"+ end=+"+ oneline contains=slrnrcVarStr,slrnrcSpaceError
+
+" Various commands
+syn region slrnrcCmdLine	matchgroup=slrnrcCmd start="\<\(autobaud\|color\|compatible_charsets\|group_display_format\|grouplens_add\|header_display_format\|ignore_quotes\|include\|interpret\|mono\|nnrpaccess\|posting_host\|server\|set\|setkey\|strip_re_regexp\|strip_sig_regexp\|strip_was_regexp\|unsetkey\|visible_headers\)\>" end="$" oneline contains=slrnrc\(String\|Comment\)
+
+" Listed for removal
+syn region slrnrcCmdLine	matchgroup=slrnrcCmd start="\<\(cc_followup_string\|decode_directory\|editor_command\|followup\|hostname\|organization\|quote_string\|realname\|replyto\|scorefile\|signature\|username\)\>" end="$" oneline contains=slrnrc\(String\|Comment\)
+
+" Setting variables
+syn keyword slrnrcSet		contained set
+syn match   slrnrcSetStr	"^\s*set\s\+\S\+" skipwhite nextgroup=slrnrcString contains=slrnrcSet,slrnrcVarStr\(Str\)\=
+syn match   slrnrcSetInt	contained "^\s*set\s\+\S\+" contains=slrnrcSet,slrnrcVarInt\(Str\)\=
+syn match   slrnrcSetIntLine	"^\s*set\s\+\S\+\s\+\(-\=\d\+\>\|'[^']\+'\)" contains=slrnrcSetInt,slrnrcNumber,slrnrcVarInt
+
+" Color definitions
+syn match   slrnrcColorObj	contained "\<quotes\d\+\>"
+syn keyword slrnrcColorObj	contained article author boldtext box cursor date description error frame from_myself group grouplens_display header_name header_number headers
+syn keyword slrnrcColorObj	contained high_score italicstext menu menu_press message neg_score normal pgpsignature pos_score quotes response_char selection signature status
+syn keyword slrnrcColorObj	contained subject thread_number tilde tree underlinetext unread_subject url verbatim
+
+" Listed for removal
+syn keyword slrnrcColorObj	contained verbatum
+
+syn region  slrnrcColorObjStr	contained matchgroup=slrnrcColorObj start=+"+ end=+"+ oneline contains=slrnrcColorObj,slrnrcSpaceError
+syn keyword slrnrcColorVal	contained default
+syn keyword slrnrcColorVal	contained black blue brightblue brightcyan brightgreen brightmagenta brightred brown cyan gray green lightgray magenta red white yellow
+syn region  slrnrcColorValStr	contained matchgroup=slrnrcColorVal start=+"+ end=+"+ oneline contains=slrnrcColorVal,slrnrcSpaceError
+" Mathcing a function with three arguments
+syn keyword slrnrcColor		contained color
+syn match   slrnrcColorInit	contained "^\s*color\s\+\S\+" skipwhite nextgroup=slrnrcColorVal\(Str\)\= contains=slrnrcColor\(Obj\|ObjStr\)\=
+syn match   slrnrcColorLine	"^\s*color\s\+\S\+\s\+\S\+" skipwhite nextgroup=slrnrcColorVal\(Str\)\= contains=slrnrcColor\(Init\|Val\|ValStr\)
+
+" Mono settings
+syn keyword slrnrcMonoVal	contained blink bold none reverse underline
+syn region  slrnrcMonoValStr	contained matchgroup=slrnrcMonoVal start=+"+ end=+"+ oneline contains=slrnrcMonoVal,slrnrcSpaceError
+" Color object is inherited
+" Mono needs at least one argument
+syn keyword slrnrcMono		contained mono
+syn match   slrnrcMonoInit	contained "^\s*mono\s\+\S\+" contains=slrnrcMono,slrnrcColorObj\(Str\)\=
+syn match   slrnrcMonoLine	"^\s*mono\s\+\S\+\s\+\S.*" contains=slrnrcMono\(Init\|Val\|ValStr\),slrnrcComment
+
+" Functions in article mode
+syn keyword slrnrcFunArt	contained article_bob article_eob article_left article_line_down article_line_up article_page_down article_page_up article_right article_search
+syn keyword slrnrcFunArt	contained author_search_backward author_search_forward browse_url cancel catchup catchup_all create_score decode delete delete_thread digit_arg
+syn keyword slrnrcFunArt	contained enlarge_article_window evaluate_cmd exchange_mark expunge fast_quit followup forward forward_digest get_children_headers get_parent_header
+syn keyword slrnrcFunArt	contained goto_article goto_last_read grouplens_rate_article header_bob header_eob header_line_down header_line_up header_page_down header_page_up
+syn keyword slrnrcFunArt	contained help hide_article locate_article mark_spot next next_high_score next_same_subject pipe post post_postponed previous print quit redraw
+syn keyword slrnrcFunArt	contained repeat_last_key reply request save show_spoilers shrink_article_window skip_quotes skip_to_next_group skip_to_previous_group
+syn keyword slrnrcFunArt	contained subject_search_backward subject_search_forward supersede suspend tag_header toggle_collapse_threads toggle_header_formats
+syn keyword slrnrcFunArt	contained toggle_header_tag toggle_headers toggle_pgpsignature toggle_quotes toggle_rot13 toggle_signature toggle_sort toggle_verbatim_marks
+syn keyword slrnrcFunArt	contained toggle_verbatim_text uncatchup uncatchup_all undelete untag_headers view_scores wrap_article zoom_article_window
+
+" Listed for removal
+syn keyword slrnrcFunArt	contained art_bob art_eob art_xpunge article_linedn article_lineup article_pagedn article_pageup down enlarge_window goto_beginning goto_end left
+syn keyword slrnrcFunArt	contained locate_header_by_msgid pagedn pageup pipe_article prev print_article right scroll_dn scroll_up shrink_window skip_to_prev_group
+syn keyword slrnrcFunArt	contained toggle_show_author up
+
+" Functions in group mode
+syn keyword slrnrcFunGroup	contained add_group bob catchup digit_arg eob evaluate_cmd group_search group_search_backward group_search_forward help line_down line_up move_group
+syn keyword slrnrcFunGroup	contained page_down page_up post post_postponed quit redraw refresh_groups repeat_last_key save_newsrc select_group subscribe suspend
+syn keyword slrnrcFunGroup	contained toggle_group_formats toggle_hidden toggle_list_all toggle_scoring transpose_groups uncatchup unsubscribe
+
+" Listed for removal
+syn keyword slrnrcFunGroup	contained down group_bob group_eob pagedown pageup toggle_group_display uncatch_up up
+
+" Functions in readline mode (actually from slang's slrline.c)
+syn keyword slrnrcFunRead	contained bdel bol complete cycle del delbol delbow deleol down enter eol left quoted_insert right self_insert trim up
+
+" Binding keys
+syn keyword slrnrcSetkeyObj	contained article group readline
+syn region  slrnrcSetkeyObjStr	contained matchgroup=slrnrcSetkeyObj start=+"+ end=+"+ oneline contains=slrnrcSetkeyObj
+syn match   slrnrcSetkeyArt	contained '\("\=\)\<article\>\1\s\+\S\+' skipwhite nextgroup=slrnrcKey contains=slrnrcSetKeyObj\(Str\)\=,slrnrcFunArt
+syn match   slrnrcSetkeyGroup	contained '\("\=\)\<group\>\1\s\+\S\+' skipwhite nextgroup=slrnrcKey contains=slrnrcSetKeyObj\(Str\)\=,slrnrcFunGroup
+syn match   slrnrcSetkeyRead	contained '\("\=\)\<readline\>\1\s\+\S\+' skipwhite nextgroup=slrnrcKey contains=slrnrcSetKeyObj\(Str\)\=,slrnrcFunRead
+syn match   slrnrcSetkey	"^\s*setkey\>" skipwhite nextgroup=slrnrcSetkeyArt,slrnrcSetkeyGroup,slrnrcSetkeyRead
+
+" Unbinding keys
+syn match   slrnrcUnsetkey	'^\s*unsetkey\s\+\("\)\=\(article\|group\|readline\)\>\1' skipwhite nextgroup=slrnrcKey contains=slrnrcSetkeyObj\(Str\)\=
+
+" Define the default highlighting.
+" For version 5.7 and earlier: only when not done already
+" For version 5.8 and later: only when an item doesn't have highlighting yet
+if version >= 508 || !exists("did_slrnrc_syntax_inits")
+  if version < 508
+    let did_slrnrc_syntax_inits = 1
+    command -nargs=+ HiLink hi link <args>
+  else
+    command -nargs=+ HiLink hi def link <args>
+  endif
+
+  HiLink slrnrcTodo		Todo
+  HiLink slrnrcSpaceError	Error
+  HiLink slrnrcNumber		Number
+  HiLink slrnrcSpecKey		SpecialChar
+  HiLink slrnrcKey		String
+  HiLink slrnrcSpecChar		SpecialChar
+  HiLink slrnrcString		String
+  HiLink slrnSlangPreCondit	Special
+  HiLink slrnrcComment		Comment
+  HiLink slrnrcVarInt		Identifier
+  HiLink slrnrcVarStr		Identifier
+  HiLink slrnrcCmd		slrnrcSet
+  HiLink slrnrcSet		Operator
+  HiLink slrnrcColor		Keyword
+  HiLink slrnrcColorObj		Identifier
+  HiLink slrnrcColorVal		String
+  HiLink slrnrcMono		Keyword
+  HiLink slrnrcMonoObj		Identifier
+  HiLink slrnrcMonoVal		String
+  HiLink slrnrcFunArt		Macro
+  HiLink slrnrcFunGroup		Macro
+  HiLink slrnrcFunRead		Macro
+  HiLink slrnrcSetkeyObj	Identifier
+  HiLink slrnrcSetkey		Keyword
+  HiLink slrnrcUnsetkey		slrnrcSetkey
+
+  delcommand HiLink
+endif
+
+let b:current_syntax = "slrnrc"
+
+"EOF	vim: ts=8 noet tw=120 sw=8 sts=0
--- /dev/null
+++ b/lib/vimfiles/syntax/slrnsc.vim
@@ -1,0 +1,85 @@
+" Vim syntax file
+" Language:	Slrn score file (based on slrn 0.9.8.0)
+" Maintainer:	Preben 'Peppe' Guldberg <peppe@wielders.org>
+" Last Change:	8 Oct 2004
+
+" For version 5.x: Clear all syntax items
+" For version 6.x: Quit when a syntax file was already loaded
+if version < 600
+  syntax clear
+elseif exists("b:current_syntax")
+  finish
+endif
+
+" characters in newsgroup names
+if version < 600
+  set isk=@,48-57,.,-,_,+
+else
+  setlocal isk=@,48-57,.,-,_,+
+endif
+
+syn match slrnscComment		"%.*$"
+syn match slrnscSectionCom	".].*"lc=2
+
+syn match slrnscGroup		contained "\(\k\|\*\)\+"
+syn match slrnscNumber		contained "\d\+"
+syn match slrnscDate		contained "\(\d\{1,2}[-/]\)\{2}\d\{4}"
+syn match slrnscDelim		contained ":"
+syn match slrnscComma		contained ","
+syn match slrnscOper		contained "\~"
+syn match slrnscEsc		contained "\\[ecC<>.]"
+syn match slrnscEsc		contained "[?^]"
+syn match slrnscEsc		contained "[^\\]$\s*$"lc=1
+
+syn keyword slrnscInclude	contained include
+syn match slrnscIncludeLine	"^\s*Include\s\+\S.*$"
+
+syn region slrnscSection	matchgroup=slrnscSectionStd start="^\s*\[" end='\]' contains=slrnscGroup,slrnscComma,slrnscSectionCom
+syn region slrnscSection	matchgroup=slrnscSectionNot start="^\s*\[\~" end='\]' contains=slrnscGroup,slrnscCommas,slrnscSectionCom
+
+syn keyword slrnscItem		contained Age Bytes Date Expires From Has-Body Lines Message-Id Newsgroup References Subject Xref
+
+syn match slrnscScoreItem	contained "%.*$"						skipempty nextgroup=slrnscScoreItem contains=slrnscComment
+syn match slrnscScoreItem	contained "^\s*Expires:\s*\(\d\{1,2}[-/]\)\{2}\d\{4}\s*$"	skipempty nextgroup=slrnscScoreItem contains=slrnscItem,slrnscDelim,slrnscDate
+syn match slrnscScoreItem	contained "^\s*\~\=\(Age\|Bytes\|Has-Body\|Lines\):\s*\d\+\s*$"	skipempty nextgroup=slrnscScoreItem contains=slrnscOper,slrnscItem,slrnscDelim,slrnscNumber
+syn match slrnscScoreItemFill	contained ".*$"							skipempty nextgroup=slrnscScoreItem contains=slrnscEsc
+syn match slrnscScoreItem	contained "^\s*\~\=\(Date\|From\|Message-Id\|Newsgroup\|References\|Subject\|Xref\):"	nextgroup=slrnscScoreItemFill contains=slrnscOper,slrnscItem,slrnscDelim
+syn region slrnscScoreItem	contained matchgroup=Special start="^\s*\~\={::\=" end="^\s*}" skipempty nextgroup=slrnscScoreItem contains=slrnscScoreItem
+
+syn keyword slrnscScore		contained Score
+syn match slrnscScoreIdent	contained "%.*"
+syn match slrnScoreLine		"^\s*Score::\=\s\+=\=[-+]\=\d\+\s*\(%.*\)\=$" skipempty nextgroup=slrnscScoreItem contains=slrnscScore,slrnscDelim,slrnscOper,slrnscNumber,slrnscScoreIdent
+
+" Define the default highlighting.
+" For version 5.7 and earlier: only when not done already
+" For version 5.8 and later: only when an item doesn't have highlighting yet
+if version >= 508 || !exists("did_slrnsc_syntax_inits")
+  if version < 508
+    let did_slrnsc_syntax_inits = 1
+    command -nargs=+ HiLink hi link <args>
+  else
+    command -nargs=+ HiLink hi def link <args>
+  endif
+
+  HiLink slrnscComment		Comment
+  HiLink slrnscSectionCom	slrnscComment
+  HiLink slrnscGroup		String
+  HiLink slrnscNumber		Number
+  HiLink slrnscDate		Special
+  HiLink slrnscDelim		Delimiter
+  HiLink slrnscComma		SpecialChar
+  HiLink slrnscOper		SpecialChar
+  HiLink slrnscEsc		String
+  HiLink slrnscSectionStd	Type
+  HiLink slrnscSectionNot	Delimiter
+  HiLink slrnscItem		Statement
+  HiLink slrnscScore		Keyword
+  HiLink slrnscScoreIdent	Identifier
+  HiLink slrnscInclude		Keyword
+
+  delcommand HiLink
+endif
+
+let b:current_syntax = "slrnsc"
+
+"EOF	vim: ts=8 noet tw=200 sw=8 sts=0
--- /dev/null
+++ b/lib/vimfiles/syntax/sm.vim
@@ -1,0 +1,96 @@
+" Vim syntax file
+" Language:	sendmail
+" Maintainer:	Dr. Charles E. Campbell, Jr. <NdrOchipS@PcampbellAfamily.Mbiz>
+" Last Change:	Sep 06, 2005
+" Version:	4
+" URL:	http://mysite.verizon.net/astronaut/vim/index.html#vimlinks_syntax
+
+" For version 5.x: Clear all syntax items
+" For version 6.x: Quit when a syntax file was already loaded
+if version < 600
+  syntax clear
+elseif exists("b:current_syntax")
+  finish
+endif
+
+" Comments
+syn match smComment	"^#.*$"	contains=@Spell
+
+" Definitions, Classes, Files, Options, Precedence, Trusted Users, Mailers
+syn match smDefine	"^[CDF]."
+syn match smDefine	"^O[AaBcdDeFfgHiLmNoQqrSsTtuvxXyYzZ]"
+syn match smDefine	"^O\s"he=e-1
+syn match smDefine	"^M[a-zA-Z0-9]\+,"he=e-1
+syn match smDefine	"^T"	nextgroup=smTrusted
+syn match smDefine	"^P"	nextgroup=smMesg
+syn match smTrusted	"\S\+$"		contained
+syn match smMesg		"\S*="he=e-1	contained nextgroup=smPrecedence
+syn match smPrecedence	"-\=[0-9]\+"		contained
+
+" Header Format  H?list-of-mailer-flags?name: format
+syn match smHeaderSep contained "[?:]"
+syn match smHeader	"^H\(?[a-zA-Z]\+?\)\=[-a-zA-Z_]\+:" contains=smHeaderSep
+
+" Variables
+syn match smVar		"\$[a-z\.\|]"
+
+" Rulesets
+syn match smRuleset	"^S\d*"
+
+" Rewriting Rules
+syn match smRewrite	"^R"			skipwhite nextgroup=smRewriteLhsToken,smRewriteLhsUser
+
+syn match smRewriteLhsUser	contained "[^\t$]\+"		skipwhite nextgroup=smRewriteLhsToken,smRewriteLhsSep
+syn match smRewriteLhsToken	contained "\(\$[-*+]\|\$[-=][A-Za-z]\|\$Y\)\+"	skipwhite nextgroup=smRewriteLhsUser,smRewriteLhsSep
+
+syn match smRewriteLhsSep	contained "\t\+"			skipwhite nextgroup=smRewriteRhsToken,smRewriteRhsUser
+
+syn match smRewriteRhsUser	contained "[^\t$]\+"		skipwhite nextgroup=smRewriteRhsToken,smRewriteRhsSep
+syn match smRewriteRhsToken	contained "\(\$\d\|\$>\d\|\$#\|\$@\|\$:[-_a-zA-Z]\+\|\$[[\]]\|\$@\|\$:\|\$[A-Za-z]\)\+" skipwhite nextgroup=smRewriteRhsUser,smRewriteRhsSep
+
+syn match smRewriteRhsSep	contained "\t\+"			skipwhite nextgroup=smRewriteComment,smRewriteRhsSep
+syn match smRewriteRhsSep	contained "$"
+
+syn match smRewriteComment	contained "[^\t$]*$"
+
+" Clauses
+syn match smClauseError		"\$\."
+syn match smElse		contained	"\$|"
+syn match smClauseCont	contained	"^\t"
+syn region smClause	matchgroup=Delimiter start="\$?." matchgroup=Delimiter end="\$\." contains=smElse,smClause,smVar,smClauseCont
+
+" Define the default highlighting.
+" For version 5.7 and earlier: only when not done already
+" For version 5.8 and later: only when an item doesn't have highlighting yet
+if version >= 508 || !exists("did_smil_syntax_inits")
+  if version < 508
+    let did_smil_syntax_inits = 1
+    command -nargs=+ HiLink hi link <args>
+  else
+    command -nargs=+ HiLink hi def link <args>
+  endif
+
+  HiLink smClause	Special
+  HiLink smClauseError	Error
+  HiLink smComment	Comment
+  HiLink smDefine	Statement
+  HiLink smElse		Delimiter
+  HiLink smHeader	Statement
+  HiLink smHeaderSep	String
+  HiLink smMesg		Special
+  HiLink smPrecedence	Number
+  HiLink smRewrite	Statement
+  HiLink smRewriteComment	Comment
+  HiLink smRewriteLhsToken	String
+  HiLink smRewriteLhsUser	Statement
+  HiLink smRewriteRhsToken	String
+  HiLink smRuleset	Preproc
+  HiLink smTrusted	Special
+  HiLink smVar		String
+
+  delcommand HiLink
+endif
+
+let b:current_syntax = "sm"
+
+" vim: ts=18
--- /dev/null
+++ b/lib/vimfiles/syntax/smarty.vim
@@ -1,0 +1,86 @@
+" Vim syntax file
+" Language:	Smarty Templates
+" Maintainer:	Manfred Stienstra manfred.stienstra@dwerg.net
+" Last Change:  Mon Nov  4 11:42:23 CET 2002
+" Filenames:    *.tpl
+" URL:		http://www.dwerg.net/projects/vim/smarty.vim
+
+" For version 5.x: Clear all syntax items
+" For version 6.x: Quit when a syntax file was already loaded
+if !exists("main_syntax")
+  if version < 600
+    syntax clear
+  elseif exists("b:current_syntax")
+  finish
+endif
+  let main_syntax = 'smarty'
+endif
+
+syn case ignore
+
+runtime! syntax/html.vim
+"syn cluster htmlPreproc add=smartyUnZone
+
+syn match smartyBlock contained "[\[\]]"
+
+syn keyword smartyTagName capture config_load include include_php
+syn keyword smartyTagName insert if elseif else ldelim rdelim literal
+syn keyword smartyTagName php section sectionelse foreach foreachelse
+syn keyword smartyTagName strip assign counter cycle debug eval fetch
+syn keyword smartyTagName html_options html_select_date html_select_time
+syn keyword smartyTagName math popup_init popup html_checkboxes html_image
+syn keyword smartyTagName html_radios html_table mailto textformat
+
+syn keyword smartyModifier cat capitalize count_characters count_paragraphs
+syn keyword smartyModifier count_sentences count_words date_format default
+syn keyword smartyModifier escape indent lower nl2br regex_replace replace
+syn keyword smartyModifier spacify string_format strip strip_tags truncate
+syn keyword smartyModifier upper wordwrap
+
+syn keyword smartyInFunc neq eq
+
+syn keyword smartyProperty contained "file="
+syn keyword smartyProperty contained "loop="
+syn keyword smartyProperty contained "name="
+syn keyword smartyProperty contained "include="
+syn keyword smartyProperty contained "skip="
+syn keyword smartyProperty contained "section="
+
+syn keyword smartyConstant "\$smarty"
+
+syn keyword smartyDot .
+
+syn region smartyZone matchgroup=Delimiter start="{" end="}" contains=smartyProperty, smartyString, smartyBlock, smartyTagName, smartyConstant, smartyInFunc, smartyModifier
+
+syn region  htmlString   contained start=+"+ end=+"+ contains=htmlSpecialChar,javaScriptExpression,@htmlPreproc,smartyZone
+syn region  htmlString   contained start=+'+ end=+'+ contains=htmlSpecialChar,javaScriptExpression,@htmlPreproc,smartyZone
+  syn region htmlLink start="<a\>\_[^>]*\<href\>" end="</a>"me=e-4 contains=@Spell,htmlTag,htmlEndTag,htmlSpecialChar,htmlPreProc,htmlComment,javaScript,@htmlPreproc,smartyZone
+
+
+if version >= 508 || !exists("did_smarty_syn_inits")
+  if version < 508
+    let did_smarty_syn_inits = 1
+    command -nargs=+ HiLink hi link <args>
+  else
+    command -nargs=+ HiLink hi def link <args>
+  endif
+
+  HiLink smartyTagName Identifier
+  HiLink smartyProperty Constant
+  " if you want the text inside the braces to be colored, then
+  " remove the comment in from of the next statement
+  "HiLink smartyZone Include
+  HiLink smartyInFunc Function
+  HiLink smartyBlock Constant
+  HiLink smartyDot SpecialChar
+  HiLink smartyModifier Function
+  delcommand HiLink
+endif
+
+let b:current_syntax = "smarty"
+
+if main_syntax == 'smarty'
+  unlet main_syntax
+endif
+
+" vim: ts=8
--- /dev/null
+++ b/lib/vimfiles/syntax/smcl.vim
@@ -1,0 +1,308 @@
+" smcl.vim -- Vim syntax file for smcl files.
+" Language:	SMCL -- Stata Markup and Control Language
+" Maintainer:	Jeff Pitblado <jpitblado@stata.com>
+" Last Change:	26apr2006
+" Version:	1.1.2
+
+" Log:
+" 20mar2003	updated the match definition for cmdab
+" 14apr2006	'syntax clear' only under version control
+"		check for 'b:current_syntax', removed 'did_smcl_syntax_inits'
+" 26apr2006	changed 'stata_smcl' to 'smcl'
+
+if version < 600
+	syntax clear
+elseif exists("b:current_syntax")
+	finish
+endif
+
+syntax case match
+
+syn keyword smclCCLword current_date		contained
+syn keyword smclCCLword current_time		contained
+syn keyword smclCCLword rmsg_time		contained
+syn keyword smclCCLword stata_version		contained
+syn keyword smclCCLword version			contained
+syn keyword smclCCLword born_date		contained
+syn keyword smclCCLword flavor			contained
+syn keyword smclCCLword SE			contained
+syn keyword smclCCLword mode			contained
+syn keyword smclCCLword console			contained
+syn keyword smclCCLword os			contained
+syn keyword smclCCLword osdtl			contained
+syn keyword smclCCLword machine_type		contained
+syn keyword smclCCLword byteorder		contained
+syn keyword smclCCLword sysdir_stata		contained
+syn keyword smclCCLword sysdir_updates		contained
+syn keyword smclCCLword sysdir_base		contained
+syn keyword smclCCLword sysdir_site		contained
+syn keyword smclCCLword sysdir_plus		contained
+syn keyword smclCCLword sysdir_personal		contained
+syn keyword smclCCLword sysdir_oldplace		contained
+syn keyword smclCCLword adopath			contained
+syn keyword smclCCLword pwd			contained
+syn keyword smclCCLword dirsep			contained
+syn keyword smclCCLword max_N_theory		contained
+syn keyword smclCCLword max_N_current		contained
+syn keyword smclCCLword max_k_theory		contained
+syn keyword smclCCLword max_k_current		contained
+syn keyword smclCCLword max_width_theory	contained
+syn keyword smclCCLword max_width_current	contained
+syn keyword smclCCLword max_matsize		contained
+syn keyword smclCCLword min_matsize		contained
+syn keyword smclCCLword max_macrolen		contained
+syn keyword smclCCLword macrolen		contained
+syn keyword smclCCLword max_cmdlen		contained
+syn keyword smclCCLword cmdlen			contained
+syn keyword smclCCLword namelen			contained
+syn keyword smclCCLword mindouble		contained
+syn keyword smclCCLword maxdouble		contained
+syn keyword smclCCLword epsdouble		contained
+syn keyword smclCCLword minfloat		contained
+syn keyword smclCCLword maxfloat		contained
+syn keyword smclCCLword epsfloat		contained
+syn keyword smclCCLword minlong			contained
+syn keyword smclCCLword maxlong			contained
+syn keyword smclCCLword minint			contained
+syn keyword smclCCLword maxint			contained
+syn keyword smclCCLword minbyte			contained
+syn keyword smclCCLword maxbyte			contained
+syn keyword smclCCLword maxstrvarlen		contained
+syn keyword smclCCLword memory			contained
+syn keyword smclCCLword maxvar			contained
+syn keyword smclCCLword matsize			contained
+syn keyword smclCCLword N			contained
+syn keyword smclCCLword k			contained
+syn keyword smclCCLword width			contained
+syn keyword smclCCLword changed			contained
+syn keyword smclCCLword filename		contained
+syn keyword smclCCLword filedate		contained
+syn keyword smclCCLword more			contained
+syn keyword smclCCLword rmsg			contained
+syn keyword smclCCLword dp			contained
+syn keyword smclCCLword linesize		contained
+syn keyword smclCCLword pagesize		contained
+syn keyword smclCCLword logtype			contained
+syn keyword smclCCLword linegap			contained
+syn keyword smclCCLword scrollbufsize		contained
+syn keyword smclCCLword varlabelpos		contained
+syn keyword smclCCLword reventries		contained
+syn keyword smclCCLword graphics		contained
+syn keyword smclCCLword scheme			contained
+syn keyword smclCCLword printcolor		contained
+syn keyword smclCCLword adosize			contained
+syn keyword smclCCLword maxdb			contained
+syn keyword smclCCLword virtual			contained
+syn keyword smclCCLword checksum		contained
+syn keyword smclCCLword timeout1		contained
+syn keyword smclCCLword timeout2		contained
+syn keyword smclCCLword httpproxy		contained
+syn keyword smclCCLword h_current		contained
+syn keyword smclCCLword max_matsize		contained
+syn keyword smclCCLword min_matsize		contained
+syn keyword smclCCLword max_macrolen		contained
+syn keyword smclCCLword macrolen		contained
+syn keyword smclCCLword max_cmdlen		contained
+syn keyword smclCCLword cmdlen			contained
+syn keyword smclCCLword namelen			contained
+syn keyword smclCCLword mindouble		contained
+syn keyword smclCCLword maxdouble		contained
+syn keyword smclCCLword epsdouble		contained
+syn keyword smclCCLword minfloat		contained
+syn keyword smclCCLword maxfloat		contained
+syn keyword smclCCLword epsfloat		contained
+syn keyword smclCCLword minlong			contained
+syn keyword smclCCLword maxlong			contained
+syn keyword smclCCLword minint			contained
+syn keyword smclCCLword maxint			contained
+syn keyword smclCCLword minbyte			contained
+syn keyword smclCCLword maxbyte			contained
+syn keyword smclCCLword maxstrvarlen		contained
+syn keyword smclCCLword memory			contained
+syn keyword smclCCLword maxvar			contained
+syn keyword smclCCLword matsize			contained
+syn keyword smclCCLword N			contained
+syn keyword smclCCLword k			contained
+syn keyword smclCCLword width			contained
+syn keyword smclCCLword changed			contained
+syn keyword smclCCLword filename		contained
+syn keyword smclCCLword filedate		contained
+syn keyword smclCCLword more			contained
+syn keyword smclCCLword rmsg			contained
+syn keyword smclCCLword dp			contained
+syn keyword smclCCLword linesize		contained
+syn keyword smclCCLword pagesize		contained
+syn keyword smclCCLword logtype			contained
+syn keyword smclCCLword linegap			contained
+syn keyword smclCCLword scrollbufsize		contained
+syn keyword smclCCLword varlabelpos		contained
+syn keyword smclCCLword reventries		contained
+syn keyword smclCCLword graphics		contained
+syn keyword smclCCLword scheme			contained
+syn keyword smclCCLword printcolor		contained
+syn keyword smclCCLword adosize			contained
+syn keyword smclCCLword maxdb			contained
+syn keyword smclCCLword virtual			contained
+syn keyword smclCCLword checksum		contained
+syn keyword smclCCLword timeout1		contained
+syn keyword smclCCLword timeout2		contained
+syn keyword smclCCLword httpproxy		contained
+syn keyword smclCCLword httpproxyhost		contained
+syn keyword smclCCLword httpproxyport		contained
+syn keyword smclCCLword httpproxyauth		contained
+syn keyword smclCCLword httpproxyuser		contained
+syn keyword smclCCLword httpproxypw		contained
+syn keyword smclCCLword trace			contained
+syn keyword smclCCLword tracedepth		contained
+syn keyword smclCCLword tracesep		contained
+syn keyword smclCCLword traceindent		contained
+syn keyword smclCCLword traceexapnd		contained
+syn keyword smclCCLword tracenumber		contained
+syn keyword smclCCLword type			contained
+syn keyword smclCCLword level			contained
+syn keyword smclCCLword seed			contained
+syn keyword smclCCLword searchdefault		contained
+syn keyword smclCCLword pi			contained
+syn keyword smclCCLword rc			contained
+
+" Directive for the contant and current-value class
+syn region smclCCL start=/{ccl / end=/}/ oneline contains=smclCCLword
+
+" The order of the following syntax definitions is roughly that of the on-line
+" documentation for smcl in Stata, from within Stata see help smcl.
+
+" Format directives for line and paragraph modes
+syn match smclFormat /{smcl}/
+syn match smclFormat /{sf\(\|:[^}]\+\)}/
+syn match smclFormat /{it\(\|:[^}]\+\)}/
+syn match smclFormat /{bf\(\|:[^}]\+\)}/
+syn match smclFormat /{inp\(\|:[^}]\+\)}/
+syn match smclFormat /{input\(\|:[^}]\+\)}/
+syn match smclFormat /{err\(\|:[^}]\+\)}/
+syn match smclFormat /{error\(\|:[^}]\+\)}/
+syn match smclFormat /{res\(\|:[^}]\+\)}/
+syn match smclFormat /{result\(\|:[^}]\+\)}/
+syn match smclFormat /{txt\(\|:[^}]\+\)}/
+syn match smclFormat /{text\(\|:[^}]\+\)}/
+syn match smclFormat /{com\(\|:[^}]\+\)}/
+syn match smclFormat /{cmd\(\|:[^}]\+\)}/
+syn match smclFormat /{cmdab:[^:}]\+:[^:}()]*\(\|:\|:(\|:()\)}/
+syn match smclFormat /{hi\(\|:[^}]\+\)}/
+syn match smclFormat /{hilite\(\|:[^}]\+\)}/
+syn match smclFormat /{ul \(on\|off\)}/
+syn match smclFormat /{ul:[^}]\+}/
+syn match smclFormat /{hline\(\| \d\+\| -\d\+\|:[^}]\+\)}/
+syn match smclFormat /{dup \d\+:[^}]\+}/
+syn match smclFormat /{c [^}]\+}/
+syn match smclFormat /{char [^}]\+}/
+syn match smclFormat /{reset}/
+
+" Formatting directives for line mode
+syn match smclFormat /{title:[^}]\+}/
+syn match smclFormat /{center:[^}]\+}/
+syn match smclFormat /{centre:[^}]\+}/
+syn match smclFormat /{center \d\+:[^}]\+}/
+syn match smclFormat /{centre \d\+:[^}]\+}/
+syn match smclFormat /{right:[^}]\+}/
+syn match smclFormat /{lalign \d\+:[^}]\+}/
+syn match smclFormat /{ralign \d\+:[^}]\+}/
+syn match smclFormat /{\.\.\.}/
+syn match smclFormat /{col \d\+}/
+syn match smclFormat /{space \d\+}/
+syn match smclFormat /{tab}/
+
+" Formatting directives for paragraph mode
+syn match smclFormat /{bind:[^}]\+}/
+syn match smclFormat /{break}/
+
+syn match smclFormat /{p}/
+syn match smclFormat /{p \d\+}/
+syn match smclFormat /{p \d\+ \d\+}/
+syn match smclFormat /{p \d\+ \d\+ \d\+}/
+syn match smclFormat /{pstd}/
+syn match smclFormat /{psee}/
+syn match smclFormat /{phang\(\|2\|3\)}/
+syn match smclFormat /{pmore\(\|2\|3\)}/
+syn match smclFormat /{pin\(\|2\|3\)}/
+syn match smclFormat /{p_end}/
+
+syn match smclFormat /{opt \w\+\(\|:\w\+\)\(\|([^)}]*)\)}/
+
+syn match smclFormat /{opth \w*\(\|:\w\+\)(\w*)}/
+syn match smclFormat /{opth "\w\+\((\w\+:[^)}]\+)\)"}/
+syn match smclFormat /{opth \w\+:\w\+(\w\+:[^)}]\+)}/
+
+syn match smclFormat /{dlgtab\s*\(\|\d\+\|\d\+\s\+\d\+\):[^}]\+}/
+
+syn match smclFormat /{p2colset\s\+\d\+\s\+\d\+\s\+\d\+\s\+\d\+}/
+syn match smclFormat /{p2col\s\+:[^{}]*}.*{p_end}/
+syn match smclFormat /{p2col\s\+:{[^{}]*}}.*{p_end}/
+syn match smclFormat /{p2coldent\s*:[^{}]*}.*{p_end}/
+syn match smclFormat /{p2coldent\s*:{[^{}]*}}.*{p_end}/
+syn match smclFormat /{p2line\s*\(\|\d\+\s\+\d\+\)}/
+syn match smclFormat /{p2colreset}/
+
+syn match smclFormat /{synoptset\s\+\d\+\s\+\w\+}/
+syn match smclFormat /{synopt\s*:[^{}]*}.*{p_end}/
+syn match smclFormat /{synopt\s*:{[^{}]*}}.*{p_end}/
+syn match smclFormat /{syntab\s*:[^{}]*}/
+syn match smclFormat /{synopthdr}/
+syn match smclFormat /{synoptline}/
+
+" Link directive for line and paragraph modes
+syn match smclLink /{help [^}]\+}/
+syn match smclLink /{helpb [^}]\+}/
+syn match smclLink /{help_d:[^}]\+}/
+syn match smclLink /{search [^}]\+}/
+syn match smclLink /{search_d:[^}]\+}/
+syn match smclLink /{browse [^}]\+}/
+syn match smclLink /{view [^}]\+}/
+syn match smclLink /{view_d:[^}]\+}/
+syn match smclLink /{news:[^}]\+}/
+syn match smclLink /{net [^}]\+}/
+syn match smclLink /{net_d:[^}]\+}/
+syn match smclLink /{netfrom_d:[^}]\+}/
+syn match smclLink /{ado [^}]\+}/
+syn match smclLink /{ado_d:[^}]\+}/
+syn match smclLink /{update [^}]\+}/
+syn match smclLink /{update_d:[^}]\+}/
+syn match smclLink /{dialog [^}]\+}/
+syn match smclLink /{back:[^}]\+}/
+syn match smclLink /{clearmore:[^}]\+}/
+syn match smclLink /{stata [^}]\+}/
+
+syn match smclLink /{newvar\(\|:[^}]\+\)}/
+syn match smclLink /{var\(\|:[^}]\+\)}/
+syn match smclLink /{varname\(\|:[^}]\+\)}/
+syn match smclLink /{vars\(\|:[^}]\+\)}/
+syn match smclLink /{varlist\(\|:[^}]\+\)}/
+syn match smclLink /{depvar\(\|:[^}]\+\)}/
+syn match smclLink /{depvars\(\|:[^}]\+\)}/
+syn match smclLink /{depvarlist\(\|:[^}]\+\)}/
+syn match smclLink /{indepvars\(\|:[^}]\+\)}/
+
+syn match smclLink /{dtype}/
+syn match smclLink /{ifin}/
+syn match smclLink /{weight}/
+
+" Comment
+syn region smclComment start=/{\*/ end=/}/ oneline
+
+" Strings
+syn region smclString  matchgroup=Nothing start=/"/ end=/"/   oneline
+syn region smclEString matchgroup=Nothing start=/`"/ end=/"'/ oneline contains=smclEString
+
+" assign highlight groups
+
+hi def link smclEString		smclString
+
+hi def link smclCCLword		Statement
+hi def link smclCCL		Type
+hi def link smclFormat		Statement
+hi def link smclLink		Underlined
+hi def link smclComment		Comment
+hi def link smclString		String
+
+let b:current_syntax = "smcl"
+
+" vim: ts=8
--- /dev/null
+++ b/lib/vimfiles/syntax/smil.vim
@@ -1,0 +1,154 @@
+" Vim syntax file
+" Language:	SMIL (Synchronized Multimedia Integration Language)
+" Maintainer:	Herve Foucher <Herve.Foucher@helio.org>
+" URL:		http://www.helio.org/vim/syntax/smil.vim
+" Last Change:	2003 May 11
+
+" To learn more about SMIL, please refer to http://www.w3.org/AudioVideo/
+" and to http://www.helio.org/products/smil/tutorial/
+
+" For version 5.x: Clear all syntax items
+" For version 6.x: Quit when a syntax file was already loaded
+if version < 600
+  syntax clear
+elseif exists("b:current_syntax")
+  finish
+endif
+
+" SMIL is case sensitive
+syn case match
+
+" illegal characters
+syn match smilError "[<>&]"
+syn match smilError "[()&]"
+
+if !exists("main_syntax")
+  let main_syntax = 'smil'
+endif
+
+" tags
+syn match   smilSpecial  contained "\\\d\d\d\|\\."
+syn match   smilSpecial  contained "("
+syn match   smilSpecial  contained "id("
+syn match   smilSpecial  contained ")"
+syn keyword smilSpecial  contained remove freeze true false on off overdub caption new pause replace
+syn keyword smilSpecial  contained first last
+syn keyword smilSpecial  contained fill meet slice scroll hidden
+syn region  smilString   contained start=+"+ skip=+\\\\\|\\"+ end=+"+ contains=smilSpecial
+syn region  smilString   contained start=+'+ skip=+\\\\\|\\'+ end=+'+ contains=smilSpecial
+syn match   smilValue    contained "=[\t ]*[^'" \t>][^ \t>]*"hs=s+1
+syn region  smilEndTag		   start=+</+	 end=+>+	      contains=smilTagN,smilTagError
+syn region  smilTag		   start=+<[^/]+ end=+>+	      contains=smilTagN,smilString,smilArg,smilValue,smilTagError,smilEvent,smilCssDefinition
+syn match   smilTagN     contained +<\s*[-a-zA-Z0-9]\++ms=s+1 contains=smilTagName,smilSpecialTagName
+syn match   smilTagN     contained +</\s*[-a-zA-Z0-9]\++ms=s+2 contains=smilTagName,smilSpecialTagName
+syn match   smilTagError contained "[^>]<"ms=s+1
+
+" tag names
+syn keyword smilTagName contained smil head body anchor a switch region layout meta
+syn match   smilTagName contained "root-layout"
+syn keyword smilTagName contained par seq
+syn keyword smilTagName contained animation video img audio ref text textstream
+syn match smilTagName contained "\<\(head\|body\)\>"
+
+
+" legal arg names
+syn keyword smilArg contained dur begin end href target id coords show title abstract author copyright alt
+syn keyword smilArg contained left top width height fit src name content fill longdesc repeat type
+syn match   smilArg contained "z-index"
+syn match   smilArg contained " end-sync"
+syn match   smilArg contained " region"
+syn match   smilArg contained "background-color"
+syn match   smilArg contained "system-bitrate"
+syn match   smilArg contained "system-captions"
+syn match   smilArg contained "system-overdub-or-caption"
+syn match   smilArg contained "system-language"
+syn match   smilArg contained "system-required"
+syn match   smilArg contained "system-screen-depth"
+syn match   smilArg contained "system-screen-size"
+syn match   smilArg contained "clip-begin"
+syn match   smilArg contained "clip-end"
+syn match   smilArg contained "skip-content"
+
+
+" SMIL Boston ext.
+" This are new SMIL functionnalities seen on www.w3.org on August 3rd 1999
+
+" Animation
+syn keyword smilTagName contained animate set move
+syn keyword smilArg contained calcMode from to by additive values origin path
+syn keyword smilArg contained accumulate hold attribute
+syn match   smilArg contained "xml:link"
+syn keyword smilSpecial contained discrete linear spline parent layout
+syn keyword smilSpecial contained top left simple
+
+" Linking
+syn keyword smilTagName contained area
+syn keyword smilArg contained actuate behavior inline sourceVolume
+syn keyword smilArg contained destinationVolume destinationPlaystate tabindex
+syn keyword smilArg contained class style lang dir onclick ondblclick onmousedown onmouseup onmouseover onmousemove onmouseout onkeypress onkeydown onkeyup shape nohref accesskey onfocus onblur
+syn keyword smilSpecial contained play pause stop rect circ poly child par seq
+
+" Media Object
+syn keyword smilTagName contained rtpmap
+syn keyword smilArg contained port transport encoding payload clipBegin clipEnd
+syn match   smilArg contained "fmt-list"
+
+" Timing and Synchronization
+syn keyword smilTagName contained excl
+syn keyword smilArg contained beginEvent endEvent eventRestart endSync repeatCount repeatDur
+syn keyword smilArg contained syncBehavior syncTolerance
+syn keyword smilSpecial contained canSlip locked
+
+" special characters
+syn match smilSpecialChar "&[^;]*;"
+
+if exists("smil_wrong_comments")
+  syn region smilComment		start=+<!--+	  end=+-->+
+else
+  syn region smilComment		start=+<!+	  end=+>+   contains=smilCommentPart,smilCommentError
+  syn match  smilCommentError contained "[^><!]"
+  syn region smilCommentPart  contained start=+--+	  end=+--+
+endif
+syn region smilComment		      start=+<!DOCTYPE+ keepend end=+>+
+
+" Define the default highlighting.
+" For version 5.7 and earlier: only when not done already
+" For version 5.8 and later: only when an item doesn't have highlighting yet
+if version >= 508 || !exists("did_smil_syntax_inits")
+  if version < 508
+    let did_smil_syntax_inits = 1
+    command -nargs=+ HiLink hi link <args>
+  else
+    command -nargs=+ HiLink hi def link <args>
+  endif
+
+  HiLink smilTag			Function
+  HiLink smilEndTag			Identifier
+  HiLink smilArg			Type
+  HiLink smilTagName			smilStatement
+  HiLink smilSpecialTagName		Exception
+  HiLink smilValue			Value
+  HiLink smilSpecialChar		Special
+
+  HiLink smilSpecial			Special
+  HiLink smilSpecialChar		Special
+  HiLink smilString			String
+  HiLink smilStatement			Statement
+  HiLink smilComment			Comment
+  HiLink smilCommentPart		Comment
+  HiLink smilPreProc			PreProc
+  HiLink smilValue			String
+  HiLink smilCommentError		smilError
+  HiLink smilTagError			smilError
+  HiLink smilError			Error
+
+  delcommand HiLink
+endif
+
+let b:current_syntax = "smil"
+
+if main_syntax == 'smil'
+  unlet main_syntax
+endif
+
+" vim: ts=8
--- /dev/null
+++ b/lib/vimfiles/syntax/smith.vim
@@ -1,0 +1,52 @@
+" Vim syntax file
+" Language:	SMITH
+" Maintainer:	Rafal M. Sulejman <rms@poczta.onet.pl>
+" Last Change:	21.07.2000
+
+" For version 5.x: Clear all syntax items
+" For version 6.x: Quit when a syntax file was already loaded
+if version < 600
+  syntax clear
+elseif exists("b:current_syntax")
+  finish
+endif
+
+syn case ignore
+
+
+syn match smithComment ";.*$"
+
+syn match smithNumber		"\<[+-]*[0-9]\d*\>"
+
+syn match smithRegister		"R[\[]*[0-9]*[\]]*"
+
+syn match smithKeyword	"COR\|MOV\|MUL\|NOT\|STOP\|SUB\|NOP\|BLA\|REP"
+
+syn region smithString		start=+"+  skip=+\\\\\|\\"+  end=+"+
+
+
+syn case match
+
+" Define the default highlighting.
+" For version 5.7 and earlier: only when not done already
+" For version 5.8 and later: only when an item doesn't have highlighting yet
+if version >= 508 || !exists("did_smith_syntax_inits")
+  if version < 508
+    let did_smith_syntax_inits = 1
+    command -nargs=+ HiLink hi link <args>
+  else
+    command -nargs=+ HiLink hi def link <args>
+  endif
+
+  HiLink smithRegister	Identifier
+  HiLink smithKeyword	Keyword
+	HiLink smithComment Comment
+	HiLink smithString String
+  HiLink smithNumber	Number
+
+	delcommand HiLink
+endif
+
+let b:current_syntax = "smith"
+
+" vim: ts=2
--- /dev/null
+++ b/lib/vimfiles/syntax/sml.vim
@@ -1,0 +1,230 @@
+" Vim syntax file
+" Language:     SML
+" Filenames:    *.sml *.sig
+" Maintainers:  Markus Mottl            <markus.mottl@gmail.com>
+"               Fabrizio Zeno Cornelli  <zeno@filibusta.crema.unimi.it>
+" URL:          http://www.ocaml.info/vim/syntax/sml.vim
+" Last Change:  2006 Oct 23 - Fixed character highlighting bug (MM)
+"               2002 Jun 02 - Fixed small typo  (MM)
+"               2001 Nov 20 - Fixed small highlighting bug with modules (MM)
+
+" For version 5.x: Clear all syntax items
+" For version 6.x: Quit when a syntax file was already loaded
+if version < 600
+  syntax clear
+elseif exists("b:current_syntax")
+  finish
+endif
+
+" SML is case sensitive.
+syn case match
+
+" lowercase identifier - the standard way to match
+syn match    smlLCIdentifier /\<\(\l\|_\)\(\w\|'\)*\>/
+
+syn match    smlKeyChar    "|"
+
+" Errors
+syn match    smlBraceErr   "}"
+syn match    smlBrackErr   "\]"
+syn match    smlParenErr   ")"
+syn match    smlCommentErr "\*)"
+syn match    smlThenErr    "\<then\>"
+
+" Error-highlighting of "end" without synchronization:
+" as keyword or as error (default)
+if exists("sml_noend_error")
+  syn match    smlKeyword    "\<end\>"
+else
+  syn match    smlEndErr     "\<end\>"
+endif
+
+" Some convenient clusters
+syn cluster  smlAllErrs contains=smlBraceErr,smlBrackErr,smlParenErr,smlCommentErr,smlEndErr,smlThenErr
+
+syn cluster  smlAENoParen contains=smlBraceErr,smlBrackErr,smlCommentErr,smlEndErr,smlThenErr
+
+syn cluster  smlContained contains=smlTodo,smlPreDef,smlModParam,smlModParam1,smlPreMPRestr,smlMPRestr,smlMPRestr1,smlMPRestr2,smlMPRestr3,smlModRHS,smlFuncWith,smlFuncStruct,smlModTypeRestr,smlModTRWith,smlWith,smlWithRest,smlModType,smlFullMod
+
+
+" Enclosing delimiters
+syn region   smlEncl transparent matchgroup=smlKeyword start="(" matchgroup=smlKeyword end=")" contains=ALLBUT,@smlContained,smlParenErr
+syn region   smlEncl transparent matchgroup=smlKeyword start="{" matchgroup=smlKeyword end="}"  contains=ALLBUT,@smlContained,smlBraceErr
+syn region   smlEncl transparent matchgroup=smlKeyword start="\[" matchgroup=smlKeyword end="\]" contains=ALLBUT,@smlContained,smlBrackErr
+syn region   smlEncl transparent matchgroup=smlKeyword start="#\[" matchgroup=smlKeyword end="\]" contains=ALLBUT,@smlContained,smlBrackErr
+
+
+" Comments
+syn region   smlComment start="(\*" end="\*)" contains=smlComment,smlTodo
+syn keyword  smlTodo contained TODO FIXME XXX
+
+
+" let
+syn region   smlEnd matchgroup=smlKeyword start="\<let\>" matchgroup=smlKeyword end="\<end\>" contains=ALLBUT,@smlContained,smlEndErr
+
+" local
+syn region   smlEnd matchgroup=smlKeyword start="\<local\>" matchgroup=smlKeyword end="\<end\>" contains=ALLBUT,@smlContained,smlEndErr
+
+" abstype
+syn region   smlNone matchgroup=smlKeyword start="\<abstype\>" matchgroup=smlKeyword end="\<end\>" contains=ALLBUT,@smlContained,smlEndErr
+
+" begin
+syn region   smlEnd matchgroup=smlKeyword start="\<begin\>" matchgroup=smlKeyword end="\<end\>" contains=ALLBUT,@smlContained,smlEndErr
+
+" if
+syn region   smlNone matchgroup=smlKeyword start="\<if\>" matchgroup=smlKeyword end="\<then\>" contains=ALLBUT,@smlContained,smlThenErr
+
+
+"" Modules
+
+" "struct"
+syn region   smlStruct matchgroup=smlModule start="\<struct\>" matchgroup=smlModule end="\<end\>" contains=ALLBUT,@smlContained,smlEndErr
+
+" "sig"
+syn region   smlSig matchgroup=smlModule start="\<sig\>" matchgroup=smlModule end="\<end\>" contains=ALLBUT,@smlContained,smlEndErr,smlModule
+syn region   smlModSpec matchgroup=smlKeyword start="\<structure\>" matchgroup=smlModule end="\<\u\(\w\|'\)*\>" contained contains=@smlAllErrs,smlComment skipwhite skipempty nextgroup=smlModTRWith,smlMPRestr
+
+" "open"
+syn region   smlNone matchgroup=smlKeyword start="\<open\>" matchgroup=smlModule end="\<\u\(\w\|'\)*\(\.\u\(\w\|'\)*\)*\>" contains=@smlAllErrs,smlComment
+
+" "structure" - somewhat complicated stuff ;-)
+syn region   smlModule matchgroup=smlKeyword start="\<\(structure\|functor\)\>" matchgroup=smlModule end="\<\u\(\w\|'\)*\>" contains=@smlAllErrs,smlComment skipwhite skipempty nextgroup=smlPreDef
+syn region   smlPreDef start="."me=e-1 matchgroup=smlKeyword end="\l\|="me=e-1 contained contains=@smlAllErrs,smlComment,smlModParam,smlModTypeRestr,smlModTRWith nextgroup=smlModPreRHS
+syn region   smlModParam start="([^*]" end=")" contained contains=@smlAENoParen,smlModParam1
+syn match    smlModParam1 "\<\u\(\w\|'\)*\>" contained skipwhite skipempty nextgroup=smlPreMPRestr
+
+syn region   smlPreMPRestr start="."me=e-1 end=")"me=e-1 contained contains=@smlAllErrs,smlComment,smlMPRestr,smlModTypeRestr
+
+syn region   smlMPRestr start=":" end="."me=e-1 contained contains=@smlComment skipwhite skipempty nextgroup=smlMPRestr1,smlMPRestr2,smlMPRestr3
+syn region   smlMPRestr1 matchgroup=smlModule start="\ssig\s\=" matchgroup=smlModule end="\<end\>" contained contains=ALLBUT,@smlContained,smlEndErr,smlModule
+syn region   smlMPRestr2 start="\sfunctor\(\s\|(\)\="me=e-1 matchgroup=smlKeyword end="->" contained contains=@smlAllErrs,smlComment,smlModParam skipwhite skipempty nextgroup=smlFuncWith
+syn match    smlMPRestr3 "\w\(\w\|'\)*\(\.\w\(\w\|'\)*\)*" contained
+syn match    smlModPreRHS "=" contained skipwhite skipempty nextgroup=smlModParam,smlFullMod
+syn region   smlModRHS start="." end=".\w\|([^*]"me=e-2 contained contains=smlComment skipwhite skipempty nextgroup=smlModParam,smlFullMod
+syn match    smlFullMod "\<\u\(\w\|'\)*\(\.\u\(\w\|'\)*\)*" contained skipwhite skipempty nextgroup=smlFuncWith
+
+syn region   smlFuncWith start="([^*]"me=e-1 end=")" contained contains=smlComment,smlWith,smlFuncStruct
+syn region   smlFuncStruct matchgroup=smlModule start="[^a-zA-Z]struct\>"hs=s+1 matchgroup=smlModule end="\<end\>" contains=ALLBUT,@smlContained,smlEndErr
+
+syn match    smlModTypeRestr "\<\w\(\w\|'\)*\(\.\w\(\w\|'\)*\)*\>" contained
+syn region   smlModTRWith start=":\s*("hs=s+1 end=")" contained contains=@smlAENoParen,smlWith
+syn match    smlWith "\<\(\u\(\w\|'\)*\.\)*\w\(\w\|'\)*\>" contained skipwhite skipempty nextgroup=smlWithRest
+syn region   smlWithRest start="[^)]" end=")"me=e-1 contained contains=ALLBUT,@smlContained
+
+" "signature"
+syn region   smlKeyword start="\<signature\>" matchgroup=smlModule end="\<\w\(\w\|'\)*\>" contains=smlComment skipwhite skipempty nextgroup=smlMTDef
+syn match    smlMTDef "=\s*\w\(\w\|'\)*\>"hs=s+1,me=s
+
+syn keyword  smlKeyword  and andalso case
+syn keyword  smlKeyword  datatype else eqtype
+syn keyword  smlKeyword  exception fn fun handle
+syn keyword  smlKeyword  in infix infixl infixr
+syn keyword  smlKeyword  match nonfix of orelse
+syn keyword  smlKeyword  raise handle type
+syn keyword  smlKeyword  val where while with withtype
+
+syn keyword  smlType     bool char exn int list option
+syn keyword  smlType     real string unit
+
+syn keyword  smlOperator div mod not or quot rem
+
+syn keyword  smlBoolean      true false
+syn match    smlConstructor  "(\s*)"
+syn match    smlConstructor  "\[\s*\]"
+syn match    smlConstructor  "#\[\s*\]"
+syn match    smlConstructor  "\u\(\w\|'\)*\>"
+
+" Module prefix
+syn match    smlModPath      "\u\(\w\|'\)*\."he=e-1
+
+syn match    smlCharacter    +#"\\""\|#"."\|#"\\\d\d\d"+
+syn match    smlCharErr      +#"\\\d\d"\|#"\\\d"+
+syn region   smlString       start=+"+ skip=+\\\\\|\\"+ end=+"+
+
+syn match    smlFunDef       "=>"
+syn match    smlRefAssign    ":="
+syn match    smlTopStop      ";;"
+syn match    smlOperator     "\^"
+syn match    smlOperator     "::"
+syn match    smlAnyVar       "\<_\>"
+syn match    smlKeyChar      "!"
+syn match    smlKeyChar      ";"
+syn match    smlKeyChar      "\*"
+syn match    smlKeyChar      "="
+
+syn match    smlNumber	      "\<-\=\d\+\>"
+syn match    smlNumber	      "\<-\=0[x|X]\x\+\>"
+syn match    smlReal	      "\<-\=\d\+\.\d*\([eE][-+]\=\d\+\)\=[fl]\=\>"
+
+" Synchronization
+syn sync minlines=20
+syn sync maxlines=500
+
+syn sync match smlEndSync     grouphere  smlEnd     "\<begin\>"
+syn sync match smlEndSync     groupthere smlEnd     "\<end\>"
+syn sync match smlStructSync  grouphere  smlStruct  "\<struct\>"
+syn sync match smlStructSync  groupthere smlStruct  "\<end\>"
+syn sync match smlSigSync     grouphere  smlSig     "\<sig\>"
+syn sync match smlSigSync     groupthere smlSig     "\<end\>"
+
+" Define the default highlighting.
+" For version 5.7 and earlier: only when not done already
+" For version 5.8 and later: only when an item doesn't have highlighting yet
+if version >= 508 || !exists("did_sml_syntax_inits")
+  if version < 508
+    let did_sml_syntax_inits = 1
+    command -nargs=+ HiLink hi link <args>
+  else
+    command -nargs=+ HiLink hi def link <args>
+  endif
+
+  HiLink smlBraceErr	 Error
+  HiLink smlBrackErr	 Error
+  HiLink smlParenErr	 Error
+
+  HiLink smlCommentErr	 Error
+
+  HiLink smlEndErr	 Error
+  HiLink smlThenErr	 Error
+
+  HiLink smlCharErr	 Error
+
+  HiLink smlComment	 Comment
+
+  HiLink smlModPath	 Include
+  HiLink smlModule	 Include
+  HiLink smlModParam1	 Include
+  HiLink smlModType	 Include
+  HiLink smlMPRestr3	 Include
+  HiLink smlFullMod	 Include
+  HiLink smlModTypeRestr Include
+  HiLink smlWith	 Include
+  HiLink smlMTDef	 Include
+
+  HiLink smlConstructor  Constant
+
+  HiLink smlModPreRHS	 Keyword
+  HiLink smlMPRestr2	 Keyword
+  HiLink smlKeyword	 Keyword
+  HiLink smlFunDef	 Keyword
+  HiLink smlRefAssign	 Keyword
+  HiLink smlKeyChar	 Keyword
+  HiLink smlAnyVar	 Keyword
+  HiLink smlTopStop	 Keyword
+  HiLink smlOperator	 Keyword
+
+  HiLink smlBoolean	 Boolean
+  HiLink smlCharacter	 Character
+  HiLink smlNumber	 Number
+  HiLink smlReal	 Float
+  HiLink smlString	 String
+  HiLink smlType	 Type
+  HiLink smlTodo	 Todo
+  HiLink smlEncl	 Keyword
+
+  delcommand HiLink
+endif
+
+let b:current_syntax = "sml"
+
+" vim: ts=8
--- /dev/null
+++ b/lib/vimfiles/syntax/snnsnet.vim
@@ -1,0 +1,77 @@
+" Vim syntax file
+" Language:	SNNS network file
+" Maintainer:	Davide Alberani <alberanid@bigfoot.com>
+" Last Change:	28 Apr 2001
+" Version:	0.2
+" URL:		http://digilander.iol.it/alberanid/vim/syntax/snnsnet.vim
+"
+" SNNS http://www-ra.informatik.uni-tuebingen.de/SNNS/
+" is a simulator for neural networks.
+
+if version < 600
+  syntax clear
+elseif exists("b:current_syntax")
+  finish
+endif
+
+syn match	snnsnetTitle	"no\."
+syn match	snnsnetTitle	"type name"
+syn match	snnsnetTitle	"unit name"
+syn match	snnsnetTitle	"act\( func\)\="
+syn match	snnsnetTitle	"out func"
+syn match	snnsnetTitle	"site\( name\)\="
+syn match	snnsnetTitle	"site function"
+syn match	snnsnetTitle	"source:weight"
+syn match	snnsnetTitle	"unitNo\."
+syn match	snnsnetTitle	"delta x"
+syn match	snnsnetTitle	"delta y"
+syn keyword	snnsnetTitle	typeName unitName bias st position subnet layer sites name target z LLN LUN Toff Soff Ctype
+
+syn match	snnsnetType	"SNNS network definition file [Vv]\d.\d.*" contains=snnsnetNumbers
+syn match	snnsnetType	"generated at.*" contains=snnsnetNumbers
+syn match	snnsnetType	"network name\s*:"
+syn match	snnsnetType	"source files\s*:"
+syn match	snnsnetType	"no\. of units\s*:.*" contains=snnsnetNumbers
+syn match	snnsnetType	"no\. of connections\s*:.*" contains=snnsnetNumbers
+syn match	snnsnetType	"no\. of unit types\s*:.*" contains=snnsnetNumbers
+syn match	snnsnetType	"no\. of site types\s*:.*" contains=snnsnetNumbers
+syn match	snnsnetType	"learning function\s*:"
+syn match	snnsnetType	"pruning function\s*:"
+syn match	snnsnetType	"subordinate learning function\s*:"
+syn match	snnsnetType	"update function\s*:"
+
+syn match	snnsnetSection	"unit definition section"
+syn match	snnsnetSection	"unit default section"
+syn match	snnsnetSection	"site definition section"
+syn match	snnsnetSection	"type definition section"
+syn match	snnsnetSection	"connection definition section"
+syn match	snnsnetSection	"layer definition section"
+syn match	snnsnetSection	"subnet definition section"
+syn match	snnsnetSection	"3D translation section"
+syn match	snnsnetSection	"time delay section"
+
+syn match	snnsnetNumbers	"\d" contained
+syn match	snnsnetComment	"#.*$" contains=snnsnetTodo
+syn keyword	snnsnetTodo	TODO XXX FIXME contained
+
+if version >= 508 || !exists("did_snnsnet_syn_inits")
+  if version < 508
+    let did_snnsnet_syn_inits = 1
+    command -nargs=+ HiLink hi link <args>
+  else
+    command -nargs=+ HiLink hi def link <args>
+  endif
+
+  HiLink snnsnetType		Type
+  HiLink snnsnetComment		Comment
+  HiLink snnsnetNumbers		Number
+  HiLink snnsnetSection		Statement
+  HiLink snnsnetTitle		Label
+  HiLink snnsnetTodo		Todo
+
+  delcommand HiLink
+endif
+
+let b:current_syntax = "snnsnet"
+
+" vim: ts=8 sw=2
--- /dev/null
+++ b/lib/vimfiles/syntax/snnspat.vim
@@ -1,0 +1,68 @@
+" Vim syntax file
+" Language:	SNNS pattern file
+" Maintainer:	Davide Alberani <alberanid@bigfoot.com>
+" Last Change:	28 Apr 2001
+" Version:	0.2
+" URL:		http://digilander.iol.it/alberanid/vim/syntax/snnspat.vim
+"
+" SNNS http://www-ra.informatik.uni-tuebingen.de/SNNS/
+" is a simulator for neural networks.
+
+if version < 600
+  syntax clear
+elseif exists("b:current_syntax")
+  finish
+endif
+
+
+" anything that isn't part of the header, a comment or a number
+" is wrong
+syn match	snnspatError	".*"
+" hoping that matches any kind of notation...
+syn match	snnspatAccepted	"\([-+]\=\(\d\+\.\|\.\)\=\d\+\([Ee][-+]\=\d\+\)\=\)"
+syn match	snnspatAccepted "\s"
+syn match	snnspatBrac	"\[\s*\d\+\(\s\|\d\)*\]" contains=snnspatNumbers
+
+" the accepted fields in the header
+syn match	snnspatNoHeader	"No\. of patterns\s*:\s*" contained
+syn match	snnspatNoHeader	"No\. of input units\s*:\s*" contained
+syn match	snnspatNoHeader	"No\. of output units\s*:\s*" contained
+syn match	snnspatNoHeader	"No\. of variable input dimensions\s*:\s*" contained
+syn match	snnspatNoHeader	"No\. of variable output dimensions\s*:\s*" contained
+syn match	snnspatNoHeader	"Maximum input dimensions\s*:\s*" contained
+syn match	snnspatNoHeader	"Maximum output dimensions\s*:\s*" contained
+syn match	snnspatGen	"generated at.*" contained contains=snnspatNumbers
+syn match	snnspatGen	"SNNS pattern definition file [Vv]\d\.\d" contained contains=snnspatNumbers
+
+" the header, what is not an accepted field, is an error
+syn region	snnspatHeader	start="^SNNS" end="^\s*[-+\.]\=[0-9#]"me=e-2 contains=snnspatNoHeader,snnspatNumbers,snnspatGen,snnspatBrac
+
+" numbers inside the header
+syn match	snnspatNumbers	"\d" contained
+syn match	snnspatComment	"#.*$" contains=snnspatTodo
+syn keyword	snnspatTodo	TODO XXX FIXME contained
+
+if version >= 508 || !exists("did_snnspat_syn_inits")
+  if version < 508
+    let did_snnspat_syn_inits = 1
+    command -nargs=+ HiLink hi link <args>
+  else
+    command -nargs=+ HiLink hi def link <args>
+  endif
+
+  HiLink snnspatGen		Statement
+  HiLink snnspatHeader		Error
+  HiLink snnspatNoHeader	Define
+  HiLink snnspatNumbers		Number
+  HiLink snnspatComment		Comment
+  HiLink snnspatError		Error
+  HiLink snnspatTodo		Todo
+  HiLink snnspatAccepted	NONE
+  HiLink snnspatBrac		NONE
+
+  delcommand HiLink
+endif
+
+let b:current_syntax = "snnspat"
+
+" vim: ts=8 sw=2
--- /dev/null
+++ b/lib/vimfiles/syntax/snnsres.vim
@@ -1,0 +1,60 @@
+" Vim syntax file
+" Language:	SNNS result file
+" Maintainer:	Davide Alberani <alberanid@bigfoot.com>
+" Last Change:	28 Apr 2001
+" Version:	0.2
+" URL:		http://digilander.iol.it/alberanid/vim/syntax/snnsres.vim
+"
+" SNNS http://www-ra.informatik.uni-tuebingen.de/SNNS/
+" is a simulator for neural networks.
+
+if version < 600
+  syntax clear
+elseif exists("b:current_syntax")
+  finish
+endif
+
+" the accepted fields in the header
+syn match	snnsresNoHeader	"No\. of patterns\s*:\s*" contained
+syn match	snnsresNoHeader	"No\. of input units\s*:\s*" contained
+syn match	snnsresNoHeader	"No\. of output units\s*:\s*" contained
+syn match	snnsresNoHeader	"No\. of variable input dimensions\s*:\s*" contained
+syn match	snnsresNoHeader	"No\. of variable output dimensions\s*:\s*" contained
+syn match	snnsresNoHeader	"Maximum input dimensions\s*:\s*" contained
+syn match	snnsresNoHeader	"Maximum output dimensions\s*:\s*" contained
+syn match	snnsresNoHeader	"startpattern\s*:\s*" contained
+syn match	snnsresNoHeader "endpattern\s*:\s*" contained
+syn match	snnsresNoHeader "input patterns included" contained
+syn match	snnsresNoHeader "teaching output included" contained
+syn match	snnsresGen	"generated at.*" contained contains=snnsresNumbers
+syn match	snnsresGen	"SNNS result file [Vv]\d\.\d" contained contains=snnsresNumbers
+
+" the header, what is not an accepted field, is an error
+syn region	snnsresHeader	start="^SNNS" end="^\s*[-+\.]\=[0-9#]"me=e-2 contains=snnsresNoHeader,snnsresNumbers,snnsresGen
+
+" numbers inside the header
+syn match	snnsresNumbers	"\d" contained
+syn match	snnsresComment	"#.*$" contains=snnsresTodo
+syn keyword	snnsresTodo	TODO XXX FIXME contained
+
+if version >= 508 || !exists("did_snnsres_syn_inits")
+  if version < 508
+    let did_snnsres_syn_inits = 1
+    command -nargs=+ HiLink hi link <args>
+  else
+    command -nargs=+ HiLink hi def link <args>
+  endif
+
+  HiLink snnsresGen		Statement
+  HiLink snnsresHeader		Statement
+  HiLink snnsresNoHeader	Define
+  HiLink snnsresNumbers		Number
+  HiLink snnsresComment		Comment
+  HiLink snnsresTodo		Todo
+
+  delcommand HiLink
+endif
+
+let b:current_syntax = "snnsres"
+
+" vim: ts=8 sw=2
--- /dev/null
+++ b/lib/vimfiles/syntax/snobol4.vim
@@ -1,0 +1,101 @@
+" Vim syntax file
+" Language:     SNOBOL4
+" Maintainer:   Rafal Sulejman <rms@poczta.onet.pl>
+" Site: http://rms.republika.pl/vim/syntax/snobol4.vim
+" Last change:  2006 may 1
+" Changes: 
+" - nonexistent Snobol4 keywords displayed as errors.
+
+" For version 5.x: Clear all syntax items
+" For version 6.x: Quit when a syntax file was already loaded
+if version < 600
+  syntax clear
+elseif exists("b:current_syntax")
+  finish
+endif
+
+syntax case ignore
+" Vanilla Snobol4 keywords
+syn keyword     snobol4Keyword   any apply arb arbno arg array
+syn keyword     snobol4Keyword   break
+syn keyword     snobol4Keyword   char clear code collect convert copy
+syn keyword     snobol4Keyword   data datatype date define detach differ dump dupl
+syn keyword     snobol4Keyword   endfile eq eval
+syn keyword     snobol4Keyword   field
+syn keyword     snobol4Keyword   ge gt ident
+syn keyword     snobol4Keyword   input integer item
+syn keyword     snobol4Keyword   le len lgt local lpad lt
+syn keyword     snobol4Keyword   ne notany
+syn keyword     snobol4Keyword   opsyn output
+syn keyword     snobol4Keyword   pos prototype
+syn keyword     snobol4Keyword   remdr replace rpad rpos rtab
+syn keyword     snobol4Keyword   size span stoptr
+syn keyword     snobol4Keyword   tab table time trace trim terminal
+syn keyword     snobol4Keyword   unload
+syn keyword     snobol4Keyword   value
+" Spitbol keywords
+" CSNOBOL keywords
+syn keyword     snobol4Keyword   sset
+
+syn region      snobol4String       matchgroup=Quote start=+"+ skip=+\\"+ end=+"+
+syn region      snobol4String       matchgroup=Quote start=+'+ skip=+\\'+ end=+'+
+syn match       snobol4Statement    "^-[^ ][^ ]*"
+syn match       snobol4Comment      "^\*.*$"
+syn match       snobol4Comment      ";\*.*$"
+syn match       snobol4Constant     "[^a-z]\.[a-z][a-z0-9\-]*"
+syn region      snobol4Goto        start=":[sf]\{0,1}(" end=")\|$\|;" contains=ALLBUT,snobol4ParenError
+syn match       snobol4Number       "\<\d*\(\.\d\d*\)*\>" 
+syn match       snobol4BogusSysVar       "&\w\{1,}"
+syn match       snobol4SysVar       "&\(abort\|alphabet\|anchor\|arb\|bal\|case\|code\|dump\|errlimit\|errtext\|errtype\|fail\|fence\|fnclevel\|ftrace\|fullscan\|input\|lastno\|lcase\|maxlngth\|output\|parm\|rem\|rtntype\|stcount\|stfcount\|stlimit\|stno\|succeed\|trace\|trim\|ucase\)"
+syn match       snobol4Label        "^[^-\.\+ \t]\S\{1,}"
+"
+" Parens matching
+syn cluster     snobol4ParenGroup   contains=snobol4ParenError
+syn region      snobol4Paren        transparent start='(' end=')' contains=ALLBUT,@snobol4ParenGroup,snobol4ErrInBracket
+syn match       snobol4ParenError   display "[\])]"
+syn match       snobol4ErrInParen   display contained "[\]{}]\|<%\|%>"
+syn region      snobol4Bracket      transparent start='\[\|<:' end=']\|:>' contains=ALLBUT,@snobol4ParenGroup,snobol4ErrInParen
+syn match       snobol4ErrInBracket display contained "[){}]\|<%\|%>"
+
+" optional shell shebang line
+syn match       snobol4Comment    "^\#\!.*$"
+
+
+" Define the default highlighting.
+" For version 5.7 and earlier: only when not done already
+" For version 5.8 and later: only when an item doesn't have highlighting yet
+if version >= 508 || !exists("did_snobol4_syntax_inits")
+  if version < 508
+    let did_snobol4_syntax_inits = 1
+    command -nargs=+ HiLink hi link <args>
+  else
+    command -nargs=+ HiLink hi def link <args>
+  endif
+
+  HiLink snobol4Constant        Constant
+  HiLink snobol4Label           Label
+  HiLink snobol4Goto            Repeat
+  HiLink snobol4Conditional     Conditional
+  HiLink snobol4Repeat          Repeat
+  HiLink snobol4Number          Number
+  HiLink snobol4Error           Error
+  HiLink snobol4Statement       PreProc
+  HiLink snobol4String          String
+  HiLink snobol4Comment         Comment
+  HiLink snobol4Special         Special
+  HiLink snobol4Todo            Todo
+  HiLink snobol4Keyword         Statement
+  HiLink snobol4Function        Statement
+  HiLink snobol4Keyword         Keyword
+  HiLink snobol4MathsOperator   Operator
+  HiLink snobol4ParenError      snobol4Error
+  HiLink snobol4ErrInParen      snobol4Error
+  HiLink snobol4ErrInBracket    snobol4Error
+  HiLink snobol4SysVar          Keyword
+  HiLink snobol4BogusSysVar     snobol4Error
+
+  delcommand HiLink
+endif
+
+let b:current_syntax = "snobol4"
+" vim: ts=8
--- /dev/null
+++ b/lib/vimfiles/syntax/spec.vim
@@ -1,0 +1,236 @@
+" Filename:    spec.vim
+" Purpose:     Vim syntax file
+" Language:    SPEC: Build/install scripts for Linux RPM packages
+" Maintainer:  Donovan Rebbechi elflord@pegasus.rutgers.edu
+" URL:	       http://pegasus.rutgers.edu/~elflord/vim/syntax/spec.vim
+" Last Change: Fri Dec 3 11:54 EST 2004 Marcin Dalecki
+
+" For version 5.x: Clear all syntax items
+" For version 6.x: Quit when a syntax file was already loaded
+if version < 600
+  syntax clear
+elseif exists("b:current_syntax")
+  finish
+endif
+
+syn sync minlines=1000
+
+syn match specSpecialChar contained '[][!$()\\|>^;:{}]'
+syn match specColon       contained ':'
+syn match specPercent     contained '%'
+
+syn match specVariables   contained '\$\h\w*' contains=specSpecialVariablesNames,specSpecialChar
+syn match specVariables   contained '\${\w*}' contains=specSpecialVariablesNames,specSpecialChar
+
+syn match specMacroIdentifier contained '%\h\w*' contains=specMacroNameLocal,specMacroNameOther,specPercent
+syn match specMacroIdentifier contained '%{\w*}' contains=specMacroNameLocal,specMacroNameOther,specPercent,specSpecialChar
+
+syn match specSpecialVariables contained '\$[0-9]\|\${[0-9]}'
+syn match specCommandOpts      contained '\s\(-\w\+\|--\w[a-zA-Z_-]\+\)'ms=s+1
+syn match specComment '^\s*#.*$'
+
+
+syn case match
+
+
+"matches with no highlight
+syn match specNoNumberHilite 'X11\|X11R6\|[a-zA-Z]*\.\d\|[a-zA-Z][-/]\d'
+syn match specManpageFile '[a-zA-Z]\.1'
+
+"Day, Month and most used license acronyms
+syn keyword specLicense contained GPL LGPL BSD MIT GNU
+syn keyword specWeekday contained Mon Tue Wed Thu Fri Sat Sun
+syn keyword specMonth   contained Jan Feb Mar Apr Jun Jul Aug Sep Oct Nov Dec
+syn keyword specMonth   contained January February March April May June July August September October November December
+
+"#, @, www
+syn match specNumber '\(^-\=\|[ \t]-\=\|-\)[0-9.-]*[0-9]'
+syn match specEmail contained "<\=\<[A-Za-z0-9_.-]\+@\([A-Za-z0-9_-]\+\.\)\+[A-Za-z]\+\>>\="
+syn match specURL      contained '\<\(\(https\{0,1}\|ftp\)://\|\(www[23]\{0,1}\.\|ftp\.\)\)[A-Za-z0-9._/~:,#-]\+\>'
+syn match specURLMacro contained '\<\(\(https\{0,1}\|ftp\)://\|\(www[23]\{0,1}\.\|ftp\.\)\)[A-Za-z0-9._/~:,#%{}-]\+\>' contains=specMacroIdentifier
+
+"TODO take specSpecialVariables out of the cluster for the sh* contains (ALLBUT)
+"Special system directories
+syn match specListedFilesPrefix contained '/\(usr\|local\|opt\|X11R6\|X11\)/'me=e-1
+syn match specListedFilesBin    contained '/s\=bin/'me=e-1
+syn match specListedFilesLib    contained '/\(lib\|include\)/'me=e-1
+syn match specListedFilesDoc    contained '/\(man\d*\|doc\|info\)\>'
+syn match specListedFilesEtc    contained '/etc/'me=e-1
+syn match specListedFilesShare  contained '/share/'me=e-1
+syn cluster specListedFiles contains=specListedFilesBin,specListedFilesLib,specListedFilesDoc,specListedFilesEtc,specListedFilesShare,specListedFilesPrefix,specVariables,specSpecialChar
+
+"specComands
+syn match   specConfigure  contained '\./configure'
+syn match   specTarCommand contained '\<tar\s\+[cxvpzIf]\{,5}\s*'
+syn keyword specCommandSpecial contained root
+syn keyword specCommand		contained make xmkmf mkdir chmod ln find sed rm strip moc echo grep ls rm mv mkdir install cp pwd cat tail then else elif cd gzip rmdir ln eval export touch
+syn cluster specCommands contains=specCommand,specTarCommand,specConfigure,specCommandSpecial
+
+"frequently used rpm env vars
+syn keyword specSpecialVariablesNames contained RPM_BUILD_ROOT RPM_BUILD_DIR RPM_SOURCE_DIR RPM_OPT_FLAGS LDFLAGS CC CC_FLAGS CPPNAME CFLAGS CXX CXXFLAGS CPPFLAGS
+
+"valid macro names from /usr/lib/rpm/macros
+syn keyword specMacroNameOther contained buildroot buildsubdir distribution disturl ix86 name nil optflags perl_sitearch release requires_eq vendor version
+syn match   specMacroNameOther contained '\<\(PATCH\|SOURCE\)\d*\>'
+
+"valid _macro names from /usr/lib/rpm/macros
+syn keyword specMacroNameLocal contained _arch _binary_payload _bindir _build _build_alias _build_cpu _builddir _build_os _buildshell _buildsubdir _build_vendor _bzip2bin _datadir _dbpath _dbpath_rebuild _defaultdocdir _docdir _excludedocs _exec_prefix _fixgroup _fixowner _fixperms _ftpport _ftpproxy _gpg_path _gzipbin _host _host_alias _host_cpu _host_os _host_vendor _httpport _httpproxy _includedir _infodir _install_langs _install_script_path _instchangelog _langpatt _lib _libdir _libexecdir _localstatedir _mandir _netsharedpath _oldincludedir _os _pgpbin _pgp_path _prefix _preScriptEnvironment _provides _rpmdir _rpmfilename _sbindir _sharedstatedir _signature _sourcedir _source_payload _specdir _srcrpmdir _sysconfdir _target _target_alias _target_cpu _target_os _target_platform _target_vendor _timecheck _tmppath _topdir _usr _usrsrc _var _vendor
+
+
+"------------------------------------------------------------------------------
+" here's is all the spec sections definitions: PreAmble, Description, Package,
+"   Scripts, Files and Changelog
+
+"One line macros - valid in all ScriptAreas
+"tip: remember do include new items on specScriptArea's skip section
+syn region specSectionMacroArea oneline matchgroup=specSectionMacro start='^%\(define\|patch\d*\|setup\|configure\|GNUconfigure\|find_lang\|makeinstall\|include\)\>' end='$' contains=specCommandOpts,specMacroIdentifier
+syn region specSectionMacroBracketArea oneline matchgroup=specSectionMacro start='^%{\(configure\|GNUconfigure\|find_lang\|makeinstall\)}' end='$' contains=specCommandOpts,specMacroIdentifier
+
+"%% Files Section %%
+"TODO %config valid parameters: missingok\|noreplace
+"TODO %verify valid parameters: \(not\)\= \(md5\|atime\|...\)
+syn region specFilesArea matchgroup=specSection start='^%[Ff][Ii][Ll][Ee][Ss]\>' skip='%\(attrib\|defattr\|attr\|dir\|config\|docdir\|doc\|lang\|verify\|ghost\)\>' end='^%[a-zA-Z]'me=e-2 contains=specFilesOpts,specFilesDirective,@specListedFiles,specComment,specCommandSpecial,specMacroIdentifier
+"tip: remember to include new itens in specFilesArea above
+syn match  specFilesDirective contained '%\(attrib\|defattr\|attr\|dir\|config\|docdir\|doc\|lang\|verify\|ghost\)\>'
+
+"valid options for certain section headers
+syn match specDescriptionOpts contained '\s-[ln]\s*\a'ms=s+1,me=e-1
+syn match specPackageOpts     contained    '\s-n\s*\w'ms=s+1,me=e-1
+syn match specFilesOpts       contained    '\s-f\s*\w'ms=s+1,me=e-1
+
+
+syn case ignore
+
+
+"%% PreAmble Section %%
+"Copyright and Serial were deprecated by License and Epoch
+syn region specPreAmbleDeprecated oneline matchgroup=specError start='^\(Copyright\|Serial\)' end='$' contains=specEmail,specURL,specURLMacro,specLicense,specColon,specVariables,specSpecialChar,specMacroIdentifier
+syn region specPreAmble oneline matchgroup=specCommand start='^\(Prereq\|Summary\|Name\|Version\|Packager\|Requires\|Icon\|URL\|Source\d*\|Patch\d*\|Prefix\|Packager\|Group\|License\|Release\|BuildRoot\|Distribution\|Vendor\|Provides\|ExclusiveArch\|ExcludeArch\|ExclusiveOS\|Obsoletes\|BuildArch\|BuildArchitectures\|BuildRequires\|BuildConflicts\|BuildPreReq\|Conflicts\|AutoRequires\|AutoReq\|AutoReqProv\|AutoProv\|Epoch\)' end='$' contains=specEmail,specURL,specURLMacro,specLicense,specColon,specVariables,specSpecialChar,specMacroIdentifier
+
+"%% Description Section %%
+syn region specDescriptionArea matchgroup=specSection start='^%description' end='^%'me=e-1 contains=specDescriptionOpts,specEmail,specURL,specNumber,specMacroIdentifier,specComment
+
+"%% Package Section %%
+syn region specPackageArea matchgroup=specSection start='^%package' end='^%'me=e-1 contains=specPackageOpts,specPreAmble,specComment
+
+"%% Scripts Section %%
+syn region specScriptArea matchgroup=specSection start='^%\(prep\|build\|install\|clean\|pre\|postun\|preun\|post\)\>' skip='^%{\|^%\(define\|patch\d*\|configure\|GNUconfigure\|setup\|find_lang\|makeinstall\)\>' end='^%'me=e-1 contains=specSpecialVariables,specVariables,@specCommands,specVariables,shDo,shFor,shCaseEsac,specNoNumberHilite,specCommandOpts,shComment,shIf,specSpecialChar,specMacroIdentifier,specSectionMacroArea,specSectionMacroBracketArea,shOperator,shQuote1,shQuote2
+
+"%% Changelog Section %%
+syn region specChangelogArea matchgroup=specSection start='^%changelog' end='^%'me=e-1 contains=specEmail,specURL,specWeekday,specMonth,specNumber,specComment,specLicense
+
+
+
+"------------------------------------------------------------------------------
+"here's the shell syntax for all the Script Sections
+
+
+syn case match
+
+
+"sh-like comment stile, only valid in script part
+syn match shComment contained '#.*$'
+
+syn region shQuote1 contained matchgroup=shQuoteDelim start=+'+ skip=+\\'+ end=+'+ contains=specMacroIdentifier
+syn region shQuote2 contained matchgroup=shQuoteDelim start=+"+ skip=+\\"+ end=+"+ contains=specVariables,specMacroIdentifier
+
+syn match shOperator contained '[><|!&;]\|[!=]='
+syn region shDo transparent matchgroup=specBlock start="\<do\>" end="\<done\>" contains=ALLBUT,shFunction,shDoError,shCase,specPreAmble,@specListedFiles
+
+syn region specIf  matchgroup=specBlock start="%ifosf\|%ifos\|%ifnos\|%ifarch\|%ifnarch\|%else"  end='%endif'  contains=ALLBUT, specIfError, shCase
+
+syn region  shIf transparent matchgroup=specBlock start="\<if\>" end="\<fi\>" contains=ALLBUT,shFunction,shIfError,shCase,@specListedFiles
+
+syn region  shFor  matchgroup=specBlock start="\<for\>" end="\<in\>" contains=ALLBUT,shFunction,shInError,shCase,@specListedFiles
+
+syn region shCaseEsac transparent matchgroup=specBlock start="\<case\>" matchgroup=NONE end="\<in\>"me=s-1 contains=ALLBUT,shFunction,shCaseError,@specListedFiles nextgroup=shCaseEsac
+syn region shCaseEsac matchgroup=specBlock start="\<in\>" end="\<esac\>" contains=ALLBUT,shFunction,shCaseError,@specListedFilesBin
+syn region shCase matchgroup=specBlock contained start=")"  end=";;" contains=ALLBUT,shFunction,shCaseError,shCase,@specListedFiles
+
+syn sync match shDoSync       grouphere  shDo       "\<do\>"
+syn sync match shDoSync       groupthere shDo       "\<done\>"
+syn sync match shIfSync       grouphere  shIf       "\<if\>"
+syn sync match shIfSync       groupthere shIf       "\<fi\>"
+syn sync match specIfSync     grouphere  specIf     "%ifarch\|%ifos\|%ifnos"
+syn sync match specIfSync     groupthere specIf     "%endIf"
+syn sync match shForSync      grouphere  shFor      "\<for\>"
+syn sync match shForSync      groupthere shFor      "\<in\>"
+syn sync match shCaseEsacSync grouphere  shCaseEsac "\<case\>"
+syn sync match shCaseEsacSync groupthere shCaseEsac "\<esac\>"
+
+" Define the default highlighting.
+" For version 5.7 and earlier: only when not done already
+" For version 5.8 and later: only when an item doesn't have highlighting yet
+if version >= 508 || !exists("did_spec_syntax_inits")
+  if version < 508
+    let did_spec_syntax_inits = 1
+    command -nargs=+ HiLink hi link <args>
+  else
+    command -nargs=+ HiLink hi def link <args>
+  endif
+
+  "main types color definitions
+  HiLink specSection			Structure
+  HiLink specSectionMacro		Macro
+  HiLink specWWWlink			PreProc
+  HiLink specOpts			Operator
+
+  "yes, it's ugly, but white is sooo cool
+  if &background == "dark"
+    hi def specGlobalMacro		ctermfg=white
+  else
+    HiLink specGlobalMacro		Identifier
+  endif
+
+  "sh colors
+  HiLink shComment			Comment
+  HiLink shIf				Statement
+  HiLink shOperator			Special
+  HiLink shQuote1			String
+  HiLink shQuote2			String
+  HiLink shQuoteDelim			Statement
+
+  "spec colors
+  HiLink specBlock			Function
+  HiLink specColon			Special
+  HiLink specCommand			Statement
+  HiLink specCommandOpts		specOpts
+  HiLink specCommandSpecial		Special
+  HiLink specComment			Comment
+  HiLink specConfigure			specCommand
+  HiLink specDate			String
+  HiLink specDescriptionOpts		specOpts
+  HiLink specEmail			specWWWlink
+  HiLink specError			Error
+  HiLink specFilesDirective		specSectionMacro
+  HiLink specFilesOpts			specOpts
+  HiLink specLicense			String
+  HiLink specMacroNameLocal		specGlobalMacro
+  HiLink specMacroNameOther		specGlobalMacro
+  HiLink specManpageFile		NONE
+  HiLink specMonth			specDate
+  HiLink specNoNumberHilite		NONE
+  HiLink specNumber			Number
+  HiLink specPackageOpts		specOpts
+  HiLink specPercent			Special
+  HiLink specSpecialChar		Special
+  HiLink specSpecialVariables		specGlobalMacro
+  HiLink specSpecialVariablesNames	specGlobalMacro
+  HiLink specTarCommand			specCommand
+  HiLink specURL			specWWWlink
+  HiLink specURLMacro			specWWWlink
+  HiLink specVariables			Identifier
+  HiLink specWeekday			specDate
+  HiLink specListedFilesBin		Statement
+  HiLink specListedFilesDoc		Statement
+  HiLink specListedFilesEtc		Statement
+  HiLink specListedFilesLib		Statement
+  HiLink specListedFilesPrefix		Statement
+  HiLink specListedFilesShare		Statement
+
+  delcommand HiLink
+endif
+
+let b:current_syntax = "spec"
+
+" vim: ts=8
--- /dev/null
+++ b/lib/vimfiles/syntax/specman.vim
@@ -1,0 +1,182 @@
+" Vim syntax file
+" Language:	SPECMAN E-LANGUAGE
+" Maintainer:	Or Freund <or@mobilian.com ;omf@gmx.co.uk; OrMeir@yahoo.com>
+" Last Update: Wed Oct 24 2001
+
+"---------------------------------------------------------
+"| If anyone found an error or fix the parenthesis part  |
+"| I will be happy to hear about it			 |
+"| Thanks Or.						 |
+"---------------------------------------------------------
+
+" Remove any old syntax stuff hanging around
+" For version 5.x: Clear all syntax items
+" For version 6.x: Quit when a syntax file was already loaded
+if version < 600
+  syntax clear
+elseif exists("b:current_syntax")
+  finish
+endif
+
+syn keyword  specmanTodo	contained TODO todo ToDo FIXME XXX
+
+syn keyword specmanStatement   var instance on compute start event expect check that routine
+syn keyword specmanStatement   specman is also first only with like
+syn keyword specmanStatement   list of all radix hex dec bin ignore illegal
+syn keyword specmanStatement   traceable untraceable
+syn keyword specmanStatement   cover using count_only trace_only at_least transition item ranges
+syn keyword specmanStatement   cross text call task within
+
+syn keyword specmanMethod      initialize non_terminal testgroup delayed exit finish
+syn keyword specmanMethod      out append print outf appendf
+syn keyword specmanMethod      post_generate pre_generate setup_test finalize_test extract_test
+syn keyword specmanMethod      init run copy as_a set_config dut_error add clear lock quit
+syn keyword specmanMethod      lock unlock release swap quit to_string value stop_run
+syn keyword specmanMethod      crc_8 crc_32 crc_32_flip get_config add0 all_indices and_all
+syn keyword specmanMethod      apply average count delete exists first_index get_indices
+syn keyword specmanMethod      has insert is_a_permutation is_empty key key_exists key_index
+syn keyword specmanMethod      last last_index max max_index max_value min min_index
+syn keyword specmanMethod      min_value or_all pop pop0 push push0 product resize reverse
+syn keyword specmanMethod      sort split sum top top0 unique clear is_all_iterations
+syn keyword specmanMethod      get_enclosing_unit hdl_path exec deep_compare deep_compare_physical
+syn keyword specmanMethod      pack unpack warning error fatal
+syn match   specmanMethod      "size()"
+syn keyword specmanPacking     packing low high
+syn keyword specmanType        locker address
+syn keyword specmanType        body code vec chars
+syn keyword specmanType        integer real bool int long uint byte bits bit time string
+syn keyword specmanType        byte_array external_pointer
+syn keyword specmanBoolean     TRUE FALSE
+syn keyword specmanPreCondit   #ifdef #ifndef #else
+
+syn keyword specmanConditional choose matches
+syn keyword specmanConditional if then else when try
+
+
+
+syn keyword specmanLabel  case casex casez default
+
+syn keyword specmanLogical     and or not xor
+
+syn keyword specmanRepeat      until repeat while for from to step each do break continue
+syn keyword specmanRepeat      before next sequence always -kind network
+syn keyword specmanRepeat      index it me in new return result select
+
+syn keyword specmanTemporal    cycle sample events forever
+syn keyword specmanTemporal    wait  change  negedge rise fall delay sync sim true detach eventually emit
+
+syn keyword specmanConstant    MAX_INT MIN_INT NULL UNDEF
+
+syn keyword specmanDefine       define as computed type extend
+syn keyword specmanDefine       verilog vhdl variable global sys
+syn keyword specmanStructure    struct unit
+syn keyword specmanInclude     import
+syn keyword specmanConstraint  gen keep keeping soft	before
+
+syn keyword specmanSpecial     untyped symtab ECHO DOECHO
+syn keyword specmanFile        files load module ntv source_ref script read write
+syn keyword specmanFSM	       initial idle others posedge clock cycles
+
+
+syn match   specmanOperator    "[&|~><!)(*%@+/=?:;}{,.\^\-\[\]]"
+syn match   specmanOperator    "+="
+syn match   specmanOperator    "-="
+syn match   specmanOperator    "*="
+
+syn match   specmanComment     "//.*"  contains=specmanTodo
+syn match   specmanComment     "--.*"
+syn region  specmanComment     start="^'>"hs=s+2 end="^<'"he=e-2
+
+syn match   specmanHDL	       "'[`.a-zA-Z0-9_@\[\]]\+\>'"
+
+
+syn match   specmanCompare    "=="
+syn match   specmanCompare    "!==="
+syn match   specmanCompare    "==="
+syn match   specmanCompare    "!="
+syn match   specmanCompare    ">="
+syn match   specmanCompare    "<="
+syn match   specmanNumber "[0-9]:[0-9]"
+syn match   specmanNumber "\(\<\d\+\|\)'[bB]\s*[0-1_xXzZ?]\+\>"
+syn match   specmanNumber "0[bB]\s*[0-1_xXzZ?]\+\>"
+syn match   specmanNumber "\(\<\d\+\|\)'[oO]\s*[0-7_xXzZ?]\+\>"
+syn match   specmanNumber "0[oO]\s*[0-9a-fA-F_xXzZ?]\+\>"
+syn match   specmanNumber "\(\<\d\+\|\)'[dD]\s*[0-9_xXzZ?]\+\>"
+syn match   specmanNumber "\(\<\d\+\|\)'[hH]\s*[0-9a-fA-F_xXzZ?]\+\>"
+syn match   specmanNumber "0[xX]\s*[0-9a-fA-F_xXzZ?]\+\>"
+syn match   specmanNumber "\<[+-]\=[0-9_]\+\(\.[0-9_]*\|\)\(e[0-9_]*\|\)\>"
+
+syn region  specmanString start=+"+  end=+"+
+
+
+
+"**********************************************************************
+" I took this section from c.vim but I didnt succeded to make it work
+" ANY one who dare jumping to this deep watter is more than welocome!
+"**********************************************************************
+""catch errors caused by wrong parenthesis and brackets
+
+"syn cluster     specmanParenGroup     contains=specmanParenError
+"" ,specmanNumbera,specmanComment
+"if exists("specman_no_bracket_error")
+"syn region    specmanParen	     transparent start='(' end=')' contains=ALLBUT,@specmanParenGroup
+"syn match     specmanParenError     ")"
+"syn match     specmanErrInParen     contained "[{}]"
+"else
+"syn region    specmanParen	     transparent start='(' end=')' contains=ALLBUT,@specmanParenGroup,specmanErrInBracket
+"syn match     specmanParenError     "[\])]"
+"syn match     specmanErrInParen     contained "[\]{}]"
+"syn region    specmanBracket	     transparent start='\[' end=']' contains=ALLBUT,@specmanParenGroup,specmanErrInParen
+"syn match     specmanErrInBracket   contained "[);{}]"
+"endif
+"
+
+"Modify the following as needed.  The trade-off is performance versus
+"functionality.
+
+syn sync lines=50
+
+" Define the default highlighting.
+" For version 5.7 and earlier: only when not done already
+" For version 5.8 and later: only when an item doesn't have highlighting yet
+if version >= 508 || !exists("did_specman_syn_inits")
+  if version < 508
+    let did_specman_syn_inits = 1
+    command -nargs=+ HiLink hi link <args>
+  else
+    command -nargs=+ HiLink hi def link <args>
+  endif
+  " The default methods for highlighting.  Can be overridden later
+	HiLink	specmanConditional	Conditional
+	HiLink	specmanConstraint	Conditional
+	HiLink	specmanRepeat		Repeat
+	HiLink	specmanString		String
+	HiLink	specmanComment		Comment
+	HiLink	specmanConstant		Macro
+	HiLink	specmanNumber		Number
+	HiLink	specmanCompare		Operator
+	HiLink	specmanOperator		Operator
+	HiLink	specmanLogical		Operator
+	HiLink	specmanStatement	Statement
+	HiLink	specmanHDL		SpecialChar
+	HiLink	specmanMethod		Function
+	HiLink	specmanInclude		Include
+	HiLink	specmanStructure	Structure
+	HiLink	specmanBoolean		Boolean
+	HiLink	specmanFSM		Label
+	HiLink	specmanSpecial		Special
+	HiLink	specmanType		Type
+	HiLink	specmanTemporal		Type
+	HiLink	specmanFile		Include
+	HiLink	specmanPreCondit	Include
+	HiLink	specmanDefine		Typedef
+	HiLink	specmanLabel		Label
+	HiLink	specmanPacking		keyword
+	HiLink	specmanTodo		Todo
+	HiLink	specmanParenError	Error
+	HiLink	specmanErrInParen	Error
+	HiLink	specmanErrInBracket	Error
+	delcommand	HiLink
+endif
+
+let b:current_syntax = "specman"
--- /dev/null
+++ b/lib/vimfiles/syntax/spice.vim
@@ -1,0 +1,87 @@
+" Vim syntax file
+" Language:	Spice circuit simulator input netlist
+" Maintainer:	Noam Halevy <Noam.Halevy.motorola.com>
+" Last Change:	12/08/99
+"
+" This is based on sh.vim by Lennart Schultz
+" but greatly simplified
+
+" For version 5.x: Clear all syntax items
+" For version 6.x: Quit when a syntax file was already loaded
+if version < 600
+  syntax clear
+elseif exists("b:current_syntax")
+  finish
+endif
+
+" spice syntax is case INsensitive
+syn case ignore
+
+syn keyword	spiceTodo	contained TODO
+
+syn match spiceComment  "^ \=\*.*$"
+syn match spiceComment  "\$.*$"
+
+" Numbers, all with engineering suffixes and optional units
+"==========================================================
+"floating point number, with dot, optional exponent
+syn match spiceNumber  "\<[0-9]\+\.[0-9]*\(e[-+]\=[0-9]\+\)\=\(meg\=\|[afpnumkg]\)\="
+"floating point number, starting with a dot, optional exponent
+syn match spiceNumber  "\.[0-9]\+\(e[-+]\=[0-9]\+\)\=\(meg\=\|[afpnumkg]\)\="
+"integer number with optional exponent
+syn match spiceNumber  "\<[0-9]\+\(e[-+]\=[0-9]\+\)\=\(meg\=\|[afpnumkg]\)\="
+
+" Misc
+"=====
+syn match   spiceWrapLineOperator       "\\$"
+syn match   spiceWrapLineOperator       "^+"
+
+syn match   spiceStatement      "^ \=\.\I\+"
+
+" Matching pairs of parentheses
+"==========================================
+syn region  spiceParen transparent matchgroup=spiceOperator start="(" end=")" contains=ALLBUT,spiceParenError
+syn region  spiceSinglequote matchgroup=spiceOperator start=+'+ end=+'+
+
+" Errors
+"=======
+syn match spiceParenError ")"
+
+" Syncs
+" =====
+syn sync minlines=50
+
+" Define the default highlighting.
+" For version 5.7 and earlier: only when not done already
+" For version 5.8 and later: only when an item doesn't have highlighting yet
+if version >= 508 || !exists("did_spice_syntax_inits")
+  if version < 508
+    let did_spice_syntax_inits = 1
+    command -nargs=+ HiLink hi link <args>
+  else
+    command -nargs=+ HiLink hi def link <args>
+  endif
+
+  HiLink spiceTodo		Todo
+  HiLink spiceWrapLineOperator	spiceOperator
+  HiLink spiceSinglequote	spiceExpr
+  HiLink spiceExpr		Function
+  HiLink spiceParenError	Error
+  HiLink spiceStatement		Statement
+  HiLink spiceNumber		Number
+  HiLink spiceComment		Comment
+  HiLink spiceOperator		Operator
+
+  delcommand HiLink
+endif
+
+let b:current_syntax = "spice"
+
+" insert the following to $VIM/syntax/scripts.vim
+" to autodetect HSpice netlists and text listing output:
+"
+" " Spice netlists and text listings
+" elseif getline(1) =~ 'spice\>' || getline("$") =~ '^\.end'
+"   so <sfile>:p:h/spice.vim
+
+" vim: ts=8
--- /dev/null
+++ b/lib/vimfiles/syntax/splint.vim
@@ -1,0 +1,260 @@
+" Vim syntax file
+" Language:	splint (C with lclint/splint Annotations)
+" Maintainer:	Ralf Wildenhues <Ralf.Wildenhues@gmx.de>
+" Splint Home:	http://www.splint.org/
+" Last Change:	$Date: 2004/06/13 20:08:47 $
+" $Revision: 1.1 $
+
+" Note:		Splint annotated files are not detected by default.
+"		If you want to use this file for highlighting C code,
+"		please make sure splint.vim is sourced instead of c.vim,
+"		for example by putting
+"			/* vim: set filetype=splint : */
+"		at the end of your code or something like
+"			au! BufRead,BufNewFile *.c	setfiletype splint
+"		in your vimrc file or filetype.vim
+
+
+" For version 5.x: Clear all syntax items
+" For version 6.x: Quit when a syntax file was already loaded
+if version < 600
+  syntax clear
+elseif exists("b:current_syntax")
+  finish
+endif
+
+" Read the C syntax to start with
+if version < 600
+  so <sfile>:p:h/c.vim
+else
+  runtime! syntax/c.vim
+endif
+
+
+" FIXME: uses and changes several clusters defined in c.vim
+"	so watch for changes there
+
+" TODO: make a little more grammar explicit
+"	match flags with hyphen and underscore notation
+"	match flag expanded forms
+"	accept other comment char than @
+
+syn case match
+" splint annotations (taken from 'splint -help annotations')
+syn match   splintStateAnnot	contained "\(pre\|post\):\(only\|shared\|owned\|dependent\|observer\|exposed\|isnull\|notnull\)"
+syn keyword splintSpecialAnnot  contained special
+syn keyword splintSpecTag	contained uses sets defines allocated releases
+syn keyword splintModifies	contained modifies
+syn keyword splintRequires	contained requires ensures
+syn keyword splintGlobals	contained globals
+syn keyword splintGlobitem	contained internalState fileSystem
+syn keyword splintGlobannot	contained undef killed
+syn keyword splintWarning	contained warn
+
+syn keyword splintModitem	contained internalState fileSystem nothing
+syn keyword splintReqitem	contained MaxSet MaxRead result
+syn keyword splintIter		contained iter yield
+syn keyword splintConst		contained constant
+syn keyword splintAlt		contained alt
+
+syn keyword splintType		contained abstract concrete mutable immutable refcounted numabstract
+syn keyword splintGlobalType	contained unchecked checkmod checked checkedstrict
+syn keyword splintMemMgm	contained dependent keep killref only owned shared temp
+syn keyword splintAlias		contained unique returned
+syn keyword splintExposure	contained observer exposed
+syn keyword splintDefState	contained out in partial reldef
+syn keyword splintGlobState	contained undef killed
+syn keyword splintNullState	contained null notnull relnull
+syn keyword splintNullPred	contained truenull falsenull nullwhentrue falsewhennull
+syn keyword splintExit		contained exits mayexit trueexit falseexit neverexit
+syn keyword splintExec		contained noreturn maynotreturn noreturnwhentrue noreturnwhenfalse alwaysreturns
+syn keyword splintSef		contained sef
+syn keyword splintDecl		contained unused external
+syn keyword splintCase		contained fallthrough
+syn keyword splintBreak		contained innerbreak loopbreak switchbreak innercontinue
+syn keyword splintUnreach	contained notreached
+syn keyword splintSpecFunc	contained printflike scanflike messagelike
+
+" TODO: make these region or match
+syn keyword splintErrSupp	contained i ignore end t
+syn match   splintErrSupp	contained "[it]\d\+\>"
+syn keyword splintTypeAcc	contained access noaccess
+
+syn keyword splintMacro		contained notfunction
+syn match   splintSpecType	contained "\(\|unsigned\|signed\)integraltype"
+
+" Flags taken from 'splint -help flags full' divided in local and global flags
+"				 Local Flags:
+syn keyword splintFlag contained abstract abstractcompare accessall accessczech accessczechoslovak
+syn keyword splintFlag contained accessfile accessmodule accessslovak aliasunique allblock
+syn keyword splintFlag contained allempty allglobs allimponly allmacros alwaysexits
+syn keyword splintFlag contained annotationerror ansi89limits assignexpose badflag bitwisesigned
+syn keyword splintFlag contained boolcompare boolfalse boolint boolops booltrue
+syn keyword splintFlag contained booltype bounds boundscompacterrormessages boundsread boundswrite
+syn keyword splintFlag contained branchstate bufferoverflow bufferoverflowhigh bugslimit casebreak
+syn keyword splintFlag contained caseinsensitivefilenames castexpose castfcnptr charindex charint
+syn keyword splintFlag contained charintliteral charunsignedchar checkedglobalias checkmodglobalias checkpost
+syn keyword splintFlag contained checkstrictglobalias checkstrictglobs codeimponly commentchar commenterror
+syn keyword splintFlag contained compdef compdestroy compmempass constmacros constprefix
+syn keyword splintFlag contained constprefixexclude constuse continuecomment controlnestdepth cppnames
+syn keyword splintFlag contained csvoverwrite czech czechconsts czechfcns czechmacros
+syn keyword splintFlag contained czechoslovak czechoslovakconsts czechoslovakfcns czechoslovakmacros czechoslovaktypes
+syn keyword splintFlag contained czechoslovakvars czechtypes czechvars debugfcnconstraint declundef
+syn keyword splintFlag contained deepbreak deparrays dependenttrans distinctexternalnames distinctinternalnames
+syn keyword splintFlag contained duplicatecases duplicatequals elseifcomplete emptyret enumindex
+syn keyword splintFlag contained enumint enummembers enummemuse enumprefix enumprefixexclude
+syn keyword splintFlag contained evalorder evalorderuncon exitarg exportany exportconst
+syn keyword splintFlag contained exportfcn exportheader exportheadervar exportiter exportlocal
+syn keyword splintFlag contained exportmacro exporttype exportvar exposetrans externalnamecaseinsensitive
+syn keyword splintFlag contained externalnamelen externalprefix externalprefixexclude fcnderef fcnmacros
+syn keyword splintFlag contained fcnpost fcnuse fielduse fileextensions filestaticprefix
+syn keyword splintFlag contained filestaticprefixexclude firstcase fixedformalarray floatdouble forblock
+syn keyword splintFlag contained forcehints forempty forloopexec formalarray formatcode
+syn keyword splintFlag contained formatconst formattype forwarddecl freshtrans fullinitblock
+syn keyword splintFlag contained globalias globalprefix globalprefixexclude globimponly globnoglobs
+syn keyword splintFlag contained globs globsimpmodsnothing globstate globuse gnuextensions
+syn keyword splintFlag contained grammar hasyield hints htmlfileformat ifblock
+syn keyword splintFlag contained ifempty ignorequals ignoresigns immediatetrans impabstract
+syn keyword splintFlag contained impcheckedglobs impcheckedspecglobs impcheckedstatics impcheckedstrictglobs impcheckedstrictspecglobs
+syn keyword splintFlag contained impcheckedstrictstatics impcheckmodglobs impcheckmodinternals impcheckmodspecglobs impcheckmodstatics
+syn keyword splintFlag contained impconj implementationoptional implictconstraint impouts imptype
+syn keyword splintFlag contained includenest incompletetype incondefs incondefslib indentspaces
+syn keyword splintFlag contained infloops infloopsuncon initallelements initsize internalglobs
+syn keyword splintFlag contained internalglobsnoglobs internalnamecaseinsensitive internalnamelen internalnamelookalike iso99limits
+syn keyword splintFlag contained isoreserved isoreservedinternal iterbalance iterloopexec iterprefix
+syn keyword splintFlag contained iterprefixexclude iteryield its4low its4moderate its4mostrisky
+syn keyword splintFlag contained its4risky its4veryrisky keep keeptrans kepttrans
+syn keyword splintFlag contained legacy libmacros likelyboundsread likelyboundswrite likelybool
+syn keyword splintFlag contained likelybounds limit linelen lintcomments localprefix
+syn keyword splintFlag contained localprefixexclude locindentspaces longint longintegral longsignedintegral
+syn keyword splintFlag contained longunsignedintegral longunsignedunsignedintegral loopexec looploopbreak looploopcontinue
+syn keyword splintFlag contained loopswitchbreak macroassign macroconstdecl macrodecl macroempty
+syn keyword splintFlag contained macrofcndecl macromatchname macroparams macroparens macroredef
+syn keyword splintFlag contained macroreturn macrostmt macrounrecog macrovarprefix macrovarprefixexclude
+syn keyword splintFlag contained maintype matchanyintegral matchfields mayaliasunique memchecks
+syn keyword splintFlag contained memimp memtrans misplacedsharequal misscase modfilesys
+syn keyword splintFlag contained modglobs modglobsnomods modglobsunchecked modinternalstrict modnomods
+syn keyword splintFlag contained modobserver modobserveruncon mods modsimpnoglobs modstrictglobsnomods
+syn keyword splintFlag contained moduncon modunconnomods modunspec multithreaded mustdefine
+syn keyword splintFlag contained mustfree mustfreefresh mustfreeonly mustmod mustnotalias
+syn keyword splintFlag contained mutrep namechecks needspec nestcomment nestedextern
+syn keyword splintFlag contained newdecl newreftrans nextlinemacros noaccess nocomments
+syn keyword splintFlag contained noeffect noeffectuncon noparams nopp noret
+syn keyword splintFlag contained null nullassign nullderef nullinit nullpass
+syn keyword splintFlag contained nullptrarith nullret nullstate nullterminated
+syn keyword splintFlag contained numabstract numabstractcast numabstractindex numabstractlit numabstractprint
+syn keyword splintFlag contained numenummembers numliteral numstructfields observertrans obviousloopexec
+syn keyword splintFlag contained oldstyle onlytrans onlyunqglobaltrans orconstraint overload
+syn keyword splintFlag contained ownedtrans paramimptemp paramuse parenfileformat partial
+syn keyword splintFlag contained passunknown portability predassign predbool predboolint
+syn keyword splintFlag contained predboolothers predboolptr preproc protoparammatch protoparamname
+syn keyword splintFlag contained protoparamprefix protoparamprefixexclude ptrarith ptrcompare ptrnegate
+syn keyword splintFlag contained quiet readonlystrings readonlytrans realcompare redecl
+syn keyword splintFlag contained redef redundantconstraints redundantsharequal refcounttrans relaxquals
+syn keyword splintFlag contained relaxtypes repeatunrecog repexpose retalias retexpose
+syn keyword splintFlag contained retimponly retval retvalbool retvalint retvalother
+syn keyword splintFlag contained sefparams sefuncon shadow sharedtrans shiftimplementation
+syn keyword splintFlag contained shiftnegative shortint showallconjs showcolumn showconstraintlocation
+syn keyword splintFlag contained showconstraintparens showdeephistory showfunc showloadloc showscan
+syn keyword splintFlag contained showsourceloc showsummary sizeofformalarray sizeoftype skipisoheaders
+syn keyword splintFlag contained skipposixheaders slashslashcomment slovak slovakconsts slovakfcns
+syn keyword splintFlag contained slovakmacros slovaktypes slovakvars specglobimponly specimponly
+syn keyword splintFlag contained specmacros specretimponly specstructimponly specundecl specundef
+syn keyword splintFlag contained stackref statemerge statetransfer staticinittrans statictrans
+syn keyword splintFlag contained strictbranchstate strictdestroy strictops strictusereleased stringliterallen
+syn keyword splintFlag contained stringliteralnoroom stringliteralnoroomfinalnull stringliteralsmaller stringliteraltoolong structimponly
+syn keyword splintFlag contained superuser switchloopbreak switchswitchbreak syntax sysdirerrors
+syn keyword splintFlag contained sysdirexpandmacros sysunrecog tagprefix tagprefixexclude temptrans
+syn keyword splintFlag contained tmpcomments toctou topuse trytorecover type
+syn keyword splintFlag contained typeprefix typeprefixexclude typeuse uncheckedglobalias uncheckedmacroprefix
+syn keyword splintFlag contained uncheckedmacroprefixexclude uniondef unixstandard unqualifiedinittrans unqualifiedtrans
+syn keyword splintFlag contained unreachable unrecog unrecogcomments unrecogdirective unrecogflagcomments
+syn keyword splintFlag contained unsignedcompare unusedspecial usedef usereleased usevarargs
+syn keyword splintFlag contained varuse voidabstract warnflags warnlintcomments warnmissingglobs
+syn keyword splintFlag contained warnmissingglobsnoglobs warnposixheaders warnrc warnsysfiles warnunixlib
+syn keyword splintFlag contained warnuse whileblock whileempty whileloopexec zerobool
+syn keyword splintFlag contained zeroptr
+"				       Global Flags:
+syn keyword splintGlobalFlag contained csv dump errorstream errorstreamstderr errorstreamstdout
+syn keyword splintGlobalFlag contained expect f help i isolib
+syn keyword splintGlobalFlag contained larchpath lclexpect lclimportdir lcs lh
+syn keyword splintGlobalFlag contained load messagestream messagestreamstderr messagestreamstdout mts
+syn keyword splintGlobalFlag contained neverinclude nof nolib posixlib posixstrictlib
+syn keyword splintGlobalFlag contained showalluses singleinclude skipsysheaders stats streamoverwrite
+syn keyword splintGlobalFlag contained strictlib supcounts sysdirs timedist tmpdir
+syn keyword splintGlobalFlag contained unixlib unixstrictlib warningstream warningstreamstderr warningstreamstdout
+syn keyword splintGlobalFlag contained whichlib
+syn match   splintFlagExpr contained "[\+\-\=]" nextgroup=splintFlag,splintGlobalFlag
+
+" detect missing /*@ and wrong */
+syn match	splintAnnError	"@\*/"
+syn cluster	cCommentGroup	add=splintAnnError
+syn match	splintAnnError2	"[^@]\*/"hs=s+1 contained
+syn region	splintAnnotation start="/\*@" end="@\*/" contains=@splintAnnotElem,cType keepend
+syn match	splintShortAnn	"/\*@\*/"
+syn cluster	splintAnnotElem	contains=splintStateAnnot,splintSpecialAnnot,splintSpecTag,splintModifies,splintRequires,splintGlobals,splintGlobitem,splintGlobannot,splintWarning,splintModitem,splintIter,splintConst,splintAlt,splintType,splintGlobalType,splintMemMgm,splintAlias,splintExposure,splintDefState,splintGlobState,splintNullState,splintNullPred,splintExit,splintExec,splintSef,splintDecl,splintCase,splintBreak,splintUnreach,splintSpecFunc,splintErrSupp,splintTypeAcc,splintMacro,splintSpecType,splintAnnError2,splintFlagExpr
+syn cluster	splintAllStuff	contains=@splintAnnotElem,splintFlag,splintGlobalFlag
+syn cluster	cParenGroup	add=@splintAllStuff
+syn cluster	cPreProcGroup	add=@splintAllStuff
+syn cluster	cMultiGroup	add=@splintAllStuff
+
+" Define the default highlighting.
+" For version 5.7 and earlier: only when not done already
+" For version 5.8 and later: only when an item doesn't have highlighting yet
+if version >= 508 || !exists("did_splint_syntax_inits")
+  if version < 508
+    let did_splint_syntax_inits = 1
+    command -nargs=+ HiLink hi link <args>
+  else
+    command -nargs=+ HiLink hi def link <args>
+  endif
+
+  HiLink splintShortAnn		splintAnnotation
+  HiLink splintAnnotation	Comment
+  HiLink splintAnnError		splintError
+  HiLink splintAnnError2	splintError
+  HiLink splintFlag		SpecialComment
+  HiLink splintGlobalFlag	splintError
+  HiLink splintSpecialAnnot	splintAnnKey
+  HiLink splintStateAnnot	splintAnnKey
+  HiLink splintSpecTag		splintAnnKey
+  HiLink splintModifies		splintAnnKey
+  HiLink splintRequires		splintAnnKey
+  HiLink splintGlobals		splintAnnKey
+  HiLink splintGlobitem		Constant
+  HiLink splintGlobannot	splintAnnKey
+  HiLink splintWarning		splintAnnKey
+  HiLink splintModitem		Constant
+  HiLink splintIter		splintAnnKey
+  HiLink splintConst		splintAnnKey
+  HiLink splintAlt		splintAnnKey
+  HiLink splintType		splintAnnKey
+  HiLink splintGlobalType	splintAnnKey
+  HiLink splintMemMgm		splintAnnKey
+  HiLink splintAlias		splintAnnKey
+  HiLink splintExposure		splintAnnKey
+  HiLink splintDefState		splintAnnKey
+  HiLink splintGlobState	splintAnnKey
+  HiLink splintNullState	splintAnnKey
+  HiLink splintNullPred		splintAnnKey
+  HiLink splintExit		splintAnnKey
+  HiLink splintExec		splintAnnKey
+  HiLink splintSef		splintAnnKey
+  HiLink splintDecl		splintAnnKey
+  HiLink splintCase		splintAnnKey
+  HiLink splintBreak		splintAnnKey
+  HiLink splintUnreach		splintAnnKey
+  HiLink splintSpecFunc		splintAnnKey
+  HiLink splintErrSupp		splintAnnKey
+  HiLink splintTypeAcc		splintAnnKey
+  HiLink splintMacro		splintAnnKey
+  HiLink splintSpecType		splintAnnKey
+  HiLink splintAnnKey		Type
+  HiLink splintError		Error
+
+  delcommand HiLink
+endif
+
+let b:current_syntax = "splint"
+
+" vim: ts=8
--- /dev/null
+++ b/lib/vimfiles/syntax/spup.vim
@@ -1,0 +1,277 @@
+" Vim syntax file
+" Language:     Speedup, plant simulator from AspenTech
+" Maintainer:   Stefan.Schwarzer <s.schwarzer@ndh.net>
+" URL:			http://www.ndh.net/home/sschwarzer/download/spup.vim
+" Last Change:  2003 May 11
+" Filename:     spup.vim
+
+" Bugs
+" - in the appropriate sections keywords are always highlighted
+"   even if they are not used with the appropriate meaning;
+"   example: in
+"       MODEL demonstration
+"       TYPE
+"      *area AS area
+"   both "area" are highlighted as spupType.
+"
+" If you encounter problems or have questions or suggestions, mail me
+
+" Remove old syntax stuff
+" For version 5.x: Clear all syntax items
+" For version 6.x: Quit when a syntax file was already loaded
+if version < 600
+    syntax clear
+elseif exists("b:current_syntax")
+    finish
+endif
+
+" don't hightlight several keywords like subsections
+"let strict_subsections = 1
+
+" highlight types usually found in DECLARE section
+if !exists("hightlight_types")
+    let highlight_types = 1
+endif
+
+" one line comment syntax (# comments)
+" 1. allow appended code after comment, do not complain
+" 2. show code beginnig with the second # as an error
+" 3. show whole lines with more than one # as an error
+if !exists("oneline_comments")
+    let oneline_comments = 2
+endif
+
+" Speedup SECTION regions
+syn case ignore
+syn region spupCdi		  matchgroup=spupSection start="^CDI"		 end="^\*\*\*\*" contains=spupCdiSubs,@spupOrdinary
+syn region spupConditions matchgroup=spupSection start="^CONDITIONS" end="^\*\*\*\*" contains=spupConditionsSubs,@spupOrdinary,spupConditional,spupOperator,spupCode
+syn region spupDeclare    matchgroup=spupSection start="^DECLARE"    end="^\*\*\*\*" contains=spupDeclareSubs,@spupOrdinary,spupTypes,spupCode
+syn region spupEstimation matchgroup=spupSection start="^ESTIMATION" end="^\*\*\*\*" contains=spupEstimationSubs,@spupOrdinary
+syn region spupExternal   matchgroup=spupSection start="^EXTERNAL"   end="^\*\*\*\*" contains=spupExternalSubs,@spupOrdinary
+syn region spupFlowsheet  matchgroup=spupSection start="^FLOWSHEET"  end="^\*\*\*\*" contains=spupFlowsheetSubs,@spupOrdinary,spupStreams,@spupTextproc
+syn region spupFunction   matchgroup=spupSection start="^FUNCTION"   end="^\*\*\*\*" contains=spupFunctionSubs,@spupOrdinary,spupHelp,spupCode,spupTypes
+syn region spupGlobal     matchgroup=spupSection start="^GLOBAL"     end="^\*\*\*\*" contains=spupGlobalSubs,@spupOrdinary
+syn region spupHomotopy   matchgroup=spupSection start="^HOMOTOPY"   end="^\*\*\*\*" contains=spupHomotopySubs,@spupOrdinary
+syn region spupMacro      matchgroup=spupSection start="^MACRO"      end="^\*\*\*\*" contains=spupMacroSubs,@spupOrdinary,@spupTextproc,spupTypes,spupStreams,spupOperator
+syn region spupModel      matchgroup=spupSection start="^MODEL"      end="^\*\*\*\*" contains=spupModelSubs,@spupOrdinary,spupConditional,spupOperator,spupTypes,spupStreams,@spupTextproc,spupHelp
+syn region spupOperation  matchgroup=spupSection start="^OPERATION"  end="^\*\*\*\*" contains=spupOperationSubs,@spupOrdinary,@spupTextproc
+syn region spupOptions    matchgroup=spupSection start="^OPTIONS"    end="^\*\*\*\*" contains=spupOptionsSubs,@spupOrdinary
+syn region spupProcedure  matchgroup=spupSection start="^PROCEDURE"  end="^\*\*\*\*" contains=spupProcedureSubs,@spupOrdinary,spupHelp,spupCode,spupTypes
+syn region spupProfiles   matchgroup=spupSection start="^PROFILES"   end="^\*\*\*\*" contains=@spupOrdinary,@spupTextproc
+syn region spupReport     matchgroup=spupSection start="^REPORT"     end="^\*\*\*\*" contains=spupReportSubs,@spupOrdinary,spupHelp,@spupTextproc
+syn region spupTitle      matchgroup=spupSection start="^TITLE"      end="^\*\*\*\*" contains=spupTitleSubs,spupComment,spupConstant,spupError
+syn region spupUnit       matchgroup=spupSection start="^UNIT"       end="^\*\*\*\*" contains=spupUnitSubs,@spupOrdinary
+
+" Subsections
+syn keyword spupCdiSubs		   INPUT FREE OUTPUT LINEARTIME MINNONZERO CALCULATE FILES SCALING contained
+syn keyword spupDeclareSubs    TYPE STREAM contained
+syn keyword spupEstimationSubs ESTIMATE SSEXP DYNEXP RESULT contained
+syn keyword spupExternalSubs   TRANSMIT RECEIVE contained
+syn keyword spupFlowsheetSubs  STREAM contained
+syn keyword spupFunctionSubs   INPUT OUTPUT contained
+syn keyword spupGlobalSubs     VARIABLES MAXIMIZE MINIMIZE CONSTRAINT contained
+syn keyword spupHomotopySubs   VARY OPTIONS contained
+syn keyword spupMacroSubs      MODEL FLOWSHEET contained
+syn keyword spupModelSubs      CATEGORY SET TYPE STREAM EQUATION PROCEDURE contained
+syn keyword spupOperationSubs  SET PRESET INITIAL SSTATE FREE contained
+syn keyword spupOptionsSubs    ROUTINES TRANSLATE EXECUTION contained
+syn keyword spupProcedureSubs  INPUT OUTPUT SPACE PRECALL POSTCALL DERIVATIVE STREAM contained
+" no subsections for Profiles
+syn keyword spupReportSubs     SET INITIAL FIELDS FIELDMARK DISPLAY WITHIN contained
+syn keyword spupUnitSubs       ROUTINES SET contained
+
+" additional keywords for subsections
+if !exists( "strict_subsections" )
+    syn keyword spupConditionsSubs STOP PRINT contained
+    syn keyword spupDeclareSubs    UNIT SET COMPONENTS THERMO OPTIONS contained
+    syn keyword spupEstimationSubs VARY MEASURE INITIAL contained
+    syn keyword spupFlowsheetSubs  TYPE FEED PRODUCT INPUT OUTPUT CONNECTION OF IS contained
+    syn keyword spupMacroSubs      CONNECTION STREAM SET INPUT OUTPUT OF IS FEED PRODUCT TYPE contained
+    syn keyword spupModelSubs      AS ARRAY OF INPUT OUTPUT CONNECTION contained
+    syn keyword spupOperationSubs  WITHIN contained
+    syn keyword spupReportSubs     LEFT RIGHT CENTER CENTRE UOM TIME DATE VERSION RELDATE contained
+    syn keyword spupUnitSubs       IS A contained
+endif
+
+" Speedup data types
+if exists( "highlight_types" )
+    syn keyword spupTypes act_coeff_liq area coefficient concentration contained
+    syn keyword spupTypes control_signal cond_liq cond_vap cp_mass_liq contained
+    syn keyword spupTypes cp_mol_liq cp_mol_vap cv_mol_liq cv_mol_vap contained
+    syn keyword spupTypes diffus_liq diffus_vap delta_p dens_mass contained
+    syn keyword spupTypes dens_mass_sol dens_mass_liq dens_mass_vap dens_mol contained
+    syn keyword spupTypes dens_mol_sol dens_mol_liq dens_mol_vap enthflow contained
+    syn keyword spupTypes enth_mass enth_mass_liq enth_mass_vap enth_mol contained
+    syn keyword spupTypes enth_mol_sol enth_mol_liq enth_mol_vap entr_mol contained
+    syn keyword spupTypes entr_mol_sol entr_mol_liq entr_mol_vap fraction contained
+    syn keyword spupTypes flow_mass flow_mass_liq flow_mass_vap flow_mol contained
+    syn keyword spupTypes flow_mol_vap flow_mol_liq flow_vol flow_vol_vap contained
+    syn keyword spupTypes flow_vol_liq fuga_vap fuga_liq fuga_sol contained
+    syn keyword spupTypes gibb_mol_sol heat_react heat_trans_coeff contained
+    syn keyword spupTypes holdup_heat holdup_heat_liq holdup_heat_vap contained
+    syn keyword spupTypes holdup_mass holdup_mass_liq holdup_mass_vap contained
+    syn keyword spupTypes holdup_mol holdup_mol_liq holdup_mol_vap k_value contained
+    syn keyword spupTypes length length_delta length_short liqfraction contained
+    syn keyword spupTypes liqmassfraction mass massfraction molefraction contained
+    syn keyword spupTypes molweight moment_inertia negative notype percent contained
+    syn keyword spupTypes positive pressure press_diff press_drop press_rise contained
+    syn keyword spupTypes ratio reaction reaction_mass rotation surf_tens contained
+    syn keyword spupTypes temperature temperature_abs temp_diff temp_drop contained
+    syn keyword spupTypes temp_rise time vapfraction vapmassfraction contained
+    syn keyword spupTypes velocity visc_liq visc_vap volume zmom_rate contained
+    syn keyword spupTypes seg_rate smom_rate tmom_rate zmom_mass seg_mass contained
+    syn keyword spupTypes smom_mass tmom_mass zmom_holdup seg_holdup contained
+    syn keyword spupTypes smom_holdup tmom_holdup contained
+endif
+
+" stream types
+syn keyword spupStreams  mainstream vapour liquid contained
+
+" "conditional" keywords
+syn keyword spupConditional  IF THEN ELSE ENDIF contained
+" Operators, symbols etc.
+syn keyword spupOperator  AND OR NOT contained
+syn match spupSymbol  "[,\-+=:;*/\"<>@%()]" contained
+syn match spupSpecial  "[&\$?]" contained
+" Surprisingly, Speedup allows no unary + instead of the -
+syn match spupError  "[(=+\-*/]\s*+\d\+\([ed][+-]\=\d\+\)\=\>"lc=1 contained
+syn match spupError  "[(=+\-*/]\s*+\d\+\.\([ed][+-]\=\d\+\)\=\>"lc=1 contained
+syn match spupError  "[(=+\-*/]\s*+\d*\.\d\+\([ed][+-]\=\d\+\)\=\>"lc=1 contained
+" String
+syn region spupString  start=+"+  end=+"+  oneline contained
+syn region spupString  start=+'+  end=+'+  oneline contained
+" Identifier
+syn match spupIdentifier  "\<[a-z][a-z0-9_]*\>" contained
+" Textprocessor directives
+syn match spupTextprocGeneric  "?[a-z][a-z0-9_]*\>" contained
+syn region spupTextprocError matchgroup=spupTextprocGeneric start="?ERROR"  end="?END"he=s-1 contained
+" Number, without decimal point
+syn match spupNumber  "-\=\d\+\([ed][+-]\=\d\+\)\=" contained
+" Number, allows 1. before exponent
+syn match spupNumber  "-\=\d\+\.\([ed][+-]\=\d\+\)\=" contained
+" Number allows .1 before exponent
+syn match spupNumber  "-\=\d*\.\d\+\([ed][+-]\=\d\+\)\=" contained
+" Help subsections
+syn region spupHelp  start="^HELP"hs=e+1  end="^\$ENDHELP"he=s-1 contained
+" Fortran code
+syn region spupCode  start="^CODE"hs=e+1  end="^\$ENDCODE"he=s-1 contained
+" oneline comments
+if oneline_comments > 3
+    oneline_comments = 2   " default
+endif
+if oneline_comments == 1
+    syn match spupComment  "#[^#]*#\="
+elseif oneline_comments == 2
+    syn match spupError  "#.*$"
+    syn match spupComment  "#[^#]*"  nextgroup=spupError
+elseif oneline_comments == 3
+    syn match spupComment  "#[^#]*"
+    syn match spupError  "#[^#]*#.*"
+endif
+" multiline comments
+syn match spupOpenBrace "{" contained
+syn match spupError  "}"
+syn region spupComment  matchgroup=spupComment2  start="{"  end="}"  keepend  contains=spupOpenBrace
+
+syn cluster spupOrdinary  contains=spupNumber,spupIdentifier,spupSymbol
+syn cluster spupOrdinary  add=spupError,spupString,spupComment
+syn cluster spupTextproc  contains=spupTextprocGeneric,spupTextprocError
+
+" define syncronizing; especially OPERATION sections can become very large
+syn sync clear
+syn sync minlines=100
+syn sync maxlines=500
+
+syn sync match spupSyncOperation  grouphere spupOperation  "^OPERATION"
+syn sync match spupSyncCdi		  grouphere spupCdi		   "^CDI"
+syn sync match spupSyncConditions grouphere spupConditions "^CONDITIONS"
+syn sync match spupSyncDeclare    grouphere spupDeclare    "^DECLARE"
+syn sync match spupSyncEstimation grouphere spupEstimation "^ESTIMATION"
+syn sync match spupSyncExternal   grouphere spupExternal   "^EXTERNAL"
+syn sync match spupSyncFlowsheet  grouphere spupFlowsheet  "^FLOWSHEET"
+syn sync match spupSyncFunction   grouphere spupFunction   "^FUNCTION"
+syn sync match spupSyncGlobal     grouphere spupGlobal     "^GLOBAL"
+syn sync match spupSyncHomotopy   grouphere spupHomotopy   "^HOMOTOPY"
+syn sync match spupSyncMacro      grouphere spupMacro      "^MACRO"
+syn sync match spupSyncModel      grouphere spupModel      "^MODEL"
+syn sync match spupSyncOperation  grouphere spupOperation  "^OPERATION"
+syn sync match spupSyncOptions    grouphere spupOptions    "^OPTIONS"
+syn sync match spupSyncProcedure  grouphere spupProcedure  "^PROCEDURE"
+syn sync match spupSyncProfiles   grouphere spupProfiles   "^PROFILES"
+syn sync match spupSyncReport     grouphere spupReport     "^REPORT"
+syn sync match spupSyncTitle      grouphere spupTitle      "^TITLE"
+syn sync match spupSyncUnit       grouphere spupUnit       "^UNIT"
+
+" Define the default highlighting.
+" For version 5.7 and earlier: only when not done already
+" For version 5.8 and later: only when an item doesn't have highlighting yet
+if version >= 508 || !exists("did_spup_syn_inits")
+    if version < 508
+		let did_spup_syn_inits = 1
+		command -nargs=+ HiLink hi link <args>
+	else
+		command -nargs=+ HiLink hi def link <args>
+    endif
+
+	HiLink spupCdi			spupSection
+	HiLink spupConditions	spupSection
+	HiLink spupDeclare		spupSection
+	HiLink spupEstimation	spupSection
+	HiLink spupExternal		spupSection
+	HiLink spupFlowsheet	spupSection
+	HiLink spupFunction		spupSection
+	HiLink spupGlobal		spupSection
+	HiLink spupHomotopy		spupSection
+	HiLink spupMacro		spupSection
+	HiLink spupModel		spupSection
+	HiLink spupOperation	spupSection
+	HiLink spupOptions		spupSection
+	HiLink spupProcedure	spupSection
+	HiLink spupProfiles		spupSection
+	HiLink spupReport		spupSection
+	HiLink spupTitle		spupConstant  " this is correct, truly ;)
+	HiLink spupUnit			spupSection
+
+	HiLink spupCdiSubs		  spupSubs
+	HiLink spupConditionsSubs spupSubs
+	HiLink spupDeclareSubs	  spupSubs
+	HiLink spupEstimationSubs spupSubs
+	HiLink spupExternalSubs   spupSubs
+	HiLink spupFlowsheetSubs  spupSubs
+	HiLink spupFunctionSubs   spupSubs
+	HiLink spupHomotopySubs   spupSubs
+	HiLink spupMacroSubs	  spupSubs
+	HiLink spupModelSubs	  spupSubs
+	HiLink spupOperationSubs  spupSubs
+	HiLink spupOptionsSubs	  spupSubs
+	HiLink spupProcedureSubs  spupSubs
+	HiLink spupReportSubs	  spupSubs
+	HiLink spupUnitSubs		  spupSubs
+
+	HiLink spupCode			   Normal
+	HiLink spupComment		   Comment
+	HiLink spupComment2		   spupComment
+	HiLink spupConditional	   Statement
+	HiLink spupConstant		   Constant
+	HiLink spupError		   Error
+	HiLink spupHelp			   Normal
+	HiLink spupIdentifier	   Identifier
+	HiLink spupNumber		   Constant
+	HiLink spupOperator		   Special
+	HiLink spupOpenBrace	   spupError
+	HiLink spupSection		   Statement
+	HiLink spupSpecial		   spupTextprocGeneric
+	HiLink spupStreams		   Type
+	HiLink spupString		   Constant
+	HiLink spupSubs			   Statement
+	HiLink spupSymbol		   Special
+	HiLink spupTextprocError   Normal
+	HiLink spupTextprocGeneric PreProc
+	HiLink spupTypes		   Type
+
+    delcommand HiLink
+endif
+
+let b:current_syntax = "spup"
+
+" vim:ts=4
--- /dev/null
+++ b/lib/vimfiles/syntax/spyce.vim
@@ -1,0 +1,110 @@
+" Vim syntax file
+" Language:	   SPYCE
+" Maintainer:	 Rimon Barr <rimon AT acm DOT org>
+" URL:		     http://spyce.sourceforge.net
+" Last Change: 2003 May 11
+
+" For version 5.x: Clear all syntax items
+" For version 6.x: Quit when a syntax file was already loaded
+if version < 600
+  syntax clear
+elseif exists("b:current_syntax")
+  finish
+endif
+
+" we define it here so that included files can test for it
+if !exists("main_syntax")
+  let main_syntax='spyce'
+endif
+
+" Read the HTML syntax to start with
+let b:did_indent = 1	     " don't perform HTML indentation!
+let html_no_rendering = 1    " do not render <b>,<i>, etc...
+if version < 600
+  so <sfile>:p:h/html.vim
+else
+  runtime! syntax/html.vim
+  unlet b:current_syntax
+endif
+
+" include python
+syn include @Python <sfile>:p:h/python.vim
+syn include @Html <sfile>:p:h/html.vim
+
+" spyce definitions
+syn keyword spyceDirectiveKeyword include compact module import contained
+syn keyword spyceDirectiveArg name names file contained
+syn region  spyceDirectiveString start=+"+ end=+"+ contained
+syn match   spyceDirectiveValue "=[\t ]*[^'", \t>][^, \t>]*"hs=s+1 contained
+
+syn match spyceBeginErrorS  ,\[\[,
+syn match spyceBeginErrorA  ,<%,
+syn cluster spyceBeginError contains=spyceBeginErrorS,spyceBeginErrorA
+syn match spyceEndErrorS    ,\]\],
+syn match spyceEndErrorA    ,%>,
+syn cluster spyceEndError contains=spyceEndErrorS,spyceEndErrorA
+
+syn match spyceEscBeginS       ,\\\[\[,
+syn match spyceEscBeginA       ,\\<%,
+syn cluster spyceEscBegin contains=spyceEscBeginS,spyceEscBeginA
+syn match spyceEscEndS	       ,\\\]\],
+syn match spyceEscEndA	       ,\\%>,
+syn cluster spyceEscEnd contains=spyceEscEndS,spyceEscEndA
+syn match spyceEscEndCommentS  ,--\\\]\],
+syn match spyceEscEndCommentA  ,--\\%>,
+syn cluster spyceEscEndComment contains=spyceEscEndCommentS,spyceEscEndCommentA
+
+syn region spyceStmtS      matchgroup=spyceStmtDelim start=,\[\[, end=,\]\], contains=@Python,spyceLambdaS,spyceLambdaA,spyceBeginError keepend
+syn region spyceStmtA      matchgroup=spyceStmtDelim start=,<%, end=,%>, contains=@Python,spyceLambdaS,spyceLambdaA,spyceBeginError keepend
+syn region spyceChunkS     matchgroup=spyceChunkDelim start=,\[\[\\, end=,\]\], contains=@Python,spyceLambdaS,spyceLambdaA,spyceBeginError keepend
+syn region spyceChunkA     matchgroup=spyceChunkDelim start=,<%\\, end=,%>, contains=@Python,spyceLambdaS,spyceLambdaA,spyceBeginError keepend
+syn region spyceEvalS      matchgroup=spyceEvalDelim start=,\[\[=, end=,\]\], contains=@Python,spyceLambdaS,spyceLambdaA,spyceBeginError keepend
+syn region spyceEvalA      matchgroup=spyceEvalDelim start=,<%=, end=,%>, contains=@Python,spyceLambdaS,spyceLambdaA,spyceBeginError keepend
+syn region spyceDirectiveS matchgroup=spyceDelim start=,\[\[\., end=,\]\], contains=spyceBeginError,spyceDirectiveKeyword,spyceDirectiveArg,spyceDirectiveValue,spyceDirectiveString keepend
+syn region spyceDirectiveA matchgroup=spyceDelim start=,<%@, end=,%>, contains=spyceBeginError,spyceDirectiveKeyword,spyceDirectiveArg,spyceDirectiveValue,spyceDirectiveString keepend
+syn region spyceCommentS   matchgroup=spyceCommentDelim start=,\[\[--, end=,--\]\],
+syn region spyceCommentA   matchgroup=spyceCommentDelim start=,<%--, end=,--%>,
+syn region spyceLambdaS    matchgroup=spyceLambdaDelim start=,\[\[spy!\?, end=,\]\], contains=@Html,@spyce extend
+syn region spyceLambdaA    matchgroup=spyceLambdaDelim start=,<%spy!\?, end=,%>, contains=@Html,@spyce extend
+
+syn cluster spyce contains=spyceStmtS,spyceStmtA,spyceChunkS,spyceChunkA,spyceEvalS,spyceEvalA,spyceCommentS,spyceCommentA,spyceDirectiveS,spyceDirectiveA
+
+syn cluster htmlPreproc contains=@spyce
+
+hi link spyceDirectiveKeyword	Special
+hi link spyceDirectiveArg	Type
+hi link spyceDirectiveString	String
+hi link spyceDirectiveValue	String
+
+hi link spyceDelim		Special
+hi link spyceStmtDelim		spyceDelim
+hi link spyceChunkDelim		spyceDelim
+hi link spyceEvalDelim		spyceDelim
+hi link spyceLambdaDelim	spyceDelim
+hi link spyceCommentDelim	Comment
+
+hi link spyceBeginErrorS	Error
+hi link spyceBeginErrorA	Error
+hi link spyceEndErrorS		Error
+hi link spyceEndErrorA		Error
+
+hi link spyceStmtS		spyce
+hi link spyceStmtA		spyce
+hi link spyceChunkS		spyce
+hi link spyceChunkA		spyce
+hi link spyceEvalS		spyce
+hi link spyceEvalA		spyce
+hi link spyceDirectiveS		spyce
+hi link spyceDirectiveA		spyce
+hi link spyceCommentS		Comment
+hi link spyceCommentA		Comment
+hi link spyceLambdaS		Normal
+hi link spyceLambdaA		Normal
+
+hi link spyce			Statement
+
+let b:current_syntax = "spyce"
+if main_syntax == 'spyce'
+  unlet main_syntax
+endif
+
--- /dev/null
+++ b/lib/vimfiles/syntax/sql.vim
@@ -1,0 +1,39 @@
+" Vim syntax file loader
+" Language:    SQL
+" Maintainer:  David Fishburn <fishburn at ianywhere dot com>
+" Last Change: Thu Sep 15 2005 10:30:02 AM
+" Version:     1.0
+
+" Description: Checks for a:
+"                  buffer local variable,
+"                  global variable,
+"              If the above exist, it will source the type specified.
+"              If none exist, it will source the default sql.vim file.
+"
+" For version 5.x: Clear all syntax items
+" For version 6.x: Quit when a syntax file was already loaded
+if version < 600
+    syntax clear
+elseif exists("b:current_syntax")
+    finish
+endif
+
+" Default to the standard Vim distribution file
+let filename = 'sqloracle'
+
+" Check for overrides.  Buffer variables have the highest priority.
+if exists("b:sql_type_override")
+    " Check the runtimepath to see if the file exists
+    if globpath(&runtimepath, 'syntax/'.b:sql_type_override.'.vim') != ''
+        let filename = b:sql_type_override
+    endif
+elseif exists("g:sql_type_default")
+    if globpath(&runtimepath, 'syntax/'.g:sql_type_default.'.vim') != ''
+        let filename = g:sql_type_default
+    endif
+endif
+
+" Source the appropriate file
+exec 'runtime syntax/'.filename.'.vim'
+
+" vim:sw=4:ff=unix:
--- /dev/null
+++ b/lib/vimfiles/syntax/sqlanywhere.vim
@@ -1,0 +1,706 @@
+" Vim syntax file
+" Language:    SQL, Adaptive Server Anywhere
+" Maintainer:  David Fishburn <fishburn at ianywhere dot com>
+" Last Change: Thu Sep 15 2005 10:30:09 AM
+" Version:     9.0.2
+
+" Description: Updated to Adaptive Server Anywhere 9.0.2
+"              Updated to Adaptive Server Anywhere 9.0.1
+"              Updated to Adaptive Server Anywhere 9.0.0
+"
+" For version 5.x: Clear all syntax items
+" For version 6.x: Quit when a syntax file was already loaded
+if version < 600
+    syntax clear
+elseif exists("b:current_syntax")
+    finish
+endif
+
+syn case ignore
+
+" The SQL reserved words, defined as keywords.
+
+syn keyword sqlSpecial  false null true
+
+" common functions
+syn keyword sqlFunction	count sum avg min max debug_eng isnull
+syn keyword sqlFunction	greater lesser argn string ymd todate
+syn keyword sqlFunction	totimestamp date today now utc_now
+syn keyword sqlFunction	number identity years months weeks days
+syn keyword sqlFunction	hours minutes seconds second minute hour
+syn keyword sqlFunction	day month year dow date_format substr
+syn keyword sqlFunction	substring byte_substr length byte_length
+syn keyword sqlFunction	datalength ifnull evaluate list
+syn keyword sqlFunction	soundex similar difference like_start
+syn keyword sqlFunction	like_end regexp_compile
+syn keyword sqlFunction	regexp_compile_patindex remainder abs
+syn keyword sqlFunction	graphical_plan plan explanation ulplan
+syn keyword sqlFunction	graphical_ulplan long_ulplan
+syn keyword sqlFunction	short_ulplan rewrite watcomsql
+syn keyword sqlFunction	transactsql dialect estimate
+syn keyword sqlFunction	estimate_source index_estimate
+syn keyword sqlFunction	experience_estimate traceback wsql_state
+syn keyword sqlFunction	lang_message dateadd datediff datepart
+syn keyword sqlFunction	datename dayname monthname quarter
+syn keyword sqlFunction	tsequal hextoint inttohex rand textptr
+syn keyword sqlFunction	rowid grouping stddev variance rank
+syn keyword sqlFunction	dense_rank density percent_rank user_name
+syn keyword sqlFunction	user_id str stuff char_length nullif
+syn keyword sqlFunction	sortkey compare ts_index_statistics
+syn keyword sqlFunction	ts_table_statistics isdate isnumeric
+syn keyword sqlFunction	get_identity lookup newid uuidtostr
+syn keyword sqlFunction	strtouuid varexists
+
+" 9.0.1 functions
+syn keyword sqlFunction	acos asin atan atn2 cast ceiling convert cos cot 
+syn keyword sqlFunction	char_length coalesce dateformat datetime degrees exp
+syn keyword sqlFunction	floor getdate insertstr 
+syn keyword sqlFunction	log log10 lower mod pi power
+syn keyword sqlFunction	property radians replicate round sign sin 
+syn keyword sqlFunction	sqldialect tan truncate truncnum
+syn keyword sqlFunction	base64_encode base64_decode
+syn keyword sqlFunction	hash compress decompress encrypt decrypt
+
+" string functions
+syn keyword sqlFunction	ascii char left ltrim repeat
+syn keyword sqlFunction	space right rtrim trim lcase ucase
+syn keyword sqlFunction	locate charindex patindex replace
+syn keyword sqlFunction	errormsg csconvert 
+
+" property functions
+syn keyword sqlFunction	db_id db_name property_name
+syn keyword sqlFunction	property_description property_number
+syn keyword sqlFunction	next_connection next_database property
+syn keyword sqlFunction	connection_property db_property db_extended_property
+syn keyword sqlFunction	event_parmeter event_condition event_condition_name
+
+" sa_ procedures
+syn keyword sqlFunction	sa_add_index_consultant_analysis
+syn keyword sqlFunction	sa_add_workload_query
+syn keyword sqlFunction sa_app_deregister
+syn keyword sqlFunction sa_app_get_infoStr
+syn keyword sqlFunction sa_app_get_status
+syn keyword sqlFunction sa_app_register
+syn keyword sqlFunction sa_app_registration_unlock
+syn keyword sqlFunction sa_app_set_infoStr
+syn keyword sqlFunction sa_audit_string
+syn keyword sqlFunction sa_check_commit
+syn keyword sqlFunction sa_checkpoint_execute
+syn keyword sqlFunction sa_conn_activity
+syn keyword sqlFunction sa_conn_compression_info
+syn keyword sqlFunction sa_conn_deregister
+syn keyword sqlFunction sa_conn_info
+syn keyword sqlFunction sa_conn_properties
+syn keyword sqlFunction sa_conn_properties_by_conn
+syn keyword sqlFunction sa_conn_properties_by_name
+syn keyword sqlFunction sa_conn_register
+syn keyword sqlFunction sa_conn_set_status
+syn keyword sqlFunction sa_create_analysis_from_query
+syn keyword sqlFunction sa_db_info
+syn keyword sqlFunction sa_db_properties
+syn keyword sqlFunction sa_disable_auditing_type
+syn keyword sqlFunction sa_disable_index
+syn keyword sqlFunction sa_disk_free_space
+syn keyword sqlFunction sa_enable_auditing_type
+syn keyword sqlFunction sa_enable_index
+syn keyword sqlFunction sa_end_forward_to
+syn keyword sqlFunction sa_eng_properties
+syn keyword sqlFunction sa_event_schedules
+syn keyword sqlFunction sa_exec_script
+syn keyword sqlFunction sa_flush_cache
+syn keyword sqlFunction sa_flush_statistics
+syn keyword sqlFunction sa_forward_to
+syn keyword sqlFunction sa_get_dtt
+syn keyword sqlFunction sa_get_histogram
+syn keyword sqlFunction sa_get_request_profile
+syn keyword sqlFunction sa_get_request_profile_sub
+syn keyword sqlFunction sa_get_request_times
+syn keyword sqlFunction sa_get_server_messages
+syn keyword sqlFunction sa_get_simulated_scale_factors
+syn keyword sqlFunction sa_get_workload_capture_status
+syn keyword sqlFunction sa_index_density
+syn keyword sqlFunction sa_index_levels
+syn keyword sqlFunction sa_index_statistics
+syn keyword sqlFunction sa_internal_alter_index_ability
+syn keyword sqlFunction sa_internal_create_analysis_from_query
+syn keyword sqlFunction sa_internal_disk_free_space
+syn keyword sqlFunction sa_internal_get_dtt
+syn keyword sqlFunction sa_internal_get_histogram
+syn keyword sqlFunction sa_internal_get_request_times
+syn keyword sqlFunction sa_internal_get_simulated_scale_factors
+syn keyword sqlFunction sa_internal_get_workload_capture_status
+syn keyword sqlFunction sa_internal_index_density
+syn keyword sqlFunction sa_internal_index_levels
+syn keyword sqlFunction sa_internal_index_statistics
+syn keyword sqlFunction sa_internal_java_loaded_classes
+syn keyword sqlFunction sa_internal_locks
+syn keyword sqlFunction sa_internal_pause_workload_capture
+syn keyword sqlFunction sa_internal_procedure_profile
+syn keyword sqlFunction sa_internal_procedure_profile_summary
+syn keyword sqlFunction sa_internal_read_backup_history
+syn keyword sqlFunction sa_internal_recommend_indexes
+syn keyword sqlFunction sa_internal_reset_identity
+syn keyword sqlFunction sa_internal_resume_workload_capture
+syn keyword sqlFunction sa_internal_start_workload_capture
+syn keyword sqlFunction sa_internal_stop_index_consultant
+syn keyword sqlFunction sa_internal_stop_workload_capture
+syn keyword sqlFunction sa_internal_table_fragmentation
+syn keyword sqlFunction sa_internal_table_page_usage
+syn keyword sqlFunction sa_internal_table_stats
+syn keyword sqlFunction sa_internal_virtual_sysindex
+syn keyword sqlFunction sa_internal_virtual_sysixcol
+syn keyword sqlFunction sa_java_loaded_classes
+syn keyword sqlFunction sa_jdk_version
+syn keyword sqlFunction sa_locks
+syn keyword sqlFunction sa_make_object
+syn keyword sqlFunction sa_pause_workload_capture
+syn keyword sqlFunction sa_proc_debug_attach_to_connection
+syn keyword sqlFunction sa_proc_debug_connect
+syn keyword sqlFunction sa_proc_debug_detach_from_connection
+syn keyword sqlFunction sa_proc_debug_disconnect
+syn keyword sqlFunction sa_proc_debug_get_connection_name
+syn keyword sqlFunction sa_proc_debug_release_connection
+syn keyword sqlFunction sa_proc_debug_request
+syn keyword sqlFunction sa_proc_debug_version
+syn keyword sqlFunction sa_proc_debug_wait_for_connection
+syn keyword sqlFunction sa_procedure_profile
+syn keyword sqlFunction sa_procedure_profile_summary
+syn keyword sqlFunction sa_read_backup_history
+syn keyword sqlFunction sa_recommend_indexes
+syn keyword sqlFunction sa_recompile_views
+syn keyword sqlFunction sa_remove_index_consultant_analysis
+syn keyword sqlFunction sa_remove_index_consultant_workload
+syn keyword sqlFunction sa_reset_identity
+syn keyword sqlFunction sa_resume_workload_capture
+syn keyword sqlFunction sa_server_option
+syn keyword sqlFunction sa_set_simulated_scale_factor
+syn keyword sqlFunction sa_setremoteuser
+syn keyword sqlFunction sa_setsubscription
+syn keyword sqlFunction sa_start_recording_commits
+syn keyword sqlFunction sa_start_workload_capture
+syn keyword sqlFunction sa_statement_text
+syn keyword sqlFunction sa_stop_index_consultant
+syn keyword sqlFunction sa_stop_recording_commits
+syn keyword sqlFunction sa_stop_workload_capture
+syn keyword sqlFunction sa_sync
+syn keyword sqlFunction sa_sync_sub
+syn keyword sqlFunction sa_table_fragmentation
+syn keyword sqlFunction sa_table_page_usage
+syn keyword sqlFunction sa_table_stats
+syn keyword sqlFunction sa_update_index_consultant_workload
+syn keyword sqlFunction sa_validate
+syn keyword sqlFunction sa_virtual_sysindex
+syn keyword sqlFunction sa_virtual_sysixcol
+
+" sp_ procedures
+syn keyword sqlFunction sp_addalias
+syn keyword sqlFunction sp_addauditrecord
+syn keyword sqlFunction sp_adddumpdevice
+syn keyword sqlFunction sp_addgroup
+syn keyword sqlFunction sp_addlanguage
+syn keyword sqlFunction sp_addlogin
+syn keyword sqlFunction sp_addmessage
+syn keyword sqlFunction sp_addremotelogin
+syn keyword sqlFunction sp_addsegment
+syn keyword sqlFunction sp_addserver
+syn keyword sqlFunction sp_addthreshold
+syn keyword sqlFunction sp_addtype
+syn keyword sqlFunction sp_adduser
+syn keyword sqlFunction sp_auditdatabase
+syn keyword sqlFunction sp_auditlogin
+syn keyword sqlFunction sp_auditobject
+syn keyword sqlFunction sp_auditoption
+syn keyword sqlFunction sp_auditsproc
+syn keyword sqlFunction sp_bindefault
+syn keyword sqlFunction sp_bindmsg
+syn keyword sqlFunction sp_bindrule
+syn keyword sqlFunction sp_changedbowner
+syn keyword sqlFunction sp_changegroup
+syn keyword sqlFunction sp_checknames
+syn keyword sqlFunction sp_checkperms
+syn keyword sqlFunction sp_checkreswords
+syn keyword sqlFunction sp_clearstats
+syn keyword sqlFunction sp_column_privileges
+syn keyword sqlFunction sp_columns
+syn keyword sqlFunction sp_commonkey
+syn keyword sqlFunction sp_configure
+syn keyword sqlFunction sp_cursorinfo
+syn keyword sqlFunction sp_databases
+syn keyword sqlFunction sp_datatype_info
+syn keyword sqlFunction sp_dboption
+syn keyword sqlFunction sp_dbremap
+syn keyword sqlFunction sp_depends
+syn keyword sqlFunction sp_diskdefault
+syn keyword sqlFunction sp_displaylogin
+syn keyword sqlFunction sp_dropalias
+syn keyword sqlFunction sp_dropdevice
+syn keyword sqlFunction sp_dropgroup
+syn keyword sqlFunction sp_dropkey
+syn keyword sqlFunction sp_droplanguage
+syn keyword sqlFunction sp_droplogin
+syn keyword sqlFunction sp_dropmessage
+syn keyword sqlFunction sp_dropremotelogin
+syn keyword sqlFunction sp_dropsegment
+syn keyword sqlFunction sp_dropserver
+syn keyword sqlFunction sp_dropthreshold
+syn keyword sqlFunction sp_droptype
+syn keyword sqlFunction sp_dropuser
+syn keyword sqlFunction sp_estspace
+syn keyword sqlFunction sp_extendsegment
+syn keyword sqlFunction sp_fkeys
+syn keyword sqlFunction sp_foreignkey
+syn keyword sqlFunction sp_getmessage
+syn keyword sqlFunction sp_help
+syn keyword sqlFunction sp_helpconstraint
+syn keyword sqlFunction sp_helpdb
+syn keyword sqlFunction sp_helpdevice
+syn keyword sqlFunction sp_helpgroup
+syn keyword sqlFunction sp_helpindex
+syn keyword sqlFunction sp_helpjoins
+syn keyword sqlFunction sp_helpkey
+syn keyword sqlFunction sp_helplanguage
+syn keyword sqlFunction sp_helplog
+syn keyword sqlFunction sp_helpprotect
+syn keyword sqlFunction sp_helpremotelogin
+syn keyword sqlFunction sp_helpsegment
+syn keyword sqlFunction sp_helpserver
+syn keyword sqlFunction sp_helpsort
+syn keyword sqlFunction sp_helptext
+syn keyword sqlFunction sp_helpthreshold
+syn keyword sqlFunction sp_helpuser
+syn keyword sqlFunction sp_indsuspect
+syn keyword sqlFunction sp_lock
+syn keyword sqlFunction sp_locklogin
+syn keyword sqlFunction sp_logdevice
+syn keyword sqlFunction sp_login_environment
+syn keyword sqlFunction sp_modifylogin
+syn keyword sqlFunction sp_modifythreshold
+syn keyword sqlFunction sp_monitor
+syn keyword sqlFunction sp_password
+syn keyword sqlFunction sp_pkeys
+syn keyword sqlFunction sp_placeobject
+syn keyword sqlFunction sp_primarykey
+syn keyword sqlFunction sp_procxmode
+syn keyword sqlFunction sp_recompile
+syn keyword sqlFunction sp_remap
+syn keyword sqlFunction sp_remote_columns
+syn keyword sqlFunction sp_remote_exported_keys
+syn keyword sqlFunction sp_remote_imported_keys
+syn keyword sqlFunction sp_remote_pcols
+syn keyword sqlFunction sp_remote_primary_keys
+syn keyword sqlFunction sp_remote_procedures
+syn keyword sqlFunction sp_remote_tables
+syn keyword sqlFunction sp_remoteoption
+syn keyword sqlFunction sp_rename
+syn keyword sqlFunction sp_renamedb
+syn keyword sqlFunction sp_reportstats
+syn keyword sqlFunction sp_reset_tsql_environment
+syn keyword sqlFunction sp_role
+syn keyword sqlFunction sp_server_info
+syn keyword sqlFunction sp_servercaps
+syn keyword sqlFunction sp_serverinfo
+syn keyword sqlFunction sp_serveroption
+syn keyword sqlFunction sp_setlangalias
+syn keyword sqlFunction sp_setreplicate
+syn keyword sqlFunction sp_setrepproc
+syn keyword sqlFunction sp_setreptable
+syn keyword sqlFunction sp_spaceused
+syn keyword sqlFunction sp_special_columns
+syn keyword sqlFunction sp_sproc_columns
+syn keyword sqlFunction sp_statistics
+syn keyword sqlFunction sp_stored_procedures
+syn keyword sqlFunction sp_syntax
+syn keyword sqlFunction sp_table_privileges
+syn keyword sqlFunction sp_tables
+syn keyword sqlFunction sp_tsql_environment
+syn keyword sqlFunction sp_tsql_feature_not_supported
+syn keyword sqlFunction sp_unbindefault
+syn keyword sqlFunction sp_unbindmsg
+syn keyword sqlFunction sp_unbindrule
+syn keyword sqlFunction sp_volchanged
+syn keyword sqlFunction sp_who
+syn keyword sqlFunction xp_scanf
+syn keyword sqlFunction xp_sprintf
+
+" server functions
+syn keyword sqlFunction col_length
+syn keyword sqlFunction col_name
+syn keyword sqlFunction index_col
+syn keyword sqlFunction object_id
+syn keyword sqlFunction object_name
+syn keyword sqlFunction proc_role
+syn keyword sqlFunction show_role
+syn keyword sqlFunction xp_cmdshell
+syn keyword sqlFunction xp_msver
+syn keyword sqlFunction xp_read_file
+syn keyword sqlFunction xp_real_cmdshell
+syn keyword sqlFunction xp_real_read_file
+syn keyword sqlFunction xp_real_sendmail
+syn keyword sqlFunction xp_real_startmail
+syn keyword sqlFunction xp_real_startsmtp
+syn keyword sqlFunction xp_real_stopmail
+syn keyword sqlFunction xp_real_stopsmtp
+syn keyword sqlFunction xp_real_write_file
+syn keyword sqlFunction xp_scanf
+syn keyword sqlFunction xp_sendmail
+syn keyword sqlFunction xp_sprintf
+syn keyword sqlFunction xp_startmail
+syn keyword sqlFunction xp_startsmtp
+syn keyword sqlFunction xp_stopmail
+syn keyword sqlFunction xp_stopsmtp
+syn keyword sqlFunction xp_write_file
+
+" http functions
+syn keyword sqlFunction	http_header http_variable
+syn keyword sqlFunction	next_http_header next_http_variable
+syn keyword sqlFunction	sa_set_http_header sa_set_http_option
+syn keyword sqlFunction	sa_http_variable_info sa_http_header_info
+
+" http functions 9.0.1 
+syn keyword sqlFunction	http_encode http_decode
+syn keyword sqlFunction	html_encode html_decode
+
+" keywords
+syn keyword sqlKeyword	absolute action activ add address after
+syn keyword sqlKeyword	algorithm allow_dup_row
+syn keyword sqlKeyword	alter and any as asc ascii ase at atomic
+syn keyword sqlKeyword	attended audit authorization 
+syn keyword sqlKeyword	autoincrement autostop bcp before
+syn keyword sqlKeyword	between blank
+syn keyword sqlKeyword	blanks block bottom unbounded break bufferpool
+syn keyword sqlKeyword	bulk by byte cache calibrate calibration
+syn keyword sqlKeyword	capability cascade cast
+syn keyword sqlKeyword	catalog changes char char_convert check
+syn keyword sqlKeyword	class classes client 
+syn keyword sqlKeyword	cluster clustered collation column
+syn keyword sqlKeyword	command comment comparisons
+syn keyword sqlKeyword	compatible component compressed compute
+syn keyword sqlKeyword	concat confirm connection
+syn keyword sqlKeyword	console consolidate consolidated
+syn keyword sqlKeyword	constraint constraints continue
+syn keyword sqlKeyword	convert count crc cross cube
+syn keyword sqlKeyword	current cursor data data database
+syn keyword sqlKeyword	current_timestamp current_user
+syn keyword sqlKeyword	datatype dba dbfile
+syn keyword sqlKeyword	dbspace debug
+syn keyword sqlKeyword	decrypted default defaults definition
+syn keyword sqlKeyword	delay deleting delimited desc
+syn keyword sqlKeyword	description deterministic directory
+syn keyword sqlKeyword	disable distinct do domain 
+syn keyword sqlKeyword	dsetpass dttm dynamic each editproc ejb
+syn keyword sqlKeyword	else elseif enable encrypted end endif
+syn keyword sqlKeyword	engine erase error escape escapes event
+syn keyword sqlKeyword	every exception exclusive exec 
+syn keyword sqlKeyword	existing exists expanded express
+syn keyword sqlKeyword	external externlogin factor false
+syn keyword sqlKeyword	fastfirstrow fieldproc file filler
+syn keyword sqlKeyword	fillfactor finish first first_keyword 
+syn keyword sqlKeyword	following force foreign format 
+syn keyword sqlKeyword	freepage full function go global
+syn keyword sqlKeyword	group handler hash having hexadecimal 
+syn keyword sqlKeyword	hidden high hng hold holdlock
+syn keyword sqlKeyword	hours id identified identity ignore
+syn keyword sqlKeyword	ignore_dup_key ignore_dup_row immediate
+syn keyword sqlKeyword	in inactive incremental index info inner
+syn keyword sqlKeyword	inout insensitive inserting
+syn keyword sqlKeyword	instead integrated
+syn keyword sqlKeyword	internal into iq is isolation jar java
+syn keyword sqlKeyword	jconnect jdk join kb key language last
+syn keyword sqlKeyword	last_keyword lateral left level like
+syn keyword sqlKeyword	limit local location log
+syn keyword sqlKeyword	logging login long low main
+syn keyword sqlKeyword	match max maximum membership 
+syn keyword sqlKeyword	minutes mirror mode modify monitor 
+syn keyword sqlKeyword	name named native natural new next no
+syn keyword sqlKeyword	noholdlock nolock nonclustered none not
+syn keyword sqlKeyword	notify null nulls of off old on
+syn keyword sqlKeyword	only optimization optimizer option
+syn keyword sqlKeyword	or order others out outer over
+syn keyword sqlKeyword	package packetsize padding page pages
+syn keyword sqlKeyword	paglock parallel part partition path
+syn keyword sqlKeyword	pctfree plan preceding precision prefetch prefix
+syn keyword sqlKeyword	preserve preview primary 
+syn keyword sqlKeyword	prior priqty private privileges
+syn keyword sqlKeyword	procedure public publication publish publisher
+syn keyword sqlKeyword	quotes range readcommitted
+syn keyword sqlKeyword	readpast readuncommitted 
+syn keyword sqlKeyword	received recompile recursive references
+syn keyword sqlKeyword	referencing relative 
+syn keyword sqlKeyword	rename repeatableread
+syn keyword sqlKeyword	replicate rereceive resend reset
+syn keyword sqlKeyword	resolve resource respect
+syn keyword sqlKeyword	restrict result retain
+syn keyword sqlKeyword	returns right 
+syn keyword sqlKeyword	rollup row rowlock rows save 
+syn keyword sqlKeyword	schedule schema scroll seconds secqty
+syn keyword sqlKeyword	send sensitive sent serializable
+syn keyword sqlKeyword	server server session sets 
+syn keyword sqlKeyword	share since site size skip
+syn keyword sqlKeyword	some sorted_data sqlcode sqlid
+syn keyword sqlKeyword	sqlstate stacker statement
+syn keyword sqlKeyword	statistics status stogroup store
+syn keyword sqlKeyword	strip subpages subscribe subscription
+syn keyword sqlKeyword	subtransaction synchronization
+syn keyword sqlKeyword	syntax_error table tablock
+syn keyword sqlKeyword	tablockx tb temp template temporary then
+syn keyword sqlKeyword	timezone to top
+syn keyword sqlKeyword	transaction transactional tries true 
+syn keyword sqlKeyword	tsequal type unconditionally unenforced
+syn keyword sqlKeyword	unique union unknown unload 
+syn keyword sqlKeyword	updating updlock upgrade use user
+syn keyword sqlKeyword	using utc utilities validproc
+syn keyword sqlKeyword	value values varchar variable
+syn keyword sqlKeyword	varying vcat verify view virtual wait 
+syn keyword sqlKeyword	warning wd when where window with within
+syn keyword sqlKeyword	with_lparen work writefile 
+syn keyword sqlKeyword	xlock zeros
+" XML function support
+syn keyword sqlFunction	openxml xmlelement xmlforest xmlgen xmlconcat xmlagg 
+syn keyword sqlFunction	xmlattributes 
+syn keyword sqlKeyword	raw auto elements explicit
+" HTTP support
+syn keyword sqlKeyword	authorization secure url service
+" HTTP 9.0.2 new procedure keywords
+syn keyword sqlKeyword	namespace certificate clientport proxy
+" OLAP support 9.0.0
+syn keyword sqlKeyword	covar_pop covar_samp corr regr_slope regr_intercept 
+syn keyword sqlKeyword	regr_count regr_r2 regr_avgx regr_avgy
+syn keyword sqlKeyword	regr_sxx regr_syy regr_sxy
+
+" Alternate keywords
+syn keyword sqlKeyword	character dec options proc reference
+syn keyword sqlKeyword	subtrans tran syn keyword 
+
+
+syn keyword sqlOperator	in any some all between exists
+syn keyword sqlOperator	like escape not is and or 
+syn keyword sqlOperator intersect minus
+syn keyword sqlOperator prior distinct
+
+syn keyword sqlStatement allocate alter backup begin call case
+syn keyword sqlStatement checkpoint clear close commit configure connect
+syn keyword sqlStatement create deallocate declare delete describe
+syn keyword sqlStatement disconnect drop execute exit explain fetch
+syn keyword sqlStatement for forward from get goto grant help if include
+syn keyword sqlStatement input insert install leave load lock loop
+syn keyword sqlStatement message open output parameter parameters passthrough
+syn keyword sqlStatement prepare print put raiserror read readtext release
+syn keyword sqlStatement remote remove reorganize resignal restore resume
+syn keyword sqlStatement return revoke rollback savepoint select
+syn keyword sqlStatement set setuser signal start stop synchronize
+syn keyword sqlStatement system trigger truncate unload update
+syn keyword sqlStatement validate waitfor whenever while writetext
+
+
+syn keyword sqlType	char long varchar text
+syn keyword sqlType	bigint decimal double float int integer numeric 
+syn keyword sqlType	smallint tinyint real
+syn keyword sqlType	money smallmoney
+syn keyword sqlType	bit 
+syn keyword sqlType	date datetime smalldate time timestamp 
+syn keyword sqlType	binary image varbinary uniqueidentifier
+syn keyword sqlType	xml unsigned
+
+syn keyword sqlOption Allow_nulls_by_default
+syn keyword sqlOption Ansi_blanks
+syn keyword sqlOption Ansi_close_cursors_on_rollback
+syn keyword sqlOption Ansi_integer_overflow
+syn keyword sqlOption Ansi_permissions
+syn keyword sqlOption Ansi_update_constraints
+syn keyword sqlOption Ansinull
+syn keyword sqlOption Assume_distinct_servers
+syn keyword sqlOption Auditing
+syn keyword sqlOption Auditing_options
+syn keyword sqlOption Auto_commit
+syn keyword sqlOption Auto_refetch
+syn keyword sqlOption Automatic_timestamp
+syn keyword sqlOption Background_priority
+syn keyword sqlOption Bell
+syn keyword sqlOption Blob_threshold
+syn keyword sqlOption Blocking
+syn keyword sqlOption Blocking_timeout
+syn keyword sqlOption Chained
+syn keyword sqlOption Char_OEM_Translation
+syn keyword sqlOption Checkpoint_time
+syn keyword sqlOption Cis_option
+syn keyword sqlOption Cis_rowset_size
+syn keyword sqlOption Close_on_endtrans
+syn keyword sqlOption Command_delimiter
+syn keyword sqlOption Commit_on_exit
+syn keyword sqlOption Compression
+syn keyword sqlOption Connection_authentication
+syn keyword sqlOption Continue_after_raiserror
+syn keyword sqlOption Conversion_error
+syn keyword sqlOption Cooperative_commit_timeout
+syn keyword sqlOption Cooperative_commits
+syn keyword sqlOption Database_authentication
+syn keyword sqlOption Date_format
+syn keyword sqlOption Date_order
+syn keyword sqlOption Debug_messages
+syn keyword sqlOption Dedicated_task
+syn keyword sqlOption Default_timestamp_increment
+syn keyword sqlOption Delayed_commit_timeout
+syn keyword sqlOption Delayed_commits
+syn keyword sqlOption Delete_old_logs
+syn keyword sqlOption Describe_Java_Format
+syn keyword sqlOption Divide_by_zero_error
+syn keyword sqlOption Echo
+syn keyword sqlOption Escape_character
+syn keyword sqlOption Exclude_operators
+syn keyword sqlOption Extended_join_syntax
+syn keyword sqlOption External_remote_options
+syn keyword sqlOption Fire_triggers
+syn keyword sqlOption First_day_of_week
+syn keyword sqlOption Float_as_double
+syn keyword sqlOption For_xml_null_treatment
+syn keyword sqlOption Force_view_creation
+syn keyword sqlOption Global_database_id
+syn keyword sqlOption Headings
+syn keyword sqlOption Input_format
+syn keyword sqlOption Integrated_server_name
+syn keyword sqlOption Isolation_level
+syn keyword sqlOption ISQL_command_timing
+syn keyword sqlOption ISQL_escape_character
+syn keyword sqlOption ISQL_field_separator
+syn keyword sqlOption ISQL_log
+syn keyword sqlOption ISQL_plan
+syn keyword sqlOption ISQL_plan_cursor_sensitivity
+syn keyword sqlOption ISQL_plan_cursor_writability
+syn keyword sqlOption ISQL_quote
+syn keyword sqlOption Java_heap_size
+syn keyword sqlOption Java_input_output
+syn keyword sqlOption Java_namespace_size
+syn keyword sqlOption Java_page_buffer_size
+syn keyword sqlOption Lock_rejected_rows
+syn keyword sqlOption Log_deadlocks
+syn keyword sqlOption Log_detailed_plans
+syn keyword sqlOption Log_max_requests
+syn keyword sqlOption Login_mode
+syn keyword sqlOption Login_procedure
+syn keyword sqlOption Max_cursor_count
+syn keyword sqlOption Max_hash_size
+syn keyword sqlOption Max_plans_cached
+syn keyword sqlOption Max_recursive_iterations
+syn keyword sqlOption Max_statement_count
+syn keyword sqlOption Max_work_table_hash_size
+syn keyword sqlOption Min_password_length
+syn keyword sqlOption Nearest_century
+syn keyword sqlOption Non_keywords
+syn keyword sqlOption NULLS
+syn keyword sqlOption ODBC_describe_binary_as_varbinary
+syn keyword sqlOption ODBC_distinguish_char_and_varchar
+syn keyword sqlOption On_Charset_conversion_failure
+syn keyword sqlOption On_error
+syn keyword sqlOption On_tsql_error
+syn keyword sqlOption Optimistic_wait_for_commit
+syn keyword sqlOption Optimization_goal
+syn keyword sqlOption Optimization_level
+syn keyword sqlOption Optimization_logging
+syn keyword sqlOption Optimization_workload
+syn keyword sqlOption Output_format
+syn keyword sqlOption Output_length
+syn keyword sqlOption Output_nulls
+syn keyword sqlOption Percent_as_comment
+syn keyword sqlOption Pinned_cursor_percent_of_cache
+syn keyword sqlOption Precision
+syn keyword sqlOption Prefetch
+syn keyword sqlOption Preserve_source_format
+syn keyword sqlOption Prevent_article_pkey_update
+syn keyword sqlOption Qualify_owners
+syn keyword sqlOption Query_plan_on_open
+syn keyword sqlOption Quiet
+syn keyword sqlOption Quote_all_identifiers
+syn keyword sqlOption Quoted_identifier
+syn keyword sqlOption Read_past_deleted
+syn keyword sqlOption Recovery_time
+syn keyword sqlOption Remote_idle_timeout
+syn keyword sqlOption Replicate_all
+syn keyword sqlOption Replication_error
+syn keyword sqlOption Replication_error_piece
+syn keyword sqlOption Return_date_time_as_string
+syn keyword sqlOption Return_java_as_string
+syn keyword sqlOption RI_Trigger_time
+syn keyword sqlOption Rollback_on_deadlock
+syn keyword sqlOption Row_counts
+syn keyword sqlOption Save_remote_passwords
+syn keyword sqlOption Scale
+syn keyword sqlOption Screen_format
+syn keyword sqlOption Sort_Collation
+syn keyword sqlOption SQL_flagger_error_level
+syn keyword sqlOption SQL_flagger_warning_level
+syn keyword sqlOption SQLConnect
+syn keyword sqlOption SQLStart
+syn keyword sqlOption SR_Date_Format
+syn keyword sqlOption SR_Time_Format
+syn keyword sqlOption SR_TimeStamp_Format
+syn keyword sqlOption Statistics
+syn keyword sqlOption String_rtruncation
+syn keyword sqlOption Subscribe_by_remote
+syn keyword sqlOption Subsume_row_locks
+syn keyword sqlOption Suppress_TDS_debugging
+syn keyword sqlOption TDS_Empty_string_is_null
+syn keyword sqlOption Temp_space_limit_check
+syn keyword sqlOption Thread_count
+syn keyword sqlOption Thread_stack
+syn keyword sqlOption Thread_swaps
+syn keyword sqlOption Time_format
+syn keyword sqlOption Time_zone_adjustment
+syn keyword sqlOption Timestamp_format
+syn keyword sqlOption Truncate_date_values
+syn keyword sqlOption Truncate_timestamp_values
+syn keyword sqlOption Truncate_with_auto_commit
+syn keyword sqlOption Truncation_length
+syn keyword sqlOption Tsql_hex_constant
+syn keyword sqlOption Tsql_variables
+syn keyword sqlOption Update_statistics
+syn keyword sqlOption User_estimates
+syn keyword sqlOption Verify_all_columns
+syn keyword sqlOption Verify_threshold
+syn keyword sqlOption Wait_for_commit
+
+" Strings and characters:
+syn region sqlString		start=+"+    end=+"+ contains=@Spell
+syn region sqlString		start=+'+    end=+'+ contains=@Spell
+
+" Numbers:
+syn match sqlNumber		"-\=\<\d*\.\=[0-9_]\>"
+
+" Comments:
+syn region sqlDashComment	start=/--/ end=/$/ contains=@Spell
+syn region sqlSlashComment	start=/\/\// end=/$/ contains=@Spell
+syn region sqlMultiComment	start="/\*" end="\*/" contains=sqlMultiComment,@Spell
+syn cluster sqlComment	contains=sqlDashComment,sqlSlashComment,sqlMultiComment,@Spell
+syn sync ccomment sqlComment
+syn sync ccomment sqlDashComment
+syn sync ccomment sqlSlashComment
+
+" Define the default highlighting.
+" For version 5.7 and earlier: only when not done already
+" For version 5.8 and later: only when an item doesn't have highlighting yet
+if version >= 508 || !exists("did_sql_syn_inits")
+    if version < 508
+        let did_sql_syn_inits = 1
+        command -nargs=+ HiLink hi link <args>
+    else
+        command -nargs=+ HiLink hi link <args>
+    endif
+
+    HiLink sqlDashComment	Comment
+    HiLink sqlSlashComment	Comment
+    HiLink sqlMultiComment	Comment
+    HiLink sqlNumber	        Number
+    HiLink sqlOperator	        Operator
+    HiLink sqlSpecial	        Special
+    HiLink sqlKeyword	        Keyword
+    HiLink sqlStatement	        Statement
+    HiLink sqlString	        String
+    HiLink sqlType	        Type
+    HiLink sqlFunction	        Function
+    HiLink sqlOption	        PreProc
+
+    delcommand HiLink
+endif
+
+let b:current_syntax = "sqlanywhere"
+
+" vim:sw=4:ff=unix:
--- /dev/null
+++ b/lib/vimfiles/syntax/sqlforms.vim
@@ -1,0 +1,168 @@
+" Vim syntax file
+"    Language: SQL*Forms (Oracle 7), based on sql.vim (vim5.0)
+"  Maintainer: Austin Ziegler (austin@halostatue.ca)
+" Last Change: 2003 May 11
+" Prev Change: 19980710
+"	  URL: http://www.halostatue.ca/vim/syntax/proc.vim
+"
+" TODO Find a new maintainer who knows SQL*Forms.
+
+    " For version 5.x, clear all syntax items.
+    " For version 6.x, quit when a syntax file was already loaded.
+if version < 600
+    syntax clear
+elseif exists("b:current_syntax")
+    finish
+endif
+
+syntax case ignore
+
+if version >= 600
+  setlocal iskeyword=a-z,A-Z,48-57,_,.,-,>
+else
+  set iskeyword=a-z,A-Z,48-57,_,.,-,>
+endif
+
+
+    " The SQL reserved words, defined as keywords.
+syntax match sqlTriggers /on-.*$/
+syntax match sqlTriggers /key-.*$/
+syntax match sqlTriggers /post-.*$/
+syntax match sqlTriggers /pre-.*$/
+syntax match sqlTriggers /user-.*$/
+
+syntax keyword sqlSpecial null false true
+
+syntax keyword sqlProcedure abort_query anchor_view bell block_menu break call
+syntax keyword sqlProcedure call_input call_query clear_block clear_eol
+syntax keyword sqlProcedure clear_field clear_form clear_record commit_form
+syntax keyword sqlProcedure copy count_query create_record default_value
+syntax keyword sqlProcedure delete_record display_error display_field down
+syntax keyword sqlProcedure duplicate_field duplicate_record edit_field
+syntax keyword sqlProcedure enter enter_query erase execute_query
+syntax keyword sqlProcedure execute_trigger exit_form first_Record go_block
+syntax keyword sqlProcedure go_field go_record help hide_menu hide_page host
+syntax keyword sqlProcedure last_record list_values lock_record message
+syntax keyword sqlProcedure move_view new_form next_block next_field next_key
+syntax keyword sqlProcedure next_record next_set pause post previous_block
+syntax keyword sqlProcedure previous_field previous_record print redisplay
+syntax keyword sqlProcedure replace_menu resize_view scroll_down scroll_up
+syntax keyword sqlProcedure set_field show_keys show_menu show_page
+syntax keyword sqlProcedure synchronize up user_exit
+
+syntax keyword sqlFunction block_characteristic error_code error_text
+syntax keyword sqlFunction error_type field_characteristic form_failure
+syntax keyword sqlFunction form_fatal form_success name_in
+
+syntax keyword sqlParameters hide no_hide replace no_replace ask_commit
+syntax keyword sqlParameters do_commit no_commit no_validate all_records
+syntax keyword sqlParameters for_update no_restrict restrict no_screen
+syntax keyword sqlParameters bar full_screen pull_down auto_help auto_skip
+syntax keyword sqlParameters fixed_length enterable required echo queryable
+syntax keyword sqlParameters updateable update_null upper_case attr_on
+syntax keyword sqlParameters attr_off base_table first_field last_field
+syntax keyword sqlParameters datatype displayed display_length field_length
+syntax keyword sqlParameters list page primary_key query_length x_pos y_pos
+
+syntax match sqlSystem /system\.block_status/
+syntax match sqlSystem /system\.current_block/
+syntax match sqlSystem /system\.current_field/
+syntax match sqlSystem /system\.current_form/
+syntax match sqlSystem /system\.current_value/
+syntax match sqlSystem /system\.cursor_block/
+syntax match sqlSystem /system\.cursor_field/
+syntax match sqlSystem /system\.cursor_record/
+syntax match sqlSystem /system\.cursor_value/
+syntax match sqlSystem /system\.form_status/
+syntax match sqlSystem /system\.last_query/
+syntax match sqlSystem /system\.last_record/
+syntax match sqlSystem /system\.message_level/
+syntax match sqlSystem /system\.record_status/
+syntax match sqlSystem /system\.trigger_block/
+syntax match sqlSystem /system\.trigger_field/
+syntax match sqlSystem /system\.trigger_record/
+syntax match sqlSystem /\$\$date\$\$/
+syntax match sqlSystem /\$\$time\$\$/
+
+syntax keyword sqlKeyword accept access add as asc by check cluster column
+syntax keyword sqlKeyword compress connect current decimal default
+syntax keyword sqlKeyword desc exclusive file for from group
+syntax keyword sqlKeyword having identified immediate increment index
+syntax keyword sqlKeyword initial into is level maxextents mode modify
+syntax keyword sqlKeyword nocompress nowait of offline on online start
+syntax keyword sqlKeyword successful synonym table to trigger uid
+syntax keyword sqlKeyword unique user validate values view whenever
+syntax keyword sqlKeyword where with option order pctfree privileges
+syntax keyword sqlKeyword public resource row rowlabel rownum rows
+syntax keyword sqlKeyword session share size smallint sql\*forms_version
+syntax keyword sqlKeyword terse define form name title procedure begin
+syntax keyword sqlKeyword default_menu_application trigger block field
+syntax keyword sqlKeyword enddefine declare exception raise when cursor
+syntax keyword sqlKeyword definition base_table pragma
+syntax keyword sqlKeyword column_name global trigger_type text description
+syntax match sqlKeyword "<<<"
+syntax match sqlKeyword ">>>"
+
+syntax keyword sqlOperator not and or out to_number to_date message erase
+syntax keyword sqlOperator in any some all between exists substr nvl
+syntax keyword sqlOperator exception_init
+syntax keyword sqlOperator like escape trunc lpad rpad sum
+syntax keyword sqlOperator union intersect minus to_char greatest
+syntax keyword sqlOperator prior distinct decode least avg
+syntax keyword sqlOperator sysdate true false field_characteristic
+syntax keyword sqlOperator display_field call host
+
+syntax keyword sqlStatement alter analyze audit comment commit create
+syntax keyword sqlStatement delete drop explain grant insert lock noaudit
+syntax keyword sqlStatement rename revoke rollback savepoint select set
+syntax keyword sqlStatement truncate update if elsif loop then
+syntax keyword sqlStatement open fetch close else end
+
+syntax keyword sqlType char character date long raw mlslabel number rowid
+syntax keyword sqlType varchar varchar2 float integer boolean global
+
+syntax keyword sqlCodes sqlcode no_data_found too_many_rows others
+syntax keyword sqlCodes form_trigger_failure notfound found
+syntax keyword sqlCodes validate no_commit
+
+    " Comments:
+syntax region sqlComment    start="/\*"  end="\*/"
+syntax match sqlComment  "--.*"
+
+    " Strings and characters:
+syntax region sqlString  start=+"+  skip=+\\\\\|\\"+  end=+"+
+syntax region sqlString  start=+'+  skip=+\\\\\|\\"+  end=+'+
+
+    " Numbers:
+syntax match sqlNumber  "-\=\<[0-9]*\.\=[0-9_]\>"
+
+syntax sync ccomment sqlComment
+
+if version >= 508 || !exists("did_sqlforms_syn_inits")
+    if version < 508
+	let did_sqlforms_syn_inits = 1
+	command -nargs=+ HiLink hi link <args>
+    else
+	command -nargs=+ HiLink hi def link <args>
+    endif
+
+    HiLink sqlComment Comment
+    HiLink sqlKeyword Statement
+    HiLink sqlNumber Number
+    HiLink sqlOperator Statement
+    HiLink sqlProcedure Statement
+    HiLink sqlFunction Statement
+    HiLink sqlSystem Identifier
+    HiLink sqlSpecial Special
+    HiLink sqlStatement Statement
+    HiLink sqlString String
+    HiLink sqlType Type
+    HiLink sqlCodes Identifier
+    HiLink sqlTriggers PreProc
+
+    delcommand HiLink
+endif
+
+let b:current_syntax = "sqlforms"
+
+" vim: ts=8 sw=4
--- /dev/null
+++ b/lib/vimfiles/syntax/sqlinformix.vim
@@ -1,0 +1,196 @@
+" Vim syntax file
+" Informix Structured Query Language (SQL) and Stored Procedure Language (SPL)
+" Language:	SQL, SPL (Informix Dynamic Server 2000 v9.2)
+" Maintainer:	Dean Hill <dhill@hotmail.com>
+" Last Change:	2004 Aug 30
+
+" For version 5.x: Clear all syntax items
+" For version 6.x: Quit when a syntax file was already loaded
+if version < 600
+  syntax clear
+elseif exists("b:current_syntax")
+  finish
+endif
+
+syn case ignore
+
+
+
+" === Comment syntax group ===
+syn region sqlComment    start="{"  end="}" contains=sqlTodo
+syn match sqlComment	"--.*$" contains=sqlTodo
+syn sync ccomment sqlComment
+
+
+
+" === Constant syntax group ===
+" = Boolean subgroup =
+syn keyword sqlBoolean  true false
+syn keyword sqlBoolean  null
+syn keyword sqlBoolean  public user
+syn keyword sqlBoolean  current today
+syn keyword sqlBoolean  year month day hour minute second fraction
+
+" = String subgroup =
+syn region sqlString		start=+"+  end=+"+
+syn region sqlString		start=+'+  end=+'+
+
+" = Numbers subgroup =
+syn match sqlNumber		"-\=\<\d*\.\=[0-9_]\>"
+
+
+
+" === Statement syntax group ===
+" SQL
+syn keyword sqlStatement allocate alter
+syn keyword sqlStatement begin
+syn keyword sqlStatement close commit connect create
+syn keyword sqlStatement database deallocate declare delete describe disconnect drop
+syn keyword sqlStatement execute fetch flush free get grant info insert
+syn keyword sqlStatement load lock open output
+syn keyword sqlStatement prepare put
+syn keyword sqlStatement rename revoke rollback select set start stop
+syn keyword sqlStatement truncate unload unlock update
+syn keyword sqlStatement whenever
+" SPL
+syn keyword sqlStatement call continue define
+syn keyword sqlStatement exit
+syn keyword sqlStatement let
+syn keyword sqlStatement return system trace
+
+" = Conditional subgroup =
+" SPL
+syn keyword sqlConditional elif else if then
+syn keyword sqlConditional case
+" Highlight "end if" with one or more separating spaces
+syn match  sqlConditional "end \+if"
+
+" = Repeat subgroup =
+" SQL/SPL
+" Handle SQL triggers' "for each row" clause and SPL "for" loop
+syn match  sqlRepeat "for\( \+each \+row\)\="
+" SPL
+syn keyword sqlRepeat foreach while
+" Highlight "end for", etc. with one or more separating spaces
+syn match  sqlRepeat "end \+for"
+syn match  sqlRepeat "end \+foreach"
+syn match  sqlRepeat "end \+while"
+
+" = Exception subgroup =
+" SPL
+syn match  sqlException "on \+exception"
+syn match  sqlException "end \+exception"
+syn match  sqlException "end \+exception \+with \+resume"
+syn match  sqlException "raise \+exception"
+
+" = Keyword subgroup =
+" SQL
+syn keyword sqlKeyword aggregate add as authorization autofree by
+syn keyword sqlKeyword cache cascade check cluster collation
+syn keyword sqlKeyword column connection constraint cross
+syn keyword sqlKeyword dataskip debug default deferred_prepare
+syn keyword sqlKeyword descriptor diagnostics
+syn keyword sqlKeyword each escape explain external
+syn keyword sqlKeyword file foreign fragment from function
+syn keyword sqlKeyword group having
+syn keyword sqlKeyword immediate index inner into isolation
+syn keyword sqlKeyword join key
+syn keyword sqlKeyword left level log
+syn keyword sqlKeyword mode modify mounting new no
+syn keyword sqlKeyword object of old optical option
+syn keyword sqlKeyword optimization order outer
+syn keyword sqlKeyword pdqpriority pload primary procedure
+syn keyword sqlKeyword references referencing release reserve
+syn keyword sqlKeyword residency right role routine row
+syn keyword sqlKeyword schedule schema scratch session set
+syn keyword sqlKeyword statement statistics synonym
+syn keyword sqlKeyword table temp temporary timeout to transaction trigger
+syn keyword sqlKeyword using values view violations
+syn keyword sqlKeyword where with work
+" Highlight "on" (if it's not followed by some words we've already handled)
+syn match sqlKeyword "on \+\(exception\)\@!"
+" SPL
+" Highlight "end" (if it's not followed by some words we've already handled)
+syn match sqlKeyword "end \+\(if\|for\|foreach\|while\|exception\)\@!"
+syn keyword sqlKeyword resume returning
+
+" = Operator subgroup =
+" SQL
+syn keyword sqlOperator	not and or
+syn keyword sqlOperator	in is any some all between exists
+syn keyword sqlOperator	like matches
+syn keyword sqlOperator union intersect
+syn keyword sqlOperator distinct unique
+
+
+
+" === Identifier syntax group ===
+" = Function subgroup =
+" SQL
+syn keyword sqlFunction	abs acos asin atan atan2 avg
+syn keyword sqlFunction	cardinality cast char_length character_length cos count
+syn keyword sqlFunction	exp filetoblob filetoclob hex
+syn keyword sqlFunction	initcap length logn log10 lower lpad
+syn keyword sqlFunction	min max mod octet_length pow range replace root round rpad
+syn keyword sqlFunction	sin sqrt stdev substr substring sum
+syn keyword sqlFunction	to_char tan to_date trim trunc upper variance
+
+
+
+" === Type syntax group ===
+" SQL
+syn keyword sqlType	blob boolean byte char character clob
+syn keyword sqlType	date datetime dec decimal double
+syn keyword sqlType	float int int8 integer interval list lvarchar
+syn keyword sqlType	money multiset nchar numeric nvarchar
+syn keyword sqlType	real serial serial8 smallfloat smallint
+syn keyword sqlType	text varchar varying
+
+
+
+" === Todo syntax group ===
+syn keyword sqlTodo TODO FIXME XXX DEBUG NOTE
+
+
+
+" Define the default highlighting.
+" For version 5.7 and earlier: only when not done already
+" For version 5.8 and later: only when an item doesn't have highlighting yet
+if version >= 508 || !exists("did_sql_syn_inits")
+  if version < 508
+    let did_sql_syn_inits = 1
+    command -nargs=+ HiLink hi link <args>
+  else
+    command -nargs=+ HiLink hi def link <args>
+  endif
+
+
+  " === Comment syntax group ===
+  HiLink sqlComment	Comment
+
+  " === Constant syntax group ===
+  HiLink sqlNumber	Number
+  HiLink sqlBoolean	Boolean
+  HiLink sqlString	String
+
+  " === Statment syntax group ===
+  HiLink sqlStatement	Statement
+  HiLink sqlConditional	Conditional
+  HiLink sqlRepeat		Repeat
+  HiLink sqlKeyword		Keyword
+  HiLink sqlOperator	Operator
+  HiLink sqlException	Exception
+
+  " === Identifier syntax group ===
+  HiLink sqlFunction	Function
+
+  " === Type syntax group ===
+  HiLink sqlType	Type
+
+  " === Todo syntax group ===
+  HiLink sqlTodo	Todo
+
+  delcommand HiLink
+endif
+
+let b:current_syntax = "sqlinformix"
--- /dev/null
+++ b/lib/vimfiles/syntax/sqlj.vim
@@ -1,0 +1,102 @@
+" Vim syntax file
+" Language:	sqlj
+" Maintainer:	Andreas Fischbach <afisch@altavista.com>
+"		This file is based on sql.vim && java.vim (thanx)
+"		with a handful of additional sql words and still
+"		a subset of whatever standard
+" Last change:	31th Dec 2001
+
+" au BufNewFile,BufRead *.sqlj so $VIM/syntax/sqlj.vim
+
+" Remove any old syntax stuff hanging around
+if version < 600
+   syntax clear
+elseif exists("b:current_syntax")
+   finish
+endif
+
+" Read the Java syntax to start with
+source <sfile>:p:h/java.vim
+
+" SQLJ extentions
+" The SQL reserved words, defined as keywords.
+
+syn case ignore
+syn keyword sqljSpecial   null
+
+syn keyword sqljKeyword	access add as asc by check cluster column
+syn keyword sqljKeyword	compress connect current decimal default
+syn keyword sqljKeyword	desc else exclusive file for from group
+syn keyword sqljKeyword	having identified immediate increment index
+syn keyword sqljKeyword	initial into is level maxextents mode modify
+syn keyword sqljKeyword	nocompress nowait of offline on online start
+syn keyword sqljKeyword	successful synonym table then to trigger uid
+syn keyword sqljKeyword	unique user validate values view whenever
+syn keyword sqljKeyword	where with option order pctfree privileges
+syn keyword sqljKeyword	public resource row rowlabel rownum rows
+syn keyword sqljKeyword	session share size smallint
+
+syn keyword sqljKeyword  fetch database context iterator field join
+syn keyword sqljKeyword  foreign outer inner isolation left right
+syn keyword sqljKeyword  match primary key
+
+syn keyword sqljOperator	not and or
+syn keyword sqljOperator	in any some all between exists
+syn keyword sqljOperator	like escape
+syn keyword sqljOperator union intersect minus
+syn keyword sqljOperator prior distinct
+syn keyword sqljOperator	sysdate
+
+syn keyword sqljOperator	max min avg sum count hex
+
+syn keyword sqljStatement	alter analyze audit comment commit create
+syn keyword sqljStatement	delete drop explain grant insert lock noaudit
+syn keyword sqljStatement	rename revoke rollback savepoint select set
+syn keyword sqljStatement	 truncate update begin work
+
+syn keyword sqljType		char character date long raw mlslabel number
+syn keyword sqljType		rowid varchar varchar2 float integer
+
+syn keyword sqljType		byte text serial
+
+
+" Strings and characters:
+syn region sqljString		start=+"+  skip=+\\\\\|\\"+  end=+"+
+syn region sqljString		start=+'+  skip=+\\\\\|\\"+  end=+'+
+
+" Numbers:
+syn match sqljNumber		"-\=\<\d*\.\=[0-9_]\>"
+
+" PreProc
+syn match sqljPre		"#sql"
+
+" Comments:
+syn region sqljComment    start="/\*"  end="\*/"
+syn match sqlComment	"--.*"
+
+syn sync ccomment sqljComment
+
+if version >= 508 || !exists("did_sqlj_syn_inits")
+  if version < 508
+    let did_sqlj_syn_inits = 1
+    command! -nargs=+ HiLink hi link <args>
+  else
+    command! -nargs=+ HiLink hi def link <args>
+  endif
+
+  " The default methods for highlighting. Can be overridden later.
+  HiLink sqljComment	Comment
+  HiLink sqljKeyword	sqljSpecial
+  HiLink sqljNumber	Number
+  HiLink sqljOperator	sqljStatement
+  HiLink sqljSpecial	Special
+  HiLink sqljStatement	Statement
+  HiLink sqljString	String
+  HiLink sqljType	Type
+  HiLink sqljPre	PreProc
+
+  delcommand HiLink
+endif
+
+let b:current_syntax = "sqlj"
+
--- /dev/null
+++ b/lib/vimfiles/syntax/sqloracle.vim
@@ -1,0 +1,89 @@
+" Vim syntax file
+" Language:	SQL, PL/SQL (Oracle 8i)
+" Maintainer:	Paul Moore <pf_moore AT yahoo.co.uk>
+" Last Change:	2005 Dec 23
+
+" For version 5.x: Clear all syntax items
+" For version 6.x: Quit when a syntax file was already loaded
+if version < 600
+  syntax clear
+elseif exists("b:current_syntax")
+  finish
+endif
+
+syn case ignore
+
+" The SQL reserved words, defined as keywords.
+
+syn keyword sqlSpecial  false null true
+
+syn keyword sqlKeyword	access add as asc begin by check cluster column
+syn keyword sqlKeyword	compress connect current cursor decimal default desc
+syn keyword sqlKeyword	else elsif end exception exclusive file for from
+syn keyword sqlKeyword	function group having identified if immediate increment
+syn keyword sqlKeyword	index initial into is level loop maxextents mode modify
+syn keyword sqlKeyword	nocompress nowait of offline on online start
+syn keyword sqlKeyword	successful synonym table then to trigger uid
+syn keyword sqlKeyword	unique user validate values view whenever
+syn keyword sqlKeyword	where with option order pctfree privileges procedure
+syn keyword sqlKeyword	public resource return row rowlabel rownum rows
+syn keyword sqlKeyword	session share size smallint type using
+
+syn keyword sqlOperator	not and or
+syn keyword sqlOperator	in any some all between exists
+syn keyword sqlOperator	like escape
+syn keyword sqlOperator union intersect minus
+syn keyword sqlOperator prior distinct
+syn keyword sqlOperator	sysdate out
+
+syn keyword sqlStatement alter analyze audit comment commit create
+syn keyword sqlStatement delete drop execute explain grant insert lock noaudit
+syn keyword sqlStatement rename revoke rollback savepoint select set
+syn keyword sqlStatement truncate update
+
+syn keyword sqlType	boolean char character date float integer long
+syn keyword sqlType	mlslabel number raw rowid varchar varchar2 varray
+
+" Strings and characters:
+syn region sqlString		start=+"+  skip=+\\\\\|\\"+  end=+"+
+syn region sqlString		start=+'+  skip=+\\\\\|\\'+  end=+'+
+
+" Numbers:
+syn match sqlNumber		"-\=\<\d*\.\=[0-9_]\>"
+
+" Comments:
+syn region sqlComment    start="/\*"  end="\*/" contains=sqlTodo
+syn match sqlComment	"--.*$" contains=sqlTodo
+
+syn sync ccomment sqlComment
+
+" Todo.
+syn keyword sqlTodo contained TODO FIXME XXX DEBUG NOTE
+
+" Define the default highlighting.
+" For version 5.7 and earlier: only when not done already
+" For version 5.8 and later: only when an item doesn't have highlighting yet
+if version >= 508 || !exists("did_sql_syn_inits")
+  if version < 508
+    let did_sql_syn_inits = 1
+    command -nargs=+ HiLink hi link <args>
+  else
+    command -nargs=+ HiLink hi def link <args>
+  endif
+
+  HiLink sqlComment	Comment
+  HiLink sqlKeyword	sqlSpecial
+  HiLink sqlNumber	Number
+  HiLink sqlOperator	sqlStatement
+  HiLink sqlSpecial	Special
+  HiLink sqlStatement	Statement
+  HiLink sqlString	String
+  HiLink sqlType	Type
+  HiLink sqlTodo	Todo
+
+  delcommand HiLink
+endif
+
+let b:current_syntax = "sql"
+
+" vim: ts=8
--- /dev/null
+++ b/lib/vimfiles/syntax/sqr.vim
@@ -1,0 +1,295 @@
+" Vim syntax file
+"    Language: Structured Query Report Writer (SQR)
+"  Maintainer: Nathan Stratton Treadway (nathanst at ontko dot com)
+"	  URL: http://www.ontko.com/sqr/#editor_config_files
+"
+" Modification History:
+"     2002-Apr-12: Updated for SQR v6.x
+"     2002-Jul-30: Added { and } to iskeyword definition
+"     2003-Oct-15: Allow "." in variable names
+"		   highlight entire open '... literal when it contains
+"		      "''" inside it (e.g. "'I can''t say" is treated
+"		      as one open string, not one terminated and one open)
+"		   {} variables can occur inside of '...' literals
+"
+"  Thanks to the previous maintainer of this file, Jeff Lanzarotta:
+"    http://lanzarotta.tripod.com/vim.html
+"    jefflanzarotta at yahoo dot com
+
+" For version 5.x, clear all syntax items.
+" For version 6.x, quit when a syntax file was already loaded.
+if version < 600
+  syntax clear
+elseif exists("b:current_syntax")
+  finish
+endif
+
+if version >= 600
+  setlocal iskeyword=@,48-57,_,-,#,$,{,}
+else
+  set iskeyword=@,48-57,_,-,#,$,{,}
+endif
+
+syn case ignore
+
+" BEGIN GENERATED SECTION ============================================
+
+" Generated by generate_vim_syntax.sqr at 2002/04/11 13:04
+" (based on the UltraEdit syntax file for SQR 6.1.4
+" found at http://www.ontko.com/sqr/#editor_config_files )
+
+syn keyword    sqrSection     begin-footing begin-heading begin-procedure
+syn keyword    sqrSection     begin-program begin-report begin-setup
+syn keyword    sqrSection     end-footing end-heading end-procedure
+syn keyword    sqrSection     end-program end-report end-setup
+
+syn keyword    sqrParagraph   alter-color-map alter-conection
+syn keyword    sqrParagraph   alter-locale alter-printer alter-report
+syn keyword    sqrParagraph   begin-document begin-execute begin-select
+syn keyword    sqrParagraph   begin-sql declare-chart declare-image
+syn keyword    sqrParagraph   declare-color-map declare-conection
+syn keyword    sqrParagraph   declare-layout declare-printer
+syn keyword    sqrParagraph   declare-report declare-procedure
+syn keyword    sqrParagraph   declare-toc declare-variable end-declare
+syn keyword    sqrParagraph   end-document end-select exit-select end-sql
+syn keyword    sqrParagraph   load-lookup
+
+syn keyword    sqrReserved    #current-column #current-date #current-line
+syn keyword    sqrReserved    #end-file #page-count #return-status
+syn keyword    sqrReserved    #sql-count #sql-status #sqr-max-columns
+syn keyword    sqrReserved    #sqr-max-lines #sqr-pid #sqr-toc-level
+syn keyword    sqrReserved    #sqr-toc-page $sqr-database {sqr-database}
+syn keyword    sqrReserved    $sqr-dbcs {sqr-dbcs} $sqr-encoding
+syn keyword    sqrReserved    {sqr-encoding} $sqr-encoding-console
+syn keyword    sqrReserved    {sqr-encoding-console}
+syn keyword    sqrReserved    $sqr-encoding-database
+syn keyword    sqrReserved    {sqr-encoding-database}
+syn keyword    sqrReserved    $sqr-encoding-file-input
+syn keyword    sqrReserved    {sqr-encoding-file-input}
+syn keyword    sqrReserved    $sqr-encoding-file-output
+syn keyword    sqrReserved    {sqr-encoding-file-output}
+syn keyword    sqrReserved    $sqr-encoding-report-input
+syn keyword    sqrReserved    {sqr-encoding-report-input}
+syn keyword    sqrReserved    $sqr-encoding-report-output
+syn keyword    sqrReserved    {sqr-encoding-report-output}
+syn keyword    sqrReserved    $sqr-encoding-source {sqr-encoding-source}
+syn keyword    sqrReserved    $sql-error $sqr-hostname {sqr-hostname}
+syn keyword    sqrReserved    $sqr-locale $sqr-platform {sqr-platform}
+syn keyword    sqrReserved    $sqr-program $sqr-report $sqr-toc-text
+syn keyword    sqrReserved    $sqr-ver $username
+
+syn keyword    sqrPreProc     #define #else #end-if #endif #if #ifdef
+syn keyword    sqrPreProc     #ifndef #include
+
+syn keyword    sqrCommand     add array-add array-divide array-multiply
+syn keyword    sqrCommand     array-subtract ask break call clear-array
+syn keyword    sqrCommand     close columns commit concat connect
+syn keyword    sqrCommand     create-array create-color-palette date-time
+syn keyword    sqrCommand     display divide do dollar-symbol else encode
+syn keyword    sqrCommand     end-evaluate end-if end-while evaluate
+syn keyword    sqrCommand     execute extract find get get-color goto
+syn keyword    sqrCommand     graphic if input last-page let lookup
+syn keyword    sqrCommand     lowercase mbtosbs money-symbol move
+syn keyword    sqrCommand     multiply new-page new-report next-column
+syn keyword    sqrCommand     next-listing no-formfeed open page-number
+syn keyword    sqrCommand     page-size position print print-bar-code
+syn keyword    sqrCommand     print-chart print-direct print-image
+syn keyword    sqrCommand     printer-deinit printer-init put read
+syn keyword    sqrCommand     rollback security set-color set-delay-print
+syn keyword    sqrCommand     set-generations set-levels set-members
+syn keyword    sqrCommand     sbtombs show stop string subtract toc-entry
+syn keyword    sqrCommand     unstring uppercase use use-column
+syn keyword    sqrCommand     use-printer-type use-procedure use-report
+syn keyword    sqrCommand     while write
+
+syn keyword    sqrParam       3d-effects after after-bold after-page
+syn keyword    sqrParam       after-report after-toc and as at-end before
+syn keyword    sqrParam       background batch-mode beep before-bold
+syn keyword    sqrParam       before-page before-report before-toc blink
+syn keyword    sqrParam       bold border bottom-margin box break by
+syn keyword    sqrParam       caption center char char-size char-width
+syn keyword    sqrParam       chars-inch chart-size checksum cl
+syn keyword    sqrParam       clear-line clear-screen color color-palette
+syn keyword    sqrParam       cs color_ data-array
+syn keyword    sqrParam       data-array-column-count
+syn keyword    sqrParam       data-array-column-labels
+syn keyword    sqrParam       data-array-row-count data-labels date
+syn keyword    sqrParam       date-edit-mask date-seperator
+syn keyword    sqrParam       day-of-week-case day-of-week-full
+syn keyword    sqrParam       day-of-week-short decimal decimal-seperator
+syn keyword    sqrParam       default-numeric delay distinct dot-leader
+syn keyword    sqrParam       edit-option-ad edit-option-am
+syn keyword    sqrParam       edit-option-bc edit-option-na
+syn keyword    sqrParam       edit-option-pm encoding entry erase-page
+syn keyword    sqrParam       extent field fill fixed fixed_nolf float
+syn keyword    sqrParam       font font-style font-type footing
+syn keyword    sqrParam       footing-size foreground for-append
+syn keyword    sqrParam       for-reading for-reports for-tocs
+syn keyword    sqrParam       for-writing format formfeed from goto-top
+syn keyword    sqrParam       group having heading heading-size height
+syn keyword    sqrParam       horz-line image-size in indentation
+syn keyword    sqrParam       init-string input-date-edit-mask insert
+syn keyword    sqrParam       integer into item-color item-size key
+syn keyword    sqrParam       layout left-margin legend legend-placement
+syn keyword    sqrParam       legend-presentation legend-title level
+syn keyword    sqrParam       line-height line-size line-width lines-inch
+syn keyword    sqrParam       local locale loops max-columns max-lines
+syn keyword    sqrParam       maxlen money money-edit-mask money-sign
+syn keyword    sqrParam       money-sign-location months-case months-full
+syn keyword    sqrParam       months-short name need newline newpage
+syn keyword    sqrParam       no-advance nolf noline noprompt normal not
+syn keyword    sqrParam       nowait number number-edit-mask on-break
+syn keyword    sqrParam       on-error or order orientation page-depth
+syn keyword    sqrParam       paper-size pie-segment-explode
+syn keyword    sqrParam       pie-segment-percent-display
+syn keyword    sqrParam       pie-segment-quantity-display pitch
+syn keyword    sqrParam       point-markers point-size printer
+syn keyword    sqrParam       printer-type quiet record reset-string
+syn keyword    sqrParam       return_value reverse right-margin rows save
+syn keyword    sqrParam       select size skip skiplines sort source
+syn keyword    sqrParam       sqr-database sqr-platform startup-file
+syn keyword    sqrParam       status stop sub-title symbol-set system
+syn keyword    sqrParam       table text thousand-seperator
+syn keyword    sqrParam       time-seperator times title to toc
+syn keyword    sqrParam       top-margin type underline update using
+syn keyword    sqrParam       value vary vert-line wait warn when
+syn keyword    sqrParam       when-other where with x-axis-grid
+syn keyword    sqrParam       x-axis-label x-axis-major-increment
+syn keyword    sqrParam       x-axis-major-tick-marks x-axis-max-value
+syn keyword    sqrParam       x-axis-min-value x-axis-minor-increment
+syn keyword    sqrParam       x-axis-minor-tick-marks x-axis-rotate
+syn keyword    sqrParam       x-axis-scale x-axis-tick-mark-placement xor
+syn keyword    sqrParam       y-axis-grid y-axis-label
+syn keyword    sqrParam       y-axis-major-increment
+syn keyword    sqrParam       y-axis-major-tick-marks y-axis-max-value
+syn keyword    sqrParam       y-axis-min-value y-axis-minor-increment
+syn keyword    sqrParam       y-axis-minor-tick-marks y-axis-scale
+syn keyword    sqrParam       y-axis-tick-mark-placement y2-type
+syn keyword    sqrParam       y2-data-array y2-data-array-row-count
+syn keyword    sqrParam       y2-data-array-column-count
+syn keyword    sqrParam       y2-data-array-column-labels
+syn keyword    sqrParam       y2-axis-color-palette y2-axis-label
+syn keyword    sqrParam       y2-axis-major-increment
+syn keyword    sqrParam       y2-axis-major-tick-marks y2-axis-max-value
+syn keyword    sqrParam       y2-axis-min-value y2-axis-minor-increment
+syn keyword    sqrParam       y2-axis-minor-tick-marks y2-axis-scale
+
+syn keyword    sqrFunction    abs acos asin atan array ascii asciic ceil
+syn keyword    sqrFunction    cos cosh chr cond deg delete dateadd
+syn keyword    sqrFunction    datediff datenow datetostr e10 exp edit
+syn keyword    sqrFunction    exists floor getenv instr instrb isblank
+syn keyword    sqrFunction    isnull log log10 length lengthb lengthp
+syn keyword    sqrFunction    lengtht lower lpad ltrim mod nvl power rad
+syn keyword    sqrFunction    round range replace roman rpad rtrim rename
+syn keyword    sqrFunction    sign sin sinh sqrt substr substrb substrp
+syn keyword    sqrFunction    substrt strtodate tan tanh trunc to_char
+syn keyword    sqrFunction    to_multi_byte to_number to_single_byte
+syn keyword    sqrFunction    transform translate unicode upper wrapdepth
+
+" END GENERATED SECTION ==============================================
+
+" Variables
+syn match	  sqrVariable	/\(\$\|#\|&\)\(\k\|\.\)*/
+
+
+" Debug compiler directives
+syn match	  sqrPreProc	/\s*#debug\a\=\(\s\|$\)/
+syn match	  sqrSubstVar	/{\k*}/
+
+
+" Strings
+" Note: if an undoubled ! is found, this is not a valid string
+" (SQR will treat the end of the line as a comment)
+syn match	  sqrString	/'\(!!\|[^!']\)*'/      contains=sqrSubstVar
+syn match	  sqrStrOpen	/'\(!!\|''\|[^!']\)*$/
+" If we find a ' followed by an unmatched ! before a matching ',
+" flag the error.
+syn match	  sqrError	/'\(!!\|[^'!]\)*![^!]/me=e-1
+syn match	  sqrError	/'\(!!\|[^'!]\)*!$/
+
+" Numbers:
+syn match	  sqrNumber	/-\=\<\d*\.\=[0-9_]\>/
+
+
+
+" Comments:
+" Handle comments that start with "!=" specially; they are only valid
+" in the first column of the source line.  Also, "!!" is only treated
+" as a start-comment if there is only whitespace ahead of it on the line.
+
+syn keyword	sqrTodo		TODO FIXME XXX DEBUG NOTE ###
+syn match	sqrTodo		/???/
+
+if version >= 600
+  " See also the sqrString section above for handling of ! characters
+  " inside of strings.  (Those patterns override the ones below.)
+  syn match	sqrComment	/!\@<!!\([^!=].*\|$\)/ contains=sqrTodo
+  "				  the ! can't be preceeded by another !,
+  "				  and must be followed by at least one
+  "				  character other than ! or =, or immediately
+  "				  by the end-of-line
+  syn match	sqrComment	/^!=.*/ contains=sqrTodo
+  syn match	sqrComment	/^!!.*/ contains=sqrTodo
+  syn match	sqrError	/^\s\+\zs!=.*/
+  "				  it's an error to have "!=" preceeded by
+  "				  just whitespace on the line ("!="
+  "				  preceeded by non-whitespace is treated
+  "				  as neither a comment nor an error, since
+  "				  it is often correct, i.e.
+  "				    if #count != 7
+  syn match	sqrError	/.\+\zs!!.*/
+  "				  a "!!" anywhere but at the beginning of
+  "				  the line is always an error
+else "For versions before 6.0, same idea as above but we are limited
+     "to simple patterns only.  Also, the sqrString patterns above
+     "don't seem to take precedence in v5 as they do in v6, so
+     "we split the last rule to ignore comments found inside of
+     "string literals.
+  syn match	sqrComment	/!\([^!=].*\|$\)/ contains=sqrTodo
+  syn match	sqrComment	/^!=.*/ contains=sqrTodo
+  syn match	sqrComment	/^!!.*/ contains=sqrTodo
+  syn match	sqrError	/^\s\+!=.*/
+  syn match	sqrError	/^[^'!]\+!!/
+  "				flag !! on lines that don't have ! or '
+  syn match	sqrError	/^\([^!']*'[^']*'[^!']*\)\+!!/
+  "				flag !! found after matched ' ' chars
+  "				(that aren't also commented)
+endif
+
+
+" Define the default highlighting.
+" For version 5.7 and earlier, only when not done already.
+" For version 5.8 and later, only when an item doesn;t have hightlighting yet.
+if version >= 508 || !exists("did_sqr_syn_inits")
+  if version < 508
+    let did_sqr_syn_inits = 1
+    command -nargs=+ HiLink hi link <args>
+  else
+    command -nargs=+ HiLink hi def link <args>
+  endif
+
+  HiLink sqrSection Statement
+  HiLink sqrParagraph Statement
+  HiLink sqrReserved Statement
+  HiLink sqrParameter Statement
+  HiLink sqrPreProc PreProc
+  HiLink sqrSubstVar PreProc
+  HiLink sqrCommand Statement
+  HiLink sqrParam Type
+  HiLink sqrFunction Special
+
+  HiLink sqrString String
+  HiLink sqrStrOpen Todo
+  HiLink sqrNumber Number
+  HiLink sqrVariable Identifier
+
+  HiLink sqrComment Comment
+  HiLink sqrTodo Todo
+  HiLink sqrError Error
+
+  delcommand HiLink
+endif
+
+let b:current_syntax = "sqr"
+
+" vim: ts=8 sw=2
--- /dev/null
+++ b/lib/vimfiles/syntax/squid.vim
@@ -1,0 +1,153 @@
+" Vim syntax file
+" Language:	Squid config file
+" Maintainer:	Klaus Muth <klaus@hampft.de>
+" Last Change:	2005 Jun 12
+" URL:		http://www.hampft.de/vim/syntax/squid.vim
+" ThanksTo:	Ilya Sher <iso8601@mail.ru>,
+"               Michael Dotzler <Michael.Dotzler@leoni.com>
+
+
+" For version 5.x: Clear all syntax items
+" For version 6.x: Quit when a syntax file was already loaded
+if version < 600
+  syntax clear
+elseif exists("b:current_syntax")
+  finish
+endif
+
+" squid.conf syntax seems to be case insensitive
+syn case ignore
+
+syn keyword	squidTodo	contained TODO
+syn match	squidComment	"#.*$" contains=squidTodo,squidTag
+syn match	squidTag	contained "TAG: .*$"
+
+" Lots & lots of Keywords!
+syn keyword	squidConf	acl always_direct announce_host announce_period
+syn keyword	squidConf	announce_port announce_to anonymize_headers
+syn keyword	squidConf	append_domain as_whois_server auth_param_basic
+syn keyword	squidConf	authenticate_children authenticate_program
+syn keyword	squidConf	authenticate_ttl broken_posts buffered_logs
+syn keyword	squidConf	cache_access_log cache_announce cache_dir
+syn keyword	squidConf	cache_dns_program cache_effective_group
+syn keyword	squidConf	cache_effective_user cache_host cache_host_acl
+syn keyword	squidConf	cache_host_domain cache_log cache_mem
+syn keyword	squidConf	cache_mem_high cache_mem_low cache_mgr
+syn keyword	squidConf	cachemgr_passwd cache_peer cache_peer_access
+syn keyword	squidConf	cahce_replacement_policy cache_stoplist
+syn keyword	squidConf	cache_stoplist_pattern cache_store_log cache_swap
+syn keyword	squidConf	cache_swap_high cache_swap_log cache_swap_low
+syn keyword	squidConf	client_db client_lifetime client_netmask
+syn keyword	squidConf	connect_timeout coredump_dir dead_peer_timeout
+syn keyword	squidConf	debug_options delay_access delay_class
+syn keyword	squidConf	delay_initial_bucket_level delay_parameters
+syn keyword	squidConf	delay_pools deny_info dns_children dns_defnames
+syn keyword	squidConf	dns_nameservers dns_testnames emulate_httpd_log
+syn keyword	squidConf	err_html_text fake_user_agent firewall_ip
+syn keyword	squidConf	forwarded_for forward_snmpd_port fqdncache_size
+syn keyword	squidConf	ftpget_options ftpget_program ftp_list_width
+syn keyword	squidConf	ftp_passive ftp_user half_closed_clients
+syn keyword	squidConf	header_access header_replace hierarchy_stoplist
+syn keyword	squidConf	high_response_time_warning high_page_fault_warning
+syn keyword	squidConf	htcp_port http_access http_anonymizer httpd_accel
+syn keyword	squidConf	httpd_accel_host httpd_accel_port
+syn keyword	squidConf	httpd_accel_uses_host_header
+syn keyword	squidConf	httpd_accel_with_proxy http_port http_reply_access
+syn keyword	squidConf	icp_access icp_hit_stale icp_port
+syn keyword	squidConf	icp_query_timeout ident_lookup ident_lookup_access
+syn keyword	squidConf	ident_timeout incoming_http_average
+syn keyword	squidConf	incoming_icp_average inside_firewall ipcache_high
+syn keyword	squidConf	ipcache_low ipcache_size local_domain local_ip
+syn keyword	squidConf	logfile_rotate log_fqdn log_icp_queries
+syn keyword	squidConf	log_mime_hdrs maximum_object_size
+syn keyword	squidConf	maximum_single_addr_tries mcast_groups
+syn keyword	squidConf	mcast_icp_query_timeout mcast_miss_addr
+syn keyword	squidConf	mcast_miss_encode_key mcast_miss_port memory_pools
+syn keyword	squidConf	memory_pools_limit memory_replacement_policy
+syn keyword	squidConf	mime_table min_http_poll_cnt min_icp_poll_cnt
+syn keyword	squidConf	minimum_direct_hops minimum_object_size
+syn keyword	squidConf	minimum_retry_timeout miss_access negative_dns_ttl
+syn keyword	squidConf	negative_ttl neighbor_timeout neighbor_type_domain
+syn keyword	squidConf	netdb_high netdb_low netdb_ping_period
+syn keyword	squidConf	netdb_ping_rate never_direct no_cache
+syn keyword	squidConf	passthrough_proxy pconn_timeout pid_filename
+syn keyword	squidConf	pinger_program positive_dns_ttl prefer_direct
+syn keyword	squidConf	proxy_auth proxy_auth_realm query_icmp quick_abort
+syn keyword	squidConf	quick_abort quick_abort_max quick_abort_min
+syn keyword	squidConf	quick_abort_pct range_offset_limit read_timeout
+syn keyword	squidConf	redirect_children redirect_program
+syn keyword	squidConf	redirect_rewrites_host_header reference_age
+syn keyword	squidConf	reference_age refresh_pattern reload_into_ims
+syn keyword	squidConf	request_body_max_size request_size request_timeout
+syn keyword	squidConf	shutdown_lifetime single_parent_bypass
+syn keyword	squidConf	siteselect_timeout snmp_access
+syn keyword	squidConf	snmp_incoming_address snmp_port source_ping
+syn keyword	squidConf	ssl_proxy store_avg_object_size
+syn keyword	squidConf	store_objects_per_bucket strip_query_terms
+syn keyword	squidConf	swap_level1_dirs swap_level2_dirs
+syn keyword	squidConf	tcp_incoming_address tcp_outgoing_address
+syn keyword	squidConf	tcp_recv_bufsize test_reachability udp_hit_obj
+syn keyword	squidConf	udp_hit_obj_size udp_incoming_address
+syn keyword	squidConf	udp_outgoing_address unique_hostname
+syn keyword	squidConf	unlinkd_program uri_whitespace useragent_log
+syn keyword	squidConf	visible_hostname wais_relay wais_relay_host
+syn keyword	squidConf	wais_relay_port
+
+syn keyword	squidOpt	proxy-only weight ttl no-query default
+syn keyword	squidOpt	round-robin multicast-responder
+syn keyword	squidOpt	on off all deny allow
+syn keyword	squidopt	via parent no-digest heap lru realm
+syn keyword	squidopt	children credentialsttl none disable
+syn keyword	squidopt	offline_toggle diskd q1 q2
+
+" Security Actions for cachemgr_passwd
+syn keyword	squidAction	shutdown info parameter server_list
+syn keyword	squidAction	client_list
+syn match	squidAction	"stats/\(objects\|vm_objects\|utilization\|ipcache\|fqdncache\|dns\|redirector\|io\|reply_headers\|filedescriptors\|netdb\)"
+syn match	squidAction	"log\(/\(status\|enable\|disable\|clear\)\)\="
+syn match	squidAction	"squid\.conf"
+
+" Keywords for the acl-config
+syn keyword	squidAcl	url_regex urlpath_regex referer_regex port proto
+syn keyword	squidAcl	req_mime_type rep_mime_type
+syn keyword	squidAcl	method browser user src dst
+syn keyword	squidAcl	time dstdomain ident snmp_community
+
+syn match	squidNumber	"\<\d\+\>"
+syn match	squidIP		"\<\d\{1,3}\.\d\{1,3}\.\d\{1,3}\.\d\{1,3}\>"
+syn match	squidStr	"\(^\s*acl\s\+\S\+\s\+\(\S*_regex\|re[pq]_mime_type\|browser\|_domain\|user\)\+\s\+\)\@<=.*" contains=squidRegexOpt
+syn match	squidRegexOpt	contained "\(^\s*acl\s\+\S\+\s\+\S\+\(_regex\|_mime_type\)\s\+\)\@<=[-+]i\s\+"
+
+" All config is in one line, so this has to be sufficient
+" Make it fast like hell :)
+syn sync minlines=3
+
+" Define the default highlighting.
+" For version 5.7 and earlier: only when not done already
+" For version 5.8 and later: only when an item doesn't have highlighting yet
+if version >= 508 || !exists("did_squid_syntax_inits")
+  if version < 508
+    let did_squid_syntax_inits = 1
+    command -nargs=+ HiLink hi link <args>
+  else
+    command -nargs=+ HiLink hi def link <args>
+  endif
+
+  HiLink squidTodo	Todo
+  HiLink squidComment	Comment
+  HiLink squidTag	Special
+  HiLink squidConf	Keyword
+  HiLink squidOpt	Constant
+  HiLink squidAction	String
+  HiLink squidNumber	Number
+  HiLink squidIP	Number
+  HiLink squidAcl	Keyword
+  HiLink squidStr	String
+  HiLink squidRegexOpt	Special
+
+  delcommand HiLink
+endif
+
+let b:current_syntax = "squid"
+
+" vim: ts=8
--- /dev/null
+++ b/lib/vimfiles/syntax/sshconfig.vim
@@ -1,0 +1,105 @@
+" Vim syntax file
+" This is a GENERATED FILE. Please always refer to source file at the URI below.
+" Language: OpenSSH server configuration file (ssh_config)
+" Maintainer: David Ne\v{c}as (Yeti) <yeti@physics.muni.cz>
+" Last Change: 2006-03-05
+" URL: http://trific.ath.cx/Ftp/vim/syntax/sshconfig.vim
+
+" Setup
+if version >= 600
+	if exists("b:current_syntax")
+		finish
+	endif
+else
+	syntax clear
+endif
+
+if version >= 600
+	setlocal iskeyword=_,-,a-z,A-Z,48-57
+else
+	set iskeyword=_,-,a-z,A-Z,48-57
+endif
+
+syn case ignore
+
+" Comments
+syn match sshconfigComment "#.*$" contains=sshconfigTodo
+syn keyword sshconfigTodo TODO FIXME NOT contained
+
+" Constants
+syn keyword sshconfigYesNo yes no ask
+syn keyword sshconfigCipher blowfish des 3des
+syn keyword sshconfigCipher aes128-cbc 3des-cbc blowfish-cbc cast128-cbc
+syn keyword sshconfigCipher aes192-cbc aes256-cbc aes128-ctr aes256-ctr
+syn keyword sshconfigCipher arcfour arcfour128 arcfour256 cast128-cbc
+syn keyword sshconfigMAC hmac-md5 hmac-sha1 hmac-ripemd160 hmac-sha1-96
+syn keyword sshconfigMAC hmac-md5-96
+syn keyword sshconfigHostKeyAlg ssh-rsa ssh-dss
+syn keyword sshconfigPreferredAuth hostbased publickey password
+syn keyword sshconfigPreferredAuth keyboard-interactive
+syn keyword sshconfigLogLevel QUIET FATAL ERROR INFO VERBOSE
+syn keyword sshconfigLogLevel DEBUG DEBUG1 DEBUG2 DEBUG3
+syn keyword sshconfigSysLogFacility DAEMON USER AUTH LOCAL0 LOCAL1 LOCAL2
+syn keyword sshconfigSysLogFacility LOCAL3 LOCAL4 LOCAL5 LOCAL6 LOCAL7
+syn match sshconfigSpecial "[*?]"
+syn match sshconfigNumber "\d\+"
+syn match sshconfigHostPort "\<\(\d\{1,3}\.\)\{3}\d\{1,3}\(:\d\+\)\?\>"
+syn match sshconfigHostPort "\<\([-a-zA-Z0-9]\+\.\)\+[-a-zA-Z0-9]\{2,}\(:\d\+\)\?\>"
+syn match sshconfigHostPort "\<\(\x\{,4}:\)\+\x\{,4}[:/]\d\+\>"
+
+" Keywords
+syn keyword sshconfigHostSect Host
+syn keyword sshconfigKeyword AddressFamily BatchMode BindAddress
+syn keyword sshconfigKeyword ChallengeResponseAuthentication CheckHostIP
+syn keyword sshconfigKeyword Cipher Ciphers ClearAllForwardings
+syn keyword sshconfigKeyword Compression CompressionLevel ConnectTimeout
+syn keyword sshconfigKeyword ConnectionAttempts ControlMaster
+syn keyword sshconfigKeyword ControlPath DynamicForward EnableSSHKeysign
+syn keyword sshconfigKeyword EscapeChar ForwardAgent ForwardX11
+syn keyword sshconfigKeyword ForwardX11Trusted GSSAPIAuthentication
+syn keyword sshconfigKeyword GSSAPIDelegateCredentials GatewayPorts
+syn keyword sshconfigKeyword GlobalKnownHostsFile HostKeyAlgorithms
+syn keyword sshconfigKeyword HashKnownHosts KbdInteractiveDevices
+syn keyword sshconfigKeyword HostKeyAlias HostName HostbasedAuthentication
+syn keyword sshconfigKeyword IdentitiesOnly IdentityFile LocalForward
+syn keyword sshconfigKeyword LogLevel MACs NoHostAuthenticationForLocalhost
+syn keyword sshconfigKeyword NumberOfPasswordPrompts PasswordAuthentication
+syn keyword sshconfigKeyword Port PreferredAuthentications Protocol
+syn keyword sshconfigKeyword ProxyCommand PubkeyAuthentication
+syn keyword sshconfigKeyword RSAAuthentication RemoteForward
+syn keyword sshconfigKeyword RhostsAuthentication RhostsRSAAuthentication
+syn keyword sshconfigKeyword SendEnv ServerAliveCountMax ServerAliveInterval
+syn keyword sshconfigKeyword SmartcardDevice StrictHostKeyChecking
+syn keyword sshconfigKeyword TCPKeepAlive UsePrivilegedPort User
+syn keyword sshconfigKeyword UserKnownHostsFile VerifyHostKeyDNS XAuthLocation
+
+" Define the default highlighting
+if version >= 508 || !exists("did_sshconfig_syntax_inits")
+	if version < 508
+		let did_sshconfig_syntax_inits = 1
+		command -nargs=+ HiLink hi link <args>
+	else
+		command -nargs=+ HiLink hi def link <args>
+	endif
+
+	HiLink sshconfigComment Comment
+	HiLink sshconfigTodo Todo
+	HiLink sshconfigHostPort sshconfigConstant
+	HiLink sshconfigNumber sshconfigConstant
+	HiLink sshconfigConstant Constant
+	HiLink sshconfigYesNo sshconfigEnum
+	HiLink sshconfigCipher sshconfigEnum
+	HiLink sshconfigMAC sshconfigEnum
+	HiLink sshconfigHostKeyAlg sshconfigEnum
+	HiLink sshconfigLogLevel sshconfigEnum
+	HiLink sshconfigSysLogFacility sshconfigEnum
+	HiLink sshconfigPreferredAuth sshconfigEnum
+	HiLink sshconfigEnum Function
+	HiLink sshconfigSpecial Special
+	HiLink sshconfigKeyword Keyword
+	HiLink sshconfigHostSect Type
+	delcommand HiLink
+endif
+
+let b:current_syntax = "sshconfig"
+
--- /dev/null
+++ b/lib/vimfiles/syntax/sshdconfig.vim
@@ -1,0 +1,104 @@
+" Vim syntax file
+" This is a GENERATED FILE. Please always refer to source file at the URI below.
+" Language: OpenSSH server configuration file (sshd_config)
+" Maintainer: David Ne\v{c}as (Yeti) <yeti@physics.muni.cz>
+" Last Change: 2006-03-05
+" URL: http://trific.ath.cx/Ftp/vim/syntax/sshdconfig.vim
+
+" Setup
+if version >= 600
+	if exists("b:current_syntax")
+		finish
+	endif
+else
+	syntax clear
+endif
+
+if version >= 600
+	setlocal iskeyword=_,-,a-z,A-Z,48-57
+else
+	set iskeyword=_,-,a-z,A-Z,48-57
+endif
+
+syn case ignore
+
+" Comments
+syn match sshdconfigComment "#.*$" contains=sshdconfigTodo
+syn keyword sshdconfigTodo TODO FIXME NOT contained
+
+" Constants
+syn keyword sshdconfigYesNo yes no
+syn keyword sshdconfigCipher aes128-cbc 3des-cbc blowfish-cbc cast128-cbc
+syn keyword sshdconfigCipher aes192-cbc aes256-cbc aes128-ctr aes256-ctr
+syn keyword sshdconfigCipher arcfour arcfour128 arcfour256 cast128-cbc
+syn keyword sshdconfigMAC hmac-md5 hmac-sha1 hmac-ripemd160 hmac-sha1-96
+syn keyword sshdconfigMAC hmac-md5-96
+syn keyword sshdconfigRootLogin without-password forced-commands-only
+syn keyword sshdconfigLogLevel QUIET FATAL ERROR INFO VERBOSE
+syn keyword sshdconfigLogLevel DEBUG DEBUG1 DEBUG2 DEBUG3
+syn keyword sshdconfigSysLogFacility DAEMON USER AUTH LOCAL0 LOCAL1 LOCAL2
+syn keyword sshdconfigSysLogFacility LOCAL3 LOCAL4 LOCAL5 LOCAL6 LOCAL7
+syn match sshdconfigSpecial "[*?]"
+syn match sshdconfigNumber "\d\+"
+syn match sshdconfigHostPort "\<\(\d\{1,3}\.\)\{3}\d\{1,3}\(:\d\+\)\?\>"
+syn match sshdconfigHostPort "\<\([-a-zA-Z0-9]\+\.\)\+[-a-zA-Z0-9]\{2,}\(:\d\+\)\?\>"
+syn match sshdconfigHostPort "\<\(\x\{,4}:\)\+\x\{,4}:\d\+\>"
+syn match sshdconfigTime "\<\(\d\+[sSmMhHdDwW]\)\+\>"
+
+" Keywords
+syn keyword sshdconfigKeyword AcceptEnv AddressFamily
+syn keyword sshdconfigKeyword AllowGroups AllowTcpForwarding
+syn keyword sshdconfigKeyword AllowUsers AuthorizedKeysFile Banner
+syn keyword sshdconfigKeyword ChallengeResponseAuthentication
+syn keyword sshdconfigKeyword Ciphers ClientAliveCountMax
+syn keyword sshdconfigKeyword ClientAliveInterval Compression
+syn keyword sshdconfigKeyword DenyGroups DenyUsers GSSAPIAuthentication
+syn keyword sshdconfigKeyword GSSAPICleanupCredentials GatewayPorts
+syn keyword sshdconfigKeyword HostKey HostbasedAuthentication
+syn keyword sshdconfigKeyword IgnoreRhosts IgnoreUserKnownHosts
+syn keyword sshdconfigKeyword KerberosAuthentication KerberosOrLocalPasswd
+syn keyword sshdconfigKeyword KerberosTgtPassing KerberosTicketCleanup
+syn keyword sshdconfigKeyword KerberosGetAFSToken
+syn keyword sshdconfigKeyword KeyRegenerationInterval ListenAddress
+syn keyword sshdconfigKeyword LogLevel LoginGraceTime MACs MaxAuthTries
+syn keyword sshdconfigKeyword MaxStartups PasswordAuthentication
+syn keyword sshdconfigKeyword PermitEmptyPasswords PermitRootLogin
+syn keyword sshdconfigKeyword PermitUserEnvironment PidFile Port
+syn keyword sshdconfigKeyword PrintLastLog PrintMotd Protocol
+syn keyword sshdconfigKeyword PubkeyAuthentication RSAAuthentication
+syn keyword sshdconfigKeyword RhostsAuthentication RhostsRSAAuthentication
+syn keyword sshdconfigKeyword ServerKeyBits StrictModes Subsystem
+syn keyword sshdconfigKeyword ShowPatchLevel
+syn keyword sshdconfigKeyword SyslogFacility TCPKeepAlive UseDNS
+syn keyword sshdconfigKeyword UseLogin UsePAM UsePrivilegeSeparation
+syn keyword sshdconfigKeyword X11DisplayOffset X11Forwarding
+syn keyword sshdconfigKeyword X11UseLocalhost XAuthLocation
+
+" Define the default highlighting
+if version >= 508 || !exists("did_sshdconfig_syntax_inits")
+	if version < 508
+		let did_sshdconfig_syntax_inits = 1
+		command -nargs=+ HiLink hi link <args>
+	else
+		command -nargs=+ HiLink hi def link <args>
+	endif
+
+	HiLink sshdconfigComment Comment
+	HiLink sshdconfigTodo Todo
+	HiLink sshdconfigHostPort sshdconfigConstant
+	HiLink sshdconfigTime sshdconfigConstant
+	HiLink sshdconfigNumber sshdconfigConstant
+	HiLink sshdconfigConstant Constant
+	HiLink sshdconfigYesNo sshdconfigEnum
+	HiLink sshdconfigCipher sshdconfigEnum
+	HiLink sshdconfigMAC sshdconfigEnum
+	HiLink sshdconfigRootLogin sshdconfigEnum
+	HiLink sshdconfigLogLevel sshdconfigEnum
+	HiLink sshdconfigSysLogFacility sshdconfigEnum
+	HiLink sshdconfigEnum Function
+	HiLink sshdconfigSpecial Special
+	HiLink sshdconfigKeyword Keyword
+	delcommand HiLink
+endif
+
+let b:current_syntax = "sshdconfig"
--- /dev/null
+++ b/lib/vimfiles/syntax/st.vim
@@ -1,0 +1,102 @@
+" Vim syntax file
+" Language:	Smalltalk
+" Maintainer:	Arndt Hesse <hesse@self.de>
+" Last Change:	2001 May 09
+
+" For version 5.x: Clear all syntax items
+" For version 6.x: Quit when a syntax file was already loaded
+if version < 600
+  syntax clear
+elseif exists("b:current_syntax")
+  finish
+endif
+
+" some Smalltalk keywords and standard methods
+syn keyword	stKeyword	super self class true false new not
+syn keyword	stKeyword	notNil isNil inspect out nil
+syn match	stMethod	"\<do\>:"
+syn match	stMethod	"\<whileTrue\>:"
+syn match	stMethod	"\<whileFalse\>:"
+syn match	stMethod	"\<ifTrue\>:"
+syn match	stMethod	"\<ifFalse\>:"
+syn match	stMethod	"\<put\>:"
+syn match	stMethod	"\<to\>:"
+syn match	stMethod	"\<at\>:"
+syn match	stMethod	"\<add\>:"
+syn match	stMethod	"\<new\>:"
+syn match	stMethod	"\<for\>:"
+syn match	stMethod	"\<methods\>:"
+syn match	stMethod	"\<methodsFor\>:"
+syn match	stMethod	"\<instanceVariableNames\>:"
+syn match	stMethod	"\<classVariableNames\>:"
+syn match	stMethod	"\<poolDictionaries\>:"
+syn match	stMethod	"\<subclass\>:"
+
+" the block of local variables of a method
+syn region stLocalVariables	start="^[ \t]*|" end="|"
+
+" the Smalltalk comment
+syn region stComment	start="\"" end="\""
+
+" the Smalltalk strings and single characters
+syn region stString	start='\'' skip="''" end='\''
+syn match  stCharacter	"$."
+
+syn case ignore
+
+" the symols prefixed by a '#'
+syn match  stSymbol	"\(#\<[a-z_][a-z0-9_]*\>\)"
+syn match  stSymbol	"\(#'[^']*'\)"
+
+" the variables in a statement block for loops
+syn match  stBlockVariable "\(:[ \t]*\<[a-z_][a-z0-9_]*\>[ \t]*\)\+|" contained
+
+" some representations of numbers
+syn match  stNumber	"\<\d\+\(u\=l\=\|lu\|f\)\>"
+syn match  stFloat	"\<\d\+\.\d*\(e[-+]\=\d\+\)\=[fl]\=\>"
+syn match  stFloat	"\<\d\+e[-+]\=\d\+[fl]\=\>"
+
+syn case match
+
+" a try to higlight paren mismatches
+syn region stParen	transparent start='(' end=')' contains=ALLBUT,stParenError
+syn match  stParenError	")"
+syn region stBlock	transparent start='\[' end='\]' contains=ALLBUT,stBlockError
+syn match  stBlockError	"\]"
+syn region stSet	transparent start='{' end='}' contains=ALLBUT,stSetError
+syn match  stSetError	"}"
+
+hi link stParenError stError
+hi link stSetError stError
+hi link stBlockError stError
+
+" synchronization for syntax analysis
+syn sync minlines=50
+
+" Define the default highlighting.
+" For version 5.7 and earlier: only when not done already
+" For version 5.8 and later: only when an item doesn't have highlighting yet
+if version >= 508 || !exists("did_st_syntax_inits")
+  if version < 508
+    let did_st_syntax_inits = 1
+    command -nargs=+ HiLink hi link <args>
+  else
+    command -nargs=+ HiLink hi def link <args>
+  endif
+
+  HiLink stKeyword		Statement
+  HiLink stMethod		Statement
+  HiLink stComment		Comment
+  HiLink stCharacter		Constant
+  HiLink stString		Constant
+  HiLink stSymbol		Special
+  HiLink stNumber		Type
+  HiLink stFloat		Type
+  HiLink stError		Error
+  HiLink stLocalVariables	Identifier
+  HiLink stBlockVariable	Identifier
+
+  delcommand HiLink
+endif
+
+let b:current_syntax = "st"
--- /dev/null
+++ b/lib/vimfiles/syntax/stata.vim
@@ -1,0 +1,451 @@
+" stata.vim -- Vim syntax file for Stata do, ado, and class files.
+" Language:	Stata and/or Mata
+" Maintainer:	Jeff Pitblado <jpitblado@stata.com>
+" Last Change:	26apr2006
+" Version:	1.1.4
+
+" Log:
+" 14apr2006	renamed syntax groups st* to stata*
+"		'syntax clear' only under version control
+"		check for 'b:current_syntax', removed 'did_stata_syntax_inits'
+" 17apr2006	fixed start expression for stataFunc
+" 26apr2006	fixed brace confusion in stataErrInParen and stataErrInBracket
+"		fixed paren/bracket confusion in stataFuncGroup
+
+if version < 600
+	syntax clear
+elseif exists("b:current_syntax")
+	finish
+endif
+
+syntax case match
+
+" comments - single line
+" note that the triple slash continuing line comment comes free
+syn region stataStarComment  start=/^\s*\*/ end=/$/    contains=stataComment oneline
+syn region stataSlashComment start="\s//"   end=/$/    contains=stataComment oneline
+syn region stataSlashComment start="^//"    end=/$/    contains=stataComment oneline
+" comments - multiple line
+syn region stataComment      start="/\*"    end="\*/"  contains=stataComment
+
+" global macros - simple case
+syn match  stataGlobal /\$\a\w*/
+" global macros - general case
+syn region stataGlobal start=/\${/ end=/}/ oneline contains=@stataMacroGroup
+" local macros - general case
+syn region stataLocal  start=/`/ end=/'/   oneline contains=@stataMacroGroup
+
+" numeric formats
+syn match  stataFormat /%-\=\d\+\.\d\+[efg]c\=/
+" numeric hex format
+syn match  stataFormat /%-\=21x/
+" string format
+syn match  stataFormat /%\(\|-\|\~\)\d\+s/
+
+" Statements
+syn keyword stataConditional else if
+syn keyword stataRepeat      foreach
+syn keyword stataRepeat      forv[alues]
+syn keyword stataRepeat      while
+
+" Common programming commands
+syn keyword stataCommand about
+syn keyword stataCommand adopath
+syn keyword stataCommand adoupdate
+syn keyword stataCommand assert
+syn keyword stataCommand break
+syn keyword stataCommand by
+syn keyword stataCommand cap[ture]
+syn keyword stataCommand cd
+syn keyword stataCommand chdir
+syn keyword stataCommand checksum
+syn keyword stataCommand class
+syn keyword stataCommand classutil
+syn keyword stataCommand compress
+syn keyword stataCommand conf[irm]
+syn keyword stataCommand conren
+syn keyword stataCommand continue
+syn keyword stataCommand cou[nt]
+syn keyword stataCommand cscript
+syn keyword stataCommand cscript_log
+syn keyword stataCommand #delimit
+syn keyword stataCommand d[escribe]
+syn keyword stataCommand dir
+syn keyword stataCommand discard
+syn keyword stataCommand di[splay]
+syn keyword stataCommand do
+syn keyword stataCommand doedit
+syn keyword stataCommand drop
+syn keyword stataCommand edit
+syn keyword stataCommand end
+syn keyword stataCommand erase
+syn keyword stataCommand eret[urn]
+syn keyword stataCommand err[or]
+syn keyword stataCommand e[xit]
+syn keyword stataCommand expand
+syn keyword stataCommand expandcl
+syn keyword stataCommand file
+syn keyword stataCommand findfile
+syn keyword stataCommand format
+syn keyword stataCommand g[enerate]
+syn keyword stataCommand gettoken
+syn keyword stataCommand gl[obal]
+syn keyword stataCommand help
+syn keyword stataCommand hexdump
+syn keyword stataCommand include
+syn keyword stataCommand infile
+syn keyword stataCommand infix
+syn keyword stataCommand input
+syn keyword stataCommand insheet
+syn keyword stataCommand joinby
+syn keyword stataCommand la[bel]
+syn keyword stataCommand levelsof
+syn keyword stataCommand list
+syn keyword stataCommand loc[al]
+syn keyword stataCommand log
+syn keyword stataCommand ma[cro]
+syn keyword stataCommand mark
+syn keyword stataCommand markout
+syn keyword stataCommand marksample
+syn keyword stataCommand mata
+syn keyword stataCommand matrix
+syn keyword stataCommand memory
+syn keyword stataCommand merge
+syn keyword stataCommand mkdir
+syn keyword stataCommand more
+syn keyword stataCommand net
+syn keyword stataCommand nobreak
+syn keyword stataCommand n[oisily]
+syn keyword stataCommand note[s]
+syn keyword stataCommand numlist
+syn keyword stataCommand outfile
+syn keyword stataCommand outsheet
+syn keyword stataCommand _parse
+syn keyword stataCommand pause
+syn keyword stataCommand plugin
+syn keyword stataCommand post
+syn keyword stataCommand postclose
+syn keyword stataCommand postfile
+syn keyword stataCommand preserve
+syn keyword stataCommand print
+syn keyword stataCommand printer
+syn keyword stataCommand profiler
+syn keyword stataCommand pr[ogram]
+syn keyword stataCommand q[uery]
+syn keyword stataCommand qui[etly]
+syn keyword stataCommand rcof
+syn keyword stataCommand reg[ress]
+syn keyword stataCommand rename
+syn keyword stataCommand repeat
+syn keyword stataCommand replace
+syn keyword stataCommand reshape
+syn keyword stataCommand ret[urn]
+syn keyword stataCommand _rmcoll
+syn keyword stataCommand _rmcoll
+syn keyword stataCommand _rmcollright
+syn keyword stataCommand rmdir
+syn keyword stataCommand _robust
+syn keyword stataCommand save
+syn keyword stataCommand sca[lar]
+syn keyword stataCommand search
+syn keyword stataCommand serset
+syn keyword stataCommand set
+syn keyword stataCommand shell
+syn keyword stataCommand sleep
+syn keyword stataCommand sort
+syn keyword stataCommand split
+syn keyword stataCommand sret[urn]
+syn keyword stataCommand ssc
+syn keyword stataCommand su[mmarize]
+syn keyword stataCommand syntax
+syn keyword stataCommand sysdescribe
+syn keyword stataCommand sysdir
+syn keyword stataCommand sysuse
+syn keyword stataCommand token[ize]
+syn keyword stataCommand translate
+syn keyword stataCommand type
+syn keyword stataCommand unab
+syn keyword stataCommand unabcmd
+syn keyword stataCommand update
+syn keyword stataCommand use
+syn keyword stataCommand vers[ion]
+syn keyword stataCommand view
+syn keyword stataCommand viewsource
+syn keyword stataCommand webdescribe
+syn keyword stataCommand webseek
+syn keyword stataCommand webuse
+syn keyword stataCommand which
+syn keyword stataCommand who
+syn keyword stataCommand window
+
+" Literals
+syn match  stataQuote   /"/
+syn region stataEString matchgroup=Nothing start=/`"/ end=/"'/ oneline contains=@stataMacroGroup,stataQuote,stataString,stataEString
+syn region stataString  matchgroup=Nothing start=/"/ end=/"/   oneline contains=@stataMacroGroup
+
+" define clusters
+syn cluster stataFuncGroup contains=@stataMacroGroup,stataFunc,stataString,stataEstring,stataParen,stataBracket
+syn cluster stataMacroGroup contains=stataGlobal,stataLocal
+syn cluster stataParenGroup contains=stataParenError,stataBracketError,stataBraceError,stataSpecial,stataFormat
+
+" Stata functions
+" Math
+syn region stataFunc matchgroup=Function start=/\<abs(/ end=/)/ contains=@stataFuncGroup
+syn region stataFunc matchgroup=Function start=/\<acos(/ end=/)/ contains=@stataFuncGroup
+syn region stataFunc matchgroup=Function start=/\<asin(/ end=/)/ contains=@stataFuncGroup
+syn region stataFunc matchgroup=Function start=/\<atan(/ end=/)/ contains=@stataFuncGroup
+syn region stataFunc matchgroup=Function start=/\<atan2(/ end=/)/ contains=@stataFuncGroup
+syn region stataFunc matchgroup=Function start=/\<atanh(/ end=/)/ contains=@stataFuncGroup
+syn region stataFunc matchgroup=Function start=/\<ceil(/ end=/)/ contains=@stataFuncGroup
+syn region stataFunc matchgroup=Function start=/\<cloglog(/ end=/)/ contains=@stataFuncGroup
+syn region stataFunc matchgroup=Function start=/\<comb(/ end=/)/ contains=@stataFuncGroup
+syn region stataFunc matchgroup=Function start=/\<cos(/ end=/)/ contains=@stataFuncGroup
+syn region stataFunc matchgroup=Function start=/\<digamma(/ end=/)/ contains=@stataFuncGroup
+syn region stataFunc matchgroup=Function start=/\<exp(/ end=/)/ contains=@stataFuncGroup
+syn region stataFunc matchgroup=Function start=/\<floor(/ end=/)/ contains=@stataFuncGroup
+syn region stataFunc matchgroup=Function start=/\<int(/ end=/)/ contains=@stataFuncGroup
+syn region stataFunc matchgroup=Function start=/\<invcloglog(/ end=/)/ contains=@stataFuncGroup
+syn region stataFunc matchgroup=Function start=/\<invlogit(/ end=/)/ contains=@stataFuncGroup
+syn region stataFunc matchgroup=Function start=/\<ln(/ end=/)/ contains=@stataFuncGroup
+syn region stataFunc matchgroup=Function start=/\<lnfact(/ end=/)/ contains=@stataFuncGroup
+syn region stataFunc matchgroup=Function start=/\<lnfactorial(/ end=/)/ contains=@stataFuncGroup
+syn region stataFunc matchgroup=Function start=/\<lngamma(/ end=/)/ contains=@stataFuncGroup
+syn region stataFunc matchgroup=Function start=/\<log(/ end=/)/ contains=@stataFuncGroup
+syn region stataFunc matchgroup=Function start=/\<log10(/ end=/)/ contains=@stataFuncGroup
+syn region stataFunc matchgroup=Function start=/\<logit(/ end=/)/ contains=@stataFuncGroup
+syn region stataFunc matchgroup=Function start=/\<max(/ end=/)/ contains=@stataFuncGroup
+syn region stataFunc matchgroup=Function start=/\<mod(/ end=/)/ contains=@stataFuncGroup
+syn region stataFunc matchgroup=Function start=/\<reldif(/ end=/)/ contains=@stataFuncGroup
+syn region stataFunc matchgroup=Function start=/\<round(/ end=/)/ contains=@stataFuncGroup
+syn region stataFunc matchgroup=Function start=/\<sign(/ end=/)/ contains=@stataFuncGroup
+syn region stataFunc matchgroup=Function start=/\<sin(/ end=/)/ contains=@stataFuncGroup
+syn region stataFunc matchgroup=Function start=/\<sqrt(/ end=/)/ contains=@stataFuncGroup
+syn region stataFunc matchgroup=Function start=/\<sum(/ end=/)/ contains=@stataFuncGroup
+syn region stataFunc matchgroup=Function start=/\<tan(/ end=/)/ contains=@stataFuncGroup
+syn region stataFunc matchgroup=Function start=/\<tanh(/ end=/)/ contains=@stataFuncGroup
+syn region stataFunc matchgroup=Function start=/\<trigamma(/ end=/)/ contains=@stataFuncGroup
+syn region stataFunc matchgroup=Function start=/\<trunc(/ end=/)/ contains=@stataFuncGroup
+" Probability distriubtions and density functions
+syn region stataFunc matchgroup=Function start=/\<betaden(/ end=/)/ contains=@stataFuncGroup
+syn region stataFunc matchgroup=Function start=/\<Binomial(/ end=/)/ contains=@stataFuncGroup
+syn region stataFunc matchgroup=Function start=/\<binorm(/ end=/)/ contains=@stataFuncGroup
+syn region stataFunc matchgroup=Function start=/\<binormal(/ end=/)/ contains=@stataFuncGroup
+syn region stataFunc matchgroup=Function start=/\<chi2(/ end=/)/ contains=@stataFuncGroup
+syn region stataFunc matchgroup=Function start=/\<chi2tail(/ end=/)/ contains=@stataFuncGroup
+syn region stataFunc matchgroup=Function start=/\<dgammapda(/ end=/)/ contains=@stataFuncGroup
+syn region stataFunc matchgroup=Function start=/\<dgammapdada(/ end=/)/ contains=@stataFuncGroup
+syn region stataFunc matchgroup=Function start=/\<dgammapdadx(/ end=/)/ contains=@stataFuncGroup
+syn region stataFunc matchgroup=Function start=/\<dgammapdx(/ end=/)/ contains=@stataFuncGroup
+syn region stataFunc matchgroup=Function start=/\<dgammapdxdx(/ end=/)/ contains=@stataFuncGroup
+syn region stataFunc matchgroup=Function start=/\<F(/ end=/)/ contains=@stataFuncGroup
+syn region stataFunc matchgroup=Function start=/\<Fden(/ end=/)/ contains=@stataFuncGroup
+syn region stataFunc matchgroup=Function start=/\<Ftail(/ end=/)/ contains=@stataFuncGroup
+syn region stataFunc matchgroup=Function start=/\<gammaden(/ end=/)/ contains=@stataFuncGroup
+syn region stataFunc matchgroup=Function start=/\<gammap(/ end=/)/ contains=@stataFuncGroup
+syn region stataFunc matchgroup=Function start=/\<ibeta(/ end=/)/ contains=@stataFuncGroup
+syn region stataFunc matchgroup=Function start=/\<invbinomial(/ end=/)/ contains=@stataFuncGroup
+syn region stataFunc matchgroup=Function start=/\<invchi2(/ end=/)/ contains=@stataFuncGroup
+syn region stataFunc matchgroup=Function start=/\<invchi2tail(/ end=/)/ contains=@stataFuncGroup
+syn region stataFunc matchgroup=Function start=/\<invF(/ end=/)/ contains=@stataFuncGroup
+syn region stataFunc matchgroup=Function start=/\<invFtail(/ end=/)/ contains=@stataFuncGroup
+syn region stataFunc matchgroup=Function start=/\<invgammap(/ end=/)/ contains=@stataFuncGroup
+syn region stataFunc matchgroup=Function start=/\<invibeta(/ end=/)/ contains=@stataFuncGroup
+syn region stataFunc matchgroup=Function start=/\<invnchi2(/ end=/)/ contains=@stataFuncGroup
+syn region stataFunc matchgroup=Function start=/\<invFtail(/ end=/)/ contains=@stataFuncGroup
+syn region stataFunc matchgroup=Function start=/\<invibeta(/ end=/)/ contains=@stataFuncGroup
+syn region stataFunc matchgroup=Function start=/\<invnorm(/ end=/)/ contains=@stataFuncGroup
+syn region stataFunc matchgroup=Function start=/\<invnormal(/ end=/)/ contains=@stataFuncGroup
+syn region stataFunc matchgroup=Function start=/\<invttail(/ end=/)/ contains=@stataFuncGroup
+syn region stataFunc matchgroup=Function start=/\<lnnormal(/ end=/)/ contains=@stataFuncGroup
+syn region stataFunc matchgroup=Function start=/\<lnnormalden(/ end=/)/ contains=@stataFuncGroup
+syn region stataFunc matchgroup=Function start=/\<nbetaden(/ end=/)/ contains=@stataFuncGroup
+syn region stataFunc matchgroup=Function start=/\<nchi2(/ end=/)/ contains=@stataFuncGroup
+syn region stataFunc matchgroup=Function start=/\<nFden(/ end=/)/ contains=@stataFuncGroup
+syn region stataFunc matchgroup=Function start=/\<nFtail(/ end=/)/ contains=@stataFuncGroup
+syn region stataFunc matchgroup=Function start=/\<nibeta(/ end=/)/ contains=@stataFuncGroup
+syn region stataFunc matchgroup=Function start=/\<norm(/ end=/)/ contains=@stataFuncGroup
+syn region stataFunc matchgroup=Function start=/\<normal(/ end=/)/ contains=@stataFuncGroup
+syn region stataFunc matchgroup=Function start=/\<normalden(/ end=/)/ contains=@stataFuncGroup
+syn region stataFunc matchgroup=Function start=/\<normden(/ end=/)/ contains=@stataFuncGroup
+syn region stataFunc matchgroup=Function start=/\<npnchi2(/ end=/)/ contains=@stataFuncGroup
+syn region stataFunc matchgroup=Function start=/\<tden(/ end=/)/ contains=@stataFuncGroup
+syn region stataFunc matchgroup=Function start=/\<ttail(/ end=/)/ contains=@stataFuncGroup
+" Random numbers
+syn region stataFunc matchgroup=Function start=/\<uniform(/ end=/)/ contains=@stataFuncGroup
+" String
+syn region stataFunc matchgroup=Function start=/\<abbrev(/ end=/)/ contains=@stataFuncGroup
+syn region stataFunc matchgroup=Function start=/\<hchar(/ end=/)/ contains=@stataFuncGroup
+syn region stataFunc matchgroup=Function start=/\<indexnot(/ end=/)/ contains=@stataFuncGroup
+syn region stataFunc matchgroup=Function start=/\<itrim(/ end=/)/ contains=@stataFuncGroup
+syn region stataFunc matchgroup=Function start=/\<length(/ end=/)/ contains=@stataFuncGroup
+syn region stataFunc matchgroup=Function start=/\<lower(/ end=/)/ contains=@stataFuncGroup
+syn region stataFunc matchgroup=Function start=/\<ltrim(/ end=/)/ contains=@stataFuncGroup
+syn region stataFunc matchgroup=Function start=/\<plural(/ end=/)/ contains=@stataFuncGroup
+syn region stataFunc matchgroup=Function start=/\<proper(/ end=/)/ contains=@stataFuncGroup
+syn region stataFunc matchgroup=Function start=/\<real(/ end=/)/ contains=@stataFuncGroup
+syn region stataFunc matchgroup=Function start=/\<regexm(/ end=/)/ contains=@stataFuncGroup
+syn region stataFunc matchgroup=Function start=/\<regexr(/ end=/)/ contains=@stataFuncGroup
+syn region stataFunc matchgroup=Function start=/\<regexs(/ end=/)/ contains=@stataFuncGroup
+syn region stataFunc matchgroup=Function start=/\<reverse(/ end=/)/ contains=@stataFuncGroup
+syn region stataFunc matchgroup=Function start=/\<rtrim(/ end=/)/ contains=@stataFuncGroup
+syn region stataFunc matchgroup=Function start=/\<string(/ end=/)/ contains=@stataFuncGroup
+syn region stataFunc matchgroup=Function start=/\<strlen(/ end=/)/ contains=@stataFuncGroup
+syn region stataFunc matchgroup=Function start=/\<strmatch(/ end=/)/ contains=@stataFuncGroup
+syn region stataFunc matchgroup=Function start=/\<strpos(/ end=/)/ contains=@stataFuncGroup
+syn region stataFunc matchgroup=Function start=/\<subinstr(/ end=/)/ contains=@stataFuncGroup
+syn region stataFunc matchgroup=Function start=/\<subinword(/ end=/)/ contains=@stataFuncGroup
+syn region stataFunc matchgroup=Function start=/\<substr(/ end=/)/ contains=@stataFuncGroup
+syn region stataFunc matchgroup=Function start=/\<trim(/ end=/)/ contains=@stataFuncGroup
+syn region stataFunc matchgroup=Function start=/\<upper(/ end=/)/ contains=@stataFuncGroup
+syn region stataFunc matchgroup=Function start=/\<word(/ end=/)/ contains=@stataFuncGroup
+syn region stataFunc matchgroup=Function start=/\<wordcount(/ end=/)/ contains=@stataFuncGroup
+" Programming
+syn region stataFunc matchgroup=Function start=/\<autocode(/ end=/)/ contains=@stataFuncGroup
+syn region stataFunc matchgroup=Function start=/\<byteorder(/ end=/)/ contains=@stataFuncGroup
+syn region stataFunc matchgroup=Function start=/\<c(/ end=/)/ contains=@stataFuncGroup
+syn region stataFunc matchgroup=Function start=/\<_caller(/ end=/)/ contains=@stataFuncGroup
+syn region stataFunc matchgroup=Function start=/\<chop(/ end=/)/ contains=@stataFuncGroup
+syn region stataFunc matchgroup=Function start=/\<clip(/ end=/)/ contains=@stataFuncGroup
+syn region stataFunc matchgroup=Function start=/\<cond(/ end=/)/ contains=@stataFuncGroup
+syn region stataFunc matchgroup=Function start=/\<e(/ end=/)/ contains=@stataFuncGroup
+syn region stataFunc matchgroup=Function start=/\<epsdouble(/ end=/)/ contains=@stataFuncGroup
+syn region stataFunc matchgroup=Function start=/\<epsfloat(/ end=/)/ contains=@stataFuncGroup
+syn region stataFunc matchgroup=Function start=/\<float(/ end=/)/ contains=@stataFuncGroup
+syn region stataFunc matchgroup=Function start=/\<has_eprop(/ end=/)/ contains=@stataFuncGroup
+syn region stataFunc matchgroup=Function start=/\<has_eprop(/ end=/)/ contains=@stataFuncGroup
+syn region stataFunc matchgroup=Function start=/\<inlist(/ end=/)/ contains=@stataFuncGroup
+syn region stataFunc matchgroup=Function start=/\<inrange(/ end=/)/ contains=@stataFuncGroup
+syn region stataFunc matchgroup=Function start=/\<irecode(/ end=/)/ contains=@stataFuncGroup
+syn region stataFunc matchgroup=Function start=/\<matrix(/ end=/)/ contains=@stataFuncGroup
+syn region stataFunc matchgroup=Function start=/\<maxbyte(/ end=/)/ contains=@stataFuncGroup
+syn region stataFunc matchgroup=Function start=/\<maxdouble(/ end=/)/ contains=@stataFuncGroup
+syn region stataFunc matchgroup=Function start=/\<maxfloat(/ end=/)/ contains=@stataFuncGroup
+syn region stataFunc matchgroup=Function start=/\<maxint(/ end=/)/ contains=@stataFuncGroup
+syn region stataFunc matchgroup=Function start=/\<maxlong(/ end=/)/ contains=@stataFuncGroup
+syn region stataFunc matchgroup=Function start=/\<mi(/ end=/)/ contains=@stataFuncGroup
+syn region stataFunc matchgroup=Function start=/\<minbyte(/ end=/)/ contains=@stataFuncGroup
+syn region stataFunc matchgroup=Function start=/\<mindouble(/ end=/)/ contains=@stataFuncGroup
+syn region stataFunc matchgroup=Function start=/\<minfloat(/ end=/)/ contains=@stataFuncGroup
+syn region stataFunc matchgroup=Function start=/\<minint(/ end=/)/ contains=@stataFuncGroup
+syn region stataFunc matchgroup=Function start=/\<minlong(/ end=/)/ contains=@stataFuncGroup
+syn region stataFunc matchgroup=Function start=/\<missing(/ end=/)/ contains=@stataFuncGroup
+syn region stataFunc matchgroup=Function start=/\<r(/ end=/)/ contains=@stataFuncGroup
+syn region stataFunc matchgroup=Function start=/\<recode(/ end=/)/ contains=@stataFuncGroup
+syn region stataFunc matchgroup=Function start=/\<replay(/ end=/)/ contains=@stataFuncGroup
+syn region stataFunc matchgroup=Function start=/\<return(/ end=/)/ contains=@stataFuncGroup
+syn region stataFunc matchgroup=Function start=/\<s(/ end=/)/ contains=@stataFuncGroup
+syn region stataFunc matchgroup=Function start=/\<scalar(/ end=/)/ contains=@stataFuncGroup
+" Date
+syn region stataFunc matchgroup=Function start=/\<d(/ end=/)/ contains=@stataFuncGroup
+syn region stataFunc matchgroup=Function start=/\<date(/ end=/)/ contains=@stataFuncGroup
+syn region stataFunc matchgroup=Function start=/\<day(/ end=/)/ contains=@stataFuncGroup
+syn region stataFunc matchgroup=Function start=/\<dow(/ end=/)/ contains=@stataFuncGroup
+syn region stataFunc matchgroup=Function start=/\<doy(/ end=/)/ contains=@stataFuncGroup
+syn region stataFunc matchgroup=Function start=/\<halfyear(/ end=/)/ contains=@stataFuncGroup
+syn region stataFunc matchgroup=Function start=/\<mdy(/ end=/)/ contains=@stataFuncGroup
+syn region stataFunc matchgroup=Function start=/\<month(/ end=/)/ contains=@stataFuncGroup
+syn region stataFunc matchgroup=Function start=/\<quarter(/ end=/)/ contains=@stataFuncGroup
+syn region stataFunc matchgroup=Function start=/\<week(/ end=/)/ contains=@stataFuncGroup
+syn region stataFunc matchgroup=Function start=/\<year(/ end=/)/ contains=@stataFuncGroup
+" Time-series
+syn region stataFunc matchgroup=Function start=/\<daily(/ end=/)/ contains=@stataFuncGroup
+syn region stataFunc matchgroup=Function start=/\<halfyearly(/ end=/)/ contains=@stataFuncGroup
+syn region stataFunc matchgroup=Function start=/\<monthly(/ end=/)/ contains=@stataFuncGroup
+syn region stataFunc matchgroup=Function start=/\<quarterly(/ end=/)/ contains=@stataFuncGroup
+syn region stataFunc matchgroup=Function start=/\<weekly(/ end=/)/ contains=@stataFuncGroup
+syn region stataFunc matchgroup=Function start=/\<yearly(/ end=/)/ contains=@stataFuncGroup
+"
+syn region stataFunc matchgroup=Function start=/\<yh(/ end=/)/ contains=@stataFuncGroup
+syn region stataFunc matchgroup=Function start=/\<ym(/ end=/)/ contains=@stataFuncGroup
+syn region stataFunc matchgroup=Function start=/\<yq(/ end=/)/ contains=@stataFuncGroup
+syn region stataFunc matchgroup=Function start=/\<yw(/ end=/)/ contains=@stataFuncGroup
+"
+syn region stataFunc matchgroup=Function start=/\<d(/ end=/)/ contains=@stataFuncGroup
+syn region stataFunc matchgroup=Function start=/\<h(/ end=/)/ contains=@stataFuncGroup
+syn region stataFunc matchgroup=Function start=/\<m(/ end=/)/ contains=@stataFuncGroup
+syn region stataFunc matchgroup=Function start=/\<q(/ end=/)/ contains=@stataFuncGroup
+syn region stataFunc matchgroup=Function start=/\<w(/ end=/)/ contains=@stataFuncGroup
+syn region stataFunc matchgroup=Function start=/\<y(/ end=/)/ contains=@stataFuncGroup
+"
+syn region stataFunc matchgroup=Function start=/\<dofd(/ end=/)/ contains=@stataFuncGroup
+syn region stataFunc matchgroup=Function start=/\<dofh(/ end=/)/ contains=@stataFuncGroup
+syn region stataFunc matchgroup=Function start=/\<dofm(/ end=/)/ contains=@stataFuncGroup
+syn region stataFunc matchgroup=Function start=/\<dofq(/ end=/)/ contains=@stataFuncGroup
+syn region stataFunc matchgroup=Function start=/\<dofw(/ end=/)/ contains=@stataFuncGroup
+syn region stataFunc matchgroup=Function start=/\<dofy(/ end=/)/ contains=@stataFuncGroup
+syn region stataFunc matchgroup=Function start=/\<hofd(/ end=/)/ contains=@stataFuncGroup
+syn region stataFunc matchgroup=Function start=/\<mofd(/ end=/)/ contains=@stataFuncGroup
+syn region stataFunc matchgroup=Function start=/\<qofd(/ end=/)/ contains=@stataFuncGroup
+syn region stataFunc matchgroup=Function start=/\<wofd(/ end=/)/ contains=@stataFuncGroup
+syn region stataFunc matchgroup=Function start=/\<yofd(/ end=/)/ contains=@stataFuncGroup
+"
+syn region stataFunc matchgroup=Function start=/\<tin(/ end=/)/ contains=@stataFuncGroup
+syn region stataFunc matchgroup=Function start=/\<twithin(/ end=/)/ contains=@stataFuncGroup
+" Matrix
+syn region stataFunc matchgroup=Function start=/\<colnumb(/ end=/)/ contains=@stataFuncGroup
+syn region stataFunc matchgroup=Function start=/\<colsof(/ end=/)/ contains=@stataFuncGroup
+syn region stataFunc matchgroup=Function start=/\<det(/ end=/)/ contains=@stataFuncGroup
+syn region stataFunc matchgroup=Function start=/\<diag0cnt(/ end=/)/ contains=@stataFuncGroup
+syn region stataFunc matchgroup=Function start=/\<el(/ end=/)/ contains=@stataFuncGroup
+syn region stataFunc matchgroup=Function start=/\<issymmetric(/ end=/)/ contains=@stataFuncGroup
+syn region stataFunc matchgroup=Function start=/\<matmissing(/ end=/)/ contains=@stataFuncGroup
+syn region stataFunc matchgroup=Function start=/\<mreldif(/ end=/)/ contains=@stataFuncGroup
+syn region stataFunc matchgroup=Function start=/\<rownumb(/ end=/)/ contains=@stataFuncGroup
+syn region stataFunc matchgroup=Function start=/\<rowsof(/ end=/)/ contains=@stataFuncGroup
+syn region stataFunc matchgroup=Function start=/\<trace(/ end=/)/ contains=@stataFuncGroup
+"
+syn region stataFunc matchgroup=Function start=/\<cholsky(/ end=/)/ contains=@stataFuncGroup
+syn region stataFunc matchgroup=Function start=/\<corr(/ end=/)/ contains=@stataFuncGroup
+syn region stataFunc matchgroup=Function start=/\<diag(/ end=/)/ contains=@stataFuncGroup
+syn region stataFunc matchgroup=Function start=/\<get(/ end=/)/ contains=@stataFuncGroup
+syn region stataFunc matchgroup=Function start=/\<hadamard(/ end=/)/ contains=@stataFuncGroup
+syn region stataFunc matchgroup=Function start=/\<I(/ end=/)/ contains=@stataFuncGroup
+syn region stataFunc matchgroup=Function start=/\<inv(/ end=/)/ contains=@stataFuncGroup
+syn region stataFunc matchgroup=Function start=/\<invsym(/ end=/)/ contains=@stataFuncGroup
+syn region stataFunc matchgroup=Function start=/\<J(/ end=/)/ contains=@stataFuncGroup
+syn region stataFunc matchgroup=Function start=/\<matuniform(/ end=/)/ contains=@stataFuncGroup
+syn region stataFunc matchgroup=Function start=/\<nullmat(/ end=/)/ contains=@stataFuncGroup
+syn region stataFunc matchgroup=Function start=/\<sweep(/ end=/)/ contains=@stataFuncGroup
+syn region stataFunc matchgroup=Function start=/\<vec(/ end=/)/ contains=@stataFuncGroup
+syn region stataFunc matchgroup=Function start=/\<vecdiag(/ end=/)/ contains=@stataFuncGroup
+
+" Errors to catch
+" taken from $VIMRUNTIME/syntax/c.vim 
+" catch errors caused by wrong parenthesis, braces and brackets
+syn region	stataParen	transparent start=/(/ end=/)/  contains=ALLBUT,@stataParenGroup,stataErrInBracket,stataErrInBrace
+syn region	stataBracket	transparent start=/\[/ end=/]/ contains=ALLBUT,@stataParenGroup,stataErrInParen,stataErrInBrace
+syn region	stataBrace	transparent start=/{/ end=/}/  contains=ALLBUT,@stataParenGroup,stataErrInParen,stataErrInBracket
+syn match	stataParenError	/[\])}]/
+syn match	stataBracketError	/]/
+syn match	stataBraceError	/}/
+syn match	stataErrInParen	contained /[\]}]/
+syn match	stataErrInBracket	contained /[)}]/
+syn match	stataErrInBrace	contained /[)\]]/
+
+" assign highlight groups
+hi def link stataBraceError	stataError
+hi def link stataBracketError	stataError
+hi def link stataErrInBrace	stataError
+hi def link stataErrInBracket	stataError
+hi def link stataErrInParen	stataError
+hi def link stataEString	stataString
+hi def link stataFormat		stataSpecial
+hi def link stataGlobal		stataMacro
+hi def link stataLocal		stataMacro
+hi def link stataParenError	stataError
+hi def link stataSlashComment	stataComment
+hi def link stataStarComment	stataComment
+
+hi def link stataCommand	Define
+hi def link stataComment	Comment
+hi def link stataConditional	Conditional
+hi def link stataError		Error
+hi def link stataFunc		None
+hi def link stataMacro		Define
+hi def link stataRepeat		Repeat
+hi def link stataSpecial	SpecialChar
+hi def link stataString		String
+
+let b:current_syntax = "stata"
+
+" vim: ts=8
--- /dev/null
+++ b/lib/vimfiles/syntax/stp.vim
@@ -1,0 +1,167 @@
+" Vim syntax file
+"    Language: Stored Procedures (STP)
+"  Maintainer: Jeff Lanzarotta (jefflanzarotta@yahoo.com)
+"	  URL: http://lanzarotta.tripod.com/vim/syntax/stp.vim.zip
+" Last Change: March 05, 2002
+
+" For version 5.x, clear all syntax items.
+" For version 6.x, quit when a syntax file was already loaded.
+if version < 600
+  syntax clear
+elseif exists("b:current_syntax")
+  finish
+endif
+
+syn case ignore
+
+" Specials.
+syn keyword stpSpecial    null
+
+" Keywords.
+syn keyword stpKeyword begin break call case create deallocate dynamic
+syn keyword stpKeyword execute from function go grant
+syn keyword stpKeyword index insert into leave max min on output procedure
+syn keyword stpKeyword public result return returns scroll table to
+syn keyword stpKeyword when
+syn match   stpKeyword "\<end\>"
+
+" Conditional.
+syn keyword stpConditional if else elseif then
+syn match   stpConditional "\<end\s\+if\>"
+
+" Repeats.
+syn keyword stpRepeat for while loop
+syn match   stpRepeat "\<end\s\+loop\>"
+
+" Operators.
+syn keyword stpOperator asc not and or desc group having in is any some all
+syn keyword stpOperator between exists like escape with union intersect minus
+syn keyword stpOperator out prior distinct sysdate
+
+" Statements.
+syn keyword stpStatement alter analyze as audit avg by close clustered comment
+syn keyword stpStatement commit continue count create cursor declare delete
+syn keyword stpStatement drop exec execute explain fetch from index insert
+syn keyword stpStatement into lock max min next noaudit nonclustered open
+syn keyword stpStatement order output print raiserror recompile rename revoke
+syn keyword stpStatement rollback savepoint select set sum transaction
+syn keyword stpStatement truncate unique update values where
+
+" Functions.
+syn keyword stpFunction abs acos ascii asin atan atn2 avg ceiling charindex
+syn keyword stpFunction charlength convert col_name col_length cos cot count
+syn keyword stpFunction curunreservedpgs datapgs datalength dateadd datediff
+syn keyword stpFunction datename datepart db_id db_name degree difference
+syn keyword stpFunction exp floor getdate hextoint host_id host_name index_col
+syn keyword stpFunction inttohex isnull lct_admin log log10 lower ltrim max
+syn keyword stpFunction min now object_id object_name patindex pi pos power
+syn keyword stpFunction proc_role radians rand replace replicate reserved_pgs
+syn keyword stpFunction reverse right rtrim rowcnt round show_role sign sin
+syn keyword stpFunction soundex space sqrt str stuff substr substring sum
+syn keyword stpFunction suser_id suser_name tan tsequal upper used_pgs user
+syn keyword stpFunction user_id user_name valid_name valid_user message
+
+" Types.
+syn keyword stpType binary bit char datetime decimal double float image
+syn keyword stpType int integer long money nchar numeric precision real
+syn keyword stpType smalldatetime smallint smallmoney text time tinyint
+syn keyword stpType timestamp varbinary varchar
+
+" Globals.
+syn match stpGlobals '@@char_convert'
+syn match stpGlobals '@@cient_csname'
+syn match stpGlobals '@@client_csid'
+syn match stpGlobals '@@connections'
+syn match stpGlobals '@@cpu_busy'
+syn match stpGlobals '@@error'
+syn match stpGlobals '@@identity'
+syn match stpGlobals '@@idle'
+syn match stpGlobals '@@io_busy'
+syn match stpGlobals '@@isolation'
+syn match stpGlobals '@@langid'
+syn match stpGlobals '@@language'
+syn match stpGlobals '@@max_connections'
+syn match stpGlobals '@@maxcharlen'
+syn match stpGlobals '@@ncharsize'
+syn match stpGlobals '@@nestlevel'
+syn match stpGlobals '@@pack_received'
+syn match stpGlobals '@@pack_sent'
+syn match stpGlobals '@@packet_errors'
+syn match stpGlobals '@@procid'
+syn match stpGlobals '@@rowcount'
+syn match stpGlobals '@@servername'
+syn match stpGlobals '@@spid'
+syn match stpGlobals '@@sqlstatus'
+syn match stpGlobals '@@testts'
+syn match stpGlobals '@@textcolid'
+syn match stpGlobals '@@textdbid'
+syn match stpGlobals '@@textobjid'
+syn match stpGlobals '@@textptr'
+syn match stpGlobals '@@textsize'
+syn match stpGlobals '@@thresh_hysteresis'
+syn match stpGlobals '@@timeticks'
+syn match stpGlobals '@@total_error'
+syn match stpGlobals '@@total_read'
+syn match stpGlobals '@@total_write'
+syn match stpGlobals '@@tranchained'
+syn match stpGlobals '@@trancount'
+syn match stpGlobals '@@transtate'
+syn match stpGlobals '@@version'
+
+" Todos.
+syn keyword stpTodo TODO FIXME XXX DEBUG NOTE
+
+" Strings and characters.
+syn match stpStringError "'.*$"
+syn match stpString "'\([^']\|''\)*'"
+
+" Numbers.
+syn match stpNumber "-\=\<\d*\.\=[0-9_]\>"
+
+" Comments.
+syn region stpComment start="/\*" end="\*/" contains=stpTodo
+syn match  stpComment "--.*" contains=stpTodo
+syn sync   ccomment stpComment
+
+" Parens.
+syn region stpParen transparent start='(' end=')' contains=ALLBUT,stpParenError
+syn match  stpParenError ")"
+
+" Syntax Synchronizing.
+syn sync minlines=10 maxlines=100
+
+" Define the default highlighting.
+" For version 5.x and earlier, only when not done already.
+" For version 5.8 and later, only when and item doesn't have highlighting yet.
+if version >= 508 || !exists("did_stp_syn_inits")
+  if version < 508
+    let did_stp_syn_inits = 1
+    command -nargs=+ HiLink hi link <args>
+  else
+    command -nargs=+ HiLink hi def link <args>
+  endif
+
+  HiLink stpConditional Conditional
+  HiLink stpComment Comment
+  HiLink stpKeyword Keyword
+  HiLink stpNumber Number
+  HiLink stpOperator Operator
+  HiLink stpSpecial Special
+  HiLink stpStatement Statement
+  HiLink stpString String
+  HiLink stpStringError Error
+  HiLink stpType Type
+  HiLink stpTodo Todo
+  HiLink stpFunction Function
+  HiLink stpGlobals Macro
+  HiLink stpParen Normal
+  HiLink stpParenError Error
+  HiLink stpSQLKeyword Function
+  HiLink stpRepeat Repeat
+
+  delcommand HiLink
+endif
+
+let b:current_syntax = "stp"
+
+" vim ts=8 sw=2
--- /dev/null
+++ b/lib/vimfiles/syntax/strace.vim
@@ -1,0 +1,66 @@
+" Vim syntax file
+" This is a GENERATED FILE. Please always refer to source file at the URI below.
+" Language: strace output
+" Maintainer: David Ne\v{c}as (Yeti) <yeti@physics.muni.cz>
+" Last Change: 2002-10-10
+" URL: http://trific.ath.cx/Ftp/vim/syntax/strace.vim
+
+" Setup
+if version >= 600
+	if exists("b:current_syntax")
+		finish
+	endif
+else
+	syntax clear
+endif
+
+syn case match
+
+" Parse the line
+syn match straceSpecialChar "\\\d\d\d\|\\." contained
+syn region straceString start=+"+ skip=+\\\\\|\\"+ end=+"+ contains=straceSpecialChar oneline
+syn match straceNumber "\W[+-]\=\(\d\+\)\=\.\=\d\+\([eE][+-]\=\d\+\)\="lc=1
+syn match straceNumber "\W0x\x\+"lc=1
+syn match straceNumberRHS "\W\(0x\x\+\|-\=\d\+\)"lc=1 contained
+syn match straceOtherRHS "?" contained
+syn match straceConstant "[A-Z_]\{2,}"
+syn region straceVerbosed start="(" end=")" matchgroup=Normal contained oneline
+syn region straceReturned start="\s=\s" end="$" contains=StraceEquals,straceNumberRHS,straceOtherRHS,straceConstant,straceVerbosed oneline transparent
+syn match straceEquals "\s=\s"ms=s+1,me=e-1
+syn match straceParenthesis "[][(){}]"
+syn match straceSysCall "^\w\+"
+syn match straceOtherPID "^\[[^]]*\]" contains=stracePID,straceNumber nextgroup=straceSysCallEmbed skipwhite
+syn match straceSysCallEmbed "\w\+" contained
+syn keyword stracePID pid contained
+syn match straceOperator "[-+=*/!%&|:,]"
+syn region straceComment start="/\*" end="\*/" oneline
+
+" Define the default highlighting
+if version >= 508 || !exists("did_strace_syntax_inits")
+	if version < 508
+		let did_strace_syntax_inits = 1
+		command -nargs=+ HiLink hi link <args>
+	else
+		command -nargs=+ HiLink hi def link <args>
+	endif
+
+	HiLink straceComment Comment
+	HiLink straceVerbosed Comment
+	HiLink stracePID PreProc
+	HiLink straceNumber Number
+	HiLink straceNumberRHS Type
+	HiLink straceOtherRHS Type
+	HiLink straceString String
+	HiLink straceConstant Function
+	HiLink straceEquals Type
+	HiLink straceSysCallEmbed straceSysCall
+	HiLink straceSysCall Statement
+	HiLink straceParenthesis Statement
+	HiLink straceOperator Normal
+	HiLink straceSpecialChar Special
+	HiLink straceOtherPID PreProc
+
+	delcommand HiLink
+endif
+
+let b:current_syntax = "strace"
--- /dev/null
+++ b/lib/vimfiles/syntax/sudoers.vim
@@ -1,0 +1,266 @@
+" Vim syntax file
+" Language:         sudoers(5) configuration files
+" Maintainer:       Nikolai Weibull <now@bitwi.se>
+" Latest Revision:  2006-04-19
+
+if exists("b:current_syntax")
+  finish
+endif
+
+let s:cpo_save = &cpo
+set cpo&vim
+
+" TODO: instead of 'skipnl', we would like to match a specific group that would
+" match \\$ and then continue with the nextgroup, actually, the skipnl doesn't
+" work...
+" TODO: treat 'ALL' like a special (yay, a bundle of new rules!!!)
+
+syn match   sudoersUserSpec '^' nextgroup=@sudoersUserInSpec skipwhite
+
+syn match   sudoersSpecEquals         contained '=' nextgroup=@sudoersCmndSpecList skipwhite
+
+syn cluster sudoersCmndSpecList       contains=sudoersUserRunasBegin,sudoersPASSWD,@sudoersCmndInSpec
+
+syn keyword sudoersTodo               contained TODO FIXME XXX NOTE
+
+syn region  sudoersComment            display oneline start='#' end='$' contains=sudoersTodo
+
+syn keyword sudoersAlias              User_Alias Runas_Alias nextgroup=sudoersUserAlias skipwhite skipnl
+syn keyword sudoersAlias              Host_Alias nextgroup=sudoersHostAlias skipwhite skipnl
+syn keyword sudoersAlias              Cmnd_Alias nextgroup=sudoersCmndAlias skipwhite skipnl
+
+syn match   sudoersUserAlias          contained '\<\u[A-Z0-9_]*\>'  nextgroup=sudoersUserAliasEquals  skipwhite skipnl
+syn match   sudoersUserNameInList     contained '\<\l\+\>'          nextgroup=@sudoersUserList        skipwhite skipnl
+syn match   sudoersUIDInList          contained '#\d\+\>'           nextgroup=@sudoersUserList        skipwhite skipnl
+syn match   sudoersGroupInList        contained '%\l\+\>'           nextgroup=@sudoersUserList        skipwhite skipnl
+syn match   sudoersUserNetgroupInList contained '+\l\+\>'           nextgroup=@sudoersUserList        skipwhite skipnl
+syn match   sudoersUserAliasInList    contained '\<\u[A-Z0-9_]*\>'  nextgroup=@sudoersUserList        skipwhite skipnl
+
+syn match   sudoersUserName           contained '\<\l\+\>'          nextgroup=@sudoersParameter       skipwhite skipnl
+syn match   sudoersUID                contained '#\d\+\>'           nextgroup=@sudoersParameter       skipwhite skipnl
+syn match   sudoersGroup              contained '%\l\+\>'           nextgroup=@sudoersParameter       skipwhite skipnl
+syn match   sudoersUserNetgroup       contained '+\l\+\>'           nextgroup=@sudoersParameter       skipwhite skipnl
+syn match   sudoersUserAliasRef       contained '\<\u[A-Z0-9_]*\>'  nextgroup=@sudoersParameter       skipwhite skipnl
+
+syn match   sudoersUserNameInSpec     contained '\<\l\+\>'          nextgroup=@sudoersUserSpec        skipwhite skipnl
+syn match   sudoersUIDInSpec          contained '#\d\+\>'           nextgroup=@sudoersUserSpec        skipwhite skipnl
+syn match   sudoersGroupInSpec        contained '%\l\+\>'           nextgroup=@sudoersUserSpec        skipwhite skipnl
+syn match   sudoersUserNetgroupInSpec contained '+\l\+\>'           nextgroup=@sudoersUserSpec        skipwhite skipnl
+syn match   sudoersUserAliasInSpec    contained '\<\u[A-Z0-9_]*\>'  nextgroup=@sudoersUserSpec        skipwhite skipnl
+
+syn match   sudoersUserNameInRunas    contained '\<\l\+\>'          nextgroup=@sudoersUserRunas       skipwhite skipnl
+syn match   sudoersUIDInRunas         contained '#\d\+\>'           nextgroup=@sudoersUserRunas       skipwhite skipnl
+syn match   sudoersGroupInRunas       contained '%\l\+\>'           nextgroup=@sudoersUserRunas       skipwhite skipnl
+syn match   sudoersUserNetgroupInRunas contained '+\l\+\>'          nextgroup=@sudoersUserRunas       skipwhite skipnl
+syn match   sudoersUserAliasInRunas   contained '\<\u[A-Z0-9_]*\>'  nextgroup=@sudoersUserRunas       skipwhite skipnl
+
+syn match   sudoersHostAlias          contained '\<\u[A-Z0-9_]*\>'  nextgroup=sudoersHostAliasEquals  skipwhite skipnl
+syn match   sudoersHostNameInList     contained '\<\l\+\>'          nextgroup=@sudoersHostList        skipwhite skipnl
+syn match   sudoersIPAddrInList       contained '\%(\d\{1,3}\.\)\{3}\d\{1,3}' nextgroup=@sudoersHostList skipwhite skipnl
+syn match   sudoersNetworkInList      contained '\%(\d\{1,3}\.\)\{3}\d\{1,3}\%(/\%(\%(\d\{1,3}\.\)\{3}\d\{1,3}\|\d\+\)\)\=' nextgroup=@sudoersHostList skipwhite skipnl
+syn match   sudoersHostNetgroupInList contained '+\l\+\>'           nextgroup=@sudoersHostList        skipwhite skipnl
+syn match   sudoersHostAliasInList    contained '\<\u[A-Z0-9_]*\>'  nextgroup=@sudoersHostList        skipwhite skipnl
+
+syn match   sudoersHostName           contained '\<\l\+\>'          nextgroup=@sudoersParameter       skipwhite skipnl
+syn match   sudoersIPAddr             contained '\%(\d\{1,3}\.\)\{3}\d\{1,3}' nextgroup=@sudoersParameter skipwhite skipnl
+syn match   sudoersNetwork            contained '\%(\d\{1,3}\.\)\{3}\d\{1,3}\%(/\%(\%(\d\{1,3}\.\)\{3}\d\{1,3}\|\d\+\)\)\=' nextgroup=@sudoersParameter skipwhite skipnl
+syn match   sudoersHostNetgroup       contained '+\l\+\>'           nextgroup=@sudoersParameter       skipwhite skipnl
+syn match   sudoersHostAliasRef       contained '\<\u[A-Z0-9_]*\>'  nextgroup=@sudoersParameter       skipwhite skipnl
+
+syn match   sudoersHostNameInSpec     contained '\<\l\+\>'          nextgroup=@sudoersHostSpec        skipwhite skipnl
+syn match   sudoersIPAddrInSpec       contained '\%(\d\{1,3}\.\)\{3}\d\{1,3}' nextgroup=@sudoersHostSpec skipwhite skipnl
+syn match   sudoersNetworkInSpec      contained '\%(\d\{1,3}\.\)\{3}\d\{1,3}\%(/\%(\%(\d\{1,3}\.\)\{3}\d\{1,3}\|\d\+\)\)\=' nextgroup=@sudoersHostSpec skipwhite skipnl
+syn match   sudoersHostNetgroupInSpec contained '+\l\+\>'           nextgroup=@sudoersHostSpec        skipwhite skipnl
+syn match   sudoersHostAliasInSpec    contained '\<\u[A-Z0-9_]*\>'  nextgroup=@sudoersHostSpec        skipwhite skipnl
+
+syn match   sudoersCmndAlias          contained '\<\u[A-Z0-9_]*\>'  nextgroup=sudoersCmndAliasEquals  skipwhite skipnl
+syn match   sudoersCmndNameInList     contained '[^[:space:],:=\\]\+\%(\\[[:space:],:=\\][^[:space:],:=\\]*\)*' nextgroup=@sudoersCmndList,sudoersCommandEmpty,sudoersCommandArgs skipwhite
+syn match   sudoersCmndAliasInList    contained '\<\u[A-Z0-9_]*\>'  nextgroup=@sudoersCmndList        skipwhite skipnl
+
+syn match   sudoersCmndNameInSpec     contained '[^[:space:],:=\\]\+\%(\\[[:space:],:=\\][^[:space:],:=\\]*\)*' nextgroup=@sudoersCmndSpec,sudoersCommandEmptyInSpec,sudoersCommandArgsInSpec skipwhite
+syn match   sudoersCmndAliasInSpec    contained '\<\u[A-Z0-9_]*\>'  nextgroup=@sudoersCmndSpec        skipwhite skipnl
+
+syn match   sudoersUserAliasEquals  contained '=' nextgroup=@sudoersUserInList  skipwhite skipnl
+syn match   sudoersUserListComma    contained ',' nextgroup=@sudoersUserInList  skipwhite skipnl
+syn match   sudoersUserListColon    contained ':' nextgroup=sudoersUserAlias    skipwhite skipnl
+syn cluster sudoersUserList         contains=sudoersUserListComma,sudoersUserListColon
+
+syn match   sudoersUserSpecComma    contained ',' nextgroup=@sudoersUserInSpec  skipwhite skipnl
+syn cluster sudoersUserSpec         contains=sudoersUserSpecComma,@sudoersHostInSpec
+
+syn match   sudoersUserRunasBegin   contained '(' nextgroup=@sudoersUserInRunas skipwhite skipnl
+syn match   sudoersUserRunasComma   contained ',' nextgroup=@sudoersUserInRunas skipwhite skipnl
+syn match   sudoersUserRunasEnd     contained ')' nextgroup=sudoersPASSWD,@sudoersCmndInSpec skipwhite skipnl
+syn cluster sudoersUserRunas        contains=sudoersUserRunasComma,@sudoersUserInRunas,sudoersUserRunasEnd
+
+
+syn match   sudoersHostAliasEquals  contained '=' nextgroup=@sudoersHostInList  skipwhite skipnl
+syn match   sudoersHostListComma    contained ',' nextgroup=@sudoersHostInList  skipwhite skipnl
+syn match   sudoersHostListColon    contained ':' nextgroup=sudoersHostAlias    skipwhite skipnl
+syn cluster sudoersHostList         contains=sudoersHostListComma,sudoersHostListColon
+
+syn match   sudoersHostSpecComma    contained ',' nextgroup=@sudoersHostInSpec  skipwhite skipnl
+syn cluster sudoersHostSpec         contains=sudoersHostSpecComma,sudoersSpecEquals
+
+
+syn match   sudoersCmndAliasEquals  contained '=' nextgroup=@sudoersCmndInList  skipwhite skipnl
+syn match   sudoersCmndListComma    contained ',' nextgroup=@sudoersCmndInList  skipwhite skipnl
+syn match   sudoersCmndListColon    contained ':' nextgroup=sudoersCmndAlias    skipwhite skipnl
+syn cluster sudoersCmndList         contains=sudoersCmndListComma,sudoersCmndListColon
+
+syn match   sudoersCmndSpecComma    contained ',' nextgroup=@sudoersCmndSpecList skipwhite skipnl
+syn match   sudoersCmndSpecColon    contained ':' nextgroup=@sudoersUserInSpec  skipwhite skipnl
+syn cluster sudoersCmndSpec         contains=sudoersCmndSpecComma,sudoersCmndSpecColon
+
+syn cluster sudoersUserInList       contains=sudoersUserNegationInList,sudoersUserNameInList,sudoersUIDInList,sudoersGroupInList,sudoersUserNetgroupInList,sudoersUserAliasInList
+syn cluster sudoersHostInList       contains=sudoersHostNegationInList,sudoersHostNameInList,sudoersIPAddrInList,sudoersNetworkInList,sudoersHostNetgroupInList,sudoersHostAliasInList
+syn cluster sudoersCmndInList       contains=sudoersCmndNegationInList,sudoersCmndNameInList,sudoersCmndAliasInList
+
+syn cluster sudoersUser             contains=sudoersUserNegation,sudoersUserName,sudoersUID,sudoersGroup,sudoersUserNetgroup,sudoersUserAliasRef
+syn cluster sudoersHost             contains=sudoersHostNegation,sudoersHostName,sudoersIPAddr,sudoersNetwork,sudoersHostNetgroup,sudoersHostAliasRef
+
+syn cluster sudoersUserInSpec       contains=sudoersUserNegationInSpec,sudoersUserNameInSpec,sudoersUIDInSpec,sudoersGroupInSpec,sudoersUserNetgroupInSpec,sudoersUserAliasInSpec
+syn cluster sudoersHostInSpec       contains=sudoersHostNegationInSpec,sudoersHostNameInSpec,sudoersIPAddrInSpec,sudoersNetworkInSpec,sudoersHostNetgroupInSpec,sudoersHostAliasInSpec
+syn cluster sudoersUserInRunas      contains=sudoersUserNegationInRunas,sudoersUserNameInRunas,sudoersUIDInRunas,sudoersGroupInRunas,sudoersUserNetgroupInRunas,sudoersUserAliasInRunas
+syn cluster sudoersCmndInSpec       contains=sudoersCmndNegationInSpec,sudoersCmndNameInSpec,sudoersCmndAliasInSpec
+
+syn match   sudoersUserNegationInList contained '!\+' nextgroup=@sudoersUserInList  skipwhite skipnl
+syn match   sudoersHostNegationInList contained '!\+' nextgroup=@sudoersHostInList  skipwhite skipnl
+syn match   sudoersCmndNegationInList contained '!\+' nextgroup=@sudoersCmndInList  skipwhite skipnl
+
+syn match   sudoersUserNegation       contained '!\+' nextgroup=@sudoersUser        skipwhite skipnl
+syn match   sudoersHostNegation       contained '!\+' nextgroup=@sudoersHost        skipwhite skipnl
+
+syn match   sudoersUserNegationInSpec contained '!\+' nextgroup=@sudoersUserInSpec  skipwhite skipnl
+syn match   sudoersHostNegationInSpec contained '!\+' nextgroup=@sudoersHostInSpec  skipwhite skipnl
+syn match   sudoersUserNegationInRunas contained '!\+' nextgroup=@sudoersUserInRunas skipwhite skipnl
+syn match   sudoersCmndNegationInSpec contained '!\+' nextgroup=@sudoersCmndInSpec  skipwhite skipnl
+
+syn match   sudoersCommandArgs      contained '[^[:space:],:=\\]\+\%(\\[[:space:],:=\\][^[:space:],:=\\]*\)*' nextgroup=sudoersCommandArgs,@sudoersCmndList skipwhite
+syn match   sudoersCommandEmpty     contained '""' nextgroup=@sudoersCmndList skipwhite skipnl
+
+syn match   sudoersCommandArgsInSpec contained '[^[:space:],:=\\]\+\%(\\[[:space:],:=\\][^[:space:],:=\\]*\)*' nextgroup=sudoersCommandArgsInSpec,@sudoersCmndSpec skipwhite
+syn match   sudoersCommandEmptyInSpec contained '""' nextgroup=@sudoersCmndSpec skipwhite skipnl
+
+syn keyword sudoersDefaultEntry Defaults nextgroup=sudoersDefaultTypeAt,sudoersDefaultTypeColon,sudoersDefaultTypeGreaterThan,@sudoersParameter skipwhite skipnl
+syn match   sudoersDefaultTypeAt          contained '@' nextgroup=@sudoersHost skipwhite skipnl
+syn match   sudoersDefaultTypeColon       contained ':' nextgroup=@sudoersUser skipwhite skipnl
+syn match   sudoersDefaultTypeGreaterThan contained '>' nextgroup=@sudoersUser skipwhite skipnl
+
+" TODO: could also deal with special characters here
+syn match   sudoersBooleanParameter contained '!' nextgroup=sudoersBooleanParameter skipwhite skipnl
+syn keyword sudoersBooleanParameter contained long_opt_prompt ignore_dot mail_always mail_badpass mail_no_user mail_no_perms tty_tickets lecture authenticate root_sudo log_host log_year shell_noargs set_home always_set_home path_info preserve_groups fqdn insults requiretty env_editor rootpw runaspw targetpw set_logname stay_setuid env_reset use_loginclass nextgroup=sudoersParameterListComma skipwhite skipnl
+syn keyword sudoersIntegerParameter contained passwd_tries loglinelen timestamp_timeout passwd_timeout umask nextgroup=sudoersIntegerParameterEquals skipwhite skipnl
+syn keyword sudoersStringParameter  contained mailsub badpass_message timestampdir timestampowner passprompt runas_default syslog_goodpri syslog_badpri editor logfile syslog mailerpath mailerflags mailto exempt_group verifypw listpw nextgroup=sudoersStringParameterEquals skipwhite skipnl
+syn keyword sudoersListParameter    contained env_check env_delete env_keep nextgroup=sudoersListParameterEquals skipwhite skipnl
+
+syn match   sudoersParameterListComma contained ',' nextgroup=@sudoersParameter skipwhite skipnl
+
+syn cluster sudoersParameter        contains=sudoersBooleanParameter,sudoersIntegerParameterEquals,sudoersStringParameter,sudoersListParameter
+
+syn match   sudoersIntegerParameterEquals contained '[+-]\==' nextgroup=sudoersIntegerValue skipwhite skipnl
+syn match   sudoersStringParameterEquals  contained '[+-]\==' nextgroup=sudoersStringValue  skipwhite skipnl
+syn match   sudoersListParameterEquals    contained '[+-]\==' nextgroup=sudoersListValue    skipwhite skipnl
+
+syn match   sudoersIntegerValue contained '\d\+' nextgroup=sudoersParameterListComma skipwhite skipnl
+syn match   sudoersStringValue  contained '[^[:space:],:=\\]*\%(\\[[:space:],:=\\][^[:space:],:=\\]*\)*' nextgroup=sudoersParameterListComma skipwhite skipnl
+syn region  sudoersStringValue  contained start=+"+ skip=+\\"+ end=+"+ nextgroup=sudoersParameterListComma skipwhite skipnl
+syn match   sudoersListValue    contained '[^[:space:],:=\\]*\%(\\[[:space:],:=\\][^[:space:],:=\\]*\)*' nextgroup=sudoersParameterListComma skipwhite skipnl
+syn region  sudoersListValue    contained start=+"+ skip=+\\"+ end=+"+ nextgroup=sudoersParameterListComma skipwhite skipnl
+
+syn match   sudoersPASSWD                   contained '\%(NO\)\=PASSWD:' nextgroup=@sudoersCmndInSpec skipwhite
+
+hi def link sudoersSpecEquals               Operator
+hi def link sudoersTodo                     Todo
+hi def link sudoersComment                  Comment
+hi def link sudoersAlias                    Keyword
+hi def link sudoersUserAlias                Identifier
+hi def link sudoersUserNameInList           String
+hi def link sudoersUIDInList                Number
+hi def link sudoersGroupInList              PreProc
+hi def link sudoersUserNetgroupInList       PreProc
+hi def link sudoersUserAliasInList          PreProc
+hi def link sudoersUserName                 String
+hi def link sudoersUID                      Number
+hi def link sudoersGroup                    PreProc
+hi def link sudoersUserNetgroup             PreProc
+hi def link sudoersUserAliasRef             PreProc
+hi def link sudoersUserNameInSpec           String
+hi def link sudoersUIDInSpec                Number
+hi def link sudoersGroupInSpec              PreProc
+hi def link sudoersUserNetgroupInSpec       PreProc
+hi def link sudoersUserAliasInSpec          PreProc
+hi def link sudoersUserNameInRunas          String
+hi def link sudoersUIDInRunas               Number
+hi def link sudoersGroupInRunas             PreProc
+hi def link sudoersUserNetgroupInRunas      PreProc
+hi def link sudoersUserAliasInRunas         PreProc
+hi def link sudoersHostAlias                Identifier
+hi def link sudoersHostNameInList           String
+hi def link sudoersIPAddrInList             Number
+hi def link sudoersNetworkInList            Number
+hi def link sudoersHostNetgroupInList       PreProc
+hi def link sudoersHostAliasInList          PreProc
+hi def link sudoersHostName                 String
+hi def link sudoersIPAddr                   Number
+hi def link sudoersNetwork                  Number
+hi def link sudoersHostNetgroup             PreProc
+hi def link sudoersHostAliasRef             PreProc
+hi def link sudoersHostNameInSpec           String
+hi def link sudoersIPAddrInSpec             Number
+hi def link sudoersNetworkInSpec            Number
+hi def link sudoersHostNetgroupInSpec       PreProc
+hi def link sudoersHostAliasInSpec          PreProc
+hi def link sudoersCmndAlias                Identifier
+hi def link sudoersCmndNameInList           String
+hi def link sudoersCmndAliasInList          PreProc
+hi def link sudoersCmndNameInSpec           String
+hi def link sudoersCmndAliasInSpec          PreProc
+hi def link sudoersUserAliasEquals          Operator
+hi def link sudoersUserListComma            Delimiter
+hi def link sudoersUserListColon            Delimiter
+hi def link sudoersUserSpecComma            Delimiter
+hi def link sudoersUserRunasBegin           Delimiter
+hi def link sudoersUserRunasComma           Delimiter
+hi def link sudoersUserRunasEnd             Delimiter
+hi def link sudoersHostAliasEquals          Operator
+hi def link sudoersHostListComma            Delimiter
+hi def link sudoersHostListColon            Delimiter
+hi def link sudoersHostSpecComma            Delimiter
+hi def link sudoersCmndAliasEquals          Operator
+hi def link sudoersCmndListComma            Delimiter
+hi def link sudoersCmndListColon            Delimiter
+hi def link sudoersCmndSpecComma            Delimiter
+hi def link sudoersCmndSpecColon            Delimiter
+hi def link sudoersUserNegationInList       Operator
+hi def link sudoersHostNegationInList       Operator
+hi def link sudoersCmndNegationInList       Operator
+hi def link sudoersUserNegation             Operator
+hi def link sudoersHostNegation             Operator
+hi def link sudoersUserNegationInSpec       Operator
+hi def link sudoersHostNegationInSpec       Operator
+hi def link sudoersUserNegationInRunas      Operator
+hi def link sudoersCmndNegationInSpec       Operator
+hi def link sudoersCommandArgs              String
+hi def link sudoersCommandEmpty             Special
+hi def link sudoersDefaultEntry             Keyword
+hi def link sudoersDefaultTypeAt            Special
+hi def link sudoersDefaultTypeColon         Special
+hi def link sudoersDefaultTypeGreaterThan   Special
+hi def link sudoersBooleanParameter         Identifier
+hi def link sudoersIntegerParameter         Identifier
+hi def link sudoersStringParameter          Identifier
+hi def link sudoersListParameter            Identifier
+hi def link sudoersParameterListComma       Delimiter
+hi def link sudoersIntegerParameterEquals   Operator
+hi def link sudoersStringParameterEquals    Operator
+hi def link sudoersListParameterEquals      Operator
+hi def link sudoersIntegerValue             Number
+hi def link sudoersStringValue              String
+hi def link sudoersListValue                String
+hi def link sudoersPASSWD                   Special
+
+let b:current_syntax = "sudoers"
+
+let &cpo = s:cpo_save
+unlet s:cpo_save
--- /dev/null
+++ b/lib/vimfiles/syntax/svn.vim
@@ -1,0 +1,50 @@
+" Vim syntax file
+" Language:     Subversion (svn) commit file
+" Maintainer:   Dmitry Vasiliev <dima at hlabs dot spb dot ru>
+" URL:          http://www.hlabs.spb.ru/vim/svn.vim
+" Revision:     $Id: svn.vim,v 1.2 2006/03/27 16:27:07 vimboss Exp $
+" Filenames:    svn-commit*.tmp
+" Version:      1.5
+
+" Contributors:
+"   Stefano Zacchiroli
+
+" For version 5.x: Clear all syntax items.
+" For version 6.x: Quit when a syntax file was already loaded.
+if version < 600
+  syntax clear
+elseif exists("b:current_syntax")
+  finish
+endif
+
+syn region svnRegion    start="^--.*--$" end="\%$" contains=ALL
+syn match svnRemoved    "^D    .*$" contained
+syn match svnAdded      "^A[ M]   .*$" contained
+syn match svnModified   "^M[ M]   .*$" contained
+syn match svnProperty   "^_M   .*$" contained
+
+" Synchronization.
+syn sync clear
+syn sync match svnSync  grouphere svnRegion "^--.*--$"me=s-1
+
+" Define the default highlighting.
+" For version 5.7 and earlier: only when not done already.
+" For version 5.8 and later: only when an item doesn't have highlighting yet.
+if version >= 508 || !exists("did_svn_syn_inits")
+  if version <= 508
+    let did_svn_syn_inits = 1
+    command -nargs=+ HiLink hi link <args>
+  else
+    command -nargs=+ HiLink hi def link <args>
+  endif
+
+  HiLink svnRegion      Comment
+  HiLink svnRemoved     Constant
+  HiLink svnAdded       Identifier
+  HiLink svnModified    Special
+  HiLink svnProperty    Special
+
+  delcommand HiLink
+endif
+
+let b:current_syntax = "svn"
--- /dev/null
+++ b/lib/vimfiles/syntax/syncolor.vim
@@ -1,0 +1,85 @@
+" Vim syntax support file
+" Maintainer:	Bram Moolenaar <Bram@vim.org>
+" Last Change:	2001 Sep 12
+
+" This file sets up the default methods for highlighting.
+" It is loaded from "synload.vim" and from Vim for ":syntax reset".
+" Also used from init_highlight().
+
+if !exists("syntax_cmd") || syntax_cmd == "on"
+  " ":syntax on" works like in Vim 5.7: set colors but keep links
+  command -nargs=* SynColor hi <args>
+  command -nargs=* SynLink hi link <args>
+else
+  if syntax_cmd == "enable"
+    " ":syntax enable" keeps any existing colors
+    command -nargs=* SynColor hi def <args>
+    command -nargs=* SynLink hi def link <args>
+  elseif syntax_cmd == "reset"
+    " ":syntax reset" resets all colors to the default
+    command -nargs=* SynColor hi <args>
+    command -nargs=* SynLink hi! link <args>
+  else
+    " User defined syncolor file has already set the colors.
+    finish
+  endif
+endif
+
+" Many terminals can only use six different colors (plus black and white).
+" Therefore the number of colors used is kept low. It doesn't look nice with
+" too many colors anyway.
+" Careful with "cterm=bold", it changes the color to bright for some terminals.
+" There are two sets of defaults: for a dark and a light background.
+if &background == "dark"
+  SynColor Comment	term=bold cterm=NONE ctermfg=Cyan ctermbg=NONE gui=NONE guifg=#80a0ff guibg=NONE
+  SynColor Constant	term=underline cterm=NONE ctermfg=Magenta ctermbg=NONE gui=NONE guifg=#ffa0a0 guibg=NONE
+  SynColor Special	term=bold cterm=NONE ctermfg=LightRed ctermbg=NONE gui=NONE guifg=Orange guibg=NONE
+  SynColor Identifier	term=underline cterm=bold ctermfg=Cyan ctermbg=NONE gui=NONE guifg=#40ffff guibg=NONE
+  SynColor Statement	term=bold cterm=NONE ctermfg=Yellow ctermbg=NONE gui=bold guifg=#ffff60 guibg=NONE
+  SynColor PreProc	term=underline cterm=NONE ctermfg=LightBlue ctermbg=NONE gui=NONE guifg=#ff80ff guibg=NONE
+  SynColor Type		term=underline cterm=NONE ctermfg=LightGreen ctermbg=NONE gui=bold guifg=#60ff60 guibg=NONE
+  SynColor Underlined	term=underline cterm=underline ctermfg=LightBlue gui=underline guifg=#80a0ff
+  SynColor Ignore	term=NONE cterm=NONE ctermfg=black ctermbg=NONE gui=NONE guifg=bg guibg=NONE
+else
+  SynColor Comment	term=bold cterm=NONE ctermfg=DarkBlue ctermbg=NONE gui=NONE guifg=Blue guibg=NONE
+  SynColor Constant	term=underline cterm=NONE ctermfg=DarkRed ctermbg=NONE gui=NONE guifg=Magenta guibg=NONE
+  SynColor Special	term=bold cterm=NONE ctermfg=DarkMagenta ctermbg=NONE gui=NONE guifg=SlateBlue guibg=NONE
+  SynColor Identifier	term=underline cterm=NONE ctermfg=DarkCyan ctermbg=NONE gui=NONE guifg=DarkCyan guibg=NONE
+  SynColor Statement	term=bold cterm=NONE ctermfg=Brown ctermbg=NONE gui=bold guifg=Brown guibg=NONE
+  SynColor PreProc	term=underline cterm=NONE ctermfg=DarkMagenta ctermbg=NONE gui=NONE guifg=Purple guibg=NONE
+  SynColor Type		term=underline cterm=NONE ctermfg=DarkGreen ctermbg=NONE gui=bold guifg=SeaGreen guibg=NONE
+  SynColor Underlined	term=underline cterm=underline ctermfg=DarkMagenta gui=underline guifg=SlateBlue
+  SynColor Ignore	term=NONE cterm=NONE ctermfg=white ctermbg=NONE gui=NONE guifg=bg guibg=NONE
+endif
+SynColor Error		term=reverse cterm=NONE ctermfg=White ctermbg=Red gui=NONE guifg=White guibg=Red
+SynColor Todo		term=standout cterm=NONE ctermfg=Black ctermbg=Yellow gui=NONE guifg=Blue guibg=Yellow
+
+" Common groups that link to default highlighting.
+" You can specify other highlighting easily.
+SynLink String		Constant
+SynLink Character	Constant
+SynLink Number		Constant
+SynLink Boolean		Constant
+SynLink Float		Number
+SynLink Function	Identifier
+SynLink Conditional	Statement
+SynLink Repeat		Statement
+SynLink Label		Statement
+SynLink Operator	Statement
+SynLink Keyword		Statement
+SynLink Exception	Statement
+SynLink Include		PreProc
+SynLink Define		PreProc
+SynLink Macro		PreProc
+SynLink PreCondit	PreProc
+SynLink StorageClass	Type
+SynLink Structure	Type
+SynLink Typedef		Type
+SynLink Tag		Special
+SynLink SpecialChar	Special
+SynLink Delimiter	Special
+SynLink SpecialComment	Special
+SynLink Debug		Special
+
+delcommand SynColor
+delcommand SynLink
--- /dev/null
+++ b/lib/vimfiles/syntax/synload.vim
@@ -1,0 +1,76 @@
+" Vim syntax support file
+" Maintainer:	Bram Moolenaar <Bram@vim.org>
+" Last Change:	2006 Apr 30
+
+" This file sets up for syntax highlighting.
+" It is loaded from "syntax.vim" and "manual.vim".
+" 1. Set the default highlight groups.
+" 2. Install Syntax autocommands for all the available syntax files.
+
+if !has("syntax")
+  finish
+endif
+
+" let others know that syntax has been switched on
+let syntax_on = 1
+
+" Set the default highlighting colors.  Use a color scheme if specified.
+if exists("colors_name")
+  exe "colors " . colors_name
+else
+  runtime! syntax/syncolor.vim
+endif
+
+" Line continuation is used here, remove 'C' from 'cpoptions'
+let s:cpo_save = &cpo
+set cpo&vim
+
+" First remove all old syntax autocommands.
+au! Syntax
+
+au Syntax *		call s:SynSet()
+
+fun! s:SynSet()
+  " clear syntax for :set syntax=OFF  and any syntax name that doesn't exist
+  syn clear
+  if exists("b:current_syntax")
+    unlet b:current_syntax
+  endif
+
+  let s = expand("<amatch>")
+  if s == "ON"
+    " :set syntax=ON
+    if &filetype == ""
+      echohl ErrorMsg
+      echo "filetype unknown"
+      echohl None
+    endif
+    let s = &filetype
+  endif
+
+  if s != ""
+    " Load the syntax file(s).  When there are several, separated by dots,
+    " load each in sequence.
+    for name in split(s, '\.')
+      exe "runtime! syntax/" . name . ".vim syntax/" . name . "/*.vim"
+    endfor
+  endif
+endfun
+
+
+" Handle adding doxygen to other languages (C, C++, IDL)
+au Syntax cpp,c,idl
+	\ if (exists('b:load_doxygen_syntax') && b:load_doxygen_syntax)
+	\	|| (exists('g:load_doxygen_syntax') && g:load_doxygen_syntax)
+	\   | runtime! syntax/doxygen.vim
+	\ | endif
+
+
+" Source the user-specified syntax highlighting file
+if exists("mysyntaxfile") && filereadable(expand(mysyntaxfile))
+  execute "source " . mysyntaxfile
+endif
+
+" Restore 'cpoptions'
+let &cpo = s:cpo_save
+unlet s:cpo_save
--- /dev/null
+++ b/lib/vimfiles/syntax/syntax.vim
@@ -1,0 +1,43 @@
+" Vim syntax support file
+" Maintainer:	Bram Moolenaar <Bram@vim.org>
+" Last Change:	2001 Sep 04
+
+" This file is used for ":syntax on".
+" It installs the autocommands and starts highlighting for all buffers.
+
+if !has("syntax")
+  finish
+endif
+
+" If Syntax highlighting appears to be on already, turn it off first, so that
+" any leftovers are cleared.
+if exists("syntax_on") || exists("syntax_manual")
+  so <sfile>:p:h/nosyntax.vim
+endif
+
+" Load the Syntax autocommands and set the default methods for highlighting.
+runtime syntax/synload.vim
+
+" Load the FileType autocommands if not done yet.
+if exists("did_load_filetypes")
+  let s:did_ft = 1
+else
+  filetype on
+  let s:did_ft = 0
+endif
+
+" Set up the connection between FileType and Syntax autocommands.
+" This makes the syntax automatically set when the file type is detected.
+augroup syntaxset
+  au! FileType *	exe "set syntax=" . expand("<amatch>")
+augroup END
+
+
+" Execute the syntax autocommands for the each buffer.
+" If the filetype wasn't detected yet, do that now.
+" Always do the syntaxset autocommands, for buffers where the 'filetype'
+" already was set manually (e.g., help buffers).
+doautoall syntaxset FileType
+if !s:did_ft
+  doautoall filetypedetect BufRead
+endif
--- /dev/null
+++ b/lib/vimfiles/syntax/sysctl.vim
@@ -1,0 +1,39 @@
+" Vim syntax file
+" Language:         sysctl.conf(5) configuration file
+" Maintainer:       Nikolai Weibull <now@bitwi.se>
+" Latest Revision:  2006-04-19
+
+if exists("b:current_syntax")
+  finish
+endif
+
+let s:cpo_save = &cpo
+set cpo&vim
+
+syn match   sysctlBegin   display '^'
+                          \ nextgroup=sysctlToken,sysctlComment skipwhite
+
+syn match   sysctlToken   contained display '\S\+'
+                          \ nextgroup=sysctlTokenEq skipwhite
+
+syn match   sysctlTokenEq contained display '=' nextgroup=sysctlValue skipwhite
+
+syn region  sysctlValue   contained display oneline
+                          \ matchgroup=sysctlValue start='\S'
+                          \ matchgroup=Normal end='\s*$'
+
+syn keyword sysctlTodo    contained TODO FIXME XXX NOTE
+
+syn region  sysctlComment display oneline start='^\s*[#;]' end='$'
+                          \ contains=sysctlTodo,@Spell
+
+hi def link sysctlTodo    Todo
+hi def link sysctlComment Comment
+hi def link sysctlToken   Identifier
+hi def link sysctlTokenEq Operator
+hi def link sysctlValue   String
+
+let b:current_syntax = "sysctl"
+
+let &cpo = s:cpo_save
+unlet s:cpo_save
--- /dev/null
+++ b/lib/vimfiles/syntax/tads.vim
@@ -1,0 +1,184 @@
+" Vim syntax file
+" Language:	TADS
+" Maintainer:	Amir Karger <karger@post.harvard.edu>
+" $Date: 2004/06/13 19:28:45 $
+" $Revision: 1.1 $
+" Stolen from: Bram Moolenaar's C language file
+" Newest version at: http://www.hec.utah.edu/~karger/vim/syntax/tads.vim
+" History info at the bottom of the file
+
+" TODO lots more keywords
+" global, self, etc. are special *objects*, not functions. They should
+" probably be a different color than the special functions
+" Actually, should cvtstr etc. be functions?! (change tadsFunction)
+" Make global etc. into Identifiers, since we don't have regular variables?
+
+" For version 5.x: Clear all syntax items
+" For version 6.x: Quit when a syntax file was already loaded
+if version < 600
+  syntax clear
+elseif exists("b:current_syntax")
+  finish
+endif
+
+" A bunch of useful keywords
+syn keyword tadsStatement	goto break return continue pass
+syn keyword tadsLabel		case default
+syn keyword tadsConditional	if else switch
+syn keyword tadsRepeat		while for do
+syn keyword tadsStorageClass	local compoundWord formatstring specialWords
+syn keyword tadsBoolean		nil true
+
+" TADS keywords
+syn keyword tadsKeyword		replace modify
+syn keyword tadsKeyword		global self inherited
+" builtin functions
+syn keyword tadsKeyword		cvtstr cvtnum caps lower upper substr
+syn keyword tadsKeyword		say length
+syn keyword tadsKeyword		setit setscore
+syn keyword tadsKeyword		datatype proptype
+syn keyword tadsKeyword		car cdr
+syn keyword tadsKeyword		defined isclass
+syn keyword tadsKeyword		find firstobj nextobj
+syn keyword tadsKeyword		getarg argcount
+syn keyword tadsKeyword		input yorn askfile
+syn keyword tadsKeyword		rand randomize
+syn keyword tadsKeyword		restart restore quit save undo
+syn keyword tadsException	abort exit exitobj
+
+syn keyword tadsTodo contained	TODO FIXME XXX
+
+" String and Character constants
+" Highlight special characters (those which have a backslash) differently
+syn match tadsSpecial contained	"\\."
+syn region tadsDoubleString		start=+"+ skip=+\\\\\|\\"+ end=+"+ contains=tadsSpecial,tadsEmbedded
+syn region tadsSingleString		start=+'+ skip=+\\\\\|\\'+ end=+'+ contains=tadsSpecial
+" Embedded expressions in strings
+syn region tadsEmbedded contained       start="<<" end=">>" contains=tadsKeyword
+
+" TADS doesn't have \xxx, right?
+"syn match cSpecial contained	"\\[0-7][0-7][0-7]\=\|\\."
+"syn match cSpecialCharacter	"'\\[0-7][0-7]'"
+"syn match cSpecialCharacter	"'\\[0-7][0-7][0-7]'"
+
+"catch errors caused by wrong parenthesis
+"syn region cParen		transparent start='(' end=')' contains=ALLBUT,cParenError,cIncluded,cSpecial,cTodo,cUserCont,cUserLabel
+"syn match cParenError		")"
+"syn match cInParen contained	"[{}]"
+syn region tadsBrace		transparent start='{' end='}' contains=ALLBUT,tadsBraceError,tadsIncluded,tadsSpecial,tadsTodo
+syn match tadsBraceError		"}"
+
+"integer number (TADS has no floating point numbers)
+syn case ignore
+syn match tadsNumber		"\<[0-9]\+\>"
+"hex number
+syn match tadsNumber		"\<0x[0-9a-f]\+\>"
+syn match tadsIdentifier	"\<[a-z][a-z0-9_$]*\>"
+syn case match
+" flag an octal number with wrong digits
+syn match tadsOctalError		"\<0[0-7]*[89]"
+
+" Removed complicated c_comment_strings
+syn region tadsComment		start="/\*" end="\*/" contains=tadsTodo
+syn match tadsComment		"//.*" contains=tadsTodo
+syntax match tadsCommentError	"\*/"
+
+syn region tadsPreCondit	start="^\s*#\s*\(if\>\|ifdef\>\|ifndef\>\|elif\>\|else\>\|endif\>\)" skip="\\$" end="$" contains=tadsComment,tadsString,tadsNumber,tadsCommentError
+syn region tadsIncluded contained start=+"+ skip=+\\\\\|\\"+ end=+"+
+syn match tadsIncluded contained "<[^>]*>"
+syn match tadsInclude		"^\s*#\s*include\>\s*["<]" contains=tadsIncluded
+syn region tadsDefine		start="^\s*#\s*\(define\>\|undef\>\)" skip="\\$" end="$" contains=ALLBUT,tadsPreCondit,tadsIncluded,tadsInclude,tadsDefine,tadsInBrace,tadsIdentifier
+
+syn region tadsPreProc start="^\s*#\s*\(pragma\>\|line\>\|warning\>\|warn\>\|error\>\)" skip="\\$" end="$" contains=ALLBUT,tadsPreCondit,tadsIncluded,tadsInclude,tadsDefine,tadsInParen,tadsIdentifier
+
+" Highlight User Labels
+" TODO labels for gotos?
+"syn region	cMulti		transparent start='?' end=':' contains=ALLBUT,cIncluded,cSpecial,cTodo,cUserCont,cUserLabel,cBitField
+" Avoid matching foo::bar() in C++ by requiring that the next char is not ':'
+"syn match	cUserCont	"^\s*\I\i*\s*:$" contains=cUserLabel
+"syn match	cUserCont	";\s*\I\i*\s*:$" contains=cUserLabel
+"syn match	cUserCont	"^\s*\I\i*\s*:[^:]" contains=cUserLabel
+"syn match	cUserCont	";\s*\I\i*\s*:[^:]" contains=cUserLabel
+
+"syn match	cUserLabel	"\I\i*" contained
+
+" identifier: class-name [, class-name [...]] [property-list] ;
+" Don't highlight comment in class def
+syn match tadsClassDef		"\<class\>[^/]*" contains=tadsObjectDef,tadsClass
+syn match tadsClass contained   "\<class\>"
+syn match tadsObjectDef "\<[a-zA-Z][a-zA-Z0-9_$]*\s*:\s*[a-zA-Z0-9_$]\+\(\s*,\s*[a-zA-Z][a-zA-Z0-9_$]*\)*\(\s*;\)\="
+syn keyword tadsFunction contained function
+syn match tadsFunctionDef	 "\<[a-zA-Z][a-zA-Z0-9_$]*\s*:\s*function[^{]*" contains=tadsFunction
+"syn region tadsObject		  transparent start = '[a-zA-Z][\i$]\s*:\s*' end=";" contains=tadsBrace,tadsObjectDef
+
+" How far back do we go to find matching groups
+if !exists("tads_minlines")
+  let tads_minlines = 15
+endif
+exec "syn sync ccomment tadsComment minlines=" . tads_minlines
+if !exists("tads_sync_dist")
+  let tads_sync_dist = 100
+endif
+execute "syn sync maxlines=" . tads_sync_dist
+
+" Define the default highlighting.
+" For version 5.7 and earlier: only when not done already
+" For version 5.8 and later: only when an item doesn't have highlighting yet
+if version >= 508 || !exists("did_tads_syn_inits")
+  if version < 508
+    let did_tads_syn_inits = 1
+    command -nargs=+ HiLink hi link <args>
+  else
+    command -nargs=+ HiLink hi def link <args>
+  endif
+
+  " The default methods for highlighting.  Can be overridden later
+  HiLink tadsFunctionDef Function
+  HiLink tadsFunction  Structure
+  HiLink tadsClass     Structure
+  HiLink tadsClassDef  Identifier
+  HiLink tadsObjectDef Identifier
+" no highlight for tadsEmbedded, so it prints as normal text w/in the string
+
+  HiLink tadsOperator	Operator
+  HiLink tadsStructure	Structure
+  HiLink tadsTodo	Todo
+  HiLink tadsLabel	Label
+  HiLink tadsConditional	Conditional
+  HiLink tadsRepeat	Repeat
+  HiLink tadsException	Exception
+  HiLink tadsStatement	Statement
+  HiLink tadsStorageClass	StorageClass
+  HiLink tadsKeyWord   Keyword
+  HiLink tadsSpecial	SpecialChar
+  HiLink tadsNumber	Number
+  HiLink tadsBoolean	Boolean
+  HiLink tadsDoubleString	tadsString
+  HiLink tadsSingleString	tadsString
+
+  HiLink tadsOctalError	tadsError
+  HiLink tadsCommentError	tadsError
+  HiLink tadsBraceError	tadsError
+  HiLink tadsInBrace	tadsError
+  HiLink tadsError	Error
+
+  HiLink tadsInclude	Include
+  HiLink tadsPreProc	PreProc
+  HiLink tadsDefine	Macro
+  HiLink tadsIncluded	tadsString
+  HiLink tadsPreCondit	PreCondit
+
+  HiLink tadsString	String
+  HiLink tadsComment	Comment
+
+  delcommand HiLink
+endif
+
+
+let b:current_syntax = "tads"
+
+" Changes:
+" 11/18/99 Added a bunch of TADS functions, tadsException
+" 10/22/99 Misspelled Moolenaar (sorry!), c_minlines to tads_minlines
+"
+" vim: ts=8
--- /dev/null
+++ b/lib/vimfiles/syntax/tags.vim
@@ -1,0 +1,47 @@
+" Language:		tags
+" Maintainer:	Dr. Charles E. Campbell, Jr.  <NdrOchip@PcampbellAfamily.Mbiz>
+" Last Change:	Sep 06, 2005
+" Version:		3
+" URL:	http://mysite.verizon.net/astronaut/vim/index.html#vimlinks_syntax
+
+" For version 5.x: Clear all syntax items
+" For version 6.x: Quit when a syntax file was already loaded
+if version < 600
+  syntax clear
+elseif exists("b:current_syntax")
+  finish
+endif
+
+syn match	tagName	"^[^\t]\+"		skipwhite	nextgroup=tagPath
+syn match	tagPath	"[^\t]\+"	contained	skipwhite	nextgroup=tagAddr	contains=tagBaseFile
+syn match	tagBaseFile	"[a-zA-Z_]\+[\.a-zA-Z_0-9]*\t"me=e-1		contained
+syn match	tagAddr	"\d*"	contained skipwhite nextgroup=tagComment
+syn region	tagAddr	matchgroup=tagDelim start="/" skip="\(\\\\\)*\\/" matchgroup=tagDelim end="$\|/" oneline contained skipwhite nextgroup=tagComment
+syn match	tagComment	";.*$"	contained contains=tagField
+syn match	tagComment	"^!_TAG_.*$"
+syn match	tagField	contained "[a-z]*:"
+
+" Define the default highlighting.
+" For version 5.7 and earlier: only when not done already
+" For version 5.8 and later: only when an item doesn't have highlighting yet
+if version >= 508 || !exists("did_drchip_tags_inits")
+  if version < 508
+    let did_drchip_tags_inits = 1
+    command -nargs=+ HiLink hi link <args>
+  else
+    command -nargs=+ HiLink hi def link <args>
+  endif
+
+  HiLink tagBaseFile	PreProc
+  HiLink tagComment	Comment
+  HiLink tagDelim	Delimiter
+  HiLink tagField	Number
+  HiLink tagName	Identifier
+  HiLink tagPath	PreProc
+
+  delcommand HiLink
+endif
+
+let b:current_syntax = "tags"
+
+" vim: ts=12
--- /dev/null
+++ b/lib/vimfiles/syntax/tak.vim
@@ -1,0 +1,136 @@
+" Vim syntax file
+" Language:     TAK2, TAK3, TAK2000 thermal modeling input file
+" Maintainer:   Adrian Nagle, anagle@ball.com
+" Last Change:  2003 May 11
+" Filenames:    *.tak
+" URL:		http://www.naglenet.org/vim/syntax/tak.vim
+" MAIN URL:     http://www.naglenet.org/vim/
+
+
+
+" For version 5.x: Clear all syntax items
+" For version 6.x: Quit when a syntax file was already loaded
+if version < 600
+  syntax clear
+elseif exists("b:current_syntax")
+  finish
+endif
+
+
+
+" Ignore case
+syn case ignore
+
+
+
+"
+"
+" Begin syntax definitions for tak input file.
+"
+
+" Force free-form fortran format
+let fortran_free_source=1
+
+" Load FORTRAN syntax file
+if version < 600
+  source <sfile>:p:h/fortran.vim
+else
+  runtime! syntax/fortran.vim
+endif
+unlet b:current_syntax
+
+
+
+" Define keywords for TAK and TAKOUT
+syn keyword takOptions  AUTODAMP CPRINT CSGDUMP GPRINT HPRINT LODTMP
+syn keyword takOptions  LOGIC LPRINT NCVPRINT PLOTQ QPRINT QDUMP
+syn keyword takOptions  SUMMARY SOLRTN UID DICTIONARIES
+
+syn keyword takRoutine  SSITER FWDWRD FWDBCK BCKWRD
+
+syn keyword takControl  ABSZRO BACKUP DAMP DTIMEI DTIMEL DTIMEH IFC
+syn keyword takControl  MAXTEMP NLOOPS NLOOPT NODELIST OUTPUT PLOT
+syn keyword takControl  SCALE SIGMA SSCRIT TIMEND TIMEN TIMEO TRCRIT
+syn keyword takControl  PLOT
+
+syn keyword takSolids   PLATE CYL
+syn keyword takSolidsArg   ID MATNAM NTYPE TEMP XL YL ZL ISTRN ISTRG NNX
+syn keyword takSolidsArg   NNY NNZ INCX INCY INCZ IAK IAC DIFF ARITH BOUN
+syn keyword takSolidsArg   RMIN RMAX AXMAX NNR NNTHETA INCR INCTHETA END
+
+syn case ignore
+
+syn keyword takMacro    fac pstart pstop
+syn keyword takMacro    takcommon fstart fstop
+
+syn keyword takIdentifier  flq flx gen ncv per sim siv stf stv tvd tvs
+syn keyword takIdentifier  tvt pro thm
+
+
+
+" Define matches for TAK
+syn match  takFortran     "^F[0-9 ]"me=e-1
+syn match  takMotran      "^M[0-9 ]"me=e-1
+
+syn match  takComment     "^C.*$"
+syn match  takComment     "^R.*$"
+syn match  takComment     "\$.*$"
+
+syn match  takHeader      "^header[^,]*"
+
+syn match  takIncludeFile "include \+[^ ]\+"hs=s+8 contains=fortranInclude
+
+syn match  takInteger     "-\=\<[0-9]*\>"
+syn match  takFloat       "-\=\<[0-9]*\.[0-9]*"
+syn match  takScientific  "-\=\<[0-9]*\.[0-9]*E[-+]\=[0-9]\+\>"
+
+syn match  takEndData     "END OF DATA"
+
+if exists("thermal_todo")
+  execute 'syn match  takTodo ' . '"^'.thermal_todo.'.*$"'
+else
+  syn match  takTodo	    "^?.*$"
+endif
+
+
+
+" Define the default highlighting
+" For version 5.7 and earlier: only when not done already
+" For version 5.8 and later: only when an item doesn't have highlighting yet
+if version >= 508 || !exists("did_tak_syntax_inits")
+  if version < 508
+    let did_tak_syntax_inits = 1
+    command -nargs=+ HiLink hi link <args>
+  else
+    command -nargs=+ HiLink hi def link <args>
+  endif
+
+  HiLink takMacro		Macro
+  HiLink takOptions		Special
+  HiLink takRoutine		Type
+  HiLink takControl		Special
+  HiLink takSolids		Special
+  HiLink takSolidsArg		Statement
+  HiLink takIdentifier		Identifier
+
+  HiLink takFortran		PreProc
+  HiLink takMotran		PreProc
+
+  HiLink takComment		Comment
+  HiLink takHeader		Typedef
+  HiLink takIncludeFile		Type
+  HiLink takInteger		Number
+  HiLink takFloat		Float
+  HiLink takScientific		Float
+
+  HiLink takEndData		Macro
+
+  HiLink takTodo		Todo
+
+  delcommand HiLink
+endif
+
+
+let b:current_syntax = "tak"
+
+" vim: ts=8 sw=2
--- /dev/null
+++ b/lib/vimfiles/syntax/takcmp.vim
@@ -1,0 +1,82 @@
+" Vim syntax file
+" Language:     TAK2, TAK3, TAK2000 thermal modeling compare file
+" Maintainer:   Adrian Nagle, anagle@ball.com
+" Last Change:  2003 May 11
+" Filenames:    *.cmp
+" URL:		http://www.naglenet.org/vim/syntax/takcmp.vim
+" MAIN URL:     http://www.naglenet.org/vim/
+
+
+
+" For version 5.x: Clear all syntax items
+" For version 6.x: Quit when a syntax file was already loaded
+if version < 600
+  syntax clear
+elseif exists("b:current_syntax")
+  finish
+endif
+
+
+
+" Ignore case
+syn case ignore
+
+
+
+"
+"
+" Begin syntax definitions for compare files.
+"
+" Define keywords for TAK compare
+  syn keyword takcmpUnit     celsius fahrenheit
+
+
+
+" Define matches for TAK compare
+  syn match  takcmpTitle       "Steady State Temperature Comparison"
+
+  syn match  takcmpLabel       "Run Date:"
+  syn match  takcmpLabel       "Run Time:"
+  syn match  takcmpLabel       "Temp. File \d Units:"
+  syn match  takcmpLabel       "Filename:"
+  syn match  takcmpLabel       "Output Units:"
+
+  syn match  takcmpHeader      "^ *Node\( *File  \d\)* *Node Description"
+
+  syn match  takcmpDate        "\d\d\/\d\d\/\d\d"
+  syn match  takcmpTime        "\d\d:\d\d:\d\d"
+  syn match  takcmpInteger     "^ *-\=\<[0-9]*\>"
+  syn match  takcmpFloat       "-\=\<[0-9]*\.[0-9]*"
+
+
+
+" Define the default highlighting
+" For version 5.7 and earlier: only when not done already
+" For version 5.8 and later: only when an item doesn't have highlighting yet
+if version >= 508 || !exists("did_takcmp_syntax_inits")
+  if version < 508
+    let did_takcmp_syntax_inits = 1
+    command -nargs=+ HiLink hi link <args>
+  else
+    command -nargs=+ HiLink hi def link <args>
+  endif
+
+  HiLink takcmpTitle		   Type
+  HiLink takcmpUnit		   PreProc
+
+  HiLink takcmpLabel		   Statement
+
+  HiLink takcmpHeader		   takHeader
+
+  HiLink takcmpDate		   Identifier
+  HiLink takcmpTime		   Identifier
+  HiLink takcmpInteger		   Number
+  HiLink takcmpFloat		   Special
+
+  delcommand HiLink
+endif
+
+
+let b:current_syntax = "takcmp"
+
+" vim: ts=8 sw=2
--- /dev/null
+++ b/lib/vimfiles/syntax/takout.vim
@@ -1,0 +1,102 @@
+" Vim syntax file
+" Language:     TAK2, TAK3, TAK2000 thermal modeling output file
+" Maintainer:   Adrian Nagle, anagle@ball.com
+" Last Change:  2003 May 11
+" Filenames:    *.out
+" URL:		http://www.naglenet.org/vim/syntax/takout.vim
+" MAIN URL:     http://www.naglenet.org/vim/
+
+
+
+" For version 5.x: Clear all syntax items
+" For version 6.x: Quit when a syntax file was already loaded
+if version < 600
+  syntax clear
+elseif exists("b:current_syntax")
+  finish
+endif
+
+
+
+" Ignore case
+syn case match
+
+
+
+" Load TAK syntax file
+if version < 600
+  source <sfile>:p:h/tak.vim
+else
+  runtime! syntax/tak.vim
+endif
+unlet b:current_syntax
+
+
+
+"
+"
+" Begin syntax definitions for tak output files.
+"
+
+" Define keywords for TAK output
+syn case match
+
+syn keyword takoutPos       ON SI
+syn keyword takoutNeg       OFF ENG
+
+
+
+" Define matches for TAK output
+syn match takoutTitle	     "TAK III"
+syn match takoutTitle	     "Release \d.\d\d"
+syn match takoutTitle	     " K & K  Associates *Thermal Analysis Kit III *Serial Number \d\d-\d\d\d"
+
+syn match takoutFile	     ": \w*\.TAK"hs=s+2
+
+syn match takoutInteger      "T\=[0-9]*\>"ms=s+1
+
+syn match takoutSectionDelim "[-<>]\{4,}" contains=takoutSectionTitle
+syn match takoutSectionDelim ":\=\.\{4,}:\=" contains=takoutSectionTitle
+syn match takoutSectionTitle "[-<:] \w[0-9A-Za-z_() ]\+ [->:]"hs=s+1,me=e-1
+
+syn match takoutHeaderDelim  "=\{5,}"
+syn match takoutHeaderDelim  "|\{5,}"
+syn match takoutHeaderDelim  "+\{5,}"
+
+syn match takoutLabel	     "Input File:" contains=takoutFile
+syn match takoutLabel	     "Begin Solution: Routine"
+
+syn match takoutError	     "<<< Error >>>"
+
+
+" Define the default highlighting
+" For version 5.7 and earlier: only when not done already
+" For version 5.8 and later: only when an item doesn't have highlighting yet
+if version >= 508 || !exists("did_takout_syntax_inits")
+  if version < 508
+    let did_takout_syntax_inits = 1
+    command -nargs=+ HiLink hi link <args>
+  else
+    command -nargs=+ HiLink hi def link <args>
+  endif
+
+  HiLink takoutPos		   Statement
+  HiLink takoutNeg		   PreProc
+  HiLink takoutTitle		   Type
+  HiLink takoutFile		   takIncludeFile
+  HiLink takoutInteger		   takInteger
+
+  HiLink takoutSectionDelim	    Delimiter
+  HiLink takoutSectionTitle	   Exception
+  HiLink takoutHeaderDelim	   SpecialComment
+  HiLink takoutLabel		   Identifier
+
+  HiLink takoutError		   Error
+
+  delcommand HiLink
+endif
+
+
+let b:current_syntax = "takout"
+
+" vim: ts=8 sw=2
--- /dev/null
+++ b/lib/vimfiles/syntax/tar.vim
@@ -1,0 +1,17 @@
+" Language   : Tar Listing Syntax
+" Maintainer : Bram Moolenaar
+" Last change: Sep 08, 2004
+
+if exists("b:current_syntax")
+ finish
+endif
+
+syn match tarComment '^".*' contains=tarFilename
+syn match tarFilename 'tarfile \zs.*' contained
+syn match tarDirectory '.*/$'
+
+hi def link tarComment	Comment
+hi def link tarFilename	Constant
+hi def link tarDirectory Type
+
+" vim: ts=8
--- /dev/null
+++ b/lib/vimfiles/syntax/tasm.vim
@@ -1,0 +1,122 @@
+" Vim syntax file
+" Language: TASM: turbo assembler by Borland
+" Maintaner: FooLman of United Force <foolman@bigfoot.com>
+" Last change: 22 aug 2000
+
+" For version 5.x: Clear all syntax items
+" For version 6.x: Quit when a syntax file was already loaded
+if version < 600
+  syntax clear
+elseif exists("b:current_syntax")
+  finish
+endif
+
+syn case ignore
+syn match tasmLabel "^[\ \t]*[@a-z_$][a-z0-9_$@]*\ *:"
+syn keyword tasmDirective ALIAS ALIGN ARG ASSUME %BIN CATSRT CODESEG
+syn match tasmDirective "\<\(byte\|word\|dword\|qword\)\ ptr\>"
+" CALL extended syntax
+syn keyword tasmDirective COMM %CONDS CONST %CREF %CREFALL %CREFREF
+syn keyword tasmDirective %CREFUREF %CTLS DATASEG DB DD %DEPTH DF DISPLAY
+syn keyword tasmDirective DOSSEG DP DQ DT DW ELSE EMUL END ENDIF
+" IF XXXX
+syn keyword tasmDirective ENDM ENDP ENDS ENUM EQU ERR EVEN EVENDATA EXITCODE
+syn keyword tasmDirective EXITM EXTRN FARDATA FASTIMUL FLIPFLAG GETFIELD GLOBAL
+syn keyword tasmDirective GOTO GROUP IDEAL %INCL INCLUDE INCLUDELIB INSTR IRP
+"JMP
+syn keyword tasmDirective IRPC JUMPS LABEL LARGESTACK %LINUM %LIST LOCAL
+syn keyword tasmDirective LOCALS MACRO %MACS MASKFLAG MASM MASM51 MODEL
+syn keyword tasmDirective MULTERRS NAME %NEWPAGE %NOCONDS %NOCREF %NOCTLS
+syn keyword tasmDirective NOEMUL %NOINCL NOJUMPS %NOLIST NOLOCALS %NOMACS
+syn keyword tasmDirective NOMASM51 NOMULTERRS NOSMART %NOSYMS %NOTRUNC NOWARN
+syn keyword tasmDirective %PAGESIZE %PCNT PNO87 %POPLCTL POPSTATE PROC PROCDESC
+syn keyword tasmDirective PROCTYPE PUBLIC PUBLICDLL PURGE %PUSHCTL PUSHSTATE
+"rept, ret
+syn keyword tasmDirective QUIRKS RADIX RECORD RETCODE SEGMENT SETFIELD
+syn keyword tasmDirective SETFLAG SIZESTR SMALLSTACK SMART STACK STARTUPCODE
+syn keyword tasmDirective STRUC SUBSTR %SUBTTL %SYMS TABLE %TABSIZE TBLINIT
+syn keyword tasmDirective TBLINST TBLPTR TESTFLAG %TEXT %TITLE %TRUNC TYPEDEF
+syn keyword tasmDirective UDATASEG UFARDATA UNION USES VERSION WAR WHILE ?DEBUG
+
+syn keyword tasmInstruction AAA AAD AAM AAS ADC ADD AND ARPL BOUND BSF BSR
+syn keyword tasmInstruction BSWAP BT BTC BTR BTS CALL CBW CLC CLD CLI CLTS
+syn keyword tasmInstruction CMC CMP CMPXCHG CMPXCHG8B CPUID CWD CDQ CWDE
+syn keyword tasmInstruction DAA DAS DEC DIV ENTER RETN RETF F2XM1
+syn keyword tasmCoprocInstr FABS FADD FADDP FBLD FBSTP FCHG FCOM FCOM2 FCOMI
+syn keyword tasmCoprocInstr FCOMIP FCOMP FCOMP3 FCOMP5 FCOMPP FCOS FDECSTP
+syn keyword tasmCoprocInstr FDISI FDIV FDIVP FDIVR FENI FFREE FFREEP FIADD
+syn keyword tasmCoprocInstr FICOM FICOMP FIDIV FIDIVR FILD FIMUL FINIT FINCSTP
+syn keyword tasmCoprocInstr FIST FISTP FISUB FISUBR FLD FLD1 FLDCW FLDENV
+syn keyword tasmCoprocInstr FLDL2E FLDL2T FLDLG2 FLDLN2 FLDPI FLDZ FMUL FMULP
+syn keyword tasmCoprocInstr FNCLEX FNINIT FNOP FNSAVE FNSTCW FNSTENV FNSTSW
+syn keyword tasmCoprocInstr FPATAN FPREM FPREM1 FPTAN FRNDINT FRSTOR FSCALE
+syn keyword tasmCoprocInstr FSETPM FSIN FSINCOM FSQRT FST FSTP FSTP1 FSTP8
+syn keyword tasmCoprocInstr FSTP9 FSUB FSUBP FSUBR FSUBRP FTST FUCOM FUCOMI
+syn keyword tasmCoprocInstr FUCOMPP FWAIT FXAM FXCH FXCH4 FXCH7 FXTRACT FYL2X
+syn keyword tasmCoprocInstr FYL2XP1 FSTCW FCHS FSINCOS
+syn keyword tasmInstruction IDIV IMUL IN INC INT INTO INVD INVLPG IRET JMP
+syn keyword tasmInstruction LAHF LAR LDS LEA LEAVE LES LFS LGDT LGS LIDT LLDT
+syn keyword tasmInstruction LMSW LOCK LODSB LSL LSS LTR MOV MOVSX MOVZX MUL
+syn keyword tasmInstruction NEG NOP NOT OR OUT POP POPA POPAD POPF POPFD PUSH
+syn keyword tasmInstruction PUSHA PUSHAD PUSHF PUSHFD RCL RCR RDMSR RDPMC RDTSC
+syn keyword tasmInstruction REP RET ROL ROR RSM SAHF SAR SBB SGDT SHL SAL SHLD
+syn keyword tasmInstruction SHR SHRD SIDT SMSW STC STD STI STR SUB TEST VERR
+syn keyword tasmInstruction VERW WBINVD WRMSR XADD XCHG XLAT XOR
+syn keyword tasmMMXinst     EMMS MOVD MOVQ PACKSSDW PACKSSWB PACKUSWB PADDB
+syn keyword tasmMMXinst     PADDD PADDSB PADDSB PADDSW PADDUSB PADDUSW PADDW
+syn keyword tasmMMXinst     PAND PANDN PCMPEQB PCMPEQD PCMPEQW PCMPGTB PCMPGTD
+syn keyword tasmMMXinst     PCMPGTW PMADDWD PMULHW PMULLW POR PSLLD PSLLQ
+syn keyword tasmMMXinst     PSLLW PSRAD PSRAW PSRLD PSRLQ PSRLW PSUBB PSUBD
+syn keyword tasmMMXinst     PSUBSB PSUBSW PSUBUSB PSUBUSW PSUBW PUNPCKHBW
+syn keyword tasmMMXinst     PUNPCKHBQ PUNPCKHWD PUNPCKLBW PUNPCKLDQ PUNPCKLWD
+syn keyword tasmMMXinst     PXOR
+"FCMOV
+syn match tasmInstruction "\<\(CMPS\|MOVS\|OUTS\|SCAS\|STOS\|LODS\|INS\)[BWD]"
+syn match tasmInstruction "\<\(CMOV\|SET\|J\)N\=[ABCGLESXZ]\>"
+syn match tasmInstruction "\<\(CMOV\|SET\|J\)N\=[ABGL]E\>"
+syn match tasmInstruction "\<\(LOOP\|REP\)N\=[EZ]\=\>"
+syn match tasmRegister "\<[A-D][LH]\>"
+syn match tasmRegister "\<E\=\([A-D]X\|[SD]I\|[BS]P\)\>"
+syn match tasmRegister "\<[C-GS]S\>"
+syn region tasmComment start=";" end="$"
+"HACK! comment ? ... selection
+syn region tasmComment start="comment \+\$" end="\$"
+syn region tasmComment start="comment \+\~" end="\~"
+syn region tasmComment start="comment \+#" end="#"
+syn region tasmString start="'" end="'"
+syn region tasmString start='"' end='"'
+
+syn match tasmDec "\<-\=[0-9]\+\.\=[0-9]*\>"
+syn match tasmHex "\<[0-9][0-9A-F]*H\>"
+syn match tasmOct "\<[0-7]\+O\>"
+syn match tasmBin "\<[01]\+B\>"
+
+" Define the default highlighting.
+" For version 5.7 and earlier: only when not done already
+" For version 5.8 and later: only when an item doesn't have highlighting yet
+if version >= 508 || !exists("did_tasm_syntax_inits")
+  if version < 508
+    let did_tasm_syntax_inits = 1
+    command -nargs=+ HiLink hi link <args>
+  else
+    command -nargs=+ HiLink hi def link <args>
+  endif
+
+  HiLink tasmString String
+  HiLink tasmDec Number
+  HiLink tasmHex Number
+  HiLink tasmOct Number
+  HiLink tasmBin Number
+  HiLink tasmInstruction Keyword
+  HiLink tasmCoprocInstr Keyword
+  HiLink tasmMMXInst	Keyword
+  HiLink tasmDirective PreProc
+  HiLink tasmRegister Identifier
+  HiLink tasmProctype PreProc
+  HiLink tasmComment Comment
+  HiLink tasmLabel Label
+
+  delcommand HiLink
+endif
+
+let b:curret_syntax = "tasm"
--- /dev/null
+++ b/lib/vimfiles/syntax/tcl.vim
@@ -1,0 +1,243 @@
+" Vim syntax file
+" Language:	TCL/TK
+" Maintainer:	Brett Cannon <brett@python.org>
+" 		(previously Dean Copsey <copsey@cs.ucdavis.edu>)
+"		(previously Matt Neumann <mattneu@purpleturtle.com>)
+"		(previously Allan Kelly <allan@fruitloaf.co.uk>)
+" Original:	Robin Becker <robin@jessikat.demon.co.uk>
+" Last Change:	2006 Nov 17
+"
+" Keywords TODO: format clock click anchor
+
+" For version 5.x: Clear all syntax items
+" For version 6.x: Quit when a syntax file was already loaded
+if version < 600
+  syntax clear
+elseif exists("b:current_syntax")
+  finish
+endif
+
+" A bunch of useful keywords
+syn keyword tclStatement  tell socket subst open eof pwd glob list exec pid
+syn keyword tclStatement  auto_load_index time unknown eval lrange fblocked
+syn keyword tclStatement  lsearch auto_import gets lappend proc variable llength
+syn keyword tclStatement  auto_execok return linsert error catch clock info
+syn keyword tclStatement  split array fconfigure concat join lreplace source
+syn keyword tclStatement  fcopy global auto_qualify update close cd auto_load
+syn keyword tclStatement  file append format read package set binary namespace
+syn keyword tclStatement  scan trace seek flush after vwait uplevel lset rename
+syn keyword tclStatement  fileevent regexp upvar unset encoding expr load regsub
+syn keyword tclStatement interp exit puts incr lindex lsort tclLog string
+syn keyword tclLabel		case default
+syn keyword tclConditional	if then else elseif switch
+syn keyword tclRepeat		while for foreach break continue
+syn keyword tcltkSwitch	contained	insert create polygon fill outline tag
+
+" WIDGETS
+" commands associated with widgets
+syn keyword tcltkWidgetSwitch contained background highlightbackground insertontime cget
+syn keyword tcltkWidgetSwitch contained selectborderwidth borderwidth highlightcolor insertwidth
+syn keyword tcltkWidgetSwitch contained selectforeground cursor highlightthickness padx setgrid
+syn keyword tcltkWidgetSwitch contained exportselection insertbackground pady takefocus
+syn keyword tcltkWidgetSwitch contained font insertborderwidth relief xscrollcommand
+syn keyword tcltkWidgetSwitch contained foreground insertofftime selectbackground yscrollcommand
+syn keyword tcltkWidgetSwitch contained height spacing1 spacing2 spacing3
+syn keyword tcltkWidgetSwitch contained state tabs width wrap
+" button
+syn keyword tcltkWidgetSwitch contained command default
+" canvas
+syn keyword tcltkWidgetSwitch contained closeenough confine scrollregion xscrollincrement yscrollincrement orient
+" checkbutton, radiobutton
+syn keyword tcltkWidgetSwitch contained indicatoron offvalue onvalue selectcolor selectimage state variable
+" entry, frame
+syn keyword tcltkWidgetSwitch contained show class colormap container visual
+" listbox, menu
+syn keyword tcltkWidgetSwitch contained selectmode postcommand selectcolor tearoff tearoffcommand title type
+" menubutton, message
+syn keyword tcltkWidgetSwitch contained direction aspect justify
+" scale
+syn keyword tcltkWidgetSwitch contained bigincrement digits from length resolution showvalue sliderlength sliderrelief tickinterval to
+" scrollbar
+syn keyword tcltkWidgetSwitch contained activerelief elementborderwidth
+" image
+syn keyword tcltkWidgetSwitch contained delete names types create
+" variable reference
+	" ::optional::namespaces
+syn match tclVarRef "$\(\(::\)\?\([[:alnum:]_.]*::\)*\)\a[a-zA-Z0-9_.]*"
+	" ${...} may contain any character except '}'
+syn match tclVarRef "${[^}]*}"
+" menu, mane add
+syn keyword tcltkWidgetSwitch contained active end last none cascade checkbutton command radiobutton separator
+syn keyword tcltkWidgetSwitch contained activebackground actveforeground accelerator background bitmap columnbreak
+syn keyword tcltkWidgetSwitch contained font foreground hidemargin image indicatoron label menu offvalue onvalue
+syn keyword tcltkWidgetSwitch contained selectcolor selectimage state underline value variable
+syn keyword tcltkWidgetSwitch contained add clone configure delete entrycget entryconfigure index insert invoke
+syn keyword tcltkWidgetSwitch contained post postcascade type unpost yposition activate
+"syn keyword tcltkWidgetSwitch contained
+"syn match tcltkWidgetSwitch contained
+syn region tcltkWidget matchgroup=tcltkWidgetColor start="\<button\>" matchgroup=NONE skip="^\s*$" end="]\|[^\\]*\s*$"he=e-1 contains=tclLineContinue,tcltkWidgetSwitch,tclString,tcltkSwitch,tclNumber,tclVarRef
+syn region tcltkWidget matchgroup=tcltkWidgetColor start="\<scale\>" matchgroup=NONE skip="^\s*$" end="]\|[^\\]*\s*$"he=e-1  contains=tclLineContinue,tcltkWidgetSwitch,tclString,tcltkSwitch,tclNumber,tclVarRef
+
+syn region tcltkWidget matchgroup=tcltkWidgetColor start="\<canvas\>" matchgroup=NONE skip="^\s*$" end="]\|[^\\]*\s*$"he=e-1  contains=tclLineContinue,tcltkWidgetSwitch,tclString,tcltkSwitch,tclNumber,tclVarRef
+syn region tcltkWidget matchgroup=tcltkWidgetColor start="\<checkbutton\>" matchgroup=NONE skip="^\s*$" end="]\|[^\\]*\s*$"he=e-1  contains=tclLineContinue,tcltkWidgetSwitch,tclString,tcltkSwitch,tclNumber,tclVarRef
+syn region tcltkWidget matchgroup=tcltkWidgetColor start="\<entry\>" matchgroup=NONE skip="^\s*$" end="]\|[^\\]*\s*$"he=e-1  contains=tclLineContinue,tcltkWidgetSwitch,tclString,tcltkSwitch,tclNumber,tclVarRef
+syn region tcltkWidget matchgroup=tcltkWidgetColor start="\<frame\>" matchgroup=NONE skip="^\s*$" end="]\|[^\\]*\s*$"he=e-1  contains=tclLineContinue,tcltkWidgetSwitch,tclString,tcltkSwitch,tclNumber,tclVarRef
+syn region tcltkWidget matchgroup=tcltkWidgetColor start="\<image\>" matchgroup=NONE skip="^\s*$" end="]\|[^\\]*\s*$"he=e-1  contains=tclLineContinue,tcltkWidgetSwitch,tclString,tcltkSwitch,tclNumber,tclVarRef
+syn region tcltkWidget matchgroup=tcltkWidgetColor start="\<listbox\>" matchgroup=NONE skip="^\s*$" end="]\|[^\\]*\s*$"he=e-1  contains=tclLineContinue,tcltkWidgetSwitch,tclString,tcltkSwitch,tclNumber,tclVarRef
+syn region tcltkWidget matchgroup=tcltkWidgetColor start="\<menubutton\>" matchgroup=NONE skip="^\s*$" end="]\|[^\\]*\s*$"he=e-1  contains=tclLineContinue,tcltkWidgetSwitch,tclString,tcltkSwitch,tclNumber,tclVarRef
+syn region tcltkWidget matchgroup=tcltkWidgetColor start="\<message\>" matchgroup=NONE skip="^\s*$" end="]\|[^\\]*\s*$"he=e-1  contains=tclLineContinue,tcltkWidgetSwitch,tclString,tcltkSwitch,tclNumber,tclVarRef
+syn region tcltkWidget matchgroup=tcltkWidgetColor start="\<radiobutton\>" matchgroup=NONE skip="^\s*$" end="]\|[^\\]*\s*$"he=e-1 contains=tclLineContinue,tcltkWidgetSwitch,tclString,tcltkSwitch,tclNumber,tclVarRef
+syn region tcltkWidget matchgroup=tcltkWidgetColor start="\<scrollbar\>" matchgroup=NONE skip="^\s*$" end="]\|[^\\]*\s*$"he=e-1  contains=tclLineContinue,tcltkWidgetSwitch,tclString,tcltkSwitch,tclNumber,tclVarRef
+" These words are dual purpose.
+" match switches
+"syn match tcltkWidgetSwitch contained "-text"hs=s+1
+syn match tcltkWidgetSwitch contained "-text\(var\)\?"hs=s+1
+syn match tcltkWidgetSwitch contained "-menu"hs=s+1
+syn match tcltkWidgetSwitch contained "-label"hs=s+1
+" match commands - 2 lines for pretty match.
+"variable
+" Special case - If a number follows a variable region, it must be at the end of
+" the pattern, by definition. Therefore, (1) either include a number as the region
+" end and exclude tclNumber from the contains list, or (2) make variable
+" keepend. As (1) would put variable out of step with everything else, use (2).
+syn region tcltkCommand matchgroup=tcltkCommandColor start="^\<variable\>" matchgroup=NONE skip="^\s*$" end="]\|[^\\]*\s*$"he=e-1  contains=tclLineContinue,tclString,tclNumber,tclVarRef,tcltkCommand
+syn region tcltkCommand matchgroup=tcltkCommandColor start="\s\<variable\>\|\[\<variable\>"hs=s+1 matchgroup=NONE skip="^\s*$" end="]\|[^\\]*\s*$"he=e-1  contains=tclLineContinue,tclString,tclNumber,tclVarRef,tcltkCommand
+" menu
+syn region tcltkWidget matchgroup=tcltkWidgetColor start="^\<menu\>" matchgroup=NONE skip="^\s*$" end="]\|[^\\]*\s*$"he=e-1  contains=tclLineContinue,tcltkWidgetSwitch,tclString,tcltkSwitch,tclNumber,tclVarRef
+syn region tcltkWidget matchgroup=tcltkWidgetColor start="\s\<menu\>\|\[\<menu\>"hs=s+1 matchgroup=NONE skip="^\s*$" end="]\|[^\\]*\s*$"he=e-1  contains=tclLineContinue,tcltkWidgetSwitch,tclString,tcltkSwitch,tclNumber,tclVarRef
+" label
+syn region tcltkWidget matchgroup=tcltkWidgetColor start="^\<label\>" matchgroup=NONE skip="^\s*$" end="]\|[^\\]*\s*$"he=e-1  contains=tclLineContinue,tcltkWidgetSwitch,tclString,tcltkSwitch,tclNumber,tclVarRef
+syn region tcltkWidget matchgroup=tcltkWidgetColor start="\s\<label\>\|\[\<label\>"hs=s+1 matchgroup=NONE skip="^\s*$" end="]\|[^\\]*\s*$"he=e-1  contains=tclLineContinue,tcltkWidgetSwitch,tclString,tcltkSwitch,tclNumber,tclVarRef
+" text
+syn region tcltkWidget matchgroup=tcltkWidgetColor start="^\<text\>" matchgroup=NONE skip="^\s*$" end="]\|[^\\]*\s*$"he=e-1  contains=tclLineContinue,tcltkWidget,tcltkWidgetSwitch,tcltkSwitch,tclNumber,tclVarRef,tclString
+syn region tcltkWidget matchgroup=tcltkWidgetColor start="\s\<text\>\|\[\<text\>"hs=s+1 matchgroup=NONE skip="^\s*$" end="]\|[^\\]*\s*$"he=e-1  contains=tclLineContinue,tcltkWidget,tcltkWidgetSwitch,tclString,tcltkSwitch,tclNumber,tclVarRef
+
+" This isn't contained (I don't think) so it's OK to just associate with the Color group.
+" TODO: This could be wrong.
+syn keyword tcltkWidgetColor	toplevel
+
+
+syn region tcltkPackConf matchgroup=tcltkPackConfColor start="\<configure\>" matchgroup=NONE skip="^\s*$" end="]\|[^\\]*\s*$"he=e-1  contains=tclLineContinue,tcltkWidgetSwitch,tclString,tcltkSwitch,tcltkPackConfSwitch,tclNumber,tclVarRef keepend
+syn region tcltkPackConf matchgroup=tcltkPackConfColor start="\<cget\>" matchgroup=NONE skip="^\s*$" end="]\|[^\\]*\s*$"me=e-1  contains=tclLineContinue,tcltkWidgetSwitch,tclString,tcltkSwitch,tcltkPackConfSwitch,tclNumber,tclVarRef
+
+
+" NAMESPACE
+" commands associated with namespace
+syn keyword tcltkNamespaceSwitch contained children code current delete eval
+syn keyword tcltkNamespaceSwitch contained export forget import inscope origin
+syn keyword tcltkNamespaceSwitch contained parent qualifiers tail which command variable
+syn region tcltkCommand matchgroup=tcltkCommandColor start="\<namespace\>" matchgroup=NONE skip="^\s*$" end="{\|}\|]\|\"\|[^\\]*\s*$"me=e-1  contains=tclLineContinue,tcltkNamespaceSwitch
+
+" EXPR
+" commands associated with expr
+syn keyword tcltkMaths	contained	acos	cos	hypot	sinh
+syn keyword tcltkMaths	contained	asin	cosh	log	sqrt
+syn keyword tcltkMaths	contained	atan	exp	log10	tan
+syn keyword tcltkMaths	contained	atan2	floor	pow	tanh
+syn keyword tcltkMaths	contained	ceil	fmod	sin
+syn region tcltkCommand matchgroup=tcltkCommandColor start="\<expr\>" matchgroup=NONE skip="^\s*$" end="]\|[^\\]*\s*$"me=e-1  contains=tclLineContinue,tcltkMaths,tclNumber,tclVarRef,tclString,tcltlWidgetSwitch,tcltkCommand,tcltkPackConf
+
+" format
+syn region tcltkCommand matchgroup=tcltkCommandColor start="\<format\>" matchgroup=NONE skip="^\s*$" end="]\|[^\\]*\s*$"me=e-1  contains=tclLineContinue,tcltkMaths,tclNumber,tclVarRef,tclString,tcltlWidgetSwitch,tcltkCommand,tcltkPackConf
+
+" PACK
+" commands associated with pack
+syn keyword tcltkPackSwitch	contained	forget info propogate slaves
+syn keyword tcltkPackConfSwitch	contained	after anchor before expand fill in ipadx ipady padx pady side
+syn region tcltkCommand matchgroup=tcltkCommandColor start="\<pack\>" matchgroup=NONE skip="^\s*$" end="]\|[^\\]*\s*$"he=e-1  contains=tclLineContinue,tcltkPackSwitch,tcltkPackConf,tcltkPackConfSwitch,tclNumber,tclVarRef,tclString,tcltkCommand keepend
+
+" STRING
+" commands associated with string
+syn keyword tcltkStringSwitch	contained	compare first index last length match range tolower toupper trim trimleft trimright wordstart wordend
+syn region tcltkCommand matchgroup=tcltkCommandColor start="\<string\>" matchgroup=NONE skip="^\s*$" end="]\|[^\\]*\s*$"he=e-1  contains=tclLineContinue,tcltkStringSwitch,tclNumber,tclVarRef,tclString,tcltkCommand
+
+" ARRAY
+" commands associated with array
+syn keyword tcltkArraySwitch	contained	anymore donesearch exists get names nextelement size startsearch set
+" match from command name to ] or EOL
+syn region tcltkCommand matchgroup=tcltkCommandColor start="\<array\>" matchgroup=NONE skip="^\s*$" end="]\|[^\\]*\s*$"he=e-1  contains=tclLineContinue,tcltkArraySwitch,tclNumber,tclVarRef,tclString,tcltkCommand
+
+" LSORT
+" switches for lsort
+syn keyword tcltkLsortSwitch	contained	ascii dictionary integer real command increasing decreasing index
+" match from command name to ] or EOL
+syn region tcltkCommand matchgroup=tcltkCommandColor start="\<lsort\>" matchgroup=NONE skip="^\s*$" end="]\|[^\\]*\s*$"he=e-1  contains=tclLineContinue,tcltkLsortSwitch,tclNumber,tclVarRef,tclString,tcltkCommand
+
+syn keyword tclTodo contained	TODO
+
+
+" String and Character contstants
+" Highlight special characters (those which have a backslash) differently
+syn match   tclSpecial contained "\\\d\d\d\=\|\\."
+" A string needs the skip argument as it may legitimately contain \".
+" Match at start of line
+syn region  tclString		  start=+^"+ end=+"+ contains=tclSpecial skip=+\\\\\|\\"+
+"Match all other legal strings.
+syn region  tclString		  start=+[^\\]"+ms=s+1  end=+"+ contains=tclSpecial skip=+\\\\\|\\"+
+
+syn match   tclLineContinue "\\\s*$"
+
+"integer number, or floating point number without a dot and with "f".
+syn case ignore
+syn match  tclNumber		"\<\d\+\(u\=l\=\|lu\|f\)\>"
+"floating point number, with dot, optional exponent
+syn match  tclNumber		"\<\d\+\.\d*\(e[-+]\=\d\+\)\=[fl]\=\>"
+"floating point number, starting with a dot, optional exponent
+syn match  tclNumber		"\.\d\+\(e[-+]\=\d\+\)\=[fl]\=\>"
+"floating point number, without dot, with exponent
+syn match  tclNumber		"\<\d\+e[-+]\=\d\+[fl]\=\>"
+"hex number
+syn match  tclNumber		"0x[0-9a-f]\+\(u\=l\=\|lu\)\>"
+"syn match  tclIdentifier	"\<[a-z_][a-z0-9_]*\>"
+syn case match
+
+syn region  tclComment		start="^\s*\#" skip="\\$" end="$" contains=tclTodo
+syn region  tclComment		start=/;\s*\#/hs=s+1 skip="\\$" end="$" contains=tclTodo
+
+"syn sync ccomment tclComment
+
+" Define the default highlighting.
+" For version 5.7 and earlier: only when not done already
+" For version 5.8 and later: only when an item doesn't have highlighting yet
+if version >= 508 || !exists("did_tcl_syntax_inits")
+  if version < 508
+    let did_tcl_syntax_inits = 1
+    command -nargs=+ HiLink hi link <args>
+  else
+    command -nargs=+ HiLink hi def link <args>
+  endif
+
+  HiLink tcltkSwitch		Special
+  HiLink tclLabel		Label
+  HiLink tclConditional		Conditional
+  HiLink tclRepeat		Repeat
+  HiLink tclNumber		Number
+  HiLink tclError		Error
+  HiLink tclStatement		Statement
+  "HiLink tclStatementColor	Statement
+  HiLink tclString		String
+  HiLink tclComment		Comment
+  HiLink tclSpecial		Special
+  HiLink tclTodo		Todo
+  " Below here are the commands and their options.
+  HiLink tcltkCommandColor	Statement
+  HiLink tcltkWidgetColor	Structure
+  HiLink tclLineContinue	WarningMsg
+  HiLink tcltkStringSwitch	Special
+  HiLink tcltkArraySwitch	Special
+  HiLink tcltkLsortSwitch	Special
+  HiLink tcltkPackSwitch	Special
+  HiLink tcltkPackConfSwitch	Special
+  HiLink tcltkMaths		Special
+  HiLink tcltkNamespaceSwitch	Special
+  HiLink tcltkWidgetSwitch	Special
+  HiLink tcltkPackConfColor	Identifier
+  "HiLink tcltkLsort		Statement
+  HiLink tclVarRef		Identifier
+
+  delcommand HiLink
+endif
+
+let b:current_syntax = "tcl"
+
+" vim: ts=8
--- /dev/null
+++ b/lib/vimfiles/syntax/tcsh.vim
@@ -1,0 +1,189 @@
+" Vim syntax file
+" Language:		C-shell (tcsh)
+" Maintainer:		Gautam Iyer <gi1242@users.sourceforge.net>
+" Last Modified:	Thu 16 Nov 2006 01:07:04 PM PST
+"
+" Description: We break up each statement into a "command" and an "end" part.
+" All groups are either a "command" or part of the "end" of a statement (ie
+" everything after the "command"). This is because blindly highlighting tcsh
+" statements as keywords caused way too many false positives. Eg:
+"
+" 	set history=200
+"
+" causes history to come up as a keyword, which we want to avoid.
+
+" Quit when a syntax file was already loaded
+if exists("b:current_syntax")
+  finish
+endif
+
+syn case match
+
+" ----- Clusters -----
+syn cluster tcshModifiers	contains=tcshModifier,tcshModifierError
+syn cluster tcshQuoteList	contains=tcshDQuote,tcshSQuote,tcshBQuote
+syn cluster tcshStatementEnds	contains=@tcshQuoteList,tcshComment,tcshUsrVar,TcshArgv,tcshSubst,tcshRedir,tcshMeta,tcshHereDoc,tcshSpecial,tcshArguement
+syn cluster tcshStatements	contains=tcshBuiltins,tcshCommands,tcshSet,tcshSetEnv,tcshAlias,tcshIf,tcshWhile
+syn cluster tcshVarList		contains=tcshUsrVar,tcshArgv,tcshSubst
+
+" ----- Statements -----
+" Tcsh commands: Any filename / modifiable variable (must be first!)
+syn match tcshCommands	'\v[a-zA-Z0-9\\./_$:-]+' contains=tcshSpecial,tcshUsrVar,tcshArgv,tcshVarError nextgroup=tcshStatementEnd
+
+" Builtin commands except (un)set(env), (un)alias, if, while, else
+syn keyword tcshBuiltins nextgroup=tcshStatementEnd alloc bg bindkey break breaksw builtins bye case cd chdir complete continue default dirs echo echotc end endif endsw eval exec exit fg filetest foreach getspath getxvers glob goto hashstat history hup inlib jobs kill limit log login logout ls ls-F migrate newgrp nice nohup notify onintr popd printenv pushd rehash repeat rootnode sched setpath setspath settc setty setxvers shift source stop suspend switch telltc time umask uncomplete unhash universe unlimit ver wait warp watchlog where which
+
+" StatementEnd is anything after a builtin / command till the lexical end of a
+" statement (;, |, ||, |&, && or end of line)
+syn region tcshStatementEnd	transparent contained matchgroup=tcshBuiltins start='' end='\v\\@<!(;|\|[|&]?|\&\&|$)' contains=@tcshStatementEnds
+
+" set expressions (Contains shell variables)
+syn keyword tcshShellVar contained afsuser ampm argv autocorrect autoexpand autolist autologout backslash_quote catalog cdpath color colorcat command complete continue continue_args correct cwd dextract dirsfile dirstack dspmbyte dunique echo echo_style edit ellipsis fignore filec gid group histchars histdup histfile histlit history home ignoreeof implicitcd inputmode killdup killring listflags listjobs listlinks listmax listmaxrows loginsh logout mail matchbeep nobeep noclobber noding noglob nokanji nonomatch nostat notify oid owd path printexitvalue prompt prompt2 prompt3 promptchars pushdtohome pushdsilent recexact recognize_only_executables rmstar rprompt savedirs savehist sched shell shlvl status symlinks tcsh term time tperiod tty uid user verbose version visiblebell watch who wordchars
+syn keyword tcshSet	nextgroup=tcshSetEnd set unset
+syn region  tcshSetEnd	contained transparent matchgroup=tcshBuiltins start='' skip="\\$" end="$\|;" contains=tcshShellVar,@tcshStatementEnds
+
+" setenv expressions (Contains enviorenment variables)
+syn keyword tcshEnvVar contained AFSUSER COLUMNS DISPLAY EDITOR GROUP HOME HOST HOSTTYPE HPATH LANG LC_CTYPE LINES LS_COLORS MACHTYPE NOREBIND OSTYPE PATH PWD REMOTEHOST SHLVL SYSTYPE TERM TERMCAP USER VENDOR VISUAL
+syn keyword tcshSetEnv	nextgroup=tcshEnvEnd setenv unsetenv
+syn region  tcshEnvEnd	contained transparent matchgroup=tcshBuiltins start='' skip="\\$" end="$\|;" contains=tcshEnvVar,@tcshStatementEnds
+
+" alias and unalias (contains special aliases)
+syn keyword tcshAliases contained beepcmd cwdcmd jobcmd helpcommand periodic precmd postcmd shell
+syn keyword tcshAlias	nextgroup=tcshAliCmd skipwhite alias unalias
+syn match   tcshAliCmd	contained nextgroup=tcshAliEnd skipwhite '\v[\w-]+' contains=tcshAliases
+syn region  tcshAliEnd	contained transparent matchgroup=tcshBuiltins start='' skip="\\$" end="$\|;" contains=@tcshStatementEnds
+
+" if statements (contains expressions / operators)
+syn keyword tcshIf	nextgroup=tcshIfEnd if
+syn region  tcshIfEnd	contained matchgroup=tcshBuiltins start='' skip="\\$" end="\v<then>|$" contains=tcshOperator,tcshNumber,@tcshStatementEnds
+
+" else statements (nextgroup if)
+syn keyword tcshElse	nextgroup=tcshIf skipwhite else
+
+" while statements (contains expressions / operators)
+syn keyword tcshWhile	nextgroup=tcshWhEnd while
+syn region  tcshWhEnd	contained transparent matchgroup=tcshBuiltins start='' skip="\\$" end="\v$" contains=tcshOperator,tcshNumber,@tcshStatementEnds
+
+" Expressions start with @.
+syn match tcshExprStart "\v\@\s+" nextgroup=tcshExprVar
+syn match tcshExprVar	contained "\v\h\w*%(\[\d+\])?" contains=tcshShellVar,tcshEnvVar nextgroup=tcshExprOp
+syn match tcshExprOp	contained "++\|--"
+syn match tcshExprOp	contained "\v\s*\=" nextgroup=tcshExprEnd
+syn match tcshExprEnd	contained "\v.*$"hs=e+1 contains=tcshOperator,tcshNumber,@tcshVarList
+syn match tcshExprEnd	contained "\v.{-};"hs=e	contains=tcshOperator,tcshNumber,@tcshVarList
+
+" ----- Comments: -----
+syn match tcshComment	'#\s.*' contains=tcshTodo,tcshCommentTi,@Spell
+syn match tcshComment	'\v#($|\S.*)' contains=tcshTodo,tcshCommentTi
+syn match tcshSharpBang '^#! .*$'
+syn match tcshCommentTi contained '\v#\s*\u\w*(\s+\u\w*)*:'hs=s+1 contains=tcshTodo
+syn match tcshTodo	contained '\v\c<todo>'
+
+" ----- Strings -----
+" Tcsh does not allow \" in strings unless the "backslash_quote" shell
+" variable is set. Set the vim variable "tcsh_backslash_quote" to 0 if you
+" want VIM to assume that no backslash quote constructs exist.
+
+" Backquotes are treated as commands, and are not contained in anything
+if(exists("tcsh_backslash_quote") && tcsh_backslash_quote == 0)
+    syn region tcshSQuote	keepend contained start="\v\\@<!'" end="'" contains=@Spell
+    syn region tcshDQuote	keepend contained start='\v\\@<!"' end='"' contains=@tcshVarList,tcshSpecial,@Spell
+    syn region tcshBQuote	keepend start='\v\\@<!`' end='`' contains=@tcshStatements
+else
+    syn region tcshSQuote	contained start="\v\\@<!'" skip="\v\\\\|\\'" end="'" contains=@Spell
+    syn region tcshDQuote	contained start='\v\\@<!"' end='"' contains=@tcshVarList,tcshSpecial,@Spell
+    syn region tcshBQuote	keepend matchgroup=tcshBQuoteGrp start='\v\\@<!`' skip='\v\\\\|\\`' end='`' contains=@tcshStatements
+endif
+
+" ----- Variables -----
+" Variable Errors. Must come first! \$ constructs will be flagged by
+" tcshSpecial, so we don't consider them here.
+syn match tcshVarError	'\v\$\S*'	contained
+
+" Modifiable Variables without {}.
+syn match tcshUsrVar contained "\v\$\h\w*%(\[\d+%(-\d+)?\])?" nextgroup=@tcshModifiers contains=tcshShellVar,tcshEnvVar
+syn match tcshArgv   contained "\v\$%(\d+|\*)" nextgroup=@tcshModifiers
+
+" Modifiable Variables with {}.
+syn match tcshUsrVar contained "\v\$\{\h\w*%(\[\d+%(-\d+)?\])?%(:\S*)?\}" contains=@tcshModifiers,tcshShellVar,tcshEnvVar
+syn match tcshArgv   contained "\v\$\{%(\d+|\*)%(:\S*)?\}" contains=@tcshModifiers
+
+" UnModifiable Substitutions. Order is important here.
+syn match tcshSubst contained	"\v\$[?#$!_<]" nextgroup=tcshModifierError
+syn match tcshSubst contained	"\v\$[%#?]%(\h\w*|\d+)" nextgroup=tcshModifierError contains=tcshShellVar,tcshEnvVar
+syn match tcshSubst contained	"\v\$\{[%#?]%(\h\w*|\d+)%(:\S*)?\}" contains=tcshModifierError contains=tcshShellVar,tcshEnvVar
+
+" Variable Name Expansion Modifiers (order important)
+syn match tcshModifierError	contained '\v:\S*'
+syn match tcshModifier		contained '\v:[ag]?[htreuls&qx]' nextgroup=@tcshModifiers
+
+" ----- Operators / Specials -----
+" Standard redirects (except <<) [<, >, >>, >>&, >>!, >>&!]
+syn match tcshRedir contained	"\v\<|\>\>?\&?!?"
+
+" Metachars
+syn match tcshMeta  contained	"\v[]{}*?[]"
+
+" Here Documents (<<)
+syn region tcshHereDoc contained matchgroup=tcshRedir start="\v\<\<\s*\z(\h\w*)" end="^\z1$" contains=@tcshVarList,tcshSpecial
+syn region tcshHereDoc contained matchgroup=tcshRedir start="\v\<\<\s*'\z(\h\w*)'" start='\v\<\<\s*"\z(\h\w*)"$' start="\v\<\<\s*\\\z(\h\w*)$" end="^\z1$"
+
+" Operators
+syn match tcshOperator	contained "&&\|!\~\|!=\|<<\|<=\|==\|=\~\|>=\|>>\|\*\|\^\|\~\|||\|!\|%\|&\|+\|-\|/\|<\|>\||"
+syn match tcshOperator	contained "[(){}]"
+
+" Numbers
+syn match tcshNumber	contained "\v<-?\d+>"
+
+" Arguements
+syn match tcshArguement	contained "\v\s@<=-(\w|-)*"
+
+" Special charectors
+syn match tcshSpecial	contained "\v\\@<!\\(\d{3}|.)"
+
+" ----- Syncronising -----
+if exists("tcsh_minlines")
+    exec "syn sync minlines=" . tcsh_minlines
+else
+    syn sync minlines=15	" Except 'here' documents, nothing is long
+endif
+
+" Define highlighting of syntax groups
+hi def link tcshBuiltins	statement
+hi def link tcshShellVar	preproc
+hi def link tcshEnvVar		tcshShellVar
+hi def link tcshAliases		tcshShellVar
+hi def link tcshAliCmd		identifier
+hi def link tcshCommands	identifier
+hi def link tcshSet		tcshBuiltins
+hi def link tcshSetEnv		tcshBuiltins
+hi def link tcshAlias		tcshBuiltins
+hi def link tcshIf		tcshBuiltins
+hi def link tcshElse		tcshBuiltins
+hi def link tcshWhile		tcshBuiltins
+hi def link tcshExprStart	tcshBuiltins
+hi def link tcshExprVar		tcshUsrVar
+hi def link tcshExprOp		tcshOperator
+hi def link tcshExprEnd		tcshOperator
+hi def link tcshComment		comment
+hi def link tcshCommentTi	preproc
+hi def link tcshSharpBang	tcshCommentTi
+hi def link tcshTodo		todo
+hi def link tcshSQuote		constant
+hi def link tcshDQuote		tcshSQuote
+hi def link tcshBQuoteGrp	include
+hi def link tcshVarError	error
+hi def link tcshUsrVar		type
+hi def link tcshArgv		tcshUsrVar
+hi def link tcshSubst		tcshUsrVar
+hi def link tcshModifier	tcshArguement
+hi def link tcshModifierError	tcshVarError
+hi def link tcshMeta		tcshSubst
+hi def link tcshRedir		tcshOperator
+hi def link tcshHereDoc		tcshSQuote
+hi def link tcshOperator	operator
+hi def link tcshNumber		number
+hi def link tcshArguement	special
+hi def link tcshSpecial		specialchar
+
+let b:current_syntax = "tcsh"
--- /dev/null
+++ b/lib/vimfiles/syntax/terminfo.vim
@@ -1,0 +1,93 @@
+" Vim syntax file
+" Language:         terminfo(5) definition
+" Maintainer:       Nikolai Weibull <now@bitwi.se>
+" Latest Revision:  2006-04-19
+
+if exists("b:current_syntax")
+  finish
+endif
+
+let s:cpo_save = &cpo
+set cpo&vim
+
+syn match terminfoKeywords      '[,=#|]'
+
+syn keyword terminfoTodo        contained TODO FIXME XXX NOTE
+
+syn region  terminfoComment     display oneline start='^#' end='$'
+                                \ contains=terminfoTodo,@Spell
+
+syn match   terminfoNumbers     '\<[0-9]\+\>'
+
+syn match   terminfoSpecialChar '\\\(\o\{3}\|[Eenlrtbfs^\,:0]\)'
+syn match   terminfoSpecialChar '\^\a'
+
+syn match   terminfoDelay       '$<[0-9]\+>'
+
+syn keyword terminfoBooleans    bw am bce ccc xhp xhpa cpix crxw xt xenl eo gn
+                                \ hc chts km daisy hs hls in lpix da db mir
+                                \ msgr nxon xsb npc ndscr nrrmc os mc5i xcpa
+                                \ sam eslok hz ul xon
+
+syn keyword terminfoNumerics    cols it lh lw lines lm xmc ma colors pairs wnum
+                                \ ncv nlab pb vt wsl bitwin bitype bufsz btns
+                                \ spinh spinv maddr mjump mcs npins orc orhi
+                                \ orl orvi cps widcs
+
+syn keyword terminfoStrings     acsc cbt bel cr cpi lpi chr cvr csr rmp tbc mgc
+                                \ clear el1 el ed hpa cmdch cwin cup cud1 home
+                                \ civis cub1 mrcup cnorm cuf1 ll cuu1 cvvis
+                                \ defc dch1 dl1 dial dsl dclk hd enacs smacs
+                                \ smam blink bold smcup smdc dim swidm sdrfq
+                                \ smir sitm slm smicm snlq snrmq prot rev
+                                \ invis sshm smso ssubm ssupm smul sum smxon
+                                \ ech rmacs rmam sgr0 rmcup rmdc rwidm rmir
+                                \ ritm rlm rmicm rshm rmso rsubm rsupm rmul
+                                \ rum rmxon pause hook flash ff fsl wingo hup
+                                \ is1 is2 is3 if iprog initc initp ich1 il1 ip
+                                \ ka1 ka3 kb2 kbs kbeg kcbt kc1 kc3 kcan ktbc
+                                \ kclr kclo kcmd kcpy kcrt kctab kdch1 kdl1
+                                \ kcud1 krmir kend kent kel ked kext kfnd khlp
+                                \ khome kich1 kil1 kcub1 kll kmrk kmsg kmov
+                                \ knxt knp kopn kopt kpp kprv kprt krdo kref
+                                \ krfr krpl krst kres kcuf1 ksav kBEG kCAN
+                                \ kCMD kCPY kCRT kDC kDL kslt kEND kEOL kEXT
+                                \ kind kFND kHLP kHOM kIC kLFT kMSG kMOV kNXT
+                                \ kOPT kPRV kPRT kri kRDO kRPL kRIT kRES kSAV
+                                \ kSPD khts kUND kspd kund kcuu1 rmkx smkx
+                                \ lf0 lf1 lf10 lf2 lf3 lf4 lf5 lf6 lf7 lf8 lf9
+                                \ fln rmln smln rmm smm mhpa mcud1 mcub1 mcuf1
+                                \ mvpa mcuu1 nel porder oc op pad dch dl cud
+                                \ mcud ich indn il cub mcub cuf mcuf rin cuu
+                                \ mccu pfkey pfloc pfx pln mc0 mc5p mc4 mc5
+                                \ pulse qdial rmclk rep rfi rs1 rs2 rs3 rf rc
+                                \ vpa sc ind ri scs sgr setbsmgb smgbp sclk
+                                \ scp setb setf smgl smglp smgr smgrp hts smgt
+                                \ smgtp wind sbim scsd rbim rcsd subcs supcs
+                                \ ht docr tsl tone uc hu u0 u1 u2 u3 u4 u5 u6
+                                \ u7 u8 u9 wait xoffc xonc zerom scesa bicr
+                                \ binel birep csnm csin colornm defbi devt
+                                \ dispc endbi smpch smsc rmpch rmsc getm kmous
+                                \ minfo pctrm pfxl reqmp scesc s0ds s1ds s2ds
+                                \ s3ds setab setaf setcolor smglr slines smgtb
+                                \ ehhlm elhlm erhlm ethlm evhlm sgr1 slengthsL
+syn match terminfoStrings       display '\<kf\([0-9]\|[0-5][0-9]\|6[0-3]\)\>'
+
+syn match terminfoParameters    '%[%dcspl+*/mAO&|^=<>!~i?te;-]'
+syn match terminfoParameters    "%\('[A-Z]'\|{[0-9]\{1,2}}\|p[1-9]\|P[a-z]\|g[A-Z]\)"
+
+hi def link terminfoComment     Comment
+hi def link terminfoTodo        Todo
+hi def link terminfoNumbers     Number
+hi def link terminfoSpecialChar SpecialChar
+hi def link terminfoDelay       Special
+hi def link terminfoBooleans    Type
+hi def link terminfoNumerics    Type
+hi def link terminfoStrings     Type
+hi def link terminfoParameters  Keyword
+hi def link terminfoKeywords    Keyword
+
+let b:current_syntax = "terminfo"
+
+let &cpo = s:cpo_save
+unlet s:cpo_save
--- /dev/null
+++ b/lib/vimfiles/syntax/tex.vim
@@ -1,0 +1,544 @@
+" Vim syntax file
+" Language:	TeX
+" Maintainer:	Dr. Charles E. Campbell, Jr. <NdrchipO@ScampbellPfamily.AbizM>
+" Last Change:	Feb 27, 2007
+" Version:	37
+" URL:		http://mysite.verizon.net/astronaut/vim/index.html#vimlinks_syntax
+"
+" Notes: {{{1
+"
+" 1. If you have a \begin{verbatim} that appears to overrun its boundaries,
+"    use %stopzone.
+"
+" 2. Run-on equations ($..$ and $$..$$, particularly) can also be stopped
+"    by suitable use of %stopzone.
+"
+" 3. If you have a slow computer, you may wish to modify
+"
+"	syn sync maxlines=200
+"	syn sync minlines=50
+"
+"    to values that are more to your liking.
+"
+" 4. There is no match-syncing for $...$ and $$...$$; hence large
+"    equation blocks constructed that way may exhibit syncing problems.
+"    (there's no difference between begin/end patterns)
+"
+" 5. If you have the variable "g:tex_no_error" defined then none of the
+"    lexical error-checking will be done.
+"
+"    ie. let g:tex_no_error=1
+
+" Version Clears: {{{1
+" For version 5.x: Clear all syntax items
+" For version 6.x: Quit when a syntax file was already loaded
+if version < 600
+  syntax clear
+elseif exists("b:current_syntax")
+  finish
+endif
+
+" Define the default highlighting. {{{1
+" For version 5.7 and earlier: only when not done already
+" For version 5.8 and later: only when an item doesn't have highlighting yet
+if version >= 508 || !exists("did_tex_syntax_inits")
+ let did_tex_syntax_inits = 1
+ if version < 508
+  command -nargs=+ HiLink hi link <args>
+ else
+  command -nargs=+ HiLink hi def link <args>
+ endif
+endif
+if exists("g:tex_tex") && !exists("g:tex_no_error")
+ let g:tex_no_error= 1
+endif
+
+" Determine whether or not to use "*.sty" mode {{{1
+" The user may override the normal determination by setting
+"   g:tex_stylish to 1      (for    "*.sty" mode)
+"    or to           0 else (normal "*.tex" mode)
+" or on a buffer-by-buffer basis with b:tex_stylish
+let b:extfname=expand("%:e")
+if exists("g:tex_stylish")
+ let b:tex_stylish= g:tex_stylish
+elseif !exists("b:tex_stylish")
+ if b:extfname == "sty" || b:extfname == "cls" || b:extfname == "clo" || b:extfname == "dtx" || b:extfname == "ltx"
+  let b:tex_stylish= 1
+ else
+  let b:tex_stylish= 0
+ endif
+endif
+
+" handle folding {{{1
+if !exists("g:tex_fold_enabled")
+ let g:tex_fold_enabled= 0
+elseif g:tex_fold_enabled && !has("folding")
+ let g:tex_fold_enabled= 0
+ echomsg "Ignoring g:tex_fold_enabled=".g:tex_fold_enabled."; need to re-compile vim for +fold support"
+endif
+if g:tex_fold_enabled && &fdm == "manual"
+ set fdm=syntax
+endif
+
+" (La)TeX keywords: only use the letters a-zA-Z {{{1
+" but _ is the only one that causes problems.
+if version < 600
+  set isk-=_
+  if b:tex_stylish
+    set isk+=@
+  endif
+else
+  setlocal isk-=_
+  if b:tex_stylish
+    setlocal isk+=@
+  endif
+endif
+
+" Clusters: {{{1
+" --------
+syn cluster texCmdGroup		contains=texCmdBody,texComment,texDefParm,texDelimiter,texDocType,texInput,texLength,texLigature,texMathDelim,texMathOper,texNewCmd,texNewEnv,texRefZone,texSection,texSectionMarker,texSectionName,texSpecialChar,texStatement,texString,texTypeSize,texTypeStyle
+if !exists("g:tex_no_error")
+ syn cluster texCmdGroup	add=texMathError
+endif
+syn cluster texEnvGroup		contains=texMatcher,texMathDelim,texSpecialChar,texStatement
+syn cluster texFoldGroup	contains=texAccent,texBadMath,texComment,texDefCmd,texDelimiter,texDocType,texInput,texInputFile,texLength,texLigature,texMatcher,texMathZoneV,texMathZoneW,texMathZoneX,texMathZoneY,texMathZoneZ,texNewCmd,texNewEnv,texOnlyMath,texOption,texParen,texRefZone,texSection,texSectionMarker,texSectionZone,texSpaceCode,texSpecialChar,texStatement,texString,texTypeSize,texTypeStyle,texZone,@texMathZones,texTitle,texAbstract
+syn cluster texMatchGroup	contains=texAccent,texBadMath,texComment,texDefCmd,texDelimiter,texDocType,texInput,texLength,texLigature,texMatcher,texNewCmd,texNewEnv,texOnlyMath,texParen,texRefZone,texSection,texSpecialChar,texStatement,texString,texTypeSize,texTypeStyle,texZone,texInputFile,texOption,@Spell
+syn cluster texRefGroup		contains=texMatcher,texComment,texDelimiter
+if !exists("tex_no_math")
+ syn cluster texMathZones	contains=texMathZoneV,texMathZoneW,texMathZoneX,texMathZoneY,texMathZoneZ
+ syn cluster texMatchGroup	add=@texMathZones
+ syn cluster texMathDelimGroup	contains=texMathDelimBad,texMathDelimKey,texMathDelimSet1,texMathDelimSet2
+ syn cluster texMathMatchGroup	contains=@texMathZones,texComment,texDefCmd,texDelimiter,texDocType,texInput,texLength,texLigature,texMathDelim,texMathMatcher,texMathOper,texNewCmd,texNewEnv,texRefZone,texSection,texSpecialChar,texStatement,texString,texTypeSize,texTypeStyle,texZone
+ syn cluster texMathZoneGroup	contains=texComment,texDelimiter,texLength,texMathDelim,texMathMatcher,texMathOper,texRefZone,texSpecialChar,texStatement,texTypeSize,texTypeStyle
+ if !exists("g:tex_no_error")
+  syn cluster texMathMatchGroup	add=texMathError
+  syn cluster texMathZoneGroup	add=texMathError
+ endif
+ syn cluster texMathZoneGroup add=@NoSpell
+ " following used in the \part \chapter \section \subsection \subsubsection
+ " \paragraph \subparagraph \author \title highlighting
+ syn cluster texDocGroup		contains=texPartZone,@texPartGroup
+ syn cluster texPartGroup		contains=texChapterZone,texSectionZone,texParaZone
+ syn cluster texChapterGroup		contains=texSectionZone,texParaZone
+ syn cluster texSectionGroup		contains=texSubSectionZone,texParaZone
+ syn cluster texSubSectionGroup		contains=texSubSubSectionZone,texParaZone
+ syn cluster texSubSubSectionGroup	contains=texParaZone
+ syn cluster texParaGroup		contains=texSubParaZone
+endif
+
+" Try to flag {} and () mismatches: {{{1
+if !exists("g:tex_no_error")
+ syn region texMatcher		matchgroup=Delimiter start="{" skip="\\\\\|\\[{}]"	end="}"		contains=@texMatchGroup,texError
+ syn region texMatcher		matchgroup=Delimiter start="\["				end="]"		contains=@texMatchGroup,texError
+else
+ syn region texMatcher		matchgroup=Delimiter start="{" skip="\\\\\|\\[{}]"	end="}"		contains=@texMatchGroup
+ syn region texMatcher		matchgroup=Delimiter start="\["				end="]"		contains=@texMatchGroup
+endif
+syn region texParen		start="("						end=")"		contains=@texMatchGroup,@Spell
+if !exists("g:tex_no_error")
+ syn match  texError		"[}\])]"
+endif
+if !exists("tex_no_math")
+ if !exists("g:tex_no_error")
+  syn match  texMathError	"}"	contained
+ endif
+ syn region texMathMatcher	matchgroup=Delimiter start="{"  skip="\\\\\|\\}"  end="}" end="%stopzone\>" contained contains=@texMathMatchGroup
+endif
+
+" TeX/LaTeX keywords: {{{1
+" Instead of trying to be All Knowing, I just match \..alphameric..
+" Note that *.tex files may not have "@" in their \commands
+if exists("g:tex_tex") || b:tex_stylish
+  syn match texStatement	"\\[a-zA-Z@]\+"
+else
+  syn match texStatement	"\\\a\+"
+  if !exists("g:tex_no_error")
+   syn match texError		"\\\a*@[a-zA-Z@]*"
+  endif
+endif
+
+" TeX/LaTeX delimiters: {{{1
+syn match texDelimiter		"&"
+syn match texDelimiter		"\\\\"
+
+" Tex/Latex Options: {{{1
+syn match texOption	"[^\\]\zs#\d\+\|^#\d\+"
+
+" texAccent (tnx to Karim Belabas) avoids annoying highlighting for accents: {{{1
+if b:tex_stylish
+  syn match texAccent		"\\[bcdvuH][^a-zA-Z@]"me=e-1
+  syn match texLigature		"\\\([ijolL]\|ae\|oe\|ss\|AA\|AE\|OE\)[^a-zA-Z@]"me=e-1
+else
+  syn match texAccent		"\\[bcdvuH]\A"me=e-1
+  syn match texLigature		"\\\([ijolL]\|ae\|oe\|ss\|AA\|AE\|OE\)\A"me=e-1
+endif
+syn match texAccent		"\\[bcdvuH]$"
+syn match texAccent		+\\[=^.\~"`']+
+syn match texAccent		+\\['=t'.c^ud"vb~Hr]{\a}+
+syn match texLigature		"\\\([ijolL]\|ae\|oe\|ss\|AA\|AE\|OE\)$"
+
+" \begin{}/\end{} section markers: {{{1
+syn match  texSectionMarker	"\\begin\>\|\\end\>" nextgroup=texSectionName
+syn region texSectionName	matchgroup=Delimiter start="{" end="}"  contained nextgroup=texSectionModifier
+syn region texSectionModifier	matchgroup=Delimiter start="\[" end="]" contained
+
+" \documentclass, \documentstyle, \usepackage: {{{1
+syn match  texDocType		"\\documentclass\>\|\\documentstyle\>\|\\usepackage\>"	nextgroup=texSectionName,texDocTypeArgs
+syn region texDocTypeArgs	matchgroup=Delimiter start="\[" end="]"			contained	nextgroup=texSectionName
+
+" Preamble syntax-based folding support: {{{1
+if g:tex_fold_enabled && has("folding")
+ syn region texPreamble	transparent fold	start='\zs\\documentclass\>' end='\ze\\begin{document}'	contains=@texMatchGroup
+endif
+
+" TeX input: {{{1
+syn match texInput		"\\input\s\+[a-zA-Z/.0-9_^]\+"hs=s+7				contains=texStatement
+syn match texInputFile		"\\include\(graphics\|list\)\=\(\[.\{-}\]\)\=\s*{.\{-}}"	contains=texStatement,texInputCurlies
+syn match texInputFile		"\\\(epsfig\|input\|usepackage\)\s*\(\[.*\]\)\={.\{-}}"		contains=texStatement,texInputCurlies,texInputFileOpt
+syn match texInputCurlies	"[{}]"								contained
+syn region texInputFileOpt	matchgroup=Delimiter start="\[" end="\]"			contained
+
+" Type Styles (LaTeX 2.09): {{{1
+syn match texTypeStyle		"\\rm\>"
+syn match texTypeStyle		"\\em\>"
+syn match texTypeStyle		"\\bf\>"
+syn match texTypeStyle		"\\it\>"
+syn match texTypeStyle		"\\sl\>"
+syn match texTypeStyle		"\\sf\>"
+syn match texTypeStyle		"\\sc\>"
+syn match texTypeStyle		"\\tt\>"
+
+" Type Styles: attributes, commands, families, etc (LaTeX2E): {{{1
+syn match texTypeStyle		"\\textbf\>"
+syn match texTypeStyle		"\\textit\>"
+syn match texTypeStyle		"\\textmd\>"
+syn match texTypeStyle		"\\textrm\>"
+syn match texTypeStyle		"\\textsc\>"
+syn match texTypeStyle		"\\textsf\>"
+syn match texTypeStyle		"\\textsl\>"
+syn match texTypeStyle		"\\texttt\>"
+syn match texTypeStyle		"\\textup\>"
+syn match texTypeStyle		"\\emph\>"
+
+syn match texTypeStyle		"\\mathbb\>"
+syn match texTypeStyle		"\\mathbf\>"
+syn match texTypeStyle		"\\mathcal\>"
+syn match texTypeStyle		"\\mathfrak\>"
+syn match texTypeStyle		"\\mathit\>"
+syn match texTypeStyle		"\\mathnormal\>"
+syn match texTypeStyle		"\\mathrm\>"
+syn match texTypeStyle		"\\mathsf\>"
+syn match texTypeStyle		"\\mathtt\>"
+
+syn match texTypeStyle		"\\rmfamily\>"
+syn match texTypeStyle		"\\sffamily\>"
+syn match texTypeStyle		"\\ttfamily\>"
+
+syn match texTypeStyle		"\\itshape\>"
+syn match texTypeStyle		"\\scshape\>"
+syn match texTypeStyle		"\\slshape\>"
+syn match texTypeStyle		"\\upshape\>"
+
+syn match texTypeStyle		"\\bfseries\>"
+syn match texTypeStyle		"\\mdseries\>"
+
+" Some type sizes: {{{1
+syn match texTypeSize		"\\tiny\>"
+syn match texTypeSize		"\\scriptsize\>"
+syn match texTypeSize		"\\footnotesize\>"
+syn match texTypeSize		"\\small\>"
+syn match texTypeSize		"\\normalsize\>"
+syn match texTypeSize		"\\large\>"
+syn match texTypeSize		"\\Large\>"
+syn match texTypeSize		"\\LARGE\>"
+syn match texTypeSize		"\\huge\>"
+syn match texTypeSize		"\\Huge\>"
+
+" Spacecodes (TeX'isms): {{{1
+" \mathcode`\^^@="2201  \delcode`\(="028300  \sfcode`\)=0 \uccode`X=`X  \lccode`x=`x
+syn match texSpaceCode		"\\\(math\|cat\|del\|lc\|sf\|uc\)code`"me=e-1 nextgroup=texSpaceCodeChar
+syn match texSpaceCodeChar    "`\\\=.\(\^.\)\==\(\d\|\"\x\{1,6}\|`.\)"	contained
+
+" Sections, subsections, etc: {{{1
+if g:tex_fold_enabled && has("folding")
+ syn region texDocZone			matchgroup=texSection start='\\begin\s*{\s*document\s*}' end='\\end\s*{\s*document\s*}'	fold contains=@texFoldGroup,@texDocGroup,@Spell
+ syn region texPartZone			matchgroup=texSection start='\\part\>'			 end='\n\ze\s*\\part\>'		fold contains=@texFoldGroup,@texPartGroup,@Spell
+ syn region texChapterZone		matchgroup=texSection start='\\chapter\>'		 end='\n\ze\s*\\chapter\>'	fold contains=@texFoldGroup,@texChapterGroup,@Spell
+ syn region texSectionZone		matchgroup=texSection start='\\section\>'		 end='\n\ze\s*\\section\>'	fold contains=@texFoldGroup,@texSectionGroup,@Spell
+ syn region texSubSectionZone		matchgroup=texSection start='\\subsection\>'		 end='\n\ze\s*\\subsection\>'	fold contains=@texFoldGroup,@texSubSectionGroup,@Spell
+ syn region texSubSubSectionZone	matchgroup=texSection start='\\subsubsection\>'		end='\n\ze\s*\\subsubsection\>'	fold contains=@texFoldGroup,@texSubSubSectionGroup,@Spell
+ syn region texParaZone			matchgroup=texSection start='\\paragraph\>'		 end='\n\ze\s*\\paragraph\>'	fold contains=@texFoldGroup,@texParaGroup,@Spell
+ syn region texSubParaZone		matchgroup=texSection start='\\subparagraph\>'		 end='\n\ze\s*\\subparagraph\>'	fold contains=@texFoldGroup,@Spell
+ syn region texTitle			matchgroup=texSection start='\\\%(author\|title\)\>\s*{' end='}'		fold contains=@texFoldGroup,@Spell
+ syn region texAbstract			matchgroup=texSection start='\\begin\s*{\s*abstract\s*}' end='\\end\s*{\s*abstract\s*}'	fold contains=@texFoldGroup,@Spell
+else
+ syn region texDocZone			matchgroup=texSection start='\\begin\s*{\s*document\s*}' end='\\end\s*{\s*document\s*}'	contains=@texFoldGroup,@texDocGroup,@Spell
+ syn region texPartZone			matchgroup=texSection start='\\part\>'			 end='\n\ze\s*\\part\>'		contains=@texFoldGroup,@texPartGroup,@Spell
+ syn region texChapterZone		matchgroup=texSection start='\\chapter\>'		 end='\n\ze\s*\\chapter\>'	contains=@texFoldGroup,@texChapterGroup,@Spell
+ syn region texSectionZone		matchgroup=texSection start='\\section\>'		 end='\n\ze\s*\\section\>'	contains=@texFoldGroup,@texSectionGroup,@Spell
+ syn region texSubSectionZone		matchgroup=texSection start='\\subsection\>'		 end='\n\ze\s*\\subsection\>'	contains=@texFoldGroup,@texSubSectionGroup,@Spell
+ syn region texSubSubSectionZone	matchgroup=texSection start='\\subsubsection\>'		end='\n\ze\s*\\subsubsection\>'	contains=@texFoldGroup,@texSubSubSectionGroup,@Spell
+ syn region texParaZone			matchgroup=texSection start='\\paragraph\>'		 end='\n\ze\s*\\paragraph\>'	contains=@texFoldGroup,@texParaGroup,@Spell
+ syn region texSubParaZone		matchgroup=texSection start='\\subparagraph\>'		 end='\n\ze\s*\\subparagraph\>'	contains=@texFoldGroup,@Spell
+ syn region texTitle			matchgroup=texSection start='\\\%(author\|title\)\>\s*{' end='}'			contains=@texFoldGroup,@Spell
+ syn region texAbstract			matchgroup=texSection start='\\begin\s*{\s*abstract\s*}' end='\\end\s*{\s*abstract\s*}'	contains=@texFoldGroup,@Spell
+endif
+
+" Bad Math (mismatched): {{{1
+if !exists("tex_no_math")
+ syn match texBadMath		"\\end\s*{\s*\(array\|gathered\|bBpvV]matrix\|split\|subequations\|smallmatrix\|xxalignat\)\s*}"
+ syn match texBadMath		"\\end\s*{\s*\(align\|alignat\|displaymath\|displaymath\|eqnarray\|equation\|flalign\|gather\|math\|multline\|xalignat\)\*\=\s*}"
+ syn match texBadMath		"\\[\])]"
+endif
+
+" Math Zones: {{{1
+if !exists("tex_no_math")
+ " TexNewMathZone: function creates a mathzone with the given suffix and mathzone name. {{{2
+ "                 Starred forms are created if starform is true.  Starred
+ "                 forms have syntax group and synchronization groups with a
+ "                 "S" appended.  Handles: cluster, syntax, sync, and HiLink.
+ fun! TexNewMathZone(sfx,mathzone,starform)
+   let grpname  = "texMathZone".a:sfx
+   let syncname = "texSyncMathZone".a:sfx
+   exe "syn cluster texMathZones add=".grpname
+   exe 'syn region '.grpname.' start='."'".'\\begin\s*{\s*'.a:mathzone.'\s*}'."'".' end='."'".'\\end\s*{\s*'.a:mathzone.'\s*}'."'".' keepend contains=@texMathZoneGroup'
+   exe 'syn sync match '.syncname.' grouphere '.grpname.' "\\begin\s*{\s*'.a:mathzone.'\*\s*}"'
+   exe 'syn sync match '.syncname.' grouphere '.grpname.' "\\begin\s*{\s*'.a:mathzone.'\*\s*}"'
+   exe 'HiLink '.grpname.' texMath'
+   if a:starform
+    let grpname  = "texMathZone".a:sfx.'S'
+    let syncname = "texSyncMathZone".a:sfx.'S'
+    exe "syn cluster texMathZones add=".grpname
+    exe 'syn region '.grpname.' start='."'".'\\begin\s*{\s*'.a:mathzone.'\*\s*}'."'".' end='."'".'\\end\s*{\s*'.a:mathzone.'\*\s*}'."'".' keepend contains=@texMathZoneGroup'
+    exe 'syn sync match '.syncname.' grouphere '.grpname.' "\\begin\s*{\s*'.a:mathzone.'\*\s*}"'
+    exe 'syn sync match '.syncname.' grouphere '.grpname.' "\\begin\s*{\s*'.a:mathzone.'\*\s*}"'
+    exe 'HiLink '.grpname.' texMath'
+   endif
+ endfun
+
+ " Standard Math Zones: {{{2
+ call TexNewMathZone("A","align",1)
+ call TexNewMathZone("B","alignat",1)
+ call TexNewMathZone("C","displaymath",1)
+ call TexNewMathZone("D","eqnarray",1)
+ call TexNewMathZone("E","equation",1)
+ call TexNewMathZone("F","flalign",1)
+ call TexNewMathZone("G","gather",1)
+ call TexNewMathZone("H","math",1)
+ call TexNewMathZone("I","multline",1)
+ call TexNewMathZone("J","subequations",0)
+ call TexNewMathZone("K","xalignat",1)
+ call TexNewMathZone("L","xxalignat",0)
+
+ " Inline Math Zones: {{{2
+ syn region texMathZoneV	matchgroup=Delimiter start="\\("	matchgroup=Delimiter end="\\)\|%stopzone\>"	keepend contains=@texMathZoneGroup
+ syn region texMathZoneW	matchgroup=Delimiter start="\\\["	matchgroup=Delimiter end="\\]\|%stopzone\>"	keepend contains=@texMathZoneGroup
+ syn region texMathZoneX	matchgroup=Delimiter start="\$" skip="\\\\\|\\\$" matchgroup=Delimiter end="\$" end="%stopzone\>"	contains=@texMathZoneGroup
+ syn region texMathZoneY	matchgroup=Delimiter start="\$\$" matchgroup=Delimiter end="\$\$" end="%stopzone\>"	keepend		contains=@texMathZoneGroup
+ syn region texMathZoneZ	matchgroup=texStatement start="\\ensuremath\s*{" matchgroup=texStatement end="}" end="%stopzone\>"	contains=@texMathZoneGroup
+
+ syn match texMathOper		"[_^=]" contained
+
+ " \left..something.. and \right..something.. support: {{{2
+ syn match   texMathDelimBad	contained		"\S"
+ syn match   texMathDelim	contained		"\\\(left\|right\|[bB]igg\=[lr]\)\>"	skipwhite nextgroup=texMathDelimSet1,texMathDelimSet2,texMathDelimBad
+ syn match   texMathDelim	contained		"\\\(left\|right\)arrow\>\|\<\([aA]rrow\|brace\)\=vert\>"
+ syn match   texMathDelim	contained		"\\lefteqn\>"
+ syn match   texMathDelimSet2	contained	"\\"		nextgroup=texMathDelimKey,texMathDelimBad
+ syn match   texMathDelimSet1	contained	"[<>()[\]|/.]\|\\[{}|]"
+ syn keyword texMathDelimKey	contained	backslash       lceil           lVert           rgroup          uparrow
+ syn keyword texMathDelimKey	contained	downarrow       lfloor          rangle          rmoustache      Uparrow
+ syn keyword texMathDelimKey	contained	Downarrow       lgroup          rbrace          rvert           updownarrow
+ syn keyword texMathDelimKey	contained	langle          lmoustache      rceil           rVert           Updownarrow
+ syn keyword texMathDelimKey	contained	lbrace          lvert           rfloor
+endif
+
+" Special TeX characters  ( \$ \& \% \# \{ \} \_ \S \P ) : {{{1
+syn match texSpecialChar	"\\[$&%#{}_]"
+if b:tex_stylish
+  syn match texSpecialChar	"\\[SP@][^a-zA-Z@]"me=e-1
+else
+  syn match texSpecialChar	"\\[SP@]\A"me=e-1
+endif
+syn match texSpecialChar	"\\\\"
+if !exists("tex_no_math")
+ syn match texOnlyMath		"[_^]"
+endif
+syn match texSpecialChar	"\^\^[0-9a-f]\{2}\|\^\^\S"
+
+" Comments: {{{1
+"    Normal TeX LaTeX     :   %....
+"    Documented TeX Format:  ^^A...	-and-	leading %s (only)
+syn cluster texCommentGroup	contains=texTodo,@Spell
+syn case ignore
+syn keyword texTodo		contained		combak	fixme	todo	xxx
+syn case match
+if b:extfname == "dtx"
+  syn match texComment		"\^\^A.*$"	contains=@texCommentGroup
+  syn match texComment		"^%\+"		contains=@texCommentGroup
+else
+  if g:tex_fold_enabled
+   " allows syntax-folding of 2 or more contiguous comment lines
+   " single-line comments are not folded
+   syn match  texComment	"%.*$"		contains=@texCommentGroup
+   syn region texComment	start="^\zs\s*%.*\_s*%"	skip="^\s*%"	end='^\ze\s*[^%]' fold
+  else
+   syn match texComment		"%.*$"		contains=@texCommentGroup
+  endif
+endif
+
+" Separate lines used for verb` and verb# so that the end conditions {{{1
+" will appropriately terminate.  Ideally vim would let me save a
+" character from the start pattern and re-use it in the end-pattern.
+syn region texZone		start="\\begin{verbatim}"		end="\\end{verbatim}\|%stopzone\>"	contains=@Spell
+" listings package:
+syn region texZone		start="\\begin{lstlisting}"		end="\\end{lstlisting}\|%stopzone\>"	contains=@Spell
+" moreverb package:
+syn region texZone		start="\\begin{verbatimtab}"		end="\\end{verbatimtab}\|%stopzone\>"	contains=@Spell
+syn region texZone		start="\\begin{verbatimwrite}"		end="\\end{verbatimwrite}\|%stopzone\>"	contains=@Spell
+syn region texZone		start="\\begin{boxedverbatim}"		end="\\end{boxedverbatim}\|%stopzone\>"	contains=@Spell
+if version < 600
+ syn region texZone		start="\\verb\*\=`"			end="`\|%stopzone\>"
+ syn region texZone		start="\\verb\*\=#"			end="#\|%stopzone\>"
+else
+  if b:tex_stylish
+    syn region texZone		start="\\verb\*\=\z([^\ta-zA-Z@]\)"	end="\z1\|%stopzone\>"
+  else
+    syn region texZone		start="\\verb\*\=\z([^\ta-zA-Z]\)"	end="\z1\|%stopzone\>"
+  endif
+endif
+
+" Tex Reference Zones: {{{1
+syn region texZone		matchgroup=texStatement start="@samp{"			end="}\|%stopzone\>"	contains=@texRefGroup
+syn region texRefZone		matchgroup=texStatement start="\\nocite{"		end="}\|%stopzone\>"	contains=@texRefGroup
+syn region texRefZone		matchgroup=texStatement start="\\bibliography{"		end="}\|%stopzone\>"	contains=@texRefGroup
+syn region texRefZone		matchgroup=texStatement start="\\label{"		end="}\|%stopzone\>"	contains=@texRefGroup
+syn region texRefZone		matchgroup=texStatement start="\\\(page\|eq\)ref{"	end="}\|%stopzone\>"	contains=@texRefGroup
+syn region texRefZone		matchgroup=texStatement start="\\v\=ref{"		end="}\|%stopzone\>"	contains=@texRefGroup
+syn match  texRefZone		'\\cite\%([tp]\*\=\)\=' nextgroup=texRefOption,texCite
+syn region texRefOption	contained	matchgroup=Delimiter start='\[' end=']'		contains=@texRefGroup	nextgroup=texRefOption,texCite
+syn region texCite	contained	matchgroup=Delimiter start='{' end='}'		contains=@texRefGroup
+
+" Handle newcommand, newenvironment : {{{1
+syn match  texNewCmd				"\\newcommand\>"			nextgroup=texCmdName skipwhite skipnl
+syn region texCmdName contained matchgroup=Delimiter start="{"rs=s+1  end="}"		nextgroup=texCmdArgs,texCmdBody skipwhite skipnl
+syn region texCmdArgs contained matchgroup=Delimiter start="\["rs=s+1 end="]"		nextgroup=texCmdBody skipwhite skipnl
+syn region texCmdBody contained matchgroup=Delimiter start="{"rs=s+1 skip="\\\\\|\\[{}]"	matchgroup=Delimiter end="}" contains=@texCmdGroup
+syn match  texNewEnv				"\\newenvironment\>"			nextgroup=texEnvName skipwhite skipnl
+syn region texEnvName contained matchgroup=Delimiter start="{"rs=s+1  end="}"		nextgroup=texEnvBgn skipwhite skipnl
+syn region texEnvBgn  contained matchgroup=Delimiter start="{"rs=s+1  end="}"		nextgroup=texEnvEnd skipwhite skipnl contains=@texEnvGroup
+syn region texEnvEnd  contained matchgroup=Delimiter start="{"rs=s+1  end="}"		skipwhite skipnl contains=@texEnvGroup
+
+" Definitions/Commands: {{{1
+syn match texDefCmd				"\\def\>"				nextgroup=texDefName skipwhite skipnl
+if b:tex_stylish
+  syn match texDefName contained		"\\[a-zA-Z@]\+"				nextgroup=texDefParms,texCmdBody skipwhite skipnl
+  syn match texDefName contained		"\\[^a-zA-Z@]"				nextgroup=texDefParms,texCmdBody skipwhite skipnl
+else
+  syn match texDefName contained		"\\\a\+"				nextgroup=texDefParms,texCmdBody skipwhite skipnl
+  syn match texDefName contained		"\\\A"					nextgroup=texDefParms,texCmdBody skipwhite skipnl
+endif
+syn match texDefParms  contained		"#[^{]*"	contains=texDefParm	nextgroup=texCmdBody skipwhite skipnl
+syn match  texDefParm  contained		"#\d\+"
+
+" TeX Lengths: {{{1
+syn match  texLength		"\<\d\+\([.,]\d\+\)\=\s*\(true\)\=\s*\(bp\|cc\|cm\|dd\|em\|ex\|in\|mm\|pc\|pt\|sp\)\>"
+
+" TeX String Delimiters: {{{1
+syn match texString		"\(``\|''\|,,\)"
+
+" LaTeX synchronization: {{{1
+syn sync maxlines=200
+syn sync minlines=50
+
+syn  sync match texSyncStop			groupthere NONE		"%stopzone\>"
+
+" Synchronization: {{{1
+" The $..$ and $$..$$ make for impossible sync patterns
+" (one can't tell if a "$$" starts or stops a math zone by itself)
+" The following grouptheres coupled with minlines above
+" help improve the odds of good syncing.
+if !exists("tex_no_math")
+ syn sync match texSyncMathZoneA		groupthere NONE		"\\end{abstract}"
+ syn sync match texSyncMathZoneA		groupthere NONE		"\\end{center}"
+ syn sync match texSyncMathZoneA		groupthere NONE		"\\end{description}"
+ syn sync match texSyncMathZoneA		groupthere NONE		"\\end{enumerate}"
+ syn sync match texSyncMathZoneA		groupthere NONE		"\\end{itemize}"
+ syn sync match texSyncMathZoneA		groupthere NONE		"\\end{table}"
+ syn sync match texSyncMathZoneA		groupthere NONE		"\\end{tabular}"
+ syn sync match texSyncMathZoneA		groupthere NONE		"\\\(sub\)*section\>"
+endif
+
+" Highlighting: {{{1
+if did_tex_syntax_inits == 1
+ let did_tex_syntax_inits= 2
+  " TeX highlighting groups which should share similar highlighting
+  if !exists("g:tex_no_error")
+   if !exists("tex_no_math")
+    HiLink texBadMath		texError
+    HiLink texMathDelimBad	texError
+    HiLink texMathError		texError
+    if !b:tex_stylish
+      HiLink texOnlyMath	texError
+    endif
+   endif
+   HiLink texError		Error
+  endif
+
+  HiLink texCite		texRefZone
+  HiLink texDefCmd		texDef
+  HiLink texDefName		texDef
+  HiLink texDocType		texCmdName
+  HiLink texDocTypeArgs		texCmdArgs
+  HiLink texInputFileOpt	texCmdArgs
+  HiLink texInputCurlies	texDelimiter
+  HiLink texLigature		texSpecialChar
+  if !exists("tex_no_math")
+   HiLink texMathDelimSet1	texMathDelim
+   HiLink texMathDelimSet2	texMathDelim
+   HiLink texMathDelimKey	texMathDelim
+   HiLink texMathMatcher	texMath
+   HiLink texMathZoneW		texMath
+   HiLink texMathZoneX		texMath
+   HiLink texMathZoneY		texMath
+   HiLink texMathZoneZ		texMath
+  endif
+  HiLink texSectionMarker	texCmdName
+  HiLink texSectionName		texSection
+  HiLink texSpaceCode		texStatement
+  HiLink texTypeSize		texType
+  HiLink texTypeStyle		texType
+
+   " Basic TeX highlighting groups
+  HiLink texCmdArgs		Number
+  HiLink texCmdName		Statement
+  HiLink texComment		Comment
+  HiLink texDef			Statement
+  HiLink texDefParm		Special
+  HiLink texDelimiter		Delimiter
+  HiLink texInput		Special
+  HiLink texInputFile		Special
+  HiLink texLength		Number
+  HiLink texMath		Special
+  HiLink texMathDelim		Statement
+  HiLink texMathOper		Operator
+  HiLink texNewCmd		Statement
+  HiLink texNewEnv		Statement
+  HiLink texOption		Number
+  HiLink texRefZone		Special
+  HiLink texSection		PreCondit
+  HiLink texSpaceCodeChar	Special
+  HiLink texSpecialChar		SpecialChar
+  HiLink texStatement		Statement
+  HiLink texString		String
+  HiLink texTodo		Todo
+  HiLink texType		Type
+  HiLink texZone		PreCondit
+
+  delcommand HiLink
+endif
+
+" Current Syntax: {{{1
+unlet b:extfname
+let   b:current_syntax = "tex"
+" vim: ts=8 fdm=marker
--- /dev/null
+++ b/lib/vimfiles/syntax/texinfo.vim
@@ -1,0 +1,409 @@
+" Vim syntax file
+" Language:	Texinfo (macro package for TeX)
+" Maintainer:	Sandor Kopanyi <sandor.kopanyi@mailbox.hu>
+" URL:		<->
+" Last Change:	2004 Jun 23
+"
+" the file follows the Texinfo manual structure; this file is based
+" on manual for Texinfo version 4.0, 28 September 1999
+" since @ can have special meanings, everything is 'match'-ed and 'region'-ed
+" (including @ in 'iskeyword' option has unexpected effects)
+
+" Remove any old syntax stuff hanging around, if needed
+if version < 600
+  syn clear
+elseif exists("b:current_syntax")
+  finish
+endif
+
+if !exists("main_syntax")
+  let main_syntax = 'texinfo'
+endif
+
+"in Texinfo can be real big things, like tables; sync for that
+syn sync lines=200
+
+"some general stuff
+"syn match texinfoError     "\S" contained TODO
+syn match texinfoIdent	    "\k\+"		  contained "IDENTifier
+syn match texinfoAssignment "\k\+\s*=\s*\k\+\s*$" contained "assigment statement ( var = val )
+syn match texinfoSinglePar  "\k\+\s*$"		  contained "single parameter (used for several @-commands)
+syn match texinfoIndexPar   "\k\k\s*$"		  contained "param. used for different *index commands (+ @documentlanguage command)
+
+
+"marking words and phrases (chap. 9 in Texinfo manual)
+"(almost) everything appears as 'contained' too; is for tables (@table)
+
+"this chapter is at the beginning of this file to avoid overwritings
+
+syn match texinfoSpecialChar				    "@acronym"		contained
+syn region texinfoBrcPrmAtCmd matchgroup=texinfoAtCmd start="@acronym{" end="}" contains=texinfoSpecialChar,texinfoBrcPrmAtCmd
+syn match texinfoSpecialChar				    "@b"		contained
+syn region texinfoBrcPrmAtCmd matchgroup=texinfoAtCmd start="@b{"	end="}" contains=texinfoSpecialChar,texinfoBrcPrmAtCmd
+syn match texinfoSpecialChar				    "@cite"		contained
+syn region texinfoBrcPrmAtCmd matchgroup=texinfoAtCmd start="@cite{"	end="}" contains=texinfoSpecialChar,texinfoBrcPrmAtCmd
+syn match texinfoSpecialChar				    "@code"		contained
+syn region texinfoBrcPrmAtCmd matchgroup=texinfoAtCmd start="@code{"	end="}" contains=texinfoSpecialChar,texinfoBrcPrmAtCmd
+syn match texinfoSpecialChar				    "@command"		contained
+syn region texinfoBrcPrmAtCmd matchgroup=texinfoAtCmd start="@command{" end="}" contains=texinfoSpecialChar,texinfoBrcPrmAtCmd
+syn match texinfoSpecialChar				    "@dfn"		contained
+syn region texinfoBrcPrmAtCmd matchgroup=texinfoAtCmd start="@dfn{"	end="}" contains=texinfoSpecialChar,texinfoBrcPrmAtCmd
+syn match texinfoSpecialChar				    "@email"		contained
+syn region texinfoBrcPrmAtCmd matchgroup=texinfoAtCmd start="@email{"	end="}" contains=texinfoSpecialChar,texinfoBrcPrmAtCmd
+syn match texinfoSpecialChar				    "@emph"		contained
+syn region texinfoBrcPrmAtCmd matchgroup=texinfoAtCmd start="@emph{"	end="}" contains=texinfoSpecialChar,texinfoBrcPrmAtCmd
+syn match texinfoSpecialChar				    "@env"		contained
+syn region texinfoBrcPrmAtCmd matchgroup=texinfoAtCmd start="@env{"	end="}" contains=texinfoSpecialChar,texinfoBrcPrmAtCmd
+syn match texinfoSpecialChar				    "@file"		contained
+syn region texinfoBrcPrmAtCmd matchgroup=texinfoAtCmd start="@file{"	end="}" contains=texinfoSpecialChar,texinfoBrcPrmAtCmd
+syn match texinfoSpecialChar				    "@i"		contained
+syn region texinfoBrcPrmAtCmd matchgroup=texinfoAtCmd start="@i{"	end="}" contains=texinfoSpecialChar,texinfoBrcPrmAtCmd
+syn match texinfoSpecialChar				    "@kbd"		contained
+syn region texinfoBrcPrmAtCmd matchgroup=texinfoAtCmd start="@kbd{"	end="}" contains=texinfoSpecialChar,texinfoBrcPrmAtCmd
+syn match texinfoSpecialChar				    "@key"		contained
+syn region texinfoBrcPrmAtCmd matchgroup=texinfoAtCmd start="@key{"	end="}" contains=texinfoSpecialChar
+syn match texinfoSpecialChar				    "@option"		contained
+syn region texinfoBrcPrmAtCmd matchgroup=texinfoAtCmd start="@option{"	end="}" contains=texinfoSpecialChar
+syn match texinfoSpecialChar				    "@r"		contained
+syn region texinfoBrcPrmAtCmd matchgroup=texinfoAtCmd start="@r{"	end="}" contains=texinfoSpecialChar,texinfoBrcPrmAtCmd
+syn match texinfoSpecialChar				    "@samp"		contained
+syn region texinfoBrcPrmAtCmd matchgroup=texinfoAtCmd start="@samp{"	end="}" contains=texinfoSpecialChar,texinfoBrcPrmAtCmd
+syn match texinfoSpecialChar				    "@sc"		contained
+syn region texinfoBrcPrmAtCmd matchgroup=texinfoAtCmd start="@sc{"	end="}" contains=texinfoSpecialChar,texinfoBrcPrmAtCmd
+syn match texinfoSpecialChar				    "@strong"		contained
+syn region texinfoBrcPrmAtCmd matchgroup=texinfoAtCmd start="@strong{"	end="}" contains=texinfoSpecialChar,texinfoBrcPrmAtCmd
+syn match texinfoSpecialChar				    "@t"		contained
+syn region texinfoBrcPrmAtCmd matchgroup=texinfoAtCmd start="@t{"	end="}" contains=texinfoSpecialChar,texinfoBrcPrmAtCmd
+syn match texinfoSpecialChar				    "@url"		contained
+syn region texinfoBrcPrmAtCmd matchgroup=texinfoAtCmd start="@url{"	end="}" contains=texinfoSpecialChar,texinfoBrcPrmAtCmd
+syn match texinfoSpecialChar				    "@var"		contained
+syn region texinfoBrcPrmAtCmd matchgroup=texinfoAtCmd start="@var{"	end="}" contains=texinfoSpecialChar,texinfoBrcPrmAtCmd
+syn match texinfoAtCmd "^@kbdinputstyle" nextgroup=texinfoSinglePar skipwhite
+
+
+"overview of Texinfo (chap. 1 in Texinfo manual)
+syn match texinfoComment  "@c .*"
+syn match texinfoComment  "@c$"
+syn match texinfoComment  "@comment .*"
+syn region texinfoMltlnAtCmd matchgroup=texinfoComment start="^@ignore\s*$" end="^@end ignore\s*$" contains=ALL
+
+
+"beginning a Texinfo file (chap. 3 in Texinfo manual)
+syn region texinfoPrmAtCmd     matchgroup=texinfoAtCmd start="@center "		 skip="\\$" end="$"		       contains=texinfoSpecialChar,texinfoBrcPrmAtCmd oneline
+syn region texinfoMltlnDMAtCmd matchgroup=texinfoAtCmd start="^@detailmenu\s*$"		    end="^@end detailmenu\s*$" contains=texinfoSpecialChar,texinfoBrcPrmAtCmd
+syn region texinfoPrmAtCmd     matchgroup=texinfoAtCmd start="^@setfilename "    skip="\\$" end="$" contains=texinfoSpecialChar oneline
+syn region texinfoPrmAtCmd     matchgroup=texinfoAtCmd start="^@settitle "       skip="\\$" end="$" contains=texinfoSpecialChar oneline
+syn region texinfoPrmAtCmd     matchgroup=texinfoAtCmd start="^@shorttitlepage " skip="\\$" end="$" contains=texinfoSpecialChar oneline
+syn region texinfoPrmAtCmd     matchgroup=texinfoAtCmd start="^@title "		 skip="\\$" end="$" contains=texinfoSpecialChar oneline
+syn region texinfoBrcPrmAtCmd  matchgroup=texinfoAtCmd start="@titlefont{"		    end="}" contains=texinfoSpecialChar,texinfoBrcPrmAtCmd
+syn region texinfoMltlnAtCmd   matchgroup=texinfoAtCmd start="^@titlepage\s*$"		    end="^@end titlepage\s*$" contains=texinfoSpecialChar,texinfoBrcPrmAtCmd,texinfoMltlnDMAtCmd,texinfoAtCmd,texinfoPrmAtCmd,texinfoMltlnAtCmd
+syn region texinfoPrmAtCmd     matchgroup=texinfoAtCmd start="^@vskip "		 skip="\\$" end="$" contains=texinfoSpecialChar oneline
+syn match texinfoAtCmd "^@exampleindent"     nextgroup=texinfoSinglePar skipwhite
+syn match texinfoAtCmd "^@headings"	     nextgroup=texinfoSinglePar skipwhite
+syn match texinfoAtCmd "^\\input"	     nextgroup=texinfoSinglePar skipwhite
+syn match texinfoAtCmd "^@paragraphindent"   nextgroup=texinfoSinglePar skipwhite
+syn match texinfoAtCmd "^@setchapternewpage" nextgroup=texinfoSinglePar skipwhite
+
+
+"ending a Texinfo file (chap. 4 in Texinfo manual)
+syn region texinfoPrmAtCmd matchgroup=texinfoAtCmd start="@author " skip="\\$" end="$" contains=texinfoSpecialChar oneline
+"all below @bye should be comment TODO
+syn match texinfoAtCmd "^@bye\s*$"
+syn match texinfoAtCmd "^@contents\s*$"
+syn match texinfoAtCmd "^@printindex" nextgroup=texinfoIndexPar skipwhite
+syn match texinfoAtCmd "^@setcontentsaftertitlepage\s*$"
+syn match texinfoAtCmd "^@setshortcontentsaftertitlepage\s*$"
+syn match texinfoAtCmd "^@shortcontents\s*$"
+syn match texinfoAtCmd "^@summarycontents\s*$"
+
+
+"chapter structuring (chap. 5 in Texinfo manual)
+syn region texinfoPrmAtCmd matchgroup=texinfoAtCmd start="^@appendix"		 skip="\\$" end="$" contains=texinfoSpecialChar oneline
+syn region texinfoPrmAtCmd matchgroup=texinfoAtCmd start="^@appendixsec"	 skip="\\$" end="$" contains=texinfoSpecialChar oneline
+syn region texinfoPrmAtCmd matchgroup=texinfoAtCmd start="^@appendixsection"	 skip="\\$" end="$" contains=texinfoSpecialChar oneline
+syn region texinfoPrmAtCmd matchgroup=texinfoAtCmd start="^@appendixsubsec"	 skip="\\$" end="$" contains=texinfoSpecialChar oneline
+syn region texinfoPrmAtCmd matchgroup=texinfoAtCmd start="^@appendixsubsubsec"	 skip="\\$" end="$" contains=texinfoSpecialChar oneline
+syn region texinfoPrmAtCmd matchgroup=texinfoAtCmd start="^@centerchap"		 skip="\\$" end="$" contains=texinfoSpecialChar oneline
+syn region texinfoPrmAtCmd matchgroup=texinfoAtCmd start="^@chapheading"	 skip="\\$" end="$" contains=texinfoSpecialChar oneline
+syn region texinfoPrmAtCmd matchgroup=texinfoAtCmd start="^@chapter"		 skip="\\$" end="$" contains=texinfoSpecialChar oneline
+syn region texinfoPrmAtCmd matchgroup=texinfoAtCmd start="^@heading"		 skip="\\$" end="$" contains=texinfoSpecialChar oneline
+syn region texinfoPrmAtCmd matchgroup=texinfoAtCmd start="^@majorheading"	 skip="\\$" end="$" contains=texinfoSpecialChar oneline
+syn region texinfoPrmAtCmd matchgroup=texinfoAtCmd start="^@section"		 skip="\\$" end="$" contains=texinfoSpecialChar oneline
+syn region texinfoPrmAtCmd matchgroup=texinfoAtCmd start="^@subheading "	 skip="\\$" end="$" contains=texinfoSpecialChar oneline
+syn region texinfoPrmAtCmd matchgroup=texinfoAtCmd start="^@subsection"		 skip="\\$" end="$" contains=texinfoSpecialChar oneline
+syn region texinfoPrmAtCmd matchgroup=texinfoAtCmd start="^@subsubheading"	 skip="\\$" end="$" contains=texinfoSpecialChar oneline
+syn region texinfoPrmAtCmd matchgroup=texinfoAtCmd start="^@subsubsection"	 skip="\\$" end="$" contains=texinfoSpecialChar oneline
+syn region texinfoPrmAtCmd matchgroup=texinfoAtCmd start="^@subtitle"		 skip="\\$" end="$" contains=texinfoSpecialChar,texinfoBrcPrmAtCmd oneline
+syn region texinfoPrmAtCmd matchgroup=texinfoAtCmd start="^@unnumbered"		 skip="\\$" end="$" contains=texinfoSpecialChar oneline
+syn region texinfoPrmAtCmd matchgroup=texinfoAtCmd start="^@unnumberedsec"	 skip="\\$" end="$" contains=texinfoSpecialChar oneline
+syn region texinfoPrmAtCmd matchgroup=texinfoAtCmd start="^@unnumberedsubsec"	 skip="\\$" end="$" contains=texinfoSpecialChar oneline
+syn region texinfoPrmAtCmd matchgroup=texinfoAtCmd start="^@unnumberedsubsubsec" skip="\\$" end="$" contains=texinfoSpecialChar oneline
+syn match  texinfoAtCmd "^@lowersections\s*$"
+syn match  texinfoAtCmd "^@raisesections\s*$"
+
+
+"nodes (chap. 6 in Texinfo manual)
+syn region texinfoBrcPrmAtCmd matchgroup=texinfoAtCmd start="@anchor{"		  end="}"
+syn region texinfoPrmAtCmd    matchgroup=texinfoAtCmd start="^@top"    skip="\\$" end="$" contains=texinfoSpecialChar oneline
+syn region texinfoPrmAtCmd    matchgroup=texinfoAtCmd start="^@node"   skip="\\$" end="$" contains=texinfoSpecialChar oneline
+
+
+"menus (chap. 7 in Texinfo manual)
+syn region texinfoMltlnAtCmd matchgroup=texinfoAtCmd start="^@menu\s*$" end="^@end menu\s*$" contains=texinfoSpecialChar,texinfoBrcPrmAtCmd,texinfoMltlnDMAtCmd
+
+
+"cross references (chap. 8 in Texinfo manual)
+syn region texinfoBrcPrmAtCmd matchgroup=texinfoAtCmd start="@inforef{" end="}" contains=texinfoSpecialChar,texinfoBrcPrmAtCmd
+syn region texinfoBrcPrmAtCmd matchgroup=texinfoAtCmd start="@pxref{"   end="}" contains=texinfoSpecialChar,texinfoBrcPrmAtCmd
+syn region texinfoBrcPrmAtCmd matchgroup=texinfoAtCmd start="@ref{"     end="}" contains=texinfoSpecialChar,texinfoBrcPrmAtCmd
+syn region texinfoBrcPrmAtCmd matchgroup=texinfoAtCmd start="@uref{"    end="}" contains=texinfoSpecialChar,texinfoBrcPrmAtCmd
+syn region texinfoBrcPrmAtCmd matchgroup=texinfoAtCmd start="@xref{"    end="}" contains=texinfoSpecialChar,texinfoBrcPrmAtCmd
+
+
+"marking words and phrases (chap. 9 in Texinfo manual)
+"(almost) everything appears as 'contained' too; is for tables (@table)
+
+"this chapter is at the beginning of this file to avoid overwritings
+
+
+"quotations and examples (chap. 10 in Texinfo manual)
+syn region texinfoMltlnAtCmd matchgroup=texinfoAtCmd start="^@cartouche\s*$"	    end="^@end cartouche\s*$"	    contains=ALL
+syn region texinfoMltlnAtCmd matchgroup=texinfoAtCmd start="^@display\s*$"	    end="^@end display\s*$"	    contains=ALL
+syn region texinfoMltlnAtCmd matchgroup=texinfoAtCmd start="^@example\s*$"	    end="^@end example\s*$"	    contains=ALL
+syn region texinfoMltlnAtCmd matchgroup=texinfoAtCmd start="^@flushleft\s*$"	    end="^@end flushleft\s*$"	    contains=ALL
+syn region texinfoMltlnAtCmd matchgroup=texinfoAtCmd start="^@flushright\s*$"	    end="^@end flushright\s*$"	    contains=ALL
+syn region texinfoMltlnAtCmd matchgroup=texinfoAtCmd start="^@format\s*$"	    end="^@end format\s*$"	    contains=ALL
+syn region texinfoMltlnAtCmd matchgroup=texinfoAtCmd start="^@lisp\s*$"		    end="^@end lisp\s*$"	    contains=ALL
+syn region texinfoMltlnAtCmd matchgroup=texinfoAtCmd start="^@quotation\s*$"	    end="^@end quotation\s*$"	    contains=ALL
+syn region texinfoMltlnAtCmd matchgroup=texinfoAtCmd start="^@smalldisplay\s*$"     end="^@end smalldisplay\s*$"    contains=ALL
+syn region texinfoMltlnAtCmd matchgroup=texinfoAtCmd start="^@smallexample\s*$"     end="^@end smallexample\s*$"    contains=ALL
+syn region texinfoMltlnAtCmd matchgroup=texinfoAtCmd start="^@smallformat\s*$"	    end="^@end smallformat\s*$"     contains=ALL
+syn region texinfoMltlnAtCmd matchgroup=texinfoAtCmd start="^@smalllisp\s*$"	    end="^@end smalllisp\s*$"	    contains=ALL
+syn region texinfoPrmAtCmd   matchgroup=texinfoAtCmd start="^@exdent"	 skip="\\$" end="$"			    contains=texinfoSpecialChar oneline
+syn match texinfoAtCmd "^@noindent\s*$"
+syn match texinfoAtCmd "^@smallbook\s*$"
+
+
+"lists and tables (chap. 11 in Texinfo manual)
+syn match texinfoAtCmd "@asis"		   contained
+syn match texinfoAtCmd "@columnfractions"  contained
+syn match texinfoAtCmd "@item"		   contained
+syn match texinfoAtCmd "@itemx"		   contained
+syn match texinfoAtCmd "@tab"		   contained
+syn region texinfoMltlnAtCmd  matchgroup=texinfoAtCmd start="^@enumerate"  end="^@end enumerate\s*$"  contains=ALL
+syn region texinfoMltlnAtCmd  matchgroup=texinfoAtCmd start="^@ftable"     end="^@end ftable\s*$"     contains=ALL
+syn region texinfoMltlnNAtCmd matchgroup=texinfoAtCmd start="^@itemize"    end="^@end itemize\s*$"    contains=ALL
+syn region texinfoMltlnNAtCmd matchgroup=texinfoAtCmd start="^@multitable" end="^@end multitable\s*$" contains=ALL
+syn region texinfoMltlnNAtCmd matchgroup=texinfoAtCmd start="^@table"      end="^@end table\s*$"      contains=ALL
+syn region texinfoMltlnAtCmd  matchgroup=texinfoAtCmd start="^@vtable"     end="^@end vtable\s*$"     contains=ALL
+
+
+"indices (chap. 12 in Texinfo manual)
+syn region texinfoPrmAtCmd matchgroup=texinfoAtCmd start="^@\(c\|f\|k\|p\|t\|v\)index"   skip="\\$" end="$" contains=texinfoSpecialChar oneline
+syn region texinfoPrmAtCmd matchgroup=texinfoAtCmd start="^@..index"			 skip="\\$" end="$" contains=texinfoSpecialChar oneline
+"@defcodeindex and @defindex is defined after chap. 15's @def* commands (otherwise those ones will overwrite these ones)
+syn match texinfoSIPar "\k\k\s*\k\k\s*$" contained
+syn match texinfoAtCmd "^@syncodeindex" nextgroup=texinfoSIPar skipwhite
+syn match texinfoAtCmd "^@synindex"     nextgroup=texinfoSIPar skipwhite
+
+"special insertions (chap. 13 in Texinfo manual)
+syn match texinfoSpecialChar "@\(!\|?\|@\|\s\)"
+syn match texinfoSpecialChar "@{"
+syn match texinfoSpecialChar "@}"
+"accents
+syn match texinfoSpecialChar "@=."
+syn match texinfoSpecialChar "@\('\|\"\|\^\|`\)[aeiouyAEIOUY]"
+syn match texinfoSpecialChar "@\~[aeinouyAEINOUY]"
+syn match texinfoSpecialChar "@dotaccent{.}"
+syn match texinfoSpecialChar "@H{.}"
+syn match texinfoSpecialChar "@,{[cC]}"
+syn match texinfoSpecialChar "@AA{}"
+syn match texinfoSpecialChar "@aa{}"
+syn match texinfoSpecialChar "@L{}"
+syn match texinfoSpecialChar "@l{}"
+syn match texinfoSpecialChar "@O{}"
+syn match texinfoSpecialChar "@o{}"
+syn match texinfoSpecialChar "@ringaccent{.}"
+syn match texinfoSpecialChar "@tieaccent{..}"
+syn match texinfoSpecialChar "@u{.}"
+syn match texinfoSpecialChar "@ubaraccent{.}"
+syn match texinfoSpecialChar "@udotaccent{.}"
+syn match texinfoSpecialChar "@v{.}"
+"ligatures
+syn match texinfoSpecialChar "@AE{}"
+syn match texinfoSpecialChar "@ae{}"
+syn match texinfoSpecialChar "@copyright{}"
+syn match texinfoSpecialChar "@bullet" contained "for tables and lists
+syn match texinfoSpecialChar "@bullet{}"
+syn match texinfoSpecialChar "@dotless{i}"
+syn match texinfoSpecialChar "@dotless{j}"
+syn match texinfoSpecialChar "@dots{}"
+syn match texinfoSpecialChar "@enddots{}"
+syn match texinfoSpecialChar "@equiv" contained "for tables and lists
+syn match texinfoSpecialChar "@equiv{}"
+syn match texinfoSpecialChar "@error{}"
+syn match texinfoSpecialChar "@exclamdown{}"
+syn match texinfoSpecialChar "@expansion{}"
+syn match texinfoSpecialChar "@minus" contained "for tables and lists
+syn match texinfoSpecialChar "@minus{}"
+syn match texinfoSpecialChar "@OE{}"
+syn match texinfoSpecialChar "@oe{}"
+syn match texinfoSpecialChar "@point" contained "for tables and lists
+syn match texinfoSpecialChar "@point{}"
+syn match texinfoSpecialChar "@pounds{}"
+syn match texinfoSpecialChar "@print{}"
+syn match texinfoSpecialChar "@questiondown{}"
+syn match texinfoSpecialChar "@result" contained "for tables and lists
+syn match texinfoSpecialChar "@result{}"
+syn match texinfoSpecialChar "@ss{}"
+syn match texinfoSpecialChar "@TeX{}"
+"other
+syn region texinfoBrcPrmAtCmd matchgroup=texinfoAtCmd start="@dmn{"      end="}"
+syn region texinfoBrcPrmAtCmd matchgroup=texinfoAtCmd start="@footnote{" end="}" contains=texinfoSpecialChar,texinfoBrcPrmAtCmd
+syn region texinfoBrcPrmAtCmd matchgroup=texinfoAtCmd start="@image{"    end="}"
+syn region texinfoBrcPrmAtCmd matchgroup=texinfoAtCmd start="@math{"     end="}"
+syn match texinfoAtCmd "@footnotestyle" nextgroup=texinfoSinglePar skipwhite
+
+
+"making and preventing breaks (chap. 14 in Texinfo manual)
+syn match texinfoSpecialChar  "@\(\*\|-\|\.\)"
+syn match texinfoAtCmd	      "^@need"	   nextgroup=texinfoSinglePar skipwhite
+syn match texinfoAtCmd	      "^@page\s*$"
+syn match texinfoAtCmd	      "^@sp"	   nextgroup=texinfoSinglePar skipwhite
+syn region texinfoMltlnAtCmd  matchgroup=texinfoAtCmd start="^@group\s*$"   end="^@end group\s*$" contains=ALL
+syn region texinfoBrcPrmAtCmd matchgroup=texinfoAtCmd start="@hyphenation{" end="}"
+syn region texinfoBrcPrmAtCmd matchgroup=texinfoAtCmd start="@w{"	    end="}"		  contains=texinfoSpecialChar,texinfoBrcPrmAtCmd
+
+
+"definition commands (chap. 15 in Texinfo manual)
+syn match texinfoMltlnAtCmdFLine "^@def\k\+" contained
+syn region texinfoMltlnAtCmd matchgroup=texinfoAtCmd start="^@def\k\+" end="^@end def\k\+$"      contains=ALL
+
+"next 2 commands are from chap. 12; must be defined after @def* commands above to overwrite them
+syn match texinfoAtCmd "@defcodeindex" nextgroup=texinfoIndexPar skipwhite
+syn match texinfoAtCmd "@defindex" nextgroup=texinfoIndexPar skipwhite
+
+
+"conditionally visible text (chap. 16 in Texinfo manual)
+syn match texinfoAtCmd "^@clear" nextgroup=texinfoSinglePar skipwhite
+syn region texinfoMltln2AtCmd matchgroup=texinfoAtCmd start="^@html\s*$"	end="^@end html\s*$"
+syn region texinfoMltlnAtCmd  matchgroup=texinfoAtCmd start="^@ifclear"		end="^@end ifclear\s*$"   contains=ALL
+syn region texinfoMltlnAtCmd  matchgroup=texinfoAtCmd start="^@ifhtml"		end="^@end ifhtml\s*$"	  contains=ALL
+syn region texinfoMltlnAtCmd  matchgroup=texinfoAtCmd start="^@ifinfo"		end="^@end ifinfo\s*$"	  contains=ALL
+syn region texinfoMltlnAtCmd  matchgroup=texinfoAtCmd start="^@ifnothtml"	end="^@end ifnothtml\s*$" contains=ALL
+syn region texinfoMltlnAtCmd  matchgroup=texinfoAtCmd start="^@ifnotinfo"	end="^@end ifnotinfo\s*$" contains=ALL
+syn region texinfoMltlnAtCmd  matchgroup=texinfoAtCmd start="^@ifnottex"	end="^@end ifnottex\s*$"  contains=ALL
+syn region texinfoMltlnAtCmd  matchgroup=texinfoAtCmd start="^@ifset"		end="^@end ifset\s*$"	  contains=ALL
+syn region texinfoMltlnAtCmd  matchgroup=texinfoAtCmd start="^@iftex"		end="^@end iftex\s*$"	  contains=ALL
+syn region texinfoPrmAtCmd    matchgroup=texinfoAtCmd start="^@set " skip="\\$" end="$" contains=texinfoSpecialChar oneline
+syn region texinfoTexCmd			      start="\$\$"		end="\$\$" contained
+syn region texinfoMltlnAtCmd  matchgroup=texinfoAtCmd start="^@tex"		end="^@end tex\s*$"	  contains=texinfoTexCmd
+syn region texinfoBrcPrmAtCmd matchgroup=texinfoAtCmd start="@value{"		end="}" contains=texinfoSpecialChar,texinfoBrcPrmAtCmd
+
+
+"internationalization (chap. 17 in Texinfo manual)
+syn match texinfoAtCmd "@documentencoding" nextgroup=texinfoSinglePar skipwhite
+syn match texinfoAtCmd "@documentlanguage" nextgroup=texinfoIndexPar skipwhite
+
+
+"defining new texinfo commands (chap. 18 in Texinfo manual)
+syn match texinfoAtCmd	"@alias"		      nextgroup=texinfoAssignment skipwhite
+syn match texinfoDIEPar "\S*\s*,\s*\S*\s*,\s*\S*\s*$" contained
+syn match texinfoAtCmd	"@definfoenclose"	      nextgroup=texinfoDIEPar	  skipwhite
+syn region texinfoMltlnAtCmd matchgroup=texinfoAtCmd start="^@macro" end="^@end macro\s*$" contains=ALL
+
+
+"formatting hardcopy (chap. 19 in Texinfo manual)
+syn match texinfoAtCmd "^@afourlatex\s*$"
+syn match texinfoAtCmd "^@afourpaper\s*$"
+syn match texinfoAtCmd "^@afourwide\s*$"
+syn match texinfoAtCmd "^@finalout\s*$"
+syn region texinfoPrmAtCmd matchgroup=texinfoAtCmd start="^@pagesizes" end="$" oneline
+
+
+"creating and installing Info Files (chap. 20 in Texinfo manual)
+syn region texinfoPrmAtCmd   matchgroup=texinfoAtCmd start="^@dircategory"  skip="\\$" end="$" oneline
+syn region texinfoMltlnAtCmd matchgroup=texinfoAtCmd start="^@direntry\s*$"	       end="^@end direntry\s*$" contains=texinfoSpecialChar
+syn match  texinfoAtCmd "^@novalidate\s*$"
+
+
+"include files (appendix E in Texinfo manual)
+syn match texinfoAtCmd "^@include" nextgroup=texinfoSinglePar skipwhite
+
+
+"page headings (appendix F in Texinfo manual)
+syn match texinfoHFSpecialChar "@|"		  contained
+syn match texinfoThisAtCmd     "@thischapter"	  contained
+syn match texinfoThisAtCmd     "@thischaptername" contained
+syn match texinfoThisAtCmd     "@thisfile"	  contained
+syn match texinfoThisAtCmd     "@thispage"	  contained
+syn match texinfoThisAtCmd     "@thistitle"	  contained
+syn match texinfoThisAtCmd     "@today{}"	  contained
+syn region texinfoPrmAtCmd matchgroup=texinfoAtCmd start="^@evenfooting"  skip="\\$" end="$" contains=texinfoSpecialChar,texinfoBrcPrmAtCmd,texinfoThisAtCmd,texinfoHFSpecialChar oneline
+syn region texinfoPrmAtCmd matchgroup=texinfoAtCmd start="^@evenheading"  skip="\\$" end="$" contains=texinfoSpecialChar,texinfoBrcPrmAtCmd,texinfoThisAtCmd,texinfoHFSpecialChar oneline
+syn region texinfoPrmAtCmd matchgroup=texinfoAtCmd start="^@everyfooting" skip="\\$" end="$" contains=texinfoSpecialChar,texinfoBrcPrmAtCmd,texinfoThisAtCmd,texinfoHFSpecialChar oneline
+syn region texinfoPrmAtCmd matchgroup=texinfoAtCmd start="^@everyheading" skip="\\$" end="$" contains=texinfoSpecialChar,texinfoBrcPrmAtCmd,texinfoThisAtCmd,texinfoHFSpecialChar oneline
+syn region texinfoPrmAtCmd matchgroup=texinfoAtCmd start="^@oddfooting"   skip="\\$" end="$" contains=texinfoSpecialChar,texinfoBrcPrmAtCmd,texinfoThisAtCmd,texinfoHFSpecialChar oneline
+syn region texinfoPrmAtCmd matchgroup=texinfoAtCmd start="^@oddheading"   skip="\\$" end="$" contains=texinfoSpecialChar,texinfoBrcPrmAtCmd,texinfoThisAtCmd,texinfoHFSpecialChar oneline
+
+
+"refilling paragraphs (appendix H in Texinfo manual)
+syn match  texinfoAtCmd "@refill"
+
+
+syn cluster texinfoAll contains=ALLBUT,texinfoThisAtCmd,texinfoHFSpecialChar
+syn cluster texinfoReducedAll contains=texinfoSpecialChar,texinfoBrcPrmAtCmd
+"==============================================================================
+" highlighting
+
+" For version 5.7 and earlier: only when not done already
+" For version 5.8 and later: only when an item doesn't have highlighting yet
+if version >= 508 || !exists("did_texinfo_syn_inits")
+
+  if version < 508
+    let did_texinfo_syn_inits = 1
+    command -nargs=+ HiLink hi link <args>
+  else
+    command -nargs=+ HiLink hi def link <args>
+  endif
+
+  HiLink texinfoSpecialChar	Special
+  HiLink texinfoHFSpecialChar	Special
+
+  HiLink texinfoError		Error
+  HiLink texinfoIdent		Identifier
+  HiLink texinfoAssignment	Identifier
+  HiLink texinfoSinglePar	Identifier
+  HiLink texinfoIndexPar	Identifier
+  HiLink texinfoSIPar		Identifier
+  HiLink texinfoDIEPar		Identifier
+  HiLink texinfoTexCmd		PreProc
+
+
+  HiLink texinfoAtCmd		Statement	"@-command
+  HiLink texinfoPrmAtCmd	String		"@-command in one line with unknown nr. of parameters
+						"is String because is found as a region and is 'matchgroup'-ed
+						"to texinfoAtCmd
+  HiLink texinfoBrcPrmAtCmd	String		"@-command with parameter(s) in braces ({})
+						"is String because is found as a region and is 'matchgroup'-ed to texinfoAtCmd
+  HiLink texinfoMltlnAtCmdFLine  texinfoAtCmd	"repeated embedded First lines in @-commands
+  HiLink texinfoMltlnAtCmd	String		"@-command in multiple lines
+						"is String because is found as a region and is 'matchgroup'-ed to texinfoAtCmd
+  HiLink texinfoMltln2AtCmd	PreProc		"@-command in multiple lines (same as texinfoMltlnAtCmd, just with other colors)
+  HiLink texinfoMltlnDMAtCmd	PreProc		"@-command in multiple lines (same as texinfoMltlnAtCmd, just with other colors; used for @detailmenu, which can be included in @menu)
+  HiLink texinfoMltlnNAtCmd	Normal		"@-command in multiple lines (same as texinfoMltlnAtCmd, just with other colors)
+  HiLink texinfoThisAtCmd	Statement	"@-command used in headers and footers (@this... series)
+
+  HiLink texinfoComment	Comment
+
+  delcommand HiLink
+endif
+
+
+let b:current_syntax = "texinfo"
+
+if main_syntax == 'texinfo'
+  unlet main_syntax
+endif
+
+" vim: ts=8
--- /dev/null
+++ b/lib/vimfiles/syntax/texmf.vim
@@ -1,0 +1,86 @@
+" Vim syntax file
+" This is a GENERATED FILE. Please always refer to source file at the URI below.
+" Language: Web2C TeX texmf.cnf configuration file
+" Maintainer: David Ne\v{c}as (Yeti) <yeti@physics.muni.cz>
+" Last Change: 2001-05-13
+" URL: http://physics.muni.cz/~yeti/download/syntax/texmf.vim
+
+" Setup
+if version >= 600
+  if exists("b:current_syntax")
+    finish
+  endif
+else
+  syntax clear
+endif
+
+syn case match
+
+" Comments
+syn match texmfComment "%..\+$" contains=texmfTodo
+syn match texmfComment "%\s*$" contains=texmfTodo
+syn keyword texmfTodo TODO FIXME XXX NOT contained
+
+" Constants and parameters
+syn match texmfPassedParameter "[-+]\=%\w\W"
+syn match texmfPassedParameter "[-+]\=%\w$"
+syn match texmfNumber "\<\d\+\>"
+syn match texmfVariable "\$\(\w\k*\|{\w\k*}\)"
+syn match texmfSpecial +\\"\|\\$+
+syn region texmfString start=+"+ end=+"+ skip=+\\"\\\\+ contains=texmfVariable,texmfSpecial,texmfPassedParameter
+
+" Assignments
+syn match texmfLHSStart "^\s*\w\k*" nextgroup=texmfLHSDot,texmfEquals
+syn match texmfLHSVariable "\w\k*" contained nextgroup=texmfLHSDot,texmfEquals
+syn match texmfLHSDot "\." contained nextgroup=texmfLHSVariable
+syn match texmfEquals "\s*=" contained
+
+" Specialities
+syn match texmfComma "," contained
+syn match texmfColons ":\|;"
+syn match texmfDoubleExclam "!!" contained
+
+" Catch errors caused by wrong parenthesization
+syn region texmfBrace matchgroup=texmfBraceBrace start="{" end="}" contains=ALLBUT,texmfTodo,texmfBraceError,texmfLHSVariable,texmfLHSDot transparent
+syn match texmfBraceError "}"
+
+" Define the default highlighting
+if version >= 508 || !exists("did_texmf_syntax_inits")
+  if version < 508
+    let did_texmf_syntax_inits = 1
+    command -nargs=+ HiLink hi link <args>
+  else
+    command -nargs=+ HiLink hi def link <args>
+  endif
+
+  HiLink texmfComment Comment
+  HiLink texmfTodo Todo
+
+  HiLink texmfPassedParameter texmfVariable
+  HiLink texmfVariable Identifier
+
+  HiLink texmfNumber Number
+  HiLink texmfString String
+
+  HiLink texmfLHSStart texmfLHS
+  HiLink texmfLHSVariable texmfLHS
+  HiLink texmfLHSDot texmfLHS
+  HiLink texmfLHS Type
+
+  HiLink texmfEquals Normal
+
+  HiLink texmfBraceBrace texmfDelimiter
+  HiLink texmfComma texmfDelimiter
+  HiLink texmfColons texmfDelimiter
+  HiLink texmfDelimiter Preproc
+
+  HiLink texmfDoubleExclam Statement
+  HiLink texmfSpecial Special
+
+  HiLink texmfBraceError texmfError
+  HiLink texmfError Error
+
+  delcommand HiLink
+endif
+
+let b:current_syntax = "texmf"
--- /dev/null
+++ b/lib/vimfiles/syntax/tf.vim
@@ -1,0 +1,209 @@
+" Vim syntax file
+" Language:	tf
+" Maintainer:	Lutz Eymers <ixtab@polzin.com>
+" URL:		http://www.isp.de/data/tf.vim
+" Email:	send syntax_vim.tgz
+" Last Change:	2001 May 10
+"
+" Options	lite_minlines = x     to sync at least x lines backwards
+
+" Remove any old syntax stuff hanging around
+
+" For version 5.x: Clear all syntax items
+" For version 6.x: Quit when a syntax file was already loaded
+if version < 600
+  syntax clear
+elseif exists("b:current_syntax")
+  finish
+endif
+
+syn case match
+
+if !exists("main_syntax")
+  let main_syntax = 'tf'
+endif
+
+" Special global variables
+syn keyword tfVar  HOME LANG MAIL SHELL TERM TFHELP TFLIBDIR TFLIBRARY TZ  contained
+syn keyword tfVar  background backslash  contained
+syn keyword tfVar  bamf bg_output borg clearfull cleardone clock connect  contained
+syn keyword tfVar  emulation end_color gag gethostbyname gpri hook hilite  contained
+syn keyword tfVar  hiliteattr histsize hpri insert isize istrip kecho  contained
+syn keyword tfVar  kprefix login lp lpquote maildelay matching max_iter  contained
+syn keyword tfVar  max_recur mecho more mprefix oldslash promt_sec  contained
+syn keyword tfVar  prompt_usec proxy_host proxy_port ptime qecho qprefix  contained
+syn keyword tfVar  quite quitdone redef refreshtime scroll shpause snarf sockmload  contained
+syn keyword tfVar  start_color tabsize telopt sub time_format visual  contained
+syn keyword tfVar  watch_dog watchname wordpunct wrap wraplog wrapsize  contained
+syn keyword tfVar  wrapspace  contained
+
+" Worldvar
+syn keyword tfWorld  world_name world_character world_password world_host contained
+syn keyword tfWorld  world_port world_mfile world_type contained
+
+" Number
+syn match tfNumber  "-\=\<\d\+\>"
+
+" Float
+syn match tfFloat  "\(-\=\<\d+\|-\=\)\.\d\+\>"
+
+" Operator
+syn match tfOperator  "[-+=?:&|!]"
+syn match tfOperator  "/[^*~@]"he=e-1
+syn match tfOperator  ":="
+syn match tfOperator  "[^/%]\*"hs=s+1
+syn match tfOperator  "$\+[([{]"he=e-1,me=e-1
+syn match tfOperator  "\^\[\+"he=s+1 contains=tfSpecialCharEsc
+
+" Relational
+syn match tfRelation  "&&"
+syn match tfRelation  "||"
+syn match tfRelation  "[<>/!=]="
+syn match tfRelation  "[<>]"
+syn match tfRelation  "[!=]\~"
+syn match tfRelation  "[=!]/"
+
+
+" Readonly Var
+syn match tfReadonly  "[#*]" contained
+syn match tfReadonly  "\<-\=L\=\d\{-}\>" contained
+syn match tfReadonly  "\<P\(\d\+\|R\|L\)\>" contained
+syn match tfReadonly  "\<R\>" contained
+
+" Identifier
+syn match tfIdentifier "%\+[a-zA-Z_#*-0-9]\w*" contains=tfVar,tfReadonly
+syn match tfIdentifier "%\+[{]"he=e-1,me=e-1
+syn match tfIdentifier "\$\+{[a-zA-Z_#*-0-9]\w*}" contains=tfWorld
+
+" Function names
+syn keyword tfFunctions  ascii char columns echo filename ftime fwrite getopts
+syn keyword tfFunctions  getpid idle kbdel kbgoto kbhead kblen kbmatch kbpoint
+syn keyword tfFunctions  kbtail kbwordleft kbwordright keycode lines mod
+syn keyword tfFunctions  moresize pad rand read regmatch send strcat strchr
+syn keyword tfFunctions  strcmp strlen strncmp strrchr strrep strstr substr
+syn keyword tfFunctions  systype time tolower toupper
+
+syn keyword tfStatement  addworld bamf beep bind break cat changes connect  contained
+syn keyword tfStatement  dc def dokey echo edit escape eval export expr fg for  contained
+syn keyword tfStatement  gag getfile grab help hilite histsize hook if input  contained
+syn keyword tfStatement  kill lcd let list listsockets listworlds load  contained
+syn keyword tfStatement  localecho log nohilite not partial paste ps purge  contained
+syn keyword tfStatement  purgeworld putfile quit quote recall recordline save  contained
+syn keyword tfStatement  saveworld send sh shift sub substitute  contained
+syn keyword tfStatement  suspend telnet test time toggle trig trigger unbind  contained
+syn keyword tfStatement  undef undefn undeft unhook  untrig unworld  contained
+syn keyword tfStatement  version watchdog watchname while world  contained
+
+" Hooks
+syn keyword tfHook  ACTIVITY BACKGROUND BAMF CONFAIL CONFLICT CONNECT DISCONNECT
+syn keyword tfHook  KILL LOAD LOADFAIL LOG LOGIN MAIL MORE PENDING PENDING
+syn keyword tfHook  PROCESS PROMPT PROXY REDEF RESIZE RESUME SEND SHADOW SHELL
+syn keyword tfHook  SIGHUP SIGTERM SIGUSR1 SIGUSR2 WORLD
+
+" Conditional
+syn keyword tfConditional  if endif then else elseif  contained
+
+" Repeat
+syn keyword tfRepeat  while do done repeat for  contained
+
+" Statement
+syn keyword tfStatement  break quit contained
+
+" Include
+syn keyword  tfInclude require load save loaded contained
+
+" Define
+syn keyword  tfDefine bind unbind def undef undefn undefn purge hook unhook trig untrig  contained
+syn keyword  tfDefine set unset setenv  contained
+
+" Todo
+syn keyword  tfTodo TODO Todo todo  contained
+
+" SpecialChar
+syn match tfSpecialChar "\\[abcfnrtyv\\]" contained
+syn match tfSpecialChar "\\\d\{3}" contained contains=tfOctalError
+syn match tfSpecialChar "\\x[0-9a-fA-F]\{2}" contained
+syn match tfSpecialCharEsc "\[\+" contained
+
+syn match tfOctalError "[89]" contained
+
+" Comment
+syn region tfComment		start="^;" end="$"  contains=tfTodo
+
+" String
+syn region tfString   oneline matchgroup=None start=+'+  skip=+\\\\\|\\'+  end=+'+ contains=tfIdentifier,tfSpecialChar,tfEscape
+syn region tfString   matchgroup=None start=+"+  skip=+\\\\\|\\"+  end=+"+ contains=tfIdentifier,tfSpecialChar,tfEscape
+
+syn match tfParentError "[)}\]]"
+
+" Parents
+syn region tfParent matchgroup=Delimiter start="(" end=")" contains=ALLBUT,tfReadonly
+syn region tfParent matchgroup=Delimiter start="\[" end="\]" contains=ALL
+syn region tfParent matchgroup=Delimiter start="{" end="}" contains=ALL
+
+syn match tfEndCommand "%%\{-};"
+syn match tfJoinLines "\\$"
+
+" Types
+
+syn match tfType "/[a-zA-Z_~@][a-zA-Z0-9_]*" contains=tfConditional,tfRepeat,tfStatement,tfInclude,tfDefine,tfStatement
+
+" Catch /quote .. '
+syn match tfQuotes "/quote .\{-}'" contains=ALLBUT,tfString
+" Catch $(/escape   )
+syn match tfEscape "(/escape .*)"
+
+" sync
+if exists("tf_minlines")
+  exec "syn sync minlines=" . tf_minlines
+else
+  syn sync minlines=100
+endif
+
+" Define the default highlighting.
+" For version 5.7 and earlier: only when not done already
+" For version 5.8 and later: only when an item doesn't have highlighting yet
+if version >= 508 || !exists("did_tf_syn_inits")
+  if version < 508
+    let did_tf_syn_inits = 1
+    command -nargs=+ HiLink hi link <args>
+  else
+    command -nargs=+ HiLink hi def link <args>
+  endif
+
+  HiLink tfComment		Comment
+  HiLink tfString		String
+  HiLink tfNumber		Number
+  HiLink tfFloat		Float
+  HiLink tfIdentifier		Identifier
+  HiLink tfVar			Identifier
+  HiLink tfWorld		Identifier
+  HiLink tfReadonly		Identifier
+  HiLink tfHook		Identifier
+  HiLink tfFunctions		Function
+  HiLink tfRepeat		Repeat
+  HiLink tfConditional		Conditional
+  HiLink tfLabel		Label
+  HiLink tfStatement		Statement
+  HiLink tfType		Type
+  HiLink tfInclude		Include
+  HiLink tfDefine		Define
+  HiLink tfSpecialChar		SpecialChar
+  HiLink tfSpecialCharEsc	SpecialChar
+  HiLink tfParentError		Error
+  HiLink tfTodo		Todo
+  HiLink tfEndCommand		Delimiter
+  HiLink tfJoinLines		Delimiter
+  HiLink tfOperator		Operator
+  HiLink tfRelation		Operator
+
+  delcommand HiLink
+endif
+
+let b:current_syntax = "tf"
+
+if main_syntax == 'tf'
+  unlet main_syntax
+endif
+
+" vim: ts=8
--- /dev/null
+++ b/lib/vimfiles/syntax/tidy.vim
@@ -1,0 +1,162 @@
+" Vim syntax file
+" Language:	HMTL Tidy configuration file ( /etc/tidyrc ~/.tidyrc )
+" Maintainer:	Doug Kearns <djkea2@gus.gscit.monash.edu.au>
+" URL:		http://gus.gscit.monash.edu.au/~djkea2/vim/syntax/tidy.vim
+" Last Change:	2005 Oct 06
+
+" For version 5.x: Clear all syntax items
+" For version 6.x: Quit when a syntax file was already loaded
+if version < 600
+  syntax clear
+elseif exists("b:current_syntax")
+  finish
+endif
+
+if version < 600
+  set iskeyword=@,48-57,-
+else
+  setlocal iskeyword=@,48-57,-
+endif
+
+syn match	tidyComment		"^\s*//.*$" contains=tidyTodo
+syn match	tidyComment		"^\s*#.*$"  contains=tidyTodo
+syn keyword	tidyTodo		TODO NOTE FIXME XXX contained
+
+syn match	tidyAssignment		"^[a-z0-9-]\+:\s*.*$" contains=tidyOption,@tidyValue,tidyDelimiter
+syn match	tidyDelimiter		":" contained
+
+syn match	tidyNewTagAssignment	"^new-\l\+-tags:\s*.*$" contains=tidyNewTagOption,tidyNewTagDelimiter,tidyNewTagValue,tidyDelimiter
+syn match	tidyNewTagDelimiter	"," contained
+syn match	tidyNewTagValue		"\<\w\+\>" contained
+
+syn case ignore
+syn keyword	tidyBoolean		t[rue] f[alse] y[es] n[o] contained
+syn case match
+syn match	tidyDoctype		"\<omit\|auto\|strict\|loose\|transitional\|user\>" contained
+" NOTE: use match rather than keyword here so that tidyEncoding 'raw' does not
+"       always have precedence over tidyOption 'raw'
+syn match	tidyEncoding		"\<\(ascii\|latin0\|latin1\|raw\|utf8\|iso2022\|mac\|utf16le\|utf16be\|utf16\|win1252\|ibm858\|big5\|shiftjis\)\>" contained
+syn match	tidyNewline		"\<\(LF\|CRLF\|CR\)\>"
+syn match	tidyNumber		"\<\d\+\>" contained
+syn match	tidyRepeat		"\<keep-first\|keep-last\>" contained
+syn region	tidyString		start=+"+ skip=+\\\\\|\\"+ end=+"+ contained oneline
+syn region	tidyString		start=+'+ skip=+\\\\\|\\'+ end=+'+ contained oneline
+syn cluster	tidyValue		contains=tidyBoolean,tidyDoctype,tidyEncoding,tidyNewline,tidyNumber,tidyRepeat,tidyString
+
+syn match	tidyOption		"^accessibility-check"		contained
+syn match	tidyOption		"^add-xml-decl"			contained
+syn match	tidyOption		"^add-xml-pi"			contained
+syn match	tidyOption		"^add-xml-space"		contained
+syn match	tidyOption		"^alt-text"			contained
+syn match	tidyOption		"^ascii-chars"			contained
+syn match	tidyOption		"^assume-xml-procins"		contained
+syn match	tidyOption		"^bare"				contained
+syn match	tidyOption		"^break-before-br"		contained
+syn match	tidyOption		"^char-encoding"		contained
+syn match	tidyOption		"^clean"			contained
+syn match	tidyOption		"^css-prefix"			contained
+syn match	tidyOption		"^doctype"			contained
+syn match	tidyOption		"^doctype-mode"			contained
+syn match	tidyOption		"^drop-empty-paras"		contained
+syn match	tidyOption		"^drop-font-tags"		contained
+syn match	tidyOption		"^drop-proprietary-attributes"	contained
+syn match	tidyOption		"^enclose-block-text"		contained
+syn match	tidyOption		"^enclose-text"			contained
+syn match	tidyOption		"^error-file"			contained
+syn match	tidyOption		"^escape-cdata"			contained
+syn match	tidyOption		"^fix-backslash"		contained
+syn match	tidyOption		"^fix-bad-comments"		contained
+syn match	tidyOption		"^fix-uri"			contained
+syn match	tidyOption		"^force-output"			contained
+syn match	tidyOption		"^gnu-emacs"			contained
+syn match	tidyOption		"^gnu-emacs-file"		contained
+syn match	tidyOption		"^hide-comments"		contained
+syn match	tidyOption		"^hide-endtags"			contained
+syn match	tidyOption		"^indent"			contained
+syn match	tidyOption		"^indent-attributes"		contained
+syn match	tidyOption		"^indent-cdata"			contained
+syn match	tidyOption		"^indent-spaces"		contained
+syn match	tidyOption		"^input-encoding"		contained
+syn match	tidyOption		"^input-xml"			contained
+syn match	tidyOption		"^join-classes"			contained
+syn match	tidyOption		"^join-styles"			contained
+syn match	tidyOption		"^keep-time"			contained
+syn match	tidyOption		"^language"			contained
+syn match	tidyOption		"^literal-attributes"		contained
+syn match	tidyOption		"^logical-emphasis"		contained
+syn match	tidyOption		"^lower-literals"		contained
+syn match	tidyOption		"^markup"			contained
+syn match	tidyOption		"^merge-divs"			contained
+syn match	tidyOption		"^ncr"				contained
+syn match	tidyOption		"^newline"			contained
+syn match	tidyOption		"^numeric-entities"		contained
+syn match	tidyOption		"^output-bom"			contained
+syn match	tidyOption		"^output-encoding"		contained
+syn match	tidyOption		"^output-file"			contained
+syn match	tidyOption		"^output-html"			contained
+syn match	tidyOption		"^output-xhtml"			contained
+syn match	tidyOption		"^output-xml"			contained
+syn match	tidyOption		"^punctuation-wrap"		contained
+syn match	tidyOption		"^quiet"			contained
+syn match	tidyOption		"^quote-ampersand"		contained
+syn match	tidyOption		"^quote-marks"			contained
+syn match	tidyOption		"^quote-nbsp"			contained
+syn match	tidyOption		"^raw"				contained
+syn match	tidyOption		"^repeated-attributes"		contained
+syn match	tidyOption		"^replace-color"		contained
+syn match	tidyOption		"^show-body-only"		contained
+syn match	tidyOption		"^show-errors"			contained
+syn match	tidyOption		"^show-warnings"		contained
+syn match	tidyOption		"^slide-style"			contained
+syn match	tidyOption		"^split"			contained
+syn match	tidyOption		"^tab-size"			contained
+syn match	tidyOption		"^tidy-mark"			contained
+syn match	tidyOption		"^uppercase-attributes"		contained
+syn match	tidyOption		"^uppercase-tags"		contained
+syn match	tidyOption		"^word-2000"			contained
+syn match	tidyOption		"^wrap"				contained
+syn match	tidyOption		"^wrap-asp"			contained
+syn match	tidyOption		"^wrap-attributes"		contained
+syn match	tidyOption		"^wrap-jste"			contained
+syn match	tidyOption		"^wrap-php"			contained
+syn match	tidyOption		"^wrap-script-literals"		contained
+syn match	tidyOption		"^wrap-sections"		contained
+syn match	tidyOption		"^write-back"			contained
+syn match	tidyOption		"^vertical-space"		contained
+syn match	tidyNewTagOption	"^new-blocklevel-tags"		contained
+syn match	tidyNewTagOption	"^new-empty-tags"		contained
+syn match	tidyNewTagOption	"^new-inline-tags"		contained
+syn match	tidyNewTagOption	"^new-pre-tags"			contained
+
+" Define the default highlighting.
+" For version 5.7 and earlier: only when not done already
+" For version 5.8 and later: only when an item doesn't have highlighting yet
+if version >= 508 || !exists("did_tidy_syn_inits")
+  if version < 508
+    let did_tidy_syn_inits = 1
+    command -nargs=+ HiLink hi link <args>
+  else
+    command -nargs=+ HiLink hi def link <args>
+  endif
+
+  HiLink tidyBoolean		Boolean
+  HiLink tidyComment		Comment
+  HiLink tidyDelimiter		Special
+  HiLink tidyDoctype		Constant
+  HiLink tidyEncoding		Constant
+  HiLink tidyNewline		Constant
+  HiLink tidyNewTagDelimiter	Special
+  HiLink tidyNewTagOption	Identifier
+  HiLink tidyNewTagValue	Constant
+  HiLink tidyNumber		Number
+  HiLink tidyOption		Identifier
+  HiLink tidyRepeat		Constant
+  HiLink tidyString		String
+  HiLink tidyTodo		Todo
+
+  delcommand HiLink
+endif
+
+let b:current_syntax = "tidy"
+
+" vim: ts=8
--- /dev/null
+++ b/lib/vimfiles/syntax/tilde.vim
@@ -1,0 +1,41 @@
+" Vim syntax file
+" This file works only for Vim6.x
+" Language:	Tilde
+" Maintainer:	Tobias Rundstr�m <tobi@tildesoftware.net>
+" URL:		http://www.tildesoftware.net
+" CVS:		$Id: tilde.vim,v 1.1 2004/06/13 19:31:51 vimboss Exp $
+
+if exists("b:current_syntax")
+  finish
+endif
+
+"tilde dosent care ...
+syn case ignore
+
+syn match	tildeFunction	"\~[a-z_0-9]\+"ms=s+1
+syn region	tildeParen	start="(" end=")" contains=tildeString,tildeNumber,tildeVariable,tildeField,tildeSymtab,tildeFunction,tildeParen,tildeHexNumber,tildeOperator
+syn region	tildeString	contained start=+"+ skip=+\\\\\|\\"+ end=+"+ keepend
+syn region	tildeString	contained start=+'+ skip=+\\\\\|\\"+ end=+'+ keepend
+syn match	tildeNumber	"\d" contained
+syn match	tildeOperator	"or\|and" contained
+syn match	tildeHexNumber  "0x[a-z0-9]\+" contained
+syn match	tildeVariable	"$[a-z_0-9]\+" contained
+syn match	tildeField	"%[a-z_0-9]\+" contained
+syn match	tildeSymtab	"@[a-z_0-9]\+" contained
+syn match	tildeComment	"^#.*"
+syn region	tildeCurly	start=+{+ end=+}+ contained contains=tildeLG,tildeString,tildeNumber,tildeVariable,tildeField,tildeFunction,tildeSymtab,tildeHexNumber
+syn match	tildeLG		"=>" contained
+
+
+hi def link	tildeComment	Comment
+hi def link	tildeFunction	Operator
+hi def link	tildeOperator	Operator
+hi def link	tildeString	String
+hi def link	tildeNumber	Number
+hi def link	tildeHexNumber	Number
+hi def link	tildeVariable	Identifier
+hi def link	tildeField	Identifier
+hi def link	tildeSymtab	Identifier
+hi def link	tildeError	Error
+
+let b:current_syntax = "tilde"
--- /dev/null
+++ b/lib/vimfiles/syntax/tli.vim
@@ -1,0 +1,71 @@
+" Vim syntax file
+" Language:	TealInfo source files (*.tli)
+" Maintainer:	Kurt W. Andrews <kandrews@fastrans.net>
+" Last Change:	2001 May 10
+" Version:      1.0
+
+" For version 5.x: Clear all syntax items
+" For version 6.x: Quit when a syntax file was already loaded
+if version < 600
+  syntax clear
+elseif exists("b:current_syntax")
+  finish
+endif
+
+" TealInfo Objects
+
+syn keyword tliObject LIST POPLIST WINDOW POPWINDOW OUTLINE CHECKMARK GOTO
+syn keyword tliObject LABEL IMAGE RECT TRES PASSWORD POPEDIT POPIMAGE CHECKLIST
+
+" TealInfo Fields
+
+syn keyword tliField X Y W H BX BY BW BH SX SY FONT BFONT CYCLE DELAY TABS
+syn keyword tliField STYLE BTEXT RECORD DATABASE KEY TARGET DEFAULT TEXT
+syn keyword tliField LINKS MAXVAL
+
+" TealInfo Styles
+
+syn keyword tliStyle INVERTED HORIZ_RULE VERT_RULE NO_SCROLL NO_BORDER BOLD_BORDER
+syn keyword tliStyle ROUND_BORDER ALIGN_RIGHT ALIGN_CENTER ALIGN_LEFT_START ALIGN_RIGHT_START
+syn keyword tliStyle ALIGN_CENTER_START ALIGN_LEFT_END ALIGN_RIGHT_END ALIGN_CENTER_END
+syn keyword tliStyle LOCKOUT BUTTON_SCROLL BUTTON_SELECT STROKE_FIND FILLED REGISTER
+
+" String and Character constants
+
+syn match tliSpecial	"@"
+syn region tliString	start=+"+ end=+"+
+
+"TealInfo Numbers, identifiers and comments
+
+syn case ignore
+syn match tliNumber	"\d*"
+syn match tliIdentifier	"\<\h\w*\>"
+syn match tliComment	"#.*"
+syn case match
+
+" Define the default highlighting.
+" For version 5.7 and earlier: only when not done already
+" For version 5.8 and later: only when an item doesn't have highlighting yet
+if version >= 508 || !exists("did_tli_syntax_inits")
+  if version < 508
+    let did_tli_syntax_inits = 1
+    command -nargs=+ HiLink hi link <args>
+  else
+    command -nargs=+ HiLink hi def link <args>
+  endif
+
+  HiLink tliNumber	Number
+  HiLink tliString	String
+  HiLink tliComment	Comment
+  HiLink tliSpecial	SpecialChar
+  HiLink tliIdentifier Identifier
+  HiLink tliObject     Statement
+  HiLink tliField      Type
+  HiLink tliStyle      PreProc
+
+  delcommand HiLink
+endif
+
+let b:current_syntax = "tli"
+
+" vim: ts=8
--- /dev/null
+++ b/lib/vimfiles/syntax/tpp.vim
@@ -1,0 +1,100 @@
+" Vim syntax file
+" Language:	tpp - Text Presentation Program
+" Maintainer:   Debian VIM Maintainers <pkg-vim-maintainers@lists.alioth.debian.org>
+" Former Maintainer:	Gerfried Fuchs <alfie@ist.org>
+" Last Change:	$LastChangedDate: 2006-04-16 22:06:40 -0400 (dom, 16 apr 2006) $
+" URL: http://svn.debian.org/wsvn/pkg-vim/trunk/runtime/syntax/tpp.vim?op=file&rev=0&sc=0
+" Filenames:	*.tpp
+" License:	BSD
+"
+" XXX This file is in need of a new maintainer, Debian VIM Maintainers maintain
+"     it only because patches have been submitted for it by Debian users and the
+"     former maintainer was MIA (Missing In Action), taking over its
+"     maintenance was thus the only way to include those patches.
+"     If you care about this file, and have time to maintain it please do so!
+"
+" Comments are very welcome - but please make sure that you are commenting on
+" the latest version of this file.
+" SPAM is _NOT_ welcome - be ready to be reported!
+
+" For version 5.x: Clear all syntax items
+" For version 6.x: Quit when a syntax file was already loaded
+if version < 600
+  syntax clear
+elseif exists("b:current_syntax")
+  finish
+endif
+
+if !exists("main_syntax")
+  let main_syntax = 'tpp'
+endif
+
+
+"" list of the legal switches/options
+syn match tppAbstractOptionKey contained "^--\%(author\|title\|date\|footer\) *" nextgroup=tppString
+syn match tppPageLocalOptionKey contained "^--\%(heading\|center\|right\|huge\|sethugefont\|exec\) *" nextgroup=tppString
+syn match tppPageLocalSwitchKey contained "^--\%(horline\|-\|\%(begin\|end\)\%(\%(shell\)\?output\|slide\%(left\|right\|top\|bottom\)\)\|\%(bold\|rev\|ul\)\%(on\|off\)\|withborder\)"
+syn match tppNewPageOptionKey contained "^--newpage *" nextgroup=tppString
+syn match tppColorOptionKey contained "^--\%(\%(bg\|fg\)\?color\) *"
+syn match tppTimeOptionKey contained "^--sleep *"
+
+syn match tppString contained ".*"
+syn match tppColor contained "\%(white\|yellow\|red\|green\|blue\|cyan\|magenta\|black\|default\)"
+syn match tppTime contained "\d\+"
+
+syn region tppPageLocalSwitch start="^--" end="$" contains=tppPageLocalSwitchKey oneline
+syn region tppColorOption start="^--\%(\%(bg\|fg\)\?color\)" end="$" contains=tppColorOptionKey,tppColor oneline
+syn region tppTimeOption start="^--sleep" end="$" contains=tppTimeOptionKey,tppTime oneline
+syn region tppNewPageOption start="^--newpage" end="$" contains=tppNewPageOptionKey oneline
+syn region tppPageLocalOption start="^--\%(heading\|center\|right\|huge\|sethugefont\|exec\)" end="$" contains=tppPageLocalOptionKey oneline
+syn region tppAbstractOption start="^--\%(author\|title\|date\|footer\)" end="$" contains=tppAbstractOptionKey oneline
+
+if main_syntax != 'sh'
+  " shell command
+  if version < 600
+    syn include @tppShExec <sfile>:p:h/sh.vim
+  else
+    syn include @tppShExec syntax/sh.vim
+  endif
+  unlet b:current_syntax
+
+  syn region shExec matchgroup=tppPageLocalOptionKey start='^--exec *' keepend end='$' contains=@tppShExec
+
+endif
+
+syn match tppComment "^--##.*$"
+
+" Define the default highlighting.
+" For version 5.7 and earlier: only when not done already
+" For version 5.8 and later: only when an item doesn't have highlighting yet
+if version >= 508 || !exists("did_tpp_syn_inits")
+  if version < 508
+    let did_tpp_syn_inits = 1
+    command -nargs=+ HiLink hi link <args>
+  else
+    command -nargs=+ HiLink hi def link <args>
+  endif
+
+  HiLink tppAbstractOptionKey		Special
+  HiLink tppPageLocalOptionKey		Keyword
+  HiLink tppPageLocalSwitchKey		Keyword
+  HiLink tppColorOptionKey		Keyword
+  HiLink tppTimeOptionKey		Comment
+  HiLink tppNewPageOptionKey		PreProc
+  HiLink tppString			String
+  HiLink tppColor			String
+  HiLink tppTime			Number
+  HiLink tppComment			Comment
+  HiLink tppAbstractOption		Error
+  HiLink tppPageLocalOption		Error
+  HiLink tppPageLocalSwitch		Error
+  HiLink tppColorOption			Error
+  HiLink tppNewPageOption		Error
+  HiLink tppTimeOption			Error
+
+  delcommand HiLink
+endif
+
+let b:current_syntax = "tpp"
+
+" vim: ts=8 sw=2
--- /dev/null
+++ b/lib/vimfiles/syntax/trasys.vim
@@ -1,0 +1,177 @@
+" Vim syntax file
+" Language:     TRASYS input file
+" Maintainer:   Adrian Nagle, anagle@ball.com
+" Last Change:  2003 May 11
+" Filenames:    *.inp
+" URL:		http://www.naglenet.org/vim/syntax/trasys.vim
+" MAIN URL:     http://www.naglenet.org/vim/
+
+
+
+" For version 5.x: Clear all syntax items
+" For version 6.x: Quit when a syntax file was already loaded
+if version < 600
+  syntax clear
+elseif exists("b:current_syntax")
+  finish
+endif
+
+
+" Force free-form fortran format
+let fortran_free_source=1
+
+" Load FORTRAN syntax file
+if version < 600
+  source <sfile>:p:h/fortran.vim
+else
+  runtime! syntax/fortran.vim
+endif
+unlet b:current_syntax
+
+
+" Ignore case
+syn case ignore
+
+
+
+" Define keywords for TRASYS
+syn keyword trasysOptions    model rsrec info maxfl nogo dmpdoc
+syn keyword trasysOptions    rsi rti rso rto bcdou cmerg emerg
+syn keyword trasysOptions    user1 nnmin erplot
+
+syn keyword trasysSurface    icsn tx ty tz rotx roty rotz inc bcsn
+syn keyword trasysSurface    nnx nny nnz nnax nnr nnth unnx
+syn keyword trasysSurface    unny unnz unnax unnr unnth type idupsf
+syn keyword trasysSurface    imagsf act active com shade bshade axmin
+syn keyword trasysSurface    axmax zmin zmax rmin rmax thmin thmin
+syn keyword trasysSurface    thmax alpha emiss trani trans spri sprs
+syn keyword trasysSurface    refno posit com dupbcs dimensions
+syn keyword trasysSurface    dimension position prop surfn
+
+syn keyword trasysSurfaceType rect trap disk cyl cone sphere parab
+syn keyword trasysSurfaceType box5 box6 shpero tor ogiv elem tape poly
+
+syn keyword trasysSurfaceArgs ff di top bottom in out both no only
+
+syn keyword trasysArgs       fig smn nodea zero only ir sol
+syn keyword trasysArgs       both wband stepn initl
+
+syn keyword trasysOperations orbgen build
+
+"syn keyword trasysSubRoutine call
+syn keyword trasysSubRoutine chgblk ndata ndatas odata odatas
+syn keyword trasysSubRoutine pldta ffdata cmdata adsurf rbdata
+syn keyword trasysSubRoutine rtdata pffshd orbit1 orbit2 orient
+syn keyword trasysSubRoutine didt1 didt1s didt2 didt2s spin
+syn keyword trasysSubRoutine spinav dicomp distab drdata gbdata
+syn keyword trasysSubRoutine gbaprx rkdata rcdata aqdata stfaq
+syn keyword trasysSubRoutine qodata qoinit modar modpr modtr
+syn keyword trasysSubRoutine modprs modshd moddat rstoff rston
+syn keyword trasysSubRoutine rsmerg ffread diread ffusr1 diusr1
+syn keyword trasysSubRoutine surfp didt3 didt3s romain stfrc
+syn keyword trasysSubRoutine rornt rocstr romove flxdata title
+
+syn keyword trassyPrcsrSegm  nplot oplot plot cmcal ffcal rbcal
+syn keyword trassyPrcsrSegm  rtcal dical drcal sfcal gbcal rccal
+syn keyword trassyPrcsrSegm  rkcal aqcal qocal
+
+
+
+" Define matches for TRASYS
+syn match  trasysOptions     "list source"
+syn match  trasysOptions     "save source"
+syn match  trasysOptions     "no print"
+
+"syn match  trasysSurface     "^K *.* [^$]"
+"syn match  trasysSurface     "^D *[0-9]*\.[0-9]\+"
+"syn match  trasysSurface     "^I *.*[0-9]\+\.\="
+"syn match  trasysSurface     "^N *[0-9]\+"
+"syn match  trasysSurface     "^M *[a-z[A-Z0-9]\+"
+"syn match  trasysSurface     "^B[C][S] *[a-zA-Z0-9]*"
+"syn match  trasysSurface     "^S *SURFN.*[0-9]"
+syn match  trasysSurface     "P[0-9]* *="he=e-1
+
+syn match  trasysIdentifier  "^L "he=e-1
+syn match  trasysIdentifier  "^K "he=e-1
+syn match  trasysIdentifier  "^D "he=e-1
+syn match  trasysIdentifier  "^I "he=e-1
+syn match  trasysIdentifier  "^N "he=e-1
+syn match  trasysIdentifier  "^M "he=e-1
+syn match  trasysIdentifier  "^B[C][S]"
+syn match  trasysIdentifier  "^S "he=e-1
+
+syn match  trasysComment     "^C.*$"
+syn match  trasysComment     "^R.*$"
+syn match  trasysComment     "\$.*$"
+
+syn match  trasysHeader      "^header[^,]*"
+
+syn match  trasysMacro       "^FAC"
+
+syn match  trasysInteger     "-\=\<[0-9]*\>"
+syn match  trasysFloat       "-\=\<[0-9]*\.[0-9]*"
+syn match  trasysScientific  "-\=\<[0-9]*\.[0-9]*E[-+]\=[0-9]\+\>"
+
+syn match  trasysBlank       "' \+'"hs=s+1,he=e-1
+
+syn match  trasysEndData     "^END OF DATA"
+
+if exists("thermal_todo")
+  execute 'syn match  trasysTodo ' . '"^'.thermal_todo.'.*$"'
+else
+  syn match  trasysTodo  "^?.*$"
+endif
+
+
+
+" Define regions for TRASYS
+syn region trasysComment  matchgroup=trasysHeader start="^HEADER DOCUMENTATION DATA" end="^HEADER[^,]*"
+
+
+
+" Define synchronizing patterns for TRASYS
+syn sync maxlines=500
+syn sync match trasysSync grouphere trasysComment "^HEADER DOCUMENTATION DATA"
+
+
+
+" Define the default highlighting
+" For version 5.7 and earlier: only when not done already
+" For version 5.8 and later: only when an item doesn't have highlighting yet
+if version >= 508 || !exists("did_trasys_syntax_inits")
+  if version < 508
+    let did_trasys_syntax_inits = 1
+    command -nargs=+ HiLink hi link <args>
+  else
+    command -nargs=+ HiLink hi def link <args>
+  endif
+
+  HiLink trasysOptions		Special
+  HiLink trasysSurface		Special
+  HiLink trasysSurfaceType	Constant
+  HiLink trasysSurfaceArgs	Constant
+  HiLink trasysArgs		Constant
+  HiLink trasysOperations	Statement
+  HiLink trasysSubRoutine	Statement
+  HiLink trassyPrcsrSegm	PreProc
+  HiLink trasysIdentifier	Identifier
+  HiLink trasysComment		Comment
+  HiLink trasysHeader		Typedef
+  HiLink trasysMacro		Macro
+  HiLink trasysInteger		Number
+  HiLink trasysFloat		Float
+  HiLink trasysScientific	Float
+
+  HiLink trasysBlank		SpecialChar
+
+  HiLink trasysEndData		Macro
+
+  HiLink trasysTodo		Todo
+
+  delcommand HiLink
+endif
+
+
+let b:current_syntax = "trasys"
+
+" vim: ts=8 sw=2
--- /dev/null
+++ b/lib/vimfiles/syntax/trustees.vim
@@ -1,0 +1,43 @@
+" Vim syntax file
+" Language:     trustees
+" Maintainer:   Nima Talebi <nima@it.net.au>
+" Last Change:  2005-10-12
+
+if version < 600
+  syntax clear
+elseif exists("b:current_syntax")
+  finish
+endif
+
+syntax case match
+syntax sync minlines=0 maxlines=0
+
+" Errors & Comments
+syntax match tfsError /.*/
+highlight link tfsError Error
+syntax keyword tfsSpecialComment TODO XXX FIXME contained
+highlight link tfsSpecialComment Todo
+syntax match tfsComment ~\s*#.*~ contains=tfsSpecialComment
+highlight link tfsComment Comment 
+
+" Operators & Delimiters
+highlight link tfsSpecialChar Operator
+syntax match tfsSpecialChar ~[*!+]~ contained
+highlight link tfsDelimiter Delimiter
+syntax match tfsDelimiter ~:~ contained
+
+" Trustees Rules - Part 1 of 3 - The Device
+syntax region tfsRuleDevice matchgroup=tfsDeviceContainer start=~\[/~ end=~\]~ nextgroup=tfsRulePath oneline
+highlight link tfsRuleDevice Label
+highlight link tfsDeviceContainer PreProc
+
+" Trustees Rules - Part 2 of 3 - The Path
+syntax match tfsRulePath ~/[-_a-zA-Z0-9/]*~ nextgroup=tfsRuleACL contained contains=tfsDelimiter 
+highlight link tfsRulePath String
+
+" Trustees Rules - Part 3 of 3 - The ACLs
+syntax match tfsRuleACL ~\(:\(\*\|[+]\{0,1\}[a-zA-Z0-9/]\+\):[RWEBXODCU!]\+\)\+$~ contained contains=tfsDelimiter,tfsRuleWho,tfsRuleWhat
+syntax match tfsRuleWho ~\(\*\|[+]\{0,1\}[a-zA-Z0-9/]\+\)~ contained contains=tfsSpecialChar
+highlight link tfsRuleWho Identifier
+syntax match tfsRuleWhat ~[RWEBXODCU!]\+~ contained contains=tfsSpecialChar
+highlight link tfsRuleWhat Structure
--- /dev/null
+++ b/lib/vimfiles/syntax/tsalt.vim
@@ -1,0 +1,214 @@
+" Vim syntax file
+" Language:	Telix (Modem Comm Program) SALT Script
+" Maintainer:	Sean M. McKee <mckee@misslink.net>
+" Last Change:	2001 May 09
+" Version Info: @(#)tsalt.vim	1.5	97/12/16 08:11:15
+
+" For version 5.x: Clear all syntax items
+" For version 6.x: Quit when a syntax file was already loaded
+if version < 600
+  syntax clear
+elseif exists("b:current_syntax")
+  finish
+endif
+
+" turn case matching off
+syn case ignore
+
+"FUNCTIONS
+" Character Handling Functions
+syn keyword tsaltFunction	IsAscii IsAlNum IsAlpha IsCntrl IsDigit
+syn keyword tsaltFunction	IsLower IsUpper ToLower ToUpper
+
+" Connect Device Operations
+syn keyword tsaltFunction	Carrier cInp_Cnt cGetC cGetCT cPutC cPutN
+syn keyword tsaltFunction	cPutS cPutS_TR FlushBuf Get_Baud
+syn keyword tsaltFunction	Get_DataB Get_Port Get_StopB Hangup
+syn keyword tsaltFunction	KillConnectDevice MakeConnectDevice
+syn keyword tsaltFunction	Send_Brk Set_ConnectDevice Set_Port
+
+" File Input/Output Operations
+syn keyword tsaltFunction	fClearErr fClose fDelete fError fEOF fFlush
+syn keyword tsaltFunction	fGetC fGetS FileAttr FileFind FileSize
+syn keyword tsaltFunction	FileTime fnStrip fOpen fPutC fPutS fRead
+syn keyword tsaltFunction	fRename fSeek fTell fWrite
+
+" File Transfers and Logs
+syn keyword tsaltFunction	Capture Capture_Stat Printer Receive Send
+syn keyword tsaltFunction	Set_DefProt UsageLog Usage_Stat UStamp
+
+" Input String Matching
+syn keyword tsaltFunction	Track Track_AddChr Track_Free Track_Hit
+syn keyword tsaltFunction	WaitFor
+
+" Keyboard Operations
+syn keyword tsaltFunction	InKey InKeyW KeyGet KeyLoad KeySave KeySet
+
+" Miscellaneous Functions
+syn keyword tsaltFunction	ChatMode Dos Dial DosFunction ExitTelix
+syn keyword tsaltFunction	GetEnv GetFon HelpScreen LoadFon NewDir
+syn keyword tsaltFunction	Randon Redial RedirectDOS Run
+syn keyword tsaltFunction	Set_Terminal Show_Directory TelixVersion
+syn keyword tsaltFunction	Terminal TransTab Update_Term
+
+" Script Management
+syn keyword tsaltFunction	ArgCount Call CallD CompileScript GetRunPath
+syn keyword tsaltFunction	Is_Loaded Load_Scr ScriptVersion
+syn keyword tsaltFunction	TelixForWindows Unload_Scr
+
+" Sound Functions
+syn keyword tsaltFunction	Alarm PlayWave Tone
+
+" String Handling
+syn keyword tsaltFunction	CopyChrs CopyStr DelChrs GetS GetSXY
+syn keyword tsaltFunction	InputBox InsChrs ItoS SetChr StoI StrCat
+syn keyword tsaltFunction	StrChr StrCompI StrLen StrLower StrMaxLen
+syn keyword tsaltFunction	StrPos StrPosI StrUpper SubChr SubChrs
+syn keyword tsaltFunction	SubStr
+
+" Time, Date, and Timer Operations
+syn keyword tsaltFunction	CurTime Date Delay Delay_Scr Get_OnlineTime
+syn keyword tsaltFunction	tDay tHour tMin tMonth tSec tYear Time
+syn keyword tsaltFunction	Time_Up Timer_Free Time_Restart
+syn keyword tsaltFunction	Time_Start Time_Total
+
+" Video Operations
+syn keyword tsaltFunction	Box CNewLine Cursor_OnOff Clear_Scr
+syn keyword tsaltFunction	GetTermHeight GetTermWidth GetX GetY
+syn keyword tsaltFunction	GotoXY MsgBox NewLine PrintC PrintC_Trm
+syn keyword tsaltFunction	PrintN PrintN_Trm PrintS PrintS_Trm
+syn keyword tsaltFunction	PrintSC PRintSC_Trm
+syn keyword tsaltFunction	PStrA PStrAXY Scroll Status_Wind vGetChr
+syn keyword tsaltFunction	vGetChrs vGetChrsA  vPutChr vPutChrs
+syn keyword tsaltFunction	vPutChrsA vRstrArea vSaveArea
+
+" Dynamic Data Exchange (DDE) Operations
+syn keyword tsaltFunction	DDEExecute DDEInitate DDEPoke DDERequest
+syn keyword tsaltFunction	DDETerminate DDETerminateAll
+"END FUNCTIONS
+
+"PREDEFINED VARAIABLES
+syn keyword tsaltSysVar	_add_lf _alarm_on _answerback_str _asc_rcrtrans
+syn keyword tsaltSysVar	_asc_remabort _asc_rlftrans _asc_scpacing
+syn keyword tsaltSysVar	_asc_scrtrans _asc_secho _asc_slpacing
+syn keyword tsaltSysVar	_asc_spacechr _asc_striph _back_color
+syn keyword tsaltSysVar	_capture_fname _connect_str _dest_bs
+syn keyword tsaltSysVar	_dial_pause _dial_time _dial_post
+syn keyword tsaltSysVar	_dial_pref1 _dial_pref2 _dial_pref3
+syn keyword tsaltSysVar	_dial_pref4 _dir_prog _down_dir
+syn keyword tsaltSysVar	_entry_bbstype _entry_comment _entry_enum
+syn keyword tsaltSysVar	_entry_name _entry_num _entry_logonname
+syn keyword tsaltSysVar	_entry_pass _fore_color _image_file
+syn keyword tsaltSysVar	_local_echo _mdm_hang_str _mdm_init_str
+syn keyword tsaltSysVar	_no_connect1 _no_connect2 _no_connect3
+syn keyword tsaltSysVar	_no_connect4 _no_connect5 _redial_stop
+syn keyword tsaltSysVar	_scr_chk_key _script_dir _sound_on
+syn keyword tsaltSysVar	_strip_high _swap_bs _telix_dir _up_dir
+syn keyword tsaltSysVar	_usage_fname _zmodauto _zmod_rcrash
+syn keyword tsaltSysVar	_zmod_scrash
+"END PREDEFINED VARAIABLES
+
+"TYPE
+syn keyword tsaltType	str int
+"END TYPE
+
+"KEYWORDS
+syn keyword tsaltStatement	goto break return continue
+syn keyword tsaltConditional	if then else
+syn keyword tsaltRepeat		while for do
+"END KEYWORDS
+
+syn keyword tsaltTodo contained	TODO
+
+" the rest is pretty close to C -----------------------------------------
+
+" String and Character constants
+" Highlight special characters (those which have a backslash) differently
+syn match tsaltSpecial		contained "\^\d\d\d\|\^."
+syn region tsaltString		start=+"+  skip=+\\\\\|\\"+  end=+"+  contains=tsaltSpecial
+syn match tsaltCharacter	"'[^\\]'"
+syn match tsaltSpecialCharacter	"'\\.'"
+
+"catch errors caused by wrong parenthesis
+syn region tsaltParen		transparent start='(' end=')' contains=ALLBUT,tsaltParenError,tsaltIncluded,tsaltSpecial,tsaltTodo
+syn match tsaltParenError		")"
+syn match tsaltInParen		contained "[{}]"
+
+hi link tsaltParenError		tsaltError
+hi link tsaltInParen		tsaltError
+
+"integer number, or floating point number without a dot and with "f".
+syn match  tsaltNumber		"\<\d\+\(u\=l\=\|lu\|f\)\>"
+"floating point number, with dot, optional exponent
+syn match  tsaltFloat		"\<\d\+\.\d*\(e[-+]\=\d\+\)\=[fl]\=\>"
+"floating point number, starting with a dot, optional exponent
+syn match  tsaltFloat		"\.\d\+\(e[-+]\=\d\+\)\=[fl]\=\>"
+"floating point number, without dot, with exponent
+syn match  tsaltFloat		"\<\d\+e[-+]\=\d\+[fl]\=\>"
+"hex number
+syn match  tsaltNumber		"0x[0-9a-f]\+\(u\=l\=\|lu\)\>"
+"syn match  cIdentifier	"\<[a-z_][a-z0-9_]*\>"
+
+syn region tsaltComment		start="/\*"  end="\*/" contains=cTodo
+syn match  tsaltComment		"//.*" contains=cTodo
+syn match  tsaltCommentError	"\*/"
+
+syn region tsaltPreCondit	start="^[ \t]*#[ \t]*\(if\>\|ifdef\>\|ifndef\>\|elif\>\|else\>\|endif\>\)"  skip="\\$"  end="$" contains=tsaltComment,tsaltString,tsaltCharacter,tsaltNumber,tsaltCommentError
+syn region tsaltIncluded	contained start=+"+  skip=+\\\\\|\\"+  end=+"+
+syn match  tsaltIncluded	contained "<[^>]*>"
+syn match  tsaltInclude		"^[ \t]*#[ \t]*include\>[ \t]*["<]" contains=tsaltIncluded
+"syn match  TelixSalyLineSkip	"\\$"
+syn region tsaltDefine		start="^[ \t]*#[ \t]*\(define\>\|undef\>\)" skip="\\$" end="$" contains=ALLBUT,tsaltPreCondit,tsaltIncluded,tsaltInclude,tsaltDefine,tsaltInParen
+syn region tsaltPreProc		start="^[ \t]*#[ \t]*\(pragma\>\|line\>\|warning\>\|warn\>\|error\>\)" skip="\\$" end="$" contains=ALLBUT,tsaltPreCondit,tsaltIncluded,tsaltInclude,tsaltDefine,tsaltInParen
+
+" Highlight User Labels
+syn region tsaltMulti	transparent start='?' end=':' contains=ALLBUT,tsaltIncluded,tsaltSpecial,tsaltTodo
+
+syn sync ccomment tsaltComment
+
+
+" Define the default highlighting.
+" For version 5.7 and earlier: only when not done already
+" For version 5.8 and later: only when an item doesn't have highlighting yet
+if version >= 508 || !exists("did_tsalt_syntax_inits")
+  if version < 508
+    let did_tsalt_syntax_inits = 1
+    command -nargs=+ HiLink hi link <args>
+  else
+    command -nargs=+ HiLink hi def link <args>
+  endif
+
+	HiLink tsaltFunction		Statement
+	HiLink tsaltSysVar		Type
+	"HiLink tsaltLibFunc		UserDefFunc
+	"HiLink tsaltConstants		Type
+	"HiLink tsaltFuncArg		Type
+	"HiLink tsaltOperator		Operator
+	"HiLink tsaltLabel		Label
+	"HiLink tsaltUserLabel		Label
+	HiLink tsaltConditional		Conditional
+	HiLink tsaltRepeat		Repeat
+	HiLink tsaltCharacter		SpecialChar
+	HiLink tsaltSpecialCharacter	SpecialChar
+	HiLink tsaltNumber		Number
+	HiLink tsaltFloat		Float
+	HiLink tsaltCommentError	tsaltError
+	HiLink tsaltInclude		Include
+	HiLink tsaltPreProc		PreProc
+	HiLink tsaltDefine		Macro
+	HiLink tsaltIncluded		tsaltString
+	HiLink tsaltError		Error
+	HiLink tsaltStatement		Statement
+	HiLink tsaltPreCondit		PreCondit
+	HiLink tsaltType		Type
+	HiLink tsaltString		String
+	HiLink tsaltComment		Comment
+	HiLink tsaltSpecial		Special
+	HiLink tsaltTodo		Todo
+
+  delcommand HiLink
+endif
+
+let b:current_syntax = "tsalt"
+
+" vim: ts=8
--- /dev/null
+++ b/lib/vimfiles/syntax/tsscl.vim
@@ -1,0 +1,217 @@
+" Vim syntax file
+" Language:     TSS (Thermal Synthesizer System) Command Line
+" Maintainer:   Adrian Nagle, anagle@ball.com
+" Last Change:  2003 May 11
+" Filenames:    *.tsscl
+" URL:		http://www.naglenet.org/vim/syntax/tsscl.vim
+" MAIN URL:     http://www.naglenet.org/vim/
+
+
+
+" For version 5.x: Clear all syntax items
+" For version 6.x: Quit when a syntax file was already loaded
+if version < 600
+  syntax clear
+elseif exists("b:current_syntax")
+  finish
+endif
+
+
+
+" Ignore case
+syn case ignore
+
+
+
+"
+"
+" Begin syntax definitions for tss geomtery file.
+"
+
+" Load TSS geometry syntax file
+"source $VIM/myvim/tssgm.vim
+"source $VIMRUNTIME/syntax/c.vim
+
+" Define keywords for TSS
+syn keyword tssclCommand  begin radk list heatrates attr draw
+
+syn keyword tssclKeyword   cells rays error nodes levels objects cpu
+syn keyword tssclKeyword   units length positions energy time unit solar
+syn keyword tssclKeyword   solar_constant albedo planet_power
+
+syn keyword tssclEnd    exit
+
+syn keyword tssclUnits  cm feet meters inches
+syn keyword tssclUnits  Celsius Kelvin Fahrenheit Rankine
+
+
+
+" Define matches for TSS
+syn match  tssclString    /"[^"]\+"/ contains=ALLBUT,tssInteger,tssclKeyword,tssclCommand,tssclEnd,tssclUnits
+
+syn match  tssclComment     "#.*$"
+
+"  rational and logical operators
+"  <       Less than
+"  >       Greater than
+"  <=      Less than or equal
+"  >=      Greater than or equal
+"  == or = Equal to
+"  !=      Not equal to
+"  && or & Logical AND
+"  || or | Logical OR
+"  !       Logical NOT
+"
+" algebraic operators:
+"  ^ or ** Exponentation
+"  *       Multiplication
+"  /       Division
+"  %       Remainder
+"  +       Addition
+"  -       Subtraction
+"
+syn match  tssclOper      "||\||\|&&\|&\|!=\|!\|>=\|<=\|>\|<\|+\|-\|^\|\*\*\|\*\|/\|%\|==\|=\|\." skipwhite
+
+" CLI Directive Commands, with arguments
+"
+" BASIC COMMAND LIST
+" *ADD input_source
+" *ARITHMETIC { [ON] | OFF }
+" *CLOSE unit_number
+" *CPU
+" *DEFINE
+" *ECHO[/qualifiers] { [ON] | OFF }
+" *ELSE [IF { 0 | 1 } ]
+" *END { IF | WHILE }
+" *EXIT
+" *IF { 0 | 1 }
+" *LIST/n list variable
+" *OPEN[/r | /r+ | /w | /w+ ] unit_number file_name
+" *PROMPT prompt_string sybol_name
+" *READ/unit=unit_number[/LOCAL | /GLOBAL ] sym1 [sym2, [sym3 ...]]
+" *REWIND
+" *STOP
+" *STRCMP string_1 string_2 difference
+" *SYSTEM command
+" *UNDEFINE[/LOCAL][/GLOBAL] symbol_name
+" *WHILE { 0 | 1 }
+" *WRITE[/unit=unit_number] output text
+"
+syn match  tssclDirective "\*ADD"
+syn match  tssclDirective "\*ARITHMETIC \+\(ON\|OFF\)"
+syn match  tssclDirective "\*CLOSE"
+syn match  tssclDirective "\*CPU"
+syn match  tssclDirective "\*DEFINE"
+syn match  tssclDirective "\*ECHO"
+syn match  tssclConditional "\*ELSE"
+syn match  tssclConditional "\*END \+\(IF\|WHILE\)"
+syn match  tssclDirective "\*EXIT"
+syn match  tssclConditional "\*IF"
+syn match  tssclDirective "\*LIST"
+syn match  tssclDirective "\*OPEN"
+syn match  tssclDirective "\*PROMPT"
+syn match  tssclDirective "\*READ"
+syn match  tssclDirective "\*REWIND"
+syn match  tssclDirective "\*STOP"
+syn match  tssclDirective "\*STRCMP"
+syn match  tssclDirective "\*SYSTEM"
+syn match  tssclDirective "\*UNDEFINE"
+syn match  tssclConditional "\*WHILE"
+syn match  tssclDirective "\*WRITE"
+
+syn match  tssclContChar  "-$"
+
+" C library functoins
+" Bessel functions (jn, yn)
+" Error and complementary error fuctions (erf, erfc)
+" Exponential functions (exp)
+" Logrithm (log, log10)
+" Power (pow)
+" Square root (sqrt)
+" Floor (floor)
+" Ceiling (ceil)
+" Floating point remainder (fmod)
+" Floating point absolute value (fabs)
+" Gamma (gamma)
+" Euclidean distance function (hypot)
+" Hperbolic functions (sinh, cosh, tanh)
+" Trigometric functions in radians (sin, cos, tan, asin, acos, atan, atan2)
+" Trigometric functions in degrees (sind, cosd, tand, asind, acosd, atand,
+"    atan2d)
+"
+" local varialbles: cl_arg1, cl_arg2, etc. (cl_arg is an array of arguments)
+" cl_args is the number of arguments
+"
+"
+" I/O: *PROMPT, *WRITE, *READ
+"
+" Conditional branching:
+" IF, ELSE IF, END
+" *IF value       *IF I==10
+" *ELSE IF value  *ELSE IF I<10
+" *ELSE		  *ELSE
+" *ENDIF	  *ENDIF
+"
+"
+" Iterative looping:
+" WHILE
+" *WHILE test
+" .....
+" *END WHILE
+"
+"
+" EXAMPLE:
+" *DEFINE I = 1
+" *WHILE (I <= 10)
+"    *WRITE I = 'I'
+"    *DEFINE I = (I + 1)
+" *END WHILE
+"
+
+syn match  tssclQualifier "/[^/ ]\+"hs=s+1
+syn match  tssclSymbol    "'\S\+'"
+"syn match  tssclSymbol2   " \S\+ " contained
+
+syn match  tssclInteger     "-\=\<[0-9]*\>"
+syn match  tssclFloat       "-\=\<[0-9]*\.[0-9]*"
+syn match  tssclScientific  "-\=\<[0-9]*\.[0-9]*E[-+]\=[0-9]\+\>"
+
+
+
+" Define the default highlighting
+" For version 5.7 and earlier: only when not done already
+" For version 5.8 and later: only when an item doesn't have highlighting yet
+if version >= 508 || !exists("did_tsscl_syntax_inits")
+  if version < 508
+    let did_tsscl_syntax_inits = 1
+    command -nargs=+ HiLink hi link <args>
+  else
+    command -nargs=+ HiLink hi def link <args>
+  endif
+
+  HiLink tssclCommand		Statement
+  HiLink tssclKeyword		Special
+  HiLink tssclEnd		Macro
+  HiLink tssclUnits		Special
+
+  HiLink tssclComment		Comment
+  HiLink tssclDirective		Statement
+  HiLink tssclConditional	Conditional
+  HiLink tssclContChar		Macro
+  HiLink tssclQualifier		Typedef
+  HiLink tssclSymbol		Identifier
+  HiLink tssclSymbol2		Symbol
+  HiLink tssclString		String
+  HiLink tssclOper		Operator
+
+  HiLink tssclInteger		Number
+  HiLink tssclFloat		Number
+  HiLink tssclScientific	Number
+
+  delcommand HiLink
+endif
+
+
+let b:current_syntax = "tsscl"
+
+" vim: ts=8 sw=2
--- /dev/null
+++ b/lib/vimfiles/syntax/tssgm.vim
@@ -1,0 +1,111 @@
+" Vim syntax file
+" Language:     TSS (Thermal Synthesizer System) Geometry
+" Maintainer:   Adrian Nagle, anagle@ball.com
+" Last Change:  2003 May 11
+" Filenames:    *.tssgm
+" URL:		http://www.naglenet.org/vim/syntax/tssgm.vim
+" MAIN URL:     http://www.naglenet.org/vim/
+
+
+
+" For version 5.x: Clear all syntax items
+" For version 6.x: Quit when a syntax file was already loaded
+if version < 600
+  syntax clear
+elseif exists("b:current_syntax")
+  finish
+endif
+
+
+
+" Ignore case
+syn case ignore
+
+
+
+"
+"
+" Begin syntax definitions for tss geomtery file.
+"
+
+" Define keywords for TSS
+syn keyword tssgmParam  units mirror param active sides submodel include
+syn keyword tssgmParam  iconductor nbeta ngamma optics material thickness color
+syn keyword tssgmParam  initial_temp
+syn keyword tssgmParam  initial_id node_ids node_add node_type
+syn keyword tssgmParam  gamma_boundaries gamma_add beta_boundaries
+syn keyword tssgmParam  p1 p2 p3 p4 p5 p6 rot1 rot2 rot3 tx ty tz
+
+syn keyword tssgmSurfType  rectangle trapezoid disc ellipse triangle
+syn keyword tssgmSurfType  polygon cylinder cone sphere ellipic-cone
+syn keyword tssgmSurfType  ogive torus box paraboloid hyperboloid ellipsoid
+syn keyword tssgmSurfType  quadrilateral trapeziod
+
+syn keyword tssgmArgs   OUT IN DOWN BOTH DOUBLE NONE SINGLE RADK CC FECC
+syn keyword tssgmArgs   white red blue green yellow orange violet pink
+syn keyword tssgmArgs   turquoise grey black
+syn keyword tssgmArgs   Arithmetic Boundary Heater
+
+syn keyword tssgmDelim  assembly
+
+syn keyword tssgmEnd    end
+
+syn keyword tssgmUnits  cm feet meters inches
+syn keyword tssgmUnits  Celsius Kelvin Fahrenheit Rankine
+
+
+
+" Define matches for TSS
+syn match  tssgmDefault     "^DEFAULT/LENGTH = \(ft\|in\|cm\|m\)"
+syn match  tssgmDefault     "^DEFAULT/TEMP = [CKFR]"
+
+syn match  tssgmComment       /comment \+= \+".*"/ contains=tssParam,tssgmCommentString
+syn match  tssgmCommentString /".*"/ contained
+
+syn match  tssgmSurfIdent   " \S\+\.\d\+ \=$"
+
+syn match  tssgmString      /"[^" ]\+"/ms=s+1,me=e-1 contains=ALLBUT,tssInteger
+
+syn match  tssgmArgs	    / = [xyz],"/ms=s+3,me=e-2
+
+syn match  tssgmInteger     "-\=\<[0-9]*\>"
+syn match  tssgmFloat       "-\=\<[0-9]*\.[0-9]*"
+syn match  tssgmScientific  "-\=\<[0-9]*\.[0-9]*E[-+]\=[0-9]\+\>"
+
+
+
+" Define the default highlighting
+" For version 5.7 and earlier: only when not done already
+" For version 5.8 and later: only when an item doesn't have highlighting yet
+if version >= 508 || !exists("did_tssgm_syntax_inits")
+  if version < 508
+    let did_tssgm_syntax_inits = 1
+    command -nargs=+ HiLink hi link <args>
+  else
+    command -nargs=+ HiLink hi def link <args>
+  endif
+
+  HiLink tssgmParam		Statement
+  HiLink tssgmSurfType		Type
+  HiLink tssgmArgs		Special
+  HiLink tssgmDelim		Typedef
+  HiLink tssgmEnd		Macro
+  HiLink tssgmUnits		Special
+
+  HiLink tssgmDefault		SpecialComment
+  HiLink tssgmComment		Statement
+  HiLink tssgmCommentString	Comment
+  HiLink tssgmSurfIdent		Identifier
+  HiLink tssgmString		Delimiter
+
+  HiLink tssgmInteger		Number
+  HiLink tssgmFloat		Float
+  HiLink tssgmScientific	Float
+
+  delcommand HiLink
+endif
+
+
+let b:current_syntax = "tssgm"
+
+" vim: ts=8 sw=2
--- /dev/null
+++ b/lib/vimfiles/syntax/tssop.vim
@@ -1,0 +1,87 @@
+" Vim syntax file
+" Language:     TSS (Thermal Synthesizer System) Optics
+" Maintainer:   Adrian Nagle, anagle@ball.com
+" Last Change:  2003 May 11
+" Filenames:    *.tssop
+" URL:		http://www.naglenet.org/vim/syntax/tssop.vim
+" MAIN URL:     http://www.naglenet.org/vim/
+
+
+
+" For version 5.x: Clear all syntax items
+" For version 6.x: Quit when a syntax file was already loaded
+if version < 600
+  syntax clear
+elseif exists("b:current_syntax")
+  finish
+endif
+
+
+
+" Ignore case
+syn case ignore
+
+
+
+"
+"
+" Begin syntax definitions for tss optics file.
+"
+
+" Define keywords for TSS
+syn keyword tssopParam  ir_eps ir_trans ir_spec ir_tspec ir_refract
+syn keyword tssopParam  sol_eps sol_trans sol_spec sol_tspec sol_refract
+syn keyword tssopParam  color
+
+"syn keyword tssopProp   property
+
+syn keyword tssopArgs   white red blue green yellow orange violet pink
+syn keyword tssopArgs   turquoise grey black
+
+
+
+" Define matches for TSS
+syn match  tssopComment       /comment \+= \+".*"/ contains=tssopParam,tssopCommentString
+syn match  tssopCommentString /".*"/ contained
+
+syn match  tssopProp	    "property "
+syn match  tssopProp	    "edit/optic "
+syn match  tssopPropName    "^property \S\+" contains=tssopProp
+syn match  tssopPropName    "^edit/optic \S\+$" contains=tssopProp
+
+syn match  tssopInteger     "-\=\<[0-9]*\>"
+syn match  tssopFloat       "-\=\<[0-9]*\.[0-9]*"
+syn match  tssopScientific  "-\=\<[0-9]*\.[0-9]*E[-+]\=[0-9]\+\>"
+
+
+
+" Define the default highlighting
+" For version 5.7 and earlier: only when not done already
+" For version 5.8 and later: only when an item doesn't have highlighting yet
+if version >= 508 || !exists("did_tssop_syntax_inits")
+  if version < 508
+    let did_tssop_syntax_inits = 1
+    command -nargs=+ HiLink hi link <args>
+  else
+    command -nargs=+ HiLink hi def link <args>
+  endif
+
+  HiLink tssopParam		Statement
+  HiLink tssopProp		Identifier
+  HiLink tssopArgs		Special
+
+  HiLink tssopComment		Statement
+  HiLink tssopCommentString	Comment
+  HiLink tssopPropName		Typedef
+
+  HiLink tssopInteger		Number
+  HiLink tssopFloat		Float
+  HiLink tssopScientific	Float
+
+  delcommand HiLink
+endif
+
+
+let b:current_syntax = "tssop"
+
+" vim: ts=8 sw=2
--- /dev/null
+++ b/lib/vimfiles/syntax/uc.vim
@@ -1,0 +1,178 @@
+" Vim syntax file
+" Language:	UnrealScript
+" Maintainer:	Mark Ferrell <major@chaoticdreams.org>
+" URL:		ftp://ftp.chaoticdreams.org/pub/ut/vim/uc.vim
+" Credits:	Based on the java.vim syntax file by Claudio Fleiner
+" Last change:	2003 May 31
+
+" Please check :help uc.vim for comments on some of the options available.
+
+" For version 5.x: Clear all syntax items
+" For version 6.x: Quit when a syntax file was already loaded
+if version < 600
+  syntax clear
+elseif exists("b:current_syntax")
+  finish
+endif
+
+" some characters that cannot be in a UnrealScript program (outside a string)
+syn match ucError "[\\@`]"
+syn match ucError "<<<\|\.\.\|=>\|<>\|||=\|&&=\|[^-]->\|\*\/"
+
+" we define it here so that included files can test for it
+if !exists("main_syntax")
+  let main_syntax='uc'
+endif
+
+syntax case ignore
+
+" keyword definitions
+syn keyword ucBranch	      break continue
+syn keyword ucConditional     if else switch
+syn keyword ucRepeat	      while for do foreach
+syn keyword ucBoolean	      true false
+syn keyword ucConstant	      null
+syn keyword ucOperator	      new instanceof
+syn keyword ucType	      boolean char byte short int long float double
+syn keyword ucType	      void Pawn sound state auto exec function ipaddr
+syn keyword ucType	      ELightType actor ammo defaultproperties bool
+syn keyword ucType	      native noexport var out vector name local string
+syn keyword ucType	      event
+syn keyword ucStatement       return
+syn keyword ucStorageClass    static synchronized transient volatile final
+syn keyword ucMethodDecl      synchronized throws
+
+" UnrealScript defines classes in sorta fscked up fashion
+syn match   ucClassDecl       "^[Cc]lass[\s$]*\S*[\s$]*expands[\s$]*\S*;" contains=ucSpecial,ucSpecialChar,ucClassKeys
+syn keyword ucClassKeys	      class expands extends
+syn match   ucExternal	      "^\#exec.*" contains=ucCommentString,ucNumber
+syn keyword ucScopeDecl       public protected private abstract
+
+" UnrealScript Functions
+syn match   ucFuncDef	      "^.*function\s*[\(]*" contains=ucType,ucStorageClass
+syn match   ucEventDef	      "^.*event\s*[\(]*" contains=ucType,ucStorageClass
+syn match   ucClassLabel      "[a-zA-Z0-9]*\'[a-zA-Z0-9]*\'" contains=ucCharacter
+
+syn region  ucLabelRegion     transparent matchgroup=ucLabel start="\<case\>" matchgroup=NONE end=":" contains=ucNumber
+syn match   ucUserLabel       "^\s*[_$a-zA-Z][_$a-zA-Z0-9_]*\s*:"he=e-1 contains=ucLabel
+syn keyword ucLabel	      default
+
+" The following cluster contains all java groups except the contained ones
+syn cluster ucTop contains=ucExternal,ucError,ucError,ucBranch,ucLabelRegion,ucLabel,ucConditional,ucRepeat,ucBoolean,ucConstant,ucTypedef,ucOperator,ucType,ucType,ucStatement,ucStorageClass,ucMethodDecl,ucClassDecl,ucClassDecl,ucClassDecl,ucScopeDecl,ucError,ucError2,ucUserLabel,ucClassLabel
+
+" Comments
+syn keyword ucTodo	       contained TODO FIXME XXX
+syn region  ucCommentString    contained start=+"+ end=+"+ end=+\*/+me=s-1,he=s-1 contains=ucSpecial,ucCommentStar,ucSpecialChar
+syn region  ucComment2String   contained start=+"+  end=+$\|"+  contains=ucSpecial,ucSpecialChar
+syn match   ucCommentCharacter contained "'\\[^']\{1,6\}'" contains=ucSpecialChar
+syn match   ucCommentCharacter contained "'\\''" contains=ucSpecialChar
+syn match   ucCommentCharacter contained "'[^\\]'"
+syn region  ucComment	       start="/\*"  end="\*/" contains=ucCommentString,ucCommentCharacter,ucNumber,ucTodo
+syn match   ucCommentStar      contained "^\s*\*[^/]"me=e-1
+syn match   ucCommentStar      contained "^\s*\*$"
+syn match   ucLineComment      "//.*" contains=ucComment2String,ucCommentCharacter,ucNumber,ucTodo
+hi link ucCommentString ucString
+hi link ucComment2String ucString
+hi link ucCommentCharacter ucCharacter
+
+syn cluster ucTop add=ucComment,ucLineComment
+
+" match the special comment /**/
+syn match   ucComment	       "/\*\*/"
+
+" Strings and constants
+syn match   ucSpecialError     contained "\\."
+"syn match   ucSpecialCharError contained "[^']"
+syn match   ucSpecialChar      contained "\\\([4-9]\d\|[0-3]\d\d\|[\"\\'ntbrf]\|u\x\{4\}\)"
+syn region  ucString	       start=+"+ end=+"+  contains=ucSpecialChar,ucSpecialError
+syn match   ucStringError      +"\([^"\\]\|\\.\)*$+
+syn match   ucCharacter        "'[^']*'" contains=ucSpecialChar,ucSpecialCharError
+syn match   ucCharacter        "'\\''" contains=ucSpecialChar
+syn match   ucCharacter        "'[^\\]'"
+syn match   ucNumber	       "\<\(0[0-7]*\|0[xX]\x\+\|\d\+\)[lL]\=\>"
+syn match   ucNumber	       "\(\<\d\+\.\d*\|\.\d\+\)\([eE][-+]\=\d\+\)\=[fFdD]\="
+syn match   ucNumber	       "\<\d\+[eE][-+]\=\d\+[fFdD]\=\>"
+syn match   ucNumber	       "\<\d\+\([eE][-+]\=\d\+\)\=[fFdD]\>"
+
+" unicode characters
+syn match   ucSpecial "\\u\d\{4\}"
+
+syn cluster ucTop add=ucString,ucCharacter,ucNumber,ucSpecial,ucStringError
+
+" catch errors caused by wrong parenthesis
+syn region  ucParen	       transparent start="(" end=")" contains=@ucTop,ucParen
+syn match   ucParenError       ")"
+hi link     ucParenError       ucError
+
+if !exists("uc_minlines")
+  let uc_minlines = 10
+endif
+exec "syn sync ccomment ucComment minlines=" . uc_minlines
+
+" Define the default highlighting.
+" For version 5.7 and earlier: only when not done already
+" For version 5.8 and later: only when an item doesn't have highlighting yet
+if version >= 508 || !exists("did_uc_syntax_inits")
+  if version < 508
+    let did_uc_syntax_inits = 1
+    command -nargs=+ HiLink hi link <args>
+  else
+    command -nargs=+ HiLink hi def link <args>
+  endif
+
+  HiLink ucFuncDef			Conditional
+  HiLink ucEventDef			Conditional
+  HiLink ucBraces			Function
+  HiLink ucBranch			Conditional
+  HiLink ucLabel			Label
+  HiLink ucUserLabel			Label
+  HiLink ucConditional			Conditional
+  HiLink ucRepeat			Repeat
+  HiLink ucStorageClass			StorageClass
+  HiLink ucMethodDecl			ucStorageClass
+  HiLink ucClassDecl			ucStorageClass
+  HiLink ucScopeDecl			ucStorageClass
+  HiLink ucBoolean			Boolean
+  HiLink ucSpecial			Special
+  HiLink ucSpecialError			Error
+  HiLink ucSpecialCharError		Error
+  HiLink ucString			String
+  HiLink ucCharacter			Character
+  HiLink ucSpecialChar			SpecialChar
+  HiLink ucNumber			Number
+  HiLink ucError			Error
+  HiLink ucStringError			Error
+  HiLink ucStatement			Statement
+  HiLink ucOperator			Operator
+  HiLink ucOverLoaded			Operator
+  HiLink ucComment			Comment
+  HiLink ucDocComment			Comment
+  HiLink ucLineComment			Comment
+  HiLink ucConstant			ucBoolean
+  HiLink ucTypedef			Typedef
+  HiLink ucTodo				Todo
+
+  HiLink ucCommentTitle			SpecialComment
+  HiLink ucDocTags			Special
+  HiLink ucDocParam			Function
+  HiLink ucCommentStar			ucComment
+
+  HiLink ucType				Type
+  HiLink ucExternal			Include
+
+  HiLink ucClassKeys			Conditional
+  HiLink ucClassLabel			Conditional
+
+  HiLink htmlComment			Special
+  HiLink htmlCommentPart		Special
+
+  delcommand HiLink
+endif
+
+let b:current_syntax = "uc"
+
+if main_syntax == 'uc'
+  unlet main_syntax
+endif
+
+" vim: ts=8
--- /dev/null
+++ b/lib/vimfiles/syntax/udevconf.vim
@@ -1,0 +1,39 @@
+" Vim syntax file
+" Language:         udev(8) configuration file
+" Maintainer:       Nikolai Weibull <now@bitwi.se>
+" Latest Revision:  2006-04-19
+
+if exists("b:current_syntax")
+  finish
+endif
+
+let s:cpo_save = &cpo
+set cpo&vim
+
+syn keyword udevconfTodo        contained TODO FIXME XXX NOTE
+
+syn region  udevconfComment     display oneline start='^\s*#' end='$'
+                                \ contains=udevconfTodo,@Spell
+
+syn match   udevconfBegin       display '^'
+                                \ nextgroup=udevconfVariable,udevconfComment
+                                \ skipwhite
+
+syn keyword udevconfVariable    contained udev_root udev_db udev_rules udev_log
+                                \ nextgroup=udevconfVariableEq
+
+syn match   udevconfVariableEq  contained '[[:space:]=]'
+                                \ nextgroup=udevconfString skipwhite
+
+syn region  udevconfString      contained display oneline start=+"+ end=+"+
+
+hi def link udevconfTodo        Todo
+hi def link udevconfComment     Comment
+hi def link udevconfVariable    Identifier
+hi def link udevconfVariableEq  Operator
+hi def link udevconfString      String
+
+let b:current_syntax = "udevconf"
+
+let &cpo = s:cpo_save
+unlet s:cpo_save
--- /dev/null
+++ b/lib/vimfiles/syntax/udevperm.vim
@@ -1,0 +1,69 @@
+" Vim syntax file
+" Language:         udev(8) permissions file
+" Maintainer:       Nikolai Weibull <now@bitwi.se>
+" Latest Revision:  2006-04-19
+
+if exists("b:current_syntax")
+  finish
+endif
+
+let s:cpo_save = &cpo
+set cpo&vim
+
+syn match   udevpermBegin       display '^' nextgroup=udevpermDevice
+
+syn match   udevpermDevice      contained display '[^:]\+'
+                                \ contains=udevpermPattern
+                                \ nextgroup=udevpermUserColon
+
+syn match   udevpermPattern     contained '[*?]'
+syn region  udevpermPattern     contained start='\[!\=' end='\]'
+                                \ contains=udevpermPatRange
+
+syn match   udevpermPatRange    contained '[^[-]-[^]-]'
+
+syn match   udevpermUserColon   contained display ':'
+                                \ nextgroup=udevpermUser
+
+syn match   udevpermUser        contained display '[^:]\+'
+                                \ nextgroup=udevpermGroupColon
+
+syn match   udevpermGroupColon  contained display ':'
+                                \ nextgroup=udevpermGroup
+
+syn match   udevpermGroup       contained display '[^:]\+'
+                                \ nextgroup=udevpermPermColon
+
+syn match   udevpermPermColon   contained display ':'
+                                \ nextgroup=udevpermPerm
+
+syn match   udevpermPerm        contained display '\<0\=\o\+\>'
+                                \ contains=udevpermOctalZero
+
+syn match   udevpermOctalZero   contained display '\<0'
+syn match   udevpermOctalError  contained display '\<0\o*[89]\d*\>'
+
+syn keyword udevpermTodo        contained TODO FIXME XXX NOTE
+
+syn region  udevpermComment     display oneline start='^\s*#' end='$'
+                                \ contains=udevpermTodo,@Spell
+
+hi def link udevpermTodo        Todo
+hi def link udevpermComment     Comment
+hi def link udevpermDevice      String
+hi def link udevpermPattern     SpecialChar
+hi def link udevpermPatRange    udevpermPattern
+hi def link udevpermColon       Normal
+hi def link udevpermUserColon   udevpermColon
+hi def link udevpermUser        Identifier
+hi def link udevpermGroupColon  udevpermColon
+hi def link udevpermGroup       Type
+hi def link udevpermPermColon   udevpermColon
+hi def link udevpermPerm        Number
+hi def link udevpermOctalZero   PreProc
+hi def link udevpermOctalError  Error
+
+let b:current_syntax = "udevperm"
+
+let &cpo = s:cpo_save
+unlet s:cpo_save
--- /dev/null
+++ b/lib/vimfiles/syntax/udevrules.vim
@@ -1,0 +1,171 @@
+" Vim syntax file
+" Language:         udev(8) rules file
+" Maintainer:       Nikolai Weibull <now@bitwi.se>
+" Latest Revision:  2006-12-18
+
+if exists("b:current_syntax")
+  finish
+endif
+
+let s:cpo_save = &cpo
+set cpo&vim
+
+" TODO: Line continuations.
+
+syn keyword udevrulesTodo       contained TODO FIXME XXX NOTE
+
+syn region  udevrulesComment    display oneline start='^\s*#' end='$'
+                                \ contains=udevrulesTodo,@Spell
+
+syn keyword udevrulesRuleKey    ACTION DEVPATH KERNEL SUBSYSTEM KERNELS
+                                \ SUBSYSTEMS DRIVERS RESULT
+                                \ nextgroup=udevrulesRuleTest
+                                \ skipwhite
+
+syn keyword udevrulesRuleKey    ATTRS nextgroup=udevrulesAttrsPath
+
+syn region  udevrulesAttrsPath  display transparent
+                                \ matchgroup=udevrulesDelimiter start='{'
+                                \ matchgroup=udevrulesDelimiter end='}'
+                                \ contains=udevrulesPath
+                                \ nextgroup=udevrulesRuleTest
+                                \ skipwhite
+
+syn keyword udevrulesRuleKey    ENV nextgroup=udevrulesEnvVar
+
+syn region  udevrulesEnvVar     display transparent
+                                \ matchgroup=udevrulesDelimiter start='{'
+                                \ matchgroup=udevrulesDelimiter end='}'
+                                \ contains=udevrulesVariable
+                                \ nextgroup=udevrulesRuleTest,udevrulesRuleEq
+                                \ skipwhite
+
+syn keyword udevrulesRuleKey    PROGRAM RESULT
+                                \ nextgroup=udevrulesEStringTest,udevrulesEStringEq
+                                \ skipwhite
+
+syn keyword udevrulesAssignKey  NAME SYMLINK OWNER GROUP RUN
+                                \ nextgroup=udevrulesEStringEq
+                                \ skipwhite
+
+syn keyword udevrulesAssignKey  MODE LABEL GOTO WAIT_FOR_SYSFS
+                                \ nextgroup=udevrulesRuleEq
+                                \ skipwhite
+
+syn keyword udevrulesAssignKey  ATTR nextgroup=udevrulesAttrsPath
+
+syn region  udevrulesAttrKey    display transparent
+                                \ matchgroup=udevrulesDelimiter start='{'
+                                \ matchgroup=udevrulesDelimiter end='}'
+                                \ contains=udevrulesKey
+                                \ nextgroup=udevrulesRuleEq
+                                \ skipwhite
+
+syn keyword udevrulesAssignKey  IMPORT nextgroup=udevrulesImport,
+                                \ udevrulesEStringEq
+                                \ skipwhite
+
+syn region  udevrulesImport     display transparent
+                                \ matchgroup=udevrulesDelimiter start='{'
+                                \ matchgroup=udevrulesDelimiter end='}'
+                                \ contains=udevrulesImportType
+                                \ nextgroup=udevrulesEStringEq
+                                \ skipwhite
+
+syn keyword udevrulesImportType program file parent
+
+syn keyword udevrulesAssignKey  OPTIONS
+                                \ nextgroup=udevrulesOptionsEq
+
+syn match   udevrulesPath       contained display '[^}]\+'
+
+syn match   udevrulesVariable   contained display '[^}]\+'
+
+syn match   udevrulesRuleTest   contained display '[=!:]='
+                                \ nextgroup=udevrulesString skipwhite
+
+syn match   udevrulesEStringTest contained display '[=!+:]='
+                                \ nextgroup=udevrulesEString skipwhite
+
+syn match   udevrulesRuleEq     contained display '+=\|=\ze[^=]'
+                                \ nextgroup=udevrulesString skipwhite
+
+syn match   udevrulesEStringEq  contained '+=\|=\ze[^=]'
+                                \ nextgroup=udevrulesEString skipwhite
+
+syn match   udevrulesOptionsEq  contained '+=\|=\ze[^=]'
+                                \ nextgroup=udevrulesOptions skipwhite
+
+syn region  udevrulesEString    contained display oneline start=+"+ end=+"+
+                                \ contains=udevrulesStrEscapes,udevrulesStrVars
+
+syn match   udevrulesStrEscapes contained '%[knpbMmcPrN%]'
+
+" TODO: This can actually stand alone (without {…}), so add a nextgroup here.
+syn region  udevrulesStrEscapes contained start='%c{' end='}'
+                                \ contains=udevrulesStrNumber
+
+syn region  udevrulesStrEscapes contained start='%s{' end='}'
+                                \ contains=udevrulesPath
+
+syn region  udevrulesStrEscapes contained start='%E{' end='}'
+                                \ contains=udevrulesVariable
+
+syn match   udevrulesStrNumber  contained '\d\++\='
+
+syn match   udevrulesStrVars    contained display '$\%(kernel\|number\|devpath\|id\|major\|minor\|result\|parent\|root\|tempnode\)\>'
+
+syn region  udevrulesStrVars    contained start='$attr{' end='}'
+                                \ contains=udevrulesPath
+
+syn region  udevrulesStrVars    contained start='$env{' end='}'
+                                \ contains=udevrulesVariable
+
+syn match   udevrulesStrVars    contained display '\$\$'
+
+syn region  udevrulesString     contained display oneline start=+"+ end=+"+
+                                \ contains=udevrulesPattern
+
+syn match   udevrulesPattern    contained '[*?]'
+syn region  udevrulesPattern    contained start='\[!\=' end='\]'
+                                \ contains=udevrulesPatRange
+
+syn match   udevrulesPatRange   contained '[^[-]-[^]-]'
+
+syn region  udevrulesOptions    contained display oneline start=+"+ end=+"+
+                                \ contains=udevrulesOption,udevrulesOptionSep
+
+syn keyword udevrulesOption     contained last_rule ignore_device ignore_remove
+                                \ all_partitions
+
+syn match   udevrulesOptionSep  contained ','
+
+hi def link udevrulesTodo       Todo
+hi def link udevrulesComment    Comment
+hi def link udevrulesRuleKey    Keyword
+hi def link udevrulesDelimiter  Delimiter
+hi def link udevrulesAssignKey  Identifier
+hi def link udevrulesPath       Identifier
+hi def link udevrulesVariable   Identifier
+hi def link udevrulesAttrKey    Identifier
+" XXX: setting this to Operator makes for extremely intense highlighting.
+hi def link udevrulesEq         Normal
+hi def link udevrulesRuleEq     udevrulesEq
+hi def link udevrulesEStringEq  udevrulesEq
+hi def link udevrulesOptionsEq  udevrulesEq
+hi def link udevrulesEString    udevrulesString
+hi def link udevrulesStrEscapes SpecialChar
+hi def link udevrulesStrNumber  Number
+hi def link udevrulesStrVars    Identifier
+hi def link udevrulesString     String
+hi def link udevrulesPattern    SpecialChar
+hi def link udevrulesPatRange   SpecialChar
+hi def link udevrulesOptions    udevrulesString
+hi def link udevrulesOption     Type
+hi def link udevrulesOptionSep  Delimiter
+hi def link udevrulesImportType Type
+
+let b:current_syntax = "udevrules"
+
+let &cpo = s:cpo_save
+unlet s:cpo_save
--- /dev/null
+++ b/lib/vimfiles/syntax/uil.vim
@@ -1,0 +1,85 @@
+" Vim syntax file
+" Language:	Motif UIL (User Interface Language)
+" Maintainer:	Thomas Koehler <jean-luc@picard.franken.de>
+" Last Change:	2002 Sep 20
+" URL:		http://jeanluc-picard.de/vim/syntax/uil.vim
+
+" Quit when a syntax file was already loaded
+if version < 600
+   syntax clear
+elseif exists("b:current_syntax")
+  finish
+endif
+
+" A bunch of useful keywords
+syn keyword uilType	arguments	callbacks	color
+syn keyword uilType	compound_string	controls	end
+syn keyword uilType	exported	file		include
+syn keyword uilType	module		object		procedure
+syn keyword uilType	user_defined	xbitmapfile
+
+syn keyword uilTodo contained	TODO
+
+" String and Character contstants
+" Highlight special characters (those which have a backslash) differently
+syn match   uilSpecial contained "\\\d\d\d\|\\."
+syn region  uilString		start=+"+  skip=+\\\\\|\\"+  end=+"+  contains=uilSpecial
+syn match   uilCharacter	"'[^\\]'"
+syn region  uilString		start=+'+  skip=+\\\\\|\\"+  end=+'+  contains=uilSpecial
+syn match   uilSpecialCharacter	"'\\.'"
+syn match   uilSpecialStatement	"Xm[^ =(){}]*"
+syn match   uilSpecialFunction	"MrmNcreateCallback"
+syn match   uilRessource	"XmN[^ =(){}]*"
+
+syn match  uilNumber		"-\=\<\d*\.\=\d\+\(e\=f\=\|[uU]\=[lL]\=\)\>"
+syn match  uilNumber		"0[xX][0-9a-fA-F]\+\>"
+
+syn region uilComment		start="/\*"  end="\*/" contains=uilTodo
+syn match  uilComment		"!.*" contains=uilTodo
+syn match  uilCommentError	"\*/"
+
+syn region uilPreCondit		start="^#\s*\(if\>\|ifdef\>\|ifndef\>\|elif\>\|else\>\|endif\>\)"  skip="\\$"  end="$" contains=uilComment,uilString,uilCharacter,uilNumber,uilCommentError
+syn match  uilIncluded contained "<[^>]*>"
+syn match  uilInclude		"^#\s*include\s\+." contains=uilString,uilIncluded
+syn match  uilLineSkip		"\\$"
+syn region uilDefine		start="^#\s*\(define\>\|undef\>\)" end="$" contains=uilLineSkip,uilComment,uilString,uilCharacter,uilNumber,uilCommentError
+
+syn sync ccomment uilComment
+
+" Define the default highlighting.
+" For version 5.7 and earlier: only when not done already
+" For version 5.8 and later: only when an item doesn't have highlighting yet
+if version >= 508 || !exists("did_uil_syn_inits")
+  if version < 508
+    let did_uil_syn_inits = 1
+    command -nargs=+ HiLink hi link <args>
+  else
+    command -nargs=+ HiLink hi def link <args>
+  endif
+
+  " The default highlighting.
+  HiLink uilCharacter		uilString
+  HiLink uilSpecialCharacter	uilSpecial
+  HiLink uilNumber		uilString
+  HiLink uilCommentError	uilError
+  HiLink uilInclude		uilPreCondit
+  HiLink uilDefine		uilPreCondit
+  HiLink uilIncluded		uilString
+  HiLink uilSpecialFunction	uilRessource
+  HiLink uilRessource		Identifier
+  HiLink uilSpecialStatement	Keyword
+  HiLink uilError		Error
+  HiLink uilPreCondit		PreCondit
+  HiLink uilType		Type
+  HiLink uilString		String
+  HiLink uilComment		Comment
+  HiLink uilSpecial		Special
+  HiLink uilTodo		Todo
+
+  delcommand HiLink
+endif
+
+
+let b:current_syntax = "uil"
+
+" vim: ts=8
--- /dev/null
+++ b/lib/vimfiles/syntax/updatedb.vim
@@ -1,0 +1,37 @@
+" Vim syntax file
+" Language:         updatedb.conf(5) configuration file
+" Maintainer:       Nikolai Weibull <now@bitwi.se>
+" Latest Revision:  2006-04-19
+
+if exists("b:current_syntax")
+  finish
+endif
+
+let s:cpo_save = &cpo
+set cpo&vim
+
+syn keyword updatedbTodo    contained TODO FIXME XXX NOTE
+
+syn region  updatedbComment display oneline start='^\s*#' end='$'
+                            \ contains=updatedbTodo,@Spell
+
+syn match   updatedbBegin   display '^'
+                            \ nextgroup=updatedbName,updatedbComment skipwhite
+
+syn keyword updatedbName    contained PRUNEFS PRUNEPATHS
+                            \ nextgroup=updatedbNameEq
+
+syn match   updatedbNameEq  contained display '=' nextgroup=updatedbValue
+
+syn region  updatedbValue   contained display oneline start='"' end='"'
+
+hi def link updatedbTodo    Todo
+hi def link updatedbComment Comment
+hi def link updatedbName    Identifier
+hi def link updatedbNameEq  Operator
+hi def link updatedbValue   String
+
+let b:current_syntax = "updatedb"
+
+let &cpo = s:cpo_save
+unlet s:cpo_save
--- /dev/null
+++ b/lib/vimfiles/syntax/valgrind.vim
@@ -1,0 +1,99 @@
+" Vim syntax file
+" Language: Valgrind Memory Debugger Output
+" Maintainer: Roger Luethi <rl@hellgate.ch>
+" Program URL: http://devel-home.kde.org/~sewardj/
+" Last Change: 2002 Apr 07
+"
+" Notes: mostly based on strace.vim and xml.vim
+
+" Quit when a syntax file was already loaded
+if exists("b:current_syntax")
+	finish
+endif
+
+syn case match
+syn sync minlines=50
+
+syn match valgrindSpecLine "^[+-]\{2}\d\+[+-]\{2}.*$"
+
+syn region valgrindRegion
+	\ start=+^==\z(\d\+\)== \w.*$+
+	\ skip=+^==\z1==\( \|    .*\)$+
+	\ end=+^+
+	\ fold
+	\ keepend
+	\ contains=valgrindPidChunk,valgrindLine
+
+syn region valgrindPidChunk
+	\ start=+\(^==\)\@<=+
+	\ end=+\(==\)\@=+
+	\ contained
+	\ contains=valgrindPid0,valgrindPid1,valgrindPid2,valgrindPid3,valgrindPid4,valgrindPid5,valgrindPid6,valgrindPid7,valgrindPid8,valgrindPid9
+	\ keepend
+
+syn match valgrindPid0 "\d\+0=" contained
+syn match valgrindPid1 "\d\+1=" contained
+syn match valgrindPid2 "\d\+2=" contained
+syn match valgrindPid3 "\d\+3=" contained
+syn match valgrindPid4 "\d\+4=" contained
+syn match valgrindPid5 "\d\+5=" contained
+syn match valgrindPid6 "\d\+6=" contained
+syn match valgrindPid7 "\d\+7=" contained
+syn match valgrindPid8 "\d\+8=" contained
+syn match valgrindPid9 "\d\+9=" contained
+
+syn region valgrindLine
+	\ start=+\(^==\d\+== \)\@<=+
+	\ end=+$+
+	\ keepend
+	\ contained
+	\ contains=valgrindOptions,valgrindMsg,valgrindLoc
+
+syn match valgrindOptions "[ ]\{3}-.*$" contained
+
+syn match valgrindMsg "\S.*$" contained
+	\ contains=valgrindError,valgrindNote,valgrindSummary
+syn match valgrindError "\(Invalid\|\d\+ errors\|.* definitely lost\).*$" contained
+syn match valgrindNote ".*still reachable.*" contained
+syn match valgrindSummary ".*SUMMARY:" contained
+
+syn match valgrindLoc "\s\+\(by\|at\|Address\).*$" contained
+	\ contains=valgrindAt,valgrindAddr,valgrindFunc,valgrindBin,valgrindSrc
+syn match valgrindAt "at\s\@=" contained
+syn match valgrindAddr "\(\W\)\@<=0x\x\+" contained
+syn match valgrindFunc "\(: \)\@<=\w\+" contained
+syn match valgrindBin "\((\(with\|\)in \)\@<=\S\+\()\)\@=" contained
+syn match valgrindSrc "\((\)\@<=.*:\d\+\()\)\@=" contained
+
+" Define the default highlighting
+
+hi def link valgrindSpecLine	Type
+"hi def link valgrindRegion	Special
+
+hi def link valgrindPid0	Special
+hi def link valgrindPid1	Comment
+hi def link valgrindPid2	Type
+hi def link valgrindPid3	Constant
+hi def link valgrindPid4	Number
+hi def link valgrindPid5	Identifier
+hi def link valgrindPid6	Statement
+hi def link valgrindPid7	Error
+hi def link valgrindPid8	LineNr
+hi def link valgrindPid9	Normal
+"hi def link valgrindLine	Special
+
+hi def link valgrindOptions	Type
+"hi def link valgrindMsg	Special
+"hi def link valgrindLoc	Special
+
+hi def link valgrindError	Special
+hi def link valgrindNote	Comment
+hi def link valgrindSummary	Type
+
+hi def link valgrindAt		Special
+hi def link valgrindAddr	Number
+hi def link valgrindFunc	Type
+hi def link valgrindBin		Comment
+hi def link valgrindSrc		Statement
+
+let b:current_syntax = "valgrind"
--- /dev/null
+++ b/lib/vimfiles/syntax/vb.vim
@@ -1,0 +1,378 @@
+" Vim syntax file
+" Language:	Visual Basic
+" Maintainer:	Tim Chase <vb.vim@tim.thechases.com>
+" Former Maintainer:	Robert M. Cortopassi <cortopar@mindspring.com>
+"	(tried multiple times to contact, but email bounced)
+" Last Change:
+"   2005 May 25  Synched with work by Thomas Barthel
+"   2004 May 30  Added a few keywords
+
+" This was thrown together after seeing numerous requests on the
+" VIM and VIM-DEV mailing lists.  It is by no means complete.
+" Send comments, suggestions and requests to the maintainer.
+
+" For version 5.x: Clear all syntax items
+" For version 6.x: Quit when a syntax file was already loaded
+if version < 600
+	syntax clear
+elseif exists("b:current_syntax")
+	finish
+endif
+
+" VB is case insensitive
+syn case ignore
+
+syn keyword vbConditional If Then ElseIf Else Select Case
+
+syn keyword vbOperator AddressOf And ByRef ByVal Eqv Imp In
+syn keyword vbOperator Is Like Mod Not Or To Xor
+
+syn match vbOperator "[()+.,\-/*=&]"
+syn match vbOperator "[<>]=\="
+syn match vbOperator "<>"
+syn match vbOperator "\s\+_$"
+
+syn keyword vbBoolean  True False
+syn keyword vbConst Null Nothing
+
+syn keyword vbRepeat Do For ForEach Loop Next
+syn keyword vbRepeat Step To Until Wend While
+
+syn keyword vbEvents AccessKeyPress Activate ActiveRowChanged
+syn keyword vbEvents AfterAddFile AfterChangeFileName AfterCloseFile
+syn keyword vbEvents AfterColEdit AfterColUpdate AfterDelete
+syn keyword vbEvents AfterInsert AfterLabelEdit AfterRemoveFile
+syn keyword vbEvents AfterUpdate AfterWriteFile AmbientChanged
+syn keyword vbEvents ApplyChanges Associate AsyncProgress
+syn keyword vbEvents AsyncReadComplete AsyncReadProgress AxisActivated
+syn keyword vbEvents AxisLabelActivated AxisLabelSelected
+syn keyword vbEvents AxisLabelUpdated AxisSelected AxisTitleActivated
+syn keyword vbEvents AxisTitleSelected AxisTitleUpdated AxisUpdated
+syn keyword vbEvents BeforeClick BeforeColEdit BeforeColUpdate
+syn keyword vbEvents BeforeConnect BeforeDelete BeforeInsert
+syn keyword vbEvents BeforeLabelEdit BeforeLoadFile BeforeUpdate
+syn keyword vbEvents BeginRequest BeginTrans ButtonClick
+syn keyword vbEvents ButtonCompleted ButtonDropDown ButtonGotFocus
+syn keyword vbEvents ButtonLostFocus CallbackKeyDown Change Changed
+syn keyword vbEvents ChartActivated ChartSelected ChartUpdated Click
+syn keyword vbEvents Close CloseQuery CloseUp ColEdit ColResize
+syn keyword vbEvents Collapse ColumnClick CommitTrans Compare
+syn keyword vbEvents ConfigChageCancelled ConfigChanged
+syn keyword vbEvents ConfigChangedCancelled Connect ConnectionRequest
+syn keyword vbEvents CurrentRecordChanged DECommandAdded
+syn keyword vbEvents DECommandPropertyChanged DECommandRemoved
+syn keyword vbEvents DEConnectionAdded DEConnectionPropertyChanged
+syn keyword vbEvents DEConnectionRemoved DataArrival DataChanged
+syn keyword vbEvents DataUpdated DateClicked DblClick Deactivate
+syn keyword vbEvents DevModeChange DeviceArrival DeviceOtherEvent
+syn keyword vbEvents DeviceQueryRemove DeviceQueryRemoveFailed
+syn keyword vbEvents DeviceRemoveComplete DeviceRemovePending
+syn keyword vbEvents Disconnect DisplayChanged Dissociate
+syn keyword vbEvents DoGetNewFileName Done DonePainting DownClick
+syn keyword vbEvents DragDrop DragOver DropDown EditProperty EditQuery
+syn keyword vbEvents EndRequest EnterCell EnterFocus ExitFocus Expand
+syn keyword vbEvents FontChanged FootnoteActivated FootnoteSelected
+syn keyword vbEvents FootnoteUpdated Format FormatSize GotFocus
+syn keyword vbEvents HeadClick HeightChanged Hide InfoMessage
+syn keyword vbEvents IniProperties InitProperties Initialize
+syn keyword vbEvents ItemActivated ItemAdded ItemCheck ItemClick
+syn keyword vbEvents ItemReloaded ItemRemoved ItemRenamed
+syn keyword vbEvents ItemSeletected KeyDown KeyPress KeyUp LeaveCell
+syn keyword vbEvents LegendActivated LegendSelected LegendUpdated
+syn keyword vbEvents LinkClose LinkError LinkExecute LinkNotify
+syn keyword vbEvents LinkOpen Load LostFocus MouseDown MouseMove
+syn keyword vbEvents MouseUp NodeCheck NodeClick OLECompleteDrag
+syn keyword vbEvents OLEDragDrop OLEDragOver OLEGiveFeedback OLESetData
+syn keyword vbEvents OLEStartDrag ObjectEvent ObjectMove OnAddNew
+syn keyword vbEvents OnComm Paint PanelClick PanelDblClick PathChange
+syn keyword vbEvents PatternChange PlotActivated PlotSelected
+syn keyword vbEvents PlotUpdated PointActivated PointLabelActivated
+syn keyword vbEvents PointLabelSelected PointLabelUpdated PointSelected
+syn keyword vbEvents PointUpdated PowerQuerySuspend PowerResume
+syn keyword vbEvents PowerStatusChanged PowerSuspend ProcessTag
+syn keyword vbEvents ProcessingTimeout QueryChangeConfig QueryClose
+syn keyword vbEvents QueryComplete QueryCompleted QueryTimeout
+syn keyword vbEvents QueryUnload ReadProperties RepeatedControlLoaded
+syn keyword vbEvents RepeatedControlUnloaded Reposition
+syn keyword vbEvents RequestChangeFileName RequestWriteFile Resize
+syn keyword vbEvents ResultsChanged RetainedProject RollbackTrans
+syn keyword vbEvents RowColChange RowCurrencyChange RowResize
+syn keyword vbEvents RowStatusChanged Scroll SelChange SelectionChanged
+syn keyword vbEvents SendComplete SendProgress SeriesActivated
+syn keyword vbEvents SeriesSelected SeriesUpdated SettingChanged Show
+syn keyword vbEvents SplitChange Start StateChanged StatusUpdate
+syn keyword vbEvents SysColorsChanged Terminate TimeChanged Timer
+syn keyword vbEvents TitleActivated TitleSelected TitleUpdated
+syn keyword vbEvents UnboundAddData UnboundDeleteRow
+syn keyword vbEvents UnboundGetRelativeBookmark UnboundReadData
+syn keyword vbEvents UnboundWriteData Unformat Unload UpClick Updated
+syn keyword vbEvents UserEvent Validate ValidationError
+syn keyword vbEvents VisibleRecordChanged WillAssociate WillChangeData
+syn keyword vbEvents WillDissociate WillExecute WillUpdateRows
+syn keyword vbEvents WriteProperties
+
+
+syn keyword vbFunction Abs Array Asc AscB AscW Atn Avg BOF CBool CByte
+syn keyword vbFunction CCur CDate CDbl CInt CLng CSng CStr CVDate CVErr
+syn keyword vbFunction CVar CallByName Cdec Choose Chr ChrB ChrW Command
+syn keyword vbFunction Cos Count CreateObject CurDir DDB Date DateAdd
+syn keyword vbFunction DateDiff DatePart DateSerial DateValue Day Dir
+syn keyword vbFunction DoEvents EOF Environ Error Exp FV FileAttr
+syn keyword vbFunction FileDateTime FileLen FilterFix Fix Format
+syn keyword vbFunction FormatCurrency FormatDateTime FormatNumber
+syn keyword vbFunction FormatPercent FreeFile GetAllStrings GetAttr
+syn keyword vbFunction GetAutoServerSettings GetObject GetSetting Hex
+syn keyword vbFunction Hour IIf IMEStatus IPmt InStr Input InputB
+syn keyword vbFunction InputBox InstrB Int IsArray IsDate IsEmpty IsError
+syn keyword vbFunction IsMissing IsNull IsNumeric IsObject Join LBound
+syn keyword vbFunction LCase LOF LTrim Left LeftB Len LenB LoadPicture
+syn keyword vbFunction LoadResData LoadResPicture LoadResString Loc Log
+syn keyword vbFunction MIRR Max Mid MidB Min Minute Month MonthName
+syn keyword vbFunction MsgBox NPV NPer Now Oct PPmt PV Partition Pmt
+syn keyword vbFunction QBColor RGB RTrim Rate Replace Right RightB Rnd
+syn keyword vbFunction Round SLN SYD Second Seek Sgn Shell Sin Space Spc
+syn keyword vbFunction Split Sqr StDev StDevP Str StrComp StrConv
+syn keyword vbFunction StrReverse String Sum Switch Tab Tan Time
+syn keyword vbFunction TimeSerial TimeValue Timer Trim TypeName UBound
+syn keyword vbFunction UCase Val Var VarP VarType Weekday WeekdayName
+syn keyword vbFunction Year
+
+syn keyword vbMethods AboutBox Accept Activate Add AddCustom AddFile
+syn keyword vbMethods AddFromFile AddFromGuid AddFromString
+syn keyword vbMethods AddFromTemplate AddItem AddNew AddToAddInToolbar
+syn keyword vbMethods AddToolboxProgID Append AppendAppendChunk
+syn keyword vbMethods AppendChunk Arrange Assert AsyncRead BatchUpdate
+syn keyword vbMethods BeginQueryEdit BeginTrans Bind BuildPath
+syn keyword vbMethods CanPropertyChange Cancel CancelAsyncRead
+syn keyword vbMethods CancelBatch CancelUpdate CaptureImage CellText
+syn keyword vbMethods CellValue Circle Clear ClearFields ClearSel
+syn keyword vbMethods ClearSelCols ClearStructure Clone Close Cls
+syn keyword vbMethods ColContaining CollapseAll ColumnSize CommitTrans
+syn keyword vbMethods CompactDatabase Compose Connect Copy CopyFile
+syn keyword vbMethods CopyFolder CopyQueryDef Count CreateDatabase
+syn keyword vbMethods CreateDragImage CreateEmbed CreateField
+syn keyword vbMethods CreateFolder CreateGroup CreateIndex CreateLink
+syn keyword vbMethods CreatePreparedStatement CreatePropery CreateQuery
+syn keyword vbMethods CreateQueryDef CreateRelation CreateTableDef
+syn keyword vbMethods CreateTextFile CreateToolWindow CreateUser
+syn keyword vbMethods CreateWorkspace Customize Cut Delete
+syn keyword vbMethods DeleteColumnLabels DeleteColumns DeleteFile
+syn keyword vbMethods DeleteFolder DeleteLines DeleteRowLabels
+syn keyword vbMethods DeleteRows DeselectAll DesignerWindow DoVerb Drag
+syn keyword vbMethods Draw DriveExists Edit EditCopy EditPaste EndDoc
+syn keyword vbMethods EnsureVisible EstablishConnection Execute Exists
+syn keyword vbMethods Expand Export ExportReport ExtractIcon Fetch
+syn keyword vbMethods FetchVerbs FileExists Files FillCache Find
+syn keyword vbMethods FindFirst FindItem FindLast FindNext FindPrevious
+syn keyword vbMethods FolderExists Forward GetAbsolutePathName
+syn keyword vbMethods GetBaseName GetBookmark GetChunk GetClipString
+syn keyword vbMethods GetData GetDrive GetDriveName GetFile GetFileName
+syn keyword vbMethods GetFirstVisible GetFolder GetFormat GetHeader
+syn keyword vbMethods GetLineFromChar GetNumTicks GetParentFolderName
+syn keyword vbMethods GetRows GetSelectedPart GetSelection
+syn keyword vbMethods GetSpecialFolder GetTempName GetText
+syn keyword vbMethods GetVisibleCount GoBack GoForward Hide HitTest
+syn keyword vbMethods HoldFields Idle Import InitializeLabels Insert
+syn keyword vbMethods InsertColumnLabels InsertColumns InsertFile
+syn keyword vbMethods InsertLines InsertObjDlg InsertRowLabels
+syn keyword vbMethods InsertRows Item Keys KillDoc Layout Line Lines
+syn keyword vbMethods LinkExecute LinkPoke LinkRequest LinkSend Listen
+syn keyword vbMethods LoadFile LoadResData LoadResPicture LoadResString
+syn keyword vbMethods LogEvent MakeCompileFile MakeCompiledFile
+syn keyword vbMethods MakeReplica MoreResults Move MoveData MoveFile
+syn keyword vbMethods MoveFirst MoveFolder MoveLast MoveNext
+syn keyword vbMethods MovePrevious NavigateTo NewPage NewPassword
+syn keyword vbMethods NextRecordset OLEDrag OnAddinsUpdate OnConnection
+syn keyword vbMethods OnDisconnection OnStartupComplete Open
+syn keyword vbMethods OpenAsTextStream OpenConnection OpenDatabase
+syn keyword vbMethods OpenQueryDef OpenRecordset OpenResultset OpenURL
+syn keyword vbMethods Overlay PSet PaintPicture PastSpecialDlg Paste
+syn keyword vbMethods PeekData Play Point PopulatePartial PopupMenu
+syn keyword vbMethods Print PrintForm PrintReport PropertyChanged Quit
+syn keyword vbMethods Raise RandomDataFill RandomFillColumns
+syn keyword vbMethods RandomFillRows ReFill Read ReadAll ReadFromFile
+syn keyword vbMethods ReadLine ReadProperty Rebind Refresh RefreshLink
+syn keyword vbMethods RegisterDatabase ReleaseInstance Reload Remove
+syn keyword vbMethods RemoveAddInFromToolbar RemoveAll RemoveItem Render
+syn keyword vbMethods RepairDatabase ReplaceLine Reply ReplyAll Requery
+syn keyword vbMethods ResetCustom ResetCustomLabel ResolveName
+syn keyword vbMethods RestoreToolbar Resync Rollback RollbackTrans
+syn keyword vbMethods RowBookmark RowContaining RowTop Save SaveAs
+syn keyword vbMethods SaveFile SaveToFile SaveToOle1File SaveToolbar
+syn keyword vbMethods Scale ScaleX ScaleY Scroll SelPrint SelectAll
+syn keyword vbMethods SelectPart Send SendData Set SetAutoServerSettings
+syn keyword vbMethods SetData SetFocus SetOption SetSelection SetSize
+syn keyword vbMethods SetText SetViewport Show ShowColor ShowFont
+syn keyword vbMethods ShowHelp ShowOpen ShowPrinter ShowSave
+syn keyword vbMethods ShowWhatsThis SignOff SignOn Size Skip SkipLine
+syn keyword vbMethods Span Split SplitContaining StartLabelEdit
+syn keyword vbMethods StartLogging Stop Synchronize Tag TextHeight
+syn keyword vbMethods TextWidth ToDefaults Trace TwipsToChartPart
+syn keyword vbMethods TypeByChartType URLFor Update UpdateControls
+syn keyword vbMethods UpdateRecord UpdateRow Upto ValidateControls Value
+syn keyword vbMethods WhatsThisMode Write WriteBlankLines WriteLine
+syn keyword vbMethods WriteProperty WriteTemplate ZOrder
+syn keyword vbMethods rdoCreateEnvironment rdoRegisterDataSource
+
+syn keyword vbStatement Alias AppActivate As Base Beep Begin Call ChDir
+syn keyword vbStatement ChDrive Close Const Date Declare DefBool DefByte
+syn keyword vbStatement DefCur DefDate DefDbl DefDec DefInt DefLng DefObj
+syn keyword vbStatement DefSng DefStr DefVar Deftype DeleteSetting Dim Do
+syn keyword vbStatement Each ElseIf End Enum Erase Error Event Exit
+syn keyword vbStatement Explicit FileCopy For ForEach Function Get GoSub
+syn keyword vbStatement GoTo Gosub Implements Kill LSet Let Lib LineInput
+syn keyword vbStatement Load Lock Loop Mid MkDir Name Next On OnError Open
+syn keyword vbStatement Option Preserve Private Property Public Put RSet
+syn keyword vbStatement RaiseEvent Randomize ReDim Redim Rem Reset Resume
+syn keyword vbStatement Return RmDir SavePicture SaveSetting Seek SendKeys
+syn keyword vbStatement Sendkeys Set SetAttr Static Step Stop Sub Time
+syn keyword vbStatement Type Unload Unlock Until Wend While Width With
+syn keyword vbStatement Write
+
+syn keyword vbKeyword As Binary ByRef ByVal Date Empty Error Friend Get
+syn keyword vbKeyword Input Is Len Lock Me Mid New Nothing Null On
+syn keyword vbKeyword Option Optional ParamArray Print Private Property
+syn keyword vbKeyword Public PublicNotCreateable OnNewProcessSingleUse
+syn keyword vbKeyword InSameProcessMultiUse GlobalMultiUse Resume Seek
+syn keyword vbKeyword Set Static Step String Time WithEvents
+
+syn keyword vbTodo contained	TODO
+
+"Datatypes
+syn keyword vbTypes Boolean Byte Currency Date Decimal Double Empty
+syn keyword vbTypes Integer Long Object Single String Variant
+
+"VB defined values
+syn keyword vbDefine dbBigInt dbBinary dbBoolean dbByte dbChar
+syn keyword vbDefine dbCurrency dbDate dbDecimal dbDouble dbFloat
+syn keyword vbDefine dbGUID dbInteger dbLong dbLongBinary dbMemo
+syn keyword vbDefine dbNumeric dbSingle dbText dbTime dbTimeStamp
+syn keyword vbDefine dbVarBinary
+
+"VB defined values
+syn keyword vbDefine vb3DDKShadow vb3DFace vb3DHighlight vb3DLight
+syn keyword vbDefine vb3DShadow vbAbort vbAbortRetryIgnore
+syn keyword vbDefine vbActiveBorder vbActiveTitleBar vbAlias
+syn keyword vbDefine vbApplicationModal vbApplicationWorkspace
+syn keyword vbDefine vbAppTaskManager vbAppWindows vbArchive vbArray
+syn keyword vbDefine vbBack vbBinaryCompare vbBlack vbBlue vbBoolean
+syn keyword vbDefine vbButtonFace vbButtonShadow vbButtonText vbByte
+syn keyword vbDefine vbCalGreg vbCalHijri vbCancel vbCr vbCritical
+syn keyword vbDefine vbCrLf vbCurrency vbCyan vbDatabaseCompare
+syn keyword vbDefine vbDataObject vbDate vbDecimal vbDefaultButton1
+syn keyword vbDefine vbDefaultButton2 vbDefaultButton3 vbDefaultButton4
+syn keyword vbDefine vbDesktop vbDirectory vbDouble vbEmpty vbError
+syn keyword vbDefine vbExclamation vbFirstFourDays vbFirstFullWeek
+syn keyword vbDefine vbFirstJan1 vbFormCode vbFormControlMenu
+syn keyword vbDefine vbFormFeed vbFormMDIForm vbFriday vbFromUnicode
+syn keyword vbDefine vbGrayText vbGreen vbHidden vbHide vbHighlight
+syn keyword vbDefine vbHighlightText vbHiragana vbIgnore vbIMEAlphaDbl
+syn keyword vbDefine vbIMEAlphaSng vbIMEDisable vbIMEHiragana
+syn keyword vbDefine vbIMEKatakanaDbl vbIMEKatakanaSng vbIMEModeAlpha
+syn keyword vbDefine vbIMEModeAlphaFull vbIMEModeDisable
+syn keyword vbDefine vbIMEModeHangul vbIMEModeHangulFull
+syn keyword vbDefine vbIMEModeHiragana vbIMEModeKatakana
+syn keyword vbDefine vbIMEModeKatakanaHalf vbIMEModeNoControl
+syn keyword vbDefine vbIMEModeOff vbIMEModeOn vbIMENoOp vbIMEOff
+syn keyword vbDefine vbIMEOn vbInactiveBorder vbInactiveCaptionText
+syn keyword vbDefine vbInactiveTitleBar vbInfoBackground vbInformation
+syn keyword vbDefine vbInfoText vbInteger vbKatakana vbKey0 vbKey1
+syn keyword vbDefine vbKey2 vbKey3 vbKey4 vbKey5 vbKey6 vbKey7 vbKey8
+syn keyword vbDefine vbKey9 vbKeyA vbKeyAdd vbKeyB vbKeyBack vbKeyC
+syn keyword vbDefine vbKeyCancel vbKeyCapital vbKeyClear vbKeyControl
+syn keyword vbDefine vbKeyD vbKeyDecimal vbKeyDelete vbKeyDivide
+syn keyword vbDefine vbKeyDown vbKeyE vbKeyEnd vbKeyEscape vbKeyExecute
+syn keyword vbDefine vbKeyF vbKeyF1 vbKeyF10 vbKeyF11 vbKeyF12 vbKeyF13
+syn keyword vbDefine vbKeyF14 vbKeyF15 vbKeyF16 vbKeyF2 vbKeyF3 vbKeyF4
+syn keyword vbDefine vbKeyF5 vbKeyF6 vbKeyF7 vbKeyF8 vbKeyF9 vbKeyG
+syn keyword vbDefine vbKeyH vbKeyHelp vbKeyHome vbKeyI vbKeyInsert
+syn keyword vbDefine vbKeyJ vbKeyK vbKeyL vbKeyLButton vbKeyLeft vbKeyM
+syn keyword vbDefine vbKeyMButton vbKeyMenu vbKeyMultiply vbKeyN
+syn keyword vbDefine vbKeyNumlock vbKeyNumpad0 vbKeyNumpad1
+syn keyword vbDefine vbKeyNumpad2 vbKeyNumpad3 vbKeyNumpad4
+syn keyword vbDefine vbKeyNumpad5 vbKeyNumpad6 vbKeyNumpad7
+syn keyword vbDefine vbKeyNumpad8 vbKeyNumpad9 vbKeyO vbKeyP
+syn keyword vbDefine vbKeyPageDown vbKeyPageUp vbKeyPause vbKeyPrint
+syn keyword vbDefine vbKeyQ vbKeyR vbKeyRButton vbKeyReturn vbKeyRight
+syn keyword vbDefine vbKeyS vbKeySelect vbKeySeparator vbKeyShift
+syn keyword vbDefine vbKeySnapshot vbKeySpace vbKeySubtract vbKeyT
+syn keyword vbDefine vbKeyTab vbKeyU vbKeyUp vbKeyV vbKeyW vbKeyX
+syn keyword vbDefine vbKeyY vbKeyZ vbLf vbLong vbLowerCase vbMagenta
+syn keyword vbDefine vbMaximizedFocus vbMenuBar vbMenuText
+syn keyword vbDefine vbMinimizedFocus vbMinimizedNoFocus vbMonday
+syn keyword vbDefine vbMsgBox vbMsgBoxHelpButton vbMsgBoxRight
+syn keyword vbDefine vbMsgBoxRtlReading vbMsgBoxSetForeground
+syn keyword vbDefine vbMsgBoxText vbNarrow vbNewLine vbNo vbNormal
+syn keyword vbDefine vbNormalFocus vbNormalNoFocus vbNull vbNullChar
+syn keyword vbDefine vbNullString vbObject vbObjectError vbOK
+syn keyword vbDefine vbOKCancel vbOKOnly vbProperCase vbQuestion
+syn keyword vbDefine vbReadOnly vbRed vbRetry vbRetryCancel vbSaturday
+syn keyword vbDefine vbScrollBars vbSingle vbString vbSunday vbSystem
+syn keyword vbDefine vbSystemModal vbTab vbTextCompare vbThursday
+syn keyword vbDefine vbTitleBarText vbTuesday vbUnicode vbUpperCase
+syn keyword vbDefine vbUseSystem vbUseSystemDayOfWeek vbVariant
+syn keyword vbDefine vbVerticalTab vbVolume vbWednesday vbWhite vbWide
+syn keyword vbDefine vbWindowBackground vbWindowFrame vbWindowText
+syn keyword vbDefine vbYellow vbYes vbYesNo vbYesNoCancel
+
+"Numbers
+"integer number, or floating point number without a dot.
+syn match vbNumber "\<\d\+\>"
+"floating point number, with dot
+syn match vbNumber "\<\d\+\.\d*\>"
+"floating point number, starting with a dot
+syn match vbNumber "\.\d\+\>"
+"syn match  vbNumber		"{[[:xdigit:]-]\+}\|&[hH][[:xdigit:]]\+&"
+"syn match  vbNumber		":[[:xdigit:]]\+"
+"syn match  vbNumber		"[-+]\=\<\d\+\>"
+syn match  vbFloat		"[-+]\=\<\d\+[eE][\-+]\=\d\+"
+syn match  vbFloat		"[-+]\=\<\d\+\.\d*\([eE][\-+]\=\d\+\)\="
+syn match  vbFloat		"[-+]\=\<\.\d\+\([eE][\-+]\=\d\+\)\="
+
+" String and Character contstants
+syn region  vbString		start=+"+  end=+"\|$+
+syn region  vbComment		start="\(^\|\s\)REM\s" end="$" contains=vbTodo
+syn region  vbComment		start="\(^\|\s\)\'"   end="$" contains=vbTodo
+syn match   vbLineNumber	"^\d\+\(\s\|$\)"
+syn match   vbTypeSpecifier  "[a-zA-Z0-9][\$%&!#]"ms=s+1
+syn match   vbTypeSpecifier  "#[a-zA-Z0-9]"me=e-1
+
+" Define the default highlighting.
+" For version 5.7 and earlier: only when not done already
+" For version 5.8 and later: only when an item doesn't have highlighting yet
+if version >= 508 || !exists("did_vb_syntax_inits")
+	if version < 508
+		let did_vb_syntax_inits = 1
+		command -nargs=+ HiLink hi link <args>
+	else
+		command -nargs=+ HiLink hi def link <args>
+	endif
+
+	HiLink vbBoolean		Boolean
+	HiLink vbLineNumber		Comment
+	HiLink vbComment		Comment
+	HiLink vbConditional	Conditional
+	HiLink vbConst			Constant
+	HiLink vbDefine			Constant
+	HiLink vbError			Error
+	HiLink vbFunction		Identifier
+	HiLink vbIdentifier		Identifier
+	HiLink vbNumber			Number
+	HiLink vbFloat			Float
+	HiLink vbMethods		PreProc
+	HiLink vbOperator		Operator
+	HiLink vbRepeat			Repeat
+	HiLink vbString			String
+	HiLink vbStatement		Statement
+	HiLink vbKeyword		Statement
+	HiLink vbEvents			Special
+	HiLink vbTodo			Todo
+	HiLink vbTypes			Type
+	HiLink vbTypeSpecifier	Type
+
+	delcommand HiLink
+endif
+
+let b:current_syntax = "vb"
+
+" vim: ts=8
--- /dev/null
+++ b/lib/vimfiles/syntax/vera.vim
@@ -1,0 +1,361 @@
+" Vim syntax file
+" Language:	Vera
+" Maintainer:	Dave Eggum (opine at bluebottle dOt com)
+" Last Change:	2005 Dec 19
+
+" NOTE: extra white space at the end of the line will be highlighted if you
+" add this line to your colorscheme:
+
+" highlight SpaceError    guibg=#204050
+
+" (change the value for guibg to any color you like)
+
+" For version 5.x: Clear all syntax items
+" For version 6.x: Quit when a syntax file was already loaded
+if version < 600
+  syntax clear
+elseif exists("b:current_syntax")
+  finish
+endif
+
+" A bunch of useful Vera keywords
+syn keyword	veraStatement	break return continue fork join terminate
+syn keyword	veraStatement	breakpoint proceed
+
+syn keyword	veraLabel	bad_state bad_trans bind constraint coverage_group
+syn keyword	veraLabel	class CLOCK default function interface m_bad_state
+syn keyword	veraLabel	m_bad_trans m_state m_trans program randseq state
+syn keyword	veraLabel	task trans
+
+syn keyword	veraConditional	if else case casex casez randcase
+syn keyword 	veraRepeat      repeat while for do foreach
+syn keyword 	veraModifier	after all any around assoc_size async
+syn keyword 	veraModifier	before big_endian bit_normal bit_reverse export
+syn keyword 	veraModifier	extends extern little_endian local hdl_node hdl_task
+syn keyword 	veraModifier	negedge none packed protected posedge public rules
+syn keyword 	veraModifier	shadow soft static super this typedef unpacked var
+syn keyword 	veraModifier	vca virtual virtuals wildcard with
+
+syn keyword 	veraType	reg string enum event bit
+syn keyword 	veraType	rand randc integer port prod
+
+syn keyword     veraDeprecated	call_func call_task close_conn get_bind get_bind_id
+syn keyword     veraDeprecated	get_conn_err mailbox_receive mailbox_send make_client
+syn keyword     veraDeprecated	make_server simwave_plot up_connections
+
+" predefined tasks and functions
+syn keyword 	veraTask	alloc assoc_index cast_assign cm_coverage
+syn keyword 	veraTask	cm_get_coverage cm_get_limit delay error error_mode
+syn keyword 	veraTask	exit fclose feof ferror fflush flag fopen fprintf
+syn keyword 	veraTask	freadb freadh freadstr get_cycle get_env get_memsize
+syn keyword 	veraTask	get_plus_arg getstate get_systime get_time get_time_unit
+syn keyword 	veraTask	initstate lock_file mailbox_get mailbox_put os_command
+syn keyword 	veraTask	printf prodget prodset psprintf query query_str query_x
+syn keyword 	veraTask	rand48 random region_enter region_exit rewind
+syn keyword 	veraTask	semaphore_get semaphore_put setstate signal_connect
+syn keyword 	veraTask	sprintf srandom sscanf stop suspend_thread sync
+syn keyword 	veraTask	timeout trace trigger unit_delay unlock_file urand48
+syn keyword 	veraTask	urandom urandom_range vera_bit_reverse vera_crc
+syn keyword 	veraTask	vera_pack vera_pack_big_endian vera_plot
+syn keyword 	veraTask	vera_report_profile vera_unpack vera_unpack_big_endian
+syn keyword 	veraTask	vsv_call_func vsv_call_task vsv_get_conn_err
+syn keyword 	veraTask	vsv_make_client vsv_make_server vsv_up_connections
+syn keyword 	veraTask	vsv_wait_for_done vsv_wait_for_input wait_child wait_var
+
+syn cluster	veraOperGroup	contains=veraOperator,veraOperParen,veraNumber,veraString,veraOperOk,veraType
+" syn match	veraOperator	"++\|--\|&\|\~&\||\|\~|\|^\|\~^\|\~\|><"
+" syn match	veraOperator	"*\|/\|%\|+\|-\|<<\|>>\|<\|<=\|>\|>=\|!in"
+" syn match	veraOperator	"=?=\|!?=\|==\|!=\|===\|!==\|&\~\|^\~\||\~"
+" syn match	veraOperator	"&&\|||\|=\|+=\|-=\|*=\|/=\|%=\|<<=\|>>=\|&="
+" syn match	veraOperator	"|=\|^=\|\~&=\|\~|=\|\~^="
+
+syn match	veraOperator	"[&|\~><!*@+/=,.\^\-]"
+syn keyword	veraOperator	or in dist not
+
+" open vera class methods
+syn keyword	veraMethods	atobin atohex atoi atooct backref bittostr capacity
+syn keyword	veraMethods	compare Configure constraint_mode delete DisableTrigger
+syn keyword	veraMethods	DoAction empty EnableCount EnableTrigger Event find
+syn keyword	veraMethods	find_index first first_index GetAssert get_at_least
+syn keyword	veraMethods	get_auto_bin getc GetCount get_coverage_goal get_cov_weight
+syn keyword	veraMethods	get_cross_bin_max GetFirstAssert GetName GetNextAssert
+syn keyword	veraMethods	get_status get_status_msg hide hash icompare insert
+syn keyword	veraMethods	inst_get_at_least inst_get_auto_bin_max inst_get_collect
+syn keyword	veraMethods	inst_get_coverage_goal inst_get_cov_weight inst_getcross_bin_max
+syn keyword	veraMethods	inst_query inst_set_at_least inst_set_auto_bin_max
+syn keyword	veraMethods	inst_set_bin_activiation inst_set_collect inst_set_coverage_goal
+syn keyword	veraMethods	inst_set_cov_weight inst_set_cross_bin_max itoa last last_index
+syn keyword	veraMethods	len load match max max_index min min_index new object_compare
+syn keyword	veraMethods	object_compare object_copy object_print pack pick_index
+syn keyword	veraMethods	pop_back pop_front post_boundary postmatch post_pack post_pack
+syn keyword	veraMethods	post_randomize post_randomize post_unpack post_unpack
+syn keyword	veraMethods	pre_boundary prematch pre_pack pre_pack pre_randomize
+syn keyword	veraMethods	pre-randomize pre_unpack push_back push_front putc query
+syn keyword	veraMethods	query_str rand_mode randomize reserve reverse rsort search
+syn keyword	veraMethods	set_at_least set_auto_bin_max set_bin_activiation
+syn keyword	veraMethods	set_coverage_goal set_cov_weight set_cross_bin_max set_name
+syn keyword	veraMethods	size sort substr sum thismatch tolower toupper unique_index
+syn keyword	veraMethods	unpack Wait
+
+" interface keywords
+syn keyword	veraInterface	ASYNC CLOCK gnr gr0 gr1 grx grz NHOLD nr NR0 NR1
+syn keyword	veraInterface	NRZ NRZ NSAMPLE PHOLD PR0 PR1 PRX PRZ r0 r1 rx snr
+syn keyword	veraInterface	sr0 sr1 srx srz depth inout input output
+syn match       veraInterface   "\$\w\+"
+
+
+syn keyword	veraTodo	contained TODO FIXME XXX FINISH
+
+" veraCommentGroup allows adding matches for special things in comments
+syn cluster	veraCommentGroup	contains=veraTodo
+
+" String and Character constants
+" Highlight special characters (those which have a backslash) differently
+syn match	veraSpecial	display contained "\\\(x\x\+\|\o\{1,3}\|.\|$\)"
+syn match	veraFormat	display "%\(\d\+\$\)\=[-+' #0*]*\(\d*\|\*\|\*\d\+\$\)\(\.\(\d*\|\*\|\*\d\+\$\)\)\=\([hlL]\|ll\)\=\([bdiuoxXDOUfeEgGcCsSpnm]\|\[\^\=.[^]]*\]\)" contained
+syn match	veraFormat	display "%%" contained
+syn region	veraString	start=+"+ skip=+\\\\\|\\"+ end=+"+ contains=veraSpecial,veraFormat,@Spell
+syn region	veraConcat	contained transparent oneline start='{' end='}'
+
+" veraCppString: same as veraString, but ends at end of line
+syn region	veraCppString	start=+"+ skip=+\\\\\|\\"\|\\$+ excludenl end=+"+ end='$' contains=veraSpecial,veraFormat,@Spell
+
+syn match	veraCharacter	"'[^\\]'"
+syn match	veraCharacter	"L'[^']*'" contains=veraSpecial
+syn match	veraSpecialError	"'\\[^'\"?\\abefnrtv]'"
+syn match	veraSpecialCharacter	"'\\['\"?\\abefnrtv]'"
+syn match	veraSpecialCharacter	display	"'\\\o\{1,3}'"
+syn match	veraSpecialCharacter	display	"'\\x\x\{1,2}'"
+syn match	veraSpecialCharacter	display	"L'\\x\x\+'"
+
+" highlight trailing white space
+syn match	veraSpaceError	display	excludenl "\s\+$"
+syn match	veraSpaceError	display	" \+\t"me=e-1
+
+"catch errors caused by wrong parenthesis and brackets
+syn cluster	veraParenGroup	contains=veraParenError,veraIncluded,veraSpecial,veraCommentSkip,veraCommentString,veraComment2String,@veraCommentGroup,veraCommentStartError,veraUserCont,veraUserLabel,veraBitField,veraCommentSkip,veraOctalZero,veraCppOut,veraCppOut2,veraCppSkip,veraFormat,veraNumber,veraFloat,veraOctal,veraOctalError,veraNumbersCom
+
+syn region	veraParen	transparent start='(' end=')' contains=ALLBUT,@veraParenGroup,veraCppParen,veraErrInBracket,veraCppBracket,veraCppString,@Spell
+" veraCppParen: same as veraParen but ends at end-of-line; used in veraDefine
+syn region	veraCppParen	transparent start='(' skip='\\$' excludenl end=')' end='$' contained contains=ALLBUT,@veraParenGroup,veraErrInBracket,veraParen,veraBracket,veraString,@Spell
+syn match	veraParenError	display "[\])]"
+" syn match	veraErrInParen	display contained "[\]{}]"
+syn match	veraErrInParen	display contained "[\]]"
+syn region	veraBracket	transparent start='\[' end=']' contains=ALLBUT,@veraParenGroup,veraErrInParen,veraCppParen,veraCppBracket,veraCppString,@Spell
+
+" veraCppBracket: same as veraParen but ends at end-of-line; used in veraDefine
+syn region	veraCppBracket	transparent start='\[' skip='\\$' excludenl end=']' end='$' contained contains=ALLBUT,@veraParenGroup,veraErrInParen,veraParen,veraBracket,veraString,@Spell
+syn match	veraErrInBracket	display contained "[);{}]"
+
+"integer number, or floating point number without a dot and with "f".
+syn case ignore
+syn match	veraNumbers	display transparent "\<\d\|\.\d" contains=veraNumber,veraFloat,veraOctalError,veraOctal
+" Same, but without octal error (for comments)
+syn match	veraNumbersCom	display contained transparent "\<\d\|\.\d" contains=veraNumber,veraFloat,veraOctal
+" syn match	veraNumber	display contained "\d\+\(u\=l\{0,2}\|ll\=u\)\>"
+" "hex number
+" syn match	veraNumber	display contained "0x\x\+\(u\=l\{0,2}\|ll\=u\)\>"
+" syn match   veraNumber "\(\<[0-9]\+\|\)'[bdoh][0-9a-fxzA-FXZ_]\+\>"
+syn match	veraNumber "\<\(\<[0-9]\+\)\?\('[bdoh]\)\?[0-9a-fxz_]\+\>"
+" syn match   veraNumber "\<[+-]\=[0-9]\+\>"
+" Flag the first zero of an octal number as something special
+syn match	veraOctal	display contained "0\o\+\(u\=l\{0,2}\|ll\=u\)\>" contains=veraOctalZero
+syn match	veraOctalZero	display contained "\<0"
+syn match	veraFloat	display contained "\d\+f"
+"floating point number, with dot, optional exponent
+syn match	veraFloat	display contained "\d\+\.\d*\(e[-+]\=\d\+\)\=[fl]\="
+"floating point number, starting with a dot, optional exponent
+syn match	veraFloat	display contained "\.\d\+\(e[-+]\=\d\+\)\=[fl]\=\>"
+"floating point number, without dot, with exponent
+syn match	veraFloat	display contained "\d\+e[-+]\=\d\+[fl]\=\>"
+"hexadecimal floating point number, optional leading digits, with dot, with exponent
+syn match	veraFloat	display contained "0x\x*\.\x\+p[-+]\=\d\+[fl]\=\>"
+"hexadecimal floating point number, with leading digits, optional dot, with exponent
+syn match	veraFloat	display contained "0x\x\+\.\=p[-+]\=\d\+[fl]\=\>"
+
+" flag an octal number with wrong digits
+syn match	veraOctalError	display contained "0\o*[89]\d*"
+syn case match
+
+let vera_comment_strings = 1
+
+if exists("vera_comment_strings")
+  " A comment can contain veraString, veraCharacter and veraNumber.
+  " But a "*/" inside a veraString in a veraComment DOES end the comment!  So we
+  " need to use a special type of veraString: veraCommentString, which also ends on
+  " "*/", and sees a "*" at the start of the line as comment again.
+  " Unfortunately this doesn't work very well for // type of comments :-(
+  syntax match	veraCommentSkip	contained "^\s*\*\($\|\s\+\)"
+  syntax region veraCommentString	contained start=+L\=\\\@<!"+ skip=+\\\\\|\\"+ end=+"+ end=+\*/+me=s-1 contains=veraSpecial,veraCommentSkip
+  syntax region veraComment2String	contained start=+\\\@<!"+ skip=+\\\\\|\\"+ end=+"+ end="$" contains=veraSpecial
+  syntax region  veraCommentL	start="//" skip="\\$" end="$" keepend contains=@veraCommentGroup,veraComment2String,veraCharacter,veraNumbersCom,veraSpaceError,@Spell
+  if exists("vera_no_comment_fold")
+    syntax region veraComment	matchgroup=veraCommentStart start="/\*" end="\*/" contains=@veraCommentGroup,veraCommentStartError,veraCommentString,veraCharacter,veraNumbersCom,veraSpaceError,@Spell
+  else
+    syntax region veraComment	matchgroup=veraCommentStart start="/\*" end="\*/" contains=@veraCommentGroup,veraCommentStartError,veraCommentString,veraCharacter,veraNumbersCom,veraSpaceError,@Spell fold
+  endif
+else
+  syn region	veraCommentL	start="//" skip="\\$" end="$" keepend contains=@veraCommentGroup,veraSpaceError,@Spell
+  if exists("vera_no_comment_fold")
+    syn region	veraComment	matchgroup=veraCommentStart start="/\*" end="\*/" contains=@veraCommentGroup,veraCommentStartError,veraSpaceError,@Spell
+  else
+    syn region	veraComment	matchgroup=veraCommentStart start="/\*" end="\*/" contains=@veraCommentGroup,veraCommentStartError,veraSpaceError,@Spell fold
+  endif
+endif
+" keep a // comment separately, it terminates a preproc. conditional
+syntax match	veraCommentError	display "\*/"
+syntax match	veraCommentStartError display "/\*"me=e-1 contained
+
+syntax region	veraBlock		start="{" end="}" transparent fold
+
+" open vera pre-defined constants
+syn keyword veraConstant	ALL ANY BAD_STATE BAD_TRANS CALL CHECK CHGEDGE
+syn keyword veraConstant	CLEAR COPY_NO_WAIT COPY_WAIT CROSS CROSS_TRANS
+syn keyword veraConstant	DEBUG DELETE EC_ARRAYX EC_CODE_END EC_CONFLICT
+syn keyword veraConstant	EC_EVNTIMOUT EC_EXPECT EC_FULLEXPECT EC_MBXTMOUT
+syn keyword veraConstant	EC_NEXPECT EC_RETURN EC_RGNTMOUT EC_SCONFLICT
+syn keyword veraConstant	EC_SEMTMOUT EC_SEXPECT EC_SFULLEXPECT EC_SNEXTPECT
+syn keyword veraConstant	EC_USERSET EQ EVENT FAIL FIRST FORK GE GOAL GT
+syn keyword veraConstant	HAND_SHAKE HI HIGH HNUM LE LIC_EXIT LIC_PRERR
+syn keyword veraConstant	LIC_PRWARN LIC_WAIT LO LOAD LOW LT MAILBOX MAX_COM
+syn keyword veraConstant	NAME NE NEGEDGE NEXT NO_OVERLAP NO_OVERLAP_STATE
+syn keyword veraConstant	NO_OVERLAP_TRANS NO_VARS NO_WAIT NUM NUM_BIN
+syn keyword veraConstant	NUM_DET null OFF OK OK_LAST ON ONE_BLAST ONE_SHOT ORDER
+syn keyword veraConstant	PAST_IT PERCENT POSEDGE PROGRAM RAWIN REGION REPORT
+syn keyword veraConstant	SAMPLE SAVE SEMAPHORE SET SILENT STATE stderr
+syn keyword veraConstant	stdin stdout STR STR_ERR_OUT_OF_RANGE
+syn keyword veraConstant	STR_ERR_REGEXP_SYNTAX SUM TRANS VERBOSE void WAIT
+syn keyword veraConstant	__LINE__ __FILE__ __DATE__ __TIME__ __VERA__
+syn keyword veraConstant	__VERSION__ __VERA_VERSION__ __VERA_MINOR__
+syn keyword veraConstant	__VERA_PATCH__ __VERA_VMC__ __VERA_VMC_MINOR__
+
+syn match   veraUserConstant "\<[A-Z][A-Z0-9_]\+\>"
+
+syn match veraClass "\zs\w\+\ze::"
+syn match veraClass "\zs\w\+\ze\s\+\w\+\s*[=;,)\[]" contains=veraConstant,veraUserConstant
+syn match veraClass "\zs\w\+\ze\s\+\w\+\s*$" contains=veraConstant,veraUserConstant
+syn match veraUserMethod "\zs\w\+\ze\s*(" contains=veraConstant,veraUserConstant
+syn match veraObject "\zs\w\+\ze\.\w"
+syn match veraObject "\zs\w\+\ze\.\$\w"
+
+" Accept ` for # (Verilog)
+syn region	veraPreCondit	start="^\s*\(`\|#\)\s*\(if\|ifdef\|ifndef\|elif\)\>" skip="\\$" end="$" end="//"me=s-1 contains=veraComment,veraCppString,veraCharacter,veraCppParen,veraParenError,veraNumbers,veraCommentError,veraSpaceError
+syn match	veraPreCondit	display "^\s*\(`\|#\)\s*\(else\|endif\)\>"
+if !exists("vera_no_if0")
+  syn region	veraCppOut		start="^\s*\(`\|#\)\s*if\s\+0\+\>" end=".\@=\|$" contains=veraCppOut2
+  syn region	veraCppOut2	contained start="0" end="^\s*\(`\|#\)\s*\(endif\>\|else\>\|elif\>\)" contains=veraSpaceError,veraCppSkip
+  syn region	veraCppSkip	contained start="^\s*\(`\|#\)\s*\(if\>\|ifdef\>\|ifndef\>\)" skip="\\$" end="^\s*\(`\|#\)\s*endif\>" contains=veraSpaceError,veraCppSkip
+endif
+syn region	veraIncluded	display contained start=+"+ skip=+\\\\\|\\"+ end=+"+
+syn match	veraIncluded	display contained "<[^>]*>"
+syn match	veraInclude	display "^\s*\(`\|#\)\s*include\>\s*["<]" contains=veraIncluded
+"syn match veraLineSkip	"\\$"
+syn cluster	veraPreProcGroup	contains=veraPreCondit,veraIncluded,veraInclude,veraDefine,veraErrInParen,veraErrInBracket,veraUserLabel,veraSpecial,veraOctalZero,veraCppOut,veraCppOut2,veraCppSkip,veraFormat,veraNumber,veraFloat,veraOctal,veraOctalError,veraNumbersCom,veraString,veraCommentSkip,veraCommentString,veraComment2String,@veraCommentGroup,veraCommentStartError,veraParen,veraBracket,veraMulti
+syn region	veraDefine		start="^\s*\(`\|#\)\s*\(define\|undef\)\>" skip="\\$" end="$" end="//"me=s-1 contains=ALLBUT,@veraPreProcGroup,@Spell
+syn region	veraPreProc	start="^\s*\(`\|#\)\s*\(pragma\>\|line\>\|warning\>\|error\>\)" skip="\\$" end="$" keepend contains=ALLBUT,@veraPreProcGroup,@Spell
+
+" Highlight User Labels
+syn cluster	veraMultiGroup	contains=veraIncluded,veraSpecial,veraCommentSkip,veraCommentString,veraComment2String,@veraCommentGroup,veraCommentStartError,veraUserCont,veraUserLabel,veraBitField,veraOctalZero,veraCppOut,veraCppOut2,veraCppSkip,veraFormat,veraNumber,veraFloat,veraOctal,veraOctalError,veraNumbersCom,veraCppParen,veraCppBracket,veraCppString
+syn region	veraMulti		transparent start='?' skip='::' end=':' contains=ALLBUT,@veraMultiGroup,@Spell
+" syn region	veraMulti		transparent start='?' skip='::' end=':' contains=ALL
+" The above causes veraCppOut2 to catch on:
+"    i = (isTrue) ? 0 : 1;
+" which ends up commenting the rest of the file
+
+" Avoid matching foo::bar() by requiring that the next char is not ':'
+syn cluster	veraLabelGroup	contains=veraUserLabel
+syn match	veraUserCont	display "^\s*\I\i*\s*:$" contains=@veraLabelGroup
+syn match	veraUserCont	display ";\s*\I\i*\s*:$" contains=@veraLabelGroup
+syn match	veraUserCont	display "^\s*\I\i*\s*:[^:]"me=e-1 contains=@veraLabelGroup
+syn match	veraUserCont	display ";\s*\I\i*\s*:[^:]"me=e-1 contains=@veraLabelGroup
+
+syn match	veraUserLabel	display "\I\i*" contained
+
+" Avoid recognizing most bitfields as labels
+syn match	veraBitField	display "^\s*\I\i*\s*:\s*[1-9]"me=e-1
+syn match	veraBitField	display ";\s*\I\i*\s*:\s*[1-9]"me=e-1
+
+if exists("vera_minlines")
+  let b:vera_minlines = vera_minlines
+else
+  if !exists("vera_no_if0")
+    let b:vera_minlines = 50	" #if 0 constructs can be long
+  else
+    let b:vera_minlines = 15	" mostly for () constructs
+  endif
+endif
+exec "syn sync ccomment veraComment minlines=" . b:vera_minlines
+
+" Define the default highlighting.
+" For version 5.7 and earlier: only when not done already
+" For version 5.8 and later: only when an item doesn't have highlighting yet
+if version >= 508 || !exists("did_vera_syn_inits")
+  if version < 508
+    let did_vera_syn_inits = 1
+    command -nargs=+ HiLink hi link <args>
+  else
+    command -nargs=+ HiLink hi def link <args>
+  endif
+
+  HiLink veraClass		Identifier
+  HiLink veraObject		Identifier
+  HiLink veraUserMethod		Function
+  HiLink veraTask		Keyword
+  HiLink veraModifier		Tag
+  HiLink veraDeprecated		veraError
+  HiLink veraMethods		Statement
+  " HiLink veraInterface		Label
+  HiLink veraInterface		Function
+
+  HiLink veraFormat		veraSpecial
+  HiLink veraCppString		veraString
+  HiLink veraCommentL		veraComment
+  HiLink veraCommentStart		veraComment
+  HiLink veraLabel			Label
+  HiLink veraUserLabel		Label
+  HiLink veraConditional		Conditional
+  HiLink veraRepeat		Repeat
+  HiLink veraCharacter		Character
+  HiLink veraSpecialCharacter	veraSpecial
+  HiLink veraNumber		Number
+  HiLink veraOctal			Number
+  HiLink veraOctalZero		PreProc	 " link this to Error if you want
+  HiLink veraFloat			Float
+  HiLink veraOctalError		veraError
+  HiLink veraParenError		veraError
+  HiLink veraErrInParen		veraError
+  HiLink veraErrInBracket		veraError
+  HiLink veraCommentError		veraError
+  HiLink veraCommentStartError	veraError
+  HiLink veraSpaceError         SpaceError
+  HiLink veraSpecialError		veraError
+  HiLink veraOperator		Operator
+  HiLink veraStructure		Structure
+  HiLink veraInclude		Include
+  HiLink veraPreProc		PreProc
+  HiLink veraDefine		Macro
+  HiLink veraIncluded		veraString
+  HiLink veraError			Error
+  HiLink veraStatement		Statement
+  HiLink veraPreCondit		PreCondit
+  HiLink veraType			Type
+  " HiLink veraConstant		Constant
+  HiLink veraConstant		Keyword
+  HiLink veraUserConstant		Constant
+  HiLink veraCommentString		veraString
+  HiLink veraComment2String	veraString
+  HiLink veraCommentSkip		veraComment
+  HiLink veraString		String
+  HiLink veraComment		Comment
+  HiLink veraSpecial		SpecialChar
+  HiLink veraTodo			Todo
+  HiLink veraCppSkip		veraCppOut
+  HiLink veraCppOut2		veraCppOut
+  HiLink veraCppOut		Comment
+
+  delcommand HiLink
+endif
+
+let b:current_syntax = "vera"
+
+" vim: ts=8
--- /dev/null
+++ b/lib/vimfiles/syntax/verilog.vim
@@ -1,0 +1,134 @@
+" Vim syntax file
+" Language:	Verilog
+" Maintainer:	Mun Johl <Mun.Johl@emulex.com>
+" Last Update:  Fri Oct 13 11:44:32 PDT 2006
+
+" For version 5.x: Clear all syntax items
+" For version 6.x: Quit when a syntax file was already loaded
+if version < 600
+   syntax clear
+elseif exists("b:current_syntax")
+   finish
+endif
+
+" Set the local value of the 'iskeyword' option
+if version >= 600
+   setlocal iskeyword=@,48-57,_,192-255
+else
+   set iskeyword=@,48-57,_,192-255
+endif
+
+" A bunch of useful Verilog keywords
+
+syn keyword verilogStatement   always and assign automatic buf
+syn keyword verilogStatement   bufif0 bufif1 cell cmos
+syn keyword verilogStatement   config deassign defparam design
+syn keyword verilogStatement   disable edge endconfig
+syn keyword verilogStatement   endfunction endgenerate endmodule
+syn keyword verilogStatement   endprimitive endspecify endtable endtask
+syn keyword verilogStatement   event force function
+syn keyword verilogStatement   generate genvar highz0 highz1 ifnone
+syn keyword verilogStatement   incdir include initial inout input
+syn keyword verilogStatement   instance integer large liblist
+syn keyword verilogStatement   library localparam macromodule medium
+syn keyword verilogStatement   module nand negedge nmos nor
+syn keyword verilogStatement   noshowcancelled not notif0 notif1 or
+syn keyword verilogStatement   output parameter pmos posedge primitive
+syn keyword verilogStatement   pull0 pull1 pulldown pullup
+syn keyword verilogStatement   pulsestyle_onevent pulsestyle_ondetect
+syn keyword verilogStatement   rcmos real realtime reg release
+syn keyword verilogStatement   rnmos rpmos rtran rtranif0 rtranif1
+syn keyword verilogStatement   scalared showcancelled signed small
+syn keyword verilogStatement   specify specparam strong0 strong1
+syn keyword verilogStatement   supply0 supply1 table task time tran
+syn keyword verilogStatement   tranif0 tranif1 tri tri0 tri1 triand
+syn keyword verilogStatement   trior trireg unsigned use vectored wait
+syn keyword verilogStatement   wand weak0 weak1 wire wor xnor xor
+syn keyword verilogLabel       begin end fork join
+syn keyword verilogConditional if else case casex casez default endcase
+syn keyword verilogRepeat      forever repeat while for
+
+syn keyword verilogTodo contained TODO
+
+syn match   verilogOperator "[&|~><!)(*#%@+/=?:;}{,.\^\-\[\]]"
+
+syn region  verilogComment start="/\*" end="\*/" contains=verilogTodo,@Spell
+syn match   verilogComment "//.*" contains=verilogTodo,@Spell
+
+"syn match   verilogGlobal "`[a-zA-Z0-9_]\+\>"
+syn match verilogGlobal "`celldefine"
+syn match verilogGlobal "`default_nettype"
+syn match verilogGlobal "`define"
+syn match verilogGlobal "`else"
+syn match verilogGlobal "`elsif"
+syn match verilogGlobal "`endcelldefine"
+syn match verilogGlobal "`endif"
+syn match verilogGlobal "`ifdef"
+syn match verilogGlobal "`ifndef"
+syn match verilogGlobal "`include"
+syn match verilogGlobal "`line"
+syn match verilogGlobal "`nounconnected_drive"
+syn match verilogGlobal "`resetall"
+syn match verilogGlobal "`timescale"
+syn match verilogGlobal "`unconnected_drive"
+syn match verilogGlobal "`undef"
+syn match   verilogGlobal "$[a-zA-Z0-9_]\+\>"
+
+syn match   verilogConstant "\<[A-Z][A-Z0-9_]\+\>"
+
+syn match   verilogNumber "\(\<\d\+\|\)'[sS]\?[bB]\s*[0-1_xXzZ?]\+\>"
+syn match   verilogNumber "\(\<\d\+\|\)'[sS]\?[oO]\s*[0-7_xXzZ?]\+\>"
+syn match   verilogNumber "\(\<\d\+\|\)'[sS]\?[dD]\s*[0-9_xXzZ?]\+\>"
+syn match   verilogNumber "\(\<\d\+\|\)'[sS]\?[hH]\s*[0-9a-fA-F_xXzZ?]\+\>"
+syn match   verilogNumber "\<[+-]\=[0-9_]\+\(\.[0-9_]*\|\)\(e[0-9_]*\|\)\>"
+
+syn region  verilogString start=+"+ skip=+\\"+ end=+"+ contains=verilogEscape,@Spell
+syn match   verilogEscape +\\[nt"\\]+ contained
+syn match   verilogEscape "\\\o\o\=\o\=" contained
+
+" Directives
+syn match   verilogDirective   "//\s*synopsys\>.*$"
+syn region  verilogDirective   start="/\*\s*synopsys\>" end="\*/"
+syn region  verilogDirective   start="//\s*synopsys dc_script_begin\>" end="//\s*synopsys dc_script_end\>"
+
+syn match   verilogDirective   "//\s*\$s\>.*$"
+syn region  verilogDirective   start="/\*\s*\$s\>" end="\*/"
+syn region  verilogDirective   start="//\s*\$s dc_script_begin\>" end="//\s*\$s dc_script_end\>"
+
+"Modify the following as needed.  The trade-off is performance versus
+"functionality.
+syn sync minlines=50
+
+" Define the default highlighting.
+" For version 5.7 and earlier: only when not done already
+" For version 5.8 and later: only when an item doesn't have highlighting yet
+if version >= 508 || !exists("did_verilog_syn_inits")
+   if version < 508
+      let did_verilog_syn_inits = 1
+      command -nargs=+ HiLink hi link <args>
+   else
+      command -nargs=+ HiLink hi def link <args>
+   endif
+
+   " The default highlighting.
+   HiLink verilogCharacter       Character
+   HiLink verilogConditional     Conditional
+   HiLink verilogRepeat		 Repeat
+   HiLink verilogString		 String
+   HiLink verilogTodo		 Todo
+   HiLink verilogComment	 Comment
+   HiLink verilogConstant	 Constant
+   HiLink verilogLabel		 Label
+   HiLink verilogNumber		 Number
+   HiLink verilogOperator	 Special
+   HiLink verilogStatement	 Statement
+   HiLink verilogGlobal		 Define
+   HiLink verilogDirective	 SpecialComment
+   HiLink verilogEscape		 Special
+
+   delcommand HiLink
+endif
+
+let b:current_syntax = "verilog"
+
+" vim: ts=8
--- /dev/null
+++ b/lib/vimfiles/syntax/verilogams.vim
@@ -1,0 +1,142 @@
+" Vim syntax file
+" Language:	Verilog-AMS
+" Maintainer:	S. Myles Prather <smprather@gmail.com>
+" Last Update:  Sun Aug 14 03:58:00 CST 2003
+
+" For version 5.x: Clear all syntax items
+" For version 6.x: Quit when a syntax file was already loaded
+if version < 600
+   syntax clear
+elseif exists("b:current_syntax")
+   finish
+endif
+
+" Set the local value of the 'iskeyword' option
+if version >= 600
+   setlocal iskeyword=@,48-57,_,192-255
+else
+   set iskeyword=@,48-57,_,192-255
+endif
+
+" Annex B.1 'All keywords'
+syn keyword verilogamsStatement above abs absdelay acos acosh ac_stim
+syn keyword verilogamsStatement always analog analysis and asin
+syn keyword verilogamsStatement asinh assign atan atan2 atanh branch
+syn keyword verilogamsStatement buf bufif1 ceil cmos
+syn keyword verilogamsStatement connectrules cos cosh cross ddt ddx deassign
+syn keyword verilogamsStatement defparam disable discipline
+syn keyword verilogamsStatement driver_update edge enddiscipline
+syn keyword verilogamsStatement endconnectrules endmodule endfunction
+syn keyword verilogamsStatement endnature endparamset endprimitive endspecify
+syn keyword verilogamsStatement endtable endtask event exp final_step
+syn keyword verilogamsStatement flicker_noise floor flow force fork
+syn keyword verilogamsStatement function generate genvar highz0
+syn keyword verilogamsStatement highz1 hypot idt idtmod if ifnone initial
+syn keyword verilogamsStatement initial_step inout input join
+syn keyword verilogamsStatement laplace_nd laplace_np laplace_zd laplace_zp
+syn keyword verilogamsStatement large last_crossing limexp ln localparam log
+syn keyword verilogamsStatement macromodule max medium min module nand nature
+syn keyword verilogamsStatement negedge net_resolution nmos noise_table nor not
+syn keyword verilogamsStatement notif0 notif1 or output paramset pmos
+syn keyword verilogamsType      parameter real integer electrical input output
+syn keyword verilogamsType      inout reg tri tri0 tri1 triand trior trireg
+syn keyword verilogamsType      string from exclude aliasparam ground
+syn keyword verilogamsStatement posedge potential pow primitive pull0 pull1
+syn keyword verilogamsStatement pullup pulldown rcmos release
+syn keyword verilogamsStatement rnmos rpmos rtran rtranif0 rtranif1
+syn keyword verilogamsStatement scalared sin sinh slew small specify specparam
+syn keyword verilogamsStatement sqrt strong0 strong1 supply0 supply1
+syn keyword verilogamsStatement table tan tanh task time timer tran tranif0
+syn keyword verilogamsStatement tranif1 transition
+syn keyword verilogamsStatement vectored wait wand weak0 weak1
+syn keyword verilogamsStatement white_noise wire wor wreal xnor xor zi_nd
+syn keyword verilogamsStatement zi_np zi_zd
+syn keyword verilogamsRepeat    forever repeat while for
+syn keyword verilogamsLabel     begin end
+syn keyword verilogamsConditional if else case casex casez default endcase
+syn match   verilogamsConstant  ":inf"lc=1
+syn match   verilogamsConstant  "-inf"lc=1
+" Annex B.2 Discipline/nature
+syn keyword verilogamsStatement abstol access continuous ddt_nature discrete
+syn keyword verilogamsStatement domain idt_nature units 
+" Annex B.3 Connect Rules
+syn keyword verilogamsStatement connect merged resolveto split
+
+syn match   verilogamsOperator  "[&|~><!)(*#%@+/=?:;}{,.\^\-\[\]]"
+syn match   verilogamsOperator  "<+"
+syn match   verilogamsStatement "[vV]("me=e-1
+syn match   verilogamsStatement "[iI]("me=e-1
+
+syn keyword verilogamsTodo contained TODO
+syn region  verilogamsComment start="/\*" end="\*/" contains=verilogamsTodo
+syn match   verilogamsComment "//.*" contains=verilogamsTodo
+
+syn match verilogamsGlobal "`celldefine"
+syn match verilogamsGlobal "`default_nettype"
+syn match verilogamsGlobal "`define"
+syn match verilogamsGlobal "`else"
+syn match verilogamsGlobal "`elsif"
+syn match verilogamsGlobal "`endcelldefine"
+syn match verilogamsGlobal "`endif"
+syn match verilogamsGlobal "`ifdef"
+syn match verilogamsGlobal "`ifndef"
+syn match verilogamsGlobal "`include"
+syn match verilogamsGlobal "`line"
+syn match verilogamsGlobal "`nounconnected_drive"
+syn match verilogamsGlobal "`resetall"
+syn match verilogamsGlobal "`timescale"
+syn match verilogamsGlobal "`unconnected_drive"
+syn match verilogamsGlobal "`undef"
+syn match verilogamsSystask "$[a-zA-Z0-9_]\+\>"
+
+syn match verilogamsConstant "\<[A-Z][A-Z0-9_]\+\>"
+
+syn match   verilogamsNumber "\(\<\d\+\|\)'[bB]\s*[0-1_xXzZ?]\+\>"
+syn match   verilogamsNumber "\(\<\d\+\|\)'[oO]\s*[0-7_xXzZ?]\+\>"
+syn match   verilogamsNumber "\(\<\d\+\|\)'[dD]\s*[0-9_xXzZ?]\+\>"
+syn match   verilogamsNumber "\(\<\d\+\|\)'[hH]\s*[0-9a-fA-F_xXzZ?]\+\>"
+syn match   verilogamsNumber "\<[+-]\=[0-9_]\+\(\.[0-9_]*\|\)\(e[0-9_]*\|\)\>"
+
+syn region  verilogamsString start=+"+ skip=+\\"+ end=+"+ contains=verilogamsEscape
+syn match   verilogamsEscape +\\[nt"\\]+ contained
+syn match   verilogamsEscape "\\\o\o\=\o\=" contained
+
+"Modify the following as needed.  The trade-off is performance versus
+"functionality.
+syn sync lines=50
+
+" Define the default highlighting.
+" For version 5.7 and earlier: only when not done already
+" For version 5.8 and later: only when an item doesn't have highlighting yet
+if version >= 508 || !exists("did_verilogams_syn_inits")
+   if version < 508
+      let did_verilogams_syn_inits = 1
+      command -nargs=+ HiLink hi link <args>
+   else
+      command -nargs=+ HiLink hi def link <args>
+   endif
+
+   " The default highlighting.
+   HiLink verilogamsCharacter    Character
+   HiLink verilogamsConditional  Conditional
+   HiLink verilogamsRepeat       Repeat
+   HiLink verilogamsString       String
+   HiLink verilogamsTodo         Todo
+   HiLink verilogamsComment      Comment
+   HiLink verilogamsConstant     Constant
+   HiLink verilogamsLabel        Label
+   HiLink verilogamsNumber       Number
+   HiLink verilogamsOperator     Special
+   HiLink verilogamsStatement    Statement
+   HiLink verilogamsGlobal       Define
+   HiLink verilogamsDirective    SpecialComment
+   HiLink verilogamsEscape       Special
+   HiLink verilogamsType         Type
+   HiLink verilogamsSystask      Function
+
+   delcommand HiLink
+endif
+
+let b:current_syntax = "verilogams"
+
+" vim: ts=8
--- /dev/null
+++ b/lib/vimfiles/syntax/vgrindefs.vim
@@ -1,0 +1,45 @@
+" Vim syntax file
+" Language:	Vgrindefs
+" Maintainer:	Bram Moolenaar <Bram@vim.org>
+" Last Change:	2005 Jun 20
+
+" The Vgrindefs file is used to specify a language for vgrind
+
+" Quit when a (custom) syntax file was already loaded
+if exists("b:current_syntax")
+  finish
+endif
+
+" Comments
+syn match vgrindefsComment "^#.*"
+
+" The fields that vgrind recognizes
+syn match vgrindefsField ":ab="
+syn match vgrindefsField ":ae="
+syn match vgrindefsField ":pb="
+syn match vgrindefsField ":bb="
+syn match vgrindefsField ":be="
+syn match vgrindefsField ":cb="
+syn match vgrindefsField ":ce="
+syn match vgrindefsField ":sb="
+syn match vgrindefsField ":se="
+syn match vgrindefsField ":lb="
+syn match vgrindefsField ":le="
+syn match vgrindefsField ":nc="
+syn match vgrindefsField ":tl"
+syn match vgrindefsField ":oc"
+syn match vgrindefsField ":kw="
+
+" Also find the ':' at the end of the line, so all ':' are highlighted
+syn match vgrindefsField ":\\$"
+syn match vgrindefsField ":$"
+syn match vgrindefsField "\\$"
+
+" Define the default highlighting.
+" Only used when an item doesn't have highlighting yet
+hi def link vgrindefsField	Statement
+hi def link vgrindefsComment	Comment
+
+let b:current_syntax = "vgrindefs"
+
+" vim: ts=8
--- /dev/null
+++ b/lib/vimfiles/syntax/vhdl.vim
@@ -1,0 +1,184 @@
+" Vim syntax file
+" Language:	VHDL
+" Maintainer:	Czo <Olivier.Sirol@lip6.fr>
+" Credits:	Stephan Hegel <stephan.hegel@snc.siemens.com.cn>
+" $Id: vhdl.vim,v 1.1 2004/06/13 15:34:56 vimboss Exp $
+
+" VHSIC Hardware Description Language
+" Very High Scale Integrated Circuit
+
+" For version 5.x: Clear all syntax items
+" For version 6.x: Quit when a syntax file was already loaded
+if version < 600
+  syntax clear
+elseif exists("b:current_syntax")
+  finish
+endif
+
+" This is not VHDL. I use the C-Preprocessor cpp to generate different binaries
+" from one VHDL source file. Unfortunately there is no preprocessor for VHDL
+" available. If you don't like this, please remove the following lines.
+syn match cDefine "^#ifdef[ ]\+[A-Za-z_]\+"
+syn match cDefine "^#endif"
+
+" case is not significant
+syn case ignore
+
+" VHDL keywords
+syn keyword vhdlStatement access after alias all assert
+syn keyword vhdlStatement architecture array attribute
+syn keyword vhdlStatement begin block body buffer bus
+syn keyword vhdlStatement case component configuration constant
+syn keyword vhdlStatement disconnect downto
+syn keyword vhdlStatement elsif end entity exit
+syn keyword vhdlStatement file for function
+syn keyword vhdlStatement generate generic group guarded
+syn keyword vhdlStatement impure in inertial inout is
+syn keyword vhdlStatement label library linkage literal loop
+syn keyword vhdlStatement map
+syn keyword vhdlStatement new next null
+syn keyword vhdlStatement of on open others out
+syn keyword vhdlStatement package port postponed procedure process pure
+syn keyword vhdlStatement range record register reject report return
+syn keyword vhdlStatement select severity signal shared
+syn keyword vhdlStatement subtype
+syn keyword vhdlStatement then to transport type
+syn keyword vhdlStatement unaffected units until use
+syn keyword vhdlStatement variable wait when while with
+syn keyword vhdlStatement note warning error failure
+
+" Special match for "if" and "else" since "else if" shouldn't be highlighted.
+" The right keyword is "elsif"
+syn match   vhdlStatement "\<\(if\|else\)\>"
+syn match   vhdlNone      "\<else\s\+if\>$"
+syn match   vhdlNone      "\<else\s\+if\>\s"
+
+" Predifined VHDL types
+syn keyword vhdlType bit bit_vector
+syn keyword vhdlType character boolean integer real time
+syn keyword vhdlType string severity_level
+" Predifined standard ieee VHDL types
+syn keyword vhdlType positive natural signed unsigned
+syn keyword vhdlType line text
+syn keyword vhdlType std_logic std_logic_vector
+syn keyword vhdlType std_ulogic std_ulogic_vector
+" Predefined non standard VHDL types for Mentor Graphics Sys1076/QuickHDL
+syn keyword vhdlType qsim_state qsim_state_vector
+syn keyword vhdlType qsim_12state qsim_12state_vector
+syn keyword vhdlType qsim_strength
+" Predefined non standard VHDL types for Alliance VLSI CAD
+syn keyword vhdlType mux_bit mux_vector reg_bit reg_vector wor_bit wor_vector
+
+" array attributes
+syn match vhdlAttribute "\'high"
+syn match vhdlAttribute "\'left"
+syn match vhdlAttribute "\'length"
+syn match vhdlAttribute "\'low"
+syn match vhdlAttribute "\'range"
+syn match vhdlAttribute "\'reverse_range"
+syn match vhdlAttribute "\'right"
+syn match vhdlAttribute "\'ascending"
+" block attributes
+syn match vhdlAttribute "\'behaviour"
+syn match vhdlAttribute "\'structure"
+syn match vhdlAttribute "\'simple_name"
+syn match vhdlAttribute "\'instance_name"
+syn match vhdlAttribute "\'path_name"
+syn match vhdlAttribute "\'foreign"
+" signal attribute
+syn match vhdlAttribute "\'active"
+syn match vhdlAttribute "\'delayed"
+syn match vhdlAttribute "\'event"
+syn match vhdlAttribute "\'last_active"
+syn match vhdlAttribute "\'last_event"
+syn match vhdlAttribute "\'last_value"
+syn match vhdlAttribute "\'quiet"
+syn match vhdlAttribute "\'stable"
+syn match vhdlAttribute "\'transaction"
+syn match vhdlAttribute "\'driving"
+syn match vhdlAttribute "\'driving_value"
+" type attributes
+syn match vhdlAttribute "\'base"
+syn match vhdlAttribute "\'high"
+syn match vhdlAttribute "\'left"
+syn match vhdlAttribute "\'leftof"
+syn match vhdlAttribute "\'low"
+syn match vhdlAttribute "\'pos"
+syn match vhdlAttribute "\'pred"
+syn match vhdlAttribute "\'rightof"
+syn match vhdlAttribute "\'succ"
+syn match vhdlAttribute "\'val"
+syn match vhdlAttribute "\'image"
+syn match vhdlAttribute "\'value"
+
+syn keyword vhdlBoolean true false
+
+" for this vector values case is significant
+syn case match
+" Values for standard VHDL types
+syn match vhdlVector "\'[0L1HXWZU\-\?]\'"
+" Values for non standard VHDL types qsim_12state for Mentor Graphics Sys1076/QuickHDL
+syn keyword vhdlVector S0S S1S SXS S0R S1R SXR S0Z S1Z SXZ S0I S1I SXI
+syn case ignore
+
+syn match  vhdlVector "B\"[01_]\+\""
+syn match  vhdlVector "O\"[0-7_]\+\""
+syn match  vhdlVector "X\"[0-9a-f_]\+\""
+syn match  vhdlCharacter "'.'"
+syn region vhdlString start=+"+  end=+"+
+
+" floating numbers
+syn match vhdlNumber "-\=\<\d\+\.\d\+\(E[+\-]\=\d\+\)\>"
+syn match vhdlNumber "-\=\<\d\+\.\d\+\>"
+syn match vhdlNumber "0*2#[01_]\+\.[01_]\+#\(E[+\-]\=\d\+\)\="
+syn match vhdlNumber "0*16#[0-9a-f_]\+\.[0-9a-f_]\+#\(E[+\-]\=\d\+\)\="
+" integer numbers
+syn match vhdlNumber "-\=\<\d\+\(E[+\-]\=\d\+\)\>"
+syn match vhdlNumber "-\=\<\d\+\>"
+syn match vhdlNumber "0*2#[01_]\+#\(E[+\-]\=\d\+\)\="
+syn match vhdlNumber "0*16#[0-9a-f_]\+#\(E[+\-]\=\d\+\)\="
+" operators
+syn keyword vhdlOperator and nand or nor xor xnor
+syn keyword vhdlOperator rol ror sla sll sra srl
+syn keyword vhdlOperator mod rem abs not
+syn match   vhdlOperator "[&><=:+\-*\/|]"
+syn match   vhdlSpecial  "[().,;]"
+" time
+syn match vhdlTime "\<\d\+\s\+\(\([fpnum]s\)\|\(sec\)\|\(min\)\|\(hr\)\)\>"
+syn match vhdlTime "\<\d\+\.\d\+\s\+\(\([fpnum]s\)\|\(sec\)\|\(min\)\|\(hr\)\)\>"
+
+syn match vhdlComment "--.*$"
+" syn match vhdlGlobal "[\'$#~!%@?\^\[\]{}\\]"
+
+" Define the default highlighting.
+" For version 5.7 and earlier: only when not done already
+" For version 5.8 and later: only when an item doesn't have highlighting yet
+if version >= 508 || !exists("did_vhdl_syntax_inits")
+  if version < 508
+    let did_vhdl_syntax_inits = 1
+    command -nargs=+ HiLink hi link <args>
+  else
+    command -nargs=+ HiLink hi def link <args>
+  endif
+
+  HiLink cDefine       PreProc
+  HiLink vhdlSpecial   Special
+  HiLink vhdlStatement Statement
+  HiLink vhdlCharacter String
+  HiLink vhdlString    String
+  HiLink vhdlVector    String
+  HiLink vhdlBoolean   String
+  HiLink vhdlComment   Comment
+  HiLink vhdlNumber    String
+  HiLink vhdlTime      String
+  HiLink vhdlType      Type
+  HiLink vhdlOperator  Type
+  HiLink vhdlGlobal    Error
+  HiLink vhdlAttribute Type
+
+  delcommand HiLink
+endif
+
+let b:current_syntax = "vhdl"
+
+" vim: ts=8
--- /dev/null
+++ b/lib/vimfiles/syntax/vim.vim
@@ -1,0 +1,714 @@
+" Vim syntax file
+" Language:	Vim 7.1 script
+" Maintainer:	Dr. Charles E. Campbell, Jr. <NdrOchipS@PcampbellAfamily.Mbiz>
+" Last Change:	May 11, 2007
+" Version:	7.1-67
+" Automatically generated keyword lists: {{{1
+
+" Quit when a syntax file was already loaded {{{2
+if exists("b:current_syntax")
+  finish
+endif
+
+" vimTodo: contains common special-notices for comments {{{2
+" Use the vimCommentGroup cluster to add your own.
+syn keyword vimTodo contained	COMBAK	FIXME	TODO	XXX
+syn cluster vimCommentGroup	contains=vimTodo,@Spell
+
+" regular vim commands {{{2
+syn keyword vimCommand contained	ab[breviate] abc[lear] abo[veleft] al[l] arga[dd] argd[elete] argdo arge[dit] argg[lobal] argl[ocal] ar[gs] argu[ment] as[cii] bad[d] ba[ll] bd[elete] be bel[owright] bf[irst] bl[ast] bm[odified] bn[ext] bN[ext] bo[tright] bp[revious] brea[k] breaka[dd] breakd[el] breakl[ist] br[ewind] bro[wse] bufdo b[uffer] buffers bun[load] bw[ipeout] ca[bbrev] cabc[lear] caddb[uffer] cad[dexpr] caddf[ile] cal[l] cat[ch] cb[uffer] cc ccl[ose] cd ce[nter] cex[pr] cf[ile] cfir[st] cgetb[uffer] cgete[xpr] cg[etfile] c[hange] changes chd[ir] che[ckpath] checkt[ime] cla[st] cl[ist] clo[se] cmapc[lear] cnew[er] cn[ext] cN[ext] cnf[ile] cNf[ile] cnorea[bbrev] col[der] colo[rscheme] comc[lear] comp[iler] conf[irm] con[tinue] cope[n] co[py] cpf[ile] cp[revious] cq[uit] cr[ewind] cuna[bbrev] cu[nmap] cw[indow] debugg[reedy] delc[ommand] d[elete] delf[unction] delm[arks] diffg[et] diffoff diffpatch diffpu[t] diffsplit diffthis diffu[pdate] dig[raphs] di[splay] dj[ump] dl[ist] dr[op] ds[earch] dsp[lit] earlier echoe[rr] echom[sg] echon e[dit] el[se] elsei[f] em[enu] emenu* endfo[r] endf[unction] en[dif] endt[ry] endw[hile] ene[w] ex exi[t] exu[sage] f[ile] files filetype fina[lly] fin[d] fini[sh] fir[st] fix[del] fo[ld] foldc[lose] folddoc[losed] foldd[oopen] foldo[pen] for fu[nction] go[to] gr[ep] grepa[dd] ha[rdcopy] h[elp] helpf[ind] helpg[rep] helpt[ags] hid[e] his[tory] ia[bbrev] iabc[lear] if ij[ump] il[ist] imapc[lear] inorea[bbrev] is[earch] isp[lit] iuna[bbrev] iu[nmap] j[oin] ju[mps] k keepalt keepj[umps] kee[pmarks] laddb[uffer] lad[dexpr] laddf[ile] lan[guage] la[st] later lb[uffer] lc[d] lch[dir] lcl[ose] le[ft] lefta[bove] lex[pr] lf[ile] lfir[st] lgetb[uffer] lgete[xpr] lg[etfile] lgr[ep] lgrepa[dd] lh[elpgrep] l[ist] ll lla[st] lli[st] lmak[e] lm[ap] lmapc[lear] lnew[er] lne[xt] lN[ext] lnf[ile] lNf[ile] ln[oremap] lo[adview] loc[kmarks] lockv[ar] lol[der] lop[en] lpf[ile] lp[revious] lr[ewind] ls lt[ag] lu[nmap] lv[imgrep] lvimgrepa[dd] lw[indow] mak[e] ma[rk] marks mat[ch] menut[ranslate] mk[exrc] mks[ession] mksp[ell] mkvie[w] mkv[imrc] mod[e] m[ove] mzf[ile] mz[scheme] nbkey new n[ext] N[ext] nmapc[lear] noh[lsearch] norea[bbrev] nu[mber] nun[map] omapc[lear] on[ly] o[pen] opt[ions] ou[nmap] pc[lose] ped[it] pe[rl] perld[o] po[p] popu popu[p] pp[op] pre[serve] prev[ious] p[rint] P[rint] profd[el] prof[ile] promptf[ind] promptr[epl] ps[earch] pta[g] ptf[irst] ptj[ump] ptl[ast] ptn[ext] ptN[ext] ptp[revious] ptr[ewind] pts[elect] pu[t] pw[d] pyf[ile] py[thon] qa[ll] q[uit] quita[ll] r[ead] rec[over] redi[r] red[o] redr[aw] redraws[tatus] reg[isters] res[ize] ret[ab] retu[rn] rew[ind] ri[ght] rightb[elow] rub[y] rubyd[o] rubyf[ile] ru[ntime] rv[iminfo] sal[l] san[dbox] sa[rgument] sav[eas] sba[ll] sbf[irst] sbl[ast] sbm[odified] sbn[ext] sbN[ext] sbp[revious] sbr[ewind] sb[uffer] scripte[ncoding] scrip[tnames] se[t] setf[iletype] setg[lobal] setl[ocal] sf[ind] sfir[st] sh[ell] sign sil[ent] sim[alt] sla[st] sl[eep] sm[agic] sm[ap] smapc[lear] sme smenu sn[ext] sN[ext] sni[ff] sno[magic] snor[emap] snoreme snoremenu sor[t] so[urce] spelld[ump] spe[llgood] spelli[nfo] spellr[epall] spellu[ndo] spellw[rong] sp[lit] spr[evious] sre[wind] sta[g] startg[replace] star[tinsert] startr[eplace] stj[ump] st[op] stopi[nsert] sts[elect] sun[hide] sunm[ap] sus[pend] sv[iew] syncbind t tab tabc[lose] tabd[o] tabe[dit] tabf[ind] tabfir[st] tabl[ast] tabm[ove] tabnew tabn[ext] tabN[ext] tabo[nly] tabp[revious] tabr[ewind] tabs ta[g] tags tc[l] tcld[o] tclf[ile] te[aroff] tf[irst] th[row] tj[ump] tl[ast] tm tm[enu] tn[ext] tN[ext] to[pleft] tp[revious] tr[ewind] try ts[elect] tu tu[nmenu] una[bbreviate] u[ndo] undoj[oin] undol[ist] unh[ide] unlo[ckvar] unm[ap] up[date] verb[ose] ve[rsion] vert[ical] vie[w] vim[grep] vimgrepa[dd] vi[sual] viu[sage] vmapc[lear] vne[w] vs[plit] vu[nmap] wa[ll] wh[ile] winc[md] windo winp[os] win[size] wn[ext] wN[ext] wp[revious] wq wqa[ll] w[rite] ws[verb] wv[iminfo] X xa[ll] x[it] xm[ap] xmapc[lear] xme xmenu XMLent XMLns xn[oremap] xnoreme xnoremenu xu[nmap] y[ank] 
+syn match   vimCommand contained	"\<z[-+^.=]"
+
+" vimOptions are caught only when contained in a vimSet {{{2
+syn keyword vimOption contained	acd ai akm al aleph allowrevins altkeymap ambiwidth ambw anti antialias ar arab arabic arabicshape ari arshape autochdir autoindent autoread autowrite autowriteall aw awa background backspace backup backupcopy backupdir backupext backupskip balloondelay ballooneval balloonexpr bdir bdlay beval bex bexpr bg bh bin binary biosk bioskey bk bkc bl bomb breakat brk browsedir bs bsdir bsk bt bufhidden buflisted buftype casemap cb ccv cd cdpath cedit cf cfu ch charconvert ci cin cindent cink cinkeys cino cinoptions cinw cinwords clipboard cmdheight cmdwinheight cmp cms co columns com comments commentstring compatible complete completefunc completeopt confirm consk conskey copyindent cot cp cpo cpoptions cpt cscopepathcomp cscopeprg cscopequickfix cscopetag cscopetagorder cscopeverbose cspc csprg csqf cst csto csverb cuc cul cursorcolumn cursorline cwh debug deco def define delcombine dex dg dict dictionary diff diffexpr diffopt digraph dip dir directory display dy ea ead eadirection eb ed edcompatible ef efm ei ek enc encoding endofline eol ep equalalways equalprg errorbells errorfile errorformat esckeys et eventignore ex expandtab exrc fcl fcs fdc fde fdi fdl fdls fdm fdn fdo fdt fen fenc fencs fex ff ffs fileencoding fileencodings fileformat fileformats filetype fillchars fk fkmap flp fml fmr fo foldclose foldcolumn foldenable foldexpr foldignore foldlevel foldlevelstart foldmarker foldmethod foldminlines foldnestmax foldopen foldtext formatexpr formatlistpat formatoptions formatprg fp fs fsync ft gcr gd gdefault gfm gfn gfs gfw ghr go gp grepformat grepprg gtl gtt guicursor guifont guifontset guifontwide guiheadroom guioptions guipty guitablabel guitabtooltip helpfile helpheight helplang hf hh hi hid hidden highlight history hk hkmap hkmapp hkp hl hlg hls hlsearch ic icon iconstring ignorecase im imactivatekey imak imc imcmdline imd imdisable imi iminsert ims imsearch inc include includeexpr incsearch inde indentexpr indentkeys indk inex inf infercase insertmode is isf isfname isi isident isk iskeyword isp isprint joinspaces js key keymap keymodel keywordprg km kmp kp langmap langmenu laststatus lazyredraw lbr lcs linebreak lines linespace lisp lispwords list listchars lm lmap loadplugins lpl ls lsp lw lz ma macatsui magic makeef makeprg mat matchpairs matchtime maxcombine maxfuncdepth maxmapdepth maxmem maxmempattern maxmemtot mco mef menuitems mfd mh mis mkspellmem ml mls mm mmd mmp mmt mod modeline modelines modifiable modified more mouse mousef mousefocus mousehide mousem mousemodel mouses mouseshape mouset mousetime mp mps msm mzq mzquantum nf nrformats nu number numberwidth nuw odev oft ofu omnifunc opendevice operatorfunc opfunc osfiletype pa para paragraphs paste pastetoggle patchexpr patchmode path pdev penc pex pexpr pfn ph pheader pi pm pmbcs pmbfn popt preserveindent previewheight previewwindow printdevice printencoding printexpr printfont printheader printmbcharset printmbfont printoptions prompt pt pumheight pvh pvw qe quoteescape readonly remap report restorescreen revins ri rightleft rightleftcmd rl rlc ro rs rtp ru ruf ruler rulerformat runtimepath sb sbo sbr sc scb scr scroll scrollbind scrolljump scrolloff scrollopt scs sect sections secure sel selection selectmode sessionoptions sft sh shcf shell shellcmdflag shellpipe shellquote shellredir shellslash shelltemp shelltype shellxquote shiftround shiftwidth shm shortmess shortname showbreak showcmd showfulltag showmatch showmode showtabline shq si sidescroll sidescrolloff siso sj slm sm smartcase smartindent smarttab smc smd sn so softtabstop sol sp spc spell spellcapcheck spellfile spelllang spellsuggest spf spl splitbelow splitright spr sps sr srr ss ssl ssop st sta stal startofline statusline stl stmp sts su sua suffixes suffixesadd sw swapfile swapsync swb swf switchbuf sws sxq syn synmaxcol syntax ta tabline tabpagemax tabstop tag tagbsearch taglength tagrelative tags tagstack tal tb tbi tbidi tbis tbs tenc term termbidi termencoding terse textauto textmode textwidth tf tgst thesaurus tildeop timeout timeoutlen title tit
\ No newline at end of file
+
+" vimOptions: These are the turn-off setting variants {{{2
+syn keyword vimOption contained	noacd noai noakm noallowrevins noaltkeymap noanti noantialias noar noarab noarabic noarabicshape noari noarshape noautochdir noautoindent noautoread noautowrite noautowriteall noaw noawa nobackup noballooneval nobeval nobin nobinary nobiosk nobioskey nobk nobl nobomb nobuflisted nocf noci nocin nocindent nocompatible noconfirm noconsk noconskey nocopyindent nocp nocscopetag nocscopeverbose nocst nocsverb nocuc nocul nocursorcolumn nocursorline nodeco nodelcombine nodg nodiff nodigraph nodisable noea noeb noed noedcompatible noek noendofline noeol noequalalways noerrorbells noesckeys noet noex noexpandtab noexrc nofen nofk nofkmap nofoldenable nogd nogdefault noguipty nohid nohidden nohk nohkmap nohkmapp nohkp nohls nohlsearch noic noicon noignorecase noim noimc noimcmdline noimd noincsearch noinf noinfercase noinsertmode nois nojoinspaces nojs nolazyredraw nolbr nolinebreak nolisp nolist noloadplugins nolpl nolz noma nomacatsui nomagic nomh noml nomod nomodeline nomodifiable nomodified nomore nomousef nomousefocus nomousehide nonu nonumber noodev noopendevice nopaste nopi nopreserveindent nopreviewwindow noprompt nopvw noreadonly noremap norestorescreen norevins nori norightleft norightleftcmd norl norlc noro nors noru noruler nosb nosc noscb noscrollbind noscs nosecure nosft noshellslash noshelltemp noshiftround noshortname noshowcmd noshowfulltag noshowmatch noshowmode nosi nosm nosmartcase nosmartindent nosmarttab nosmd nosn nosol nospell nosplitbelow nosplitright nospr nosr nossl nosta nostartofline nostmp noswapfile noswf nota notagbsearch notagrelative notagstack notbi notbidi notbs notermbidi noterse notextauto notextmode notf notgst notildeop notimeout notitle noto notop notr nottimeout nottybuiltin nottyfast notx novb novisualbell nowa nowarn nowb noweirdinvert nowfh nowfw nowildmenu nowinfixheight nowinfixwidth nowiv nowmnu nowrap nowrapscan nowrite nowriteany nowritebackup nows 
+
+" vimOptions: These are the invertible variants {{{2
+syn keyword vimOption contained	invacd invai invakm invallowrevins invaltkeymap invanti invantialias invar invarab invarabic invarabicshape invari invarshape invautochdir invautoindent invautoread invautowrite invautowriteall invaw invawa invbackup invballooneval invbeval invbin invbinary invbiosk invbioskey invbk invbl invbomb invbuflisted invcf invci invcin invcindent invcompatible invconfirm invconsk invconskey invcopyindent invcp invcscopetag invcscopeverbose invcst invcsverb invcuc invcul invcursorcolumn invcursorline invdeco invdelcombine invdg invdiff invdigraph invdisable invea inveb inved invedcompatible invek invendofline inveol invequalalways inverrorbells invesckeys invet invex invexpandtab invexrc invfen invfk invfkmap invfoldenable invgd invgdefault invguipty invhid invhidden invhk invhkmap invhkmapp invhkp invhls invhlsearch invic invicon invignorecase invim invimc invimcmdline invimd invincsearch invinf invinfercase invinsertmode invis invjoinspaces invjs invlazyredraw invlbr invlinebreak invlisp invlist invloadplugins invlpl invlz invma invmacatsui invmagic invmh invml invmod invmodeline invmodifiable invmodified invmore invmousef invmousefocus invmousehide invnu invnumber invodev invopendevice invpaste invpi invpreserveindent invpreviewwindow invprompt invpvw invreadonly invremap invrestorescreen invrevins invri invrightleft invrightleftcmd invrl invrlc invro invrs invru invruler invsb invsc invscb invscrollbind invscs invsecure invsft invshellslash invshelltemp invshiftround invshortname invshowcmd invshowfulltag invshowmatch invshowmode invsi invsm invsmartcase invsmartindent invsmarttab invsmd invsn invsol invspell invsplitbelow invsplitright invspr invsr invssl invsta invstartofline invstmp invswapfile invswf invta invtagbsearch invtagrelative invtagstack invtbi invtbidi invtbs invtermbidi invterse invtextauto invtextmode invtf invtgst invtildeop invtimeout invtitle invto invtop invtr invttimeout invttybuiltin invttyfast invtx invvb invvisualbell invwa invwarn invwb invweirdinvert invwfh invwfw invwildmenu invwinfixheight invwinfixwidth invwiv invwmnu invwrap invwrapscan invwrite invwriteany invwritebackup invws 
+
+" termcap codes (which can also be set) {{{2
+syn keyword vimOption contained	t_AB t_AF t_al t_AL t_bc t_cd t_ce t_Ce t_cl t_cm t_Co t_cs t_Cs t_CS t_CV t_da t_db t_dl t_DL t_EI t_F1 t_F2 t_F3 t_F4 t_F5 t_F6 t_F7 t_F8 t_F9 t_fs t_IE t_IS t_k1 t_K1 t_k2 t_k3 t_K3 t_k4 t_K4 t_k5 t_K5 t_k6 t_K6 t_k7 t_K7 t_k8 t_K8 t_k9 t_K9 t_KA t_kb t_kB t_KB t_KC t_kd t_kD t_KD t_ke t_KE t_KF t_KG t_kh t_KH t_kI t_KI t_KJ t_KK t_kl t_KL t_kN t_kP t_kr t_ks t_ku t_le t_mb t_md t_me t_mr t_ms t_nd t_op t_RI t_RV t_Sb t_se t_Sf t_SI t_so t_sr t_te t_ti t_ts t_ue t_us t_ut t_vb t_ve t_vi t_vs t_WP t_WS t_xs t_ZH t_ZR 
+syn match   vimOption contained	"t_%1"
+syn match   vimOption contained	"t_#2"
+syn match   vimOption contained	"t_#4"
+syn match   vimOption contained	"t_@7"
+syn match   vimOption contained	"t_*7"
+syn match   vimOption contained	"t_&8"
+syn match   vimOption contained	"t_%i"
+syn match   vimOption contained	"t_k;"
+
+" unsupported settings: these are supported by vi but don't do anything in vim {{{2
+syn keyword vimErrSetting contained	hardtabs ht w1200 w300 w9600 
+
+" AutoCmd Events {{{2
+syn case ignore
+syn keyword vimAutoEvent contained	BufAdd BufCreate BufDelete BufEnter BufFilePost BufFilePre BufHidden BufLeave BufNew BufNewFile BufRead BufReadCmd BufReadPost BufReadPre BufUnload BufWinEnter BufWinLeave BufWipeout BufWrite BufWriteCmd BufWritePost BufWritePre Cmd-event CmdwinEnter CmdwinLeave ColorScheme CursorHold CursorHoldI CursorMoved CursorMovedI EncodingChanged FileAppendCmd FileAppendPost FileAppendPre FileChangedRO FileChangedShell FileChangedShellPost FileEncoding FileReadCmd FileReadPost FileReadPre FileType FileWriteCmd FileWritePost FileWritePre FilterReadPost FilterReadPre FilterWritePost FilterWritePre FocusGained FocusLost FuncUndefined GUIEnter GUIFailed InsertChange InsertEnter InsertLeave MenuPopup QuickFixCmdPost QuickFixCmdPre RemoteReply SessionLoadPost ShellCmdPost ShellFilterPost SourceCmd SourcePre SpellFileMissing StdinReadPost StdinReadPre SwapExists Syntax TabEnter TabLeave TermChanged TermResponse User UserGettingBored VimEnter VimLeave VimLeavePre VimResized WinEnter WinLeave 
+
+" Highlight commonly used Groupnames {{{2
+syn keyword vimGroup contained	Comment Constant String Character Number Boolean Float Identifier Function Statement Conditional Repeat Label Operator Keyword Exception PreProc Include Define Macro PreCondit Type StorageClass Structure Typedef Special SpecialChar Tag Delimiter SpecialComment Debug Underlined Ignore Error Todo 
+
+" Default highlighting groups {{{2
+syn keyword vimHLGroup contained	Cursor CursorColumn CursorIM CursorLine DiffAdd DiffChange DiffDelete DiffText Directory ErrorMsg FoldColumn Folded IncSearch LineNr MatchParen Menu ModeMsg MoreMsg NonText Normal Pmenu PmenuSbar PmenuSel PmenuThumb Question Scrollbar Search SignColumn SpecialKey SpellBad SpellCap SpellLocal SpellRare StatusLine StatusLineNC TabLine TabLineFill TabLineSel Title Tooltip VertSplit Visual VisualNOS WarningMsg WildMenu 
+syn match vimHLGroup contained	"Conceal"
+syn case match
+
+" Function Names {{{2
+syn keyword vimFuncName contained	add append argc argidx argv browse browsedir bufexists buflisted bufloaded bufname bufnr bufwinnr byte2line byteidx call changenr char2nr cindent col complete complete_add complete_check confirm copy count cscope_connection cursor deepcopy delete did_filetype diff_filler diff_hlID empty escape eval eventhandler executable exists expand expr8 extend feedkeys filereadable filewritable filter finddir findfile fnamemodify foldclosed foldclosedend foldlevel foldtext foldtextresult foreground function garbagecollect get getbufline getbufvar getchar getcharmod getcmdline getcmdpos getcmdtype getcwd getfontname getfperm getfsize getftime getftype getline getloclist getpos getqflist getreg getregtype gettabwinvar getwinposx getwinposy getwinvar glob globpath has has_key haslocaldir hasmapto histadd histdel histget histnr hlexists hlID hostname iconv indent index input inputdialog inputlist inputrestore inputsave inputsecret insert isdirectory islocked items join keys len libcall libcallnr line line2byte lispindent localtime map maparg mapcheck match matcharg matchend matchlist matchstr max min mkdir mode nextnonblank nr2char pathshorten prevnonblank printf pumvisible range readfile reltime reltimestr remote_expr remote_foreground remote_peek remote_read remote_send remove rename repeat resolve reverse search searchdecl searchpair searchpairpos searchpos server2client serverlist setbufvar setcmdpos setline setloclist setpos setqflist setreg settabwinvar setwinvar shellescape simplify sort soundfold spellbadword spellsuggest split str2nr strftime stridx string strlen strpart strridx strtrans submatch substitute synID synIDattr synIDtrans system tabpagebuflist tabpagenr tabpagewinnr tagfiles taglist tempname tolower toupper tr type values virtcol visualmode winbufnr wincol winheight winline winnr winrestcmd winrestview winsaveview winwidth writefile 
+
+"--- syntax above generated by mkvimvim ---
+" Special Vim Highlighting (not automatic) {{{1
+
+" Numbers {{{2
+" =======
+syn match vimNumber	"\<\d\+\([lL]\|\.\d\+\)\="
+syn match vimNumber	"-\d\+\([lL]\|\.\d\+\)\="
+syn match vimNumber	"\<0[xX]\x\+"
+syn match vimNumber	"#\x\{6}"
+
+" All vimCommands are contained by vimIsCommands. {{{2
+syn match vimCmdSep	"[:|]\+"	skipwhite nextgroup=vimAddress,vimAutoCmd,vimCommand,vimExtCmd,vimFilter,vimLet,vimMap,vimMark,vimSet,vimSyntax,vimUserCmd
+syn match vimIsCommand	"\<\h\w*\>"	contains=vimCommand
+syn match vimVar		"\<[bwglsav]:\K\k*\>"
+syn match vimVar contained	"\<\K\k*\>"
+syn keyword vimCommand contained	in
+
+" Insertions And Appends: insert append {{{2
+" =======================
+syn region vimInsert	matchgroup=vimCommand start="^[: \t]*\(\d\+\(,\d\+\)\=\)\=a\%[ppend]$"	matchgroup=vimCommand end="^\.$""
+syn region vimInsert	matchgroup=vimCommand start="^[: \t]*\(\d\+\(,\d\+\)\=\)\=c\%[hange]$"	matchgroup=vimCommand end="^\.$""
+syn region vimInsert	matchgroup=vimCommand start="^[: \t]*\(\d\+\(,\d\+\)\=\)\=i\%[nsert]$"	matchgroup=vimCommand end="^\.$""
+
+" Behave! {{{2
+" =======
+syn match   vimBehave	"\<be\%[have]\>" skipwhite nextgroup=vimBehaveModel,vimBehaveError
+syn keyword vimBehaveModel contained	mswin	xterm
+if !exists("g:vimsyntax_noerror")
+ syn match   vimBehaveError contained	"[^ ]\+"
+endif
+
+" Filetypes {{{2
+" =========
+syn match   vimFiletype	"\<filet\%[ype]\(\s\+\I\i*\)*"	skipwhite contains=vimFTCmd,vimFTOption,vimFTError
+if !exists("g:vimsyntax_noerror")
+ syn match   vimFTError  contained	"\I\i*"
+endif
+syn keyword vimFTCmd    contained	filet[ype]
+syn keyword vimFTOption contained	detect indent off on plugin
+
+" Augroup : vimAugroupError removed because long augroups caused sync'ing problems. {{{2
+" ======= : Trade-off: Increasing synclines with slower editing vs augroup END error checking.
+syn cluster vimAugroupList	contains=vimIsCommand,vimFunction,vimFunctionError,vimLineComment,vimSpecFile,vimOper,vimNumber,vimComment,vimString,vimSubst,vimMark,vimRegister,vimAddress,vimFilter,vimCmplxRepeat,vimComment,vimLet,vimSet,vimAutoCmd,vimRegion,vimSynLine,vimNotation,vimCtrlChar,vimFuncVar,vimContinue
+syn region  vimAugroup	start="\<aug\%[roup]\>\s\+\K\k*" end="\<aug\%[roup]\>\s\+[eE][nN][dD]\>"	contains=vimAugroupKey,vimAutoCmd,@vimAugroupList keepend
+syn match   vimAugroup	"aug\%[roup]!" contains=vimAugroupKey
+if !exists("g:vimsyntax_noerror")
+ syn match   vimAugroupError	"\<aug\%[roup]\>\s\+[eE][nN][dD]\>"
+endif
+syn keyword vimAugroupKey contained	aug[roup]
+
+" Functions : Tag is provided for those who wish to highlight tagged functions {{{2
+" =========
+syn cluster vimFuncList	contains=vimCommand,vimFuncKey,Tag,vimFuncSID
+syn cluster vimFuncBodyList	contains=vimIsCommand,vimFunction,vimFunctionError,vimFuncBody,vimLineComment,vimSpecFile,vimOper,vimNumber,vimComment,vimString,vimSubst,vimMark,vimRegister,vimAddress,vimFilter,vimCmplxRepeat,vimComment,vimLet,vimSet,vimAutoCmd,vimRegion,vimSynLine,vimNotation,vimCtrlChar,vimFuncVar,vimContinue
+if !exists("g:vimsyntax_noerror")
+ syn match   vimFunctionError	"\<fu\%[nction]!\=\s\+\zs\U\i\{-}\ze\s*("                	contains=vimFuncKey,vimFuncBlank nextgroup=vimFuncBody
+endif
+syn match   vimFunction	"\<fu\%[nction]!\=\s\+\(\(<[sS][iI][dD]>\|[Ss]:\|\u\)\i*\|g:\(\I\i*\.\)\+\I\i*\)\ze\s*("	contains=@vimFuncList nextgroup=vimFuncBody
+syn region  vimFuncBody  contained	start=")"	end="\<endf\%[unction]"		contains=@vimFuncBodyList
+syn match   vimFuncVar   contained	"a:\(\I\i*\|\d\+\)"
+syn match   vimFuncSID   contained	"\c<sid>\|\<s:"
+syn keyword vimFuncKey   contained	fu[nction]
+syn match   vimFuncBlank contained	"\s\+"
+
+syn keyword vimPattern   contained	start	skip	end
+
+" Operators: {{{2
+" =========
+syn cluster vimOperGroup	contains=vimOper,vimOperParen,vimNumber,vimString,vimRegister,vimContinue
+syn match  vimOper	"\(==\|!=\|>=\|<=\|=\~\|!\~\|>\|<\|=\)[?#]\{0,2}"	skipwhite nextgroup=vimString,vimSpecFile
+syn match  vimOper	"||\|&&\|[-+.]"	skipwhite nextgroup=vimString,vimSpecFile
+syn region vimOperParen 	oneline matchgroup=vimOper start="(" end=")" contains=@vimOperGroup
+syn region vimOperParen	oneline matchgroup=vimSep  start="{" end="}" contains=@vimOperGroup nextgroup=vimVar
+if !exists("g:vimsyntax_noerror")
+ syn match  vimOperError	")"
+endif
+
+" Special Filenames, Modifiers, Extension Removal: {{{2
+" ===============================================
+syn match vimSpecFile	"<c\(word\|WORD\)>"	nextgroup=vimSpecFileMod,vimSubst
+syn match vimSpecFile	"<\([acs]file\|amatch\|abuf\)>"	nextgroup=vimSpecFileMod,vimSubst
+syn match vimSpecFile	"\s%[ \t:]"ms=s+1,me=e-1	nextgroup=vimSpecFileMod,vimSubst
+syn match vimSpecFile	"\s%$"ms=s+1	nextgroup=vimSpecFileMod,vimSubst
+syn match vimSpecFile	"\s%<"ms=s+1,me=e-1	nextgroup=vimSpecFileMod,vimSubst
+syn match vimSpecFile	"#\d\+\|[#%]<\>"	nextgroup=vimSpecFileMod,vimSubst
+syn match vimSpecFileMod	"\(:[phtre]\)\+"	contained
+
+" User-Specified Commands: {{{2
+" =======================
+syn cluster vimUserCmdList	contains=vimAddress,vimSyntax,vimHighlight,vimAutoCmd,vimCmplxRepeat,vimComment,vimCtrlChar,vimEscapeBrace,vimFilter,vimFunc,vimFunction,vimIsCommand,vimMark,vimNotation,vimNumber,vimOper,vimRegion,vimRegister,vimLet,vimSet,vimSetEqual,vimSetString,vimSpecFile,vimString,vimSubst,vimSubstRep,vimSubstRange,vimSynLine
+syn keyword vimUserCommand	contained	com[mand]
+syn match   vimUserCmd	"\<com\%[mand]!\=\>.*$"	contains=vimUserAttrb,vimUserCommand,@vimUserCmdList
+syn match   vimUserAttrb	contained	"-n\%[args]=[01*?+]"	contains=vimUserAttrbKey,vimOper
+syn match   vimUserAttrb	contained	"-com\%[plete]="	contains=vimUserAttrbKey,vimOper nextgroup=vimUserAttrbCmplt,vimUserCmdError
+syn match   vimUserAttrb	contained	"-ra\%[nge]\(=%\|=\d\+\)\="	contains=vimNumber,vimOper,vimUserAttrbKey
+syn match   vimUserAttrb	contained	"-cou\%[nt]=\d\+"	contains=vimNumber,vimOper,vimUserAttrbKey
+syn match   vimUserAttrb	contained	"-bang\=\>"	contains=vimOper,vimUserAttrbKey
+syn match   vimUserAttrb	contained	"-bar\>"	contains=vimOper,vimUserAttrbKey
+syn match   vimUserAttrb	contained	"-re\%[gister]\>"	contains=vimOper,vimUserAttrbKey
+if !exists("g:vimsyntax_noerror")
+ syn match   vimUserCmdError	contained	"\S\+\>"
+endif
+syn case ignore
+syn keyword vimUserAttrbKey   contained	bar	ban[g]	cou[nt]	ra[nge] com[plete]	n[args]	re[gister]
+syn keyword vimUserAttrbCmplt contained	augroup buffer command dir environment event expression file function help highlight mapping menu option something tag tag_listfiles var
+syn keyword vimUserAttrbCmplt contained	custom customlist nextgroup=vimUserAttrbCmpltFunc,vimUserCmdError
+syn match   vimUserAttrbCmpltFunc contained	",\%([sS]:\|<[sS][iI][dD]>\)\=\%(\h\w*\%(#\u\w*\)\+\|\u\w*\)"hs=s+1 nextgroup=vimUserCmdError
+
+syn case match
+syn match   vimUserAttrbCmplt contained	"custom,\u\w*"
+
+" Errors: {{{2
+" ======
+if !exists("g:vimsyntax_noerror")
+ syn match  vimElseIfErr	"\<else\s\+if\>"
+endif
+
+" Lower Priority Comments: after some vim commands... {{{2
+" =======================
+syn match  vimComment	excludenl +\s"[^\-:.%#=*].*$+lc=1	contains=@vimCommentGroup,vimCommentString
+syn match  vimComment	+\<endif\s\+".*$+lc=5	contains=@vimCommentGroup,vimCommentString
+syn match  vimComment	+\<else\s\+".*$+lc=4	contains=@vimCommentGroup,vimCommentString
+syn region vimCommentString	contained oneline start='\S\s\+"'ms=e	end='"'
+
+" Environment Variables: {{{2
+" =====================
+syn match vimEnvvar	"\$\I\i*"
+syn match vimEnvvar	"\${\I\i*}"
+
+" In-String Specials: {{{2
+" Try to catch strings, if nothing else matches (therefore it must precede the others!)
+"  vimEscapeBrace handles ["]  []"] (ie. "s don't terminate string inside [])
+syn region vimEscapeBrace	oneline   contained transparent start="[^\\]\(\\\\\)*\[\zs\^\=\]\=" skip="\\\\\|\\\]" end="]"me=e-1
+syn match  vimPatSepErr	contained	"\\)"
+syn match  vimPatSep	contained	"\\|"
+syn region vimPatSepZone	oneline   contained   matchgroup=vimPatSepZ start="\\%\=\ze(" skip="\\\\" end="\\)\|[^\]['"]"	contains=@vimStringGroup
+syn region vimPatRegion	contained transparent matchgroup=vimPatSepR start="\\[z%]\=(" end="\\)"	contains=@vimSubstList oneline
+syn match  vimNotPatSep	contained	"\\\\"
+syn cluster vimStringGroup	contains=vimEscapeBrace,vimPatSep,vimNotPatSep,vimPatSepErr,vimPatSepZone,@Spell
+syn region vimString	oneline keepend	start=+[^:a-zA-Z>!\\@]"+lc=1 skip=+\\\\\|\\"+ end=+"+	contains=@vimStringGroup
+syn region vimString	oneline keepend	start=+[^:a-zA-Z>!\\@]'+lc=1 end=+'+
+syn region vimString	oneline	start=+=!+lc=1	skip=+\\\\\|\\!+ end=+!+	contains=@vimStringGroup
+syn region vimString	oneline	start="=+"lc=1	skip="\\\\\|\\+" end="+"	contains=@vimStringGroup
+syn region vimString	oneline	start="\s/\s*\A"lc=1 skip="\\\\\|\\+" end="/"	contains=@vimStringGroup
+syn match  vimString	contained	+"[^"]*\\$+	skipnl nextgroup=vimStringCont
+syn match  vimStringCont	contained	+\(\\\\\|.\)\{-}[^\\]"+
+
+" Substitutions: {{{2
+" =============
+syn cluster vimSubstList	contains=vimPatSep,vimPatRegion,vimPatSepErr,vimSubstTwoBS,vimSubstRange,vimNotation
+syn cluster vimSubstRepList	contains=vimSubstSubstr,vimSubstTwoBS,vimNotation
+syn cluster vimSubstList	add=vimCollection
+syn match   vimSubst	"\(:\+\s*\|^\s*\||\s*\)\<s\%[ubstitute][:[:alpha:]]\@!" nextgroup=vimSubstPat
+syn match   vimSubst	"s\%[ubstitute][:[:alpha:]]\@!"	nextgroup=vimSubstPat contained
+syn match   vimSubst	"/\zss\%[ubstitute]\ze/"	nextgroup=vimSubstPat
+syn match   vimSubst1       contained	"s\%[ubstitute]\>"	nextgroup=vimSubstPat
+syn region  vimSubstPat     contained	matchgroup=vimSubstDelim start="\z([^a-zA-Z( \t[\]&]\)"rs=s+1 skip="\\\\\|\\\z1" end="\z1"re=e-1,me=e-1	 contains=@vimSubstList	nextgroup=vimSubstRep4	oneline
+syn region  vimSubstRep4    contained	matchgroup=vimSubstDelim start="\z(.\)" skip="\\\\\|\\\z1" end="\z1" matchgroup=vimNotation end="<[cC][rR]>" contains=@vimSubstRepList	nextgroup=vimSubstFlagErr	oneline
+syn region  vimCollection   contained transparent	start="\\\@<!\[" skip="\\\[" end="\]"	contains=vimCollClass
+syn match   vimCollClassErr contained	"\[:.\{-\}:\]"
+syn match   vimCollClass    contained transparent	"\[:\(alnum\|alpha\|blank\|cntrl\|digit\|graph\|lower\|print\|punct\|space\|upper\|xdigit\|return\|tab\|escape\|backspace\):\]"
+syn match   vimSubstSubstr  contained	"\\z\=\d"
+syn match   vimSubstTwoBS   contained	"\\\\"
+syn match   vimSubstFlagErr contained	"[^< \t\r|]\+" contains=vimSubstFlags
+syn match   vimSubstFlags   contained	"[&cegiIpr]\+"
+
+" 'String': {{{2
+syn match  vimString	"[^(,]'[^']\{-}\zs'"
+
+" Marks, Registers, Addresses, Filters: {{{2
+syn match  vimMark	"'[a-zA-Z0-9]\ze[-+,!]"	nextgroup=vimOper,vimMarkNumber,vimSubst
+syn match  vimMark	"'[<>]\ze[-+,!]"		nextgroup=vimOper,vimMarkNumber,vimSubst
+syn match  vimMark	",\zs'[<>]\ze"		nextgroup=vimOper,vimMarkNumber,vimSubst
+syn match  vimMark	"[!,:]\zs'[a-zA-Z0-9]"	nextgroup=vimOper,vimMarkNumber,vimSubst
+syn match  vimMark	"\<norm\%[al]\s\zs'[a-zA-Z0-9]"	nextgroup=vimOper,vimMarkNumber,vimSubst
+syn match  vimMarkNumber	"[-+]\d\+"		nextgroup=vimSubst contained contains=vimOper
+syn match  vimPlainMark contained	"'[a-zA-Z0-9]"
+
+syn match  vimRegister	'[^,;]\zs"[a-zA-Z0-9.%#:_\-/]\ze[^a-zA-Z_":]'
+syn match  vimRegister	'\<norm\s\+\zs"[a-zA-Z0-9]'
+syn match  vimRegister	'\<normal\s\+\zs"[a-zA-Z0-9]'
+syn match  vimRegister	'@"'
+syn match  vimPlainRegister contained	'"[a-zA-Z0-9\-:.%#*+=]'
+
+syn match  vimAddress	",\zs[.$]"	skipwhite nextgroup=vimSubst1
+syn match  vimAddress	"%\ze\a"	skipwhite nextgroup=vimString,vimSubst1
+
+syn match  vimFilter contained	"^!.\{-}\(|\|$\)"		contains=vimSpecFile
+syn match  vimFilter contained	"\A!.\{-}\(|\|$\)"ms=s+1	contains=vimSpecFile
+
+" Complex repeats (:h complex-repeat) {{{2
+"syn match  vimCmplxRepeat	'[^a-zA-Z_/\\()]q[0-9a-zA-Z"]'lc=1
+"syn match  vimCmplxRepeat	'@[0-9a-z".=@:]\ze\($\|[^a-zA-Z]\)'
+
+" Set command and associated set-options (vimOptions) with comment {{{2
+syn region vimSet		matchgroup=vimCommand start="\<\%(setl\%[ocal]\|setg\%[lobal]\|set\)\>" skip="\%(\\\\\)*\\." end="$" matchgroup=vimNotation end="<[cC][rR]>" keepend oneline contains=vimSetEqual,vimOption,vimErrSetting,vimComment,vimSetString,vimSetMod
+syn region vimSetEqual  contained	start="="	skip="\\\\\|\\\s" end="[| \t]\|$"me=e-1 contains=vimCtrlChar,vimSetSep,vimNotation oneline
+syn region vimSetString contained	start=+="+hs=s+1	skip=+\\\\\|\\"+  end=+"+	contains=vimCtrlChar
+syn match  vimSetSep    contained	"[,:]"
+syn match  vimSetMod	contained	"&vim\|[!&]\|all&"
+
+" Let {{{2
+" ===
+syn keyword vimLet	let	unl[et]	skipwhite nextgroup=vimVar
+
+" Autocmd {{{2
+" =======
+syn match   vimAutoEventList	contained	"\(!\s\+\)\=\(\a\+,\)*\a\+"	contains=vimAutoEvent nextgroup=vimAutoCmdSpace
+syn match   vimAutoCmdSpace	contained	"\s\+"	nextgroup=vimAutoCmdSfxList
+syn match   vimAutoCmdSfxList	contained	"\S*"
+syn keyword vimAutoCmd	au[tocmd] do[autocmd] doautoa[ll]	skipwhite nextgroup=vimAutoEventList
+
+" Echo and Execute -- prefer strings! {{{2
+" ================
+syn region  vimEcho	oneline excludenl matchgroup=vimCommand start="\<ec\%[ho]\>" skip="\(\\\\\)*\\|" end="$\||" contains=vimFunc,vimString,varVar
+syn region  vimExecute	oneline excludenl matchgroup=vimCommand start="\<exe\%[cute]\>" skip="\(\\\\\)*\\|" end="$\||\|<[cC][rR]>" contains=vimIsCommand,vimString,vimOper,vimVar,vimNotation,vimOperParen
+syn match   vimEchoHL	"echohl\="	skipwhite nextgroup=vimGroup,vimHLGroup,vimEchoHLNone
+syn case ignore
+syn keyword vimEchoHLNone	none
+syn case match
+
+" Maps {{{2
+" ====
+syn match   vimMap	"\<map!\=\ze\s*[^(]" skipwhite nextgroup=vimMapMod,vimMapLhs
+syn keyword vimMap	cm[ap] cno[remap] im[ap] ino[remap] ln[oremap] nm[ap] nn[oremap] no[remap] om[ap] ono[remap] snor[emap] vm[ap] vn[oremap] xn[oremap] skipwhite nextgroup=vimMapBang,vimMapMod,vimMapLhs
+syn match   vimMapLhs    contained	"\S\+"	contains=vimNotation,vimCtrlChar skipwhite nextgroup=vimMapRhs
+syn match   vimMapBang   contained	"!"	skipwhite nextgroup=vimMapMod,vimMapLhs
+syn match   vimMapMod    contained	"\c<\(buffer\|expr\|\(local\)\=leader\|plug\|script\|sid\|unique\|silent\)\+>" contains=vimMapModKey,vimMapModErr skipwhite nextgroup=vimMapMod,vimMapLhs
+syn match   vimMapRhs    contained  ".*" contains=vimNotation,vimCtrlChar skipnl nextgroup=vimMapRhsExtend
+syn match   vimMapRhsExtend contained "^\s*\\.*$" contains=vimContinue
+syn case ignore
+syn keyword vimMapModKey contained	buffer	expr	leader	localleader	plug	script	sid	silent	unique
+syn case match
+
+" Menus {{{2
+" =====
+syn cluster vimMenuList contains=vimMenuBang,vimMenuPriority,vimMenuName,vimMenuMod
+syn keyword vimCommand	am[enu] an[oremenu] aun[menu] cme[nu] cnoreme[nu] cunme[nu] ime[nu] inoreme[nu] iunme[nu] me[nu] nme[nu] nnoreme[nu] noreme[nu] nunme[nu] ome[nu] onoreme[nu] ounme[nu] unme[nu] vme[nu] vnoreme[nu] vunme[nu] skipwhite nextgroup=@vimMenuList
+syn match   vimMenuName	"[^ \t\\<]\+"	contained nextgroup=vimMenuNameMore,vimMenuMap
+syn match   vimMenuPriority	"\d\+\(\.\d\+\)*"	contained skipwhite nextgroup=vimMenuName
+syn match   vimMenuNameMore	"\c\\\s\|<tab>\|\\\."	contained nextgroup=vimMenuName,vimMenuNameMore contains=vimNotation
+syn match   vimMenuMod    contained	"\c<\(script\|silent\)\+>"  skipwhite contains=vimMapModKey,vimMapModErr nextgroup=@vimMenuList
+syn match   vimMenuMap	"\s"	contained skipwhite nextgroup=vimMenuRhs
+syn match   vimMenuRhs	".*$"	contained contains=vimString,vimComment,vimIsCommand
+syn match   vimMenuBang	"!"	contained skipwhite nextgroup=@vimMenuList
+
+" Angle-Bracket Notation (tnx to Michael Geddes) {{{2
+" ======================
+syn case ignore
+syn match vimNotation	"\(\\\|<lt>\)\=<\([scamd]-\)\{0,4}x\=\(f\d\{1,2}\|[^ \t:]\|cr\|lf\|linefeed\|return\|k\=del\%[ete]\|bs\|backspace\|tab\|esc\|right\|left\|help\|undo\|insert\|ins\|k\=home\|k\=end\|kplus\|kminus\|kdivide\|kmultiply\|kenter\|space\|k\=\(page\)\=\(\|down\|up\)\)>" contains=vimBracket
+syn match vimNotation	"\(\\\|<lt>\)\=<\([scam2-4]-\)\{0,4}\(right\|left\|middle\)\(mouse\)\=\(drag\|release\)\=>"	contains=vimBracket
+syn match vimNotation	"\(\\\|<lt>\)\=<\(bslash\|plug\|sid\|space\|bar\|nop\|nul\|lt\)>"		contains=vimBracket
+syn match vimNotation	'\(\\\|<lt>\)\=<C-R>[0-9a-z"%#:.\-=]'he=e-1			contains=vimBracket
+syn match vimNotation	'\(\\\|<lt>\)\=<\%(q-\)\=\(line[12]\|count\|bang\|reg\|args\|f-args\|lt\)>'	contains=vimBracket
+syn match vimNotation	"\(\\\|<lt>\)\=<\([cas]file\|abuf\|amatch\|cword\|cWORD\|client\)>"		contains=vimBracket
+syn match vimBracket contained	"[\\<>]"
+syn case match
+
+" User Function Highlighting (following Gautam Iyer's suggestion) {{{2
+" ==========================
+syn match vimFunc		"\%(\%([gGsS]:\|<[sS][iI][dD]>\)\=\%([a-zA-Z0-9.]\+\.\)*\I[a-zA-Z0-9.]*\)\ze\s*("		contains=vimFuncName,vimUserFunc,vimExecute
+syn match vimUserFunc contained	"\%(\%([gGsS]:\|<[sS][iI][dD]>\)\=\%([a-zA-Z0-9.]\+\.\)*\I[a-zA-Z0-9.]*\)\|\<\u[a-zA-Z0-9.]*\>\|\<if\>"	contains=vimNotation
+syn match vimNotFunc	"\<if\>\|\<el\%[seif]\>"
+
+" Norm
+" ====
+syn match vimNorm		"\<norm\%[al]!\=" skipwhite nextgroup=vimNormCmds
+syn match vimNormCmds contained	".*$"
+
+" Syntax {{{2
+"=======
+syn match   vimGroupList	contained	"@\=[^ \t,]*"	contains=vimGroupSpecial,vimPatSep
+syn match   vimGroupList	contained	"@\=[^ \t,]*,"	nextgroup=vimGroupList contains=vimGroupSpecial,vimPatSep
+syn keyword vimGroupSpecial	contained	ALL	ALLBUT
+if !exists("g:vimsyntax_noerror")
+ syn match   vimSynError	contained	"\i\+"
+ syn match   vimSynError	contained	"\i\+="	nextgroup=vimGroupList
+endif
+syn match   vimSynContains	contained	"\<contain\(s\|edin\)="	nextgroup=vimGroupList
+syn match   vimSynKeyContainedin	contained	"\<containedin="	nextgroup=vimGroupList
+syn match   vimSynNextgroup	contained	"nextgroup="	nextgroup=vimGroupList
+
+syn match   vimSyntax	"\<sy\%[ntax]\>"	contains=vimCommand skipwhite nextgroup=vimSynType,vimComment
+syn match   vimAuSyntax	contained	"\s+sy\%[ntax]"	contains=vimCommand skipwhite nextgroup=vimSynType,vimComment
+
+" Syntax: case {{{2
+syn keyword vimSynType	contained	case	skipwhite nextgroup=vimSynCase,vimSynCaseError
+if !exists("g:vimsyntax_noerror")
+ syn match   vimSynCaseError	contained	"\i\+"
+endif
+syn keyword vimSynCase	contained	ignore	match
+
+" Syntax: clear {{{2
+syn keyword vimSynType	contained	clear	skipwhite nextgroup=vimGroupList
+
+" Syntax: cluster {{{2
+syn keyword vimSynType	contained	cluster	skipwhite nextgroup=vimClusterName
+syn region  vimClusterName	contained	matchgroup=vimGroupName start="\k\+" skip="\\\\\|\\|" matchgroup=vimSep end="$\||" contains=vimGroupAdd,vimGroupRem,vimSynContains,vimSynError
+syn match   vimGroupAdd	contained	"add="	nextgroup=vimGroupList
+syn match   vimGroupRem	contained	"remove="	nextgroup=vimGroupList
+
+" Syntax: include {{{2
+syn keyword vimSynType	contained	include	skipwhite nextgroup=vimGroupList
+
+" Syntax: keyword {{{2
+syn cluster vimSynKeyGroup	contains=vimSynNextgroup,vimSynKeyOpt,vimSynKeyContainedin
+syn keyword vimSynType	contained	keyword	skipwhite nextgroup=vimSynKeyRegion
+syn region  vimSynKeyRegion	contained keepend	matchgroup=vimGroupName start="\k\+" skip="\\\\\|\\|" matchgroup=vimSep end="|\|$" contains=@vimSynKeyGroup
+syn match   vimSynKeyOpt	contained	"\<\(conceal\|contained\|transparent\|skipempty\|skipwhite\|skipnl\)\>"
+
+" Syntax: match {{{2
+syn cluster vimSynMtchGroup	contains=vimMtchComment,vimSynContains,vimSynError,vimSynMtchOpt,vimSynNextgroup,vimSynRegPat,vimNotation
+syn keyword vimSynType	contained	match	skipwhite nextgroup=vimSynMatchRegion
+syn region  vimSynMatchRegion	contained keepend	matchgroup=vimGroupName start="\k\+" matchgroup=vimSep end="|\|$" contains=@vimSynMtchGroup
+syn match   vimSynMtchOpt	contained	"\<\(conceal\|transparent\|contained\|excludenl\|skipempty\|skipwhite\|display\|extend\|skipnl\|fold\)\>"
+if has("conceal")
+ syn match   vimSynMtchOpt	contained	"\<cchar="	nextgroup=VimSynMtchCchar
+ syn match   vimSynMtchCchar	contained	"."
+endif
+
+" Syntax: off and on {{{2
+syn keyword vimSynType	contained	enable	list	manual	off	on	reset
+
+" Syntax: region {{{2
+syn cluster vimSynRegPatGroup	contains=vimPatSep,vimNotPatSep,vimSynPatRange,vimSynNotPatRange,vimSubstSubstr,vimPatRegion,vimPatSepErr,vimNotation
+syn cluster vimSynRegGroup	contains=vimSynContains,vimSynNextgroup,vimSynRegOpt,vimSynReg,vimSynMtchGrp
+syn keyword vimSynType	contained	region	skipwhite nextgroup=vimSynRegion
+syn region  vimSynRegion	contained keepend	matchgroup=vimGroupName start="\k\+" skip="\\\\\|\\|" end="|\|$" contains=@vimSynRegGroup
+syn match   vimSynRegOpt	contained	"\<\(conceal\(ends\)\=\|transparent\|contained\|excludenl\|skipempty\|skipwhite\|display\|keepend\|oneline\|extend\|skipnl\|fold\)\>"
+syn match   vimSynReg	contained	"\(start\|skip\|end\)="he=e-1	nextgroup=vimSynRegPat
+syn match   vimSynMtchGrp	contained	"matchgroup="	nextgroup=vimGroup,vimHLGroup
+syn region  vimSynRegPat	contained extend	start="\z([-`~!@#$%^&*_=+;:'",./?]\)"  skip="\\\\\|\\\z1"  end="\z1"  contains=@vimSynRegPatGroup skipwhite nextgroup=vimSynPatMod,vimSynReg
+syn match   vimSynPatMod	contained	"\(hs\|ms\|me\|hs\|he\|rs\|re\)=[se]\([-+]\d\+\)\="
+syn match   vimSynPatMod	contained	"\(hs\|ms\|me\|hs\|he\|rs\|re\)=[se]\([-+]\d\+\)\=," nextgroup=vimSynPatMod
+syn match   vimSynPatMod	contained	"lc=\d\+"
+syn match   vimSynPatMod	contained	"lc=\d\+," nextgroup=vimSynPatMod
+syn region  vimSynPatRange	contained	start="\["	skip="\\\\\|\\]"   end="]"
+syn match   vimSynNotPatRange	contained	"\\\\\|\\\["
+syn match   vimMtchComment	contained	'"[^"]\+$'
+
+" Syntax: sync {{{2
+" ============
+syn keyword vimSynType	contained	sync	skipwhite	nextgroup=vimSyncC,vimSyncLines,vimSyncMatch,vimSyncError,vimSyncLinebreak,vimSyncLinecont,vimSyncRegion
+if !exists("g:vimsyntax_noerror")
+ syn match   vimSyncError	contained	"\i\+"
+endif
+syn keyword vimSyncC	contained	ccomment	clear	fromstart
+syn keyword vimSyncMatch	contained	match	skipwhite	nextgroup=vimSyncGroupName
+syn keyword vimSyncRegion	contained	region	skipwhite	nextgroup=vimSynReg
+syn match   vimSyncLinebreak	contained	"\<linebreaks="	skipwhite	nextgroup=vimNumber
+syn keyword vimSyncLinecont	contained	linecont	skipwhite	nextgroup=vimSynRegPat
+syn match   vimSyncLines	contained	"\(min\|max\)\=lines="	nextgroup=vimNumber
+syn match   vimSyncGroupName	contained	"\k\+"	skipwhite	nextgroup=vimSyncKey
+syn match   vimSyncKey	contained	"\<groupthere\|grouphere\>"	skipwhite nextgroup=vimSyncGroup
+syn match   vimSyncGroup	contained	"\k\+"	skipwhite	nextgroup=vimSynRegPat,vimSyncNone
+syn keyword vimSyncNone	contained	NONE
+
+" Additional IsCommand, here by reasons of precedence {{{2
+" ====================
+syn match vimIsCommand	"<Bar>\s*\a\+"	transparent contains=vimCommand,vimNotation
+
+" Highlighting {{{2
+" ============
+syn cluster vimHighlightCluster	contains=vimHiLink,vimHiClear,vimHiKeyList,vimComment
+syn match   vimHighlight	"\<hi\%[ghlight]\>" skipwhite nextgroup=vimHiBang,@vimHighlightCluster
+syn match   vimHiBang	contained	"!"	  skipwhite nextgroup=@vimHighlightCluster
+
+syn match   vimHiGroup	contained	"\i\+"
+syn case ignore
+syn keyword vimHiAttrib	contained	none bold inverse italic reverse standout underline undercurl
+syn keyword vimFgBgAttrib	contained	none bg background fg foreground
+syn case match
+syn match   vimHiAttribList	contained	"\i\+"	contains=vimHiAttrib
+syn match   vimHiAttribList	contained	"\i\+,"he=e-1	contains=vimHiAttrib nextgroup=vimHiAttribList
+syn case ignore
+syn keyword vimHiCtermColor	contained	black blue brown cyan darkBlue darkcyan darkgray darkgreen darkgrey darkmagenta darkred darkyellow gray green grey lightblue lightcyan lightgray lightgreen lightgrey lightmagenta lightred magenta red white yellow
+
+syn case match
+syn match   vimHiFontname	contained	"[a-zA-Z\-*]\+"
+syn match   vimHiGuiFontname	contained	"'[a-zA-Z\-* ]\+'"
+syn match   vimHiGuiRgb	contained	"#\x\{6}"
+if !exists("g:vimsyntax_noerror")
+ syn match   vimHiCtermError	contained	"[^0-9]\i*"
+endif
+
+" Highlighting: hi group key=arg ... {{{2
+syn cluster vimHiCluster contains=vimHiGroup,vimHiTerm,vimHiCTerm,vimHiStartStop,vimHiCtermFgBg,vimHiGui,vimHiGuiFont,vimHiGuiFgBg,vimHiKeyError,vimNotation
+syn region vimHiKeyList	contained oneline start="\i\+" skip="\\\\\|\\|" end="$\||"	contains=@vimHiCluster
+if !exists("g:vimsyntax_noerror")
+ syn match  vimHiKeyError	contained	"\i\+="he=e-1
+endif
+syn match  vimHiTerm	contained	"\cterm="he=e-1		nextgroup=vimHiAttribList
+syn match  vimHiStartStop	contained	"\c\(start\|stop\)="he=e-1	nextgroup=vimHiTermcap,vimOption
+syn match  vimHiCTerm	contained	"\ccterm="he=e-1		nextgroup=vimHiAttribList
+syn match  vimHiCtermFgBg	contained	"\ccterm[fb]g="he=e-1	nextgroup=vimNumber,vimHiCtermColor,vimFgBgAttrib,vimHiCtermError
+syn match  vimHiGui	contained	"\cgui="he=e-1		nextgroup=vimHiAttribList
+syn match  vimHiGuiFont	contained	"\cfont="he=e-1		nextgroup=vimHiFontname
+syn match  vimHiGuiFgBg	contained	"\cgui\%([fb]g\|sp\)="he=e-1	nextgroup=vimHiGroup,vimHiGuiFontname,vimHiGuiRgb,vimFgBgAttrib
+syn match  vimHiTermcap	contained	"\S\+"		contains=vimNotation
+
+" Highlight: clear {{{2
+syn keyword vimHiClear	contained	clear	nextgroup=vimHiGroup
+
+" Highlight: link {{{2
+syn region vimHiLink	contained oneline matchgroup=vimCommand start="\<\(def\s\+\)\=link\>\|\<def\>" end="$"	contains=vimHiGroup,vimGroup,vimHLGroup,vimNotation
+
+" Control Characters {{{2
+" ==================
+syn match vimCtrlChar	"[--]"
+
+" Beginners - Patterns that involve ^ {{{2
+" =========
+syn match  vimLineComment	+^[ \t:]*".*$+	contains=@vimCommentGroup,vimCommentString,vimCommentTitle
+syn match  vimCommentTitle	'"\s*\%([sS]:\|\h\w*#\)\=\u\w*\(\s\+\u\w*\)*:'hs=s+1	contained contains=vimCommentTitleLeader,vimTodo,@vimCommentGroup
+syn match  vimContinue	"^\s*\\"
+syn region vimString	start="^\s*\\\z(['"]\)" skip='\\\\\|\\\z1' end="\z1" oneline keepend contains=@vimStringGroup,vimContinue
+syn match  vimCommentTitleLeader	'"\s\+'ms=s+1	contained
+
+" Searches And Globals: {{{2
+" ====================
+syn match vimSearch	'^\s*[/?].*'		contains=vimSearchDelim
+syn match vimSearchDelim	'^\s*\zs[/?]\|[/?]$'	contained
+syn region vimGlobal	matchgroup=Statement start='\<g\%[lobal]!\=/' skip='\\.' end='/'
+syn region vimGlobal	matchgroup=Statement start='\<v\%[global]!\=/' skip='\\.' end='/'
+
+" Scripts  : perl,ruby : Benoit Cerrina {{{2
+" =======    python,tcl: Johannes Zellner
+
+" allow users to prevent embedded script syntax highlighting
+" when vim doesn't have perl/python/ruby/tcl support.  Do
+" so by setting g:vimembedscript= 0 in the user's <.vimrc>.
+if !exists("g:vimembedscript")
+ let g:vimembedscript= 1
+endif
+
+" [-- perl --] {{{3
+if (has("perl") || g:vimembedscript) && filereadable(expand("<sfile>:p:h")."/perl.vim")
+ unlet! b:current_syntax
+ syn include @vimPerlScript <sfile>:p:h/perl.vim
+ syn region vimPerlRegion matchgroup=vimScriptDelim start=+pe\%[rl]\s*<<\s*\z(.*\)$+ end=+^\z1$+ contains=@vimPerlScript
+ syn region vimPerlRegion matchgroup=vimScriptDelim start=+pe\%[rl]\s*<<\s*$+ end=+\.$+ contains=@vimPerlScript
+endif
+
+" [-- ruby --] {{{3
+if (has("ruby") || g:vimembedscript) && filereadable(expand("<sfile>:p:h")."/ruby.vim")
+ unlet! b:current_syntax
+ syn include @vimRubyScript <sfile>:p:h/ruby.vim
+ syn region vimRubyRegion matchgroup=vimScriptDelim start=+rub[y]\s*<<\s*\z(.*\)$+ end=+^\z1$+ contains=@vimRubyScript
+ syn region vimRubyRegion matchgroup=vimScriptDelim start=+rub[y]\s*<<\s*$+ end=+\.$+ contains=@vimRubyScript
+endif
+
+" [-- python --] {{{3
+if (has("python") || g:vimembedscript) && filereadable(expand("<sfile>:p:h")."/python.vim")
+ unlet! b:current_syntax
+ syn include @vimPythonScript <sfile>:p:h/python.vim
+ syn region vimPythonRegion matchgroup=vimScriptDelim start=+py\%[thon]\s*<<\s*\z(.*\)$+ end=+^\z1$+ contains=@vimPythonScript
+ syn region vimPythonRegion matchgroup=vimScriptDelim start=+py\%[thon]\s*<<\s*$+ end=+\.$+ contains=@vimPythonScript
+endif
+
+" [-- tcl --] {{{3
+if has("win32") || has("win95") || has("win64") || has("win16")
+ " apparently has("tcl") has been hanging vim on some windows systems with cygwin
+ let trytcl= (&shell !~ '\%(\<bash\>\|\<zsh\>\)\%(\.exe\)\=$') || g:vimembedscript
+else
+ let trytcl= 1
+endif
+if trytcl
+ if (has("tcl") || g:vimembedscript) && filereadable(expand("<sfile>:p:h")."/tcl.vim")
+  unlet! b:current_syntax
+  syn include @vimTclScript <sfile>:p:h/tcl.vim
+  syn region vimTclRegion matchgroup=vimScriptDelim start=+tc[l]\=\s*<<\s*\z(.*\)$+ end=+^\z1$+ contains=@vimTclScript
+  syn region vimTclRegion matchgroup=vimScriptDelim start=+tc[l]\=\s*<<\s*$+ end=+\.$+ contains=@vimTclScript
+ endif
+endif
+unlet trytcl
+
+" [-- mzscheme --] {{{3
+if (has("mzscheme") || g:vimembedscript) && filereadable(expand("<sfile>:p:h")."/scheme.vim")
+ unlet! b:current_syntax
+ let iskKeep= &isk
+ syn include @vimMzSchemeScript <sfile>:p:h/scheme.vim
+ let &isk= iskKeep
+ syn region vimMzSchemeRegion matchgroup=vimScriptDelim start=+mz\%[scheme]\s*<<\s*\z(.*\)$+ end=+^\z1$+ contains=@vimMzSchemeScript
+ syn region vimMzSchemeRegion matchgroup=vimScriptDelim start=+mz\%[scheme]\s*<<\s*$+ end=+\.$+ contains=@vimMzSchemeScript
+endif
+
+" Synchronize (speed) {{{2
+"============
+if exists("g:vim_minlines")
+ exe "syn sync minlines=".g:vim_minlines
+endif
+if exists("g:vim_maxlines")
+ exe "syn sync maxlines=".g:vim_maxlines
+else
+ syn sync maxlines=60
+endif
+syn sync linecont	"^\s\+\\"
+syn sync match vimAugroupSyncA	groupthere NONE	"\<aug\%[roup]\>\s\+[eE][nN][dD]"
+
+" Highlighting Settings {{{2
+" ====================
+
+hi def link vimAuHighlight	vimHighlight
+hi def link vimSubst1	vimSubst
+hi def link vimBehaveModel	vimBehave
+
+if !exists("g:vimsyntax_noerror")
+ hi def link vimBehaveError	vimError
+ hi def link vimCollClassErr	vimError
+ hi def link vimErrSetting	vimError
+ hi def link vimFTError	vimError
+ hi def link vimFunctionError	vimError
+ hi def link vimFunc         	vimError
+ hi def link vimHiAttribList	vimError
+ hi def link vimHiCtermError	vimError
+ hi def link vimHiKeyError	vimError
+ hi def link vimKeyCodeError	vimError
+ hi def link vimMapModErr	vimError
+ hi def link vimSubstFlagErr	vimError
+ hi def link vimSynCaseError	vimError
+endif
+
+hi def link vimAddress	vimMark
+hi def link vimAugroupKey	vimCommand
+hi def link vimAutoCmdOpt	vimOption
+hi def link vimAutoCmd	vimCommand
+hi def link vimAutoSet	vimCommand
+hi def link vimBehave	vimCommand
+hi def link vimCommentString	vimString
+hi def link vimCondHL	vimCommand
+hi def link vimEchoHLNone	vimGroup
+hi def link vimEchoHL	vimCommand
+hi def link vimElseif	vimCondHL
+hi def link vimFgBgAttrib	vimHiAttrib
+hi def link vimFTCmd	vimCommand
+hi def link vimFTOption	vimSynType
+hi def link vimFuncKey	vimCommand
+hi def link vimGroupAdd	vimSynOption
+hi def link vimGroupRem	vimSynOption
+hi def link vimHiCtermFgBg	vimHiTerm
+hi def link vimHiCTerm	vimHiTerm
+hi def link vimHighlight	vimCommand
+hi def link vimHiGroup	vimGroupName
+hi def link vimHiGuiFgBg	vimHiTerm
+hi def link vimHiGuiFont	vimHiTerm
+hi def link vimHiGuiRgb	vimNumber
+hi def link vimHiGui	vimHiTerm
+hi def link vimHiStartStop	vimHiTerm
+hi def link vimHLGroup	vimGroup
+hi def link vimInsert	vimString
+hi def link vimKeyCode	vimSpecFile
+hi def link vimLet	vimCommand
+hi def link vimLineComment	vimComment
+hi def link vimMapBang	vimCommand
+hi def link vimMapModKey	vimFuncSID
+hi def link vimMapMod	vimBracket
+hi def link vimMap	vimCommand
+hi def link vimMarkNumber	vimNumber
+hi def link vimMenuMod	vimMapMod
+hi def link vimMenuNameMore	vimMenuName
+hi def link vimMtchComment	vimComment
+hi def link vimNorm	vimCommand
+hi def link vimNotPatSep	vimString
+hi def link vimPatSepR	vimPatSep
+hi def link vimPatSepZ	vimPatSep
+hi def link vimPatSepErr	vimPatSep
+hi def link vimPatSepZone	vimString
+hi def link vimPlainMark	vimMark
+hi def link vimPlainRegister	vimRegister
+hi def link vimSearch	vimString
+hi def link vimSearchDelim	Statement
+hi def link vimSetMod	vimOption
+hi def link vimSetString	vimString
+hi def link vimSpecFileMod	vimSpecFile
+hi def link vimStringCont	vimString
+hi def link vimSubstTwoBS	vimString
+hi def link vimSubst	vimCommand
+hi def link vimSyncGroupName	vimGroupName
+hi def link vimSyncGroup	vimGroupName
+hi def link vimSynContains	vimSynOption
+hi def link vimSynKeyContainedin	vimSynContains
+hi def link vimSynKeyOpt	vimSynOption
+hi def link vimSynMtchGrp	vimSynOption
+hi def link vimSynMtchOpt	vimSynOption
+hi def link vimSynNextgroup	vimSynOption
+hi def link vimSynNotPatRange	vimSynRegPat
+hi def link vimSynPatRange	vimString
+hi def link vimSynRegOpt	vimSynOption
+hi def link vimSynRegPat	vimString
+hi def link vimSyntax	vimCommand
+hi def link vimSynType	vimSpecial
+hi def link vimUserAttrbCmplt	vimSpecial
+hi def link vimUserAttrbKey	vimOption
+hi def link vimUserAttrb	vimSpecial
+hi def link vimUserCommand	vimCommand
+hi def link vimUserFunc	Normal
+
+hi def link vimAutoEvent	Type
+hi def link vimBracket	Delimiter
+hi def link vimCmplxRepeat	SpecialChar
+hi def link vimCommand	Statement
+hi def link vimComment	Comment
+hi def link vimCommentTitle	PreProc
+hi def link vimContinue	Special
+hi def link vimCtrlChar	SpecialChar
+hi def link vimElseIfErr	Error
+hi def link vimEnvvar	PreProc
+hi def link vimError	Error
+hi def link vimFold	Folded
+hi def link vimFuncName	Function
+hi def link vimFuncSID	Special
+hi def link vimFuncVar	Identifier
+hi def link vimGroup	Type
+hi def link vimGroupSpecial	Special
+hi def link vimHLMod	PreProc
+hi def link vimHiAttrib	PreProc
+hi def link vimHiTerm	Type
+hi def link vimKeyword	Statement
+hi def link vimMark	Number
+hi def link vimMenuName	PreProc
+hi def link vimNotation	Special
+hi def link vimNotFunc	vimCommand
+hi def link vimNumber	Number
+hi def link vimOper	Operator
+hi def link vimOption	PreProc
+hi def link vimOperError	Error
+hi def link vimPatSep	SpecialChar
+hi def link vimPattern	Type
+hi def link vimRegister	SpecialChar
+hi def link vimScriptDelim	Comment
+hi def link vimSep	Delimiter
+hi def link vimSetSep	Statement
+hi def link vimSpecFile	Identifier
+hi def link vimSpecial	Type
+hi def link vimStatement	Statement
+hi def link vimString	String
+hi def link vimSubstDelim	Delimiter
+hi def link vimSubstFlags	Special
+hi def link vimSubstSubstr	SpecialChar
+hi def link vimSynCase	Type
+hi def link vimSynCaseError	Error
+hi def link vimSynError	Error
+hi def link vimSynOption	Special
+hi def link vimSynReg	Type
+hi def link vimSyncC	Type
+hi def link vimSyncError	Error
+hi def link vimSyncKey	Type
+hi def link vimSyncNone	Type
+hi def link vimTodo	Todo
+hi def link vimUserCmdError	Error
+hi def link vimUserAttrbCmpltFunc	Special
+
+" Current Syntax Variable: {{{2
+let b:current_syntax = "vim"
+" vim:ts=18  fdm=marker
--- /dev/null
+++ b/lib/vimfiles/syntax/viminfo.vim
@@ -1,0 +1,38 @@
+" Vim syntax file
+" Language:	Vim .viminfo file
+" Maintainer:	Bram Moolenaar <Bram@vim.org>
+" Last Change:	2005 Jun 20
+
+" Quit when a (custom) syntax file was already loaded
+if exists("b:current_syntax")
+  finish
+endif
+
+" The lines that are NOT recognized
+syn match viminfoError "^[^\t].*"
+
+" The one-character one-liners that are recognized
+syn match viminfoStatement "^[/&$@:?=%!<]"
+
+" The two-character one-liners that are recognized
+syn match viminfoStatement "^[-'>"]."
+syn match viminfoStatement +^"".+
+syn match viminfoStatement "^\~[/&]"
+syn match viminfoStatement "^\~[hH]"
+syn match viminfoStatement "^\~[mM][sS][lL][eE]\d\+\~\=[/&]"
+
+syn match viminfoOption "^\*.*=" contains=viminfoOptionName
+syn match viminfoOptionName "\*\a*"ms=s+1 contained
+
+" Comments
+syn match viminfoComment "^#.*"
+
+" Define the default highlighting.
+" Only used when an item doesn't have highlighting yet
+hi def link viminfoComment	Comment
+hi def link viminfoError	Error
+hi def link viminfoStatement	Statement
+
+let b:current_syntax = "viminfo"
+
+" vim: ts=8 sw=2
--- /dev/null
+++ b/lib/vimfiles/syntax/virata.vim
@@ -1,0 +1,219 @@
+" Vim syntax file
+" Language:	Virata AConfig Configuration Script
+" Maintainer:	Manuel M.H. Stol	<mmh.stol@gmx.net>
+" Last Change:	2003 May 11
+" Vim URL:	http://www.vim.org/lang.html
+" Virata URL:	http://www.globespanvirata.com/
+
+
+" Virata AConfig Configuration Script syntax
+"  Can be detected by: 1) Extension .hw, .sw, .pkg and .module
+"		       2) The file name pattern "mk.*\.cfg"
+"		       3) The string "Virata" in the first 5 lines
+
+
+" Setup Syntax:
+if version < 600
+  "  Clear old syntax settings
+  syn clear
+elseif exists("b:current_syntax")
+  finish
+endif
+"  Virata syntax is case insensitive (mostly)
+syn case ignore
+
+
+
+" Comments:
+" Virata comments start with %, but % is not a keyword character
+syn region  virataComment	start="^%" start="\s%"lc=1 keepend end="$" contains=@virataGrpInComments
+syn region  virataSpclComment	start="^%%" start="\s%%"lc=1 keepend end="$" contains=@virataGrpInComments
+syn keyword virataInCommentTodo	contained TODO FIXME XXX[XXXXX] REVIEW TBD
+syn cluster virataGrpInComments	contains=virataInCommentTodo
+syn cluster virataGrpComments	contains=@virataGrpInComments,virataComment,virataSpclComment
+
+
+" Constants:
+syn match   virataStringError	+["]+
+syn region  virataString	start=+"+ skip=+\(\\\\\|\\"\)+ end=+"+ oneline contains=virataSpclCharError,virataSpclChar,@virataGrpDefSubsts
+syn match   virataCharacter	+'[^']\{-}'+ contains=virataSpclCharError,virataSpclChar
+syn match   virataSpclChar	contained +\\\(x\x\+\|\o\{1,3}\|['\"?\\abefnrtv]\)+
+syn match   virataNumberError	"\<\d\{-1,}\I\{-1,}\>"
+syn match   virataNumberError	"\<0x\x*\X\x*\>"
+syn match   virataNumberError	"\<\d\+\.\d*\(e[+-]\=\d\+\)\=\>"
+syn match   virataDecNumber	"\<\d\+U\=L\=\>"
+syn match   virataHexNumber	"\<0x\x\+U\=L\=\>"
+syn match   virataSizeNumber	"\<\d\+[BKM]\>"he=e-1
+syn match   virataSizeNumber	"\<\d\+[KM]B\>"he=e-2
+syn cluster virataGrpNumbers	contains=virataNumberError,virataDecNumber,virataHexNumber,virataSizeNumber
+syn cluster virataGrpConstants	contains=@virataGrpNumbers,virataStringError,virataString,virataCharacter,virataSpclChar
+
+
+" Identifiers:
+syn match   virataIdentError	contained "\<\D\S*\>"
+syn match   virataIdentifier	contained "\<\I\i\{-}\(\-\i\{-1,}\)*\>" contains=@virataGrpDefSubsts
+syn match   virataFileIdent	contained "\F\f*" contains=@virataGrpDefSubsts
+syn cluster virataGrpIdents	contains=virataIdentifier,virataIdentError
+syn cluster virataGrpFileIdents	contains=virataFileIdent,virataIdentError
+
+
+" Statements:
+syn match   virataStatement	"^\s*Config\(\(/Kernel\)\=\.\(hs\=\|s\)\)\=\>"
+syn match   virataStatement	"^\s*Config\s\+\I\i\{-}\(\-\i\{-1,}\)*\.\(hs\=\|s\)\>"
+syn match   virataStatement	"^\s*Make\.\I\i\{-}\(\-\i\{-1}\)*\>" skipwhite nextgroup=@virataGrpIdents
+syn match   virataStatement	"^\s*Make\.c\(at\)\=++\s"me=e-1 skipwhite nextgroup=@virataGrpIdents
+syn match   virataStatement	"^\s*\(Architecture\|GetEnv\|Reserved\|\(Un\)\=Define\|Version\)\>" skipwhite nextgroup=@virataGrpIdents
+syn match   virataStatement	"^\s*\(Hardware\|ModuleSource\|\(Release\)\=Path\|Software\)\>" skipwhite nextgroup=@virataGrpFileIdents
+syn match   virataStatement	"^\s*\(DefaultPri\|Hydrogen\)\>" skipwhite nextgroup=virataDecNumber,virataNumberError
+syn match   virataStatement	"^\s*\(NoInit\|PCI\|SysLink\)\>"
+syn match   virataStatement	"^\s*Allow\s\+\(ModuleConfig\)\>"
+syn match   virataStatement	"^\s*NoWarn\s\+\(Export\|Parse\=able\|Relative]\)\>"
+syn match   virataStatement	"^\s*Debug\s\+O\(ff\|n\)\>"
+
+" Import (Package <exec>|Module <name> from <dir>)
+syn region  virataImportDef	transparent matchgroup=virataStatement start="^\s*Import\>" keepend end="$" contains=virataInImport,virataModuleDef,virataNumberError,virataStringError,@virataGrpDefSubsts
+syn match   virataInImport	contained "\<\(Module\|Package\|from\)\>" skipwhite nextgroup=@virataGrpFileIdents
+" Export (Header <header file>|SLibrary <obj file>)
+syn region  virataExportDef	transparent matchgroup=virataStatement start="^\s*Export\>" keepend end="$" contains=virataInExport,virataNumberError,virataStringError,@virataGrpDefSubsts
+syn match   virataInExport	contained "\<\(Header\|[SU]Library\)\>" skipwhite nextgroup=@virataGrpFileIdents
+" Process <name> is <dir/exec>
+syn region  virataProcessDef	transparent matchgroup=virataStatement start="^\s*Process\>" keepend end="$" contains=virataInProcess,virataInExec,virataNumberError,virataStringError,@virataGrpDefSubsts,@virataGrpIdents
+syn match   virataInProcess	contained "\<is\>"
+" Instance <name> of <module>
+syn region  virataInstanceDef	transparent matchgroup=virataStatement start="^\s*Instance\>" keepend end="$" contains=virataInInstance,virataNumberError,virataStringError,@virataGrpDefSubsts,@virataGrpIdents
+syn match   virataInInstance	contained "\<of\>"
+" Module <name> from <dir>
+syn region  virataModuleDef	transparent matchgroup=virataStatement start="^\s*\(Package\|Module\)\>" keepend end="$" contains=virataInModule,virataNumberError,virataStringError,@virataGrpDefSubsts
+syn match   virataInModule	contained "^\s*Package\>"hs=e-7 skipwhite nextgroup=@virataGrpIdents
+syn match   virataInModule	contained "^\s*Module\>"hs=e-6 skipwhite nextgroup=@virataGrpIdents
+syn match   virataInModule	contained "\<from\>" skipwhite nextgroup=@virataGrpFileIdents
+" Colour <name> from <dir>
+syn region  virataColourDef	transparent matchgroup=virataStatement start="^\s*Colour\>" keepend end="$" contains=virataInColour,virataNumberError,virataStringError,@virataGrpDefSubsts
+syn match   virataInColour	contained "^\s*Colour\>"hs=e-6 skipwhite nextgroup=@virataGrpIdents
+syn match   virataInColour	contained "\<from\>" skipwhite nextgroup=@virataGrpFileIdents
+" Link {<link cmds>}
+" Object {Executable [<ExecOptions>]}
+syn match   virataStatement	"^\s*\(Link\|Object\)"
+" Executable <name> [<ExecOptions>]
+syn region  virataExecDef	transparent matchgroup=virataStatement start="^\s*Executable\>" keepend end="$" contains=virataInExec,virataNumberError,virataStringError
+syn match   virataInExec	contained "^\s*Executable\>" skipwhite nextgroup=@virataGrpDefSubsts,@virataGrpIdents
+syn match   virataInExec	contained "\<\(epilogue\|pro\(logue\|cess\)\|qhandler\)\>" skipwhite nextgroup=@virataGrpDefSubsts,@virataGrpIdents
+syn match   virataInExec	contained "\<\(priority\|stack\)\>" skipwhite nextgroup=@virataGrpDefSubsts,@virataGrpNumbers
+" Message <name> {<msg format>}
+" MessageId <number>
+syn match   virataStatement	"^\s*Message\(Id\)\=\>" skipwhite nextgroup=@virataGrpNumbers
+" MakeRule <make suffix=file> {<make cmds>}
+syn region  virataMakeDef	transparent matchgroup=virataStatement start="^\s*MakeRule\>" keepend end="$" contains=virataInMake,@virataGrpDefSubsts
+syn case match
+syn match   virataInMake	contained "\<N\>"
+syn case ignore
+" (Append|Edit|Copy)Rule <make suffix=file> <subst cmd>
+syn match   virataStatement	"^\s*\(Append\|Copy\|Edit\)Rule\>"
+" AlterRules in <file> <subst cmd>
+syn region  virataAlterDef	transparent matchgroup=virataStatement start="^\s*AlterRules\>" keepend end="$" contains=virataInAlter,@virataGrpDefSubsts
+syn match   virataInAlter	contained "\<in\>" skipwhite nextgroup=@virataGrpIdents
+" Clustering
+syn cluster virataGrpInStatmnts	contains=virataInImport,virataInExport,virataInExec,virataInProcess,virataInAlter,virataInInstance,virataInModule,virataInColour
+syn cluster virataGrpStatements	contains=@virataGrpInStatmnts,virataStatement,virataImportDef,virataExportDef,virataExecDef,virataProcessDef,virataAlterDef,virataInstanceDef,virataModuleDef,virataColourDef
+
+
+" MkFlash.Cfg File Statements:
+syn region  virataCfgFileDef	transparent matchgroup=virataCfgStatement start="^\s*Dir\>" start="^\s*\a\{-}File\>" start="^\s*OutputFile\d\d\=\>" start="^\s*\a\w\{-}[NP]PFile\>" keepend end="$" contains=@virataGrpFileIdents
+syn region  virataCfgSizeDef	transparent matchgroup=virataCfgStatement start="^\s*\a\{-}Size\>" start="^\s*ConfigInfo\>" keepend end="$" contains=@virataGrpNumbers,@virataGrpDefSubsts,virataIdentError
+syn region  virataCfgNumberDef	transparent matchgroup=virataCfgStatement start="^\s*FlashchipNum\(b\(er\=\)\=\)\=\>" start="^\s*Granularity\>" keepend end="$" contains=@virataGrpNumbers,@virataGrpDefSubsts
+syn region  virataCfgMacAddrDef	transparent matchgroup=virataCfgStatement start="^\s*MacAddress\>" keepend end="$" contains=virataNumberError,virataStringError,virataIdentError,virataInMacAddr,@virataGrpDefSubsts
+syn match   virataInMacAddr	contained "\x[:]\x\{1,2}\>"lc=2
+syn match   virataInMacAddr	contained "\s\x\{1,2}[:]\x"lc=1,me=e-1,he=e-2 nextgroup=virataInMacAddr
+syn match   virataCfgStatement	"^\s*Target\>" skipwhite nextgroup=@virataGrpIdents
+syn cluster virataGrpCfgs	contains=virataCfgStatement,virataCfgFileDef,virataCfgSizeDef,virataCfgNumberDef,virataCfgMacAddrDef,virataInMacAddr
+
+
+
+" PreProcessor Instructions:
+"  Defines
+syn match   virataDefine	"^\s*\(Un\)\=Set\>" skipwhite nextgroup=@virataGrpIdents
+syn match   virataInclude	"^\s*Include\>" skipwhite nextgroup=@virataGrpFileIdents
+syn match   virataDefSubstError	"[^$]\$"lc=1
+syn match   virataDefSubstError	"\$\(\w\|{\(.\{-}}\)\=\)"
+syn case match
+syn match   virataDefSubst	"\$\(\d\|[DINORS]\|{\I\i\{-}\(\-\i\{-1,}\)*}\)"
+syn case ignore
+"  Conditionals
+syn cluster virataGrpCntnPreCon	contains=ALLBUT,@virataGrpInComments,@virataGrpFileIdents,@virataGrpInStatmnts
+syn region  virataPreConDef	transparent matchgroup=virataPreCondit start="^\s*If\>" end="^\s*Endif\>" contains=@virataGrpCntnPreCon
+syn match   virataPreCondit	contained "^\s*Else\(\s\+If\)\=\>"
+syn region  virataPreConDef	transparent matchgroup=virataPreCondit start="^\s*ForEach\>" end="^\s*Done\>" contains=@virataGrpCntnPreCon
+"  Pre-Processors
+syn region  virataPreProc	start="^\s*Error\>" start="^\s*Warning\>" oneline end="$" contains=@virataGrpConstants,@virataGrpDefSubsts
+syn cluster virataGrpDefSubsts	contains=virataDefSubstError,virataDefSubst
+syn cluster virataGrpPreProcs	contains=@virataGrpDefSubsts,virataDefine,virataInclude,virataPreConDef,virataPreCondit,virataPreProc
+
+
+" Synchronize Syntax:
+syn sync clear
+syn sync minlines=50		"for multiple region nesting
+
+
+
+" Define the default highlighting.
+" For version 5.7 and earlier: only when not done already
+" For version 5.8 and later  : only when an item doesn't have highlighting yet
+if version >= 508 || !exists("did_virata_syntax_inits")
+  if version < 508
+    let did_virata_syntax_inits = 1
+    command -nargs=+ HiLink hi link <args>
+  else
+    command -nargs=+ HiLink hi def link <args>
+  endif
+
+  " Sub Links:
+  HiLink virataDefSubstError	virataPreProcError
+  HiLink virataDefSubst		virataPreProc
+  HiLink virataInAlter		virataOperator
+  HiLink virataInExec		virataOperator
+  HiLink virataInExport		virataOperator
+  HiLink virataInImport		virataOperator
+  HiLink virataInInstance	virataOperator
+  HiLink virataInMake		virataOperator
+  HiLink virataInModule		virataOperator
+  HiLink virataInProcess	virataOperator
+  HiLink virataInMacAddr	virataHexNumber
+
+  " Comment Group:
+  HiLink virataComment		Comment
+  HiLink virataSpclComment	SpecialComment
+  HiLink virataInCommentTodo	Todo
+
+  " Constant Group:
+  HiLink virataString		String
+  HiLink virataStringError	Error
+  HiLink virataCharacter	Character
+  HiLink virataSpclChar		Special
+  HiLink virataDecNumber	Number
+  HiLink virataHexNumber	Number
+  HiLink virataSizeNumber	Number
+  HiLink virataNumberError	Error
+
+  " Identifier Group:
+  HiLink virataIdentError	Error
+
+  " PreProc Group:
+  HiLink virataPreProc		PreProc
+  HiLink virataDefine		Define
+  HiLink virataInclude		Include
+  HiLink virataPreCondit	PreCondit
+  HiLink virataPreProcError	Error
+  HiLink virataPreProcWarn	Todo
+
+  " Directive Group:
+  HiLink virataStatement	Statement
+  HiLink virataCfgStatement	Statement
+  HiLink virataOperator		Operator
+  HiLink virataDirective	Keyword
+
+  delcommand HiLink
+endif
+
+let b:current_syntax = "virata"
+
+" vim:ts=8:sw=2:noet:
--- /dev/null
+++ b/lib/vimfiles/syntax/vmasm.vim
@@ -1,0 +1,251 @@
+" Vim syntax file
+" Language:	(VAX) Macro Assembly
+" Maintainer:	Tom Uijldert <tom.uijldert [at] cmg.nl>
+" Last change:	2004 May 16
+"
+" This is incomplete. Feel free to contribute...
+"
+
+" For version 5.x: Clear all syntax items
+" For version 6.x: Quit when a syntax file was already loaded
+if version < 600
+  syntax clear
+elseif exists("b:current_syntax")
+  finish
+endif
+
+syn case ignore
+
+" Partial list of register symbols
+syn keyword vmasmReg	r0 r1 r2 r3 r4 r5 r6 r7 r8 r9 r10 r11 r12
+syn keyword vmasmReg	ap fp sp pc iv dv
+
+" All matches - order is important!
+syn keyword vmasmOpcode adawi adwc ashl ashq bitb bitw bitl decb decw decl
+syn keyword vmasmOpcode ediv emul incb incw incl mcomb mcomw mcoml
+syn keyword vmasmOpcode movzbw movzbl movzwl popl pushl rotl sbwc
+syn keyword vmasmOpcode cmpv cmpzv cmpc3 cmpc5 locc matchc movc3 movc5
+syn keyword vmasmOpcode movtc movtuc scanc skpc spanc crc extv extzv
+syn keyword vmasmOpcode ffc ffs insv aobleq aoblss bbc bbs bbcci bbssi
+syn keyword vmasmOpcode blbc blbs brb brw bsbb bsbw caseb casew casel
+syn keyword vmasmOpcode jmp jsb rsb sobgeq sobgtr callg calls ret
+syn keyword vmasmOpcode bicpsw bispsw bpt halt index movpsl nop popr pushr xfc
+syn keyword vmasmOpcode insqhi insqti insque remqhi remqti remque
+syn keyword vmasmOpcode addp4 addp6 ashp cmpp3 cmpp4 cvtpl cvtlp cvtps cvtpt
+syn keyword vmasmOpcode cvtsp cvttp divp movp mulp subp4 subp6 editpc
+syn keyword vmasmOpcode prober probew rei ldpctx svpctx mfpr mtpr bugw bugl
+syn keyword vmasmOpcode vldl vldq vgathl vgathq vstl vstq vscatl vscatq
+syn keyword vmasmOpcode vvcvt iota mfvp mtvp vsync
+syn keyword vmasmOpcode beql[u] bgtr[u] blss[u]
+syn match vmasmOpcode "\<add[bwlfdgh][23]\>"
+syn match vmasmOpcode "\<bi[cs][bwl][23]\>"
+syn match vmasmOpcode "\<clr[bwlqofdgh]\>"
+syn match vmasmOpcode "\<cmp[bwlfdgh]\>"
+syn match vmasmOpcode "\<cvt[bwlfdgh][bwlfdgh]\>"
+syn match vmasmOpcode "\<cvtr[fdgh]l\>"
+syn match vmasmOpcode "\<div[bwlfdgh][23]\>"
+syn match vmasmOpcode "\<emod[fdgh]\>"
+syn match vmasmOpcode "\<mneg[bwlfdgh]\>"
+syn match vmasmOpcode "\<mov[bwlqofdgh]\>"
+syn match vmasmOpcode "\<mul[bwlfdgh][23]\>"
+syn match vmasmOpcode "\<poly[fdgh]\>"
+syn match vmasmOpcode "\<sub[bwlfdgh][23]\>"
+syn match vmasmOpcode "\<tst[bwlfdgh]\>"
+syn match vmasmOpcode "\<xor[bwl][23]\>"
+syn match vmasmOpcode "\<mova[bwlfqdgho]\>"
+syn match vmasmOpcode "\<push[bwlfqdgho]\>"
+syn match vmasmOpcode "\<acb[bwlfgdh]\>"
+syn match vmasmOpcode "\<b[lng]equ\=\>"
+syn match vmasmOpcode "\<b[cv][cs]\>"
+syn match vmasmOpcode "\<bb[cs][cs]\>"
+syn match vmasmOpcode "\<v[vs]add[lfdg]\>"
+syn match vmasmOpcode "\<v[vs]cmp[lfdg]\>"
+syn match vmasmOpcode "\<v[vs]div[fdg]\>"
+syn match vmasmOpcode "\<v[vs]mul[lfdg]\>"
+syn match vmasmOpcode "\<v[vs]sub[lfdg]\>"
+syn match vmasmOpcode "\<v[vs]bi[cs]l\>"
+syn match vmasmOpcode "\<v[vs]xorl\>"
+syn match vmasmOpcode "\<v[vs]merge\>"
+syn match vmasmOpcode "\<v[vs]s[rl]ll\>"
+
+" Various number formats
+syn match vmasmdecNumber	"[+-]\=[0-9]\+\>"
+syn match vmasmdecNumber	"^d[0-9]\+\>"
+syn match vmasmhexNumber	"^x[0-9a-f]\+\>"
+syn match vmasmoctNumber	"^o[0-7]\+\>"
+syn match vmasmbinNumber	"^b[01]\+\>"
+syn match vmasmfloatNumber	"[-+]\=[0-9]\+E[-+]\=[0-9]\+"
+syn match vmasmfloatNumber	"[-+]\=[0-9]\+\.[0-9]*\(E[-+]\=[0-9]\+\)\="
+
+" Valid labels
+syn match vmasmLabel		"^[a-z_$.][a-z0-9_$.]\{,30}::\="
+syn match vmasmLabel		"\<[0-9]\{1,5}\$:\="          " Local label
+
+" Character string constants
+"       Too complex really. Could be "<...>" but those could also be
+"       expressions. Don't know how to handle chosen delimiters
+"       ("^<sep>...<sep>")
+" syn region vmasmString		start="<" end=">" oneline
+
+" Operators
+syn match vmasmOperator	"[-+*/@&!\\]"
+syn match vmasmOperator	"="
+syn match vmasmOperator	"=="		" Global assignment
+syn match vmasmOperator	"%length(.*)"
+syn match vmasmOperator	"%locate(.*)"
+syn match vmasmOperator	"%extract(.*)"
+syn match vmasmOperator	"^[amfc]"
+syn match vmasmOperator	"[bwlg]^"
+
+syn match vmasmOperator	"\<\(not_\)\=equal\>"
+syn match vmasmOperator	"\<less_equal\>"
+syn match vmasmOperator	"\<greater\(_equal\)\=\>"
+syn match vmasmOperator	"\<less_than\>"
+syn match vmasmOperator	"\<\(not_\)\=defined\>"
+syn match vmasmOperator	"\<\(not_\)\=blank\>"
+syn match vmasmOperator	"\<identical\>"
+syn match vmasmOperator	"\<different\>"
+syn match vmasmOperator	"\<eq\>"
+syn match vmasmOperator	"\<[gl]t\>"
+syn match vmasmOperator	"\<n\=df\>"
+syn match vmasmOperator	"\<n\=b\>"
+syn match vmasmOperator	"\<idn\>"
+syn match vmasmOperator	"\<[nlg]e\>"
+syn match vmasmOperator	"\<dif\>"
+
+" Special items for comments
+syn keyword vmasmTodo		contained todo
+
+" Comments
+syn match vmasmComment		";.*" contains=vmasmTodo
+
+" Include
+syn match vmasmInclude		"\.library\>"
+
+" Macro definition
+syn match vmasmMacro		"\.macro\>"
+syn match vmasmMacro		"\.mexit\>"
+syn match vmasmMacro		"\.endm\>"
+syn match vmasmMacro		"\.mcall\>"
+syn match vmasmMacro		"\.mdelete\>"
+
+" Conditional assembly
+syn match vmasmPreCond		"\.iff\=\>"
+syn match vmasmPreCond		"\.if_false\>"
+syn match vmasmPreCond		"\.iftf\=\>"
+syn match vmasmPreCond		"\.if_true\(_false\)\=\>"
+syn match vmasmPreCond		"\.iif\>"
+
+" Loop control
+syn match vmasmRepeat		"\.irpc\=\>"
+syn match vmasmRepeat		"\.repeat\>"
+syn match vmasmRepeat		"\.rept\>"
+syn match vmasmRepeat		"\.endr\>"
+
+" Directives
+syn match vmasmDirective	"\.address\>"
+syn match vmasmDirective	"\.align\>"
+syn match vmasmDirective	"\.asci[cdiz]\>"
+syn match vmasmDirective	"\.blk[abdfghloqw]\>"
+syn match vmasmDirective	"\.\(signed_\)\=byte\>"
+syn match vmasmDirective	"\.\(no\)\=cross\>"
+syn match vmasmDirective	"\.debug\>"
+syn match vmasmDirective	"\.default displacement\>"
+syn match vmasmDirective	"\.[dfgh]_floating\>"
+syn match vmasmDirective	"\.disable\>"
+syn match vmasmDirective	"\.double\>"
+syn match vmasmDirective	"\.dsabl\>"
+syn match vmasmDirective	"\.enable\=\>"
+syn match vmasmDirective	"\.endc\=\>"
+syn match vmasmDirective	"\.entry\>"
+syn match vmasmDirective	"\.error\>"
+syn match vmasmDirective	"\.even\>"
+syn match vmasmDirective	"\.external\>"
+syn match vmasmDirective	"\.extrn\>"
+syn match vmasmDirective	"\.float\>"
+syn match vmasmDirective	"\.globa\=l\>"
+syn match vmasmDirective	"\.ident\>"
+syn match vmasmDirective	"\.link\>"
+syn match vmasmDirective	"\.list\>"
+syn match vmasmDirective	"\.long\>"
+syn match vmasmDirective	"\.mask\>"
+syn match vmasmDirective	"\.narg\>"
+syn match vmasmDirective	"\.nchr\>"
+syn match vmasmDirective	"\.nlist\>"
+syn match vmasmDirective	"\.ntype\>"
+syn match vmasmDirective	"\.octa\>"
+syn match vmasmDirective	"\.odd\>"
+syn match vmasmDirective	"\.opdef\>"
+syn match vmasmDirective	"\.packed\>"
+syn match vmasmDirective	"\.page\>"
+syn match vmasmDirective	"\.print\>"
+syn match vmasmDirective	"\.psect\>"
+syn match vmasmDirective	"\.quad\>"
+syn match vmasmDirective	"\.ref[1248]\>"
+syn match vmasmDirective	"\.ref16\>"
+syn match vmasmDirective	"\.restore\(_psect\)\=\>"
+syn match vmasmDirective	"\.save\(_psect\)\=\>"
+syn match vmasmDirective	"\.sbttl\>"
+syn match vmasmDirective	"\.\(no\)\=show\>"
+syn match vmasmDirective	"\.\(sub\)\=title\>"
+syn match vmasmDirective	"\.transfer\>"
+syn match vmasmDirective	"\.warn\>"
+syn match vmasmDirective	"\.weak\>"
+syn match vmasmDirective	"\.\(signed_\)\=word\>"
+
+syn case match
+
+" Define the default highlighting.
+" For version 5.7 and earlier: only when not done already
+" For version 5.8 and later: only when an item doesn't have highlighting yet
+if version >= 508 || !exists("did_macro_syntax_inits")
+  if version < 508
+    let did_macro_syntax_inits = 1
+    command -nargs=+ HiLink hi link <args>
+  else
+    command -nargs=+ HiLink hi def link <args>
+  endif
+
+  " The default methods for highlighting.  Can be overridden later
+  " Comment Constant Error Identifier PreProc Special Statement Todo Type
+  "
+  " Constant		Boolean Character Number String
+  " Identifier		Function
+  " PreProc		Define Include Macro PreCondit
+  " Special		Debug Delimiter SpecialChar SpecialComment Tag
+  " Statement		Conditional Exception Keyword Label Operator Repeat
+  " Type		StorageClass Structure Typedef
+
+  HiLink vmasmComment		Comment
+  HiLink vmasmTodo		Todo
+
+  HiLink vmasmhexNumber		Number		" Constant
+  HiLink vmasmoctNumber		Number		" Constant
+  HiLink vmasmbinNumber		Number		" Constant
+  HiLink vmasmdecNumber		Number		" Constant
+  HiLink vmasmfloatNumber	Number		" Constant
+
+"  HiLink vmasmString		String		" Constant
+
+  HiLink vmasmReg		Identifier
+  HiLink vmasmOperator		Identifier
+
+  HiLink vmasmInclude		Include		" PreProc
+  HiLink vmasmMacro		Macro		" PreProc
+  " HiLink vmasmMacroParam	Keyword		" Statement
+
+  HiLink vmasmDirective		Special
+  HiLink vmasmPreCond		Special
+
+
+  HiLink vmasmOpcode		Statement
+  HiLink vmasmCond		Conditional	" Statement
+  HiLink vmasmRepeat		Repeat		" Statement
+
+  HiLink vmasmLabel		Type
+  delcommand HiLink
+endif
+
+let b:current_syntax = "vmasm"
+
+" vim: ts=8 sw=2
--- /dev/null
+++ b/lib/vimfiles/syntax/vrml.vim
@@ -1,0 +1,239 @@
+" Vim syntax file
+" Language:	   VRML97
+" Modified from:   VRML 1.0C by David Brown <dbrown@cgs.c4.gmeds.com>
+" Maintainer:	   vacancy!
+" Former Maintainer:    Gregory Seidman <gsslist+vim@anthropohedron.net>
+" Last change:	   2006 May 03
+
+" For version 5.x: Clear all syntax items
+" For version 6.x: Quit when a syntax file was already loaded
+if version < 600
+  syntax clear
+elseif exists("b:current_syntax")
+  finish
+endif
+
+" keyword definitions
+
+syn keyword VRMLFields	       ambientIntensity appearance attenuation
+syn keyword VRMLFields	       autoOffset avatarSize axisOfRotation backUrl
+syn keyword VRMLFields	       bboxCenter bboxSize beamWidth beginCap
+syn keyword VRMLFields	       bottom bottomRadius bottomUrl ccw center
+syn keyword VRMLFields	       children choice collide color colorIndex
+syn keyword VRMLFields	       colorPerVertex convex coord coordIndex
+syn keyword VRMLFields	       creaseAngle crossSection cutOffAngle
+syn keyword VRMLFields	       cycleInterval description diffuseColor
+syn keyword VRMLFields	       directOutput direction diskAngle
+syn keyword VRMLFields	       emissiveColor enabled endCap family
+syn keyword VRMLFields	       fieldOfView fogType fontStyle frontUrl
+syn keyword VRMLFields	       geometry groundAngle groundColor headlight
+syn keyword VRMLFields	       height horizontal info intensity jump
+syn keyword VRMLFields	       justify key keyValue language leftToRight
+syn keyword VRMLFields	       leftUrl length level location loop material
+syn keyword VRMLFields	       maxAngle maxBack maxExtent maxFront
+syn keyword VRMLFields	       maxPosition minAngle minBack minFront
+syn keyword VRMLFields	       minPosition mustEvaluate normal normalIndex
+syn keyword VRMLFields	       normalPerVertex offset on orientation
+syn keyword VRMLFields	       parameter pitch point position priority
+syn keyword VRMLFields	       proxy radius range repeatS repeatT rightUrl
+syn keyword VRMLFields	       rotation scale scaleOrientation shininess
+syn keyword VRMLFields	       side size skyAngle skyColor solid source
+syn keyword VRMLFields	       spacing spatialize specularColor speed spine
+syn keyword VRMLFields	       startTime stopTime string style texCoord
+syn keyword VRMLFields	       texCoordIndex texture textureTransform title
+syn keyword VRMLFields	       top topToBottom topUrl translation
+syn keyword VRMLFields	       transparency type url vector visibilityLimit
+syn keyword VRMLFields	       visibilityRange whichChoice xDimension
+syn keyword VRMLFields	       xSpacing zDimension zSpacing
+syn match   VRMLFields	       "\<[A-Za-z_][A-Za-z0-9_]*\>" contains=VRMLComment,VRMLProtos,VRMLfTypes
+" syn match   VRMLFields	 "\<[A-Za-z_][A-Za-z0-9_]*\>\(,\|\s\)*\(#.*$\)*\<IS\>\(#.*$\)*\(,\|\s\)*\<[A-Za-z_][A-Za-z0-9_]*\>\(,\|\s\)*\(#.*$\)*" contains=VRMLComment,VRMLProtos
+" syn region  VRMLFields	 start="\<[A-Za-z_][A-Za-z0-9_]*\>" end=+\(,\|#\|\s\)+me=e-1 contains=VRMLComment,VRMLProtos
+
+syn keyword VRMLEvents	       addChildren ambientIntensity_changed
+syn keyword VRMLEvents	       appearance_changed attenuation_changed
+syn keyword VRMLEvents	       autoOffset_changed avatarSize_changed
+syn keyword VRMLEvents	       axisOfRotation_changed backUrl_changed
+syn keyword VRMLEvents	       beamWidth_changed bindTime bottomUrl_changed
+syn keyword VRMLEvents	       center_changed children_changed
+syn keyword VRMLEvents	       choice_changed collideTime collide_changed
+syn keyword VRMLEvents	       color_changed coord_changed
+syn keyword VRMLEvents	       cutOffAngle_changed cycleInterval_changed
+syn keyword VRMLEvents	       cycleTime description_changed
+syn keyword VRMLEvents	       diffuseColor_changed direction_changed
+syn keyword VRMLEvents	       diskAngle_changed duration_changed
+syn keyword VRMLEvents	       emissiveColor_changed enabled_changed
+syn keyword VRMLEvents	       enterTime exitTime fogType_changed
+syn keyword VRMLEvents	       fontStyle_changed fraction_changed
+syn keyword VRMLEvents	       frontUrl_changed geometry_changed
+syn keyword VRMLEvents	       groundAngle_changed headlight_changed
+syn keyword VRMLEvents	       hitNormal_changed hitPoint_changed
+syn keyword VRMLEvents	       hitTexCoord_changed intensity_changed
+syn keyword VRMLEvents	       isActive isBound isOver jump_changed
+syn keyword VRMLEvents	       keyValue_changed key_changed leftUrl_changed
+syn keyword VRMLEvents	       length_changed level_changed
+syn keyword VRMLEvents	       location_changed loop_changed
+syn keyword VRMLEvents	       material_changed maxAngle_changed
+syn keyword VRMLEvents	       maxBack_changed maxExtent_changed
+syn keyword VRMLEvents	       maxFront_changed maxPosition_changed
+syn keyword VRMLEvents	       minAngle_changed minBack_changed
+syn keyword VRMLEvents	       minFront_changed minPosition_changed
+syn keyword VRMLEvents	       normal_changed offset_changed on_changed
+syn keyword VRMLEvents	       orientation_changed parameter_changed
+syn keyword VRMLEvents	       pitch_changed point_changed position_changed
+syn keyword VRMLEvents	       priority_changed radius_changed
+syn keyword VRMLEvents	       removeChildren rightUrl_changed
+syn keyword VRMLEvents	       rotation_changed scaleOrientation_changed
+syn keyword VRMLEvents	       scale_changed set_ambientIntensity
+syn keyword VRMLEvents	       set_appearance set_attenuation
+syn keyword VRMLEvents	       set_autoOffset set_avatarSize
+syn keyword VRMLEvents	       set_axisOfRotation set_backUrl set_beamWidth
+syn keyword VRMLEvents	       set_bind set_bottomUrl set_center
+syn keyword VRMLEvents	       set_children set_choice set_collide
+syn keyword VRMLEvents	       set_color set_colorIndex set_coord
+syn keyword VRMLEvents	       set_coordIndex set_crossSection
+syn keyword VRMLEvents	       set_cutOffAngle set_cycleInterval
+syn keyword VRMLEvents	       set_description set_diffuseColor
+syn keyword VRMLEvents	       set_direction set_diskAngle
+syn keyword VRMLEvents	       set_emissiveColor set_enabled set_fogType
+syn keyword VRMLEvents	       set_fontStyle set_fraction set_frontUrl
+syn keyword VRMLEvents	       set_geometry set_groundAngle set_headlight
+syn keyword VRMLEvents	       set_height set_intensity set_jump set_key
+syn keyword VRMLEvents	       set_keyValue set_leftUrl set_length
+syn keyword VRMLEvents	       set_level set_location set_loop set_material
+syn keyword VRMLEvents	       set_maxAngle set_maxBack set_maxExtent
+syn keyword VRMLEvents	       set_maxFront set_maxPosition set_minAngle
+syn keyword VRMLEvents	       set_minBack set_minFront set_minPosition
+syn keyword VRMLEvents	       set_normal set_normalIndex set_offset set_on
+syn keyword VRMLEvents	       set_orientation set_parameter set_pitch
+syn keyword VRMLEvents	       set_point set_position set_priority
+syn keyword VRMLEvents	       set_radius set_rightUrl set_rotation
+syn keyword VRMLEvents	       set_scale set_scaleOrientation set_shininess
+syn keyword VRMLEvents	       set_size set_skyAngle set_skyColor
+syn keyword VRMLEvents	       set_source set_specularColor set_speed
+syn keyword VRMLEvents	       set_spine set_startTime set_stopTime
+syn keyword VRMLEvents	       set_string set_texCoord set_texCoordIndex
+syn keyword VRMLEvents	       set_texture set_textureTransform set_topUrl
+syn keyword VRMLEvents	       set_translation set_transparency set_type
+syn keyword VRMLEvents	       set_url set_vector set_visibilityLimit
+syn keyword VRMLEvents	       set_visibilityRange set_whichChoice
+syn keyword VRMLEvents	       shininess_changed size_changed
+syn keyword VRMLEvents	       skyAngle_changed skyColor_changed
+syn keyword VRMLEvents	       source_changed specularColor_changed
+syn keyword VRMLEvents	       speed_changed startTime_changed
+syn keyword VRMLEvents	       stopTime_changed string_changed
+syn keyword VRMLEvents	       texCoord_changed textureTransform_changed
+syn keyword VRMLEvents	       texture_changed time topUrl_changed
+syn keyword VRMLEvents	       touchTime trackPoint_changed
+syn keyword VRMLEvents	       translation_changed transparency_changed
+syn keyword VRMLEvents	       type_changed url_changed value_changed
+syn keyword VRMLEvents	       vector_changed visibilityLimit_changed
+syn keyword VRMLEvents	       visibilityRange_changed whichChoice_changed
+syn region  VRMLEvents	       start="\S+[^0-9]+\.[A-Za-z_]+"ms=s+1 end="\(,\|$\|\s\)"me=e-1
+
+syn keyword VRMLNodes	       Anchor Appearance AudioClip Background
+syn keyword VRMLNodes	       Billboard Box Collision Color
+syn keyword VRMLNodes	       ColorInterpolator Cone Coordinate
+syn keyword VRMLNodes	       CoordinateInterpolator Cylinder
+syn keyword VRMLNodes	       CylinderSensor DirectionalLight
+syn keyword VRMLNodes	       ElevationGrid Extrusion Fog FontStyle
+syn keyword VRMLNodes	       Group ImageTexture IndexedFaceSet
+syn keyword VRMLNodes	       IndexedLineSet Inline LOD Material
+syn keyword VRMLNodes	       MovieTexture NavigationInfo Normal
+syn keyword VRMLNodes	       NormalInterpolator OrientationInterpolator
+syn keyword VRMLNodes	       PixelTexture PlaneSensor PointLight
+syn keyword VRMLNodes	       PointSet PositionInterpolator
+syn keyword VRMLNodes	       ProximitySensor ScalarInterpolator
+syn keyword VRMLNodes	       Script Shape Sound Sphere SphereSensor
+syn keyword VRMLNodes	       SpotLight Switch Text TextureCoordinate
+syn keyword VRMLNodes	       TextureTransform TimeSensor TouchSensor
+syn keyword VRMLNodes	       Transform Viewpoint VisibilitySensor
+syn keyword VRMLNodes	       WorldInfo
+
+" the following line doesn't catch <node><newline><openbrace> since \n
+" doesn't match as an atom yet :-(
+syn match   VRMLNodes	       "[A-Za-z_][A-Za-z0-9_]*\(,\|\s\)*{"me=e-1
+syn region  VRMLNodes	       start="\<EXTERNPROTO\>\(,\|\s\)*[A-Za-z_]"ms=e start="\<EXTERNPROTO\>\(,\|\s\)*" end="[\s]*\["me=e-1 contains=VRMLProtos,VRMLComment
+syn region  VRMLNodes	       start="PROTO\>\(,\|\s\)*[A-Za-z_]"ms=e start="PROTO\>\(,\|\s\)*" end="[\s]*\["me=e-1 contains=VRMLProtos,VRMLComment
+
+syn keyword VRMLTypes	       SFBool SFColor MFColor SFFloat MFFloat
+syn keyword VRMLTypes	       SFImage SFInt32 MFInt32 SFNode MFNode
+syn keyword VRMLTypes	       SFRotation MFRotation SFString MFString
+syn keyword VRMLTypes	       SFTime MFTime SFVec2f MFVec2f SFVec3f MFVec3f
+
+syn keyword VRMLfTypes	       field exposedField eventIn eventOut
+
+syn keyword VRMLValues	       TRUE FALSE NULL
+
+syn keyword VRMLProtos	       contained EXTERNPROTO PROTO IS
+
+syn keyword VRMLRoutes	       contained ROUTE TO
+
+if version >= 502
+"containment!
+  syn include @jscript $VIMRUNTIME/syntax/javascript.vim
+  syn region VRMLjScriptString contained start=+"\(\(javascript\)\|\(vrmlscript\)\|\(ecmascript\)\):+ms=e+1 skip=+\\\\\|\\"+ end=+"+me=e-1 contains=@jscript
+endif
+
+" match definitions.
+syn match   VRMLSpecial		  contained "\\[0-9][0-9][0-9]\|\\."
+syn region  VRMLString		  start=+"+  skip=+\\\\\|\\"+  end=+"+	contains=VRMLSpecial,VRMLjScriptString
+syn match   VRMLCharacter	  "'[^\\]'"
+syn match   VRMLSpecialCharacter  "'\\.'"
+syn match   VRMLNumber		  "[-+]\=\<[0-9]\+\(\.[0-9]\+\)\=\([eE]\{1}[-+]\=[0-9]\+\)\=\>\|0[xX][0-9a-fA-F]\+\>"
+syn match   VRMLNumber		  "0[xX][0-9a-fA-F]\+\>"
+syn match   VRMLComment		  "#.*$"
+
+" newlines should count as whitespace, but they can't be matched yet :-(
+syn region  VRMLRouteNode	  start="[^O]TO\(,\|\s\)*" end="\."me=e-1 contains=VRMLRoutes,VRMLComment
+syn region  VRMLRouteNode	  start="ROUTE\(,\|\s\)*" end="\."me=e-1 contains=VRMLRoutes,VRMLComment
+syn region  VRMLInstName	  start="DEF\>"hs=e+1 skip="DEF\(,\|\s\)*" end="[A-Za-z0-9_]\(\s\|$\|,\)"me=e contains=VRMLInstances,VRMLComment
+syn region  VRMLInstName	  start="USE\>"hs=e+1 skip="USE\(,\|\s\)*" end="[A-Za-z0-9_]\(\s\|$\|,\)"me=e contains=VRMLInstances,VRMLComment
+
+syn keyword VRMLInstances      contained DEF USE
+syn sync minlines=1
+
+if version >= 600
+"FOLDS!
+  syn sync fromstart
+  "setlocal foldmethod=syntax
+  syn region braceFold start="{" end="}" transparent fold contains=TOP
+  syn region bracketFold start="\[" end="]" transparent fold contains=TOP
+  syn region VRMLString start=+"+ skip=+\\\\\|\\"+ end=+"+ fold contains=VRMLSpecial,VRMLjScriptString
+endif
+
+" Define the default highlighting.
+" For version 5.7 and earlier: only when not done already
+" For version 5.8 and later: only when an item doesn't have highlighting yet
+if version >= 508 || !exists("did_VRML_syntax_inits")
+  if version < 508
+    let did_VRML_syntax_inits = 1
+    command -nargs=+ HiLink hi link <args>
+  else
+    command -nargs=+ HiLink hi def link <args>
+  endif
+
+  HiLink VRMLCharacter  VRMLString
+  HiLink VRMLSpecialCharacter VRMLSpecial
+  HiLink VRMLNumber     VRMLString
+  HiLink VRMLValues     VRMLString
+  HiLink VRMLString     String
+  HiLink VRMLSpecial    Special
+  HiLink VRMLComment    Comment
+  HiLink VRMLNodes      Statement
+  HiLink VRMLFields     Type
+  HiLink VRMLEvents     Type
+  HiLink VRMLfTypes     LineNr
+"  hi     VRMLfTypes     ctermfg=6 guifg=Brown
+  HiLink VRMLInstances  PreCondit
+  HiLink VRMLRoutes     PreCondit
+  HiLink VRMLProtos     PreProc
+  HiLink VRMLRouteNode  Identifier
+  HiLink VRMLInstName   Identifier
+  HiLink VRMLTypes      Identifier
+
+  delcommand HiLink
+endif
+
+let b:current_syntax = "vrml"
+
+" vim: ts=8
--- /dev/null
+++ b/lib/vimfiles/syntax/vsejcl.vim
@@ -1,0 +1,49 @@
+" Vim syntax file
+" Language:    JCL job control language - DOS/VSE
+" Maintainer:  Davyd Ondrejko <david.ondrejko@safelite.com>
+" URL:
+" Last change: 2001 May 10
+
+" For version 5.x: Clear all syntax items
+" For version 6.x: Quit when a syntax file was already loaded
+if version < 600
+  syntax clear
+elseif exists("b:current_syntax")
+  finish
+endif
+
+" tags
+syn keyword vsejclKeyword DLBL EXEC JOB ASSGN EOJ
+syn keyword vsejclField JNM CLASS DISP USER SYSID JSEP SIZE
+syn keyword vsejclField VSAM
+syn region vsejclComment start="^/\*" end="$"
+syn region vsejclComment start="^[\* ]\{}$" end="$"
+syn region vsejclMisc start="^  " end="$" contains=Jparms
+syn match vsejclString /'.\{-}'/
+syn match vsejclParms /(.\{-})/ contained
+
+" Define the default highlighting.
+" For version 5.7 and earlier: only when not done already
+" For version 5.8 and later: only when an item doesn't have highlighting yet
+if version >= 508 || !exists("did_vsejcl_syntax")
+  if version < 508
+    let did_vsejcl_syntax = 1
+    command -nargs=+ HiLink hi link <args>
+  else
+    command -nargs=+ HiLink hi def link <args>
+  endif
+
+  HiLink vsejclComment		Comment
+  HiLink vsejclField		Type
+  HiLink vsejclKeyword		Statement
+  HiLink vsejclObject		Constant
+  HiLink vsejclString		Constant
+  HiLink vsejclMisc			Special
+  HiLink vsejclParms		Constant
+
+  delcommand HiLink
+endif
+
+let b:current_syntax = "vsejcl"
+
+" vim: ts=4
--- /dev/null
+++ b/lib/vimfiles/syntax/wdiff.vim
@@ -1,0 +1,43 @@
+" Vim syntax file
+" Language:     wDiff (wordwise diff)
+" Maintainer:   Gerfried Fuchs <alfie@ist.org>
+" Last Change:  25 Apr 2001
+" URL:		http://alfie.ist.org/vim/syntax/wdiff.vim
+"
+" Comments are very welcome - but please make sure that you are commenting on
+" the latest version of this file.
+" SPAM is _NOT_ welcome - be ready to be reported!
+
+
+" For version 5.x: Clear all syntax items
+" For version 6.x: Quit when a syntax file was already loaded
+if version < 600
+  syn clear
+elseif exists("b:current_syntax")
+  finish
+endif
+
+
+syn region wdiffOld start=+\[-+ end=+-]+
+syn region wdiffNew start="{+" end="+}"
+
+
+" Define the default highlighting.
+" For version 5.7 and earlier: only when not done already
+" For version 5.8 and later: only when an item doesn't have highlighting yet
+if version >= 508 || !exists("did_wdiff_syn_inits")
+  let did_wdiff_syn_inits = 1
+  if version < 508
+    let did_wdiff_syn_inits = 1
+    command -nargs=+ HiLink hi link <args>
+  else
+    command -nargs=+ HiLink hi def link <args>
+  endif
+
+  HiLink wdiffOld       Special
+  HiLink wdiffNew       Identifier
+
+  delcommand HiLink
+endif
+
+let b:current_syntax = "wdiff"
--- /dev/null
+++ b/lib/vimfiles/syntax/web.vim
@@ -1,0 +1,39 @@
+" Vim syntax file
+" Language:	WEB
+" Maintainer:	Andreas Scherer <andreas.scherer@pobox.com>
+" Last Change:	April 30, 2001
+
+" Details of the WEB language can be found in the article by Donald E. Knuth,
+" "The WEB System of Structured Documentation", included as "webman.tex" in
+" the standard WEB distribution, available for anonymous ftp at
+" ftp://labrea.stanford.edu/pub/tex/web/.
+
+" For version 5.x: Clear all syntax items
+" For version 6.x: Quit when a syntax file was already loaded
+if version < 600
+  syntax clear
+elseif exists("b:current_syntax")
+  finish
+endif
+
+" Although WEB is the ur-language for the "Literate Programming" paradigm,
+" we base this syntax file on the modern superset, CWEB.  Note: This shortcut
+" may introduce some illegal constructs, e.g., CWEB's "@c" does _not_ start a
+" code section in WEB.  Anyway, I'm not a WEB programmer.
+if version < 600
+  source <sfile>:p:h/cweb.vim
+else
+  runtime! syntax/cweb.vim
+  unlet b:current_syntax
+endif
+
+" Replace C/C++ syntax by Pascal syntax.
+syntax include @webIncludedC <sfile>:p:h/pascal.vim
+
+" Double-@ means single-@, anywhere in the WEB source (as in CWEB).
+" Don't misinterpret "@'" as the start of a Pascal string.
+syntax match webIgnoredStuff "@[@']"
+
+let b:current_syntax = "web"
+
+" vim: ts=8
--- /dev/null
+++ b/lib/vimfiles/syntax/webmacro.vim
@@ -1,0 +1,82 @@
+" WebMacro syntax file
+" Language:     WebMacro
+" Maintainer:   Claudio Fleiner <claudio@fleiner.com>
+" URL:		http://www.fleiner.com/vim/syntax/webmacro.vim
+" Last Change:  2003 May 11
+
+" webmacro is a nice little language that you should
+" check out if you use java servlets.
+" webmacro: http://www.webmacro.org
+
+" For version 5.x: Clear all syntax items
+" For version 6.x: Quit when a syntax file was already loaded
+if !exists("main_syntax")
+  if version < 600
+    syntax clear
+  elseif exists("b:current_syntax")
+    finish
+  endif
+  let main_syntax = 'webmacro'
+endif
+
+
+if version < 600
+  source <sfile>:p:h/html.vim
+else
+  runtime! syntax/html.vim
+  unlet b:current_syntax
+endif
+
+syn cluster htmlPreProc add=webmacroIf,webmacroUse,webmacroBraces,webmacroParse,webmacroInclude,webmacroSet,webmacroForeach,webmacroComment
+
+syn match webmacroVariable "\$[a-zA-Z0-9.()]*;\="
+syn match webmacroNumber "[-+]\=\d\+[lL]\=" contained
+syn keyword webmacroBoolean true false contained
+syn match webmacroSpecial "\\." contained
+syn region  webmacroString   contained start=+"+ end=+"+ contains=webmacroSpecial,webmacroVariable
+syn region  webmacroString   contained start=+'+ end=+'+ contains=webmacroSpecial,webmacroVariable
+syn region webmacroList contained matchgroup=Structure start="\[" matchgroup=Structure end="\]" contains=webmacroString,webmacroVariable,webmacroNumber,webmacroBoolean,webmacroList
+
+syn region webmacroIf start="#if" start="#else" end="{"me=e-1 contains=webmacroVariable,webmacroNumber,webmacroString,webmacroBoolean,webmacroList nextgroup=webmacroBraces
+syn region webmacroForeach start="#foreach" end="{"me=e-1 contains=webmacroVariable,webmacroNumber,webmacroString,webmacroBoolean,webmacroList nextgroup=webmacroBraces
+syn match webmacroSet "#set .*$" contains=webmacroVariable,webmacroNumber,webmacroNumber,webmacroBoolean,webmacroString,webmacroList
+syn match webmacroInclude "#include .*$" contains=webmacroVariable,webmacroNumber,webmacroNumber,webmacroBoolean,webmacroString,webmacroList
+syn match webmacroParse "#parse .*$" contains=webmacroVariable,webmacroNumber,webmacroNumber,webmacroBoolean,webmacroString,webmacroList
+syn region webmacroUse matchgroup=PreProc start="#use .*" matchgroup=PreProc end="^-.*" contains=webmacroHash,@HtmlTop
+syn region webmacroBraces matchgroup=Structure start="{" matchgroup=Structure end="}" contained transparent
+syn match webmacroBracesError "[{}]"
+syn match webmacroComment "##.*$"
+syn match webmacroHash "[#{}\$]" contained
+
+" Define the default highlighting.
+" For version 5.7 and earlier: only when not done already
+" For version 5.8 and later: only when an item doesn't have highlighting yet
+if version >= 508 || !exists("did_webmacro_syn_inits")
+  if version < 508
+    let did_webmacro_syn_inits = 1
+    command -nargs=+ HiLink hi link <args>
+  else
+    command -nargs=+ HiLink hi def link <args>
+  endif
+
+  HiLink webmacroComment CommentTitle
+  HiLink webmacroVariable PreProc
+  HiLink webmacroIf webmacroStatement
+  HiLink webmacroForeach webmacroStatement
+  HiLink webmacroSet webmacroStatement
+  HiLink webmacroInclude webmacroStatement
+  HiLink webmacroParse webmacroStatement
+  HiLink webmacroStatement Function
+  HiLink webmacroNumber Number
+  HiLink webmacroBoolean Boolean
+  HiLink webmacroSpecial Special
+  HiLink webmacroString String
+  HiLink webmacroBracesError Error
+  delcommand HiLink
+endif
+
+let b:current_syntax = "webmacro"
+
+if main_syntax == 'webmacro'
+  unlet main_syntax
+endif
--- /dev/null
+++ b/lib/vimfiles/syntax/wget.vim
@@ -1,0 +1,194 @@
+" Wget syntax file
+" Filename:     wget.vim
+" Language:     Wget configuration file ( /etc/wgetrc ~/.wgetrc )
+" Maintainer:   Doug Kearns <djkea2@gus.gscit.monash.edu.au>
+" URL:          http://gus.gscit.monash.edu.au/~djkea2/vim/syntax/wget.vim
+" Last Change:  2005 Jul 24
+
+" TODO: all commands are actually underscore and hyphen insensitive, though
+"       they are normally named as listed below
+
+" For version 5.x: Clear all syntax items
+" For version 6.x: Quit when a syntax file was already loaded
+if version < 600
+  syntax clear
+elseif exists("b:current_syntax")
+  finish
+endif
+
+syn match   wgetComment "^\s*#.*$" contains=wgetTodo
+
+syn keyword wgetTodo TODO NOTE FIXME XXX contained
+
+syn match   wgetAssignment "^\s*[A-Za-z0-9_-]\+\s*=\s*.*$" contains=wgetCommand,wgetAssignmentOperator,wgetString,wgetBoolean,wgetNumber,wgetValue,wgetQuota,wgetRestriction,wgetTime
+
+syn match   wgetAssignmentOperator "=" contained
+
+syn region  wgetString start=+"+ skip=+\\\\\|\\"+ end=+"+ contained oneline
+syn region  wgetString start=+'+ skip=+\\\\\|\\'+ end=+'+ contained oneline
+
+" Note: make this a match so that always_rest matches properly
+syn case ignore
+syn match   wgetBoolean	"\<on\|off\|always\|never\|1\|0\>" contained
+syn case match
+
+syn match   wgetNumber	"\<\d\+\|inf\>"		contained
+syn match   wgetQuota	"\<\d\+[kKmM]\?\>"	contained
+syn match   wgetTime	"\<\d\+[smhdw]\>"	contained
+
+syn case ignore
+syn keyword wgetValue	default binary mega giga micro contained
+syn case match
+
+syn match   wgetRestriction  "\<\%(windows\|unix\)\%(,nocontrol\)\=\>"	contained
+syn match   wgetRestriction  "\<nocontrol\>"				contained
+
+syn case ignore
+syn match wgetCommand "^\s*accept" contained
+syn match wgetCommand "^\s*add[-_]\=hostdir" contained
+syn match wgetCommand "^\s*always[-_]\=rest" contained
+syn match wgetCommand "^\s*background" contained
+syn match wgetCommand "^\s*backup[-_]\=converted" contained
+syn match wgetCommand "^\s*backups" contained
+syn match wgetCommand "^\s*base" contained
+syn match wgetCommand "^\s*bind[-_]\=address" contained
+syn match wgetCommand "^\s*ca[-_]\=certificate" contained
+syn match wgetCommand "^\s*ca[-_]\=directory" contained
+syn match wgetCommand "^\s*cache" contained
+syn match wgetCommand "^\s*certificate" contained
+syn match wgetCommand "^\s*certificate[-_]\=type" contained
+syn match wgetCommand "^\s*check[-_]\=certificate" contained
+syn match wgetCommand "^\s*connect[-_]\=timeout" contained
+syn match wgetCommand "^\s*continue" contained
+syn match wgetCommand "^\s*convert[-_]\=links" contained
+syn match wgetCommand "^\s*cookies" contained
+syn match wgetCommand "^\s*cut[-_]\=dirs" contained
+syn match wgetCommand "^\s*debug" contained
+syn match wgetCommand "^\s*delete[-_]\=after" contained
+syn match wgetCommand "^\s*dns[-_]\=cache" contained
+syn match wgetCommand "^\s*dns[-_]\=timeout" contained
+syn match wgetCommand "^\s*dir[-_]\=prefix" contained
+syn match wgetCommand "^\s*dir[-_]\=struct" contained
+syn match wgetCommand "^\s*domains" contained
+syn match wgetCommand "^\s*dot[-_]\=bytes" contained
+syn match wgetCommand "^\s*dots[-_]\=in[-_]\=line" contained
+syn match wgetCommand "^\s*dot[-_]\=spacing" contained
+syn match wgetCommand "^\s*dot[-_]\=style" contained
+syn match wgetCommand "^\s*egd[-_]\=file" contained
+syn match wgetCommand "^\s*exclude[-_]\=directories" contained
+syn match wgetCommand "^\s*exclude[-_]\=domains" contained
+syn match wgetCommand "^\s*follow[-_]\=ftp" contained
+syn match wgetCommand "^\s*follow[-_]\=tags" contained
+syn match wgetCommand "^\s*force[-_]\=html" contained
+syn match wgetCommand "^\s*ftp[-_]\=passw\(or\)\=d" contained
+syn match wgetCommand "^\s*ftp[-_]\=user" contained
+syn match wgetCommand "^\s*ftp[-_]\=proxy" contained
+syn match wgetCommand "^\s*glob" contained
+syn match wgetCommand "^\s*header" contained
+syn match wgetCommand "^\s*html[-_]\=extension" contained
+syn match wgetCommand "^\s*htmlify" contained
+syn match wgetCommand "^\s*http[-_]\=keep[-_]\=alive" contained
+syn match wgetCommand "^\s*http[-_]\=passwd" contained
+syn match wgetCommand "^\s*http[-_]\=password" contained
+syn match wgetCommand "^\s*http[-_]\=proxy" contained
+syn match wgetCommand "^\s*https[-_]\=proxy" contained
+syn match wgetCommand "^\s*http[-_]\=user" contained
+syn match wgetCommand "^\s*ignore[-_]\=length" contained
+syn match wgetCommand "^\s*ignore[-_]\=tags" contained
+syn match wgetCommand "^\s*include[-_]\=directories" contained
+syn match wgetCommand "^\s*inet4[-_]\=only" contained
+syn match wgetCommand "^\s*inet6[-_]\=only" contained
+syn match wgetCommand "^\s*input" contained
+syn match wgetCommand "^\s*keep[-_]\=session[-_]\=cookies" contained
+syn match wgetCommand "^\s*kill[-_]\=longer" contained
+syn match wgetCommand "^\s*limit[-_]\=rate" contained
+syn match wgetCommand "^\s*load[-_]\=cookies" contained
+syn match wgetCommand "^\s*logfile" contained
+syn match wgetCommand "^\s*login" contained
+syn match wgetCommand "^\s*mirror" contained
+syn match wgetCommand "^\s*netrc" contained
+syn match wgetCommand "^\s*no[-_]\=clobber" contained
+syn match wgetCommand "^\s*no[-_]\=parent" contained
+syn match wgetCommand "^\s*no[-_]\=proxy" contained
+" Note: this option is deprecated, use 'tries' instead
+syn match wgetCommand "^\s*numtries" contained
+syn match wgetCommand "^\s*output[-_]\=document" contained
+syn match wgetCommand "^\s*page[-_]\=requisites" contained
+syn match wgetCommand "^\s*passive[-_]\=ftp" contained
+syn match wgetCommand "^\s*passwd" contained
+syn match wgetCommand "^\s*password" contained
+syn match wgetCommand "^\s*post[-_]\=data" contained
+syn match wgetCommand "^\s*post[-_]\=file" contained
+syn match wgetCommand "^\s*prefer[-_]\=family" contained
+syn match wgetCommand "^\s*preserve[-_]\=permissions" contained
+syn match wgetCommand "^\s*private[-_]\=key" contained
+syn match wgetCommand "^\s*private[-_]\=key[-_]\=type" contained
+syn match wgetCommand "^\s*progress" contained
+syn match wgetCommand "^\s*protocol[-_]\=directories" contained
+syn match wgetCommand "^\s*proxy[-_]\=passwd" contained
+syn match wgetCommand "^\s*proxy[-_]\=password" contained
+syn match wgetCommand "^\s*proxy[-_]\=user" contained
+syn match wgetCommand "^\s*quiet" contained
+syn match wgetCommand "^\s*quota" contained
+syn match wgetCommand "^\s*random[-_]\=file" contained
+syn match wgetCommand "^\s*random[-_]\=wait" contained
+syn match wgetCommand "^\s*read[-_]\=timeout" contained
+syn match wgetCommand "^\s*reclevel" contained
+syn match wgetCommand "^\s*recursive" contained
+syn match wgetCommand "^\s*referer" contained
+syn match wgetCommand "^\s*reject" contained
+syn match wgetCommand "^\s*relative[-_]\=only" contained
+syn match wgetCommand "^\s*remove[-_]\=listing" contained
+syn match wgetCommand "^\s*restrict[-_]\=file[-_]\=names" contained
+syn match wgetCommand "^\s*retr[-_]\=symlinks" contained
+syn match wgetCommand "^\s*retry[-_]\=connrefused" contained
+syn match wgetCommand "^\s*robots" contained
+syn match wgetCommand "^\s*save[-_]\=cookies" contained
+syn match wgetCommand "^\s*save[-_]\=headers" contained
+syn match wgetCommand "^\s*secure[-_]\=protocol" contained
+syn match wgetCommand "^\s*server[-_]\=response" contained
+" Note: this option was removed in wget 1.8
+syn match wgetCommand "^\s*simple[-_]\=host[-_]\=check" contained
+syn match wgetCommand "^\s*span[-_]\=hosts" contained
+syn match wgetCommand "^\s*spider" contained
+syn match wgetCommand "^\s*strict[-_]\=comments" contained
+syn match wgetCommand "^\s*sslcertfile" contained
+syn match wgetCommand "^\s*sslcertkey" contained
+syn match wgetCommand "^\s*timeout" contained
+syn match wgetCommand "^\s*time[-_]\=stamping" contained
+syn match wgetCommand "^\s*tries" contained
+syn match wgetCommand "^\s*user" contained
+syn match wgetCommand "^\s*use[-_]\=proxy" contained
+syn match wgetCommand "^\s*user[-_]\=agent" contained
+syn match wgetCommand "^\s*verbose" contained
+syn match wgetCommand "^\s*wait" contained
+syn match wgetCommand "^\s*wait[-_]\=retry" contained
+syn case match
+
+" Define the default highlighting.
+" For version 5.7 and earlier: only when not done already
+" For version 5.8 and later: only when an item doesn't have highlighting yet
+if version >= 508 || !exists("did_wget_syn_inits")
+  if version < 508
+    let did_wget_syn_inits = 1
+    command -nargs=+ HiLink hi link <args>
+  else
+    command -nargs=+ HiLink hi def link <args>
+  endif
+
+  HiLink wgetAssignmentOperator Special
+  HiLink wgetBoolean            Boolean
+  HiLink wgetCommand            Identifier
+  HiLink wgetComment            Comment
+  HiLink wgetNumber             Number
+  HiLink wgetQuota              Number
+  HiLink wgetString             String
+  HiLink wgetTodo               Todo
+  HiLink wgetValue              Constant
+
+  delcommand HiLink
+endif
+
+let b:current_syntax = "wget"
+
+" vim: ts=8
--- /dev/null
+++ b/lib/vimfiles/syntax/whitespace.vim
@@ -1,0 +1,13 @@
+" Simplistic way to make spaces and Tabs visible
+
+" This can be added to an already active syntax.
+
+syn match Space " "
+syn match Tab "\t"
+if &background == "dark"
+  hi def Space ctermbg=darkred guibg=#500000
+  hi def Tab ctermbg=darkgreen guibg=#003000
+else
+  hi def Space ctermbg=lightred guibg=#ffd0d0
+  hi def Tab ctermbg=lightgreen guibg=#d0ffd0
+endif
--- /dev/null
+++ b/lib/vimfiles/syntax/winbatch.vim
@@ -1,0 +1,187 @@
+" Vim syntax file
+" Language:	WinBatch/Webbatch (*.wbt, *.web)
+" Maintainer:	dominique@mggen.com
+" URL:		http://www.mggen.com/vim/syntax/winbatch.zip
+" Last change:	2001 May 10
+
+" For version 5.x: Clear all syntax items
+" For version 6.x: Quit when a syntax file was already loaded
+if version < 600
+  syntax clear
+elseif exists("b:current_syntax")
+  finish
+endif
+
+syn case ignore
+
+syn keyword winbatchCtl	if then else endif break end return exit next
+syn keyword winbatchCtl while for gosub goto switch select to case
+syn keyword winbatchCtl endselect endwhile endselect endswitch
+
+" String
+syn region  winbatchVar		start=+%+  end=+%+
+" %var% in strings
+syn region  winbatchString	start=+"+  end=+"+ contains=winbatchVar
+
+syn match winbatchComment	";.*$"
+syn match winbatchLabel		"^\ *:[0-9a-zA-Z_\-]\+\>"
+
+" constant (bezgin by @)
+syn match winbatchConstant	"@[0_9a-zA-Z_\-]\+"
+
+" number
+syn match winbatchNumber	"\<[0-9]\+\(u\=l\=\|lu\|f\)\>"
+
+syn keyword winbatchImplicit aboveicons acc_attrib acc_chng_nt acc_control acc_create
+syn keyword winbatchImplicit acc_delete acc_full_95 acc_full_nt acc_list acc_pfull_nt
+syn keyword winbatchImplicit acc_pmang_nt acc_print_nt acc_read acc_read_95 acc_read_nt
+syn keyword winbatchImplicit acc_write amc arrange ascending attr_a attr_a attr_ci attr_ci
+syn keyword winbatchImplicit attr_dc attr_dc attr_di attr_di attr_dm attr_dm attr_h attr_h
+syn keyword winbatchImplicit attr_ic attr_ic attr_p attr_p attr_ri attr_ri attr_ro attr_ro
+syn keyword winbatchImplicit attr_sh attr_sh attr_sy attr_sy attr_t attr_t attr_x attr_x
+syn keyword winbatchImplicit avogadro backscan boltzmann cancel capslock check columns
+syn keyword winbatchImplicit commonformat cr crlf ctrl default default deg2rad descending
+syn keyword winbatchImplicit disable drive electric enable eulers false faraday float8
+syn keyword winbatchImplicit fwdscan gftsec globalgroup gmtsec goldenratio gravitation hidden
+syn keyword winbatchImplicit icon lbutton lclick ldblclick lf lightmps lightmtps localgroup
+syn keyword winbatchImplicit magfield major mbokcancel mbutton mbyesno mclick mdblclick minor
+syn keyword winbatchImplicit msformat multiple ncsaformat no none none noresize normal
+syn keyword winbatchImplicit notify nowait numlock off on open parsec parseonly pi
+syn keyword winbatchImplicit planckergs planckjoules printer rad2deg rbutton rclick rdblclick
+syn keyword winbatchImplicit regclasses regcurrent regmachine regroot regusers rows save
+syn keyword winbatchImplicit scrolllock server shift single sorted stack string tab tile
+syn keyword winbatchImplicit true uncheck unsorted wait wholesection word1 word2 word4 yes
+syn keyword winbatchImplicit zoomed about abs acos addextender appexist appwaitclose asin
+syn keyword winbatchImplicit askfilename askfiletext askitemlist askline askpassword askyesno
+syn keyword winbatchImplicit atan average beep binaryalloc binarycopy binaryeodget binaryeodset
+syn keyword winbatchImplicit binaryfree binaryhashrec binaryincr binaryincr2 binaryincr4
+syn keyword winbatchImplicit binaryincrflt binaryindex binaryindexnc binaryoletype binarypeek
+syn keyword winbatchImplicit binarypeek2 binarypeek4 binarypeekflt binarypeekstr binarypoke
+syn keyword winbatchImplicit binarypoke2 binarypoke4 binarypokeflt binarypokestr binaryread
+syn keyword winbatchImplicit binarysort binarystrcnt binarywrite boxbuttondraw boxbuttonkill
+syn keyword winbatchImplicit boxbuttonstat boxbuttonwait boxcaption boxcolor
+syn keyword winbatchImplicit boxdataclear boxdatatag
+syn keyword winbatchImplicit boxdestroy boxdrawcircle boxdrawline boxdrawrect boxdrawtext
+syn keyword winbatchImplicit boxesup boxmapmode boxnew boxopen boxpen boxshut boxtext boxtextcolor
+syn keyword winbatchImplicit boxtextfont boxtitle boxupdates break buttonnames by call
+syn keyword winbatchImplicit callext ceiling char2num clipappend clipget clipput
+syn keyword winbatchImplicit continue cos cosh datetime
+syn keyword winbatchImplicit ddeexecute ddeinitiate ddepoke dderequest ddeterminate
+syn keyword winbatchImplicit ddetimeout debug debugdata decimals delay dialog
+syn keyword winbatchImplicit dialogbox dirattrget dirattrset dirchange direxist
+syn keyword winbatchImplicit dirget dirhome diritemize dirmake dirremove dirrename
+syn keyword winbatchImplicit dirwindows diskexist diskfree diskinfo diskscan disksize
+syn keyword winbatchImplicit diskvolinfo display dllcall dllfree dllhinst dllhwnd dllload
+syn keyword winbatchImplicit dosboxcursorx dosboxcursory dosboxgetall dosboxgetdata
+syn keyword winbatchImplicit dosboxheight dosboxscrmode dosboxversion dosboxwidth dosversion
+syn keyword winbatchImplicit drop edosgetinfo edosgetvar edoslistvars edospathadd edospathchk
+syn keyword winbatchImplicit edospathdel edossetvar
+syn keyword winbatchImplicit endsession envgetinfo envgetvar environment
+syn keyword winbatchImplicit environset envitemize envlistvars envpathadd envpathchk
+syn keyword winbatchImplicit envpathdel envsetvar errormode exclusive execute exetypeinfo
+syn keyword winbatchImplicit exp fabs fileappend fileattrget fileattrset fileclose
+syn keyword winbatchImplicit filecompare filecopy filedelete fileexist fileextension filefullname
+syn keyword winbatchImplicit fileitemize filelocate filemapname filemove filenameeval1
+syn keyword winbatchImplicit filenameeval2 filenamelong filenameshort fileopen filepath
+syn keyword winbatchImplicit fileread filerename fileroot filesize filetimecode filetimeget
+syn keyword winbatchImplicit filetimeset filetimetouch fileverinfo filewrite fileymdhms
+syn keyword winbatchImplicit findwindow floor getexacttime gettickcount
+syn keyword winbatchImplicit iconarrange iconreplace ignoreinput inidelete inideletepvt
+syn keyword winbatchImplicit iniitemize iniitemizepvt iniread inireadpvt iniwrite iniwritepvt
+syn keyword winbatchImplicit installfile int intcontrol isdefined isfloat isint iskeydown
+syn keyword winbatchImplicit islicensed isnumber itemcount itemextract iteminsert itemlocate
+syn keyword winbatchImplicit itemremove itemselect itemsort keytoggleget keytoggleset
+syn keyword winbatchImplicit lasterror log10 logdisk loge max message min mod mouseclick
+syn keyword winbatchImplicit mouseclickbtn mousedrag mouseinfo mousemove msgtextget n3attach
+syn keyword winbatchImplicit n3captureend n3captureprt n3chgpassword n3detach n3dirattrget
+syn keyword winbatchImplicit n3dirattrset n3drivepath n3drivepath2 n3drivestatus n3fileattrget
+syn keyword winbatchImplicit n3fileattrset n3getloginid n3getmapped n3getnetaddr n3getuser
+syn keyword winbatchImplicit n3getuserid n3logout n3map n3mapdelete n3mapdir n3maproot n3memberdel
+syn keyword winbatchImplicit n3memberget n3memberset n3msgsend n3msgsendall n3serverinfo
+syn keyword winbatchImplicit n3serverlist n3setsrchdrv n3usergroups n3version n4attach
+syn keyword winbatchImplicit n4captureend n4captureprt n4chgpassword n4detach n4dirattrget
+syn keyword winbatchImplicit n4dirattrset n4drivepath n4drivestatus n4fileattrget n4fileattrset
+syn keyword winbatchImplicit n4getloginid n4getmapped n4getnetaddr n4getuser n4getuserid
+syn keyword winbatchImplicit n4login n4logout n4map n4mapdelete n4mapdir n4maproot n4memberdel
+syn keyword winbatchImplicit n4memberget n4memberset n4msgsend n4msgsendall n4serverinfo
+syn keyword winbatchImplicit n4serverlist n4setsrchdrv n4usergroups n4version netadddrive
+syn keyword winbatchImplicit netaddprinter netcancelcon netdirdialog netgetcon netgetuser
+syn keyword winbatchImplicit netinfo netresources netversion num2char objectclose
+syn keyword winbatchImplicit objectopen parsedata pause playmedia playmidi playwaveform
+syn keyword winbatchImplicit print random regapp regclosekey regconnect regcreatekey
+syn keyword winbatchImplicit regdeletekey regdelvalue regentrytype regloadhive regopenkey
+syn keyword winbatchImplicit regquerybin regquerydword regqueryex regqueryexpsz regqueryitem
+syn keyword winbatchImplicit regquerykey regquerymulsz regqueryvalue regsetbin
+syn keyword winbatchImplicit regsetdword regsetex regsetexpsz regsetmulsz regsetvalue
+syn keyword winbatchImplicit regunloadhive reload reload rtstatus run runenviron
+syn keyword winbatchImplicit runexit runhide runhidewait runicon runiconwait runshell runwait
+syn keyword winbatchImplicit runzoom runzoomwait sendkey sendkeyschild sendkeysto
+syn keyword winbatchImplicit sendmenusto shellexecute shortcutedit shortcutextra shortcutinfo
+syn keyword winbatchImplicit shortcutmake sin sinh snapshot sounds sqrt
+syn keyword winbatchImplicit srchfree srchinit srchnext strcat strcharcount strcmp
+syn keyword winbatchImplicit strfill strfix strfixchars stricmp strindex strlen
+syn keyword winbatchImplicit strlower strreplace strscan strsub strtrim strupper
+syn keyword winbatchImplicit tan tanh tcpaddr2host tcpftpchdir tcpftpclose tcpftpget
+syn keyword winbatchImplicit tcpftplist tcpftpmode tcpftpopen tcpftpput tcphost2addr tcphttpget
+syn keyword winbatchImplicit tcphttppost tcpparmget tcpparmset tcpping tcpsmtp terminate
+syn keyword winbatchImplicit textbox textboxsort textoutbufdel textoutbuffer textoutdebug
+syn keyword winbatchImplicit textoutfree textoutinfo textoutreset textouttrack textouttrackb
+syn keyword winbatchImplicit textouttrackp textoutwait textselect timeadd timedate
+syn keyword winbatchImplicit timedelay timediffdays timediffsecs timejulianday timejultoymd
+syn keyword winbatchImplicit timesubtract timewait timeymdhms version versiondll
+syn keyword winbatchImplicit w3addcon w3cancelcon w3dirbrowse w3getcaps w3getcon w3netdialog
+syn keyword winbatchImplicit w3netgetuser w3prtbrowse w3version w95accessadd w95accessdel
+syn keyword winbatchImplicit w95adddrive w95addprinter w95cancelcon w95dirdialog w95getcon
+syn keyword winbatchImplicit w95getuser w95resources w95shareadd w95sharedel w95shareset
+syn keyword winbatchImplicit w95version waitforkey wallpaper webbaseconv webcloselog
+syn keyword winbatchImplicit webcmddata webcondata webcounter webdatdata webdumperror webhashcode
+syn keyword winbatchImplicit webislocal weblogline webopenlog webout weboutfile webparamdata
+syn keyword winbatchImplicit webparamnames websettimeout webverifycard winactivate
+syn keyword winbatchImplicit winactivchild winarrange winclose winclosenot winconfig winexename
+syn keyword winbatchImplicit winexist winparset winparget winexistchild wingetactive
+syn keyword winbatchImplicit winhelp winhide winiconize winidget winisdos winitemchild
+syn keyword winbatchImplicit winitemize winitemnameid winmetrics winname winparmget
+syn keyword winbatchImplicit winparmset winplace winplaceget winplaceset
+syn keyword winbatchImplicit winposition winresources winshow winstate winsysinfo
+syn keyword winbatchImplicit wintitle winversion winwaitchild winwaitclose winwaitexist
+syn keyword winbatchImplicit winzoom wnaddcon wncancelcon wncmptrinfo wndialog
+syn keyword winbatchImplicit wndlgbrowse wndlgcon wndlgcon2 wndlgcon3
+syn keyword winbatchImplicit wndlgcon4 wndlgdiscon wndlgnoshare wndlgshare wngetcaps
+syn keyword winbatchImplicit wngetcon wngetuser wnnetnames wnrestore wnservers wnsharecnt
+syn keyword winbatchImplicit wnsharename wnsharepath wnshares wntaccessadd wntaccessdel
+syn keyword winbatchImplicit wntaccessget wntadddrive wntaddprinter wntcancelcon wntdirdialog
+syn keyword winbatchImplicit wntgetcon wntgetuser wntlistgroups wntmemberdel wntmemberget
+syn keyword winbatchImplicit wntmembergrps wntmemberlist wntmemberset wntresources wntshareadd
+syn keyword winbatchImplicit wntsharedel wntshareset wntversion wnversion wnwrkgroups wwenvunload
+syn keyword winbatchImplicit xbaseconvert xcursorset xdisklabelget xdriveready xextenderinfo
+syn keyword winbatchImplicit xgetchildhwnd xgetelapsed xhex xmemcompact xmessagebox
+syn keyword winbatchImplicit xsendmessage xverifyccard yield
+
+" Define the default highlighting.
+" For version 5.7 and earlier: only when not done already
+" For version 5.8 and later: only when an item doesn't have highlighting yet
+if version >= 508 || !exists("did_winbatch_syntax_inits")
+  if version < 508
+    let did_winbatch_syntax_inits = 1
+    command -nargs=+ HiLink hi link <args>
+  else
+    command -nargs=+ HiLink hi def link <args>
+  endif
+
+  HiLink winbatchLabel		PreProc
+  HiLink winbatchCtl		Operator
+  HiLink winbatchStatement	Statement
+  HiLink winbatchTodo		Todo
+  HiLink winbatchString		String
+  HiLink winbatchVar		Type
+  HiLink winbatchComment	Comment
+  HiLink winbatchImplicit	Special
+  HiLink winbatchNumber		Number
+  HiLink winbatchConstant	StorageClass
+
+  delcommand HiLink
+endif
+
+let b:current_syntax = "winbatch"
+
+" vim: ts=8
--- /dev/null
+++ b/lib/vimfiles/syntax/wml.vim
@@ -1,0 +1,172 @@
+" Vim syntax file
+" Language:     WML - Website MetaLanguage
+" Maintainer:   Gerfried Fuchs <alfie@ist.org>
+" Filenames:    *.wml
+" Last Change:  07 Feb 2002
+" URL:		http://alfie.ist.org/software/vim/syntax/wml.vim
+"
+" Original Version: Craig Small <csmall@eye-net.com.au>
+
+" Comments are very welcome - but please make sure that you are commenting on
+" the latest version of this file.
+" SPAM is _NOT_ welcome - be ready to be reported!
+
+"  If you are looking for the "Wireless Markup Language" syntax file,
+"  please take a look at the wap.vim file done by Ralf Schandl, soon in a
+"  vim-package around your corner :)
+
+
+" For version 5.x: Clear all syntax items
+" For version 6.x: Quit when a syntax file was already loaded
+if version < 600
+  syn clear
+elseif exists("b:current_syntax")
+  finish
+endif
+
+
+" A lot of the web stuff looks like HTML so we load that first
+if version < 600
+  so <sfile>:p:h/html.vim
+else
+  runtime! syntax/html.vim
+endif
+unlet b:current_syntax
+
+if !exists("main_syntax")
+  let main_syntax = 'wml'
+endif
+
+" special character
+syn match wmlNextLine	"\\$"
+
+" Redfine htmlTag
+syn clear htmlTag
+syn region  htmlTag  start=+<[^/<]+ end=+>+  contains=htmlTagN,htmlString,htmlArg,htmlValue,htmlTagError,htmlEvent,htmlCssDefinition
+
+"
+" Add in extra Arguments used by wml
+syn keyword htmlTagName contained gfont imgbg imgdot lowsrc
+syn keyword htmlTagName contained navbar:define navbar:header
+syn keyword htmlTagName contained navbar:footer navbar:prolog
+syn keyword htmlTagName contained navbar:epilog navbar:button
+syn keyword htmlTagName contained navbar:filter navbar:debug
+syn keyword htmlTagName contained navbar:render
+syn keyword htmlTagName contained preload rollover
+syn keyword htmlTagName contained space hspace vspace over
+syn keyword htmlTagName contained ps ds pi ein big sc spaced headline
+syn keyword htmlTagName contained ue subheadline zwue verbcode
+syn keyword htmlTagName contained isolatin pod sdf text url verbatim
+syn keyword htmlTagName contained xtable
+syn keyword htmlTagName contained csmap fsview import box
+syn keyword htmlTagName contained case:upper case:lower
+syn keyword htmlTagName contained grid cell info lang: logo page
+syn keyword htmlTagName contained set-var restore
+syn keyword htmlTagName contained array:push array:show set-var ifdef
+syn keyword htmlTagName contained say m4 symbol dump enter divert
+syn keyword htmlTagName contained toc
+syn keyword htmlTagName contained wml card do refresh oneevent catch spawn
+
+"
+" The wml arguments
+syn keyword htmlArg contained adjust background base bdcolor bdspace
+syn keyword htmlArg contained bdwidth complete copyright created crop
+syn keyword htmlArg contained direction description domainname eperlfilter
+syn keyword htmlArg contained file hint imgbase imgstar interchar interline
+syn keyword htmlArg contained keephr keepindex keywords layout spacing
+syn keyword htmlArg contained padding nonetscape noscale notag notypo
+syn keyword htmlArg contained onload oversrc pos select slices style
+syn keyword htmlArg contained subselected txtcol_select txtcol_normal
+syn keyword htmlArg contained txtonly via
+syn keyword htmlArg contained mode columns localsrc ordered
+
+
+" Lines starting with an # are usually comments
+syn match   wmlComment     "^\s*#.*"
+" The different exceptions to comments
+syn match   wmlSharpBang   "^#!.*"
+syn match   wmlUsed	   contained "\s\s*[A-Za-z:_-]*"
+syn match   wmlUse	   "^\s*#\s*use\s\+" contains=wmlUsed
+syn match   wmlInclude	   "^\s*#\s*include.+"
+
+syn region  wmlBody	   contained start=+<<+ end=+>>+
+
+syn match   wmlLocationId  contained "[A-Za-z]\+"
+syn region  wmlLocation    start=+<<+ end=+>>+ contains=wmlLocationId
+"syn region  wmlLocation    start=+{#+ end=+#}+ contains=wmlLocationId
+"syn region  wmlLocationed  contained start=+<<+ end=+>>+ contains=wmlLocationId
+
+syn match   wmlDivert      "\.\.[a-zA-Z_]\+>>"
+syn match   wmlDivertEnd   "<<\.\."
+" new version
+"syn match   wmlDivert      "{#[a-zA-Z_]\+#:"
+"syn match   wmlDivertEnd   ":##}"
+
+syn match   wmlDefineName  contained "\s\+[A-Za-z-]\+"
+syn region  htmlTagName    start="\<\(define-tag\|define-region\)" end="\>" contains=wmlDefineName
+
+" The perl include stuff
+if main_syntax != 'perl'
+  " Perl script
+  if version < 600
+    syn include @wmlPerlScript <sfile>:p:h/perl.vim
+  else
+    syn include @wmlPerlScript syntax/perl.vim
+  endif
+  unlet b:current_syntax
+
+  syn region perlScript   start=+<perl>+ keepend end=+</perl>+ contains=@wmlPerlScript,wmlPerlTag
+" eperl between '<:' and ':>'  -- Alfie [1999-12-26]
+  syn region perlScript   start=+<:+ keepend end=+:>+ contains=@wmlPerlScript,wmlPerlTag
+  syn match    wmlPerlTag  contained "</*perl>" contains=wmlPerlTagN
+  syn keyword  wmlPerlTagN contained perl
+
+  hi link   wmlPerlTag  htmlTag
+  hi link   wmlPerlTagN htmlStatement
+endif
+
+" verbatim tags -- don't highlight anything in between  -- Alfie [2002-02-07]
+syn region  wmlVerbatimText start=+<verbatim>+ keepend end=+</verbatim>+ contains=wmlVerbatimTag
+syn match   wmlVerbatimTag  contained "</*verbatim>" contains=wmlVerbatimTagN
+syn keyword wmlVerbatimTagN contained verbatim
+hi link     wmlVerbatimTag  htmlTag
+hi link     wmlVerbatimTagN htmlStatement
+
+if main_syntax == "html"
+  syn sync match wmlHighlight groupthere NONE "</a-zA-Z]"
+  syn sync match wmlHighlight groupthere perlScript "<perl>"
+  syn sync match wmlHighlightSkip "^.*['\"].*$"
+  syn sync minlines=10
+endif
+
+" Define the default highlighting.
+" For version 5.7 and earlier: only when not done already
+" For version 5.8 and later: only when an item doesn't have highlighting yet
+if version >= 508 || !exists("did_wml_syn_inits")
+  let did_wml_syn_inits = 1
+  if version < 508
+    let did_wml_syn_inits = 1
+    command -nargs=+ HiLink hi link <args>
+  else
+    command -nargs=+ HiLink hi def link <args>
+  endif
+
+  HiLink wmlNextLine	Special
+  HiLink wmlUse		Include
+  HiLink wmlUsed	String
+  HiLink wmlBody	Special
+  HiLink wmlDiverted	Label
+  HiLink wmlDivert	Delimiter
+  HiLink wmlDivertEnd	Delimiter
+  HiLink wmlLocationId	Label
+  HiLink wmlLocation	Delimiter
+" HiLink wmlLocationed	Delimiter
+  HiLink wmlDefineName	String
+  HiLink wmlComment	Comment
+  HiLink wmlInclude	Include
+  HiLink wmlSharpBang	PreProc
+
+  delcommand HiLink
+endif
+
+let b:current_syntax = "wml"
--- /dev/null
+++ b/lib/vimfiles/syntax/wsh.vim
@@ -1,0 +1,45 @@
+" Vim syntax file
+" Language:	Windows Scripting Host
+" Maintainer:	Paul Moore <pf_moore AT yahoo.co.uk>
+" Last Change:	Fre, 24 Nov 2000 21:54:09 +0100
+
+" This reuses the XML, VB and JavaScript syntax files. While VB is not
+" VBScript, it's close enough for us. No attempt is made to handle
+" other languages.
+" Send comments, suggestions and requests to the maintainer.
+
+" Quit when a syntax file was already loaded
+if exists("b:current_syntax")
+  finish
+endif
+
+let s:wsh_cpo_save = &cpo
+set cpo&vim
+
+runtime! syntax/xml.vim
+unlet b:current_syntax
+
+syn case ignore
+syn include @wshVBScript <sfile>:p:h/vb.vim
+unlet b:current_syntax
+syn include @wshJavaScript <sfile>:p:h/javascript.vim
+unlet b:current_syntax
+syn region wshVBScript
+    \ matchgroup=xmlTag    start="<script[^>]*VBScript\(>\|[^>]*[^/>]>\)"
+    \ matchgroup=xmlEndTag end="</script>"
+    \ fold
+    \ contains=@wshVBScript
+    \ keepend
+syn region wshJavaScript
+    \ matchgroup=xmlTag    start="<script[^>]*J\(ava\)\=Script\(>\|[^>]*[^/>]>\)"
+    \ matchgroup=xmlEndTag end="</script>"
+    \ fold
+    \ contains=@wshJavaScript
+    \ keepend
+
+syn cluster xmlRegionHook add=wshVBScript,wshJavaScript
+
+let b:current_syntax = "wsh"
+
+let &cpo = s:wsh_cpo_save
+unlet s:wsh_cpo_save
--- /dev/null
+++ b/lib/vimfiles/syntax/wsml.vim
@@ -1,0 +1,125 @@
+" Vim syntax file
+" Language:     WSML
+" Maintainer:   Thomas Haselwanter <thomas.haselwanter@deri.org>
+" URL:		none
+" Last Change:  2006 Apr 30
+
+" Quit when a syntax file was already loaded
+if version < 600
+  syntax clear
+elseif exists("b:current_syntax")
+  finish
+endif
+
+" WSML
+syn keyword wsmlHeader		wsmlVariant
+syn keyword wsmlNamespace	namespace
+syn keyword wsmlTopLevel	concept instance relationInstance ofType usesMediator usesService relation sharedVariables importsOntology
+syn keyword wsmlOntology	hasValue memberOf ofType impliesType subConceptOf
+syn keyword wsmlAxiom		axiom definedBy
+syn keyword wsmlService		assumption effect postcondition precondition capability interface
+syn keyword wsmlTopLevel	ooMediator wwMediator wgMediator ggMediator
+syn keyword wsmlMediation	usesService source target
+syn match wsmlDataTypes	        "\( _string\| _decimal\| _integer\| _float\| _double\| _iri\| _sqname\| _boolean\| _duration\| _dateTime\| _time\| _date\| _gyearmonth\| _gyear\| _gmonthday\| _gday\| _gmonth\| _hexbinary\| _base64binary\)\((\S*)\)\?" contains=wsmlString,wsmlNumber,wsmlCharacter
+syn keyword wsmlTopLevel	goal webService ontology
+syn keyword wsmlKeywordsInsideLEs	true false memberOf hasValue subConceptOf ofType impliesType and or implies impliedBy equivalent neg naf forall exists
+syn keyword wsmlNFP		nfp endnfp nonFunctionalProperties endNonFunctionalProperties
+syn region wsmlNFPregion	start="nfp\|nonFunctionalProperties" end="endnfp\|endNonFunctionalProperties" contains=ALL
+syn region wsmlNamespace	start="namespace" end="}" contains=wsmlIdentifier
+syn match wsmlOperator		"!=\|:=:\|=<\|>=\|=\|+\|\*\|/\|<->\|->\|<-\|:-\|!-\|-\|<\|>"
+syn match wsmlBrace		"(\|)\|\[\|\]\|{\|}"
+syn match wsmlIdentifier	+_"\S*"+
+syn match wsmlIdentifier	"_#\d*"
+syn match wsmlSqName		"[0-9A-Za-z]\+#[0-9A-Za-z]\+"
+syn match wsmlVariable		"?[0-9A-Za-z]\+"
+
+" ASM-specific code
+syn keyword wsmlBehavioral	choreography orchestration transitionRules
+syn keyword wsmlChoreographyPri	stateSignature in out shared static controlled 
+syn keyword wsmlChoreographySec with do withGrounding forall endForall choose if then endIf
+syn match wsmlChoreographyTer   "\(\s\|\_^\)\(add\|delete\|update\)\s*(.*)" contains=wsmlKeywordsInsideLEs,wsmlIdentifier,wsmlSqName,wsmlString,wsmlNumber,wsmlDataTypes,wsmlVariable
+
+" Comments
+syn keyword wsmlTodo		 contained TODO
+syn keyword wsmlFixMe		 contained FIXME
+if exists("wsml_comment_strings")
+  syn region  wsmlCommentString    contained start=+"+ end=+"+ end=+$+ end=+\*/+me=s-1,he=s-1 contains=wsmlSpecial,wsmlCommentStar,wsmlSpecialChar,@Spell
+  syn region  wsmlComment2String   contained start=+"+  end=+$\|"+  contains=wsmlSpecial,wsmlSpecialChar,@Spell
+  syn match   wsmlCommentCharacter contained "'\\[^']\{1,6\}'" contains=wsmlSpecialChar
+  syn match   wsmlCommentCharacter contained "'\\''" contains=wsmlSpecialChar
+  syn match   wsmlCommentCharacter contained "'[^\\]'"
+  syn cluster wsmlCommentSpecial add=wsmlCommentString,wsmlCommentCharacter,wsmlNumber
+  syn cluster wsmlCommentSpecial2 add=wsmlComment2String,wsmlCommentCharacter,wsmlNumber
+endif
+
+syn region  wsmlComment		 start="/\*"  end="\*/" contains=@wsmlCommentSpecial,wsmlTodo,wsmlFixMe,@Spell
+syn match   wsmlCommentStar      contained "^\s*\*[^/]"me=e-1
+syn match   wsmlCommentStar      contained "^\s*\*$"
+syn match   wsmlLineComment      "//.*" contains=@wsmlCommentSpecial2,wsmlTodo,@Spell
+
+syn cluster wsmlTop add=wsmlComment,wsmlLineComment
+
+"match the special comment /**/
+syn match   wsmlComment		 "/\*\*/"
+
+" Strings
+syn region  wsmlString		start=+"+ end=+"+ contains=wsmlSpecialChar,wsmlSpecialError,@Spell
+syn match   wsmlCharacter	 "'[^']*'" contains=javaSpecialChar,javaSpecialCharError
+syn match   wsmlCharacter	 "'\\''" contains=javaSpecialChar
+syn match   wsmlCharacter	 "'[^\\]'"
+syn match   wsmlNumber		 "\<\(0[0-7]*\|0[xX]\x\+\|\d\+\)[lL]\=\>"
+syn match   wsmlNumber		 "\(\<\d\+\.\d*\|\.\d\+\)\([eE][-+]\=\d\+\)\=[fFdD]\="
+syn match   wsmlNumber		 "\<\d\+[eE][-+]\=\d\+[fFdD]\=\>"
+syn match   wsmlNumber		 "\<\d\+\([eE][-+]\=\d\+\)\=[fFdD]\>"
+
+" unicode characters
+syn match   wsmlSpecial "\\u\d\{4\}"
+
+syn cluster wsmlTop add=wsmlString,wsmlCharacter,wsmlNumber,wsmlSpecial,wsmlStringError
+
+" Define the default highlighting.
+" " For version 5.7 and earlier: only when not done already
+" " For version 5.8 and later: only when an item doesn't have highlighting yet
+ if version >= 508 || !exists("did_wsml_syn_inits")
+   if version < 508
+       let did_wsml_syn_inits = 1
+       command -nargs=+ HiLink hi link <args>
+   else
+       command -nargs=+ HiLink hi def link <args>
+   endif              
+   HiLink wsmlHeader			TypeDef
+   HiLink wsmlNamespace			TypeDef
+   HiLink wsmlOntology			Statement
+   HiLink wsmlAxiom			TypeDef
+   HiLink wsmlService			TypeDef
+   HiLink wsmlNFP			TypeDef
+   HiLink wsmlTopLevel			TypeDef
+   HiLink wsmlMediation			TypeDef 
+   HiLink wsmlBehavioral		TypeDef
+   HiLink wsmlChoreographyPri		TypeDef
+   HiLink wsmlChoreographySec		Operator
+   HiLink wsmlChoreographyTer		Special
+   HiLink wsmlString			String
+   HiLink wsmlIdentifier		Normal 
+   HiLink wsmlSqName                     Normal
+   HiLink wsmlVariable			Define
+   HiLink wsmlKeywordsInsideLEs		Operator
+   HiLink wsmlOperator			Operator
+   HiLink wsmlBrace			Operator
+   HiLink wsmlCharacter			Character
+   HiLink wsmlNumber			Number
+   HiLink wsmlDataTypes			Special
+   HiLink wsmlComment			Comment
+   HiLink wsmlDocComment		Comment
+   HiLink wsmlLineComment		Comment
+   HiLink wsmlTodo			Todo
+   HiLink wsmlFixMe			Error
+   HiLink wsmlCommentTitle		SpecialComment
+   HiLink wsmlCommentStar		wsmlComment
+ endif
+
+delcommand HiLink
+
+let b:current_syntax = "wsml"
+let b:spell_options="contained"
+
--- /dev/null
+++ b/lib/vimfiles/syntax/wvdial.vim
@@ -1,0 +1,28 @@
+" Vim syntax file
+" Language:     Configuration file for WvDial
+" Maintainer:   Prahlad Vaidyanathan <slime@vsnl.net>
+" Last Update:  Mon, 15 Oct 2001 09:39:03 Indian Standard Time
+
+" Quit if syntax file is already loaded
+if exists("b:current_syntax")
+	finish
+endif
+
+syn match   wvdialComment   "^;.*$"lc=1
+syn match   wvdialComment   "[^\\];.*$"lc=1
+syn match   wvdialSection   "^\s*\[.*\]"
+syn match   wvdialValue     "=.*$"ms=s+1
+syn match   wvdialValue     "\s*[^ ;"' ]\+"lc=1
+syn match   wvdialVar       "^\s*\(Inherits\|Modem\|Baud\|Init.\|Phone\|Area\ Code\|Dial\ Prefix\|Dial\ Command\|Login\|Login\| Prompt\|Password\|Password\ Prompt\|PPPD\ Path\|Force\ Address\|Remote\ Name\|Carrier\ Check\|Stupid\ [Mm]ode\|New\ PPPD\|Default\ Reply\|Auto\ Reconnect\|SetVolume\|Username\)"
+syn match   wvdialEqual     "="
+
+" The default highlighting
+hi def link wvdialComment   Comment
+hi def link wvdialSection   PreProc
+hi def link wvdialVar       Identifier
+hi def link wvdialValue     String
+hi def link wvdialEqual     Statement
+
+let b:current_syntax = "wvdial"
+
+"EOF vim: tw=78:ft=vim:ts=8
--- /dev/null
+++ b/lib/vimfiles/syntax/xdefaults.vim
@@ -1,0 +1,145 @@
+" Vim syntax file
+" Language:	X resources files like ~/.Xdefaults (xrdb)
+" Maintainer:	Johannes Zellner <johannes@zellner.org>
+"		Author and previous maintainer:
+"		Gautam H. Mudunuri <gmudunur@informatica.com>
+" Last Change:	Di, 09 Mai 2006 23:10:23 CEST
+" $Id: xdefaults.vim,v 1.2 2007/05/05 17:19:40 vimboss Exp $
+"
+" REFERENCES:
+"   xrdb manual page
+"   xrdb source: ftp://ftp.x.org/pub/R6.4/xc/programs/xrdb/xrdb.c
+
+" For version 5.x: Clear all syntax items
+" For version 6.x: Quit when a syntax file was already loaded
+if version < 600
+  syntax clear
+elseif exists("b:current_syntax")
+  finish
+endif
+
+" turn case on
+syn case match
+
+
+if !exists("xdefaults_no_colon_errors")
+    " mark lines which do not contain a colon as errors.
+    " This does not really catch all errors but only lines
+    " which contain at least two WORDS and no colon. This
+    " was done this way so that a line is not marked as
+    " error while typing (which would be annoying).
+    syntax match xdefaultsErrorLine "^\s*[a-zA-Z.*]\+\s\+[^: 	]\+"
+endif
+
+
+" syn region  xdefaultsLabel   start=+^[^:]\{-}:+he=e-1 skip=+\\+ end="$"
+syn match   xdefaultsLabel   +[^:]\{-}:+he=e-1                       contains=xdefaultsPunct,xdefaultsSpecial,xdefaultsLineEnd
+syn region  xdefaultsValue   keepend start=+:+lc=1 skip=+\\+ end=+$+ contains=xdefaultsSpecial,xdefaultsLabel,xdefaultsLineEnd
+
+syn match   xdefaultsSpecial	contained +#override+
+syn match   xdefaultsSpecial	contained +#augment+
+syn match   xdefaultsPunct	contained +[.*:]+
+syn match   xdefaultsLineEnd	contained +\\$+
+syn match   xdefaultsLineEnd	contained +\\n\\$+
+syn match   xdefaultsLineEnd	contained +\\n$+
+
+
+
+" COMMENTS
+
+" note, that the '!' must be at the very first position of the line
+syn match   xdefaultsComment "^!.*$"                     contains=xdefaultsTodo,@Spell
+
+" lines starting with a '#' mark and which are not preprocessor
+" lines are skipped.  This is not part of the xrdb documentation.
+" It was reported by Bram Moolenaar and could be confirmed by
+" having a look at xrdb.c:GetEntries()
+syn match   xdefaultsCommentH		"^#.*$"
+"syn region  xdefaultsComment start="^#"  end="$" keepend contains=ALL
+syn region  xdefaultsComment start="/\*" end="\*/"       contains=xdefaultsTodo,@Spell
+
+syntax match xdefaultsCommentError	"\*/"
+
+syn keyword xdefaultsTodo contained TODO FIXME XXX display
+
+
+
+" PREPROCESSOR STUFF
+
+syn region	xdefaultsPreProc	start="^\s*#\s*\(if\|ifdef\|ifndef\|elif\|else\|endif\)\>" skip="\\$" end="$" contains=xdefaultsSymbol
+if !exists("xdefaults_no_if0")
+  syn region	xdefaultsCppOut		start="^\s*#\s*if\s\+0\>" end=".\|$" contains=xdefaultsCppOut2
+  syn region	xdefaultsCppOut2	contained start="0" end="^\s*#\s*\(endif\>\|else\>\|elif\>\)" contains=xdefaultsCppSkip
+  syn region	xdefaultsCppSkip	contained start="^\s*#\s*\(if\>\|ifdef\>\|ifndef\>\)" skip="\\$" end="^\s*#\s*endif\>" contains=xdefaultsCppSkip
+endif
+syn region	xdefaultsIncluded	contained start=+"+ skip=+\\\\\|\\"+ end=+"+
+syn match	xdefaultsIncluded	contained "<[^>]*>"
+syn match	xdefaultsInclude	"^\s*#\s*include\>\s*["<]" contains=xdefaultsIncluded
+syn cluster	xdefaultsPreProcGroup	contains=xdefaultsPreProc,xdefaultsIncluded,xdefaultsInclude,xdefaultsDefine
+syn region	xdefaultsDefine		start="^\s*#\s*\(define\|undef\)\>" skip="\\$" end="$" contains=ALLBUT,@xdefaultsPreProcGroup,xdefaultsCommentH,xdefaultsErrorLine
+syn region	xdefaultsPreProc	start="^\s*#\s*\(pragma\>\|line\>\|warning\>\|warn\>\|error\>\)" skip="\\$" end="$" keepend contains=ALLBUT,@xdefaultsPreProcGroup,xdefaultsCommentH,xdefaultsErrorLine
+
+
+
+" symbols as defined by xrdb
+syn keyword xdefaultsSymbol contained SERVERHOST
+syn match   xdefaultsSymbol contained "SRVR_[a-zA-Z0-9_]\+"
+syn keyword xdefaultsSymbol contained HOST
+syn keyword xdefaultsSymbol contained DISPLAY_NUM
+syn keyword xdefaultsSymbol contained CLIENTHOST
+syn match   xdefaultsSymbol contained "CLNT_[a-zA-Z0-9_]\+"
+syn keyword xdefaultsSymbol contained RELEASE
+syn keyword xdefaultsSymbol contained REVISION
+syn keyword xdefaultsSymbol contained VERSION
+syn keyword xdefaultsSymbol contained VENDOR
+syn match   xdefaultsSymbol contained "VNDR_[a-zA-Z0-9_]\+"
+syn match   xdefaultsSymbol contained "EXT_[a-zA-Z0-9_]\+"
+syn keyword xdefaultsSymbol contained NUM_SCREENS
+syn keyword xdefaultsSymbol contained SCREEN_NUM
+syn keyword xdefaultsSymbol contained BITS_PER_RGB
+syn keyword xdefaultsSymbol contained CLASS
+syn keyword xdefaultsSymbol contained StaticGray GrayScale StaticColor PseudoColor TrueColor DirectColor
+syn match   xdefaultsSymbol contained "CLASS_\(StaticGray\|GrayScale\|StaticColor\|PseudoColor\|TrueColor\|DirectColor\)"
+syn keyword xdefaultsSymbol contained COLOR
+syn match   xdefaultsSymbol contained "CLASS_\(StaticGray\|GrayScale\|StaticColor\|PseudoColor\|TrueColor\|DirectColor\)_[0-9]\+"
+syn keyword xdefaultsSymbol contained HEIGHT
+syn keyword xdefaultsSymbol contained WIDTH
+syn keyword xdefaultsSymbol contained PLANES
+syn keyword xdefaultsSymbol contained X_RESOLUTION
+syn keyword xdefaultsSymbol contained Y_RESOLUTION
+
+" Define the default highlighting.
+" For version 5.7 and earlier: only when not done already
+" For version 5.8 and later: only when an item doesn't have highlighting yet
+if version >= 508 || !exists("did_xdefaults_syntax_inits")
+  if version < 508
+    let did_xdefaults_syntax_inits = 1
+    command -nargs=+ HiLink hi link <args>
+  else
+    command -nargs=+ HiLink hi def link <args>
+  endif
+  HiLink xdefaultsLabel		Type
+  HiLink xdefaultsValue		Constant
+  HiLink xdefaultsComment	Comment
+  HiLink xdefaultsCommentH	xdefaultsComment
+  HiLink xdefaultsPreProc	PreProc
+  HiLink xdefaultsInclude	xdefaultsPreProc
+  HiLink xdefaultsCppSkip	xdefaultsCppOut
+  HiLink xdefaultsCppOut2	xdefaultsCppOut
+  HiLink xdefaultsCppOut	Comment
+  HiLink xdefaultsIncluded	String
+  HiLink xdefaultsDefine	Macro
+  HiLink xdefaultsSymbol	Statement
+  HiLink xdefaultsSpecial	Statement
+  HiLink xdefaultsErrorLine	Error
+  HiLink xdefaultsCommentError	Error
+  HiLink xdefaultsPunct		Normal
+  HiLink xdefaultsLineEnd	Special
+  HiLink xdefaultsTodo		Todo
+
+  delcommand HiLink
+endif
+
+let b:current_syntax = "xdefaults"
+
+" vim:ts=8
--- /dev/null
+++ b/lib/vimfiles/syntax/xf86conf.vim
@@ -1,0 +1,209 @@
+" Vim syntax file
+" This is a GENERATED FILE. Please always refer to source file at the URI below.
+" Language: XF86Config (XFree86 configuration file)
+" Maintainer: David Ne\v{c}as (Yeti) <yeti@physics.muni.cz>
+" Last Change: 2005 Jul 12
+" URL: http://trific.ath.cx/Ftp/vim/syntax/xf86conf.vim
+" Required Vim Version: 6.0
+"
+" Options: let xf86conf_xfree86_version = 3 or 4
+"							 to force XFree86 3.x or 4.x XF86Config syntax
+
+" Setup
+if version >= 600
+	if exists("b:current_syntax")
+		finish
+	endif
+else
+	echo "Sorry, but this syntax file relies on Vim 6 features.	 Either upgrade Vim or usea version of " . expand("<sfile>:t:r") . " syntax file appropriate for Vim " . version/100 . "." . version %100 . "."
+	finish
+endif
+
+if !exists("b:xf86conf_xfree86_version")
+	if exists("xf86conf_xfree86_version")
+		let b:xf86conf_xfree86_version = xf86conf_xfree86_version
+	else
+		let b:xf86conf_xfree86_version = 4
+	endif
+endif
+
+syn case ignore
+
+" Comments
+syn match xf86confComment "#.*$" contains=xf86confTodo
+syn case match
+syn keyword xf86confTodo FIXME TODO XXX NOT contained
+syn case ignore
+syn match xf86confTodo "???" contained
+
+" Sectioning errors
+syn keyword xf86confSectionError Section contained
+syn keyword xf86confSectionError EndSection
+syn keyword xf86confSubSectionError SubSection
+syn keyword xf86confSubSectionError EndSubSection
+syn keyword xf86confModeSubSectionError Mode
+syn keyword xf86confModeSubSectionError EndMode
+syn cluster xf86confSectionErrors contains=xf86confSectionError,xf86confSubSectionError,xf86confModeSubSectionError
+
+" Values
+if b:xf86conf_xfree86_version >= 4
+	syn region xf86confString start=+"+ skip=+\\\\\|\\"+ end=+"+ contained contains=xf86confSpecialChar,xf86confConstant,xf86confOptionName oneline keepend nextgroup=xf86confValue skipwhite
+else
+	syn region xf86confString start=+"+ skip=+\\\\\|\\"+ end=+"+ contained contains=xf86confSpecialChar,xf86confOptionName oneline keepend
+endif
+syn match xf86confSpecialChar "\\\d\d\d\|\\." contained
+syn match xf86confDecimalNumber "\(\s\|-\)\zs\d*\.\=\d\+\>"
+syn match xf86confFrequency "\(\s\|-\)\zs\d\+\.\=\d*\(Hz\|k\|kHz\|M\|MHz\)"
+syn match xf86confOctalNumber "\<0\o\+\>"
+syn match xf86confOctalNumberError "\<0\o\+[89]\d*\>"
+syn match xf86confHexadecimalNumber "\<0x\x\+\>"
+syn match xf86confValue "\s\+.*$" contained contains=xf86confComment,xf86confString,xf86confFrequency,xf86conf\w\+Number,xf86confConstant
+syn keyword xf86confOption Option nextgroup=xf86confString skipwhite
+syn match xf86confModeLineValue "\"[^\"]\+\"\(\_s\+[0-9.]\+\)\{9}" nextgroup=xf86confSync skipwhite skipnl
+
+" Sections and subsections
+if b:xf86conf_xfree86_version >= 4
+	syn region xf86confSection matchgroup=xf86confSectionDelim start="^\s*Section\s\+\"\(Files\|Server[_ ]*Flags\|Input[_ ]*Device\|Device\|Video[_ ]*Adaptor\|Server[_ ]*Layout\|DRI\|Extensions\|Vendor\|Keyboard\|Pointer\)\"" end="^\s*EndSection\>" skip="#.*$\|\"[^\"]*\"" contains=xf86confComment,xf86confOption,xf86confKeyword,xf86confSectionError
+	syn region xf86confSectionModule matchgroup=xf86confSectionDelim start="^\s*Section\s\+\"Module\"" end="^\s*EndSection\>" skip="#.*$\|\"[^\"]*\"" contains=xf86confSubsectionAny,xf86confComment,xf86confOption,xf86confKeyword
+	syn region xf86confSectionMonitor matchgroup=xf86confSectionDelim start="^\s*Section\s\+\"Monitor\"" end="^\s*EndSection\>" skip="#.*$\|\"[^\"]*\"" contains=xf86confSubsectionMode,xf86confModeLine,xf86confComment,xf86confOption,xf86confKeyword
+	syn region xf86confSectionModes matchgroup=xf86confSectionDelim start="^\s*Section\s\+\"Modes\"" end="^\s*EndSection\>" skip="#.*$\|\"[^\"]*\"" contains=xf86confSubsectionMode,xf86confModeLine,xf86confComment
+	syn region xf86confSectionScreen matchgroup=xf86confSectionDelim start="^\s*Section\s\+\"Screen\"" end="^\s*EndSection\>" skip="#.*$\|\"[^\"]*\"" contains=xf86confSubsectionDisplay,xf86confComment,xf86confOption,xf86confKeyword
+	syn region xf86confSubSectionAny matchgroup=xf86confSectionDelim start="^\s*SubSection\s\+\"[^\"]\+\"" end="^\s*EndSubSection\>" skip="#.*$\|\"[^\"]*\"" contains=xf86confComment,xf86confOption,xf86confKeyword,@xf86confSectionErrors
+	syn region xf86confSubSectionMode matchgroup=xf86confSectionDelim start="^\s*Mode\s\+\"[^\"]\+\"" end="^\s*EndMode\>" skip="#.*$\|\"[^\"]*\"" contains=xf86confComment,xf86confKeyword,@xf86confSectionErrors
+	syn region xf86confSubSectionDisplay matchgroup=xf86confSectionDelim start="^\s*SubSection\s\+\"Display\"" end="^\s*EndSubSection\>" skip="#.*$\|\"[^\"]*\"" contains=xf86confComment,xf86confOption,xf86confKeyword,@xf86confSectionErrors
+else
+	syn region xf86confSection matchgroup=xf86confSectionDelim start="^\s*Section\s\+\"\(Files\|Server[_ ]*Flags\|Device\|Keyboard\|Pointer\)\"" end="^\s*EndSection\>" skip="#.*$\|\"[^\"]*\"" contains=xf86confComment,xf86confOptionName,xf86confOption,xf86confKeyword
+	syn region xf86confSectionMX matchgroup=xf86confSectionDelim start="^\s*Section\s\+\"\(Module\|Xinput\)\"" end="^\s*EndSection\>" skip="#.*$\|\"[^\"]*\"" contains=xf86confSubsectionAny,xf86confComment,xf86confOptionName,xf86confOption,xf86confKeyword
+	syn region xf86confSectionMonitor matchgroup=xf86confSectionDelim start="^\s*Section\s\+\"Monitor\"" end="^\s*EndSection\>" skip="#.*$\|\"[^\"]*\"" contains=xf86confSubsectionMode,xf86confModeLine,xf86confComment,xf86confOptionName,xf86confOption,xf86confKeyword
+	syn region xf86confSectionScreen matchgroup=xf86confSectionDelim start="^\s*Section\s\+\"Screen\"" end="^\s*EndSection\>" skip="#.*$\|\"[^\"]*\"" contains=xf86confSubsectionDisplay,xf86confComment,xf86confOptionName,xf86confOption,xf86confKeyword
+	syn region xf86confSubSectionAny matchgroup=xf86confSectionDelim start="^\s*SubSection\s\+\"[^\"]\+\"" end="^\s*EndSubSection\>" skip="#.*$\|\"[^\"]*\"" contains=xf86confComment,xf86confOptionName,xf86confOption,xf86confKeyword,@xf86confSectionErrors
+	syn region xf86confSubSectionMode matchgroup=xf86confSectionDelim start="^\s*Mode\s\+\"[^\"]\+\"" end="^\s*EndMode\>" skip="#.*$\|\"[^\"]*\"" contains=xf86confComment,xf86confOptionName,xf86confOption,xf86confKeyword,@xf86confSectionErrors
+	syn region xf86confSubSectionDisplay matchgroup=xf86confSectionDelim start="^\s*SubSection\s\+\"Display\"" end="^\s*EndSubSection\>" skip="#.*$\|\"[^\"]*\"" contains=xf86confComment,xf86confOptionName,xf86confOption,xf86confKeyword,@xf86confSectionErrors
+endif
+
+" Options
+if b:xf86conf_xfree86_version >= 4
+	command -nargs=+ Xf86confdeclopt syn keyword xf86confOptionName <args> contained
+else
+	command -nargs=+ Xf86confdeclopt syn keyword xf86confOptionName <args> contained nextgroup=xf86confValue,xf86confComment skipwhite
+endif
+
+Xf86confdeclopt 18bitBus AGPFastWrite AGPMode Accel AllowClosedownGrabs AllowDeactivateGrabs
+Xf86confdeclopt AllowMouseOpenFail AllowNonLocalModInDev AllowNonLocalXvidtune AlwaysCore
+Xf86confdeclopt AngleOffset AutoRepeat BaudRate BeamTimeout Beep BlankTime BlockWrite BottomX
+Xf86confdeclopt BottomY ButtonNumber ButtonThreshold Buttons ByteSwap CacheLines ChordMiddle
+Xf86confdeclopt ClearDTR ClearDTS ClickMode CloneDisplay CloneHSync CloneMode CloneVRefresh
+Xf86confdeclopt ColorKey Composite CompositeSync CoreKeyboard CorePointer Crt2Memory CrtScreen
+Xf86confdeclopt CrtcNumber CyberShadow CyberStretch DDC DDCMode DMAForXv DPMS Dac6Bit DacSpeed
+Xf86confdeclopt DataBits Debug DebugLevel DefaultServerLayout DeltaX DeltaY Device DeviceName
+Xf86confdeclopt DisableModInDev DisableVidModeExtension Display Display1400 DontVTSwitch
+Xf86confdeclopt DontZap DontZoom DoubleScan DozeMode DozeScan DozeTime DragLockButtons
+Xf86confdeclopt DualCount DualRefresh EarlyRasPrecharge Emulate3Buttons Emulate3Timeout
+Xf86confdeclopt EmulateWheel EmulateWheelButton EmulateWheelInertia EnablePageFlip EnterCount
+Xf86confdeclopt EstimateSizesAggressively ExternDisp FPClock16 FPClock24 FPClock32
+Xf86confdeclopt FPClock8 FPDither FastDram FifoAggresive FifoConservative FifoModerate
+Xf86confdeclopt FireGL3000 FixPanelSize FlatPanel FlipXY FlowControl ForceCRT1 ForceCRT2Type
+Xf86confdeclopt ForceLegacyCRT ForcePCIMode FpmVRAM FrameBufferWC FullMMIO GammaBrightness
+Xf86confdeclopt HWClocks HWCursor HandleSpecialKeys HistorySize Interlace Interlaced InternDisp
+Xf86confdeclopt InvX InvY InvertX InvertY KeepShape LCDClock LateRasPrecharge LcdCenter
+Xf86confdeclopt LeftAlt Linear MGASDRAM MMIO MMIOCache MTTR MaxX MaxY MaximumXPosition
+Xf86confdeclopt MaximumYPosition MinX MinY MinimumXPosition MinimumYPosition NoAccel
+Xf86confdeclopt NoAllowMouseOpenFail NoAllowNonLocalModInDev NoAllowNonLocalXvidtune
+Xf86confdeclopt NoBlockWrite NoCompositeSync NoCompression NoCrtScreen NoCyberShadow NoDCC
+Xf86confdeclopt NoDDC NoDac6Bit NoDebug NoDisableModInDev NoDisableVidModeExtension NoDontZap
+Xf86confdeclopt NoDontZoom NoFireGL3000 NoFixPanelSize NoFpmVRAM NoFrameBufferWC NoHWClocks
+Xf86confdeclopt NoHWCursor NoHal NoLcdCenter NoLinear NoMGASDRAM NoMMIO NoMMIOCache NoMTTR
+Xf86confdeclopt NoOverClockMem NoOverlay NoPC98 NoPM NoPciBurst NoPciRetry NoProbeClock
+Xf86confdeclopt NoSTN NoSWCursor NoShadowFb NoShowCache NoSlowEDODRAM NoStretch NoSuspendHack
+Xf86confdeclopt NoTexturedVideo NoTrapSignals NoUseFBDev NoUseModeline NoUseVclk1 NoVTSysReq
+Xf86confdeclopt NoXVideo NvAGP OSMImageBuffers OffTime Origin OverClockMem Overlay
+Xf86confdeclopt PC98 PCIBurst PM PWMActive PWMSleep PanelDelayCompensation PanelHeight
+Xf86confdeclopt PanelOff PanelWidth Parity PciBurst PciRetry Pixmap Port PressDur PressPitch
+Xf86confdeclopt PressVol ProbeClocks ProgramFPRegs Protocol RGBBits ReleaseDur ReleasePitch
+Xf86confdeclopt ReportingMode Resolution RightAlt RightCtl Rotate STN SWCursor SampleRate
+Xf86confdeclopt ScreenNumber ScrollLock SendCoreEvents SendDragEvents Serial ServerNumLock
+Xf86confdeclopt SetLcdClk SetMClk SetRefClk ShadowFb ShadowStatus ShowCache SleepMode
+Xf86confdeclopt SleepScan SleepTime SlowDram SlowEDODRAM StandbyTime StopBits Stretch
+Xf86confdeclopt SuspendHack SuspendTime SwapXY SyncOnGreen TV TVOutput TVOverscan TVStandard
+Xf86confdeclopt TVXPosOffset TVYPosOffset TexturedVideo Threshold Tilt TopX TopY TouchTime
+Xf86confdeclopt TrapSignals Type USB UseBIOS UseFB UseFBDev UseFlatPanel UseModeline
+Xf86confdeclopt UseROMData UseVclk1 VTInit VTSysReq VTime VideoKey Vmin XAxisMapping
+Xf86confdeclopt XLeds XVideo XaaNoCPUToScreenColorExpandFill XaaNoColor8x8PatternFillRect
+Xf86confdeclopt XaaNoColor8x8PatternFillTrap XaaNoDashedBresenhamLine XaaNoDashedTwoPointLine
+Xf86confdeclopt XaaNoImageWriteRect XaaNoMono8x8PatternFillRect XaaNoMono8x8PatternFillTrap
+Xf86confdeclopt XaaNoOffscreenPixmaps XaaNoPixmapCache XaaNoScanlineCPUToScreenColorExpandFill
+Xf86confdeclopt XaaNoScanlineImageWriteRect XaaNoScreenToScreenColorExpandFill
+Xf86confdeclopt XaaNoScreenToScreenCopy XaaNoSolidBresenhamLine XaaNoSolidFillRect
+Xf86confdeclopt XaaNoSolidFillTrap XaaNoSolidHorVertLine XaaNoSolidTwoPointLine Xinerama
+Xf86confdeclopt XkbCompat XkbDisable XkbGeometry XkbKeycodes XkbKeymap XkbLayout XkbModel
+Xf86confdeclopt XkbOptions XkbRules XkbSymbols XkbTypes XkbVariant XvBskew XvHsync XvOnCRT2
+Xf86confdeclopt XvRskew XvVsync YAxisMapping ZAxisMapping ZoomOnLCD
+
+delcommand Xf86confdeclopt
+
+" Keywords
+syn keyword xf86confKeyword Device Driver FontPath Group Identifier Load ModelName ModulePath Monitor RGBPath VendorName VideoAdaptor Visual nextgroup=xf86confComment,xf86confString skipwhite
+syn keyword xf86confKeyword BiosBase Black BoardName BusID ChipID ChipRev Chipset nextgroup=xf86confComment,xf86confValue
+syn keyword xf86confKeyword ClockChip Clocks DacSpeed DefaultDepth DefaultFbBpp nextgroup=xf86confComment,xf86confValue
+syn keyword xf86confKeyword DefaultColorDepth nextgroup=xf86confComment,xf86confValue
+syn keyword xf86confKeyword Depth DisplaySize DotClock FbBpp Flags Gamma HorizSync nextgroup=xf86confComment,xf86confValue
+syn keyword xf86confKeyword Hskew HTimings InputDevice IOBase MemBase Mode nextgroup=xf86confComment,xf86confValue
+syn keyword xf86confKeyword Modes Ramdac Screen TextClockFreq UseModes VendorName nextgroup=xf86confComment,xf86confValue
+syn keyword xf86confKeyword VertRefresh VideoRam ViewPort Virtual VScan VTimings nextgroup=xf86confComment,xf86confValue
+syn keyword xf86confKeyword Weight White nextgroup=xf86confComment,xf86confValue
+syn keyword xf86confModeLine ModeLine nextgroup=xf86confComment,xf86confModeLineValue skipwhite skipnl
+
+" Constants
+if b:xf86conf_xfree86_version >= 4
+	syn keyword xf86confConstant true false on off yes no omit contained
+else
+	syn keyword xf86confConstant Meta Compose Control
+endif
+syn keyword xf86confConstant StaticGray GrayScale StaticColor PseudoColor TrueColor DirectColor contained
+syn keyword xf86confConstant Absolute RightOf LeftOf Above Below Relative StaticGray GrayScale StaticColor PseudoColor TrueColor DirectColor contained
+syn match xf86confSync "\(\s\+[+-][CHV]_*Sync\)\+" contained
+
+" Synchronization
+if b:xf86conf_xfree86_version >= 4
+	syn sync match xf86confSyncSection grouphere xf86confSection "^\s*Section\s\+\"\(Files\|Server[_ ]*Flags\|Input[_ ]*Device\|Device\|Video[_ ]*Adaptor\|Server[_ ]*Layout\|DRI\|Extensions\|Vendor\|Keyboard\|Pointer\)\""
+	syn sync match xf86confSyncSectionModule grouphere xf86confSectionModule "^\s*Section\s\+\"Module\""
+	syn sync match xf86confSyncSectionModes groupthere xf86confSectionModes "^\s*Section\s\+\"Modes\""
+else
+	syn sync match xf86confSyncSection grouphere xf86confSection "^\s*Section\s\+\"\(Files\|Server[_ ]*Flags\|Device\|Keyboard\|Pointer\)\""
+	syn sync match xf86confSyncSectionMX grouphere xf86confSectionMX "^\s*Section\s\+\"\(Module\|Xinput\)\""
+endif
+syn sync match xf86confSyncSectionMonitor groupthere xf86confSectionMonitor "^\s*Section\s\+\"Monitor\""
+syn sync match xf86confSyncSectionScreen groupthere xf86confSectionScreen "^\s*Section\s\+\"Screen\""
+syn sync match xf86confSyncEndSection groupthere NONE "^\s*End_*Section\s*$"
+
+" Define the default highlighting
+hi def link xf86confComment Comment
+hi def link xf86confTodo Todo
+hi def link xf86confSectionDelim Statement
+hi def link xf86confOptionName Identifier
+
+hi def link xf86confSectionError xf86confError
+hi def link xf86confSubSectionError xf86confError
+hi def link xf86confModeSubSectionError xf86confError
+hi def link xf86confOctalNumberError xf86confError
+hi def link xf86confError Error
+
+hi def link xf86confOption xf86confKeyword
+hi def link xf86confModeLine xf86confKeyword
+hi def link xf86confKeyword Type
+
+hi def link xf86confDecimalNumber xf86confNumber
+hi def link xf86confOctalNumber xf86confNumber
+hi def link xf86confHexadecimalNumber xf86confNumber
+hi def link xf86confFrequency xf86confNumber
+hi def link xf86confModeLineValue Constant
+hi def link xf86confNumber Constant
+
+hi def link xf86confSync xf86confConstant
+hi def link xf86confConstant Special
+hi def link xf86confSpecialChar Special
+hi def link xf86confString String
+
+hi def link xf86confValue Constant
+
+let b:current_syntax = "xf86conf"
--- /dev/null
+++ b/lib/vimfiles/syntax/xhtml.vim
@@ -1,0 +1,11 @@
+" Vim syntax file
+" Language:	XHTML
+" Maintainer:	noone
+" Last Change:	2003 Feb 04
+
+" Load the HTML syntax for now.
+runtime! syntax/html.vim
+
+let b:current_syntax = "xhtml"
+
+" vim: ts=8
--- /dev/null
+++ b/lib/vimfiles/syntax/xinetd.vim
@@ -1,0 +1,347 @@
+" Vim syntax file
+" Language:         xinetd.conf(5) configuration file
+" Maintainer:       Nikolai Weibull <now@bitwi.se>
+" Latest Revision:  2006-04-19
+
+if exists("b:current_syntax")
+  finish
+endif
+
+let s:cpo_save = &cpo
+set cpo&vim
+
+syn keyword xinetdTodo          contained TODO FIXME XXX NOTE
+
+syn region  xinetdComment       display oneline start='^\s*#' end='$'
+                                \ contains=xinetdTodo,@Spell
+
+syn match   xinetdService       '^\s*service\>'
+                                \ nextgroup=xinetdServiceName skipwhite
+
+syn match   xinetdServiceName   contained '\S\+'
+                                \ nextgroup=xinetdServiceGroup skipwhite skipnl
+
+syn match   xinetdDefaults      '^\s*defaults'
+                                \ nextgroup=xinetdServiceGroup skipwhite skipnl
+
+syn region  xinetdServiceGroup  contained transparent
+                                \ matchgroup=xinetdServiceGroupD start='{'
+                                \ matchgroup=xinetdServiceGroupD end='}'
+                                \ contains=xinetdAttribute,xinetdReqAttribute,
+                                \ xinetdDisable
+
+syn keyword xinetdReqAttribute  contained user server protocol
+                                \ nextgroup=xinetdStringEq skipwhite
+
+syn keyword xinetdAttribute     contained id group bind
+                                \ interface
+                                \ nextgroup=xinetdStringEq skipwhite
+
+syn match   xinetdStringEq      contained display '='
+                                \ nextgroup=xinetdString skipwhite
+
+syn match   xinetdString        contained display '\S\+'
+
+syn keyword xinetdAttribute     contained type nextgroup=xinetdTypeEq skipwhite
+
+syn match   xinetdTypeEq        contained display '='
+                                \ nextgroup=xinetdType skipwhite
+
+syn keyword xinetdType          contained RPC INTERNAL TCPMUX TCPMUXPLUS
+                                \ UNLISTED
+                                \ nextgroup=xinetdType skipwhite
+
+syn keyword xinetdAttribute     contained flags
+                                \ nextgroup=xinetdFlagsEq skipwhite
+
+syn cluster xinetdFlagsC        contains=xinetdFlags,xinetdDeprFlags
+
+syn match   xinetdFlagsEq       contained display '='
+                                \ nextgroup=@xinetdFlagsC skipwhite
+
+syn keyword xinetdFlags         contained INTERCEPT NORETRY IDONLY NAMEINARGS
+                                \ NODELAY KEEPALIVE NOLIBWRAP SENSOR IPv4 IPv6
+                                \ nextgroup=@xinetdFlagsC skipwhite
+
+syn keyword xinetdDeprFlags     contained REUSE nextgroup=xinetdFlagsC skipwhite
+
+syn keyword xinetdDisable       contained disable
+                                \ nextgroup=xinetdBooleanEq skipwhite
+
+syn match   xinetdBooleanEq     contained display '='
+                                \ nextgroup=xinetdBoolean skipwhite
+
+syn keyword xinetdBoolean       contained yes no
+
+syn keyword xinetdReqAttribute  contained socket_type
+                                \ nextgroup=xinetdSocketTypeEq skipwhite
+
+syn match   xinetdSocketTypeEq  contained display '='
+                                \ nextgroup=xinetdSocketType skipwhite
+
+syn keyword xinetdSocketType    contained stream dgram raw seqpacket
+
+syn keyword xinetdReqAttribute  contained wait
+                                \ nextgroup=xinetdBooleanEq skipwhite
+
+syn keyword xinetdAttribute     contained groups mdns
+                                \ nextgroup=xinetdBooleanEq skipwhite
+
+syn keyword xinetdAttribute     contained instances per_source rlimit_cpu
+                                \ rlimit_data rlimit_rss rlimit_stack
+                                \ nextgroup=xinetdUNumberEq skipwhite
+
+syn match   xinetdUNumberEq     contained display '='
+                                \ nextgroup=xinetdUnlimited,xinetdNumber
+                                \ skipwhite
+
+syn keyword xinetdUnlimited     contained UNLIMITED
+
+syn match   xinetdNumber        contained display '\<\d\+\>'
+
+syn keyword xinetdAttribute     contained nice
+                                \ nextgroup=xinetdSignedNumEq skipwhite
+
+syn match   xinetdSignedNumEq   contained display '='
+                                \ nextgroup=xinetdSignedNumber skipwhite
+
+syn match   xinetdSignedNumber  contained display '[+-]\=\d\+\>'
+
+syn keyword xinetdAttribute     contained server_args
+                                \ enabled
+                                \ nextgroup=xinetdStringsEq skipwhite
+
+syn match   xinetdStringsEq     contained display '='
+                                \ nextgroup=xinetdStrings skipwhite
+
+syn match   xinetdStrings       contained display '\S\+'
+                                \ nextgroup=xinetdStrings skipwhite
+
+syn keyword xinetdAttribute     contained only_from no_access passenv
+                                \ nextgroup=xinetdStringsAdvEq skipwhite
+
+syn match   xinetdStringsAdvEq  contained display '[+-]\=='
+                                \ nextgroup=xinetdStrings skipwhite
+
+syn keyword xinetdAttribute     contained access_times
+                                \ nextgroup=xinetdTimeRangesEq skipwhite
+
+syn match   xinetdTimeRangesEq  contained display '='
+                                \ nextgroup=xinetdTimeRanges skipwhite
+
+syn match   xinetdTimeRanges    contained display
+                                \ '\%(0?\d\|1\d\|2[0-3]\):\%(0?\d\|[1-5]\d\)-\%(0?\d\|1\d\|2[0-3]\):\%(0?\d\|[1-5]\d\)'
+                                \ nextgroup=xinetdTimeRanges skipwhite
+
+syn keyword xinetdAttribute     contained log_type nextgroup=xinetdLogTypeEq
+                                \ skipwhite
+
+syn match   xinetdLogTypeEq     contained display '='
+                                \ nextgroup=xinetdLogType skipwhite
+
+syn keyword xinetdLogType       contained SYSLOG nextgroup=xinetdSyslogType
+                                \ skipwhite
+
+syn keyword xinetdLogType       contained FILE nextgroup=xinetdLogFile skipwhite
+
+syn keyword xinetdSyslogType    contained daemon auth authpriv user mail lpr
+                                \ news uucp ftp local0 local1 local2 local3
+                                \ local4 local5 local6 local7
+                                \ nextgroup=xinetdSyslogLevel skipwhite
+
+syn keyword xinetdSyslogLevel   contained emerg alert crit err warning notice
+                                \ info debug
+
+syn match   xinetdLogFile       contained display '\S\+'
+                                \ nextgroup=xinetdLogSoftLimit skipwhite
+
+syn match   xinetdLogSoftLimit  contained display '\<\d\+\>'
+                                \ nextgroup=xinetdLogHardLimit skipwhite
+
+syn match   xinetdLogHardLimit  contained display '\<\d\+\>'
+
+syn keyword xinetdAttribute     contained log_on_success
+                                \ nextgroup=xinetdLogSuccessEq skipwhite
+
+syn match   xinetdLogSuccessEq  contained display '[+-]\=='
+                                \ nextgroup=xinetdLogSuccess skipwhite
+
+syn keyword xinetdLogSuccess    contained PID HOST USERID EXIT DURATION TRAFFIC
+                                \ nextgroup=xinetdLogSuccess skipwhite
+
+syn keyword xinetdAttribute     contained log_on_failure
+                                \ nextgroup=xinetdLogFailureEq skipwhite
+
+syn match   xinetdLogFailureEq  contained display '[+-]\=='
+                                \ nextgroup=xinetdLogFailure skipwhite
+
+syn keyword xinetdLogFailure    contained HOST USERID ATTEMPT
+                                \ nextgroup=xinetdLogFailure skipwhite
+
+syn keyword xinetdReqAttribute  contained rpc_version
+                                \ nextgroup=xinetdRPCVersionEq skipwhite
+
+syn match   xinetdRPCVersionEq  contained display '='
+                                \ nextgroup=xinetdRPCVersion skipwhite
+
+syn match   xinetdRPCVersion    contained display '\d\+\%(-\d\+\)\=\>'
+
+syn keyword xinetdReqAttribute  contained rpc_number port
+                                \ nextgroup=xinetdNumberEq skipwhite
+
+syn match   xinetdNumberEq      contained display '='
+                                \ nextgroup=xinetdNumber skipwhite
+
+syn keyword xinetdAttribute     contained env nextgroup=xinetdEnvEq skipwhite
+
+syn match   xinetdEnvEq         contained display '+\=='
+                                \ nextgroup=xinetdEnvName skipwhite
+
+syn match   xinetdEnvName       contained display '[^=]\+'
+                                \ nextgroup=xinetdEnvNameEq
+
+syn match   xinetdEnvNameEq     contained display '=' nextgroup=xinetdEnvValue
+
+syn match   xinetdEnvValue      contained display '\S\+'
+                                \ nextgroup=xinetdEnvName skipwhite
+
+syn keyword xinetdAttribute     contained banner banner_success banner_failure
+                                \ nextgroup=xinetdPathEq skipwhite
+
+syn keyword xinetdPPAttribute   include includedir
+                                \ nextgroup=xinetdPath skipwhite
+
+syn match   xinetdPathEq        contained display '='
+                                \ nextgroup=xinetdPath skipwhite
+
+syn match   xinetdPath          contained display '\S\+'
+
+syn keyword xinetdAttribute     contained redirect nextgroup=xinetdRedirectEq
+                                \ skipwhite
+
+syn match   xinetdRedirectEq    contained display '='
+                                \ nextgroup=xinetdRedirectIP skipwhite
+
+syn match   xinetdRedirectIP    contained display '\S\+'
+                                \ nextgroup=xinetdNumber skipwhite
+
+syn keyword xinetdAttribute     contained cps nextgroup=xinetdCPSEq skipwhite
+
+syn match   xinetdCPSEq         contained display '='
+                                \ nextgroup=xinetdCPS skipwhite
+
+syn match   xinetdCPS           contained display '\<\d\+\>'
+                                \ nextgroup=xinetdNumber skipwhite
+
+syn keyword xinetdAttribute     contained max_load nextgroup=xinetdFloatEq
+                                \ skipwhite
+
+syn match   xinetdFloatEq       contained display '='
+                                \ nextgroup=xinetdFloat skipwhite
+
+syn match   xinetdFloat         contained display '\d\+\.\d*\|\.\d\+'
+
+syn keyword xinetdAttribute     contained umask nextgroup=xinetdOctalEq
+                                \ skipwhite
+
+syn match   xinetdOctalEq       contained display '='
+                                \ nextgroup=xinetdOctal,xinetdOctalError
+                                \ skipwhite
+
+syn match   xinetdOctal         contained display '\<0\o\+\>'
+                                \ contains=xinetdOctalZero
+syn match   xinetdOctalZero     contained display '\<0'
+syn match   xinetdOctalError    contained display '\<0\o*[89]\d*\>'
+
+syn keyword xinetdAttribute     contained rlimit_as nextgroup=xinetdASEq
+                                \ skipwhite
+
+syn match   xinetdASEq          contained display '='
+                                \ nextgroup=xinetdAS,xinetdUnlimited
+                                \ skipwhite
+
+syn match   xinetdAS            contained display '\d\+' nextgroup=xinetdASMult
+
+syn match   xinetdASMult        contained display '[KM]'
+
+syn keyword xinetdAttribute     contained deny_time nextgroup=xinetdDenyTimeEq
+                                \ skipwhite
+
+syn match   xinetdDenyTimeEq    contained display '='
+                                \ nextgroup=xinetdDenyTime,xinetdNumber
+                                \ skipwhite
+
+syn keyword xinetdDenyTime      contained FOREVER NEVER
+
+hi def link xinetdTodo          Todo
+hi def link xinetdComment       Comment
+hi def link xinetdService       Keyword
+hi def link xinetdServiceName   String
+hi def link xinetdDefaults      Keyword
+hi def link xinetdServiceGroupD Delimiter
+hi def link xinetdReqAttribute  Keyword
+hi def link xinetdAttribute     Type
+hi def link xinetdEq            Operator
+hi def link xinetdStringEq      xinetdEq
+hi def link xinetdString        String
+hi def link xinetdTypeEq        xinetdEq
+hi def link xinetdType          Identifier
+hi def link xinetdFlagsEq       xinetdEq
+hi def link xinetdFlags         xinetdType
+hi def link xinetdDeprFlags     WarningMsg
+hi def link xinetdDisable       Special
+hi def link xinetdBooleanEq     xinetdEq
+hi def link xinetdBoolean       Boolean
+hi def link xinetdSocketTypeEq  xinetdEq
+hi def link xinetdSocketType    xinetdType
+hi def link xinetdUNumberEq     xinetdEq
+hi def link xinetdUnlimited     Define
+hi def link xinetdNumber        Number
+hi def link xinetdSignedNumEq   xinetdEq
+hi def link xinetdSignedNumber  xinetdNumber
+hi def link xinetdStringsEq     xinetdEq
+hi def link xinetdStrings       xinetdString
+hi def link xinetdStringsAdvEq  xinetdEq
+hi def link xinetdTimeRangesEq  xinetdEq
+hi def link xinetdTimeRanges    Number
+hi def link xinetdLogTypeEq     xinetdEq
+hi def link xinetdLogType       Keyword
+hi def link xinetdSyslogType    xinetdType
+hi def link xinetdSyslogLevel   Number
+hi def link xinetdLogFile       xinetdPath
+hi def link xinetdLogSoftLimit  xinetdNumber
+hi def link xinetdLogHardLimit  xinetdNumber
+hi def link xinetdLogSuccessEq  xinetdEq
+hi def link xinetdLogSuccess    xinetdType
+hi def link xinetdLogFailureEq  xinetdEq
+hi def link xinetdLogFailure    xinetdType
+hi def link xinetdRPCVersionEq  xinetdEq
+hi def link xinetdRPCVersion    xinetdNumber
+hi def link xinetdNumberEq      xinetdEq
+hi def link xinetdEnvEq         xinetdEq
+hi def link xinetdEnvName       Identifier
+hi def link xinetdEnvNameEq     xinetdEq
+hi def link xinetdEnvValue      String
+hi def link xinetdPPAttribute   PreProc
+hi def link xinetdPathEq        xinetdEq
+hi def link xinetdPath          String
+hi def link xinetdRedirectEq    xinetdEq
+hi def link xinetdRedirectIP    String
+hi def link xinetdCPSEq         xinetdEq
+hi def link xinetdCPS           xinetdNumber
+hi def link xinetdFloatEq       xinetdEq
+hi def link xinetdFloat         xinetdNumber
+hi def link xinetdOctalEq       xinetdEq
+hi def link xinetdOctal         xinetdNumber
+hi def link xinetdOctalZero     PreProc
+hi def link xinetdOctalError    Error
+hi def link xinetdASEq          xinetdEq
+hi def link xinetdAS            xinetdNumber
+hi def link xinetdASMult        PreProc
+hi def link xinetdDenyTimeEq    xinetdEq
+hi def link xinetdDenyTime      PreProc
+
+let b:current_syntax = "xinetd"
+
+let &cpo = s:cpo_save
+unlet s:cpo_save
--- /dev/null
+++ b/lib/vimfiles/syntax/xkb.vim
@@ -1,0 +1,91 @@
+" Vim syntax file
+" This is a GENERATED FILE. Please always refer to source file at the URI below.
+" Language: XKB (X Keyboard Extension) components
+" Maintainer: David Ne\v{c}as (Yeti) <yeti@physics.muni.cz>
+" Last Change: 2003-04-13
+" URL: http://trific.ath.cx/Ftp/vim/syntax/xkb.vim
+
+" Setup
+if version >= 600
+	if exists("b:current_syntax")
+		finish
+	endif
+else
+	syntax clear
+endif
+
+syn case match
+syn sync minlines=100
+
+" Comments
+syn region xkbComment start="//" skip="\\$" end="$" keepend contains=xkbTodo
+syn region xkbComment start="/\*" matchgroup=NONE end="\*/" contains=xkbCommentStartError,xkbTodo
+syn match xkbCommentError "\*/"
+syntax match xkbCommentStartError "/\*" contained
+syn sync ccomment xkbComment
+syn keyword xkbTodo TODO FIXME contained
+
+" Literal strings
+syn match xkbSpecialChar "\\\d\d\d\|\\." contained
+syn region xkbString start=+"+ skip=+\\\\\|\\"+ end=+"+ contains=xkbSpecialChar oneline
+
+" Catch errors caused by wrong parenthesization
+syn region xkbParen start='(' end=')' contains=ALLBUT,xkbParenError,xkbSpecial,xkbTodo transparent
+syn match xkbParenError ")"
+syn region xkbBrace start='{' end='}' contains=ALLBUT,xkbBraceError,xkbSpecial,xkbTodo transparent
+syn match xkbBraceError "}"
+syn region xkbBracket start='\[' end='\]' contains=ALLBUT,xkbBracketError,xkbSpecial,xkbTodo transparent
+syn match xkbBracketError "\]"
+
+" Physical keys
+syn match xkbPhysicalKey "<\w\+>"
+
+" Keywords
+syn keyword xkbPreproc augment include replace
+syn keyword xkbConstant False True
+syn keyword xkbModif override replace
+syn keyword xkbIdentifier action affect alias allowExplicit approx baseColor button clearLocks color controls cornerRadius count ctrls description driveskbd font fontSize gap group groups height indicator indicatorDrivesKeyboard interpret key keys labelColor latchToLock latchMods left level_name map maximum minimum modifier_map modifiers name offColor onColor outline preserve priority repeat row section section setMods shape slant solid symbols text top type useModMapMods virtualModifier virtualMods virtual_modifiers weight whichModState width
+syn keyword xkbFunction AnyOf ISOLock LatchGroup LatchMods LockControls LockGroup LockMods LockPointerButton MovePtr NoAction PointerButton SetControls SetGroup SetMods SetPtrDflt Terminate
+syn keyword xkbTModif default hidden partial virtual
+syn keyword xkbSect alphanumeric_keys alternate_group function_keys keypad_keys modifier_keys xkb_compatibility xkb_geometry xkb_keycodes xkb_keymap xkb_semantics xkb_symbols xkb_types
+
+" Define the default highlighting
+if version >= 508 || !exists("did_xkb_syntax_inits")
+	if version < 508
+		let did_xkb_syntax_inits = 1
+		command -nargs=+ HiLink hi link <args>
+	else
+		command -nargs=+ HiLink hi def link <args>
+	endif
+
+	HiLink xkbModif xkbPreproc
+	HiLink xkbTModif xkbPreproc
+	HiLink xkbPreproc Preproc
+
+	HiLink xkbIdentifier Keyword
+	HiLink xkbFunction Function
+	HiLink xkbSect Type
+	HiLink xkbPhysicalKey Identifier
+	HiLink xkbKeyword Keyword
+
+	HiLink xkbComment Comment
+	HiLink xkbTodo Todo
+
+	HiLink xkbConstant Constant
+	HiLink xkbString String
+
+	HiLink xkbSpecialChar xkbSpecial
+	HiLink xkbSpecial Special
+
+	HiLink xkbParenError xkbBalancingError
+	HiLink xkbBraceError xkbBalancingError
+	HiLink xkbBraketError xkbBalancingError
+	HiLink xkbBalancingError xkbError
+	HiLink xkbCommentStartError xkbCommentError
+	HiLink xkbCommentError xkbError
+	HiLink xkbError Error
+
+	delcommand HiLink
+endif
+
+let b:current_syntax = "xkb"
--- /dev/null
+++ b/lib/vimfiles/syntax/xmath.vim
@@ -1,0 +1,236 @@
+" Vim syntax file
+" Language:	xmath (a simulation tool)
+" Maintainer:	Dr. Charles E. Campbell, Jr. <NdrOchipS@PcampbellAfamily.Mbiz>
+" Last Change:	Sep 11, 2006
+" Version:	6
+" URL:	http://mysite.verizon.net/astronaut/vim/index.html#vimlinks_syntax
+
+" For version 5.x: Clear all syntax items
+" For version 6.x: Quit when a syntax file was already loaded
+if version < 600
+  syntax clear
+elseif exists("b:current_syntax")
+  finish
+endif
+
+" parenthesis sanity checker
+syn region xmathZone	matchgroup=Delimiter start="(" matchgroup=Delimiter end=")" transparent contains=ALLBUT,xmathError,xmathBraceError,xmathCurlyError
+syn region xmathZone	matchgroup=Delimiter start="{" matchgroup=Delimiter end="}" transparent contains=ALLBUT,xmathError,xmathBraceError,xmathParenError
+syn region xmathZone	matchgroup=Delimiter start="\[" matchgroup=Delimiter end="]" transparent contains=ALLBUT,xmathError,xmathCurlyError,xmathParenError
+syn match  xmathError	"[)\]}]"
+syn match  xmathBraceError	"[)}]"	contained
+syn match  xmathCurlyError	"[)\]]"	contained
+syn match  xmathParenError	"[\]}]"	contained
+syn match  xmathComma	"[,;:]"
+syn match  xmathComma	"\.\.\.$"
+
+" A bunch of useful xmath keywords
+syn case ignore
+syn keyword xmathFuncCmd	function	endfunction	command	endcommand
+syn keyword xmathStatement	abort	beep	debug	default	define
+syn keyword xmathStatement	execute	exit	pause	return	undefine
+syn keyword xmathConditional	if	else	elseif	endif
+syn keyword xmathRepeat	while	for	endwhile	endfor
+syn keyword xmathCmd	anigraph	deletedatastore	keep	renamedatastore
+syn keyword xmathCmd	autocode	deletestd	linkhyper	renamestd
+syn keyword xmathCmd	build	deletesuperblock	linksim	renamesuperblock
+syn keyword xmathCmd	comment	deletetransition	listusertype	save
+syn keyword xmathCmd	copydatastore	deleteusertype	load	sbadisplay
+syn keyword xmathCmd	copystd	detailmodel	lock	set
+syn keyword xmathCmd	copysuperblock	display	minmax_display	setsbdefault
+syn keyword xmathCmd	createblock	documentit	modifyblock	show
+syn keyword xmathCmd	createbubble	editcatalog	modifybubble	showlicense
+syn keyword xmathCmd	createconnection	erase	modifystd	showsbdefault
+syn keyword xmathCmd	creatertf	expandsuperbubble	modifysuperblock	stop
+syn keyword xmathCmd	createstd	for	modifytransition	stopcosim
+syn keyword xmathCmd	createsuperblock	go	modifyusertype	syntax
+syn keyword xmathCmd	createsuperbubble	goto	new	unalias
+syn keyword xmathCmd	createtransition	hardcopy	next	unlock
+syn keyword xmathCmd	createusertype	help	polargraph	usertype
+syn keyword xmathCmd	delete	hyperbuild	print	whatis
+syn keyword xmathCmd	deleteblock	if	printmodel	while
+syn keyword xmathCmd	deletebubble	ifilter	quit	who
+syn keyword xmathCmd	deleteconnection	ipcwc	remove	xgraph
+
+syn keyword xmathFunc	abcd	eye	irea	querystdoptions
+syn keyword xmathFunc	abs	eyepattern	is	querysuperblock
+syn keyword xmathFunc	acos	feedback	ISID	querysuperblockopt
+syn keyword xmathFunc	acosh	fft	ISID	Models	querytransition
+syn keyword xmathFunc	adconversion	fftpdm	kronecker	querytransitionopt
+syn keyword xmathFunc	afeedback	filter	length	qz
+syn keyword xmathFunc	all	find	limit	rampinvar
+syn keyword xmathFunc	ambiguity	firparks	lin	random
+syn keyword xmathFunc	amdemod	firremez	lin30	randpdm
+syn keyword xmathFunc	analytic	firwind	linearfm	randpert
+syn keyword xmathFunc	analyze	fmdemod	linfnorm	randsys
+syn keyword xmathFunc	any	forwdiff	lintodb	rank
+syn keyword xmathFunc	append	fprintf	list	rayleigh
+syn keyword xmathFunc	argn	frac	log	rcepstrum
+syn keyword xmathFunc	argv	fracred	log10	rcond
+syn keyword xmathFunc	arma	freq	logm	rdintegrate
+syn keyword xmathFunc	arma2ss	freqcircle	lognormal	read
+syn keyword xmathFunc	armax	freqcont	logspace	real
+syn keyword xmathFunc	ascii	frequencyhop	lowpass	rectify
+syn keyword xmathFunc	asin	fsesti	lpopt	redschur
+syn keyword xmathFunc	asinh	fslqgcomp	lqgcomp	reflect
+syn keyword xmathFunc	atan	fsregu	lqgltr	regulator
+syn keyword xmathFunc	atan2	fwls	ls	residue
+syn keyword xmathFunc	atanh	gabor	ls2unc	riccati
+syn keyword xmathFunc	attach_ac100	garb	ls2var	riccati_eig
+syn keyword xmathFunc	backdiff	gaussian	lsjoin	riccati_schur
+syn keyword xmathFunc	balance	gcexp	lu	ricean
+syn keyword xmathFunc	balmoore	gcos	lyapunov	rifd
+syn keyword xmathFunc	bandpass	gdfileselection	makecontinuous	rlinfo
+syn keyword xmathFunc	bandstop	gdmessage	makematrix	rlocus
+syn keyword xmathFunc	bj	gdselection	makepoly	rms
+syn keyword xmathFunc	blknorm	genconv	margin	rootlocus
+syn keyword xmathFunc	bode	get	markoff	roots
+syn keyword xmathFunc	bpm	get_info30	matchedpz	round
+syn keyword xmathFunc	bpm2inn	get_inn	max	rref
+syn keyword xmathFunc	bpmjoin	gfdm	maxlike	rve_get
+syn keyword xmathFunc	bpmsplit	gfsk	mean	rve_info
+syn keyword xmathFunc	bst	gfskernel	mergeseg	rve_reset
+syn keyword xmathFunc	buttconstr	gfunction	min	rve_update
+syn keyword xmathFunc	butterworth	ggauss	minimal	samplehold
+syn keyword xmathFunc	cancel	giv	mkpert	schur
+syn keyword xmathFunc	canform	giv2var	mkphase	sdf
+syn keyword xmathFunc	ccepstrum	givjoin	mma	sds
+syn keyword xmathFunc	char	gpsk	mmaget	sdtrsp
+syn keyword xmathFunc	chebconstr	gpulse	mmaput	sec
+syn keyword xmathFunc	chebyshev	gqam	mod	sech
+syn keyword xmathFunc	check	gqpsk	modal	siginterp
+syn keyword xmathFunc	cholesky	gramp	modalstate	sign
+syn keyword xmathFunc	chop	gsawtooth	modcarrier	sim
+syn keyword xmathFunc	circonv	gsigmoid	mreduce	sim30
+syn keyword xmathFunc	circorr	gsin	mtxplt	simin
+syn keyword xmathFunc	clock	gsinc	mu	simin30
+syn keyword xmathFunc	clocus	gsqpsk	mulhank	simout
+syn keyword xmathFunc	clsys	gsquarewave	multipath	simout30
+syn keyword xmathFunc	coherence	gstep	musynfit	simtransform
+syn keyword xmathFunc	colorind	GuiDialogCreate	mxstr2xmstr	sin
+syn keyword xmathFunc	combinepf	GuiDialogDestroy	mxstring2xmstring	singriccati
+syn keyword xmathFunc	commentof	GuiFlush	names	sinh
+syn keyword xmathFunc	compare	GuiGetValue	nichols	sinm
+syn keyword xmathFunc	complementaryerf	GuiManage	noisefilt	size
+syn keyword xmathFunc	complexenvelope	GuiPlot	none	smargin
+syn keyword xmathFunc	complexfreqshift	GuiPlotGet	norm	sns2sys
+syn keyword xmathFunc	concatseg	GuiSetValue	numden	sort
+syn keyword xmathFunc	condition	GuiShellCreate	nyquist	spectrad
+syn keyword xmathFunc	conj	GuiShellDeiconify	obscf	spectrum
+syn keyword xmathFunc	conmap	GuiShellDestroy	observable	spline
+syn keyword xmathFunc	connect	GuiShellIconify	oe	sprintf
+syn keyword xmathFunc	conpdm	GuiShellLower	ones	sqrt
+syn keyword xmathFunc	constellation	GuiShellRaise	ophank	sqrtm
+syn keyword xmathFunc	consys	GuiShellRealize	optimize	sresidualize
+syn keyword xmathFunc	controllable	GuiShellUnrealize	optscale	ss2arma
+syn keyword xmathFunc	convolve	GuiTimer	orderfilt	sst
+syn keyword xmathFunc	correlate	GuiToolCreate	orderstate	ssv
+syn keyword xmathFunc	cos	GuiToolDestroy	orth	stable
+syn keyword xmathFunc	cosh	GuiToolExist	oscmd	stair
+syn keyword xmathFunc	cosm	GuiUnmanage	oscope	starp
+syn keyword xmathFunc	cot	GuiWidgetExist	osscale	step
+syn keyword xmathFunc	coth	h2norm	padcrop	stepinvar
+syn keyword xmathFunc	covariance	h2syn	partialsum	string
+syn keyword xmathFunc	csc	hadamard	pdm	stringex
+syn keyword xmathFunc	csch	hankelsv	pdmslice	substr
+syn keyword xmathFunc	csum	hessenberg	pem	subsys
+syn keyword xmathFunc	ctrcf	highpass	perfplots	sum
+syn keyword xmathFunc	ctrlplot	hilbert	period	svd
+syn keyword xmathFunc	daug	hilberttransform	pfscale	svplot
+syn keyword xmathFunc	dbtolin	hinfcontr	phaseshift	sweep
+syn keyword xmathFunc	dct	hinfnorm	pinv	symbolmap
+syn keyword xmathFunc	decimate	hinfsyn	plot	sys2sns
+syn keyword xmathFunc	defFreqRange	histogram	plot30	sysic
+syn keyword xmathFunc	defTimeRange	idfreq	pmdemod	Sysid
+syn keyword xmathFunc	delay	idimpulse	poisson	system
+syn keyword xmathFunc	delsubstr	idsim	poissonimpulse	tan
+syn keyword xmathFunc	det	ifft	poleplace	tanh
+syn keyword xmathFunc	detrend	imag	poles	taper
+syn keyword xmathFunc	dht	impinvar	polezero	tfid
+syn keyword xmathFunc	diagonal	impplot	poltrend	toeplitz
+syn keyword xmathFunc	differentiate	impulse	polyfit	trace
+syn keyword xmathFunc	directsequence	index	polynomial	tril
+syn keyword xmathFunc	discretize	indexlist	polyval	trim
+syn keyword xmathFunc	divide	initial	polyvalm	trim30
+syn keyword xmathFunc	domain	initmodel	prbs	triu
+syn keyword xmathFunc	dst	initx0	product	trsp
+syn keyword xmathFunc	eig	inn2bpm	psd	truncate
+syn keyword xmathFunc	ellipconstr	inn2pe	put_inn	tustin
+syn keyword xmathFunc	elliptic	inn2unc	qpopt	uniform
+syn keyword xmathFunc	erf	insertseg	qr	val
+syn keyword xmathFunc	error	int	quantize	variance
+syn keyword xmathFunc	estimator	integrate	queryblock	videolines
+syn keyword xmathFunc	etfe	integratedump	queryblockoptions	wcbode
+syn keyword xmathFunc	exist	interp	querybubble	wcgain
+syn keyword xmathFunc	exp	interpolate	querybubbleoptionswindow
+syn keyword xmathFunc	expm	inv	querycatalog	wtbalance
+syn keyword xmathFunc	extractchan	invhilbert	queryconnection	zeros
+syn keyword xmathFunc	extractseg	iqmix	querystd
+
+syn case match
+
+" Labels (supports xmath's goto)
+syn match   xmathLabel	 "^\s*<[a-zA-Z_][a-zA-Z0-9]*>"
+
+" String and Character constants
+" Highlight special characters (those which have a backslash) differently
+syn match   xmathSpecial	contained "\\\d\d\d\|\\."
+syn region  xmathString	start=+"+  skip=+\\\\\|\\"+  end=+"+ contains=xmathSpecial,@Spell
+syn match   xmathCharacter	"'[^\\]'"
+syn match   xmathSpecialChar	"'\\.'"
+
+syn match   xmathNumber	"-\=\<\d\+L\=\>\|0[xX][0-9a-fA-F]\+\>"
+
+" Comments:
+" xmath supports #...  (like Unix shells)
+"       and      #{ ... }# comment blocks
+syn cluster xmathCommentGroup	contains=xmathString,xmathTodo,@Spell
+syn keyword xmathTodo contained	COMBAK	DEBUG	FIXME	Todo	TODO	XXX
+syn match   xmathComment	"#.*$"		contains=@xmathCommentGroup
+syn region  xmathCommentBlock	start="#{" end="}#"	contains=@xmathCommentGroup
+
+" synchronizing
+syn sync match xmathSyncComment	grouphere xmathCommentBlock "#{"
+syn sync match xmathSyncComment	groupthere NONE "}#"
+
+" Define the default highlighting.
+" For version 5.7 and earlier: only when not done already
+" For version 5.8 and later: only when an item doesn't have highlighting yet
+if version >= 508 || !exists("did_xmath_syntax_inits")
+  if version < 508
+    let did_xmath_syntax_inits = 1
+    command -nargs=+ HiLink hi link <args>
+  else
+    command -nargs=+ HiLink hi def link <args>
+  endif
+
+  HiLink xmathBraceError	xmathError
+  HiLink xmathCmd	xmathStatement
+  HiLink xmathCommentBlock	xmathComment
+  HiLink xmathCurlyError	xmathError
+  HiLink xmathFuncCmd	xmathStatement
+  HiLink xmathParenError	xmathError
+
+  " The default methods for highlighting.  Can be overridden later
+  HiLink xmathCharacter	Character
+  HiLink xmathComma	Delimiter
+  HiLink xmathComment	Comment
+  HiLink xmathCommentBlock	Comment
+  HiLink xmathConditional	Conditional
+  HiLink xmathError	Error
+  HiLink xmathFunc	Function
+  HiLink xmathLabel	PreProc
+  HiLink xmathNumber	Number
+  HiLink xmathRepeat	Repeat
+  HiLink xmathSpecial	Type
+  HiLink xmathSpecialChar	SpecialChar
+  HiLink xmathStatement	Statement
+  HiLink xmathString	String
+  HiLink xmathTodo	Todo
+
+  delcommand HiLink
+endif
+
+let b:current_syntax = "xmath"
+
+" vim: ts=17
--- /dev/null
+++ b/lib/vimfiles/syntax/xml.vim
@@ -1,0 +1,344 @@
+" Vim syntax file
+" Language:	XML
+" Maintainer:	Johannes Zellner <johannes@zellner.org>
+"		Author and previous maintainer:
+"		Paul Siegmann <pauls@euronet.nl>
+" Last Change:	Mi, 13 Apr 2005 22:40:09 CEST
+" Filenames:	*.xml
+" $Id: xml.vim,v 1.3 2006/04/11 21:32:00 vimboss Exp $
+
+" CONFIGURATION:
+"   syntax folding can be turned on by
+"
+"      let g:xml_syntax_folding = 1
+"
+"   before the syntax file gets loaded (e.g. in ~/.vimrc).
+"   This might slow down syntax highlighting significantly,
+"   especially for large files.
+"
+" CREDITS:
+"   The original version was derived by Paul Siegmann from
+"   Claudio Fleiner's html.vim.
+"
+" REFERENCES:
+"   [1] http://www.w3.org/TR/2000/REC-xml-20001006
+"   [2] http://www.w3.org/XML/1998/06/xmlspec-report-19980910.htm
+"
+"   as <hirauchi@kiwi.ne.jp> pointed out according to reference [1]
+"
+"   2.3 Common Syntactic Constructs
+"   [4]    NameChar    ::=    Letter | Digit | '.' | '-' | '_' | ':' | CombiningChar | Extender
+"   [5]    Name        ::=    (Letter | '_' | ':') (NameChar)*
+"
+" NOTE:
+"   1) empty tag delimiters "/>" inside attribute values (strings)
+"      confuse syntax highlighting.
+"   2) for large files, folding can be pretty slow, especially when
+"      loading a file the first time and viewoptions contains 'folds'
+"      so that folds of previous sessions are applied.
+"      Don't use 'foldmethod=syntax' in this case.
+
+
+" Quit when a syntax file was already loaded
+if exists("b:current_syntax")
+    finish
+endif
+
+let s:xml_cpo_save = &cpo
+set cpo&vim
+
+syn case match
+
+" mark illegal characters
+syn match xmlError "[<&]"
+
+" strings (inside tags) aka VALUES
+"
+" EXAMPLE:
+"
+" <tag foo.attribute = "value">
+"                      ^^^^^^^
+syn region  xmlString contained start=+"+ end=+"+ contains=xmlEntity,@Spell display
+syn region  xmlString contained start=+'+ end=+'+ contains=xmlEntity,@Spell display
+
+
+" punctuation (within attributes) e.g. <tag xml:foo.attribute ...>
+"                                              ^   ^
+" syn match   xmlAttribPunct +[-:._]+ contained display
+syn match   xmlAttribPunct +[:.]+ contained display
+
+" no highlighting for xmlEqual (xmlEqual has no highlighting group)
+syn match   xmlEqual +=+ display
+
+
+" attribute, everything before the '='
+"
+" PROVIDES: @xmlAttribHook
+"
+" EXAMPLE:
+"
+" <tag foo.attribute = "value">
+"      ^^^^^^^^^^^^^
+"
+syn match   xmlAttrib
+    \ +[-'"<]\@<!\<[a-zA-Z:_][-.0-9a-zA-Z0-9:_]*\>\(['">]\@!\|$\)+
+    \ contained
+    \ contains=xmlAttribPunct,@xmlAttribHook
+    \ display
+
+
+" namespace spec
+"
+" PROVIDES: @xmlNamespaceHook
+"
+" EXAMPLE:
+"
+" <xsl:for-each select = "lola">
+"  ^^^
+"
+if exists("g:xml_namespace_transparent")
+syn match   xmlNamespace
+    \ +\(<\|</\)\@<=[^ /!?<>"':]\+[:]\@=+
+    \ contained
+    \ contains=@xmlNamespaceHook
+    \ transparent
+    \ display
+else
+syn match   xmlNamespace
+    \ +\(<\|</\)\@<=[^ /!?<>"':]\+[:]\@=+
+    \ contained
+    \ contains=@xmlNamespaceHook
+    \ display
+endif
+
+
+" tag name
+"
+" PROVIDES: @xmlTagHook
+"
+" EXAMPLE:
+"
+" <tag foo.attribute = "value">
+"  ^^^
+"
+syn match   xmlTagName
+    \ +[<]\@<=[^ /!?<>"']\++
+    \ contained
+    \ contains=xmlNamespace,xmlAttribPunct,@xmlTagHook
+    \ display
+
+
+if exists('g:xml_syntax_folding')
+
+    " start tag
+    " use matchgroup=xmlTag to skip over the leading '<'
+    "
+    " PROVIDES: @xmlStartTagHook
+    "
+    " EXAMPLE:
+    "
+    " <tag id="whoops">
+    " s^^^^^^^^^^^^^^^e
+    "
+    syn region   xmlTag
+	\ matchgroup=xmlTag start=+<[^ /!?<>"']\@=+
+	\ matchgroup=xmlTag end=+>+
+	\ contained
+	\ contains=xmlError,xmlTagName,xmlAttrib,xmlEqual,xmlString,@xmlStartTagHook
+
+
+    " highlight the end tag
+    "
+    " PROVIDES: @xmlTagHook
+    " (should we provide a separate @xmlEndTagHook ?)
+    "
+    " EXAMPLE:
+    "
+    " </tag>
+    " ^^^^^^
+    "
+    syn match   xmlEndTag
+	\ +</[^ /!?<>"']\+>+
+	\ contained
+	\ contains=xmlNamespace,xmlAttribPunct,@xmlTagHook
+
+
+    " tag elements with syntax-folding.
+    " NOTE: NO HIGHLIGHTING -- highlighting is done by contained elements
+    "
+    " PROVIDES: @xmlRegionHook
+    "
+    " EXAMPLE:
+    "
+    " <tag id="whoops">
+    "   <!-- comment -->
+    "   <another.tag></another.tag>
+    "   <empty.tag/>
+    "   some data
+    " </tag>
+    "
+    syn region   xmlRegion
+	\ start=+<\z([^ /!?<>"']\+\)+
+	\ skip=+<!--\_.\{-}-->+
+	\ end=+</\z1\_\s\{-}>+
+	\ matchgroup=xmlEndTag end=+/>+
+	\ fold
+	\ contains=xmlTag,xmlEndTag,xmlCdata,xmlRegion,xmlComment,xmlEntity,xmlProcessing,@xmlRegionHook,@Spell
+	\ keepend
+	\ extend
+
+else
+
+    " no syntax folding:
+    " - contained attribute removed
+    " - xmlRegion not defined
+    "
+    syn region   xmlTag
+	\ matchgroup=xmlTag start=+<[^ /!?<>"']\@=+
+	\ matchgroup=xmlTag end=+>+
+	\ contains=xmlError,xmlTagName,xmlAttrib,xmlEqual,xmlString,@xmlStartTagHook
+
+    syn match   xmlEndTag
+	\ +</[^ /!?<>"']\+>+
+	\ contains=xmlNamespace,xmlAttribPunct,@xmlTagHook
+
+endif
+
+
+" &entities; compare with dtd
+syn match   xmlEntity                 "&[^; \t]*;" contains=xmlEntityPunct
+syn match   xmlEntityPunct  contained "[&.;]"
+
+if exists('g:xml_syntax_folding')
+
+    " The real comments (this implements the comments as defined by xml,
+    " but not all xml pages actually conform to it. Errors are flagged.
+    syn region  xmlComment
+	\ start=+<!+
+	\ end=+>+
+	\ contains=xmlCommentPart,xmlCommentError
+	\ extend
+	\ fold
+
+else
+
+    " no syntax folding:
+    " - fold attribute removed
+    "
+    syn region  xmlComment
+	\ start=+<!+
+	\ end=+>+
+	\ contains=xmlCommentPart,xmlCommentError
+	\ extend
+
+endif
+
+syn keyword xmlTodo         contained TODO FIXME XXX
+syn match   xmlCommentError contained "[^><!]"
+syn region  xmlCommentPart
+    \ start=+--+
+    \ end=+--+
+    \ contained
+    \ contains=xmlTodo,@xmlCommentHook,@Spell
+
+
+" CData sections
+"
+" PROVIDES: @xmlCdataHook
+"
+syn region    xmlCdata
+    \ start=+<!\[CDATA\[+
+    \ end=+]]>+
+    \ contains=xmlCdataStart,xmlCdataEnd,@xmlCdataHook,@Spell
+    \ keepend
+    \ extend
+
+" using the following line instead leads to corrupt folding at CDATA regions
+" syn match    xmlCdata      +<!\[CDATA\[\_.\{-}]]>+  contains=xmlCdataStart,xmlCdataEnd,@xmlCdataHook
+syn match    xmlCdataStart +<!\[CDATA\[+  contained contains=xmlCdataCdata
+syn keyword  xmlCdataCdata CDATA          contained
+syn match    xmlCdataEnd   +]]>+          contained
+
+
+" Processing instructions
+" This allows "?>" inside strings -- good idea?
+syn region  xmlProcessing matchgroup=xmlProcessingDelim start="<?" end="?>" contains=xmlAttrib,xmlEqual,xmlString
+
+
+if exists('g:xml_syntax_folding')
+
+    " DTD -- we use dtd.vim here
+    syn region  xmlDocType matchgroup=xmlDocTypeDecl
+	\ start="<!DOCTYPE"he=s+2,rs=s+2 end=">"
+	\ fold
+	\ contains=xmlDocTypeKeyword,xmlInlineDTD,xmlString
+else
+
+    " no syntax folding:
+    " - fold attribute removed
+    "
+    syn region  xmlDocType matchgroup=xmlDocTypeDecl
+	\ start="<!DOCTYPE"he=s+2,rs=s+2 end=">"
+	\ contains=xmlDocTypeKeyword,xmlInlineDTD,xmlString
+
+endif
+
+syn keyword xmlDocTypeKeyword contained DOCTYPE PUBLIC SYSTEM
+syn region  xmlInlineDTD contained matchgroup=xmlDocTypeDecl start="\[" end="]" contains=@xmlDTD
+syn include @xmlDTD <sfile>:p:h/dtd.vim
+unlet b:current_syntax
+
+
+" synchronizing
+" TODO !!! to be improved !!!
+
+syn sync match xmlSyncDT grouphere  xmlDocType +\_.\(<!DOCTYPE\)\@=+
+" syn sync match xmlSyncDT groupthere  NONE       +]>+
+
+if exists('g:xml_syntax_folding')
+    syn sync match xmlSync grouphere   xmlRegion  +\_.\(<[^ /!?<>"']\+\)\@=+
+    " syn sync match xmlSync grouphere  xmlRegion "<[^ /!?<>"']*>"
+    syn sync match xmlSync groupthere  xmlRegion  +</[^ /!?<>"']\+>+
+endif
+
+syn sync minlines=100
+
+
+" The default highlighting.
+hi def link xmlTodo		Todo
+hi def link xmlTag		Function
+hi def link xmlTagName		Function
+hi def link xmlEndTag		Identifier
+if !exists("g:xml_namespace_transparent")
+    hi def link xmlNamespace	Tag
+endif
+hi def link xmlEntity		Statement
+hi def link xmlEntityPunct	Type
+
+hi def link xmlAttribPunct	Comment
+hi def link xmlAttrib		Type
+
+hi def link xmlString		String
+hi def link xmlComment		Comment
+hi def link xmlCommentPart	Comment
+hi def link xmlCommentError	Error
+hi def link xmlError		Error
+
+hi def link xmlProcessingDelim	Comment
+hi def link xmlProcessing	Type
+
+hi def link xmlCdata		String
+hi def link xmlCdataCdata	Statement
+hi def link xmlCdataStart	Type
+hi def link xmlCdataEnd		Type
+
+hi def link xmlDocTypeDecl	Function
+hi def link xmlDocTypeKeyword	Statement
+hi def link xmlInlineDTD	Function
+
+let b:current_syntax = "xml"
+
+let &cpo = s:xml_cpo_save
+unlet s:xml_cpo_save
+
+" vim: ts=8
--- /dev/null
+++ b/lib/vimfiles/syntax/xmodmap.vim
@@ -1,0 +1,677 @@
+" Vim syntax file
+" Language:         xmodmap(1) definition file
+" Maintainer:       Nikolai Weibull <now@bitwi.se>
+" Latest Revision:  2006-04-19
+
+if exists("b:current_syntax")
+  finish
+endif
+
+let s:cpo_save = &cpo
+set cpo&vim
+
+syn keyword xmodmapTodo       contained TODO FIXME XXX NOTE
+
+syn region  xmodmapComment    display oneline start='^!' end='$'
+                              \ contains=xmodmapTodo,@Spell
+
+syn case ignore
+syn match   xmodmapInt        display '\<\d\+\>'
+syn match   xmodmapHex        display '\<0x\x\+\>'
+syn match   xmodmapOctal      display '\<0\o\+\>'
+syn match   xmodmapOctalError display '\<0\o*[89]\d*'
+syn case match
+
+syn match   xmodmapKeySym     display '\<[A-Za-z]\>'
+
+" #include <X11/keysymdef.h>
+syn keyword xmodmapKeySym     XK_VoidSymbol XK_BackSpace XK_Tab XK_Linefeed
+                              \ XK_Clear XK_Return XK_Pause XK_Scroll_Lock
+                              \ XK_Sys_Req XK_Escape XK_Delete XK_Multi_key
+                              \ XK_Codeinput XK_SingleCandidate
+                              \ XK_MultipleCandidate XK_PreviousCandidate
+                              \ XK_Kanji XK_Muhenkan XK_Henkan_Mode
+                              \ XK_Henkan XK_Romaji XK_Hiragana XK_Katakana
+                              \ XK_Hiragana_Katakana XK_Zenkaku XK_Hankaku
+                              \ XK_Zenkaku_Hankaku XK_Touroku XK_Massyo
+                              \ XK_Kana_Lock XK_Kana_Shift XK_Eisu_Shift
+                              \ XK_Eisu_toggle XK_Kanji_Bangou XK_Zen_Koho
+                              \ XK_Mae_Koho XK_Home XK_Left XK_Up XK_Right
+                              \ XK_Down XK_Prior XK_Page_Up XK_Next
+                              \ XK_Page_Down XK_End XK_Begin XK_Select
+                              \ XK_Print XK_Execute XK_Insert XK_Undo XK_Redo
+                              \ XK_Menu XK_Find XK_Cancel XK_Help XK_Break
+                              \ XK_Mode_switch XK_script_switch XK_Num_Lock
+                              \ XK_KP_Space XK_KP_Tab XK_KP_Enter XK_KP_F1
+                              \ XK_KP_F2 XK_KP_F3 XK_KP_F4 XK_KP_Home
+                              \ XK_KP_Left XK_KP_Up XK_KP_Right XK_KP_Down
+                              \ XK_KP_Prior XK_KP_Page_Up XK_KP_Next
+                              \ XK_KP_Page_Down XK_KP_End XK_KP_Begin
+                              \ XK_KP_Insert XK_KP_Delete XK_KP_Equal
+                              \ XK_KP_Multiply XK_KP_Add XK_KP_Separator
+                              \ XK_KP_Subtract XK_KP_Decimal XK_KP_Divide
+                              \ XK_KP_0 XK_KP_1 XK_KP_2 XK_KP_3 XK_KP_4
+                              \ XK_KP_5 XK_KP_6 XK_KP_7 XK_KP_8 XK_KP_9 XK_F1
+                              \ XK_F2 XK_F3 XK_F4 XK_F5 XK_F6 XK_F7 XK_F8
+                              \ XK_F9 XK_F10 XK_F11 XK_L1 XK_F12 XK_L2 XK_F13
+                              \ XK_L3 XK_F14 XK_L4 XK_F15 XK_L5 XK_F16 XK_L6
+                              \ XK_F17 XK_L7 XK_F18 XK_L8 XK_F19 XK_L9 XK_F20
+                              \ XK_L10 XK_F21 XK_R1 XK_F22 XK_R2 XK_F23
+                              \ XK_R3 XK_F24 XK_R4 XK_F25 XK_R5 XK_F26
+                              \ XK_R6 XK_F27 XK_R7 XK_F28 XK_R8 XK_F29
+                              \ XK_R9 XK_F30 XK_R10 XK_F31 XK_R11 XK_F32
+                              \ XK_R12 XK_F33 XK_R13 XK_F34 XK_R14 XK_F35
+                              \ XK_R15 XK_Shift_L XK_Shift_R XK_Control_L
+                              \ XK_Control_R XK_Caps_Lock XK_Shift_Lock
+                              \ XK_Meta_L XK_Meta_R XK_Alt_L XK_Alt_R
+                              \ XK_Super_L XK_Super_R XK_Hyper_L XK_Hyper_R
+                              \ XK_dead_hook XK_dead_horn XK_3270_Duplicate
+                              \ XK_3270_FieldMark XK_3270_Right2 XK_3270_Left2
+                              \ XK_3270_BackTab XK_3270_EraseEOF
+                              \ XK_3270_EraseInput XK_3270_Reset
+                              \ XK_3270_Quit XK_3270_PA1 XK_3270_PA2
+                              \ XK_3270_PA3 XK_3270_Test XK_3270_Attn
+                              \ XK_3270_CursorBlink XK_3270_AltCursor
+                              \ XK_3270_KeyClick XK_3270_Jump
+                              \ XK_3270_Ident XK_3270_Rule XK_3270_Copy
+                              \ XK_3270_Play XK_3270_Setup XK_3270_Record
+                              \ XK_3270_ChangeScreen XK_3270_DeleteWord
+                              \ XK_3270_ExSelect XK_3270_CursorSelect
+                              \ XK_3270_PrintScreen XK_3270_Enter XK_space
+                              \ XK_exclam XK_quotedbl XK_numbersign XK_dollar
+                              \ XK_percent XK_ampersand XK_apostrophe
+                              \ XK_quoteright XK_parenleft XK_parenright
+                              \ XK_asterisk XK_plus XK_comma XK_minus
+                              \ XK_period XK_slash XK_0 XK_1 XK_2 XK_3
+                              \ XK_4 XK_5 XK_6 XK_7 XK_8 XK_9 XK_colon
+                              \ XK_semicolon XK_less XK_equal XK_greater
+                              \ XK_question XK_at XK_A XK_B XK_C XK_D XK_E
+                              \ XK_F XK_G XK_H XK_I XK_J XK_K XK_L XK_M XK_N
+                              \ XK_O XK_P XK_Q XK_R XK_S XK_T XK_U XK_V XK_W
+                              \ XK_X XK_Y XK_Z XK_bracketleft XK_backslash
+                              \ XK_bracketright XK_asciicircum XK_underscore
+                              \ XK_grave XK_quoteleft XK_a XK_b XK_c XK_d
+                              \ XK_e XK_f XK_g XK_h XK_i XK_j XK_k XK_l
+                              \ XK_m XK_n XK_o XK_p XK_q XK_r XK_s XK_t XK_u
+                              \ XK_v XK_w XK_x XK_y XK_z XK_braceleft XK_bar
+                              \ XK_braceright XK_asciitilde XK_nobreakspace
+                              \ XK_exclamdown XK_cent XK_sterling XK_currency
+                              \ XK_yen XK_brokenbar XK_section XK_diaeresis
+                              \ XK_copyright XK_ordfeminine XK_guillemotleft
+                              \ XK_notsign XK_hyphen XK_registered XK_macron
+                              \ XK_degree XK_plusminus XK_twosuperior
+                              \ XK_threesuperior XK_acute XK_mu XK_paragraph
+                              \ XK_periodcentered XK_cedilla XK_onesuperior
+                              \ XK_masculine XK_guillemotright XK_onequarter
+                              \ XK_onehalf XK_threequarters XK_questiondown
+                              \ XK_Agrave XK_Aacute XK_Acircumflex XK_Atilde
+                              \ XK_Adiaeresis XK_Aring XK_AE XK_Ccedilla
+                              \ XK_Egrave XK_Eacute XK_Ecircumflex
+                              \ XK_Ediaeresis XK_Igrave XK_Iacute
+                              \ XK_Icircumflex XK_Idiaeresis XK_ETH XK_Eth
+                              \ XK_Ntilde XK_Ograve XK_Oacute XK_Ocircumflex
+                              \ XK_Otilde XK_Odiaeresis XK_multiply
+                              \ XK_Ooblique XK_Ugrave XK_Uacute XK_Ucircumflex
+                              \ XK_Udiaeresis XK_Yacute XK_THORN XK_Thorn
+                              \ XK_ssharp XK_agrave XK_aacute XK_acircumflex
+                              \ XK_atilde XK_adiaeresis XK_aring XK_ae
+                              \ XK_ccedilla XK_egrave XK_eacute XK_ecircumflex
+                              \ XK_ediaeresis XK_igrave XK_iacute
+                              \ XK_icircumflex XK_idiaeresis XK_eth XK_ntilde
+                              \ XK_ograve XK_oacute XK_ocircumflex XK_otilde
+                              \ XK_odiaeresis XK_division XK_oslash XK_ugrave
+                              \ XK_uacute XK_ucircumflex XK_udiaeresis
+                              \ XK_yacute XK_thorn XK_ydiaeresis XK_Aogonek
+                              \ XK_breve XK_Lstroke XK_Lcaron XK_Sacute
+                              \ XK_Scaron XK_Scedilla XK_Tcaron XK_Zacute
+                              \ XK_Zcaron XK_Zabovedot XK_aogonek XK_ogonek
+                              \ XK_lstroke XK_lcaron XK_sacute XK_caron
+                              \ XK_scaron XK_scedilla XK_tcaron XK_zacute
+                              \ XK_doubleacute XK_zcaron XK_zabovedot
+                              \ XK_Racute XK_Abreve XK_Lacute XK_Cacute
+                              \ XK_Ccaron XK_Eogonek XK_Ecaron XK_Dcaron
+                              \ XK_Dstroke XK_Nacute XK_Ncaron XK_Odoubleacute
+                              \ XK_Rcaron XK_Uring XK_Udoubleacute
+                              \ XK_Tcedilla XK_racute XK_abreve XK_lacute
+                              \ XK_cacute XK_ccaron XK_eogonek XK_ecaron
+                              \ XK_dcaron XK_dstroke XK_nacute XK_ncaron
+                              \ XK_odoubleacute XK_udoubleacute XK_rcaron
+                              \ XK_uring XK_tcedilla XK_abovedot XK_Hstroke
+                              \ XK_Hcircumflex XK_Iabovedot XK_Gbreve
+                              \ XK_Jcircumflex XK_hstroke XK_hcircumflex
+                              \ XK_idotless XK_gbreve XK_jcircumflex
+                              \ XK_Cabovedot XK_Ccircumflex XK_Gabovedot
+                              \ XK_Gcircumflex XK_Ubreve XK_Scircumflex
+                              \ XK_cabovedot XK_ccircumflex XK_gabovedot
+                              \ XK_gcircumflex XK_ubreve XK_scircumflex XK_kra
+                              \ XK_kappa XK_Rcedilla XK_Itilde XK_Lcedilla
+                              \ XK_Emacron XK_Gcedilla XK_Tslash XK_rcedilla
+                              \ XK_itilde XK_lcedilla XK_emacron XK_gcedilla
+                              \ XK_tslash XK_ENG XK_eng XK_Amacron XK_Iogonek
+                              \ XK_Eabovedot XK_Imacron XK_Ncedilla XK_Omacron
+                              \ XK_Kcedilla XK_Uogonek XK_Utilde XK_Umacron
+                              \ XK_amacron XK_iogonek XK_eabovedot XK_imacron
+                              \ XK_ncedilla XK_omacron XK_kcedilla XK_uogonek
+                              \ XK_utilde XK_umacron XK_Babovedot XK_babovedot
+                              \ XK_Dabovedot XK_Wgrave XK_Wacute XK_dabovedot
+                              \ XK_Ygrave XK_Fabovedot XK_fabovedot
+                              \ XK_Mabovedot XK_mabovedot XK_Pabovedot
+                              \ XK_wgrave XK_pabovedot XK_wacute XK_Sabovedot
+                              \ XK_ygrave XK_Wdiaeresis XK_wdiaeresis
+                              \ XK_sabovedot XK_Wcircumflex XK_Tabovedot
+                              \ XK_Ycircumflex XK_wcircumflex
+                              \ XK_tabovedot XK_ycircumflex XK_OE XK_oe
+                              \ XK_Ydiaeresis XK_overline XK_kana_fullstop
+                              \ XK_kana_openingbracket XK_kana_closingbracket
+                              \ XK_kana_comma XK_kana_conjunctive
+                              \ XK_kana_middledot XK_kana_WO XK_kana_a
+                              \ XK_kana_i XK_kana_u XK_kana_e XK_kana_o
+                              \ XK_kana_ya XK_kana_yu XK_kana_yo
+                              \ XK_kana_tsu XK_kana_tu XK_prolongedsound
+                              \ XK_kana_A XK_kana_I XK_kana_U XK_kana_E
+                              \ XK_kana_O XK_kana_KA XK_kana_KI XK_kana_KU
+                              \ XK_kana_KE XK_kana_KO XK_kana_SA XK_kana_SHI
+                              \ XK_kana_SU XK_kana_SE XK_kana_SO XK_kana_TA
+                              \ XK_kana_CHI XK_kana_TI XK_kana_TSU
+                              \ XK_kana_TU XK_kana_TE XK_kana_TO XK_kana_NA
+                              \ XK_kana_NI XK_kana_NU XK_kana_NE XK_kana_NO
+                              \ XK_kana_HA XK_kana_HI XK_kana_FU XK_kana_HU
+                              \ XK_kana_HE XK_kana_HO XK_kana_MA XK_kana_MI
+                              \ XK_kana_MU XK_kana_ME XK_kana_MO XK_kana_YA
+                              \ XK_kana_YU XK_kana_YO XK_kana_RA XK_kana_RI
+                              \ XK_kana_RU XK_kana_RE XK_kana_RO XK_kana_WA
+                              \ XK_kana_N XK_voicedsound XK_semivoicedsound
+                              \ XK_kana_switch XK_Farsi_0 XK_Farsi_1
+                              \ XK_Farsi_2 XK_Farsi_3 XK_Farsi_4 XK_Farsi_5
+                              \ XK_Farsi_6 XK_Farsi_7 XK_Farsi_8 XK_Farsi_9
+                              \ XK_Arabic_percent XK_Arabic_superscript_alef
+                              \ XK_Arabic_tteh XK_Arabic_peh XK_Arabic_tcheh
+                              \ XK_Arabic_ddal XK_Arabic_rreh XK_Arabic_comma
+                              \ XK_Arabic_fullstop XK_Arabic_0 XK_Arabic_1
+                              \ XK_Arabic_2 XK_Arabic_3 XK_Arabic_4
+                              \ XK_Arabic_5 XK_Arabic_6 XK_Arabic_7
+                              \ XK_Arabic_8 XK_Arabic_9 XK_Arabic_semicolon
+                              \ XK_Arabic_question_mark XK_Arabic_hamza
+                              \ XK_Arabic_maddaonalef XK_Arabic_hamzaonalef
+                              \ XK_Arabic_hamzaonwaw XK_Arabic_hamzaunderalef
+                              \ XK_Arabic_hamzaonyeh XK_Arabic_alef
+                              \ XK_Arabic_beh XK_Arabic_tehmarbuta
+                              \ XK_Arabic_teh XK_Arabic_theh XK_Arabic_jeem
+                              \ XK_Arabic_hah XK_Arabic_khah XK_Arabic_dal
+                              \ XK_Arabic_thal XK_Arabic_ra XK_Arabic_zain
+                              \ XK_Arabic_seen XK_Arabic_sheen
+                              \ XK_Arabic_sad XK_Arabic_dad XK_Arabic_tah
+                              \ XK_Arabic_zah XK_Arabic_ain XK_Arabic_ghain
+                              \ XK_Arabic_tatweel XK_Arabic_feh XK_Arabic_qaf
+                              \ XK_Arabic_kaf XK_Arabic_lam XK_Arabic_meem
+                              \ XK_Arabic_noon XK_Arabic_ha XK_Arabic_heh
+                              \ XK_Arabic_waw XK_Arabic_alefmaksura
+                              \ XK_Arabic_yeh XK_Arabic_fathatan
+                              \ XK_Arabic_dammatan XK_Arabic_kasratan
+                              \ XK_Arabic_fatha XK_Arabic_damma
+                              \ XK_Arabic_kasra XK_Arabic_shadda
+                              \ XK_Arabic_sukun XK_Arabic_madda_above
+                              \ XK_Arabic_hamza_above XK_Arabic_hamza_below
+                              \ XK_Arabic_jeh XK_Arabic_veh XK_Arabic_keheh
+                              \ XK_Arabic_gaf XK_Arabic_noon_ghunna
+                              \ XK_Arabic_heh_doachashmee XK_Farsi_yeh
+                              \ XK_Arabic_yeh_baree XK_Arabic_heh_goal
+                              \ XK_Arabic_switch XK_Cyrillic_GHE_bar
+                              \ XK_Cyrillic_ghe_bar XK_Cyrillic_ZHE_descender
+                              \ XK_Cyrillic_zhe_descender
+                              \ XK_Cyrillic_KA_descender
+                              \ XK_Cyrillic_ka_descender
+                              \ XK_Cyrillic_KA_vertstroke
+                              \ XK_Cyrillic_ka_vertstroke
+                              \ XK_Cyrillic_EN_descender
+                              \ XK_Cyrillic_en_descender
+                              \ XK_Cyrillic_U_straight XK_Cyrillic_u_straight
+                              \ XK_Cyrillic_U_straight_bar
+                              \ XK_Cyrillic_u_straight_bar
+                              \ XK_Cyrillic_HA_descender
+                              \ XK_Cyrillic_ha_descender
+                              \ XK_Cyrillic_CHE_descender
+                              \ XK_Cyrillic_che_descender
+                              \ XK_Cyrillic_CHE_vertstroke
+                              \ XK_Cyrillic_che_vertstroke XK_Cyrillic_SHHA
+                              \ XK_Cyrillic_shha XK_Cyrillic_SCHWA
+                              \ XK_Cyrillic_schwa XK_Cyrillic_I_macron
+                              \ XK_Cyrillic_i_macron XK_Cyrillic_O_bar
+                              \ XK_Cyrillic_o_bar XK_Cyrillic_U_macron
+                              \ XK_Cyrillic_u_macron XK_Serbian_dje
+                              \ XK_Macedonia_gje XK_Cyrillic_io
+                              \ XK_Ukrainian_ie XK_Ukranian_je
+                              \ XK_Macedonia_dse XK_Ukrainian_i XK_Ukranian_i
+                              \ XK_Ukrainian_yi XK_Ukranian_yi XK_Cyrillic_je
+                              \ XK_Serbian_je XK_Cyrillic_lje XK_Serbian_lje
+                              \ XK_Cyrillic_nje XK_Serbian_nje XK_Serbian_tshe
+                              \ XK_Macedonia_kje XK_Ukrainian_ghe_with_upturn
+                              \ XK_Byelorussian_shortu XK_Cyrillic_dzhe
+                              \ XK_Serbian_dze XK_numerosign
+                              \ XK_Serbian_DJE XK_Macedonia_GJE
+                              \ XK_Cyrillic_IO XK_Ukrainian_IE XK_Ukranian_JE
+                              \ XK_Macedonia_DSE XK_Ukrainian_I XK_Ukranian_I
+                              \ XK_Ukrainian_YI XK_Ukranian_YI XK_Cyrillic_JE
+                              \ XK_Serbian_JE XK_Cyrillic_LJE XK_Serbian_LJE
+                              \ XK_Cyrillic_NJE XK_Serbian_NJE XK_Serbian_TSHE
+                              \ XK_Macedonia_KJE XK_Ukrainian_GHE_WITH_UPTURN
+                              \ XK_Byelorussian_SHORTU XK_Cyrillic_DZHE
+                              \ XK_Serbian_DZE XK_Cyrillic_yu
+                              \ XK_Cyrillic_a XK_Cyrillic_be XK_Cyrillic_tse
+                              \ XK_Cyrillic_de XK_Cyrillic_ie XK_Cyrillic_ef
+                              \ XK_Cyrillic_ghe XK_Cyrillic_ha XK_Cyrillic_i
+                              \ XK_Cyrillic_shorti XK_Cyrillic_ka
+                              \ XK_Cyrillic_el XK_Cyrillic_em XK_Cyrillic_en
+                              \ XK_Cyrillic_o XK_Cyrillic_pe XK_Cyrillic_ya
+                              \ XK_Cyrillic_er XK_Cyrillic_es XK_Cyrillic_te
+                              \ XK_Cyrillic_u XK_Cyrillic_zhe XK_Cyrillic_ve
+                              \ XK_Cyrillic_softsign XK_Cyrillic_yeru
+                              \ XK_Cyrillic_ze XK_Cyrillic_sha XK_Cyrillic_e
+                              \ XK_Cyrillic_shcha XK_Cyrillic_che
+                              \ XK_Cyrillic_hardsign XK_Cyrillic_YU
+                              \ XK_Cyrillic_A XK_Cyrillic_BE XK_Cyrillic_TSE
+                              \ XK_Cyrillic_DE XK_Cyrillic_IE XK_Cyrillic_EF
+                              \ XK_Cyrillic_GHE XK_Cyrillic_HA XK_Cyrillic_I
+                              \ XK_Cyrillic_SHORTI XK_Cyrillic_KA
+                              \ XK_Cyrillic_EL XK_Cyrillic_EM XK_Cyrillic_EN
+                              \ XK_Cyrillic_O XK_Cyrillic_PE XK_Cyrillic_YA
+                              \ XK_Cyrillic_ER XK_Cyrillic_ES XK_Cyrillic_TE
+                              \ XK_Cyrillic_U XK_Cyrillic_ZHE XK_Cyrillic_VE
+                              \ XK_Cyrillic_SOFTSIGN XK_Cyrillic_YERU
+                              \ XK_Cyrillic_ZE XK_Cyrillic_SHA XK_Cyrillic_E
+                              \ XK_Cyrillic_SHCHA XK_Cyrillic_CHE
+                              \ XK_Cyrillic_HARDSIGN XK_Greek_ALPHAaccent
+                              \ XK_Greek_EPSILONaccent XK_Greek_ETAaccent
+                              \ XK_Greek_IOTAaccent XK_Greek_IOTAdieresis
+                              \ XK_Greek_OMICRONaccent XK_Greek_UPSILONaccent
+                              \ XK_Greek_UPSILONdieresis
+                              \ XK_Greek_OMEGAaccent XK_Greek_accentdieresis
+                              \ XK_Greek_horizbar XK_Greek_alphaaccent
+                              \ XK_Greek_epsilonaccent XK_Greek_etaaccent
+                              \ XK_Greek_iotaaccent XK_Greek_iotadieresis
+                              \ XK_Greek_iotaaccentdieresis
+                              \ XK_Greek_omicronaccent XK_Greek_upsilonaccent
+                              \ XK_Greek_upsilondieresis
+                              \ XK_Greek_upsilonaccentdieresis
+                              \ XK_Greek_omegaaccent XK_Greek_ALPHA
+                              \ XK_Greek_BETA XK_Greek_GAMMA XK_Greek_DELTA
+                              \ XK_Greek_EPSILON XK_Greek_ZETA XK_Greek_ETA
+                              \ XK_Greek_THETA XK_Greek_IOTA XK_Greek_KAPPA
+                              \ XK_Greek_LAMDA XK_Greek_LAMBDA XK_Greek_MU
+                              \ XK_Greek_NU XK_Greek_XI XK_Greek_OMICRON
+                              \ XK_Greek_PI XK_Greek_RHO XK_Greek_SIGMA
+                              \ XK_Greek_TAU XK_Greek_UPSILON XK_Greek_PHI
+                              \ XK_Greek_CHI XK_Greek_PSI XK_Greek_OMEGA
+                              \ XK_Greek_alpha XK_Greek_beta XK_Greek_gamma
+                              \ XK_Greek_delta XK_Greek_epsilon XK_Greek_zeta
+                              \ XK_Greek_eta XK_Greek_theta XK_Greek_iota
+                              \ XK_Greek_kappa XK_Greek_lamda XK_Greek_lambda
+                              \ XK_Greek_mu XK_Greek_nu XK_Greek_xi
+                              \ XK_Greek_omicron XK_Greek_pi XK_Greek_rho
+                              \ XK_Greek_sigma XK_Greek_finalsmallsigma
+                              \ XK_Greek_tau XK_Greek_upsilon XK_Greek_phi
+                              \ XK_Greek_chi XK_Greek_psi XK_Greek_omega
+                              \ XK_Greek_switch XK_leftradical
+                              \ XK_topleftradical XK_horizconnector
+                              \ XK_topintegral XK_botintegral
+                              \ XK_vertconnector XK_topleftsqbracket
+                              \ XK_botleftsqbracket XK_toprightsqbracket
+                              \ XK_botrightsqbracket XK_topleftparens
+                              \ XK_botleftparens XK_toprightparens
+                              \ XK_botrightparens XK_leftmiddlecurlybrace
+                              \ XK_rightmiddlecurlybrace
+                              \ XK_topleftsummation XK_botleftsummation
+                              \ XK_topvertsummationconnector
+                              \ XK_botvertsummationconnector
+                              \ XK_toprightsummation XK_botrightsummation
+                              \ XK_rightmiddlesummation XK_lessthanequal
+                              \ XK_notequal XK_greaterthanequal XK_integral
+                              \ XK_therefore XK_variation XK_infinity
+                              \ XK_nabla XK_approximate XK_similarequal
+                              \ XK_ifonlyif XK_implies XK_identical XK_radical
+                              \ XK_includedin XK_includes XK_intersection
+                              \ XK_union XK_logicaland XK_logicalor
+                              \ XK_partialderivative XK_function XK_leftarrow
+                              \ XK_uparrow XK_rightarrow XK_downarrow XK_blank
+                              \ XK_soliddiamond XK_checkerboard XK_ht XK_ff
+                              \ XK_cr XK_lf XK_nl XK_vt XK_lowrightcorner
+                              \ XK_uprightcorner XK_upleftcorner
+                              \ XK_lowleftcorner XK_crossinglines
+                              \ XK_horizlinescan1 XK_horizlinescan3
+                              \ XK_horizlinescan5 XK_horizlinescan7
+                              \ XK_horizlinescan9 XK_leftt XK_rightt XK_bott
+                              \ XK_topt XK_vertbar XK_emspace XK_enspace
+                              \ XK_em3space XK_em4space XK_digitspace
+                              \ XK_punctspace XK_thinspace XK_hairspace
+                              \ XK_emdash XK_endash XK_signifblank XK_ellipsis
+                              \ XK_doubbaselinedot XK_onethird XK_twothirds
+                              \ XK_onefifth XK_twofifths XK_threefifths
+                              \ XK_fourfifths XK_onesixth XK_fivesixths
+                              \ XK_careof XK_figdash XK_leftanglebracket
+                              \ XK_decimalpoint XK_rightanglebracket
+                              \ XK_marker XK_oneeighth XK_threeeighths
+                              \ XK_fiveeighths XK_seveneighths XK_trademark
+                              \ XK_signaturemark XK_trademarkincircle
+                              \ XK_leftopentriangle XK_rightopentriangle
+                              \ XK_emopencircle XK_emopenrectangle
+                              \ XK_leftsinglequotemark XK_rightsinglequotemark
+                              \ XK_leftdoublequotemark XK_rightdoublequotemark
+                              \ XK_prescription XK_minutes XK_seconds
+                              \ XK_latincross XK_hexagram XK_filledrectbullet
+                              \ XK_filledlefttribullet XK_filledrighttribullet
+                              \ XK_emfilledcircle XK_emfilledrect
+                              \ XK_enopencircbullet XK_enopensquarebullet
+                              \ XK_openrectbullet XK_opentribulletup
+                              \ XK_opentribulletdown XK_openstar
+                              \ XK_enfilledcircbullet XK_enfilledsqbullet
+                              \ XK_filledtribulletup XK_filledtribulletdown
+                              \ XK_leftpointer XK_rightpointer XK_club
+                              \ XK_diamond XK_heart XK_maltesecross
+                              \ XK_dagger XK_doubledagger XK_checkmark
+                              \ XK_ballotcross XK_musicalsharp XK_musicalflat
+                              \ XK_malesymbol XK_femalesymbol XK_telephone
+                              \ XK_telephonerecorder XK_phonographcopyright
+                              \ XK_caret XK_singlelowquotemark
+                              \ XK_doublelowquotemark XK_cursor
+                              \ XK_leftcaret XK_rightcaret XK_downcaret
+                              \ XK_upcaret XK_overbar XK_downtack XK_upshoe
+                              \ XK_downstile XK_underbar XK_jot XK_quad
+                              \ XK_uptack XK_circle XK_upstile XK_downshoe
+                              \ XK_rightshoe XK_leftshoe XK_lefttack
+                              \ XK_righttack XK_hebrew_doublelowline
+                              \ XK_hebrew_aleph XK_hebrew_bet XK_hebrew_beth
+                              \ XK_hebrew_gimel XK_hebrew_gimmel
+                              \ XK_hebrew_dalet XK_hebrew_daleth
+                              \ XK_hebrew_he XK_hebrew_waw XK_hebrew_zain
+                              \ XK_hebrew_zayin XK_hebrew_chet XK_hebrew_het
+                              \ XK_hebrew_tet XK_hebrew_teth XK_hebrew_yod
+                              \ XK_hebrew_finalkaph XK_hebrew_kaph
+                              \ XK_hebrew_lamed XK_hebrew_finalmem
+                              \ XK_hebrew_mem XK_hebrew_finalnun XK_hebrew_nun
+                              \ XK_hebrew_samech XK_hebrew_samekh
+                              \ XK_hebrew_ayin XK_hebrew_finalpe XK_hebrew_pe
+                              \ XK_hebrew_finalzade XK_hebrew_finalzadi
+                              \ XK_hebrew_zade XK_hebrew_zadi XK_hebrew_qoph
+                              \ XK_hebrew_kuf XK_hebrew_resh XK_hebrew_shin
+                              \ XK_hebrew_taw XK_hebrew_taf XK_Hebrew_switch
+                              \ XK_Thai_kokai XK_Thai_khokhai XK_Thai_khokhuat
+                              \ XK_Thai_khokhwai XK_Thai_khokhon
+                              \ XK_Thai_khorakhang XK_Thai_ngongu
+                              \ XK_Thai_chochan XK_Thai_choching
+                              \ XK_Thai_chochang XK_Thai_soso XK_Thai_chochoe
+                              \ XK_Thai_yoying XK_Thai_dochada XK_Thai_topatak
+                              \ XK_Thai_thothan XK_Thai_thonangmontho
+                              \ XK_Thai_thophuthao XK_Thai_nonen
+                              \ XK_Thai_dodek XK_Thai_totao XK_Thai_thothung
+                              \ XK_Thai_thothahan XK_Thai_thothong
+                              \ XK_Thai_nonu XK_Thai_bobaimai XK_Thai_popla
+                              \ XK_Thai_phophung XK_Thai_fofa XK_Thai_phophan
+                              \ XK_Thai_fofan XK_Thai_phosamphao XK_Thai_moma
+                              \ XK_Thai_yoyak XK_Thai_rorua XK_Thai_ru
+                              \ XK_Thai_loling XK_Thai_lu XK_Thai_wowaen
+                              \ XK_Thai_sosala XK_Thai_sorusi XK_Thai_sosua
+                              \ XK_Thai_hohip XK_Thai_lochula XK_Thai_oang
+                              \ XK_Thai_honokhuk XK_Thai_paiyannoi
+                              \ XK_Thai_saraa XK_Thai_maihanakat
+                              \ XK_Thai_saraaa XK_Thai_saraam XK_Thai_sarai
+                              \ XK_Thai_saraii XK_Thai_saraue XK_Thai_sarauee
+                              \ XK_Thai_sarau XK_Thai_sarauu XK_Thai_phinthu
+                              \ XK_Thai_maihanakat_maitho XK_Thai_baht
+                              \ XK_Thai_sarae XK_Thai_saraae XK_Thai_sarao
+                              \ XK_Thai_saraaimaimuan XK_Thai_saraaimaimalai
+                              \ XK_Thai_lakkhangyao XK_Thai_maiyamok
+                              \ XK_Thai_maitaikhu XK_Thai_maiek XK_Thai_maitho
+                              \ XK_Thai_maitri XK_Thai_maichattawa
+                              \ XK_Thai_thanthakhat XK_Thai_nikhahit
+                              \ XK_Thai_leksun XK_Thai_leknung XK_Thai_leksong
+                              \ XK_Thai_leksam XK_Thai_leksi XK_Thai_lekha
+                              \ XK_Thai_lekhok XK_Thai_lekchet XK_Thai_lekpaet
+                              \ XK_Thai_lekkao XK_Hangul XK_Hangul_Start
+                              \ XK_Hangul_End XK_Hangul_Hanja XK_Hangul_Jamo
+                              \ XK_Hangul_Romaja XK_Hangul_Codeinput
+                              \ XK_Hangul_Jeonja XK_Hangul_Banja
+                              \ XK_Hangul_PreHanja XK_Hangul_PostHanja
+                              \ XK_Hangul_SingleCandidate
+                              \ XK_Hangul_MultipleCandidate
+                              \ XK_Hangul_PreviousCandidate XK_Hangul_Special
+                              \ XK_Hangul_switch XK_Hangul_Kiyeog
+                              \ XK_Hangul_SsangKiyeog XK_Hangul_KiyeogSios
+                              \ XK_Hangul_Nieun XK_Hangul_NieunJieuj
+                              \ XK_Hangul_NieunHieuh XK_Hangul_Dikeud
+                              \ XK_Hangul_SsangDikeud XK_Hangul_Rieul
+                              \ XK_Hangul_RieulKiyeog XK_Hangul_RieulMieum
+                              \ XK_Hangul_RieulPieub XK_Hangul_RieulSios
+                              \ XK_Hangul_RieulTieut XK_Hangul_RieulPhieuf
+                              \ XK_Hangul_RieulHieuh XK_Hangul_Mieum
+                              \ XK_Hangul_Pieub XK_Hangul_SsangPieub
+                              \ XK_Hangul_PieubSios XK_Hangul_Sios
+                              \ XK_Hangul_SsangSios XK_Hangul_Ieung
+                              \ XK_Hangul_Jieuj XK_Hangul_SsangJieuj
+                              \ XK_Hangul_Cieuc XK_Hangul_Khieuq
+                              \ XK_Hangul_Tieut XK_Hangul_Phieuf
+                              \ XK_Hangul_Hieuh XK_Hangul_A XK_Hangul_AE
+                              \ XK_Hangul_YA XK_Hangul_YAE XK_Hangul_EO
+                              \ XK_Hangul_E XK_Hangul_YEO XK_Hangul_YE
+                              \ XK_Hangul_O XK_Hangul_WA XK_Hangul_WAE
+                              \ XK_Hangul_OE XK_Hangul_YO XK_Hangul_U
+                              \ XK_Hangul_WEO XK_Hangul_WE XK_Hangul_WI
+                              \ XK_Hangul_YU XK_Hangul_EU XK_Hangul_YI
+                              \ XK_Hangul_I XK_Hangul_J_Kiyeog
+                              \ XK_Hangul_J_SsangKiyeog XK_Hangul_J_KiyeogSios
+                              \ XK_Hangul_J_Nieun XK_Hangul_J_NieunJieuj
+                              \ XK_Hangul_J_NieunHieuh XK_Hangul_J_Dikeud
+                              \ XK_Hangul_J_Rieul XK_Hangul_J_RieulKiyeog
+                              \ XK_Hangul_J_RieulMieum XK_Hangul_J_RieulPieub
+                              \ XK_Hangul_J_RieulSios XK_Hangul_J_RieulTieut
+                              \ XK_Hangul_J_RieulPhieuf XK_Hangul_J_RieulHieuh
+                              \ XK_Hangul_J_Mieum XK_Hangul_J_Pieub
+                              \ XK_Hangul_J_PieubSios XK_Hangul_J_Sios
+                              \ XK_Hangul_J_SsangSios XK_Hangul_J_Ieung
+                              \ XK_Hangul_J_Jieuj XK_Hangul_J_Cieuc
+                              \ XK_Hangul_J_Khieuq XK_Hangul_J_Tieut
+                              \ XK_Hangul_J_Phieuf XK_Hangul_J_Hieuh
+                              \ XK_Hangul_RieulYeorinHieuh
+                              \ XK_Hangul_SunkyeongeumMieum
+                              \ XK_Hangul_SunkyeongeumPieub XK_Hangul_PanSios
+                              \ XK_Hangul_KkogjiDalrinIeung
+                              \ XK_Hangul_SunkyeongeumPhieuf
+                              \ XK_Hangul_YeorinHieuh XK_Hangul_AraeA
+                              \ XK_Hangul_AraeAE XK_Hangul_J_PanSios
+                              \ XK_Hangul_J_KkogjiDalrinIeung
+                              \ XK_Hangul_J_YeorinHieuh XK_Korean_Won
+                              \ XK_Armenian_eternity XK_Armenian_ligature_ew
+                              \ XK_Armenian_full_stop XK_Armenian_verjaket
+                              \ XK_Armenian_parenright XK_Armenian_parenleft
+                              \ XK_Armenian_guillemotright
+                              \ XK_Armenian_guillemotleft XK_Armenian_em_dash
+                              \ XK_Armenian_dot XK_Armenian_mijaket
+                              \ XK_Armenian_separation_mark XK_Armenian_but
+                              \ XK_Armenian_comma XK_Armenian_en_dash
+                              \ XK_Armenian_hyphen XK_Armenian_yentamna
+                              \ XK_Armenian_ellipsis XK_Armenian_exclam
+                              \ XK_Armenian_amanak XK_Armenian_accent
+                              \ XK_Armenian_shesht XK_Armenian_question
+                              \ XK_Armenian_paruyk XK_Armenian_AYB
+                              \ XK_Armenian_ayb XK_Armenian_BEN
+                              \ XK_Armenian_ben XK_Armenian_GIM
+                              \ XK_Armenian_gim XK_Armenian_DA XK_Armenian_da
+                              \ XK_Armenian_YECH XK_Armenian_yech
+                              \ XK_Armenian_ZA XK_Armenian_za XK_Armenian_E
+                              \ XK_Armenian_e XK_Armenian_AT XK_Armenian_at
+                              \ XK_Armenian_TO XK_Armenian_to
+                              \ XK_Armenian_ZHE XK_Armenian_zhe
+                              \ XK_Armenian_INI XK_Armenian_ini
+                              \ XK_Armenian_LYUN XK_Armenian_lyun
+                              \ XK_Armenian_KHE XK_Armenian_khe
+                              \ XK_Armenian_TSA XK_Armenian_tsa
+                              \ XK_Armenian_KEN XK_Armenian_ken XK_Armenian_HO
+                              \ XK_Armenian_ho XK_Armenian_DZA XK_Armenian_dza
+                              \ XK_Armenian_GHAT XK_Armenian_ghat
+                              \ XK_Armenian_TCHE XK_Armenian_tche
+                              \ XK_Armenian_MEN XK_Armenian_men XK_Armenian_HI
+                              \ XK_Armenian_hi XK_Armenian_NU XK_Armenian_nu
+                              \ XK_Armenian_SHA XK_Armenian_sha XK_Armenian_VO
+                              \ XK_Armenian_vo XK_Armenian_CHA XK_Armenian_cha
+                              \ XK_Armenian_PE XK_Armenian_pe XK_Armenian_JE
+                              \ XK_Armenian_je XK_Armenian_RA XK_Armenian_ra
+                              \ XK_Armenian_SE XK_Armenian_se XK_Armenian_VEV
+                              \ XK_Armenian_vev XK_Armenian_TYUN
+                              \ XK_Armenian_tyun XK_Armenian_RE
+                              \ XK_Armenian_re XK_Armenian_TSO
+                              \ XK_Armenian_tso XK_Armenian_VYUN
+                              \ XK_Armenian_vyun XK_Armenian_PYUR
+                              \ XK_Armenian_pyur XK_Armenian_KE XK_Armenian_ke
+                              \ XK_Armenian_O XK_Armenian_o XK_Armenian_FE
+                              \ XK_Armenian_fe XK_Armenian_apostrophe
+                              \ XK_Armenian_section_sign XK_Georgian_an
+                              \ XK_Georgian_ban XK_Georgian_gan
+                              \ XK_Georgian_don XK_Georgian_en XK_Georgian_vin
+                              \ XK_Georgian_zen XK_Georgian_tan
+                              \ XK_Georgian_in XK_Georgian_kan XK_Georgian_las
+                              \ XK_Georgian_man XK_Georgian_nar XK_Georgian_on
+                              \ XK_Georgian_par XK_Georgian_zhar
+                              \ XK_Georgian_rae XK_Georgian_san
+                              \ XK_Georgian_tar XK_Georgian_un
+                              \ XK_Georgian_phar XK_Georgian_khar
+                              \ XK_Georgian_ghan XK_Georgian_qar
+                              \ XK_Georgian_shin XK_Georgian_chin
+                              \ XK_Georgian_can XK_Georgian_jil
+                              \ XK_Georgian_cil XK_Georgian_char
+                              \ XK_Georgian_xan XK_Georgian_jhan
+                              \ XK_Georgian_hae XK_Georgian_he XK_Georgian_hie
+                              \ XK_Georgian_we XK_Georgian_har XK_Georgian_hoe
+                              \ XK_Georgian_fi XK_Ccedillaabovedot
+                              \ XK_Xabovedot XK_Qabovedot XK_IE XK_UO
+                              \ XK_Zstroke XK_ccedillaabovedot XK_xabovedot
+                              \ XK_qabovedot XK_ie XK_uo XK_zstroke XK_SCHWA
+                              \ XK_schwa XK_Lbelowdot XK_Lstrokebelowdot
+                              \ XK_lbelowdot XK_lstrokebelowdot XK_Gtilde
+                              \ XK_gtilde XK_Abelowdot XK_abelowdot
+                              \ XK_Ahook XK_ahook XK_Acircumflexacute
+                              \ XK_acircumflexacute XK_Acircumflexgrave
+                              \ XK_acircumflexgrave XK_Acircumflexhook
+                              \ XK_acircumflexhook XK_Acircumflextilde
+                              \ XK_acircumflextilde XK_Acircumflexbelowdot
+                              \ XK_acircumflexbelowdot XK_Abreveacute
+                              \ XK_abreveacute XK_Abrevegrave XK_abrevegrave
+                              \ XK_Abrevehook XK_abrevehook XK_Abrevetilde
+                              \ XK_abrevetilde XK_Abrevebelowdot
+                              \ XK_abrevebelowdot XK_Ebelowdot XK_ebelowdot
+                              \ XK_Ehook XK_ehook XK_Etilde XK_etilde
+                              \ XK_Ecircumflexacute XK_ecircumflexacute
+                              \ XK_Ecircumflexgrave XK_ecircumflexgrave
+                              \ XK_Ecircumflexhook XK_ecircumflexhook
+                              \ XK_Ecircumflextilde XK_ecircumflextilde
+                              \ XK_Ecircumflexbelowdot XK_ecircumflexbelowdot
+                              \ XK_Ihook XK_ihook XK_Ibelowdot XK_ibelowdot
+                              \ XK_Obelowdot XK_obelowdot XK_Ohook XK_ohook
+                              \ XK_Ocircumflexacute XK_ocircumflexacute
+                              \ XK_Ocircumflexgrave XK_ocircumflexgrave
+                              \ XK_Ocircumflexhook XK_ocircumflexhook
+                              \ XK_Ocircumflextilde XK_ocircumflextilde
+                              \ XK_Ocircumflexbelowdot XK_ocircumflexbelowdot
+                              \ XK_Ohornacute XK_ohornacute XK_Ohorngrave
+                              \ XK_ohorngrave XK_Ohornhook XK_ohornhook
+                              \ XK_Ohorntilde XK_ohorntilde XK_Ohornbelowdot
+                              \ XK_ohornbelowdot XK_Ubelowdot XK_ubelowdot
+                              \ XK_Uhook XK_uhook XK_Uhornacute XK_uhornacute
+                              \ XK_Uhorngrave XK_uhorngrave XK_Uhornhook
+                              \ XK_uhornhook XK_Uhorntilde XK_uhorntilde
+                              \ XK_Uhornbelowdot XK_uhornbelowdot XK_Ybelowdot
+                              \ XK_ybelowdot XK_Yhook XK_yhook XK_Ytilde
+                              \ XK_ytilde XK_Ohorn XK_ohorn XK_Uhorn XK_uhorn
+                              \ XK_combining_tilde XK_combining_grave
+                              \ XK_combining_acute XK_combining_hook
+                              \ XK_combining_belowdot XK_EcuSign XK_ColonSign
+                              \ XK_CruzeiroSign XK_FFrancSign XK_LiraSign
+                              \ XK_MillSign XK_NairaSign XK_PesetaSign
+                              \ XK_RupeeSign XK_WonSign XK_NewSheqelSign
+                              \ XK_DongSign XK_EuroSign
+
+" #include <X11/Sunkeysym.h>
+syn keyword xmodmapKeySym     SunXK_Sys_Req SunXK_Print_Screen SunXK_Compose
+                              \ SunXK_AltGraph SunXK_PageUp SunXK_PageDown
+                              \ SunXK_Undo SunXK_Again SunXK_Find SunXK_Stop
+                              \ SunXK_Props SunXK_Front SunXK_Copy SunXK_Open
+                              \ SunXK_Paste SunXK_Cut SunXK_PowerSwitch
+                              \ SunXK_AudioLowerVolume SunXK_AudioMute
+                              \ SunXK_AudioRaiseVolume SunXK_VideoDegauss
+                              \ SunXK_VideoLowerBrightness
+                              \ SunXK_VideoRaiseBrightness
+                              \ SunXK_PowerSwitchShift
+
+" #include <X11/XF86keysym.h>
+syn keyword xmodmapKeySym     XF86XK_ModeLock XF86XK_Standby
+                              \ XF86XK_AudioLowerVolume XF86XK_AudioMute
+                              \ XF86XK_AudioRaiseVolume XF86XK_AudioPlay
+                              \ XF86XK_AudioStop XF86XK_AudioPrev
+                              \ XF86XK_AudioNext XF86XK_HomePage
+                              \ XF86XK_Mail XF86XK_Start XF86XK_Search
+                              \ XF86XK_AudioRecord XF86XK_Calculator
+                              \ XF86XK_Memo XF86XK_ToDoList XF86XK_Calendar
+                              \ XF86XK_PowerDown XF86XK_ContrastAdjust
+                              \ XF86XK_RockerUp XF86XK_RockerDown
+                              \ XF86XK_RockerEnter XF86XK_Back XF86XK_Forward
+                              \ XF86XK_Stop XF86XK_Refresh XF86XK_PowerOff
+                              \ XF86XK_WakeUp XF86XK_Eject XF86XK_ScreenSaver
+                              \ XF86XK_WWW XF86XK_Sleep XF86XK_Favorites
+                              \ XF86XK_AudioPause XF86XK_AudioMedia
+                              \ XF86XK_MyComputer XF86XK_VendorHome
+                              \ XF86XK_LightBulb XF86XK_Shop XF86XK_History
+                              \ XF86XK_OpenURL XF86XK_AddFavorite
+                              \ XF86XK_HotLinks XF86XK_BrightnessAdjust
+                              \ XF86XK_Finance XF86XK_Community
+                              \ XF86XK_AudioRewind XF86XK_XF86BackForward
+                              \ XF86XK_Launch0 XF86XK_Launch1 XF86XK_Launch2
+                              \ XF86XK_Launch3 XF86XK_Launch4 XF86XK_Launch5
+                              \ XF86XK_Launch6 XF86XK_Launch7 XF86XK_Launch8
+                              \ XF86XK_Launch9 XF86XK_LaunchA XF86XK_LaunchB
+                              \ XF86XK_LaunchC XF86XK_LaunchD XF86XK_LaunchE
+                              \ XF86XK_LaunchF XF86XK_ApplicationLeft
+                              \ XF86XK_ApplicationRight XF86XK_Book
+                              \ XF86XK_CD XF86XK_Calculater XF86XK_Clear
+                              \ XF86XK_Close XF86XK_Copy XF86XK_Cut
+                              \ XF86XK_Display XF86XK_DOS XF86XK_Documents
+                              \ XF86XK_Excel XF86XK_Explorer XF86XK_Game
+                              \ XF86XK_Go XF86XK_iTouch XF86XK_LogOff
+                              \ XF86XK_Market XF86XK_Meeting XF86XK_MenuKB
+                              \ XF86XK_MenuPB XF86XK_MySites XF86XK_New
+                              \ XF86XK_News XF86XK_OfficeHome XF86XK_Open
+                              \ XF86XK_Option XF86XK_Paste XF86XK_Phone
+                              \ XF86XK_Q XF86XK_Reply XF86XK_Reload
+                              \ XF86XK_RotateWindows XF86XK_RotationPB
+                              \ XF86XK_RotationKB XF86XK_Save XF86XK_ScrollUp
+                              \ XF86XK_ScrollDown XF86XK_ScrollClick
+                              \ XF86XK_Send XF86XK_Spell XF86XK_SplitScreen
+                              \ XF86XK_Support XF86XK_TaskPane XF86XK_Terminal
+                              \ XF86XK_Tools XF86XK_Travel XF86XK_UserPB
+                              \ XF86XK_User1KB XF86XK_User2KB XF86XK_Video
+                              \ XF86XK_WheelButton XF86XK_Word XF86XK_Xfer
+                              \ XF86XK_ZoomIn XF86XK_ZoomOut XF86XK_Away
+                              \ XF86XK_Messenger XF86XK_WebCam
+                              \ XF86XK_MailForward XF86XK_Pictures
+                              \ XF86XK_Music XF86XK_Switch_VT_1
+                              \ XF86XK_Switch_VT_2 XF86XK_Switch_VT_3
+                              \ XF86XK_Switch_VT_4 XF86XK_Switch_VT_5
+                              \ XF86XK_Switch_VT_6 XF86XK_Switch_VT_7
+                              \ XF86XK_Switch_VT_8 XF86XK_Switch_VT_9
+                              \ XF86XK_Switch_VT_10 XF86XK_Switch_VT_11
+                              \ XF86XK_Switch_VT_12 XF86XK_Ungrab
+                              \ XF86XK_ClearGrab XF86XK_Next_VMode
+                              \ XF86XK_Prev_VMode
+
+syn keyword xmodmapKeyword    keycode keysym clear add remove pointer
+
+hi def link xmodmapComment    Comment
+hi def link xmodmapTodo       Todo
+hi def link xmodmapInt        Number
+hi def link xmodmapHex        Number
+hi def link xmodmapOctal      Number
+hi def link xmodmapOctalError Error
+hi def link xmodmapKeySym     Constant
+hi def link xmodmapKeyword    Keyword
+
+let b:current_syntax = "xmodmap"
+
+let &cpo = s:cpo_save
+unlet s:cpo_save
--- /dev/null
+++ b/lib/vimfiles/syntax/xpm.vim
@@ -1,0 +1,144 @@
+" Vim syntax file
+" Language:	X Pixmap
+" Maintainer:	Ronald Schild <rs@scutum.de>
+" Last Change:	2001 May 09
+" Version:	5.4n.1
+
+" For version 5.x: Clear all syntax items
+" For version 6.x: Quit when a syntax file was already loaded
+if version < 600
+  syntax clear
+elseif exists("b:current_syntax")
+  finish
+endif
+
+syn keyword xpmType		char
+syn keyword xpmStorageClass	static
+syn keyword xpmTodo		TODO FIXME XXX  contained
+syn region  xpmComment		start="/\*"  end="\*/"  contains=xpmTodo
+syn region  xpmPixelString	start=+"+  skip=+\\\\\|\\"+  end=+"+  contains=@xpmColors
+
+if has("gui_running")
+
+let color  = ""
+let chars  = ""
+let colors = 0
+let cpp    = 0
+let n      = 0
+let i      = 1
+
+while i <= line("$")		" scanning all lines
+
+   let s = matchstr(getline(i), '".\{-1,}"')
+   if s != ""			" does line contain a string?
+
+      if n == 0			" first string is the Values string
+
+	 " get the 3rd value: colors = number of colors
+	 let colors = substitute(s, '"\s*\d\+\s\+\d\+\s\+\(\d\+\).*"', '\1', '')
+	 " get the 4th value: cpp = number of character per pixel
+	 let cpp = substitute(s, '"\s*\d\+\s\+\d\+\s\+\d\+\s\+\(\d\+\).*"', '\1', '')
+
+	 " highlight the Values string as normal string (no pixel string)
+	 exe 'syn match xpmValues /'.s.'/'
+	 hi link xpmValues String
+
+	 let n = 1		" n = color index
+
+      elseif n <= colors	" string is a color specification
+
+	 " get chars = <cpp> length string representing the pixels
+	 " (first incl. the following whitespace)
+	 let chars = substitute(s, '"\(.\{'.cpp.'}\s\).*"', '\1', '')
+
+	 " now get color, first try 'c' key if any (color visual)
+	 let color = substitute(s, '".*\sc\s\+\(.\{-}\)\s*\(\(g4\=\|[ms]\)\s.*\)*\s*"', '\1', '')
+	 if color == s
+	    " no 'c' key, try 'g' key (grayscale with more than 4 levels)
+	    let color = substitute(s, '".*\sg\s\+\(.\{-}\)\s*\(\(g4\|[ms]\)\s.*\)*\s*"', '\1', '')
+	    if color == s
+	       " next try: 'g4' key (4-level grayscale)
+	       let color = substitute(s, '".*\sg4\s\+\(.\{-}\)\s*\([ms]\s.*\)*\s*"', '\1', '')
+	       if color == s
+		  " finally try 'm' key (mono visual)
+		  let color = substitute(s, '".*\sm\s\+\(.\{-}\)\s*\(s\s.*\)*\s*"', '\1', '')
+		  if color == s
+		     let color = ""
+		  endif
+	       endif
+	    endif
+	 endif
+
+	 " Vim cannot handle RGB codes with more than 6 hex digits
+	 if color =~ '#\x\{10,}$'
+	    let color = substitute(color, '\(\x\x\)\x\x', '\1', 'g')
+	 elseif color =~ '#\x\{7,}$'
+	    let color = substitute(color, '\(\x\x\)\x', '\1', 'g')
+	 " nor with 3 digits
+	 elseif color =~ '#\x\{3}$'
+	    let color = substitute(color, '\(\x\)\(\x\)\(\x\)', '0\10\20\3', '')
+	 endif
+
+	 " escape meta characters in patterns
+	 let s = escape(s, '/\*^$.~[]')
+	 let chars = escape(chars, '/\*^$.~[]')
+
+	 " now create syntax items
+	 " highlight the color string as normal string (no pixel string)
+	 exe 'syn match xpmCol'.n.'Def /'.s.'/ contains=xpmCol'.n.'inDef'
+	 exe 'hi link xpmCol'.n.'Def String'
+
+	 " but highlight the first whitespace after chars in its color
+	 exe 'syn match xpmCol'.n.'inDef /"'.chars.'/hs=s+'.(cpp+1).' contained'
+	 exe 'hi link xpmCol'.n.'inDef xpmColor'.n
+
+	 " remove the following whitespace from chars
+	 let chars = substitute(chars, '.$', '', '')
+
+	 " and create the syntax item contained in the pixel strings
+	 exe 'syn match xpmColor'.n.' /'.chars.'/ contained'
+	 exe 'syn cluster xpmColors add=xpmColor'.n
+
+	 " if no color or color = "None" show background
+	 if color == ""  ||  substitute(color, '.*', '\L&', '') == 'none'
+	    exe 'hi xpmColor'.n.' guifg=bg'
+	    exe 'hi xpmColor'.n.' guibg=NONE'
+	 else
+	    exe 'hi xpmColor'.n." guifg='".color."'"
+	    exe 'hi xpmColor'.n." guibg='".color."'"
+	 endif
+	 let n = n + 1
+      else
+	 break		" no more color string
+      endif
+   endif
+   let i = i + 1
+endwhile
+
+unlet color chars colors cpp n i s
+
+endif		" has("gui_running")
+
+" Define the default highlighting.
+" For version 5.7 and earlier: only when not done already
+" For version 5.8 and later: only when an item doesn't have highlighting yet
+if version >= 508 || !exists("did_xpm_syntax_inits")
+  if version < 508
+    let did_xpm_syntax_inits = 1
+    command -nargs=+ HiLink hi link <args>
+  else
+    command -nargs=+ HiLink hi def link <args>
+  endif
+
+  HiLink xpmType		Type
+  HiLink xpmStorageClass	StorageClass
+  HiLink xpmTodo		Todo
+  HiLink xpmComment		Comment
+  HiLink xpmPixelString	String
+
+  delcommand HiLink
+endif
+
+let b:current_syntax = "xpm"
+
+" vim: ts=8:sw=3:noet:
--- /dev/null
+++ b/lib/vimfiles/syntax/xpm2.vim
@@ -1,0 +1,156 @@
+" Vim syntax file
+" Language:	X Pixmap v2
+" Maintainer:	Steve Wall (hitched97@velnet.com)
+" Last Change:	2001 Apr 25
+" Version:	5.8
+"
+" Made from xpm.vim by Ronald Schild <rs@scutum.de>
+
+" For version 5.x: Clear all syntax items
+" For version 6.x: Quit when a syntax file was already loaded
+if version < 600
+  syntax clear
+elseif exists("b:current_syntax")
+  finish
+endif
+
+syn region  xpm2PixelString	start="^"  end="$"  contains=@xpm2Colors
+syn keyword xpm2Todo		TODO FIXME XXX  contained
+syn match   xpm2Comment		"\!.*$"  contains=xpm2Todo
+
+
+if version < 508
+  command -nargs=+ HiLink hi link <args>
+  command -nargs=+ Hi hi <args>
+else
+  command -nargs=+ HiLink hi def link <args>
+  command -nargs=+ Hi hi def <args>
+endif
+
+if has("gui_running")
+
+  let color  = ""
+  let chars  = ""
+  let colors = 0
+  let cpp    = 0
+  let n      = 0
+  let i      = 1
+
+  while i <= line("$")		" scanning all lines
+
+    let s = getline(i)
+    if match(s,"\!.*$") != -1
+      let s = matchstr(s, "^[^\!]*")
+    endif
+    if s != ""			" does line contain a string?
+
+      if n == 0			" first string is the Values string
+
+	" get the 3rd value: colors = number of colors
+	let colors = substitute(s, '\s*\d\+\s\+\d\+\s\+\(\d\+\).*', '\1', '')
+	" get the 4th value: cpp = number of character per pixel
+	let cpp = substitute(s, '\s*\d\+\s\+\d\+\s\+\d\+\s\+\(\d\+\).*', '\1', '')
+
+	" highlight the Values string as normal string (no pixel string)
+	exe 'syn match xpm2Values /'.s.'/'
+	HiLink xpm2Values Statement
+
+	let n = 1			" n = color index
+
+      elseif n <= colors		" string is a color specification
+
+	" get chars = <cpp> length string representing the pixels
+	" (first incl. the following whitespace)
+	let chars = substitute(s, '\(.\{'.cpp.'}\s\+\).*', '\1', '')
+
+	" now get color, first try 'c' key if any (color visual)
+	let color = substitute(s, '.*\sc\s\+\(.\{-}\)\s*\(\(g4\=\|[ms]\)\s.*\)*\s*', '\1', '')
+	if color == s
+	  " no 'c' key, try 'g' key (grayscale with more than 4 levels)
+	  let color = substitute(s, '.*\sg\s\+\(.\{-}\)\s*\(\(g4\|[ms]\)\s.*\)*\s*', '\1', '')
+	  if color == s
+	    " next try: 'g4' key (4-level grayscale)
+	    let color = substitute(s, '.*\sg4\s\+\(.\{-}\)\s*\([ms]\s.*\)*\s*', '\1', '')
+	    if color == s
+	      " finally try 'm' key (mono visual)
+	      let color = substitute(s, '.*\sm\s\+\(.\{-}\)\s*\(s\s.*\)*\s*', '\1', '')
+	      if color == s
+		let color = ""
+	      endif
+	    endif
+	  endif
+	endif
+
+	" Vim cannot handle RGB codes with more than 6 hex digits
+	if color =~ '#\x\{10,}$'
+	  let color = substitute(color, '\(\x\x\)\x\x', '\1', 'g')
+	elseif color =~ '#\x\{7,}$'
+	  let color = substitute(color, '\(\x\x\)\x', '\1', 'g')
+	" nor with 3 digits
+	elseif color =~ '#\x\{3}$'
+	  let color = substitute(color, '\(\x\)\(\x\)\(\x\)', '0\10\20\3', '')
+	endif
+
+	" escape meta characters in patterns
+	let s = escape(s, '/\*^$.~[]')
+	let chars = escape(chars, '/\*^$.~[]')
+
+	" change whitespace to "\s\+"
+	let s = substitute(s, "[ \t][ \t]*", "\\\\s\\\\+", "g")
+	let chars = substitute(chars, "[ \t][ \t]*", "\\\\s\\\\+", "g")
+
+	" now create syntax items
+	" highlight the color string as normal string (no pixel string)
+	exe 'syn match xpm2Col'.n.'Def /'.s.'/ contains=xpm2Col'.n.'inDef'
+	exe 'HiLink xpm2Col'.n.'Def Constant'
+
+	" but highlight the first whitespace after chars in its color
+	exe 'syn match xpm2Col'.n.'inDef /^'.chars.'/hs=s+'.(cpp).' contained'
+	exe 'HiLink xpm2Col'.n.'inDef xpm2Color'.n
+
+	" remove the following whitespace from chars
+	let chars = substitute(chars, '\\s\\+$', '', '')
+
+	" and create the syntax item contained in the pixel strings
+	exe 'syn match xpm2Color'.n.' /'.chars.'/ contained'
+	exe 'syn cluster xpm2Colors add=xpm2Color'.n
+
+	" if no color or color = "None" show background
+	if color == ""  ||  substitute(color, '.*', '\L&', '') == 'none'
+	  exe 'Hi xpm2Color'.n.' guifg=bg guibg=NONE'
+	else
+	  exe 'Hi xpm2Color'.n." guifg='".color."' guibg='".color."'"
+	endif
+	let n = n + 1
+      else
+	break			" no more color string
+      endif
+    endif
+    let i = i + 1
+  endwhile
+
+  unlet color chars colors cpp n i s
+
+endif		" has("gui_running")
+
+" Define the default highlighting.
+" For version 5.7 and earlier: only when not done already
+" For version 5.8 and later: only when an item doesn't have highlighting yet
+if version >= 508 || !exists("did_xpm2_syntax_inits")
+  if version < 508
+    let did_xpm2_syntax_inits = 1
+  endif
+
+  " The default highlighting.
+  HiLink xpm2Type		Type
+  HiLink xpm2StorageClass	StorageClass
+  HiLink xpm2Todo		Todo
+  HiLink xpm2Comment		Comment
+  HiLink xpm2PixelString	String
+endif
+delcommand HiLink
+delcommand Hi
+
+let b:current_syntax = "xpm2"
+
+" vim: ts=8:sw=2:noet:
--- /dev/null
+++ b/lib/vimfiles/syntax/xquery.vim
@@ -1,0 +1,80 @@
+" Vim syntax file
+" Language:	XQuery
+" Author:	Jean-Marc Vanel <http://jmvanel.free.fr/>
+" Last Change:	mar jui 12 18:04:05 CEST 2005
+" Filenames:	*.xq
+" URL:		http://jmvanel.free.fr/vim/xquery.vim
+" $Id: xquery.vim,v 1.1 2005/07/18 21:44:56 vimboss Exp $
+
+" REFERENCES:
+"   [1] http://www.w3.org/TR/xquery/
+
+" Quit when a syntax file was already loaded
+if exists("b:current_syntax")
+    finish
+endif
+
+runtime syntax/xml.vim
+
+syn case match
+
+" From XQuery grammar:
+syn	keyword	xqueryStatement ancestor ancestor-or-self and as ascending at attribute base-uri by case cast castable child collation construction declare default descendant descendant-or-self descending div document element else empty encoding eq every except external following following-sibling for function ge greatest gt idiv if import in inherit-namespaces instance intersect is le least let lt mod module namespace ne no of or order ordered ordering parent preceding preceding-sibling preserve return satisfies schema self some stable strip then to treat typeswitch union unordered validate variable version where xmlspace xquery yes
+
+" TODO contains clashes with vim keyword
+syn	keyword	xqueryFunction abs adjust-date-to-timezone adjust-date-to-timezone adjust-dateTime-to-timezone adjust-dateTime-to-timezone adjust-time-to-timezone adjust-time-to-timezone avg base-uri base-uri boolean ceiling codepoint-equal codepoints-to-string collection collection compare concat count current-date current-dateTime current-time data dateTime day-from-date day-from-dateTime days-from-duration deep-equal deep-equal default-collation distinct-values distinct-values doc doc-available document-uri empty ends-with ends-with error error error error escape-uri exactly-one exists false floor hours-from-dateTime hours-from-duration hours-from-time id id idref idref implicit-timezone in-scope-prefixes index-of index-of insert-before lang lang last local-name local-name local-name-from-QName lower-case matches matches max max min min minutes-from-dateTime minutes-from-duration minutes-from-time month-from-date month-from-dateTime months-from-duration name name namespace-uri namespace-uri namespace-uri-for-prefix namespace-uri-from-QName nilled node-name normalize-space normalize-space normalize-unicode normalize-unicode not number number one-or-more position prefix-from-QName QName remove replace replace resolve-QName resolve-uri resolve-uri reverse root root round round-half-to-even round-half-to-even seconds-from-dateTime seconds-from-duration seconds-from-time starts-with starts-with static-base-uri string string string-join string-length string-length string-to-codepoints subsequence subsequence substring substring substring-after substring-after substring-before substring-before sum sum timezone-from-date timezone-from-dateTime timezone-from-time tokenize tokenize trace translate true unordered upper-case year-from-date year-from-dateTime years-from-duration zero-or-one
+
+syn	keyword	xqueryOperator add-dayTimeDuration-to-date add-dayTimeDuration-to-dateTime add-dayTimeDuration-to-time add-dayTimeDurations add-yearMonthDuration-to-date add-yearMonthDuration-to-dateTime add-yearMonthDurations base64Binary-equal boolean-equal boolean-greater-than boolean-less-than concatenate date-equal date-greater-than date-less-than dateTime-equal dateTime-greater-than dateTime-less-than dayTimeDuration-equal dayTimeDuration-greater-than dayTimeDuration-less-than divide-dayTimeDuration divide-dayTimeDuration-by-dayTimeDuration divide-yearMonthDuration divide-yearMonthDuration-by-yearMonthDuration except gDay-equal gMonth-equal gMonthDay-equal gYear-equal gYearMonth-equal hexBinary-equal intersect is-same-node multiply-dayTimeDuration multiply-yearMonthDuration node-after node-before NOTATION-equal numeric-add numeric-divide numeric-equal numeric-greater-than numeric-integer-divide numeric-less-than numeric-mod numeric-multiply numeric-subtract numeric-unary-minus numeric-unary-plus QName-equal subtract-dates-yielding-dayTimeDuration subtract-dateTimes-yielding-dayTimeDuration subtract-dayTimeDuration-from-date subtract-dayTimeDuration-from-dateTime subtract-dayTimeDuration-from-time subtract-dayTimeDurations subtract-times subtract-yearMonthDuration-from-date subtract-yearMonthDuration-from-dateTime subtract-yearMonthDurations time-equal time-greater-than time-less-than to union yearMonthDuration-equal yearMonthDuration-greater-than yearMonthDuration-less-than
+
+syn	match	xqueryType "xs:\(\|Datatype\|primitive\|string\|boolean\|float\|double\|decimal\|duration\|dateTime\|time\|date\|gYearMonth\|gYear\|gMonthDay\|gDay\|gMonth\|hexBinary\|base64Binary\|anyURI\|QName\|NOTATION\|\|normalizedString\|token\|language\|IDREFS\|ENTITIES\|NMTOKEN\|NMTOKENS\|Name\|NCName\|ID\|IDREF\|ENTITY\|integer\|nonPositiveInteger\|negativeInteger\|long\|int\|short\|byte\|nonNegativeInteger\|unsignedLong\|unsignedInt\|unsignedShort\|unsignedByte\|positiveInteger\)"
+
+" From XPath grammar:
+syn	keyword	xqueryXPath some every in in satisfies if then else to div idiv mod union intersect except instance of treat castable cast eq ne lt le gt ge is child descendant attribute self descendant-or-self following-sibling following namespace parent ancestor preceding-sibling preceding ancestor-or-self void item node document-node text comment processing-instruction attribute schema-attribute schema-element
+
+" eXist extensions
+syn	match xqExist "&="
+
+" XQdoc
+syn	match	XQdoc contained "@\(param\|return\|author\)\>" 
+
+highlight def link	xqueryStatement	Statement
+highlight def link	xqueryFunction	Function
+highlight def link	xqueryOperator	Operator
+highlight def link	xqueryType		Type
+highlight def link	xqueryXPath		Operator
+highlight def link	XQdoc			Special
+highlight def link	xqExist			Operator
+
+
+"floating point number, with dot, optional exponent
+syn match	cFloat		"\d\+\.\d*\(e[-+]\=\d\+\)\=[fl]\="
+"floating point number, starting with a dot, optional exponent
+syn match	cFloat		"\.\d\+\(e[-+]\=\d\+\)\=[fl]\=\>"
+"floating point number, without dot, with exponent
+syn match	cFloat		"\d\+e[-+]\=\d\+[fl]\=\>"
+syn match	cNumber		"0x\x\+\(u\=l\{0,2}\|ll\=u\)\>"
+syn match	cNumber		 "\<\d\+\>"
+highlight def link	cNumber	Number
+highlight def link	cFloat	Number
+
+syn region	xqComment	start='(:' excludenl end=':)' contains=XQdoc
+highlight def link	xqComment	Comment
+" syntax match	xqVariable	"$\w\+"
+syntax match	xqVariable	+$\<[a-zA-Z:_][-.0-9a-zA-Z0-9:_]*\>+
+highlight def link	xqVariable	Identifier
+
+" Redefine the default XML highlighting:
+highlight def link	xmlTag		Structure
+highlight def link	xmlTagName	Structure
+highlight def link	xmlEndTag	Structure
+
+syntax match	xqSeparator	",\|;"
+highlight link	xqSeparator	Operator
+
+syn region	xqCode	transparent contained start='{' excludenl end='}' contains=xmlRegionBis,xqComment,xqueryStatement,xmlString,xqSeparator,cNumber,xqVariable keepend extend
+
+syn region xmlRegionBis start=+<\z([^ /!?<>"']\+\)+ skip=+<!--\_.\{-}-->+ end=+</\z1\_\s\{-}>+ end=+/>+ fold contains=xmlTag,xmlEndTag,xmlCdata,xmlRegionBis,xmlComment,xmlEntity,xmlProcessing,xqCode keepend extend
+
+syn region	List	transparent start='(' excludenl end=')' contains=xqCode,xmlRegion,xqComment,xqSeparator,xqueryStatement,xqVariable,xqueryType  keepend extend
+
+
--- /dev/null
+++ b/lib/vimfiles/syntax/xs.vim
@@ -1,0 +1,54 @@
+" Vim syntax file
+" Language:	XS (Perl extension interface language)
+" Maintainer:	Michael W. Dodge <sarge@pobox.com>
+" Last Change:	2001 May 09
+
+" For version 5.x: Clear all syntax items
+" For version 6.x: Quit when a syntax file was already loaded
+if version < 600
+  syntax clear
+elseif exists("b:current_syntax")
+  finish
+endif
+
+" Read the C syntax to start with
+if version < 600
+  source <sfile>:p:h/c.vim
+else
+  runtime! syntax/c.vim
+endif
+
+" XS extentions
+" TODO: Figure out how to look for trailing '='.
+syn keyword xsKeyword	MODULE PACKAGE PREFIX
+syn keyword xsKeyword	OUTPUT: CODE: INIT: PREINIT: INPUT:
+syn keyword xsKeyword	PPCODE: REQUIRE: CLEANUP: BOOT:
+syn keyword xsKeyword	VERSIONCHECK: PROTOTYPES: PROTOTYPE:
+syn keyword xsKeyword	ALIAS: INCLUDE: CASE:
+" TODO: Figure out how to look for trailing '('.
+syn keyword xsMacro	SV EXTEND PUSHs
+syn keyword xsVariable	RETVAL NO_INIT
+"syn match xsCast	"\<\(const\|static\|dynamic\|reinterpret\)_cast\s*<"me=e-1
+"syn match xsCast	"\<\(const\|static\|dynamic\|reinterpret\)_cast\s*$"
+
+" Define the default highlighting.
+" For version 5.7 and earlier: only when not done already
+" For version 5.8 and later: only when an item doesn't have highlighting yet
+if version >= 508 || !exists("did_xs_syntax_inits")
+  if version < 508
+    let did_xs_syntax_inits = 1
+    command -nargs=+ HiLink hi link <args>
+  else
+    command -nargs=+ HiLink hi def link <args>
+  endif
+
+  HiLink xsKeyword	Keyword
+  HiLink xsMacro	Macro
+  HiLink xsVariable	Identifier
+
+  delcommand HiLink
+endif
+
+let b:current_syntax = "xs"
+
+" vim: ts=8
--- /dev/null
+++ b/lib/vimfiles/syntax/xsd.vim
@@ -1,0 +1,61 @@
+" Vim syntax file
+" Language:	XSD (XML Schema)
+" Maintainer:	Johannes Zellner <johannes@zellner.org>
+" Last Change:	Tue, 27 Apr 2004 14:54:59 CEST
+" Filenames:	*.xsd
+" $Id: xsd.vim,v 1.1 2004/06/13 18:20:48 vimboss Exp $
+
+" REFERENCES:
+"   [1] http://www.w3.org/TR/xmlschema-0
+"
+
+" Quit when a syntax file was already loaded
+if exists("b:current_syntax")
+    finish
+endif
+
+runtime syntax/xml.vim
+
+syn cluster xmlTagHook add=xsdElement
+syn case match
+
+syn match xsdElement '\%(xsd:\)\@<=all'
+syn match xsdElement '\%(xsd:\)\@<=annotation'
+syn match xsdElement '\%(xsd:\)\@<=any'
+syn match xsdElement '\%(xsd:\)\@<=anyAttribute'
+syn match xsdElement '\%(xsd:\)\@<=appInfo'
+syn match xsdElement '\%(xsd:\)\@<=attribute'
+syn match xsdElement '\%(xsd:\)\@<=attributeGroup'
+syn match xsdElement '\%(xsd:\)\@<=choice'
+syn match xsdElement '\%(xsd:\)\@<=complexContent'
+syn match xsdElement '\%(xsd:\)\@<=complexType'
+syn match xsdElement '\%(xsd:\)\@<=documentation'
+syn match xsdElement '\%(xsd:\)\@<=element'
+syn match xsdElement '\%(xsd:\)\@<=enumeration'
+syn match xsdElement '\%(xsd:\)\@<=extension'
+syn match xsdElement '\%(xsd:\)\@<=field'
+syn match xsdElement '\%(xsd:\)\@<=group'
+syn match xsdElement '\%(xsd:\)\@<=import'
+syn match xsdElement '\%(xsd:\)\@<=include'
+syn match xsdElement '\%(xsd:\)\@<=key'
+syn match xsdElement '\%(xsd:\)\@<=keyref'
+syn match xsdElement '\%(xsd:\)\@<=length'
+syn match xsdElement '\%(xsd:\)\@<=list'
+syn match xsdElement '\%(xsd:\)\@<=maxInclusive'
+syn match xsdElement '\%(xsd:\)\@<=maxLength'
+syn match xsdElement '\%(xsd:\)\@<=minInclusive'
+syn match xsdElement '\%(xsd:\)\@<=minLength'
+syn match xsdElement '\%(xsd:\)\@<=pattern'
+syn match xsdElement '\%(xsd:\)\@<=redefine'
+syn match xsdElement '\%(xsd:\)\@<=restriction'
+syn match xsdElement '\%(xsd:\)\@<=schema'
+syn match xsdElement '\%(xsd:\)\@<=selector'
+syn match xsdElement '\%(xsd:\)\@<=sequence'
+syn match xsdElement '\%(xsd:\)\@<=simpleContent'
+syn match xsdElement '\%(xsd:\)\@<=simpleType'
+syn match xsdElement '\%(xsd:\)\@<=union'
+syn match xsdElement '\%(xsd:\)\@<=unique'
+
+hi def link xsdElement Statement
+
+" vim: ts=8
--- /dev/null
+++ b/lib/vimfiles/syntax/xslt.vim
@@ -1,0 +1,62 @@
+" Vim syntax file
+" Language:	XSLT
+" Maintainer:	Johannes Zellner <johannes@zellner.org>
+" Last Change:	Sun, 28 Oct 2001 21:22:24 +0100
+" Filenames:	*.xsl
+" $Id: xslt.vim,v 1.1 2004/06/13 15:52:10 vimboss Exp $
+
+" REFERENCES:
+"   [1] http://www.w3.org/TR/xslt
+"
+
+" Quit when a syntax file was already loaded
+if exists("b:current_syntax")
+    finish
+endif
+
+runtime syntax/xml.vim
+
+syn cluster xmlTagHook add=xslElement
+syn case match
+
+syn match xslElement '\%(xsl:\)\@<=apply-imports'
+syn match xslElement '\%(xsl:\)\@<=apply-templates'
+syn match xslElement '\%(xsl:\)\@<=attribute'
+syn match xslElement '\%(xsl:\)\@<=attribute-set'
+syn match xslElement '\%(xsl:\)\@<=call-template'
+syn match xslElement '\%(xsl:\)\@<=choose'
+syn match xslElement '\%(xsl:\)\@<=comment'
+syn match xslElement '\%(xsl:\)\@<=copy'
+syn match xslElement '\%(xsl:\)\@<=copy-of'
+syn match xslElement '\%(xsl:\)\@<=decimal-format'
+syn match xslElement '\%(xsl:\)\@<=document'
+syn match xslElement '\%(xsl:\)\@<=element'
+syn match xslElement '\%(xsl:\)\@<=fallback'
+syn match xslElement '\%(xsl:\)\@<=for-each'
+syn match xslElement '\%(xsl:\)\@<=if'
+syn match xslElement '\%(xsl:\)\@<=include'
+syn match xslElement '\%(xsl:\)\@<=import'
+syn match xslElement '\%(xsl:\)\@<=key'
+syn match xslElement '\%(xsl:\)\@<=message'
+syn match xslElement '\%(xsl:\)\@<=namespace-alias'
+syn match xslElement '\%(xsl:\)\@<=number'
+syn match xslElement '\%(xsl:\)\@<=otherwise'
+syn match xslElement '\%(xsl:\)\@<=output'
+syn match xslElement '\%(xsl:\)\@<=param'
+syn match xslElement '\%(xsl:\)\@<=processing-instruction'
+syn match xslElement '\%(xsl:\)\@<=preserve-space'
+syn match xslElement '\%(xsl:\)\@<=script'
+syn match xslElement '\%(xsl:\)\@<=sort'
+syn match xslElement '\%(xsl:\)\@<=strip-space'
+syn match xslElement '\%(xsl:\)\@<=stylesheet'
+syn match xslElement '\%(xsl:\)\@<=template'
+syn match xslElement '\%(xsl:\)\@<=transform'
+syn match xslElement '\%(xsl:\)\@<=text'
+syn match xslElement '\%(xsl:\)\@<=value-of'
+syn match xslElement '\%(xsl:\)\@<=variable'
+syn match xslElement '\%(xsl:\)\@<=when'
+syn match xslElement '\%(xsl:\)\@<=with-param'
+
+hi def link xslElement Statement
+
+" vim: ts=8
--- /dev/null
+++ b/lib/vimfiles/syntax/xxd.vim
@@ -1,0 +1,42 @@
+" Vim syntax file
+" Language:		bin using xxd
+" Maintainer:	Dr. Charles E. Campbell, Jr. <NdrOchipS@PcampbellAfamily.Mbiz>
+" Last Change:	Sep 06, 2005
+" Version:		7
+" Notes:		use :help xxd   to see how to invoke it
+" URL:	http://mysite.verizon.net/astronaut/vim/index.html#vimlinks_syntax
+
+" For version 5.x: Clear all syntax items
+" For version 6.x: Quit when a syntax file was already loaded
+if version < 600
+  syntax clear
+elseif exists("b:current_syntax")
+  finish
+endif
+
+syn match xxdAddress			"^[0-9a-f]\+:"		contains=xxdSep
+syn match xxdSep	contained	":"
+syn match xxdAscii				"  .\{,16\}\r\=$"hs=s+2	contains=xxdDot
+syn match xxdDot	contained	"[.\r]"
+
+" Define the default highlighting.
+" For version 5.7 and earlier: only when not done already
+" For version 5.8 and later: only when an item doesn't have highlighting yet
+if version >= 508 || !exists("did_xxd_syntax_inits")
+  if version < 508
+    let did_xxd_syntax_inits = 1
+    command -nargs=+ HiLink hi link <args>
+  else
+    command -nargs=+ HiLink hi def link <args>
+  endif
+
+ HiLink xxdAddress	Constant
+ HiLink xxdSep		Identifier
+ HiLink xxdAscii	Statement
+
+ delcommand HiLink
+endif
+
+let b:current_syntax = "xxd"
+
+" vim: ts=4
--- /dev/null
+++ b/lib/vimfiles/syntax/yacc.vim
@@ -1,0 +1,98 @@
+" Vim syntax file
+" Language:	Yacc
+" Maintainer:	Dr. Charles E. Campbell, Jr. <NdrOchipS@PcampbellAfamily.Mbiz>
+" Last Change:	Feb 22, 2006
+" Version:	4
+" URL:	http://mysite.verizon.net/astronaut/vim/index.html#vimlinks_syntax
+"
+" Option:
+"   g:yacc_uses_cpp : if this variable exists, then C++ is loaded rather than C
+
+" For version 5.x: Clear all syntax items
+" For version 6.x: Quit when a syntax file was already loaded
+if version < 600
+  syntax clear
+elseif exists("b:current_syntax")
+  finish
+endif
+
+" Read the C syntax to start with
+if version >= 600
+  if exists("g:yacc_uses_cpp")
+    runtime! syntax/cpp.vim
+  else
+    runtime! syntax/c.vim
+  endif
+elseif exists("g:yacc_uses_cpp")
+  so <sfile>:p:h/cpp.vim
+else
+  so <sfile>:p:h/c.vim
+endif
+
+" Clusters
+syn cluster	yaccActionGroup	contains=yaccDelim,cInParen,cTodo,cIncluded,yaccDelim,yaccCurlyError,yaccUnionCurly,yaccUnion,cUserLabel,cOctalZero,cCppOut2,cCppSkip,cErrInBracket,cErrInParen,cOctalError,cCommentStartError,cParenError
+syn cluster	yaccUnionGroup	contains=yaccKey,cComment,yaccCurly,cType,cStructure,cStorageClass,yaccUnionCurly
+
+" Yacc stuff
+syn match	yaccDelim	"^\s*[:|;]"
+syn match	yaccOper	"@\d\+"
+
+syn match	yaccKey	"^\s*%\(token\|type\|left\|right\|start\|ident\|nonassoc\)\>"
+syn match	yaccKey	"\s%\(prec\|expect\)\>"
+syn match	yaccKey	"\$\(<[a-zA-Z_][a-zA-Z_0-9]*>\)\=[\$0-9]\+"
+syn keyword	yaccKeyActn	yyerrok yyclearin
+
+syn match	yaccUnionStart	"^%union"	skipwhite skipnl nextgroup=yaccUnion
+syn region	yaccUnion	contained matchgroup=yaccCurly start="{" matchgroup=yaccCurly end="}"	contains=@yaccUnionGroup
+syn region	yaccUnionCurly	contained matchgroup=yaccCurly start="{" matchgroup=yaccCurly end="}" contains=@yaccUnionGroup
+syn match	yaccBrkt	contained "[<>]"
+syn match	yaccType	"<[a-zA-Z_][a-zA-Z0-9_]*>"	contains=yaccBrkt
+syn match	yaccDefinition	"^[A-Za-z][A-Za-z0-9_]*\_s*:"
+
+" special Yacc separators
+syn match	yaccSectionSep	"^[ \t]*%%"
+syn match	yaccSep	"^[ \t]*%{"
+syn match	yaccSep	"^[ \t]*%}"
+
+" I'd really like to highlight just the outer {}.  Any suggestions???
+syn match	yaccCurlyError	"[{}]"
+syn region	yaccAction	matchgroup=yaccCurly start="{" end="}" contains=ALLBUT,@yaccActionGroup
+
+
+" Define the default highlighting.
+" For version 5.7 and earlier: only when not done already
+" For version 5.8 and later: only when an item doesn't have highlighting yet
+if version >= 508 || !exists("did_yacc_syn_inits")
+  if version < 508
+    let did_yacchdl_syn_inits = 1
+    command -nargs=+ HiLink hi link <args>
+  else
+    command -nargs=+ HiLink hi def link <args>
+  endif
+
+  " Internal yacc highlighting links
+  HiLink yaccBrkt	yaccStmt
+  HiLink yaccKey	yaccStmt
+  HiLink yaccOper	yaccStmt
+  HiLink yaccUnionStart	yaccKey
+
+  " External yacc highlighting links
+  HiLink yaccCurly	Delimiter
+  HiLink yaccCurlyError	Error
+  HiLink yaccDefinition	Function
+  HiLink yaccDelim	Function
+  HiLink yaccKeyActn	Special
+  HiLink yaccSectionSep	Todo
+  HiLink yaccSep	Delimiter
+  HiLink yaccStmt	Statement
+  HiLink yaccType	Type
+
+  " since Bram doesn't like my Delimiter :|
+  HiLink Delimiter	Type
+
+  delcommand HiLink
+endif
+
+let b:current_syntax = "yacc"
+
+" vim: ts=15
--- /dev/null
+++ b/lib/vimfiles/syntax/yaml.vim
@@ -1,0 +1,83 @@
+" Vim syntax file
+" Language:         YAML (YAML Ain't Markup Language)
+" Maintainer:       Nikolai Weibull <now@bitwi.se>
+" Latest Revision:  2006-04-19
+
+if exists("b:current_syntax")
+  finish
+endif
+
+let s:cpo_save = &cpo
+set cpo&vim
+
+syn keyword yamlTodo            contained TODO FIXME XXX NOTE
+
+syn region  yamlComment         display oneline start='\%(^\|\s\)#' end='$'
+                                \ contains=yamlTodo,@Spell
+
+syn match   yamlNodeProperty    '!\%(![^\\^%     ]\+\|[^!][^:/   ]*\)'
+
+syn match   yamlAnchor          '&.\+'
+
+syn match   yamlAlias           '\*.\+'
+
+syn match   yamlDelimiter       '[-,:]'
+syn match   yamlBlock           '[\[\]{}>|]'
+syn match   yamlOperator        '[?+-]'
+syn match   yamlKey             '\w\+\(\s\+\w\+\)*\ze\s*:'
+
+syn region  yamlString          start=+"+ skip=+\\"+ end=+"+
+                                \ contains=yamlEscape
+syn region  yamlString          start=+'+ skip=+''+ end=+'+
+                                \ contains=yamlSingleEscape
+syn match   yamlEscape          contained display +\\[\\"abefnrtv^0_ NLP]+
+syn match   yamlEscape          contained display '\\x\x\{2}'
+syn match   yamlEscape          contained display '\\u\x\{4}'
+syn match   yamlEscape          contained display '\\U\x\{8}'
+" TODO: how do we get 0x85, 0x2028, and 0x2029 into this?
+syn match   yamlEscape          display '\\\%(\r\n\|[\r\n]\)'
+syn match   yamlSingleEscape    contained display +''+
+
+" TODO: sexagecimal and fixed (20:30.15 and 1,230.15)
+syn match   yamlNumber          display
+                                \ '\<[+-]\=\d\+\%(\.\d\+\%([eE][+-]\=\d\+\)\=\)\='
+syn match   yamlNumber          display '0\o\+'
+syn match   yamlNumber          display '0x\x\+'
+syn match   yamlNumber          display '([+-]\=[iI]nf)'
+syn match   yamlNumber          display '(NaN)'
+
+syn match   yamlConstant        '\<[~yn]\>'
+syn keyword yamlConstant        true True TRUE false False FALSE
+syn keyword yamlConstant        yes Yes on ON no No off OFF
+syn keyword yamlConstant        null Null NULL nil Nil NIL
+
+syn match   yamlTimestamp       '\d\d\d\d-\%(1[0-2]\|\d\)-\%(3[0-2]\|2\d\|1\d\|\d\)\%( \%([01]\d\|2[0-3]\):[0-5]\d:[0-5]\d.\d\d [+-]\%([01]\d\|2[0-3]\):[0-5]\d\|t\%([01]\d\|2[0-3]\):[0-5]\d:[0-5]\d.\d\d[+-]\%([01]\d\|2[0-3]\):[0-5]\d\|T\%([01]\d\|2[0-3]\):[0-5]\d:[0-5]\d.\dZ\)\='
+
+syn region  yamlDocumentHeader  start='---' end='$' contains=yamlDirective
+syn match   yamlDocumentEnd     '\.\.\.'
+
+syn match   yamlDirective       contained '%[^:]\+:.\+'
+
+hi def link yamlTodo            Todo
+hi def link yamlComment         Comment
+hi def link yamlDocumentHeader  PreProc
+hi def link yamlDocumentEnd     PreProc
+hi def link yamlDirective       Keyword
+hi def link yamlNodeProperty    Type
+hi def link yamlAnchor          Type
+hi def link yamlAlias           Type
+hi def link yamlDelimiter       Delimiter
+hi def link yamlBlock           Operator
+hi def link yamlOperator        Operator
+hi def link yamlKey             Identifier
+hi def link yamlString          String
+hi def link yamlEscape          SpecialChar
+hi def link yamlSingleEscape    SpecialChar
+hi def link yamlNumber          Number
+hi def link yamlConstant        Constant
+hi def link yamlTimestamp       Number
+
+let b:current_syntax = "yaml"
+
+let &cpo = s:cpo_save
+unlet s:cpo_save
--- /dev/null
+++ b/lib/vimfiles/syntax/z8a.vim
@@ -1,0 +1,114 @@
+" Vim syntax file
+" Language:	Z80 assembler asz80
+" Maintainer:	Milan Pikula <www@fornax.elf.stuba.sk>
+" Last Change:	2003 May 11
+
+" For version 5.x: Clear all syntax items
+" For version 6.x: Quit when a syntax file was already loaded
+if version < 600
+  syntax clear
+elseif exists("b:current_syntax")
+  finish
+endif
+
+syn case ignore
+
+" Common Z80 Assembly instructions
+syn keyword z8aInstruction adc add and bit ccf cp cpd cpdr cpi cpir cpl
+syn keyword z8aInstruction daa di djnz ei exx halt im in
+syn keyword z8aInstruction ind ini indr inir jp jr ld ldd lddr ldi ldir
+syn keyword z8aInstruction neg nop or otdr otir out outd outi
+syn keyword z8aInstruction res rl rla rlc rlca rld
+syn keyword z8aInstruction rr rra rrc rrca rrd sbc scf set sla sra
+syn keyword z8aInstruction srl sub xor
+" syn keyword z8aInstruction push pop call ret reti retn inc dec ex rst
+
+" Any other stuff
+syn match z8aIdentifier		"[a-z_][a-z0-9_]*"
+
+" Instructions changing stack
+syn keyword z8aSpecInst push pop call ret reti retn rst
+syn match z8aInstruction "\<inc\>"
+syn match z8aInstruction "\<dec\>"
+syn match z8aInstruction "\<ex\>"
+syn match z8aSpecInst "\<inc\s\+sp\>"me=s+3
+syn match z8aSpecInst "\<dec\s\+sp\>"me=s+3
+syn match z8aSpecInst "\<ex\s\+(\s*sp\s*)\s*,\s*hl\>"me=s+2
+
+"Labels
+syn match z8aLabel		"[a-z_][a-z0-9_]*:"
+syn match z8aSpecialLabel	"[a-z_][a-z0-9_]*::"
+
+" PreProcessor commands
+syn match z8aPreProc	"\.org"
+syn match z8aPreProc	"\.globl"
+syn match z8aPreProc	"\.db"
+syn match z8aPreProc	"\.dw"
+syn match z8aPreProc	"\.ds"
+syn match z8aPreProc	"\.byte"
+syn match z8aPreProc	"\.word"
+syn match z8aPreProc	"\.blkb"
+syn match z8aPreProc	"\.blkw"
+syn match z8aPreProc	"\.ascii"
+syn match z8aPreProc	"\.asciz"
+syn match z8aPreProc	"\.module"
+syn match z8aPreProc	"\.title"
+syn match z8aPreProc	"\.sbttl"
+syn match z8aPreProc	"\.even"
+syn match z8aPreProc	"\.odd"
+syn match z8aPreProc	"\.area"
+syn match z8aPreProc	"\.page"
+syn match z8aPreProc	"\.setdp"
+syn match z8aPreProc	"\.radix"
+syn match z8aInclude	"\.include"
+syn match z8aPreCondit	"\.if"
+syn match z8aPreCondit	"\.else"
+syn match z8aPreCondit	"\.endif"
+
+" Common strings
+syn match z8aString		"\".*\""
+syn match z8aString		"\'.*\'"
+
+" Numbers
+syn match z8aNumber		"[0-9]\+"
+syn match z8aNumber		"0[xXhH][0-9a-fA-F]\+"
+syn match z8aNumber		"0[bB][0-1]*"
+syn match z8aNumber		"0[oO\@qQ][0-7]\+"
+syn match z8aNumber		"0[dD][0-9]\+"
+
+" Character constant
+syn match z8aString		"\#\'."hs=s+1
+
+" Comments
+syn match z8aComment		";.*"
+
+syn case match
+
+" Define the default highlighting.
+" For version 5.7 and earlier: only when not done already
+" For version 5.8 and later: only when an item doesn't have highlighting yet
+if version >= 508 || !exists("did_z8a_syntax_inits")
+  if version < 508
+    let did_z8a_syntax_inits = 1
+    command -nargs=+ HiLink hi link <args>
+  else
+    command -nargs=+ HiLink hi def link <args>
+  endif
+
+  HiLink z8aSection		Special
+  HiLink z8aLabel		Label
+  HiLink z8aSpecialLabel	Label
+  HiLink z8aComment		Comment
+  HiLink z8aInstruction	Statement
+  HiLink z8aSpecInst		Statement
+  HiLink z8aInclude		Include
+  HiLink z8aPreCondit		PreCondit
+  HiLink z8aPreProc		PreProc
+  HiLink z8aNumber		Number
+  HiLink z8aString		String
+
+  delcommand HiLink
+endif
+
+let b:current_syntax = "z8a"
+" vim: ts=8
--- /dev/null
+++ b/lib/vimfiles/syntax/zsh.vim
@@ -1,0 +1,194 @@
+" Vim syntax file
+" Language:         Zsh shell script
+" Maintainer:       Nikolai Weibull <now@bitwi.se>
+" Latest Revision:  2006-08-06
+
+if exists("b:current_syntax")
+  finish
+endif
+
+let s:cpo_save = &cpo
+set cpo&vim
+
+setlocal iskeyword=@,48-57,_,-
+
+syn keyword zshTodo             contained TODO FIXME XXX NOTE
+
+syn region  zshComment          display oneline start='\%(^\|\s\)#' end='$'
+                                \ contains=zshTodo,@Spell
+
+syn match   zshPreProc          '^\%1l#\%(!\|compdef\|autoload\).*$'
+
+syn match   zshQuoted           '\\.'
+syn region  zshString           matchgroup=zshStringDelimiter start=+"+ end=+"+
+                                \ contains=zshQuoted,@zshDerefs,@zshSubst
+syn region  zshString           matchgroup=zshStringDelimiter start=+'+ end=+'+
+" XXX: This should probably be more precise, but Zsh seems a bit confused about it itself
+syn region  zshPOSIXString      matchgroup=zshStringDelimiter start=+\$'+
+                                \ end=+'+ contains=zshQuoted
+syn match   zshJobSpec          '%\(\d\+\|?\=\w\+\|[%+-]\)'
+
+syn keyword zshPrecommand       noglob nocorrect exec command builtin - time
+
+syn keyword zshDelimiter        do done
+
+syn keyword zshConditional      if then elif else fi case in esac select
+
+syn keyword zshRepeat           for while until repeat foreach
+
+syn keyword zshException        always
+
+syn keyword zshKeyword          function nextgroup=zshKSHFunction skipwhite
+
+syn match   zshKSHFunction      contained '\k\+'
+syn match   zshFunction         '^\s*\k\+\ze\s*()'
+
+syn match   zshOperator         '||\|&&\|;\|&!\='
+
+syn match   zshRedir            '\d\=\(<\|<>\|<<<\|<&\s*[0-9p-]\=\)'
+syn match   zshRedir            '\d\=\(>\|>>\|>&\s*[0-9p-]\=\|&>\|>>&\|&>>\)[|!]\='
+syn match   zshRedir            '|&\='
+
+syn region  zshHereDoc          matchgroup=zshRedir start='<<\s*\z(\S*\)'
+                                \ end='^\z1\>' contains=@zshSubst
+syn region  zshHereDoc          matchgroup=zshRedir start='<<-\s*\z(\S*\)'
+                                \ end='^\s*\z1\>' contains=@zshSubst
+syn region  zshHereDoc          matchgroup=zshRedir
+                                \ start=+<<\s*\(["']\)\z(\S*\)\1+  end='^\z1\>'
+syn region  zshHereDoc          matchgroup=zshRedir
+                                \ start=+<<-\s*\(["']\)\z(\S*\)\1+
+                                \ end='^\s*\z1\>'
+
+syn match   zshVariable         '\<\h\w*\ze+\=='
+" XXX: how safe is this?
+syn region  zshVariable         oneline
+                                \ start='\$\@<!\<\h\w*\[' end='\]\ze+\=='
+                                \ contains=@zshSubst
+
+syn cluster zshDerefs           contains=zshShortDeref,zshLongDeref,zshDeref
+
+if !exists("g:zsh_syntax_variables")
+  let s:zsh_syntax_variables = 'all'
+else
+  let s:zsh_syntax_variables = g:zsh_syntax_variables
+endif
+
+if s:zsh_syntax_variables =~ 'short\|all'
+  syn match zshShortDeref       '\$[!#$*@?_-]\w\@!'
+  syn match zshShortDeref       '\$[=^~]*[#+]*\d\+\>'
+endif
+
+if s:zsh_syntax_variables =~ 'long\|all'
+  syn match zshLongDeref        '\$\%(ARGC\|argv\|status\|pipestatus\|CPUTYPE\|EGID\|EUID\|ERRNO\|GID\|HOST\|LINENO\|LOGNAME\)'
+  syn match zshLongDeref        '\$\%(MACHTYPE\|OLDPWD OPTARG\|OPTIND\|OSTYPE\|PPID\|PWD\|RANDOM\|SECONDS\|SHLVL\|signals\)'
+  syn match zshLongDeref        '\$\%(TRY_BLOCK_ERROR\|TTY\|TTYIDLE\|UID\|USERNAME\|VENDOR\|ZSH_NAME\|ZSH_VERSION\|REPLY\|reply\|TERM\)'
+endif
+
+if s:zsh_syntax_variables =~ 'all'
+  syn match zshDeref            '\$[=^~]*[#+]*\h\w*\>'
+else
+  syn match zshDeref            transparent '\$[=^~]*[#+]*\h\w*\>'
+endif
+
+syn match   zshCommands         '\%(^\|\s\)[.:]\ze\s'
+syn keyword zshCommands         alias autoload bg bindkey break bye cap cd
+                                \ chdir clone comparguments compcall compctl
+                                \ compdescribe compfiles compgroups compquote
+                                \ comptags comptry compvalues continue dirs
+                                \ disable disown echo echotc echoti emulate
+                                \ enable eval exec exit export false fc fg
+                                \ functions getcap getln getopts hash history
+                                \ jobs kill let limit log logout popd print
+                                \ printf pushd pushln pwd r read readonly
+                                \ rehash return sched set setcap setopt shift
+                                \ source stat suspend test times trap true
+                                \ ttyctl type ulimit umask unalias unfunction
+                                \ unhash unlimit unset unsetopt vared wait
+                                \ whence where which zcompile zformat zftp zle
+                                \ zmodload zparseopts zprof zpty zregexparse
+                                \ zsocket zstyle ztcp
+
+syn keyword zshTypes            float integer local typeset declare
+
+" XXX: this may be too much
+" syn match   zshSwitches         '\s\zs--\=[a-zA-Z0-9-]\+'
+
+syn match   zshNumber           '[+-]\=\<\d\+\>'
+syn match   zshNumber           '[+-]\=\<0x\x\+\>'
+syn match   zshNumber           '[+-]\=\<0\o\+\>'
+syn match   zshNumber           '[+-]\=\d\+#[-+]\=\w\+\>'
+syn match   zshNumber           '[+-]\=\d\+\.\d\+\>'
+
+syn cluster zshSubst            contains=zshSubst,zshOldSubst,zshMathSubst
+syn region  zshSubst            matchgroup=zshSubstDelim transparent
+                                \ start='\$(' skip='\\)' end=')' contains=TOP
+syn region  zshParentheses      transparent start='(' skip='\\)' end=')'
+syn region  zshMathSubst        matchgroup=zshSubstDelim transparent
+                                \ start='\$((' skip='\\)'
+                                \ matchgroup=zshSubstDelim end='))'
+                                \ contains=zshParentheses,@zshSubst,zshNumber,
+                                \ @zshDerefs,zshString
+syn region  zshBrackets         contained transparent start='{' skip='\\}'
+                                \ end='}'
+syn region  zshSubst            matchgroup=zshSubstDelim start='\${' skip='\\}'
+                                \ end='}' contains=@zshSubst,zshBrackets,zshQuoted
+syn region  zshOldSubst         matchgroup=zshSubstDelim start=+`+ skip=+\\`+
+                                \ end=+`+ contains=TOP,zshOldSubst
+
+hi def link zshTodo             Todo
+hi def link zshComment          Comment
+hi def link zshPreProc          PreProc
+hi def link zshQuoted           SpecialChar
+hi def link zshString           String
+hi def link zshStringDelimiter  zshString
+hi def link zshPOSIXString      zshString
+hi def link zshJobSpec          Special
+hi def link zshPrecommand       Special
+hi def link zshDelimiter        Keyword
+hi def link zshConditional      Conditional
+hi def link zshException        Exception
+hi def link zshRepeat           Repeat
+hi def link zshKeyword          Keyword
+hi def link zshFunction         None
+hi def link zshKSHFunction      zshFunction
+hi def link zshHereDoc          String
+if 0
+  hi def link zshOperator         Operator
+else
+  hi def link zshOperator         None
+endif
+if 1
+  hi def link zshRedir            Operator
+else
+  hi def link zshRedir            None
+endif
+hi def link zshVariable         None
+hi def link zshDereferencing    PreProc
+if s:zsh_syntax_variables =~ 'short\|all'
+  hi def link zshShortDeref     zshDereferencing
+else
+  hi def link zshShortDeref     None
+endif
+if s:zsh_syntax_variables =~ 'long\|all'
+  hi def link zshLongDeref      zshDereferencing
+else
+  hi def link zshLongDeref      None
+endif
+if s:zsh_syntax_variables =~ 'all'
+  hi def link zshDeref          zshDereferencing
+else
+  hi def link zshDeref          None
+endif
+hi def link zshCommands         Keyword
+hi def link zshTypes            Type
+hi def link zshSwitches         Special
+hi def link zshNumber           Number
+hi def link zshSubst            PreProc
+hi def link zshMathSubst        zshSubst
+hi def link zshOldSubst         zshSubst
+hi def link zshSubstDelim       zshSubst
+
+let b:current_syntax = "zsh"
+
+let &cpo = s:cpo_save
+unlet s:cpo_save
--- /dev/null
+++ b/lib/vimfiles/termcap
@@ -1,0 +1,135 @@
+#
+# Demonstration of a termcap file (for the Amiga and Archimedes)
+#
+# Maintainer:	Bram Moolenaar <Bram@vim.org>
+# Last change:	1999 Feb 02
+#
+sx|ansi|any ansi terminal with pessimistic assumptions:\
+	:co#80:li#24:cl=50\E[;H\E[2J:bs:am:cm=\E[%i%d;%dH:\
+	:nd=\E[C:up=\E[A:ce=\E[K:ho=\E[H:pt:
+
+Mu|sun|Sun Microsystems Workstation console:\
+	:am:bs:km:mi:ms:pt:li#34:co#80:cl=^L:cm=\E[%i%d;%dH:\
+	:ce=\E[K:cd=\E[J:\
+	:so=\E[7m:se=\E[m:us=\E[4m:ue=\E[m:rs=\E[s:\
+	:md=\E[1m:mr=\E[7m:me=\E[m:\
+	:al=\E[L:dl=\E[M:im=:ei=:ic=\E[@:dc=\E[P:\
+	:AL=\E[%dL:DL=\E[%dM:IC=\E[%d@:DC=\E[%dP:\
+	:up=\E[A:nd=\E[C:ku=\E[A:kd=\E[B:kr=\E[C:kl=\E[D:\
+	:k1=\E[224z:k2=\E[225z:k3=\E[226z:k4=\E[227z:k5=\E[228z:\
+	:k6=\E[229z:k7=\E[230z:k8=\E[231z:k9=\E[232z:
+
+M-|sun-e|sun-nic|sune|Sun Microsystems Workstation without insert character:\
+	:ic@:im@:ei@:tc=sun:
+Mu|sun-s|Sun Microsystems Workstation window with status line:\
+	:hs:ts=\E]l:fs=\E\\:ds=\E]l\E\\:tc=sun:
+Mu|sun-e-s|sun-s-e|Sun Microsystems Workstation with status hacked for emacs:\
+	:hs:ts=\E]l:fs=\E\\:ds=\E]l\E\\:tc=sun-e:
+M0|sun-48|Sun 48-line window:\
+	:li#48:co#80:tc=sun:
+M1|sun-34|Sun 34-line window:\
+	:li#34:co#80:tc=sun:
+M2|sun-24|Sun 24-line window:\
+	:li#24:co#80:tc=sun:
+M3|sun-17|Sun 17-line window:\
+	:li#17:co#80:tc=sun:
+
+v9|925a|tvi925a|TeleVideo Model 925:\
+	:al=\EE:am:bs:bt=\EI:bw:cd=\EY:ce=\ET:cl=^Z:cm=\E=%+ %+ :co#80:dc=\EW:\
+	:dl=\ER:do=^V:ei=:ic=\EQ:if=/usr/share/lib/tabset/std:im=:kb=^H:kd=^V:\
+	:kh=^^:kl=^H:kn#12:kr=^L:ku=^K:li#24:nd=^L:pt:se=\EG0:sg#1:so=\EG4:\
+	:ue=\EG0:ug#1:ul:up=^K:us=\EG8:is=\El\
+	:vb=\Eb\200\200\200\200\200\200\200\200\200\200\200\200\200\200\Ed:\
+	:ve=\E.4:vs=\E.2:
+
+d0|vt100|vt100-am|vt100am|dec vt100:\
+	:do=^J:co#80:li#24:cl=50\E[;H\E[2J:sf=5\ED:\
+	:le=^H:bs:am:cm=5\E[%i%d;%dH:nd=2\E[C:up=2\E[A:\
+	:ce=3\E[K:cd=50\E[J:so=2\E[7m:se=2\E[m:us=2\E[4m:ue=2\E[m:\
+	:md=2\E[1m:mr=2\E[7m:mb=2\E[5m:me=2\E[m:is=\E[1;24r\E[24;1H:\
+	:rf=/usr/share/lib/tabset/vt100:\
+	:rs=\E>\E[?3l\E[?4l\E[?5l\E[?7h\E[?8h:ks=\E[?1h\E=:ke=\E[?1l\E>:\
+	:ku=\EOA:kd=\EOB:kr=\EOC:kl=\EOD:kb=^H:\
+	:ho=\E[H:k1=\EOP:k2=\EOQ:k3=\EOR:k4=\EOS:pt:sr=5\EM:vt#3:xn:\
+	:sc=\E7:rc=\E8:cs=\E[%i%d;%dr:
+
+# Amiga termcap by Bram Moolenaar
+AA|amiga|Amiga ANSI:\
+	:co#80:li#25:am:do=\E[B:ce=\E[K:cd=\E[J:\
+	:cl=\014:ku=\233A:kd=\233B:kl=\233D:kr=\233C:kb=^H:\
+	:#4=\233 A:%i=\233 @:%1=\233?~:\
+	:k1=\2330~:k2=\2331~:k3=\2332~:k4=\2333~:k5=\2334~:\
+	:k6=\2335~:k7=\2336~:k8=\2337~:k9=\2338~:k;=\2339~:\
+	:F1=\23310~:F2=\23311~:F3=\23312~:F4=\23313~:F5=\23314~:\
+	:F6=\23315~:F7=\23316~:F8=\23317~:F9=\23318~:FA=\23319~:\
+	:al=\E[L:AL=\E[%dL:dl=\E[M:DL=\E[%dM:le=^H:cm=\E[%i%d;%dH:\
+	:nd=\E[C:RI=\E[%dC:up=\E[A:\
+	:ce=\E[K:ho=\E[H:dc=\E[P:ic=\E[@:vi=\E[0 p:ve=\E[1 p:\
+	:so=\E[2m:se=\E[m:us=\E[4m:ue=\E[m:mr=\E[7m:mb=\E[7;2m:me=\E[m:
+
+# Acorn VDU
+# For non-green text, change the ^B in the :cl= line to
+# your favourite control code.
+a0|acorn0|Acorn VDU Driver Mode 0:\
+	:cl=^V\200^S^A^B\200\200\200:\
+	:is=^C^F^D^O^V\200^S^A^B\200\200\200:\
+	:tc=acorn_generic
+
+ag|acorn_generic|Acorn Generic VDU driver:\
+	:li#32:\
+	:co#80:\
+	:am:\
+	:bs:\
+	:bw:\
+	:bl=^G:\
+	:ce=^W^H^E^F\200\200\200\200\200\200:\
+	:cl=^L:\
+	:cm=^_%r%.%.:\
+	:ho=^^:\
+	:le=\010:\
+	:cr=\015:\
+	:me=^W^Q^E\200\200\200\200\200\200\200:\
+	:mr=^W^Q^E\200\200\200\200\200\200\200:\
+	:sb=^W^G^A^B\200\200\200\200\200\200:\
+	:se=^W^Q^E\200\200\200\200\200\200\200:\
+	:sf=^W^G^A^C\200\200\200\200\200\200:\
+	:so=^W^Q^E\200\200\200\200\200\200\200:\
+	:sr=^W^G^A^B\200\200\200\200\200\200:\
+	:up=^K:\
+	:vb=^R^C^G^Y^D\200\200\200\200^Ye\200^E\200^D^Ye\200\200\200\200:\
+	:vi=^W^A\200\200\200\200\200\200\200\200:\
+	:ve=^W^A^A\200\200\200\200\200\200\200:\
+	:ku=\317:\
+	:kd=\316:\
+	:kl=\314:\
+	:kr=\315:\
+	:kP=\337:\
+	:kN=\336:\
+	:kh=\036:\
+	:kH=\313:\
+	:su=\337:\
+	:sd=\336:\
+	:#4=\334:\
+	:%i=\335:\
+	:k1=\301:\
+	:k2=\302:\
+	:k3=\303:\
+	:k4=\304:\
+	:k5=\305:\
+	:k6=\306:\
+	:k7=\307:\
+	:k8=\310:\
+	:k9=\311:\
+	:F1=\321:\
+	:F2=\322:\
+	:F3=\323:\
+	:F4=\324:\
+	:F5=\325:\
+	:F6=\326:\
+	:F7=\327:\
+	:F8=\330:\
+	:F9=\331
+
+#
+# END OF TERMCAP
+#
--- /dev/null
+++ b/lib/vimfiles/tools/README.txt
@@ -1,0 +1,35 @@
+Some tools that can be used with Vim:
+
+blink.c:	C program to make the cursor blink in an xterm.
+
+ccfilter*:	C program to filter the output of a few compilers to a common
+		QuickFix format.
+
+efm_filter.*:	Perl script to filter compiler messages to QuickFix format.
+
+efm_perl.pl:	Perl script to filter error messages from the Perl interpreter
+		for use with Vim quickfix mode.
+
+mve.*		Awk script to filter error messages to QuickFix format.
+
+pltags.pl:	Perl script to create a tags file from Perl scripts.
+
+ref:		Shell script for the K command.
+
+shtags.*:	Perl script to create a tags file from a shell script.
+
+vim132:		Shell script to edit in 132 column mode on vt100 compatible
+		terminals.
+
+vimm:		Shell script to start Vim on a DEC terminal with mouse
+		enabled.
+
+vimspell.*:	Shell script for highlighting spelling mistakes.
+
+vim_vs_net.cmd: MS-Windows command file to use Vim with MS Visual Studio 7 and
+		later.
+
+xcmdsrv_client.c:  Example for a client program that communicates with a Vim
+		   server through the X-Windows interface.
+
+[xxd (and tee for OS/2) can be found in the src directory]
--- /dev/null
+++ b/lib/vimfiles/tools/blink.c
@@ -1,0 +1,21 @@
+/*
+ * An extremely simple program to make the cursor blink in an xterm.
+ * This is useful when the cursor is hard to spot in a highlighted file.
+ * Start in the background: "blink&"  Stop by killing it.
+ * Bram Moolenaar  980109  (based on an idea from John Lange).
+ */
+
+#include <stdio.h>
+
+main()
+{
+	while (1)
+	{
+		printf("\e[?25h");
+		fflush(stdout);
+		usleep(400000);		/* on time */
+		printf("\e[?25l");
+		fflush(stdout);
+		usleep(250000);		/* off time */
+	}
+}
--- /dev/null
+++ b/lib/vimfiles/tools/ccfilter.1
@@ -1,0 +1,93 @@
+.TH ccfilter 1 "01-Apr-97"
+.SH NAME
+ccfilter \- a compiler's output filter for vim quickfix
+.SH SYNOPSIS
+ccfilter [
+.B <options>
+]
+.SH DESCRIPTION
+The ccfilter utility "filters" the output of several compilers
+and makers (make/gmake) from several platforms (see NOTES below)
+to a standardized format which easily fits in vim's quickfix
+feature. For further details, see in vim ":help quickfix".
+.PP
+ccfilter reads
+.B 'stdin'
+and outputs to
+.B 'stdout'
+\.
+.PP
+The need for ccfilter is clear, as some compilers have irregular
+and/or multiple line error messages (with the relevant information on
+line 2), which makes it impossible for the errorformat to correctly
+display them !
+
+When working on different platforms, and with different compilers,
+ccfilter eases the utilization of quickfix, due to it's standardized
+output, allowing to have in .vimrc a plain
+.br
+.B \ \ \ \ :set\ errorformat=%f:%l:%c:%t:%m
+
+.SH USAGE
+When using ccfilter, one would include the following lines in .vimrc:
+.br
+.B \ \ \ \ :set shellpipe=\\\\|&ccfilter\\\\>
+.br
+.B \ \ \ \ :set errorformat=%f:%l:%c:%t:%m
+
+.SH OPTIONS
+.TP 16
+-c
+Decrement column by one. This may be needed, depending on
+the compiler being used.
+.TP
+-r
+Decrement row by one.  This may be needed, depending on
+the compiler being used.
+.TP
+-v
+Verbose (Outputs also invalid lines).
+This option makes ccfilter output also the lines that
+couldn't be correctly parsed. This is used mostly for
+ccfilter debugging.
+.TP
+-o <COMPILER>
+Treat input as <COMPILER>'s output.
+Even when configuring ccfilter to assume a default
+COMPILER, sometimes it's helpful to be able to specify
+the COMPILER used to generate ccfilter's input.
+For example, when cross-compiling on a network from a
+single machine.
+.TP
+-h
+Shows a brief help, describing the configured default COMPILER
+and the valid parameters for COMPILER.
+
+.SH NOTES
+Currently, ccfilter accepts output from several compilers, as
+described below:
+.TP 10
+GCC
+GCC compiler
+.TP
+AIX
+AIX's C compiler
+.TP
+ATT
+AT&T/NCR's High Performance C Compiler
+.TP
+IRIX
+IRIX's MIPS/MIPSpro C compiler
+.TP
+SOLARIS
+SOLARIS's SparcWorks C compiler
+.TP
+HPUX
+HPUX's C compiler
+
+.SH AUTHOR
+.B ccfilter
+was developed by
+.B Pablo Ariel Kohan
+.BR
+.B mailto:pablo@memco.co.il
--- /dev/null
+++ b/lib/vimfiles/tools/ccfilter.c
@@ -1,0 +1,326 @@
+/* ======================================================================= */
+/*  Project : VIM							   */
+/*  Module  : ccfilter				    Version: 02.01.01	   */
+/*  File    : ccfilter.c						   */
+/*  Purpose : Filter gmake/cc output into a standardized form		   */
+/* ======================================================================= */
+/*	   Created On: 12-Sep-95 20:32					   */
+/*  Last modification: 03-Feb-98					   */
+/*  -e option added by Bernd Feige					   */
+/* ======================================================================= */
+/*  Copyright :								   */
+/*     This source file is copyright (c) to Pablo Ariel Kohan		   */
+/* ======================================================================= */
+#define __CCFILTER_C__
+
+#include <ctype.h>
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+
+#define LINELENGTH 2048
+
+/* Collector(s) */
+char	       Line[LINELENGTH];
+char	       Line2[LINELENGTH];
+/* Components */
+char	       FileName[1024];
+char	       BasePath[1024];
+char	       CWD[1024];
+unsigned long  Row;
+unsigned long  Col;
+char	       Severity;
+char	       Reason[LINELENGTH];
+
+#define COMPILER_UNKNOWN    0
+#define COMPILER_GCC	    1
+#define COMPILER_AIX	    2
+#define COMPILER_ATT	    3
+#define COMPILER_IRIX	    4
+#define COMPILER_SOLARIS    5
+#define COMPILER_HPUX	    6
+
+char	*COMPILER_Names[][2] =
+    {
+      /* Name		 Description */
+      { "N/A",		""						},
+      { "GCC",		"GCC compiler"					},
+      { "AIX",		"AIX's C compiler"				},
+      { "ATT",		"AT&T/NCR's High Performance C Compiler"	},
+      { "IRIX",		"IRIX's MIPS/MIPSpro C compiler"		},
+      { "SOLARIS",	"SOLARIS's SparcWorks C compiler"		},
+      { "HPUX",		"HPUX's C compiler"				}
+    };
+#define COMPILER_QTY (sizeof(COMPILER_Names)/sizeof(COMPILER_Names[0]))
+
+#if   defined(_GCC)
+#			define COMPILER_DEFAULT COMPILER_GCC
+#elif defined(_AIX)
+#			define COMPILER_DEFAULT COMPILER_AIX
+#elif defined(_ATT)
+#			define COMPILER_DEFAULT COMPILER_ATT
+#elif defined(_IRIX)
+#			define COMPILER_DEFAULT COMPILER_IRIX
+#elif defined(_SOLARIS)
+#			define COMPILER_DEFAULT COMPILER_SOLARIS
+#elif defined(_HPUX)
+#			define COMPILER_DEFAULT COMPILER_HPUX
+#else
+#			define COMPILER_DEFAULT COMPILER_UNKNOWN
+#endif
+
+const char USAGE[] =
+"ccfilter  v2.1              (c)1994-1997 by Pablo Ariel Kohan\n"
+"Filter Out compiler's output, and converts it to fit VIM\n\n"
+"Usage:\n"
+"  ccfilter [<options>]\n"
+"Where: <options> is one or more of:\n"
+"  -c              Decrement column by one\n"
+"  -r              Decrement row by one\n"
+"  -e              Echo stdin to stderr\n"
+"  -v              Verbose (Outputs also invalid lines)\n"
+"  -o <COMPILER>   Treat input as <COMPILER>'s output\n"
+"                  Note: COMPILER may be preceded by an _\n"
+"  -h              This usage.\n";
+
+
+int ShowUsage( char *szError )
+{ int i;
+
+  fprintf( stderr, USAGE );
+
+  fprintf( stderr, "Current default <COMPILER>: %s\n",
+		   COMPILER_Names[COMPILER_DEFAULT][0] );
+
+  fprintf( stderr, "Acceptable parameters for <COMPILER> are:\n" );
+  for (i=1; i < COMPILER_QTY; i++)
+      fprintf( stderr, "     %-15.15s     %s\n",
+		       COMPILER_Names[i][0],
+		       COMPILER_Names[i][1] );
+  fprintf(stderr, szError);
+  return 0;
+}
+
+char *echogets(char *s, int echo) {
+ char * const retval=fgets(s, LINELENGTH, stdin);
+ if (echo!=0 && retval!=NULL) {
+  fputs(retval, stderr);
+ }
+ return retval;
+}
+
+int main( int argc, char *argv[] )
+{ int   rv, i, j, ok;
+  int   stay;
+  int   prefetch;
+  char *p;
+  int   dec_col = 0; /* Decrement column value by 1 */
+  int   dec_row = 0; /* Decrement row    value by 1 */
+  int   echo = 0;    /* Echo stdin to stderr */
+  int   verbose = 0; /* Include Bad Formatted Lines */
+  int   CWDlen;
+  int   COMPILER = COMPILER_DEFAULT;
+
+  getcwd( CWD, sizeof(CWD) );
+  CWDlen = strlen(CWD);
+
+  for (i=1; i<argc; i++)
+    {
+      if (argv[i][0] != '-')
+	return ShowUsage("");
+      switch ( argv[i][1] )
+	{
+	  case 'c':
+	    dec_col = 1;
+	    break;
+	  case 'r':
+	    dec_row = 1;
+	    break;
+	  case 'e':
+	    echo = 1;
+	    break;
+	  case 'v':
+	    verbose = 1;
+	    break;
+	  case 'o':
+	      {
+		if (i+1 >= argc)
+		    return ShowUsage("Error: Missing parameter for -o\n");
+		i++;
+		COMPILER = -1;
+		for (j=1; j<COMPILER_QTY; j++)
+		    if (  (strcmp(argv[i], COMPILER_Names[j][0]) == 0) ||
+			  ( (argv[i][0] == '_') &&
+			    (strcmp(&argv[i][1], COMPILER_Names[j][0]) == 0) )	)
+			COMPILER = j;
+		if (COMPILER == -1)
+		    return ShowUsage("Error: Invalid COMPILER specified\n");
+	      }
+	    break;
+	  case 'h':
+	    return ShowUsage("");
+	  default:
+	    return ShowUsage("Error: Invalid option\n");
+	}
+    }
+  if (COMPILER == 0)
+      return ShowUsage("Error: COMPILER must be specified in this system\n");
+
+  stay	   = ( echogets(Line, echo) != NULL );
+  prefetch = 0;
+
+  while( stay )
+    {
+      *FileName = 0;
+      Row	= 0;
+      Col	= 0;
+      Severity	= ' ';
+      *Reason	= 0;
+      ok	= 0;
+      switch (COMPILER)
+	{
+	  case COMPILER_GCC:
+	    Severity = 'e';
+#ifdef GOTO_FROM_WHERE_INCLUDED
+	    rv = sscanf( Line, "In file included from %[^:]:%u:",
+			       FileName, &Row );
+	    if ( rv == 2 )
+	      {
+		ok = (echogets(Reason, echo) != NULL);
+	      }
+	    else
+#endif
+	      {
+		if ((rv = sscanf( Line, "%[^:]:%u: warning: %[^\n]",
+				   FileName, &Row, Reason ))==3) {
+		 Severity = 'w';
+		} else {
+		rv = sscanf( Line, "%[^:]:%u: %[^\n]",
+				   FileName, &Row, Reason );
+		}
+		ok = ( rv == 3 );
+	      }
+	    Col = (dec_col ? 1 : 0 );
+	    break;
+	  case COMPILER_AIX:
+	    rv = sscanf( Line, "\"%[^\"]\", line %u.%u: %*s (%c) %[^\n]",
+			       FileName, &Row, &Col, &Severity, Reason );
+	    ok = ( rv == 5 );
+	    break;
+	  case COMPILER_HPUX:
+	    rv = sscanf( Line, "cc: \"%[^\"]\", line %u: %c%*[^:]: %[^\n]",
+			       FileName, &Row, &Severity, Reason );
+	    ok = ( rv == 4 );
+	    Col = (dec_col ? 1 : 0 );
+	    break;
+	  case COMPILER_SOLARIS:
+	    rv = sscanf( Line, "\"%[^\"]\", line %u: warning: %[^\n]",
+			       FileName, &Row, Reason );
+	    Severity = 'w';
+	    ok = ( rv == 3 );
+	    if ( rv != 3 )
+	      {
+		rv = sscanf( Line, "\"%[^\"]\", line %u: %[^\n]",
+				   FileName, &Row, Reason );
+		Severity = 'e';
+		ok = ( rv == 3 );
+	      }
+	    Col = (dec_col ? 1 : 0 );
+	    break;
+	  case COMPILER_ATT:
+	    rv	 = sscanf( Line, "%c \"%[^\"]\",L%u/C%u%*[^:]:%[^\n]",
+				 &Severity, FileName, &Row, &Col, Reason );
+	    ok = ( rv == 5 );
+
+	    if (rv != 5)
+	      { rv   = sscanf( Line, "%c \"%[^\"]\",L%u/C%u: %[^\n]",
+				     &Severity, FileName, &Row, &Col, Reason );
+		ok = ( rv == 5 );
+	      }
+
+	    if (rv != 5)
+	      { rv  = sscanf( Line, "%c \"%[^\"]\",L%u: %[^\n]",
+				   &Severity, FileName, &Row, Reason );
+		ok = ( rv == 4 );
+		Col = (dec_col ? 1 : 0 );
+	      }
+
+	    stay = (echogets(Line2, echo) != NULL);
+	    while ( stay && (Line2[0] == '|') )
+	      { for (p=&Line2[2]; (*p) && (isspace(*p)); p++);
+		strcat( Reason, ": " );
+		strcat( Reason, p );
+		Line2[0] = 0;
+		stay = (echogets(Line2, echo) != NULL);
+	      }
+	    prefetch = 1;
+	    strcpy( Line, Line2 );
+	    break;
+	  case COMPILER_IRIX:
+	    Col       = 1;
+	    prefetch  = 0;
+	    rv	      = 0;
+	    ok	      = 0;
+	    if ( !strncmp(Line, "cfe: ", 5) )
+	      { p = &Line[5];
+		Severity = tolower(*p);
+		p = strchr( &Line[5], ':' );
+		if (p == NULL)
+		  { ok = 0;
+		  }
+		 else
+		  {
+		    rv = sscanf( p+2, "%[^:]: %u: %[^\n]",
+				 FileName, &Row, Reason );
+		    if (rv != 3)
+		      rv = sscanf( p+2, "%[^,], line %u: %[^\n]",
+				   FileName, &Row, Reason );
+		    ok = ( rv == 3 );
+		  }
+
+		if (ok)
+		  { prefetch = 1;
+		    stay = (echogets(Line, echo) != NULL);
+		    if (Line[0] == ' ')
+		      stay = (echogets(Line2, echo) != NULL);
+		    if (  (Line2[0] == ' ') &&
+			  ( (Line2[1] == '-') || (Line2[1] == '^') )  )
+		      { Col = strlen(Line2)-1;
+			prefetch = 0;
+		      }
+		     else
+		      { strcat( Line, "\n" );
+			strcat( Line, Line2 );
+		      }
+		  }
+	      }
+	    break;
+	}
+      if (dec_col) Col--;
+      if (dec_row) Row--;
+      if (!ok)
+	{
+	  if ( Line[0] == 'g' )
+	      p = &Line[1];
+	  else
+	      p = &Line[0];
+	  ok = sscanf( p, "make[%*d]: Entering directory `%[^']",
+		       BasePath );
+	  if (verbose)
+	    printf( "[%u]?%s\n", ok, Line );
+	}
+       else
+	{
+	  for (p=Reason; (*p) && (isspace(*p)); p++);
+	  if ( BasePath[CWDlen] == 0 )
+	      printf( "%s:%u:%u:%c:%s\n", FileName, Row, Col, Severity, p );
+	  else
+	    {
+	      printf( "%s/%s:%u:%u:%c:%s\n", &BasePath[CWDlen+1], FileName, Row, Col, Severity, p );
+	    }
+	}
+      if (!prefetch)
+	stay = ( echogets(Line, echo) != NULL );
+    }
+  return 0;
+}
--- /dev/null
+++ b/lib/vimfiles/tools/ccfilter_README.txt
@@ -1,0 +1,91 @@
+COMPILING AND INSTALLING:
+=========================
+
+To compile ccfilter, you can just do a plain:
+    cc ccfilter.c -o ccfilter
+Though, it may be wise to have your default compiler defined,
+so you would normally compile it with one of the following:
+    cc -D_GCC     ccfilter.c -o ccfilter
+    cc -D_AIX     ccfilter.c -o ccfilter
+    cc -D_ATT     ccfilter.c -o ccfilter
+    cc -D_IRIX    ccfilter.c -o ccfilter
+    cc -D_SOLARIS ccfilter.c -o ccfilter
+    cc -D_HPUX    ccfilter.c -o ccfilter
+You can then copy ccfilter to it's target destination (i.e: /usr/local/bin).
+The man page ccfilter.1 has to be copied to somewhere in your MANPATH,
+under a man1 directory (i.e: /usr/local/man/man1).
+
+
+SUPPORTED COMPILERS/PORTING NOTES:
+==================================
+
+The supported formats for the different compilers are described below:
+In this section, meta-names are used as place-holders in the line
+formats: <FILE> <ROW> <COL> <SEVERITY> <REASON> <>
+The <> denotes ignored text.
+Line formats are delimited by the ^ (caret) symbol.
+
+0)  Special case: "gmake directory change" lines:
+    Lines with a format like:
+      ^gmake[<NUM>]: Entering directory `<DIR>'^
+    are used to follow the directory changes during the make process,
+    providing in the <FILE> part, a relative (if possible) directory
+    path to the erroneous file.
+
+
+1)  GCC:
+    Recognized lines are of the format:
+    - ^In file included from <FILE>:<ROW>:^
+      Line following this one is used as <REASON>
+      <SEVERITY> is always 'e' (error)
+      <COL> is always '0'
+
+    - ^<FILE>:<ROW>:<REASON>^
+      <SEVERITY> is always 'e' (error)
+      <COL> is always '0'
+
+
+2)  AIX:
+    Recognized lines are of the format:
+    - ^"<FILE>", line <ROW>.<COL>: <> (<SEVERITY>) <REASON>",
+
+
+3)  HPUX:
+    Recognized lines are of the format:
+    - ^cc: "<FILE>", line <ROW>: <SEVERITY>: <REASON>^
+      <COL> is always '0'
+
+
+4)  SOLARIS:
+    Recognized lines are of the format:
+    - ^"<FILE>", line <ROW>: warning: <REASON>^
+      This assumes <SEVERITY> is "W"
+      <COL> is always '0'
+
+    - ^"<FILE>", line <ROW>: <REASON>^
+      This assumes <SEVERITY> is "E"
+      <COL> is always '0'
+
+
+5)  ATT / NCR:
+    Recognized lines are of the format:
+    - ^<SEVERITY> "<FILE>",L<ROW>/C<COL><>:<REASON>^
+			 or
+    - ^<SEVERITY> "<FILE>",L<ROW>/C<COL>:<REASON>^
+      Following lines beginning with a pipe (|) are continuation
+      lines, and are therefore appended to the <REASON>
+
+    - ^<SEVERITY> "<FILE>",L<ROW>:<REASON>^
+      <COL> is '0'
+      Following lines beginning with a pipe (|) are continuation
+      lines, and are therefore appended to the <REASON>
+
+
+6)  SGI-IRIX:
+    Recognized lines are of the format:
+    - ^cfe: <SEVERITY>: <FILE>: <ROW>: <REASON>^
+			 or
+      ^cfe: <SEVERITY>: <FILE>, line <ROW>: <REASON>^
+      Following lines beginning with a dash (-) are "column-bar"
+      that end with a caret in the column of the error. These lines
+      are analyzed to generate the <COL>.
--- /dev/null
+++ b/lib/vimfiles/tools/efm_filter.pl
@@ -1,0 +1,39 @@
+#!/usr/bin/env perl
+#
+# This program works as a filter that reads from stdin, copies to
+# stdout *and* creates an error file that can be read by vim.
+#
+# This program has only been tested on SGI, Irix5.3.
+#
+# Written by Ives Aerts in 1996. This little program is not guaranteed
+# to do (or not do) anything at all and can be freely used for
+# whatever purpose you can think of.
+
+$args = @ARGV;
+
+unless ($args == 1) {
+  die("Usage: vimccparse <output filename>\n");
+}
+
+$filename = @ARGV[0];
+open (OUT, ">$filename") || die ("Can't open file: \"$filename\"");
+
+while (<STDIN>) {
+  print;
+  if (   (/"(.*)", line (\d+): (e)rror\((\d+)\):/)
+      || (/"(.*)", line (\d+): (w)arning\((\d+)\):/) ) {
+    $file=$1;
+    $line=$2;
+    $errortype="\u$3";
+    $errornr=$4;
+    chop($errormsg=<STDIN>);
+    $errormsg =~ s/^\s*//;
+    $sourceline=<STDIN>;
+    $column=index(<STDIN>, "^") - 1;
+
+    print OUT "$file>$line:$column:$errortype:$errornr:$errormsg\n";
+  }
+}
+
+close(OUT);
+exit(0);
--- /dev/null
+++ b/lib/vimfiles/tools/efm_filter.txt
@@ -1,0 +1,31 @@
+[adopted from a message that Ives posted in the Vim mailing list]
+
+Some compilers produce an error message that cannot be handled with
+'errorformat' in Vim.  Following is an example of a Perl script that
+translates one error message into something that Vim understands.
+
+
+The compiler that generates this kind of error messages (4 lines):
+
+"/tmp_mnt/cm/src/apertos/MoU/MetaCore/MetaCore/common/src/MetaCoreImp_M.cc",
+line 50: error(3114):
+	   identifier "PRIMITIVE_M" is undefined
+	 return(ExecuteCore(PRIMITIVE_M,
+
+You can find a small perl program at the end.
+The way I use it is:
+
+:set   errorformat=%f>%l:%c:%t:%n:%m
+:set   makeprg=clearmake\ -C\ gnu
+:set   shellpipe=2>&1\|\ vimccparse
+
+If somebody thinks this is useful: feel free to do whatever you can think
+of with this code.
+
+-Ives
+____________________________________________________________
+Ives Aerts (SW Developer)	    Sony Telecom Europe
+ives@sonytel.be			    St.Stevens Woluwestr. 55
+`Death could create most things,    B-1130 Brussels, Belgium
+ except for plumbing.'		    PHONE : +32 2 724 19 67
+	 (Soul Music - T.Pratchett) FAX   : +32 2 726 26 86
--- /dev/null
+++ b/lib/vimfiles/tools/efm_perl.pl
@@ -1,0 +1,153 @@
+#!/usr/bin/perl -w
+
+# vimparse.pl - Reformats the error messages of the Perl interpreter for use
+# with the quickfix mode of Vim
+#
+# Copyright (�) 2001 by J�rg Ziefle <joerg.ziefle@gmx.de>
+# You may use and distribute this software under the same terms as Perl itself.
+#
+# Usage: put one of the two configurations below in your ~/.vimrc (without the
+# description and '# ') and enjoy (be sure to adjust the paths to vimparse.pl
+# before):
+#
+# Program is run interactively with 'perl -w':
+#
+# set makeprg=$HOME/bin/vimparse.pl\ %\ $*
+# set errorformat=%f:%l:%m
+#
+# Program is only compiled with 'perl -wc':
+#
+# set makeprg=$HOME/bin/vimparse.pl\ -c\ %\ $*
+# set errorformat=%f:%l:%m
+#
+# Usage:
+#	vimparse.pl [-c] [-f <errorfile>] <programfile> [programargs]
+#
+#		-c	compile only, don't run (perl -wc)
+#		-f	write errors to <errorfile>
+#
+# Example usages:
+#	* From the command line:
+#		vimparse.pl program.pl
+#
+#		vimparse.pl -c -f errorfile program.pl
+#		Then run vim -q errorfile to edit the errors with Vim.
+#
+#	* From Vim:
+#		Edit in Vim (and save, if you don't have autowrite on), then
+#		type ':mak' or ':mak args' (args being the program arguments)
+#		to error check.
+#
+# Version history:
+#	0.2 (04/12/2001):
+#		* First public version (sent to Bram)
+#		* -c command line option for compiling only
+#		* grammatical fix: 'There was 1 error.'
+#		* bug fix for multiple arguments
+#		* more error checks
+#		* documentation (top of file, &usage)
+#		* minor code clean ups
+#	0.1 (02/02/2001):
+#		* Initial version
+#		* Basic functionality
+#
+# Todo:
+#	* test on more systems
+#	* use portable way to determine the location of perl ('use Config')
+#	* include option that shows perldiag messages for each error
+#	* allow to pass in program by STDIN
+#	* more intuitive behaviour if no error is found (show message)
+#
+# Tested under SunOS 5.7 with Perl 5.6.0.  Let me know if it's not working for
+# you.
+
+use strict;
+use Getopt::Std;
+
+use vars qw/$opt_c $opt_f $opt_h/; # needed for Getopt in combination with use strict 'vars'
+
+use constant VERSION => 0.2;
+
+getopts('cf:h');
+
+&usage if $opt_h; # not necessarily needed, but good for further extension
+
+if (defined $opt_f) {
+
+    open FILE, "> $opt_f" or do {
+	warn "Couldn't open $opt_f: $!.  Using STDOUT instead.\n";
+	undef $opt_f;
+    };
+
+};
+
+my $handle = (defined $opt_f ? \*FILE : \*STDOUT);
+
+(my $file = shift) or &usage; # display usage if no filename is supplied
+my $args = (@ARGV ? ' ' . join ' ', @ARGV : '');
+
+my @lines = `perl @{[defined $opt_c ? '-c ' : '' ]} -w "$file$args" 2>&1`;
+
+my $errors = 0;
+foreach my $line (@lines) {
+
+    chomp($line);
+    my ($file, $lineno, $message, $rest);
+
+    if ($line =~ /^(.*)\sat\s(.*)\sline\s(\d+)(\.|,\snear\s\".*\")$/) {
+
+	($message, $file, $lineno, $rest) = ($1, $2, $3, $4);
+	$errors++;
+	$message .= $rest if ($rest =~ s/^,//);
+	print $handle "$file:$lineno:$message\n";
+
+    } else { next };
+
+}
+
+if (defined $opt_f) {
+
+    my $msg;
+    if ($errors == 1) {
+
+	$msg = "There was 1 error.\n";
+
+    } else {
+
+	$msg = "There were $errors errors.\n";
+
+    };
+
+    print STDOUT $msg;
+    close FILE;
+    unlink $opt_f unless $errors;
+
+};
+
+sub usage {
+
+    (local $0 = $0) =~ s/^.*\/([^\/]+)$/$1/; # remove path from name of program
+    print<<EOT;
+Usage:
+	$0 [-c] [-f <errorfile>] <programfile> [programargs]
+
+		-c	compile only, don't run (executes 'perl -wc')
+		-f	write errors to <errorfile>
+
+Examples:
+	* At the command line:
+		$0 program.pl
+		Displays output on STDOUT.
+
+		$0 -c -f errorfile program.pl
+		Then run 'vim -q errorfile' to edit the errors with Vim.
+
+	* In Vim:
+		Edit in Vim (and save, if you don't have autowrite on), then
+		type ':mak' or ':mak args' (args being the program arguments)
+		to error check.
+EOT
+
+    exit 0;
+
+};
--- /dev/null
+++ b/lib/vimfiles/tools/mve.awk
@@ -1,0 +1,23 @@
+#!/usr/bin/nawk -f
+#
+# Change "nawk" to "awk" or "gawk" if you get errors.
+#
+# Make Vim Errors
+# Processes errors from cc for use by Vim's quick fix tools
+# specifically it translates the ---------^ notation to a
+# column number
+#
+BEGIN { FS="[:,]" }
+
+/^cfe/ { file=$3
+	 msg=$5
+	 split($4,s," ")
+	 line=s[2]
+}
+
+# You may have to substitute a tab character for the \t here:
+/^[\t-]*\^/ {
+	p=match($0, ".*\\^" )
+	col=RLENGTH-2
+	printf("%s, line %d, col %d : %s\n", file,line,col,msg)
+}
--- /dev/null
+++ b/lib/vimfiles/tools/mve.txt
@@ -1,0 +1,20 @@
+[ The mve awk script was posted on the vimdev mailing list ]
+
+From: jimmer@barney.mdhc.mdc.com (J. McGlasson)
+Date: Mon, 31 Mar 1997 13:16:49 -0700 (Mar)
+
+My compiler (SGI MIPSpro C compiler - IRIX 6.4) works like this.
+I have written a script mve (make vim errors), through which I pipe my make
+output, which translates output of the following form:
+
+cfe: Error: syntax.c, line 4: Syntax Error
+     int i[12;
+ ------------^
+
+into:
+
+ cl.c, line 4, col 12 :  Syntax Error
+
+(in vim notation:  %f, line %l, col %c : %m)
+
+You might be able to tailor this for your compiler's output.
--- /dev/null
+++ b/lib/vimfiles/tools/pltags.pl
@@ -1,0 +1,300 @@
+#!/usr/bin/env perl
+
+# pltags - create a tags file for Perl code, for use by vi(m)
+#
+# Distributed with Vim <http://www.vim.org/>, latest version always available
+# at <http://www.mscha.com/mscha.html?pltags#tools>
+#
+# Version 2.3, 28 February 2002
+#
+# Written by Michael Schaap <pltags@mscha.com>.  Suggestions for improvement
+# are very welcome!
+#
+# This script will not work with Perl 4 or below!
+#
+# Revision history:
+#  1.0  1997?     Original version, quickly hacked together
+#  2.0  1999?     Completely rewritten, better structured and documented,
+#		  support for variables, packages, Exuberant Ctags extensions
+#  2.1	Jun 2000  Fixed critical bug (typo in comment) ;-)
+#		  Support multiple level packages (e.g. Archive::Zip::Member)
+#  2.2	Jul 2001  'Glob' wildcards - especially useful under Windows
+#		  (thanks to Serge Sivkov and Jason King)
+#		  Bug fix: reset package name for each file
+#  2.21 Jul 2001  Oops... bug in variable detection (/local../ -> /^local.../)
+#  2.3	Feb 2002  Support variables declared with "our"
+#		  (thanks to Lutz Mende)
+
+# Complain about undeclared variables
+use strict;
+
+# Used modules
+use Getopt::Long;
+
+# Options with their defaults
+my $do_subs = 1;    # --subs, --nosubs    include subs in tags file?
+my $do_vars = 1;    # --vars, --novars    include variables in tags file?
+my $do_pkgs = 1;    # --pkgs, --nopkgs    include packages in tags file?
+my $do_exts = 1;    # --extensions, --noextensions
+		    #			  include Exuberant Ctags extensions
+
+# Global variables
+my $VERSION = "2.21";	# pltags version
+my $status = 0;		# GetOptions return value
+my $file = "";		# File being processed
+my @tags = ();		# List of produced tags
+my $is_pkg = 0;		# Are we tagging a package?
+my $has_subs = 0;	# Has this file any subs yet?
+my $package_name = "";	# Name of current package
+my $var_continues = 0;	# Variable declaration continues on last line
+my $line = "";		# Current line in file
+my $stmt = "";		# Current Perl statement
+my @vars = ();		# List of variables in declaration
+my $var = "";		# Variable in declaration
+my $tagline = "";	# Tag file line
+
+# Create a tag file line and push it on the list of found tags
+sub MakeTag($$$$$)
+{
+    my ($tag,		# Tag name
+	$type,		# Type of tag
+	$is_static,	# Is this a static tag?
+	$file,		# File in which tag appears
+	$line) = @_;	# Line in which tag appears
+
+    my $tagline = "";   # Created tag line
+
+    # Only process tag if not empty
+    if ($tag)
+    {
+	# Get rid of \n, and escape / and \ in line
+	chomp $line;
+	$line =~ s/\\/\\\\/g;
+	$line =~ s/\//\\\//g;
+
+	# Create a tag line
+	$tagline = "$tag\t$file\t/^$line\$/";
+
+	# If we're told to do so, add extensions
+	if ($do_exts)
+	{
+	    $tagline .= ";\"\t$type"
+			    . ($is_static ? "\tfile:" : "")
+			    . ($package_name ? "\tclass:$package_name" : "");
+	}
+
+	# Push it on the stack
+	push (@tags, $tagline);
+    }
+}
+
+# Parse package name from statement
+sub PackageName($)
+{
+    my ($stmt) = @_;    # Statement
+
+    # Look for the argument to "package".  Return it if found, else return ""
+    if ($stmt =~ /^package\s+([\w:]+)/)
+    {
+	my $pkgname = $1;
+
+	# Remove any parent package name(s)
+	$pkgname =~ s/.*://;
+	return $pkgname;
+    }
+    else
+    {
+	return "";
+    }
+}
+
+# Parse sub name from statement
+sub SubName($)
+{
+    my ($stmt) = @_;    # Statement
+
+    # Look for the argument to "sub".  Return it if found, else return ""
+    if ($stmt =~ /^sub\s+([\w:]+)/)
+    {
+	my $subname = $1;
+
+	# Remove any parent package name(s)
+	$subname =~ s/.*://;
+	return $subname;
+    }
+    else
+    {
+	return "";
+    }
+}
+
+# Parse all variable names from statement
+sub VarNames($)
+{
+    my ($stmt) = @_;
+
+    # Remove my or local from statement, if present
+    $stmt =~ s/^(my|our|local)\s+//;
+
+    # Remove any assignment piece
+    $stmt =~ s/\s*=.*//;
+
+    # Now find all variable names, i.e. "words" preceded by $, @ or %
+    @vars = ($stmt =~ /[\$\@\%]([\w:]+)\b/g);
+
+    # Remove any parent package name(s)
+    map(s/.*://, @vars);
+
+    return (@vars);
+}
+
+############### Start ###############
+
+print "\npltags $VERSION by Michael Schaap <mscha\@mscha.com>\n\n";
+
+# Get options
+$status = GetOptions("subs!" => \$do_subs,
+		     "vars!" => \$do_vars,
+		     "pkgs!" => \$do_pkgs,
+		     "extensions!" => \$do_exts);
+
+# Usage if error in options or no arguments given
+unless ($status && @ARGV)
+{
+    print "\n" unless ($status);
+    print "  Usage: $0 [options] filename ...\n\n";
+    print "  Where options can be:\n";
+    print "    --subs (--nosubs)     (don't) include sub declarations in tag file\n";
+    print "    --vars (--novars)     (don't) include variable declarations in tag file\n";
+    print "    --pkgs (--nopkgs)     (don't) include package declarations in tag file\n";
+    print "    --extensions (--noextensions)\n";
+    print "                          (don't) include Exuberant Ctags / Vim style\n";
+    print "                          extensions in tag file\n\n";
+    print "  Default options: ";
+    print ($do_subs ? "--subs " : "--nosubs ");
+    print ($do_vars ? "--vars " : "--novars ");
+    print ($do_pkgs ? "--pkgs " : "--nopkgs ");
+    print ($do_exts ? "--extensions\n\n" : "--noextensions\n\n");
+    print "  Example: $0 *.pl *.pm ../shared/*.pm\n\n";
+    exit;
+}
+
+# Loop through files on command line - 'glob' any wildcards, since Windows
+# doesn't do this for us
+foreach $file (map { glob } @ARGV)
+{
+    # Skip if this is not a file we can open.  Also skip tags files and backup
+    # files
+    next unless ((-f $file) && (-r $file) && ($file !~ /tags$/)
+		 && ($file !~ /~$/));
+
+    print "Tagging file $file...\n";
+
+    $is_pkg = 0;
+    $package_name = "";
+    $has_subs = 0;
+    $var_continues = 0;
+
+    open (IN, $file) or die "Can't open file '$file': $!";
+
+    # Loop through file
+    foreach $line (<IN>)
+    {
+	# Statement is line with comments and whitespace trimmed
+	($stmt = $line) =~ s/#.*//;
+	$stmt =~ s/^\s*//;
+	$stmt =~ s/\s*$//;
+
+	# Nothing left? Never mind.
+	next unless ($stmt);
+
+	# This is a variable declaration if one was started on the previous
+	# line, or if this line starts with my or local
+	if ($var_continues or ($stmt =~/^my\b/)
+			    or ($stmt =~/^our\b/) or ($stmt =~/^local\b/))
+	{
+	    # The declaration continues if the line does not end with ;
+	    $var_continues = ($stmt !~ /;$/);
+
+	    # Loop through all variable names in the declaration
+	    foreach $var (VarNames($stmt))
+	    {
+		# Make a tag for this variable unless we're told not to.  We
+		# assume that a variable is always static, unless it appears
+		# in a package before any sub.	(Not necessarily true, but
+		# it's ok for most purposes and Vim works fine even if it is
+		# incorrect)
+		if ($do_vars)
+		{
+		    MakeTag($var, "v", (!$is_pkg or $has_subs), $file, $line);
+		}
+	    }
+	}
+
+	# This is a package declaration if the line starts with package
+	elsif ($stmt =~/^package\b/)
+	{
+	    # Get name of the package
+	    $package_name = PackageName($stmt);
+
+	    if ($package_name)
+	    {
+		# Remember that we're doing a package
+		$is_pkg = 1;
+
+		# Make a tag for this package unless we're told not to.  A
+		# package is never static.
+		if ($do_pkgs)
+		{
+		    MakeTag($package_name, "p", 0, $file, $line);
+		}
+	    }
+	}
+
+	# This is a sub declaration if the line starts with sub
+	elsif ($stmt =~/^sub\b/)
+	{
+	    # Remember that this file has subs
+	    $has_subs = 1;
+
+	    # Make a tag for this sub unless we're told not to.  We assume
+	    # that a sub is static, unless it appears in a package.  (Not
+	    # necessarily true, but it's ok for most purposes and Vim works
+	    # fine even if it is incorrect)
+	    if ($do_subs)
+	    {
+		MakeTag(SubName($stmt), "s", (!$is_pkg), $file, $line);
+	    }
+	}
+    }
+    close (IN);
+}
+
+# Do we have any tags?  If so, write them to the tags file
+if (@tags)
+{
+    # Add some tag file extensions if we're told to
+    if ($do_exts)
+    {
+	push (@tags, "!_TAG_FILE_FORMAT\t2\t/extended format/");
+	push (@tags, "!_TAG_FILE_SORTED\t1\t/0=unsorted, 1=sorted/");
+	push (@tags, "!_TAG_PROGRAM_AUTHOR\tMichael Schaap\t/mscha\@mscha.com/");
+	push (@tags, "!_TAG_PROGRAM_NAME\tpltags\t//");
+	push (@tags, "!_TAG_PROGRAM_VERSION\t$VERSION\t/supports multiple tags and extended format/");
+    }
+
+    print "\nWriting tags file.\n";
+
+    open (OUT, ">tags") or die "Can't open tags file: $!";
+
+    foreach $tagline (sort @tags)
+    {
+	print OUT "$tagline\n";
+    }
+
+    close (OUT);
+}
+else
+{
+    print "\nNo tags found.\n";
+}
--- /dev/null
+++ b/lib/vimfiles/tools/ref
@@ -1,0 +1,11 @@
+#!/bin/sh
+#
+# ref - Check spelling of the arguments
+#
+# Usage: ref word ..
+#
+# can be used for the K command of Vim
+#
+spell <<EOF
+$*
+EOF
--- /dev/null
+++ b/lib/vimfiles/tools/shtags.1
@@ -1,0 +1,61 @@
+.TH shtags 1 "local Utilities"
+.SH NAME
+shtags \- Create tags for shell scripts
+.SH SYNOPSIS
+.B shtags
+[\fI-mvw\fP] [\fI-t <file>\fP] [\fI-s <shell>\fP] <files>
+.SH DESCRIPTION
+\fBshtags\fP creates a \fBvi(1)\fP tags file for shell scripts - which
+essentially turns your code into a hypertext document. \fBshtags\fP
+attempts to create tags for all function and variable definitions,
+although this is a little difficult, because in most shell languages,
+variables don't need to be explicitly defined, and as such there is
+often no distinct "variable definition". If this is the case,
+\fBshtags\fP simply creates a tag for the first instance of a variable
+which is being set in a simple way, ie: \fIset x = 5\fP.
+.SH OPTIONS
+.IP "\fB-t <file>\fP"
+Name of tags file to create. (default is 'tags')
+.IP "\fB-s <shell>\fP"
+The name of the shell used by the script(s). By default,
+\fBshtags\fP tries to work out which is the appropriate shell for each
+file individually by looking at the first line of each file. This wont
+work however, if the script starts as a bourne shell script and tries
+to be clever about starting the shell it really wants.
+.b
+Currently supported shells are:
+.RS
+.IP \fBsh\fP
+Bourne Shell
+.IP \fBperl\fP
+Perl (versions 4 and 5)
+.IP \fBksh\fP
+Korn Shell
+.IP \fBtclsh\fP
+The TCL shell
+.IP \fBwish\fP
+The TK Windowing shell (same as tclsh)
+.RE
+
+.IP \fB-v\fP
+Include variable definitions (variables mentioned at the start of a line)
+.IP \fB-V\fP
+Print version information.
+.IP \fB-w\fP
+Suppress "duplicate tag" warning messages.
+.IP \fB-x\fP
+Explicitly create a new tags file. Normally new tags are merged with
+the old tags file.
+.PP
+\fBshtags\fP scans the specified files for subroutines and possibly
+variable definitions, and creates a \fBvi\fP style tags file.
+.SH FILES
+.IP \fBtags\fP
+A tags file contains a sorted list of tags, one tag per line. The
+format is the same as that used by \fBvi\fP(1)
+.SH AUTHOR
+Stephen Riehm
+.br
+sr@pc-plus.de
+.SH "SEE ALSO"
+ctags(1), etags(1), perl(1), tclsh(1), wish(1), sh(1), ksh(1).
--- /dev/null
+++ b/lib/vimfiles/tools/shtags.pl
@@ -1,0 +1,144 @@
+#!/usr/bin/env perl
+#
+# shtags: create a tags file for perl scripts
+#
+# Author:	Stephen Riehm
+# Last Changed:	96/11/27 19:46:06
+#
+# "@(#) shtags 1.1 by S. Riehm"
+#
+
+# obvious... :-)
+sub usage
+    {
+    print <<_EOUSAGE_ ;
+USAGE: $program [-kvwVx] [-t <file>] <files>
+    -t <file>	Name of tags file to create. (default is 'tags')
+    -s <shell>	Name of the shell language in the script
+    -v		Include variable definitions.
+		(variables mentioned at the start of a line)
+    -V		Print version information.
+    -w		Suppress "duplicate tag" warnings.
+    -x		Explicitly create a new tags file. Normally tags are merged.
+    <files>	List of files to scan for tags.
+_EOUSAGE_
+    exit 0
+    }
+
+sub version
+{
+    #
+    # Version information
+    #
+    @id = split( ', ', 'scripts/bin/shtags, /usr/local/, LOCAL_SCRIPTS, 1.1, 96/11/27, 19:46:06' );
+    $id[0] =~ s,.*/,,;
+    print <<_EOVERS;
+$id[0]:		$id[3]
+Last Modified:	@id[4,5]
+Component:	$id[1]
+Release:	$id[2]
+_EOVERS
+    exit( 1 );
+}
+
+#
+# initialisations
+#
+($program = $0) =~ s,.*/,,;
+require 'getopts.pl';
+
+#
+# parse command line
+#
+&Getopts( "t:s:vVwx" ) || &usage();
+$tags_file = $opt_t || 'tags';
+$explicit = $opt_x;
+$variable_tags = $opt_v;
+$allow_warnings = ! $opt_w;
+&version	  if $opt_V;
+&usage()	unless @ARGV != 0;
+
+# slurp up the existing tags. Some will be replaced, the ones that aren't
+# will be re-written exactly as they were read
+if( ! $explicit && open( TAGS, "< $tags_file" ) )
+    {
+    while( <TAGS> )
+	{
+	/^\S+/;
+	$tags{$&} = $_;
+	}
+    close( TAGS );
+    }
+
+#
+# for each line of every file listed on the command line, look for a
+# 'sub' definition, or, if variables are wanted aswell, look for a
+# variable definition at the start of a line
+#
+while( <> )
+    {
+    &check_shell($_), ( $old_file = $ARGV ) if $ARGV ne $old_file;
+    next unless $shell;
+    if( $shell eq "sh" )
+	{
+	next	unless /^\s*(((\w+)))\s*\(\s*\)/
+		    || ( $variable_tags && /^(((\w+)=))/ );
+	$match = $3;
+	}
+    if( $shell eq "ksh" )
+	{
+	# ksh
+	next	unless /^\s*function\s+(((\w+)))/
+		    || ( $variable_tags && /^(((\w+)=))/ );
+	$match = $3;
+	}
+    if( $shell eq "perl" )
+	{
+	# perl
+	next	unless /^\s*sub\s+(\w+('|::))?(\w+)/
+		    || /^\s*(((\w+))):/
+		    || ( $variable_tags && /^(([(\s]*[\$\@\%]{1}(\w+).*=))/ );
+	$match = $3;
+	}
+    if( $shell eq "tcl" )
+	{
+	next	unless /^\s*proc\s+(((\S+)))/
+		    || ( $variable_tags && /^\s*set\s+(((\w+)\s))/ );
+	$match = $3;
+	}
+    chop;
+    warn "$match - duplicate ignored\n"
+	if ( $new{$match}++
+	    || !( $tags{$match} = sprintf( "%s\t%s\t?^%s\$?\n", $match, $ARGV, $_ ) ) )
+	    && $allow_warnings;
+    }
+
+# write the new tags to the tags file - note that the whole file is rewritten
+open( TAGS, "> $tags_file" );
+foreach( sort( keys %tags ) )
+    {
+    print TAGS "$tags{$_}";
+    }
+close( TAGS );
+
+sub check_shell
+    {
+    local( $_ ) = @_;
+    # read the first line of a script, and work out which shell it is,
+    # unless a shell was specified on the command line
+    #
+    # This routine can't handle clever scripts which start sh and then
+    # use sh to start the shell they really wanted.
+    if( $opt_s )
+	{
+	$shell = $opt_s;
+	}
+    else
+	{
+	$shell = "sh"	if /^:$/ || /^#!.*\/bin\/sh/;
+	$shell = "ksh"	if /^#!.*\/ksh/;
+	$shell = "perl"	if /^#!.*\/perl/;
+	$shell = "tcl"  if /^#!.*\/wish/;
+	printf "Using $shell for $ARGV\n";
+	}
+    }
--- /dev/null
+++ b/lib/vimfiles/tools/vim132
@@ -1,0 +1,13 @@
+#!/bin/csh
+#
+# Shell script for use with UNIX
+# Starts up Vim with the terminal in 132 column mode
+# Only works on VT-100 terminals and lookalikes
+# You need to have a termcap entry "vt100-w". Same as vt100 but 132 columns.
+#
+set oldterm=$term
+echo "[?3h"
+setenv TERM vt100-w
+vim $*
+set term=$oldterm
+echo "[?3l"
--- /dev/null
+++ b/lib/vimfiles/tools/vim_vs_net.cmd
@@ -1,0 +1,24 @@
+@rem
+@rem To use this with Visual Studio .Net
+@rem Tools->External Tools...
+@rem Add
+@rem      Title     - Vim
+@rem      Command   - d:\files\util\vim_vs_net.cmd
+@rem      Arguments - +$(CurLine) $(ItemPath)
+@rem      Init Dir  - Empty
+@rem
+@rem Coutesy of Brian Sturk
+@rem
+@rem --remote-silent +%1 is a command +954, move ahead 954 lines
+@rem --remote-silent %2 full path to file
+@rem In Vim
+@rem    :h --remote-silent for mor details
+@rem
+@rem --servername VS_NET
+@rem This will create a new instance of vim called VS_NET.  So if you
+open
+@rem multiple files from VS, they will use the same instance of Vim.
+@rem This allows you to have multiple copies of Vim running, but you can
+@rem control which one has VS files in it.
+@rem
+start /b gvim.exe --servername VS_NET --remote-silent "%1"  "%2"
--- /dev/null
+++ b/lib/vimfiles/tools/vimm
@@ -1,0 +1,6 @@
+#!/bin/sh
+# enable DEC locator input model on remote terminal
+echo  "\033[1;2'z\033[1;3'{\c"
+vim "$@"
+# disable DEC locator input model on remote terminal
+echo  "\033[2;4'{\033[0'z\c"
--- /dev/null
+++ b/lib/vimfiles/tools/vimspell.sh
@@ -1,0 +1,54 @@
+#!/bin/sh
+#
+# Spell a file & generate the syntax statements necessary to
+# highlight in vim.  Based on a program from Krishna Gadepalli
+# <krishna@stdavids.picker.com>.
+#
+# I use the following mappings (in .vimrc):
+#
+#	noremap <F8> :so `vimspell.sh %`<CR><CR>
+#	noremap <F7> :syntax clear SpellErrors<CR>
+#
+# Neil Schemenauer <nascheme@ucalgary.ca>
+# March 1999
+#
+# Safe method for the temp file by Javier Fern�ndez-Sanguino_Pe+
+INFILE=$1
+tmp="${TMPDIR-/tmp}"
+OUTFILE=`mktemp -t vimspellXXXXXX || tempfile -p vimspell || echo none`
+# If the standard commands failed then create the file
+# since we cannot create a directory (we cannot remove it on exit)
+# create a file in the safest way possible.
+if test "$OUTFILE" = none; then
+        OUTFILE=$tmp/vimspell$$
+	[ -e $OUTFILE ] && { echo "Cannot use temporary file $OUTFILE, it already exists!; exit 1 ; } 
+        (umask 077; touch $OUTFILE)
+fi
+# Note the copy of vimspell cannot be deleted on exit since it is
+# used by vim, otherwise it should do this:
+# trap "rm -f $OUTFILE" 0 1 2 3 9 11 13 15
+
+
+#
+# local spellings
+#
+LOCAL_DICT=${LOCAL_DICT-$HOME/local/lib/local_dict}
+
+if [ -f $LOCAL_DICT ]
+then
+	SPELL_ARGS="+$LOCAL_DICT"
+fi
+
+spell $SPELL_ARGS $INFILE | sort -u |
+awk '
+      {
+	printf "syntax match SpellErrors \"\\<%s\\>\"\n", $0 ;
+      }
+
+END   {
+	printf "highlight link SpellErrors ErrorMsg\n\n" ;
+      }
+' > $OUTFILE
+echo "!rm $OUTFILE" >> $OUTFILE
+echo $OUTFILE
--- /dev/null
+++ b/lib/vimfiles/tools/vimspell.txt
@@ -1,0 +1,22 @@
+vimspell.sh
+===========
+
+This is a simple script to spell check a file and generate the syntax
+statements necessary to highlight the errors in vim.  It is based on a
+similar program by Krishna Gadepalli <krishna@stdavids.picker.com>.
+
+To use this script, first place it in a directory in your path.  Next,
+you should add some convenient key mappings.  I use the following (in
+.vimrc):
+
+	noremap <F8> :so `vimspell.sh %`<CR><CR>
+	noremap <F7> :syntax clear SpellErrors<CR>
+
+This program requires the old Unix "spell" command.  On my Debian
+system, "spell" is a wrapper around "ispell".  For better security,
+you should uncomment the line in the script that uses "tempfile" to
+create a temporary file.  As all systems don't have "tempfile" the
+insecure "pid method" is used.
+
+
+    Neil Schemenauer <nascheme@ucalgary.ca>
--- /dev/null
+++ b/lib/vimfiles/tools/xcmdsrv_client.c
@@ -1,0 +1,584 @@
+/* vi:set ts=8 sts=4 sw=4:
+ *
+ * VIM - Vi IMproved	by Bram Moolenaar
+ * X-Windows communication by Flemming Madsen
+ *
+ * Do ":help uganda"  in Vim to read copying and usage conditions.
+ * Do ":help credits" in Vim to see a list of people who contributed.
+ * See README.txt for an overview of the Vim source code.
+ *
+ * Client for sending commands to an '+xcmdsrv' enabled vim.
+ * This is mostly a de-Vimified version of if_xcmdsrv.c in vim.
+ * See that file for a protocol specification.
+ *
+ * You can make a test program with a Makefile like:
+ *  xcmdsrv_client: xcmdsrv_client.c
+ *	cc -o $@ -g -DMAIN -I/usr/X11R6/include -L/usr/X11R6/lib $< -lX11
+ *
+ */
+
+#include <stdio.h>
+#include <string.h>
+#ifdef HAVE_SELECT
+#include <sys/time.h>
+#include <sys/types.h>
+#include <unistd.h>
+#else
+#include <sys/poll.h>
+#endif
+#include <X11/Intrinsic.h>
+#include <X11/Xatom.h>
+
+#define __ARGS(x) x
+
+/* Client API */
+char * sendToVim __ARGS((Display *dpy, char *name, char *cmd, int asKeys, int *code));
+
+#ifdef MAIN
+/* A sample program */
+main(int argc, char **argv)
+{
+    char    *res;
+    int	    code;
+
+    if (argc == 4)
+    {
+	if ((res = sendToVim(XOpenDisplay(NULL), argv[2], argv[3],
+			     argv[1][0] != 'e', &code)) != NULL)
+	{
+	    if (code)
+		printf("Error code returned: %d\n", code);
+	    puts(res);
+	}
+	exit(0);
+    }
+    else
+	fprintf(stderr, "Usage: %s {k|e} <server> <command>", argv[0]);
+
+    exit(1);
+}
+#endif
+
+/*
+ * Maximum size property that can be read at one time by
+ * this module:
+ */
+
+#define MAX_PROP_WORDS 100000
+
+/*
+ * Forward declarations for procedures defined later in this file:
+ */
+
+static int	x_error_check __ARGS((Display *dpy, XErrorEvent *error_event));
+static int	AppendPropCarefully __ARGS((Display *display,
+		    Window window, Atom property, char *value, int length));
+static Window	LookupName __ARGS((Display *dpy, char *name,
+		    int delete, char **loose));
+static int	SendInit __ARGS((Display *dpy));
+static char	*SendEventProc __ARGS((Display *dpy, XEvent *eventPtr,
+				      int expect, int *code));
+static int	IsSerialName __ARGS((char *name));
+
+/* Private variables */
+static Atom	registryProperty = None;
+static Atom	commProperty = None;
+static Window	commWindow = None;
+static int	got_x_error = FALSE;
+
+
+/*
+ * sendToVim --
+ *	Send to an instance of Vim via the X display.
+ *
+ * Results:
+ *	A string with the result or NULL. Caller must free if non-NULL
+ */
+
+    char *
+sendToVim(dpy, name, cmd, asKeys, code)
+    Display	*dpy;			/* Where to send. */
+    char	*name;			/* Where to send. */
+    char	*cmd;			/* What to send. */
+    int		asKeys;			/* Interpret as keystrokes or expr ? */
+    int		*code;			/* Return code. 0 => OK */
+{
+    Window	    w;
+    Atom	    *plist;
+    XErrorHandler   old_handler;
+#define STATIC_SPACE 500
+    char	    *property, staticSpace[STATIC_SPACE];
+    int		    length;
+    int		    res;
+    static int	    serial = 0;	/* Running count of sent commands.
+				 * Used to give each command a
+				 * different serial number. */
+    XEvent	    event;
+    XPropertyEvent  *e = (XPropertyEvent *)&event;
+    time_t	    start;
+    char	    *result;
+    char	    *loosename = NULL;
+
+    if (commProperty == None && dpy != NULL)
+    {
+	if (SendInit(dpy) < 0)
+	    return NULL;
+    }
+
+    /*
+     * Bind the server name to a communication window.
+     *
+     * Find any survivor with a serialno attached to the name if the
+     * original registrant of the wanted name is no longer present.
+     *
+     * Delete any lingering names from dead editors.
+     */
+
+    old_handler = XSetErrorHandler(x_error_check);
+    while (TRUE)
+    {
+	got_x_error = FALSE;
+	w = LookupName(dpy, name, 0, &loosename);
+	/* Check that the window is hot */
+	if (w != None)
+	{
+	    plist = XListProperties(dpy, w, &res);
+	    XSync(dpy, False);
+	    if (plist != NULL)
+		XFree(plist);
+	    if (got_x_error)
+	    {
+		LookupName(dpy, loosename ? loosename : name,
+			   /*DELETE=*/TRUE, NULL);
+		continue;
+	    }
+	}
+	break;
+    }
+    if (w == None)
+    {
+	fprintf(stderr, "no registered server named %s\n", name);
+	return NULL;
+    }
+    else if (loosename != NULL)
+	name = loosename;
+
+    /*
+     * Send the command to target interpreter by appending it to the
+     * comm window in the communication window.
+     */
+
+    length = strlen(name) + strlen(cmd) + 10;
+    if (length <= STATIC_SPACE)
+	property = staticSpace;
+    else
+	property = (char *) malloc((unsigned) length);
+
+    serial++;
+    sprintf(property, "%c%c%c-n %s%c-s %s",
+		      0, asKeys ? 'k' : 'c', 0, name, 0, cmd);
+    if (name == loosename)
+	free(loosename);
+    if (!asKeys)
+    {
+	/* Add a back reference to our comm window */
+	sprintf(property + length, "%c-r %x %d", 0, (uint) commWindow, serial);
+	length += strlen(property + length + 1) + 1;
+    }
+
+    res = AppendPropCarefully(dpy, w, commProperty, property, length + 1);
+    if (length > STATIC_SPACE)
+	free(property);
+    if (res < 0)
+    {
+	fprintf(stderr, "Failed to send command to the destination program\n");
+	return NULL;
+    }
+
+    if (asKeys) /* There is no answer for this - Keys are sent async */
+	return NULL;
+
+
+    /*
+     * Enter a loop processing X events & pooling chars until we see the result
+     */
+
+#define SEND_MSEC_POLL 50
+
+    time(&start);
+    while ((time((time_t *) 0) - start) < 60)
+    {
+	/* Look out for the answer */
+#ifndef HAVE_SELECT
+	struct pollfd   fds;
+
+	fds.fd = ConnectionNumber(dpy);
+	fds.events = POLLIN;
+	if (poll(&fds, 1, SEND_MSEC_POLL) < 0)
+	    break;
+#else
+	fd_set	    fds;
+	struct timeval  tv;
+
+	tv.tv_sec = 0;
+	tv.tv_usec =  SEND_MSEC_POLL * 1000;
+	FD_ZERO(&fds);
+	FD_SET(ConnectionNumber(dpy), &fds);
+	if (select(ConnectionNumber(dpy) + 1, &fds, NULL, NULL, &tv) < 0)
+	    break;
+#endif
+	while (XEventsQueued(dpy, QueuedAfterReading) > 0)
+	{
+	    XNextEvent(dpy, &event);
+	    if (event.type == PropertyNotify && e->window == commWindow)
+		if ((result = SendEventProc(dpy, &event, serial, code)) != NULL)
+		    return result;
+	}
+    }
+    return NULL;
+}
+
+
+/*
+ * SendInit --
+ *	This procedure is called to initialize the
+ *	communication channels for sending commands and
+ *	receiving results.
+ */
+
+    static int
+SendInit(dpy)
+    Display *dpy;
+{
+    XErrorHandler old_handler;
+
+    /*
+     * Create the window used for communication, and set up an
+     * event handler for it.
+     */
+    old_handler = XSetErrorHandler(x_error_check);
+    got_x_error = FALSE;
+
+    commProperty = XInternAtom(dpy, "Comm", False);
+    /* Change this back to "InterpRegistry" to talk to tk processes */
+    registryProperty = XInternAtom(dpy, "VimRegistry", False);
+
+    if (commWindow == None)
+    {
+	commWindow =
+	    XCreateSimpleWindow(dpy, XDefaultRootWindow(dpy),
+				getpid(), 0, 10, 10, 0,
+				WhitePixel(dpy, DefaultScreen(dpy)),
+				WhitePixel(dpy, DefaultScreen(dpy)));
+	XSelectInput(dpy, commWindow, PropertyChangeMask);
+    }
+
+    XSync(dpy, False);
+    (void) XSetErrorHandler(old_handler);
+
+    return got_x_error ? -1 : 0;
+}
+
+/*
+ * LookupName --
+ *	Given an interpreter name, see if the name exists in
+ *	the interpreter registry for a particular display.
+ *
+ * Results:
+ *	If the given name is registered, return the ID of
+ *	the window associated with the name.  If the name
+ *	isn't registered, then return 0.
+ */
+
+    static Window
+LookupName(dpy, name, delete, loose)
+    Display *dpy;	/* Display whose registry to check. */
+    char *name;		/* Name of an interpreter. */
+    int delete;		/* If non-zero, delete info about name. */
+    char **loose;	/* Do another search matching -999 if not found
+			   Return result here if a match is found */
+{
+    unsigned char   *regProp, *entry;
+    unsigned char   *p;
+    int		    result, actualFormat;
+    unsigned long   numItems, bytesAfter;
+    Atom	    actualType;
+    Window	    returnValue;
+
+    /*
+     * Read the registry property.
+     */
+
+    regProp = NULL;
+    result = XGetWindowProperty(dpy, RootWindow(dpy, 0), registryProperty, 0,
+				MAX_PROP_WORDS, False, XA_STRING, &actualType,
+				&actualFormat, &numItems, &bytesAfter,
+				&regProp);
+
+    if (actualType == None)
+	return 0;
+
+    /*
+     * If the property is improperly formed, then delete it.
+     */
+
+    if ((result != Success) || (actualFormat != 8) || (actualType != XA_STRING))
+    {
+	if (regProp != NULL)
+	    XFree(regProp);
+	XDeleteProperty(dpy, RootWindow(dpy, 0), registryProperty);
+	return 0;
+    }
+
+    /*
+     * Scan the property for the desired name.
+     */
+
+    returnValue = None;
+    entry = NULL;	/* Not needed, but eliminates compiler warning. */
+    for (p = regProp; (p - regProp) < numItems; )
+    {
+	entry = p;
+	while ((*p != 0) && (!isspace(*p)))
+	    p++;
+	if ((*p != 0) && (strcasecmp(name, p + 1) == 0))
+	{
+	    sscanf(entry, "%x", (uint*) &returnValue);
+	    break;
+	}
+	while (*p != 0)
+	    p++;
+	p++;
+    }
+
+    if (loose != NULL && returnValue == None && !IsSerialName(name))
+    {
+	for (p = regProp; (p - regProp) < numItems; )
+	{
+	    entry = p;
+	    while ((*p != 0) && (!isspace(*p)))
+		p++;
+	    if ((*p != 0) && IsSerialName(p + 1)
+		    && (strncmp(name, p + 1, strlen(name)) == 0))
+	    {
+		sscanf(entry, "%x", (uint*) &returnValue);
+		*loose = strdup(p + 1);
+		break;
+	    }
+	    while (*p != 0)
+		p++;
+	    p++;
+	}
+    }
+
+    /*
+     * Delete the property, if that is desired (copy down the
+     * remainder of the registry property to overlay the deleted
+     * info, then rewrite the property).
+     */
+
+    if ((delete) && (returnValue != None))
+    {
+	int count;
+
+	while (*p != 0)
+	    p++;
+	p++;
+	count = numItems - (p-regProp);
+	if (count > 0)
+	    memcpy(entry, p, count);
+	XChangeProperty(dpy, RootWindow(dpy, 0), registryProperty, XA_STRING,
+			8, PropModeReplace, regProp,
+			(int) (numItems - (p-entry)));
+	XSync(dpy, False);
+    }
+
+    XFree(regProp);
+    return returnValue;
+}
+
+    static char *
+SendEventProc(dpy, eventPtr, expected, code)
+    Display	   *dpy;
+    XEvent	    *eventPtr;		/* Information about event. */
+    int		    expected;		/* The one were waiting for */
+    int		    *code;		/* Return code. 0 => OK */
+{
+    unsigned char   *propInfo;
+    unsigned char   *p;
+    int		    result, actualFormat;
+    int		    retCode;
+    unsigned long   numItems, bytesAfter;
+    Atom	    actualType;
+
+    if ((eventPtr->xproperty.atom != commProperty)
+	    || (eventPtr->xproperty.state != PropertyNewValue))
+    {
+	return;
+    }
+
+    /*
+     * Read the comm property and delete it.
+     */
+
+    propInfo = NULL;
+    result = XGetWindowProperty(dpy, commWindow, commProperty, 0,
+				MAX_PROP_WORDS, True, XA_STRING, &actualType,
+				&actualFormat, &numItems, &bytesAfter,
+				&propInfo);
+
+    /*
+     * If the property doesn't exist or is improperly formed
+     * then ignore it.
+     */
+
+    if ((result != Success) || (actualType != XA_STRING)
+	    || (actualFormat != 8))
+    {
+	if (propInfo != NULL)
+	{
+	    XFree(propInfo);
+	}
+	return;
+    }
+
+    /*
+     * Several commands and results could arrive in the property at
+     * one time;  each iteration through the outer loop handles a
+     * single command or result.
+     */
+
+    for (p = propInfo; (p - propInfo) < numItems; )
+    {
+	/*
+	 * Ignore leading NULs; each command or result starts with a
+	 * NUL so that no matter how badly formed a preceding command
+	 * is, we'll be able to tell that a new command/result is
+	 * starting.
+	 */
+
+	if (*p == 0)
+	{
+	    p++;
+	    continue;
+	}
+
+	if ((*p == 'r') && (p[1] == 0))
+	{
+	    int	    serial, gotSerial;
+	    char  *res;
+
+	    /*
+	     * This is a reply to some command that we sent out.  Iterate
+	     * over all of its options.  Stop when we reach the end of the
+	     * property or something that doesn't look like an option.
+	     */
+
+	    p += 2;
+	    gotSerial = 0;
+	    res = "";
+	    retCode = 0;
+	    while (((p-propInfo) < numItems) && (*p == '-'))
+	    {
+		switch (p[1])
+		{
+		    case 'r':
+			if (p[2] == ' ')
+			    res = p + 3;
+			break;
+		    case 's':
+			if (sscanf(p + 2, " %d", &serial) == 1)
+			    gotSerial = 1;
+			break;
+		    case 'c':
+			if (sscanf(p + 2, " %d", &retCode) != 1)
+			    retCode = 0;
+			break;
+		}
+		while (*p != 0)
+		    p++;
+		p++;
+	    }
+
+	    if (!gotSerial)
+		continue;
+
+	    if (code != NULL)
+		*code = retCode;
+	    return serial == expected ? strdup(res) : NULL;
+	}
+	else
+	{
+	    /*
+	     * Didn't recognize this thing.  Just skip through the next
+	     * null character and try again.
+	     * Also, throw away commands that we cant process anyway.
+	     */
+
+	    while (*p != 0)
+		p++;
+	    p++;
+	}
+    }
+    XFree(propInfo);
+}
+
+/*
+ * AppendPropCarefully --
+ *
+ *	Append a given property to a given window, but set up
+ *	an X error handler so that if the append fails this
+ *	procedure can return an error code rather than having
+ *	Xlib panic.
+ *
+ *  Return:
+ *	0 on OK - -1 on error
+ *--------------------------------------------------------------
+ */
+
+    static int
+AppendPropCarefully(dpy, window, property, value, length)
+    Display *dpy;		/* Display on which to operate. */
+    Window window;		/* Window whose property is to
+				 * be modified. */
+    Atom property;		/* Name of property. */
+    char *value;		/* Characters  to append to property. */
+    int  length;		/* How much to append */
+{
+    XErrorHandler old_handler;
+
+    old_handler = XSetErrorHandler(x_error_check);
+    got_x_error = FALSE;
+    XChangeProperty(dpy, window, property, XA_STRING, 8,
+		    PropModeAppend, value, length);
+    XSync(dpy, False);
+    (void) XSetErrorHandler(old_handler);
+    return got_x_error ? -1 : 0;
+}
+
+
+/*
+ * Another X Error handler, just used to check for errors.
+ */
+/* ARGSUSED */
+    static int
+x_error_check(dpy, error_event)
+    Display *dpy;
+    XErrorEvent	*error_event;
+{
+    got_x_error = TRUE;
+    return 0;
+}
+
+/*
+ * Check if "str" looks like it had a serial number appended.
+ * Actually just checks if the name ends in a digit.
+ */
+    static int
+IsSerialName(str)
+    char   *str;
+{
+    int len = strlen(str);
+
+    return (len > 1 && isdigit(str[len - 1]));
+}
--- /dev/null
+++ b/lib/vimfiles/tutor/README.txt
@@ -1,0 +1,22 @@
+Tutor is a "hands on" tutorial for new users of the Vim editor.
+
+Most new users can get through it in less than one hour. The result
+is that you can do a simple editing task using the Vim editor.
+
+Tutor is a file that contains the tutorial lessons. You can simply
+execute "vim tutor" and then follow the instructions in the lessons.
+The lessons tell you to modify the file, so DON'T DO THIS ON YOUR
+ORIGINAL COPY.
+
+On Unix you can also use the "vimtutor" program.  It will make a
+scratch copy of the tutor first.
+
+I have considered adding more advanced lessons but have not found the
+time. Please let me know how you like it and send any improvements you
+make.
+
+Bob Ware, Colorado School of Mines, Golden, Co 80401, USA
+(303) 273-3987
+bware@mines.colorado.edu bware@slate.mines.colorado.edu bware@mines.bitnet
+
+[This file was modified for Vim by Bram Moolenaar]
--- /dev/null
+++ b/lib/vimfiles/tutor/tutor
@@ -1,0 +1,970 @@
+===============================================================================
+=    W e l c o m e   t o   t h e   V I M   T u t o r    -    Version 1.7      =
+===============================================================================
+
+     Vim is a very powerful editor that has many commands, too many to
+     explain in a tutor such as this.  This tutor is designed to describe
+     enough of the commands that you will be able to easily use Vim as
+     an all-purpose editor.
+
+     The approximate time required to complete the tutor is 25-30 minutes,
+     depending upon how much time is spent with experimentation.
+
+     ATTENTION:
+     The commands in the lessons will modify the text.  Make a copy of this
+     file to practise on (if you started "vimtutor" this is already a copy).
+
+     It is important to remember that this tutor is set up to teach by
+     use.  That means that you need to execute the commands to learn them
+     properly.  If you only read the text, you will forget the commands!
+
+     Now, make sure that your Shift-Lock key is NOT depressed and press
+     the   j   key enough times to move the cursor so that Lesson 1.1
+     completely fills the screen.
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+			Lesson 1.1:  MOVING THE CURSOR
+
+
+   ** To move the cursor, press the h,j,k,l keys as indicated. **
+	     ^
+	     k		    Hint:  The h key is at the left and moves left.
+       < h	 l >		   The l key is at the right and moves right.
+	     j			   The j key looks like a down arrow.
+	     v
+  1. Move the cursor around the screen until you are comfortable.
+
+  2. Hold down the down key (j) until it repeats.
+     Now you know how to move to the next lesson.
+
+  3. Using the down key, move to Lesson 1.2.
+
+NOTE: If you are ever unsure about something you typed, press <ESC> to place
+      you in Normal mode.  Then retype the command you wanted.
+
+NOTE: The cursor keys should also work.  But using hjkl you will be able to
+      move around much faster, once you get used to it.  Really!
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+			    Lesson 1.2: EXITING VIM
+
+
+  !! NOTE: Before executing any of the steps below, read this entire lesson!!
+
+  1. Press the <ESC> key (to make sure you are in Normal mode).
+
+  2. Type:	:q! <ENTER>.
+     This exits the editor, DISCARDING any changes you have made.
+
+  3. When you see the shell prompt, type the command that got you into this
+     tutor.  That would be:	vimtutor <ENTER>
+
+  4. If you have these steps memorized and are confident, execute steps
+     1 through 3 to exit and re-enter the editor.
+
+NOTE:  :q! <ENTER>  discards any changes you made.  In a few lessons you
+       will learn how to save the changes to a file.
+
+  5. Move the cursor down to Lesson 1.3.
+
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+		     Lesson 1.3: TEXT EDITING - DELETION
+
+
+	   ** Press  x  to delete the character under the cursor. **
+
+  1. Move the cursor to the line below marked --->.
+
+  2. To fix the errors, move the cursor until it is on top of the
+     character to be deleted.
+
+  3. Press the	x  key to delete the unwanted character.
+
+  4. Repeat steps 2 through 4 until the sentence is correct.
+
+---> The ccow jumpedd ovverr thhe mooon.
+
+  5. Now that the line is correct, go on to Lesson 1.4.
+
+NOTE: As you go through this tutor, do not try to memorize, learn by usage.
+
+
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+		      Lesson 1.4: TEXT EDITING - INSERTION
+
+
+			** Press  i  to insert text. **
+
+  1. Move the cursor to the first line below marked --->.
+
+  2. To make the first line the same as the second, move the cursor on top
+     of the first character AFTER where the text is to be inserted.
+
+  3. Press  i  and type in the necessary additions.
+
+  4. As each error is fixed press <ESC> to return to Normal mode.
+     Repeat steps 2 through 4 to correct the sentence.
+
+---> There is text misng this .
+---> There is some text missing from this line.
+
+  5. When you are comfortable inserting text move to lesson 1.5.
+
+
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+		     Lesson 1.5: TEXT EDITING - APPENDING
+
+
+			** Press  A  to append text. **
+
+  1. Move the cursor to the first line below marked --->.
+     It does not matter on what character the cursor is in that line.
+
+  2. Press  A  and type in the necessary additions.
+
+  3. As the text has been appended press <ESC> to return to Normal mode.
+
+  4. Move the cursor to the second line marked ---> and repeat 
+     steps 2 and 3 to correct this sentence.
+
+---> There is some text missing from th
+     There is some text missing from this line.
+---> There is also some text miss
+     There is also some text missing here.
+
+  5. When you are comfortable appending text move to lesson 1.6.
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+		     Lesson 1.6: EDITING A FILE
+
+
+		    ** Use  :wq  to save a file and exit. **
+
+  !! NOTE: Before executing any of the steps below, read this entire lesson!!
+
+  1. Exit this tutor as you did in lesson 1.2:  :q!
+
+  2. At the shell prompt type this command:  vim tutor <ENTER>
+     'vim' is the command to start the Vim editor, 'tutor' is the name of the
+     file you wish to edit.  Use a file that may be changed.
+
+  3. Insert and delete text as you learned in the previous lessons.
+
+  4. Save the file with changes and exit Vim with:  :wq  <ENTER>
+
+  5. Restart the vimtutor and move down to the following summary.
+
+  6. After reading the above steps and understanding them: do it.
+
+  
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+			       Lesson 1 SUMMARY
+
+
+  1. The cursor is moved using either the arrow keys or the hjkl keys.
+	 h (left)	j (down)       k (up)	    l (right)
+
+  2. To start Vim from the shell prompt type:  vim FILENAME <ENTER>
+
+  3. To exit Vim type:	   <ESC>   :q!	 <ENTER>  to trash all changes.
+	     OR type:	   <ESC>   :wq	 <ENTER>  to save the changes.
+
+  4. To delete the character at the cursor type:  x
+
+  5. To insert or append text type:
+	 i   type inserted text   <ESC>		insert before the cursor
+	 A   type appended text   <ESC>         append after the line
+
+NOTE: Pressing <ESC> will place you in Normal mode or will cancel
+      an unwanted and partially completed command.
+
+Now continue with Lesson 2.
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+			Lesson 2.1: DELETION COMMANDS
+
+
+		       ** Type  dw  to delete a word. **
+
+  1. Press  <ESC>  to make sure you are in Normal mode.
+
+  2. Move the cursor to the line below marked --->.
+
+  3. Move the cursor to the beginning of a word that needs to be deleted.
+
+  4. Type   dw	 to make the word disappear.
+
+  NOTE: The letter  d  will appear on the last line of the screen as you type
+	it.  Vim is waiting for you to type  w .  If you see another character
+	than  d  you typed something wrong; press  <ESC>  and start over.
+
+---> There are a some words fun that don't belong paper in this sentence.
+
+  5. Repeat steps 3 and 4 until the sentence is correct and go to Lesson 2.2.
+
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+		      Lesson 2.2: MORE DELETION COMMANDS
+
+
+	   ** Type  d$	to delete to the end of the line. **
+
+  1. Press  <ESC>  to make sure you are in Normal mode.
+
+  2. Move the cursor to the line below marked --->.
+
+  3. Move the cursor to the end of the correct line (AFTER the first . ).
+
+  4. Type    d$    to delete to the end of the line.
+
+---> Somebody typed the end of this line twice. end of this line twice.
+
+
+  5. Move on to Lesson 2.3 to understand what is happening.
+
+
+
+
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+		     Lesson 2.3: ON OPERATORS AND MOTIONS
+
+
+  Many commands that change text are made from an operator and a motion.
+  The format for a delete command with the  d  delete operator is as follows:
+
+  	d   motion
+
+  Where:
+    d      - is the delete operator.
+    motion - is what the operator will operate on (listed below).
+
+  A short list of motions:
+    w - until the start of the next word, EXCLUDING its first character.
+    e - to the end of the current word, INCLUDING the last character.
+    $ - to the end of the line, INCLUDING the last character.
+
+  Thus typing  de  will delete from the cursor to the end of the word.
+
+NOTE:  Pressing just the motion while in Normal mode without an operator will
+       move the cursor as specified.
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+		     Lesson 2.4: USING A COUNT FOR A MOTION
+
+
+   ** Typing a number before a motion repeats it that many times. **
+
+  1. Move the cursor to the start of the line marked ---> below.
+
+  2. Type  2w  to move the cursor two words forward.
+
+  3. Type  3e  to move the cursor to the end of the third word forward.
+
+  4. Type  0  (zero) to move to the start of the line.
+
+  5. Repeat steps 2 and 3 with different numbers.
+
+---> This is just a line with words you can move around in.
+
+  6. Move on to Lesson 2.5.
+
+
+
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+		     Lesson 2.5: USING A COUNT TO DELETE MORE
+
+
+   ** Typing a number with an operator repeats it that many times. **
+
+  In the combination of the delete operator and a motion mentioned above you
+  insert a count before the motion to delete more:
+	 d   number   motion
+
+  1. Move the cursor to the first UPPER CASE word in the line marked --->.
+
+  2. Type  d2w  to delete the two UPPER CASE words
+
+  3. Repeat steps 1 and 2 with a different count to delete the consecutive
+     UPPER CASE words with one command
+
+--->  this ABC DE line FGHI JK LMN OP of words is Q RS TUV cleaned up.
+
+
+
+
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+			 Lesson 2.6: OPERATING ON LINES
+
+
+		   ** Type  dd   to delete a whole line. **
+
+  Due to the frequency of whole line deletion, the designers of Vi decided
+  it would be easier to simply type two d's to delete a line.
+
+  1. Move the cursor to the second line in the phrase below.
+  2. Type  dd  to delete the line.
+  3. Now move to the fourth line.
+  4. Type   2dd   to delete two lines.
+
+--->  1)  Roses are red,
+--->  2)  Mud is fun,
+--->  3)  Violets are blue,
+--->  4)  I have a car,
+--->  5)  Clocks tell time,
+--->  6)  Sugar is sweet
+--->  7)  And so are you.
+
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+			 Lesson 2.7: THE UNDO COMMAND
+
+
+   ** Press  u	to undo the last commands,   U  to fix a whole line. **
+
+  1. Move the cursor to the line below marked ---> and place it on the
+     first error.
+  2. Type  x  to delete the first unwanted character.
+  3. Now type  u  to undo the last command executed.
+  4. This time fix all the errors on the line using the  x  command.
+  5. Now type a capital  U  to return the line to its original state.
+  6. Now type  u  a few times to undo the  U  and preceding commands.
+  7. Now type CTRL-R (keeping CTRL key pressed while hitting R) a few times
+     to redo the commands (undo the undo's).
+
+---> Fiix the errors oon thhis line and reeplace them witth undo.
+
+  8. These are very useful commands.  Now move on to the Lesson 2 Summary.
+
+
+
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+			       Lesson 2 SUMMARY
+
+
+  1. To delete from the cursor up to the next word type:    dw
+  2. To delete from the cursor to the end of a line type:    d$
+  3. To delete a whole line type:    dd
+
+  4. To repeat a motion prepend it with a number:   2w
+  5. The format for a change command is:
+               operator   [number]   motion
+     where:
+       operator - is what to do, such as  d  for delete
+       [number] - is an optional count to repeat the motion
+       motion   - moves over the text to operate on, such as  w (word),
+		  $ (to the end of line), etc.
+
+  6. To move to the start of the line use a zero:  0
+
+  7. To undo previous actions, type: 	       u  (lowercase u)
+     To undo all the changes on a line, type:  U  (capital U)
+     To undo the undo's, type:		       CTRL-R
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+			 Lesson 3.1: THE PUT COMMAND
+
+
+       ** Type	p  to put previously deleted text after the cursor. **
+
+  1. Move the cursor to the first ---> line below.
+
+  2. Type  dd  to delete the line and store it in a Vim register.
+
+  3. Move the cursor to the c) line, ABOVE where the deleted line should go.
+
+  4. Type   p   to put the line below the cursor.
+
+  5. Repeat steps 2 through 4 to put all the lines in correct order.
+
+---> d) Can you learn too?
+---> b) Violets are blue,
+---> c) Intelligence is learned,
+---> a) Roses are red,
+
+
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+		       Lesson 3.2: THE REPLACE COMMAND
+
+
+       ** Type  rx  to replace the character at the cursor with  x . **
+
+  1. Move the cursor to the first line below marked --->.
+
+  2. Move the cursor so that it is on top of the first error.
+
+  3. Type   r	and then the character which should be there.
+
+  4. Repeat steps 2 and 3 until the first line is equal to the second one.
+
+--->  Whan this lime was tuoed in, someone presswd some wrojg keys!
+--->  When this line was typed in, someone pressed some wrong keys!
+
+  5. Now move on to Lesson 3.3.
+
+NOTE: Remember that you should be learning by doing, not memorization.
+
+
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+			Lesson 3.3: THE CHANGE OPERATOR
+
+
+	   ** To change until the end of a word, type  ce . **
+
+  1. Move the cursor to the first line below marked --->.
+
+  2. Place the cursor on the  u  in  lubw.
+
+  3. Type  ce  and the correct word (in this case, type  ine ).
+
+  4. Press <ESC> and move to the next character that needs to be changed.
+
+  5. Repeat steps 3 and 4 until the first sentence is the same as the second.
+
+---> This lubw has a few wptfd that mrrf changing usf the change operator.
+---> This line has a few words that need changing using the change operator.
+
+Notice that  ce  deletes the word and places you in Insert mode.
+
+
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+		       Lesson 3.4: MORE CHANGES USING c
+
+
+     ** The change operator is used with the same motions as delete. **
+
+  1. The change operator works in the same way as delete.  The format is:
+
+         c    [number]   motion
+
+  2. The motions are the same, such as   w (word) and  $ (end of line).
+
+  3. Move to the first line below marked --->.
+
+  4. Move the cursor to the first error.
+
+  5. Type  c$  and type the rest of the line like the second and press <ESC>.
+
+---> The end of this line needs some help to make it like the second.
+---> The end of this line needs to be corrected using the  c$  command.
+
+NOTE:  You can use the Backspace key to correct mistakes while typing.
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+			       Lesson 3 SUMMARY
+
+
+  1. To put back text that has just been deleted, type   p .  This puts the
+     deleted text AFTER the cursor (if a line was deleted it will go on the
+     line below the cursor).
+
+  2. To replace the character under the cursor, type   r   and then the
+     character you want to have there.
+
+  3. The change operator allows you to change from the cursor to where the
+     motion takes you.  eg. Type  ce  to change from the cursor to the end of
+     the word,  c$  to change to the end of a line.
+
+  4. The format for change is:
+
+	 c   [number]   motion
+
+Now go on to the next lesson.
+
+
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+		  Lesson 4.1: CURSOR LOCATION AND FILE STATUS
+
+  ** Type CTRL-G to show your location in the file and the file status.
+     Type  G  to move to a line in the file. **
+
+  NOTE: Read this entire lesson before executing any of the steps!!
+
+  1. Hold down the Ctrl key and press  g .  We call this CTRL-G.
+     A message will appear at the bottom of the page with the filename and the
+     position in the file.  Remember the line number for Step 3.
+
+NOTE:  You may see the cursor position in the lower right corner of the screen
+       This happens when the 'ruler' option is set (see  :help 'ruler'  )
+
+  2. Press  G  to move you to the bottom of the file.
+     Type  gg  to move you to the start of the file.
+
+  3. Type the number of the line you were on and then  G .  This will
+     return you to the line you were on when you first pressed CTRL-G.
+
+  4. If you feel confident to do this, execute steps 1 through 3.
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+			Lesson 4.2: THE SEARCH COMMAND
+
+
+     ** Type  /  followed by a phrase to search for the phrase. **
+
+  1. In Normal mode type the  /  character.  Notice that it and the cursor
+     appear at the bottom of the screen as with the  :	command.
+
+  2. Now type 'errroor' <ENTER>.  This is the word you want to search for.
+
+  3. To search for the same phrase again, simply type  n .
+     To search for the same phrase in the opposite direction, type  N .
+
+  4. To search for a phrase in the backward direction, use  ?  instead of  / .
+
+  5. To go back to where you came from press  CTRL-O  (Keep Ctrl down while
+     pressing the letter o).  Repeat to go back further.  CTRL-I goes forward.
+
+--->  "errroor" is not the way to spell error;  errroor is an error.
+NOTE: When the search reaches the end of the file it will continue at the
+      start, unless the 'wrapscan' option has been reset.
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+		   Lesson 4.3: MATCHING PARENTHESES SEARCH
+
+
+	      ** Type  %  to find a matching ),], or } . **
+
+  1. Place the cursor on any (, [, or { in the line below marked --->.
+
+  2. Now type the  %  character.
+
+  3. The cursor will move to the matching parenthesis or bracket.
+
+  4. Type  %  to move the cursor to the other matching bracket.
+
+  5. Move the cursor to another (,),[,],{ or } and see what  %  does.
+
+---> This ( is a test line with ('s, ['s ] and {'s } in it. ))
+
+
+NOTE: This is very useful in debugging a program with unmatched parentheses!
+
+
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+		      Lesson 4.4: THE SUBSTITUTE COMMAND
+
+
+	** Type  :s/old/new/g  to substitute 'new' for 'old'. **
+
+  1. Move the cursor to the line below marked --->.
+
+  2. Type  :s/thee/the <ENTER> .  Note that this command only changes the
+     first occurrence of "thee" in the line.
+
+  3. Now type  :s/thee/the/g .  Adding the  g  flag means to substitute
+     globally in the line, change all occurrences of "thee" in the line.
+
+---> thee best time to see thee flowers is in thee spring.
+
+  4. To change every occurrence of a character string between two lines,
+     type   :#,#s/old/new/g    where #,# are the line numbers of the range
+                               of lines where the substitution is to be done.
+     Type   :%s/old/new/g      to change every occurrence in the whole file.
+     Type   :%s/old/new/gc     to find every occurrence in the whole file,
+     			       with a prompt whether to substitute or not.
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+			       Lesson 4 SUMMARY
+
+
+  1. CTRL-G  displays your location in the file and the file status.
+             G  moves to the end of the file.
+     number  G  moves to that line number.
+            gg  moves to the first line.
+
+  2. Typing  /	followed by a phrase searches FORWARD for the phrase.
+     Typing  ?	followed by a phrase searches BACKWARD for the phrase.
+     After a search type  n  to find the next occurrence in the same direction
+     or  N  to search in the opposite direction.
+     CTRL-O takes you back to older positions, CTRL-I to newer positions.
+
+  3. Typing  %	while the cursor is on a (,),[,],{, or } goes to its match.
+
+  4. To substitute new for the first old in a line type    :s/old/new
+     To substitute new for all 'old's on a line type	   :s/old/new/g
+     To substitute phrases between two line #'s type	   :#,#s/old/new/g
+     To substitute all occurrences in the file type	   :%s/old/new/g
+     To ask for confirmation each time add 'c'		   :%s/old/new/gc
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+		Lesson 5.1: HOW TO EXECUTE AN EXTERNAL COMMAND
+
+
+   ** Type  :!	followed by an external command to execute that command. **
+
+  1. Type the familiar command	:  to set the cursor at the bottom of the
+     screen.  This allows you to enter a command-line command.
+
+  2. Now type the  !  (exclamation point) character.  This allows you to
+     execute any external shell command.
+
+  3. As an example type   ls   following the ! and then hit <ENTER>.  This
+     will show you a listing of your directory, just as if you were at the
+     shell prompt.  Or use  :!dir  if ls doesn't work.
+
+NOTE:  It is possible to execute any external command this way, also with
+       arguments.
+
+NOTE:  All  :  commands must be finished by hitting <ENTER>
+       From here on we will not always mention it.
+
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+		      Lesson 5.2: MORE ON WRITING FILES
+
+
+     ** To save the changes made to the text, type  :w FILENAME. **
+
+  1. Type  :!dir  or  :!ls  to get a listing of your directory.
+     You already know you must hit <ENTER> after this.
+
+  2. Choose a filename that does not exist yet, such as TEST.
+
+  3. Now type:	 :w TEST   (where TEST is the filename you chose.)
+
+  4. This saves the whole file (the Vim Tutor) under the name TEST.
+     To verify this, type    :!dir  or  :!ls   again to see your directory.
+
+NOTE: If you were to exit Vim and start it again with  vim TEST , the file
+      would be an exact copy of the tutor when you saved it.
+
+  5. Now remove the file by typing (MS-DOS):    :!del TEST
+				or (Unix):	:!rm TEST
+
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+		    Lesson 5.3: SELECTING TEXT TO WRITE
+
+
+	** To save part of the file, type  v  motion  :w FILENAME **
+
+  1. Move the cursor to this line.
+
+  2. Press  v  and move the cursor to the fifth item below.  Notice that the
+     text is highlighted.
+
+  3. Press the  :  character.  At the bottom of the screen  :'<,'> will appear.
+
+  4. Type  w TEST  , where TEST is a filename that does not exist yet.  Verify
+     that you see  :'<,'>w TEST  before you press Enter.
+
+  5. Vim will write the selected lines to the file TEST.  Use  :!dir  or  !ls
+     to see it.  Do not remove it yet!  We will use it in the next lesson.
+
+NOTE:  Pressing  v  starts Visual selection.  You can move the cursor around
+       to make the selection bigger or smaller.  Then you can use an operator
+       to do something with the text.  For example,  d  deletes the text.
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+		   Lesson 5.4: RETRIEVING AND MERGING FILES
+
+
+       ** To insert the contents of a file, type  :r FILENAME  **
+
+  1. Place the cursor just above this line.
+
+NOTE:  After executing Step 2 you will see text from Lesson 5.3.  Then move
+       DOWN to see this lesson again.
+
+  2. Now retrieve your TEST file using the command   :r TEST   where TEST is
+     the name of the file you used.
+     The file you retrieve is placed below the cursor line.
+
+  3. To verify that a file was retrieved, cursor back and notice that there
+     are now two copies of Lesson 5.3, the original and the file version.
+
+NOTE:  You can also read the output of an external command.  For example,
+       :r !ls  reads the output of the ls command and puts it below the
+       cursor.
+
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+			       Lesson 5 SUMMARY
+
+
+  1.  :!command  executes an external command.
+
+      Some useful examples are:
+	 (MS-DOS)	  (Unix)
+	  :!dir		   :!ls		   -  shows a directory listing.
+	  :!del FILENAME   :!rm FILENAME   -  removes file FILENAME.
+
+  2.  :w FILENAME  writes the current Vim file to disk with name FILENAME.
+
+  3.  v  motion  :w FILENAME  saves the Visually selected lines in file
+      FILENAME.
+
+  4.  :r FILENAME  retrieves disk file FILENAME and puts it below the
+      cursor position.
+
+  5.  :r !dir  reads the output of the dir command and puts it below the
+      cursor position.
+
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+			 Lesson 6.1: THE OPEN COMMAND
+
+
+ ** Type  o  to open a line below the cursor and place you in Insert mode. **
+
+  1. Move the cursor to the line below marked --->.
+
+  2. Type the lowercase letter  o  to open up a line BELOW the cursor and place
+     you in Insert mode.
+
+  3. Now type some text and press <ESC> to exit Insert mode.
+
+---> After typing  o  the cursor is placed on the open line in Insert mode.
+
+  4. To open up a line ABOVE the cursor, simply type a capital	O , rather
+     than a lowercase  o.  Try this on the line below.
+
+---> Open up a line above this by typing O while the cursor is on this line.
+
+
+
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+			Lesson 6.2: THE APPEND COMMAND
+
+
+	     ** Type  a  to insert text AFTER the cursor. **
+
+  1. Move the cursor to the start of the line below marked --->.
+  
+  2. Press  e  until the cursor is on the end of  li .
+
+  3. Type an  a  (lowercase) to append text AFTER the cursor.
+
+  4. Complete the word like the line below it.  Press <ESC> to exit Insert
+     mode.
+
+  5. Use  e  to move to the next incomplete word and repeat steps 3 and 4.
+  
+---> This li will allow you to pract appendi text to a line.
+---> This line will allow you to practice appending text to a line.
+
+NOTE:  a, i and A all go to the same Insert mode, the only difference is where
+       the characters are inserted.
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+		    Lesson 6.3: ANOTHER WAY TO REPLACE
+
+
+      ** Type a capital  R  to replace more than one character. **
+
+  1. Move the cursor to the first line below marked --->.  Move the cursor to
+     the beginning of the first  xxx .
+
+  2. Now press  R  and type the number below it in the second line, so that it
+     replaces the xxx .
+
+  3. Press <ESC> to leave Replace mode.  Notice that the rest of the line
+     remains unmodified.
+
+  4. Repeat the steps to replace the remaining xxx.
+
+---> Adding 123 to xxx gives you xxx.
+---> Adding 123 to 456 gives you 579.
+
+NOTE:  Replace mode is like Insert mode, but every typed character deletes an
+       existing character.
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+			Lesson 6.4: COPY AND PASTE TEXT
+
+
+	  ** Use the  y  operator to copy text and  p  to paste it **
+
+  1. Go to the line marked with ---> below and place the cursor after "a)".
+  
+  2. Start Visual mode with  v  and move the cursor to just before "first".
+  
+  3. Type  y  to yank (copy) the highlighted text.
+
+  4. Move the cursor to the end of the next line:  j$
+
+  5. Type  p  to put (paste) the text.  Then type:  a second <ESC> .
+
+  6. Use Visual mode to select " item.", yank it with  y , move to the end of
+     the next line with  j$  and put the text there with  p .
+
+--->  a) this is the first item.
+      b)
+
+  NOTE: you can also use  y  as an operator;  yw  yanks one word.
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+			    Lesson 6.5: SET OPTION
+
+
+	  ** Set an option so a search or substitute ignores case **
+
+  1. Search for 'ignore' by entering:   /ignore  <ENTER>
+     Repeat several times by pressing  n .
+
+  2. Set the 'ic' (Ignore case) option by entering:   :set ic
+
+  3. Now search for 'ignore' again by pressing  n
+     Notice that Ignore and IGNORE are now also found.
+
+  4. Set the 'hlsearch' and 'incsearch' options:  :set hls is
+
+  5. Now type the search command again and see what happens:  /ignore <ENTER>
+
+  6. To disable ignoring case enter:  :set noic
+
+NOTE:  To remove the highlighting of matches enter:   :nohlsearch 
+NOTE:  If you want to ignore case for just one search command, use  \c
+       in the phrase:  /ignore\c  <ENTER>
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+			       Lesson 6 SUMMARY
+
+  1. Type  o  to open a line BELOW the cursor and start Insert mode.
+     Type  O  to open a line ABOVE the cursor.
+
+  2. Type  a  to insert text AFTER the cursor.
+     Type  A  to insert text after the end of the line.
+
+  3. The  e  command moves to the end of a word.
+
+  4. The  y  operator yanks (copies) text,  p  puts (pastes) it.
+
+  5. Typing a capital  R  enters Replace mode until  <ESC>  is pressed.
+
+  6. Typing ":set xxx" sets the option "xxx".  Some options are:
+  	'ic' 'ignorecase'	ignore upper/lower case when searching
+	'is' 'incsearch'	show partial matches for a search phrase
+	'hls' 'hlsearch'	highlight all matching phrases
+     You can either use the long or the short option name.
+
+  7. Prepend "no" to switch an option off:   :set noic
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+		       Lesson 7.1: GETTING HELP
+
+
+		      ** Use the on-line help system **
+
+  Vim has a comprehensive on-line help system.  To get started, try one of
+  these three:
+	- press the <HELP> key (if you have one)
+	- press the <F1> key (if you have one)
+	- type   :help <ENTER>
+
+  Read the text in the help window to find out how the help works.
+  Type  CTRL-W CTRL-W   to jump from one window to another.
+  Type    :q <ENTER>    to close the help window.
+
+  You can find help on just about any subject, by giving an argument to the
+  ":help" command.  Try these (don't forget pressing <ENTER>):
+
+	:help w
+	:help c_CTRL-D
+	:help insert-index
+	:help user-manual
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+		      Lesson 7.2: CREATE A STARTUP SCRIPT
+
+
+			  ** Enable Vim features **
+
+  Vim has many more features than Vi, but most of them are disabled by
+  default.  To start using more features you have to create a "vimrc" file.
+
+  1. Start editing the "vimrc" file.  This depends on your system:
+	:e ~/.vimrc		for Unix
+	:e $VIM/_vimrc		for MS-Windows
+
+  2. Now read the example "vimrc" file contents:
+	:r $VIMRUNTIME/vimrc_example.vim
+
+  3. Write the file with:
+	:w
+
+  The next time you start Vim it will use syntax highlighting.
+  You can add all your preferred settings to this "vimrc" file.
+  For more information type  :help vimrc-intro
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+			     Lesson 7.3: COMPLETION
+
+
+	      ** Command line completion with CTRL-D and <TAB> **
+
+  1. Make sure Vim is not in compatible mode:  :set nocp
+
+  2. Look what files exist in the directory:  :!ls   or  :!dir
+
+  3. Type the start of a command:  :e
+
+  4. Press  CTRL-D  and Vim will show a list of commands that start with "e".
+
+  5. Press <TAB>  and Vim will complete the command name to ":edit".
+
+  6. Now add a space and the start of an existing file name:  :edit FIL
+
+  7. Press <TAB>.  Vim will complete the name (if it is unique).
+
+NOTE:  Completion works for many commands.  Just try pressing CTRL-D and
+       <TAB>.  It is especially useful for  :help .
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+			       Lesson 7 SUMMARY
+
+
+  1. Type  :help  or press <F1> or <Help>  to open a help window.
+
+  2. Type  :help cmd  to find help on  cmd .
+
+  3. Type  CTRL-W CTRL-W  to jump to another window
+
+  4. Type  :q  to close the help window
+
+  5. Create a vimrc startup script to keep your preferred settings.
+
+  6. When typing a  :  command, press CTRL-D to see possible completions.
+     Press <TAB> to use one completion.
+
+
+
+
+
+
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+  This concludes the Vim Tutor.  It was intended to give a brief overview of
+  the Vim editor, just enough to allow you to use the editor fairly easily.
+  It is far from complete as Vim has many many more commands.  Read the user
+  manual next: ":help user-manual".
+
+  For further reading and studying, this book is recommended:
+	Vim - Vi Improved - by Steve Oualline
+	Publisher: New Riders
+  The first book completely dedicated to Vim.  Especially useful for beginners.
+  There are many examples and pictures.
+  See http://iccf-holland.org/click5.html
+
+  This book is older and more about Vi than Vim, but also recommended:
+	Learning the Vi Editor - by Linda Lamb
+	Publisher: O'Reilly & Associates Inc.
+  It is a good book to get to know almost anything you want to do with Vi.
+  The sixth edition also includes information on Vim.
+
+  This tutorial was written by Michael C. Pierce and Robert K. Ware,
+  Colorado School of Mines using ideas supplied by Charles Smith,
+  Colorado State University.  E-mail: bware@mines.colorado.edu.
+
+  Modified for Vim by Bram Moolenaar.
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
--- /dev/null
+++ b/lib/vimfiles/tutor/tutor.vim
@@ -1,0 +1,173 @@
+" Vim tutor support file
+" Author: Eduardo F. Amatria <eferna1@platea.pntic.mec.es>
+" Last Change:	2007 Mar 01
+
+" This small source file is used for detecting if a translation of the
+" tutor file exist, i.e., a tutor.xx file, where xx is the language.
+" If the translation does not exist, or no extension is given,
+" it defaults to the english version.
+
+" It is invoked by the vimtutor shell script.
+
+" 1. Build the extension of the file, if any:
+let s:ext = ""
+if strlen($xx) > 1
+  let s:ext = "." . $xx
+else
+  let s:lang = ""
+  " Check that a potential value has at least two letters.
+  " Ignore "1043" and "C".
+  if exists("v:lang") && v:lang =~ '\a\a'
+    let s:lang = v:lang
+  elseif $LC_ALL =~ '\a\a'
+    let s:lang = $LC_ALL
+  elseif $LANG =~ '\a\a'
+    let s:lang = $LANG
+  endif
+  if s:lang != ""
+    " Remove "@euro" (ignoring case), it may be at the end
+    let s:lang = substitute(s:lang, '\c@euro', '', '')
+    " On MS-Windows it may be German_Germany.1252 or Polish_Poland.1250.  How
+    " about other languages?
+    if s:lang =~ "German"
+      let s:ext = ".de"
+    elseif s:lang =~ "Polish"
+      let s:ext = ".pl"
+    elseif s:lang =~ "Slovak"
+      let s:ext = ".sk"
+    elseif s:lang =~ "Czech"
+      let s:ext = ".cs"
+    elseif s:lang =~ "Dutch"
+      let s:ext = ".nl"
+    else
+      let s:ext = "." . strpart(s:lang, 0, 2)
+    endif
+  endif
+endif
+
+" The japanese tutor is available in two encodings, guess which one to use
+" The "sjis" one is actually "cp932", it doesn't matter for this text.
+if s:ext =~? '\.ja'
+  if &enc =~ "euc"
+    let s:ext = ".ja.euc"
+  elseif &enc =~ "utf-8$"
+    let s:ext = ".ja.utf-8"
+  else
+    let s:ext = ".ja.sjis"
+  endif
+endif
+
+" The korean tutor is available in two encodings, guess which one to use
+if s:ext =~? '\.ko'
+  if &enc =~ "utf-8$"
+    let s:ext = ".ko.utf-8"
+  else
+    let s:ext = ".ko.euc"
+  endif
+endif
+
+" The Chinese tutor is available in two encodings, guess which one to use
+" This segment is from the above lines and modified by
+" Mendel L Chan <beos@turbolinux.com.cn> for Chinese vim tutorial
+if s:ext =~? '\.zh'
+  if &enc =~ 'big5\|cp950'
+    let s:ext = ".zh.big5"
+  else
+    let s:ext = ".zh.euc"
+  endif
+endif
+
+" The Polish tutor is available in two encodings, guess which one to use.
+if s:ext =~? '\.pl'
+  if &enc =~ 1250
+    let s:ext = ".pl.cp1250"
+  elseif &enc =~ "utf-8$"
+    let s:ext = ".pl.utf-8"
+  endif
+endif
+
+" The Turkish tutor is available in two encodings, guess which one to use
+if s:ext =~? '\.tr'
+  if &enc == "utf-8"
+    let s:ext = ".tr.utf-8"
+  elseif &enc == "iso-8859-9"
+    let s:ext = ".tr.iso9"
+  endif
+endif
+
+" The Greek tutor is available in three encodings, guess what to use.
+" We used ".gr" (Greece) instead of ".el" (Greek); accept both.
+if s:ext =~? '\.gr\|\.el'
+  if &enc == "iso-8859-7"
+    let s:ext = ".gr"
+  elseif &enc == "utf-8"
+    let s:ext = ".gr.utf-8"
+  elseif &enc =~ 737
+    let s:ext = ".gr.cp737"
+  endif
+endif
+
+" The Slovak tutor is available in three encodings, guess which one to use
+if s:ext =~? '\.sk'
+  if &enc == 'utf-8'
+    let s:ext = ".sk.utf-8"
+  elseif &enc =~ 1250
+    let s:ext = ".sk.cp1250"
+  endif
+endif
+
+" The Czech tutor is available in three encodings, guess which one to use
+if s:ext =~? '\.cs'
+  if &enc == 'utf-8'
+    let s:ext = ".cs.utf-8"
+  elseif &enc =~ 1250
+    let s:ext = ".cs.cp1250"
+  endif
+endif
+
+" The Russian tutor is available in three encodings, guess which one to use.
+if s:ext =~? '\.ru'
+  if &enc == 'utf-8'
+    let s:ext = '.ru.utf-8'
+  elseif &enc =~ '1251'
+    let s:ext = '.ru.cp1251'
+  elseif &enc =~ 'koi8'
+    let s:ext = '.ru'
+  endif
+endif
+
+" The Hungarian tutor is available in two encodings, guess which one to use.
+if s:ext =~? '\.hu'
+  if &enc == 'utf-8'
+    let s:ext = '.hu.utf-8'
+  elseif &enc =~ 'iso-8859-2'
+    let s:ext = '.hu'
+  endif
+endif
+
+" Somehow ".ge" (Germany) is sometimes used for ".de" (Deutsch).
+if s:ext =~? '\.ge'
+  let s:ext = ".de"
+endif
+
+if s:ext =~? '\.en'
+  let s:ext = ""
+endif
+
+" 2. Build the name of the file:
+let s:tutorfile = "/tutor/tutor"
+let s:tutorxx = $VIMRUNTIME . s:tutorfile . s:ext
+
+" 3. Finding the file:
+if filereadable(s:tutorxx)
+  let $TUTOR = s:tutorxx
+else
+  let $TUTOR = $VIMRUNTIME . s:tutorfile
+  echo "The file " . s:tutorxx . " does not exist.\n"
+  echo "Copying English version: " . $TUTOR
+  4sleep
+endif
+
+" 4. Making the copy and exiting Vim:
+e $TUTOR
+wq! $TUTORCOPY
--- /dev/null
+++ b/lib/vimfiles/vimrc_example.vim
@@ -1,0 +1,85 @@
+" An example for a vimrc file.
+"
+" Maintainer:	Bram Moolenaar <Bram@vim.org>
+" Last change:	2006 Nov 16
+"
+" To use it, copy it to
+"     for Unix and OS/2:  ~/.vimrc
+"	      for Amiga:  s:.vimrc
+"  for MS-DOS and Win32:  $VIM\_vimrc
+"	    for OpenVMS:  sys$login:.vimrc
+
+" When started as "evim", evim.vim will already have done these settings.
+if v:progname =~? "evim"
+  finish
+endif
+
+" Use Vim settings, rather then Vi settings (much better!).
+" This must be first, because it changes other options as a side effect.
+set nocompatible
+
+" allow backspacing over everything in insert mode
+set backspace=indent,eol,start
+
+if has("vms")
+  set nobackup		" do not keep a backup file, use versions instead
+else
+  set backup		" keep a backup file
+endif
+set history=50		" keep 50 lines of command line history
+set ruler		" show the cursor position all the time
+set showcmd		" display incomplete commands
+set incsearch		" do incremental searching
+
+" For Win32 GUI: remove 't' flag from 'guioptions': no tearoff menu entries
+" let &guioptions = substitute(&guioptions, "t", "", "g")
+
+" Don't use Ex mode, use Q for formatting
+map Q gq
+
+" In many terminal emulators the mouse works just fine, thus enable it.
+set mouse=a
+
+" Switch syntax highlighting on, when the terminal has colors
+" Also switch on highlighting the last used search pattern.
+if &t_Co > 2 || has("gui_running")
+  syntax on
+  set hlsearch
+endif
+
+" Only do this part when compiled with support for autocommands.
+if has("autocmd")
+
+  " Enable file type detection.
+  " Use the default filetype settings, so that mail gets 'tw' set to 72,
+  " 'cindent' is on in C files, etc.
+  " Also load indent files, to automatically do language-dependent indenting.
+  filetype plugin indent on
+
+  " Put these in an autocmd group, so that we can delete them easily.
+  augroup vimrcEx
+  au!
+
+  " For all text files set 'textwidth' to 78 characters.
+  autocmd FileType text setlocal textwidth=78
+
+  " When editing a file, always jump to the last known cursor position.
+  " Don't do it when the position is invalid or when inside an event handler
+  " (happens when dropping a file on gvim).
+  autocmd BufReadPost *
+    \ if line("'\"") > 0 && line("'\"") <= line("$") |
+    \   exe "normal! g`\"" |
+    \ endif
+
+  augroup END
+
+else
+
+  set autoindent		" always set autoindenting on
+
+endif " has("autocmd")
+
+" Convenient command to see the difference between the current buffer and the
+" file it was loaded from, thus the changes you made.
+command DiffOrig vert new | set bt=nofile | r # | 0d_ | diffthis
+	 	\ | wincmd p | diffthis
--- /dev/null
+++ b/macros.h
@@ -1,0 +1,284 @@
+/* vi:set ts=8 sts=4 sw=4:
+ *
+ * VIM - Vi IMproved	by Bram Moolenaar
+ *
+ * Do ":help uganda"  in Vim to read copying and usage conditions.
+ * Do ":help credits" in Vim to see a list of people who contributed.
+ */
+
+/*
+ * macros.h: macro definitions for often used code
+ */
+
+/*
+ * pchar(lp, c) - put character 'c' at position 'lp'
+ */
+#define pchar(lp, c) (*(ml_get_buf(curbuf, (lp).lnum, TRUE) + (lp).col) = (c))
+
+/*
+ * Position comparisons
+ */
+#ifdef FEAT_VIRTUALEDIT
+# define lt(a, b) (((a).lnum != (b).lnum) \
+		   ? (a).lnum < (b).lnum \
+		   : (a).col != (b).col \
+		       ? (a).col < (b).col \
+		       : (a).coladd < (b).coladd)
+# define ltp(a, b) (((a)->lnum != (b)->lnum) \
+		   ? (a)->lnum < (b)->lnum \
+		   : (a)->col != (b)->col \
+		       ? (a)->col < (b)->col \
+		       : (a)->coladd < (b)->coladd)
+# define equalpos(a, b) (((a).lnum == (b).lnum) && ((a).col == (b).col) && ((a).coladd == (b).coladd))
+# define clearpos(a) {(a)->lnum = 0; (a)->col = 0; (a)->coladd = 0;}
+#else
+# define lt(a, b) (((a).lnum != (b).lnum) \
+		   ? ((a).lnum < (b).lnum) : ((a).col < (b).col))
+# define ltp(a, b) (((a)->lnum != (b)->lnum) \
+		   ? ((a)->lnum < (b)->lnum) : ((a)->col < (b)->col))
+# define equalpos(a, b) (((a).lnum == (b).lnum) && ((a).col == (b).col))
+# define clearpos(a) {(a)->lnum = 0; (a)->col = 0;}
+#endif
+
+#define ltoreq(a, b) (lt(a, b) || equalpos(a, b))
+
+/*
+ * lineempty() - return TRUE if the line is empty
+ */
+#define lineempty(p) (*ml_get(p) == NUL)
+
+/*
+ * bufempty() - return TRUE if the current buffer is empty
+ */
+#define bufempty() (curbuf->b_ml.ml_line_count == 1 && *ml_get((linenr_T)1) == NUL)
+
+/*
+ * toupper() and tolower() that use the current locale.
+ * On some systems toupper()/tolower() only work on lower/uppercase characters
+ * Careful: Only call TOUPPER_LOC() and TOLOWER_LOC() with a character in the
+ * range 0 - 255.  toupper()/tolower() on some systems can't handle others.
+ * Note: for UTF-8 use utf_toupper() and utf_tolower().
+ */
+#ifdef MSWIN
+#  define TOUPPER_LOC(c)	toupper_tab[(c) & 255]
+#  define TOLOWER_LOC(c)	tolower_tab[(c) & 255]
+#else
+# ifdef BROKEN_TOUPPER
+#  define TOUPPER_LOC(c)	(islower(c) ? toupper(c) : (c))
+#  define TOLOWER_LOC(c)	(isupper(c) ? tolower(c) : (c))
+# else
+#  define TOUPPER_LOC		toupper
+#  define TOLOWER_LOC		tolower
+# endif
+#endif
+
+/* toupper() and tolower() for ASCII only and ignore the current locale. */
+#ifdef EBCDIC
+# define TOUPPER_ASC(c)	(islower(c) ? toupper(c) : (c))
+# define TOLOWER_ASC(c)	(isupper(c) ? tolower(c) : (c))
+#else
+# define TOUPPER_ASC(c)	(((c) < 'a' || (c) > 'z') ? (c) : (c) - ('a' - 'A'))
+# define TOLOWER_ASC(c)	(((c) < 'A' || (c) > 'Z') ? (c) : (c) + ('a' - 'A'))
+#endif
+
+/*
+ * MB_ISLOWER() and MB_ISUPPER() are to be used on multi-byte characters.  But
+ * don't use them for negative values!
+ */
+#ifdef FEAT_MBYTE
+# define MB_ISLOWER(c)	vim_islower(c)
+# define MB_ISUPPER(c)	vim_isupper(c)
+# define MB_TOLOWER(c)	vim_tolower(c)
+# define MB_TOUPPER(c)	vim_toupper(c)
+#else
+# define MB_ISLOWER(c)	islower(c)
+# define MB_ISUPPER(c)	isupper(c)
+# define MB_TOLOWER(c)	TOLOWER_LOC(c)
+# define MB_TOUPPER(c)	TOUPPER_LOC(c)
+#endif
+
+/* Like isalpha() but reject non-ASCII characters.  Can't be used with a
+ * special key (negative value). */
+#ifdef EBCDIC
+# define ASCII_ISALPHA(c) isalpha(c)
+# define ASCII_ISALNUM(c) isalnum(c)
+# define ASCII_ISLOWER(c) islower(c)
+# define ASCII_ISUPPER(c) isupper(c)
+#else
+# define ASCII_ISALPHA(c) ((c) < 0x7f && isalpha(c))
+# define ASCII_ISALNUM(c) ((c) < 0x7f && isalnum(c))
+# define ASCII_ISLOWER(c) ((c) < 0x7f && islower(c))
+# define ASCII_ISUPPER(c) ((c) < 0x7f && isupper(c))
+#endif
+
+/* Use our own isdigit() replacement, because on MS-Windows isdigit() returns
+ * non-zero for superscript 1.  Also avoids that isdigit() crashes for numbers
+ * below 0 and above 255.  For complicated arguments and in/decrement use
+ * vim_isdigit() instead. */
+#define VIM_ISDIGIT(c) ((c) >= '0' && (c) <= '9')
+
+/* macro version of chartab().
+ * Only works with values 0-255!
+ * Doesn't work for UTF-8 mode with chars >= 0x80. */
+#define CHARSIZE(c)	(chartab[c] & CT_CELL_MASK)
+
+#ifdef FEAT_LANGMAP
+/*
+ * Adjust chars in a language according to 'langmap' option.
+ * NOTE that there is NO overhead if 'langmap' is not set; but even
+ * when set we only have to do 2 ifs and an array lookup.
+ * Don't apply 'langmap' if the character comes from the Stuff buffer.
+ * The do-while is just to ignore a ';' after the macro.
+ */
+# define LANGMAP_ADJUST(c, condition) do { \
+	if (*p_langmap && (condition) && !KeyStuffed && (c) >= 0 && (c) < 256) \
+	    c = langmap_mapchar[c]; \
+    } while (0)
+#endif
+
+/*
+ * vim_isbreak() is used very often if 'linebreak' is set, use a macro to make
+ * it work fast.
+ */
+#define vim_isbreak(c) (breakat_flags[(char_u)(c)])
+
+/*
+ * On VMS file names are different and require a translation.
+ * On the Mac open() has only two arguments.
+ */
+#ifdef VMS
+# define mch_access(n, p)	access(vms_fixfilename(n), (p))
+				/* see mch_open() comment */
+# define mch_fopen(n, p)	fopen(vms_fixfilename(n), (p))
+# define mch_fstat(n, p)	fstat(vms_fixfilename(n), (p))
+	/* VMS does not have lstat() */
+# define mch_stat(n, p)		stat(vms_fixfilename(n), (p))
+#else
+# ifndef WIN32
+#   define mch_access(n, p)	access((n), (p))
+# endif
+# if !(defined(FEAT_MBYTE) && defined(WIN3264))
+#  define mch_fopen(n, p)	fopen((n), (p))
+# endif
+# define mch_fstat(n, p)	fstat((n), (p))
+# ifdef MSWIN	/* has it's own mch_stat() function */
+#  define mch_stat(n, p)	vim_stat((n), (p))
+# else
+#  ifdef STAT_IGNORES_SLASH
+    /* On Solaris stat() accepts "file/" as if it was "file".  Return -1 if
+     * the name ends in "/" and it's not a directory. */
+#   define mch_stat(n, p)	(illegal_slash(n) ? -1 : stat((n), (p)))
+#  else
+#   define mch_stat(n, p)	stat((n), (p))
+#  endif
+# endif
+#endif
+
+#ifdef HAVE_LSTAT
+# define mch_lstat(n, p)	lstat((n), (p))
+#else
+# define mch_lstat(n, p)	mch_stat((n), (p))
+#endif
+
+#ifdef MACOS_CLASSIC
+/* MacOS classic doesn't support perm but MacOS X does. */
+# define mch_open(n, m, p)	open((n), (m))
+#else
+# ifdef VMS
+/*
+ * It is possible to force some record format with:
+ * #  define mch_open(n, m, p) open(vms_fixfilename(n), (m), (p)), "rat=cr", "rfm=stmlf", "mrs=0")
+ * but it is not recommended, because it can destroy indexes etc.
+ */
+#  define mch_open(n, m, p)	open(vms_fixfilename(n), (m), (p))
+# else
+#  if !(defined(FEAT_MBYTE) && defined(WIN3264))
+#   define mch_open(n, m, p)	open((n), (m), (p))
+#  endif
+# endif
+#endif
+
+/* mch_open_rw(): invoke mch_open() with third argument for user R/W. */
+#if defined(UNIX) || defined(VMS) || defined(PLAN9)  /* open in rw------- mode */
+# define mch_open_rw(n, f)	mch_open((n), (f), (mode_t)0600)
+#else
+# if defined(MSDOS) || defined(MSWIN) || defined(OS2)  /* open read/write */
+#  define mch_open_rw(n, f)	mch_open((n), (f), S_IREAD | S_IWRITE)
+# else
+#  define mch_open_rw(n, f)	mch_open((n), (f), 0)
+# endif
+#endif
+
+/*
+ * Encryption macros.  Mohsin Ahmed, mosh@sasi.com 98-09-24
+ * Based on zip/crypt sources.
+ */
+
+#ifdef FEAT_CRYPT
+
+/* encode byte c, using temp t.  Warning: c must not have side effects. */
+# define ZENCODE(c, t)  (t = decrypt_byte(), update_keys(c), t^(c))
+
+/* decode byte c in place */
+# define ZDECODE(c)   update_keys(c ^= decrypt_byte())
+
+#endif
+
+#ifdef STARTUPTIME
+# define TIME_MSG(s) time_msg(s, NULL)
+#else
+# define TIME_MSG(s)
+#endif
+
+#ifdef FEAT_VREPLACE
+# define REPLACE_NORMAL(s) (((s) & REPLACE_FLAG) && !((s) & VREPLACE_FLAG))
+#else
+# define REPLACE_NORMAL(s) ((s) & REPLACE_FLAG)
+#endif
+
+#ifdef FEAT_ARABIC
+# define UTF_COMPOSINGLIKE(p1, p2)  utf_composinglike((p1), (p2))
+#else
+# define UTF_COMPOSINGLIKE(p1, p2)  utf_iscomposing(utf_ptr2char(p2))
+#endif
+
+#ifdef FEAT_RIGHTLEFT
+    /* Whether to draw the vertical bar on the right side of the cell. */
+# define CURSOR_BAR_RIGHT (curwin->w_p_rl && (!(State & CMDLINE) || cmdmsg_rl))
+#endif
+
+/*
+ * mb_ptr_adv(): advance a pointer to the next character, taking care of
+ * multi-byte characters if needed.
+ * mb_ptr_back(): backup a pointer to the previous character, taking care of
+ * multi-byte characters if needed.
+ * MB_COPY_CHAR(f, t): copy one char from "f" to "t" and advance the pointers.
+ * PTR2CHAR(): get character from pointer.
+ */
+#ifdef FEAT_MBYTE
+/* Advance multi-byte pointer, skip over composing chars. */
+# define mb_ptr_adv(p)	    p += has_mbyte ? (*mb_ptr2len)(p) : 1
+/* Advance multi-byte pointer, do not skip over composing chars. */
+# define mb_cptr_adv(p)	    p += enc_utf8 ? utf_ptr2len(p) : has_mbyte ? (*mb_ptr2len)(p) : 1
+/* Backup multi-byte pointer. */
+# define mb_ptr_back(s, p)  p -= has_mbyte ? ((*mb_head_off)(s, p - 1) + 1) : 1
+/* get length of multi-byte char, not including composing chars */
+# define mb_cptr2len(p)	    (enc_utf8 ? utf_ptr2len(p) : (*mb_ptr2len)(p))
+
+# define MB_COPY_CHAR(f, t) if (has_mbyte) mb_copy_char(&f, &t); else *t++ = *f++
+# define MB_CHARLEN(p)	    (has_mbyte ? mb_charlen(p) : STRLEN(p))
+# define PTR2CHAR(p)	    (has_mbyte ? mb_ptr2char(p) : (int)*(p))
+#else
+# define mb_ptr_adv(p)		++p
+# define mb_cptr_adv(p)		++p
+# define mb_ptr_back(s, p)	--p
+# define MB_COPY_CHAR(f, t)	*t++ = *f++
+# define MB_CHARLEN(p)		STRLEN(p)
+# define PTR2CHAR(p)		((int)*(p))
+#endif
+
+#ifdef FEAT_AUTOCHDIR
+# define DO_AUTOCHDIR if (p_acd) do_autochdir();
+#else
+# define DO_AUTOCHDIR
+#endif
--- /dev/null
+++ b/main.aap
@@ -1,0 +1,1215 @@
+# A-A-P recipe for building Vim
+#
+# There are no user choices in here!
+# Put configure arguments in the file config.arg.
+# Later there will be a config.txt file that contains examples and
+# explanations.
+#
+# Optional arguments:
+#  PREFIX=dir           Overrules the install directory.
+#                       Can be specified when installing only.
+#                       Example: aap install PREFIX=$HOME
+#
+@if os.name != "posix":
+    :error Sorry, this recipe only works for Unix-like systems.
+
+# Skip the configure stuff when "link.sh" is executing this recipe recursively
+# to build pathdef.c or not building something and auto/config.aap does exist.
+@if ((_no.TARGETARG != "pathdef" and has_build_target())
+@       or not os.path.exists("auto/config.aap")):
+
+    #
+    # A U T O C O N F
+    #
+
+    # Run autoconf when configure.in has been changed since it was last run.
+    # This is skipped when the signatures in "mysign" are up-to-date.  When
+    # there is no autoconf program skip this (the signature is often the only
+    # thing that's outdated)
+    auto/configure {signfile = mysign} : configure.in
+        @if not program_path("autoconf"):
+            :print Can't find autoconf, using existing configure script.
+        @else:
+            # Move configure aside, autoconf would overwrite it
+            :move {exist} configure configure.save
+            :sys autoconf
+            :cat configure | :eval re.sub('\\./config.log', 'auto/config.log', stdin) | :eval re.sub('>config.log', '>auto/config.log', stdin) >! auto/configure
+            :chmod 755 auto/configure
+            :move configure.save configure
+            :del {force} auto/config.cache auto/config.status
+
+    # Change the configure script to produce config.aap instead of config.mk.
+    auto/configure.aap : auto/configure
+        :print Adjusting auto/configure for A-A-P.
+        :cat auto/configure | :eval re.sub("config.mk", "config.aap", stdin)
+                                                        >! auto/configure.aap
+        :chmod 755 auto/configure.aap
+
+    # The configure script uses the directory where it's located, use a link.
+    configure.aap:  {buildcheck=}
+        :symlink {f} auto/configure.aap configure.aap
+
+    # Dependency: run configure.aap to update config.h and config.aap in the
+    # "auto" directory.
+    # NOTE: we can only build for one architecture, because -MM doesn't work
+    # when building for both.
+    config {virtual} auto/config.h auto/config.aap :
+                         auto/configure.aap configure.aap
+                         config.arg config.h.in config.aap.in
+        :sys CONFIG_STATUS=auto/config.status
+                ./configure.aap `file2string("config.arg")`
+                    --with-mac-arch=ppc
+                    --cache-file=auto/config.cache
+
+    # Configure arguments: create an empty "config.arg" file when its missing
+    config.arg:
+        :touch {exist} config.arg
+
+    # "auto/config.aap" contains a lot of settings, such as the name of the
+    # executable "Target".
+    # First update it, forcefully if the "reconfig" target was used.
+    @if _no.TARGETARG != "comment" and _no.TARGETARG != "make":
+        @if "reconfig" in var2list(_no.TARGETARG):
+            :del {force} auto/config.cache auto/config.status
+            :update {force} auto/config.aap
+        @else:
+            :update auto/config.aap
+
+# Include the recipe that autoconf generated.
+:include auto/config.aap
+
+# Unfortunately "-M" doesn't work when building for two architectures.  Switch
+# back to PPC only.
+@if string.find(_no.CPPFLAGS, "-arch i386 -arch ppc") >= 0:
+    CPPFLAGS = `string.replace(_no.CPPFLAGS, "-arch i386 -arch ppc", "-arch ppc")`
+
+# A "PREFIX=dir" argument overrules the value of $prefix
+# But don't use the default "/usr/local".
+@if _no.get("PREFIX") and _no.get("PREFIX") != '/usr/local':
+    prefix = $PREFIX
+
+# Don't want "~/" in prefix.
+prefix = `os.path.expanduser(prefix)`
+
+# For Mac.
+APPDIR = $(VIMNAME).app
+
+### Names of the programs and targets
+VIMTARGET       = $VIMNAME$EXESUF
+EXTARGET        = $EXNAME$LNKSUF
+VIEWTARGET      = $VIEWNAME$LNKSUF
+GVIMNAME        = g$VIMNAME
+GVIMTARGET      = $GVIMNAME$LNKSUF
+GVIEWNAME       = g$VIEWNAME
+GVIEWTARGET     = $GVIEWNAME$LNKSUF
+RVIMNAME        = r$VIMNAME
+RVIMTARGET      = $RVIMNAME$LNKSUF
+RVIEWNAME       = r$VIEWNAME
+RVIEWTARGET     = $RVIEWNAME$LNKSUF
+RGVIMNAME       = r$GVIMNAME
+RGVIMTARGET     = $RGVIMNAME$LNKSUF
+RGVIEWNAME      = r$GVIEWNAME
+RGVIEWTARGET    = $RGVIEWNAME$LNKSUF
+VIMDIFFNAME     = $(VIMNAME)diff
+GVIMDIFFNAME    = g$VIMDIFFNAME
+VIMDIFFTARGET   = $VIMDIFFNAME$LNKSUF
+GVIMDIFFTARGET  = $GVIMDIFFNAME$LNKSUF
+EVIMNAME        = e$VIMNAME
+EVIMTARGET      = $EVIMNAME$LNKSUF
+EVIEWNAME       = e$VIEWNAME
+EVIEWTARGET     = $EVIEWNAME$LNKSUF
+
+#
+# G U I  variant
+#
+# The GUI is selected by configure, a lot of other things depend on it.
+#
+:variant GUI
+    GTK
+        GUI_SRC         = gui.c gui_gtk.c gui_gtk_x11.c pty.c gui_beval.c
+                            gui_gtk_f.c
+        GUI_OBJ         =
+        GUI_DEFS        = -DFEAT_GUI_GTK $NARROW_PROTO
+        GUI_IPATH       = $GUI_INC_LOC
+        GUI_LIBS_DIR    = $GUI_LIB_LOC
+        GUI_LIBS1       =
+        GUI_LIBS2       = $GTK_LIBNAME
+        GUI_INSTALL     = install_normal
+        GUI_TARGETS     = installglinks
+        GUI_MAN_TARGETS = yes
+        GUI_TESTTARGET  = gui
+        GUI_BUNDLE      =
+        GUI_TESTARG     =
+    MOTIF
+        GUI_SRC         = gui.c gui_motif.c gui_x11.c pty.c gui_beval.c
+                          gui_xmdlg.c gui_xmebw.c
+        GUI_OBJ         =
+        GUI_DEFS        = -DFEAT_GUI_MOTIF $NARROW_PROTO
+        GUI_IPATH       = $GUI_INC_LOC
+        GUI_LIBS_DIR    = $GUI_LIB_LOC
+        GUI_LIBS1       =
+        GUI_LIBS2       = $MOTIF_LIBNAME -lXt
+        GUI_INSTALL     = install_normal
+        GUI_TARGETS     = installglinks
+        GUI_MAN_TARGETS = yes
+        GUI_TESTTARGET  = gui
+        GUI_BUNDLE      =
+        GUI_TESTARG     =
+    ATHENA
+        # XAW_LIB et al. can be overruled to use Xaw3d widgets
+        XAW_LIB         ?= -lXaw
+        GUI_SRC         =  gui.c gui_athena.c gui_x11.c pty.c gui_beval.c \
+                            gui_at_sb.c gui_at_fs.c
+        GUI_OBJ         =
+        GUI_DEFS        = -DFEAT_GUI_ATHENA $NARROW_PROTO
+        GUI_IPATH       = $GUI_INC_LOC
+        GUI_LIBS_DIR    = $GUI_LIB_LOC
+        GUI_LIBS1       = $XAW_LIB
+        GUI_LIBS2       = -lXt
+        GUI_INSTALL     = install_normal
+        GUI_TARGETS     = installglinks
+        GUI_MAN_TARGETS = yes
+        GUI_TESTTARGET  = gui
+        GUI_BUNDLE      =
+        GUI_TESTARG     =
+    NEXTAW
+        # XAW_LIB et al. can be overruled to use Xaw3d widgets
+        XAW_LIB         ?= -lXaw
+        GUI_SRC         =  gui.c gui_athena.c gui_x11.c pty.c gui_beval.c
+                            gui_at_fs.c
+        GUI_OBJ         =
+        GUI_DEFS        = -DFEAT_GUI_ATHENA -DFEAT_GUI_NEXTAW $NARROW_PROTO
+        GUI_IPATH       = $GUI_INC_LOC
+        GUI_LIBS_DIR    = $GUI_LIB_LOC
+        GUI_LIBS1       = $NEXTAW_LIB
+        GUI_LIBS2       = -lXt
+        GUI_INSTALL     = install_normal
+        GUI_TARGETS     = installglinks
+        GUI_MAN_TARGETS = yes
+        GUI_TESTTARGET  = gui
+        GUI_BUNDLE      =
+        GUI_TESTARG     =
+    CARBONGUI
+        GUI_SRC         =  gui.c gui_mac.c pty.c
+        GUI_OBJ         =
+        GUI_DEFS        = -DFEAT_GUI_MAC -fno-common -fpascal-strings \
+                            -Wall -Wno-unknown-pragmas -mdynamic-no-pic -pipe
+        GUI_IPATH       = $GUI_INC_LOC
+        GUI_LIBS_DIR    = $GUI_LIB_LOC
+        GUI_LIBS1       = -framework Carbon
+        GUI_LIBS2       =
+        GUI_INSTALL     = install_macosx
+        GUI_TARGETS     = installglinks
+        GUI_MAN_TARGETS = yes
+        GUI_TESTTARGET  = gui
+        GUI_BUNDLE      = gui_bundle
+        GUI_TESTARG     = VIMPROG=../$(APPDIR)/Contents/MacOS/$(VIMTARGET)
+    PHOTONGUI
+        GUI_SRC         = gui.c gui_photon.c pty.c
+        GUI_OBJ         =
+        GUI_DEFS        = -DFEAT_GUI_PHOTON
+        GUI_IPATH       =
+        GUI_LIBS_DIR    =
+        GUI_LIBS1       = -lph -lphexlib
+        GUI_LIBS2       =
+        GUI_INSTALL     = install_normal
+        GUI_TARGETS     = installglinks
+        GUI_MAN_TARGETS = yes
+        GUI_TESTTARGET  = gui
+        GUI_BUNDLE      =
+        GUI_TESTARG     =
+    *
+        GUI_SRC         =
+        GUI_OBJ         =
+        GUI_DEFS        =
+        GUI_IPATH       =
+        GUI_LIBS_DIR    =
+        GUI_LIBS1       =
+        GUI_LIBS2       =
+        GUI_INSTALL     = install_normal
+        GUI_TARGETS     =
+        GUI_MAN_TARGETS =
+        GUI_TESTTARGET  =
+        GUI_BUNDLE      =
+        GUI_TESTARG     =
+
+
+PRE_DEFS = -Iproto -I. $DEFS $GUI_DEFS $GUI_IPATH $CPPFLAGS $?(EXTRA_IPATHS)
+POST_DEFS = $X_CFLAGS $MZSCHEME_CFLAGS $PERL_CFLAGS $PYTHON_CFLAGS $TCL_CFLAGS $RUBY_CFLAGS $?(EXTRA_DEFS)
+CFLAGS = $PRE_DEFS $CONF_CFLAGS $?(PROFILE_CFLAGS) $POST_DEFS
+CPPFLAGS =
+
+ALL_LIB_DIRS = $GUI_LIBS_DIR $X_LIBS_DIR
+LDFLAGS = $ALL_LIB_DIRS $CONF_LDFLAGS
+LIBS = $GUI_LIBS1 $GUI_X_LIBS $GUI_LIBS2 $X_PRE_LIBS $X_LIBS $X_EXTRA_LIBS $CONF_LIBS $?(EXTRA_LIBS) $MZSCHEME_LIBS $PERL_LIBS $PYTHON_LIBS $TCL_LIBS $RUBY_LIBS $?(PROFILE_LIBS)
+
+Target = $VIMNAME
+
+# reconfig target also builds Vim (reconfiguration is handled above).
+reconfig {virtual}: $Target
+
+distclean: clean
+    :del {force} auto/config.h auto/config.aap
+    :del {force} auto/config.cache auto/config.status
+
+
+# Execute the test scripts.  Run these after compiling Vim, before installing.
+#
+# This will produce a lot of garbage on your screen, including a few error
+# messages.  Don't worry about that.
+# If there is a real error, there will be a difference between "test.out" and
+# a "test99.ok" file.
+# If everything is alright, the final message will be "ALL DONE".
+#
+test check:
+    VimProg = ../$Target
+    :execute testdir/main.aap $GUI_TESTTARGET $GUI_TESTARG
+
+testclean {virtual}:
+    :del {force} testdir/*.out testdir/test.log
+
+# When no fetch target exists we are not a child of the ../main.aap recipe,
+# Use ../main.aap to do the fetching.
+# --- If you get an error here for wrong number of arguments, you need to
+#     update to a newer version of A-A-P.
+@if not has_target("fetch"):
+    fetch:
+        :execute ../main.aap fetch
+
+
+# All the source files that need to be compiled.
+# Some are optional and depend on configure.
+# "version.c" is missing, it's always compiled (see below).
+Source =
+        buffer.c
+        charset.c
+        diff.c
+        digraph.c
+        edit.c
+        eval.c
+        ex_cmds.c
+        ex_cmds2.c
+        ex_docmd.c
+        ex_eval.c
+        ex_getln.c
+        fileio.c
+        fold.c
+        getchar.c
+        hardcopy.c
+        hashtab.c
+        if_cscope.c
+        if_xcmdsrv.c
+        main.c
+        mark.c
+        memfile.c
+        memline.c
+        menu.c
+        message.c
+        misc1.c
+        misc2.c
+        move.c
+        mbyte.c
+        normal.c
+        ops.c
+        option.c
+        os_unix.c
+        auto/pathdef.c
+        popupmnu.c
+        quickfix.c
+        regexp.c
+        screen.c
+        search.c
+        spell.c
+        syntax.c
+        tag.c
+        term.c
+        ui.c
+        undo.c
+        window.c
+        $OS_EXTRA_SRC
+        $GUI_SRC
+        $HANGULIN_SRC
+        $MZSCHEME_SRC
+        $PERL_SRC
+        $NETBEANS_SRC
+        $PYTHON_SRC
+        $TCL_SRC
+        $RUBY_SRC
+        $SNIFF_SRC
+        $WORKSHOP_SRC
+
+Objects =
+        $GUI_OBJ
+
+# TODO: make is still used for subdirectories, need to write a recipe.
+MAKE ?= make
+
+all: $Target $GUI_BUNDLE
+
+# This dependency is required to build auto/osdef.h before automatic
+# dependencies are generated.
+$Source version.c : auto/osdef.h
+
+# Need to mention that the target also depends on version.c, since it's not
+# included in $Source
+$Target : version.c
+
+# Some sources are to be found in the "auto" directory.
+SRCPATH += auto
+
+# When building Vim always compile version.c to get the timestamp.
+:filetype
+    declare my_prog
+:attr {filetype = my_prog} $Target
+
+:program $Target : $Source $Objects
+
+:action build my_prog object
+        version_obj = `src2obj("version.c")`
+        :do compile {target = $version_obj} version.c
+        #:do build {target = $target {filetype = program}} $source $version_obj
+        link_sed = $BDIR/link.sed
+        @if os.path.exists(link_sed):
+            :move {force} $link_sed auto/link.sed
+        @else:
+            :del {force} auto/link.sed
+        :update link2.sh
+        :sys LINK="$?(PURIFY) $?(SHRPENV) $CC $LDFLAGS \
+                -o $target $source $version_obj $LIBS" \
+                MAKE="aap" sh ./link2.sh
+        :copy {force} auto/link.sed $BDIR/link.sed
+
+# "link.sh" must be modified for A-A-P
+link2.sh : link.sh
+    :print Adjusting $-source for A-A-P.
+    :cat $source | :eval re.sub("objects/pathdef.o", "pathdef", stdin)
+                                                                      >! $target
+
+xxd/xxd$EXESUF: xxd/xxd.c
+    :sys cd xxd; CC="$CC" CFLAGS="$CPPFLAGS $CFLAGS" \
+            $MAKE -f Makefile
+
+# Build the language specific files if they were unpacked.
+# Generate the converted .mo files separately, it's no problem if this fails.
+languages {virtual}:
+        @if _no.MAKEMO:
+            :sys cd $PODIR; CC="$CC" $MAKE prefix=$DESTDIR$prefix
+            @try:
+                :sys cd $PODIR; CC="$CC" $MAKE prefix=$DESTDIR$prefix converted
+            @except:
+                :print Generated converted language files failed, continuing
+
+# Update the *.po files for changes in the sources.  Only run manually.
+update-po {virtual}:
+        cd $PODIR; CC="$CC" $MAKE prefix=$DESTDIR$prefix update-po
+
+auto/if_perl.c: if_perl.xs
+        :sys $PERL -e 'unless ( $$] >= 5.005 ) { for (qw(na defgv errgv)) { print "#define PL_$$_ $$_\n" }}' > $target
+        :sys $PERL $PERLLIB/ExtUtils/xsubpp -prototypes -typemap \
+            $PERLLIB/ExtUtils/typemap if_perl.xs >> $target
+
+auto/osdef.h: auto/config.h osdef.sh osdef1.h.in osdef2.h.in
+        :sys CC="$CC $CFLAGS" srcdir=$srcdir sh $srcdir/osdef.sh
+
+pathdef {virtual} : $BDIR/auto/pathdef$OBJSUF
+
+auto/pathdef.c: auto/config.aap
+        :print Creating $target
+        :print >! $target /* pathdef.c */
+        :print >> $target /* This file is automatically created by main.aap */
+        :print >> $target /* DO NOT EDIT!  Change main.aap only. */
+        :print >> $target $#include "vim.h"
+        :print >> $target char_u *default_vim_dir = (char_u *)"$VIMRCLOC";
+        :print >> $target char_u *default_vimruntime_dir = (char_u *)"$?VIMRUNTIMEDIR";
+        v = $CC -c -I$srcdir $CFLAGS
+        @v = string.replace(v, '"', '\\"')
+        :print >> $target char_u *all_cflags = (char_u *)"$v";
+        linkcmd = $CC $LDFLAGS -o $VIMTARGET $LIBS
+        link_sed = $BDIR/link.sed
+        @if os.path.exists(link_sed):
+            # filter $linkcmd through $BDIR/link.sed
+            :print $linkcmd | :syseval sed -f $link_sed | :eval re.sub("\n", "", stdin) | :assign linkcmd
+        @linkcmd = string.replace(linkcmd, '"', '\\"')
+        :print >> $target char_u *all_lflags = (char_u *)"$linkcmd";
+        @if _no.get("COMPILEDBY"):
+            who = $COMPILEDBY
+            where = ''
+        @else:
+            :syseval whoami | :eval re.sub("\n", "", stdin) | :assign who
+
+            :syseval hostname | :eval re.sub("\n", "", stdin) | :assign where
+        :print >> $target char_u *compiled_user = (char_u *)"$who";
+        :print >> $target char_u *compiled_sys = (char_u *)"$where";
+
+
+### Names of the tools that are also made
+TOOLS = xxd/xxd$EXESUF
+
+# Root of the installation tree.  Empty for a normal install, set to an
+# existing path to install into a special place (for generating a package).
+DESTDIR ?=
+
+### Location of man pages under $MANTOPDIR
+MAN1DIR = /man1
+
+### Location of Vim files (should not need to be changed, and
+### some things might not work when they are changed!)
+VIMDIR = /vim
+@r = re.compile('.*VIM_VERSION_NODOT\\s*"(vim\\d\\d[^"]*)".*', re.S)
+VIMRTDIR = /`r.match(open("version.h").read()).group(1)`
+HELPSUBDIR = /doc
+COLSUBDIR = /colors
+SYNSUBDIR = /syntax
+INDSUBDIR = /indent
+AUTOSUBDIR = /autoload
+PLUGSUBDIR = /plugin
+FTPLUGSUBDIR = /ftplugin
+LANGSUBDIR = /lang
+COMPSUBDIR = /compiler
+KMAPSUBDIR = /keymap
+MACROSUBDIR = /macros
+TOOLSSUBDIR = /tools
+TUTORSUBDIR = /tutor
+SPELLSUBDIR = /spell
+PRINTSUBDIR = /print
+PODIR = po
+
+### VIMLOC      common root of the Vim files (all versions)
+### VIMRTLOC    common root of the runtime Vim files (this version)
+### VIMRCLOC    compiled-in location for global [g]vimrc files (all versions)
+### VIMRUNTIMEDIR  compiled-in location for runtime files (optional)
+### HELPSUBLOC  location for help files
+### COLSUBLOC   location for colorscheme files
+### SYNSUBLOC   location for syntax files
+### INDSUBLOC   location for indent files
+### AUTOSUBLOC  location for standard autoload files
+### PLUGSUBLOC  location for standard plugin files
+### FTPLUGSUBLOC  location for ftplugin files
+### LANGSUBLOC  location for language files
+### COMPSUBLOC  location for compiler files
+### KMAPSUBLOC  location for keymap files
+### MACROSUBLOC location for macro files
+### TOOLSSUBLOC location for tools files
+### TUTORSUBLOC location for tutor files
+### PRINTSUBLOC location for print files
+### SCRIPTLOC   location for script files (menu.vim, bugreport.vim, ..)
+### You can override these if you want to install them somewhere else.
+### Edit feature.h for compile-time settings.
+VIMLOC          = $DATADIR$VIMDIR
+@if not _no.get("VIMRTLOC"):
+    VIMRTLOC        = $DATADIR$VIMDIR$VIMRTDIR
+VIMRCLOC        = $VIMLOC
+HELPSUBLOC      = $VIMRTLOC$HELPSUBDIR
+COLSUBLOC       = $VIMRTLOC$COLSUBDIR
+SYNSUBLOC       = $VIMRTLOC$SYNSUBDIR
+INDSUBLOC       = $VIMRTLOC$INDSUBDIR
+AUTOSUBLOC      = $VIMRTLOC$AUTOSUBDIR
+PLUGSUBLOC      = $VIMRTLOC$PLUGSUBDIR
+FTPLUGSUBLOC    = $VIMRTLOC$FTPLUGSUBDIR
+LANGSUBLOC      = $VIMRTLOC$LANGSUBDIR
+COMPSUBLOC      = $VIMRTLOC$COMPSUBDIR
+KMAPSUBLOC      = $VIMRTLOC$KMAPSUBDIR
+MACROSUBLOC     = $VIMRTLOC$MACROSUBDIR
+TOOLSSUBLOC     = $VIMRTLOC$TOOLSSUBDIR
+TUTORSUBLOC     = $VIMRTLOC$TUTORSUBDIR
+SPELLSUBLOC	= $VIMRTLOC$SPELLSUBDIR
+PRINTSUBLOC     = $VIMRTLOC$PRINTSUBDIR
+SCRIPTLOC       = $VIMRTLOC
+
+### Only set VIMRUNTIMEDIR when VIMRTLOC is set to a different location and
+### the runtime directory is not below it.
+#VIMRUNTIMEDIR = $VIMRTLOC
+
+### Name of the evim file target.
+EVIM_FILE       = $DESTDIR$SCRIPTLOC/evim.vim
+MSWIN_FILE      = $DESTDIR$SCRIPTLOC/mswin.vim
+
+### Name of the menu file target.
+SYS_MENU_FILE   = $DESTDIR$SCRIPTLOC/menu.vim
+SYS_SYNMENU_FILE = $DESTDIR$SCRIPTLOC/synmenu.vim
+SYS_DELMENU_FILE = $DESTDIR$SCRIPTLOC/delmenu.vim
+
+### Name of the bugreport file target.
+SYS_BUGR_FILE   = $DESTDIR$SCRIPTLOC/bugreport.vim
+
+### Name of the file type detection file target.
+SYS_FILETYPE_FILE = $DESTDIR$SCRIPTLOC/filetype.vim
+
+### Name of the file type detection file target.
+SYS_FTOFF_FILE  = $DESTDIR$SCRIPTLOC/ftoff.vim
+
+### Name of the file type detection script file target.
+SYS_SCRIPTS_FILE = $DESTDIR$SCRIPTLOC/scripts.vim
+
+### Name of the ftplugin-on file target.
+SYS_FTPLUGIN_FILE = $DESTDIR$SCRIPTLOC/ftplugin.vim
+
+### Name of the ftplugin-off file target.
+SYS_FTPLUGOF_FILE = $DESTDIR$SCRIPTLOC/ftplugof.vim
+
+### Name of the indent-on file target.
+SYS_INDENT_FILE = $DESTDIR$SCRIPTLOC/indent.vim
+
+### Name of the indent-off file target.
+SYS_INDOFF_FILE = $DESTDIR$SCRIPTLOC/indoff.vim
+
+### Name of the option window script file target.
+SYS_OPTWIN_FILE = $DESTDIR$SCRIPTLOC/optwin.vim
+
+### Permissions for binaries
+BINMOD = 755
+
+### Permissions for man page
+MANMOD = 644
+
+### Permissions for help files
+HELPMOD = 644
+
+### Permissions for Perl and shell scripts
+SCRIPTMOD = 755
+
+### Permission for Vim script files (menu.vim, bugreport.vim, ..)
+VIMSCRIPTMOD = 644
+
+### Permissions for all directories that are created
+DIRMOD = 755
+
+### Permissions for all other files that are created
+FILEMOD = 644
+
+# Where to copy the man and help files from
+HELPSOURCE = ../runtime/doc
+
+# Where to copy the script files from (menu, bugreport)
+SCRIPTSOURCE = ../runtime
+
+# Where to copy the colorscheme files from
+COLSOURCE = ../runtime/colors
+
+# Where to copy the syntax files from
+SYNSOURCE = ../runtime/syntax
+
+# Where to copy the indent files from
+INDSOURCE = ../runtime/indent
+
+# Where to copy the standard plugin files from
+AUTOSOURCE = ../runtime/autoload
+
+# Where to copy the standard plugin files from
+PLUGSOURCE = ../runtime/plugin
+
+# Where to copy the ftplugin files from
+FTPLUGSOURCE = ../runtime/ftplugin
+
+# Where to copy the macro files from
+MACROSOURCE = ../runtime/macros
+
+# Where to copy the tools files from
+TOOLSSOURCE = ../runtime/tools
+
+# Where to copy the tutor files from
+TUTORSOURCE = ../runtime/tutor
+
+# Where to copy the spell files from
+SPELLSOURCE = ../runtime/spell
+
+# Where to look for language specific files
+LANGSOURCE = ../runtime/lang
+
+# Where to look for compiler files
+COMPSOURCE = ../runtime/compiler
+
+# Where to look for keymap files
+KMAPSOURCE = ../runtime/keymap
+
+# Where to look for print resource files
+PRINTSOURCE = ../runtime/print
+
+# abbreviations
+DEST_BIN = $DESTDIR$BINDIR
+DEST_VIM = $DESTDIR$VIMLOC
+DEST_RT = $DESTDIR$VIMRTLOC
+DEST_HELP = $DESTDIR$HELPSUBLOC
+DEST_COL = $DESTDIR$COLSUBLOC
+DEST_SYN = $DESTDIR$SYNSUBLOC
+DEST_IND = $DESTDIR$INDSUBLOC
+DEST_AUTO = $DESTDIR$AUTOSUBLOC
+DEST_PLUG = $DESTDIR$PLUGSUBLOC
+DEST_FTP = $DESTDIR$FTPLUGSUBLOC
+DEST_LANG = $DESTDIR$LANGSUBLOC
+DEST_COMP = $DESTDIR$COMPSUBLOC
+DEST_KMAP = $DESTDIR$KMAPSUBLOC
+DEST_MACRO = $DESTDIR$MACROSUBLOC
+DEST_TOOLS = $DESTDIR$TOOLSSUBLOC
+DEST_TUTOR = $DESTDIR$TUTORSUBLOC
+DEST_SPELL = $DESTDIR$SPELLSUBLOC
+DEST_SCRIPT = $DESTDIR$SCRIPTLOC
+DEST_PRINT = $DESTDIR$PRINTSUBLOC
+DEST_MAN_TOP = $DESTDIR$?(MANDIR)
+
+# We assume that the ".../man/xx/man1/" directory is for latin1 manual pages.
+# Some systems use UTF-8, but these should find the ".../man/xx.UTF-8/man1/"
+# directory first.
+# FreeBSD uses ".../man/xx.ISO8859-1/man1" for latin1, use that one too.
+DEST_MAN = $(DEST_MAN_TOP)$(MAN1DIR)
+DEST_MAN_FR = $(DEST_MAN_TOP)/fr$(MAN1DIR)
+DEST_MAN_FR_I = $(DEST_MAN_TOP)/fr.ISO8859-1$(MAN1DIR)
+DEST_MAN_FR_U = $(DEST_MAN_TOP)/fr.UTF-8$(MAN1DIR)
+DEST_MAN_IT = $(DEST_MAN_TOP)/it$(MAN1DIR)
+DEST_MAN_IT_I = $(DEST_MAN_TOP)/it.ISO8859-1$(MAN1DIR)
+DEST_MAN_IT_U = $(DEST_MAN_TOP)/it.UTF-8$(MAN1DIR)
+DEST_MAN_PL = $(DEST_MAN_TOP)/pl.ISO8859-2$(MAN1DIR)
+DEST_MAN_PL_U = $(DEST_MAN_TOP)/pl.UTF-8$(MAN1DIR)
+DEST_MAN_RU = $(DEST_MAN_TOP)/ru.KOI8-R$(MAN1DIR)
+DEST_MAN_RU_U = $(DEST_MAN_TOP)/ru.UTF-8$(MAN1DIR)
+
+# These are directories, create them when needed.
+:attr {directory = $DIRMOD} $DEST_BIN $DEST_VIM $DEST_RT $DEST_HELP $DEST_COL
+                $DEST_SYN $DEST_IND $DEST_AUTO $DEST_AUTO/xml $DEST_PLUG
+                $DEST_FTP $DEST_LANG
+                $DEST_COMP $DEST_KMAP $DEST_MACRO $DEST_TOOLS $DEST_TUTOR
+                $DEST_SCRIPT $DEST_PRINT $DEST_MAN $DEST_SPELL
+                $DEST_MAN_FR $DEST_MAN_FR_I $DEST_MAN_FR_U $DEST_MAN_IT
+                $DEST_MAN_IT_I $DEST_MAN_IT_U
+                $DEST_MAN_PL $DEST_MAN_PL_U
+                $DEST_MAN_RU $DEST_MAN_RU_U
+
+#
+# I N S T A L L
+#
+install: $GUI_INSTALL
+
+install_normal:
+    @if not os.path.isdir(_no.DEST_BIN):
+        @try:
+            :mkdir $DEST_BIN
+        @except:
+        @   pass
+    @if os.access(_no.DEST_BIN, os.W_OK):
+        # Bin directory is writable, install directly.
+        :update installvim installtools $INSTALL_LANGS install-icons
+    @else:
+        # Bin directory is not writable, need to become root.
+        :print The destination directory "$DEST_BIN" is not writable.
+        :print If this is the wrong directory, use PREFIX to specify another one.
+        :print Otherwise, type the root password to continue installing.
+        :asroot $AAP install
+
+installvim {virtual}: installvimbin  installtutorbin \
+                        installruntime installlinks installmanlinks
+
+installvimbin {virtual}{force}: $Target $DEST_BIN
+        exe = $DEST_BIN/$VIMTARGET
+        @if os.path.exists(exe):
+            # Move the old executable aside and delete it.  Any other method
+            # may cause a crash if the executable is currently being used.
+            :move {force} $exe $(exe).rm
+            :del {force} $(exe).rm
+        :copy $VIMTARGET $DEST_BIN
+        :do strip $exe
+        :chmod $BINMOD $DEST_BIN/$VIMTARGET
+# may create a link to the new executable from /usr/bin/vi
+        @if _no.get("LINKIT"):
+            :sys $LINKIT
+
+# Long list of arguments for the shell script that installs the manual pages
+# for one language.
+INSTALLMANARGS = $(VIMLOC) $(SCRIPTLOC) $(VIMRCLOC) $(HELPSOURCE) $(MANMOD) \
+		$(VIMNAME) $(VIMDIFFNAME) $(EVIMNAME)
+
+# Install most of the runtime files
+installruntime {virtual}: installrtbase installmacros installtutor installspell
+
+# install the help files; first adjust the contents for the location
+installrtbase {virtual}{force}: $HELPSOURCE/vim.1 $DEST_VIM
+                $DEST_RT $DEST_HELP $DEST_COL $DEST_SYN $DEST_IND
+                $DEST_FTP $DEST_AUTO $DEST_AUTO/xml $DEST_PLUG $DEST_TUTOR
+                $DEST_COMP $DEST_SPELL $DEST_PRINT
+        :chmod 755 installman.sh
+        :sys ./installman.sh install $(DEST_MAN) "" $(INSTALLMANARGS)
+
+        :cd $HELPSOURCE
+        @try:
+            XTRA = `glob.glob("*.??x")` `glob.glob("tags-??")`
+        @except:
+            XTRA =       # It's OK if there are no matches.
+        :copy *.txt tags $XTRA $DEST_HELP
+        :cd -
+        :cd $DEST_HELP
+        :chmod $HELPMOD *.txt tags $XTRA
+        :cd -
+        :copy  $HELPSOURCE/*.pl $DEST_HELP
+        :chmod $SCRIPTMOD $DEST_HELP/*.pl
+# install the menu files
+        :copy $SCRIPTSOURCE/menu.vim $SYS_MENU_FILE
+        :chmod $VIMSCRIPTMOD $SYS_MENU_FILE
+        :copy $SCRIPTSOURCE/synmenu.vim $SYS_SYNMENU_FILE
+        :chmod $VIMSCRIPTMOD $SYS_SYNMENU_FILE
+        :copy $SCRIPTSOURCE/delmenu.vim $SYS_DELMENU_FILE
+        :chmod $VIMSCRIPTMOD $SYS_DELMENU_FILE
+# install the evim file
+        :copy $SCRIPTSOURCE/mswin.vim $MSWIN_FILE
+        :chmod $VIMSCRIPTMOD $MSWIN_FILE
+        :copy $SCRIPTSOURCE/evim.vim $EVIM_FILE
+        :chmod $VIMSCRIPTMOD $EVIM_FILE
+# install the bugreport file
+        :copy $SCRIPTSOURCE/bugreport.vim $SYS_BUGR_FILE
+        :chmod $VIMSCRIPTMOD $SYS_BUGR_FILE
+# install the example vimrc files
+        :copy $SCRIPTSOURCE/vimrc_example.vim $DEST_SCRIPT
+        :chmod $VIMSCRIPTMOD $DEST_SCRIPT/vimrc_example.vim
+        :copy $SCRIPTSOURCE/gvimrc_example.vim $DEST_SCRIPT
+        :chmod $VIMSCRIPTMOD $DEST_SCRIPT/gvimrc_example.vim
+# install the file type detection files
+        :copy $SCRIPTSOURCE/filetype.vim $SYS_FILETYPE_FILE
+        :chmod $VIMSCRIPTMOD $SYS_FILETYPE_FILE
+        :copy $SCRIPTSOURCE/ftoff.vim $SYS_FTOFF_FILE
+        :chmod $VIMSCRIPTMOD $SYS_FTOFF_FILE
+        :copy $SCRIPTSOURCE/scripts.vim $SYS_SCRIPTS_FILE
+        :chmod $VIMSCRIPTMOD $SYS_SCRIPTS_FILE
+        :copy $SCRIPTSOURCE/ftplugin.vim $SYS_FTPLUGIN_FILE
+        :chmod $VIMSCRIPTMOD $SYS_FTPLUGIN_FILE
+        :copy $SCRIPTSOURCE/ftplugof.vim $SYS_FTPLUGOF_FILE
+        :chmod $VIMSCRIPTMOD $SYS_FTPLUGOF_FILE
+        :copy $SCRIPTSOURCE/indent.vim $SYS_INDENT_FILE
+        :chmod $VIMSCRIPTMOD $SYS_INDENT_FILE
+        :copy $SCRIPTSOURCE/indoff.vim $SYS_INDOFF_FILE
+        :chmod $VIMSCRIPTMOD $SYS_INDOFF_FILE
+        :copy $SCRIPTSOURCE/optwin.vim $SYS_OPTWIN_FILE
+        :chmod $VIMSCRIPTMOD $SYS_OPTWIN_FILE
+# install the print resource files
+        :copy $PRINTSOURCE/*.ps $DEST_PRINT
+        :chmod $FILEMOD $DEST_PRINT/*.ps
+# install the colorscheme files
+        :copy $COLSOURCE/*.vim $COLSOURCE/README.txt $DEST_COL
+        :chmod $HELPMOD $DEST_COL/*.vim $DEST_COL/README.txt
+# install the syntax files
+        :copy $SYNSOURCE/*.vim $SYNSOURCE/README.txt $DEST_SYN
+        :chmod $HELPMOD $DEST_SYN/*.vim $DEST_SYN/README.txt
+# install the indent files
+        :copy $INDSOURCE/*.vim $INDSOURCE/README.txt $DEST_IND
+        :chmod $HELPMOD $DEST_IND/*.vim
+# install the standard autoload files
+        :copy $AUTOSOURCE/*.vim $AUTOSOURCE/README.txt $DEST_AUTO
+        :chmod $HELPMOD $DEST_AUTO/*.vim $DEST_AUTO/README.txt
+        :copy $AUTOSOURCE/xml/*.vim $DEST_AUTO/xml
+        :chmod $HELPMOD $DEST_AUTO/xml/*.vim
+# install the standard plugin files
+        :copy $PLUGSOURCE/*.vim $PLUGSOURCE/README.txt $DEST_PLUG
+        :chmod $HELPMOD $DEST_PLUG/*.vim $DEST_PLUG/README.txt
+# install the ftplugin files
+        :copy $FTPLUGSOURCE/*.vim $FTPLUGSOURCE/README.txt $DEST_FTP
+        :chmod $HELPMOD $DEST_FTP/*.vim $DEST_FTP/README.txt
+# install the compiler files
+        :copy $COMPSOURCE/*.vim $COMPSOURCE/README.txt $DEST_COMP
+        :chmod $HELPMOD $DEST_COMP/*.vim $DEST_COMP/README.txt
+
+installmacros {virtual}{force}: $MACROSOURCE $DEST_VIM $DEST_RT $DEST_MACRO
+        :copy {recursive}{force} $MACROSOURCE/* $DEST_MACRO
+        # Delete any CVS and AAPDIR directories.
+        # Use the ":tree" command if possible.  It was added later, fall back
+        # to using "find" when it doesn't work.
+        @try:
+           :tree $DEST_MACRO {dirname = CVS}
+              :del {recursive} $name
+           :tree $DEST_MACRO {dirname = AAPDIR}
+              :del {recursive} $name
+           :tree $DEST_MACRO {dirname = .*}
+              :chmod $DIRMOD $name
+           :tree $DEST_MACRO {filename = .*}
+              :chmod $FILEMOD $name
+        @except:
+        @  ok, cvsdirs = redir_system('find %s -name CVS -print' % _no.DEST_MACRO)
+        @  if ok and cvsdirs:
+             :del {recursive} $cvsdirs
+           :sys chmod $DIRMOD ``find $DEST_MACRO -type d -print``
+           :sys chmod $FILEMOD ``find $DEST_MACRO -type f -print``
+        :chmod $SCRIPTMOD $DEST_MACRO/less.sh
+
+# install the tutor files
+installtutorbin {virtual}{force}: $DEST_VIM
+        :copy vimtutor $DEST_BIN/$(VIMNAME)tutor
+        :chmod $SCRIPTMOD $DEST_BIN/$(VIMNAME)tutor
+
+installtutor {virtual}{force}: $DEST_RT $DEST_TUTOR
+        :copy $TUTORSOURCE/tutor* $TUTORSOURCE/README* $DEST_TUTOR
+        :chmod $HELPMOD $DEST_TUTOR/*
+
+# Install the spell files, if they exist.  This assumes at least the English
+# spell file is there.
+installspell {virtual}: $(DEST_VIM) $(DEST_RT) $(DEST_SPELL)
+	enspl = $(SPELLSOURCE)/en.latin1.spl
+        @if os.path.exists(enspl):
+            :copy $(SPELLSOURCE)/*.spl $(SPELLSOURCE)/*.vim $(DEST_SPELL)
+            :chmod $(HELPMOD) $(DEST_SPELL)/*.spl $(DEST_SPELL)/*.vim
+            @try:
+                :copy $(SPELLSOURCE)/*.sug $(DEST_SPELL)
+                :chmod $(HELPMOD) $(DEST_SPELL)/*.sug
+            @except:
+            @   pass
+
+# install helper program xxd
+installtools {virtual}{force}: $TOOLS $DEST_BIN $DEST_MAN \
+                $TOOLSSOURCE $DEST_VIM $DEST_RT $DEST_TOOLS \
+                $INSTALL_TOOL_LANGS
+        xxd = $DEST_BIN/xxd$EXESUF
+        @if os.path.exists(xxd):
+          :move {force} $xxd $(xxd).rm
+          :del $(xxd).rm
+        :copy xxd/xxd$EXESUF $DEST_BIN
+        :do strip $DEST_BIN/xxd$EXESUF
+        :chmod $BINMOD $DEST_BIN/xxd$EXESUF
+        :chmod 755 installman.sh
+        :sys ./installman.sh xxd $(DEST_MAN) "" $(INSTALLMANARGS)
+#
+# install the runtime tools
+        @try:
+        @  if aap_has(":tree"):
+              # New method: copy everything and delete CVS and AAPDIR dirs
+              :copy {recursive} $TOOLSSOURCE/* $DEST_TOOLS
+              :tree $DEST_TOOLS {dirname = CVS}
+                 :delete {recursive} $name
+              :tree $DEST_TOOLS {dirname = AAPDIR}
+                 :delete {recursive} $name
+        @except:
+            # Old method: copy only specific files and directories.
+            :copy {recursive} $TOOLSSOURCE/README.txt $TOOLSSOURCE/[a-z]* $DEST_TOOLS
+        :chmod $FILEMOD $DEST_TOOLS/*
+# replace the path in some tools
+        :progsearch perlpath perl
+        @if perlpath:
+            :cat $TOOLSSOURCE/efm_perl.pl |
+                    :eval re.sub("/usr/bin/perl", perlpath, stdin)
+                    >! $DEST_TOOLS/efm_perl.pl
+        @else:
+            :copy $TOOLSSOURCE/efm_perl.pl $DEST_TOOLS
+
+        :progsearch awkpath nawk gawk awk
+        @if awkpath:
+            :cat $TOOLSSOURCE/mve.awk |
+                    :eval re.sub("/usr/bin/nawk", awkpath, stdin)
+                    >! $DEST_TOOLS/mve.awk
+        @else:
+            :copy $TOOLSSOURCE/mve.awk $DEST_TOOLS
+
+        :sys chmod $SCRIPTMOD ``grep -l "^#!" $DEST_TOOLS/*``
+
+# install the language specific files for tools, if they were unpacked
+install-tool-languages:
+        :chmod 755 installman.sh
+        :sys ./installman.sh xxd $(DEST_MAN_FR) "-fr" $(INSTALLMANARGS)
+	:sys ./installman.sh xxd $(DEST_MAN_FR_I) "-fr" $(INSTALLMANARGS)
+	:sys ./installman.sh xxd $(DEST_MAN_FR_U) "-fr.UTF-8" $(INSTALLMANARGS)
+	:sys ./installman.sh xxd $(DEST_MAN_IT) "-it" $(INSTALLMANARGS)
+	:sys ./installman.sh xxd $(DEST_MAN_IT_I) "-it" $(INSTALLMANARGS)
+	:sys ./installman.sh xxd $(DEST_MAN_IT_U) "-it.UTF-8" $(INSTALLMANARGS)
+	:sys ./installman.sh xxd $(DEST_MAN_PL) "-pl" $(INSTALLMANARGS)
+	:sys ./installman.sh xxd $(DEST_MAN_PL_U) "-pl.UTF-8" $(INSTALLMANARGS)
+	:sys ./installman.sh xxd $(DEST_MAN_RU) "-ru" $(INSTALLMANARGS)
+	:sys ./installman.sh xxd $(DEST_MAN_RU_U) "-ru.UTF-8" $(INSTALLMANARGS)
+
+# install the language specific files, if they were unpacked
+install-languages {virtual}{force}: languages $DEST_LANG $DEST_KMAP
+        :chmod 755 installman.sh
+        :sys ./installman.sh install $(DEST_MAN_FR) "-fr" $(INSTALLMANARGS)
+	:sys ./installman.sh install $(DEST_MAN_FR_I) "-fr" $(INSTALLMANARGS)
+	:sys ./installman.sh install $(DEST_MAN_FR_U) "-fr.UTF-8" $(INSTALLMANARGS)
+	:sys ./installman.sh install $(DEST_MAN_IT) "-it" $(INSTALLMANARGS)
+	:sys ./installman.sh install $(DEST_MAN_IT_I) "-it" $(INSTALLMANARGS)
+	:sys ./installman.sh install $(DEST_MAN_IT_U) "-it.UTF-8" $(INSTALLMANARGS)
+	:sys ./installman.sh install $(DEST_MAN_PL) "-pl" $(INSTALLMANARGS)
+	:sys ./installman.sh install $(DEST_MAN_PL_U) "-pl.UTF-8" $(INSTALLMANARGS)
+	:sys ./installman.sh install $(DEST_MAN_RU) "-ru" $(INSTALLMANARGS)
+	:sys ./installman.sh install $(DEST_MAN_RU_U) "-ru.UTF-8" $(INSTALLMANARGS)
+        :chmod 755 installml.sh
+	:sys ./installml.sh install "$(GUI_MAN_TARGETS)" \
+		$(DEST_MAN_FR) $(INSTALLMLARGS)
+        :sys ./installml.sh install "$(GUI_MAN_TARGETS)" \
+		$(DEST_MAN_FR_I) $(INSTALLMLARGS)
+        :sys ./installml.sh install "$(GUI_MAN_TARGETS)" \
+		$(DEST_MAN_FR_U) $(INSTALLMLARGS)
+        :sys ./installml.sh install "$(GUI_MAN_TARGETS)" \
+		$(DEST_MAN_IT) $(INSTALLMLARGS)
+        :sys ./installml.sh install "$(GUI_MAN_TARGETS)" \
+		$(DEST_MAN_IT_I) $(INSTALLMLARGS)
+        :sys ./installml.sh install "$(GUI_MAN_TARGETS)" \
+		$(DEST_MAN_IT_U) $(INSTALLMLARGS)
+        :sys ./installml.sh install "$(GUI_MAN_TARGETS)" \
+		$(DEST_MAN_PL) $(INSTALLMLARGS)
+        :sys ./installml.sh install "$(GUI_MAN_TARGETS)" \
+		$(DEST_MAN_PL_U) $(INSTALLMLARGS)
+        :sys ./installml.sh install "$(GUI_MAN_TARGETS)" \
+		$(DEST_MAN_RU) $(INSTALLMLARGS)
+        :sys ./installml.sh install "$(GUI_MAN_TARGETS)" \
+		$(DEST_MAN_RU_U) $(INSTALLMLARGS)
+
+        @if _no.MAKEMO:
+           :sys cd $PODIR; $MAKE prefix=$DESTDIR$prefix \
+                    LOCALEDIR=$DEST_LANG INSTALL_DATA=cp FILEMOD=$FILEMOD install
+        @if os.path.exists(_no.LANGSOURCE):
+           :print installing language files
+           :copy $LANGSOURCE/README.txt $LANGSOURCE/*.vim $DEST_LANG
+           :chmod $FILEMOD $DEST_LANG/*.vim
+        @if os.path.exists(_no.KMAPSOURCE):
+           :copy $KMAPSOURCE/README.txt $KMAPSOURCE/*.vim $DEST_KMAP
+           :chmod $FILEMOD $DEST_KMAP/*.vim
+
+# install the icons for KDE, if the directory exists and the icon doesn't.
+ICON48PATH = $DESTDIR$DATADIR/icons/hicolor/48x48/apps
+ICON32PATH = $DESTDIR$DATADIR/icons/locolor/32x32/apps
+ICON16PATH = $DESTDIR$DATADIR/icons/locolor/16x16/apps
+KDEPATH = $HOME/.kde/share/icons
+install-icons {virtual}:
+        gp = $ICON48PATH/gvim.png
+        @if os.path.isdir(_no.ICON48PATH) and not os.path.exists(gp):
+           :copy $SCRIPTSOURCE/vim48x48.png $gp
+        gp = $ICON32PATH/gvim.png
+        @if os.path.isdir(_no.ICON32PATH) and not os.path.exists(gp):
+           :copy $SCRIPTSOURCE/vim32x32.png $gp
+        gp = $ICON16PATH/gvim.png
+        @if os.path.isdir(_no.ICON16PATH) and not os.path.exists(gp):
+           :copy $SCRIPTSOURCE/vim16x16.png $gp
+
+
+$HELPSOURCE/vim.1 $MACROSOURCE $TOOLSSOURCE:
+        @if not os.path.exists(_no.TOOLSSOURCE):
+            :print Runtime files not found.
+            :error You need to unpack the runtime archive before running "make install".
+
+# create links from various names to vim.  This is only done when the links
+# (or executables with the same name) don't exist yet.
+installlinks {virtual}: $GUI_TARGETS \
+                        $DEST_BIN/$EXTARGET \
+                        $DEST_BIN/$VIEWTARGET \
+                        $DEST_BIN/$RVIMTARGET \
+                        $DEST_BIN/$RVIEWTARGET \
+                        $INSTALLVIMDIFF
+
+installglinks {virtual}: $DEST_BIN/$GVIMTARGET \
+                        $DEST_BIN/$GVIEWTARGET \
+                        $DEST_BIN/$RGVIMTARGET \
+                        $DEST_BIN/$RGVIEWTARGET \
+                        $DEST_BIN/$EVIMTARGET \
+                        $DEST_BIN/$EVIEWTARGET \
+                        $INSTALLGVIMDIFF
+
+installvimdiff {virtual}: $DEST_BIN/$VIMDIFFTARGET
+installgvimdiff {virtual}: $DEST_BIN/$GVIMDIFFTARGET
+
+# These dependencies use an empty buildcheck so that they are only done when
+# the target doesn't exist.
+$DEST_BIN/$EXTARGET: {buildcheck = }
+    :sys cd $DEST_BIN; ln -s $VIMTARGET $EXTARGET
+
+$DEST_BIN/$VIEWTARGET: {buildcheck = }
+    :sys cd $DEST_BIN; ln -s $VIMTARGET $VIEWTARGET
+
+$DEST_BIN/$GVIMTARGET: {buildcheck = }
+    :sys cd $DEST_BIN; ln -s $VIMTARGET $GVIMTARGET
+
+$DEST_BIN/$GVIEWTARGET: {buildcheck = }
+    :sys cd $DEST_BIN; ln -s $VIMTARGET $GVIEWTARGET
+
+$DEST_BIN/$RVIMTARGET: {buildcheck = }
+    :sys cd $DEST_BIN; ln -s $VIMTARGET $RVIMTARGET
+
+$DEST_BIN/$RVIEWTARGET: {buildcheck = }
+    :sys cd $DEST_BIN; ln -s $VIMTARGET $RVIEWTARGET
+
+$DEST_BIN/$RGVIMTARGET: {buildcheck = }
+    :sys cd $DEST_BIN; ln -s $VIMTARGET $RGVIMTARGET
+
+$DEST_BIN/$RGVIEWTARGET: {buildcheck = }
+    :sys cd $DEST_BIN; ln -s $VIMTARGET $RGVIEWTARGET
+
+$DEST_BIN/$VIMDIFFTARGET: {buildcheck = }
+    :sys cd $DEST_BIN; ln -s $VIMTARGET $VIMDIFFTARGET
+
+$DEST_BIN/$GVIMDIFFTARGET: {buildcheck = }
+    :sys cd $DEST_BIN; ln -s $VIMTARGET $GVIMDIFFTARGET
+
+$DEST_BIN/$EVIMTARGET: {buildcheck = }
+    :sys cd $DEST_BIN; ln -s $VIMTARGET $EVIMTARGET
+
+$DEST_BIN/$EVIEWTARGET: {buildcheck = }
+    :sys cd $DEST_BIN; ln -s $VIMTARGET $EVIEWTARGET
+
+# create links for the manual pages with various names to vim.  This is only
+# done when the links (or manpages with the same name) don't exist yet.
+INSTALLMLARGS = $(VIMNAME) $(VIMDIFFNAME) $(EVIMNAME) \
+		$(EXNAME) $(VIEWNAME) $(RVIMNAME) $(RVIEWNAME) \
+		$(GVIMNAME) $(GVIEWNAME) $(RGVIMNAME) $(RGVIEWNAME) \
+		$(GVIMDIFFNAME) $(EVIEWNAME)
+
+installmanlinks {virtual}:
+    :chmod 755 installml.sh
+    :sys ./installml.sh install "$(GUI_MAN_TARGETS)" \
+		$(DEST_MAN) $(INSTALLMLARGS)
+
+#
+# U N I N S T A L L
+#
+uninstall {virtual}{force}: uninstall_runtime
+    :del {force} $DEST_BIN/$VIMTARGET
+    :del {force} $DEST_BIN/vimtutor
+    :del {force} $DEST_BIN/$EXTARGET $DEST_BIN/$VIEWTARGET
+    :del {force} $DEST_BIN/$GVIMTARGET $DEST_BIN/$GVIEWTARGET
+    :del {force} $DEST_BIN/$RVIMTARGET $DEST_BIN/$RVIEWTARGET
+    :del {force} $DEST_BIN/$RGVIMTARGET $DEST_BIN/$RGVIEWTARGET
+    :del {force} $DEST_BIN/$VIMDIFFTARGET $DEST_BIN/$GVIMDIFFTARGET
+    :del {force} $DEST_BIN/$EVIMTARGET $DEST_BIN/$EVIEWTARGET
+    :del {force} $DEST_BIN/xxd$EXESUF
+
+# Note: "deldir" will fail if any files were added after "make install", that
+# is intentionally: Keep files the user added.
+uninstall_runtime {virtual}{force}:
+    :chmod 755 installman.sh
+    :sys ./installman.sh uninstall $(DEST_MAN) "" $(INSTALLMANARGS)
+    :sys ./installman.sh uninstall $(DEST_MAN_FR) "" $(INSTALLMANARGS)
+    :sys ./installman.sh uninstall $(DEST_MAN_FR_I) "" $(INSTALLMANARGS)
+    :sys ./installman.sh uninstall $(DEST_MAN_FR_U) "" $(INSTALLMANARGS)
+    :sys ./installman.sh uninstall $(DEST_MAN_IT) "" $(INSTALLMANARGS)
+    :sys ./installman.sh uninstall $(DEST_MAN_IT_I) "" $(INSTALLMANARGS)
+    :sys ./installman.sh uninstall $(DEST_MAN_IT_U) "" $(INSTALLMANARGS)
+    :sys ./installman.sh uninstall $(DEST_MAN_PL) "" $(INSTALLMANARGS)
+    :sys ./installman.sh uninstall $(DEST_MAN_PL_U) "" $(INSTALLMANARGS)
+    :sys ./installman.sh uninstall $(DEST_MAN_RU) "" $(INSTALLMANARGS)
+    :sys ./installman.sh uninstall $(DEST_MAN_RU_U) "" $(INSTALLMANARGS)
+    :chmod 755 installml.sh
+    :sys ./installml.sh uninstall "$(GUI_MAN_TARGETS)" \
+            $(DEST_MAN) $(INSTALLMLARGS)
+    :sys ./installml.sh uninstall "$(GUI_MAN_TARGETS)" \
+            $(DEST_MAN_FR) $(INSTALLMLARGS)
+    :sys ./installml.sh uninstall "$(GUI_MAN_TARGETS)" \
+            $(DEST_MAN_FR_I) $(INSTALLMLARGS)
+    :sys ./installml.sh uninstall "$(GUI_MAN_TARGETS)" \
+            $(DEST_MAN_FR_U) $(INSTALLMLARGS)
+    :sys ./installml.sh uninstall "$(GUI_MAN_TARGETS)" \
+            $(DEST_MAN_IT) $(INSTALLMLARGS)
+    :sys ./installml.sh uninstall "$(GUI_MAN_TARGETS)" \
+            $(DEST_MAN_IT_I) $(INSTALLMLARGS)
+    :sys ./installml.sh uninstall "$(GUI_MAN_TARGETS)" \
+            $(DEST_MAN_IT_U) $(INSTALLMLARGS)
+    :sys ./installml.sh uninstall "$(GUI_MAN_TARGETS)" \
+            $(DEST_MAN_PL) $(INSTALLMLARGS)
+    :sys ./installml.sh uninstall "$(GUI_MAN_TARGETS)" \
+            $(DEST_MAN_PL_U) $(INSTALLMLARGS)
+    :sys ./installml.sh uninstall "$(GUI_MAN_TARGETS)" \
+            $(DEST_MAN_RU) $(INSTALLMLARGS)
+    :sys ./installml.sh uninstall "$(GUI_MAN_TARGETS)" \
+            $(DEST_MAN_RU_U) $(INSTALLMLARGS)
+    :del {force} $DEST_MAN/xxd.1
+    :del {force} $(DEST_MAN_FR)/xxd.1 $(DEST_MAN_FR_I)/xxd.1 $(DEST_MAN_FR_U)/xxd.1
+    :del {force} $(DEST_MAN_IT)/xxd.1 $(DEST_MAN_IT_I)/xxd.1 $(DEST_MAN_IT_U)/xxd.1
+    :del {force} $(DEST_MAN_PL)/xxd.1 $(DEST_MAN_PL_U)/xxd.1
+    :del {force} $(DEST_MAN_RU)/xxd.1 $(DEST_MAN_RU_U)/xxd.1
+
+    :del {force} $DEST_HELP/*.txt $DEST_HELP/tags $DEST_HELP/*.pl
+    :del {force} $SYS_MENU_FILE $SYS_SYNMENU_FILE $SYS_DELMENU_FILE
+    :del {force} $SYS_BUGR_FILE $EVIM_FILE $MSWIN_FILE
+    :del {force} $DEST_SCRIPT/gvimrc_example.vim $DEST_SCRIPT/vimrc_example.vim
+    :del {force} $SYS_FILETYPE_FILE $SYS_FTOFF_FILE $SYS_SCRIPTS_FILE
+    :del {force} $SYS_INDOFF_FILE $SYS_INDENT_FILE
+    :del {force} $SYS_FTPLUGOF_FILE $SYS_FTPLUGIN_FILE
+    :del {force} $SYS_OPTWIN_FILE
+    :del {force} $DEST_COL/*.vim $DEST_COL/README.txt
+    :del {force} $DEST_SYN/*.vim $DEST_SYN/README.txt
+    :del {force} $DEST_IND/*.vim $DEST_IND/README.txt
+    :del {force} $DEST_PRINT/*.ps
+    :del {force}{recursive} $DEST_MACRO
+    :del {force}{recursive} $DEST_TUTOR
+    :del {force}{recursive} $DEST_SPELL
+    :del {force}{recursive} $DEST_TOOLS
+    :del {force}{recursive} $DEST_LANG
+    :del {force}{recursive} $DEST_KMAP
+    :del {force}{recursive} $DEST_COMP
+    :deldir {force} $DEST_HELP $DEST_COL $DEST_SYN $DEST_IND
+    :del {force}{recursive} $DEST_FTP/*.vim $DEST_FTP/README.txt
+    :del {force} $DEST_AUTO/*.vim $DEST_AUTO/README.txt $DEST_AUTO/xml/*.vim
+    :del {force} $DEST_PLUG/*.vim $DEST_PLUG/README.txt
+    :deldir {force} $DEST_FTP $DEST_AUTO/xml $DEST_AUTO $DEST_PLUG $DEST_PRINT $DEST_RT
+#       This will fail when other Vim versions are installed, no worries.
+    @try:
+        :deldir $DEST_VIM
+    @except:
+        :print Cannot delete $DEST_VIM
+
+###############################################################################
+### MacOS X installation
+###
+### This installs a runnable Vim.app in $(prefix)
+
+REZ    = /Developer/Tools/Rez
+RESDIR = $(APPDIR)/Contents/Resources
+@r = re.compile('.*VIM_VERSION_SHORT\\s*"(\\d[^"]*)".*', re.S)
+VERSION = /`r.match(open("version.h").read()).group(1)`
+
+### Common flags
+M4FLAGSX = $?(M4FLAGS) -DAPP_EXE=$(VIMNAME) -DAPP_NAME=$(VIMNAME) \
+		-DAPP_VER=$(VERSION)
+
+# Resources used for the Mac are in one directory.
+RSRC_DIR = os_mac_rsrc
+
+:attr {directory = $DIRMOD} $RESDIR
+
+install_macosx {virtual}: gui_bundle
+# Remove the link to the runtime dir, don't want to copy all of that.
+        :delete {force} $(RESDIR)/vim/runtime
+        :copy {r} $APPDIR $DESTDIR$prefix
+        :tree $DESTDIR$prefix {dirname = AAPDIR}
+             :delete {recursive} $name
+# Install the runtime files.  Recursive!
+	:mkdir {r}{f} $DESTDIR$prefix/$RESDIR/vim/runtime
+#	:mkdir $(DESTDIR)$(prefix)/$(APPDIR)/bin
+        :execute main.aap PREFIX=$DESTDIR$prefix/$RESDIR/vim VIMRTLOC=$DESTDIR$prefix/$RESDIR/vim/runtime installruntime
+# Put the link back.
+        :symlink `os.getcwd()`/../runtime $RESDIR/vim/runtime
+# TODO: Create the vimtutor application.
+
+gui_bundle {virtual}: $(RESDIR) bundle-dir bundle-executable bundle-info
+                        bundle-resource bundle-language
+
+bundle-dir {virtual}: $(APPDIR)/Contents $(VIMTARGET)
+# Make a link to the runtime directory, so that we can try out the executable
+# without installing it.
+        :mkdir {r}{f} $(RESDIR)/vim
+        :symlink {quiet} `os.getcwd()`/../runtime $(RESDIR)/vim/runtime
+
+bundle-executable {virtual}: $(VIMTARGET)
+        :mkdir {r}{f} $(APPDIR)/Contents/MacOS
+        :copy $(VIMTARGET) $(APPDIR)/Contents/MacOS/$(VIMTARGET)
+
+bundle-info {virtual}:  bundle-dir
+        :print Creating PkgInfo
+        :print "APPLVIM!" >! $(APPDIR)/Contents/PkgInfo
+        :print Creating Info.plist
+        :sys m4 $(M4FLAGSX) infplist.xml > $(APPDIR)/Contents/Info.plist
+
+bundle-resource {virtual}: bundle-dir bundle-rsrc
+    :copy {force} $(RSRC_DIR)/*.icns $(RESDIR)
+
+### Classic resources
+# Resource fork (in the form of a .rsrc file) for Classic Vim (Mac OS 9)
+# This file is also required for OS X Vim.
+bundle-rsrc {virtual}: os_mac.rsr.hqx
+    :print Creating resource fork
+    :sys python dehqx.py $source
+    :del {force} gui_mac.rsrc
+    :move gui_mac.rsrc.rsrcfork $(RESDIR)/$(VIMNAME).rsrc
+
+# po/Make_osx.pl says something about generating a Mac message file
+# for Ukrananian.  Would somebody using Mac OS X in Ukranian
+# *really* be upset that Carbon Vim was not localised in
+# Ukranian?
+#
+#bundle-language: bundle-dir po/Make_osx.pl
+#	cd po && perl Make_osx.pl --outdir ../$(RESDIR) $(MULTILANG)
+bundle-language {virtual}: bundle-dir
+
+$(APPDIR)/Contents:
+    :mkdir {r} $(APPDIR)/Contents/MacOS
+    :mkdir {r} $(RESDIR)/English.lproj
+
+
+# vim: sts=4 sw=4 :
--- /dev/null
+++ b/main.c
@@ -1,0 +1,3841 @@
+/* vi:set ts=8 sts=4 sw=4:
+ *
+ * VIM - Vi IMproved	by Bram Moolenaar
+ *
+ * Do ":help uganda"  in Vim to read copying and usage conditions.
+ * Do ":help credits" in Vim to see a list of people who contributed.
+ * See README.txt for an overview of the Vim source code.
+ */
+
+#if defined(MSDOS) || defined(WIN32) || defined(_WIN64)
+# include "vimio.h"		/* for close() and dup() */
+#endif
+
+#define EXTERN
+#include "vim.h"
+
+#ifdef SPAWNO
+# include <spawno.h>		/* special MS-DOS swapping library */
+#endif
+
+#ifdef HAVE_FCNTL_H
+# include <fcntl.h>
+#endif
+
+#ifdef __CYGWIN__
+# ifndef WIN32
+#  include <sys/cygwin.h>	/* for cygwin_conv_to_posix_path() */
+# endif
+# include <limits.h>
+#endif
+
+/* Maximum number of commands from + or -c arguments. */
+#define MAX_ARG_CMDS 10
+
+/* values for "window_layout" */
+#define WIN_HOR	    1	    /* "-o" horizontally split windows */
+#define	WIN_VER	    2	    /* "-O" vertically split windows */
+#define	WIN_TABS    3	    /* "-p" windows on tab pages */
+
+/* Struct for various parameters passed between main() and other functions. */
+typedef struct
+{
+    int		argc;
+    char	**argv;
+
+    int		evim_mode;		/* started as "evim" */
+    char_u	*use_vimrc;		/* vimrc from -u argument */
+
+    int		n_commands;		     /* no. of commands from + or -c */
+    char_u	*commands[MAX_ARG_CMDS];     /* commands from + or -c arg. */
+    char_u	cmds_tofree[MAX_ARG_CMDS];   /* commands that need free() */
+    int		n_pre_commands;		     /* no. of commands from --cmd */
+    char_u	*pre_commands[MAX_ARG_CMDS]; /* commands from --cmd argument */
+
+    int		edit_type;		/* type of editing to do */
+    char_u	*tagname;		/* tag from -t argument */
+#ifdef FEAT_QUICKFIX
+    char_u	*use_ef;		/* 'errorfile' from -q argument */
+#endif
+
+    int		want_full_screen;
+    int		stdout_isatty;		/* is stdout a terminal? */
+    char_u	*term;			/* specified terminal name */
+#ifdef FEAT_CRYPT
+    int		ask_for_key;		/* -x argument */
+#endif
+    int		no_swap_file;		/* "-n" argument used */
+#ifdef FEAT_EVAL
+    int		use_debug_break_level;
+#endif
+#ifdef FEAT_WINDOWS
+    int		window_count;		/* number of windows to use */
+    int		window_layout;		/* 0, WIN_HOR, WIN_VER or WIN_TABS */
+#endif
+
+#ifdef FEAT_CLIENTSERVER
+    int		serverArg;		/* TRUE when argument for a server */
+    char_u	*serverName_arg;	/* cmdline arg for server name */
+    char_u	*serverStr;		/* remote server command */
+    char_u	*serverStrEnc;		/* encoding of serverStr */
+    char_u	*servername;		/* allocated name for our server */
+#endif
+#if (!defined(UNIX) && !defined(__EMX__)) || defined(ARCHIE)
+    int		literal;		/* don't expand file names */
+#endif
+#ifdef MSWIN
+    int		full_path;		/* file name argument was full path */
+#endif
+#ifdef FEAT_DIFF
+    int		diff_mode;		/* start with 'diff' set */
+#endif
+} mparm_T;
+
+/* Values for edit_type. */
+#define EDIT_NONE   0	    /* no edit type yet */
+#define EDIT_FILE   1	    /* file name argument[s] given, use argument list */
+#define EDIT_STDIN  2	    /* read file from stdin */
+#define EDIT_TAG    3	    /* tag name argument given, use tagname */
+#define EDIT_QF	    4	    /* start in quickfix mode */
+
+#if defined(UNIX) || defined(VMS)
+static int file_owned __ARGS((char *fname));
+#endif
+static void mainerr __ARGS((int, char_u *));
+static void main_msg __ARGS((char *s));
+static void usage __ARGS((void));
+static int get_number_arg __ARGS((char_u *p, int *idx, int def));
+#if defined(HAVE_LOCALE_H) || defined(X_LOCALE)
+static void init_locale __ARGS((void));
+#endif
+static void parse_command_name __ARGS((mparm_T *parmp));
+static void early_arg_scan __ARGS((mparm_T *parmp));
+static void command_line_scan __ARGS((mparm_T *parmp));
+static void check_tty __ARGS((mparm_T *parmp));
+static void read_stdin __ARGS((void));
+static void create_windows __ARGS((mparm_T *parmp));
+#ifdef FEAT_WINDOWS
+static void edit_buffers __ARGS((mparm_T *parmp));
+#endif
+static void exe_pre_commands __ARGS((mparm_T *parmp));
+static void exe_commands __ARGS((mparm_T *parmp));
+static void source_startup_scripts __ARGS((mparm_T *parmp));
+static void main_start_gui __ARGS((void));
+#if defined(HAS_SWAP_EXISTS_ACTION)
+static void check_swap_exists_action __ARGS((void));
+#endif
+#ifdef FEAT_CLIENTSERVER
+static void exec_on_server __ARGS((mparm_T *parmp));
+static void prepare_server __ARGS((mparm_T *parmp));
+static void cmdsrv_main __ARGS((int *argc, char **argv, char_u *serverName_arg, char_u **serverStr));
+static char_u *serverMakeName __ARGS((char_u *arg, char *cmd));
+#endif
+
+
+#ifdef STARTUPTIME
+static FILE *time_fd = NULL;
+#endif
+
+/*
+ * Different types of error messages.
+ */
+static char *(main_errors[]) =
+{
+    N_("Unknown option argument"),
+#define ME_UNKNOWN_OPTION	0
+    N_("Too many edit arguments"),
+#define ME_TOO_MANY_ARGS	1
+    N_("Argument missing after"),
+#define ME_ARG_MISSING		2
+    N_("Garbage after option argument"),
+#define ME_GARBAGE		3
+    N_("Too many \"+command\", \"-c command\" or \"--cmd command\" arguments"),
+#define ME_EXTRA_CMD		4
+    N_("Invalid argument for"),
+#define ME_INVALID_ARG		5
+};
+
+#ifndef PROTO	    /* don't want a prototype for main() */
+    int
+# ifdef VIMDLL
+_export
+# endif
+# ifdef FEAT_GUI_MSWIN
+#  ifdef __BORLANDC__
+_cdecl
+#  endif
+VimMain
+# else
+main
+# endif
+(argc, argv)
+    int		argc;
+    char	**argv;
+{
+    char_u	*fname = NULL;		/* file name from command line */
+    mparm_T	params;			/* various parameters passed between
+					 * main() and other functions. */
+
+    /*
+     * Do any system-specific initialisations.  These can NOT use IObuff or
+     * NameBuff.  Thus emsg2() cannot be called!
+     */
+    mch_early_init();
+
+    /* Many variables are in "params" so that we can pass them to invoked
+     * functions without a lot of arguments.  "argc" and "argv" are also
+     * copied, so that they can be changed. */
+    vim_memset(&params, 0, sizeof(params));
+    params.argc = argc;
+    params.argv = argv;
+    params.want_full_screen = TRUE;
+#ifdef FEAT_EVAL
+    params.use_debug_break_level = -1;
+#endif
+#ifdef FEAT_WINDOWS
+    params.window_count = -1;
+#endif
+
+#ifdef FEAT_TCL
+    vim_tcl_init(params.argv[0]);
+#endif
+
+#ifdef MEM_PROFILE
+    atexit(vim_mem_profile_dump);
+#endif
+
+#ifdef STARTUPTIME
+    time_fd = mch_fopen(STARTUPTIME, "a");
+    TIME_MSG("--- VIM STARTING ---");
+#endif
+    starttime = time(NULL);
+
+#ifdef __EMX__
+    _wildcard(&params.argc, &params.argv);
+#endif
+
+#ifdef FEAT_MBYTE
+    (void)mb_init();	/* init mb_bytelen_tab[] to ones */
+#endif
+#ifdef FEAT_EVAL
+    eval_init();	/* init global variables */
+#endif
+
+#ifdef __QNXNTO__
+    qnx_init();		/* PhAttach() for clipboard, (and gui) */
+#endif
+
+#ifdef MAC_OS_CLASSIC
+    /* Prepare for possibly starting GUI sometime */
+    /* Macintosh needs this before any memory is allocated. */
+    gui_prepare(&params.argc, params.argv);
+    TIME_MSG("GUI prepared");
+#endif
+
+    /* Init the table of Normal mode commands. */
+    init_normal_cmds();
+
+#if defined(HAVE_DATE_TIME) && defined(VMS) && defined(VAXC)
+    make_version();	/* Construct the long version string. */
+#endif
+
+    /*
+     * Allocate space for the generic buffers (needed for set_init_1() and
+     * EMSG2()).
+     */
+    if ((IObuff = alloc(IOSIZE)) == NULL
+	    || (NameBuff = alloc(MAXPATHL)) == NULL)
+	mch_exit(0);
+    TIME_MSG("Allocated generic buffers");
+
+#ifdef NBDEBUG
+    /* Wait a moment for debugging NetBeans.  Must be after allocating
+     * NameBuff. */
+    nbdebug_log_init("SPRO_GVIM_DEBUG", "SPRO_GVIM_DLEVEL");
+    nbdebug_wait(WT_ENV | WT_WAIT | WT_STOP, "SPRO_GVIM_WAIT", 20);
+    TIME_MSG("NetBeans debug wait");
+#endif
+
+#if defined(HAVE_LOCALE_H) || defined(X_LOCALE)
+    /*
+     * Setup to use the current locale (for ctype() and many other things).
+     * NOTE: Translated messages with encodings other than latin1 will not
+     * work until set_init_1() has been called!
+     */
+    init_locale();
+    TIME_MSG("locale set");
+#endif
+
+#ifdef FEAT_GUI
+    gui.dofork = TRUE;		    /* default is to use fork() */
+#endif
+
+    /*
+     * Do a first scan of the arguments in "argv[]":
+     *   -display or --display
+     *   --server...
+     *   --socketid
+     */
+    early_arg_scan(&params);
+
+#ifdef FEAT_SUN_WORKSHOP
+    findYourself(params.argv[0]);
+#endif
+#if defined(FEAT_GUI) && !defined(MAC_OS_CLASSIC)
+    /* Prepare for possibly starting GUI sometime */
+    gui_prepare(&params.argc, params.argv);
+    TIME_MSG("GUI prepared");
+#endif
+
+#ifdef FEAT_CLIPBOARD
+    clip_init(FALSE);		/* Initialise clipboard stuff */
+    TIME_MSG("clipboard setup");
+#endif
+
+    /*
+     * Check if we have an interactive window.
+     * On the Amiga: If there is no window, we open one with a newcli command
+     * (needed for :! to * work). mch_check_win() will also handle the -d or
+     * -dev argument.
+     */
+    params.stdout_isatty = (mch_check_win(params.argc, params.argv) != FAIL);
+    TIME_MSG("window checked");
+
+    /*
+     * Allocate the first window and buffer.
+     * Can't do anything without it, exit when it fails.
+     */
+    if (win_alloc_first() == FAIL)
+	mch_exit(0);
+
+    init_yank();		/* init yank buffers */
+
+    alist_init(&global_alist);	/* Init the argument list to empty. */
+
+    /*
+     * Set the default values for the options.
+     * NOTE: Non-latin1 translated messages are working only after this,
+     * because this is where "has_mbyte" will be set, which is used by
+     * msg_outtrans_len_attr().
+     * First find out the home directory, needed to expand "~" in options.
+     */
+    init_homedir();		/* find real value of $HOME */
+    set_init_1();
+    TIME_MSG("inits 1");
+
+#ifdef FEAT_EVAL
+    set_lang_var();		/* set v:lang and v:ctype */
+#endif
+
+#ifdef FEAT_CLIENTSERVER
+    /*
+     * Do the client-server stuff, unless "--servername ''" was used.
+     * This may exit Vim if the command was sent to the server.
+     */
+    exec_on_server(&params);
+#endif
+
+    /*
+     * Figure out the way to work from the command name argv[0].
+     * "vimdiff" starts diff mode, "rvim" sets "restricted", etc.
+     */
+    parse_command_name(&params);
+
+    /*
+     * Process the command line arguments.  File names are put in the global
+     * argument list "global_alist".
+     */
+    command_line_scan(&params);
+    TIME_MSG("parsing arguments");
+
+    /*
+     * On some systems, when we compile with the GUI, we always use it.  On Mac
+     * there is no terminal version, and on Windows we can't fork one off with
+     * :gui.
+     */
+#ifdef ALWAYS_USE_GUI
+    gui.starting = TRUE;
+#else
+# if defined(FEAT_GUI_X11) || defined(FEAT_GUI_GTK)
+    /*
+     * Check if the GUI can be started.  Reset gui.starting if not.
+     * Don't know about other systems, stay on the safe side and don't check.
+     */
+    if (gui.starting && gui_init_check() == FAIL)
+    {
+	gui.starting = FALSE;
+
+	/* When running "evim" or "gvim -y" we need the menus, exit if we
+	 * don't have them. */
+	if (params.evim_mode)
+	    mch_exit(1);
+    }
+# endif
+#endif
+
+    if (GARGCOUNT > 0)
+    {
+#if (!defined(UNIX) && !defined(__EMX__)) || defined(ARCHIE)
+	/*
+	 * Expand wildcards in file names.
+	 */
+	if (!params.literal)
+	{
+	    /* Temporarily add '(' and ')' to 'isfname'.  These are valid
+	     * filename characters but are excluded from 'isfname' to make
+	     * "gf" work on a file name in parenthesis (e.g.: see vim.h). */
+	    do_cmdline_cmd((char_u *)":set isf+=(,)");
+	    alist_expand(NULL, 0);
+	    do_cmdline_cmd((char_u *)":set isf&");
+	}
+#endif
+	fname = alist_name(&GARGLIST[0]);
+    }
+
+#if defined(WIN32) && defined(FEAT_MBYTE)
+    {
+	extern void set_alist_count(void);
+
+	/* Remember the number of entries in the argument list.  If it changes
+	 * we don't react on setting 'encoding'. */
+	set_alist_count();
+    }
+#endif
+
+#ifdef MSWIN
+    if (GARGCOUNT == 1 && params.full_path)
+    {
+	/*
+	 * If there is one filename, fully qualified, we have very probably
+	 * been invoked from explorer, so change to the file's directory.
+	 * Hint: to avoid this when typing a command use a forward slash.
+	 * If the cd fails, it doesn't matter.
+	 */
+	(void)vim_chdirfile(fname);
+    }
+#endif
+    TIME_MSG("expanding arguments");
+
+#ifdef FEAT_DIFF
+    if (params.diff_mode && params.window_count == -1)
+	params.window_count = 0;	/* open up to 3 windows */
+#endif
+
+    /* Don't redraw until much later. */
+    ++RedrawingDisabled;
+
+    /*
+     * When listing swap file names, don't do cursor positioning et. al.
+     */
+    if (recoverymode && fname == NULL)
+	params.want_full_screen = FALSE;
+
+    /*
+     * When certain to start the GUI, don't check capabilities of terminal.
+     * For GTK we can't be sure, but when started from the desktop it doesn't
+     * make sense to try using a terminal.
+     */
+#if defined(ALWAYS_USE_GUI) || defined(FEAT_GUI_X11) || defined(FEAT_GUI_GTK)
+    if (gui.starting
+# ifdef FEAT_GUI_GTK
+	    && !isatty(2)
+# endif
+	    )
+	params.want_full_screen = FALSE;
+#endif
+
+#if defined(FEAT_GUI_MAC) && defined(MACOS_X_UNIX)
+    /* When the GUI is started from Finder, need to display messages in a
+     * message box.  isatty(2) returns TRUE anyway, thus we need to check the
+     * name to know we're not started from a terminal. */
+    if (gui.starting && (!isatty(2) || strcmp("/dev/console", ttyname(2)) == 0))
+    {
+	params.want_full_screen = FALSE;
+
+	/* Avoid always using "/" as the current directory.  Note that when
+	 * started from Finder the arglist will be filled later in
+	 * HandleODocAE() and "fname" will be NULL. */
+	if (getcwd((char *)NameBuff, MAXPATHL) != NULL
+						&& STRCMP(NameBuff, "/") == 0)
+	{
+	    if (fname != NULL)
+		(void)vim_chdirfile(fname);
+	    else
+	    {
+		expand_env((char_u *)"$HOME", NameBuff, MAXPATHL);
+		vim_chdir(NameBuff);
+	    }
+	}
+    }
+#endif
+
+    /*
+     * mch_init() sets up the terminal (window) for use.  This must be
+     * done after resetting full_screen, otherwise it may move the cursor
+     * (MSDOS).
+     * Note that we may use mch_exit() before mch_init()!
+     */
+    mch_init();
+    TIME_MSG("shell init");
+
+#ifdef USE_XSMP
+    /*
+     * For want of anywhere else to do it, try to connect to xsmp here.
+     * Fitting it in after gui_mch_init, but before gui_init (via termcapinit).
+     * Hijacking -X 'no X connection' to also disable XSMP connection as that
+     * has a similar delay upon failure.
+     * Only try if SESSION_MANAGER is set to something non-null.
+     */
+    if (!x_no_connect)
+    {
+	char *p = getenv("SESSION_MANAGER");
+
+	if (p != NULL && *p != NUL)
+	{
+	    xsmp_init();
+	    TIME_MSG("xsmp init");
+	}
+    }
+#endif
+
+    /*
+     * Print a warning if stdout is not a terminal.
+     */
+    check_tty(&params);
+
+    /* This message comes before term inits, but after setting "silent_mode"
+     * when the input is not a tty. */
+    if (GARGCOUNT > 1 && !silent_mode)
+	printf(_("%d files to edit\n"), GARGCOUNT);
+
+    if (params.want_full_screen && !silent_mode)
+    {
+	termcapinit(params.term);	/* set terminal name and get terminal
+				   capabilities (will set full_screen) */
+	screen_start();		/* don't know where cursor is now */
+	TIME_MSG("Termcap init");
+    }
+
+    /*
+     * Set the default values for the options that use Rows and Columns.
+     */
+    ui_get_shellsize();		/* inits Rows and Columns */
+#ifdef FEAT_NETBEANS_INTG
+    if (usingNetbeans)
+	Columns += 2;		/* leave room for glyph gutter */
+#endif
+    win_init_size();
+#ifdef FEAT_DIFF
+    /* Set the 'diff' option now, so that it can be checked for in a .vimrc
+     * file.  There is no buffer yet though. */
+    if (params.diff_mode)
+	diff_win_options(firstwin, FALSE);
+#endif
+
+    cmdline_row = Rows - p_ch;
+    msg_row = cmdline_row;
+    screenalloc(FALSE);		/* allocate screen buffers */
+    set_init_2();
+    TIME_MSG("inits 2");
+
+    msg_scroll = TRUE;
+    no_wait_return = TRUE;
+
+    init_mappings();		/* set up initial mappings */
+
+    init_highlight(TRUE, FALSE); /* set the default highlight groups */
+    TIME_MSG("init highlight");
+
+#ifdef FEAT_EVAL
+    /* Set the break level after the terminal is initialized. */
+    debug_break_level = params.use_debug_break_level;
+#endif
+
+    /* Execute --cmd arguments. */
+    exe_pre_commands(&params);
+
+    /* Source startup scripts. */
+    source_startup_scripts(&params);
+
+#ifdef FEAT_EVAL
+    /*
+     * Read all the plugin files.
+     * Only when compiled with +eval, since most plugins need it.
+     */
+    if (p_lpl)
+    {
+# ifdef VMS	/* Somehow VMS doesn't handle the "**". */
+	source_runtime((char_u *)"plugin/*.vim", TRUE);
+# else
+	source_runtime((char_u *)"plugin/**/*.vim", TRUE);
+# endif
+	TIME_MSG("loading plugins");
+    }
+#endif
+
+#ifdef FEAT_DIFF
+    /* Decide about window layout for diff mode after reading vimrc. */
+    if (params.diff_mode && params.window_layout == 0)
+    {
+	if (diffopt_horizontal())
+	    params.window_layout = WIN_HOR;	/* use horizontal split */
+	else
+	    params.window_layout = WIN_VER;	/* use vertical split */
+    }
+#endif
+
+    /*
+     * Recovery mode without a file name: List swap files.
+     * This uses the 'dir' option, therefore it must be after the
+     * initializations.
+     */
+    if (recoverymode && fname == NULL)
+    {
+	recover_names(NULL, TRUE, 0);
+	mch_exit(0);
+    }
+
+    /*
+     * Set a few option defaults after reading .vimrc files:
+     * 'title' and 'icon', Unix: 'shellpipe' and 'shellredir'.
+     */
+    set_init_3();
+    TIME_MSG("inits 3");
+
+    /*
+     * "-n" argument: Disable swap file by setting 'updatecount' to 0.
+     * Note that this overrides anything from a vimrc file.
+     */
+    if (params.no_swap_file)
+	p_uc = 0;
+
+#ifdef FEAT_FKMAP
+    if (curwin->w_p_rl && p_altkeymap)
+    {
+	p_hkmap = FALSE;	/* Reset the Hebrew keymap mode */
+# ifdef FEAT_ARABIC
+	curwin->w_p_arab = FALSE; /* Reset the Arabic keymap mode */
+# endif
+	p_fkmap = TRUE;		/* Set the Farsi keymap mode */
+    }
+#endif
+
+#ifdef FEAT_GUI
+    if (gui.starting)
+    {
+#if defined(UNIX) || defined(VMS)
+	/* When something caused a message from a vimrc script, need to output
+	 * an extra newline before the shell prompt. */
+	if (did_emsg || msg_didout)
+	    putchar('\n');
+#endif
+
+	gui_start();		/* will set full_screen to TRUE */
+	TIME_MSG("starting GUI");
+
+	/* When running "evim" or "gvim -y" we need the menus, exit if we
+	 * don't have them. */
+	if (!gui.in_use && params.evim_mode)
+	    mch_exit(1);
+    }
+#endif
+
+#ifdef SPAWNO		/* special MSDOS swapping library */
+    init_SPAWNO("", SWAP_ANY);
+#endif
+
+#ifdef FEAT_VIMINFO
+    /*
+     * Read in registers, history etc, but not marks, from the viminfo file
+     */
+    if (*p_viminfo != NUL)
+    {
+	read_viminfo(NULL, TRUE, FALSE, FALSE);
+	TIME_MSG("reading viminfo");
+    }
+#endif
+
+#ifdef FEAT_QUICKFIX
+    /*
+     * "-q errorfile": Load the error file now.
+     * If the error file can't be read, exit before doing anything else.
+     */
+    if (params.edit_type == EDIT_QF)
+    {
+	if (params.use_ef != NULL)
+	    set_string_option_direct((char_u *)"ef", -1,
+					   params.use_ef, OPT_FREE, SID_CARG);
+	if (qf_init(NULL, p_ef, p_efm, TRUE) < 0)
+	{
+	    out_char('\n');
+	    mch_exit(3);
+	}
+	TIME_MSG("reading errorfile");
+    }
+#endif
+
+    /*
+     * Start putting things on the screen.
+     * Scroll screen down before drawing over it
+     * Clear screen now, so file message will not be cleared.
+     */
+    starting = NO_BUFFERS;
+    no_wait_return = FALSE;
+    if (!exmode_active)
+	msg_scroll = FALSE;
+
+#ifdef FEAT_GUI
+    /*
+     * This seems to be required to make callbacks to be called now, instead
+     * of after things have been put on the screen, which then may be deleted
+     * when getting a resize callback.
+     * For the Mac this handles putting files dropped on the Vim icon to
+     * global_alist.
+     */
+    if (gui.in_use)
+    {
+# ifdef FEAT_SUN_WORKSHOP
+	if (!usingSunWorkShop)
+# endif
+	    gui_wait_for_chars(50L);
+	TIME_MSG("GUI delay");
+    }
+#endif
+
+#if defined(FEAT_GUI_PHOTON) && defined(FEAT_CLIPBOARD)
+    qnx_clip_init();
+#endif
+
+#ifdef FEAT_XCLIPBOARD
+    /* Start using the X clipboard, unless the GUI was started. */
+# ifdef FEAT_GUI
+    if (!gui.in_use)
+# endif
+    {
+	setup_term_clip();
+	TIME_MSG("setup clipboard");
+    }
+#endif
+
+#ifdef FEAT_CLIENTSERVER
+    /* Prepare for being a Vim server. */
+    prepare_server(&params);
+#endif
+
+    /*
+     * If "-" argument given: Read file from stdin.
+     * Do this before starting Raw mode, because it may change things that the
+     * writing end of the pipe doesn't like, e.g., in case stdin and stderr
+     * are the same terminal: "cat | vim -".
+     * Using autocommands here may cause trouble...
+     */
+    if (params.edit_type == EDIT_STDIN && !recoverymode)
+	read_stdin();
+
+#if defined(UNIX) || defined(VMS)
+    /* When switching screens and something caused a message from a vimrc
+     * script, need to output an extra newline on exit. */
+    if ((did_emsg || msg_didout) && *T_TI != NUL)
+	newline_on_exit = TRUE;
+#endif
+
+    /*
+     * When done something that is not allowed or error message call
+     * wait_return.  This must be done before starttermcap(), because it may
+     * switch to another screen. It must be done after settmode(TMODE_RAW),
+     * because we want to react on a single key stroke.
+     * Call settmode and starttermcap here, so the T_KS and T_TI may be
+     * defined by termcapinit and redefined in .exrc.
+     */
+    settmode(TMODE_RAW);
+    TIME_MSG("setting raw mode");
+
+    if (need_wait_return || msg_didany)
+    {
+	wait_return(TRUE);
+	TIME_MSG("waiting for return");
+    }
+
+    starttermcap();	    /* start termcap if not done by wait_return() */
+    TIME_MSG("start termcap");
+
+#ifdef FEAT_MOUSE
+    setmouse();				/* may start using the mouse */
+#endif
+    if (scroll_region)
+	scroll_region_reset();		/* In case Rows changed */
+    scroll_start();	/* may scroll the screen to the right position */
+
+    /*
+     * Don't clear the screen when starting in Ex mode, unless using the GUI.
+     */
+    if (exmode_active
+#ifdef FEAT_GUI
+			&& !gui.in_use
+#endif
+					)
+	must_redraw = CLEAR;
+    else
+    {
+	screenclear();			/* clear screen */
+	TIME_MSG("clearing screen");
+    }
+
+#ifdef FEAT_CRYPT
+    if (params.ask_for_key)
+    {
+	(void)get_crypt_key(TRUE, TRUE);
+	TIME_MSG("getting crypt key");
+    }
+#endif
+
+    no_wait_return = TRUE;
+
+    /*
+     * Create the requested number of windows and edit buffers in them.
+     * Also does recovery if "recoverymode" set.
+     */
+    create_windows(&params);
+    TIME_MSG("opening buffers");
+
+#ifdef FEAT_EVAL
+    /* clear v:swapcommand */
+    set_vim_var_string(VV_SWAPCOMMAND, NULL, -1);
+#endif
+
+    /* Ex starts at last line of the file */
+    if (exmode_active)
+	curwin->w_cursor.lnum = curbuf->b_ml.ml_line_count;
+
+#ifdef FEAT_AUTOCMD
+    apply_autocmds(EVENT_BUFENTER, NULL, NULL, FALSE, curbuf);
+    TIME_MSG("BufEnter autocommands");
+#endif
+    setpcmark();
+
+#ifdef FEAT_QUICKFIX
+    /*
+     * When started with "-q errorfile" jump to first error now.
+     */
+    if (params.edit_type == EDIT_QF)
+    {
+	qf_jump(NULL, 0, 0, FALSE);
+	TIME_MSG("jump to first error");
+    }
+#endif
+
+#ifdef FEAT_WINDOWS
+    /*
+     * If opened more than one window, start editing files in the other
+     * windows.
+     */
+    edit_buffers(&params);
+#endif
+
+#ifdef FEAT_DIFF
+    if (params.diff_mode)
+    {
+	win_T	*wp;
+
+	/* set options in each window for "vimdiff". */
+	for (wp = firstwin; wp != NULL; wp = wp->w_next)
+	    diff_win_options(wp, TRUE);
+    }
+#endif
+
+    /*
+     * Shorten any of the filenames, but only when absolute.
+     */
+    shorten_fnames(FALSE);
+
+    /*
+     * Need to jump to the tag before executing the '-c command'.
+     * Makes "vim -c '/return' -t main" work.
+     */
+    if (params.tagname != NULL)
+    {
+#if defined(HAS_SWAP_EXISTS_ACTION)
+	swap_exists_did_quit = FALSE;
+#endif
+
+	vim_snprintf((char *)IObuff, IOSIZE, "ta %s", params.tagname);
+	do_cmdline_cmd(IObuff);
+	TIME_MSG("jumping to tag");
+
+#if defined(HAS_SWAP_EXISTS_ACTION)
+	/* If the user doesn't want to edit the file then we quit here. */
+	if (swap_exists_did_quit)
+	    getout(1);
+#endif
+    }
+
+    /* Execute any "+", "-c" and "-S" arguments. */
+    if (params.n_commands > 0)
+	exe_commands(&params);
+
+    RedrawingDisabled = 0;
+    redraw_all_later(NOT_VALID);
+    no_wait_return = FALSE;
+    starting = 0;
+
+#ifdef FEAT_TERMRESPONSE
+    /* Requesting the termresponse is postponed until here, so that a "-c q"
+     * argument doesn't make it appear in the shell Vim was started from. */
+    may_req_termresponse();
+#endif
+
+    /* start in insert mode */
+    if (p_im)
+	need_start_insertmode = TRUE;
+
+#ifdef FEAT_AUTOCMD
+    apply_autocmds(EVENT_VIMENTER, NULL, NULL, FALSE, curbuf);
+    TIME_MSG("VimEnter autocommands");
+#endif
+
+#if defined(FEAT_DIFF) && defined(FEAT_SCROLLBIND)
+    /* When a startup script or session file setup for diff'ing and
+     * scrollbind, sync the scrollbind now. */
+    if (curwin->w_p_diff && curwin->w_p_scb)
+    {
+	update_topline();
+	check_scrollbind((linenr_T)0, 0L);
+	TIME_MSG("diff scrollbinding");
+    }
+#endif
+
+#if defined(WIN3264) && !defined(FEAT_GUI_W32)
+    mch_set_winsize_now();	    /* Allow winsize changes from now on */
+#endif
+
+#if defined(FEAT_GUI) && defined(FEAT_WINDOWS)
+    /* When tab pages were created, may need to update the tab pages line and
+     * scrollbars.  This is skipped while creating them. */
+    if (first_tabpage->tp_next != NULL)
+    {
+	out_flush();
+	gui_init_which_components(NULL);
+	gui_update_scrollbars(TRUE);
+    }
+    need_mouse_correct = TRUE;
+#endif
+
+    /* If ":startinsert" command used, stuff a dummy command to be able to
+     * call normal_cmd(), which will then start Insert mode. */
+    if (restart_edit != 0)
+	stuffcharReadbuff(K_NOP);
+
+#ifdef FEAT_NETBEANS_INTG
+    if (usingNetbeans)
+	/* Tell the client that it can start sending commands. */
+	netbeans_startup_done();
+#endif
+
+    TIME_MSG("before starting main loop");
+
+    /*
+     * Call the main command loop.  This never returns.
+     */
+    main_loop(FALSE, FALSE);
+
+    return 0;
+}
+#endif /* PROTO */
+
+/*
+ * Main loop: Execute Normal mode commands until exiting Vim.
+ * Also used to handle commands in the command-line window, until the window
+ * is closed.
+ * Also used to handle ":visual" command after ":global": execute Normal mode
+ * commands, return when entering Ex mode.  "noexmode" is TRUE then.
+ */
+    void
+main_loop(cmdwin, noexmode)
+    int		cmdwin;	    /* TRUE when working in the command-line window */
+    int		noexmode;   /* TRUE when return on entering Ex mode */
+{
+    oparg_T	oa;	/* operator arguments */
+
+#if defined(FEAT_X11) && defined(FEAT_XCLIPBOARD)
+    /* Setup to catch a terminating error from the X server.  Just ignore
+     * it, restore the state and continue.  This might not always work
+     * properly, but at least we don't exit unexpectedly when the X server
+     * exists while Vim is running in a console. */
+    if (!cmdwin && !noexmode && SETJMP(x_jump_env))
+    {
+	State = NORMAL;
+# ifdef FEAT_VISUAL
+	VIsual_active = FALSE;
+# endif
+	got_int = TRUE;
+	need_wait_return = FALSE;
+	global_busy = FALSE;
+	exmode_active = 0;
+	skip_redraw = FALSE;
+	RedrawingDisabled = 0;
+	no_wait_return = 0;
+# ifdef FEAT_EVAL
+	emsg_skip = 0;
+# endif
+	emsg_off = 0;
+# ifdef FEAT_MOUSE
+	setmouse();
+# endif
+	settmode(TMODE_RAW);
+	starttermcap();
+	scroll_start();
+	redraw_later_clear();
+    }
+#endif
+
+    clear_oparg(&oa);
+    while (!cmdwin
+#ifdef FEAT_CMDWIN
+	    || cmdwin_result == 0
+#endif
+	    )
+    {
+	if (stuff_empty())
+	{
+	    did_check_timestamps = FALSE;
+	    if (need_check_timestamps)
+		check_timestamps(FALSE);
+	    if (need_wait_return)	/* if wait_return still needed ... */
+		wait_return(FALSE);	/* ... call it now */
+	    if (need_start_insertmode && goto_im()
+#ifdef FEAT_VISUAL
+		    && !VIsual_active
+#endif
+		    )
+	    {
+		need_start_insertmode = FALSE;
+		stuffReadbuff((char_u *)"i");	/* start insert mode next */
+		/* skip the fileinfo message now, because it would be shown
+		 * after insert mode finishes! */
+		need_fileinfo = FALSE;
+	    }
+	}
+	if (got_int && !global_busy)
+	{
+	    if (!quit_more)
+		(void)vgetc();		/* flush all buffers */
+	    got_int = FALSE;
+	}
+	if (!exmode_active)
+	    msg_scroll = FALSE;
+	quit_more = FALSE;
+
+	/*
+	 * If skip redraw is set (for ":" in wait_return()), don't redraw now.
+	 * If there is nothing in the stuff_buffer or do_redraw is TRUE,
+	 * update cursor and redraw.
+	 */
+	if (skip_redraw || exmode_active)
+	    skip_redraw = FALSE;
+	else if (do_redraw || stuff_empty())
+	{
+#ifdef FEAT_AUTOCMD
+	    /* Trigger CursorMoved if the cursor moved. */
+	    if (!finish_op && has_cursormoved()
+			     && !equalpos(last_cursormoved, curwin->w_cursor))
+	    {
+		apply_autocmds(EVENT_CURSORMOVED, NULL, NULL, FALSE, curbuf);
+		last_cursormoved = curwin->w_cursor;
+	    }
+#endif
+
+#if defined(FEAT_DIFF) && defined(FEAT_SCROLLBIND)
+	    /* Scroll-binding for diff mode may have been postponed until
+	     * here.  Avoids doing it for every change. */
+	    if (diff_need_scrollbind)
+	    {
+		check_scrollbind((linenr_T)0, 0L);
+		diff_need_scrollbind = FALSE;
+	    }
+#endif
+#if defined(FEAT_FOLDING) && defined(FEAT_VISUAL)
+	    /* Include a closed fold completely in the Visual area. */
+	    foldAdjustVisual();
+#endif
+#ifdef FEAT_FOLDING
+	    /*
+	     * When 'foldclose' is set, apply 'foldlevel' to folds that don't
+	     * contain the cursor.
+	     * When 'foldopen' is "all", open the fold(s) under the cursor.
+	     * This may mark the window for redrawing.
+	     */
+	    if (hasAnyFolding(curwin) && !char_avail())
+	    {
+		foldCheckClose();
+		if (fdo_flags & FDO_ALL)
+		    foldOpenCursor();
+	    }
+#endif
+
+	    /*
+	     * Before redrawing, make sure w_topline is correct, and w_leftcol
+	     * if lines don't wrap, and w_skipcol if lines wrap.
+	     */
+	    update_topline();
+	    validate_cursor();
+
+#ifdef FEAT_VISUAL
+	    if (VIsual_active)
+		update_curbuf(INVERTED);/* update inverted part */
+	    else
+#endif
+		if (must_redraw)
+		update_screen(0);
+	    else if (redraw_cmdline || clear_cmdline)
+		showmode();
+#ifdef FEAT_WINDOWS
+	    redraw_statuslines();
+#endif
+#ifdef FEAT_TITLE
+	    if (need_maketitle)
+		maketitle();
+#endif
+	    /* display message after redraw */
+	    if (keep_msg != NULL)
+	    {
+		char_u *p;
+
+		/* msg_attr_keep() will set keep_msg to NULL, must free the
+		 * string here. */
+		p = keep_msg;
+		keep_msg = NULL;
+		msg_attr(p, keep_msg_attr);
+		vim_free(p);
+	    }
+	    if (need_fileinfo)		/* show file info after redraw */
+	    {
+		fileinfo(FALSE, TRUE, FALSE);
+		need_fileinfo = FALSE;
+	    }
+
+	    emsg_on_display = FALSE;	/* can delete error message now */
+	    did_emsg = FALSE;
+	    msg_didany = FALSE;		/* reset lines_left in msg_start() */
+	    may_clear_sb_text();	/* clear scroll-back text on next msg */
+	    showruler(FALSE);
+
+	    setcursor();
+	    cursor_on();
+
+	    do_redraw = FALSE;
+	}
+#ifdef FEAT_GUI
+	if (need_mouse_correct)
+	    gui_mouse_correct();
+#endif
+
+	/*
+	 * Update w_curswant if w_set_curswant has been set.
+	 * Postponed until here to avoid computing w_virtcol too often.
+	 */
+	update_curswant();
+
+#ifdef FEAT_EVAL
+	/*
+	 * May perform garbage collection when waiting for a character, but
+	 * only at the very toplevel.  Otherwise we may be using a List or
+	 * Dict internally somewhere.
+	 * "may_garbage_collect" is reset in vgetc() which is invoked through
+	 * do_exmode() and normal_cmd().
+	 */
+	may_garbage_collect = (!cmdwin && !noexmode);
+#endif
+	/*
+	 * If we're invoked as ex, do a round of ex commands.
+	 * Otherwise, get and execute a normal mode command.
+	 */
+	if (exmode_active)
+	{
+	    if (noexmode)   /* End of ":global/path/visual" commands */
+		return;
+	    do_exmode(exmode_active == EXMODE_VIM);
+	}
+	else
+	    normal_cmd(&oa, TRUE);
+    }
+}
+
+
+#if defined(USE_XSMP) || defined(FEAT_GUI_MSWIN) || defined(PROTO)
+/*
+ * Exit, but leave behind swap files for modified buffers.
+ */
+    void
+getout_preserve_modified(exitval)
+    int		exitval;
+{
+# if defined(SIGHUP) && defined(SIG_IGN)
+    /* Ignore SIGHUP, because a dropped connection causes a read error, which
+     * makes Vim exit and then handling SIGHUP causes various reentrance
+     * problems. */
+    signal(SIGHUP, SIG_IGN);
+# endif
+
+    ml_close_notmod();		    /* close all not-modified buffers */
+    ml_sync_all(FALSE, FALSE);	    /* preserve all swap files */
+    ml_close_all(FALSE);	    /* close all memfiles, without deleting */
+    getout(exitval);		    /* exit Vim properly */
+}
+#endif
+
+
+/* Exit properly */
+    void
+getout(exitval)
+    int		exitval;
+{
+#ifdef FEAT_AUTOCMD
+    buf_T	*buf;
+    win_T	*wp;
+    tabpage_T	*tp, *next_tp;
+#endif
+
+    exiting = TRUE;
+
+    /* When running in Ex mode an error causes us to exit with a non-zero exit
+     * code.  POSIX requires this, although it's not 100% clear from the
+     * standard. */
+    if (exmode_active)
+	exitval += ex_exitval;
+
+    /* Position the cursor on the last screen line, below all the text */
+#ifdef FEAT_GUI
+    if (!gui.in_use)
+#endif
+	windgoto((int)Rows - 1, 0);
+
+#if defined(FEAT_EVAL) || defined(FEAT_SYN_HL)
+    /* Optionally print hashtable efficiency. */
+    hash_debug_results();
+#endif
+
+#ifdef FEAT_GUI
+    msg_didany = FALSE;
+#endif
+
+#ifdef FEAT_AUTOCMD
+    /* Trigger BufWinLeave for all windows, but only once per buffer. */
+# if defined FEAT_WINDOWS
+    for (tp = first_tabpage; tp != NULL; tp = next_tp)
+    {
+	next_tp = tp->tp_next;
+	for (wp = (tp == curtab)
+		    ? firstwin : tp->tp_firstwin; wp != NULL; wp = wp->w_next)
+	{
+	    buf = wp->w_buffer;
+	    if (buf->b_changedtick != -1)
+	    {
+		apply_autocmds(EVENT_BUFWINLEAVE, buf->b_fname, buf->b_fname,
+								  FALSE, buf);
+		buf->b_changedtick = -1;    /* note that we did it already */
+		/* start all over, autocommands may mess up the lists */
+		next_tp = first_tabpage;
+		break;
+	    }
+	}
+    }
+# else
+    apply_autocmds(EVENT_BUFWINLEAVE, curbuf, curbuf->b_fname, FALSE, curbuf);
+# endif
+
+    /* Trigger BufUnload for buffers that are loaded */
+    for (buf = firstbuf; buf != NULL; buf = buf->b_next)
+	if (buf->b_ml.ml_mfp != NULL)
+	{
+	    apply_autocmds(EVENT_BUFUNLOAD, buf->b_fname, buf->b_fname,
+								  FALSE, buf);
+	    if (!buf_valid(buf))	/* autocmd may delete the buffer */
+		break;
+	}
+    apply_autocmds(EVENT_VIMLEAVEPRE, NULL, NULL, FALSE, curbuf);
+#endif
+
+#ifdef FEAT_VIMINFO
+    if (*p_viminfo != NUL)
+	/* Write out the registers, history, marks etc, to the viminfo file */
+	write_viminfo(NULL, FALSE);
+#endif
+
+#ifdef FEAT_AUTOCMD
+    apply_autocmds(EVENT_VIMLEAVE, NULL, NULL, FALSE, curbuf);
+#endif
+
+#ifdef FEAT_PROFILE
+    profile_dump();
+#endif
+
+    if (did_emsg
+#ifdef FEAT_GUI
+	    || (gui.in_use && msg_didany && p_verbose > 0)
+#endif
+	    )
+    {
+	/* give the user a chance to read the (error) message */
+	no_wait_return = FALSE;
+	wait_return(FALSE);
+    }
+
+#ifdef FEAT_AUTOCMD
+    /* Position the cursor again, the autocommands may have moved it */
+# ifdef FEAT_GUI
+    if (!gui.in_use)
+# endif
+	windgoto((int)Rows - 1, 0);
+#endif
+
+#ifdef FEAT_MZSCHEME
+    mzscheme_end();
+#endif
+#ifdef FEAT_TCL
+    tcl_end();
+#endif
+#ifdef FEAT_RUBY
+    ruby_end();
+#endif
+#ifdef FEAT_PYTHON
+    python_end();
+#endif
+#ifdef FEAT_PERL
+    perl_end();
+#endif
+#if defined(USE_ICONV) && defined(DYNAMIC_ICONV)
+    iconv_end();
+#endif
+#ifdef FEAT_NETBEANS_INTG
+    netbeans_end();
+#endif
+
+    mch_exit(exitval);
+}
+
+/*
+ * Get a (optional) count for a Vim argument.
+ */
+    static int
+get_number_arg(p, idx, def)
+    char_u	*p;	    /* pointer to argument */
+    int		*idx;	    /* index in argument, is incremented */
+    int		def;	    /* default value */
+{
+    if (vim_isdigit(p[*idx]))
+    {
+	def = atoi((char *)&(p[*idx]));
+	while (vim_isdigit(p[*idx]))
+	    *idx = *idx + 1;
+    }
+    return def;
+}
+
+#if defined(HAVE_LOCALE_H) || defined(X_LOCALE)
+/*
+ * Setup to use the current locale (for ctype() and many other things).
+ */
+    static void
+init_locale()
+{
+    setlocale(LC_ALL, "");
+# ifdef WIN32
+    /* Apparently MS-Windows printf() may cause a crash when we give it 8-bit
+     * text while it's expecting text in the current locale.  This call avoids
+     * that. */
+    setlocale(LC_CTYPE, "C");
+# endif
+
+# ifdef FEAT_GETTEXT
+    {
+	int	mustfree = FALSE;
+	char_u	*p;
+
+#  ifdef DYNAMIC_GETTEXT
+	/* Initialize the gettext library */
+	dyn_libintl_init(NULL);
+#  endif
+	/* expand_env() doesn't work yet, because chartab[] is not initialized
+	 * yet, call vim_getenv() directly */
+	p = vim_getenv((char_u *)"VIMRUNTIME", &mustfree);
+	if (p != NULL && *p != NUL)
+	{
+	    STRCPY(NameBuff, p);
+	    STRCAT(NameBuff, "/lang");
+	    bindtextdomain(VIMPACKAGE, (char *)NameBuff);
+	}
+	if (mustfree)
+	    vim_free(p);
+	textdomain(VIMPACKAGE);
+    }
+# endif
+}
+#endif
+
+/*
+ * Check for: [r][e][g][vi|vim|view][diff][ex[im]]
+ * If the executable name starts with "r" we disable shell commands.
+ * If the next character is "e" we run in Easy mode.
+ * If the next character is "g" we run the GUI version.
+ * If the next characters are "view" we start in readonly mode.
+ * If the next characters are "diff" or "vimdiff" we start in diff mode.
+ * If the next characters are "ex" we start in Ex mode.  If it's followed
+ * by "im" use improved Ex mode.
+ */
+    static void
+parse_command_name(parmp)
+    mparm_T	*parmp;
+{
+    char_u	*initstr;
+
+    initstr = gettail((char_u *)parmp->argv[0]);
+
+#ifdef MACOS_X_UNIX
+    /* An issue has been seen when launching Vim in such a way that
+     * $PWD/$ARGV[0] or $ARGV[0] is not the absolute path to the
+     * executable or a symbolic link of it. Until this issue is resolved
+     * we prohibit the GUI from being used.
+     */
+    if (STRCMP(initstr, parmp->argv[0]) == 0)
+	disallow_gui = TRUE;
+
+    /* TODO: On MacOS X default to gui if argv[0] ends in:
+     *       /Vim.app/Contents/MacOS/Vim */
+#endif
+
+#ifdef FEAT_EVAL
+    set_vim_var_string(VV_PROGNAME, initstr, -1);
+#endif
+
+    if (TOLOWER_ASC(initstr[0]) == 'r')
+    {
+	restricted = TRUE;
+	++initstr;
+    }
+
+    /* Avoid using evim mode for "editor". */
+    if (TOLOWER_ASC(initstr[0]) == 'e'
+	    && (TOLOWER_ASC(initstr[1]) == 'v'
+		|| TOLOWER_ASC(initstr[1]) == 'g'))
+    {
+#ifdef FEAT_GUI
+	gui.starting = TRUE;
+#endif
+	parmp->evim_mode = TRUE;
+	++initstr;
+    }
+
+    if (TOLOWER_ASC(initstr[0]) == 'g' || initstr[0] == 'k')
+    {
+	main_start_gui();
+#ifdef FEAT_GUI
+	++initstr;
+#endif
+    }
+
+    if (STRNICMP(initstr, "view", 4) == 0)
+    {
+	readonlymode = TRUE;
+	curbuf->b_p_ro = TRUE;
+	p_uc = 10000;			/* don't update very often */
+	initstr += 4;
+    }
+    else if (STRNICMP(initstr, "vim", 3) == 0)
+	initstr += 3;
+
+    /* Catch "[r][g]vimdiff" and "[r][g]viewdiff". */
+    if (STRICMP(initstr, "diff") == 0)
+    {
+#ifdef FEAT_DIFF
+	parmp->diff_mode = TRUE;
+#else
+	mch_errmsg(_("This Vim was not compiled with the diff feature."));
+	mch_errmsg("\n");
+	mch_exit(2);
+#endif
+    }
+
+    if (STRNICMP(initstr, "ex", 2) == 0)
+    {
+	if (STRNICMP(initstr + 2, "im", 2) == 0)
+	    exmode_active = EXMODE_VIM;
+	else
+	    exmode_active = EXMODE_NORMAL;
+	change_compatible(TRUE);	/* set 'compatible' */
+    }
+}
+
+/*
+ * Get the name of the display, before gui_prepare() removes it from
+ * argv[].  Used for the xterm-clipboard display.
+ *
+ * Also find the --server... arguments and --socketid
+ */
+/*ARGSUSED*/
+    static void
+early_arg_scan(parmp)
+    mparm_T	*parmp;
+{
+#if defined(FEAT_XCLIPBOARD) || defined(FEAT_CLIENTSERVER)
+    int		argc = parmp->argc;
+    char	**argv = parmp->argv;
+    int		i;
+
+    for (i = 1; i < argc; i++)
+    {
+	if (STRCMP(argv[i], "--") == 0)
+	    break;
+# ifdef FEAT_XCLIPBOARD
+	else if (STRICMP(argv[i], "-display") == 0
+#  if defined(FEAT_GUI_GTK)
+		|| STRICMP(argv[i], "--display") == 0
+#  endif
+		)
+	{
+	    if (i == argc - 1)
+		mainerr_arg_missing((char_u *)argv[i]);
+	    xterm_display = argv[++i];
+	}
+# endif
+# ifdef FEAT_CLIENTSERVER
+	else if (STRICMP(argv[i], "--servername") == 0)
+	{
+	    if (i == argc - 1)
+		mainerr_arg_missing((char_u *)argv[i]);
+	    parmp->serverName_arg = (char_u *)argv[++i];
+	}
+	else if (STRICMP(argv[i], "--serverlist") == 0)
+	    parmp->serverArg = TRUE;
+	else if (STRNICMP(argv[i], "--remote", 8) == 0)
+	{
+	    parmp->serverArg = TRUE;
+#  ifdef FEAT_GUI
+	    if (strstr(argv[i], "-wait") != 0)
+		/* don't fork() when starting the GUI to edit files ourself */
+		gui.dofork = FALSE;
+#  endif
+	}
+# endif
+# ifdef FEAT_GUI_GTK
+	else if (STRICMP(argv[i], "--socketid") == 0)
+	{
+	    unsigned int    socket_id;
+	    int		    count;
+
+	    if (i == argc - 1)
+		mainerr_arg_missing((char_u *)argv[i]);
+	    if (STRNICMP(argv[i+1], "0x", 2) == 0)
+		count = sscanf(&(argv[i + 1][2]), "%x", &socket_id);
+	    else
+		count = sscanf(argv[i+1], "%u", &socket_id);
+	    if (count != 1)
+		mainerr(ME_INVALID_ARG, (char_u *)argv[i]);
+	    else
+		gtk_socket_id = socket_id;
+	    i++;
+	}
+	else if (STRICMP(argv[i], "--echo-wid") == 0)
+	    echo_wid_arg = TRUE;
+# endif
+    }
+#endif
+}
+
+/*
+ * Scan the command line arguments.
+ */
+    static void
+command_line_scan(parmp)
+    mparm_T	*parmp;
+{
+    int		argc = parmp->argc;
+    char	**argv = parmp->argv;
+    int		argv_idx;		/* index in argv[n][] */
+    int		had_minmin = FALSE;	/* found "--" argument */
+    int		want_argument;		/* option argument with argument */
+    int		c;
+    char_u	*p = NULL;
+    long	n;
+
+    --argc;
+    ++argv;
+    argv_idx = 1;	    /* active option letter is argv[0][argv_idx] */
+    while (argc > 0)
+    {
+	/*
+	 * "+" or "+{number}" or "+/{pat}" or "+{command}" argument.
+	 */
+	if (argv[0][0] == '+' && !had_minmin)
+	{
+	    if (parmp->n_commands >= MAX_ARG_CMDS)
+		mainerr(ME_EXTRA_CMD, NULL);
+	    argv_idx = -1;	    /* skip to next argument */
+	    if (argv[0][1] == NUL)
+		parmp->commands[parmp->n_commands++] = (char_u *)"$";
+	    else
+		parmp->commands[parmp->n_commands++] = (char_u *)&(argv[0][1]);
+	}
+
+	/*
+	 * Optional argument.
+	 */
+	else if (argv[0][0] == '-' && !had_minmin)
+	{
+	    want_argument = FALSE;
+	    c = argv[0][argv_idx++];
+#ifdef VMS
+	    /*
+	     * VMS only uses upper case command lines.  Interpret "-X" as "-x"
+	     * and "-/X" as "-X".
+	     */
+	    if (c == '/')
+	    {
+		c = argv[0][argv_idx++];
+		c = TOUPPER_ASC(c);
+	    }
+	    else
+		c = TOLOWER_ASC(c);
+#endif
+	    switch (c)
+	    {
+	    case NUL:		/* "vim -"  read from stdin */
+				/* "ex -" silent mode */
+		if (exmode_active)
+		    silent_mode = TRUE;
+		else
+		{
+		    if (parmp->edit_type != EDIT_NONE)
+			mainerr(ME_TOO_MANY_ARGS, (char_u *)argv[0]);
+		    parmp->edit_type = EDIT_STDIN;
+		    read_cmd_fd = 2;	/* read from stderr instead of stdin */
+		}
+		argv_idx = -1;		/* skip to next argument */
+		break;
+
+	    case '-':		/* "--" don't take any more option arguments */
+				/* "--help" give help message */
+				/* "--version" give version message */
+				/* "--literal" take files literally */
+				/* "--nofork" don't fork */
+				/* "--noplugin[s]" skip plugins */
+				/* "--cmd <cmd>" execute cmd before vimrc */
+		if (STRICMP(argv[0] + argv_idx, "help") == 0)
+		    usage();
+		else if (STRICMP(argv[0] + argv_idx, "version") == 0)
+		{
+		    Columns = 80;	/* need to init Columns */
+		    info_message = TRUE; /* use mch_msg(), not mch_errmsg() */
+		    list_version();
+		    msg_putchar('\n');
+		    msg_didout = FALSE;
+		    mch_exit(0);
+		}
+		else if (STRNICMP(argv[0] + argv_idx, "literal", 7) == 0)
+		{
+#if (!defined(UNIX) && !defined(__EMX__)) || defined(ARCHIE)
+		    parmp->literal = TRUE;
+#endif
+		}
+		else if (STRNICMP(argv[0] + argv_idx, "nofork", 6) == 0)
+		{
+#ifdef FEAT_GUI
+		    gui.dofork = FALSE;	/* don't fork() when starting GUI */
+#endif
+		}
+		else if (STRNICMP(argv[0] + argv_idx, "noplugin", 8) == 0)
+		    p_lpl = FALSE;
+		else if (STRNICMP(argv[0] + argv_idx, "cmd", 3) == 0)
+		{
+		    want_argument = TRUE;
+		    argv_idx += 3;
+		}
+#ifdef FEAT_CLIENTSERVER
+		else if (STRNICMP(argv[0] + argv_idx, "serverlist", 10) == 0)
+		    ; /* already processed -- no arg */
+		else if (STRNICMP(argv[0] + argv_idx, "servername", 10) == 0
+		       || STRNICMP(argv[0] + argv_idx, "serversend", 10) == 0)
+		{
+		    /* already processed -- snatch the following arg */
+		    if (argc > 1)
+		    {
+			--argc;
+			++argv;
+		    }
+		}
+#endif
+#ifdef FEAT_GUI_GTK
+		else if (STRNICMP(argv[0] + argv_idx, "socketid", 8) == 0)
+		{
+		    /* already processed -- snatch the following arg */
+		    if (argc > 1)
+		    {
+			--argc;
+			++argv;
+		    }
+		}
+		else if (STRNICMP(argv[0] + argv_idx, "echo-wid", 8) == 0)
+		{
+		    /* already processed, skip */
+		}
+#endif
+		else
+		{
+		    if (argv[0][argv_idx])
+			mainerr(ME_UNKNOWN_OPTION, (char_u *)argv[0]);
+		    had_minmin = TRUE;
+		}
+		if (!want_argument)
+		    argv_idx = -1;	/* skip to next argument */
+		break;
+
+	    case 'A':		/* "-A" start in Arabic mode */
+#ifdef FEAT_ARABIC
+		set_option_value((char_u *)"arabic", 1L, NULL, 0);
+#else
+		mch_errmsg(_(e_noarabic));
+		mch_exit(2);
+#endif
+		break;
+
+	    case 'b':		/* "-b" binary mode */
+		/* Needs to be effective before expanding file names, because
+		 * for Win32 this makes us edit a shortcut file itself,
+		 * instead of the file it links to. */
+		set_options_bin(curbuf->b_p_bin, 1, 0);
+		curbuf->b_p_bin = 1;	    /* binary file I/O */
+		break;
+
+	    case 'C':		/* "-C"  Compatible */
+		change_compatible(TRUE);
+		break;
+
+	    case 'e':		/* "-e" Ex mode */
+		exmode_active = EXMODE_NORMAL;
+		break;
+
+	    case 'E':		/* "-E" Improved Ex mode */
+		exmode_active = EXMODE_VIM;
+		break;
+
+	    case 'f':		/* "-f"  GUI: run in foreground.  Amiga: open
+				window directly, not with newcli */
+#ifdef FEAT_GUI
+		gui.dofork = FALSE;	/* don't fork() when starting GUI */
+#endif
+		break;
+
+	    case 'g':		/* "-g" start GUI */
+		main_start_gui();
+		break;
+
+	    case 'F':		/* "-F" start in Farsi mode: rl + fkmap set */
+#ifdef FEAT_FKMAP
+		curwin->w_p_rl = p_fkmap = TRUE;
+#else
+		mch_errmsg(_(e_nofarsi));
+		mch_exit(2);
+#endif
+		break;
+
+	    case 'h':		/* "-h" give help message */
+#ifdef FEAT_GUI_GNOME
+		/* Tell usage() to exit for "gvim". */
+		gui.starting = FALSE;
+#endif
+		usage();
+		break;
+
+	    case 'H':		/* "-H" start in Hebrew mode: rl + hkmap set */
+#ifdef FEAT_RIGHTLEFT
+		curwin->w_p_rl = p_hkmap = TRUE;
+#else
+		mch_errmsg(_(e_nohebrew));
+		mch_exit(2);
+#endif
+		break;
+
+	    case 'l':		/* "-l" lisp mode, 'lisp' and 'showmatch' on */
+#ifdef FEAT_LISP
+		set_option_value((char_u *)"lisp", 1L, NULL, 0);
+		p_sm = TRUE;
+#endif
+		break;
+
+	    case 'M':		/* "-M"  no changes or writing of files */
+		reset_modifiable();
+		/* FALLTHROUGH */
+
+	    case 'm':		/* "-m"  no writing of files */
+		p_write = FALSE;
+		break;
+
+	    case 'y':		/* "-y"  easy mode */
+#ifdef FEAT_GUI
+		gui.starting = TRUE;	/* start GUI a bit later */
+#endif
+		parmp->evim_mode = TRUE;
+		break;
+
+	    case 'N':		/* "-N"  Nocompatible */
+		change_compatible(FALSE);
+		break;
+
+	    case 'n':		/* "-n" no swap file */
+		parmp->no_swap_file = TRUE;
+		break;
+
+	    case 'p':		/* "-p[N]" open N tab pages */
+#ifdef TARGET_API_MAC_OSX
+		/* For some reason on MacOS X, an argument like:
+		   -psn_0_10223617 is passed in when invoke from Finder
+		   or with the 'open' command */
+		if (argv[0][argv_idx] == 's')
+		{
+		    argv_idx = -1; /* bypass full -psn */
+		    main_start_gui();
+		    break;
+		}
+#endif
+#ifdef FEAT_WINDOWS
+		/* default is 0: open window for each file */
+		parmp->window_count = get_number_arg((char_u *)argv[0],
+								&argv_idx, 0);
+		parmp->window_layout = WIN_TABS;
+#endif
+		break;
+
+	    case 'o':		/* "-o[N]" open N horizontal split windows */
+#ifdef FEAT_WINDOWS
+		/* default is 0: open window for each file */
+		parmp->window_count = get_number_arg((char_u *)argv[0],
+								&argv_idx, 0);
+		parmp->window_layout = WIN_HOR;
+#endif
+		break;
+
+		case 'O':	/* "-O[N]" open N vertical split windows */
+#if defined(FEAT_VERTSPLIT) && defined(FEAT_WINDOWS)
+		/* default is 0: open window for each file */
+		parmp->window_count = get_number_arg((char_u *)argv[0],
+								&argv_idx, 0);
+		parmp->window_layout = WIN_VER;
+#endif
+		break;
+
+#ifdef FEAT_QUICKFIX
+	    case 'q':		/* "-q" QuickFix mode */
+		if (parmp->edit_type != EDIT_NONE)
+		    mainerr(ME_TOO_MANY_ARGS, (char_u *)argv[0]);
+		parmp->edit_type = EDIT_QF;
+		if (argv[0][argv_idx])		/* "-q{errorfile}" */
+		{
+		    parmp->use_ef = (char_u *)argv[0] + argv_idx;
+		    argv_idx = -1;
+		}
+		else if (argc > 1)		/* "-q {errorfile}" */
+		    want_argument = TRUE;
+		break;
+#endif
+
+	    case 'R':		/* "-R" readonly mode */
+		readonlymode = TRUE;
+		curbuf->b_p_ro = TRUE;
+		p_uc = 10000;			/* don't update very often */
+		break;
+
+	    case 'r':		/* "-r" recovery mode */
+	    case 'L':		/* "-L" recovery mode */
+		recoverymode = 1;
+		break;
+
+	    case 's':
+		if (exmode_active)	/* "-s" silent (batch) mode */
+		    silent_mode = TRUE;
+		else		/* "-s {scriptin}" read from script file */
+		    want_argument = TRUE;
+		break;
+
+	    case 't':		/* "-t {tag}" or "-t{tag}" jump to tag */
+		if (parmp->edit_type != EDIT_NONE)
+		    mainerr(ME_TOO_MANY_ARGS, (char_u *)argv[0]);
+		parmp->edit_type = EDIT_TAG;
+		if (argv[0][argv_idx])		/* "-t{tag}" */
+		{
+		    parmp->tagname = (char_u *)argv[0] + argv_idx;
+		    argv_idx = -1;
+		}
+		else				/* "-t {tag}" */
+		    want_argument = TRUE;
+		break;
+
+#ifdef FEAT_EVAL
+	    case 'D':		/* "-D"		Debugging */
+		parmp->use_debug_break_level = 9999;
+		break;
+#endif
+#ifdef FEAT_DIFF
+	    case 'd':		/* "-d"		'diff' */
+# ifdef AMIGA
+		/* check for "-dev {device}" */
+		if (argv[0][argv_idx] == 'e' && argv[0][argv_idx + 1] == 'v')
+		    want_argument = TRUE;
+		else
+# endif
+		    parmp->diff_mode = TRUE;
+		break;
+#endif
+	    case 'V':		/* "-V{N}"	Verbose level */
+		/* default is 10: a little bit verbose */
+		p_verbose = get_number_arg((char_u *)argv[0], &argv_idx, 10);
+		if (argv[0][argv_idx] != NUL)
+		{
+		    set_option_value((char_u *)"verbosefile", 0L,
+					     (char_u *)argv[0] + argv_idx, 0);
+		    argv_idx = (int)STRLEN(argv[0]);
+		}
+		break;
+
+	    case 'v':		/* "-v"  Vi-mode (as if called "vi") */
+		exmode_active = 0;
+#ifdef FEAT_GUI
+		gui.starting = FALSE;	/* don't start GUI */
+#endif
+		break;
+
+	    case 'w':		/* "-w{number}"	set window height */
+				/* "-w {scriptout}"	write to script */
+		if (vim_isdigit(((char_u *)argv[0])[argv_idx]))
+		{
+		    n = get_number_arg((char_u *)argv[0], &argv_idx, 10);
+		    set_option_value((char_u *)"window", n, NULL, 0);
+		    break;
+		}
+		want_argument = TRUE;
+		break;
+
+#ifdef FEAT_CRYPT
+	    case 'x':		/* "-x"  encrypted reading/writing of files */
+		parmp->ask_for_key = TRUE;
+		break;
+#endif
+
+	    case 'X':		/* "-X"  don't connect to X server */
+#if (defined(UNIX) || defined(VMS)) && defined(FEAT_X11)
+		x_no_connect = TRUE;
+#endif
+		break;
+
+	    case 'Z':		/* "-Z"  restricted mode */
+		restricted = TRUE;
+		break;
+
+	    case 'c':		/* "-c{command}" or "-c {command}" execute
+				   command */
+		if (argv[0][argv_idx] != NUL)
+		{
+		    if (parmp->n_commands >= MAX_ARG_CMDS)
+			mainerr(ME_EXTRA_CMD, NULL);
+		    parmp->commands[parmp->n_commands++] = (char_u *)argv[0]
+								   + argv_idx;
+		    argv_idx = -1;
+		    break;
+		}
+		/*FALLTHROUGH*/
+	    case 'S':		/* "-S {file}" execute Vim script */
+	    case 'i':		/* "-i {viminfo}" use for viminfo */
+#ifndef FEAT_DIFF
+	    case 'd':		/* "-d {device}" device (for Amiga) */
+#endif
+	    case 'T':		/* "-T {terminal}" terminal name */
+	    case 'u':		/* "-u {vimrc}" vim inits file */
+	    case 'U':		/* "-U {gvimrc}" gvim inits file */
+	    case 'W':		/* "-W {scriptout}" overwrite */
+#ifdef FEAT_GUI_W32
+	    case 'P':		/* "-P {parent title}" MDI parent */
+#endif
+		want_argument = TRUE;
+		break;
+
+	    default:
+		mainerr(ME_UNKNOWN_OPTION, (char_u *)argv[0]);
+	    }
+
+	    /*
+	     * Handle option arguments with argument.
+	     */
+	    if (want_argument)
+	    {
+		/*
+		 * Check for garbage immediately after the option letter.
+		 */
+		if (argv[0][argv_idx] != NUL)
+		    mainerr(ME_GARBAGE, (char_u *)argv[0]);
+
+		--argc;
+		if (argc < 1 && c != 'S')
+		    mainerr_arg_missing((char_u *)argv[0]);
+		++argv;
+		argv_idx = -1;
+
+		switch (c)
+		{
+		case 'c':	/* "-c {command}" execute command */
+		case 'S':	/* "-S {file}" execute Vim script */
+		    if (parmp->n_commands >= MAX_ARG_CMDS)
+			mainerr(ME_EXTRA_CMD, NULL);
+		    if (c == 'S')
+		    {
+			char	*a;
+
+			if (argc < 1)
+			    /* "-S" without argument: use default session file
+			     * name. */
+			    a = SESSION_FILE;
+			else if (argv[0][0] == '-')
+			{
+			    /* "-S" followed by another option: use default
+			     * session file name. */
+			    a = SESSION_FILE;
+			    ++argc;
+			    --argv;
+			}
+			else
+			    a = argv[0];
+			p = alloc((unsigned)(STRLEN(a) + 4));
+			if (p == NULL)
+			    mch_exit(2);
+			sprintf((char *)p, "so %s", a);
+			parmp->cmds_tofree[parmp->n_commands] = TRUE;
+			parmp->commands[parmp->n_commands++] = p;
+		    }
+		    else
+			parmp->commands[parmp->n_commands++] =
+							    (char_u *)argv[0];
+		    break;
+
+		case '-':	/* "--cmd {command}" execute command */
+		    if (parmp->n_pre_commands >= MAX_ARG_CMDS)
+			mainerr(ME_EXTRA_CMD, NULL);
+		    parmp->pre_commands[parmp->n_pre_commands++] =
+							    (char_u *)argv[0];
+		    break;
+
+	    /*	case 'd':   -d {device} is handled in mch_check_win() for the
+	     *		    Amiga */
+
+#ifdef FEAT_QUICKFIX
+		case 'q':	/* "-q {errorfile}" QuickFix mode */
+		    parmp->use_ef = (char_u *)argv[0];
+		    break;
+#endif
+
+		case 'i':	/* "-i {viminfo}" use for viminfo */
+		    use_viminfo = (char_u *)argv[0];
+		    break;
+
+		case 's':	/* "-s {scriptin}" read from script file */
+		    if (scriptin[0] != NULL)
+		    {
+scripterror:
+			mch_errmsg(_("Attempt to open script file again: \""));
+			mch_errmsg(argv[-1]);
+			mch_errmsg(" ");
+			mch_errmsg(argv[0]);
+			mch_errmsg("\"\n");
+			mch_exit(2);
+		    }
+		    if ((scriptin[0] = mch_fopen(argv[0], READBIN)) == NULL)
+		    {
+			mch_errmsg(_("Cannot open for reading: \""));
+			mch_errmsg(argv[0]);
+			mch_errmsg("\"\n");
+			mch_exit(2);
+		    }
+		    if (save_typebuf() == FAIL)
+			mch_exit(2);	/* out of memory */
+		    break;
+
+		case 't':	/* "-t {tag}" */
+		    parmp->tagname = (char_u *)argv[0];
+		    break;
+
+		case 'T':	/* "-T {terminal}" terminal name */
+		    /*
+		     * The -T term argument is always available and when
+		     * HAVE_TERMLIB is supported it overrides the environment
+		     * variable TERM.
+		     */
+#ifdef FEAT_GUI
+		    if (term_is_gui((char_u *)argv[0]))
+			gui.starting = TRUE;	/* start GUI a bit later */
+		    else
+#endif
+			parmp->term = (char_u *)argv[0];
+		    break;
+
+		case 'u':	/* "-u {vimrc}" vim inits file */
+		    parmp->use_vimrc = (char_u *)argv[0];
+		    break;
+
+		case 'U':	/* "-U {gvimrc}" gvim inits file */
+#ifdef FEAT_GUI
+		    use_gvimrc = (char_u *)argv[0];
+#endif
+		    break;
+
+		case 'w':	/* "-w {nr}" 'window' value */
+				/* "-w {scriptout}" append to script file */
+		    if (vim_isdigit(*((char_u *)argv[0])))
+		    {
+			argv_idx = 0;
+			n = get_number_arg((char_u *)argv[0], &argv_idx, 10);
+			set_option_value((char_u *)"window", n, NULL, 0);
+			argv_idx = -1;
+			break;
+		    }
+		    /*FALLTHROUGH*/
+		case 'W':	/* "-W {scriptout}" overwrite script file */
+		    if (scriptout != NULL)
+			goto scripterror;
+		    if ((scriptout = mch_fopen(argv[0],
+				    c == 'w' ? APPENDBIN : WRITEBIN)) == NULL)
+		    {
+			mch_errmsg(_("Cannot open for script output: \""));
+			mch_errmsg(argv[0]);
+			mch_errmsg("\"\n");
+			mch_exit(2);
+		    }
+		    break;
+
+#ifdef FEAT_GUI_W32
+		case 'P':		/* "-P {parent title}" MDI parent */
+		    gui_mch_set_parent(argv[0]);
+		    break;
+#endif
+		}
+	    }
+	}
+
+	/*
+	 * File name argument.
+	 */
+	else
+	{
+	    argv_idx = -1;	    /* skip to next argument */
+
+	    /* Check for only one type of editing. */
+	    if (parmp->edit_type != EDIT_NONE && parmp->edit_type != EDIT_FILE)
+		mainerr(ME_TOO_MANY_ARGS, (char_u *)argv[0]);
+	    parmp->edit_type = EDIT_FILE;
+
+#ifdef MSWIN
+	    /* Remember if the argument was a full path before changing
+	     * slashes to backslashes. */
+	    if (argv[0][0] != NUL && argv[0][1] == ':' && argv[0][2] == '\\')
+		parmp->full_path = TRUE;
+#endif
+
+	    /* Add the file to the global argument list. */
+	    if (ga_grow(&global_alist.al_ga, 1) == FAIL
+		    || (p = vim_strsave((char_u *)argv[0])) == NULL)
+		mch_exit(2);
+#ifdef FEAT_DIFF
+	    if (parmp->diff_mode && mch_isdir(p) && GARGCOUNT > 0
+				      && !mch_isdir(alist_name(&GARGLIST[0])))
+	    {
+		char_u	    *r;
+
+		r = concat_fnames(p, gettail(alist_name(&GARGLIST[0])), TRUE);
+		if (r != NULL)
+		{
+		    vim_free(p);
+		    p = r;
+		}
+	    }
+#endif
+#if defined(__CYGWIN32__) && !defined(WIN32)
+	    /*
+	     * If vim is invoked by non-Cygwin tools, convert away any
+	     * DOS paths, so things like .swp files are created correctly.
+	     * Look for evidence of non-Cygwin paths before we bother.
+	     * This is only for when using the Unix files.
+	     */
+	    if (strpbrk(p, "\\:") != NULL)
+	    {
+		char posix_path[PATH_MAX];
+
+		cygwin_conv_to_posix_path(p, posix_path);
+		vim_free(p);
+		p = vim_strsave(posix_path);
+		if (p == NULL)
+		    mch_exit(2);
+	    }
+#endif
+
+#ifdef USE_FNAME_CASE
+	    /* Make the case of the file name match the actual file. */
+	    fname_case(p, 0);
+#endif
+
+	    alist_add(&global_alist, p,
+#if (!defined(UNIX) && !defined(__EMX__)) || defined(ARCHIE)
+		    parmp->literal ? 2 : 0	/* add buffer nr after exp. */
+#else
+		    2		/* add buffer number now and use curbuf */
+#endif
+		    );
+
+#if defined(FEAT_MBYTE) && defined(WIN32)
+	    {
+		/* Remember this argument has been added to the argument list.
+		 * Needed when 'encoding' is changed. */
+		used_file_arg(argv[0], parmp->literal, parmp->full_path,
+							    parmp->diff_mode);
+	    }
+#endif
+	}
+
+	/*
+	 * If there are no more letters after the current "-", go to next
+	 * argument.  argv_idx is set to -1 when the current argument is to be
+	 * skipped.
+	 */
+	if (argv_idx <= 0 || argv[0][argv_idx] == NUL)
+	{
+	    --argc;
+	    ++argv;
+	    argv_idx = 1;
+	}
+    }
+
+#ifdef FEAT_EVAL
+    /* If there is a "+123" or "-c" command, set v:swapcommand to the first
+     * one. */
+    if (parmp->n_commands > 0)
+    {
+	p = alloc((unsigned)STRLEN(parmp->commands[0]) + 3);
+	if (p != NULL)
+	{
+	    sprintf((char *)p, ":%s\r", parmp->commands[0]);
+	    set_vim_var_string(VV_SWAPCOMMAND, p, -1);
+	    vim_free(p);
+	}
+    }
+#endif
+}
+
+/*
+ * Print a warning if stdout is not a terminal.
+ * When starting in Ex mode and commands come from a file, set Silent mode.
+ */
+    static void
+check_tty(parmp)
+    mparm_T	*parmp;
+{
+    int		input_isatty;		/* is active input a terminal? */
+
+    input_isatty = mch_input_isatty();
+    if (exmode_active)
+    {
+	if (!input_isatty)
+	    silent_mode = TRUE;
+    }
+    else if (parmp->want_full_screen && (!parmp->stdout_isatty || !input_isatty)
+#ifdef FEAT_GUI
+	    /* don't want the delay when started from the desktop */
+	    && !gui.starting
+#endif
+	    )
+    {
+#ifdef NBDEBUG
+	/*
+	 * This shouldn't be necessary. But if I run netbeans with the log
+	 * output coming to the console and XOpenDisplay fails, I get vim
+	 * trying to start with input/output to my console tty.  This fills my
+	 * input buffer so fast I can't even kill the process in under 2
+	 * minutes (and it beeps continuously the whole time :-)
+	 */
+	if (usingNetbeans && (!parmp->stdout_isatty || !input_isatty))
+	{
+	    mch_errmsg(_("Vim: Error: Failure to start gvim from NetBeans\n"));
+	    exit(1);
+	}
+#endif
+	if (!parmp->stdout_isatty)
+	    mch_errmsg(_("Vim: Warning: Output is not to a terminal\n"));
+	if (!input_isatty)
+	    mch_errmsg(_("Vim: Warning: Input is not from a terminal\n"));
+	out_flush();
+	if (scriptin[0] == NULL)
+	    ui_delay(2000L, TRUE);
+	TIME_MSG("Warning delay");
+    }
+}
+
+/*
+ * Read text from stdin.
+ */
+    static void
+read_stdin()
+{
+    int	    i;
+
+#if defined(HAS_SWAP_EXISTS_ACTION)
+    /* When getting the ATTENTION prompt here, use a dialog */
+    swap_exists_action = SEA_DIALOG;
+#endif
+    no_wait_return = TRUE;
+    i = msg_didany;
+    set_buflisted(TRUE);
+    (void)open_buffer(TRUE, NULL);	/* create memfile and read file */
+    no_wait_return = FALSE;
+    msg_didany = i;
+    TIME_MSG("reading stdin");
+#if defined(HAS_SWAP_EXISTS_ACTION)
+    check_swap_exists_action();
+#endif
+#if !(defined(AMIGA) || defined(MACOS))
+    /*
+     * Close stdin and dup it from stderr.  Required for GPM to work
+     * properly, and for running external commands.
+     * Is there any other system that cannot do this?
+     */
+    close(0);
+    dup(2);
+#endif
+}
+
+/*
+ * Create the requested number of windows and edit buffers in them.
+ * Also does recovery if "recoverymode" set.
+ */
+/*ARGSUSED*/
+    static void
+create_windows(parmp)
+    mparm_T	*parmp;
+{
+#ifdef FEAT_WINDOWS
+    int		dorewind;
+    int		done = 0;
+
+    /*
+     * Create the number of windows that was requested.
+     */
+    if (parmp->window_count == -1)	/* was not set */
+	parmp->window_count = 1;
+    if (parmp->window_count == 0)
+	parmp->window_count = GARGCOUNT;
+    if (parmp->window_count > 1)
+    {
+	/* Don't change the windows if there was a command in .vimrc that
+	 * already split some windows */
+	if (parmp->window_layout == 0)
+	    parmp->window_layout = WIN_HOR;
+	if (parmp->window_layout == WIN_TABS)
+	{
+	    parmp->window_count = make_tabpages(parmp->window_count);
+	    TIME_MSG("making tab pages");
+	}
+	else if (firstwin->w_next == NULL)
+	{
+	    parmp->window_count = make_windows(parmp->window_count,
+					     parmp->window_layout == WIN_VER);
+	    TIME_MSG("making windows");
+	}
+	else
+	    parmp->window_count = win_count();
+    }
+    else
+	parmp->window_count = 1;
+#endif
+
+    if (recoverymode)			/* do recover */
+    {
+	msg_scroll = TRUE;		/* scroll message up */
+	ml_recover();
+	if (curbuf->b_ml.ml_mfp == NULL) /* failed */
+	    getout(1);
+	do_modelines(0);		/* do modelines */
+    }
+    else
+    {
+	/*
+	 * Open a buffer for windows that don't have one yet.
+	 * Commands in the .vimrc might have loaded a file or split the window.
+	 * Watch out for autocommands that delete a window.
+	 */
+#ifdef FEAT_AUTOCMD
+	/*
+	 * Don't execute Win/Buf Enter/Leave autocommands here
+	 */
+	++autocmd_no_enter;
+	++autocmd_no_leave;
+#endif
+#ifdef FEAT_WINDOWS
+	dorewind = TRUE;
+	while (done++ < 1000)
+	{
+	    if (dorewind)
+	    {
+		if (parmp->window_layout == WIN_TABS)
+		    goto_tabpage(1);
+		else
+		    curwin = firstwin;
+	    }
+	    else if (parmp->window_layout == WIN_TABS)
+	    {
+		if (curtab->tp_next == NULL)
+		    break;
+		goto_tabpage(0);
+	    }
+	    else
+	    {
+		if (curwin->w_next == NULL)
+		    break;
+		curwin = curwin->w_next;
+	    }
+	    dorewind = FALSE;
+#endif
+	    curbuf = curwin->w_buffer;
+	    if (curbuf->b_ml.ml_mfp == NULL)
+	    {
+#ifdef FEAT_FOLDING
+		/* Set 'foldlevel' to 'foldlevelstart' if it's not negative. */
+		if (p_fdls >= 0)
+		    curwin->w_p_fdl = p_fdls;
+#endif
+#if defined(HAS_SWAP_EXISTS_ACTION)
+		/* When getting the ATTENTION prompt here, use a dialog */
+		swap_exists_action = SEA_DIALOG;
+#endif
+		set_buflisted(TRUE);
+		(void)open_buffer(FALSE, NULL); /* create memfile, read file */
+
+#if defined(HAS_SWAP_EXISTS_ACTION)
+		if (swap_exists_action == SEA_QUIT)
+		{
+		    if (got_int || only_one_window())
+		    {
+			/* abort selected or quit and only one window */
+			did_emsg = FALSE;   /* avoid hit-enter prompt */
+			getout(1);
+		    }
+		    /* We can't close the window, it would disturb what
+		     * happens next.  Clear the file name and set the arg
+		     * index to -1 to delete it later. */
+		    setfname(curbuf, NULL, NULL, FALSE);
+		    curwin->w_arg_idx = -1;
+		    swap_exists_action = SEA_NONE;
+		}
+		else
+		    handle_swap_exists(NULL);
+#endif
+#ifdef FEAT_AUTOCMD
+		dorewind = TRUE;		/* start again */
+#endif
+	    }
+#ifdef FEAT_WINDOWS
+	    ui_breakcheck();
+	    if (got_int)
+	    {
+		(void)vgetc();	/* only break the file loading, not the rest */
+		break;
+	    }
+	}
+#endif
+#ifdef FEAT_WINDOWS
+	if (parmp->window_layout == WIN_TABS)
+	    goto_tabpage(1);
+	else
+	    curwin = firstwin;
+	curbuf = curwin->w_buffer;
+#endif
+#ifdef FEAT_AUTOCMD
+	--autocmd_no_enter;
+	--autocmd_no_leave;
+#endif
+    }
+}
+
+#ifdef FEAT_WINDOWS
+    /*
+     * If opened more than one window, start editing files in the other
+     * windows.  make_windows() has already opened the windows.
+     */
+    static void
+edit_buffers(parmp)
+    mparm_T	*parmp;
+{
+    int		arg_idx;		/* index in argument list */
+    int		i;
+    int		advance = TRUE;
+    buf_T	*old_curbuf;
+
+# ifdef FEAT_AUTOCMD
+    /*
+     * Don't execute Win/Buf Enter/Leave autocommands here
+     */
+    ++autocmd_no_enter;
+    ++autocmd_no_leave;
+# endif
+
+    /* When w_arg_idx is -1 remove the window (see create_windows()). */
+    if (curwin->w_arg_idx == -1)
+    {
+	win_close(curwin, TRUE);
+	advance = FALSE;
+    }
+
+    arg_idx = 1;
+    for (i = 1; i < parmp->window_count; ++i)
+    {
+	/* When w_arg_idx is -1 remove the window (see create_windows()). */
+	if (curwin->w_arg_idx == -1)
+	{
+	    ++arg_idx;
+	    win_close(curwin, TRUE);
+	    advance = FALSE;
+	    continue;
+	}
+
+	if (advance)
+	{
+	    if (parmp->window_layout == WIN_TABS)
+	    {
+		if (curtab->tp_next == NULL)	/* just checking */
+		    break;
+		goto_tabpage(0);
+	    }
+	    else
+	    {
+		if (curwin->w_next == NULL)	/* just checking */
+		    break;
+		win_enter(curwin->w_next, FALSE);
+	    }
+	}
+	advance = TRUE;
+
+	/* Only open the file if there is no file in this window yet (that can
+	 * happen when .vimrc contains ":sall"). */
+	if (curbuf == firstwin->w_buffer || curbuf->b_ffname == NULL)
+	{
+	    curwin->w_arg_idx = arg_idx;
+	    /* Edit file from arg list, if there is one.  When "Quit" selected
+	     * at the ATTENTION prompt close the window. */
+	    old_curbuf = curbuf;
+	    (void)do_ecmd(0, arg_idx < GARGCOUNT
+			  ? alist_name(&GARGLIST[arg_idx]) : NULL,
+			  NULL, NULL, ECMD_LASTL, ECMD_HIDE);
+	    if (curbuf == old_curbuf)
+	    {
+		if (got_int || only_one_window())
+		{
+		    /* abort selected or quit and only one window */
+		    did_emsg = FALSE;   /* avoid hit-enter prompt */
+		    getout(1);
+		}
+		win_close(curwin, TRUE);
+		advance = FALSE;
+	    }
+	    if (arg_idx == GARGCOUNT - 1)
+		arg_had_last = TRUE;
+	    ++arg_idx;
+	}
+	ui_breakcheck();
+	if (got_int)
+	{
+	    (void)vgetc();	/* only break the file loading, not the rest */
+	    break;
+	}
+    }
+
+    if (parmp->window_layout == WIN_TABS)
+	goto_tabpage(1);
+# ifdef FEAT_AUTOCMD
+    --autocmd_no_enter;
+# endif
+    win_enter(firstwin, FALSE);		/* back to first window */
+# ifdef FEAT_AUTOCMD
+    --autocmd_no_leave;
+# endif
+    TIME_MSG("editing files in windows");
+    if (parmp->window_count > 1 && parmp->window_layout != WIN_TABS)
+	win_equal(curwin, FALSE, 'b');	/* adjust heights */
+}
+#endif /* FEAT_WINDOWS */
+
+/*
+ * Execute the commands from --cmd arguments "cmds[cnt]".
+ */
+    static void
+exe_pre_commands(parmp)
+    mparm_T	*parmp;
+{
+    char_u	**cmds = parmp->pre_commands;
+    int		cnt = parmp->n_pre_commands;
+    int		i;
+
+    if (cnt > 0)
+    {
+	curwin->w_cursor.lnum = 0; /* just in case.. */
+	sourcing_name = (char_u *)_("pre-vimrc command line");
+# ifdef FEAT_EVAL
+	current_SID = SID_CMDARG;
+# endif
+	for (i = 0; i < cnt; ++i)
+	    do_cmdline_cmd(cmds[i]);
+	sourcing_name = NULL;
+# ifdef FEAT_EVAL
+	current_SID = 0;
+# endif
+	TIME_MSG("--cmd commands");
+    }
+}
+
+/*
+ * Execute "+", "-c" and "-S" arguments.
+ */
+    static void
+exe_commands(parmp)
+    mparm_T	*parmp;
+{
+    int		i;
+
+    /*
+     * We start commands on line 0, make "vim +/pat file" match a
+     * pattern on line 1.  But don't move the cursor when an autocommand
+     * with g`" was used.
+     */
+    msg_scroll = TRUE;
+    if (parmp->tagname == NULL && curwin->w_cursor.lnum <= 1)
+	curwin->w_cursor.lnum = 0;
+    sourcing_name = (char_u *)"command line";
+#ifdef FEAT_EVAL
+    current_SID = SID_CARG;
+#endif
+    for (i = 0; i < parmp->n_commands; ++i)
+    {
+	do_cmdline_cmd(parmp->commands[i]);
+	if (parmp->cmds_tofree[i])
+	    vim_free(parmp->commands[i]);
+    }
+    sourcing_name = NULL;
+#ifdef FEAT_EVAL
+    current_SID = 0;
+#endif
+    if (curwin->w_cursor.lnum == 0)
+	curwin->w_cursor.lnum = 1;
+
+    if (!exmode_active)
+	msg_scroll = FALSE;
+
+#ifdef FEAT_QUICKFIX
+    /* When started with "-q errorfile" jump to first error again. */
+    if (parmp->edit_type == EDIT_QF)
+	qf_jump(NULL, 0, 0, FALSE);
+#endif
+    TIME_MSG("executing command arguments");
+}
+
+/*
+ * Source startup scripts.
+ */
+    static void
+source_startup_scripts(parmp)
+    mparm_T	*parmp;
+{
+    int		i;
+
+    /*
+     * For "evim" source evim.vim first of all, so that the user can overrule
+     * any things he doesn't like.
+     */
+    if (parmp->evim_mode)
+    {
+	(void)do_source((char_u *)EVIM_FILE, FALSE, DOSO_NONE);
+	TIME_MSG("source evim file");
+    }
+
+    /*
+     * If -u argument given, use only the initializations from that file and
+     * nothing else.
+     */
+    if (parmp->use_vimrc != NULL)
+    {
+	if (STRCMP(parmp->use_vimrc, "NONE") == 0
+				     || STRCMP(parmp->use_vimrc, "NORC") == 0)
+	{
+#ifdef FEAT_GUI
+	    if (use_gvimrc == NULL)	    /* don't load gvimrc either */
+		use_gvimrc = parmp->use_vimrc;
+#endif
+	    if (parmp->use_vimrc[2] == 'N')
+		p_lpl = FALSE;		    /* don't load plugins either */
+	}
+	else
+	{
+	    if (do_source(parmp->use_vimrc, FALSE, DOSO_NONE) != OK)
+		EMSG2(_("E282: Cannot read from \"%s\""), parmp->use_vimrc);
+	}
+    }
+    else if (!silent_mode)
+    {
+#ifdef AMIGA
+	struct Process	*proc = (struct Process *)FindTask(0L);
+	APTR		save_winptr = proc->pr_WindowPtr;
+
+	/* Avoid a requester here for a volume that doesn't exist. */
+	proc->pr_WindowPtr = (APTR)-1L;
+#endif
+
+	/*
+	 * Get system wide defaults, if the file name is defined.
+	 */
+#ifdef SYS_VIMRC_FILE
+	(void)do_source((char_u *)SYS_VIMRC_FILE, FALSE, DOSO_NONE);
+#endif
+#ifdef MACOS_X
+	(void)do_source((char_u *)"$VIMRUNTIME/macmap.vim", FALSE, DOSO_NONE);
+#endif
+
+	/*
+	 * Try to read initialization commands from the following places:
+	 * - environment variable VIMINIT
+	 * - user vimrc file (s:.vimrc for Amiga, ~/.vimrc otherwise)
+	 * - second user vimrc file ($VIM/.vimrc for Dos)
+	 * - environment variable EXINIT
+	 * - user exrc file (s:.exrc for Amiga, ~/.exrc otherwise)
+	 * - second user exrc file ($VIM/.exrc for Dos)
+	 * The first that exists is used, the rest is ignored.
+	 */
+	if (process_env((char_u *)"VIMINIT", TRUE) != OK)
+	{
+	    if (do_source((char_u *)USR_VIMRC_FILE, TRUE, DOSO_VIMRC) == FAIL
+#ifdef USR_VIMRC_FILE2
+		&& do_source((char_u *)USR_VIMRC_FILE2, TRUE,
+							   DOSO_VIMRC) == FAIL
+#endif
+#ifdef USR_VIMRC_FILE3
+		&& do_source((char_u *)USR_VIMRC_FILE3, TRUE,
+							   DOSO_VIMRC) == FAIL
+#endif
+		&& process_env((char_u *)"EXINIT", FALSE) == FAIL
+		&& do_source((char_u *)USR_EXRC_FILE, FALSE, DOSO_NONE) == FAIL)
+	    {
+#ifdef USR_EXRC_FILE2
+		(void)do_source((char_u *)USR_EXRC_FILE2, FALSE, DOSO_NONE);
+#endif
+	    }
+	}
+
+	/*
+	 * Read initialization commands from ".vimrc" or ".exrc" in current
+	 * directory.  This is only done if the 'exrc' option is set.
+	 * Because of security reasons we disallow shell and write commands
+	 * now, except for unix if the file is owned by the user or 'secure'
+	 * option has been reset in environment of global ".exrc" or ".vimrc".
+	 * Only do this if VIMRC_FILE is not the same as USR_VIMRC_FILE or
+	 * SYS_VIMRC_FILE.
+	 */
+	if (p_exrc)
+	{
+#if defined(UNIX) || defined(VMS)
+	    /* If ".vimrc" file is not owned by user, set 'secure' mode. */
+	    if (!file_owned(VIMRC_FILE))
+#endif
+		secure = p_secure;
+
+	    i = FAIL;
+	    if (fullpathcmp((char_u *)USR_VIMRC_FILE,
+				      (char_u *)VIMRC_FILE, FALSE) != FPC_SAME
+#ifdef USR_VIMRC_FILE2
+		    && fullpathcmp((char_u *)USR_VIMRC_FILE2,
+				      (char_u *)VIMRC_FILE, FALSE) != FPC_SAME
+#endif
+#ifdef USR_VIMRC_FILE3
+		    && fullpathcmp((char_u *)USR_VIMRC_FILE3,
+				      (char_u *)VIMRC_FILE, FALSE) != FPC_SAME
+#endif
+#ifdef SYS_VIMRC_FILE
+		    && fullpathcmp((char_u *)SYS_VIMRC_FILE,
+				      (char_u *)VIMRC_FILE, FALSE) != FPC_SAME
+#endif
+				)
+		i = do_source((char_u *)VIMRC_FILE, TRUE, DOSO_VIMRC);
+
+	    if (i == FAIL)
+	    {
+#if defined(UNIX) || defined(VMS)
+		/* if ".exrc" is not owned by user set 'secure' mode */
+		if (!file_owned(EXRC_FILE))
+		    secure = p_secure;
+		else
+		    secure = 0;
+#endif
+		if (	   fullpathcmp((char_u *)USR_EXRC_FILE,
+				      (char_u *)EXRC_FILE, FALSE) != FPC_SAME
+#ifdef USR_EXRC_FILE2
+			&& fullpathcmp((char_u *)USR_EXRC_FILE2,
+				      (char_u *)EXRC_FILE, FALSE) != FPC_SAME
+#endif
+				)
+		    (void)do_source((char_u *)EXRC_FILE, FALSE, DOSO_NONE);
+	    }
+	}
+	if (secure == 2)
+	    need_wait_return = TRUE;
+	secure = 0;
+#ifdef AMIGA
+	proc->pr_WindowPtr = save_winptr;
+#endif
+    }
+    TIME_MSG("sourcing vimrc file(s)");
+}
+
+/*
+ * Setup to start using the GUI.  Exit with an error when not available.
+ */
+    static void
+main_start_gui()
+{
+#ifdef FEAT_GUI
+    gui.starting = TRUE;	/* start GUI a bit later */
+#else
+    mch_errmsg(_(e_nogvim));
+    mch_errmsg("\n");
+    mch_exit(2);
+#endif
+}
+
+/*
+ * Get an environment variable, and execute it as Ex commands.
+ * Returns FAIL if the environment variable was not executed, OK otherwise.
+ */
+    int
+process_env(env, is_viminit)
+    char_u	*env;
+    int		is_viminit; /* when TRUE, called for VIMINIT */
+{
+    char_u	*initstr;
+    char_u	*save_sourcing_name;
+    linenr_T	save_sourcing_lnum;
+#ifdef FEAT_EVAL
+    scid_T	save_sid;
+#endif
+
+    if ((initstr = mch_getenv(env)) != NULL && *initstr != NUL)
+    {
+	if (is_viminit)
+	    vimrc_found(NULL, NULL);
+	save_sourcing_name = sourcing_name;
+	save_sourcing_lnum = sourcing_lnum;
+	sourcing_name = env;
+	sourcing_lnum = 0;
+#ifdef FEAT_EVAL
+	save_sid = current_SID;
+	current_SID = SID_ENV;
+#endif
+	do_cmdline_cmd(initstr);
+	sourcing_name = save_sourcing_name;
+	sourcing_lnum = save_sourcing_lnum;
+#ifdef FEAT_EVAL
+	current_SID = save_sid;;
+#endif
+	return OK;
+    }
+    return FAIL;
+}
+
+#if defined(UNIX) || defined(VMS)
+/*
+ * Return TRUE if we are certain the user owns the file "fname".
+ * Used for ".vimrc" and ".exrc".
+ * Use both stat() and lstat() for extra security.
+ */
+    static int
+file_owned(fname)
+    char	*fname;
+{
+    struct stat s;
+# ifdef UNIX
+    uid_t	uid = getuid();
+# else	 /* VMS */
+    uid_t	uid = ((getgid() << 16) | getuid());
+# endif
+
+    return !(mch_stat(fname, &s) != 0 || s.st_uid != uid
+# ifdef HAVE_LSTAT
+	    || mch_lstat(fname, &s) != 0 || s.st_uid != uid
+# endif
+	    );
+}
+#endif
+
+/*
+ * Give an error message main_errors["n"] and exit.
+ */
+    static void
+mainerr(n, str)
+    int		n;	/* one of the ME_ defines */
+    char_u	*str;	/* extra argument or NULL */
+{
+#if defined(UNIX) || defined(__EMX__) || defined(VMS)
+    reset_signals();		/* kill us with CTRL-C here, if you like */
+#endif
+
+    mch_errmsg(longVersion);
+    mch_errmsg("\n");
+    mch_errmsg(_(main_errors[n]));
+    if (str != NULL)
+    {
+	mch_errmsg(": \"");
+	mch_errmsg((char *)str);
+	mch_errmsg("\"");
+    }
+    mch_errmsg(_("\nMore info with: \"vim -h\"\n"));
+
+    mch_exit(1);
+}
+
+    void
+mainerr_arg_missing(str)
+    char_u	*str;
+{
+    mainerr(ME_ARG_MISSING, str);
+}
+
+/*
+ * print a message with three spaces prepended and '\n' appended.
+ */
+    static void
+main_msg(s)
+    char *s;
+{
+    mch_msg("   ");
+    mch_msg(s);
+    mch_msg("\n");
+}
+
+/*
+ * Print messages for "vim -h" or "vim --help" and exit.
+ */
+    static void
+usage()
+{
+    int		i;
+    static char	*(use[]) =
+    {
+	N_("[file ..]       edit specified file(s)"),
+	N_("-               read text from stdin"),
+	N_("-t tag          edit file where tag is defined"),
+#ifdef FEAT_QUICKFIX
+	N_("-q [errorfile]  edit file with first error")
+#endif
+    };
+
+#if defined(UNIX) || defined(__EMX__) || defined(VMS)
+    reset_signals();		/* kill us with CTRL-C here, if you like */
+#endif
+
+    mch_msg(longVersion);
+    mch_msg(_("\n\nusage:"));
+    for (i = 0; ; ++i)
+    {
+	mch_msg(_(" vim [arguments] "));
+	mch_msg(_(use[i]));
+	if (i == (sizeof(use) / sizeof(char_u *)) - 1)
+	    break;
+	mch_msg(_("\n   or:"));
+    }
+#ifdef VMS
+    mch_msg(_("\nWhere case is ignored prepend / to make flag upper case"));
+#endif
+
+    mch_msg(_("\n\nArguments:\n"));
+    main_msg(_("--\t\t\tOnly file names after this"));
+#if (!defined(UNIX) && !defined(__EMX__)) || defined(ARCHIE)
+    main_msg(_("--literal\t\tDon't expand wildcards"));
+#endif
+#ifdef FEAT_OLE
+    main_msg(_("-register\t\tRegister this gvim for OLE"));
+    main_msg(_("-unregister\t\tUnregister gvim for OLE"));
+#endif
+#ifdef FEAT_GUI
+    main_msg(_("-g\t\t\tRun using GUI (like \"gvim\")"));
+    main_msg(_("-f  or  --nofork\tForeground: Don't fork when starting GUI"));
+#endif
+    main_msg(_("-v\t\t\tVi mode (like \"vi\")"));
+    main_msg(_("-e\t\t\tEx mode (like \"ex\")"));
+    main_msg(_("-s\t\t\tSilent (batch) mode (only for \"ex\")"));
+#ifdef FEAT_DIFF
+    main_msg(_("-d\t\t\tDiff mode (like \"vimdiff\")"));
+#endif
+    main_msg(_("-y\t\t\tEasy mode (like \"evim\", modeless)"));
+    main_msg(_("-R\t\t\tReadonly mode (like \"view\")"));
+    main_msg(_("-Z\t\t\tRestricted mode (like \"rvim\")"));
+    main_msg(_("-m\t\t\tModifications (writing files) not allowed"));
+    main_msg(_("-M\t\t\tModifications in text not allowed"));
+    main_msg(_("-b\t\t\tBinary mode"));
+#ifdef FEAT_LISP
+    main_msg(_("-l\t\t\tLisp mode"));
+#endif
+    main_msg(_("-C\t\t\tCompatible with Vi: 'compatible'"));
+    main_msg(_("-N\t\t\tNot fully Vi compatible: 'nocompatible'"));
+    main_msg(_("-V[N][fname]\t\tBe verbose [level N] [log messages to fname]"));
+#ifdef FEAT_EVAL
+    main_msg(_("-D\t\t\tDebugging mode"));
+#endif
+    main_msg(_("-n\t\t\tNo swap file, use memory only"));
+    main_msg(_("-r\t\t\tList swap files and exit"));
+    main_msg(_("-r (with file name)\tRecover crashed session"));
+    main_msg(_("-L\t\t\tSame as -r"));
+#ifdef AMIGA
+    main_msg(_("-f\t\t\tDon't use newcli to open window"));
+    main_msg(_("-dev <device>\t\tUse <device> for I/O"));
+#endif
+#ifdef FEAT_ARABIC
+    main_msg(_("-A\t\t\tstart in Arabic mode"));
+#endif
+#ifdef FEAT_RIGHTLEFT
+    main_msg(_("-H\t\t\tStart in Hebrew mode"));
+#endif
+#ifdef FEAT_FKMAP
+    main_msg(_("-F\t\t\tStart in Farsi mode"));
+#endif
+    main_msg(_("-T <terminal>\tSet terminal type to <terminal>"));
+    main_msg(_("-u <vimrc>\t\tUse <vimrc> instead of any .vimrc"));
+#ifdef FEAT_GUI
+    main_msg(_("-U <gvimrc>\t\tUse <gvimrc> instead of any .gvimrc"));
+#endif
+    main_msg(_("--noplugin\t\tDon't load plugin scripts"));
+#ifdef FEAT_WINDOWS
+    main_msg(_("-p[N]\t\tOpen N tab pages (default: one for each file)"));
+    main_msg(_("-o[N]\t\tOpen N windows (default: one for each file)"));
+    main_msg(_("-O[N]\t\tLike -o but split vertically"));
+#endif
+    main_msg(_("+\t\t\tStart at end of file"));
+    main_msg(_("+<lnum>\t\tStart at line <lnum>"));
+    main_msg(_("--cmd <command>\tExecute <command> before loading any vimrc file"));
+    main_msg(_("-c <command>\t\tExecute <command> after loading the first file"));
+    main_msg(_("-S <session>\t\tSource file <session> after loading the first file"));
+    main_msg(_("-s <scriptin>\tRead Normal mode commands from file <scriptin>"));
+    main_msg(_("-w <scriptout>\tAppend all typed commands to file <scriptout>"));
+    main_msg(_("-W <scriptout>\tWrite all typed commands to file <scriptout>"));
+#ifdef FEAT_CRYPT
+    main_msg(_("-x\t\t\tEdit encrypted files"));
+#endif
+#if (defined(UNIX) || defined(VMS)) && defined(FEAT_X11)
+# if defined(FEAT_GUI_X11) && !defined(FEAT_GUI_GTK)
+    main_msg(_("-display <display>\tConnect vim to this particular X-server"));
+# endif
+    main_msg(_("-X\t\t\tDo not connect to X server"));
+#endif
+#ifdef FEAT_CLIENTSERVER
+    main_msg(_("--remote <files>\tEdit <files> in a Vim server if possible"));
+    main_msg(_("--remote-silent <files>  Same, don't complain if there is no server"));
+    main_msg(_("--remote-wait <files>  As --remote but wait for files to have been edited"));
+    main_msg(_("--remote-wait-silent <files>  Same, don't complain if there is no server"));
+# ifdef FEAT_WINDOWS
+    main_msg(_("--remote-tab <files>  As --remote but open tab page for each file"));
+# endif
+    main_msg(_("--remote-send <keys>\tSend <keys> to a Vim server and exit"));
+    main_msg(_("--remote-expr <expr>\tEvaluate <expr> in a Vim server and print result"));
+    main_msg(_("--serverlist\t\tList available Vim server names and exit"));
+    main_msg(_("--servername <name>\tSend to/become the Vim server <name>"));
+#endif
+#ifdef FEAT_VIMINFO
+    main_msg(_("-i <viminfo>\t\tUse <viminfo> instead of .viminfo"));
+#endif
+    main_msg(_("-h  or  --help\tPrint Help (this message) and exit"));
+    main_msg(_("--version\t\tPrint version information and exit"));
+
+#ifdef FEAT_GUI_X11
+# ifdef FEAT_GUI_MOTIF
+    mch_msg(_("\nArguments recognised by gvim (Motif version):\n"));
+# else
+#  ifdef FEAT_GUI_ATHENA
+#   ifdef FEAT_GUI_NEXTAW
+    mch_msg(_("\nArguments recognised by gvim (neXtaw version):\n"));
+#   else
+    mch_msg(_("\nArguments recognised by gvim (Athena version):\n"));
+#   endif
+#  endif
+# endif
+    main_msg(_("-display <display>\tRun vim on <display>"));
+    main_msg(_("-iconic\t\tStart vim iconified"));
+# if 0
+    main_msg(_("-name <name>\t\tUse resource as if vim was <name>"));
+    mch_msg(_("\t\t\t  (Unimplemented)\n"));
+# endif
+    main_msg(_("-background <color>\tUse <color> for the background (also: -bg)"));
+    main_msg(_("-foreground <color>\tUse <color> for normal text (also: -fg)"));
+    main_msg(_("-font <font>\t\tUse <font> for normal text (also: -fn)"));
+    main_msg(_("-boldfont <font>\tUse <font> for bold text"));
+    main_msg(_("-italicfont <font>\tUse <font> for italic text"));
+    main_msg(_("-geometry <geom>\tUse <geom> for initial geometry (also: -geom)"));
+    main_msg(_("-borderwidth <width>\tUse a border width of <width> (also: -bw)"));
+    main_msg(_("-scrollbarwidth <width>  Use a scrollbar width of <width> (also: -sw)"));
+# ifdef FEAT_GUI_ATHENA
+    main_msg(_("-menuheight <height>\tUse a menu bar height of <height> (also: -mh)"));
+# endif
+    main_msg(_("-reverse\t\tUse reverse video (also: -rv)"));
+    main_msg(_("+reverse\t\tDon't use reverse video (also: +rv)"));
+    main_msg(_("-xrm <resource>\tSet the specified resource"));
+#endif /* FEAT_GUI_X11 */
+#if defined(FEAT_GUI) && defined(RISCOS)
+    mch_msg(_("\nArguments recognised by gvim (RISC OS version):\n"));
+    main_msg(_("--columns <number>\tInitial width of window in columns"));
+    main_msg(_("--rows <number>\tInitial height of window in rows"));
+#endif
+#ifdef FEAT_GUI_GTK
+    mch_msg(_("\nArguments recognised by gvim (GTK+ version):\n"));
+    main_msg(_("-font <font>\t\tUse <font> for normal text (also: -fn)"));
+    main_msg(_("-geometry <geom>\tUse <geom> for initial geometry (also: -geom)"));
+    main_msg(_("-reverse\t\tUse reverse video (also: -rv)"));
+    main_msg(_("-display <display>\tRun vim on <display> (also: --display)"));
+# ifdef HAVE_GTK2
+    main_msg(_("--role <role>\tSet a unique role to identify the main window"));
+# endif
+    main_msg(_("--socketid <xid>\tOpen Vim inside another GTK widget"));
+#endif
+#ifdef FEAT_GUI_W32
+    main_msg(_("-P <parent title>\tOpen Vim inside parent application"));
+#endif
+
+#ifdef FEAT_GUI_GNOME
+    /* Gnome gives extra messages for --help if we continue, but not for -h. */
+    if (gui.starting)
+	mch_msg("\n");
+    else
+#endif
+	mch_exit(0);
+}
+
+#if defined(HAS_SWAP_EXISTS_ACTION)
+/*
+ * Check the result of the ATTENTION dialog:
+ * When "Quit" selected, exit Vim.
+ * When "Recover" selected, recover the file.
+ */
+    static void
+check_swap_exists_action()
+{
+    if (swap_exists_action == SEA_QUIT)
+	getout(1);
+    handle_swap_exists(NULL);
+}
+#endif
+
+#if defined(STARTUPTIME) || defined(PROTO)
+static void time_diff __ARGS((struct timeval *then, struct timeval *now));
+
+static struct timeval	prev_timeval;
+
+/*
+ * Save the previous time before doing something that could nest.
+ * set "*tv_rel" to the time elapsed so far.
+ */
+    void
+time_push(tv_rel, tv_start)
+    void	*tv_rel, *tv_start;
+{
+    *((struct timeval *)tv_rel) = prev_timeval;
+    gettimeofday(&prev_timeval, NULL);
+    ((struct timeval *)tv_rel)->tv_usec = prev_timeval.tv_usec
+					- ((struct timeval *)tv_rel)->tv_usec;
+    ((struct timeval *)tv_rel)->tv_sec = prev_timeval.tv_sec
+					 - ((struct timeval *)tv_rel)->tv_sec;
+    if (((struct timeval *)tv_rel)->tv_usec < 0)
+    {
+	((struct timeval *)tv_rel)->tv_usec += 1000000;
+	--((struct timeval *)tv_rel)->tv_sec;
+    }
+    *(struct timeval *)tv_start = prev_timeval;
+}
+
+/*
+ * Compute the previous time after doing something that could nest.
+ * Subtract "*tp" from prev_timeval;
+ * Note: The arguments are (void *) to avoid trouble with systems that don't
+ * have struct timeval.
+ */
+    void
+time_pop(tp)
+    void	*tp;	/* actually (struct timeval *) */
+{
+    prev_timeval.tv_usec -= ((struct timeval *)tp)->tv_usec;
+    prev_timeval.tv_sec -= ((struct timeval *)tp)->tv_sec;
+    if (prev_timeval.tv_usec < 0)
+    {
+	prev_timeval.tv_usec += 1000000;
+	--prev_timeval.tv_sec;
+    }
+}
+
+    static void
+time_diff(then, now)
+    struct timeval	*then;
+    struct timeval	*now;
+{
+    long	usec;
+    long	msec;
+
+    usec = now->tv_usec - then->tv_usec;
+    msec = (now->tv_sec - then->tv_sec) * 1000L + usec / 1000L,
+    usec = usec % 1000L;
+    fprintf(time_fd, "%03ld.%03ld", msec, usec >= 0 ? usec : usec + 1000L);
+}
+
+    void
+time_msg(msg, tv_start)
+    char	*msg;
+    void	*tv_start;  /* only for do_source: start time; actually
+			       (struct timeval *) */
+{
+    static struct timeval	start;
+    struct timeval		now;
+
+    if (time_fd != NULL)
+    {
+	if (strstr(msg, "STARTING") != NULL)
+	{
+	    gettimeofday(&start, NULL);
+	    prev_timeval = start;
+	    fprintf(time_fd, "\n\ntimes in msec\n");
+	    fprintf(time_fd, " clock   self+sourced   self:  sourced script\n");
+	    fprintf(time_fd, " clock   elapsed:              other lines\n\n");
+	}
+	gettimeofday(&now, NULL);
+	time_diff(&start, &now);
+	if (((struct timeval *)tv_start) != NULL)
+	{
+	    fprintf(time_fd, "  ");
+	    time_diff(((struct timeval *)tv_start), &now);
+	}
+	fprintf(time_fd, "  ");
+	time_diff(&prev_timeval, &now);
+	prev_timeval = now;
+	fprintf(time_fd, ": %s\n", msg);
+    }
+}
+
+# ifdef WIN3264
+/*
+ * Windows doesn't have gettimeofday(), although it does have struct timeval.
+ */
+    int
+gettimeofday(struct timeval *tv, char *dummy)
+{
+    long t = clock();
+    tv->tv_sec = t / CLOCKS_PER_SEC;
+    tv->tv_usec = (t - tv->tv_sec * CLOCKS_PER_SEC) * 1000000 / CLOCKS_PER_SEC;
+    return 0;
+}
+# endif
+
+#endif
+
+#if defined(FEAT_CLIENTSERVER) || defined(PROTO)
+
+/*
+ * Common code for the X command server and the Win32 command server.
+ */
+
+static char_u *build_drop_cmd __ARGS((int filec, char **filev, int tabs, int sendReply));
+
+/*
+ * Do the client-server stuff, unless "--servername ''" was used.
+ */
+    static void
+exec_on_server(parmp)
+    mparm_T	*parmp;
+{
+    if (parmp->serverName_arg == NULL || *parmp->serverName_arg != NUL)
+    {
+# ifdef WIN32
+	/* Initialise the client/server messaging infrastructure. */
+	serverInitMessaging();
+# endif
+
+	/*
+	 * When a command server argument was found, execute it.  This may
+	 * exit Vim when it was successful.  Otherwise it's executed further
+	 * on.  Remember the encoding used here in "serverStrEnc".
+	 */
+	if (parmp->serverArg)
+	{
+	    cmdsrv_main(&parmp->argc, parmp->argv,
+				    parmp->serverName_arg, &parmp->serverStr);
+# ifdef FEAT_MBYTE
+	    parmp->serverStrEnc = vim_strsave(p_enc);
+# endif
+	}
+
+	/* If we're still running, get the name to register ourselves.
+	 * On Win32 can register right now, for X11 need to setup the
+	 * clipboard first, it's further down. */
+	parmp->servername = serverMakeName(parmp->serverName_arg,
+							      parmp->argv[0]);
+# ifdef WIN32
+	if (parmp->servername != NULL)
+	{
+	    serverSetName(parmp->servername);
+	    vim_free(parmp->servername);
+	}
+# endif
+    }
+}
+
+/*
+ * Prepare for running as a Vim server.
+ */
+    static void
+prepare_server(parmp)
+    mparm_T	*parmp;
+{
+# if defined(FEAT_X11)
+    /*
+     * Register for remote command execution with :serversend and --remote
+     * unless there was a -X or a --servername '' on the command line.
+     * Only register nongui-vim's with an explicit --servername argument.
+     * When running as root --servername is also required.
+     */
+    if (X_DISPLAY != NULL && parmp->servername != NULL && (
+#  ifdef FEAT_GUI
+		(gui.in_use
+#   ifdef UNIX
+		 && getuid() != ROOT_UID
+#   endif
+		) ||
+#  endif
+		parmp->serverName_arg != NULL))
+    {
+	(void)serverRegisterName(X_DISPLAY, parmp->servername);
+	vim_free(parmp->servername);
+	TIME_MSG("register server name");
+    }
+    else
+	serverDelayedStartName = parmp->servername;
+# endif
+
+    /*
+     * Execute command ourselves if we're here because the send failed (or
+     * else we would have exited above).
+     */
+    if (parmp->serverStr != NULL)
+    {
+	char_u *p;
+
+	server_to_input_buf(serverConvert(parmp->serverStrEnc,
+						       parmp->serverStr, &p));
+	vim_free(p);
+    }
+}
+
+    static void
+cmdsrv_main(argc, argv, serverName_arg, serverStr)
+    int		*argc;
+    char	**argv;
+    char_u	*serverName_arg;
+    char_u	**serverStr;
+{
+    char_u	*res;
+    int		i;
+    char_u	*sname;
+    int		ret;
+    int		didone = FALSE;
+    int		exiterr = 0;
+    char	**newArgV = argv + 1;
+    int		newArgC = 1,
+		Argc = *argc;
+    int		argtype;
+#define ARGTYPE_OTHER		0
+#define ARGTYPE_EDIT		1
+#define ARGTYPE_EDIT_WAIT	2
+#define ARGTYPE_SEND		3
+    int		silent = FALSE;
+    int		tabs = FALSE;
+# ifndef FEAT_X11
+    HWND	srv;
+# else
+    Window	srv;
+
+    setup_term_clip();
+# endif
+
+    sname = serverMakeName(serverName_arg, argv[0]);
+    if (sname == NULL)
+	return;
+
+    /*
+     * Execute the command server related arguments and remove them
+     * from the argc/argv array; We may have to return into main()
+     */
+    for (i = 1; i < Argc; i++)
+    {
+	res = NULL;
+	if (STRCMP(argv[i], "--") == 0)	/* end of option arguments */
+	{
+	    for (; i < *argc; i++)
+	    {
+		*newArgV++ = argv[i];
+		newArgC++;
+	    }
+	    break;
+	}
+
+	if (STRICMP(argv[i], "--remote-send") == 0)
+	    argtype = ARGTYPE_SEND;
+	else if (STRNICMP(argv[i], "--remote", 8) == 0)
+	{
+	    char	*p = argv[i] + 8;
+
+	    argtype = ARGTYPE_EDIT;
+	    while (*p != NUL)
+	    {
+		if (STRNICMP(p, "-wait", 5) == 0)
+		{
+		    argtype = ARGTYPE_EDIT_WAIT;
+		    p += 5;
+		}
+		else if (STRNICMP(p, "-silent", 7) == 0)
+		{
+		    silent = TRUE;
+		    p += 7;
+		}
+		else if (STRNICMP(p, "-tab", 4) == 0)
+		{
+		    tabs = TRUE;
+		    p += 4;
+		}
+		else
+		{
+		    argtype = ARGTYPE_OTHER;
+		    break;
+		}
+	    }
+	}
+	else
+	    argtype = ARGTYPE_OTHER;
+
+	if (argtype != ARGTYPE_OTHER)
+	{
+	    if (i == *argc - 1)
+		mainerr_arg_missing((char_u *)argv[i]);
+	    if (argtype == ARGTYPE_SEND)
+	    {
+		*serverStr = (char_u *)argv[i + 1];
+		i++;
+	    }
+	    else
+	    {
+		*serverStr = build_drop_cmd(*argc - i - 1, argv + i + 1,
+					  tabs, argtype == ARGTYPE_EDIT_WAIT);
+		if (*serverStr == NULL)
+		{
+		    /* Probably out of memory, exit. */
+		    didone = TRUE;
+		    exiterr = 1;
+		    break;
+		}
+		Argc = i;
+	    }
+# ifdef FEAT_X11
+	    if (xterm_dpy == NULL)
+	    {
+		mch_errmsg(_("No display"));
+		ret = -1;
+	    }
+	    else
+		ret = serverSendToVim(xterm_dpy, sname, *serverStr,
+						    NULL, &srv, 0, 0, silent);
+# else
+	    /* Win32 always works? */
+	    ret = serverSendToVim(sname, *serverStr, NULL, &srv, 0, silent);
+# endif
+	    if (ret < 0)
+	    {
+		if (argtype == ARGTYPE_SEND)
+		{
+		    /* Failed to send, abort. */
+		    mch_errmsg(_(": Send failed.\n"));
+		    didone = TRUE;
+		    exiterr = 1;
+		}
+		else if (!silent)
+		    /* Let vim start normally.  */
+		    mch_errmsg(_(": Send failed. Trying to execute locally\n"));
+		break;
+	    }
+
+# ifdef FEAT_GUI_W32
+	    /* Guess that when the server name starts with "g" it's a GUI
+	     * server, which we can bring to the foreground here.
+	     * Foreground() in the server doesn't work very well. */
+	    if (argtype != ARGTYPE_SEND && TOUPPER_ASC(*sname) == 'G')
+		SetForegroundWindow(srv);
+# endif
+
+	    /*
+	     * For --remote-wait: Wait until the server did edit each
+	     * file.  Also detect that the server no longer runs.
+	     */
+	    if (ret >= 0 && argtype == ARGTYPE_EDIT_WAIT)
+	    {
+		int	numFiles = *argc - i - 1;
+		int	j;
+		char_u  *done = alloc(numFiles);
+		char_u  *p;
+# ifdef FEAT_GUI_W32
+		NOTIFYICONDATA ni;
+		int	count = 0;
+		extern HWND message_window;
+# endif
+
+		if (numFiles > 0 && argv[i + 1][0] == '+')
+		    /* Skip "+cmd" argument, don't wait for it to be edited. */
+		    --numFiles;
+
+# ifdef FEAT_GUI_W32
+		ni.cbSize = sizeof(ni);
+		ni.hWnd = message_window;
+		ni.uID = 0;
+		ni.uFlags = NIF_ICON|NIF_TIP;
+		ni.hIcon = LoadIcon((HINSTANCE)GetModuleHandle(0), "IDR_VIM");
+		sprintf(ni.szTip, _("%d of %d edited"), count, numFiles);
+		Shell_NotifyIcon(NIM_ADD, &ni);
+# endif
+
+		/* Wait for all files to unload in remote */
+		memset(done, 0, numFiles);
+		while (memchr(done, 0, numFiles) != NULL)
+		{
+# ifdef WIN32
+		    p = serverGetReply(srv, NULL, TRUE, TRUE);
+		    if (p == NULL)
+			break;
+# else
+		    if (serverReadReply(xterm_dpy, srv, &p, TRUE) < 0)
+			break;
+# endif
+		    j = atoi((char *)p);
+		    if (j >= 0 && j < numFiles)
+		    {
+# ifdef FEAT_GUI_W32
+			++count;
+			sprintf(ni.szTip, _("%d of %d edited"),
+							     count, numFiles);
+			Shell_NotifyIcon(NIM_MODIFY, &ni);
+# endif
+			done[j] = 1;
+		    }
+		}
+# ifdef FEAT_GUI_W32
+		Shell_NotifyIcon(NIM_DELETE, &ni);
+# endif
+	    }
+	}
+	else if (STRICMP(argv[i], "--remote-expr") == 0)
+	{
+	    if (i == *argc - 1)
+		mainerr_arg_missing((char_u *)argv[i]);
+# ifdef WIN32
+	    /* Win32 always works? */
+	    if (serverSendToVim(sname, (char_u *)argv[i + 1],
+						    &res, NULL, 1, FALSE) < 0)
+# else
+	    if (xterm_dpy == NULL)
+		mch_errmsg(_("No display: Send expression failed.\n"));
+	    else if (serverSendToVim(xterm_dpy, sname, (char_u *)argv[i + 1],
+						 &res, NULL, 1, 1, FALSE) < 0)
+# endif
+	    {
+		if (res != NULL && *res != NUL)
+		{
+		    /* Output error from remote */
+		    mch_errmsg((char *)res);
+		    vim_free(res);
+		    res = NULL;
+		}
+		mch_errmsg(_(": Send expression failed.\n"));
+	    }
+	}
+	else if (STRICMP(argv[i], "--serverlist") == 0)
+	{
+# ifdef WIN32
+	    /* Win32 always works? */
+	    res = serverGetVimNames();
+# else
+	    if (xterm_dpy != NULL)
+		res = serverGetVimNames(xterm_dpy);
+# endif
+	    if (called_emsg)
+		mch_errmsg("\n");
+	}
+	else if (STRICMP(argv[i], "--servername") == 0)
+	{
+	    /* Alredy processed. Take it out of the command line */
+	    i++;
+	    continue;
+	}
+	else
+	{
+	    *newArgV++ = argv[i];
+	    newArgC++;
+	    continue;
+	}
+	didone = TRUE;
+	if (res != NULL && *res != NUL)
+	{
+	    mch_msg((char *)res);
+	    if (res[STRLEN(res) - 1] != '\n')
+		mch_msg("\n");
+	}
+	vim_free(res);
+    }
+
+    if (didone)
+    {
+	display_errors();	/* display any collected messages */
+	exit(exiterr);	/* Mission accomplished - get out */
+    }
+
+    /* Return back into main() */
+    *argc = newArgC;
+    vim_free(sname);
+}
+
+/*
+ * Build a ":drop" command to send to a Vim server.
+ */
+    static char_u *
+build_drop_cmd(filec, filev, tabs, sendReply)
+    int		filec;
+    char	**filev;
+    int		tabs;		/* Use ":tab drop" instead of ":drop". */
+    int		sendReply;
+{
+    garray_T	ga;
+    int		i;
+    char_u	*inicmd = NULL;
+    char_u	*p;
+    char_u	cwd[MAXPATHL];
+
+    if (filec > 0 && filev[0][0] == '+')
+    {
+	inicmd = (char_u *)filev[0] + 1;
+	filev++;
+	filec--;
+    }
+    /* Check if we have at least one argument. */
+    if (filec <= 0)
+	mainerr_arg_missing((char_u *)filev[-1]);
+    if (mch_dirname(cwd, MAXPATHL) != OK)
+	return NULL;
+    if ((p = vim_strsave_escaped_ext(cwd, PATH_ESC_CHARS, '\\', TRUE)) == NULL)
+	return NULL;
+    ga_init2(&ga, 1, 100);
+    ga_concat(&ga, (char_u *)"<C-\\><C-N>:cd ");
+    ga_concat(&ga, p);
+    vim_free(p);
+
+    /* Call inputsave() so that a prompt for an encryption key works. */
+    ga_concat(&ga, (char_u *)"<CR>:if exists('*inputsave')|call inputsave()|endif|");
+    if (tabs)
+	ga_concat(&ga, (char_u *)"tab ");
+    ga_concat(&ga, (char_u *)"drop");
+    for (i = 0; i < filec; i++)
+    {
+	/* On Unix the shell has already expanded the wildcards, don't want to
+	 * do it again in the Vim server.  On MS-Windows only escape
+	 * non-wildcard characters. */
+	p = vim_strsave_escaped((char_u *)filev[i],
+#ifdef UNIX
+		PATH_ESC_CHARS
+#else
+		(char_u *)" \t%#"
+#endif
+		);
+	if (p == NULL)
+	{
+	    vim_free(ga.ga_data);
+	    return NULL;
+	}
+	ga_concat(&ga, (char_u *)" ");
+	ga_concat(&ga, p);
+	vim_free(p);
+    }
+    /* The :drop commands goes to Insert mode when 'insertmode' is set, use
+     * CTRL-\ CTRL-N again. */
+    ga_concat(&ga, (char_u *)"|if exists('*inputrestore')|call inputrestore()|endif<CR>");
+    ga_concat(&ga, (char_u *)"<C-\\><C-N>:cd -");
+    if (sendReply)
+	ga_concat(&ga, (char_u *)"<CR>:call SetupRemoteReplies()");
+    ga_concat(&ga, (char_u *)"<CR>:");
+    if (inicmd != NULL)
+    {
+	/* Can't use <CR> after "inicmd", because an "startinsert" would cause
+	 * the following commands to be inserted as text.  Use a "|",
+	 * hopefully "inicmd" does allow this... */
+	ga_concat(&ga, inicmd);
+	ga_concat(&ga, (char_u *)"|");
+    }
+    /* Bring the window to the foreground, goto Insert mode when 'im' set and
+     * clear command line. */
+    ga_concat(&ga, (char_u *)"cal foreground()|if &im|star|en|redr|f<CR>");
+    ga_append(&ga, NUL);
+    return ga.ga_data;
+}
+
+/*
+ * Replace termcodes such as <CR> and insert as key presses if there is room.
+ */
+    void
+server_to_input_buf(str)
+    char_u	*str;
+{
+    char_u      *ptr = NULL;
+    char_u      *cpo_save = p_cpo;
+
+    /* Set 'cpoptions' the way we want it.
+     *    B set - backslashes are *not* treated specially
+     *    k set - keycodes are *not* reverse-engineered
+     *    < unset - <Key> sequences *are* interpreted
+     *  The last but one parameter of replace_termcodes() is TRUE so that the
+     *  <lt> sequence is recognised - needed for a real backslash.
+     */
+    p_cpo = (char_u *)"Bk";
+    str = replace_termcodes((char_u *)str, &ptr, FALSE, TRUE, FALSE);
+    p_cpo = cpo_save;
+
+    if (*ptr != NUL)	/* trailing CTRL-V results in nothing */
+    {
+	/*
+	 * Add the string to the input stream.
+	 * Can't use add_to_input_buf() here, we now have K_SPECIAL bytes.
+	 *
+	 * First clear typed characters from the typeahead buffer, there could
+	 * be half a mapping there.  Then append to the existing string, so
+	 * that multiple commands from a client are concatenated.
+	 */
+	if (typebuf.tb_maplen < typebuf.tb_len)
+	    del_typebuf(typebuf.tb_len - typebuf.tb_maplen, typebuf.tb_maplen);
+	(void)ins_typebuf(str, REMAP_NONE, typebuf.tb_len, TRUE, FALSE);
+
+	/* Let input_available() know we inserted text in the typeahead
+	 * buffer. */
+	typebuf_was_filled = TRUE;
+    }
+    vim_free((char_u *)ptr);
+}
+
+/*
+ * Evaluate an expression that the client sent to a string.
+ * Handles disabling error messages and disables debugging, otherwise Vim
+ * hangs, waiting for "cont" to be typed.
+ */
+    char_u *
+eval_client_expr_to_string(expr)
+    char_u *expr;
+{
+    char_u	*res;
+    int		save_dbl = debug_break_level;
+    int		save_ro = redir_off;
+
+    debug_break_level = -1;
+    redir_off = 0;
+    ++emsg_skip;
+
+    res = eval_to_string(expr, NULL, TRUE);
+
+    debug_break_level = save_dbl;
+    redir_off = save_ro;
+    --emsg_skip;
+
+    /* A client can tell us to redraw, but not to display the cursor, so do
+     * that here. */
+    setcursor();
+    out_flush();
+#ifdef FEAT_GUI
+    if (gui.in_use)
+	gui_update_cursor(FALSE, FALSE);
+#endif
+
+    return res;
+}
+
+/*
+ * If conversion is needed, convert "data" from "client_enc" to 'encoding' and
+ * return an allocated string.  Otherwise return "data".
+ * "*tofree" is set to the result when it needs to be freed later.
+ */
+/*ARGSUSED*/
+    char_u *
+serverConvert(client_enc, data, tofree)
+    char_u *client_enc;
+    char_u *data;
+    char_u **tofree;
+{
+    char_u	*res = data;
+
+    *tofree = NULL;
+# ifdef FEAT_MBYTE
+    if (client_enc != NULL && p_enc != NULL)
+    {
+	vimconv_T	vimconv;
+
+	vimconv.vc_type = CONV_NONE;
+	if (convert_setup(&vimconv, client_enc, p_enc) != FAIL
+					      && vimconv.vc_type != CONV_NONE)
+	{
+	    res = string_convert(&vimconv, data, NULL);
+	    if (res == NULL)
+		res = data;
+	    else
+		*tofree = res;
+	}
+	convert_setup(&vimconv, NULL, NULL);
+    }
+# endif
+    return res;
+}
+
+
+/*
+ * Make our basic server name: use the specified "arg" if given, otherwise use
+ * the tail of the command "cmd" we were started with.
+ * Return the name in allocated memory.  This doesn't include a serial number.
+ */
+    static char_u *
+serverMakeName(arg, cmd)
+    char_u	*arg;
+    char	*cmd;
+{
+    char_u *p;
+
+    if (arg != NULL && *arg != NUL)
+	p = vim_strsave_up(arg);
+    else
+    {
+	p = vim_strsave_up(gettail((char_u *)cmd));
+	/* Remove .exe or .bat from the name. */
+	if (p != NULL && vim_strchr(p, '.') != NULL)
+	    *vim_strchr(p, '.') = NUL;
+    }
+    return p;
+}
+#endif /* FEAT_CLIENTSERVER */
+
+/*
+ * When FEAT_FKMAP is defined, also compile the Farsi source code.
+ */
+#if defined(FEAT_FKMAP) || defined(PROTO)
+# include "farsi.c"
+#endif
+
+/*
+ * When FEAT_ARABIC is defined, also compile the Arabic source code.
+ */
+#if defined(FEAT_ARABIC) || defined(PROTO)
+# include "arabic.c"
+#endif
--- /dev/null
+++ b/mark.c
@@ -1,0 +1,1753 @@
+/* vi:set ts=8 sts=4 sw=4:
+ *
+ * VIM - Vi IMproved	by Bram Moolenaar
+ *
+ * Do ":help uganda"  in Vim to read copying and usage conditions.
+ * Do ":help credits" in Vim to see a list of people who contributed.
+ * See README.txt for an overview of the Vim source code.
+ */
+
+/*
+ * mark.c: functions for setting marks and jumping to them
+ */
+
+#include "vim.h"
+
+/*
+ * This file contains routines to maintain and manipulate marks.
+ */
+
+/*
+ * If a named file mark's lnum is non-zero, it is valid.
+ * If a named file mark's fnum is non-zero, it is for an existing buffer,
+ * otherwise it is from .viminfo and namedfm[n].fname is the file name.
+ * There are marks 'A - 'Z (set by user) and '0 to '9 (set when writing
+ * viminfo).
+ */
+#define EXTRA_MARKS 10					/* marks 0-9 */
+static xfmark_T namedfm[NMARKS + EXTRA_MARKS];		/* marks with file nr */
+
+static void fname2fnum __ARGS((xfmark_T *fm));
+static void fmarks_check_one __ARGS((xfmark_T *fm, char_u *name, buf_T *buf));
+static char_u *mark_line __ARGS((pos_T *mp, int lead_len));
+static void show_one_mark __ARGS((int, char_u *, pos_T *, char_u *, int current));
+#ifdef FEAT_JUMPLIST
+static void cleanup_jumplist __ARGS((void));
+#endif
+#ifdef FEAT_VIMINFO
+static void write_one_filemark __ARGS((FILE *fp, xfmark_T *fm, int c1, int c2));
+#endif
+
+/*
+ * Set named mark "c" at current cursor position.
+ * Returns OK on success, FAIL if bad name given.
+ */
+    int
+setmark(c)
+    int		c;
+{
+    return setmark_pos(c, &curwin->w_cursor, curbuf->b_fnum);
+}
+
+/*
+ * Set named mark "c" to position "pos".
+ * When "c" is upper case use file "fnum".
+ * Returns OK on success, FAIL if bad name given.
+ */
+    int
+setmark_pos(c, pos, fnum)
+    int		c;
+    pos_T	*pos;
+    int		fnum;
+{
+    int		i;
+
+    /* Check for a special key (may cause islower() to crash). */
+    if (c < 0)
+	return FAIL;
+
+    if (c == '\'' || c == '`')
+    {
+	if (pos == &curwin->w_cursor)
+	{
+	    setpcmark();
+	    /* keep it even when the cursor doesn't move */
+	    curwin->w_prev_pcmark = curwin->w_pcmark;
+	}
+	else
+	    curwin->w_pcmark = *pos;
+	return OK;
+    }
+
+    /* Allow setting '[ and '] for an autocommand that simulates reading a
+     * file. */
+    if (c == '[')
+    {
+	curbuf->b_op_start = *pos;
+	return OK;
+    }
+    if (c == ']')
+    {
+	curbuf->b_op_end = *pos;
+	return OK;
+    }
+
+#ifndef EBCDIC
+    if (c > 'z')	    /* some islower() and isupper() cannot handle
+				characters above 127 */
+	return FAIL;
+#endif
+    if (islower(c))
+    {
+	i = c - 'a';
+	curbuf->b_namedm[i] = *pos;
+	return OK;
+    }
+    if (isupper(c))
+    {
+	i = c - 'A';
+	namedfm[i].fmark.mark = *pos;
+	namedfm[i].fmark.fnum = fnum;
+	vim_free(namedfm[i].fname);
+	namedfm[i].fname = NULL;
+	return OK;
+    }
+    return FAIL;
+}
+
+/*
+ * Set the previous context mark to the current position and add it to the
+ * jump list.
+ */
+    void
+setpcmark()
+{
+#ifdef FEAT_JUMPLIST
+    int		i;
+    xfmark_T	*fm;
+#endif
+#ifdef JUMPLIST_ROTATE
+    xfmark_T	tempmark;
+#endif
+
+    /* for :global the mark is set only once */
+    if (global_busy || listcmd_busy || cmdmod.keepjumps)
+	return;
+
+    curwin->w_prev_pcmark = curwin->w_pcmark;
+    curwin->w_pcmark = curwin->w_cursor;
+
+#ifdef FEAT_JUMPLIST
+# ifdef JUMPLIST_ROTATE
+    /*
+     * If last used entry is not at the top, put it at the top by rotating
+     * the stack until it is (the newer entries will be at the bottom).
+     * Keep one entry (the last used one) at the top.
+     */
+    if (curwin->w_jumplistidx < curwin->w_jumplistlen)
+	++curwin->w_jumplistidx;
+    while (curwin->w_jumplistidx < curwin->w_jumplistlen)
+    {
+	tempmark = curwin->w_jumplist[curwin->w_jumplistlen - 1];
+	for (i = curwin->w_jumplistlen - 1; i > 0; --i)
+	    curwin->w_jumplist[i] = curwin->w_jumplist[i - 1];
+	curwin->w_jumplist[0] = tempmark;
+	++curwin->w_jumplistidx;
+    }
+# endif
+
+    /* If jumplist is full: remove oldest entry */
+    if (++curwin->w_jumplistlen > JUMPLISTSIZE)
+    {
+	curwin->w_jumplistlen = JUMPLISTSIZE;
+	vim_free(curwin->w_jumplist[0].fname);
+	for (i = 1; i < JUMPLISTSIZE; ++i)
+	    curwin->w_jumplist[i - 1] = curwin->w_jumplist[i];
+    }
+    curwin->w_jumplistidx = curwin->w_jumplistlen;
+    fm = &curwin->w_jumplist[curwin->w_jumplistlen - 1];
+
+    fm->fmark.mark = curwin->w_pcmark;
+    fm->fmark.fnum = curbuf->b_fnum;
+    fm->fname = NULL;
+#endif
+}
+
+/*
+ * To change context, call setpcmark(), then move the current position to
+ * where ever, then call checkpcmark().  This ensures that the previous
+ * context will only be changed if the cursor moved to a different line.
+ * If pcmark was deleted (with "dG") the previous mark is restored.
+ */
+    void
+checkpcmark()
+{
+    if (curwin->w_prev_pcmark.lnum != 0
+	    && (equalpos(curwin->w_pcmark, curwin->w_cursor)
+		|| curwin->w_pcmark.lnum == 0))
+    {
+	curwin->w_pcmark = curwin->w_prev_pcmark;
+	curwin->w_prev_pcmark.lnum = 0;		/* Show it has been checked */
+    }
+}
+
+#if defined(FEAT_JUMPLIST) || defined(PROTO)
+/*
+ * move "count" positions in the jump list (count may be negative)
+ */
+    pos_T *
+movemark(count)
+    int count;
+{
+    pos_T	*pos;
+    xfmark_T	*jmp;
+
+    cleanup_jumplist();
+
+    if (curwin->w_jumplistlen == 0)	    /* nothing to jump to */
+	return (pos_T *)NULL;
+
+    for (;;)
+    {
+	if (curwin->w_jumplistidx + count < 0
+		|| curwin->w_jumplistidx + count >= curwin->w_jumplistlen)
+	    return (pos_T *)NULL;
+
+	/*
+	 * if first CTRL-O or CTRL-I command after a jump, add cursor position
+	 * to list.  Careful: If there are duplicates (CTRL-O immediately after
+	 * starting Vim on a file), another entry may have been removed.
+	 */
+	if (curwin->w_jumplistidx == curwin->w_jumplistlen)
+	{
+	    setpcmark();
+	    --curwin->w_jumplistidx;	/* skip the new entry */
+	    if (curwin->w_jumplistidx + count < 0)
+		return (pos_T *)NULL;
+	}
+
+	curwin->w_jumplistidx += count;
+
+	jmp = curwin->w_jumplist + curwin->w_jumplistidx;
+	if (jmp->fmark.fnum == 0)
+	    fname2fnum(jmp);
+	if (jmp->fmark.fnum != curbuf->b_fnum)
+	{
+	    /* jump to other file */
+	    if (buflist_findnr(jmp->fmark.fnum) == NULL)
+	    {					     /* Skip this one .. */
+		count += count < 0 ? -1 : 1;
+		continue;
+	    }
+	    if (buflist_getfile(jmp->fmark.fnum, jmp->fmark.mark.lnum,
+							    0, FALSE) == FAIL)
+		return (pos_T *)NULL;
+	    /* Set lnum again, autocommands my have changed it */
+	    curwin->w_cursor = jmp->fmark.mark;
+	    pos = (pos_T *)-1;
+	}
+	else
+	    pos = &(jmp->fmark.mark);
+	return pos;
+    }
+}
+
+/*
+ * Move "count" positions in the changelist (count may be negative).
+ */
+    pos_T *
+movechangelist(count)
+    int		count;
+{
+    int		n;
+
+    if (curbuf->b_changelistlen == 0)	    /* nothing to jump to */
+	return (pos_T *)NULL;
+
+    n = curwin->w_changelistidx;
+    if (n + count < 0)
+    {
+	if (n == 0)
+	    return (pos_T *)NULL;
+	n = 0;
+    }
+    else if (n + count >= curbuf->b_changelistlen)
+    {
+	if (n == curbuf->b_changelistlen - 1)
+	    return (pos_T *)NULL;
+	n = curbuf->b_changelistlen - 1;
+    }
+    else
+	n += count;
+    curwin->w_changelistidx = n;
+    return curbuf->b_changelist + n;
+}
+#endif
+
+/*
+ * Find mark "c".
+ * If "changefile" is TRUE it's allowed to edit another file for '0, 'A, etc.
+ * If "fnum" is not NULL store the fnum there for '0, 'A etc., don't edit
+ * another file.
+ * Returns:
+ * - pointer to pos_T if found.  lnum is 0 when mark not set, -1 when mark is
+ *   in another file which can't be gotten. (caller needs to check lnum!)
+ * - NULL if there is no mark called 'c'.
+ * - -1 if mark is in other file and jumped there (only if changefile is TRUE)
+ */
+    pos_T *
+getmark(c, changefile)
+    int		c;
+    int		changefile;
+{
+    return getmark_fnum(c, changefile, NULL);
+}
+
+    pos_T *
+getmark_fnum(c, changefile, fnum)
+    int		c;
+    int		changefile;
+    int		*fnum;
+{
+    pos_T		*posp;
+#ifdef FEAT_VISUAL
+    pos_T		*startp, *endp;
+#endif
+    static pos_T	pos_copy;
+
+    posp = NULL;
+
+    /* Check for special key, can't be a mark name and might cause islower()
+     * to crash. */
+    if (c < 0)
+	return posp;
+#ifndef EBCDIC
+    if (c > '~')			/* check for islower()/isupper() */
+	;
+    else
+#endif
+	if (c == '\'' || c == '`')	/* previous context mark */
+    {
+	pos_copy = curwin->w_pcmark;	/* need to make a copy because */
+	posp = &pos_copy;		/*   w_pcmark may be changed soon */
+    }
+    else if (c == '"')			/* to pos when leaving buffer */
+	posp = &(curbuf->b_last_cursor);
+    else if (c == '^')			/* to where Insert mode stopped */
+	posp = &(curbuf->b_last_insert);
+    else if (c == '.')			/* to where last change was made */
+	posp = &(curbuf->b_last_change);
+    else if (c == '[')			/* to start of previous operator */
+	posp = &(curbuf->b_op_start);
+    else if (c == ']')			/* to end of previous operator */
+	posp = &(curbuf->b_op_end);
+    else if (c == '{' || c == '}')	/* to previous/next paragraph */
+    {
+	pos_T	pos;
+	oparg_T	oa;
+	int	slcb = listcmd_busy;
+
+	pos = curwin->w_cursor;
+	listcmd_busy = TRUE;	    /* avoid that '' is changed */
+	if (findpar(&oa.inclusive,
+			       c == '}' ? FORWARD : BACKWARD, 1L, NUL, FALSE))
+	{
+	    pos_copy = curwin->w_cursor;
+	    posp = &pos_copy;
+	}
+	curwin->w_cursor = pos;
+	listcmd_busy = slcb;
+    }
+    else if (c == '(' || c == ')')	/* to previous/next sentence */
+    {
+	pos_T	pos;
+	int	slcb = listcmd_busy;
+
+	pos = curwin->w_cursor;
+	listcmd_busy = TRUE;	    /* avoid that '' is changed */
+	if (findsent(c == ')' ? FORWARD : BACKWARD, 1L))
+	{
+	    pos_copy = curwin->w_cursor;
+	    posp = &pos_copy;
+	}
+	curwin->w_cursor = pos;
+	listcmd_busy = slcb;
+    }
+#ifdef FEAT_VISUAL
+    else if (c == '<' || c == '>')	/* start/end of visual area */
+    {
+	startp = &curbuf->b_visual.vi_start;
+	endp = &curbuf->b_visual.vi_end;
+	if ((c == '<') == lt(*startp, *endp))
+	    posp = startp;
+	else
+	    posp = endp;
+	/*
+	 * For Visual line mode, set mark at begin or end of line
+	 */
+	if (curbuf->b_visual.vi_mode == 'V')
+	{
+	    pos_copy = *posp;
+	    posp = &pos_copy;
+	    if (c == '<')
+		pos_copy.col = 0;
+	    else
+		pos_copy.col = MAXCOL;
+#ifdef FEAT_VIRTUALEDIT
+	    pos_copy.coladd = 0;
+#endif
+	}
+    }
+#endif
+    else if (ASCII_ISLOWER(c))		/* normal named mark */
+    {
+	posp = &(curbuf->b_namedm[c - 'a']);
+    }
+    else if (ASCII_ISUPPER(c) || VIM_ISDIGIT(c))	/* named file mark */
+    {
+	if (VIM_ISDIGIT(c))
+	    c = c - '0' + NMARKS;
+	else
+	    c -= 'A';
+	posp = &(namedfm[c].fmark.mark);
+
+	if (namedfm[c].fmark.fnum == 0)
+	    fname2fnum(&namedfm[c]);
+
+	if (fnum != NULL)
+	    *fnum = namedfm[c].fmark.fnum;
+	else if (namedfm[c].fmark.fnum != curbuf->b_fnum)
+	{
+	    /* mark is in another file */
+	    posp = &pos_copy;
+
+	    if (namedfm[c].fmark.mark.lnum != 0
+				       && changefile && namedfm[c].fmark.fnum)
+	    {
+		if (buflist_getfile(namedfm[c].fmark.fnum,
+				      (linenr_T)1, GETF_SETMARK, FALSE) == OK)
+		{
+		    /* Set the lnum now, autocommands could have changed it */
+		    curwin->w_cursor = namedfm[c].fmark.mark;
+		    return (pos_T *)-1;
+		}
+		pos_copy.lnum = -1;	/* can't get file */
+	    }
+	    else
+		pos_copy.lnum = 0;	/* mark exists, but is not valid in
+					   current buffer */
+	}
+    }
+
+    return posp;
+}
+
+/*
+ * Search for the next named mark in the current file.
+ *
+ * Returns pointer to pos_T of the next mark or NULL if no mark is found.
+ */
+    pos_T *
+getnextmark(startpos, dir, begin_line)
+    pos_T	*startpos;	/* where to start */
+    int		dir;	/* direction for search */
+    int		begin_line;
+{
+    int		i;
+    pos_T	*result = NULL;
+    pos_T	pos;
+
+    pos = *startpos;
+
+    /* When searching backward and leaving the cursor on the first non-blank,
+     * position must be in a previous line.
+     * When searching forward and leaving the cursor on the first non-blank,
+     * position must be in a next line. */
+    if (dir == BACKWARD && begin_line)
+	pos.col = 0;
+    else if (dir == FORWARD && begin_line)
+	pos.col = MAXCOL;
+
+    for (i = 0; i < NMARKS; i++)
+    {
+	if (curbuf->b_namedm[i].lnum > 0)
+	{
+	    if (dir == FORWARD)
+	    {
+		if ((result == NULL || lt(curbuf->b_namedm[i], *result))
+			&& lt(pos, curbuf->b_namedm[i]))
+		    result = &curbuf->b_namedm[i];
+	    }
+	    else
+	    {
+		if ((result == NULL || lt(*result, curbuf->b_namedm[i]))
+			&& lt(curbuf->b_namedm[i], pos))
+		    result = &curbuf->b_namedm[i];
+	    }
+	}
+    }
+
+    return result;
+}
+
+/*
+ * For an xtended filemark: set the fnum from the fname.
+ * This is used for marks obtained from the .viminfo file.  It's postponed
+ * until the mark is used to avoid a long startup delay.
+ */
+    static void
+fname2fnum(fm)
+    xfmark_T	*fm;
+{
+    char_u	*p;
+
+    if (fm->fname != NULL)
+    {
+	/*
+	 * First expand "~/" in the file name to the home directory.
+	 * Try to shorten the file name.
+	 */
+	expand_env(fm->fname, NameBuff, MAXPATHL);
+	mch_dirname(IObuff, IOSIZE);
+	p = shorten_fname(NameBuff, IObuff);
+
+	/* buflist_new() will call fmarks_check_names() */
+	(void)buflist_new(NameBuff, p, (linenr_T)1, 0);
+    }
+}
+
+/*
+ * Check all file marks for a name that matches the file name in buf.
+ * May replace the name with an fnum.
+ * Used for marks that come from the .viminfo file.
+ */
+    void
+fmarks_check_names(buf)
+    buf_T	*buf;
+{
+    char_u	*name;
+    int		i;
+#ifdef FEAT_JUMPLIST
+    win_T	*wp;
+#endif
+
+    if (buf->b_ffname == NULL)
+	return;
+
+    name = home_replace_save(buf, buf->b_ffname);
+    if (name == NULL)
+	return;
+
+    for (i = 0; i < NMARKS + EXTRA_MARKS; ++i)
+	fmarks_check_one(&namedfm[i], name, buf);
+
+#ifdef FEAT_JUMPLIST
+    FOR_ALL_WINDOWS(wp)
+    {
+	for (i = 0; i < wp->w_jumplistlen; ++i)
+	    fmarks_check_one(&wp->w_jumplist[i], name, buf);
+    }
+#endif
+
+    vim_free(name);
+}
+
+    static void
+fmarks_check_one(fm, name, buf)
+    xfmark_T	*fm;
+    char_u	*name;
+    buf_T	*buf;
+{
+    if (fm->fmark.fnum == 0
+	    && fm->fname != NULL
+	    && fnamecmp(name, fm->fname) == 0)
+    {
+	fm->fmark.fnum = buf->b_fnum;
+	vim_free(fm->fname);
+	fm->fname = NULL;
+    }
+}
+
+/*
+ * Check a if a position from a mark is valid.
+ * Give and error message and return FAIL if not.
+ */
+    int
+check_mark(pos)
+    pos_T    *pos;
+{
+    if (pos == NULL)
+    {
+	EMSG(_(e_umark));
+	return FAIL;
+    }
+    if (pos->lnum <= 0)
+    {
+	/* lnum is negative if mark is in another file can can't get that
+	 * file, error message already give then. */
+	if (pos->lnum == 0)
+	    EMSG(_(e_marknotset));
+	return FAIL;
+    }
+    if (pos->lnum > curbuf->b_ml.ml_line_count)
+    {
+	EMSG(_(e_markinval));
+	return FAIL;
+    }
+    return OK;
+}
+
+/*
+ * clrallmarks() - clear all marks in the buffer 'buf'
+ *
+ * Used mainly when trashing the entire buffer during ":e" type commands
+ */
+    void
+clrallmarks(buf)
+    buf_T	*buf;
+{
+    static int		i = -1;
+
+    if (i == -1)	/* first call ever: initialize */
+	for (i = 0; i < NMARKS + 1; i++)
+	{
+	    namedfm[i].fmark.mark.lnum = 0;
+	    namedfm[i].fname = NULL;
+	}
+
+    for (i = 0; i < NMARKS; i++)
+	buf->b_namedm[i].lnum = 0;
+    buf->b_op_start.lnum = 0;		/* start/end op mark cleared */
+    buf->b_op_end.lnum = 0;
+    buf->b_last_cursor.lnum = 1;	/* '" mark cleared */
+    buf->b_last_cursor.col = 0;
+#ifdef FEAT_VIRTUALEDIT
+    buf->b_last_cursor.coladd = 0;
+#endif
+    buf->b_last_insert.lnum = 0;	/* '^ mark cleared */
+    buf->b_last_change.lnum = 0;	/* '. mark cleared */
+#ifdef FEAT_JUMPLIST
+    buf->b_changelistlen = 0;
+#endif
+}
+
+/*
+ * Get name of file from a filemark.
+ * When it's in the current buffer, return the text at the mark.
+ * Returns an allocated string.
+ */
+    char_u *
+fm_getname(fmark, lead_len)
+    fmark_T	*fmark;
+    int		lead_len;
+{
+    if (fmark->fnum == curbuf->b_fnum)		    /* current buffer */
+	return mark_line(&(fmark->mark), lead_len);
+    return buflist_nr2name(fmark->fnum, FALSE, TRUE);
+}
+
+/*
+ * Return the line at mark "mp".  Truncate to fit in window.
+ * The returned string has been allocated.
+ */
+    static char_u *
+mark_line(mp, lead_len)
+    pos_T	*mp;
+    int		lead_len;
+{
+    char_u	*s, *p;
+    int		len;
+
+    if (mp->lnum == 0 || mp->lnum > curbuf->b_ml.ml_line_count)
+	return vim_strsave((char_u *)"-invalid-");
+    s = vim_strnsave(skipwhite(ml_get(mp->lnum)), (int)Columns);
+    if (s == NULL)
+	return NULL;
+    /* Truncate the line to fit it in the window */
+    len = 0;
+    for (p = s; *p != NUL; mb_ptr_adv(p))
+    {
+	len += ptr2cells(p);
+	if (len >= Columns - lead_len)
+	    break;
+    }
+    *p = NUL;
+    return s;
+}
+
+/*
+ * print the marks
+ */
+    void
+do_marks(eap)
+    exarg_T	*eap;
+{
+    char_u	*arg = eap->arg;
+    int		i;
+    char_u	*name;
+
+    if (arg != NULL && *arg == NUL)
+	arg = NULL;
+
+    show_one_mark('\'', arg, &curwin->w_pcmark, NULL, TRUE);
+    for (i = 0; i < NMARKS; ++i)
+	show_one_mark(i + 'a', arg, &curbuf->b_namedm[i], NULL, TRUE);
+    for (i = 0; i < NMARKS + EXTRA_MARKS; ++i)
+    {
+	if (namedfm[i].fmark.fnum != 0)
+	    name = fm_getname(&namedfm[i].fmark, 15);
+	else
+	    name = namedfm[i].fname;
+	if (name != NULL)
+	{
+	    show_one_mark(i >= NMARKS ? i - NMARKS + '0' : i + 'A',
+		    arg, &namedfm[i].fmark.mark, name,
+		    namedfm[i].fmark.fnum == curbuf->b_fnum);
+	    if (namedfm[i].fmark.fnum != 0)
+		vim_free(name);
+	}
+    }
+    show_one_mark('"', arg, &curbuf->b_last_cursor, NULL, TRUE);
+    show_one_mark('[', arg, &curbuf->b_op_start, NULL, TRUE);
+    show_one_mark(']', arg, &curbuf->b_op_end, NULL, TRUE);
+    show_one_mark('^', arg, &curbuf->b_last_insert, NULL, TRUE);
+    show_one_mark('.', arg, &curbuf->b_last_change, NULL, TRUE);
+#ifdef FEAT_VISUAL
+    show_one_mark('<', arg, &curbuf->b_visual.vi_start, NULL, TRUE);
+    show_one_mark('>', arg, &curbuf->b_visual.vi_end, NULL, TRUE);
+#endif
+    show_one_mark(-1, arg, NULL, NULL, FALSE);
+}
+
+    static void
+show_one_mark(c, arg, p, name, current)
+    int		c;
+    char_u	*arg;
+    pos_T	*p;
+    char_u	*name;
+    int		current;	/* in current file */
+{
+    static int	did_title = FALSE;
+    int		mustfree = FALSE;
+
+    if (c == -1)			    /* finish up */
+    {
+	if (did_title)
+	    did_title = FALSE;
+	else
+	{
+	    if (arg == NULL)
+		MSG(_("No marks set"));
+	    else
+		EMSG2(_("E283: No marks matching \"%s\""), arg);
+	}
+    }
+    /* don't output anything if 'q' typed at --more-- prompt */
+    else if (!got_int
+	    && (arg == NULL || vim_strchr(arg, c) != NULL)
+	    && p->lnum != 0)
+    {
+	if (!did_title)
+	{
+	    /* Highlight title */
+	    MSG_PUTS_TITLE(_("\nmark line  col file/text"));
+	    did_title = TRUE;
+	}
+	msg_putchar('\n');
+	if (!got_int)
+	{
+	    sprintf((char *)IObuff, " %c %6ld %4d ", c, p->lnum, p->col);
+	    msg_outtrans(IObuff);
+	    if (name == NULL && current)
+	    {
+		name = mark_line(p, 15);
+		mustfree = TRUE;
+	    }
+	    if (name != NULL)
+	    {
+		msg_outtrans_attr(name, current ? hl_attr(HLF_D) : 0);
+		if (mustfree)
+		    vim_free(name);
+	    }
+	}
+	out_flush();		    /* show one line at a time */
+    }
+}
+
+/*
+ * ":delmarks[!] [marks]"
+ */
+    void
+ex_delmarks(eap)
+    exarg_T *eap;
+{
+    char_u	*p;
+    int		from, to;
+    int		i;
+    int		lower;
+    int		digit;
+    int		n;
+
+    if (*eap->arg == NUL && eap->forceit)
+	/* clear all marks */
+	clrallmarks(curbuf);
+    else if (eap->forceit)
+	EMSG(_(e_invarg));
+    else if (*eap->arg == NUL)
+	EMSG(_(e_argreq));
+    else
+    {
+	/* clear specified marks only */
+	for (p = eap->arg; *p != NUL; ++p)
+	{
+	    lower = ASCII_ISLOWER(*p);
+	    digit = VIM_ISDIGIT(*p);
+	    if (lower || digit || ASCII_ISUPPER(*p))
+	    {
+		if (p[1] == '-')
+		{
+		    /* clear range of marks */
+		    from = *p;
+		    to = p[2];
+		    if (!(lower ? ASCII_ISLOWER(p[2])
+				: (digit ? VIM_ISDIGIT(p[2])
+				    : ASCII_ISUPPER(p[2])))
+			    || to < from)
+		    {
+			EMSG2(_(e_invarg2), p);
+			return;
+		    }
+		    p += 2;
+		}
+		else
+		    /* clear one lower case mark */
+		    from = to = *p;
+
+		for (i = from; i <= to; ++i)
+		{
+		    if (lower)
+			curbuf->b_namedm[i - 'a'].lnum = 0;
+		    else
+		    {
+			if (digit)
+			    n = i - '0' + NMARKS;
+			else
+			    n = i - 'A';
+			namedfm[n].fmark.mark.lnum = 0;
+			vim_free(namedfm[n].fname);
+			namedfm[n].fname = NULL;
+		    }
+		}
+	    }
+	    else
+		switch (*p)
+		{
+		    case '"': curbuf->b_last_cursor.lnum = 0; break;
+		    case '^': curbuf->b_last_insert.lnum = 0; break;
+		    case '.': curbuf->b_last_change.lnum = 0; break;
+		    case '[': curbuf->b_op_start.lnum    = 0; break;
+		    case ']': curbuf->b_op_end.lnum      = 0; break;
+#ifdef FEAT_VISUAL
+		    case '<': curbuf->b_visual.vi_start.lnum = 0; break;
+		    case '>': curbuf->b_visual.vi_end.lnum   = 0; break;
+#endif
+		    case ' ': break;
+		    default:  EMSG2(_(e_invarg2), p);
+			      return;
+		}
+	}
+    }
+}
+
+#if defined(FEAT_JUMPLIST) || defined(PROTO)
+/*
+ * print the jumplist
+ */
+/*ARGSUSED*/
+    void
+ex_jumps(eap)
+    exarg_T	*eap;
+{
+    int		i;
+    char_u	*name;
+
+    cleanup_jumplist();
+    /* Highlight title */
+    MSG_PUTS_TITLE(_("\n jump line  col file/text"));
+    for (i = 0; i < curwin->w_jumplistlen && !got_int; ++i)
+    {
+	if (curwin->w_jumplist[i].fmark.mark.lnum != 0)
+	{
+	    if (curwin->w_jumplist[i].fmark.fnum == 0)
+		fname2fnum(&curwin->w_jumplist[i]);
+	    name = fm_getname(&curwin->w_jumplist[i].fmark, 16);
+	    if (name == NULL)	    /* file name not available */
+		continue;
+
+	    msg_putchar('\n');
+	    if (got_int)
+		break;
+	    sprintf((char *)IObuff, "%c %2d %5ld %4d ",
+		i == curwin->w_jumplistidx ? '>' : ' ',
+		i > curwin->w_jumplistidx ? i - curwin->w_jumplistidx
+					  : curwin->w_jumplistidx - i,
+		curwin->w_jumplist[i].fmark.mark.lnum,
+		curwin->w_jumplist[i].fmark.mark.col);
+	    msg_outtrans(IObuff);
+	    msg_outtrans_attr(name,
+			    curwin->w_jumplist[i].fmark.fnum == curbuf->b_fnum
+							? hl_attr(HLF_D) : 0);
+	    vim_free(name);
+	    ui_breakcheck();
+	}
+	out_flush();
+    }
+    if (curwin->w_jumplistidx == curwin->w_jumplistlen)
+	MSG_PUTS("\n>");
+}
+
+/*
+ * print the changelist
+ */
+/*ARGSUSED*/
+    void
+ex_changes(eap)
+    exarg_T	*eap;
+{
+    int		i;
+    char_u	*name;
+
+    /* Highlight title */
+    MSG_PUTS_TITLE(_("\nchange line  col text"));
+
+    for (i = 0; i < curbuf->b_changelistlen && !got_int; ++i)
+    {
+	if (curbuf->b_changelist[i].lnum != 0)
+	{
+	    msg_putchar('\n');
+	    if (got_int)
+		break;
+	    sprintf((char *)IObuff, "%c %3d %5ld %4d ",
+		    i == curwin->w_changelistidx ? '>' : ' ',
+		    i > curwin->w_changelistidx ? i - curwin->w_changelistidx
+						: curwin->w_changelistidx - i,
+		    (long)curbuf->b_changelist[i].lnum,
+		    curbuf->b_changelist[i].col);
+	    msg_outtrans(IObuff);
+	    name = mark_line(&curbuf->b_changelist[i], 17);
+	    if (name == NULL)
+		break;
+	    msg_outtrans_attr(name, hl_attr(HLF_D));
+	    vim_free(name);
+	    ui_breakcheck();
+	}
+	out_flush();
+    }
+    if (curwin->w_changelistidx == curbuf->b_changelistlen)
+	MSG_PUTS("\n>");
+}
+#endif
+
+#define one_adjust(add) \
+    { \
+	lp = add; \
+	if (*lp >= line1 && *lp <= line2) \
+	{ \
+	    if (amount == MAXLNUM) \
+		*lp = 0; \
+	    else \
+		*lp += amount; \
+	} \
+	else if (amount_after && *lp > line2) \
+	    *lp += amount_after; \
+    }
+
+/* don't delete the line, just put at first deleted line */
+#define one_adjust_nodel(add) \
+    { \
+	lp = add; \
+	if (*lp >= line1 && *lp <= line2) \
+	{ \
+	    if (amount == MAXLNUM) \
+		*lp = line1; \
+	    else \
+		*lp += amount; \
+	} \
+	else if (amount_after && *lp > line2) \
+	    *lp += amount_after; \
+    }
+
+/*
+ * Adjust marks between line1 and line2 (inclusive) to move 'amount' lines.
+ * Must be called before changed_*(), appended_lines() or deleted_lines().
+ * May be called before or after changing the text.
+ * When deleting lines line1 to line2, use an 'amount' of MAXLNUM: The marks
+ * within this range are made invalid.
+ * If 'amount_after' is non-zero adjust marks after line2.
+ * Example: Delete lines 34 and 35: mark_adjust(34, 35, MAXLNUM, -2);
+ * Example: Insert two lines below 55: mark_adjust(56, MAXLNUM, 2, 0);
+ *				   or: mark_adjust(56, 55, MAXLNUM, 2);
+ */
+    void
+mark_adjust(line1, line2, amount, amount_after)
+    linenr_T	line1;
+    linenr_T	line2;
+    long	amount;
+    long	amount_after;
+{
+    int		i;
+    int		fnum = curbuf->b_fnum;
+    linenr_T	*lp;
+    win_T	*win;
+
+    if (line2 < line1 && amount_after == 0L)	    /* nothing to do */
+	return;
+
+    if (!cmdmod.lockmarks)
+    {
+	/* named marks, lower case and upper case */
+	for (i = 0; i < NMARKS; i++)
+	{
+	    one_adjust(&(curbuf->b_namedm[i].lnum));
+	    if (namedfm[i].fmark.fnum == fnum)
+		one_adjust_nodel(&(namedfm[i].fmark.mark.lnum));
+	}
+	for (i = NMARKS; i < NMARKS + EXTRA_MARKS; i++)
+	{
+	    if (namedfm[i].fmark.fnum == fnum)
+		one_adjust_nodel(&(namedfm[i].fmark.mark.lnum));
+	}
+
+	/* last Insert position */
+	one_adjust(&(curbuf->b_last_insert.lnum));
+
+	/* last change position */
+	one_adjust(&(curbuf->b_last_change.lnum));
+
+#ifdef FEAT_JUMPLIST
+	/* list of change positions */
+	for (i = 0; i < curbuf->b_changelistlen; ++i)
+	    one_adjust_nodel(&(curbuf->b_changelist[i].lnum));
+#endif
+
+#ifdef FEAT_VISUAL
+	/* Visual area */
+	one_adjust_nodel(&(curbuf->b_visual.vi_start.lnum));
+	one_adjust_nodel(&(curbuf->b_visual.vi_end.lnum));
+#endif
+
+#ifdef FEAT_QUICKFIX
+	/* quickfix marks */
+	qf_mark_adjust(NULL, line1, line2, amount, amount_after);
+	/* location lists */
+	FOR_ALL_WINDOWS(win)
+	    qf_mark_adjust(win, line1, line2, amount, amount_after);
+#endif
+
+#ifdef FEAT_SIGNS
+	sign_mark_adjust(line1, line2, amount, amount_after);
+#endif
+    }
+
+    /* previous context mark */
+    one_adjust(&(curwin->w_pcmark.lnum));
+
+    /* previous pcmark */
+    one_adjust(&(curwin->w_prev_pcmark.lnum));
+
+    /* saved cursor for formatting */
+    if (saved_cursor.lnum != 0)
+	one_adjust_nodel(&(saved_cursor.lnum));
+
+    /*
+     * Adjust items in all windows related to the current buffer.
+     */
+    FOR_ALL_WINDOWS(win)
+    {
+#ifdef FEAT_JUMPLIST
+	if (!cmdmod.lockmarks)
+	    /* Marks in the jumplist.  When deleting lines, this may create
+	     * duplicate marks in the jumplist, they will be removed later. */
+	    for (i = 0; i < win->w_jumplistlen; ++i)
+		if (win->w_jumplist[i].fmark.fnum == fnum)
+		    one_adjust_nodel(&(win->w_jumplist[i].fmark.mark.lnum));
+#endif
+
+	if (win->w_buffer == curbuf)
+	{
+	    if (!cmdmod.lockmarks)
+		/* marks in the tag stack */
+		for (i = 0; i < win->w_tagstacklen; i++)
+		    if (win->w_tagstack[i].fmark.fnum == fnum)
+			one_adjust_nodel(&(win->w_tagstack[i].fmark.mark.lnum));
+
+#ifdef FEAT_VISUAL
+	    /* the displayed Visual area */
+	    if (win->w_old_cursor_lnum != 0)
+	    {
+		one_adjust_nodel(&(win->w_old_cursor_lnum));
+		one_adjust_nodel(&(win->w_old_visual_lnum));
+	    }
+#endif
+
+	    /* topline and cursor position for windows with the same buffer
+	     * other than the current window */
+	    if (win != curwin)
+	    {
+		if (win->w_topline >= line1 && win->w_topline <= line2)
+		{
+		    if (amount == MAXLNUM)	    /* topline is deleted */
+		    {
+			if (line1 <= 1)
+			    win->w_topline = 1;
+			else
+			    win->w_topline = line1 - 1;
+		    }
+		    else		/* keep topline on the same line */
+			win->w_topline += amount;
+#ifdef FEAT_DIFF
+		    win->w_topfill = 0;
+#endif
+		}
+		else if (amount_after && win->w_topline > line2)
+		{
+		    win->w_topline += amount_after;
+#ifdef FEAT_DIFF
+		    win->w_topfill = 0;
+#endif
+		}
+		if (win->w_cursor.lnum >= line1 && win->w_cursor.lnum <= line2)
+		{
+		    if (amount == MAXLNUM) /* line with cursor is deleted */
+		    {
+			if (line1 <= 1)
+			    win->w_cursor.lnum = 1;
+			else
+			    win->w_cursor.lnum = line1 - 1;
+			win->w_cursor.col = 0;
+		    }
+		    else		/* keep cursor on the same line */
+			win->w_cursor.lnum += amount;
+		}
+		else if (amount_after && win->w_cursor.lnum > line2)
+		    win->w_cursor.lnum += amount_after;
+	    }
+
+#ifdef FEAT_FOLDING
+	    /* adjust folds */
+	    foldMarkAdjust(win, line1, line2, amount, amount_after);
+#endif
+	}
+    }
+
+#ifdef FEAT_DIFF
+    /* adjust diffs */
+    diff_mark_adjust(line1, line2, amount, amount_after);
+#endif
+}
+
+/* This code is used often, needs to be fast. */
+#define col_adjust(pp) \
+    { \
+	posp = pp; \
+	if (posp->lnum == lnum && posp->col >= mincol) \
+	{ \
+	    posp->lnum += lnum_amount; \
+	    if (col_amount < 0 && posp->col <= (colnr_T)-col_amount) \
+		posp->col = 0; \
+	    else \
+		posp->col += col_amount; \
+	} \
+    }
+
+/*
+ * Adjust marks in line "lnum" at column "mincol" and further: add
+ * "lnum_amount" to the line number and add "col_amount" to the column
+ * position.
+ */
+    void
+mark_col_adjust(lnum, mincol, lnum_amount, col_amount)
+    linenr_T	lnum;
+    colnr_T	mincol;
+    long	lnum_amount;
+    long	col_amount;
+{
+    int		i;
+    int		fnum = curbuf->b_fnum;
+    win_T	*win;
+    pos_T	*posp;
+
+    if ((col_amount == 0L && lnum_amount == 0L) || cmdmod.lockmarks)
+	return; /* nothing to do */
+
+    /* named marks, lower case and upper case */
+    for (i = 0; i < NMARKS; i++)
+    {
+	col_adjust(&(curbuf->b_namedm[i]));
+	if (namedfm[i].fmark.fnum == fnum)
+	    col_adjust(&(namedfm[i].fmark.mark));
+    }
+    for (i = NMARKS; i < NMARKS + EXTRA_MARKS; i++)
+    {
+	if (namedfm[i].fmark.fnum == fnum)
+	    col_adjust(&(namedfm[i].fmark.mark));
+    }
+
+    /* last Insert position */
+    col_adjust(&(curbuf->b_last_insert));
+
+    /* last change position */
+    col_adjust(&(curbuf->b_last_change));
+
+#ifdef FEAT_JUMPLIST
+    /* list of change positions */
+    for (i = 0; i < curbuf->b_changelistlen; ++i)
+	col_adjust(&(curbuf->b_changelist[i]));
+#endif
+
+#ifdef FEAT_VISUAL
+    /* Visual area */
+    col_adjust(&(curbuf->b_visual.vi_start));
+    col_adjust(&(curbuf->b_visual.vi_end));
+#endif
+
+    /* previous context mark */
+    col_adjust(&(curwin->w_pcmark));
+
+    /* previous pcmark */
+    col_adjust(&(curwin->w_prev_pcmark));
+
+    /* saved cursor for formatting */
+    col_adjust(&saved_cursor);
+
+    /*
+     * Adjust items in all windows related to the current buffer.
+     */
+    FOR_ALL_WINDOWS(win)
+    {
+#ifdef FEAT_JUMPLIST
+	/* marks in the jumplist */
+	for (i = 0; i < win->w_jumplistlen; ++i)
+	    if (win->w_jumplist[i].fmark.fnum == fnum)
+		col_adjust(&(win->w_jumplist[i].fmark.mark));
+#endif
+
+	if (win->w_buffer == curbuf)
+	{
+	    /* marks in the tag stack */
+	    for (i = 0; i < win->w_tagstacklen; i++)
+		if (win->w_tagstack[i].fmark.fnum == fnum)
+		    col_adjust(&(win->w_tagstack[i].fmark.mark));
+
+	    /* cursor position for other windows with the same buffer */
+	    if (win != curwin)
+		col_adjust(&win->w_cursor);
+	}
+    }
+}
+
+#ifdef FEAT_JUMPLIST
+/*
+ * When deleting lines, this may create duplicate marks in the
+ * jumplist. They will be removed here for the current window.
+ */
+    static void
+cleanup_jumplist()
+{
+    int	    i;
+    int	    from, to;
+
+    to = 0;
+    for (from = 0; from < curwin->w_jumplistlen; ++from)
+    {
+	if (curwin->w_jumplistidx == from)
+	    curwin->w_jumplistidx = to;
+	for (i = from + 1; i < curwin->w_jumplistlen; ++i)
+	    if (curwin->w_jumplist[i].fmark.fnum
+					== curwin->w_jumplist[from].fmark.fnum
+		    && curwin->w_jumplist[from].fmark.fnum != 0
+		    && curwin->w_jumplist[i].fmark.mark.lnum
+				  == curwin->w_jumplist[from].fmark.mark.lnum)
+		break;
+	if (i >= curwin->w_jumplistlen)	    /* no duplicate */
+	    curwin->w_jumplist[to++] = curwin->w_jumplist[from];
+	else
+	    vim_free(curwin->w_jumplist[from].fname);
+    }
+    if (curwin->w_jumplistidx == curwin->w_jumplistlen)
+	curwin->w_jumplistidx = to;
+    curwin->w_jumplistlen = to;
+}
+
+# if defined(FEAT_WINDOWS) || defined(PROTO)
+/*
+ * Copy the jumplist from window "from" to window "to".
+ */
+    void
+copy_jumplist(from, to)
+    win_T	*from;
+    win_T	*to;
+{
+    int		i;
+
+    for (i = 0; i < from->w_jumplistlen; ++i)
+    {
+	to->w_jumplist[i] = from->w_jumplist[i];
+	if (from->w_jumplist[i].fname != NULL)
+	    to->w_jumplist[i].fname = vim_strsave(from->w_jumplist[i].fname);
+    }
+    to->w_jumplistlen = from->w_jumplistlen;
+    to->w_jumplistidx = from->w_jumplistidx;
+}
+
+/*
+ * Free items in the jumplist of window "wp".
+ */
+    void
+free_jumplist(wp)
+    win_T	*wp;
+{
+    int		i;
+
+    for (i = 0; i < wp->w_jumplistlen; ++i)
+	vim_free(wp->w_jumplist[i].fname);
+}
+# endif
+#endif /* FEAT_JUMPLIST */
+
+    void
+set_last_cursor(win)
+    win_T	*win;
+{
+    win->w_buffer->b_last_cursor = win->w_cursor;
+}
+
+#if defined(EXITFREE) || defined(PROTO)
+    void
+free_all_marks()
+{
+    int		i;
+
+    for (i = 0; i < NMARKS + EXTRA_MARKS; i++)
+	if (namedfm[i].fmark.mark.lnum != 0)
+	    vim_free(namedfm[i].fname);
+}
+#endif
+
+#if defined(FEAT_VIMINFO) || defined(PROTO)
+    int
+read_viminfo_filemark(virp, force)
+    vir_T	*virp;
+    int		force;
+{
+    char_u	*str;
+    xfmark_T	*fm;
+    int		i;
+
+    /* We only get here if line[0] == '\'' or '-'.
+     * Illegal mark names are ignored (for future expansion). */
+    str = virp->vir_line + 1;
+    if (
+#ifndef EBCDIC
+	    *str <= 127 &&
+#endif
+	    ((*virp->vir_line == '\'' && (VIM_ISDIGIT(*str) || isupper(*str)))
+	     || (*virp->vir_line == '-' && *str == '\'')))
+    {
+	if (*str == '\'')
+	{
+#ifdef FEAT_JUMPLIST
+	    /* If the jumplist isn't full insert fmark as oldest entry */
+	    if (curwin->w_jumplistlen == JUMPLISTSIZE)
+		fm = NULL;
+	    else
+	    {
+		for (i = curwin->w_jumplistlen; i > 0; --i)
+		    curwin->w_jumplist[i] = curwin->w_jumplist[i - 1];
+		++curwin->w_jumplistidx;
+		++curwin->w_jumplistlen;
+		fm = &curwin->w_jumplist[0];
+		fm->fmark.mark.lnum = 0;
+		fm->fname = NULL;
+	    }
+#else
+	    fm = NULL;
+#endif
+	}
+	else if (VIM_ISDIGIT(*str))
+	    fm = &namedfm[*str - '0' + NMARKS];
+	else
+	    fm = &namedfm[*str - 'A'];
+	if (fm != NULL && (fm->fmark.mark.lnum == 0 || force))
+	{
+	    str = skipwhite(str + 1);
+	    fm->fmark.mark.lnum = getdigits(&str);
+	    str = skipwhite(str);
+	    fm->fmark.mark.col = getdigits(&str);
+#ifdef FEAT_VIRTUALEDIT
+	    fm->fmark.mark.coladd = 0;
+#endif
+	    fm->fmark.fnum = 0;
+	    str = skipwhite(str);
+	    vim_free(fm->fname);
+	    fm->fname = viminfo_readstring(virp, (int)(str - virp->vir_line),
+								       FALSE);
+	}
+    }
+    return vim_fgets(virp->vir_line, LSIZE, virp->vir_fd);
+}
+
+    void
+write_viminfo_filemarks(fp)
+    FILE	*fp;
+{
+    int		i;
+    char_u	*name;
+    buf_T	*buf;
+    xfmark_T	*fm;
+
+    if (get_viminfo_parameter('f') == 0)
+	return;
+
+    fprintf(fp, _("\n# File marks:\n"));
+
+    /*
+     * Find a mark that is the same file and position as the cursor.
+     * That one, or else the last one is deleted.
+     * Move '0 to '1, '1 to '2, etc. until the matching one or '9
+     * Set '0 mark to current cursor position.
+     */
+    if (curbuf->b_ffname != NULL && !removable(curbuf->b_ffname))
+    {
+	name = buflist_nr2name(curbuf->b_fnum, TRUE, FALSE);
+	for (i = NMARKS; i < NMARKS + EXTRA_MARKS - 1; ++i)
+	    if (namedfm[i].fmark.mark.lnum == curwin->w_cursor.lnum
+		    && (namedfm[i].fname == NULL
+			    ? namedfm[i].fmark.fnum == curbuf->b_fnum
+			    : (name != NULL
+				    && STRCMP(name, namedfm[i].fname) == 0)))
+		break;
+	vim_free(name);
+
+	vim_free(namedfm[i].fname);
+	for ( ; i > NMARKS; --i)
+	    namedfm[i] = namedfm[i - 1];
+	namedfm[NMARKS].fmark.mark = curwin->w_cursor;
+	namedfm[NMARKS].fmark.fnum = curbuf->b_fnum;
+	namedfm[NMARKS].fname = NULL;
+    }
+
+    /* Write the filemarks '0 - '9 and 'A - 'Z */
+    for (i = 0; i < NMARKS + EXTRA_MARKS; i++)
+	write_one_filemark(fp, &namedfm[i], '\'',
+				     i < NMARKS ? i + 'A' : i - NMARKS + '0');
+
+#ifdef FEAT_JUMPLIST
+    /* Write the jumplist with -' */
+    fprintf(fp, _("\n# Jumplist (newest first):\n"));
+    setpcmark();	/* add current cursor position */
+    cleanup_jumplist();
+    for (fm = &curwin->w_jumplist[curwin->w_jumplistlen - 1];
+					   fm >= &curwin->w_jumplist[0]; --fm)
+    {
+	if (fm->fmark.fnum == 0
+		|| ((buf = buflist_findnr(fm->fmark.fnum)) != NULL
+		    && !removable(buf->b_ffname)))
+	    write_one_filemark(fp, fm, '-', '\'');
+    }
+#endif
+}
+
+    static void
+write_one_filemark(fp, fm, c1, c2)
+    FILE	*fp;
+    xfmark_T	*fm;
+    int		c1;
+    int		c2;
+{
+    char_u	*name;
+
+    if (fm->fmark.mark.lnum == 0)	/* not set */
+	return;
+
+    if (fm->fmark.fnum != 0)		/* there is a buffer */
+	name = buflist_nr2name(fm->fmark.fnum, TRUE, FALSE);
+    else
+	name = fm->fname;		/* use name from .viminfo */
+    if (name != NULL && *name != NUL)
+    {
+	fprintf(fp, "%c%c  %ld  %ld  ", c1, c2, (long)fm->fmark.mark.lnum,
+						    (long)fm->fmark.mark.col);
+	viminfo_writestring(fp, name);
+    }
+
+    if (fm->fmark.fnum != 0)
+	vim_free(name);
+}
+
+/*
+ * Return TRUE if "name" is on removable media (depending on 'viminfo').
+ */
+    int
+removable(name)
+    char_u  *name;
+{
+    char_u  *p;
+    char_u  part[51];
+    int	    retval = FALSE;
+    size_t  n;
+
+    name = home_replace_save(NULL, name);
+    if (name != NULL)
+    {
+	for (p = p_viminfo; *p; )
+	{
+	    copy_option_part(&p, part, 51, ", ");
+	    if (part[0] == 'r')
+	    {
+		n = STRLEN(part + 1);
+		if (MB_STRNICMP(part + 1, name, n) == 0)
+		{
+		    retval = TRUE;
+		    break;
+		}
+	    }
+	}
+	vim_free(name);
+    }
+    return retval;
+}
+
+static void write_one_mark __ARGS((FILE *fp_out, int c, pos_T *pos));
+
+/*
+ * Write all the named marks for all buffers.
+ * Return the number of buffers for which marks have been written.
+ */
+    int
+write_viminfo_marks(fp_out)
+    FILE	*fp_out;
+{
+    int		count;
+    buf_T	*buf;
+    int		is_mark_set;
+    int		i;
+#ifdef FEAT_WINDOWS
+    win_T	*win;
+    tabpage_T	*tp;
+
+    /*
+     * Set b_last_cursor for the all buffers that have a window.
+     */
+    FOR_ALL_TAB_WINDOWS(tp, win)
+	set_last_cursor(win);
+#else
+	set_last_cursor(curwin);
+#endif
+
+    fprintf(fp_out, _("\n# History of marks within files (newest to oldest):\n"));
+    count = 0;
+    for (buf = firstbuf; buf != NULL; buf = buf->b_next)
+    {
+	/*
+	 * Only write something if buffer has been loaded and at least one
+	 * mark is set.
+	 */
+	if (buf->b_marks_read)
+	{
+	    if (buf->b_last_cursor.lnum != 0)
+		is_mark_set = TRUE;
+	    else
+	    {
+		is_mark_set = FALSE;
+		for (i = 0; i < NMARKS; i++)
+		    if (buf->b_namedm[i].lnum != 0)
+		    {
+			is_mark_set = TRUE;
+			break;
+		    }
+	    }
+	    if (is_mark_set && buf->b_ffname != NULL
+		      && buf->b_ffname[0] != NUL && !removable(buf->b_ffname))
+	    {
+		home_replace(NULL, buf->b_ffname, IObuff, IOSIZE, TRUE);
+		fprintf(fp_out, "\n> ");
+		viminfo_writestring(fp_out, IObuff);
+		write_one_mark(fp_out, '"', &buf->b_last_cursor);
+		write_one_mark(fp_out, '^', &buf->b_last_insert);
+		write_one_mark(fp_out, '.', &buf->b_last_change);
+#ifdef FEAT_JUMPLIST
+		/* changelist positions are stored oldest first */
+		for (i = 0; i < buf->b_changelistlen; ++i)
+		    write_one_mark(fp_out, '+', &buf->b_changelist[i]);
+#endif
+		for (i = 0; i < NMARKS; i++)
+		    write_one_mark(fp_out, 'a' + i, &buf->b_namedm[i]);
+		count++;
+	    }
+	}
+    }
+
+    return count;
+}
+
+    static void
+write_one_mark(fp_out, c, pos)
+    FILE	*fp_out;
+    int		c;
+    pos_T	*pos;
+{
+    if (pos->lnum != 0)
+	fprintf(fp_out, "\t%c\t%ld\t%d\n", c, (long)pos->lnum, (int)pos->col);
+}
+
+/*
+ * Handle marks in the viminfo file:
+ * fp_out == NULL   read marks for current buffer only
+ * fp_out != NULL   copy marks for buffers not in buffer list
+ */
+    void
+copy_viminfo_marks(virp, fp_out, count, eof)
+    vir_T	*virp;
+    FILE	*fp_out;
+    int		count;
+    int		eof;
+{
+    char_u	*line = virp->vir_line;
+    buf_T	*buf;
+    int		num_marked_files;
+    int		load_marks;
+    int		copy_marks_out;
+    char_u	*str;
+    int		i;
+    char_u	*p;
+    char_u	*name_buf;
+    pos_T	pos;
+
+    if ((name_buf = alloc(LSIZE)) == NULL)
+	return;
+    *name_buf = NUL;
+    num_marked_files = get_viminfo_parameter('\'');
+    while (!eof && (count < num_marked_files || fp_out == NULL))
+    {
+	if (line[0] != '>')
+	{
+	    if (line[0] != '\n' && line[0] != '\r' && line[0] != '#')
+	    {
+		if (viminfo_error("E576: ", _("Missing '>'"), line))
+		    break;	/* too many errors, return now */
+	    }
+	    eof = vim_fgets(line, LSIZE, virp->vir_fd);
+	    continue;		/* Skip this dud line */
+	}
+
+	/*
+	 * Handle long line and translate escaped characters.
+	 * Find file name, set str to start.
+	 * Ignore leading and trailing white space.
+	 */
+	str = skipwhite(line + 1);
+	str = viminfo_readstring(virp, (int)(str - virp->vir_line), FALSE);
+	if (str == NULL)
+	    continue;
+	p = str + STRLEN(str);
+	while (p != str && (*p == NUL || vim_isspace(*p)))
+	    p--;
+	if (*p)
+	    p++;
+	*p = NUL;
+
+	/*
+	 * If fp_out == NULL, load marks for current buffer.
+	 * If fp_out != NULL, copy marks for buffers not in buflist.
+	 */
+	load_marks = copy_marks_out = FALSE;
+	if (fp_out == NULL)
+	{
+	    if (curbuf->b_ffname != NULL)
+	    {
+		if (*name_buf == NUL)	    /* only need to do this once */
+		    home_replace(NULL, curbuf->b_ffname, name_buf, LSIZE, TRUE);
+		if (fnamecmp(str, name_buf) == 0)
+		    load_marks = TRUE;
+	    }
+	}
+	else /* fp_out != NULL */
+	{
+	    /* This is slow if there are many buffers!! */
+	    for (buf = firstbuf; buf != NULL; buf = buf->b_next)
+		if (buf->b_ffname != NULL)
+		{
+		    home_replace(NULL, buf->b_ffname, name_buf, LSIZE, TRUE);
+		    if (fnamecmp(str, name_buf) == 0)
+			break;
+		}
+
+	    /*
+	     * copy marks if the buffer has not been loaded
+	     */
+	    if (buf == NULL || !buf->b_marks_read)
+	    {
+		copy_marks_out = TRUE;
+		fputs("\n> ", fp_out);
+		viminfo_writestring(fp_out, str);
+		count++;
+	    }
+	}
+	vim_free(str);
+
+#ifdef FEAT_VIRTUALEDIT
+	pos.coladd = 0;
+#endif
+	while (!(eof = viminfo_readline(virp)) && line[0] == TAB)
+	{
+	    if (load_marks)
+	    {
+		if (line[1] != NUL)
+		{
+		    sscanf((char *)line + 2, "%ld %u", &pos.lnum, &pos.col);
+		    switch (line[1])
+		    {
+			case '"': curbuf->b_last_cursor = pos; break;
+			case '^': curbuf->b_last_insert = pos; break;
+			case '.': curbuf->b_last_change = pos; break;
+			case '+':
+#ifdef FEAT_JUMPLIST
+				  /* changelist positions are stored oldest
+				   * first */
+				  if (curbuf->b_changelistlen == JUMPLISTSIZE)
+				      /* list is full, remove oldest entry */
+				      mch_memmove(curbuf->b_changelist,
+					    curbuf->b_changelist + 1,
+					    sizeof(pos_T) * (JUMPLISTSIZE - 1));
+				  else
+				      ++curbuf->b_changelistlen;
+				  curbuf->b_changelist[
+					   curbuf->b_changelistlen - 1] = pos;
+#endif
+				  break;
+			default:  if ((i = line[1] - 'a') >= 0 && i < NMARKS)
+				      curbuf->b_namedm[i] = pos;
+		    }
+		}
+	    }
+	    else if (copy_marks_out)
+		fputs((char *)line, fp_out);
+	}
+	if (load_marks)
+	{
+#ifdef FEAT_JUMPLIST
+	    win_T	*wp;
+
+	    FOR_ALL_WINDOWS(wp)
+	    {
+		if (wp->w_buffer == curbuf)
+		    wp->w_changelistidx = curbuf->b_changelistlen;
+	    }
+#endif
+	    break;
+	}
+    }
+    vim_free(name_buf);
+}
+#endif /* FEAT_VIMINFO */
--- /dev/null
+++ b/mbyte.c
@@ -1,0 +1,6106 @@
+/* vi:set ts=8 sts=4 sw=4:
+ *
+ * VIM - Vi IMproved	by Bram Moolenaar
+ * Multibyte extensions partly by Sung-Hoon Baek
+ *
+ * Do ":help uganda"  in Vim to read copying and usage conditions.
+ * Do ":help credits" in Vim to see a list of people who contributed.
+ * See README.txt for an overview of the Vim source code.
+ */
+/*
+ * mbyte.c: Code specifically for handling multi-byte characters.
+ *
+ * The encoding used in the core is set with 'encoding'.  When 'encoding' is
+ * changed, the following four variables are set (for speed).
+ * Currently these types of character encodings are supported:
+ *
+ * "enc_dbcs"	    When non-zero it tells the type of double byte character
+ *		    encoding (Chinese, Korean, Japanese, etc.).
+ *		    The cell width on the display is equal to the number of
+ *		    bytes.  (exception: DBCS_JPNU with first byte 0x8e)
+ *		    Recognizing the first or second byte is difficult, it
+ *		    requires checking a byte sequence from the start.
+ * "enc_utf8"	    When TRUE use Unicode characters in UTF-8 encoding.
+ *		    The cell width on the display needs to be determined from
+ *		    the character value.
+ *		    Recognizing bytes is easy: 0xxx.xxxx is a single-byte
+ *		    char, 10xx.xxxx is a trailing byte, 11xx.xxxx is a leading
+ *		    byte of a multi-byte character.
+ *		    To make things complicated, up to two composing characters
+ *		    are allowed.  These are drawn on top of the first char.
+ *		    For most editing the sequence of bytes with composing
+ *		    characters included is considered to be one character.
+ * "enc_unicode"    When 2 use 16-bit Unicode characters (or UTF-16).
+ *		    When 4 use 32-but Unicode characters.
+ *		    Internally characters are stored in UTF-8 encoding to
+ *		    avoid NUL bytes.  Conversion happens when doing I/O.
+ *		    "enc_utf8" will also be TRUE.
+ *
+ * "has_mbyte" is set when "enc_dbcs" or "enc_utf8" is non-zero.
+ *
+ * If none of these is TRUE, 8-bit bytes are used for a character.  The
+ * encoding isn't currently specified (TODO).
+ *
+ * 'encoding' specifies the encoding used in the core.  This is in registers,
+ * text manipulation, buffers, etc.  Conversion has to be done when characters
+ * in another encoding are received or send:
+ *
+ *		       clipboard
+ *			   ^
+ *			   | (2)
+ *			   V
+ *		   +---------------+
+ *	      (1)  |		   | (3)
+ *  keyboard ----->|	 core	   |-----> display
+ *		   |		   |
+ *		   +---------------+
+ *			   ^
+ *			   | (4)
+ *			   V
+ *			 file
+ *
+ * (1) Typed characters arrive in the current locale.  Conversion is to be
+ *     done when 'encoding' is different from 'termencoding'.
+ * (2) Text will be made available with the encoding specified with
+ *     'encoding'.  If this is not sufficient, system-specific conversion
+ *     might be required.
+ * (3) For the GUI the correct font must be selected, no conversion done.
+ *     Otherwise, conversion is to be done when 'encoding' differs from
+ *     'termencoding'.  (Different in the GTK+ 2 port -- 'termencoding'
+ *     is always used for both input and output and must always be set to
+ *     "utf-8".  gui_mch_init() does this automatically.)
+ * (4) The encoding of the file is specified with 'fileencoding'.  Conversion
+ *     is to be done when it's different from 'encoding'.
+ *
+ * The viminfo file is a special case: Only text is converted, not file names.
+ * Vim scripts may contain an ":encoding" command.  This has an effect for
+ * some commands, like ":menutrans"
+ */
+
+#include "vim.h"
+
+#ifdef WIN32UNIX
+# ifndef WIN32_LEAN_AND_MEAN
+#  define WIN32_LEAN_AND_MEAN
+# endif
+# include <windows.h>
+# ifdef WIN32
+#  undef WIN32	    /* Some windows.h define WIN32, we don't want that here. */
+# endif
+#endif
+
+#if (defined(WIN3264) || defined(WIN32UNIX)) && !defined(__MINGW32__)
+# include <winnls.h>
+#endif
+
+#ifdef FEAT_GUI_X11
+# include <X11/Intrinsic.h>
+#endif
+#ifdef X_LOCALE
+#include <X11/Xlocale.h>
+#endif
+
+#if defined(FEAT_GUI_GTK) && defined(FEAT_XIM) && defined(HAVE_GTK2)
+# include <gdk/gdkkeysyms.h>
+# ifdef WIN3264
+#  include <gdk/gdkwin32.h>
+# else
+#  include <gdk/gdkx.h>
+# endif
+#endif
+
+#ifdef HAVE_WCHAR_H
+# include <wchar.h>
+#endif
+
+#if 0
+/* This has been disabled, because several people reported problems with the
+ * wcwidth() and iswprint() library functions, esp. for Hebrew. */
+# ifdef __STDC_ISO_10646__
+#  define USE_WCHAR_FUNCTIONS
+# endif
+#endif
+
+#if defined(FEAT_MBYTE) || defined(PROTO)
+
+static int enc_canon_search __ARGS((char_u *name));
+static int dbcs_char2len __ARGS((int c));
+static int dbcs_char2bytes __ARGS((int c, char_u *buf));
+static int dbcs_ptr2len __ARGS((char_u *p));
+static int dbcs_char2cells __ARGS((int c));
+static int dbcs_ptr2char __ARGS((char_u *p));
+
+/* Lookup table to quickly get the length in bytes of a UTF-8 character from
+ * the first byte of a UTF-8 string.  Bytes which are illegal when used as the
+ * first byte have a one, because these will be used separately. */
+static char utf8len_tab[256] =
+{
+    1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+    1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+    1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+    1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+    1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /*bogus*/
+    1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /*bogus*/
+    2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
+    3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,5,5,5,5,6,6,1,1,
+};
+
+/*
+ * XIM often causes trouble.  Define XIM_DEBUG to get a log of XIM callbacks
+ * in the "xim.log" file.
+ */
+/* #define XIM_DEBUG */
+#ifdef XIM_DEBUG
+    static void
+xim_log(char *s, ...)
+{
+    va_list arglist;
+    static FILE *fd = NULL;
+
+    if (fd == (FILE *)-1)
+	return;
+    if (fd == NULL)
+    {
+	fd = mch_fopen("xim.log", "w");
+	if (fd == NULL)
+	{
+	    EMSG("Cannot open xim.log");
+	    fd = (FILE *)-1;
+	    return;
+	}
+    }
+
+    va_start(arglist, s);
+    vfprintf(fd, s, arglist);
+    va_end(arglist);
+}
+#endif
+
+#endif
+
+#if defined(FEAT_MBYTE) || defined(FEAT_POSTSCRIPT) || defined(PROTO)
+/*
+ * Canonical encoding names and their properties.
+ * "iso-8859-n" is handled by enc_canonize() directly.
+ */
+static struct
+{   char *name;		int prop;		int codepage;}
+enc_canon_table[] =
+{
+#define IDX_LATIN_1	0
+    {"latin1",		ENC_8BIT + ENC_LATIN1,	1252},
+#define IDX_ISO_2	1
+    {"iso-8859-2",	ENC_8BIT,		0},
+#define IDX_ISO_3	2
+    {"iso-8859-3",	ENC_8BIT,		0},
+#define IDX_ISO_4	3
+    {"iso-8859-4",	ENC_8BIT,		0},
+#define IDX_ISO_5	4
+    {"iso-8859-5",	ENC_8BIT,		0},
+#define IDX_ISO_6	5
+    {"iso-8859-6",	ENC_8BIT,		0},
+#define IDX_ISO_7	6
+    {"iso-8859-7",	ENC_8BIT,		0},
+#define IDX_ISO_8	7
+    {"iso-8859-8",	ENC_8BIT,		0},
+#define IDX_ISO_9	8
+    {"iso-8859-9",	ENC_8BIT,		0},
+#define IDX_ISO_10	9
+    {"iso-8859-10",	ENC_8BIT,		0},
+#define IDX_ISO_11	10
+    {"iso-8859-11",	ENC_8BIT,		0},
+#define IDX_ISO_13	11
+    {"iso-8859-13",	ENC_8BIT,		0},
+#define IDX_ISO_14	12
+    {"iso-8859-14",	ENC_8BIT,		0},
+#define IDX_ISO_15	13
+    {"iso-8859-15",	ENC_8BIT + ENC_LATIN9,	0},
+#define IDX_KOI8_R	14
+    {"koi8-r",		ENC_8BIT,		0},
+#define IDX_KOI8_U	15
+    {"koi8-u",		ENC_8BIT,		0},
+#define IDX_UTF8	16
+    {"utf-8",		ENC_UNICODE,		0},
+#define IDX_UCS2	17
+    {"ucs-2",		ENC_UNICODE + ENC_ENDIAN_B + ENC_2BYTE, 0},
+#define IDX_UCS2LE	18
+    {"ucs-2le",		ENC_UNICODE + ENC_ENDIAN_L + ENC_2BYTE, 0},
+#define IDX_UTF16	19
+    {"utf-16",		ENC_UNICODE + ENC_ENDIAN_B + ENC_2WORD, 0},
+#define IDX_UTF16LE	20
+    {"utf-16le",	ENC_UNICODE + ENC_ENDIAN_L + ENC_2WORD, 0},
+#define IDX_UCS4	21
+    {"ucs-4",		ENC_UNICODE + ENC_ENDIAN_B + ENC_4BYTE, 0},
+#define IDX_UCS4LE	22
+    {"ucs-4le",		ENC_UNICODE + ENC_ENDIAN_L + ENC_4BYTE, 0},
+
+    /* For debugging DBCS encoding on Unix. */
+#define IDX_DEBUG	23
+    {"debug",		ENC_DBCS,		DBCS_DEBUG},
+#define IDX_EUC_JP	24
+    {"euc-jp",		ENC_DBCS,		DBCS_JPNU},
+#define IDX_SJIS	25
+    {"sjis",		ENC_DBCS,		DBCS_JPN},
+#define IDX_EUC_KR	26
+    {"euc-kr",		ENC_DBCS,		DBCS_KORU},
+#define IDX_EUC_CN	27
+    {"euc-cn",		ENC_DBCS,		DBCS_CHSU},
+#define IDX_EUC_TW	28
+    {"euc-tw",		ENC_DBCS,		DBCS_CHTU},
+#define IDX_BIG5	29
+    {"big5",		ENC_DBCS,		DBCS_CHT},
+
+    /* MS-DOS and MS-Windows codepages are included here, so that they can be
+     * used on Unix too.  Most of them are similar to ISO-8859 encodings, but
+     * not exactly the same. */
+#define IDX_CP437	30
+    {"cp437",		ENC_8BIT,		437}, /* like iso-8859-1 */
+#define IDX_CP737	31
+    {"cp737",		ENC_8BIT,		737}, /* like iso-8859-7 */
+#define IDX_CP775	32
+    {"cp775",		ENC_8BIT,		775}, /* Baltic */
+#define IDX_CP850	33
+    {"cp850",		ENC_8BIT,		850}, /* like iso-8859-4 */
+#define IDX_CP852	34
+    {"cp852",		ENC_8BIT,		852}, /* like iso-8859-1 */
+#define IDX_CP855	35
+    {"cp855",		ENC_8BIT,		855}, /* like iso-8859-2 */
+#define IDX_CP857	36
+    {"cp857",		ENC_8BIT,		857}, /* like iso-8859-5 */
+#define IDX_CP860	37
+    {"cp860",		ENC_8BIT,		860}, /* like iso-8859-9 */
+#define IDX_CP861	38
+    {"cp861",		ENC_8BIT,		861}, /* like iso-8859-1 */
+#define IDX_CP862	39
+    {"cp862",		ENC_8BIT,		862}, /* like iso-8859-1 */
+#define IDX_CP863	40
+    {"cp863",		ENC_8BIT,		863}, /* like iso-8859-8 */
+#define IDX_CP865	41
+    {"cp865",		ENC_8BIT,		865}, /* like iso-8859-1 */
+#define IDX_CP866	42
+    {"cp866",		ENC_8BIT,		866}, /* like iso-8859-5 */
+#define IDX_CP869	43
+    {"cp869",		ENC_8BIT,		869}, /* like iso-8859-7 */
+#define IDX_CP874	44
+    {"cp874",		ENC_8BIT,		874}, /* Thai */
+#define IDX_CP932	45
+    {"cp932",		ENC_DBCS,		DBCS_JPN},
+#define IDX_CP936	46
+    {"cp936",		ENC_DBCS,		DBCS_CHS},
+#define IDX_CP949	47
+    {"cp949",		ENC_DBCS,		DBCS_KOR},
+#define IDX_CP950	48
+    {"cp950",		ENC_DBCS,		DBCS_CHT},
+#define IDX_CP1250	49
+    {"cp1250",		ENC_8BIT,		1250}, /* Czech, Polish, etc. */
+#define IDX_CP1251	50
+    {"cp1251",		ENC_8BIT,		1251}, /* Cyrillic */
+    /* cp1252 is considered to be equal to latin1 */
+#define IDX_CP1253	51
+    {"cp1253",		ENC_8BIT,		1253}, /* Greek */
+#define IDX_CP1254	52
+    {"cp1254",		ENC_8BIT,		1254}, /* Turkish */
+#define IDX_CP1255	53
+    {"cp1255",		ENC_8BIT,		1255}, /* Hebrew */
+#define IDX_CP1256	54
+    {"cp1256",		ENC_8BIT,		1256}, /* Arabic */
+#define IDX_CP1257	55
+    {"cp1257",		ENC_8BIT,		1257}, /* Baltic */
+#define IDX_CP1258	56
+    {"cp1258",		ENC_8BIT,		1258}, /* Vietnamese */
+
+#define IDX_MACROMAN	57
+    {"macroman",	ENC_8BIT + ENC_MACROMAN, 0},	/* Mac OS */
+#define IDX_DECMCS	58
+    {"dec-mcs",		ENC_8BIT,		0},	/* DEC MCS */
+#define IDX_HPROMAN8	59
+    {"hp-roman8",	ENC_8BIT,		0},	/* HP Roman8 */
+#define IDX_COUNT	60
+};
+
+/*
+ * Aliases for encoding names.
+ */
+static struct
+{   char *name;		int canon;}
+enc_alias_table[] =
+{
+    {"ansi",		IDX_LATIN_1},
+    {"iso-8859-1",	IDX_LATIN_1},
+    {"latin2",		IDX_ISO_2},
+    {"latin3",		IDX_ISO_3},
+    {"latin4",		IDX_ISO_4},
+    {"cyrillic",	IDX_ISO_5},
+    {"arabic",		IDX_ISO_6},
+    {"greek",		IDX_ISO_7},
+#ifdef WIN3264
+    {"hebrew",		IDX_CP1255},
+#else
+    {"hebrew",		IDX_ISO_8},
+#endif
+    {"latin5",		IDX_ISO_9},
+    {"turkish",		IDX_ISO_9}, /* ? */
+    {"latin6",		IDX_ISO_10},
+    {"nordic",		IDX_ISO_10}, /* ? */
+    {"thai",		IDX_ISO_11}, /* ? */
+    {"latin7",		IDX_ISO_13},
+    {"latin8",		IDX_ISO_14},
+    {"latin9",		IDX_ISO_15},
+    {"utf8",		IDX_UTF8},
+    {"unicode",		IDX_UCS2},
+    {"ucs2",		IDX_UCS2},
+    {"ucs2be",		IDX_UCS2},
+    {"ucs-2be",		IDX_UCS2},
+    {"ucs2le",		IDX_UCS2LE},
+    {"utf16",		IDX_UTF16},
+    {"utf16be",		IDX_UTF16},
+    {"utf-16be",	IDX_UTF16},
+    {"utf16le",		IDX_UTF16LE},
+    {"ucs4",		IDX_UCS4},
+    {"ucs4be",		IDX_UCS4},
+    {"ucs-4be",		IDX_UCS4},
+    {"ucs4le",		IDX_UCS4LE},
+    {"932",		IDX_CP932},
+    {"949",		IDX_CP949},
+    {"936",		IDX_CP936},
+    {"gbk",		IDX_CP936},
+    {"950",		IDX_CP950},
+    {"eucjp",		IDX_EUC_JP},
+    {"unix-jis",	IDX_EUC_JP},
+    {"ujis",		IDX_EUC_JP},
+    {"shift-jis",	IDX_SJIS},
+    {"euckr",		IDX_EUC_KR},
+    {"5601",		IDX_EUC_KR},	/* Sun: KS C 5601 */
+    {"euccn",		IDX_EUC_CN},
+    {"gb2312",		IDX_EUC_CN},
+    {"euctw",		IDX_EUC_TW},
+#if defined(WIN3264) || defined(WIN32UNIX) || defined(MACOS)
+    {"japan",		IDX_CP932},
+    {"korea",		IDX_CP949},
+    {"prc",		IDX_CP936},
+    {"chinese",		IDX_CP936},
+    {"taiwan",		IDX_CP950},
+    {"big5",		IDX_CP950},
+#else
+    {"japan",		IDX_EUC_JP},
+    {"korea",		IDX_EUC_KR},
+    {"prc",		IDX_EUC_CN},
+    {"chinese",		IDX_EUC_CN},
+    {"taiwan",		IDX_EUC_TW},
+    {"cp950",		IDX_BIG5},
+    {"950",		IDX_BIG5},
+#endif
+    {"mac",		IDX_MACROMAN},
+    {"mac-roman",	IDX_MACROMAN},
+    {NULL,		0}
+};
+
+#ifndef CP_UTF8
+# define CP_UTF8 65001	/* magic number from winnls.h */
+#endif
+
+/*
+ * Find encoding "name" in the list of canonical encoding names.
+ * Returns -1 if not found.
+ */
+    static int
+enc_canon_search(name)
+    char_u	*name;
+{
+    int		i;
+
+    for (i = 0; i < IDX_COUNT; ++i)
+	if (STRCMP(name, enc_canon_table[i].name) == 0)
+	    return i;
+    return -1;
+}
+
+#endif
+
+#if defined(FEAT_MBYTE) || defined(PROTO)
+
+/*
+ * Find canonical encoding "name" in the list and return its properties.
+ * Returns 0 if not found.
+ */
+    int
+enc_canon_props(name)
+    char_u	*name;
+{
+    int		i;
+
+    i = enc_canon_search(name);
+    if (i >= 0)
+	return enc_canon_table[i].prop;
+#ifdef WIN3264
+    if (name[0] == 'c' && name[1] == 'p' && VIM_ISDIGIT(name[2]))
+    {
+	CPINFO	cpinfo;
+
+	/* Get info on this codepage to find out what it is. */
+	if (GetCPInfo(atoi(name + 2), &cpinfo) != 0)
+	{
+	    if (cpinfo.MaxCharSize == 1) /* some single-byte encoding */
+		return ENC_8BIT;
+	    if (cpinfo.MaxCharSize == 2
+		    && (cpinfo.LeadByte[0] != 0 || cpinfo.LeadByte[1] != 0))
+		/* must be a DBCS encoding */
+		return ENC_DBCS;
+	}
+	return 0;
+    }
+#endif
+    if (STRNCMP(name, "2byte-", 6) == 0)
+	return ENC_DBCS;
+    if (STRNCMP(name, "8bit-", 5) == 0 || STRNCMP(name, "iso-8859-", 9) == 0)
+	return ENC_8BIT;
+    return 0;
+}
+
+/*
+ * Set up for using multi-byte characters.
+ * Called in three cases:
+ * - by main() to initialize (p_enc == NULL)
+ * - by set_init_1() after 'encoding' was set to its default.
+ * - by do_set() when 'encoding' has been set.
+ * p_enc must have been passed through enc_canonize() already.
+ * Sets the "enc_unicode", "enc_utf8", "enc_dbcs" and "has_mbyte" flags.
+ * Fills mb_bytelen_tab[] and returns NULL when there are no problems.
+ * When there is something wrong: Returns an error message and doesn't change
+ * anything.
+ */
+    char_u *
+mb_init()
+{
+    int		i;
+    int		idx;
+    int		n;
+    int		enc_dbcs_new = 0;
+#if defined(USE_ICONV) && !defined(WIN3264) && !defined(WIN32UNIX) \
+	&& !defined(MACOS)
+# define LEN_FROM_CONV
+    vimconv_T	vimconv;
+    char_u	*p;
+#endif
+
+    if (p_enc == NULL)
+    {
+	/* Just starting up: set the whole table to one's. */
+	for (i = 0; i < 256; ++i)
+	    mb_bytelen_tab[i] = 1;
+	input_conv.vc_type = CONV_NONE;
+	input_conv.vc_factor = 1;
+	output_conv.vc_type = CONV_NONE;
+	return NULL;
+    }
+
+#ifdef WIN3264
+    if (p_enc[0] == 'c' && p_enc[1] == 'p' && VIM_ISDIGIT(p_enc[2]))
+    {
+	CPINFO	cpinfo;
+
+	/* Get info on this codepage to find out what it is. */
+	if (GetCPInfo(atoi(p_enc + 2), &cpinfo) != 0)
+	{
+	    if (cpinfo.MaxCharSize == 1)
+	    {
+		/* some single-byte encoding */
+		enc_unicode = 0;
+		enc_utf8 = FALSE;
+	    }
+	    else if (cpinfo.MaxCharSize == 2
+		    && (cpinfo.LeadByte[0] != 0 || cpinfo.LeadByte[1] != 0))
+	    {
+		/* must be a DBCS encoding, check below */
+		enc_dbcs_new = atoi(p_enc + 2);
+	    }
+	    else
+		goto codepage_invalid;
+	}
+	else if (GetLastError() == ERROR_INVALID_PARAMETER)
+	{
+codepage_invalid:
+	    return (char_u *)N_("E543: Not a valid codepage");
+	}
+    }
+#endif
+    else if (STRNCMP(p_enc, "8bit-", 5) == 0
+	    || STRNCMP(p_enc, "iso-8859-", 9) == 0)
+    {
+	/* Accept any "8bit-" or "iso-8859-" name. */
+	enc_unicode = 0;
+	enc_utf8 = FALSE;
+    }
+    else if (STRNCMP(p_enc, "2byte-", 6) == 0)
+    {
+#ifdef WIN3264
+	/* Windows: accept only valid codepage numbers, check below. */
+	if (p_enc[6] != 'c' || p_enc[7] != 'p'
+				      || (enc_dbcs_new = atoi(p_enc + 8)) == 0)
+	    return e_invarg;
+#else
+	/* Unix: accept any "2byte-" name, assume current locale. */
+	enc_dbcs_new = DBCS_2BYTE;
+#endif
+    }
+    else if ((idx = enc_canon_search(p_enc)) >= 0)
+    {
+	i = enc_canon_table[idx].prop;
+	if (i & ENC_UNICODE)
+	{
+	    /* Unicode */
+	    enc_utf8 = TRUE;
+	    if (i & (ENC_2BYTE | ENC_2WORD))
+		enc_unicode = 2;
+	    else if (i & ENC_4BYTE)
+		enc_unicode = 4;
+	    else
+		enc_unicode = 0;
+	}
+	else if (i & ENC_DBCS)
+	{
+	    /* 2byte, handle below */
+	    enc_dbcs_new = enc_canon_table[idx].codepage;
+	}
+	else
+	{
+	    /* Must be 8-bit. */
+	    enc_unicode = 0;
+	    enc_utf8 = FALSE;
+	}
+    }
+    else    /* Don't know what encoding this is, reject it. */
+	return e_invarg;
+
+    if (enc_dbcs_new != 0)
+    {
+#ifdef WIN3264
+	/* Check if the DBCS code page is OK. */
+	if (!IsValidCodePage(enc_dbcs_new))
+	    goto codepage_invalid;
+#endif
+	enc_unicode = 0;
+	enc_utf8 = FALSE;
+    }
+    enc_dbcs = enc_dbcs_new;
+    has_mbyte = (enc_dbcs != 0 || enc_utf8);
+
+#ifdef WIN3264
+    enc_codepage = encname2codepage(p_enc);
+    enc_latin9 = (STRCMP(p_enc, "iso-8859-15") == 0);
+#endif
+
+    /* Detect an encoding that uses latin1 characters. */
+    enc_latin1like = (enc_utf8 || STRCMP(p_enc, "latin1") == 0
+					|| STRCMP(p_enc, "iso-8859-15") == 0);
+
+    /*
+     * Set the function pointers.
+     */
+    if (enc_utf8)
+    {
+	mb_ptr2len = utfc_ptr2len;
+	mb_char2len = utf_char2len;
+	mb_char2bytes = utf_char2bytes;
+	mb_ptr2cells = utf_ptr2cells;
+	mb_char2cells = utf_char2cells;
+	mb_off2cells = utf_off2cells;
+	mb_ptr2char = utf_ptr2char;
+	mb_head_off = utf_head_off;
+    }
+    else if (enc_dbcs != 0)
+    {
+	mb_ptr2len = dbcs_ptr2len;
+	mb_char2len = dbcs_char2len;
+	mb_char2bytes = dbcs_char2bytes;
+	mb_ptr2cells = dbcs_ptr2cells;
+	mb_char2cells = dbcs_char2cells;
+	mb_off2cells = dbcs_off2cells;
+	mb_ptr2char = dbcs_ptr2char;
+	mb_head_off = dbcs_head_off;
+    }
+    else
+    {
+	mb_ptr2len = latin_ptr2len;
+	mb_char2len = latin_char2len;
+	mb_char2bytes = latin_char2bytes;
+	mb_ptr2cells = latin_ptr2cells;
+	mb_char2cells = latin_char2cells;
+	mb_off2cells = latin_off2cells;
+	mb_ptr2char = latin_ptr2char;
+	mb_head_off = latin_head_off;
+    }
+
+    /*
+     * Fill the mb_bytelen_tab[] for MB_BYTE2LEN().
+     */
+#ifdef LEN_FROM_CONV
+    /* When 'encoding' is different from the current locale mblen() won't
+     * work.  Use conversion to "utf-8" instead. */
+    vimconv.vc_type = CONV_NONE;
+    if (enc_dbcs)
+    {
+	p = enc_locale();
+	if (p == NULL || STRCMP(p, p_enc) != 0)
+	{
+	    convert_setup(&vimconv, p_enc, (char_u *)"utf-8");
+	    vimconv.vc_fail = TRUE;
+	}
+	vim_free(p);
+    }
+#endif
+
+    for (i = 0; i < 256; ++i)
+    {
+	/* Our own function to reliably check the length of UTF-8 characters,
+	 * independent of mblen(). */
+	if (enc_utf8)
+	    n = utf8len_tab[i];
+	else if (enc_dbcs == 0)
+	    n = 1;
+	else
+	{
+#if defined(WIN3264) || defined(WIN32UNIX)
+	    /* enc_dbcs is set by setting 'fileencoding'.  It becomes a Windows
+	     * CodePage identifier, which we can pass directly in to Windows
+	     * API */
+	    n = IsDBCSLeadByteEx(enc_dbcs, (BYTE)i) ? 2 : 1;
+#else
+# if defined(MACOS) || defined(__amigaos4__)
+	    /*
+	     * if mblen() is not available, character which MSB is turned on
+	     * are treated as leading byte character. (note : This assumption
+	     * is not always true.)
+	     */
+	    n = (i & 0x80) ? 2 : 1;
+# else
+	    char buf[MB_MAXBYTES];
+# ifdef X_LOCALE
+#  ifndef mblen
+#   define mblen _Xmblen
+#  endif
+# endif
+	    if (i == NUL)	/* just in case mblen() can't handle "" */
+		n = 1;
+	    else
+	    {
+		buf[0] = i;
+		buf[1] = 0;
+#ifdef LEN_FROM_CONV
+		if (vimconv.vc_type != CONV_NONE)
+		{
+		    /*
+		     * string_convert() should fail when converting the first
+		     * byte of a double-byte character.
+		     */
+		    p = string_convert(&vimconv, (char_u *)buf, NULL);
+		    if (p != NULL)
+		    {
+			vim_free(p);
+			n = 1;
+		    }
+		    else
+			n = 2;
+		}
+		else
+#endif
+		{
+		    /*
+		     * mblen() should return -1 for invalid (means the leading
+		     * multibyte) character.  However there are some platforms
+		     * where mblen() returns 0 for invalid character.
+		     * Therefore, following condition includes 0.
+		     */
+		    (void)mblen(NULL, 0);	/* First reset the state. */
+		    if (mblen(buf, (size_t)1) <= 0)
+			n = 2;
+		    else
+			n = 1;
+		}
+	    }
+# endif
+#endif
+	}
+
+	mb_bytelen_tab[i] = n;
+    }
+
+#ifdef LEN_FROM_CONV
+    convert_setup(&vimconv, NULL, NULL);
+#endif
+
+    /* The cell width depends on the type of multi-byte characters. */
+    (void)init_chartab();
+
+    /* When enc_utf8 is set or reset, (de)allocate ScreenLinesUC[] */
+    screenalloc(FALSE);
+
+    /* When using Unicode, set default for 'fileencodings'. */
+    if (enc_utf8 && !option_was_set((char_u *)"fencs"))
+	set_string_option_direct((char_u *)"fencs", -1,
+		       (char_u *)"ucs-bom,utf-8,default,latin1", OPT_FREE, 0);
+
+#if defined(HAVE_BIND_TEXTDOMAIN_CODESET) && defined(FEAT_GETTEXT)
+    /* GNU gettext 0.10.37 supports this feature: set the codeset used for
+     * translated messages independently from the current locale. */
+    (void)bind_textdomain_codeset(VIMPACKAGE,
+					  enc_utf8 ? "utf-8" : (char *)p_enc);
+#endif
+
+#ifdef WIN32
+    /* When changing 'encoding' while starting up, then convert the command
+     * line arguments from the active codepage to 'encoding'. */
+    if (starting != 0)
+	fix_arg_enc();
+#endif
+
+#ifdef FEAT_AUTOCMD
+    /* Fire an autocommand to let people do custom font setup. This must be
+     * after Vim has been setup for the new encoding. */
+    apply_autocmds(EVENT_ENCODINGCHANGED, NULL, (char_u *)"", FALSE, curbuf);
+#endif
+
+#ifdef FEAT_SPELL
+    /* Need to reload spell dictionaries */
+    spell_reload();
+#endif
+
+    return NULL;
+}
+
+/*
+ * Return the size of the BOM for the current buffer:
+ * 0 - no BOM
+ * 2 - UCS-2 or UTF-16 BOM
+ * 4 - UCS-4 BOM
+ * 3 - UTF-8 BOM
+ */
+    int
+bomb_size()
+{
+    int n = 0;
+
+    if (curbuf->b_p_bomb && !curbuf->b_p_bin)
+    {
+	if (*curbuf->b_p_fenc == NUL)
+	{
+	    if (enc_utf8)
+	    {
+		if (enc_unicode != 0)
+		    n = enc_unicode;
+		else
+		    n = 3;
+	    }
+	}
+	else if (STRCMP(curbuf->b_p_fenc, "utf-8") == 0)
+	    n = 3;
+	else if (STRNCMP(curbuf->b_p_fenc, "ucs-2", 5) == 0
+		|| STRNCMP(curbuf->b_p_fenc, "utf-16", 6) == 0)
+	    n = 2;
+	else if (STRNCMP(curbuf->b_p_fenc, "ucs-4", 5) == 0)
+	    n = 4;
+    }
+    return n;
+}
+
+/*
+ * Get class of pointer:
+ * 0 for blank or NUL
+ * 1 for punctuation
+ * 2 for an (ASCII) word character
+ * >2 for other word characters
+ */
+    int
+mb_get_class(p)
+    char_u	*p;
+{
+    if (MB_BYTE2LEN(p[0]) == 1)
+    {
+	if (p[0] == NUL || vim_iswhite(p[0]))
+	    return 0;
+	if (vim_iswordc(p[0]))
+	    return 2;
+	return 1;
+    }
+    if (enc_dbcs != 0 && p[0] != NUL && p[1] != NUL)
+	return dbcs_class(p[0], p[1]);
+    if (enc_utf8)
+	return utf_class(utf_ptr2char(p));
+    return 0;
+}
+
+/*
+ * Get class of a double-byte character.  This always returns 3 or bigger.
+ * TODO: Should return 1 for punctuation.
+ */
+    int
+dbcs_class(lead, trail)
+    unsigned	lead;
+    unsigned	trail;
+{
+    switch (enc_dbcs)
+    {
+	/* please add classfy routine for your language in here */
+
+	case DBCS_JPNU:	/* ? */
+	case DBCS_JPN:
+	    {
+		/* JIS code classification */
+		unsigned char lb = lead;
+		unsigned char tb = trail;
+
+		/* convert process code to JIS */
+# if defined(WIN3264) || defined(WIN32UNIX) || defined(MACOS)
+		/* process code is SJIS */
+		if (lb <= 0x9f)
+		    lb = (lb - 0x81) * 2 + 0x21;
+		else
+		    lb = (lb - 0xc1) * 2 + 0x21;
+		if (tb <= 0x7e)
+		    tb -= 0x1f;
+		else if (tb <= 0x9e)
+		    tb -= 0x20;
+		else
+		{
+		    tb -= 0x7e;
+		    lb += 1;
+		}
+# else
+		/*
+		 * XXX: Code page identification can not use with all
+		 *	    system! So, some other encoding information
+		 *	    will be needed.
+		 *	    In japanese: SJIS,EUC,UNICODE,(JIS)
+		 *	    Note that JIS-code system don't use as
+		 *	    process code in most system because it uses
+		 *	    escape sequences(JIS is context depend encoding).
+		 */
+		/* assume process code is JAPANESE-EUC */
+		lb &= 0x7f;
+		tb &= 0x7f;
+# endif
+		/* exceptions */
+		switch (lb << 8 | tb)
+		{
+		    case 0x2121: /* ZENKAKU space */
+			return 0;
+		    case 0x2122: /* KU-TEN (Japanese comma) */
+		    case 0x2123: /* TOU-TEN (Japanese period) */
+		    case 0x2124: /* ZENKAKU comma */
+		    case 0x2125: /* ZENKAKU period */
+			return 1;
+		    case 0x213c: /* prolongedsound handled as KATAKANA */
+			return 13;
+		}
+		/* sieved by KU code */
+		switch (lb)
+		{
+		    case 0x21:
+		    case 0x22:
+			/* special symbols */
+			return 10;
+		    case 0x23:
+			/* alpha-numeric */
+			return 11;
+		    case 0x24:
+			/* hiragana */
+			return 12;
+		    case 0x25:
+			/* katakana */
+			return 13;
+		    case 0x26:
+			/* greek */
+			return 14;
+		    case 0x27:
+			/* russian */
+			return 15;
+		    case 0x28:
+			/* lines */
+			return 16;
+		    default:
+			/* kanji */
+			return 17;
+		}
+	    }
+
+	case DBCS_KORU:	/* ? */
+	case DBCS_KOR:
+	    {
+		/* KS code classification */
+		unsigned char c1 = lead;
+		unsigned char c2 = trail;
+
+		/*
+		 * 20 : Hangul
+		 * 21 : Hanja
+		 * 22 : Symbols
+		 * 23 : Alpha-numeric/Roman Letter (Full width)
+		 * 24 : Hangul Letter(Alphabet)
+		 * 25 : Roman Numeral/Greek Letter
+		 * 26 : Box Drawings
+		 * 27 : Unit Symbols
+		 * 28 : Circled/Parenthesized Letter
+		 * 29 : Hirigana/Katakana
+		 * 30 : Cyrillic Letter
+		 */
+
+		if (c1 >= 0xB0 && c1 <= 0xC8)
+		    /* Hangul */
+		    return 20;
+#if defined(WIN3264) || defined(WIN32UNIX)
+		else if (c1 <= 0xA0 || c2 <= 0xA0)
+		    /* Extended Hangul Region : MS UHC(Unified Hangul Code) */
+		    /* c1: 0x81-0xA0 with c2: 0x41-0x5A, 0x61-0x7A, 0x81-0xFE
+		     * c1: 0xA1-0xC6 with c2: 0x41-0x5A, 0x61-0x7A, 0x81-0xA0
+		     */
+		    return 20;
+#endif
+
+		else if (c1 >= 0xCA && c1 <= 0xFD)
+		    /* Hanja */
+		    return 21;
+		else switch (c1)
+		{
+		    case 0xA1:
+		    case 0xA2:
+			/* Symbols */
+			return 22;
+		    case 0xA3:
+			/* Alpha-numeric */
+			return 23;
+		    case 0xA4:
+			/* Hangul Letter(Alphabet) */
+			return 24;
+		    case 0xA5:
+			/* Roman Numeral/Greek Letter */
+			return 25;
+		    case 0xA6:
+			/* Box Drawings */
+			return 26;
+		    case 0xA7:
+			/* Unit Symbols */
+			return 27;
+		    case 0xA8:
+		    case 0xA9:
+			if (c2 <= 0xAF)
+			    return 25;  /* Roman Letter */
+			else if (c2 >= 0xF6)
+			    return 22;  /* Symbols */
+			else
+			    /* Circled/Parenthesized Letter */
+			    return 28;
+		    case 0xAA:
+		    case 0xAB:
+			/* Hirigana/Katakana */
+			return 29;
+		    case 0xAC:
+			/* Cyrillic Letter */
+			return 30;
+		}
+	    }
+	default:
+	    break;
+    }
+    return 3;
+}
+
+/*
+ * mb_char2len() function pointer.
+ * Return length in bytes of character "c".
+ * Returns 1 for a single-byte character.
+ */
+/* ARGSUSED */
+    int
+latin_char2len(c)
+    int		c;
+{
+    return 1;
+}
+
+    static int
+dbcs_char2len(c)
+    int		c;
+{
+    if (c >= 0x100)
+	return 2;
+    return 1;
+}
+
+/*
+ * mb_char2bytes() function pointer.
+ * Convert a character to its bytes.
+ * Returns the length in bytes.
+ */
+    int
+latin_char2bytes(c, buf)
+    int		c;
+    char_u	*buf;
+{
+    buf[0] = c;
+    return 1;
+}
+
+    static int
+dbcs_char2bytes(c, buf)
+    int		c;
+    char_u	*buf;
+{
+    if (c >= 0x100)
+    {
+	buf[0] = (unsigned)c >> 8;
+	buf[1] = c;
+	/* Never use a NUL byte, it causes lots of trouble.  It's an invalid
+	 * character anyway. */
+	if (buf[1] == NUL)
+	    buf[1] = '\n';
+	return 2;
+    }
+    buf[0] = c;
+    return 1;
+}
+
+/*
+ * mb_ptr2len() function pointer.
+ * Get byte length of character at "*p" but stop at a NUL.
+ * For UTF-8 this includes following composing characters.
+ * Returns 0 when *p is NUL.
+ *
+ */
+    int
+latin_ptr2len(p)
+    char_u	*p;
+{
+    return MB_BYTE2LEN(*p);
+}
+
+    static int
+dbcs_ptr2len(p)
+    char_u	*p;
+{
+    int		len;
+
+    /* Check if second byte is not missing. */
+    len = MB_BYTE2LEN(*p);
+    if (len == 2 && p[1] == NUL)
+	len = 1;
+    return len;
+}
+
+struct interval
+{
+    unsigned short first;
+    unsigned short last;
+};
+static int intable __ARGS((struct interval *table, size_t size, int c));
+
+/*
+ * Return TRUE if "c" is in "table[size / sizeof(struct interval)]".
+ */
+    static int
+intable(table, size, c)
+    struct interval	*table;
+    size_t		size;
+    int			c;
+{
+    int mid, bot, top;
+
+    /* first quick check for Latin1 etc. characters */
+    if (c < table[0].first)
+	return FALSE;
+
+    /* binary search in table */
+    bot = 0;
+    top = (int)(size / sizeof(struct interval) - 1);
+    while (top >= bot)
+    {
+	mid = (bot + top) / 2;
+	if (table[mid].last < c)
+	    bot = mid + 1;
+	else if (table[mid].first > c)
+	    top = mid - 1;
+	else
+	    return TRUE;
+    }
+    return FALSE;
+}
+
+/*
+ * For UTF-8 character "c" return 2 for a double-width character, 1 for others.
+ * Returns 4 or 6 for an unprintable character.
+ * Is only correct for characters >= 0x80.
+ * When p_ambw is "double", return 2 for a character with East Asian Width
+ * class 'A'(mbiguous).
+ */
+    int
+utf_char2cells(c)
+    int		c;
+{
+    /* sorted list of non-overlapping intervals of East Asian Ambiguous
+     * characters, generated with:
+     * "uniset +WIDTH-A -cat=Me -cat=Mn -cat=Cf c" */
+    static struct interval ambiguous[] = {
+	{0x00A1, 0x00A1}, {0x00A4, 0x00A4}, {0x00A7, 0x00A8},
+	{0x00AA, 0x00AA}, {0x00AE, 0x00AE}, {0x00B0, 0x00B4},
+	{0x00B6, 0x00BA}, {0x00BC, 0x00BF}, {0x00C6, 0x00C6},
+	{0x00D0, 0x00D0}, {0x00D7, 0x00D8}, {0x00DE, 0x00E1},
+	{0x00E6, 0x00E6}, {0x00E8, 0x00EA}, {0x00EC, 0x00ED},
+	{0x00F0, 0x00F0}, {0x00F2, 0x00F3}, {0x00F7, 0x00FA},
+	{0x00FC, 0x00FC}, {0x00FE, 0x00FE}, {0x0101, 0x0101},
+	{0x0111, 0x0111}, {0x0113, 0x0113}, {0x011B, 0x011B},
+	{0x0126, 0x0127}, {0x012B, 0x012B}, {0x0131, 0x0133},
+	{0x0138, 0x0138}, {0x013F, 0x0142}, {0x0144, 0x0144},
+	{0x0148, 0x014B}, {0x014D, 0x014D}, {0x0152, 0x0153},
+	{0x0166, 0x0167}, {0x016B, 0x016B}, {0x01CE, 0x01CE},
+	{0x01D0, 0x01D0}, {0x01D2, 0x01D2}, {0x01D4, 0x01D4},
+	{0x01D6, 0x01D6}, {0x01D8, 0x01D8}, {0x01DA, 0x01DA},
+	{0x01DC, 0x01DC}, {0x0251, 0x0251}, {0x0261, 0x0261},
+	{0x02C4, 0x02C4}, {0x02C7, 0x02C7}, {0x02C9, 0x02CB},
+	{0x02CD, 0x02CD}, {0x02D0, 0x02D0}, {0x02D8, 0x02DB},
+	{0x02DD, 0x02DD}, {0x02DF, 0x02DF}, {0x0391, 0x03A1},
+	{0x03A3, 0x03A9}, {0x03B1, 0x03C1}, {0x03C3, 0x03C9},
+	{0x0401, 0x0401}, {0x0410, 0x044F}, {0x0451, 0x0451},
+	{0x2010, 0x2010}, {0x2013, 0x2016}, {0x2018, 0x2019},
+	{0x201C, 0x201D}, {0x2020, 0x2022}, {0x2024, 0x2027},
+	{0x2030, 0x2030}, {0x2032, 0x2033}, {0x2035, 0x2035},
+	{0x203B, 0x203B}, {0x203E, 0x203E}, {0x2074, 0x2074},
+	{0x207F, 0x207F}, {0x2081, 0x2084}, {0x20AC, 0x20AC},
+	{0x2103, 0x2103}, {0x2105, 0x2105}, {0x2109, 0x2109},
+	{0x2113, 0x2113}, {0x2116, 0x2116}, {0x2121, 0x2122},
+	{0x2126, 0x2126}, {0x212B, 0x212B}, {0x2153, 0x2154},
+	{0x215B, 0x215E}, {0x2160, 0x216B}, {0x2170, 0x2179},
+	{0x2190, 0x2199}, {0x21B8, 0x21B9}, {0x21D2, 0x21D2},
+	{0x21D4, 0x21D4}, {0x21E7, 0x21E7}, {0x2200, 0x2200},
+	{0x2202, 0x2203}, {0x2207, 0x2208}, {0x220B, 0x220B},
+	{0x220F, 0x220F}, {0x2211, 0x2211}, {0x2215, 0x2215},
+	{0x221A, 0x221A}, {0x221D, 0x2220}, {0x2223, 0x2223},
+	{0x2225, 0x2225}, {0x2227, 0x222C}, {0x222E, 0x222E},
+	{0x2234, 0x2237}, {0x223C, 0x223D}, {0x2248, 0x2248},
+	{0x224C, 0x224C}, {0x2252, 0x2252}, {0x2260, 0x2261},
+	{0x2264, 0x2267}, {0x226A, 0x226B}, {0x226E, 0x226F},
+	{0x2282, 0x2283}, {0x2286, 0x2287}, {0x2295, 0x2295},
+	{0x2299, 0x2299}, {0x22A5, 0x22A5}, {0x22BF, 0x22BF},
+	{0x2312, 0x2312}, {0x2460, 0x24E9}, {0x24EB, 0x254B},
+	{0x2550, 0x2573}, {0x2580, 0x258F}, {0x2592, 0x2595},
+	{0x25A0, 0x25A1}, {0x25A3, 0x25A9}, {0x25B2, 0x25B3},
+	{0x25B6, 0x25B7}, {0x25BC, 0x25BD}, {0x25C0, 0x25C1},
+	{0x25C6, 0x25C8}, {0x25CB, 0x25CB}, {0x25CE, 0x25D1},
+	{0x25E2, 0x25E5}, {0x25EF, 0x25EF}, {0x2605, 0x2606},
+	{0x2609, 0x2609}, {0x260E, 0x260F}, {0x2614, 0x2615},
+	{0x261C, 0x261C}, {0x261E, 0x261E}, {0x2640, 0x2640},
+	{0x2642, 0x2642}, {0x2660, 0x2661}, {0x2663, 0x2665},
+	{0x2667, 0x266A}, {0x266C, 0x266D}, {0x266F, 0x266F},
+	{0x273D, 0x273D}, {0x2776, 0x277F}, {0xE000, 0xF8FF},
+	{0xFFFD, 0xFFFD}, /* {0xF0000, 0xFFFFD}, {0x100000, 0x10FFFD} */
+    };
+
+    if (c >= 0x100)
+    {
+#ifdef USE_WCHAR_FUNCTIONS
+	/*
+	 * Assume the library function wcwidth() works better than our own
+	 * stuff.  It should return 1 for ambiguous width chars!
+	 */
+	int	n = wcwidth(c);
+
+	if (n < 0)
+	    return 6;		/* unprintable, displays <xxxx> */
+	if (n > 1)
+	    return n;
+#else
+	if (!utf_printable(c))
+	    return 6;		/* unprintable, displays <xxxx> */
+	if (c >= 0x1100
+	    && (c <= 0x115f			/* Hangul Jamo */
+		|| c == 0x2329
+		|| c == 0x232a
+		|| (c >= 0x2e80 && c <= 0xa4cf
+		    && c != 0x303f)		/* CJK ... Yi */
+		|| (c >= 0xac00 && c <= 0xd7a3)	/* Hangul Syllables */
+		|| (c >= 0xf900 && c <= 0xfaff)	/* CJK Compatibility
+						   Ideographs */
+		|| (c >= 0xfe30 && c <= 0xfe6f)	/* CJK Compatibility Forms */
+		|| (c >= 0xff00 && c <= 0xff60)	/* Fullwidth Forms */
+		|| (c >= 0xffe0 && c <= 0xffe6)
+		|| (c >= 0x20000 && c <= 0x2fffd)
+		|| (c >= 0x30000 && c <= 0x3fffd)))
+	    return 2;
+#endif
+    }
+
+    /* Characters below 0x100 are influenced by 'isprint' option */
+    else if (c >= 0x80 && !vim_isprintc(c))
+	return 4;		/* unprintable, displays <xx> */
+
+    if (c >= 0x80 && *p_ambw == 'd' && intable(ambiguous, sizeof(ambiguous), c))
+	return 2;
+
+    return 1;
+}
+
+/*
+ * mb_ptr2cells() function pointer.
+ * Return the number of display cells character at "*p" occupies.
+ * This doesn't take care of unprintable characters, use ptr2cells() for that.
+ */
+/*ARGSUSED*/
+    int
+latin_ptr2cells(p)
+    char_u	*p;
+{
+    return 1;
+}
+
+    int
+utf_ptr2cells(p)
+    char_u	*p;
+{
+    int		c;
+
+    /* Need to convert to a wide character. */
+    if (*p >= 0x80)
+    {
+	c = utf_ptr2char(p);
+	/* An illegal byte is displayed as <xx>. */
+	if (utf_ptr2len(p) == 1 || c == NUL)
+	    return 4;
+	/* If the char is ASCII it must be an overlong sequence. */
+	if (c < 0x80)
+	    return char2cells(c);
+	return utf_char2cells(c);
+    }
+    return 1;
+}
+
+    int
+dbcs_ptr2cells(p)
+    char_u	*p;
+{
+    /* Number of cells is equal to number of bytes, except for euc-jp when
+     * the first byte is 0x8e. */
+    if (enc_dbcs == DBCS_JPNU && *p == 0x8e)
+	return 1;
+    return MB_BYTE2LEN(*p);
+}
+
+/*
+ * mb_char2cells() function pointer.
+ * Return the number of display cells character "c" occupies.
+ * Only takes care of multi-byte chars, not "^C" and such.
+ */
+/*ARGSUSED*/
+    int
+latin_char2cells(c)
+    int		c;
+{
+    return 1;
+}
+
+    static int
+dbcs_char2cells(c)
+    int		c;
+{
+    /* Number of cells is equal to number of bytes, except for euc-jp when
+     * the first byte is 0x8e. */
+    if (enc_dbcs == DBCS_JPNU && ((unsigned)c >> 8) == 0x8e)
+	return 1;
+    /* use the first byte */
+    return MB_BYTE2LEN((unsigned)c >> 8);
+}
+
+/*
+ * mb_off2cells() function pointer.
+ * Return number of display cells for char at ScreenLines[off].
+ * Caller must make sure "off" and "off + 1" are valid!
+ */
+/*ARGSUSED*/
+    int
+latin_off2cells(off)
+    unsigned	off;
+{
+    return 1;
+}
+
+    int
+dbcs_off2cells(off)
+    unsigned	off;
+{
+    /* Number of cells is equal to number of bytes, except for euc-jp when
+     * the first byte is 0x8e. */
+    if (enc_dbcs == DBCS_JPNU && ScreenLines[off] == 0x8e)
+	return 1;
+    return MB_BYTE2LEN(ScreenLines[off]);
+}
+
+    int
+utf_off2cells(off)
+    unsigned	off;
+{
+    return ScreenLines[off + 1] == 0 ? 2 : 1;
+}
+
+/*
+ * mb_ptr2char() function pointer.
+ * Convert a byte sequence into a character.
+ */
+    int
+latin_ptr2char(p)
+    char_u	*p;
+{
+    return *p;
+}
+
+    static int
+dbcs_ptr2char(p)
+    char_u	*p;
+{
+    if (MB_BYTE2LEN(*p) > 1 && p[1] != NUL)
+	return (p[0] << 8) + p[1];
+    return *p;
+}
+
+/*
+ * Convert a UTF-8 byte sequence to a wide character.
+ * If the sequence is illegal or truncated by a NUL the first byte is
+ * returned.
+ * Does not include composing characters, of course.
+ */
+    int
+utf_ptr2char(p)
+    char_u	*p;
+{
+    int		len;
+
+    if (p[0] < 0x80)	/* be quick for ASCII */
+	return p[0];
+
+    len = utf8len_tab[p[0]];
+    if ((p[1] & 0xc0) == 0x80)
+    {
+	if (len == 2)
+	    return ((p[0] & 0x1f) << 6) + (p[1] & 0x3f);
+	if ((p[2] & 0xc0) == 0x80)
+	{
+	    if (len == 3)
+		return ((p[0] & 0x0f) << 12) + ((p[1] & 0x3f) << 6)
+		    + (p[2] & 0x3f);
+	    if ((p[3] & 0xc0) == 0x80)
+	    {
+		if (len == 4)
+		    return ((p[0] & 0x07) << 18) + ((p[1] & 0x3f) << 12)
+			+ ((p[2] & 0x3f) << 6) + (p[3] & 0x3f);
+		if ((p[4] & 0xc0) == 0x80)
+		{
+		    if (len == 5)
+			return ((p[0] & 0x03) << 24) + ((p[1] & 0x3f) << 18)
+			    + ((p[2] & 0x3f) << 12) + ((p[3] & 0x3f) << 6)
+			    + (p[4] & 0x3f);
+		    if ((p[5] & 0xc0) == 0x80 && len == 6)
+			return ((p[0] & 0x01) << 30) + ((p[1] & 0x3f) << 24)
+			    + ((p[2] & 0x3f) << 18) + ((p[3] & 0x3f) << 12)
+			    + ((p[4] & 0x3f) << 6) + (p[5] & 0x3f);
+		}
+	    }
+	}
+    }
+    /* Illegal value, just return the first byte */
+    return p[0];
+}
+
+/*
+ * Get character at **pp and advance *pp to the next character.
+ * Note: composing characters are skipped!
+ */
+    int
+mb_ptr2char_adv(pp)
+    char_u	**pp;
+{
+    int		c;
+
+    c = (*mb_ptr2char)(*pp);
+    *pp += (*mb_ptr2len)(*pp);
+    return c;
+}
+
+/*
+ * Get character at **pp and advance *pp to the next character.
+ * Note: composing characters are returned as separate characters.
+ */
+    int
+mb_cptr2char_adv(pp)
+    char_u	**pp;
+{
+    int		c;
+
+    c = (*mb_ptr2char)(*pp);
+    if (enc_utf8)
+	*pp += utf_ptr2len(*pp);
+    else
+	*pp += (*mb_ptr2len)(*pp);
+    return c;
+}
+
+#if defined(FEAT_ARABIC) || defined(PROTO)
+/*
+ * Check whether we are dealing with Arabic combining characters.
+ * Note: these are NOT really composing characters!
+ */
+    int
+arabic_combine(one, two)
+    int		one;	    /* first character */
+    int		two;	    /* character just after "one" */
+{
+    if (one == a_LAM)
+	return arabic_maycombine(two);
+    return FALSE;
+}
+
+/*
+ * Check whether we are dealing with a character that could be regarded as an
+ * Arabic combining character, need to check the character before this.
+ */
+    int
+arabic_maycombine(two)
+    int		two;
+{
+    if (p_arshape && !p_tbidi)
+	return (two == a_ALEF_MADDA
+		    || two == a_ALEF_HAMZA_ABOVE
+		    || two == a_ALEF_HAMZA_BELOW
+		    || two == a_ALEF);
+    return FALSE;
+}
+
+/*
+ * Check if the character pointed to by "p2" is a composing character when it
+ * comes after "p1".  For Arabic sometimes "ab" is replaced with "c", which
+ * behaves like a composing character.
+ */
+    int
+utf_composinglike(p1, p2)
+    char_u	*p1;
+    char_u	*p2;
+{
+    int		c2;
+
+    c2 = utf_ptr2char(p2);
+    if (utf_iscomposing(c2))
+	return TRUE;
+    if (!arabic_maycombine(c2))
+	return FALSE;
+    return arabic_combine(utf_ptr2char(p1), c2);
+}
+#endif
+
+/*
+ * Convert a UTF-8 byte string to a wide character.  Also get up to MAX_MCO
+ * composing characters.
+ */
+    int
+utfc_ptr2char(p, pcc)
+    char_u	*p;
+    int		*pcc;	/* return: composing chars, last one is 0 */
+{
+    int		len;
+    int		c;
+    int		cc;
+    int		i = 0;
+
+    c = utf_ptr2char(p);
+    len = utf_ptr2len(p);
+
+    /* Only accept a composing char when the first char isn't illegal. */
+    if ((len > 1 || *p < 0x80)
+	    && p[len] >= 0x80
+	    && UTF_COMPOSINGLIKE(p, p + len))
+    {
+	cc = utf_ptr2char(p + len);
+	for (;;)
+	{
+	    pcc[i++] = cc;
+	    if (i == MAX_MCO)
+		break;
+	    len += utf_ptr2len(p + len);
+	    if (p[len] < 0x80 || !utf_iscomposing(cc = utf_ptr2char(p + len)))
+		break;
+	}
+    }
+
+    if (i < MAX_MCO)	/* last composing char must be 0 */
+	pcc[i] = 0;
+
+    return c;
+}
+
+/*
+ * Convert a UTF-8 byte string to a wide character.  Also get up to MAX_MCO
+ * composing characters.  Use no more than p[maxlen].
+ */
+    int
+utfc_ptr2char_len(p, pcc, maxlen)
+    char_u	*p;
+    int		*pcc;	/* return: composing chars, last one is 0 */
+    int		maxlen;
+{
+    int		len;
+    int		c;
+    int		cc;
+    int		i = 0;
+
+    c = utf_ptr2char(p);
+    len = utf_ptr2len_len(p, maxlen);
+    /* Only accept a composing char when the first char isn't illegal. */
+    if ((len > 1 || *p < 0x80)
+	    && len < maxlen
+	    && p[len] >= 0x80
+	    && UTF_COMPOSINGLIKE(p, p + len))
+    {
+	cc = utf_ptr2char(p + len);
+	for (;;)
+	{
+	    pcc[i++] = cc;
+	    if (i == MAX_MCO)
+		break;
+	    len += utf_ptr2len_len(p + len, maxlen - len);
+	    if (len >= maxlen
+		    || p[len] < 0x80
+		    || !utf_iscomposing(cc = utf_ptr2char(p + len)))
+		break;
+	}
+    }
+
+    if (i < MAX_MCO)	/* last composing char must be 0 */
+	pcc[i] = 0;
+
+    return c;
+}
+
+/*
+ * Convert the character at screen position "off" to a sequence of bytes.
+ * Includes the composing characters.
+ * "buf" must at least have the length MB_MAXBYTES.
+ * Returns the produced number of bytes.
+ */
+    int
+utfc_char2bytes(off, buf)
+    int		off;
+    char_u	*buf;
+{
+    int		len;
+    int		i;
+
+    len = utf_char2bytes(ScreenLinesUC[off], buf);
+    for (i = 0; i < Screen_mco; ++i)
+    {
+	if (ScreenLinesC[i][off] == 0)
+	    break;
+	len += utf_char2bytes(ScreenLinesC[i][off], buf + len);
+    }
+    return len;
+}
+
+/*
+ * Get the length of a UTF-8 byte sequence, not including any following
+ * composing characters.
+ * Returns 0 for "".
+ * Returns 1 for an illegal byte sequence.
+ */
+    int
+utf_ptr2len(p)
+    char_u	*p;
+{
+    int		len;
+    int		i;
+
+    if (*p == NUL)
+	return 0;
+    len = utf8len_tab[*p];
+    for (i = 1; i < len; ++i)
+	if ((p[i] & 0xc0) != 0x80)
+	    return 1;
+    return len;
+}
+
+/*
+ * Return length of UTF-8 character, obtained from the first byte.
+ * "b" must be between 0 and 255!
+ */
+    int
+utf_byte2len(b)
+    int		b;
+{
+    return utf8len_tab[b];
+}
+
+/*
+ * Get the length of UTF-8 byte sequence "p[size]".  Does not include any
+ * following composing characters.
+ * Returns 1 for "".
+ * Returns 1 for an illegal byte sequence.
+ * Returns number > "size" for an incomplete byte sequence.
+ */
+    int
+utf_ptr2len_len(p, size)
+    char_u	*p;
+    int		size;
+{
+    int		len;
+    int		i;
+
+    if (*p == NUL)
+	return 1;
+    len = utf8len_tab[*p];
+    if (len > size)
+	return len;	/* incomplete byte sequence. */
+    for (i = 1; i < len; ++i)
+	if ((p[i] & 0xc0) != 0x80)
+	    return 1;
+    return len;
+}
+
+/*
+ * Return the number of bytes the UTF-8 encoding of the character at "p" takes.
+ * This includes following composing characters.
+ */
+    int
+utfc_ptr2len(p)
+    char_u	*p;
+{
+    int		len;
+    int		b0 = *p;
+#ifdef FEAT_ARABIC
+    int		prevlen;
+#endif
+
+    if (b0 == NUL)
+	return 0;
+    if (b0 < 0x80 && p[1] < 0x80)	/* be quick for ASCII */
+	return 1;
+
+    /* Skip over first UTF-8 char, stopping at a NUL byte. */
+    len = utf_ptr2len(p);
+
+    /* Check for illegal byte. */
+    if (len == 1 && b0 >= 0x80)
+	return 1;
+
+    /*
+     * Check for composing characters.  We can handle only the first two, but
+     * skip all of them (otherwise the cursor would get stuck).
+     */
+#ifdef FEAT_ARABIC
+    prevlen = 0;
+#endif
+    for (;;)
+    {
+	if (p[len] < 0x80 || !UTF_COMPOSINGLIKE(p + prevlen, p + len))
+	    return len;
+
+	/* Skip over composing char */
+#ifdef FEAT_ARABIC
+	prevlen = len;
+#endif
+	len += utf_ptr2len(p + len);
+    }
+}
+
+/*
+ * Return the number of bytes the UTF-8 encoding of the character at "p[size]"
+ * takes.  This includes following composing characters.
+ * Returns 1 for an illegal char or an incomplete byte sequence.
+ */
+    int
+utfc_ptr2len_len(p, size)
+    char_u	*p;
+    int		size;
+{
+    int		len;
+#ifdef FEAT_ARABIC
+    int		prevlen;
+#endif
+
+    if (*p == NUL)
+	return 0;
+    if (p[0] < 0x80 && (size == 1 || p[1] < 0x80)) /* be quick for ASCII */
+	return 1;
+
+    /* Skip over first UTF-8 char, stopping at a NUL byte. */
+    len = utf_ptr2len_len(p, size);
+
+    /* Check for illegal byte and incomplete byte sequence. */
+    if ((len == 1 && p[0] >= 0x80) || len > size)
+	return 1;
+
+    /*
+     * Check for composing characters.  We can handle only the first two, but
+     * skip all of them (otherwise the cursor would get stuck).
+     */
+#ifdef FEAT_ARABIC
+    prevlen = 0;
+#endif
+    while (len < size)
+    {
+	if (p[len] < 0x80 || !UTF_COMPOSINGLIKE(p + prevlen, p + len))
+	    break;
+
+	/* Skip over composing char */
+#ifdef FEAT_ARABIC
+	prevlen = len;
+#endif
+	len += utf_ptr2len_len(p + len, size - len);
+    }
+    return len;
+}
+
+/*
+ * Return the number of bytes the UTF-8 encoding of character "c" takes.
+ * This does not include composing characters.
+ */
+    int
+utf_char2len(c)
+    int		c;
+{
+    if (c < 0x80)
+	return 1;
+    if (c < 0x800)
+	return 2;
+    if (c < 0x10000)
+	return 3;
+    if (c < 0x200000)
+	return 4;
+    if (c < 0x4000000)
+	return 5;
+    return 6;
+}
+
+/*
+ * Convert Unicode character "c" to UTF-8 string in "buf[]".
+ * Returns the number of bytes.
+ * This does not include composing characters.
+ */
+    int
+utf_char2bytes(c, buf)
+    int		c;
+    char_u	*buf;
+{
+    if (c < 0x80)		/* 7 bits */
+    {
+	buf[0] = c;
+	return 1;
+    }
+    if (c < 0x800)		/* 11 bits */
+    {
+	buf[0] = 0xc0 + ((unsigned)c >> 6);
+	buf[1] = 0x80 + (c & 0x3f);
+	return 2;
+    }
+    if (c < 0x10000)		/* 16 bits */
+    {
+	buf[0] = 0xe0 + ((unsigned)c >> 12);
+	buf[1] = 0x80 + (((unsigned)c >> 6) & 0x3f);
+	buf[2] = 0x80 + (c & 0x3f);
+	return 3;
+    }
+    if (c < 0x200000)		/* 21 bits */
+    {
+	buf[0] = 0xf0 + ((unsigned)c >> 18);
+	buf[1] = 0x80 + (((unsigned)c >> 12) & 0x3f);
+	buf[2] = 0x80 + (((unsigned)c >> 6) & 0x3f);
+	buf[3] = 0x80 + (c & 0x3f);
+	return 4;
+    }
+    if (c < 0x4000000)		/* 26 bits */
+    {
+	buf[0] = 0xf8 + ((unsigned)c >> 24);
+	buf[1] = 0x80 + (((unsigned)c >> 18) & 0x3f);
+	buf[2] = 0x80 + (((unsigned)c >> 12) & 0x3f);
+	buf[3] = 0x80 + (((unsigned)c >> 6) & 0x3f);
+	buf[4] = 0x80 + (c & 0x3f);
+	return 5;
+    }
+				/* 31 bits */
+    buf[0] = 0xfc + ((unsigned)c >> 30);
+    buf[1] = 0x80 + (((unsigned)c >> 24) & 0x3f);
+    buf[2] = 0x80 + (((unsigned)c >> 18) & 0x3f);
+    buf[3] = 0x80 + (((unsigned)c >> 12) & 0x3f);
+    buf[4] = 0x80 + (((unsigned)c >> 6) & 0x3f);
+    buf[5] = 0x80 + (c & 0x3f);
+    return 6;
+}
+
+/*
+ * Return TRUE if "c" is a composing UTF-8 character.  This means it will be
+ * drawn on top of the preceding character.
+ * Based on code from Markus Kuhn.
+ */
+    int
+utf_iscomposing(c)
+    int		c;
+{
+    /* sorted list of non-overlapping intervals */
+    static struct interval combining[] =
+    {
+	{0x0300, 0x034f}, {0x0360, 0x036f}, {0x0483, 0x0486}, {0x0488, 0x0489},
+	{0x0591, 0x05a1}, {0x05a3, 0x05b9}, {0x05bb, 0x05bd}, {0x05bf, 0x05bf},
+	{0x05c1, 0x05c2}, {0x05c4, 0x05c4}, {0x0610, 0x0615}, {0x064b, 0x0658},
+	{0x0670, 0x0670}, {0x06d6, 0x06dc}, {0x06de, 0x06e4}, {0x06e7, 0x06e8},
+	{0x06ea, 0x06ed}, {0x0711, 0x0711}, {0x0730, 0x074a}, {0x07a6, 0x07b0},
+	{0x0901, 0x0903}, {0x093c, 0x093c}, {0x093e, 0x094d}, {0x0951, 0x0954},
+	{0x0962, 0x0963}, {0x0981, 0x0983}, {0x09bc, 0x09bc}, {0x09be, 0x09c4},
+	{0x09c7, 0x09c8}, {0x09cb, 0x09cd}, {0x09d7, 0x09d7}, {0x09e2, 0x09e3},
+	{0x0a01, 0x0a03}, {0x0a3c, 0x0a3c}, {0x0a3e, 0x0a42}, {0x0a47, 0x0a48},
+	{0x0a4b, 0x0a4d}, {0x0a70, 0x0a71}, {0x0a81, 0x0a83}, {0x0abc, 0x0abc},
+	{0x0abe, 0x0ac5}, {0x0ac7, 0x0ac9}, {0x0acb, 0x0acd}, {0x0ae2, 0x0ae3},
+	{0x0b01, 0x0b03}, {0x0b3c, 0x0b3c}, {0x0b3e, 0x0b43}, {0x0b47, 0x0b48},
+	{0x0b4b, 0x0b4d}, {0x0b56, 0x0b57}, {0x0b82, 0x0b82}, {0x0bbe, 0x0bc2},
+	{0x0bc6, 0x0bc8}, {0x0bca, 0x0bcd}, {0x0bd7, 0x0bd7}, {0x0c01, 0x0c03},
+	{0x0c3e, 0x0c44}, {0x0c46, 0x0c48}, {0x0c4a, 0x0c4d}, {0x0c55, 0x0c56},
+	{0x0c82, 0x0c83}, {0x0cbc, 0x0cbc}, {0x0cbe, 0x0cc4}, {0x0cc6, 0x0cc8},
+	{0x0cca, 0x0ccd}, {0x0cd5, 0x0cd6}, {0x0d02, 0x0d03}, {0x0d3e, 0x0d43},
+	{0x0d46, 0x0d48}, {0x0d4a, 0x0d4d}, {0x0d57, 0x0d57}, {0x0d82, 0x0d83},
+	{0x0dca, 0x0dca}, {0x0dcf, 0x0dd4}, {0x0dd6, 0x0dd6}, {0x0dd8, 0x0ddf},
+	{0x0df2, 0x0df3}, {0x0e31, 0x0e31}, {0x0e34, 0x0e3a}, {0x0e47, 0x0e4e},
+	{0x0eb1, 0x0eb1}, {0x0eb4, 0x0eb9}, {0x0ebb, 0x0ebc}, {0x0ec8, 0x0ecd},
+	{0x0f18, 0x0f19}, {0x0f35, 0x0f35}, {0x0f37, 0x0f37}, {0x0f39, 0x0f39},
+	{0x0f3e, 0x0f3f}, {0x0f71, 0x0f84}, {0x0f86, 0x0f87}, {0x0f90, 0x0f97},
+	{0x0f99, 0x0fbc}, {0x0fc6, 0x0fc6}, {0x102c, 0x1032}, {0x1036, 0x1039},
+	{0x1056, 0x1059}, {0x1712, 0x1714}, {0x1732, 0x1734}, {0x1752, 0x1753},
+	{0x1772, 0x1773}, {0x17b6, 0x17d3}, {0x17dd, 0x17dd}, {0x180b, 0x180d},
+	{0x18a9, 0x18a9}, {0x1920, 0x192b}, {0x1930, 0x193b}, {0x20d0, 0x20ea},
+	{0x302a, 0x302f}, {0x3099, 0x309a}, {0xfb1e, 0xfb1e}, {0xfe00, 0xfe0f},
+	{0xfe20, 0xfe23},
+    };
+
+    return intable(combining, sizeof(combining), c);
+}
+
+/*
+ * Return TRUE for characters that can be displayed in a normal way.
+ * Only for characters of 0x100 and above!
+ */
+    int
+utf_printable(c)
+    int		c;
+{
+#ifdef USE_WCHAR_FUNCTIONS
+    /*
+     * Assume the iswprint() library function works better than our own stuff.
+     */
+    return iswprint(c);
+#else
+    /* Sorted list of non-overlapping intervals.
+     * 0xd800-0xdfff is reserved for UTF-16, actually illegal. */
+    static struct interval nonprint[] =
+    {
+	{0x070f, 0x070f}, {0x180b, 0x180e}, {0x200b, 0x200f}, {0x202a, 0x202e},
+	{0x206a, 0x206f}, {0xd800, 0xdfff}, {0xfeff, 0xfeff}, {0xfff9, 0xfffb},
+	{0xfffe, 0xffff}
+    };
+
+    return !intable(nonprint, sizeof(nonprint), c);
+#endif
+}
+
+/*
+ * Get class of a Unicode character.
+ * 0: white space
+ * 1: punctuation
+ * 2 or bigger: some class of word character.
+ */
+    int
+utf_class(c)
+    int		c;
+{
+    /* sorted list of non-overlapping intervals */
+    static struct clinterval
+    {
+	unsigned short first;
+	unsigned short last;
+	unsigned short class;
+    } classes[] =
+    {
+	{0x037e, 0x037e, 1},		/* Greek question mark */
+	{0x0387, 0x0387, 1},		/* Greek ano teleia */
+	{0x055a, 0x055f, 1},		/* Armenian punctuation */
+	{0x0589, 0x0589, 1},		/* Armenian full stop */
+	{0x05be, 0x05be, 1},
+	{0x05c0, 0x05c0, 1},
+	{0x05c3, 0x05c3, 1},
+	{0x05f3, 0x05f4, 1},
+	{0x060c, 0x060c, 1},
+	{0x061b, 0x061b, 1},
+	{0x061f, 0x061f, 1},
+	{0x066a, 0x066d, 1},
+	{0x06d4, 0x06d4, 1},
+	{0x0700, 0x070d, 1},		/* Syriac punctuation */
+	{0x0964, 0x0965, 1},
+	{0x0970, 0x0970, 1},
+	{0x0df4, 0x0df4, 1},
+	{0x0e4f, 0x0e4f, 1},
+	{0x0e5a, 0x0e5b, 1},
+	{0x0f04, 0x0f12, 1},
+	{0x0f3a, 0x0f3d, 1},
+	{0x0f85, 0x0f85, 1},
+	{0x104a, 0x104f, 1},		/* Myanmar punctuation */
+	{0x10fb, 0x10fb, 1},		/* Georgian punctuation */
+	{0x1361, 0x1368, 1},		/* Ethiopic punctuation */
+	{0x166d, 0x166e, 1},		/* Canadian Syl. punctuation */
+	{0x1680, 0x1680, 0},
+	{0x169b, 0x169c, 1},
+	{0x16eb, 0x16ed, 1},
+	{0x1735, 0x1736, 1},
+	{0x17d4, 0x17dc, 1},		/* Khmer punctuation */
+	{0x1800, 0x180a, 1},		/* Mongolian punctuation */
+	{0x2000, 0x200b, 0},		/* spaces */
+	{0x200c, 0x2027, 1},		/* punctuation and symbols */
+	{0x2028, 0x2029, 0},
+	{0x202a, 0x202e, 1},		/* punctuation and symbols */
+	{0x202f, 0x202f, 0},
+	{0x2030, 0x205e, 1},		/* punctuation and symbols */
+	{0x205f, 0x205f, 0},
+	{0x2060, 0x27ff, 1},		/* punctuation and symbols */
+	{0x2070, 0x207f, 0x2070},	/* superscript */
+	{0x2080, 0x208f, 0x2080},	/* subscript */
+	{0x2983, 0x2998, 1},
+	{0x29d8, 0x29db, 1},
+	{0x29fc, 0x29fd, 1},
+	{0x3000, 0x3000, 0},		/* ideographic space */
+	{0x3001, 0x3020, 1},		/* ideographic punctuation */
+	{0x3030, 0x3030, 1},
+	{0x303d, 0x303d, 1},
+	{0x3040, 0x309f, 0x3040},	/* Hiragana */
+	{0x30a0, 0x30ff, 0x30a0},	/* Katakana */
+	{0x3300, 0x9fff, 0x4e00},	/* CJK Ideographs */
+	{0xac00, 0xd7a3, 0xac00},	/* Hangul Syllables */
+	{0xf900, 0xfaff, 0x4e00},	/* CJK Ideographs */
+	{0xfd3e, 0xfd3f, 1},
+	{0xfe30, 0xfe6b, 1},		/* punctuation forms */
+	{0xff00, 0xff0f, 1},		/* half/fullwidth ASCII */
+	{0xff1a, 0xff20, 1},		/* half/fullwidth ASCII */
+	{0xff3b, 0xff40, 1},		/* half/fullwidth ASCII */
+	{0xff5b, 0xff65, 1},		/* half/fullwidth ASCII */
+    };
+    int bot = 0;
+    int top = sizeof(classes) / sizeof(struct clinterval) - 1;
+    int mid;
+
+    /* First quick check for Latin1 characters, use 'iskeyword'. */
+    if (c < 0x100)
+    {
+	if (c == ' ' || c == '\t' || c == NUL || c == 0xa0)
+	    return 0;	    /* blank */
+	if (vim_iswordc(c))
+	    return 2;	    /* word character */
+	return 1;	    /* punctuation */
+    }
+
+    /* binary search in table */
+    while (top >= bot)
+    {
+	mid = (bot + top) / 2;
+	if (classes[mid].last < c)
+	    bot = mid + 1;
+	else if (classes[mid].first > c)
+	    top = mid - 1;
+	else
+	    return (int)classes[mid].class;
+    }
+
+    /* most other characters are "word" characters */
+    return 2;
+}
+
+/*
+ * Code for Unicode case-dependent operations.  Based on notes in
+ * http://www.unicode.org/Public/UNIDATA/CaseFolding.txt
+ * This code uses simple case folding, not full case folding.
+ */
+
+/*
+ * The following table is built by foldExtract.pl < CaseFolding.txt .
+ * It must be in numeric order, because we use binary search on it.
+ * An entry such as {0x41,0x5a,1,32} means that UCS-4 characters in the range
+ * from 0x41 to 0x5a inclusive, stepping by 1, are folded by adding 32.
+ */
+
+typedef struct
+{
+    int rangeStart;
+    int rangeEnd;
+    int step;
+    int offset;
+} convertStruct;
+
+static convertStruct foldCase[] =
+{
+	{0x41,0x5a,1,32}, {0xc0,0xd6,1,32}, {0xd8,0xde,1,32},
+	{0x100,0x12e,2,1}, {0x130,0x130,-1,-199}, {0x132,0x136,2,1},
+	{0x139,0x147,2,1}, {0x14a,0x176,2,1}, {0x178,0x178,-1,-121},
+	{0x179,0x17d,2,1}, {0x181,0x181,-1,210}, {0x182,0x184,2,1},
+	{0x186,0x186,-1,206}, {0x187,0x187,-1,1}, {0x189,0x18a,1,205},
+	{0x18b,0x18b,-1,1}, {0x18e,0x18e,-1,79}, {0x18f,0x18f,-1,202},
+	{0x190,0x190,-1,203}, {0x191,0x191,-1,1}, {0x193,0x193,-1,205},
+	{0x194,0x194,-1,207}, {0x196,0x196,-1,211}, {0x197,0x197,-1,209},
+	{0x198,0x198,-1,1}, {0x19c,0x19c,-1,211}, {0x19d,0x19d,-1,213},
+	{0x19f,0x19f,-1,214}, {0x1a0,0x1a4,2,1}, {0x1a6,0x1a6,-1,218},
+	{0x1a7,0x1a7,-1,1}, {0x1a9,0x1a9,-1,218}, {0x1ac,0x1ac,-1,1},
+	{0x1ae,0x1ae,-1,218}, {0x1af,0x1af,-1,1}, {0x1b1,0x1b2,1,217},
+	{0x1b3,0x1b5,2,1}, {0x1b7,0x1b7,-1,219}, {0x1b8,0x1bc,4,1},
+	{0x1c4,0x1c4,-1,2}, {0x1c5,0x1c5,-1,1}, {0x1c7,0x1c7,-1,2},
+	{0x1c8,0x1c8,-1,1}, {0x1ca,0x1ca,-1,2}, {0x1cb,0x1db,2,1},
+	{0x1de,0x1ee,2,1}, {0x1f1,0x1f1,-1,2}, {0x1f2,0x1f4,2,1},
+	{0x1f6,0x1f6,-1,-97}, {0x1f7,0x1f7,-1,-56}, {0x1f8,0x21e,2,1},
+	{0x220,0x220,-1,-130}, {0x222,0x232,2,1}, {0x386,0x386,-1,38},
+	{0x388,0x38a,1,37}, {0x38c,0x38c,-1,64}, {0x38e,0x38f,1,63},
+	{0x391,0x3a1,1,32}, {0x3a3,0x3ab,1,32}, {0x3d8,0x3ee,2,1},
+	{0x3f4,0x3f4,-1,-60}, {0x3f7,0x3f7,-1,1}, {0x3f9,0x3f9,-1,-7},
+	{0x3fa,0x3fa,-1,1}, {0x400,0x40f,1,80}, {0x410,0x42f,1,32},
+	{0x460,0x480,2,1}, {0x48a,0x4be,2,1}, {0x4c1,0x4cd,2,1},
+	{0x4d0,0x4f4,2,1}, {0x4f8,0x500,8,1}, {0x502,0x50e,2,1},
+	{0x531,0x556,1,48}, {0x1e00,0x1e94,2,1}, {0x1ea0,0x1ef8,2,1},
+	{0x1f08,0x1f0f,1,-8}, {0x1f18,0x1f1d,1,-8}, {0x1f28,0x1f2f,1,-8},
+	{0x1f38,0x1f3f,1,-8}, {0x1f48,0x1f4d,1,-8}, {0x1f59,0x1f5f,2,-8},
+	{0x1f68,0x1f6f,1,-8}, {0x1f88,0x1f8f,1,-8}, {0x1f98,0x1f9f,1,-8},
+	{0x1fa8,0x1faf,1,-8}, {0x1fb8,0x1fb9,1,-8}, {0x1fba,0x1fbb,1,-74},
+	{0x1fbc,0x1fbc,-1,-9}, {0x1fc8,0x1fcb,1,-86}, {0x1fcc,0x1fcc,-1,-9},
+	{0x1fd8,0x1fd9,1,-8}, {0x1fda,0x1fdb,1,-100}, {0x1fe8,0x1fe9,1,-8},
+	{0x1fea,0x1feb,1,-112}, {0x1fec,0x1fec,-1,-7}, {0x1ff8,0x1ff9,1,-128},
+	{0x1ffa,0x1ffb,1,-126}, {0x1ffc,0x1ffc,-1,-9}, {0x2126,0x2126,-1,-7517},
+	{0x212a,0x212a,-1,-8383}, {0x212b,0x212b,-1,-8262},
+	{0x2160,0x216f,1,16}, {0x24b6,0x24cf,1,26}, {0xff21,0xff3a,1,32},
+	{0x10400,0x10427,1,40}
+};
+
+static int utf_convert(int a, convertStruct table[], int tableSize);
+
+/*
+ * Generic conversion function for case operations.
+ * Return the converted equivalent of "a", which is a UCS-4 character.  Use
+ * the given conversion "table".  Uses binary search on "table".
+ */
+    static int
+utf_convert(a, table, tableSize)
+    int			a;
+    convertStruct	table[];
+    int			tableSize;
+{
+    int start, mid, end; /* indices into table */
+
+    start = 0;
+    end = tableSize / sizeof(convertStruct);
+    while (start < end)
+    {
+	/* need to search further */
+	mid = (end + start) /2;
+	if (table[mid].rangeEnd < a)
+	    start = mid + 1;
+	else
+	    end = mid;
+    }
+    if (table[start].rangeStart <= a && a <= table[start].rangeEnd
+	    && (a - table[start].rangeStart) % table[start].step == 0)
+	return (a + table[start].offset);
+    else
+	return a;
+}
+
+/*
+ * Return the folded-case equivalent of "a", which is a UCS-4 character.  Uses
+ * simple case folding.
+ */
+    int
+utf_fold(a)
+    int		a;
+{
+    return utf_convert(a, foldCase, sizeof(foldCase));
+}
+
+/*
+ * The following tables are built by upperLowerExtract.pl < UnicodeData.txt .
+ * They must be in numeric order, because we use binary search on them.
+ * An entry such as {0x41,0x5a,1,32} means that UCS-4 characters in the range
+ * from 0x41 to 0x5a inclusive, stepping by 1, are switched to lower (for
+ * example) by adding 32.
+ */
+static convertStruct toLower[] =
+{
+	{0x41,0x5a,1,32}, {0xc0,0xd6,1,32}, {0xd8,0xde,1,32},
+	{0x100,0x12e,2,1}, {0x130,0x130,-1,-199}, {0x132,0x136,2,1},
+	{0x139,0x147,2,1}, {0x14a,0x176,2,1}, {0x178,0x178,-1,-121},
+	{0x179,0x17d,2,1}, {0x181,0x181,-1,210}, {0x182,0x184,2,1},
+	{0x186,0x186,-1,206}, {0x187,0x187,-1,1}, {0x189,0x18a,1,205},
+	{0x18b,0x18b,-1,1}, {0x18e,0x18e,-1,79}, {0x18f,0x18f,-1,202},
+	{0x190,0x190,-1,203}, {0x191,0x191,-1,1}, {0x193,0x193,-1,205},
+	{0x194,0x194,-1,207}, {0x196,0x196,-1,211}, {0x197,0x197,-1,209},
+	{0x198,0x198,-1,1}, {0x19c,0x19c,-1,211}, {0x19d,0x19d,-1,213},
+	{0x19f,0x19f,-1,214}, {0x1a0,0x1a4,2,1}, {0x1a6,0x1a6,-1,218},
+	{0x1a7,0x1a7,-1,1}, {0x1a9,0x1a9,-1,218}, {0x1ac,0x1ac,-1,1},
+	{0x1ae,0x1ae,-1,218}, {0x1af,0x1af,-1,1}, {0x1b1,0x1b2,1,217},
+	{0x1b3,0x1b5,2,1}, {0x1b7,0x1b7,-1,219}, {0x1b8,0x1bc,4,1},
+	{0x1c4,0x1ca,3,2}, {0x1cd,0x1db,2,1}, {0x1de,0x1ee,2,1},
+	{0x1f1,0x1f1,-1,2}, {0x1f4,0x1f4,-1,1}, {0x1f6,0x1f6,-1,-97},
+	{0x1f7,0x1f7,-1,-56}, {0x1f8,0x21e,2,1}, {0x220,0x220,-1,-130},
+	{0x222,0x232,2,1}, {0x386,0x386,-1,38}, {0x388,0x38a,1,37},
+	{0x38c,0x38c,-1,64}, {0x38e,0x38f,1,63}, {0x391,0x3a1,1,32},
+	{0x3a3,0x3ab,1,32}, {0x3d8,0x3ee,2,1}, {0x3f4,0x3f4,-1,-60},
+	{0x3f7,0x3f7,-1,1}, {0x3f9,0x3f9,-1,-7}, {0x3fa,0x3fa,-1,1},
+	{0x400,0x40f,1,80}, {0x410,0x42f,1,32}, {0x460,0x480,2,1},
+	{0x48a,0x4be,2,1}, {0x4c1,0x4cd,2,1}, {0x4d0,0x4f4,2,1},
+	{0x4f8,0x500,8,1}, {0x502,0x50e,2,1}, {0x531,0x556,1,48},
+	{0x1e00,0x1e94,2,1}, {0x1ea0,0x1ef8,2,1}, {0x1f08,0x1f0f,1,-8},
+	{0x1f18,0x1f1d,1,-8}, {0x1f28,0x1f2f,1,-8}, {0x1f38,0x1f3f,1,-8},
+	{0x1f48,0x1f4d,1,-8}, {0x1f59,0x1f5f,2,-8}, {0x1f68,0x1f6f,1,-8},
+	{0x1fb8,0x1fb9,1,-8}, {0x1fba,0x1fbb,1,-74}, {0x1fc8,0x1fcb,1,-86},
+	{0x1fd8,0x1fd9,1,-8}, {0x1fda,0x1fdb,1,-100}, {0x1fe8,0x1fe9,1,-8},
+	{0x1fea,0x1feb,1,-112}, {0x1fec,0x1fec,-1,-7}, {0x1ff8,0x1ff9,1,-128},
+	{0x1ffa,0x1ffb,1,-126}, {0x2126,0x2126,-1,-7517}, {0x212a,0x212a,-1,-8383},
+	{0x212b,0x212b,-1,-8262}, {0xff21,0xff3a,1,32}, {0x10400,0x10427,1,40}
+};
+
+static convertStruct toUpper[] =
+{
+	{0x61,0x7a,1,-32}, {0xb5,0xb5,-1,743}, {0xe0,0xf6,1,-32},
+	{0xf8,0xfe,1,-32}, {0xff,0xff,-1,121}, {0x101,0x12f,2,-1},
+	{0x131,0x131,-1,-232}, {0x133,0x137,2,-1}, {0x13a,0x148,2,-1},
+	{0x14b,0x177,2,-1}, {0x17a,0x17e,2,-1}, {0x17f,0x17f,-1,-300},
+	{0x183,0x185,2,-1}, {0x188,0x18c,4,-1}, {0x192,0x192,-1,-1},
+	{0x195,0x195,-1,97}, {0x199,0x199,-1,-1}, {0x19e,0x19e,-1,130},
+	{0x1a1,0x1a5,2,-1}, {0x1a8,0x1ad,5,-1}, {0x1b0,0x1b4,4,-1},
+	{0x1b6,0x1b9,3,-1}, {0x1bd,0x1bd,-1,-1}, {0x1bf,0x1bf,-1,56},
+	{0x1c5,0x1c6,1,-1}, {0x1c8,0x1c9,1,-1}, {0x1cb,0x1cc,1,-1},
+	{0x1ce,0x1dc,2,-1}, {0x1dd,0x1dd,-1,-79}, {0x1df,0x1ef,2,-1},
+	{0x1f2,0x1f3,1,-1}, {0x1f5,0x1f9,4,-1}, {0x1fb,0x21f,2,-1},
+	{0x223,0x233,2,-1}, {0x253,0x253,-1,-210}, {0x254,0x254,-1,-206},
+	{0x256,0x257,1,-205}, {0x259,0x259,-1,-202}, {0x25b,0x25b,-1,-203},
+	{0x260,0x260,-1,-205}, {0x263,0x263,-1,-207}, {0x268,0x268,-1,-209},
+	{0x269,0x26f,6,-211}, {0x272,0x272,-1,-213}, {0x275,0x275,-1,-214},
+	{0x280,0x283,3,-218}, {0x288,0x288,-1,-218}, {0x28a,0x28b,1,-217},
+	{0x292,0x292,-1,-219}, {0x3ac,0x3ac,-1,-38}, {0x3ad,0x3af,1,-37},
+	{0x3b1,0x3c1,1,-32}, {0x3c2,0x3c2,-1,-31}, {0x3c3,0x3cb,1,-32},
+	{0x3cc,0x3cc,-1,-64}, {0x3cd,0x3ce,1,-63}, {0x3d0,0x3d0,-1,-62},
+	{0x3d1,0x3d1,-1,-57}, {0x3d5,0x3d5,-1,-47}, {0x3d6,0x3d6,-1,-54},
+	{0x3d9,0x3ef,2,-1}, {0x3f0,0x3f0,-1,-86}, {0x3f1,0x3f1,-1,-80},
+	{0x3f2,0x3f2,-1,7}, {0x3f5,0x3f5,-1,-96}, {0x3f8,0x3fb,3,-1},
+	{0x430,0x44f,1,-32}, {0x450,0x45f,1,-80}, {0x461,0x481,2,-1},
+	{0x48b,0x4bf,2,-1}, {0x4c2,0x4ce,2,-1}, {0x4d1,0x4f5,2,-1},
+	{0x4f9,0x501,8,-1}, {0x503,0x50f,2,-1}, {0x561,0x586,1,-48},
+	{0x1e01,0x1e95,2,-1}, {0x1e9b,0x1e9b,-1,-59}, {0x1ea1,0x1ef9,2,-1},
+	{0x1f00,0x1f07,1,8}, {0x1f10,0x1f15,1,8}, {0x1f20,0x1f27,1,8},
+	{0x1f30,0x1f37,1,8}, {0x1f40,0x1f45,1,8}, {0x1f51,0x1f57,2,8},
+	{0x1f60,0x1f67,1,8}, {0x1f70,0x1f71,1,74}, {0x1f72,0x1f75,1,86},
+	{0x1f76,0x1f77,1,100}, {0x1f78,0x1f79,1,128}, {0x1f7a,0x1f7b,1,112},
+	{0x1f7c,0x1f7d,1,126}, {0x1f80,0x1f87,1,8}, {0x1f90,0x1f97,1,8},
+	{0x1fa0,0x1fa7,1,8}, {0x1fb0,0x1fb1,1,8}, {0x1fb3,0x1fb3,-1,9},
+	{0x1fbe,0x1fbe,-1,-7205}, {0x1fc3,0x1fc3,-1,9}, {0x1fd0,0x1fd1,1,8},
+	{0x1fe0,0x1fe1,1,8}, {0x1fe5,0x1fe5,-1,7}, {0x1ff3,0x1ff3,-1,9},
+	{0xff41,0xff5a,1,-32}, {0x10428,0x1044f,1,-40}
+};
+
+/*
+ * Return the upper-case equivalent of "a", which is a UCS-4 character.  Use
+ * simple case folding.
+ */
+    int
+utf_toupper(a)
+    int		a;
+{
+    /* If 'casemap' contains "keepascii" use ASCII style toupper(). */
+    if (a < 128 && (cmp_flags & CMP_KEEPASCII))
+	return TOUPPER_ASC(a);
+
+#if defined(HAVE_TOWUPPER) && defined(__STDC_ISO_10646__)
+    /* If towupper() is available and handles Unicode, use it. */
+    if (!(cmp_flags & CMP_INTERNAL))
+	return towupper(a);
+#endif
+
+    /* For characters below 128 use locale sensitive toupper(). */
+    if (a < 128)
+	return TOUPPER_LOC(a);
+
+    /* For any other characters use the above mapping table. */
+    return utf_convert(a, toUpper, sizeof(toUpper));
+}
+
+    int
+utf_islower(a)
+    int		a;
+{
+    return (utf_toupper(a) != a);
+}
+
+/*
+ * Return the lower-case equivalent of "a", which is a UCS-4 character.  Use
+ * simple case folding.
+ */
+    int
+utf_tolower(a)
+    int		a;
+{
+    /* If 'casemap' contains "keepascii" use ASCII style tolower(). */
+    if (a < 128 && (cmp_flags & CMP_KEEPASCII))
+	return TOLOWER_ASC(a);
+
+#if defined(HAVE_TOWLOWER) && defined(__STDC_ISO_10646__)
+    /* If towlower() is available and handles Unicode, use it. */
+    if (!(cmp_flags & CMP_INTERNAL))
+	return towlower(a);
+#endif
+
+    /* For characters below 128 use locale sensitive tolower(). */
+    if (a < 128)
+	return TOLOWER_LOC(a);
+
+    /* For any other characters use the above mapping table. */
+    return utf_convert(a, toLower, sizeof(toLower));
+}
+
+    int
+utf_isupper(a)
+    int		a;
+{
+    return (utf_tolower(a) != a);
+}
+
+/*
+ * Version of strnicmp() that handles multi-byte characters.
+ * Needed for Big5, Sjift-JIS and UTF-8 encoding.  Other DBCS encodings can
+ * probably use strnicmp(), because there are no ASCII characters in the
+ * second byte.
+ * Returns zero if s1 and s2 are equal (ignoring case), the difference between
+ * two characters otherwise.
+ */
+    int
+mb_strnicmp(s1, s2, nn)
+    char_u	*s1, *s2;
+    size_t	nn;
+{
+    int		i, j, l;
+    int		cdiff;
+    int		incomplete = FALSE;
+    int		n = (int)nn;
+
+    for (i = 0; i < n; i += l)
+    {
+	if (s1[i] == NUL && s2[i] == NUL)   /* both strings end */
+	    return 0;
+	if (enc_utf8)
+	{
+	    l = utf_byte2len(s1[i]);
+	    if (l > n - i)
+	    {
+		l = n - i;		    /* incomplete character */
+		incomplete = TRUE;
+	    }
+	    /* Check directly first, it's faster. */
+	    for (j = 0; j < l; ++j)
+	    {
+		if (s1[i + j] != s2[i + j])
+		    break;
+		if (s1[i + j] == 0)
+		    /* Both stings have the same bytes but are incomplete or
+		     * have illegal bytes, accept them as equal. */
+		    l = j;
+	    }
+	    if (j < l)
+	    {
+		/* If one of the two characters is incomplete return -1. */
+		if (incomplete || i + utf_byte2len(s2[i]) > n)
+		    return -1;
+		cdiff = utf_fold(utf_ptr2char(s1 + i))
+					     - utf_fold(utf_ptr2char(s2 + i));
+		if (cdiff != 0)
+		    return cdiff;
+	    }
+	}
+	else
+	{
+	    l = (*mb_ptr2len)(s1 + i);
+	    if (l <= 1)
+	    {
+		/* Single byte: first check normally, then with ignore case. */
+		if (s1[i] != s2[i])
+		{
+		    cdiff = TOLOWER_LOC(s1[i]) - TOLOWER_LOC(s2[i]);
+		    if (cdiff != 0)
+			return cdiff;
+		}
+	    }
+	    else
+	    {
+		/* For non-Unicode multi-byte don't ignore case. */
+		if (l > n - i)
+		    l = n - i;
+		cdiff = STRNCMP(s1 + i, s2 + i, l);
+		if (cdiff != 0)
+		    return cdiff;
+	    }
+	}
+    }
+    return 0;
+}
+
+/*
+ * "g8": show bytes of the UTF-8 char under the cursor.  Doesn't matter what
+ * 'encoding' has been set to.
+ */
+    void
+show_utf8()
+{
+    int		len;
+    int		rlen = 0;
+    char_u	*line;
+    int		clen;
+    int		i;
+
+    /* Get the byte length of the char under the cursor, including composing
+     * characters. */
+    line = ml_get_cursor();
+    len = utfc_ptr2len(line);
+    if (len == 0)
+    {
+	MSG("NUL");
+	return;
+    }
+
+    clen = 0;
+    for (i = 0; i < len; ++i)
+    {
+	if (clen == 0)
+	{
+	    /* start of (composing) character, get its length */
+	    if (i > 0)
+	    {
+		STRCPY(IObuff + rlen, "+ ");
+		rlen += 2;
+	    }
+	    clen = utf_ptr2len(line + i);
+	}
+	sprintf((char *)IObuff + rlen, "%02x ", line[i]);
+	--clen;
+	rlen += (int)STRLEN(IObuff + rlen);
+	if (rlen > IOSIZE - 20)
+	    break;
+    }
+
+    msg(IObuff);
+}
+
+/*
+ * mb_head_off() function pointer.
+ * Return offset from "p" to the first byte of the character it points into.
+ * Returns 0 when already at the first byte of a character.
+ */
+/*ARGSUSED*/
+    int
+latin_head_off(base, p)
+    char_u	*base;
+    char_u	*p;
+{
+    return 0;
+}
+
+    int
+dbcs_head_off(base, p)
+    char_u	*base;
+    char_u	*p;
+{
+    char_u	*q;
+
+    /* It can't be a trailing byte when not using DBCS, at the start of the
+     * string or the previous byte can't start a double-byte. */
+    if (p <= base || MB_BYTE2LEN(p[-1]) == 1)
+	return 0;
+
+    /* This is slow: need to start at the base and go forward until the
+     * byte we are looking for.  Return 1 when we went past it, 0 otherwise. */
+    q = base;
+    while (q < p)
+	q += dbcs_ptr2len(q);
+    return (q == p) ? 0 : 1;
+}
+
+#if defined(FEAT_CLIPBOARD) || defined(FEAT_GUI) || defined(FEAT_RIGHTLEFT) \
+	|| defined(PROTO)
+/*
+ * Special version of dbcs_head_off() that works for ScreenLines[], where
+ * single-width DBCS_JPNU characters are stored separately.
+ */
+    int
+dbcs_screen_head_off(base, p)
+    char_u	*base;
+    char_u	*p;
+{
+    char_u	*q;
+
+    /* It can't be a trailing byte when not using DBCS, at the start of the
+     * string or the previous byte can't start a double-byte.
+     * For euc-jp an 0x8e byte in the previous cell always means we have a
+     * lead byte in the current cell. */
+    if (p <= base
+	    || (enc_dbcs == DBCS_JPNU && p[-1] == 0x8e)
+	    || MB_BYTE2LEN(p[-1]) == 1)
+	return 0;
+
+    /* This is slow: need to start at the base and go forward until the
+     * byte we are looking for.  Return 1 when we went past it, 0 otherwise.
+     * For DBCS_JPNU look out for 0x8e, which means the second byte is not
+     * stored as the next byte. */
+    q = base;
+    while (q < p)
+    {
+	if (enc_dbcs == DBCS_JPNU && *q == 0x8e)
+	    ++q;
+	else
+	    q += dbcs_ptr2len(q);
+    }
+    return (q == p) ? 0 : 1;
+}
+#endif
+
+    int
+utf_head_off(base, p)
+    char_u	*base;
+    char_u	*p;
+{
+    char_u	*q;
+    char_u	*s;
+    int		c;
+#ifdef FEAT_ARABIC
+    char_u	*j;
+#endif
+
+    if (*p < 0x80)		/* be quick for ASCII */
+	return 0;
+
+    /* Skip backwards over trailing bytes: 10xx.xxxx
+     * Skip backwards again if on a composing char. */
+    for (q = p; ; --q)
+    {
+	/* Move s to the last byte of this char. */
+	for (s = q; (s[1] & 0xc0) == 0x80; ++s)
+	    ;
+	/* Move q to the first byte of this char. */
+	while (q > base && (*q & 0xc0) == 0x80)
+	    --q;
+	/* Check for illegal sequence. Do allow an illegal byte after where we
+	 * started. */
+	if (utf8len_tab[*q] != (int)(s - q + 1)
+				       && utf8len_tab[*q] != (int)(p - q + 1))
+	    return 0;
+
+	if (q <= base)
+	    break;
+
+	c = utf_ptr2char(q);
+	if (utf_iscomposing(c))
+	    continue;
+
+#ifdef FEAT_ARABIC
+	if (arabic_maycombine(c))
+	{
+	    /* Advance to get a sneak-peak at the next char */
+	    j = q;
+	    --j;
+	    /* Move j to the first byte of this char. */
+	    while (j > base && (*j & 0xc0) == 0x80)
+		--j;
+	    if (arabic_combine(utf_ptr2char(j), c))
+		continue;
+	}
+#endif
+	break;
+    }
+
+    return (int)(p - q);
+}
+
+#if defined(FEAT_EVAL) || defined(PROTO)
+/*
+ * Copy a character from "*fp" to "*tp" and advance the pointers.
+ */
+    void
+mb_copy_char(fp, tp)
+    char_u	**fp;
+    char_u	**tp;
+{
+    int	    l = (*mb_ptr2len)(*fp);
+
+    mch_memmove(*tp, *fp, (size_t)l);
+    *tp += l;
+    *fp += l;
+}
+#endif
+
+/*
+ * Return the offset from "p" to the first byte of a character.  When "p" is
+ * at the start of a character 0 is returned, otherwise the offset to the next
+ * character.  Can start anywhere in a stream of bytes.
+ */
+    int
+mb_off_next(base, p)
+    char_u	*base;
+    char_u	*p;
+{
+    int		i;
+    int		j;
+
+    if (enc_utf8)
+    {
+	if (*p < 0x80)		/* be quick for ASCII */
+	    return 0;
+
+	/* Find the next character that isn't 10xx.xxxx */
+	for (i = 0; (p[i] & 0xc0) == 0x80; ++i)
+	    ;
+	if (i > 0)
+	{
+	    /* Check for illegal sequence. */
+	    for (j = 0; p - j > base; ++j)
+		if ((p[-j] & 0xc0) != 0x80)
+		    break;
+	    if (utf8len_tab[p[-j]] != i + j)
+		return 0;
+	}
+	return i;
+    }
+
+    /* Only need to check if we're on a trail byte, it doesn't matter if we
+     * want the offset to the next or current character. */
+    return (*mb_head_off)(base, p);
+}
+
+/*
+ * Return the offset from "p" to the last byte of the character it points
+ * into.  Can start anywhere in a stream of bytes.
+ */
+    int
+mb_tail_off(base, p)
+    char_u	*base;
+    char_u	*p;
+{
+    int		i;
+    int		j;
+
+    if (*p == NUL)
+	return 0;
+
+    if (enc_utf8)
+    {
+	/* Find the last character that is 10xx.xxxx */
+	for (i = 0; (p[i + 1] & 0xc0) == 0x80; ++i)
+	    ;
+	/* Check for illegal sequence. */
+	for (j = 0; p - j > base; ++j)
+	    if ((p[-j] & 0xc0) != 0x80)
+		break;
+	if (utf8len_tab[p[-j]] != i + j + 1)
+	    return 0;
+	return i;
+    }
+
+    /* It can't be the first byte if a double-byte when not using DBCS, at the
+     * end of the string or the byte can't start a double-byte. */
+    if (enc_dbcs == 0 || p[1] == NUL || MB_BYTE2LEN(*p) == 1)
+	return 0;
+
+    /* Return 1 when on the lead byte, 0 when on the tail byte. */
+    return 1 - dbcs_head_off(base, p);
+}
+
+/*
+ * Find the next illegal byte sequence.
+ */
+    void
+utf_find_illegal()
+{
+    pos_T	pos = curwin->w_cursor;
+    char_u	*p;
+    int		len;
+    vimconv_T	vimconv;
+    char_u	*tofree = NULL;
+
+    vimconv.vc_type = CONV_NONE;
+    if (enc_utf8 && (enc_canon_props(curbuf->b_p_fenc) & ENC_8BIT))
+    {
+	/* 'encoding' is "utf-8" but we are editing a 8-bit encoded file,
+	 * possibly a utf-8 file with illegal bytes.  Setup for conversion
+	 * from utf-8 to 'fileencoding'. */
+	convert_setup(&vimconv, p_enc, curbuf->b_p_fenc);
+    }
+
+#ifdef FEAT_VIRTUALEDIT
+    curwin->w_cursor.coladd = 0;
+#endif
+    for (;;)
+    {
+	p = ml_get_cursor();
+	if (vimconv.vc_type != CONV_NONE)
+	{
+	    vim_free(tofree);
+	    tofree = string_convert(&vimconv, p, NULL);
+	    if (tofree == NULL)
+		break;
+	    p = tofree;
+	}
+
+	while (*p != NUL)
+	{
+	    /* Illegal means that there are not enough trail bytes (checked by
+	     * utf_ptr2len()) or too many of them (overlong sequence). */
+	    len = utf_ptr2len(p);
+	    if (*p >= 0x80 && (len == 1
+				     || utf_char2len(utf_ptr2char(p)) != len))
+	    {
+		if (vimconv.vc_type == CONV_NONE)
+		    curwin->w_cursor.col += (colnr_T)(p - ml_get_cursor());
+		else
+		{
+		    int	    l;
+
+		    len = (int)(p - tofree);
+		    for (p = ml_get_cursor(); *p != NUL && len-- > 0; p += l)
+		    {
+			l = utf_ptr2len(p);
+			curwin->w_cursor.col += l;
+		    }
+		}
+		goto theend;
+	    }
+	    p += len;
+	}
+	if (curwin->w_cursor.lnum == curbuf->b_ml.ml_line_count)
+	    break;
+	++curwin->w_cursor.lnum;
+	curwin->w_cursor.col = 0;
+    }
+
+    /* didn't find it: don't move and beep */
+    curwin->w_cursor = pos;
+    beep_flush();
+
+theend:
+    vim_free(tofree);
+    convert_setup(&vimconv, NULL, NULL);
+}
+
+#if defined(HAVE_GTK2) || defined(PROTO)
+/*
+ * Return TRUE if string "s" is a valid utf-8 string.
+ * When "end" is NULL stop at the first NUL.
+ * When "end" is positive stop there.
+ */
+    int
+utf_valid_string(s, end)
+    char_u	*s;
+    char_u	*end;
+{
+    int		l;
+    char_u	*p = s;
+
+    while (end == NULL ? *p != NUL : p < end)
+    {
+	if ((*p & 0xc0) == 0x80)
+	    return FALSE;	/* invalid lead byte */
+	l = utf8len_tab[*p];
+	if (end != NULL && p + l > end)
+	    return FALSE;	/* incomplete byte sequence */
+	++p;
+	while (--l > 0)
+	    if ((*p++ & 0xc0) != 0x80)
+		return FALSE;	/* invalid trail byte */
+    }
+    return TRUE;
+}
+#endif
+
+#if defined(FEAT_GUI) || defined(PROTO)
+/*
+ * Special version of mb_tail_off() for use in ScreenLines[].
+ */
+    int
+dbcs_screen_tail_off(base, p)
+    char_u	*base;
+    char_u	*p;
+{
+    /* It can't be the first byte if a double-byte when not using DBCS, at the
+     * end of the string or the byte can't start a double-byte.
+     * For euc-jp an 0x8e byte always means we have a lead byte in the current
+     * cell. */
+    if (*p == NUL || p[1] == NUL
+	    || (enc_dbcs == DBCS_JPNU && *p == 0x8e)
+	    || MB_BYTE2LEN(*p) == 1)
+	return 0;
+
+    /* Return 1 when on the lead byte, 0 when on the tail byte. */
+    return 1 - dbcs_screen_head_off(base, p);
+}
+#endif
+
+/*
+ * If the cursor moves on an trail byte, set the cursor on the lead byte.
+ * Thus it moves left if necessary.
+ * Return TRUE when the cursor was adjusted.
+ */
+    void
+mb_adjust_cursor()
+{
+    mb_adjustpos(&curwin->w_cursor);
+}
+
+/*
+ * Adjust position "*lp" to point to the first byte of a multi-byte character.
+ * If it points to a tail byte it's moved backwards to the head byte.
+ */
+    void
+mb_adjustpos(lp)
+    pos_T	*lp;
+{
+    char_u	*p;
+
+    if (lp->col > 0
+#ifdef FEAT_VIRTUALEDIT
+	    || lp->coladd > 1
+#endif
+	    )
+    {
+	p = ml_get(lp->lnum);
+	lp->col -= (*mb_head_off)(p, p + lp->col);
+#ifdef FEAT_VIRTUALEDIT
+	/* Reset "coladd" when the cursor would be on the right half of a
+	 * double-wide character. */
+	if (lp->coladd == 1
+		&& p[lp->col] != TAB
+		&& vim_isprintc((*mb_ptr2char)(p + lp->col))
+		&& ptr2cells(p + lp->col) > 1)
+	    lp->coladd = 0;
+#endif
+    }
+}
+
+/*
+ * Return a pointer to the character before "*p", if there is one.
+ */
+    char_u *
+mb_prevptr(line, p)
+    char_u *line;	/* start of the string */
+    char_u *p;
+{
+    if (p > line)
+	mb_ptr_back(line, p);
+    return p;
+}
+
+/*
+ * Return the character length of "str".  Each multi-byte character (with
+ * following composing characters) counts as one.
+ */
+    int
+mb_charlen(str)
+    char_u	*str;
+{
+    char_u	*p = str;
+    int		count;
+
+    if (p == NULL)
+	return 0;
+
+    for (count = 0; *p != NUL; count++)
+	p += (*mb_ptr2len)(p);
+
+    return count;
+}
+
+#if defined(FEAT_SPELL) || defined(PROTO)
+/*
+ * Like mb_charlen() but for a string with specified length.
+ */
+    int
+mb_charlen_len(str, len)
+    char_u	*str;
+    int		len;
+{
+    char_u	*p = str;
+    int		count;
+
+    for (count = 0; *p != NUL && p < str + len; count++)
+	p += (*mb_ptr2len)(p);
+
+    return count;
+}
+#endif
+
+/*
+ * Try to un-escape a multi-byte character.
+ * Used for the "to" and "from" part of a mapping.
+ * Return the un-escaped string if it is a multi-byte character, and advance
+ * "pp" to just after the bytes that formed it.
+ * Return NULL if no multi-byte char was found.
+ */
+    char_u *
+mb_unescape(pp)
+    char_u **pp;
+{
+    static char_u	buf[MB_MAXBYTES + 1];
+    int			n, m = 0;
+    char_u		*str = *pp;
+
+    /* Must translate K_SPECIAL KS_SPECIAL KE_FILLER to K_SPECIAL and CSI
+     * KS_EXTRA KE_CSI to CSI. */
+    for (n = 0; str[n] != NUL && m <= MB_MAXBYTES; ++n)
+    {
+	if (str[n] == K_SPECIAL
+		&& str[n + 1] == KS_SPECIAL
+		&& str[n + 2] == KE_FILLER)
+	{
+	    buf[m++] = K_SPECIAL;
+	    n += 2;
+	}
+# ifdef FEAT_GUI
+	else if (str[n] == CSI
+		&& str[n + 1] == KS_EXTRA
+		&& str[n + 2] == (int)KE_CSI)
+	{
+	    buf[m++] = CSI;
+	    n += 2;
+	}
+# endif
+	else if (str[n] == K_SPECIAL
+# ifdef FEAT_GUI
+		|| str[n] == CSI
+# endif
+		)
+	    break;		/* a special key can't be a multibyte char */
+	else
+	    buf[m++] = str[n];
+	buf[m] = NUL;
+
+	/* Return a multi-byte character if it's found.  An illegal sequence
+	 * will result in a 1 here. */
+	if ((*mb_ptr2len)(buf) > 1)
+	{
+	    *pp = str + n + 1;
+	    return buf;
+	}
+    }
+    return NULL;
+}
+
+/*
+ * Return TRUE if the character at "row"/"col" on the screen is the left side
+ * of a double-width character.
+ * Caller must make sure "row" and "col" are not invalid!
+ */
+    int
+mb_lefthalve(row, col)
+    int	    row;
+    int	    col;
+{
+#ifdef FEAT_HANGULIN
+    if (composing_hangul)
+	return TRUE;
+#endif
+    if (enc_dbcs != 0)
+	return dbcs_off2cells(LineOffset[row] + col) > 1;
+    if (enc_utf8)
+	return (col + 1 < Columns
+		&& ScreenLines[LineOffset[row] + col + 1] == 0);
+    return FALSE;
+}
+
+# if defined(FEAT_CLIPBOARD) || defined(FEAT_GUI) || defined(FEAT_RIGHTLEFT) \
+	|| defined(PROTO)
+/*
+ * Correct a position on the screen, if it's the right halve of a double-wide
+ * char move it to the left halve.  Returns the corrected column.
+ */
+    int
+mb_fix_col(col, row)
+    int		col;
+    int		row;
+{
+    col = check_col(col);
+    row = check_row(row);
+    if (has_mbyte && ScreenLines != NULL && col > 0
+	    && ((enc_dbcs
+		    && ScreenLines[LineOffset[row] + col] != NUL
+		    && dbcs_screen_head_off(ScreenLines + LineOffset[row],
+					 ScreenLines + LineOffset[row] + col))
+		|| (enc_utf8 && ScreenLines[LineOffset[row] + col] == 0)))
+	--col;
+    return col;
+}
+# endif
+#endif
+
+#if defined(FEAT_MBYTE) || defined(FEAT_POSTSCRIPT) || defined(PROTO)
+static int enc_alias_search __ARGS((char_u *name));
+
+/*
+ * Skip the Vim specific head of a 'encoding' name.
+ */
+    char_u *
+enc_skip(p)
+    char_u	*p;
+{
+    if (STRNCMP(p, "2byte-", 6) == 0)
+	return p + 6;
+    if (STRNCMP(p, "8bit-", 5) == 0)
+	return p + 5;
+    return p;
+}
+
+/*
+ * Find the canonical name for encoding "enc".
+ * When the name isn't recognized, returns "enc" itself, but with all lower
+ * case characters and '_' replaced with '-'.
+ * Returns an allocated string.  NULL for out-of-memory.
+ */
+    char_u *
+enc_canonize(enc)
+    char_u	*enc;
+{
+    char_u	*r;
+    char_u	*p, *s;
+    int		i;
+
+# ifdef FEAT_MBYTE
+    if (STRCMP(enc, "default") == 0)
+    {
+	/* Use the default encoding as it's found by set_init_1(). */
+	r = get_encoding_default();
+	if (r == NULL)
+	    r = (char_u *)"latin1";
+	return vim_strsave(r);
+    }
+# endif
+
+    /* copy "enc" to allocated memory, with room for two '-' */
+    r = alloc((unsigned)(STRLEN(enc) + 3));
+    if (r != NULL)
+    {
+	/* Make it all lower case and replace '_' with '-'. */
+	p = r;
+	for (s = enc; *s != NUL; ++s)
+	{
+	    if (*s == '_')
+		*p++ = '-';
+	    else
+		*p++ = TOLOWER_ASC(*s);
+	}
+	*p = NUL;
+
+	/* Skip "2byte-" and "8bit-". */
+	p = enc_skip(r);
+
+	/* Change "microsoft-cp" to "cp".  Used in some spell files. */
+	if (STRNCMP(p, "microsoft-cp", 12) == 0)
+	    mch_memmove(p, p + 10, STRLEN(p + 10) + 1);
+
+	/* "iso8859" -> "iso-8859" */
+	if (STRNCMP(p, "iso8859", 7) == 0)
+	{
+	    mch_memmove(p + 4, p + 3, STRLEN(p + 2));
+	    p[3] = '-';
+	}
+
+	/* "iso-8859n" -> "iso-8859-n" */
+	if (STRNCMP(p, "iso-8859", 8) == 0 && p[8] != '-')
+	{
+	    mch_memmove(p + 9, p + 8, STRLEN(p + 7));
+	    p[8] = '-';
+	}
+
+	/* "latin-N" -> "latinN" */
+	if (STRNCMP(p, "latin-", 6) == 0)
+	    mch_memmove(p + 5, p + 6, STRLEN(p + 5));
+
+	if (enc_canon_search(p) >= 0)
+	{
+	    /* canonical name can be used unmodified */
+	    if (p != r)
+		mch_memmove(r, p, STRLEN(p) + 1);
+	}
+	else if ((i = enc_alias_search(p)) >= 0)
+	{
+	    /* alias recognized, get canonical name */
+	    vim_free(r);
+	    r = vim_strsave((char_u *)enc_canon_table[i].name);
+	}
+    }
+    return r;
+}
+
+/*
+ * Search for an encoding alias of "name".
+ * Returns -1 when not found.
+ */
+    static int
+enc_alias_search(name)
+    char_u	*name;
+{
+    int		i;
+
+    for (i = 0; enc_alias_table[i].name != NULL; ++i)
+	if (STRCMP(name, enc_alias_table[i].name) == 0)
+	    return enc_alias_table[i].canon;
+    return -1;
+}
+#endif
+
+#if defined(FEAT_MBYTE) || defined(PROTO)
+
+#ifdef HAVE_LANGINFO_H
+# include <langinfo.h>
+#endif
+
+/*
+ * Get the canonicalized encoding of the current locale.
+ * Returns an allocated string when successful, NULL when not.
+ */
+    char_u *
+enc_locale()
+{
+#ifndef WIN3264
+    char	*s;
+    char	*p;
+    int		i;
+#endif
+    char	buf[50];
+#if defined(WIN3264)
+    long	acp = GetACP();
+
+    if (acp == 1200)
+	STRCPY(buf, "ucs-2le");
+    else if (acp == 1252)	    /* cp1252 is used as latin1 */
+	STRCPY(buf, "latin1");
+    else
+	sprintf(buf, "cp%ld", acp);
+#elif defined(PLAN9)
+    /* Plan 9 uses unicode internally */
+    STRCPY(buf, "utf-8");
+#else
+# ifdef HAVE_NL_LANGINFO_CODESET
+    if ((s = nl_langinfo(CODESET)) == NULL || *s == NUL)
+# endif
+#  if defined(HAVE_LOCALE_H) || defined(X_LOCALE)
+	if ((s = setlocale(LC_CTYPE, NULL)) == NULL || *s == NUL)
+#  endif
+	    if ((s = getenv("LC_ALL")) == NULL || *s == NUL)
+		if ((s = getenv("LC_CTYPE")) == NULL || *s == NUL)
+		    s = getenv("LANG");
+
+    if (s == NULL || *s == NUL)
+	return FAIL;
+
+    /* The most generic locale format is:
+     * language[_territory][.codeset][@modifier][+special][,[sponsor][_revision]]
+     * If there is a '.' remove the part before it.
+     * if there is something after the codeset, remove it.
+     * Make the name lowercase and replace '_' with '-'.
+     * Exception: "ja_JP.EUC" == "euc-jp", "zh_CN.EUC" = "euc-cn",
+     * "ko_KR.EUC" == "euc-kr"
+     */
+    if ((p = (char *)vim_strchr((char_u *)s, '.')) != NULL)
+    {
+	if (p > s + 2 && STRNICMP(p + 1, "EUC", 3) == 0
+			&& !isalnum((int)p[4]) && p[4] != '-' && p[-3] == '_')
+	{
+	    /* copy "XY.EUC" to "euc-XY" to buf[10] */
+	    STRCPY(buf + 10, "euc-");
+	    buf[14] = p[-2];
+	    buf[15] = p[-1];
+	    buf[16] = 0;
+	    s = buf + 10;
+	}
+	else
+	    s = p + 1;
+    }
+    for (i = 0; s[i] != NUL && s + i < buf + sizeof(buf) - 1; ++i)
+    {
+	if (s[i] == '_' || s[i] == '-')
+	    buf[i] = '-';
+	else if (isalnum((int)s[i]))
+	    buf[i] = TOLOWER_ASC(s[i]);
+	else
+	    break;
+    }
+    buf[i] = NUL;
+#endif
+
+    return enc_canonize((char_u *)buf);
+}
+
+#if defined(WIN3264) || defined(PROTO)
+/*
+ * Convert an encoding name to an MS-Windows codepage.
+ * Returns zero if no codepage can be figured out.
+ */
+    int
+encname2codepage(name)
+    char_u	*name;
+{
+    int		cp;
+    char_u	*p = name;
+    int		idx;
+
+    if (STRNCMP(p, "8bit-", 5) == 0)
+	p += 5;
+    else if (STRNCMP(p_enc, "2byte-", 6) == 0)
+	p += 6;
+
+    if (p[0] == 'c' && p[1] == 'p')
+	cp = atoi(p + 2);
+    else if ((idx = enc_canon_search(p)) >= 0)
+	cp = enc_canon_table[idx].codepage;
+    else
+	return 0;
+    if (IsValidCodePage(cp))
+	return cp;
+    return 0;
+}
+#endif
+
+# if defined(USE_ICONV) || defined(PROTO)
+
+static char_u *iconv_string __ARGS((vimconv_T *vcp, char_u *str, int slen, int *unconvlenp));
+
+/*
+ * Call iconv_open() with a check if iconv() works properly (there are broken
+ * versions).
+ * Returns (void *)-1 if failed.
+ * (should return iconv_t, but that causes problems with prototypes).
+ */
+    void *
+my_iconv_open(to, from)
+    char_u	*to;
+    char_u	*from;
+{
+    iconv_t	fd;
+#define ICONV_TESTLEN 400
+    char_u	tobuf[ICONV_TESTLEN];
+    char	*p;
+    size_t	tolen;
+    static int	iconv_ok = -1;
+
+    if (iconv_ok == FALSE)
+	return (void *)-1;	/* detected a broken iconv() previously */
+
+#ifdef DYNAMIC_ICONV
+    /* Check if the iconv.dll can be found. */
+    if (!iconv_enabled(TRUE))
+	return (void *)-1;
+#endif
+
+    fd = iconv_open((char *)enc_skip(to), (char *)enc_skip(from));
+
+    if (fd != (iconv_t)-1 && iconv_ok == -1)
+    {
+	/*
+	 * Do a dummy iconv() call to check if it actually works.  There is a
+	 * version of iconv() on Linux that is broken.  We can't ignore it,
+	 * because it's wide-spread.  The symptoms are that after outputting
+	 * the initial shift state the "to" pointer is NULL and conversion
+	 * stops for no apparent reason after about 8160 characters.
+	 */
+	p = (char *)tobuf;
+	tolen = ICONV_TESTLEN;
+	(void)iconv(fd, NULL, NULL, &p, &tolen);
+	if (p == NULL)
+	{
+	    iconv_ok = FALSE;
+	    iconv_close(fd);
+	    fd = (iconv_t)-1;
+	}
+	else
+	    iconv_ok = TRUE;
+    }
+
+    return (void *)fd;
+}
+
+/*
+ * Convert the string "str[slen]" with iconv().
+ * If "unconvlenp" is not NULL handle the string ending in an incomplete
+ * sequence and set "*unconvlenp" to the length of it.
+ * Returns the converted string in allocated memory.  NULL for an error.
+ */
+    static char_u *
+iconv_string(vcp, str, slen, unconvlenp)
+    vimconv_T	*vcp;
+    char_u	*str;
+    int		slen;
+    int		*unconvlenp;
+{
+    const char	*from;
+    size_t	fromlen;
+    char	*to;
+    size_t	tolen;
+    size_t	len = 0;
+    size_t	done = 0;
+    char_u	*result = NULL;
+    char_u	*p;
+    int		l;
+
+    from = (char *)str;
+    fromlen = slen;
+    for (;;)
+    {
+	if (len == 0 || ICONV_ERRNO == ICONV_E2BIG)
+	{
+	    /* Allocate enough room for most conversions.  When re-allocating
+	     * increase the buffer size. */
+	    len = len + fromlen * 2 + 40;
+	    p = alloc((unsigned)len);
+	    if (p != NULL && done > 0)
+		mch_memmove(p, result, done);
+	    vim_free(result);
+	    result = p;
+	    if (result == NULL)	/* out of memory */
+		break;
+	}
+
+	to = (char *)result + done;
+	tolen = len - done - 2;
+	/* Avoid a warning for systems with a wrong iconv() prototype by
+	 * casting the second argument to void *. */
+	if (iconv(vcp->vc_fd, (void *)&from, &fromlen, &to, &tolen)
+								!= (size_t)-1)
+	{
+	    /* Finished, append a NUL. */
+	    *to = NUL;
+	    break;
+	}
+
+	/* Check both ICONV_EINVAL and EINVAL, because the dynamically loaded
+	 * iconv library may use one of them. */
+	if (!vcp->vc_fail && unconvlenp != NULL
+		&& (ICONV_ERRNO == ICONV_EINVAL || ICONV_ERRNO == EINVAL))
+	{
+	    /* Handle an incomplete sequence at the end. */
+	    *to = NUL;
+	    *unconvlenp = (int)fromlen;
+	    break;
+	}
+
+	/* Check both ICONV_EILSEQ and EILSEQ, because the dynamically loaded
+	 * iconv library may use one of them. */
+	else if (!vcp->vc_fail
+		&& (ICONV_ERRNO == ICONV_EILSEQ || ICONV_ERRNO == EILSEQ
+		    || ICONV_ERRNO == ICONV_EINVAL || ICONV_ERRNO == EINVAL))
+	{
+	    /* Can't convert: insert a '?' and skip a character.  This assumes
+	     * conversion from 'encoding' to something else.  In other
+	     * situations we don't know what to skip anyway. */
+	    *to++ = '?';
+	    if ((*mb_ptr2cells)((char_u *)from) > 1)
+		*to++ = '?';
+	    if (enc_utf8)
+		l = utfc_ptr2len_len((char_u *)from, (int)fromlen);
+	    else
+	    {
+		l = (*mb_ptr2len)((char_u *)from);
+		if (l > (int)fromlen)
+		    l = (int)fromlen;
+	    }
+	    from += l;
+	    fromlen -= l;
+	}
+	else if (ICONV_ERRNO != ICONV_E2BIG)
+	{
+	    /* conversion failed */
+	    vim_free(result);
+	    result = NULL;
+	    break;
+	}
+	/* Not enough room or skipping illegal sequence. */
+	done = to - (char *)result;
+    }
+    return result;
+}
+
+#  if defined(DYNAMIC_ICONV) || defined(PROTO)
+/*
+ * Dynamically load the "iconv.dll" on Win32.
+ */
+
+#ifndef DYNAMIC_ICONV	    /* just generating prototypes */
+# define HINSTANCE int
+#endif
+static HINSTANCE hIconvDLL = 0;
+static HINSTANCE hMsvcrtDLL = 0;
+
+#  ifndef DYNAMIC_ICONV_DLL
+#   define DYNAMIC_ICONV_DLL "iconv.dll"
+#   define DYNAMIC_ICONV_DLL_ALT "libiconv.dll"
+#  endif
+#  ifndef DYNAMIC_MSVCRT_DLL
+#   define DYNAMIC_MSVCRT_DLL "msvcrt.dll"
+#  endif
+
+/*
+ * Try opening the iconv.dll and return TRUE if iconv() can be used.
+ */
+    int
+iconv_enabled(verbose)
+    int		verbose;
+{
+    if (hIconvDLL != 0 && hMsvcrtDLL != 0)
+	return TRUE;
+    hIconvDLL = LoadLibrary(DYNAMIC_ICONV_DLL);
+    if (hIconvDLL == 0)		/* sometimes it's called libiconv.dll */
+	hIconvDLL = LoadLibrary(DYNAMIC_ICONV_DLL_ALT);
+    if (hIconvDLL != 0)
+	hMsvcrtDLL = LoadLibrary(DYNAMIC_MSVCRT_DLL);
+    if (hIconvDLL == 0 || hMsvcrtDLL == 0)
+    {
+	/* Only give the message when 'verbose' is set, otherwise it might be
+	 * done whenever a conversion is attempted. */
+	if (verbose && p_verbose > 0)
+	{
+	    verbose_enter();
+	    EMSG2(_(e_loadlib),
+		    hIconvDLL == 0 ? DYNAMIC_ICONV_DLL : DYNAMIC_MSVCRT_DLL);
+	    verbose_leave();
+	}
+	iconv_end();
+	return FALSE;
+    }
+
+    iconv	= (void *)GetProcAddress(hIconvDLL, "libiconv");
+    iconv_open	= (void *)GetProcAddress(hIconvDLL, "libiconv_open");
+    iconv_close	= (void *)GetProcAddress(hIconvDLL, "libiconv_close");
+    iconvctl	= (void *)GetProcAddress(hIconvDLL, "libiconvctl");
+    iconv_errno	= (void *)GetProcAddress(hMsvcrtDLL, "_errno");
+    if (iconv == NULL || iconv_open == NULL || iconv_close == NULL
+	    || iconvctl == NULL || iconv_errno == NULL)
+    {
+	iconv_end();
+	if (verbose && p_verbose > 0)
+	{
+	    verbose_enter();
+	    EMSG2(_(e_loadfunc), "for libiconv");
+	    verbose_leave();
+	}
+	return FALSE;
+    }
+    return TRUE;
+}
+
+    void
+iconv_end()
+{
+    /* Don't use iconv() when inputting or outputting characters. */
+    if (input_conv.vc_type == CONV_ICONV)
+	convert_setup(&input_conv, NULL, NULL);
+    if (output_conv.vc_type == CONV_ICONV)
+	convert_setup(&output_conv, NULL, NULL);
+
+    if (hIconvDLL != 0)
+	FreeLibrary(hIconvDLL);
+    if (hMsvcrtDLL != 0)
+	FreeLibrary(hMsvcrtDLL);
+    hIconvDLL = 0;
+    hMsvcrtDLL = 0;
+}
+#  endif /* DYNAMIC_ICONV */
+# endif /* USE_ICONV */
+
+#endif /* FEAT_MBYTE */
+
+#if defined(FEAT_XIM) || defined(PROTO)
+
+# ifdef FEAT_GUI_GTK
+static int xim_has_preediting INIT(= FALSE);  /* IM current status */
+
+/*
+ * Set preedit_start_col to the current cursor position.
+ */
+    static void
+init_preedit_start_col(void)
+{
+    if (State & CMDLINE)
+	preedit_start_col = cmdline_getvcol_cursor();
+    else if (curwin != NULL)
+	getvcol(curwin, &curwin->w_cursor, &preedit_start_col, NULL, NULL);
+    /* Prevent that preediting marks the buffer as changed. */
+    xim_changed_while_preediting = curbuf->b_changed;
+}
+# endif
+
+# if defined(HAVE_GTK2) && !defined(PROTO)
+
+static int im_is_active	       = FALSE;	/* IM is enabled for current mode    */
+static int im_preedit_cursor   = 0;	/* cursor offset in characters       */
+static int im_preedit_trailing = 0;	/* number of characters after cursor */
+
+static unsigned long im_commit_handler_id  = 0;
+static unsigned int  im_activatekey_keyval = GDK_VoidSymbol;
+static unsigned int  im_activatekey_state  = 0;
+
+    void
+im_set_active(int active)
+{
+    int was_active;
+
+    was_active = !!im_is_active;
+    im_is_active = (active && !p_imdisable);
+
+    if (im_is_active != was_active)
+	xim_reset();
+}
+
+    void
+xim_set_focus(int focus)
+{
+    if (xic != NULL)
+    {
+	if (focus)
+	    gtk_im_context_focus_in(xic);
+	else
+	    gtk_im_context_focus_out(xic);
+    }
+}
+
+    void
+im_set_position(int row, int col)
+{
+    if (xic != NULL)
+    {
+	GdkRectangle area;
+
+	area.x = FILL_X(col);
+	area.y = FILL_Y(row);
+	area.width  = gui.char_width * (mb_lefthalve(row, col) ? 2 : 1);
+	area.height = gui.char_height;
+
+	gtk_im_context_set_cursor_location(xic, &area);
+    }
+}
+
+#  if 0 || defined(PROTO) /* apparently only used in gui_x11.c */
+    void
+xim_set_preedit(void)
+{
+    im_set_position(gui.row, gui.col);
+}
+#  endif
+
+    static void
+im_add_to_input(char_u *str, int len)
+{
+    /* Convert from 'termencoding' (always "utf-8") to 'encoding' */
+    if (input_conv.vc_type != CONV_NONE)
+    {
+	str = string_convert(&input_conv, str, &len);
+	g_return_if_fail(str != NULL);
+    }
+
+    add_to_input_buf_csi(str, len);
+
+    if (input_conv.vc_type != CONV_NONE)
+	vim_free(str);
+
+    if (p_mh) /* blank out the pointer if necessary */
+	gui_mch_mousehide(TRUE);
+}
+
+    static void
+im_delete_preedit(void)
+{
+    char_u bskey[]  = {CSI, 'k', 'b'};
+    char_u delkey[] = {CSI, 'k', 'D'};
+
+    if (State & NORMAL)
+    {
+	im_preedit_cursor = 0;
+	return;
+    }
+    for (; im_preedit_cursor > 0; --im_preedit_cursor)
+	add_to_input_buf(bskey, (int)sizeof(bskey));
+
+    for (; im_preedit_trailing > 0; --im_preedit_trailing)
+	add_to_input_buf(delkey, (int)sizeof(delkey));
+}
+
+/*
+ * Move the cursor left by "num_move_back" characters.
+ * Note that ins_left() checks im_is_preediting() to avoid breaking undo for
+ * these K_LEFT keys.
+ */
+    static void
+im_correct_cursor(int num_move_back)
+{
+    char_u backkey[] = {CSI, 'k', 'l'};
+
+    if (State & NORMAL)
+	return;
+#  ifdef FEAT_RIGHTLEFT
+    if ((State & CMDLINE) == 0 && curwin != NULL && curwin->w_p_rl)
+	backkey[2] = 'r';
+#  endif
+    for (; num_move_back > 0; --num_move_back)
+	add_to_input_buf(backkey, (int)sizeof(backkey));
+}
+
+static int xim_expected_char = NUL;
+static int xim_ignored_char = FALSE;
+
+/*
+ * Update the mode and cursor while in an IM callback.
+ */
+    static void
+im_show_info(void)
+{
+    int	    old_vgetc_busy;
+
+    old_vgetc_busy = vgetc_busy;
+    vgetc_busy = TRUE;
+    showmode();
+    vgetc_busy = old_vgetc_busy;
+    setcursor();
+    out_flush();
+}
+
+/*
+ * Callback invoked when the user finished preediting.
+ * Put the final string into the input buffer.
+ */
+/*ARGSUSED0*/
+    static void
+im_commit_cb(GtkIMContext *context, const gchar *str, gpointer data)
+{
+    int	slen = (int)STRLEN(str);
+    int	add_to_input = TRUE;
+    int	clen;
+    int	len = slen;
+    int	commit_with_preedit = TRUE;
+    char_u	*im_str, *p;
+
+#ifdef XIM_DEBUG
+    xim_log("im_commit_cb(): %s\n", str);
+#endif
+
+    /* The imhangul module doesn't reset the preedit string before
+     * committing.  Call im_delete_preedit() to work around that. */
+    im_delete_preedit();
+
+    /* Indicate that preediting has finished. */
+    if (preedit_start_col == MAXCOL)
+    {
+	init_preedit_start_col();
+	commit_with_preedit = FALSE;
+    }
+
+    /* The thing which setting "preedit_start_col" to MAXCOL means that
+     * "preedit_start_col" will be set forcely when calling
+     * preedit_changed_cb() next time.
+     * "preedit_start_col" should not reset with MAXCOL on this part. Vim
+     * is simulating the preediting by using add_to_input_str(). when
+     * preedit begin immediately before committed, the typebuf is not
+     * flushed to screen, then it can't get correct "preedit_start_col".
+     * Thus, it should calculate the cells by adding cells of the committed
+     * string. */
+    if (input_conv.vc_type != CONV_NONE)
+    {
+	im_str = string_convert(&input_conv, (char_u *)str, &len);
+	g_return_if_fail(im_str != NULL);
+    }
+    else
+	im_str = (char_u *)str;
+    clen = 0;
+    for (p = im_str; p < im_str + len; p += (*mb_ptr2len)(p))
+	clen += (*mb_ptr2cells)(p);
+    if (input_conv.vc_type != CONV_NONE)
+	vim_free(im_str);
+    preedit_start_col += clen;
+
+    /* Is this a single character that matches a keypad key that's just
+     * been pressed?  If so, we don't want it to be entered as such - let
+     * us carry on processing the raw keycode so that it may be used in
+     * mappings as <kSomething>. */
+    if (xim_expected_char != NUL)
+    {
+	/* We're currently processing a keypad or other special key */
+	if (slen == 1 && str[0] == xim_expected_char)
+	{
+	    /* It's a match - don't do it here */
+	    xim_ignored_char = TRUE;
+	    add_to_input = FALSE;
+	}
+	else
+	{
+	    /* Not a match */
+	    xim_ignored_char = FALSE;
+	}
+    }
+
+    if (add_to_input)
+	im_add_to_input((char_u *)str, slen);
+
+    /* Inserting chars while "im_is_active" is set does not cause a change of
+     * buffer.  When the chars are committed the buffer must be marked as
+     * changed. */
+    if (!commit_with_preedit)
+	preedit_start_col = MAXCOL;
+
+    /* This flag is used in changed() at next call. */
+    xim_changed_while_preediting = TRUE;
+
+    if (gtk_main_level() > 0)
+	gtk_main_quit();
+}
+
+/*
+ * Callback invoked after start to the preedit.
+ */
+/*ARGSUSED*/
+    static void
+im_preedit_start_cb(GtkIMContext *context, gpointer data)
+{
+#ifdef XIM_DEBUG
+    xim_log("im_preedit_start_cb()\n");
+#endif
+
+    im_is_active = TRUE;
+    gui_update_cursor(TRUE, FALSE);
+}
+
+/*
+ * Callback invoked after end to the preedit.
+ */
+/*ARGSUSED*/
+    static void
+im_preedit_end_cb(GtkIMContext *context, gpointer data)
+{
+#ifdef XIM_DEBUG
+    xim_log("im_preedit_end_cb()\n");
+#endif
+    im_delete_preedit();
+
+    /* Indicate that preediting has finished */
+    preedit_start_col = MAXCOL;
+    xim_has_preediting = FALSE;
+
+    im_is_active = FALSE;
+    gui_update_cursor(TRUE, FALSE);
+    im_show_info();
+}
+
+/*
+ * Callback invoked after changes to the preedit string.  If the preedit
+ * string was empty before, remember the preedit start column so we know
+ * where to apply feedback attributes.  Delete the previous preedit string
+ * if there was one, save the new preedit cursor offset, and put the new
+ * string into the input buffer.
+ *
+ * TODO: The pragmatic "put into input buffer" approach used here has
+ *       several fundamental problems:
+ *
+ * - The characters in the preedit string are subject to remapping.
+ *   That's broken, only the finally committed string should be remapped.
+ *
+ * - There is a race condition involved:  The retrieved value for the
+ *   current cursor position will be wrong if any unprocessed characters
+ *   are still queued in the input buffer.
+ *
+ * - Due to the lack of synchronization between the file buffer in memory
+ *   and any typed characters, it's practically impossible to implement the
+ *   "retrieve_surrounding" and "delete_surrounding" signals reliably.  IM
+ *   modules for languages such as Thai are likely to rely on this feature
+ *   for proper operation.
+ *
+ * Conclusions:  I think support for preediting needs to be moved to the
+ * core parts of Vim.  Ideally, until it has been committed, the preediting
+ * string should only be displayed and not affect the buffer content at all.
+ * The question how to deal with the synchronization issue still remains.
+ * Circumventing the input buffer is probably not desirable.  Anyway, I think
+ * implementing "retrieve_surrounding" is the only hard problem.
+ *
+ * One way to solve all of this in a clean manner would be to queue all key
+ * press/release events "as is" in the input buffer, and apply the IM filtering
+ * at the receiving end of the queue.  This, however, would have a rather large
+ * impact on the code base.  If there is an easy way to force processing of all
+ * remaining input from within the "retrieve_surrounding" signal handler, this
+ * might not be necessary.  Gotta ask on vim-dev for opinions.
+ */
+/*ARGSUSED1*/
+    static void
+im_preedit_changed_cb(GtkIMContext *context, gpointer data)
+{
+    char    *preedit_string = NULL;
+    int	    cursor_index    = 0;
+    int	    num_move_back   = 0;
+    char_u  *str;
+    char_u  *p;
+    int	    i;
+
+    gtk_im_context_get_preedit_string(context,
+				      &preedit_string, NULL,
+				      &cursor_index);
+
+#ifdef XIM_DEBUG
+    xim_log("im_preedit_changed_cb(): %s\n", preedit_string);
+#endif
+
+    g_return_if_fail(preedit_string != NULL); /* just in case */
+
+    /* If preedit_start_col is MAXCOL set it to the current cursor position. */
+    if (preedit_start_col == MAXCOL && preedit_string[0] != '\0')
+    {
+	xim_has_preediting = TRUE;
+
+	/* Urgh, this breaks if the input buffer isn't empty now */
+	init_preedit_start_col();
+    }
+    else if (cursor_index == 0 && preedit_string[0] == '\0')
+    {
+	xim_has_preediting = FALSE;
+
+	/* If at the start position (after typing backspace)
+	 * preedit_start_col must be reset. */
+	preedit_start_col = MAXCOL;
+    }
+
+    im_delete_preedit();
+
+    /*
+     * Compute the end of the preediting area: "preedit_end_col".
+     * According to the documentation of gtk_im_context_get_preedit_string(),
+     * the cursor_pos output argument returns the offset in bytes.  This is
+     * unfortunately not true -- real life shows the offset is in characters,
+     * and the GTK+ source code agrees with me.  Will file a bug later.
+     */
+    if (preedit_start_col != MAXCOL)
+	preedit_end_col = preedit_start_col;
+    str = (char_u *)preedit_string;
+    for (p = str, i = 0; *p != NUL; p += utf_byte2len(*p), ++i)
+    {
+	int is_composing;
+
+	is_composing = ((*p & 0x80) != 0 && utf_iscomposing(utf_ptr2char(p)));
+	/*
+	 * These offsets are used as counters when generating <BS> and <Del>
+	 * to delete the preedit string.  So don't count composing characters
+	 * unless 'delcombine' is enabled.
+	 */
+	if (!is_composing || p_deco)
+	{
+	    if (i < cursor_index)
+		++im_preedit_cursor;
+	    else
+		++im_preedit_trailing;
+	}
+	if (!is_composing && i >= cursor_index)
+	{
+	    /* This is essentially the same as im_preedit_trailing, except
+	     * composing characters are not counted even if p_deco is set. */
+	    ++num_move_back;
+	}
+	if (preedit_start_col != MAXCOL)
+	    preedit_end_col += utf_ptr2cells(p);
+    }
+
+    if (p > str)
+    {
+	im_add_to_input(str, (int)(p - str));
+	im_correct_cursor(num_move_back);
+    }
+
+    g_free(preedit_string);
+
+    if (gtk_main_level() > 0)
+	gtk_main_quit();
+}
+
+/*
+ * Translate the Pango attributes at iter to Vim highlighting attributes.
+ * Ignore attributes not supported by Vim highlighting.  This shouldn't have
+ * too much impact -- right now we handle even more attributes than necessary
+ * for the IM modules I tested with.
+ */
+    static int
+translate_pango_attributes(PangoAttrIterator *iter)
+{
+    PangoAttribute  *attr;
+    int		    char_attr = HL_NORMAL;
+
+    attr = pango_attr_iterator_get(iter, PANGO_ATTR_UNDERLINE);
+    if (attr != NULL && ((PangoAttrInt *)attr)->value
+						 != (int)PANGO_UNDERLINE_NONE)
+	char_attr |= HL_UNDERLINE;
+
+    attr = pango_attr_iterator_get(iter, PANGO_ATTR_WEIGHT);
+    if (attr != NULL && ((PangoAttrInt *)attr)->value >= (int)PANGO_WEIGHT_BOLD)
+	char_attr |= HL_BOLD;
+
+    attr = pango_attr_iterator_get(iter, PANGO_ATTR_STYLE);
+    if (attr != NULL && ((PangoAttrInt *)attr)->value
+						   != (int)PANGO_STYLE_NORMAL)
+	char_attr |= HL_ITALIC;
+
+    attr = pango_attr_iterator_get(iter, PANGO_ATTR_BACKGROUND);
+    if (attr != NULL)
+    {
+	const PangoColor *color = &((PangoAttrColor *)attr)->color;
+
+	/* Assume inverse if black background is requested */
+	if ((color->red | color->green | color->blue) == 0)
+	    char_attr |= HL_INVERSE;
+    }
+
+    return char_attr;
+}
+
+/*
+ * Retrieve the highlighting attributes at column col in the preedit string.
+ * Return -1 if not in preediting mode or if col is out of range.
+ */
+    int
+im_get_feedback_attr(int col)
+{
+    char	    *preedit_string = NULL;
+    PangoAttrList   *attr_list	    = NULL;
+    int		    char_attr	    = -1;
+
+    if (xic == NULL)
+	return char_attr;
+
+    gtk_im_context_get_preedit_string(xic, &preedit_string, &attr_list, NULL);
+
+    if (preedit_string != NULL && attr_list != NULL)
+    {
+	int idx;
+
+	/* Get the byte index as used by PangoAttrIterator */
+	for (idx = 0; col > 0 && preedit_string[idx] != '\0'; --col)
+	    idx += utfc_ptr2len((char_u *)preedit_string + idx);
+
+	if (preedit_string[idx] != '\0')
+	{
+	    PangoAttrIterator	*iter;
+	    int			start, end;
+
+	    char_attr = HL_NORMAL;
+	    iter = pango_attr_list_get_iterator(attr_list);
+
+	    /* Extract all relevant attributes from the list. */
+	    do
+	    {
+		pango_attr_iterator_range(iter, &start, &end);
+
+		if (idx >= start && idx < end)
+		    char_attr |= translate_pango_attributes(iter);
+	    }
+	    while (pango_attr_iterator_next(iter));
+
+	    pango_attr_iterator_destroy(iter);
+	}
+    }
+
+    if (attr_list != NULL)
+	pango_attr_list_unref(attr_list);
+    g_free(preedit_string);
+
+    return char_attr;
+}
+
+    void
+xim_init(void)
+{
+#ifdef XIM_DEBUG
+    xim_log("xim_init()\n");
+#endif
+
+    g_return_if_fail(gui.drawarea != NULL);
+    g_return_if_fail(gui.drawarea->window != NULL);
+
+    xic = gtk_im_multicontext_new();
+    g_object_ref(xic);
+
+    im_commit_handler_id = g_signal_connect(G_OBJECT(xic), "commit",
+					    G_CALLBACK(&im_commit_cb), NULL);
+    g_signal_connect(G_OBJECT(xic), "preedit_changed",
+		     G_CALLBACK(&im_preedit_changed_cb), NULL);
+    g_signal_connect(G_OBJECT(xic), "preedit_start",
+		     G_CALLBACK(&im_preedit_start_cb), NULL);
+    g_signal_connect(G_OBJECT(xic), "preedit_end",
+		     G_CALLBACK(&im_preedit_end_cb), NULL);
+
+    gtk_im_context_set_client_window(xic, gui.drawarea->window);
+}
+
+    void
+im_shutdown(void)
+{
+#ifdef XIM_DEBUG
+    xim_log("im_shutdown()\n");
+#endif
+
+    if (xic != NULL)
+    {
+	gtk_im_context_focus_out(xic);
+	g_object_unref(xic);
+	xic = NULL;
+    }
+    im_is_active = FALSE;
+    im_commit_handler_id = 0;
+    preedit_start_col = MAXCOL;
+    xim_has_preediting = FALSE;
+}
+
+/*
+ * Convert the string argument to keyval and state for GdkEventKey.
+ * If str is valid return TRUE, otherwise FALSE.
+ *
+ * See 'imactivatekey' for documentation of the format.
+ */
+    static int
+im_string_to_keyval(const char *str, unsigned int *keyval, unsigned int *state)
+{
+    const char	    *mods_end;
+    unsigned	    tmp_keyval;
+    unsigned	    tmp_state = 0;
+
+    mods_end = strrchr(str, '-');
+    mods_end = (mods_end != NULL) ? mods_end + 1 : str;
+
+    /* Parse modifier keys */
+    while (str < mods_end)
+	switch (*str++)
+	{
+	    case '-':							break;
+	    case 'S': case 's': tmp_state |= (unsigned)GDK_SHIFT_MASK;	break;
+	    case 'L': case 'l': tmp_state |= (unsigned)GDK_LOCK_MASK;	break;
+	    case 'C': case 'c': tmp_state |= (unsigned)GDK_CONTROL_MASK;break;
+	    case '1':		tmp_state |= (unsigned)GDK_MOD1_MASK;	break;
+	    case '2':		tmp_state |= (unsigned)GDK_MOD2_MASK;	break;
+	    case '3':		tmp_state |= (unsigned)GDK_MOD3_MASK;	break;
+	    case '4':		tmp_state |= (unsigned)GDK_MOD4_MASK;	break;
+	    case '5':		tmp_state |= (unsigned)GDK_MOD5_MASK;	break;
+	    default:
+		return FALSE;
+	}
+
+    tmp_keyval = gdk_keyval_from_name(str);
+
+    if (tmp_keyval == 0 || tmp_keyval == GDK_VoidSymbol)
+	return FALSE;
+
+    if (keyval != NULL)
+	*keyval = tmp_keyval;
+    if (state != NULL)
+	*state = tmp_state;
+
+    return TRUE;
+}
+
+/*
+ * Return TRUE if p_imak is valid, otherwise FALSE.  As a special case, an
+ * empty string is also regarded as valid.
+ *
+ * Note: The numerical key value of p_imak is cached if it was valid; thus
+ * boldly assuming im_xim_isvalid_imactivate() will always be called whenever
+ * 'imak' changes.  This is currently the case but not obvious -- should
+ * probably rename the function for clarity.
+ */
+    int
+im_xim_isvalid_imactivate(void)
+{
+    if (p_imak[0] == NUL)
+    {
+	im_activatekey_keyval = GDK_VoidSymbol;
+	im_activatekey_state  = 0;
+	return TRUE;
+    }
+
+    return im_string_to_keyval((const char *)p_imak,
+			       &im_activatekey_keyval,
+			       &im_activatekey_state);
+}
+
+    static void
+im_synthesize_keypress(unsigned int keyval, unsigned int state)
+{
+    GdkEventKey *event;
+
+#  ifdef HAVE_GTK_MULTIHEAD
+    event = (GdkEventKey *)gdk_event_new(GDK_KEY_PRESS);
+    g_object_ref(gui.drawarea->window); /* unreffed by gdk_event_free() */
+#  else
+    event = (GdkEventKey *)g_malloc0((gulong)sizeof(GdkEvent));
+    event->type = GDK_KEY_PRESS;
+#  endif
+    event->window = gui.drawarea->window;
+    event->send_event = TRUE;
+    event->time = GDK_CURRENT_TIME;
+    event->state  = state;
+    event->keyval = keyval;
+    event->hardware_keycode = /* needed for XIM */
+	XKeysymToKeycode(GDK_WINDOW_XDISPLAY(event->window), (KeySym)keyval);
+    event->length = 0;
+    event->string = NULL;
+
+    gtk_im_context_filter_keypress(xic, event);
+
+    /* For consistency, also send the corresponding release event. */
+    event->type = GDK_KEY_RELEASE;
+    event->send_event = FALSE;
+    gtk_im_context_filter_keypress(xic, event);
+
+#  ifdef HAVE_GTK_MULTIHEAD
+    gdk_event_free((GdkEvent *)event);
+#  else
+    g_free(event);
+#  endif
+}
+
+    void
+xim_reset(void)
+{
+    if (xic != NULL)
+    {
+	/*
+	 * The third-party imhangul module (and maybe others too) ignores
+	 * gtk_im_context_reset() or at least doesn't reset the active state.
+	 * Thus sending imactivatekey would turn it off if it was on before,
+	 * which is clearly not what we want.  Fortunately we can work around
+	 * that for imhangul by sending GDK_Escape, but I don't know if it
+	 * works with all IM modules that support an activation key :/
+	 *
+	 * An alternative approach would be to destroy the IM context and
+	 * recreate it.  But that means loading/unloading the IM module on
+	 * every mode switch, which causes a quite noticable delay even on
+	 * my rather fast box...
+	 * *
+	 * Moreover, there are some XIM which cannot respond to
+	 * im_synthesize_keypress(). we hope that they reset by
+	 * xim_shutdown().
+	 */
+	if (im_activatekey_keyval != GDK_VoidSymbol && im_is_active)
+	    im_synthesize_keypress(GDK_Escape, 0U);
+
+	gtk_im_context_reset(xic);
+
+	/*
+	 * HACK for Ami: This sequence of function calls makes Ami handle
+	 * the IM reset graciously, without breaking loads of other stuff.
+	 * It seems to force English mode as well, which is exactly what we
+	 * want because it makes the Ami status display work reliably.
+	 */
+	gtk_im_context_set_use_preedit(xic, FALSE);
+
+	if (p_imdisable)
+	    im_shutdown();
+	else
+	{
+	    gtk_im_context_set_use_preedit(xic, TRUE);
+	    xim_set_focus(gui.in_focus);
+
+	    if (im_activatekey_keyval != GDK_VoidSymbol)
+	    {
+		if (im_is_active)
+		{
+		    g_signal_handler_block(xic, im_commit_handler_id);
+		    im_synthesize_keypress(im_activatekey_keyval,
+						    im_activatekey_state);
+		    g_signal_handler_unblock(xic, im_commit_handler_id);
+		}
+	    }
+	    else
+	    {
+		im_shutdown();
+		xim_init();
+		xim_set_focus(gui.in_focus);
+	    }
+	}
+    }
+
+    preedit_start_col = MAXCOL;
+    xim_has_preediting = FALSE;
+}
+
+    int
+xim_queue_key_press_event(GdkEventKey *event, int down)
+{
+    if (down)
+    {
+	/*
+	 * Workaround GTK2 XIM 'feature' that always converts keypad keys to
+	 * chars., even when not part of an IM sequence (ref. feature of
+	 * gdk/gdkkeyuni.c).
+	 * Flag any keypad keys that might represent a single char.
+	 * If this (on its own - i.e., not part of an IM sequence) is
+	 * committed while we're processing one of these keys, we can ignore
+	 * that commit and go ahead & process it ourselves.  That way we can
+	 * still distinguish keypad keys for use in mappings.
+	 */
+	switch (event->keyval)
+	{
+	    case GDK_KP_Add:      xim_expected_char = '+';  break;
+	    case GDK_KP_Subtract: xim_expected_char = '-';  break;
+	    case GDK_KP_Divide:   xim_expected_char = '/';  break;
+	    case GDK_KP_Multiply: xim_expected_char = '*';  break;
+	    case GDK_KP_Decimal:  xim_expected_char = '.';  break;
+	    case GDK_KP_Equal:    xim_expected_char = '=';  break;
+	    case GDK_KP_0:	  xim_expected_char = '0';  break;
+	    case GDK_KP_1:	  xim_expected_char = '1';  break;
+	    case GDK_KP_2:	  xim_expected_char = '2';  break;
+	    case GDK_KP_3:	  xim_expected_char = '3';  break;
+	    case GDK_KP_4:	  xim_expected_char = '4';  break;
+	    case GDK_KP_5:	  xim_expected_char = '5';  break;
+	    case GDK_KP_6:	  xim_expected_char = '6';  break;
+	    case GDK_KP_7:	  xim_expected_char = '7';  break;
+	    case GDK_KP_8:	  xim_expected_char = '8';  break;
+	    case GDK_KP_9:	  xim_expected_char = '9';  break;
+	    default:		  xim_expected_char = NUL;
+	}
+	xim_ignored_char = FALSE;
+    }
+
+    /*
+     * When typing fFtT, XIM may be activated. Thus it must pass
+     * gtk_im_context_filter_keypress() in Normal mode.
+     * And while doing :sh too.
+     */
+    if (xic != NULL && !p_imdisable
+		    && (State & (INSERT | CMDLINE | NORMAL | EXTERNCMD)) != 0)
+    {
+	/*
+	 * Filter 'imactivatekey' and map it to CTRL-^.  This way, Vim is
+	 * always aware of the current status of IM, and can even emulate
+	 * the activation key for modules that don't support one.
+	 */
+	if (event->keyval == im_activatekey_keyval
+	     && (event->state & im_activatekey_state) == im_activatekey_state)
+	{
+	    unsigned int state_mask;
+
+	    /* Require the state of the 3 most used modifiers to match exactly.
+	     * Otherwise e.g. <S-C-space> would be unusable for other purposes
+	     * if the IM activate key is <S-space>. */
+	    state_mask  = im_activatekey_state;
+	    state_mask |= ((int)GDK_SHIFT_MASK | (int)GDK_CONTROL_MASK
+							| (int)GDK_MOD1_MASK);
+
+	    if ((event->state & state_mask) != im_activatekey_state)
+		return FALSE;
+
+	    /* Don't send it a second time on GDK_KEY_RELEASE. */
+	    if (event->type != GDK_KEY_PRESS)
+		return TRUE;
+
+	    if (map_to_exists_mode((char_u *)"", LANGMAP, FALSE))
+	    {
+		im_set_active(FALSE);
+
+		/* ":lmap" mappings exists, toggle use of mappings. */
+		State ^= LANGMAP;
+		if (State & LANGMAP)
+		{
+		    curbuf->b_p_iminsert = B_IMODE_NONE;
+		    State &= ~LANGMAP;
+		}
+		else
+		{
+		    curbuf->b_p_iminsert = B_IMODE_LMAP;
+		    State |= LANGMAP;
+		}
+		return TRUE;
+	    }
+
+	    return gtk_im_context_filter_keypress(xic, event);
+	}
+
+	/* Don't filter events through the IM context if IM isn't active
+	 * right now.  Unlike with GTK+ 1.2 we cannot rely on the IM module
+	 * not doing anything before the activation key was sent. */
+	if (im_activatekey_keyval == GDK_VoidSymbol || im_is_active)
+	{
+	    int imresult = gtk_im_context_filter_keypress(xic, event);
+
+	    /* Some XIM send following sequence:
+	     * 1. preedited string.
+	     * 2. committed string.
+	     * 3. line changed key.
+	     * 4. preedited string.
+	     * 5. remove preedited string.
+	     * if 3, Vim can't move back the above line for 5.
+	     * thus, this part should not parse the key. */
+	    if (!imresult && preedit_start_col != MAXCOL
+					       && event->keyval == GDK_Return)
+	    {
+		im_synthesize_keypress(GDK_Return, 0U);
+		return FALSE;
+	    }
+
+	    /* If XIM tried to commit a keypad key as a single char.,
+	     * ignore it so we can use the keypad key 'raw', for mappings. */
+	    if (xim_expected_char != NUL && xim_ignored_char)
+		/* We had a keypad key, and XIM tried to thieve it */
+		return FALSE;
+
+	    /* Normal processing */
+	    return imresult;
+	}
+    }
+
+    return FALSE;
+}
+
+    int
+im_get_status(void)
+{
+    return im_is_active;
+}
+
+# else /* !HAVE_GTK2 */
+
+static int	xim_is_active = FALSE;  /* XIM should be active in the current
+					   mode */
+static int	xim_has_focus = FALSE;	/* XIM is really being used for Vim */
+#ifdef FEAT_GUI_X11
+static XIMStyle	input_style;
+static int	status_area_enabled = TRUE;
+#endif
+
+#ifdef FEAT_GUI_GTK
+# ifdef WIN3264
+#  include <gdk/gdkwin32.h>
+# else
+#  include <gdk/gdkx.h>
+# endif
+#else
+# ifdef PROTO
+/* Define a few things to be able to generate prototypes while not configured
+ * for GTK. */
+#  define GSList int
+#  define gboolean int
+   typedef int GdkEvent;
+   typedef int GdkEventKey;
+#  define GdkIC int
+# endif
+#endif
+
+#if defined(FEAT_GUI_GTK) || defined(PROTO)
+static int	preedit_buf_len = 0;
+static int	xim_can_preediting INIT(= FALSE);	/* XIM in showmode() */
+static int	xim_input_style;
+#ifndef FEAT_GUI_GTK
+# define gboolean int
+#endif
+static gboolean	use_status_area = 0;
+
+static int im_xim_str2keycode __ARGS((unsigned int *code, unsigned int *state));
+static void im_xim_send_event_imactivate __ARGS((void));
+
+/*
+ * Convert string to keycode and state for XKeyEvent.
+ * When string is valid return OK, when invalid return FAIL.
+ *
+ * See 'imactivatekey' documentation for the format.
+ */
+    static int
+im_xim_str2keycode(code, state)
+    unsigned int *code;
+    unsigned int *state;
+{
+    int		retval = OK;
+    int		len;
+    unsigned	keycode = 0, keystate = 0;
+    Window	window;
+    Display	*display;
+    char_u	*flag_end;
+    char_u	*str;
+
+    if (*p_imak != NUL)
+    {
+	len = STRLEN(p_imak);
+	for (flag_end = p_imak + len - 1;
+			    flag_end > p_imak && *flag_end != '-'; --flag_end)
+	    ;
+
+	/* Parse modifier keys */
+	for (str = p_imak; str < flag_end; ++str)
+	{
+	    switch (*str)
+	    {
+		case 's': case 'S':
+		    keystate |= ShiftMask;
+		    break;
+		case 'l': case 'L':
+		    keystate |= LockMask;
+		    break;
+		case 'c': case 'C':
+		    keystate |= ControlMask;
+		    break;
+		case '1':
+		    keystate |= Mod1Mask;
+		    break;
+		case '2':
+		    keystate |= Mod2Mask;
+		    break;
+		case '3':
+		    keystate |= Mod3Mask;
+		    break;
+		case '4':
+		    keystate |= Mod4Mask;
+		    break;
+		case '5':
+		    keystate |= Mod5Mask;
+		    break;
+		case '-':
+		    break;
+		default:
+		    retval = FAIL;
+	    }
+	}
+	if (*str == '-')
+	    ++str;
+
+	/* Get keycode from string. */
+	gui_get_x11_windis(&window, &display);
+	if (display)
+	    keycode = XKeysymToKeycode(display, XStringToKeysym((char *)str));
+	if (keycode == 0)
+	    retval = FAIL;
+
+	if (code != NULL)
+	    *code = keycode;
+	if (state != NULL)
+	    *state = keystate;
+    }
+    return retval;
+}
+
+    static void
+im_xim_send_event_imactivate()
+{
+    /* Force turn on preedit state by symulate keypress event.
+     * Keycode and state is specified by 'imactivatekey'.
+     */
+    XKeyEvent ev;
+
+    gui_get_x11_windis(&ev.window, &ev.display);
+    ev.root = RootWindow(ev.display, DefaultScreen(ev.display));
+    ev.subwindow = None;
+    ev.time = CurrentTime;
+    ev.x = 1;
+    ev.y = 1;
+    ev.x_root = 1;
+    ev.y_root = 1;
+    ev.same_screen = 1;
+    ev.type = KeyPress;
+    if (im_xim_str2keycode(&ev.keycode, &ev.state) == OK)
+	XSendEvent(ev.display, ev.window, 1, KeyPressMask, (XEvent*)&ev);
+}
+
+/*
+ * Return TRUE if 'imactivatekey' has a valid value.
+ */
+    int
+im_xim_isvalid_imactivate()
+{
+    return im_xim_str2keycode(NULL, NULL) == OK;
+}
+#endif /* FEAT_GUI_GTK */
+
+/*
+ * Switch using XIM on/off.  This is used by the code that changes "State".
+ */
+    void
+im_set_active(active)
+    int		active;
+{
+    if (xic == NULL)
+	return;
+
+    /* If 'imdisable' is set, XIM is never active. */
+    if (p_imdisable)
+	active = FALSE;
+#if !defined (FEAT_GUI_GTK)
+    else if (input_style & XIMPreeditPosition)
+	/* There is a problem in switching XIM off when preediting is used,
+	 * and it is not clear how this can be solved.  For now, keep XIM on
+	 * all the time, like it was done in Vim 5.8. */
+	active = TRUE;
+#endif
+
+    /* Remember the active state, it is needed when Vim gets keyboard focus. */
+    xim_is_active = active;
+
+#ifdef FEAT_GUI_GTK
+    /* When 'imactivatekey' has valid key-string, try to control XIM preedit
+     * state.  When 'imactivatekey' has no or invalid string, try old XIM
+     * focus control.
+     */
+    if (*p_imak != NUL)
+    {
+	/* BASIC STRATEGY:
+	 * Destroy old Input Context (XIC), and create new one.  New XIC
+	 * would have a state of preedit that is off.  When argument:active
+	 * is false, that's all.  Else argument:active is true, send a key
+	 * event specified by 'imactivatekey' to activate XIM preedit state.
+	 */
+
+	xim_is_active = TRUE; /* Disable old XIM focus control */
+	/* If we can monitor preedit state with preedit callback functions,
+	 * try least creation of new XIC.
+	 */
+	if (xim_input_style & (int)GDK_IM_PREEDIT_CALLBACKS)
+	{
+	    if (xim_can_preediting && !active)
+	    {
+		/* Force turn off preedit state.  With some IM
+		 * implementations, we cannot turn off preedit state by
+		 * symulate keypress event.  It is why using such a method
+		 * that destroy old IC (input context), and create new one.
+		 * When create new IC, its preedit state is usually off.
+		 */
+		xim_reset();
+		xim_set_focus(FALSE);
+		gdk_ic_destroy(xic);
+		xim_init();
+		xim_can_preediting = FALSE;
+	    }
+	    else if (!xim_can_preediting && active)
+		im_xim_send_event_imactivate();
+	}
+	else
+	{
+	    /* First, force destroy old IC, and create new one.  It
+	     * symulates "turning off preedit state".
+	     */
+	    xim_set_focus(FALSE);
+	    gdk_ic_destroy(xic);
+	    xim_init();
+	    xim_can_preediting = FALSE;
+
+	    /* 2nd, when requested to activate IM, symulate this by sending
+	     * the event.
+	     */
+	    if (active)
+	    {
+		im_xim_send_event_imactivate();
+		xim_can_preediting = TRUE;
+	    }
+	}
+    }
+    else
+    {
+# ifndef XIMPreeditUnKnown
+	/* X11R5 doesn't have these, it looks safe enough to define here. */
+	typedef unsigned long XIMPreeditState;
+#  define XIMPreeditUnKnown	0L
+#  define XIMPreeditEnable	1L
+#  define XIMPreeditDisable	(1L<<1)
+#  define XNPreeditState	"preeditState"
+# endif
+	XIMPreeditState preedit_state = XIMPreeditUnKnown;
+	XVaNestedList preedit_attr;
+	XIC pxic;
+
+	preedit_attr = XVaCreateNestedList(0,
+				XNPreeditState, &preedit_state,
+				NULL);
+	pxic = ((GdkICPrivate *)xic)->xic;
+
+	if (!XGetICValues(pxic, XNPreeditAttributes, preedit_attr, NULL))
+	{
+	    XFree(preedit_attr);
+	    preedit_attr = XVaCreateNestedList(0,
+				XNPreeditState,
+				active ? XIMPreeditEnable : XIMPreeditDisable,
+				NULL);
+	    XSetICValues(pxic, XNPreeditAttributes, preedit_attr, NULL);
+	    xim_can_preediting = active;
+	    xim_is_active = active;
+	}
+	XFree(preedit_attr);
+    }
+    if (xim_input_style & XIMPreeditCallbacks)
+    {
+	preedit_buf_len = 0;
+	init_preedit_start_col();
+    }
+#else
+# if 0
+	/* When had tested kinput2 + canna + Athena GUI version with
+	 * 'imactivatekey' is "s-space", im_xim_send_event_imactivate() did not
+	 * work correctly.  It just inserted one space.  I don't know why we
+	 * couldn't switch state of XIM preediting.  This is reason why these
+	 * codes are commented out.
+	 */
+	/* First, force destroy old IC, and create new one.  It symulates
+	 * "turning off preedit state".
+	 */
+	xim_set_focus(FALSE);
+	XDestroyIC(xic);
+	xic = NULL;
+	xim_init();
+
+	/* 2nd, when requested to activate IM, symulate this by sending the
+	 * event.
+	 */
+	if (active)
+	    im_xim_send_event_imactivate();
+# endif
+#endif
+    xim_set_preedit();
+}
+
+/*
+ * Adjust using XIM for gaining or losing keyboard focus.  Also called when
+ * "xim_is_active" changes.
+ */
+    void
+xim_set_focus(focus)
+    int		focus;
+{
+    if (xic == NULL)
+	return;
+
+    /*
+     * XIM only gets focus when the Vim window has keyboard focus and XIM has
+     * been set active for the current mode.
+     */
+    if (focus && xim_is_active)
+    {
+	if (!xim_has_focus)
+	{
+	    xim_has_focus = TRUE;
+#ifdef FEAT_GUI_GTK
+	    gdk_im_begin(xic, gui.drawarea->window);
+#else
+	    XSetICFocus(xic);
+#endif
+	}
+    }
+    else
+    {
+	if (xim_has_focus)
+	{
+	    xim_has_focus = FALSE;
+#ifdef FEAT_GUI_GTK
+	    gdk_im_end();
+#else
+	    XUnsetICFocus(xic);
+#endif
+	}
+    }
+}
+
+/*ARGSUSED*/
+    void
+im_set_position(row, col)
+    int		row;
+    int		col;
+{
+    xim_set_preedit();
+}
+
+/*
+ * Set the XIM to the current cursor position.
+ */
+    void
+xim_set_preedit()
+{
+    if (xic == NULL)
+	return;
+
+    xim_set_focus(TRUE);
+
+#ifdef FEAT_GUI_GTK
+    if (gdk_im_ready())
+    {
+	int		attrmask;
+	GdkICAttr	*attr;
+
+	if (!xic_attr)
+	    return;
+
+	attr = xic_attr;
+	attrmask = 0;
+
+# ifdef FEAT_XFONTSET
+	if ((xim_input_style & (int)GDK_IM_PREEDIT_POSITION)
+		&& gui.fontset != NOFONTSET
+		&& gui.fontset->type == GDK_FONT_FONTSET)
+	{
+	    if (!xim_has_focus)
+	    {
+		if (attr->spot_location.y >= 0)
+		{
+		    attr->spot_location.x = 0;
+		    attr->spot_location.y = -100;
+		    attrmask |= (int)GDK_IC_SPOT_LOCATION;
+		}
+	    }
+	    else
+	    {
+		gint	width, height;
+
+		if (attr->spot_location.x != TEXT_X(gui.col)
+		    || attr->spot_location.y != TEXT_Y(gui.row))
+		{
+		    attr->spot_location.x = TEXT_X(gui.col);
+		    attr->spot_location.y = TEXT_Y(gui.row);
+		    attrmask |= (int)GDK_IC_SPOT_LOCATION;
+		}
+
+		gdk_window_get_size(gui.drawarea->window, &width, &height);
+		width -= 2 * gui.border_offset;
+		height -= 2 * gui.border_offset;
+		if (xim_input_style & (int)GDK_IM_STATUS_AREA)
+		    height -= gui.char_height;
+		if (attr->preedit_area.width != width
+		    || attr->preedit_area.height != height)
+		{
+		    attr->preedit_area.x = gui.border_offset;
+		    attr->preedit_area.y = gui.border_offset;
+		    attr->preedit_area.width = width;
+		    attr->preedit_area.height = height;
+		    attrmask |= (int)GDK_IC_PREEDIT_AREA;
+		}
+
+		if (attr->preedit_fontset != gui.current_font)
+		{
+		    attr->preedit_fontset = gui.current_font;
+		    attrmask |= (int)GDK_IC_PREEDIT_FONTSET;
+		}
+	    }
+	}
+# endif /* FEAT_XFONTSET */
+
+	if (xim_fg_color == INVALCOLOR)
+	{
+	    xim_fg_color = gui.def_norm_pixel;
+	    xim_bg_color = gui.def_back_pixel;
+	}
+	if (attr->preedit_foreground.pixel != xim_fg_color)
+	{
+	    attr->preedit_foreground.pixel = xim_fg_color;
+	    attrmask |= (int)GDK_IC_PREEDIT_FOREGROUND;
+	}
+	if (attr->preedit_background.pixel != xim_bg_color)
+	{
+	    attr->preedit_background.pixel = xim_bg_color;
+	    attrmask |= (int)GDK_IC_PREEDIT_BACKGROUND;
+	}
+
+	if (attrmask != 0)
+	    gdk_ic_set_attr(xic, attr, (GdkICAttributesType)attrmask);
+    }
+#else /* FEAT_GUI_GTK */
+    {
+	XVaNestedList attr_list;
+	XRectangle spot_area;
+	XPoint over_spot;
+	int line_space;
+
+	if (!xim_has_focus)
+	{
+	    /* hide XIM cursor */
+	    over_spot.x = 0;
+	    over_spot.y = -100; /* arbitrary invisible position */
+	    attr_list = (XVaNestedList) XVaCreateNestedList(0,
+							    XNSpotLocation,
+							    &over_spot,
+							    NULL);
+	    XSetICValues(xic, XNPreeditAttributes, attr_list, NULL);
+	    XFree(attr_list);
+	    return;
+	}
+
+	if (input_style & XIMPreeditPosition)
+	{
+	    if (xim_fg_color == INVALCOLOR)
+	    {
+		xim_fg_color = gui.def_norm_pixel;
+		xim_bg_color = gui.def_back_pixel;
+	    }
+	    over_spot.x = TEXT_X(gui.col);
+	    over_spot.y = TEXT_Y(gui.row);
+	    spot_area.x = 0;
+	    spot_area.y = 0;
+	    spot_area.height = gui.char_height * Rows;
+	    spot_area.width  = gui.char_width * Columns;
+	    line_space = gui.char_height;
+	    attr_list = (XVaNestedList) XVaCreateNestedList(0,
+					    XNSpotLocation, &over_spot,
+					    XNForeground, (Pixel) xim_fg_color,
+					    XNBackground, (Pixel) xim_bg_color,
+					    XNArea, &spot_area,
+					    XNLineSpace, line_space,
+					    NULL);
+	    if (XSetICValues(xic, XNPreeditAttributes, attr_list, NULL))
+		EMSG(_("E284: Cannot set IC values"));
+	    XFree(attr_list);
+	}
+    }
+#endif /* FEAT_GUI_GTK */
+}
+
+/*
+ * Set up the status area.
+ *
+ * This should use a separate Widget, but that seems not possible, because
+ * preedit_area and status_area should be set to the same window as for the
+ * text input.  Unfortunately this means the status area pollutes the text
+ * window...
+ */
+    void
+xim_set_status_area()
+{
+    if (xic == NULL)
+	return;
+
+#ifdef FEAT_GUI_GTK
+# if defined(FEAT_XFONTSET)
+    if (use_status_area)
+    {
+	GdkICAttr	*attr;
+	int		style;
+	gint		width, height;
+	GtkWidget	*widget;
+	int		attrmask;
+
+	if (!xic_attr)
+	    return;
+
+	attr = xic_attr;
+	attrmask = 0;
+	style = (int)gdk_ic_get_style(xic);
+	if ((style & (int)GDK_IM_STATUS_MASK) == (int)GDK_IM_STATUS_AREA)
+	{
+	    if (gui.fontset != NOFONTSET
+		    && gui.fontset->type == GDK_FONT_FONTSET)
+	    {
+		widget = gui.mainwin;
+		gdk_window_get_size(widget->window, &width, &height);
+
+		attrmask |= (int)GDK_IC_STATUS_AREA;
+		attr->status_area.x = 0;
+		attr->status_area.y = height - gui.char_height - 1;
+		attr->status_area.width = width;
+		attr->status_area.height = gui.char_height;
+	    }
+	}
+	if (attrmask != 0)
+	    gdk_ic_set_attr(xic, attr, (GdkICAttributesType)attrmask);
+    }
+# endif
+#else
+    {
+	XVaNestedList preedit_list = 0, status_list = 0, list = 0;
+	XRectangle pre_area, status_area;
+
+	if (input_style & XIMStatusArea)
+	{
+	    if (input_style & XIMPreeditArea)
+	    {
+		XRectangle *needed_rect;
+
+		/* to get status_area width */
+		status_list = XVaCreateNestedList(0, XNAreaNeeded,
+						  &needed_rect, NULL);
+		XGetICValues(xic, XNStatusAttributes, status_list, NULL);
+		XFree(status_list);
+
+		status_area.width = needed_rect->width;
+	    }
+	    else
+		status_area.width = gui.char_width * Columns;
+
+	    status_area.x = 0;
+	    status_area.y = gui.char_height * Rows + gui.border_offset;
+	    if (gui.which_scrollbars[SBAR_BOTTOM])
+		status_area.y += gui.scrollbar_height;
+#ifdef FEAT_MENU
+	    if (gui.menu_is_active)
+		status_area.y += gui.menu_height;
+#endif
+	    status_area.height = gui.char_height;
+	    status_list = XVaCreateNestedList(0, XNArea, &status_area, NULL);
+	}
+	else
+	{
+	    status_area.x = 0;
+	    status_area.y = gui.char_height * Rows + gui.border_offset;
+	    if (gui.which_scrollbars[SBAR_BOTTOM])
+		status_area.y += gui.scrollbar_height;
+#ifdef FEAT_MENU
+	    if (gui.menu_is_active)
+		status_area.y += gui.menu_height;
+#endif
+	    status_area.width = 0;
+	    status_area.height = gui.char_height;
+	}
+
+	if (input_style & XIMPreeditArea)   /* off-the-spot */
+	{
+	    pre_area.x = status_area.x + status_area.width;
+	    pre_area.y = gui.char_height * Rows + gui.border_offset;
+	    pre_area.width = gui.char_width * Columns - pre_area.x;
+	    if (gui.which_scrollbars[SBAR_BOTTOM])
+		pre_area.y += gui.scrollbar_height;
+#ifdef FEAT_MENU
+	    if (gui.menu_is_active)
+		pre_area.y += gui.menu_height;
+#endif
+	    pre_area.height = gui.char_height;
+	    preedit_list = XVaCreateNestedList(0, XNArea, &pre_area, NULL);
+	}
+	else if (input_style & XIMPreeditPosition)   /* over-the-spot */
+	{
+	    pre_area.x = 0;
+	    pre_area.y = 0;
+	    pre_area.height = gui.char_height * Rows;
+	    pre_area.width = gui.char_width * Columns;
+	    preedit_list = XVaCreateNestedList(0, XNArea, &pre_area, NULL);
+	}
+
+	if (preedit_list && status_list)
+	    list = XVaCreateNestedList(0, XNPreeditAttributes, preedit_list,
+				       XNStatusAttributes, status_list, NULL);
+	else if (preedit_list)
+	    list = XVaCreateNestedList(0, XNPreeditAttributes, preedit_list,
+				       NULL);
+	else if (status_list)
+	    list = XVaCreateNestedList(0, XNStatusAttributes, status_list,
+				       NULL);
+	else
+	    list = NULL;
+
+	if (list)
+	{
+	    XSetICValues(xic, XNVaNestedList, list, NULL);
+	    XFree(list);
+	}
+	if (status_list)
+	    XFree(status_list);
+	if (preedit_list)
+	    XFree(preedit_list);
+    }
+#endif
+}
+
+#if defined(FEAT_GUI_X11) || defined(FEAT_GUI_GTK)
+static char e_xim[] = N_("E285: Failed to create input context");
+#endif
+
+#if defined(FEAT_GUI_X11) || defined(PROTO)
+# if defined(XtSpecificationRelease) && XtSpecificationRelease >= 6 && !defined(sun)
+#  define USE_X11R6_XIM
+# endif
+
+static int xim_real_init __ARGS((Window x11_window, Display *x11_display));
+
+
+#ifdef USE_X11R6_XIM
+static void xim_instantiate_cb __ARGS((Display *display, XPointer client_data, XPointer	call_data));
+static void xim_destroy_cb __ARGS((XIM im, XPointer client_data, XPointer call_data));
+
+/*ARGSUSED*/
+    static void
+xim_instantiate_cb(display, client_data, call_data)
+    Display	*display;
+    XPointer	client_data;
+    XPointer	call_data;
+{
+    Window	x11_window;
+    Display	*x11_display;
+
+#ifdef XIM_DEBUG
+    xim_log("xim_instantiate_cb()\n");
+#endif
+
+    gui_get_x11_windis(&x11_window, &x11_display);
+    if (display != x11_display)
+	return;
+
+    xim_real_init(x11_window, x11_display);
+    gui_set_shellsize(FALSE, FALSE, RESIZE_BOTH);
+    if (xic != NULL)
+	XUnregisterIMInstantiateCallback(x11_display, NULL, NULL, NULL,
+					 xim_instantiate_cb, NULL);
+}
+
+/*ARGSUSED*/
+    static void
+xim_destroy_cb(im, client_data, call_data)
+    XIM		im;
+    XPointer	client_data;
+    XPointer	call_data;
+{
+    Window	x11_window;
+    Display	*x11_display;
+
+#ifdef XIM_DEBUG
+    xim_log("xim_destroy_cb()\n");
+#endif
+    gui_get_x11_windis(&x11_window, &x11_display);
+
+    xic = NULL;
+    status_area_enabled = FALSE;
+
+    gui_set_shellsize(FALSE, FALSE, RESIZE_BOTH);
+
+    XRegisterIMInstantiateCallback(x11_display, NULL, NULL, NULL,
+				   xim_instantiate_cb, NULL);
+}
+#endif
+
+    void
+xim_init()
+{
+    Window	x11_window;
+    Display	*x11_display;
+
+#ifdef XIM_DEBUG
+    xim_log("xim_init()\n");
+#endif
+
+    gui_get_x11_windis(&x11_window, &x11_display);
+
+    xic = NULL;
+
+    if (xim_real_init(x11_window, x11_display))
+	return;
+
+    gui_set_shellsize(FALSE, FALSE, RESIZE_BOTH);
+
+#ifdef USE_X11R6_XIM
+    XRegisterIMInstantiateCallback(x11_display, NULL, NULL, NULL,
+				   xim_instantiate_cb, NULL);
+#endif
+}
+
+    static int
+xim_real_init(x11_window, x11_display)
+    Window	x11_window;
+    Display	*x11_display;
+{
+    int		i;
+    char	*p,
+		*s,
+		*ns,
+		*end,
+		tmp[1024];
+#define IMLEN_MAX 40
+    char	buf[IMLEN_MAX + 7];
+    XIM		xim = NULL;
+    XIMStyles	*xim_styles;
+    XIMStyle	this_input_style = 0;
+    Boolean	found;
+    XPoint	over_spot;
+    XVaNestedList preedit_list, status_list;
+
+    input_style = 0;
+    status_area_enabled = FALSE;
+
+    if (xic != NULL)
+	return FALSE;
+
+    if (gui.rsrc_input_method != NULL && *gui.rsrc_input_method != NUL)
+    {
+	strcpy(tmp, gui.rsrc_input_method);
+	for (ns = s = tmp; ns != NULL && *s != NUL;)
+	{
+	    s = (char *)skipwhite((char_u *)s);
+	    if (*s == NUL)
+		break;
+	    if ((ns = end = strchr(s, ',')) == NULL)
+		end = s + strlen(s);
+	    while (isspace(((char_u *)end)[-1]))
+		end--;
+	    *end = NUL;
+
+	    if (strlen(s) <= IMLEN_MAX)
+	    {
+		strcpy(buf, "@im=");
+		strcat(buf, s);
+		if ((p = XSetLocaleModifiers(buf)) != NULL && *p != NUL
+			&& (xim = XOpenIM(x11_display, NULL, NULL, NULL))
+								      != NULL)
+		    break;
+	    }
+
+	    s = ns + 1;
+	}
+    }
+
+    if (xim == NULL && (p = XSetLocaleModifiers("")) != NULL && *p != NUL)
+	xim = XOpenIM(x11_display, NULL, NULL, NULL);
+
+    /* This is supposed to be useful to obtain characters through
+     * XmbLookupString() without really using a XIM. */
+    if (xim == NULL && (p = XSetLocaleModifiers("@im=none")) != NULL
+								 && *p != NUL)
+	xim = XOpenIM(x11_display, NULL, NULL, NULL);
+
+    if (xim == NULL)
+    {
+	/* Only give this message when verbose is set, because too many people
+	 * got this message when they didn't want to use a XIM. */
+	if (p_verbose > 0)
+	{
+	    verbose_enter();
+	    EMSG(_("E286: Failed to open input method"));
+	    verbose_leave();
+	}
+	return FALSE;
+    }
+
+#ifdef USE_X11R6_XIM
+    {
+	XIMCallback destroy_cb;
+
+	destroy_cb.callback = xim_destroy_cb;
+	destroy_cb.client_data = NULL;
+	if (XSetIMValues(xim, XNDestroyCallback, &destroy_cb, NULL))
+	    EMSG(_("E287: Warning: Could not set destroy callback to IM"));
+    }
+#endif
+
+    if (XGetIMValues(xim, XNQueryInputStyle, &xim_styles, NULL) || !xim_styles)
+    {
+	EMSG(_("E288: input method doesn't support any style"));
+	XCloseIM(xim);
+	return FALSE;
+    }
+
+    found = False;
+    strcpy(tmp, gui.rsrc_preedit_type_name);
+    for (s = tmp; s && !found; )
+    {
+	while (*s && isspace((unsigned char)*s))
+	    s++;
+	if (!*s)
+	    break;
+	if ((ns = end = strchr(s, ',')) != 0)
+	    ns++;
+	else
+	    end = s + strlen(s);
+	while (isspace((unsigned char)*end))
+	    end--;
+	*end = '\0';
+
+	if (!strcmp(s, "OverTheSpot"))
+	    this_input_style = (XIMPreeditPosition | XIMStatusArea);
+	else if (!strcmp(s, "OffTheSpot"))
+	    this_input_style = (XIMPreeditArea | XIMStatusArea);
+	else if (!strcmp(s, "Root"))
+	    this_input_style = (XIMPreeditNothing | XIMStatusNothing);
+
+	for (i = 0; (unsigned short)i < xim_styles->count_styles; i++)
+	{
+	    if (this_input_style == xim_styles->supported_styles[i])
+	    {
+		found = True;
+		break;
+	    }
+	}
+	if (!found)
+	    for (i = 0; (unsigned short)i < xim_styles->count_styles; i++)
+	    {
+		if ((xim_styles->supported_styles[i] & this_input_style)
+			== (this_input_style & ~XIMStatusArea))
+		{
+		    this_input_style &= ~XIMStatusArea;
+		    found = True;
+		    break;
+		}
+	    }
+
+	s = ns;
+    }
+    XFree(xim_styles);
+
+    if (!found)
+    {
+	/* Only give this message when verbose is set, because too many people
+	 * got this message when they didn't want to use a XIM. */
+	if (p_verbose > 0)
+	{
+	    verbose_enter();
+	    EMSG(_("E289: input method doesn't support my preedit type"));
+	    verbose_leave();
+	}
+	XCloseIM(xim);
+	return FALSE;
+    }
+
+    over_spot.x = TEXT_X(gui.col);
+    over_spot.y = TEXT_Y(gui.row);
+    input_style = this_input_style;
+
+    /* A crash was reported when trying to pass gui.norm_font as XNFontSet,
+     * thus that has been removed.  Hopefully the default works... */
+#ifdef FEAT_XFONTSET
+    if (gui.fontset != NOFONTSET)
+    {
+	preedit_list = XVaCreateNestedList(0,
+				XNSpotLocation, &over_spot,
+				XNForeground, (Pixel)gui.def_norm_pixel,
+				XNBackground, (Pixel)gui.def_back_pixel,
+				XNFontSet, (XFontSet)gui.fontset,
+				NULL);
+	status_list = XVaCreateNestedList(0,
+				XNForeground, (Pixel)gui.def_norm_pixel,
+				XNBackground, (Pixel)gui.def_back_pixel,
+				XNFontSet, (XFontSet)gui.fontset,
+				NULL);
+    }
+    else
+#endif
+    {
+	preedit_list = XVaCreateNestedList(0,
+				XNSpotLocation, &over_spot,
+				XNForeground, (Pixel)gui.def_norm_pixel,
+				XNBackground, (Pixel)gui.def_back_pixel,
+				NULL);
+	status_list = XVaCreateNestedList(0,
+				XNForeground, (Pixel)gui.def_norm_pixel,
+				XNBackground, (Pixel)gui.def_back_pixel,
+				NULL);
+    }
+
+    xic = XCreateIC(xim,
+		    XNInputStyle, input_style,
+		    XNClientWindow, x11_window,
+		    XNFocusWindow, gui.wid,
+		    XNPreeditAttributes, preedit_list,
+		    XNStatusAttributes, status_list,
+		    NULL);
+    XFree(status_list);
+    XFree(preedit_list);
+    if (xic != NULL)
+    {
+	if (input_style & XIMStatusArea)
+	{
+	    xim_set_status_area();
+	    status_area_enabled = TRUE;
+	}
+	else
+	    gui_set_shellsize(FALSE, FALSE, RESIZE_BOTH);
+    }
+    else
+    {
+	EMSG(_(e_xim));
+	XCloseIM(xim);
+	return FALSE;
+    }
+
+    return TRUE;
+}
+
+#endif /* FEAT_GUI_X11 */
+
+#if defined(FEAT_GUI_GTK) || defined(PROTO)
+
+# ifdef FEAT_XFONTSET
+static char e_overthespot[] = N_("E290: over-the-spot style requires fontset");
+# endif
+
+# ifdef PROTO
+typedef int GdkIC;
+# endif
+
+    void
+xim_decide_input_style()
+{
+    /* GDK_IM_STATUS_CALLBACKS was disabled, enabled it to allow Japanese
+     * OverTheSpot. */
+    int supported_style = (int)GDK_IM_PREEDIT_NONE |
+				 (int)GDK_IM_PREEDIT_NOTHING |
+				 (int)GDK_IM_PREEDIT_POSITION |
+				 (int)GDK_IM_PREEDIT_CALLBACKS |
+				 (int)GDK_IM_STATUS_CALLBACKS |
+				 (int)GDK_IM_STATUS_AREA |
+				 (int)GDK_IM_STATUS_NONE |
+				 (int)GDK_IM_STATUS_NOTHING;
+
+#ifdef XIM_DEBUG
+    xim_log("xim_decide_input_style()\n");
+#endif
+
+    if (!gdk_im_ready())
+	xim_input_style = 0;
+    else
+    {
+	if (gtk_major_version > 1
+		|| (gtk_major_version == 1
+		    && (gtk_minor_version > 2
+			|| (gtk_minor_version == 2 && gtk_micro_version >= 3))))
+	    use_status_area = TRUE;
+	else
+	{
+	    EMSG(_("E291: Your GTK+ is older than 1.2.3. Status area disabled"));
+	    use_status_area = FALSE;
+	}
+#ifdef FEAT_XFONTSET
+	if (gui.fontset == NOFONTSET || gui.fontset->type != GDK_FONT_FONTSET)
+#endif
+	    supported_style &= ~((int)GDK_IM_PREEDIT_POSITION
+						   | (int)GDK_IM_STATUS_AREA);
+	if (!use_status_area)
+	    supported_style &= ~(int)GDK_IM_STATUS_AREA;
+	xim_input_style = (int)gdk_im_decide_style((GdkIMStyle)supported_style);
+    }
+}
+
+/*ARGSUSED*/
+    static void
+preedit_start_cbproc(XIC xic, XPointer client_data, XPointer call_data)
+{
+#ifdef XIM_DEBUG
+    xim_log("xim_decide_input_style()\n");
+#endif
+
+    draw_feedback = NULL;
+    xim_can_preediting = TRUE;
+    xim_has_preediting = TRUE;
+    gui_update_cursor(TRUE, FALSE);
+    if (showmode() > 0)
+    {
+	setcursor();
+	out_flush();
+    }
+}
+
+    static void
+xim_back_delete(int n)
+{
+    char_u str[3];
+
+    str[0] = CSI;
+    str[1] = 'k';
+    str[2] = 'b';
+    while (n-- > 0)
+	add_to_input_buf(str, 3);
+}
+
+static GSList *key_press_event_queue = NULL;
+static gboolean processing_queued_event = FALSE;
+
+/*ARGSUSED*/
+    static void
+preedit_draw_cbproc(XIC xic, XPointer client_data, XPointer call_data)
+{
+    XIMPreeditDrawCallbackStruct *draw_data;
+    XIMText	*text;
+    char	*src;
+    GSList	*event_queue;
+
+#ifdef XIM_DEBUG
+    xim_log("preedit_draw_cbproc()\n");
+#endif
+
+    draw_data = (XIMPreeditDrawCallbackStruct *) call_data;
+    text = (XIMText *) draw_data->text;
+
+    if ((text == NULL && draw_data->chg_length == preedit_buf_len)
+						      || preedit_buf_len == 0)
+    {
+	init_preedit_start_col();
+	vim_free(draw_feedback);
+	draw_feedback = NULL;
+    }
+    if (draw_data->chg_length > 0)
+    {
+	int bs_cnt;
+
+	if (draw_data->chg_length > preedit_buf_len)
+	    bs_cnt = preedit_buf_len;
+	else
+	    bs_cnt = draw_data->chg_length;
+	xim_back_delete(bs_cnt);
+	preedit_buf_len -= bs_cnt;
+    }
+    if (text != NULL)
+    {
+	int		len;
+#ifdef FEAT_MBYTE
+	char_u		*buf = NULL;
+	unsigned int	nfeedback = 0;
+#endif
+	char_u		*ptr;
+
+	src = text->string.multi_byte;
+	if (src != NULL && !text->encoding_is_wchar)
+	{
+	    len = strlen(src);
+	    ptr = (char_u *)src;
+	    /* Avoid the enter for decision */
+	    if (*ptr == '\n')
+		return;
+
+#ifdef FEAT_MBYTE
+	    if (input_conv.vc_type != CONV_NONE
+		    && (buf = string_convert(&input_conv,
+						 (char_u *)src, &len)) != NULL)
+	    {
+		/* Converted from 'termencoding' to 'encoding'. */
+		add_to_input_buf_csi(buf, len);
+		ptr = buf;
+	    }
+	    else
+#endif
+		add_to_input_buf_csi((char_u *)src, len);
+	    /* Add count of character to preedit_buf_len  */
+	    while (*ptr != NUL)
+	    {
+#ifdef FEAT_MBYTE
+		if (draw_data->text->feedback != NULL)
+		{
+		    if (draw_feedback == NULL)
+			draw_feedback = (char *)alloc(draw_data->chg_first
+							      + text->length);
+		    else
+			draw_feedback = realloc(draw_feedback,
+					 draw_data->chg_first + text->length);
+		    if (draw_feedback != NULL)
+		    {
+			draw_feedback[nfeedback + draw_data->chg_first]
+				       = draw_data->text->feedback[nfeedback];
+			nfeedback++;
+		    }
+		}
+		if (has_mbyte)
+		    ptr += (*mb_ptr2len)(ptr);
+		else
+#endif
+		    ptr++;
+		preedit_buf_len++;
+	    }
+#ifdef FEAT_MBYTE
+	    vim_free(buf);
+#endif
+	    preedit_end_col = MAXCOL;
+	}
+    }
+    if (text != NULL || draw_data->chg_length > 0)
+    {
+	event_queue = key_press_event_queue;
+	processing_queued_event = TRUE;
+	while (event_queue != NULL && processing_queued_event)
+	{
+	    GdkEvent *ev = event_queue->data;
+
+	    gboolean *ret;
+	    gtk_signal_emit_by_name((GtkObject*)gui.mainwin, "key_press_event",
+								    ev, &ret);
+	    gdk_event_free(ev);
+	    event_queue = event_queue->next;
+	}
+	processing_queued_event = FALSE;
+	if (key_press_event_queue)
+	{
+	    g_slist_free(key_press_event_queue);
+	    key_press_event_queue = NULL;
+	}
+    }
+    if (gtk_main_level() > 0)
+	gtk_main_quit();
+}
+
+/*
+ * Retrieve the highlighting attributes at column col in the preedit string.
+ * Return -1 if not in preediting mode or if col is out of range.
+ */
+    int
+im_get_feedback_attr(int col)
+{
+    if (draw_feedback != NULL && col < preedit_buf_len)
+    {
+	if (draw_feedback[col] & XIMReverse)
+	    return HL_INVERSE;
+	else if (draw_feedback[col] & XIMUnderline)
+	    return HL_UNDERLINE;
+	else
+	    return hl_attr(HLF_V);
+    }
+
+    return -1;
+}
+
+/*ARGSUSED*/
+    static void
+preedit_caret_cbproc(XIC xic, XPointer client_data, XPointer call_data)
+{
+#ifdef XIM_DEBUG
+    xim_log("preedit_caret_cbproc()\n");
+#endif
+}
+
+/*ARGSUSED*/
+    static void
+preedit_done_cbproc(XIC xic, XPointer client_data, XPointer call_data)
+{
+#ifdef XIM_DEBUG
+    xim_log("preedit_done_cbproc()\n");
+#endif
+
+    vim_free(draw_feedback);
+    draw_feedback = NULL;
+    xim_can_preediting = FALSE;
+    xim_has_preediting = FALSE;
+    gui_update_cursor(TRUE, FALSE);
+    if (showmode() > 0)
+    {
+	setcursor();
+	out_flush();
+    }
+}
+
+    void
+xim_reset(void)
+{
+    char *text;
+
+#ifdef XIM_DEBUG
+    xim_log("xim_reset()\n");
+#endif
+
+    if (xic != NULL)
+    {
+	text = XmbResetIC(((GdkICPrivate *)xic)->xic);
+	if (text != NULL && !(xim_input_style & (int)GDK_IM_PREEDIT_CALLBACKS))
+	    add_to_input_buf_csi((char_u *)text, strlen(text));
+	else
+	    preedit_buf_len = 0;
+	if (text != NULL)
+	    XFree(text);
+    }
+}
+
+/*ARGSUSED*/
+    int
+xim_queue_key_press_event(GdkEventKey *event, int down)
+{
+#ifdef XIM_DEBUG
+    xim_log("xim_queue_key_press_event()\n");
+#endif
+
+    if (preedit_buf_len <= 0)
+	return FALSE;
+    if (processing_queued_event)
+	processing_queued_event = FALSE;
+
+    key_press_event_queue = g_slist_append(key_press_event_queue,
+					   gdk_event_copy((GdkEvent *)event));
+    return TRUE;
+}
+
+/*ARGSUSED*/
+    static void
+preedit_callback_setup(GdkIC *ic)
+{
+    XIC xxic;
+    XVaNestedList preedit_attr;
+    XIMCallback preedit_start_cb;
+    XIMCallback preedit_draw_cb;
+    XIMCallback preedit_caret_cb;
+    XIMCallback preedit_done_cb;
+
+    xxic = ((GdkICPrivate*)xic)->xic;
+    preedit_start_cb.callback = (XIMProc)preedit_start_cbproc;
+    preedit_draw_cb.callback = (XIMProc)preedit_draw_cbproc;
+    preedit_caret_cb.callback = (XIMProc)preedit_caret_cbproc;
+    preedit_done_cb.callback = (XIMProc)preedit_done_cbproc;
+    preedit_attr
+	= XVaCreateNestedList (0,
+			       XNPreeditStartCallback, &preedit_start_cb,
+			       XNPreeditDrawCallback, &preedit_draw_cb,
+			       XNPreeditCaretCallback, &preedit_caret_cb,
+			       XNPreeditDoneCallback, &preedit_done_cb,
+			       0);
+    XSetICValues (xxic, XNPreeditAttributes, preedit_attr, 0);
+    XFree(preedit_attr);
+}
+
+/*ARGSUSED*/
+    static void
+reset_state_setup(GdkIC *ic)
+{
+#ifdef USE_X11R6_XIM
+    /* don't change the input context when we call reset */
+    XSetICValues(((GdkICPrivate*)ic)->xic, XNResetState, XIMPreserveState, 0);
+#endif
+}
+
+    void
+xim_init(void)
+{
+#ifdef XIM_DEBUG
+    xim_log("xim_init()\n");
+#endif
+
+    xic = NULL;
+    xic_attr = NULL;
+
+    if (!gdk_im_ready())
+    {
+	if (p_verbose > 0)
+	{
+	    verbose_enter();
+	    EMSG(_("E292: Input Method Server is not running"));
+	    verbose_leave();
+	}
+	return;
+    }
+    if ((xic_attr = gdk_ic_attr_new()) != NULL)
+    {
+#ifdef FEAT_XFONTSET
+	gint width, height;
+#endif
+	int		mask;
+	GdkColormap	*colormap;
+	GdkICAttr	*attr = xic_attr;
+	int		attrmask = (int)GDK_IC_ALL_REQ;
+	GtkWidget	*widget = gui.drawarea;
+
+	attr->style = (GdkIMStyle)xim_input_style;
+	attr->client_window = gui.mainwin->window;
+
+	if ((colormap = gtk_widget_get_colormap(widget)) !=
+	    gtk_widget_get_default_colormap())
+	{
+	    attrmask |= (int)GDK_IC_PREEDIT_COLORMAP;
+	    attr->preedit_colormap = colormap;
+	}
+	attrmask |= (int)GDK_IC_PREEDIT_FOREGROUND;
+	attrmask |= (int)GDK_IC_PREEDIT_BACKGROUND;
+	attr->preedit_foreground = widget->style->fg[GTK_STATE_NORMAL];
+	attr->preedit_background = widget->style->base[GTK_STATE_NORMAL];
+
+#ifdef FEAT_XFONTSET
+	if ((xim_input_style & (int)GDK_IM_PREEDIT_MASK)
+					      == (int)GDK_IM_PREEDIT_POSITION)
+	{
+	    if (gui.fontset == NOFONTSET
+		    || gui.fontset->type != GDK_FONT_FONTSET)
+	    {
+		EMSG(_(e_overthespot));
+	    }
+	    else
+	    {
+		gdk_window_get_size(widget->window, &width, &height);
+
+		attrmask |= (int)GDK_IC_PREEDIT_POSITION_REQ;
+		attr->spot_location.x = TEXT_X(0);
+		attr->spot_location.y = TEXT_Y(0);
+		attr->preedit_area.x = gui.border_offset;
+		attr->preedit_area.y = gui.border_offset;
+		attr->preedit_area.width = width - 2*gui.border_offset;
+		attr->preedit_area.height = height - 2*gui.border_offset;
+		attr->preedit_fontset = gui.fontset;
+	    }
+	}
+
+	if ((xim_input_style & (int)GDK_IM_STATUS_MASK)
+						   == (int)GDK_IM_STATUS_AREA)
+	{
+	    if (gui.fontset == NOFONTSET
+		    || gui.fontset->type != GDK_FONT_FONTSET)
+	    {
+		EMSG(_(e_overthespot));
+	    }
+	    else
+	    {
+		gdk_window_get_size(gui.mainwin->window, &width, &height);
+		attrmask |= (int)GDK_IC_STATUS_AREA_REQ;
+		attr->status_area.x = 0;
+		attr->status_area.y = height - gui.char_height - 1;
+		attr->status_area.width = width;
+		attr->status_area.height = gui.char_height;
+		attr->status_fontset = gui.fontset;
+	    }
+	}
+	else if ((xim_input_style & (int)GDK_IM_STATUS_MASK)
+					      == (int)GDK_IM_STATUS_CALLBACKS)
+	{
+	    /* FIXME */
+	}
+#endif
+
+	xic = gdk_ic_new(attr, (GdkICAttributesType)attrmask);
+
+	if (xic == NULL)
+	    EMSG(_(e_xim));
+	else
+	{
+	    mask = (int)gdk_window_get_events(widget->window);
+	    mask |= (int)gdk_ic_get_events(xic);
+	    gdk_window_set_events(widget->window, (GdkEventMask)mask);
+	    if (xim_input_style & (int)GDK_IM_PREEDIT_CALLBACKS)
+		preedit_callback_setup(xic);
+	    reset_state_setup(xic);
+	}
+    }
+}
+
+    void
+im_shutdown(void)
+{
+#ifdef XIM_DEBUG
+    xim_log("im_shutdown()\n");
+#endif
+
+    if (xic != NULL)
+    {
+	gdk_im_end();
+	gdk_ic_destroy(xic);
+	xic = NULL;
+    }
+    xim_is_active = FALSE;
+    xim_can_preediting = FALSE;
+    preedit_start_col = MAXCOL;
+    xim_has_preediting = FALSE;
+}
+
+#endif /* FEAT_GUI_GTK */
+
+    int
+xim_get_status_area_height()
+{
+#ifdef FEAT_GUI_GTK
+    if (xim_input_style & (int)GDK_IM_STATUS_AREA)
+	return gui.char_height;
+#else
+    if (status_area_enabled)
+	return gui.char_height;
+#endif
+    return 0;
+}
+
+/*
+ * Get IM status.  When IM is on, return TRUE.  Else return FALSE.
+ * FIXME: This doesn't work correctly: Having focus doesn't always mean XIM is
+ * active, when not having focus XIM may still be active (e.g., when using a
+ * tear-off menu item).
+ */
+    int
+im_get_status()
+{
+#  ifdef FEAT_GUI_GTK
+    if (xim_input_style & (int)GDK_IM_PREEDIT_CALLBACKS)
+	return xim_can_preediting;
+#  endif
+    return xim_has_focus;
+}
+
+# endif /* !HAVE_GTK2 */
+
+# if defined(FEAT_GUI_GTK) || defined(PROTO)
+    int
+im_is_preediting()
+{
+    return xim_has_preediting;
+}
+# endif
+#endif /* FEAT_XIM */
+
+#if defined(FEAT_MBYTE) || defined(PROTO)
+
+/*
+ * Setup "vcp" for conversion from "from" to "to".
+ * The names must have been made canonical with enc_canonize().
+ * vcp->vc_type must have been initialized to CONV_NONE.
+ * Note: cannot be used for conversion from/to ucs-2 and ucs-4 (will use utf-8
+ * instead).
+ * Afterwards invoke with "from" and "to" equal to NULL to cleanup.
+ * Return FAIL when conversion is not supported, OK otherwise.
+ */
+    int
+convert_setup(vcp, from, to)
+    vimconv_T	*vcp;
+    char_u	*from;
+    char_u	*to;
+{
+    int		from_prop;
+    int		to_prop;
+
+    /* Reset to no conversion. */
+# ifdef USE_ICONV
+    if (vcp->vc_type == CONV_ICONV && vcp->vc_fd != (iconv_t)-1)
+	iconv_close(vcp->vc_fd);
+# endif
+    vcp->vc_type = CONV_NONE;
+    vcp->vc_factor = 1;
+    vcp->vc_fail = FALSE;
+
+    /* No conversion when one of the names is empty or they are equal. */
+    if (from == NULL || *from == NUL || to == NULL || *to == NUL
+						     || STRCMP(from, to) == 0)
+	return OK;
+
+    from_prop = enc_canon_props(from);
+    to_prop = enc_canon_props(to);
+    if ((from_prop & ENC_LATIN1) && (to_prop & ENC_UNICODE))
+    {
+	/* Internal latin1 -> utf-8 conversion. */
+	vcp->vc_type = CONV_TO_UTF8;
+	vcp->vc_factor = 2;	/* up to twice as long */
+    }
+    else if ((from_prop & ENC_LATIN9) && (to_prop & ENC_UNICODE))
+    {
+	/* Internal latin9 -> utf-8 conversion. */
+	vcp->vc_type = CONV_9_TO_UTF8;
+	vcp->vc_factor = 3;	/* up to three as long (euro sign) */
+    }
+    else if ((from_prop & ENC_UNICODE) && (to_prop & ENC_LATIN1))
+    {
+	/* Internal utf-8 -> latin1 conversion. */
+	vcp->vc_type = CONV_TO_LATIN1;
+    }
+    else if ((from_prop & ENC_UNICODE) && (to_prop & ENC_LATIN9))
+    {
+	/* Internal utf-8 -> latin9 conversion. */
+	vcp->vc_type = CONV_TO_LATIN9;
+    }
+#ifdef WIN3264
+    /* Win32-specific codepage <-> codepage conversion without iconv. */
+    else if (((from_prop & ENC_UNICODE) || encname2codepage(from) > 0)
+	    && ((to_prop & ENC_UNICODE) || encname2codepage(to) > 0))
+    {
+	vcp->vc_type = CONV_CODEPAGE;
+	vcp->vc_factor = 2;	/* up to twice as long */
+	vcp->vc_cpfrom = (from_prop & ENC_UNICODE) ? 0 : encname2codepage(from);
+	vcp->vc_cpto = (to_prop & ENC_UNICODE) ? 0 : encname2codepage(to);
+    }
+#endif
+#ifdef MACOS_X
+    else if ((from_prop & ENC_MACROMAN) && (to_prop & ENC_LATIN1))
+    {
+	vcp->vc_type = CONV_MAC_LATIN1;
+    }
+    else if ((from_prop & ENC_MACROMAN) && (to_prop & ENC_UNICODE))
+    {
+	vcp->vc_type = CONV_MAC_UTF8;
+	vcp->vc_factor = 2;	/* up to twice as long */
+    }
+    else if ((from_prop & ENC_LATIN1) && (to_prop & ENC_MACROMAN))
+    {
+	vcp->vc_type = CONV_LATIN1_MAC;
+    }
+    else if ((from_prop & ENC_UNICODE) && (to_prop & ENC_MACROMAN))
+    {
+	vcp->vc_type = CONV_UTF8_MAC;
+    }
+#endif
+# ifdef USE_ICONV
+    else
+    {
+	/* Use iconv() for conversion. */
+	vcp->vc_fd = (iconv_t)my_iconv_open(
+		(to_prop & ENC_UNICODE) ? (char_u *)"utf-8" : to,
+		(from_prop & ENC_UNICODE) ? (char_u *)"utf-8" : from);
+	if (vcp->vc_fd != (iconv_t)-1)
+	{
+	    vcp->vc_type = CONV_ICONV;
+	    vcp->vc_factor = 4;	/* could be longer too... */
+	}
+    }
+# endif
+    if (vcp->vc_type == CONV_NONE)
+	return FAIL;
+
+    return OK;
+}
+
+#if defined(FEAT_GUI) || defined(AMIGA) || defined(WIN3264) \
+	|| defined(MSDOS) || defined(PROTO)
+/*
+ * Do conversion on typed input characters in-place.
+ * The input and output are not NUL terminated!
+ * Returns the length after conversion.
+ */
+    int
+convert_input(ptr, len, maxlen)
+    char_u	*ptr;
+    int		len;
+    int		maxlen;
+{
+    return convert_input_safe(ptr, len, maxlen, NULL, NULL);
+}
+#endif
+
+/*
+ * Like convert_input(), but when there is an incomplete byte sequence at the
+ * end return that as an allocated string in "restp" and set "*restlenp" to
+ * the length.  If "restp" is NULL it is not used.
+ */
+    int
+convert_input_safe(ptr, len, maxlen, restp, restlenp)
+    char_u	*ptr;
+    int		len;
+    int		maxlen;
+    char_u	**restp;
+    int		*restlenp;
+{
+    char_u	*d;
+    int		dlen = len;
+    int		unconvertlen = 0;
+
+    d = string_convert_ext(&input_conv, ptr, &dlen,
+					restp == NULL ? NULL : &unconvertlen);
+    if (d != NULL)
+    {
+	if (dlen <= maxlen)
+	{
+	    if (unconvertlen > 0)
+	    {
+		/* Move the unconverted characters to allocated memory. */
+		*restp = alloc(unconvertlen);
+		if (*restp != NULL)
+		    mch_memmove(*restp, ptr + len - unconvertlen, unconvertlen);
+		*restlenp = unconvertlen;
+	    }
+	    mch_memmove(ptr, d, dlen);
+	}
+	else
+	    /* result is too long, keep the unconverted text (the caller must
+	     * have done something wrong!) */
+	    dlen = len;
+	vim_free(d);
+    }
+    return dlen;
+}
+
+/*
+ * Convert text "ptr[*lenp]" according to "vcp".
+ * Returns the result in allocated memory and sets "*lenp".
+ * When "lenp" is NULL, use NUL terminated strings.
+ * Illegal chars are often changed to "?", unless vcp->vc_fail is set.
+ * When something goes wrong, NULL is returned and "*lenp" is unchanged.
+ */
+    char_u *
+string_convert(vcp, ptr, lenp)
+    vimconv_T	*vcp;
+    char_u	*ptr;
+    int		*lenp;
+{
+    return string_convert_ext(vcp, ptr, lenp, NULL);
+}
+
+/*
+ * Like string_convert(), but when "unconvlenp" is not NULL and there are is
+ * an incomplete sequence at the end it is not converted and "*unconvlenp" is
+ * set to the number of remaining bytes.
+ */
+    char_u *
+string_convert_ext(vcp, ptr, lenp, unconvlenp)
+    vimconv_T	*vcp;
+    char_u	*ptr;
+    int		*lenp;
+    int		*unconvlenp;
+{
+    char_u	*retval = NULL;
+    char_u	*d;
+    int		len;
+    int		i;
+    int		l;
+    int		c;
+
+    if (lenp == NULL)
+	len = (int)STRLEN(ptr);
+    else
+	len = *lenp;
+    if (len == 0)
+	return vim_strsave((char_u *)"");
+
+    switch (vcp->vc_type)
+    {
+	case CONV_TO_UTF8:	/* latin1 to utf-8 conversion */
+	    retval = alloc(len * 2 + 1);
+	    if (retval == NULL)
+		break;
+	    d = retval;
+	    for (i = 0; i < len; ++i)
+	    {
+		c = ptr[i];
+		if (c < 0x80)
+		    *d++ = c;
+		else
+		{
+		    *d++ = 0xc0 + ((unsigned)c >> 6);
+		    *d++ = 0x80 + (c & 0x3f);
+		}
+	    }
+	    *d = NUL;
+	    if (lenp != NULL)
+		*lenp = (int)(d - retval);
+	    break;
+
+	case CONV_9_TO_UTF8:	/* latin9 to utf-8 conversion */
+	    retval = alloc(len * 3 + 1);
+	    if (retval == NULL)
+		break;
+	    d = retval;
+	    for (i = 0; i < len; ++i)
+	    {
+		c = ptr[i];
+		switch (c)
+		{
+		    case 0xa4: c = 0x20ac; break;   /* euro */
+		    case 0xa6: c = 0x0160; break;   /* S hat */
+		    case 0xa8: c = 0x0161; break;   /* S -hat */
+		    case 0xb4: c = 0x017d; break;   /* Z hat */
+		    case 0xb8: c = 0x017e; break;   /* Z -hat */
+		    case 0xbc: c = 0x0152; break;   /* OE */
+		    case 0xbd: c = 0x0153; break;   /* oe */
+		    case 0xbe: c = 0x0178; break;   /* Y */
+		}
+		d += utf_char2bytes(c, d);
+	    }
+	    *d = NUL;
+	    if (lenp != NULL)
+		*lenp = (int)(d - retval);
+	    break;
+
+	case CONV_TO_LATIN1:	/* utf-8 to latin1 conversion */
+	case CONV_TO_LATIN9:	/* utf-8 to latin9 conversion */
+	    retval = alloc(len + 1);
+	    if (retval == NULL)
+		break;
+	    d = retval;
+	    for (i = 0; i < len; ++i)
+	    {
+		l = utf_ptr2len(ptr + i);
+		if (l == 0)
+		    *d++ = NUL;
+		else if (l == 1)
+		{
+		    if (unconvlenp != NULL && utf8len_tab[ptr[i]] > len - i)
+		    {
+			/* Incomplete sequence at the end. */
+			*unconvlenp = len - i;
+			break;
+		    }
+		    *d++ = ptr[i];
+		}
+		else
+		{
+		    c = utf_ptr2char(ptr + i);
+		    if (vcp->vc_type == CONV_TO_LATIN9)
+			switch (c)
+			{
+			    case 0x20ac: c = 0xa4; break;   /* euro */
+			    case 0x0160: c = 0xa6; break;   /* S hat */
+			    case 0x0161: c = 0xa8; break;   /* S -hat */
+			    case 0x017d: c = 0xb4; break;   /* Z hat */
+			    case 0x017e: c = 0xb8; break;   /* Z -hat */
+			    case 0x0152: c = 0xbc; break;   /* OE */
+			    case 0x0153: c = 0xbd; break;   /* oe */
+			    case 0x0178: c = 0xbe; break;   /* Y */
+			    case 0xa4:
+			    case 0xa6:
+			    case 0xa8:
+			    case 0xb4:
+			    case 0xb8:
+			    case 0xbc:
+			    case 0xbd:
+			    case 0xbe: c = 0x100; break; /* not in latin9 */
+			}
+		    if (!utf_iscomposing(c))	/* skip composing chars */
+		    {
+			if (c < 0x100)
+			    *d++ = c;
+			else if (vcp->vc_fail)
+			{
+			    vim_free(retval);
+			    return NULL;
+			}
+			else
+			{
+			    *d++ = 0xbf;
+			    if (utf_char2cells(c) > 1)
+				*d++ = '?';
+			}
+		    }
+		    i += l - 1;
+		}
+	    }
+	    *d = NUL;
+	    if (lenp != NULL)
+		*lenp = (int)(d - retval);
+	    break;
+
+# ifdef MACOS_CONVERT
+	case CONV_MAC_LATIN1:
+	    retval = mac_string_convert(ptr, len, lenp, vcp->vc_fail,
+					'm', 'l', unconvlenp);
+	    break;
+
+	case CONV_LATIN1_MAC:
+	    retval = mac_string_convert(ptr, len, lenp, vcp->vc_fail,
+					'l', 'm', unconvlenp);
+	    break;
+
+	case CONV_MAC_UTF8:
+	    retval = mac_string_convert(ptr, len, lenp, vcp->vc_fail,
+					'm', 'u', unconvlenp);
+	    break;
+
+	case CONV_UTF8_MAC:
+	    retval = mac_string_convert(ptr, len, lenp, vcp->vc_fail,
+					'u', 'm', unconvlenp);
+	    break;
+# endif
+
+# ifdef USE_ICONV
+	case CONV_ICONV:	/* conversion with output_conv.vc_fd */
+	    retval = iconv_string(vcp, ptr, len, unconvlenp);
+	    if (retval != NULL && lenp != NULL)
+		*lenp = (int)STRLEN(retval);
+	    break;
+# endif
+# ifdef WIN3264
+	case CONV_CODEPAGE:		/* codepage -> codepage */
+	{
+	    int		retlen;
+	    int		tmp_len;
+	    short_u	*tmp;
+
+	    /* 1. codepage/UTF-8  ->  ucs-2. */
+	    if (vcp->vc_cpfrom == 0)
+		tmp_len = utf8_to_ucs2(ptr, len, NULL, NULL);
+	    else
+		tmp_len = MultiByteToWideChar(vcp->vc_cpfrom, 0,
+							      ptr, len, 0, 0);
+	    tmp = (short_u *)alloc(sizeof(short_u) * tmp_len);
+	    if (tmp == NULL)
+		break;
+	    if (vcp->vc_cpfrom == 0)
+		utf8_to_ucs2(ptr, len, tmp, unconvlenp);
+	    else
+		MultiByteToWideChar(vcp->vc_cpfrom, 0, ptr, len, tmp, tmp_len);
+
+	    /* 2. ucs-2  ->  codepage/UTF-8. */
+	    if (vcp->vc_cpto == 0)
+		retlen = ucs2_to_utf8(tmp, tmp_len, NULL);
+	    else
+		retlen = WideCharToMultiByte(vcp->vc_cpto, 0,
+						    tmp, tmp_len, 0, 0, 0, 0);
+	    retval = alloc(retlen + 1);
+	    if (retval != NULL)
+	    {
+		if (vcp->vc_cpto == 0)
+		    ucs2_to_utf8(tmp, tmp_len, retval);
+		else
+		    WideCharToMultiByte(vcp->vc_cpto, 0,
+					  tmp, tmp_len, retval, retlen, 0, 0);
+		retval[retlen] = NUL;
+		if (lenp != NULL)
+		    *lenp = retlen;
+	    }
+	    vim_free(tmp);
+	    break;
+	}
+# endif
+    }
+
+    return retval;
+}
+#endif
--- /dev/null
+++ b/memfile.c
@@ -1,0 +1,1350 @@
+/* vi:set ts=8 sts=4 sw=4:
+ *
+ * VIM - Vi IMproved	by Bram Moolenaar
+ *
+ * Do ":help uganda"  in Vim to read copying and usage conditions.
+ * Do ":help credits" in Vim to see a list of people who contributed.
+ * See README.txt for an overview of the Vim source code.
+ */
+
+/*
+ * memfile.c: Contains the functions for handling blocks of memory which can
+ * be stored in a file. This is the implementation of a sort of virtual memory.
+ *
+ * A memfile consists of a sequence of blocks. The blocks numbered from 0
+ * upwards have been assigned a place in the actual file. The block number
+ * is equal to the page number in the file. The
+ * blocks with negative numbers are currently in memory only. They can be
+ * assigned a place in the file when too much memory is being used. At that
+ * moment they get a new, positive, number. A list is used for translation of
+ * negative to positive numbers.
+ *
+ * The size of a block is a multiple of a page size, normally the page size of
+ * the device the file is on. Most blocks are 1 page long. A Block of multiple
+ * pages is used for a line that does not fit in a single page.
+ *
+ * Each block can be in memory and/or in a file. The block stays in memory
+ * as long as it is locked. If it is no longer locked it can be swapped out to
+ * the file. It is only written to the file if it has been changed.
+ *
+ * Under normal operation the file is created when opening the memory file and
+ * deleted when closing the memory file. Only with recovery an existing memory
+ * file is opened.
+ */
+
+#if defined MSDOS || defined(WIN32) || defined(_WIN64)
+# include "vimio.h"	/* for lseek(), must be before vim.h */
+#endif
+
+#include "vim.h"
+
+#ifdef HAVE_FCNTL_H
+# include <fcntl.h>
+#endif
+
+/*
+ * Some systems have the page size in statfs.f_bsize, some in stat.st_blksize
+ */
+#ifdef HAVE_ST_BLKSIZE
+# define STATFS stat
+# define F_BSIZE st_blksize
+# define fstatfs(fd, buf, len, nul) mch_fstat((fd), (buf))
+#else
+# ifdef HAVE_SYS_STATFS_H
+#  include <sys/statfs.h>
+#  define STATFS statfs
+#  define F_BSIZE f_bsize
+#  ifdef __MINT__		/* do we still need this? */
+#   define fstatfs(fd, buf, len, nul) mch_fstat((fd), (buf))
+#  endif
+# endif
+#endif
+
+/*
+ * for Amiga Dos 2.0x we use Flush
+ */
+#ifdef AMIGA
+# ifdef FEAT_ARP
+extern int dos2;			/* this is in os_amiga.c */
+# endif
+# ifdef SASC
+#  include <proto/dos.h>
+#  include <ios1.h>			/* for chkufb() */
+# endif
+#endif
+
+#define MEMFILE_PAGE_SIZE 4096		/* default page size */
+
+static long_u	total_mem_used = 0;	/* total memory used for memfiles */
+
+static void mf_ins_hash __ARGS((memfile_T *, bhdr_T *));
+static void mf_rem_hash __ARGS((memfile_T *, bhdr_T *));
+static bhdr_T *mf_find_hash __ARGS((memfile_T *, blocknr_T));
+static void mf_ins_used __ARGS((memfile_T *, bhdr_T *));
+static void mf_rem_used __ARGS((memfile_T *, bhdr_T *));
+static bhdr_T *mf_release __ARGS((memfile_T *, int));
+static bhdr_T *mf_alloc_bhdr __ARGS((memfile_T *, int));
+static void mf_free_bhdr __ARGS((bhdr_T *));
+static void mf_ins_free __ARGS((memfile_T *, bhdr_T *));
+static bhdr_T *mf_rem_free __ARGS((memfile_T *));
+static int  mf_read __ARGS((memfile_T *, bhdr_T *));
+static int  mf_write __ARGS((memfile_T *, bhdr_T *));
+static int  mf_trans_add __ARGS((memfile_T *, bhdr_T *));
+static void mf_do_open __ARGS((memfile_T *, char_u *, int));
+
+/*
+ * The functions for using a memfile:
+ *
+ * mf_open()	    open a new or existing memfile
+ * mf_open_file()   open a swap file for an existing memfile
+ * mf_close()	    close (and delete) a memfile
+ * mf_new()	    create a new block in a memfile and lock it
+ * mf_get()	    get an existing block and lock it
+ * mf_put()	    unlock a block, may be marked for writing
+ * mf_free()	    remove a block
+ * mf_sync()	    sync changed parts of memfile to disk
+ * mf_release_all() release as much memory as possible
+ * mf_trans_del()   may translate negative to positive block number
+ * mf_fullname()    make file name full path (use before first :cd)
+ */
+
+/*
+ * Open an existing or new memory block file.
+ *
+ *  fname:	name of file to use (NULL means no file at all)
+ *		Note: fname must have been allocated, it is not copied!
+ *			If opening the file fails, fname is freed.
+ *  flags:	flags for open() call
+ *
+ *  If fname != NULL and file cannot be opened, fail.
+ *
+ * return value: identifier for this memory block file.
+ */
+    memfile_T *
+mf_open(fname, flags)
+    char_u	*fname;
+    int		flags;
+{
+    memfile_T		*mfp;
+    int			i;
+    off_t		size;
+#if defined(STATFS) && defined(UNIX) && !defined(__QNX__)
+# define USE_FSTATFS
+    struct STATFS	stf;
+#endif
+
+    if ((mfp = (memfile_T *)alloc((unsigned)sizeof(memfile_T))) == NULL)
+	return NULL;
+
+    if (fname == NULL)	    /* no file for this memfile, use memory only */
+    {
+	mfp->mf_fname = NULL;
+	mfp->mf_ffname = NULL;
+	mfp->mf_fd = -1;
+    }
+    else
+    {
+	mf_do_open(mfp, fname, flags);	/* try to open the file */
+
+	/* if the file cannot be opened, return here */
+	if (mfp->mf_fd < 0)
+	{
+	    vim_free(mfp);
+	    return NULL;
+	}
+    }
+
+    mfp->mf_free_first = NULL;		/* free list is empty */
+    mfp->mf_used_first = NULL;		/* used list is empty */
+    mfp->mf_used_last = NULL;
+    mfp->mf_dirty = FALSE;
+    mfp->mf_used_count = 0;
+    for (i = 0; i < MEMHASHSIZE; ++i)
+    {
+	mfp->mf_hash[i] = NULL;		/* hash lists are empty */
+	mfp->mf_trans[i] = NULL;	/* trans lists are empty */
+    }
+    mfp->mf_page_size = MEMFILE_PAGE_SIZE;
+
+#ifdef USE_FSTATFS
+    /*
+     * Try to set the page size equal to the block size of the device.
+     * Speeds up I/O a lot.
+     * When recovering, the actual block size will be retrieved from block 0
+     * in ml_recover().  The size used here may be wrong, therefore
+     * mf_blocknr_max must be rounded up.
+     */
+    if (mfp->mf_fd >= 0
+	    && fstatfs(mfp->mf_fd, &stf, sizeof(struct statfs), 0) == 0
+	    && stf.F_BSIZE >= MIN_SWAP_PAGE_SIZE
+	    && stf.F_BSIZE <= MAX_SWAP_PAGE_SIZE)
+	mfp->mf_page_size = stf.F_BSIZE;
+#endif
+
+    if (mfp->mf_fd < 0 || (flags & (O_TRUNC|O_EXCL))
+		      || (size = lseek(mfp->mf_fd, (off_t)0L, SEEK_END)) <= 0)
+	mfp->mf_blocknr_max = 0;	/* no file or empty file */
+    else
+	mfp->mf_blocknr_max = (blocknr_T)((size + mfp->mf_page_size - 1)
+							 / mfp->mf_page_size);
+    mfp->mf_blocknr_min = -1;
+    mfp->mf_neg_count = 0;
+    mfp->mf_infile_count = mfp->mf_blocknr_max;
+
+    /*
+     * Compute maximum number of pages ('maxmem' is in Kbyte):
+     *	'mammem' * 1Kbyte / page-size-in-bytes.
+     * Avoid overflow by first reducing page size as much as possible.
+     */
+    {
+	int	    shift = 10;
+	unsigned    page_size = mfp->mf_page_size;
+
+	while (shift > 0 && (page_size & 1) == 0)
+	{
+	    page_size = page_size >> 1;
+	    --shift;
+	}
+	mfp->mf_used_count_max = (p_mm << shift) / page_size;
+	if (mfp->mf_used_count_max < 10)
+	    mfp->mf_used_count_max = 10;
+    }
+
+    return mfp;
+}
+
+/*
+ * Open a file for an existing memfile.  Used when updatecount set from 0 to
+ * some value.
+ * If the file already exists, this fails.
+ * "fname" is the name of file to use (NULL means no file at all)
+ * Note: "fname" must have been allocated, it is not copied!  If opening the
+ * file fails, "fname" is freed.
+ *
+ * return value: FAIL if file could not be opened, OK otherwise
+ */
+    int
+mf_open_file(mfp, fname)
+    memfile_T	*mfp;
+    char_u	*fname;
+{
+    mf_do_open(mfp, fname, O_RDWR|O_CREAT|O_EXCL); /* try to open the file */
+
+    if (mfp->mf_fd < 0)
+	return FAIL;
+
+    mfp->mf_dirty = TRUE;
+    return OK;
+}
+
+/*
+ * close a memory file and delete the associated file if 'del_file' is TRUE
+ */
+    void
+mf_close(mfp, del_file)
+    memfile_T	*mfp;
+    int		del_file;
+{
+    bhdr_T	*hp, *nextp;
+    NR_TRANS	*tp, *tpnext;
+    int		i;
+
+    if (mfp == NULL)		    /* safety check */
+	return;
+    if (mfp->mf_fd >= 0)
+    {
+	if (close(mfp->mf_fd) < 0)
+	    EMSG(_(e_swapclose));
+    }
+    if (del_file && mfp->mf_fname != NULL)
+	mch_remove(mfp->mf_fname);
+					    /* free entries in used list */
+    for (hp = mfp->mf_used_first; hp != NULL; hp = nextp)
+    {
+	total_mem_used -= hp->bh_page_count * mfp->mf_page_size;
+	nextp = hp->bh_next;
+	mf_free_bhdr(hp);
+    }
+    while (mfp->mf_free_first != NULL)	    /* free entries in free list */
+	vim_free(mf_rem_free(mfp));
+    for (i = 0; i < MEMHASHSIZE; ++i)	    /* free entries in trans lists */
+	for (tp = mfp->mf_trans[i]; tp != NULL; tp = tpnext)
+	{
+	    tpnext = tp->nt_next;
+	    vim_free(tp);
+	}
+    vim_free(mfp->mf_fname);
+    vim_free(mfp->mf_ffname);
+    vim_free(mfp);
+}
+
+/*
+ * Close the swap file for a memfile.  Used when 'swapfile' is reset.
+ */
+    void
+mf_close_file(buf, getlines)
+    buf_T	*buf;
+    int		getlines;	/* get all lines into memory? */
+{
+    memfile_T	*mfp;
+    linenr_T	lnum;
+
+    mfp = buf->b_ml.ml_mfp;
+    if (mfp == NULL || mfp->mf_fd < 0)		/* nothing to close */
+	return;
+
+    if (getlines)
+    {
+	/* get all blocks in memory by accessing all lines (clumsy!) */
+	mf_dont_release = TRUE;
+	for (lnum = 1; lnum <= buf->b_ml.ml_line_count; ++lnum)
+	    (void)ml_get_buf(buf, lnum, FALSE);
+	mf_dont_release = FALSE;
+	/* TODO: should check if all blocks are really in core */
+    }
+
+    if (close(mfp->mf_fd) < 0)			/* close the file */
+	EMSG(_(e_swapclose));
+    mfp->mf_fd = -1;
+
+    if (mfp->mf_fname != NULL)
+    {
+	mch_remove(mfp->mf_fname);		/* delete the swap file */
+	vim_free(mfp->mf_fname);
+	vim_free(mfp->mf_ffname);
+	mfp->mf_fname = NULL;
+	mfp->mf_ffname = NULL;
+    }
+}
+
+/*
+ * Set new size for a memfile.  Used when block 0 of a swapfile has been read
+ * and the size it indicates differs from what was guessed.
+ */
+    void
+mf_new_page_size(mfp, new_size)
+    memfile_T	*mfp;
+    unsigned	new_size;
+{
+    /* Correct the memory used for block 0 to the new size, because it will be
+     * freed with that size later on. */
+    total_mem_used += new_size - mfp->mf_page_size;
+    mfp->mf_page_size = new_size;
+}
+
+/*
+ * get a new block
+ *
+ *   negative: TRUE if negative block number desired (data block)
+ */
+    bhdr_T *
+mf_new(mfp, negative, page_count)
+    memfile_T	*mfp;
+    int		negative;
+    int		page_count;
+{
+    bhdr_T	*hp;	/* new bhdr_T */
+    bhdr_T	*freep;	/* first block in free list */
+    char_u	*p;
+
+    /*
+     * If we reached the maximum size for the used memory blocks, release one
+     * If a bhdr_T is returned, use it and adjust the page_count if necessary.
+     */
+    hp = mf_release(mfp, page_count);
+
+/*
+ * Decide on the number to use:
+ * If there is a free block, use its number.
+ * Otherwise use mf_block_min for a negative number, mf_block_max for
+ * a positive number.
+ */
+    freep = mfp->mf_free_first;
+    if (!negative && freep != NULL && freep->bh_page_count >= page_count)
+    {
+	/*
+	 * If the block in the free list has more pages, take only the number
+	 * of pages needed and allocate a new bhdr_T with data
+	 *
+	 * If the number of pages matches and mf_release() did not return a
+	 * bhdr_T, use the bhdr_T from the free list and allocate the data
+	 *
+	 * If the number of pages matches and mf_release() returned a bhdr_T,
+	 * just use the number and free the bhdr_T from the free list
+	 */
+	if (freep->bh_page_count > page_count)
+	{
+	    if (hp == NULL && (hp = mf_alloc_bhdr(mfp, page_count)) == NULL)
+		return NULL;
+	    hp->bh_bnum = freep->bh_bnum;
+	    freep->bh_bnum += page_count;
+	    freep->bh_page_count -= page_count;
+	}
+	else if (hp == NULL)	    /* need to allocate memory for this block */
+	{
+	    if ((p = (char_u *)alloc(mfp->mf_page_size * page_count)) == NULL)
+		return NULL;
+	    hp = mf_rem_free(mfp);
+	    hp->bh_data = p;
+	}
+	else		    /* use the number, remove entry from free list */
+	{
+	    freep = mf_rem_free(mfp);
+	    hp->bh_bnum = freep->bh_bnum;
+	    vim_free(freep);
+	}
+    }
+    else	/* get a new number */
+    {
+	if (hp == NULL && (hp = mf_alloc_bhdr(mfp, page_count)) == NULL)
+	    return NULL;
+	if (negative)
+	{
+	    hp->bh_bnum = mfp->mf_blocknr_min--;
+	    mfp->mf_neg_count++;
+	}
+	else
+	{
+	    hp->bh_bnum = mfp->mf_blocknr_max;
+	    mfp->mf_blocknr_max += page_count;
+	}
+    }
+    hp->bh_flags = BH_LOCKED | BH_DIRTY;	/* new block is always dirty */
+    mfp->mf_dirty = TRUE;
+    hp->bh_page_count = page_count;
+    mf_ins_used(mfp, hp);
+    mf_ins_hash(mfp, hp);
+
+    /*
+     * Init the data to all zero, to avoid reading uninitialized data.
+     * This also avoids that the passwd file ends up in the swap file!
+     */
+    (void)vim_memset((char *)(hp->bh_data), 0, (size_t)mfp->mf_page_size);
+
+    return hp;
+}
+
+/*
+ * get existing block 'nr' with 'page_count' pages
+ *
+ * Note: The caller should first check a negative nr with mf_trans_del()
+ */
+    bhdr_T *
+mf_get(mfp, nr, page_count)
+    memfile_T	*mfp;
+    blocknr_T	nr;
+    int		page_count;
+{
+    bhdr_T    *hp;
+						/* doesn't exist */
+    if (nr >= mfp->mf_blocknr_max || nr <= mfp->mf_blocknr_min)
+	return NULL;
+
+    /*
+     * see if it is in the cache
+     */
+    hp = mf_find_hash(mfp, nr);
+    if (hp == NULL)	/* not in the hash list */
+    {
+	if (nr < 0 || nr >= mfp->mf_infile_count)   /* can't be in the file */
+	    return NULL;
+
+	/* could check here if the block is in the free list */
+
+	/*
+	 * Check if we need to flush an existing block.
+	 * If so, use that block.
+	 * If not, allocate a new block.
+	 */
+	hp = mf_release(mfp, page_count);
+	if (hp == NULL && (hp = mf_alloc_bhdr(mfp, page_count)) == NULL)
+	    return NULL;
+
+	hp->bh_bnum = nr;
+	hp->bh_flags = 0;
+	hp->bh_page_count = page_count;
+	if (mf_read(mfp, hp) == FAIL)	    /* cannot read the block! */
+	{
+	    mf_free_bhdr(hp);
+	    return NULL;
+	}
+    }
+    else
+    {
+	mf_rem_used(mfp, hp);	/* remove from list, insert in front below */
+	mf_rem_hash(mfp, hp);
+    }
+
+    hp->bh_flags |= BH_LOCKED;
+    mf_ins_used(mfp, hp);	/* put in front of used list */
+    mf_ins_hash(mfp, hp);	/* put in front of hash list */
+
+    return hp;
+}
+
+/*
+ * release the block *hp
+ *
+ *   dirty: Block must be written to file later
+ *   infile: Block should be in file (needed for recovery)
+ *
+ *  no return value, function cannot fail
+ */
+    void
+mf_put(mfp, hp, dirty, infile)
+    memfile_T	*mfp;
+    bhdr_T	*hp;
+    int		dirty;
+    int		infile;
+{
+    int		flags;
+
+    flags = hp->bh_flags;
+
+    if ((flags & BH_LOCKED) == 0)
+	EMSG(_("E293: block was not locked"));
+    flags &= ~BH_LOCKED;
+    if (dirty)
+    {
+	flags |= BH_DIRTY;
+	mfp->mf_dirty = TRUE;
+    }
+    hp->bh_flags = flags;
+    if (infile)
+	mf_trans_add(mfp, hp);	    /* may translate negative in positive nr */
+}
+
+/*
+ * block *hp is no longer in used, may put it in the free list of memfile *mfp
+ */
+    void
+mf_free(mfp, hp)
+    memfile_T	*mfp;
+    bhdr_T	*hp;
+{
+    vim_free(hp->bh_data);	/* free the memory */
+    mf_rem_hash(mfp, hp);	/* get *hp out of the hash list */
+    mf_rem_used(mfp, hp);	/* get *hp out of the used list */
+    if (hp->bh_bnum < 0)
+    {
+	vim_free(hp);		/* don't want negative numbers in free list */
+	mfp->mf_neg_count--;
+    }
+    else
+	mf_ins_free(mfp, hp);	/* put *hp in the free list */
+}
+
+#if defined(__MORPHOS__) && defined(__libnix__)
+/* function is missing in MorphOS libnix version */
+extern unsigned long *__stdfiledes;
+
+    static unsigned long
+fdtofh(int filedescriptor)
+{
+    return __stdfiledes[filedescriptor];
+}
+#endif
+
+/*
+ * Sync the memory file *mfp to disk.
+ * Flags:
+ *  MFS_ALL	If not given, blocks with negative numbers are not synced,
+ *		even when they are dirty!
+ *  MFS_STOP	Stop syncing when a character becomes available, but sync at
+ *		least one block.
+ *  MFS_FLUSH	Make sure buffers are flushed to disk, so they will survive a
+ *		system crash.
+ *  MFS_ZERO	Only write block 0.
+ *
+ * Return FAIL for failure, OK otherwise
+ */
+    int
+mf_sync(mfp, flags)
+    memfile_T	*mfp;
+    int		flags;
+{
+    int		status;
+    bhdr_T	*hp;
+#if defined(SYNC_DUP_CLOSE) && !defined(MSDOS)
+    int		fd;
+#endif
+    int		got_int_save = got_int;
+
+    if (mfp->mf_fd < 0)	    /* there is no file, nothing to do */
+    {
+	mfp->mf_dirty = FALSE;
+	return FAIL;
+    }
+
+    /* Only a CTRL-C while writing will break us here, not one typed
+     * previously. */
+    got_int = FALSE;
+
+    /*
+     * sync from last to first (may reduce the probability of an inconsistent
+     * file) If a write fails, it is very likely caused by a full filesystem.
+     * Then we only try to write blocks within the existing file. If that also
+     * fails then we give up.
+     */
+    status = OK;
+    for (hp = mfp->mf_used_last; hp != NULL; hp = hp->bh_prev)
+	if (((flags & MFS_ALL) || hp->bh_bnum >= 0)
+		&& (hp->bh_flags & BH_DIRTY)
+		&& (status == OK || (hp->bh_bnum >= 0
+		    && hp->bh_bnum < mfp->mf_infile_count)))
+	{
+	    if ((flags & MFS_ZERO) && hp->bh_bnum != 0)
+		continue;
+	    if (mf_write(mfp, hp) == FAIL)
+	    {
+		if (status == FAIL)	/* double error: quit syncing */
+		    break;
+		status = FAIL;
+	    }
+	    if (flags & MFS_STOP)
+	    {
+		/* Stop when char available now. */
+		if (ui_char_avail())
+		    break;
+	    }
+	    else
+		ui_breakcheck();
+	    if (got_int)
+		break;
+	}
+
+    /*
+     * If the whole list is flushed, the memfile is not dirty anymore.
+     * In case of an error this flag is also set, to avoid trying all the time.
+     */
+    if (hp == NULL || status == FAIL)
+	mfp->mf_dirty = FALSE;
+
+    if ((flags & MFS_FLUSH) && *p_sws != NUL)
+    {
+#if defined(UNIX)
+# ifdef HAVE_FSYNC
+	/*
+	 * most Unixes have the very useful fsync() function, just what we need.
+	 * However, with OS/2 and EMX it is also available, but there are
+	 * reports of bad problems with it (a bug in HPFS.IFS).
+	 * So we disable use of it here in case someone tries to be smart
+	 * and changes os_os2_cfg.h... (even though there is no __EMX__ test
+	 * in the #if, as __EMX__ does not have sync(); we hope for a timely
+	 * sync from the system itself).
+	 */
+#  if defined(__EMX__)
+   error "Dont use fsync with EMX! Read emxdoc.doc or emxfix01.doc for info."
+#  endif
+	if (STRCMP(p_sws, "fsync") == 0)
+	{
+	    if (fsync(mfp->mf_fd))
+		status = FAIL;
+	}
+	else
+# endif
+	    /* OpenNT is strictly POSIX (Benzinger) */
+	    /* Tandem/Himalaya NSK-OSS doesn't have sync() */
+# if defined(__OPENNT) || defined(__TANDEM)
+	    fflush(NULL);
+# else
+	    sync();
+# endif
+#endif
+#ifdef VMS
+	if (STRCMP(p_sws, "fsync") == 0)
+	{
+	    if (fsync(mfp->mf_fd))
+		status = FAIL;
+	}
+#endif
+#ifdef MSDOS
+	if (_dos_commit(mfp->mf_fd))
+	    status = FAIL;
+#else
+# ifdef SYNC_DUP_CLOSE
+	/*
+	 * Win32 is a bit more work: Duplicate the file handle and close it.
+	 * This should flush the file to disk.
+	 */
+	if ((fd = dup(mfp->mf_fd)) >= 0)
+	    close(fd);
+# endif
+#endif
+#ifdef AMIGA
+# if defined(__AROS__) || defined(__amigaos4__)
+	if (fsync(mfp->mf_fd) != 0)
+	    status = FAIL;
+# else
+	/*
+	 * Flush() only exists for AmigaDos 2.0.
+	 * For 1.3 it should be done with close() + open(), but then the risk
+	 * is that the open() may fail and lose the file....
+	 */
+#  ifdef FEAT_ARP
+	if (dos2)
+#  endif
+#  ifdef SASC
+	{
+	    struct UFB *fp = chkufb(mfp->mf_fd);
+
+	    if (fp != NULL)
+		Flush(fp->ufbfh);
+	}
+#  else
+#   if defined(_DCC) || defined(__GNUC__) || defined(__MORPHOS__)
+	{
+#    if defined(__GNUC__) && !defined(__MORPHOS__) && defined(__libnix__)
+	    /* Have function (in libnix at least),
+	     * but ain't got no prototype anywhere. */
+	    extern unsigned long fdtofh(int filedescriptor);
+#    endif
+#    if !defined(__libnix__)
+	    fflush(NULL);
+#    else
+	    BPTR fh = (BPTR)fdtofh(mfp->mf_fd);
+
+	    if (fh != 0)
+		Flush(fh);
+#    endif
+	}
+#   else /* assume Manx */
+	    Flush(_devtab[mfp->mf_fd].fd);
+#   endif
+#  endif
+# endif
+#endif /* AMIGA */
+    }
+
+    got_int |= got_int_save;
+
+    return status;
+}
+
+/*
+ * For all blocks in memory file *mfp that have a positive block number set
+ * the dirty flag.  These are blocks that need to be written to a newly
+ * created swapfile.
+ */
+    void
+mf_set_dirty(mfp)
+    memfile_T	*mfp;
+{
+    bhdr_T	*hp;
+
+    for (hp = mfp->mf_used_last; hp != NULL; hp = hp->bh_prev)
+	if (hp->bh_bnum > 0)
+	    hp->bh_flags |= BH_DIRTY;
+    mfp->mf_dirty = TRUE;
+}
+
+/*
+ * insert block *hp in front of hashlist of memfile *mfp
+ */
+    static void
+mf_ins_hash(mfp, hp)
+    memfile_T	*mfp;
+    bhdr_T	*hp;
+{
+    bhdr_T	*hhp;
+    int		hash;
+
+    hash = MEMHASH(hp->bh_bnum);
+    hhp = mfp->mf_hash[hash];
+    hp->bh_hash_next = hhp;
+    hp->bh_hash_prev = NULL;
+    if (hhp != NULL)
+	hhp->bh_hash_prev = hp;
+    mfp->mf_hash[hash] = hp;
+}
+
+/*
+ * remove block *hp from hashlist of memfile list *mfp
+ */
+    static void
+mf_rem_hash(mfp, hp)
+    memfile_T	*mfp;
+    bhdr_T	*hp;
+{
+    if (hp->bh_hash_prev == NULL)
+	mfp->mf_hash[MEMHASH(hp->bh_bnum)] = hp->bh_hash_next;
+    else
+	hp->bh_hash_prev->bh_hash_next = hp->bh_hash_next;
+
+    if (hp->bh_hash_next)
+	hp->bh_hash_next->bh_hash_prev = hp->bh_hash_prev;
+}
+
+/*
+ * look in hash lists of memfile *mfp for block header with number 'nr'
+ */
+    static bhdr_T *
+mf_find_hash(mfp, nr)
+    memfile_T	*mfp;
+    blocknr_T	nr;
+{
+    bhdr_T	*hp;
+
+    for (hp = mfp->mf_hash[MEMHASH(nr)]; hp != NULL; hp = hp->bh_hash_next)
+	if (hp->bh_bnum == nr)
+	    break;
+    return hp;
+}
+
+/*
+ * insert block *hp in front of used list of memfile *mfp
+ */
+    static void
+mf_ins_used(mfp, hp)
+    memfile_T	*mfp;
+    bhdr_T	*hp;
+{
+    hp->bh_next = mfp->mf_used_first;
+    mfp->mf_used_first = hp;
+    hp->bh_prev = NULL;
+    if (hp->bh_next == NULL)	    /* list was empty, adjust last pointer */
+	mfp->mf_used_last = hp;
+    else
+	hp->bh_next->bh_prev = hp;
+    mfp->mf_used_count += hp->bh_page_count;
+    total_mem_used += hp->bh_page_count * mfp->mf_page_size;
+}
+
+/*
+ * remove block *hp from used list of memfile *mfp
+ */
+    static void
+mf_rem_used(mfp, hp)
+    memfile_T	*mfp;
+    bhdr_T	*hp;
+{
+    if (hp->bh_next == NULL)	    /* last block in used list */
+	mfp->mf_used_last = hp->bh_prev;
+    else
+	hp->bh_next->bh_prev = hp->bh_prev;
+    if (hp->bh_prev == NULL)	    /* first block in used list */
+	mfp->mf_used_first = hp->bh_next;
+    else
+	hp->bh_prev->bh_next = hp->bh_next;
+    mfp->mf_used_count -= hp->bh_page_count;
+    total_mem_used -= hp->bh_page_count * mfp->mf_page_size;
+}
+
+/*
+ * Release the least recently used block from the used list if the number
+ * of used memory blocks gets to big.
+ *
+ * Return the block header to the caller, including the memory block, so
+ * it can be re-used. Make sure the page_count is right.
+ */
+    static bhdr_T *
+mf_release(mfp, page_count)
+    memfile_T	*mfp;
+    int		page_count;
+{
+    bhdr_T	*hp;
+    int		need_release;
+    buf_T	*buf;
+
+    /* don't release while in mf_close_file() */
+    if (mf_dont_release)
+	return NULL;
+
+    /*
+     * Need to release a block if the number of blocks for this memfile is
+     * higher than the maximum or total memory used is over 'maxmemtot'
+     */
+    need_release = ((mfp->mf_used_count >= mfp->mf_used_count_max)
+				  || (total_mem_used >> 10) >= (long_u)p_mmt);
+
+    /*
+     * Try to create a swap file if the amount of memory used is getting too
+     * high.
+     */
+    if (mfp->mf_fd < 0 && need_release && p_uc)
+    {
+	/* find for which buffer this memfile is */
+	for (buf = firstbuf; buf != NULL; buf = buf->b_next)
+	    if (buf->b_ml.ml_mfp == mfp)
+		break;
+	if (buf != NULL && buf->b_may_swap)
+	    ml_open_file(buf);
+    }
+
+    /*
+     * don't release a block if
+     *	there is no file for this memfile
+     * or
+     *	the number of blocks for this memfile is lower than the maximum
+     *	  and
+     *	total memory used is not up to 'maxmemtot'
+     */
+    if (mfp->mf_fd < 0 || !need_release)
+	return NULL;
+
+    for (hp = mfp->mf_used_last; hp != NULL; hp = hp->bh_prev)
+	if (!(hp->bh_flags & BH_LOCKED))
+	    break;
+    if (hp == NULL)	/* not a single one that can be released */
+	return NULL;
+
+    /*
+     * If the block is dirty, write it.
+     * If the write fails we don't free it.
+     */
+    if ((hp->bh_flags & BH_DIRTY) && mf_write(mfp, hp) == FAIL)
+	return NULL;
+
+    mf_rem_used(mfp, hp);
+    mf_rem_hash(mfp, hp);
+
+    /*
+     * If a bhdr_T is returned, make sure that the page_count of bh_data is
+     * right
+     */
+    if (hp->bh_page_count != page_count)
+    {
+	vim_free(hp->bh_data);
+	if ((hp->bh_data = alloc(mfp->mf_page_size * page_count)) == NULL)
+	{
+	    vim_free(hp);
+	    return NULL;
+	}
+	hp->bh_page_count = page_count;
+    }
+    return hp;
+}
+
+/*
+ * release as many blocks as possible
+ * Used in case of out of memory
+ *
+ * return TRUE if any memory was released
+ */
+    int
+mf_release_all()
+{
+    buf_T	*buf;
+    memfile_T	*mfp;
+    bhdr_T	*hp;
+    int		retval = FALSE;
+
+    for (buf = firstbuf; buf != NULL; buf = buf->b_next)
+    {
+	mfp = buf->b_ml.ml_mfp;
+	if (mfp != NULL)
+	{
+	    /* If no swap file yet, may open one */
+	    if (mfp->mf_fd < 0 && buf->b_may_swap)
+		ml_open_file(buf);
+
+	    /* only if there is a swapfile */
+	    if (mfp->mf_fd >= 0)
+	    {
+		for (hp = mfp->mf_used_last; hp != NULL; )
+		{
+		    if (!(hp->bh_flags & BH_LOCKED)
+			    && (!(hp->bh_flags & BH_DIRTY)
+				|| mf_write(mfp, hp) != FAIL))
+		    {
+			mf_rem_used(mfp, hp);
+			mf_rem_hash(mfp, hp);
+			mf_free_bhdr(hp);
+			hp = mfp->mf_used_last;	/* re-start, list was changed */
+			retval = TRUE;
+		    }
+		    else
+			hp = hp->bh_prev;
+		}
+	    }
+	}
+    }
+    return retval;
+}
+
+/*
+ * Allocate a block header and a block of memory for it
+ */
+    static bhdr_T *
+mf_alloc_bhdr(mfp, page_count)
+    memfile_T	*mfp;
+    int		page_count;
+{
+    bhdr_T	*hp;
+
+    if ((hp = (bhdr_T *)alloc((unsigned)sizeof(bhdr_T))) != NULL)
+    {
+	if ((hp->bh_data = (char_u *)alloc(mfp->mf_page_size * page_count))
+								      == NULL)
+	{
+	    vim_free(hp);	    /* not enough memory */
+	    return NULL;
+	}
+	hp->bh_page_count = page_count;
+    }
+    return hp;
+}
+
+/*
+ * Free a block header and the block of memory for it
+ */
+    static void
+mf_free_bhdr(hp)
+    bhdr_T	*hp;
+{
+    vim_free(hp->bh_data);
+    vim_free(hp);
+}
+
+/*
+ * insert entry *hp in the free list
+ */
+    static void
+mf_ins_free(mfp, hp)
+    memfile_T	*mfp;
+    bhdr_T	*hp;
+{
+    hp->bh_next = mfp->mf_free_first;
+    mfp->mf_free_first = hp;
+}
+
+/*
+ * remove the first entry from the free list and return a pointer to it
+ * Note: caller must check that mfp->mf_free_first is not NULL!
+ */
+    static bhdr_T *
+mf_rem_free(mfp)
+    memfile_T	*mfp;
+{
+    bhdr_T	*hp;
+
+    hp = mfp->mf_free_first;
+    mfp->mf_free_first = hp->bh_next;
+    return hp;
+}
+
+/*
+ * read a block from disk
+ *
+ * Return FAIL for failure, OK otherwise
+ */
+    static int
+mf_read(mfp, hp)
+    memfile_T	*mfp;
+    bhdr_T	*hp;
+{
+    off_t	offset;
+    unsigned	page_size;
+    unsigned	size;
+
+    if (mfp->mf_fd < 0)	    /* there is no file, can't read */
+	return FAIL;
+
+    page_size = mfp->mf_page_size;
+    offset = (off_t)page_size * hp->bh_bnum;
+    size = page_size * hp->bh_page_count;
+    if (lseek(mfp->mf_fd, offset, SEEK_SET) != offset)
+    {
+	PERROR(_("E294: Seek error in swap file read"));
+	return FAIL;
+    }
+    if ((unsigned)vim_read(mfp->mf_fd, hp->bh_data, size) != size)
+    {
+	PERROR(_("E295: Read error in swap file"));
+	return FAIL;
+    }
+    return OK;
+}
+
+/*
+ * write a block to disk
+ *
+ * Return FAIL for failure, OK otherwise
+ */
+    static int
+mf_write(mfp, hp)
+    memfile_T	*mfp;
+    bhdr_T	*hp;
+{
+    off_t	offset;	    /* offset in the file */
+    blocknr_T	nr;	    /* block nr which is being written */
+    bhdr_T	*hp2;
+    unsigned	page_size;  /* number of bytes in a page */
+    unsigned	page_count; /* number of pages written */
+    unsigned	size;	    /* number of bytes written */
+
+    if (mfp->mf_fd < 0)	    /* there is no file, can't write */
+	return FAIL;
+
+    if (hp->bh_bnum < 0)	/* must assign file block number */
+	if (mf_trans_add(mfp, hp) == FAIL)
+	    return FAIL;
+
+    page_size = mfp->mf_page_size;
+
+    /*
+     * We don't want gaps in the file. Write the blocks in front of *hp
+     * to extend the file.
+     * If block 'mf_infile_count' is not in the hash list, it has been
+     * freed. Fill the space in the file with data from the current block.
+     */
+    for (;;)
+    {
+	nr = hp->bh_bnum;
+	if (nr > mfp->mf_infile_count)		/* beyond end of file */
+	{
+	    nr = mfp->mf_infile_count;
+	    hp2 = mf_find_hash(mfp, nr);	/* NULL catched below */
+	}
+	else
+	    hp2 = hp;
+
+	offset = (off_t)page_size * nr;
+	if (lseek(mfp->mf_fd, offset, SEEK_SET) != offset)
+	{
+	    PERROR(_("E296: Seek error in swap file write"));
+	    return FAIL;
+	}
+	if (hp2 == NULL)	    /* freed block, fill with dummy data */
+	    page_count = 1;
+	else
+	    page_count = hp2->bh_page_count;
+	size = page_size * page_count;
+	if ((unsigned)vim_write(mfp->mf_fd,
+	     (hp2 == NULL ? hp : hp2)->bh_data, size) != size)
+	{
+	    /*
+	     * Avoid repeating the error message, this mostly happens when the
+	     * disk is full. We give the message again only after a successful
+	     * write or when hitting a key. We keep on trying, in case some
+	     * space becomes available.
+	     */
+	    if (!did_swapwrite_msg)
+		EMSG(_("E297: Write error in swap file"));
+	    did_swapwrite_msg = TRUE;
+	    return FAIL;
+	}
+	did_swapwrite_msg = FALSE;
+	if (hp2 != NULL)		    /* written a non-dummy block */
+	    hp2->bh_flags &= ~BH_DIRTY;
+					    /* appended to the file */
+	if (nr + (blocknr_T)page_count > mfp->mf_infile_count)
+	    mfp->mf_infile_count = nr + page_count;
+	if (nr == hp->bh_bnum)		    /* written the desired block */
+	    break;
+    }
+    return OK;
+}
+
+/*
+ * Make block number for *hp positive and add it to the translation list
+ *
+ * Return FAIL for failure, OK otherwise
+ */
+    static int
+mf_trans_add(mfp, hp)
+    memfile_T	*mfp;
+    bhdr_T	*hp;
+{
+    bhdr_T	*freep;
+    blocknr_T	new_bnum;
+    int		hash;
+    NR_TRANS	*np;
+    int		page_count;
+
+    if (hp->bh_bnum >= 0)		    /* it's already positive */
+	return OK;
+
+    if ((np = (NR_TRANS *)alloc((unsigned)sizeof(NR_TRANS))) == NULL)
+	return FAIL;
+
+/*
+ * get a new number for the block.
+ * If the first item in the free list has sufficient pages, use its number
+ * Otherwise use mf_blocknr_max.
+ */
+    freep = mfp->mf_free_first;
+    page_count = hp->bh_page_count;
+    if (freep != NULL && freep->bh_page_count >= page_count)
+    {
+	new_bnum = freep->bh_bnum;
+	/*
+	 * If the page count of the free block was larger, recude it.
+	 * If the page count matches, remove the block from the free list
+	 */
+	if (freep->bh_page_count > page_count)
+	{
+	    freep->bh_bnum += page_count;
+	    freep->bh_page_count -= page_count;
+	}
+	else
+	{
+	    freep = mf_rem_free(mfp);
+	    vim_free(freep);
+	}
+    }
+    else
+    {
+	new_bnum = mfp->mf_blocknr_max;
+	mfp->mf_blocknr_max += page_count;
+    }
+
+    np->nt_old_bnum = hp->bh_bnum;	    /* adjust number */
+    np->nt_new_bnum = new_bnum;
+
+    mf_rem_hash(mfp, hp);		    /* remove from old hash list */
+    hp->bh_bnum = new_bnum;
+    mf_ins_hash(mfp, hp);		    /* insert in new hash list */
+
+    hash = MEMHASH(np->nt_old_bnum);	    /* insert in trans list */
+    np->nt_next = mfp->mf_trans[hash];
+    mfp->mf_trans[hash] = np;
+    if (np->nt_next != NULL)
+	np->nt_next->nt_prev = np;
+    np->nt_prev = NULL;
+
+    return OK;
+}
+
+/*
+ * Lookup a translation from the trans lists and delete the entry
+ *
+ * Return the positive new number when found, the old number when not found
+ */
+    blocknr_T
+mf_trans_del(mfp, old_nr)
+    memfile_T	*mfp;
+    blocknr_T	old_nr;
+{
+    int		hash;
+    NR_TRANS	*np;
+    blocknr_T	new_bnum;
+
+    hash = MEMHASH(old_nr);
+    for (np = mfp->mf_trans[hash]; np != NULL; np = np->nt_next)
+	if (np->nt_old_bnum == old_nr)
+	    break;
+    if (np == NULL)		/* not found */
+	return old_nr;
+
+    mfp->mf_neg_count--;
+    new_bnum = np->nt_new_bnum;
+    if (np->nt_prev != NULL)		/* remove entry from the trans list */
+	np->nt_prev->nt_next = np->nt_next;
+    else
+	mfp->mf_trans[hash] = np->nt_next;
+    if (np->nt_next != NULL)
+	np->nt_next->nt_prev = np->nt_prev;
+    vim_free(np);
+
+    return new_bnum;
+}
+
+/*
+ * Set mfp->mf_ffname according to mfp->mf_fname and some other things.
+ * Only called when creating or renaming the swapfile.	Either way it's a new
+ * name so we must work out the full path name.
+ */
+    void
+mf_set_ffname(mfp)
+    memfile_T	*mfp;
+{
+    mfp->mf_ffname = FullName_save(mfp->mf_fname, FALSE);
+}
+
+/*
+ * Make the name of the file used for the memfile a full path.
+ * Used before doing a :cd
+ */
+    void
+mf_fullname(mfp)
+    memfile_T	*mfp;
+{
+    if (mfp != NULL && mfp->mf_fname != NULL && mfp->mf_ffname != NULL)
+    {
+	vim_free(mfp->mf_fname);
+	mfp->mf_fname = mfp->mf_ffname;
+	mfp->mf_ffname = NULL;
+    }
+}
+
+/*
+ * return TRUE if there are any translations pending for 'mfp'
+ */
+    int
+mf_need_trans(mfp)
+    memfile_T	*mfp;
+{
+    return (mfp->mf_fname != NULL && mfp->mf_neg_count > 0);
+}
+
+/*
+ * Open a swap file for a memfile.
+ * The "fname" must be in allocated memory, and is consumed (also when an
+ * error occurs).
+ */
+    static void
+mf_do_open(mfp, fname, flags)
+    memfile_T	*mfp;
+    char_u	*fname;
+    int		flags;		/* flags for open() */
+{
+#ifdef HAVE_LSTAT
+    struct stat sb;
+#endif
+
+    mfp->mf_fname = fname;
+
+    /*
+     * Get the full path name before the open, because this is
+     * not possible after the open on the Amiga.
+     * fname cannot be NameBuff, because it must have been allocated.
+     */
+    mf_set_ffname(mfp);
+#if defined(MSDOS) || defined(MSWIN) || defined(RISCOS)
+    /*
+     * A ":!cd e:xxx" may change the directory without us knowning, use the
+     * full pathname always.  Careful: This frees fname!
+     */
+    mf_fullname(mfp);
+#endif
+
+#ifdef HAVE_LSTAT
+    /*
+     * Extra security check: When creating a swap file it really shouldn't
+     * exist yet.  If there is a symbolic link, this is most likely an attack.
+     */
+    if ((flags & O_CREAT) && mch_lstat((char *)mfp->mf_fname, &sb) >= 0)
+    {
+	mfp->mf_fd = -1;
+	EMSG(_("E300: Swap file already exists (symlink attack?)"));
+    }
+    else
+#endif
+    {
+	/*
+	 * try to open the file
+	 */
+	flags |= O_EXTRA | O_NOFOLLOW;
+#ifdef WIN32
+	/* Prevent handle inheritance that cause problems with Cscope
+	 * (swap file may not be deleted if cscope connection was open after
+	 * the file) */
+	flags |= O_NOINHERIT;
+#endif
+	mfp->mf_fd = mch_open_rw((char *)mfp->mf_fname, flags);
+    }
+
+    /*
+     * If the file cannot be opened, use memory only
+     */
+    if (mfp->mf_fd < 0)
+    {
+	vim_free(mfp->mf_fname);
+	vim_free(mfp->mf_ffname);
+	mfp->mf_fname = NULL;
+	mfp->mf_ffname = NULL;
+    }
+    else
+	mch_hide(mfp->mf_fname);    /* try setting the 'hidden' flag */
+}
--- /dev/null
+++ b/memline.c
@@ -1,0 +1,4861 @@
+/* vi:set ts=8 sts=4 sw=4:
+ *
+ * VIM - Vi IMproved	by Bram Moolenaar
+ *
+ * Do ":help uganda"  in Vim to read copying and usage conditions.
+ * Do ":help credits" in Vim to see a list of people who contributed.
+ * See README.txt for an overview of the Vim source code.
+ */
+
+/* for debugging */
+/* #define CHECK(c, s)	if (c) EMSG(s) */
+#define CHECK(c, s)
+
+/*
+ * memline.c: Contains the functions for appending, deleting and changing the
+ * text lines. The memfile functions are used to store the information in
+ * blocks of memory, backed up by a file. The structure of the information is
+ * a tree.  The root of the tree is a pointer block. The leaves of the tree
+ * are data blocks. In between may be several layers of pointer blocks,
+ * forming branches.
+ *
+ * Three types of blocks are used:
+ * - Block nr 0 contains information for recovery
+ * - Pointer blocks contain list of pointers to other blocks.
+ * - Data blocks contain the actual text.
+ *
+ * Block nr 0 contains the block0 structure (see below).
+ *
+ * Block nr 1 is the first pointer block. It is the root of the tree.
+ * Other pointer blocks are branches.
+ *
+ *  If a line is too big to fit in a single page, the block containing that
+ *  line is made big enough to hold the line. It may span several pages.
+ *  Otherwise all blocks are one page.
+ *
+ *  A data block that was filled when starting to edit a file and was not
+ *  changed since then, can have a negative block number. This means that it
+ *  has not yet been assigned a place in the file. When recovering, the lines
+ *  in this data block can be read from the original file. When the block is
+ *  changed (lines appended/deleted/changed) or when it is flushed it gets a
+ *  positive number. Use mf_trans_del() to get the new number, before calling
+ *  mf_get().
+ */
+
+#if defined(MSDOS) || defined(WIN32) || defined(_WIN64)
+# include "vimio.h"
+#endif
+
+#include "vim.h"
+
+#ifdef HAVE_FCNTL_H
+# include <fcntl.h>
+#endif
+#ifndef UNIX		/* it's in os_unix.h for Unix */
+# include <time.h>
+#endif
+
+#if defined(SASC) || defined(__amigaos4__)
+# include <proto/dos.h>	    /* for Open() and Close() */
+#endif
+
+#ifdef HAVE_ERRNO_H
+# include <errno.h>
+#endif
+
+typedef struct block0		ZERO_BL;    /* contents of the first block */
+typedef struct pointer_block	PTR_BL;	    /* contents of a pointer block */
+typedef struct data_block	DATA_BL;    /* contents of a data block */
+typedef struct pointer_entry	PTR_EN;	    /* block/line-count pair */
+
+#define DATA_ID	    (('d' << 8) + 'a')	    /* data block id */
+#define PTR_ID	    (('p' << 8) + 't')	    /* pointer block id */
+#define BLOCK0_ID0  'b'			    /* block 0 id 0 */
+#define BLOCK0_ID1  '0'			    /* block 0 id 1 */
+
+/*
+ * pointer to a block, used in a pointer block
+ */
+struct pointer_entry
+{
+    blocknr_T	pe_bnum;	/* block number */
+    linenr_T	pe_line_count;	/* number of lines in this branch */
+    linenr_T	pe_old_lnum;	/* lnum for this block (for recovery) */
+    int		pe_page_count;	/* number of pages in block pe_bnum */
+};
+
+/*
+ * A pointer block contains a list of branches in the tree.
+ */
+struct pointer_block
+{
+    short_u	pb_id;		/* ID for pointer block: PTR_ID */
+    short_u	pb_count;	/* number of pointer in this block */
+    short_u	pb_count_max;	/* maximum value for pb_count */
+    PTR_EN	pb_pointer[1];	/* list of pointers to blocks (actually longer)
+				 * followed by empty space until end of page */
+};
+
+/*
+ * A data block is a leaf in the tree.
+ *
+ * The text of the lines is at the end of the block. The text of the first line
+ * in the block is put at the end, the text of the second line in front of it,
+ * etc. Thus the order of the lines is the opposite of the line number.
+ */
+struct data_block
+{
+    short_u	db_id;		/* ID for data block: DATA_ID */
+    unsigned	db_free;	/* free space available */
+    unsigned	db_txt_start;	/* byte where text starts */
+    unsigned	db_txt_end;	/* byte just after data block */
+    linenr_T	db_line_count;	/* number of lines in this block */
+    unsigned	db_index[1];	/* index for start of line (actually bigger)
+				 * followed by empty space upto db_txt_start
+				 * followed by the text in the lines until
+				 * end of page */
+};
+
+/*
+ * The low bits of db_index hold the actual index. The topmost bit is
+ * used for the global command to be able to mark a line.
+ * This method is not clean, but otherwise there would be at least one extra
+ * byte used for each line.
+ * The mark has to be in this place to keep it with the correct line when other
+ * lines are inserted or deleted.
+ */
+#define DB_MARKED	((unsigned)1 << ((sizeof(unsigned) * 8) - 1))
+#define DB_INDEX_MASK	(~DB_MARKED)
+
+#define INDEX_SIZE  (sizeof(unsigned))	    /* size of one db_index entry */
+#define HEADER_SIZE (sizeof(DATA_BL) - INDEX_SIZE)  /* size of data block header */
+
+#define B0_FNAME_SIZE_ORG	900	/* what it was in older versions */
+#define B0_FNAME_SIZE		898
+#define B0_UNAME_SIZE		40
+#define B0_HNAME_SIZE		40
+/*
+ * Restrict the numbers to 32 bits, otherwise most compilers will complain.
+ * This won't detect a 64 bit machine that only swaps a byte in the top 32
+ * bits, but that is crazy anyway.
+ */
+#define B0_MAGIC_LONG	0x30313233L
+#define B0_MAGIC_INT	0x20212223L
+#define B0_MAGIC_SHORT	0x10111213L
+#define B0_MAGIC_CHAR	0x55
+
+/*
+ * Block zero holds all info about the swap file.
+ *
+ * NOTE: DEFINITION OF BLOCK 0 SHOULD NOT CHANGE! It would make all existing
+ * swap files unusable!
+ *
+ * If size of block0 changes anyway, adjust MIN_SWAP_PAGE_SIZE in vim.h!!
+ *
+ * This block is built up of single bytes, to make it portable across
+ * different machines. b0_magic_* is used to check the byte order and size of
+ * variables, because the rest of the swap file is not portable.
+ */
+struct block0
+{
+    char_u	b0_id[2];	/* id for block 0: BLOCK0_ID0 and BLOCK0_ID1 */
+    char_u	b0_version[10];	/* Vim version string */
+    char_u	b0_page_size[4];/* number of bytes per page */
+    char_u	b0_mtime[4];	/* last modification time of file */
+    char_u	b0_ino[4];	/* inode of b0_fname */
+    char_u	b0_pid[4];	/* process id of creator (or 0) */
+    char_u	b0_uname[B0_UNAME_SIZE]; /* name of user (uid if no name) */
+    char_u	b0_hname[B0_HNAME_SIZE]; /* host name (if it has a name) */
+    char_u	b0_fname[B0_FNAME_SIZE_ORG]; /* name of file being edited */
+    long	b0_magic_long;	/* check for byte order of long */
+    int		b0_magic_int;	/* check for byte order of int */
+    short	b0_magic_short;	/* check for byte order of short */
+    char_u	b0_magic_char;	/* check for last char */
+};
+
+/*
+ * Note: b0_dirty and b0_flags are put at the end of the file name.  For very
+ * long file names in older versions of Vim they are invalid.
+ * The 'fileencoding' comes before b0_flags, with a NUL in front.  But only
+ * when there is room, for very long file names it's omitted.
+ */
+#define B0_DIRTY	0x55
+#define b0_dirty	b0_fname[B0_FNAME_SIZE_ORG-1]
+
+/*
+ * The b0_flags field is new in Vim 7.0.
+ */
+#define b0_flags	b0_fname[B0_FNAME_SIZE_ORG-2]
+
+/* The lowest two bits contain the fileformat.  Zero means it's not set
+ * (compatible with Vim 6.x), otherwise it's EOL_UNIX + 1, EOL_DOS + 1 or
+ * EOL_MAC + 1. */
+#define B0_FF_MASK	3
+
+/* Swap file is in directory of edited file.  Used to find the file from
+ * different mount points. */
+#define B0_SAME_DIR	4
+
+/* The 'fileencoding' is at the end of b0_fname[], with a NUL in front of it.
+ * When empty there is only the NUL. */
+#define B0_HAS_FENC	8
+
+#define STACK_INCR	5	/* nr of entries added to ml_stack at a time */
+
+/*
+ * The line number where the first mark may be is remembered.
+ * If it is 0 there are no marks at all.
+ * (always used for the current buffer only, no buffer change possible while
+ * executing a global command).
+ */
+static linenr_T	lowest_marked = 0;
+
+/*
+ * arguments for ml_find_line()
+ */
+#define ML_DELETE	0x11	    /* delete line */
+#define ML_INSERT	0x12	    /* insert line */
+#define ML_FIND		0x13	    /* just find the line */
+#define ML_FLUSH	0x02	    /* flush locked block */
+#define ML_SIMPLE(x)	(x & 0x10)  /* DEL, INS or FIND */
+
+static void ml_upd_block0 __ARGS((buf_T *buf, int set_fname));
+static void set_b0_fname __ARGS((ZERO_BL *, buf_T *buf));
+static void set_b0_dir_flag __ARGS((ZERO_BL *b0p, buf_T *buf));
+#ifdef FEAT_MBYTE
+static void add_b0_fenc __ARGS((ZERO_BL *b0p, buf_T *buf));
+#endif
+static time_t swapfile_info __ARGS((char_u *));
+static int recov_file_names __ARGS((char_u **, char_u *, int prepend_dot));
+static int ml_append_int __ARGS((buf_T *, linenr_T, char_u *, colnr_T, int, int));
+static int ml_delete_int __ARGS((buf_T *, linenr_T, int));
+static char_u *findswapname __ARGS((buf_T *, char_u **, char_u *));
+static void ml_flush_line __ARGS((buf_T *));
+static bhdr_T *ml_new_data __ARGS((memfile_T *, int, int));
+static bhdr_T *ml_new_ptr __ARGS((memfile_T *));
+static bhdr_T *ml_find_line __ARGS((buf_T *, linenr_T, int));
+static int ml_add_stack __ARGS((buf_T *));
+static void ml_lineadd __ARGS((buf_T *, int));
+static int b0_magic_wrong __ARGS((ZERO_BL *));
+#ifdef CHECK_INODE
+static int fnamecmp_ino __ARGS((char_u *, char_u *, long));
+#endif
+static void long_to_char __ARGS((long, char_u *));
+static long char_to_long __ARGS((char_u *));
+#if defined(UNIX) || defined(WIN3264)
+static char_u *make_percent_swname __ARGS((char_u *dir, char_u *name));
+#endif
+#ifdef FEAT_BYTEOFF
+static void ml_updatechunk __ARGS((buf_T *buf, long line, long len, int updtype));
+#endif
+
+/*
+ * Open a new memline for "buf".
+ *
+ * Return FAIL for failure, OK otherwise.
+ */
+    int
+ml_open(buf)
+    buf_T	*buf;
+{
+    memfile_T	*mfp;
+    bhdr_T	*hp = NULL;
+    ZERO_BL	*b0p;
+    PTR_BL	*pp;
+    DATA_BL	*dp;
+
+    /*
+     * init fields in memline struct
+     */
+    buf->b_ml.ml_stack_size = 0;	/* no stack yet */
+    buf->b_ml.ml_stack = NULL;	/* no stack yet */
+    buf->b_ml.ml_stack_top = 0;	/* nothing in the stack */
+    buf->b_ml.ml_locked = NULL;	/* no cached block */
+    buf->b_ml.ml_line_lnum = 0;	/* no cached line */
+#ifdef FEAT_BYTEOFF
+    buf->b_ml.ml_chunksize = NULL;
+#endif
+
+    /*
+     * When 'updatecount' is non-zero swap file may be opened later.
+     */
+    if (p_uc && buf->b_p_swf)
+	buf->b_may_swap = TRUE;
+    else
+	buf->b_may_swap = FALSE;
+
+    /*
+     * Open the memfile.  No swap file is created yet.
+     */
+    mfp = mf_open(NULL, 0);
+    if (mfp == NULL)
+	goto error;
+
+    buf->b_ml.ml_mfp = mfp;
+    buf->b_ml.ml_flags = ML_EMPTY;
+    buf->b_ml.ml_line_count = 1;
+#ifdef FEAT_LINEBREAK
+    curwin->w_nrwidth_line_count = 0;
+#endif
+
+#if defined(MSDOS) && !defined(DJGPP)
+    /* for 16 bit MS-DOS create a swapfile now, because we run out of
+     * memory very quickly */
+    if (p_uc != 0)
+	ml_open_file(buf);
+#endif
+
+/*
+ * fill block0 struct and write page 0
+ */
+    if ((hp = mf_new(mfp, FALSE, 1)) == NULL)
+	goto error;
+    if (hp->bh_bnum != 0)
+    {
+	EMSG(_("E298: Didn't get block nr 0?"));
+	goto error;
+    }
+    b0p = (ZERO_BL *)(hp->bh_data);
+
+    b0p->b0_id[0] = BLOCK0_ID0;
+    b0p->b0_id[1] = BLOCK0_ID1;
+    b0p->b0_magic_long = (long)B0_MAGIC_LONG;
+    b0p->b0_magic_int = (int)B0_MAGIC_INT;
+    b0p->b0_magic_short = (short)B0_MAGIC_SHORT;
+    b0p->b0_magic_char = B0_MAGIC_CHAR;
+    STRNCPY(b0p->b0_version, "VIM ", 4);
+    STRNCPY(b0p->b0_version + 4, Version, 6);
+    long_to_char((long)mfp->mf_page_size, b0p->b0_page_size);
+
+#ifdef FEAT_SPELL
+    if (!buf->b_spell)
+#endif
+    {
+	b0p->b0_dirty = buf->b_changed ? B0_DIRTY : 0;
+	b0p->b0_flags = get_fileformat(buf) + 1;
+	set_b0_fname(b0p, buf);
+	(void)get_user_name(b0p->b0_uname, B0_UNAME_SIZE);
+	b0p->b0_uname[B0_UNAME_SIZE - 1] = NUL;
+	mch_get_host_name(b0p->b0_hname, B0_HNAME_SIZE);
+	b0p->b0_hname[B0_HNAME_SIZE - 1] = NUL;
+	long_to_char(mch_get_pid(), b0p->b0_pid);
+    }
+
+    /*
+     * Always sync block number 0 to disk, so we can check the file name in
+     * the swap file in findswapname(). Don't do this for help files though
+     * and spell buffer though.
+     * Only works when there's a swapfile, otherwise it's done when the file
+     * is created.
+     */
+    mf_put(mfp, hp, TRUE, FALSE);
+    if (!buf->b_help && !B_SPELL(buf))
+	(void)mf_sync(mfp, 0);
+
+    /*
+     * Fill in root pointer block and write page 1.
+     */
+    if ((hp = ml_new_ptr(mfp)) == NULL)
+	goto error;
+    if (hp->bh_bnum != 1)
+    {
+	EMSG(_("E298: Didn't get block nr 1?"));
+	goto error;
+    }
+    pp = (PTR_BL *)(hp->bh_data);
+    pp->pb_count = 1;
+    pp->pb_pointer[0].pe_bnum = 2;
+    pp->pb_pointer[0].pe_page_count = 1;
+    pp->pb_pointer[0].pe_old_lnum = 1;
+    pp->pb_pointer[0].pe_line_count = 1;    /* line count after insertion */
+    mf_put(mfp, hp, TRUE, FALSE);
+
+    /*
+     * Allocate first data block and create an empty line 1.
+     */
+    if ((hp = ml_new_data(mfp, FALSE, 1)) == NULL)
+	goto error;
+    if (hp->bh_bnum != 2)
+    {
+	EMSG(_("E298: Didn't get block nr 2?"));
+	goto error;
+    }
+
+    dp = (DATA_BL *)(hp->bh_data);
+    dp->db_index[0] = --dp->db_txt_start;	/* at end of block */
+    dp->db_free -= 1 + INDEX_SIZE;
+    dp->db_line_count = 1;
+    *((char_u *)dp + dp->db_txt_start) = NUL;	/* emtpy line */
+
+    return OK;
+
+error:
+    if (mfp != NULL)
+    {
+	if (hp)
+	    mf_put(mfp, hp, FALSE, FALSE);
+	mf_close(mfp, TRUE);	    /* will also free(mfp->mf_fname) */
+    }
+    buf->b_ml.ml_mfp = NULL;
+    return FAIL;
+}
+
+/*
+ * ml_setname() is called when the file name of "buf" has been changed.
+ * It may rename the swap file.
+ */
+    void
+ml_setname(buf)
+    buf_T	*buf;
+{
+    int		success = FALSE;
+    memfile_T	*mfp;
+    char_u	*fname;
+    char_u	*dirp;
+#if defined(MSDOS) || defined(MSWIN)
+    char_u	*p;
+#endif
+
+    mfp = buf->b_ml.ml_mfp;
+    if (mfp->mf_fd < 0)		    /* there is no swap file yet */
+    {
+	/*
+	 * When 'updatecount' is 0 and 'noswapfile' there is no swap file.
+	 * For help files we will make a swap file now.
+	 */
+	if (p_uc != 0)
+	    ml_open_file(buf);	    /* create a swap file */
+	return;
+    }
+
+    /*
+     * Try all directories in the 'directory' option.
+     */
+    dirp = p_dir;
+    for (;;)
+    {
+	if (*dirp == NUL)	    /* tried all directories, fail */
+	    break;
+	fname = findswapname(buf, &dirp, mfp->mf_fname);
+						    /* alloc's fname */
+	if (fname == NULL)	    /* no file name found for this dir */
+	    continue;
+
+#if defined(MSDOS) || defined(MSWIN)
+	/*
+	 * Set full pathname for swap file now, because a ":!cd dir" may
+	 * change directory without us knowing it.
+	 */
+	p = FullName_save(fname, FALSE);
+	vim_free(fname);
+	fname = p;
+	if (fname == NULL)
+	    continue;
+#endif
+	/* if the file name is the same we don't have to do anything */
+	if (fnamecmp(fname, mfp->mf_fname) == 0)
+	{
+	    vim_free(fname);
+	    success = TRUE;
+	    break;
+	}
+	/* need to close the swap file before renaming */
+	if (mfp->mf_fd >= 0)
+	{
+	    close(mfp->mf_fd);
+	    mfp->mf_fd = -1;
+	}
+
+	/* try to rename the swap file */
+	if (vim_rename(mfp->mf_fname, fname) == 0)
+	{
+	    success = TRUE;
+	    vim_free(mfp->mf_fname);
+	    mfp->mf_fname = fname;
+	    vim_free(mfp->mf_ffname);
+#if defined(MSDOS) || defined(MSWIN)
+	    mfp->mf_ffname = NULL;  /* mf_fname is full pathname already */
+#else
+	    mf_set_ffname(mfp);
+#endif
+	    ml_upd_block0(buf, FALSE);
+	    break;
+	}
+	vim_free(fname);	    /* this fname didn't work, try another */
+    }
+
+    if (mfp->mf_fd == -1)	    /* need to (re)open the swap file */
+    {
+	mfp->mf_fd = mch_open((char *)mfp->mf_fname, O_RDWR | O_EXTRA, 0);
+	if (mfp->mf_fd < 0)
+	{
+	    /* could not (re)open the swap file, what can we do???? */
+	    EMSG(_("E301: Oops, lost the swap file!!!"));
+	    return;
+	}
+    }
+    if (!success)
+	EMSG(_("E302: Could not rename swap file"));
+}
+
+/*
+ * Open a file for the memfile for all buffers that are not readonly or have
+ * been modified.
+ * Used when 'updatecount' changes from zero to non-zero.
+ */
+    void
+ml_open_files()
+{
+    buf_T	*buf;
+
+    for (buf = firstbuf; buf != NULL; buf = buf->b_next)
+	if (!buf->b_p_ro || buf->b_changed)
+	    ml_open_file(buf);
+}
+
+/*
+ * Open a swap file for an existing memfile, if there is no swap file yet.
+ * If we are unable to find a file name, mf_fname will be NULL
+ * and the memfile will be in memory only (no recovery possible).
+ */
+    void
+ml_open_file(buf)
+    buf_T	*buf;
+{
+    memfile_T	*mfp;
+    char_u	*fname;
+    char_u	*dirp;
+
+    mfp = buf->b_ml.ml_mfp;
+    if (mfp == NULL || mfp->mf_fd >= 0 || !buf->b_p_swf)
+	return;		/* nothing to do */
+
+#ifdef FEAT_SPELL
+    /* For a spell buffer use a temp file name. */
+    if (buf->b_spell)
+    {
+	fname = vim_tempname('s');
+	if (fname != NULL)
+	    (void)mf_open_file(mfp, fname);	/* consumes fname! */
+	buf->b_may_swap = FALSE;
+	return;
+    }
+#endif
+
+    /*
+     * Try all directories in 'directory' option.
+     */
+    dirp = p_dir;
+    for (;;)
+    {
+	if (*dirp == NUL)
+	    break;
+	/* There is a small chance that between chosing the swap file name and
+	 * creating it, another Vim creates the file.  In that case the
+	 * creation will fail and we will use another directory. */
+	fname = findswapname(buf, &dirp, NULL); /* allocates fname */
+	if (fname == NULL)
+	    continue;
+	if (mf_open_file(mfp, fname) == OK)	/* consumes fname! */
+	{
+#if defined(MSDOS) || defined(MSWIN) || defined(RISCOS)
+	    /*
+	     * set full pathname for swap file now, because a ":!cd dir" may
+	     * change directory without us knowing it.
+	     */
+	    mf_fullname(mfp);
+#endif
+	    ml_upd_block0(buf, FALSE);
+
+	    /* Flush block zero, so others can read it */
+	    if (mf_sync(mfp, MFS_ZERO) == OK)
+	    {
+		/* Mark all blocks that should be in the swapfile as dirty.
+		 * Needed for when the 'swapfile' option was reset, so that
+		 * the swap file was deleted, and then on again. */
+		mf_set_dirty(mfp);
+		break;
+	    }
+	    /* Writing block 0 failed: close the file and try another dir */
+	    mf_close_file(buf, FALSE);
+	}
+    }
+
+    if (mfp->mf_fname == NULL)		/* Failed! */
+    {
+	need_wait_return = TRUE;	/* call wait_return later */
+	++no_wait_return;
+	(void)EMSG2(_("E303: Unable to open swap file for \"%s\", recovery impossible"),
+		    buf_spname(buf) != NULL
+			? (char_u *)buf_spname(buf)
+			: buf->b_fname);
+	--no_wait_return;
+    }
+
+    /* don't try to open a swap file again */
+    buf->b_may_swap = FALSE;
+}
+
+/*
+ * If still need to create a swap file, and starting to edit a not-readonly
+ * file, or reading into an existing buffer, create a swap file now.
+ */
+    void
+check_need_swap(newfile)
+    int	    newfile;		/* reading file into new buffer */
+{
+    if (curbuf->b_may_swap && (!curbuf->b_p_ro || !newfile))
+	ml_open_file(curbuf);
+}
+
+/*
+ * Close memline for buffer 'buf'.
+ * If 'del_file' is TRUE, delete the swap file
+ */
+    void
+ml_close(buf, del_file)
+    buf_T	*buf;
+    int		del_file;
+{
+    if (buf->b_ml.ml_mfp == NULL)		/* not open */
+	return;
+    mf_close(buf->b_ml.ml_mfp, del_file);	/* close the .swp file */
+    if (buf->b_ml.ml_line_lnum != 0 && (buf->b_ml.ml_flags & ML_LINE_DIRTY))
+	vim_free(buf->b_ml.ml_line_ptr);
+    vim_free(buf->b_ml.ml_stack);
+#ifdef FEAT_BYTEOFF
+    vim_free(buf->b_ml.ml_chunksize);
+    buf->b_ml.ml_chunksize = NULL;
+#endif
+    buf->b_ml.ml_mfp = NULL;
+
+    /* Reset the "recovered" flag, give the ATTENTION prompt the next time
+     * this buffer is loaded. */
+    buf->b_flags &= ~BF_RECOVERED;
+}
+
+/*
+ * Close all existing memlines and memfiles.
+ * Only used when exiting.
+ * When 'del_file' is TRUE, delete the memfiles.
+ * But don't delete files that were ":preserve"d when we are POSIX compatible.
+ */
+    void
+ml_close_all(del_file)
+    int		del_file;
+{
+    buf_T	*buf;
+
+    for (buf = firstbuf; buf != NULL; buf = buf->b_next)
+	ml_close(buf, del_file && ((buf->b_flags & BF_PRESERVED) == 0
+				 || vim_strchr(p_cpo, CPO_PRESERVE) == NULL));
+#ifdef TEMPDIRNAMES
+    vim_deltempdir();	    /* delete created temp directory */
+#endif
+}
+
+/*
+ * Close all memfiles for not modified buffers.
+ * Only use just before exiting!
+ */
+    void
+ml_close_notmod()
+{
+    buf_T	*buf;
+
+    for (buf = firstbuf; buf != NULL; buf = buf->b_next)
+	if (!bufIsChanged(buf))
+	    ml_close(buf, TRUE);    /* close all not-modified buffers */
+}
+
+/*
+ * Update the timestamp in the .swp file.
+ * Used when the file has been written.
+ */
+    void
+ml_timestamp(buf)
+    buf_T	*buf;
+{
+    ml_upd_block0(buf, TRUE);
+}
+
+/*
+ * Update the timestamp or the B0_SAME_DIR flag of the .swp file.
+ */
+    static void
+ml_upd_block0(buf, set_fname)
+    buf_T	*buf;
+    int		set_fname;
+{
+    memfile_T	*mfp;
+    bhdr_T	*hp;
+    ZERO_BL	*b0p;
+
+    mfp = buf->b_ml.ml_mfp;
+    if (mfp == NULL || (hp = mf_get(mfp, (blocknr_T)0, 1)) == NULL)
+	return;
+    b0p = (ZERO_BL *)(hp->bh_data);
+    if (b0p->b0_id[0] != BLOCK0_ID0 || b0p->b0_id[1] != BLOCK0_ID1)
+	EMSG(_("E304: ml_upd_block0(): Didn't get block 0??"));
+    else
+    {
+	if (set_fname)
+	    set_b0_fname(b0p, buf);
+	else
+	    set_b0_dir_flag(b0p, buf);
+    }
+    mf_put(mfp, hp, TRUE, FALSE);
+}
+
+/*
+ * Write file name and timestamp into block 0 of a swap file.
+ * Also set buf->b_mtime.
+ * Don't use NameBuff[]!!!
+ */
+    static void
+set_b0_fname(b0p, buf)
+    ZERO_BL	*b0p;
+    buf_T	*buf;
+{
+    struct stat	st;
+
+    if (buf->b_ffname == NULL)
+	b0p->b0_fname[0] = NUL;
+    else
+    {
+#if defined(MSDOS) || defined(MSWIN) || defined(AMIGA) || defined(RISCOS)
+	/* Systems that cannot translate "~user" back into a path: copy the
+	 * file name unmodified.  Do use slashes instead of backslashes for
+	 * portability. */
+	vim_strncpy(b0p->b0_fname, buf->b_ffname, B0_FNAME_SIZE - 1);
+# ifdef BACKSLASH_IN_FILENAME
+	forward_slash(b0p->b0_fname);
+# endif
+#else
+	size_t	flen, ulen;
+	char_u	uname[B0_UNAME_SIZE];
+
+	/*
+	 * For a file under the home directory of the current user, we try to
+	 * replace the home directory path with "~user". This helps when
+	 * editing the same file on different machines over a network.
+	 * First replace home dir path with "~/" with home_replace().
+	 * Then insert the user name to get "~user/".
+	 */
+	home_replace(NULL, buf->b_ffname, b0p->b0_fname, B0_FNAME_SIZE, TRUE);
+	if (b0p->b0_fname[0] == '~')
+	{
+	    flen = STRLEN(b0p->b0_fname);
+	    /* If there is no user name or it is too long, don't use "~/" */
+	    if (get_user_name(uname, B0_UNAME_SIZE) == FAIL
+			 || (ulen = STRLEN(uname)) + flen > B0_FNAME_SIZE - 1)
+		vim_strncpy(b0p->b0_fname, buf->b_ffname, B0_FNAME_SIZE - 1);
+	    else
+	    {
+		mch_memmove(b0p->b0_fname + ulen + 1, b0p->b0_fname + 1, flen);
+		mch_memmove(b0p->b0_fname + 1, uname, ulen);
+	    }
+	}
+#endif
+	if (mch_stat((char *)buf->b_ffname, &st) >= 0)
+	{
+	    long_to_char((long)st.st_mtime, b0p->b0_mtime);
+#ifdef CHECK_INODE
+	    long_to_char((long)st.st_ino, b0p->b0_ino);
+#endif
+	    buf_store_time(buf, &st, buf->b_ffname);
+	    buf->b_mtime_read = buf->b_mtime;
+	}
+	else
+	{
+	    long_to_char(0L, b0p->b0_mtime);
+#ifdef CHECK_INODE
+	    long_to_char(0L, b0p->b0_ino);
+#endif
+	    buf->b_mtime = 0;
+	    buf->b_mtime_read = 0;
+	    buf->b_orig_size = 0;
+	    buf->b_orig_mode = 0;
+	}
+    }
+
+#ifdef FEAT_MBYTE
+    /* Also add the 'fileencoding' if there is room. */
+    add_b0_fenc(b0p, curbuf);
+#endif
+}
+
+/*
+ * Update the B0_SAME_DIR flag of the swap file.  It's set if the file and the
+ * swapfile for "buf" are in the same directory.
+ * This is fail safe: if we are not sure the directories are equal the flag is
+ * not set.
+ */
+    static void
+set_b0_dir_flag(b0p, buf)
+    ZERO_BL	*b0p;
+    buf_T	*buf;
+{
+    if (same_directory(buf->b_ml.ml_mfp->mf_fname, buf->b_ffname))
+	b0p->b0_flags |= B0_SAME_DIR;
+    else
+	b0p->b0_flags &= ~B0_SAME_DIR;
+}
+
+#ifdef FEAT_MBYTE
+/*
+ * When there is room, add the 'fileencoding' to block zero.
+ */
+    static void
+add_b0_fenc(b0p, buf)
+    ZERO_BL	*b0p;
+    buf_T	*buf;
+{
+    int		n;
+
+    n = (int)STRLEN(buf->b_p_fenc);
+    if (STRLEN(b0p->b0_fname) + n + 1 > B0_FNAME_SIZE)
+	b0p->b0_flags &= ~B0_HAS_FENC;
+    else
+    {
+	mch_memmove((char *)b0p->b0_fname + B0_FNAME_SIZE - n,
+					    (char *)buf->b_p_fenc, (size_t)n);
+	*(b0p->b0_fname + B0_FNAME_SIZE - n - 1) = NUL;
+	b0p->b0_flags |= B0_HAS_FENC;
+    }
+}
+#endif
+
+
+/*
+ * try to recover curbuf from the .swp file
+ */
+    void
+ml_recover()
+{
+    buf_T	*buf = NULL;
+    memfile_T	*mfp = NULL;
+    char_u	*fname;
+    bhdr_T	*hp = NULL;
+    ZERO_BL	*b0p;
+    int		b0_ff;
+    char_u	*b0_fenc = NULL;
+    PTR_BL	*pp;
+    DATA_BL	*dp;
+    infoptr_T	*ip;
+    blocknr_T	bnum;
+    int		page_count;
+    struct stat	org_stat, swp_stat;
+    int		len;
+    int		directly;
+    linenr_T	lnum;
+    char_u	*p;
+    int		i;
+    long	error;
+    int		cannot_open;
+    linenr_T	line_count;
+    int		has_error;
+    int		idx;
+    int		top;
+    int		txt_start;
+    off_t	size;
+    int		called_from_main;
+    int		serious_error = TRUE;
+    long	mtime;
+    int		attr;
+
+    recoverymode = TRUE;
+    called_from_main = (curbuf->b_ml.ml_mfp == NULL);
+    attr = hl_attr(HLF_E);
+/*
+ * If the file name ends in ".sw?" we use it directly.
+ * Otherwise a search is done to find the swap file(s).
+ */
+    fname = curbuf->b_fname;
+    if (fname == NULL)		    /* When there is no file name */
+	fname = (char_u *)"";
+    len = (int)STRLEN(fname);
+    if (len >= 4 &&
+#if defined(VMS) || defined(RISCOS)
+	    STRNICMP(fname + len - 4, "_sw" , 3)
+#else
+	    STRNICMP(fname + len - 4, ".sw" , 3)
+#endif
+		== 0)
+    {
+	directly = TRUE;
+	fname = vim_strsave(fname); /* make a copy for mf_open() */
+    }
+    else
+    {
+	directly = FALSE;
+
+	/* count the number of matching swap files */
+	len = recover_names(&fname, FALSE, 0);
+	if (len == 0)		    /* no swap files found */
+	{
+	    EMSG2(_("E305: No swap file found for %s"), fname);
+	    goto theend;
+	}
+	if (len == 1)		    /* one swap file found, use it */
+	    i = 1;
+	else			    /* several swap files found, choose */
+	{
+	    /* list the names of the swap files */
+	    (void)recover_names(&fname, TRUE, 0);
+	    msg_putchar('\n');
+	    MSG_PUTS(_("Enter number of swap file to use (0 to quit): "));
+	    i = get_number(FALSE, NULL);
+	    if (i < 1 || i > len)
+		goto theend;
+	}
+	/* get the swap file name that will be used */
+	(void)recover_names(&fname, FALSE, i);
+    }
+    if (fname == NULL)
+	goto theend;			/* out of memory */
+
+    /* When called from main() still need to initialize storage structure */
+    if (called_from_main && ml_open(curbuf) == FAIL)
+	getout(1);
+
+/*
+ * allocate a buffer structure (only the memline in it is really used)
+ */
+    buf = (buf_T *)alloc((unsigned)sizeof(buf_T));
+    if (buf == NULL)
+    {
+	vim_free(fname);
+	goto theend;
+    }
+
+/*
+ * init fields in memline struct
+ */
+    buf->b_ml.ml_stack_size = 0;	/* no stack yet */
+    buf->b_ml.ml_stack = NULL;		/* no stack yet */
+    buf->b_ml.ml_stack_top = 0;		/* nothing in the stack */
+    buf->b_ml.ml_line_lnum = 0;		/* no cached line */
+    buf->b_ml.ml_locked = NULL;		/* no locked block */
+    buf->b_ml.ml_flags = 0;
+
+/*
+ * open the memfile from the old swap file
+ */
+    p = vim_strsave(fname);		/* save fname for the message
+					   (mf_open() may free fname) */
+    mfp = mf_open(fname, O_RDONLY);	/* consumes fname! */
+    if (mfp == NULL || mfp->mf_fd < 0)
+    {
+	if (p != NULL)
+	{
+	    EMSG2(_("E306: Cannot open %s"), p);
+	    vim_free(p);
+	}
+	goto theend;
+    }
+    vim_free(p);
+    buf->b_ml.ml_mfp = mfp;
+
+    /*
+     * The page size set in mf_open() might be different from the page size
+     * used in the swap file, we must get it from block 0.  But to read block
+     * 0 we need a page size.  Use the minimal size for block 0 here, it will
+     * be set to the real value below.
+     */
+    mfp->mf_page_size = MIN_SWAP_PAGE_SIZE;
+
+/*
+ * try to read block 0
+ */
+    if ((hp = mf_get(mfp, (blocknr_T)0, 1)) == NULL)
+    {
+	msg_start();
+	MSG_PUTS_ATTR(_("Unable to read block 0 from "), attr | MSG_HIST);
+	msg_outtrans_attr(mfp->mf_fname, attr | MSG_HIST);
+	MSG_PUTS_ATTR(
+	   _("\nMaybe no changes were made or Vim did not update the swap file."),
+		attr | MSG_HIST);
+	msg_end();
+	goto theend;
+    }
+    b0p = (ZERO_BL *)(hp->bh_data);
+    if (STRNCMP(b0p->b0_version, "VIM 3.0", 7) == 0)
+    {
+	msg_start();
+	msg_outtrans_attr(mfp->mf_fname, MSG_HIST);
+	MSG_PUTS_ATTR(_(" cannot be used with this version of Vim.\n"),
+								    MSG_HIST);
+	MSG_PUTS_ATTR(_("Use Vim version 3.0.\n"), MSG_HIST);
+	msg_end();
+	goto theend;
+    }
+    if (b0p->b0_id[0] != BLOCK0_ID0 || b0p->b0_id[1] != BLOCK0_ID1)
+    {
+	EMSG2(_("E307: %s does not look like a Vim swap file"), mfp->mf_fname);
+	goto theend;
+    }
+    if (b0_magic_wrong(b0p))
+    {
+	msg_start();
+	msg_outtrans_attr(mfp->mf_fname, attr | MSG_HIST);
+#if defined(MSDOS) || defined(MSWIN)
+	if (STRNCMP(b0p->b0_hname, "PC ", 3) == 0)
+	    MSG_PUTS_ATTR(_(" cannot be used with this version of Vim.\n"),
+							     attr | MSG_HIST);
+	else
+#endif
+	    MSG_PUTS_ATTR(_(" cannot be used on this computer.\n"),
+							     attr | MSG_HIST);
+	MSG_PUTS_ATTR(_("The file was created on "), attr | MSG_HIST);
+	/* avoid going past the end of a currupted hostname */
+	b0p->b0_fname[0] = NUL;
+	MSG_PUTS_ATTR(b0p->b0_hname, attr | MSG_HIST);
+	MSG_PUTS_ATTR(_(",\nor the file has been damaged."), attr | MSG_HIST);
+	msg_end();
+	goto theend;
+    }
+
+    /*
+     * If we guessed the wrong page size, we have to recalculate the
+     * highest block number in the file.
+     */
+    if (mfp->mf_page_size != (unsigned)char_to_long(b0p->b0_page_size))
+    {
+	unsigned previous_page_size = mfp->mf_page_size;
+
+	mf_new_page_size(mfp, (unsigned)char_to_long(b0p->b0_page_size));
+	if (mfp->mf_page_size < previous_page_size)
+	{
+	    msg_start();
+	    msg_outtrans_attr(mfp->mf_fname, attr | MSG_HIST);
+	    MSG_PUTS_ATTR(_(" has been damaged (page size is smaller than minimum value).\n"),
+			attr | MSG_HIST);
+	    msg_end();
+	    goto theend;
+	}
+	if ((size = lseek(mfp->mf_fd, (off_t)0L, SEEK_END)) <= 0)
+	    mfp->mf_blocknr_max = 0;	    /* no file or empty file */
+	else
+	    mfp->mf_blocknr_max = (blocknr_T)(size / mfp->mf_page_size);
+	mfp->mf_infile_count = mfp->mf_blocknr_max;
+
+	/* need to reallocate the memory used to store the data */
+	p = alloc(mfp->mf_page_size);
+	if (p == NULL)
+	    goto theend;
+	mch_memmove(p, hp->bh_data, previous_page_size);
+	vim_free(hp->bh_data);
+	hp->bh_data = p;
+	b0p = (ZERO_BL *)(hp->bh_data);
+    }
+
+/*
+ * If .swp file name given directly, use name from swap file for buffer.
+ */
+    if (directly)
+    {
+	expand_env(b0p->b0_fname, NameBuff, MAXPATHL);
+	if (setfname(curbuf, NameBuff, NULL, TRUE) == FAIL)
+	    goto theend;
+    }
+
+    home_replace(NULL, mfp->mf_fname, NameBuff, MAXPATHL, TRUE);
+    smsg((char_u *)_("Using swap file \"%s\""), NameBuff);
+
+    if (buf_spname(curbuf) != NULL)
+	STRCPY(NameBuff, buf_spname(curbuf));
+    else
+	home_replace(NULL, curbuf->b_ffname, NameBuff, MAXPATHL, TRUE);
+    smsg((char_u *)_("Original file \"%s\""), NameBuff);
+    msg_putchar('\n');
+
+/*
+ * check date of swap file and original file
+ */
+    mtime = char_to_long(b0p->b0_mtime);
+    if (curbuf->b_ffname != NULL
+	    && mch_stat((char *)curbuf->b_ffname, &org_stat) != -1
+	    && ((mch_stat((char *)mfp->mf_fname, &swp_stat) != -1
+		    && org_stat.st_mtime > swp_stat.st_mtime)
+		|| org_stat.st_mtime != mtime))
+    {
+	EMSG(_("E308: Warning: Original file may have been changed"));
+    }
+    out_flush();
+
+    /* Get the 'fileformat' and 'fileencoding' from block zero. */
+    b0_ff = (b0p->b0_flags & B0_FF_MASK);
+    if (b0p->b0_flags & B0_HAS_FENC)
+    {
+	for (p = b0p->b0_fname + B0_FNAME_SIZE;
+				       p > b0p->b0_fname && p[-1] != NUL; --p)
+	    ;
+	b0_fenc = vim_strnsave(p, (int)(b0p->b0_fname + B0_FNAME_SIZE - p));
+    }
+
+    mf_put(mfp, hp, FALSE, FALSE);	/* release block 0 */
+    hp = NULL;
+
+    /*
+     * Now that we are sure that the file is going to be recovered, clear the
+     * contents of the current buffer.
+     */
+    while (!(curbuf->b_ml.ml_flags & ML_EMPTY))
+	ml_delete((linenr_T)1, FALSE);
+
+    /*
+     * Try reading the original file to obtain the values of 'fileformat',
+     * 'fileencoding', etc.  Ignore errors.  The text itself is not used.
+     */
+    if (curbuf->b_ffname != NULL)
+    {
+	(void)readfile(curbuf->b_ffname, NULL, (linenr_T)0,
+			      (linenr_T)0, (linenr_T)MAXLNUM, NULL, READ_NEW);
+	while (!(curbuf->b_ml.ml_flags & ML_EMPTY))
+	    ml_delete((linenr_T)1, FALSE);
+    }
+
+    /* Use the 'fileformat' and 'fileencoding' as stored in the swap file. */
+    if (b0_ff != 0)
+	set_fileformat(b0_ff - 1, OPT_LOCAL);
+    if (b0_fenc != NULL)
+    {
+	set_option_value((char_u *)"fenc", 0L, b0_fenc, OPT_LOCAL);
+	vim_free(b0_fenc);
+    }
+    unchanged(curbuf, TRUE);
+
+    bnum = 1;		/* start with block 1 */
+    page_count = 1;	/* which is 1 page */
+    lnum = 0;		/* append after line 0 in curbuf */
+    line_count = 0;
+    idx = 0;		/* start with first index in block 1 */
+    error = 0;
+    buf->b_ml.ml_stack_top = 0;
+    buf->b_ml.ml_stack = NULL;
+    buf->b_ml.ml_stack_size = 0;	/* no stack yet */
+
+    if (curbuf->b_ffname == NULL)
+	cannot_open = TRUE;
+    else
+	cannot_open = FALSE;
+
+    serious_error = FALSE;
+    for ( ; !got_int; line_breakcheck())
+    {
+	if (hp != NULL)
+	    mf_put(mfp, hp, FALSE, FALSE);	/* release previous block */
+
+	/*
+	 * get block
+	 */
+	if ((hp = mf_get(mfp, (blocknr_T)bnum, page_count)) == NULL)
+	{
+	    if (bnum == 1)
+	    {
+		EMSG2(_("E309: Unable to read block 1 from %s"), mfp->mf_fname);
+		goto theend;
+	    }
+	    ++error;
+	    ml_append(lnum++, (char_u *)_("???MANY LINES MISSING"),
+							    (colnr_T)0, TRUE);
+	}
+	else		/* there is a block */
+	{
+	    pp = (PTR_BL *)(hp->bh_data);
+	    if (pp->pb_id == PTR_ID)		/* it is a pointer block */
+	    {
+		/* check line count when using pointer block first time */
+		if (idx == 0 && line_count != 0)
+		{
+		    for (i = 0; i < (int)pp->pb_count; ++i)
+			line_count -= pp->pb_pointer[i].pe_line_count;
+		    if (line_count != 0)
+		    {
+			++error;
+			ml_append(lnum++, (char_u *)_("???LINE COUNT WRONG"),
+							    (colnr_T)0, TRUE);
+		    }
+		}
+
+		if (pp->pb_count == 0)
+		{
+		    ml_append(lnum++, (char_u *)_("???EMPTY BLOCK"),
+							    (colnr_T)0, TRUE);
+		    ++error;
+		}
+		else if (idx < (int)pp->pb_count)	/* go a block deeper */
+		{
+		    if (pp->pb_pointer[idx].pe_bnum < 0)
+		    {
+			/*
+			 * Data block with negative block number.
+			 * Try to read lines from the original file.
+			 * This is slow, but it works.
+			 */
+			if (!cannot_open)
+			{
+			    line_count = pp->pb_pointer[idx].pe_line_count;
+			    if (readfile(curbuf->b_ffname, NULL, lnum,
+					pp->pb_pointer[idx].pe_old_lnum - 1,
+					line_count, NULL, 0) == FAIL)
+				cannot_open = TRUE;
+			    else
+				lnum += line_count;
+			}
+			if (cannot_open)
+			{
+			    ++error;
+			    ml_append(lnum++, (char_u *)_("???LINES MISSING"),
+							    (colnr_T)0, TRUE);
+			}
+			++idx;	    /* get same block again for next index */
+			continue;
+		    }
+
+		    /*
+		     * going one block deeper in the tree
+		     */
+		    if ((top = ml_add_stack(buf)) < 0)	/* new entry in stack */
+		    {
+			++error;
+			break;		    /* out of memory */
+		    }
+		    ip = &(buf->b_ml.ml_stack[top]);
+		    ip->ip_bnum = bnum;
+		    ip->ip_index = idx;
+
+		    bnum = pp->pb_pointer[idx].pe_bnum;
+		    line_count = pp->pb_pointer[idx].pe_line_count;
+		    page_count = pp->pb_pointer[idx].pe_page_count;
+		    continue;
+		}
+	    }
+	    else	    /* not a pointer block */
+	    {
+		dp = (DATA_BL *)(hp->bh_data);
+		if (dp->db_id != DATA_ID)	/* block id wrong */
+		{
+		    if (bnum == 1)
+		    {
+			EMSG2(_("E310: Block 1 ID wrong (%s not a .swp file?)"),
+							       mfp->mf_fname);
+			goto theend;
+		    }
+		    ++error;
+		    ml_append(lnum++, (char_u *)_("???BLOCK MISSING"),
+							    (colnr_T)0, TRUE);
+		}
+		else
+		{
+		    /*
+		     * it is a data block
+		     * Append all the lines in this block
+		     */
+		    has_error = FALSE;
+			/*
+			 * check length of block
+			 * if wrong, use length in pointer block
+			 */
+		    if (page_count * mfp->mf_page_size != dp->db_txt_end)
+		    {
+			ml_append(lnum++, (char_u *)_("??? from here until ???END lines may be messed up"),
+							    (colnr_T)0, TRUE);
+			++error;
+			has_error = TRUE;
+			dp->db_txt_end = page_count * mfp->mf_page_size;
+		    }
+
+			/* make sure there is a NUL at the end of the block */
+		    *((char_u *)dp + dp->db_txt_end - 1) = NUL;
+
+			/*
+			 * check number of lines in block
+			 * if wrong, use count in data block
+			 */
+		    if (line_count != dp->db_line_count)
+		    {
+			ml_append(lnum++, (char_u *)_("??? from here until ???END lines may have been inserted/deleted"),
+							    (colnr_T)0, TRUE);
+			++error;
+			has_error = TRUE;
+		    }
+
+		    for (i = 0; i < dp->db_line_count; ++i)
+		    {
+			txt_start = (dp->db_index[i] & DB_INDEX_MASK);
+			if (txt_start <= HEADER_SIZE
+					  || txt_start >= (int)dp->db_txt_end)
+			{
+			    p = (char_u *)"???";
+			    ++error;
+			}
+			else
+			    p = (char_u *)dp + txt_start;
+			ml_append(lnum++, p, (colnr_T)0, TRUE);
+		    }
+		    if (has_error)
+			ml_append(lnum++, (char_u *)_("???END"), (colnr_T)0, TRUE);
+		}
+	    }
+	}
+
+	if (buf->b_ml.ml_stack_top == 0)	/* finished */
+	    break;
+
+	/*
+	 * go one block up in the tree
+	 */
+	ip = &(buf->b_ml.ml_stack[--(buf->b_ml.ml_stack_top)]);
+	bnum = ip->ip_bnum;
+	idx = ip->ip_index + 1;	    /* go to next index */
+	page_count = 1;
+    }
+
+    /*
+     * The dummy line from the empty buffer will now be after the last line in
+     * the buffer. Delete it.
+     */
+    ml_delete(curbuf->b_ml.ml_line_count, FALSE);
+    curbuf->b_flags |= BF_RECOVERED;
+
+    recoverymode = FALSE;
+    if (got_int)
+	EMSG(_("E311: Recovery Interrupted"));
+    else if (error)
+    {
+	++no_wait_return;
+	MSG(">>>>>>>>>>>>>");
+	EMSG(_("E312: Errors detected while recovering; look for lines starting with ???"));
+	--no_wait_return;
+	MSG(_("See \":help E312\" for more information."));
+	MSG(">>>>>>>>>>>>>");
+    }
+    else
+    {
+	MSG(_("Recovery completed. You should check if everything is OK."));
+	MSG_PUTS(_("\n(You might want to write out this file under another name\n"));
+	MSG_PUTS(_("and run diff with the original file to check for changes)\n"));
+	MSG_PUTS(_("Delete the .swp file afterwards.\n\n"));
+	cmdline_row = msg_row;
+    }
+    redraw_curbuf_later(NOT_VALID);
+
+theend:
+    recoverymode = FALSE;
+    if (mfp != NULL)
+    {
+	if (hp != NULL)
+	    mf_put(mfp, hp, FALSE, FALSE);
+	mf_close(mfp, FALSE);	    /* will also vim_free(mfp->mf_fname) */
+    }
+    if (buf != NULL)
+    {
+	vim_free(buf->b_ml.ml_stack);
+	vim_free(buf);
+    }
+    if (serious_error && called_from_main)
+	ml_close(curbuf, TRUE);
+#ifdef FEAT_AUTOCMD
+    else
+    {
+	apply_autocmds(EVENT_BUFREADPOST, NULL, curbuf->b_fname, FALSE, curbuf);
+	apply_autocmds(EVENT_BUFWINENTER, NULL, curbuf->b_fname, FALSE, curbuf);
+    }
+#endif
+    return;
+}
+
+/*
+ * Find the names of swap files in current directory and the directory given
+ * with the 'directory' option.
+ *
+ * Used to:
+ * - list the swap files for "vim -r"
+ * - count the number of swap files when recovering
+ * - list the swap files when recovering
+ * - find the name of the n'th swap file when recovering
+ */
+    int
+recover_names(fname, list, nr)
+    char_u	**fname;    /* base for swap file name */
+    int		list;	    /* when TRUE, list the swap file names */
+    int		nr;	    /* when non-zero, return nr'th swap file name */
+{
+    int		num_names;
+    char_u	*(names[6]);
+    char_u	*tail;
+    char_u	*p;
+    int		num_files;
+    int		file_count = 0;
+    char_u	**files;
+    int		i;
+    char_u	*dirp;
+    char_u	*dir_name;
+
+    if (list)
+    {
+	    /* use msg() to start the scrolling properly */
+	msg((char_u *)_("Swap files found:"));
+	msg_putchar('\n');
+    }
+
+    /*
+     * Do the loop for every directory in 'directory'.
+     * First allocate some memory to put the directory name in.
+     */
+    dir_name = alloc((unsigned)STRLEN(p_dir) + 1);
+    dirp = p_dir;
+    while (dir_name != NULL && *dirp)
+    {
+	/*
+	 * Isolate a directory name from *dirp and put it in dir_name (we know
+	 * it is large enough, so use 31000 for length).
+	 * Advance dirp to next directory name.
+	 */
+	(void)copy_option_part(&dirp, dir_name, 31000, ",");
+
+	if (dir_name[0] == '.' && dir_name[1] == NUL)	/* check current dir */
+	{
+	    if (fname == NULL || *fname == NULL)
+	    {
+#ifdef VMS
+		names[0] = vim_strsave((char_u *)"*_sw%");
+#else
+# ifdef RISCOS
+		names[0] = vim_strsave((char_u *)"*_sw#");
+# else
+		names[0] = vim_strsave((char_u *)"*.sw?");
+# endif
+#endif
+#if defined(UNIX) || defined(WIN3264)
+		/* For Unix names starting with a dot are special.  MS-Windows
+		 * supports this too, on some file systems. */
+		names[1] = vim_strsave((char_u *)".*.sw?");
+		names[2] = vim_strsave((char_u *)".sw?");
+		num_names = 3;
+#else
+# ifdef VMS
+		names[1] = vim_strsave((char_u *)".*_sw%");
+		num_names = 2;
+# else
+		num_names = 1;
+# endif
+#endif
+	    }
+	    else
+		num_names = recov_file_names(names, *fname, TRUE);
+	}
+	else			    /* check directory dir_name */
+	{
+	    if (fname == NULL || *fname == NULL)
+	    {
+#ifdef VMS
+		names[0] = concat_fnames(dir_name, (char_u *)"*_sw%", TRUE);
+#else
+# ifdef RISCOS
+		names[0] = concat_fnames(dir_name, (char_u *)"*_sw#", TRUE);
+# else
+		names[0] = concat_fnames(dir_name, (char_u *)"*.sw?", TRUE);
+# endif
+#endif
+#if defined(UNIX) || defined(WIN3264)
+		/* For Unix names starting with a dot are special.  MS-Windows
+		 * supports this too, on some file systems. */
+		names[1] = concat_fnames(dir_name, (char_u *)".*.sw?", TRUE);
+		names[2] = concat_fnames(dir_name, (char_u *)".sw?", TRUE);
+		num_names = 3;
+#else
+# ifdef VMS
+		names[1] = concat_fnames(dir_name, (char_u *)".*_sw%", TRUE);
+		num_names = 2;
+# else
+		num_names = 1;
+# endif
+#endif
+	    }
+	    else
+	    {
+#if defined(UNIX) || defined(WIN3264)
+		p = dir_name + STRLEN(dir_name);
+		if (after_pathsep(dir_name, p) && p[-1] == p[-2])
+		{
+		    /* Ends with '//', Use Full path for swap name */
+		    tail = make_percent_swname(dir_name, *fname);
+		}
+		else
+#endif
+		{
+		    tail = gettail(*fname);
+		    tail = concat_fnames(dir_name, tail, TRUE);
+		}
+		if (tail == NULL)
+		    num_names = 0;
+		else
+		{
+		    num_names = recov_file_names(names, tail, FALSE);
+		    vim_free(tail);
+		}
+	    }
+	}
+
+	    /* check for out-of-memory */
+	for (i = 0; i < num_names; ++i)
+	{
+	    if (names[i] == NULL)
+	    {
+		for (i = 0; i < num_names; ++i)
+		    vim_free(names[i]);
+		num_names = 0;
+	    }
+	}
+	if (num_names == 0)
+	    num_files = 0;
+	else if (expand_wildcards(num_names, names, &num_files, &files,
+					EW_KEEPALL|EW_FILE|EW_SILENT) == FAIL)
+	    num_files = 0;
+
+	/*
+	 * When no swap file found, wildcard expansion might have failed (e.g.
+	 * not able to execute the shell).
+	 * Try finding a swap file by simply adding ".swp" to the file name.
+	 */
+	if (*dirp == NUL && file_count + num_files == 0
+					   && fname != NULL && *fname != NULL)
+	{
+	    struct stat	    st;
+	    char_u	    *swapname;
+
+#if defined(VMS) || defined(RISCOS)
+	    swapname = modname(*fname, (char_u *)"_swp", FALSE);
+#else
+	    swapname = modname(*fname, (char_u *)".swp", TRUE);
+#endif
+	    if (swapname != NULL)
+	    {
+		if (mch_stat((char *)swapname, &st) != -1)	    /* It exists! */
+		{
+		    files = (char_u **)alloc((unsigned)sizeof(char_u *));
+		    if (files != NULL)
+		    {
+			files[0] = swapname;
+			swapname = NULL;
+			num_files = 1;
+		    }
+		}
+		vim_free(swapname);
+	    }
+	}
+
+	/*
+	 * remove swapfile name of the current buffer, it must be ignored
+	 */
+	if (curbuf->b_ml.ml_mfp != NULL
+			       && (p = curbuf->b_ml.ml_mfp->mf_fname) != NULL)
+	{
+	    for (i = 0; i < num_files; ++i)
+		if (fullpathcmp(p, files[i], TRUE) & FPC_SAME)
+		{
+		    vim_free(files[i]);
+		    --num_files;
+		    for ( ; i < num_files; ++i)
+			files[i] = files[i + 1];
+		}
+	}
+	if (nr > 0)
+	{
+	    file_count += num_files;
+	    if (nr <= file_count)
+	    {
+		*fname = vim_strsave(files[nr - 1 + num_files - file_count]);
+		dirp = (char_u *)"";		    /* stop searching */
+	    }
+	}
+	else if (list)
+	{
+	    if (dir_name[0] == '.' && dir_name[1] == NUL)
+	    {
+		if (fname == NULL || *fname == NULL)
+		    MSG_PUTS(_("   In current directory:\n"));
+		else
+		    MSG_PUTS(_("   Using specified name:\n"));
+	    }
+	    else
+	    {
+		MSG_PUTS(_("   In directory "));
+		msg_home_replace(dir_name);
+		MSG_PUTS(":\n");
+	    }
+
+	    if (num_files)
+	    {
+		for (i = 0; i < num_files; ++i)
+		{
+		    /* print the swap file name */
+		    msg_outnum((long)++file_count);
+		    MSG_PUTS(".    ");
+		    msg_puts(gettail(files[i]));
+		    msg_putchar('\n');
+		    (void)swapfile_info(files[i]);
+		}
+	    }
+	    else
+		MSG_PUTS(_("      -- none --\n"));
+	    out_flush();
+	}
+	else
+	    file_count += num_files;
+
+	for (i = 0; i < num_names; ++i)
+	    vim_free(names[i]);
+	if (num_files > 0)
+	    FreeWild(num_files, files);
+    }
+    vim_free(dir_name);
+    return file_count;
+}
+
+#if defined(UNIX) || defined(WIN3264)  /* Need _very_ long file names */
+/*
+ * Append the full path to name with path separators made into percent
+ * signs, to dir. An unnamed buffer is handled as "" (<currentdir>/"")
+ */
+    static char_u *
+make_percent_swname(dir, name)
+    char_u	*dir;
+    char_u	*name;
+{
+    char_u *d, *s, *f;
+
+    f = fix_fname(name != NULL ? name : (char_u *) "");
+    d = NULL;
+    if (f != NULL)
+    {
+	s = alloc((unsigned)(STRLEN(f) + 1));
+	if (s != NULL)
+	{
+	    STRCPY(s, f);
+	    for (d = s; *d != NUL; mb_ptr_adv(d))
+		if (vim_ispathsep(*d))
+		    *d = '%';
+	    d = concat_fnames(dir, s, TRUE);
+	    vim_free(s);
+	}
+	vim_free(f);
+    }
+    return d;
+}
+#endif
+
+#if (defined(UNIX) || defined(__EMX__) || defined(VMS)) && (defined(FEAT_GUI_DIALOG) || defined(FEAT_CON_DIALOG))
+static int process_still_running;
+#endif
+
+/*
+ * Give information about an existing swap file.
+ * Returns timestamp (0 when unknown).
+ */
+    static time_t
+swapfile_info(fname)
+    char_u	*fname;
+{
+    struct stat	    st;
+    int		    fd;
+    struct block0   b0;
+    time_t	    x = (time_t)0;
+    char	    *p;
+#ifdef UNIX
+    char_u	    uname[B0_UNAME_SIZE];
+#endif
+
+    /* print the swap file date */
+    if (mch_stat((char *)fname, &st) != -1)
+    {
+#ifdef UNIX
+	/* print name of owner of the file */
+	if (mch_get_uname(st.st_uid, uname, B0_UNAME_SIZE) == OK)
+	{
+	    MSG_PUTS(_("          owned by: "));
+	    msg_outtrans(uname);
+	    MSG_PUTS(_("   dated: "));
+	}
+	else
+#endif
+	    MSG_PUTS(_("             dated: "));
+	x = st.st_mtime;		    /* Manx C can't do &st.st_mtime */
+	p = ctime(&x);			    /* includes '\n' */
+	if (p == NULL)
+	    MSG_PUTS("(invalid)\n");
+	else
+	    MSG_PUTS(p);
+    }
+
+    /*
+     * print the original file name
+     */
+    fd = mch_open((char *)fname, O_RDONLY | O_EXTRA, 0);
+    if (fd >= 0)
+    {
+	if (read(fd, (char *)&b0, sizeof(b0)) == sizeof(b0))
+	{
+	    if (STRNCMP(b0.b0_version, "VIM 3.0", 7) == 0)
+	    {
+		MSG_PUTS(_("         [from Vim version 3.0]"));
+	    }
+	    else if (b0.b0_id[0] != BLOCK0_ID0 || b0.b0_id[1] != BLOCK0_ID1)
+	    {
+		MSG_PUTS(_("         [does not look like a Vim swap file]"));
+	    }
+	    else
+	    {
+		MSG_PUTS(_("         file name: "));
+		if (b0.b0_fname[0] == NUL)
+		    MSG_PUTS(_("[No Name]"));
+		else
+		    msg_outtrans(b0.b0_fname);
+
+		MSG_PUTS(_("\n          modified: "));
+		MSG_PUTS(b0.b0_dirty ? _("YES") : _("no"));
+
+		if (*(b0.b0_uname) != NUL)
+		{
+		    MSG_PUTS(_("\n         user name: "));
+		    msg_outtrans(b0.b0_uname);
+		}
+
+		if (*(b0.b0_hname) != NUL)
+		{
+		    if (*(b0.b0_uname) != NUL)
+			MSG_PUTS(_("   host name: "));
+		    else
+			MSG_PUTS(_("\n         host name: "));
+		    msg_outtrans(b0.b0_hname);
+		}
+
+		if (char_to_long(b0.b0_pid) != 0L)
+		{
+		    MSG_PUTS(_("\n        process ID: "));
+		    msg_outnum(char_to_long(b0.b0_pid));
+#if defined(UNIX) || defined(__EMX__)
+		    /* EMX kill() not working correctly, it seems */
+		    if (kill((pid_t)char_to_long(b0.b0_pid), 0) == 0)
+		    {
+			MSG_PUTS(_(" (still running)"));
+# if defined(FEAT_GUI_DIALOG) || defined(FEAT_CON_DIALOG)
+			process_still_running = TRUE;
+# endif
+		    }
+#endif
+		}
+
+		if (b0_magic_wrong(&b0))
+		{
+#if defined(MSDOS) || defined(MSWIN)
+		    if (STRNCMP(b0.b0_hname, "PC ", 3) == 0)
+			MSG_PUTS(_("\n         [not usable with this version of Vim]"));
+		    else
+#endif
+			MSG_PUTS(_("\n         [not usable on this computer]"));
+		}
+	    }
+	}
+	else
+	    MSG_PUTS(_("         [cannot be read]"));
+	close(fd);
+    }
+    else
+	MSG_PUTS(_("         [cannot be opened]"));
+    msg_putchar('\n');
+
+    return x;
+}
+
+    static int
+recov_file_names(names, path, prepend_dot)
+    char_u	**names;
+    char_u	*path;
+    int		prepend_dot;
+{
+    int		num_names;
+
+#ifdef SHORT_FNAME
+    /*
+     * (MS-DOS) always short names
+     */
+    names[0] = modname(path, (char_u *)".sw?", FALSE);
+    num_names = 1;
+#else /* !SHORT_FNAME */
+    /*
+     * (Win32 and Win64) never short names, but do prepend a dot.
+     * (Not MS-DOS or Win32 or Win64) maybe short name, maybe not: Try both.
+     * Only use the short name if it is different.
+     */
+    char_u	*p;
+    int		i;
+# ifndef WIN3264
+    int	    shortname = curbuf->b_shortname;
+
+    curbuf->b_shortname = FALSE;
+# endif
+
+    num_names = 0;
+
+    /*
+     * May also add the file name with a dot prepended, for swap file in same
+     * dir as original file.
+     */
+    if (prepend_dot)
+    {
+	names[num_names] = modname(path, (char_u *)".sw?", TRUE);
+	if (names[num_names] == NULL)
+	    goto end;
+	++num_names;
+    }
+
+    /*
+     * Form the normal swap file name pattern by appending ".sw?".
+     */
+#ifdef VMS
+    names[num_names] = concat_fnames(path, (char_u *)"_sw%", FALSE);
+#else
+# ifdef RISCOS
+    names[num_names] = concat_fnames(path, (char_u *)"_sw#", FALSE);
+# else
+    names[num_names] = concat_fnames(path, (char_u *)".sw?", FALSE);
+# endif
+#endif
+    if (names[num_names] == NULL)
+	goto end;
+    if (num_names >= 1)	    /* check if we have the same name twice */
+    {
+	p = names[num_names - 1];
+	i = (int)STRLEN(names[num_names - 1]) - (int)STRLEN(names[num_names]);
+	if (i > 0)
+	    p += i;	    /* file name has been expanded to full path */
+
+	if (STRCMP(p, names[num_names]) != 0)
+	    ++num_names;
+	else
+	    vim_free(names[num_names]);
+    }
+    else
+	++num_names;
+
+# ifndef WIN3264
+    /*
+     * Also try with 'shortname' set, in case the file is on a DOS filesystem.
+     */
+    curbuf->b_shortname = TRUE;
+#ifdef VMS
+    names[num_names] = modname(path, (char_u *)"_sw%", FALSE);
+#else
+# ifdef RISCOS
+    names[num_names] = modname(path, (char_u *)"_sw#", FALSE);
+# else
+    names[num_names] = modname(path, (char_u *)".sw?", FALSE);
+# endif
+#endif
+    if (names[num_names] == NULL)
+	goto end;
+
+    /*
+     * Remove the one from 'shortname', if it's the same as with 'noshortname'.
+     */
+    p = names[num_names];
+    i = STRLEN(names[num_names]) - STRLEN(names[num_names - 1]);
+    if (i > 0)
+	p += i;		/* file name has been expanded to full path */
+    if (STRCMP(names[num_names - 1], p) == 0)
+	vim_free(names[num_names]);
+    else
+	++num_names;
+# endif
+
+end:
+# ifndef WIN3264
+    curbuf->b_shortname = shortname;
+# endif
+
+#endif /* !SHORT_FNAME */
+
+    return num_names;
+}
+
+/*
+ * sync all memlines
+ *
+ * If 'check_file' is TRUE, check if original file exists and was not changed.
+ * If 'check_char' is TRUE, stop syncing when character becomes available, but
+ * always sync at least one block.
+ */
+    void
+ml_sync_all(check_file, check_char)
+    int	    check_file;
+    int	    check_char;
+{
+    buf_T		*buf;
+    struct stat		st;
+
+    for (buf = firstbuf; buf != NULL; buf = buf->b_next)
+    {
+	if (buf->b_ml.ml_mfp == NULL || buf->b_ml.ml_mfp->mf_fname == NULL)
+	    continue;			    /* no file */
+
+	ml_flush_line(buf);		    /* flush buffered line */
+					    /* flush locked block */
+	(void)ml_find_line(buf, (linenr_T)0, ML_FLUSH);
+	if (bufIsChanged(buf) && check_file && mf_need_trans(buf->b_ml.ml_mfp)
+						     && buf->b_ffname != NULL)
+	{
+	    /*
+	     * If the original file does not exist anymore or has been changed
+	     * call ml_preserve() to get rid of all negative numbered blocks.
+	     */
+	    if (mch_stat((char *)buf->b_ffname, &st) == -1
+		    || st.st_mtime != buf->b_mtime_read
+		    || (size_t)st.st_size != buf->b_orig_size)
+	    {
+		ml_preserve(buf, FALSE);
+		did_check_timestamps = FALSE;
+		need_check_timestamps = TRUE;	/* give message later */
+	    }
+	}
+	if (buf->b_ml.ml_mfp->mf_dirty)
+	{
+	    (void)mf_sync(buf->b_ml.ml_mfp, (check_char ? MFS_STOP : 0)
+					| (bufIsChanged(buf) ? MFS_FLUSH : 0));
+	    if (check_char && ui_char_avail())	/* character available now */
+		break;
+	}
+    }
+}
+
+/*
+ * sync one buffer, including negative blocks
+ *
+ * after this all the blocks are in the swap file
+ *
+ * Used for the :preserve command and when the original file has been
+ * changed or deleted.
+ *
+ * when message is TRUE the success of preserving is reported
+ */
+    void
+ml_preserve(buf, message)
+    buf_T	*buf;
+    int		message;
+{
+    bhdr_T	*hp;
+    linenr_T	lnum;
+    memfile_T	*mfp = buf->b_ml.ml_mfp;
+    int		status;
+    int		got_int_save = got_int;
+
+    if (mfp == NULL || mfp->mf_fname == NULL)
+    {
+	if (message)
+	    EMSG(_("E313: Cannot preserve, there is no swap file"));
+	return;
+    }
+
+    /* We only want to stop when interrupted here, not when interrupted
+     * before. */
+    got_int = FALSE;
+
+    ml_flush_line(buf);				    /* flush buffered line */
+    (void)ml_find_line(buf, (linenr_T)0, ML_FLUSH); /* flush locked block */
+    status = mf_sync(mfp, MFS_ALL | MFS_FLUSH);
+
+    /* stack is invalid after mf_sync(.., MFS_ALL) */
+    buf->b_ml.ml_stack_top = 0;
+
+    /*
+     * Some of the data blocks may have been changed from negative to
+     * positive block number. In that case the pointer blocks need to be
+     * updated.
+     *
+     * We don't know in which pointer block the references are, so we visit
+     * all data blocks until there are no more translations to be done (or
+     * we hit the end of the file, which can only happen in case a write fails,
+     * e.g. when file system if full).
+     * ml_find_line() does the work by translating the negative block numbers
+     * when getting the first line of each data block.
+     */
+    if (mf_need_trans(mfp) && !got_int)
+    {
+	lnum = 1;
+	while (mf_need_trans(mfp) && lnum <= buf->b_ml.ml_line_count)
+	{
+	    hp = ml_find_line(buf, lnum, ML_FIND);
+	    if (hp == NULL)
+	    {
+		status = FAIL;
+		goto theend;
+	    }
+	    CHECK(buf->b_ml.ml_locked_low != lnum, "low != lnum");
+	    lnum = buf->b_ml.ml_locked_high + 1;
+	}
+	(void)ml_find_line(buf, (linenr_T)0, ML_FLUSH);	/* flush locked block */
+	/* sync the updated pointer blocks */
+	if (mf_sync(mfp, MFS_ALL | MFS_FLUSH) == FAIL)
+	    status = FAIL;
+	buf->b_ml.ml_stack_top = 0;	    /* stack is invalid now */
+    }
+theend:
+    got_int |= got_int_save;
+
+    if (message)
+    {
+	if (status == OK)
+	    MSG(_("File preserved"));
+	else
+	    EMSG(_("E314: Preserve failed"));
+    }
+}
+
+/*
+ * NOTE: The pointer returned by the ml_get_*() functions only remains valid
+ * until the next call!
+ *  line1 = ml_get(1);
+ *  line2 = ml_get(2);	// line1 is now invalid!
+ * Make a copy of the line if necessary.
+ */
+/*
+ * get a pointer to a (read-only copy of a) line
+ *
+ * On failure an error message is given and IObuff is returned (to avoid
+ * having to check for error everywhere).
+ */
+    char_u  *
+ml_get(lnum)
+    linenr_T	lnum;
+{
+    return ml_get_buf(curbuf, lnum, FALSE);
+}
+
+/*
+ * ml_get_pos: get pointer to position 'pos'
+ */
+    char_u *
+ml_get_pos(pos)
+    pos_T	*pos;
+{
+    return (ml_get_buf(curbuf, pos->lnum, FALSE) + pos->col);
+}
+
+/*
+ * ml_get_curline: get pointer to cursor line.
+ */
+    char_u *
+ml_get_curline()
+{
+    return ml_get_buf(curbuf, curwin->w_cursor.lnum, FALSE);
+}
+
+/*
+ * ml_get_cursor: get pointer to cursor position
+ */
+    char_u *
+ml_get_cursor()
+{
+    return (ml_get_buf(curbuf, curwin->w_cursor.lnum, FALSE) +
+							curwin->w_cursor.col);
+}
+
+/*
+ * get a pointer to a line in a specific buffer
+ *
+ * "will_change": if TRUE mark the buffer dirty (chars in the line will be
+ * changed)
+ */
+    char_u  *
+ml_get_buf(buf, lnum, will_change)
+    buf_T	*buf;
+    linenr_T	lnum;
+    int		will_change;		/* line will be changed */
+{
+    bhdr_T	*hp;
+    DATA_BL	*dp;
+    char_u	*ptr;
+    static int	recursive = 0;
+
+    if (lnum > buf->b_ml.ml_line_count)	/* invalid line number */
+    {
+	if (recursive == 0)
+	{
+	    /* Avoid giving this message for a recursive call, may happen when
+	     * the GUI redraws part of the text. */
+	    ++recursive;
+	    EMSGN(_("E315: ml_get: invalid lnum: %ld"), lnum);
+	    --recursive;
+	}
+errorret:
+	STRCPY(IObuff, "???");
+	return IObuff;
+    }
+    if (lnum <= 0)			/* pretend line 0 is line 1 */
+	lnum = 1;
+
+    if (buf->b_ml.ml_mfp == NULL)	/* there are no lines */
+	return (char_u *)"";
+
+/*
+ * See if it is the same line as requested last time.
+ * Otherwise may need to flush last used line.
+ * Don't use the last used line when 'swapfile' is reset, need to load all
+ * blocks.
+ */
+    if (buf->b_ml.ml_line_lnum != lnum || mf_dont_release)
+    {
+	ml_flush_line(buf);
+
+	/*
+	 * Find the data block containing the line.
+	 * This also fills the stack with the blocks from the root to the data
+	 * block and releases any locked block.
+	 */
+	if ((hp = ml_find_line(buf, lnum, ML_FIND)) == NULL)
+	{
+	    if (recursive == 0)
+	    {
+		/* Avoid giving this message for a recursive call, may happen
+		 * when the GUI redraws part of the text. */
+		++recursive;
+		EMSGN(_("E316: ml_get: cannot find line %ld"), lnum);
+		--recursive;
+	    }
+	    goto errorret;
+	}
+
+	dp = (DATA_BL *)(hp->bh_data);
+
+	ptr = (char_u *)dp + ((dp->db_index[lnum - buf->b_ml.ml_locked_low]) & DB_INDEX_MASK);
+	buf->b_ml.ml_line_ptr = ptr;
+	buf->b_ml.ml_line_lnum = lnum;
+	buf->b_ml.ml_flags &= ~ML_LINE_DIRTY;
+    }
+    if (will_change)
+	buf->b_ml.ml_flags |= (ML_LOCKED_DIRTY | ML_LOCKED_POS);
+
+    return buf->b_ml.ml_line_ptr;
+}
+
+/*
+ * Check if a line that was just obtained by a call to ml_get
+ * is in allocated memory.
+ */
+    int
+ml_line_alloced()
+{
+    return (curbuf->b_ml.ml_flags & ML_LINE_DIRTY);
+}
+
+/*
+ * Append a line after lnum (may be 0 to insert a line in front of the file).
+ * "line" does not need to be allocated, but can't be another line in a
+ * buffer, unlocking may make it invalid.
+ *
+ *   newfile: TRUE when starting to edit a new file, meaning that pe_old_lnum
+ *		will be set for recovery
+ * Check: The caller of this function should probably also call
+ * appended_lines().
+ *
+ * return FAIL for failure, OK otherwise
+ */
+    int
+ml_append(lnum, line, len, newfile)
+    linenr_T	lnum;		/* append after this line (can be 0) */
+    char_u	*line;		/* text of the new line */
+    colnr_T	len;		/* length of new line, including NUL, or 0 */
+    int		newfile;	/* flag, see above */
+{
+    /* When starting up, we might still need to create the memfile */
+    if (curbuf->b_ml.ml_mfp == NULL && open_buffer(FALSE, NULL) == FAIL)
+	return FAIL;
+
+    if (curbuf->b_ml.ml_line_lnum != 0)
+	ml_flush_line(curbuf);
+    return ml_append_int(curbuf, lnum, line, len, newfile, FALSE);
+}
+
+#if defined(FEAT_SPELL) || defined(PROTO)
+/*
+ * Like ml_append() but for an arbitrary buffer.  The buffer must already have
+ * a memline.
+ */
+    int
+ml_append_buf(buf, lnum, line, len, newfile)
+    buf_T	*buf;
+    linenr_T	lnum;		/* append after this line (can be 0) */
+    char_u	*line;		/* text of the new line */
+    colnr_T	len;		/* length of new line, including NUL, or 0 */
+    int		newfile;	/* flag, see above */
+{
+    if (buf->b_ml.ml_mfp == NULL)
+	return FAIL;
+
+    if (buf->b_ml.ml_line_lnum != 0)
+	ml_flush_line(buf);
+    return ml_append_int(buf, lnum, line, len, newfile, FALSE);
+}
+#endif
+
+    static int
+ml_append_int(buf, lnum, line, len, newfile, mark)
+    buf_T	*buf;
+    linenr_T	lnum;		/* append after this line (can be 0) */
+    char_u	*line;		/* text of the new line */
+    colnr_T	len;		/* length of line, including NUL, or 0 */
+    int		newfile;	/* flag, see above */
+    int		mark;		/* mark the new line */
+{
+    int		i;
+    int		line_count;	/* number of indexes in current block */
+    int		offset;
+    int		from, to;
+    int		space_needed;	/* space needed for new line */
+    int		page_size;
+    int		page_count;
+    int		db_idx;		/* index for lnum in data block */
+    bhdr_T	*hp;
+    memfile_T	*mfp;
+    DATA_BL	*dp;
+    PTR_BL	*pp;
+    infoptr_T	*ip;
+
+					/* lnum out of range */
+    if (lnum > buf->b_ml.ml_line_count || buf->b_ml.ml_mfp == NULL)
+	return FAIL;
+
+    if (lowest_marked && lowest_marked > lnum)
+	lowest_marked = lnum + 1;
+
+    if (len == 0)
+	len = (colnr_T)STRLEN(line) + 1;	/* space needed for the text */
+    space_needed = len + INDEX_SIZE;	/* space needed for text + index */
+
+    mfp = buf->b_ml.ml_mfp;
+    page_size = mfp->mf_page_size;
+
+/*
+ * find the data block containing the previous line
+ * This also fills the stack with the blocks from the root to the data block
+ * This also releases any locked block.
+ */
+    if ((hp = ml_find_line(buf, lnum == 0 ? (linenr_T)1 : lnum,
+							  ML_INSERT)) == NULL)
+	return FAIL;
+
+    buf->b_ml.ml_flags &= ~ML_EMPTY;
+
+    if (lnum == 0)		/* got line one instead, correct db_idx */
+	db_idx = -1;		/* careful, it is negative! */
+    else
+	db_idx = lnum - buf->b_ml.ml_locked_low;
+		/* get line count before the insertion */
+    line_count = buf->b_ml.ml_locked_high - buf->b_ml.ml_locked_low;
+
+    dp = (DATA_BL *)(hp->bh_data);
+
+/*
+ * If
+ * - there is not enough room in the current block
+ * - appending to the last line in the block
+ * - not appending to the last line in the file
+ * insert in front of the next block.
+ */
+    if ((int)dp->db_free < space_needed && db_idx == line_count - 1
+					    && lnum < buf->b_ml.ml_line_count)
+    {
+	/*
+	 * Now that the line is not going to be inserted in the block that we
+	 * expected, the line count has to be adjusted in the pointer blocks
+	 * by using ml_locked_lineadd.
+	 */
+	--(buf->b_ml.ml_locked_lineadd);
+	--(buf->b_ml.ml_locked_high);
+	if ((hp = ml_find_line(buf, lnum + 1, ML_INSERT)) == NULL)
+	    return FAIL;
+
+	db_idx = -1;		    /* careful, it is negative! */
+		    /* get line count before the insertion */
+	line_count = buf->b_ml.ml_locked_high - buf->b_ml.ml_locked_low;
+	CHECK(buf->b_ml.ml_locked_low != lnum + 1, "locked_low != lnum + 1");
+
+	dp = (DATA_BL *)(hp->bh_data);
+    }
+
+    ++buf->b_ml.ml_line_count;
+
+    if ((int)dp->db_free >= space_needed)	/* enough room in data block */
+    {
+/*
+ * Insert new line in existing data block, or in data block allocated above.
+ */
+	dp->db_txt_start -= len;
+	dp->db_free -= space_needed;
+	++(dp->db_line_count);
+
+	/*
+	 * move the text of the lines that follow to the front
+	 * adjust the indexes of the lines that follow
+	 */
+	if (line_count > db_idx + 1)	    /* if there are following lines */
+	{
+	    /*
+	     * Offset is the start of the previous line.
+	     * This will become the character just after the new line.
+	     */
+	    if (db_idx < 0)
+		offset = dp->db_txt_end;
+	    else
+		offset = ((dp->db_index[db_idx]) & DB_INDEX_MASK);
+	    mch_memmove((char *)dp + dp->db_txt_start,
+					  (char *)dp + dp->db_txt_start + len,
+				 (size_t)(offset - (dp->db_txt_start + len)));
+	    for (i = line_count - 1; i > db_idx; --i)
+		dp->db_index[i + 1] = dp->db_index[i] - len;
+	    dp->db_index[db_idx + 1] = offset - len;
+	}
+	else				    /* add line at the end */
+	    dp->db_index[db_idx + 1] = dp->db_txt_start;
+
+	/*
+	 * copy the text into the block
+	 */
+	mch_memmove((char *)dp + dp->db_index[db_idx + 1], line, (size_t)len);
+	if (mark)
+	    dp->db_index[db_idx + 1] |= DB_MARKED;
+
+	/*
+	 * Mark the block dirty.
+	 */
+	buf->b_ml.ml_flags |= ML_LOCKED_DIRTY;
+	if (!newfile)
+	    buf->b_ml.ml_flags |= ML_LOCKED_POS;
+    }
+    else	    /* not enough space in data block */
+    {
+/*
+ * If there is not enough room we have to create a new data block and copy some
+ * lines into it.
+ * Then we have to insert an entry in the pointer block.
+ * If this pointer block also is full, we go up another block, and so on, up
+ * to the root if necessary.
+ * The line counts in the pointer blocks have already been adjusted by
+ * ml_find_line().
+ */
+	long	    line_count_left, line_count_right;
+	int	    page_count_left, page_count_right;
+	bhdr_T	    *hp_left;
+	bhdr_T	    *hp_right;
+	bhdr_T	    *hp_new;
+	int	    lines_moved;
+	int	    data_moved = 0;	    /* init to shut up gcc */
+	int	    total_moved = 0;	    /* init to shut up gcc */
+	DATA_BL	    *dp_right, *dp_left;
+	int	    stack_idx;
+	int	    in_left;
+	int	    lineadd;
+	blocknr_T   bnum_left, bnum_right;
+	linenr_T    lnum_left, lnum_right;
+	int	    pb_idx;
+	PTR_BL	    *pp_new;
+
+	/*
+	 * We are going to allocate a new data block. Depending on the
+	 * situation it will be put to the left or right of the existing
+	 * block.  If possible we put the new line in the left block and move
+	 * the lines after it to the right block. Otherwise the new line is
+	 * also put in the right block. This method is more efficient when
+	 * inserting a lot of lines at one place.
+	 */
+	if (db_idx < 0)		/* left block is new, right block is existing */
+	{
+	    lines_moved = 0;
+	    in_left = TRUE;
+	    /* space_needed does not change */
+	}
+	else			/* left block is existing, right block is new */
+	{
+	    lines_moved = line_count - db_idx - 1;
+	    if (lines_moved == 0)
+		in_left = FALSE;	/* put new line in right block */
+					/* space_needed does not change */
+	    else
+	    {
+		data_moved = ((dp->db_index[db_idx]) & DB_INDEX_MASK) -
+							    dp->db_txt_start;
+		total_moved = data_moved + lines_moved * INDEX_SIZE;
+		if ((int)dp->db_free + total_moved >= space_needed)
+		{
+		    in_left = TRUE;	/* put new line in left block */
+		    space_needed = total_moved;
+		}
+		else
+		{
+		    in_left = FALSE;	    /* put new line in right block */
+		    space_needed += total_moved;
+		}
+	    }
+	}
+
+	page_count = ((space_needed + HEADER_SIZE) + page_size - 1) / page_size;
+	if ((hp_new = ml_new_data(mfp, newfile, page_count)) == NULL)
+	{
+			/* correct line counts in pointer blocks */
+	    --(buf->b_ml.ml_locked_lineadd);
+	    --(buf->b_ml.ml_locked_high);
+	    return FAIL;
+	}
+	if (db_idx < 0)		/* left block is new */
+	{
+	    hp_left = hp_new;
+	    hp_right = hp;
+	    line_count_left = 0;
+	    line_count_right = line_count;
+	}
+	else			/* right block is new */
+	{
+	    hp_left = hp;
+	    hp_right = hp_new;
+	    line_count_left = line_count;
+	    line_count_right = 0;
+	}
+	dp_right = (DATA_BL *)(hp_right->bh_data);
+	dp_left = (DATA_BL *)(hp_left->bh_data);
+	bnum_left = hp_left->bh_bnum;
+	bnum_right = hp_right->bh_bnum;
+	page_count_left = hp_left->bh_page_count;
+	page_count_right = hp_right->bh_page_count;
+
+	/*
+	 * May move the new line into the right/new block.
+	 */
+	if (!in_left)
+	{
+	    dp_right->db_txt_start -= len;
+	    dp_right->db_free -= len + INDEX_SIZE;
+	    dp_right->db_index[0] = dp_right->db_txt_start;
+	    if (mark)
+		dp_right->db_index[0] |= DB_MARKED;
+
+	    mch_memmove((char *)dp_right + dp_right->db_txt_start,
+							   line, (size_t)len);
+	    ++line_count_right;
+	}
+	/*
+	 * may move lines from the left/old block to the right/new one.
+	 */
+	if (lines_moved)
+	{
+	    /*
+	     */
+	    dp_right->db_txt_start -= data_moved;
+	    dp_right->db_free -= total_moved;
+	    mch_memmove((char *)dp_right + dp_right->db_txt_start,
+			(char *)dp_left + dp_left->db_txt_start,
+			(size_t)data_moved);
+	    offset = dp_right->db_txt_start - dp_left->db_txt_start;
+	    dp_left->db_txt_start += data_moved;
+	    dp_left->db_free += total_moved;
+
+	    /*
+	     * update indexes in the new block
+	     */
+	    for (to = line_count_right, from = db_idx + 1;
+					 from < line_count_left; ++from, ++to)
+		dp_right->db_index[to] = dp->db_index[from] + offset;
+	    line_count_right += lines_moved;
+	    line_count_left -= lines_moved;
+	}
+
+	/*
+	 * May move the new line into the left (old or new) block.
+	 */
+	if (in_left)
+	{
+	    dp_left->db_txt_start -= len;
+	    dp_left->db_free -= len + INDEX_SIZE;
+	    dp_left->db_index[line_count_left] = dp_left->db_txt_start;
+	    if (mark)
+		dp_left->db_index[line_count_left] |= DB_MARKED;
+	    mch_memmove((char *)dp_left + dp_left->db_txt_start,
+							   line, (size_t)len);
+	    ++line_count_left;
+	}
+
+	if (db_idx < 0)		/* left block is new */
+	{
+	    lnum_left = lnum + 1;
+	    lnum_right = 0;
+	}
+	else			/* right block is new */
+	{
+	    lnum_left = 0;
+	    if (in_left)
+		lnum_right = lnum + 2;
+	    else
+		lnum_right = lnum + 1;
+	}
+	dp_left->db_line_count = line_count_left;
+	dp_right->db_line_count = line_count_right;
+
+	/*
+	 * release the two data blocks
+	 * The new one (hp_new) already has a correct blocknumber.
+	 * The old one (hp, in ml_locked) gets a positive blocknumber if
+	 * we changed it and we are not editing a new file.
+	 */
+	if (lines_moved || in_left)
+	    buf->b_ml.ml_flags |= ML_LOCKED_DIRTY;
+	if (!newfile && db_idx >= 0 && in_left)
+	    buf->b_ml.ml_flags |= ML_LOCKED_POS;
+	mf_put(mfp, hp_new, TRUE, FALSE);
+
+	/*
+	 * flush the old data block
+	 * set ml_locked_lineadd to 0, because the updating of the
+	 * pointer blocks is done below
+	 */
+	lineadd = buf->b_ml.ml_locked_lineadd;
+	buf->b_ml.ml_locked_lineadd = 0;
+	ml_find_line(buf, (linenr_T)0, ML_FLUSH);   /* flush data block */
+
+	/*
+	 * update pointer blocks for the new data block
+	 */
+	for (stack_idx = buf->b_ml.ml_stack_top - 1; stack_idx >= 0;
+								  --stack_idx)
+	{
+	    ip = &(buf->b_ml.ml_stack[stack_idx]);
+	    pb_idx = ip->ip_index;
+	    if ((hp = mf_get(mfp, ip->ip_bnum, 1)) == NULL)
+		return FAIL;
+	    pp = (PTR_BL *)(hp->bh_data);   /* must be pointer block */
+	    if (pp->pb_id != PTR_ID)
+	    {
+		EMSG(_("E317: pointer block id wrong 3"));
+		mf_put(mfp, hp, FALSE, FALSE);
+		return FAIL;
+	    }
+	    /*
+	     * TODO: If the pointer block is full and we are adding at the end
+	     * try to insert in front of the next block
+	     */
+	    /* block not full, add one entry */
+	    if (pp->pb_count < pp->pb_count_max)
+	    {
+		if (pb_idx + 1 < (int)pp->pb_count)
+		    mch_memmove(&pp->pb_pointer[pb_idx + 2],
+				&pp->pb_pointer[pb_idx + 1],
+			(size_t)(pp->pb_count - pb_idx - 1) * sizeof(PTR_EN));
+		++pp->pb_count;
+		pp->pb_pointer[pb_idx].pe_line_count = line_count_left;
+		pp->pb_pointer[pb_idx].pe_bnum = bnum_left;
+		pp->pb_pointer[pb_idx].pe_page_count = page_count_left;
+		pp->pb_pointer[pb_idx + 1].pe_line_count = line_count_right;
+		pp->pb_pointer[pb_idx + 1].pe_bnum = bnum_right;
+		pp->pb_pointer[pb_idx + 1].pe_page_count = page_count_right;
+
+		if (lnum_left != 0)
+		    pp->pb_pointer[pb_idx].pe_old_lnum = lnum_left;
+		if (lnum_right != 0)
+		    pp->pb_pointer[pb_idx + 1].pe_old_lnum = lnum_right;
+
+		mf_put(mfp, hp, TRUE, FALSE);
+		buf->b_ml.ml_stack_top = stack_idx + 1;	    /* truncate stack */
+
+		if (lineadd)
+		{
+		    --(buf->b_ml.ml_stack_top);
+		    /* fix line count for rest of blocks in the stack */
+		    ml_lineadd(buf, lineadd);
+							/* fix stack itself */
+		    buf->b_ml.ml_stack[buf->b_ml.ml_stack_top].ip_high +=
+								      lineadd;
+		    ++(buf->b_ml.ml_stack_top);
+		}
+
+		/*
+		 * We are finished, break the loop here.
+		 */
+		break;
+	    }
+	    else			/* pointer block full */
+	    {
+		/*
+		 * split the pointer block
+		 * allocate a new pointer block
+		 * move some of the pointer into the new block
+		 * prepare for updating the parent block
+		 */
+		for (;;)	/* do this twice when splitting block 1 */
+		{
+		    hp_new = ml_new_ptr(mfp);
+		    if (hp_new == NULL)	    /* TODO: try to fix tree */
+			return FAIL;
+		    pp_new = (PTR_BL *)(hp_new->bh_data);
+
+		    if (hp->bh_bnum != 1)
+			break;
+
+		    /*
+		     * if block 1 becomes full the tree is given an extra level
+		     * The pointers from block 1 are moved into the new block.
+		     * block 1 is updated to point to the new block
+		     * then continue to split the new block
+		     */
+		    mch_memmove(pp_new, pp, (size_t)page_size);
+		    pp->pb_count = 1;
+		    pp->pb_pointer[0].pe_bnum = hp_new->bh_bnum;
+		    pp->pb_pointer[0].pe_line_count = buf->b_ml.ml_line_count;
+		    pp->pb_pointer[0].pe_old_lnum = 1;
+		    pp->pb_pointer[0].pe_page_count = 1;
+		    mf_put(mfp, hp, TRUE, FALSE);   /* release block 1 */
+		    hp = hp_new;		/* new block is to be split */
+		    pp = pp_new;
+		    CHECK(stack_idx != 0, _("stack_idx should be 0"));
+		    ip->ip_index = 0;
+		    ++stack_idx;	/* do block 1 again later */
+		}
+		/*
+		 * move the pointers after the current one to the new block
+		 * If there are none, the new entry will be in the new block.
+		 */
+		total_moved = pp->pb_count - pb_idx - 1;
+		if (total_moved)
+		{
+		    mch_memmove(&pp_new->pb_pointer[0],
+				&pp->pb_pointer[pb_idx + 1],
+				(size_t)(total_moved) * sizeof(PTR_EN));
+		    pp_new->pb_count = total_moved;
+		    pp->pb_count -= total_moved - 1;
+		    pp->pb_pointer[pb_idx + 1].pe_bnum = bnum_right;
+		    pp->pb_pointer[pb_idx + 1].pe_line_count = line_count_right;
+		    pp->pb_pointer[pb_idx + 1].pe_page_count = page_count_right;
+		    if (lnum_right)
+			pp->pb_pointer[pb_idx + 1].pe_old_lnum = lnum_right;
+		}
+		else
+		{
+		    pp_new->pb_count = 1;
+		    pp_new->pb_pointer[0].pe_bnum = bnum_right;
+		    pp_new->pb_pointer[0].pe_line_count = line_count_right;
+		    pp_new->pb_pointer[0].pe_page_count = page_count_right;
+		    pp_new->pb_pointer[0].pe_old_lnum = lnum_right;
+		}
+		pp->pb_pointer[pb_idx].pe_bnum = bnum_left;
+		pp->pb_pointer[pb_idx].pe_line_count = line_count_left;
+		pp->pb_pointer[pb_idx].pe_page_count = page_count_left;
+		if (lnum_left)
+		    pp->pb_pointer[pb_idx].pe_old_lnum = lnum_left;
+		lnum_left = 0;
+		lnum_right = 0;
+
+		/*
+		 * recompute line counts
+		 */
+		line_count_right = 0;
+		for (i = 0; i < (int)pp_new->pb_count; ++i)
+		    line_count_right += pp_new->pb_pointer[i].pe_line_count;
+		line_count_left = 0;
+		for (i = 0; i < (int)pp->pb_count; ++i)
+		    line_count_left += pp->pb_pointer[i].pe_line_count;
+
+		bnum_left = hp->bh_bnum;
+		bnum_right = hp_new->bh_bnum;
+		page_count_left = 1;
+		page_count_right = 1;
+		mf_put(mfp, hp, TRUE, FALSE);
+		mf_put(mfp, hp_new, TRUE, FALSE);
+	    }
+	}
+
+	/*
+	 * Safety check: fallen out of for loop?
+	 */
+	if (stack_idx < 0)
+	{
+	    EMSG(_("E318: Updated too many blocks?"));
+	    buf->b_ml.ml_stack_top = 0;	/* invalidate stack */
+	}
+    }
+
+#ifdef FEAT_BYTEOFF
+    /* The line was inserted below 'lnum' */
+    ml_updatechunk(buf, lnum + 1, (long)len, ML_CHNK_ADDLINE);
+#endif
+#ifdef FEAT_NETBEANS_INTG
+    if (usingNetbeans)
+    {
+	if (STRLEN(line) > 0)
+	    netbeans_inserted(buf, lnum+1, (colnr_T)0, line, (int)STRLEN(line));
+	netbeans_inserted(buf, lnum+1, (colnr_T)STRLEN(line),
+							   (char_u *)"\n", 1);
+    }
+#endif
+    return OK;
+}
+
+/*
+ * Replace line lnum, with buffering, in current buffer.
+ *
+ * If "copy" is TRUE, make a copy of the line, otherwise the line has been
+ * copied to allocated memory already.
+ *
+ * Check: The caller of this function should probably also call
+ * changed_lines(), unless update_screen(NOT_VALID) is used.
+ *
+ * return FAIL for failure, OK otherwise
+ */
+    int
+ml_replace(lnum, line, copy)
+    linenr_T	lnum;
+    char_u	*line;
+    int		copy;
+{
+    if (line == NULL)		/* just checking... */
+	return FAIL;
+
+    /* When starting up, we might still need to create the memfile */
+    if (curbuf->b_ml.ml_mfp == NULL && open_buffer(FALSE, NULL) == FAIL)
+	return FAIL;
+
+    if (copy && (line = vim_strsave(line)) == NULL) /* allocate memory */
+	return FAIL;
+#ifdef FEAT_NETBEANS_INTG
+    if (usingNetbeans)
+    {
+	netbeans_removed(curbuf, lnum, 0, (long)STRLEN(ml_get(lnum)));
+	netbeans_inserted(curbuf, lnum, 0, line, (int)STRLEN(line));
+    }
+#endif
+    if (curbuf->b_ml.ml_line_lnum != lnum)	    /* other line buffered */
+	ml_flush_line(curbuf);			    /* flush it */
+    else if (curbuf->b_ml.ml_flags & ML_LINE_DIRTY) /* same line allocated */
+	vim_free(curbuf->b_ml.ml_line_ptr);	    /* free it */
+    curbuf->b_ml.ml_line_ptr = line;
+    curbuf->b_ml.ml_line_lnum = lnum;
+    curbuf->b_ml.ml_flags = (curbuf->b_ml.ml_flags | ML_LINE_DIRTY) & ~ML_EMPTY;
+
+    return OK;
+}
+
+/*
+ * Delete line 'lnum' in the current buffer.
+ *
+ * Check: The caller of this function should probably also call
+ * deleted_lines() after this.
+ *
+ * return FAIL for failure, OK otherwise
+ */
+    int
+ml_delete(lnum, message)
+    linenr_T	lnum;
+    int		message;
+{
+    ml_flush_line(curbuf);
+    return ml_delete_int(curbuf, lnum, message);
+}
+
+    static int
+ml_delete_int(buf, lnum, message)
+    buf_T	*buf;
+    linenr_T	lnum;
+    int		message;
+{
+    bhdr_T	*hp;
+    memfile_T	*mfp;
+    DATA_BL	*dp;
+    PTR_BL	*pp;
+    infoptr_T	*ip;
+    int		count;	    /* number of entries in block */
+    int		idx;
+    int		stack_idx;
+    int		text_start;
+    int		line_start;
+    long	line_size;
+    int		i;
+
+    if (lnum < 1 || lnum > buf->b_ml.ml_line_count)
+	return FAIL;
+
+    if (lowest_marked && lowest_marked > lnum)
+	lowest_marked--;
+
+/*
+ * If the file becomes empty the last line is replaced by an empty line.
+ */
+    if (buf->b_ml.ml_line_count == 1)	    /* file becomes empty */
+    {
+	if (message
+#ifdef FEAT_NETBEANS_INTG
+		&& !netbeansSuppressNoLines
+#endif
+	   )
+	    set_keep_msg((char_u *)_(no_lines_msg), 0);
+
+	/* FEAT_BYTEOFF already handled in there, dont worry 'bout it below */
+	i = ml_replace((linenr_T)1, (char_u *)"", TRUE);
+	buf->b_ml.ml_flags |= ML_EMPTY;
+
+	return i;
+    }
+
+/*
+ * find the data block containing the line
+ * This also fills the stack with the blocks from the root to the data block
+ * This also releases any locked block.
+ */
+    mfp = buf->b_ml.ml_mfp;
+    if (mfp == NULL)
+	return FAIL;
+
+    if ((hp = ml_find_line(buf, lnum, ML_DELETE)) == NULL)
+	return FAIL;
+
+    dp = (DATA_BL *)(hp->bh_data);
+    /* compute line count before the delete */
+    count = (long)(buf->b_ml.ml_locked_high)
+					- (long)(buf->b_ml.ml_locked_low) + 2;
+    idx = lnum - buf->b_ml.ml_locked_low;
+
+    --buf->b_ml.ml_line_count;
+
+    line_start = ((dp->db_index[idx]) & DB_INDEX_MASK);
+    if (idx == 0)		/* first line in block, text at the end */
+	line_size = dp->db_txt_end - line_start;
+    else
+	line_size = ((dp->db_index[idx - 1]) & DB_INDEX_MASK) - line_start;
+
+#ifdef FEAT_NETBEANS_INTG
+    if (usingNetbeans)
+	netbeans_removed(buf, lnum, 0, (long)line_size);
+#endif
+
+/*
+ * special case: If there is only one line in the data block it becomes empty.
+ * Then we have to remove the entry, pointing to this data block, from the
+ * pointer block. If this pointer block also becomes empty, we go up another
+ * block, and so on, up to the root if necessary.
+ * The line counts in the pointer blocks have already been adjusted by
+ * ml_find_line().
+ */
+    if (count == 1)
+    {
+	mf_free(mfp, hp);	/* free the data block */
+	buf->b_ml.ml_locked = NULL;
+
+	for (stack_idx = buf->b_ml.ml_stack_top - 1; stack_idx >= 0; --stack_idx)
+	{
+	    buf->b_ml.ml_stack_top = 0;	    /* stack is invalid when failing */
+	    ip = &(buf->b_ml.ml_stack[stack_idx]);
+	    idx = ip->ip_index;
+	    if ((hp = mf_get(mfp, ip->ip_bnum, 1)) == NULL)
+		return FAIL;
+	    pp = (PTR_BL *)(hp->bh_data);   /* must be pointer block */
+	    if (pp->pb_id != PTR_ID)
+	    {
+		EMSG(_("E317: pointer block id wrong 4"));
+		mf_put(mfp, hp, FALSE, FALSE);
+		return FAIL;
+	    }
+	    count = --(pp->pb_count);
+	    if (count == 0)	    /* the pointer block becomes empty! */
+		mf_free(mfp, hp);
+	    else
+	    {
+		if (count != idx)	/* move entries after the deleted one */
+		    mch_memmove(&pp->pb_pointer[idx], &pp->pb_pointer[idx + 1],
+				      (size_t)(count - idx) * sizeof(PTR_EN));
+		mf_put(mfp, hp, TRUE, FALSE);
+
+		buf->b_ml.ml_stack_top = stack_idx;	/* truncate stack */
+		/* fix line count for rest of blocks in the stack */
+		if (buf->b_ml.ml_locked_lineadd != 0)
+		{
+		    ml_lineadd(buf, buf->b_ml.ml_locked_lineadd);
+		    buf->b_ml.ml_stack[buf->b_ml.ml_stack_top].ip_high +=
+						  buf->b_ml.ml_locked_lineadd;
+		}
+		++(buf->b_ml.ml_stack_top);
+
+		break;
+	    }
+	}
+	CHECK(stack_idx < 0, _("deleted block 1?"));
+    }
+    else
+    {
+	/*
+	 * delete the text by moving the next lines forwards
+	 */
+	text_start = dp->db_txt_start;
+	mch_memmove((char *)dp + text_start + line_size,
+		  (char *)dp + text_start, (size_t)(line_start - text_start));
+
+	/*
+	 * delete the index by moving the next indexes backwards
+	 * Adjust the indexes for the text movement.
+	 */
+	for (i = idx; i < count - 1; ++i)
+	    dp->db_index[i] = dp->db_index[i + 1] + line_size;
+
+	dp->db_free += line_size + INDEX_SIZE;
+	dp->db_txt_start += line_size;
+	--(dp->db_line_count);
+
+	/*
+	 * mark the block dirty and make sure it is in the file (for recovery)
+	 */
+	buf->b_ml.ml_flags |= (ML_LOCKED_DIRTY | ML_LOCKED_POS);
+    }
+
+#ifdef FEAT_BYTEOFF
+    ml_updatechunk(buf, lnum, line_size, ML_CHNK_DELLINE);
+#endif
+    return OK;
+}
+
+/*
+ * set the B_MARKED flag for line 'lnum'
+ */
+    void
+ml_setmarked(lnum)
+    linenr_T lnum;
+{
+    bhdr_T    *hp;
+    DATA_BL *dp;
+				    /* invalid line number */
+    if (lnum < 1 || lnum > curbuf->b_ml.ml_line_count
+					       || curbuf->b_ml.ml_mfp == NULL)
+	return;			    /* give error message? */
+
+    if (lowest_marked == 0 || lowest_marked > lnum)
+	lowest_marked = lnum;
+
+    /*
+     * find the data block containing the line
+     * This also fills the stack with the blocks from the root to the data block
+     * This also releases any locked block.
+     */
+    if ((hp = ml_find_line(curbuf, lnum, ML_FIND)) == NULL)
+	return;		    /* give error message? */
+
+    dp = (DATA_BL *)(hp->bh_data);
+    dp->db_index[lnum - curbuf->b_ml.ml_locked_low] |= DB_MARKED;
+    curbuf->b_ml.ml_flags |= ML_LOCKED_DIRTY;
+}
+
+/*
+ * find the first line with its B_MARKED flag set
+ */
+    linenr_T
+ml_firstmarked()
+{
+    bhdr_T	*hp;
+    DATA_BL	*dp;
+    linenr_T	lnum;
+    int		i;
+
+    if (curbuf->b_ml.ml_mfp == NULL)
+	return (linenr_T) 0;
+
+    /*
+     * The search starts with lowest_marked line. This is the last line where
+     * a mark was found, adjusted by inserting/deleting lines.
+     */
+    for (lnum = lowest_marked; lnum <= curbuf->b_ml.ml_line_count; )
+    {
+	/*
+	 * Find the data block containing the line.
+	 * This also fills the stack with the blocks from the root to the data
+	 * block This also releases any locked block.
+	 */
+	if ((hp = ml_find_line(curbuf, lnum, ML_FIND)) == NULL)
+	    return (linenr_T)0;		    /* give error message? */
+
+	dp = (DATA_BL *)(hp->bh_data);
+
+	for (i = lnum - curbuf->b_ml.ml_locked_low;
+			    lnum <= curbuf->b_ml.ml_locked_high; ++i, ++lnum)
+	    if ((dp->db_index[i]) & DB_MARKED)
+	    {
+		(dp->db_index[i]) &= DB_INDEX_MASK;
+		curbuf->b_ml.ml_flags |= ML_LOCKED_DIRTY;
+		lowest_marked = lnum + 1;
+		return lnum;
+	    }
+    }
+
+    return (linenr_T) 0;
+}
+
+#if 0  /* not used */
+/*
+ * return TRUE if line 'lnum' has a mark
+ */
+    int
+ml_has_mark(lnum)
+    linenr_T	lnum;
+{
+    bhdr_T	*hp;
+    DATA_BL	*dp;
+
+    if (curbuf->b_ml.ml_mfp == NULL
+			|| (hp = ml_find_line(curbuf, lnum, ML_FIND)) == NULL)
+	return FALSE;
+
+    dp = (DATA_BL *)(hp->bh_data);
+    return (int)((dp->db_index[lnum - curbuf->b_ml.ml_locked_low]) & DB_MARKED);
+}
+#endif
+
+/*
+ * clear all DB_MARKED flags
+ */
+    void
+ml_clearmarked()
+{
+    bhdr_T	*hp;
+    DATA_BL	*dp;
+    linenr_T	lnum;
+    int		i;
+
+    if (curbuf->b_ml.ml_mfp == NULL)	    /* nothing to do */
+	return;
+
+    /*
+     * The search starts with line lowest_marked.
+     */
+    for (lnum = lowest_marked; lnum <= curbuf->b_ml.ml_line_count; )
+    {
+	/*
+	 * Find the data block containing the line.
+	 * This also fills the stack with the blocks from the root to the data
+	 * block and releases any locked block.
+	 */
+	if ((hp = ml_find_line(curbuf, lnum, ML_FIND)) == NULL)
+	    return;		/* give error message? */
+
+	dp = (DATA_BL *)(hp->bh_data);
+
+	for (i = lnum - curbuf->b_ml.ml_locked_low;
+			    lnum <= curbuf->b_ml.ml_locked_high; ++i, ++lnum)
+	    if ((dp->db_index[i]) & DB_MARKED)
+	    {
+		(dp->db_index[i]) &= DB_INDEX_MASK;
+		curbuf->b_ml.ml_flags |= ML_LOCKED_DIRTY;
+	    }
+    }
+
+    lowest_marked = 0;
+    return;
+}
+
+/*
+ * flush ml_line if necessary
+ */
+    static void
+ml_flush_line(buf)
+    buf_T	*buf;
+{
+    bhdr_T	*hp;
+    DATA_BL	*dp;
+    linenr_T	lnum;
+    char_u	*new_line;
+    char_u	*old_line;
+    colnr_T	new_len;
+    int		old_len;
+    int		extra;
+    int		idx;
+    int		start;
+    int		count;
+    int		i;
+
+    if (buf->b_ml.ml_line_lnum == 0 || buf->b_ml.ml_mfp == NULL)
+	return;		/* nothing to do */
+
+    if (buf->b_ml.ml_flags & ML_LINE_DIRTY)
+    {
+	lnum = buf->b_ml.ml_line_lnum;
+	new_line = buf->b_ml.ml_line_ptr;
+
+	hp = ml_find_line(buf, lnum, ML_FIND);
+	if (hp == NULL)
+	    EMSGN(_("E320: Cannot find line %ld"), lnum);
+	else
+	{
+	    dp = (DATA_BL *)(hp->bh_data);
+	    idx = lnum - buf->b_ml.ml_locked_low;
+	    start = ((dp->db_index[idx]) & DB_INDEX_MASK);
+	    old_line = (char_u *)dp + start;
+	    if (idx == 0)	/* line is last in block */
+		old_len = dp->db_txt_end - start;
+	    else		/* text of previous line follows */
+		old_len = (dp->db_index[idx - 1] & DB_INDEX_MASK) - start;
+	    new_len = (colnr_T)STRLEN(new_line) + 1;
+	    extra = new_len - old_len;	    /* negative if lines gets smaller */
+
+	    /*
+	     * if new line fits in data block, replace directly
+	     */
+	    if ((int)dp->db_free >= extra)
+	    {
+		/* if the length changes and there are following lines */
+		count = buf->b_ml.ml_locked_high - buf->b_ml.ml_locked_low + 1;
+		if (extra != 0 && idx < count - 1)
+		{
+		    /* move text of following lines */
+		    mch_memmove((char *)dp + dp->db_txt_start - extra,
+				(char *)dp + dp->db_txt_start,
+				(size_t)(start - dp->db_txt_start));
+
+		    /* adjust pointers of this and following lines */
+		    for (i = idx + 1; i < count; ++i)
+			dp->db_index[i] -= extra;
+		}
+		dp->db_index[idx] -= extra;
+
+		/* adjust free space */
+		dp->db_free -= extra;
+		dp->db_txt_start -= extra;
+
+		/* copy new line into the data block */
+		mch_memmove(old_line - extra, new_line, (size_t)new_len);
+		buf->b_ml.ml_flags |= (ML_LOCKED_DIRTY | ML_LOCKED_POS);
+#ifdef FEAT_BYTEOFF
+		/* The else case is already covered by the insert and delete */
+		ml_updatechunk(buf, lnum, (long)extra, ML_CHNK_UPDLINE);
+#endif
+	    }
+	    else
+	    {
+		/*
+		 * Cannot do it in one data block: Delete and append.
+		 * Append first, because ml_delete_int() cannot delete the
+		 * last line in a buffer, which causes trouble for a buffer
+		 * that has only one line.
+		 * Don't forget to copy the mark!
+		 */
+		/* How about handling errors??? */
+		(void)ml_append_int(buf, lnum, new_line, new_len, FALSE,
+					     (dp->db_index[idx] & DB_MARKED));
+		(void)ml_delete_int(buf, lnum, FALSE);
+	    }
+	}
+	vim_free(new_line);
+    }
+
+    buf->b_ml.ml_line_lnum = 0;
+}
+
+/*
+ * create a new, empty, data block
+ */
+    static bhdr_T *
+ml_new_data(mfp, negative, page_count)
+    memfile_T	*mfp;
+    int		negative;
+    int		page_count;
+{
+    bhdr_T	*hp;
+    DATA_BL	*dp;
+
+    if ((hp = mf_new(mfp, negative, page_count)) == NULL)
+	return NULL;
+
+    dp = (DATA_BL *)(hp->bh_data);
+    dp->db_id = DATA_ID;
+    dp->db_txt_start = dp->db_txt_end = page_count * mfp->mf_page_size;
+    dp->db_free = dp->db_txt_start - HEADER_SIZE;
+    dp->db_line_count = 0;
+
+    return hp;
+}
+
+/*
+ * create a new, empty, pointer block
+ */
+    static bhdr_T *
+ml_new_ptr(mfp)
+    memfile_T	*mfp;
+{
+    bhdr_T	*hp;
+    PTR_BL	*pp;
+
+    if ((hp = mf_new(mfp, FALSE, 1)) == NULL)
+	return NULL;
+
+    pp = (PTR_BL *)(hp->bh_data);
+    pp->pb_id = PTR_ID;
+    pp->pb_count = 0;
+    pp->pb_count_max = (short_u)((mfp->mf_page_size - sizeof(PTR_BL)) / sizeof(PTR_EN) + 1);
+
+    return hp;
+}
+
+/*
+ * lookup line 'lnum' in a memline
+ *
+ *   action: if ML_DELETE or ML_INSERT the line count is updated while searching
+ *	     if ML_FLUSH only flush a locked block
+ *	     if ML_FIND just find the line
+ *
+ * If the block was found it is locked and put in ml_locked.
+ * The stack is updated to lead to the locked block. The ip_high field in
+ * the stack is updated to reflect the last line in the block AFTER the
+ * insert or delete, also if the pointer block has not been updated yet. But
+ * if ml_locked != NULL ml_locked_lineadd must be added to ip_high.
+ *
+ * return: NULL for failure, pointer to block header otherwise
+ */
+    static bhdr_T *
+ml_find_line(buf, lnum, action)
+    buf_T	*buf;
+    linenr_T	lnum;
+    int		action;
+{
+    DATA_BL	*dp;
+    PTR_BL	*pp;
+    infoptr_T	*ip;
+    bhdr_T	*hp;
+    memfile_T	*mfp;
+    linenr_T	t;
+    blocknr_T	bnum, bnum2;
+    int		dirty;
+    linenr_T	low, high;
+    int		top;
+    int		page_count;
+    int		idx;
+
+    mfp = buf->b_ml.ml_mfp;
+
+    /*
+     * If there is a locked block check if the wanted line is in it.
+     * If not, flush and release the locked block.
+     * Don't do this for ML_INSERT_SAME, because the stack need to be updated.
+     * Don't do this for ML_FLUSH, because we want to flush the locked block.
+     * Don't do this when 'swapfile' is reset, we want to load all the blocks.
+     */
+    if (buf->b_ml.ml_locked)
+    {
+	if (ML_SIMPLE(action)
+		&& buf->b_ml.ml_locked_low <= lnum
+		&& buf->b_ml.ml_locked_high >= lnum
+		&& !mf_dont_release)
+	{
+	    /* remember to update pointer blocks and stack later */
+	    if (action == ML_INSERT)
+	    {
+		++(buf->b_ml.ml_locked_lineadd);
+		++(buf->b_ml.ml_locked_high);
+	    }
+	    else if (action == ML_DELETE)
+	    {
+		--(buf->b_ml.ml_locked_lineadd);
+		--(buf->b_ml.ml_locked_high);
+	    }
+	    return (buf->b_ml.ml_locked);
+	}
+
+	mf_put(mfp, buf->b_ml.ml_locked, buf->b_ml.ml_flags & ML_LOCKED_DIRTY,
+					    buf->b_ml.ml_flags & ML_LOCKED_POS);
+	buf->b_ml.ml_locked = NULL;
+
+	/*
+	 * If lines have been added or deleted in the locked block, need to
+	 * update the line count in pointer blocks.
+	 */
+	if (buf->b_ml.ml_locked_lineadd != 0)
+	    ml_lineadd(buf, buf->b_ml.ml_locked_lineadd);
+    }
+
+    if (action == ML_FLUSH)	    /* nothing else to do */
+	return NULL;
+
+    bnum = 1;			    /* start at the root of the tree */
+    page_count = 1;
+    low = 1;
+    high = buf->b_ml.ml_line_count;
+
+    if (action == ML_FIND)	/* first try stack entries */
+    {
+	for (top = buf->b_ml.ml_stack_top - 1; top >= 0; --top)
+	{
+	    ip = &(buf->b_ml.ml_stack[top]);
+	    if (ip->ip_low <= lnum && ip->ip_high >= lnum)
+	    {
+		bnum = ip->ip_bnum;
+		low = ip->ip_low;
+		high = ip->ip_high;
+		buf->b_ml.ml_stack_top = top;	/* truncate stack at prev entry */
+		break;
+	    }
+	}
+	if (top < 0)
+	    buf->b_ml.ml_stack_top = 0;		/* not found, start at the root */
+    }
+    else	/* ML_DELETE or ML_INSERT */
+	buf->b_ml.ml_stack_top = 0;	/* start at the root */
+
+/*
+ * search downwards in the tree until a data block is found
+ */
+    for (;;)
+    {
+	if ((hp = mf_get(mfp, bnum, page_count)) == NULL)
+	    goto error_noblock;
+
+	/*
+	 * update high for insert/delete
+	 */
+	if (action == ML_INSERT)
+	    ++high;
+	else if (action == ML_DELETE)
+	    --high;
+
+	dp = (DATA_BL *)(hp->bh_data);
+	if (dp->db_id == DATA_ID)	/* data block */
+	{
+	    buf->b_ml.ml_locked = hp;
+	    buf->b_ml.ml_locked_low = low;
+	    buf->b_ml.ml_locked_high = high;
+	    buf->b_ml.ml_locked_lineadd = 0;
+	    buf->b_ml.ml_flags &= ~(ML_LOCKED_DIRTY | ML_LOCKED_POS);
+	    return hp;
+	}
+
+	pp = (PTR_BL *)(dp);		/* must be pointer block */
+	if (pp->pb_id != PTR_ID)
+	{
+	    EMSG(_("E317: pointer block id wrong"));
+	    goto error_block;
+	}
+
+	if ((top = ml_add_stack(buf)) < 0)	/* add new entry to stack */
+	    goto error_block;
+	ip = &(buf->b_ml.ml_stack[top]);
+	ip->ip_bnum = bnum;
+	ip->ip_low = low;
+	ip->ip_high = high;
+	ip->ip_index = -1;		/* index not known yet */
+
+	dirty = FALSE;
+	for (idx = 0; idx < (int)pp->pb_count; ++idx)
+	{
+	    t = pp->pb_pointer[idx].pe_line_count;
+	    CHECK(t == 0, _("pe_line_count is zero"));
+	    if ((low += t) > lnum)
+	    {
+		ip->ip_index = idx;
+		bnum = pp->pb_pointer[idx].pe_bnum;
+		page_count = pp->pb_pointer[idx].pe_page_count;
+		high = low - 1;
+		low -= t;
+
+		/*
+		 * a negative block number may have been changed
+		 */
+		if (bnum < 0)
+		{
+		    bnum2 = mf_trans_del(mfp, bnum);
+		    if (bnum != bnum2)
+		    {
+			bnum = bnum2;
+			pp->pb_pointer[idx].pe_bnum = bnum;
+			dirty = TRUE;
+		    }
+		}
+
+		break;
+	    }
+	}
+	if (idx >= (int)pp->pb_count)	    /* past the end: something wrong! */
+	{
+	    if (lnum > buf->b_ml.ml_line_count)
+		EMSGN(_("E322: line number out of range: %ld past the end"),
+					      lnum - buf->b_ml.ml_line_count);
+
+	    else
+		EMSGN(_("E323: line count wrong in block %ld"), bnum);
+	    goto error_block;
+	}
+	if (action == ML_DELETE)
+	{
+	    pp->pb_pointer[idx].pe_line_count--;
+	    dirty = TRUE;
+	}
+	else if (action == ML_INSERT)
+	{
+	    pp->pb_pointer[idx].pe_line_count++;
+	    dirty = TRUE;
+	}
+	mf_put(mfp, hp, dirty, FALSE);
+    }
+
+error_block:
+    mf_put(mfp, hp, FALSE, FALSE);
+error_noblock:
+/*
+ * If action is ML_DELETE or ML_INSERT we have to correct the tree for
+ * the incremented/decremented line counts, because there won't be a line
+ * inserted/deleted after all.
+ */
+    if (action == ML_DELETE)
+	ml_lineadd(buf, 1);
+    else if (action == ML_INSERT)
+	ml_lineadd(buf, -1);
+    buf->b_ml.ml_stack_top = 0;
+    return NULL;
+}
+
+/*
+ * add an entry to the info pointer stack
+ *
+ * return -1 for failure, number of the new entry otherwise
+ */
+    static int
+ml_add_stack(buf)
+    buf_T	*buf;
+{
+    int		top;
+    infoptr_T	*newstack;
+
+    top = buf->b_ml.ml_stack_top;
+
+	/* may have to increase the stack size */
+    if (top == buf->b_ml.ml_stack_size)
+    {
+	CHECK(top > 0, _("Stack size increases"));	/* more than 5 levels??? */
+
+	newstack = (infoptr_T *)alloc((unsigned)sizeof(infoptr_T) *
+					(buf->b_ml.ml_stack_size + STACK_INCR));
+	if (newstack == NULL)
+	    return -1;
+	mch_memmove(newstack, buf->b_ml.ml_stack, (size_t)top * sizeof(infoptr_T));
+	vim_free(buf->b_ml.ml_stack);
+	buf->b_ml.ml_stack = newstack;
+	buf->b_ml.ml_stack_size += STACK_INCR;
+    }
+
+    buf->b_ml.ml_stack_top++;
+    return top;
+}
+
+/*
+ * Update the pointer blocks on the stack for inserted/deleted lines.
+ * The stack itself is also updated.
+ *
+ * When a insert/delete line action fails, the line is not inserted/deleted,
+ * but the pointer blocks have already been updated. That is fixed here by
+ * walking through the stack.
+ *
+ * Count is the number of lines added, negative if lines have been deleted.
+ */
+    static void
+ml_lineadd(buf, count)
+    buf_T	*buf;
+    int		count;
+{
+    int		idx;
+    infoptr_T	*ip;
+    PTR_BL	*pp;
+    memfile_T	*mfp = buf->b_ml.ml_mfp;
+    bhdr_T	*hp;
+
+    for (idx = buf->b_ml.ml_stack_top - 1; idx >= 0; --idx)
+    {
+	ip = &(buf->b_ml.ml_stack[idx]);
+	if ((hp = mf_get(mfp, ip->ip_bnum, 1)) == NULL)
+	    break;
+	pp = (PTR_BL *)(hp->bh_data);	/* must be pointer block */
+	if (pp->pb_id != PTR_ID)
+	{
+	    mf_put(mfp, hp, FALSE, FALSE);
+	    EMSG(_("E317: pointer block id wrong 2"));
+	    break;
+	}
+	pp->pb_pointer[ip->ip_index].pe_line_count += count;
+	ip->ip_high += count;
+	mf_put(mfp, hp, TRUE, FALSE);
+    }
+}
+
+#ifdef HAVE_READLINK
+static int resolve_symlink __ARGS((char_u *fname, char_u *buf));
+
+/*
+ * Resolve a symlink in the last component of a file name.
+ * Note that f_resolve() does it for every part of the path, we don't do that
+ * here.
+ * If it worked returns OK and the resolved link in "buf[MAXPATHL]".
+ * Otherwise returns FAIL.
+ */
+    static int
+resolve_symlink(fname, buf)
+    char_u	*fname;
+    char_u	*buf;
+{
+    char_u	tmp[MAXPATHL];
+    int		ret;
+    int		depth = 0;
+
+    if (fname == NULL)
+	return FAIL;
+
+    /* Put the result so far in tmp[], starting with the original name. */
+    vim_strncpy(tmp, fname, MAXPATHL - 1);
+
+    for (;;)
+    {
+	/* Limit symlink depth to 100, catch recursive loops. */
+	if (++depth == 100)
+	{
+	    EMSG2(_("E773: Symlink loop for \"%s\""), fname);
+	    return FAIL;
+	}
+
+	ret = readlink((char *)tmp, (char *)buf, MAXPATHL - 1);
+	if (ret <= 0)
+	{
+	    if (errno == EINVAL || errno == ENOENT)
+	    {
+		/* Found non-symlink or not existing file, stop here.
+		 * When at the first level use the unmodifed name, skip the
+		 * call to vim_FullName(). */
+		if (depth == 1)
+		    return FAIL;
+
+		/* Use the resolved name in tmp[]. */
+		break;
+	    }
+
+	    /* There must be some error reading links, use original name. */
+	    return FAIL;
+	}
+	buf[ret] = NUL;
+
+	/*
+	 * Check whether the symlink is relative or absolute.
+	 * If it's relative, build a new path based on the directory
+	 * portion of the filename (if any) and the path the symlink
+	 * points to.
+	 */
+	if (mch_isFullName(buf))
+	    STRCPY(tmp, buf);
+	else
+	{
+	    char_u *tail;
+
+	    tail = gettail(tmp);
+	    if (STRLEN(tail) + STRLEN(buf) >= MAXPATHL)
+		return FAIL;
+	    STRCPY(tail, buf);
+	}
+    }
+
+    /*
+     * Try to resolve the full name of the file so that the swapfile name will
+     * be consistent even when opening a relative symlink from different
+     * working directories.
+     */
+    return vim_FullName(tmp, buf, MAXPATHL, TRUE);
+}
+#endif
+
+/*
+ * Make swap file name out of the file name and a directory name.
+ * Returns pointer to allocated memory or NULL.
+ */
+/*ARGSUSED*/
+    char_u *
+makeswapname(fname, ffname, buf, dir_name)
+    char_u	*fname;
+    char_u	*ffname;
+    buf_T	*buf;
+    char_u	*dir_name;
+{
+    char_u	*r, *s;
+#ifdef HAVE_READLINK
+    char_u	fname_buf[MAXPATHL];
+    char_u	*fname_res;
+#endif
+
+#if defined(UNIX) || defined(WIN3264)  /* Need _very_ long file names */
+    s = dir_name + STRLEN(dir_name);
+    if (after_pathsep(dir_name, s) && s[-1] == s[-2])
+    {			       /* Ends with '//', Use Full path */
+	r = NULL;
+	if ((s = make_percent_swname(dir_name, fname)) != NULL)
+	{
+	    r = modname(s, (char_u *)".swp", FALSE);
+	    vim_free(s);
+	}
+	return r;
+    }
+#endif
+
+#ifdef HAVE_READLINK
+    /* Expand symlink in the file name, so that we put the swap file with the
+     * actual file instead of with the symlink. */
+    if (resolve_symlink(fname, fname_buf) == OK)
+	fname_res = fname_buf;
+    else
+	fname_res = fname;
+#endif
+
+    r = buf_modname(
+#ifdef SHORT_FNAME
+	    TRUE,
+#else
+	    (buf->b_p_sn || buf->b_shortname),
+#endif
+#ifdef RISCOS
+	    /* Avoid problems if fname has special chars, eg <Wimp$Scrap> */
+	    ffname,
+#else
+# ifdef HAVE_READLINK
+	    fname_res,
+# else
+	    fname,
+# endif
+#endif
+	    (char_u *)
+#if defined(VMS) || defined(RISCOS)
+	    "_swp",
+#else
+	    ".swp",
+#endif
+#ifdef SHORT_FNAME		/* always 8.3 file name */
+	    FALSE
+#else
+	    /* Prepend a '.' to the swap file name for the current directory. */
+	    dir_name[0] == '.' && dir_name[1] == NUL
+#endif
+	       );
+    if (r == NULL)	    /* out of memory */
+	return NULL;
+
+    s = get_file_in_dir(r, dir_name);
+    vim_free(r);
+    return s;
+}
+
+/*
+ * Get file name to use for swap file or backup file.
+ * Use the name of the edited file "fname" and an entry in the 'dir' or 'bdir'
+ * option "dname".
+ * - If "dname" is ".", return "fname" (swap file in dir of file).
+ * - If "dname" starts with "./", insert "dname" in "fname" (swap file
+ *   relative to dir of file).
+ * - Otherwise, prepend "dname" to the tail of "fname" (swap file in specific
+ *   dir).
+ *
+ * The return value is an allocated string and can be NULL.
+ */
+    char_u *
+get_file_in_dir(fname, dname)
+    char_u  *fname;
+    char_u  *dname;	/* don't use "dirname", it is a global for Alpha */
+{
+    char_u	*t;
+    char_u	*tail;
+    char_u	*retval;
+    int		save_char;
+
+    tail = gettail(fname);
+
+    if (dname[0] == '.' && dname[1] == NUL)
+	retval = vim_strsave(fname);
+    else if (dname[0] == '.' && vim_ispathsep(dname[1]))
+    {
+	if (tail == fname)	    /* no path before file name */
+	    retval = concat_fnames(dname + 2, tail, TRUE);
+	else
+	{
+	    save_char = *tail;
+	    *tail = NUL;
+	    t = concat_fnames(fname, dname + 2, TRUE);
+	    *tail = save_char;
+	    if (t == NULL)	    /* out of memory */
+		retval = NULL;
+	    else
+	    {
+		retval = concat_fnames(t, tail, TRUE);
+		vim_free(t);
+	    }
+	}
+    }
+    else
+	retval = concat_fnames(dname, tail, TRUE);
+
+    return retval;
+}
+
+static void attention_message __ARGS((buf_T *buf, char_u *fname));
+
+/*
+ * Print the ATTENTION message: info about an existing swap file.
+ */
+    static void
+attention_message(buf, fname)
+    buf_T   *buf;	/* buffer being edited */
+    char_u  *fname;	/* swap file name */
+{
+    struct stat st;
+    time_t	x, sx;
+    char	*p;
+
+    ++no_wait_return;
+    (void)EMSG(_("E325: ATTENTION"));
+    MSG_PUTS(_("\nFound a swap file by the name \""));
+    msg_home_replace(fname);
+    MSG_PUTS("\"\n");
+    sx = swapfile_info(fname);
+    MSG_PUTS(_("While opening file \""));
+    msg_outtrans(buf->b_fname);
+    MSG_PUTS("\"\n");
+    if (mch_stat((char *)buf->b_fname, &st) != -1)
+    {
+	MSG_PUTS(_("             dated: "));
+	x = st.st_mtime;    /* Manx C can't do &st.st_mtime */
+	p = ctime(&x);			    /* includes '\n' */
+	if (p == NULL)
+	    MSG_PUTS("(invalid)\n");
+	else
+	    MSG_PUTS(p);
+	if (sx != 0 && x > sx)
+	    MSG_PUTS(_("      NEWER than swap file!\n"));
+    }
+    /* Some of these messages are long to allow translation to
+     * other languages. */
+    MSG_PUTS(_("\n(1) Another program may be editing the same file.\n    If this is the case, be careful not to end up with two\n    different instances of the same file when making changes.\n"));
+    MSG_PUTS(_("    Quit, or continue with caution.\n"));
+    MSG_PUTS(_("\n(2) An edit session for this file crashed.\n"));
+    MSG_PUTS(_("    If this is the case, use \":recover\" or \"vim -r "));
+    msg_outtrans(buf->b_fname);
+    MSG_PUTS(_("\"\n    to recover the changes (see \":help recovery\").\n"));
+    MSG_PUTS(_("    If you did this already, delete the swap file \""));
+    msg_outtrans(fname);
+    MSG_PUTS(_("\"\n    to avoid this message.\n"));
+    cmdline_row = msg_row;
+    --no_wait_return;
+}
+
+#ifdef FEAT_AUTOCMD
+static int do_swapexists __ARGS((buf_T *buf, char_u *fname));
+
+/*
+ * Trigger the SwapExists autocommands.
+ * Returns a value for equivalent to do_dialog() (see below):
+ * 0: still need to ask for a choice
+ * 1: open read-only
+ * 2: edit anyway
+ * 3: recover
+ * 4: delete it
+ * 5: quit
+ * 6: abort
+ */
+    static int
+do_swapexists(buf, fname)
+    buf_T	*buf;
+    char_u	*fname;
+{
+    set_vim_var_string(VV_SWAPNAME, fname, -1);
+    set_vim_var_string(VV_SWAPCHOICE, NULL, -1);
+
+    /* Trigger SwapExists autocommands with <afile> set to the file being
+     * edited. */
+    apply_autocmds(EVENT_SWAPEXISTS, buf->b_fname, NULL, FALSE, NULL);
+
+    set_vim_var_string(VV_SWAPNAME, NULL, -1);
+
+    switch (*get_vim_var_str(VV_SWAPCHOICE))
+    {
+	case 'o': return 1;
+	case 'e': return 2;
+	case 'r': return 3;
+	case 'd': return 4;
+	case 'q': return 5;
+	case 'a': return 6;
+    }
+
+    return 0;
+}
+#endif
+
+/*
+ * Find out what name to use for the swap file for buffer 'buf'.
+ *
+ * Several names are tried to find one that does not exist
+ * Returns the name in allocated memory or NULL.
+ *
+ * Note: If BASENAMELEN is not correct, you will get error messages for
+ *	 not being able to open the swapfile
+ */
+    static char_u *
+findswapname(buf, dirp, old_fname)
+    buf_T	*buf;
+    char_u	**dirp;		/* pointer to list of directories */
+    char_u	*old_fname;	/* don't give warning for this file name */
+{
+    char_u	*fname;
+    int		n;
+    char_u	*dir_name;
+#ifdef AMIGA
+    BPTR	fh;
+#endif
+#ifndef SHORT_FNAME
+    int		r;
+#endif
+
+#if !defined(SHORT_FNAME) \
+		     && ((!defined(UNIX) && !defined(OS2)) || defined(ARCHIE))
+# define CREATE_DUMMY_FILE
+    FILE	*dummyfd = NULL;
+
+/*
+ * If we start editing a new file, e.g. "test.doc", which resides on an MSDOS
+ * compatible filesystem, it is possible that the file "test.doc.swp" which we
+ * create will be exactly the same file. To avoid this problem we temporarily
+ * create "test.doc".
+ * Don't do this when the check below for a 8.3 file name is used.
+ */
+    if (!(buf->b_p_sn || buf->b_shortname) && buf->b_fname != NULL
+					     && mch_getperm(buf->b_fname) < 0)
+	dummyfd = mch_fopen((char *)buf->b_fname, "w");
+#endif
+
+/*
+ * Isolate a directory name from *dirp and put it in dir_name.
+ * First allocate some memory to put the directory name in.
+ */
+    dir_name = alloc((unsigned)STRLEN(*dirp) + 1);
+    if (dir_name != NULL)
+	(void)copy_option_part(dirp, dir_name, 31000, ",");
+
+/*
+ * we try different names until we find one that does not exist yet
+ */
+    if (dir_name == NULL)	    /* out of memory */
+	fname = NULL;
+    else
+	fname = makeswapname(buf->b_fname, buf->b_ffname, buf, dir_name);
+
+    for (;;)
+    {
+	if (fname == NULL)	/* must be out of memory */
+	    break;
+	if ((n = (int)STRLEN(fname)) == 0)	/* safety check */
+	{
+	    vim_free(fname);
+	    fname = NULL;
+	    break;
+	}
+#if (defined(UNIX) || defined(OS2)) && !defined(ARCHIE) && !defined(SHORT_FNAME)
+/*
+ * Some systems have a MS-DOS compatible filesystem that use 8.3 character
+ * file names. If this is the first try and the swap file name does not fit in
+ * 8.3, detect if this is the case, set shortname and try again.
+ */
+	if (fname[n - 2] == 'w' && fname[n - 1] == 'p'
+					&& !(buf->b_p_sn || buf->b_shortname))
+	{
+	    char_u	    *tail;
+	    char_u	    *fname2;
+	    struct stat	    s1, s2;
+	    int		    f1, f2;
+	    int		    created1 = FALSE, created2 = FALSE;
+	    int		    same = FALSE;
+
+	    /*
+	     * Check if swapfile name does not fit in 8.3:
+	     * It either contains two dots, is longer than 8 chars, or starts
+	     * with a dot.
+	     */
+	    tail = gettail(buf->b_fname);
+	    if (       vim_strchr(tail, '.') != NULL
+		    || STRLEN(tail) > (size_t)8
+		    || *gettail(fname) == '.')
+	    {
+		fname2 = alloc(n + 2);
+		if (fname2 != NULL)
+		{
+		    STRCPY(fname2, fname);
+		    /* if fname == "xx.xx.swp",	    fname2 = "xx.xx.swx"
+		     * if fname == ".xx.swp",	    fname2 = ".xx.swpx"
+		     * if fname == "123456789.swp", fname2 = "12345678x.swp"
+		     */
+		    if (vim_strchr(tail, '.') != NULL)
+			fname2[n - 1] = 'x';
+		    else if (*gettail(fname) == '.')
+		    {
+			fname2[n] = 'x';
+			fname2[n + 1] = NUL;
+		    }
+		    else
+			fname2[n - 5] += 1;
+		    /*
+		     * may need to create the files to be able to use mch_stat()
+		     */
+		    f1 = mch_open((char *)fname, O_RDONLY | O_EXTRA, 0);
+		    if (f1 < 0)
+		    {
+			f1 = mch_open_rw((char *)fname,
+					       O_RDWR|O_CREAT|O_EXCL|O_EXTRA);
+#if defined(OS2)
+			if (f1 < 0 && errno == ENOENT)
+			    same = TRUE;
+#endif
+			created1 = TRUE;
+		    }
+		    if (f1 >= 0)
+		    {
+			f2 = mch_open((char *)fname2, O_RDONLY | O_EXTRA, 0);
+			if (f2 < 0)
+			{
+			    f2 = mch_open_rw((char *)fname2,
+					       O_RDWR|O_CREAT|O_EXCL|O_EXTRA);
+			    created2 = TRUE;
+			}
+			if (f2 >= 0)
+			{
+			    /*
+			     * Both files exist now. If mch_stat() returns the
+			     * same device and inode they are the same file.
+			     */
+			    if (mch_fstat(f1, &s1) != -1
+				    && mch_fstat(f2, &s2) != -1
+				    && s1.st_dev == s2.st_dev
+				    && s1.st_ino == s2.st_ino)
+				same = TRUE;
+			    close(f2);
+			    if (created2)
+				mch_remove(fname2);
+			}
+			close(f1);
+			if (created1)
+			    mch_remove(fname);
+		    }
+		    vim_free(fname2);
+		    if (same)
+		    {
+			buf->b_shortname = TRUE;
+			vim_free(fname);
+			fname = makeswapname(buf->b_fname, buf->b_ffname,
+							       buf, dir_name);
+			continue;	/* try again with b_shortname set */
+		    }
+		}
+	    }
+	}
+#endif
+	/*
+	 * check if the swapfile already exists
+	 */
+	if (mch_getperm(fname) < 0)	/* it does not exist */
+	{
+#ifdef HAVE_LSTAT
+	    struct stat sb;
+
+	    /*
+	     * Extra security check: When a swap file is a symbolic link, this
+	     * is most likely a symlink attack.
+	     */
+	    if (mch_lstat((char *)fname, &sb) < 0)
+#else
+# ifdef AMIGA
+	    fh = Open((UBYTE *)fname, (long)MODE_NEWFILE);
+	    /*
+	     * on the Amiga mch_getperm() will return -1 when the file exists
+	     * but is being used by another program. This happens if you edit
+	     * a file twice.
+	     */
+	    if (fh != (BPTR)NULL)	/* can open file, OK */
+	    {
+		Close(fh);
+		mch_remove(fname);
+		break;
+	    }
+	    if (IoErr() != ERROR_OBJECT_IN_USE
+					    && IoErr() != ERROR_OBJECT_EXISTS)
+# endif
+#endif
+		break;
+	}
+
+	/*
+	 * A file name equal to old_fname is OK to use.
+	 */
+	if (old_fname != NULL && fnamecmp(fname, old_fname) == 0)
+	    break;
+
+	/*
+	 * get here when file already exists
+	 */
+	if (fname[n - 2] == 'w' && fname[n - 1] == 'p')	/* first try */
+	{
+#ifndef SHORT_FNAME
+	    /*
+	     * on MS-DOS compatible filesystems (e.g. messydos) file.doc.swp
+	     * and file.doc are the same file. To guess if this problem is
+	     * present try if file.doc.swx exists. If it does, we set
+	     * buf->b_shortname and try file_doc.swp (dots replaced by
+	     * underscores for this file), and try again. If it doesn't we
+	     * assume that "file.doc.swp" already exists.
+	     */
+	    if (!(buf->b_p_sn || buf->b_shortname))	/* not tried yet */
+	    {
+		fname[n - 1] = 'x';
+		r = mch_getperm(fname);		/* try "file.swx" */
+		fname[n - 1] = 'p';
+		if (r >= 0)		    /* "file.swx" seems to exist */
+		{
+		    buf->b_shortname = TRUE;
+		    vim_free(fname);
+		    fname = makeswapname(buf->b_fname, buf->b_ffname,
+							       buf, dir_name);
+		    continue;	    /* try again with '.' replaced with '_' */
+		}
+	    }
+#endif
+	    /*
+	     * If we get here the ".swp" file really exists.
+	     * Give an error message, unless recovering, no file name, we are
+	     * viewing a help file or when the path of the file is different
+	     * (happens when all .swp files are in one directory).
+	     */
+	    if (!recoverymode && buf->b_fname != NULL
+				&& !buf->b_help && !(buf->b_flags & BF_DUMMY))
+	    {
+		int		fd;
+		struct block0	b0;
+		int		differ = FALSE;
+
+		/*
+		 * Try to read block 0 from the swap file to get the original
+		 * file name (and inode number).
+		 */
+		fd = mch_open((char *)fname, O_RDONLY | O_EXTRA, 0);
+		if (fd >= 0)
+		{
+		    if (read(fd, (char *)&b0, sizeof(b0)) == sizeof(b0))
+		    {
+			/*
+			 * If the swapfile has the same directory as the
+			 * buffer don't compare the directory names, they can
+			 * have a different mountpoint.
+			 */
+			if (b0.b0_flags & B0_SAME_DIR)
+			{
+			    if (fnamecmp(gettail(buf->b_ffname),
+						   gettail(b0.b0_fname)) != 0
+				    || !same_directory(fname, buf->b_ffname))
+			    {
+#ifdef CHECK_INODE
+				/* Symlinks may point to the same file even
+				 * when the name differs, need to check the
+				 * inode too. */
+				expand_env(b0.b0_fname, NameBuff, MAXPATHL);
+				if (fnamecmp_ino(buf->b_ffname, NameBuff,
+						     char_to_long(b0.b0_ino)))
+#endif
+				    differ = TRUE;
+			    }
+			}
+			else
+			{
+			    /*
+			     * The name in the swap file may be
+			     * "~user/path/file".  Expand it first.
+			     */
+			    expand_env(b0.b0_fname, NameBuff, MAXPATHL);
+#ifdef CHECK_INODE
+			    if (fnamecmp_ino(buf->b_ffname, NameBuff,
+						     char_to_long(b0.b0_ino)))
+				differ = TRUE;
+#else
+			    if (fnamecmp(NameBuff, buf->b_ffname) != 0)
+				differ = TRUE;
+#endif
+			}
+		    }
+		    close(fd);
+		}
+#ifdef RISCOS
+		else
+		    /* Can't open swap file, though it does exist.
+		     * Assume that the user is editing two files with
+		     * the same name in different directories. No error.
+		     */
+		    differ = TRUE;
+#endif
+
+		/* give the ATTENTION message when there is an old swap file
+		 * for the current file, and the buffer was not recovered. */
+		if (differ == FALSE && !(curbuf->b_flags & BF_RECOVERED)
+			&& vim_strchr(p_shm, SHM_ATTENTION) == NULL)
+		{
+#if defined(HAS_SWAP_EXISTS_ACTION)
+		    int		choice = 0;
+#endif
+#ifdef CREATE_DUMMY_FILE
+		    int		did_use_dummy = FALSE;
+
+		    /* Avoid getting a warning for the file being created
+		     * outside of Vim, it was created at the start of this
+		     * function.  Delete the file now, because Vim might exit
+		     * here if the window is closed. */
+		    if (dummyfd != NULL)
+		    {
+			fclose(dummyfd);
+			dummyfd = NULL;
+			mch_remove(buf->b_fname);
+			did_use_dummy = TRUE;
+		    }
+#endif
+
+#if (defined(UNIX) || defined(__EMX__) || defined(VMS)) && (defined(FEAT_GUI_DIALOG) || defined(FEAT_CON_DIALOG))
+		    process_still_running = FALSE;
+#endif
+#ifdef FEAT_AUTOCMD
+		    /*
+		     * If there is an SwapExists autocommand and we can handle
+		     * the response, trigger it.  It may return 0 to ask the
+		     * user anyway.
+		     */
+		    if (swap_exists_action != SEA_NONE
+			    && has_autocmd(EVENT_SWAPEXISTS, buf->b_fname, buf))
+			choice = do_swapexists(buf, fname);
+
+		    if (choice == 0)
+#endif
+		    {
+#ifdef FEAT_GUI
+			/* If we are supposed to start the GUI but it wasn't
+			 * completely started yet, start it now.  This makes
+			 * the messages displayed in the Vim window when
+			 * loading a session from the .gvimrc file. */
+			if (gui.starting && !gui.in_use)
+			    gui_start();
+#endif
+			/* Show info about the existing swap file. */
+			attention_message(buf, fname);
+
+			/* We don't want a 'q' typed at the more-prompt
+			 * interrupt loading a file. */
+			got_int = FALSE;
+		    }
+
+#if defined(FEAT_GUI_DIALOG) || defined(FEAT_CON_DIALOG)
+		    if (swap_exists_action != SEA_NONE && choice == 0)
+		    {
+			char_u	*name;
+
+			name = alloc((unsigned)(STRLEN(fname)
+				+ STRLEN(_("Swap file \""))
+				+ STRLEN(_("\" already exists!")) + 5));
+			if (name != NULL)
+			{
+			    STRCPY(name, _("Swap file \""));
+			    home_replace(NULL, fname, name + STRLEN(name),
+								  1000, TRUE);
+			    STRCAT(name, _("\" already exists!"));
+			}
+			choice = do_dialog(VIM_WARNING,
+				    (char_u *)_("VIM - ATTENTION"),
+				    name == NULL
+					?  (char_u *)_("Swap file already exists!")
+					: name,
+# if defined(UNIX) || defined(__EMX__) || defined(VMS)
+				    process_still_running
+					? (char_u *)_("&Open Read-Only\n&Edit anyway\n&Recover\n&Quit\n&Abort") :
+# endif
+					(char_u *)_("&Open Read-Only\n&Edit anyway\n&Recover\n&Delete it\n&Quit\n&Abort"), 1, NULL);
+
+# if defined(UNIX) || defined(__EMX__) || defined(VMS)
+			if (process_still_running && choice >= 4)
+			    choice++;	/* Skip missing "Delete it" button */
+# endif
+			vim_free(name);
+
+			/* pretend screen didn't scroll, need redraw anyway */
+			msg_scrolled = 0;
+			redraw_all_later(NOT_VALID);
+		    }
+#endif
+
+#if defined(HAS_SWAP_EXISTS_ACTION)
+		    if (choice > 0)
+		    {
+			switch (choice)
+			{
+			    case 1:
+				buf->b_p_ro = TRUE;
+				break;
+			    case 2:
+				break;
+			    case 3:
+				swap_exists_action = SEA_RECOVER;
+				break;
+			    case 4:
+				mch_remove(fname);
+				break;
+			    case 5:
+				swap_exists_action = SEA_QUIT;
+				break;
+			    case 6:
+				swap_exists_action = SEA_QUIT;
+				got_int = TRUE;
+				break;
+			}
+
+			/* If the file was deleted this fname can be used. */
+			if (mch_getperm(fname) < 0)
+			    break;
+		    }
+		    else
+#endif
+		    {
+			MSG_PUTS("\n");
+			if (msg_silent == 0)
+			    /* call wait_return() later */
+			    need_wait_return = TRUE;
+		    }
+
+#ifdef CREATE_DUMMY_FILE
+		    /* Going to try another name, need the dummy file again. */
+		    if (did_use_dummy)
+			dummyfd = mch_fopen((char *)buf->b_fname, "w");
+#endif
+		}
+	    }
+	}
+
+	/*
+	 * Change the ".swp" extension to find another file that can be used.
+	 * First decrement the last char: ".swo", ".swn", etc.
+	 * If that still isn't enough decrement the last but one char: ".svz"
+	 * Can happen when editing many "No Name" buffers.
+	 */
+	if (fname[n - 1] == 'a')	/* ".s?a" */
+	{
+	    if (fname[n - 2] == 'a')    /* ".saa": tried enough, give up */
+	    {
+		EMSG(_("E326: Too many swap files found"));
+		vim_free(fname);
+		fname = NULL;
+		break;
+	    }
+	    --fname[n - 2];		/* ".svz", ".suz", etc. */
+	    fname[n - 1] = 'z' + 1;
+	}
+	--fname[n - 1];			/* ".swo", ".swn", etc. */
+    }
+
+    vim_free(dir_name);
+#ifdef CREATE_DUMMY_FILE
+    if (dummyfd != NULL)	/* file has been created temporarily */
+    {
+	fclose(dummyfd);
+	mch_remove(buf->b_fname);
+    }
+#endif
+    return fname;
+}
+
+    static int
+b0_magic_wrong(b0p)
+    ZERO_BL *b0p;
+{
+    return (b0p->b0_magic_long != (long)B0_MAGIC_LONG
+	    || b0p->b0_magic_int != (int)B0_MAGIC_INT
+	    || b0p->b0_magic_short != (short)B0_MAGIC_SHORT
+	    || b0p->b0_magic_char != B0_MAGIC_CHAR);
+}
+
+#ifdef CHECK_INODE
+/*
+ * Compare current file name with file name from swap file.
+ * Try to use inode numbers when possible.
+ * Return non-zero when files are different.
+ *
+ * When comparing file names a few things have to be taken into consideration:
+ * - When working over a network the full path of a file depends on the host.
+ *   We check the inode number if possible.  It is not 100% reliable though,
+ *   because the device number cannot be used over a network.
+ * - When a file does not exist yet (editing a new file) there is no inode
+ *   number.
+ * - The file name in a swap file may not be valid on the current host.  The
+ *   "~user" form is used whenever possible to avoid this.
+ *
+ * This is getting complicated, let's make a table:
+ *
+ *		ino_c  ino_s  fname_c  fname_s	differ =
+ *
+ * both files exist -> compare inode numbers:
+ *		!= 0   != 0	X	 X	ino_c != ino_s
+ *
+ * inode number(s) unknown, file names available -> compare file names
+ *		== 0	X	OK	 OK	fname_c != fname_s
+ *		 X     == 0	OK	 OK	fname_c != fname_s
+ *
+ * current file doesn't exist, file for swap file exist, file name(s) not
+ * available -> probably different
+ *		== 0   != 0    FAIL	 X	TRUE
+ *		== 0   != 0	X	FAIL	TRUE
+ *
+ * current file exists, inode for swap unknown, file name(s) not
+ * available -> probably different
+ *		!= 0   == 0    FAIL	 X	TRUE
+ *		!= 0   == 0	X	FAIL	TRUE
+ *
+ * current file doesn't exist, inode for swap unknown, one file name not
+ * available -> probably different
+ *		== 0   == 0    FAIL	 OK	TRUE
+ *		== 0   == 0	OK	FAIL	TRUE
+ *
+ * current file doesn't exist, inode for swap unknown, both file names not
+ * available -> probably same file
+ *		== 0   == 0    FAIL	FAIL	FALSE
+ *
+ * Note that when the ino_t is 64 bits, only the last 32 will be used.  This
+ * can't be changed without making the block 0 incompatible with 32 bit
+ * versions.
+ */
+
+    static int
+fnamecmp_ino(fname_c, fname_s, ino_block0)
+    char_u	*fname_c;	    /* current file name */
+    char_u	*fname_s;	    /* file name from swap file */
+    long	ino_block0;
+{
+    struct stat	st;
+    ino_t	ino_c = 0;	    /* ino of current file */
+    ino_t	ino_s;		    /* ino of file from swap file */
+    char_u	buf_c[MAXPATHL];    /* full path of fname_c */
+    char_u	buf_s[MAXPATHL];    /* full path of fname_s */
+    int		retval_c;	    /* flag: buf_c valid */
+    int		retval_s;	    /* flag: buf_s valid */
+
+    if (mch_stat((char *)fname_c, &st) == 0)
+	ino_c = (ino_t)st.st_ino;
+
+    /*
+     * First we try to get the inode from the file name, because the inode in
+     * the swap file may be outdated.  If that fails (e.g. this path is not
+     * valid on this machine), use the inode from block 0.
+     */
+    if (mch_stat((char *)fname_s, &st) == 0)
+	ino_s = (ino_t)st.st_ino;
+    else
+	ino_s = (ino_t)ino_block0;
+
+    if (ino_c && ino_s)
+	return (ino_c != ino_s);
+
+    /*
+     * One of the inode numbers is unknown, try a forced vim_FullName() and
+     * compare the file names.
+     */
+    retval_c = vim_FullName(fname_c, buf_c, MAXPATHL, TRUE);
+    retval_s = vim_FullName(fname_s, buf_s, MAXPATHL, TRUE);
+    if (retval_c == OK && retval_s == OK)
+	return (STRCMP(buf_c, buf_s) != 0);
+
+    /*
+     * Can't compare inodes or file names, guess that the files are different,
+     * unless both appear not to exist at all.
+     */
+    if (ino_s == 0 && ino_c == 0 && retval_c == FAIL && retval_s == FAIL)
+	return FALSE;
+    return TRUE;
+}
+#endif /* CHECK_INODE */
+
+/*
+ * Move a long integer into a four byte character array.
+ * Used for machine independency in block zero.
+ */
+    static void
+long_to_char(n, s)
+    long    n;
+    char_u  *s;
+{
+    s[0] = (char_u)(n & 0xff);
+    n = (unsigned)n >> 8;
+    s[1] = (char_u)(n & 0xff);
+    n = (unsigned)n >> 8;
+    s[2] = (char_u)(n & 0xff);
+    n = (unsigned)n >> 8;
+    s[3] = (char_u)(n & 0xff);
+}
+
+    static long
+char_to_long(s)
+    char_u  *s;
+{
+    long    retval;
+
+    retval = s[3];
+    retval <<= 8;
+    retval |= s[2];
+    retval <<= 8;
+    retval |= s[1];
+    retval <<= 8;
+    retval |= s[0];
+
+    return retval;
+}
+
+/*
+ * Set the flags in the first block of the swap file:
+ * - file is modified or not: buf->b_changed
+ * - 'fileformat'
+ * - 'fileencoding'
+ */
+    void
+ml_setflags(buf)
+    buf_T	*buf;
+{
+    bhdr_T	*hp;
+    ZERO_BL	*b0p;
+
+    if (!buf->b_ml.ml_mfp)
+	return;
+    for (hp = buf->b_ml.ml_mfp->mf_used_last; hp != NULL; hp = hp->bh_prev)
+    {
+	if (hp->bh_bnum == 0)
+	{
+	    b0p = (ZERO_BL *)(hp->bh_data);
+	    b0p->b0_dirty = buf->b_changed ? B0_DIRTY : 0;
+	    b0p->b0_flags = (b0p->b0_flags & ~B0_FF_MASK)
+						  | (get_fileformat(buf) + 1);
+#ifdef FEAT_MBYTE
+	    add_b0_fenc(b0p, buf);
+#endif
+	    hp->bh_flags |= BH_DIRTY;
+	    mf_sync(buf->b_ml.ml_mfp, MFS_ZERO);
+	    break;
+	}
+    }
+}
+
+#if defined(FEAT_BYTEOFF) || defined(PROTO)
+
+#define MLCS_MAXL 800	/* max no of lines in chunk */
+#define MLCS_MINL 400   /* should be half of MLCS_MAXL */
+
+/*
+ * Keep information for finding byte offset of a line, updtytpe may be one of:
+ * ML_CHNK_ADDLINE: Add len to parent chunk, possibly splitting it
+ *	   Careful: ML_CHNK_ADDLINE may cause ml_find_line() to be called.
+ * ML_CHNK_DELLINE: Subtract len from parent chunk, possibly deleting it
+ * ML_CHNK_UPDLINE: Add len to parent chunk, as a signed entity.
+ */
+    static void
+ml_updatechunk(buf, line, len, updtype)
+    buf_T	*buf;
+    linenr_T	line;
+    long	len;
+    int		updtype;
+{
+    static buf_T	*ml_upd_lastbuf = NULL;
+    static linenr_T	ml_upd_lastline;
+    static linenr_T	ml_upd_lastcurline;
+    static int		ml_upd_lastcurix;
+
+    linenr_T		curline = ml_upd_lastcurline;
+    int			curix = ml_upd_lastcurix;
+    long		size;
+    chunksize_T		*curchnk;
+    int			rest;
+    bhdr_T		*hp;
+    DATA_BL		*dp;
+
+    if (buf->b_ml.ml_usedchunks == -1 || len == 0)
+	return;
+    if (buf->b_ml.ml_chunksize == NULL)
+    {
+	buf->b_ml.ml_chunksize = (chunksize_T *)
+				  alloc((unsigned)sizeof(chunksize_T) * 100);
+	if (buf->b_ml.ml_chunksize == NULL)
+	{
+	    buf->b_ml.ml_usedchunks = -1;
+	    return;
+	}
+	buf->b_ml.ml_numchunks = 100;
+	buf->b_ml.ml_usedchunks = 1;
+	buf->b_ml.ml_chunksize[0].mlcs_numlines = 1;
+	buf->b_ml.ml_chunksize[0].mlcs_totalsize = 1;
+    }
+
+    if (updtype == ML_CHNK_UPDLINE && buf->b_ml.ml_line_count == 1)
+    {
+	/*
+	 * First line in empty buffer from ml_flush_line() -- reset
+	 */
+	buf->b_ml.ml_usedchunks = 1;
+	buf->b_ml.ml_chunksize[0].mlcs_numlines = 1;
+	buf->b_ml.ml_chunksize[0].mlcs_totalsize =
+				  (long)STRLEN(buf->b_ml.ml_line_ptr) + 1;
+	return;
+    }
+
+    /*
+     * Find chunk that our line belongs to, curline will be at start of the
+     * chunk.
+     */
+    if (buf != ml_upd_lastbuf || line != ml_upd_lastline + 1
+	    || updtype != ML_CHNK_ADDLINE)
+    {
+	for (curline = 1, curix = 0;
+	     curix < buf->b_ml.ml_usedchunks - 1
+	     && line >= curline + buf->b_ml.ml_chunksize[curix].mlcs_numlines;
+	     curix++)
+	{
+	    curline += buf->b_ml.ml_chunksize[curix].mlcs_numlines;
+	}
+    }
+    else if (line >= curline + buf->b_ml.ml_chunksize[curix].mlcs_numlines
+		 && curix < buf->b_ml.ml_usedchunks - 1)
+    {
+	/* Adjust cached curix & curline */
+	curline += buf->b_ml.ml_chunksize[curix].mlcs_numlines;
+	curix++;
+    }
+    curchnk = buf->b_ml.ml_chunksize + curix;
+
+    if (updtype == ML_CHNK_DELLINE)
+	len = -len;
+    curchnk->mlcs_totalsize += len;
+    if (updtype == ML_CHNK_ADDLINE)
+    {
+	curchnk->mlcs_numlines++;
+
+	/* May resize here so we don't have to do it in both cases below */
+	if (buf->b_ml.ml_usedchunks + 1 >= buf->b_ml.ml_numchunks)
+	{
+	    buf->b_ml.ml_numchunks = buf->b_ml.ml_numchunks * 3 / 2;
+	    buf->b_ml.ml_chunksize = (chunksize_T *)
+		vim_realloc(buf->b_ml.ml_chunksize,
+			    sizeof(chunksize_T) * buf->b_ml.ml_numchunks);
+	    if (buf->b_ml.ml_chunksize == NULL)
+	    {
+		/* Hmmmm, Give up on offset for this buffer */
+		buf->b_ml.ml_usedchunks = -1;
+		return;
+	    }
+	}
+
+	if (buf->b_ml.ml_chunksize[curix].mlcs_numlines >= MLCS_MAXL)
+	{
+	    int	    count;	    /* number of entries in block */
+	    int	    idx;
+	    int	    text_end;
+	    int	    linecnt;
+
+	    mch_memmove(buf->b_ml.ml_chunksize + curix + 1,
+			buf->b_ml.ml_chunksize + curix,
+			(buf->b_ml.ml_usedchunks - curix) *
+			sizeof(chunksize_T));
+	    /* Compute length of first half of lines in the splitted chunk */
+	    size = 0;
+	    linecnt = 0;
+	    while (curline < buf->b_ml.ml_line_count
+			&& linecnt < MLCS_MINL)
+	    {
+		if ((hp = ml_find_line(buf, curline, ML_FIND)) == NULL)
+		{
+		    buf->b_ml.ml_usedchunks = -1;
+		    return;
+		}
+		dp = (DATA_BL *)(hp->bh_data);
+		count = (long)(buf->b_ml.ml_locked_high) -
+			(long)(buf->b_ml.ml_locked_low) + 1;
+		idx = curline - buf->b_ml.ml_locked_low;
+		curline = buf->b_ml.ml_locked_high + 1;
+		if (idx == 0)/* first line in block, text at the end */
+		    text_end = dp->db_txt_end;
+		else
+		    text_end = ((dp->db_index[idx - 1]) & DB_INDEX_MASK);
+		/* Compute index of last line to use in this MEMLINE */
+		rest = count - idx;
+		if (linecnt + rest > MLCS_MINL)
+		{
+		    idx += MLCS_MINL - linecnt - 1;
+		    linecnt = MLCS_MINL;
+		}
+		else
+		{
+		    idx = count - 1;
+		    linecnt += rest;
+		}
+		size += text_end - ((dp->db_index[idx]) & DB_INDEX_MASK);
+	    }
+	    buf->b_ml.ml_chunksize[curix].mlcs_numlines = linecnt;
+	    buf->b_ml.ml_chunksize[curix + 1].mlcs_numlines -= linecnt;
+	    buf->b_ml.ml_chunksize[curix].mlcs_totalsize = size;
+	    buf->b_ml.ml_chunksize[curix + 1].mlcs_totalsize -= size;
+	    buf->b_ml.ml_usedchunks++;
+	    ml_upd_lastbuf = NULL;   /* Force recalc of curix & curline */
+	    return;
+	}
+	else if (buf->b_ml.ml_chunksize[curix].mlcs_numlines >= MLCS_MINL
+		     && curix == buf->b_ml.ml_usedchunks - 1
+		     && buf->b_ml.ml_line_count - line <= 1)
+	{
+	    /*
+	     * We are in the last chunk and it is cheap to crate a new one
+	     * after this. Do it now to avoid the loop above later on
+	     */
+	    curchnk = buf->b_ml.ml_chunksize + curix + 1;
+	    buf->b_ml.ml_usedchunks++;
+	    if (line == buf->b_ml.ml_line_count)
+	    {
+		curchnk->mlcs_numlines = 0;
+		curchnk->mlcs_totalsize = 0;
+	    }
+	    else
+	    {
+		/*
+		 * Line is just prior to last, move count for last
+		 * This is the common case  when loading a new file
+		 */
+		hp = ml_find_line(buf, buf->b_ml.ml_line_count, ML_FIND);
+		if (hp == NULL)
+		{
+		    buf->b_ml.ml_usedchunks = -1;
+		    return;
+		}
+		dp = (DATA_BL *)(hp->bh_data);
+		if (dp->db_line_count == 1)
+		    rest = dp->db_txt_end - dp->db_txt_start;
+		else
+		    rest =
+			((dp->db_index[dp->db_line_count - 2]) & DB_INDEX_MASK)
+			- dp->db_txt_start;
+		curchnk->mlcs_totalsize = rest;
+		curchnk->mlcs_numlines = 1;
+		curchnk[-1].mlcs_totalsize -= rest;
+		curchnk[-1].mlcs_numlines -= 1;
+	    }
+	}
+    }
+    else if (updtype == ML_CHNK_DELLINE)
+    {
+	curchnk->mlcs_numlines--;
+	ml_upd_lastbuf = NULL;   /* Force recalc of curix & curline */
+	if (curix < (buf->b_ml.ml_usedchunks - 1)
+		&& (curchnk->mlcs_numlines + curchnk[1].mlcs_numlines)
+		   <= MLCS_MINL)
+	{
+	    curix++;
+	    curchnk = buf->b_ml.ml_chunksize + curix;
+	}
+	else if (curix == 0 && curchnk->mlcs_numlines <= 0)
+	{
+	    buf->b_ml.ml_usedchunks--;
+	    mch_memmove(buf->b_ml.ml_chunksize, buf->b_ml.ml_chunksize + 1,
+			buf->b_ml.ml_usedchunks * sizeof(chunksize_T));
+	    return;
+	}
+	else if (curix == 0 || (curchnk->mlcs_numlines > 10
+		    && (curchnk->mlcs_numlines + curchnk[-1].mlcs_numlines)
+		       > MLCS_MINL))
+	{
+	    return;
+	}
+
+	/* Collapse chunks */
+	curchnk[-1].mlcs_numlines += curchnk->mlcs_numlines;
+	curchnk[-1].mlcs_totalsize += curchnk->mlcs_totalsize;
+	buf->b_ml.ml_usedchunks--;
+	if (curix < buf->b_ml.ml_usedchunks)
+	{
+	    mch_memmove(buf->b_ml.ml_chunksize + curix,
+			buf->b_ml.ml_chunksize + curix + 1,
+			(buf->b_ml.ml_usedchunks - curix) *
+			sizeof(chunksize_T));
+	}
+	return;
+    }
+    ml_upd_lastbuf = buf;
+    ml_upd_lastline = line;
+    ml_upd_lastcurline = curline;
+    ml_upd_lastcurix = curix;
+}
+
+/*
+ * Find offset for line or line with offset.
+ * Find line with offset if "lnum" is 0; return remaining offset in offp
+ * Find offset of line if "lnum" > 0
+ * return -1 if information is not available
+ */
+    long
+ml_find_line_or_offset(buf, lnum, offp)
+    buf_T	*buf;
+    linenr_T	lnum;
+    long	*offp;
+{
+    linenr_T	curline;
+    int		curix;
+    long	size;
+    bhdr_T	*hp;
+    DATA_BL	*dp;
+    int		count;		/* number of entries in block */
+    int		idx;
+    int		start_idx;
+    int		text_end;
+    long	offset;
+    int		len;
+    int		ffdos = (get_fileformat(buf) == EOL_DOS);
+    int		extra = 0;
+
+    /* take care of cached line first */
+    ml_flush_line(curbuf);
+
+    if (buf->b_ml.ml_usedchunks == -1
+	    || buf->b_ml.ml_chunksize == NULL
+	    || lnum < 0)
+	return -1;
+
+    if (offp == NULL)
+	offset = 0;
+    else
+	offset = *offp;
+    if (lnum == 0 && offset <= 0)
+	return 1;   /* Not a "find offset" and offset 0 _must_ be in line 1 */
+    /*
+     * Find the last chunk before the one containing our line. Last chunk is
+     * special because it will never qualify
+     */
+    curline = 1;
+    curix = size = 0;
+    while (curix < buf->b_ml.ml_usedchunks - 1
+	    && ((lnum != 0
+	     && lnum >= curline + buf->b_ml.ml_chunksize[curix].mlcs_numlines)
+		|| (offset != 0
+	       && offset > size + buf->b_ml.ml_chunksize[curix].mlcs_totalsize
+		      + ffdos * buf->b_ml.ml_chunksize[curix].mlcs_numlines)))
+    {
+	curline += buf->b_ml.ml_chunksize[curix].mlcs_numlines;
+	size += buf->b_ml.ml_chunksize[curix].mlcs_totalsize;
+	if (offset && ffdos)
+	    size += buf->b_ml.ml_chunksize[curix].mlcs_numlines;
+	curix++;
+    }
+
+    while ((lnum != 0 && curline < lnum) || (offset != 0 && size < offset))
+    {
+	if (curline > buf->b_ml.ml_line_count
+		|| (hp = ml_find_line(buf, curline, ML_FIND)) == NULL)
+	    return -1;
+	dp = (DATA_BL *)(hp->bh_data);
+	count = (long)(buf->b_ml.ml_locked_high) -
+		(long)(buf->b_ml.ml_locked_low) + 1;
+	start_idx = idx = curline - buf->b_ml.ml_locked_low;
+	if (idx == 0)/* first line in block, text at the end */
+	    text_end = dp->db_txt_end;
+	else
+	    text_end = ((dp->db_index[idx - 1]) & DB_INDEX_MASK);
+	/* Compute index of last line to use in this MEMLINE */
+	if (lnum != 0)
+	{
+	    if (curline + (count - idx) >= lnum)
+		idx += lnum - curline - 1;
+	    else
+		idx = count - 1;
+	}
+	else
+	{
+	    extra = 0;
+	    while (offset >= size
+		       + text_end - (int)((dp->db_index[idx]) & DB_INDEX_MASK)
+								      + ffdos)
+	    {
+		if (ffdos)
+		    size++;
+		if (idx == count - 1)
+		{
+		    extra = 1;
+		    break;
+		}
+		idx++;
+	    }
+	}
+	len = text_end - ((dp->db_index[idx]) & DB_INDEX_MASK);
+	size += len;
+	if (offset != 0 && size >= offset)
+	{
+	    if (size + ffdos == offset)
+		*offp = 0;
+	    else if (idx == start_idx)
+		*offp = offset - size + len;
+	    else
+		*offp = offset - size + len
+		     - (text_end - ((dp->db_index[idx - 1]) & DB_INDEX_MASK));
+	    curline += idx - start_idx + extra;
+	    if (curline > buf->b_ml.ml_line_count)
+		return -1;	/* exactly one byte beyond the end */
+	    return curline;
+	}
+	curline = buf->b_ml.ml_locked_high + 1;
+    }
+
+    if (lnum != 0)
+    {
+	/* Count extra CR characters. */
+	if (ffdos)
+	    size += lnum - 1;
+
+	/* Don't count the last line break if 'bin' and 'noeol'. */
+	if (buf->b_p_bin && !buf->b_p_eol)
+	    size -= ffdos + 1;
+    }
+
+    return size;
+}
+
+/*
+ * Goto byte in buffer with offset 'cnt'.
+ */
+    void
+goto_byte(cnt)
+    long	cnt;
+{
+    long	boff = cnt;
+    linenr_T	lnum;
+
+    ml_flush_line(curbuf);	/* cached line may be dirty */
+    setpcmark();
+    if (boff)
+	--boff;
+    lnum = ml_find_line_or_offset(curbuf, (linenr_T)0, &boff);
+    if (lnum < 1)	/* past the end */
+    {
+	curwin->w_cursor.lnum = curbuf->b_ml.ml_line_count;
+	curwin->w_curswant = MAXCOL;
+	coladvance((colnr_T)MAXCOL);
+    }
+    else
+    {
+	curwin->w_cursor.lnum = lnum;
+	curwin->w_cursor.col = (colnr_T)boff;
+# ifdef FEAT_VIRTUALEDIT
+	curwin->w_cursor.coladd = 0;
+# endif
+	curwin->w_set_curswant = TRUE;
+    }
+    check_cursor();
+
+# ifdef FEAT_MBYTE
+    /* Make sure the cursor is on the first byte of a multi-byte char. */
+    if (has_mbyte)
+	mb_adjust_cursor();
+# endif
+}
+#endif
--- /dev/null
+++ b/menu.c
@@ -1,0 +1,2473 @@
+/* vi:set ts=8 sts=4 sw=4:
+ *
+ * VIM - Vi IMproved		by Bram Moolenaar
+ *				GUI/Motif support by Robert Webb
+ *
+ * Do ":help uganda"  in Vim to read copying and usage conditions.
+ * Do ":help credits" in Vim to see a list of people who contributed.
+ * See README.txt for an overview of the Vim source code.
+ */
+
+/*
+ * Code for menus.  Used for the GUI and 'wildmenu'.
+ */
+
+#include "vim.h"
+
+#if defined(FEAT_MENU) || defined(PROTO)
+
+#define MENUDEPTH   10		/* maximum depth of menus */
+
+#ifdef FEAT_GUI_W32
+static int add_menu_path __ARGS((char_u *, vimmenu_T *, int *, char_u *, int));
+#else
+static int add_menu_path __ARGS((char_u *, vimmenu_T *, int *, char_u *));
+#endif
+static int menu_nable_recurse __ARGS((vimmenu_T *menu, char_u *name, int modes, int enable));
+static int remove_menu __ARGS((vimmenu_T **, char_u *, int, int silent));
+static void free_menu __ARGS((vimmenu_T **menup));
+static void free_menu_string __ARGS((vimmenu_T *, int));
+static int show_menus __ARGS((char_u *, int));
+static void show_menus_recursive __ARGS((vimmenu_T *, int, int));
+static int menu_name_equal __ARGS((char_u *name, vimmenu_T *menu));
+static int menu_namecmp __ARGS((char_u *name, char_u *mname));
+static int get_menu_cmd_modes __ARGS((char_u *, int, int *, int *));
+static char_u *popup_mode_name __ARGS((char_u *name, int idx));
+static char_u *menu_text __ARGS((char_u *text, int *mnemonic, char_u **actext));
+#ifdef FEAT_GUI
+static int get_menu_mode __ARGS((void));
+static void gui_update_menus_recurse __ARGS((vimmenu_T *, int));
+#endif
+
+#if defined(FEAT_GUI_W32) && defined(FEAT_TEAROFF)
+static void gui_create_tearoffs_recurse __ARGS((vimmenu_T *menu, const char_u *pname, int *pri_tab, int pri_idx));
+static void gui_add_tearoff __ARGS((char_u *tearpath, int *pri_tab, int pri_idx));
+static void gui_destroy_tearoffs_recurse __ARGS((vimmenu_T *menu));
+static int s_tearoffs = FALSE;
+#endif
+
+static int menu_is_hidden __ARGS((char_u *name));
+#if defined(FEAT_CMDL_COMPL) || (defined(FEAT_GUI_W32) && defined(FEAT_TEAROFF))
+static int menu_is_tearoff __ARGS((char_u *name));
+#endif
+
+#if defined(FEAT_MULTI_LANG) || defined(FEAT_TOOLBAR)
+static char_u *menu_skip_part __ARGS((char_u *p));
+#endif
+#ifdef FEAT_MULTI_LANG
+static char_u *menutrans_lookup __ARGS((char_u *name, int len));
+#endif
+
+/* The character for each menu mode */
+static char_u	menu_mode_chars[] = {'n', 'v', 's', 'o', 'i', 'c', 't'};
+
+static char_u e_notsubmenu[] = N_("E327: Part of menu-item path is not sub-menu");
+static char_u e_othermode[] = N_("E328: Menu only exists in another mode");
+static char_u e_nomenu[] = N_("E329: No menu \"%s\"");
+
+#ifdef FEAT_TOOLBAR
+static const char *toolbar_names[] =
+{
+    /*  0 */ "New", "Open", "Save", "Undo", "Redo",
+    /*  5 */ "Cut", "Copy", "Paste", "Print", "Help",
+    /* 10 */ "Find", "SaveAll", "SaveSesn", "NewSesn", "LoadSesn",
+    /* 15 */ "RunScript", "Replace", "WinClose", "WinMax", "WinMin",
+    /* 20 */ "WinSplit", "Shell", "FindPrev", "FindNext", "FindHelp",
+    /* 25 */ "Make", "TagJump", "RunCtags", "WinVSplit", "WinMaxWidth",
+    /* 30 */ "WinMinWidth", "Exit"
+};
+# define TOOLBAR_NAME_COUNT (sizeof(toolbar_names) / sizeof(char *))
+#endif
+
+/*
+ * Do the :menu command and relatives.
+ */
+    void
+ex_menu(eap)
+    exarg_T	*eap;		    /* Ex command arguments */
+{
+    char_u	*menu_path;
+    int		modes;
+    char_u	*map_to;
+    int		noremap;
+    int		silent = FALSE;
+    int		special = FALSE;
+    int		unmenu;
+    char_u	*map_buf;
+    char_u	*arg;
+    char_u	*p;
+    int		i;
+#if defined(FEAT_GUI) && !defined(FEAT_GUI_GTK)
+    int		old_menu_height;
+# if defined(FEAT_TOOLBAR) && !defined(FEAT_GUI_W32) && !defined(FEAT_GUI_W16)
+    int		old_toolbar_height;
+# endif
+#endif
+    int		pri_tab[MENUDEPTH + 1];
+    int		enable = MAYBE;	    /* TRUE for "menu enable", FALSE for "menu
+				     * disable */
+#ifdef FEAT_MULTI_LANG
+    char_u	*tofree = NULL;
+    char_u	*new_cmd;
+#endif
+#ifdef FEAT_TOOLBAR
+    char_u	*icon = NULL;
+#endif
+    vimmenu_T	menuarg;
+
+    modes = get_menu_cmd_modes(eap->cmd, eap->forceit, &noremap, &unmenu);
+    arg = eap->arg;
+
+    for (;;)
+    {
+	if (STRNCMP(arg, "<script>", 8) == 0)
+	{
+	    noremap = REMAP_SCRIPT;
+	    arg = skipwhite(arg + 8);
+	    continue;
+	}
+	if (STRNCMP(arg, "<silent>", 8) == 0)
+	{
+	    silent = TRUE;
+	    arg = skipwhite(arg + 8);
+	    continue;
+	}
+	if (STRNCMP(arg, "<special>", 9) == 0)
+	{
+	    special = TRUE;
+	    arg = skipwhite(arg + 9);
+	    continue;
+	}
+	break;
+    }
+
+
+    /* Locate an optional "icon=filename" argument. */
+    if (STRNCMP(arg, "icon=", 5) == 0)
+    {
+	arg += 5;
+#ifdef FEAT_TOOLBAR
+	icon = arg;
+#endif
+	while (*arg != NUL && *arg != ' ')
+	{
+	    if (*arg == '\\')
+		mch_memmove(arg, arg + 1, STRLEN(arg));
+	    mb_ptr_adv(arg);
+	}
+	if (*arg != NUL)
+	{
+	    *arg++ = NUL;
+	    arg = skipwhite(arg);
+	}
+    }
+
+    /*
+     * Fill in the priority table.
+     */
+    for (p = arg; *p; ++p)
+	if (!VIM_ISDIGIT(*p) && *p != '.')
+	    break;
+    if (vim_iswhite(*p))
+    {
+	for (i = 0; i < MENUDEPTH && !vim_iswhite(*arg); ++i)
+	{
+	    pri_tab[i] = getdigits(&arg);
+	    if (pri_tab[i] == 0)
+		pri_tab[i] = 500;
+	    if (*arg == '.')
+		++arg;
+	}
+	arg = skipwhite(arg);
+    }
+    else if (eap->addr_count && eap->line2 != 0)
+    {
+	pri_tab[0] = eap->line2;
+	i = 1;
+    }
+    else
+	i = 0;
+    while (i < MENUDEPTH)
+	pri_tab[i++] = 500;
+    pri_tab[MENUDEPTH] = -1;		/* mark end of the table */
+
+    /*
+     * Check for "disable" or "enable" argument.
+     */
+    if (STRNCMP(arg, "enable", 6) == 0 && vim_iswhite(arg[6]))
+    {
+	enable = TRUE;
+	arg = skipwhite(arg + 6);
+    }
+    else if (STRNCMP(arg, "disable", 7) == 0 && vim_iswhite(arg[7]))
+    {
+	enable = FALSE;
+	arg = skipwhite(arg + 7);
+    }
+
+    /*
+     * If there is no argument, display all menus.
+     */
+    if (*arg == NUL)
+    {
+	show_menus(arg, modes);
+	return;
+    }
+
+#ifdef FEAT_TOOLBAR
+    /*
+     * Need to get the toolbar icon index before doing the translation.
+     */
+    menuarg.iconidx = -1;
+    menuarg.icon_builtin = FALSE;
+    if (menu_is_toolbar(arg))
+    {
+	menu_path = menu_skip_part(arg);
+	if (*menu_path == '.')
+	{
+	    p = menu_skip_part(++menu_path);
+	    if (STRNCMP(menu_path, "BuiltIn", 7) == 0)
+	    {
+		if (skipdigits(menu_path + 7) == p)
+		{
+		    menuarg.iconidx = atoi((char *)menu_path + 7);
+		    if (menuarg.iconidx >= TOOLBAR_NAME_COUNT)
+			menuarg.iconidx = -1;
+		    else
+			menuarg.icon_builtin = TRUE;
+		}
+	    }
+	    else
+	    {
+		for (i = 0; i < TOOLBAR_NAME_COUNT; ++i)
+		    if (STRNCMP(toolbar_names[i], menu_path, p - menu_path)
+									 == 0)
+		    {
+			menuarg.iconidx = i;
+			break;
+		    }
+	    }
+	}
+    }
+#endif
+
+#ifdef FEAT_MULTI_LANG
+    /*
+     * Translate menu names as specified with ":menutrans" commands.
+     */
+    menu_path = arg;
+    while (*menu_path)
+    {
+	/* find the end of one part and check if it should be translated */
+	p = menu_skip_part(menu_path);
+	map_to = menutrans_lookup(menu_path, (int)(p - menu_path));
+	if (map_to != NULL)
+	{
+	    /* found a match: replace with the translated part */
+	    i = (int)STRLEN(map_to);
+	    new_cmd = alloc((unsigned)STRLEN(arg) + i + 1);
+	    if (new_cmd == NULL)
+		break;
+	    mch_memmove(new_cmd, arg, menu_path - arg);
+	    mch_memmove(new_cmd + (menu_path - arg), map_to, (size_t)i);
+	    STRCPY(new_cmd + (menu_path - arg) + i, p);
+	    p = new_cmd + (menu_path - arg) + i;
+	    vim_free(tofree);
+	    tofree = new_cmd;
+	    arg = new_cmd;
+	}
+	if (*p != '.')
+	    break;
+	menu_path = p + 1;
+    }
+#endif
+
+    /*
+     * Isolate the menu name.
+     * Skip the menu name, and translate <Tab> into a real TAB.
+     */
+    menu_path = arg;
+    if (*menu_path == '.')
+    {
+	EMSG2(_(e_invarg2), menu_path);
+	goto theend;
+    }
+
+    while (*arg && !vim_iswhite(*arg))
+    {
+	if ((*arg == '\\' || *arg == Ctrl_V) && arg[1] != NUL)
+	    arg++;
+	else if (STRNICMP(arg, "<TAB>", 5) == 0)
+	{
+	    *arg = TAB;
+	    mch_memmove(arg + 1, arg + 5, STRLEN(arg + 4));
+	}
+	arg++;
+    }
+    if (*arg != NUL)
+	*arg++ = NUL;
+    arg = skipwhite(arg);
+    map_to = arg;
+
+    /*
+     * If there is only a menu name, display menus with that name.
+     */
+    if (*map_to == NUL && !unmenu && enable == MAYBE)
+    {
+	show_menus(menu_path, modes);
+	goto theend;
+    }
+    else if (*map_to != NUL && (unmenu || enable != MAYBE))
+    {
+	EMSG(_(e_trailing));
+	goto theend;
+    }
+#if defined(FEAT_GUI) && !(defined(FEAT_GUI_GTK) || defined(FEAT_GUI_PHOTON))
+    old_menu_height = gui.menu_height;
+# if defined(FEAT_TOOLBAR) && !defined(FEAT_GUI_W32) && !defined(FEAT_GUI_W16)
+    old_toolbar_height = gui.toolbar_height;
+# endif
+#endif
+
+    if (enable != MAYBE)
+    {
+	/*
+	 * Change sensitivity of the menu.
+	 * For the PopUp menu, remove a menu for each mode separately.
+	 * Careful: menu_nable_recurse() changes menu_path.
+	 */
+	if (STRCMP(menu_path, "*") == 0)	/* meaning: do all menus */
+	    menu_path = (char_u *)"";
+
+	if (menu_is_popup(menu_path))
+	{
+	    for (i = 0; i < MENU_INDEX_TIP; ++i)
+		if (modes & (1 << i))
+		{
+		    p = popup_mode_name(menu_path, i);
+		    if (p != NULL)
+		    {
+			menu_nable_recurse(root_menu, p, MENU_ALL_MODES,
+								      enable);
+			vim_free(p);
+		    }
+		}
+	}
+	menu_nable_recurse(root_menu, menu_path, modes, enable);
+    }
+    else if (unmenu)
+    {
+	/*
+	 * Delete menu(s).
+	 */
+	if (STRCMP(menu_path, "*") == 0)	/* meaning: remove all menus */
+	    menu_path = (char_u *)"";
+
+	/*
+	 * For the PopUp menu, remove a menu for each mode separately.
+	 */
+	if (menu_is_popup(menu_path))
+	{
+	    for (i = 0; i < MENU_INDEX_TIP; ++i)
+		if (modes & (1 << i))
+		{
+		    p = popup_mode_name(menu_path, i);
+		    if (p != NULL)
+		    {
+			remove_menu(&root_menu, p, MENU_ALL_MODES, TRUE);
+			vim_free(p);
+		    }
+		}
+	}
+
+	/* Careful: remove_menu() changes menu_path */
+	remove_menu(&root_menu, menu_path, modes, FALSE);
+    }
+    else
+    {
+	/*
+	 * Add menu(s).
+	 * Replace special key codes.
+	 */
+	if (STRICMP(map_to, "<nop>") == 0)	/* "<Nop>" means nothing */
+	{
+	    map_to = (char_u *)"";
+	    map_buf = NULL;
+	}
+	else if (modes & MENU_TIP_MODE)
+	    map_buf = NULL;	/* Menu tips are plain text. */
+	else
+	    map_to = replace_termcodes(map_to, &map_buf, FALSE, TRUE, special);
+	menuarg.modes = modes;
+#ifdef FEAT_TOOLBAR
+	menuarg.iconfile = icon;
+#endif
+	menuarg.noremap[0] = noremap;
+	menuarg.silent[0] = silent;
+	add_menu_path(menu_path, &menuarg, pri_tab, map_to
+#ifdef FEAT_GUI_W32
+		, TRUE
+#endif
+		);
+
+	/*
+	 * For the PopUp menu, add a menu for each mode separately.
+	 */
+	if (menu_is_popup(menu_path))
+	{
+	    for (i = 0; i < MENU_INDEX_TIP; ++i)
+		if (modes & (1 << i))
+		{
+		    p = popup_mode_name(menu_path, i);
+		    if (p != NULL)
+		    {
+			/* Include all modes, to make ":amenu" work */
+			menuarg.modes = modes;
+#ifdef FEAT_TOOLBAR
+			menuarg.iconfile = NULL;
+			menuarg.iconidx = -1;
+			menuarg.icon_builtin = FALSE;
+#endif
+			add_menu_path(p, &menuarg, pri_tab, map_to
+#ifdef FEAT_GUI_W32
+				, TRUE
+#endif
+					 );
+			vim_free(p);
+		    }
+		}
+	}
+
+	vim_free(map_buf);
+    }
+
+#if defined(FEAT_GUI) && !(defined(FEAT_GUI_GTK))
+    /* If the menubar height changed, resize the window */
+    if (gui.in_use
+	    && (gui.menu_height != old_menu_height
+# if defined(FEAT_TOOLBAR) && !defined(FEAT_GUI_W32) && !defined(FEAT_GUI_W16)
+		|| gui.toolbar_height != old_toolbar_height
+# endif
+	    ))
+	gui_set_shellsize(FALSE, FALSE, RESIZE_VERT);
+#endif
+
+theend:
+#ifdef FEAT_MULTI_LANG
+    vim_free(tofree);
+#else
+    ;
+#endif
+}
+
+/*
+ * Add the menu with the given name to the menu hierarchy
+ */
+    static int
+add_menu_path(menu_path, menuarg, pri_tab, call_data
+#ifdef FEAT_GUI_W32
+	, addtearoff
+#endif
+	)
+    char_u	*menu_path;
+    vimmenu_T	*menuarg;	/* passes modes, iconfile, iconidx,
+				   icon_builtin, silent[0], noremap[0] */
+    int		*pri_tab;
+    char_u	*call_data;
+#ifdef FEAT_GUI_W32
+    int		addtearoff;	/* may add tearoff item */
+#endif
+{
+    char_u	*path_name;
+    int		modes = menuarg->modes;
+    vimmenu_T	**menup;
+    vimmenu_T	*menu = NULL;
+    vimmenu_T	*parent;
+    vimmenu_T	**lower_pri;
+    char_u	*p;
+    char_u	*name;
+    char_u	*dname;
+    char_u	*next_name;
+    int		i;
+    int		c;
+#ifdef FEAT_GUI
+    int		idx;
+    int		new_idx;
+#endif
+    int		pri_idx = 0;
+    int		old_modes = 0;
+    int		amenu;
+
+    /* Make a copy so we can stuff around with it, since it could be const */
+    path_name = vim_strsave(menu_path);
+    if (path_name == NULL)
+	return FAIL;
+    menup = &root_menu;
+    parent = NULL;
+    name = path_name;
+    while (*name)
+    {
+	/* Get name of this element in the menu hierarchy, and the simplified
+	 * name (without mnemonic and accelerator text). */
+	next_name = menu_name_skip(name);
+	dname = menu_text(name, NULL, NULL);
+	if (dname == NULL)
+	    goto erret;
+	if (*dname == NUL)
+	{
+	    /* Only a mnemonic or accelerator is not valid. */
+	    EMSG(_("E792: Empty menu name"));
+	    goto erret;
+	}
+
+	/* See if it's already there */
+	lower_pri = menup;
+#ifdef FEAT_GUI
+	idx = 0;
+	new_idx = 0;
+#endif
+	menu = *menup;
+	while (menu != NULL)
+	{
+	    if (menu_name_equal(name, menu) || menu_name_equal(dname, menu))
+	    {
+		if (*next_name == NUL && menu->children != NULL)
+		{
+		    if (!sys_menu)
+			EMSG(_("E330: Menu path must not lead to a sub-menu"));
+		    goto erret;
+		}
+		if (*next_name != NUL && menu->children == NULL
+#ifdef FEAT_GUI_W32
+			&& addtearoff
+#endif
+			)
+		{
+		    if (!sys_menu)
+			EMSG(_(e_notsubmenu));
+		    goto erret;
+		}
+		break;
+	    }
+	    menup = &menu->next;
+
+	    /* Count menus, to find where this one needs to be inserted.
+	     * Ignore menus that are not in the menubar (PopUp and Toolbar) */
+	    if (parent != NULL || menu_is_menubar(menu->name))
+	    {
+#ifdef FEAT_GUI
+		++idx;
+#endif
+		if (menu->priority <= pri_tab[pri_idx])
+		{
+		    lower_pri = menup;
+#ifdef FEAT_GUI
+		    new_idx = idx;
+#endif
+		}
+	    }
+	    menu = menu->next;
+	}
+
+	if (menu == NULL)
+	{
+	    if (*next_name == NUL && parent == NULL)
+	    {
+		EMSG(_("E331: Must not add menu items directly to menu bar"));
+		goto erret;
+	    }
+
+	    if (menu_is_separator(dname) && *next_name != NUL)
+	    {
+		EMSG(_("E332: Separator cannot be part of a menu path"));
+		goto erret;
+	    }
+
+	    /* Not already there, so lets add it */
+	    menu = (vimmenu_T *)alloc_clear((unsigned)sizeof(vimmenu_T));
+	    if (menu == NULL)
+		goto erret;
+
+	    menu->modes = modes;
+	    menu->enabled = MENU_ALL_MODES;
+	    menu->name = vim_strsave(name);
+	    /* separate mnemonic and accelerator text from actual menu name */
+	    menu->dname = menu_text(name, &menu->mnemonic, &menu->actext);
+	    menu->priority = pri_tab[pri_idx];
+	    menu->parent = parent;
+#ifdef FEAT_GUI_MOTIF
+	    menu->sensitive = TRUE;	    /* the default */
+#endif
+#ifdef FEAT_BEVAL_TIP
+	    menu->tip = NULL;
+#endif
+#ifdef FEAT_GUI_ATHENA
+	    menu->image = None;		    /* X-Windows definition for NULL*/
+#endif
+
+	    /*
+	     * Add after menu that has lower priority.
+	     */
+	    menu->next = *lower_pri;
+	    *lower_pri = menu;
+
+	    old_modes = 0;
+
+#ifdef FEAT_TOOLBAR
+	    menu->iconidx = menuarg->iconidx;
+	    menu->icon_builtin = menuarg->icon_builtin;
+	    if (*next_name == NUL && menuarg->iconfile != NULL)
+		menu->iconfile = vim_strsave(menuarg->iconfile);
+#endif
+#if defined(FEAT_GUI_W32) && defined(FEAT_TEAROFF)
+	    /* the tearoff item must be present in the modes of each item. */
+	    if (parent != NULL && menu_is_tearoff(parent->children->dname))
+		parent->children->modes |= modes;
+#endif
+	}
+	else
+	{
+	    old_modes = menu->modes;
+
+	    /*
+	     * If this menu option was previously only available in other
+	     * modes, then make sure it's available for this one now
+	     * Also enable a menu when it's created or changed.
+	     */
+#ifdef FEAT_GUI_W32
+	    /* If adding a tearbar (addtearoff == FALSE) don't update modes */
+	    if (addtearoff)
+#endif
+	    {
+		menu->modes |= modes;
+		menu->enabled |= modes;
+	    }
+	}
+
+#ifdef FEAT_GUI
+	/*
+	 * Add the menu item when it's used in one of the modes, but not when
+	 * only a tooltip is defined.
+	 */
+	if ((old_modes & MENU_ALL_MODES) == 0
+		&& (menu->modes & MENU_ALL_MODES) != 0)
+	{
+	    if (gui.in_use)  /* Otherwise it will be added when GUI starts */
+	    {
+		if (*next_name == NUL)
+		{
+		    /* Real menu item, not sub-menu */
+		    gui_mch_add_menu_item(menu, new_idx);
+
+		    /* Want to update menus now even if mode not changed */
+		    force_menu_update = TRUE;
+		}
+		else
+		{
+		    /* Sub-menu (not at end of path yet) */
+		    gui_mch_add_menu(menu, new_idx);
+		}
+	    }
+
+# if defined(FEAT_GUI_W32) & defined(FEAT_TEAROFF)
+	    /* When adding a new submenu, may add a tearoff item */
+	    if (	addtearoff
+		    && *next_name
+		    && vim_strchr(p_go, GO_TEAROFF) != NULL
+		    && menu_is_menubar(name))
+	    {
+		char_u		*tearpath;
+
+		/*
+		 * The pointers next_name & path_name refer to a string with
+		 * \'s and ^V's stripped out. But menu_path is a "raw"
+		 * string, so we must correct for special characters.
+		 */
+		tearpath = alloc((unsigned int)STRLEN(menu_path) + TEAR_LEN + 2);
+		if (tearpath != NULL)
+		{
+		    char_u  *s;
+		    int	    idx;
+
+		    STRCPY(tearpath, menu_path);
+		    idx = (int)(next_name - path_name - 1);
+		    for (s = tearpath; *s && s < tearpath + idx; mb_ptr_adv(s))
+		    {
+			if ((*s == '\\' || *s == Ctrl_V) && s[1])
+			{
+			    ++idx;
+			    ++s;
+			}
+		    }
+		    tearpath[idx] = NUL;
+		    gui_add_tearoff(tearpath, pri_tab, pri_idx);
+		    vim_free(tearpath);
+		}
+	    }
+# endif
+	}
+#endif /* FEAT_GUI */
+
+	menup = &menu->children;
+	parent = menu;
+	name = next_name;
+	vim_free(dname);
+	dname = NULL;
+	if (pri_tab[pri_idx + 1] != -1)
+	    ++pri_idx;
+    }
+    vim_free(path_name);
+
+    /*
+     * Only add system menu items which have not been defined yet.
+     * First check if this was an ":amenu".
+     */
+    amenu = ((modes & (MENU_NORMAL_MODE | MENU_INSERT_MODE)) ==
+				       (MENU_NORMAL_MODE | MENU_INSERT_MODE));
+    if (sys_menu)
+	modes &= ~old_modes;
+
+    if (menu != NULL && modes)
+    {
+#ifdef FEAT_GUI
+	menu->cb = gui_menu_cb;
+#endif
+	p = (call_data == NULL) ? NULL : vim_strsave(call_data);
+
+	/* loop over all modes, may add more than one */
+	for (i = 0; i < MENU_MODES; ++i)
+	{
+	    if (modes & (1 << i))
+	    {
+		/* free any old menu */
+		free_menu_string(menu, i);
+
+		/* For "amenu", may insert an extra character.
+		 * Don't do this if adding a tearbar (addtearoff == FALSE).
+		 * Don't do this for "<Nop>". */
+		c = 0;
+		if (amenu && call_data != NULL && *call_data != NUL
+#ifdef FEAT_GUI_W32
+		       && addtearoff
+#endif
+				       )
+		{
+		    switch (1 << i)
+		    {
+			case MENU_VISUAL_MODE:
+			case MENU_SELECT_MODE:
+			case MENU_OP_PENDING_MODE:
+			case MENU_CMDLINE_MODE:
+			    c = Ctrl_C;
+			    break;
+			case MENU_INSERT_MODE:
+			    c = Ctrl_O;
+			    break;
+		    }
+		}
+
+		if (c)
+		{
+		    menu->strings[i] = alloc((unsigned)(STRLEN(call_data) + 4));
+		    if (menu->strings[i] != NULL)
+		    {
+			menu->strings[i][0] = c;
+			STRCPY(menu->strings[i] + 1, call_data);
+			if (c == Ctrl_C)
+			{
+			    int	    len = (int)STRLEN(menu->strings[i]);
+
+			    /* Append CTRL-\ CTRL-G to obey 'insertmode'. */
+			    menu->strings[i][len] = Ctrl_BSL;
+			    menu->strings[i][len + 1] = Ctrl_G;
+			    menu->strings[i][len + 2] = NUL;
+			}
+		    }
+		}
+		else
+		    menu->strings[i] = p;
+		menu->noremap[i] = menuarg->noremap[0];
+		menu->silent[i] = menuarg->silent[0];
+	    }
+	}
+#if defined(FEAT_TOOLBAR) && !defined(FEAT_GUI_W32) \
+	&& (defined(FEAT_BEVAL) || defined(FEAT_GUI_GTK))
+	/* Need to update the menu tip. */
+	if (modes & MENU_TIP_MODE)
+	    gui_mch_menu_set_tip(menu);
+#endif
+    }
+    return OK;
+
+erret:
+    vim_free(path_name);
+    vim_free(dname);
+
+    /* Delete any empty submenu we added before discovering the error.  Repeat
+     * for higher levels. */
+    while (parent != NULL && parent->children == NULL)
+    {
+	if (parent->parent == NULL)
+	    menup = &root_menu;
+	else
+	    menup = &parent->parent->children;
+	for ( ; *menup != NULL && *menup != parent; menup = &((*menup)->next))
+	    ;
+	if (*menup == NULL) /* safety check */
+	    break;
+	parent = parent->parent;
+	free_menu(menup);
+    }
+    return FAIL;
+}
+
+/*
+ * Set the (sub)menu with the given name to enabled or disabled.
+ * Called recursively.
+ */
+    static int
+menu_nable_recurse(menu, name, modes, enable)
+    vimmenu_T	*menu;
+    char_u	*name;
+    int		modes;
+    int		enable;
+{
+    char_u	*p;
+
+    if (menu == NULL)
+	return OK;		/* Got to bottom of hierarchy */
+
+    /* Get name of this element in the menu hierarchy */
+    p = menu_name_skip(name);
+
+    /* Find the menu */
+    while (menu != NULL)
+    {
+	if (*name == NUL || *name == '*' || menu_name_equal(name, menu))
+	{
+	    if (*p != NUL)
+	    {
+		if (menu->children == NULL)
+		{
+		    EMSG(_(e_notsubmenu));
+		    return FAIL;
+		}
+		if (menu_nable_recurse(menu->children, p, modes, enable)
+								      == FAIL)
+		    return FAIL;
+	    }
+	    else
+		if (enable)
+		    menu->enabled |= modes;
+		else
+		    menu->enabled &= ~modes;
+
+	    /*
+	     * When name is empty, we are doing all menu items for the given
+	     * modes, so keep looping, otherwise we are just doing the named
+	     * menu item (which has been found) so break here.
+	     */
+	    if (*name != NUL && *name != '*')
+		break;
+	}
+	menu = menu->next;
+    }
+    if (*name != NUL && *name != '*' && menu == NULL)
+    {
+	EMSG2(_(e_nomenu), name);
+	return FAIL;
+    }
+
+#ifdef FEAT_GUI
+    /* Want to update menus now even if mode not changed */
+    force_menu_update = TRUE;
+#endif
+
+    return OK;
+}
+
+/*
+ * Remove the (sub)menu with the given name from the menu hierarchy
+ * Called recursively.
+ */
+    static int
+remove_menu(menup, name, modes, silent)
+    vimmenu_T	**menup;
+    char_u	*name;
+    int		modes;
+    int		silent;		/* don't give error messages */
+{
+    vimmenu_T	*menu;
+    vimmenu_T	*child;
+    char_u	*p;
+
+    if (*menup == NULL)
+	return OK;		/* Got to bottom of hierarchy */
+
+    /* Get name of this element in the menu hierarchy */
+    p = menu_name_skip(name);
+
+    /* Find the menu */
+    while ((menu = *menup) != NULL)
+    {
+	if (*name == NUL || menu_name_equal(name, menu))
+	{
+	    if (*p != NUL && menu->children == NULL)
+	    {
+		if (!silent)
+		    EMSG(_(e_notsubmenu));
+		return FAIL;
+	    }
+	    if ((menu->modes & modes) != 0x0)
+	    {
+#if defined(FEAT_GUI_W32) & defined(FEAT_TEAROFF)
+		/*
+		 * If we are removing all entries for this menu,MENU_ALL_MODES,
+		 * Then kill any tearoff before we start
+		 */
+		if (*p == NUL && modes == MENU_ALL_MODES)
+		{
+		    if (IsWindow(menu->tearoff_handle))
+			DestroyWindow(menu->tearoff_handle);
+		}
+#endif
+		if (remove_menu(&menu->children, p, modes, silent) == FAIL)
+		    return FAIL;
+	    }
+	    else if (*name != NUL)
+	    {
+		if (!silent)
+		    EMSG(_(e_othermode));
+		return FAIL;
+	    }
+
+	    /*
+	     * When name is empty, we are removing all menu items for the given
+	     * modes, so keep looping, otherwise we are just removing the named
+	     * menu item (which has been found) so break here.
+	     */
+	    if (*name != NUL)
+		break;
+
+	    /* Remove the menu item for the given mode[s].  If the menu item
+	     * is no longer valid in ANY mode, delete it */
+	    menu->modes &= ~modes;
+	    if (modes & MENU_TIP_MODE)
+		free_menu_string(menu, MENU_INDEX_TIP);
+	    if ((menu->modes & MENU_ALL_MODES) == 0)
+		free_menu(menup);
+	    else
+		menup = &menu->next;
+	}
+	else
+	    menup = &menu->next;
+    }
+    if (*name != NUL)
+    {
+	if (menu == NULL)
+	{
+	    if (!silent)
+		EMSG2(_(e_nomenu), name);
+	    return FAIL;
+	}
+
+
+	/* Recalculate modes for menu based on the new updated children */
+	menu->modes &= ~modes;
+#if defined(FEAT_GUI_W32) & defined(FEAT_TEAROFF)
+	if ((s_tearoffs) && (menu->children != NULL)) /* there's a tear bar.. */
+	    child = menu->children->next; /* don't count tearoff bar */
+	else
+#endif
+	    child = menu->children;
+	for ( ; child != NULL; child = child->next)
+	    menu->modes |= child->modes;
+	if (modes & MENU_TIP_MODE)
+	{
+	    free_menu_string(menu, MENU_INDEX_TIP);
+#if defined(FEAT_TOOLBAR) && !defined(FEAT_GUI_W32) \
+	    && (defined(FEAT_BEVAL) || defined(FEAT_GUI_GTK))
+	    /* Need to update the menu tip. */
+	    if (gui.in_use)
+		gui_mch_menu_set_tip(menu);
+#endif
+	}
+	if ((menu->modes & MENU_ALL_MODES) == 0)
+	{
+	    /* The menu item is no longer valid in ANY mode, so delete it */
+#if defined(FEAT_GUI_W32) & defined(FEAT_TEAROFF)
+	    if (s_tearoffs && menu->children != NULL) /* there's a tear bar.. */
+		free_menu(&menu->children);
+#endif
+	    *menup = menu;
+	    free_menu(menup);
+	}
+    }
+
+    return OK;
+}
+
+/*
+ * Free the given menu structure and remove it from the linked list.
+ */
+    static void
+free_menu(menup)
+    vimmenu_T	**menup;
+{
+    int		i;
+    vimmenu_T	*menu;
+
+    menu = *menup;
+
+#ifdef FEAT_GUI
+    /* Free machine specific menu structures (only when already created) */
+    /* Also may rebuild a tearoff'ed menu */
+    if (gui.in_use)
+	gui_mch_destroy_menu(menu);
+#endif
+
+    /* Don't change *menup until after calling gui_mch_destroy_menu(). The
+     * MacOS code needs the original structure to properly delete the menu. */
+    *menup = menu->next;
+    vim_free(menu->name);
+    vim_free(menu->dname);
+    vim_free(menu->actext);
+#ifdef FEAT_TOOLBAR
+    vim_free(menu->iconfile);
+# ifdef FEAT_GUI_MOTIF
+    vim_free(menu->xpm_fname);
+# endif
+#endif
+    for (i = 0; i < MENU_MODES; i++)
+	free_menu_string(menu, i);
+    vim_free(menu);
+
+#ifdef FEAT_GUI
+    /* Want to update menus now even if mode not changed */
+    force_menu_update = TRUE;
+#endif
+}
+
+/*
+ * Free the menu->string with the given index.
+ */
+    static void
+free_menu_string(menu, idx)
+    vimmenu_T	*menu;
+    int		idx;
+{
+    int		count = 0;
+    int		i;
+
+    for (i = 0; i < MENU_MODES; i++)
+	if (menu->strings[i] == menu->strings[idx])
+	    count++;
+    if (count == 1)
+	vim_free(menu->strings[idx]);
+    menu->strings[idx] = NULL;
+}
+
+/*
+ * Show the mapping associated with a menu item or hierarchy in a sub-menu.
+ */
+    static int
+show_menus(path_name, modes)
+    char_u  *path_name;
+    int	    modes;
+{
+    char_u	*p;
+    char_u	*name;
+    vimmenu_T	*menu;
+    vimmenu_T	*parent = NULL;
+
+    menu = root_menu;
+    name = path_name = vim_strsave(path_name);
+    if (path_name == NULL)
+	return FAIL;
+
+    /* First, find the (sub)menu with the given name */
+    while (*name)
+    {
+	p = menu_name_skip(name);
+	while (menu != NULL)
+	{
+	    if (menu_name_equal(name, menu))
+	    {
+		/* Found menu */
+		if (*p != NUL && menu->children == NULL)
+		{
+		    EMSG(_(e_notsubmenu));
+		    vim_free(path_name);
+		    return FAIL;
+		}
+		else if ((menu->modes & modes) == 0x0)
+		{
+		    EMSG(_(e_othermode));
+		    vim_free(path_name);
+		    return FAIL;
+		}
+		break;
+	    }
+	    menu = menu->next;
+	}
+	if (menu == NULL)
+	{
+	    EMSG2(_(e_nomenu), name);
+	    vim_free(path_name);
+	    return FAIL;
+	}
+	name = p;
+	parent = menu;
+	menu = menu->children;
+    }
+
+    /* Now we have found the matching menu, and we list the mappings */
+						    /* Highlight title */
+    MSG_PUTS_TITLE(_("\n--- Menus ---"));
+
+    show_menus_recursive(parent, modes, 0);
+    return OK;
+}
+
+/*
+ * Recursively show the mappings associated with the menus under the given one
+ */
+    static void
+show_menus_recursive(menu, modes, depth)
+    vimmenu_T	*menu;
+    int		modes;
+    int		depth;
+{
+    int		i;
+    int		bit;
+
+    if (menu != NULL && (menu->modes & modes) == 0x0)
+	return;
+
+    if (menu != NULL)
+    {
+	msg_putchar('\n');
+	if (got_int)		/* "q" hit for "--more--" */
+	    return;
+	for (i = 0; i < depth; i++)
+	    MSG_PUTS("  ");
+	if (menu->priority)
+	{
+	    msg_outnum((long)menu->priority);
+	    MSG_PUTS(" ");
+	}
+				/* Same highlighting as for directories!? */
+	msg_outtrans_attr(menu->name, hl_attr(HLF_D));
+    }
+
+    if (menu != NULL && menu->children == NULL)
+    {
+	for (bit = 0; bit < MENU_MODES; bit++)
+	    if ((menu->modes & modes & (1 << bit)) != 0)
+	    {
+		msg_putchar('\n');
+		if (got_int)		/* "q" hit for "--more--" */
+		    return;
+		for (i = 0; i < depth + 2; i++)
+		    MSG_PUTS("  ");
+		msg_putchar(menu_mode_chars[bit]);
+		if (menu->noremap[bit] == REMAP_NONE)
+		    msg_putchar('*');
+		else if (menu->noremap[bit] == REMAP_SCRIPT)
+		    msg_putchar('&');
+		else
+		    msg_putchar(' ');
+		if (menu->silent[bit])
+		    msg_putchar('s');
+		else
+		    msg_putchar(' ');
+		if ((menu->modes & menu->enabled & (1 << bit)) == 0)
+		    msg_putchar('-');
+		else
+		    msg_putchar(' ');
+		MSG_PUTS(" ");
+		if (*menu->strings[bit] == NUL)
+		    msg_puts_attr((char_u *)"<Nop>", hl_attr(HLF_8));
+		else
+		    msg_outtrans_special(menu->strings[bit], FALSE);
+	    }
+    }
+    else
+    {
+	if (menu == NULL)
+	{
+	    menu = root_menu;
+	    depth--;
+	}
+	else
+	    menu = menu->children;
+
+	/* recursively show all children.  Skip PopUp[nvoci]. */
+	for (; menu != NULL && !got_int; menu = menu->next)
+	    if (!menu_is_hidden(menu->dname))
+		show_menus_recursive(menu, modes, depth + 1);
+    }
+}
+
+#ifdef FEAT_CMDL_COMPL
+
+/*
+ * Used when expanding menu names.
+ */
+static vimmenu_T	*expand_menu = NULL;
+static int		expand_modes = 0x0;
+static int		expand_emenu;	/* TRUE for ":emenu" command */
+
+/*
+ * Work out what to complete when doing command line completion of menu names.
+ */
+    char_u *
+set_context_in_menu_cmd(xp, cmd, arg, forceit)
+    expand_T	*xp;
+    char_u	*cmd;
+    char_u	*arg;
+    int		forceit;
+{
+    char_u	*after_dot;
+    char_u	*p;
+    char_u	*path_name = NULL;
+    char_u	*name;
+    int		unmenu;
+    vimmenu_T	*menu;
+    int		expand_menus;
+
+    xp->xp_context = EXPAND_UNSUCCESSFUL;
+
+
+    /* Check for priority numbers, enable and disable */
+    for (p = arg; *p; ++p)
+	if (!VIM_ISDIGIT(*p) && *p != '.')
+	    break;
+
+    if (!vim_iswhite(*p))
+    {
+	if (STRNCMP(arg, "enable", 6) == 0
+		&& (arg[6] == NUL ||  vim_iswhite(arg[6])))
+	    p = arg + 6;
+	else if (STRNCMP(arg, "disable", 7) == 0
+		&& (arg[7] == NUL || vim_iswhite(arg[7])))
+	    p = arg + 7;
+	else
+	    p = arg;
+    }
+
+    while (*p != NUL && vim_iswhite(*p))
+	++p;
+
+    arg = after_dot = p;
+
+    for (; *p && !vim_iswhite(*p); ++p)
+    {
+	if ((*p == '\\' || *p == Ctrl_V) && p[1] != NUL)
+	    p++;
+	else if (*p == '.')
+	    after_dot = p + 1;
+    }
+
+    /* ":tearoff" and ":popup" only use menus, not entries */
+    expand_menus = !((*cmd == 't' && cmd[1] == 'e') || *cmd == 'p');
+    expand_emenu = (*cmd == 'e');
+    if (expand_menus && vim_iswhite(*p))
+	return NULL;	/* TODO: check for next command? */
+    if (*p == NUL)		/* Complete the menu name */
+    {
+	/*
+	 * With :unmenu, you only want to match menus for the appropriate mode.
+	 * With :menu though you might want to add a menu with the same name as
+	 * one in another mode, so match menus from other modes too.
+	 */
+	expand_modes = get_menu_cmd_modes(cmd, forceit, NULL, &unmenu);
+	if (!unmenu)
+	    expand_modes = MENU_ALL_MODES;
+
+	menu = root_menu;
+	if (after_dot != arg)
+	{
+	    path_name = alloc((unsigned)(after_dot - arg));
+	    if (path_name == NULL)
+		return NULL;
+	    vim_strncpy(path_name, arg, after_dot - arg - 1);
+	}
+	name = path_name;
+	while (name != NULL && *name)
+	{
+	    p = menu_name_skip(name);
+	    while (menu != NULL)
+	    {
+		if (menu_name_equal(name, menu))
+		{
+		    /* Found menu */
+		    if ((*p != NUL && menu->children == NULL)
+			|| ((menu->modes & expand_modes) == 0x0))
+		    {
+			/*
+			 * Menu path continues, but we have reached a leaf.
+			 * Or menu exists only in another mode.
+			 */
+			vim_free(path_name);
+			return NULL;
+		    }
+		    break;
+		}
+		menu = menu->next;
+	    }
+	    if (menu == NULL)
+	    {
+		/* No menu found with the name we were looking for */
+		vim_free(path_name);
+		return NULL;
+	    }
+	    name = p;
+	    menu = menu->children;
+	}
+	vim_free(path_name);
+
+	xp->xp_context = expand_menus ? EXPAND_MENUNAMES : EXPAND_MENUS;
+	xp->xp_pattern = after_dot;
+	expand_menu = menu;
+    }
+    else			/* We're in the mapping part */
+	xp->xp_context = EXPAND_NOTHING;
+    return NULL;
+}
+
+/*
+ * Function given to ExpandGeneric() to obtain the list of (sub)menus (not
+ * entries).
+ */
+/*ARGSUSED*/
+    char_u *
+get_menu_name(xp, idx)
+    expand_T	*xp;
+    int		idx;
+{
+    static vimmenu_T	*menu = NULL;
+    char_u		*str;
+
+    if (idx == 0)	    /* first call: start at first item */
+	menu = expand_menu;
+
+    /* Skip PopUp[nvoci]. */
+    while (menu != NULL && (menu_is_hidden(menu->dname)
+	    || menu_is_separator(menu->dname)
+	    || menu_is_tearoff(menu->dname)
+	    || menu->children == NULL))
+	menu = menu->next;
+
+    if (menu == NULL)	    /* at end of linked list */
+	return NULL;
+
+    if (menu->modes & expand_modes)
+	str = menu->dname;
+    else
+	str = (char_u *)"";
+
+    /* Advance to next menu entry. */
+    menu = menu->next;
+
+    return str;
+}
+
+/*
+ * Function given to ExpandGeneric() to obtain the list of menus and menu
+ * entries.
+ */
+/*ARGSUSED*/
+    char_u *
+get_menu_names(xp, idx)
+    expand_T	*xp;
+    int		idx;
+{
+    static vimmenu_T	*menu = NULL;
+    static char_u	tbuffer[256]; /*hack*/
+    char_u		*str;
+
+    if (idx == 0)	    /* first call: start at first item */
+	menu = expand_menu;
+
+    /* Skip Browse-style entries, popup menus and separators. */
+    while (menu != NULL
+	    && (   menu_is_hidden(menu->dname)
+		|| (expand_emenu && menu_is_separator(menu->dname))
+		|| menu_is_tearoff(menu->dname)
+#ifndef FEAT_BROWSE
+		|| menu->dname[STRLEN(menu->dname) - 1] == '.'
+#endif
+	       ))
+	menu = menu->next;
+
+    if (menu == NULL)	    /* at end of linked list */
+	return NULL;
+
+    if (menu->modes & expand_modes)
+    {
+	if (menu->children != NULL)
+	{
+	    STRCPY(tbuffer, menu->dname);
+	    /* hack on menu separators:  use a 'magic' char for the separator
+	     * so that '.' in names gets escaped properly */
+	    STRCAT(tbuffer, "\001");
+	    str = tbuffer;
+	}
+	else
+	    str = menu->dname;
+    }
+    else
+	str = (char_u *)"";
+
+    /* Advance to next menu entry. */
+    menu = menu->next;
+
+    return str;
+}
+#endif /* FEAT_CMDL_COMPL */
+
+/*
+ * Skip over this element of the menu path and return the start of the next
+ * element.  Any \ and ^Vs are removed from the current element.
+ * "name" may be modified.
+ */
+    char_u *
+menu_name_skip(name)
+    char_u  *name;
+{
+    char_u  *p;
+
+    for (p = name; *p && *p != '.'; mb_ptr_adv(p))
+    {
+	if (*p == '\\' || *p == Ctrl_V)
+	{
+	    mch_memmove(p, p + 1, STRLEN(p));
+	    if (*p == NUL)
+		break;
+	}
+    }
+    if (*p)
+	*p++ = NUL;
+    return p;
+}
+
+/*
+ * Return TRUE when "name" matches with menu "menu".  The name is compared in
+ * two ways: raw menu name and menu name without '&'.  ignore part after a TAB.
+ */
+    static int
+menu_name_equal(name, menu)
+    char_u	*name;
+    vimmenu_T	*menu;
+{
+    return (menu_namecmp(name, menu->name) || menu_namecmp(name, menu->dname));
+}
+
+    static int
+menu_namecmp(name, mname)
+    char_u	*name;
+    char_u	*mname;
+{
+    int		i;
+
+    for (i = 0; name[i] != NUL && name[i] != TAB; ++i)
+	if (name[i] != mname[i])
+	    break;
+    return ((name[i] == NUL || name[i] == TAB)
+	    && (mname[i] == NUL || mname[i] == TAB));
+}
+
+/*
+ * Return the modes specified by the given menu command (eg :menu! returns
+ * MENU_CMDLINE_MODE | MENU_INSERT_MODE).
+ * If "noremap" is not NULL, then the flag it points to is set according to
+ * whether the command is a "nore" command.
+ * If "unmenu" is not NULL, then the flag it points to is set according to
+ * whether the command is an "unmenu" command.
+ */
+    static int
+get_menu_cmd_modes(cmd, forceit, noremap, unmenu)
+    char_u  *cmd;
+    int	    forceit;	    /* Was there a "!" after the command? */
+    int	    *noremap;
+    int	    *unmenu;
+{
+    int	    modes;
+
+    switch (*cmd++)
+    {
+	case 'v':			/* vmenu, vunmenu, vnoremenu */
+	    modes = MENU_VISUAL_MODE | MENU_SELECT_MODE;
+	    break;
+	case 'x':			/* xmenu, xunmenu, xnoremenu */
+	    modes = MENU_VISUAL_MODE;
+	    break;
+	case 's':			/* smenu, sunmenu, snoremenu */
+	    modes = MENU_SELECT_MODE;
+	    break;
+	case 'o':			/* omenu */
+	    modes = MENU_OP_PENDING_MODE;
+	    break;
+	case 'i':			/* imenu */
+	    modes = MENU_INSERT_MODE;
+	    break;
+	case 't':
+	    modes = MENU_TIP_MODE;	/* tmenu */
+	    break;
+	case 'c':			/* cmenu */
+	    modes = MENU_CMDLINE_MODE;
+	    break;
+	case 'a':			/* amenu */
+	    modes = MENU_INSERT_MODE | MENU_CMDLINE_MODE | MENU_NORMAL_MODE
+				    | MENU_VISUAL_MODE | MENU_SELECT_MODE
+				    | MENU_OP_PENDING_MODE;
+	    break;
+	case 'n':
+	    if (*cmd != 'o')		/* nmenu, not noremenu */
+	    {
+		modes = MENU_NORMAL_MODE;
+		break;
+	    }
+	    /* FALLTHROUGH */
+	default:
+	    --cmd;
+	    if (forceit)		/* menu!! */
+		modes = MENU_INSERT_MODE | MENU_CMDLINE_MODE;
+	    else			/* menu */
+		modes = MENU_NORMAL_MODE | MENU_VISUAL_MODE | MENU_SELECT_MODE
+						       | MENU_OP_PENDING_MODE;
+    }
+
+    if (noremap != NULL)
+	*noremap = (*cmd == 'n' ? REMAP_NONE : REMAP_YES);
+    if (unmenu != NULL)
+	*unmenu = (*cmd == 'u');
+    return modes;
+}
+
+/*
+ * Modify a menu name starting with "PopUp" to include the mode character.
+ * Returns the name in allocated memory (NULL for failure).
+ */
+    static char_u *
+popup_mode_name(name, idx)
+    char_u	*name;
+    int		idx;
+{
+    char_u	*p;
+    int		len = (int)STRLEN(name);
+
+    p = vim_strnsave(name, len + 1);
+    if (p != NULL)
+    {
+	mch_memmove(p + 6, p + 5, (size_t)(len - 4));
+	p[5] = menu_mode_chars[idx];
+    }
+    return p;
+}
+
+#if defined(FEAT_GUI) || defined(PROTO)
+/*
+ * Return the index into the menu->strings or menu->noremap arrays for the
+ * current state.  Returns MENU_INDEX_INVALID if there is no mapping for the
+ * given menu in the current mode.
+ */
+    int
+get_menu_index(menu, state)
+    vimmenu_T	*menu;
+    int		state;
+{
+    int		idx;
+
+    if ((state & INSERT))
+	idx = MENU_INDEX_INSERT;
+    else if (state & CMDLINE)
+	idx = MENU_INDEX_CMDLINE;
+#ifdef FEAT_VISUAL
+    else if (VIsual_active)
+    {
+	if (VIsual_select)
+	    idx = MENU_INDEX_SELECT;
+	else
+	    idx = MENU_INDEX_VISUAL;
+    }
+#endif
+    else if (state == HITRETURN || state == ASKMORE)
+	idx = MENU_INDEX_CMDLINE;
+    else if (finish_op)
+	idx = MENU_INDEX_OP_PENDING;
+    else if ((state & NORMAL))
+	idx = MENU_INDEX_NORMAL;
+    else
+	idx = MENU_INDEX_INVALID;
+
+    if (idx != MENU_INDEX_INVALID && menu->strings[idx] == NULL)
+	idx = MENU_INDEX_INVALID;
+    return idx;
+}
+#endif
+
+/*
+ * Duplicate the menu item text and then process to see if a mnemonic key
+ * and/or accelerator text has been identified.
+ * Returns a pointer to allocated memory, or NULL for failure.
+ * If mnemonic != NULL, *mnemonic is set to the character after the first '&'.
+ * If actext != NULL, *actext is set to the text after the first TAB.
+ */
+    static char_u *
+menu_text(str, mnemonic, actext)
+    char_u	*str;
+    int		*mnemonic;
+    char_u	**actext;
+{
+    char_u	*p;
+    char_u	*text;
+
+    /* Locate accelerator text, after the first TAB */
+    p = vim_strchr(str, TAB);
+    if (p != NULL)
+    {
+	if (actext != NULL)
+	    *actext = vim_strsave(p + 1);
+	text = vim_strnsave(str, (int)(p - str));
+    }
+    else
+	text = vim_strsave(str);
+
+    /* Find mnemonic characters "&a" and reduce "&&" to "&". */
+    for (p = text; p != NULL; )
+    {
+	p = vim_strchr(p, '&');
+	if (p != NULL)
+	{
+	    if (p[1] == NUL)	    /* trailing "&" */
+		break;
+	    if (mnemonic != NULL && p[1] != '&')
+#if !defined(__MVS__) || defined(MOTIF390_MNEMONIC_FIXED)
+		*mnemonic = p[1];
+#else
+	    {
+		/*
+		 * Well there is a bug in the Motif libraries on OS390 Unix.
+		 * The mnemonic keys needs to be converted to ASCII values
+		 * first.
+		 * This behavior has been seen in 2.8 and 2.9.
+		 */
+		char c = p[1];
+		__etoa_l(&c, 1);
+		*mnemonic = c;
+	    }
+#endif
+	    mch_memmove(p, p + 1, STRLEN(p));
+	    p = p + 1;
+	}
+    }
+    return text;
+}
+
+/*
+ * Return TRUE if "name" can be a menu in the MenuBar.
+ */
+    int
+menu_is_menubar(name)
+    char_u	*name;
+{
+    return (!menu_is_popup(name)
+	    && !menu_is_toolbar(name)
+	    && *name != MNU_HIDDEN_CHAR);
+}
+
+/*
+ * Return TRUE if "name" is a popup menu name.
+ */
+    int
+menu_is_popup(name)
+    char_u	*name;
+{
+    return (STRNCMP(name, "PopUp", 5) == 0);
+}
+
+#if (defined(FEAT_GUI_MOTIF) && (XmVersion <= 1002)) || defined(PROTO)
+/*
+ * Return TRUE if "name" is part of a popup menu.
+ */
+    int
+menu_is_child_of_popup(menu)
+    vimmenu_T *menu;
+{
+    while (menu->parent != NULL)
+	menu = menu->parent;
+    return menu_is_popup(menu->name);
+}
+#endif
+
+/*
+ * Return TRUE if "name" is a toolbar menu name.
+ */
+    int
+menu_is_toolbar(name)
+    char_u	*name;
+{
+    return (STRNCMP(name, "ToolBar", 7) == 0);
+}
+
+/*
+ * Return TRUE if the name is a menu separator identifier: Starts and ends
+ * with '-'
+ */
+    int
+menu_is_separator(name)
+    char_u *name;
+{
+    return (name[0] == '-' && name[STRLEN(name) - 1] == '-');
+}
+
+/*
+ * Return TRUE if the menu is hidden:  Starts with ']'
+ */
+    static int
+menu_is_hidden(name)
+    char_u *name;
+{
+    return (name[0] == ']') || (menu_is_popup(name) && name[5] != NUL);
+}
+
+#if defined(FEAT_CMDL_COMPL) \
+	|| (defined(FEAT_GUI_W32) && defined(FEAT_TEAROFF))
+/*
+ * Return TRUE if the menu is the tearoff menu.
+ */
+/*ARGSUSED*/
+    static int
+menu_is_tearoff(name)
+    char_u *name;
+{
+#ifdef FEAT_GUI
+    return (STRCMP(name, TEAR_STRING) == 0);
+#else
+    return FALSE;
+#endif
+}
+#endif
+
+#ifdef FEAT_GUI
+
+    static int
+get_menu_mode()
+{
+#ifdef FEAT_VISUAL
+    if (VIsual_active)
+    {
+	if (VIsual_select)
+	    return MENU_INDEX_SELECT;
+	return MENU_INDEX_VISUAL;
+    }
+#endif
+    if (State & INSERT)
+	return MENU_INDEX_INSERT;
+    if ((State & CMDLINE) || State == ASKMORE || State == HITRETURN)
+	return MENU_INDEX_CMDLINE;
+    if (finish_op)
+	return MENU_INDEX_OP_PENDING;
+    if (State & NORMAL)
+	return MENU_INDEX_NORMAL;
+    if (State & LANGMAP)	/* must be a "r" command, like Insert mode */
+	return MENU_INDEX_INSERT;
+    return MENU_INDEX_INVALID;
+}
+
+/*
+ * Check that a pointer appears in the menu tree.  Used to protect from using
+ * a menu that was deleted after it was selected but before the event was
+ * handled.
+ * Return OK or FAIL.  Used recursively.
+ */
+    int
+check_menu_pointer(root, menu_to_check)
+    vimmenu_T *root;
+    vimmenu_T *menu_to_check;
+{
+    vimmenu_T	*p;
+
+    for (p = root; p != NULL; p = p->next)
+	if (p == menu_to_check
+		|| (p->children != NULL
+		    && check_menu_pointer(p->children, menu_to_check) == OK))
+	    return OK;
+    return FAIL;
+}
+
+/*
+ * After we have started the GUI, then we can create any menus that have been
+ * defined.  This is done once here.  add_menu_path() may have already been
+ * called to define these menus, and may be called again.  This function calls
+ * itself recursively.	Should be called at the top level with:
+ * gui_create_initial_menus(root_menu, NULL);
+ */
+    void
+gui_create_initial_menus(menu)
+    vimmenu_T	*menu;
+{
+    int		idx = 0;
+
+    while (menu != NULL)
+    {
+	/* Don't add a menu when only a tip was defined. */
+	if (menu->modes & MENU_ALL_MODES)
+	{
+	    if (menu->children != NULL)
+	    {
+		gui_mch_add_menu(menu, idx);
+		gui_create_initial_menus(menu->children);
+	    }
+	    else
+		gui_mch_add_menu_item(menu, idx);
+	}
+	menu = menu->next;
+	++idx;
+    }
+}
+
+/*
+ * Used recursively by gui_update_menus (see below)
+ */
+    static void
+gui_update_menus_recurse(menu, mode)
+    vimmenu_T	*menu;
+    int		mode;
+{
+    int		grey;
+
+    while (menu)
+    {
+	if ((menu->modes & menu->enabled & mode)
+#if defined(FEAT_GUI_W32) && defined(FEAT_TEAROFF)
+		|| menu_is_tearoff(menu->dname)
+#endif
+	   )
+	    grey = FALSE;
+	else
+	    grey = TRUE;
+#ifdef FEAT_GUI_ATHENA
+	/* Hiding menus doesn't work for Athena, it can cause a crash. */
+	gui_mch_menu_grey(menu, grey);
+#else
+	/* Never hide a toplevel menu, it may make the menubar resize or
+	 * disappear. Same problem for ToolBar items. */
+	if (vim_strchr(p_go, GO_GREY) != NULL || menu->parent == NULL
+# ifdef FEAT_TOOLBAR
+		|| menu_is_toolbar(menu->parent->name)
+# endif
+		   )
+	    gui_mch_menu_grey(menu, grey);
+	else
+	    gui_mch_menu_hidden(menu, grey);
+#endif
+	gui_update_menus_recurse(menu->children, mode);
+	menu = menu->next;
+    }
+}
+
+/*
+ * Make sure only the valid menu items appear for this mode.  If
+ * force_menu_update is not TRUE, then we only do this if the mode has changed
+ * since last time.  If "modes" is not 0, then we use these modes instead.
+ */
+    void
+gui_update_menus(modes)
+    int	    modes;
+{
+    static int	    prev_mode = -1;
+    int		    mode = 0;
+
+    if (modes != 0x0)
+	mode = modes;
+    else
+    {
+	mode = get_menu_mode();
+	if (mode == MENU_INDEX_INVALID)
+	    mode = 0;
+	else
+	    mode = (1 << mode);
+    }
+
+    if (force_menu_update || mode != prev_mode)
+    {
+	gui_update_menus_recurse(root_menu, mode);
+	gui_mch_draw_menubar();
+	prev_mode = mode;
+	force_menu_update = FALSE;
+#ifdef FEAT_GUI_W32
+	/* This can leave a tearoff as active window - make sure we
+	 * have the focus <negri>*/
+	gui_mch_activate_window();
+#endif
+    }
+}
+
+#if defined(FEAT_GUI_MSWIN) || defined(FEAT_GUI_MOTIF) \
+    || defined(FEAT_GUI_GTK) || defined(FEAT_GUI_PHOTON) || defined(PROTO)
+/*
+ * Check if a key is used as a mnemonic for a toplevel menu.
+ * Case of the key is ignored.
+ */
+    int
+gui_is_menu_shortcut(key)
+    int		key;
+{
+    vimmenu_T	*menu;
+
+    if (key < 256)
+	key = TOLOWER_LOC(key);
+    for (menu = root_menu; menu != NULL; menu = menu->next)
+	if (menu->mnemonic == key
+		|| (menu->mnemonic < 256 && TOLOWER_LOC(menu->mnemonic) == key))
+	    return TRUE;
+    return FALSE;
+}
+#endif
+
+/*
+ * Display the Special "PopUp" menu as a pop-up at the current mouse
+ * position.  The "PopUpn" menu is for Normal mode, "PopUpi" for Insert mode,
+ * etc.
+ */
+    void
+gui_show_popupmenu()
+{
+    vimmenu_T	*menu;
+    int		mode;
+
+    mode = get_menu_mode();
+    if (mode == MENU_INDEX_INVALID)
+	return;
+    mode = menu_mode_chars[mode];
+
+#ifdef FEAT_AUTOCMD
+    {
+	char_u	    ename[2];
+
+	ename[0] = mode;
+	ename[1] = NUL;
+	apply_autocmds(EVENT_MENUPOPUP, ename, NULL, FALSE, curbuf);
+    }
+#endif
+
+    for (menu = root_menu; menu != NULL; menu = menu->next)
+	if (STRNCMP("PopUp", menu->name, 5) == 0 && menu->name[5] == mode)
+	    break;
+
+    /* Only show a popup when it is defined and has entries */
+    if (menu != NULL && menu->children != NULL)
+	gui_mch_show_popupmenu(menu);
+}
+#endif /* FEAT_GUI */
+
+#if (defined(FEAT_GUI_W32) && defined(FEAT_TEAROFF)) || defined(PROTO)
+
+/*
+ * Deal with tearoff items that are added like a menu item.
+ * Currently only for Win32 GUI.  Others may follow later.
+ */
+
+    void
+gui_mch_toggle_tearoffs(int enable)
+{
+    int		pri_tab[MENUDEPTH + 1];
+    int		i;
+
+    if (enable)
+    {
+	for (i = 0; i < MENUDEPTH; ++i)
+	    pri_tab[i] = 500;
+	pri_tab[MENUDEPTH] = -1;
+	gui_create_tearoffs_recurse(root_menu, (char_u *)"", pri_tab, 0);
+    }
+    else
+	gui_destroy_tearoffs_recurse(root_menu);
+    s_tearoffs = enable;
+}
+
+/*
+ * Recursively add tearoff items
+ */
+    static void
+gui_create_tearoffs_recurse(menu, pname, pri_tab, pri_idx)
+    vimmenu_T		*menu;
+    const char_u	*pname;
+    int			*pri_tab;
+    int			pri_idx;
+{
+    char_u	*newpname = NULL;
+    int		len;
+    char_u	*s;
+    char_u	*d;
+
+    if (pri_tab[pri_idx + 1] != -1)
+	++pri_idx;
+    while (menu != NULL)
+    {
+	if (menu->children != NULL && menu_is_menubar(menu->name))
+	{
+	    /* Add the menu name to the menu path.  Insert a backslash before
+	     * dots (it's used to separate menu names). */
+	    len = (int)STRLEN(pname) + (int)STRLEN(menu->name);
+	    for (s = menu->name; *s; ++s)
+		if (*s == '.' || *s == '\\')
+		    ++len;
+	    newpname = alloc(len + TEAR_LEN + 2);
+	    if (newpname != NULL)
+	    {
+		STRCPY(newpname, pname);
+		d = newpname + STRLEN(newpname);
+		for (s = menu->name; *s; ++s)
+		{
+		    if (*s == '.' || *s == '\\')
+			*d++ = '\\';
+		    *d++ = *s;
+		}
+		*d = NUL;
+
+		/* check if tearoff already exists */
+		if (STRCMP(menu->children->name, TEAR_STRING) != 0)
+		{
+		    gui_add_tearoff(newpname, pri_tab, pri_idx - 1);
+		    *d = NUL;			/* remove TEAR_STRING */
+		}
+
+		STRCAT(newpname, ".");
+		gui_create_tearoffs_recurse(menu->children, newpname,
+							    pri_tab, pri_idx);
+		vim_free(newpname);
+	    }
+	}
+	menu = menu->next;
+    }
+}
+
+/*
+ * Add tear-off menu item for a submenu.
+ * "tearpath" is the menu path, and must have room to add TEAR_STRING.
+ */
+    static void
+gui_add_tearoff(tearpath, pri_tab, pri_idx)
+    char_u	*tearpath;
+    int		*pri_tab;
+    int		pri_idx;
+{
+    char_u	*tbuf;
+    int		t;
+    vimmenu_T	menuarg;
+
+    tbuf = alloc(5 + (unsigned int)STRLEN(tearpath));
+    if (tbuf != NULL)
+    {
+	tbuf[0] = K_SPECIAL;
+	tbuf[1] = K_SECOND(K_TEAROFF);
+	tbuf[2] = K_THIRD(K_TEAROFF);
+	STRCPY(tbuf + 3, tearpath);
+	STRCAT(tbuf + 3, "\r");
+
+	STRCAT(tearpath, ".");
+	STRCAT(tearpath, TEAR_STRING);
+
+	/* Priority of tear-off is always 1 */
+	t = pri_tab[pri_idx + 1];
+	pri_tab[pri_idx + 1] = 1;
+
+#ifdef FEAT_TOOLBAR
+	menuarg.iconfile = NULL;
+	menuarg.iconidx = -1;
+	menuarg.icon_builtin = FALSE;
+#endif
+	menuarg.noremap[0] = REMAP_NONE;
+	menuarg.silent[0] = TRUE;
+
+	menuarg.modes = MENU_ALL_MODES;
+	add_menu_path(tearpath, &menuarg, pri_tab, tbuf, FALSE);
+
+	menuarg.modes = MENU_TIP_MODE;
+	add_menu_path(tearpath, &menuarg, pri_tab,
+		(char_u *)_("Tear off this menu"), FALSE);
+
+	pri_tab[pri_idx + 1] = t;
+	vim_free(tbuf);
+    }
+}
+
+/*
+ * Recursively destroy tearoff items
+ */
+    static void
+gui_destroy_tearoffs_recurse(menu)
+    vimmenu_T	*menu;
+{
+    while (menu)
+    {
+	if (menu->children)
+	{
+	    /* check if tearoff exists */
+	    if (STRCMP(menu->children->name, TEAR_STRING) == 0)
+	    {
+		/* Disconnect the item and free the memory */
+		free_menu(&menu->children);
+	    }
+	    if (menu->children != NULL) /* if not the last one */
+		gui_destroy_tearoffs_recurse(menu->children);
+	}
+	menu = menu->next;
+    }
+}
+
+#endif /* FEAT_GUI_W32 && FEAT_TEAROFF */
+
+/*
+ * Given a menu descriptor, e.g. "File.New", find it in the menu hierarchy and
+ * execute it.
+ */
+    void
+ex_emenu(eap)
+    exarg_T	*eap;
+{
+    vimmenu_T	*menu;
+    char_u	*name;
+    char_u	*saved_name;
+    char_u	*p;
+    int		idx;
+    char_u	*mode;
+
+    saved_name = vim_strsave(eap->arg);
+    if (saved_name == NULL)
+	return;
+
+    menu = root_menu;
+    name = saved_name;
+    while (*name)
+    {
+	/* Find in the menu hierarchy */
+	p = menu_name_skip(name);
+
+	while (menu != NULL)
+	{
+	    if (menu_name_equal(name, menu))
+	    {
+		if (*p == NUL && menu->children != NULL)
+		{
+		    EMSG(_("E333: Menu path must lead to a menu item"));
+		    menu = NULL;
+		}
+		else if (*p != NUL && menu->children == NULL)
+		{
+		    EMSG(_(e_notsubmenu));
+		    menu = NULL;
+		}
+		break;
+	    }
+	    menu = menu->next;
+	}
+	if (menu == NULL || *p == NUL)
+	    break;
+	menu = menu->children;
+	name = p;
+    }
+    vim_free(saved_name);
+    if (menu == NULL)
+    {
+	EMSG2(_("E334: Menu not found: %s"), eap->arg);
+	return;
+    }
+
+    /* Found the menu, so execute.
+     * Use the Insert mode entry when returning to Insert mode. */
+    if (restart_edit
+#ifdef FEAT_EVAL
+	    && !current_SID
+#endif
+	    )
+    {
+	mode = (char_u *)"Insert";
+	idx = MENU_INDEX_INSERT;
+    }
+    else if (eap->addr_count)
+    {
+	pos_T	tpos;
+
+	mode = (char_u *)"Visual";
+	idx = MENU_INDEX_VISUAL;
+
+	/* GEDDES: This is not perfect - but it is a
+	 * quick way of detecting whether we are doing this from a
+	 * selection - see if the range matches up with the visual
+	 * select start and end.  */
+	if ((curbuf->b_visual.vi_start.lnum == eap->line1)
+		&& (curbuf->b_visual.vi_end.lnum) == eap->line2)
+	{
+	    /* Set it up for visual mode - equivalent to gv.  */
+	    VIsual_mode = curbuf->b_visual.vi_mode;
+	    tpos = curbuf->b_visual.vi_end;
+	    curwin->w_cursor = curbuf->b_visual.vi_start;
+	    curwin->w_curswant = curbuf->b_visual.vi_curswant;
+	}
+	else
+	{
+	    /* Set it up for line-wise visual mode */
+	    VIsual_mode = 'V';
+	    curwin->w_cursor.lnum = eap->line1;
+	    curwin->w_cursor.col = 1;
+	    tpos.lnum = eap->line2;
+	    tpos.col = MAXCOL;
+#ifdef FEAT_VIRTUALEDIT
+	    tpos.coladd = 0;
+#endif
+	}
+
+	/* Activate visual mode */
+	VIsual_active = TRUE;
+	VIsual_reselect = TRUE;
+	check_cursor();
+	VIsual = curwin->w_cursor;
+	curwin->w_cursor = tpos;
+
+	check_cursor();
+
+	/* Adjust the cursor to make sure it is in the correct pos
+	 * for exclusive mode */
+	if (*p_sel == 'e' && gchar_cursor() != NUL)
+	    ++curwin->w_cursor.col;
+    }
+    else
+    {
+	mode = (char_u *)"Normal";
+	idx = MENU_INDEX_NORMAL;
+    }
+
+    if (idx != MENU_INDEX_INVALID && menu->strings[idx] != NULL)
+    {
+	/* When executing a script or function execute the commands right now.
+	 * Otherwise put them in the typeahead buffer. */
+#ifdef FEAT_EVAL
+	if (current_SID != 0)
+	    exec_normal_cmd(menu->strings[idx], menu->noremap[idx],
+							   menu->silent[idx]);
+	else
+#endif
+	    ins_typebuf(menu->strings[idx], menu->noremap[idx], 0,
+						     TRUE, menu->silent[idx]);
+    }
+    else
+	EMSG2(_("E335: Menu not defined for %s mode"), mode);
+}
+
+#if defined(FEAT_GUI_MSWIN) \
+	|| (defined(FEAT_GUI_GTK) && defined(FEAT_MENU)) \
+	|| defined(FEAT_BEVAL_TIP) || defined(PROTO)
+/*
+ * Given a menu descriptor, e.g. "File.New", find it in the menu hierarchy.
+ */
+    vimmenu_T *
+gui_find_menu(path_name)
+    char_u *path_name;
+{
+    vimmenu_T	*menu = NULL;
+    char_u	*name;
+    char_u	*saved_name;
+    char_u	*p;
+
+    menu = root_menu;
+
+    saved_name = vim_strsave(path_name);
+    if (saved_name == NULL)
+	return NULL;
+
+    name = saved_name;
+    while (*name)
+    {
+	/* find the end of one dot-separated name and put a NUL at the dot */
+	p = menu_name_skip(name);
+
+	while (menu != NULL)
+	{
+	    if (STRCMP(name, menu->name) == 0 || STRCMP(name, menu->dname) == 0)
+	    {
+		if (menu->children == NULL)
+		{
+		    /* found a menu item instead of a sub-menu */
+		    if (*p == NUL)
+			EMSG(_("E336: Menu path must lead to a sub-menu"));
+		    else
+			EMSG(_(e_notsubmenu));
+		    menu = NULL;
+		    goto theend;
+		}
+		if (*p == NUL)	    /* found a full match */
+		    goto theend;
+		break;
+	    }
+	    menu = menu->next;
+	}
+	if (menu == NULL)	/* didn't find it */
+	    break;
+
+	/* Found a match, search the sub-menu. */
+	menu = menu->children;
+	name = p;
+    }
+
+    if (menu == NULL)
+	EMSG(_("E337: Menu not found - check menu names"));
+theend:
+    vim_free(saved_name);
+    return menu;
+}
+#endif
+
+#ifdef FEAT_MULTI_LANG
+/*
+ * Translation of menu names.  Just a simple lookup table.
+ */
+
+typedef struct
+{
+    char_u	*from;		/* English name */
+    char_u	*from_noamp;	/* same, without '&' */
+    char_u	*to;		/* translated name */
+} menutrans_T;
+
+static garray_T menutrans_ga = {0, 0, 0, 0, NULL};
+#endif
+
+/*
+ * ":menutrans".
+ * This function is also defined without the +multi_lang feature, in which
+ * case the commands are ignored.
+ */
+/*ARGSUSED*/
+    void
+ex_menutranslate(eap)
+    exarg_T	*eap;
+{
+#ifdef FEAT_MULTI_LANG
+    char_u		*arg = eap->arg;
+    menutrans_T		*tp;
+    int			i;
+    char_u		*from, *from_noamp, *to;
+
+    if (menutrans_ga.ga_itemsize == 0)
+	ga_init2(&menutrans_ga, (int)sizeof(menutrans_T), 5);
+
+    /*
+     * ":menutrans clear": clear all translations.
+     */
+    if (STRNCMP(arg, "clear", 5) == 0 && ends_excmd(*skipwhite(arg + 5)))
+    {
+	tp = (menutrans_T *)menutrans_ga.ga_data;
+	for (i = 0; i < menutrans_ga.ga_len; ++i)
+	{
+	    vim_free(tp[i].from);
+	    vim_free(tp[i].from_noamp);
+	    vim_free(tp[i].to);
+	}
+	ga_clear(&menutrans_ga);
+# ifdef FEAT_EVAL
+	/* Delete all "menutrans_" global variables. */
+	del_menutrans_vars();
+# endif
+    }
+    else
+    {
+	/* ":menutrans from to": add translation */
+	from = arg;
+	arg = menu_skip_part(arg);
+	to = skipwhite(arg);
+	*arg = NUL;
+	arg = menu_skip_part(to);
+	if (arg == to)
+	    EMSG(_(e_invarg));
+	else
+	{
+	    if (ga_grow(&menutrans_ga, 1) == OK)
+	    {
+		tp = (menutrans_T *)menutrans_ga.ga_data;
+		from = vim_strsave(from);
+		if (from != NULL)
+		{
+		    from_noamp = menu_text(from, NULL, NULL);
+		    to = vim_strnsave(to, (int)(arg - to));
+		    if (from_noamp != NULL && to != NULL)
+		    {
+			tp[menutrans_ga.ga_len].from = from;
+			tp[menutrans_ga.ga_len].from_noamp = from_noamp;
+			tp[menutrans_ga.ga_len].to = to;
+			++menutrans_ga.ga_len;
+		    }
+		    else
+		    {
+			vim_free(from);
+			vim_free(from_noamp);
+			vim_free(to);
+		    }
+		}
+	    }
+	}
+    }
+#endif
+}
+
+#if defined(FEAT_MULTI_LANG) || defined(FEAT_TOOLBAR)
+/*
+ * Find the character just after one part of a menu name.
+ */
+    static char_u *
+menu_skip_part(p)
+    char_u	*p;
+{
+    while (*p != NUL && *p != '.' && !vim_iswhite(*p))
+    {
+	if ((*p == '\\' || *p == Ctrl_V) && p[1] != NUL)
+	    ++p;
+	++p;
+    }
+    return p;
+}
+#endif
+
+#ifdef FEAT_MULTI_LANG
+/*
+ * Lookup part of a menu name in the translations.
+ * Return a pointer to the translation or NULL if not found.
+ */
+    static char_u *
+menutrans_lookup(name, len)
+    char_u	*name;
+    int		len;
+{
+    menutrans_T		*tp = (menutrans_T *)menutrans_ga.ga_data;
+    int			i;
+    char_u		*dname;
+
+    for (i = 0; i < menutrans_ga.ga_len; ++i)
+	if (STRNCMP(name, tp[i].from, len) == 0 && tp[i].from[len] == NUL)
+	    return tp[i].to;
+
+    /* Now try again while ignoring '&' characters. */
+    i = name[len];
+    name[len] = NUL;
+    dname = menu_text(name, NULL, NULL);
+    name[len] = i;
+    if (dname != NULL)
+    {
+	for (i = 0; i < menutrans_ga.ga_len; ++i)
+	    if (STRCMP(dname, tp[i].from_noamp) == 0)
+	    {
+		vim_free(dname);
+		return tp[i].to;
+	    }
+	vim_free(dname);
+    }
+
+    return NULL;
+}
+#endif /* FEAT_MULTI_LANG */
+
+#endif /* FEAT_MENU */
--- /dev/null
+++ b/message.c
@@ -1,0 +1,4595 @@
+/* vi:set ts=8 sts=4 sw=4:
+ *
+ * VIM - Vi IMproved	by Bram Moolenaar
+ *
+ * Do ":help uganda"  in Vim to read copying and usage conditions.
+ * Do ":help credits" in Vim to see a list of people who contributed.
+ * See README.txt for an overview of the Vim source code.
+ */
+
+/*
+ * message.c: functions for displaying messages on the command line
+ */
+
+#define MESSAGE_FILE		/* don't include prototype for smsg() */
+
+#include "vim.h"
+
+static int other_sourcing_name __ARGS((void));
+static char_u *get_emsg_source __ARGS((void));
+static char_u *get_emsg_lnum __ARGS((void));
+static void add_msg_hist __ARGS((char_u *s, int len, int attr));
+static void hit_return_msg __ARGS((void));
+static void msg_home_replace_attr __ARGS((char_u *fname, int attr));
+#ifdef FEAT_MBYTE
+static char_u *screen_puts_mbyte __ARGS((char_u *s, int l, int attr));
+#endif
+static void msg_puts_attr_len __ARGS((char_u *str, int maxlen, int attr));
+static void msg_puts_display __ARGS((char_u *str, int maxlen, int attr, int recurse));
+static void msg_scroll_up __ARGS((void));
+static void inc_msg_scrolled __ARGS((void));
+static void store_sb_text __ARGS((char_u **sb_str, char_u *s, int attr, int *sb_col, int finish));
+static void t_puts __ARGS((int *t_col, char_u *t_s, char_u *s, int attr));
+static void msg_puts_printf __ARGS((char_u *str, int maxlen));
+static int do_more_prompt __ARGS((int typed_char));
+static void msg_screen_putchar __ARGS((int c, int attr));
+static int  msg_check_screen __ARGS((void));
+static void redir_write __ARGS((char_u *s, int maxlen));
+static void verbose_write __ARGS((char_u *s, int maxlen));
+#ifdef FEAT_CON_DIALOG
+static char_u *msg_show_console_dialog __ARGS((char_u *message, char_u *buttons, int dfltbutton));
+static int	confirm_msg_used = FALSE;	/* displaying confirm_msg */
+static char_u	*confirm_msg = NULL;		/* ":confirm" message */
+static char_u	*confirm_msg_tail;		/* tail of confirm_msg */
+#endif
+
+struct msg_hist
+{
+    struct msg_hist	*next;
+    char_u		*msg;
+    int			attr;
+};
+
+static struct msg_hist *first_msg_hist = NULL;
+static struct msg_hist *last_msg_hist = NULL;
+static int msg_hist_len = 0;
+
+/*
+ * When writing messages to the screen, there are many different situations.
+ * A number of variables is used to remember the current state:
+ * msg_didany	    TRUE when messages were written since the last time the
+ *		    user reacted to a prompt.
+ *		    Reset: After hitting a key for the hit-return prompt,
+ *		    hitting <CR> for the command line or input().
+ *		    Set: When any message is written to the screen.
+ * msg_didout	    TRUE when something was written to the current line.
+ *		    Reset: When advancing to the next line, when the current
+ *		    text can be overwritten.
+ *		    Set: When any message is written to the screen.
+ * msg_nowait	    No extra delay for the last drawn message.
+ *		    Used in normal_cmd() before the mode message is drawn.
+ * emsg_on_display  There was an error message recently.  Indicates that there
+ *		    should be a delay before redrawing.
+ * msg_scroll	    The next message should not overwrite the current one.
+ * msg_scrolled	    How many lines the screen has been scrolled (because of
+ *		    messages).  Used in update_screen() to scroll the screen
+ *		    back.  Incremented each time the screen scrolls a line.
+ * msg_scrolled_ign  TRUE when msg_scrolled is non-zero and msg_puts_attr()
+ *		    writes something without scrolling should not make
+ *		    need_wait_return to be set.  This is a hack to make ":ts"
+ *		    work without an extra prompt.
+ * lines_left	    Number of lines available for messages before the
+ *		    more-prompt is to be given.
+ * need_wait_return TRUE when the hit-return prompt is needed.
+ *		    Reset: After giving the hit-return prompt, when the user
+ *		    has answered some other prompt.
+ *		    Set: When the ruler or typeahead display is overwritten,
+ *		    scrolling the screen for some message.
+ * keep_msg	    Message to be displayed after redrawing the screen, in
+ *		    main_loop().
+ *		    This is an allocated string or NULL when not used.
+ */
+
+/*
+ * msg(s) - displays the string 's' on the status line
+ * When terminal not initialized (yet) mch_errmsg(..) is used.
+ * return TRUE if wait_return not called
+ */
+    int
+msg(s)
+    char_u	*s;
+{
+    return msg_attr_keep(s, 0, FALSE);
+}
+
+#if defined(FEAT_EVAL) || defined(FEAT_X11) || defined(USE_XSMP) \
+    || defined(PROTO)
+/*
+ * Like msg() but keep it silent when 'verbosefile' is set.
+ */
+    int
+verb_msg(s)
+    char_u	*s;
+{
+    int		n;
+
+    verbose_enter();
+    n = msg_attr_keep(s, 0, FALSE);
+    verbose_leave();
+
+    return n;
+}
+#endif
+
+    int
+msg_attr(s, attr)
+    char_u	*s;
+    int		attr;
+{
+    return msg_attr_keep(s, attr, FALSE);
+}
+
+    int
+msg_attr_keep(s, attr, keep)
+    char_u	*s;
+    int		attr;
+    int		keep;	    /* TRUE: set keep_msg if it doesn't scroll */
+{
+    static int	entered = 0;
+    int		retval;
+    char_u	*buf = NULL;
+
+#ifdef FEAT_EVAL
+    if (attr == 0)
+	set_vim_var_string(VV_STATUSMSG, s, -1);
+#endif
+
+    /*
+     * It is possible that displaying a messages causes a problem (e.g.,
+     * when redrawing the window), which causes another message, etc..	To
+     * break this loop, limit the recursiveness to 3 levels.
+     */
+    if (entered >= 3)
+	return TRUE;
+    ++entered;
+
+    /* Add message to history (unless it's a repeated kept message or a
+     * truncated message) */
+    if (s != keep_msg
+	    || (*s != '<'
+		&& last_msg_hist != NULL
+		&& last_msg_hist->msg != NULL
+		&& STRCMP(s, last_msg_hist->msg)))
+	add_msg_hist(s, -1, attr);
+
+    /* When displaying keep_msg, don't let msg_start() free it, caller must do
+     * that. */
+    if (s == keep_msg)
+	keep_msg = NULL;
+
+    /* Truncate the message if needed. */
+    msg_start();
+    buf = msg_strtrunc(s, FALSE);
+    if (buf != NULL)
+	s = buf;
+
+    msg_outtrans_attr(s, attr);
+    msg_clr_eos();
+    retval = msg_end();
+
+    if (keep && retval && vim_strsize(s) < (int)(Rows - cmdline_row - 1)
+							   * Columns + sc_col)
+	set_keep_msg(s, 0);
+
+    vim_free(buf);
+    --entered;
+    return retval;
+}
+
+/*
+ * Truncate a string such that it can be printed without causing a scroll.
+ * Returns an allocated string or NULL when no truncating is done.
+ */
+    char_u *
+msg_strtrunc(s, force)
+    char_u	*s;
+    int		force;	    /* always truncate */
+{
+    char_u	*buf = NULL;
+    int		len;
+    int		room;
+
+    /* May truncate message to avoid a hit-return prompt */
+    if ((!msg_scroll && !need_wait_return && shortmess(SHM_TRUNCALL)
+			       && !exmode_active && msg_silent == 0) || force)
+    {
+	len = vim_strsize(s);
+	if (msg_scrolled != 0)
+	    /* Use all the columns. */
+	    room = (int)(Rows - msg_row) * Columns - 1;
+	else
+	    /* Use up to 'showcmd' column. */
+	    room = (int)(Rows - msg_row - 1) * Columns + sc_col - 1;
+	if (len > room && room > 0)
+	{
+#ifdef FEAT_MBYTE
+	    if (enc_utf8)
+		/* may have up to 18 bytes per cell (6 per char, up to two
+		 * composing chars) */
+		buf = alloc((room + 2) * 18);
+	    else if (enc_dbcs == DBCS_JPNU)
+		/* may have up to 2 bytes per cell for euc-jp */
+		buf = alloc((room + 2) * 2);
+	    else
+#endif
+		buf = alloc(room + 2);
+	    if (buf != NULL)
+		trunc_string(s, buf, room);
+	}
+    }
+    return buf;
+}
+
+/*
+ * Truncate a string "s" to "buf" with cell width "room".
+ * "s" and "buf" may be equal.
+ */
+    void
+trunc_string(s, buf, room)
+    char_u	*s;
+    char_u	*buf;
+    int		room;
+{
+    int		half;
+    int		len;
+    int		e;
+    int		i;
+    int		n;
+
+    room -= 3;
+    half = room / 2;
+    len = 0;
+
+    /* First part: Start of the string. */
+    for (e = 0; len < half; ++e)
+    {
+	if (s[e] == NUL)
+	{
+	    /* text fits without truncating! */
+	    buf[e] = NUL;
+	    return;
+	}
+	n = ptr2cells(s + e);
+	if (len + n >= half)
+	    break;
+	len += n;
+	buf[e] = s[e];
+#ifdef FEAT_MBYTE
+	if (has_mbyte)
+	    for (n = (*mb_ptr2len)(s + e); --n > 0; )
+	    {
+		++e;
+		buf[e] = s[e];
+	    }
+#endif
+    }
+
+    /* Last part: End of the string. */
+    i = e;
+#ifdef FEAT_MBYTE
+    if (enc_dbcs != 0)
+    {
+	/* For DBCS going backwards in a string is slow, but
+	 * computing the cell width isn't too slow: go forward
+	 * until the rest fits. */
+	n = vim_strsize(s + i);
+	while (len + n > room)
+	{
+	    n -= ptr2cells(s + i);
+	    i += (*mb_ptr2len)(s + i);
+	}
+    }
+    else if (enc_utf8)
+    {
+	/* For UTF-8 we can go backwards easily. */
+	half = i = (int)STRLEN(s);
+	for (;;)
+	{
+	    do
+		half = half - (*mb_head_off)(s, s + half - 1) - 1;
+	    while (utf_iscomposing(utf_ptr2char(s + half)) && half > 0);
+	    n = ptr2cells(s + half);
+	    if (len + n > room)
+		break;
+	    len += n;
+	    i = half;
+	}
+    }
+    else
+#endif
+    {
+	for (i = (int)STRLEN(s); len + (n = ptr2cells(s + i - 1)) <= room; --i)
+	    len += n;
+    }
+
+    /* Set the middle and copy the last part. */
+    mch_memmove(buf + e, "...", (size_t)3);
+    mch_memmove(buf + e + 3, s + i, STRLEN(s + i) + 1);
+}
+
+/*
+ * Automatic prototype generation does not understand this function.
+ * Note: Caller of smgs() and smsg_attr() must check the resulting string is
+ * shorter than IOSIZE!!!
+ */
+#ifndef PROTO
+# ifndef HAVE_STDARG_H
+
+int
+#ifdef __BORLANDC__
+_RTLENTRYF
+#endif
+smsg __ARGS((char_u *, long, long, long,
+			long, long, long, long, long, long, long));
+int
+#ifdef __BORLANDC__
+_RTLENTRYF
+#endif
+smsg_attr __ARGS((int, char_u *, long, long, long,
+			long, long, long, long, long, long, long));
+
+int vim_snprintf __ARGS((char *, size_t, char *, long, long, long,
+				   long, long, long, long, long, long, long));
+
+/*
+ * smsg(str, arg, ...) is like using sprintf(buf, str, arg, ...) and then
+ * calling msg(buf).
+ * The buffer used is IObuff, the message is truncated at IOSIZE.
+ */
+
+/* VARARGS */
+    int
+#ifdef __BORLANDC__
+_RTLENTRYF
+#endif
+smsg(s, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10)
+    char_u	*s;
+    long	a1, a2, a3, a4, a5, a6, a7, a8, a9, a10;
+{
+    return smsg_attr(0, s, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10);
+}
+
+/* VARARGS */
+    int
+#ifdef __BORLANDC__
+_RTLENTRYF
+#endif
+smsg_attr(attr, s, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10)
+    int		attr;
+    char_u	*s;
+    long	a1, a2, a3, a4, a5, a6, a7, a8, a9, a10;
+{
+    vim_snprintf((char *)IObuff, IOSIZE, (char *)s,
+				     a1, a2, a3, a4, a5, a6, a7, a8, a9, a10);
+    return msg_attr(IObuff, attr);
+}
+
+# else /* HAVE_STDARG_H */
+
+int vim_snprintf(char *str, size_t str_m, char *fmt, ...);
+
+    int
+#ifdef __BORLANDC__
+_RTLENTRYF
+#endif
+smsg(char_u *s, ...)
+{
+    va_list arglist;
+
+    va_start(arglist, s);
+    vim_vsnprintf((char *)IObuff, IOSIZE, (char *)s, arglist, NULL);
+    va_end(arglist);
+    return msg(IObuff);
+}
+
+    int
+#ifdef __BORLANDC__
+_RTLENTRYF
+#endif
+smsg_attr(int attr, char_u *s, ...)
+{
+    va_list arglist;
+
+    va_start(arglist, s);
+    vim_vsnprintf((char *)IObuff, IOSIZE, (char *)s, arglist, NULL);
+    va_end(arglist);
+    return msg_attr(IObuff, attr);
+}
+
+# endif /* HAVE_STDARG_H */
+#endif
+
+/*
+ * Remember the last sourcing name/lnum used in an error message, so that it
+ * isn't printed each time when it didn't change.
+ */
+static int	last_sourcing_lnum = 0;
+static char_u   *last_sourcing_name = NULL;
+
+/*
+ * Reset the last used sourcing name/lnum.  Makes sure it is displayed again
+ * for the next error message;
+ */
+    void
+reset_last_sourcing()
+{
+    vim_free(last_sourcing_name);
+    last_sourcing_name = NULL;
+    last_sourcing_lnum = 0;
+}
+
+/*
+ * Return TRUE if "sourcing_name" differs from "last_sourcing_name".
+ */
+    static int
+other_sourcing_name()
+{
+    if (sourcing_name != NULL)
+    {
+	if (last_sourcing_name != NULL)
+	    return STRCMP(sourcing_name, last_sourcing_name) != 0;
+	return TRUE;
+    }
+    return FALSE;
+}
+
+/*
+ * Get the message about the source, as used for an error message.
+ * Returns an allocated string with room for one more character.
+ * Returns NULL when no message is to be given.
+ */
+    static char_u *
+get_emsg_source()
+{
+    char_u	*Buf, *p;
+
+    if (sourcing_name != NULL && other_sourcing_name())
+    {
+	p = (char_u *)_("Error detected while processing %s:");
+	Buf = alloc((unsigned)(STRLEN(sourcing_name) + STRLEN(p)));
+	if (Buf != NULL)
+	    sprintf((char *)Buf, (char *)p, sourcing_name);
+	return Buf;
+    }
+    return NULL;
+}
+
+/*
+ * Get the message about the source lnum, as used for an error message.
+ * Returns an allocated string with room for one more character.
+ * Returns NULL when no message is to be given.
+ */
+    static char_u *
+get_emsg_lnum()
+{
+    char_u	*Buf, *p;
+
+    /* lnum is 0 when executing a command from the command line
+     * argument, we don't want a line number then */
+    if (sourcing_name != NULL
+	    && (other_sourcing_name() || sourcing_lnum != last_sourcing_lnum)
+	    && sourcing_lnum != 0)
+    {
+	p = (char_u *)_("line %4ld:");
+	Buf = alloc((unsigned)(STRLEN(p) + 20));
+	if (Buf != NULL)
+	    sprintf((char *)Buf, (char *)p, (long)sourcing_lnum);
+	return Buf;
+    }
+    return NULL;
+}
+
+/*
+ * Display name and line number for the source of an error.
+ * Remember the file name and line number, so that for the next error the info
+ * is only displayed if it changed.
+ */
+    void
+msg_source(attr)
+    int		attr;
+{
+    char_u	*p;
+
+    ++no_wait_return;
+    p = get_emsg_source();
+    if (p != NULL)
+    {
+	msg_attr(p, attr);
+	vim_free(p);
+    }
+    p = get_emsg_lnum();
+    if (p != NULL)
+    {
+	msg_attr(p, hl_attr(HLF_N));
+	vim_free(p);
+	last_sourcing_lnum = sourcing_lnum;  /* only once for each line */
+    }
+
+    /* remember the last sourcing name printed, also when it's empty */
+    if (sourcing_name == NULL || other_sourcing_name())
+    {
+	vim_free(last_sourcing_name);
+	if (sourcing_name == NULL)
+	    last_sourcing_name = NULL;
+	else
+	    last_sourcing_name = vim_strsave(sourcing_name);
+    }
+    --no_wait_return;
+}
+
+/*
+ * Return TRUE if not giving error messages right now:
+ * If "emsg_off" is set: no error messages at the moment.
+ * If "msg" is in 'debug': do error message but without side effects.
+ * If "emsg_skip" is set: never do error messages.
+ */
+    int
+emsg_not_now()
+{
+    if ((emsg_off > 0 && vim_strchr(p_debug, 'm') == NULL
+					  && vim_strchr(p_debug, 't') == NULL)
+#ifdef FEAT_EVAL
+	    || emsg_skip > 0
+#endif
+	    )
+	return TRUE;
+    return FALSE;
+}
+
+/*
+ * emsg() - display an error message
+ *
+ * Rings the bell, if appropriate, and calls message() to do the real work
+ * When terminal not initialized (yet) mch_errmsg(..) is used.
+ *
+ * return TRUE if wait_return not called
+ */
+    int
+emsg(s)
+    char_u	*s;
+{
+    int		attr;
+    char_u	*p;
+#ifdef FEAT_EVAL
+    int		ignore = FALSE;
+    int		severe;
+#endif
+
+    called_emsg = TRUE;
+    ex_exitval = 1;
+
+    /*
+     * If "emsg_severe" is TRUE: When an error exception is to be thrown,
+     * prefer this message over previous messages for the same command.
+     */
+#ifdef FEAT_EVAL
+    severe = emsg_severe;
+    emsg_severe = FALSE;
+#endif
+
+    /* Skip this if not giving error messages at the moment. */
+    if (emsg_not_now())
+	return TRUE;
+
+    if (!emsg_off || vim_strchr(p_debug, 't') != NULL)
+    {
+#ifdef FEAT_EVAL
+	/*
+	 * Cause a throw of an error exception if appropriate.  Don't display
+	 * the error message in this case.  (If no matching catch clause will
+	 * be found, the message will be displayed later on.)  "ignore" is set
+	 * when the message should be ignored completely (used for the
+	 * interrupt message).
+	 */
+	if (cause_errthrow(s, severe, &ignore) == TRUE)
+	{
+	    if (!ignore)
+		did_emsg = TRUE;
+	    return TRUE;
+	}
+
+	/* set "v:errmsg", also when using ":silent! cmd" */
+	set_vim_var_string(VV_ERRMSG, s, -1);
+#endif
+
+	/*
+	 * When using ":silent! cmd" ignore error messsages.
+	 * But do write it to the redirection file.
+	 */
+	if (emsg_silent != 0)
+	{
+	    msg_start();
+	    p = get_emsg_source();
+	    if (p != NULL)
+	    {
+		STRCAT(p, "\n");
+		redir_write(p, -1);
+		vim_free(p);
+	    }
+	    p = get_emsg_lnum();
+	    if (p != NULL)
+	    {
+		STRCAT(p, "\n");
+		redir_write(p, -1);
+		vim_free(p);
+	    }
+	    redir_write(s, -1);
+	    return TRUE;
+	}
+
+	/* Reset msg_silent, an error causes messages to be switched back on. */
+	msg_silent = 0;
+	cmd_silent = FALSE;
+
+	if (global_busy)		/* break :global command */
+	    ++global_busy;
+
+	if (p_eb)
+	    beep_flush();		/* also includes flush_buffers() */
+	else
+	    flush_buffers(FALSE);	/* flush internal buffers */
+	did_emsg = TRUE;		/* flag for DoOneCmd() */
+    }
+
+    emsg_on_display = TRUE;	/* remember there is an error message */
+    ++msg_scroll;		/* don't overwrite a previous message */
+    attr = hl_attr(HLF_E);	/* set highlight mode for error messages */
+    if (msg_scrolled != 0)
+	need_wait_return = TRUE;    /* needed in case emsg() is called after
+				     * wait_return has reset need_wait_return
+				     * and a redraw is expected because
+				     * msg_scrolled is non-zero */
+
+    /*
+     * Display name and line number for the source of the error.
+     */
+    msg_source(attr);
+
+    /*
+     * Display the error message itself.
+     */
+    msg_nowait = FALSE;			/* wait for this msg */
+    return msg_attr(s, attr);
+}
+
+/*
+ * Print an error message with one "%s" and one string argument.
+ */
+    int
+emsg2(s, a1)
+    char_u *s, *a1;
+{
+    return emsg3(s, a1, NULL);
+}
+
+/* emsg3() and emsgn() are in misc2.c to avoid warnings for the prototypes. */
+
+    void
+emsg_invreg(name)
+    int	    name;
+{
+    EMSG2(_("E354: Invalid register name: '%s'"), transchar(name));
+}
+
+/*
+ * Like msg(), but truncate to a single line if p_shm contains 't', or when
+ * "force" is TRUE.  This truncates in another way as for normal messages.
+ * Careful: The string may be changed by msg_may_trunc()!
+ * Returns a pointer to the printed message, if wait_return() not called.
+ */
+    char_u *
+msg_trunc_attr(s, force, attr)
+    char_u	*s;
+    int		force;
+    int		attr;
+{
+    int		n;
+
+    /* Add message to history before truncating */
+    add_msg_hist(s, -1, attr);
+
+    s = msg_may_trunc(force, s);
+
+    msg_hist_off = TRUE;
+    n = msg_attr(s, attr);
+    msg_hist_off = FALSE;
+
+    if (n)
+	return s;
+    return NULL;
+}
+
+/*
+ * Check if message "s" should be truncated at the start (for filenames).
+ * Return a pointer to where the truncated message starts.
+ * Note: May change the message by replacing a character with '<'.
+ */
+    char_u *
+msg_may_trunc(force, s)
+    int		force;
+    char_u	*s;
+{
+    int		n;
+    int		room;
+
+    room = (int)(Rows - cmdline_row - 1) * Columns + sc_col - 1;
+    if ((force || (shortmess(SHM_TRUNC) && !exmode_active))
+	    && (n = (int)STRLEN(s) - room) > 0)
+    {
+#ifdef FEAT_MBYTE
+	if (has_mbyte)
+	{
+	    int	size = vim_strsize(s);
+
+	    /* There may be room anyway when there are multibyte chars. */
+	    if (size <= room)
+		return s;
+
+	    for (n = 0; size >= room; )
+	    {
+		size -= (*mb_ptr2cells)(s + n);
+		n += (*mb_ptr2len)(s + n);
+	    }
+	    --n;
+	}
+#endif
+	s += n;
+	*s = '<';
+    }
+    return s;
+}
+
+    static void
+add_msg_hist(s, len, attr)
+    char_u	*s;
+    int		len;		/* -1 for undetermined length */
+    int		attr;
+{
+    struct msg_hist *p;
+
+    if (msg_hist_off || msg_silent != 0)
+	return;
+
+    /* Don't let the message history get too big */
+    while (msg_hist_len > MAX_MSG_HIST_LEN)
+	(void)delete_first_msg();
+
+    /* allocate an entry and add the message at the end of the history */
+    p = (struct msg_hist *)alloc((int)sizeof(struct msg_hist));
+    if (p != NULL)
+    {
+	if (len < 0)
+	    len = (int)STRLEN(s);
+	/* remove leading and trailing newlines */
+	while (len > 0 && *s == '\n')
+	{
+	    ++s;
+	    --len;
+	}
+	while (len > 0 && s[len - 1] == '\n')
+	    --len;
+	p->msg = vim_strnsave(s, len);
+	p->next = NULL;
+	p->attr = attr;
+	if (last_msg_hist != NULL)
+	    last_msg_hist->next = p;
+	last_msg_hist = p;
+	if (first_msg_hist == NULL)
+	    first_msg_hist = last_msg_hist;
+	++msg_hist_len;
+    }
+}
+
+/*
+ * Delete the first (oldest) message from the history.
+ * Returns FAIL if there are no messages.
+ */
+    int
+delete_first_msg()
+{
+    struct msg_hist *p;
+
+    if (msg_hist_len <= 0)
+	return FAIL;
+    p = first_msg_hist;
+    first_msg_hist = p->next;
+    vim_free(p->msg);
+    vim_free(p);
+    --msg_hist_len;
+    return OK;
+}
+
+/*
+ * ":messages" command.
+ */
+/*ARGSUSED*/
+    void
+ex_messages(eap)
+    exarg_T	*eap;
+{
+    struct msg_hist *p;
+    char_u	    *s;
+
+    msg_hist_off = TRUE;
+
+    s = mch_getenv((char_u *)"LANG");
+    if (s != NULL && *s != NUL)
+	msg_attr((char_u *)
+		_("Messages maintainer: Bram Moolenaar <Bram@vim.org>"),
+		hl_attr(HLF_T));
+
+    for (p = first_msg_hist; p != NULL; p = p->next)
+	if (p->msg != NULL)
+	    msg_attr(p->msg, p->attr);
+
+    msg_hist_off = FALSE;
+}
+
+#if defined(FEAT_CON_DIALOG) || defined(FIND_REPLACE_DIALOG) || defined(PROTO)
+/*
+ * Call this after prompting the user.  This will avoid a hit-return message
+ * and a delay.
+ */
+    void
+msg_end_prompt()
+{
+    need_wait_return = FALSE;
+    emsg_on_display = FALSE;
+    cmdline_row = msg_row;
+    msg_col = 0;
+    msg_clr_eos();
+}
+#endif
+
+/*
+ * wait for the user to hit a key (normally a return)
+ * if 'redraw' is TRUE, clear and redraw the screen
+ * if 'redraw' is FALSE, just redraw the screen
+ * if 'redraw' is -1, don't redraw at all
+ */
+    void
+wait_return(redraw)
+    int		redraw;
+{
+    int		c;
+    int		oldState;
+    int		tmpState;
+    int		had_got_int;
+
+    if (redraw == TRUE)
+	must_redraw = CLEAR;
+
+    /* If using ":silent cmd", don't wait for a return.  Also don't set
+     * need_wait_return to do it later. */
+    if (msg_silent != 0)
+	return;
+
+/*
+ * With the global command (and some others) we only need one return at the
+ * end. Adjust cmdline_row to avoid the next message overwriting the last one.
+ * When inside vgetc(), we can't wait for a typed character at all.
+ */
+    if (vgetc_busy > 0)
+	return;
+    if (no_wait_return)
+    {
+	need_wait_return = TRUE;
+	if (!exmode_active)
+	    cmdline_row = msg_row;
+	return;
+    }
+
+    redir_off = TRUE;		/* don't redirect this message */
+    oldState = State;
+    if (quit_more)
+    {
+	c = CAR;		/* just pretend CR was hit */
+	quit_more = FALSE;
+	got_int = FALSE;
+    }
+    else if (exmode_active)
+    {
+	MSG_PUTS(" ");		/* make sure the cursor is on the right line */
+	c = CAR;		/* no need for a return in ex mode */
+	got_int = FALSE;
+    }
+    else
+    {
+	/* Make sure the hit-return prompt is on screen when 'guioptions' was
+	 * just changed. */
+	screenalloc(FALSE);
+
+	State = HITRETURN;
+#ifdef FEAT_MOUSE
+	setmouse();
+#endif
+#ifdef USE_ON_FLY_SCROLL
+	dont_scroll = TRUE;		/* disallow scrolling here */
+#endif
+	hit_return_msg();
+
+	do
+	{
+	    /* Remember "got_int", if it is set vgetc() probably returns a
+	     * CTRL-C, but we need to loop then. */
+	    had_got_int = got_int;
+
+	    /* Don't do mappings here, we put the character back in the
+	     * typeahead buffer. */
+	    ++no_mapping;
+	    ++allow_keys;
+	    c = safe_vgetc();
+	    if (had_got_int && !global_busy)
+		got_int = FALSE;
+	    --no_mapping;
+	    --allow_keys;
+
+#ifdef FEAT_CLIPBOARD
+	    /* Strange way to allow copying (yanking) a modeless selection at
+	     * the hit-enter prompt.  Use CTRL-Y, because the same is used in
+	     * Cmdline-mode and it's harmless when there is no selection. */
+	    if (c == Ctrl_Y && clip_star.state == SELECT_DONE)
+	    {
+		clip_copy_modeless_selection(TRUE);
+		c = K_IGNORE;
+	    }
+#endif
+	    /*
+	     * Allow scrolling back in the messages.
+	     * Also accept scroll-down commands when messages fill the screen,
+	     * to avoid that typing one 'j' too many makes the messages
+	     * disappear.
+	     */
+	    if (p_more && !p_cp)
+	    {
+		if (c == 'b' || c == 'k' || c == 'u' || c == 'g' || c == K_UP)
+		{
+		    /* scroll back to show older messages */
+		    do_more_prompt(c);
+		    if (quit_more)
+		    {
+			c = CAR;		/* just pretend CR was hit */
+			quit_more = FALSE;
+			got_int = FALSE;
+		    }
+		    else
+		    {
+			c = K_IGNORE;
+			hit_return_msg();
+		    }
+		}
+		else if (msg_scrolled > Rows - 2
+				     && (c == 'j' || c == K_DOWN || c == 'd'))
+		    c = K_IGNORE;
+	    }
+	} while ((had_got_int && c == Ctrl_C)
+				|| c == K_IGNORE
+#ifdef FEAT_GUI
+				|| c == K_VER_SCROLLBAR || c == K_HOR_SCROLLBAR
+#endif
+#ifdef FEAT_MOUSE
+				|| c == K_LEFTDRAG   || c == K_LEFTRELEASE
+				|| c == K_MIDDLEDRAG || c == K_MIDDLERELEASE
+				|| c == K_RIGHTDRAG  || c == K_RIGHTRELEASE
+				|| c == K_MOUSEDOWN  || c == K_MOUSEUP
+				|| (!mouse_has(MOUSE_RETURN)
+				    && mouse_row < msg_row
+				    && (c == K_LEFTMOUSE
+					|| c == K_MIDDLEMOUSE
+					|| c == K_RIGHTMOUSE
+					|| c == K_X1MOUSE
+					|| c == K_X2MOUSE))
+#endif
+				);
+	ui_breakcheck();
+#ifdef FEAT_MOUSE
+	/*
+	 * Avoid that the mouse-up event causes visual mode to start.
+	 */
+	if (c == K_LEFTMOUSE || c == K_MIDDLEMOUSE || c == K_RIGHTMOUSE
+					  || c == K_X1MOUSE || c == K_X2MOUSE)
+	    (void)jump_to_mouse(MOUSE_SETPOS, NULL, 0);
+	else
+#endif
+	    if (vim_strchr((char_u *)"\r\n ", c) == NULL && c != Ctrl_C)
+	{
+	    /* Put the character back in the typeahead buffer.  Don't use the
+	     * stuff buffer, because lmaps wouldn't work. */
+	    ins_char_typebuf(c);
+	    do_redraw = TRUE;	    /* need a redraw even though there is
+				       typeahead */
+	}
+    }
+    redir_off = FALSE;
+
+    /*
+     * If the user hits ':', '?' or '/' we get a command line from the next
+     * line.
+     */
+    if (c == ':' || c == '?' || c == '/')
+    {
+	if (!exmode_active)
+	    cmdline_row = msg_row;
+	skip_redraw = TRUE;	    /* skip redraw once */
+	do_redraw = FALSE;
+    }
+
+    /*
+     * If the window size changed set_shellsize() will redraw the screen.
+     * Otherwise the screen is only redrawn if 'redraw' is set and no ':'
+     * typed.
+     */
+    tmpState = State;
+    State = oldState;		    /* restore State before set_shellsize */
+#ifdef FEAT_MOUSE
+    setmouse();
+#endif
+    msg_check();
+
+#if defined(UNIX) || defined(VMS)
+    /*
+     * When switching screens, we need to output an extra newline on exit.
+     */
+    if (swapping_screen() && !termcap_active)
+	newline_on_exit = TRUE;
+#endif
+
+    need_wait_return = FALSE;
+    did_wait_return = TRUE;
+    emsg_on_display = FALSE;	/* can delete error message now */
+    lines_left = -1;		/* reset lines_left at next msg_start() */
+    reset_last_sourcing();
+    if (keep_msg != NULL && vim_strsize(keep_msg) >=
+				  (Rows - cmdline_row - 1) * Columns + sc_col)
+    {
+	vim_free(keep_msg);
+	keep_msg = NULL;	    /* don't redisplay message, it's too long */
+    }
+
+    if (tmpState == SETWSIZE)	    /* got resize event while in vgetc() */
+    {
+	starttermcap();		    /* start termcap before redrawing */
+	shell_resized();
+    }
+    else if (!skip_redraw
+	    && (redraw == TRUE || (msg_scrolled != 0 && redraw != -1)))
+    {
+	starttermcap();		    /* start termcap before redrawing */
+	redraw_later(VALID);
+    }
+}
+
+/*
+ * Write the hit-return prompt.
+ */
+    static void
+hit_return_msg()
+{
+    int		save_p_more = p_more;
+
+    p_more = FALSE;	/* don't want see this message when scrolling back */
+    if (msg_didout)	/* start on a new line */
+	msg_putchar('\n');
+    if (got_int)
+	MSG_PUTS(_("Interrupt: "));
+
+    MSG_PUTS_ATTR(_("Press ENTER or type command to continue"), hl_attr(HLF_R));
+    if (!msg_use_printf())
+	msg_clr_eos();
+    p_more = save_p_more;
+}
+
+/*
+ * Set "keep_msg" to "s".  Free the old value and check for NULL pointer.
+ */
+    void
+set_keep_msg(s, attr)
+    char_u	*s;
+    int		attr;
+{
+    vim_free(keep_msg);
+    if (s != NULL && msg_silent == 0)
+	keep_msg = vim_strsave(s);
+    else
+	keep_msg = NULL;
+    keep_msg_more = FALSE;
+    keep_msg_attr = attr;
+}
+
+#if defined(FEAT_TERMRESPONSE) || defined(PROTO)
+/*
+ * If there currently is a message being displayed, set "keep_msg" to it, so
+ * that it will be displayed again after redraw.
+ */
+    void
+set_keep_msg_from_hist()
+{
+    if (keep_msg == NULL && last_msg_hist != NULL && msg_scrolled == 0
+							  && (State & NORMAL))
+	set_keep_msg(last_msg_hist->msg, last_msg_hist->attr);
+}
+#endif
+
+/*
+ * Prepare for outputting characters in the command line.
+ */
+    void
+msg_start()
+{
+    int		did_return = FALSE;
+
+    vim_free(keep_msg);
+    keep_msg = NULL;			/* don't display old message now */
+    if (!msg_scroll && full_screen)	/* overwrite last message */
+    {
+	msg_row = cmdline_row;
+	msg_col =
+#ifdef FEAT_RIGHTLEFT
+	    cmdmsg_rl ? Columns - 1 :
+#endif
+	    0;
+    }
+    else if (msg_didout)		    /* start message on next line */
+    {
+	msg_putchar('\n');
+	did_return = TRUE;
+	if (exmode_active != EXMODE_NORMAL)
+	    cmdline_row = msg_row;
+    }
+    if (!msg_didany || lines_left < 0)
+	msg_starthere();
+    if (msg_silent == 0)
+    {
+	msg_didout = FALSE;		    /* no output on current line yet */
+	cursor_off();
+    }
+
+    /* when redirecting, may need to start a new line. */
+    if (!did_return)
+	redir_write((char_u *)"\n", -1);
+}
+
+/*
+ * Note that the current msg position is where messages start.
+ */
+    void
+msg_starthere()
+{
+    lines_left = cmdline_row;
+    msg_didany = FALSE;
+}
+
+    void
+msg_putchar(c)
+    int		c;
+{
+    msg_putchar_attr(c, 0);
+}
+
+    void
+msg_putchar_attr(c, attr)
+    int		c;
+    int		attr;
+{
+#ifdef FEAT_MBYTE
+    char_u	buf[MB_MAXBYTES + 1];
+#else
+    char_u	buf[4];
+#endif
+
+    if (IS_SPECIAL(c))
+    {
+	buf[0] = K_SPECIAL;
+	buf[1] = K_SECOND(c);
+	buf[2] = K_THIRD(c);
+	buf[3] = NUL;
+    }
+    else
+    {
+#ifdef FEAT_MBYTE
+	buf[(*mb_char2bytes)(c, buf)] = NUL;
+#else
+	buf[0] = c;
+	buf[1] = NUL;
+#endif
+    }
+    msg_puts_attr(buf, attr);
+}
+
+    void
+msg_outnum(n)
+    long	n;
+{
+    char_u	buf[20];
+
+    sprintf((char *)buf, "%ld", n);
+    msg_puts(buf);
+}
+
+    void
+msg_home_replace(fname)
+    char_u	*fname;
+{
+    msg_home_replace_attr(fname, 0);
+}
+
+#if defined(FEAT_FIND_ID) || defined(PROTO)
+    void
+msg_home_replace_hl(fname)
+    char_u	*fname;
+{
+    msg_home_replace_attr(fname, hl_attr(HLF_D));
+}
+#endif
+
+    static void
+msg_home_replace_attr(fname, attr)
+    char_u  *fname;
+    int	    attr;
+{
+    char_u	*name;
+
+    name = home_replace_save(NULL, fname);
+    if (name != NULL)
+	msg_outtrans_attr(name, attr);
+    vim_free(name);
+}
+
+/*
+ * Output 'len' characters in 'str' (including NULs) with translation
+ * if 'len' is -1, output upto a NUL character.
+ * Use attributes 'attr'.
+ * Return the number of characters it takes on the screen.
+ */
+    int
+msg_outtrans(str)
+    char_u	    *str;
+{
+    return msg_outtrans_attr(str, 0);
+}
+
+    int
+msg_outtrans_attr(str, attr)
+    char_u	*str;
+    int		attr;
+{
+    return msg_outtrans_len_attr(str, (int)STRLEN(str), attr);
+}
+
+    int
+msg_outtrans_len(str, len)
+    char_u	*str;
+    int		len;
+{
+    return msg_outtrans_len_attr(str, len, 0);
+}
+
+/*
+ * Output one character at "p".  Return pointer to the next character.
+ * Handles multi-byte characters.
+ */
+    char_u *
+msg_outtrans_one(p, attr)
+    char_u	*p;
+    int		attr;
+{
+#ifdef FEAT_MBYTE
+    int		l;
+
+    if (has_mbyte && (l = (*mb_ptr2len)(p)) > 1)
+    {
+	msg_outtrans_len_attr(p, l, attr);
+	return p + l;
+    }
+#endif
+    msg_puts_attr(transchar_byte(*p), attr);
+    return p + 1;
+}
+
+    int
+msg_outtrans_len_attr(msgstr, len, attr)
+    char_u	*msgstr;
+    int		len;
+    int		attr;
+{
+    int		retval = 0;
+    char_u	*str = msgstr;
+    char_u	*plain_start = msgstr;
+    char_u	*s;
+#ifdef FEAT_MBYTE
+    int		mb_l;
+    int		c;
+#endif
+
+    /* if MSG_HIST flag set, add message to history */
+    if (attr & MSG_HIST)
+    {
+	add_msg_hist(str, len, attr);
+	attr &= ~MSG_HIST;
+    }
+
+#ifdef FEAT_MBYTE
+    /* If the string starts with a composing character first draw a space on
+     * which the composing char can be drawn. */
+    if (enc_utf8 && utf_iscomposing(utf_ptr2char(msgstr)))
+	msg_puts_attr((char_u *)" ", attr);
+#endif
+
+    /*
+     * Go over the string.  Special characters are translated and printed.
+     * Normal characters are printed several at a time.
+     */
+    while (--len >= 0)
+    {
+#ifdef FEAT_MBYTE
+	if (enc_utf8)
+	    /* Don't include composing chars after the end. */
+	    mb_l = utfc_ptr2len_len(str, len + 1);
+	else if (has_mbyte)
+	    mb_l = (*mb_ptr2len)(str);
+	else
+	    mb_l = 1;
+	if (has_mbyte && mb_l > 1)
+	{
+	    c = (*mb_ptr2char)(str);
+	    if (vim_isprintc(c))
+		/* printable multi-byte char: count the cells. */
+		retval += (*mb_ptr2cells)(str);
+	    else
+	    {
+		/* unprintable multi-byte char: print the printable chars so
+		 * far and the translation of the unprintable char. */
+		if (str > plain_start)
+		    msg_puts_attr_len(plain_start, (int)(str - plain_start),
+									attr);
+		plain_start = str + mb_l;
+		msg_puts_attr(transchar(c), attr == 0 ? hl_attr(HLF_8) : attr);
+		retval += char2cells(c);
+	    }
+	    len -= mb_l - 1;
+	    str += mb_l;
+	}
+	else
+#endif
+	{
+	    s = transchar_byte(*str);
+	    if (s[1] != NUL)
+	    {
+		/* unprintable char: print the printable chars so far and the
+		 * translation of the unprintable char. */
+		if (str > plain_start)
+		    msg_puts_attr_len(plain_start, (int)(str - plain_start),
+									attr);
+		plain_start = str + 1;
+		msg_puts_attr(s, attr == 0 ? hl_attr(HLF_8) : attr);
+	    }
+	    retval += ptr2cells(str);
+	    ++str;
+	}
+    }
+
+    if (str > plain_start)
+	/* print the printable chars at the end */
+	msg_puts_attr_len(plain_start, (int)(str - plain_start), attr);
+
+    return retval;
+}
+
+#if defined(FEAT_QUICKFIX) || defined(PROTO)
+    void
+msg_make(arg)
+    char_u  *arg;
+{
+    int	    i;
+    static char_u *str = (char_u *)"eeffoc", *rs = (char_u *)"Plon#dqg#vxjduB";
+
+    arg = skipwhite(arg);
+    for (i = 5; *arg && i >= 0; --i)
+	if (*arg++ != str[i])
+	    break;
+    if (i < 0)
+    {
+	msg_putchar('\n');
+	for (i = 0; rs[i]; ++i)
+	    msg_putchar(rs[i] - 3);
+    }
+}
+#endif
+
+/*
+ * Output the string 'str' upto a NUL character.
+ * Return the number of characters it takes on the screen.
+ *
+ * If K_SPECIAL is encountered, then it is taken in conjunction with the
+ * following character and shown as <F1>, <S-Up> etc.  Any other character
+ * which is not printable shown in <> form.
+ * If 'from' is TRUE (lhs of a mapping), a space is shown as <Space>.
+ * If a character is displayed in one of these special ways, is also
+ * highlighted (its highlight name is '8' in the p_hl variable).
+ * Otherwise characters are not highlighted.
+ * This function is used to show mappings, where we want to see how to type
+ * the character/string -- webb
+ */
+    int
+msg_outtrans_special(strstart, from)
+    char_u	*strstart;
+    int		from;	/* TRUE for lhs of a mapping */
+{
+    char_u	*str = strstart;
+    int		retval = 0;
+    char_u	*string;
+    int		attr;
+    int		len;
+
+    attr = hl_attr(HLF_8);
+    while (*str != NUL)
+    {
+	/* Leading and trailing spaces need to be displayed in <> form. */
+	if ((str == strstart || str[1] == NUL) && *str == ' ')
+	{
+	    string = (char_u *)"<Space>";
+	    ++str;
+	}
+	else
+	    string = str2special(&str, from);
+	len = vim_strsize(string);
+	/* Highlight special keys */
+	msg_puts_attr(string, len > 1
+#ifdef FEAT_MBYTE
+		&& (*mb_ptr2len)(string) <= 1
+#endif
+		? attr : 0);
+	retval += len;
+    }
+    return retval;
+}
+
+/*
+ * Return the printable string for the key codes at "*sp".
+ * Used for translating the lhs or rhs of a mapping to printable chars.
+ * Advances "sp" to the next code.
+ */
+    char_u *
+str2special(sp, from)
+    char_u	**sp;
+    int		from;	/* TRUE for lhs of mapping */
+{
+    int			c;
+    static char_u	buf[7];
+    char_u		*str = *sp;
+    int			modifiers = 0;
+    int			special = FALSE;
+
+#ifdef FEAT_MBYTE
+    if (has_mbyte)
+    {
+	char_u	*p;
+
+	/* Try to un-escape a multi-byte character.  Return the un-escaped
+	 * string if it is a multi-byte character. */
+	p = mb_unescape(sp);
+	if (p != NULL)
+	    return p;
+    }
+#endif
+
+    c = *str;
+    if (c == K_SPECIAL && str[1] != NUL && str[2] != NUL)
+    {
+	if (str[1] == KS_MODIFIER)
+	{
+	    modifiers = str[2];
+	    str += 3;
+	    c = *str;
+	}
+	if (c == K_SPECIAL && str[1] != NUL && str[2] != NUL)
+	{
+	    c = TO_SPECIAL(str[1], str[2]);
+	    str += 2;
+	    if (c == K_ZERO)	/* display <Nul> as ^@ */
+		c = NUL;
+	}
+	if (IS_SPECIAL(c) || modifiers)	/* special key */
+	    special = TRUE;
+    }
+    *sp = str + 1;
+
+#ifdef FEAT_MBYTE
+    /* For multi-byte characters check for an illegal byte. */
+    if (has_mbyte && MB_BYTE2LEN(*str) > (*mb_ptr2len)(str))
+    {
+	transchar_nonprint(buf, c);
+	return buf;
+    }
+#endif
+
+    /* Make unprintable characters in <> form, also <M-Space> and <Tab>.
+     * Use <Space> only for lhs of a mapping. */
+    if (special || char2cells(c) > 1 || (from && c == ' '))
+	return get_special_key_name(c, modifiers);
+    buf[0] = c;
+    buf[1] = NUL;
+    return buf;
+}
+
+/*
+ * Translate a key sequence into special key names.
+ */
+    void
+str2specialbuf(sp, buf, len)
+    char_u	*sp;
+    char_u	*buf;
+    int		len;
+{
+    char_u	*s;
+
+    *buf = NUL;
+    while (*sp)
+    {
+	s = str2special(&sp, FALSE);
+	if ((int)(STRLEN(s) + STRLEN(buf)) < len)
+	    STRCAT(buf, s);
+    }
+}
+
+/*
+ * print line for :print or :list command
+ */
+    void
+msg_prt_line(s, list)
+    char_u	*s;
+    int		list;
+{
+    int		c;
+    int		col = 0;
+    int		n_extra = 0;
+    int		c_extra = 0;
+    char_u	*p_extra = NULL;	    /* init to make SASC shut up */
+    int		n;
+    int		attr = 0;
+    char_u	*trail = NULL;
+#ifdef FEAT_MBYTE
+    int		l;
+    char_u	buf[MB_MAXBYTES + 1];
+#endif
+
+    if (curwin->w_p_list)
+	list = TRUE;
+
+    /* find start of trailing whitespace */
+    if (list && lcs_trail)
+    {
+	trail = s + STRLEN(s);
+	while (trail > s && vim_iswhite(trail[-1]))
+	    --trail;
+    }
+
+    /* output a space for an empty line, otherwise the line will be
+     * overwritten */
+    if (*s == NUL && !(list && lcs_eol != NUL))
+	msg_putchar(' ');
+
+    while (!got_int)
+    {
+	if (n_extra > 0)
+	{
+	    --n_extra;
+	    if (c_extra)
+		c = c_extra;
+	    else
+		c = *p_extra++;
+	}
+#ifdef FEAT_MBYTE
+	else if (has_mbyte && (l = (*mb_ptr2len)(s)) > 1)
+	{
+	    col += (*mb_ptr2cells)(s);
+	    mch_memmove(buf, s, (size_t)l);
+	    buf[l] = NUL;
+	    msg_puts(buf);
+	    s += l;
+	    continue;
+	}
+#endif
+	else
+	{
+	    attr = 0;
+	    c = *s++;
+	    if (c == TAB && (!list || lcs_tab1))
+	    {
+		/* tab amount depends on current column */
+		n_extra = curbuf->b_p_ts - col % curbuf->b_p_ts - 1;
+		if (!list)
+		{
+		    c = ' ';
+		    c_extra = ' ';
+		}
+		else
+		{
+		    c = lcs_tab1;
+		    c_extra = lcs_tab2;
+		    attr = hl_attr(HLF_8);
+		}
+	    }
+	    else if (c == NUL && list && lcs_eol != NUL)
+	    {
+		p_extra = (char_u *)"";
+		c_extra = NUL;
+		n_extra = 1;
+		c = lcs_eol;
+		attr = hl_attr(HLF_AT);
+		--s;
+	    }
+	    else if (c != NUL && (n = byte2cells(c)) > 1)
+	    {
+		n_extra = n - 1;
+		p_extra = transchar_byte(c);
+		c_extra = NUL;
+		c = *p_extra++;
+		/* Use special coloring to be able to distinguish <hex> from
+		 * the same in plain text. */
+		attr = hl_attr(HLF_8);
+	    }
+	    else if (c == ' ' && trail != NULL && s > trail)
+	    {
+		c = lcs_trail;
+		attr = hl_attr(HLF_8);
+	    }
+	}
+
+	if (c == NUL)
+	    break;
+
+	msg_putchar_attr(c, attr);
+	col++;
+    }
+    msg_clr_eos();
+}
+
+#ifdef FEAT_MBYTE
+/*
+ * Use screen_puts() to output one multi-byte character.
+ * Return the pointer "s" advanced to the next character.
+ */
+    static char_u *
+screen_puts_mbyte(s, l, attr)
+    char_u	*s;
+    int		l;
+    int		attr;
+{
+    int		cw;
+
+    msg_didout = TRUE;		/* remember that line is not empty */
+    cw = (*mb_ptr2cells)(s);
+    if (cw > 1 && (
+#ifdef FEAT_RIGHTLEFT
+		cmdmsg_rl ? msg_col <= 1 :
+#endif
+		msg_col == Columns - 1))
+    {
+	/* Doesn't fit, print a highlighted '>' to fill it up. */
+	msg_screen_putchar('>', hl_attr(HLF_AT));
+	return s;
+    }
+
+    screen_puts_len(s, l, msg_row, msg_col, attr);
+#ifdef FEAT_RIGHTLEFT
+    if (cmdmsg_rl)
+    {
+	msg_col -= cw;
+	if (msg_col == 0)
+	{
+	    msg_col = Columns;
+	    ++msg_row;
+	}
+    }
+    else
+#endif
+    {
+	msg_col += cw;
+	if (msg_col >= Columns)
+	{
+	    msg_col = 0;
+	    ++msg_row;
+	}
+    }
+    return s + l;
+}
+#endif
+
+/*
+ * Output a string to the screen at position msg_row, msg_col.
+ * Update msg_row and msg_col for the next message.
+ */
+    void
+msg_puts(s)
+    char_u	*s;
+{
+    msg_puts_attr(s, 0);
+}
+
+    void
+msg_puts_title(s)
+    char_u	*s;
+{
+    msg_puts_attr(s, hl_attr(HLF_T));
+}
+
+/*
+ * Show a message in such a way that it always fits in the line.  Cut out a
+ * part in the middle and replace it with "..." when necessary.
+ * Does not handle multi-byte characters!
+ */
+    void
+msg_puts_long_attr(longstr, attr)
+    char_u	*longstr;
+    int		attr;
+{
+    msg_puts_long_len_attr(longstr, (int)STRLEN(longstr), attr);
+}
+
+    void
+msg_puts_long_len_attr(longstr, len, attr)
+    char_u	*longstr;
+    int		len;
+    int		attr;
+{
+    int		slen = len;
+    int		room;
+
+    room = Columns - msg_col;
+    if (len > room && room >= 20)
+    {
+	slen = (room - 3) / 2;
+	msg_outtrans_len_attr(longstr, slen, attr);
+	msg_puts_attr((char_u *)"...", hl_attr(HLF_8));
+    }
+    msg_outtrans_len_attr(longstr + len - slen, slen, attr);
+}
+
+/*
+ * Basic function for writing a message with highlight attributes.
+ */
+    void
+msg_puts_attr(s, attr)
+    char_u	*s;
+    int		attr;
+{
+    msg_puts_attr_len(s, -1, attr);
+}
+
+/*
+ * Like msg_puts_attr(), but with a maximum length "maxlen" (in bytes).
+ * When "maxlen" is -1 there is no maximum length.
+ * When "maxlen" is >= 0 the message is not put in the history.
+ */
+    static void
+msg_puts_attr_len(str, maxlen, attr)
+    char_u	*str;
+    int		maxlen;
+    int		attr;
+{
+    /*
+     * If redirection is on, also write to the redirection file.
+     */
+    redir_write(str, maxlen);
+
+    /*
+     * Don't print anything when using ":silent cmd".
+     */
+    if (msg_silent != 0)
+	return;
+
+    /* if MSG_HIST flag set, add message to history */
+    if ((attr & MSG_HIST) && maxlen < 0)
+    {
+	add_msg_hist(str, -1, attr);
+	attr &= ~MSG_HIST;
+    }
+
+    /*
+     * When writing something to the screen after it has scrolled, requires a
+     * wait-return prompt later.  Needed when scrolling, resetting
+     * need_wait_return after some prompt, and then outputting something
+     * without scrolling
+     */
+    if (msg_scrolled != 0 && !msg_scrolled_ign)
+	need_wait_return = TRUE;
+    msg_didany = TRUE;		/* remember that something was outputted */
+
+    /*
+     * If there is no valid screen, use fprintf so we can see error messages.
+     * If termcap is not active, we may be writing in an alternate console
+     * window, cursor positioning may not work correctly (window size may be
+     * different, e.g. for Win32 console) or we just don't know where the
+     * cursor is.
+     */
+    if (msg_use_printf())
+	msg_puts_printf(str, maxlen);
+    else
+	msg_puts_display(str, maxlen, attr, FALSE);
+}
+
+/*
+ * The display part of msg_puts_attr_len().
+ * May be called recursively to display scroll-back text.
+ */
+    static void
+msg_puts_display(str, maxlen, attr, recurse)
+    char_u	*str;
+    int		maxlen;
+    int		attr;
+    int		recurse;
+{
+    char_u	*s = str;
+    char_u	*t_s = str;	/* string from "t_s" to "s" is still todo */
+    int		t_col = 0;	/* screen cells todo, 0 when "t_s" not used */
+#ifdef FEAT_MBYTE
+    int		l;
+    int		cw;
+#endif
+    char_u	*sb_str = str;
+    int		sb_col = msg_col;
+    int		wrap;
+
+    did_wait_return = FALSE;
+    while (*s != NUL && (maxlen < 0 || (int)(s - str) < maxlen))
+    {
+	/*
+	 * We are at the end of the screen line when:
+	 * - When outputting a newline.
+	 * - When outputting a character in the last column.
+	 */
+	if (!recurse && msg_row >= Rows - 1 && (*s == '\n' || (
+#ifdef FEAT_RIGHTLEFT
+		    cmdmsg_rl
+		    ? (
+			msg_col <= 1
+			|| (*s == TAB && msg_col <= 7)
+# ifdef FEAT_MBYTE
+			|| (has_mbyte && (*mb_ptr2cells)(s) > 1 && msg_col <= 2)
+# endif
+		      )
+		    :
+#endif
+		      (msg_col + t_col >= Columns - 1
+		       || (*s == TAB && msg_col + t_col >= ((Columns - 1) & ~7))
+# ifdef FEAT_MBYTE
+		       || (has_mbyte && (*mb_ptr2cells)(s) > 1
+					    && msg_col + t_col >= Columns - 2)
+# endif
+		      ))))
+	{
+	    /*
+	     * The screen is scrolled up when at the last row (some terminals
+	     * scroll automatically, some don't.  To avoid problems we scroll
+	     * ourselves).
+	     */
+	    if (t_col > 0)
+		/* output postponed text */
+		t_puts(&t_col, t_s, s, attr);
+
+	    /* When no more prompt an no more room, truncate here */
+	    if (msg_no_more && lines_left == 0)
+		break;
+
+	    /* Scroll the screen up one line. */
+	    msg_scroll_up();
+
+	    msg_row = Rows - 2;
+	    if (msg_col >= Columns)	/* can happen after screen resize */
+		msg_col = Columns - 1;
+
+	    /* Display char in last column before showing more-prompt. */
+	    if (*s >= ' '
+#ifdef FEAT_RIGHTLEFT
+		    && !cmdmsg_rl
+#endif
+	       )
+	    {
+#ifdef FEAT_MBYTE
+		if (has_mbyte)
+		{
+		    if (enc_utf8 && maxlen >= 0)
+			/* avoid including composing chars after the end */
+			l = utfc_ptr2len_len(s, (int)((str + maxlen) - s));
+		    else
+			l = (*mb_ptr2len)(s);
+		    s = screen_puts_mbyte(s, l, attr);
+		}
+		else
+#endif
+		    msg_screen_putchar(*s++, attr);
+	    }
+
+	    if (p_more)
+		/* store text for scrolling back */
+		store_sb_text(&sb_str, s, attr, &sb_col, TRUE);
+
+	    inc_msg_scrolled();
+	    need_wait_return = TRUE; /* may need wait_return in main() */
+	    if (must_redraw < VALID)
+		must_redraw = VALID;
+	    redraw_cmdline = TRUE;
+	    if (cmdline_row > 0 && !exmode_active)
+		--cmdline_row;
+
+	    /*
+	     * If screen is completely filled and 'more' is set then wait
+	     * for a character.
+	     */
+	    --lines_left;
+	    if (p_more && lines_left == 0 && State != HITRETURN
+					    && !msg_no_more && !exmode_active)
+	    {
+#ifdef FEAT_CON_DIALOG
+		if (do_more_prompt(NUL))
+		    s = confirm_msg_tail;
+#else
+		(void)do_more_prompt(NUL);
+#endif
+		if (quit_more)
+		    return;
+	    }
+
+	    /* When we displayed a char in last column need to check if there
+	     * is still more. */
+	    if (*s >= ' '
+#ifdef FEAT_RIGHTLEFT
+		    && !cmdmsg_rl
+#endif
+	       )
+		continue;
+	}
+
+	wrap = *s == '\n'
+		    || msg_col + t_col >= Columns
+#ifdef FEAT_MBYTE
+		    || (has_mbyte && (*mb_ptr2cells)(s) > 1
+					    && msg_col + t_col >= Columns - 1)
+#endif
+		    ;
+	if (t_col > 0 && (wrap || *s == '\r' || *s == '\b'
+						 || *s == '\t' || *s == BELL))
+	    /* output any postponed text */
+	    t_puts(&t_col, t_s, s, attr);
+
+	if (wrap && p_more && !recurse)
+	    /* store text for scrolling back */
+	    store_sb_text(&sb_str, s, attr, &sb_col, TRUE);
+
+	if (*s == '\n')		    /* go to next line */
+	{
+	    msg_didout = FALSE;	    /* remember that line is empty */
+#ifdef FEAT_RIGHTLEFT
+	    if (cmdmsg_rl)
+		msg_col = Columns - 1;
+	    else
+#endif
+		msg_col = 0;
+	    if (++msg_row >= Rows)  /* safety check */
+		msg_row = Rows - 1;
+	}
+	else if (*s == '\r')	    /* go to column 0 */
+	{
+	    msg_col = 0;
+	}
+	else if (*s == '\b')	    /* go to previous char */
+	{
+	    if (msg_col)
+		--msg_col;
+	}
+	else if (*s == TAB)	    /* translate Tab into spaces */
+	{
+	    do
+		msg_screen_putchar(' ', attr);
+	    while (msg_col & 7);
+	}
+	else if (*s == BELL)	    /* beep (from ":sh") */
+	    vim_beep();
+	else
+	{
+#ifdef FEAT_MBYTE
+	    if (has_mbyte)
+	    {
+		cw = (*mb_ptr2cells)(s);
+		if (enc_utf8 && maxlen >= 0)
+		    /* avoid including composing chars after the end */
+		    l = utfc_ptr2len_len(s, (int)((str + maxlen) - s));
+		else
+		    l = (*mb_ptr2len)(s);
+	    }
+	    else
+	    {
+		cw = 1;
+		l = 1;
+	    }
+#endif
+	    /* When drawing from right to left or when a double-wide character
+	     * doesn't fit, draw a single character here.  Otherwise collect
+	     * characters and draw them all at once later. */
+#if defined(FEAT_RIGHTLEFT) || defined(FEAT_MBYTE)
+	    if (
+# ifdef FEAT_RIGHTLEFT
+		    cmdmsg_rl
+#  ifdef FEAT_MBYTE
+		    ||
+#  endif
+# endif
+# ifdef FEAT_MBYTE
+		    (cw > 1 && msg_col + t_col >= Columns - 1)
+# endif
+		    )
+	    {
+# ifdef FEAT_MBYTE
+		if (l > 1)
+		    s = screen_puts_mbyte(s, l, attr) - 1;
+		else
+# endif
+		    msg_screen_putchar(*s, attr);
+	    }
+	    else
+#endif
+	    {
+		/* postpone this character until later */
+		if (t_col == 0)
+		    t_s = s;
+#ifdef FEAT_MBYTE
+		t_col += cw;
+		s += l - 1;
+#else
+		++t_col;
+#endif
+	    }
+	}
+	++s;
+    }
+
+    /* output any postponed text */
+    if (t_col > 0)
+	t_puts(&t_col, t_s, s, attr);
+    if (p_more && !recurse)
+	store_sb_text(&sb_str, s, attr, &sb_col, FALSE);
+
+    msg_check();
+}
+
+/*
+ * Scroll the screen up one line for displaying the next message line.
+ */
+    static void
+msg_scroll_up()
+{
+#ifdef FEAT_GUI
+    /* Remove the cursor before scrolling, ScreenLines[] is going
+     * to become invalid. */
+    if (gui.in_use)
+	gui_undraw_cursor();
+#endif
+    /* scrolling up always works */
+    screen_del_lines(0, 0, 1, (int)Rows, TRUE, NULL);
+
+    if (!can_clear((char_u *)" "))
+    {
+	/* Scrolling up doesn't result in the right background.  Set the
+	 * background here.  It's not efficient, but avoids that we have to do
+	 * it all over the code. */
+	screen_fill((int)Rows - 1, (int)Rows, 0, (int)Columns, ' ', ' ', 0);
+
+	/* Also clear the last char of the last but one line if it was not
+	 * cleared before to avoid a scroll-up. */
+	if (ScreenAttrs[LineOffset[Rows - 2] + Columns - 1] == (sattr_T)-1)
+	    screen_fill((int)Rows - 2, (int)Rows - 1,
+				 (int)Columns - 1, (int)Columns, ' ', ' ', 0);
+    }
+}
+
+/*
+ * Increment "msg_scrolled".
+ */
+    static void
+inc_msg_scrolled()
+{
+#ifdef FEAT_EVAL
+    if (*get_vim_var_str(VV_SCROLLSTART) == NUL)
+    {
+	char_u	    *p = sourcing_name;
+	char_u	    *tofree = NULL;
+	int	    len;
+
+	/* v:scrollstart is empty, set it to the script/function name and line
+	 * number */
+	if (p == NULL)
+	    p = (char_u *)_("Unknown");
+	else
+	{
+	    len = (int)STRLEN(p) + 40;
+	    tofree = alloc(len);
+	    if (tofree != NULL)
+	    {
+		vim_snprintf((char *)tofree, len, _("%s line %ld"),
+						      p, (long)sourcing_lnum);
+		p = tofree;
+	    }
+	}
+	set_vim_var_string(VV_SCROLLSTART, p, -1);
+	vim_free(tofree);
+    }
+#endif
+    ++msg_scrolled;
+}
+
+/*
+ * To be able to scroll back at the "more" and "hit-enter" prompts we need to
+ * store the displayed text and remember where screen lines start.
+ */
+typedef struct msgchunk_S msgchunk_T;
+struct msgchunk_S
+{
+    msgchunk_T	*sb_next;
+    msgchunk_T	*sb_prev;
+    char	sb_eol;		/* TRUE when line ends after this text */
+    int		sb_msg_col;	/* column in which text starts */
+    int		sb_attr;	/* text attributes */
+    char_u	sb_text[1];	/* text to be displayed, actually longer */
+};
+
+static msgchunk_T *last_msgchunk = NULL; /* last displayed text */
+
+static msgchunk_T *msg_sb_start __ARGS((msgchunk_T *mps));
+static msgchunk_T *disp_sb_line __ARGS((int row, msgchunk_T *smp));
+
+static int do_clear_sb_text = FALSE;	/* clear text on next msg */
+
+/*
+ * Store part of a printed message for displaying when scrolling back.
+ */
+    static void
+store_sb_text(sb_str, s, attr, sb_col, finish)
+    char_u	**sb_str;	/* start of string */
+    char_u	*s;		/* just after string */
+    int		attr;
+    int		*sb_col;
+    int		finish;		/* line ends */
+{
+    msgchunk_T	*mp;
+
+    if (do_clear_sb_text)
+    {
+	clear_sb_text();
+	do_clear_sb_text = FALSE;
+    }
+
+    if (s > *sb_str)
+    {
+	mp = (msgchunk_T *)alloc((int)(sizeof(msgchunk_T) + (s - *sb_str)));
+	if (mp != NULL)
+	{
+	    mp->sb_eol = finish;
+	    mp->sb_msg_col = *sb_col;
+	    mp->sb_attr = attr;
+	    vim_strncpy(mp->sb_text, *sb_str, s - *sb_str);
+
+	    if (last_msgchunk == NULL)
+	    {
+		last_msgchunk = mp;
+		mp->sb_prev = NULL;
+	    }
+	    else
+	    {
+		mp->sb_prev = last_msgchunk;
+		last_msgchunk->sb_next = mp;
+		last_msgchunk = mp;
+	    }
+	    mp->sb_next = NULL;
+	}
+    }
+    else if (finish && last_msgchunk != NULL)
+	last_msgchunk->sb_eol = TRUE;
+
+    *sb_str = s;
+    *sb_col = 0;
+}
+
+/*
+ * Finished showing messages, clear the scroll-back text on the next message.
+ */
+    void
+may_clear_sb_text()
+{
+    do_clear_sb_text = TRUE;
+}
+
+/*
+ * Clear any text remembered for scrolling back.
+ * Called when redrawing the screen.
+ */
+    void
+clear_sb_text()
+{
+    msgchunk_T	*mp;
+
+    while (last_msgchunk != NULL)
+    {
+	mp = last_msgchunk->sb_prev;
+	vim_free(last_msgchunk);
+	last_msgchunk = mp;
+    }
+}
+
+/*
+ * "g<" command.
+ */
+    void
+show_sb_text()
+{
+    msgchunk_T	*mp;
+
+    /* Only show somethign if there is more than one line, otherwise it looks
+     * weird, typing a command without output results in one line. */
+    mp = msg_sb_start(last_msgchunk);
+    if (mp == NULL || mp->sb_prev == NULL)
+	vim_beep();
+    else
+    {
+	do_more_prompt('G');
+	wait_return(FALSE);
+    }
+}
+
+/*
+ * Move to the start of screen line in already displayed text.
+ */
+    static msgchunk_T *
+msg_sb_start(mps)
+    msgchunk_T *mps;
+{
+    msgchunk_T *mp = mps;
+
+    while (mp != NULL && mp->sb_prev != NULL && !mp->sb_prev->sb_eol)
+	mp = mp->sb_prev;
+    return mp;
+}
+
+/*
+ * Display a screen line from previously displayed text at row "row".
+ * Returns a pointer to the text for the next line (can be NULL).
+ */
+    static msgchunk_T *
+disp_sb_line(row, smp)
+    int		row;
+    msgchunk_T	*smp;
+{
+    msgchunk_T	*mp = smp;
+    char_u	*p;
+
+    for (;;)
+    {
+	msg_row = row;
+	msg_col = mp->sb_msg_col;
+	p = mp->sb_text;
+	if (*p == '\n')	    /* don't display the line break */
+	    ++p;
+	msg_puts_display(p, -1, mp->sb_attr, TRUE);
+	if (mp->sb_eol || mp->sb_next == NULL)
+	    break;
+	mp = mp->sb_next;
+    }
+    return mp->sb_next;
+}
+
+/*
+ * Output any postponed text for msg_puts_attr_len().
+ */
+    static void
+t_puts(t_col, t_s, s, attr)
+    int		*t_col;
+    char_u	*t_s;
+    char_u	*s;
+    int		attr;
+{
+    /* output postponed text */
+    msg_didout = TRUE;		/* remember that line is not empty */
+    screen_puts_len(t_s, (int)(s - t_s), msg_row, msg_col, attr);
+    msg_col += *t_col;
+    *t_col = 0;
+#ifdef FEAT_MBYTE
+    /* If the string starts with a composing character don't increment the
+     * column position for it. */
+    if (enc_utf8 && utf_iscomposing(utf_ptr2char(t_s)))
+	--msg_col;
+#endif
+    if (msg_col >= Columns)
+    {
+	msg_col = 0;
+	++msg_row;
+    }
+}
+
+/*
+ * Returns TRUE when messages should be printed with mch_errmsg().
+ * This is used when there is no valid screen, so we can see error messages.
+ * If termcap is not active, we may be writing in an alternate console
+ * window, cursor positioning may not work correctly (window size may be
+ * different, e.g. for Win32 console) or we just don't know where the
+ * cursor is.
+ */
+    int
+msg_use_printf()
+{
+    return (!msg_check_screen()
+#if defined(WIN3264) && !defined(FEAT_GUI_MSWIN)
+	    || !termcap_active
+#endif
+	    || (swapping_screen() && !termcap_active)
+	       );
+}
+
+/*
+ * Print a message when there is no valid screen.
+ */
+    static void
+msg_puts_printf(str, maxlen)
+    char_u	*str;
+    int		maxlen;
+{
+    char_u	*s = str;
+    char_u	buf[4];
+    char_u	*p;
+
+#ifdef WIN3264
+    if (!(silent_mode && p_verbose == 0))
+	mch_settmode(TMODE_COOK);	/* handle '\r' and '\n' correctly */
+#endif
+    while (*s != NUL && (maxlen < 0 || (int)(s - str) < maxlen))
+    {
+	if (!(silent_mode && p_verbose == 0))
+	{
+	    /* NL --> CR NL translation (for Unix, not for "--version") */
+	    /* NL --> CR translation (for Mac) */
+	    p = &buf[0];
+	    if (*s == '\n' && !info_message)
+		*p++ = '\r';
+#if defined(USE_CR) && !defined(MACOS_X_UNIX)
+	    else
+#endif
+		*p++ = *s;
+	    *p = '\0';
+	    if (info_message)	/* informative message, not an error */
+		mch_msg((char *)buf);
+	    else
+		mch_errmsg((char *)buf);
+	}
+
+	/* primitive way to compute the current column */
+#ifdef FEAT_RIGHTLEFT
+	if (cmdmsg_rl)
+	{
+	    if (*s == '\r' || *s == '\n')
+		msg_col = Columns - 1;
+	    else
+		--msg_col;
+	}
+	else
+#endif
+	{
+	    if (*s == '\r' || *s == '\n')
+		msg_col = 0;
+	    else
+		++msg_col;
+	}
+	++s;
+    }
+    msg_didout = TRUE;	    /* assume that line is not empty */
+
+#ifdef WIN3264
+    if (!(silent_mode && p_verbose == 0))
+	mch_settmode(TMODE_RAW);
+#endif
+}
+
+/*
+ * Show the more-prompt and handle the user response.
+ * This takes care of scrolling back and displaying previously displayed text.
+ * When at hit-enter prompt "typed_char" is the already typed character,
+ * otherwise it's NUL.
+ * Returns TRUE when jumping ahead to "confirm_msg_tail".
+ */
+    static int
+do_more_prompt(typed_char)
+    int		typed_char;
+{
+    int		used_typed_char = typed_char;
+    int		oldState = State;
+    int		c;
+#ifdef FEAT_CON_DIALOG
+    int		retval = FALSE;
+#endif
+    int		scroll;
+    msgchunk_T	*mp_last = NULL;
+    msgchunk_T	*mp;
+    int		i;
+
+    if (typed_char == 'G')
+    {
+	/* "g<": Find first line on the last page. */
+	mp_last = msg_sb_start(last_msgchunk);
+	for (i = 0; i < Rows - 2 && mp_last != NULL
+					     && mp_last->sb_prev != NULL; ++i)
+	    mp_last = msg_sb_start(mp_last->sb_prev);
+    }
+
+    State = ASKMORE;
+#ifdef FEAT_MOUSE
+    setmouse();
+#endif
+    if (typed_char == NUL)
+	msg_moremsg(FALSE);
+    for (;;)
+    {
+	/*
+	 * Get a typed character directly from the user.
+	 */
+	if (used_typed_char != NUL)
+	{
+	    c = used_typed_char;	/* was typed at hit-enter prompt */
+	    used_typed_char = NUL;
+	}
+	else
+	    c = get_keystroke();
+
+#if defined(FEAT_MENU) && defined(FEAT_GUI)
+	if (c == K_MENU)
+	{
+	    int idx = get_menu_index(current_menu, ASKMORE);
+
+	    /* Used a menu.  If it starts with CTRL-Y, it must
+	     * be a "Copy" for the clipboard.  Otherwise
+	     * assume that we end */
+	    if (idx == MENU_INDEX_INVALID)
+		continue;
+	    c = *current_menu->strings[idx];
+	    if (c != NUL && current_menu->strings[idx][1] != NUL)
+		ins_typebuf(current_menu->strings[idx] + 1,
+				current_menu->noremap[idx], 0, TRUE,
+						   current_menu->silent[idx]);
+	}
+#endif
+
+	scroll = 0;
+	switch (c)
+	{
+	case BS:		/* scroll one line back */
+	case K_BS:
+	case 'k':
+	case K_UP:
+	    scroll = -1;
+	    break;
+
+	case CAR:		/* one extra line */
+	case NL:
+	case 'j':
+	case K_DOWN:
+	    scroll = 1;
+	    break;
+
+	case 'u':		/* Up half a page */
+	case K_PAGEUP:
+	    scroll = -(Rows / 2);
+	    break;
+
+	case 'd':		/* Down half a page */
+	    scroll = Rows / 2;
+	    break;
+
+	case 'b':		/* one page back */
+	    scroll = -(Rows - 1);
+	    break;
+
+	case ' ':		/* one extra page */
+	case K_PAGEDOWN:
+	case K_LEFTMOUSE:
+	    scroll = Rows - 1;
+	    break;
+
+	case 'g':		/* all the way back to the start */
+	    scroll = -999999;
+	    break;
+
+	case 'G':		/* all the way to the end */
+	    scroll = 999999;
+	    lines_left = 999999;
+	    break;
+
+	case ':':		/* start new command line */
+#ifdef FEAT_CON_DIALOG
+	    if (!confirm_msg_used)
+#endif
+	    {
+		/* Since got_int is set all typeahead will be flushed, but we
+		 * want to keep this ':', remember that in a special way. */
+		typeahead_noflush(':');
+		cmdline_row = Rows - 1;		/* put ':' on this line */
+		skip_redraw = TRUE;		/* skip redraw once */
+		need_wait_return = FALSE;	/* don't wait in main() */
+	    }
+	    /*FALLTHROUGH*/
+	case 'q':		/* quit */
+	case Ctrl_C:
+	case ESC:
+#ifdef FEAT_CON_DIALOG
+	    if (confirm_msg_used)
+	    {
+		/* Jump to the choices of the dialog. */
+		retval = TRUE;
+		lines_left = Rows - 1;
+	    }
+	    else
+#endif
+	    {
+		got_int = TRUE;
+		quit_more = TRUE;
+	    }
+	    break;
+
+#ifdef FEAT_CLIPBOARD
+	case Ctrl_Y:
+	    /* Strange way to allow copying (yanking) a modeless
+	     * selection at the more prompt.  Use CTRL-Y,
+	     * because the same is used in Cmdline-mode and at the
+	     * hit-enter prompt.  However, scrolling one line up
+	     * might be expected... */
+	    if (clip_star.state == SELECT_DONE)
+		clip_copy_modeless_selection(TRUE);
+	    continue;
+#endif
+	default:		/* no valid response */
+	    msg_moremsg(TRUE);
+	    continue;
+	}
+
+	if (scroll != 0)
+	{
+	    if (scroll < 0)
+	    {
+		/* go to start of last line */
+		if (mp_last == NULL)
+		    mp = msg_sb_start(last_msgchunk);
+		else if (mp_last->sb_prev != NULL)
+		    mp = msg_sb_start(mp_last->sb_prev);
+		else
+		    mp = NULL;
+
+		/* go to start of line at top of the screen */
+		for (i = 0; i < Rows - 2 && mp != NULL && mp->sb_prev != NULL;
+									  ++i)
+		    mp = msg_sb_start(mp->sb_prev);
+
+		if (mp != NULL && mp->sb_prev != NULL)
+		{
+		    /* Find line to be displayed at top. */
+		    for (i = 0; i > scroll; --i)
+		    {
+			if (mp == NULL || mp->sb_prev == NULL)
+			    break;
+			mp = msg_sb_start(mp->sb_prev);
+			if (mp_last == NULL)
+			    mp_last = msg_sb_start(last_msgchunk);
+			else
+			    mp_last = msg_sb_start(mp_last->sb_prev);
+		    }
+
+		    if (scroll == -1 && screen_ins_lines(0, 0, 1,
+						       (int)Rows, NULL) == OK)
+		    {
+			/* display line at top */
+			(void)disp_sb_line(0, mp);
+		    }
+		    else
+		    {
+			/* redisplay all lines */
+			screenclear();
+			for (i = 0; mp != NULL && i < Rows - 1; ++i)
+			{
+			    mp = disp_sb_line(i, mp);
+			    ++msg_scrolled;
+			}
+		    }
+		    scroll = 0;
+		}
+	    }
+	    else
+	    {
+		/* First display any text that we scrolled back. */
+		while (scroll > 0 && mp_last != NULL)
+		{
+		    /* scroll up, display line at bottom */
+		    msg_scroll_up();
+		    inc_msg_scrolled();
+		    screen_fill((int)Rows - 2, (int)Rows - 1, 0,
+						   (int)Columns, ' ', ' ', 0);
+		    mp_last = disp_sb_line((int)Rows - 2, mp_last);
+		    --scroll;
+		}
+	    }
+
+	    if (scroll < 0 || (scroll == 0 && mp_last != NULL))
+	    {
+		/* displayed the requested text, more prompt again */
+		screen_fill((int)Rows - 1, (int)Rows, 0,
+						   (int)Columns, ' ', ' ', 0);
+		msg_moremsg(FALSE);
+		continue;
+	    }
+
+	    /* display more text, return to caller */
+	    lines_left = scroll;
+	}
+
+	break;
+    }
+
+    /* clear the --more-- message */
+    screen_fill((int)Rows - 1, (int)Rows, 0, (int)Columns, ' ', ' ', 0);
+    State = oldState;
+#ifdef FEAT_MOUSE
+    setmouse();
+#endif
+    if (quit_more)
+    {
+	msg_row = Rows - 1;
+	msg_col = 0;
+    }
+#ifdef FEAT_RIGHTLEFT
+    else if (cmdmsg_rl)
+	msg_col = Columns - 1;
+#endif
+
+#ifdef FEAT_CON_DIALOG
+    return retval;
+#else
+    return FALSE;
+#endif
+}
+
+#if defined(USE_MCH_ERRMSG) || defined(PROTO)
+
+#ifdef mch_errmsg
+# undef mch_errmsg
+#endif
+#ifdef mch_msg
+# undef mch_msg
+#endif
+
+/*
+ * Give an error message.  To be used when the screen hasn't been initialized
+ * yet.  When stderr can't be used, collect error messages until the GUI has
+ * started and they can be displayed in a message box.
+ */
+    void
+mch_errmsg(str)
+    char	*str;
+{
+    int		len;
+
+#if (defined(UNIX) || defined(FEAT_GUI)) && !defined(ALWAYS_USE_GUI)
+    /* On Unix use stderr if it's a tty.
+     * When not going to start the GUI also use stderr.
+     * On Mac, when started from Finder, stderr is the console. */
+    if (
+# ifdef UNIX
+#  ifdef MACOS_X_UNIX
+	    (isatty(2) && strcmp("/dev/console", ttyname(2)) != 0)
+#  else
+	    isatty(2)
+#  endif
+#  ifdef FEAT_GUI
+	    ||
+#  endif
+# endif
+# ifdef FEAT_GUI
+	    !(gui.in_use || gui.starting)
+# endif
+	    )
+    {
+	fprintf(stderr, "%s", str);
+	return;
+    }
+#endif
+
+    /* avoid a delay for a message that isn't there */
+    emsg_on_display = FALSE;
+
+    len = (int)STRLEN(str) + 1;
+    if (error_ga.ga_growsize == 0)
+    {
+	error_ga.ga_growsize = 80;
+	error_ga.ga_itemsize = 1;
+    }
+    if (ga_grow(&error_ga, len) == OK)
+    {
+	mch_memmove((char_u *)error_ga.ga_data + error_ga.ga_len,
+							  (char_u *)str, len);
+#ifdef UNIX
+	/* remove CR characters, they are displayed */
+	{
+	    char_u	*p;
+
+	    p = (char_u *)error_ga.ga_data + error_ga.ga_len;
+	    for (;;)
+	    {
+		p = vim_strchr(p, '\r');
+		if (p == NULL)
+		    break;
+		*p = ' ';
+	    }
+	}
+#endif
+	--len;		/* don't count the NUL at the end */
+	error_ga.ga_len += len;
+    }
+}
+
+/*
+ * Give a message.  To be used when the screen hasn't been initialized yet.
+ * When there is no tty, collect messages until the GUI has started and they
+ * can be displayed in a message box.
+ */
+    void
+mch_msg(str)
+    char	*str;
+{
+#if (defined(UNIX) || defined(FEAT_GUI)) && !defined(ALWAYS_USE_GUI)
+    /* On Unix use stdout if we have a tty.  This allows "vim -h | more" and
+     * uses mch_errmsg() when started from the desktop.
+     * When not going to start the GUI also use stdout.
+     * On Mac, when started from Finder, stderr is the console. */
+    if (
+#  ifdef UNIX
+#   ifdef MACOS_X_UNIX
+	    (isatty(2) && strcmp("/dev/console", ttyname(2)) != 0)
+#   else
+	    isatty(2)
+#    endif
+#   ifdef FEAT_GUI
+	    ||
+#   endif
+#  endif
+#  ifdef FEAT_GUI
+	    !(gui.in_use || gui.starting)
+#  endif
+	    )
+    {
+	printf("%s", str);
+	return;
+    }
+# endif
+    mch_errmsg(str);
+}
+#endif /* USE_MCH_ERRMSG */
+
+/*
+ * Put a character on the screen at the current message position and advance
+ * to the next position.  Only for printable ASCII!
+ */
+    static void
+msg_screen_putchar(c, attr)
+    int		c;
+    int		attr;
+{
+    msg_didout = TRUE;		/* remember that line is not empty */
+    screen_putchar(c, msg_row, msg_col, attr);
+#ifdef FEAT_RIGHTLEFT
+    if (cmdmsg_rl)
+    {
+	if (--msg_col == 0)
+	{
+	    msg_col = Columns;
+	    ++msg_row;
+	}
+    }
+    else
+#endif
+    {
+	if (++msg_col >= Columns)
+	{
+	    msg_col = 0;
+	    ++msg_row;
+	}
+    }
+}
+
+    void
+msg_moremsg(full)
+    int	    full;
+{
+    int		attr;
+    char_u	*s = (char_u *)_("-- More --");
+
+    attr = hl_attr(HLF_M);
+    screen_puts(s, (int)Rows - 1, 0, attr);
+    if (full)
+	screen_puts((char_u *)
+		_(" SPACE/d/j: screen/page/line down, b/u/k: up, q: quit "),
+		(int)Rows - 1, vim_strsize(s), attr);
+}
+
+/*
+ * Repeat the message for the current mode: ASKMORE, EXTERNCMD, CONFIRM or
+ * exmode_active.
+ */
+    void
+repeat_message()
+{
+    if (State == ASKMORE)
+    {
+	msg_moremsg(TRUE);	/* display --more-- message again */
+	msg_row = Rows - 1;
+    }
+#ifdef FEAT_CON_DIALOG
+    else if (State == CONFIRM)
+    {
+	display_confirm_msg();	/* display ":confirm" message again */
+	msg_row = Rows - 1;
+    }
+#endif
+    else if (State == EXTERNCMD)
+    {
+	windgoto(msg_row, msg_col); /* put cursor back */
+    }
+    else if (State == HITRETURN || State == SETWSIZE)
+    {
+	hit_return_msg();
+	msg_row = Rows - 1;
+    }
+}
+
+/*
+ * msg_check_screen - check if the screen is initialized.
+ * Also check msg_row and msg_col, if they are too big it may cause a crash.
+ * While starting the GUI the terminal codes will be set for the GUI, but the
+ * output goes to the terminal.  Don't use the terminal codes then.
+ */
+    static int
+msg_check_screen()
+{
+    if (!full_screen || !screen_valid(FALSE))
+	return FALSE;
+
+    if (msg_row >= Rows)
+	msg_row = Rows - 1;
+    if (msg_col >= Columns)
+	msg_col = Columns - 1;
+    return TRUE;
+}
+
+/*
+ * Clear from current message position to end of screen.
+ * Skip this when ":silent" was used, no need to clear for redirection.
+ */
+    void
+msg_clr_eos()
+{
+    if (msg_silent == 0)
+	msg_clr_eos_force();
+}
+
+/*
+ * Clear from current message position to end of screen.
+ * Note: msg_col is not updated, so we remember the end of the message
+ * for msg_check().
+ */
+    void
+msg_clr_eos_force()
+{
+    if (msg_use_printf())
+    {
+	if (full_screen)	/* only when termcap codes are valid */
+	{
+	    if (*T_CD)
+		out_str(T_CD);	/* clear to end of display */
+	    else if (*T_CE)
+		out_str(T_CE);	/* clear to end of line */
+	}
+    }
+    else
+    {
+#ifdef FEAT_RIGHTLEFT
+	if (cmdmsg_rl)
+	{
+	    screen_fill(msg_row, msg_row + 1, 0, msg_col + 1, ' ', ' ', 0);
+	    screen_fill(msg_row + 1, (int)Rows, 0, (int)Columns, ' ', ' ', 0);
+	}
+	else
+#endif
+	{
+	    screen_fill(msg_row, msg_row + 1, msg_col, (int)Columns,
+								 ' ', ' ', 0);
+	    screen_fill(msg_row + 1, (int)Rows, 0, (int)Columns, ' ', ' ', 0);
+	}
+    }
+}
+
+/*
+ * Clear the command line.
+ */
+    void
+msg_clr_cmdline()
+{
+    msg_row = cmdline_row;
+    msg_col = 0;
+    msg_clr_eos_force();
+}
+
+/*
+ * end putting a message on the screen
+ * call wait_return if the message does not fit in the available space
+ * return TRUE if wait_return not called.
+ */
+    int
+msg_end()
+{
+    /*
+     * if the string is larger than the window,
+     * or the ruler option is set and we run into it,
+     * we have to redraw the window.
+     * Do not do this if we are abandoning the file or editing the command line.
+     */
+    if (!exiting && need_wait_return && !(State & CMDLINE))
+    {
+	wait_return(FALSE);
+	return FALSE;
+    }
+    out_flush();
+    return TRUE;
+}
+
+/*
+ * If the written message runs into the shown command or ruler, we have to
+ * wait for hit-return and redraw the window later.
+ */
+    void
+msg_check()
+{
+    if (msg_row == Rows - 1 && msg_col >= sc_col)
+    {
+	need_wait_return = TRUE;
+	redraw_cmdline = TRUE;
+    }
+}
+
+/*
+ * May write a string to the redirection file.
+ * When "maxlen" is -1 write the whole string, otherwise up to "maxlen" bytes.
+ */
+    static void
+redir_write(str, maxlen)
+    char_u	*str;
+    int		maxlen;
+{
+    char_u	*s = str;
+    static int	cur_col = 0;
+
+    /* Don't do anything for displaying prompts and the like. */
+    if (redir_off)
+	return;
+
+    /*
+     * If 'verbosefile' is set write message in that file.
+     * Must come before the rest because of updating "msg_col".
+     */
+    if (*p_vfile != NUL)
+	verbose_write(s, maxlen);
+
+    if (redir_fd != NULL
+#ifdef FEAT_EVAL
+			  || redir_reg || redir_vname
+#endif
+				       )
+    {
+	/* If the string doesn't start with CR or NL, go to msg_col */
+	if (*s != '\n' && *s != '\r')
+	{
+	    while (cur_col < msg_col)
+	    {
+#ifdef FEAT_EVAL
+		if (redir_reg)
+		    write_reg_contents(redir_reg, (char_u *)" ", -1, TRUE);
+		else if (redir_vname)
+		    var_redir_str((char_u *)" ", -1);
+		else if (redir_fd)
+#endif
+		    fputs(" ", redir_fd);
+		++cur_col;
+	    }
+	}
+
+#ifdef FEAT_EVAL
+	if (redir_reg)
+	    write_reg_contents(redir_reg, s, maxlen, TRUE);
+	if (redir_vname)
+	    var_redir_str(s, maxlen);
+#endif
+
+	/* Adjust the current column */
+	while (*s != NUL && (maxlen < 0 || (int)(s - str) < maxlen))
+	{
+#ifdef FEAT_EVAL
+	    if (!redir_reg && !redir_vname && redir_fd != NULL)
+#endif
+		putc(*s, redir_fd);
+	    if (*s == '\r' || *s == '\n')
+		cur_col = 0;
+	    else if (*s == '\t')
+		cur_col += (8 - cur_col % 8);
+	    else
+		++cur_col;
+	    ++s;
+	}
+
+	if (msg_silent != 0)	/* should update msg_col */
+	    msg_col = cur_col;
+    }
+}
+
+/*
+ * Before giving verbose message.
+ * Must always be called paired with verbose_leave()!
+ */
+    void
+verbose_enter()
+{
+    if (*p_vfile != NUL)
+	++msg_silent;
+}
+
+/*
+ * After giving verbose message.
+ * Must always be called paired with verbose_enter()!
+ */
+    void
+verbose_leave()
+{
+    if (*p_vfile != NUL)
+	if (--msg_silent < 0)
+	    msg_silent = 0;
+}
+
+/*
+ * Like verbose_enter() and set msg_scroll when displaying the message.
+ */
+    void
+verbose_enter_scroll()
+{
+    if (*p_vfile != NUL)
+	++msg_silent;
+    else
+	/* always scroll up, don't overwrite */
+	msg_scroll = TRUE;
+}
+
+/*
+ * Like verbose_leave() and set cmdline_row when displaying the message.
+ */
+    void
+verbose_leave_scroll()
+{
+    if (*p_vfile != NUL)
+    {
+	if (--msg_silent < 0)
+	    msg_silent = 0;
+    }
+    else
+	cmdline_row = msg_row;
+}
+
+static FILE *verbose_fd = NULL;
+static int  verbose_did_open = FALSE;
+
+/*
+ * Called when 'verbosefile' is set: stop writing to the file.
+ */
+    void
+verbose_stop()
+{
+    if (verbose_fd != NULL)
+    {
+	fclose(verbose_fd);
+	verbose_fd = NULL;
+    }
+    verbose_did_open = FALSE;
+}
+
+/*
+ * Open the file 'verbosefile'.
+ * Return FAIL or OK.
+ */
+    int
+verbose_open()
+{
+    if (verbose_fd == NULL && !verbose_did_open)
+    {
+	/* Only give the error message once. */
+	verbose_did_open = TRUE;
+
+	verbose_fd = mch_fopen((char *)p_vfile, "a");
+	if (verbose_fd == NULL)
+	{
+	    EMSG2(_(e_notopen), p_vfile);
+	    return FAIL;
+	}
+    }
+    return OK;
+}
+
+/*
+ * Write a string to 'verbosefile'.
+ * When "maxlen" is -1 write the whole string, otherwise up to "maxlen" bytes.
+ */
+    static void
+verbose_write(str, maxlen)
+    char_u	*str;
+    int		maxlen;
+{
+    char_u	*s = str;
+    static int	cur_col = 0;
+
+    /* Open the file when called the first time. */
+    if (verbose_fd == NULL)
+	verbose_open();
+
+    if (verbose_fd != NULL)
+    {
+	/* If the string doesn't start with CR or NL, go to msg_col */
+	if (*s != '\n' && *s != '\r')
+	{
+	    while (cur_col < msg_col)
+	    {
+		fputs(" ", verbose_fd);
+		++cur_col;
+	    }
+	}
+
+	/* Adjust the current column */
+	while (*s != NUL && (maxlen < 0 || (int)(s - str) < maxlen))
+	{
+	    putc(*s, verbose_fd);
+	    if (*s == '\r' || *s == '\n')
+		cur_col = 0;
+	    else if (*s == '\t')
+		cur_col += (8 - cur_col % 8);
+	    else
+		++cur_col;
+	    ++s;
+	}
+    }
+}
+
+/*
+ * Give a warning message (for searching).
+ * Use 'w' highlighting and may repeat the message after redrawing
+ */
+    void
+give_warning(message, hl)
+    char_u  *message;
+    int	    hl;
+{
+    /* Don't do this for ":silent". */
+    if (msg_silent != 0)
+	return;
+
+    /* Don't want a hit-enter prompt here. */
+    ++no_wait_return;
+
+#ifdef FEAT_EVAL
+    set_vim_var_string(VV_WARNINGMSG, message, -1);
+#endif
+    vim_free(keep_msg);
+    keep_msg = NULL;
+    if (hl)
+	keep_msg_attr = hl_attr(HLF_W);
+    else
+	keep_msg_attr = 0;
+    if (msg_attr(message, keep_msg_attr) && msg_scrolled == 0)
+	set_keep_msg(message, keep_msg_attr);
+    msg_didout = FALSE;	    /* overwrite this message */
+    msg_nowait = TRUE;	    /* don't wait for this message */
+    msg_col = 0;
+
+    --no_wait_return;
+}
+
+/*
+ * Advance msg cursor to column "col".
+ */
+    void
+msg_advance(col)
+    int	    col;
+{
+    if (msg_silent != 0)	/* nothing to advance to */
+    {
+	msg_col = col;		/* for redirection, may fill it up later */
+	return;
+    }
+    if (col >= Columns)		/* not enough room */
+	col = Columns - 1;
+#ifdef FEAT_RIGHTLEFT
+    if (cmdmsg_rl)
+	while (msg_col > Columns - col)
+	    msg_putchar(' ');
+    else
+#endif
+	while (msg_col < col)
+	    msg_putchar(' ');
+}
+
+#if defined(FEAT_CON_DIALOG) || defined(PROTO)
+/*
+ * Used for "confirm()" function, and the :confirm command prefix.
+ * Versions which haven't got flexible dialogs yet, and console
+ * versions, get this generic handler which uses the command line.
+ *
+ * type  = one of:
+ *	   VIM_QUESTION, VIM_INFO, VIM_WARNING, VIM_ERROR or VIM_GENERIC
+ * title = title string (can be NULL for default)
+ * (neither used in console dialogs at the moment)
+ *
+ * Format of the "buttons" string:
+ * "Button1Name\nButton2Name\nButton3Name"
+ * The first button should normally be the default/accept
+ * The second button should be the 'Cancel' button
+ * Other buttons- use your imagination!
+ * A '&' in a button name becomes a shortcut, so each '&' should be before a
+ * different letter.
+ */
+/* ARGSUSED */
+    int
+do_dialog(type, title, message, buttons, dfltbutton, textfield)
+    int		type;
+    char_u	*title;
+    char_u	*message;
+    char_u	*buttons;
+    int		dfltbutton;
+    char_u	*textfield;	/* IObuff for inputdialog(), NULL otherwise */
+{
+    int		oldState;
+    int		retval = 0;
+    char_u	*hotkeys;
+    int		c;
+    int		i;
+
+#ifndef NO_CONSOLE
+    /* Don't output anything in silent mode ("ex -s") */
+    if (silent_mode)
+	return dfltbutton;   /* return default option */
+#endif
+
+#ifdef FEAT_GUI_DIALOG
+    /* When GUI is running and 'c' not in 'guioptions', use the GUI dialog */
+    if (gui.in_use && vim_strchr(p_go, GO_CONDIALOG) == NULL)
+    {
+	c = gui_mch_dialog(type, title, message, buttons, dfltbutton,
+								   textfield);
+	msg_end_prompt();
+
+	/* Flush output to avoid that further messages and redrawing is done
+	 * in the wrong order. */
+	out_flush();
+	gui_mch_update();
+
+	return c;
+    }
+#endif
+
+    oldState = State;
+    State = CONFIRM;
+#ifdef FEAT_MOUSE
+    setmouse();
+#endif
+
+    /*
+     * Since we wait for a keypress, don't make the
+     * user press RETURN as well afterwards.
+     */
+    ++no_wait_return;
+    hotkeys = msg_show_console_dialog(message, buttons, dfltbutton);
+
+    if (hotkeys != NULL)
+    {
+	for (;;)
+	{
+	    /* Get a typed character directly from the user. */
+	    c = get_keystroke();
+	    switch (c)
+	    {
+	    case CAR:		/* User accepts default option */
+	    case NL:
+		retval = dfltbutton;
+		break;
+	    case Ctrl_C:	/* User aborts/cancels */
+	    case ESC:
+		retval = 0;
+		break;
+	    default:		/* Could be a hotkey? */
+		if (c < 0)	/* special keys are ignored here */
+		    continue;
+		/* Make the character lowercase, as chars in "hotkeys" are. */
+		c = MB_TOLOWER(c);
+		retval = 1;
+		for (i = 0; hotkeys[i]; ++i)
+		{
+#ifdef FEAT_MBYTE
+		    if (has_mbyte)
+		    {
+			if ((*mb_ptr2char)(hotkeys + i) == c)
+			    break;
+			i += (*mb_ptr2len)(hotkeys + i) - 1;
+		    }
+		    else
+#endif
+			if (hotkeys[i] == c)
+			    break;
+		    ++retval;
+		}
+		if (hotkeys[i])
+		    break;
+		/* No hotkey match, so keep waiting */
+		continue;
+	    }
+	    break;
+	}
+
+	vim_free(hotkeys);
+    }
+
+    State = oldState;
+#ifdef FEAT_MOUSE
+    setmouse();
+#endif
+    --no_wait_return;
+    msg_end_prompt();
+
+    return retval;
+}
+
+static int copy_char __ARGS((char_u *from, char_u *to, int lowercase));
+
+/*
+ * Copy one character from "*from" to "*to", taking care of multi-byte
+ * characters.  Return the length of the character in bytes.
+ */
+    static int
+copy_char(from, to, lowercase)
+    char_u	*from;
+    char_u	*to;
+    int		lowercase;	/* make character lower case */
+{
+#ifdef FEAT_MBYTE
+    int		len;
+    int		c;
+
+    if (has_mbyte)
+    {
+	if (lowercase)
+	{
+	    c = MB_TOLOWER((*mb_ptr2char)(from));
+	    return (*mb_char2bytes)(c, to);
+	}
+	else
+	{
+	    len = (*mb_ptr2len)(from);
+	    mch_memmove(to, from, (size_t)len);
+	    return len;
+	}
+    }
+    else
+#endif
+    {
+	if (lowercase)
+	    *to = (char_u)TOLOWER_LOC(*from);
+	else
+	    *to = *from;
+	return 1;
+    }
+}
+
+/*
+ * Format the dialog string, and display it at the bottom of
+ * the screen. Return a string of hotkey chars (if defined) for
+ * each 'button'. If a button has no hotkey defined, the first character of
+ * the button is used.
+ * The hotkeys can be multi-byte characters, but without combining chars.
+ *
+ * Returns an allocated string with hotkeys, or NULL for error.
+ */
+    static char_u *
+msg_show_console_dialog(message, buttons, dfltbutton)
+    char_u	*message;
+    char_u	*buttons;
+    int		dfltbutton;
+{
+    int		len = 0;
+#ifdef FEAT_MBYTE
+# define HOTK_LEN (has_mbyte ? MB_MAXBYTES : 1)
+#else
+# define HOTK_LEN 1
+#endif
+    int		lenhotkey = HOTK_LEN;	/* count first button */
+    char_u	*hotk = NULL;
+    char_u	*msgp = NULL;
+    char_u	*hotkp = NULL;
+    char_u	*r;
+    int		copy;
+#define HAS_HOTKEY_LEN 30
+    char_u	has_hotkey[HAS_HOTKEY_LEN];
+    int		first_hotkey = FALSE;	/* first char of button is hotkey */
+    int		idx;
+
+    has_hotkey[0] = FALSE;
+
+    /*
+     * First loop: compute the size of memory to allocate.
+     * Second loop: copy to the allocated memory.
+     */
+    for (copy = 0; copy <= 1; ++copy)
+    {
+	r = buttons;
+	idx = 0;
+	while (*r)
+	{
+	    if (*r == DLG_BUTTON_SEP)
+	    {
+		if (copy)
+		{
+		    *msgp++ = ',';
+		    *msgp++ = ' ';	    /* '\n' -> ', ' */
+
+		    /* advance to next hotkey and set default hotkey */
+#ifdef FEAT_MBYTE
+		    if (has_mbyte)
+			hotkp += (*mb_ptr2len)(hotkp);
+		    else
+#endif
+			++hotkp;
+		    (void)copy_char(r + 1, hotkp, TRUE);
+		    if (dfltbutton)
+			--dfltbutton;
+
+		    /* If no hotkey is specified first char is used. */
+		    if (idx < HAS_HOTKEY_LEN - 1 && !has_hotkey[++idx])
+			first_hotkey = TRUE;
+		}
+		else
+		{
+		    len += 3;		    /* '\n' -> ', '; 'x' -> '(x)' */
+		    lenhotkey += HOTK_LEN;  /* each button needs a hotkey */
+		    if (idx < HAS_HOTKEY_LEN - 1)
+			has_hotkey[++idx] = FALSE;
+		}
+	    }
+	    else if (*r == DLG_HOTKEY_CHAR || first_hotkey)
+	    {
+		if (*r == DLG_HOTKEY_CHAR)
+		    ++r;
+		first_hotkey = FALSE;
+		if (copy)
+		{
+		    if (*r == DLG_HOTKEY_CHAR)		/* '&&a' -> '&a' */
+			*msgp++ = *r;
+		    else
+		    {
+			/* '&a' -> '[a]' */
+			*msgp++ = (dfltbutton == 1) ? '[' : '(';
+			msgp += copy_char(r, msgp, FALSE);
+			*msgp++ = (dfltbutton == 1) ? ']' : ')';
+
+			/* redefine hotkey */
+			(void)copy_char(r, hotkp, TRUE);
+		    }
+		}
+		else
+		{
+		    ++len;	    /* '&a' -> '[a]' */
+		    if (idx < HAS_HOTKEY_LEN - 1)
+			has_hotkey[idx] = TRUE;
+		}
+	    }
+	    else
+	    {
+		/* everything else copy literally */
+		if (copy)
+		    msgp += copy_char(r, msgp, FALSE);
+	    }
+
+	    /* advance to the next character */
+	    mb_ptr_adv(r);
+	}
+
+	if (copy)
+	{
+	    *msgp++ = ':';
+	    *msgp++ = ' ';
+	    *msgp = NUL;
+	    mb_ptr_adv(hotkp);
+	    *hotkp = NUL;
+	}
+	else
+	{
+	    len += (int)(STRLEN(message)
+			+ 2			/* for the NL's */
+			+ STRLEN(buttons)
+			+ 3);			/* for the ": " and NUL */
+	    lenhotkey++;			/* for the NUL */
+
+	    /* If no hotkey is specified first char is used. */
+	    if (!has_hotkey[0])
+	    {
+		first_hotkey = TRUE;
+		len += 2;		/* "x" -> "[x]" */
+	    }
+
+	    /*
+	     * Now allocate and load the strings
+	     */
+	    vim_free(confirm_msg);
+	    confirm_msg = alloc(len);
+	    if (confirm_msg == NULL)
+		return NULL;
+	    *confirm_msg = NUL;
+	    hotk = alloc(lenhotkey);
+	    if (hotk == NULL)
+		return NULL;
+
+	    *confirm_msg = '\n';
+	    STRCPY(confirm_msg + 1, message);
+
+	    msgp = confirm_msg + 1 + STRLEN(message);
+	    hotkp = hotk;
+
+	    /* define first default hotkey */
+	    (void)copy_char(buttons, hotkp, TRUE);
+
+	    /* Remember where the choices start, displaying starts here when
+	     * "hotkp" typed at the more prompt. */
+	    confirm_msg_tail = msgp;
+	    *msgp++ = '\n';
+	}
+    }
+
+    display_confirm_msg();
+    return hotk;
+}
+
+/*
+ * Display the ":confirm" message.  Also called when screen resized.
+ */
+    void
+display_confirm_msg()
+{
+    /* avoid that 'q' at the more prompt truncates the message here */
+    ++confirm_msg_used;
+    if (confirm_msg != NULL)
+	msg_puts_attr(confirm_msg, hl_attr(HLF_M));
+    --confirm_msg_used;
+}
+
+#endif /* FEAT_CON_DIALOG */
+
+#if defined(FEAT_CON_DIALOG) || defined(FEAT_GUI_DIALOG)
+
+    int
+vim_dialog_yesno(type, title, message, dflt)
+    int		type;
+    char_u	*title;
+    char_u	*message;
+    int		dflt;
+{
+    if (do_dialog(type,
+		title == NULL ? (char_u *)_("Question") : title,
+		message,
+		(char_u *)_("&Yes\n&No"), dflt, NULL) == 1)
+	return VIM_YES;
+    return VIM_NO;
+}
+
+    int
+vim_dialog_yesnocancel(type, title, message, dflt)
+    int		type;
+    char_u	*title;
+    char_u	*message;
+    int		dflt;
+{
+    switch (do_dialog(type,
+		title == NULL ? (char_u *)_("Question") : title,
+		message,
+		(char_u *)_("&Yes\n&No\n&Cancel"), dflt, NULL))
+    {
+	case 1: return VIM_YES;
+	case 2: return VIM_NO;
+    }
+    return VIM_CANCEL;
+}
+
+    int
+vim_dialog_yesnoallcancel(type, title, message, dflt)
+    int		type;
+    char_u	*title;
+    char_u	*message;
+    int		dflt;
+{
+    switch (do_dialog(type,
+		title == NULL ? (char_u *)"Question" : title,
+		message,
+		(char_u *)_("&Yes\n&No\nSave &All\n&Discard All\n&Cancel"),
+								  dflt, NULL))
+    {
+	case 1: return VIM_YES;
+	case 2: return VIM_NO;
+	case 3: return VIM_ALL;
+	case 4: return VIM_DISCARDALL;
+    }
+    return VIM_CANCEL;
+}
+
+#endif /* FEAT_GUI_DIALOG || FEAT_CON_DIALOG */
+
+#if defined(FEAT_BROWSE) || defined(PROTO)
+/*
+ * Generic browse function.  Calls gui_mch_browse() when possible.
+ * Later this may pop-up a non-GUI file selector (external command?).
+ */
+    char_u *
+do_browse(flags, title, dflt, ext, initdir, filter, buf)
+    int		flags;		/* BROWSE_SAVE and BROWSE_DIR */
+    char_u	*title;		/* title for the window */
+    char_u	*dflt;		/* default file name (may include directory) */
+    char_u	*ext;		/* extension added */
+    char_u	*initdir;	/* initial directory, NULL for current dir or
+				   when using path from "dflt" */
+    char_u	*filter;	/* file name filter */
+    buf_T	*buf;		/* buffer to read/write for */
+{
+    char_u		*fname;
+    static char_u	*last_dir = NULL;    /* last used directory */
+    char_u		*tofree = NULL;
+    int			save_browse = cmdmod.browse;
+
+    /* Must turn off browse to avoid that autocommands will get the
+     * flag too!  */
+    cmdmod.browse = FALSE;
+
+    if (title == NULL || *title == NUL)
+    {
+	if (flags & BROWSE_DIR)
+	    title = (char_u *)_("Select Directory dialog");
+	else if (flags & BROWSE_SAVE)
+	    title = (char_u *)_("Save File dialog");
+	else
+	    title = (char_u *)_("Open File dialog");
+    }
+
+    /* When no directory specified, use default file name, default dir, buffer
+     * dir, last dir or current dir */
+    if ((initdir == NULL || *initdir == NUL) && dflt != NULL && *dflt != NUL)
+    {
+	if (mch_isdir(dflt))		/* default file name is a directory */
+	{
+	    initdir = dflt;
+	    dflt = NULL;
+	}
+	else if (gettail(dflt) != dflt)	/* default file name includes a path */
+	{
+	    tofree = vim_strsave(dflt);
+	    if (tofree != NULL)
+	    {
+		initdir = tofree;
+		*gettail(initdir) = NUL;
+		dflt = gettail(dflt);
+	    }
+	}
+    }
+
+    if (initdir == NULL || *initdir == NUL)
+    {
+	/* When 'browsedir' is a directory, use it */
+	if (STRCMP(p_bsdir, "last") != 0
+		&& STRCMP(p_bsdir, "buffer") != 0
+		&& STRCMP(p_bsdir, "current") != 0
+		&& mch_isdir(p_bsdir))
+	    initdir = p_bsdir;
+	/* When saving or 'browsedir' is "buffer", use buffer fname */
+	else if (((flags & BROWSE_SAVE) || *p_bsdir == 'b')
+		&& buf != NULL && buf->b_ffname != NULL)
+	{
+	    if (dflt == NULL || *dflt == NUL)
+		dflt = gettail(curbuf->b_ffname);
+	    tofree = vim_strsave(curbuf->b_ffname);
+	    if (tofree != NULL)
+	    {
+		initdir = tofree;
+		*gettail(initdir) = NUL;
+	    }
+	}
+	/* When 'browsedir' is "last", use dir from last browse */
+	else if (*p_bsdir == 'l')
+	    initdir = last_dir;
+	/* When 'browsedir is "current", use current directory.  This is the
+	 * default already, leave initdir empty. */
+    }
+
+# ifdef FEAT_GUI
+    if (gui.in_use)		/* when this changes, also adjust f_has()! */
+    {
+	if (filter == NULL
+#  ifdef FEAT_EVAL
+		&& (filter = get_var_value((char_u *)"b:browsefilter")) == NULL
+		&& (filter = get_var_value((char_u *)"g:browsefilter")) == NULL
+#  endif
+	)
+	    filter = BROWSE_FILTER_DEFAULT;
+	if (flags & BROWSE_DIR)
+	{
+#  if defined(HAVE_GTK2) || defined(WIN3264)
+	    /* For systems that have a directory dialog. */
+	    fname = gui_mch_browsedir(title, initdir);
+#  else
+	    /* Generic solution for selecting a directory: select a file and
+	     * remove the file name. */
+	    fname = gui_mch_browse(0, title, dflt, ext, initdir, (char_u *)"");
+#  endif
+#  if !defined(HAVE_GTK2)
+	    /* Win32 adds a dummy file name, others return an arbitrary file
+	     * name.  GTK+ 2 returns only the directory, */
+	    if (fname != NULL && *fname != NUL && !mch_isdir(fname))
+	    {
+		/* Remove the file name. */
+		char_u	    *tail = gettail_sep(fname);
+
+		if (tail == fname)
+		    *tail++ = '.';	/* use current dir */
+		*tail = NUL;
+	    }
+#  endif
+	}
+	else
+	    fname = gui_mch_browse(flags & BROWSE_SAVE,
+					   title, dflt, ext, initdir, filter);
+
+	/* We hang around in the dialog for a while, the user might do some
+	 * things to our files.  The Win32 dialog allows deleting or renaming
+	 * a file, check timestamps. */
+	need_check_timestamps = TRUE;
+	did_check_timestamps = FALSE;
+    }
+    else
+# endif
+    {
+	/* TODO: non-GUI file selector here */
+	EMSG(_("E338: Sorry, no file browser in console mode"));
+	fname = NULL;
+    }
+
+    /* keep the directory for next time */
+    if (fname != NULL)
+    {
+	vim_free(last_dir);
+	last_dir = vim_strsave(fname);
+	if (last_dir != NULL && !(flags & BROWSE_DIR))
+	{
+	    *gettail(last_dir) = NUL;
+	    if (*last_dir == NUL)
+	    {
+		/* filename only returned, must be in current dir */
+		vim_free(last_dir);
+		last_dir = alloc(MAXPATHL);
+		if (last_dir != NULL)
+		    mch_dirname(last_dir, MAXPATHL);
+	    }
+	}
+    }
+
+    vim_free(tofree);
+    cmdmod.browse = save_browse;
+
+    return fname;
+}
+#endif
+
+#if defined(HAVE_STDARG_H) && defined(FEAT_EVAL)
+static char *e_printf = N_("E766: Insufficient arguments for printf()");
+
+static long tv_nr __ARGS((typval_T *tvs, int *idxp));
+static char *tv_str __ARGS((typval_T *tvs, int *idxp));
+
+/*
+ * Get number argument from "idxp" entry in "tvs".  First entry is 1.
+ */
+    static long
+tv_nr(tvs, idxp)
+    typval_T	*tvs;
+    int		*idxp;
+{
+    int		idx = *idxp - 1;
+    long	n = 0;
+    int		err = FALSE;
+
+    if (tvs[idx].v_type == VAR_UNKNOWN)
+	EMSG(_(e_printf));
+    else
+    {
+	++*idxp;
+	n = get_tv_number_chk(&tvs[idx], &err);
+	if (err)
+	    n = 0;
+    }
+    return n;
+}
+
+/*
+ * Get string argument from "idxp" entry in "tvs".  First entry is 1.
+ * Returns NULL for an error.
+ */
+    static char *
+tv_str(tvs, idxp)
+    typval_T	*tvs;
+    int		*idxp;
+{
+    int		idx = *idxp - 1;
+    char	*s = NULL;
+
+    if (tvs[idx].v_type == VAR_UNKNOWN)
+	EMSG(_(e_printf));
+    else
+    {
+	++*idxp;
+	s = (char *)get_tv_string_chk(&tvs[idx]);
+    }
+    return s;
+}
+#endif
+
+/*
+ * This code was included to provide a portable vsnprintf() and snprintf().
+ * Some systems may provide their own, but we always use this one for
+ * consistency.
+ *
+ * This code is based on snprintf.c - a portable implementation of snprintf
+ * by Mark Martinec <mark.martinec@ijs.si>, Version 2.2, 2000-10-06.
+ * Included with permission.  It was heavily modified to fit in Vim.
+ * The original code, including useful comments, can be found here:
+ *	http://www.ijs.si/software/snprintf/
+ *
+ * This snprintf() only supports the following conversion specifiers:
+ * s, c, d, u, o, x, X, p  (and synonyms: i, D, U, O - see below)
+ * with flags: '-', '+', ' ', '0' and '#'.
+ * An asterisk is supported for field width as well as precision.
+ *
+ * Length modifiers 'h' (short int) and 'l' (long int) are supported.
+ * 'll' (long long int) is not supported.
+ *
+ * The locale is not used, the string is used as a byte string.  This is only
+ * relevant for double-byte encodings where the second byte may be '%'.
+ *
+ * It is permitted for "str_m" to be zero, and it is permitted to specify NULL
+ * pointer for resulting string argument if "str_m" is zero (as per ISO C99).
+ *
+ * The return value is the number of characters which would be generated
+ * for the given input, excluding the trailing null. If this value
+ * is greater or equal to "str_m", not all characters from the result
+ * have been stored in str, output bytes beyond the ("str_m"-1) -th character
+ * are discarded. If "str_m" is greater than zero it is guaranteed
+ * the resulting string will be null-terminated.
+ */
+
+/*
+ * When va_list is not supported we only define vim_snprintf().
+ *
+ * vim_vsnprintf() can be invoked with either "va_list" or a list of
+ * "typval_T".  When the latter is not used it must be NULL.
+ */
+
+/* When generating prototypes all of this is skipped, cproto doesn't
+ * understand this. */
+#ifndef PROTO
+# ifdef HAVE_STDARG_H
+    int
+vim_snprintf(char *str, size_t str_m, char *fmt, ...)
+{
+    va_list	ap;
+    int		str_l;
+
+    va_start(ap, fmt);
+    str_l = vim_vsnprintf(str, str_m, fmt, ap, NULL);
+    va_end(ap);
+    return str_l;
+}
+
+    int
+vim_vsnprintf(str, str_m, fmt, ap, tvs)
+# else
+    /* clumsy way to work around missing va_list */
+#  define get_a_arg(i) (++i, i == 2 ? a1 : i == 3 ? a2 : i == 4 ? a3 : i == 5 ? a4 : i == 6 ? a5 : i == 7 ? a6 : i == 8 ? a7 : i == 9 ? a8 : i == 10 ? a9 : a10)
+
+/* VARARGS */
+    int
+#ifdef __BORLANDC__
+_RTLENTRYF
+#endif
+vim_snprintf(str, str_m, fmt, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10)
+# endif
+    char	*str;
+    size_t	str_m;
+    char	*fmt;
+# ifdef HAVE_STDARG_H
+    va_list	ap;
+    typval_T	*tvs;
+# else
+    long	a1, a2, a3, a4, a5, a6, a7, a8, a9, a10;
+# endif
+{
+    size_t	str_l = 0;
+    char	*p = fmt;
+    int		arg_idx = 1;
+
+    if (p == NULL)
+	p = "";
+    while (*p != NUL)
+    {
+	if (*p != '%')
+	{
+	    char    *q = strchr(p + 1, '%');
+	    size_t  n = (q == NULL) ? STRLEN(p) : (q - p);
+
+	    /* Copy up to the next '%' or NUL without any changes. */
+	    if (str_l < str_m)
+	    {
+		size_t avail = str_m - str_l;
+
+		mch_memmove(str + str_l, p, n > avail ? avail : n);
+	    }
+	    p += n;
+	    str_l += n;
+	}
+	else
+	{
+	    size_t  min_field_width = 0, precision = 0;
+	    int	    zero_padding = 0, precision_specified = 0, justify_left = 0;
+	    int	    alternate_form = 0, force_sign = 0;
+
+	    /* If both the ' ' and '+' flags appear, the ' ' flag should be
+	     * ignored. */
+	    int	    space_for_positive = 1;
+
+	    /* allowed values: \0, h, l, L */
+	    char    length_modifier = '\0';
+
+	    /* temporary buffer for simple numeric->string conversion */
+	    char    tmp[32];
+
+	    /* string address in case of string argument */
+	    char    *str_arg;
+
+	    /* natural field width of arg without padding and sign */
+	    size_t  str_arg_l;
+
+	    /* unsigned char argument value - only defined for c conversion.
+	     * N.B. standard explicitly states the char argument for the c
+	     * conversion is unsigned */
+	    unsigned char uchar_arg;
+
+	    /* number of zeros to be inserted for numeric conversions as
+	     * required by the precision or minimal field width */
+	    size_t  number_of_zeros_to_pad = 0;
+
+	    /* index into tmp where zero padding is to be inserted */
+	    size_t  zero_padding_insertion_ind = 0;
+
+	    /* current conversion specifier character */
+	    char    fmt_spec = '\0';
+
+	    str_arg = NULL;
+	    p++;  /* skip '%' */
+
+	    /* parse flags */
+	    while (*p == '0' || *p == '-' || *p == '+' || *p == ' '
+						   || *p == '#' || *p == '\'')
+	    {
+		switch (*p)
+		{
+		    case '0': zero_padding = 1; break;
+		    case '-': justify_left = 1; break;
+		    case '+': force_sign = 1; space_for_positive = 0; break;
+		    case ' ': force_sign = 1;
+			      /* If both the ' ' and '+' flags appear, the ' '
+			       * flag should be ignored */
+			      break;
+		    case '#': alternate_form = 1; break;
+		    case '\'': break;
+		}
+		p++;
+	    }
+	    /* If the '0' and '-' flags both appear, the '0' flag should be
+	     * ignored. */
+
+	    /* parse field width */
+	    if (*p == '*')
+	    {
+		int j;
+
+		p++;
+		j =
+#ifndef HAVE_STDARG_H
+		    get_a_arg(arg_idx);
+#else
+# if defined(FEAT_EVAL)
+		    tvs != NULL ? tv_nr(tvs, &arg_idx) :
+# endif
+			va_arg(ap, int);
+#endif
+		if (j >= 0)
+		    min_field_width = j;
+		else
+		{
+		    min_field_width = -j;
+		    justify_left = 1;
+		}
+	    }
+	    else if (VIM_ISDIGIT((int)(*p)))
+	    {
+		/* size_t could be wider than unsigned int; make sure we treat
+		 * argument like common implementations do */
+		unsigned int uj = *p++ - '0';
+
+		while (VIM_ISDIGIT((int)(*p)))
+		    uj = 10 * uj + (unsigned int)(*p++ - '0');
+		min_field_width = uj;
+	    }
+
+	    /* parse precision */
+	    if (*p == '.')
+	    {
+		p++;
+		precision_specified = 1;
+		if (*p == '*')
+		{
+		    int j;
+
+		    j =
+#ifndef HAVE_STDARG_H
+			get_a_arg(arg_idx);
+#else
+# if defined(FEAT_EVAL)
+			tvs != NULL ? tv_nr(tvs, &arg_idx) :
+# endif
+			    va_arg(ap, int);
+#endif
+		    p++;
+		    if (j >= 0)
+			precision = j;
+		    else
+		    {
+			precision_specified = 0;
+			precision = 0;
+		    }
+		}
+		else if (VIM_ISDIGIT((int)(*p)))
+		{
+		    /* size_t could be wider than unsigned int; make sure we
+		     * treat argument like common implementations do */
+		    unsigned int uj = *p++ - '0';
+
+		    while (VIM_ISDIGIT((int)(*p)))
+			uj = 10 * uj + (unsigned int)(*p++ - '0');
+		    precision = uj;
+		}
+	    }
+
+	    /* parse 'h', 'l' and 'll' length modifiers */
+	    if (*p == 'h' || *p == 'l')
+	    {
+		length_modifier = *p;
+		p++;
+		if (length_modifier == 'l' && *p == 'l')
+		{
+		    /* double l = long long */
+		    length_modifier = 'l';	/* treat it as a single 'l' */
+		    p++;
+		}
+	    }
+	    fmt_spec = *p;
+
+	    /* common synonyms: */
+	    switch (fmt_spec)
+	    {
+		case 'i': fmt_spec = 'd'; break;
+		case 'D': fmt_spec = 'd'; length_modifier = 'l'; break;
+		case 'U': fmt_spec = 'u'; length_modifier = 'l'; break;
+		case 'O': fmt_spec = 'o'; length_modifier = 'l'; break;
+		default: break;
+	    }
+
+	    /* get parameter value, do initial processing */
+	    switch (fmt_spec)
+	    {
+		/* '%' and 'c' behave similar to 's' regarding flags and field
+		 * widths */
+	    case '%':
+	    case 'c':
+	    case 's':
+		length_modifier = '\0';
+		str_arg_l = 1;
+		switch (fmt_spec)
+		{
+		case '%':
+		    str_arg = p;
+		    break;
+
+		case 'c':
+		    {
+			int j;
+
+			j =
+#ifndef HAVE_STDARG_H
+			    get_a_arg(arg_idx);
+#else
+# if defined(FEAT_EVAL)
+			    tvs != NULL ? tv_nr(tvs, &arg_idx) :
+# endif
+				va_arg(ap, int);
+#endif
+			/* standard demands unsigned char */
+			uchar_arg = (unsigned char)j;
+			str_arg = (char *)&uchar_arg;
+			break;
+		    }
+
+		case 's':
+		    str_arg =
+#ifndef HAVE_STDARG_H
+				(char *)get_a_arg(arg_idx);
+#else
+# if defined(FEAT_EVAL)
+				tvs != NULL ? tv_str(tvs, &arg_idx) :
+# endif
+				    va_arg(ap, char *);
+#endif
+		    if (str_arg == NULL)
+		    {
+			str_arg = "[NULL]";
+			str_arg_l = 6;
+		    }
+		    /* make sure not to address string beyond the specified
+		     * precision !!! */
+		    else if (!precision_specified)
+			str_arg_l = strlen(str_arg);
+		    /* truncate string if necessary as requested by precision */
+		    else if (precision == 0)
+			str_arg_l = 0;
+		    else
+		    {
+			/* Don't put the #if inside memchr(), it can be a
+			 * macro. */
+#if SIZEOF_INT <= 2
+			char *q = memchr(str_arg, '\0', precision);
+#else
+			/* memchr on HP does not like n > 2^31  !!! */
+			char *q = memchr(str_arg, '\0',
+				  precision <= (size_t)0x7fffffffL ? precision
+						       : (size_t)0x7fffffffL);
+#endif
+			str_arg_l = (q == NULL) ? precision : q - str_arg;
+		    }
+		    break;
+
+		default:
+		    break;
+		}
+		break;
+
+	    case 'd': case 'u': case 'o': case 'x': case 'X': case 'p':
+		{
+		    /* NOTE: the u, o, x, X and p conversion specifiers
+		     * imply the value is unsigned;  d implies a signed
+		     * value */
+
+		    /* 0 if numeric argument is zero (or if pointer is
+		     * NULL for 'p'), +1 if greater than zero (or nonzero
+		     * for unsigned arguments), -1 if negative (unsigned
+		     * argument is never negative) */
+		    int arg_sign = 0;
+
+		    /* only defined for length modifier h, or for no
+		     * length modifiers */
+		    int int_arg = 0;
+		    unsigned int uint_arg = 0;
+
+		    /* only defined for length modifier l */
+		    long int long_arg = 0;
+		    unsigned long int ulong_arg = 0;
+
+		    /* pointer argument value -only defined for p
+		     * conversion */
+		    void *ptr_arg = NULL;
+
+		    if (fmt_spec == 'p')
+		    {
+			length_modifier = '\0';
+			ptr_arg =
+#ifndef HAVE_STDARG_H
+				 (void *)get_a_arg(arg_idx);
+#else
+# if defined(FEAT_EVAL)
+				 tvs != NULL ? (void *)tv_str(tvs, &arg_idx) :
+# endif
+					va_arg(ap, void *);
+#endif
+			if (ptr_arg != NULL)
+			    arg_sign = 1;
+		    }
+		    else if (fmt_spec == 'd')
+		    {
+			/* signed */
+			switch (length_modifier)
+			{
+			case '\0':
+			case 'h':
+			    /* char and short arguments are passed as int. */
+			    int_arg =
+#ifndef HAVE_STDARG_H
+					get_a_arg(arg_idx);
+#else
+# if defined(FEAT_EVAL)
+					tvs != NULL ? tv_nr(tvs, &arg_idx) :
+# endif
+					    va_arg(ap, int);
+#endif
+			    if (int_arg > 0)
+				arg_sign =  1;
+			    else if (int_arg < 0)
+				arg_sign = -1;
+			    break;
+			case 'l':
+			    long_arg =
+#ifndef HAVE_STDARG_H
+					get_a_arg(arg_idx);
+#else
+# if defined(FEAT_EVAL)
+					tvs != NULL ? tv_nr(tvs, &arg_idx) :
+# endif
+					    va_arg(ap, long int);
+#endif
+			    if (long_arg > 0)
+				arg_sign =  1;
+			    else if (long_arg < 0)
+				arg_sign = -1;
+			    break;
+			}
+		    }
+		    else
+		    {
+			/* unsigned */
+			switch (length_modifier)
+			{
+			    case '\0':
+			    case 'h':
+				uint_arg =
+#ifndef HAVE_STDARG_H
+					    get_a_arg(arg_idx);
+#else
+# if defined(FEAT_EVAL)
+					    tvs != NULL ? tv_nr(tvs, &arg_idx) :
+# endif
+						va_arg(ap, unsigned int);
+#endif
+				if (uint_arg != 0)
+				    arg_sign = 1;
+				break;
+			    case 'l':
+				ulong_arg =
+#ifndef HAVE_STDARG_H
+					    get_a_arg(arg_idx);
+#else
+# if defined(FEAT_EVAL)
+					    tvs != NULL ? tv_nr(tvs, &arg_idx) :
+# endif
+						va_arg(ap, unsigned long int);
+#endif
+				if (ulong_arg != 0)
+				    arg_sign = 1;
+				break;
+			}
+		    }
+
+		    str_arg = tmp;
+		    str_arg_l = 0;
+
+		    /* NOTE:
+		     *   For d, i, u, o, x, and X conversions, if precision is
+		     *   specified, the '0' flag should be ignored. This is so
+		     *   with Solaris 2.6, Digital UNIX 4.0, HPUX 10, Linux,
+		     *   FreeBSD, NetBSD; but not with Perl.
+		     */
+		    if (precision_specified)
+			zero_padding = 0;
+		    if (fmt_spec == 'd')
+		    {
+			if (force_sign && arg_sign >= 0)
+			    tmp[str_arg_l++] = space_for_positive ? ' ' : '+';
+			/* leave negative numbers for sprintf to handle, to
+			 * avoid handling tricky cases like (short int)-32768 */
+		    }
+		    else if (alternate_form)
+		    {
+			if (arg_sign != 0
+				     && (fmt_spec == 'x' || fmt_spec == 'X') )
+			{
+			    tmp[str_arg_l++] = '0';
+			    tmp[str_arg_l++] = fmt_spec;
+			}
+			/* alternate form should have no effect for p
+			 * conversion, but ... */
+		    }
+
+		    zero_padding_insertion_ind = str_arg_l;
+		    if (!precision_specified)
+			precision = 1;   /* default precision is 1 */
+		    if (precision == 0 && arg_sign == 0)
+		    {
+			/* When zero value is formatted with an explicit
+			 * precision 0, the resulting formatted string is
+			 * empty (d, i, u, o, x, X, p).   */
+		    }
+		    else
+		    {
+			char	f[5];
+			int	f_l = 0;
+
+			/* construct a simple format string for sprintf */
+			f[f_l++] = '%';
+			if (!length_modifier)
+			    ;
+			else if (length_modifier == '2')
+			{
+			    f[f_l++] = 'l';
+			    f[f_l++] = 'l';
+			}
+			else
+			    f[f_l++] = length_modifier;
+			f[f_l++] = fmt_spec;
+			f[f_l++] = '\0';
+
+			if (fmt_spec == 'p')
+			    str_arg_l += sprintf(tmp + str_arg_l, f, ptr_arg);
+			else if (fmt_spec == 'd')
+			{
+			    /* signed */
+			    switch (length_modifier)
+			    {
+			    case '\0':
+			    case 'h': str_arg_l += sprintf(
+						 tmp + str_arg_l, f, int_arg);
+				      break;
+			    case 'l': str_arg_l += sprintf(
+						tmp + str_arg_l, f, long_arg);
+				      break;
+			    }
+			}
+			else
+			{
+			    /* unsigned */
+			    switch (length_modifier)
+			    {
+			    case '\0':
+			    case 'h': str_arg_l += sprintf(
+						tmp + str_arg_l, f, uint_arg);
+				      break;
+			    case 'l': str_arg_l += sprintf(
+					       tmp + str_arg_l, f, ulong_arg);
+				      break;
+			    }
+			}
+
+			/* include the optional minus sign and possible
+			 * "0x" in the region before the zero padding
+			 * insertion point */
+			if (zero_padding_insertion_ind < str_arg_l
+				&& tmp[zero_padding_insertion_ind] == '-')
+			    zero_padding_insertion_ind++;
+			if (zero_padding_insertion_ind + 1 < str_arg_l
+				&& tmp[zero_padding_insertion_ind]   == '0'
+				&& (tmp[zero_padding_insertion_ind + 1] == 'x'
+				 || tmp[zero_padding_insertion_ind + 1] == 'X'))
+			    zero_padding_insertion_ind += 2;
+		    }
+
+		    {
+			size_t num_of_digits = str_arg_l
+						 - zero_padding_insertion_ind;
+
+			if (alternate_form && fmt_spec == 'o'
+				/* unless zero is already the first
+				 * character */
+				&& !(zero_padding_insertion_ind < str_arg_l
+				    && tmp[zero_padding_insertion_ind] == '0'))
+			{
+			    /* assure leading zero for alternate-form
+			     * octal numbers */
+			    if (!precision_specified
+					     || precision < num_of_digits + 1)
+			    {
+				/* precision is increased to force the
+				 * first character to be zero, except if a
+				 * zero value is formatted with an
+				 * explicit precision of zero */
+				precision = num_of_digits + 1;
+				precision_specified = 1;
+			    }
+			}
+			/* zero padding to specified precision? */
+			if (num_of_digits < precision)
+			    number_of_zeros_to_pad = precision - num_of_digits;
+		    }
+		    /* zero padding to specified minimal field width? */
+		    if (!justify_left && zero_padding)
+		    {
+			int n = (int)(min_field_width - (str_arg_l
+						    + number_of_zeros_to_pad));
+			if (n > 0)
+			    number_of_zeros_to_pad += n;
+		    }
+		    break;
+		}
+
+	    default:
+		/* unrecognized conversion specifier, keep format string
+		 * as-is */
+		zero_padding = 0;  /* turn zero padding off for non-numeric
+				      conversion */
+		justify_left = 1;
+		min_field_width = 0;		    /* reset flags */
+
+		/* discard the unrecognized conversion, just keep *
+		 * the unrecognized conversion character	  */
+		str_arg = p;
+		str_arg_l = 0;
+		if (*p != NUL)
+		    str_arg_l++;  /* include invalid conversion specifier
+				     unchanged if not at end-of-string */
+		break;
+	    }
+
+	    if (*p != NUL)
+		p++;     /* step over the just processed conversion specifier */
+
+	    /* insert padding to the left as requested by min_field_width;
+	     * this does not include the zero padding in case of numerical
+	     * conversions*/
+	    if (!justify_left)
+	    {
+		/* left padding with blank or zero */
+		int pn = (int)(min_field_width - (str_arg_l + number_of_zeros_to_pad));
+
+		if (pn > 0)
+		{
+		    if (str_l < str_m)
+		    {
+			size_t avail = str_m - str_l;
+
+			vim_memset(str + str_l, zero_padding ? '0' : ' ',
+					     (size_t)pn > avail ? avail : pn);
+		    }
+		    str_l += pn;
+		}
+	    }
+
+	    /* zero padding as requested by the precision or by the minimal
+	     * field width for numeric conversions required? */
+	    if (number_of_zeros_to_pad == 0)
+	    {
+		/* will not copy first part of numeric right now, *
+		 * force it to be copied later in its entirety    */
+		zero_padding_insertion_ind = 0;
+	    }
+	    else
+	    {
+		/* insert first part of numerics (sign or '0x') before zero
+		 * padding */
+		int zn = (int)zero_padding_insertion_ind;
+
+		if (zn > 0)
+		{
+		    if (str_l < str_m)
+		    {
+			size_t avail = str_m - str_l;
+
+			mch_memmove(str + str_l, str_arg,
+					     (size_t)zn > avail ? avail : zn);
+		    }
+		    str_l += zn;
+		}
+
+		/* insert zero padding as requested by the precision or min
+		 * field width */
+		zn = (int)number_of_zeros_to_pad;
+		if (zn > 0)
+		{
+		    if (str_l < str_m)
+		    {
+			size_t avail = str_m-str_l;
+
+			vim_memset(str + str_l, '0',
+					     (size_t)zn > avail ? avail : zn);
+		    }
+		    str_l += zn;
+		}
+	    }
+
+	    /* insert formatted string
+	     * (or as-is conversion specifier for unknown conversions) */
+	    {
+		int sn = (int)(str_arg_l - zero_padding_insertion_ind);
+
+		if (sn > 0)
+		{
+		    if (str_l < str_m)
+		    {
+			size_t avail = str_m - str_l;
+
+			mch_memmove(str + str_l,
+				str_arg + zero_padding_insertion_ind,
+				(size_t)sn > avail ? avail : sn);
+		    }
+		    str_l += sn;
+		}
+	    }
+
+	    /* insert right padding */
+	    if (justify_left)
+	    {
+		/* right blank padding to the field width */
+		int pn = (int)(min_field_width - (str_arg_l + number_of_zeros_to_pad));
+
+		if (pn > 0)
+		{
+		    if (str_l < str_m)
+		    {
+			size_t avail = str_m - str_l;
+
+			vim_memset(str + str_l, ' ',
+					     (size_t)pn > avail ? avail : pn);
+		    }
+		    str_l += pn;
+		}
+	    }
+	}
+    }
+
+    if (str_m > 0)
+    {
+	/* make sure the string is nul-terminated even at the expense of
+	 * overwriting the last character (shouldn't happen, but just in case)
+	 * */
+	str[str_l <= str_m - 1 ? str_l : str_m - 1] = '\0';
+    }
+
+#ifdef HAVE_STDARG_H
+    if (tvs != NULL && tvs[arg_idx - 1].v_type != VAR_UNKNOWN)
+	EMSG(_("E767: Too many arguments to printf()"));
+#endif
+
+    /* Return the number of characters formatted (excluding trailing nul
+     * character), that is, the number of characters that would have been
+     * written to the buffer if it were large enough. */
+    return (int)str_l;
+}
+
+#endif /* PROTO */
--- /dev/null
+++ b/misc1.c
@@ -1,0 +1,9419 @@
+/* vi:set ts=8 sts=4 sw=4:
+ *
+ * VIM - Vi IMproved	by Bram Moolenaar
+ *
+ * Do ":help uganda"  in Vim to read copying and usage conditions.
+ * Do ":help credits" in Vim to see a list of people who contributed.
+ * See README.txt for an overview of the Vim source code.
+ */
+
+/*
+ * misc1.c: functions that didn't seem to fit elsewhere
+ */
+
+#include "vim.h"
+#include "version.h"
+
+#ifdef HAVE_FCNTL_H
+# include <fcntl.h>		/* for chdir() */
+#endif
+
+static char_u *vim_version_dir __ARGS((char_u *vimdir));
+static char_u *remove_tail __ARGS((char_u *p, char_u *pend, char_u *name));
+static int copy_indent __ARGS((int size, char_u	*src));
+
+/*
+ * Count the size (in window cells) of the indent in the current line.
+ */
+    int
+get_indent()
+{
+    return get_indent_str(ml_get_curline(), (int)curbuf->b_p_ts);
+}
+
+/*
+ * Count the size (in window cells) of the indent in line "lnum".
+ */
+    int
+get_indent_lnum(lnum)
+    linenr_T	lnum;
+{
+    return get_indent_str(ml_get(lnum), (int)curbuf->b_p_ts);
+}
+
+#if defined(FEAT_FOLDING) || defined(PROTO)
+/*
+ * Count the size (in window cells) of the indent in line "lnum" of buffer
+ * "buf".
+ */
+    int
+get_indent_buf(buf, lnum)
+    buf_T	*buf;
+    linenr_T	lnum;
+{
+    return get_indent_str(ml_get_buf(buf, lnum, FALSE), (int)buf->b_p_ts);
+}
+#endif
+
+/*
+ * count the size (in window cells) of the indent in line "ptr", with
+ * 'tabstop' at "ts"
+ */
+    int
+get_indent_str(ptr, ts)
+    char_u	*ptr;
+    int		ts;
+{
+    int		count = 0;
+
+    for ( ; *ptr; ++ptr)
+    {
+	if (*ptr == TAB)    /* count a tab for what it is worth */
+	    count += ts - (count % ts);
+	else if (*ptr == ' ')
+	    ++count;		/* count a space for one */
+	else
+	    break;
+    }
+    return count;
+}
+
+/*
+ * Set the indent of the current line.
+ * Leaves the cursor on the first non-blank in the line.
+ * Caller must take care of undo.
+ * "flags":
+ *	SIN_CHANGED:	call changed_bytes() if the line was changed.
+ *	SIN_INSERT:	insert the indent in front of the line.
+ *	SIN_UNDO:	save line for undo before changing it.
+ * Returns TRUE if the line was changed.
+ */
+    int
+set_indent(size, flags)
+    int		size;
+    int		flags;
+{
+    char_u	*p;
+    char_u	*newline;
+    char_u	*oldline;
+    char_u	*s;
+    int		todo;
+    int		ind_len;
+    int		line_len;
+    int		doit = FALSE;
+    int		ind_done;
+    int		tab_pad;
+    int		retval = FALSE;
+
+    /*
+     * First check if there is anything to do and compute the number of
+     * characters needed for the indent.
+     */
+    todo = size;
+    ind_len = 0;
+    p = oldline = ml_get_curline();
+
+    /* Calculate the buffer size for the new indent, and check to see if it
+     * isn't already set */
+
+    /* if 'expandtab' isn't set: use TABs */
+    if (!curbuf->b_p_et)
+    {
+	/* If 'preserveindent' is set then reuse as much as possible of
+	 * the existing indent structure for the new indent */
+	if (!(flags & SIN_INSERT) && curbuf->b_p_pi)
+	{
+	    ind_done = 0;
+
+	    /* count as many characters as we can use */
+	    while (todo > 0 && vim_iswhite(*p))
+	    {
+		if (*p == TAB)
+		{
+		    tab_pad = (int)curbuf->b_p_ts
+					   - (ind_done % (int)curbuf->b_p_ts);
+		    /* stop if this tab will overshoot the target */
+		    if (todo < tab_pad)
+			break;
+		    todo -= tab_pad;
+		    ++ind_len;
+		    ind_done += tab_pad;
+		}
+		else
+		{
+		    --todo;
+		    ++ind_len;
+		    ++ind_done;
+		}
+		++p;
+	    }
+
+	    /* Fill to next tabstop with a tab, if possible */
+	    tab_pad = (int)curbuf->b_p_ts - (ind_done % (int)curbuf->b_p_ts);
+	    if (todo >= tab_pad)
+	    {
+		doit = TRUE;
+		todo -= tab_pad;
+		++ind_len;
+		/* ind_done += tab_pad; */
+	    }
+	}
+
+	/* count tabs required for indent */
+	while (todo >= (int)curbuf->b_p_ts)
+	{
+	    if (*p != TAB)
+		doit = TRUE;
+	    else
+		++p;
+	    todo -= (int)curbuf->b_p_ts;
+	    ++ind_len;
+	    /* ind_done += (int)curbuf->b_p_ts; */
+	}
+    }
+    /* count spaces required for indent */
+    while (todo > 0)
+    {
+	if (*p != ' ')
+	    doit = TRUE;
+	else
+	    ++p;
+	--todo;
+	++ind_len;
+	/* ++ind_done; */
+    }
+
+    /* Return if the indent is OK already. */
+    if (!doit && !vim_iswhite(*p) && !(flags & SIN_INSERT))
+	return FALSE;
+
+    /* Allocate memory for the new line. */
+    if (flags & SIN_INSERT)
+	p = oldline;
+    else
+	p = skipwhite(p);
+    line_len = (int)STRLEN(p) + 1;
+    newline = alloc(ind_len + line_len);
+    if (newline == NULL)
+	return FALSE;
+
+    /* Put the characters in the new line. */
+    s = newline;
+    todo = size;
+    /* if 'expandtab' isn't set: use TABs */
+    if (!curbuf->b_p_et)
+    {
+	/* If 'preserveindent' is set then reuse as much as possible of
+	 * the existing indent structure for the new indent */
+	if (!(flags & SIN_INSERT) && curbuf->b_p_pi)
+	{
+	    p = oldline;
+	    ind_done = 0;
+
+	    while (todo > 0 && vim_iswhite(*p))
+	    {
+		if (*p == TAB)
+		{
+		    tab_pad = (int)curbuf->b_p_ts
+					   - (ind_done % (int)curbuf->b_p_ts);
+		    /* stop if this tab will overshoot the target */
+		    if (todo < tab_pad)
+			break;
+		    todo -= tab_pad;
+		    ind_done += tab_pad;
+		}
+		else
+		{
+		    --todo;
+		    ++ind_done;
+		}
+		*s++ = *p++;
+	    }
+
+	    /* Fill to next tabstop with a tab, if possible */
+	    tab_pad = (int)curbuf->b_p_ts - (ind_done % (int)curbuf->b_p_ts);
+	    if (todo >= tab_pad)
+	    {
+		*s++ = TAB;
+		todo -= tab_pad;
+	    }
+
+	    p = skipwhite(p);
+	}
+
+	while (todo >= (int)curbuf->b_p_ts)
+	{
+	    *s++ = TAB;
+	    todo -= (int)curbuf->b_p_ts;
+	}
+    }
+    while (todo > 0)
+    {
+	*s++ = ' ';
+	--todo;
+    }
+    mch_memmove(s, p, (size_t)line_len);
+
+    /* Replace the line (unless undo fails). */
+    if (!(flags & SIN_UNDO) || u_savesub(curwin->w_cursor.lnum) == OK)
+    {
+	ml_replace(curwin->w_cursor.lnum, newline, FALSE);
+	if (flags & SIN_CHANGED)
+	    changed_bytes(curwin->w_cursor.lnum, 0);
+	/* Correct saved cursor position if it's after the indent. */
+	if (saved_cursor.lnum == curwin->w_cursor.lnum
+				&& saved_cursor.col >= (colnr_T)(p - oldline))
+	    saved_cursor.col += ind_len - (colnr_T)(p - oldline);
+	retval = TRUE;
+    }
+    else
+	vim_free(newline);
+
+    curwin->w_cursor.col = ind_len;
+    return retval;
+}
+
+/*
+ * Copy the indent from ptr to the current line (and fill to size)
+ * Leaves the cursor on the first non-blank in the line.
+ * Returns TRUE if the line was changed.
+ */
+    static int
+copy_indent(size, src)
+    int		size;
+    char_u	*src;
+{
+    char_u	*p = NULL;
+    char_u	*line = NULL;
+    char_u	*s;
+    int		todo;
+    int		ind_len;
+    int		line_len = 0;
+    int		tab_pad;
+    int		ind_done;
+    int		round;
+
+    /* Round 1: compute the number of characters needed for the indent
+     * Round 2: copy the characters. */
+    for (round = 1; round <= 2; ++round)
+    {
+	todo = size;
+	ind_len = 0;
+	ind_done = 0;
+	s = src;
+
+	/* Count/copy the usable portion of the source line */
+	while (todo > 0 && vim_iswhite(*s))
+	{
+	    if (*s == TAB)
+	    {
+		tab_pad = (int)curbuf->b_p_ts
+					   - (ind_done % (int)curbuf->b_p_ts);
+		/* Stop if this tab will overshoot the target */
+		if (todo < tab_pad)
+		    break;
+		todo -= tab_pad;
+		ind_done += tab_pad;
+	    }
+	    else
+	    {
+		--todo;
+		++ind_done;
+	    }
+	    ++ind_len;
+	    if (p != NULL)
+		*p++ = *s;
+	    ++s;
+	}
+
+	/* Fill to next tabstop with a tab, if possible */
+	tab_pad = (int)curbuf->b_p_ts - (ind_done % (int)curbuf->b_p_ts);
+	if (todo >= tab_pad)
+	{
+	    todo -= tab_pad;
+	    ++ind_len;
+	    if (p != NULL)
+		*p++ = TAB;
+	}
+
+	/* Add tabs required for indent */
+	while (todo >= (int)curbuf->b_p_ts)
+	{
+	    todo -= (int)curbuf->b_p_ts;
+	    ++ind_len;
+	    if (p != NULL)
+		*p++ = TAB;
+	}
+
+	/* Count/add spaces required for indent */
+	while (todo > 0)
+	{
+	    --todo;
+	    ++ind_len;
+	    if (p != NULL)
+		*p++ = ' ';
+	}
+
+	if (p == NULL)
+	{
+	    /* Allocate memory for the result: the copied indent, new indent
+	     * and the rest of the line. */
+	    line_len = (int)STRLEN(ml_get_curline()) + 1;
+	    line = alloc(ind_len + line_len);
+	    if (line == NULL)
+		return FALSE;
+	    p = line;
+	}
+    }
+
+    /* Append the original line */
+    mch_memmove(p, ml_get_curline(), (size_t)line_len);
+
+    /* Replace the line */
+    ml_replace(curwin->w_cursor.lnum, line, FALSE);
+
+    /* Put the cursor after the indent. */
+    curwin->w_cursor.col = ind_len;
+    return TRUE;
+}
+
+/*
+ * Return the indent of the current line after a number.  Return -1 if no
+ * number was found.  Used for 'n' in 'formatoptions': numbered list.
+ * Since a pattern is used it can actually handle more than numbers.
+ */
+    int
+get_number_indent(lnum)
+    linenr_T	lnum;
+{
+    colnr_T	col;
+    pos_T	pos;
+    regmmatch_T	regmatch;
+
+    if (lnum > curbuf->b_ml.ml_line_count)
+	return -1;
+    pos.lnum = 0;
+    regmatch.regprog = vim_regcomp(curbuf->b_p_flp, RE_MAGIC);
+    if (regmatch.regprog != NULL)
+    {
+	regmatch.rmm_ic = FALSE;
+	regmatch.rmm_maxcol = 0;
+	if (vim_regexec_multi(&regmatch, curwin, curbuf, lnum, (colnr_T)0))
+	{
+	    pos.lnum = regmatch.endpos[0].lnum + lnum;
+	    pos.col = regmatch.endpos[0].col;
+#ifdef FEAT_VIRTUALEDIT
+	    pos.coladd = 0;
+#endif
+	}
+	vim_free(regmatch.regprog);
+    }
+
+    if (pos.lnum == 0 || *ml_get_pos(&pos) == NUL)
+	return -1;
+    getvcol(curwin, &pos, &col, NULL, NULL);
+    return (int)col;
+}
+
+#if defined(FEAT_CINDENT) || defined(FEAT_SMARTINDENT)
+
+static int cin_is_cinword __ARGS((char_u *line));
+
+/*
+ * Return TRUE if the string "line" starts with a word from 'cinwords'.
+ */
+    static int
+cin_is_cinword(line)
+    char_u	*line;
+{
+    char_u	*cinw;
+    char_u	*cinw_buf;
+    int		cinw_len;
+    int		retval = FALSE;
+    int		len;
+
+    cinw_len = (int)STRLEN(curbuf->b_p_cinw) + 1;
+    cinw_buf = alloc((unsigned)cinw_len);
+    if (cinw_buf != NULL)
+    {
+	line = skipwhite(line);
+	for (cinw = curbuf->b_p_cinw; *cinw; )
+	{
+	    len = copy_option_part(&cinw, cinw_buf, cinw_len, ",");
+	    if (STRNCMP(line, cinw_buf, len) == 0
+		    && (!vim_iswordc(line[len]) || !vim_iswordc(line[len - 1])))
+	    {
+		retval = TRUE;
+		break;
+	    }
+	}
+	vim_free(cinw_buf);
+    }
+    return retval;
+}
+#endif
+
+/*
+ * open_line: Add a new line below or above the current line.
+ *
+ * For VREPLACE mode, we only add a new line when we get to the end of the
+ * file, otherwise we just start replacing the next line.
+ *
+ * Caller must take care of undo.  Since VREPLACE may affect any number of
+ * lines however, it may call u_save_cursor() again when starting to change a
+ * new line.
+ * "flags": OPENLINE_DELSPACES	delete spaces after cursor
+ *	    OPENLINE_DO_COM	format comments
+ *	    OPENLINE_KEEPTRAIL	keep trailing spaces
+ *	    OPENLINE_MARKFIX	adjust mark positions after the line break
+ *
+ * Return TRUE for success, FALSE for failure
+ */
+    int
+open_line(dir, flags, old_indent)
+    int		dir;		/* FORWARD or BACKWARD */
+    int		flags;
+    int		old_indent;	/* indent for after ^^D in Insert mode */
+{
+    char_u	*saved_line;		/* copy of the original line */
+    char_u	*next_line = NULL;	/* copy of the next line */
+    char_u	*p_extra = NULL;	/* what goes to next line */
+    int		less_cols = 0;		/* less columns for mark in new line */
+    int		less_cols_off = 0;	/* columns to skip for mark adjust */
+    pos_T	old_cursor;		/* old cursor position */
+    int		newcol = 0;		/* new cursor column */
+    int		newindent = 0;		/* auto-indent of the new line */
+    int		n;
+    int		trunc_line = FALSE;	/* truncate current line afterwards */
+    int		retval = FALSE;		/* return value, default is FAIL */
+#ifdef FEAT_COMMENTS
+    int		extra_len = 0;		/* length of p_extra string */
+    int		lead_len;		/* length of comment leader */
+    char_u	*lead_flags;	/* position in 'comments' for comment leader */
+    char_u	*leader = NULL;		/* copy of comment leader */
+#endif
+    char_u	*allocated = NULL;	/* allocated memory */
+#if defined(FEAT_SMARTINDENT) || defined(FEAT_VREPLACE) || defined(FEAT_LISP) \
+	|| defined(FEAT_CINDENT) || defined(FEAT_COMMENTS)
+    char_u	*p;
+#endif
+    int		saved_char = NUL;	/* init for GCC */
+#if defined(FEAT_SMARTINDENT) || defined(FEAT_COMMENTS)
+    pos_T	*pos;
+#endif
+#ifdef FEAT_SMARTINDENT
+    int		do_si = (!p_paste && curbuf->b_p_si
+# ifdef FEAT_CINDENT
+					&& !curbuf->b_p_cin
+# endif
+			);
+    int		no_si = FALSE;		/* reset did_si afterwards */
+    int		first_char = NUL;	/* init for GCC */
+#endif
+#if defined(FEAT_VREPLACE) && (defined(FEAT_LISP) || defined(FEAT_CINDENT))
+    int		vreplace_mode;
+#endif
+    int		did_append;		/* appended a new line */
+    int		saved_pi = curbuf->b_p_pi; /* copy of preserveindent setting */
+
+    /*
+     * make a copy of the current line so we can mess with it
+     */
+    saved_line = vim_strsave(ml_get_curline());
+    if (saved_line == NULL)	    /* out of memory! */
+	return FALSE;
+
+#ifdef FEAT_VREPLACE
+    if (State & VREPLACE_FLAG)
+    {
+	/*
+	 * With VREPLACE we make a copy of the next line, which we will be
+	 * starting to replace.  First make the new line empty and let vim play
+	 * with the indenting and comment leader to its heart's content.  Then
+	 * we grab what it ended up putting on the new line, put back the
+	 * original line, and call ins_char() to put each new character onto
+	 * the line, replacing what was there before and pushing the right
+	 * stuff onto the replace stack.  -- webb.
+	 */
+	if (curwin->w_cursor.lnum < orig_line_count)
+	    next_line = vim_strsave(ml_get(curwin->w_cursor.lnum + 1));
+	else
+	    next_line = vim_strsave((char_u *)"");
+	if (next_line == NULL)	    /* out of memory! */
+	    goto theend;
+
+	/*
+	 * In VREPLACE mode, a NL replaces the rest of the line, and starts
+	 * replacing the next line, so push all of the characters left on the
+	 * line onto the replace stack.  We'll push any other characters that
+	 * might be replaced at the start of the next line (due to autoindent
+	 * etc) a bit later.
+	 */
+	replace_push(NUL);  /* Call twice because BS over NL expects it */
+	replace_push(NUL);
+	p = saved_line + curwin->w_cursor.col;
+	while (*p != NUL)
+	    replace_push(*p++);
+	saved_line[curwin->w_cursor.col] = NUL;
+    }
+#endif
+
+    if ((State & INSERT)
+#ifdef FEAT_VREPLACE
+	    && !(State & VREPLACE_FLAG)
+#endif
+	    )
+    {
+	p_extra = saved_line + curwin->w_cursor.col;
+#ifdef FEAT_SMARTINDENT
+	if (do_si)		/* need first char after new line break */
+	{
+	    p = skipwhite(p_extra);
+	    first_char = *p;
+	}
+#endif
+#ifdef FEAT_COMMENTS
+	extra_len = (int)STRLEN(p_extra);
+#endif
+	saved_char = *p_extra;
+	*p_extra = NUL;
+    }
+
+    u_clearline();		/* cannot do "U" command when adding lines */
+#ifdef FEAT_SMARTINDENT
+    did_si = FALSE;
+#endif
+    ai_col = 0;
+
+    /*
+     * If we just did an auto-indent, then we didn't type anything on
+     * the prior line, and it should be truncated.  Do this even if 'ai' is not
+     * set because automatically inserting a comment leader also sets did_ai.
+     */
+    if (dir == FORWARD && did_ai)
+	trunc_line = TRUE;
+
+    /*
+     * If 'autoindent' and/or 'smartindent' is set, try to figure out what
+     * indent to use for the new line.
+     */
+    if (curbuf->b_p_ai
+#ifdef FEAT_SMARTINDENT
+			|| do_si
+#endif
+					    )
+    {
+	/*
+	 * count white space on current line
+	 */
+	newindent = get_indent_str(saved_line, (int)curbuf->b_p_ts);
+	if (newindent == 0)
+	    newindent = old_indent;	/* for ^^D command in insert mode */
+
+#ifdef FEAT_SMARTINDENT
+	/*
+	 * Do smart indenting.
+	 * In insert/replace mode (only when dir == FORWARD)
+	 * we may move some text to the next line. If it starts with '{'
+	 * don't add an indent. Fixes inserting a NL before '{' in line
+	 *	"if (condition) {"
+	 */
+	if (!trunc_line && do_si && *saved_line != NUL
+				    && (p_extra == NULL || first_char != '{'))
+	{
+	    char_u  *ptr;
+	    char_u  last_char;
+
+	    old_cursor = curwin->w_cursor;
+	    ptr = saved_line;
+# ifdef FEAT_COMMENTS
+	    if (flags & OPENLINE_DO_COM)
+		lead_len = get_leader_len(ptr, NULL, FALSE);
+	    else
+		lead_len = 0;
+# endif
+	    if (dir == FORWARD)
+	    {
+		/*
+		 * Skip preprocessor directives, unless they are
+		 * recognised as comments.
+		 */
+		if (
+# ifdef FEAT_COMMENTS
+			lead_len == 0 &&
+# endif
+			ptr[0] == '#')
+		{
+		    while (ptr[0] == '#' && curwin->w_cursor.lnum > 1)
+			ptr = ml_get(--curwin->w_cursor.lnum);
+		    newindent = get_indent();
+		}
+# ifdef FEAT_COMMENTS
+		if (flags & OPENLINE_DO_COM)
+		    lead_len = get_leader_len(ptr, NULL, FALSE);
+		else
+		    lead_len = 0;
+		if (lead_len > 0)
+		{
+		    /*
+		     * This case gets the following right:
+		     *	    \*
+		     *	     * A comment (read '\' as '/').
+		     *	     *\
+		     * #define IN_THE_WAY
+		     *	    This should line up here;
+		     */
+		    p = skipwhite(ptr);
+		    if (p[0] == '/' && p[1] == '*')
+			p++;
+		    if (p[0] == '*')
+		    {
+			for (p++; *p; p++)
+			{
+			    if (p[0] == '/' && p[-1] == '*')
+			    {
+				/*
+				 * End of C comment, indent should line up
+				 * with the line containing the start of
+				 * the comment
+				 */
+				curwin->w_cursor.col = (colnr_T)(p - ptr);
+				if ((pos = findmatch(NULL, NUL)) != NULL)
+				{
+				    curwin->w_cursor.lnum = pos->lnum;
+				    newindent = get_indent();
+				}
+			    }
+			}
+		    }
+		}
+		else	/* Not a comment line */
+# endif
+		{
+		    /* Find last non-blank in line */
+		    p = ptr + STRLEN(ptr) - 1;
+		    while (p > ptr && vim_iswhite(*p))
+			--p;
+		    last_char = *p;
+
+		    /*
+		     * find the character just before the '{' or ';'
+		     */
+		    if (last_char == '{' || last_char == ';')
+		    {
+			if (p > ptr)
+			    --p;
+			while (p > ptr && vim_iswhite(*p))
+			    --p;
+		    }
+		    /*
+		     * Try to catch lines that are split over multiple
+		     * lines.  eg:
+		     *	    if (condition &&
+		     *			condition) {
+		     *		Should line up here!
+		     *	    }
+		     */
+		    if (*p == ')')
+		    {
+			curwin->w_cursor.col = (colnr_T)(p - ptr);
+			if ((pos = findmatch(NULL, '(')) != NULL)
+			{
+			    curwin->w_cursor.lnum = pos->lnum;
+			    newindent = get_indent();
+			    ptr = ml_get_curline();
+			}
+		    }
+		    /*
+		     * If last character is '{' do indent, without
+		     * checking for "if" and the like.
+		     */
+		    if (last_char == '{')
+		    {
+			did_si = TRUE;	/* do indent */
+			no_si = TRUE;	/* don't delete it when '{' typed */
+		    }
+		    /*
+		     * Look for "if" and the like, use 'cinwords'.
+		     * Don't do this if the previous line ended in ';' or
+		     * '}'.
+		     */
+		    else if (last_char != ';' && last_char != '}'
+						       && cin_is_cinword(ptr))
+			did_si = TRUE;
+		}
+	    }
+	    else /* dir == BACKWARD */
+	    {
+		/*
+		 * Skip preprocessor directives, unless they are
+		 * recognised as comments.
+		 */
+		if (
+# ifdef FEAT_COMMENTS
+			lead_len == 0 &&
+# endif
+			ptr[0] == '#')
+		{
+		    int was_backslashed = FALSE;
+
+		    while ((ptr[0] == '#' || was_backslashed) &&
+			 curwin->w_cursor.lnum < curbuf->b_ml.ml_line_count)
+		    {
+			if (*ptr && ptr[STRLEN(ptr) - 1] == '\\')
+			    was_backslashed = TRUE;
+			else
+			    was_backslashed = FALSE;
+			ptr = ml_get(++curwin->w_cursor.lnum);
+		    }
+		    if (was_backslashed)
+			newindent = 0;	    /* Got to end of file */
+		    else
+			newindent = get_indent();
+		}
+		p = skipwhite(ptr);
+		if (*p == '}')	    /* if line starts with '}': do indent */
+		    did_si = TRUE;
+		else		    /* can delete indent when '{' typed */
+		    can_si_back = TRUE;
+	    }
+	    curwin->w_cursor = old_cursor;
+	}
+	if (do_si)
+	    can_si = TRUE;
+#endif /* FEAT_SMARTINDENT */
+
+	did_ai = TRUE;
+    }
+
+#ifdef FEAT_COMMENTS
+    /*
+     * Find out if the current line starts with a comment leader.
+     * This may then be inserted in front of the new line.
+     */
+    end_comment_pending = NUL;
+    if (flags & OPENLINE_DO_COM)
+	lead_len = get_leader_len(saved_line, &lead_flags, dir == BACKWARD);
+    else
+	lead_len = 0;
+    if (lead_len > 0)
+    {
+	char_u	*lead_repl = NULL;	    /* replaces comment leader */
+	int	lead_repl_len = 0;	    /* length of *lead_repl */
+	char_u	lead_middle[COM_MAX_LEN];   /* middle-comment string */
+	char_u	lead_end[COM_MAX_LEN];	    /* end-comment string */
+	char_u	*comment_end = NULL;	    /* where lead_end has been found */
+	int	extra_space = FALSE;	    /* append extra space */
+	int	current_flag;
+	int	require_blank = FALSE;	    /* requires blank after middle */
+	char_u	*p2;
+
+	/*
+	 * If the comment leader has the start, middle or end flag, it may not
+	 * be used or may be replaced with the middle leader.
+	 */
+	for (p = lead_flags; *p && *p != ':'; ++p)
+	{
+	    if (*p == COM_BLANK)
+	    {
+		require_blank = TRUE;
+		continue;
+	    }
+	    if (*p == COM_START || *p == COM_MIDDLE)
+	    {
+		current_flag = *p;
+		if (*p == COM_START)
+		{
+		    /*
+		     * Doing "O" on a start of comment does not insert leader.
+		     */
+		    if (dir == BACKWARD)
+		    {
+			lead_len = 0;
+			break;
+		    }
+
+		    /* find start of middle part */
+		    (void)copy_option_part(&p, lead_middle, COM_MAX_LEN, ",");
+		    require_blank = FALSE;
+		}
+
+		/*
+		 * Isolate the strings of the middle and end leader.
+		 */
+		while (*p && p[-1] != ':')	/* find end of middle flags */
+		{
+		    if (*p == COM_BLANK)
+			require_blank = TRUE;
+		    ++p;
+		}
+		(void)copy_option_part(&p, lead_middle, COM_MAX_LEN, ",");
+
+		while (*p && p[-1] != ':')	/* find end of end flags */
+		{
+		    /* Check whether we allow automatic ending of comments */
+		    if (*p == COM_AUTO_END)
+			end_comment_pending = -1; /* means we want to set it */
+		    ++p;
+		}
+		n = copy_option_part(&p, lead_end, COM_MAX_LEN, ",");
+
+		if (end_comment_pending == -1)	/* we can set it now */
+		    end_comment_pending = lead_end[n - 1];
+
+		/*
+		 * If the end of the comment is in the same line, don't use
+		 * the comment leader.
+		 */
+		if (dir == FORWARD)
+		{
+		    for (p = saved_line + lead_len; *p; ++p)
+			if (STRNCMP(p, lead_end, n) == 0)
+			{
+			    comment_end = p;
+			    lead_len = 0;
+			    break;
+			}
+		}
+
+		/*
+		 * Doing "o" on a start of comment inserts the middle leader.
+		 */
+		if (lead_len > 0)
+		{
+		    if (current_flag == COM_START)
+		    {
+			lead_repl = lead_middle;
+			lead_repl_len = (int)STRLEN(lead_middle);
+		    }
+
+		    /*
+		     * If we have hit RETURN immediately after the start
+		     * comment leader, then put a space after the middle
+		     * comment leader on the next line.
+		     */
+		    if (!vim_iswhite(saved_line[lead_len - 1])
+			    && ((p_extra != NULL
+				    && (int)curwin->w_cursor.col == lead_len)
+				|| (p_extra == NULL
+				    && saved_line[lead_len] == NUL)
+				|| require_blank))
+			extra_space = TRUE;
+		}
+		break;
+	    }
+	    if (*p == COM_END)
+	    {
+		/*
+		 * Doing "o" on the end of a comment does not insert leader.
+		 * Remember where the end is, might want to use it to find the
+		 * start (for C-comments).
+		 */
+		if (dir == FORWARD)
+		{
+		    comment_end = skipwhite(saved_line);
+		    lead_len = 0;
+		    break;
+		}
+
+		/*
+		 * Doing "O" on the end of a comment inserts the middle leader.
+		 * Find the string for the middle leader, searching backwards.
+		 */
+		while (p > curbuf->b_p_com && *p != ',')
+		    --p;
+		for (lead_repl = p; lead_repl > curbuf->b_p_com
+					 && lead_repl[-1] != ':'; --lead_repl)
+		    ;
+		lead_repl_len = (int)(p - lead_repl);
+
+		/* We can probably always add an extra space when doing "O" on
+		 * the comment-end */
+		extra_space = TRUE;
+
+		/* Check whether we allow automatic ending of comments */
+		for (p2 = p; *p2 && *p2 != ':'; p2++)
+		{
+		    if (*p2 == COM_AUTO_END)
+			end_comment_pending = -1; /* means we want to set it */
+		}
+		if (end_comment_pending == -1)
+		{
+		    /* Find last character in end-comment string */
+		    while (*p2 && *p2 != ',')
+			p2++;
+		    end_comment_pending = p2[-1];
+		}
+		break;
+	    }
+	    if (*p == COM_FIRST)
+	    {
+		/*
+		 * Comment leader for first line only:	Don't repeat leader
+		 * when using "O", blank out leader when using "o".
+		 */
+		if (dir == BACKWARD)
+		    lead_len = 0;
+		else
+		{
+		    lead_repl = (char_u *)"";
+		    lead_repl_len = 0;
+		}
+		break;
+	    }
+	}
+	if (lead_len)
+	{
+	    /* allocate buffer (may concatenate p_exta later) */
+	    leader = alloc(lead_len + lead_repl_len + extra_space +
+							      extra_len + 1);
+	    allocated = leader;		    /* remember to free it later */
+
+	    if (leader == NULL)
+		lead_len = 0;
+	    else
+	    {
+		vim_strncpy(leader, saved_line, lead_len);
+
+		/*
+		 * Replace leader with lead_repl, right or left adjusted
+		 */
+		if (lead_repl != NULL)
+		{
+		    int		c = 0;
+		    int		off = 0;
+
+		    for (p = lead_flags; *p && *p != ':'; ++p)
+		    {
+			if (*p == COM_RIGHT || *p == COM_LEFT)
+			    c = *p;
+			else if (VIM_ISDIGIT(*p) || *p == '-')
+			    off = getdigits(&p);
+		    }
+		    if (c == COM_RIGHT)    /* right adjusted leader */
+		    {
+			/* find last non-white in the leader to line up with */
+			for (p = leader + lead_len - 1; p > leader
+						      && vim_iswhite(*p); --p)
+			    ;
+			++p;
+
+#ifdef FEAT_MBYTE
+			/* Compute the length of the replaced characters in
+			 * screen characters, not bytes. */
+			{
+			    int	    repl_size = vim_strnsize(lead_repl,
+							       lead_repl_len);
+			    int	    old_size = 0;
+			    char_u  *endp = p;
+			    int	    l;
+
+			    while (old_size < repl_size && p > leader)
+			    {
+				mb_ptr_back(leader, p);
+				old_size += ptr2cells(p);
+			    }
+			    l = lead_repl_len - (int)(endp - p);
+			    if (l != 0)
+				mch_memmove(endp + l, endp,
+					(size_t)((leader + lead_len) - endp));
+			    lead_len += l;
+			}
+#else
+			if (p < leader + lead_repl_len)
+			    p = leader;
+			else
+			    p -= lead_repl_len;
+#endif
+			mch_memmove(p, lead_repl, (size_t)lead_repl_len);
+			if (p + lead_repl_len > leader + lead_len)
+			    p[lead_repl_len] = NUL;
+
+			/* blank-out any other chars from the old leader. */
+			while (--p >= leader)
+			{
+#ifdef FEAT_MBYTE
+			    int l = mb_head_off(leader, p);
+
+			    if (l > 1)
+			    {
+				p -= l;
+				if (ptr2cells(p) > 1)
+				{
+				    p[1] = ' ';
+				    --l;
+				}
+				mch_memmove(p + 1, p + l + 1,
+				   (size_t)((leader + lead_len) - (p + l + 1)));
+				lead_len -= l;
+				*p = ' ';
+			    }
+			    else
+#endif
+			    if (!vim_iswhite(*p))
+				*p = ' ';
+			}
+		    }
+		    else		    /* left adjusted leader */
+		    {
+			p = skipwhite(leader);
+#ifdef FEAT_MBYTE
+			/* Compute the length of the replaced characters in
+			 * screen characters, not bytes. Move the part that is
+			 * not to be overwritten. */
+			{
+			    int	    repl_size = vim_strnsize(lead_repl,
+							       lead_repl_len);
+			    int	    i;
+			    int	    l;
+
+			    for (i = 0; p[i] != NUL && i < lead_len; i += l)
+			    {
+				l = (*mb_ptr2len)(p + i);
+				if (vim_strnsize(p, i + l) > repl_size)
+				    break;
+			    }
+			    if (i != lead_repl_len)
+			    {
+				mch_memmove(p + lead_repl_len, p + i,
+				       (size_t)(lead_len - i - (leader - p)));
+				lead_len += lead_repl_len - i;
+			    }
+			}
+#endif
+			mch_memmove(p, lead_repl, (size_t)lead_repl_len);
+
+			/* Replace any remaining non-white chars in the old
+			 * leader by spaces.  Keep Tabs, the indent must
+			 * remain the same. */
+			for (p += lead_repl_len; p < leader + lead_len; ++p)
+			    if (!vim_iswhite(*p))
+			    {
+				/* Don't put a space before a TAB. */
+				if (p + 1 < leader + lead_len && p[1] == TAB)
+				{
+				    --lead_len;
+				    mch_memmove(p, p + 1,
+						     (leader + lead_len) - p);
+				}
+				else
+				{
+#ifdef FEAT_MBYTE
+				    int	    l = (*mb_ptr2len)(p);
+
+				    if (l > 1)
+				    {
+					if (ptr2cells(p) > 1)
+					{
+					    /* Replace a double-wide char with
+					     * two spaces */
+					    --l;
+					    *p++ = ' ';
+					}
+					mch_memmove(p + 1, p + l,
+						     (leader + lead_len) - p);
+					lead_len -= l - 1;
+				    }
+#endif
+				    *p = ' ';
+				}
+			    }
+			*p = NUL;
+		    }
+
+		    /* Recompute the indent, it may have changed. */
+		    if (curbuf->b_p_ai
+#ifdef FEAT_SMARTINDENT
+					|| do_si
+#endif
+							   )
+			newindent = get_indent_str(leader, (int)curbuf->b_p_ts);
+
+		    /* Add the indent offset */
+		    if (newindent + off < 0)
+		    {
+			off = -newindent;
+			newindent = 0;
+		    }
+		    else
+			newindent += off;
+
+		    /* Correct trailing spaces for the shift, so that
+		     * alignment remains equal. */
+		    while (off > 0 && lead_len > 0
+					       && leader[lead_len - 1] == ' ')
+		    {
+			/* Don't do it when there is a tab before the space */
+			if (vim_strchr(skipwhite(leader), '\t') != NULL)
+			    break;
+			--lead_len;
+			--off;
+		    }
+
+		    /* If the leader ends in white space, don't add an
+		     * extra space */
+		    if (lead_len > 0 && vim_iswhite(leader[lead_len - 1]))
+			extra_space = FALSE;
+		    leader[lead_len] = NUL;
+		}
+
+		if (extra_space)
+		{
+		    leader[lead_len++] = ' ';
+		    leader[lead_len] = NUL;
+		}
+
+		newcol = lead_len;
+
+		/*
+		 * if a new indent will be set below, remove the indent that
+		 * is in the comment leader
+		 */
+		if (newindent
+#ifdef FEAT_SMARTINDENT
+				|| did_si
+#endif
+					   )
+		{
+		    while (lead_len && vim_iswhite(*leader))
+		    {
+			--lead_len;
+			--newcol;
+			++leader;
+		    }
+		}
+
+	    }
+#ifdef FEAT_SMARTINDENT
+	    did_si = can_si = FALSE;
+#endif
+	}
+	else if (comment_end != NULL)
+	{
+	    /*
+	     * We have finished a comment, so we don't use the leader.
+	     * If this was a C-comment and 'ai' or 'si' is set do a normal
+	     * indent to align with the line containing the start of the
+	     * comment.
+	     */
+	    if (comment_end[0] == '*' && comment_end[1] == '/' &&
+			(curbuf->b_p_ai
+#ifdef FEAT_SMARTINDENT
+					|| do_si
+#endif
+							   ))
+	    {
+		old_cursor = curwin->w_cursor;
+		curwin->w_cursor.col = (colnr_T)(comment_end - saved_line);
+		if ((pos = findmatch(NULL, NUL)) != NULL)
+		{
+		    curwin->w_cursor.lnum = pos->lnum;
+		    newindent = get_indent();
+		}
+		curwin->w_cursor = old_cursor;
+	    }
+	}
+    }
+#endif
+
+    /* (State == INSERT || State == REPLACE), only when dir == FORWARD */
+    if (p_extra != NULL)
+    {
+	*p_extra = saved_char;		/* restore char that NUL replaced */
+
+	/*
+	 * When 'ai' set or "flags" has OPENLINE_DELSPACES, skip to the first
+	 * non-blank.
+	 *
+	 * When in REPLACE mode, put the deleted blanks on the replace stack,
+	 * preceded by a NUL, so they can be put back when a BS is entered.
+	 */
+	if (REPLACE_NORMAL(State))
+	    replace_push(NUL);	    /* end of extra blanks */
+	if (curbuf->b_p_ai || (flags & OPENLINE_DELSPACES))
+	{
+	    while ((*p_extra == ' ' || *p_extra == '\t')
+#ifdef FEAT_MBYTE
+		    && (!enc_utf8
+			       || !utf_iscomposing(utf_ptr2char(p_extra + 1)))
+#endif
+		    )
+	    {
+		if (REPLACE_NORMAL(State))
+		    replace_push(*p_extra);
+		++p_extra;
+		++less_cols_off;
+	    }
+	}
+	if (*p_extra != NUL)
+	    did_ai = FALSE;	    /* append some text, don't truncate now */
+
+	/* columns for marks adjusted for removed columns */
+	less_cols = (int)(p_extra - saved_line);
+    }
+
+    if (p_extra == NULL)
+	p_extra = (char_u *)"";		    /* append empty line */
+
+#ifdef FEAT_COMMENTS
+    /* concatenate leader and p_extra, if there is a leader */
+    if (lead_len)
+    {
+	STRCAT(leader, p_extra);
+	p_extra = leader;
+	did_ai = TRUE;	    /* So truncating blanks works with comments */
+	less_cols -= lead_len;
+    }
+    else
+	end_comment_pending = NUL;  /* turns out there was no leader */
+#endif
+
+    old_cursor = curwin->w_cursor;
+    if (dir == BACKWARD)
+	--curwin->w_cursor.lnum;
+#ifdef FEAT_VREPLACE
+    if (!(State & VREPLACE_FLAG) || old_cursor.lnum >= orig_line_count)
+#endif
+    {
+	if (ml_append(curwin->w_cursor.lnum, p_extra, (colnr_T)0, FALSE)
+								      == FAIL)
+	    goto theend;
+	/* Postpone calling changed_lines(), because it would mess up folding
+	 * with markers. */
+	mark_adjust(curwin->w_cursor.lnum + 1, (linenr_T)MAXLNUM, 1L, 0L);
+	did_append = TRUE;
+    }
+#ifdef FEAT_VREPLACE
+    else
+    {
+	/*
+	 * In VREPLACE mode we are starting to replace the next line.
+	 */
+	curwin->w_cursor.lnum++;
+	if (curwin->w_cursor.lnum >= Insstart.lnum + vr_lines_changed)
+	{
+	    /* In case we NL to a new line, BS to the previous one, and NL
+	     * again, we don't want to save the new line for undo twice.
+	     */
+	    (void)u_save_cursor();		    /* errors are ignored! */
+	    vr_lines_changed++;
+	}
+	ml_replace(curwin->w_cursor.lnum, p_extra, TRUE);
+	changed_bytes(curwin->w_cursor.lnum, 0);
+	curwin->w_cursor.lnum--;
+	did_append = FALSE;
+    }
+#endif
+
+    if (newindent
+#ifdef FEAT_SMARTINDENT
+		    || did_si
+#endif
+				)
+    {
+	++curwin->w_cursor.lnum;
+#ifdef FEAT_SMARTINDENT
+	if (did_si)
+	{
+	    if (p_sr)
+		newindent -= newindent % (int)curbuf->b_p_sw;
+	    newindent += (int)curbuf->b_p_sw;
+	}
+#endif
+	/* Copy the indent only if expand tab is disabled */
+	if (curbuf->b_p_ci && !curbuf->b_p_et)
+	{
+	    (void)copy_indent(newindent, saved_line);
+
+	    /*
+	     * Set the 'preserveindent' option so that any further screwing
+	     * with the line doesn't entirely destroy our efforts to preserve
+	     * it.  It gets restored at the function end.
+	     */
+	    curbuf->b_p_pi = TRUE;
+	}
+	else
+	    (void)set_indent(newindent, SIN_INSERT);
+	less_cols -= curwin->w_cursor.col;
+
+	ai_col = curwin->w_cursor.col;
+
+	/*
+	 * In REPLACE mode, for each character in the new indent, there must
+	 * be a NUL on the replace stack, for when it is deleted with BS
+	 */
+	if (REPLACE_NORMAL(State))
+	    for (n = 0; n < (int)curwin->w_cursor.col; ++n)
+		replace_push(NUL);
+	newcol += curwin->w_cursor.col;
+#ifdef FEAT_SMARTINDENT
+	if (no_si)
+	    did_si = FALSE;
+#endif
+    }
+
+#ifdef FEAT_COMMENTS
+    /*
+     * In REPLACE mode, for each character in the extra leader, there must be
+     * a NUL on the replace stack, for when it is deleted with BS.
+     */
+    if (REPLACE_NORMAL(State))
+	while (lead_len-- > 0)
+	    replace_push(NUL);
+#endif
+
+    curwin->w_cursor = old_cursor;
+
+    if (dir == FORWARD)
+    {
+	if (trunc_line || (State & INSERT))
+	{
+	    /* truncate current line at cursor */
+	    saved_line[curwin->w_cursor.col] = NUL;
+	    /* Remove trailing white space, unless OPENLINE_KEEPTRAIL used. */
+	    if (trunc_line && !(flags & OPENLINE_KEEPTRAIL))
+		truncate_spaces(saved_line);
+	    ml_replace(curwin->w_cursor.lnum, saved_line, FALSE);
+	    saved_line = NULL;
+	    if (did_append)
+	    {
+		changed_lines(curwin->w_cursor.lnum, curwin->w_cursor.col,
+					       curwin->w_cursor.lnum + 1, 1L);
+		did_append = FALSE;
+
+		/* Move marks after the line break to the new line. */
+		if (flags & OPENLINE_MARKFIX)
+		    mark_col_adjust(curwin->w_cursor.lnum,
+					 curwin->w_cursor.col + less_cols_off,
+							1L, (long)-less_cols);
+	    }
+	    else
+		changed_bytes(curwin->w_cursor.lnum, curwin->w_cursor.col);
+	}
+
+	/*
+	 * Put the cursor on the new line.  Careful: the scrollup() above may
+	 * have moved w_cursor, we must use old_cursor.
+	 */
+	curwin->w_cursor.lnum = old_cursor.lnum + 1;
+    }
+    if (did_append)
+	changed_lines(curwin->w_cursor.lnum, 0, curwin->w_cursor.lnum, 1L);
+
+    curwin->w_cursor.col = newcol;
+#ifdef FEAT_VIRTUALEDIT
+    curwin->w_cursor.coladd = 0;
+#endif
+
+#if defined(FEAT_VREPLACE) && (defined(FEAT_LISP) || defined(FEAT_CINDENT))
+    /*
+     * In VREPLACE mode, we are handling the replace stack ourselves, so stop
+     * fixthisline() from doing it (via change_indent()) by telling it we're in
+     * normal INSERT mode.
+     */
+    if (State & VREPLACE_FLAG)
+    {
+	vreplace_mode = State;	/* So we know to put things right later */
+	State = INSERT;
+    }
+    else
+	vreplace_mode = 0;
+#endif
+#ifdef FEAT_LISP
+    /*
+     * May do lisp indenting.
+     */
+    if (!p_paste
+# ifdef FEAT_COMMENTS
+	    && leader == NULL
+# endif
+	    && curbuf->b_p_lisp
+	    && curbuf->b_p_ai)
+    {
+	fixthisline(get_lisp_indent);
+	p = ml_get_curline();
+	ai_col = (colnr_T)(skipwhite(p) - p);
+    }
+#endif
+#ifdef FEAT_CINDENT
+    /*
+     * May do indenting after opening a new line.
+     */
+    if (!p_paste
+	    && (curbuf->b_p_cin
+#  ifdef FEAT_EVAL
+		    || *curbuf->b_p_inde != NUL
+#  endif
+		)
+	    && in_cinkeys(dir == FORWARD
+		? KEY_OPEN_FORW
+		: KEY_OPEN_BACK, ' ', linewhite(curwin->w_cursor.lnum)))
+    {
+	do_c_expr_indent();
+	p = ml_get_curline();
+	ai_col = (colnr_T)(skipwhite(p) - p);
+    }
+#endif
+#if defined(FEAT_VREPLACE) && (defined(FEAT_LISP) || defined(FEAT_CINDENT))
+    if (vreplace_mode != 0)
+	State = vreplace_mode;
+#endif
+
+#ifdef FEAT_VREPLACE
+    /*
+     * Finally, VREPLACE gets the stuff on the new line, then puts back the
+     * original line, and inserts the new stuff char by char, pushing old stuff
+     * onto the replace stack (via ins_char()).
+     */
+    if (State & VREPLACE_FLAG)
+    {
+	/* Put new line in p_extra */
+	p_extra = vim_strsave(ml_get_curline());
+	if (p_extra == NULL)
+	    goto theend;
+
+	/* Put back original line */
+	ml_replace(curwin->w_cursor.lnum, next_line, FALSE);
+
+	/* Insert new stuff into line again */
+	curwin->w_cursor.col = 0;
+#ifdef FEAT_VIRTUALEDIT
+	curwin->w_cursor.coladd = 0;
+#endif
+	ins_bytes(p_extra);	/* will call changed_bytes() */
+	vim_free(p_extra);
+	next_line = NULL;
+    }
+#endif
+
+    retval = TRUE;		/* success! */
+theend:
+    curbuf->b_p_pi = saved_pi;
+    vim_free(saved_line);
+    vim_free(next_line);
+    vim_free(allocated);
+    return retval;
+}
+
+#if defined(FEAT_COMMENTS) || defined(PROTO)
+/*
+ * get_leader_len() returns the length of the prefix of the given string
+ * which introduces a comment.	If this string is not a comment then 0 is
+ * returned.
+ * When "flags" is not NULL, it is set to point to the flags of the recognized
+ * comment leader.
+ * "backward" must be true for the "O" command.
+ */
+    int
+get_leader_len(line, flags, backward)
+    char_u	*line;
+    char_u	**flags;
+    int		backward;
+{
+    int		i, j;
+    int		got_com = FALSE;
+    int		found_one;
+    char_u	part_buf[COM_MAX_LEN];	/* buffer for one option part */
+    char_u	*string;		/* pointer to comment string */
+    char_u	*list;
+
+    i = 0;
+    while (vim_iswhite(line[i]))    /* leading white space is ignored */
+	++i;
+
+    /*
+     * Repeat to match several nested comment strings.
+     */
+    while (line[i])
+    {
+	/*
+	 * scan through the 'comments' option for a match
+	 */
+	found_one = FALSE;
+	for (list = curbuf->b_p_com; *list; )
+	{
+	    /*
+	     * Get one option part into part_buf[].  Advance list to next one.
+	     * put string at start of string.
+	     */
+	    if (!got_com && flags != NULL)  /* remember where flags started */
+		*flags = list;
+	    (void)copy_option_part(&list, part_buf, COM_MAX_LEN, ",");
+	    string = vim_strchr(part_buf, ':');
+	    if (string == NULL)	    /* missing ':', ignore this part */
+		continue;
+	    *string++ = NUL;	    /* isolate flags from string */
+
+	    /*
+	     * When already found a nested comment, only accept further
+	     * nested comments.
+	     */
+	    if (got_com && vim_strchr(part_buf, COM_NEST) == NULL)
+		continue;
+
+	    /* When 'O' flag used don't use for "O" command */
+	    if (backward && vim_strchr(part_buf, COM_NOBACK) != NULL)
+		continue;
+
+	    /*
+	     * Line contents and string must match.
+	     * When string starts with white space, must have some white space
+	     * (but the amount does not need to match, there might be a mix of
+	     * TABs and spaces).
+	     */
+	    if (vim_iswhite(string[0]))
+	    {
+		if (i == 0 || !vim_iswhite(line[i - 1]))
+		    continue;
+		while (vim_iswhite(string[0]))
+		    ++string;
+	    }
+	    for (j = 0; string[j] != NUL && string[j] == line[i + j]; ++j)
+		;
+	    if (string[j] != NUL)
+		continue;
+
+	    /*
+	     * When 'b' flag used, there must be white space or an
+	     * end-of-line after the string in the line.
+	     */
+	    if (vim_strchr(part_buf, COM_BLANK) != NULL
+			   && !vim_iswhite(line[i + j]) && line[i + j] != NUL)
+		continue;
+
+	    /*
+	     * We have found a match, stop searching.
+	     */
+	    i += j;
+	    got_com = TRUE;
+	    found_one = TRUE;
+	    break;
+	}
+
+	/*
+	 * No match found, stop scanning.
+	 */
+	if (!found_one)
+	    break;
+
+	/*
+	 * Include any trailing white space.
+	 */
+	while (vim_iswhite(line[i]))
+	    ++i;
+
+	/*
+	 * If this comment doesn't nest, stop here.
+	 */
+	if (vim_strchr(part_buf, COM_NEST) == NULL)
+	    break;
+    }
+    return (got_com ? i : 0);
+}
+#endif
+
+/*
+ * Return the number of window lines occupied by buffer line "lnum".
+ */
+    int
+plines(lnum)
+    linenr_T	lnum;
+{
+    return plines_win(curwin, lnum, TRUE);
+}
+
+    int
+plines_win(wp, lnum, winheight)
+    win_T	*wp;
+    linenr_T	lnum;
+    int		winheight;	/* when TRUE limit to window height */
+{
+#if defined(FEAT_DIFF) || defined(PROTO)
+    /* Check for filler lines above this buffer line.  When folded the result
+     * is one line anyway. */
+    return plines_win_nofill(wp, lnum, winheight) + diff_check_fill(wp, lnum);
+}
+
+    int
+plines_nofill(lnum)
+    linenr_T	lnum;
+{
+    return plines_win_nofill(curwin, lnum, TRUE);
+}
+
+    int
+plines_win_nofill(wp, lnum, winheight)
+    win_T	*wp;
+    linenr_T	lnum;
+    int		winheight;	/* when TRUE limit to window height */
+{
+#endif
+    int		lines;
+
+    if (!wp->w_p_wrap)
+	return 1;
+
+#ifdef FEAT_VERTSPLIT
+    if (wp->w_width == 0)
+	return 1;
+#endif
+
+#ifdef FEAT_FOLDING
+    /* A folded lines is handled just like an empty line. */
+    /* NOTE: Caller must handle lines that are MAYBE folded. */
+    if (lineFolded(wp, lnum) == TRUE)
+	return 1;
+#endif
+
+    lines = plines_win_nofold(wp, lnum);
+    if (winheight > 0 && lines > wp->w_height)
+	return (int)wp->w_height;
+    return lines;
+}
+
+/*
+ * Return number of window lines physical line "lnum" will occupy in window
+ * "wp".  Does not care about folding, 'wrap' or 'diff'.
+ */
+    int
+plines_win_nofold(wp, lnum)
+    win_T	*wp;
+    linenr_T	lnum;
+{
+    char_u	*s;
+    long	col;
+    int		width;
+
+    s = ml_get_buf(wp->w_buffer, lnum, FALSE);
+    if (*s == NUL)		/* empty line */
+	return 1;
+    col = win_linetabsize(wp, s, (colnr_T)MAXCOL);
+
+    /*
+     * If list mode is on, then the '$' at the end of the line may take up one
+     * extra column.
+     */
+    if (wp->w_p_list && lcs_eol != NUL)
+	col += 1;
+
+    /*
+     * Add column offset for 'number' and 'foldcolumn'.
+     */
+    width = W_WIDTH(wp) - win_col_off(wp);
+    if (width <= 0)
+	return 32000;
+    if (col <= width)
+	return 1;
+    col -= width;
+    width += win_col_off2(wp);
+    return (col + (width - 1)) / width + 1;
+}
+
+/*
+ * Like plines_win(), but only reports the number of physical screen lines
+ * used from the start of the line to the given column number.
+ */
+    int
+plines_win_col(wp, lnum, column)
+    win_T	*wp;
+    linenr_T	lnum;
+    long	column;
+{
+    long	col;
+    char_u	*s;
+    int		lines = 0;
+    int		width;
+
+#ifdef FEAT_DIFF
+    /* Check for filler lines above this buffer line.  When folded the result
+     * is one line anyway. */
+    lines = diff_check_fill(wp, lnum);
+#endif
+
+    if (!wp->w_p_wrap)
+	return lines + 1;
+
+#ifdef FEAT_VERTSPLIT
+    if (wp->w_width == 0)
+	return lines + 1;
+#endif
+
+    s = ml_get_buf(wp->w_buffer, lnum, FALSE);
+
+    col = 0;
+    while (*s != NUL && --column >= 0)
+    {
+	col += win_lbr_chartabsize(wp, s, (colnr_T)col, NULL);
+	mb_ptr_adv(s);
+    }
+
+    /*
+     * If *s is a TAB, and the TAB is not displayed as ^I, and we're not in
+     * INSERT mode, then col must be adjusted so that it represents the last
+     * screen position of the TAB.  This only fixes an error when the TAB wraps
+     * from one screen line to the next (when 'columns' is not a multiple of
+     * 'ts') -- webb.
+     */
+    if (*s == TAB && (State & NORMAL) && (!wp->w_p_list || lcs_tab1))
+	col += win_lbr_chartabsize(wp, s, (colnr_T)col, NULL) - 1;
+
+    /*
+     * Add column offset for 'number', 'foldcolumn', etc.
+     */
+    width = W_WIDTH(wp) - win_col_off(wp);
+    if (width <= 0)
+	return 9999;
+
+    lines += 1;
+    if (col > width)
+	lines += (col - width) / (width + win_col_off2(wp)) + 1;
+    return lines;
+}
+
+    int
+plines_m_win(wp, first, last)
+    win_T	*wp;
+    linenr_T	first, last;
+{
+    int		count = 0;
+
+    while (first <= last)
+    {
+#ifdef FEAT_FOLDING
+	int	x;
+
+	/* Check if there are any really folded lines, but also included lines
+	 * that are maybe folded. */
+	x = foldedCount(wp, first, NULL);
+	if (x > 0)
+	{
+	    ++count;	    /* count 1 for "+-- folded" line */
+	    first += x;
+	}
+	else
+#endif
+	{
+#ifdef FEAT_DIFF
+	    if (first == wp->w_topline)
+		count += plines_win_nofill(wp, first, TRUE) + wp->w_topfill;
+	    else
+#endif
+		count += plines_win(wp, first, TRUE);
+	    ++first;
+	}
+    }
+    return (count);
+}
+
+#if defined(FEAT_VREPLACE) || defined(FEAT_INS_EXPAND) || defined(PROTO)
+/*
+ * Insert string "p" at the cursor position.  Stops at a NUL byte.
+ * Handles Replace mode and multi-byte characters.
+ */
+    void
+ins_bytes(p)
+    char_u	*p;
+{
+    ins_bytes_len(p, (int)STRLEN(p));
+}
+#endif
+
+#if defined(FEAT_VREPLACE) || defined(FEAT_INS_EXPAND) \
+	|| defined(FEAT_COMMENTS) || defined(FEAT_MBYTE) || defined(PROTO)
+/*
+ * Insert string "p" with length "len" at the cursor position.
+ * Handles Replace mode and multi-byte characters.
+ */
+    void
+ins_bytes_len(p, len)
+    char_u	*p;
+    int		len;
+{
+    int		i;
+# ifdef FEAT_MBYTE
+    int		n;
+
+    for (i = 0; i < len; i += n)
+    {
+	n = (*mb_ptr2len)(p + i);
+	ins_char_bytes(p + i, n);
+    }
+# else
+    for (i = 0; i < len; ++i)
+	ins_char(p[i]);
+# endif
+}
+#endif
+
+/*
+ * Insert or replace a single character at the cursor position.
+ * When in REPLACE or VREPLACE mode, replace any existing character.
+ * Caller must have prepared for undo.
+ * For multi-byte characters we get the whole character, the caller must
+ * convert bytes to a character.
+ */
+    void
+ins_char(c)
+    int		c;
+{
+#if defined(FEAT_MBYTE) || defined(PROTO)
+    char_u	buf[MB_MAXBYTES];
+    int		n;
+
+    n = (*mb_char2bytes)(c, buf);
+
+    /* When "c" is 0x100, 0x200, etc. we don't want to insert a NUL byte.
+     * Happens for CTRL-Vu9900. */
+    if (buf[0] == 0)
+	buf[0] = '\n';
+
+    ins_char_bytes(buf, n);
+}
+
+    void
+ins_char_bytes(buf, charlen)
+    char_u	*buf;
+    int		charlen;
+{
+    int		c = buf[0];
+    int		l, j;
+#endif
+    int		newlen;		/* nr of bytes inserted */
+    int		oldlen;		/* nr of bytes deleted (0 when not replacing) */
+    char_u	*p;
+    char_u	*newp;
+    char_u	*oldp;
+    int		linelen;	/* length of old line including NUL */
+    colnr_T	col;
+    linenr_T	lnum = curwin->w_cursor.lnum;
+    int		i;
+
+#ifdef FEAT_VIRTUALEDIT
+    /* Break tabs if needed. */
+    if (virtual_active() && curwin->w_cursor.coladd > 0)
+	coladvance_force(getviscol());
+#endif
+
+    col = curwin->w_cursor.col;
+    oldp = ml_get(lnum);
+    linelen = (int)STRLEN(oldp) + 1;
+
+    /* The lengths default to the values for when not replacing. */
+    oldlen = 0;
+#ifdef FEAT_MBYTE
+    newlen = charlen;
+#else
+    newlen = 1;
+#endif
+
+    if (State & REPLACE_FLAG)
+    {
+#ifdef FEAT_VREPLACE
+	if (State & VREPLACE_FLAG)
+	{
+	    colnr_T	new_vcol = 0;   /* init for GCC */
+	    colnr_T	vcol;
+	    int		old_list;
+#ifndef FEAT_MBYTE
+	    char_u	buf[2];
+#endif
+
+	    /*
+	     * Disable 'list' temporarily, unless 'cpo' contains the 'L' flag.
+	     * Returns the old value of list, so when finished,
+	     * curwin->w_p_list should be set back to this.
+	     */
+	    old_list = curwin->w_p_list;
+	    if (old_list && vim_strchr(p_cpo, CPO_LISTWM) == NULL)
+		curwin->w_p_list = FALSE;
+
+	    /*
+	     * In virtual replace mode each character may replace one or more
+	     * characters (zero if it's a TAB).  Count the number of bytes to
+	     * be deleted to make room for the new character, counting screen
+	     * cells.  May result in adding spaces to fill a gap.
+	     */
+	    getvcol(curwin, &curwin->w_cursor, NULL, &vcol, NULL);
+#ifndef FEAT_MBYTE
+	    buf[0] = c;
+	    buf[1] = NUL;
+#endif
+	    new_vcol = vcol + chartabsize(buf, vcol);
+	    while (oldp[col + oldlen] != NUL && vcol < new_vcol)
+	    {
+		vcol += chartabsize(oldp + col + oldlen, vcol);
+		/* Don't need to remove a TAB that takes us to the right
+		 * position. */
+		if (vcol > new_vcol && oldp[col + oldlen] == TAB)
+		    break;
+#ifdef FEAT_MBYTE
+		oldlen += (*mb_ptr2len)(oldp + col + oldlen);
+#else
+		++oldlen;
+#endif
+		/* Deleted a bit too much, insert spaces. */
+		if (vcol > new_vcol)
+		    newlen += vcol - new_vcol;
+	    }
+	    curwin->w_p_list = old_list;
+	}
+	else
+#endif
+	    if (oldp[col] != NUL)
+	{
+	    /* normal replace */
+#ifdef FEAT_MBYTE
+	    oldlen = (*mb_ptr2len)(oldp + col);
+#else
+	    oldlen = 1;
+#endif
+	}
+
+
+	/* Push the replaced bytes onto the replace stack, so that they can be
+	 * put back when BS is used.  The bytes of a multi-byte character are
+	 * done the other way around, so that the first byte is popped off
+	 * first (it tells the byte length of the character). */
+	replace_push(NUL);
+	for (i = 0; i < oldlen; ++i)
+	{
+#ifdef FEAT_MBYTE
+	    l = (*mb_ptr2len)(oldp + col + i) - 1;
+	    for (j = l; j >= 0; --j)
+		replace_push(oldp[col + i + j]);
+	    i += l;
+#else
+	    replace_push(oldp[col + i]);
+#endif
+	}
+    }
+
+    newp = alloc_check((unsigned)(linelen + newlen - oldlen));
+    if (newp == NULL)
+	return;
+
+    /* Copy bytes before the cursor. */
+    if (col > 0)
+	mch_memmove(newp, oldp, (size_t)col);
+
+    /* Copy bytes after the changed character(s). */
+    p = newp + col;
+    mch_memmove(p + newlen, oldp + col + oldlen,
+					    (size_t)(linelen - col - oldlen));
+
+    /* Insert or overwrite the new character. */
+#ifdef FEAT_MBYTE
+    mch_memmove(p, buf, charlen);
+    i = charlen;
+#else
+    *p = c;
+    i = 1;
+#endif
+
+    /* Fill with spaces when necessary. */
+    while (i < newlen)
+	p[i++] = ' ';
+
+    /* Replace the line in the buffer. */
+    ml_replace(lnum, newp, FALSE);
+
+    /* mark the buffer as changed and prepare for displaying */
+    changed_bytes(lnum, col);
+
+    /*
+     * If we're in Insert or Replace mode and 'showmatch' is set, then briefly
+     * show the match for right parens and braces.
+     */
+    if (p_sm && (State & INSERT)
+	    && msg_silent == 0
+#ifdef FEAT_MBYTE
+	    && charlen == 1
+#endif
+#ifdef FEAT_INS_EXPAND
+	    && !ins_compl_active()
+#endif
+       )
+	showmatch(c);
+
+#ifdef FEAT_RIGHTLEFT
+    if (!p_ri || (State & REPLACE_FLAG))
+#endif
+    {
+	/* Normal insert: move cursor right */
+#ifdef FEAT_MBYTE
+	curwin->w_cursor.col += charlen;
+#else
+	++curwin->w_cursor.col;
+#endif
+    }
+    /*
+     * TODO: should try to update w_row here, to avoid recomputing it later.
+     */
+}
+
+/*
+ * Insert a string at the cursor position.
+ * Note: Does NOT handle Replace mode.
+ * Caller must have prepared for undo.
+ */
+    void
+ins_str(s)
+    char_u	*s;
+{
+    char_u	*oldp, *newp;
+    int		newlen = (int)STRLEN(s);
+    int		oldlen;
+    colnr_T	col;
+    linenr_T	lnum = curwin->w_cursor.lnum;
+
+#ifdef FEAT_VIRTUALEDIT
+    if (virtual_active() && curwin->w_cursor.coladd > 0)
+	coladvance_force(getviscol());
+#endif
+
+    col = curwin->w_cursor.col;
+    oldp = ml_get(lnum);
+    oldlen = (int)STRLEN(oldp);
+
+    newp = alloc_check((unsigned)(oldlen + newlen + 1));
+    if (newp == NULL)
+	return;
+    if (col > 0)
+	mch_memmove(newp, oldp, (size_t)col);
+    mch_memmove(newp + col, s, (size_t)newlen);
+    mch_memmove(newp + col + newlen, oldp + col, (size_t)(oldlen - col + 1));
+    ml_replace(lnum, newp, FALSE);
+    changed_bytes(lnum, col);
+    curwin->w_cursor.col += newlen;
+}
+
+/*
+ * Delete one character under the cursor.
+ * If "fixpos" is TRUE, don't leave the cursor on the NUL after the line.
+ * Caller must have prepared for undo.
+ *
+ * return FAIL for failure, OK otherwise
+ */
+    int
+del_char(fixpos)
+    int		fixpos;
+{
+#ifdef FEAT_MBYTE
+    if (has_mbyte)
+    {
+	/* Make sure the cursor is at the start of a character. */
+	mb_adjust_cursor();
+	if (*ml_get_cursor() == NUL)
+	    return FAIL;
+	return del_chars(1L, fixpos);
+    }
+#endif
+    return del_bytes(1L, fixpos, TRUE);
+}
+
+#if defined(FEAT_MBYTE) || defined(PROTO)
+/*
+ * Like del_bytes(), but delete characters instead of bytes.
+ */
+    int
+del_chars(count, fixpos)
+    long	count;
+    int		fixpos;
+{
+    long	bytes = 0;
+    long	i;
+    char_u	*p;
+    int		l;
+
+    p = ml_get_cursor();
+    for (i = 0; i < count && *p != NUL; ++i)
+    {
+	l = (*mb_ptr2len)(p);
+	bytes += l;
+	p += l;
+    }
+    return del_bytes(bytes, fixpos, TRUE);
+}
+#endif
+
+/*
+ * Delete "count" bytes under the cursor.
+ * If "fixpos" is TRUE, don't leave the cursor on the NUL after the line.
+ * Caller must have prepared for undo.
+ *
+ * return FAIL for failure, OK otherwise
+ */
+/*ARGSUSED*/
+    int
+del_bytes(count, fixpos_arg, use_delcombine)
+    long	count;
+    int		fixpos_arg;
+    int		use_delcombine;	    /* 'delcombine' option applies */
+{
+    char_u	*oldp, *newp;
+    colnr_T	oldlen;
+    linenr_T	lnum = curwin->w_cursor.lnum;
+    colnr_T	col = curwin->w_cursor.col;
+    int		was_alloced;
+    long	movelen;
+    int		fixpos = fixpos_arg;
+
+    oldp = ml_get(lnum);
+    oldlen = (int)STRLEN(oldp);
+
+    /*
+     * Can't do anything when the cursor is on the NUL after the line.
+     */
+    if (col >= oldlen)
+	return FAIL;
+
+#ifdef FEAT_MBYTE
+    /* If 'delcombine' is set and deleting (less than) one character, only
+     * delete the last combining character. */
+    if (p_deco && use_delcombine && enc_utf8
+					 && utfc_ptr2len(oldp + col) >= count)
+    {
+	int	cc[MAX_MCO];
+	int	n;
+
+	(void)utfc_ptr2char(oldp + col, cc);
+	if (cc[0] != NUL)
+	{
+	    /* Find the last composing char, there can be several. */
+	    n = col;
+	    do
+	    {
+		col = n;
+		count = utf_ptr2len(oldp + n);
+		n += count;
+	    } while (UTF_COMPOSINGLIKE(oldp + col, oldp + n));
+	    fixpos = 0;
+	}
+    }
+#endif
+
+    /*
+     * When count is too big, reduce it.
+     */
+    movelen = (long)oldlen - (long)col - count + 1; /* includes trailing NUL */
+    if (movelen <= 1)
+    {
+	/*
+	 * If we just took off the last character of a non-blank line, and
+	 * fixpos is TRUE, we don't want to end up positioned at the NUL,
+	 * unless "restart_edit" is set or 'virtualedit' contains "onemore".
+	 */
+	if (col > 0 && fixpos && restart_edit == 0
+#ifdef FEAT_VIRTUALEDIT
+					      && (ve_flags & VE_ONEMORE) == 0
+#endif
+					      )
+	{
+	    --curwin->w_cursor.col;
+#ifdef FEAT_VIRTUALEDIT
+	    curwin->w_cursor.coladd = 0;
+#endif
+#ifdef FEAT_MBYTE
+	    if (has_mbyte)
+		curwin->w_cursor.col -=
+			    (*mb_head_off)(oldp, oldp + curwin->w_cursor.col);
+#endif
+	}
+	count = oldlen - col;
+	movelen = 1;
+    }
+
+    /*
+     * If the old line has been allocated the deletion can be done in the
+     * existing line. Otherwise a new line has to be allocated
+     */
+    was_alloced = ml_line_alloced();	    /* check if oldp was allocated */
+#ifdef FEAT_NETBEANS_INTG
+    if (was_alloced && usingNetbeans)
+	netbeans_removed(curbuf, lnum, col, count);
+    /* else is handled by ml_replace() */
+#endif
+    if (was_alloced)
+	newp = oldp;			    /* use same allocated memory */
+    else
+    {					    /* need to allocate a new line */
+	newp = alloc((unsigned)(oldlen + 1 - count));
+	if (newp == NULL)
+	    return FAIL;
+	mch_memmove(newp, oldp, (size_t)col);
+    }
+    mch_memmove(newp + col, oldp + col + count, (size_t)movelen);
+    if (!was_alloced)
+	ml_replace(lnum, newp, FALSE);
+
+    /* mark the buffer as changed and prepare for displaying */
+    changed_bytes(lnum, curwin->w_cursor.col);
+
+    return OK;
+}
+
+/*
+ * Delete from cursor to end of line.
+ * Caller must have prepared for undo.
+ *
+ * return FAIL for failure, OK otherwise
+ */
+    int
+truncate_line(fixpos)
+    int		fixpos;	    /* if TRUE fix the cursor position when done */
+{
+    char_u	*newp;
+    linenr_T	lnum = curwin->w_cursor.lnum;
+    colnr_T	col = curwin->w_cursor.col;
+
+    if (col == 0)
+	newp = vim_strsave((char_u *)"");
+    else
+	newp = vim_strnsave(ml_get(lnum), col);
+
+    if (newp == NULL)
+	return FAIL;
+
+    ml_replace(lnum, newp, FALSE);
+
+    /* mark the buffer as changed and prepare for displaying */
+    changed_bytes(lnum, curwin->w_cursor.col);
+
+    /*
+     * If "fixpos" is TRUE we don't want to end up positioned at the NUL.
+     */
+    if (fixpos && curwin->w_cursor.col > 0)
+	--curwin->w_cursor.col;
+
+    return OK;
+}
+
+/*
+ * Delete "nlines" lines at the cursor.
+ * Saves the lines for undo first if "undo" is TRUE.
+ */
+    void
+del_lines(nlines, undo)
+    long	nlines;		/* number of lines to delete */
+    int		undo;		/* if TRUE, prepare for undo */
+{
+    long	n;
+
+    if (nlines <= 0)
+	return;
+
+    /* save the deleted lines for undo */
+    if (undo && u_savedel(curwin->w_cursor.lnum, nlines) == FAIL)
+	return;
+
+    for (n = 0; n < nlines; )
+    {
+	if (curbuf->b_ml.ml_flags & ML_EMPTY)	    /* nothing to delete */
+	    break;
+
+	ml_delete(curwin->w_cursor.lnum, TRUE);
+	++n;
+
+	/* If we delete the last line in the file, stop */
+	if (curwin->w_cursor.lnum > curbuf->b_ml.ml_line_count)
+	    break;
+    }
+    /* adjust marks, mark the buffer as changed and prepare for displaying */
+    deleted_lines_mark(curwin->w_cursor.lnum, n);
+
+    curwin->w_cursor.col = 0;
+    check_cursor_lnum();
+}
+
+    int
+gchar_pos(pos)
+    pos_T *pos;
+{
+    char_u	*ptr = ml_get_pos(pos);
+
+#ifdef FEAT_MBYTE
+    if (has_mbyte)
+	return (*mb_ptr2char)(ptr);
+#endif
+    return (int)*ptr;
+}
+
+    int
+gchar_cursor()
+{
+#ifdef FEAT_MBYTE
+    if (has_mbyte)
+	return (*mb_ptr2char)(ml_get_cursor());
+#endif
+    return (int)*ml_get_cursor();
+}
+
+/*
+ * Write a character at the current cursor position.
+ * It is directly written into the block.
+ */
+    void
+pchar_cursor(c)
+    int c;
+{
+    *(ml_get_buf(curbuf, curwin->w_cursor.lnum, TRUE)
+						  + curwin->w_cursor.col) = c;
+}
+
+#if 0 /* not used */
+/*
+ * Put *pos at end of current buffer
+ */
+    void
+goto_endofbuf(pos)
+    pos_T    *pos;
+{
+    char_u  *p;
+
+    pos->lnum = curbuf->b_ml.ml_line_count;
+    pos->col = 0;
+    p = ml_get(pos->lnum);
+    while (*p++)
+	++pos->col;
+}
+#endif
+
+/*
+ * When extra == 0: Return TRUE if the cursor is before or on the first
+ *		    non-blank in the line.
+ * When extra == 1: Return TRUE if the cursor is before the first non-blank in
+ *		    the line.
+ */
+    int
+inindent(extra)
+    int	    extra;
+{
+    char_u	*ptr;
+    colnr_T	col;
+
+    for (col = 0, ptr = ml_get_curline(); vim_iswhite(*ptr); ++col)
+	++ptr;
+    if (col >= curwin->w_cursor.col + extra)
+	return TRUE;
+    else
+	return FALSE;
+}
+
+/*
+ * Skip to next part of an option argument: Skip space and comma.
+ */
+    char_u *
+skip_to_option_part(p)
+    char_u  *p;
+{
+    if (*p == ',')
+	++p;
+    while (*p == ' ')
+	++p;
+    return p;
+}
+
+/*
+ * changed() is called when something in the current buffer is changed.
+ *
+ * Most often called through changed_bytes() and changed_lines(), which also
+ * mark the area of the display to be redrawn.
+ */
+    void
+changed()
+{
+#if defined(FEAT_XIM) && defined(FEAT_GUI_GTK)
+    /* The text of the preediting area is inserted, but this doesn't
+     * mean a change of the buffer yet.  That is delayed until the
+     * text is committed. (this means preedit becomes empty) */
+    if (im_is_preediting() && !xim_changed_while_preediting)
+	return;
+    xim_changed_while_preediting = FALSE;
+#endif
+
+    if (!curbuf->b_changed)
+    {
+	int	save_msg_scroll = msg_scroll;
+
+	/* Give a warning about changing a read-only file.  This may also
+	 * check-out the file, thus change "curbuf"! */
+	change_warning(0);
+
+	/* Create a swap file if that is wanted.
+	 * Don't do this for "nofile" and "nowrite" buffer types. */
+	if (curbuf->b_may_swap
+#ifdef FEAT_QUICKFIX
+		&& !bt_dontwrite(curbuf)
+#endif
+		)
+	{
+	    ml_open_file(curbuf);
+
+	    /* The ml_open_file() can cause an ATTENTION message.
+	     * Wait two seconds, to make sure the user reads this unexpected
+	     * message.  Since we could be anywhere, call wait_return() now,
+	     * and don't let the emsg() set msg_scroll. */
+	    if (need_wait_return && emsg_silent == 0)
+	    {
+		out_flush();
+		ui_delay(2000L, TRUE);
+		wait_return(TRUE);
+		msg_scroll = save_msg_scroll;
+	    }
+	}
+	curbuf->b_changed = TRUE;
+	ml_setflags(curbuf);
+#ifdef FEAT_WINDOWS
+	check_status(curbuf);
+	redraw_tabline = TRUE;
+#endif
+#ifdef FEAT_TITLE
+	need_maketitle = TRUE;	    /* set window title later */
+#endif
+    }
+    ++curbuf->b_changedtick;
+}
+
+static void changedOneline __ARGS((buf_T *buf, linenr_T lnum));
+static void changed_lines_buf __ARGS((buf_T *buf, linenr_T lnum, linenr_T lnume, long xtra));
+static void changed_common __ARGS((linenr_T lnum, colnr_T col, linenr_T lnume, long xtra));
+
+/*
+ * Changed bytes within a single line for the current buffer.
+ * - marks the windows on this buffer to be redisplayed
+ * - marks the buffer changed by calling changed()
+ * - invalidates cached values
+ */
+    void
+changed_bytes(lnum, col)
+    linenr_T	lnum;
+    colnr_T	col;
+{
+    changedOneline(curbuf, lnum);
+    changed_common(lnum, col, lnum + 1, 0L);
+
+#ifdef FEAT_DIFF
+    /* Diff highlighting in other diff windows may need to be updated too. */
+    if (curwin->w_p_diff)
+    {
+	win_T	    *wp;
+	linenr_T    wlnum;
+
+	for (wp = firstwin; wp != NULL; wp = wp->w_next)
+	    if (wp->w_p_diff && wp != curwin)
+	    {
+		redraw_win_later(wp, VALID);
+		wlnum = diff_lnum_win(lnum, wp);
+		if (wlnum > 0)
+		    changedOneline(wp->w_buffer, wlnum);
+	    }
+    }
+#endif
+}
+
+    static void
+changedOneline(buf, lnum)
+    buf_T	*buf;
+    linenr_T	lnum;
+{
+    if (buf->b_mod_set)
+    {
+	/* find the maximum area that must be redisplayed */
+	if (lnum < buf->b_mod_top)
+	    buf->b_mod_top = lnum;
+	else if (lnum >= buf->b_mod_bot)
+	    buf->b_mod_bot = lnum + 1;
+    }
+    else
+    {
+	/* set the area that must be redisplayed to one line */
+	buf->b_mod_set = TRUE;
+	buf->b_mod_top = lnum;
+	buf->b_mod_bot = lnum + 1;
+	buf->b_mod_xlines = 0;
+    }
+}
+
+/*
+ * Appended "count" lines below line "lnum" in the current buffer.
+ * Must be called AFTER the change and after mark_adjust().
+ * Takes care of marking the buffer to be redrawn and sets the changed flag.
+ */
+    void
+appended_lines(lnum, count)
+    linenr_T	lnum;
+    long	count;
+{
+    changed_lines(lnum + 1, 0, lnum + 1, count);
+}
+
+/*
+ * Like appended_lines(), but adjust marks first.
+ */
+    void
+appended_lines_mark(lnum, count)
+    linenr_T	lnum;
+    long	count;
+{
+    mark_adjust(lnum + 1, (linenr_T)MAXLNUM, count, 0L);
+    changed_lines(lnum + 1, 0, lnum + 1, count);
+}
+
+/*
+ * Deleted "count" lines at line "lnum" in the current buffer.
+ * Must be called AFTER the change and after mark_adjust().
+ * Takes care of marking the buffer to be redrawn and sets the changed flag.
+ */
+    void
+deleted_lines(lnum, count)
+    linenr_T	lnum;
+    long	count;
+{
+    changed_lines(lnum, 0, lnum + count, -count);
+}
+
+/*
+ * Like deleted_lines(), but adjust marks first.
+ */
+    void
+deleted_lines_mark(lnum, count)
+    linenr_T	lnum;
+    long	count;
+{
+    mark_adjust(lnum, (linenr_T)(lnum + count - 1), (long)MAXLNUM, -count);
+    changed_lines(lnum, 0, lnum + count, -count);
+}
+
+/*
+ * Changed lines for the current buffer.
+ * Must be called AFTER the change and after mark_adjust().
+ * - mark the buffer changed by calling changed()
+ * - mark the windows on this buffer to be redisplayed
+ * - invalidate cached values
+ * "lnum" is the first line that needs displaying, "lnume" the first line
+ * below the changed lines (BEFORE the change).
+ * When only inserting lines, "lnum" and "lnume" are equal.
+ * Takes care of calling changed() and updating b_mod_*.
+ */
+    void
+changed_lines(lnum, col, lnume, xtra)
+    linenr_T	lnum;	    /* first line with change */
+    colnr_T	col;	    /* column in first line with change */
+    linenr_T	lnume;	    /* line below last changed line */
+    long	xtra;	    /* number of extra lines (negative when deleting) */
+{
+    changed_lines_buf(curbuf, lnum, lnume, xtra);
+
+#ifdef FEAT_DIFF
+    if (xtra == 0 && curwin->w_p_diff)
+    {
+	/* When the number of lines doesn't change then mark_adjust() isn't
+	 * called and other diff buffers still need to be marked for
+	 * displaying. */
+	win_T	    *wp;
+	linenr_T    wlnum;
+
+	for (wp = firstwin; wp != NULL; wp = wp->w_next)
+	    if (wp->w_p_diff && wp != curwin)
+	    {
+		redraw_win_later(wp, VALID);
+		wlnum = diff_lnum_win(lnum, wp);
+		if (wlnum > 0)
+		    changed_lines_buf(wp->w_buffer, wlnum,
+						    lnume - lnum + wlnum, 0L);
+	    }
+    }
+#endif
+
+    changed_common(lnum, col, lnume, xtra);
+}
+
+    static void
+changed_lines_buf(buf, lnum, lnume, xtra)
+    buf_T	*buf;
+    linenr_T	lnum;	    /* first line with change */
+    linenr_T	lnume;	    /* line below last changed line */
+    long	xtra;	    /* number of extra lines (negative when deleting) */
+{
+    if (buf->b_mod_set)
+    {
+	/* find the maximum area that must be redisplayed */
+	if (lnum < buf->b_mod_top)
+	    buf->b_mod_top = lnum;
+	if (lnum < buf->b_mod_bot)
+	{
+	    /* adjust old bot position for xtra lines */
+	    buf->b_mod_bot += xtra;
+	    if (buf->b_mod_bot < lnum)
+		buf->b_mod_bot = lnum;
+	}
+	if (lnume + xtra > buf->b_mod_bot)
+	    buf->b_mod_bot = lnume + xtra;
+	buf->b_mod_xlines += xtra;
+    }
+    else
+    {
+	/* set the area that must be redisplayed */
+	buf->b_mod_set = TRUE;
+	buf->b_mod_top = lnum;
+	buf->b_mod_bot = lnume + xtra;
+	buf->b_mod_xlines = xtra;
+    }
+}
+
+    static void
+changed_common(lnum, col, lnume, xtra)
+    linenr_T	lnum;
+    colnr_T	col;
+    linenr_T	lnume;
+    long	xtra;
+{
+    win_T	*wp;
+    int		i;
+#ifdef FEAT_JUMPLIST
+    int		cols;
+    pos_T	*p;
+    int		add;
+#endif
+
+    /* mark the buffer as modified */
+    changed();
+
+    /* set the '. mark */
+    if (!cmdmod.keepjumps)
+    {
+	curbuf->b_last_change.lnum = lnum;
+	curbuf->b_last_change.col = col;
+
+#ifdef FEAT_JUMPLIST
+	/* Create a new entry if a new undo-able change was started or we
+	 * don't have an entry yet. */
+	if (curbuf->b_new_change || curbuf->b_changelistlen == 0)
+	{
+	    if (curbuf->b_changelistlen == 0)
+		add = TRUE;
+	    else
+	    {
+		/* Don't create a new entry when the line number is the same
+		 * as the last one and the column is not too far away.  Avoids
+		 * creating many entries for typing "xxxxx". */
+		p = &curbuf->b_changelist[curbuf->b_changelistlen - 1];
+		if (p->lnum != lnum)
+		    add = TRUE;
+		else
+		{
+		    cols = comp_textwidth(FALSE);
+		    if (cols == 0)
+			cols = 79;
+		    add = (p->col + cols < col || col + cols < p->col);
+		}
+	    }
+	    if (add)
+	    {
+		/* This is the first of a new sequence of undo-able changes
+		 * and it's at some distance of the last change.  Use a new
+		 * position in the changelist. */
+		curbuf->b_new_change = FALSE;
+
+		if (curbuf->b_changelistlen == JUMPLISTSIZE)
+		{
+		    /* changelist is full: remove oldest entry */
+		    curbuf->b_changelistlen = JUMPLISTSIZE - 1;
+		    mch_memmove(curbuf->b_changelist, curbuf->b_changelist + 1,
+					  sizeof(pos_T) * (JUMPLISTSIZE - 1));
+		    FOR_ALL_WINDOWS(wp)
+		    {
+			/* Correct position in changelist for other windows on
+			 * this buffer. */
+			if (wp->w_buffer == curbuf && wp->w_changelistidx > 0)
+			    --wp->w_changelistidx;
+		    }
+		}
+		FOR_ALL_WINDOWS(wp)
+		{
+		    /* For other windows, if the position in the changelist is
+		     * at the end it stays at the end. */
+		    if (wp->w_buffer == curbuf
+			    && wp->w_changelistidx == curbuf->b_changelistlen)
+			++wp->w_changelistidx;
+		}
+		++curbuf->b_changelistlen;
+	    }
+	}
+	curbuf->b_changelist[curbuf->b_changelistlen - 1] =
+							curbuf->b_last_change;
+	/* The current window is always after the last change, so that "g,"
+	 * takes you back to it. */
+	curwin->w_changelistidx = curbuf->b_changelistlen;
+#endif
+    }
+
+    FOR_ALL_WINDOWS(wp)
+    {
+	if (wp->w_buffer == curbuf)
+	{
+	    /* Mark this window to be redrawn later. */
+	    if (wp->w_redr_type < VALID)
+		wp->w_redr_type = VALID;
+
+	    /* Check if a change in the buffer has invalidated the cached
+	     * values for the cursor. */
+#ifdef FEAT_FOLDING
+	    /*
+	     * Update the folds for this window.  Can't postpone this, because
+	     * a following operator might work on the whole fold: ">>dd".
+	     */
+	    foldUpdate(wp, lnum, lnume + xtra - 1);
+
+	    /* The change may cause lines above or below the change to become
+	     * included in a fold.  Set lnum/lnume to the first/last line that
+	     * might be displayed differently.
+	     * Set w_cline_folded here as an efficient way to update it when
+	     * inserting lines just above a closed fold. */
+	    i = hasFoldingWin(wp, lnum, &lnum, NULL, FALSE, NULL);
+	    if (wp->w_cursor.lnum == lnum)
+		wp->w_cline_folded = i;
+	    i = hasFoldingWin(wp, lnume, NULL, &lnume, FALSE, NULL);
+	    if (wp->w_cursor.lnum == lnume)
+		wp->w_cline_folded = i;
+
+	    /* If the changed line is in a range of previously folded lines,
+	     * compare with the first line in that range. */
+	    if (wp->w_cursor.lnum <= lnum)
+	    {
+		i = find_wl_entry(wp, lnum);
+		if (i >= 0 && wp->w_cursor.lnum > wp->w_lines[i].wl_lnum)
+		    changed_line_abv_curs_win(wp);
+	    }
+#endif
+
+	    if (wp->w_cursor.lnum > lnum)
+		changed_line_abv_curs_win(wp);
+	    else if (wp->w_cursor.lnum == lnum && wp->w_cursor.col >= col)
+		changed_cline_bef_curs_win(wp);
+	    if (wp->w_botline >= lnum)
+	    {
+		/* Assume that botline doesn't change (inserted lines make
+		 * other lines scroll down below botline). */
+		approximate_botline_win(wp);
+	    }
+
+	    /* Check if any w_lines[] entries have become invalid.
+	     * For entries below the change: Correct the lnums for
+	     * inserted/deleted lines.  Makes it possible to stop displaying
+	     * after the change. */
+	    for (i = 0; i < wp->w_lines_valid; ++i)
+		if (wp->w_lines[i].wl_valid)
+		{
+		    if (wp->w_lines[i].wl_lnum >= lnum)
+		    {
+			if (wp->w_lines[i].wl_lnum < lnume)
+			{
+			    /* line included in change */
+			    wp->w_lines[i].wl_valid = FALSE;
+			}
+			else if (xtra != 0)
+			{
+			    /* line below change */
+			    wp->w_lines[i].wl_lnum += xtra;
+#ifdef FEAT_FOLDING
+			    wp->w_lines[i].wl_lastlnum += xtra;
+#endif
+			}
+		    }
+#ifdef FEAT_FOLDING
+		    else if (wp->w_lines[i].wl_lastlnum >= lnum)
+		    {
+			/* change somewhere inside this range of folded lines,
+			 * may need to be redrawn */
+			wp->w_lines[i].wl_valid = FALSE;
+		    }
+#endif
+		}
+	}
+    }
+
+    /* Call update_screen() later, which checks out what needs to be redrawn,
+     * since it notices b_mod_set and then uses b_mod_*. */
+    if (must_redraw < VALID)
+	must_redraw = VALID;
+
+#ifdef FEAT_AUTOCMD
+    /* when the cursor line is changed always trigger CursorMoved */
+    if (lnum <= curwin->w_cursor.lnum
+		 && lnume + (xtra < 0 ? -xtra : xtra) > curwin->w_cursor.lnum)
+	last_cursormoved.lnum = 0;
+#endif
+}
+
+/*
+ * unchanged() is called when the changed flag must be reset for buffer 'buf'
+ */
+    void
+unchanged(buf, ff)
+    buf_T	*buf;
+    int		ff;	/* also reset 'fileformat' */
+{
+    if (buf->b_changed || (ff && file_ff_differs(buf)))
+    {
+	buf->b_changed = 0;
+	ml_setflags(buf);
+	if (ff)
+	    save_file_ff(buf);
+#ifdef FEAT_WINDOWS
+	check_status(buf);
+	redraw_tabline = TRUE;
+#endif
+#ifdef FEAT_TITLE
+	need_maketitle = TRUE;	    /* set window title later */
+#endif
+    }
+    ++buf->b_changedtick;
+#ifdef FEAT_NETBEANS_INTG
+    netbeans_unmodified(buf);
+#endif
+}
+
+#if defined(FEAT_WINDOWS) || defined(PROTO)
+/*
+ * check_status: called when the status bars for the buffer 'buf'
+ *		 need to be updated
+ */
+    void
+check_status(buf)
+    buf_T	*buf;
+{
+    win_T	*wp;
+
+    for (wp = firstwin; wp != NULL; wp = wp->w_next)
+	if (wp->w_buffer == buf && wp->w_status_height)
+	{
+	    wp->w_redr_status = TRUE;
+	    if (must_redraw < VALID)
+		must_redraw = VALID;
+	}
+}
+#endif
+
+/*
+ * If the file is readonly, give a warning message with the first change.
+ * Don't do this for autocommands.
+ * Don't use emsg(), because it flushes the macro buffer.
+ * If we have undone all changes b_changed will be FALSE, but "b_did_warn"
+ * will be TRUE.
+ */
+    void
+change_warning(col)
+    int	    col;		/* column for message; non-zero when in insert
+				   mode and 'showmode' is on */
+{
+    if (curbuf->b_did_warn == FALSE
+	    && curbufIsChanged() == 0
+#ifdef FEAT_AUTOCMD
+	    && !autocmd_busy
+#endif
+	    && curbuf->b_p_ro)
+    {
+#ifdef FEAT_AUTOCMD
+	++curbuf_lock;
+	apply_autocmds(EVENT_FILECHANGEDRO, NULL, NULL, FALSE, curbuf);
+	--curbuf_lock;
+	if (!curbuf->b_p_ro)
+	    return;
+#endif
+	/*
+	 * Do what msg() does, but with a column offset if the warning should
+	 * be after the mode message.
+	 */
+	msg_start();
+	if (msg_row == Rows - 1)
+	    msg_col = col;
+	msg_source(hl_attr(HLF_W));
+	MSG_PUTS_ATTR(_("W10: Warning: Changing a readonly file"),
+						   hl_attr(HLF_W) | MSG_HIST);
+	msg_clr_eos();
+	(void)msg_end();
+	if (msg_silent == 0 && !silent_mode)
+	{
+	    out_flush();
+	    ui_delay(1000L, TRUE); /* give the user time to think about it */
+	}
+	curbuf->b_did_warn = TRUE;
+	redraw_cmdline = FALSE;	/* don't redraw and erase the message */
+	if (msg_row < Rows - 1)
+	    showmode();
+    }
+}
+
+/*
+ * Ask for a reply from the user, a 'y' or a 'n'.
+ * No other characters are accepted, the message is repeated until a valid
+ * reply is entered or CTRL-C is hit.
+ * If direct is TRUE, don't use vgetc() but ui_inchar(), don't get characters
+ * from any buffers but directly from the user.
+ *
+ * return the 'y' or 'n'
+ */
+    int
+ask_yesno(str, direct)
+    char_u  *str;
+    int	    direct;
+{
+    int	    r = ' ';
+    int	    save_State = State;
+
+    if (exiting)		/* put terminal in raw mode for this question */
+	settmode(TMODE_RAW);
+    ++no_wait_return;
+#ifdef USE_ON_FLY_SCROLL
+    dont_scroll = TRUE;		/* disallow scrolling here */
+#endif
+    State = CONFIRM;		/* mouse behaves like with :confirm */
+#ifdef FEAT_MOUSE
+    setmouse();			/* disables mouse for xterm */
+#endif
+    ++no_mapping;
+    ++allow_keys;		/* no mapping here, but recognize keys */
+
+    while (r != 'y' && r != 'n')
+    {
+	/* same highlighting as for wait_return */
+	smsg_attr(hl_attr(HLF_R), (char_u *)"%s (y/n)?", str);
+	if (direct)
+	    r = get_keystroke();
+	else
+	    r = safe_vgetc();
+	if (r == Ctrl_C || r == ESC)
+	    r = 'n';
+	msg_putchar(r);	    /* show what you typed */
+	out_flush();
+    }
+    --no_wait_return;
+    State = save_State;
+#ifdef FEAT_MOUSE
+    setmouse();
+#endif
+    --no_mapping;
+    --allow_keys;
+
+    return r;
+}
+
+/*
+ * Get a key stroke directly from the user.
+ * Ignores mouse clicks and scrollbar events, except a click for the left
+ * button (used at the more prompt).
+ * Doesn't use vgetc(), because it syncs undo and eats mapped characters.
+ * Disadvantage: typeahead is ignored.
+ * Translates the interrupt character for unix to ESC.
+ */
+    int
+get_keystroke()
+{
+#define CBUFLEN 151
+    char_u	buf[CBUFLEN];
+    int		len = 0;
+    int		n;
+    int		save_mapped_ctrl_c = mapped_ctrl_c;
+    int		waited = 0;
+
+    mapped_ctrl_c = FALSE;	/* mappings are not used here */
+    for (;;)
+    {
+	cursor_on();
+	out_flush();
+
+	/* First time: blocking wait.  Second time: wait up to 100ms for a
+	 * terminal code to complete.  Leave some room for check_termcode() to
+	 * insert a key code into (max 5 chars plus NUL).  And
+	 * fix_input_buffer() can triple the number of bytes. */
+	n = ui_inchar(buf + len, (CBUFLEN - 6 - len) / 3,
+						    len == 0 ? -1L : 100L, 0);
+	if (n > 0)
+	{
+	    /* Replace zero and CSI by a special key code. */
+	    n = fix_input_buffer(buf + len, n, FALSE);
+	    len += n;
+	    waited = 0;
+	}
+	else if (len > 0)
+	    ++waited;	    /* keep track of the waiting time */
+
+	/* Incomplete termcode and not timed out yet: get more characters */
+	if ((n = check_termcode(1, buf, len)) < 0
+	       && (!p_ttimeout || waited * 100L < (p_ttm < 0 ? p_tm : p_ttm)))
+	    continue;
+
+	/* found a termcode: adjust length */
+	if (n > 0)
+	    len = n;
+	if (len == 0)	    /* nothing typed yet */
+	    continue;
+
+	/* Handle modifier and/or special key code. */
+	n = buf[0];
+	if (n == K_SPECIAL)
+	{
+	    n = TO_SPECIAL(buf[1], buf[2]);
+	    if (buf[1] == KS_MODIFIER
+		    || n == K_IGNORE
+#ifdef FEAT_MOUSE
+		    || n == K_LEFTMOUSE_NM
+		    || n == K_LEFTDRAG
+		    || n == K_LEFTRELEASE
+		    || n == K_LEFTRELEASE_NM
+		    || n == K_MIDDLEMOUSE
+		    || n == K_MIDDLEDRAG
+		    || n == K_MIDDLERELEASE
+		    || n == K_RIGHTMOUSE
+		    || n == K_RIGHTDRAG
+		    || n == K_RIGHTRELEASE
+		    || n == K_MOUSEDOWN
+		    || n == K_MOUSEUP
+		    || n == K_X1MOUSE
+		    || n == K_X1DRAG
+		    || n == K_X1RELEASE
+		    || n == K_X2MOUSE
+		    || n == K_X2DRAG
+		    || n == K_X2RELEASE
+# ifdef FEAT_GUI
+		    || n == K_VER_SCROLLBAR
+		    || n == K_HOR_SCROLLBAR
+# endif
+#endif
+	       )
+	    {
+		if (buf[1] == KS_MODIFIER)
+		    mod_mask = buf[2];
+		len -= 3;
+		if (len > 0)
+		    mch_memmove(buf, buf + 3, (size_t)len);
+		continue;
+	    }
+	    break;
+	}
+#ifdef FEAT_MBYTE
+	if (has_mbyte)
+	{
+	    if (MB_BYTE2LEN(n) > len)
+		continue;	/* more bytes to get */
+	    buf[len >= CBUFLEN ? CBUFLEN - 1 : len] = NUL;
+	    n = (*mb_ptr2char)(buf);
+	}
+#endif
+#ifdef UNIX
+	if (n == intr_char)
+	    n = ESC;
+#endif
+	break;
+    }
+
+    mapped_ctrl_c = save_mapped_ctrl_c;
+    return n;
+}
+
+/*
+ * Get a number from the user.
+ * When "mouse_used" is not NULL allow using the mouse.
+ */
+    int
+get_number(colon, mouse_used)
+    int	    colon;			/* allow colon to abort */
+    int	    *mouse_used;
+{
+    int	n = 0;
+    int	c;
+    int typed = 0;
+
+    if (mouse_used != NULL)
+	*mouse_used = FALSE;
+
+    /* When not printing messages, the user won't know what to type, return a
+     * zero (as if CR was hit). */
+    if (msg_silent != 0)
+	return 0;
+
+#ifdef USE_ON_FLY_SCROLL
+    dont_scroll = TRUE;		/* disallow scrolling here */
+#endif
+    ++no_mapping;
+    ++allow_keys;		/* no mapping here, but recognize keys */
+    for (;;)
+    {
+	windgoto(msg_row, msg_col);
+	c = safe_vgetc();
+	if (VIM_ISDIGIT(c))
+	{
+	    n = n * 10 + c - '0';
+	    msg_putchar(c);
+	    ++typed;
+	}
+	else if (c == K_DEL || c == K_KDEL || c == K_BS || c == Ctrl_H)
+	{
+	    if (typed > 0)
+	    {
+		MSG_PUTS("\b \b");
+		--typed;
+	    }
+	    n /= 10;
+	}
+#ifdef FEAT_MOUSE
+	else if (mouse_used != NULL && c == K_LEFTMOUSE)
+	{
+	    *mouse_used = TRUE;
+	    n = mouse_row + 1;
+	    break;
+	}
+#endif
+	else if (n == 0 && c == ':' && colon)
+	{
+	    stuffcharReadbuff(':');
+	    if (!exmode_active)
+		cmdline_row = msg_row;
+	    skip_redraw = TRUE;	    /* skip redraw once */
+	    do_redraw = FALSE;
+	    break;
+	}
+	else if (c == CAR || c == NL || c == Ctrl_C || c == ESC)
+	    break;
+    }
+    --no_mapping;
+    --allow_keys;
+    return n;
+}
+
+/*
+ * Ask the user to enter a number.
+ * When "mouse_used" is not NULL allow using the mouse and in that case return
+ * the line number.
+ */
+    int
+prompt_for_number(mouse_used)
+    int		*mouse_used;
+{
+    int		i;
+    int		save_cmdline_row;
+    int		save_State;
+
+    /* When using ":silent" assume that <CR> was entered. */
+    if (mouse_used != NULL)
+	MSG_PUTS(_("Type number or click with mouse (<Enter> cancels): "));
+    else
+	MSG_PUTS(_("Choice number (<Enter> cancels): "));
+
+    /* Set the state such that text can be selected/copied/pasted and we still
+     * get mouse events. */
+    save_cmdline_row = cmdline_row;
+    cmdline_row = 0;
+    save_State = State;
+    State = CMDLINE;
+
+    i = get_number(TRUE, mouse_used);
+    if (KeyTyped)
+    {
+	/* don't call wait_return() now */
+	/* msg_putchar('\n'); */
+	cmdline_row = msg_row - 1;
+	need_wait_return = FALSE;
+	msg_didany = FALSE;
+    }
+    else
+	cmdline_row = save_cmdline_row;
+    State = save_State;
+
+    return i;
+}
+
+    void
+msgmore(n)
+    long n;
+{
+    long pn;
+
+    if (global_busy	    /* no messages now, wait until global is finished */
+	    || !messaging())  /* 'lazyredraw' set, don't do messages now */
+	return;
+
+    /* We don't want to overwrite another important message, but do overwrite
+     * a previous "more lines" or "fewer lines" message, so that "5dd" and
+     * then "put" reports the last action. */
+    if (keep_msg != NULL && !keep_msg_more)
+	return;
+
+    if (n > 0)
+	pn = n;
+    else
+	pn = -n;
+
+    if (pn > p_report)
+    {
+	if (pn == 1)
+	{
+	    if (n > 0)
+		STRCPY(msg_buf, _("1 more line"));
+	    else
+		STRCPY(msg_buf, _("1 line less"));
+	}
+	else
+	{
+	    if (n > 0)
+		sprintf((char *)msg_buf, _("%ld more lines"), pn);
+	    else
+		sprintf((char *)msg_buf, _("%ld fewer lines"), pn);
+	}
+	if (got_int)
+	    STRCAT(msg_buf, _(" (Interrupted)"));
+	if (msg(msg_buf))
+	{
+	    set_keep_msg(msg_buf, 0);
+	    keep_msg_more = TRUE;
+	}
+    }
+}
+
+/*
+ * flush map and typeahead buffers and give a warning for an error
+ */
+    void
+beep_flush()
+{
+    if (emsg_silent == 0)
+    {
+	flush_buffers(FALSE);
+	vim_beep();
+    }
+}
+
+/*
+ * give a warning for an error
+ */
+    void
+vim_beep()
+{
+    if (emsg_silent == 0)
+    {
+	if (p_vb
+#ifdef FEAT_GUI
+		/* While the GUI is starting up the termcap is set for the GUI
+		 * but the output still goes to a terminal. */
+		&& !(gui.in_use && gui.starting)
+#endif
+		)
+	{
+	    out_str(T_VB);
+	}
+	else
+	{
+#ifdef MSDOS
+	    /*
+	     * The number of beeps outputted is reduced to avoid having to wait
+	     * for all the beeps to finish. This is only a problem on systems
+	     * where the beeps don't overlap.
+	     */
+	    if (beep_count == 0 || beep_count == 10)
+	    {
+		out_char(BELL);
+		beep_count = 1;
+	    }
+	    else
+		++beep_count;
+#else
+	    out_char(BELL);
+#endif
+	}
+
+	/* When 'verbose' is set and we are sourcing a script or executing a
+	 * function give the user a hint where the beep comes from. */
+	if (vim_strchr(p_debug, 'e') != NULL)
+	{
+	    msg_source(hl_attr(HLF_W));
+	    msg_attr((char_u *)_("Beep!"), hl_attr(HLF_W));
+	}
+    }
+}
+
+/*
+ * To get the "real" home directory:
+ * - get value of $HOME
+ * For Unix:
+ *  - go to that directory
+ *  - do mch_dirname() to get the real name of that directory.
+ *  This also works with mounts and links.
+ *  Don't do this for MS-DOS, it will change the "current dir" for a drive.
+ */
+static char_u	*homedir = NULL;
+
+    void
+init_homedir()
+{
+    char_u  *var;
+
+    /* In case we are called a second time (when 'encoding' changes). */
+    vim_free(homedir);
+    homedir = NULL;
+
+#if defined(VMS)
+    var = mch_getenv((char_u *)"SYS$LOGIN");
+#elif defined(PLAN9)
+    var = mch_getenv((char_u *)"home");
+#else
+    var = mch_getenv((char_u *)"HOME");
+#endif
+
+    if (var != NULL && *var == NUL)	/* empty is same as not set */
+	var = NULL;
+
+#ifdef WIN3264
+    /*
+     * Weird but true: $HOME may contain an indirect reference to another
+     * variable, esp. "%USERPROFILE%".  Happens when $USERPROFILE isn't set
+     * when $HOME is being set.
+     */
+    if (var != NULL && *var == '%')
+    {
+	char_u	*p;
+	char_u	*exp;
+
+	p = vim_strchr(var + 1, '%');
+	if (p != NULL)
+	{
+	    vim_strncpy(NameBuff, var + 1, p - (var + 1));
+	    exp = mch_getenv(NameBuff);
+	    if (exp != NULL && *exp != NUL
+					&& STRLEN(exp) + STRLEN(p) < MAXPATHL)
+	    {
+		vim_snprintf((char *)NameBuff, MAXPATHL, "%s%s", exp, p + 1);
+		var = NameBuff;
+		/* Also set $HOME, it's needed for _viminfo. */
+		vim_setenv((char_u *)"HOME", NameBuff);
+	    }
+	}
+    }
+
+    /*
+     * Typically, $HOME is not defined on Windows, unless the user has
+     * specifically defined it for Vim's sake.  However, on Windows NT
+     * platforms, $HOMEDRIVE and $HOMEPATH are automatically defined for
+     * each user.  Try constructing $HOME from these.
+     */
+    if (var == NULL)
+    {
+	char_u *homedrive, *homepath;
+
+	homedrive = mch_getenv((char_u *)"HOMEDRIVE");
+	homepath = mch_getenv((char_u *)"HOMEPATH");
+	if (homedrive != NULL && homepath != NULL
+			   && STRLEN(homedrive) + STRLEN(homepath) < MAXPATHL)
+	{
+	    sprintf((char *)NameBuff, "%s%s", homedrive, homepath);
+	    if (NameBuff[0] != NUL)
+	    {
+		var = NameBuff;
+		/* Also set $HOME, it's needed for _viminfo. */
+		vim_setenv((char_u *)"HOME", NameBuff);
+	    }
+	}
+    }
+
+# if defined(FEAT_MBYTE)
+    if (enc_utf8 && var != NULL)
+    {
+	int	len;
+	char_u  *pp;
+
+	/* Convert from active codepage to UTF-8.  Other conversions are
+	 * not done, because they would fail for non-ASCII characters. */
+	acp_to_enc(var, (int)STRLEN(var), &pp, &len);
+	if (pp != NULL)
+	{
+	    homedir = pp;
+	    return;
+	}
+    }
+# endif
+#endif
+
+#if defined(OS2) || defined(MSDOS) || defined(MSWIN)
+    /*
+     * Default home dir is C:/
+     * Best assumption we can make in such a situation.
+     */
+    if (var == NULL)
+	var = "C:/";
+#endif
+    if (var != NULL)
+    {
+#ifdef UNIX
+	/*
+	 * Change to the directory and get the actual path.  This resolves
+	 * links.  Don't do it when we can't return.
+	 */
+	if (mch_dirname(NameBuff, MAXPATHL) == OK
+					  && mch_chdir((char *)NameBuff) == 0)
+	{
+	    if (!mch_chdir((char *)var) && mch_dirname(IObuff, IOSIZE) == OK)
+		var = IObuff;
+	    if (mch_chdir((char *)NameBuff) != 0)
+		EMSG(_(e_prev_dir));
+	}
+#endif
+	homedir = vim_strsave(var);
+    }
+}
+
+#if defined(EXITFREE) || defined(PROTO)
+    void
+free_homedir()
+{
+    vim_free(homedir);
+}
+#endif
+
+/*
+ * Expand environment variable with path name.
+ * "~/" is also expanded, using $HOME.	For Unix "~user/" is expanded.
+ * Skips over "\ ", "\~" and "\$".
+ * If anything fails no expansion is done and dst equals src.
+ */
+    void
+expand_env(src, dst, dstlen)
+    char_u	*src;		/* input string e.g. "$HOME/vim.hlp" */
+    char_u	*dst;		/* where to put the result */
+    int		dstlen;		/* maximum length of the result */
+{
+    expand_env_esc(src, dst, dstlen, FALSE, NULL);
+}
+
+    void
+expand_env_esc(srcp, dst, dstlen, esc, startstr)
+    char_u	*srcp;		/* input string e.g. "$HOME/vim.hlp" */
+    char_u	*dst;		/* where to put the result */
+    int		dstlen;		/* maximum length of the result */
+    int		esc;		/* escape spaces in expanded variables */
+    char_u	*startstr;	/* start again after this (can be NULL) */
+{
+    char_u	*src;
+    char_u	*tail;
+    int		c;
+    char_u	*var;
+    int		copy_char;
+    int		mustfree;	/* var was allocated, need to free it later */
+    int		at_start = TRUE; /* at start of a name */
+    int		startstr_len = 0;
+
+    if (startstr != NULL)
+	startstr_len = (int)STRLEN(startstr);
+
+    src = skipwhite(srcp);
+    --dstlen;		    /* leave one char space for "\," */
+    while (*src && dstlen > 0)
+    {
+	copy_char = TRUE;
+	if ((*src == '$'
+#ifdef VMS
+		    && at_start
+#endif
+	   )
+#if defined(MSDOS) || defined(MSWIN) || defined(OS2)
+		|| *src == '%'
+#endif
+		|| (*src == '~' && at_start))
+	{
+	    mustfree = FALSE;
+
+	    /*
+	     * The variable name is copied into dst temporarily, because it may
+	     * be a string in read-only memory and a NUL needs to be appended.
+	     */
+	    if (*src != '~')				/* environment var */
+	    {
+		tail = src + 1;
+		var = dst;
+		c = dstlen - 1;
+
+#ifdef UNIX
+		/* Unix has ${var-name} type environment vars */
+		if (*tail == '{' && !vim_isIDc('{'))
+		{
+		    tail++;	/* ignore '{' */
+		    while (c-- > 0 && *tail && *tail != '}')
+			*var++ = *tail++;
+		}
+		else
+#endif
+		{
+		    while (c-- > 0 && *tail != NUL && ((vim_isIDc(*tail))
+#if defined(MSDOS) || defined(MSWIN) || defined(OS2)
+			    || (*src == '%' && *tail != '%')
+#endif
+			    ))
+		    {
+#ifdef OS2		/* env vars only in uppercase */
+			*var++ = TOUPPER_LOC(*tail);
+			tail++;	    /* toupper() may be a macro! */
+#else
+			*var++ = *tail++;
+#endif
+		    }
+		}
+
+#if defined(MSDOS) || defined(MSWIN) || defined(OS2) || defined(UNIX)
+# ifdef UNIX
+		if (src[1] == '{' && *tail != '}')
+# else
+		if (*src == '%' && *tail != '%')
+# endif
+		    var = NULL;
+		else
+		{
+# ifdef UNIX
+		    if (src[1] == '{')
+# else
+		    if (*src == '%')
+#endif
+			++tail;
+#endif
+		    *var = NUL;
+		    var = vim_getenv(dst, &mustfree);
+#if defined(MSDOS) || defined(MSWIN) || defined(OS2) || defined(UNIX)
+		}
+#endif
+	    }
+							/* home directory */
+	    else if (  src[1] == NUL
+		    || vim_ispathsep(src[1])
+		    || vim_strchr((char_u *)" ,\t\n", src[1]) != NULL)
+	    {
+		var = homedir;
+		tail = src + 1;
+	    }
+	    else					/* user directory */
+	    {
+#if defined(UNIX) || (defined(VMS) && defined(USER_HOME))
+		/*
+		 * Copy ~user to dst[], so we can put a NUL after it.
+		 */
+		tail = src;
+		var = dst;
+		c = dstlen - 1;
+		while (	   c-- > 0
+			&& *tail
+			&& vim_isfilec(*tail)
+			&& !vim_ispathsep(*tail))
+		    *var++ = *tail++;
+		*var = NUL;
+# ifdef UNIX
+		/*
+		 * If the system supports getpwnam(), use it.
+		 * Otherwise, or if getpwnam() fails, the shell is used to
+		 * expand ~user.  This is slower and may fail if the shell
+		 * does not support ~user (old versions of /bin/sh).
+		 */
+#  if defined(HAVE_GETPWNAM) && defined(HAVE_PWD_H)
+		{
+		    struct passwd *pw;
+
+		    /* Note: memory allocated by getpwnam() is never freed.
+		     * Calling endpwent() apparently doesn't help. */
+		    pw = getpwnam((char *)dst + 1);
+		    if (pw != NULL)
+			var = (char_u *)pw->pw_dir;
+		    else
+			var = NULL;
+		}
+		if (var == NULL)
+#  endif
+		{
+		    expand_T	xpc;
+
+		    ExpandInit(&xpc);
+		    xpc.xp_context = EXPAND_FILES;
+		    var = ExpandOne(&xpc, dst, NULL,
+				WILD_ADD_SLASH|WILD_SILENT, WILD_EXPAND_FREE);
+		    mustfree = TRUE;
+		}
+
+# else	/* !UNIX, thus VMS */
+		/*
+		 * USER_HOME is a comma-separated list of
+		 * directories to search for the user account in.
+		 */
+		{
+		    char_u	test[MAXPATHL], paths[MAXPATHL];
+		    char_u	*path, *next_path, *ptr;
+		    struct stat	st;
+
+		    STRCPY(paths, USER_HOME);
+		    next_path = paths;
+		    while (*next_path)
+		    {
+			for (path = next_path; *next_path && *next_path != ',';
+				next_path++);
+			if (*next_path)
+			    *next_path++ = NUL;
+			STRCPY(test, path);
+			STRCAT(test, "/");
+			STRCAT(test, dst + 1);
+			if (mch_stat(test, &st) == 0)
+			{
+			    var = alloc(STRLEN(test) + 1);
+			    STRCPY(var, test);
+			    mustfree = TRUE;
+			    break;
+			}
+		    }
+		}
+# endif /* UNIX */
+#else
+		/* cannot expand user's home directory, so don't try */
+		var = NULL;
+		tail = (char_u *)"";	/* for gcc */
+#endif /* UNIX || VMS */
+	    }
+
+#ifdef BACKSLASH_IN_FILENAME
+	    /* If 'shellslash' is set change backslashes to forward slashes.
+	     * Can't use slash_adjust(), p_ssl may be set temporarily. */
+	    if (p_ssl && var != NULL && vim_strchr(var, '\\') != NULL)
+	    {
+		char_u	*p = vim_strsave(var);
+
+		if (p != NULL)
+		{
+		    if (mustfree)
+			vim_free(var);
+		    var = p;
+		    mustfree = TRUE;
+		    forward_slash(var);
+		}
+	    }
+#endif
+
+	    /* If "var" contains white space, escape it with a backslash.
+	     * Required for ":e ~/tt" when $HOME includes a space. */
+	    if (esc && var != NULL && vim_strpbrk(var, (char_u *)" \t") != NULL)
+	    {
+		char_u	*p = vim_strsave_escaped(var, (char_u *)" \t");
+
+		if (p != NULL)
+		{
+		    if (mustfree)
+			vim_free(var);
+		    var = p;
+		    mustfree = TRUE;
+		}
+	    }
+
+	    if (var != NULL && *var != NUL
+		    && (STRLEN(var) + STRLEN(tail) + 1 < (unsigned)dstlen))
+	    {
+		STRCPY(dst, var);
+		dstlen -= (int)STRLEN(var);
+		c = (int)STRLEN(var);
+		/* if var[] ends in a path separator and tail[] starts
+		 * with it, skip a character */
+		if (*var != NUL && after_pathsep(dst, dst + c)
+#if defined(BACKSLASH_IN_FILENAME) || defined(AMIGA)
+			&& dst[-1] != ':'
+#endif
+			&& vim_ispathsep(*tail))
+		    ++tail;
+		dst += c;
+		src = tail;
+		copy_char = FALSE;
+	    }
+	    if (mustfree)
+		vim_free(var);
+	}
+
+	if (copy_char)	    /* copy at least one char */
+	{
+	    /*
+	     * Recognize the start of a new name, for '~'.
+	     */
+	    at_start = FALSE;
+	    if (src[0] == '\\' && src[1] != NUL)
+	    {
+		*dst++ = *src++;
+		--dstlen;
+	    }
+	    else if (src[0] == ' ' || src[0] == ',')
+		at_start = TRUE;
+	    *dst++ = *src++;
+	    --dstlen;
+
+	    if (startstr != NULL && src - startstr_len >= srcp
+		    && STRNCMP(src - startstr_len, startstr, startstr_len) == 0)
+		at_start = TRUE;
+	}
+    }
+    *dst = NUL;
+}
+
+/*
+ * Vim's version of getenv().
+ * Special handling of $HOME, $VIM and $VIMRUNTIME.
+ * Also does ACP to 'enc' conversion for Win32.
+ */
+    char_u *
+vim_getenv(name, mustfree)
+    char_u	*name;
+    int		*mustfree;	/* set to TRUE when returned is allocated */
+{
+    char_u	*p;
+    char_u	*pend;
+    int		vimruntime;
+
+#if defined(OS2) || defined(MSDOS) || defined(MSWIN)
+    /* use "C:/" when $HOME is not set */
+    if (STRCMP(name, "HOME") == 0)
+	return homedir;
+#endif
+
+    p = mch_getenv(name);
+    if (p != NULL && *p == NUL)	    /* empty is the same as not set */
+	p = NULL;
+
+    if (p != NULL)
+    {
+#if defined(FEAT_MBYTE) && defined(WIN3264)
+	if (enc_utf8)
+	{
+	    int	    len;
+	    char_u  *pp;
+
+	    /* Convert from active codepage to UTF-8.  Other conversions are
+	     * not done, because they would fail for non-ASCII characters. */
+	    acp_to_enc(p, (int)STRLEN(p), &pp, &len);
+	    if (pp != NULL)
+	    {
+		p = pp;
+		*mustfree = TRUE;
+	    }
+	}
+#endif
+	return p;
+    }
+
+    vimruntime = (STRCMP(name, "VIMRUNTIME") == 0);
+    if (!vimruntime && STRCMP(name, "VIM") != 0)
+	return NULL;
+
+    /*
+     * When expanding $VIMRUNTIME fails, try using $VIM/vim<version> or $VIM.
+     * Don't do this when default_vimruntime_dir is non-empty.
+     */
+    if (vimruntime
+#ifdef HAVE_PATHDEF
+	    && *default_vimruntime_dir == NUL
+#endif
+       )
+    {
+	p = mch_getenv((char_u *)"VIM");
+	if (p != NULL && *p == NUL)	    /* empty is the same as not set */
+	    p = NULL;
+	if (p != NULL)
+	{
+	    p = vim_version_dir(p);
+	    if (p != NULL)
+		*mustfree = TRUE;
+	    else
+		p = mch_getenv((char_u *)"VIM");
+
+#if defined(FEAT_MBYTE) && defined(WIN3264)
+	    if (enc_utf8)
+	    {
+		int	len;
+		char_u  *pp;
+
+		/* Convert from active codepage to UTF-8.  Other conversions
+		 * are not done, because they would fail for non-ASCII
+		 * characters. */
+		acp_to_enc(p, (int)STRLEN(p), &pp, &len);
+		if (pp != NULL)
+		{
+		    if (mustfree)
+			vim_free(p);
+		    p = pp;
+		    *mustfree = TRUE;
+		}
+	    }
+#endif
+	}
+    }
+
+    /*
+     * When expanding $VIM or $VIMRUNTIME fails, try using:
+     * - the directory name from 'helpfile' (unless it contains '$')
+     * - the executable name from argv[0]
+     */
+    if (p == NULL)
+    {
+	if (p_hf != NULL && vim_strchr(p_hf, '$') == NULL)
+	    p = p_hf;
+#ifdef USE_EXE_NAME
+	/*
+	 * Use the name of the executable, obtained from argv[0].
+	 */
+	else
+	    p = exe_name;
+#endif
+	if (p != NULL)
+	{
+	    /* remove the file name */
+	    pend = gettail(p);
+
+	    /* remove "doc/" from 'helpfile', if present */
+	    if (p == p_hf)
+		pend = remove_tail(p, pend, (char_u *)"doc");
+
+#ifdef USE_EXE_NAME
+# ifdef MACOS_X
+	    /* remove "MacOS" from exe_name and add "Resources/vim" */
+	    if (p == exe_name)
+	    {
+		char_u	*pend1;
+		char_u	*pnew;
+
+		pend1 = remove_tail(p, pend, (char_u *)"MacOS");
+		if (pend1 != pend)
+		{
+		    pnew = alloc((unsigned)(pend1 - p) + 15);
+		    if (pnew != NULL)
+		    {
+			STRNCPY(pnew, p, (pend1 - p));
+			STRCPY(pnew + (pend1 - p), "Resources/vim");
+			p = pnew;
+			pend = p + STRLEN(p);
+		    }
+		}
+	    }
+# endif
+	    /* remove "src/" from exe_name, if present */
+	    if (p == exe_name)
+		pend = remove_tail(p, pend, (char_u *)"src");
+#endif
+
+	    /* for $VIM, remove "runtime/" or "vim54/", if present */
+	    if (!vimruntime)
+	    {
+		pend = remove_tail(p, pend, (char_u *)RUNTIME_DIRNAME);
+		pend = remove_tail(p, pend, (char_u *)VIM_VERSION_NODOT);
+	    }
+
+	    /* remove trailing path separator */
+#ifndef MACOS_CLASSIC
+	    /* With MacOS path (with  colons) the final colon is required */
+	    /* to avoid confusion between absoulute and relative path */
+	    if (pend > p && after_pathsep(p, pend))
+		--pend;
+#endif
+
+#ifdef MACOS_X
+	    if (p == exe_name || p == p_hf)
+#endif
+		/* check that the result is a directory name */
+		p = vim_strnsave(p, (int)(pend - p));
+
+	    if (p != NULL && !mch_isdir(p))
+	    {
+		vim_free(p);
+		p = NULL;
+	    }
+	    else
+	    {
+#ifdef USE_EXE_NAME
+		/* may add "/vim54" or "/runtime" if it exists */
+		if (vimruntime && (pend = vim_version_dir(p)) != NULL)
+		{
+		    vim_free(p);
+		    p = pend;
+		}
+#endif
+		*mustfree = TRUE;
+	    }
+	}
+    }
+
+#ifdef HAVE_PATHDEF
+    /* When there is a pathdef.c file we can use default_vim_dir and
+     * default_vimruntime_dir */
+    if (p == NULL)
+    {
+	/* Only use default_vimruntime_dir when it is not empty */
+	if (vimruntime && *default_vimruntime_dir != NUL)
+	{
+	    p = default_vimruntime_dir;
+	    *mustfree = FALSE;
+	}
+	else if (*default_vim_dir != NUL)
+	{
+	    if (vimruntime && (p = vim_version_dir(default_vim_dir)) != NULL)
+		*mustfree = TRUE;
+	    else
+	    {
+		p = default_vim_dir;
+		*mustfree = FALSE;
+	    }
+	}
+    }
+#endif
+
+    /*
+     * Set the environment variable, so that the new value can be found fast
+     * next time, and others can also use it (e.g. Perl).
+     */
+    if (p != NULL)
+    {
+	if (vimruntime)
+	{
+	    vim_setenv((char_u *)"VIMRUNTIME", p);
+	    didset_vimruntime = TRUE;
+#ifdef FEAT_GETTEXT
+	    {
+		char_u	*buf = concat_str(p, (char_u *)"/lang");
+
+		if (buf != NULL)
+		{
+		    bindtextdomain(VIMPACKAGE, (char *)buf);
+		    vim_free(buf);
+		}
+	    }
+#endif
+	}
+	else
+	{
+	    vim_setenv((char_u *)"VIM", p);
+	    didset_vim = TRUE;
+	}
+    }
+    return p;
+}
+
+/*
+ * Check if the directory "vimdir/<version>" or "vimdir/runtime" exists.
+ * Return NULL if not, return its name in allocated memory otherwise.
+ */
+    static char_u *
+vim_version_dir(vimdir)
+    char_u	*vimdir;
+{
+    char_u	*p;
+
+    if (vimdir == NULL || *vimdir == NUL)
+	return NULL;
+    p = concat_fnames(vimdir, (char_u *)VIM_VERSION_NODOT, TRUE);
+    if (p != NULL && mch_isdir(p))
+	return p;
+    vim_free(p);
+    p = concat_fnames(vimdir, (char_u *)RUNTIME_DIRNAME, TRUE);
+    if (p != NULL && mch_isdir(p))
+	return p;
+    vim_free(p);
+    return NULL;
+}
+
+/*
+ * If the string between "p" and "pend" ends in "name/", return "pend" minus
+ * the length of "name/".  Otherwise return "pend".
+ */
+    static char_u *
+remove_tail(p, pend, name)
+    char_u	*p;
+    char_u	*pend;
+    char_u	*name;
+{
+    int		len = (int)STRLEN(name) + 1;
+    char_u	*newend = pend - len;
+
+    if (newend >= p
+	    && fnamencmp(newend, name, len - 1) == 0
+	    && (newend == p || after_pathsep(p, newend)))
+	return newend;
+    return pend;
+}
+
+/*
+ * Call expand_env() and store the result in an allocated string.
+ * This is not very memory efficient, this expects the result to be freed
+ * again soon.
+ */
+    char_u *
+expand_env_save(src)
+    char_u	*src;
+{
+    char_u	*p;
+
+    p = alloc(MAXPATHL);
+    if (p != NULL)
+	expand_env(src, p, MAXPATHL);
+    return p;
+}
+
+/*
+ * Our portable version of setenv.
+ */
+    void
+vim_setenv(name, val)
+    char_u	*name;
+    char_u	*val;
+{
+#ifdef HAVE_SETENV
+    mch_setenv((char *)name, (char *)val, 1);
+#else
+    char_u	*envbuf;
+
+    /*
+     * Putenv does not copy the string, it has to remain
+     * valid.  The allocated memory will never be freed.
+     */
+    envbuf = alloc((unsigned)(STRLEN(name) + STRLEN(val) + 2));
+    if (envbuf != NULL)
+    {
+	sprintf((char *)envbuf, "%s=%s", name, val);
+	putenv((char *)envbuf);
+    }
+#endif
+}
+
+#if defined(FEAT_CMDL_COMPL) || defined(PROTO)
+/*
+ * Function given to ExpandGeneric() to obtain an environment variable name.
+ */
+/*ARGSUSED*/
+    char_u *
+get_env_name(xp, idx)
+    expand_T	*xp;
+    int		idx;
+{
+# if defined(AMIGA) || defined(__MRC__) || defined(__SC__)
+    /*
+     * No environ[] on the Amiga and on the Mac (using MPW).
+     */
+    return NULL;
+# else
+# ifndef __WIN32__
+    /* Borland C++ 5.2 has this in a header file. */
+    extern char		**environ;
+# endif
+# define ENVNAMELEN 100
+    static char_u	name[ENVNAMELEN];
+    char_u		*str;
+    int			n;
+
+    str = (char_u *)environ[idx];
+    if (str == NULL)
+	return NULL;
+
+    for (n = 0; n < ENVNAMELEN - 1; ++n)
+    {
+	if (str[n] == '=' || str[n] == NUL)
+	    break;
+	name[n] = str[n];
+    }
+    name[n] = NUL;
+    return name;
+# endif
+}
+#endif
+
+/*
+ * Replace home directory by "~" in each space or comma separated file name in
+ * 'src'.
+ * If anything fails (except when out of space) dst equals src.
+ */
+    void
+home_replace(buf, src, dst, dstlen, one)
+    buf_T	*buf;	/* when not NULL, check for help files */
+    char_u	*src;	/* input file name */
+    char_u	*dst;	/* where to put the result */
+    int		dstlen;	/* maximum length of the result */
+    int		one;	/* if TRUE, only replace one file name, include
+			   spaces and commas in the file name. */
+{
+    size_t	dirlen = 0, envlen = 0;
+    size_t	len;
+    char_u	*homedir_env;
+    char_u	*p;
+
+    if (src == NULL)
+    {
+	*dst = NUL;
+	return;
+    }
+
+    /*
+     * If the file is a help file, remove the path completely.
+     */
+    if (buf != NULL && buf->b_help)
+    {
+	STRCPY(dst, gettail(src));
+	return;
+    }
+
+    /*
+     * We check both the value of the $HOME environment variable and the
+     * "real" home directory.
+     */
+    if (homedir != NULL)
+	dirlen = STRLEN(homedir);
+
+#ifdef VMS
+    homedir_env = mch_getenv((char_u *)"SYS$LOGIN");
+#else
+    homedir_env = mch_getenv((char_u *)"HOME");
+#endif
+
+    if (homedir_env != NULL && *homedir_env == NUL)
+	homedir_env = NULL;
+    if (homedir_env != NULL)
+	envlen = STRLEN(homedir_env);
+
+    if (!one)
+	src = skipwhite(src);
+    while (*src && dstlen > 0)
+    {
+	/*
+	 * Here we are at the beginning of a file name.
+	 * First, check to see if the beginning of the file name matches
+	 * $HOME or the "real" home directory. Check that there is a '/'
+	 * after the match (so that if e.g. the file is "/home/pieter/bla",
+	 * and the home directory is "/home/piet", the file does not end up
+	 * as "~er/bla" (which would seem to indicate the file "bla" in user
+	 * er's home directory)).
+	 */
+	p = homedir;
+	len = dirlen;
+	for (;;)
+	{
+	    if (   len
+		&& fnamencmp(src, p, len) == 0
+		&& (vim_ispathsep(src[len])
+		    || (!one && (src[len] == ',' || src[len] == ' '))
+		    || src[len] == NUL))
+	    {
+		src += len;
+		if (--dstlen > 0)
+		    *dst++ = '~';
+
+		/*
+		 * If it's just the home directory, add  "/".
+		 */
+		if (!vim_ispathsep(src[0]) && --dstlen > 0)
+		    *dst++ = '/';
+		break;
+	    }
+	    if (p == homedir_env)
+		break;
+	    p = homedir_env;
+	    len = envlen;
+	}
+
+	/* if (!one) skip to separator: space or comma */
+	while (*src && (one || (*src != ',' && *src != ' ')) && --dstlen > 0)
+	    *dst++ = *src++;
+	/* skip separator */
+	while ((*src == ' ' || *src == ',') && --dstlen > 0)
+	    *dst++ = *src++;
+    }
+    /* if (dstlen == 0) out of space, what to do??? */
+
+    *dst = NUL;
+}
+
+/*
+ * Like home_replace, store the replaced string in allocated memory.
+ * When something fails, NULL is returned.
+ */
+    char_u  *
+home_replace_save(buf, src)
+    buf_T	*buf;	/* when not NULL, check for help files */
+    char_u	*src;	/* input file name */
+{
+    char_u	*dst;
+    unsigned	len;
+
+    len = 3;			/* space for "~/" and trailing NUL */
+    if (src != NULL)		/* just in case */
+	len += (unsigned)STRLEN(src);
+    dst = alloc(len);
+    if (dst != NULL)
+	home_replace(buf, src, dst, len, TRUE);
+    return dst;
+}
+
+/*
+ * Compare two file names and return:
+ * FPC_SAME   if they both exist and are the same file.
+ * FPC_SAMEX  if they both don't exist and have the same file name.
+ * FPC_DIFF   if they both exist and are different files.
+ * FPC_NOTX   if they both don't exist.
+ * FPC_DIFFX  if one of them doesn't exist.
+ * For the first name environment variables are expanded
+ */
+    int
+fullpathcmp(s1, s2, checkname)
+    char_u *s1, *s2;
+    int	    checkname;		/* when both don't exist, check file names */
+{
+#ifdef UNIX
+    char_u	    exp1[MAXPATHL];
+    char_u	    full1[MAXPATHL];
+    char_u	    full2[MAXPATHL];
+    struct stat	    st1, st2;
+    int		    r1, r2;
+
+    expand_env(s1, exp1, MAXPATHL);
+    r1 = mch_stat((char *)exp1, &st1);
+    r2 = mch_stat((char *)s2, &st2);
+    if (r1 != 0 && r2 != 0)
+    {
+	/* if mch_stat() doesn't work, may compare the names */
+	if (checkname)
+	{
+	    if (fnamecmp(exp1, s2) == 0)
+		return FPC_SAMEX;
+	    r1 = vim_FullName(exp1, full1, MAXPATHL, FALSE);
+	    r2 = vim_FullName(s2, full2, MAXPATHL, FALSE);
+	    if (r1 == OK && r2 == OK && fnamecmp(full1, full2) == 0)
+		return FPC_SAMEX;
+	}
+	return FPC_NOTX;
+    }
+    if (r1 != 0 || r2 != 0)
+	return FPC_DIFFX;
+    if (st1.st_dev == st2.st_dev && st1.st_ino == st2.st_ino)
+	return FPC_SAME;
+    return FPC_DIFF;
+#else
+    char_u  *exp1;		/* expanded s1 */
+    char_u  *full1;		/* full path of s1 */
+    char_u  *full2;		/* full path of s2 */
+    int	    retval = FPC_DIFF;
+    int	    r1, r2;
+
+    /* allocate one buffer to store three paths (alloc()/free() is slow!) */
+    if ((exp1 = alloc(MAXPATHL * 3)) != NULL)
+    {
+	full1 = exp1 + MAXPATHL;
+	full2 = full1 + MAXPATHL;
+
+	expand_env(s1, exp1, MAXPATHL);
+	r1 = vim_FullName(exp1, full1, MAXPATHL, FALSE);
+	r2 = vim_FullName(s2, full2, MAXPATHL, FALSE);
+
+	/* If vim_FullName() fails, the file probably doesn't exist. */
+	if (r1 != OK && r2 != OK)
+	{
+	    if (checkname && fnamecmp(exp1, s2) == 0)
+		retval = FPC_SAMEX;
+	    else
+		retval = FPC_NOTX;
+	}
+	else if (r1 != OK || r2 != OK)
+	    retval = FPC_DIFFX;
+	else if (fnamecmp(full1, full2))
+	    retval = FPC_DIFF;
+	else
+	    retval = FPC_SAME;
+	vim_free(exp1);
+    }
+    return retval;
+#endif
+}
+
+/*
+ * Get the tail of a path: the file name.
+ * Fail safe: never returns NULL.
+ */
+    char_u *
+gettail(fname)
+    char_u *fname;
+{
+    char_u  *p1, *p2;
+
+    if (fname == NULL)
+	return (char_u *)"";
+    for (p1 = p2 = fname; *p2; )	/* find last part of path */
+    {
+	if (vim_ispathsep(*p2))
+	    p1 = p2 + 1;
+	mb_ptr_adv(p2);
+    }
+    return p1;
+}
+
+/*
+ * Get pointer to tail of "fname", including path separators.  Putting a NUL
+ * here leaves the directory name.  Takes care of "c:/" and "//".
+ * Always returns a valid pointer.
+ */
+    char_u *
+gettail_sep(fname)
+    char_u	*fname;
+{
+    char_u	*p;
+    char_u	*t;
+
+    p = get_past_head(fname);	/* don't remove the '/' from "c:/file" */
+    t = gettail(fname);
+    while (t > p && after_pathsep(fname, t))
+	--t;
+#ifdef VMS
+    /* path separator is part of the path */
+    ++t;
+#endif
+    return t;
+}
+
+/*
+ * get the next path component (just after the next path separator).
+ */
+    char_u *
+getnextcomp(fname)
+    char_u *fname;
+{
+    while (*fname && !vim_ispathsep(*fname))
+	mb_ptr_adv(fname);
+    if (*fname)
+	++fname;
+    return fname;
+}
+
+/*
+ * Get a pointer to one character past the head of a path name.
+ * Unix: after "/"; DOS: after "c:\"; Amiga: after "disk:/"; Mac: no head.
+ * If there is no head, path is returned.
+ */
+    char_u *
+get_past_head(path)
+    char_u  *path;
+{
+    char_u  *retval;
+
+#if defined(MSDOS) || defined(MSWIN) || defined(OS2)
+    /* may skip "c:" */
+    if (isalpha(path[0]) && path[1] == ':')
+	retval = path + 2;
+    else
+	retval = path;
+#else
+# if defined(AMIGA)
+    /* may skip "label:" */
+    retval = vim_strchr(path, ':');
+    if (retval == NULL)
+	retval = path;
+# else	/* Unix */
+    retval = path;
+# endif
+#endif
+
+    while (vim_ispathsep(*retval))
+	++retval;
+
+    return retval;
+}
+
+/*
+ * return TRUE if 'c' is a path separator.
+ */
+    int
+vim_ispathsep(c)
+    int c;
+{
+#ifdef RISCOS
+    return (c == '.' || c == ':');
+#else
+# ifdef UNIX
+    return (c == '/');	    /* UNIX has ':' inside file names */
+# else
+#  ifdef BACKSLASH_IN_FILENAME
+    return (c == ':' || c == '/' || c == '\\');
+#  else
+#   ifdef VMS
+    /* server"user passwd"::device:[full.path.name]fname.extension;version" */
+    return (c == ':' || c == '[' || c == ']' || c == '/'
+	    || c == '<' || c == '>' || c == '"' );
+#   else		/* Amiga */
+    return (c == ':' || c == '/');
+#   endif /* VMS */
+#  endif
+# endif
+#endif /* RISC OS */
+}
+
+#if defined(FEAT_SEARCHPATH) || defined(PROTO)
+/*
+ * return TRUE if 'c' is a path list separator.
+ */
+    int
+vim_ispathlistsep(c)
+    int c;
+{
+#ifdef UNIX
+    return (c == ':');
+#else
+    return (c == ';');	/* might not be right for every system... */
+#endif
+}
+#endif
+
+#if defined(FEAT_GUI_TABLINE) || defined(FEAT_WINDOWS) \
+	|| defined(FEAT_EVAL) || defined(PROTO)
+/*
+ * Shorten the path of a file from "~/foo/../.bar/fname" to "~/f/../.b/fname"
+ * It's done in-place.
+ */
+    void
+shorten_dir(str)
+    char_u *str;
+{
+    char_u	*tail, *s, *d;
+    int		skip = FALSE;
+
+    tail = gettail(str);
+    d = str;
+    for (s = str; ; ++s)
+    {
+	if (s >= tail)		    /* copy the whole tail */
+	{
+	    *d++ = *s;
+	    if (*s == NUL)
+		break;
+	}
+	else if (vim_ispathsep(*s))	    /* copy '/' and next char */
+	{
+	    *d++ = *s;
+	    skip = FALSE;
+	}
+	else if (!skip)
+	{
+	    *d++ = *s;		    /* copy next char */
+	    if (*s != '~' && *s != '.') /* and leading "~" and "." */
+		skip = TRUE;
+# ifdef FEAT_MBYTE
+	    if (has_mbyte)
+	    {
+		int l = mb_ptr2len(s);
+
+		while (--l > 0)
+		    *d++ = *++s;
+	    }
+# endif
+	}
+    }
+}
+#endif
+
+/*
+ * Return TRUE if the directory of "fname" exists, FALSE otherwise.
+ * Also returns TRUE if there is no directory name.
+ * "fname" must be writable!.
+ */
+    int
+dir_of_file_exists(fname)
+    char_u	*fname;
+{
+    char_u	*p;
+    int		c;
+    int		retval;
+
+    p = gettail_sep(fname);
+    if (p == fname)
+	return TRUE;
+    c = *p;
+    *p = NUL;
+    retval = mch_isdir(fname);
+    *p = c;
+    return retval;
+}
+
+#if (defined(CASE_INSENSITIVE_FILENAME) && defined(BACKSLASH_IN_FILENAME)) \
+	|| defined(PROTO)
+/*
+ * Versions of fnamecmp() and fnamencmp() that handle '/' and '\' equally.
+ */
+    int
+vim_fnamecmp(x, y)
+    char_u	*x, *y;
+{
+    return vim_fnamencmp(x, y, MAXPATHL);
+}
+
+    int
+vim_fnamencmp(x, y, len)
+    char_u	*x, *y;
+    size_t	len;
+{
+    while (len > 0 && *x && *y)
+    {
+	if (TOLOWER_LOC(*x) != TOLOWER_LOC(*y)
+		&& !(*x == '/' && *y == '\\')
+		&& !(*x == '\\' && *y == '/'))
+	    break;
+	++x;
+	++y;
+	--len;
+    }
+    if (len == 0)
+	return 0;
+    return (*x - *y);
+}
+#endif
+
+/*
+ * Concatenate file names fname1 and fname2 into allocated memory.
+ * Only add a '/' or '\\' when 'sep' is TRUE and it is necessary.
+ */
+    char_u  *
+concat_fnames(fname1, fname2, sep)
+    char_u  *fname1;
+    char_u  *fname2;
+    int	    sep;
+{
+    char_u  *dest;
+
+    dest = alloc((unsigned)(STRLEN(fname1) + STRLEN(fname2) + 3));
+    if (dest != NULL)
+    {
+	STRCPY(dest, fname1);
+	if (sep)
+	    add_pathsep(dest);
+	STRCAT(dest, fname2);
+    }
+    return dest;
+}
+
+#if defined(FEAT_EVAL) || defined(FEAT_GETTEXT) || defined(PROTO)
+/*
+ * Concatenate two strings and return the result in allocated memory.
+ * Returns NULL when out of memory.
+ */
+    char_u  *
+concat_str(str1, str2)
+    char_u  *str1;
+    char_u  *str2;
+{
+    char_u  *dest;
+    size_t  l = STRLEN(str1);
+
+    dest = alloc((unsigned)(l + STRLEN(str2) + 1L));
+    if (dest != NULL)
+    {
+	STRCPY(dest, str1);
+	STRCPY(dest + l, str2);
+    }
+    return dest;
+}
+#endif
+
+/*
+ * Add a path separator to a file name, unless it already ends in a path
+ * separator.
+ */
+    void
+add_pathsep(p)
+    char_u	*p;
+{
+    if (*p != NUL && !after_pathsep(p, p + STRLEN(p)))
+	STRCAT(p, PATHSEPSTR);
+}
+
+/*
+ * FullName_save - Make an allocated copy of a full file name.
+ * Returns NULL when out of memory.
+ */
+    char_u  *
+FullName_save(fname, force)
+    char_u	*fname;
+    int		force;	    /* force expansion, even when it already looks
+			       like a full path name */
+{
+    char_u	*buf;
+    char_u	*new_fname = NULL;
+
+    if (fname == NULL)
+	return NULL;
+
+    buf = alloc((unsigned)MAXPATHL);
+    if (buf != NULL)
+    {
+	if (vim_FullName(fname, buf, MAXPATHL, force) != FAIL)
+	    new_fname = vim_strsave(buf);
+	else
+	    new_fname = vim_strsave(fname);
+	vim_free(buf);
+    }
+    return new_fname;
+}
+
+#if defined(FEAT_CINDENT) || defined(FEAT_SYN_HL)
+
+static char_u	*skip_string __ARGS((char_u *p));
+
+/*
+ * Find the start of a comment, not knowing if we are in a comment right now.
+ * Search starts at w_cursor.lnum and goes backwards.
+ */
+    pos_T *
+find_start_comment(ind_maxcomment)	    /* XXX */
+    int		ind_maxcomment;
+{
+    pos_T	*pos;
+    char_u	*line;
+    char_u	*p;
+    int		cur_maxcomment = ind_maxcomment;
+
+    for (;;)
+    {
+	pos = findmatchlimit(NULL, '*', FM_BACKWARD, cur_maxcomment);
+	if (pos == NULL)
+	    break;
+
+	/*
+	 * Check if the comment start we found is inside a string.
+	 * If it is then restrict the search to below this line and try again.
+	 */
+	line = ml_get(pos->lnum);
+	for (p = line; *p && (unsigned)(p - line) < pos->col; ++p)
+	    p = skip_string(p);
+	if ((unsigned)(p - line) <= pos->col)
+	    break;
+	cur_maxcomment = curwin->w_cursor.lnum - pos->lnum - 1;
+	if (cur_maxcomment <= 0)
+	{
+	    pos = NULL;
+	    break;
+	}
+    }
+    return pos;
+}
+
+/*
+ * Skip to the end of a "string" and a 'c' character.
+ * If there is no string or character, return argument unmodified.
+ */
+    static char_u *
+skip_string(p)
+    char_u  *p;
+{
+    int	    i;
+
+    /*
+     * We loop, because strings may be concatenated: "date""time".
+     */
+    for ( ; ; ++p)
+    {
+	if (p[0] == '\'')		    /* 'c' or '\n' or '\000' */
+	{
+	    if (!p[1])			    /* ' at end of line */
+		break;
+	    i = 2;
+	    if (p[1] == '\\')		    /* '\n' or '\000' */
+	    {
+		++i;
+		while (vim_isdigit(p[i - 1]))   /* '\000' */
+		    ++i;
+	    }
+	    if (p[i] == '\'')		    /* check for trailing ' */
+	    {
+		p += i;
+		continue;
+	    }
+	}
+	else if (p[0] == '"')		    /* start of string */
+	{
+	    for (++p; p[0]; ++p)
+	    {
+		if (p[0] == '\\' && p[1] != NUL)
+		    ++p;
+		else if (p[0] == '"')	    /* end of string */
+		    break;
+	    }
+	    if (p[0] == '"')
+		continue;
+	}
+	break;				    /* no string found */
+    }
+    if (!*p)
+	--p;				    /* backup from NUL */
+    return p;
+}
+#endif /* FEAT_CINDENT || FEAT_SYN_HL */
+
+#if defined(FEAT_CINDENT) || defined(PROTO)
+
+/*
+ * Do C or expression indenting on the current line.
+ */
+    void
+do_c_expr_indent()
+{
+# ifdef FEAT_EVAL
+    if (*curbuf->b_p_inde != NUL)
+	fixthisline(get_expr_indent);
+    else
+# endif
+	fixthisline(get_c_indent);
+}
+
+/*
+ * Functions for C-indenting.
+ * Most of this originally comes from Eric Fischer.
+ */
+/*
+ * Below "XXX" means that this function may unlock the current line.
+ */
+
+static char_u	*cin_skipcomment __ARGS((char_u *));
+static int	cin_nocode __ARGS((char_u *));
+static pos_T	*find_line_comment __ARGS((void));
+static int	cin_islabel_skip __ARGS((char_u **));
+static int	cin_isdefault __ARGS((char_u *));
+static char_u	*after_label __ARGS((char_u *l));
+static int	get_indent_nolabel __ARGS((linenr_T lnum));
+static int	skip_label __ARGS((linenr_T, char_u **pp, int ind_maxcomment));
+static int	cin_first_id_amount __ARGS((void));
+static int	cin_get_equal_amount __ARGS((linenr_T lnum));
+static int	cin_ispreproc __ARGS((char_u *));
+static int	cin_ispreproc_cont __ARGS((char_u **pp, linenr_T *lnump));
+static int	cin_iscomment __ARGS((char_u *));
+static int	cin_islinecomment __ARGS((char_u *));
+static int	cin_isterminated __ARGS((char_u *, int, int));
+static int	cin_isinit __ARGS((void));
+static int	cin_isfuncdecl __ARGS((char_u **, linenr_T));
+static int	cin_isif __ARGS((char_u *));
+static int	cin_iselse __ARGS((char_u *));
+static int	cin_isdo __ARGS((char_u *));
+static int	cin_iswhileofdo __ARGS((char_u *, linenr_T, int));
+static int	cin_iswhileofdo_end __ARGS((int terminated, int	ind_maxparen, int ind_maxcomment));
+static int	cin_isbreak __ARGS((char_u *));
+static int	cin_is_cpp_baseclass __ARGS((char_u *line, colnr_T *col));
+static int	get_baseclass_amount __ARGS((int col, int ind_maxparen, int ind_maxcomment, int ind_cpp_baseclass));
+static int	cin_ends_in __ARGS((char_u *, char_u *, char_u *));
+static int	cin_skip2pos __ARGS((pos_T *trypos));
+static pos_T	*find_start_brace __ARGS((int));
+static pos_T	*find_match_paren __ARGS((int, int));
+static int	corr_ind_maxparen __ARGS((int ind_maxparen, pos_T *startpos));
+static int	find_last_paren __ARGS((char_u *l, int start, int end));
+static int	find_match __ARGS((int lookfor, linenr_T ourscope, int ind_maxparen, int ind_maxcomment));
+
+static int	ind_hash_comment = 0;   /* # starts a comment */
+
+/*
+ * Skip over white space and C comments within the line.
+ * Also skip over Perl/shell comments if desired.
+ */
+    static char_u *
+cin_skipcomment(s)
+    char_u	*s;
+{
+    while (*s)
+    {
+	char_u *prev_s = s;
+
+	s = skipwhite(s);
+
+	/* Perl/shell # comment comment continues until eol.  Require a space
+	 * before # to avoid recognizing $#array. */
+	if (ind_hash_comment != 0 && s != prev_s && *s == '#')
+	{
+	    s += STRLEN(s);
+	    break;
+	}
+	if (*s != '/')
+	    break;
+	++s;
+	if (*s == '/')		/* slash-slash comment continues till eol */
+	{
+	    s += STRLEN(s);
+	    break;
+	}
+	if (*s != '*')
+	    break;
+	for (++s; *s; ++s)	/* skip slash-star comment */
+	    if (s[0] == '*' && s[1] == '/')
+	    {
+		s += 2;
+		break;
+	    }
+    }
+    return s;
+}
+
+/*
+ * Return TRUE if there there is no code at *s.  White space and comments are
+ * not considered code.
+ */
+    static int
+cin_nocode(s)
+    char_u	*s;
+{
+    return *cin_skipcomment(s) == NUL;
+}
+
+/*
+ * Check previous lines for a "//" line comment, skipping over blank lines.
+ */
+    static pos_T *
+find_line_comment() /* XXX */
+{
+    static pos_T pos;
+    char_u	 *line;
+    char_u	 *p;
+
+    pos = curwin->w_cursor;
+    while (--pos.lnum > 0)
+    {
+	line = ml_get(pos.lnum);
+	p = skipwhite(line);
+	if (cin_islinecomment(p))
+	{
+	    pos.col = (int)(p - line);
+	    return &pos;
+	}
+	if (*p != NUL)
+	    break;
+    }
+    return NULL;
+}
+
+/*
+ * Check if string matches "label:"; move to character after ':' if true.
+ */
+    static int
+cin_islabel_skip(s)
+    char_u	**s;
+{
+    if (!vim_isIDc(**s))	    /* need at least one ID character */
+	return FALSE;
+
+    while (vim_isIDc(**s))
+	(*s)++;
+
+    *s = cin_skipcomment(*s);
+
+    /* "::" is not a label, it's C++ */
+    return (**s == ':' && *++*s != ':');
+}
+
+/*
+ * Recognize a label: "label:".
+ * Note: curwin->w_cursor must be where we are looking for the label.
+ */
+    int
+cin_islabel(ind_maxcomment)		/* XXX */
+    int		ind_maxcomment;
+{
+    char_u	*s;
+
+    s = cin_skipcomment(ml_get_curline());
+
+    /*
+     * Exclude "default" from labels, since it should be indented
+     * like a switch label.  Same for C++ scope declarations.
+     */
+    if (cin_isdefault(s))
+	return FALSE;
+    if (cin_isscopedecl(s))
+	return FALSE;
+
+    if (cin_islabel_skip(&s))
+    {
+	/*
+	 * Only accept a label if the previous line is terminated or is a case
+	 * label.
+	 */
+	pos_T	cursor_save;
+	pos_T	*trypos;
+	char_u	*line;
+
+	cursor_save = curwin->w_cursor;
+	while (curwin->w_cursor.lnum > 1)
+	{
+	    --curwin->w_cursor.lnum;
+
+	    /*
+	     * If we're in a comment now, skip to the start of the comment.
+	     */
+	    curwin->w_cursor.col = 0;
+	    if ((trypos = find_start_comment(ind_maxcomment)) != NULL) /* XXX */
+		curwin->w_cursor = *trypos;
+
+	    line = ml_get_curline();
+	    if (cin_ispreproc(line))	/* ignore #defines, #if, etc. */
+		continue;
+	    if (*(line = cin_skipcomment(line)) == NUL)
+		continue;
+
+	    curwin->w_cursor = cursor_save;
+	    if (cin_isterminated(line, TRUE, FALSE)
+		    || cin_isscopedecl(line)
+		    || cin_iscase(line)
+		    || (cin_islabel_skip(&line) && cin_nocode(line)))
+		return TRUE;
+	    return FALSE;
+	}
+	curwin->w_cursor = cursor_save;
+	return TRUE;		/* label at start of file??? */
+    }
+    return FALSE;
+}
+
+/*
+ * Recognize structure initialization and enumerations.
+ * Q&D-Implementation:
+ * check for "=" at end or "[typedef] enum" at beginning of line.
+ */
+    static int
+cin_isinit(void)
+{
+    char_u	*s;
+
+    s = cin_skipcomment(ml_get_curline());
+
+    if (STRNCMP(s, "typedef", 7) == 0 && !vim_isIDc(s[7]))
+	s = cin_skipcomment(s + 7);
+
+    if (STRNCMP(s, "enum", 4) == 0 && !vim_isIDc(s[4]))
+	return TRUE;
+
+    if (cin_ends_in(s, (char_u *)"=", (char_u *)"{"))
+	return TRUE;
+
+    return FALSE;
+}
+
+/*
+ * Recognize a switch label: "case .*:" or "default:".
+ */
+     int
+cin_iscase(s)
+    char_u *s;
+{
+    s = cin_skipcomment(s);
+    if (STRNCMP(s, "case", 4) == 0 && !vim_isIDc(s[4]))
+    {
+	for (s += 4; *s; ++s)
+	{
+	    s = cin_skipcomment(s);
+	    if (*s == ':')
+	    {
+		if (s[1] == ':')	/* skip over "::" for C++ */
+		    ++s;
+		else
+		    return TRUE;
+	    }
+	    if (*s == '\'' && s[1] && s[2] == '\'')
+		s += 2;			/* skip over '.' */
+	    else if (*s == '/' && (s[1] == '*' || s[1] == '/'))
+		return FALSE;		/* stop at comment */
+	    else if (*s == '"')
+		return FALSE;		/* stop at string */
+	}
+	return FALSE;
+    }
+
+    if (cin_isdefault(s))
+	return TRUE;
+    return FALSE;
+}
+
+/*
+ * Recognize a "default" switch label.
+ */
+    static int
+cin_isdefault(s)
+    char_u  *s;
+{
+    return (STRNCMP(s, "default", 7) == 0
+	    && *(s = cin_skipcomment(s + 7)) == ':'
+	    && s[1] != ':');
+}
+
+/*
+ * Recognize a "public/private/proctected" scope declaration label.
+ */
+    int
+cin_isscopedecl(s)
+    char_u	*s;
+{
+    int		i;
+
+    s = cin_skipcomment(s);
+    if (STRNCMP(s, "public", 6) == 0)
+	i = 6;
+    else if (STRNCMP(s, "protected", 9) == 0)
+	i = 9;
+    else if (STRNCMP(s, "private", 7) == 0)
+	i = 7;
+    else
+	return FALSE;
+    return (*(s = cin_skipcomment(s + i)) == ':' && s[1] != ':');
+}
+
+/*
+ * Return a pointer to the first non-empty non-comment character after a ':'.
+ * Return NULL if not found.
+ *	  case 234:    a = b;
+ *		       ^
+ */
+    static char_u *
+after_label(l)
+    char_u  *l;
+{
+    for ( ; *l; ++l)
+    {
+	if (*l == ':')
+	{
+	    if (l[1] == ':')	    /* skip over "::" for C++ */
+		++l;
+	    else if (!cin_iscase(l + 1))
+		break;
+	}
+	else if (*l == '\'' && l[1] && l[2] == '\'')
+	    l += 2;		    /* skip over 'x' */
+    }
+    if (*l == NUL)
+	return NULL;
+    l = cin_skipcomment(l + 1);
+    if (*l == NUL)
+	return NULL;
+    return l;
+}
+
+/*
+ * Get indent of line "lnum", skipping a label.
+ * Return 0 if there is nothing after the label.
+ */
+    static int
+get_indent_nolabel(lnum)		/* XXX */
+    linenr_T	lnum;
+{
+    char_u	*l;
+    pos_T	fp;
+    colnr_T	col;
+    char_u	*p;
+
+    l = ml_get(lnum);
+    p = after_label(l);
+    if (p == NULL)
+	return 0;
+
+    fp.col = (colnr_T)(p - l);
+    fp.lnum = lnum;
+    getvcol(curwin, &fp, &col, NULL, NULL);
+    return (int)col;
+}
+
+/*
+ * Find indent for line "lnum", ignoring any case or jump label.
+ * Also return a pointer to the text (after the label) in "pp".
+ *   label:	if (asdf && asdfasdf)
+ *		^
+ */
+    static int
+skip_label(lnum, pp, ind_maxcomment)
+    linenr_T	lnum;
+    char_u	**pp;
+    int		ind_maxcomment;
+{
+    char_u	*l;
+    int		amount;
+    pos_T	cursor_save;
+
+    cursor_save = curwin->w_cursor;
+    curwin->w_cursor.lnum = lnum;
+    l = ml_get_curline();
+				    /* XXX */
+    if (cin_iscase(l) || cin_isscopedecl(l) || cin_islabel(ind_maxcomment))
+    {
+	amount = get_indent_nolabel(lnum);
+	l = after_label(ml_get_curline());
+	if (l == NULL)		/* just in case */
+	    l = ml_get_curline();
+    }
+    else
+    {
+	amount = get_indent();
+	l = ml_get_curline();
+    }
+    *pp = l;
+
+    curwin->w_cursor = cursor_save;
+    return amount;
+}
+
+/*
+ * Return the indent of the first variable name after a type in a declaration.
+ *  int	    a,			indent of "a"
+ *  static struct foo    b,	indent of "b"
+ *  enum bla    c,		indent of "c"
+ * Returns zero when it doesn't look like a declaration.
+ */
+    static int
+cin_first_id_amount()
+{
+    char_u	*line, *p, *s;
+    int		len;
+    pos_T	fp;
+    colnr_T	col;
+
+    line = ml_get_curline();
+    p = skipwhite(line);
+    len = (int)(skiptowhite(p) - p);
+    if (len == 6 && STRNCMP(p, "static", 6) == 0)
+    {
+	p = skipwhite(p + 6);
+	len = (int)(skiptowhite(p) - p);
+    }
+    if (len == 6 && STRNCMP(p, "struct", 6) == 0)
+	p = skipwhite(p + 6);
+    else if (len == 4 && STRNCMP(p, "enum", 4) == 0)
+	p = skipwhite(p + 4);
+    else if ((len == 8 && STRNCMP(p, "unsigned", 8) == 0)
+	    || (len == 6 && STRNCMP(p, "signed", 6) == 0))
+    {
+	s = skipwhite(p + len);
+	if ((STRNCMP(s, "int", 3) == 0 && vim_iswhite(s[3]))
+		|| (STRNCMP(s, "long", 4) == 0 && vim_iswhite(s[4]))
+		|| (STRNCMP(s, "short", 5) == 0 && vim_iswhite(s[5]))
+		|| (STRNCMP(s, "char", 4) == 0 && vim_iswhite(s[4])))
+	    p = s;
+    }
+    for (len = 0; vim_isIDc(p[len]); ++len)
+	;
+    if (len == 0 || !vim_iswhite(p[len]) || cin_nocode(p))
+	return 0;
+
+    p = skipwhite(p + len);
+    fp.lnum = curwin->w_cursor.lnum;
+    fp.col = (colnr_T)(p - line);
+    getvcol(curwin, &fp, &col, NULL, NULL);
+    return (int)col;
+}
+
+/*
+ * Return the indent of the first non-blank after an equal sign.
+ *       char *foo = "here";
+ * Return zero if no (useful) equal sign found.
+ * Return -1 if the line above "lnum" ends in a backslash.
+ *      foo = "asdf\
+ *	       asdf\
+ *	       here";
+ */
+    static int
+cin_get_equal_amount(lnum)
+    linenr_T	lnum;
+{
+    char_u	*line;
+    char_u	*s;
+    colnr_T	col;
+    pos_T	fp;
+
+    if (lnum > 1)
+    {
+	line = ml_get(lnum - 1);
+	if (*line != NUL && line[STRLEN(line) - 1] == '\\')
+	    return -1;
+    }
+
+    line = s = ml_get(lnum);
+    while (*s != NUL && vim_strchr((char_u *)"=;{}\"'", *s) == NULL)
+    {
+	if (cin_iscomment(s))	/* ignore comments */
+	    s = cin_skipcomment(s);
+	else
+	    ++s;
+    }
+    if (*s != '=')
+	return 0;
+
+    s = skipwhite(s + 1);
+    if (cin_nocode(s))
+	return 0;
+
+    if (*s == '"')	/* nice alignment for continued strings */
+	++s;
+
+    fp.lnum = lnum;
+    fp.col = (colnr_T)(s - line);
+    getvcol(curwin, &fp, &col, NULL, NULL);
+    return (int)col;
+}
+
+/*
+ * Recognize a preprocessor statement: Any line that starts with '#'.
+ */
+    static int
+cin_ispreproc(s)
+    char_u *s;
+{
+    s = skipwhite(s);
+    if (*s == '#')
+	return TRUE;
+    return FALSE;
+}
+
+/*
+ * Return TRUE if line "*pp" at "*lnump" is a preprocessor statement or a
+ * continuation line of a preprocessor statement.  Decrease "*lnump" to the
+ * start and return the line in "*pp".
+ */
+    static int
+cin_ispreproc_cont(pp, lnump)
+    char_u	**pp;
+    linenr_T	*lnump;
+{
+    char_u	*line = *pp;
+    linenr_T	lnum = *lnump;
+    int		retval = FALSE;
+
+    for (;;)
+    {
+	if (cin_ispreproc(line))
+	{
+	    retval = TRUE;
+	    *lnump = lnum;
+	    break;
+	}
+	if (lnum == 1)
+	    break;
+	line = ml_get(--lnum);
+	if (*line == NUL || line[STRLEN(line) - 1] != '\\')
+	    break;
+    }
+
+    if (lnum != *lnump)
+	*pp = ml_get(*lnump);
+    return retval;
+}
+
+/*
+ * Recognize the start of a C or C++ comment.
+ */
+    static int
+cin_iscomment(p)
+    char_u  *p;
+{
+    return (p[0] == '/' && (p[1] == '*' || p[1] == '/'));
+}
+
+/*
+ * Recognize the start of a "//" comment.
+ */
+    static int
+cin_islinecomment(p)
+    char_u *p;
+{
+    return (p[0] == '/' && p[1] == '/');
+}
+
+/*
+ * Recognize a line that starts with '{' or '}', or ends with ';', '{' or '}'.
+ * Don't consider "} else" a terminated line.
+ * Return the character terminating the line (ending char's have precedence if
+ * both apply in order to determine initializations).
+ */
+    static int
+cin_isterminated(s, incl_open, incl_comma)
+    char_u	*s;
+    int		incl_open;	/* include '{' at the end as terminator */
+    int		incl_comma;	/* recognize a trailing comma */
+{
+    char_u found_start = 0;
+
+    s = cin_skipcomment(s);
+
+    if (*s == '{' || (*s == '}' && !cin_iselse(s)))
+	found_start = *s;
+
+    while (*s)
+    {
+	/* skip over comments, "" strings and 'c'haracters */
+	s = skip_string(cin_skipcomment(s));
+	if ((*s == ';' || (incl_open && *s == '{') || *s == '}'
+						 || (incl_comma && *s == ','))
+		&& cin_nocode(s + 1))
+	    return *s;
+
+	if (*s)
+	    s++;
+    }
+    return found_start;
+}
+
+/*
+ * Recognize the basic picture of a function declaration -- it needs to
+ * have an open paren somewhere and a close paren at the end of the line and
+ * no semicolons anywhere.
+ * When a line ends in a comma we continue looking in the next line.
+ * "sp" points to a string with the line.  When looking at other lines it must
+ * be restored to the line.  When it's NULL fetch lines here.
+ * "lnum" is where we start looking.
+ */
+    static int
+cin_isfuncdecl(sp, first_lnum)
+    char_u	**sp;
+    linenr_T	first_lnum;
+{
+    char_u	*s;
+    linenr_T	lnum = first_lnum;
+    int		retval = FALSE;
+
+    if (sp == NULL)
+	s = ml_get(lnum);
+    else
+	s = *sp;
+
+    while (*s && *s != '(' && *s != ';' && *s != '\'' && *s != '"')
+    {
+	if (cin_iscomment(s))	/* ignore comments */
+	    s = cin_skipcomment(s);
+	else
+	    ++s;
+    }
+    if (*s != '(')
+	return FALSE;		/* ';', ' or "  before any () or no '(' */
+
+    while (*s && *s != ';' && *s != '\'' && *s != '"')
+    {
+	if (*s == ')' && cin_nocode(s + 1))
+	{
+	    /* ')' at the end: may have found a match
+	     * Check for he previous line not to end in a backslash:
+	     *       #if defined(x) && \
+	     *		 defined(y)
+	     */
+	    lnum = first_lnum - 1;
+	    s = ml_get(lnum);
+	    if (*s == NUL || s[STRLEN(s) - 1] != '\\')
+		retval = TRUE;
+	    goto done;
+	}
+	if (*s == ',' && cin_nocode(s + 1))
+	{
+	    /* ',' at the end: continue looking in the next line */
+	    if (lnum >= curbuf->b_ml.ml_line_count)
+		break;
+
+	    s = ml_get(++lnum);
+	}
+	else if (cin_iscomment(s))	/* ignore comments */
+	    s = cin_skipcomment(s);
+	else
+	    ++s;
+    }
+
+done:
+    if (lnum != first_lnum && sp != NULL)
+	*sp = ml_get(first_lnum);
+
+    return retval;
+}
+
+    static int
+cin_isif(p)
+    char_u  *p;
+{
+    return (STRNCMP(p, "if", 2) == 0 && !vim_isIDc(p[2]));
+}
+
+    static int
+cin_iselse(p)
+    char_u  *p;
+{
+    if (*p == '}')	    /* accept "} else" */
+	p = cin_skipcomment(p + 1);
+    return (STRNCMP(p, "else", 4) == 0 && !vim_isIDc(p[4]));
+}
+
+    static int
+cin_isdo(p)
+    char_u  *p;
+{
+    return (STRNCMP(p, "do", 2) == 0 && !vim_isIDc(p[2]));
+}
+
+/*
+ * Check if this is a "while" that should have a matching "do".
+ * We only accept a "while (condition) ;", with only white space between the
+ * ')' and ';'. The condition may be spread over several lines.
+ */
+    static int
+cin_iswhileofdo(p, lnum, ind_maxparen)	    /* XXX */
+    char_u	*p;
+    linenr_T	lnum;
+    int		ind_maxparen;
+{
+    pos_T	cursor_save;
+    pos_T	*trypos;
+    int		retval = FALSE;
+
+    p = cin_skipcomment(p);
+    if (*p == '}')		/* accept "} while (cond);" */
+	p = cin_skipcomment(p + 1);
+    if (STRNCMP(p, "while", 5) == 0 && !vim_isIDc(p[5]))
+    {
+	cursor_save = curwin->w_cursor;
+	curwin->w_cursor.lnum = lnum;
+	curwin->w_cursor.col = 0;
+	p = ml_get_curline();
+	while (*p && *p != 'w')	/* skip any '}', until the 'w' of the "while" */
+	{
+	    ++p;
+	    ++curwin->w_cursor.col;
+	}
+	if ((trypos = findmatchlimit(NULL, 0, 0, ind_maxparen)) != NULL
+		&& *cin_skipcomment(ml_get_pos(trypos) + 1) == ';')
+	    retval = TRUE;
+	curwin->w_cursor = cursor_save;
+    }
+    return retval;
+}
+
+/*
+ * Return TRUE if we are at the end of a do-while.
+ *    do
+ *       nothing;
+ *    while (foo
+ *	       && bar);  <-- here
+ * Adjust the cursor to the line with "while".
+ */
+    static int
+cin_iswhileofdo_end(terminated, ind_maxparen, ind_maxcomment)
+    int	    terminated;
+    int	    ind_maxparen;
+    int	    ind_maxcomment;
+{
+    char_u	*line;
+    char_u	*p;
+    char_u	*s;
+    pos_T	*trypos;
+    int		i;
+
+    if (terminated != ';')	/* there must be a ';' at the end */
+	return FALSE;
+
+    p = line = ml_get_curline();
+    while (*p != NUL)
+    {
+	p = cin_skipcomment(p);
+	if (*p == ')')
+	{
+	    s = skipwhite(p + 1);
+	    if (*s == ';' && cin_nocode(s + 1))
+	    {
+		/* Found ");" at end of the line, now check there is "while"
+		 * before the matching '('.  XXX */
+		i = (int)(p - line);
+		curwin->w_cursor.col = i;
+		trypos = find_match_paren(ind_maxparen, ind_maxcomment);
+		if (trypos != NULL)
+		{
+		    s = cin_skipcomment(ml_get(trypos->lnum));
+		    if (*s == '}')		/* accept "} while (cond);" */
+			s = cin_skipcomment(s + 1);
+		    if (STRNCMP(s, "while", 5) == 0 && !vim_isIDc(s[5]))
+		    {
+			curwin->w_cursor.lnum = trypos->lnum;
+			return TRUE;
+		    }
+		}
+
+		/* Searching may have made "line" invalid, get it again. */
+		line = ml_get_curline();
+		p = line + i;
+	    }
+	}
+	if (*p != NUL)
+	    ++p;
+    }
+    return FALSE;
+}
+
+    static int
+cin_isbreak(p)
+    char_u  *p;
+{
+    return (STRNCMP(p, "break", 5) == 0 && !vim_isIDc(p[5]));
+}
+
+/*
+ * Find the position of a C++ base-class declaration or
+ * constructor-initialization. eg:
+ *
+ * class MyClass :
+ *	baseClass		<-- here
+ * class MyClass : public baseClass,
+ *	anotherBaseClass	<-- here (should probably lineup ??)
+ * MyClass::MyClass(...) :
+ *	baseClass(...)		<-- here (constructor-initialization)
+ *
+ * This is a lot of guessing.  Watch out for "cond ? func() : foo".
+ */
+    static int
+cin_is_cpp_baseclass(line, col)
+    char_u	*line;
+    colnr_T	*col;	    /* return: column to align with */
+{
+    char_u	*s;
+    int		class_or_struct, lookfor_ctor_init, cpp_base_class;
+    linenr_T	lnum = curwin->w_cursor.lnum;
+
+    *col = 0;
+
+    s = skipwhite(line);
+    if (*s == '#')		/* skip #define FOO x ? (x) : x */
+	return FALSE;
+    s = cin_skipcomment(s);
+    if (*s == NUL)
+	return FALSE;
+
+    cpp_base_class = lookfor_ctor_init = class_or_struct = FALSE;
+
+    /* Search for a line starting with '#', empty, ending in ';' or containing
+     * '{' or '}' and start below it.  This handles the following situations:
+     *	a = cond ?
+     *	      func() :
+     *		   asdf;
+     *	func::foo()
+     *	      : something
+     *	{}
+     *	Foo::Foo (int one, int two)
+     *		: something(4),
+     *		somethingelse(3)
+     *	{}
+     */
+    while (lnum > 1)
+    {
+	s = skipwhite(ml_get(lnum - 1));
+	if (*s == '#' || *s == NUL)
+	    break;
+	while (*s != NUL)
+	{
+	    s = cin_skipcomment(s);
+	    if (*s == '{' || *s == '}'
+		    || (*s == ';' && cin_nocode(s + 1)))
+		break;
+	    if (*s != NUL)
+		++s;
+	}
+	if (*s != NUL)
+	    break;
+	--lnum;
+    }
+
+    s = cin_skipcomment(ml_get(lnum));
+    for (;;)
+    {
+	if (*s == NUL)
+	{
+	    if (lnum == curwin->w_cursor.lnum)
+		break;
+	    /* Continue in the cursor line. */
+	    s = cin_skipcomment(ml_get(++lnum));
+	}
+
+	if (s[0] == ':')
+	{
+	    if (s[1] == ':')
+	    {
+		/* skip double colon. It can't be a constructor
+		 * initialization any more */
+		lookfor_ctor_init = FALSE;
+		s = cin_skipcomment(s + 2);
+	    }
+	    else if (lookfor_ctor_init || class_or_struct)
+	    {
+		/* we have something found, that looks like the start of
+		 * cpp-base-class-declaration or contructor-initialization */
+		cpp_base_class = TRUE;
+		lookfor_ctor_init = class_or_struct = FALSE;
+		*col = 0;
+		s = cin_skipcomment(s + 1);
+	    }
+	    else
+		s = cin_skipcomment(s + 1);
+	}
+	else if ((STRNCMP(s, "class", 5) == 0 && !vim_isIDc(s[5]))
+		|| (STRNCMP(s, "struct", 6) == 0 && !vim_isIDc(s[6])))
+	{
+	    class_or_struct = TRUE;
+	    lookfor_ctor_init = FALSE;
+
+	    if (*s == 'c')
+		s = cin_skipcomment(s + 5);
+	    else
+		s = cin_skipcomment(s + 6);
+	}
+	else
+	{
+	    if (s[0] == '{' || s[0] == '}' || s[0] == ';')
+	    {
+		cpp_base_class = lookfor_ctor_init = class_or_struct = FALSE;
+	    }
+	    else if (s[0] == ')')
+	    {
+		/* Constructor-initialization is assumed if we come across
+		 * something like "):" */
+		class_or_struct = FALSE;
+		lookfor_ctor_init = TRUE;
+	    }
+	    else if (s[0] == '?')
+	    {
+		/* Avoid seeing '() :' after '?' as constructor init. */
+		return FALSE;
+	    }
+	    else if (!vim_isIDc(s[0]))
+	    {
+		/* if it is not an identifier, we are wrong */
+		class_or_struct = FALSE;
+		lookfor_ctor_init = FALSE;
+	    }
+	    else if (*col == 0)
+	    {
+		/* it can't be a constructor-initialization any more */
+		lookfor_ctor_init = FALSE;
+
+		/* the first statement starts here: lineup with this one... */
+		if (cpp_base_class)
+		    *col = (colnr_T)(s - line);
+	    }
+
+	    /* When the line ends in a comma don't align with it. */
+	    if (lnum == curwin->w_cursor.lnum && *s == ',' && cin_nocode(s + 1))
+		*col = 0;
+
+	    s = cin_skipcomment(s + 1);
+	}
+    }
+
+    return cpp_base_class;
+}
+
+    static int
+get_baseclass_amount(col, ind_maxparen, ind_maxcomment, ind_cpp_baseclass)
+    int		col;
+    int		ind_maxparen;
+    int		ind_maxcomment;
+    int		ind_cpp_baseclass;
+{
+    int		amount;
+    colnr_T	vcol;
+    pos_T	*trypos;
+
+    if (col == 0)
+    {
+	amount = get_indent();
+	if (find_last_paren(ml_get_curline(), '(', ')')
+		&& (trypos = find_match_paren(ind_maxparen,
+						     ind_maxcomment)) != NULL)
+	    amount = get_indent_lnum(trypos->lnum); /* XXX */
+	if (!cin_ends_in(ml_get_curline(), (char_u *)",", NULL))
+	    amount += ind_cpp_baseclass;
+    }
+    else
+    {
+	curwin->w_cursor.col = col;
+	getvcol(curwin, &curwin->w_cursor, &vcol, NULL, NULL);
+	amount = (int)vcol;
+    }
+    if (amount < ind_cpp_baseclass)
+	amount = ind_cpp_baseclass;
+    return amount;
+}
+
+/*
+ * Return TRUE if string "s" ends with the string "find", possibly followed by
+ * white space and comments.  Skip strings and comments.
+ * Ignore "ignore" after "find" if it's not NULL.
+ */
+    static int
+cin_ends_in(s, find, ignore)
+    char_u	*s;
+    char_u	*find;
+    char_u	*ignore;
+{
+    char_u	*p = s;
+    char_u	*r;
+    int		len = (int)STRLEN(find);
+
+    while (*p != NUL)
+    {
+	p = cin_skipcomment(p);
+	if (STRNCMP(p, find, len) == 0)
+	{
+	    r = skipwhite(p + len);
+	    if (ignore != NULL && STRNCMP(r, ignore, STRLEN(ignore)) == 0)
+		r = skipwhite(r + STRLEN(ignore));
+	    if (cin_nocode(r))
+		return TRUE;
+	}
+	if (*p != NUL)
+	    ++p;
+    }
+    return FALSE;
+}
+
+/*
+ * Skip strings, chars and comments until at or past "trypos".
+ * Return the column found.
+ */
+    static int
+cin_skip2pos(trypos)
+    pos_T	*trypos;
+{
+    char_u	*line;
+    char_u	*p;
+
+    p = line = ml_get(trypos->lnum);
+    while (*p && (colnr_T)(p - line) < trypos->col)
+    {
+	if (cin_iscomment(p))
+	    p = cin_skipcomment(p);
+	else
+	{
+	    p = skip_string(p);
+	    ++p;
+	}
+    }
+    return (int)(p - line);
+}
+
+/*
+ * Find the '{' at the start of the block we are in.
+ * Return NULL if no match found.
+ * Ignore a '{' that is in a comment, makes indenting the next three lines
+ * work. */
+/* foo()    */
+/* {	    */
+/* }	    */
+
+    static pos_T *
+find_start_brace(ind_maxcomment)	    /* XXX */
+    int		ind_maxcomment;
+{
+    pos_T	cursor_save;
+    pos_T	*trypos;
+    pos_T	*pos;
+    static pos_T	pos_copy;
+
+    cursor_save = curwin->w_cursor;
+    while ((trypos = findmatchlimit(NULL, '{', FM_BLOCKSTOP, 0)) != NULL)
+    {
+	pos_copy = *trypos;	/* copy pos_T, next findmatch will change it */
+	trypos = &pos_copy;
+	curwin->w_cursor = *trypos;
+	pos = NULL;
+	/* ignore the { if it's in a // or / *  * / comment */
+	if ((colnr_T)cin_skip2pos(trypos) == trypos->col
+		&& (pos = find_start_comment(ind_maxcomment)) == NULL) /* XXX */
+	    break;
+	if (pos != NULL)
+	    curwin->w_cursor.lnum = pos->lnum;
+    }
+    curwin->w_cursor = cursor_save;
+    return trypos;
+}
+
+/*
+ * Find the matching '(', failing if it is in a comment.
+ * Return NULL of no match found.
+ */
+    static pos_T *
+find_match_paren(ind_maxparen, ind_maxcomment)	    /* XXX */
+    int		ind_maxparen;
+    int		ind_maxcomment;
+{
+    pos_T	cursor_save;
+    pos_T	*trypos;
+    static pos_T pos_copy;
+
+    cursor_save = curwin->w_cursor;
+    if ((trypos = findmatchlimit(NULL, '(', 0, ind_maxparen)) != NULL)
+    {
+	/* check if the ( is in a // comment */
+	if ((colnr_T)cin_skip2pos(trypos) > trypos->col)
+	    trypos = NULL;
+	else
+	{
+	    pos_copy = *trypos;	    /* copy trypos, findmatch will change it */
+	    trypos = &pos_copy;
+	    curwin->w_cursor = *trypos;
+	    if (find_start_comment(ind_maxcomment) != NULL) /* XXX */
+		trypos = NULL;
+	}
+    }
+    curwin->w_cursor = cursor_save;
+    return trypos;
+}
+
+/*
+ * Return ind_maxparen corrected for the difference in line number between the
+ * cursor position and "startpos".  This makes sure that searching for a
+ * matching paren above the cursor line doesn't find a match because of
+ * looking a few lines further.
+ */
+    static int
+corr_ind_maxparen(ind_maxparen, startpos)
+    int		ind_maxparen;
+    pos_T	*startpos;
+{
+    long	n = (long)startpos->lnum - (long)curwin->w_cursor.lnum;
+
+    if (n > 0 && n < ind_maxparen / 2)
+	return ind_maxparen - (int)n;
+    return ind_maxparen;
+}
+
+/*
+ * Set w_cursor.col to the column number of the last unmatched ')' or '{' in
+ * line "l".
+ */
+    static int
+find_last_paren(l, start, end)
+    char_u	*l;
+    int		start, end;
+{
+    int		i;
+    int		retval = FALSE;
+    int		open_count = 0;
+
+    curwin->w_cursor.col = 0;		    /* default is start of line */
+
+    for (i = 0; l[i]; i++)
+    {
+	i = (int)(cin_skipcomment(l + i) - l); /* ignore parens in comments */
+	i = (int)(skip_string(l + i) - l);    /* ignore parens in quotes */
+	if (l[i] == start)
+	    ++open_count;
+	else if (l[i] == end)
+	{
+	    if (open_count > 0)
+		--open_count;
+	    else
+	    {
+		curwin->w_cursor.col = i;
+		retval = TRUE;
+	    }
+	}
+    }
+    return retval;
+}
+
+    int
+get_c_indent()
+{
+    /*
+     * spaces from a block's opening brace the prevailing indent for that
+     * block should be
+     */
+    int ind_level = curbuf->b_p_sw;
+
+    /*
+     * spaces from the edge of the line an open brace that's at the end of a
+     * line is imagined to be.
+     */
+    int ind_open_imag = 0;
+
+    /*
+     * spaces from the prevailing indent for a line that is not precededof by
+     * an opening brace.
+     */
+    int ind_no_brace = 0;
+
+    /*
+     * column where the first { of a function should be located }
+     */
+    int ind_first_open = 0;
+
+    /*
+     * spaces from the prevailing indent a leftmost open brace should be
+     * located
+     */
+    int ind_open_extra = 0;
+
+    /*
+     * spaces from the matching open brace (real location for one at the left
+     * edge; imaginary location from one that ends a line) the matching close
+     * brace should be located
+     */
+    int ind_close_extra = 0;
+
+    /*
+     * spaces from the edge of the line an open brace sitting in the leftmost
+     * column is imagined to be
+     */
+    int ind_open_left_imag = 0;
+
+    /*
+     * spaces from the switch() indent a "case xx" label should be located
+     */
+    int ind_case = curbuf->b_p_sw;
+
+    /*
+     * spaces from the "case xx:" code after a switch() should be located
+     */
+    int ind_case_code = curbuf->b_p_sw;
+
+    /*
+     * lineup break at end of case in switch() with case label
+     */
+    int ind_case_break = 0;
+
+    /*
+     * spaces from the class declaration indent a scope declaration label
+     * should be located
+     */
+    int ind_scopedecl = curbuf->b_p_sw;
+
+    /*
+     * spaces from the scope declaration label code should be located
+     */
+    int ind_scopedecl_code = curbuf->b_p_sw;
+
+    /*
+     * amount K&R-style parameters should be indented
+     */
+    int ind_param = curbuf->b_p_sw;
+
+    /*
+     * amount a function type spec should be indented
+     */
+    int ind_func_type = curbuf->b_p_sw;
+
+    /*
+     * amount a cpp base class declaration or constructor initialization
+     * should be indented
+     */
+    int ind_cpp_baseclass = curbuf->b_p_sw;
+
+    /*
+     * additional spaces beyond the prevailing indent a continuation line
+     * should be located
+     */
+    int ind_continuation = curbuf->b_p_sw;
+
+    /*
+     * spaces from the indent of the line with an unclosed parentheses
+     */
+    int ind_unclosed = curbuf->b_p_sw * 2;
+
+    /*
+     * spaces from the indent of the line with an unclosed parentheses, which
+     * itself is also unclosed
+     */
+    int ind_unclosed2 = curbuf->b_p_sw;
+
+    /*
+     * suppress ignoring spaces from the indent of a line starting with an
+     * unclosed parentheses.
+     */
+    int ind_unclosed_noignore = 0;
+
+    /*
+     * If the opening paren is the last nonwhite character on the line, and
+     * ind_unclosed_wrapped is nonzero, use this indent relative to the outer
+     * context (for very long lines).
+     */
+    int ind_unclosed_wrapped = 0;
+
+    /*
+     * suppress ignoring white space when lining up with the character after
+     * an unclosed parentheses.
+     */
+    int ind_unclosed_whiteok = 0;
+
+    /*
+     * indent a closing parentheses under the line start of the matching
+     * opening parentheses.
+     */
+    int ind_matching_paren = 0;
+
+    /*
+     * indent a closing parentheses under the previous line.
+     */
+    int ind_paren_prev = 0;
+
+    /*
+     * Extra indent for comments.
+     */
+    int ind_comment = 0;
+
+    /*
+     * spaces from the comment opener when there is nothing after it.
+     */
+    int ind_in_comment = 3;
+
+    /*
+     * boolean: if non-zero, use ind_in_comment even if there is something
+     * after the comment opener.
+     */
+    int ind_in_comment2 = 0;
+
+    /*
+     * max lines to search for an open paren
+     */
+    int ind_maxparen = 20;
+
+    /*
+     * max lines to search for an open comment
+     */
+    int ind_maxcomment = 70;
+
+    /*
+     * handle braces for java code
+     */
+    int	ind_java = 0;
+
+    /*
+     * handle blocked cases correctly
+     */
+    int ind_keep_case_label = 0;
+
+    pos_T	cur_curpos;
+    int		amount;
+    int		scope_amount;
+    int		cur_amount = MAXCOL;
+    colnr_T	col;
+    char_u	*theline;
+    char_u	*linecopy;
+    pos_T	*trypos;
+    pos_T	*tryposBrace = NULL;
+    pos_T	our_paren_pos;
+    char_u	*start;
+    int		start_brace;
+#define BRACE_IN_COL0		1	    /* '{' is in comumn 0 */
+#define BRACE_AT_START		2	    /* '{' is at start of line */
+#define BRACE_AT_END		3	    /* '{' is at end of line */
+    linenr_T	ourscope;
+    char_u	*l;
+    char_u	*look;
+    char_u	terminated;
+    int		lookfor;
+#define LOOKFOR_INITIAL		0
+#define LOOKFOR_IF		1
+#define LOOKFOR_DO		2
+#define LOOKFOR_CASE		3
+#define LOOKFOR_ANY		4
+#define LOOKFOR_TERM		5
+#define LOOKFOR_UNTERM		6
+#define LOOKFOR_SCOPEDECL	7
+#define LOOKFOR_NOBREAK		8
+#define LOOKFOR_CPP_BASECLASS	9
+#define LOOKFOR_ENUM_OR_INIT	10
+
+    int		whilelevel;
+    linenr_T	lnum;
+    char_u	*options;
+    int		fraction = 0;	    /* init for GCC */
+    int		divider;
+    int		n;
+    int		iscase;
+    int		lookfor_break;
+    int		cont_amount = 0;    /* amount for continuation line */
+
+    for (options = curbuf->b_p_cino; *options; )
+    {
+	l = options++;
+	if (*options == '-')
+	    ++options;
+	n = getdigits(&options);
+	divider = 0;
+	if (*options == '.')	    /* ".5s" means a fraction */
+	{
+	    fraction = atol((char *)++options);
+	    while (VIM_ISDIGIT(*options))
+	    {
+		++options;
+		if (divider)
+		    divider *= 10;
+		else
+		    divider = 10;
+	    }
+	}
+	if (*options == 's')	    /* "2s" means two times 'shiftwidth' */
+	{
+	    if (n == 0 && fraction == 0)
+		n = curbuf->b_p_sw;	/* just "s" is one 'shiftwidth' */
+	    else
+	    {
+		n *= curbuf->b_p_sw;
+		if (divider)
+		    n += (curbuf->b_p_sw * fraction + divider / 2) / divider;
+	    }
+	    ++options;
+	}
+	if (l[1] == '-')
+	    n = -n;
+	/* When adding an entry here, also update the default 'cinoptions' in
+	 * doc/indent.txt, and add explanation for it! */
+	switch (*l)
+	{
+	    case '>': ind_level = n; break;
+	    case 'e': ind_open_imag = n; break;
+	    case 'n': ind_no_brace = n; break;
+	    case 'f': ind_first_open = n; break;
+	    case '{': ind_open_extra = n; break;
+	    case '}': ind_close_extra = n; break;
+	    case '^': ind_open_left_imag = n; break;
+	    case ':': ind_case = n; break;
+	    case '=': ind_case_code = n; break;
+	    case 'b': ind_case_break = n; break;
+	    case 'p': ind_param = n; break;
+	    case 't': ind_func_type = n; break;
+	    case '/': ind_comment = n; break;
+	    case 'c': ind_in_comment = n; break;
+	    case 'C': ind_in_comment2 = n; break;
+	    case 'i': ind_cpp_baseclass = n; break;
+	    case '+': ind_continuation = n; break;
+	    case '(': ind_unclosed = n; break;
+	    case 'u': ind_unclosed2 = n; break;
+	    case 'U': ind_unclosed_noignore = n; break;
+	    case 'W': ind_unclosed_wrapped = n; break;
+	    case 'w': ind_unclosed_whiteok = n; break;
+	    case 'm': ind_matching_paren = n; break;
+	    case 'M': ind_paren_prev = n; break;
+	    case ')': ind_maxparen = n; break;
+	    case '*': ind_maxcomment = n; break;
+	    case 'g': ind_scopedecl = n; break;
+	    case 'h': ind_scopedecl_code = n; break;
+	    case 'j': ind_java = n; break;
+	    case 'l': ind_keep_case_label = n; break;
+	    case '#': ind_hash_comment = n; break;
+	}
+    }
+
+    /* remember where the cursor was when we started */
+    cur_curpos = curwin->w_cursor;
+
+    /* Get a copy of the current contents of the line.
+     * This is required, because only the most recent line obtained with
+     * ml_get is valid! */
+    linecopy = vim_strsave(ml_get(cur_curpos.lnum));
+    if (linecopy == NULL)
+	return 0;
+
+    /*
+     * In insert mode and the cursor is on a ')' truncate the line at the
+     * cursor position.  We don't want to line up with the matching '(' when
+     * inserting new stuff.
+     * For unknown reasons the cursor might be past the end of the line, thus
+     * check for that.
+     */
+    if ((State & INSERT)
+	    && curwin->w_cursor.col < STRLEN(linecopy)
+	    && linecopy[curwin->w_cursor.col] == ')')
+	linecopy[curwin->w_cursor.col] = NUL;
+
+    theline = skipwhite(linecopy);
+
+    /* move the cursor to the start of the line */
+
+    curwin->w_cursor.col = 0;
+
+    /*
+     * #defines and so on always go at the left when included in 'cinkeys'.
+     */
+    if (*theline == '#' && (*linecopy == '#' || in_cinkeys('#', ' ', TRUE)))
+    {
+	amount = 0;
+    }
+
+    /*
+     * Is it a non-case label?	Then that goes at the left margin too.
+     */
+    else if (cin_islabel(ind_maxcomment))	    /* XXX */
+    {
+	amount = 0;
+    }
+
+    /*
+     * If we're inside a "//" comment and there is a "//" comment in a
+     * previous line, lineup with that one.
+     */
+    else if (cin_islinecomment(theline)
+	    && (trypos = find_line_comment()) != NULL) /* XXX */
+    {
+	/* find how indented the line beginning the comment is */
+	getvcol(curwin, trypos, &col, NULL, NULL);
+	amount = col;
+    }
+
+    /*
+     * If we're inside a comment and not looking at the start of the
+     * comment, try using the 'comments' option.
+     */
+    else if (!cin_iscomment(theline)
+	    && (trypos = find_start_comment(ind_maxcomment)) != NULL) /* XXX */
+    {
+	int	lead_start_len = 2;
+	int	lead_middle_len = 1;
+	char_u	lead_start[COM_MAX_LEN];	/* start-comment string */
+	char_u	lead_middle[COM_MAX_LEN];	/* middle-comment string */
+	char_u	lead_end[COM_MAX_LEN];		/* end-comment string */
+	char_u	*p;
+	int	start_align = 0;
+	int	start_off = 0;
+	int	done = FALSE;
+
+	/* find how indented the line beginning the comment is */
+	getvcol(curwin, trypos, &col, NULL, NULL);
+	amount = col;
+
+	p = curbuf->b_p_com;
+	while (*p != NUL)
+	{
+	    int	align = 0;
+	    int	off = 0;
+	    int what = 0;
+
+	    while (*p != NUL && *p != ':')
+	    {
+		if (*p == COM_START || *p == COM_END || *p == COM_MIDDLE)
+		    what = *p++;
+		else if (*p == COM_LEFT || *p == COM_RIGHT)
+		    align = *p++;
+		else if (VIM_ISDIGIT(*p) || *p == '-')
+		    off = getdigits(&p);
+		else
+		    ++p;
+	    }
+
+	    if (*p == ':')
+		++p;
+	    (void)copy_option_part(&p, lead_end, COM_MAX_LEN, ",");
+	    if (what == COM_START)
+	    {
+		STRCPY(lead_start, lead_end);
+		lead_start_len = (int)STRLEN(lead_start);
+		start_off = off;
+		start_align = align;
+	    }
+	    else if (what == COM_MIDDLE)
+	    {
+		STRCPY(lead_middle, lead_end);
+		lead_middle_len = (int)STRLEN(lead_middle);
+	    }
+	    else if (what == COM_END)
+	    {
+		/* If our line starts with the middle comment string, line it
+		 * up with the comment opener per the 'comments' option. */
+		if (STRNCMP(theline, lead_middle, lead_middle_len) == 0
+			&& STRNCMP(theline, lead_end, STRLEN(lead_end)) != 0)
+		{
+		    done = TRUE;
+		    if (curwin->w_cursor.lnum > 1)
+		    {
+			/* If the start comment string matches in the previous
+			 * line, use the indent of that line pluss offset.  If
+			 * the middle comment string matches in the previous
+			 * line, use the indent of that line.  XXX */
+			look = skipwhite(ml_get(curwin->w_cursor.lnum - 1));
+			if (STRNCMP(look, lead_start, lead_start_len) == 0)
+			    amount = get_indent_lnum(curwin->w_cursor.lnum - 1);
+			else if (STRNCMP(look, lead_middle,
+							lead_middle_len) == 0)
+			{
+			    amount = get_indent_lnum(curwin->w_cursor.lnum - 1);
+			    break;
+			}
+			/* If the start comment string doesn't match with the
+			 * start of the comment, skip this entry. XXX */
+			else if (STRNCMP(ml_get(trypos->lnum) + trypos->col,
+					     lead_start, lead_start_len) != 0)
+			    continue;
+		    }
+		    if (start_off != 0)
+			amount += start_off;
+		    else if (start_align == COM_RIGHT)
+			amount += vim_strsize(lead_start)
+						   - vim_strsize(lead_middle);
+		    break;
+		}
+
+		/* If our line starts with the end comment string, line it up
+		 * with the middle comment */
+		if (STRNCMP(theline, lead_middle, lead_middle_len) != 0
+			&& STRNCMP(theline, lead_end, STRLEN(lead_end)) == 0)
+		{
+		    amount = get_indent_lnum(curwin->w_cursor.lnum - 1);
+								     /* XXX */
+		    if (off != 0)
+			amount += off;
+		    else if (align == COM_RIGHT)
+			amount += vim_strsize(lead_start)
+						   - vim_strsize(lead_middle);
+		    done = TRUE;
+		    break;
+		}
+	    }
+	}
+
+	/* If our line starts with an asterisk, line up with the
+	 * asterisk in the comment opener; otherwise, line up
+	 * with the first character of the comment text.
+	 */
+	if (done)
+	    ;
+	else if (theline[0] == '*')
+	    amount += 1;
+	else
+	{
+	    /*
+	     * If we are more than one line away from the comment opener, take
+	     * the indent of the previous non-empty line.  If 'cino' has "CO"
+	     * and we are just below the comment opener and there are any
+	     * white characters after it line up with the text after it;
+	     * otherwise, add the amount specified by "c" in 'cino'
+	     */
+	    amount = -1;
+	    for (lnum = cur_curpos.lnum - 1; lnum > trypos->lnum; --lnum)
+	    {
+		if (linewhite(lnum))		    /* skip blank lines */
+		    continue;
+		amount = get_indent_lnum(lnum);	    /* XXX */
+		break;
+	    }
+	    if (amount == -1)			    /* use the comment opener */
+	    {
+		if (!ind_in_comment2)
+		{
+		    start = ml_get(trypos->lnum);
+		    look = start + trypos->col + 2; /* skip / and * */
+		    if (*look != NUL)		    /* if something after it */
+			trypos->col = (colnr_T)(skipwhite(look) - start);
+		}
+		getvcol(curwin, trypos, &col, NULL, NULL);
+		amount = col;
+		if (ind_in_comment2 || *look == NUL)
+		    amount += ind_in_comment;
+	    }
+	}
+    }
+
+    /*
+     * Are we inside parentheses or braces?
+     */						    /* XXX */
+    else if (((trypos = find_match_paren(ind_maxparen, ind_maxcomment)) != NULL
+		&& ind_java == 0)
+	    || (tryposBrace = find_start_brace(ind_maxcomment)) != NULL
+	    || trypos != NULL)
+    {
+      if (trypos != NULL && tryposBrace != NULL)
+      {
+	  /* Both an unmatched '(' and '{' is found.  Use the one which is
+	   * closer to the current cursor position, set the other to NULL. */
+	  if (trypos->lnum != tryposBrace->lnum
+		  ? trypos->lnum < tryposBrace->lnum
+		  : trypos->col < tryposBrace->col)
+	      trypos = NULL;
+	  else
+	      tryposBrace = NULL;
+      }
+
+      if (trypos != NULL)
+      {
+	/*
+	 * If the matching paren is more than one line away, use the indent of
+	 * a previous non-empty line that matches the same paren.
+	 */
+	if (theline[0] == ')' && ind_paren_prev)
+	{
+	    /* Line up with the start of the matching paren line. */
+	    amount = get_indent_lnum(curwin->w_cursor.lnum - 1);  /* XXX */
+	}
+	else
+	{
+	    amount = -1;
+	    our_paren_pos = *trypos;
+	    for (lnum = cur_curpos.lnum - 1; lnum > our_paren_pos.lnum; --lnum)
+	    {
+		l = skipwhite(ml_get(lnum));
+		if (cin_nocode(l))		/* skip comment lines */
+		    continue;
+		if (cin_ispreproc_cont(&l, &lnum))
+		    continue;			/* ignore #define, #if, etc. */
+		curwin->w_cursor.lnum = lnum;
+
+		/* Skip a comment. XXX */
+		if ((trypos = find_start_comment(ind_maxcomment)) != NULL)
+		{
+		    lnum = trypos->lnum + 1;
+		    continue;
+		}
+
+		/* XXX */
+		if ((trypos = find_match_paren(
+				corr_ind_maxparen(ind_maxparen, &cur_curpos),
+						      ind_maxcomment)) != NULL
+			&& trypos->lnum == our_paren_pos.lnum
+			&& trypos->col == our_paren_pos.col)
+		{
+			amount = get_indent_lnum(lnum);	/* XXX */
+
+			if (theline[0] == ')')
+			{
+			    if (our_paren_pos.lnum != lnum
+						       && cur_amount > amount)
+				cur_amount = amount;
+			    amount = -1;
+			}
+		    break;
+		}
+	    }
+	}
+
+	/*
+	 * Line up with line where the matching paren is. XXX
+	 * If the line starts with a '(' or the indent for unclosed
+	 * parentheses is zero, line up with the unclosed parentheses.
+	 */
+	if (amount == -1)
+	{
+	    int	    ignore_paren_col = 0;
+
+	    amount = skip_label(our_paren_pos.lnum, &look, ind_maxcomment);
+	    look = skipwhite(look);
+	    if (*look == '(')
+	    {
+		linenr_T    save_lnum = curwin->w_cursor.lnum;
+		char_u	    *line;
+		int	    look_col;
+
+		/* Ignore a '(' in front of the line that has a match before
+		 * our matching '('. */
+		curwin->w_cursor.lnum = our_paren_pos.lnum;
+		line = ml_get_curline();
+		look_col = (int)(look - line);
+		curwin->w_cursor.col = look_col + 1;
+		if ((trypos = findmatchlimit(NULL, ')', 0, ind_maxparen))
+								      != NULL
+			  && trypos->lnum == our_paren_pos.lnum
+			  && trypos->col < our_paren_pos.col)
+		    ignore_paren_col = trypos->col + 1;
+
+		curwin->w_cursor.lnum = save_lnum;
+		look = ml_get(our_paren_pos.lnum) + look_col;
+	    }
+	    if (theline[0] == ')' || ind_unclosed == 0
+		    || (!ind_unclosed_noignore && *look == '('
+						    && ignore_paren_col == 0))
+	    {
+		/*
+		 * If we're looking at a close paren, line up right there;
+		 * otherwise, line up with the next (non-white) character.
+		 * When ind_unclosed_wrapped is set and the matching paren is
+		 * the last nonwhite character of the line, use either the
+		 * indent of the current line or the indentation of the next
+		 * outer paren and add ind_unclosed_wrapped (for very long
+		 * lines).
+		 */
+		if (theline[0] != ')')
+		{
+		    cur_amount = MAXCOL;
+		    l = ml_get(our_paren_pos.lnum);
+		    if (ind_unclosed_wrapped
+				       && cin_ends_in(l, (char_u *)"(", NULL))
+		    {
+			/* look for opening unmatched paren, indent one level
+			 * for each additional level */
+			n = 1;
+			for (col = 0; col < our_paren_pos.col; ++col)
+			{
+			    switch (l[col])
+			    {
+				case '(':
+				case '{': ++n;
+					  break;
+
+				case ')':
+				case '}': if (n > 1)
+					      --n;
+					  break;
+			    }
+			}
+
+			our_paren_pos.col = 0;
+			amount += n * ind_unclosed_wrapped;
+		    }
+		    else if (ind_unclosed_whiteok)
+			our_paren_pos.col++;
+		    else
+		    {
+			col = our_paren_pos.col + 1;
+			while (vim_iswhite(l[col]))
+			    col++;
+			if (l[col] != NUL)	/* In case of trailing space */
+			    our_paren_pos.col = col;
+			else
+			    our_paren_pos.col++;
+		    }
+		}
+
+		/*
+		 * Find how indented the paren is, or the character after it
+		 * if we did the above "if".
+		 */
+		if (our_paren_pos.col > 0)
+		{
+		    getvcol(curwin, &our_paren_pos, &col, NULL, NULL);
+		    if (cur_amount > (int)col)
+			cur_amount = col;
+		}
+	    }
+
+	    if (theline[0] == ')' && ind_matching_paren)
+	    {
+		/* Line up with the start of the matching paren line. */
+	    }
+	    else if (ind_unclosed == 0 || (!ind_unclosed_noignore
+				    && *look == '(' && ignore_paren_col == 0))
+	    {
+		if (cur_amount != MAXCOL)
+		    amount = cur_amount;
+	    }
+	    else
+	    {
+		/* Add ind_unclosed2 for each '(' before our matching one, but
+		 * ignore (void) before the line (ignore_paren_col). */
+		col = our_paren_pos.col;
+		while ((int)our_paren_pos.col > ignore_paren_col)
+		{
+		    --our_paren_pos.col;
+		    switch (*ml_get_pos(&our_paren_pos))
+		    {
+			case '(': amount += ind_unclosed2;
+				  col = our_paren_pos.col;
+				  break;
+			case ')': amount -= ind_unclosed2;
+				  col = MAXCOL;
+				  break;
+		    }
+		}
+
+		/* Use ind_unclosed once, when the first '(' is not inside
+		 * braces */
+		if (col == MAXCOL)
+		    amount += ind_unclosed;
+		else
+		{
+		    curwin->w_cursor.lnum = our_paren_pos.lnum;
+		    curwin->w_cursor.col = col;
+		    if ((trypos = find_match_paren(ind_maxparen,
+						     ind_maxcomment)) != NULL)
+			amount += ind_unclosed2;
+		    else
+			amount += ind_unclosed;
+		}
+		/*
+		 * For a line starting with ')' use the minimum of the two
+		 * positions, to avoid giving it more indent than the previous
+		 * lines:
+		 *  func_long_name(		    if (x
+		 *	arg				    && yy
+		 *	)	  ^ not here	       )    ^ not here
+		 */
+		if (cur_amount < amount)
+		    amount = cur_amount;
+	    }
+	}
+
+	/* add extra indent for a comment */
+	if (cin_iscomment(theline))
+	    amount += ind_comment;
+      }
+
+      /*
+       * Are we at least inside braces, then?
+       */
+      else
+      {
+	trypos = tryposBrace;
+
+	ourscope = trypos->lnum;
+	start = ml_get(ourscope);
+
+	/*
+	 * Now figure out how indented the line is in general.
+	 * If the brace was at the start of the line, we use that;
+	 * otherwise, check out the indentation of the line as
+	 * a whole and then add the "imaginary indent" to that.
+	 */
+	look = skipwhite(start);
+	if (*look == '{')
+	{
+	    getvcol(curwin, trypos, &col, NULL, NULL);
+	    amount = col;
+	    if (*start == '{')
+		start_brace = BRACE_IN_COL0;
+	    else
+		start_brace = BRACE_AT_START;
+	}
+	else
+	{
+	    /*
+	     * that opening brace might have been on a continuation
+	     * line.  if so, find the start of the line.
+	     */
+	    curwin->w_cursor.lnum = ourscope;
+
+	    /*
+	     * position the cursor over the rightmost paren, so that
+	     * matching it will take us back to the start of the line.
+	     */
+	    lnum = ourscope;
+	    if (find_last_paren(start, '(', ')')
+		    && (trypos = find_match_paren(ind_maxparen,
+						     ind_maxcomment)) != NULL)
+		lnum = trypos->lnum;
+
+	    /*
+	     * It could have been something like
+	     *	   case 1: if (asdf &&
+	     *			ldfd) {
+	     *		    }
+	     */
+	    if (ind_keep_case_label && cin_iscase(skipwhite(ml_get_curline())))
+		amount = get_indent();
+	    else
+		amount = skip_label(lnum, &l, ind_maxcomment);
+
+	    start_brace = BRACE_AT_END;
+	}
+
+	/*
+	 * if we're looking at a closing brace, that's where
+	 * we want to be.  otherwise, add the amount of room
+	 * that an indent is supposed to be.
+	 */
+	if (theline[0] == '}')
+	{
+	    /*
+	     * they may want closing braces to line up with something
+	     * other than the open brace.  indulge them, if so.
+	     */
+	    amount += ind_close_extra;
+	}
+	else
+	{
+	    /*
+	     * If we're looking at an "else", try to find an "if"
+	     * to match it with.
+	     * If we're looking at a "while", try to find a "do"
+	     * to match it with.
+	     */
+	    lookfor = LOOKFOR_INITIAL;
+	    if (cin_iselse(theline))
+		lookfor = LOOKFOR_IF;
+	    else if (cin_iswhileofdo(theline, cur_curpos.lnum, ind_maxparen))
+								    /* XXX */
+		lookfor = LOOKFOR_DO;
+	    if (lookfor != LOOKFOR_INITIAL)
+	    {
+		curwin->w_cursor.lnum = cur_curpos.lnum;
+		if (find_match(lookfor, ourscope, ind_maxparen,
+							ind_maxcomment) == OK)
+		{
+		    amount = get_indent();	/* XXX */
+		    goto theend;
+		}
+	    }
+
+	    /*
+	     * We get here if we are not on an "while-of-do" or "else" (or
+	     * failed to find a matching "if").
+	     * Search backwards for something to line up with.
+	     * First set amount for when we don't find anything.
+	     */
+
+	    /*
+	     * if the '{' is  _really_ at the left margin, use the imaginary
+	     * location of a left-margin brace.  Otherwise, correct the
+	     * location for ind_open_extra.
+	     */
+
+	    if (start_brace == BRACE_IN_COL0)	    /* '{' is in column 0 */
+	    {
+		amount = ind_open_left_imag;
+	    }
+	    else
+	    {
+		if (start_brace == BRACE_AT_END)    /* '{' is at end of line */
+		    amount += ind_open_imag;
+		else
+		{
+		    /* Compensate for adding ind_open_extra later. */
+		    amount -= ind_open_extra;
+		    if (amount < 0)
+			amount = 0;
+		}
+	    }
+
+	    lookfor_break = FALSE;
+
+	    if (cin_iscase(theline))	/* it's a switch() label */
+	    {
+		lookfor = LOOKFOR_CASE;	/* find a previous switch() label */
+		amount += ind_case;
+	    }
+	    else if (cin_isscopedecl(theline))	/* private:, ... */
+	    {
+		lookfor = LOOKFOR_SCOPEDECL;	/* class decl is this block */
+		amount += ind_scopedecl;
+	    }
+	    else
+	    {
+		if (ind_case_break && cin_isbreak(theline))	/* break; ... */
+		    lookfor_break = TRUE;
+
+		lookfor = LOOKFOR_INITIAL;
+		amount += ind_level;	/* ind_level from start of block */
+	    }
+	    scope_amount = amount;
+	    whilelevel = 0;
+
+	    /*
+	     * Search backwards.  If we find something we recognize, line up
+	     * with that.
+	     *
+	     * if we're looking at an open brace, indent
+	     * the usual amount relative to the conditional
+	     * that opens the block.
+	     */
+	    curwin->w_cursor = cur_curpos;
+	    for (;;)
+	    {
+		curwin->w_cursor.lnum--;
+		curwin->w_cursor.col = 0;
+
+		/*
+		 * If we went all the way back to the start of our scope, line
+		 * up with it.
+		 */
+		if (curwin->w_cursor.lnum <= ourscope)
+		{
+		    /* we reached end of scope:
+		     * if looking for a enum or structure initialization
+		     * go further back:
+		     * if it is an initializer (enum xxx or xxx =), then
+		     * don't add ind_continuation, otherwise it is a variable
+		     * declaration:
+		     * int x,
+		     *     here; <-- add ind_continuation
+		     */
+		    if (lookfor == LOOKFOR_ENUM_OR_INIT)
+		    {
+			if (curwin->w_cursor.lnum == 0
+				|| curwin->w_cursor.lnum
+						    < ourscope - ind_maxparen)
+			{
+			    /* nothing found (abuse ind_maxparen as limit)
+			     * assume terminated line (i.e. a variable
+			     * initialization) */
+			    if (cont_amount > 0)
+				amount = cont_amount;
+			    else
+				amount += ind_continuation;
+			    break;
+			}
+
+			l = ml_get_curline();
+
+			/*
+			 * If we're in a comment now, skip to the start of the
+			 * comment.
+			 */
+			trypos = find_start_comment(ind_maxcomment);
+			if (trypos != NULL)
+			{
+			    curwin->w_cursor.lnum = trypos->lnum + 1;
+			    continue;
+			}
+
+			/*
+			 * Skip preprocessor directives and blank lines.
+			 */
+			if (cin_ispreproc_cont(&l, &curwin->w_cursor.lnum))
+			    continue;
+
+			if (cin_nocode(l))
+			    continue;
+
+			terminated = cin_isterminated(l, FALSE, TRUE);
+
+			/*
+			 * If we are at top level and the line looks like a
+			 * function declaration, we are done
+			 * (it's a variable declaration).
+			 */
+			if (start_brace != BRACE_IN_COL0
+				|| !cin_isfuncdecl(&l, curwin->w_cursor.lnum))
+			{
+			    /* if the line is terminated with another ','
+			     * it is a continued variable initialization.
+			     * don't add extra indent.
+			     * TODO: does not work, if  a function
+			     * declaration is split over multiple lines:
+			     * cin_isfuncdecl returns FALSE then.
+			     */
+			    if (terminated == ',')
+				break;
+
+			    /* if it es a enum declaration or an assignment,
+			     * we are done.
+			     */
+			    if (terminated != ';' && cin_isinit())
+				break;
+
+			    /* nothing useful found */
+			    if (terminated == 0 || terminated == '{')
+				continue;
+			}
+
+			if (terminated != ';')
+			{
+			    /* Skip parens and braces. Position the cursor
+			     * over the rightmost paren, so that matching it
+			     * will take us back to the start of the line.
+			     */					/* XXX */
+			    trypos = NULL;
+			    if (find_last_paren(l, '(', ')'))
+				trypos = find_match_paren(ind_maxparen,
+					ind_maxcomment);
+
+			    if (trypos == NULL && find_last_paren(l, '{', '}'))
+				trypos = find_start_brace(ind_maxcomment);
+
+			    if (trypos != NULL)
+			    {
+				curwin->w_cursor.lnum = trypos->lnum + 1;
+				continue;
+			    }
+			}
+
+			/* it's a variable declaration, add indentation
+			 * like in
+			 * int a,
+			 *    b;
+			 */
+			if (cont_amount > 0)
+			    amount = cont_amount;
+			else
+			    amount += ind_continuation;
+		    }
+		    else if (lookfor == LOOKFOR_UNTERM)
+		    {
+			if (cont_amount > 0)
+			    amount = cont_amount;
+			else
+			    amount += ind_continuation;
+		    }
+		    else if (lookfor != LOOKFOR_TERM
+					  && lookfor != LOOKFOR_CPP_BASECLASS)
+		    {
+			amount = scope_amount;
+			if (theline[0] == '{')
+			    amount += ind_open_extra;
+		    }
+		    break;
+		}
+
+		/*
+		 * If we're in a comment now, skip to the start of the comment.
+		 */					    /* XXX */
+		if ((trypos = find_start_comment(ind_maxcomment)) != NULL)
+		{
+		    curwin->w_cursor.lnum = trypos->lnum + 1;
+		    continue;
+		}
+
+		l = ml_get_curline();
+
+		/*
+		 * If this is a switch() label, may line up relative to that.
+		 * If this is a C++ scope declaration, do the same.
+		 */
+		iscase = cin_iscase(l);
+		if (iscase || cin_isscopedecl(l))
+		{
+		    /* we are only looking for cpp base class
+		     * declaration/initialization any longer */
+		    if (lookfor == LOOKFOR_CPP_BASECLASS)
+			break;
+
+		    /* When looking for a "do" we are not interested in
+		     * labels. */
+		    if (whilelevel > 0)
+			continue;
+
+		    /*
+		     *	case xx:
+		     *	    c = 99 +	    <- this indent plus continuation
+		     *->	   here;
+		     */
+		    if (lookfor == LOOKFOR_UNTERM
+					   || lookfor == LOOKFOR_ENUM_OR_INIT)
+		    {
+			if (cont_amount > 0)
+			    amount = cont_amount;
+			else
+			    amount += ind_continuation;
+			break;
+		    }
+
+		    /*
+		     *	case xx:	<- line up with this case
+		     *	    x = 333;
+		     *	case yy:
+		     */
+		    if (       (iscase && lookfor == LOOKFOR_CASE)
+			    || (iscase && lookfor_break)
+			    || (!iscase && lookfor == LOOKFOR_SCOPEDECL))
+		    {
+			/*
+			 * Check that this case label is not for another
+			 * switch()
+			 */				    /* XXX */
+			if ((trypos = find_start_brace(ind_maxcomment)) ==
+					     NULL || trypos->lnum == ourscope)
+			{
+			    amount = get_indent();	/* XXX */
+			    break;
+			}
+			continue;
+		    }
+
+		    n = get_indent_nolabel(curwin->w_cursor.lnum);  /* XXX */
+
+		    /*
+		     *	 case xx: if (cond)	    <- line up with this if
+		     *		      y = y + 1;
+		     * ->	  s = 99;
+		     *
+		     *	 case xx:
+		     *	     if (cond)		<- line up with this line
+		     *		 y = y + 1;
+		     * ->    s = 99;
+		     */
+		    if (lookfor == LOOKFOR_TERM)
+		    {
+			if (n)
+			    amount = n;
+
+			if (!lookfor_break)
+			    break;
+		    }
+
+		    /*
+		     *	 case xx: x = x + 1;	    <- line up with this x
+		     * ->	  y = y + 1;
+		     *
+		     *	 case xx: if (cond)	    <- line up with this if
+		     * ->	       y = y + 1;
+		     */
+		    if (n)
+		    {
+			amount = n;
+			l = after_label(ml_get_curline());
+			if (l != NULL && cin_is_cinword(l))
+			{
+			    if (theline[0] == '{')
+				amount += ind_open_extra;
+			    else
+				amount += ind_level + ind_no_brace;
+			}
+			break;
+		    }
+
+		    /*
+		     * Try to get the indent of a statement before the switch
+		     * label.  If nothing is found, line up relative to the
+		     * switch label.
+		     *	    break;		<- may line up with this line
+		     *	 case xx:
+		     * ->   y = 1;
+		     */
+		    scope_amount = get_indent() + (iscase    /* XXX */
+					? ind_case_code : ind_scopedecl_code);
+		    lookfor = ind_case_break ? LOOKFOR_NOBREAK : LOOKFOR_ANY;
+		    continue;
+		}
+
+		/*
+		 * Looking for a switch() label or C++ scope declaration,
+		 * ignore other lines, skip {}-blocks.
+		 */
+		if (lookfor == LOOKFOR_CASE || lookfor == LOOKFOR_SCOPEDECL)
+		{
+		    if (find_last_paren(l, '{', '}') && (trypos =
+				    find_start_brace(ind_maxcomment)) != NULL)
+			curwin->w_cursor.lnum = trypos->lnum + 1;
+		    continue;
+		}
+
+		/*
+		 * Ignore jump labels with nothing after them.
+		 */
+		if (cin_islabel(ind_maxcomment))
+		{
+		    l = after_label(ml_get_curline());
+		    if (l == NULL || cin_nocode(l))
+			continue;
+		}
+
+		/*
+		 * Ignore #defines, #if, etc.
+		 * Ignore comment and empty lines.
+		 * (need to get the line again, cin_islabel() may have
+		 * unlocked it)
+		 */
+		l = ml_get_curline();
+		if (cin_ispreproc_cont(&l, &curwin->w_cursor.lnum)
+							     || cin_nocode(l))
+		    continue;
+
+		/*
+		 * Are we at the start of a cpp base class declaration or
+		 * constructor initialization?
+		 */						    /* XXX */
+		n = FALSE;
+		if (lookfor != LOOKFOR_TERM && ind_cpp_baseclass > 0)
+		{
+		    n = cin_is_cpp_baseclass(l, &col);
+		    l = ml_get_curline();
+		}
+		if (n)
+		{
+		    if (lookfor == LOOKFOR_UNTERM)
+		    {
+			if (cont_amount > 0)
+			    amount = cont_amount;
+			else
+			    amount += ind_continuation;
+		    }
+		    else if (theline[0] == '{')
+		    {
+			/* Need to find start of the declaration. */
+			lookfor = LOOKFOR_UNTERM;
+			ind_continuation = 0;
+			continue;
+		    }
+		    else
+								     /* XXX */
+			amount = get_baseclass_amount(col, ind_maxparen,
+					   ind_maxcomment, ind_cpp_baseclass);
+		    break;
+		}
+		else if (lookfor == LOOKFOR_CPP_BASECLASS)
+		{
+		    /* only look, whether there is a cpp base class
+		     * declaration or initialization before the opening brace.
+		     */
+		    if (cin_isterminated(l, TRUE, FALSE))
+			break;
+		    else
+			continue;
+		}
+
+		/*
+		 * What happens next depends on the line being terminated.
+		 * If terminated with a ',' only consider it terminating if
+		 * there is another unterminated statement behind, eg:
+		 *   123,
+		 *   sizeof
+		 *	  here
+		 * Otherwise check whether it is a enumeration or structure
+		 * initialisation (not indented) or a variable declaration
+		 * (indented).
+		 */
+		terminated = cin_isterminated(l, FALSE, TRUE);
+
+		if (terminated == 0 || (lookfor != LOOKFOR_UNTERM
+							&& terminated == ','))
+		{
+		    /*
+		     * if we're in the middle of a paren thing,
+		     * go back to the line that starts it so
+		     * we can get the right prevailing indent
+		     *	   if ( foo &&
+		     *		    bar )
+		     */
+		    /*
+		     * position the cursor over the rightmost paren, so that
+		     * matching it will take us back to the start of the line.
+		     */
+		    (void)find_last_paren(l, '(', ')');
+		    trypos = find_match_paren(
+				 corr_ind_maxparen(ind_maxparen, &cur_curpos),
+							      ind_maxcomment);
+
+		    /*
+		     * If we are looking for ',', we also look for matching
+		     * braces.
+		     */
+		    if (trypos == NULL && terminated == ','
+					      && find_last_paren(l, '{', '}'))
+			trypos = find_start_brace(ind_maxcomment);
+
+		    if (trypos != NULL)
+		    {
+			/*
+			 * Check if we are on a case label now.  This is
+			 * handled above.
+			 *     case xx:  if ( asdf &&
+			 *			asdf)
+			 */
+			curwin->w_cursor.lnum = trypos->lnum;
+			l = ml_get_curline();
+			if (cin_iscase(l) || cin_isscopedecl(l))
+			{
+			    ++curwin->w_cursor.lnum;
+			    continue;
+			}
+		    }
+
+		    /*
+		     * Skip over continuation lines to find the one to get the
+		     * indent from
+		     * char *usethis = "bla\
+		     *		 bla",
+		     *      here;
+		     */
+		    if (terminated == ',')
+		    {
+			while (curwin->w_cursor.lnum > 1)
+			{
+			    l = ml_get(curwin->w_cursor.lnum - 1);
+			    if (*l == NUL || l[STRLEN(l) - 1] != '\\')
+				break;
+			    --curwin->w_cursor.lnum;
+			}
+		    }
+
+		    /*
+		     * Get indent and pointer to text for current line,
+		     * ignoring any jump label.	    XXX
+		     */
+		    cur_amount = skip_label(curwin->w_cursor.lnum,
+							  &l, ind_maxcomment);
+
+		    /*
+		     * If this is just above the line we are indenting, and it
+		     * starts with a '{', line it up with this line.
+		     *		while (not)
+		     * ->	{
+		     *		}
+		     */
+		    if (terminated != ',' && lookfor != LOOKFOR_TERM
+							 && theline[0] == '{')
+		    {
+			amount = cur_amount;
+			/*
+			 * Only add ind_open_extra when the current line
+			 * doesn't start with a '{', which must have a match
+			 * in the same line (scope is the same).  Probably:
+			 *	{ 1, 2 },
+			 * ->	{ 3, 4 }
+			 */
+			if (*skipwhite(l) != '{')
+			    amount += ind_open_extra;
+
+			if (ind_cpp_baseclass)
+			{
+			    /* have to look back, whether it is a cpp base
+			     * class declaration or initialization */
+			    lookfor = LOOKFOR_CPP_BASECLASS;
+			    continue;
+			}
+			break;
+		    }
+
+		    /*
+		     * Check if we are after an "if", "while", etc.
+		     * Also allow "   } else".
+		     */
+		    if (cin_is_cinword(l) || cin_iselse(skipwhite(l)))
+		    {
+			/*
+			 * Found an unterminated line after an if (), line up
+			 * with the last one.
+			 *   if (cond)
+			 *	    100 +
+			 * ->		here;
+			 */
+			if (lookfor == LOOKFOR_UNTERM
+					   || lookfor == LOOKFOR_ENUM_OR_INIT)
+			{
+			    if (cont_amount > 0)
+				amount = cont_amount;
+			    else
+				amount += ind_continuation;
+			    break;
+			}
+
+			/*
+			 * If this is just above the line we are indenting, we
+			 * are finished.
+			 *	    while (not)
+			 * ->		here;
+			 * Otherwise this indent can be used when the line
+			 * before this is terminated.
+			 *	yyy;
+			 *	if (stat)
+			 *	    while (not)
+			 *		xxx;
+			 * ->	here;
+			 */
+			amount = cur_amount;
+			if (theline[0] == '{')
+			    amount += ind_open_extra;
+			if (lookfor != LOOKFOR_TERM)
+			{
+			    amount += ind_level + ind_no_brace;
+			    break;
+			}
+
+			/*
+			 * Special trick: when expecting the while () after a
+			 * do, line up with the while()
+			 *     do
+			 *	    x = 1;
+			 * ->  here
+			 */
+			l = skipwhite(ml_get_curline());
+			if (cin_isdo(l))
+			{
+			    if (whilelevel == 0)
+				break;
+			    --whilelevel;
+			}
+
+			/*
+			 * When searching for a terminated line, don't use the
+			 * one between the "if" and the "else".
+			 * Need to use the scope of this "else".  XXX
+			 * If whilelevel != 0 continue looking for a "do {".
+			 */
+			if (cin_iselse(l)
+				&& whilelevel == 0
+				&& ((trypos = find_start_brace(ind_maxcomment))
+								    == NULL
+				    || find_match(LOOKFOR_IF, trypos->lnum,
+					ind_maxparen, ind_maxcomment) == FAIL))
+			    break;
+		    }
+
+		    /*
+		     * If we're below an unterminated line that is not an
+		     * "if" or something, we may line up with this line or
+		     * add something for a continuation line, depending on
+		     * the line before this one.
+		     */
+		    else
+		    {
+			/*
+			 * Found two unterminated lines on a row, line up with
+			 * the last one.
+			 *   c = 99 +
+			 *	    100 +
+			 * ->	    here;
+			 */
+			if (lookfor == LOOKFOR_UNTERM)
+			{
+			    /* When line ends in a comma add extra indent */
+			    if (terminated == ',')
+				amount += ind_continuation;
+			    break;
+			}
+
+			if (lookfor == LOOKFOR_ENUM_OR_INIT)
+			{
+			    /* Found two lines ending in ',', lineup with the
+			     * lowest one, but check for cpp base class
+			     * declaration/initialization, if it is an
+			     * opening brace or we are looking just for
+			     * enumerations/initializations. */
+			    if (terminated == ',')
+			    {
+				if (ind_cpp_baseclass == 0)
+				    break;
+
+				lookfor = LOOKFOR_CPP_BASECLASS;
+				continue;
+			    }
+
+			    /* Ignore unterminated lines in between, but
+			     * reduce indent. */
+			    if (amount > cur_amount)
+				amount = cur_amount;
+			}
+			else
+			{
+			    /*
+			     * Found first unterminated line on a row, may
+			     * line up with this line, remember its indent
+			     *	    100 +
+			     * ->	    here;
+			     */
+			    amount = cur_amount;
+
+			    /*
+			     * If previous line ends in ',', check whether we
+			     * are in an initialization or enum
+			     * struct xxx =
+			     * {
+			     *      sizeof a,
+			     *      124 };
+			     * or a normal possible continuation line.
+			     * but only, of no other statement has been found
+			     * yet.
+			     */
+			    if (lookfor == LOOKFOR_INITIAL && terminated == ',')
+			    {
+				lookfor = LOOKFOR_ENUM_OR_INIT;
+				cont_amount = cin_first_id_amount();
+			    }
+			    else
+			    {
+				if (lookfor == LOOKFOR_INITIAL
+					&& *l != NUL
+					&& l[STRLEN(l) - 1] == '\\')
+								/* XXX */
+				    cont_amount = cin_get_equal_amount(
+						       curwin->w_cursor.lnum);
+				if (lookfor != LOOKFOR_TERM)
+				    lookfor = LOOKFOR_UNTERM;
+			    }
+			}
+		    }
+		}
+
+		/*
+		 * Check if we are after a while (cond);
+		 * If so: Ignore until the matching "do".
+		 */
+							/* XXX */
+		else if (cin_iswhileofdo_end(terminated, ind_maxparen,
+							      ind_maxcomment))
+		{
+		    /*
+		     * Found an unterminated line after a while ();, line up
+		     * with the last one.
+		     *	    while (cond);
+		     *	    100 +		<- line up with this one
+		     * ->	    here;
+		     */
+		    if (lookfor == LOOKFOR_UNTERM
+					   || lookfor == LOOKFOR_ENUM_OR_INIT)
+		    {
+			if (cont_amount > 0)
+			    amount = cont_amount;
+			else
+			    amount += ind_continuation;
+			break;
+		    }
+
+		    if (whilelevel == 0)
+		    {
+			lookfor = LOOKFOR_TERM;
+			amount = get_indent();	    /* XXX */
+			if (theline[0] == '{')
+			    amount += ind_open_extra;
+		    }
+		    ++whilelevel;
+		}
+
+		/*
+		 * We are after a "normal" statement.
+		 * If we had another statement we can stop now and use the
+		 * indent of that other statement.
+		 * Otherwise the indent of the current statement may be used,
+		 * search backwards for the next "normal" statement.
+		 */
+		else
+		{
+		    /*
+		     * Skip single break line, if before a switch label. It
+		     * may be lined up with the case label.
+		     */
+		    if (lookfor == LOOKFOR_NOBREAK
+				  && cin_isbreak(skipwhite(ml_get_curline())))
+		    {
+			lookfor = LOOKFOR_ANY;
+			continue;
+		    }
+
+		    /*
+		     * Handle "do {" line.
+		     */
+		    if (whilelevel > 0)
+		    {
+			l = cin_skipcomment(ml_get_curline());
+			if (cin_isdo(l))
+			{
+			    amount = get_indent();	/* XXX */
+			    --whilelevel;
+			    continue;
+			}
+		    }
+
+		    /*
+		     * Found a terminated line above an unterminated line. Add
+		     * the amount for a continuation line.
+		     *	 x = 1;
+		     *	 y = foo +
+		     * ->	here;
+		     * or
+		     *	 int x = 1;
+		     *	 int foo,
+		     * ->	here;
+		     */
+		    if (lookfor == LOOKFOR_UNTERM
+					   || lookfor == LOOKFOR_ENUM_OR_INIT)
+		    {
+			if (cont_amount > 0)
+			    amount = cont_amount;
+			else
+			    amount += ind_continuation;
+			break;
+		    }
+
+		    /*
+		     * Found a terminated line above a terminated line or "if"
+		     * etc. line. Use the amount of the line below us.
+		     *	 x = 1;				x = 1;
+		     *	 if (asdf)		    y = 2;
+		     *	     while (asdf)	  ->here;
+		     *		here;
+		     * ->foo;
+		     */
+		    if (lookfor == LOOKFOR_TERM)
+		    {
+			if (!lookfor_break && whilelevel == 0)
+			    break;
+		    }
+
+		    /*
+		     * First line above the one we're indenting is terminated.
+		     * To know what needs to be done look further backward for
+		     * a terminated line.
+		     */
+		    else
+		    {
+			/*
+			 * position the cursor over the rightmost paren, so
+			 * that matching it will take us back to the start of
+			 * the line.  Helps for:
+			 *     func(asdr,
+			 *	      asdfasdf);
+			 *     here;
+			 */
+term_again:
+			l = ml_get_curline();
+			if (find_last_paren(l, '(', ')')
+				&& (trypos = find_match_paren(ind_maxparen,
+						     ind_maxcomment)) != NULL)
+			{
+			    /*
+			     * Check if we are on a case label now.  This is
+			     * handled above.
+			     *	   case xx:  if ( asdf &&
+			     *			    asdf)
+			     */
+			    curwin->w_cursor.lnum = trypos->lnum;
+			    l = ml_get_curline();
+			    if (cin_iscase(l) || cin_isscopedecl(l))
+			    {
+				++curwin->w_cursor.lnum;
+				continue;
+			    }
+			}
+
+			/* When aligning with the case statement, don't align
+			 * with a statement after it.
+			 *  case 1: {   <-- don't use this { position
+			 *	stat;
+			 *  }
+			 *  case 2:
+			 *	stat;
+			 * }
+			 */
+			iscase = (ind_keep_case_label && cin_iscase(l));
+
+			/*
+			 * Get indent and pointer to text for current line,
+			 * ignoring any jump label.
+			 */
+			amount = skip_label(curwin->w_cursor.lnum,
+							  &l, ind_maxcomment);
+
+			if (theline[0] == '{')
+			    amount += ind_open_extra;
+			/* See remark above: "Only add ind_open_extra.." */
+			l = skipwhite(l);
+			if (*l == '{')
+			    amount -= ind_open_extra;
+			lookfor = iscase ? LOOKFOR_ANY : LOOKFOR_TERM;
+
+			/*
+			 * When a terminated line starts with "else" skip to
+			 * the matching "if":
+			 *       else 3;
+			 *	     indent this;
+			 * Need to use the scope of this "else".  XXX
+			 * If whilelevel != 0 continue looking for a "do {".
+			 */
+			if (lookfor == LOOKFOR_TERM
+				&& *l != '}'
+				&& cin_iselse(l)
+				&& whilelevel == 0)
+			{
+			    if ((trypos = find_start_brace(ind_maxcomment))
+								       == NULL
+				    || find_match(LOOKFOR_IF, trypos->lnum,
+					ind_maxparen, ind_maxcomment) == FAIL)
+				break;
+			    continue;
+			}
+
+			/*
+			 * If we're at the end of a block, skip to the start of
+			 * that block.
+			 */
+			curwin->w_cursor.col = 0;
+			if (*cin_skipcomment(l) == '}'
+				&& (trypos = find_start_brace(ind_maxcomment))
+							    != NULL) /* XXX */
+			{
+			    curwin->w_cursor.lnum = trypos->lnum;
+			    /* if not "else {" check for terminated again */
+			    /* but skip block for "} else {" */
+			    l = cin_skipcomment(ml_get_curline());
+			    if (*l == '}' || !cin_iselse(l))
+				goto term_again;
+			    ++curwin->w_cursor.lnum;
+			}
+		    }
+		}
+	    }
+	}
+      }
+
+      /* add extra indent for a comment */
+      if (cin_iscomment(theline))
+	  amount += ind_comment;
+    }
+
+    /*
+     * ok -- we're not inside any sort of structure at all!
+     *
+     * this means we're at the top level, and everything should
+     * basically just match where the previous line is, except
+     * for the lines immediately following a function declaration,
+     * which are K&R-style parameters and need to be indented.
+     */
+    else
+    {
+	/*
+	 * if our line starts with an open brace, forget about any
+	 * prevailing indent and make sure it looks like the start
+	 * of a function
+	 */
+
+	if (theline[0] == '{')
+	{
+	    amount = ind_first_open;
+	}
+
+	/*
+	 * If the NEXT line is a function declaration, the current
+	 * line needs to be indented as a function type spec.
+	 * Don't do this if the current line looks like a comment
+	 * or if the current line is terminated, ie. ends in ';'.
+	 */
+	else if (cur_curpos.lnum < curbuf->b_ml.ml_line_count
+		&& !cin_nocode(theline)
+		&& !cin_ends_in(theline, (char_u *)":", NULL)
+		&& !cin_ends_in(theline, (char_u *)",", NULL)
+		&& cin_isfuncdecl(NULL, cur_curpos.lnum + 1)
+		&& !cin_isterminated(theline, FALSE, TRUE))
+	{
+	    amount = ind_func_type;
+	}
+	else
+	{
+	    amount = 0;
+	    curwin->w_cursor = cur_curpos;
+
+	    /* search backwards until we find something we recognize */
+
+	    while (curwin->w_cursor.lnum > 1)
+	    {
+		curwin->w_cursor.lnum--;
+		curwin->w_cursor.col = 0;
+
+		l = ml_get_curline();
+
+		/*
+		 * If we're in a comment now, skip to the start of the comment.
+		 */						/* XXX */
+		if ((trypos = find_start_comment(ind_maxcomment)) != NULL)
+		{
+		    curwin->w_cursor.lnum = trypos->lnum + 1;
+		    continue;
+		}
+
+		/*
+		 * Are we at the start of a cpp base class declaration or
+		 * constructor initialization?
+		 */						    /* XXX */
+		n = FALSE;
+		if (ind_cpp_baseclass != 0 && theline[0] != '{')
+		{
+		    n = cin_is_cpp_baseclass(l, &col);
+		    l = ml_get_curline();
+		}
+		if (n)
+		{
+								     /* XXX */
+		    amount = get_baseclass_amount(col, ind_maxparen,
+					   ind_maxcomment, ind_cpp_baseclass);
+		    break;
+		}
+
+		/*
+		 * Skip preprocessor directives and blank lines.
+		 */
+		if (cin_ispreproc_cont(&l, &curwin->w_cursor.lnum))
+		    continue;
+
+		if (cin_nocode(l))
+		    continue;
+
+		/*
+		 * If the previous line ends in ',', use one level of
+		 * indentation:
+		 * int foo,
+		 *     bar;
+		 * do this before checking for '}' in case of eg.
+		 * enum foobar
+		 * {
+		 *   ...
+		 * } foo,
+		 *   bar;
+		 */
+		n = 0;
+		if (cin_ends_in(l, (char_u *)",", NULL)
+			     || (*l != NUL && (n = l[STRLEN(l) - 1]) == '\\'))
+		{
+		    /* take us back to opening paren */
+		    if (find_last_paren(l, '(', ')')
+			    && (trypos = find_match_paren(ind_maxparen,
+						     ind_maxcomment)) != NULL)
+			curwin->w_cursor.lnum = trypos->lnum;
+
+		    /* For a line ending in ',' that is a continuation line go
+		     * back to the first line with a backslash:
+		     * char *foo = "bla\
+		     *		 bla",
+		     *      here;
+		     */
+		    while (n == 0 && curwin->w_cursor.lnum > 1)
+		    {
+			l = ml_get(curwin->w_cursor.lnum - 1);
+			if (*l == NUL || l[STRLEN(l) - 1] != '\\')
+			    break;
+			--curwin->w_cursor.lnum;
+		    }
+
+		    amount = get_indent();	    /* XXX */
+
+		    if (amount == 0)
+			amount = cin_first_id_amount();
+		    if (amount == 0)
+			amount = ind_continuation;
+		    break;
+		}
+
+		/*
+		 * If the line looks like a function declaration, and we're
+		 * not in a comment, put it the left margin.
+		 */
+		if (cin_isfuncdecl(NULL, cur_curpos.lnum))  /* XXX */
+		    break;
+		l = ml_get_curline();
+
+		/*
+		 * Finding the closing '}' of a previous function.  Put
+		 * current line at the left margin.  For when 'cino' has "fs".
+		 */
+		if (*skipwhite(l) == '}')
+		    break;
+
+		/*			    (matching {)
+		 * If the previous line ends on '};' (maybe followed by
+		 * comments) align at column 0.  For example:
+		 * char *string_array[] = { "foo",
+		 *     / * x * / "b};ar" }; / * foobar * /
+		 */
+		if (cin_ends_in(l, (char_u *)"};", NULL))
+		    break;
+
+		/*
+		 * If the PREVIOUS line is a function declaration, the current
+		 * line (and the ones that follow) needs to be indented as
+		 * parameters.
+		 */
+		if (cin_isfuncdecl(&l, curwin->w_cursor.lnum))
+		{
+		    amount = ind_param;
+		    break;
+		}
+
+		/*
+		 * If the previous line ends in ';' and the line before the
+		 * previous line ends in ',' or '\', ident to column zero:
+		 * int foo,
+		 *     bar;
+		 * indent_to_0 here;
+		 */
+		if (cin_ends_in(l, (char_u *)";", NULL))
+		{
+		    l = ml_get(curwin->w_cursor.lnum - 1);
+		    if (cin_ends_in(l, (char_u *)",", NULL)
+			    || (*l != NUL && l[STRLEN(l) - 1] == '\\'))
+			break;
+		    l = ml_get_curline();
+		}
+
+		/*
+		 * Doesn't look like anything interesting -- so just
+		 * use the indent of this line.
+		 *
+		 * Position the cursor over the rightmost paren, so that
+		 * matching it will take us back to the start of the line.
+		 */
+		find_last_paren(l, '(', ')');
+
+		if ((trypos = find_match_paren(ind_maxparen,
+						     ind_maxcomment)) != NULL)
+		    curwin->w_cursor.lnum = trypos->lnum;
+		amount = get_indent();	    /* XXX */
+		break;
+	    }
+
+	    /* add extra indent for a comment */
+	    if (cin_iscomment(theline))
+		amount += ind_comment;
+
+	    /* add extra indent if the previous line ended in a backslash:
+	     *	      "asdfasdf\
+	     *		  here";
+	     *	    char *foo = "asdf\
+	     *			 here";
+	     */
+	    if (cur_curpos.lnum > 1)
+	    {
+		l = ml_get(cur_curpos.lnum - 1);
+		if (*l != NUL && l[STRLEN(l) - 1] == '\\')
+		{
+		    cur_amount = cin_get_equal_amount(cur_curpos.lnum - 1);
+		    if (cur_amount > 0)
+			amount = cur_amount;
+		    else if (cur_amount == 0)
+			amount += ind_continuation;
+		}
+	    }
+	}
+    }
+
+theend:
+    /* put the cursor back where it belongs */
+    curwin->w_cursor = cur_curpos;
+
+    vim_free(linecopy);
+
+    if (amount < 0)
+	return 0;
+    return amount;
+}
+
+    static int
+find_match(lookfor, ourscope, ind_maxparen, ind_maxcomment)
+    int		lookfor;
+    linenr_T	ourscope;
+    int		ind_maxparen;
+    int		ind_maxcomment;
+{
+    char_u	*look;
+    pos_T	*theirscope;
+    char_u	*mightbeif;
+    int		elselevel;
+    int		whilelevel;
+
+    if (lookfor == LOOKFOR_IF)
+    {
+	elselevel = 1;
+	whilelevel = 0;
+    }
+    else
+    {
+	elselevel = 0;
+	whilelevel = 1;
+    }
+
+    curwin->w_cursor.col = 0;
+
+    while (curwin->w_cursor.lnum > ourscope + 1)
+    {
+	curwin->w_cursor.lnum--;
+	curwin->w_cursor.col = 0;
+
+	look = cin_skipcomment(ml_get_curline());
+	if (cin_iselse(look)
+		|| cin_isif(look)
+		|| cin_isdo(look)			    /* XXX */
+		|| cin_iswhileofdo(look, curwin->w_cursor.lnum, ind_maxparen))
+	{
+	    /*
+	     * if we've gone outside the braces entirely,
+	     * we must be out of scope...
+	     */
+	    theirscope = find_start_brace(ind_maxcomment);  /* XXX */
+	    if (theirscope == NULL)
+		break;
+
+	    /*
+	     * and if the brace enclosing this is further
+	     * back than the one enclosing the else, we're
+	     * out of luck too.
+	     */
+	    if (theirscope->lnum < ourscope)
+		break;
+
+	    /*
+	     * and if they're enclosed in a *deeper* brace,
+	     * then we can ignore it because it's in a
+	     * different scope...
+	     */
+	    if (theirscope->lnum > ourscope)
+		continue;
+
+	    /*
+	     * if it was an "else" (that's not an "else if")
+	     * then we need to go back to another if, so
+	     * increment elselevel
+	     */
+	    look = cin_skipcomment(ml_get_curline());
+	    if (cin_iselse(look))
+	    {
+		mightbeif = cin_skipcomment(look + 4);
+		if (!cin_isif(mightbeif))
+		    ++elselevel;
+		continue;
+	    }
+
+	    /*
+	     * if it was a "while" then we need to go back to
+	     * another "do", so increment whilelevel.  XXX
+	     */
+	    if (cin_iswhileofdo(look, curwin->w_cursor.lnum, ind_maxparen))
+	    {
+		++whilelevel;
+		continue;
+	    }
+
+	    /* If it's an "if" decrement elselevel */
+	    look = cin_skipcomment(ml_get_curline());
+	    if (cin_isif(look))
+	    {
+		elselevel--;
+		/*
+		 * When looking for an "if" ignore "while"s that
+		 * get in the way.
+		 */
+		if (elselevel == 0 && lookfor == LOOKFOR_IF)
+		    whilelevel = 0;
+	    }
+
+	    /* If it's a "do" decrement whilelevel */
+	    if (cin_isdo(look))
+		whilelevel--;
+
+	    /*
+	     * if we've used up all the elses, then
+	     * this must be the if that we want!
+	     * match the indent level of that if.
+	     */
+	    if (elselevel <= 0 && whilelevel <= 0)
+	    {
+		return OK;
+	    }
+	}
+    }
+    return FAIL;
+}
+
+# if defined(FEAT_EVAL) || defined(PROTO)
+/*
+ * Get indent level from 'indentexpr'.
+ */
+    int
+get_expr_indent()
+{
+    int		indent;
+    pos_T	pos;
+    int		save_State;
+    int		use_sandbox = was_set_insecurely((char_u *)"indentexpr",
+								   OPT_LOCAL);
+
+    pos = curwin->w_cursor;
+    set_vim_var_nr(VV_LNUM, curwin->w_cursor.lnum);
+    if (use_sandbox)
+	++sandbox;
+    ++textlock;
+    indent = eval_to_number(curbuf->b_p_inde);
+    if (use_sandbox)
+	--sandbox;
+    --textlock;
+
+    /* Restore the cursor position so that 'indentexpr' doesn't need to.
+     * Pretend to be in Insert mode, allow cursor past end of line for "o"
+     * command. */
+    save_State = State;
+    State = INSERT;
+    curwin->w_cursor = pos;
+    check_cursor();
+    State = save_State;
+
+    /* If there is an error, just keep the current indent. */
+    if (indent < 0)
+	indent = get_indent();
+
+    return indent;
+}
+# endif
+
+#endif /* FEAT_CINDENT */
+
+#if defined(FEAT_LISP) || defined(PROTO)
+
+static int lisp_match __ARGS((char_u *p));
+
+    static int
+lisp_match(p)
+    char_u	*p;
+{
+    char_u	buf[LSIZE];
+    int		len;
+    char_u	*word = p_lispwords;
+
+    while (*word != NUL)
+    {
+	(void)copy_option_part(&word, buf, LSIZE, ",");
+	len = (int)STRLEN(buf);
+	if (STRNCMP(buf, p, len) == 0 && p[len] == ' ')
+	    return TRUE;
+    }
+    return FALSE;
+}
+
+/*
+ * When 'p' is present in 'cpoptions, a Vi compatible method is used.
+ * The incompatible newer method is quite a bit better at indenting
+ * code in lisp-like languages than the traditional one; it's still
+ * mostly heuristics however -- Dirk van Deun, dirk@rave.org
+ *
+ * TODO:
+ * Findmatch() should be adapted for lisp, also to make showmatch
+ * work correctly: now (v5.3) it seems all C/C++ oriented:
+ * - it does not recognize the #\( and #\) notations as character literals
+ * - it doesn't know about comments starting with a semicolon
+ * - it incorrectly interprets '(' as a character literal
+ * All this messes up get_lisp_indent in some rare cases.
+ * Update from Sergey Khorev:
+ * I tried to fix the first two issues.
+ */
+    int
+get_lisp_indent()
+{
+    pos_T	*pos, realpos, paren;
+    int		amount;
+    char_u	*that;
+    colnr_T	col;
+    colnr_T	firsttry;
+    int		parencount, quotecount;
+    int		vi_lisp;
+
+    /* Set vi_lisp to use the vi-compatible method */
+    vi_lisp = (vim_strchr(p_cpo, CPO_LISP) != NULL);
+
+    realpos = curwin->w_cursor;
+    curwin->w_cursor.col = 0;
+
+    if ((pos = findmatch(NULL, '(')) == NULL)
+	pos = findmatch(NULL, '[');
+    else
+    {
+	paren = *pos;
+	pos = findmatch(NULL, '[');
+	if (pos == NULL || ltp(pos, &paren))
+	    pos = &paren;
+    }
+    if (pos != NULL)
+    {
+	/* Extra trick: Take the indent of the first previous non-white
+	 * line that is at the same () level. */
+	amount = -1;
+	parencount = 0;
+
+	while (--curwin->w_cursor.lnum >= pos->lnum)
+	{
+	    if (linewhite(curwin->w_cursor.lnum))
+		continue;
+	    for (that = ml_get_curline(); *that != NUL; ++that)
+	    {
+		if (*that == ';')
+		{
+		    while (*(that + 1) != NUL)
+			++that;
+		    continue;
+		}
+		if (*that == '\\')
+		{
+		    if (*(that + 1) != NUL)
+			++that;
+		    continue;
+		}
+		if (*that == '"' && *(that + 1) != NUL)
+		{
+		    while (*++that && *that != '"')
+		    {
+			/* skipping escaped characters in the string */
+			if (*that == '\\')
+			{
+			    if (*++that == NUL)
+				break;
+			    if (that[1] == NUL)
+			    {
+				++that;
+				break;
+			    }
+			}
+		    }
+		}
+		if (*that == '(' || *that == '[')
+		    ++parencount;
+		else if (*that == ')' || *that == ']')
+		    --parencount;
+	    }
+	    if (parencount == 0)
+	    {
+		amount = get_indent();
+		break;
+	    }
+	}
+
+	if (amount == -1)
+	{
+	    curwin->w_cursor.lnum = pos->lnum;
+	    curwin->w_cursor.col = pos->col;
+	    col = pos->col;
+
+	    that = ml_get_curline();
+
+	    if (vi_lisp && get_indent() == 0)
+		amount = 2;
+	    else
+	    {
+		amount = 0;
+		while (*that && col)
+		{
+		    amount += lbr_chartabsize_adv(&that, (colnr_T)amount);
+		    col--;
+		}
+
+		/*
+		 * Some keywords require "body" indenting rules (the
+		 * non-standard-lisp ones are Scheme special forms):
+		 *
+		 * (let ((a 1))    instead    (let ((a 1))
+		 *   (...))	      of	   (...))
+		 */
+
+		if (!vi_lisp && (*that == '(' || *that == '[')
+						      && lisp_match(that + 1))
+		    amount += 2;
+		else
+		{
+		    that++;
+		    amount++;
+		    firsttry = amount;
+
+		    while (vim_iswhite(*that))
+		    {
+			amount += lbr_chartabsize(that, (colnr_T)amount);
+			++that;
+		    }
+
+		    if (*that && *that != ';') /* not a comment line */
+		    {
+			/* test *that != '(' to accomodate first let/do
+			 * argument if it is more than one line */
+			if (!vi_lisp && *that != '(' && *that != '[')
+			    firsttry++;
+
+			parencount = 0;
+			quotecount = 0;
+
+			if (vi_lisp
+				|| (*that != '"'
+				    && *that != '\''
+				    && *that != '#'
+				    && (*that < '0' || *that > '9')))
+			{
+			    while (*that
+				    && (!vim_iswhite(*that)
+					|| quotecount
+					|| parencount)
+				    && (!((*that == '(' || *that == '[')
+					    && !quotecount
+					    && !parencount
+					    && vi_lisp)))
+			    {
+				if (*that == '"')
+				    quotecount = !quotecount;
+				if ((*that == '(' || *that == '[')
+							       && !quotecount)
+				    ++parencount;
+				if ((*that == ')' || *that == ']')
+							       && !quotecount)
+				    --parencount;
+				if (*that == '\\' && *(that+1) != NUL)
+				    amount += lbr_chartabsize_adv(&that,
+							     (colnr_T)amount);
+				amount += lbr_chartabsize_adv(&that,
+							     (colnr_T)amount);
+			    }
+			}
+			while (vim_iswhite(*that))
+			{
+			    amount += lbr_chartabsize(that, (colnr_T)amount);
+			    that++;
+			}
+			if (!*that || *that == ';')
+			    amount = firsttry;
+		    }
+		}
+	    }
+	}
+    }
+    else
+	amount = 0;	/* no matching '(' or '[' found, use zero indent */
+
+    curwin->w_cursor = realpos;
+
+    return amount;
+}
+#endif /* FEAT_LISP */
+
+    void
+prepare_to_exit()
+{
+#if defined(SIGHUP) && defined(SIG_IGN)
+    /* Ignore SIGHUP, because a dropped connection causes a read error, which
+     * makes Vim exit and then handling SIGHUP causes various reentrance
+     * problems. */
+    signal(SIGHUP, SIG_IGN);
+#endif
+
+#ifdef FEAT_GUI
+    if (gui.in_use)
+    {
+	gui.dying = TRUE;
+	out_trash();	/* trash any pending output */
+    }
+    else
+#endif
+    {
+	windgoto((int)Rows - 1, 0);
+
+	/*
+	 * Switch terminal mode back now, so messages end up on the "normal"
+	 * screen (if there are two screens).
+	 */
+	settmode(TMODE_COOK);
+#ifdef WIN3264
+	if (can_end_termcap_mode(FALSE) == TRUE)
+#endif
+	    stoptermcap();
+	out_flush();
+    }
+}
+
+/*
+ * Preserve files and exit.
+ * When called IObuff must contain a message.
+ */
+    void
+preserve_exit()
+{
+    buf_T	*buf;
+
+    prepare_to_exit();
+
+    /* Setting this will prevent free() calls.  That avoids calling free()
+     * recursively when free() was invoked with a bad pointer. */
+    really_exiting = TRUE;
+
+    out_str(IObuff);
+    screen_start();		    /* don't know where cursor is now */
+    out_flush();
+
+    ml_close_notmod();		    /* close all not-modified buffers */
+
+    for (buf = firstbuf; buf != NULL; buf = buf->b_next)
+    {
+	if (buf->b_ml.ml_mfp != NULL && buf->b_ml.ml_mfp->mf_fname != NULL)
+	{
+	    OUT_STR(_("Vim: preserving files...\n"));
+	    screen_start();	    /* don't know where cursor is now */
+	    out_flush();
+	    ml_sync_all(FALSE, FALSE);	/* preserve all swap files */
+	    break;
+	}
+    }
+
+    ml_close_all(FALSE);	    /* close all memfiles, without deleting */
+
+    OUT_STR(_("Vim: Finished.\n"));
+
+    getout(1);
+}
+
+/*
+ * return TRUE if "fname" exists.
+ */
+    int
+vim_fexists(fname)
+    char_u  *fname;
+{
+    struct stat st;
+
+    if (mch_stat((char *)fname, &st))
+	return FALSE;
+    return TRUE;
+}
+
+/*
+ * Check for CTRL-C pressed, but only once in a while.
+ * Should be used instead of ui_breakcheck() for functions that check for
+ * each line in the file.  Calling ui_breakcheck() each time takes too much
+ * time, because it can be a system call.
+ */
+
+#ifndef BREAKCHECK_SKIP
+# ifdef FEAT_GUI		    /* assume the GUI only runs on fast computers */
+#  define BREAKCHECK_SKIP 200
+# else
+#  define BREAKCHECK_SKIP 32
+# endif
+#endif
+
+static int	breakcheck_count = 0;
+
+    void
+line_breakcheck()
+{
+    if (++breakcheck_count >= BREAKCHECK_SKIP)
+    {
+	breakcheck_count = 0;
+	ui_breakcheck();
+    }
+}
+
+/*
+ * Like line_breakcheck() but check 10 times less often.
+ */
+    void
+fast_breakcheck()
+{
+    if (++breakcheck_count >= BREAKCHECK_SKIP * 10)
+    {
+	breakcheck_count = 0;
+	ui_breakcheck();
+    }
+}
+
+/*
+ * Expand wildcards.  Calls gen_expand_wildcards() and removes files matching
+ * 'wildignore'.
+ * Returns OK or FAIL.
+ */
+    int
+expand_wildcards(num_pat, pat, num_file, file, flags)
+    int		   num_pat;	/* number of input patterns */
+    char_u	 **pat;		/* array of input patterns */
+    int		  *num_file;	/* resulting number of files */
+    char_u	***file;	/* array of resulting files */
+    int		   flags;	/* EW_DIR, etc. */
+{
+    int		retval;
+    int		i, j;
+    char_u	*p;
+    int		non_suf_match;	/* number without matching suffix */
+
+    retval = gen_expand_wildcards(num_pat, pat, num_file, file, flags);
+
+    /* When keeping all matches, return here */
+    if (flags & EW_KEEPALL)
+	return retval;
+
+#ifdef FEAT_WILDIGN
+    /*
+     * Remove names that match 'wildignore'.
+     */
+    if (*p_wig)
+    {
+	char_u	*ffname;
+
+	/* check all files in (*file)[] */
+	for (i = 0; i < *num_file; ++i)
+	{
+	    ffname = FullName_save((*file)[i], FALSE);
+	    if (ffname == NULL)		/* out of memory */
+		break;
+# ifdef VMS
+	    vms_remove_version(ffname);
+# endif
+	    if (match_file_list(p_wig, (*file)[i], ffname))
+	    {
+		/* remove this matching file from the list */
+		vim_free((*file)[i]);
+		for (j = i; j + 1 < *num_file; ++j)
+		    (*file)[j] = (*file)[j + 1];
+		--*num_file;
+		--i;
+	    }
+	    vim_free(ffname);
+	}
+    }
+#endif
+
+    /*
+     * Move the names where 'suffixes' match to the end.
+     */
+    if (*num_file > 1)
+    {
+	non_suf_match = 0;
+	for (i = 0; i < *num_file; ++i)
+	{
+	    if (!match_suffix((*file)[i]))
+	    {
+		/*
+		 * Move the name without matching suffix to the front
+		 * of the list.
+		 */
+		p = (*file)[i];
+		for (j = i; j > non_suf_match; --j)
+		    (*file)[j] = (*file)[j - 1];
+		(*file)[non_suf_match++] = p;
+	    }
+	}
+    }
+
+    return retval;
+}
+
+/*
+ * Return TRUE if "fname" matches with an entry in 'suffixes'.
+ */
+    int
+match_suffix(fname)
+    char_u	*fname;
+{
+    int		fnamelen, setsuflen;
+    char_u	*setsuf;
+#define MAXSUFLEN 30	    /* maximum length of a file suffix */
+    char_u	suf_buf[MAXSUFLEN];
+
+    fnamelen = (int)STRLEN(fname);
+    setsuflen = 0;
+    for (setsuf = p_su; *setsuf; )
+    {
+	setsuflen = copy_option_part(&setsuf, suf_buf, MAXSUFLEN, ".,");
+	if (fnamelen >= setsuflen
+		&& fnamencmp(suf_buf, fname + fnamelen - setsuflen,
+					      (size_t)setsuflen) == 0)
+	    break;
+	setsuflen = 0;
+    }
+    return (setsuflen != 0);
+}
+
+#if !defined(NO_EXPANDPATH) || defined(PROTO)
+
+# ifdef VIM_BACKTICK
+static int vim_backtick __ARGS((char_u *p));
+static int expand_backtick __ARGS((garray_T *gap, char_u *pat, int flags));
+# endif
+
+# if defined(MSDOS) || defined(FEAT_GUI_W16) || defined(WIN3264)
+/*
+ * File name expansion code for MS-DOS, Win16 and Win32.  It's here because
+ * it's shared between these systems.
+ */
+# if defined(DJGPP) || defined(PROTO)
+#  define _cdecl	    /* DJGPP doesn't have this */
+# else
+#  ifdef __BORLANDC__
+#   define _cdecl _RTLENTRYF
+#  endif
+# endif
+
+/*
+ * comparison function for qsort in dos_expandpath()
+ */
+    static int _cdecl
+pstrcmp(const void *a, const void *b)
+{
+    return (pathcmp(*(char **)a, *(char **)b, -1));
+}
+
+# ifndef WIN3264
+    static void
+namelowcpy(
+    char_u *d,
+    char_u *s)
+{
+#  ifdef DJGPP
+    if (USE_LONG_FNAME)	    /* don't lower case on Windows 95/NT systems */
+	while (*s)
+	    *d++ = *s++;
+    else
+#  endif
+	while (*s)
+	    *d++ = TOLOWER_LOC(*s++);
+    *d = NUL;
+}
+# endif
+
+/*
+ * Recursively expand one path component into all matching files and/or
+ * directories.  Adds matches to "gap".  Handles "*", "?", "[a-z]", "**", etc.
+ * Return the number of matches found.
+ * "path" has backslashes before chars that are not to be expanded, starting
+ * at "path[wildoff]".
+ * Return the number of matches found.
+ * NOTE: much of this is identical to unix_expandpath(), keep in sync!
+ */
+    static int
+dos_expandpath(
+    garray_T	*gap,
+    char_u	*path,
+    int		wildoff,
+    int		flags,		/* EW_* flags */
+    int		didstar)	/* expanded "**" once already */
+{
+    char_u	*buf;
+    char_u	*path_end;
+    char_u	*p, *s, *e;
+    int		start_len = gap->ga_len;
+    char_u	*pat;
+    regmatch_T	regmatch;
+    int		starts_with_dot;
+    int		matches;
+    int		len;
+    int		starstar = FALSE;
+    static int	stardepth = 0;	    /* depth for "**" expansion */
+#ifdef WIN3264
+    WIN32_FIND_DATA	fb;
+    HANDLE		hFind = (HANDLE)0;
+# ifdef FEAT_MBYTE
+    WIN32_FIND_DATAW    wfb;
+    WCHAR		*wn = NULL;	/* UCS-2 name, NULL when not used. */
+# endif
+#else
+    struct ffblk	fb;
+#endif
+    char_u		*matchname;
+    int			ok;
+
+    /* Expanding "**" may take a long time, check for CTRL-C. */
+    if (stardepth > 0)
+    {
+	ui_breakcheck();
+	if (got_int)
+	    return 0;
+    }
+
+    /* make room for file name */
+    buf = alloc((int)STRLEN(path) + BASENAMELEN + 5);
+    if (buf == NULL)
+	return 0;
+
+    /*
+     * Find the first part in the path name that contains a wildcard or a ~1.
+     * Copy it into buf, including the preceding characters.
+     */
+    p = buf;
+    s = buf;
+    e = NULL;
+    path_end = path;
+    while (*path_end != NUL)
+    {
+	/* May ignore a wildcard that has a backslash before it; it will
+	 * be removed by rem_backslash() or file_pat_to_reg_pat() below. */
+	if (path_end >= path + wildoff && rem_backslash(path_end))
+	    *p++ = *path_end++;
+	else if (*path_end == '\\' || *path_end == ':' || *path_end == '/')
+	{
+	    if (e != NULL)
+		break;
+	    s = p + 1;
+	}
+	else if (path_end >= path + wildoff
+			 && vim_strchr((char_u *)"*?[~", *path_end) != NULL)
+	    e = p;
+#ifdef FEAT_MBYTE
+	if (has_mbyte)
+	{
+	    len = (*mb_ptr2len)(path_end);
+	    STRNCPY(p, path_end, len);
+	    p += len;
+	    path_end += len;
+	}
+	else
+#endif
+	    *p++ = *path_end++;
+    }
+    e = p;
+    *e = NUL;
+
+    /* now we have one wildcard component between s and e */
+    /* Remove backslashes between "wildoff" and the start of the wildcard
+     * component. */
+    for (p = buf + wildoff; p < s; ++p)
+	if (rem_backslash(p))
+	{
+	    STRCPY(p, p + 1);
+	    --e;
+	    --s;
+	}
+
+    /* Check for "**" between "s" and "e". */
+    for (p = s; p < e; ++p)
+	if (p[0] == '*' && p[1] == '*')
+	    starstar = TRUE;
+
+    starts_with_dot = (*s == '.');
+    pat = file_pat_to_reg_pat(s, e, NULL, FALSE);
+    if (pat == NULL)
+    {
+	vim_free(buf);
+	return 0;
+    }
+
+    /* compile the regexp into a program */
+    regmatch.rm_ic = TRUE;		/* Always ignore case */
+    regmatch.regprog = vim_regcomp(pat, RE_MAGIC);
+    vim_free(pat);
+
+    if (regmatch.regprog == NULL)
+    {
+	vim_free(buf);
+	return 0;
+    }
+
+    /* remember the pattern or file name being looked for */
+    matchname = vim_strsave(s);
+
+    /* If "**" is by itself, this is the first time we encounter it and more
+     * is following then find matches without any directory. */
+    if (!didstar && stardepth < 100 && starstar && e - s == 2
+							  && *path_end == '/')
+    {
+	STRCPY(s, path_end + 1);
+	++stardepth;
+	(void)dos_expandpath(gap, buf, (int)(s - buf), flags, TRUE);
+	--stardepth;
+    }
+
+    /* Scan all files in the directory with "dir/ *.*" */
+    STRCPY(s, "*.*");
+#ifdef WIN3264
+# ifdef FEAT_MBYTE
+    if (enc_codepage >= 0 && (int)GetACP() != enc_codepage)
+    {
+	/* The active codepage differs from 'encoding'.  Attempt using the
+	 * wide function.  If it fails because it is not implemented fall back
+	 * to the non-wide version (for Windows 98) */
+	wn = enc_to_ucs2(buf, NULL);
+	if (wn != NULL)
+	{
+	    hFind = FindFirstFileW(wn, &wfb);
+	    if (hFind == INVALID_HANDLE_VALUE
+			      && GetLastError() == ERROR_CALL_NOT_IMPLEMENTED)
+	    {
+		vim_free(wn);
+		wn = NULL;
+	    }
+	}
+    }
+
+    if (wn == NULL)
+# endif
+	hFind = FindFirstFile(buf, &fb);
+    ok = (hFind != INVALID_HANDLE_VALUE);
+#else
+    /* If we are expanding wildcards we try both files and directories */
+    ok = (findfirst((char *)buf, &fb,
+		(*path_end != NUL || (flags & EW_DIR)) ? FA_DIREC : 0) == 0);
+#endif
+
+    while (ok)
+    {
+#ifdef WIN3264
+# ifdef FEAT_MBYTE
+	if (wn != NULL)
+	    p = ucs2_to_enc(wfb.cFileName, NULL);   /* p is allocated here */
+	else
+# endif
+	    p = (char_u *)fb.cFileName;
+#else
+	p = (char_u *)fb.ff_name;
+#endif
+	/* Ignore entries starting with a dot, unless when asked for.  Accept
+	 * all entries found with "matchname". */
+	if ((p[0] != '.' || starts_with_dot)
+		&& (matchname == NULL
+		    || vim_regexec(&regmatch, p, (colnr_T)0)))
+	{
+#ifdef WIN3264
+	    STRCPY(s, p);
+#else
+	    namelowcpy(s, p);
+#endif
+	    len = (int)STRLEN(buf);
+
+	    if (starstar && stardepth < 100)
+	    {
+		/* For "**" in the pattern first go deeper in the tree to
+		 * find matches. */
+		STRCPY(buf + len, "/**");
+		STRCPY(buf + len + 3, path_end);
+		++stardepth;
+		(void)dos_expandpath(gap, buf, len + 1, flags, TRUE);
+		--stardepth;
+	    }
+
+	    STRCPY(buf + len, path_end);
+	    if (mch_has_exp_wildcard(path_end))
+	    {
+		/* need to expand another component of the path */
+		/* remove backslashes for the remaining components only */
+		(void)dos_expandpath(gap, buf, len + 1, flags, FALSE);
+	    }
+	    else
+	    {
+		/* no more wildcards, check if there is a match */
+		/* remove backslashes for the remaining components only */
+		if (*path_end != 0)
+		    backslash_halve(buf + len + 1);
+		if (mch_getperm(buf) >= 0)	/* add existing file */
+		    addfile(gap, buf, flags);
+	    }
+	}
+
+#ifdef WIN3264
+# ifdef FEAT_MBYTE
+	if (wn != NULL)
+	{
+	    vim_free(p);
+	    ok = FindNextFileW(hFind, &wfb);
+	}
+	else
+# endif
+	    ok = FindNextFile(hFind, &fb);
+#else
+	ok = (findnext(&fb) == 0);
+#endif
+
+	/* If no more matches and no match was used, try expanding the name
+	 * itself.  Finds the long name of a short filename. */
+	if (!ok && matchname != NULL && gap->ga_len == start_len)
+	{
+	    STRCPY(s, matchname);
+#ifdef WIN3264
+	    FindClose(hFind);
+# ifdef FEAT_MBYTE
+	    if (wn != NULL)
+	    {
+		vim_free(wn);
+		wn = enc_to_ucs2(buf, NULL);
+		if (wn != NULL)
+		    hFind = FindFirstFileW(wn, &wfb);
+	    }
+	    if (wn == NULL)
+# endif
+		hFind = FindFirstFile(buf, &fb);
+	    ok = (hFind != INVALID_HANDLE_VALUE);
+#else
+	    ok = (findfirst((char *)buf, &fb,
+		 (*path_end != NUL || (flags & EW_DIR)) ? FA_DIREC : 0) == 0);
+#endif
+	    vim_free(matchname);
+	    matchname = NULL;
+	}
+    }
+
+#ifdef WIN3264
+    FindClose(hFind);
+# ifdef FEAT_MBYTE
+    vim_free(wn);
+# endif
+#endif
+    vim_free(buf);
+    vim_free(regmatch.regprog);
+    vim_free(matchname);
+
+    matches = gap->ga_len - start_len;
+    if (matches > 0)
+	qsort(((char_u **)gap->ga_data) + start_len, (size_t)matches,
+						   sizeof(char_u *), pstrcmp);
+    return matches;
+}
+
+    int
+mch_expandpath(
+    garray_T	*gap,
+    char_u	*path,
+    int		flags)		/* EW_* flags */
+{
+    return dos_expandpath(gap, path, 0, flags, FALSE);
+}
+# endif /* MSDOS || FEAT_GUI_W16 || WIN3264 */
+
+#if (defined(UNIX) && !defined(VMS)) || defined(USE_UNIXFILENAME) \
+	|| defined(PROTO)
+/*
+ * Unix style wildcard expansion code.
+ * It's here because it's used both for Unix and Mac.
+ */
+static int	pstrcmp __ARGS((const void *, const void *));
+
+    static int
+pstrcmp(a, b)
+    const void *a, *b;
+{
+    return (pathcmp(*(char **)a, *(char **)b, -1));
+}
+
+/*
+ * Recursively expand one path component into all matching files and/or
+ * directories.  Adds matches to "gap".  Handles "*", "?", "[a-z]", "**", etc.
+ * "path" has backslashes before chars that are not to be expanded, starting
+ * at "path + wildoff".
+ * Return the number of matches found.
+ * NOTE: much of this is identical to dos_expandpath(), keep in sync!
+ */
+    int
+unix_expandpath(gap, path, wildoff, flags, didstar)
+    garray_T	*gap;
+    char_u	*path;
+    int		wildoff;
+    int		flags;		/* EW_* flags */
+    int		didstar;	/* expanded "**" once already */
+{
+    char_u	*buf;
+    char_u	*path_end;
+    char_u	*p, *s, *e;
+    int		start_len = gap->ga_len;
+    char_u	*pat;
+    regmatch_T	regmatch;
+    int		starts_with_dot;
+    int		matches;
+    int		len;
+    int		starstar = FALSE;
+    static int	stardepth = 0;	    /* depth for "**" expansion */
+
+    DIR		*dirp;
+    struct dirent *dp;
+
+    /* Expanding "**" may take a long time, check for CTRL-C. */
+    if (stardepth > 0)
+    {
+	ui_breakcheck();
+	if (got_int)
+	    return 0;
+    }
+
+    /* make room for file name */
+    buf = alloc((int)STRLEN(path) + BASENAMELEN + 5);
+    if (buf == NULL)
+	return 0;
+
+    /*
+     * Find the first part in the path name that contains a wildcard.
+     * Copy it into "buf", including the preceding characters.
+     */
+    p = buf;
+    s = buf;
+    e = NULL;
+    path_end = path;
+    while (*path_end != NUL)
+    {
+	/* May ignore a wildcard that has a backslash before it; it will
+	 * be removed by rem_backslash() or file_pat_to_reg_pat() below. */
+	if (path_end >= path + wildoff && rem_backslash(path_end))
+	    *p++ = *path_end++;
+	else if (*path_end == '/')
+	{
+	    if (e != NULL)
+		break;
+	    s = p + 1;
+	}
+	else if (path_end >= path + wildoff
+			 && vim_strchr((char_u *)"*?[{~$", *path_end) != NULL)
+	    e = p;
+#ifdef FEAT_MBYTE
+	if (has_mbyte)
+	{
+	    len = (*mb_ptr2len)(path_end);
+	    STRNCPY(p, path_end, len);
+	    p += len;
+	    path_end += len;
+	}
+	else
+#endif
+	    *p++ = *path_end++;
+    }
+    e = p;
+    *e = NUL;
+
+    /* now we have one wildcard component between "s" and "e" */
+    /* Remove backslashes between "wildoff" and the start of the wildcard
+     * component. */
+    for (p = buf + wildoff; p < s; ++p)
+	if (rem_backslash(p))
+	{
+	    STRCPY(p, p + 1);
+	    --e;
+	    --s;
+	}
+
+    /* Check for "**" between "s" and "e". */
+    for (p = s; p < e; ++p)
+	if (p[0] == '*' && p[1] == '*')
+	    starstar = TRUE;
+
+    /* convert the file pattern to a regexp pattern */
+    starts_with_dot = (*s == '.');
+    pat = file_pat_to_reg_pat(s, e, NULL, FALSE);
+    if (pat == NULL)
+    {
+	vim_free(buf);
+	return 0;
+    }
+
+    /* compile the regexp into a program */
+#ifdef CASE_INSENSITIVE_FILENAME
+    regmatch.rm_ic = TRUE;		/* Behave like Terminal.app */
+#else
+    regmatch.rm_ic = FALSE;		/* Don't ever ignore case */
+#endif
+    regmatch.regprog = vim_regcomp(pat, RE_MAGIC);
+    vim_free(pat);
+
+    if (regmatch.regprog == NULL)
+    {
+	vim_free(buf);
+	return 0;
+    }
+
+    /* If "**" is by itself, this is the first time we encounter it and more
+     * is following then find matches without any directory. */
+    if (!didstar && stardepth < 100 && starstar && e - s == 2
+							  && *path_end == '/')
+    {
+	STRCPY(s, path_end + 1);
+	++stardepth;
+	(void)unix_expandpath(gap, buf, (int)(s - buf), flags, TRUE);
+	--stardepth;
+    }
+
+    /* open the directory for scanning */
+    *s = NUL;
+    dirp = opendir(*buf == NUL ? "." : (char *)buf);
+
+    /* Find all matching entries */
+    if (dirp != NULL)
+    {
+	for (;;)
+	{
+	    dp = readdir(dirp);
+	    if (dp == NULL)
+		break;
+	    if ((dp->d_name[0] != '.' || starts_with_dot)
+		    && vim_regexec(&regmatch, (char_u *)dp->d_name, (colnr_T)0))
+	    {
+		STRCPY(s, dp->d_name);
+		len = STRLEN(buf);
+
+		if (starstar && stardepth < 100)
+		{
+		    /* For "**" in the pattern first go deeper in the tree to
+		     * find matches. */
+		    STRCPY(buf + len, "/**");
+		    STRCPY(buf + len + 3, path_end);
+		    ++stardepth;
+		    (void)unix_expandpath(gap, buf, len + 1, flags, TRUE);
+		    --stardepth;
+		}
+
+		STRCPY(buf + len, path_end);
+		if (mch_has_exp_wildcard(path_end)) /* handle more wildcards */
+		{
+		    /* need to expand another component of the path */
+		    /* remove backslashes for the remaining components only */
+		    (void)unix_expandpath(gap, buf, len + 1, flags, FALSE);
+		}
+		else
+		{
+		    /* no more wildcards, check if there is a match */
+		    /* remove backslashes for the remaining components only */
+		    if (*path_end != NUL)
+			backslash_halve(buf + len + 1);
+		    if (mch_getperm(buf) >= 0)	/* add existing file */
+		    {
+#ifdef MACOS_CONVERT
+			size_t precomp_len = STRLEN(buf)+1;
+			char_u *precomp_buf =
+			    mac_precompose_path(buf, precomp_len, &precomp_len);
+
+			if (precomp_buf)
+			{
+			    mch_memmove(buf, precomp_buf, precomp_len);
+			    vim_free(precomp_buf);
+			}
+#endif
+			addfile(gap, buf, flags);
+		    }
+		}
+	    }
+	}
+
+	closedir(dirp);
+    }
+
+    vim_free(buf);
+    vim_free(regmatch.regprog);
+
+    matches = gap->ga_len - start_len;
+    if (matches > 0)
+	qsort(((char_u **)gap->ga_data) + start_len, matches,
+						   sizeof(char_u *), pstrcmp);
+    return matches;
+}
+#endif
+
+/*
+ * Generic wildcard expansion code.
+ *
+ * Characters in "pat" that should not be expanded must be preceded with a
+ * backslash. E.g., "/path\ with\ spaces/my\*star*"
+ *
+ * Return FAIL when no single file was found.  In this case "num_file" is not
+ * set, and "file" may contain an error message.
+ * Return OK when some files found.  "num_file" is set to the number of
+ * matches, "file" to the array of matches.  Call FreeWild() later.
+ */
+    int
+gen_expand_wildcards(num_pat, pat, num_file, file, flags)
+    int		num_pat;	/* number of input patterns */
+    char_u	**pat;		/* array of input patterns */
+    int		*num_file;	/* resulting number of files */
+    char_u	***file;	/* array of resulting files */
+    int		flags;		/* EW_* flags */
+{
+    int			i;
+    garray_T		ga;
+    char_u		*p;
+    static int		recursive = FALSE;
+    int			add_pat;
+
+    /*
+     * expand_env() is called to expand things like "~user".  If this fails,
+     * it calls ExpandOne(), which brings us back here.  In this case, always
+     * call the machine specific expansion function, if possible.  Otherwise,
+     * return FAIL.
+     */
+    if (recursive)
+#ifdef SPECIAL_WILDCHAR
+	return mch_expand_wildcards(num_pat, pat, num_file, file, flags);
+#else
+	return FAIL;
+#endif
+
+#ifdef SPECIAL_WILDCHAR
+    /*
+     * If there are any special wildcard characters which we cannot handle
+     * here, call machine specific function for all the expansion.  This
+     * avoids starting the shell for each argument separately.
+     * For `=expr` do use the internal function.
+     */
+    for (i = 0; i < num_pat; i++)
+    {
+	if (vim_strpbrk(pat[i], (char_u *)SPECIAL_WILDCHAR) != NULL
+# ifdef VIM_BACKTICK
+		&& !(vim_backtick(pat[i]) && pat[i][1] == '=')
+# endif
+	   )
+	    return mch_expand_wildcards(num_pat, pat, num_file, file, flags);
+    }
+#endif
+
+    recursive = TRUE;
+
+    /*
+     * The matching file names are stored in a growarray.  Init it empty.
+     */
+    ga_init2(&ga, (int)sizeof(char_u *), 30);
+
+    for (i = 0; i < num_pat; ++i)
+    {
+	add_pat = -1;
+	p = pat[i];
+
+#ifdef VIM_BACKTICK
+	if (vim_backtick(p))
+	    add_pat = expand_backtick(&ga, p, flags);
+	else
+#endif
+	{
+	    /*
+	     * First expand environment variables, "~/" and "~user/".
+	     */
+	    if (vim_strpbrk(p, (char_u *)"$~") != NULL)
+	    {
+		p = expand_env_save(p);
+		if (p == NULL)
+		    p = pat[i];
+#ifdef UNIX
+		/*
+		 * On Unix, if expand_env() can't expand an environment
+		 * variable, use the shell to do that.  Discard previously
+		 * found file names and start all over again.
+		 */
+		else if (vim_strpbrk(p, (char_u *)"$~") != NULL)
+		{
+		    vim_free(p);
+		    ga_clear(&ga);
+		    i = mch_expand_wildcards(num_pat, pat, num_file, file,
+								       flags);
+		    recursive = FALSE;
+		    return i;
+		}
+#endif
+	    }
+
+	    /*
+	     * If there are wildcards: Expand file names and add each match to
+	     * the list.  If there is no match, and EW_NOTFOUND is given, add
+	     * the pattern.
+	     * If there are no wildcards: Add the file name if it exists or
+	     * when EW_NOTFOUND is given.
+	     */
+	    if (mch_has_exp_wildcard(p))
+		add_pat = mch_expandpath(&ga, p, flags);
+	}
+
+	if (add_pat == -1 || (add_pat == 0 && (flags & EW_NOTFOUND)))
+	{
+	    char_u	*t = backslash_halve_save(p);
+
+#if defined(MACOS_CLASSIC)
+	    slash_to_colon(t);
+#endif
+	    /* When EW_NOTFOUND is used, always add files and dirs.  Makes
+	     * "vim c:/" work. */
+	    if (flags & EW_NOTFOUND)
+		addfile(&ga, t, flags | EW_DIR | EW_FILE);
+	    else if (mch_getperm(t) >= 0)
+		addfile(&ga, t, flags);
+	    vim_free(t);
+	}
+
+	if (p != pat[i])
+	    vim_free(p);
+    }
+
+    *num_file = ga.ga_len;
+    *file = (ga.ga_data != NULL) ? (char_u **)ga.ga_data : (char_u **)"";
+
+    recursive = FALSE;
+
+    return (ga.ga_data != NULL) ? OK : FAIL;
+}
+
+# ifdef VIM_BACKTICK
+
+/*
+ * Return TRUE if we can expand this backtick thing here.
+ */
+    static int
+vim_backtick(p)
+    char_u	*p;
+{
+    return (*p == '`' && *(p + 1) != NUL && *(p + STRLEN(p) - 1) == '`');
+}
+
+/*
+ * Expand an item in `backticks` by executing it as a command.
+ * Currently only works when pat[] starts and ends with a `.
+ * Returns number of file names found.
+ */
+    static int
+expand_backtick(gap, pat, flags)
+    garray_T	*gap;
+    char_u	*pat;
+    int		flags;	/* EW_* flags */
+{
+    char_u	*p;
+    char_u	*cmd;
+    char_u	*buffer;
+    int		cnt = 0;
+    int		i;
+
+    /* Create the command: lop off the backticks. */
+    cmd = vim_strnsave(pat + 1, (int)STRLEN(pat) - 2);
+    if (cmd == NULL)
+	return 0;
+
+#ifdef FEAT_EVAL
+    if (*cmd == '=')	    /* `={expr}`: Expand expression */
+	buffer = eval_to_string(cmd + 1, &p, TRUE);
+    else
+#endif
+	buffer = get_cmd_output(cmd, NULL,
+				      (flags & EW_SILENT) ? SHELL_SILENT : 0);
+    vim_free(cmd);
+    if (buffer == NULL)
+	return 0;
+
+    cmd = buffer;
+    while (*cmd != NUL)
+    {
+	cmd = skipwhite(cmd);		/* skip over white space */
+	p = cmd;
+	while (*p != NUL && *p != '\r' && *p != '\n') /* skip over entry */
+	    ++p;
+	/* add an entry if it is not empty */
+	if (p > cmd)
+	{
+	    i = *p;
+	    *p = NUL;
+	    addfile(gap, cmd, flags);
+	    *p = i;
+	    ++cnt;
+	}
+	cmd = p;
+	while (*cmd != NUL && (*cmd == '\r' || *cmd == '\n'))
+	    ++cmd;
+    }
+
+    vim_free(buffer);
+    return cnt;
+}
+# endif /* VIM_BACKTICK */
+
+/*
+ * Add a file to a file list.  Accepted flags:
+ * EW_DIR	add directories
+ * EW_FILE	add files
+ * EW_EXEC	add executable files
+ * EW_NOTFOUND	add even when it doesn't exist
+ * EW_ADDSLASH	add slash after directory name
+ */
+    void
+addfile(gap, f, flags)
+    garray_T	*gap;
+    char_u	*f;	/* filename */
+    int		flags;
+{
+    char_u	*p;
+    int		isdir;
+
+    /* if the file/dir doesn't exist, may not add it */
+    if (!(flags & EW_NOTFOUND) && mch_getperm(f) < 0)
+	return;
+
+#ifdef FNAME_ILLEGAL
+    /* if the file/dir contains illegal characters, don't add it */
+    if (vim_strpbrk(f, (char_u *)FNAME_ILLEGAL) != NULL)
+	return;
+#endif
+
+    isdir = mch_isdir(f);
+    if ((isdir && !(flags & EW_DIR)) || (!isdir && !(flags & EW_FILE)))
+	return;
+
+    /* If the file isn't executable, may not add it.  Do accept directories. */
+    if (!isdir && (flags & EW_EXEC) && !mch_can_exe(f))
+	return;
+
+    /* Make room for another item in the file list. */
+    if (ga_grow(gap, 1) == FAIL)
+	return;
+
+    p = alloc((unsigned)(STRLEN(f) + 1 + isdir));
+    if (p == NULL)
+	return;
+
+    STRCPY(p, f);
+#ifdef BACKSLASH_IN_FILENAME
+    slash_adjust(p);
+#endif
+    /*
+     * Append a slash or backslash after directory names if none is present.
+     */
+#ifndef DONT_ADD_PATHSEP_TO_DIR
+    if (isdir && (flags & EW_ADDSLASH))
+	add_pathsep(p);
+#endif
+    ((char_u **)gap->ga_data)[gap->ga_len++] = p;
+}
+#endif /* !NO_EXPANDPATH */
+
+#if defined(VIM_BACKTICK) || defined(FEAT_EVAL) || defined(PROTO)
+
+#ifndef SEEK_SET
+# define SEEK_SET 0
+#endif
+#ifndef SEEK_END
+# define SEEK_END 2
+#endif
+
+/*
+ * Get the stdout of an external command.
+ * Returns an allocated string, or NULL for error.
+ */
+    char_u *
+get_cmd_output(cmd, infile, flags)
+    char_u	*cmd;
+    char_u	*infile;	/* optional input file name */
+    int		flags;		/* can be SHELL_SILENT */
+{
+    char_u	*tempname;
+    char_u	*command;
+    char_u	*buffer = NULL;
+    int		len;
+    int		i = 0;
+    FILE	*fd;
+
+    if (check_restricted() || check_secure())
+	return NULL;
+
+    /* get a name for the temp file */
+    if ((tempname = vim_tempname('o')) == NULL)
+    {
+	EMSG(_(e_notmp));
+	return NULL;
+    }
+
+    /* Add the redirection stuff */
+    command = make_filter_cmd(cmd, infile, tempname);
+    if (command == NULL)
+	goto done;
+
+    /*
+     * Call the shell to execute the command (errors are ignored).
+     * Don't check timestamps here.
+     */
+    ++no_check_timestamps;
+    call_shell(command, SHELL_DOOUT | SHELL_EXPAND | flags);
+    --no_check_timestamps;
+
+    vim_free(command);
+
+    /*
+     * read the names from the file into memory
+     */
+# ifdef VMS
+    /* created temporary file is not always readable as binary */
+    fd = mch_fopen((char *)tempname, "r");
+# else
+    fd = mch_fopen((char *)tempname, READBIN);
+# endif
+
+    if (fd == NULL)
+    {
+	EMSG2(_(e_notopen), tempname);
+	goto done;
+    }
+
+    fseek(fd, 0L, SEEK_END);
+    len = ftell(fd);		    /* get size of temp file */
+    fseek(fd, 0L, SEEK_SET);
+
+    buffer = alloc(len + 1);
+    if (buffer != NULL)
+	i = (int)fread((char *)buffer, (size_t)1, (size_t)len, fd);
+    fclose(fd);
+    mch_remove(tempname);
+    if (buffer == NULL)
+	goto done;
+#ifdef VMS
+    len = i;	/* VMS doesn't give us what we asked for... */
+#endif
+    if (i != len)
+    {
+	EMSG2(_(e_notread), tempname);
+	vim_free(buffer);
+	buffer = NULL;
+    }
+    else
+	buffer[len] = '\0';	/* make sure the buffer is terminated */
+
+done:
+    vim_free(tempname);
+    return buffer;
+}
+#endif
+
+/*
+ * Free the list of files returned by expand_wildcards() or other expansion
+ * functions.
+ */
+    void
+FreeWild(count, files)
+    int	    count;
+    char_u  **files;
+{
+    if (count <= 0 || files == NULL)
+	return;
+#if defined(__EMX__) && defined(__ALWAYS_HAS_TRAILING_NULL_POINTER) /* XXX */
+    /*
+     * Is this still OK for when other functions than expand_wildcards() have
+     * been used???
+     */
+    _fnexplodefree((char **)files);
+#else
+    while (count--)
+	vim_free(files[count]);
+    vim_free(files);
+#endif
+}
+
+/*
+ * return TRUE when need to go to Insert mode because of 'insertmode'.
+ * Don't do this when still processing a command or a mapping.
+ * Don't do this when inside a ":normal" command.
+ */
+    int
+goto_im()
+{
+    return (p_im && stuff_empty() && typebuf_typed());
+}
--- /dev/null
+++ b/misc2.c
@@ -1,0 +1,5942 @@
+/* vi:set ts=8 sts=4 sw=4:
+ *
+ * VIM - Vi IMproved	by Bram Moolenaar
+ *
+ * Do ":help uganda"  in Vim to read copying and usage conditions.
+ * Do ":help credits" in Vim to see a list of people who contributed.
+ * See README.txt for an overview of the Vim source code.
+ */
+
+/*
+ * misc2.c: Various functions.
+ */
+#include "vim.h"
+
+#ifdef HAVE_FCNTL_H
+# include <fcntl.h>	    /* for chdir() */
+#endif
+
+static char_u	*username = NULL; /* cached result of mch_get_user_name() */
+
+static char_u	*ff_expand_buffer = NULL; /* used for expanding filenames */
+
+#if defined(FEAT_VIRTUALEDIT) || defined(PROTO)
+static int coladvance2 __ARGS((pos_T *pos, int addspaces, int finetune, colnr_T wcol));
+
+/*
+ * Return TRUE if in the current mode we need to use virtual.
+ */
+    int
+virtual_active()
+{
+    /* While an operator is being executed we return "virtual_op", because
+     * VIsual_active has already been reset, thus we can't check for "block"
+     * being used. */
+    if (virtual_op != MAYBE)
+	return virtual_op;
+    return (ve_flags == VE_ALL
+# ifdef FEAT_VISUAL
+	    || ((ve_flags & VE_BLOCK) && VIsual_active && VIsual_mode == Ctrl_V)
+# endif
+	    || ((ve_flags & VE_INSERT) && (State & INSERT)));
+}
+
+/*
+ * Get the screen position of the cursor.
+ */
+    int
+getviscol()
+{
+    colnr_T	x;
+
+    getvvcol(curwin, &curwin->w_cursor, &x, NULL, NULL);
+    return (int)x;
+}
+
+/*
+ * Get the screen position of character col with a coladd in the cursor line.
+ */
+    int
+getviscol2(col, coladd)
+    colnr_T	col;
+    colnr_T	coladd;
+{
+    colnr_T	x;
+    pos_T	pos;
+
+    pos.lnum = curwin->w_cursor.lnum;
+    pos.col = col;
+    pos.coladd = coladd;
+    getvvcol(curwin, &pos, &x, NULL, NULL);
+    return (int)x;
+}
+
+/*
+ * Go to column "wcol", and add/insert white space as necessary to get the
+ * cursor in that column.
+ * The caller must have saved the cursor line for undo!
+ */
+    int
+coladvance_force(wcol)
+    colnr_T wcol;
+{
+    int rc = coladvance2(&curwin->w_cursor, TRUE, FALSE, wcol);
+
+    if (wcol == MAXCOL)
+	curwin->w_valid &= ~VALID_VIRTCOL;
+    else
+    {
+	/* Virtcol is valid */
+	curwin->w_valid |= VALID_VIRTCOL;
+	curwin->w_virtcol = wcol;
+    }
+    return rc;
+}
+#endif
+
+/*
+ * Try to advance the Cursor to the specified screen column.
+ * If virtual editing: fine tune the cursor position.
+ * Note that all virtual positions off the end of a line should share
+ * a curwin->w_cursor.col value (n.b. this is equal to STRLEN(line)),
+ * beginning at coladd 0.
+ *
+ * return OK if desired column is reached, FAIL if not
+ */
+    int
+coladvance(wcol)
+    colnr_T	wcol;
+{
+    int rc = getvpos(&curwin->w_cursor, wcol);
+
+    if (wcol == MAXCOL || rc == FAIL)
+	curwin->w_valid &= ~VALID_VIRTCOL;
+    else if (*ml_get_cursor() != TAB)
+    {
+	/* Virtcol is valid when not on a TAB */
+	curwin->w_valid |= VALID_VIRTCOL;
+	curwin->w_virtcol = wcol;
+    }
+    return rc;
+}
+
+/*
+ * Return in "pos" the position of the cursor advanced to screen column "wcol".
+ * return OK if desired column is reached, FAIL if not
+ */
+    int
+getvpos(pos, wcol)
+    pos_T   *pos;
+    colnr_T wcol;
+{
+#ifdef FEAT_VIRTUALEDIT
+    return coladvance2(pos, FALSE, virtual_active(), wcol);
+}
+
+    static int
+coladvance2(pos, addspaces, finetune, wcol)
+    pos_T	*pos;
+    int		addspaces;	/* change the text to achieve our goal? */
+    int		finetune;	/* change char offset for the exact column */
+    colnr_T	wcol;		/* column to move to */
+{
+#endif
+    int		idx;
+    char_u	*ptr;
+    char_u	*line;
+    colnr_T	col = 0;
+    int		csize = 0;
+    int		one_more;
+#ifdef FEAT_LINEBREAK
+    int		head = 0;
+#endif
+
+    one_more = (State & INSERT)
+		    || restart_edit != NUL
+#ifdef FEAT_VISUAL
+		    || (VIsual_active && *p_sel != 'o')
+#endif
+#ifdef FEAT_VIRTUALEDIT
+		    || ((ve_flags & VE_ONEMORE) && wcol < MAXCOL)
+#endif
+		    ;
+    line = ml_get_curline();
+
+    if (wcol >= MAXCOL)
+    {
+	    idx = (int)STRLEN(line) - 1 + one_more;
+	    col = wcol;
+
+#ifdef FEAT_VIRTUALEDIT
+	    if ((addspaces || finetune) && !VIsual_active)
+	    {
+		curwin->w_curswant = linetabsize(line) + one_more;
+		if (curwin->w_curswant > 0)
+		    --curwin->w_curswant;
+	    }
+#endif
+    }
+    else
+    {
+#ifdef FEAT_VIRTUALEDIT
+	int width = W_WIDTH(curwin) - win_col_off(curwin);
+
+	if (finetune
+		&& curwin->w_p_wrap
+# ifdef FEAT_VERTSPLIT
+		&& curwin->w_width != 0
+# endif
+		&& wcol >= (colnr_T)width)
+	{
+	    csize = linetabsize(line);
+	    if (csize > 0)
+		csize--;
+
+	    if (wcol / width > (colnr_T)csize / width
+		    && ((State & INSERT) == 0 || (int)wcol > csize + 1))
+	    {
+		/* In case of line wrapping don't move the cursor beyond the
+		 * right screen edge.  In Insert mode allow going just beyond
+		 * the last character (like what happens when typing and
+		 * reaching the right window edge). */
+		wcol = (csize / width + 1) * width - 1;
+	    }
+	}
+#endif
+
+	idx = -1;
+	ptr = line;
+	while (col <= wcol && *ptr != NUL)
+	{
+	    /* Count a tab for what it's worth (if list mode not on) */
+#ifdef FEAT_LINEBREAK
+	    csize = win_lbr_chartabsize(curwin, ptr, col, &head);
+	    mb_ptr_adv(ptr);
+#else
+	    csize = lbr_chartabsize_adv(&ptr, col);
+#endif
+	    col += csize;
+	}
+	idx = (int)(ptr - line);
+	/*
+	 * Handle all the special cases.  The virtual_active() check
+	 * is needed to ensure that a virtual position off the end of
+	 * a line has the correct indexing.  The one_more comparison
+	 * replaces an explicit add of one_more later on.
+	 */
+	if (col > wcol || (!virtual_active() && one_more == 0))
+	{
+	    idx -= 1;
+# ifdef FEAT_LINEBREAK
+	    /* Don't count the chars from 'showbreak'. */
+	    csize -= head;
+# endif
+	    col -= csize;
+	}
+
+#ifdef FEAT_VIRTUALEDIT
+	if (virtual_active()
+		&& addspaces
+		&& ((col != wcol && col != wcol + 1) || csize > 1))
+	{
+	    /* 'virtualedit' is set: The difference between wcol and col is
+	     * filled with spaces. */
+
+	    if (line[idx] == NUL)
+	    {
+		/* Append spaces */
+		int	correct = wcol - col;
+		char_u	*newline = alloc(idx + correct + 1);
+		int	t;
+
+		if (newline == NULL)
+		    return FAIL;
+
+		for (t = 0; t < idx; ++t)
+		    newline[t] = line[t];
+
+		for (t = 0; t < correct; ++t)
+		    newline[t + idx] = ' ';
+
+		newline[idx + correct] = NUL;
+
+		ml_replace(pos->lnum, newline, FALSE);
+		changed_bytes(pos->lnum, (colnr_T)idx);
+		idx += correct;
+		col = wcol;
+	    }
+	    else
+	    {
+		/* Break a tab */
+		int	linelen = (int)STRLEN(line);
+		int	correct = wcol - col - csize + 1; /* negative!! */
+		char_u	*newline;
+		int	t, s = 0;
+		int	v;
+
+		if (-correct > csize)
+		    return FAIL;
+
+		newline = alloc(linelen + csize);
+		if (newline == NULL)
+		    return FAIL;
+
+		for (t = 0; t < linelen; t++)
+		{
+		    if (t != idx)
+			newline[s++] = line[t];
+		    else
+			for (v = 0; v < csize; v++)
+			    newline[s++] = ' ';
+		}
+
+		newline[linelen + csize - 1] = NUL;
+
+		ml_replace(pos->lnum, newline, FALSE);
+		changed_bytes(pos->lnum, idx);
+		idx += (csize - 1 + correct);
+		col += correct;
+	    }
+	}
+#endif
+    }
+
+    if (idx < 0)
+	pos->col = 0;
+    else
+	pos->col = idx;
+
+#ifdef FEAT_VIRTUALEDIT
+    pos->coladd = 0;
+
+    if (finetune)
+    {
+	if (wcol == MAXCOL)
+	{
+	    /* The width of the last character is used to set coladd. */
+	    if (!one_more)
+	    {
+		colnr_T	    scol, ecol;
+
+		getvcol(curwin, pos, &scol, NULL, &ecol);
+		pos->coladd = ecol - scol;
+	    }
+	}
+	else
+	{
+	    int b = (int)wcol - (int)col;
+
+	    /* The difference between wcol and col is used to set coladd. */
+	    if (b > 0 && b < (MAXCOL - 2 * W_WIDTH(curwin)))
+		pos->coladd = b;
+
+	    col += b;
+	}
+    }
+#endif
+
+#ifdef FEAT_MBYTE
+    /* prevent cursor from moving on the trail byte */
+    if (has_mbyte)
+	mb_adjust_cursor();
+#endif
+
+    if (col < wcol)
+	return FAIL;
+    return OK;
+}
+
+/*
+ * inc(p)
+ *
+ * Increment the line pointer 'p' crossing line boundaries as necessary.
+ * Return 1 when going to the next line.
+ * Return 2 when moving forward onto a NUL at the end of the line).
+ * Return -1 when at the end of file.
+ * Return 0 otherwise.
+ */
+    int
+inc_cursor()
+{
+    return inc(&curwin->w_cursor);
+}
+
+    int
+inc(lp)
+    pos_T  *lp;
+{
+    char_u  *p = ml_get_pos(lp);
+
+    if (*p != NUL)	/* still within line, move to next char (may be NUL) */
+    {
+#ifdef FEAT_MBYTE
+	if (has_mbyte)
+	{
+	    int l = (*mb_ptr2len)(p);
+
+	    lp->col += l;
+	    return ((p[l] != NUL) ? 0 : 2);
+	}
+#endif
+	lp->col++;
+#ifdef FEAT_VIRTUALEDIT
+	lp->coladd = 0;
+#endif
+	return ((p[1] != NUL) ? 0 : 2);
+    }
+    if (lp->lnum != curbuf->b_ml.ml_line_count)     /* there is a next line */
+    {
+	lp->col = 0;
+	lp->lnum++;
+#ifdef FEAT_VIRTUALEDIT
+	lp->coladd = 0;
+#endif
+	return 1;
+    }
+    return -1;
+}
+
+/*
+ * incl(lp): same as inc(), but skip the NUL at the end of non-empty lines
+ */
+    int
+incl(lp)
+    pos_T    *lp;
+{
+    int	    r;
+
+    if ((r = inc(lp)) >= 1 && lp->col)
+	r = inc(lp);
+    return r;
+}
+
+/*
+ * dec(p)
+ *
+ * Decrement the line pointer 'p' crossing line boundaries as necessary.
+ * Return 1 when crossing a line, -1 when at start of file, 0 otherwise.
+ */
+    int
+dec_cursor()
+{
+    return dec(&curwin->w_cursor);
+}
+
+    int
+dec(lp)
+    pos_T  *lp;
+{
+    char_u	*p;
+
+#ifdef FEAT_VIRTUALEDIT
+    lp->coladd = 0;
+#endif
+    if (lp->col > 0)		/* still within line */
+    {
+	lp->col--;
+#ifdef FEAT_MBYTE
+	if (has_mbyte)
+	{
+	    p = ml_get(lp->lnum);
+	    lp->col -= (*mb_head_off)(p, p + lp->col);
+	}
+#endif
+	return 0;
+    }
+    if (lp->lnum > 1)		/* there is a prior line */
+    {
+	lp->lnum--;
+	p = ml_get(lp->lnum);
+	lp->col = (colnr_T)STRLEN(p);
+#ifdef FEAT_MBYTE
+	if (has_mbyte)
+	    lp->col -= (*mb_head_off)(p, p + lp->col);
+#endif
+	return 1;
+    }
+    return -1;			/* at start of file */
+}
+
+/*
+ * decl(lp): same as dec(), but skip the NUL at the end of non-empty lines
+ */
+    int
+decl(lp)
+    pos_T    *lp;
+{
+    int	    r;
+
+    if ((r = dec(lp)) == 1 && lp->col)
+	r = dec(lp);
+    return r;
+}
+
+/*
+ * Make sure curwin->w_cursor.lnum is valid.
+ */
+    void
+check_cursor_lnum()
+{
+    if (curwin->w_cursor.lnum > curbuf->b_ml.ml_line_count)
+    {
+#ifdef FEAT_FOLDING
+	/* If there is a closed fold at the end of the file, put the cursor in
+	 * its first line.  Otherwise in the last line. */
+	if (!hasFolding(curbuf->b_ml.ml_line_count,
+						&curwin->w_cursor.lnum, NULL))
+#endif
+	    curwin->w_cursor.lnum = curbuf->b_ml.ml_line_count;
+    }
+    if (curwin->w_cursor.lnum <= 0)
+	curwin->w_cursor.lnum = 1;
+}
+
+/*
+ * Make sure curwin->w_cursor.col is valid.
+ */
+    void
+check_cursor_col()
+{
+    colnr_T len;
+#ifdef FEAT_VIRTUALEDIT
+    colnr_T oldcol = curwin->w_cursor.col + curwin->w_cursor.coladd;
+#endif
+
+    len = (colnr_T)STRLEN(ml_get_curline());
+    if (len == 0)
+	curwin->w_cursor.col = 0;
+    else if (curwin->w_cursor.col >= len)
+    {
+	/* Allow cursor past end-of-line in Insert mode, restarting Insert
+	 * mode or when in Visual mode and 'selection' isn't "old" */
+	if ((State & INSERT) || restart_edit
+#ifdef FEAT_VISUAL
+		|| (VIsual_active && *p_sel != 'o')
+#endif
+		|| virtual_active())
+	    curwin->w_cursor.col = len;
+	else
+	{
+	    curwin->w_cursor.col = len - 1;
+#ifdef FEAT_MBYTE
+	    /* prevent cursor from moving on the trail byte */
+	    if (has_mbyte)
+		mb_adjust_cursor();
+#endif
+	}
+    }
+
+#ifdef FEAT_VIRTUALEDIT
+    /* If virtual editing is on, we can leave the cursor on the old position,
+     * only we must set it to virtual.  But don't do it when at the end of the
+     * line. */
+    if (oldcol == MAXCOL)
+	curwin->w_cursor.coladd = 0;
+    else if (ve_flags == VE_ALL)
+	curwin->w_cursor.coladd = oldcol - curwin->w_cursor.col;
+#endif
+}
+
+/*
+ * make sure curwin->w_cursor in on a valid character
+ */
+    void
+check_cursor()
+{
+    check_cursor_lnum();
+    check_cursor_col();
+}
+
+#if defined(FEAT_TEXTOBJ) || defined(PROTO)
+/*
+ * Make sure curwin->w_cursor is not on the NUL at the end of the line.
+ * Allow it when in Visual mode and 'selection' is not "old".
+ */
+    void
+adjust_cursor_col()
+{
+    if (curwin->w_cursor.col > 0
+# ifdef FEAT_VISUAL
+	    && (!VIsual_active || *p_sel == 'o')
+# endif
+	    && gchar_cursor() == NUL)
+	--curwin->w_cursor.col;
+}
+#endif
+
+/*
+ * When curwin->w_leftcol has changed, adjust the cursor position.
+ * Return TRUE if the cursor was moved.
+ */
+    int
+leftcol_changed()
+{
+    long	lastcol;
+    colnr_T	s, e;
+    int		retval = FALSE;
+
+    changed_cline_bef_curs();
+    lastcol = curwin->w_leftcol + W_WIDTH(curwin) - curwin_col_off() - 1;
+    validate_virtcol();
+
+    /*
+     * If the cursor is right or left of the screen, move it to last or first
+     * character.
+     */
+    if (curwin->w_virtcol > (colnr_T)(lastcol - p_siso))
+    {
+	retval = TRUE;
+	coladvance((colnr_T)(lastcol - p_siso));
+    }
+    else if (curwin->w_virtcol < curwin->w_leftcol + p_siso)
+    {
+	retval = TRUE;
+	(void)coladvance((colnr_T)(curwin->w_leftcol + p_siso));
+    }
+
+    /*
+     * If the start of the character under the cursor is not on the screen,
+     * advance the cursor one more char.  If this fails (last char of the
+     * line) adjust the scrolling.
+     */
+    getvvcol(curwin, &curwin->w_cursor, &s, NULL, &e);
+    if (e > (colnr_T)lastcol)
+    {
+	retval = TRUE;
+	coladvance(s - 1);
+    }
+    else if (s < curwin->w_leftcol)
+    {
+	retval = TRUE;
+	if (coladvance(e + 1) == FAIL)	/* there isn't another character */
+	{
+	    curwin->w_leftcol = s;	/* adjust w_leftcol instead */
+	    changed_cline_bef_curs();
+	}
+    }
+
+    if (retval)
+	curwin->w_set_curswant = TRUE;
+    redraw_later(NOT_VALID);
+    return retval;
+}
+
+/**********************************************************************
+ * Various routines dealing with allocation and deallocation of memory.
+ */
+
+#if defined(MEM_PROFILE) || defined(PROTO)
+
+# define MEM_SIZES  8200
+static long_u mem_allocs[MEM_SIZES];
+static long_u mem_frees[MEM_SIZES];
+static long_u mem_allocated;
+static long_u mem_freed;
+static long_u mem_peak;
+static long_u num_alloc;
+static long_u num_freed;
+
+static void mem_pre_alloc_s __ARGS((size_t *sizep));
+static void mem_pre_alloc_l __ARGS((long_u *sizep));
+static void mem_post_alloc __ARGS((void **pp, size_t size));
+static void mem_pre_free __ARGS((void **pp));
+
+    static void
+mem_pre_alloc_s(sizep)
+    size_t *sizep;
+{
+    *sizep += sizeof(size_t);
+}
+
+    static void
+mem_pre_alloc_l(sizep)
+    long_u *sizep;
+{
+    *sizep += sizeof(size_t);
+}
+
+    static void
+mem_post_alloc(pp, size)
+    void **pp;
+    size_t size;
+{
+    if (*pp == NULL)
+	return;
+    size -= sizeof(size_t);
+    *(long_u *)*pp = size;
+    if (size <= MEM_SIZES-1)
+	mem_allocs[size-1]++;
+    else
+	mem_allocs[MEM_SIZES-1]++;
+    mem_allocated += size;
+    if (mem_allocated - mem_freed > mem_peak)
+	mem_peak = mem_allocated - mem_freed;
+    num_alloc++;
+    *pp = (void *)((char *)*pp + sizeof(size_t));
+}
+
+    static void
+mem_pre_free(pp)
+    void **pp;
+{
+    long_u size;
+
+    *pp = (void *)((char *)*pp - sizeof(size_t));
+    size = *(size_t *)*pp;
+    if (size <= MEM_SIZES-1)
+	mem_frees[size-1]++;
+    else
+	mem_frees[MEM_SIZES-1]++;
+    mem_freed += size;
+    num_freed++;
+}
+
+/*
+ * called on exit via atexit()
+ */
+    void
+vim_mem_profile_dump()
+{
+    int i, j;
+
+    printf("\r\n");
+    j = 0;
+    for (i = 0; i < MEM_SIZES - 1; i++)
+    {
+	if (mem_allocs[i] || mem_frees[i])
+	{
+	    if (mem_frees[i] > mem_allocs[i])
+		printf("\r\n%s", _("ERROR: "));
+	    printf("[%4d / %4lu-%-4lu] ", i + 1, mem_allocs[i], mem_frees[i]);
+	    j++;
+	    if (j > 3)
+	    {
+		j = 0;
+		printf("\r\n");
+	    }
+	}
+    }
+
+    i = MEM_SIZES - 1;
+    if (mem_allocs[i])
+    {
+	printf("\r\n");
+	if (mem_frees[i] > mem_allocs[i])
+	    printf(_("ERROR: "));
+	printf("[>%d / %4lu-%-4lu]", i, mem_allocs[i], mem_frees[i]);
+    }
+
+    printf(_("\n[bytes] total alloc-freed %lu-%lu, in use %lu, peak use %lu\n"),
+	    mem_allocated, mem_freed, mem_allocated - mem_freed, mem_peak);
+    printf(_("[calls] total re/malloc()'s %lu, total free()'s %lu\n\n"),
+	    num_alloc, num_freed);
+}
+
+#endif /* MEM_PROFILE */
+
+/*
+ * Some memory is reserved for error messages and for being able to
+ * call mf_release_all(), which needs some memory for mf_trans_add().
+ */
+#if defined(MSDOS) && !defined(DJGPP)
+# define SMALL_MEM
+# define KEEP_ROOM 8192L
+#else
+# define KEEP_ROOM (2 * 8192L)
+#endif
+
+/*
+ * Note: if unsinged is 16 bits we can only allocate up to 64K with alloc().
+ * Use lalloc for larger blocks.
+ */
+    char_u *
+alloc(size)
+    unsigned	    size;
+{
+    return (lalloc((long_u)size, TRUE));
+}
+
+/*
+ * Allocate memory and set all bytes to zero.
+ */
+    char_u *
+alloc_clear(size)
+    unsigned	    size;
+{
+    char_u *p;
+
+    p = (lalloc((long_u)size, TRUE));
+    if (p != NULL)
+	(void)vim_memset(p, 0, (size_t)size);
+    return p;
+}
+
+/*
+ * alloc() with check for maximum line length
+ */
+    char_u *
+alloc_check(size)
+    unsigned	    size;
+{
+#if !defined(UNIX) && !defined(__EMX__)
+    if (sizeof(int) == 2 && size > 0x7fff)
+    {
+	/* Don't hide this message */
+	emsg_silent = 0;
+	EMSG(_("E340: Line is becoming too long"));
+	return NULL;
+    }
+#endif
+    return (lalloc((long_u)size, TRUE));
+}
+
+/*
+ * Allocate memory like lalloc() and set all bytes to zero.
+ */
+    char_u *
+lalloc_clear(size, message)
+    long_u	size;
+    int		message;
+{
+    char_u *p;
+
+    p = (lalloc(size, message));
+    if (p != NULL)
+	(void)vim_memset(p, 0, (size_t)size);
+    return p;
+}
+
+/*
+ * Low level memory allocation function.
+ * This is used often, KEEP IT FAST!
+ */
+    char_u *
+lalloc(size, message)
+    long_u	size;
+    int		message;
+{
+    char_u	*p;		    /* pointer to new storage space */
+    static int	releasing = FALSE;  /* don't do mf_release_all() recursive */
+    int		try_again;
+#if defined(HAVE_AVAIL_MEM) && !defined(SMALL_MEM)
+    static long_u allocated = 0;    /* allocated since last avail check */
+#endif
+
+    /* Safety check for allocating zero bytes */
+    if (size == 0)
+    {
+	/* Don't hide this message */
+	emsg_silent = 0;
+	EMSGN(_("E341: Internal error: lalloc(%ld, )"), size);
+	return NULL;
+    }
+
+#ifdef MEM_PROFILE
+    mem_pre_alloc_l(&size);
+#endif
+
+#if defined(MSDOS) && !defined(DJGPP)
+    if (size >= 0xfff0)		/* in MSDOS we can't deal with >64K blocks */
+	p = NULL;
+    else
+#endif
+
+    /*
+     * Loop when out of memory: Try to release some memfile blocks and
+     * if some blocks are released call malloc again.
+     */
+    for (;;)
+    {
+	/*
+	 * Handle three kind of systems:
+	 * 1. No check for available memory: Just return.
+	 * 2. Slow check for available memory: call mch_avail_mem() after
+	 *    allocating KEEP_ROOM amount of memory.
+	 * 3. Strict check for available memory: call mch_avail_mem()
+	 */
+	if ((p = (char_u *)malloc((size_t)size)) != NULL)
+	{
+#ifndef HAVE_AVAIL_MEM
+	    /* 1. No check for available memory: Just return. */
+	    goto theend;
+#else
+# ifndef SMALL_MEM
+	    /* 2. Slow check for available memory: call mch_avail_mem() after
+	     *    allocating (KEEP_ROOM / 2) amount of memory. */
+	    allocated += size;
+	    if (allocated < KEEP_ROOM / 2)
+		goto theend;
+	    allocated = 0;
+# endif
+	    /* 3. check for available memory: call mch_avail_mem() */
+	    if (mch_avail_mem(TRUE) < KEEP_ROOM && !releasing)
+	    {
+		vim_free((char *)p);	/* System is low... no go! */
+		p = NULL;
+	    }
+	    else
+		goto theend;
+#endif
+	}
+	/*
+	 * Remember that mf_release_all() is being called to avoid an endless
+	 * loop, because mf_release_all() may call alloc() recursively.
+	 */
+	if (releasing)
+	    break;
+	releasing = TRUE;
+
+	clear_sb_text();	      /* free any scrollback text */
+	try_again = mf_release_all(); /* release as many blocks as possible */
+#ifdef FEAT_EVAL
+	try_again |= garbage_collect(); /* cleanup recursive lists/dicts */
+#endif
+
+	releasing = FALSE;
+	if (!try_again)
+	    break;
+    }
+
+    if (message && p == NULL)
+	do_outofmem_msg(size);
+
+theend:
+#ifdef MEM_PROFILE
+    mem_post_alloc((void **)&p, (size_t)size);
+#endif
+    return p;
+}
+
+#if defined(MEM_PROFILE) || defined(PROTO)
+/*
+ * realloc() with memory profiling.
+ */
+    void *
+mem_realloc(ptr, size)
+    void *ptr;
+    size_t size;
+{
+    void *p;
+
+    mem_pre_free(&ptr);
+    mem_pre_alloc_s(&size);
+
+    p = realloc(ptr, size);
+
+    mem_post_alloc(&p, size);
+
+    return p;
+}
+#endif
+
+/*
+* Avoid repeating the error message many times (they take 1 second each).
+* Did_outofmem_msg is reset when a character is read.
+*/
+    void
+do_outofmem_msg(size)
+    long_u	size;
+{
+    if (!did_outofmem_msg)
+    {
+	/* Don't hide this message */
+	emsg_silent = 0;
+	EMSGN(_("E342: Out of memory!  (allocating %lu bytes)"), size);
+	did_outofmem_msg = TRUE;
+    }
+}
+
+#if defined(EXITFREE) || defined(PROTO)
+
+# if defined(FEAT_SEARCHPATH)
+static void free_findfile __ARGS((void));
+# endif
+
+/*
+ * Free everything that we allocated.
+ * Can be used to detect memory leaks, e.g., with ccmalloc.
+ * NOTE: This is tricky!  Things are freed that functions depend on.  Don't be
+ * surprised if Vim crashes...
+ * Some things can't be freed, esp. things local to a library function.
+ */
+    void
+free_all_mem()
+{
+    buf_T	*buf, *nextbuf;
+    static int	entered = FALSE;
+    win_T	*win;
+
+    /* When we cause a crash here it is caught and Vim tries to exit cleanly.
+     * Don't try freeing everything again. */
+    if (entered)
+	return;
+    entered = TRUE;
+
+    ++autocmd_block;	    /* don't want to trigger autocommands here */
+
+#ifdef FEAT_WINDOWS
+    /* close all tabs and windows */
+    if (first_tabpage->tp_next != NULL)
+	do_cmdline_cmd((char_u *)"tabonly!");
+    if (firstwin != lastwin)
+	do_cmdline_cmd((char_u *)"only!");
+#endif
+
+# if defined(FEAT_SPELL)
+    /* Free all spell info. */
+    spell_free_all();
+# endif
+
+# if defined(FEAT_USR_CMDS)
+    /* Clear user commands (before deleting buffers). */
+    ex_comclear(NULL);
+# endif
+
+# ifdef FEAT_MENU
+    /* Clear menus. */
+    do_cmdline_cmd((char_u *)"aunmenu *");
+# endif
+
+    /* Clear mappings, abbreviations, breakpoints. */
+    do_cmdline_cmd((char_u *)"mapclear");
+    do_cmdline_cmd((char_u *)"mapclear!");
+    do_cmdline_cmd((char_u *)"abclear");
+# if defined(FEAT_EVAL)
+    do_cmdline_cmd((char_u *)"breakdel *");
+# endif
+# if defined(FEAT_PROFILE)
+    do_cmdline_cmd((char_u *)"profdel *");
+# endif
+
+# ifdef FEAT_TITLE
+    free_titles();
+# endif
+# if defined(FEAT_SEARCHPATH)
+    free_findfile();
+# endif
+
+    /* Obviously named calls. */
+# if defined(FEAT_AUTOCMD)
+    free_all_autocmds();
+# endif
+    clear_termcodes();
+    free_all_options();
+    free_all_marks();
+    alist_clear(&global_alist);
+    free_homedir();
+    free_search_patterns();
+    free_old_sub();
+    free_last_insert();
+    free_prev_shellcmd();
+    free_regexp_stuff();
+    free_tag_stuff();
+    free_cd_dir();
+    set_expr_line(NULL);
+    diff_clear(curtab);
+    clear_sb_text();	      /* free any scrollback text */
+
+    /* Free some global vars. */
+    vim_free(username);
+    vim_free(clip_exclude_prog);
+    vim_free(last_cmdline);
+    vim_free(new_last_cmdline);
+    set_keep_msg(NULL, 0);
+    vim_free(ff_expand_buffer);
+
+    /* Clear cmdline history. */
+    p_hi = 0;
+    init_history();
+
+#ifdef FEAT_QUICKFIX
+    qf_free_all(NULL);
+    /* Free all location lists */
+    FOR_ALL_WINDOWS(win)
+	qf_free_all(win);
+#endif
+
+    /* Close all script inputs. */
+    close_all_scripts();
+
+#if defined(FEAT_WINDOWS)
+    /* Destroy all windows.  Must come before freeing buffers. */
+    win_free_all();
+#endif
+
+    /* Free all buffers. */
+    for (buf = firstbuf; buf != NULL; )
+    {
+	nextbuf = buf->b_next;
+	close_buffer(NULL, buf, DOBUF_WIPE);
+	if (buf_valid(buf))
+	    buf = nextbuf;	/* didn't work, try next one */
+	else
+	    buf = firstbuf;
+    }
+
+#ifdef FEAT_ARABIC
+    free_cmdline_buf();
+#endif
+
+    /* Clear registers. */
+    clear_registers();
+    ResetRedobuff();
+    ResetRedobuff();
+
+#if defined(FEAT_CLIENTSERVER) && defined(FEAT_X11)
+    vim_free(serverDelayedStartName);
+#endif
+
+    /* highlight info */
+    free_highlight();
+
+    reset_last_sourcing();
+
+#ifdef FEAT_WINDOWS
+    free_tabpage(first_tabpage);
+    first_tabpage = NULL;
+#endif
+
+# ifdef UNIX
+    /* Machine-specific free. */
+    mch_free_mem();
+# endif
+
+    /* message history */
+    for (;;)
+	if (delete_first_msg() == FAIL)
+	    break;
+
+# ifdef FEAT_EVAL
+    eval_clear();
+# endif
+
+    free_termoptions();
+
+    /* screenlines (can't display anything now!) */
+    free_screenlines();
+
+#if defined(USE_XSMP)
+    xsmp_close();
+#endif
+#ifdef FEAT_GUI_GTK
+    gui_mch_free_all();
+#endif
+    clear_hl_tables();
+
+    vim_free(IObuff);
+    vim_free(NameBuff);
+}
+#endif
+
+/*
+ * copy a string into newly allocated memory
+ */
+    char_u *
+vim_strsave(string)
+    char_u	*string;
+{
+    char_u	*p;
+    unsigned	len;
+
+    len = (unsigned)STRLEN(string) + 1;
+    p = alloc(len);
+    if (p != NULL)
+	mch_memmove(p, string, (size_t)len);
+    return p;
+}
+
+    char_u *
+vim_strnsave(string, len)
+    char_u	*string;
+    int		len;
+{
+    char_u	*p;
+
+    p = alloc((unsigned)(len + 1));
+    if (p != NULL)
+    {
+	STRNCPY(p, string, len);
+	p[len] = NUL;
+    }
+    return p;
+}
+
+/*
+ * Same as vim_strsave(), but any characters found in esc_chars are preceded
+ * by a backslash.
+ */
+    char_u *
+vim_strsave_escaped(string, esc_chars)
+    char_u	*string;
+    char_u	*esc_chars;
+{
+    return vim_strsave_escaped_ext(string, esc_chars, '\\', FALSE);
+}
+
+/*
+ * Same as vim_strsave_escaped(), but when "bsl" is TRUE also escape
+ * characters where rem_backslash() would remove the backslash.
+ * Escape the characters with "cc".
+ */
+    char_u *
+vim_strsave_escaped_ext(string, esc_chars, cc, bsl)
+    char_u	*string;
+    char_u	*esc_chars;
+    int		cc;
+    int		bsl;
+{
+    char_u	*p;
+    char_u	*p2;
+    char_u	*escaped_string;
+    unsigned	length;
+#ifdef FEAT_MBYTE
+    int		l;
+#endif
+
+    /*
+     * First count the number of backslashes required.
+     * Then allocate the memory and insert them.
+     */
+    length = 1;				/* count the trailing NUL */
+    for (p = string; *p; p++)
+    {
+#ifdef FEAT_MBYTE
+	if (has_mbyte && (l = (*mb_ptr2len)(p)) > 1)
+	{
+	    length += l;		/* count a multibyte char */
+	    p += l - 1;
+	    continue;
+	}
+#endif
+	if (vim_strchr(esc_chars, *p) != NULL || (bsl && rem_backslash(p)))
+	    ++length;			/* count a backslash */
+	++length;			/* count an ordinary char */
+    }
+    escaped_string = alloc(length);
+    if (escaped_string != NULL)
+    {
+	p2 = escaped_string;
+	for (p = string; *p; p++)
+	{
+#ifdef FEAT_MBYTE
+	    if (has_mbyte && (l = (*mb_ptr2len)(p)) > 1)
+	    {
+		mch_memmove(p2, p, (size_t)l);
+		p2 += l;
+		p += l - 1;		/* skip multibyte char  */
+		continue;
+	    }
+#endif
+	    if (vim_strchr(esc_chars, *p) != NULL || (bsl && rem_backslash(p)))
+		*p2++ = cc;
+	    *p2++ = *p;
+	}
+	*p2 = NUL;
+    }
+    return escaped_string;
+}
+
+#if defined(FEAT_EVAL) || defined(PROTO)
+/*
+ * Escape "string" for use as a shell argument with system().
+ * This uses single quotes, except when we know we need to use double qoutes
+ * (MS-DOS and MS-Windows without 'shellslash' set).
+ * Returns the result in allocated memory, NULL if we have run out.
+ */
+    char_u *
+vim_strsave_shellescape(string)
+    char_u	*string;
+{
+    unsigned	length;
+    char_u	*p;
+    char_u	*d;
+    char_u	*escaped_string;
+
+    /* First count the number of extra bytes required. */
+    length = (unsigned)STRLEN(string) + 3;  /* two quotes and a trailing NUL */
+    for (p = string; *p != NUL; mb_ptr_adv(p))
+    {
+# if defined(WIN32) || defined(WIN16) || defined(DOS)
+	if (!p_ssl)
+	{
+	    if (*p == '"')
+		++length;		/* " -> "" */
+	}
+	else
+# endif
+	if (*p == '\'')
+	    length += 3;		/* ' => '\'' */
+    }
+
+    /* Allocate memory for the result and fill it. */
+    escaped_string = alloc(length);
+    if (escaped_string != NULL)
+    {
+	d = escaped_string;
+
+	/* add opening quote */
+# if defined(WIN32) || defined(WIN16) || defined(DOS)
+	if (!p_ssl)
+	    *d++ = '"';
+	else
+# endif
+	    *d++ = '\'';
+
+	for (p = string; *p != NUL; )
+	{
+# if defined(WIN32) || defined(WIN16) || defined(DOS)
+	    if (!p_ssl)
+	    {
+		if (*p == '"')
+		{
+		    *d++ = '"';
+		    *d++ = '"';
+		    ++p;
+		    continue;
+		}
+	    }
+	    else
+# endif
+	    if (*p == '\'')
+	    {
+		*d++='\'';
+		*d++='\\';
+		*d++='\'';
+		*d++='\'';
+		++p;
+		continue;
+	    }
+
+	    MB_COPY_CHAR(p, d);
+	}
+
+	/* add terminating quote and finish with a NUL */
+# if defined(WIN32) || defined(WIN16) || defined(DOS)
+	if (!p_ssl)
+	    *d++ = '"';
+	else
+# endif
+	    *d++ = '\'';
+	*d = NUL;
+    }
+
+    return escaped_string;
+}
+#endif
+
+/*
+ * Like vim_strsave(), but make all characters uppercase.
+ * This uses ASCII lower-to-upper case translation, language independent.
+ */
+    char_u *
+vim_strsave_up(string)
+    char_u	*string;
+{
+    char_u *p1;
+
+    p1 = vim_strsave(string);
+    vim_strup(p1);
+    return p1;
+}
+
+/*
+ * Like vim_strnsave(), but make all characters uppercase.
+ * This uses ASCII lower-to-upper case translation, language independent.
+ */
+    char_u *
+vim_strnsave_up(string, len)
+    char_u	*string;
+    int		len;
+{
+    char_u *p1;
+
+    p1 = vim_strnsave(string, len);
+    vim_strup(p1);
+    return p1;
+}
+
+/*
+ * ASCII lower-to-upper case translation, language independent.
+ */
+    void
+vim_strup(p)
+    char_u	*p;
+{
+    char_u  *p2;
+    int	    c;
+
+    if (p != NULL)
+    {
+	p2 = p;
+	while ((c = *p2) != NUL)
+#ifdef EBCDIC
+	    *p2++ = isalpha(c) ? toupper(c) : c;
+#else
+	    *p2++ = (c < 'a' || c > 'z') ? c : (c - 0x20);
+#endif
+    }
+}
+
+#if defined(FEAT_EVAL) || defined(FEAT_SPELL) || defined(PROTO)
+/*
+ * Make string "s" all upper-case and return it in allocated memory.
+ * Handles multi-byte characters as well as possible.
+ * Returns NULL when out of memory.
+ */
+    char_u *
+strup_save(orig)
+    char_u	*orig;
+{
+    char_u	*p;
+    char_u	*res;
+
+    res = p = vim_strsave(orig);
+
+    if (res != NULL)
+	while (*p != NUL)
+	{
+# ifdef FEAT_MBYTE
+	    int		l;
+
+	    if (enc_utf8)
+	    {
+		int	c, uc;
+		int	nl;
+		char_u	*s;
+
+		c = utf_ptr2char(p);
+		uc = utf_toupper(c);
+
+		/* Reallocate string when byte count changes.  This is rare,
+		 * thus it's OK to do another malloc()/free(). */
+		l = utf_ptr2len(p);
+		nl = utf_char2len(uc);
+		if (nl != l)
+		{
+		    s = alloc((unsigned)STRLEN(res) + 1 + nl - l);
+		    if (s == NULL)
+			break;
+		    mch_memmove(s, res, p - res);
+		    STRCPY(s + (p - res) + nl, p + l);
+		    p = s + (p - res);
+		    vim_free(res);
+		    res = s;
+		}
+
+		utf_char2bytes(uc, p);
+		p += nl;
+	    }
+	    else if (has_mbyte && (l = (*mb_ptr2len)(p)) > 1)
+		p += l;		/* skip multi-byte character */
+	    else
+# endif
+	    {
+		*p = TOUPPER_LOC(*p); /* note that toupper() can be a macro */
+		p++;
+	    }
+	}
+
+    return res;
+}
+#endif
+
+/*
+ * copy a space a number of times
+ */
+    void
+copy_spaces(ptr, count)
+    char_u	*ptr;
+    size_t	count;
+{
+    size_t	i = count;
+    char_u	*p = ptr;
+
+    while (i--)
+	*p++ = ' ';
+}
+
+#if defined(FEAT_VISUALEXTRA) || defined(PROTO)
+/*
+ * Copy a character a number of times.
+ * Does not work for multi-byte charactes!
+ */
+    void
+copy_chars(ptr, count, c)
+    char_u	*ptr;
+    size_t	count;
+    int		c;
+{
+    size_t	i = count;
+    char_u	*p = ptr;
+
+    while (i--)
+	*p++ = c;
+}
+#endif
+
+/*
+ * delete spaces at the end of a string
+ */
+    void
+del_trailing_spaces(ptr)
+    char_u	*ptr;
+{
+    char_u	*q;
+
+    q = ptr + STRLEN(ptr);
+    while (--q > ptr && vim_iswhite(q[0]) && q[-1] != '\\' && q[-1] != Ctrl_V)
+	*q = NUL;
+}
+
+/*
+ * Like strncpy(), but always terminate the result with one NUL.
+ * "to" must be "len + 1" long!
+ */
+    void
+vim_strncpy(to, from, len)
+    char_u	*to;
+    char_u	*from;
+    size_t	len;
+{
+    STRNCPY(to, from, len);
+    to[len] = NUL;
+}
+
+/*
+ * Isolate one part of a string option where parts are separated with
+ * "sep_chars".
+ * The part is copied into "buf[maxlen]".
+ * "*option" is advanced to the next part.
+ * The length is returned.
+ */
+    int
+copy_option_part(option, buf, maxlen, sep_chars)
+    char_u	**option;
+    char_u	*buf;
+    int		maxlen;
+    char	*sep_chars;
+{
+    int	    len = 0;
+    char_u  *p = *option;
+
+    /* skip '.' at start of option part, for 'suffixes' */
+    if (*p == '.')
+	buf[len++] = *p++;
+    while (*p != NUL && vim_strchr((char_u *)sep_chars, *p) == NULL)
+    {
+	/*
+	 * Skip backslash before a separator character and space.
+	 */
+	if (p[0] == '\\' && vim_strchr((char_u *)sep_chars, p[1]) != NULL)
+	    ++p;
+	if (len < maxlen - 1)
+	    buf[len++] = *p;
+	++p;
+    }
+    buf[len] = NUL;
+
+    if (*p != NUL && *p != ',')	/* skip non-standard separator */
+	++p;
+    p = skip_to_option_part(p);	/* p points to next file name */
+
+    *option = p;
+    return len;
+}
+
+/*
+ * Replacement for free() that ignores NULL pointers.
+ * Also skip free() when exiting for sure, this helps when we caught a deadly
+ * signal that was caused by a crash in free().
+ */
+    void
+vim_free(x)
+    void *x;
+{
+    if (x != NULL && !really_exiting)
+    {
+#ifdef MEM_PROFILE
+	mem_pre_free(&x);
+#endif
+	free(x);
+    }
+}
+
+#ifndef HAVE_MEMSET
+    void *
+vim_memset(ptr, c, size)
+    void    *ptr;
+    int	    c;
+    size_t  size;
+{
+    char *p = ptr;
+
+    while (size-- > 0)
+	*p++ = c;
+    return ptr;
+}
+#endif
+
+#ifdef VIM_MEMCMP
+/*
+ * Return zero when "b1" and "b2" are the same for "len" bytes.
+ * Return non-zero otherwise.
+ */
+    int
+vim_memcmp(b1, b2, len)
+    void    *b1;
+    void    *b2;
+    size_t  len;
+{
+    char_u  *p1 = (char_u *)b1, *p2 = (char_u *)b2;
+
+    for ( ; len > 0; --len)
+    {
+	if (*p1 != *p2)
+	    return 1;
+	++p1;
+	++p2;
+    }
+    return 0;
+}
+#endif
+
+#ifdef VIM_MEMMOVE
+/*
+ * Version of memmove() that handles overlapping source and destination.
+ * For systems that don't have a function that is guaranteed to do that (SYSV).
+ */
+    void
+mch_memmove(dst_arg, src_arg, len)
+    void    *src_arg, *dst_arg;
+    size_t  len;
+{
+    /*
+     * A void doesn't have a size, we use char pointers.
+     */
+    char *dst = dst_arg, *src = src_arg;
+
+					/* overlap, copy backwards */
+    if (dst > src && dst < src + len)
+    {
+	src += len;
+	dst += len;
+	while (len-- > 0)
+	    *--dst = *--src;
+    }
+    else				/* copy forwards */
+	while (len-- > 0)
+	    *dst++ = *src++;
+}
+#endif
+
+#if (!defined(HAVE_STRCASECMP) && !defined(HAVE_STRICMP)) || defined(PROTO)
+/*
+ * Compare two strings, ignoring case, using current locale.
+ * Doesn't work for multi-byte characters.
+ * return 0 for match, < 0 for smaller, > 0 for bigger
+ */
+    int
+vim_stricmp(s1, s2)
+    char	*s1;
+    char	*s2;
+{
+    int		i;
+
+    for (;;)
+    {
+	i = (int)TOLOWER_LOC(*s1) - (int)TOLOWER_LOC(*s2);
+	if (i != 0)
+	    return i;			    /* this character different */
+	if (*s1 == NUL)
+	    break;			    /* strings match until NUL */
+	++s1;
+	++s2;
+    }
+    return 0;				    /* strings match */
+}
+#endif
+
+#if (!defined(HAVE_STRNCASECMP) && !defined(HAVE_STRNICMP)) || defined(PROTO)
+/*
+ * Compare two strings, for length "len", ignoring case, using current locale.
+ * Doesn't work for multi-byte characters.
+ * return 0 for match, < 0 for smaller, > 0 for bigger
+ */
+    int
+vim_strnicmp(s1, s2, len)
+    char	*s1;
+    char	*s2;
+    size_t	len;
+{
+    int		i;
+
+    while (len > 0)
+    {
+	i = (int)TOLOWER_LOC(*s1) - (int)TOLOWER_LOC(*s2);
+	if (i != 0)
+	    return i;			    /* this character different */
+	if (*s1 == NUL)
+	    break;			    /* strings match until NUL */
+	++s1;
+	++s2;
+	--len;
+    }
+    return 0;				    /* strings match */
+}
+#endif
+
+#if 0	/* currently not used */
+/*
+ * Check if string "s2" appears somewhere in "s1" while ignoring case.
+ * Return NULL if not, a pointer to the first occurrence if it does.
+ */
+    char_u *
+vim_stristr(s1, s2)
+    char_u	*s1;
+    char_u	*s2;
+{
+    char_u	*p;
+    int		len = STRLEN(s2);
+    char_u	*end = s1 + STRLEN(s1) - len;
+
+    for (p = s1; p <= end; ++p)
+	if (STRNICMP(p, s2, len) == 0)
+	    return p;
+    return NULL;
+}
+#endif
+
+/*
+ * Version of strchr() and strrchr() that handle unsigned char strings
+ * with characters from 128 to 255 correctly.  It also doesn't return a
+ * pointer to the NUL at the end of the string.
+ */
+    char_u  *
+vim_strchr(string, c)
+    char_u	*string;
+    int		c;
+{
+    char_u	*p;
+    int		b;
+
+    p = string;
+#ifdef FEAT_MBYTE
+    if (enc_utf8 && c >= 0x80)
+    {
+	while (*p != NUL)
+	{
+	    if (utf_ptr2char(p) == c)
+		return p;
+	    p += (*mb_ptr2len)(p);
+	}
+	return NULL;
+    }
+    if (enc_dbcs != 0 && c > 255)
+    {
+	int	n2 = c & 0xff;
+
+	c = ((unsigned)c >> 8) & 0xff;
+	while ((b = *p) != NUL)
+	{
+	    if (b == c && p[1] == n2)
+		return p;
+	    p += (*mb_ptr2len)(p);
+	}
+	return NULL;
+    }
+    if (has_mbyte)
+    {
+	while ((b = *p) != NUL)
+	{
+	    if (b == c)
+		return p;
+	    p += (*mb_ptr2len)(p);
+	}
+	return NULL;
+    }
+#endif
+    while ((b = *p) != NUL)
+    {
+	if (b == c)
+	    return p;
+	++p;
+    }
+    return NULL;
+}
+
+/*
+ * Version of strchr() that only works for bytes and handles unsigned char
+ * strings with characters above 128 correctly. It also doesn't return a
+ * pointer to the NUL at the end of the string.
+ */
+    char_u  *
+vim_strbyte(string, c)
+    char_u	*string;
+    int		c;
+{
+    char_u	*p = string;
+
+    while (*p != NUL)
+    {
+	if (*p == c)
+	    return p;
+	++p;
+    }
+    return NULL;
+}
+
+/*
+ * Search for last occurrence of "c" in "string".
+ * Return NULL if not found.
+ * Does not handle multi-byte char for "c"!
+ */
+    char_u  *
+vim_strrchr(string, c)
+    char_u	*string;
+    int		c;
+{
+    char_u	*retval = NULL;
+    char_u	*p = string;
+
+    while (*p)
+    {
+	if (*p == c)
+	    retval = p;
+	mb_ptr_adv(p);
+    }
+    return retval;
+}
+
+/*
+ * Vim's version of strpbrk(), in case it's missing.
+ * Don't generate a prototype for this, causes problems when it's not used.
+ */
+#ifndef PROTO
+# ifndef HAVE_STRPBRK
+#  ifdef vim_strpbrk
+#   undef vim_strpbrk
+#  endif
+    char_u *
+vim_strpbrk(s, charset)
+    char_u	*s;
+    char_u	*charset;
+{
+    while (*s)
+    {
+	if (vim_strchr(charset, *s) != NULL)
+	    return s;
+	mb_ptr_adv(s);
+    }
+    return NULL;
+}
+# endif
+#endif
+
+/*
+ * Vim has its own isspace() function, because on some machines isspace()
+ * can't handle characters above 128.
+ */
+    int
+vim_isspace(x)
+    int	    x;
+{
+    return ((x >= 9 && x <= 13) || x == ' ');
+}
+
+/************************************************************************
+ * Functions for handling growing arrays.
+ */
+
+/*
+ * Clear an allocated growing array.
+ */
+    void
+ga_clear(gap)
+    garray_T *gap;
+{
+    vim_free(gap->ga_data);
+    ga_init(gap);
+}
+
+/*
+ * Clear a growing array that contains a list of strings.
+ */
+    void
+ga_clear_strings(gap)
+    garray_T *gap;
+{
+    int		i;
+
+    for (i = 0; i < gap->ga_len; ++i)
+	vim_free(((char_u **)(gap->ga_data))[i]);
+    ga_clear(gap);
+}
+
+/*
+ * Initialize a growing array.	Don't forget to set ga_itemsize and
+ * ga_growsize!  Or use ga_init2().
+ */
+    void
+ga_init(gap)
+    garray_T *gap;
+{
+    gap->ga_data = NULL;
+    gap->ga_maxlen = 0;
+    gap->ga_len = 0;
+}
+
+    void
+ga_init2(gap, itemsize, growsize)
+    garray_T	*gap;
+    int		itemsize;
+    int		growsize;
+{
+    ga_init(gap);
+    gap->ga_itemsize = itemsize;
+    gap->ga_growsize = growsize;
+}
+
+/*
+ * Make room in growing array "gap" for at least "n" items.
+ * Return FAIL for failure, OK otherwise.
+ */
+    int
+ga_grow(gap, n)
+    garray_T	*gap;
+    int		n;
+{
+    size_t	len;
+    char_u	*pp;
+
+    if (gap->ga_maxlen - gap->ga_len < n)
+    {
+	if (n < gap->ga_growsize)
+	    n = gap->ga_growsize;
+	len = gap->ga_itemsize * (gap->ga_len + n);
+	pp = alloc_clear((unsigned)len);
+	if (pp == NULL)
+	    return FAIL;
+	gap->ga_maxlen = gap->ga_len + n;
+	if (gap->ga_data != NULL)
+	{
+	    mch_memmove(pp, gap->ga_data,
+				      (size_t)(gap->ga_itemsize * gap->ga_len));
+	    vim_free(gap->ga_data);
+	}
+	gap->ga_data = pp;
+    }
+    return OK;
+}
+
+/*
+ * Concatenate a string to a growarray which contains characters.
+ * Note: Does NOT copy the NUL at the end!
+ */
+    void
+ga_concat(gap, s)
+    garray_T	*gap;
+    char_u	*s;
+{
+    int    len = (int)STRLEN(s);
+
+    if (ga_grow(gap, len) == OK)
+    {
+	mch_memmove((char *)gap->ga_data + gap->ga_len, s, (size_t)len);
+	gap->ga_len += len;
+    }
+}
+
+/*
+ * Append one byte to a growarray which contains bytes.
+ */
+    void
+ga_append(gap, c)
+    garray_T	*gap;
+    int		c;
+{
+    if (ga_grow(gap, 1) == OK)
+    {
+	*((char *)gap->ga_data + gap->ga_len) = c;
+	++gap->ga_len;
+    }
+}
+
+/************************************************************************
+ * functions that use lookup tables for various things, generally to do with
+ * special key codes.
+ */
+
+/*
+ * Some useful tables.
+ */
+
+static struct modmasktable
+{
+    short	mod_mask;	/* Bit-mask for particular key modifier */
+    short	mod_flag;	/* Bit(s) for particular key modifier */
+    char_u	name;		/* Single letter name of modifier */
+} mod_mask_table[] =
+{
+    {MOD_MASK_ALT,		MOD_MASK_ALT,		(char_u)'M'},
+    {MOD_MASK_META,		MOD_MASK_META,		(char_u)'T'},
+    {MOD_MASK_CTRL,		MOD_MASK_CTRL,		(char_u)'C'},
+    {MOD_MASK_SHIFT,		MOD_MASK_SHIFT,		(char_u)'S'},
+    {MOD_MASK_MULTI_CLICK,	MOD_MASK_2CLICK,	(char_u)'2'},
+    {MOD_MASK_MULTI_CLICK,	MOD_MASK_3CLICK,	(char_u)'3'},
+    {MOD_MASK_MULTI_CLICK,	MOD_MASK_4CLICK,	(char_u)'4'},
+#ifdef MACOS
+    {MOD_MASK_CMD,		MOD_MASK_CMD,		(char_u)'D'},
+#endif
+    /* 'A' must be the last one */
+    {MOD_MASK_ALT,		MOD_MASK_ALT,		(char_u)'A'},
+    {0, 0, NUL}
+};
+
+/*
+ * Shifted key terminal codes and their unshifted equivalent.
+ * Don't add mouse codes here, they are handled separately!
+ */
+#define MOD_KEYS_ENTRY_SIZE 5
+
+static char_u modifier_keys_table[] =
+{
+/*  mod mask	    with modifier		without modifier */
+    MOD_MASK_SHIFT, '&', '9',			'@', '1',	/* begin */
+    MOD_MASK_SHIFT, '&', '0',			'@', '2',	/* cancel */
+    MOD_MASK_SHIFT, '*', '1',			'@', '4',	/* command */
+    MOD_MASK_SHIFT, '*', '2',			'@', '5',	/* copy */
+    MOD_MASK_SHIFT, '*', '3',			'@', '6',	/* create */
+    MOD_MASK_SHIFT, '*', '4',			'k', 'D',	/* delete char */
+    MOD_MASK_SHIFT, '*', '5',			'k', 'L',	/* delete line */
+    MOD_MASK_SHIFT, '*', '7',			'@', '7',	/* end */
+    MOD_MASK_CTRL,  KS_EXTRA, (int)KE_C_END,	'@', '7',	/* end */
+    MOD_MASK_SHIFT, '*', '9',			'@', '9',	/* exit */
+    MOD_MASK_SHIFT, '*', '0',			'@', '0',	/* find */
+    MOD_MASK_SHIFT, '#', '1',			'%', '1',	/* help */
+    MOD_MASK_SHIFT, '#', '2',			'k', 'h',	/* home */
+    MOD_MASK_CTRL,  KS_EXTRA, (int)KE_C_HOME,	'k', 'h',	/* home */
+    MOD_MASK_SHIFT, '#', '3',			'k', 'I',	/* insert */
+    MOD_MASK_SHIFT, '#', '4',			'k', 'l',	/* left arrow */
+    MOD_MASK_CTRL,  KS_EXTRA, (int)KE_C_LEFT,	'k', 'l',	/* left arrow */
+    MOD_MASK_SHIFT, '%', 'a',			'%', '3',	/* message */
+    MOD_MASK_SHIFT, '%', 'b',			'%', '4',	/* move */
+    MOD_MASK_SHIFT, '%', 'c',			'%', '5',	/* next */
+    MOD_MASK_SHIFT, '%', 'd',			'%', '7',	/* options */
+    MOD_MASK_SHIFT, '%', 'e',			'%', '8',	/* previous */
+    MOD_MASK_SHIFT, '%', 'f',			'%', '9',	/* print */
+    MOD_MASK_SHIFT, '%', 'g',			'%', '0',	/* redo */
+    MOD_MASK_SHIFT, '%', 'h',			'&', '3',	/* replace */
+    MOD_MASK_SHIFT, '%', 'i',			'k', 'r',	/* right arr. */
+    MOD_MASK_CTRL,  KS_EXTRA, (int)KE_C_RIGHT,	'k', 'r',	/* right arr. */
+    MOD_MASK_SHIFT, '%', 'j',			'&', '5',	/* resume */
+    MOD_MASK_SHIFT, '!', '1',			'&', '6',	/* save */
+    MOD_MASK_SHIFT, '!', '2',			'&', '7',	/* suspend */
+    MOD_MASK_SHIFT, '!', '3',			'&', '8',	/* undo */
+    MOD_MASK_SHIFT, KS_EXTRA, (int)KE_S_UP,	'k', 'u',	/* up arrow */
+    MOD_MASK_SHIFT, KS_EXTRA, (int)KE_S_DOWN,	'k', 'd',	/* down arrow */
+
+								/* vt100 F1 */
+    MOD_MASK_SHIFT, KS_EXTRA, (int)KE_S_XF1,	KS_EXTRA, (int)KE_XF1,
+    MOD_MASK_SHIFT, KS_EXTRA, (int)KE_S_XF2,	KS_EXTRA, (int)KE_XF2,
+    MOD_MASK_SHIFT, KS_EXTRA, (int)KE_S_XF3,	KS_EXTRA, (int)KE_XF3,
+    MOD_MASK_SHIFT, KS_EXTRA, (int)KE_S_XF4,	KS_EXTRA, (int)KE_XF4,
+
+    MOD_MASK_SHIFT, KS_EXTRA, (int)KE_S_F1,	'k', '1',	/* F1 */
+    MOD_MASK_SHIFT, KS_EXTRA, (int)KE_S_F2,	'k', '2',
+    MOD_MASK_SHIFT, KS_EXTRA, (int)KE_S_F3,	'k', '3',
+    MOD_MASK_SHIFT, KS_EXTRA, (int)KE_S_F4,	'k', '4',
+    MOD_MASK_SHIFT, KS_EXTRA, (int)KE_S_F5,	'k', '5',
+    MOD_MASK_SHIFT, KS_EXTRA, (int)KE_S_F6,	'k', '6',
+    MOD_MASK_SHIFT, KS_EXTRA, (int)KE_S_F7,	'k', '7',
+    MOD_MASK_SHIFT, KS_EXTRA, (int)KE_S_F8,	'k', '8',
+    MOD_MASK_SHIFT, KS_EXTRA, (int)KE_S_F9,	'k', '9',
+    MOD_MASK_SHIFT, KS_EXTRA, (int)KE_S_F10,	'k', ';',	/* F10 */
+
+    MOD_MASK_SHIFT, KS_EXTRA, (int)KE_S_F11,	'F', '1',
+    MOD_MASK_SHIFT, KS_EXTRA, (int)KE_S_F12,	'F', '2',
+    MOD_MASK_SHIFT, KS_EXTRA, (int)KE_S_F13,	'F', '3',
+    MOD_MASK_SHIFT, KS_EXTRA, (int)KE_S_F14,	'F', '4',
+    MOD_MASK_SHIFT, KS_EXTRA, (int)KE_S_F15,	'F', '5',
+    MOD_MASK_SHIFT, KS_EXTRA, (int)KE_S_F16,	'F', '6',
+    MOD_MASK_SHIFT, KS_EXTRA, (int)KE_S_F17,	'F', '7',
+    MOD_MASK_SHIFT, KS_EXTRA, (int)KE_S_F18,	'F', '8',
+    MOD_MASK_SHIFT, KS_EXTRA, (int)KE_S_F19,	'F', '9',
+    MOD_MASK_SHIFT, KS_EXTRA, (int)KE_S_F20,	'F', 'A',
+
+    MOD_MASK_SHIFT, KS_EXTRA, (int)KE_S_F21,	'F', 'B',
+    MOD_MASK_SHIFT, KS_EXTRA, (int)KE_S_F22,	'F', 'C',
+    MOD_MASK_SHIFT, KS_EXTRA, (int)KE_S_F23,	'F', 'D',
+    MOD_MASK_SHIFT, KS_EXTRA, (int)KE_S_F24,	'F', 'E',
+    MOD_MASK_SHIFT, KS_EXTRA, (int)KE_S_F25,	'F', 'F',
+    MOD_MASK_SHIFT, KS_EXTRA, (int)KE_S_F26,	'F', 'G',
+    MOD_MASK_SHIFT, KS_EXTRA, (int)KE_S_F27,	'F', 'H',
+    MOD_MASK_SHIFT, KS_EXTRA, (int)KE_S_F28,	'F', 'I',
+    MOD_MASK_SHIFT, KS_EXTRA, (int)KE_S_F29,	'F', 'J',
+    MOD_MASK_SHIFT, KS_EXTRA, (int)KE_S_F30,	'F', 'K',
+
+    MOD_MASK_SHIFT, KS_EXTRA, (int)KE_S_F31,	'F', 'L',
+    MOD_MASK_SHIFT, KS_EXTRA, (int)KE_S_F32,	'F', 'M',
+    MOD_MASK_SHIFT, KS_EXTRA, (int)KE_S_F33,	'F', 'N',
+    MOD_MASK_SHIFT, KS_EXTRA, (int)KE_S_F34,	'F', 'O',
+    MOD_MASK_SHIFT, KS_EXTRA, (int)KE_S_F35,	'F', 'P',
+    MOD_MASK_SHIFT, KS_EXTRA, (int)KE_S_F36,	'F', 'Q',
+    MOD_MASK_SHIFT, KS_EXTRA, (int)KE_S_F37,	'F', 'R',
+
+							    /* TAB pseudo code*/
+    MOD_MASK_SHIFT, 'k', 'B',			KS_EXTRA, (int)KE_TAB,
+
+    NUL
+};
+
+static struct key_name_entry
+{
+    int	    key;	/* Special key code or ascii value */
+    char_u  *name;	/* Name of key */
+} key_names_table[] =
+{
+    {' ',		(char_u *)"Space"},
+    {TAB,		(char_u *)"Tab"},
+    {K_TAB,		(char_u *)"Tab"},
+    {NL,		(char_u *)"NL"},
+    {NL,		(char_u *)"NewLine"},	/* Alternative name */
+    {NL,		(char_u *)"LineFeed"},	/* Alternative name */
+    {NL,		(char_u *)"LF"},	/* Alternative name */
+    {CAR,		(char_u *)"CR"},
+    {CAR,		(char_u *)"Return"},	/* Alternative name */
+    {CAR,		(char_u *)"Enter"},	/* Alternative name */
+    {K_BS,		(char_u *)"BS"},
+    {K_BS,		(char_u *)"BackSpace"},	/* Alternative name */
+    {ESC,		(char_u *)"Esc"},
+    {CSI,		(char_u *)"CSI"},
+    {K_CSI,		(char_u *)"xCSI"},
+    {'|',		(char_u *)"Bar"},
+    {'\\',		(char_u *)"Bslash"},
+    {K_DEL,		(char_u *)"Del"},
+    {K_DEL,		(char_u *)"Delete"},	/* Alternative name */
+    {K_KDEL,		(char_u *)"kDel"},
+    {K_UP,		(char_u *)"Up"},
+    {K_DOWN,		(char_u *)"Down"},
+    {K_LEFT,		(char_u *)"Left"},
+    {K_RIGHT,		(char_u *)"Right"},
+    {K_XUP,		(char_u *)"xUp"},
+    {K_XDOWN,		(char_u *)"xDown"},
+    {K_XLEFT,		(char_u *)"xLeft"},
+    {K_XRIGHT,		(char_u *)"xRight"},
+
+    {K_F1,		(char_u *)"F1"},
+    {K_F2,		(char_u *)"F2"},
+    {K_F3,		(char_u *)"F3"},
+    {K_F4,		(char_u *)"F4"},
+    {K_F5,		(char_u *)"F5"},
+    {K_F6,		(char_u *)"F6"},
+    {K_F7,		(char_u *)"F7"},
+    {K_F8,		(char_u *)"F8"},
+    {K_F9,		(char_u *)"F9"},
+    {K_F10,		(char_u *)"F10"},
+
+    {K_F11,		(char_u *)"F11"},
+    {K_F12,		(char_u *)"F12"},
+    {K_F13,		(char_u *)"F13"},
+    {K_F14,		(char_u *)"F14"},
+    {K_F15,		(char_u *)"F15"},
+    {K_F16,		(char_u *)"F16"},
+    {K_F17,		(char_u *)"F17"},
+    {K_F18,		(char_u *)"F18"},
+    {K_F19,		(char_u *)"F19"},
+    {K_F20,		(char_u *)"F20"},
+
+    {K_F21,		(char_u *)"F21"},
+    {K_F22,		(char_u *)"F22"},
+    {K_F23,		(char_u *)"F23"},
+    {K_F24,		(char_u *)"F24"},
+    {K_F25,		(char_u *)"F25"},
+    {K_F26,		(char_u *)"F26"},
+    {K_F27,		(char_u *)"F27"},
+    {K_F28,		(char_u *)"F28"},
+    {K_F29,		(char_u *)"F29"},
+    {K_F30,		(char_u *)"F30"},
+
+    {K_F31,		(char_u *)"F31"},
+    {K_F32,		(char_u *)"F32"},
+    {K_F33,		(char_u *)"F33"},
+    {K_F34,		(char_u *)"F34"},
+    {K_F35,		(char_u *)"F35"},
+    {K_F36,		(char_u *)"F36"},
+    {K_F37,		(char_u *)"F37"},
+
+    {K_XF1,		(char_u *)"xF1"},
+    {K_XF2,		(char_u *)"xF2"},
+    {K_XF3,		(char_u *)"xF3"},
+    {K_XF4,		(char_u *)"xF4"},
+
+    {K_HELP,		(char_u *)"Help"},
+    {K_UNDO,		(char_u *)"Undo"},
+    {K_INS,		(char_u *)"Insert"},
+    {K_INS,		(char_u *)"Ins"},	/* Alternative name */
+    {K_KINS,		(char_u *)"kInsert"},
+    {K_HOME,		(char_u *)"Home"},
+    {K_KHOME,		(char_u *)"kHome"},
+    {K_XHOME,		(char_u *)"xHome"},
+    {K_ZHOME,		(char_u *)"zHome"},
+    {K_END,		(char_u *)"End"},
+    {K_KEND,		(char_u *)"kEnd"},
+    {K_XEND,		(char_u *)"xEnd"},
+    {K_ZEND,		(char_u *)"zEnd"},
+    {K_PAGEUP,		(char_u *)"PageUp"},
+    {K_PAGEDOWN,	(char_u *)"PageDown"},
+    {K_KPAGEUP,		(char_u *)"kPageUp"},
+    {K_KPAGEDOWN,	(char_u *)"kPageDown"},
+
+    {K_KPLUS,		(char_u *)"kPlus"},
+    {K_KMINUS,		(char_u *)"kMinus"},
+    {K_KDIVIDE,		(char_u *)"kDivide"},
+    {K_KMULTIPLY,	(char_u *)"kMultiply"},
+    {K_KENTER,		(char_u *)"kEnter"},
+    {K_KPOINT,		(char_u *)"kPoint"},
+
+    {K_K0,		(char_u *)"k0"},
+    {K_K1,		(char_u *)"k1"},
+    {K_K2,		(char_u *)"k2"},
+    {K_K3,		(char_u *)"k3"},
+    {K_K4,		(char_u *)"k4"},
+    {K_K5,		(char_u *)"k5"},
+    {K_K6,		(char_u *)"k6"},
+    {K_K7,		(char_u *)"k7"},
+    {K_K8,		(char_u *)"k8"},
+    {K_K9,		(char_u *)"k9"},
+
+    {'<',		(char_u *)"lt"},
+
+    {K_MOUSE,		(char_u *)"Mouse"},
+    {K_NETTERM_MOUSE,	(char_u *)"NetMouse"},
+    {K_DEC_MOUSE,	(char_u *)"DecMouse"},
+    {K_JSBTERM_MOUSE,	(char_u *)"JsbMouse"},
+    {K_PTERM_MOUSE,	(char_u *)"PtermMouse"},
+    {K_LEFTMOUSE,	(char_u *)"LeftMouse"},
+    {K_LEFTMOUSE_NM,	(char_u *)"LeftMouseNM"},
+    {K_LEFTDRAG,	(char_u *)"LeftDrag"},
+    {K_LEFTRELEASE,	(char_u *)"LeftRelease"},
+    {K_LEFTRELEASE_NM,	(char_u *)"LeftReleaseNM"},
+    {K_MIDDLEMOUSE,	(char_u *)"MiddleMouse"},
+    {K_MIDDLEDRAG,	(char_u *)"MiddleDrag"},
+    {K_MIDDLERELEASE,	(char_u *)"MiddleRelease"},
+    {K_RIGHTMOUSE,	(char_u *)"RightMouse"},
+    {K_RIGHTDRAG,	(char_u *)"RightDrag"},
+    {K_RIGHTRELEASE,	(char_u *)"RightRelease"},
+    {K_MOUSEDOWN,	(char_u *)"MouseDown"},
+    {K_MOUSEUP,		(char_u *)"MouseUp"},
+    {K_X1MOUSE,		(char_u *)"X1Mouse"},
+    {K_X1DRAG,		(char_u *)"X1Drag"},
+    {K_X1RELEASE,		(char_u *)"X1Release"},
+    {K_X2MOUSE,		(char_u *)"X2Mouse"},
+    {K_X2DRAG,		(char_u *)"X2Drag"},
+    {K_X2RELEASE,		(char_u *)"X2Release"},
+    {K_DROP,		(char_u *)"Drop"},
+    {K_ZERO,		(char_u *)"Nul"},
+#ifdef FEAT_EVAL
+    {K_SNR,		(char_u *)"SNR"},
+#endif
+    {K_PLUG,		(char_u *)"Plug"},
+    {0,			NULL}
+};
+
+#define KEY_NAMES_TABLE_LEN (sizeof(key_names_table) / sizeof(struct key_name_entry))
+
+#ifdef FEAT_MOUSE
+static struct mousetable
+{
+    int	    pseudo_code;	/* Code for pseudo mouse event */
+    int	    button;		/* Which mouse button is it? */
+    int	    is_click;		/* Is it a mouse button click event? */
+    int	    is_drag;		/* Is it a mouse drag event? */
+} mouse_table[] =
+{
+    {(int)KE_LEFTMOUSE,		MOUSE_LEFT,	TRUE,	FALSE},
+#ifdef FEAT_GUI
+    {(int)KE_LEFTMOUSE_NM,	MOUSE_LEFT,	TRUE,	FALSE},
+#endif
+    {(int)KE_LEFTDRAG,		MOUSE_LEFT,	FALSE,	TRUE},
+    {(int)KE_LEFTRELEASE,	MOUSE_LEFT,	FALSE,	FALSE},
+#ifdef FEAT_GUI
+    {(int)KE_LEFTRELEASE_NM,	MOUSE_LEFT,	FALSE,	FALSE},
+#endif
+    {(int)KE_MIDDLEMOUSE,	MOUSE_MIDDLE,	TRUE,	FALSE},
+    {(int)KE_MIDDLEDRAG,	MOUSE_MIDDLE,	FALSE,	TRUE},
+    {(int)KE_MIDDLERELEASE,	MOUSE_MIDDLE,	FALSE,	FALSE},
+    {(int)KE_RIGHTMOUSE,	MOUSE_RIGHT,	TRUE,	FALSE},
+    {(int)KE_RIGHTDRAG,		MOUSE_RIGHT,	FALSE,	TRUE},
+    {(int)KE_RIGHTRELEASE,	MOUSE_RIGHT,	FALSE,	FALSE},
+    {(int)KE_X1MOUSE,		MOUSE_X1,	TRUE,	FALSE},
+    {(int)KE_X1DRAG,		MOUSE_X1,	FALSE,	TRUE},
+    {(int)KE_X1RELEASE,		MOUSE_X1,	FALSE,	FALSE},
+    {(int)KE_X2MOUSE,		MOUSE_X2,	TRUE,	FALSE},
+    {(int)KE_X2DRAG,		MOUSE_X2,	FALSE,	TRUE},
+    {(int)KE_X2RELEASE,		MOUSE_X2,	FALSE,	FALSE},
+    /* DRAG without CLICK */
+    {(int)KE_IGNORE,		MOUSE_RELEASE,	FALSE,	TRUE},
+    /* RELEASE without CLICK */
+    {(int)KE_IGNORE,		MOUSE_RELEASE,	FALSE,	FALSE},
+    {0,				0,		0,	0},
+};
+#endif /* FEAT_MOUSE */
+
+/*
+ * Return the modifier mask bit (MOD_MASK_*) which corresponds to the given
+ * modifier name ('S' for Shift, 'C' for Ctrl etc).
+ */
+    int
+name_to_mod_mask(c)
+    int	    c;
+{
+    int	    i;
+
+    c = TOUPPER_ASC(c);
+    for (i = 0; mod_mask_table[i].mod_mask != 0; i++)
+	if (c == mod_mask_table[i].name)
+	    return mod_mask_table[i].mod_flag;
+    return 0;
+}
+
+/*
+ * Check if if there is a special key code for "key" that includes the
+ * modifiers specified.
+ */
+    int
+simplify_key(key, modifiers)
+    int	    key;
+    int	    *modifiers;
+{
+    int	    i;
+    int	    key0;
+    int	    key1;
+
+    if (*modifiers & (MOD_MASK_SHIFT | MOD_MASK_CTRL | MOD_MASK_ALT))
+    {
+	/* TAB is a special case */
+	if (key == TAB && (*modifiers & MOD_MASK_SHIFT))
+	{
+	    *modifiers &= ~MOD_MASK_SHIFT;
+	    return K_S_TAB;
+	}
+	key0 = KEY2TERMCAP0(key);
+	key1 = KEY2TERMCAP1(key);
+	for (i = 0; modifier_keys_table[i] != NUL; i += MOD_KEYS_ENTRY_SIZE)
+	    if (key0 == modifier_keys_table[i + 3]
+		    && key1 == modifier_keys_table[i + 4]
+		    && (*modifiers & modifier_keys_table[i]))
+	    {
+		*modifiers &= ~modifier_keys_table[i];
+		return TERMCAP2KEY(modifier_keys_table[i + 1],
+						   modifier_keys_table[i + 2]);
+	    }
+    }
+    return key;
+}
+
+/*
+ * Change <xHome> to <Home>, <xUp> to <Up>, etc.
+ */
+    int
+handle_x_keys(key)
+    int	    key;
+{
+    switch (key)
+    {
+	case K_XUP:	return K_UP;
+	case K_XDOWN:	return K_DOWN;
+	case K_XLEFT:	return K_LEFT;
+	case K_XRIGHT:	return K_RIGHT;
+	case K_XHOME:	return K_HOME;
+	case K_ZHOME:	return K_HOME;
+	case K_XEND:	return K_END;
+	case K_ZEND:	return K_END;
+	case K_XF1:	return K_F1;
+	case K_XF2:	return K_F2;
+	case K_XF3:	return K_F3;
+	case K_XF4:	return K_F4;
+	case K_S_XF1:	return K_S_F1;
+	case K_S_XF2:	return K_S_F2;
+	case K_S_XF3:	return K_S_F3;
+	case K_S_XF4:	return K_S_F4;
+    }
+    return key;
+}
+
+/*
+ * Return a string which contains the name of the given key when the given
+ * modifiers are down.
+ */
+    char_u *
+get_special_key_name(c, modifiers)
+    int	    c;
+    int	    modifiers;
+{
+    static char_u string[MAX_KEY_NAME_LEN + 1];
+
+    int	    i, idx;
+    int	    table_idx;
+    char_u  *s;
+
+    string[0] = '<';
+    idx = 1;
+
+    /* Key that stands for a normal character. */
+    if (IS_SPECIAL(c) && KEY2TERMCAP0(c) == KS_KEY)
+	c = KEY2TERMCAP1(c);
+
+    /*
+     * Translate shifted special keys into unshifted keys and set modifier.
+     * Same for CTRL and ALT modifiers.
+     */
+    if (IS_SPECIAL(c))
+    {
+	for (i = 0; modifier_keys_table[i] != 0; i += MOD_KEYS_ENTRY_SIZE)
+	    if (       KEY2TERMCAP0(c) == (int)modifier_keys_table[i + 1]
+		    && (int)KEY2TERMCAP1(c) == (int)modifier_keys_table[i + 2])
+	    {
+		modifiers |= modifier_keys_table[i];
+		c = TERMCAP2KEY(modifier_keys_table[i + 3],
+						   modifier_keys_table[i + 4]);
+		break;
+	    }
+    }
+
+    /* try to find the key in the special key table */
+    table_idx = find_special_key_in_table(c);
+
+    /*
+     * When not a known special key, and not a printable character, try to
+     * extract modifiers.
+     */
+    if (c > 0
+#ifdef FEAT_MBYTE
+	    && (*mb_char2len)(c) == 1
+#endif
+       )
+    {
+	if (table_idx < 0
+		&& (!vim_isprintc(c) || (c & 0x7f) == ' ')
+		&& (c & 0x80))
+	{
+	    c &= 0x7f;
+	    modifiers |= MOD_MASK_ALT;
+	    /* try again, to find the un-alted key in the special key table */
+	    table_idx = find_special_key_in_table(c);
+	}
+	if (table_idx < 0 && !vim_isprintc(c) && c < ' ')
+	{
+#ifdef EBCDIC
+	    c = CtrlChar(c);
+#else
+	    c += '@';
+#endif
+	    modifiers |= MOD_MASK_CTRL;
+	}
+    }
+
+    /* translate the modifier into a string */
+    for (i = 0; mod_mask_table[i].name != 'A'; i++)
+	if ((modifiers & mod_mask_table[i].mod_mask)
+						== mod_mask_table[i].mod_flag)
+	{
+	    string[idx++] = mod_mask_table[i].name;
+	    string[idx++] = (char_u)'-';
+	}
+
+    if (table_idx < 0)		/* unknown special key, may output t_xx */
+    {
+	if (IS_SPECIAL(c))
+	{
+	    string[idx++] = 't';
+	    string[idx++] = '_';
+	    string[idx++] = KEY2TERMCAP0(c);
+	    string[idx++] = KEY2TERMCAP1(c);
+	}
+	/* Not a special key, only modifiers, output directly */
+	else
+	{
+#ifdef FEAT_MBYTE
+	    if (has_mbyte && (*mb_char2len)(c) > 1)
+		idx += (*mb_char2bytes)(c, string + idx);
+	    else
+#endif
+	    if (vim_isprintc(c))
+		string[idx++] = c;
+	    else
+	    {
+		s = transchar(c);
+		while (*s)
+		    string[idx++] = *s++;
+	    }
+	}
+    }
+    else		/* use name of special key */
+    {
+	STRCPY(string + idx, key_names_table[table_idx].name);
+	idx = (int)STRLEN(string);
+    }
+    string[idx++] = '>';
+    string[idx] = NUL;
+    return string;
+}
+
+/*
+ * Try translating a <> name at (*srcp)[] to dst[].
+ * Return the number of characters added to dst[], zero for no match.
+ * If there is a match, srcp is advanced to after the <> name.
+ * dst[] must be big enough to hold the result (up to six characters)!
+ */
+    int
+trans_special(srcp, dst, keycode)
+    char_u	**srcp;
+    char_u	*dst;
+    int		keycode; /* prefer key code, e.g. K_DEL instead of DEL */
+{
+    int		modifiers = 0;
+    int		key;
+    int		dlen = 0;
+
+    key = find_special_key(srcp, &modifiers, keycode);
+    if (key == 0)
+	return 0;
+
+    /* Put the appropriate modifier in a string */
+    if (modifiers != 0)
+    {
+	dst[dlen++] = K_SPECIAL;
+	dst[dlen++] = KS_MODIFIER;
+	dst[dlen++] = modifiers;
+    }
+
+    if (IS_SPECIAL(key))
+    {
+	dst[dlen++] = K_SPECIAL;
+	dst[dlen++] = KEY2TERMCAP0(key);
+	dst[dlen++] = KEY2TERMCAP1(key);
+    }
+#ifdef FEAT_MBYTE
+    else if (has_mbyte && !keycode)
+	dlen += (*mb_char2bytes)(key, dst + dlen);
+#endif
+    else if (keycode)
+	dlen = (int)(add_char2buf(key, dst + dlen) - dst);
+    else
+	dst[dlen++] = key;
+
+    return dlen;
+}
+
+/*
+ * Try translating a <> name at (*srcp)[], return the key and modifiers.
+ * srcp is advanced to after the <> name.
+ * returns 0 if there is no match.
+ */
+    int
+find_special_key(srcp, modp, keycode)
+    char_u	**srcp;
+    int		*modp;
+    int		keycode; /* prefer key code, e.g. K_DEL instead of DEL */
+{
+    char_u	*last_dash;
+    char_u	*end_of_name;
+    char_u	*src;
+    char_u	*bp;
+    int		modifiers;
+    int		bit;
+    int		key;
+    unsigned long n;
+
+    src = *srcp;
+    if (src[0] != '<')
+	return 0;
+
+    /* Find end of modifier list */
+    last_dash = src;
+    for (bp = src + 1; *bp == '-' || vim_isIDc(*bp); bp++)
+    {
+	if (*bp == '-')
+	{
+	    last_dash = bp;
+	    if (bp[1] != NUL && bp[2] == '>')
+		++bp;	/* anything accepted, like <C-?> */
+	}
+	if (bp[0] == 't' && bp[1] == '_' && bp[2] && bp[3])
+	    bp += 3;	/* skip t_xx, xx may be '-' or '>' */
+    }
+
+    if (*bp == '>')	/* found matching '>' */
+    {
+	end_of_name = bp + 1;
+
+	if (STRNICMP(src + 1, "char-", 5) == 0 && VIM_ISDIGIT(src[6]))
+	{
+	    /* <Char-123> or <Char-033> or <Char-0x33> */
+	    vim_str2nr(src + 6, NULL, NULL, TRUE, TRUE, NULL, &n);
+	    *modp = 0;
+	    *srcp = end_of_name;
+	    return (int)n;
+	}
+
+	/* Which modifiers are given? */
+	modifiers = 0x0;
+	for (bp = src + 1; bp < last_dash; bp++)
+	{
+	    if (*bp != '-')
+	    {
+		bit = name_to_mod_mask(*bp);
+		if (bit == 0x0)
+		    break;	/* Illegal modifier name */
+		modifiers |= bit;
+	    }
+	}
+
+	/*
+	 * Legal modifier name.
+	 */
+	if (bp >= last_dash)
+	{
+	    /*
+	     * Modifier with single letter, or special key name.
+	     */
+	    if (modifiers != 0 && last_dash[2] == '>')
+		key = last_dash[1];
+	    else
+	    {
+		key = get_special_key_code(last_dash + 1);
+		key = handle_x_keys(key);
+	    }
+
+	    /*
+	     * get_special_key_code() may return NUL for invalid
+	     * special key name.
+	     */
+	    if (key != NUL)
+	    {
+		/*
+		 * Only use a modifier when there is no special key code that
+		 * includes the modifier.
+		 */
+		key = simplify_key(key, &modifiers);
+
+		if (!keycode)
+		{
+		    /* don't want keycode, use single byte code */
+		    if (key == K_BS)
+			key = BS;
+		    else if (key == K_DEL || key == K_KDEL)
+			key = DEL;
+		}
+
+		/*
+		 * Normal Key with modifier: Try to make a single byte code.
+		 */
+		if (!IS_SPECIAL(key))
+		    key = extract_modifiers(key, &modifiers);
+
+		*modp = modifiers;
+		*srcp = end_of_name;
+		return key;
+	    }
+	}
+    }
+    return 0;
+}
+
+/*
+ * Try to include modifiers in the key.
+ * Changes "Shift-a" to 'A', "Alt-A" to 0xc0, etc.
+ */
+    int
+extract_modifiers(key, modp)
+    int	    key;
+    int	    *modp;
+{
+    int	modifiers = *modp;
+
+#ifdef MACOS
+    /* Command-key really special, No fancynest */
+    if (!(modifiers & MOD_MASK_CMD))
+#endif
+    if ((modifiers & MOD_MASK_SHIFT) && ASCII_ISALPHA(key))
+    {
+	key = TOUPPER_ASC(key);
+	modifiers &= ~MOD_MASK_SHIFT;
+    }
+    if ((modifiers & MOD_MASK_CTRL)
+#ifdef EBCDIC
+	    /* * TODO: EBCDIC Better use:
+	     * && (Ctrl_chr(key) || key == '?')
+	     * ???  */
+	    && strchr("?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_", key)
+						       != NULL
+#else
+	    && ((key >= '?' && key <= '_') || ASCII_ISALPHA(key))
+#endif
+	    )
+    {
+	key = Ctrl_chr(key);
+	modifiers &= ~MOD_MASK_CTRL;
+	/* <C-@> is <Nul> */
+	if (key == 0)
+	    key = K_ZERO;
+    }
+#ifdef MACOS
+    /* Command-key really special, No fancynest */
+    if (!(modifiers & MOD_MASK_CMD))
+#endif
+    if ((modifiers & MOD_MASK_ALT) && key < 0x80
+#ifdef FEAT_MBYTE
+	    && !enc_dbcs		/* avoid creating a lead byte */
+#endif
+	    )
+    {
+	key |= 0x80;
+	modifiers &= ~MOD_MASK_ALT;	/* remove the META modifier */
+    }
+
+    *modp = modifiers;
+    return key;
+}
+
+/*
+ * Try to find key "c" in the special key table.
+ * Return the index when found, -1 when not found.
+ */
+    int
+find_special_key_in_table(c)
+    int	    c;
+{
+    int	    i;
+
+    for (i = 0; key_names_table[i].name != NULL; i++)
+	if (c == key_names_table[i].key)
+	    break;
+    if (key_names_table[i].name == NULL)
+	i = -1;
+    return i;
+}
+
+/*
+ * Find the special key with the given name (the given string does not have to
+ * end with NUL, the name is assumed to end before the first non-idchar).
+ * If the name starts with "t_" the next two characters are interpreted as a
+ * termcap name.
+ * Return the key code, or 0 if not found.
+ */
+    int
+get_special_key_code(name)
+    char_u  *name;
+{
+    char_u  *table_name;
+    char_u  string[3];
+    int	    i, j;
+
+    /*
+     * If it's <t_xx> we get the code for xx from the termcap
+     */
+    if (name[0] == 't' && name[1] == '_' && name[2] != NUL && name[3] != NUL)
+    {
+	string[0] = name[2];
+	string[1] = name[3];
+	string[2] = NUL;
+	if (add_termcap_entry(string, FALSE) == OK)
+	    return TERMCAP2KEY(name[2], name[3]);
+    }
+    else
+	for (i = 0; key_names_table[i].name != NULL; i++)
+	{
+	    table_name = key_names_table[i].name;
+	    for (j = 0; vim_isIDc(name[j]) && table_name[j] != NUL; j++)
+		if (TOLOWER_ASC(table_name[j]) != TOLOWER_ASC(name[j]))
+		    break;
+	    if (!vim_isIDc(name[j]) && table_name[j] == NUL)
+		return key_names_table[i].key;
+	}
+    return 0;
+}
+
+#ifdef FEAT_CMDL_COMPL
+    char_u *
+get_key_name(i)
+    int	    i;
+{
+    if (i >= KEY_NAMES_TABLE_LEN)
+	return NULL;
+    return  key_names_table[i].name;
+}
+#endif
+
+#ifdef FEAT_MOUSE
+/*
+ * Look up the given mouse code to return the relevant information in the other
+ * arguments.  Return which button is down or was released.
+ */
+    int
+get_mouse_button(code, is_click, is_drag)
+    int	    code;
+    int	    *is_click;
+    int	    *is_drag;
+{
+    int	    i;
+
+    for (i = 0; mouse_table[i].pseudo_code; i++)
+	if (code == mouse_table[i].pseudo_code)
+	{
+	    *is_click = mouse_table[i].is_click;
+	    *is_drag = mouse_table[i].is_drag;
+	    return mouse_table[i].button;
+	}
+    return 0;	    /* Shouldn't get here */
+}
+
+/*
+ * Return the appropriate pseudo mouse event token (KE_LEFTMOUSE etc) based on
+ * the given information about which mouse button is down, and whether the
+ * mouse was clicked, dragged or released.
+ */
+    int
+get_pseudo_mouse_code(button, is_click, is_drag)
+    int	    button;	/* eg MOUSE_LEFT */
+    int	    is_click;
+    int	    is_drag;
+{
+    int	    i;
+
+    for (i = 0; mouse_table[i].pseudo_code; i++)
+	if (button == mouse_table[i].button
+	    && is_click == mouse_table[i].is_click
+	    && is_drag == mouse_table[i].is_drag)
+	{
+#ifdef FEAT_GUI
+	    /* Trick: a non mappable left click and release has mouse_col -1
+	     * or added MOUSE_COLOFF.  Used for 'mousefocus' in
+	     * gui_mouse_moved() */
+	    if (mouse_col < 0 || mouse_col > MOUSE_COLOFF)
+	    {
+		if (mouse_col < 0)
+		    mouse_col = 0;
+		else
+		    mouse_col -= MOUSE_COLOFF;
+		if (mouse_table[i].pseudo_code == (int)KE_LEFTMOUSE)
+		    return (int)KE_LEFTMOUSE_NM;
+		if (mouse_table[i].pseudo_code == (int)KE_LEFTRELEASE)
+		    return (int)KE_LEFTRELEASE_NM;
+	    }
+#endif
+	    return mouse_table[i].pseudo_code;
+	}
+    return (int)KE_IGNORE;	    /* not recognized, ignore it */
+}
+#endif /* FEAT_MOUSE */
+
+/*
+ * Return the current end-of-line type: EOL_DOS, EOL_UNIX or EOL_MAC.
+ */
+    int
+get_fileformat(buf)
+    buf_T	*buf;
+{
+    int		c = *buf->b_p_ff;
+
+    if (buf->b_p_bin || c == 'u')
+	return EOL_UNIX;
+    if (c == 'm')
+	return EOL_MAC;
+    return EOL_DOS;
+}
+
+/*
+ * Like get_fileformat(), but override 'fileformat' with "p" for "++opt=val"
+ * argument.
+ */
+    int
+get_fileformat_force(buf, eap)
+    buf_T	*buf;
+    exarg_T	*eap;	    /* can be NULL! */
+{
+    int		c;
+
+    if (eap != NULL && eap->force_ff != 0)
+	c = eap->cmd[eap->force_ff];
+    else
+    {
+	if ((eap != NULL && eap->force_bin != 0)
+			       ? (eap->force_bin == FORCE_BIN) : buf->b_p_bin)
+	    return EOL_UNIX;
+	c = *buf->b_p_ff;
+    }
+    if (c == 'u')
+	return EOL_UNIX;
+    if (c == 'm')
+	return EOL_MAC;
+    return EOL_DOS;
+}
+
+/*
+ * Set the current end-of-line type to EOL_DOS, EOL_UNIX or EOL_MAC.
+ * Sets both 'textmode' and 'fileformat'.
+ * Note: Does _not_ set global value of 'textmode'!
+ */
+    void
+set_fileformat(t, opt_flags)
+    int		t;
+    int		opt_flags;	/* OPT_LOCAL and/or OPT_GLOBAL */
+{
+    char	*p = NULL;
+
+    switch (t)
+    {
+    case EOL_DOS:
+	p = FF_DOS;
+	curbuf->b_p_tx = TRUE;
+	break;
+    case EOL_UNIX:
+	p = FF_UNIX;
+	curbuf->b_p_tx = FALSE;
+	break;
+    case EOL_MAC:
+	p = FF_MAC;
+	curbuf->b_p_tx = FALSE;
+	break;
+    }
+    if (p != NULL)
+	set_string_option_direct((char_u *)"ff", -1, (char_u *)p,
+						     OPT_FREE | opt_flags, 0);
+
+#ifdef FEAT_WINDOWS
+    /* This may cause the buffer to become (un)modified. */
+    check_status(curbuf);
+    redraw_tabline = TRUE;
+#endif
+#ifdef FEAT_TITLE
+    need_maketitle = TRUE;	    /* set window title later */
+#endif
+}
+
+/*
+ * Return the default fileformat from 'fileformats'.
+ */
+    int
+default_fileformat()
+{
+    switch (*p_ffs)
+    {
+	case 'm':   return EOL_MAC;
+	case 'd':   return EOL_DOS;
+    }
+    return EOL_UNIX;
+}
+
+/*
+ * Call shell.	Calls mch_call_shell, with 'shellxquote' added.
+ */
+    int
+call_shell(cmd, opt)
+    char_u	*cmd;
+    int		opt;
+{
+    char_u	*ncmd;
+    int		retval;
+#ifdef FEAT_PROFILE
+    proftime_T	wait_time;
+#endif
+
+    if (p_verbose > 3)
+    {
+	verbose_enter();
+	smsg((char_u *)_("Calling shell to execute: \"%s\""),
+						    cmd == NULL ? p_sh : cmd);
+	out_char('\n');
+	cursor_on();
+	verbose_leave();
+    }
+
+#ifdef FEAT_PROFILE
+    if (do_profiling == PROF_YES)
+	prof_child_enter(&wait_time);
+#endif
+
+    if (*p_sh == NUL)
+    {
+	EMSG(_(e_shellempty));
+	retval = -1;
+    }
+    else
+    {
+#ifdef FEAT_GUI_MSWIN
+	/* Don't hide the pointer while executing a shell command. */
+	gui_mch_mousehide(FALSE);
+#endif
+#ifdef FEAT_GUI
+	++hold_gui_events;
+#endif
+	/* The external command may update a tags file, clear cached tags. */
+	tag_freematch();
+
+	if (cmd == NULL || *p_sxq == NUL)
+	    retval = mch_call_shell(cmd, opt);
+	else
+	{
+	    ncmd = alloc((unsigned)(STRLEN(cmd) + STRLEN(p_sxq) * 2 + 1));
+	    if (ncmd != NULL)
+	    {
+		STRCPY(ncmd, p_sxq);
+		STRCAT(ncmd, cmd);
+		STRCAT(ncmd, p_sxq);
+		retval = mch_call_shell(ncmd, opt);
+		vim_free(ncmd);
+	    }
+	    else
+		retval = -1;
+	}
+#ifdef FEAT_GUI
+	--hold_gui_events;
+#endif
+	/*
+	 * Check the window size, in case it changed while executing the
+	 * external command.
+	 */
+	shell_resized_check();
+    }
+
+#ifdef FEAT_EVAL
+    set_vim_var_nr(VV_SHELL_ERROR, (long)retval);
+# ifdef FEAT_PROFILE
+    if (do_profiling == PROF_YES)
+	prof_child_exit(&wait_time);
+# endif
+#endif
+
+    return retval;
+}
+
+/*
+ * VISUAL, SELECTMODE and OP_PENDING State are never set, they are equal to
+ * NORMAL State with a condition.  This function returns the real State.
+ */
+    int
+get_real_state()
+{
+    if (State & NORMAL)
+    {
+#ifdef FEAT_VISUAL
+	if (VIsual_active)
+	{
+	    if (VIsual_select)
+		return SELECTMODE;
+	    return VISUAL;
+	}
+	else
+#endif
+	    if (finish_op)
+		return OP_PENDING;
+    }
+    return State;
+}
+
+#if defined(FEAT_MBYTE) || defined(PROTO)
+/*
+ * Return TRUE if "p" points to just after a path separator.
+ * Take care of multi-byte characters.
+ * "b" must point to the start of the file name
+ */
+    int
+after_pathsep(b, p)
+    char_u	*b;
+    char_u	*p;
+{
+    return vim_ispathsep(p[-1])
+			     && (!has_mbyte || (*mb_head_off)(b, p - 1) == 0);
+}
+#endif
+
+/*
+ * Return TRUE if file names "f1" and "f2" are in the same directory.
+ * "f1" may be a short name, "f2" must be a full path.
+ */
+    int
+same_directory(f1, f2)
+    char_u	*f1;
+    char_u	*f2;
+{
+    char_u	ffname[MAXPATHL];
+    char_u	*t1;
+    char_u	*t2;
+
+    /* safety check */
+    if (f1 == NULL || f2 == NULL)
+	return FALSE;
+
+    (void)vim_FullName(f1, ffname, MAXPATHL, FALSE);
+    t1 = gettail_sep(ffname);
+    t2 = gettail_sep(f2);
+    return (t1 - ffname == t2 - f2
+	     && pathcmp((char *)ffname, (char *)f2, (int)(t1 - ffname)) == 0);
+}
+
+#if defined(FEAT_SESSION) || defined(MSWIN) || defined(FEAT_GUI_MAC) \
+	|| ((defined(FEAT_GUI_GTK)) \
+			&& ( defined(FEAT_WINDOWS) || defined(FEAT_DND)) ) \
+	|| defined(FEAT_SUN_WORKSHOP) || defined(FEAT_NETBEANS_INTG) \
+	|| defined(PROTO)
+/*
+ * Change to a file's directory.
+ * Caller must call shorten_fnames()!
+ * Return OK or FAIL.
+ */
+    int
+vim_chdirfile(fname)
+    char_u	*fname;
+{
+    char_u	dir[MAXPATHL];
+
+    vim_strncpy(dir, fname, MAXPATHL - 1);
+    *gettail_sep(dir) = NUL;
+    return mch_chdir((char *)dir) == 0 ? OK : FAIL;
+}
+#endif
+
+#if defined(STAT_IGNORES_SLASH) || defined(PROTO)
+/*
+ * Check if "name" ends in a slash and is not a directory.
+ * Used for systems where stat() ignores a trailing slash on a file name.
+ * The Vim code assumes a trailing slash is only ignored for a directory.
+ */
+    int
+illegal_slash(name)
+    char *name;
+{
+    if (name[0] == NUL)
+	return FALSE;	    /* no file name is not illegal */
+    if (name[strlen(name) - 1] != '/')
+	return FALSE;	    /* no trailing slash */
+    if (mch_isdir((char_u *)name))
+	return FALSE;	    /* trailing slash for a directory */
+    return TRUE;
+}
+#endif
+
+#if defined(CURSOR_SHAPE) || defined(PROTO)
+
+/*
+ * Handling of cursor and mouse pointer shapes in various modes.
+ */
+
+cursorentry_T shape_table[SHAPE_IDX_COUNT] =
+{
+    /* The values will be filled in from the 'guicursor' and 'mouseshape'
+     * defaults when Vim starts.
+     * Adjust the SHAPE_IDX_ defines when making changes! */
+    {0,	0, 0, 700L, 400L, 250L, 0, 0, "n", SHAPE_CURSOR+SHAPE_MOUSE},
+    {0,	0, 0, 700L, 400L, 250L, 0, 0, "v", SHAPE_CURSOR+SHAPE_MOUSE},
+    {0,	0, 0, 700L, 400L, 250L, 0, 0, "i", SHAPE_CURSOR+SHAPE_MOUSE},
+    {0,	0, 0, 700L, 400L, 250L, 0, 0, "r", SHAPE_CURSOR+SHAPE_MOUSE},
+    {0,	0, 0, 700L, 400L, 250L, 0, 0, "c", SHAPE_CURSOR+SHAPE_MOUSE},
+    {0,	0, 0, 700L, 400L, 250L, 0, 0, "ci", SHAPE_CURSOR+SHAPE_MOUSE},
+    {0,	0, 0, 700L, 400L, 250L, 0, 0, "cr", SHAPE_CURSOR+SHAPE_MOUSE},
+    {0,	0, 0, 700L, 400L, 250L, 0, 0, "o", SHAPE_CURSOR+SHAPE_MOUSE},
+    {0,	0, 0, 700L, 400L, 250L, 0, 0, "ve", SHAPE_CURSOR+SHAPE_MOUSE},
+    {0,	0, 0,   0L,   0L,   0L, 0, 0, "e", SHAPE_MOUSE},
+    {0,	0, 0,   0L,   0L,   0L, 0, 0, "s", SHAPE_MOUSE},
+    {0,	0, 0,   0L,   0L,   0L, 0, 0, "sd", SHAPE_MOUSE},
+    {0,	0, 0,   0L,   0L,   0L, 0, 0, "vs", SHAPE_MOUSE},
+    {0,	0, 0,   0L,   0L,   0L, 0, 0, "vd", SHAPE_MOUSE},
+    {0,	0, 0,   0L,   0L,   0L, 0, 0, "m", SHAPE_MOUSE},
+    {0,	0, 0,   0L,   0L,   0L, 0, 0, "ml", SHAPE_MOUSE},
+    {0,	0, 0, 100L, 100L, 100L, 0, 0, "sm", SHAPE_CURSOR},
+};
+
+#ifdef FEAT_MOUSESHAPE
+/*
+ * Table with names for mouse shapes.  Keep in sync with all the tables for
+ * mch_set_mouse_shape()!.
+ */
+static char * mshape_names[] =
+{
+    "arrow",	/* default, must be the first one */
+    "blank",	/* hidden */
+    "beam",
+    "updown",
+    "udsizing",
+    "leftright",
+    "lrsizing",
+    "busy",
+    "no",
+    "crosshair",
+    "hand1",
+    "hand2",
+    "pencil",
+    "question",
+    "rightup-arrow",
+    "up-arrow",
+    NULL
+};
+#endif
+
+/*
+ * Parse the 'guicursor' option ("what" is SHAPE_CURSOR) or 'mouseshape'
+ * ("what" is SHAPE_MOUSE).
+ * Returns error message for an illegal option, NULL otherwise.
+ */
+    char_u *
+parse_shape_opt(what)
+    int		what;
+{
+    char_u	*modep;
+    char_u	*colonp;
+    char_u	*commap;
+    char_u	*slashp;
+    char_u	*p, *endp;
+    int		idx = 0;		/* init for GCC */
+    int		all_idx;
+    int		len;
+    int		i;
+    long	n;
+    int		found_ve = FALSE;	/* found "ve" flag */
+    int		round;
+
+    /*
+     * First round: check for errors; second round: do it for real.
+     */
+    for (round = 1; round <= 2; ++round)
+    {
+	/*
+	 * Repeat for all comma separated parts.
+	 */
+#ifdef FEAT_MOUSESHAPE
+	if (what == SHAPE_MOUSE)
+	    modep = p_mouseshape;
+	else
+#endif
+	    modep = p_guicursor;
+	while (*modep != NUL)
+	{
+	    colonp = vim_strchr(modep, ':');
+	    if (colonp == NULL)
+		return (char_u *)N_("E545: Missing colon");
+	    if (colonp == modep)
+		return (char_u *)N_("E546: Illegal mode");
+	    commap = vim_strchr(modep, ',');
+
+	    /*
+	     * Repeat for all mode's before the colon.
+	     * For the 'a' mode, we loop to handle all the modes.
+	     */
+	    all_idx = -1;
+	    while (modep < colonp || all_idx >= 0)
+	    {
+		if (all_idx < 0)
+		{
+		    /* Find the mode. */
+		    if (modep[1] == '-' || modep[1] == ':')
+			len = 1;
+		    else
+			len = 2;
+		    if (len == 1 && TOLOWER_ASC(modep[0]) == 'a')
+			all_idx = SHAPE_IDX_COUNT - 1;
+		    else
+		    {
+			for (idx = 0; idx < SHAPE_IDX_COUNT; ++idx)
+			    if (STRNICMP(modep, shape_table[idx].name, len)
+									 == 0)
+				break;
+			if (idx == SHAPE_IDX_COUNT
+				   || (shape_table[idx].used_for & what) == 0)
+			    return (char_u *)N_("E546: Illegal mode");
+			if (len == 2 && modep[0] == 'v' && modep[1] == 'e')
+			    found_ve = TRUE;
+		    }
+		    modep += len + 1;
+		}
+
+		if (all_idx >= 0)
+		    idx = all_idx--;
+		else if (round == 2)
+		{
+#ifdef FEAT_MOUSESHAPE
+		    if (what == SHAPE_MOUSE)
+		    {
+			/* Set the default, for the missing parts */
+			shape_table[idx].mshape = 0;
+		    }
+		    else
+#endif
+		    {
+			/* Set the defaults, for the missing parts */
+			shape_table[idx].shape = SHAPE_BLOCK;
+			shape_table[idx].blinkwait = 700L;
+			shape_table[idx].blinkon = 400L;
+			shape_table[idx].blinkoff = 250L;
+		    }
+		}
+
+		/* Parse the part after the colon */
+		for (p = colonp + 1; *p && *p != ','; )
+		{
+#ifdef FEAT_MOUSESHAPE
+		    if (what == SHAPE_MOUSE)
+		    {
+			for (i = 0; ; ++i)
+			{
+			    if (mshape_names[i] == NULL)
+			    {
+				if (!VIM_ISDIGIT(*p))
+				    return (char_u *)N_("E547: Illegal mouseshape");
+				if (round == 2)
+				    shape_table[idx].mshape =
+					      getdigits(&p) + MSHAPE_NUMBERED;
+				else
+				    (void)getdigits(&p);
+				break;
+			    }
+			    len = (int)STRLEN(mshape_names[i]);
+			    if (STRNICMP(p, mshape_names[i], len) == 0)
+			    {
+				if (round == 2)
+				    shape_table[idx].mshape = i;
+				p += len;
+				break;
+			    }
+			}
+		    }
+		    else /* if (what == SHAPE_MOUSE) */
+#endif
+		    {
+			/*
+			 * First handle the ones with a number argument.
+			 */
+			i = *p;
+			len = 0;
+			if (STRNICMP(p, "ver", 3) == 0)
+			    len = 3;
+			else if (STRNICMP(p, "hor", 3) == 0)
+			    len = 3;
+			else if (STRNICMP(p, "blinkwait", 9) == 0)
+			    len = 9;
+			else if (STRNICMP(p, "blinkon", 7) == 0)
+			    len = 7;
+			else if (STRNICMP(p, "blinkoff", 8) == 0)
+			    len = 8;
+			if (len != 0)
+			{
+			    p += len;
+			    if (!VIM_ISDIGIT(*p))
+				return (char_u *)N_("E548: digit expected");
+			    n = getdigits(&p);
+			    if (len == 3)   /* "ver" or "hor" */
+			    {
+				if (n == 0)
+				    return (char_u *)N_("E549: Illegal percentage");
+				if (round == 2)
+				{
+				    if (TOLOWER_ASC(i) == 'v')
+					shape_table[idx].shape = SHAPE_VER;
+				    else
+					shape_table[idx].shape = SHAPE_HOR;
+				    shape_table[idx].percentage = n;
+				}
+			    }
+			    else if (round == 2)
+			    {
+				if (len == 9)
+				    shape_table[idx].blinkwait = n;
+				else if (len == 7)
+				    shape_table[idx].blinkon = n;
+				else
+				    shape_table[idx].blinkoff = n;
+			    }
+			}
+			else if (STRNICMP(p, "block", 5) == 0)
+			{
+			    if (round == 2)
+				shape_table[idx].shape = SHAPE_BLOCK;
+			    p += 5;
+			}
+			else	/* must be a highlight group name then */
+			{
+			    endp = vim_strchr(p, '-');
+			    if (commap == NULL)		    /* last part */
+			    {
+				if (endp == NULL)
+				    endp = p + STRLEN(p);   /* find end of part */
+			    }
+			    else if (endp > commap || endp == NULL)
+				endp = commap;
+			    slashp = vim_strchr(p, '/');
+			    if (slashp != NULL && slashp < endp)
+			    {
+				/* "group/langmap_group" */
+				i = syn_check_group(p, (int)(slashp - p));
+				p = slashp + 1;
+			    }
+			    if (round == 2)
+			    {
+				shape_table[idx].id = syn_check_group(p,
+							     (int)(endp - p));
+				shape_table[idx].id_lm = shape_table[idx].id;
+				if (slashp != NULL && slashp < endp)
+				    shape_table[idx].id = i;
+			    }
+			    p = endp;
+			}
+		    } /* if (what != SHAPE_MOUSE) */
+
+		    if (*p == '-')
+			++p;
+		}
+	    }
+	    modep = p;
+	    if (*modep == ',')
+		++modep;
+	}
+    }
+
+    /* If the 's' flag is not given, use the 'v' cursor for 's' */
+    if (!found_ve)
+    {
+#ifdef FEAT_MOUSESHAPE
+	if (what == SHAPE_MOUSE)
+	{
+	    shape_table[SHAPE_IDX_VE].mshape = shape_table[SHAPE_IDX_V].mshape;
+	}
+	else
+#endif
+	{
+	    shape_table[SHAPE_IDX_VE].shape = shape_table[SHAPE_IDX_V].shape;
+	    shape_table[SHAPE_IDX_VE].percentage =
+					 shape_table[SHAPE_IDX_V].percentage;
+	    shape_table[SHAPE_IDX_VE].blinkwait =
+					  shape_table[SHAPE_IDX_V].blinkwait;
+	    shape_table[SHAPE_IDX_VE].blinkon =
+					    shape_table[SHAPE_IDX_V].blinkon;
+	    shape_table[SHAPE_IDX_VE].blinkoff =
+					   shape_table[SHAPE_IDX_V].blinkoff;
+	    shape_table[SHAPE_IDX_VE].id = shape_table[SHAPE_IDX_V].id;
+	    shape_table[SHAPE_IDX_VE].id_lm = shape_table[SHAPE_IDX_V].id_lm;
+	}
+    }
+
+    return NULL;
+}
+
+# if defined(MCH_CURSOR_SHAPE) || defined(FEAT_GUI) \
+	|| defined(FEAT_MOUSESHAPE) || defined(PROTO)
+/*
+ * Return the index into shape_table[] for the current mode.
+ * When "mouse" is TRUE, consider indexes valid for the mouse pointer.
+ */
+    int
+get_shape_idx(mouse)
+    int	mouse;
+{
+#ifdef FEAT_MOUSESHAPE
+    if (mouse && (State == HITRETURN || State == ASKMORE))
+    {
+# ifdef FEAT_GUI
+	int x, y;
+	gui_mch_getmouse(&x, &y);
+	if (Y_2_ROW(y) == Rows - 1)
+	    return SHAPE_IDX_MOREL;
+# endif
+	return SHAPE_IDX_MORE;
+    }
+    if (mouse && drag_status_line)
+	return SHAPE_IDX_SDRAG;
+# ifdef FEAT_VERTSPLIT
+    if (mouse && drag_sep_line)
+	return SHAPE_IDX_VDRAG;
+# endif
+#endif
+    if (!mouse && State == SHOWMATCH)
+	return SHAPE_IDX_SM;
+#ifdef FEAT_VREPLACE
+    if (State & VREPLACE_FLAG)
+	return SHAPE_IDX_R;
+#endif
+    if (State & REPLACE_FLAG)
+	return SHAPE_IDX_R;
+    if (State & INSERT)
+	return SHAPE_IDX_I;
+    if (State & CMDLINE)
+    {
+	if (cmdline_at_end())
+	    return SHAPE_IDX_C;
+	if (cmdline_overstrike())
+	    return SHAPE_IDX_CR;
+	return SHAPE_IDX_CI;
+    }
+    if (finish_op)
+	return SHAPE_IDX_O;
+#ifdef FEAT_VISUAL
+    if (VIsual_active)
+    {
+	if (*p_sel == 'e')
+	    return SHAPE_IDX_VE;
+	else
+	    return SHAPE_IDX_V;
+    }
+#endif
+    return SHAPE_IDX_N;
+}
+#endif
+
+# if defined(FEAT_MOUSESHAPE) || defined(PROTO)
+static int old_mouse_shape = 0;
+
+/*
+ * Set the mouse shape:
+ * If "shape" is -1, use shape depending on the current mode,
+ * depending on the current state.
+ * If "shape" is -2, only update the shape when it's CLINE or STATUS (used
+ * when the mouse moves off the status or command line).
+ */
+    void
+update_mouseshape(shape_idx)
+    int	shape_idx;
+{
+    int new_mouse_shape;
+
+    /* Only works in GUI mode. */
+    if (!gui.in_use || gui.starting)
+	return;
+
+    /* Postpone the updating when more is to come.  Speeds up executing of
+     * mappings. */
+    if (shape_idx == -1 && char_avail())
+    {
+	postponed_mouseshape = TRUE;
+	return;
+    }
+
+    /* When ignoring the mouse don't change shape on the statusline. */
+    if (*p_mouse == NUL
+	    && (shape_idx == SHAPE_IDX_CLINE
+		|| shape_idx == SHAPE_IDX_STATUS
+		|| shape_idx == SHAPE_IDX_VSEP))
+	shape_idx = -2;
+
+    if (shape_idx == -2
+	    && old_mouse_shape != shape_table[SHAPE_IDX_CLINE].mshape
+	    && old_mouse_shape != shape_table[SHAPE_IDX_STATUS].mshape
+	    && old_mouse_shape != shape_table[SHAPE_IDX_VSEP].mshape)
+	return;
+    if (shape_idx < 0)
+	new_mouse_shape = shape_table[get_shape_idx(TRUE)].mshape;
+    else
+	new_mouse_shape = shape_table[shape_idx].mshape;
+    if (new_mouse_shape != old_mouse_shape)
+    {
+	mch_set_mouse_shape(new_mouse_shape);
+	old_mouse_shape = new_mouse_shape;
+    }
+    postponed_mouseshape = FALSE;
+}
+# endif
+
+#endif /* CURSOR_SHAPE */
+
+
+#ifdef FEAT_CRYPT
+/*
+ * Optional encryption support.
+ * Mohsin Ahmed, mosh@sasi.com, 98-09-24
+ * Based on zip/crypt sources.
+ *
+ * NOTE FOR USA: Since 2000 exporting this code from the USA is allowed to
+ * most countries.  There are a few exceptions, but that still should not be a
+ * problem since this code was originally created in Europe and India.
+ */
+
+/* from zip.h */
+
+typedef unsigned short ush;	/* unsigned 16-bit value */
+typedef unsigned long  ulg;	/* unsigned 32-bit value */
+
+static void make_crc_tab __ARGS((void));
+
+static ulg crc_32_tab[256];
+
+/*
+ * Fill the CRC table.
+ */
+    static void
+make_crc_tab()
+{
+    ulg		s,t,v;
+    static int	done = FALSE;
+
+    if (done)
+	return;
+    for (t = 0; t < 256; t++)
+    {
+	v = t;
+	for (s = 0; s < 8; s++)
+	    v = (v >> 1) ^ ((v & 1) * (ulg)0xedb88320L);
+	crc_32_tab[t] = v;
+    }
+    done = TRUE;
+}
+
+#define CRC32(c, b) (crc_32_tab[((int)(c) ^ (b)) & 0xff] ^ ((c) >> 8))
+
+
+static ulg keys[3]; /* keys defining the pseudo-random sequence */
+
+/*
+ * Return the next byte in the pseudo-random sequence
+ */
+    int
+decrypt_byte()
+{
+    ush temp;
+
+    temp = (ush)keys[2] | 2;
+    return (int)(((unsigned)(temp * (temp ^ 1)) >> 8) & 0xff);
+}
+
+/*
+ * Update the encryption keys with the next byte of plain text
+ */
+    int
+update_keys(c)
+    int c;			/* byte of plain text */
+{
+    keys[0] = CRC32(keys[0], c);
+    keys[1] += keys[0] & 0xff;
+    keys[1] = keys[1] * 134775813L + 1;
+    keys[2] = CRC32(keys[2], (int)(keys[1] >> 24));
+    return c;
+}
+
+/*
+ * Initialize the encryption keys and the random header according to
+ * the given password.
+ * If "passwd" is NULL or empty, don't do anything.
+ */
+    void
+crypt_init_keys(passwd)
+    char_u *passwd;		/* password string with which to modify keys */
+{
+    if (passwd != NULL && *passwd != NUL)
+    {
+	make_crc_tab();
+	keys[0] = 305419896L;
+	keys[1] = 591751049L;
+	keys[2] = 878082192L;
+	while (*passwd != '\0')
+	    update_keys((int)*passwd++);
+    }
+}
+
+/*
+ * Ask the user for a crypt key.
+ * When "store" is TRUE, the new key in stored in the 'key' option, and the
+ * 'key' option value is returned: Don't free it.
+ * When "store" is FALSE, the typed key is returned in allocated memory.
+ * Returns NULL on failure.
+ */
+    char_u *
+get_crypt_key(store, twice)
+    int		store;
+    int		twice;	    /* Ask for the key twice. */
+{
+    char_u	*p1, *p2 = NULL;
+    int		round;
+
+    for (round = 0; ; ++round)
+    {
+	cmdline_star = TRUE;
+	cmdline_row = msg_row;
+	p1 = getcmdline_prompt(NUL, round == 0
+		? (char_u *)_("Enter encryption key: ")
+		: (char_u *)_("Enter same key again: "), 0, EXPAND_NOTHING,
+		NULL);
+	cmdline_star = FALSE;
+
+	if (p1 == NULL)
+	    break;
+
+	if (round == twice)
+	{
+	    if (p2 != NULL && STRCMP(p1, p2) != 0)
+	    {
+		MSG(_("Keys don't match!"));
+		vim_free(p1);
+		vim_free(p2);
+		p2 = NULL;
+		round = -1;		/* do it again */
+		continue;
+	    }
+	    if (store)
+	    {
+		set_option_value((char_u *)"key", 0L, p1, OPT_LOCAL);
+		vim_free(p1);
+		p1 = curbuf->b_p_key;
+	    }
+	    break;
+	}
+	p2 = p1;
+    }
+
+    /* since the user typed this, no need to wait for return */
+    need_wait_return = FALSE;
+    msg_didout = FALSE;
+
+    vim_free(p2);
+    return p1;
+}
+
+#endif /* FEAT_CRYPT */
+
+/* TODO: make some #ifdef for this */
+/*--------[ file searching ]-------------------------------------------------*/
+/*
+ * File searching functions for 'path', 'tags' and 'cdpath' options.
+ * External visible functions:
+ * vim_findfile_init()		creates/initialises the search context
+ * vim_findfile_free_visited()	free list of visited files/dirs of search
+ *				context
+ * vim_findfile()		find a file in the search context
+ * vim_findfile_cleanup()	cleanup/free search context created by
+ *				vim_findfile_init()
+ *
+ * All static functions and variables start with 'ff_'
+ *
+ * In general it works like this:
+ * First you create yourself a search context by calling vim_findfile_init().
+ * It is possible to give a search context from a previous call to
+ * vim_findfile_init(), so it can be reused. After this you call vim_findfile()
+ * until you are satisfied with the result or it returns NULL. On every call it
+ * returns the next file which matches the conditions given to
+ * vim_findfile_init(). If it doesn't find a next file it returns NULL.
+ *
+ * It is possible to call vim_findfile_init() again to reinitialise your search
+ * with some new parameters. Don't forget to pass your old search context to
+ * it, so it can reuse it and especially reuse the list of already visited
+ * directories. If you want to delete the list of already visited directories
+ * simply call vim_findfile_free_visited().
+ *
+ * When you are done call vim_findfile_cleanup() to free the search context.
+ *
+ * The function vim_findfile_init() has a long comment, which describes the
+ * needed parameters.
+ *
+ *
+ *
+ * ATTENTION:
+ * ==========
+ *	Also we use an allocated search context here, this functions are NOT
+ *	thread-safe!!!!!
+ *
+ *	To minimize parameter passing (or because I'm to lazy), only the
+ *	external visible functions get a search context as a parameter. This is
+ *	then assigned to a static global, which is used throughout the local
+ *	functions.
+ */
+
+/*
+ * type for the directory search stack
+ */
+typedef struct ff_stack
+{
+    struct ff_stack	*ffs_prev;
+
+    /* the fix part (no wildcards) and the part containing the wildcards
+     * of the search path
+     */
+    char_u		*ffs_fix_path;
+#ifdef FEAT_PATH_EXTRA
+    char_u		*ffs_wc_path;
+#endif
+
+    /* files/dirs found in the above directory, matched by the first wildcard
+     * of wc_part
+     */
+    char_u		**ffs_filearray;
+    int			ffs_filearray_size;
+    char_u		ffs_filearray_cur;   /* needed for partly handled dirs */
+
+    /* to store status of partly handled directories
+     * 0: we work the on this directory for the first time
+     * 1: this directory was partly searched in an earlier step
+    */
+    int			ffs_stage;
+
+    /* How deep are we in the directory tree?
+     * Counts backward from value of level parameter to vim_findfile_init
+     */
+    int			ffs_level;
+
+    /* Did we already expand '**' to an empty string? */
+    int			ffs_star_star_empty;
+} ff_stack_T;
+
+/*
+ * type for already visited directories or files.
+ */
+typedef struct ff_visited
+{
+    struct ff_visited	*ffv_next;
+
+#ifdef FEAT_PATH_EXTRA
+    /* Visited directories are different if the wildcard string are
+     * different. So we have to save it.
+     */
+    char_u		*ffv_wc_path;
+#endif
+    /* for unix use inode etc for comparison (needed because of links), else
+     * use filename.
+     */
+#ifdef UNIX
+    int			ffv_dev;	/* device number (-1 if not set) */
+    ino_t		ffv_ino;	/* inode number */
+#endif
+    /* The memory for this struct is allocated according to the length of
+     * ffv_fname.
+     */
+    char_u		ffv_fname[1];	/* actually longer */
+} ff_visited_T;
+
+/*
+ * We might have to manage several visited lists during a search.
+ * This is especially needed for the tags option. If tags is set to:
+ *      "./++/tags,./++/TAGS,++/tags"  (replace + with *)
+ * So we have to do 3 searches:
+ *   1) search from the current files directory downward for the file "tags"
+ *   2) search from the current files directory downward for the file "TAGS"
+ *   3) search from Vims current directory downwards for the file "tags"
+ * As you can see, the first and the third search are for the same file, so for
+ * the third search we can use the visited list of the first search. For the
+ * second search we must start from a empty visited list.
+ * The struct ff_visited_list_hdr is used to manage a linked list of already
+ * visited lists.
+ */
+typedef struct ff_visited_list_hdr
+{
+    struct ff_visited_list_hdr	*ffvl_next;
+
+    /* the filename the attached visited list is for */
+    char_u			*ffvl_filename;
+
+    ff_visited_T		*ffvl_visited_list;
+
+} ff_visited_list_hdr_T;
+
+
+/*
+ * '**' can be expanded to several directory levels.
+ * Set the default maximum depth.
+ */
+#define FF_MAX_STAR_STAR_EXPAND ((char_u)30)
+/*
+ * The search context:
+ *   ffsc_stack_ptr:	the stack for the dirs to search
+ *   ffsc_visited_list: the currently active visited list
+ *   ffsc_dir_visited_list: the currently active visited list for search dirs
+ *   ffsc_visited_lists_list: the list of all visited lists
+ *   ffsc_dir_visited_lists_list: the list of all visited lists for search dirs
+ *   ffsc_file_to_search:     the file to search for
+ *   ffsc_start_dir:	the starting directory, if search path was relative
+ *   ffsc_fix_path:	the fix part of the given path (without wildcards)
+ *			Needed for upward search.
+ *   ffsc_wc_path:	the part of the given path containing wildcards
+ *   ffsc_level:	how many levels of dirs to search downwards
+ *   ffsc_stopdirs_v:	array of stop directories for upward search
+ *   ffsc_need_dir:	TRUE if we search for a directory
+ */
+typedef struct ff_search_ctx_T
+{
+     ff_stack_T			*ffsc_stack_ptr;
+     ff_visited_list_hdr_T	*ffsc_visited_list;
+     ff_visited_list_hdr_T	*ffsc_dir_visited_list;
+     ff_visited_list_hdr_T	*ffsc_visited_lists_list;
+     ff_visited_list_hdr_T	*ffsc_dir_visited_lists_list;
+     char_u			*ffsc_file_to_search;
+     char_u			*ffsc_start_dir;
+     char_u			*ffsc_fix_path;
+#ifdef FEAT_PATH_EXTRA
+     char_u			*ffsc_wc_path;
+     int			ffsc_level;
+     char_u			**ffsc_stopdirs_v;
+#endif
+     int			ffsc_need_dir;
+} ff_search_ctx_T;
+
+static ff_search_ctx_T *ff_search_ctx = NULL;
+
+/* locally needed functions */
+#ifdef FEAT_PATH_EXTRA
+static int ff_check_visited __ARGS((ff_visited_T **, char_u *, char_u *));
+#else
+static int ff_check_visited __ARGS((ff_visited_T **, char_u *));
+#endif
+static void vim_findfile_free_visited_list __ARGS((ff_visited_list_hdr_T **list_headp));
+static void ff_free_visited_list __ARGS((ff_visited_T *vl));
+static ff_visited_list_hdr_T* ff_get_visited_list __ARGS((char_u *, ff_visited_list_hdr_T **list_headp));
+#ifdef FEAT_PATH_EXTRA
+static int ff_wc_equal __ARGS((char_u *s1, char_u *s2));
+#endif
+
+static void ff_push __ARGS((ff_stack_T *));
+static ff_stack_T * ff_pop __ARGS((void));
+static void ff_clear __ARGS((void));
+static void ff_free_stack_element __ARGS((ff_stack_T *));
+#ifdef FEAT_PATH_EXTRA
+static ff_stack_T *ff_create_stack_element __ARGS((char_u *, char_u *, int, int));
+#else
+static ff_stack_T *ff_create_stack_element __ARGS((char_u *, int, int));
+#endif
+#ifdef FEAT_PATH_EXTRA
+static int ff_path_in_stoplist __ARGS((char_u *, int, char_u **));
+#endif
+
+#if 0
+/*
+ * if someone likes findfirst/findnext, here are the functions
+ * NOT TESTED!!
+ */
+
+static void *ff_fn_search_context = NULL;
+
+    char_u *
+vim_findfirst(path, filename, level)
+    char_u	*path;
+    char_u	*filename;
+    int		level;
+{
+    ff_fn_search_context =
+	vim_findfile_init(path, filename, NULL, level, TRUE, FALSE,
+		ff_fn_search_context, rel_fname);
+    if (NULL == ff_fn_search_context)
+	return NULL;
+    else
+	return vim_findnext()
+}
+
+    char_u *
+vim_findnext()
+{
+    char_u *ret = vim_findfile(ff_fn_search_context);
+
+    if (NULL == ret)
+    {
+	vim_findfile_cleanup(ff_fn_search_context);
+	ff_fn_search_context = NULL;
+    }
+    return ret;
+}
+#endif
+
+/*
+ * Initialization routine for vim_findfile.
+ *
+ * Returns the newly allocated search context or NULL if an error occured.
+ *
+ * Don't forget to clean up by calling vim_findfile_cleanup() if you are done
+ * with the search context.
+ *
+ * Find the file 'filename' in the directory 'path'.
+ * The parameter 'path' may contain wildcards. If so only search 'level'
+ * directories deep. The parameter 'level' is the absolute maximum and is
+ * not related to restricts given to the '**' wildcard. If 'level' is 100
+ * and you use '**200' vim_findfile() will stop after 100 levels.
+ *
+ * If 'stopdirs' is not NULL and nothing is found downward, the search is
+ * restarted on the next higher directory level. This is repeated until the
+ * start-directory of a search is contained in 'stopdirs'. 'stopdirs' has the
+ * format ";*<dirname>*\(;<dirname>\)*;\=$".
+ *
+ * If the 'path' is relative, the starting dir for the search is either VIM's
+ * current dir or if the path starts with "./" the current files dir.
+ * If the 'path' is absolut, the starting dir is that part of the path before
+ * the first wildcard.
+ *
+ * Upward search is only done on the starting dir.
+ *
+ * If 'free_visited' is TRUE the list of already visited files/directories is
+ * cleared. Set this to FALSE if you just want to search from another
+ * directory, but want to be sure that no directory from a previous search is
+ * searched again. This is useful if you search for a file at different places.
+ * The list of visited files/dirs can also be cleared with the function
+ * vim_findfile_free_visited().
+ *
+ * Set the parameter 'need_dir' to TRUE if you want to search for a directory
+ * instead of a file.
+ *
+ * A search context returned by a previous call to vim_findfile_init() can be
+ * passed in the parameter 'search_ctx'. This context is than reused and
+ * reinitialized with the new parameters. The list of already viseted
+ * directories from this context is only deleted if the parameter
+ * 'free_visited' is true. Be aware that the passed search_context is freed if
+ * the reinitialization fails.
+ *
+ * If you don't have a search context from a previous call 'search_ctx' must be
+ * NULL.
+ *
+ * This function silently ignores a few errors, vim_findfile() will have
+ * limited functionality then.
+ */
+/*ARGSUSED*/
+    void *
+vim_findfile_init(path, filename, stopdirs, level, free_visited, need_dir,
+						search_ctx, tagfile, rel_fname)
+    char_u	*path;
+    char_u	*filename;
+    char_u	*stopdirs;
+    int		level;
+    int		free_visited;
+    int		need_dir;
+    void	*search_ctx;
+    int		tagfile;
+    char_u	*rel_fname;	/* file name to use for "." */
+{
+#ifdef FEAT_PATH_EXTRA
+    char_u	*wc_part;
+#endif
+    ff_stack_T	*sptr;
+
+    /* If a search context is given by the caller, reuse it, else allocate a
+     * new one.
+     */
+    if (search_ctx != NULL)
+	ff_search_ctx = search_ctx;
+    else
+    {
+	ff_search_ctx = (ff_search_ctx_T*)alloc(
+					   (unsigned)sizeof(ff_search_ctx_T));
+	if (ff_search_ctx == NULL)
+	    goto error_return;
+	memset(ff_search_ctx, 0, sizeof(ff_search_ctx_T));
+    }
+
+    /* clear the search context, but NOT the visited lists */
+    ff_clear();
+
+    /* clear visited list if wanted */
+    if (free_visited == TRUE)
+	vim_findfile_free_visited(ff_search_ctx);
+    else
+    {
+	/* Reuse old visited lists. Get the visited list for the given
+	 * filename. If no list for the current filename exists, creates a new
+	 * one.
+	 */
+	ff_search_ctx->ffsc_visited_list = ff_get_visited_list(filename,
+				     &ff_search_ctx->ffsc_visited_lists_list);
+	if (ff_search_ctx->ffsc_visited_list == NULL)
+	    goto error_return;
+	ff_search_ctx->ffsc_dir_visited_list = ff_get_visited_list(filename,
+				 &ff_search_ctx->ffsc_dir_visited_lists_list);
+	if (ff_search_ctx->ffsc_dir_visited_list == NULL)
+	    goto error_return;
+    }
+
+    if (ff_expand_buffer == NULL)
+    {
+	ff_expand_buffer = (char_u*)alloc(MAXPATHL);
+	if (ff_expand_buffer == NULL)
+	    goto error_return;
+    }
+
+    /* Store information on starting dir now if path is relative.
+     * If path is absolute, we do that later.  */
+    if (path[0] == '.'
+	    && (vim_ispathsep(path[1]) || path[1] == NUL)
+	    && (!tagfile || vim_strchr(p_cpo, CPO_DOTTAG) == NULL)
+	    && rel_fname != NULL)
+    {
+	int	len = (int)(gettail(rel_fname) - rel_fname);
+
+	if (!vim_isAbsName(rel_fname) && len + 1 < MAXPATHL)
+	{
+	    /* Make the start dir an absolute path name. */
+	    vim_strncpy(ff_expand_buffer, rel_fname, len);
+	    ff_search_ctx->ffsc_start_dir = FullName_save(ff_expand_buffer,
+								       FALSE);
+	}
+	else
+	    ff_search_ctx->ffsc_start_dir = vim_strnsave(rel_fname, len);
+	if (ff_search_ctx->ffsc_start_dir == NULL)
+	    goto error_return;
+	if (*++path != NUL)
+	    ++path;
+    }
+    else if (*path == NUL || !vim_isAbsName(path))
+    {
+#ifdef BACKSLASH_IN_FILENAME
+	/* "c:dir" needs "c:" to be expanded, otherwise use current dir */
+	if (*path != NUL && path[1] == ':')
+	{
+	    char_u  drive[3];
+
+	    drive[0] = path[0];
+	    drive[1] = ':';
+	    drive[2] = NUL;
+	    if (vim_FullName(drive, ff_expand_buffer, MAXPATHL, TRUE) == FAIL)
+		goto error_return;
+	    path += 2;
+	}
+	else
+#endif
+	if (mch_dirname(ff_expand_buffer, MAXPATHL) == FAIL)
+	    goto error_return;
+
+	ff_search_ctx->ffsc_start_dir = vim_strsave(ff_expand_buffer);
+	if (ff_search_ctx->ffsc_start_dir == NULL)
+	    goto error_return;
+
+#ifdef BACKSLASH_IN_FILENAME
+	/* A path that starts with "/dir" is relative to the drive, not to the
+	 * directory (but not for "//machine/dir").  Only use the drive name. */
+	if ((*path == '/' || *path == '\\')
+		&& path[1] != path[0]
+		&& ff_search_ctx->ffsc_start_dir[1] == ':')
+	    ff_search_ctx->ffsc_start_dir[2] = NUL;
+#endif
+    }
+
+#ifdef FEAT_PATH_EXTRA
+    /*
+     * If stopdirs are given, split them into an array of pointers.
+     * If this fails (mem allocation), there is no upward search at all or a
+     * stop directory is not recognized -> continue silently.
+     * If stopdirs just contains a ";" or is empty,
+     * ff_search_ctx->ffsc_stopdirs_v will only contain a  NULL pointer. This
+     * is handled as unlimited upward search.  See function
+     * ff_path_in_stoplist() for details.
+     */
+    if (stopdirs != NULL)
+    {
+	char_u	*walker = stopdirs;
+	int	dircount;
+
+	while (*walker == ';')
+	    walker++;
+
+	dircount = 1;
+	ff_search_ctx->ffsc_stopdirs_v =
+	    (char_u **)alloc((unsigned)sizeof(char_u *));
+
+	if (ff_search_ctx->ffsc_stopdirs_v != NULL)
+	{
+	    do
+	    {
+		char_u	*helper;
+		void	*ptr;
+
+		helper = walker;
+		ptr = vim_realloc(ff_search_ctx->ffsc_stopdirs_v,
+					   (dircount + 1) * sizeof(char_u *));
+		if (ptr)
+		    ff_search_ctx->ffsc_stopdirs_v = ptr;
+		else
+		    /* ignore, keep what we have and continue */
+		    break;
+		walker = vim_strchr(walker, ';');
+		if (walker)
+		{
+		    ff_search_ctx->ffsc_stopdirs_v[dircount-1] =
+			vim_strnsave(helper, (int)(walker - helper));
+		    walker++;
+		}
+		else
+		    /* this might be "", which means ascent till top
+		     * of directory tree.
+		     */
+		    ff_search_ctx->ffsc_stopdirs_v[dircount-1] =
+			vim_strsave(helper);
+
+		dircount++;
+
+	    } while (walker != NULL);
+	    ff_search_ctx->ffsc_stopdirs_v[dircount-1] = NULL;
+	}
+    }
+#endif
+
+#ifdef FEAT_PATH_EXTRA
+    ff_search_ctx->ffsc_level = level;
+
+    /* split into:
+     *  -fix path
+     *  -wildcard_stuff (might be NULL)
+     */
+    wc_part = vim_strchr(path, '*');
+    if (wc_part != NULL)
+    {
+	int	llevel;
+	int	len;
+	char	*errpt;
+
+	/* save the fix part of the path */
+	ff_search_ctx->ffsc_fix_path = vim_strnsave(path,
+						       (int)(wc_part - path));
+
+	/*
+	 * copy wc_path and add restricts to the '**' wildcard.
+	 * The octet after a '**' is used as a (binary) counter.
+	 * So '**3' is transposed to '**^C' ('^C' is ASCII value 3)
+	 * or '**76' is transposed to '**N'( 'N' is ASCII value 76).
+	 * For EBCDIC you get different character values.
+	 * If no restrict is given after '**' the default is used.
+	 * Due to this technic the path looks awful if you print it as a
+	 * string.
+	 */
+	len = 0;
+	while (*wc_part != NUL)
+	{
+	    if (STRNCMP(wc_part, "**", 2) == 0)
+	    {
+		ff_expand_buffer[len++] = *wc_part++;
+		ff_expand_buffer[len++] = *wc_part++;
+
+		llevel = strtol((char *)wc_part, &errpt, 10);
+		if ((char_u *)errpt != wc_part && llevel > 0 && llevel < 255)
+		    ff_expand_buffer[len++] = llevel;
+		else if ((char_u *)errpt != wc_part && llevel == 0)
+		    /* restrict is 0 -> remove already added '**' */
+		    len -= 2;
+		else
+		    ff_expand_buffer[len++] = FF_MAX_STAR_STAR_EXPAND;
+		wc_part = (char_u *)errpt;
+		if (*wc_part != NUL && !vim_ispathsep(*wc_part))
+		{
+		    EMSG2(_("E343: Invalid path: '**[number]' must be at the end of the path or be followed by '%s'."), PATHSEPSTR);
+		    goto error_return;
+		}
+	    }
+	    else
+		ff_expand_buffer[len++] = *wc_part++;
+	}
+	ff_expand_buffer[len] = NUL;
+	ff_search_ctx->ffsc_wc_path = vim_strsave(ff_expand_buffer);
+
+	if (ff_search_ctx->ffsc_wc_path == NULL)
+	    goto error_return;
+    }
+    else
+#endif
+	ff_search_ctx->ffsc_fix_path = vim_strsave(path);
+
+    if (ff_search_ctx->ffsc_start_dir == NULL)
+    {
+	/* store the fix part as startdir.
+	 * This is needed if the parameter path is fully qualified.
+	 */
+	ff_search_ctx->ffsc_start_dir = vim_strsave(ff_search_ctx->ffsc_fix_path);
+	if (ff_search_ctx->ffsc_start_dir)
+	    ff_search_ctx->ffsc_fix_path[0] = NUL;
+    }
+
+    /* create an absolute path */
+    STRCPY(ff_expand_buffer, ff_search_ctx->ffsc_start_dir);
+    add_pathsep(ff_expand_buffer);
+    STRCAT(ff_expand_buffer, ff_search_ctx->ffsc_fix_path);
+    add_pathsep(ff_expand_buffer);
+
+    sptr = ff_create_stack_element(ff_expand_buffer,
+#ifdef FEAT_PATH_EXTRA
+	    ff_search_ctx->ffsc_wc_path,
+#endif
+	    level, 0);
+
+    if (sptr == NULL)
+	goto error_return;
+
+    ff_push(sptr);
+
+    ff_search_ctx->ffsc_file_to_search = vim_strsave(filename);
+    if (ff_search_ctx->ffsc_file_to_search == NULL)
+	goto error_return;
+
+    return ff_search_ctx;
+
+error_return:
+    /*
+     * We clear the search context now!
+     * Even when the caller gave us a (perhaps valid) context we free it here,
+     * as we might have already destroyed it.
+     */
+    vim_findfile_cleanup(ff_search_ctx);
+    return NULL;
+}
+
+#if defined(FEAT_PATH_EXTRA) || defined(PROTO)
+/*
+ * Get the stopdir string.  Check that ';' is not escaped.
+ */
+    char_u *
+vim_findfile_stopdir(buf)
+    char_u	*buf;
+{
+    char_u	*r_ptr = buf;
+
+    while (*r_ptr != NUL && *r_ptr != ';')
+    {
+	if (r_ptr[0] == '\\' && r_ptr[1] == ';')
+	{
+	    /* overwrite the escape char,
+	     * use STRLEN(r_ptr) to move the trailing '\0'
+	     */
+	    mch_memmove(r_ptr, r_ptr + 1, STRLEN(r_ptr));
+	    r_ptr++;
+	}
+	r_ptr++;
+    }
+    if (*r_ptr == ';')
+    {
+	*r_ptr = 0;
+	r_ptr++;
+    }
+    else if (*r_ptr == NUL)
+	r_ptr = NULL;
+    return r_ptr;
+}
+#endif
+
+/* Clean up the given search context. Can handle a NULL pointer */
+    void
+vim_findfile_cleanup(ctx)
+    void	*ctx;
+{
+    if (ctx == NULL)
+	return;
+
+    ff_search_ctx = ctx;
+
+    vim_findfile_free_visited(ctx);
+    ff_clear();
+    vim_free(ctx);
+    ff_search_ctx = NULL;
+}
+
+/*
+ * Find a file in a search context.
+ * The search context was created with vim_findfile_init() above.
+ * Return a pointer to an allocated file name or NULL if nothing found.
+ * To get all matching files call this function until you get NULL.
+ *
+ * If the passed search_context is NULL, NULL is returned.
+ *
+ * The search algorithm is depth first. To change this replace the
+ * stack with a list (don't forget to leave partly searched directories on the
+ * top of the list).
+ */
+    char_u *
+vim_findfile(search_ctx)
+    void	*search_ctx;
+{
+    char_u	*file_path;
+#ifdef FEAT_PATH_EXTRA
+    char_u	*rest_of_wildcards;
+    char_u	*path_end = NULL;
+#endif
+    ff_stack_T	*ctx;
+#if defined(FEAT_SEARCHPATH) || defined(FEAT_PATH_EXTRA)
+    int		len;
+#endif
+    int		i;
+    char_u	*p;
+#ifdef FEAT_SEARCHPATH
+    char_u	*suf;
+#endif
+
+    if (search_ctx == NULL)
+	return NULL;
+
+    ff_search_ctx = (ff_search_ctx_T*)search_ctx;
+
+    /*
+     * filepath is used as buffer for various actions and as the storage to
+     * return a found filename.
+     */
+    if ((file_path = alloc((int)MAXPATHL)) == NULL)
+	return NULL;
+
+#ifdef FEAT_PATH_EXTRA
+    /* store the end of the start dir -- needed for upward search */
+    if (ff_search_ctx->ffsc_start_dir != NULL)
+	path_end = &ff_search_ctx->ffsc_start_dir[STRLEN(ff_search_ctx->ffsc_start_dir)];
+#endif
+
+#ifdef FEAT_PATH_EXTRA
+    /* upward search loop */
+    for (;;)
+    {
+#endif
+	/* downward search loop */
+	for (;;)
+	{
+	    /* check if user user wants to stop the search*/
+	    ui_breakcheck();
+	    if (got_int)
+		break;
+
+	    /* get directory to work on from stack */
+	    ctx = ff_pop();
+	    if (ctx == NULL)
+		break;
+
+	    /*
+	     * TODO: decide if we leave this test in
+	     *
+	     * GOOD: don't search a directory(-tree) twice.
+	     * BAD:  - check linked list for every new directory entered.
+	     *       - check for double files also done below
+	     *
+	     * Here we check if we already searched this directory.
+	     * We already searched a directory if:
+	     * 1) The directory is the same.
+	     * 2) We would use the same wildcard string.
+	     *
+	     * Good if you have links on same directory via several ways
+	     *  or you have selfreferences in directories (e.g. SuSE Linux 6.3:
+	     *  /etc/rc.d/init.d is linked to /etc/rc.d -> endless loop)
+	     *
+	     * This check is only needed for directories we work on for the
+	     * first time (hence ctx->ff_filearray == NULL)
+	     */
+	    if (ctx->ffs_filearray == NULL
+		    && ff_check_visited(&ff_search_ctx->ffsc_dir_visited_list
+							  ->ffvl_visited_list,
+			ctx->ffs_fix_path
+#ifdef FEAT_PATH_EXTRA
+			, ctx->ffs_wc_path
+#endif
+			) == FAIL)
+	    {
+#ifdef FF_VERBOSE
+		if (p_verbose >= 5)
+		{
+		    verbose_enter_scroll();
+		    smsg((char_u *)"Already Searched: %s (%s)",
+					   ctx->ffs_fix_path, ctx->ffs_wc_path);
+		    /* don't overwrite this either */
+		    msg_puts((char_u *)"\n");
+		    verbose_leave_scroll();
+		}
+#endif
+		ff_free_stack_element(ctx);
+		continue;
+	    }
+#ifdef FF_VERBOSE
+	    else if (p_verbose >= 5)
+	    {
+		verbose_enter_scroll();
+		smsg((char_u *)"Searching: %s (%s)",
+					 ctx->ffs_fix_path, ctx->ffs_wc_path);
+		/* don't overwrite this either */
+		msg_puts((char_u *)"\n");
+		verbose_leave_scroll();
+	    }
+#endif
+
+	    /* check depth */
+	    if (ctx->ffs_level <= 0)
+	    {
+		ff_free_stack_element(ctx);
+		continue;
+	    }
+
+	    file_path[0] = NUL;
+
+	    /*
+	     * If no filearray till now expand wildcards
+	     * The function expand_wildcards() can handle an array of paths
+	     * and all possible expands are returned in one array. We use this
+	     * to handle the expansion of '**' into an empty string.
+	     */
+	    if (ctx->ffs_filearray == NULL)
+	    {
+		char_u *dirptrs[2];
+
+		/* we use filepath to build the path expand_wildcards() should
+		 * expand.
+		 */
+		dirptrs[0] = file_path;
+		dirptrs[1] = NULL;
+
+		/* if we have a start dir copy it in */
+		if (!vim_isAbsName(ctx->ffs_fix_path)
+			&& ff_search_ctx->ffsc_start_dir)
+		{
+		    STRCPY(file_path, ff_search_ctx->ffsc_start_dir);
+		    add_pathsep(file_path);
+		}
+
+		/* append the fix part of the search path */
+		STRCAT(file_path, ctx->ffs_fix_path);
+		add_pathsep(file_path);
+
+#ifdef FEAT_PATH_EXTRA
+		rest_of_wildcards = ctx->ffs_wc_path;
+		if (*rest_of_wildcards != NUL)
+		{
+		    len = (int)STRLEN(file_path);
+		    if (STRNCMP(rest_of_wildcards, "**", 2) == 0)
+		    {
+			/* pointer to the restrict byte
+			 * The restrict byte is not a character!
+			 */
+			p = rest_of_wildcards + 2;
+
+			if (*p > 0)
+			{
+			    (*p)--;
+			    file_path[len++] = '*';
+			}
+
+			if (*p == 0)
+			{
+			    /* remove '**<numb> from wildcards */
+			    mch_memmove(rest_of_wildcards,
+				    rest_of_wildcards + 3,
+				    STRLEN(rest_of_wildcards + 3) + 1);
+			}
+			else
+			    rest_of_wildcards += 3;
+
+			if (ctx->ffs_star_star_empty == 0)
+			{
+			    /* if not done before, expand '**' to empty */
+			    ctx->ffs_star_star_empty = 1;
+			    dirptrs[1] = ctx->ffs_fix_path;
+			}
+		    }
+
+		    /*
+		     * Here we copy until the next path separator or the end of
+		     * the path. If we stop at a path separator, there is
+		     * still something else left. This is handled below by
+		     * pushing every directory returned from expand_wildcards()
+		     * on the stack again for further search.
+		     */
+		    while (*rest_of_wildcards
+			    && !vim_ispathsep(*rest_of_wildcards))
+			file_path[len++] = *rest_of_wildcards++;
+
+		    file_path[len] = NUL;
+		    if (vim_ispathsep(*rest_of_wildcards))
+			rest_of_wildcards++;
+		}
+#endif
+
+		/*
+		 * Expand wildcards like "*" and "$VAR".
+		 * If the path is a URL don't try this.
+		 */
+		if (path_with_url(dirptrs[0]))
+		{
+		    ctx->ffs_filearray = (char_u **)
+					      alloc((unsigned)sizeof(char *));
+		    if (ctx->ffs_filearray != NULL
+			    && (ctx->ffs_filearray[0]
+				= vim_strsave(dirptrs[0])) != NULL)
+			ctx->ffs_filearray_size = 1;
+		    else
+			ctx->ffs_filearray_size = 0;
+		}
+		else
+		    expand_wildcards((dirptrs[1] == NULL) ? 1 : 2, dirptrs,
+			    &ctx->ffs_filearray_size,
+			    &ctx->ffs_filearray,
+			    EW_DIR|EW_ADDSLASH|EW_SILENT);
+
+		ctx->ffs_filearray_cur = 0;
+		ctx->ffs_stage = 0;
+	    }
+#ifdef FEAT_PATH_EXTRA
+	    else
+		rest_of_wildcards = &ctx->ffs_wc_path[STRLEN(ctx->ffs_wc_path)];
+#endif
+
+	    if (ctx->ffs_stage == 0)
+	    {
+		/* this is the first time we work on this directory */
+#ifdef FEAT_PATH_EXTRA
+		if (*rest_of_wildcards == NUL)
+#endif
+		{
+		    /*
+		     * we don't have further wildcards to expand, so we have to
+		     * check for the final file now
+		     */
+		    for (i = ctx->ffs_filearray_cur;
+					     i < ctx->ffs_filearray_size; ++i)
+		    {
+			if (!path_with_url(ctx->ffs_filearray[i])
+					 && !mch_isdir(ctx->ffs_filearray[i]))
+			    continue;   /* not a directory */
+
+			/* prepare the filename to be checked for existance
+			 * below */
+			STRCPY(file_path, ctx->ffs_filearray[i]);
+			add_pathsep(file_path);
+			STRCAT(file_path, ff_search_ctx->ffsc_file_to_search);
+
+			/*
+			 * Try without extra suffix and then with suffixes
+			 * from 'suffixesadd'.
+			 */
+#ifdef FEAT_SEARCHPATH
+			len = (int)STRLEN(file_path);
+			suf = curbuf->b_p_sua;
+			for (;;)
+#endif
+			{
+			    /* if file exists and we didn't already find it */
+			    if ((path_with_url(file_path)
+					|| (mch_getperm(file_path) >= 0
+					    && (!ff_search_ctx->ffsc_need_dir
+						|| mch_isdir(file_path))))
+#ifndef FF_VERBOSE
+				    && (ff_check_visited(
+					    &ff_search_ctx->ffsc_visited_list->ffvl_visited_list,
+					    file_path
+#ifdef FEAT_PATH_EXTRA
+					    , (char_u *)""
+#endif
+					    ) == OK)
+#endif
+			       )
+			    {
+#ifdef FF_VERBOSE
+				if (ff_check_visited(
+					    &ff_search_ctx->ffsc_visited_list->ffvl_visited_list,
+					    file_path
+#ifdef FEAT_PATH_EXTRA
+					    , (char_u *)""
+#endif
+						    ) == FAIL)
+				{
+				    if (p_verbose >= 5)
+				    {
+					verbose_enter_scroll();
+					smsg((char_u *)"Already: %s",
+								   file_path);
+					/* don't overwrite this either */
+					msg_puts((char_u *)"\n");
+					verbose_leave_scroll();
+				    }
+				    continue;
+				}
+#endif
+
+				/* push dir to examine rest of subdirs later */
+				ctx->ffs_filearray_cur = i + 1;
+				ff_push(ctx);
+
+				simplify_filename(file_path);
+				if (mch_dirname(ff_expand_buffer, MAXPATHL)
+									== OK)
+				{
+				    p = shorten_fname(file_path,
+							    ff_expand_buffer);
+				    if (p != NULL)
+					mch_memmove(file_path, p,
+							       STRLEN(p) + 1);
+				}
+#ifdef FF_VERBOSE
+				if (p_verbose >= 5)
+				{
+				    verbose_enter_scroll();
+				    smsg((char_u *)"HIT: %s", file_path);
+				    /* don't overwrite this either */
+				    msg_puts((char_u *)"\n");
+				    verbose_leave_scroll();
+				}
+#endif
+				return file_path;
+			    }
+
+#ifdef FEAT_SEARCHPATH
+			    /* Not found or found already, try next suffix. */
+			    if (*suf == NUL)
+				break;
+			    copy_option_part(&suf, file_path + len,
+							 MAXPATHL - len, ",");
+#endif
+			}
+		    }
+		}
+#ifdef FEAT_PATH_EXTRA
+		else
+		{
+		    /*
+		     * still wildcards left, push the directories for further
+		     * search
+		     */
+		    for (i = ctx->ffs_filearray_cur;
+					     i < ctx->ffs_filearray_size; ++i)
+		    {
+			if (!mch_isdir(ctx->ffs_filearray[i]))
+			    continue;	/* not a directory */
+
+			ff_push(ff_create_stack_element(ctx->ffs_filearray[i],
+				      rest_of_wildcards, ctx->ffs_level - 1, 0));
+		    }
+		}
+#endif
+		ctx->ffs_filearray_cur = 0;
+		ctx->ffs_stage = 1;
+	    }
+
+#ifdef FEAT_PATH_EXTRA
+	    /*
+	     * if wildcards contains '**' we have to descent till we reach the
+	     * leaves of the directory tree.
+	     */
+	    if (STRNCMP(ctx->ffs_wc_path, "**", 2) == 0)
+	    {
+		for (i = ctx->ffs_filearray_cur;
+					     i < ctx->ffs_filearray_size; ++i)
+		{
+		    if (fnamecmp(ctx->ffs_filearray[i], ctx->ffs_fix_path) == 0)
+			continue; /* don't repush same directory */
+		    if (!mch_isdir(ctx->ffs_filearray[i]))
+			continue;   /* not a directory */
+		    ff_push(ff_create_stack_element(ctx->ffs_filearray[i],
+				ctx->ffs_wc_path, ctx->ffs_level - 1, 1));
+		}
+	    }
+#endif
+
+	    /* we are done with the current directory */
+	    ff_free_stack_element(ctx);
+
+	}
+
+#ifdef FEAT_PATH_EXTRA
+	/* If we reached this, we didn't find anything downwards.
+	 * Let's check if we should do an upward search.
+	 */
+	if (ff_search_ctx->ffsc_start_dir
+		&& ff_search_ctx->ffsc_stopdirs_v != NULL && !got_int)
+	{
+	    ff_stack_T  *sptr;
+
+	    /* is the last starting directory in the stop list? */
+	    if (ff_path_in_stoplist(ff_search_ctx->ffsc_start_dir,
+		       (int)(path_end - ff_search_ctx->ffsc_start_dir),
+		       ff_search_ctx->ffsc_stopdirs_v) == TRUE)
+		break;
+
+	    /* cut of last dir */
+	    while (path_end > ff_search_ctx->ffsc_start_dir
+		    && vim_ispathsep(*path_end))
+		path_end--;
+	    while (path_end > ff_search_ctx->ffsc_start_dir
+		    && !vim_ispathsep(path_end[-1]))
+		path_end--;
+	    *path_end = 0;
+	    path_end--;
+
+	    if (*ff_search_ctx->ffsc_start_dir == 0)
+		break;
+
+	    STRCPY(file_path, ff_search_ctx->ffsc_start_dir);
+	    add_pathsep(file_path);
+	    STRCAT(file_path, ff_search_ctx->ffsc_fix_path);
+
+	    /* create a new stack entry */
+	    sptr = ff_create_stack_element(file_path,
+		    ff_search_ctx->ffsc_wc_path, ff_search_ctx->ffsc_level, 0);
+	    if (sptr == NULL)
+		break;
+	    ff_push(sptr);
+	}
+	else
+	    break;
+    }
+#endif
+
+    vim_free(file_path);
+    return NULL;
+}
+
+/*
+ * Free the list of lists of visited files and directories
+ * Can handle it if the passed search_context is NULL;
+ */
+    void
+vim_findfile_free_visited(search_ctx)
+    void	*search_ctx;
+{
+    if (search_ctx == NULL)
+	return;
+
+    ff_search_ctx = (ff_search_ctx_T *)search_ctx;
+
+    vim_findfile_free_visited_list(&ff_search_ctx->ffsc_visited_lists_list);
+    vim_findfile_free_visited_list(&ff_search_ctx->ffsc_dir_visited_lists_list);
+}
+
+    static void
+vim_findfile_free_visited_list(list_headp)
+    ff_visited_list_hdr_T	**list_headp;
+{
+    ff_visited_list_hdr_T *vp;
+
+    while (*list_headp != NULL)
+    {
+	vp = (*list_headp)->ffvl_next;
+	ff_free_visited_list((*list_headp)->ffvl_visited_list);
+
+	vim_free((*list_headp)->ffvl_filename);
+	vim_free(*list_headp);
+	*list_headp = vp;
+    }
+    *list_headp = NULL;
+}
+
+    static void
+ff_free_visited_list(vl)
+    ff_visited_T *vl;
+{
+    ff_visited_T *vp;
+
+    while (vl != NULL)
+    {
+	vp = vl->ffv_next;
+#ifdef FEAT_PATH_EXTRA
+	vim_free(vl->ffv_wc_path);
+#endif
+	vim_free(vl);
+	vl = vp;
+    }
+    vl = NULL;
+}
+
+/*
+ * Returns the already visited list for the given filename. If none is found it
+ * allocates a new one.
+ */
+    static ff_visited_list_hdr_T*
+ff_get_visited_list(filename, list_headp)
+    char_u			*filename;
+    ff_visited_list_hdr_T	**list_headp;
+{
+    ff_visited_list_hdr_T  *retptr = NULL;
+
+    /* check if a visited list for the given filename exists */
+    if (*list_headp != NULL)
+    {
+	retptr = *list_headp;
+	while (retptr != NULL)
+	{
+	    if (fnamecmp(filename, retptr->ffvl_filename) == 0)
+	    {
+#ifdef FF_VERBOSE
+		if (p_verbose >= 5)
+		{
+		    verbose_enter_scroll();
+		    smsg((char_u *)"ff_get_visited_list: FOUND list for %s",
+								    filename);
+		    /* don't overwrite this either */
+		    msg_puts((char_u *)"\n");
+		    verbose_leave_scroll();
+		}
+#endif
+		return retptr;
+	    }
+	    retptr = retptr->ffvl_next;
+	}
+    }
+
+#ifdef FF_VERBOSE
+    if (p_verbose >= 5)
+    {
+	verbose_enter_scroll();
+	smsg((char_u *)"ff_get_visited_list: new list for %s", filename);
+	/* don't overwrite this either */
+	msg_puts((char_u *)"\n");
+	verbose_leave_scroll();
+    }
+#endif
+
+    /*
+     * if we reach this we didn't find a list and we have to allocate new list
+     */
+    retptr = (ff_visited_list_hdr_T*)alloc((unsigned)sizeof(*retptr));
+    if (retptr == NULL)
+	return NULL;
+
+    retptr->ffvl_visited_list = NULL;
+    retptr->ffvl_filename = vim_strsave(filename);
+    if (retptr->ffvl_filename == NULL)
+    {
+	vim_free(retptr);
+	return NULL;
+    }
+    retptr->ffvl_next = *list_headp;
+    *list_headp = retptr;
+
+    return retptr;
+}
+
+#ifdef FEAT_PATH_EXTRA
+/*
+ * check if two wildcard paths are equal. Returns TRUE or FALSE.
+ * They are equal if:
+ *  - both paths are NULL
+ *  - they have the same length
+ *  - char by char comparison is OK
+ *  - the only differences are in the counters behind a '**', so
+ *    '**\20' is equal to '**\24'
+ */
+    static int
+ff_wc_equal(s1, s2)
+    char_u	*s1;
+    char_u	*s2;
+{
+    int		i;
+
+    if (s1 == s2)
+	return TRUE;
+
+    if (s1 == NULL || s2 == NULL)
+	return FALSE;
+
+    if (STRLEN(s1) != STRLEN(s2))
+	return FAIL;
+
+    for (i = 0; s1[i] != NUL && s2[i] != NUL; i++)
+    {
+	if (s1[i] != s2[i]
+#ifdef CASE_INSENSITIVE_FILENAME
+		&& TOUPPER_LOC(s1[i]) != TOUPPER_LOC(s2[i])
+#endif
+		)
+	{
+	    if (i >= 2)
+		if (s1[i-1] == '*' && s1[i-2] == '*')
+		    continue;
+		else
+		    return FAIL;
+	    else
+		return FAIL;
+	}
+    }
+    return TRUE;
+}
+#endif
+
+/*
+ * maintains the list of already visited files and dirs
+ * returns FAIL if the given file/dir is already in the list
+ * returns OK if it is newly added
+ *
+ * TODO: What to do on memory allocation problems?
+ *	 -> return TRUE - Better the file is found several times instead of
+ *	    never.
+ */
+    static int
+ff_check_visited(visited_list, fname
+#ifdef FEAT_PATH_EXTRA
+	, wc_path
+#endif
+	)
+    ff_visited_T	**visited_list;
+    char_u		*fname;
+#ifdef FEAT_PATH_EXTRA
+    char_u		*wc_path;
+#endif
+{
+    ff_visited_T	*vp;
+#ifdef UNIX
+    struct stat		st;
+    int			url = FALSE;
+#endif
+
+    /* For an URL we only compare the name, otherwise we compare the
+     * device/inode (unix) or the full path name (not Unix). */
+    if (path_with_url(fname))
+    {
+	vim_strncpy(ff_expand_buffer, fname, MAXPATHL - 1);
+#ifdef UNIX
+	url = TRUE;
+#endif
+    }
+    else
+    {
+	ff_expand_buffer[0] = NUL;
+#ifdef UNIX
+	if (mch_stat((char *)fname, &st) < 0)
+#else
+	if (vim_FullName(fname, ff_expand_buffer, MAXPATHL, TRUE) == FAIL)
+#endif
+	    return FAIL;
+    }
+
+    /* check against list of already visited files */
+    for (vp = *visited_list; vp != NULL; vp = vp->ffv_next)
+    {
+	if (
+#ifdef UNIX
+		!url
+		    ? (vp->ffv_dev == st.st_dev
+			&& vp->ffv_ino == st.st_ino)
+		    :
+#endif
+		fnamecmp(vp->ffv_fname, ff_expand_buffer) == 0
+	   )
+	{
+#ifdef FEAT_PATH_EXTRA
+	    /* are the wildcard parts equal */
+	    if (ff_wc_equal(vp->ffv_wc_path, wc_path) == TRUE)
+#endif
+		/* already visited */
+		return FAIL;
+	}
+    }
+
+    /*
+     * New file/dir.  Add it to the list of visited files/dirs.
+     */
+    vp = (ff_visited_T *)alloc((unsigned)(sizeof(ff_visited_T)
+						 + STRLEN(ff_expand_buffer)));
+
+    if (vp != NULL)
+    {
+#ifdef UNIX
+	if (!url)
+	{
+	    vp->ffv_ino = st.st_ino;
+	    vp->ffv_dev = st.st_dev;
+	    vp->ffv_fname[0] = NUL;
+	}
+	else
+	{
+	    vp->ffv_ino = 0;
+	    vp->ffv_dev = -1;
+#endif
+	    STRCPY(vp->ffv_fname, ff_expand_buffer);
+#ifdef UNIX
+	}
+#endif
+#ifdef FEAT_PATH_EXTRA
+	if (wc_path != NULL)
+	    vp->ffv_wc_path = vim_strsave(wc_path);
+	else
+	    vp->ffv_wc_path = NULL;
+#endif
+
+	vp->ffv_next = *visited_list;
+	*visited_list = vp;
+    }
+
+    return OK;
+}
+
+/*
+ * create stack element from given path pieces
+ */
+    static ff_stack_T *
+ff_create_stack_element(fix_part,
+#ifdef FEAT_PATH_EXTRA
+	wc_part,
+#endif
+	level, star_star_empty)
+    char_u	*fix_part;
+#ifdef FEAT_PATH_EXTRA
+    char_u	*wc_part;
+#endif
+    int		level;
+    int		star_star_empty;
+{
+    ff_stack_T	*new;
+
+    new = (ff_stack_T *)alloc((unsigned)sizeof(ff_stack_T));
+    if (new == NULL)
+	return NULL;
+
+    new->ffs_prev	   = NULL;
+    new->ffs_filearray	   = NULL;
+    new->ffs_filearray_size = 0;
+    new->ffs_filearray_cur  = 0;
+    new->ffs_stage	   = 0;
+    new->ffs_level	   = level;
+    new->ffs_star_star_empty = star_star_empty;;
+
+    /* the following saves NULL pointer checks in vim_findfile */
+    if (fix_part == NULL)
+	fix_part = (char_u *)"";
+    new->ffs_fix_path = vim_strsave(fix_part);
+
+#ifdef FEAT_PATH_EXTRA
+    if (wc_part == NULL)
+	wc_part  = (char_u *)"";
+    new->ffs_wc_path = vim_strsave(wc_part);
+#endif
+
+    if (new->ffs_fix_path == NULL
+#ifdef FEAT_PATH_EXTRA
+	    || new->ffs_wc_path == NULL
+#endif
+	    )
+    {
+	ff_free_stack_element(new);
+	new = NULL;
+    }
+
+    return new;
+}
+
+/*
+ * push a dir on the directory stack
+ */
+    static void
+ff_push(ctx)
+    ff_stack_T *ctx;
+{
+    /* check for NULL pointer, not to return an error to the user, but
+     * to prevent a crash */
+    if (ctx != NULL)
+    {
+	ctx->ffs_prev   = ff_search_ctx->ffsc_stack_ptr;
+	ff_search_ctx->ffsc_stack_ptr = ctx;
+    }
+}
+
+/*
+ * pop a dir from the directory stack
+ * returns NULL if stack is empty
+ */
+    static ff_stack_T *
+ff_pop()
+{
+    ff_stack_T  *sptr;
+
+    sptr = ff_search_ctx->ffsc_stack_ptr;
+    if (ff_search_ctx->ffsc_stack_ptr != NULL)
+	ff_search_ctx->ffsc_stack_ptr = ff_search_ctx->ffsc_stack_ptr->ffs_prev;
+
+    return sptr;
+}
+
+/*
+ * free the given stack element
+ */
+    static void
+ff_free_stack_element(ctx)
+    ff_stack_T  *ctx;
+{
+    /* vim_free handles possible NULL pointers */
+    vim_free(ctx->ffs_fix_path);
+#ifdef FEAT_PATH_EXTRA
+    vim_free(ctx->ffs_wc_path);
+#endif
+
+    if (ctx->ffs_filearray != NULL)
+	FreeWild(ctx->ffs_filearray_size, ctx->ffs_filearray);
+
+    vim_free(ctx);
+}
+
+/*
+ * clear the search context
+ */
+    static void
+ff_clear()
+{
+    ff_stack_T   *sptr;
+
+    /* clear up stack */
+    while ((sptr = ff_pop()) != NULL)
+	ff_free_stack_element(sptr);
+
+    vim_free(ff_search_ctx->ffsc_file_to_search);
+    vim_free(ff_search_ctx->ffsc_start_dir);
+    vim_free(ff_search_ctx->ffsc_fix_path);
+#ifdef FEAT_PATH_EXTRA
+    vim_free(ff_search_ctx->ffsc_wc_path);
+#endif
+
+#ifdef FEAT_PATH_EXTRA
+    if (ff_search_ctx->ffsc_stopdirs_v != NULL)
+    {
+	int  i = 0;
+
+	while (ff_search_ctx->ffsc_stopdirs_v[i] != NULL)
+	{
+	    vim_free(ff_search_ctx->ffsc_stopdirs_v[i]);
+	    i++;
+	}
+	vim_free(ff_search_ctx->ffsc_stopdirs_v);
+    }
+    ff_search_ctx->ffsc_stopdirs_v = NULL;
+#endif
+
+    /* reset everything */
+    ff_search_ctx->ffsc_file_to_search	= NULL;
+    ff_search_ctx->ffsc_start_dir	= NULL;
+    ff_search_ctx->ffsc_fix_path	= NULL;
+#ifdef FEAT_PATH_EXTRA
+    ff_search_ctx->ffsc_wc_path		= NULL;
+    ff_search_ctx->ffsc_level		= 0;
+#endif
+}
+
+#ifdef FEAT_PATH_EXTRA
+/*
+ * check if the given path is in the stopdirs
+ * returns TRUE if yes else FALSE
+ */
+    static int
+ff_path_in_stoplist(path, path_len, stopdirs_v)
+    char_u	*path;
+    int		path_len;
+    char_u	**stopdirs_v;
+{
+    int		i = 0;
+
+    /* eat up trailing path separators, except the first */
+    while (path_len > 1 && vim_ispathsep(path[path_len - 1]))
+	path_len--;
+
+    /* if no path consider it as match */
+    if (path_len == 0)
+	return TRUE;
+
+    for (i = 0; stopdirs_v[i] != NULL; i++)
+    {
+	if ((int)STRLEN(stopdirs_v[i]) > path_len)
+	{
+	    /* match for parent directory. So '/home' also matches
+	     * '/home/rks'. Check for PATHSEP in stopdirs_v[i], else
+	     * '/home/r' would also match '/home/rks'
+	     */
+	    if (fnamencmp(stopdirs_v[i], path, path_len) == 0
+		    && vim_ispathsep(stopdirs_v[i][path_len]))
+		return TRUE;
+	}
+	else
+	{
+	    if (fnamecmp(stopdirs_v[i], path) == 0)
+		return TRUE;
+	}
+    }
+    return FALSE;
+}
+#endif
+
+#if defined(FEAT_SEARCHPATH) || defined(PROTO)
+/*
+ * Find the file name "ptr[len]" in the path.
+ *
+ * On the first call set the parameter 'first' to TRUE to initialize
+ * the search.  For repeating calls to FALSE.
+ *
+ * Repeating calls will return other files called 'ptr[len]' from the path.
+ *
+ * Only on the first call 'ptr' and 'len' are used.  For repeating calls they
+ * don't need valid values.
+ *
+ * If nothing found on the first call the option FNAME_MESS will issue the
+ * message:
+ *	    'Can't find file "<file>" in path'
+ * On repeating calls:
+ *	    'No more file "<file>" found in path'
+ *
+ * options:
+ * FNAME_MESS	    give error message when not found
+ *
+ * Uses NameBuff[]!
+ *
+ * Returns an allocated string for the file name.  NULL for error.
+ *
+ */
+    char_u *
+find_file_in_path(ptr, len, options, first, rel_fname)
+    char_u	*ptr;		/* file name */
+    int		len;		/* length of file name */
+    int		options;
+    int		first;		/* use count'th matching file name */
+    char_u	*rel_fname;	/* file name searching relative to */
+{
+    return find_file_in_path_option(ptr, len, options, first,
+	    *curbuf->b_p_path == NUL ? p_path : curbuf->b_p_path,
+	    FALSE, rel_fname, curbuf->b_p_sua);
+}
+
+static char_u	*ff_file_to_find = NULL;
+static void	*fdip_search_ctx = NULL;
+
+#if defined(EXITFREE)
+    static void
+free_findfile()
+{
+    vim_free(ff_file_to_find);
+    vim_findfile_cleanup(fdip_search_ctx);
+}
+#endif
+
+/*
+ * Find the directory name "ptr[len]" in the path.
+ *
+ * options:
+ * FNAME_MESS	    give error message when not found
+ *
+ * Uses NameBuff[]!
+ *
+ * Returns an allocated string for the file name.  NULL for error.
+ */
+    char_u *
+find_directory_in_path(ptr, len, options, rel_fname)
+    char_u	*ptr;		/* file name */
+    int		len;		/* length of file name */
+    int		options;
+    char_u	*rel_fname;	/* file name searching relative to */
+{
+    return find_file_in_path_option(ptr, len, options, TRUE, p_cdpath,
+					       TRUE, rel_fname, (char_u *)"");
+}
+
+    char_u *
+find_file_in_path_option(ptr, len, options, first, path_option, need_dir, rel_fname, suffixes)
+    char_u	*ptr;		/* file name */
+    int		len;		/* length of file name */
+    int		options;
+    int		first;		/* use count'th matching file name */
+    char_u	*path_option;	/* p_path or p_cdpath */
+    int		need_dir;	/* looking for directory name */
+    char_u	*rel_fname;	/* file name we are looking relative to. */
+    char_u	*suffixes;	/* list of suffixes, 'suffixesadd' option */
+{
+    static char_u	*dir;
+    static int		did_findfile_init = FALSE;
+    char_u		save_char;
+    char_u		*file_name = NULL;
+    char_u		*buf = NULL;
+    int			rel_to_curdir;
+#ifdef AMIGA
+    struct Process	*proc = (struct Process *)FindTask(0L);
+    APTR		save_winptr = proc->pr_WindowPtr;
+
+    /* Avoid a requester here for a volume that doesn't exist. */
+    proc->pr_WindowPtr = (APTR)-1L;
+#endif
+
+    if (first == TRUE)
+    {
+	/* copy file name into NameBuff, expanding environment variables */
+	save_char = ptr[len];
+	ptr[len] = NUL;
+	expand_env(ptr, NameBuff, MAXPATHL);
+	ptr[len] = save_char;
+
+	vim_free(ff_file_to_find);
+	ff_file_to_find = vim_strsave(NameBuff);
+	if (ff_file_to_find == NULL)	/* out of memory */
+	{
+	    file_name = NULL;
+	    goto theend;
+	}
+    }
+
+    rel_to_curdir = (ff_file_to_find[0] == '.'
+		    && (ff_file_to_find[1] == NUL
+			|| vim_ispathsep(ff_file_to_find[1])
+			|| (ff_file_to_find[1] == '.'
+			    && (ff_file_to_find[2] == NUL
+				|| vim_ispathsep(ff_file_to_find[2])))));
+    if (vim_isAbsName(ff_file_to_find)
+	    /* "..", "../path", "." and "./path": don't use the path_option */
+	    || rel_to_curdir
+#if defined(MSWIN) || defined(MSDOS) || defined(OS2)
+	    /* handle "\tmp" as absolute path */
+	    || vim_ispathsep(ff_file_to_find[0])
+	    /* handle "c:name" as absulute path */
+	    || (ff_file_to_find[0] != NUL && ff_file_to_find[1] == ':')
+#endif
+#ifdef AMIGA
+	    /* handle ":tmp" as absolute path */
+	    || ff_file_to_find[0] == ':'
+#endif
+       )
+    {
+	/*
+	 * Absolute path, no need to use "path_option".
+	 * If this is not a first call, return NULL.  We already returned a
+	 * filename on the first call.
+	 */
+	if (first == TRUE)
+	{
+	    int		l;
+	    int		run;
+
+	    if (path_with_url(ff_file_to_find))
+	    {
+		file_name = vim_strsave(ff_file_to_find);
+		goto theend;
+	    }
+
+	    /* When FNAME_REL flag given first use the directory of the file.
+	     * Otherwise or when this fails use the current directory. */
+	    for (run = 1; run <= 2; ++run)
+	    {
+		l = (int)STRLEN(ff_file_to_find);
+		if (run == 1
+			&& rel_to_curdir
+			&& (options & FNAME_REL)
+			&& rel_fname != NULL
+			&& STRLEN(rel_fname) + l < MAXPATHL)
+		{
+		    STRCPY(NameBuff, rel_fname);
+		    STRCPY(gettail(NameBuff), ff_file_to_find);
+		    l = (int)STRLEN(NameBuff);
+		}
+		else
+		{
+		    STRCPY(NameBuff, ff_file_to_find);
+		    run = 2;
+		}
+
+		/* When the file doesn't exist, try adding parts of
+		 * 'suffixesadd'. */
+		buf = suffixes;
+		for (;;)
+		{
+		    if (
+#ifdef DJGPP
+			    /* "C:" by itself will fail for mch_getperm(),
+			     * assume it's always valid. */
+			    (need_dir && NameBuff[0] != NUL
+				  && NameBuff[1] == ':'
+				  && NameBuff[2] == NUL) ||
+#endif
+			    (mch_getperm(NameBuff) >= 0
+				       && (!need_dir || mch_isdir(NameBuff))))
+		    {
+			file_name = vim_strsave(NameBuff);
+			goto theend;
+		    }
+		    if (*buf == NUL)
+			break;
+		    copy_option_part(&buf, NameBuff + l, MAXPATHL - l, ",");
+		}
+	    }
+	}
+    }
+    else
+    {
+	/*
+	 * Loop over all paths in the 'path' or 'cdpath' option.
+	 * When "first" is set, first setup to the start of the option.
+	 * Otherwise continue to find the next match.
+	 */
+	if (first == TRUE)
+	{
+	    /* vim_findfile_free_visited can handle a possible NULL pointer */
+	    vim_findfile_free_visited(fdip_search_ctx);
+	    dir = path_option;
+	    did_findfile_init = FALSE;
+	}
+
+	for (;;)
+	{
+	    if (did_findfile_init)
+	    {
+		ff_search_ctx->ffsc_need_dir = need_dir;
+		file_name = vim_findfile(fdip_search_ctx);
+		ff_search_ctx->ffsc_need_dir = FALSE;
+		if (file_name != NULL)
+		    break;
+
+		did_findfile_init = FALSE;
+	    }
+	    else
+	    {
+		char_u  *r_ptr;
+
+		if (dir == NULL || *dir == NUL)
+		{
+		    /* We searched all paths of the option, now we can
+		     * free the search context. */
+		    vim_findfile_cleanup(fdip_search_ctx);
+		    fdip_search_ctx = NULL;
+		    break;
+		}
+
+		if ((buf = alloc((int)(MAXPATHL))) == NULL)
+		    break;
+
+		/* copy next path */
+		buf[0] = 0;
+		copy_option_part(&dir, buf, MAXPATHL, " ,");
+
+#ifdef FEAT_PATH_EXTRA
+		/* get the stopdir string */
+		r_ptr = vim_findfile_stopdir(buf);
+#else
+		r_ptr = NULL;
+#endif
+		fdip_search_ctx = vim_findfile_init(buf, ff_file_to_find,
+					    r_ptr, 100, FALSE, TRUE,
+					   fdip_search_ctx, FALSE, rel_fname);
+		if (fdip_search_ctx != NULL)
+		    did_findfile_init = TRUE;
+		vim_free(buf);
+	    }
+	}
+    }
+    if (file_name == NULL && (options & FNAME_MESS))
+    {
+	if (first == TRUE)
+	{
+	    if (need_dir)
+		EMSG2(_("E344: Can't find directory \"%s\" in cdpath"),
+			ff_file_to_find);
+	    else
+		EMSG2(_("E345: Can't find file \"%s\" in path"),
+			ff_file_to_find);
+	}
+	else
+	{
+	    if (need_dir)
+		EMSG2(_("E346: No more directory \"%s\" found in cdpath"),
+			ff_file_to_find);
+	    else
+		EMSG2(_("E347: No more file \"%s\" found in path"),
+			ff_file_to_find);
+	}
+    }
+
+theend:
+#ifdef AMIGA
+    proc->pr_WindowPtr = save_winptr;
+#endif
+    return file_name;
+}
+
+#endif /* FEAT_SEARCHPATH */
+
+/*
+ * Change directory to "new_dir".  If FEAT_SEARCHPATH is defined, search
+ * 'cdpath' for relative directory names, otherwise just mch_chdir().
+ */
+    int
+vim_chdir(new_dir)
+    char_u	*new_dir;
+{
+#ifndef FEAT_SEARCHPATH
+    return mch_chdir((char *)new_dir);
+#else
+    char_u	*dir_name;
+    int		r;
+
+    dir_name = find_directory_in_path(new_dir, (int)STRLEN(new_dir),
+						FNAME_MESS, curbuf->b_ffname);
+    if (dir_name == NULL)
+	return -1;
+    r = mch_chdir((char *)dir_name);
+    vim_free(dir_name);
+    return r;
+#endif
+}
+
+/*
+ * Get user name from machine-specific function.
+ * Returns the user name in "buf[len]".
+ * Some systems are quite slow in obtaining the user name (Windows NT), thus
+ * cache the result.
+ * Returns OK or FAIL.
+ */
+    int
+get_user_name(buf, len)
+    char_u	*buf;
+    int		len;
+{
+    if (username == NULL)
+    {
+	if (mch_get_user_name(buf, len) == FAIL)
+	    return FAIL;
+	username = vim_strsave(buf);
+    }
+    else
+	vim_strncpy(buf, username, len - 1);
+    return OK;
+}
+
+#ifndef HAVE_QSORT
+/*
+ * Our own qsort(), for systems that don't have it.
+ * It's simple and slow.  From the K&R C book.
+ */
+    void
+qsort(base, elm_count, elm_size, cmp)
+    void	*base;
+    size_t	elm_count;
+    size_t	elm_size;
+    int (*cmp) __ARGS((const void *, const void *));
+{
+    char_u	*buf;
+    char_u	*p1;
+    char_u	*p2;
+    int		i, j;
+    int		gap;
+
+    buf = alloc((unsigned)elm_size);
+    if (buf == NULL)
+	return;
+
+    for (gap = elm_count / 2; gap > 0; gap /= 2)
+	for (i = gap; i < elm_count; ++i)
+	    for (j = i - gap; j >= 0; j -= gap)
+	    {
+		/* Compare the elements. */
+		p1 = (char_u *)base + j * elm_size;
+		p2 = (char_u *)base + (j + gap) * elm_size;
+		if ((*cmp)((void *)p1, (void *)p2) <= 0)
+		    break;
+		/* Exchange the elemets. */
+		mch_memmove(buf, p1, elm_size);
+		mch_memmove(p1, p2, elm_size);
+		mch_memmove(p2, buf, elm_size);
+	    }
+
+    vim_free(buf);
+}
+#endif
+
+/*
+ * Sort an array of strings.
+ */
+static int
+#ifdef __BORLANDC__
+_RTLENTRYF
+#endif
+sort_compare __ARGS((const void *s1, const void *s2));
+
+    static int
+#ifdef __BORLANDC__
+_RTLENTRYF
+#endif
+sort_compare(s1, s2)
+    const void	*s1;
+    const void	*s2;
+{
+    return STRCMP(*(char **)s1, *(char **)s2);
+}
+
+    void
+sort_strings(files, count)
+    char_u	**files;
+    int		count;
+{
+    qsort((void *)files, (size_t)count, sizeof(char_u *), sort_compare);
+}
+
+#if !defined(NO_EXPANDPATH) || defined(PROTO)
+/*
+ * Compare path "p[]" to "q[]".
+ * If "maxlen" >= 0 compare "p[maxlen]" to "q[maxlen]"
+ * Return value like strcmp(p, q), but consider path separators.
+ */
+    int
+pathcmp(p, q, maxlen)
+    const char *p, *q;
+    int maxlen;
+{
+    int		i;
+    const char	*s = NULL;
+
+    for (i = 0; maxlen < 0 || i < maxlen; ++i)
+    {
+	/* End of "p": check if "q" also ends or just has a slash. */
+	if (p[i] == NUL)
+	{
+	    if (q[i] == NUL)  /* full match */
+		return 0;
+	    s = q;
+	    break;
+	}
+
+	/* End of "q": check if "p" just has a slash. */
+	if (q[i] == NUL)
+	{
+	    s = p;
+	    break;
+	}
+
+	if (
+#ifdef CASE_INSENSITIVE_FILENAME
+		TOUPPER_LOC(p[i]) != TOUPPER_LOC(q[i])
+#else
+		p[i] != q[i]
+#endif
+#ifdef BACKSLASH_IN_FILENAME
+		/* consider '/' and '\\' to be equal */
+		&& !((p[i] == '/' && q[i] == '\\')
+		    || (p[i] == '\\' && q[i] == '/'))
+#endif
+		)
+	{
+	    if (vim_ispathsep(p[i]))
+		return -1;
+	    if (vim_ispathsep(q[i]))
+		return 1;
+	    return ((char_u *)p)[i] - ((char_u *)q)[i];	    /* no match */
+	}
+    }
+    if (s == NULL)	/* "i" ran into "maxlen" */
+	return 0;
+
+    /* ignore a trailing slash, but not "//" or ":/" */
+    if (s[i + 1] == NUL
+	    && i > 0
+	    && !after_pathsep((char_u *)s, (char_u *)s + i)
+#ifdef BACKSLASH_IN_FILENAME
+	    && (s[i] == '/' || s[i] == '\\')
+#else
+	    && s[i] == '/'
+#endif
+       )
+	return 0;   /* match with trailing slash */
+    if (s == q)
+	return -1;	    /* no match */
+    return 1;
+}
+#endif
+
+/*
+ * The putenv() implementation below comes from the "screen" program.
+ * Included with permission from Juergen Weigert.
+ * See pty.c for the copyright notice.
+ */
+
+/*
+ *  putenv  --	put value into environment
+ *
+ *  Usage:  i = putenv (string)
+ *    int i;
+ *    char  *string;
+ *
+ *  where string is of the form <name>=<value>.
+ *  Putenv returns 0 normally, -1 on error (not enough core for malloc).
+ *
+ *  Putenv may need to add a new name into the environment, or to
+ *  associate a value longer than the current value with a particular
+ *  name.  So, to make life simpler, putenv() copies your entire
+ *  environment into the heap (i.e. malloc()) from the stack
+ *  (i.e. where it resides when your process is initiated) the first
+ *  time you call it.
+ *
+ *  (history removed, not very interesting.  See the "screen" sources.)
+ */
+
+#if !defined(HAVE_SETENV) && !defined(HAVE_PUTENV)
+
+#define EXTRASIZE 5		/* increment to add to env. size */
+
+static int  envsize = -1;	/* current size of environment */
+#ifndef MACOS_CLASSIC
+extern
+#endif
+       char **environ;		/* the global which is your env. */
+
+static int  findenv __ARGS((char *name)); /* look for a name in the env. */
+static int  newenv __ARGS((void));	/* copy env. from stack to heap */
+static int  moreenv __ARGS((void));	/* incr. size of env. */
+
+    int
+putenv(string)
+    const char *string;
+{
+    int	    i;
+    char    *p;
+
+    if (envsize < 0)
+    {				/* first time putenv called */
+	if (newenv() < 0)	/* copy env. to heap */
+	    return -1;
+    }
+
+    i = findenv((char *)string); /* look for name in environment */
+
+    if (i < 0)
+    {				/* name must be added */
+	for (i = 0; environ[i]; i++);
+	if (i >= (envsize - 1))
+	{			/* need new slot */
+	    if (moreenv() < 0)
+		return -1;
+	}
+	p = (char *)alloc((unsigned)(strlen(string) + 1));
+	if (p == NULL)		/* not enough core */
+	    return -1;
+	environ[i + 1] = 0;	/* new end of env. */
+    }
+    else
+    {				/* name already in env. */
+	p = vim_realloc(environ[i], strlen(string) + 1);
+	if (p == NULL)
+	    return -1;
+    }
+    sprintf(p, "%s", string);	/* copy into env. */
+    environ[i] = p;
+
+    return 0;
+}
+
+    static int
+findenv(name)
+    char *name;
+{
+    char    *namechar, *envchar;
+    int	    i, found;
+
+    found = 0;
+    for (i = 0; environ[i] && !found; i++)
+    {
+	envchar = environ[i];
+	namechar = name;
+	while (*namechar && *namechar != '=' && (*namechar == *envchar))
+	{
+	    namechar++;
+	    envchar++;
+	}
+	found = ((*namechar == '\0' || *namechar == '=') && *envchar == '=');
+    }
+    return found ? i - 1 : -1;
+}
+
+    static int
+newenv()
+{
+    char    **env, *elem;
+    int	    i, esize;
+
+#ifdef MACOS
+    /* for Mac a new, empty environment is created */
+    i = 0;
+#else
+    for (i = 0; environ[i]; i++)
+	;
+#endif
+    esize = i + EXTRASIZE + 1;
+    env = (char **)alloc((unsigned)(esize * sizeof (elem)));
+    if (env == NULL)
+	return -1;
+
+#ifndef MACOS
+    for (i = 0; environ[i]; i++)
+    {
+	elem = (char *)alloc((unsigned)(strlen(environ[i]) + 1));
+	if (elem == NULL)
+	    return -1;
+	env[i] = elem;
+	strcpy(elem, environ[i]);
+    }
+#endif
+
+    env[i] = 0;
+    environ = env;
+    envsize = esize;
+    return 0;
+}
+
+    static int
+moreenv()
+{
+    int	    esize;
+    char    **env;
+
+    esize = envsize + EXTRASIZE;
+    env = (char **)vim_realloc((char *)environ, esize * sizeof (*env));
+    if (env == 0)
+	return -1;
+    environ = env;
+    envsize = esize;
+    return 0;
+}
+
+# ifdef USE_VIMPTY_GETENV
+    char_u *
+vimpty_getenv(string)
+    const char_u *string;
+{
+    int i;
+    char_u *p;
+
+    if (envsize < 0)
+	return NULL;
+
+    i = findenv((char *)string);
+
+    if (i < 0)
+	return NULL;
+
+    p = vim_strchr((char_u *)environ[i], '=');
+    return (p + 1);
+}
+# endif
+
+#endif /* !defined(HAVE_SETENV) && !defined(HAVE_PUTENV) */
+
+#if defined(FEAT_EVAL) || defined(FEAT_SPELL) || defined(PROTO)
+/*
+ * Return 0 for not writable, 1 for writable file, 2 for a dir which we have
+ * rights to write into.
+ */
+    int
+filewritable(fname)
+    char_u	*fname;
+{
+    int		retval = 0;
+#if defined(UNIX) || defined(VMS)
+    int		perm = 0;
+#endif
+
+#if defined(UNIX) || defined(VMS)
+    perm = mch_getperm(fname);
+#endif
+#ifndef MACOS_CLASSIC /* TODO: get either mch_writable or mch_access */
+    if (
+# ifdef WIN3264
+	    mch_writable(fname) &&
+# else
+# if defined(UNIX) || defined(VMS)
+	    (perm & 0222) &&
+#  endif
+# endif
+	    mch_access((char *)fname, W_OK) == 0
+       )
+#endif
+    {
+	++retval;
+	if (mch_isdir(fname))
+	    ++retval;
+    }
+    return retval;
+}
+#endif
+
+/*
+ * Print an error message with one or two "%s" and one or two string arguments.
+ * This is not in message.c to avoid a warning for prototypes.
+ */
+    int
+emsg3(s, a1, a2)
+    char_u *s, *a1, *a2;
+{
+    if (emsg_not_now())
+	return TRUE;		/* no error messages at the moment */
+    vim_snprintf((char *)IObuff, IOSIZE, (char *)s, (long_u)a1, (long_u)a2);
+    return emsg(IObuff);
+}
+
+/*
+ * Print an error message with one "%ld" and one long int argument.
+ * This is not in message.c to avoid a warning for prototypes.
+ */
+    int
+emsgn(s, n)
+    char_u	*s;
+    long	n;
+{
+    if (emsg_not_now())
+	return TRUE;		/* no error messages at the moment */
+    vim_snprintf((char *)IObuff, IOSIZE, (char *)s, n);
+    return emsg(IObuff);
+}
--- /dev/null
+++ b/mkfile
@@ -1,0 +1,104 @@
+#
+# Makefile for VIM on Plan 9
+#
+
+#>>>>> choose options:
+
+### See feature.h for a list of optionals.
+
+# The root directory for resources.
+#VIMRCLOC=/sys/lib/vim
+VIMRCLOC=./lib
+
+# The runtime files.
+VIMRUNTIMEDIR=$VIMRCLOC/vimfiles
+
+#>>>>> end of choices
+###########################################################################
+
+APE=/sys/src/ape
+<$APE/config
+
+BIN=/$objtype/bin
+
+TARG=\
+	vim\
+	xxd\
+
+VOFILES=\
+	buffer.$O\
+	charset.$O\
+	diff.$O\
+	digraph.$O\
+	edit.$O\
+	eval.$O\
+	ex_cmds.$O\
+	ex_cmds2.$O\
+	ex_docmd.$O\
+	ex_eval.$O\
+	ex_getln.$O\
+	fileio.$O\
+	fold.$O\
+	getchar.$O\
+	hardcopy.$O\
+	hashtab.$O\
+	main.$O\
+	mark.$O\
+	mbyte.$O\
+	memfile.$O\
+	memline.$O\
+	menu.$O\
+	message.$O\
+	misc1.$O\
+	misc2.$O\
+	move.$O\
+	normal.$O\
+	ops.$O\
+	option.$O\
+	os_plan9.$O\
+	pathdef.$O\
+	popupmnu.$O\
+	quickfix.$O\
+	regexp.$O\
+	screen.$O\
+	search.$O\
+	spell.$O\
+	syntax.$O\
+	tag.$O\
+	term.$O\
+	ui.$O\
+	undo.$O\
+	version.$O\
+	window.$O\
+
+</sys/src/cmd/mkmany
+
+CFLAGS=-c -D_POSIX_SOURCE -DPLAN9 -D_PLAN9_SOURCE -Iproto
+
+pathdef.$O:VQ:
+	echo creating pathdef.c...
+	cat > pathdef.c <<EOF
+	/* pathdef.c */
+	#include "vim.h"
+	char_u *default_vim_dir = (char_u *)"$VIMRCLOC";
+	char_u *default_vimruntime_dir = (char_u *)"$VIMRUNTIMEDIR";
+	char_u *all_cflags = (char_u *)"$CC $CFLAGS";
+	char_u *all_lflags = (char_u *)"$LD -o $O.vim";
+	char_u *compiled_user = (char_u *)"$user";
+	char_u *compiled_sys = (char_u *)"$sysname";
+	EOF
+	$CC $CFLAGS pathdef.c
+
+# version.c is compiled each time, so that it sets the build time.
+version.$O:V:
+	$CC $CFLAGS version.c
+
+# be stricter on our own code.
+os_plan9.$O: os_plan9.c
+	$CC $CFLAGS -FVw $prereq
+
+$O.vim:V:	$VOFILES
+	$LD -o $target $prereq
+
+$O.xxd:	xxd/xxd.c
+	$CC -D_POSIX_SOURCE -o $target $prereq
--- /dev/null
+++ b/move.c
@@ -1,0 +1,2859 @@
+/* vi:set ts=8 sts=4 sw=4:
+ *
+ * VIM - Vi IMproved	by Bram Moolenaar
+ *
+ * Do ":help uganda"  in Vim to read copying and usage conditions.
+ * Do ":help credits" in Vim to see a list of people who contributed.
+ * See README.txt for an overview of the Vim source code.
+ */
+/*
+ * move.c: Functions for moving the cursor and scrolling text.
+ *
+ * There are two ways to move the cursor:
+ * 1. Move the cursor directly, the text is scrolled to keep the cursor in the
+ *    window.
+ * 2. Scroll the text, the cursor is moved into the text visible in the
+ *    window.
+ * The 'scrolloff' option makes this a bit complicated.
+ */
+
+#include "vim.h"
+
+static void comp_botline __ARGS((win_T *wp));
+static int scrolljump_value __ARGS((void));
+static int check_top_offset __ARGS((void));
+static void curs_rows __ARGS((win_T *wp, int do_botline));
+static void validate_botline_win __ARGS((win_T *wp));
+static void validate_cheight __ARGS((void));
+
+typedef struct
+{
+    linenr_T	    lnum;	/* line number */
+#ifdef FEAT_DIFF
+    int		    fill;	/* filler lines */
+#endif
+    int		    height;	/* height of added line */
+} lineoff_T;
+
+static void topline_back __ARGS((lineoff_T *lp));
+static void botline_forw __ARGS((lineoff_T *lp));
+#ifdef FEAT_DIFF
+static void botline_topline __ARGS((lineoff_T *lp));
+static void topline_botline __ARGS((lineoff_T *lp));
+static void max_topfill __ARGS((void));
+#endif
+
+/*
+ * Compute wp->w_botline for the current wp->w_topline.  Can be called after
+ * wp->w_topline changed.
+ */
+    static void
+comp_botline(wp)
+    win_T	*wp;
+{
+    int		n;
+    linenr_T	lnum;
+    int		done;
+#ifdef FEAT_FOLDING
+    linenr_T    last;
+    int		folded;
+#endif
+
+    /*
+     * If w_cline_row is valid, start there.
+     * Otherwise have to start at w_topline.
+     */
+    check_cursor_moved(wp);
+    if (wp->w_valid & VALID_CROW)
+    {
+	lnum = wp->w_cursor.lnum;
+	done = wp->w_cline_row;
+    }
+    else
+    {
+	lnum = wp->w_topline;
+	done = 0;
+    }
+
+    for ( ; lnum <= wp->w_buffer->b_ml.ml_line_count; ++lnum)
+    {
+#ifdef FEAT_FOLDING
+	last = lnum;
+	folded = FALSE;
+	if (hasFoldingWin(wp, lnum, NULL, &last, TRUE, NULL))
+	{
+	    n = 1;
+	    folded = TRUE;
+	}
+	else
+#endif
+#ifdef FEAT_DIFF
+	    if (lnum == wp->w_topline)
+		n = plines_win_nofill(wp, lnum, TRUE) + wp->w_topfill;
+	    else
+#endif
+		n = plines_win(wp, lnum, TRUE);
+	if (
+#ifdef FEAT_FOLDING
+		lnum <= wp->w_cursor.lnum && last >= wp->w_cursor.lnum
+#else
+		lnum == wp->w_cursor.lnum
+#endif
+	   )
+	{
+	    wp->w_cline_row = done;
+	    wp->w_cline_height = n;
+#ifdef FEAT_FOLDING
+	    wp->w_cline_folded = folded;
+#endif
+	    wp->w_valid |= (VALID_CROW|VALID_CHEIGHT);
+	}
+	if (done + n > wp->w_height)
+	    break;
+	done += n;
+#ifdef FEAT_FOLDING
+	lnum = last;
+#endif
+    }
+
+    /* wp->w_botline is the line that is just below the window */
+    wp->w_botline = lnum;
+    wp->w_valid |= VALID_BOTLINE|VALID_BOTLINE_AP;
+
+    set_empty_rows(wp, done);
+}
+
+/*
+ * Update curwin->w_topline and redraw if necessary.
+ * Used to update the screen before printing a message.
+ */
+    void
+update_topline_redraw()
+{
+    update_topline();
+    if (must_redraw)
+	update_screen(0);
+}
+
+/*
+ * Update curwin->w_topline to move the cursor onto the screen.
+ */
+    void
+update_topline()
+{
+    long	line_count;
+    int		halfheight;
+    int		n;
+    linenr_T	old_topline;
+#ifdef FEAT_DIFF
+    int		old_topfill;
+#endif
+#ifdef FEAT_FOLDING
+    linenr_T	lnum;
+#endif
+    int		check_topline = FALSE;
+    int		check_botline = FALSE;
+#ifdef FEAT_MOUSE
+    int		save_so = p_so;
+#endif
+
+    if (!screen_valid(TRUE))
+	return;
+
+    check_cursor_moved(curwin);
+    if (curwin->w_valid & VALID_TOPLINE)
+	return;
+
+#ifdef FEAT_MOUSE
+    /* When dragging with the mouse, don't scroll that quickly */
+    if (mouse_dragging > 0)
+	p_so = mouse_dragging - 1;
+#endif
+
+    old_topline = curwin->w_topline;
+#ifdef FEAT_DIFF
+    old_topfill = curwin->w_topfill;
+#endif
+
+    /*
+     * If the buffer is empty, always set topline to 1.
+     */
+    if (bufempty())		/* special case - file is empty */
+    {
+	if (curwin->w_topline != 1)
+	    redraw_later(NOT_VALID);
+	curwin->w_topline = 1;
+#ifdef FEAT_DIFF
+	curwin->w_topfill = 0;
+#endif
+	curwin->w_botline = 2;
+	curwin->w_valid |= VALID_BOTLINE|VALID_BOTLINE_AP;
+#ifdef FEAT_SCROLLBIND
+	curwin->w_scbind_pos = 1;
+#endif
+    }
+
+    /*
+     * If the cursor is above or near the top of the window, scroll the window
+     * to show the line the cursor is in, with 'scrolloff' context.
+     */
+    else
+    {
+	if (curwin->w_topline > 1)
+	{
+	    /* If the cursor is above topline, scrolling is always needed.
+	     * If the cursor is far below topline and there is no folding,
+	     * scrolling down is never needed. */
+	    if (curwin->w_cursor.lnum < curwin->w_topline)
+		check_topline = TRUE;
+	    else if (check_top_offset())
+		check_topline = TRUE;
+	}
+#ifdef FEAT_DIFF
+	    /* Check if there are more filler lines than allowed. */
+	if (!check_topline && curwin->w_topfill > diff_check_fill(curwin,
+							   curwin->w_topline))
+	    check_topline = TRUE;
+#endif
+
+	if (check_topline)
+	{
+	    halfheight = curwin->w_height / 2 - 1;
+	    if (halfheight < 2)
+		halfheight = 2;
+
+#ifdef FEAT_FOLDING
+	    if (hasAnyFolding(curwin))
+	    {
+		/* Count the number of logical lines between the cursor and
+		 * topline + p_so (approximation of how much will be
+		 * scrolled). */
+		n = 0;
+		for (lnum = curwin->w_cursor.lnum;
+				      lnum < curwin->w_topline + p_so; ++lnum)
+		{
+		    ++n;
+		    /* stop at end of file or when we know we are far off */
+		    if (lnum >= curbuf->b_ml.ml_line_count || n >= halfheight)
+			break;
+		    (void)hasFolding(lnum, NULL, &lnum);
+		}
+	    }
+	    else
+#endif
+		n = curwin->w_topline + p_so - curwin->w_cursor.lnum;
+
+	    /* If we weren't very close to begin with, we scroll to put the
+	     * cursor in the middle of the window.  Otherwise put the cursor
+	     * near the top of the window. */
+	    if (n >= halfheight)
+		scroll_cursor_halfway(FALSE);
+	    else
+	    {
+		scroll_cursor_top(scrolljump_value(), FALSE);
+		check_botline = TRUE;
+	    }
+	}
+
+	else
+	{
+#ifdef FEAT_FOLDING
+	    /* Make sure topline is the first line of a fold. */
+	    (void)hasFolding(curwin->w_topline, &curwin->w_topline, NULL);
+#endif
+	    check_botline = TRUE;
+	}
+    }
+
+    /*
+     * If the cursor is below the bottom of the window, scroll the window
+     * to put the cursor on the window.
+     * When w_botline is invalid, recompute it first, to avoid a redraw later.
+     * If w_botline was approximated, we might need a redraw later in a few
+     * cases, but we don't want to spend (a lot of) time recomputing w_botline
+     * for every small change.
+     */
+    if (check_botline)
+    {
+	if (!(curwin->w_valid & VALID_BOTLINE_AP))
+	    validate_botline();
+
+	if (curwin->w_botline <= curbuf->b_ml.ml_line_count)
+	{
+	    if (curwin->w_cursor.lnum < curwin->w_botline
+		    && ((long)curwin->w_cursor.lnum
+					     >= (long)curwin->w_botline - p_so
+#ifdef FEAT_FOLDING
+			|| hasAnyFolding(curwin)
+#endif
+			))
+	    {
+		lineoff_T	loff;
+
+		/* Cursor is above botline, check if there are 'scrolloff'
+		 * window lines below the cursor.  If not, need to scroll. */
+		n = curwin->w_empty_rows;
+		loff.lnum = curwin->w_cursor.lnum;
+#ifdef FEAT_FOLDING
+		/* In a fold go to its last line. */
+		(void)hasFolding(loff.lnum, NULL, &loff.lnum);
+#endif
+#ifdef FEAT_DIFF
+		loff.fill = 0;
+		n += curwin->w_filler_rows;
+#endif
+		loff.height = 0;
+		while (loff.lnum < curwin->w_botline
+#ifdef FEAT_DIFF
+			&& (loff.lnum + 1 < curwin->w_botline || loff.fill == 0)
+#endif
+			)
+		{
+		    n += loff.height;
+		    if (n >= p_so)
+			break;
+		    botline_forw(&loff);
+		}
+		if (n >= p_so)
+		    /* sufficient context, no need to scroll */
+		    check_botline = FALSE;
+	    }
+	    if (check_botline)
+	    {
+#ifdef FEAT_FOLDING
+		if (hasAnyFolding(curwin))
+		{
+		    /* Count the number of logical lines between the cursor and
+		     * botline - p_so (approximation of how much will be
+		     * scrolled). */
+		    line_count = 0;
+		    for (lnum = curwin->w_cursor.lnum;
+				     lnum >= curwin->w_botline - p_so; --lnum)
+		    {
+			++line_count;
+			/* stop at end of file or when we know we are far off */
+			if (lnum <= 0 || line_count > curwin->w_height + 1)
+			    break;
+			(void)hasFolding(lnum, &lnum, NULL);
+		    }
+		}
+		else
+#endif
+		    line_count = curwin->w_cursor.lnum - curwin->w_botline
+								   + 1 + p_so;
+		if (line_count <= curwin->w_height + 1)
+		    scroll_cursor_bot(scrolljump_value(), FALSE);
+		else
+		    scroll_cursor_halfway(FALSE);
+	    }
+	}
+    }
+    curwin->w_valid |= VALID_TOPLINE;
+
+    /*
+     * Need to redraw when topline changed.
+     */
+    if (curwin->w_topline != old_topline
+#ifdef FEAT_DIFF
+	    || curwin->w_topfill != old_topfill
+#endif
+	    )
+    {
+	dollar_vcol = 0;
+	if (curwin->w_skipcol != 0)
+	{
+	    curwin->w_skipcol = 0;
+	    redraw_later(NOT_VALID);
+	}
+	else
+	    redraw_later(VALID);
+	/* May need to set w_skipcol when cursor in w_topline. */
+	if (curwin->w_cursor.lnum == curwin->w_topline)
+	    validate_cursor();
+    }
+
+#ifdef FEAT_MOUSE
+    p_so = save_so;
+#endif
+}
+
+/*
+ * Return the scrolljump value to use for the current window.
+ * When 'scrolljump' is positive use it as-is.
+ * When 'scrolljump' is negative use it as a percentage of the window height.
+ */
+    static int
+scrolljump_value()
+{
+    if (p_sj >= 0)
+	return (int)p_sj;
+    return (curwin->w_height * -p_sj) / 100;
+}
+
+/*
+ * Return TRUE when there are not 'scrolloff' lines above the cursor for the
+ * current window.
+ */
+    static int
+check_top_offset()
+{
+    lineoff_T	loff;
+    int		n;
+
+    if (curwin->w_cursor.lnum < curwin->w_topline + p_so
+#ifdef FEAT_FOLDING
+		    || hasAnyFolding(curwin)
+#endif
+	    )
+    {
+	loff.lnum = curwin->w_cursor.lnum;
+#ifdef FEAT_DIFF
+	loff.fill = 0;
+	n = curwin->w_topfill;	    /* always have this context */
+#else
+	n = 0;
+#endif
+	/* Count the visible screen lines above the cursor line. */
+	while (n < p_so)
+	{
+	    topline_back(&loff);
+	    /* Stop when included a line above the window. */
+	    if (loff.lnum < curwin->w_topline
+#ifdef FEAT_DIFF
+		    || (loff.lnum == curwin->w_topline && loff.fill > 0)
+#endif
+		    )
+		break;
+	    n += loff.height;
+	}
+	if (n < p_so)
+	    return TRUE;
+    }
+    return FALSE;
+}
+
+    void
+update_curswant()
+{
+    if (curwin->w_set_curswant)
+    {
+	validate_virtcol();
+	curwin->w_curswant = curwin->w_virtcol;
+	curwin->w_set_curswant = FALSE;
+    }
+}
+
+/*
+ * Check if the cursor has moved.  Set the w_valid flag accordingly.
+ */
+    void
+check_cursor_moved(wp)
+    win_T	*wp;
+{
+    if (wp->w_cursor.lnum != wp->w_valid_cursor.lnum)
+    {
+	wp->w_valid &= ~(VALID_WROW|VALID_WCOL|VALID_VIRTCOL
+				     |VALID_CHEIGHT|VALID_CROW|VALID_TOPLINE);
+	wp->w_valid_cursor = wp->w_cursor;
+	wp->w_valid_leftcol = wp->w_leftcol;
+    }
+    else if (wp->w_cursor.col != wp->w_valid_cursor.col
+	     || wp->w_leftcol != wp->w_valid_leftcol
+#ifdef FEAT_VIRTUALEDIT
+	     || wp->w_cursor.coladd != wp->w_valid_cursor.coladd
+#endif
+	     )
+    {
+	wp->w_valid &= ~(VALID_WROW|VALID_WCOL|VALID_VIRTCOL);
+	wp->w_valid_cursor.col = wp->w_cursor.col;
+	wp->w_valid_leftcol = wp->w_leftcol;
+#ifdef FEAT_VIRTUALEDIT
+	wp->w_valid_cursor.coladd = wp->w_cursor.coladd;
+#endif
+    }
+}
+
+/*
+ * Call this function when some window settings have changed, which require
+ * the cursor position, botline and topline to be recomputed and the window to
+ * be redrawn.  E.g, when changing the 'wrap' option or folding.
+ */
+    void
+changed_window_setting()
+{
+    changed_window_setting_win(curwin);
+}
+
+    void
+changed_window_setting_win(wp)
+    win_T	*wp;
+{
+    wp->w_lines_valid = 0;
+    changed_line_abv_curs_win(wp);
+    wp->w_valid &= ~(VALID_BOTLINE|VALID_BOTLINE_AP|VALID_TOPLINE);
+    redraw_win_later(wp, NOT_VALID);
+}
+
+/*
+ * Set wp->w_topline to a certain number.
+ */
+    void
+set_topline(wp, lnum)
+    win_T	*wp;
+    linenr_T	lnum;
+{
+#ifdef FEAT_FOLDING
+    /* go to first of folded lines */
+    (void)hasFoldingWin(wp, lnum, &lnum, NULL, TRUE, NULL);
+#endif
+    /* Approximate the value of w_botline */
+    wp->w_botline += lnum - wp->w_topline;
+    wp->w_topline = lnum;
+#ifdef FEAT_DIFF
+    wp->w_topfill = 0;
+#endif
+    wp->w_valid &= ~(VALID_WROW|VALID_CROW|VALID_BOTLINE|VALID_TOPLINE);
+    /* Don't set VALID_TOPLINE here, 'scrolloff' needs to be checked. */
+    redraw_later(VALID);
+}
+
+/*
+ * Call this function when the length of the cursor line (in screen
+ * characters) has changed, and the change is before the cursor.
+ * Need to take care of w_botline separately!
+ */
+    void
+changed_cline_bef_curs()
+{
+    curwin->w_valid &= ~(VALID_WROW|VALID_WCOL|VALID_VIRTCOL
+						|VALID_CHEIGHT|VALID_TOPLINE);
+}
+
+    void
+changed_cline_bef_curs_win(wp)
+    win_T	*wp;
+{
+    wp->w_valid &= ~(VALID_WROW|VALID_WCOL|VALID_VIRTCOL
+						|VALID_CHEIGHT|VALID_TOPLINE);
+}
+
+#if 0 /* not used */
+/*
+ * Call this function when the length of the cursor line (in screen
+ * characters) has changed, and the position of the cursor doesn't change.
+ * Need to take care of w_botline separately!
+ */
+    void
+changed_cline_aft_curs()
+{
+    curwin->w_valid &= ~VALID_CHEIGHT;
+}
+#endif
+
+/*
+ * Call this function when the length of a line (in screen characters) above
+ * the cursor have changed.
+ * Need to take care of w_botline separately!
+ */
+    void
+changed_line_abv_curs()
+{
+    curwin->w_valid &= ~(VALID_WROW|VALID_WCOL|VALID_VIRTCOL|VALID_CROW
+						|VALID_CHEIGHT|VALID_TOPLINE);
+}
+
+    void
+changed_line_abv_curs_win(wp)
+    win_T	*wp;
+{
+    wp->w_valid &= ~(VALID_WROW|VALID_WCOL|VALID_VIRTCOL|VALID_CROW
+						|VALID_CHEIGHT|VALID_TOPLINE);
+}
+
+/*
+ * Make sure the value of curwin->w_botline is valid.
+ */
+    void
+validate_botline()
+{
+    if (!(curwin->w_valid & VALID_BOTLINE))
+	comp_botline(curwin);
+}
+
+/*
+ * Make sure the value of wp->w_botline is valid.
+ */
+    static void
+validate_botline_win(wp)
+    win_T	*wp;
+{
+    if (!(wp->w_valid & VALID_BOTLINE))
+	comp_botline(wp);
+}
+
+/*
+ * Mark curwin->w_botline as invalid (because of some change in the buffer).
+ */
+    void
+invalidate_botline()
+{
+    curwin->w_valid &= ~(VALID_BOTLINE|VALID_BOTLINE_AP);
+}
+
+    void
+invalidate_botline_win(wp)
+    win_T	*wp;
+{
+    wp->w_valid &= ~(VALID_BOTLINE|VALID_BOTLINE_AP);
+}
+
+#if 0 /* never used */
+/*
+ * Mark curwin->w_botline as approximated (because of some small change in the
+ * buffer).
+ */
+    void
+approximate_botline()
+{
+    curwin->w_valid &= ~VALID_BOTLINE;
+}
+#endif
+
+    void
+approximate_botline_win(wp)
+    win_T	*wp;
+{
+    wp->w_valid &= ~VALID_BOTLINE;
+}
+
+#if 0 /* not used */
+/*
+ * Return TRUE if curwin->w_botline is valid.
+ */
+    int
+botline_valid()
+{
+    return (curwin->w_valid & VALID_BOTLINE);
+}
+#endif
+
+#if 0 /* not used */
+/*
+ * Return TRUE if curwin->w_botline is valid or approximated.
+ */
+    int
+botline_approximated()
+{
+    return (curwin->w_valid & VALID_BOTLINE_AP);
+}
+#endif
+
+/*
+ * Return TRUE if curwin->w_wrow and curwin->w_wcol are valid.
+ */
+    int
+cursor_valid()
+{
+    check_cursor_moved(curwin);
+    return ((curwin->w_valid & (VALID_WROW|VALID_WCOL)) ==
+						      (VALID_WROW|VALID_WCOL));
+}
+
+/*
+ * Validate cursor position.  Makes sure w_wrow and w_wcol are valid.
+ * w_topline must be valid, you may need to call update_topline() first!
+ */
+    void
+validate_cursor()
+{
+    check_cursor_moved(curwin);
+    if ((curwin->w_valid & (VALID_WCOL|VALID_WROW)) != (VALID_WCOL|VALID_WROW))
+	curs_columns(TRUE);
+}
+
+#if defined(FEAT_GUI) || defined(PROTO)
+/*
+ * validate w_cline_row.
+ */
+    void
+validate_cline_row()
+{
+    /*
+     * First make sure that w_topline is valid (after moving the cursor).
+     */
+    update_topline();
+    check_cursor_moved(curwin);
+    if (!(curwin->w_valid & VALID_CROW))
+	curs_rows(curwin, FALSE);
+}
+#endif
+
+/*
+ * Compute wp->w_cline_row and wp->w_cline_height, based on the current value
+ * of wp->w_topine.
+ *
+ * Returns OK when cursor is in the window, FAIL when it isn't.
+ */
+    static void
+curs_rows(wp, do_botline)
+    win_T	*wp;
+    int		do_botline;		/* also compute w_botline */
+{
+    linenr_T	lnum;
+    int		i;
+    int		all_invalid;
+    int		valid;
+#ifdef FEAT_FOLDING
+    long	fold_count;
+#endif
+
+    /* Check if wp->w_lines[].wl_size is invalid */
+    all_invalid = (!redrawing()
+			|| wp->w_lines_valid == 0
+			|| wp->w_lines[0].wl_lnum > wp->w_topline);
+    i = 0;
+    wp->w_cline_row = 0;
+    for (lnum = wp->w_topline; lnum < wp->w_cursor.lnum; ++i)
+    {
+	valid = FALSE;
+	if (!all_invalid && i < wp->w_lines_valid)
+	{
+	    if (wp->w_lines[i].wl_lnum < lnum || !wp->w_lines[i].wl_valid)
+		continue;		/* skip changed or deleted lines */
+	    if (wp->w_lines[i].wl_lnum == lnum)
+	    {
+#ifdef FEAT_FOLDING
+		/* Check for newly inserted lines below this row, in which
+		 * case we need to check for folded lines. */
+		if (!wp->w_buffer->b_mod_set
+			|| wp->w_lines[i].wl_lastlnum < wp->w_cursor.lnum
+			|| wp->w_buffer->b_mod_top
+					     > wp->w_lines[i].wl_lastlnum + 1)
+#endif
+		valid = TRUE;
+	    }
+	    else if (wp->w_lines[i].wl_lnum > lnum)
+		--i;			/* hold at inserted lines */
+	}
+	if (valid
+#ifdef FEAT_DIFF
+		&& (lnum != wp->w_topline || !wp->w_p_diff)
+#endif
+		)
+	{
+#ifdef FEAT_FOLDING
+	    lnum = wp->w_lines[i].wl_lastlnum + 1;
+	    /* Cursor inside folded lines, don't count this row */
+	    if (lnum > wp->w_cursor.lnum)
+		break;
+#else
+	    ++lnum;
+#endif
+	    wp->w_cline_row += wp->w_lines[i].wl_size;
+	}
+	else
+	{
+#ifdef FEAT_FOLDING
+	    fold_count = foldedCount(wp, lnum, NULL);
+	    if (fold_count)
+	    {
+		lnum += fold_count;
+		if (lnum > wp->w_cursor.lnum)
+		    break;
+		++wp->w_cline_row;
+	    }
+	    else
+#endif
+#ifdef FEAT_DIFF
+		if (lnum == wp->w_topline)
+		    wp->w_cline_row += plines_win_nofill(wp, lnum++, TRUE)
+							      + wp->w_topfill;
+		else
+#endif
+		    wp->w_cline_row += plines_win(wp, lnum++, TRUE);
+	}
+    }
+
+    check_cursor_moved(wp);
+    if (!(wp->w_valid & VALID_CHEIGHT))
+    {
+	if (all_invalid
+		|| i == wp->w_lines_valid
+		|| (i < wp->w_lines_valid
+		    && (!wp->w_lines[i].wl_valid
+			|| wp->w_lines[i].wl_lnum != wp->w_cursor.lnum)))
+	{
+#ifdef FEAT_DIFF
+	    if (wp->w_cursor.lnum == wp->w_topline)
+		wp->w_cline_height = plines_win_nofill(wp, wp->w_cursor.lnum,
+							TRUE) + wp->w_topfill;
+	    else
+#endif
+		wp->w_cline_height = plines_win(wp, wp->w_cursor.lnum, TRUE);
+#ifdef FEAT_FOLDING
+	    wp->w_cline_folded = hasFoldingWin(wp, wp->w_cursor.lnum,
+						      NULL, NULL, TRUE, NULL);
+#endif
+	}
+	else if (i > wp->w_lines_valid)
+	{
+	    /* a line that is too long to fit on the last screen line */
+	    wp->w_cline_height = 0;
+#ifdef FEAT_FOLDING
+	    wp->w_cline_folded = hasFoldingWin(wp, wp->w_cursor.lnum,
+						      NULL, NULL, TRUE, NULL);
+#endif
+	}
+	else
+	{
+	    wp->w_cline_height = wp->w_lines[i].wl_size;
+#ifdef FEAT_FOLDING
+	    wp->w_cline_folded = wp->w_lines[i].wl_folded;
+#endif
+	}
+    }
+
+    wp->w_valid |= VALID_CROW|VALID_CHEIGHT;
+
+    /* validate botline too, if update_screen doesn't do it */
+    if (do_botline && all_invalid)
+	validate_botline_win(wp);
+}
+
+/*
+ * Validate curwin->w_virtcol only.
+ */
+    void
+validate_virtcol()
+{
+    validate_virtcol_win(curwin);
+}
+
+/*
+ * Validate wp->w_virtcol only.
+ */
+    void
+validate_virtcol_win(wp)
+    win_T	*wp;
+{
+    check_cursor_moved(wp);
+    if (!(wp->w_valid & VALID_VIRTCOL))
+    {
+	getvvcol(wp, &wp->w_cursor, NULL, &(wp->w_virtcol), NULL);
+	wp->w_valid |= VALID_VIRTCOL;
+#ifdef FEAT_SYN_HL
+	if (wp->w_p_cuc
+# ifdef FEAT_INS_EXPAND
+		&& !pum_visible()
+# endif
+		)
+	    redraw_win_later(wp, SOME_VALID);
+#endif
+    }
+}
+
+/*
+ * Validate curwin->w_cline_height only.
+ */
+    static void
+validate_cheight()
+{
+    check_cursor_moved(curwin);
+    if (!(curwin->w_valid & VALID_CHEIGHT))
+    {
+#ifdef FEAT_DIFF
+	if (curwin->w_cursor.lnum == curwin->w_topline)
+	    curwin->w_cline_height = plines_nofill(curwin->w_cursor.lnum)
+							  + curwin->w_topfill;
+	else
+#endif
+	    curwin->w_cline_height = plines(curwin->w_cursor.lnum);
+#ifdef FEAT_FOLDING
+	curwin->w_cline_folded = hasFolding(curwin->w_cursor.lnum, NULL, NULL);
+#endif
+	curwin->w_valid |= VALID_CHEIGHT;
+    }
+}
+
+/*
+ * validate w_wcol and w_virtcol only.	Only correct when 'wrap' on!
+ */
+    void
+validate_cursor_col()
+{
+    colnr_T off;
+    colnr_T col;
+
+    validate_virtcol();
+    if (!(curwin->w_valid & VALID_WCOL))
+    {
+	col = curwin->w_virtcol;
+	off = curwin_col_off();
+	col += off;
+
+	/* long line wrapping, adjust curwin->w_wrow */
+	if (curwin->w_p_wrap && col >= (colnr_T)W_WIDTH(curwin)
+		&& W_WIDTH(curwin) - off + curwin_col_off2() > 0)
+	{
+	    col -= W_WIDTH(curwin);
+	    col = col % (W_WIDTH(curwin) - off + curwin_col_off2());
+	}
+	curwin->w_wcol = col;
+	curwin->w_valid |= VALID_WCOL;
+    }
+}
+
+/*
+ * Compute offset of a window, occupied by line number, fold column and sign
+ * column (these don't move when scrolling horizontally).
+ */
+    int
+win_col_off(wp)
+    win_T	*wp;
+{
+    return ((wp->w_p_nu ? number_width(wp) + 1 : 0)
+#ifdef FEAT_CMDWIN
+	    + (cmdwin_type == 0 || wp != curwin ? 0 : 1)
+#endif
+#ifdef FEAT_FOLDING
+	    + wp->w_p_fdc
+#endif
+#ifdef FEAT_SIGNS
+	    + (
+# ifdef FEAT_NETBEANS_INTG
+		/* always show glyph gutter in netbeans */
+		usingNetbeans ||
+# endif
+		wp->w_buffer->b_signlist != NULL ? 2 : 0)
+#endif
+	   );
+}
+
+    int
+curwin_col_off()
+{
+    return win_col_off(curwin);
+}
+
+/*
+ * Return the difference in column offset for the second screen line of a
+ * wrapped line.  It's 8 if 'number' is on and 'n' is in 'cpoptions'.
+ */
+    int
+win_col_off2(wp)
+    win_T	*wp;
+{
+    if (wp->w_p_nu && vim_strchr(p_cpo, CPO_NUMCOL) != NULL)
+	return number_width(wp) + 1;
+    return 0;
+}
+
+    int
+curwin_col_off2()
+{
+    return win_col_off2(curwin);
+}
+
+/*
+ * compute curwin->w_wcol and curwin->w_virtcol.
+ * Also updates curwin->w_wrow and curwin->w_cline_row.
+ * Also updates curwin->w_leftcol.
+ */
+    void
+curs_columns(scroll)
+    int		scroll;		/* when TRUE, may scroll horizontally */
+{
+    int		diff;
+    int		extra;		/* offset for first screen line */
+    int		off_left, off_right;
+    int		n;
+    int		p_lines;
+    int		width = 0;
+    int		textwidth;
+    int		new_leftcol;
+    colnr_T	startcol;
+    colnr_T	endcol;
+    colnr_T	prev_skipcol;
+
+    /*
+     * First make sure that w_topline is valid (after moving the cursor).
+     */
+    update_topline();
+
+    /*
+     * Next make sure that w_cline_row is valid.
+     */
+    if (!(curwin->w_valid & VALID_CROW))
+	curs_rows(curwin, FALSE);
+
+    /*
+     * Compute the number of virtual columns.
+     */
+#ifdef FEAT_FOLDING
+    if (curwin->w_cline_folded)
+	/* In a folded line the cursor is always in the first column */
+	startcol = curwin->w_virtcol = endcol = curwin->w_leftcol;
+    else
+#endif
+	getvvcol(curwin, &curwin->w_cursor,
+				&startcol, &(curwin->w_virtcol), &endcol);
+
+    /* remove '$' from change command when cursor moves onto it */
+    if (startcol > dollar_vcol)
+	dollar_vcol = 0;
+
+    extra = curwin_col_off();
+    curwin->w_wcol = curwin->w_virtcol + extra;
+    endcol += extra;
+
+    /*
+     * Now compute w_wrow, counting screen lines from w_cline_row.
+     */
+    curwin->w_wrow = curwin->w_cline_row;
+
+    textwidth = W_WIDTH(curwin) - extra;
+    if (textwidth <= 0)
+    {
+	/* No room for text, put cursor in last char of window. */
+	curwin->w_wcol = W_WIDTH(curwin) - 1;
+	curwin->w_wrow = curwin->w_height - 1;
+    }
+    else if (curwin->w_p_wrap
+#ifdef FEAT_VERTSPLIT
+	    && curwin->w_width != 0
+#endif
+	    )
+    {
+	width = textwidth + curwin_col_off2();
+
+	/* long line wrapping, adjust curwin->w_wrow */
+	if (curwin->w_wcol >= W_WIDTH(curwin))
+	{
+	    n = (curwin->w_wcol - W_WIDTH(curwin)) / width + 1;
+	    curwin->w_wcol -= n * width;
+	    curwin->w_wrow += n;
+
+#ifdef FEAT_LINEBREAK
+	    /* When cursor wraps to first char of next line in Insert
+	     * mode, the 'showbreak' string isn't shown, backup to first
+	     * column */
+	    if (*p_sbr && *ml_get_cursor() == NUL
+		    && curwin->w_wcol == (int)vim_strsize(p_sbr))
+		curwin->w_wcol = 0;
+#endif
+	}
+    }
+
+    /* No line wrapping: compute curwin->w_leftcol if scrolling is on and line
+     * is not folded.
+     * If scrolling is off, curwin->w_leftcol is assumed to be 0 */
+    else if (scroll
+#ifdef FEAT_FOLDING
+	    && !curwin->w_cline_folded
+#endif
+	    )
+    {
+	/*
+	 * If Cursor is left of the screen, scroll rightwards.
+	 * If Cursor is right of the screen, scroll leftwards
+	 * If we get closer to the edge than 'sidescrolloff', scroll a little
+	 * extra
+	 */
+	off_left = (int)startcol - (int)curwin->w_leftcol - p_siso;
+	off_right = (int)endcol - (int)(curwin->w_leftcol + W_WIDTH(curwin)
+								- p_siso) + 1;
+	if (off_left < 0 || off_right > 0)
+	{
+	    if (off_left < 0)
+		diff = -off_left;
+	    else
+		diff = off_right;
+
+	    /* When far off or not enough room on either side, put cursor in
+	     * middle of window. */
+	    if (p_ss == 0 || diff >= textwidth / 2 || off_right >= off_left)
+		new_leftcol = curwin->w_wcol - extra - textwidth / 2;
+	    else
+	    {
+		if (diff < p_ss)
+		    diff = p_ss;
+		if (off_left < 0)
+		    new_leftcol = curwin->w_leftcol - diff;
+		else
+		    new_leftcol = curwin->w_leftcol + diff;
+	    }
+	    if (new_leftcol < 0)
+		new_leftcol = 0;
+	    if (new_leftcol != (int)curwin->w_leftcol)
+	    {
+		curwin->w_leftcol = new_leftcol;
+		/* screen has to be redrawn with new curwin->w_leftcol */
+		redraw_later(NOT_VALID);
+	    }
+	}
+	curwin->w_wcol -= curwin->w_leftcol;
+    }
+    else if (curwin->w_wcol > (int)curwin->w_leftcol)
+	curwin->w_wcol -= curwin->w_leftcol;
+    else
+	curwin->w_wcol = 0;
+
+#ifdef FEAT_DIFF
+    /* Skip over filler lines.  At the top use w_topfill, there
+     * may be some filler lines above the window. */
+    if (curwin->w_cursor.lnum == curwin->w_topline)
+	curwin->w_wrow += curwin->w_topfill;
+    else
+	curwin->w_wrow += diff_check_fill(curwin, curwin->w_cursor.lnum);
+#endif
+
+    prev_skipcol = curwin->w_skipcol;
+
+    p_lines = 0;
+    if ((curwin->w_wrow >= curwin->w_height
+		|| ((prev_skipcol > 0
+			|| curwin->w_wrow + p_so >= curwin->w_height)
+		    && (p_lines =
+#ifdef FEAT_DIFF
+			plines_win_nofill
+#else
+			plines_win
+#endif
+			(curwin, curwin->w_cursor.lnum, FALSE))
+						    - 1 >= curwin->w_height))
+	    && curwin->w_height != 0
+	    && curwin->w_cursor.lnum == curwin->w_topline
+	    && width > 0
+#ifdef FEAT_VERTSPLIT
+	    && curwin->w_width != 0
+#endif
+	    )
+    {
+	/* Cursor past end of screen.  Happens with a single line that does
+	 * not fit on screen.  Find a skipcol to show the text around the
+	 * cursor.  Avoid scrolling all the time. compute value of "extra":
+	 * 1: Less than "p_so" lines above
+	 * 2: Less than "p_so" lines below
+	 * 3: both of them */
+	extra = 0;
+	if (curwin->w_skipcol + p_so * width > curwin->w_virtcol)
+	    extra = 1;
+	/* Compute last display line of the buffer line that we want at the
+	 * bottom of the window. */
+	if (p_lines == 0)
+	    p_lines = plines_win(curwin, curwin->w_cursor.lnum, FALSE);
+	--p_lines;
+	if (p_lines > curwin->w_wrow + p_so)
+	    n = curwin->w_wrow + p_so;
+	else
+	    n = p_lines;
+	if ((colnr_T)n >= curwin->w_height + curwin->w_skipcol / width)
+	    extra += 2;
+
+	if (extra == 3 || p_lines < p_so * 2)
+	{
+	    /* not enough room for 'scrolloff', put cursor in the middle */
+	    n = curwin->w_virtcol / width;
+	    if (n > curwin->w_height / 2)
+		n -= curwin->w_height / 2;
+	    else
+		n = 0;
+	    /* don't skip more than necessary */
+	    if (n > p_lines - curwin->w_height + 1)
+		n = p_lines - curwin->w_height + 1;
+	    curwin->w_skipcol = n * width;
+	}
+	else if (extra == 1)
+	{
+	    /* less then 'scrolloff' lines above, decrease skipcol */
+	    extra = (curwin->w_skipcol + p_so * width - curwin->w_virtcol
+				     + width - 1) / width;
+	    if (extra > 0)
+	    {
+		if ((colnr_T)(extra * width) > curwin->w_skipcol)
+		    extra = curwin->w_skipcol / width;
+		curwin->w_skipcol -= extra * width;
+	    }
+	}
+	else if (extra == 2)
+	{
+	    /* less then 'scrolloff' lines below, increase skipcol */
+	    endcol = (n - curwin->w_height + 1) * width;
+	    while (endcol > curwin->w_virtcol)
+		endcol -= width;
+	    if (endcol > curwin->w_skipcol)
+		curwin->w_skipcol = endcol;
+	}
+
+	curwin->w_wrow -= curwin->w_skipcol / width;
+	if (curwin->w_wrow >= curwin->w_height)
+	{
+	    /* small window, make sure cursor is in it */
+	    extra = curwin->w_wrow - curwin->w_height + 1;
+	    curwin->w_skipcol += extra * width;
+	    curwin->w_wrow -= extra;
+	}
+
+	extra = ((int)prev_skipcol - (int)curwin->w_skipcol) / width;
+	if (extra > 0)
+	    win_ins_lines(curwin, 0, extra, FALSE, FALSE);
+	else if (extra < 0)
+	    win_del_lines(curwin, 0, -extra, FALSE, FALSE);
+    }
+    else
+	curwin->w_skipcol = 0;
+    if (prev_skipcol != curwin->w_skipcol)
+	redraw_later(NOT_VALID);
+
+#ifdef FEAT_SYN_HL
+    /* Redraw when w_virtcol changes and 'cursorcolumn' is set, or when w_row
+     * changes and 'cursorline' is set. */
+    if (((curwin->w_p_cuc && (curwin->w_valid & VALID_VIRTCOL) == 0)
+		|| (curwin->w_p_cul && (curwin->w_valid & VALID_WROW) == 0))
+# ifdef FEAT_INS_EXPAND
+	    && !pum_visible()
+# endif
+	    )
+	redraw_later(SOME_VALID);
+#endif
+
+    curwin->w_valid |= VALID_WCOL|VALID_WROW|VALID_VIRTCOL;
+}
+
+/*
+ * Scroll the current window down by "line_count" logical lines.  "CTRL-Y"
+ */
+/*ARGSUSED*/
+    void
+scrolldown(line_count, byfold)
+    long	line_count;
+    int		byfold;		/* TRUE: count a closed fold as one line */
+{
+    long	done = 0;	/* total # of physical lines done */
+    int		wrow;
+    int		moved = FALSE;
+
+#ifdef FEAT_FOLDING
+    linenr_T	first;
+
+    /* Make sure w_topline is at the first of a sequence of folded lines. */
+    (void)hasFolding(curwin->w_topline, &curwin->w_topline, NULL);
+#endif
+    validate_cursor();		/* w_wrow needs to be valid */
+    while (line_count-- > 0)
+    {
+#ifdef FEAT_DIFF
+	if (curwin->w_topfill < diff_check(curwin, curwin->w_topline))
+	{
+	    ++curwin->w_topfill;
+	    ++done;
+	}
+	else
+#endif
+	{
+	    if (curwin->w_topline == 1)
+		break;
+	    --curwin->w_topline;
+#ifdef FEAT_DIFF
+	    curwin->w_topfill = 0;
+#endif
+#ifdef FEAT_FOLDING
+	    /* A sequence of folded lines only counts for one logical line */
+	    if (hasFolding(curwin->w_topline, &first, NULL))
+	    {
+		++done;
+		if (!byfold)
+		    line_count -= curwin->w_topline - first - 1;
+		curwin->w_botline -= curwin->w_topline - first;
+		curwin->w_topline = first;
+	    }
+	    else
+#endif
+#ifdef FEAT_DIFF
+		done += plines_nofill(curwin->w_topline);
+#else
+		done += plines(curwin->w_topline);
+#endif
+	}
+	--curwin->w_botline;		/* approximate w_botline */
+	invalidate_botline();
+    }
+    curwin->w_wrow += done;		/* keep w_wrow updated */
+    curwin->w_cline_row += done;	/* keep w_cline_row updated */
+
+#ifdef FEAT_DIFF
+    if (curwin->w_cursor.lnum == curwin->w_topline)
+	curwin->w_cline_row = 0;
+    check_topfill(curwin, TRUE);
+#endif
+
+    /*
+     * Compute the row number of the last row of the cursor line
+     * and move the cursor onto the displayed part of the window.
+     */
+    wrow = curwin->w_wrow;
+    if (curwin->w_p_wrap
+#ifdef FEAT_VERTSPLIT
+		&& curwin->w_width != 0
+#endif
+	    )
+    {
+	validate_virtcol();
+	validate_cheight();
+	wrow += curwin->w_cline_height - 1 -
+	    curwin->w_virtcol / W_WIDTH(curwin);
+    }
+    while (wrow >= curwin->w_height && curwin->w_cursor.lnum > 1)
+    {
+#ifdef FEAT_FOLDING
+	if (hasFolding(curwin->w_cursor.lnum, &first, NULL))
+	{
+	    --wrow;
+	    if (first == 1)
+		curwin->w_cursor.lnum = 1;
+	    else
+		curwin->w_cursor.lnum = first - 1;
+	}
+	else
+#endif
+	    wrow -= plines(curwin->w_cursor.lnum--);
+	curwin->w_valid &=
+	      ~(VALID_WROW|VALID_WCOL|VALID_CHEIGHT|VALID_CROW|VALID_VIRTCOL);
+	moved = TRUE;
+    }
+    if (moved)
+    {
+#ifdef FEAT_FOLDING
+	/* Move cursor to first line of closed fold. */
+	foldAdjustCursor();
+#endif
+	coladvance(curwin->w_curswant);
+    }
+}
+
+/*
+ * Scroll the current window up by "line_count" logical lines.  "CTRL-E"
+ */
+/*ARGSUSED*/
+    void
+scrollup(line_count, byfold)
+    long	line_count;
+    int		byfold;		/* TRUE: count a closed fold as one line */
+{
+#if defined(FEAT_FOLDING) || defined(FEAT_DIFF)
+    linenr_T	lnum;
+
+    if (
+# ifdef FEAT_FOLDING
+	    (byfold && hasAnyFolding(curwin))
+#  ifdef FEAT_DIFF
+	    ||
+#  endif
+# endif
+# ifdef FEAT_DIFF
+	    curwin->w_p_diff
+# endif
+	    )
+    {
+	/* count each sequence of folded lines as one logical line */
+	lnum = curwin->w_topline;
+	while (line_count--)
+	{
+# ifdef FEAT_DIFF
+	    if (curwin->w_topfill > 0)
+		--curwin->w_topfill;
+	    else
+# endif
+	    {
+# ifdef FEAT_FOLDING
+		if (byfold)
+		    (void)hasFolding(lnum, NULL, &lnum);
+# endif
+		if (lnum >= curbuf->b_ml.ml_line_count)
+		    break;
+		++lnum;
+# ifdef FEAT_DIFF
+		curwin->w_topfill = diff_check_fill(curwin, lnum);
+# endif
+	    }
+	}
+	/* approximate w_botline */
+	curwin->w_botline += lnum - curwin->w_topline;
+	curwin->w_topline = lnum;
+    }
+    else
+#endif
+    {
+	curwin->w_topline += line_count;
+	curwin->w_botline += line_count;	/* approximate w_botline */
+    }
+
+    if (curwin->w_topline > curbuf->b_ml.ml_line_count)
+	curwin->w_topline = curbuf->b_ml.ml_line_count;
+    if (curwin->w_botline > curbuf->b_ml.ml_line_count + 1)
+	curwin->w_botline = curbuf->b_ml.ml_line_count + 1;
+
+#ifdef FEAT_DIFF
+    check_topfill(curwin, FALSE);
+#endif
+
+#ifdef FEAT_FOLDING
+    if (hasAnyFolding(curwin))
+	/* Make sure w_topline is at the first of a sequence of folded lines. */
+	(void)hasFolding(curwin->w_topline, &curwin->w_topline, NULL);
+#endif
+
+    curwin->w_valid &= ~(VALID_WROW|VALID_CROW|VALID_BOTLINE);
+    if (curwin->w_cursor.lnum < curwin->w_topline)
+    {
+	curwin->w_cursor.lnum = curwin->w_topline;
+	curwin->w_valid &=
+	      ~(VALID_WROW|VALID_WCOL|VALID_CHEIGHT|VALID_CROW|VALID_VIRTCOL);
+	coladvance(curwin->w_curswant);
+    }
+}
+
+#ifdef FEAT_DIFF
+/*
+ * Don't end up with too many filler lines in the window.
+ */
+    void
+check_topfill(wp, down)
+    win_T	*wp;
+    int		down;	/* when TRUE scroll down when not enough space */
+{
+    int		n;
+
+    if (wp->w_topfill > 0)
+    {
+	n = plines_win_nofill(wp, wp->w_topline, TRUE);
+	if (wp->w_topfill + n > wp->w_height)
+	{
+	    if (down && wp->w_topline > 1)
+	    {
+		--wp->w_topline;
+		wp->w_topfill = 0;
+	    }
+	    else
+	    {
+		wp->w_topfill = wp->w_height - n;
+		if (wp->w_topfill < 0)
+		    wp->w_topfill = 0;
+	    }
+	}
+    }
+}
+
+/*
+ * Use as many filler lines as possible for w_topline.  Make sure w_topline
+ * is still visible.
+ */
+    static void
+max_topfill()
+{
+    int		n;
+
+    n = plines_nofill(curwin->w_topline);
+    if (n >= curwin->w_height)
+	curwin->w_topfill = 0;
+    else
+    {
+	curwin->w_topfill = diff_check_fill(curwin, curwin->w_topline);
+	if (curwin->w_topfill + n > curwin->w_height)
+	    curwin->w_topfill = curwin->w_height - n;
+    }
+}
+#endif
+
+#if defined(FEAT_INS_EXPAND) || defined(PROTO)
+/*
+ * Scroll the screen one line down, but don't do it if it would move the
+ * cursor off the screen.
+ */
+    void
+scrolldown_clamp()
+{
+    int		end_row;
+#ifdef FEAT_DIFF
+    int		can_fill = (curwin->w_topfill
+				< diff_check_fill(curwin, curwin->w_topline));
+#endif
+
+    if (curwin->w_topline <= 1
+#ifdef FEAT_DIFF
+	    && !can_fill
+#endif
+	    )
+	return;
+
+    validate_cursor();	    /* w_wrow needs to be valid */
+
+    /*
+     * Compute the row number of the last row of the cursor line
+     * and make sure it doesn't go off the screen. Make sure the cursor
+     * doesn't go past 'scrolloff' lines from the screen end.
+     */
+    end_row = curwin->w_wrow;
+#ifdef FEAT_DIFF
+    if (can_fill)
+	++end_row;
+    else
+	end_row += plines_nofill(curwin->w_topline - 1);
+#else
+    end_row += plines(curwin->w_topline - 1);
+#endif
+    if (curwin->w_p_wrap
+#ifdef FEAT_VERTSPLIT
+		&& curwin->w_width != 0
+#endif
+	    )
+    {
+	validate_cheight();
+	validate_virtcol();
+	end_row += curwin->w_cline_height - 1 -
+	    curwin->w_virtcol / W_WIDTH(curwin);
+    }
+    if (end_row < curwin->w_height - p_so)
+    {
+#ifdef FEAT_DIFF
+	if (can_fill)
+	{
+	    ++curwin->w_topfill;
+	    check_topfill(curwin, TRUE);
+	}
+	else
+	{
+	    --curwin->w_topline;
+	    curwin->w_topfill = 0;
+	}
+#else
+	--curwin->w_topline;
+#endif
+#ifdef FEAT_FOLDING
+	hasFolding(curwin->w_topline, &curwin->w_topline, NULL);
+#endif
+	--curwin->w_botline;	    /* approximate w_botline */
+	curwin->w_valid &= ~(VALID_WROW|VALID_CROW|VALID_BOTLINE);
+    }
+}
+
+/*
+ * Scroll the screen one line up, but don't do it if it would move the cursor
+ * off the screen.
+ */
+    void
+scrollup_clamp()
+{
+    int	    start_row;
+
+    if (curwin->w_topline == curbuf->b_ml.ml_line_count
+#ifdef FEAT_DIFF
+	    && curwin->w_topfill == 0
+#endif
+	    )
+	return;
+
+    validate_cursor();	    /* w_wrow needs to be valid */
+
+    /*
+     * Compute the row number of the first row of the cursor line
+     * and make sure it doesn't go off the screen. Make sure the cursor
+     * doesn't go before 'scrolloff' lines from the screen start.
+     */
+#ifdef FEAT_DIFF
+    start_row = curwin->w_wrow - plines_nofill(curwin->w_topline)
+							  - curwin->w_topfill;
+#else
+    start_row = curwin->w_wrow - plines(curwin->w_topline);
+#endif
+    if (curwin->w_p_wrap
+#ifdef FEAT_VERTSPLIT
+		&& curwin->w_width != 0
+#endif
+	    )
+    {
+	validate_virtcol();
+	start_row -= curwin->w_virtcol / W_WIDTH(curwin);
+    }
+    if (start_row >= p_so)
+    {
+#ifdef FEAT_DIFF
+	if (curwin->w_topfill > 0)
+	    --curwin->w_topfill;
+	else
+#endif
+	{
+#ifdef FEAT_FOLDING
+	    (void)hasFolding(curwin->w_topline, NULL, &curwin->w_topline);
+#endif
+	    ++curwin->w_topline;
+	}
+	++curwin->w_botline;		/* approximate w_botline */
+	curwin->w_valid &= ~(VALID_WROW|VALID_CROW|VALID_BOTLINE);
+    }
+}
+#endif /* FEAT_INS_EXPAND */
+
+/*
+ * Add one line above "lp->lnum".  This can be a filler line, a closed fold or
+ * a (wrapped) text line.  Uses and sets "lp->fill".
+ * Returns the height of the added line in "lp->height".
+ * Lines above the first one are incredibly high.
+ */
+    static void
+topline_back(lp)
+    lineoff_T	*lp;
+{
+#ifdef FEAT_DIFF
+    if (lp->fill < diff_check_fill(curwin, lp->lnum))
+    {
+	/* Add a filler line. */
+	++lp->fill;
+	lp->height = 1;
+    }
+    else
+#endif
+    {
+	--lp->lnum;
+#ifdef FEAT_DIFF
+	lp->fill = 0;
+#endif
+	if (lp->lnum < 1)
+	    lp->height = MAXCOL;
+	else
+#ifdef FEAT_FOLDING
+	    if (hasFolding(lp->lnum, &lp->lnum, NULL))
+	    /* Add a closed fold */
+	    lp->height = 1;
+	else
+#endif
+	{
+#ifdef FEAT_DIFF
+	    lp->height = plines_nofill(lp->lnum);
+#else
+	    lp->height = plines(lp->lnum);
+#endif
+	}
+    }
+}
+
+/*
+ * Add one line below "lp->lnum".  This can be a filler line, a closed fold or
+ * a (wrapped) text line.  Uses and sets "lp->fill".
+ * Returns the height of the added line in "lp->height".
+ * Lines below the last one are incredibly high.
+ */
+    static void
+botline_forw(lp)
+    lineoff_T	*lp;
+{
+#ifdef FEAT_DIFF
+    if (lp->fill < diff_check_fill(curwin, lp->lnum + 1))
+    {
+	/* Add a filler line. */
+	++lp->fill;
+	lp->height = 1;
+    }
+    else
+#endif
+    {
+	++lp->lnum;
+#ifdef FEAT_DIFF
+	lp->fill = 0;
+#endif
+	if (lp->lnum > curbuf->b_ml.ml_line_count)
+	    lp->height = MAXCOL;
+	else
+#ifdef FEAT_FOLDING
+	    if (hasFolding(lp->lnum, NULL, &lp->lnum))
+	    /* Add a closed fold */
+	    lp->height = 1;
+	else
+#endif
+	{
+#ifdef FEAT_DIFF
+	    lp->height = plines_nofill(lp->lnum);
+#else
+	    lp->height = plines(lp->lnum);
+#endif
+	}
+    }
+}
+
+#ifdef FEAT_DIFF
+/*
+ * Switch from including filler lines below lp->lnum to including filler
+ * lines above loff.lnum + 1.  This keeps pointing to the same line.
+ * When there are no filler lines nothing changes.
+ */
+    static void
+botline_topline(lp)
+    lineoff_T	*lp;
+{
+    if (lp->fill > 0)
+    {
+	++lp->lnum;
+	lp->fill = diff_check_fill(curwin, lp->lnum) - lp->fill + 1;
+    }
+}
+
+/*
+ * Switch from including filler lines above lp->lnum to including filler
+ * lines below loff.lnum - 1.  This keeps pointing to the same line.
+ * When there are no filler lines nothing changes.
+ */
+    static void
+topline_botline(lp)
+    lineoff_T	*lp;
+{
+    if (lp->fill > 0)
+    {
+	lp->fill = diff_check_fill(curwin, lp->lnum) - lp->fill + 1;
+	--lp->lnum;
+    }
+}
+#endif
+
+/*
+ * Recompute topline to put the cursor at the top of the window.
+ * Scroll at least "min_scroll" lines.
+ * If "always" is TRUE, always set topline (for "zt").
+ */
+    void
+scroll_cursor_top(min_scroll, always)
+    int		min_scroll;
+    int		always;
+{
+    int		scrolled = 0;
+    int		extra = 0;
+    int		used;
+    int		i;
+    linenr_T	top;		/* just above displayed lines */
+    linenr_T	bot;		/* just below displayed lines */
+    linenr_T	old_topline = curwin->w_topline;
+#ifdef FEAT_DIFF
+    linenr_T	old_topfill = curwin->w_topfill;
+#endif
+    linenr_T	new_topline;
+    int		off = p_so;
+
+#ifdef FEAT_MOUSE
+    if (mouse_dragging > 0)
+	off = mouse_dragging - 1;
+#endif
+
+    /*
+     * Decrease topline until:
+     * - it has become 1
+     * - (part of) the cursor line is moved off the screen or
+     * - moved at least 'scrolljump' lines and
+     * - at least 'scrolloff' lines above and below the cursor
+     */
+    validate_cheight();
+    used = curwin->w_cline_height;
+    if (curwin->w_cursor.lnum < curwin->w_topline)
+	scrolled = used;
+
+#ifdef FEAT_FOLDING
+    if (hasFolding(curwin->w_cursor.lnum, &top, &bot))
+    {
+	--top;
+	++bot;
+    }
+    else
+#endif
+    {
+	top = curwin->w_cursor.lnum - 1;
+	bot = curwin->w_cursor.lnum + 1;
+    }
+    new_topline = top + 1;
+
+#ifdef FEAT_DIFF
+    /* count filler lines of the cursor window as context */
+    i = diff_check_fill(curwin, curwin->w_cursor.lnum);
+    used += i;
+    extra += i;
+#endif
+
+    /*
+     * Check if the lines from "top" to "bot" fit in the window.  If they do,
+     * set new_topline and advance "top" and "bot" to include more lines.
+     */
+    while (top > 0)
+    {
+#ifdef FEAT_FOLDING
+	if (hasFolding(top, &top, NULL))
+	    /* count one logical line for a sequence of folded lines */
+	    i = 1;
+	else
+#endif
+	    i = plines(top);
+	used += i;
+	if (extra + i <= off && bot < curbuf->b_ml.ml_line_count)
+	{
+#ifdef FEAT_FOLDING
+	    if (hasFolding(bot, NULL, &bot))
+		/* count one logical line for a sequence of folded lines */
+		++used;
+	    else
+#endif
+		used += plines(bot);
+	}
+	if (used > curwin->w_height)
+	    break;
+	if (top < curwin->w_topline)
+	    scrolled += i;
+
+	/*
+	 * If scrolling is needed, scroll at least 'sj' lines.
+	 */
+	if ((new_topline >= curwin->w_topline || scrolled > min_scroll)
+		&& extra >= off)
+	    break;
+
+	extra += i;
+	new_topline = top;
+	--top;
+	++bot;
+    }
+
+    /*
+     * If we don't have enough space, put cursor in the middle.
+     * This makes sure we get the same position when using "k" and "j"
+     * in a small window.
+     */
+    if (used > curwin->w_height)
+	scroll_cursor_halfway(FALSE);
+    else
+    {
+	/*
+	 * If "always" is FALSE, only adjust topline to a lower value, higher
+	 * value may happen with wrapping lines
+	 */
+	if (new_topline < curwin->w_topline || always)
+	    curwin->w_topline = new_topline;
+	if (curwin->w_topline > curwin->w_cursor.lnum)
+	    curwin->w_topline = curwin->w_cursor.lnum;
+#ifdef FEAT_DIFF
+	curwin->w_topfill = diff_check_fill(curwin, curwin->w_topline);
+	if (curwin->w_topfill > 0 && extra > off)
+	{
+	    curwin->w_topfill -= extra - off;
+	    if (curwin->w_topfill < 0)
+		curwin->w_topfill = 0;
+	}
+	check_topfill(curwin, FALSE);
+#endif
+	if (curwin->w_topline != old_topline
+#ifdef FEAT_DIFF
+		|| curwin->w_topfill != old_topfill
+#endif
+		)
+	    curwin->w_valid &=
+		      ~(VALID_WROW|VALID_CROW|VALID_BOTLINE|VALID_BOTLINE_AP);
+	curwin->w_valid |= VALID_TOPLINE;
+    }
+}
+
+/*
+ * Set w_empty_rows and w_filler_rows for window "wp", having used up "used"
+ * screen lines for text lines.
+ */
+    void
+set_empty_rows(wp, used)
+    win_T	*wp;
+    int		used;
+{
+#ifdef FEAT_DIFF
+    wp->w_filler_rows = 0;
+#endif
+    if (used == 0)
+	wp->w_empty_rows = 0;	/* single line that doesn't fit */
+    else
+    {
+	wp->w_empty_rows = wp->w_height - used;
+#ifdef FEAT_DIFF
+	if (wp->w_botline <= wp->w_buffer->b_ml.ml_line_count)
+	{
+	    wp->w_filler_rows = diff_check_fill(wp, wp->w_botline);
+	    if (wp->w_empty_rows > wp->w_filler_rows)
+		wp->w_empty_rows -= wp->w_filler_rows;
+	    else
+	    {
+		wp->w_filler_rows = wp->w_empty_rows;
+		wp->w_empty_rows = 0;
+	    }
+	}
+#endif
+    }
+}
+
+/*
+ * Recompute topline to put the cursor at the bottom of the window.
+ * Scroll at least "min_scroll" lines.
+ * If "set_topbot" is TRUE, set topline and botline first (for "zb").
+ * This is messy stuff!!!
+ */
+    void
+scroll_cursor_bot(min_scroll, set_topbot)
+    int		min_scroll;
+    int		set_topbot;
+{
+    int		used;
+    int		scrolled = 0;
+    int		extra = 0;
+    int		i;
+    linenr_T	line_count;
+    linenr_T	old_topline = curwin->w_topline;
+    lineoff_T	loff;
+    lineoff_T	boff;
+#ifdef FEAT_DIFF
+    int		old_topfill = curwin->w_topfill;
+    int		fill_below_window;
+#endif
+    linenr_T	old_botline = curwin->w_botline;
+    linenr_T	old_valid = curwin->w_valid;
+    int		old_empty_rows = curwin->w_empty_rows;
+    linenr_T	cln;		    /* Cursor Line Number */
+
+    cln = curwin->w_cursor.lnum;
+    if (set_topbot)
+    {
+	used = 0;
+	curwin->w_botline = cln + 1;
+#ifdef FEAT_DIFF
+	loff.fill = 0;
+#endif
+	for (curwin->w_topline = curwin->w_botline;
+		curwin->w_topline > 1;
+		curwin->w_topline = loff.lnum)
+	{
+	    loff.lnum = curwin->w_topline;
+	    topline_back(&loff);
+	    if (used + loff.height > curwin->w_height)
+		break;
+	    used += loff.height;
+#ifdef FEAT_DIFF
+	    curwin->w_topfill = loff.fill;
+#endif
+	}
+	set_empty_rows(curwin, used);
+	curwin->w_valid |= VALID_BOTLINE|VALID_BOTLINE_AP;
+	if (curwin->w_topline != old_topline
+#ifdef FEAT_DIFF
+		|| curwin->w_topfill != old_topfill
+#endif
+		)
+	    curwin->w_valid &= ~(VALID_WROW|VALID_CROW);
+    }
+    else
+	validate_botline();
+
+    /* The lines of the cursor line itself are always used. */
+#ifdef FEAT_DIFF
+    used = plines_nofill(cln);
+#else
+    validate_cheight();
+    used = curwin->w_cline_height;
+#endif
+
+    /* If the cursor is below botline, we will at least scroll by the height
+     * of the cursor line.  Correct for empty lines, which are really part of
+     * botline. */
+    if (cln >= curwin->w_botline)
+    {
+	scrolled = used;
+	if (cln == curwin->w_botline)
+	    scrolled -= curwin->w_empty_rows;
+    }
+
+    /*
+     * Stop counting lines to scroll when
+     * - hitting start of the file
+     * - scrolled nothing or at least 'sj' lines
+     * - at least 'so' lines below the cursor
+     * - lines between botline and cursor have been counted
+     */
+#ifdef FEAT_FOLDING
+    if (!hasFolding(curwin->w_cursor.lnum, &loff.lnum, &boff.lnum))
+#endif
+    {
+	loff.lnum = cln;
+	boff.lnum = cln;
+    }
+#ifdef FEAT_DIFF
+    loff.fill = 0;
+    boff.fill = 0;
+    fill_below_window = diff_check_fill(curwin, curwin->w_botline)
+						      - curwin->w_filler_rows;
+#endif
+
+    while (loff.lnum > 1)
+    {
+	/* Stop when scrolled nothing or at least "min_scroll", found "extra"
+	 * context for 'scrolloff' and counted all lines below the window. */
+	if ((((scrolled <= 0 || scrolled >= min_scroll)
+			&& extra >= (
+#ifdef FEAT_MOUSE
+			    mouse_dragging > 0 ? mouse_dragging - 1 :
+#endif
+			    p_so))
+		    || boff.lnum + 1 > curbuf->b_ml.ml_line_count)
+		&& loff.lnum <= curwin->w_botline
+#ifdef FEAT_DIFF
+		&& (loff.lnum < curwin->w_botline
+		    || loff.fill >= fill_below_window)
+#endif
+		)
+	    break;
+
+	/* Add one line above */
+	topline_back(&loff);
+	used += loff.height;
+	if (used > curwin->w_height)
+	    break;
+	if (loff.lnum >= curwin->w_botline
+#ifdef FEAT_DIFF
+		&& (loff.lnum > curwin->w_botline
+		    || loff.fill <= fill_below_window)
+#endif
+		)
+	{
+	    /* Count screen lines that are below the window. */
+	    scrolled += loff.height;
+	    if (loff.lnum == curwin->w_botline
+#ifdef FEAT_DIFF
+			    && boff.fill == 0
+#endif
+		    )
+		scrolled -= curwin->w_empty_rows;
+	}
+
+	if (boff.lnum < curbuf->b_ml.ml_line_count)
+	{
+	    /* Add one line below */
+	    botline_forw(&boff);
+	    used += boff.height;
+	    if (used > curwin->w_height)
+		break;
+	    if (extra < (
+#ifdef FEAT_MOUSE
+			mouse_dragging > 0 ? mouse_dragging - 1 :
+#endif
+			p_so) || scrolled < min_scroll)
+	    {
+		extra += boff.height;
+		if (boff.lnum >= curwin->w_botline
+#ifdef FEAT_DIFF
+			|| (boff.lnum + 1 == curwin->w_botline
+			    && boff.fill > curwin->w_filler_rows)
+#endif
+		   )
+		{
+		    /* Count screen lines that are below the window. */
+		    scrolled += boff.height;
+		    if (boff.lnum == curwin->w_botline
+#ifdef FEAT_DIFF
+			    && boff.fill == 0
+#endif
+			    )
+			scrolled -= curwin->w_empty_rows;
+		}
+	    }
+	}
+    }
+
+    /* curwin->w_empty_rows is larger, no need to scroll */
+    if (scrolled <= 0)
+	line_count = 0;
+    /* more than a screenfull, don't scroll but redraw */
+    else if (used > curwin->w_height)
+	line_count = used;
+    /* scroll minimal number of lines */
+    else
+    {
+	line_count = 0;
+#ifdef FEAT_DIFF
+	boff.fill = curwin->w_topfill;
+#endif
+	boff.lnum = curwin->w_topline - 1;
+	for (i = 0; i < scrolled && boff.lnum < curwin->w_botline; )
+	{
+	    botline_forw(&boff);
+	    i += boff.height;
+	    ++line_count;
+	}
+	if (i < scrolled)	/* below curwin->w_botline, don't scroll */
+	    line_count = 9999;
+    }
+
+    /*
+     * Scroll up if the cursor is off the bottom of the screen a bit.
+     * Otherwise put it at 1/2 of the screen.
+     */
+    if (line_count >= curwin->w_height && line_count > min_scroll)
+	scroll_cursor_halfway(FALSE);
+    else
+	scrollup(line_count, TRUE);
+
+    /*
+     * If topline didn't change we need to restore w_botline and w_empty_rows
+     * (we changed them).
+     * If topline did change, update_screen() will set botline.
+     */
+    if (curwin->w_topline == old_topline && set_topbot)
+    {
+	curwin->w_botline = old_botline;
+	curwin->w_empty_rows = old_empty_rows;
+	curwin->w_valid = old_valid;
+    }
+    curwin->w_valid |= VALID_TOPLINE;
+}
+
+/*
+ * Recompute topline to put the cursor halfway the window
+ * If "atend" is TRUE, also put it halfway at the end of the file.
+ */
+    void
+scroll_cursor_halfway(atend)
+    int		atend;
+{
+    int		above = 0;
+    linenr_T	topline;
+#ifdef FEAT_DIFF
+    int		topfill = 0;
+#endif
+    int		below = 0;
+    int		used;
+    lineoff_T	loff;
+    lineoff_T	boff;
+
+    loff.lnum = boff.lnum = curwin->w_cursor.lnum;
+#ifdef FEAT_FOLDING
+    (void)hasFolding(loff.lnum, &loff.lnum, &boff.lnum);
+#endif
+#ifdef FEAT_DIFF
+    used = plines_nofill(loff.lnum);
+    loff.fill = 0;
+    boff.fill = 0;
+#else
+    used = plines(loff.lnum);
+#endif
+    topline = loff.lnum;
+    while (topline > 1)
+    {
+	if (below <= above)	    /* add a line below the cursor first */
+	{
+	    if (boff.lnum < curbuf->b_ml.ml_line_count)
+	    {
+		botline_forw(&boff);
+		used += boff.height;
+		if (used > curwin->w_height)
+		    break;
+		below += boff.height;
+	    }
+	    else
+	    {
+		++below;	    /* count a "~" line */
+		if (atend)
+		    ++used;
+	    }
+	}
+
+	if (below > above)	    /* add a line above the cursor */
+	{
+	    topline_back(&loff);
+	    used += loff.height;
+	    if (used > curwin->w_height)
+		break;
+	    above += loff.height;
+	    topline = loff.lnum;
+#ifdef FEAT_DIFF
+	    topfill = loff.fill;
+#endif
+	}
+    }
+#ifdef FEAT_FOLDING
+    if (!hasFolding(topline, &curwin->w_topline, NULL))
+#endif
+	curwin->w_topline = topline;
+#ifdef FEAT_DIFF
+    curwin->w_topfill = topfill;
+    check_topfill(curwin, FALSE);
+#endif
+    curwin->w_valid &= ~(VALID_WROW|VALID_CROW|VALID_BOTLINE|VALID_BOTLINE_AP);
+    curwin->w_valid |= VALID_TOPLINE;
+}
+
+/*
+ * Correct the cursor position so that it is in a part of the screen at least
+ * 'so' lines from the top and bottom, if possible.
+ * If not possible, put it at the same position as scroll_cursor_halfway().
+ * When called topline must be valid!
+ */
+    void
+cursor_correct()
+{
+    int		above = 0;	    /* screen lines above topline */
+    linenr_T	topline;
+    int		below = 0;	    /* screen lines below botline */
+    linenr_T	botline;
+    int		above_wanted, below_wanted;
+    linenr_T	cln;		    /* Cursor Line Number */
+    int		max_off;
+
+    /*
+     * How many lines we would like to have above/below the cursor depends on
+     * whether the first/last line of the file is on screen.
+     */
+    above_wanted = p_so;
+    below_wanted = p_so;
+#ifdef FEAT_MOUSE
+    if (mouse_dragging > 0)
+    {
+	above_wanted = mouse_dragging - 1;
+	below_wanted = mouse_dragging - 1;
+    }
+#endif
+    if (curwin->w_topline == 1)
+    {
+	above_wanted = 0;
+	max_off = curwin->w_height / 2;
+	if (below_wanted > max_off)
+	    below_wanted = max_off;
+    }
+    validate_botline();
+    if (curwin->w_botline == curbuf->b_ml.ml_line_count + 1
+#ifdef FEAT_MOUSE
+	    && mouse_dragging == 0
+#endif
+	    )
+    {
+	below_wanted = 0;
+	max_off = (curwin->w_height - 1) / 2;
+	if (above_wanted > max_off)
+	    above_wanted = max_off;
+    }
+
+    /*
+     * If there are sufficient file-lines above and below the cursor, we can
+     * return now.
+     */
+    cln = curwin->w_cursor.lnum;
+    if (cln >= curwin->w_topline + above_wanted
+	    && cln < curwin->w_botline - below_wanted
+#ifdef FEAT_FOLDING
+	    && !hasAnyFolding(curwin)
+#endif
+	    )
+	return;
+
+    /*
+     * Narrow down the area where the cursor can be put by taking lines from
+     * the top and the bottom until:
+     * - the desired context lines are found
+     * - the lines from the top is past the lines from the bottom
+     */
+    topline = curwin->w_topline;
+    botline = curwin->w_botline - 1;
+#ifdef FEAT_DIFF
+    /* count filler lines as context */
+    above = curwin->w_topfill;
+    below = curwin->w_filler_rows;
+#endif
+    while ((above < above_wanted || below < below_wanted) && topline < botline)
+    {
+	if (below < below_wanted && (below <= above || above >= above_wanted))
+	{
+#ifdef FEAT_FOLDING
+	    if (hasFolding(botline, &botline, NULL))
+		++below;
+	    else
+#endif
+		below += plines(botline);
+	    --botline;
+	}
+	if (above < above_wanted && (above < below || below >= below_wanted))
+	{
+#ifdef FEAT_FOLDING
+	    if (hasFolding(topline, NULL, &topline))
+		++above;
+	    else
+#endif
+#ifndef FEAT_DIFF
+		above += plines(topline);
+#else
+		above += plines_nofill(topline);
+
+	    /* Count filler lines below this line as context. */
+	    if (topline < botline)
+		above += diff_check_fill(curwin, topline + 1);
+#endif
+	    ++topline;
+	}
+    }
+    if (topline == botline || botline == 0)
+	curwin->w_cursor.lnum = topline;
+    else if (topline > botline)
+	curwin->w_cursor.lnum = botline;
+    else
+    {
+	if (cln < topline && curwin->w_topline > 1)
+	{
+	    curwin->w_cursor.lnum = topline;
+	    curwin->w_valid &=
+			    ~(VALID_WROW|VALID_WCOL|VALID_CHEIGHT|VALID_CROW);
+	}
+	if (cln > botline && curwin->w_botline <= curbuf->b_ml.ml_line_count)
+	{
+	    curwin->w_cursor.lnum = botline;
+	    curwin->w_valid &=
+			    ~(VALID_WROW|VALID_WCOL|VALID_CHEIGHT|VALID_CROW);
+	}
+    }
+    curwin->w_valid |= VALID_TOPLINE;
+}
+
+static void get_scroll_overlap __ARGS((lineoff_T *lp, int dir));
+
+/*
+ * move screen 'count' pages up or down and update screen
+ *
+ * return FAIL for failure, OK otherwise
+ */
+    int
+onepage(dir, count)
+    int		dir;
+    long	count;
+{
+    long	n;
+    int		retval = OK;
+    lineoff_T	loff;
+    linenr_T	old_topline = curwin->w_topline;
+
+    if (curbuf->b_ml.ml_line_count == 1)    /* nothing to do */
+    {
+	beep_flush();
+	return FAIL;
+    }
+
+    for ( ; count > 0; --count)
+    {
+	validate_botline();
+	/*
+	 * It's an error to move a page up when the first line is already on
+	 * the screen.	It's an error to move a page down when the last line
+	 * is on the screen and the topline is 'scrolloff' lines from the
+	 * last line.
+	 */
+	if (dir == FORWARD
+		? ((curwin->w_topline >= curbuf->b_ml.ml_line_count - p_so)
+		    && curwin->w_botline > curbuf->b_ml.ml_line_count)
+		: (curwin->w_topline == 1
+#ifdef FEAT_DIFF
+		    && curwin->w_topfill ==
+				    diff_check_fill(curwin, curwin->w_topline)
+#endif
+		    ))
+	{
+	    beep_flush();
+	    retval = FAIL;
+	    break;
+	}
+
+#ifdef FEAT_DIFF
+	loff.fill = 0;
+#endif
+	if (dir == FORWARD)
+	{
+	    if (firstwin == lastwin && p_window > 0 && p_window < Rows - 1)
+	    {
+		/* Vi compatible scrolling */
+		if (p_window <= 2)
+		    ++curwin->w_topline;
+		else
+		    curwin->w_topline += p_window - 2;
+		if (curwin->w_topline > curbuf->b_ml.ml_line_count)
+		    curwin->w_topline = curbuf->b_ml.ml_line_count;
+		curwin->w_cursor.lnum = curwin->w_topline;
+	    }
+	    else if (curwin->w_botline > curbuf->b_ml.ml_line_count)
+	    {
+		/* at end of file */
+		curwin->w_topline = curbuf->b_ml.ml_line_count;
+#ifdef FEAT_DIFF
+		curwin->w_topfill = 0;
+#endif
+		curwin->w_valid &= ~(VALID_WROW|VALID_CROW);
+	    }
+	    else
+	    {
+		/* For the overlap, start with the line just below the window
+		 * and go upwards. */
+		loff.lnum = curwin->w_botline;
+#ifdef FEAT_DIFF
+		loff.fill = diff_check_fill(curwin, loff.lnum)
+						      - curwin->w_filler_rows;
+#endif
+		get_scroll_overlap(&loff, -1);
+		curwin->w_topline = loff.lnum;
+#ifdef FEAT_DIFF
+		curwin->w_topfill = loff.fill;
+		check_topfill(curwin, FALSE);
+#endif
+		curwin->w_cursor.lnum = curwin->w_topline;
+		curwin->w_valid &= ~(VALID_WCOL|VALID_CHEIGHT|VALID_WROW|
+				   VALID_CROW|VALID_BOTLINE|VALID_BOTLINE_AP);
+	    }
+	}
+	else	/* dir == BACKWARDS */
+	{
+#ifdef FEAT_DIFF
+	    if (curwin->w_topline == 1)
+	    {
+		/* Include max number of filler lines */
+		max_topfill();
+		continue;
+	    }
+#endif
+	    if (firstwin == lastwin && p_window > 0 && p_window < Rows - 1)
+	    {
+		/* Vi compatible scrolling (sort of) */
+		if (p_window <= 2)
+		    --curwin->w_topline;
+		else
+		    curwin->w_topline -= p_window - 2;
+		if (curwin->w_topline < 1)
+		    curwin->w_topline = 1;
+		curwin->w_cursor.lnum = curwin->w_topline + p_window - 1;
+		if (curwin->w_cursor.lnum > curbuf->b_ml.ml_line_count)
+		    curwin->w_cursor.lnum = curbuf->b_ml.ml_line_count;
+		continue;
+	    }
+
+	    /* Find the line at the top of the window that is going to be the
+	     * line at the bottom of the window.  Make sure this results in
+	     * the same line as before doing CTRL-F. */
+	    loff.lnum = curwin->w_topline - 1;
+#ifdef FEAT_DIFF
+	    loff.fill = diff_check_fill(curwin, loff.lnum + 1)
+							  - curwin->w_topfill;
+#endif
+	    get_scroll_overlap(&loff, 1);
+
+	    if (loff.lnum >= curbuf->b_ml.ml_line_count)
+	    {
+		loff.lnum = curbuf->b_ml.ml_line_count;
+#ifdef FEAT_DIFF
+		loff.fill = 0;
+	    }
+	    else
+	    {
+		botline_topline(&loff);
+#endif
+	    }
+	    curwin->w_cursor.lnum = loff.lnum;
+
+	    /* Find the line just above the new topline to get the right line
+	     * at the bottom of the window. */
+	    n = 0;
+	    while (n <= curwin->w_height && loff.lnum >= 1)
+	    {
+		topline_back(&loff);
+		n += loff.height;
+	    }
+	    if (n <= curwin->w_height)		    /* at begin of file */
+	    {
+		curwin->w_topline = 1;
+#ifdef FEAT_DIFF
+		max_topfill();
+#endif
+		curwin->w_valid &= ~(VALID_WROW|VALID_CROW|VALID_BOTLINE);
+	    }
+	    else
+	    {
+		/* Go two lines forward again. */
+#ifdef FEAT_DIFF
+		topline_botline(&loff);
+#endif
+		botline_forw(&loff);
+		botline_forw(&loff);
+#ifdef FEAT_DIFF
+		botline_topline(&loff);
+#endif
+#ifdef FEAT_FOLDING
+		/* We're at the wrong end of a fold now. */
+		(void)hasFolding(loff.lnum, &loff.lnum, NULL);
+#endif
+
+		/* Always scroll at least one line.  Avoid getting stuck on
+		 * very long lines. */
+		if (loff.lnum >= curwin->w_topline
+#ifdef FEAT_DIFF
+			&& (loff.lnum > curwin->w_topline
+			    || loff.fill >= curwin->w_topfill)
+#endif
+			)
+		{
+#ifdef FEAT_DIFF
+		    /* First try using the maximum number of filler lines.  If
+		     * that's not enough, backup one line. */
+		    loff.fill = curwin->w_topfill;
+		    if (curwin->w_topfill < diff_check_fill(curwin,
+							   curwin->w_topline))
+			max_topfill();
+		    if (curwin->w_topfill == loff.fill)
+#endif
+		    {
+			--curwin->w_topline;
+#ifdef FEAT_DIFF
+			curwin->w_topfill = 0;
+#endif
+		    }
+		    comp_botline(curwin);
+		    curwin->w_cursor.lnum = curwin->w_botline - 1;
+		    curwin->w_valid &= ~(VALID_WCOL|VALID_CHEIGHT|
+			    VALID_WROW|VALID_CROW);
+		}
+		else
+		{
+		    curwin->w_topline = loff.lnum;
+#ifdef FEAT_DIFF
+		    curwin->w_topfill = loff.fill;
+		    check_topfill(curwin, FALSE);
+#endif
+		    curwin->w_valid &= ~(VALID_WROW|VALID_CROW|VALID_BOTLINE);
+		}
+	    }
+	}
+    }
+#ifdef FEAT_FOLDING
+    foldAdjustCursor();
+#endif
+    cursor_correct();
+    if (retval == OK)
+	beginline(BL_SOL | BL_FIX);
+    curwin->w_valid &= ~(VALID_WCOL|VALID_WROW|VALID_VIRTCOL);
+
+    /*
+     * Avoid the screen jumping up and down when 'scrolloff' is non-zero.
+     * But make sure we scroll at least one line (happens with mix of long
+     * wrapping lines and non-wrapping line).
+     */
+    if (retval == OK && dir == FORWARD && check_top_offset())
+    {
+	scroll_cursor_top(1, FALSE);
+	if (curwin->w_topline <= old_topline
+				  && old_topline < curbuf->b_ml.ml_line_count)
+	{
+	    curwin->w_topline = old_topline + 1;
+#ifdef FEAT_FOLDING
+	    (void)hasFolding(curwin->w_topline, &curwin->w_topline, NULL);
+#endif
+	}
+    }
+
+    redraw_later(VALID);
+    return retval;
+}
+
+/*
+ * Decide how much overlap to use for page-up or page-down scrolling.
+ * This is symmetric, so that doing both keeps the same lines displayed.
+ * Three lines are examined:
+ *
+ *  before CTRL-F	    after CTRL-F / before CTRL-B
+ *     etc.			l1
+ *  l1 last but one line	------------
+ *  l2 last text line		l2 top text line
+ *  -------------		l3 second text line
+ *  l3				   etc.
+ */
+    static void
+get_scroll_overlap(lp, dir)
+    lineoff_T	*lp;
+    int		dir;
+{
+    int		h1, h2, h3, h4;
+    int		min_height = curwin->w_height - 2;
+    lineoff_T	loff0, loff1, loff2;
+
+#ifdef FEAT_DIFF
+    if (lp->fill > 0)
+	lp->height = 1;
+    else
+	lp->height = plines_nofill(lp->lnum);
+#else
+    lp->height = plines(lp->lnum);
+#endif
+    h1 = lp->height;
+    if (h1 > min_height)
+	return;		/* no overlap */
+
+    loff0 = *lp;
+    if (dir > 0)
+	botline_forw(lp);
+    else
+	topline_back(lp);
+    h2 = lp->height;
+    if (h2 + h1 > min_height)
+    {
+	*lp = loff0;	/* no overlap */
+	return;
+    }
+
+    loff1 = *lp;
+    if (dir > 0)
+	botline_forw(lp);
+    else
+	topline_back(lp);
+    h3 = lp->height;
+    if (h3 + h2 > min_height)
+    {
+	*lp = loff0;	/* no overlap */
+	return;
+    }
+
+    loff2 = *lp;
+    if (dir > 0)
+	botline_forw(lp);
+    else
+	topline_back(lp);
+    h4 = lp->height;
+    if (h4 + h3 + h2 > min_height || h3 + h2 + h1 > min_height)
+	*lp = loff1;	/* 1 line overlap */
+    else
+	*lp = loff2;	/* 2 lines overlap */
+    return;
+}
+
+/* #define KEEP_SCREEN_LINE */
+/*
+ * Scroll 'scroll' lines up or down.
+ */
+    void
+halfpage(flag, Prenum)
+    int		flag;
+    linenr_T	Prenum;
+{
+    long	scrolled = 0;
+    int		i;
+    int		n;
+    int		room;
+
+    if (Prenum)
+	curwin->w_p_scr = (Prenum > curwin->w_height) ?
+						curwin->w_height : Prenum;
+    n = (curwin->w_p_scr <= curwin->w_height) ?
+				    curwin->w_p_scr : curwin->w_height;
+
+    validate_botline();
+    room = curwin->w_empty_rows;
+#ifdef FEAT_DIFF
+    room += curwin->w_filler_rows;
+#endif
+    if (flag)
+    {
+	/*
+	 * scroll the text up
+	 */
+	while (n > 0 && curwin->w_botline <= curbuf->b_ml.ml_line_count)
+	{
+#ifdef FEAT_DIFF
+	    if (curwin->w_topfill > 0)
+	    {
+		i = 1;
+		if (--n < 0 && scrolled > 0)
+		    break;
+		--curwin->w_topfill;
+	    }
+	    else
+#endif
+	    {
+#ifdef FEAT_DIFF
+		i = plines_nofill(curwin->w_topline);
+#else
+		i = plines(curwin->w_topline);
+#endif
+		n -= i;
+		if (n < 0 && scrolled > 0)
+		    break;
+#ifdef FEAT_FOLDING
+		(void)hasFolding(curwin->w_topline, NULL, &curwin->w_topline);
+#endif
+		++curwin->w_topline;
+#ifdef FEAT_DIFF
+		curwin->w_topfill = diff_check_fill(curwin, curwin->w_topline);
+#endif
+
+#ifndef KEEP_SCREEN_LINE
+		if (curwin->w_cursor.lnum < curbuf->b_ml.ml_line_count)
+		{
+		    ++curwin->w_cursor.lnum;
+		    curwin->w_valid &=
+				    ~(VALID_VIRTCOL|VALID_CHEIGHT|VALID_WCOL);
+		}
+#endif
+	    }
+	    curwin->w_valid &= ~(VALID_CROW|VALID_WROW);
+	    scrolled += i;
+
+	    /*
+	     * Correct w_botline for changed w_topline.
+	     * Won't work when there are filler lines.
+	     */
+#ifdef FEAT_DIFF
+	    if (curwin->w_p_diff)
+		curwin->w_valid &= ~(VALID_BOTLINE|VALID_BOTLINE_AP);
+	    else
+#endif
+	    {
+		room += i;
+		do
+		{
+		    i = plines(curwin->w_botline);
+		    if (i > room)
+			break;
+#ifdef FEAT_FOLDING
+		    (void)hasFolding(curwin->w_botline, NULL,
+							  &curwin->w_botline);
+#endif
+		    ++curwin->w_botline;
+		    room -= i;
+		} while (curwin->w_botline <= curbuf->b_ml.ml_line_count);
+	    }
+	}
+
+#ifndef KEEP_SCREEN_LINE
+	/*
+	 * When hit bottom of the file: move cursor down.
+	 */
+	if (n > 0)
+	{
+# ifdef FEAT_FOLDING
+	    if (hasAnyFolding(curwin))
+	    {
+		while (--n >= 0
+			&& curwin->w_cursor.lnum < curbuf->b_ml.ml_line_count)
+		{
+		    (void)hasFolding(curwin->w_cursor.lnum, NULL,
+						      &curwin->w_cursor.lnum);
+		    ++curwin->w_cursor.lnum;
+		}
+	    }
+	    else
+# endif
+		curwin->w_cursor.lnum += n;
+	    check_cursor_lnum();
+	}
+#else
+	/* try to put the cursor in the same screen line */
+	while ((curwin->w_cursor.lnum < curwin->w_topline || scrolled > 0)
+			     && curwin->w_cursor.lnum < curwin->w_botline - 1)
+	{
+	    scrolled -= plines(curwin->w_cursor.lnum);
+	    if (scrolled < 0 && curwin->w_cursor.lnum >= curwin->w_topline)
+		break;
+# ifdef FEAT_FOLDING
+	    (void)hasFolding(curwin->w_cursor.lnum, NULL,
+						      &curwin->w_cursor.lnum);
+# endif
+	    ++curwin->w_cursor.lnum;
+	}
+#endif
+    }
+    else
+    {
+	/*
+	 * scroll the text down
+	 */
+	while (n > 0 && curwin->w_topline > 1)
+	{
+#ifdef FEAT_DIFF
+	    if (curwin->w_topfill < diff_check_fill(curwin, curwin->w_topline))
+	    {
+		i = 1;
+		if (--n < 0 && scrolled > 0)
+		    break;
+		++curwin->w_topfill;
+	    }
+	    else
+#endif
+	    {
+#ifdef FEAT_DIFF
+		i = plines_nofill(curwin->w_topline - 1);
+#else
+		i = plines(curwin->w_topline - 1);
+#endif
+		n -= i;
+		if (n < 0 && scrolled > 0)
+		    break;
+		--curwin->w_topline;
+#ifdef FEAT_FOLDING
+		(void)hasFolding(curwin->w_topline, &curwin->w_topline, NULL);
+#endif
+#ifdef FEAT_DIFF
+		curwin->w_topfill = 0;
+#endif
+	    }
+	    curwin->w_valid &= ~(VALID_CROW|VALID_WROW|
+					      VALID_BOTLINE|VALID_BOTLINE_AP);
+	    scrolled += i;
+#ifndef KEEP_SCREEN_LINE
+	    if (curwin->w_cursor.lnum > 1)
+	    {
+		--curwin->w_cursor.lnum;
+		curwin->w_valid &= ~(VALID_VIRTCOL|VALID_CHEIGHT|VALID_WCOL);
+	    }
+#endif
+	}
+#ifndef KEEP_SCREEN_LINE
+	/*
+	 * When hit top of the file: move cursor up.
+	 */
+	if (n > 0)
+	{
+	    if (curwin->w_cursor.lnum <= (linenr_T)n)
+		curwin->w_cursor.lnum = 1;
+	    else
+# ifdef FEAT_FOLDING
+	    if (hasAnyFolding(curwin))
+	    {
+		while (--n >= 0 && curwin->w_cursor.lnum > 1)
+		{
+		    --curwin->w_cursor.lnum;
+		    (void)hasFolding(curwin->w_cursor.lnum,
+						&curwin->w_cursor.lnum, NULL);
+		}
+	    }
+	    else
+# endif
+		curwin->w_cursor.lnum -= n;
+	}
+#else
+	/* try to put the cursor in the same screen line */
+	scrolled += n;	    /* move cursor when topline is 1 */
+	while (curwin->w_cursor.lnum > curwin->w_topline
+	      && (scrolled > 0 || curwin->w_cursor.lnum >= curwin->w_botline))
+	{
+	    scrolled -= plines(curwin->w_cursor.lnum - 1);
+	    if (scrolled < 0 && curwin->w_cursor.lnum < curwin->w_botline)
+		break;
+	    --curwin->w_cursor.lnum;
+# ifdef FEAT_FOLDING
+	    foldAdjustCursor();
+# endif
+	}
+#endif
+    }
+# ifdef FEAT_FOLDING
+    /* Move cursor to first line of closed fold. */
+    foldAdjustCursor();
+# endif
+#ifdef FEAT_DIFF
+    check_topfill(curwin, !flag);
+#endif
+    cursor_correct();
+    beginline(BL_SOL | BL_FIX);
+    redraw_later(VALID);
+}
--- /dev/null
+++ b/mysign
@@ -1,0 +1,1 @@
+=auto/configure-lastupdate=1178970549.78-@buildcheck=dfc15c059b7ce88a951584995c49a201=configure.in@md5=e0d6e9a7d7b986d63ce4e8e7362fd0b9
--- /dev/null
+++ b/nbdebug.c
@@ -1,0 +1,196 @@
+/* vi:set ts=8 sts=8 sw=8:
+ *
+ * VIM - Vi IMproved	by Bram Moolenaar
+ *			Visual Workshop integration by Gordon Prieur
+ *
+ * Do ":help uganda"  in Vim to read copying and usage conditions.
+ * Do ":help credits" in Vim to see a list of people who contributed.
+ * See README.txt for an overview of the Vim source code.
+ */
+
+/*
+ * NetBeans Debugging Tools. What are these tools and why are they important?
+ * There are two main tools here. The first tool is a tool for delaying or
+ * stopping gvim during startup.  The second tool is a protocol log tool.
+ *
+ * The startup delay tool is called nbdebug_wait(). This is very important for
+ * debugging startup problems because gvim will be started automatically from
+ * netbeans and cannot be run directly from a debugger. The only way to debug
+ * a gvim started by netbeans is by attaching a debugger to it. Without this
+ * tool all starup code will have completed before you can get the pid and
+ * attach.
+ *
+ * The second tool is a log tool.
+ *
+ * This code must have NBDEBUG defined for it to be compiled into vim/gvim.
+ */
+
+#ifdef NBDEBUG
+
+#include "vim.h"
+
+FILE		*nb_debug = NULL;
+u_int		 nb_dlevel = 0;		/* nb_debug verbosity level */
+
+void		 nbdb(char *, ...);
+void		 nbtrace(char *, ...);
+
+static int	 lookup(char *);
+#ifndef FEAT_GUI_W32
+static int	 errorHandler(Display *, XErrorEvent *);
+#endif
+
+/*
+ * nbdebug_wait	-   This function can be used to delay or stop execution of vim.
+ *		    Its normally used to delay startup while attaching a
+ *		    debugger to a running process. Since workshop starts gvim
+ *		    from a background process this is the only way to debug
+ *		    startup problems.
+ */
+
+void nbdebug_wait(
+	u_int		 wait_flags,	/* tells what to do */
+	char		*wait_var,	/* wait environment variable */
+	u_int		 wait_secs)	/* how many seconds to wait */
+{
+
+	init_homedir();			/* not inited yet */
+#ifdef USE_WDDUMP
+	WDDump(0, 0, 0);
+#endif
+
+	/* for debugging purposes only */
+	if (wait_flags & WT_ENV && wait_var && getenv(wait_var) != NULL) {
+		sleep(atoi(getenv(wait_var)));
+	} else if (wait_flags & WT_WAIT && lookup("~/.gvimwait")) {
+		sleep(wait_secs > 0 && wait_secs < 120 ? wait_secs : 20);
+	} else if (wait_flags & WT_STOP && lookup("~/.gvimstop")) {
+		int w = 1;
+		while (w) {
+			;
+		}
+	}
+}    /* end nbdebug_wait */
+
+
+void
+nbdebug_log_init(
+	char		*log_var,	/* env var with log file */
+	char		*level_var)	/* env var with nb_debug level */
+{
+	char		*file;		/* possible nb_debug output file */
+	char		*cp;		/* nb_dlevel pointer */
+
+	if (log_var && (file = getenv(log_var)) != NULL) {
+		time_t now;
+
+		nb_debug = fopen(file, "a");
+		time(&now);
+		fprintf(nb_debug, "%s", asctime(localtime(&now)));
+		if (level_var && (cp = getenv(level_var)) != NULL) {
+			nb_dlevel = strtoul(cp, NULL, 0);
+		} else {
+			nb_dlevel = NB_TRACE;	/* default level */
+		}
+	}
+
+}    /* end nbdebug_log_init */
+
+
+
+
+void
+nbtrace(
+	char		*fmt,
+	...)
+{
+	va_list		 ap;
+
+	if (nb_debug!= NULL && (nb_dlevel & (NB_TRACE | NB_TRACE_VERBOSE))) {
+		va_start(ap, fmt);
+		vfprintf(nb_debug, fmt, ap);
+		va_end(ap);
+		fflush(nb_debug);
+	}
+
+}    /* end nbtrace */
+
+
+void
+nbdbg(
+	char		*fmt,
+	...)
+{
+	va_list		 ap;
+
+	if (nb_debug != NULL && nb_dlevel & NB_TRACE) {
+		va_start(ap, fmt);
+		vfprintf(nb_debug, fmt, ap);
+		va_end(ap);
+		fflush(nb_debug);
+	}
+
+}    /* end nbdbg */
+
+
+void
+nbprt(
+	char		*fmt,
+	...)
+{
+	va_list		 ap;
+
+	if (nb_debug != NULL && nb_dlevel & NB_PRINT) {
+		va_start(ap, fmt);
+		vfprintf(nb_debug, fmt, ap);
+		va_end(ap);
+		fflush(nb_debug);
+	}
+
+}    /* end nbprt */
+
+
+static int
+lookup(
+	char		*file)
+{
+	char		 buf[BUFSIZ];
+
+	expand_env((char_u *) file, (char_u *) buf, BUFSIZ);
+	return
+#ifndef FEAT_GUI_W32
+		(access(buf, F_OK) == 0);
+#else
+		(access(buf, 0) == 0);
+#endif
+
+}    /* end lookup */
+
+#ifndef FEAT_GUI_W32
+static int
+errorHandler(
+	Display		*dpy,
+	XErrorEvent	*err)
+{
+	char		 msg[256];
+	char		 buf[256];
+
+	XGetErrorText(dpy, err->error_code, msg, sizeof(msg));
+	nbdbg("\n\nNBDEBUG Vim: X Error of failed request: %s\n", msg);
+
+	sprintf(buf, "%d", err->request_code);
+	XGetErrorDatabaseText(dpy,
+	    "XRequest", buf, "Unknown", msg, sizeof(msg));
+	nbdbg("\tMajor opcode of failed request: %d (%s)\n",
+	    err->request_code, msg);
+	if (err->request_code > 128) {
+		nbdbg("\tMinor opcode of failed request: %d\n",
+		    err->minor_code);
+	}
+
+	return 0;
+}
+#endif
+
+
+#endif /* NBDEBUG */
--- /dev/null
+++ b/nbdebug.h
@@ -1,0 +1,88 @@
+/* vi:set ts=8 sts=8 sw=8:
+ *
+ * VIM - Vi IMproved	by Bram Moolenaar
+ *			Visual Workshop integration by Gordon Prieur
+ *
+ * Do ":help uganda"  in Vim to read copying and usage conditions.
+ * Do ":help credits" in Vim to see a list of people who contributed.
+ */
+
+
+#ifndef NBDEBUG_H
+#define NBDEBUG_H
+
+#ifdef NBDEBUG
+
+#ifndef ASSERT
+#define ASSERT(c) \
+    if (!(c)) { \
+	fprintf(stderr, "Assertion failed: line %d, file %s\n", \
+		__LINE__, __FILE__); \
+	fflush(stderr); \
+	abort(); \
+    }
+#endif
+
+#define nbdebug(a) nbdbg##a
+
+#define NB_TRACE		0x00000001
+#define NB_TRACE_VERBOSE	0x00000002
+#define NB_TRACE_COLONCMD	0x00000004
+#define NB_PRINT		0x00000008
+#define NB_DEBUG_ALL		0xffffffff
+
+#define NBDLEVEL(flags)		(nb_debug != NULL && (nb_dlevel & (flags)))
+
+#define NBDEBUG_TRACE	1
+
+typedef enum {
+		WT_ENV = 1,		/* look for env var if set */
+		WT_WAIT,		/* look for ~/.gvimwait if set */
+		WT_STOP			/* look for ~/.gvimstop if set */
+} WtWait;
+
+
+void		 nbdbg(char *, ...);
+void		 nbprt(char *, ...);
+void		 nbtrace(char *, ...);
+
+void nbdebug_wait __ARGS((u_int wait_flags, char *wait_var, u_int wait_secs));
+void nbdebug_log_init __ARGS((char *log_var, char *level_var));
+
+extern FILE	*nb_debug;
+extern u_int	 nb_dlevel;		/* nb_debug verbosity level */
+
+# else		/* not NBDEBUG */
+
+#ifndef ASSERT
+# define ASSERT(c)
+#endif
+
+/*
+ * The following 3 stubs are needed because a macro cannot be used because of
+ * the variable number of arguments.
+ */
+
+void
+nbdbg(
+	char		*fmt,
+	...)
+{
+}
+
+void
+nbprt(
+	char		*fmt,
+	...)
+{
+}
+
+void
+nbtrace(
+	char		*fmt,
+	...)
+{
+}
+
+#endif /* NBDEBUG */
+#endif /* NBDEBUG_H */
--- /dev/null
+++ b/netbeans.c
@@ -1,0 +1,3520 @@
+/* vi:set ts=8 sts=4 sw=4:
+ *
+ * VIM - Vi IMproved	by Bram Moolenaar
+ *			Netbeans integration by David Weatherford
+ *			Adopted for Win32 by Sergey Khorev
+ *
+ * Do ":help uganda"  in Vim to read copying and usage conditions.
+ * Do ":help credits" in Vim to see a list of people who contributed.
+ */
+
+/*
+ * Implements client side of org.netbeans.modules.emacs editor
+ * integration protocol.  Be careful!  The protocol uses offsets
+ * which are *between* characters, whereas vim uses line number
+ * and column number which are *on* characters.
+ * See ":help netbeans-protocol" for explanation.
+ */
+
+#include "vim.h"
+
+#if defined(FEAT_NETBEANS_INTG) || defined(PROTO)
+
+/* Note: when making changes here also adjust configure.in. */
+# include <fcntl.h>
+#ifdef WIN32
+# ifdef DEBUG
+#  include <tchar.h>	/* for _T definition for TRACEn macros */
+# endif
+# include "vimio.h"
+/* WinSock API is separated from C API, thus we can't use read(), write(),
+ * errno... */
+# define sock_errno WSAGetLastError()
+# define ECONNREFUSED WSAECONNREFUSED
+# ifdef EINTR
+#  undef EINTR
+# endif
+# define EINTR WSAEINTR
+# define sock_write(sd, buf, len) send(sd, buf, len, 0)
+# define sock_read(sd, buf, len) recv(sd, buf, len, 0)
+# define sock_close(sd) closesocket(sd)
+# define sleep(t) Sleep(t*1000) /* WinAPI Sleep() accepts milliseconds */
+#else
+# include <netdb.h>
+# include <netinet/in.h>
+# include <sys/socket.h>
+# ifdef HAVE_LIBGEN_H
+#  include <libgen.h>
+# endif
+# define sock_errno errno
+# define sock_write(sd, buf, len) write(sd, buf, len)
+# define sock_read(sd, buf, len) read(sd, buf, len)
+# define sock_close(sd) close(sd)
+#endif
+
+#include "version.h"
+
+#define INET_SOCKETS
+
+#define GUARDED		10000 /* typenr for "guarded" annotation */
+#define GUARDEDOFFSET 1000000 /* base for "guarded" sign id's */
+
+/* The first implementation (working only with Netbeans) returned "1.1".  The
+ * protocol implemented here also supports A-A-P. */
+static char *ExtEdProtocolVersion = "2.4";
+
+static long pos2off __ARGS((buf_T *, pos_T *));
+static pos_T *off2pos __ARGS((buf_T *, long));
+static pos_T *get_off_or_lnum __ARGS((buf_T *buf, char_u **argp));
+static long get_buf_size __ARGS((buf_T *));
+static void netbeans_keystring __ARGS((int key, char *keystr));
+static void special_keys __ARGS((char_u *args));
+
+static void netbeans_connect __ARGS((void));
+static int getConnInfo __ARGS((char *file, char **host, char **port, char **password));
+
+static void nb_init_graphics __ARGS((void));
+static void coloncmd __ARGS((char *cmd, ...));
+static void nb_set_curbuf __ARGS((buf_T *buf));
+#ifdef FEAT_GUI_MOTIF
+static void messageFromNetbeans __ARGS((XtPointer, int *, XtInputId *));
+#endif
+#ifdef FEAT_GUI_GTK
+static void messageFromNetbeans __ARGS((gpointer, gint, GdkInputCondition));
+#endif
+static void nb_parse_cmd __ARGS((char_u *));
+static int  nb_do_cmd __ARGS((int, char_u *, int, int, char_u *));
+static void nb_send __ARGS((char *buf, char *fun));
+
+#ifdef WIN64
+typedef __int64 NBSOCK;
+#else
+typedef int NBSOCK;
+#endif
+
+static NBSOCK sd = -1;			/* socket fd for Netbeans connection */
+#ifdef FEAT_GUI_MOTIF
+static XtInputId inputHandler;		/* Cookie for input */
+#endif
+#ifdef FEAT_GUI_GTK
+static gint inputHandler;		/* Cookie for input */
+#endif
+#ifdef FEAT_GUI_W32
+static int  inputHandler = -1;		/* simply ret.value of WSAAsyncSelect() */
+extern HWND s_hwnd;			/* Gvim's Window handle */
+#endif
+static int r_cmdno;			/* current command number for reply */
+static int haveConnection = FALSE;	/* socket is connected and
+					   initialization is done */
+#ifdef FEAT_GUI_MOTIF
+static void netbeans_Xt_connect __ARGS((void *context));
+#endif
+#ifdef FEAT_GUI_GTK
+static void netbeans_gtk_connect __ARGS((void));
+#endif
+#ifdef FEAT_GUI_W32
+static void netbeans_w32_connect __ARGS((void));
+#endif
+
+static int dosetvisible = FALSE;
+
+/*
+ * Include the debugging code if wanted.
+ */
+#ifdef NBDEBUG
+# include "nbdebug.c"
+#endif
+
+/* Connect back to Netbeans process */
+#ifdef FEAT_GUI_MOTIF
+    static void
+netbeans_Xt_connect(void *context)
+{
+    netbeans_connect();
+    if (sd > 0)
+    {
+	/* tell notifier we are interested in being called
+	 * when there is input on the editor connection socket
+	 */
+	inputHandler = XtAppAddInput((XtAppContext)context, sd,
+			     (XtPointer)(XtInputReadMask + XtInputExceptMask),
+						   messageFromNetbeans, NULL);
+    }
+}
+
+    static void
+netbeans_disconnect(void)
+{
+    if (inputHandler != (XtInputId)NULL)
+    {
+	XtRemoveInput(inputHandler);
+	inputHandler = (XtInputId)NULL;
+    }
+    sd = -1;
+    haveConnection = FALSE;
+# ifdef FEAT_BEVAL
+    bevalServers &= ~BEVAL_NETBEANS;
+# endif
+}
+#endif /* FEAT_MOTIF_GUI */
+
+#ifdef FEAT_GUI_GTK
+    static void
+netbeans_gtk_connect(void)
+{
+    netbeans_connect();
+    if (sd > 0)
+    {
+	/*
+	 * Tell gdk we are interested in being called when there
+	 * is input on the editor connection socket
+	 */
+	inputHandler = gdk_input_add((gint)sd, (GdkInputCondition)
+		((int)GDK_INPUT_READ + (int)GDK_INPUT_EXCEPTION),
+						   messageFromNetbeans, NULL);
+    }
+}
+
+    static void
+netbeans_disconnect(void)
+{
+    if (inputHandler != 0)
+    {
+	gdk_input_remove(inputHandler);
+	inputHandler = 0;
+    }
+    sd = -1;
+    haveConnection = FALSE;
+# ifdef FEAT_BEVAL
+    bevalServers &= ~BEVAL_NETBEANS;
+# endif
+}
+#endif /* FEAT_GUI_GTK */
+
+#if defined(FEAT_GUI_W32) || defined(PROTO)
+    static void
+netbeans_w32_connect(void)
+{
+    netbeans_connect();
+    if (sd > 0)
+    {
+	/*
+	 * Tell Windows we are interested in receiving message when there
+	 * is input on the editor connection socket
+	 */
+	inputHandler = WSAAsyncSelect(sd, s_hwnd, WM_NETBEANS, FD_READ);
+    }
+}
+
+    static void
+netbeans_disconnect(void)
+{
+    if (inputHandler == 0)
+    {
+	WSAAsyncSelect(sd, s_hwnd, 0, 0);
+	inputHandler = -1;
+    }
+    sd = -1;
+    haveConnection = FALSE;
+# ifdef FEAT_BEVAL
+    bevalServers &= ~BEVAL_NETBEANS;
+# endif
+}
+#endif /* FEAT_GUI_W32 */
+
+#define NB_DEF_HOST "localhost"
+#define NB_DEF_ADDR "3219"
+#define NB_DEF_PASS "changeme"
+
+    static void
+netbeans_connect(void)
+{
+#ifdef INET_SOCKETS
+    struct sockaddr_in	server;
+    struct hostent *	host;
+# ifdef FEAT_GUI_W32
+    u_short		port;
+# else
+    int			port;
+#endif
+#else
+    struct sockaddr_un	server;
+#endif
+    char	buf[32];
+    char	*hostname = NULL;
+    char	*address = NULL;
+    char	*password = NULL;
+    char	*fname;
+    char	*arg = NULL;
+
+    if (netbeansArg[3] == '=')
+    {
+	/* "-nb=fname": Read info from specified file. */
+	if (getConnInfo(netbeansArg + 4, &hostname, &address, &password)
+								      == FAIL)
+	    return;
+    }
+    else
+    {
+	if (netbeansArg[3] == ':')
+	    /* "-nb:<host>:<addr>:<password>": get info from argument */
+	    arg = netbeansArg + 4;
+	if (arg == NULL && (fname = getenv("__NETBEANS_CONINFO")) != NULL)
+	{
+	    /* "-nb": get info from file specified in environment */
+	    if (getConnInfo(fname, &hostname, &address, &password) == FAIL)
+		return;
+	}
+	else
+	{
+	    if (arg != NULL)
+	    {
+		/* "-nb:<host>:<addr>:<password>": get info from argument */
+		hostname = arg;
+		address = strchr(hostname, ':');
+		if (address != NULL)
+		{
+		    *address++ = '\0';
+		    password = strchr(address, ':');
+		    if (password != NULL)
+			*password++ = '\0';
+		}
+	    }
+
+	    /* Get the missing values from the environment. */
+	    if (hostname == NULL || *hostname == '\0')
+		hostname = getenv("__NETBEANS_HOST");
+	    if (address == NULL)
+		address = getenv("__NETBEANS_SOCKET");
+	    if (password == NULL)
+		password = getenv("__NETBEANS_VIM_PASSWORD");
+
+	    /* Move values to allocated memory. */
+	    if (hostname != NULL)
+		hostname = (char *)vim_strsave((char_u *)hostname);
+	    if (address != NULL)
+		address = (char *)vim_strsave((char_u *)address);
+	    if (password != NULL)
+		password = (char *)vim_strsave((char_u *)password);
+	}
+    }
+
+    /* Use the default when a value is missing. */
+    if (hostname == NULL || *hostname == '\0')
+    {
+	vim_free(hostname);
+	hostname = (char *)vim_strsave((char_u *)NB_DEF_HOST);
+    }
+    if (address == NULL || *address == '\0')
+    {
+	vim_free(address);
+	address = (char *)vim_strsave((char_u *)NB_DEF_ADDR);
+    }
+    if (password == NULL || *password == '\0')
+    {
+	vim_free(password);
+	password = (char *)vim_strsave((char_u *)NB_DEF_PASS);
+    }
+    if (hostname == NULL || address == NULL || password == NULL)
+	goto theend;	    /* out of memory */
+
+#ifdef INET_SOCKETS
+    port = atoi(address);
+
+    if ((sd = (NBSOCK)socket(AF_INET, SOCK_STREAM, 0)) == (NBSOCK)-1)
+    {
+	PERROR("socket() in netbeans_connect()");
+	goto theend;
+    }
+
+    /* Get the server internet address and put into addr structure */
+    /* fill in the socket address structure and connect to server */
+    memset((char *)&server, '\0', sizeof(server));
+    server.sin_family = AF_INET;
+    server.sin_port = htons(port);
+    if ((host = gethostbyname(hostname)) == NULL)
+    {
+	if (mch_access(hostname, R_OK) >= 0)
+	{
+	    /* DEBUG: input file */
+	    sd = mch_open(hostname, O_RDONLY, 0);
+	    goto theend;
+	}
+	PERROR("gethostbyname() in netbeans_connect()");
+	sd = -1;
+	goto theend;
+    }
+    memcpy((char *)&server.sin_addr, host->h_addr, host->h_length);
+#else
+    if ((sd = socket(AF_UNIX, SOCK_STREAM, 0)) == -1)
+    {
+	PERROR("socket()");
+	goto theend;
+    }
+
+    server.sun_family = AF_UNIX;
+    strcpy(server.sun_path, address);
+#endif
+    /* Connect to server */
+    if (connect(sd, (struct sockaddr *)&server, sizeof(server)))
+    {
+	nbdebug(("netbeans_connect: Connect failed with errno %d\n", sock_errno));
+	if (sock_errno == ECONNREFUSED)
+	{
+	    sock_close(sd);
+#ifdef INET_SOCKETS
+	    if ((sd = (NBSOCK)socket(AF_INET, SOCK_STREAM, 0)) == (NBSOCK)-1)
+	    {
+		PERROR("socket()#2 in netbeans_connect()");
+		goto theend;
+	    }
+#else
+	    if ((sd = socket(AF_UNIX, SOCK_STREAM, 0)) == -1)
+	    {
+		PERROR("socket()#2 in netbeans_connect()");
+		goto theend;
+	    }
+#endif
+	    if (connect(sd, (struct sockaddr *)&server, sizeof(server)))
+	    {
+		int retries = 36;
+		int success = FALSE;
+		while (retries--
+			     && ((sock_errno == ECONNREFUSED) || (sock_errno == EINTR)))
+		{
+		    nbdebug(("retrying...\n"));
+		    sleep(5);
+		    if (connect(sd, (struct sockaddr *)&server,
+				sizeof(server)) == 0)
+		    {
+			success = TRUE;
+			break;
+		    }
+		}
+		if (!success)
+		{
+		    /* Get here when the server can't be found. */
+		    PERROR(_("Cannot connect to Netbeans #2"));
+		    getout(1);
+		}
+	    }
+
+	}
+	else
+	{
+	    PERROR(_("Cannot connect to Netbeans"));
+	    getout(1);
+	}
+    }
+
+    vim_snprintf(buf, sizeof(buf), "AUTH %s\n", password);
+    nb_send(buf, "netbeans_connect");
+
+    sprintf(buf, "0:version=0 \"%s\"\n", ExtEdProtocolVersion);
+    nb_send(buf, "externaleditor_version");
+
+/*    nb_init_graphics();  delay until needed */
+
+    haveConnection = TRUE;
+
+theend:
+    vim_free(hostname);
+    vim_free(address);
+    vim_free(password);
+    return;
+}
+
+/*
+ * Obtain the NetBeans hostname, port address and password from a file.
+ * Return the strings in allocated memory.
+ * Return FAIL if the file could not be read, OK otherwise (no matter what it
+ * contains).
+ */
+    static int
+getConnInfo(char *file, char **host, char **port, char **auth)
+{
+    FILE *fp;
+    char_u buf[BUFSIZ];
+    char_u *lp;
+    char_u *nl;
+#ifdef UNIX
+    struct stat	st;
+
+    /*
+     * For Unix only accept the file when it's not accessible by others.
+     * The open will then fail if we don't own the file.
+     */
+    if (mch_stat(file, &st) == 0 && (st.st_mode & 0077) != 0)
+    {
+	EMSG2(_("E668: Wrong access mode for NetBeans connection info file: \"%s\""),
+									file);
+	return FAIL;
+    }
+#endif
+
+    fp = mch_fopen(file, "r");
+    if (fp == NULL)
+    {
+	PERROR("E660: Cannot open NetBeans connection info file");
+	return FAIL;
+    }
+
+    /* Read the file. There should be one of each parameter */
+    while ((lp = (char_u *)fgets((char *)buf, BUFSIZ, fp)) != NULL)
+    {
+	if ((nl = vim_strchr(lp, '\n')) != NULL)
+	    *nl = 0;	    /* strip off the trailing newline */
+
+	if (STRNCMP(lp, "host=", 5) == 0)
+	{
+	    vim_free(*host);
+	    *host = (char *)vim_strsave(&buf[5]);
+	}
+	else if (STRNCMP(lp, "port=", 5) == 0)
+	{
+	    vim_free(*port);
+	    *port = (char *)vim_strsave(&buf[5]);
+	}
+	else if (STRNCMP(lp, "auth=", 5) == 0)
+	{
+	    vim_free(*auth);
+	    *auth = (char *)vim_strsave(&buf[5]);
+	}
+    }
+    fclose(fp);
+
+    return OK;
+}
+
+
+struct keyqueue
+{
+    int		     key;
+    struct keyqueue *next;
+    struct keyqueue *prev;
+};
+
+typedef struct keyqueue keyQ_T;
+
+static keyQ_T keyHead; /* dummy node, header for circular queue */
+
+
+/*
+ * Queue up key commands sent from netbeans.
+ */
+    static void
+postpone_keycommand(int key)
+{
+    keyQ_T *node;
+
+    node = (keyQ_T *)alloc(sizeof(keyQ_T));
+
+    if (keyHead.next == NULL) /* initialize circular queue */
+    {
+	keyHead.next = &keyHead;
+	keyHead.prev = &keyHead;
+    }
+
+    /* insert node at tail of queue */
+    node->next = &keyHead;
+    node->prev = keyHead.prev;
+    keyHead.prev->next = node;
+    keyHead.prev = node;
+
+    node->key = key;
+}
+
+/*
+ * Handle any queued-up NetBeans keycommands to be send.
+ */
+    static void
+handle_key_queue(void)
+{
+    while (keyHead.next && keyHead.next != &keyHead)
+    {
+	/* first, unlink the node */
+	keyQ_T *node = keyHead.next;
+	keyHead.next = node->next;
+	node->next->prev = node->prev;
+
+	/* now, send the keycommand */
+	netbeans_keycommand(node->key);
+
+	/* Finally, dispose of the node */
+	vim_free(node);
+    }
+}
+
+
+struct cmdqueue
+{
+    char_u	    *buffer;
+    struct cmdqueue *next;
+    struct cmdqueue *prev;
+};
+
+typedef struct cmdqueue queue_T;
+
+static queue_T head;  /* dummy node, header for circular queue */
+
+
+/*
+ * Put the buffer on the work queue; possibly save it to a file as well.
+ */
+    static void
+save(char_u *buf, int len)
+{
+    queue_T *node;
+
+    node = (queue_T *)alloc(sizeof(queue_T));
+    if (node == NULL)
+	return;	    /* out of memory */
+    node->buffer = alloc(len + 1);
+    if (node->buffer == NULL)
+    {
+	vim_free(node);
+	return;	    /* out of memory */
+    }
+    mch_memmove(node->buffer, buf, (size_t)len);
+    node->buffer[len] = NUL;
+
+    if (head.next == NULL)   /* initialize circular queue */
+    {
+	head.next = &head;
+	head.prev = &head;
+    }
+
+    /* insert node at tail of queue */
+    node->next = &head;
+    node->prev = head.prev;
+    head.prev->next = node;
+    head.prev = node;
+
+#ifdef NBDEBUG
+    {
+	static int outfd = -2;
+
+	/* possibly write buffer out to a file */
+	if (outfd == -3)
+	    return;
+
+	if (outfd == -2)
+	{
+	    char *file = getenv("__NETBEANS_SAVE");
+	    if (file == NULL)
+		outfd = -3;
+	    else
+		outfd = mch_open(file, O_WRONLY|O_CREAT|O_TRUNC, 0666);
+	}
+
+	if (outfd >= 0)
+	    write(outfd, buf, len);
+    }
+#endif
+}
+
+
+/*
+ * While there's still a command in the work queue, parse and execute it.
+ */
+    static void
+nb_parse_messages(void)
+{
+    char_u	*p;
+    queue_T	*node;
+
+    while (head.next != &head)
+    {
+	node = head.next;
+
+	/* Locate the first line in the first buffer. */
+	p = vim_strchr(node->buffer, '\n');
+	if (p == NULL)
+	{
+	    /* Command isn't complete.  If there is no following buffer,
+	     * return (wait for more). If there is another buffer following,
+	     * prepend the text to that buffer and delete this one.  */
+	    if (node->next == &head)
+		return;
+	    p = alloc((unsigned)(STRLEN(node->buffer) + STRLEN(node->next->buffer) + 1));
+	    if (p == NULL)
+		return;	    /* out of memory */
+	    STRCPY(p, node->buffer);
+	    STRCAT(p, node->next->buffer);
+	    vim_free(node->next->buffer);
+	    node->next->buffer = p;
+
+	    /* dispose of the node and buffer */
+	    head.next = node->next;
+	    node->next->prev = node->prev;
+	    vim_free(node->buffer);
+	    vim_free(node);
+	}
+	else
+	{
+	    /* There is a complete command at the start of the buffer.
+	     * Terminate it with a NUL.  When no more text is following unlink
+	     * the buffer.  Do this before executing, because new buffers can
+	     * be added while busy handling the command. */
+	    *p++ = NUL;
+	    if (*p == NUL)
+	    {
+		head.next = node->next;
+		node->next->prev = node->prev;
+	    }
+
+	    /* now, parse and execute the commands */
+	    nb_parse_cmd(node->buffer);
+
+	    if (*p == NUL)
+	    {
+		/* buffer finished, dispose of the node and buffer */
+		vim_free(node->buffer);
+		vim_free(node);
+	    }
+	    else
+	    {
+		/* more follows, move to the start */
+		mch_memmove(node->buffer, p, STRLEN(p) + 1);
+	    }
+	}
+    }
+}
+
+/* Buffer size for reading incoming messages. */
+#define MAXMSGSIZE 4096
+
+/*
+ * Read and process a command from netbeans.
+ */
+/*ARGSUSED*/
+#if defined(FEAT_GUI_W32) || defined(PROTO)
+/* Use this one when generating prototypes, the others are static. */
+    void
+messageFromNetbeansW32()
+#else
+# ifdef FEAT_GUI_MOTIF
+    static void
+messageFromNetbeans(XtPointer clientData, int *unused1, XtInputId *unused2)
+# endif
+# ifdef FEAT_GUI_GTK
+    static void
+messageFromNetbeans(gpointer clientData, gint unused1,
+						    GdkInputCondition unused2)
+# endif
+#endif
+{
+    static char_u	*buf = NULL;
+    int			len;
+    int			readlen = 0;
+    static int		level = 0;
+
+    if (sd < 0)
+    {
+	nbdebug(("messageFromNetbeans() called without a socket\n"));
+	return;
+    }
+
+    ++level;  /* recursion guard; this will be called from the X event loop */
+
+    /* Allocate a buffer to read into. */
+    if (buf == NULL)
+    {
+	buf = alloc(MAXMSGSIZE);
+	if (buf == NULL)
+	    return;	/* out of memory! */
+    }
+
+    /* Keep on reading for as long as there is something to read. */
+    for (;;)
+    {
+	len = sock_read(sd, buf, MAXMSGSIZE);
+	if (len <= 0)
+	    break;	/* error or nothing more to read */
+
+	/* Store the read message in the queue. */
+	save(buf, len);
+	readlen += len;
+	if (len < MAXMSGSIZE)
+	    break;	/* did read everything that's available */
+    }
+
+    if (readlen <= 0)
+    {
+	/* read error or didn't read anything */
+	netbeans_disconnect();
+	nbdebug(("messageFromNetbeans: Error in read() from socket\n"));
+	if (len < 0)
+	    PERROR(_("read from Netbeans socket"));
+	return; /* don't try to parse it */
+    }
+
+    /* Parse the messages, but avoid recursion. */
+    if (level == 1)
+	nb_parse_messages();
+
+    --level;
+}
+
+/*
+ * Handle one NUL terminated command.
+ *
+ * format of a command from netbeans:
+ *
+ *    6:setTitle!84 "a.c"
+ *
+ *    bufno
+ *     colon
+ *      cmd
+ *		!
+ *		 cmdno
+ *		    args
+ *
+ * for function calls, the ! is replaced by a /
+ */
+    static void
+nb_parse_cmd(char_u *cmd)
+{
+    char	*verb;
+    char	*q;
+    int		bufno;
+    int		isfunc = -1;
+
+    if (STRCMP(cmd, "DISCONNECT") == 0)
+    {
+	/* We assume the server knows that we can safely exit! */
+	if (sd >= 0)
+	    sock_close(sd);
+	/* Disconnect before exiting, Motif hangs in a Select error
+	 * message otherwise. */
+	netbeans_disconnect();
+	getout(0);
+	/* NOTREACHED */
+    }
+
+    if (STRCMP(cmd, "DETACH") == 0)
+    {
+	/* The IDE is breaking the connection. */
+	if (sd >= 0)
+	    sock_close(sd);
+	netbeans_disconnect();
+	return;
+    }
+
+    bufno = strtol((char *)cmd, &verb, 10);
+
+    if (*verb != ':')
+    {
+	EMSG2("E627: missing colon: %s", cmd);
+	return;
+    }
+    ++verb; /* skip colon */
+
+    for (q = verb; *q; q++)
+    {
+	if (*q == '!')
+	{
+	    *q++ = NUL;
+	    isfunc = 0;
+	    break;
+	}
+	else if (*q == '/')
+	{
+	    *q++ = NUL;
+	    isfunc = 1;
+	    break;
+	}
+    }
+
+    if (isfunc < 0)
+    {
+	EMSG2("E628: missing ! or / in: %s", cmd);
+	return;
+    }
+
+    r_cmdno = strtol(q, &q, 10);
+
+    q = (char *)skipwhite((char_u *)q);
+
+    if (nb_do_cmd(bufno, (char_u *)verb, isfunc, r_cmdno, (char_u *)q) == FAIL)
+    {
+#ifdef NBDEBUG
+	/*
+	 * This happens because the ExtEd can send a cammand or 2 after
+	 * doing a stopDocumentListen command. It doesn't harm anything
+	 * so I'm disabling it except for debugging.
+	 */
+	nbdebug(("nb_parse_cmd: Command error for \"%s\"\n", cmd));
+	EMSG("E629: bad return from nb_do_cmd");
+#endif
+    }
+}
+
+struct nbbuf_struct
+{
+    buf_T		*bufp;
+    unsigned int	 fireChanges:1;
+    unsigned int	 initDone:1;
+    unsigned int	 insertDone:1;
+    unsigned int	 modified:1;
+    int			 nbbuf_number;
+    char		*displayname;
+    int			*signmap;
+    short_u		 signmaplen;
+    short_u		 signmapused;
+};
+
+typedef struct nbbuf_struct nbbuf_T;
+
+static nbbuf_T *buf_list = 0;
+static int buf_list_size = 0;	/* size of buf_list */
+static int buf_list_used = 0;	/* nr of entries in buf_list actually in use */
+
+static char **globalsignmap;
+static int globalsignmaplen;
+static int globalsignmapused;
+
+static int  mapsigntype __ARGS((nbbuf_T *, int localsigntype));
+static void addsigntype __ARGS((nbbuf_T *, int localsigntype, char_u *typeName,
+			char_u *tooltip, char_u *glyphfile,
+			int usefg, int fg, int usebg, int bg));
+static void print_read_msg __ARGS((nbbuf_T *buf));
+static void print_save_msg __ARGS((nbbuf_T *buf, long nchars));
+
+static int curPCtype = -1;
+
+/*
+ * Get the Netbeans buffer number for the specified buffer.
+ */
+    static int
+nb_getbufno(buf_T *bufp)
+{
+    int i;
+
+    for (i = 0; i < buf_list_used; i++)
+	if (buf_list[i].bufp == bufp)
+	    return i;
+    return -1;
+}
+
+/*
+ * Is this a NetBeans-owned buffer?
+ */
+    int
+isNetbeansBuffer(buf_T *bufp)
+{
+    return usingNetbeans && bufp->b_netbeans_file;
+}
+
+/*
+ * NetBeans and Vim have different undo models. In Vim, the file isn't
+ * changed if changes are undone via the undo command. In NetBeans, once
+ * a change has been made the file is marked as modified until saved. It
+ * doesn't matter if the change was undone.
+ *
+ * So this function is for the corner case where Vim thinks a buffer is
+ * unmodified but NetBeans thinks it IS modified.
+ */
+    int
+isNetbeansModified(buf_T *bufp)
+{
+    if (usingNetbeans && bufp->b_netbeans_file)
+    {
+	int bufno = nb_getbufno(bufp);
+
+	if (bufno > 0)
+	    return buf_list[bufno].modified;
+	else
+	    return FALSE;
+    }
+    else
+	return FALSE;
+}
+
+/*
+ * Given a Netbeans buffer number, return the netbeans buffer.
+ * Returns NULL for 0 or a negative number. A 0 bufno means a
+ * non-buffer related command has been sent.
+ */
+    static nbbuf_T *
+nb_get_buf(int bufno)
+{
+    /* find or create a buffer with the given number */
+    int incr;
+
+    if (bufno <= 0)
+	return NULL;
+
+    if (!buf_list)
+    {
+	/* initialize */
+	buf_list = (nbbuf_T *)alloc_clear(100 * sizeof(nbbuf_T));
+	buf_list_size = 100;
+    }
+    if (bufno >= buf_list_used) /* new */
+    {
+	if (bufno >= buf_list_size) /* grow list */
+	{
+	    incr = bufno - buf_list_size + 90;
+	    buf_list_size += incr;
+	    buf_list = (nbbuf_T *)vim_realloc(
+				   buf_list, buf_list_size * sizeof(nbbuf_T));
+	    memset(buf_list + buf_list_size - incr, 0, incr * sizeof(nbbuf_T));
+	}
+
+	while (buf_list_used <= bufno)
+	{
+	    /* Default is to fire text changes. */
+	    buf_list[buf_list_used].fireChanges = 1;
+	    ++buf_list_used;
+	}
+    }
+
+    return buf_list + bufno;
+}
+
+/*
+ * Return the number of buffers that are modified.
+ */
+    static int
+count_changed_buffers(void)
+{
+    buf_T	*bufp;
+    int		n;
+
+    n = 0;
+    for (bufp = firstbuf; bufp != NULL; bufp = bufp->b_next)
+	if (bufp->b_changed)
+	    ++n;
+    return n;
+}
+
+/*
+ * End the netbeans session.
+ */
+    void
+netbeans_end(void)
+{
+    int i;
+    static char buf[128];
+
+    if (!haveConnection)
+	return;
+
+    for (i = 0; i < buf_list_used; i++)
+    {
+	if (!buf_list[i].bufp)
+	    continue;
+	if (netbeansForcedQuit)
+	{
+	    /* mark as unmodified so NetBeans won't put up dialog on "killed" */
+	    sprintf(buf, "%d:unmodified=%d\n", i, r_cmdno);
+	    nbdebug(("EVT: %s", buf));
+	    nb_send(buf, "netbeans_end");
+	}
+	sprintf(buf, "%d:killed=%d\n", i, r_cmdno);
+	nbdebug(("EVT: %s", buf));
+/*	nb_send(buf, "netbeans_end");    avoid "write failed" messages */
+	if (sd >= 0)
+	    sock_write(sd, buf, (int)STRLEN(buf));  /* ignore errors */
+    }
+}
+
+/*
+ * Send a message to netbeans.
+ */
+    static void
+nb_send(char *buf, char *fun)
+{
+    /* Avoid giving pages full of error messages when the other side has
+     * exited, only mention the first error until the connection works again. */
+    static int did_error = FALSE;
+
+    if (sd < 0)
+    {
+	if (!did_error)
+	    EMSG2("E630: %s(): write while not connected", fun);
+	did_error = TRUE;
+    }
+    else if (sock_write(sd, buf, (int)STRLEN(buf)) != (int)STRLEN(buf))
+    {
+	if (!did_error)
+	    EMSG2("E631: %s(): write failed", fun);
+	did_error = TRUE;
+    }
+    else
+	did_error = FALSE;
+}
+
+/*
+ * Some input received from netbeans requires a response. This function
+ * handles a response with no information (except the command number).
+ */
+    static void
+nb_reply_nil(int cmdno)
+{
+    char reply[32];
+
+    if (!haveConnection)
+	return;
+
+    nbdebug(("REP %d: <none>\n", cmdno));
+
+    sprintf(reply, "%d\n", cmdno);
+    nb_send(reply, "nb_reply_nil");
+}
+
+
+/*
+ * Send a response with text.
+ * "result" must have been quoted already (using nb_quote()).
+ */
+    static void
+nb_reply_text(int cmdno, char_u *result)
+{
+    char_u *reply;
+
+    if (!haveConnection)
+	return;
+
+    nbdebug(("REP %d: %s\n", cmdno, (char *)result));
+
+    reply = alloc((unsigned)STRLEN(result) + 32);
+    sprintf((char *)reply, "%d %s\n", cmdno, (char *)result);
+    nb_send((char *)reply, "nb_reply_text");
+
+    vim_free(reply);
+}
+
+
+/*
+ * Send a response with a number result code.
+ */
+    static void
+nb_reply_nr(int cmdno, long result)
+{
+    char reply[32];
+
+    if (!haveConnection)
+	return;
+
+    nbdebug(("REP %d: %ld\n", cmdno, result));
+
+    sprintf(reply, "%d %ld\n", cmdno, result);
+    nb_send(reply, "nb_reply_nr");
+}
+
+
+/*
+ * Encode newline, ret, backslash, double quote for transmission to NetBeans.
+ */
+    static char_u *
+nb_quote(char_u *txt)
+{
+    char_u *buf = alloc((unsigned)(2 * STRLEN(txt) + 1));
+    char_u *p = txt;
+    char_u *q = buf;
+
+    if (buf == NULL)
+	return NULL;
+    for (; *p; p++)
+    {
+	switch (*p)
+	{
+	    case '\"':
+	    case '\\':
+		*q++ = '\\'; *q++ = *p; break;
+	 /* case '\t': */
+	 /*     *q++ = '\\'; *q++ = 't'; break; */
+	    case '\n':
+		*q++ = '\\'; *q++ = 'n'; break;
+	    case '\r':
+		*q++ = '\\'; *q++ = 'r'; break;
+	    default:
+		*q++ = *p;
+		break;
+	}
+    }
+    *q++ = '\0';
+
+    return buf;
+}
+
+
+/*
+ * Remove top level double quotes; convert backslashed chars.
+ * Returns an allocated string (NULL for failure).
+ * If "endp" is not NULL it is set to the character after the terminating
+ * quote.
+ */
+    static char *
+nb_unquote(char_u *p, char_u **endp)
+{
+    char *result = 0;
+    char *q;
+    int done = 0;
+
+    /* result is never longer than input */
+    result = (char *)alloc_clear((unsigned)STRLEN(p) + 1);
+    if (result == NULL)
+	return NULL;
+
+    if (*p++ != '"')
+    {
+	nbdebug(("nb_unquote called with string that doesn't start with a quote!: %s\n",
+			p));
+	result[0] = NUL;
+	return result;
+    }
+
+    for (q = result; !done && *p != NUL;)
+    {
+	switch (*p)
+	{
+	    case '"':
+		/*
+		 * Unbackslashed dquote marks the end, if first char was dquote.
+		 */
+		done = 1;
+		break;
+
+	    case '\\':
+		++p;
+		switch (*p)
+		{
+		    case '\\':	*q++ = '\\';	break;
+		    case 'n':	*q++ = '\n';	break;
+		    case 't':	*q++ = '\t';	break;
+		    case 'r':	*q++ = '\r';	break;
+		    case '"':	*q++ = '"';	break;
+		    case NUL:	--p;		break;
+		    /* default: skip over illegal chars */
+		}
+		++p;
+		break;
+
+	    default:
+		*q++ = *p++;
+	}
+    }
+
+    if (endp != NULL)
+	*endp = p;
+
+    return result;
+}
+
+#define SKIP_STOP 2
+#define streq(a,b) (strcmp(a,b) == 0)
+static int needupdate = 0;
+static int inAtomic = 0;
+
+/*
+ * Do the actual processing of a single netbeans command or function.
+ * The difference between a command and function is that a function
+ * gets a response (it's required) but a command does not.
+ * For arguments see comment for nb_parse_cmd().
+ */
+    static int
+nb_do_cmd(
+    int		bufno,
+    char_u	*cmd,
+    int		func,
+    int		cmdno,
+    char_u	*args)	    /* points to space before arguments or NUL */
+{
+    int		doupdate = 0;
+    long	off = 0;
+    nbbuf_T	*buf = nb_get_buf(bufno);
+    static int	skip = 0;
+    int		retval = OK;
+    char	*cp;	    /* for when a char pointer is needed */
+
+    nbdebug(("%s %d: (%d) %s %s\n", (func) ? "FUN" : "CMD", cmdno, bufno, cmd,
+	STRCMP(cmd, "insert") == 0 ? "<text>" : (char *)args));
+
+    if (func)
+    {
+/* =====================================================================*/
+	if (streq((char *)cmd, "getModified"))
+	{
+	    if (buf == NULL || buf->bufp == NULL)
+		/* Return the number of buffers that are modified. */
+		nb_reply_nr(cmdno, (long)count_changed_buffers());
+	    else
+		/* Return whether the buffer is modified. */
+		nb_reply_nr(cmdno, (long)(buf->bufp->b_changed
+					   || isNetbeansModified(buf->bufp)));
+/* =====================================================================*/
+	}
+	else if (streq((char *)cmd, "saveAndExit"))
+	{
+	    /* Note: this will exit Vim if successful. */
+	    coloncmd(":confirm qall");
+
+	    /* We didn't exit: return the number of changed buffers. */
+	    nb_reply_nr(cmdno, (long)count_changed_buffers());
+/* =====================================================================*/
+	}
+	else if (streq((char *)cmd, "getCursor"))
+	{
+	    char_u text[200];
+
+	    /* Note: nb_getbufno() may return -1.  This indicates the IDE
+	     * didn't assign a number to the current buffer in response to a
+	     * fileOpened event. */
+	    sprintf((char *)text, "%d %ld %d %ld",
+		    nb_getbufno(curbuf),
+		    (long)curwin->w_cursor.lnum,
+		    (int)curwin->w_cursor.col,
+		    pos2off(curbuf, &curwin->w_cursor));
+	    nb_reply_text(cmdno, text);
+/* =====================================================================*/
+	}
+	else if (streq((char *)cmd, "getAnno"))
+	{
+	    long linenum = 0;
+#ifdef FEAT_SIGNS
+	    if (buf == NULL || buf->bufp == NULL)
+	    {
+		nbdebug(("    null bufp in getAnno"));
+		EMSG("E652: null bufp in getAnno");
+		retval = FAIL;
+	    }
+	    else
+	    {
+		int serNum;
+
+		cp = (char *)args;
+		serNum = strtol(cp, &cp, 10);
+		/* If the sign isn't found linenum will be zero. */
+		linenum = (long)buf_findsign(buf->bufp, serNum);
+	    }
+#endif
+	    nb_reply_nr(cmdno, linenum);
+/* =====================================================================*/
+	}
+	else if (streq((char *)cmd, "getLength"))
+	{
+	    long len = 0;
+
+	    if (buf == NULL || buf->bufp == NULL)
+	    {
+		nbdebug(("    null bufp in getLength"));
+		EMSG("E632: null bufp in getLength");
+		retval = FAIL;
+	    }
+	    else
+	    {
+		len = get_buf_size(buf->bufp);
+	    }
+	    nb_reply_nr(cmdno, len);
+/* =====================================================================*/
+	}
+	else if (streq((char *)cmd, "getText"))
+	{
+	    long	len;
+	    linenr_T	nlines;
+	    char_u	*text = NULL;
+	    linenr_T	lno = 1;
+	    char_u	*p;
+	    char_u	*line;
+
+	    if (buf == NULL || buf->bufp == NULL)
+	    {
+		nbdebug(("    null bufp in getText"));
+		EMSG("E633: null bufp in getText");
+		retval = FAIL;
+	    }
+	    else
+	    {
+		len = get_buf_size(buf->bufp);
+		nlines = buf->bufp->b_ml.ml_line_count;
+		text = alloc((unsigned)((len > 0)
+						 ? ((len + nlines) * 2) : 4));
+		if (text == NULL)
+		{
+		    nbdebug(("    nb_do_cmd: getText has null text field\n"));
+		    retval = FAIL;
+		}
+		else
+		{
+		    p = text;
+		    *p++ = '\"';
+		    for (; lno <= nlines ; lno++)
+		    {
+			line = nb_quote(ml_get_buf(buf->bufp, lno, FALSE));
+			if (line != NULL)
+			{
+			    STRCPY(p, line);
+			    p += STRLEN(line);
+			    *p++ = '\\';
+			    *p++ = 'n';
+			    vim_free(line);
+			}
+		    }
+		    *p++ = '\"';
+		    *p = '\0';
+		}
+	    }
+	    if (text == NULL)
+		nb_reply_text(cmdno, (char_u *)"");
+	    else
+	    {
+		nb_reply_text(cmdno, text);
+		vim_free(text);
+	    }
+/* =====================================================================*/
+	}
+	else if (streq((char *)cmd, "remove"))
+	{
+	    long count;
+	    pos_T first, last;
+	    pos_T *pos;
+	    int oldFire = netbeansFireChanges;
+	    int oldSuppress = netbeansSuppressNoLines;
+	    int wasChanged;
+
+	    if (skip >= SKIP_STOP)
+	    {
+		nbdebug(("    Skipping %s command\n", (char *) cmd));
+		nb_reply_nil(cmdno);
+		return OK;
+	    }
+
+	    if (buf == NULL || buf->bufp == NULL)
+	    {
+		nbdebug(("    null bufp in remove"));
+		EMSG("E634: null bufp in remove");
+		retval = FAIL;
+	    }
+	    else
+	    {
+		netbeansFireChanges = FALSE;
+		netbeansSuppressNoLines = TRUE;
+
+		nb_set_curbuf(buf->bufp);
+		wasChanged = buf->bufp->b_changed;
+		cp = (char *)args;
+		off = strtol(cp, &cp, 10);
+		count = strtol(cp, &cp, 10);
+		args = (char_u *)cp;
+		/* delete "count" chars, starting at "off" */
+		pos = off2pos(buf->bufp, off);
+		if (!pos)
+		{
+		    nb_reply_text(cmdno, (char_u *)"!bad position");
+		    netbeansFireChanges = oldFire;
+		    netbeansSuppressNoLines = oldSuppress;
+		    return FAIL;
+		}
+		first = *pos;
+		nbdebug(("    FIRST POS: line %d, col %d\n", first.lnum, first.col));
+		pos = off2pos(buf->bufp, off+count-1);
+		if (!pos)
+		{
+		    nb_reply_text(cmdno, (char_u *)"!bad count");
+		    netbeansFireChanges = oldFire;
+		    netbeansSuppressNoLines = oldSuppress;
+		    return FAIL;
+		}
+		last = *pos;
+		nbdebug(("    LAST POS: line %d, col %d\n", last.lnum, last.col));
+		curwin->w_cursor = first;
+		doupdate = 1;
+
+		/* keep part of first line */
+		if (first.lnum == last.lnum && first.col != last.col)
+		{
+		    /* deletion is within one line */
+		    char_u *p = ml_get(first.lnum);
+		    mch_memmove(p + first.col, p + last.col + 1, STRLEN(p + last.col) + 1);
+		    nbdebug(("    NEW LINE %d: %s\n", first.lnum, p));
+		    ml_replace(first.lnum, p, TRUE);
+		}
+
+		if (first.lnum < last.lnum)
+		{
+		    int i;
+
+		    /* delete signs from the lines being deleted */
+		    for (i = first.lnum; i <= last.lnum; i++)
+		    {
+			int id = buf_findsign_id(buf->bufp, (linenr_T)i);
+			if (id > 0)
+			{
+			    nbdebug(("    Deleting sign %d on line %d\n", id, i));
+			    buf_delsign(buf->bufp, id);
+			}
+			else
+			    nbdebug(("    No sign on line %d\n", i));
+		    }
+
+		    /* delete whole lines */
+		    nbdebug(("    Deleting lines %d through %d\n", first.lnum, last.lnum));
+		    del_lines(last.lnum - first.lnum + 1, FALSE);
+		}
+		buf->bufp->b_changed = wasChanged; /* logically unchanged */
+		netbeansFireChanges = oldFire;
+		netbeansSuppressNoLines = oldSuppress;
+
+		u_blockfree(buf->bufp);
+		u_clearall(buf->bufp);
+	    }
+	    nb_reply_nil(cmdno);
+/* =====================================================================*/
+	}
+	else if (streq((char *)cmd, "insert"))
+	{
+	    char_u	*to_free;
+
+	    if (skip >= SKIP_STOP)
+	    {
+		nbdebug(("    Skipping %s command\n", (char *) cmd));
+		nb_reply_nil(cmdno);
+		return OK;
+	    }
+
+	    /* get offset */
+	    cp = (char *)args;
+	    off = strtol(cp, &cp, 10);
+	    args = (char_u *)cp;
+
+	    /* get text to be inserted */
+	    args = skipwhite(args);
+	    args = to_free = (char_u *)nb_unquote(args, NULL);
+	    /*
+	    nbdebug(("    CHUNK[%d]: %d bytes at offset %d\n",
+		    buf->bufp->b_ml.ml_line_count, STRLEN(args), off));
+	    */
+
+	    if (buf == NULL || buf->bufp == NULL)
+	    {
+		nbdebug(("    null bufp in insert"));
+		EMSG("E635: null bufp in insert");
+		retval = FAIL;
+	    }
+	    else if (args != NULL)
+	    {
+		int	ff_detected = EOL_UNKNOWN;
+		int	buf_was_empty = (buf->bufp->b_ml.ml_flags & ML_EMPTY);
+		size_t	len = 0;
+		int	added = 0;
+		int	oldFire = netbeansFireChanges;
+		int	old_b_changed;
+		char_u	*nl;
+		linenr_T lnum;
+		linenr_T lnum_start;
+		pos_T	*pos;
+
+		netbeansFireChanges = 0;
+
+		/* Jump to the buffer where we insert.  After this "curbuf"
+		 * can be used. */
+		nb_set_curbuf(buf->bufp);
+		old_b_changed = curbuf->b_changed;
+
+		/* Convert the specified character offset into a lnum/col
+		 * position. */
+		pos = off2pos(curbuf, off);
+		if (pos != NULL)
+		{
+		    if (pos->lnum <= 0)
+			lnum_start = 1;
+		    else
+			lnum_start = pos->lnum;
+		}
+		else
+		{
+		    /* If the given position is not found, assume we want
+		     * the end of the file.  See setLocAndSize HACK. */
+		    if (buf_was_empty)
+			lnum_start = 1;	    /* above empty line */
+		    else
+			lnum_start = curbuf->b_ml.ml_line_count + 1;
+		}
+
+		/* "lnum" is the line where we insert: either append to it or
+		 * insert a new line above it. */
+		lnum = lnum_start;
+
+		/* Loop over the "\n" separated lines of the argument. */
+		doupdate = 1;
+		while (*args != NUL)
+		{
+		    nl = vim_strchr(args, '\n');
+		    if (nl == NULL)
+		    {
+			/* Incomplete line, probably truncated.  Next "insert"
+			 * command should append to this one. */
+			len = STRLEN(args);
+		    }
+		    else
+		    {
+			len = nl - args;
+
+			/*
+			 * We need to detect EOL style, because the commands
+			 * use a character offset.
+			 */
+			if (nl > args && nl[-1] == '\r')
+			{
+			    ff_detected = EOL_DOS;
+			    --len;
+			}
+			else
+			    ff_detected = EOL_UNIX;
+		    }
+		    args[len] = NUL;
+
+		    if (lnum == lnum_start
+			    && ((pos != NULL && pos->col > 0)
+				|| (lnum == 1 && buf_was_empty)))
+		    {
+			char_u *oldline = ml_get(lnum);
+			char_u *newline;
+
+			/* Insert halfway a line.  For simplicity we assume we
+			 * need to append to the line. */
+			newline = alloc_check((unsigned)(STRLEN(oldline) + len + 1));
+			if (newline != NULL)
+			{
+			    STRCPY(newline, oldline);
+			    STRCAT(newline, args);
+			    ml_replace(lnum, newline, FALSE);
+			}
+		    }
+		    else
+		    {
+			/* Append a new line.  Not that we always do this,
+			 * also when the text doesn't end in a "\n". */
+			ml_append((linenr_T)(lnum - 1), args, (colnr_T)(len + 1), FALSE);
+			++added;
+		    }
+
+		    if (nl == NULL)
+			break;
+		    ++lnum;
+		    args = nl + 1;
+		}
+
+		/* Adjust the marks below the inserted lines. */
+		appended_lines_mark(lnum_start - 1, (long)added);
+
+		/*
+		 * When starting with an empty buffer set the fileformat.
+		 * This is just guessing...
+		 */
+		if (buf_was_empty)
+		{
+		    if (ff_detected == EOL_UNKNOWN)
+#if defined(MSDOS) || defined(MSWIN) || defined(OS2)
+			ff_detected = EOL_DOS;
+#else
+			ff_detected = EOL_UNIX;
+#endif
+		    set_fileformat(ff_detected, OPT_LOCAL);
+		    curbuf->b_start_ffc = *curbuf->b_p_ff;
+		}
+
+		/*
+		 * XXX - GRP - Is the next line right? If I've inserted
+		 * text the buffer has been updated but not written. Will
+		 * netbeans guarantee to write it? Even if I do a :q! ?
+		 */
+		curbuf->b_changed = old_b_changed; /* logically unchanged */
+		netbeansFireChanges = oldFire;
+
+		/* Undo info is invalid now... */
+		u_blockfree(curbuf);
+		u_clearall(curbuf);
+	    }
+	    vim_free(to_free);
+	    nb_reply_nil(cmdno); /* or !error */
+	}
+	else
+	{
+	    nbdebug(("UNIMPLEMENTED FUNCTION: %s\n", cmd));
+	    nb_reply_nil(cmdno);
+	    retval = FAIL;
+	}
+    }
+    else /* Not a function; no reply required. */
+    {
+/* =====================================================================*/
+	if (streq((char *)cmd, "create"))
+	{
+	    /* Create a buffer without a name. */
+	    if (buf == NULL)
+	    {
+		EMSG("E636: null buf in create");
+		return FAIL;
+	    }
+	    vim_free(buf->displayname);
+	    buf->displayname = NULL;
+
+	    netbeansReadFile = 0; /* don't try to open disk file */
+	    do_ecmd(0, NULL, 0, 0, ECMD_ONE, ECMD_HIDE + ECMD_OLDBUF);
+	    netbeansReadFile = 1;
+	    buf->bufp = curbuf;
+	    maketitle();
+	    buf->insertDone = FALSE;
+	    gui_update_menus(0);
+/* =====================================================================*/
+	}
+	else if (streq((char *)cmd, "insertDone"))
+	{
+	    if (buf == NULL || buf->bufp == NULL)
+	    {
+		nbdebug(("    null bufp in insertDone"));
+	    }
+	    else
+	    {
+		buf->bufp->b_start_eol = *args == 'T';
+		buf->insertDone = TRUE;
+		args += 2;
+		buf->bufp->b_p_ro = *args == 'T';
+		print_read_msg(buf);
+	    }
+/* =====================================================================*/
+	}
+	else if (streq((char *)cmd, "saveDone"))
+	{
+	    long savedChars = atol((char *)args);
+
+	    if (buf == NULL || buf->bufp == NULL)
+	    {
+		nbdebug(("    null bufp in saveDone"));
+	    }
+	    else
+		print_save_msg(buf, savedChars);
+/* =====================================================================*/
+	}
+	else if (streq((char *)cmd, "startDocumentListen"))
+	{
+	    if (buf == NULL)
+	    {
+		EMSG("E637: null buf in startDocumentListen");
+		return FAIL;
+	    }
+	    buf->fireChanges = 1;
+/* =====================================================================*/
+	}
+	else if (streq((char *)cmd, "stopDocumentListen"))
+	{
+	    if (buf == NULL)
+	    {
+		EMSG("E638: null buf in stopDocumentListen");
+		return FAIL;
+	    }
+	    buf->fireChanges = 0;
+	    if (buf->bufp != NULL && buf->bufp->b_was_netbeans_file)
+	    {
+		if (!buf->bufp->b_netbeans_file)
+		    EMSGN(_("E658: NetBeans connection lost for buffer %ld"),
+							   buf->bufp->b_fnum);
+		else
+		{
+		    /* NetBeans uses stopDocumentListen when it stops editing
+		     * a file.  It then expects the buffer in Vim to
+		     * disappear. */
+		    do_bufdel(DOBUF_DEL, (char_u *)"", 1,
+				  buf->bufp->b_fnum, buf->bufp->b_fnum, TRUE);
+		    vim_memset(buf, 0, sizeof(nbbuf_T));
+		}
+	    }
+/* =====================================================================*/
+	}
+	else if (streq((char *)cmd, "setTitle"))
+	{
+	    if (buf == NULL)
+	    {
+		EMSG("E639: null buf in setTitle");
+		return FAIL;
+	    }
+	    vim_free(buf->displayname);
+	    buf->displayname = nb_unquote(args, NULL);
+/* =====================================================================*/
+	}
+	else if (streq((char *)cmd, "initDone"))
+	{
+	    if (buf == NULL || buf->bufp == NULL)
+	    {
+		EMSG("E640: null buf in initDone");
+		return FAIL;
+	    }
+	    doupdate = 1;
+	    buf->initDone = TRUE;
+	    nb_set_curbuf(buf->bufp);
+#if defined(FEAT_AUTOCMD)
+	    apply_autocmds(EVENT_BUFREADPOST, 0, 0, FALSE, buf->bufp);
+#endif
+
+	    /* handle any postponed key commands */
+	    handle_key_queue();
+/* =====================================================================*/
+	}
+	else if (streq((char *)cmd, "setBufferNumber")
+		|| streq((char *)cmd, "putBufferNumber"))
+	{
+	    char_u	*path;
+	    buf_T	*bufp;
+
+	    if (buf == NULL)
+	    {
+		EMSG("E641: null buf in setBufferNumber");
+		return FAIL;
+	    }
+	    path = (char_u *)nb_unquote(args, NULL);
+	    if (path == NULL)
+		return FAIL;
+	    bufp = buflist_findname(path);
+	    vim_free(path);
+	    if (bufp == NULL)
+	    {
+		EMSG2("E642: File %s not found in setBufferNumber", args);
+		return FAIL;
+	    }
+	    buf->bufp = bufp;
+	    buf->nbbuf_number = bufp->b_fnum;
+
+	    /* "setBufferNumber" has the side effect of jumping to the buffer
+	     * (don't know why!).  Don't do that for "putBufferNumber". */
+	    if (*cmd != 'p')
+		coloncmd(":buffer %d", bufp->b_fnum);
+	    else
+	    {
+		buf->initDone = TRUE;
+
+		/* handle any postponed key commands */
+		handle_key_queue();
+	    }
+
+#if 0  /* never used */
+	    buf->internalname = (char *)alloc_clear(8);
+	    sprintf(buf->internalname, "<%d>", bufno);
+	    buf->netbeansOwns = 0;
+#endif
+/* =====================================================================*/
+	}
+	else if (streq((char *)cmd, "setFullName"))
+	{
+	    if (buf == NULL)
+	    {
+		EMSG("E643: null buf in setFullName");
+		return FAIL;
+	    }
+	    vim_free(buf->displayname);
+	    buf->displayname = nb_unquote(args, NULL);
+
+	    netbeansReadFile = 0; /* don't try to open disk file */
+	    do_ecmd(0, (char_u *)buf->displayname, 0, 0, ECMD_ONE,
+						     ECMD_HIDE + ECMD_OLDBUF);
+	    netbeansReadFile = 1;
+	    buf->bufp = curbuf;
+	    maketitle();
+	    gui_update_menus(0);
+/* =====================================================================*/
+	}
+	else if (streq((char *)cmd, "editFile"))
+	{
+	    if (buf == NULL)
+	    {
+		EMSG("E644: null buf in editFile");
+		return FAIL;
+	    }
+	    /* Edit a file: like create + setFullName + read the file. */
+	    vim_free(buf->displayname);
+	    buf->displayname = nb_unquote(args, NULL);
+	    do_ecmd(0, (char_u *)buf->displayname, NULL, NULL, ECMD_ONE,
+						     ECMD_HIDE + ECMD_OLDBUF);
+	    buf->bufp = curbuf;
+	    buf->initDone = TRUE;
+	    doupdate = 1;
+#if defined(FEAT_TITLE)
+	    maketitle();
+#endif
+	    gui_update_menus(0);
+/* =====================================================================*/
+	}
+	else if (streq((char *)cmd, "setVisible"))
+	{
+	    if (buf == NULL || buf->bufp == NULL)
+	    {
+/*		EMSG("E645: null bufp in setVisible"); */
+		return FAIL;
+	    }
+	    if (streq((char *)args, "T") && buf->bufp != curbuf)
+	    {
+		exarg_T exarg;
+		exarg.cmd = (char_u *)"goto";
+		exarg.forceit = FALSE;
+		dosetvisible = TRUE;
+		goto_buffer(&exarg, DOBUF_FIRST, FORWARD, buf->bufp->b_fnum);
+		doupdate = 1;
+		dosetvisible = FALSE;
+
+		/* Side effect!!!. */
+		if (!gui.starting)
+		    gui_mch_set_foreground();
+	    }
+/* =====================================================================*/
+	}
+	else if (streq((char *)cmd, "raise"))
+	{
+	    /* Bring gvim to the foreground. */
+	    if (!gui.starting)
+		gui_mch_set_foreground();
+/* =====================================================================*/
+	}
+	else if (streq((char *)cmd, "setModified"))
+	{
+	    if (buf == NULL || buf->bufp == NULL)
+	    {
+/*		EMSG("E646: null bufp in setModified"); */
+		return FAIL;
+	    }
+	    if (streq((char *)args, "T"))
+		buf->bufp->b_changed = 1;
+	    else
+	    {
+		struct stat	st;
+
+		/* Assume NetBeans stored the file.  Reset the timestamp to
+		 * avoid "file changed" warnings. */
+		if (buf->bufp->b_ffname != NULL
+			&& mch_stat((char *)buf->bufp->b_ffname, &st) >= 0)
+		    buf_store_time(buf->bufp, &st, buf->bufp->b_ffname);
+		buf->bufp->b_changed = 0;
+	    }
+	    buf->modified = buf->bufp->b_changed;
+/* =====================================================================*/
+	}
+	else if (streq((char *)cmd, "setModtime"))
+	{
+	    if (buf == NULL || buf->bufp == NULL)
+		nbdebug(("    null bufp in setModtime"));
+	    else
+		buf->bufp->b_mtime = atoi((char *)args);
+/* =====================================================================*/
+	}
+	else if (streq((char *)cmd, "setReadOnly"))
+	{
+	    if (buf == NULL || buf->bufp == NULL)
+		nbdebug(("    null bufp in setReadOnly"));
+	    else if (streq((char *)args, "T"))
+		buf->bufp->b_p_ro = TRUE;
+	    else
+		buf->bufp->b_p_ro = FALSE;
+/* =====================================================================*/
+	}
+	else if (streq((char *)cmd, "setMark"))
+	{
+	    /* not yet */
+/* =====================================================================*/
+	}
+	else if (streq((char *)cmd, "showBalloon"))
+	{
+#if defined(FEAT_BEVAL)
+	    static char	*text = NULL;
+
+	    /*
+	     * Set up the Balloon Expression Evaluation area.
+	     * Ignore 'ballooneval' here.
+	     * The text pointer must remain valid for a while.
+	     */
+	    if (balloonEval != NULL)
+	    {
+		vim_free(text);
+		text = nb_unquote(args, NULL);
+		if (text != NULL)
+		    gui_mch_post_balloon(balloonEval, (char_u *)text);
+	    }
+#endif
+/* =====================================================================*/
+	}
+	else if (streq((char *)cmd, "setDot"))
+	{
+	    pos_T *pos;
+#ifdef NBDEBUG
+	    char_u *s;
+#endif
+
+	    if (buf == NULL || buf->bufp == NULL)
+	    {
+		EMSG("E647: null bufp in setDot");
+		return FAIL;
+	    }
+
+	    nb_set_curbuf(buf->bufp);
+
+#ifdef FEAT_VISUAL
+	    /* Don't want Visual mode now. */
+	    if (VIsual_active)
+		end_visual_mode();
+#endif
+#ifdef NBDEBUG
+	    s = args;
+#endif
+	    pos = get_off_or_lnum(buf->bufp, &args);
+	    if (pos)
+	    {
+		curwin->w_cursor = *pos;
+		check_cursor();
+#ifdef FEAT_FOLDING
+		foldOpenCursor();
+#endif
+	    }
+	    else
+		nbdebug(("    BAD POSITION in setDot: %s\n", s));
+
+	    /* gui_update_cursor(TRUE, FALSE); */
+	    /* update_curbuf(NOT_VALID); */
+	    update_topline();		/* scroll to show the line */
+	    update_screen(VALID);
+	    setcursor();
+	    out_flush();
+	    gui_update_cursor(TRUE, FALSE);
+	    gui_mch_flush();
+	    /* Quit a hit-return or more prompt. */
+	    if (State == HITRETURN || State == ASKMORE)
+	    {
+#ifdef FEAT_GUI_GTK
+		if (gtk_main_level() > 0)
+		    gtk_main_quit();
+#endif
+	    }
+/* =====================================================================*/
+	}
+	else if (streq((char *)cmd, "close"))
+	{
+#ifdef NBDEBUG
+	    char *name = "<NONE>";
+#endif
+
+	    if (buf == NULL)
+	    {
+		EMSG("E648: null buf in close");
+		return FAIL;
+	    }
+
+#ifdef NBDEBUG
+	    if (buf->displayname != NULL)
+		name = buf->displayname;
+#endif
+/*	    if (buf->bufp == NULL) */
+/*		EMSG("E649: null bufp in close"); */
+	    nbdebug(("    CLOSE %d: %s\n", bufno, name));
+	    need_mouse_correct = TRUE;
+	    if (buf->bufp != NULL)
+		do_buffer(DOBUF_WIPE, DOBUF_FIRST, FORWARD,
+						     buf->bufp->b_fnum, TRUE);
+	    buf->bufp = NULL;
+	    buf->initDone = FALSE;
+	    doupdate = 1;
+/* =====================================================================*/
+	}
+	else if (streq((char *)cmd, "setStyle")) /* obsolete... */
+	{
+	    nbdebug(("    setStyle is obsolete!"));
+/* =====================================================================*/
+	}
+	else if (streq((char *)cmd, "setExitDelay"))
+	{
+	    /* Only used in version 2.1. */
+/* =====================================================================*/
+	}
+	else if (streq((char *)cmd, "defineAnnoType"))
+	{
+#ifdef FEAT_SIGNS
+	    int typeNum;
+	    char_u *typeName;
+	    char_u *tooltip;
+	    char_u *p;
+	    char_u *glyphFile;
+	    int use_fg = 0;
+	    int use_bg = 0;
+	    int fg = -1;
+	    int bg = -1;
+
+	    if (buf == NULL)
+	    {
+		EMSG("E650: null buf in defineAnnoType");
+		return FAIL;
+	    }
+
+	    cp = (char *)args;
+	    typeNum = strtol(cp, &cp, 10);
+	    args = (char_u *)cp;
+	    args = skipwhite(args);
+	    typeName = (char_u *)nb_unquote(args, &args);
+	    args = skipwhite(args + 1);
+	    tooltip = (char_u *)nb_unquote(args, &args);
+	    args = skipwhite(args + 1);
+
+	    p = (char_u *)nb_unquote(args, &args);
+	    glyphFile = vim_strsave_escaped(p, escape_chars);
+	    vim_free(p);
+
+	    args = skipwhite(args + 1);
+	    if (STRNCMP(args, "none", 4) == 0)
+		args += 5;
+	    else
+	    {
+		use_fg = 1;
+		cp = (char *)args;
+		fg = strtol(cp, &cp, 10);
+		args = (char_u *)cp;
+	    }
+	    if (STRNCMP(args, "none", 4) == 0)
+		args += 5;
+	    else
+	    {
+		use_bg = 1;
+		cp = (char *)args;
+		bg = strtol(cp, &cp, 10);
+		args = (char_u *)cp;
+	    }
+	    if (typeName != NULL && tooltip != NULL && glyphFile != NULL)
+		addsigntype(buf, typeNum, typeName, tooltip, glyphFile,
+						      use_fg, fg, use_bg, bg);
+	    else
+		vim_free(typeName);
+
+	    /* don't free typeName; it's used directly in addsigntype() */
+	    vim_free(tooltip);
+	    vim_free(glyphFile);
+
+#endif
+/* =====================================================================*/
+	}
+	else if (streq((char *)cmd, "addAnno"))
+	{
+#ifdef FEAT_SIGNS
+	    int serNum;
+	    int localTypeNum;
+	    int typeNum;
+# ifdef NBDEBUG
+	    int len;
+# endif
+	    pos_T *pos;
+
+	    if (buf == NULL || buf->bufp == NULL)
+	    {
+		EMSG("E651: null bufp in addAnno");
+		return FAIL;
+	    }
+
+	    doupdate = 1;
+
+	    cp = (char *)args;
+	    serNum = strtol(cp, &cp, 10);
+
+	    /* Get the typenr specific for this buffer and convert it to
+	     * the global typenumber, as used for the sign name. */
+	    localTypeNum = strtol(cp, &cp, 10);
+	    args = (char_u *)cp;
+	    typeNum = mapsigntype(buf, localTypeNum);
+
+	    pos = get_off_or_lnum(buf->bufp, &args);
+
+	    cp = (char *)args;
+# ifdef NBDEBUG
+	    len =
+# endif
+		strtol(cp, &cp, 10);
+	    args = (char_u *)cp;
+# ifdef NBDEBUG
+	    if (len != -1)
+	    {
+		nbdebug(("    partial line annotation -- Not Yet Implemented!"));
+	    }
+# endif
+	    if (serNum >= GUARDEDOFFSET)
+	    {
+		nbdebug(("    too many annotations! ignoring..."));
+		return FAIL;
+	    }
+	    if (pos)
+	    {
+		coloncmd(":sign place %d line=%d name=%d buffer=%d",
+			   serNum, pos->lnum, typeNum, buf->bufp->b_fnum);
+		if (typeNum == curPCtype)
+		    coloncmd(":sign jump %d buffer=%d", serNum,
+						       buf->bufp->b_fnum);
+	    }
+#endif
+/* =====================================================================*/
+	}
+	else if (streq((char *)cmd, "removeAnno"))
+	{
+#ifdef FEAT_SIGNS
+	    int serNum;
+
+	    if (buf == NULL || buf->bufp == NULL)
+	    {
+		nbdebug(("    null bufp in removeAnno"));
+		return FAIL;
+	    }
+	    doupdate = 1;
+	    cp = (char *)args;
+	    serNum = strtol(cp, &cp, 10);
+	    args = (char_u *)cp;
+	    coloncmd(":sign unplace %d buffer=%d",
+		     serNum, buf->bufp->b_fnum);
+	    redraw_buf_later(buf->bufp, NOT_VALID);
+#endif
+/* =====================================================================*/
+	}
+	else if (streq((char *)cmd, "moveAnnoToFront"))
+	{
+#ifdef FEAT_SIGNS
+	    nbdebug(("    moveAnnoToFront: Not Yet Implemented!"));
+#endif
+/* =====================================================================*/
+	}
+	else if (streq((char *)cmd, "guard") || streq((char *)cmd, "unguard"))
+	{
+	    int len;
+	    pos_T first;
+	    pos_T last;
+	    pos_T *pos;
+	    int un = (cmd[0] == 'u');
+	    static int guardId = GUARDEDOFFSET;
+
+	    if (skip >= SKIP_STOP)
+	    {
+		nbdebug(("    Skipping %s command\n", (char *) cmd));
+		return OK;
+	    }
+
+	    nb_init_graphics();
+
+	    if (buf == NULL || buf->bufp == NULL)
+	    {
+		nbdebug(("    null bufp in %s command", cmd));
+		return FAIL;
+	    }
+	    nb_set_curbuf(buf->bufp);
+	    cp = (char *)args;
+	    off = strtol(cp, &cp, 10);
+	    len = strtol(cp, NULL, 10);
+	    args = (char_u *)cp;
+	    pos = off2pos(buf->bufp, off);
+	    doupdate = 1;
+	    if (!pos)
+		nbdebug(("    no such start pos in %s, %ld\n", cmd, off));
+	    else
+	    {
+		first = *pos;
+		pos = off2pos(buf->bufp, off + len - 1);
+		if (pos != NULL && pos->col == 0)
+		{
+			/*
+			 * In Java Swing the offset is a position between 2
+			 * characters. If col == 0 then we really want the
+			 * previous line as the end.
+			 */
+			pos = off2pos(buf->bufp, off + len - 2);
+		}
+		if (!pos)
+		    nbdebug(("    no such end pos in %s, %ld\n",
+			    cmd, off + len - 1));
+		else
+		{
+		    long lnum;
+		    last = *pos;
+		    /* set highlight for region */
+		    nbdebug(("    %sGUARD %ld,%d to %ld,%d\n", (un) ? "UN" : "",
+			     first.lnum, first.col,
+			     last.lnum, last.col));
+#ifdef FEAT_SIGNS
+		    for (lnum = first.lnum; lnum <= last.lnum; lnum++)
+		    {
+			if (un)
+			{
+			    /* never used */
+			}
+			else
+			{
+			    if (buf_findsigntype_id(buf->bufp, lnum,
+				GUARDED) == 0)
+			    {
+				coloncmd(
+				    ":sign place %d line=%d name=%d buffer=%d",
+				     guardId++, lnum, GUARDED,
+				     buf->bufp->b_fnum);
+			    }
+			}
+		    }
+#endif
+		    redraw_buf_later(buf->bufp, NOT_VALID);
+		}
+	    }
+/* =====================================================================*/
+	}
+	else if (streq((char *)cmd, "startAtomic"))
+	{
+	    inAtomic = 1;
+/* =====================================================================*/
+	}
+	else if (streq((char *)cmd, "endAtomic"))
+	{
+	    inAtomic = 0;
+	    if (needupdate)
+	    {
+		doupdate = 1;
+		needupdate = 0;
+	    }
+/* =====================================================================*/
+	}
+	else if (streq((char *)cmd, "save"))
+	{
+	    /*
+	     * NOTE - This command is obsolete wrt NetBeans. Its left in
+	     * only for historical reasons.
+	     */
+	    if (buf == NULL || buf->bufp == NULL)
+	    {
+		nbdebug(("    null bufp in %s command", cmd));
+		return FAIL;
+	    }
+
+	    /* the following is taken from ex_cmds.c (do_wqall function) */
+	    if (bufIsChanged(buf->bufp))
+	    {
+		/* Only write if the buffer can be written. */
+		if (p_write
+			&& !buf->bufp->b_p_ro
+			&& buf->bufp->b_ffname != NULL
+#ifdef FEAT_QUICKFIX
+			&& !bt_dontwrite(buf->bufp)
+#endif
+			)
+		{
+		    buf_write_all(buf->bufp, FALSE);
+#ifdef FEAT_AUTOCMD
+		    /* an autocommand may have deleted the buffer */
+		    if (!buf_valid(buf->bufp))
+			buf->bufp = NULL;
+#endif
+		}
+	    }
+/* =====================================================================*/
+	}
+	else if (streq((char *)cmd, "netbeansBuffer"))
+	{
+	    if (buf == NULL || buf->bufp == NULL)
+	    {
+		nbdebug(("    null bufp in %s command", cmd));
+		return FAIL;
+	    }
+	    if (*args == 'T')
+	    {
+		buf->bufp->b_netbeans_file = TRUE;
+		buf->bufp->b_was_netbeans_file = TRUE;
+	    }
+	    else
+		buf->bufp->b_netbeans_file = FALSE;
+/* =====================================================================*/
+	}
+	else if (streq((char *)cmd, "specialKeys"))
+	{
+	    special_keys(args);
+/* =====================================================================*/
+	}
+	else if (streq((char *)cmd, "actionMenuItem"))
+	{
+	    /* not used yet */
+/* =====================================================================*/
+	}
+	else if (streq((char *)cmd, "version"))
+	{
+	    /* not used yet */
+	}
+	/*
+	 * Unrecognized command is ignored.
+	 */
+    }
+    if (inAtomic && doupdate)
+    {
+	needupdate = 1;
+	doupdate = 0;
+    }
+
+    /*
+     * Is this needed? I moved the netbeans_Xt_connect() later during startup
+     * and it may no longer be necessary. If its not needed then needupdate
+     * and doupdate can also be removed.
+     */
+    if (buf != NULL && buf->initDone && doupdate)
+    {
+	update_screen(NOT_VALID);
+	setcursor();
+	out_flush();
+	gui_update_cursor(TRUE, FALSE);
+	gui_mch_flush();
+	/* Quit a hit-return or more prompt. */
+	if (State == HITRETURN || State == ASKMORE)
+	{
+#ifdef FEAT_GUI_GTK
+	    if (gtk_main_level() > 0)
+		gtk_main_quit();
+#endif
+	}
+    }
+
+    return retval;
+}
+
+
+/*
+ * If "buf" is not the current buffer try changing to a window that edits this
+ * buffer.  If there is no such window then close the current buffer and set
+ * the current buffer as "buf".
+ */
+    static void
+nb_set_curbuf(buf)
+    buf_T *buf;
+{
+    if (curbuf != buf && buf_jump_open_win(buf) == NULL)
+	set_curbuf(buf, DOBUF_GOTO);
+}
+
+/*
+ * Process a vim colon command.
+ */
+    static void
+coloncmd(char *cmd, ...)
+{
+    char buf[1024];
+    va_list ap;
+
+    va_start(ap, cmd);
+    vsprintf(buf, cmd, ap);
+    va_end(ap);
+
+    nbdebug(("    COLONCMD %s\n", buf));
+
+/*     ALT_INPUT_LOCK_ON; */
+    do_cmdline((char_u *)buf, NULL, NULL, DOCMD_NOWAIT | DOCMD_KEYTYPED);
+/*     ALT_INPUT_LOCK_OFF; */
+
+    setcursor();		/* restore the cursor position */
+    out_flush();		/* make sure output has been written */
+
+    gui_update_cursor(TRUE, FALSE);
+    gui_mch_flush();
+}
+
+
+/*
+ * Parse the specialKeys argument and issue the appropriate map commands.
+ */
+    static void
+special_keys(char_u *args)
+{
+    char *save_str = nb_unquote(args, NULL);
+    char *tok = strtok(save_str, " ");
+    char *sep;
+    char keybuf[64];
+    char cmdbuf[256];
+
+    while (tok != NULL)
+    {
+	int i = 0;
+
+	if ((sep = strchr(tok, '-')) != NULL)
+	{
+	    *sep = NUL;
+	    while (*tok)
+	    {
+		switch (*tok)
+		{
+		    case 'A':
+		    case 'M':
+		    case 'C':
+		    case 'S':
+			keybuf[i++] = *tok;
+			keybuf[i++] = '-';
+			break;
+		}
+		tok++;
+	    }
+	    tok++;
+	}
+
+	strcpy(&keybuf[i], tok);
+	vim_snprintf(cmdbuf, sizeof(cmdbuf),
+				"<silent><%s> :nbkey %s<CR>", keybuf, keybuf);
+	do_map(0, (char_u *)cmdbuf, NORMAL, FALSE);
+	tok = strtok(NULL, " ");
+    }
+    vim_free(save_str);
+}
+
+
+    void
+ex_nbkey(eap)
+    exarg_T	*eap;
+{
+    netbeans_keystring(0, (char *)eap->arg);
+}
+
+
+/*
+ * Initialize highlights and signs for use by netbeans  (mostly obsolete)
+ */
+    static void
+nb_init_graphics(void)
+{
+    static int did_init = FALSE;
+
+    if (!did_init)
+    {
+	coloncmd(":highlight NBGuarded guibg=Cyan guifg=Black");
+	coloncmd(":sign define %d linehl=NBGuarded", GUARDED);
+
+	did_init = TRUE;
+    }
+}
+
+/*
+ * Convert key to netbeans name.
+ */
+    static void
+netbeans_keyname(int key, char *buf)
+{
+    char *name = 0;
+    char namebuf[2];
+    int ctrl  = 0;
+    int shift = 0;
+    int alt   = 0;
+
+    if (mod_mask & MOD_MASK_CTRL)
+	ctrl = 1;
+    if (mod_mask & MOD_MASK_SHIFT)
+	shift = 1;
+    if (mod_mask & MOD_MASK_ALT)
+	alt = 1;
+
+
+    switch (key)
+    {
+	case K_F1:		name = "F1";		break;
+	case K_S_F1:	name = "F1";	shift = 1;	break;
+	case K_F2:		name = "F2";		break;
+	case K_S_F2:	name = "F2";	shift = 1;	break;
+	case K_F3:		name = "F3";		break;
+	case K_S_F3:	name = "F3";	shift = 1;	break;
+	case K_F4:		name = "F4";		break;
+	case K_S_F4:	name = "F4";	shift = 1;	break;
+	case K_F5:		name = "F5";		break;
+	case K_S_F5:	name = "F5";	shift = 1;	break;
+	case K_F6:		name = "F6";		break;
+	case K_S_F6:	name = "F6";	shift = 1;	break;
+	case K_F7:		name = "F7";		break;
+	case K_S_F7:	name = "F7";	shift = 1;	break;
+	case K_F8:		name = "F8";		break;
+	case K_S_F8:	name = "F8";	shift = 1;	break;
+	case K_F9:		name = "F9";		break;
+	case K_S_F9:	name = "F9";	shift = 1;	break;
+	case K_F10:		name = "F10";		break;
+	case K_S_F10:	name = "F10";	shift = 1;	break;
+	case K_F11:		name = "F11";		break;
+	case K_S_F11:	name = "F11";	shift = 1;	break;
+	case K_F12:		name = "F12";		break;
+	case K_S_F12:	name = "F12";	shift = 1;	break;
+	default:
+			if (key >= ' ' && key <= '~')
+			{
+			    /* Allow ASCII characters. */
+			    name = namebuf;
+			    namebuf[0] = key;
+			    namebuf[1] = NUL;
+			}
+			else
+			    name = "X";
+			break;
+    }
+
+    buf[0] = '\0';
+    if (ctrl)
+	strcat(buf, "C");
+    if (shift)
+	strcat(buf, "S");
+    if (alt)
+	strcat(buf, "M"); /* META */
+    if (ctrl || shift || alt)
+	strcat(buf, "-");
+    strcat(buf, name);
+}
+
+#ifdef FEAT_BEVAL
+/*
+ * Function to be called for balloon evaluation.  Grabs the text under the
+ * cursor and sends it to the debugger for evaluation.  The debugger should
+ * respond with a showBalloon command when there is a useful result.
+ */
+/*ARGSUSED*/
+    void
+netbeans_beval_cb(
+	BalloonEval	*beval,
+	int		 state)
+{
+    win_T	*wp;
+    char_u	*text;
+    linenr_T	lnum;
+    int		col;
+    char	buf[MAXPATHL * 2 + 25];
+    char_u	*p;
+
+    /* Don't do anything when 'ballooneval' is off, messages scrolled the
+     * windows up or we have no connection. */
+    if (!p_beval || msg_scrolled > 0 || !haveConnection)
+	return;
+
+    if (get_beval_info(beval, TRUE, &wp, &lnum, &text, &col) == OK)
+    {
+	/* Send debugger request.  Only when the text is of reasonable
+	 * length. */
+	if (text != NULL && text[0] != NUL && STRLEN(text) < MAXPATHL)
+	{
+	    p = nb_quote(text);
+	    if (p != NULL)
+	    {
+		vim_snprintf(buf, sizeof(buf),
+				       "0:balloonText=%d \"%s\"\n", r_cmdno, p);
+		vim_free(p);
+	    }
+	    nbdebug(("EVT: %s", buf));
+	    nb_send(buf, "netbeans_beval_cb");
+	}
+	vim_free(text);
+    }
+}
+#endif
+
+/*
+ * Tell netbeans that the window was opened, ready for commands.
+ */
+    void
+netbeans_startup_done(void)
+{
+    char *cmd = "0:startupDone=0\n";
+
+    if (usingNetbeans)
+#ifdef FEAT_GUI_MOTIF
+	netbeans_Xt_connect(app_context);
+#else
+# ifdef FEAT_GUI_GTK
+	netbeans_gtk_connect();
+# else
+#  ifdef FEAT_GUI_W32
+	netbeans_w32_connect();
+#  endif
+# endif
+#endif
+
+    if (!haveConnection)
+	return;
+
+#ifdef FEAT_BEVAL
+    bevalServers |= BEVAL_NETBEANS;
+#endif
+
+    nbdebug(("EVT: %s", cmd));
+    nb_send(cmd, "netbeans_startup_done");
+}
+
+/*
+ * Tell netbeans that we're exiting. This should be called right
+ * before calling exit.
+ */
+    void
+netbeans_send_disconnect()
+{
+    char buf[128];
+
+    if (haveConnection)
+    {
+	sprintf(buf, "0:disconnect=%d\n", r_cmdno);
+	nbdebug(("EVT: %s", buf));
+	nb_send(buf, "netbeans_disconnect");
+    }
+}
+
+#if defined(FEAT_GUI_MOTIF) || defined(FEAT_GUI_W32) || defined(PROTO)
+/*
+ * Tell netbeans that the window was moved or resized.
+ */
+    void
+netbeans_frame_moved(int new_x, int new_y)
+{
+    char buf[128];
+
+    if (!haveConnection)
+	return;
+
+    sprintf(buf, "0:geometry=%d %d %d %d %d\n",
+		    r_cmdno, (int)Columns, (int)Rows, new_x, new_y);
+    /*nbdebug(("EVT: %s", buf)); happens too many times during a move */
+    nb_send(buf, "netbeans_frame_moved");
+}
+#endif
+
+/*
+ * Tell netbeans the user opened or activated a file.
+ */
+    void
+netbeans_file_activated(buf_T *bufp)
+{
+    int bufno = nb_getbufno(bufp);
+    nbbuf_T *bp = nb_get_buf(bufno);
+    char    buffer[2*MAXPATHL];
+    char_u  *q;
+
+    if (!haveConnection || dosetvisible)
+	return;
+
+    q = nb_quote(bufp->b_ffname);
+    if (q == NULL || bp == NULL)
+	return;
+
+    vim_snprintf(buffer, sizeof(buffer),  "%d:fileOpened=%d \"%s\" %s %s\n",
+	    bufno,
+	    bufno,
+	    (char *)q,
+	    "T",  /* open in NetBeans */
+	    "F"); /* modified */
+
+    vim_free(q);
+    nbdebug(("EVT: %s", buffer));
+
+    nb_send(buffer, "netbeans_file_opened");
+}
+
+/*
+ * Tell netbeans the user opened a file.
+ */
+    void
+netbeans_file_opened(buf_T *bufp)
+{
+    int bufno = nb_getbufno(bufp);
+    char    buffer[2*MAXPATHL];
+    char_u  *q;
+    nbbuf_T *bp = nb_get_buf(nb_getbufno(bufp));
+    int	    bnum;
+
+    if (!haveConnection)
+	return;
+
+    q = nb_quote(bufp->b_ffname);
+    if (q == NULL)
+	return;
+    if (bp != NULL)
+	bnum = bufno;
+    else
+	bnum = 0;
+
+    vim_snprintf(buffer, sizeof(buffer), "%d:fileOpened=%d \"%s\" %s %s\n",
+	    bnum,
+	    0,
+	    (char *)q,
+	    "T",  /* open in NetBeans */
+	    "F"); /* modified */
+
+    vim_free(q);
+    nbdebug(("EVT: %s", buffer));
+
+    nb_send(buffer, "netbeans_file_opened");
+    if (p_acd && vim_chdirfile(bufp->b_ffname) == OK)
+	shorten_fnames(TRUE);
+}
+
+/*
+ * Tell netbeans a file was closed.
+ */
+    void
+netbeans_file_closed(buf_T *bufp)
+{
+    int		bufno = nb_getbufno(bufp);
+    nbbuf_T	*nbbuf = nb_get_buf(bufno);
+    char	buffer[2*MAXPATHL];
+
+    if (!haveConnection || bufno < 0)
+	return;
+
+    if (!netbeansCloseFile)
+    {
+	nbdebug(("Ignoring file_closed for %s. File was closed from IDE\n",
+		    bufp->b_ffname));
+	return;
+    }
+
+    nbdebug(("netbeans_file_closed:\n"));
+    nbdebug(("    Closing bufno: %d", bufno));
+    if (curbuf != NULL && curbuf != bufp)
+    {
+	nbdebug(("    Curbuf bufno:  %d\n", nb_getbufno(curbuf)));
+    }
+    else if (curbuf == bufp)
+    {
+	nbdebug(("    curbuf == bufp\n"));
+    }
+
+    if (bufno <= 0)
+	return;
+
+    sprintf(buffer, "%d:killed=%d\n", bufno, r_cmdno);
+
+    nbdebug(("EVT: %s", buffer));
+
+    nb_send(buffer, "netbeans_file_closed");
+
+    if (nbbuf != NULL)
+	nbbuf->bufp = NULL;
+}
+
+/*
+ * Get a pointer to the Netbeans buffer for Vim buffer "bufp".
+ * Return NULL if there is no such buffer or changes are not to be reported.
+ * Otherwise store the buffer number in "*bufnop".
+ */
+    static nbbuf_T *
+nb_bufp2nbbuf_fire(buf_T *bufp, int *bufnop)
+{
+    int		bufno;
+    nbbuf_T	*nbbuf;
+
+    if (!haveConnection || !netbeansFireChanges)
+	return NULL;		/* changes are not reported at all */
+
+    bufno = nb_getbufno(bufp);
+    if (bufno <= 0)
+	return NULL;		/* file is not known to NetBeans */
+
+    nbbuf = nb_get_buf(bufno);
+    if (nbbuf != NULL && !nbbuf->fireChanges)
+	return NULL;		/* changes in this buffer are not reported */
+
+    *bufnop = bufno;
+    return nbbuf;
+}
+
+/*
+ * Tell netbeans the user inserted some text.
+ */
+    void
+netbeans_inserted(
+    buf_T	*bufp,
+    linenr_T	linenr,
+    colnr_T	col,
+    char_u	*txt,
+    int		newlen)
+{
+    char_u	*buf;
+    int		bufno;
+    nbbuf_T	*nbbuf;
+    pos_T	pos;
+    long	off;
+    char_u	*p;
+    char_u	*newtxt;
+
+    nbbuf = nb_bufp2nbbuf_fire(bufp, &bufno);
+    if (nbbuf == NULL)
+	return;
+
+    /* Don't mark as modified for initial read */
+    if (nbbuf->insertDone)
+	nbbuf->modified = 1;
+
+    pos.lnum = linenr;
+    pos.col = col;
+    off = pos2off(bufp, &pos);
+
+    /* send the "insert" EVT */
+    newtxt = alloc(newlen + 1);
+    vim_strncpy(newtxt, txt, newlen);
+    p = nb_quote(newtxt);
+    if (p != NULL)
+    {
+	buf = alloc(128 + 2*newlen);
+	sprintf((char *)buf, "%d:insert=%d %ld \"%s\"\n",
+						      bufno, r_cmdno, off, p);
+	nbdebug(("EVT: %s", buf));
+	nb_send((char *)buf, "netbeans_inserted");
+	vim_free(p);
+	vim_free(buf);
+    }
+    vim_free(newtxt);
+}
+
+/*
+ * Tell netbeans some bytes have been removed.
+ */
+    void
+netbeans_removed(
+    buf_T	*bufp,
+    linenr_T	linenr,
+    colnr_T	col,
+    long	len)
+{
+    char_u	buf[128];
+    int		bufno;
+    nbbuf_T	*nbbuf;
+    pos_T	pos;
+    long	off;
+
+    nbbuf = nb_bufp2nbbuf_fire(bufp, &bufno);
+    if (nbbuf == NULL)
+	return;
+
+    if (len < 0)
+    {
+	nbdebug(("Negative len %ld in netbeans_removed()!", len));
+	return;
+    }
+
+    nbbuf->modified = 1;
+
+    pos.lnum = linenr;
+    pos.col = col;
+
+    off = pos2off(bufp, &pos);
+
+    sprintf((char *)buf, "%d:remove=%d %ld %ld\n", bufno, r_cmdno, off, len);
+    nbdebug(("EVT: %s", buf));
+    nb_send((char *)buf, "netbeans_removed");
+}
+
+/*
+ * Send netbeans an unmodufied command.
+ */
+/*ARGSUSED*/
+    void
+netbeans_unmodified(buf_T *bufp)
+{
+#if 0
+    char_u	buf[128];
+    int		bufno;
+    nbbuf_T	*nbbuf;
+
+    /* This has been disabled, because NetBeans considers a buffer modified
+     * even when all changes have been undone. */
+    nbbuf = nb_bufp2nbbuf_fire(bufp, &bufno);
+    if (nbbuf == NULL)
+	return;
+
+    nbbuf->modified = 0;
+
+    sprintf((char *)buf, "%d:unmodified=%d\n", bufno, r_cmdno);
+    nbdebug(("EVT: %s", buf));
+    nb_send((char *)buf, "netbeans_unmodified");
+#endif
+}
+
+/*
+ * Send a button release event back to netbeans. Its up to netbeans
+ * to decide what to do (if anything) with this event.
+ */
+    void
+netbeans_button_release(int button)
+{
+    char	buf[128];
+    int		bufno;
+
+    bufno = nb_getbufno(curbuf);
+
+    if (bufno >= 0 && curwin != NULL && curwin->w_buffer == curbuf)
+    {
+	int col = mouse_col - W_WINCOL(curwin) - (curwin->w_p_nu ? 9 : 1);
+	long off = pos2off(curbuf, &curwin->w_cursor);
+
+	/* sync the cursor position */
+	sprintf(buf, "%d:newDotAndMark=%d %ld %ld\n", bufno, r_cmdno, off, off);
+	nbdebug(("EVT: %s", buf));
+	nb_send(buf, "netbeans_button_release[newDotAndMark]");
+
+	sprintf(buf, "%d:buttonRelease=%d %d %ld %d\n", bufno, r_cmdno,
+				    button, (long)curwin->w_cursor.lnum, col);
+	nbdebug(("EVT: %s", buf));
+	nb_send(buf, "netbeans_button_release");
+    }
+}
+
+
+/*
+ * Send a keypress event back to netbeans. This usually simulates some
+ * kind of function key press. This function operates on a key code.
+ */
+    void
+netbeans_keycommand(int key)
+{
+    char	keyName[60];
+
+    netbeans_keyname(key, keyName);
+    netbeans_keystring(key, keyName);
+}
+
+
+/*
+ * Send a keypress event back to netbeans. This usually simulates some
+ * kind of function key press. This function operates on a key string.
+ */
+    static void
+netbeans_keystring(int key, char *keyName)
+{
+    char	buf[2*MAXPATHL];
+    int		bufno = nb_getbufno(curbuf);
+    long	off;
+    char_u	*q;
+
+    if (!haveConnection)
+	return;
+
+
+    if (bufno == -1)
+    {
+	nbdebug(("got keycommand for non-NetBeans buffer, opening...\n"));
+	q = curbuf->b_ffname == NULL ? (char_u *)""
+						 : nb_quote(curbuf->b_ffname);
+	if (q == NULL)
+	    return;
+	vim_snprintf(buf, sizeof(buf), "0:fileOpened=%d \"%s\" %s %s\n", 0,
+		q,
+		"T",  /* open in NetBeans */
+		"F"); /* modified */
+	if (curbuf->b_ffname != NULL)
+	    vim_free(q);
+	nbdebug(("EVT: %s", buf));
+	nb_send(buf, "netbeans_keycommand");
+
+	if (key > 0)
+	    postpone_keycommand(key);
+	return;
+    }
+
+    /* sync the cursor position */
+    off = pos2off(curbuf, &curwin->w_cursor);
+    sprintf(buf, "%d:newDotAndMark=%d %ld %ld\n", bufno, r_cmdno, off, off);
+    nbdebug(("EVT: %s", buf));
+    nb_send(buf, "netbeans_keycommand");
+
+    /* To work on Win32 you must apply patch to ExtEditor module
+     * from ExtEdCaret.java.diff - make EVT_newDotAndMark handler
+     * more synchronous
+     */
+
+    /* now send keyCommand event */
+    vim_snprintf(buf, sizeof(buf), "%d:keyCommand=%d \"%s\"\n",
+						     bufno, r_cmdno, keyName);
+    nbdebug(("EVT: %s", buf));
+    nb_send(buf, "netbeans_keycommand");
+
+    /* New: do both at once and include the lnum/col. */
+    vim_snprintf(buf, sizeof(buf), "%d:keyAtPos=%d \"%s\" %ld %ld/%ld\n",
+	    bufno, r_cmdno, keyName,
+		off, (long)curwin->w_cursor.lnum, (long)curwin->w_cursor.col);
+    nbdebug(("EVT: %s", buf));
+    nb_send(buf, "netbeans_keycommand");
+}
+
+
+/*
+ * Send a save event to netbeans.
+ */
+    void
+netbeans_save_buffer(buf_T *bufp)
+{
+    char_u	buf[64];
+    int		bufno;
+    nbbuf_T	*nbbuf;
+
+    nbbuf = nb_bufp2nbbuf_fire(bufp, &bufno);
+    if (nbbuf == NULL)
+	return;
+
+    nbbuf->modified = 0;
+
+    sprintf((char *)buf, "%d:save=%d\n", bufno, r_cmdno);
+    nbdebug(("EVT: %s", buf));
+    nb_send((char *)buf, "netbeans_save_buffer");
+}
+
+
+/*
+ * Send remove command to netbeans (this command has been turned off).
+ */
+    void
+netbeans_deleted_all_lines(buf_T *bufp)
+{
+    char_u	buf[64];
+    int		bufno;
+    nbbuf_T	*nbbuf;
+
+    nbbuf = nb_bufp2nbbuf_fire(bufp, &bufno);
+    if (nbbuf == NULL)
+	return;
+
+    /* Don't mark as modified for initial read */
+    if (nbbuf->insertDone)
+	nbbuf->modified = 1;
+
+    sprintf((char *)buf, "%d:remove=%d 0 -1\n", bufno, r_cmdno);
+    nbdebug(("EVT(suppressed): %s", buf));
+/*     nb_send(buf, "netbeans_deleted_all_lines"); */
+}
+
+
+/*
+ * See if the lines are guarded. The top and bot parameters are from
+ * u_savecommon(), these are the line above the change and the line below the
+ * change.
+ */
+    int
+netbeans_is_guarded(linenr_T top, linenr_T bot)
+{
+    signlist_T	*p;
+    int		lnum;
+
+    for (p = curbuf->b_signlist; p != NULL; p = p->next)
+	if (p->id >= GUARDEDOFFSET)
+	    for (lnum = top + 1; lnum < bot; lnum++)
+		if (lnum == p->lnum)
+		    return TRUE;
+
+    return FALSE;
+}
+
+#if defined(FEAT_GUI_MOTIF) || defined(PROTO)
+/*
+ * We have multiple signs to draw at the same location. Draw the
+ * multi-sign indicator instead. This is the Motif version.
+ */
+    void
+netbeans_draw_multisign_indicator(int row)
+{
+    int i;
+    int y;
+    int x;
+
+    x = 0;
+    y = row * gui.char_height + 2;
+
+    for (i = 0; i < gui.char_height - 3; i++)
+	XDrawPoint(gui.dpy, gui.wid, gui.text_gc, x+2, y++);
+
+    XDrawPoint(gui.dpy, gui.wid, gui.text_gc, x+0, y);
+    XDrawPoint(gui.dpy, gui.wid, gui.text_gc, x+2, y);
+    XDrawPoint(gui.dpy, gui.wid, gui.text_gc, x+4, y++);
+    XDrawPoint(gui.dpy, gui.wid, gui.text_gc, x+1, y);
+    XDrawPoint(gui.dpy, gui.wid, gui.text_gc, x+2, y);
+    XDrawPoint(gui.dpy, gui.wid, gui.text_gc, x+3, y++);
+    XDrawPoint(gui.dpy, gui.wid, gui.text_gc, x+2, y);
+}
+#endif /* FEAT_GUI_MOTIF */
+
+#ifdef FEAT_GUI_GTK
+/*
+ * We have multiple signs to draw at the same location. Draw the
+ * multi-sign indicator instead. This is the GTK/Gnome version.
+ */
+    void
+netbeans_draw_multisign_indicator(int row)
+{
+    int i;
+    int y;
+    int x;
+    GdkDrawable *drawable = gui.drawarea->window;
+
+    x = 0;
+    y = row * gui.char_height + 2;
+
+    for (i = 0; i < gui.char_height - 3; i++)
+	gdk_draw_point(drawable, gui.text_gc, x+2, y++);
+
+    gdk_draw_point(drawable, gui.text_gc, x+0, y);
+    gdk_draw_point(drawable, gui.text_gc, x+2, y);
+    gdk_draw_point(drawable, gui.text_gc, x+4, y++);
+    gdk_draw_point(drawable, gui.text_gc, x+1, y);
+    gdk_draw_point(drawable, gui.text_gc, x+2, y);
+    gdk_draw_point(drawable, gui.text_gc, x+3, y++);
+    gdk_draw_point(drawable, gui.text_gc, x+2, y);
+}
+#endif /* FEAT_GUI_GTK */
+
+/*
+ * If the mouse is clicked in the gutter of a line with multiple
+ * annotations, cycle through the set of signs.
+ */
+    void
+netbeans_gutter_click(linenr_T lnum)
+{
+    signlist_T	*p;
+
+    for (p = curbuf->b_signlist; p != NULL; p = p->next)
+    {
+	if (p->lnum == lnum && p->next && p->next->lnum == lnum)
+	{
+	    signlist_T *tail;
+
+	    /* remove "p" from list, reinsert it at the tail of the sublist */
+	    if (p->prev)
+		p->prev->next = p->next;
+	    else
+		curbuf->b_signlist = p->next;
+	    p->next->prev = p->prev;
+	    /* now find end of sublist and insert p */
+	    for (tail = p->next;
+		  tail->next && tail->next->lnum == lnum
+					    && tail->next->id < GUARDEDOFFSET;
+		  tail = tail->next)
+		;
+	    /* tail now points to last entry with same lnum (except
+	     * that "guarded" annotations are always last) */
+	    p->next = tail->next;
+	    if (tail->next)
+		tail->next->prev = p;
+	    p->prev = tail;
+	    tail->next = p;
+	    update_debug_sign(curbuf, lnum);
+	    break;
+	}
+    }
+}
+
+
+/*
+ * Add a sign of the reqested type at the requested location.
+ *
+ * Reverse engineering:
+ * Apparently an annotation is defined the first time it is used in a buffer.
+ * When the same annotation is used in two buffers, the second time we do not
+ * need to define a new sign name but reuse the existing one.  But since the
+ * ID number used in the second buffer starts counting at one again, a mapping
+ * is made from the ID specifically for the buffer to the global sign name
+ * (which is a number).
+ *
+ * globalsignmap[]	stores the signs that have been defined globally.
+ * buf->signmapused[]	maps buffer-local annotation IDs to an index in
+ *			globalsignmap[].
+ */
+/*ARGSUSED*/
+    static void
+addsigntype(
+    nbbuf_T	*buf,
+    int		typeNum,
+    char_u	*typeName,
+    char_u	*tooltip,
+    char_u	*glyphFile,
+    int		use_fg,
+    int		fg,
+    int		use_bg,
+    int		bg)
+{
+    char fgbuf[32];
+    char bgbuf[32];
+    int i, j;
+
+    for (i = 0; i < globalsignmapused; i++)
+	if (STRCMP(typeName, globalsignmap[i]) == 0)
+	    break;
+
+    if (i == globalsignmapused) /* not found; add it to global map */
+    {
+	nbdebug(("DEFINEANNOTYPE(%d,%s,%s,%s,%d,%d)\n",
+			    typeNum, typeName, tooltip, glyphFile, fg, bg));
+	if (use_fg || use_bg)
+	{
+	    sprintf(fgbuf, "guifg=#%06x", fg & 0xFFFFFF);
+	    sprintf(bgbuf, "guibg=#%06x", bg & 0xFFFFFF);
+
+	    coloncmd(":highlight NB_%s %s %s", typeName, (use_fg) ? fgbuf : "",
+		     (use_bg) ? bgbuf : "");
+	    if (*glyphFile == NUL)
+		/* no glyph, line highlighting only */
+		coloncmd(":sign define %d linehl=NB_%s", i + 1, typeName);
+	    else if (vim_strsize(glyphFile) <= 2)
+		/* one- or two-character glyph name, use as text glyph with
+		 * texthl */
+		coloncmd(":sign define %d text=%s texthl=NB_%s", i + 1,
+							 glyphFile, typeName);
+	    else
+		/* glyph, line highlighting */
+		coloncmd(":sign define %d icon=%s linehl=NB_%s", i + 1,
+							 glyphFile, typeName);
+	}
+	else
+	    /* glyph, no line highlighting */
+	    coloncmd(":sign define %d icon=%s", i + 1, glyphFile);
+
+	if (STRCMP(typeName,"CurrentPC") == 0)
+	    curPCtype = typeNum;
+
+	if (globalsignmapused == globalsignmaplen)
+	{
+	    if (globalsignmaplen == 0) /* first allocation */
+	    {
+		globalsignmaplen = 20;
+		globalsignmap = (char **)alloc_clear(globalsignmaplen*sizeof(char *));
+	    }
+	    else    /* grow it */
+	    {
+		int incr;
+		int oldlen = globalsignmaplen;
+
+		globalsignmaplen *= 2;
+		incr = globalsignmaplen - oldlen;
+		globalsignmap = (char **)vim_realloc(globalsignmap,
+					   globalsignmaplen * sizeof(char *));
+		memset(globalsignmap + oldlen, 0, incr * sizeof(char *));
+	    }
+	}
+
+	globalsignmap[i] = (char *)typeName;
+	globalsignmapused = i + 1;
+    }
+
+    /* check local map; should *not* be found! */
+    for (j = 0; j < buf->signmapused; j++)
+	if (buf->signmap[j] == i + 1)
+	    return;
+
+    /* add to local map */
+    if (buf->signmapused == buf->signmaplen)
+    {
+	if (buf->signmaplen == 0) /* first allocation */
+	{
+	    buf->signmaplen = 5;
+	    buf->signmap = (int *)alloc_clear(buf->signmaplen * sizeof(int *));
+	}
+	else    /* grow it */
+	{
+	    int incr;
+	    int oldlen = buf->signmaplen;
+	    buf->signmaplen *= 2;
+	    incr = buf->signmaplen - oldlen;
+	    buf->signmap = (int *)vim_realloc(buf->signmap,
+					       buf->signmaplen*sizeof(int *));
+	    memset(buf->signmap + oldlen, 0, incr * sizeof(int *));
+	}
+    }
+
+    buf->signmap[buf->signmapused++] = i + 1;
+
+}
+
+
+/*
+ * See if we have the requested sign type in the buffer.
+ */
+    static int
+mapsigntype(nbbuf_T *buf, int localsigntype)
+{
+    if (--localsigntype >= 0 && localsigntype < buf->signmapused)
+	return buf->signmap[localsigntype];
+
+    return 0;
+}
+
+
+/*
+ * Compute length of buffer, don't print anything.
+ */
+    static long
+get_buf_size(buf_T *bufp)
+{
+    linenr_T	lnum;
+    long	char_count = 0;
+    int		eol_size;
+    long	last_check = 100000L;
+
+    if (bufp->b_ml.ml_flags & ML_EMPTY)
+	return 0;
+    else
+    {
+	if (get_fileformat(bufp) == EOL_DOS)
+	    eol_size = 2;
+	else
+	    eol_size = 1;
+	for (lnum = 1; lnum <= bufp->b_ml.ml_line_count; ++lnum)
+	{
+	    char_count += (long)STRLEN(ml_get(lnum)) + eol_size;
+	    /* Check for a CTRL-C every 100000 characters */
+	    if (char_count > last_check)
+	    {
+		ui_breakcheck();
+		if (got_int)
+		    return char_count;
+		last_check = char_count + 100000L;
+	    }
+	}
+	/* Correction for when last line doesn't have an EOL. */
+	if (!bufp->b_p_eol && bufp->b_p_bin)
+	    char_count -= eol_size;
+    }
+
+    return char_count;
+}
+
+/*
+ * Convert character offset to lnum,col
+ */
+    static pos_T *
+off2pos(buf_T *buf, long offset)
+{
+    linenr_T	 lnum;
+    static pos_T pos;
+
+    pos.lnum = 0;
+    pos.col = 0;
+#ifdef FEAT_VIRTUALEDIT
+    pos.coladd = 0;
+#endif
+
+    if (!(buf->b_ml.ml_flags & ML_EMPTY))
+    {
+	if ((lnum = ml_find_line_or_offset(buf, (linenr_T)0, &offset)) < 0)
+	    return NULL;
+	pos.lnum = lnum;
+	pos.col = offset;
+    }
+
+    return &pos;
+}
+
+/*
+ * Convert an argument in the form "1234" to an offset and compute the
+ * lnum/col from it.  Convert an argument in the form "123/12" directly to a
+ * lnum/col.
+ * "argp" is advanced to after the argument.
+ * Return a pointer to the position, NULL if something is wrong.
+ */
+    static pos_T *
+get_off_or_lnum(buf_T *buf, char_u **argp)
+{
+    static pos_T	mypos;
+    long		off;
+
+    off = strtol((char *)*argp, (char **)argp, 10);
+    if (**argp == '/')
+    {
+	mypos.lnum = (linenr_T)off;
+	++*argp;
+	mypos.col = strtol((char *)*argp, (char **)argp, 10);
+#ifdef FEAT_VIRTUALEDIT
+	mypos.coladd = 0;
+#endif
+	return &mypos;
+    }
+    return off2pos(buf, off);
+}
+
+
+/*
+ * Convert (lnum,col) to byte offset in the file.
+ */
+    static long
+pos2off(buf_T *buf, pos_T *pos)
+{
+    long	 offset = 0;
+
+    if (!(buf->b_ml.ml_flags & ML_EMPTY))
+    {
+	if ((offset = ml_find_line_or_offset(buf, pos->lnum, 0)) < 0)
+	    return 0;
+	offset += pos->col;
+    }
+
+    return offset;
+}
+
+
+/*
+ * This message is printed after NetBeans opens a new file. Its
+ * similar to the message readfile() uses, but since NetBeans
+ * doesn't normally call readfile, we do our own.
+ */
+    static void
+print_read_msg(buf)
+    nbbuf_T	*buf;
+{
+    int	    lnum = buf->bufp->b_ml.ml_line_count;
+    long    nchars = (long)buf->bufp->b_orig_size;
+    char_u  c;
+
+    msg_add_fname(buf->bufp, buf->bufp->b_ffname);
+    c = FALSE;
+
+    if (buf->bufp->b_p_ro)
+    {
+	STRCAT(IObuff, shortmess(SHM_RO) ? _("[RO]") : _("[readonly]"));
+	c = TRUE;
+    }
+    if (!buf->bufp->b_start_eol)
+    {
+	STRCAT(IObuff, shortmess(SHM_LAST) ? _("[noeol]") : _("[Incomplete last line]"));
+	c = TRUE;
+    }
+    msg_add_lines(c, (long)lnum, nchars);
+
+    /* Now display it */
+    vim_free(keep_msg);
+    keep_msg = NULL;
+    msg_scrolled_ign = TRUE;
+    msg_trunc_attr(IObuff, FALSE, 0);
+    msg_scrolled_ign = FALSE;
+}
+
+
+/*
+ * Print a message after NetBeans writes the file. This message should be identical
+ * to the standard message a non-netbeans user would see when writing a file.
+ */
+    static void
+print_save_msg(buf, nchars)
+    nbbuf_T	*buf;
+    long	nchars;
+{
+    char_u	c;
+    char_u	*p;
+
+    if (nchars >= 0)
+    {
+	msg_add_fname(buf->bufp, buf->bufp->b_ffname);   /* fname in IObuff with quotes */
+	c = FALSE;
+
+	msg_add_lines(c, buf->bufp->b_ml.ml_line_count,
+						(long)buf->bufp->b_orig_size);
+
+	vim_free(keep_msg);
+	keep_msg = NULL;
+	msg_scrolled_ign = TRUE;
+	p = msg_trunc_attr(IObuff, FALSE, 0);
+	if ((msg_scrolled && !need_wait_return) || !buf->initDone)
+	{
+	    /* Need to repeat the message after redrawing when:
+	     * - When reading from stdin (the screen will be cleared next).
+	     * - When restart_edit is set (otherwise there will be a delay
+	     *   before redrawing).
+	     * - When the screen was scrolled but there is no wait-return
+	     *   prompt. */
+	    set_keep_msg(p, 0);
+	}
+	msg_scrolled_ign = FALSE;
+	/* add_to_input_buf((char_u *)"\f", 1); */
+    }
+    else
+    {
+	char_u ebuf[BUFSIZ];
+
+	STRCPY(ebuf, (char_u *)_("E505: "));
+	STRCAT(ebuf, IObuff);
+	STRCAT(ebuf, (char_u *)_("is read-only (add ! to override)"));
+	STRCPY(IObuff, ebuf);
+	emsg(IObuff);
+    }
+}
+
+#endif /* defined(FEAT_NETBEANS_INTG) */
--- /dev/null
+++ b/normal.c
@@ -1,0 +1,9118 @@
+/* vi:set ts=8 sts=4 sw=4:
+ *
+ * VIM - Vi IMproved	by Bram Moolenaar
+ *
+ * Do ":help uganda"  in Vim to read copying and usage conditions.
+ * Do ":help credits" in Vim to see a list of people who contributed.
+ * See README.txt for an overview of the Vim source code.
+ */
+/*
+ * normal.c:	Contains the main routine for processing characters in command
+ *		mode.  Communicates closely with the code in ops.c to handle
+ *		the operators.
+ */
+
+#include "vim.h"
+
+#ifdef FEAT_VISUAL
+/*
+ * The Visual area is remembered for reselection.
+ */
+static int	resel_VIsual_mode = NUL;	/* 'v', 'V', or Ctrl-V */
+static linenr_T	resel_VIsual_line_count;	/* number of lines */
+static colnr_T	resel_VIsual_col;		/* nr of cols or end col */
+
+static int	restart_VIsual_select = 0;
+#endif
+
+static int
+# ifdef __BORLANDC__
+_RTLENTRYF
+# endif
+		nv_compare __ARGS((const void *s1, const void *s2));
+static int	find_command __ARGS((int cmdchar));
+static void	op_colon __ARGS((oparg_T *oap));
+static void	op_function __ARGS((oparg_T *oap));
+#if defined(FEAT_MOUSE) && defined(FEAT_VISUAL)
+static void	find_start_of_word __ARGS((pos_T *));
+static void	find_end_of_word __ARGS((pos_T *));
+static int	get_mouse_class __ARGS((char_u *p));
+#endif
+static void	prep_redo_cmd __ARGS((cmdarg_T *cap));
+static void	prep_redo __ARGS((int regname, long, int, int, int, int, int));
+static int	checkclearop __ARGS((oparg_T *oap));
+static int	checkclearopq __ARGS((oparg_T *oap));
+static void	clearop __ARGS((oparg_T *oap));
+static void	clearopbeep __ARGS((oparg_T *oap));
+#ifdef FEAT_VISUAL
+static void	unshift_special __ARGS((cmdarg_T *cap));
+#endif
+#ifdef FEAT_CMDL_INFO
+static void	del_from_showcmd __ARGS((int));
+#endif
+
+/*
+ * nv_*(): functions called to handle Normal and Visual mode commands.
+ * n_*(): functions called to handle Normal mode commands.
+ * v_*(): functions called to handle Visual mode commands.
+ */
+static void	nv_ignore __ARGS((cmdarg_T *cap));
+static void	nv_nop __ARGS((cmdarg_T *cap));
+static void	nv_error __ARGS((cmdarg_T *cap));
+static void	nv_help __ARGS((cmdarg_T *cap));
+static void	nv_addsub __ARGS((cmdarg_T *cap));
+static void	nv_page __ARGS((cmdarg_T *cap));
+static void	nv_gd __ARGS((oparg_T *oap, int nchar, int thisblock));
+static int	nv_screengo __ARGS((oparg_T *oap, int dir, long dist));
+#ifdef FEAT_MOUSE
+static void	nv_mousescroll __ARGS((cmdarg_T *cap));
+static void	nv_mouse __ARGS((cmdarg_T *cap));
+#endif
+static void	nv_scroll_line __ARGS((cmdarg_T *cap));
+static void	nv_zet __ARGS((cmdarg_T *cap));
+#ifdef FEAT_GUI
+static void	nv_ver_scrollbar __ARGS((cmdarg_T *cap));
+static void	nv_hor_scrollbar __ARGS((cmdarg_T *cap));
+#endif
+#ifdef FEAT_GUI_TABLINE
+static void	nv_tabline __ARGS((cmdarg_T *cap));
+static void	nv_tabmenu __ARGS((cmdarg_T *cap));
+#endif
+static void	nv_exmode __ARGS((cmdarg_T *cap));
+static void	nv_colon __ARGS((cmdarg_T *cap));
+static void	nv_ctrlg __ARGS((cmdarg_T *cap));
+static void	nv_ctrlh __ARGS((cmdarg_T *cap));
+static void	nv_clear __ARGS((cmdarg_T *cap));
+static void	nv_ctrlo __ARGS((cmdarg_T *cap));
+static void	nv_hat __ARGS((cmdarg_T *cap));
+static void	nv_Zet __ARGS((cmdarg_T *cap));
+static void	nv_ident __ARGS((cmdarg_T *cap));
+static void	nv_tagpop __ARGS((cmdarg_T *cap));
+static void	nv_scroll __ARGS((cmdarg_T *cap));
+static void	nv_right __ARGS((cmdarg_T *cap));
+static void	nv_left __ARGS((cmdarg_T *cap));
+static void	nv_up __ARGS((cmdarg_T *cap));
+static void	nv_down __ARGS((cmdarg_T *cap));
+#ifdef FEAT_SEARCHPATH
+static void	nv_gotofile __ARGS((cmdarg_T *cap));
+#endif
+static void	nv_end __ARGS((cmdarg_T *cap));
+static void	nv_dollar __ARGS((cmdarg_T *cap));
+static void	nv_search __ARGS((cmdarg_T *cap));
+static void	nv_next __ARGS((cmdarg_T *cap));
+static void	normal_search __ARGS((cmdarg_T *cap, int dir, char_u *pat, int opt));
+static void	nv_csearch __ARGS((cmdarg_T *cap));
+static void	nv_brackets __ARGS((cmdarg_T *cap));
+static void	nv_percent __ARGS((cmdarg_T *cap));
+static void	nv_brace __ARGS((cmdarg_T *cap));
+static void	nv_mark __ARGS((cmdarg_T *cap));
+static void	nv_findpar __ARGS((cmdarg_T *cap));
+static void	nv_undo __ARGS((cmdarg_T *cap));
+static void	nv_kundo __ARGS((cmdarg_T *cap));
+static void	nv_Replace __ARGS((cmdarg_T *cap));
+#ifdef FEAT_VREPLACE
+static void	nv_vreplace __ARGS((cmdarg_T *cap));
+#endif
+#ifdef FEAT_VISUAL
+static void	v_swap_corners __ARGS((int cmdchar));
+#endif
+static void	nv_replace __ARGS((cmdarg_T *cap));
+static void	n_swapchar __ARGS((cmdarg_T *cap));
+static void	nv_cursormark __ARGS((cmdarg_T *cap, int flag, pos_T *pos));
+#ifdef FEAT_VISUAL
+static void	v_visop __ARGS((cmdarg_T *cap));
+#endif
+static void	nv_subst __ARGS((cmdarg_T *cap));
+static void	nv_abbrev __ARGS((cmdarg_T *cap));
+static void	nv_optrans __ARGS((cmdarg_T *cap));
+static void	nv_gomark __ARGS((cmdarg_T *cap));
+static void	nv_pcmark __ARGS((cmdarg_T *cap));
+static void	nv_regname __ARGS((cmdarg_T *cap));
+#ifdef FEAT_VISUAL
+static void	nv_visual __ARGS((cmdarg_T *cap));
+static void	n_start_visual_mode __ARGS((int c));
+#endif
+static void	nv_window __ARGS((cmdarg_T *cap));
+static void	nv_suspend __ARGS((cmdarg_T *cap));
+static void	nv_g_cmd __ARGS((cmdarg_T *cap));
+static void	n_opencmd __ARGS((cmdarg_T *cap));
+static void	nv_dot __ARGS((cmdarg_T *cap));
+static void	nv_redo __ARGS((cmdarg_T *cap));
+static void	nv_Undo __ARGS((cmdarg_T *cap));
+static void	nv_tilde __ARGS((cmdarg_T *cap));
+static void	nv_operator __ARGS((cmdarg_T *cap));
+static void	nv_lineop __ARGS((cmdarg_T *cap));
+static void	nv_home __ARGS((cmdarg_T *cap));
+static void	nv_pipe __ARGS((cmdarg_T *cap));
+static void	nv_bck_word __ARGS((cmdarg_T *cap));
+static void	nv_wordcmd __ARGS((cmdarg_T *cap));
+static void	nv_beginline __ARGS((cmdarg_T *cap));
+#ifdef FEAT_VISUAL
+static void	adjust_for_sel __ARGS((cmdarg_T *cap));
+static int	unadjust_for_sel __ARGS((void));
+static void	nv_select __ARGS((cmdarg_T *cap));
+#endif
+static void	nv_goto __ARGS((cmdarg_T *cap));
+static void	nv_normal __ARGS((cmdarg_T *cap));
+static void	nv_esc __ARGS((cmdarg_T *oap));
+static void	nv_edit __ARGS((cmdarg_T *cap));
+static void	invoke_edit __ARGS((cmdarg_T *cap, int repl, int cmd, int startln));
+#ifdef FEAT_TEXTOBJ
+static void	nv_object __ARGS((cmdarg_T *cap));
+#endif
+static void	nv_record __ARGS((cmdarg_T *cap));
+static void	nv_at __ARGS((cmdarg_T *cap));
+static void	nv_halfpage __ARGS((cmdarg_T *cap));
+static void	nv_join __ARGS((cmdarg_T *cap));
+static void	nv_put __ARGS((cmdarg_T *cap));
+static void	nv_open __ARGS((cmdarg_T *cap));
+#ifdef FEAT_SNIFF
+static void	nv_sniff __ARGS((cmdarg_T *cap));
+#endif
+#ifdef FEAT_NETBEANS_INTG
+static void	nv_nbcmd __ARGS((cmdarg_T *cap));
+#endif
+#ifdef FEAT_DND
+static void	nv_drop __ARGS((cmdarg_T *cap));
+#endif
+#ifdef FEAT_AUTOCMD
+static void	nv_cursorhold __ARGS((cmdarg_T *cap));
+#endif
+
+/*
+ * Function to be called for a Normal or Visual mode command.
+ * The argument is a cmdarg_T.
+ */
+typedef void (*nv_func_T) __ARGS((cmdarg_T *cap));
+
+/* Values for cmd_flags. */
+#define NV_NCH	    0x01	  /* may need to get a second char */
+#define NV_NCH_NOP  (0x02|NV_NCH) /* get second char when no operator pending */
+#define NV_NCH_ALW  (0x04|NV_NCH) /* always get a second char */
+#define NV_LANG	    0x08	/* second char needs language adjustment */
+
+#define NV_SS	    0x10	/* may start selection */
+#define NV_SSS	    0x20	/* may start selection with shift modifier */
+#define NV_STS	    0x40	/* may stop selection without shift modif. */
+#define NV_RL	    0x80	/* 'rightleft' modifies command */
+#define NV_KEEPREG  0x100	/* don't clear regname */
+#define NV_NCW	    0x200	/* not allowed in command-line window */
+
+/*
+ * Generally speaking, every Normal mode command should either clear any
+ * pending operator (with *clearop*()), or set the motion type variable
+ * oap->motion_type.
+ *
+ * When a cursor motion command is made, it is marked as being a character or
+ * line oriented motion.  Then, if an operator is in effect, the operation
+ * becomes character or line oriented accordingly.
+ */
+
+/*
+ * This table contains one entry for every Normal or Visual mode command.
+ * The order doesn't matter, init_normal_cmds() will create a sorted index.
+ * It is faster when all keys from zero to '~' are present.
+ */
+static const struct nv_cmd
+{
+    int		cmd_char;	/* (first) command character */
+    nv_func_T   cmd_func;	/* function for this command */
+    short_u	cmd_flags;	/* NV_ flags */
+    short	cmd_arg;	/* value for ca.arg */
+} nv_cmds[] =
+{
+    {NUL,	nv_error,	0,			0},
+    {Ctrl_A,	nv_addsub,	0,			0},
+    {Ctrl_B,	nv_page,	NV_STS,			BACKWARD},
+    {Ctrl_C,	nv_esc,		0,			TRUE},
+    {Ctrl_D,	nv_halfpage,	0,			0},
+    {Ctrl_E,	nv_scroll_line,	0,			TRUE},
+    {Ctrl_F,	nv_page,	NV_STS,			FORWARD},
+    {Ctrl_G,	nv_ctrlg,	0,			0},
+    {Ctrl_H,	nv_ctrlh,	0,			0},
+    {Ctrl_I,	nv_pcmark,	0,			0},
+    {NL,	nv_down,	0,			FALSE},
+    {Ctrl_K,	nv_error,	0,			0},
+    {Ctrl_L,	nv_clear,	0,			0},
+    {Ctrl_M,	nv_down,	0,			TRUE},
+    {Ctrl_N,	nv_down,	NV_STS,			FALSE},
+    {Ctrl_O,	nv_ctrlo,	0,			0},
+    {Ctrl_P,	nv_up,		NV_STS,			FALSE},
+#ifdef FEAT_VISUAL
+    {Ctrl_Q,	nv_visual,	0,			FALSE},
+#else
+    {Ctrl_Q,	nv_ignore,	0,			0},
+#endif
+    {Ctrl_R,	nv_redo,	0,			0},
+    {Ctrl_S,	nv_ignore,	0,			0},
+    {Ctrl_T,	nv_tagpop,	NV_NCW,			0},
+    {Ctrl_U,	nv_halfpage,	0,			0},
+#ifdef FEAT_VISUAL
+    {Ctrl_V,	nv_visual,	0,			FALSE},
+    {'V',	nv_visual,	0,			FALSE},
+    {'v',	nv_visual,	0,			FALSE},
+#else
+    {Ctrl_V,	nv_error,	0,			0},
+    {'V',	nv_error,	0,			0},
+    {'v',	nv_error,	0,			0},
+#endif
+    {Ctrl_W,	nv_window,	0,			0},
+    {Ctrl_X,	nv_addsub,	0,			0},
+    {Ctrl_Y,	nv_scroll_line,	0,			FALSE},
+    {Ctrl_Z,	nv_suspend,	0,			0},
+    {ESC,	nv_esc,		0,			FALSE},
+    {Ctrl_BSL,	nv_normal,	NV_NCH_ALW,		0},
+    {Ctrl_RSB,	nv_ident,	NV_NCW,			0},
+    {Ctrl_HAT,	nv_hat,		NV_NCW,			0},
+    {Ctrl__,	nv_error,	0,			0},
+    {' ',	nv_right,	0,			0},
+    {'!',	nv_operator,	0,			0},
+    {'"',	nv_regname,	NV_NCH_NOP|NV_KEEPREG,	0},
+    {'#',	nv_ident,	0,			0},
+    {'$',	nv_dollar,	0,			0},
+    {'%',	nv_percent,	0,			0},
+    {'&',	nv_optrans,	0,			0},
+    {'\'',	nv_gomark,	NV_NCH_ALW,		TRUE},
+    {'(',	nv_brace,	0,			BACKWARD},
+    {')',	nv_brace,	0,			FORWARD},
+    {'*',	nv_ident,	0,			0},
+    {'+',	nv_down,	0,			TRUE},
+    {',',	nv_csearch,	0,			TRUE},
+    {'-',	nv_up,		0,			TRUE},
+    {'.',	nv_dot,		NV_KEEPREG,		0},
+    {'/',	nv_search,	0,			FALSE},
+    {'0',	nv_beginline,	0,			0},
+    {'1',	nv_ignore,	0,			0},
+    {'2',	nv_ignore,	0,			0},
+    {'3',	nv_ignore,	0,			0},
+    {'4',	nv_ignore,	0,			0},
+    {'5',	nv_ignore,	0,			0},
+    {'6',	nv_ignore,	0,			0},
+    {'7',	nv_ignore,	0,			0},
+    {'8',	nv_ignore,	0,			0},
+    {'9',	nv_ignore,	0,			0},
+    {':',	nv_colon,	0,			0},
+    {';',	nv_csearch,	0,			FALSE},
+    {'<',	nv_operator,	NV_RL,			0},
+    {'=',	nv_operator,	0,			0},
+    {'>',	nv_operator,	NV_RL,			0},
+    {'?',	nv_search,	0,			FALSE},
+    {'@',	nv_at,		NV_NCH_NOP,		FALSE},
+    {'A',	nv_edit,	0,			0},
+    {'B',	nv_bck_word,	0,			1},
+    {'C',	nv_abbrev,	NV_KEEPREG,		0},
+    {'D',	nv_abbrev,	NV_KEEPREG,		0},
+    {'E',	nv_wordcmd,	0,			TRUE},
+    {'F',	nv_csearch,	NV_NCH_ALW|NV_LANG,	BACKWARD},
+    {'G',	nv_goto,	0,			TRUE},
+    {'H',	nv_scroll,	0,			0},
+    {'I',	nv_edit,	0,			0},
+    {'J',	nv_join,	0,			0},
+    {'K',	nv_ident,	0,			0},
+    {'L',	nv_scroll,	0,			0},
+    {'M',	nv_scroll,	0,			0},
+    {'N',	nv_next,	0,			SEARCH_REV},
+    {'O',	nv_open,	0,			0},
+    {'P',	nv_put,		0,			0},
+    {'Q',	nv_exmode,	NV_NCW,			0},
+    {'R',	nv_Replace,	0,			FALSE},
+    {'S',	nv_subst,	NV_KEEPREG,		0},
+    {'T',	nv_csearch,	NV_NCH_ALW|NV_LANG,	BACKWARD},
+    {'U',	nv_Undo,	0,			0},
+    {'W',	nv_wordcmd,	0,			TRUE},
+    {'X',	nv_abbrev,	NV_KEEPREG,		0},
+    {'Y',	nv_abbrev,	NV_KEEPREG,		0},
+    {'Z',	nv_Zet,		NV_NCH_NOP|NV_NCW,	0},
+    {'[',	nv_brackets,	NV_NCH_ALW,		BACKWARD},
+    {'\\',	nv_error,	0,			0},
+    {']',	nv_brackets,	NV_NCH_ALW,		FORWARD},
+    {'^',	nv_beginline,	0,			BL_WHITE | BL_FIX},
+    {'_',	nv_lineop,	0,			0},
+    {'`',	nv_gomark,	NV_NCH_ALW,		FALSE},
+    {'a',	nv_edit,	NV_NCH,			0},
+    {'b',	nv_bck_word,	0,			0},
+    {'c',	nv_operator,	0,			0},
+    {'d',	nv_operator,	0,			0},
+    {'e',	nv_wordcmd,	0,			FALSE},
+    {'f',	nv_csearch,	NV_NCH_ALW|NV_LANG,	FORWARD},
+    {'g',	nv_g_cmd,	NV_NCH_ALW,		FALSE},
+    {'h',	nv_left,	NV_RL,			0},
+    {'i',	nv_edit,	NV_NCH,			0},
+    {'j',	nv_down,	0,			FALSE},
+    {'k',	nv_up,		0,			FALSE},
+    {'l',	nv_right,	NV_RL,			0},
+    {'m',	nv_mark,	NV_NCH_NOP,		0},
+    {'n',	nv_next,	0,			0},
+    {'o',	nv_open,	0,			0},
+    {'p',	nv_put,		0,			0},
+    {'q',	nv_record,	NV_NCH,			0},
+    {'r',	nv_replace,	NV_NCH_NOP|NV_LANG,	0},
+    {'s',	nv_subst,	NV_KEEPREG,		0},
+    {'t',	nv_csearch,	NV_NCH_ALW|NV_LANG,	FORWARD},
+    {'u',	nv_undo,	0,			0},
+    {'w',	nv_wordcmd,	0,			FALSE},
+    {'x',	nv_abbrev,	NV_KEEPREG,		0},
+    {'y',	nv_operator,	0,			0},
+    {'z',	nv_zet,		NV_NCH_ALW,		0},
+    {'{',	nv_findpar,	0,			BACKWARD},
+    {'|',	nv_pipe,	0,			0},
+    {'}',	nv_findpar,	0,			FORWARD},
+    {'~',	nv_tilde,	0,			0},
+
+    /* pound sign */
+    {POUND,	nv_ident,	0,			0},
+#ifdef FEAT_MOUSE
+    {K_MOUSEUP, nv_mousescroll,	0,			TRUE},
+    {K_MOUSEDOWN, nv_mousescroll, 0,			FALSE},
+    {K_LEFTMOUSE, nv_mouse,	0,			0},
+    {K_LEFTMOUSE_NM, nv_mouse,	0,			0},
+    {K_LEFTDRAG, nv_mouse,	0,			0},
+    {K_LEFTRELEASE, nv_mouse,	0,			0},
+    {K_LEFTRELEASE_NM, nv_mouse, 0,			0},
+    {K_MIDDLEMOUSE, nv_mouse,	0,			0},
+    {K_MIDDLEDRAG, nv_mouse,	0,			0},
+    {K_MIDDLERELEASE, nv_mouse,	0,			0},
+    {K_RIGHTMOUSE, nv_mouse,	0,			0},
+    {K_RIGHTDRAG, nv_mouse,	0,			0},
+    {K_RIGHTRELEASE, nv_mouse,	0,			0},
+    {K_X1MOUSE, nv_mouse,	0,			0},
+    {K_X1DRAG, nv_mouse,	0,			0},
+    {K_X1RELEASE, nv_mouse,	0,			0},
+    {K_X2MOUSE, nv_mouse,	0,			0},
+    {K_X2DRAG, nv_mouse,	0,			0},
+    {K_X2RELEASE, nv_mouse,	0,			0},
+#endif
+    {K_IGNORE,	nv_ignore,	NV_KEEPREG,		0},
+    {K_NOP,	nv_nop,		0,			0},
+    {K_INS,	nv_edit,	0,			0},
+    {K_KINS,	nv_edit,	0,			0},
+    {K_BS,	nv_ctrlh,	0,			0},
+    {K_UP,	nv_up,		NV_SSS|NV_STS,		FALSE},
+    {K_S_UP,	nv_page,	NV_SS,			BACKWARD},
+    {K_DOWN,	nv_down,	NV_SSS|NV_STS,		FALSE},
+    {K_S_DOWN,	nv_page,	NV_SS,			FORWARD},
+    {K_LEFT,	nv_left,	NV_SSS|NV_STS|NV_RL,	0},
+    {K_S_LEFT,	nv_bck_word,	NV_SS|NV_RL,		0},
+    {K_C_LEFT,	nv_bck_word,	NV_SSS|NV_RL|NV_STS,	1},
+    {K_RIGHT,	nv_right,	NV_SSS|NV_STS|NV_RL,	0},
+    {K_S_RIGHT,	nv_wordcmd,	NV_SS|NV_RL,		FALSE},
+    {K_C_RIGHT,	nv_wordcmd,	NV_SSS|NV_RL|NV_STS,	TRUE},
+    {K_PAGEUP,	nv_page,	NV_SSS|NV_STS,		BACKWARD},
+    {K_KPAGEUP,	nv_page,	NV_SSS|NV_STS,		BACKWARD},
+    {K_PAGEDOWN, nv_page,	NV_SSS|NV_STS,		FORWARD},
+    {K_KPAGEDOWN, nv_page,	NV_SSS|NV_STS,		FORWARD},
+    {K_END,	nv_end,		NV_SSS|NV_STS,		FALSE},
+    {K_KEND,	nv_end,		NV_SSS|NV_STS,		FALSE},
+    {K_S_END,	nv_end,		NV_SS,			FALSE},
+    {K_C_END,	nv_end,		NV_SSS|NV_STS,		TRUE},
+    {K_HOME,	nv_home,	NV_SSS|NV_STS,		0},
+    {K_KHOME,	nv_home,	NV_SSS|NV_STS,		0},
+    {K_S_HOME,	nv_home,	NV_SS,			0},
+    {K_C_HOME,	nv_goto,	NV_SSS|NV_STS,		FALSE},
+    {K_DEL,	nv_abbrev,	0,			0},
+    {K_KDEL,	nv_abbrev,	0,			0},
+    {K_UNDO,	nv_kundo,	0,			0},
+    {K_HELP,	nv_help,	NV_NCW,			0},
+    {K_F1,	nv_help,	NV_NCW,			0},
+    {K_XF1,	nv_help,	NV_NCW,			0},
+#ifdef FEAT_VISUAL
+    {K_SELECT,	nv_select,	0,			0},
+#endif
+#ifdef FEAT_GUI
+    {K_VER_SCROLLBAR, nv_ver_scrollbar, 0,		0},
+    {K_HOR_SCROLLBAR, nv_hor_scrollbar, 0,		0},
+#endif
+#ifdef FEAT_GUI_TABLINE
+    {K_TABLINE, nv_tabline,	0,			0},
+    {K_TABMENU, nv_tabmenu,	0,			0},
+#endif
+#ifdef FEAT_FKMAP
+    {K_F8,	farsi_fkey,	0,			0},
+    {K_F9,	farsi_fkey,	0,			0},
+#endif
+#ifdef FEAT_SNIFF
+    {K_SNIFF,	nv_sniff,	0,			0},
+#endif
+#ifdef FEAT_NETBEANS_INTG
+    {K_F21,	nv_nbcmd,	NV_NCH_ALW,		0},
+#endif
+#ifdef FEAT_DND
+    {K_DROP,	nv_drop,	NV_STS,			0},
+#endif
+#ifdef FEAT_AUTOCMD
+    {K_CURSORHOLD, nv_cursorhold, NV_KEEPREG,		0},
+#endif
+};
+
+/* Number of commands in nv_cmds[]. */
+#define NV_CMDS_SIZE (sizeof(nv_cmds) / sizeof(struct nv_cmd))
+
+/* Sorted index of commands in nv_cmds[]. */
+static short nv_cmd_idx[NV_CMDS_SIZE];
+
+/* The highest index for which
+ * nv_cmds[idx].cmd_char == nv_cmd_idx[nv_cmds[idx].cmd_char] */
+static int nv_max_linear;
+
+/*
+ * Compare functions for qsort() below, that checks the command character
+ * through the index in nv_cmd_idx[].
+ */
+    static int
+#ifdef __BORLANDC__
+_RTLENTRYF
+#endif
+nv_compare(s1, s2)
+    const void	*s1;
+    const void	*s2;
+{
+    int		c1, c2;
+
+    /* The commands are sorted on absolute value. */
+    c1 = nv_cmds[*(const short *)s1].cmd_char;
+    c2 = nv_cmds[*(const short *)s2].cmd_char;
+    if (c1 < 0)
+	c1 = -c1;
+    if (c2 < 0)
+	c2 = -c2;
+    return c1 - c2;
+}
+
+/*
+ * Initialize the nv_cmd_idx[] table.
+ */
+    void
+init_normal_cmds()
+{
+    int		i;
+
+    /* Fill the index table with a one to one relation. */
+    for (i = 0; i < NV_CMDS_SIZE; ++i)
+	nv_cmd_idx[i] = i;
+
+    /* Sort the commands by the command character.  */
+    qsort((void *)&nv_cmd_idx, (size_t)NV_CMDS_SIZE, sizeof(short), nv_compare);
+
+    /* Find the first entry that can't be indexed by the command character. */
+    for (i = 0; i < NV_CMDS_SIZE; ++i)
+	if (i != nv_cmds[nv_cmd_idx[i]].cmd_char)
+	    break;
+    nv_max_linear = i - 1;
+}
+
+/*
+ * Search for a command in the commands table.
+ * Returns -1 for invalid command.
+ */
+    static int
+find_command(cmdchar)
+    int		cmdchar;
+{
+    int		i;
+    int		idx;
+    int		top, bot;
+    int		c;
+
+#ifdef FEAT_MBYTE
+    /* A multi-byte character is never a command. */
+    if (cmdchar >= 0x100)
+	return -1;
+#endif
+
+    /* We use the absolute value of the character.  Special keys have a
+     * negative value, but are sorted on their absolute value. */
+    if (cmdchar < 0)
+	cmdchar = -cmdchar;
+
+    /* If the character is in the first part: The character is the index into
+     * nv_cmd_idx[]. */
+    if (cmdchar <= nv_max_linear)
+	return nv_cmd_idx[cmdchar];
+
+    /* Perform a binary search. */
+    bot = nv_max_linear + 1;
+    top = NV_CMDS_SIZE - 1;
+    idx = -1;
+    while (bot <= top)
+    {
+	i = (top + bot) / 2;
+	c = nv_cmds[nv_cmd_idx[i]].cmd_char;
+	if (c < 0)
+	    c = -c;
+	if (cmdchar == c)
+	{
+	    idx = nv_cmd_idx[i];
+	    break;
+	}
+	if (cmdchar > c)
+	    bot = i + 1;
+	else
+	    top = i - 1;
+    }
+    return idx;
+}
+
+/*
+ * Execute a command in Normal mode.
+ */
+/*ARGSUSED*/
+    void
+normal_cmd(oap, toplevel)
+    oparg_T	*oap;
+    int		toplevel;		/* TRUE when called from main() */
+{
+    static long	opcount = 0;		/* ca.opcount saved here */
+    cmdarg_T	ca;			/* command arguments */
+    int		c;
+    int		ctrl_w = FALSE;		/* got CTRL-W command */
+    int		old_col = curwin->w_curswant;
+#ifdef FEAT_CMDL_INFO
+    int		need_flushbuf;		/* need to call out_flush() */
+#endif
+#ifdef FEAT_VISUAL
+    pos_T	old_pos;		/* cursor position before command */
+    int		mapped_len;
+    static int	old_mapped_len = 0;
+#endif
+    int		idx;
+
+    vim_memset(&ca, 0, sizeof(ca));	/* also resets ca.retval */
+    ca.oap = oap;
+    ca.opcount = opcount;
+
+#ifdef FEAT_SNIFF
+    want_sniff_request = sniff_connected;
+#endif
+
+    /*
+     * If there is an operator pending, then the command we take this time
+     * will terminate it. Finish_op tells us to finish the operation before
+     * returning this time (unless the operation was cancelled).
+     */
+#ifdef CURSOR_SHAPE
+    c = finish_op;
+#endif
+    finish_op = (oap->op_type != OP_NOP);
+#ifdef CURSOR_SHAPE
+    if (finish_op != c)
+    {
+	ui_cursor_shape();		/* may show different cursor shape */
+# ifdef FEAT_MOUSESHAPE
+	update_mouseshape(-1);
+# endif
+    }
+#endif
+
+    if (!finish_op && !oap->regname)
+	ca.opcount = 0;
+
+#ifdef FEAT_VISUAL
+    mapped_len = typebuf_maplen();
+#endif
+
+    State = NORMAL_BUSY;
+#ifdef USE_ON_FLY_SCROLL
+    dont_scroll = FALSE;	/* allow scrolling here */
+#endif
+
+    /*
+     * Get the command character from the user.
+     */
+    c = safe_vgetc();
+
+#ifdef FEAT_LANGMAP
+    LANGMAP_ADJUST(c, TRUE);
+#endif
+
+#ifdef FEAT_VISUAL
+    /*
+     * If a mapping was started in Visual or Select mode, remember the length
+     * of the mapping.  This is used below to not return to Insert mode for as
+     * long as the mapping is being executed.
+     */
+    if (restart_edit == 0)
+	old_mapped_len = 0;
+    else if (old_mapped_len
+		|| (VIsual_active && mapped_len == 0 && typebuf_maplen() > 0))
+	old_mapped_len = typebuf_maplen();
+#endif
+
+    if (c == NUL)
+	c = K_ZERO;
+
+#ifdef FEAT_VISUAL
+    /*
+     * In Select mode, typed text replaces the selection.
+     */
+    if (VIsual_active
+	    && VIsual_select
+	    && (vim_isprintc(c) || c == NL || c == CAR || c == K_KENTER))
+    {
+	/* Fake a "c"hange command.  When "restart_edit" is set (e.g., because
+	 * 'insertmode' is set) fake a "d"elete command, Insert mode will
+	 * restart automatically.
+	 * Insert the typed character in the typeahead buffer, so that it can
+	 * be mapped in Insert mode.  Required for ":lmap" to work. */
+	ins_char_typebuf(c);
+	if (restart_edit != 0)
+	    c = 'd';
+	else
+	    c = 'c';
+	msg_nowait = TRUE;	/* don't delay going to insert mode */
+    }
+#endif
+
+#ifdef FEAT_CMDL_INFO
+    need_flushbuf = add_to_showcmd(c);
+#endif
+
+getcount:
+#ifdef FEAT_VISUAL
+    if (!(VIsual_active && VIsual_select))
+#endif
+    {
+	/*
+	 * Handle a count before a command and compute ca.count0.
+	 * Note that '0' is a command and not the start of a count, but it's
+	 * part of a count after other digits.
+	 */
+	while (    (c >= '1' && c <= '9')
+		|| (ca.count0 != 0 && (c == K_DEL || c == K_KDEL || c == '0')))
+	{
+	    if (c == K_DEL || c == K_KDEL)
+	    {
+		ca.count0 /= 10;
+#ifdef FEAT_CMDL_INFO
+		del_from_showcmd(4);	/* delete the digit and ~@% */
+#endif
+	    }
+	    else
+		ca.count0 = ca.count0 * 10 + (c - '0');
+	    if (ca.count0 < 0)	    /* got too large! */
+		ca.count0 = 999999999L;
+	    if (ctrl_w)
+	    {
+		++no_mapping;
+		++allow_keys;		/* no mapping for nchar, but keys */
+	    }
+	    ++no_zero_mapping;		/* don't map zero here */
+	    c = safe_vgetc();
+#ifdef FEAT_LANGMAP
+	    LANGMAP_ADJUST(c, TRUE);
+#endif
+	    --no_zero_mapping;
+	    if (ctrl_w)
+	    {
+		--no_mapping;
+		--allow_keys;
+	    }
+#ifdef FEAT_CMDL_INFO
+	    need_flushbuf |= add_to_showcmd(c);
+#endif
+	}
+
+	/*
+	 * If we got CTRL-W there may be a/another count
+	 */
+	if (c == Ctrl_W && !ctrl_w && oap->op_type == OP_NOP)
+	{
+	    ctrl_w = TRUE;
+	    ca.opcount = ca.count0;	/* remember first count */
+	    ca.count0 = 0;
+	    ++no_mapping;
+	    ++allow_keys;		/* no mapping for nchar, but keys */
+	    c = safe_vgetc();		/* get next character */
+#ifdef FEAT_LANGMAP
+	    LANGMAP_ADJUST(c, TRUE);
+#endif
+	    --no_mapping;
+	    --allow_keys;
+#ifdef FEAT_CMDL_INFO
+	    need_flushbuf |= add_to_showcmd(c);
+#endif
+	    goto getcount;		/* jump back */
+	}
+    }
+
+    /*
+     * If we're in the middle of an operator (including after entering a yank
+     * buffer with '"') AND we had a count before the operator, then that
+     * count overrides the current value of ca.count0.
+     * What this means effectively, is that commands like "3dw" get turned
+     * into "d3w" which makes things fall into place pretty neatly.
+     * If you give a count before AND after the operator, they are multiplied.
+     */
+    if (ca.opcount != 0)
+    {
+	if (ca.count0)
+	    ca.count0 *= ca.opcount;
+	else
+	    ca.count0 = ca.opcount;
+    }
+
+    /*
+     * Always remember the count.  It will be set to zero (on the next call,
+     * above) when there is no pending operator.
+     * When called from main(), save the count for use by the "count" built-in
+     * variable.
+     */
+    ca.opcount = ca.count0;
+    ca.count1 = (ca.count0 == 0 ? 1 : ca.count0);
+
+#ifdef FEAT_EVAL
+    /*
+     * Only set v:count when called from main() and not a stuffed command.
+     */
+    if (toplevel && stuff_empty())
+	set_vcount(ca.count0, ca.count1);
+#endif
+
+    /*
+     * Find the command character in the table of commands.
+     * For CTRL-W we already got nchar when looking for a count.
+     */
+    if (ctrl_w)
+    {
+	ca.nchar = c;
+	ca.cmdchar = Ctrl_W;
+    }
+    else
+	ca.cmdchar = c;
+    idx = find_command(ca.cmdchar);
+    if (idx < 0)
+    {
+	/* Not a known command: beep. */
+	clearopbeep(oap);
+	goto normal_end;
+    }
+
+    if (text_locked() && (nv_cmds[idx].cmd_flags & NV_NCW))
+    {
+	/* This command is not allowed wile editing a ccmdline: beep. */
+	clearopbeep(oap);
+	text_locked_msg();
+	goto normal_end;
+    }
+#ifdef FEAT_AUTOCMD
+    if ((nv_cmds[idx].cmd_flags & NV_NCW) && curbuf_locked())
+	goto normal_end;
+#endif
+
+#ifdef FEAT_VISUAL
+    /*
+     * In Visual/Select mode, a few keys are handled in a special way.
+     */
+    if (VIsual_active)
+    {
+	/* when 'keymodel' contains "stopsel" may stop Select/Visual mode */
+	if (km_stopsel
+		&& (nv_cmds[idx].cmd_flags & NV_STS)
+		&& !(mod_mask & MOD_MASK_SHIFT))
+	{
+	    end_visual_mode();
+	    redraw_curbuf_later(INVERTED);
+	}
+
+	/* Keys that work different when 'keymodel' contains "startsel" */
+	if (km_startsel)
+	{
+	    if (nv_cmds[idx].cmd_flags & NV_SS)
+	    {
+		unshift_special(&ca);
+		idx = find_command(ca.cmdchar);
+		if (idx < 0)
+		{
+		    /* Just in case */
+		    clearopbeep(oap);
+		    goto normal_end;
+		}
+	    }
+	    else if ((nv_cmds[idx].cmd_flags & NV_SSS)
+					       && (mod_mask & MOD_MASK_SHIFT))
+	    {
+		mod_mask &= ~MOD_MASK_SHIFT;
+	    }
+	}
+    }
+#endif
+
+#ifdef FEAT_RIGHTLEFT
+    if (curwin->w_p_rl && KeyTyped && !KeyStuffed
+					  && (nv_cmds[idx].cmd_flags & NV_RL))
+    {
+	/* Invert horizontal movements and operations.  Only when typed by the
+	 * user directly, not when the result of a mapping or "x" translated
+	 * to "dl". */
+	switch (ca.cmdchar)
+	{
+	    case 'l':	    ca.cmdchar = 'h'; break;
+	    case K_RIGHT:   ca.cmdchar = K_LEFT; break;
+	    case K_S_RIGHT: ca.cmdchar = K_S_LEFT; break;
+	    case K_C_RIGHT: ca.cmdchar = K_C_LEFT; break;
+	    case 'h':	    ca.cmdchar = 'l'; break;
+	    case K_LEFT:    ca.cmdchar = K_RIGHT; break;
+	    case K_S_LEFT:  ca.cmdchar = K_S_RIGHT; break;
+	    case K_C_LEFT:  ca.cmdchar = K_C_RIGHT; break;
+	    case '>':	    ca.cmdchar = '<'; break;
+	    case '<':	    ca.cmdchar = '>'; break;
+	}
+	idx = find_command(ca.cmdchar);
+    }
+#endif
+
+    /*
+     * Get an additional character if we need one.
+     */
+    if ((nv_cmds[idx].cmd_flags & NV_NCH)
+	    && (((nv_cmds[idx].cmd_flags & NV_NCH_NOP) == NV_NCH_NOP
+		    && oap->op_type == OP_NOP)
+		|| (nv_cmds[idx].cmd_flags & NV_NCH_ALW) == NV_NCH_ALW
+		|| (ca.cmdchar == 'q'
+		    && oap->op_type == OP_NOP
+		    && !Recording
+		    && !Exec_reg)
+		|| ((ca.cmdchar == 'a' || ca.cmdchar == 'i')
+		    && (oap->op_type != OP_NOP
+#ifdef FEAT_VISUAL
+			|| VIsual_active
+#endif
+		       ))))
+    {
+	int	*cp;
+	int	repl = FALSE;	/* get character for replace mode */
+	int	lit = FALSE;	/* get extra character literally */
+	int	langmap_active = FALSE;    /* using :lmap mappings */
+	int	lang;		/* getting a text character */
+#ifdef USE_IM_CONTROL
+	int	save_smd;	/* saved value of p_smd */
+#endif
+
+	++no_mapping;
+	++allow_keys;		/* no mapping for nchar, but allow key codes */
+	if (ca.cmdchar == 'g')
+	{
+	    /*
+	     * For 'g' get the next character now, so that we can check for
+	     * "gr", "g'" and "g`".
+	     */
+	    ca.nchar = safe_vgetc();
+#ifdef FEAT_LANGMAP
+	    LANGMAP_ADJUST(ca.nchar, TRUE);
+#endif
+#ifdef FEAT_CMDL_INFO
+	    need_flushbuf |= add_to_showcmd(ca.nchar);
+#endif
+	    if (ca.nchar == 'r' || ca.nchar == '\'' || ca.nchar == '`'
+						      || ca.nchar == Ctrl_BSL)
+	    {
+		cp = &ca.extra_char;	/* need to get a third character */
+		if (ca.nchar != 'r')
+		    lit = TRUE;			/* get it literally */
+		else
+		    repl = TRUE;		/* get it in replace mode */
+	    }
+	    else
+		cp = NULL;		/* no third character needed */
+	}
+	else
+	{
+	    if (ca.cmdchar == 'r')		/* get it in replace mode */
+		repl = TRUE;
+	    cp = &ca.nchar;
+	}
+	lang = (repl || (nv_cmds[idx].cmd_flags & NV_LANG));
+
+	/*
+	 * Get a second or third character.
+	 */
+	if (cp != NULL)
+	{
+#ifdef CURSOR_SHAPE
+	    if (repl)
+	    {
+		State = REPLACE;	/* pretend Replace mode */
+		ui_cursor_shape();	/* show different cursor shape */
+	    }
+#endif
+	    if (lang && curbuf->b_p_iminsert == B_IMODE_LMAP)
+	    {
+		/* Allow mappings defined with ":lmap". */
+		--no_mapping;
+		--allow_keys;
+		if (repl)
+		    State = LREPLACE;
+		else
+		    State = LANGMAP;
+		langmap_active = TRUE;
+	    }
+#ifdef USE_IM_CONTROL
+	    save_smd = p_smd;
+	    p_smd = FALSE;	/* Don't let the IM code show the mode here */
+	    if (lang && curbuf->b_p_iminsert == B_IMODE_IM)
+		im_set_active(TRUE);
+#endif
+
+	    *cp = safe_vgetc();
+
+	    if (langmap_active)
+	    {
+		/* Undo the decrement done above */
+		++no_mapping;
+		++allow_keys;
+		State = NORMAL_BUSY;
+	    }
+#ifdef USE_IM_CONTROL
+	    if (lang)
+	    {
+		if (curbuf->b_p_iminsert != B_IMODE_LMAP)
+		    im_save_status(&curbuf->b_p_iminsert);
+		im_set_active(FALSE);
+	    }
+	    p_smd = save_smd;
+#endif
+#ifdef CURSOR_SHAPE
+	    State = NORMAL_BUSY;
+#endif
+#ifdef FEAT_CMDL_INFO
+	    need_flushbuf |= add_to_showcmd(*cp);
+#endif
+
+	    if (!lit)
+	    {
+#ifdef FEAT_DIGRAPHS
+		/* Typing CTRL-K gets a digraph. */
+		if (*cp == Ctrl_K
+			&& ((nv_cmds[idx].cmd_flags & NV_LANG)
+			    || cp == &ca.extra_char)
+			&& vim_strchr(p_cpo, CPO_DIGRAPH) == NULL)
+		{
+		    c = get_digraph(FALSE);
+		    if (c > 0)
+		    {
+			*cp = c;
+# ifdef FEAT_CMDL_INFO
+			/* Guessing how to update showcmd here... */
+			del_from_showcmd(3);
+			need_flushbuf |= add_to_showcmd(*cp);
+# endif
+		    }
+		}
+#endif
+
+#ifdef FEAT_LANGMAP
+		/* adjust chars > 127, except after "tTfFr" commands */
+		LANGMAP_ADJUST(*cp, !lang);
+#endif
+#ifdef FEAT_RIGHTLEFT
+		/* adjust Hebrew mapped char */
+		if (p_hkmap && lang && KeyTyped)
+		    *cp = hkmap(*cp);
+# ifdef FEAT_FKMAP
+		/* adjust Farsi mapped char */
+		if (p_fkmap && lang && KeyTyped)
+		    *cp = fkmap(*cp);
+# endif
+#endif
+	    }
+
+	    /*
+	     * When the next character is CTRL-\ a following CTRL-N means the
+	     * command is aborted and we go to Normal mode.
+	     */
+	    if (cp == &ca.extra_char
+		    && ca.nchar == Ctrl_BSL
+		    && (ca.extra_char == Ctrl_N || ca.extra_char == Ctrl_G))
+	    {
+		ca.cmdchar = Ctrl_BSL;
+		ca.nchar = ca.extra_char;
+		idx = find_command(ca.cmdchar);
+	    }
+	    else if (*cp == Ctrl_BSL)
+	    {
+		long towait = (p_ttm >= 0 ? p_ttm : p_tm);
+
+		/* There is a busy wait here when typing "f<C-\>" and then
+		 * something different from CTRL-N.  Can't be avoided. */
+		while ((c = vpeekc()) <= 0 && towait > 0L)
+		{
+		    do_sleep(towait > 50L ? 50L : towait);
+		    towait -= 50L;
+		}
+		if (c > 0)
+		{
+		    c = safe_vgetc();
+		    if (c != Ctrl_N && c != Ctrl_G)
+			vungetc(c);
+		    else
+		    {
+			ca.cmdchar = Ctrl_BSL;
+			ca.nchar = c;
+			idx = find_command(ca.cmdchar);
+		    }
+		}
+	    }
+
+#ifdef FEAT_MBYTE
+	    /* When getting a text character and the next character is a
+	     * multi-byte character, it could be a composing character.
+	     * However, don't wait for it to arrive. */
+	    while (enc_utf8 && lang && (c = vpeekc()) > 0
+				 && (c >= 0x100 || MB_BYTE2LEN(vpeekc()) > 1))
+	    {
+		c = safe_vgetc();
+		if (!utf_iscomposing(c))
+		{
+		    vungetc(c);		/* it wasn't, put it back */
+		    break;
+		}
+		else if (ca.ncharC1 == 0)
+		    ca.ncharC1 = c;
+		else
+		    ca.ncharC2 = c;
+	    }
+#endif
+	}
+	--no_mapping;
+	--allow_keys;
+    }
+
+#ifdef FEAT_CMDL_INFO
+    /*
+     * Flush the showcmd characters onto the screen so we can see them while
+     * the command is being executed.  Only do this when the shown command was
+     * actually displayed, otherwise this will slow down a lot when executing
+     * mappings.
+     */
+    if (need_flushbuf)
+	out_flush();
+#endif
+#ifdef FEAT_AUTOCMD
+    did_cursorhold = FALSE;
+#endif
+
+    State = NORMAL;
+
+    if (ca.nchar == ESC)
+    {
+	clearop(oap);
+	if (restart_edit == 0 && goto_im())
+	    restart_edit = 'a';
+	goto normal_end;
+    }
+
+    if (ca.cmdchar != K_IGNORE)
+    {
+	msg_didout = FALSE;    /* don't scroll screen up for normal command */
+	msg_col = 0;
+    }
+
+#ifdef FEAT_VISUAL
+    old_pos = curwin->w_cursor;		/* remember where cursor was */
+
+    /* When 'keymodel' contains "startsel" some keys start Select/Visual
+     * mode. */
+    if (!VIsual_active && km_startsel)
+    {
+	if (nv_cmds[idx].cmd_flags & NV_SS)
+	{
+	    start_selection();
+	    unshift_special(&ca);
+	    idx = find_command(ca.cmdchar);
+	}
+	else if ((nv_cmds[idx].cmd_flags & NV_SSS)
+					   && (mod_mask & MOD_MASK_SHIFT))
+	{
+	    start_selection();
+	    mod_mask &= ~MOD_MASK_SHIFT;
+	}
+    }
+#endif
+
+    /*
+     * Execute the command!
+     * Call the command function found in the commands table.
+     */
+    ca.arg = nv_cmds[idx].cmd_arg;
+    (nv_cmds[idx].cmd_func)(&ca);
+
+    /*
+     * If we didn't start or finish an operator, reset oap->regname, unless we
+     * need it later.
+     */
+    if (!finish_op
+	    && !oap->op_type
+	    && (idx < 0 || !(nv_cmds[idx].cmd_flags & NV_KEEPREG)))
+    {
+	clearop(oap);
+#ifdef FEAT_EVAL
+	set_reg_var('"');
+#endif
+    }
+
+#ifdef FEAT_VISUAL
+    /* Get the length of mapped chars again after typing a count, second
+     * character or "z333<cr>". */
+    if (old_mapped_len > 0)
+	old_mapped_len = typebuf_maplen();
+#endif
+
+    /*
+     * If an operation is pending, handle it...
+     */
+    do_pending_operator(&ca, old_col, FALSE);
+
+    /*
+     * Wait for a moment when a message is displayed that will be overwritten
+     * by the mode message.
+     * In Visual mode and with "^O" in Insert mode, a short message will be
+     * overwritten by the mode message.  Wait a bit, until a key is hit.
+     * In Visual mode, it's more important to keep the Visual area updated
+     * than keeping a message (e.g. from a /pat search).
+     * Only do this if the command was typed, not from a mapping.
+     * Don't wait when emsg_silent is non-zero.
+     * Also wait a bit after an error message, e.g. for "^O:".
+     * Don't redraw the screen, it would remove the message.
+     */
+    if (       ((p_smd
+		    && msg_silent == 0
+		    && (restart_edit != 0
+#ifdef FEAT_VISUAL
+			|| (VIsual_active
+			    && old_pos.lnum == curwin->w_cursor.lnum
+			    && old_pos.col == curwin->w_cursor.col)
+#endif
+		       )
+		    && (clear_cmdline
+			|| redraw_cmdline)
+		    && (msg_didout || (msg_didany && msg_scroll))
+		    && !msg_nowait
+		    && KeyTyped)
+		|| (restart_edit != 0
+#ifdef FEAT_VISUAL
+		    && !VIsual_active
+#endif
+		    && (msg_scroll
+			|| emsg_on_display)))
+	    && oap->regname == 0
+	    && !(ca.retval & CA_COMMAND_BUSY)
+	    && stuff_empty()
+	    && typebuf_typed()
+	    && emsg_silent == 0
+	    && !did_wait_return
+	    && oap->op_type == OP_NOP)
+    {
+	int	save_State = State;
+
+	/* Draw the cursor with the right shape here */
+	if (restart_edit != 0)
+	    State = INSERT;
+
+	/* If need to redraw, and there is a "keep_msg", redraw before the
+	 * delay */
+	if (must_redraw && keep_msg != NULL && !emsg_on_display)
+	{
+	    char_u	*kmsg;
+
+	    kmsg = keep_msg;
+	    keep_msg = NULL;
+	    /* showmode() will clear keep_msg, but we want to use it anyway */
+	    update_screen(0);
+	    /* now reset it, otherwise it's put in the history again */
+	    keep_msg = kmsg;
+	    msg_attr(kmsg, keep_msg_attr);
+	    vim_free(kmsg);
+	}
+	setcursor();
+	cursor_on();
+	out_flush();
+	if (msg_scroll || emsg_on_display)
+	    ui_delay(1000L, TRUE);	/* wait at least one second */
+	ui_delay(3000L, FALSE);		/* wait up to three seconds */
+	State = save_State;
+
+	msg_scroll = FALSE;
+	emsg_on_display = FALSE;
+    }
+
+    /*
+     * Finish up after executing a Normal mode command.
+     */
+normal_end:
+
+    msg_nowait = FALSE;
+
+    /* Reset finish_op, in case it was set */
+#ifdef CURSOR_SHAPE
+    c = finish_op;
+#endif
+    finish_op = FALSE;
+#ifdef CURSOR_SHAPE
+    /* Redraw the cursor with another shape, if we were in Operator-pending
+     * mode or did a replace command. */
+    if (c || ca.cmdchar == 'r')
+    {
+	ui_cursor_shape();		/* may show different cursor shape */
+# ifdef FEAT_MOUSESHAPE
+	update_mouseshape(-1);
+# endif
+    }
+#endif
+
+#ifdef FEAT_CMDL_INFO
+    if (oap->op_type == OP_NOP && oap->regname == 0)
+	clear_showcmd();
+#endif
+
+    checkpcmark();		/* check if we moved since setting pcmark */
+    vim_free(ca.searchbuf);
+
+#ifdef FEAT_MBYTE
+    if (has_mbyte)
+	mb_adjust_cursor();
+#endif
+
+#ifdef FEAT_SCROLLBIND
+    if (curwin->w_p_scb && toplevel)
+    {
+	validate_cursor();	/* may need to update w_leftcol */
+	do_check_scrollbind(TRUE);
+    }
+#endif
+
+    /*
+     * May restart edit(), if we got here with CTRL-O in Insert mode (but not
+     * if still inside a mapping that started in Visual mode).
+     * May switch from Visual to Select mode after CTRL-O command.
+     */
+    if (       oap->op_type == OP_NOP
+#ifdef FEAT_VISUAL
+	    && ((restart_edit != 0 && !VIsual_active && old_mapped_len == 0)
+		|| restart_VIsual_select == 1)
+#else
+	    && restart_edit != 0
+#endif
+	    && !(ca.retval & CA_COMMAND_BUSY)
+	    && stuff_empty()
+	    && oap->regname == 0)
+    {
+#ifdef FEAT_VISUAL
+	if (restart_VIsual_select == 1)
+	{
+	    VIsual_select = TRUE;
+	    showmode();
+	    restart_VIsual_select = 0;
+	}
+#endif
+	if (restart_edit != 0
+#ifdef FEAT_VISUAL
+		&& !VIsual_active && old_mapped_len == 0
+#endif
+		)
+	    (void)edit(restart_edit, FALSE, 1L);
+    }
+
+#ifdef FEAT_VISUAL
+    if (restart_VIsual_select == 2)
+	restart_VIsual_select = 1;
+#endif
+
+    /* Save count before an operator for next time. */
+    opcount = ca.opcount;
+}
+
+/*
+ * Handle an operator after visual mode or when the movement is finished
+ */
+    void
+do_pending_operator(cap, old_col, gui_yank)
+    cmdarg_T	*cap;
+    int		old_col;
+    int		gui_yank;
+{
+    oparg_T	*oap = cap->oap;
+    pos_T	old_cursor;
+    int		empty_region_error;
+    int		restart_edit_save;
+
+#ifdef FEAT_VISUAL
+    /* The visual area is remembered for redo */
+    static int	    redo_VIsual_mode = NUL; /* 'v', 'V', or Ctrl-V */
+    static linenr_T redo_VIsual_line_count; /* number of lines */
+    static colnr_T  redo_VIsual_col;	    /* number of cols or end column */
+    static long	    redo_VIsual_count;	    /* count for Visual operator */
+# ifdef FEAT_VIRTUALEDIT
+    int		    include_line_break = FALSE;
+# endif
+#endif
+
+#if defined(FEAT_CLIPBOARD)
+    /*
+     * Yank the visual area into the GUI selection register before we operate
+     * on it and lose it forever.
+     * Don't do it if a specific register was specified, so that ""x"*P works.
+     * This could call do_pending_operator() recursively, but that's OK
+     * because gui_yank will be TRUE for the nested call.
+     */
+    if (clip_star.available
+	    && oap->op_type != OP_NOP
+	    && !gui_yank
+# ifdef FEAT_VISUAL
+	    && VIsual_active
+	    && !redo_VIsual_busy
+# endif
+	    && oap->regname == 0)
+	clip_auto_select();
+#endif
+    old_cursor = curwin->w_cursor;
+
+    /*
+     * If an operation is pending, handle it...
+     */
+    if ((finish_op
+#ifdef FEAT_VISUAL
+		|| VIsual_active
+#endif
+		) && oap->op_type != OP_NOP)
+    {
+#ifdef FEAT_VISUAL
+	oap->is_VIsual = VIsual_active;
+	if (oap->motion_force == 'V')
+	    oap->motion_type = MLINE;
+	else if (oap->motion_force == 'v')
+	{
+	    /* If the motion was linewise, "inclusive" will not have been set.
+	     * Use "exclusive" to be consistent.  Makes "dvj" work nice. */
+	    if (oap->motion_type == MLINE)
+		oap->inclusive = FALSE;
+	    /* If the motion already was characterwise, toggle "inclusive" */
+	    else if (oap->motion_type == MCHAR)
+		oap->inclusive = !oap->inclusive;
+	    oap->motion_type = MCHAR;
+	}
+	else if (oap->motion_force == Ctrl_V)
+	{
+	    /* Change line- or characterwise motion into Visual block mode. */
+	    VIsual_active = TRUE;
+	    VIsual = oap->start;
+	    VIsual_mode = Ctrl_V;
+	    VIsual_select = FALSE;
+	    VIsual_reselect = FALSE;
+	}
+#endif
+
+	/* only redo yank when 'y' flag is in 'cpoptions' */
+	/* never redo "zf" (define fold) */
+	if ((vim_strchr(p_cpo, CPO_YANK) != NULL || oap->op_type != OP_YANK)
+#ifdef FEAT_VISUAL
+		&& (!VIsual_active || oap->motion_force)
+#endif
+		&& cap->cmdchar != 'D'
+#ifdef FEAT_FOLDING
+		&& oap->op_type != OP_FOLD
+		&& oap->op_type != OP_FOLDOPEN
+		&& oap->op_type != OP_FOLDOPENREC
+		&& oap->op_type != OP_FOLDCLOSE
+		&& oap->op_type != OP_FOLDCLOSEREC
+		&& oap->op_type != OP_FOLDDEL
+		&& oap->op_type != OP_FOLDDELREC
+#endif
+		)
+	{
+	    prep_redo(oap->regname, cap->count0,
+		    get_op_char(oap->op_type), get_extra_op_char(oap->op_type),
+		    oap->motion_force, cap->cmdchar, cap->nchar);
+	    if (cap->cmdchar == '/' || cap->cmdchar == '?') /* was a search */
+	    {
+		/*
+		 * If 'cpoptions' does not contain 'r', insert the search
+		 * pattern to really repeat the same command.
+		 */
+		if (vim_strchr(p_cpo, CPO_REDO) == NULL)
+		    AppendToRedobuffLit(cap->searchbuf, -1);
+		AppendToRedobuff(NL_STR);
+	    }
+	    else if (cap->cmdchar == ':')
+	    {
+		/* do_cmdline() has stored the first typed line in
+		 * "repeat_cmdline".  When several lines are typed repeating
+		 * won't be possible. */
+		if (repeat_cmdline == NULL)
+		    ResetRedobuff();
+		else
+		{
+		    AppendToRedobuffLit(repeat_cmdline, -1);
+		    AppendToRedobuff(NL_STR);
+		    vim_free(repeat_cmdline);
+		    repeat_cmdline = NULL;
+		}
+	    }
+	}
+
+#ifdef FEAT_VISUAL
+	if (redo_VIsual_busy)
+	{
+	    oap->start = curwin->w_cursor;
+	    curwin->w_cursor.lnum += redo_VIsual_line_count - 1;
+	    if (curwin->w_cursor.lnum > curbuf->b_ml.ml_line_count)
+		curwin->w_cursor.lnum = curbuf->b_ml.ml_line_count;
+	    VIsual_mode = redo_VIsual_mode;
+	    if (VIsual_mode == 'v')
+	    {
+		if (redo_VIsual_line_count <= 1)
+		    curwin->w_cursor.col += redo_VIsual_col - 1;
+		else
+		    curwin->w_cursor.col = redo_VIsual_col;
+	    }
+	    if (redo_VIsual_col == MAXCOL)
+	    {
+		curwin->w_curswant = MAXCOL;
+		coladvance((colnr_T)MAXCOL);
+	    }
+	    cap->count0 = redo_VIsual_count;
+	    if (redo_VIsual_count != 0)
+		cap->count1 = redo_VIsual_count;
+	    else
+		cap->count1 = 1;
+	}
+	else if (VIsual_active)
+	{
+	    if (!gui_yank)
+	    {
+		/* Save the current VIsual area for '< and '> marks, and "gv" */
+		curbuf->b_visual.vi_start = VIsual;
+		curbuf->b_visual.vi_end = curwin->w_cursor;
+		curbuf->b_visual.vi_mode = VIsual_mode;
+		curbuf->b_visual.vi_curswant = curwin->w_curswant;
+# ifdef FEAT_EVAL
+		curbuf->b_visual_mode_eval = VIsual_mode;
+# endif
+	    }
+
+	    /* In Select mode, a linewise selection is operated upon like a
+	     * characterwise selection. */
+	    if (VIsual_select && VIsual_mode == 'V')
+	    {
+		if (lt(VIsual, curwin->w_cursor))
+		{
+		    VIsual.col = 0;
+		    curwin->w_cursor.col =
+			       (colnr_T)STRLEN(ml_get(curwin->w_cursor.lnum));
+		}
+		else
+		{
+		    curwin->w_cursor.col = 0;
+		    VIsual.col = (colnr_T)STRLEN(ml_get(VIsual.lnum));
+		}
+		VIsual_mode = 'v';
+	    }
+	    /* If 'selection' is "exclusive", backup one character for
+	     * charwise selections. */
+	    else if (VIsual_mode == 'v')
+	    {
+# ifdef FEAT_VIRTUALEDIT
+		include_line_break =
+# endif
+		    unadjust_for_sel();
+	    }
+
+	    oap->start = VIsual;
+	    if (VIsual_mode == 'V')
+		oap->start.col = 0;
+	}
+#endif /* FEAT_VISUAL */
+
+	/*
+	 * Set oap->start to the first position of the operated text, oap->end
+	 * to the end of the operated text.  w_cursor is equal to oap->start.
+	 */
+	if (lt(oap->start, curwin->w_cursor))
+	{
+#ifdef FEAT_FOLDING
+	    /* Include folded lines completely. */
+	    if (!VIsual_active)
+	    {
+		if (hasFolding(oap->start.lnum, &oap->start.lnum, NULL))
+		    oap->start.col = 0;
+		if (hasFolding(curwin->w_cursor.lnum, NULL,
+						      &curwin->w_cursor.lnum))
+		    curwin->w_cursor.col = (colnr_T)STRLEN(ml_get_curline());
+	    }
+#endif
+	    oap->end = curwin->w_cursor;
+	    curwin->w_cursor = oap->start;
+
+	    /* w_virtcol may have been updated; if the cursor goes back to its
+	     * previous position w_virtcol becomes invalid and isn't updated
+	     * automatically. */
+	    curwin->w_valid &= ~VALID_VIRTCOL;
+	}
+	else
+	{
+#ifdef FEAT_FOLDING
+	    /* Include folded lines completely. */
+	    if (!VIsual_active && oap->motion_type == MLINE)
+	    {
+		if (hasFolding(curwin->w_cursor.lnum, &curwin->w_cursor.lnum,
+									NULL))
+		    curwin->w_cursor.col = 0;
+		if (hasFolding(oap->start.lnum, NULL, &oap->start.lnum))
+		    oap->start.col = (colnr_T)STRLEN(ml_get(oap->start.lnum));
+	    }
+#endif
+	    oap->end = oap->start;
+	    oap->start = curwin->w_cursor;
+	}
+
+	oap->line_count = oap->end.lnum - oap->start.lnum + 1;
+
+#ifdef FEAT_VIRTUALEDIT
+	/* Set "virtual_op" before resetting VIsual_active. */
+	virtual_op = virtual_active();
+#endif
+
+#ifdef FEAT_VISUAL
+	if (VIsual_active || redo_VIsual_busy)
+	{
+	    if (VIsual_mode == Ctrl_V)	/* block mode */
+	    {
+		colnr_T	    start, end;
+
+		oap->block_mode = TRUE;
+
+		getvvcol(curwin, &(oap->start),
+				      &oap->start_vcol, NULL, &oap->end_vcol);
+		if (!redo_VIsual_busy)
+		{
+		    getvvcol(curwin, &(oap->end), &start, NULL, &end);
+
+		    if (start < oap->start_vcol)
+			oap->start_vcol = start;
+		    if (end > oap->end_vcol)
+		    {
+			if (*p_sel == 'e' && start >= 1
+						&& start - 1 >= oap->end_vcol)
+			    oap->end_vcol = start - 1;
+			else
+			    oap->end_vcol = end;
+		    }
+		}
+
+		/* if '$' was used, get oap->end_vcol from longest line */
+		if (curwin->w_curswant == MAXCOL)
+		{
+		    curwin->w_cursor.col = MAXCOL;
+		    oap->end_vcol = 0;
+		    for (curwin->w_cursor.lnum = oap->start.lnum;
+			    curwin->w_cursor.lnum <= oap->end.lnum;
+						      ++curwin->w_cursor.lnum)
+		    {
+			getvvcol(curwin, &curwin->w_cursor, NULL, NULL, &end);
+			if (end > oap->end_vcol)
+			    oap->end_vcol = end;
+		    }
+		}
+		else if (redo_VIsual_busy)
+		    oap->end_vcol = oap->start_vcol + redo_VIsual_col - 1;
+		/*
+		 * Correct oap->end.col and oap->start.col to be the
+		 * upper-left and lower-right corner of the block area.
+		 *
+		 * (Actually, this does convert column positions into character
+		 * positions)
+		 */
+		curwin->w_cursor.lnum = oap->end.lnum;
+		coladvance(oap->end_vcol);
+		oap->end = curwin->w_cursor;
+
+		curwin->w_cursor = oap->start;
+		coladvance(oap->start_vcol);
+		oap->start = curwin->w_cursor;
+	    }
+
+	    if (!redo_VIsual_busy && !gui_yank)
+	    {
+		/*
+		 * Prepare to reselect and redo Visual: this is based on the
+		 * size of the Visual text
+		 */
+		resel_VIsual_mode = VIsual_mode;
+		if (curwin->w_curswant == MAXCOL)
+		    resel_VIsual_col = MAXCOL;
+		else if (VIsual_mode == Ctrl_V)
+		    resel_VIsual_col = oap->end_vcol - oap->start_vcol + 1;
+		else if (oap->line_count > 1)
+		    resel_VIsual_col = oap->end.col;
+		else
+		    resel_VIsual_col = oap->end.col - oap->start.col + 1;
+		resel_VIsual_line_count = oap->line_count;
+	    }
+
+	    /* can't redo yank (unless 'y' is in 'cpoptions') and ":" */
+	    if ((vim_strchr(p_cpo, CPO_YANK) != NULL || oap->op_type != OP_YANK)
+		    && oap->op_type != OP_COLON
+#ifdef FEAT_FOLDING
+		    && oap->op_type != OP_FOLD
+		    && oap->op_type != OP_FOLDOPEN
+		    && oap->op_type != OP_FOLDOPENREC
+		    && oap->op_type != OP_FOLDCLOSE
+		    && oap->op_type != OP_FOLDCLOSEREC
+		    && oap->op_type != OP_FOLDDEL
+		    && oap->op_type != OP_FOLDDELREC
+#endif
+		    && oap->motion_force == NUL
+		    )
+	    {
+		/* Prepare for redoing.  Only use the nchar field for "r",
+		 * otherwise it might be the second char of the operator. */
+		prep_redo(oap->regname, 0L, NUL, 'v',
+				get_op_char(oap->op_type),
+				get_extra_op_char(oap->op_type),
+				oap->op_type == OP_REPLACE ? cap->nchar : NUL);
+		if (!redo_VIsual_busy)
+		{
+		    redo_VIsual_mode = resel_VIsual_mode;
+		    redo_VIsual_col = resel_VIsual_col;
+		    redo_VIsual_line_count = resel_VIsual_line_count;
+		    redo_VIsual_count = cap->count0;
+		}
+	    }
+
+	    /*
+	     * oap->inclusive defaults to TRUE.
+	     * If oap->end is on a NUL (empty line) oap->inclusive becomes
+	     * FALSE.  This makes "d}P" and "v}dP" work the same.
+	     */
+	    if (oap->motion_force == NUL || oap->motion_type == MLINE)
+		oap->inclusive = TRUE;
+	    if (VIsual_mode == 'V')
+		oap->motion_type = MLINE;
+	    else
+	    {
+		oap->motion_type = MCHAR;
+		if (VIsual_mode != Ctrl_V && *ml_get_pos(&(oap->end)) == NUL
+# ifdef FEAT_VIRTUALEDIT
+			&& (include_line_break || !virtual_op)
+# endif
+			)
+		{
+		    oap->inclusive = FALSE;
+		    /* Try to include the newline, unless it's an operator
+		     * that works on lines only */
+		    if (*p_sel != 'o'
+			    && !op_on_lines(oap->op_type)
+			    && oap->end.lnum < curbuf->b_ml.ml_line_count)
+		    {
+			++oap->end.lnum;
+			oap->end.col = 0;
+# ifdef FEAT_VIRTUALEDIT
+			oap->end.coladd = 0;
+# endif
+			++oap->line_count;
+		    }
+		}
+	    }
+
+	    redo_VIsual_busy = FALSE;
+
+	    /*
+	     * Switch Visual off now, so screen updating does
+	     * not show inverted text when the screen is redrawn.
+	     * With OP_YANK and sometimes with OP_COLON and OP_FILTER there is
+	     * no screen redraw, so it is done here to remove the inverted
+	     * part.
+	     */
+	    if (!gui_yank)
+	    {
+		VIsual_active = FALSE;
+# ifdef FEAT_MOUSE
+		setmouse();
+		mouse_dragging = 0;
+# endif
+		if (mode_displayed)
+		    clear_cmdline = TRUE;   /* unshow visual mode later */
+#ifdef FEAT_CMDL_INFO
+		else
+		    clear_showcmd();
+#endif
+		if ((oap->op_type == OP_YANK
+			    || oap->op_type == OP_COLON
+			    || oap->op_type == OP_FUNCTION
+			    || oap->op_type == OP_FILTER)
+			&& oap->motion_force == NUL)
+		    redraw_curbuf_later(INVERTED);
+	    }
+	}
+#endif
+
+#ifdef FEAT_MBYTE
+	/* Include the trailing byte of a multi-byte char. */
+	if (has_mbyte && oap->inclusive)
+	{
+	    int		l;
+
+	    l = (*mb_ptr2len)(ml_get_pos(&oap->end));
+	    if (l > 1)
+		oap->end.col += l - 1;
+	}
+#endif
+	curwin->w_set_curswant = TRUE;
+
+	/*
+	 * oap->empty is set when start and end are the same.  The inclusive
+	 * flag affects this too, unless yanking and the end is on a NUL.
+	 */
+	oap->empty = (oap->motion_type == MCHAR
+		    && (!oap->inclusive
+			|| (oap->op_type == OP_YANK
+			    && gchar_pos(&oap->end) == NUL))
+		    && equalpos(oap->start, oap->end)
+#ifdef FEAT_VIRTUALEDIT
+		    && !(virtual_op && oap->start.coladd != oap->end.coladd)
+#endif
+		    );
+	/*
+	 * For delete, change and yank, it's an error to operate on an
+	 * empty region, when 'E' included in 'cpoptions' (Vi compatible).
+	 */
+	empty_region_error = (oap->empty
+				&& vim_strchr(p_cpo, CPO_EMPTYREGION) != NULL);
+
+#ifdef FEAT_VISUAL
+	/* Force a redraw when operating on an empty Visual region, when
+	 * 'modifiable is off or creating a fold. */
+	if (oap->is_VIsual && (oap->empty || !curbuf->b_p_ma
+# ifdef FEAT_FOLDING
+		    || oap->op_type == OP_FOLD
+# endif
+		    ))
+	    redraw_curbuf_later(INVERTED);
+#endif
+
+	/*
+	 * If the end of an operator is in column one while oap->motion_type
+	 * is MCHAR and oap->inclusive is FALSE, we put op_end after the last
+	 * character in the previous line. If op_start is on or before the
+	 * first non-blank in the line, the operator becomes linewise
+	 * (strange, but that's the way vi does it).
+	 */
+	if (	   oap->motion_type == MCHAR
+		&& oap->inclusive == FALSE
+		&& !(cap->retval & CA_NO_ADJ_OP_END)
+		&& oap->end.col == 0
+#ifdef FEAT_VISUAL
+		&& (!oap->is_VIsual || *p_sel == 'o')
+		&& !oap->block_mode
+#endif
+		&& oap->line_count > 1)
+	{
+	    oap->end_adjusted = TRUE;	    /* remember that we did this */
+	    --oap->line_count;
+	    --oap->end.lnum;
+	    if (inindent(0))
+		oap->motion_type = MLINE;
+	    else
+	    {
+		oap->end.col = (colnr_T)STRLEN(ml_get(oap->end.lnum));
+		if (oap->end.col)
+		{
+		    --oap->end.col;
+		    oap->inclusive = TRUE;
+		}
+	    }
+	}
+	else
+	    oap->end_adjusted = FALSE;
+
+	switch (oap->op_type)
+	{
+	case OP_LSHIFT:
+	case OP_RSHIFT:
+	    op_shift(oap, TRUE,
+#ifdef FEAT_VISUAL
+		    oap->is_VIsual ? (int)cap->count1 :
+#endif
+		    1);
+	    auto_format(FALSE, TRUE);
+	    break;
+
+	case OP_JOIN_NS:
+	case OP_JOIN:
+	    if (oap->line_count < 2)
+		oap->line_count = 2;
+	    if (curwin->w_cursor.lnum + oap->line_count - 1 >
+						   curbuf->b_ml.ml_line_count)
+		beep_flush();
+	    else
+	    {
+		do_do_join(oap->line_count, oap->op_type == OP_JOIN);
+		auto_format(FALSE, TRUE);
+	    }
+	    break;
+
+	case OP_DELETE:
+#ifdef FEAT_VISUAL
+	    VIsual_reselect = FALSE;	    /* don't reselect now */
+#endif
+	    if (empty_region_error)
+		vim_beep();
+	    else
+	    {
+		(void)op_delete(oap);
+		if (oap->motion_type == MLINE && has_format_option(FO_AUTO))
+		    u_save_cursor();	    /* cursor line wasn't saved yet */
+		auto_format(FALSE, TRUE);
+	    }
+	    break;
+
+	case OP_YANK:
+	    if (empty_region_error)
+	    {
+		if (!gui_yank)
+		    vim_beep();
+	    }
+	    else
+		(void)op_yank(oap, FALSE, !gui_yank);
+	    check_cursor_col();
+	    break;
+
+	case OP_CHANGE:
+#ifdef FEAT_VISUAL
+	    VIsual_reselect = FALSE;	    /* don't reselect now */
+#endif
+	    if (empty_region_error)
+		vim_beep();
+	    else
+	    {
+		/* This is a new edit command, not a restart.  Need to
+		 * remember it to make 'insertmode' work with mappings for
+		 * Visual mode.  But do this only once and not when typed and
+		 * 'insertmode' isn't set. */
+		if (p_im || !KeyTyped)
+		    restart_edit_save = restart_edit;
+		else
+		    restart_edit_save = 0;
+		restart_edit = 0;
+		/* Reset finish_op now, don't want it set inside edit(). */
+		finish_op = FALSE;
+		if (op_change(oap))	/* will call edit() */
+		    cap->retval |= CA_COMMAND_BUSY;
+		if (restart_edit == 0)
+		    restart_edit = restart_edit_save;
+	    }
+	    break;
+
+	case OP_FILTER:
+	    if (vim_strchr(p_cpo, CPO_FILTER) != NULL)
+		AppendToRedobuff((char_u *)"!\r");  /* use any last used !cmd */
+	    else
+		bangredo = TRUE;    /* do_bang() will put cmd in redo buffer */
+
+	case OP_INDENT:
+	case OP_COLON:
+
+#if defined(FEAT_LISP) || defined(FEAT_CINDENT)
+	    /*
+	     * If 'equalprg' is empty, do the indenting internally.
+	     */
+	    if (oap->op_type == OP_INDENT && *get_equalprg() == NUL)
+	    {
+# ifdef FEAT_LISP
+		if (curbuf->b_p_lisp)
+		{
+		    op_reindent(oap, get_lisp_indent);
+		    break;
+		}
+# endif
+# ifdef FEAT_CINDENT
+		op_reindent(oap,
+#  ifdef FEAT_EVAL
+			*curbuf->b_p_inde != NUL ? get_expr_indent :
+#  endif
+			    get_c_indent);
+		break;
+# endif
+	    }
+#endif
+
+	    op_colon(oap);
+	    break;
+
+	case OP_TILDE:
+	case OP_UPPER:
+	case OP_LOWER:
+	case OP_ROT13:
+	    if (empty_region_error)
+		vim_beep();
+	    else
+		op_tilde(oap);
+	    check_cursor_col();
+	    break;
+
+	case OP_FORMAT:
+#if defined(FEAT_EVAL)
+	    if (*curbuf->b_p_fex != NUL)
+		op_formatexpr(oap);	/* use expression */
+	    else
+#endif
+		if (*p_fp != NUL)
+		op_colon(oap);		/* use external command */
+	    else
+		op_format(oap, FALSE);	/* use internal function */
+	    break;
+
+	case OP_FORMAT2:
+	    op_format(oap, TRUE);	/* use internal function */
+	    break;
+
+	case OP_FUNCTION:
+	    op_function(oap);		/* call 'operatorfunc' */
+	    break;
+
+	case OP_INSERT:
+	case OP_APPEND:
+#ifdef FEAT_VISUAL
+	    VIsual_reselect = FALSE;	/* don't reselect now */
+#endif
+#ifdef FEAT_VISUALEXTRA
+	    if (empty_region_error)
+		vim_beep();
+	    else
+	    {
+		/* This is a new edit command, not a restart.  Need to
+		 * remember it to make 'insertmode' work with mappings for
+		 * Visual mode.  But do this only once. */
+		restart_edit_save = restart_edit;
+		restart_edit = 0;
+
+		op_insert(oap, cap->count1);
+
+		/* TODO: when inserting in several lines, should format all
+		 * the lines. */
+		auto_format(FALSE, TRUE);
+
+		if (restart_edit == 0)
+		    restart_edit = restart_edit_save;
+	    }
+#else
+	    vim_beep();
+#endif
+	    break;
+
+	case OP_REPLACE:
+#ifdef FEAT_VISUAL
+	    VIsual_reselect = FALSE;	/* don't reselect now */
+#endif
+#ifdef FEAT_VISUALEXTRA
+	    if (empty_region_error)
+#endif
+		vim_beep();
+#ifdef FEAT_VISUALEXTRA
+	    else
+		op_replace(oap, cap->nchar);
+#endif
+	    break;
+
+#ifdef FEAT_FOLDING
+	case OP_FOLD:
+	    VIsual_reselect = FALSE;	/* don't reselect now */
+	    foldCreate(oap->start.lnum, oap->end.lnum);
+	    break;
+
+	case OP_FOLDOPEN:
+	case OP_FOLDOPENREC:
+	case OP_FOLDCLOSE:
+	case OP_FOLDCLOSEREC:
+	    VIsual_reselect = FALSE;	/* don't reselect now */
+	    opFoldRange(oap->start.lnum, oap->end.lnum,
+		    oap->op_type == OP_FOLDOPEN
+					    || oap->op_type == OP_FOLDOPENREC,
+		    oap->op_type == OP_FOLDOPENREC
+					  || oap->op_type == OP_FOLDCLOSEREC,
+					  oap->is_VIsual);
+	    break;
+
+	case OP_FOLDDEL:
+	case OP_FOLDDELREC:
+	    VIsual_reselect = FALSE;	/* don't reselect now */
+	    deleteFold(oap->start.lnum, oap->end.lnum,
+			       oap->op_type == OP_FOLDDELREC, oap->is_VIsual);
+	    break;
+#endif
+	default:
+	    clearopbeep(oap);
+	}
+#ifdef FEAT_VIRTUALEDIT
+	virtual_op = MAYBE;
+#endif
+	if (!gui_yank)
+	{
+	    /*
+	     * if 'sol' not set, go back to old column for some commands
+	     */
+	    if (!p_sol && oap->motion_type == MLINE && !oap->end_adjusted
+		    && (oap->op_type == OP_LSHIFT || oap->op_type == OP_RSHIFT
+						|| oap->op_type == OP_DELETE))
+		coladvance(curwin->w_curswant = old_col);
+	}
+	else
+	{
+	    curwin->w_cursor = old_cursor;
+	}
+#ifdef FEAT_VISUAL
+	oap->block_mode = FALSE;
+#endif
+	clearop(oap);
+    }
+}
+
+/*
+ * Handle indent and format operators and visual mode ":".
+ */
+    static void
+op_colon(oap)
+    oparg_T	*oap;
+{
+    stuffcharReadbuff(':');
+#ifdef FEAT_VISUAL
+    if (oap->is_VIsual)
+	stuffReadbuff((char_u *)"'<,'>");
+    else
+#endif
+    {
+	/*
+	 * Make the range look nice, so it can be repeated.
+	 */
+	if (oap->start.lnum == curwin->w_cursor.lnum)
+	    stuffcharReadbuff('.');
+	else
+	    stuffnumReadbuff((long)oap->start.lnum);
+	if (oap->end.lnum != oap->start.lnum)
+	{
+	    stuffcharReadbuff(',');
+	    if (oap->end.lnum == curwin->w_cursor.lnum)
+		stuffcharReadbuff('.');
+	    else if (oap->end.lnum == curbuf->b_ml.ml_line_count)
+		stuffcharReadbuff('$');
+	    else if (oap->start.lnum == curwin->w_cursor.lnum)
+	    {
+		stuffReadbuff((char_u *)".+");
+		stuffnumReadbuff((long)oap->line_count - 1);
+	    }
+	    else
+		stuffnumReadbuff((long)oap->end.lnum);
+	}
+    }
+    if (oap->op_type != OP_COLON)
+	stuffReadbuff((char_u *)"!");
+    if (oap->op_type == OP_INDENT)
+    {
+#ifndef FEAT_CINDENT
+	if (*get_equalprg() == NUL)
+	    stuffReadbuff((char_u *)"indent");
+	else
+#endif
+	    stuffReadbuff(get_equalprg());
+	stuffReadbuff((char_u *)"\n");
+    }
+    else if (oap->op_type == OP_FORMAT)
+    {
+	if (*p_fp == NUL)
+	    stuffReadbuff((char_u *)"fmt");
+	else
+	    stuffReadbuff(p_fp);
+	stuffReadbuff((char_u *)"\n']");
+    }
+
+    /*
+     * do_cmdline() does the rest
+     */
+}
+
+/*
+ * Handle the "g@" operator: call 'operatorfunc'.
+ */
+/*ARGSUSED*/
+    static void
+op_function(oap)
+    oparg_T	*oap;
+{
+#ifdef FEAT_EVAL
+    char_u	*(argv[1]);
+
+    if (*p_opfunc == NUL)
+	EMSG(_("E774: 'operatorfunc' is empty"));
+    else
+    {
+	/* Set '[ and '] marks to text to be operated on. */
+	curbuf->b_op_start = oap->start;
+	curbuf->b_op_end = oap->end;
+	if (oap->motion_type != MLINE && !oap->inclusive)
+	    /* Exclude the end position. */
+	    decl(&curbuf->b_op_end);
+
+	if (oap->block_mode)
+	    argv[0] = (char_u *)"block";
+	else if (oap->motion_type == MLINE)
+	    argv[0] = (char_u *)"line";
+	else
+	    argv[0] = (char_u *)"char";
+	(void)call_func_retnr(p_opfunc, 1, argv, FALSE);
+    }
+#else
+    EMSG(_("E775: Eval feature not available"));
+#endif
+}
+
+#if defined(FEAT_MOUSE) || defined(PROTO)
+/*
+ * Do the appropriate action for the current mouse click in the current mode.
+ * Not used for Command-line mode.
+ *
+ * Normal Mode:
+ * event	 modi-	position      visual	   change   action
+ *		 fier	cursor			   window
+ * left press	  -	yes	    end		    yes
+ * left press	  C	yes	    end		    yes	    "^]" (2)
+ * left press	  S	yes	    end		    yes	    "*" (2)
+ * left drag	  -	yes	start if moved	    no
+ * left relse	  -	yes	start if moved	    no
+ * middle press	  -	yes	 if not active	    no	    put register
+ * middle press	  -	yes	 if active	    no	    yank and put
+ * right press	  -	yes	start or extend	    yes
+ * right press	  S	yes	no change	    yes	    "#" (2)
+ * right drag	  -	yes	extend		    no
+ * right relse	  -	yes	extend		    no
+ *
+ * Insert or Replace Mode:
+ * event	 modi-	position      visual	   change   action
+ *		 fier	cursor			   window
+ * left press	  -	yes	(cannot be active)  yes
+ * left press	  C	yes	(cannot be active)  yes	    "CTRL-O^]" (2)
+ * left press	  S	yes	(cannot be active)  yes	    "CTRL-O*" (2)
+ * left drag	  -	yes	start or extend (1) no	    CTRL-O (1)
+ * left relse	  -	yes	start or extend (1) no	    CTRL-O (1)
+ * middle press	  -	no	(cannot be active)  no	    put register
+ * right press	  -	yes	start or extend	    yes	    CTRL-O
+ * right press	  S	yes	(cannot be active)  yes	    "CTRL-O#" (2)
+ *
+ * (1) only if mouse pointer moved since press
+ * (2) only if click is in same buffer
+ *
+ * Return TRUE if start_arrow() should be called for edit mode.
+ */
+    int
+do_mouse(oap, c, dir, count, fixindent)
+    oparg_T	*oap;		/* operator argument, can be NULL */
+    int		c;		/* K_LEFTMOUSE, etc */
+    int		dir;		/* Direction to 'put' if necessary */
+    long	count;
+    int		fixindent;	/* PUT_FIXINDENT if fixing indent necessary */
+{
+    static int	do_always = FALSE;	/* ignore 'mouse' setting next time */
+    static int	got_click = FALSE;	/* got a click some time back */
+
+    int		which_button;	/* MOUSE_LEFT, _MIDDLE or _RIGHT */
+    int		is_click;	/* If FALSE it's a drag or release event */
+    int		is_drag;	/* If TRUE it's a drag event */
+    int		jump_flags = 0;	/* flags for jump_to_mouse() */
+    pos_T	start_visual;
+    int		moved;		/* Has cursor moved? */
+    int		in_status_line;	/* mouse in status line */
+#ifdef FEAT_VERTSPLIT
+    int		in_sep_line;	/* mouse in vertical separator line */
+#endif
+    int		c1, c2;
+#if defined(FEAT_FOLDING)
+    pos_T	save_cursor;
+#endif
+    win_T	*old_curwin = curwin;
+#ifdef FEAT_VISUAL
+    static pos_T orig_cursor;
+    colnr_T	leftcol, rightcol;
+    pos_T	end_visual;
+    int		diff;
+    int		old_active = VIsual_active;
+    int		old_mode = VIsual_mode;
+#endif
+    int		regname;
+
+#if defined(FEAT_FOLDING)
+    save_cursor = curwin->w_cursor;
+#endif
+
+    /*
+     * When GUI is active, always recognize mouse events, otherwise:
+     * - Ignore mouse event in normal mode if 'mouse' doesn't include 'n'.
+     * - Ignore mouse event in visual mode if 'mouse' doesn't include 'v'.
+     * - For command line and insert mode 'mouse' is checked before calling
+     *	 do_mouse().
+     */
+    if (do_always)
+	do_always = FALSE;
+    else
+#ifdef FEAT_GUI
+	if (!gui.in_use)
+#endif
+	{
+#ifdef FEAT_VISUAL
+	    if (VIsual_active)
+	    {
+		if (!mouse_has(MOUSE_VISUAL))
+		    return FALSE;
+	    }
+	    else
+#endif
+		if (State == NORMAL && !mouse_has(MOUSE_NORMAL))
+		return FALSE;
+	}
+
+    which_button = get_mouse_button(KEY2TERMCAP1(c), &is_click, &is_drag);
+
+#ifdef FEAT_MOUSESHAPE
+    /* May have stopped dragging the status or separator line.  The pointer is
+     * most likely still on the status or separator line. */
+    if (!is_drag && drag_status_line)
+    {
+	drag_status_line = FALSE;
+	update_mouseshape(SHAPE_IDX_STATUS);
+    }
+# ifdef FEAT_VERTSPLIT
+    if (!is_drag && drag_sep_line)
+    {
+	drag_sep_line = FALSE;
+	update_mouseshape(SHAPE_IDX_VSEP);
+    }
+# endif
+#endif
+
+    /*
+     * Ignore drag and release events if we didn't get a click.
+     */
+    if (is_click)
+	got_click = TRUE;
+    else
+    {
+	if (!got_click)			/* didn't get click, ignore */
+	    return FALSE;
+	if (!is_drag)			/* release, reset got_click */
+	    got_click = FALSE;
+    }
+
+#ifndef FEAT_VISUAL
+    /*
+     * ALT is only used for starging/extending Visual mode.
+     */
+    if ((mod_mask & MOD_MASK_ALT))
+	return FALSE;
+#endif
+
+    /*
+     * CTRL right mouse button does CTRL-T
+     */
+    if (is_click && (mod_mask & MOD_MASK_CTRL) && which_button == MOUSE_RIGHT)
+    {
+	if (State & INSERT)
+	    stuffcharReadbuff(Ctrl_O);
+	if (count > 1)
+	    stuffnumReadbuff(count);
+	stuffcharReadbuff(Ctrl_T);
+	got_click = FALSE;		/* ignore drag&release now */
+	return FALSE;
+    }
+
+    /*
+     * CTRL only works with left mouse button
+     */
+    if ((mod_mask & MOD_MASK_CTRL) && which_button != MOUSE_LEFT)
+	return FALSE;
+
+    /*
+     * When a modifier is down, ignore drag and release events, as well as
+     * multiple clicks and the middle mouse button.
+     * Accept shift-leftmouse drags when 'mousemodel' is "popup.*".
+     */
+    if ((mod_mask & (MOD_MASK_SHIFT | MOD_MASK_CTRL | MOD_MASK_ALT
+							     | MOD_MASK_META))
+	    && (!is_click
+		|| (mod_mask & MOD_MASK_MULTI_CLICK)
+		|| which_button == MOUSE_MIDDLE)
+	    && !((mod_mask & (MOD_MASK_SHIFT|MOD_MASK_ALT))
+		&& mouse_model_popup()
+		&& which_button == MOUSE_LEFT)
+	    && !((mod_mask & MOD_MASK_ALT)
+		&& !mouse_model_popup()
+		&& which_button == MOUSE_RIGHT)
+	    )
+	return FALSE;
+
+    /*
+     * If the button press was used as the movement command for an operator
+     * (eg "d<MOUSE>"), or it is the middle button that is held down, ignore
+     * drag/release events.
+     */
+    if (!is_click && which_button == MOUSE_MIDDLE)
+	return FALSE;
+
+    if (oap != NULL)
+	regname = oap->regname;
+    else
+	regname = 0;
+
+    /*
+     * Middle mouse button does a 'put' of the selected text
+     */
+    if (which_button == MOUSE_MIDDLE)
+    {
+	if (State == NORMAL)
+	{
+	    /*
+	     * If an operator was pending, we don't know what the user wanted
+	     * to do. Go back to normal mode: Clear the operator and beep().
+	     */
+	    if (oap != NULL && oap->op_type != OP_NOP)
+	    {
+		clearopbeep(oap);
+		return FALSE;
+	    }
+
+#ifdef FEAT_VISUAL
+	    /*
+	     * If visual was active, yank the highlighted text and put it
+	     * before the mouse pointer position.
+	     * In Select mode replace the highlighted text with the clipboard.
+	     */
+	    if (VIsual_active)
+	    {
+		if (VIsual_select)
+		{
+		    stuffcharReadbuff(Ctrl_G);
+		    stuffReadbuff((char_u *)"\"+p");
+		}
+		else
+		{
+		    stuffcharReadbuff('y');
+		    stuffcharReadbuff(K_MIDDLEMOUSE);
+		}
+		do_always = TRUE;	/* ignore 'mouse' setting next time */
+		return FALSE;
+	    }
+#endif
+	    /*
+	     * The rest is below jump_to_mouse()
+	     */
+	}
+
+	else if ((State & INSERT) == 0)
+	    return FALSE;
+
+	/*
+	 * Middle click in insert mode doesn't move the mouse, just insert the
+	 * contents of a register.  '.' register is special, can't insert that
+	 * with do_put().
+	 * Also paste at the cursor if the current mode isn't in 'mouse' (only
+	 * happens for the GUI).
+	 */
+	if ((State & INSERT) || !mouse_has(MOUSE_NORMAL))
+	{
+	    if (regname == '.')
+		insert_reg(regname, TRUE);
+	    else
+	    {
+#ifdef FEAT_CLIPBOARD
+		if (clip_star.available && regname == 0)
+		    regname = '*';
+#endif
+		if ((State & REPLACE_FLAG) && !yank_register_mline(regname))
+		    insert_reg(regname, TRUE);
+		else
+		{
+		    do_put(regname, BACKWARD, 1L, fixindent | PUT_CURSEND);
+
+		    /* Repeat it with CTRL-R CTRL-O r or CTRL-R CTRL-P r */
+		    AppendCharToRedobuff(Ctrl_R);
+		    AppendCharToRedobuff(fixindent ? Ctrl_P : Ctrl_O);
+		    AppendCharToRedobuff(regname == 0 ? '"' : regname);
+		}
+	    }
+	    return FALSE;
+	}
+    }
+
+    /* When dragging or button-up stay in the same window. */
+    if (!is_click)
+	jump_flags |= MOUSE_FOCUS | MOUSE_DID_MOVE;
+
+    start_visual.lnum = 0;
+
+#ifdef FEAT_WINDOWS
+    /* Check for clicking in the tab page line. */
+    if (mouse_row == 0 && firstwin->w_winrow > 0)
+    {
+	got_click = FALSE;	/* ignore mouse-up and drag events */
+
+	/* click in a tab selects that tab page */
+	if (is_click
+# ifdef FEAT_CMDWIN
+		&& cmdwin_type == 0
+# endif
+		&& mouse_col < Columns)
+	{
+	    c1 = TabPageIdxs[mouse_col];
+	    if (c1 >= 0)
+	    {
+		if ((mod_mask & MOD_MASK_MULTI_CLICK) == MOD_MASK_2CLICK)
+		{
+		    /* double click opens new page */
+		    end_visual_mode();
+		    tabpage_new();
+		    tabpage_move(c1 == 0 ? 9999 : c1 - 1);
+		}
+		else
+		{
+		    /* Go to specified tab page, or next one if not clicking
+		     * on a label. */
+		    goto_tabpage(c1);
+
+		    /* It's like clicking on the status line of a window. */
+		    if (curwin != old_curwin)
+			end_visual_mode();
+		}
+	    }
+	    else if (c1 < 0)
+	    {
+		tabpage_T	*tp;
+
+		/* Close the current or specified tab page. */
+		if (c1 == -999)
+		    tp = curtab;
+		else
+		    tp = find_tabpage(-c1);
+		if (tp == curtab)
+		{
+		    if (first_tabpage->tp_next != NULL)
+			tabpage_close(FALSE);
+		}
+		else if (tp != NULL)
+		    tabpage_close_other(tp, FALSE);
+	    }
+	}
+	return TRUE;
+    }
+#endif
+
+    /*
+     * When 'mousemodel' is "popup" or "popup_setpos", translate mouse events:
+     * right button up   -> pop-up menu
+     * shift-left button -> right button
+     * alt-left button   -> alt-right button
+     */
+    if (mouse_model_popup())
+    {
+	if (which_button == MOUSE_RIGHT
+			    && !(mod_mask & (MOD_MASK_SHIFT | MOD_MASK_CTRL)))
+	{
+	    /*
+	     * NOTE: Ignore right button down and drag mouse events.
+	     * Windows only shows the popup menu on the button up event.
+	     */
+#if defined(FEAT_GUI_MOTIF) || defined(FEAT_GUI_GTK) \
+			  || defined(FEAT_GUI_PHOTON) || defined(FEAT_GUI_MAC)
+	    if (!is_click)
+		return FALSE;
+#endif
+#if defined(FEAT_GUI_ATHENA) || defined(FEAT_GUI_MSWIN)
+	    if (is_click || is_drag)
+		return FALSE;
+#endif
+#if defined(FEAT_GUI_MOTIF) || defined(FEAT_GUI_GTK) \
+	    || defined(FEAT_GUI_ATHENA) || defined(FEAT_GUI_MSWIN) \
+	    || defined(FEAT_GUI_MAC) || defined(FEAT_GUI_PHOTON)
+	    if (gui.in_use)
+	    {
+		jump_flags = 0;
+		if (STRCMP(p_mousem, "popup_setpos") == 0)
+		{
+		    /* First set the cursor position before showing the popup
+		     * menu. */
+#ifdef FEAT_VISUAL
+		    if (VIsual_active)
+		    {
+			pos_T    m_pos;
+
+			/*
+			 * set MOUSE_MAY_STOP_VIS if we are outside the
+			 * selection or the current window (might have false
+			 * negative here)
+			 */
+			if (mouse_row < W_WINROW(curwin)
+			     || mouse_row
+				      > (W_WINROW(curwin) + curwin->w_height))
+			    jump_flags = MOUSE_MAY_STOP_VIS;
+			else if (get_fpos_of_mouse(&m_pos) != IN_BUFFER)
+			    jump_flags = MOUSE_MAY_STOP_VIS;
+			else
+			{
+			    if ((lt(curwin->w_cursor, VIsual)
+					&& (lt(m_pos, curwin->w_cursor)
+					    || lt(VIsual, m_pos)))
+				    || (lt(VIsual, curwin->w_cursor)
+					&& (lt(m_pos, VIsual)
+					    || lt(curwin->w_cursor, m_pos))))
+			    {
+				jump_flags = MOUSE_MAY_STOP_VIS;
+			    }
+			    else if (VIsual_mode == Ctrl_V)
+			    {
+				getvcols(curwin, &curwin->w_cursor, &VIsual,
+							 &leftcol, &rightcol);
+				getvcol(curwin, &m_pos, NULL, &m_pos.col, NULL);
+				if (m_pos.col < leftcol || m_pos.col > rightcol)
+				    jump_flags = MOUSE_MAY_STOP_VIS;
+			    }
+			}
+		    }
+		    else
+			jump_flags = MOUSE_MAY_STOP_VIS;
+#endif
+		}
+		if (jump_flags)
+		{
+		    jump_flags = jump_to_mouse(jump_flags, NULL, which_button);
+		    update_curbuf(
+#ifdef FEAT_VISUAL
+			    VIsual_active ? INVERTED :
+#endif
+			    VALID);
+		    setcursor();
+		    out_flush();    /* Update before showing popup menu */
+		}
+# ifdef FEAT_MENU
+		gui_show_popupmenu();
+# endif
+		return (jump_flags & CURSOR_MOVED) != 0;
+	    }
+	    else
+		return FALSE;
+#else
+	    return FALSE;
+#endif
+	}
+	if (which_button == MOUSE_LEFT
+				&& (mod_mask & (MOD_MASK_SHIFT|MOD_MASK_ALT)))
+	{
+	    which_button = MOUSE_RIGHT;
+	    mod_mask &= ~MOD_MASK_SHIFT;
+	}
+    }
+
+#ifdef FEAT_VISUAL
+    if ((State & (NORMAL | INSERT))
+			    && !(mod_mask & (MOD_MASK_SHIFT | MOD_MASK_CTRL)))
+    {
+	if (which_button == MOUSE_LEFT)
+	{
+	    if (is_click)
+	    {
+		/* stop Visual mode for a left click in a window, but not when
+		 * on a status line */
+		if (VIsual_active)
+		    jump_flags |= MOUSE_MAY_STOP_VIS;
+	    }
+	    else if (mouse_has(MOUSE_VISUAL))
+		jump_flags |= MOUSE_MAY_VIS;
+	}
+	else if (which_button == MOUSE_RIGHT)
+	{
+	    if (is_click && VIsual_active)
+	    {
+		/*
+		 * Remember the start and end of visual before moving the
+		 * cursor.
+		 */
+		if (lt(curwin->w_cursor, VIsual))
+		{
+		    start_visual = curwin->w_cursor;
+		    end_visual = VIsual;
+		}
+		else
+		{
+		    start_visual = VIsual;
+		    end_visual = curwin->w_cursor;
+		}
+	    }
+	    jump_flags |= MOUSE_FOCUS;
+	    if (mouse_has(MOUSE_VISUAL))
+		jump_flags |= MOUSE_MAY_VIS;
+	}
+    }
+#endif
+
+    /*
+     * If an operator is pending, ignore all drags and releases until the
+     * next mouse click.
+     */
+    if (!is_drag && oap != NULL && oap->op_type != OP_NOP)
+    {
+	got_click = FALSE;
+	oap->motion_type = MCHAR;
+    }
+
+    /* When releasing the button let jump_to_mouse() know. */
+    if (!is_click && !is_drag)
+	jump_flags |= MOUSE_RELEASED;
+
+    /*
+     * JUMP!
+     */
+    jump_flags = jump_to_mouse(jump_flags,
+			oap == NULL ? NULL : &(oap->inclusive), which_button);
+    moved = (jump_flags & CURSOR_MOVED);
+    in_status_line = (jump_flags & IN_STATUS_LINE);
+#ifdef FEAT_VERTSPLIT
+    in_sep_line = (jump_flags & IN_SEP_LINE);
+#endif
+
+#ifdef FEAT_NETBEANS_INTG
+    if (usingNetbeans && isNetbeansBuffer(curbuf)
+			    && !(jump_flags & (IN_STATUS_LINE | IN_SEP_LINE)))
+    {
+	int key = KEY2TERMCAP1(c);
+
+	if (key == (int)KE_LEFTRELEASE || key == (int)KE_MIDDLERELEASE
+					       || key == (int)KE_RIGHTRELEASE)
+	    netbeans_button_release(which_button);
+    }
+#endif
+
+    /* When jumping to another window, clear a pending operator.  That's a bit
+     * friendlier than beeping and not jumping to that window. */
+    if (curwin != old_curwin && oap != NULL && oap->op_type != OP_NOP)
+	clearop(oap);
+
+#ifdef FEAT_FOLDING
+    if (mod_mask == 0
+	    && !is_drag
+	    && (jump_flags & (MOUSE_FOLD_CLOSE | MOUSE_FOLD_OPEN))
+	    && which_button == MOUSE_LEFT)
+    {
+	/* open or close a fold at this line */
+	if (jump_flags & MOUSE_FOLD_OPEN)
+	    openFold(curwin->w_cursor.lnum, 1L);
+	else
+	    closeFold(curwin->w_cursor.lnum, 1L);
+	/* don't move the cursor if still in the same window */
+	if (curwin == old_curwin)
+	    curwin->w_cursor = save_cursor;
+    }
+#endif
+
+#if defined(FEAT_CLIPBOARD) && defined(FEAT_CMDWIN)
+    if ((jump_flags & IN_OTHER_WIN) && !VIsual_active && clip_star.available)
+    {
+	clip_modeless(which_button, is_click, is_drag);
+	return FALSE;
+    }
+#endif
+
+#ifdef FEAT_VISUAL
+    /* Set global flag that we are extending the Visual area with mouse
+     * dragging; temporarily minimize 'scrolloff'. */
+    if (VIsual_active && is_drag && p_so)
+    {
+	/* In the very first line, allow scrolling one line */
+	if (mouse_row == 0)
+	    mouse_dragging = 2;
+	else
+	    mouse_dragging = 1;
+    }
+
+    /* When dragging the mouse above the window, scroll down. */
+    if (is_drag && mouse_row < 0 && !in_status_line)
+    {
+	scroll_redraw(FALSE, 1L);
+	mouse_row = 0;
+    }
+
+    if (start_visual.lnum)		/* right click in visual mode */
+    {
+       /* When ALT is pressed make Visual mode blockwise. */
+       if (mod_mask & MOD_MASK_ALT)
+	   VIsual_mode = Ctrl_V;
+
+	/*
+	 * In Visual-block mode, divide the area in four, pick up the corner
+	 * that is in the quarter that the cursor is in.
+	 */
+	if (VIsual_mode == Ctrl_V)
+	{
+	    getvcols(curwin, &start_visual, &end_visual, &leftcol, &rightcol);
+	    if (curwin->w_curswant > (leftcol + rightcol) / 2)
+		end_visual.col = leftcol;
+	    else
+		end_visual.col = rightcol;
+	    if (curwin->w_cursor.lnum <
+				    (start_visual.lnum + end_visual.lnum) / 2)
+		end_visual.lnum = end_visual.lnum;
+	    else
+		end_visual.lnum = start_visual.lnum;
+
+	    /* move VIsual to the right column */
+	    start_visual = curwin->w_cursor;	    /* save the cursor pos */
+	    curwin->w_cursor = end_visual;
+	    coladvance(end_visual.col);
+	    VIsual = curwin->w_cursor;
+	    curwin->w_cursor = start_visual;	    /* restore the cursor */
+	}
+	else
+	{
+	    /*
+	     * If the click is before the start of visual, change the start.
+	     * If the click is after the end of visual, change the end.  If
+	     * the click is inside the visual, change the closest side.
+	     */
+	    if (lt(curwin->w_cursor, start_visual))
+		VIsual = end_visual;
+	    else if (lt(end_visual, curwin->w_cursor))
+		VIsual = start_visual;
+	    else
+	    {
+		/* In the same line, compare column number */
+		if (end_visual.lnum == start_visual.lnum)
+		{
+		    if (curwin->w_cursor.col - start_visual.col >
+				    end_visual.col - curwin->w_cursor.col)
+			VIsual = start_visual;
+		    else
+			VIsual = end_visual;
+		}
+
+		/* In different lines, compare line number */
+		else
+		{
+		    diff = (curwin->w_cursor.lnum - start_visual.lnum) -
+				(end_visual.lnum - curwin->w_cursor.lnum);
+
+		    if (diff > 0)		/* closest to end */
+			VIsual = start_visual;
+		    else if (diff < 0)	/* closest to start */
+			VIsual = end_visual;
+		    else			/* in the middle line */
+		    {
+			if (curwin->w_cursor.col <
+					(start_visual.col + end_visual.col) / 2)
+			    VIsual = end_visual;
+			else
+			    VIsual = start_visual;
+		    }
+		}
+	    }
+	}
+    }
+    /*
+     * If Visual mode started in insert mode, execute "CTRL-O"
+     */
+    else if ((State & INSERT) && VIsual_active)
+	stuffcharReadbuff(Ctrl_O);
+#endif
+
+    /*
+     * Middle mouse click: Put text before cursor.
+     */
+    if (which_button == MOUSE_MIDDLE)
+    {
+#ifdef FEAT_CLIPBOARD
+	if (clip_star.available && regname == 0)
+	    regname = '*';
+#endif
+	if (yank_register_mline(regname))
+	{
+	    if (mouse_past_bottom)
+		dir = FORWARD;
+	}
+	else if (mouse_past_eol)
+	    dir = FORWARD;
+
+	if (fixindent)
+	{
+	    c1 = (dir == BACKWARD) ? '[' : ']';
+	    c2 = 'p';
+	}
+	else
+	{
+	    c1 = (dir == FORWARD) ? 'p' : 'P';
+	    c2 = NUL;
+	}
+	prep_redo(regname, count, NUL, c1, NUL, c2, NUL);
+
+	/*
+	 * Remember where the paste started, so in edit() Insstart can be set
+	 * to this position
+	 */
+	if (restart_edit != 0)
+	    where_paste_started = curwin->w_cursor;
+	do_put(regname, dir, count, fixindent | PUT_CURSEND);
+    }
+
+#if defined(FEAT_WINDOWS) && defined(FEAT_QUICKFIX)
+    /*
+     * Ctrl-Mouse click or double click in a quickfix window jumps to the
+     * error under the mouse pointer.
+     */
+    else if (((mod_mask & MOD_MASK_CTRL)
+		|| (mod_mask & MOD_MASK_MULTI_CLICK) == MOD_MASK_2CLICK)
+	    && bt_quickfix(curbuf))
+    {
+	if (State & INSERT)
+	    stuffcharReadbuff(Ctrl_O);
+	if (curwin->w_llist_ref == NULL)	/* quickfix window */
+	    stuffReadbuff((char_u *)":.cc\n");
+	else					/* location list window */
+	    stuffReadbuff((char_u *)":.ll\n");
+	got_click = FALSE;		/* ignore drag&release now */
+    }
+#endif
+
+    /*
+     * Ctrl-Mouse click (or double click in a help window) jumps to the tag
+     * under the mouse pointer.
+     */
+    else if ((mod_mask & MOD_MASK_CTRL) || (curbuf->b_help
+		     && (mod_mask & MOD_MASK_MULTI_CLICK) == MOD_MASK_2CLICK))
+    {
+	if (State & INSERT)
+	    stuffcharReadbuff(Ctrl_O);
+	stuffcharReadbuff(Ctrl_RSB);
+	got_click = FALSE;		/* ignore drag&release now */
+    }
+
+    /*
+     * Shift-Mouse click searches for the next occurrence of the word under
+     * the mouse pointer
+     */
+    else if ((mod_mask & MOD_MASK_SHIFT))
+    {
+	if (State & INSERT
+#ifdef FEAT_VISUAL
+		|| (VIsual_active && VIsual_select)
+#endif
+		)
+	    stuffcharReadbuff(Ctrl_O);
+	if (which_button == MOUSE_LEFT)
+	    stuffcharReadbuff('*');
+	else	/* MOUSE_RIGHT */
+	    stuffcharReadbuff('#');
+    }
+
+    /* Handle double clicks, unless on status line */
+    else if (in_status_line)
+    {
+#ifdef FEAT_MOUSESHAPE
+	if ((is_drag || is_click) && !drag_status_line)
+	{
+	    drag_status_line = TRUE;
+	    update_mouseshape(-1);
+	}
+#endif
+    }
+#ifdef FEAT_VERTSPLIT
+    else if (in_sep_line)
+    {
+# ifdef FEAT_MOUSESHAPE
+	if ((is_drag || is_click) && !drag_sep_line)
+	{
+	    drag_sep_line = TRUE;
+	    update_mouseshape(-1);
+	}
+# endif
+    }
+#endif
+#ifdef FEAT_VISUAL
+    else if ((mod_mask & MOD_MASK_MULTI_CLICK) && (State & (NORMAL | INSERT))
+	     && mouse_has(MOUSE_VISUAL))
+    {
+	if (is_click || !VIsual_active)
+	{
+	    if (VIsual_active)
+		orig_cursor = VIsual;
+	    else
+	    {
+		check_visual_highlight();
+		VIsual = curwin->w_cursor;
+		orig_cursor = VIsual;
+		VIsual_active = TRUE;
+		VIsual_reselect = TRUE;
+		/* start Select mode if 'selectmode' contains "mouse" */
+		may_start_select('o');
+		setmouse();
+	    }
+	    if ((mod_mask & MOD_MASK_MULTI_CLICK) == MOD_MASK_2CLICK)
+	    {
+		/* Double click with ALT pressed makes it blockwise. */
+		if (mod_mask & MOD_MASK_ALT)
+		    VIsual_mode = Ctrl_V;
+		else
+		    VIsual_mode = 'v';
+	    }
+	    else if ((mod_mask & MOD_MASK_MULTI_CLICK) == MOD_MASK_3CLICK)
+		VIsual_mode = 'V';
+	    else if ((mod_mask & MOD_MASK_MULTI_CLICK) == MOD_MASK_4CLICK)
+		VIsual_mode = Ctrl_V;
+#ifdef FEAT_CLIPBOARD
+	    /* Make sure the clipboard gets updated.  Needed because start and
+	     * end may still be the same, and the selection needs to be owned */
+	    clip_star.vmode = NUL;
+#endif
+	}
+	/*
+	 * A double click selects a word or a block.
+	 */
+	if ((mod_mask & MOD_MASK_MULTI_CLICK) == MOD_MASK_2CLICK)
+	{
+	    pos_T	*pos = NULL;
+	    int		gc;
+
+	    if (is_click)
+	    {
+		/* If the character under the cursor (skipping white space) is
+		 * not a word character, try finding a match and select a (),
+		 * {}, [], #if/#endif, etc. block. */
+		end_visual = curwin->w_cursor;
+		while (gc = gchar_pos(&end_visual), vim_iswhite(gc))
+		    inc(&end_visual);
+		if (oap != NULL)
+		    oap->motion_type = MCHAR;
+		if (oap != NULL
+			&& VIsual_mode == 'v'
+			&& !vim_iswordc(gchar_pos(&end_visual))
+			&& equalpos(curwin->w_cursor, VIsual)
+			&& (pos = findmatch(oap, NUL)) != NULL)
+		{
+		    curwin->w_cursor = *pos;
+		    if (oap->motion_type == MLINE)
+			VIsual_mode = 'V';
+		    else if (*p_sel == 'e')
+		    {
+			if (lt(curwin->w_cursor, VIsual))
+			    ++VIsual.col;
+			else
+			    ++curwin->w_cursor.col;
+		    }
+		}
+	    }
+
+	    if (pos == NULL && (is_click || is_drag))
+	    {
+		/* When not found a match or when dragging: extend to include
+		 * a word. */
+		if (lt(curwin->w_cursor, orig_cursor))
+		{
+		    find_start_of_word(&curwin->w_cursor);
+		    find_end_of_word(&VIsual);
+		}
+		else
+		{
+		    find_start_of_word(&VIsual);
+		    if (*p_sel == 'e' && *ml_get_cursor() != NUL)
+#ifdef FEAT_MBYTE
+			curwin->w_cursor.col +=
+					 (*mb_ptr2len)(ml_get_cursor());
+#else
+			++curwin->w_cursor.col;
+#endif
+		    find_end_of_word(&curwin->w_cursor);
+		}
+	    }
+	    curwin->w_set_curswant = TRUE;
+	}
+	if (is_click)
+	    redraw_curbuf_later(INVERTED);	/* update the inversion */
+    }
+    else if (VIsual_active && !old_active)
+    {
+	if (mod_mask & MOD_MASK_ALT)
+	    VIsual_mode = Ctrl_V;
+	else
+	    VIsual_mode = 'v';
+    }
+
+    /* If Visual mode changed show it later. */
+    if ((!VIsual_active && old_active && mode_displayed)
+	    || (VIsual_active && p_smd && msg_silent == 0
+				 && (!old_active || VIsual_mode != old_mode)))
+	redraw_cmdline = TRUE;
+#endif
+
+    return moved;
+}
+
+#ifdef FEAT_VISUAL
+/*
+ * Move "pos" back to the start of the word it's in.
+ */
+    static void
+find_start_of_word(pos)
+    pos_T	*pos;
+{
+    char_u	*line;
+    int		cclass;
+    int		col;
+
+    line = ml_get(pos->lnum);
+    cclass = get_mouse_class(line + pos->col);
+
+    while (pos->col > 0)
+    {
+	col = pos->col - 1;
+#ifdef FEAT_MBYTE
+	col -= (*mb_head_off)(line, line + col);
+#endif
+	if (get_mouse_class(line + col) != cclass)
+	    break;
+	pos->col = col;
+    }
+}
+
+/*
+ * Move "pos" forward to the end of the word it's in.
+ * When 'selection' is "exclusive", the position is just after the word.
+ */
+    static void
+find_end_of_word(pos)
+    pos_T	*pos;
+{
+    char_u	*line;
+    int		cclass;
+    int		col;
+
+    line = ml_get(pos->lnum);
+    if (*p_sel == 'e' && pos->col > 0)
+    {
+	--pos->col;
+#ifdef FEAT_MBYTE
+	pos->col -= (*mb_head_off)(line, line + pos->col);
+#endif
+    }
+    cclass = get_mouse_class(line + pos->col);
+    while (line[pos->col] != NUL)
+    {
+#ifdef FEAT_MBYTE
+	col = pos->col + (*mb_ptr2len)(line + pos->col);
+#else
+	col = pos->col + 1;
+#endif
+	if (get_mouse_class(line + col) != cclass)
+	{
+	    if (*p_sel == 'e')
+		pos->col = col;
+	    break;
+	}
+	pos->col = col;
+    }
+}
+
+/*
+ * Get class of a character for selection: same class means same word.
+ * 0: blank
+ * 1: punctuation groups
+ * 2: normal word character
+ * >2: multi-byte word character.
+ */
+    static int
+get_mouse_class(p)
+    char_u	*p;
+{
+    int		c;
+
+#ifdef FEAT_MBYTE
+    if (has_mbyte && MB_BYTE2LEN(p[0]) > 1)
+	return mb_get_class(p);
+#endif
+
+    c = *p;
+    if (c == ' ' || c == '\t')
+	return 0;
+
+    if (vim_iswordc(c))
+	return 2;
+
+    /*
+     * There are a few special cases where we want certain combinations of
+     * characters to be considered as a single word.  These are things like
+     * "->", "/ *", "*=", "+=", "&=", "<=", ">=", "!=" etc.  Otherwise, each
+     * character is in it's own class.
+     */
+    if (c != NUL && vim_strchr((char_u *)"-+*/%<>&|^!=", c) != NULL)
+	return 1;
+    return c;
+}
+#endif /* FEAT_VISUAL */
+#endif /* FEAT_MOUSE */
+
+#if defined(FEAT_VISUAL) || defined(PROTO)
+/*
+ * Check if  highlighting for visual mode is possible, give a warning message
+ * if not.
+ */
+    void
+check_visual_highlight()
+{
+    static int	    did_check = FALSE;
+
+    if (full_screen)
+    {
+	if (!did_check && hl_attr(HLF_V) == 0)
+	    MSG(_("Warning: terminal cannot highlight"));
+	did_check = TRUE;
+    }
+}
+
+/*
+ * End Visual mode.
+ * This function should ALWAYS be called to end Visual mode, except from
+ * do_pending_operator().
+ */
+    void
+end_visual_mode()
+{
+#ifdef FEAT_CLIPBOARD
+    /*
+     * If we are using the clipboard, then remember what was selected in case
+     * we need to paste it somewhere while we still own the selection.
+     * Only do this when the clipboard is already owned.  Don't want to grab
+     * the selection when hitting ESC.
+     */
+    if (clip_star.available && clip_star.owned)
+	clip_auto_select();
+#endif
+
+    VIsual_active = FALSE;
+#ifdef FEAT_MOUSE
+    setmouse();
+    mouse_dragging = 0;
+#endif
+
+    /* Save the current VIsual area for '< and '> marks, and "gv" */
+    curbuf->b_visual.vi_mode = VIsual_mode;
+    curbuf->b_visual.vi_start = VIsual;
+    curbuf->b_visual.vi_end = curwin->w_cursor;
+    curbuf->b_visual.vi_curswant = curwin->w_curswant;
+#ifdef FEAT_EVAL
+    curbuf->b_visual_mode_eval = VIsual_mode;
+#endif
+#ifdef FEAT_VIRTUALEDIT
+    if (!virtual_active())
+	curwin->w_cursor.coladd = 0;
+#endif
+
+    if (mode_displayed)
+	clear_cmdline = TRUE;		/* unshow visual mode later */
+#ifdef FEAT_CMDL_INFO
+    else
+	clear_showcmd();
+#endif
+
+    adjust_cursor_eol();
+}
+
+/*
+ * Reset VIsual_active and VIsual_reselect.
+ */
+    void
+reset_VIsual_and_resel()
+{
+    if (VIsual_active)
+    {
+	end_visual_mode();
+	redraw_curbuf_later(INVERTED);	/* delete the inversion later */
+    }
+    VIsual_reselect = FALSE;
+}
+
+/*
+ * Reset VIsual_active and VIsual_reselect if it's set.
+ */
+    void
+reset_VIsual()
+{
+    if (VIsual_active)
+    {
+	end_visual_mode();
+	redraw_curbuf_later(INVERTED);	/* delete the inversion later */
+	VIsual_reselect = FALSE;
+    }
+}
+#endif /* FEAT_VISUAL */
+
+#if defined(FEAT_BEVAL)
+static int find_is_eval_item __ARGS((char_u *ptr, int *colp, int *nbp, int dir));
+
+/*
+ * Check for a balloon-eval special item to include when searching for an
+ * identifier.  When "dir" is BACKWARD "ptr[-1]" must be valid!
+ * Returns TRUE if the character at "*ptr" should be included.
+ * "dir" is FORWARD or BACKWARD, the direction of searching.
+ * "*colp" is in/decremented if "ptr[-dir]" should also be included.
+ * "bnp" points to a counter for square brackets.
+ */
+    static int
+find_is_eval_item(ptr, colp, bnp, dir)
+    char_u	*ptr;
+    int		*colp;
+    int		*bnp;
+    int		dir;
+{
+    /* Accept everything inside []. */
+    if ((*ptr == ']' && dir == BACKWARD) || (*ptr == '[' && dir == FORWARD))
+	++*bnp;
+    if (*bnp > 0)
+    {
+	if ((*ptr == '[' && dir == BACKWARD) || (*ptr == ']' && dir == FORWARD))
+	    --*bnp;
+	return TRUE;
+    }
+
+    /* skip over "s.var" */
+    if (*ptr == '.')
+	return TRUE;
+
+    /* two-character item: s->var */
+    if (ptr[dir == BACKWARD ? 0 : 1] == '>'
+	    && ptr[dir == BACKWARD ? -1 : 0] == '-')
+    {
+	*colp += dir;
+	return TRUE;
+    }
+    return FALSE;
+}
+#endif
+
+/*
+ * Find the identifier under or to the right of the cursor.
+ * "find_type" can have one of three values:
+ * FIND_IDENT:   find an identifier (keyword)
+ * FIND_STRING:  find any non-white string
+ * FIND_IDENT + FIND_STRING: find any non-white string, identifier preferred.
+ * FIND_EVAL:	 find text useful for C program debugging
+ *
+ * There are three steps:
+ * 1. Search forward for the start of an identifier/string.  Doesn't move if
+ *    already on one.
+ * 2. Search backward for the start of this identifier/string.
+ *    This doesn't match the real Vi but I like it a little better and it
+ *    shouldn't bother anyone.
+ * 3. Search forward to the end of this identifier/string.
+ *    When FIND_IDENT isn't defined, we backup until a blank.
+ *
+ * Returns the length of the string, or zero if no string is found.
+ * If a string is found, a pointer to the string is put in "*string".  This
+ * string is not always NUL terminated.
+ */
+    int
+find_ident_under_cursor(string, find_type)
+    char_u	**string;
+    int		find_type;
+{
+    return find_ident_at_pos(curwin, curwin->w_cursor.lnum,
+				     curwin->w_cursor.col, string, find_type);
+}
+
+/*
+ * Like find_ident_under_cursor(), but for any window and any position.
+ * However: Uses 'iskeyword' from the current window!.
+ */
+    int
+find_ident_at_pos(wp, lnum, startcol, string, find_type)
+    win_T	*wp;
+    linenr_T	lnum;
+    colnr_T	startcol;
+    char_u	**string;
+    int		find_type;
+{
+    char_u	*ptr;
+    int		col = 0;	    /* init to shut up GCC */
+    int		i;
+#ifdef FEAT_MBYTE
+    int		this_class = 0;
+    int		prev_class;
+    int		prevcol;
+#endif
+#if defined(FEAT_BEVAL)
+    int		bn = 0;	    /* bracket nesting */
+#endif
+
+    /*
+     * if i == 0: try to find an identifier
+     * if i == 1: try to find any non-white string
+     */
+    ptr = ml_get_buf(wp->w_buffer, lnum, FALSE);
+    for (i = (find_type & FIND_IDENT) ? 0 : 1;	i < 2; ++i)
+    {
+	/*
+	 * 1. skip to start of identifier/string
+	 */
+	col = startcol;
+#ifdef FEAT_MBYTE
+	if (has_mbyte)
+	{
+	    while (ptr[col] != NUL)
+	    {
+# if defined(FEAT_BEVAL)
+		/* Stop at a ']' to evaluate "a[x]". */
+		if ((find_type & FIND_EVAL) && ptr[col] == ']')
+		    break;
+# endif
+		this_class = mb_get_class(ptr + col);
+		if (this_class != 0 && (i == 1 || this_class != 1))
+		    break;
+		col += (*mb_ptr2len)(ptr + col);
+	    }
+	}
+	else
+#endif
+	    while (ptr[col] != NUL
+		    && (i == 0 ? !vim_iswordc(ptr[col]) : vim_iswhite(ptr[col]))
+# if defined(FEAT_BEVAL)
+		    && (!(find_type & FIND_EVAL) || ptr[col] != ']')
+# endif
+		    )
+		++col;
+
+#if defined(FEAT_BEVAL)
+	/* When starting on a ']' count it, so that we include the '['. */
+	bn = ptr[col] == ']';
+#endif
+
+	/*
+	 * 2. Back up to start of identifier/string.
+	 */
+#ifdef FEAT_MBYTE
+	if (has_mbyte)
+	{
+	    /* Remember class of character under cursor. */
+# if defined(FEAT_BEVAL)
+	    if ((find_type & FIND_EVAL) && ptr[col] == ']')
+		this_class = mb_get_class((char_u *)"a");
+	    else
+# endif
+		this_class = mb_get_class(ptr + col);
+	    while (col > 0 && this_class != 0)
+	    {
+		prevcol = col - 1 - (*mb_head_off)(ptr, ptr + col - 1);
+		prev_class = mb_get_class(ptr + prevcol);
+		if (this_class != prev_class
+			&& (i == 0
+			    || prev_class == 0
+			    || (find_type & FIND_IDENT))
+# if defined(FEAT_BEVAL)
+			&& (!(find_type & FIND_EVAL)
+			    || prevcol == 0
+			    || !find_is_eval_item(ptr + prevcol, &prevcol,
+							       &bn, BACKWARD))
+# endif
+			)
+		    break;
+		col = prevcol;
+	    }
+
+	    /* If we don't want just any old string, or we've found an
+	     * identifier, stop searching. */
+	    if (this_class > 2)
+		this_class = 2;
+	    if (!(find_type & FIND_STRING) || this_class == 2)
+		break;
+	}
+	else
+#endif
+	{
+	    while (col > 0
+		    && ((i == 0
+			    ? vim_iswordc(ptr[col - 1])
+			    : (!vim_iswhite(ptr[col - 1])
+				&& (!(find_type & FIND_IDENT)
+				    || !vim_iswordc(ptr[col - 1]))))
+#if defined(FEAT_BEVAL)
+			|| ((find_type & FIND_EVAL)
+			    && col > 1
+			    && find_is_eval_item(ptr + col - 1, &col,
+							       &bn, BACKWARD))
+#endif
+			))
+		--col;
+
+	    /* If we don't want just any old string, or we've found an
+	     * identifier, stop searching. */
+	    if (!(find_type & FIND_STRING) || vim_iswordc(ptr[col]))
+		break;
+	}
+    }
+
+    if (ptr[col] == NUL || (i == 0 && (
+#ifdef FEAT_MBYTE
+		has_mbyte ? this_class != 2 :
+#endif
+		!vim_iswordc(ptr[col]))))
+    {
+	/*
+	 * didn't find an identifier or string
+	 */
+	if (find_type & FIND_STRING)
+	    EMSG(_("E348: No string under cursor"));
+	else
+	    EMSG(_("E349: No identifier under cursor"));
+	return 0;
+    }
+    ptr += col;
+    *string = ptr;
+
+    /*
+     * 3. Find the end if the identifier/string.
+     */
+#if defined(FEAT_BEVAL)
+    bn = 0;
+    startcol -= col;
+#endif
+    col = 0;
+#ifdef FEAT_MBYTE
+    if (has_mbyte)
+    {
+	/* Search for point of changing multibyte character class. */
+	this_class = mb_get_class(ptr);
+	while (ptr[col] != NUL
+		&& ((i == 0 ? mb_get_class(ptr + col) == this_class
+			    : mb_get_class(ptr + col) != 0)
+# if defined(FEAT_BEVAL)
+		    || ((find_type & FIND_EVAL)
+			&& col <= (int)startcol
+			&& find_is_eval_item(ptr + col, &col, &bn, FORWARD))
+# endif
+		))
+	    col += (*mb_ptr2len)(ptr + col);
+    }
+    else
+#endif
+	while ((i == 0 ? vim_iswordc(ptr[col])
+		       : (ptr[col] != NUL && !vim_iswhite(ptr[col])))
+# if defined(FEAT_BEVAL)
+		    || ((find_type & FIND_EVAL)
+			&& col <= (int)startcol
+			&& find_is_eval_item(ptr + col, &col, &bn, FORWARD))
+# endif
+		)
+	{
+	    ++col;
+	}
+
+    return col;
+}
+
+/*
+ * Prepare for redo of a normal command.
+ */
+    static void
+prep_redo_cmd(cap)
+    cmdarg_T  *cap;
+{
+    prep_redo(cap->oap->regname, cap->count0,
+				     NUL, cap->cmdchar, NUL, NUL, cap->nchar);
+}
+
+/*
+ * Prepare for redo of any command.
+ * Note that only the last argument can be a multi-byte char.
+ */
+    static void
+prep_redo(regname, num, cmd1, cmd2, cmd3, cmd4, cmd5)
+    int	    regname;
+    long    num;
+    int	    cmd1;
+    int	    cmd2;
+    int	    cmd3;
+    int	    cmd4;
+    int	    cmd5;
+{
+    ResetRedobuff();
+    if (regname != 0)	/* yank from specified buffer */
+    {
+	AppendCharToRedobuff('"');
+	AppendCharToRedobuff(regname);
+    }
+    if (num)
+	AppendNumberToRedobuff(num);
+
+    if (cmd1 != NUL)
+	AppendCharToRedobuff(cmd1);
+    if (cmd2 != NUL)
+	AppendCharToRedobuff(cmd2);
+    if (cmd3 != NUL)
+	AppendCharToRedobuff(cmd3);
+    if (cmd4 != NUL)
+	AppendCharToRedobuff(cmd4);
+    if (cmd5 != NUL)
+	AppendCharToRedobuff(cmd5);
+}
+
+/*
+ * check for operator active and clear it
+ *
+ * return TRUE if operator was active
+ */
+    static int
+checkclearop(oap)
+    oparg_T	*oap;
+{
+    if (oap->op_type == OP_NOP)
+	return FALSE;
+    clearopbeep(oap);
+    return TRUE;
+}
+
+/*
+ * Check for operator or Visual active.  Clear active operator.
+ *
+ * Return TRUE if operator or Visual was active.
+ */
+    static int
+checkclearopq(oap)
+    oparg_T	*oap;
+{
+    if (oap->op_type == OP_NOP
+#ifdef FEAT_VISUAL
+	    && !VIsual_active
+#endif
+	    )
+	return FALSE;
+    clearopbeep(oap);
+    return TRUE;
+}
+
+    static void
+clearop(oap)
+    oparg_T	*oap;
+{
+    oap->op_type = OP_NOP;
+    oap->regname = 0;
+    oap->motion_force = NUL;
+    oap->use_reg_one = FALSE;
+}
+
+    static void
+clearopbeep(oap)
+    oparg_T	*oap;
+{
+    clearop(oap);
+    beep_flush();
+}
+
+#ifdef FEAT_VISUAL
+/*
+ * Remove the shift modifier from a special key.
+ */
+    static void
+unshift_special(cap)
+    cmdarg_T	*cap;
+{
+    switch (cap->cmdchar)
+    {
+	case K_S_RIGHT:	cap->cmdchar = K_RIGHT; break;
+	case K_S_LEFT:	cap->cmdchar = K_LEFT; break;
+	case K_S_UP:	cap->cmdchar = K_UP; break;
+	case K_S_DOWN:	cap->cmdchar = K_DOWN; break;
+	case K_S_HOME:	cap->cmdchar = K_HOME; break;
+	case K_S_END:	cap->cmdchar = K_END; break;
+    }
+    cap->cmdchar = simplify_key(cap->cmdchar, &mod_mask);
+}
+#endif
+
+#if defined(FEAT_CMDL_INFO) || defined(PROTO)
+/*
+ * Routines for displaying a partly typed command
+ */
+
+#ifdef FEAT_VISUAL	/* need room for size of Visual area */
+# define SHOWCMD_BUFLEN SHOWCMD_COLS + 1 + 30
+#else
+# define SHOWCMD_BUFLEN SHOWCMD_COLS + 1
+#endif
+static char_u	showcmd_buf[SHOWCMD_BUFLEN];
+static char_u	old_showcmd_buf[SHOWCMD_BUFLEN];  /* For push_showcmd() */
+static int	showcmd_is_clear = TRUE;
+static int	showcmd_visual = FALSE;
+
+static void display_showcmd __ARGS((void));
+
+    void
+clear_showcmd()
+{
+    if (!p_sc)
+	return;
+
+#ifdef FEAT_VISUAL
+    if (VIsual_active && !char_avail())
+    {
+	int		i = lt(VIsual, curwin->w_cursor);
+	long		lines;
+	colnr_T		leftcol, rightcol;
+	linenr_T	top, bot;
+
+	/* Show the size of the Visual area. */
+	if (i)
+	{
+	    top = VIsual.lnum;
+	    bot = curwin->w_cursor.lnum;
+	}
+	else
+	{
+	    top = curwin->w_cursor.lnum;
+	    bot = VIsual.lnum;
+	}
+# ifdef FEAT_FOLDING
+	/* Include closed folds as a whole. */
+	hasFolding(top, &top, NULL);
+	hasFolding(bot, NULL, &bot);
+# endif
+	lines = bot - top + 1;
+
+	if (VIsual_mode == Ctrl_V)
+	{
+	    getvcols(curwin, &curwin->w_cursor, &VIsual, &leftcol, &rightcol);
+	    sprintf((char *)showcmd_buf, "%ldx%ld", lines,
+					      (long)(rightcol - leftcol + 1));
+	}
+	else if (VIsual_mode == 'V' || VIsual.lnum != curwin->w_cursor.lnum)
+	    sprintf((char *)showcmd_buf, "%ld", lines);
+	else
+	    sprintf((char *)showcmd_buf, "%ld", (long)(i
+		    ? curwin->w_cursor.col - VIsual.col
+		    : VIsual.col - curwin->w_cursor.col) + (*p_sel != 'e'));
+	showcmd_buf[SHOWCMD_COLS] = NUL;	/* truncate */
+	showcmd_visual = TRUE;
+    }
+    else
+#endif
+    {
+	showcmd_buf[0] = NUL;
+	showcmd_visual = FALSE;
+
+	/* Don't actually display something if there is nothing to clear. */
+	if (showcmd_is_clear)
+	    return;
+    }
+
+    display_showcmd();
+}
+
+/*
+ * Add 'c' to string of shown command chars.
+ * Return TRUE if output has been written (and setcursor() has been called).
+ */
+    int
+add_to_showcmd(c)
+    int		c;
+{
+    char_u	*p;
+    int		old_len;
+    int		extra_len;
+    int		overflow;
+#if defined(FEAT_MOUSE)
+    int		i;
+    static int	ignore[] =
+    {
+# ifdef FEAT_GUI
+	K_VER_SCROLLBAR, K_HOR_SCROLLBAR,
+	K_LEFTMOUSE_NM, K_LEFTRELEASE_NM,
+# endif
+	K_IGNORE,
+	K_LEFTMOUSE, K_LEFTDRAG, K_LEFTRELEASE,
+	K_MIDDLEMOUSE, K_MIDDLEDRAG, K_MIDDLERELEASE,
+	K_RIGHTMOUSE, K_RIGHTDRAG, K_RIGHTRELEASE,
+	K_MOUSEDOWN, K_MOUSEUP,
+	K_X1MOUSE, K_X1DRAG, K_X1RELEASE, K_X2MOUSE, K_X2DRAG, K_X2RELEASE,
+	K_CURSORHOLD,
+	0
+    };
+#endif
+
+    if (!p_sc || msg_silent != 0)
+	return FALSE;
+
+    if (showcmd_visual)
+    {
+	showcmd_buf[0] = NUL;
+	showcmd_visual = FALSE;
+    }
+
+#if defined(FEAT_MOUSE)
+    /* Ignore keys that are scrollbar updates and mouse clicks */
+    if (IS_SPECIAL(c))
+	for (i = 0; ignore[i] != 0; ++i)
+	    if (ignore[i] == c)
+		return FALSE;
+#endif
+
+    p = transchar(c);
+    old_len = (int)STRLEN(showcmd_buf);
+    extra_len = (int)STRLEN(p);
+    overflow = old_len + extra_len - SHOWCMD_COLS;
+    if (overflow > 0)
+	STRCPY(showcmd_buf, showcmd_buf + overflow);
+    STRCAT(showcmd_buf, p);
+
+    if (char_avail())
+	return FALSE;
+
+    display_showcmd();
+
+    return TRUE;
+}
+
+    void
+add_to_showcmd_c(c)
+    int		c;
+{
+    if (!add_to_showcmd(c))
+	setcursor();
+}
+
+/*
+ * Delete 'len' characters from the end of the shown command.
+ */
+    static void
+del_from_showcmd(len)
+    int	    len;
+{
+    int	    old_len;
+
+    if (!p_sc)
+	return;
+
+    old_len = (int)STRLEN(showcmd_buf);
+    if (len > old_len)
+	len = old_len;
+    showcmd_buf[old_len - len] = NUL;
+
+    if (!char_avail())
+	display_showcmd();
+}
+
+/*
+ * push_showcmd() and pop_showcmd() are used when waiting for the user to type
+ * something and there is a partial mapping.
+ */
+    void
+push_showcmd()
+{
+    if (p_sc)
+	STRCPY(old_showcmd_buf, showcmd_buf);
+}
+
+    void
+pop_showcmd()
+{
+    if (!p_sc)
+	return;
+
+    STRCPY(showcmd_buf, old_showcmd_buf);
+
+    display_showcmd();
+}
+
+    static void
+display_showcmd()
+{
+    int	    len;
+
+    cursor_off();
+
+    len = (int)STRLEN(showcmd_buf);
+    if (len == 0)
+	showcmd_is_clear = TRUE;
+    else
+    {
+	screen_puts(showcmd_buf, (int)Rows - 1, sc_col, 0);
+	showcmd_is_clear = FALSE;
+    }
+
+    /*
+     * clear the rest of an old message by outputting up to SHOWCMD_COLS
+     * spaces
+     */
+    screen_puts((char_u *)"          " + len, (int)Rows - 1, sc_col + len, 0);
+
+    setcursor();	    /* put cursor back where it belongs */
+}
+#endif
+
+#ifdef FEAT_SCROLLBIND
+/*
+ * When "check" is FALSE, prepare for commands that scroll the window.
+ * When "check" is TRUE, take care of scroll-binding after the window has
+ * scrolled.  Called from normal_cmd() and edit().
+ */
+    void
+do_check_scrollbind(check)
+    int		check;
+{
+    static win_T	*old_curwin = NULL;
+    static linenr_T	old_topline = 0;
+#ifdef FEAT_DIFF
+    static int		old_topfill = 0;
+#endif
+    static buf_T	*old_buf = NULL;
+    static colnr_T	old_leftcol = 0;
+
+    if (check && curwin->w_p_scb)
+    {
+	/* If a ":syncbind" command was just used, don't scroll, only reset
+	 * the values. */
+	if (did_syncbind)
+	    did_syncbind = FALSE;
+	else if (curwin == old_curwin)
+	{
+	    /*
+	     * Synchronize other windows, as necessary according to
+	     * 'scrollbind'.  Don't do this after an ":edit" command, except
+	     * when 'diff' is set.
+	     */
+	    if ((curwin->w_buffer == old_buf
+#ifdef FEAT_DIFF
+			|| curwin->w_p_diff
+#endif
+		)
+		&& (curwin->w_topline != old_topline
+#ifdef FEAT_DIFF
+			|| curwin->w_topfill != old_topfill
+#endif
+			|| curwin->w_leftcol != old_leftcol))
+	    {
+		check_scrollbind(curwin->w_topline - old_topline,
+			(long)(curwin->w_leftcol - old_leftcol));
+	    }
+	}
+	else if (vim_strchr(p_sbo, 'j')) /* jump flag set in 'scrollopt' */
+	{
+	    /*
+	     * When switching between windows, make sure that the relative
+	     * vertical offset is valid for the new window.  The relative
+	     * offset is invalid whenever another 'scrollbind' window has
+	     * scrolled to a point that would force the current window to
+	     * scroll past the beginning or end of its buffer.  When the
+	     * resync is performed, some of the other 'scrollbind' windows may
+	     * need to jump so that the current window's relative position is
+	     * visible on-screen.
+	     */
+	    check_scrollbind(curwin->w_topline - curwin->w_scbind_pos, 0L);
+	}
+	curwin->w_scbind_pos = curwin->w_topline;
+    }
+
+    old_curwin = curwin;
+    old_topline = curwin->w_topline;
+#ifdef FEAT_DIFF
+    old_topfill = curwin->w_topfill;
+#endif
+    old_buf = curwin->w_buffer;
+    old_leftcol = curwin->w_leftcol;
+}
+
+/*
+ * Synchronize any windows that have "scrollbind" set, based on the
+ * number of rows by which the current window has changed
+ * (1998-11-02 16:21:01  R. Edward Ralston <eralston@computer.org>)
+ */
+    void
+check_scrollbind(topline_diff, leftcol_diff)
+    linenr_T	topline_diff;
+    long	leftcol_diff;
+{
+    int		want_ver;
+    int		want_hor;
+    win_T	*old_curwin = curwin;
+    buf_T	*old_curbuf = curbuf;
+#ifdef FEAT_VISUAL
+    int		old_VIsual_select = VIsual_select;
+    int		old_VIsual_active = VIsual_active;
+#endif
+    colnr_T	tgt_leftcol = curwin->w_leftcol;
+    long	topline;
+    long	y;
+
+    /*
+     * check 'scrollopt' string for vertical and horizontal scroll options
+     */
+    want_ver = (vim_strchr(p_sbo, 'v') && topline_diff != 0);
+#ifdef FEAT_DIFF
+    want_ver |= old_curwin->w_p_diff;
+#endif
+    want_hor = (vim_strchr(p_sbo, 'h') && (leftcol_diff || topline_diff != 0));
+
+    /*
+     * loop through the scrollbound windows and scroll accordingly
+     */
+#ifdef FEAT_VISUAL
+    VIsual_select = VIsual_active = 0;
+#endif
+    for (curwin = firstwin; curwin; curwin = curwin->w_next)
+    {
+	curbuf = curwin->w_buffer;
+	/* skip original window  and windows with 'noscrollbind' */
+	if (curwin != old_curwin && curwin->w_p_scb)
+	{
+	    /*
+	     * do the vertical scroll
+	     */
+	    if (want_ver)
+	    {
+#ifdef FEAT_DIFF
+		if (old_curwin->w_p_diff && curwin->w_p_diff)
+		{
+		    diff_set_topline(old_curwin, curwin);
+		}
+		else
+#endif
+		{
+		    curwin->w_scbind_pos += topline_diff;
+		    topline = curwin->w_scbind_pos;
+		    if (topline > curbuf->b_ml.ml_line_count)
+			topline = curbuf->b_ml.ml_line_count;
+		    if (topline < 1)
+			topline = 1;
+
+		    y = topline - curwin->w_topline;
+		    if (y > 0)
+			scrollup(y, FALSE);
+		    else
+			scrolldown(-y, FALSE);
+		}
+
+		redraw_later(VALID);
+		cursor_correct();
+#ifdef FEAT_WINDOWS
+		curwin->w_redr_status = TRUE;
+#endif
+	    }
+
+	    /*
+	     * do the horizontal scroll
+	     */
+	    if (want_hor && curwin->w_leftcol != tgt_leftcol)
+	    {
+		curwin->w_leftcol = tgt_leftcol;
+		leftcol_changed();
+	    }
+	}
+    }
+
+    /*
+     * reset current-window
+     */
+#ifdef FEAT_VISUAL
+    VIsual_select = old_VIsual_select;
+    VIsual_active = old_VIsual_active;
+#endif
+    curwin = old_curwin;
+    curbuf = old_curbuf;
+}
+#endif /* #ifdef FEAT_SCROLLBIND */
+
+/*
+ * Command character that's ignored.
+ * Used for CTRL-Q and CTRL-S to avoid problems with terminals that use
+ * xon/xoff
+ */
+    static void
+nv_ignore(cap)
+    cmdarg_T	*cap;
+{
+    cap->retval |= CA_COMMAND_BUSY;	/* don't call edit() now */
+}
+
+/*
+ * Command character that doesn't do anything, but unlike nv_ignore() does
+ * start edit().  Used for "startinsert" executed while starting up.
+ */
+/*ARGSUSED */
+    static void
+nv_nop(cap)
+    cmdarg_T	*cap;
+{
+}
+
+/*
+ * Command character doesn't exist.
+ */
+    static void
+nv_error(cap)
+    cmdarg_T	*cap;
+{
+    clearopbeep(cap->oap);
+}
+
+/*
+ * <Help> and <F1> commands.
+ */
+    static void
+nv_help(cap)
+    cmdarg_T	*cap;
+{
+    if (!checkclearopq(cap->oap))
+	ex_help(NULL);
+}
+
+/*
+ * CTRL-A and CTRL-X: Add or subtract from letter or number under cursor.
+ */
+    static void
+nv_addsub(cap)
+    cmdarg_T	*cap;
+{
+    if (!checkclearopq(cap->oap)
+	    && do_addsub((int)cap->cmdchar, cap->count1) == OK)
+	prep_redo_cmd(cap);
+}
+
+/*
+ * CTRL-F, CTRL-B, etc: Scroll page up or down.
+ */
+    static void
+nv_page(cap)
+    cmdarg_T	*cap;
+{
+    if (!checkclearop(cap->oap))
+    {
+#ifdef FEAT_WINDOWS
+	if (mod_mask & MOD_MASK_CTRL)
+	{
+	    /* <C-PageUp>: tab page back; <C-PageDown>: tab page forward */
+	    if (cap->arg == BACKWARD)
+		goto_tabpage(-(int)cap->count1);
+	    else
+		goto_tabpage((int)cap->count0);
+	}
+	else
+#endif
+	(void)onepage(cap->arg, cap->count1);
+    }
+}
+
+/*
+ * Implementation of "gd" and "gD" command.
+ */
+    static void
+nv_gd(oap, nchar, thisblock)
+    oparg_T	*oap;
+    int		nchar;
+    int		thisblock;	/* 1 for "1gd" and "1gD" */
+{
+    int		len;
+    char_u	*ptr;
+
+    if ((len = find_ident_under_cursor(&ptr, FIND_IDENT)) == 0
+	    || find_decl(ptr, len, nchar == 'd', thisblock, 0) == FAIL)
+	clearopbeep(oap);
+#ifdef FEAT_FOLDING
+    else if ((fdo_flags & FDO_SEARCH) && KeyTyped && oap->op_type == OP_NOP)
+	foldOpenCursor();
+#endif
+}
+
+/*
+ * Search for variable declaration of "ptr[len]".
+ * When "locally" is TRUE in the current function ("gd"), otherwise in the
+ * current file ("gD").
+ * When "thisblock" is TRUE check the {} block scope.
+ * Return FAIL when not found.
+ */
+    int
+find_decl(ptr, len, locally, thisblock, searchflags)
+    char_u	*ptr;
+    int		len;
+    int		locally;
+    int		thisblock;
+    int		searchflags;	/* flags passed to searchit() */
+{
+    char_u	*pat;
+    pos_T	old_pos;
+    pos_T	par_pos;
+    pos_T	found_pos;
+    int		t;
+    int		save_p_ws;
+    int		save_p_scs;
+    int		retval = OK;
+    int		incll;
+
+    if ((pat = alloc(len + 7)) == NULL)
+	return FAIL;
+
+    /* Put "\V" before the pattern to avoid that the special meaning of "."
+     * and "~" causes trouble. */
+    sprintf((char *)pat, vim_iswordp(ptr) ? "\\V\\<%.*s\\>" : "\\V%.*s",
+								    len, ptr);
+    old_pos = curwin->w_cursor;
+    save_p_ws = p_ws;
+    save_p_scs = p_scs;
+    p_ws = FALSE;	/* don't wrap around end of file now */
+    p_scs = FALSE;	/* don't switch ignorecase off now */
+
+    /*
+     * With "gD" go to line 1.
+     * With "gd" Search back for the start of the current function, then go
+     * back until a blank line.  If this fails go to line 1.
+     */
+    if (!locally || !findpar(&incll, BACKWARD, 1L, '{', FALSE))
+    {
+	setpcmark();			/* Set in findpar() otherwise */
+	curwin->w_cursor.lnum = 1;
+	par_pos = curwin->w_cursor;
+    }
+    else
+    {
+	par_pos = curwin->w_cursor;
+	while (curwin->w_cursor.lnum > 1 && *skipwhite(ml_get_curline()) != NUL)
+	    --curwin->w_cursor.lnum;
+    }
+    curwin->w_cursor.col = 0;
+
+    /* Search forward for the identifier, ignore comment lines. */
+    clearpos(&found_pos);
+    for (;;)
+    {
+	t = searchit(curwin, curbuf, &curwin->w_cursor, FORWARD,
+				  pat, 1L, searchflags, RE_LAST, (linenr_T)0);
+	if (curwin->w_cursor.lnum >= old_pos.lnum)
+	    t = FAIL;	/* match after start is failure too */
+
+	if (thisblock && t != FAIL)
+	{
+	    pos_T	*pos;
+
+	    /* Check that the block the match is in doesn't end before the
+	     * position where we started the search from. */
+	    if ((pos = findmatchlimit(NULL, '}', FM_FORWARD,
+		     (int)(old_pos.lnum - curwin->w_cursor.lnum + 1))) != NULL
+		    && pos->lnum < old_pos.lnum)
+		continue;
+	}
+
+	if (t == FAIL)
+	{
+	    /* If we previously found a valid position, use it. */
+	    if (found_pos.lnum != 0)
+	    {
+		curwin->w_cursor = found_pos;
+		t = OK;
+	    }
+	    break;
+	}
+#ifdef FEAT_COMMENTS
+	if (get_leader_len(ml_get_curline(), NULL, FALSE) > 0)
+	{
+	    /* Ignore this line, continue at start of next line. */
+	    ++curwin->w_cursor.lnum;
+	    curwin->w_cursor.col = 0;
+	    continue;
+	}
+#endif
+	if (!locally)	/* global search: use first match found */
+	    break;
+	if (curwin->w_cursor.lnum >= par_pos.lnum)
+	{
+	    /* If we previously found a valid position, use it. */
+	    if (found_pos.lnum != 0)
+		curwin->w_cursor = found_pos;
+	    break;
+	}
+
+	/* For finding a local variable and the match is before the "{" search
+	 * to find a later match.  For K&R style function declarations this
+	 * skips the function header without types. */
+	found_pos = curwin->w_cursor;
+    }
+
+    if (t == FAIL)
+    {
+	retval = FAIL;
+	curwin->w_cursor = old_pos;
+    }
+    else
+    {
+	curwin->w_set_curswant = TRUE;
+	/* "n" searches forward now */
+	reset_search_dir();
+    }
+
+    vim_free(pat);
+    p_ws = save_p_ws;
+    p_scs = save_p_scs;
+
+    return retval;
+}
+
+/*
+ * Move 'dist' lines in direction 'dir', counting lines by *screen*
+ * lines rather than lines in the file.
+ * 'dist' must be positive.
+ *
+ * Return OK if able to move cursor, FAIL otherwise.
+ */
+    static int
+nv_screengo(oap, dir, dist)
+    oparg_T	*oap;
+    int		dir;
+    long	dist;
+{
+    int		linelen = linetabsize(ml_get_curline());
+    int		retval = OK;
+    int		atend = FALSE;
+    int		n;
+    int		col_off1;	/* margin offset for first screen line */
+    int		col_off2;	/* margin offset for wrapped screen line */
+    int		width1;		/* text width for first screen line */
+    int		width2;		/* test width for wrapped screen line */
+
+    oap->motion_type = MCHAR;
+    oap->inclusive = FALSE;
+
+    col_off1 = curwin_col_off();
+    col_off2 = col_off1 - curwin_col_off2();
+    width1 = W_WIDTH(curwin) - col_off1;
+    width2 = W_WIDTH(curwin) - col_off2;
+
+#ifdef FEAT_VERTSPLIT
+    if (curwin->w_width != 0)
+    {
+#endif
+      /*
+       * Instead of sticking at the last character of the buffer line we
+       * try to stick in the last column of the screen.
+       */
+      if (curwin->w_curswant == MAXCOL)
+      {
+	atend = TRUE;
+	validate_virtcol();
+	if (width1 <= 0)
+	    curwin->w_curswant = 0;
+	else
+	{
+	    curwin->w_curswant = width1 - 1;
+	    if (curwin->w_virtcol > curwin->w_curswant)
+		curwin->w_curswant += ((curwin->w_virtcol
+			     - curwin->w_curswant - 1) / width2 + 1) * width2;
+	}
+      }
+      else
+      {
+	if (linelen > width1)
+	    n = ((linelen - width1 - 1) / width2 + 1) * width2 + width1;
+	else
+	    n = width1;
+	if (curwin->w_curswant > (colnr_T)n + 1)
+	    curwin->w_curswant -= ((curwin->w_curswant - n) / width2 + 1)
+								     * width2;
+      }
+
+      while (dist--)
+      {
+	if (dir == BACKWARD)
+	{
+	    if ((long)curwin->w_curswant >= width2)
+		/* move back within line */
+		curwin->w_curswant -= width2;
+	    else
+	    {
+		/* to previous line */
+		if (curwin->w_cursor.lnum == 1)
+		{
+		    retval = FAIL;
+		    break;
+		}
+		--curwin->w_cursor.lnum;
+#ifdef FEAT_FOLDING
+		/* Move to the start of a closed fold.  Don't do that when
+		 * 'foldopen' contains "all": it will open in a moment. */
+		if (!(fdo_flags & FDO_ALL))
+		    (void)hasFolding(curwin->w_cursor.lnum,
+						&curwin->w_cursor.lnum, NULL);
+#endif
+		linelen = linetabsize(ml_get_curline());
+		if (linelen > width1)
+		    curwin->w_curswant += (((linelen - width1 - 1) / width2)
+								+ 1) * width2;
+	    }
+	}
+	else /* dir == FORWARD */
+	{
+	    if (linelen > width1)
+		n = ((linelen - width1 - 1) / width2 + 1) * width2 + width1;
+	    else
+		n = width1;
+	    if (curwin->w_curswant + width2 < (colnr_T)n)
+		/* move forward within line */
+		curwin->w_curswant += width2;
+	    else
+	    {
+		/* to next line */
+#ifdef FEAT_FOLDING
+		/* Move to the end of a closed fold. */
+		(void)hasFolding(curwin->w_cursor.lnum, NULL,
+						      &curwin->w_cursor.lnum);
+#endif
+		if (curwin->w_cursor.lnum == curbuf->b_ml.ml_line_count)
+		{
+		    retval = FAIL;
+		    break;
+		}
+		curwin->w_cursor.lnum++;
+		curwin->w_curswant %= width2;
+	    }
+	}
+      }
+#ifdef FEAT_VERTSPLIT
+    }
+#endif
+
+    coladvance(curwin->w_curswant);
+
+#if defined(FEAT_LINEBREAK) || defined(FEAT_MBYTE)
+    if (curwin->w_cursor.col > 0 && curwin->w_p_wrap)
+    {
+	/*
+	 * Check for landing on a character that got split at the end of the
+	 * last line.  We want to advance a screenline, not end up in the same
+	 * screenline or move two screenlines.
+	 */
+	validate_virtcol();
+	if (curwin->w_virtcol > curwin->w_curswant
+		&& (curwin->w_curswant < (colnr_T)width1
+		    ? (curwin->w_curswant > (colnr_T)width1 / 2)
+		    : ((curwin->w_curswant - width1) % width2
+						      > (colnr_T)width2 / 2)))
+	    --curwin->w_cursor.col;
+    }
+#endif
+
+    if (atend)
+	curwin->w_curswant = MAXCOL;	    /* stick in the last column */
+
+    return retval;
+}
+
+#ifdef FEAT_MOUSE
+/*
+ * Mouse scroll wheel: Default action is to scroll three lines, or one page
+ * when Shift or Ctrl is used.
+ * K_MOUSEUP (cap->arg == TRUE) or K_MOUSEDOWN (cap->arg == FALSE)
+ */
+    static void
+nv_mousescroll(cap)
+    cmdarg_T	*cap;
+{
+# if defined(FEAT_GUI) && defined(FEAT_WINDOWS)
+    win_T *old_curwin = curwin;
+
+    /* Currently we only get the mouse coordinates in the GUI. */
+    if (gui.in_use && mouse_row >= 0 && mouse_col >= 0)
+    {
+	int row, col;
+
+	row = mouse_row;
+	col = mouse_col;
+
+	/* find the window at the pointer coordinates */
+	curwin = mouse_find_win(&row, &col);
+	curbuf = curwin->w_buffer;
+    }
+# endif
+
+    if (mod_mask & (MOD_MASK_SHIFT | MOD_MASK_CTRL))
+    {
+	(void)onepage(cap->arg ? FORWARD : BACKWARD, 1L);
+    }
+    else
+    {
+	cap->count1 = 3;
+	cap->count0 = 3;
+	nv_scroll_line(cap);
+    }
+
+# if defined(FEAT_GUI) && defined(FEAT_WINDOWS)
+    curwin->w_redr_status = TRUE;
+
+    curwin = old_curwin;
+    curbuf = curwin->w_buffer;
+# endif
+}
+
+/*
+ * Mouse clicks and drags.
+ */
+    static void
+nv_mouse(cap)
+    cmdarg_T	*cap;
+{
+    (void)do_mouse(cap->oap, cap->cmdchar, BACKWARD, cap->count1, 0);
+}
+#endif
+
+/*
+ * Handle CTRL-E and CTRL-Y commands: scroll a line up or down.
+ * cap->arg must be TRUE for CTRL-E.
+ */
+    static void
+nv_scroll_line(cap)
+    cmdarg_T	*cap;
+{
+    if (!checkclearop(cap->oap))
+	scroll_redraw(cap->arg, cap->count1);
+}
+
+/*
+ * Scroll "count" lines up or down, and redraw.
+ */
+    void
+scroll_redraw(up, count)
+    int		up;
+    long	count;
+{
+    linenr_T	prev_topline = curwin->w_topline;
+#ifdef FEAT_DIFF
+    int		prev_topfill = curwin->w_topfill;
+#endif
+    linenr_T	prev_lnum = curwin->w_cursor.lnum;
+
+    if (up)
+	scrollup(count, TRUE);
+    else
+	scrolldown(count, TRUE);
+    if (p_so)
+    {
+	/* Adjust the cursor position for 'scrolloff'.  Mark w_topline as
+	 * valid, otherwise the screen jumps back at the end of the file. */
+	cursor_correct();
+	check_cursor_moved(curwin);
+	curwin->w_valid |= VALID_TOPLINE;
+
+	/* If moved back to where we were, at least move the cursor, otherwise
+	 * we get stuck at one position.  Don't move the cursor up if the
+	 * first line of the buffer is already on the screen */
+	while (curwin->w_topline == prev_topline
+#ifdef FEAT_DIFF
+		&& curwin->w_topfill == prev_topfill
+#endif
+		)
+	{
+	    if (up)
+	    {
+		if (curwin->w_cursor.lnum > prev_lnum
+			|| cursor_down(1L, FALSE) == FAIL)
+		    break;
+	    }
+	    else
+	    {
+		if (curwin->w_cursor.lnum < prev_lnum
+			|| prev_topline == 1L
+			|| cursor_up(1L, FALSE) == FAIL)
+		    break;
+	    }
+	    /* Mark w_topline as valid, otherwise the screen jumps back at the
+	     * end of the file. */
+	    check_cursor_moved(curwin);
+	    curwin->w_valid |= VALID_TOPLINE;
+	}
+    }
+    if (curwin->w_cursor.lnum != prev_lnum)
+	coladvance(curwin->w_curswant);
+    redraw_later(VALID);
+}
+
+/*
+ * Commands that start with "z".
+ */
+    static void
+nv_zet(cap)
+    cmdarg_T  *cap;
+{
+    long	n;
+    colnr_T	col;
+    int		nchar = cap->nchar;
+#ifdef FEAT_FOLDING
+    long	old_fdl = curwin->w_p_fdl;
+    int		old_fen = curwin->w_p_fen;
+#endif
+#ifdef FEAT_SPELL
+    int		undo = FALSE;
+#endif
+
+    if (VIM_ISDIGIT(nchar))
+    {
+	/*
+	 * "z123{nchar}": edit the count before obtaining {nchar}
+	 */
+	if (checkclearop(cap->oap))
+	    return;
+	n = nchar - '0';
+	for (;;)
+	{
+#ifdef USE_ON_FLY_SCROLL
+	    dont_scroll = TRUE;		/* disallow scrolling here */
+#endif
+	    ++no_mapping;
+	    ++allow_keys;   /* no mapping for nchar, but allow key codes */
+	    nchar = safe_vgetc();
+#ifdef FEAT_LANGMAP
+	    LANGMAP_ADJUST(nchar, TRUE);
+#endif
+	    --no_mapping;
+	    --allow_keys;
+#ifdef FEAT_CMDL_INFO
+	    (void)add_to_showcmd(nchar);
+#endif
+	    if (nchar == K_DEL || nchar == K_KDEL)
+		n /= 10;
+	    else if (VIM_ISDIGIT(nchar))
+		n = n * 10 + (nchar - '0');
+	    else if (nchar == CAR)
+	    {
+#ifdef FEAT_GUI
+		need_mouse_correct = TRUE;
+#endif
+		win_setheight((int)n);
+		break;
+	    }
+	    else if (nchar == 'l'
+		    || nchar == 'h'
+		    || nchar == K_LEFT
+		    || nchar == K_RIGHT)
+	    {
+		cap->count1 = n ? n * cap->count1 : cap->count1;
+		goto dozet;
+	    }
+	    else
+	    {
+		clearopbeep(cap->oap);
+		break;
+	    }
+	}
+	cap->oap->op_type = OP_NOP;
+	return;
+    }
+
+dozet:
+    if (
+#ifdef FEAT_FOLDING
+	    /* "zf" and "zF" are always an operator, "zd", "zo", "zO", "zc"
+	     * and "zC" only in Visual mode.  "zj" and "zk" are motion
+	     * commands. */
+	    cap->nchar != 'f' && cap->nchar != 'F'
+	    && !(VIsual_active && vim_strchr((char_u *)"dcCoO", cap->nchar))
+	    && cap->nchar != 'j' && cap->nchar != 'k'
+	    &&
+#endif
+	    checkclearop(cap->oap))
+	return;
+
+    /*
+     * For "z+", "z<CR>", "zt", "z.", "zz", "z^", "z-", "zb":
+     * If line number given, set cursor.
+     */
+    if ((vim_strchr((char_u *)"+\r\nt.z^-b", nchar) != NULL)
+	    && cap->count0
+	    && cap->count0 != curwin->w_cursor.lnum)
+    {
+	setpcmark();
+	if (cap->count0 > curbuf->b_ml.ml_line_count)
+	    curwin->w_cursor.lnum = curbuf->b_ml.ml_line_count;
+	else
+	    curwin->w_cursor.lnum = cap->count0;
+	check_cursor_col();
+    }
+
+    switch (nchar)
+    {
+		/* "z+", "z<CR>" and "zt": put cursor at top of screen */
+    case '+':
+		if (cap->count0 == 0)
+		{
+		    /* No count given: put cursor at the line below screen */
+		    validate_botline();	/* make sure w_botline is valid */
+		    if (curwin->w_botline > curbuf->b_ml.ml_line_count)
+			curwin->w_cursor.lnum = curbuf->b_ml.ml_line_count;
+		    else
+			curwin->w_cursor.lnum = curwin->w_botline;
+		}
+		/* FALLTHROUGH */
+    case NL:
+    case CAR:
+    case K_KENTER:
+		beginline(BL_WHITE | BL_FIX);
+		/* FALLTHROUGH */
+
+    case 't':	scroll_cursor_top(0, TRUE);
+		redraw_later(VALID);
+		break;
+
+		/* "z." and "zz": put cursor in middle of screen */
+    case '.':	beginline(BL_WHITE | BL_FIX);
+		/* FALLTHROUGH */
+
+    case 'z':	scroll_cursor_halfway(TRUE);
+		redraw_later(VALID);
+		break;
+
+		/* "z^", "z-" and "zb": put cursor at bottom of screen */
+    case '^':	/* Strange Vi behavior: <count>z^ finds line at top of window
+		 * when <count> is at bottom of window, and puts that one at
+		 * bottom of window. */
+		if (cap->count0 != 0)
+		{
+		    scroll_cursor_bot(0, TRUE);
+		    curwin->w_cursor.lnum = curwin->w_topline;
+		}
+		else if (curwin->w_topline == 1)
+		    curwin->w_cursor.lnum = 1;
+		else
+		    curwin->w_cursor.lnum = curwin->w_topline - 1;
+		/* FALLTHROUGH */
+    case '-':
+		beginline(BL_WHITE | BL_FIX);
+		/* FALLTHROUGH */
+
+    case 'b':	scroll_cursor_bot(0, TRUE);
+		redraw_later(VALID);
+		break;
+
+		/* "zH" - scroll screen right half-page */
+    case 'H':
+		cap->count1 *= W_WIDTH(curwin) / 2;
+		/* FALLTHROUGH */
+
+		/* "zh" - scroll screen to the right */
+    case 'h':
+    case K_LEFT:
+		if (!curwin->w_p_wrap)
+		{
+		    if ((colnr_T)cap->count1 > curwin->w_leftcol)
+			curwin->w_leftcol = 0;
+		    else
+			curwin->w_leftcol -= (colnr_T)cap->count1;
+		    leftcol_changed();
+		}
+		break;
+
+		/* "zL" - scroll screen left half-page */
+    case 'L':	cap->count1 *= W_WIDTH(curwin) / 2;
+		/* FALLTHROUGH */
+
+		/* "zl" - scroll screen to the left */
+    case 'l':
+    case K_RIGHT:
+		if (!curwin->w_p_wrap)
+		{
+		    /* scroll the window left */
+		    curwin->w_leftcol += (colnr_T)cap->count1;
+		    leftcol_changed();
+		}
+		break;
+
+		/* "zs" - scroll screen, cursor at the start */
+    case 's':	if (!curwin->w_p_wrap)
+		{
+#ifdef FEAT_FOLDING
+		    if (hasFolding(curwin->w_cursor.lnum, NULL, NULL))
+			col = 0;	/* like the cursor is in col 0 */
+		    else
+#endif
+		    getvcol(curwin, &curwin->w_cursor, &col, NULL, NULL);
+		    if ((long)col > p_siso)
+			col -= p_siso;
+		    else
+			col = 0;
+		    if (curwin->w_leftcol != col)
+		    {
+			curwin->w_leftcol = col;
+			redraw_later(NOT_VALID);
+		    }
+		}
+		break;
+
+		/* "ze" - scroll screen, cursor at the end */
+    case 'e':	if (!curwin->w_p_wrap)
+		{
+#ifdef FEAT_FOLDING
+		    if (hasFolding(curwin->w_cursor.lnum, NULL, NULL))
+			col = 0;	/* like the cursor is in col 0 */
+		    else
+#endif
+		    getvcol(curwin, &curwin->w_cursor, NULL, NULL, &col);
+		    n = W_WIDTH(curwin) - curwin_col_off();
+		    if ((long)col + p_siso < n)
+			col = 0;
+		    else
+			col = col + p_siso - n + 1;
+		    if (curwin->w_leftcol != col)
+		    {
+			curwin->w_leftcol = col;
+			redraw_later(NOT_VALID);
+		    }
+		}
+		break;
+
+#ifdef FEAT_FOLDING
+		/* "zF": create fold command */
+		/* "zf": create fold operator */
+    case 'F':
+    case 'f':   if (foldManualAllowed(TRUE))
+		{
+		    cap->nchar = 'f';
+		    nv_operator(cap);
+		    curwin->w_p_fen = TRUE;
+
+		    /* "zF" is like "zfzf" */
+		    if (nchar == 'F' && cap->oap->op_type == OP_FOLD)
+		    {
+			nv_operator(cap);
+			finish_op = TRUE;
+		    }
+		}
+		else
+		    clearopbeep(cap->oap);
+		break;
+
+		/* "zd": delete fold at cursor */
+		/* "zD": delete fold at cursor recursively */
+    case 'd':
+    case 'D':	if (foldManualAllowed(FALSE))
+		{
+		    if (VIsual_active)
+			nv_operator(cap);
+		    else
+			deleteFold(curwin->w_cursor.lnum,
+				  curwin->w_cursor.lnum, nchar == 'D', FALSE);
+		}
+		break;
+
+		/* "zE": erease all folds */
+    case 'E':	if (foldmethodIsManual(curwin))
+		{
+		    clearFolding(curwin);
+		    changed_window_setting();
+		}
+		else if (foldmethodIsMarker(curwin))
+		    deleteFold((linenr_T)1, curbuf->b_ml.ml_line_count,
+								 TRUE, FALSE);
+		else
+		    EMSG(_("E352: Cannot erase folds with current 'foldmethod'"));
+		break;
+
+		/* "zn": fold none: reset 'foldenable' */
+    case 'n':	curwin->w_p_fen = FALSE;
+		break;
+
+		/* "zN": fold Normal: set 'foldenable' */
+    case 'N':	curwin->w_p_fen = TRUE;
+		break;
+
+		/* "zi": invert folding: toggle 'foldenable' */
+    case 'i':	curwin->w_p_fen = !curwin->w_p_fen;
+		break;
+
+		/* "za": open closed fold or close open fold at cursor */
+    case 'a':	if (hasFolding(curwin->w_cursor.lnum, NULL, NULL))
+		    openFold(curwin->w_cursor.lnum, cap->count1);
+		else
+		{
+		    closeFold(curwin->w_cursor.lnum, cap->count1);
+		    curwin->w_p_fen = TRUE;
+		}
+		break;
+
+		/* "zA": open fold at cursor recursively */
+    case 'A':	if (hasFolding(curwin->w_cursor.lnum, NULL, NULL))
+		    openFoldRecurse(curwin->w_cursor.lnum);
+		else
+		{
+		    closeFoldRecurse(curwin->w_cursor.lnum);
+		    curwin->w_p_fen = TRUE;
+		}
+		break;
+
+		/* "zo": open fold at cursor or Visual area */
+    case 'o':	if (VIsual_active)
+		    nv_operator(cap);
+		else
+		    openFold(curwin->w_cursor.lnum, cap->count1);
+		break;
+
+		/* "zO": open fold recursively */
+    case 'O':	if (VIsual_active)
+		    nv_operator(cap);
+		else
+		    openFoldRecurse(curwin->w_cursor.lnum);
+		break;
+
+		/* "zc": close fold at cursor or Visual area */
+    case 'c':	if (VIsual_active)
+		    nv_operator(cap);
+		else
+		    closeFold(curwin->w_cursor.lnum, cap->count1);
+		curwin->w_p_fen = TRUE;
+		break;
+
+		/* "zC": close fold recursively */
+    case 'C':	if (VIsual_active)
+		    nv_operator(cap);
+		else
+		    closeFoldRecurse(curwin->w_cursor.lnum);
+		curwin->w_p_fen = TRUE;
+		break;
+
+		/* "zv": open folds at the cursor */
+    case 'v':	foldOpenCursor();
+		break;
+
+		/* "zx": re-apply 'foldlevel' and open folds at the cursor */
+    case 'x':	curwin->w_p_fen = TRUE;
+		newFoldLevel();		/* update right now */
+		foldOpenCursor();
+		break;
+
+		/* "zX": undo manual opens/closes, re-apply 'foldlevel' */
+    case 'X':	curwin->w_p_fen = TRUE;
+		old_fdl = -1;		/* force an update */
+		break;
+
+		/* "zm": fold more */
+    case 'm':	if (curwin->w_p_fdl > 0)
+		    --curwin->w_p_fdl;
+		old_fdl = -1;		/* force an update */
+		curwin->w_p_fen = TRUE;
+		break;
+
+		/* "zM": close all folds */
+    case 'M':	curwin->w_p_fdl = 0;
+		old_fdl = -1;		/* force an update */
+		curwin->w_p_fen = TRUE;
+		break;
+
+		/* "zr": reduce folding */
+    case 'r':	++curwin->w_p_fdl;
+		break;
+
+		/* "zR": open all folds */
+    case 'R':	curwin->w_p_fdl = getDeepestNesting();
+		old_fdl = -1;		/* force an update */
+		break;
+
+    case 'j':	/* "zj" move to next fold downwards */
+    case 'k':	/* "zk" move to next fold upwards */
+		if (foldMoveTo(TRUE, nchar == 'j' ? FORWARD : BACKWARD,
+							  cap->count1) == FAIL)
+		    clearopbeep(cap->oap);
+		break;
+
+#endif /* FEAT_FOLDING */
+
+#ifdef FEAT_SPELL
+    case 'u':	/* "zug" and "zuw": undo "zg" and "zw" */
+		++no_mapping;
+		++allow_keys;   /* no mapping for nchar, but allow key codes */
+		nchar = safe_vgetc();
+#ifdef FEAT_LANGMAP
+		LANGMAP_ADJUST(nchar, TRUE);
+#endif
+		--no_mapping;
+		--allow_keys;
+#ifdef FEAT_CMDL_INFO
+		(void)add_to_showcmd(nchar);
+#endif
+		if (vim_strchr((char_u *)"gGwW", nchar) == NULL)
+		{
+		    clearopbeep(cap->oap);
+		    break;
+		}
+		undo = TRUE;
+		/*FALLTHROUGH*/
+
+    case 'g':	/* "zg": add good word to word list */
+    case 'w':	/* "zw": add wrong word to word list */
+    case 'G':	/* "zG": add good word to temp word list */
+    case 'W':	/* "zW": add wrong word to temp word list */
+		{
+		    char_u  *ptr = NULL;
+		    int	    len;
+
+		    if (checkclearop(cap->oap))
+			break;
+# ifdef FEAT_VISUAL
+		    if (VIsual_active && get_visual_text(cap, &ptr, &len)
+								      == FAIL)
+			return;
+# endif
+		    if (ptr == NULL)
+		    {
+			pos_T	pos = curwin->w_cursor;
+
+			/* Find bad word under the cursor. */
+			len = spell_move_to(curwin, FORWARD, TRUE, TRUE, NULL);
+			if (len != 0 && curwin->w_cursor.col <= pos.col)
+			    ptr = ml_get_pos(&curwin->w_cursor);
+			curwin->w_cursor = pos;
+		    }
+
+		    if (ptr == NULL && (len = find_ident_under_cursor(&ptr,
+							    FIND_IDENT)) == 0)
+			return;
+		    spell_add_word(ptr, len, nchar == 'w' || nchar == 'W',
+					    (nchar == 'G' || nchar == 'W')
+						       ? 0 : (int)cap->count1,
+					    undo);
+		}
+		break;
+
+    case '=':	/* "z=": suggestions for a badly spelled word  */
+		if (!checkclearop(cap->oap))
+		    spell_suggest((int)cap->count0);
+		break;
+#endif
+
+    default:	clearopbeep(cap->oap);
+    }
+
+#ifdef FEAT_FOLDING
+    /* Redraw when 'foldenable' changed */
+    if (old_fen != curwin->w_p_fen)
+    {
+# ifdef FEAT_DIFF
+	win_T	    *wp;
+
+	if (foldmethodIsDiff(curwin) && curwin->w_p_scb)
+	{
+	    /* Adjust 'foldenable' in diff-synced windows. */
+	    FOR_ALL_WINDOWS(wp)
+	    {
+		if (wp != curwin && foldmethodIsDiff(wp) && wp->w_p_scb)
+		{
+		    wp->w_p_fen = curwin->w_p_fen;
+		    changed_window_setting_win(wp);
+		}
+	    }
+	}
+# endif
+	changed_window_setting();
+    }
+
+    /* Redraw when 'foldlevel' changed. */
+    if (old_fdl != curwin->w_p_fdl)
+	newFoldLevel();
+#endif
+}
+
+#ifdef FEAT_GUI
+/*
+ * Vertical scrollbar movement.
+ */
+    static void
+nv_ver_scrollbar(cap)
+    cmdarg_T	*cap;
+{
+    if (cap->oap->op_type != OP_NOP)
+	clearopbeep(cap->oap);
+
+    /* Even if an operator was pending, we still want to scroll */
+    gui_do_scroll();
+}
+
+/*
+ * Horizontal scrollbar movement.
+ */
+    static void
+nv_hor_scrollbar(cap)
+    cmdarg_T	*cap;
+{
+    if (cap->oap->op_type != OP_NOP)
+	clearopbeep(cap->oap);
+
+    /* Even if an operator was pending, we still want to scroll */
+    gui_do_horiz_scroll();
+}
+#endif
+
+#if defined(FEAT_GUI_TABLINE) || defined(PROTO)
+/*
+ * Click in GUI tab.
+ */
+    static void
+nv_tabline(cap)
+    cmdarg_T	*cap;
+{
+    if (cap->oap->op_type != OP_NOP)
+	clearopbeep(cap->oap);
+
+    /* Even if an operator was pending, we still want to jump tabs. */
+    goto_tabpage(current_tab);
+}
+
+/*
+ * Selected item in tab line menu.
+ */
+    static void
+nv_tabmenu(cap)
+    cmdarg_T	*cap;
+{
+    if (cap->oap->op_type != OP_NOP)
+	clearopbeep(cap->oap);
+
+    /* Even if an operator was pending, we still want to jump tabs. */
+    handle_tabmenu();
+}
+
+/*
+ * Handle selecting an item of the GUI tab line menu.
+ * Used in Normal and Insert mode.
+ */
+    void
+handle_tabmenu()
+{
+    switch (current_tabmenu)
+    {
+	case TABLINE_MENU_CLOSE:
+	    if (current_tab == 0)
+		do_cmdline_cmd((char_u *)"tabclose");
+	    else
+	    {
+		vim_snprintf((char *)IObuff, IOSIZE, "tabclose %d",
+								 current_tab);
+		do_cmdline_cmd(IObuff);
+	    }
+	    break;
+
+	case TABLINE_MENU_NEW:
+	    vim_snprintf((char *)IObuff, IOSIZE, "%dtabnew",
+				     current_tab > 0 ? current_tab - 1 : 999);
+	    do_cmdline_cmd(IObuff);
+	    break;
+
+	case TABLINE_MENU_OPEN:
+	    vim_snprintf((char *)IObuff, IOSIZE, "browse %dtabnew",
+				     current_tab > 0 ? current_tab - 1 : 999);
+	    do_cmdline_cmd(IObuff);
+	    break;
+    }
+}
+#endif
+
+/*
+ * "Q" command.
+ */
+    static void
+nv_exmode(cap)
+    cmdarg_T	*cap;
+{
+    /*
+     * Ignore 'Q' in Visual mode, just give a beep.
+     */
+#ifdef FEAT_VISUAL
+    if (VIsual_active)
+	vim_beep();
+    else
+#endif
+	if (!checkclearop(cap->oap))
+	do_exmode(FALSE);
+}
+
+/*
+ * Handle a ":" command.
+ */
+    static void
+nv_colon(cap)
+    cmdarg_T  *cap;
+{
+    int	    old_p_im;
+
+#ifdef FEAT_VISUAL
+    if (VIsual_active)
+	nv_operator(cap);
+    else
+#endif
+    {
+	if (cap->oap->op_type != OP_NOP)
+	{
+	    /* Using ":" as a movement is characterwise exclusive. */
+	    cap->oap->motion_type = MCHAR;
+	    cap->oap->inclusive = FALSE;
+	}
+	else if (cap->count0)
+	{
+	    /* translate "count:" into ":.,.+(count - 1)" */
+	    stuffcharReadbuff('.');
+	    if (cap->count0 > 1)
+	    {
+		stuffReadbuff((char_u *)",.+");
+		stuffnumReadbuff((long)cap->count0 - 1L);
+	    }
+	}
+
+	/* When typing, don't type below an old message */
+	if (KeyTyped)
+	    compute_cmdrow();
+
+	old_p_im = p_im;
+
+	/* get a command line and execute it */
+	do_cmdline(NULL, getexline, NULL,
+			    cap->oap->op_type != OP_NOP ? DOCMD_KEEPLINE : 0);
+
+	/* If 'insertmode' changed, enter or exit Insert mode */
+	if (p_im != old_p_im)
+	{
+	    if (p_im)
+		restart_edit = 'i';
+	    else
+		restart_edit = 0;
+	}
+
+	/* The start of the operator may have become invalid by the Ex
+	 * command. */
+	if (cap->oap->op_type != OP_NOP
+		&& (cap->oap->start.lnum > curbuf->b_ml.ml_line_count
+		    || cap->oap->start.col >
+					 STRLEN(ml_get(cap->oap->start.lnum))))
+	    clearopbeep(cap->oap);
+    }
+}
+
+/*
+ * Handle CTRL-G command.
+ */
+    static void
+nv_ctrlg(cap)
+    cmdarg_T *cap;
+{
+#ifdef FEAT_VISUAL
+    if (VIsual_active)	/* toggle Selection/Visual mode */
+    {
+	VIsual_select = !VIsual_select;
+	showmode();
+    }
+    else
+#endif
+	if (!checkclearop(cap->oap))
+	/* print full name if count given or :cd used */
+	fileinfo((int)cap->count0, FALSE, TRUE);
+}
+
+/*
+ * Handle CTRL-H <Backspace> command.
+ */
+    static void
+nv_ctrlh(cap)
+    cmdarg_T *cap;
+{
+#ifdef FEAT_VISUAL
+    if (VIsual_active && VIsual_select)
+    {
+	cap->cmdchar = 'x';	/* BS key behaves like 'x' in Select mode */
+	v_visop(cap);
+    }
+    else
+#endif
+	nv_left(cap);
+}
+
+/*
+ * CTRL-L: clear screen and redraw.
+ */
+    static void
+nv_clear(cap)
+    cmdarg_T	*cap;
+{
+    if (!checkclearop(cap->oap))
+    {
+#if defined(__BEOS__) && !USE_THREAD_FOR_INPUT_WITH_TIMEOUT
+	/*
+	 * Right now, the BeBox doesn't seem to have an easy way to detect
+	 * window resizing, so we cheat and make the user detect it
+	 * manually with CTRL-L instead
+	 */
+	ui_get_shellsize();
+#endif
+#ifdef FEAT_SYN_HL
+	/* Clear all syntax states to force resyncing. */
+	syn_stack_free_all(curbuf);
+#endif
+	redraw_later(CLEAR);
+    }
+}
+
+/*
+ * CTRL-O: In Select mode: switch to Visual mode for one command.
+ * Otherwise: Go to older pcmark.
+ */
+    static void
+nv_ctrlo(cap)
+    cmdarg_T	*cap;
+{
+#ifdef FEAT_VISUAL
+    if (VIsual_active && VIsual_select)
+    {
+	VIsual_select = FALSE;
+	showmode();
+	restart_VIsual_select = 2;	/* restart Select mode later */
+    }
+    else
+#endif
+    {
+	cap->count1 = -cap->count1;
+	nv_pcmark(cap);
+    }
+}
+
+/*
+ * CTRL-^ command, short for ":e #"
+ */
+    static void
+nv_hat(cap)
+    cmdarg_T	*cap;
+{
+    if (!checkclearopq(cap->oap))
+	(void)buflist_getfile((int)cap->count0, (linenr_T)0,
+						GETF_SETMARK|GETF_ALT, FALSE);
+}
+
+/*
+ * "Z" commands.
+ */
+    static void
+nv_Zet(cap)
+    cmdarg_T *cap;
+{
+    if (!checkclearopq(cap->oap))
+    {
+	switch (cap->nchar)
+	{
+			/* "ZZ": equivalent to ":x". */
+	    case 'Z':	do_cmdline_cmd((char_u *)"x");
+			break;
+
+			/* "ZQ": equivalent to ":q!" (Elvis compatible). */
+	    case 'Q':	do_cmdline_cmd((char_u *)"q!");
+			break;
+
+	    default:	clearopbeep(cap->oap);
+	}
+    }
+}
+
+#if defined(FEAT_WINDOWS) || defined(PROTO)
+/*
+ * Call nv_ident() as if "c1" was used, with "c2" as next character.
+ */
+    void
+do_nv_ident(c1, c2)
+    int		c1;
+    int		c2;
+{
+    oparg_T	oa;
+    cmdarg_T	ca;
+
+    clear_oparg(&oa);
+    vim_memset(&ca, 0, sizeof(ca));
+    ca.oap = &oa;
+    ca.cmdchar = c1;
+    ca.nchar = c2;
+    nv_ident(&ca);
+}
+#endif
+
+/*
+ * Handle the commands that use the word under the cursor.
+ * [g] CTRL-]	:ta to current identifier
+ * [g] 'K'	run program for current identifier
+ * [g] '*'	/ to current identifier or string
+ * [g] '#'	? to current identifier or string
+ *  g  ']'	:tselect for current identifier
+ */
+    static void
+nv_ident(cap)
+    cmdarg_T	*cap;
+{
+    char_u	*ptr = NULL;
+    char_u	*buf;
+    char_u	*p;
+    char_u	*kp;		/* value of 'keywordprg' */
+    int		kp_help;	/* 'keywordprg' is ":help" */
+    int		n = 0;		/* init for GCC */
+    int		cmdchar;
+    int		g_cmd;		/* "g" command */
+    char_u	*aux_ptr;
+    int		isman;
+    int		isman_s;
+
+    if (cap->cmdchar == 'g')	/* "g*", "g#", "g]" and "gCTRL-]" */
+    {
+	cmdchar = cap->nchar;
+	g_cmd = TRUE;
+    }
+    else
+    {
+	cmdchar = cap->cmdchar;
+	g_cmd = FALSE;
+    }
+
+    if (cmdchar == POUND)	/* the pound sign, '#' for English keyboards */
+	cmdchar = '#';
+
+    /*
+     * The "]", "CTRL-]" and "K" commands accept an argument in Visual mode.
+     */
+    if (cmdchar == ']' || cmdchar == Ctrl_RSB || cmdchar == 'K')
+    {
+#ifdef FEAT_VISUAL
+	if (VIsual_active && get_visual_text(cap, &ptr, &n) == FAIL)
+	    return;
+#endif
+	if (checkclearopq(cap->oap))
+	    return;
+    }
+
+    if (ptr == NULL && (n = find_ident_under_cursor(&ptr,
+		    (cmdchar == '*' || cmdchar == '#')
+				 ? FIND_IDENT|FIND_STRING : FIND_IDENT)) == 0)
+    {
+	clearop(cap->oap);
+	return;
+    }
+
+    /* Allocate buffer to put the command in.  Inserting backslashes can
+     * double the length of the word.  p_kp / curbuf->b_p_kp could be added
+     * and some numbers. */
+    kp = (*curbuf->b_p_kp == NUL ? p_kp : curbuf->b_p_kp);
+    kp_help = (*kp == NUL || STRCMP(kp, ":he") == 0
+						 || STRCMP(kp, ":help") == 0);
+    buf = alloc((unsigned)(n * 2 + 30 + STRLEN(kp)));
+    if (buf == NULL)
+	return;
+    buf[0] = NUL;
+
+    switch (cmdchar)
+    {
+	case '*':
+	case '#':
+	    /*
+	     * Put cursor at start of word, makes search skip the word
+	     * under the cursor.
+	     * Call setpcmark() first, so "*``" puts the cursor back where
+	     * it was.
+	     */
+	    setpcmark();
+	    curwin->w_cursor.col = (colnr_T) (ptr - ml_get_curline());
+
+	    if (!g_cmd && vim_iswordp(ptr))
+		STRCPY(buf, "\\<");
+	    no_smartcase = TRUE;	/* don't use 'smartcase' now */
+	    break;
+
+	case 'K':
+	    if (kp_help)
+		STRCPY(buf, "he! ");
+	    else
+	    {
+		/* When a count is given, turn it into a range.  Is this
+		 * really what we want? */
+		isman = (STRCMP(kp, "man") == 0);
+		isman_s = (STRCMP(kp, "man -s") == 0);
+		if (cap->count0 != 0 && !(isman || isman_s))
+		    sprintf((char *)buf, ".,.+%ld", cap->count0 - 1);
+
+		STRCAT(buf, "! ");
+		if (cap->count0 == 0 && isman_s)
+		    STRCAT(buf, "man");
+		else
+		    STRCAT(buf, kp);
+		STRCAT(buf, " ");
+		if (cap->count0 != 0 && (isman || isman_s))
+		{
+		    sprintf((char *)buf + STRLEN(buf), "%ld", cap->count0);
+		    STRCAT(buf, " ");
+		}
+	    }
+	    break;
+
+	case ']':
+#ifdef FEAT_CSCOPE
+	    if (p_cst)
+		STRCPY(buf, "cstag ");
+	    else
+#endif
+		STRCPY(buf, "ts ");
+	    break;
+
+	default:
+	    if (curbuf->b_help)
+		STRCPY(buf, "he! ");
+	    else if (g_cmd)
+		STRCPY(buf, "tj ");
+	    else
+		sprintf((char *)buf, "%ldta ", cap->count0);
+    }
+
+    /*
+     * Now grab the chars in the identifier
+     */
+    if (cmdchar == '*')
+	aux_ptr = (char_u *)(p_magic ? "/.*~[^$\\" : "/^$\\");
+    else if (cmdchar == '#')
+	aux_ptr = (char_u *)(p_magic ? "/?.*~[^$\\" : "/?^$\\");
+    else if (cmdchar == 'K' && !kp_help)
+	aux_ptr = (char_u *)" \t\\\"|!";
+    else
+	/* Don't escape spaces and Tabs in a tag with a backslash */
+	aux_ptr = (char_u *)"\\|\"";
+
+    p = buf + STRLEN(buf);
+    while (n-- > 0)
+    {
+	/* put a backslash before \ and some others */
+	if (vim_strchr(aux_ptr, *ptr) != NULL)
+	    *p++ = '\\';
+#ifdef FEAT_MBYTE
+	/* When current byte is a part of multibyte character, copy all bytes
+	 * of that character. */
+	if (has_mbyte)
+	{
+	    int i;
+	    int len = (*mb_ptr2len)(ptr) - 1;
+
+	    for (i = 0; i < len && n >= 1; ++i, --n)
+		*p++ = *ptr++;
+	}
+#endif
+	*p++ = *ptr++;
+    }
+    *p = NUL;
+
+    /*
+     * Execute the command.
+     */
+    if (cmdchar == '*' || cmdchar == '#')
+    {
+	if (!g_cmd && (
+#ifdef FEAT_MBYTE
+		has_mbyte ? vim_iswordp(mb_prevptr(ml_get_curline(), ptr)) :
+#endif
+		vim_iswordc(ptr[-1])))
+	    STRCAT(buf, "\\>");
+#ifdef FEAT_CMDHIST
+	/* put pattern in search history */
+	add_to_history(HIST_SEARCH, buf, TRUE, NUL);
+#endif
+	normal_search(cap, cmdchar == '*' ? '/' : '?', buf, 0);
+    }
+    else
+	do_cmdline_cmd(buf);
+
+    vim_free(buf);
+}
+
+#if defined(FEAT_VISUAL) || defined(PROTO)
+/*
+ * Get visually selected text, within one line only.
+ * Returns FAIL if more than one line selected.
+ */
+    int
+get_visual_text(cap, pp, lenp)
+    cmdarg_T	*cap;
+    char_u	**pp;	    /* return: start of selected text */
+    int		*lenp;	    /* return: length of selected text */
+{
+    if (VIsual_mode != 'V')
+	unadjust_for_sel();
+    if (VIsual.lnum != curwin->w_cursor.lnum)
+    {
+	if (cap != NULL)
+	    clearopbeep(cap->oap);
+	return FAIL;
+    }
+    if (VIsual_mode == 'V')
+    {
+	*pp = ml_get_curline();
+	*lenp = (int)STRLEN(*pp);
+    }
+    else
+    {
+	if (lt(curwin->w_cursor, VIsual))
+	{
+	    *pp = ml_get_pos(&curwin->w_cursor);
+	    *lenp = VIsual.col - curwin->w_cursor.col + 1;
+	}
+	else
+	{
+	    *pp = ml_get_pos(&VIsual);
+	    *lenp = curwin->w_cursor.col - VIsual.col + 1;
+	}
+#ifdef FEAT_MBYTE
+	if (has_mbyte)
+	    /* Correct the length to include the whole last character. */
+	    *lenp += (*mb_ptr2len)(*pp + (*lenp - 1)) - 1;
+#endif
+    }
+    reset_VIsual_and_resel();
+    return OK;
+}
+#endif
+
+/*
+ * CTRL-T: backwards in tag stack
+ */
+    static void
+nv_tagpop(cap)
+    cmdarg_T	*cap;
+{
+    if (!checkclearopq(cap->oap))
+	do_tag((char_u *)"", DT_POP, (int)cap->count1, FALSE, TRUE);
+}
+
+/*
+ * Handle scrolling command 'H', 'L' and 'M'.
+ */
+    static void
+nv_scroll(cap)
+    cmdarg_T  *cap;
+{
+    int		used = 0;
+    long	n;
+#ifdef FEAT_FOLDING
+    linenr_T	lnum;
+#endif
+    int		half;
+
+    cap->oap->motion_type = MLINE;
+    setpcmark();
+
+    if (cap->cmdchar == 'L')
+    {
+	validate_botline();	    /* make sure curwin->w_botline is valid */
+	curwin->w_cursor.lnum = curwin->w_botline - 1;
+	if (cap->count1 - 1 >= curwin->w_cursor.lnum)
+	    curwin->w_cursor.lnum = 1;
+	else
+	{
+#ifdef FEAT_FOLDING
+	    if (hasAnyFolding(curwin))
+	    {
+		/* Count a fold for one screen line. */
+		for (n = cap->count1 - 1; n > 0
+			    && curwin->w_cursor.lnum > curwin->w_topline; --n)
+		{
+		    (void)hasFolding(curwin->w_cursor.lnum,
+						&curwin->w_cursor.lnum, NULL);
+		    --curwin->w_cursor.lnum;
+		}
+	    }
+	    else
+#endif
+		curwin->w_cursor.lnum -= cap->count1 - 1;
+	}
+    }
+    else
+    {
+	if (cap->cmdchar == 'M')
+	{
+#ifdef FEAT_DIFF
+	    /* Don't count filler lines above the window. */
+	    used -= diff_check_fill(curwin, curwin->w_topline)
+							  - curwin->w_topfill;
+#endif
+	    validate_botline();	    /* make sure w_empty_rows is valid */
+	    half = (curwin->w_height - curwin->w_empty_rows + 1) / 2;
+	    for (n = 0; curwin->w_topline + n < curbuf->b_ml.ml_line_count; ++n)
+	    {
+#ifdef FEAT_DIFF
+		/* Count half he number of filler lines to be "below this
+		 * line" and half to be "above the next line". */
+		if (n > 0 && used + diff_check_fill(curwin, curwin->w_topline
+							     + n) / 2 >= half)
+		{
+		    --n;
+		    break;
+		}
+#endif
+		used += plines(curwin->w_topline + n);
+		if (used >= half)
+		    break;
+#ifdef FEAT_FOLDING
+		if (hasFolding(curwin->w_topline + n, NULL, &lnum))
+		    n = lnum - curwin->w_topline;
+#endif
+	    }
+	    if (n > 0 && used > curwin->w_height)
+		--n;
+	}
+	else /* (cap->cmdchar == 'H') */
+	{
+	    n = cap->count1 - 1;
+#ifdef FEAT_FOLDING
+	    if (hasAnyFolding(curwin))
+	    {
+		/* Count a fold for one screen line. */
+		lnum = curwin->w_topline;
+		while (n-- > 0 && lnum < curwin->w_botline - 1)
+		{
+		    hasFolding(lnum, NULL, &lnum);
+		    ++lnum;
+		}
+		n = lnum - curwin->w_topline;
+	    }
+#endif
+	}
+	curwin->w_cursor.lnum = curwin->w_topline + n;
+	if (curwin->w_cursor.lnum > curbuf->b_ml.ml_line_count)
+	    curwin->w_cursor.lnum = curbuf->b_ml.ml_line_count;
+    }
+
+    cursor_correct();	/* correct for 'so' */
+    beginline(BL_SOL | BL_FIX);
+}
+
+/*
+ * Cursor right commands.
+ */
+    static void
+nv_right(cap)
+    cmdarg_T	*cap;
+{
+    long	n;
+#ifdef FEAT_VISUAL
+    int		PAST_LINE;
+#else
+# define PAST_LINE 0
+#endif
+
+    if (mod_mask & (MOD_MASK_SHIFT | MOD_MASK_CTRL))
+    {
+	/* <C-Right> and <S-Right> move a word or WORD right */
+	if (mod_mask & MOD_MASK_CTRL)
+	    cap->arg = TRUE;
+	nv_wordcmd(cap);
+	return;
+    }
+
+    cap->oap->motion_type = MCHAR;
+    cap->oap->inclusive = FALSE;
+#ifdef FEAT_VISUAL
+    PAST_LINE = (VIsual_active && *p_sel != 'o');
+
+# ifdef FEAT_VIRTUALEDIT
+    /*
+     * In virtual mode, there's no such thing as "PAST_LINE", as lines are
+     * (theoretically) infinitely long.
+     */
+    if (virtual_active())
+	PAST_LINE = 0;
+# endif
+#endif
+
+    for (n = cap->count1; n > 0; --n)
+    {
+	if ((!PAST_LINE && oneright() == FAIL)
+		|| (PAST_LINE && *ml_get_cursor() == NUL))
+	{
+	    /*
+	     *	  <Space> wraps to next line if 'whichwrap' has 's'.
+	     *	      'l' wraps to next line if 'whichwrap' has 'l'.
+	     * CURS_RIGHT wraps to next line if 'whichwrap' has '>'.
+	     */
+	    if (       ((cap->cmdchar == ' '
+			    && vim_strchr(p_ww, 's') != NULL)
+			|| (cap->cmdchar == 'l'
+			    && vim_strchr(p_ww, 'l') != NULL)
+			|| (cap->cmdchar == K_RIGHT
+			    && vim_strchr(p_ww, '>') != NULL))
+		    && curwin->w_cursor.lnum < curbuf->b_ml.ml_line_count)
+	    {
+		/* When deleting we also count the NL as a character.
+		 * Set cap->oap->inclusive when last char in the line is
+		 * included, move to next line after that */
+		if (	   cap->oap->op_type != OP_NOP
+			&& !cap->oap->inclusive
+			&& !lineempty(curwin->w_cursor.lnum))
+		    cap->oap->inclusive = TRUE;
+		else
+		{
+		    ++curwin->w_cursor.lnum;
+		    curwin->w_cursor.col = 0;
+#ifdef FEAT_VIRTUALEDIT
+		    curwin->w_cursor.coladd = 0;
+#endif
+		    curwin->w_set_curswant = TRUE;
+		    cap->oap->inclusive = FALSE;
+		}
+		continue;
+	    }
+	    if (cap->oap->op_type == OP_NOP)
+	    {
+		/* Only beep and flush if not moved at all */
+		if (n == cap->count1)
+		    beep_flush();
+	    }
+	    else
+	    {
+		if (!lineempty(curwin->w_cursor.lnum))
+		    cap->oap->inclusive = TRUE;
+	    }
+	    break;
+	}
+#ifdef FEAT_VISUAL
+	else if (PAST_LINE)
+	{
+	    curwin->w_set_curswant = TRUE;
+# ifdef FEAT_VIRTUALEDIT
+	    if (virtual_active())
+		oneright();
+	    else
+# endif
+	    {
+# ifdef FEAT_MBYTE
+		if (has_mbyte)
+		    curwin->w_cursor.col +=
+					 (*mb_ptr2len)(ml_get_cursor());
+		else
+# endif
+		    ++curwin->w_cursor.col;
+	    }
+	}
+#endif
+    }
+#ifdef FEAT_FOLDING
+    if (n != cap->count1 && (fdo_flags & FDO_HOR) && KeyTyped
+					       && cap->oap->op_type == OP_NOP)
+	foldOpenCursor();
+#endif
+}
+
+/*
+ * Cursor left commands.
+ *
+ * Returns TRUE when operator end should not be adjusted.
+ */
+    static void
+nv_left(cap)
+    cmdarg_T	*cap;
+{
+    long	n;
+
+    if (mod_mask & (MOD_MASK_SHIFT | MOD_MASK_CTRL))
+    {
+	/* <C-Left> and <S-Left> move a word or WORD left */
+	if (mod_mask & MOD_MASK_CTRL)
+	    cap->arg = 1;
+	nv_bck_word(cap);
+	return;
+    }
+
+    cap->oap->motion_type = MCHAR;
+    cap->oap->inclusive = FALSE;
+    for (n = cap->count1; n > 0; --n)
+    {
+	if (oneleft() == FAIL)
+	{
+	    /* <BS> and <Del> wrap to previous line if 'whichwrap' has 'b'.
+	     *		 'h' wraps to previous line if 'whichwrap' has 'h'.
+	     *	   CURS_LEFT wraps to previous line if 'whichwrap' has '<'.
+	     */
+	    if (       (((cap->cmdchar == K_BS
+				|| cap->cmdchar == Ctrl_H)
+			    && vim_strchr(p_ww, 'b') != NULL)
+			|| (cap->cmdchar == 'h'
+			    && vim_strchr(p_ww, 'h') != NULL)
+			|| (cap->cmdchar == K_LEFT
+			    && vim_strchr(p_ww, '<') != NULL))
+		    && curwin->w_cursor.lnum > 1)
+	    {
+		--(curwin->w_cursor.lnum);
+		coladvance((colnr_T)MAXCOL);
+		curwin->w_set_curswant = TRUE;
+
+		/* When the NL before the first char has to be deleted we
+		 * put the cursor on the NUL after the previous line.
+		 * This is a very special case, be careful!
+		 * don't adjust op_end now, otherwise it won't work */
+		if (	   (cap->oap->op_type == OP_DELETE
+			    || cap->oap->op_type == OP_CHANGE)
+			&& !lineempty(curwin->w_cursor.lnum))
+		{
+		    ++curwin->w_cursor.col;
+		    cap->retval |= CA_NO_ADJ_OP_END;
+		}
+		continue;
+	    }
+	    /* Only beep and flush if not moved at all */
+	    else if (cap->oap->op_type == OP_NOP && n == cap->count1)
+		beep_flush();
+	    break;
+	}
+    }
+#ifdef FEAT_FOLDING
+    if (n != cap->count1 && (fdo_flags & FDO_HOR) && KeyTyped
+					       && cap->oap->op_type == OP_NOP)
+	foldOpenCursor();
+#endif
+}
+
+/*
+ * Cursor up commands.
+ * cap->arg is TRUE for "-": Move cursor to first non-blank.
+ */
+    static void
+nv_up(cap)
+    cmdarg_T	*cap;
+{
+    if (mod_mask & MOD_MASK_SHIFT)
+    {
+	/* <S-Up> is page up */
+	cap->arg = BACKWARD;
+	nv_page(cap);
+    }
+    else
+    {
+	cap->oap->motion_type = MLINE;
+	if (cursor_up(cap->count1, cap->oap->op_type == OP_NOP) == FAIL)
+	    clearopbeep(cap->oap);
+	else if (cap->arg)
+	    beginline(BL_WHITE | BL_FIX);
+    }
+}
+
+/*
+ * Cursor down commands.
+ * cap->arg is TRUE for CR and "+": Move cursor to first non-blank.
+ */
+    static void
+nv_down(cap)
+    cmdarg_T	*cap;
+{
+    if (mod_mask & MOD_MASK_SHIFT)
+    {
+	/* <S-Down> is page down */
+	cap->arg = FORWARD;
+	nv_page(cap);
+    }
+    else
+#if defined(FEAT_WINDOWS) && defined(FEAT_QUICKFIX)
+    /* In a quickfix window a <CR> jumps to the error under the cursor. */
+    if (bt_quickfix(curbuf) && cap->cmdchar == CAR)
+	if (curwin->w_llist_ref == NULL)
+	    do_cmdline_cmd((char_u *)".cc");	/* quickfix window */
+	else
+	    do_cmdline_cmd((char_u *)".ll");	/* location list window */
+    else
+#endif
+    {
+#ifdef FEAT_CMDWIN
+	/* In the cmdline window a <CR> executes the command. */
+	if (cmdwin_type != 0 && cap->cmdchar == CAR)
+	    cmdwin_result = CAR;
+	else
+#endif
+	{
+	    cap->oap->motion_type = MLINE;
+	    if (cursor_down(cap->count1, cap->oap->op_type == OP_NOP) == FAIL)
+		clearopbeep(cap->oap);
+	    else if (cap->arg)
+		beginline(BL_WHITE | BL_FIX);
+	}
+    }
+}
+
+#ifdef FEAT_SEARCHPATH
+/*
+ * Grab the file name under the cursor and edit it.
+ */
+    static void
+nv_gotofile(cap)
+    cmdarg_T	*cap;
+{
+    char_u	*ptr;
+    linenr_T	lnum = -1;
+
+    if (text_locked())
+    {
+	clearopbeep(cap->oap);
+	text_locked_msg();
+	return;
+    }
+#ifdef FEAT_AUTOCMD
+    if (curbuf_locked())
+    {
+	clearop(cap->oap);
+	return;
+    }
+#endif
+
+    ptr = grab_file_name(cap->count1, &lnum);
+
+    if (ptr != NULL)
+    {
+	/* do autowrite if necessary */
+	if (curbufIsChanged() && curbuf->b_nwindows <= 1 && !P_HID(curbuf))
+	    autowrite(curbuf, FALSE);
+	setpcmark();
+	(void)do_ecmd(0, ptr, NULL, NULL, ECMD_LAST,
+					       P_HID(curbuf) ? ECMD_HIDE : 0);
+	if (cap->nchar == 'F' && lnum >= 0)
+	{
+	    curwin->w_cursor.lnum = lnum;
+	    check_cursor_lnum();
+	    beginline(BL_SOL | BL_FIX);
+	}
+	vim_free(ptr);
+    }
+    else
+	clearop(cap->oap);
+}
+#endif
+
+/*
+ * <End> command: to end of current line or last line.
+ */
+    static void
+nv_end(cap)
+    cmdarg_T	*cap;
+{
+    if (cap->arg || (mod_mask & MOD_MASK_CTRL))	/* CTRL-END = goto last line */
+    {
+	cap->arg = TRUE;
+	nv_goto(cap);
+	cap->count1 = 1;		/* to end of current line */
+    }
+    nv_dollar(cap);
+}
+
+/*
+ * Handle the "$" command.
+ */
+    static void
+nv_dollar(cap)
+    cmdarg_T	*cap;
+{
+    cap->oap->motion_type = MCHAR;
+    cap->oap->inclusive = TRUE;
+#ifdef FEAT_VIRTUALEDIT
+    /* In virtual mode when off the edge of a line and an operator
+     * is pending (whew!) keep the cursor where it is.
+     * Otherwise, send it to the end of the line. */
+    if (!virtual_active() || gchar_cursor() != NUL
+					       || cap->oap->op_type == OP_NOP)
+#endif
+	curwin->w_curswant = MAXCOL;	/* so we stay at the end */
+    if (cursor_down((long)(cap->count1 - 1),
+					 cap->oap->op_type == OP_NOP) == FAIL)
+	clearopbeep(cap->oap);
+#ifdef FEAT_FOLDING
+    else if ((fdo_flags & FDO_HOR) && KeyTyped && cap->oap->op_type == OP_NOP)
+	foldOpenCursor();
+#endif
+}
+
+/*
+ * Implementation of '?' and '/' commands.
+ * If cap->arg is TRUE don't set PC mark.
+ */
+    static void
+nv_search(cap)
+    cmdarg_T	    *cap;
+{
+    oparg_T	*oap = cap->oap;
+
+    if (cap->cmdchar == '?' && cap->oap->op_type == OP_ROT13)
+    {
+	/* Translate "g??" to "g?g?" */
+	cap->cmdchar = 'g';
+	cap->nchar = '?';
+	nv_operator(cap);
+	return;
+    }
+
+    cap->searchbuf = getcmdline(cap->cmdchar, cap->count1, 0);
+
+    if (cap->searchbuf == NULL)
+    {
+	clearop(oap);
+	return;
+    }
+
+    normal_search(cap, cap->cmdchar, cap->searchbuf,
+						(cap->arg ? 0 : SEARCH_MARK));
+}
+
+/*
+ * Handle "N" and "n" commands.
+ * cap->arg is SEARCH_REV for "N", 0 for "n".
+ */
+    static void
+nv_next(cap)
+    cmdarg_T	*cap;
+{
+    normal_search(cap, 0, NULL, SEARCH_MARK | cap->arg);
+}
+
+/*
+ * Search for "pat" in direction "dir" ('/' or '?', 0 for repeat).
+ * Uses only cap->count1 and cap->oap from "cap".
+ */
+    static void
+normal_search(cap, dir, pat, opt)
+    cmdarg_T	*cap;
+    int		dir;
+    char_u	*pat;
+    int		opt;		/* extra flags for do_search() */
+{
+    int		i;
+
+    cap->oap->motion_type = MCHAR;
+    cap->oap->inclusive = FALSE;
+    cap->oap->use_reg_one = TRUE;
+    curwin->w_set_curswant = TRUE;
+
+    i = do_search(cap->oap, dir, pat, cap->count1,
+				 opt | SEARCH_OPT | SEARCH_ECHO | SEARCH_MSG);
+    if (i == 0)
+	clearop(cap->oap);
+    else
+    {
+	if (i == 2)
+	    cap->oap->motion_type = MLINE;
+#ifdef FEAT_VIRTUALEDIT
+	curwin->w_cursor.coladd = 0;
+#endif
+#ifdef FEAT_FOLDING
+	if (cap->oap->op_type == OP_NOP && (fdo_flags & FDO_SEARCH) && KeyTyped)
+	    foldOpenCursor();
+#endif
+    }
+
+    /* "/$" will put the cursor after the end of the line, may need to
+     * correct that here */
+    check_cursor();
+}
+
+/*
+ * Character search commands.
+ * cap->arg is BACKWARD for 'F' and 'T', FORWARD for 'f' and 't', TRUE for
+ * ',' and FALSE for ';'.
+ * cap->nchar is NUL for ',' and ';' (repeat the search)
+ */
+    static void
+nv_csearch(cap)
+    cmdarg_T	*cap;
+{
+    int		t_cmd;
+
+    if (cap->cmdchar == 't' || cap->cmdchar == 'T')
+	t_cmd = TRUE;
+    else
+	t_cmd = FALSE;
+
+    cap->oap->motion_type = MCHAR;
+    if (IS_SPECIAL(cap->nchar) || searchc(cap, t_cmd) == FAIL)
+	clearopbeep(cap->oap);
+    else
+    {
+	curwin->w_set_curswant = TRUE;
+#ifdef FEAT_VIRTUALEDIT
+	/* Include a Tab for "tx" and for "dfx". */
+	if (gchar_cursor() == TAB && virtual_active() && cap->arg == FORWARD
+		&& (t_cmd || cap->oap->op_type != OP_NOP))
+	{
+	    colnr_T	scol, ecol;
+
+	    getvcol(curwin, &curwin->w_cursor, &scol, NULL, &ecol);
+	    curwin->w_cursor.coladd = ecol - scol;
+	}
+	else
+	    curwin->w_cursor.coladd = 0;
+#endif
+#ifdef FEAT_VISUAL
+	adjust_for_sel(cap);
+#endif
+#ifdef FEAT_FOLDING
+	if ((fdo_flags & FDO_HOR) && KeyTyped && cap->oap->op_type == OP_NOP)
+	    foldOpenCursor();
+#endif
+    }
+}
+
+/*
+ * "[" and "]" commands.
+ * cap->arg is BACKWARD for "[" and FORWARD for "]".
+ */
+    static void
+nv_brackets(cap)
+    cmdarg_T	*cap;
+{
+    pos_T	new_pos;
+    pos_T	prev_pos;
+    pos_T	*pos = NULL;	    /* init for GCC */
+    pos_T	old_pos;	    /* cursor position before command */
+    int		flag;
+    long	n;
+    int		findc;
+    int		c;
+
+    cap->oap->motion_type = MCHAR;
+    cap->oap->inclusive = FALSE;
+    old_pos = curwin->w_cursor;
+#ifdef FEAT_VIRTUALEDIT
+    curwin->w_cursor.coladd = 0;	    /* TODO: don't do this for an error. */
+#endif
+
+#ifdef FEAT_SEARCHPATH
+    /*
+     * "[f" or "]f" : Edit file under the cursor (same as "gf")
+     */
+    if (cap->nchar == 'f')
+	nv_gotofile(cap);
+    else
+#endif
+
+#ifdef FEAT_FIND_ID
+    /*
+     * Find the occurrence(s) of the identifier or define under cursor
+     * in current and included files or jump to the first occurrence.
+     *
+     *			search	     list	    jump
+     *		      fwd   bwd    fwd	 bwd	 fwd	bwd
+     * identifier     "]i"  "[i"   "]I"  "[I"	"]^I"  "[^I"
+     * define	      "]d"  "[d"   "]D"  "[D"	"]^D"  "[^D"
+     */
+    if (vim_strchr((char_u *)
+#ifdef EBCDIC
+		"iI\005dD\067",
+#else
+		"iI\011dD\004",
+#endif
+		cap->nchar) != NULL)
+    {
+	char_u	*ptr;
+	int	len;
+
+	if ((len = find_ident_under_cursor(&ptr, FIND_IDENT)) == 0)
+	    clearop(cap->oap);
+	else
+	{
+	    find_pattern_in_path(ptr, 0, len, TRUE,
+		cap->count0 == 0 ? !isupper(cap->nchar) : FALSE,
+		((cap->nchar & 0xf) == ('d' & 0xf)) ?  FIND_DEFINE : FIND_ANY,
+		cap->count1,
+		isupper(cap->nchar) ? ACTION_SHOW_ALL :
+			    islower(cap->nchar) ? ACTION_SHOW : ACTION_GOTO,
+		cap->cmdchar == ']' ? curwin->w_cursor.lnum + 1 : (linenr_T)1,
+		(linenr_T)MAXLNUM);
+	    curwin->w_set_curswant = TRUE;
+	}
+    }
+    else
+#endif
+
+    /*
+     * "[{", "[(", "]}" or "])": go to Nth unclosed '{', '(', '}' or ')'
+     * "[#", "]#": go to start/end of Nth innermost #if..#endif construct.
+     * "[/", "[*", "]/", "]*": go to Nth comment start/end.
+     * "[m" or "]m" search for prev/next start of (Java) method.
+     * "[M" or "]M" search for prev/next end of (Java) method.
+     */
+    if (  (cap->cmdchar == '['
+		&& vim_strchr((char_u *)"{(*/#mM", cap->nchar) != NULL)
+	    || (cap->cmdchar == ']'
+		&& vim_strchr((char_u *)"})*/#mM", cap->nchar) != NULL))
+    {
+	if (cap->nchar == '*')
+	    cap->nchar = '/';
+	new_pos.lnum = 0;
+	prev_pos.lnum = 0;
+	if (cap->nchar == 'm' || cap->nchar == 'M')
+	{
+	    if (cap->cmdchar == '[')
+		findc = '{';
+	    else
+		findc = '}';
+	    n = 9999;
+	}
+	else
+	{
+	    findc = cap->nchar;
+	    n = cap->count1;
+	}
+	for ( ; n > 0; --n)
+	{
+	    if ((pos = findmatchlimit(cap->oap, findc,
+		(cap->cmdchar == '[') ? FM_BACKWARD : FM_FORWARD, 0)) == NULL)
+	    {
+		if (new_pos.lnum == 0)	/* nothing found */
+		{
+		    if (cap->nchar != 'm' && cap->nchar != 'M')
+			clearopbeep(cap->oap);
+		}
+		else
+		    pos = &new_pos;	/* use last one found */
+		break;
+	    }
+	    prev_pos = new_pos;
+	    curwin->w_cursor = *pos;
+	    new_pos = *pos;
+	}
+	curwin->w_cursor = old_pos;
+
+	/*
+	 * Handle "[m", "]m", "[M" and "[M".  The findmatchlimit() only
+	 * brought us to the match for "[m" and "]M" when inside a method.
+	 * Try finding the '{' or '}' we want to be at.
+	 * Also repeat for the given count.
+	 */
+	if (cap->nchar == 'm' || cap->nchar == 'M')
+	{
+	    /* norm is TRUE for "]M" and "[m" */
+	    int	    norm = ((findc == '{') == (cap->nchar == 'm'));
+
+	    n = cap->count1;
+	    /* found a match: we were inside a method */
+	    if (prev_pos.lnum != 0)
+	    {
+		pos = &prev_pos;
+		curwin->w_cursor = prev_pos;
+		if (norm)
+		    --n;
+	    }
+	    else
+		pos = NULL;
+	    while (n > 0)
+	    {
+		for (;;)
+		{
+		    if ((findc == '{' ? dec_cursor() : inc_cursor()) < 0)
+		    {
+			/* if not found anything, that's an error */
+			if (pos == NULL)
+			    clearopbeep(cap->oap);
+			n = 0;
+			break;
+		    }
+		    c = gchar_cursor();
+		    if (c == '{' || c == '}')
+		    {
+			/* Must have found end/start of class: use it.
+			 * Or found the place to be at. */
+			if ((c == findc && norm) || (n == 1 && !norm))
+			{
+			    new_pos = curwin->w_cursor;
+			    pos = &new_pos;
+			    n = 0;
+			}
+			/* if no match found at all, we started outside of the
+			 * class and we're inside now.  Just go on. */
+			else if (new_pos.lnum == 0)
+			{
+			    new_pos = curwin->w_cursor;
+			    pos = &new_pos;
+			}
+			/* found start/end of other method: go to match */
+			else if ((pos = findmatchlimit(cap->oap, findc,
+			    (cap->cmdchar == '[') ? FM_BACKWARD : FM_FORWARD,
+								  0)) == NULL)
+			    n = 0;
+			else
+			    curwin->w_cursor = *pos;
+			break;
+		    }
+		}
+		--n;
+	    }
+	    curwin->w_cursor = old_pos;
+	    if (pos == NULL && new_pos.lnum != 0)
+		clearopbeep(cap->oap);
+	}
+	if (pos != NULL)
+	{
+	    setpcmark();
+	    curwin->w_cursor = *pos;
+	    curwin->w_set_curswant = TRUE;
+#ifdef FEAT_FOLDING
+	    if ((fdo_flags & FDO_BLOCK) && KeyTyped
+					       && cap->oap->op_type == OP_NOP)
+		foldOpenCursor();
+#endif
+	}
+    }
+
+    /*
+     * "[[", "[]", "]]" and "][": move to start or end of function
+     */
+    else if (cap->nchar == '[' || cap->nchar == ']')
+    {
+	if (cap->nchar == cap->cmdchar)		    /* "]]" or "[[" */
+	    flag = '{';
+	else
+	    flag = '}';		    /* "][" or "[]" */
+
+	curwin->w_set_curswant = TRUE;
+	/*
+	 * Imitate strange Vi behaviour: When using "]]" with an operator
+	 * we also stop at '}'.
+	 */
+	if (!findpar(&cap->oap->inclusive, cap->arg, cap->count1, flag,
+	      (cap->oap->op_type != OP_NOP
+				      && cap->arg == FORWARD && flag == '{')))
+	    clearopbeep(cap->oap);
+	else
+	{
+	    if (cap->oap->op_type == OP_NOP)
+		beginline(BL_WHITE | BL_FIX);
+#ifdef FEAT_FOLDING
+	    if ((fdo_flags & FDO_BLOCK) && KeyTyped && cap->oap->op_type == OP_NOP)
+		foldOpenCursor();
+#endif
+	}
+    }
+
+    /*
+     * "[p", "[P", "]P" and "]p": put with indent adjustment
+     */
+    else if (cap->nchar == 'p' || cap->nchar == 'P')
+    {
+	if (!checkclearopq(cap->oap))
+	{
+	    prep_redo_cmd(cap);
+	    do_put(cap->oap->regname,
+	      (cap->cmdchar == ']' && cap->nchar == 'p') ? FORWARD : BACKWARD,
+						  cap->count1, PUT_FIXINDENT);
+	}
+    }
+
+    /*
+     * "['", "[`", "]'" and "]`": jump to next mark
+     */
+    else if (cap->nchar == '\'' || cap->nchar == '`')
+    {
+	pos = &curwin->w_cursor;
+	for (n = cap->count1; n > 0; --n)
+	{
+	    prev_pos = *pos;
+	    pos = getnextmark(pos, cap->cmdchar == '[' ? BACKWARD : FORWARD,
+							  cap->nchar == '\'');
+	    if (pos == NULL)
+		break;
+	}
+	if (pos == NULL)
+	    pos = &prev_pos;
+	nv_cursormark(cap, cap->nchar == '\'', pos);
+    }
+
+#ifdef FEAT_MOUSE
+    /*
+     * [ or ] followed by a middle mouse click: put selected text with
+     * indent adjustment.  Any other button just does as usual.
+     */
+    else if (cap->nchar >= K_LEFTMOUSE && cap->nchar <= K_RIGHTRELEASE)
+    {
+	(void)do_mouse(cap->oap, cap->nchar,
+		       (cap->cmdchar == ']') ? FORWARD : BACKWARD,
+		       cap->count1, PUT_FIXINDENT);
+    }
+#endif /* FEAT_MOUSE */
+
+#ifdef FEAT_FOLDING
+    /*
+     * "[z" and "]z": move to start or end of open fold.
+     */
+    else if (cap->nchar == 'z')
+    {
+	if (foldMoveTo(FALSE, cap->cmdchar == ']' ? FORWARD : BACKWARD,
+							 cap->count1) == FAIL)
+	    clearopbeep(cap->oap);
+    }
+#endif
+
+#ifdef FEAT_DIFF
+    /*
+     * "[c" and "]c": move to next or previous diff-change.
+     */
+    else if (cap->nchar == 'c')
+    {
+	if (diff_move_to(cap->cmdchar == ']' ? FORWARD : BACKWARD,
+							 cap->count1) == FAIL)
+	    clearopbeep(cap->oap);
+    }
+#endif
+
+#ifdef FEAT_SPELL
+    /*
+     * "[s", "[S", "]s" and "]S": move to next spell error.
+     */
+    else if (cap->nchar == 's' || cap->nchar == 'S')
+    {
+	setpcmark();
+	for (n = 0; n < cap->count1; ++n)
+	    if (spell_move_to(curwin, cap->cmdchar == ']' ? FORWARD : BACKWARD,
+			  cap->nchar == 's' ? TRUE : FALSE, FALSE, NULL) == 0)
+	    {
+		clearopbeep(cap->oap);
+		break;
+	    }
+# ifdef FEAT_FOLDING
+	if (cap->oap->op_type == OP_NOP && (fdo_flags & FDO_SEARCH) && KeyTyped)
+	    foldOpenCursor();
+# endif
+    }
+#endif
+
+    /* Not a valid cap->nchar. */
+    else
+	clearopbeep(cap->oap);
+}
+
+/*
+ * Handle Normal mode "%" command.
+ */
+    static void
+nv_percent(cap)
+    cmdarg_T	*cap;
+{
+    pos_T	*pos;
+#ifdef FEAT_FOLDING
+    linenr_T	lnum = curwin->w_cursor.lnum;
+#endif
+
+    cap->oap->inclusive = TRUE;
+    if (cap->count0)	    /* {cnt}% : goto {cnt} percentage in file */
+    {
+	if (cap->count0 > 100)
+	    clearopbeep(cap->oap);
+	else
+	{
+	    cap->oap->motion_type = MLINE;
+	    setpcmark();
+	    /* Round up, so CTRL-G will give same value.  Watch out for a
+	     * large line count, the line number must not go negative! */
+	    if (curbuf->b_ml.ml_line_count > 1000000)
+		curwin->w_cursor.lnum = (curbuf->b_ml.ml_line_count + 99L)
+							 / 100L * cap->count0;
+	    else
+		curwin->w_cursor.lnum = (curbuf->b_ml.ml_line_count *
+						    cap->count0 + 99L) / 100L;
+	    if (curwin->w_cursor.lnum > curbuf->b_ml.ml_line_count)
+		curwin->w_cursor.lnum = curbuf->b_ml.ml_line_count;
+	    beginline(BL_SOL | BL_FIX);
+	}
+    }
+    else		    /* "%" : go to matching paren */
+    {
+	cap->oap->motion_type = MCHAR;
+	cap->oap->use_reg_one = TRUE;
+	if ((pos = findmatch(cap->oap, NUL)) == NULL)
+	    clearopbeep(cap->oap);
+	else
+	{
+	    setpcmark();
+	    curwin->w_cursor = *pos;
+	    curwin->w_set_curswant = TRUE;
+#ifdef FEAT_VIRTUALEDIT
+	    curwin->w_cursor.coladd = 0;
+#endif
+#ifdef FEAT_VISUAL
+	    adjust_for_sel(cap);
+#endif
+	}
+    }
+#ifdef FEAT_FOLDING
+    if (cap->oap->op_type == OP_NOP
+	    && lnum != curwin->w_cursor.lnum
+	    && (fdo_flags & FDO_PERCENT)
+	    && KeyTyped)
+	foldOpenCursor();
+#endif
+}
+
+/*
+ * Handle "(" and ")" commands.
+ * cap->arg is BACKWARD for "(" and FORWARD for ")".
+ */
+    static void
+nv_brace(cap)
+    cmdarg_T	*cap;
+{
+    cap->oap->motion_type = MCHAR;
+    cap->oap->use_reg_one = TRUE;
+    /* The motion used to be inclusive for "(", but that is not what Vi does. */
+    cap->oap->inclusive = FALSE;
+    curwin->w_set_curswant = TRUE;
+
+    if (findsent(cap->arg, cap->count1) == FAIL)
+	clearopbeep(cap->oap);
+    else
+    {
+#ifdef FEAT_VIRTUALEDIT
+	curwin->w_cursor.coladd = 0;
+#endif
+#ifdef FEAT_FOLDING
+	if ((fdo_flags & FDO_BLOCK) && KeyTyped && cap->oap->op_type == OP_NOP)
+	    foldOpenCursor();
+#endif
+    }
+}
+
+/*
+ * "m" command: Mark a position.
+ */
+    static void
+nv_mark(cap)
+    cmdarg_T	*cap;
+{
+    if (!checkclearop(cap->oap))
+    {
+	if (setmark(cap->nchar) == FAIL)
+	    clearopbeep(cap->oap);
+    }
+}
+
+/*
+ * "{" and "}" commands.
+ * cmd->arg is BACKWARD for "{" and FORWARD for "}".
+ */
+    static void
+nv_findpar(cap)
+    cmdarg_T	*cap;
+{
+    cap->oap->motion_type = MCHAR;
+    cap->oap->inclusive = FALSE;
+    cap->oap->use_reg_one = TRUE;
+    curwin->w_set_curswant = TRUE;
+    if (!findpar(&cap->oap->inclusive, cap->arg, cap->count1, NUL, FALSE))
+	clearopbeep(cap->oap);
+    else
+    {
+#ifdef FEAT_VIRTUALEDIT
+	curwin->w_cursor.coladd = 0;
+#endif
+#ifdef FEAT_FOLDING
+	if ((fdo_flags & FDO_BLOCK) && KeyTyped && cap->oap->op_type == OP_NOP)
+	    foldOpenCursor();
+#endif
+    }
+}
+
+/*
+ * "u" command: Undo or make lower case.
+ */
+    static void
+nv_undo(cap)
+    cmdarg_T	*cap;
+{
+    if (cap->oap->op_type == OP_LOWER
+#ifdef FEAT_VISUAL
+	    || VIsual_active
+#endif
+	    )
+    {
+	/* translate "<Visual>u" to "<Visual>gu" and "guu" to "gugu" */
+	cap->cmdchar = 'g';
+	cap->nchar = 'u';
+	nv_operator(cap);
+    }
+    else
+	nv_kundo(cap);
+}
+
+/*
+ * <Undo> command.
+ */
+    static void
+nv_kundo(cap)
+    cmdarg_T	*cap;
+{
+    if (!checkclearopq(cap->oap))
+    {
+	u_undo((int)cap->count1);
+	curwin->w_set_curswant = TRUE;
+    }
+}
+
+/*
+ * Handle the "r" command.
+ */
+    static void
+nv_replace(cap)
+    cmdarg_T	*cap;
+{
+    char_u	*ptr;
+    int		had_ctrl_v;
+    long	n;
+
+    if (checkclearop(cap->oap))
+	return;
+
+    /* get another character */
+    if (cap->nchar == Ctrl_V)
+    {
+	had_ctrl_v = Ctrl_V;
+	cap->nchar = get_literal();
+	/* Don't redo a multibyte character with CTRL-V. */
+	if (cap->nchar > DEL)
+	    had_ctrl_v = NUL;
+    }
+    else
+	had_ctrl_v = NUL;
+
+#ifdef FEAT_VISUAL
+    /* Visual mode "r" */
+    if (VIsual_active)
+    {
+	nv_operator(cap);
+	return;
+    }
+#endif
+
+#ifdef FEAT_VIRTUALEDIT
+    /* Break tabs, etc. */
+    if (virtual_active())
+    {
+	if (u_save_cursor() == FAIL)
+	    return;
+	if (gchar_cursor() == NUL)
+	{
+	    /* Add extra space and put the cursor on the first one. */
+	    coladvance_force((colnr_T)(getviscol() + cap->count1));
+	    curwin->w_cursor.col -= cap->count1;
+	}
+	else if (gchar_cursor() == TAB)
+	    coladvance_force(getviscol());
+    }
+#endif
+
+    /*
+     * Check for a special key or not enough characters to replace.
+     */
+    ptr = ml_get_cursor();
+    if (IS_SPECIAL(cap->nchar) || STRLEN(ptr) < (unsigned)cap->count1
+#ifdef FEAT_MBYTE
+	    || (has_mbyte && mb_charlen(ptr) < cap->count1)
+#endif
+	    )
+    {
+	clearopbeep(cap->oap);
+	return;
+    }
+
+    /*
+     * Replacing with a TAB is done by edit() when it is complicated because
+     * 'expandtab' or 'smarttab' is set.  CTRL-V TAB inserts a literal TAB.
+     * Other characters are done below to avoid problems with things like
+     * CTRL-V 048 (for edit() this would be R CTRL-V 0 ESC).
+     */
+    if (had_ctrl_v != Ctrl_V && cap->nchar == '\t' && (curbuf->b_p_et || p_sta))
+    {
+	stuffnumReadbuff(cap->count1);
+	stuffcharReadbuff('R');
+	stuffcharReadbuff('\t');
+	stuffcharReadbuff(ESC);
+	return;
+    }
+
+    /* save line for undo */
+    if (u_save_cursor() == FAIL)
+	return;
+
+    if (had_ctrl_v != Ctrl_V && (cap->nchar == '\r' || cap->nchar == '\n'))
+    {
+	/*
+	 * Replace character(s) by a single newline.
+	 * Strange vi behaviour: Only one newline is inserted.
+	 * Delete the characters here.
+	 * Insert the newline with an insert command, takes care of
+	 * autoindent.	The insert command depends on being on the last
+	 * character of a line or not.
+	 */
+#ifdef FEAT_MBYTE
+	(void)del_chars(cap->count1, FALSE);	/* delete the characters */
+#else
+	(void)del_bytes(cap->count1, FALSE, FALSE); /* delete the characters */
+#endif
+	stuffcharReadbuff('\r');
+	stuffcharReadbuff(ESC);
+
+	/* Give 'r' to edit(), to get the redo command right. */
+	invoke_edit(cap, TRUE, 'r', FALSE);
+    }
+    else
+    {
+	prep_redo(cap->oap->regname, cap->count1,
+				       NUL, 'r', NUL, had_ctrl_v, cap->nchar);
+
+	curbuf->b_op_start = curwin->w_cursor;
+#ifdef FEAT_MBYTE
+	if (has_mbyte)
+	{
+	    int		old_State = State;
+
+	    if (cap->ncharC1 != 0)
+		AppendCharToRedobuff(cap->ncharC1);
+	    if (cap->ncharC2 != 0)
+		AppendCharToRedobuff(cap->ncharC2);
+
+	    /* This is slow, but it handles replacing a single-byte with a
+	     * multi-byte and the other way around.  Also handles adding
+	     * composing characters for utf-8. */
+	    for (n = cap->count1; n > 0; --n)
+	    {
+		State = REPLACE;
+		ins_char(cap->nchar);
+		State = old_State;
+		if (cap->ncharC1 != 0)
+		    ins_char(cap->ncharC1);
+		if (cap->ncharC2 != 0)
+		    ins_char(cap->ncharC2);
+	    }
+	}
+	else
+#endif
+	{
+	    /*
+	     * Replace the characters within one line.
+	     */
+	    for (n = cap->count1; n > 0; --n)
+	    {
+		/*
+		 * Get ptr again, because u_save and/or showmatch() will have
+		 * released the line.  At the same time we let know that the
+		 * line will be changed.
+		 */
+		ptr = ml_get_buf(curbuf, curwin->w_cursor.lnum, TRUE);
+		ptr[curwin->w_cursor.col] = cap->nchar;
+		if (p_sm && msg_silent == 0)
+		    showmatch(cap->nchar);
+		++curwin->w_cursor.col;
+	    }
+#ifdef FEAT_NETBEANS_INTG
+	    if (usingNetbeans)
+	    {
+		colnr_T start = (colnr_T)(curwin->w_cursor.col - cap->count1);
+
+		netbeans_removed(curbuf, curwin->w_cursor.lnum, start,
+							    (long)cap->count1);
+		netbeans_inserted(curbuf, curwin->w_cursor.lnum, start,
+					       &ptr[start], (int)cap->count1);
+	    }
+#endif
+
+	    /* mark the buffer as changed and prepare for displaying */
+	    changed_bytes(curwin->w_cursor.lnum,
+			       (colnr_T)(curwin->w_cursor.col - cap->count1));
+	}
+	--curwin->w_cursor.col;	    /* cursor on the last replaced char */
+#ifdef FEAT_MBYTE
+	/* if the character on the left of the current cursor is a multi-byte
+	 * character, move two characters left */
+	if (has_mbyte)
+	    mb_adjust_cursor();
+#endif
+	curbuf->b_op_end = curwin->w_cursor;
+	curwin->w_set_curswant = TRUE;
+	set_last_insert(cap->nchar);
+    }
+}
+
+#ifdef FEAT_VISUAL
+/*
+ * 'o': Exchange start and end of Visual area.
+ * 'O': same, but in block mode exchange left and right corners.
+ */
+    static void
+v_swap_corners(cmdchar)
+    int		cmdchar;
+{
+    pos_T	old_cursor;
+    colnr_T	left, right;
+
+    if (cmdchar == 'O' && VIsual_mode == Ctrl_V)
+    {
+	old_cursor = curwin->w_cursor;
+	getvcols(curwin, &old_cursor, &VIsual, &left, &right);
+	curwin->w_cursor.lnum = VIsual.lnum;
+	coladvance(left);
+	VIsual = curwin->w_cursor;
+
+	curwin->w_cursor.lnum = old_cursor.lnum;
+	curwin->w_curswant = right;
+	/* 'selection "exclusive" and cursor at right-bottom corner: move it
+	 * right one column */
+	if (old_cursor.lnum >= VIsual.lnum && *p_sel == 'e')
+	    ++curwin->w_curswant;
+	coladvance(curwin->w_curswant);
+	if (curwin->w_cursor.col == old_cursor.col
+#ifdef FEAT_VIRTUALEDIT
+		&& (!virtual_active()
+		    || curwin->w_cursor.coladd == old_cursor.coladd)
+#endif
+		)
+	{
+	    curwin->w_cursor.lnum = VIsual.lnum;
+	    if (old_cursor.lnum <= VIsual.lnum && *p_sel == 'e')
+		++right;
+	    coladvance(right);
+	    VIsual = curwin->w_cursor;
+
+	    curwin->w_cursor.lnum = old_cursor.lnum;
+	    coladvance(left);
+	    curwin->w_curswant = left;
+	}
+    }
+    else
+    {
+	old_cursor = curwin->w_cursor;
+	curwin->w_cursor = VIsual;
+	VIsual = old_cursor;
+	curwin->w_set_curswant = TRUE;
+    }
+}
+#endif /* FEAT_VISUAL */
+
+/*
+ * "R" (cap->arg is FALSE) and "gR" (cap->arg is TRUE).
+ */
+    static void
+nv_Replace(cap)
+    cmdarg_T	    *cap;
+{
+#ifdef FEAT_VISUAL
+    if (VIsual_active)		/* "R" is replace lines */
+    {
+	cap->cmdchar = 'c';
+	cap->nchar = NUL;
+	VIsual_mode = 'V';
+	nv_operator(cap);
+    }
+    else
+#endif
+	if (!checkclearopq(cap->oap))
+    {
+	if (!curbuf->b_p_ma)
+	    EMSG(_(e_modifiable));
+	else
+	{
+#ifdef FEAT_VIRTUALEDIT
+	    if (virtual_active())
+		coladvance(getviscol());
+#endif
+	    invoke_edit(cap, FALSE, cap->arg ? 'V' : 'R', FALSE);
+	}
+    }
+}
+
+#ifdef FEAT_VREPLACE
+/*
+ * "gr".
+ */
+    static void
+nv_vreplace(cap)
+    cmdarg_T	*cap;
+{
+# ifdef FEAT_VISUAL
+    if (VIsual_active)
+    {
+	cap->cmdchar = 'r';
+	cap->nchar = cap->extra_char;
+	nv_replace(cap);	/* Do same as "r" in Visual mode for now */
+    }
+    else
+# endif
+	if (!checkclearopq(cap->oap))
+    {
+	if (!curbuf->b_p_ma)
+	    EMSG(_(e_modifiable));
+	else
+	{
+	    if (cap->extra_char == Ctrl_V)	/* get another character */
+		cap->extra_char = get_literal();
+	    stuffcharReadbuff(cap->extra_char);
+	    stuffcharReadbuff(ESC);
+# ifdef FEAT_VIRTUALEDIT
+	    if (virtual_active())
+		coladvance(getviscol());
+# endif
+	    invoke_edit(cap, TRUE, 'v', FALSE);
+	}
+    }
+}
+#endif
+
+/*
+ * Swap case for "~" command, when it does not work like an operator.
+ */
+    static void
+n_swapchar(cap)
+    cmdarg_T	*cap;
+{
+    long	n;
+    pos_T	startpos;
+    int		did_change = 0;
+#ifdef FEAT_NETBEANS_INTG
+    pos_T	pos;
+    char_u	*ptr;
+    int		count;
+#endif
+
+    if (checkclearopq(cap->oap))
+	return;
+
+    if (lineempty(curwin->w_cursor.lnum) && vim_strchr(p_ww, '~') == NULL)
+    {
+	clearopbeep(cap->oap);
+	return;
+    }
+
+    prep_redo_cmd(cap);
+
+    if (u_save_cursor() == FAIL)
+	return;
+
+    startpos = curwin->w_cursor;
+#ifdef FEAT_NETBEANS_INTG
+    pos = startpos;
+#endif
+    for (n = cap->count1; n > 0; --n)
+    {
+	did_change |= swapchar(cap->oap->op_type, &curwin->w_cursor);
+	inc_cursor();
+	if (gchar_cursor() == NUL)
+	{
+	    if (vim_strchr(p_ww, '~') != NULL
+		    && curwin->w_cursor.lnum < curbuf->b_ml.ml_line_count)
+	    {
+#ifdef FEAT_NETBEANS_INTG
+		if (usingNetbeans)
+		{
+		    if (did_change)
+		    {
+			ptr = ml_get(pos.lnum);
+			count = (int)STRLEN(ptr) - pos.col;
+			netbeans_removed(curbuf, pos.lnum, pos.col,
+								 (long)count);
+			netbeans_inserted(curbuf, pos.lnum, pos.col,
+							&ptr[pos.col], count);
+		    }
+		    pos.col = 0;
+		    pos.lnum++;
+		}
+#endif
+		++curwin->w_cursor.lnum;
+		curwin->w_cursor.col = 0;
+		if (n > 1)
+		{
+		    if (u_savesub(curwin->w_cursor.lnum) == FAIL)
+			break;
+		    u_clearline();
+		}
+	    }
+	    else
+		break;
+	}
+    }
+#ifdef FEAT_NETBEANS_INTG
+    if (did_change && usingNetbeans)
+    {
+	ptr = ml_get(pos.lnum);
+	count = curwin->w_cursor.col - pos.col;
+	netbeans_removed(curbuf, pos.lnum, pos.col, (long)count);
+	netbeans_inserted(curbuf, pos.lnum, pos.col, &ptr[pos.col], count);
+    }
+#endif
+
+
+    check_cursor();
+    curwin->w_set_curswant = TRUE;
+    if (did_change)
+    {
+	changed_lines(startpos.lnum, startpos.col, curwin->w_cursor.lnum + 1,
+									  0L);
+	curbuf->b_op_start = startpos;
+	curbuf->b_op_end = curwin->w_cursor;
+	if (curbuf->b_op_end.col > 0)
+	    --curbuf->b_op_end.col;
+    }
+}
+
+/*
+ * Move cursor to mark.
+ */
+    static void
+nv_cursormark(cap, flag, pos)
+    cmdarg_T	*cap;
+    int		flag;
+    pos_T	*pos;
+{
+    if (check_mark(pos) == FAIL)
+	clearop(cap->oap);
+    else
+    {
+	if (cap->cmdchar == '\''
+		|| cap->cmdchar == '`'
+		|| cap->cmdchar == '['
+		|| cap->cmdchar == ']')
+	    setpcmark();
+	curwin->w_cursor = *pos;
+	if (flag)
+	    beginline(BL_WHITE | BL_FIX);
+	else
+	    check_cursor();
+    }
+    cap->oap->motion_type = flag ? MLINE : MCHAR;
+    if (cap->cmdchar == '`')
+	cap->oap->use_reg_one = TRUE;
+    cap->oap->inclusive = FALSE;		/* ignored if not MCHAR */
+    curwin->w_set_curswant = TRUE;
+}
+
+#ifdef FEAT_VISUAL
+/*
+ * Handle commands that are operators in Visual mode.
+ */
+    static void
+v_visop(cap)
+    cmdarg_T	*cap;
+{
+    static char_u trans[] = "YyDdCcxdXdAAIIrr";
+
+    /* Uppercase means linewise, except in block mode, then "D" deletes till
+     * the end of the line, and "C" replaces til EOL */
+    if (isupper(cap->cmdchar))
+    {
+	if (VIsual_mode != Ctrl_V)
+	    VIsual_mode = 'V';
+	else if (cap->cmdchar == 'C' || cap->cmdchar == 'D')
+	    curwin->w_curswant = MAXCOL;
+    }
+    cap->cmdchar = *(vim_strchr(trans, cap->cmdchar) + 1);
+    nv_operator(cap);
+}
+#endif
+
+/*
+ * "s" and "S" commands.
+ */
+    static void
+nv_subst(cap)
+    cmdarg_T	*cap;
+{
+#ifdef FEAT_VISUAL
+    if (VIsual_active)	/* "vs" and "vS" are the same as "vc" */
+    {
+	if (cap->cmdchar == 'S')
+	    VIsual_mode = 'V';
+	cap->cmdchar = 'c';
+	nv_operator(cap);
+    }
+    else
+#endif
+	nv_optrans(cap);
+}
+
+/*
+ * Abbreviated commands.
+ */
+    static void
+nv_abbrev(cap)
+    cmdarg_T	*cap;
+{
+    if (cap->cmdchar == K_DEL || cap->cmdchar == K_KDEL)
+	cap->cmdchar = 'x';		/* DEL key behaves like 'x' */
+
+#ifdef FEAT_VISUAL
+    /* in Visual mode these commands are operators */
+    if (VIsual_active)
+	v_visop(cap);
+    else
+#endif
+	nv_optrans(cap);
+}
+
+/*
+ * Translate a command into another command.
+ */
+    static void
+nv_optrans(cap)
+    cmdarg_T	*cap;
+{
+    static char_u *(ar[8]) = {(char_u *)"dl", (char_u *)"dh",
+			      (char_u *)"d$", (char_u *)"c$",
+			      (char_u *)"cl", (char_u *)"cc",
+			      (char_u *)"yy", (char_u *)":s\r"};
+    static char_u *str = (char_u *)"xXDCsSY&";
+
+    if (!checkclearopq(cap->oap))
+    {
+	/* In Vi "2D" doesn't delete the next line.  Can't translate it
+	 * either, because "2." should also not use the count. */
+	if (cap->cmdchar == 'D' && vim_strchr(p_cpo, CPO_HASH) != NULL)
+	{
+	    cap->oap->start = curwin->w_cursor;
+	    cap->oap->op_type = OP_DELETE;
+	    cap->count1 = 1;
+	    nv_dollar(cap);
+	    finish_op = TRUE;
+	    ResetRedobuff();
+	    AppendCharToRedobuff('D');
+	}
+	else
+	{
+	    if (cap->count0)
+		stuffnumReadbuff(cap->count0);
+	    stuffReadbuff(ar[(int)(vim_strchr(str, cap->cmdchar) - str)]);
+	}
+    }
+    cap->opcount = 0;
+}
+
+/*
+ * "'" and "`" commands.  Also for "g'" and "g`".
+ * cap->arg is TRUE for "'" and "g'".
+ */
+    static void
+nv_gomark(cap)
+    cmdarg_T	*cap;
+{
+    pos_T	*pos;
+    int		c;
+#ifdef FEAT_FOLDING
+    linenr_T	lnum = curwin->w_cursor.lnum;
+    int		old_KeyTyped = KeyTyped;    /* getting file may reset it */
+#endif
+
+    if (cap->cmdchar == 'g')
+	c = cap->extra_char;
+    else
+	c = cap->nchar;
+    pos = getmark(c, (cap->oap->op_type == OP_NOP));
+    if (pos == (pos_T *)-1)	    /* jumped to other file */
+    {
+	if (cap->arg)
+	{
+	    check_cursor_lnum();
+	    beginline(BL_WHITE | BL_FIX);
+	}
+	else
+	    check_cursor();
+    }
+    else
+	nv_cursormark(cap, cap->arg, pos);
+
+#ifdef FEAT_VIRTUALEDIT
+    /* May need to clear the coladd that a mark includes. */
+    if (!virtual_active())
+	curwin->w_cursor.coladd = 0;
+#endif
+#ifdef FEAT_FOLDING
+    if (cap->oap->op_type == OP_NOP
+	    && (pos == (pos_T *)-1 || lnum != curwin->w_cursor.lnum)
+	    && (fdo_flags & FDO_MARK)
+	    && old_KeyTyped)
+	foldOpenCursor();
+#endif
+}
+
+/*
+ * Handle CTRL-O, CTRL-I, "g;" and "g," commands.
+ */
+    static void
+nv_pcmark(cap)
+    cmdarg_T	*cap;
+{
+#ifdef FEAT_JUMPLIST
+    pos_T	*pos;
+# ifdef FEAT_FOLDING
+    linenr_T	lnum = curwin->w_cursor.lnum;
+    int		old_KeyTyped = KeyTyped;    /* getting file may reset it */
+# endif
+
+    if (!checkclearopq(cap->oap))
+    {
+	if (cap->cmdchar == 'g')
+	    pos = movechangelist((int)cap->count1);
+	else
+	    pos = movemark((int)cap->count1);
+	if (pos == (pos_T *)-1)		/* jump to other file */
+	{
+	    curwin->w_set_curswant = TRUE;
+	    check_cursor();
+	}
+	else if (pos != NULL)		    /* can jump */
+	    nv_cursormark(cap, FALSE, pos);
+	else if (cap->cmdchar == 'g')
+	{
+	    if (curbuf->b_changelistlen == 0)
+		EMSG(_("E664: changelist is empty"));
+	    else if (cap->count1 < 0)
+		EMSG(_("E662: At start of changelist"));
+	    else
+		EMSG(_("E663: At end of changelist"));
+	}
+	else
+	    clearopbeep(cap->oap);
+# ifdef FEAT_FOLDING
+	if (cap->oap->op_type == OP_NOP
+		&& (pos == (pos_T *)-1 || lnum != curwin->w_cursor.lnum)
+		&& (fdo_flags & FDO_MARK)
+		&& old_KeyTyped)
+	    foldOpenCursor();
+# endif
+    }
+#else
+    clearopbeep(cap->oap);
+#endif
+}
+
+/*
+ * Handle '"' command.
+ */
+    static void
+nv_regname(cap)
+    cmdarg_T	*cap;
+{
+    if (checkclearop(cap->oap))
+	return;
+#ifdef FEAT_EVAL
+    if (cap->nchar == '=')
+	cap->nchar = get_expr_register();
+#endif
+    if (cap->nchar != NUL && valid_yank_reg(cap->nchar, FALSE))
+    {
+	cap->oap->regname = cap->nchar;
+	cap->opcount = cap->count0;	/* remember count before '"' */
+#ifdef FEAT_EVAL
+	set_reg_var(cap->oap->regname);
+#endif
+    }
+    else
+	clearopbeep(cap->oap);
+}
+
+#ifdef FEAT_VISUAL
+/*
+ * Handle "v", "V" and "CTRL-V" commands.
+ * Also for "gh", "gH" and "g^H" commands: Always start Select mode, cap->arg
+ * is TRUE.
+ * Handle CTRL-Q just like CTRL-V.
+ */
+    static void
+nv_visual(cap)
+    cmdarg_T	*cap;
+{
+    if (cap->cmdchar == Ctrl_Q)
+	cap->cmdchar = Ctrl_V;
+
+    /* 'v', 'V' and CTRL-V can be used while an operator is pending to make it
+     * characterwise, linewise, or blockwise. */
+    if (cap->oap->op_type != OP_NOP)
+    {
+	cap->oap->motion_force = cap->cmdchar;
+	finish_op = FALSE;	/* operator doesn't finish now but later */
+	return;
+    }
+
+    VIsual_select = cap->arg;
+    if (VIsual_active)	    /* change Visual mode */
+    {
+	if (VIsual_mode == cap->cmdchar)    /* stop visual mode */
+	    end_visual_mode();
+	else				    /* toggle char/block mode */
+	{				    /*	   or char/line mode */
+	    VIsual_mode = cap->cmdchar;
+	    showmode();
+	}
+	redraw_curbuf_later(INVERTED);	    /* update the inversion */
+    }
+    else		    /* start Visual mode */
+    {
+	check_visual_highlight();
+	if (cap->count0)		    /* use previously selected part */
+	{
+	    if (resel_VIsual_mode == NUL)   /* there is none */
+	    {
+		beep_flush();
+		return;
+	    }
+	    VIsual = curwin->w_cursor;
+
+	    VIsual_active = TRUE;
+	    VIsual_reselect = TRUE;
+	    if (!cap->arg)
+		/* start Select mode when 'selectmode' contains "cmd" */
+		may_start_select('c');
+#ifdef FEAT_MOUSE
+	    setmouse();
+#endif
+	    if (p_smd && msg_silent == 0)
+		redraw_cmdline = TRUE;	    /* show visual mode later */
+	    /*
+	     * For V and ^V, we multiply the number of lines even if there
+	     * was only one -- webb
+	     */
+	    if (resel_VIsual_mode != 'v' || resel_VIsual_line_count > 1)
+	    {
+		curwin->w_cursor.lnum +=
+				    resel_VIsual_line_count * cap->count0 - 1;
+		if (curwin->w_cursor.lnum > curbuf->b_ml.ml_line_count)
+		    curwin->w_cursor.lnum = curbuf->b_ml.ml_line_count;
+	    }
+	    VIsual_mode = resel_VIsual_mode;
+	    if (VIsual_mode == 'v')
+	    {
+		if (resel_VIsual_line_count <= 1)
+		    curwin->w_cursor.col += resel_VIsual_col * cap->count0 - 1;
+		else
+		    curwin->w_cursor.col = resel_VIsual_col;
+		check_cursor_col();
+	    }
+	    if (resel_VIsual_col == MAXCOL)
+	    {
+		curwin->w_curswant = MAXCOL;
+		coladvance((colnr_T)MAXCOL);
+	    }
+	    else if (VIsual_mode == Ctrl_V)
+	    {
+		validate_virtcol();
+		curwin->w_curswant = curwin->w_virtcol
+					 + resel_VIsual_col * cap->count0 - 1;
+		coladvance(curwin->w_curswant);
+	    }
+	    else
+		curwin->w_set_curswant = TRUE;
+	    redraw_curbuf_later(INVERTED);	/* show the inversion */
+	}
+	else
+	{
+	    if (!cap->arg)
+		/* start Select mode when 'selectmode' contains "cmd" */
+		may_start_select('c');
+	    n_start_visual_mode(cap->cmdchar);
+	}
+    }
+}
+
+/*
+ * Start selection for Shift-movement keys.
+ */
+    void
+start_selection()
+{
+    /* if 'selectmode' contains "key", start Select mode */
+    may_start_select('k');
+    n_start_visual_mode('v');
+}
+
+/*
+ * Start Select mode, if "c" is in 'selectmode' and not in a mapping or menu.
+ */
+    void
+may_start_select(c)
+    int		c;
+{
+    VIsual_select = (stuff_empty() && typebuf_typed()
+		    && (vim_strchr(p_slm, c) != NULL));
+}
+
+/*
+ * Start Visual mode "c".
+ * Should set VIsual_select before calling this.
+ */
+    static void
+n_start_visual_mode(c)
+    int		c;
+{
+    VIsual_mode = c;
+    VIsual_active = TRUE;
+    VIsual_reselect = TRUE;
+#ifdef FEAT_VIRTUALEDIT
+    /* Corner case: the 0 position in a tab may change when going into
+     * virtualedit.  Recalculate curwin->w_cursor to avoid bad hilighting.
+     */
+    if (c == Ctrl_V && (ve_flags & VE_BLOCK) && gchar_cursor() == TAB)
+	coladvance(curwin->w_virtcol);
+#endif
+    VIsual = curwin->w_cursor;
+
+#ifdef FEAT_FOLDING
+    foldAdjustVisual();
+#endif
+
+#ifdef FEAT_MOUSE
+    setmouse();
+#endif
+    if (p_smd && msg_silent == 0)
+	redraw_cmdline = TRUE;	/* show visual mode later */
+#ifdef FEAT_CLIPBOARD
+    /* Make sure the clipboard gets updated.  Needed because start and
+     * end may still be the same, and the selection needs to be owned */
+    clip_star.vmode = NUL;
+#endif
+
+    /* Only need to redraw this line, unless still need to redraw an old
+     * Visual area (when 'lazyredraw' is set). */
+    if (curwin->w_redr_type < INVERTED)
+    {
+	curwin->w_old_cursor_lnum = curwin->w_cursor.lnum;
+	curwin->w_old_visual_lnum = curwin->w_cursor.lnum;
+    }
+}
+
+#endif /* FEAT_VISUAL */
+
+/*
+ * CTRL-W: Window commands
+ */
+    static void
+nv_window(cap)
+    cmdarg_T	*cap;
+{
+#ifdef FEAT_WINDOWS
+    if (!checkclearop(cap->oap))
+	do_window(cap->nchar, cap->count0, NUL); /* everything is in window.c */
+#else
+    (void)checkclearop(cap->oap);
+#endif
+}
+
+/*
+ * CTRL-Z: Suspend
+ */
+    static void
+nv_suspend(cap)
+    cmdarg_T	*cap;
+{
+    clearop(cap->oap);
+#ifdef FEAT_VISUAL
+    if (VIsual_active)
+	end_visual_mode();		/* stop Visual mode */
+#endif
+    do_cmdline_cmd((char_u *)"st");
+}
+
+/*
+ * Commands starting with "g".
+ */
+    static void
+nv_g_cmd(cap)
+    cmdarg_T	*cap;
+{
+    oparg_T	*oap = cap->oap;
+#ifdef FEAT_VISUAL
+    pos_T	tpos;
+#endif
+    int		i;
+    int		flag = FALSE;
+
+    switch (cap->nchar)
+    {
+#ifdef MEM_PROFILE
+    /*
+     * "g^A": dump log of used memory.
+     */
+    case Ctrl_A:
+	vim_mem_profile_dump();
+	break;
+#endif
+
+#ifdef FEAT_VREPLACE
+    /*
+     * "gR": Enter virtual replace mode.
+     */
+    case 'R':
+	cap->arg = TRUE;
+	nv_Replace(cap);
+	break;
+
+    case 'r':
+	nv_vreplace(cap);
+	break;
+#endif
+
+    case '&':
+	do_cmdline_cmd((char_u *)"%s//~/&");
+	break;
+
+#ifdef FEAT_VISUAL
+    /*
+     * "gv": Reselect the previous Visual area.  If Visual already active,
+     *	     exchange previous and current Visual area.
+     */
+    case 'v':
+	if (checkclearop(oap))
+	    break;
+
+	if (	   curbuf->b_visual.vi_start.lnum == 0
+		|| curbuf->b_visual.vi_start.lnum > curbuf->b_ml.ml_line_count
+		|| curbuf->b_visual.vi_end.lnum == 0)
+	    beep_flush();
+	else
+	{
+	    /* set w_cursor to the start of the Visual area, tpos to the end */
+	    if (VIsual_active)
+	    {
+		i = VIsual_mode;
+		VIsual_mode = curbuf->b_visual.vi_mode;
+		curbuf->b_visual.vi_mode = i;
+# ifdef FEAT_EVAL
+		curbuf->b_visual_mode_eval = i;
+# endif
+		i = curwin->w_curswant;
+		curwin->w_curswant = curbuf->b_visual.vi_curswant;
+		curbuf->b_visual.vi_curswant = i;
+
+		tpos = curbuf->b_visual.vi_end;
+		curbuf->b_visual.vi_end = curwin->w_cursor;
+		curwin->w_cursor = curbuf->b_visual.vi_start;
+		curbuf->b_visual.vi_start = VIsual;
+	    }
+	    else
+	    {
+		VIsual_mode = curbuf->b_visual.vi_mode;
+		curwin->w_curswant = curbuf->b_visual.vi_curswant;
+		tpos = curbuf->b_visual.vi_end;
+		curwin->w_cursor = curbuf->b_visual.vi_start;
+	    }
+
+	    VIsual_active = TRUE;
+	    VIsual_reselect = TRUE;
+
+	    /* Set Visual to the start and w_cursor to the end of the Visual
+	     * area.  Make sure they are on an existing character. */
+	    check_cursor();
+	    VIsual = curwin->w_cursor;
+	    curwin->w_cursor = tpos;
+	    check_cursor();
+	    update_topline();
+	    /*
+	     * When called from normal "g" command: start Select mode when
+	     * 'selectmode' contains "cmd".  When called for K_SELECT, always
+	     * start Select mode.
+	     */
+	    if (cap->arg)
+		VIsual_select = TRUE;
+	    else
+		may_start_select('c');
+#ifdef FEAT_MOUSE
+	    setmouse();
+#endif
+#ifdef FEAT_CLIPBOARD
+	    /* Make sure the clipboard gets updated.  Needed because start and
+	     * end are still the same, and the selection needs to be owned */
+	    clip_star.vmode = NUL;
+#endif
+	    redraw_curbuf_later(INVERTED);
+	    showmode();
+	}
+	break;
+    /*
+     * "gV": Don't reselect the previous Visual area after a Select mode
+     *	     mapping of menu.
+     */
+    case 'V':
+	VIsual_reselect = FALSE;
+	break;
+
+    /*
+     * "gh":  start Select mode.
+     * "gH":  start Select line mode.
+     * "g^H": start Select block mode.
+     */
+    case K_BS:
+	cap->nchar = Ctrl_H;
+	/* FALLTHROUGH */
+    case 'h':
+    case 'H':
+    case Ctrl_H:
+# ifdef EBCDIC
+	/* EBCDIC: 'v'-'h' != '^v'-'^h' */
+	if (cap->nchar == Ctrl_H)
+	    cap->cmdchar = Ctrl_V;
+	else
+# endif
+	cap->cmdchar = cap->nchar + ('v' - 'h');
+	cap->arg = TRUE;
+	nv_visual(cap);
+	break;
+#endif /* FEAT_VISUAL */
+
+    /*
+     * "gj" and "gk" two new funny movement keys -- up and down
+     * movement based on *screen* line rather than *file* line.
+     */
+    case 'j':
+    case K_DOWN:
+	/* with 'nowrap' it works just like the normal "j" command; also when
+	 * in a closed fold */
+	if (!curwin->w_p_wrap
+#ifdef FEAT_FOLDING
+		|| hasFolding(curwin->w_cursor.lnum, NULL, NULL)
+#endif
+		)
+	{
+	    oap->motion_type = MLINE;
+	    i = cursor_down(cap->count1, oap->op_type == OP_NOP);
+	}
+	else
+	    i = nv_screengo(oap, FORWARD, cap->count1);
+	if (i == FAIL)
+	    clearopbeep(oap);
+	break;
+
+    case 'k':
+    case K_UP:
+	/* with 'nowrap' it works just like the normal "k" command; also when
+	 * in a closed fold */
+	if (!curwin->w_p_wrap
+#ifdef FEAT_FOLDING
+		|| hasFolding(curwin->w_cursor.lnum, NULL, NULL)
+#endif
+	   )
+	{
+	    oap->motion_type = MLINE;
+	    i = cursor_up(cap->count1, oap->op_type == OP_NOP);
+	}
+	else
+	    i = nv_screengo(oap, BACKWARD, cap->count1);
+	if (i == FAIL)
+	    clearopbeep(oap);
+	break;
+
+    /*
+     * "gJ": join two lines without inserting a space.
+     */
+    case 'J':
+	nv_join(cap);
+	break;
+
+    /*
+     * "g0", "g^" and "g$": Like "0", "^" and "$" but for screen lines.
+     * "gm": middle of "g0" and "g$".
+     */
+    case '^':
+	flag = TRUE;
+	/* FALLTHROUGH */
+
+    case '0':
+    case 'm':
+    case K_HOME:
+    case K_KHOME:
+	oap->motion_type = MCHAR;
+	oap->inclusive = FALSE;
+	if (curwin->w_p_wrap
+#ifdef FEAT_VERTSPLIT
+		&& curwin->w_width != 0
+#endif
+		)
+	{
+	    int		width1 = W_WIDTH(curwin) - curwin_col_off();
+	    int		width2 = width1 + curwin_col_off2();
+
+	    validate_virtcol();
+	    i = 0;
+	    if (curwin->w_virtcol >= (colnr_T)width1 && width2 > 0)
+		i = (curwin->w_virtcol - width1) / width2 * width2 + width1;
+	}
+	else
+	    i = curwin->w_leftcol;
+	/* Go to the middle of the screen line.  When 'number' is on and lines
+	 * are wrapping the middle can be more to the left.*/
+	if (cap->nchar == 'm')
+	    i += (W_WIDTH(curwin) - curwin_col_off()
+		    + ((curwin->w_p_wrap && i > 0)
+			? curwin_col_off2() : 0)) / 2;
+	coladvance((colnr_T)i);
+	if (flag)
+	{
+	    do
+		i = gchar_cursor();
+	    while (vim_iswhite(i) && oneright() == OK);
+	}
+	curwin->w_set_curswant = TRUE;
+	break;
+
+    case '_':
+	/* "g_": to the last non-blank character in the line or <count> lines
+	 * downward. */
+	cap->oap->motion_type = MCHAR;
+	cap->oap->inclusive = TRUE;
+	curwin->w_curswant = MAXCOL;
+	if (cursor_down((long)(cap->count1 - 1),
+					 cap->oap->op_type == OP_NOP) == FAIL)
+	    clearopbeep(cap->oap);
+	else
+	{
+	    char_u  *ptr = ml_get_curline();
+
+	    /* In Visual mode we may end up after the line. */
+	    if (curwin->w_cursor.col > 0 && ptr[curwin->w_cursor.col] == NUL)
+		--curwin->w_cursor.col;
+
+	    /* Decrease the cursor column until it's on a non-blank. */
+	    while (curwin->w_cursor.col > 0
+				    && vim_iswhite(ptr[curwin->w_cursor.col]))
+		--curwin->w_cursor.col;
+	    curwin->w_set_curswant = TRUE;
+	}
+	break;
+
+    case '$':
+    case K_END:
+    case K_KEND:
+	{
+	    int col_off = curwin_col_off();
+
+	    oap->motion_type = MCHAR;
+	    oap->inclusive = TRUE;
+	    if (curwin->w_p_wrap
+#ifdef FEAT_VERTSPLIT
+		    && curwin->w_width != 0
+#endif
+	       )
+	    {
+		curwin->w_curswant = MAXCOL;    /* so we stay at the end */
+		if (cap->count1 == 1)
+		{
+		    int		width1 = W_WIDTH(curwin) - col_off;
+		    int		width2 = width1 + curwin_col_off2();
+
+		    validate_virtcol();
+		    i = width1 - 1;
+		    if (curwin->w_virtcol >= (colnr_T)width1)
+			i += ((curwin->w_virtcol - width1) / width2 + 1)
+								     * width2;
+		    coladvance((colnr_T)i);
+#if defined(FEAT_LINEBREAK) || defined(FEAT_MBYTE)
+		    if (curwin->w_cursor.col > 0 && curwin->w_p_wrap)
+		    {
+			/*
+			 * Check for landing on a character that got split at
+			 * the end of the line.  We do not want to advance to
+			 * the next screen line.
+			 */
+			validate_virtcol();
+			if (curwin->w_virtcol > (colnr_T)i)
+			    --curwin->w_cursor.col;
+		    }
+#endif
+		}
+		else if (nv_screengo(oap, FORWARD, cap->count1 - 1) == FAIL)
+		    clearopbeep(oap);
+	    }
+	    else
+	    {
+		i = curwin->w_leftcol + W_WIDTH(curwin) - col_off - 1;
+		coladvance((colnr_T)i);
+
+		/* Make sure we stick in this column. */
+		validate_virtcol();
+		curwin->w_curswant = curwin->w_virtcol;
+		curwin->w_set_curswant = FALSE;
+	    }
+	}
+	break;
+
+    /*
+     * "g*" and "g#", like "*" and "#" but without using "\<" and "\>"
+     */
+    case '*':
+    case '#':
+#if POUND != '#'
+    case POUND:		/* pound sign (sometimes equal to '#') */
+#endif
+    case Ctrl_RSB:		/* :tag or :tselect for current identifier */
+    case ']':			/* :tselect for current identifier */
+	nv_ident(cap);
+	break;
+
+    /*
+     * ge and gE: go back to end of word
+     */
+    case 'e':
+    case 'E':
+	oap->motion_type = MCHAR;
+	curwin->w_set_curswant = TRUE;
+	oap->inclusive = TRUE;
+	if (bckend_word(cap->count1, cap->nchar == 'E', FALSE) == FAIL)
+	    clearopbeep(oap);
+	break;
+
+    /*
+     * "g CTRL-G": display info about cursor position
+     */
+    case Ctrl_G:
+	cursor_pos_info();
+	break;
+
+    /*
+     * "gi": start Insert at the last position.
+     */
+    case 'i':
+	if (curbuf->b_last_insert.lnum != 0)
+	{
+	    curwin->w_cursor = curbuf->b_last_insert;
+	    check_cursor_lnum();
+	    i = (int)STRLEN(ml_get_curline());
+	    if (curwin->w_cursor.col > (colnr_T)i)
+	    {
+#ifdef FEAT_VIRTUALEDIT
+		if (virtual_active())
+		    curwin->w_cursor.coladd += curwin->w_cursor.col - i;
+#endif
+		curwin->w_cursor.col = i;
+	    }
+	}
+	cap->cmdchar = 'i';
+	nv_edit(cap);
+	break;
+
+    /*
+     * "gI": Start insert in column 1.
+     */
+    case 'I':
+	beginline(0);
+	if (!checkclearopq(oap))
+	    invoke_edit(cap, FALSE, 'g', FALSE);
+	break;
+
+#ifdef FEAT_SEARCHPATH
+    /*
+     * "gf": goto file, edit file under cursor
+     * "]f" and "[f": can also be used.
+     */
+    case 'f':
+    case 'F':
+	nv_gotofile(cap);
+	break;
+#endif
+
+	/* "g'm" and "g`m": jump to mark without setting pcmark */
+    case '\'':
+	cap->arg = TRUE;
+	/*FALLTHROUGH*/
+    case '`':
+	nv_gomark(cap);
+	break;
+
+    /*
+     * "gs": Goto sleep.
+     */
+    case 's':
+	do_sleep(cap->count1 * 1000L);
+	break;
+
+    /*
+     * "ga": Display the ascii value of the character under the
+     * cursor.	It is displayed in decimal, hex, and octal. -- webb
+     */
+    case 'a':
+	do_ascii(NULL);
+	break;
+
+#ifdef FEAT_MBYTE
+    /*
+     * "g8": Display the bytes used for the UTF-8 character under the
+     * cursor.	It is displayed in hex.
+     * "8g8" finds illegal byte sequence.
+     */
+    case '8':
+	if (cap->count0 == 8)
+	    utf_find_illegal();
+	else
+	    show_utf8();
+	break;
+#endif
+
+    case '<':
+	show_sb_text();
+	break;
+
+    /*
+     * "gg": Goto the first line in file.  With a count it goes to
+     * that line number like for "G". -- webb
+     */
+    case 'g':
+	cap->arg = FALSE;
+	nv_goto(cap);
+	break;
+
+    /*
+     *	 Two-character operators:
+     *	 "gq"	    Format text
+     *	 "gw"	    Format text and keep cursor position
+     *	 "g~"	    Toggle the case of the text.
+     *	 "gu"	    Change text to lower case.
+     *	 "gU"	    Change text to upper case.
+     *   "g?"	    rot13 encoding
+     *   "g@"	    call 'operatorfunc'
+     */
+    case 'q':
+    case 'w':
+	oap->cursor_start = curwin->w_cursor;
+	/*FALLTHROUGH*/
+    case '~':
+    case 'u':
+    case 'U':
+    case '?':
+    case '@':
+	nv_operator(cap);
+	break;
+
+    /*
+     * "gd": Find first occurrence of pattern under the cursor in the
+     *	 current function
+     * "gD": idem, but in the current file.
+     */
+    case 'd':
+    case 'D':
+	nv_gd(oap, cap->nchar, (int)cap->count0);
+	break;
+
+#ifdef FEAT_MOUSE
+    /*
+     * g<*Mouse> : <C-*mouse>
+     */
+    case K_MIDDLEMOUSE:
+    case K_MIDDLEDRAG:
+    case K_MIDDLERELEASE:
+    case K_LEFTMOUSE:
+    case K_LEFTDRAG:
+    case K_LEFTRELEASE:
+    case K_RIGHTMOUSE:
+    case K_RIGHTDRAG:
+    case K_RIGHTRELEASE:
+    case K_X1MOUSE:
+    case K_X1DRAG:
+    case K_X1RELEASE:
+    case K_X2MOUSE:
+    case K_X2DRAG:
+    case K_X2RELEASE:
+	mod_mask = MOD_MASK_CTRL;
+	(void)do_mouse(oap, cap->nchar, BACKWARD, cap->count1, 0);
+	break;
+#endif
+
+    case K_IGNORE:
+	break;
+
+    /*
+     * "gP" and "gp": same as "P" and "p" but leave cursor just after new text
+     */
+    case 'p':
+    case 'P':
+	nv_put(cap);
+	break;
+
+#ifdef FEAT_BYTEOFF
+    /* "go": goto byte count from start of buffer */
+    case 'o':
+	goto_byte(cap->count0);
+	break;
+#endif
+
+    /* "gQ": improved Ex mode */
+    case 'Q':
+	if (text_locked())
+	{
+	    clearopbeep(cap->oap);
+	    text_locked_msg();
+	    break;
+	}
+
+	if (!checkclearopq(oap))
+	    do_exmode(TRUE);
+	break;
+
+#ifdef FEAT_JUMPLIST
+    case ',':
+	nv_pcmark(cap);
+	break;
+
+    case ';':
+	cap->count1 = -cap->count1;
+	nv_pcmark(cap);
+	break;
+#endif
+
+#ifdef FEAT_WINDOWS
+    case 't':
+	goto_tabpage((int)cap->count0);
+	break;
+    case 'T':
+	goto_tabpage(-(int)cap->count1);
+	break;
+#endif
+
+    case '+':
+    case '-': /* "g+" and "g-": undo or redo along the timeline */
+	if (!checkclearopq(oap))
+	    undo_time(cap->nchar == '-' ? -cap->count1 : cap->count1,
+								FALSE, FALSE);
+	break;
+
+    default:
+	clearopbeep(oap);
+	break;
+    }
+}
+
+/*
+ * Handle "o" and "O" commands.
+ */
+    static void
+n_opencmd(cap)
+    cmdarg_T	*cap;
+{
+    if (!checkclearopq(cap->oap))
+    {
+#ifdef FEAT_FOLDING
+	if (cap->cmdchar == 'O')
+	    /* Open above the first line of a folded sequence of lines */
+	    (void)hasFolding(curwin->w_cursor.lnum,
+						&curwin->w_cursor.lnum, NULL);
+	else
+	    /* Open below the last line of a folded sequence of lines */
+	    (void)hasFolding(curwin->w_cursor.lnum,
+						NULL, &curwin->w_cursor.lnum);
+#endif
+	if (u_save((linenr_T)(curwin->w_cursor.lnum -
+					       (cap->cmdchar == 'O' ? 1 : 0)),
+		   (linenr_T)(curwin->w_cursor.lnum +
+					       (cap->cmdchar == 'o' ? 1 : 0))
+		       ) == OK
+		&& open_line(cap->cmdchar == 'O' ? BACKWARD : FORWARD,
+#ifdef FEAT_COMMENTS
+		    has_format_option(FO_OPEN_COMS) ? OPENLINE_DO_COM :
+#endif
+		    0, 0))
+	{
+	    /* When '#' is in 'cpoptions' ignore the count. */
+	    if (vim_strchr(p_cpo, CPO_HASH) != NULL)
+		cap->count1 = 1;
+	    invoke_edit(cap, FALSE, cap->cmdchar, TRUE);
+	}
+    }
+}
+
+/*
+ * "." command: redo last change.
+ */
+    static void
+nv_dot(cap)
+    cmdarg_T	*cap;
+{
+    if (!checkclearopq(cap->oap))
+    {
+	/*
+	 * If "restart_edit" is TRUE, the last but one command is repeated
+	 * instead of the last command (inserting text). This is used for
+	 * CTRL-O <.> in insert mode.
+	 */
+	if (start_redo(cap->count0, restart_edit != 0 && !arrow_used) == FAIL)
+	    clearopbeep(cap->oap);
+    }
+}
+
+/*
+ * CTRL-R: undo undo
+ */
+    static void
+nv_redo(cap)
+    cmdarg_T	*cap;
+{
+    if (!checkclearopq(cap->oap))
+    {
+	u_redo((int)cap->count1);
+	curwin->w_set_curswant = TRUE;
+    }
+}
+
+/*
+ * Handle "U" command.
+ */
+    static void
+nv_Undo(cap)
+    cmdarg_T	*cap;
+{
+    /* In Visual mode and typing "gUU" triggers an operator */
+    if (cap->oap->op_type == OP_UPPER
+#ifdef FEAT_VISUAL
+	    || VIsual_active
+#endif
+	    )
+    {
+	/* translate "gUU" to "gUgU" */
+	cap->cmdchar = 'g';
+	cap->nchar = 'U';
+	nv_operator(cap);
+    }
+    else if (!checkclearopq(cap->oap))
+    {
+	u_undoline();
+	curwin->w_set_curswant = TRUE;
+    }
+}
+
+/*
+ * '~' command: If tilde is not an operator and Visual is off: swap case of a
+ * single character.
+ */
+    static void
+nv_tilde(cap)
+    cmdarg_T	*cap;
+{
+    if (!p_to
+#ifdef FEAT_VISUAL
+	    && !VIsual_active
+#endif
+	    && cap->oap->op_type != OP_TILDE)
+	n_swapchar(cap);
+    else
+	nv_operator(cap);
+}
+
+/*
+ * Handle an operator command.
+ * The actual work is done by do_pending_operator().
+ */
+    static void
+nv_operator(cap)
+    cmdarg_T	*cap;
+{
+    int	    op_type;
+
+    op_type = get_op_type(cap->cmdchar, cap->nchar);
+
+    if (op_type == cap->oap->op_type)	    /* double operator works on lines */
+	nv_lineop(cap);
+    else if (!checkclearop(cap->oap))
+    {
+	cap->oap->start = curwin->w_cursor;
+	cap->oap->op_type = op_type;
+    }
+}
+
+/*
+ * Handle linewise operator "dd", "yy", etc.
+ *
+ * "_" is is a strange motion command that helps make operators more logical.
+ * It is actually implemented, but not documented in the real Vi.  This motion
+ * command actually refers to "the current line".  Commands like "dd" and "yy"
+ * are really an alternate form of "d_" and "y_".  It does accept a count, so
+ * "d3_" works to delete 3 lines.
+ */
+    static void
+nv_lineop(cap)
+    cmdarg_T	*cap;
+{
+    cap->oap->motion_type = MLINE;
+    if (cursor_down(cap->count1 - 1L, cap->oap->op_type == OP_NOP) == FAIL)
+	clearopbeep(cap->oap);
+    else if (  cap->oap->op_type == OP_DELETE
+	    || cap->oap->op_type == OP_LSHIFT
+	    || cap->oap->op_type == OP_RSHIFT)
+	beginline(BL_SOL | BL_FIX);
+    else if (cap->oap->op_type != OP_YANK)	/* 'Y' does not move cursor */
+	beginline(BL_WHITE | BL_FIX);
+}
+
+/*
+ * <Home> command.
+ */
+    static void
+nv_home(cap)
+    cmdarg_T	*cap;
+{
+    /* CTRL-HOME is like "gg" */
+    if (mod_mask & MOD_MASK_CTRL)
+	nv_goto(cap);
+    else
+    {
+	cap->count0 = 1;
+	nv_pipe(cap);
+    }
+    ins_at_eol = FALSE;	    /* Don't move cursor past eol (only necessary in a
+			       one-character line). */
+}
+
+/*
+ * "|" command.
+ */
+    static void
+nv_pipe(cap)
+    cmdarg_T *cap;
+{
+    cap->oap->motion_type = MCHAR;
+    cap->oap->inclusive = FALSE;
+    beginline(0);
+    if (cap->count0 > 0)
+    {
+	coladvance((colnr_T)(cap->count0 - 1));
+	curwin->w_curswant = (colnr_T)(cap->count0 - 1);
+    }
+    else
+	curwin->w_curswant = 0;
+    /* keep curswant at the column where we wanted to go, not where
+       we ended; differs if line is too short */
+    curwin->w_set_curswant = FALSE;
+}
+
+/*
+ * Handle back-word command "b" and "B".
+ * cap->arg is 1 for "B"
+ */
+    static void
+nv_bck_word(cap)
+    cmdarg_T	*cap;
+{
+    cap->oap->motion_type = MCHAR;
+    cap->oap->inclusive = FALSE;
+    curwin->w_set_curswant = TRUE;
+    if (bck_word(cap->count1, cap->arg, FALSE) == FAIL)
+	clearopbeep(cap->oap);
+#ifdef FEAT_FOLDING
+    else if ((fdo_flags & FDO_HOR) && KeyTyped && cap->oap->op_type == OP_NOP)
+	foldOpenCursor();
+#endif
+}
+
+/*
+ * Handle word motion commands "e", "E", "w" and "W".
+ * cap->arg is TRUE for "E" and "W".
+ */
+    static void
+nv_wordcmd(cap)
+    cmdarg_T	*cap;
+{
+    int		n;
+    int		word_end;
+    int		flag = FALSE;
+
+    /*
+     * Set inclusive for the "E" and "e" command.
+     */
+    if (cap->cmdchar == 'e' || cap->cmdchar == 'E')
+	word_end = TRUE;
+    else
+	word_end = FALSE;
+    cap->oap->inclusive = word_end;
+
+    /*
+     * "cw" and "cW" are a special case.
+     */
+    if (!word_end && cap->oap->op_type == OP_CHANGE)
+    {
+	n = gchar_cursor();
+	if (n != NUL)			/* not an empty line */
+	{
+	    if (vim_iswhite(n))
+	    {
+		/*
+		 * Reproduce a funny Vi behaviour: "cw" on a blank only
+		 * changes one character, not all blanks until the start of
+		 * the next word.  Only do this when the 'w' flag is included
+		 * in 'cpoptions'.
+		 */
+		if (cap->count1 == 1 && vim_strchr(p_cpo, CPO_CW) != NULL)
+		{
+		    cap->oap->inclusive = TRUE;
+		    cap->oap->motion_type = MCHAR;
+		    return;
+		}
+	    }
+	    else
+	    {
+		/*
+		 * This is a little strange. To match what the real Vi does,
+		 * we effectively map 'cw' to 'ce', and 'cW' to 'cE', provided
+		 * that we are not on a space or a TAB.  This seems impolite
+		 * at first, but it's really more what we mean when we say
+		 * 'cw'.
+		 * Another strangeness: When standing on the end of a word
+		 * "ce" will change until the end of the next wordt, but "cw"
+		 * will change only one character! This is done by setting
+		 * flag.
+		 */
+		cap->oap->inclusive = TRUE;
+		word_end = TRUE;
+		flag = TRUE;
+	    }
+	}
+    }
+
+    cap->oap->motion_type = MCHAR;
+    curwin->w_set_curswant = TRUE;
+    if (word_end)
+	n = end_word(cap->count1, cap->arg, flag, FALSE);
+    else
+	n = fwd_word(cap->count1, cap->arg, cap->oap->op_type != OP_NOP);
+
+    /* Don't leave the cursor on the NUL past a line */
+    if (curwin->w_cursor.col && gchar_cursor() == NUL)
+    {
+	--curwin->w_cursor.col;
+	cap->oap->inclusive = TRUE;
+    }
+
+    if (n == FAIL && cap->oap->op_type == OP_NOP)
+	clearopbeep(cap->oap);
+    else
+    {
+#ifdef FEAT_VISUAL
+	adjust_for_sel(cap);
+#endif
+#ifdef FEAT_FOLDING
+	if ((fdo_flags & FDO_HOR) && KeyTyped && cap->oap->op_type == OP_NOP)
+	    foldOpenCursor();
+#endif
+    }
+}
+
+/*
+ * "0" and "^" commands.
+ * cap->arg is the argument for beginline().
+ */
+    static void
+nv_beginline(cap)
+    cmdarg_T	*cap;
+{
+    cap->oap->motion_type = MCHAR;
+    cap->oap->inclusive = FALSE;
+    beginline(cap->arg);
+#ifdef FEAT_FOLDING
+    if ((fdo_flags & FDO_HOR) && KeyTyped && cap->oap->op_type == OP_NOP)
+	foldOpenCursor();
+#endif
+    ins_at_eol = FALSE;	    /* Don't move cursor past eol (only necessary in a
+			       one-character line). */
+}
+
+#ifdef FEAT_VISUAL
+/*
+ * In exclusive Visual mode, may include the last character.
+ */
+    static void
+adjust_for_sel(cap)
+    cmdarg_T	*cap;
+{
+    if (VIsual_active && cap->oap->inclusive && *p_sel == 'e'
+	    && gchar_cursor() != NUL && lt(VIsual, curwin->w_cursor))
+    {
+# ifdef FEAT_MBYTE
+	if (has_mbyte)
+	    inc_cursor();
+	else
+# endif
+	    ++curwin->w_cursor.col;
+	cap->oap->inclusive = FALSE;
+    }
+}
+
+/*
+ * Exclude last character at end of Visual area for 'selection' == "exclusive".
+ * Should check VIsual_mode before calling this.
+ * Returns TRUE when backed up to the previous line.
+ */
+    static int
+unadjust_for_sel()
+{
+    pos_T	*pp;
+
+    if (*p_sel == 'e' && !equalpos(VIsual, curwin->w_cursor))
+    {
+	if (lt(VIsual, curwin->w_cursor))
+	    pp = &curwin->w_cursor;
+	else
+	    pp = &VIsual;
+#ifdef FEAT_VIRTUALEDIT
+	if (pp->coladd > 0)
+	    --pp->coladd;
+	else
+#endif
+	if (pp->col > 0)
+	{
+	    --pp->col;
+#ifdef FEAT_MBYTE
+	    mb_adjustpos(pp);
+#endif
+	}
+	else if (pp->lnum > 1)
+	{
+	    --pp->lnum;
+	    pp->col = (colnr_T)STRLEN(ml_get(pp->lnum));
+	    return TRUE;
+	}
+    }
+    return FALSE;
+}
+
+/*
+ * SELECT key in Normal or Visual mode: end of Select mode mapping.
+ */
+    static void
+nv_select(cap)
+    cmdarg_T	*cap;
+{
+    if (VIsual_active)
+	VIsual_select = TRUE;
+    else if (VIsual_reselect)
+    {
+	cap->nchar = 'v';	    /* fake "gv" command */
+	cap->arg = TRUE;
+	nv_g_cmd(cap);
+    }
+}
+
+#endif
+
+/*
+ * "G", "gg", CTRL-END, CTRL-HOME.
+ * cap->arg is TRUE for "G".
+ */
+    static void
+nv_goto(cap)
+    cmdarg_T	*cap;
+{
+    linenr_T	lnum;
+
+    if (cap->arg)
+	lnum = curbuf->b_ml.ml_line_count;
+    else
+	lnum = 1L;
+    cap->oap->motion_type = MLINE;
+    setpcmark();
+
+    /* When a count is given, use it instead of the default lnum */
+    if (cap->count0 != 0)
+	lnum = cap->count0;
+    if (lnum < 1L)
+	lnum = 1L;
+    else if (lnum > curbuf->b_ml.ml_line_count)
+	lnum = curbuf->b_ml.ml_line_count;
+    curwin->w_cursor.lnum = lnum;
+    beginline(BL_SOL | BL_FIX);
+#ifdef FEAT_FOLDING
+    if ((fdo_flags & FDO_JUMP) && KeyTyped && cap->oap->op_type == OP_NOP)
+	foldOpenCursor();
+#endif
+}
+
+/*
+ * CTRL-\ in Normal mode.
+ */
+    static void
+nv_normal(cap)
+    cmdarg_T	*cap;
+{
+    if (cap->nchar == Ctrl_N || cap->nchar == Ctrl_G)
+    {
+	clearop(cap->oap);
+	if (restart_edit != 0 && mode_displayed)
+	    clear_cmdline = TRUE;		/* unshow mode later */
+	restart_edit = 0;
+#ifdef FEAT_CMDWIN
+	if (cmdwin_type != 0)
+	    cmdwin_result = Ctrl_C;
+#endif
+#ifdef FEAT_VISUAL
+	if (VIsual_active)
+	{
+	    end_visual_mode();		/* stop Visual */
+	    redraw_curbuf_later(INVERTED);
+	}
+#endif
+	/* CTRL-\ CTRL-G restarts Insert mode when 'insertmode' is set. */
+	if (cap->nchar == Ctrl_G && p_im)
+	    restart_edit = 'a';
+    }
+    else
+	clearopbeep(cap->oap);
+}
+
+/*
+ * ESC in Normal mode: beep, but don't flush buffers.
+ * Don't even beep if we are canceling a command.
+ */
+    static void
+nv_esc(cap)
+    cmdarg_T	*cap;
+{
+    int		no_reason;
+
+    no_reason = (cap->oap->op_type == OP_NOP
+		&& cap->opcount == 0
+		&& cap->count0 == 0
+		&& cap->oap->regname == 0
+		&& !p_im);
+
+    if (cap->arg)		/* TRUE for CTRL-C */
+    {
+	if (restart_edit == 0
+#ifdef FEAT_CMDWIN
+		&& cmdwin_type == 0
+#endif
+#ifdef FEAT_VISUAL
+		&& !VIsual_active
+#endif
+		&& no_reason)
+	    MSG(_("Type  :quit<Enter>  to exit Vim"));
+
+	/* Don't reset "restart_edit" when 'insertmode' is set, it won't be
+	 * set again below when halfway a mapping. */
+	if (!p_im)
+	    restart_edit = 0;
+#ifdef FEAT_CMDWIN
+	if (cmdwin_type != 0)
+	{
+	    cmdwin_result = K_IGNORE;
+	    got_int = FALSE;	/* don't stop executing autocommands et al. */
+	    return;
+	}
+#endif
+    }
+
+#ifdef FEAT_VISUAL
+    if (VIsual_active)
+    {
+	end_visual_mode();	/* stop Visual */
+	check_cursor_col();	/* make sure cursor is not beyond EOL */
+	curwin->w_set_curswant = TRUE;
+	redraw_curbuf_later(INVERTED);
+    }
+    else
+#endif
+	if (no_reason)
+	    vim_beep();
+    clearop(cap->oap);
+
+    /* A CTRL-C is often used at the start of a menu.  When 'insertmode' is
+     * set return to Insert mode afterwards. */
+    if (restart_edit == 0 && goto_im()
+#ifdef FEAT_EX_EXTRA
+	    && ex_normal_busy == 0
+#endif
+	    )
+	restart_edit = 'a';
+}
+
+/*
+ * Handle "A", "a", "I", "i" and <Insert> commands.
+ */
+    static void
+nv_edit(cap)
+    cmdarg_T *cap;
+{
+    /* <Insert> is equal to "i" */
+    if (cap->cmdchar == K_INS || cap->cmdchar == K_KINS)
+	cap->cmdchar = 'i';
+
+#ifdef FEAT_VISUAL
+    /* in Visual mode "A" and "I" are an operator */
+    if (VIsual_active && (cap->cmdchar == 'A' || cap->cmdchar == 'I'))
+	v_visop(cap);
+
+    /* in Visual mode and after an operator "a" and "i" are for text objects */
+    else
+#endif
+	if ((cap->cmdchar == 'a' || cap->cmdchar == 'i')
+	    && (cap->oap->op_type != OP_NOP
+#ifdef FEAT_VISUAL
+		|| VIsual_active
+#endif
+		))
+    {
+#ifdef FEAT_TEXTOBJ
+	nv_object(cap);
+#else
+	clearopbeep(cap->oap);
+#endif
+    }
+    else if (!curbuf->b_p_ma && !p_im)
+    {
+	/* Only give this error when 'insertmode' is off. */
+	EMSG(_(e_modifiable));
+	clearop(cap->oap);
+    }
+    else if (!checkclearopq(cap->oap))
+    {
+	switch (cap->cmdchar)
+	{
+	    case 'A':	/* "A"ppend after the line */
+		curwin->w_set_curswant = TRUE;
+#ifdef FEAT_VIRTUALEDIT
+		if (ve_flags == VE_ALL)
+		{
+		    int save_State = State;
+
+		    /* Pretent Insert mode here to allow the cursor on the
+		     * character past the end of the line */
+		    State = INSERT;
+		    coladvance((colnr_T)MAXCOL);
+		    State = save_State;
+		}
+		else
+#endif
+		    curwin->w_cursor.col += (colnr_T)STRLEN(ml_get_cursor());
+		break;
+
+	    case 'I':	/* "I"nsert before the first non-blank */
+		if (vim_strchr(p_cpo, CPO_INSEND) == NULL)
+		    beginline(BL_WHITE);
+		else
+		    beginline(BL_WHITE|BL_FIX);
+		break;
+
+	    case 'a':	/* "a"ppend is like "i"nsert on the next character. */
+#ifdef FEAT_VIRTUALEDIT
+		/* increment coladd when in virtual space, increment the
+		 * column otherwise, also to append after an unprintable char */
+		if (virtual_active()
+			&& (curwin->w_cursor.coladd > 0
+			    || *ml_get_cursor() == NUL
+			    || *ml_get_cursor() == TAB))
+		    curwin->w_cursor.coladd++;
+		else
+#endif
+		if (*ml_get_cursor() != NUL)
+		    inc_cursor();
+		break;
+	}
+
+#ifdef FEAT_VIRTUALEDIT
+	if (curwin->w_cursor.coladd && cap->cmdchar != 'A')
+	{
+	    int save_State = State;
+
+	    /* Pretent Insert mode here to allow the cursor on the
+	     * character past the end of the line */
+	    State = INSERT;
+	    coladvance(getviscol());
+	    State = save_State;
+	}
+#endif
+
+	invoke_edit(cap, FALSE, cap->cmdchar, FALSE);
+    }
+}
+
+/*
+ * Invoke edit() and take care of "restart_edit" and the return value.
+ */
+    static void
+invoke_edit(cap, repl, cmd, startln)
+    cmdarg_T	*cap;
+    int		repl;		/* "r" or "gr" command */
+    int		cmd;
+    int		startln;
+{
+    int		restart_edit_save = 0;
+
+    /* Complicated: When the user types "a<C-O>a" we don't want to do Insert
+     * mode recursively.  But when doing "a<C-O>." or "a<C-O>rx" we do allow
+     * it. */
+    if (repl || !stuff_empty())
+	restart_edit_save = restart_edit;
+    else
+	restart_edit_save = 0;
+
+    /* Always reset "restart_edit", this is not a restarted edit. */
+    restart_edit = 0;
+
+    if (edit(cmd, startln, cap->count1))
+	cap->retval |= CA_COMMAND_BUSY;
+
+    if (restart_edit == 0)
+	restart_edit = restart_edit_save;
+}
+
+#ifdef FEAT_TEXTOBJ
+/*
+ * "a" or "i" while an operator is pending or in Visual mode: object motion.
+ */
+    static void
+nv_object(cap)
+    cmdarg_T	*cap;
+{
+    int		flag;
+    int		include;
+    char_u	*mps_save;
+
+    if (cap->cmdchar == 'i')
+	include = FALSE;    /* "ix" = inner object: exclude white space */
+    else
+	include = TRUE;	    /* "ax" = an object: include white space */
+
+    /* Make sure (), [], {} and <> are in 'matchpairs' */
+    mps_save = curbuf->b_p_mps;
+    curbuf->b_p_mps = (char_u *)"(:),{:},[:],<:>";
+
+    switch (cap->nchar)
+    {
+	case 'w': /* "aw" = a word */
+		flag = current_word(cap->oap, cap->count1, include, FALSE);
+		break;
+	case 'W': /* "aW" = a WORD */
+		flag = current_word(cap->oap, cap->count1, include, TRUE);
+		break;
+	case 'b': /* "ab" = a braces block */
+	case '(':
+	case ')':
+		flag = current_block(cap->oap, cap->count1, include, '(', ')');
+		break;
+	case 'B': /* "aB" = a Brackets block */
+	case '{':
+	case '}':
+		flag = current_block(cap->oap, cap->count1, include, '{', '}');
+		break;
+	case '[': /* "a[" = a [] block */
+	case ']':
+		flag = current_block(cap->oap, cap->count1, include, '[', ']');
+		break;
+	case '<': /* "a<" = a <> block */
+	case '>':
+		flag = current_block(cap->oap, cap->count1, include, '<', '>');
+		break;
+	case 't': /* "at" = a tag block (xml and html) */
+		flag = current_tagblock(cap->oap, cap->count1, include);
+		break;
+	case 'p': /* "ap" = a paragraph */
+		flag = current_par(cap->oap, cap->count1, include, 'p');
+		break;
+	case 's': /* "as" = a sentence */
+		flag = current_sent(cap->oap, cap->count1, include);
+		break;
+	case '"': /* "a"" = a double quoted string */
+	case '\'': /* "a'" = a single quoted string */
+	case '`': /* "a`" = a backtick quoted string */
+		flag = current_quote(cap->oap, cap->count1, include,
+								  cap->nchar);
+		break;
+#if 0	/* TODO */
+	case 'S': /* "aS" = a section */
+	case 'f': /* "af" = a filename */
+	case 'u': /* "au" = a URL */
+#endif
+	default:
+		flag = FAIL;
+		break;
+    }
+
+    curbuf->b_p_mps = mps_save;
+    if (flag == FAIL)
+	clearopbeep(cap->oap);
+    adjust_cursor_col();
+    curwin->w_set_curswant = TRUE;
+}
+#endif
+
+/*
+ * "q" command: Start/stop recording.
+ * "q:", "q/", "q?": edit command-line in command-line window.
+ */
+    static void
+nv_record(cap)
+    cmdarg_T	*cap;
+{
+    if (cap->oap->op_type == OP_FORMAT)
+    {
+	/* "gqq" is the same as "gqgq": format line */
+	cap->cmdchar = 'g';
+	cap->nchar = 'q';
+	nv_operator(cap);
+    }
+    else if (!checkclearop(cap->oap))
+    {
+#ifdef FEAT_CMDWIN
+	if (cap->nchar == ':' || cap->nchar == '/' || cap->nchar == '?')
+	{
+	    stuffcharReadbuff(cap->nchar);
+	    stuffcharReadbuff(K_CMDWIN);
+	}
+	else
+#endif
+	    /* (stop) recording into a named register, unless executing a
+	     * register */
+	    if (!Exec_reg && do_record(cap->nchar) == FAIL)
+		clearopbeep(cap->oap);
+    }
+}
+
+/*
+ * Handle the "@r" command.
+ */
+    static void
+nv_at(cap)
+    cmdarg_T	*cap;
+{
+    if (checkclearop(cap->oap))
+	return;
+#ifdef FEAT_EVAL
+    if (cap->nchar == '=')
+    {
+	if (get_expr_register() == NUL)
+	    return;
+    }
+#endif
+    while (cap->count1-- && !got_int)
+    {
+	if (do_execreg(cap->nchar, FALSE, FALSE, FALSE) == FAIL)
+	{
+	    clearopbeep(cap->oap);
+	    break;
+	}
+	line_breakcheck();
+    }
+}
+
+/*
+ * Handle the CTRL-U and CTRL-D commands.
+ */
+    static void
+nv_halfpage(cap)
+    cmdarg_T	*cap;
+{
+    if ((cap->cmdchar == Ctrl_U && curwin->w_cursor.lnum == 1)
+	    || (cap->cmdchar == Ctrl_D
+		&& curwin->w_cursor.lnum == curbuf->b_ml.ml_line_count))
+	clearopbeep(cap->oap);
+    else if (!checkclearop(cap->oap))
+	halfpage(cap->cmdchar == Ctrl_D, cap->count0);
+}
+
+/*
+ * Handle "J" or "gJ" command.
+ */
+    static void
+nv_join(cap)
+    cmdarg_T *cap;
+{
+#ifdef FEAT_VISUAL
+    if (VIsual_active)	/* join the visual lines */
+	nv_operator(cap);
+    else
+#endif
+	if (!checkclearop(cap->oap))
+    {
+	if (cap->count0 <= 1)
+	    cap->count0 = 2;	    /* default for join is two lines! */
+	if (curwin->w_cursor.lnum + cap->count0 - 1 >
+						   curbuf->b_ml.ml_line_count)
+	    clearopbeep(cap->oap);  /* beyond last line */
+	else
+	{
+	    prep_redo(cap->oap->regname, cap->count0,
+			 NUL, cap->cmdchar, NUL, NUL, cap->nchar);
+	    do_do_join(cap->count0, cap->nchar == NUL);
+	}
+    }
+}
+
+/*
+ * "P", "gP", "p" and "gp" commands.
+ */
+    static void
+nv_put(cap)
+    cmdarg_T  *cap;
+{
+#ifdef FEAT_VISUAL
+    int		regname = 0;
+    void	*reg1 = NULL, *reg2 = NULL;
+    int		empty = FALSE;
+    int		was_visual = FALSE;
+#endif
+    int		dir;
+    int		flags = 0;
+
+    if (cap->oap->op_type != OP_NOP)
+    {
+#ifdef FEAT_DIFF
+	/* "dp" is ":diffput" */
+	if (cap->oap->op_type == OP_DELETE && cap->cmdchar == 'p')
+	{
+	    clearop(cap->oap);
+	    nv_diffgetput(TRUE);
+	}
+	else
+#endif
+	clearopbeep(cap->oap);
+    }
+    else
+    {
+	dir = (cap->cmdchar == 'P'
+		|| (cap->cmdchar == 'g' && cap->nchar == 'P'))
+							 ? BACKWARD : FORWARD;
+	prep_redo_cmd(cap);
+	if (cap->cmdchar == 'g')
+	    flags |= PUT_CURSEND;
+
+#ifdef FEAT_VISUAL
+	if (VIsual_active)
+	{
+	    /* Putting in Visual mode: The put text replaces the selected
+	     * text.  First delete the selected text, then put the new text.
+	     * Need to save and restore the registers that the delete
+	     * overwrites if the old contents is being put.
+	     */
+	    was_visual = TRUE;
+	    regname = cap->oap->regname;
+# ifdef FEAT_CLIPBOARD
+	    adjust_clip_reg(&regname);
+# endif
+	    if (regname == 0 || VIM_ISDIGIT(regname)
+# ifdef FEAT_CLIPBOARD
+		    || (clip_unnamed && (regname == '*' || regname == '+'))
+# endif
+
+		    )
+	    {
+		/* the delete is going to overwrite the register we want to
+		 * put, save it first. */
+		reg1 = get_register(regname, TRUE);
+	    }
+
+	    /* Now delete the selected text. */
+	    cap->cmdchar = 'd';
+	    cap->nchar = NUL;
+	    cap->oap->regname = NUL;
+	    nv_operator(cap);
+	    do_pending_operator(cap, 0, FALSE);
+	    empty = (curbuf->b_ml.ml_flags & ML_EMPTY);
+
+	    /* delete PUT_LINE_BACKWARD; */
+	    cap->oap->regname = regname;
+
+	    if (reg1 != NULL)
+	    {
+		/* Delete probably changed the register we want to put, save
+		 * it first. Then put back what was there before the delete. */
+		reg2 = get_register(regname, FALSE);
+		put_register(regname, reg1);
+	    }
+
+	    /* When deleted a linewise Visual area, put the register as
+	     * lines to avoid it joined with the next line.  When deletion was
+	     * characterwise, split a line when putting lines. */
+	    if (VIsual_mode == 'V')
+		flags |= PUT_LINE;
+	    else if (VIsual_mode == 'v')
+		flags |= PUT_LINE_SPLIT;
+	    if (VIsual_mode == Ctrl_V && dir == FORWARD)
+		flags |= PUT_LINE_FORWARD;
+	    dir = BACKWARD;
+	    if ((VIsual_mode != 'V'
+			&& curwin->w_cursor.col < curbuf->b_op_start.col)
+		    || (VIsual_mode == 'V'
+			&& curwin->w_cursor.lnum < curbuf->b_op_start.lnum))
+		/* cursor is at the end of the line or end of file, put
+		 * forward. */
+		dir = FORWARD;
+	}
+#endif
+	do_put(cap->oap->regname, dir, cap->count1, flags);
+
+#ifdef FEAT_VISUAL
+	/* If a register was saved, put it back now. */
+	if (reg2 != NULL)
+	    put_register(regname, reg2);
+
+	/* What to reselect with "gv"?  Selecting the just put text seems to
+	 * be the most useful, since the original text was removed. */
+	if (was_visual)
+	{
+	    curbuf->b_visual.vi_start = curbuf->b_op_start;
+	    curbuf->b_visual.vi_end = curbuf->b_op_end;
+	}
+
+	/* When all lines were selected and deleted do_put() leaves an empty
+	 * line that needs to be deleted now. */
+	if (empty && *ml_get(curbuf->b_ml.ml_line_count) == NUL)
+	{
+	    ml_delete(curbuf->b_ml.ml_line_count, TRUE);
+
+	    /* If the cursor was in that line, move it to the end of the last
+	     * line. */
+	    if (curwin->w_cursor.lnum > curbuf->b_ml.ml_line_count)
+	    {
+		curwin->w_cursor.lnum = curbuf->b_ml.ml_line_count;
+		coladvance((colnr_T)MAXCOL);
+	    }
+	}
+#endif
+	auto_format(FALSE, TRUE);
+    }
+}
+
+/*
+ * "o" and "O" commands.
+ */
+    static void
+nv_open(cap)
+    cmdarg_T	*cap;
+{
+#ifdef FEAT_DIFF
+    /* "do" is ":diffget" */
+    if (cap->oap->op_type == OP_DELETE && cap->cmdchar == 'o')
+    {
+	clearop(cap->oap);
+	nv_diffgetput(FALSE);
+    }
+    else
+#endif
+#ifdef FEAT_VISUAL
+    if (VIsual_active)  /* switch start and end of visual */
+	v_swap_corners(cap->cmdchar);
+    else
+#endif
+	n_opencmd(cap);
+}
+
+#ifdef FEAT_SNIFF
+/*ARGSUSED*/
+    static void
+nv_sniff(cap)
+    cmdarg_T	*cap;
+{
+    ProcessSniffRequests();
+}
+#endif
+
+#ifdef FEAT_NETBEANS_INTG
+    static void
+nv_nbcmd(cap)
+    cmdarg_T	*cap;
+{
+    netbeans_keycommand(cap->nchar);
+}
+#endif
+
+#ifdef FEAT_DND
+/*ARGSUSED*/
+    static void
+nv_drop(cap)
+    cmdarg_T	*cap;
+{
+    do_put('~', BACKWARD, 1L, PUT_CURSEND);
+}
+#endif
+
+#ifdef FEAT_AUTOCMD
+/*
+ * Trigger CursorHold event.
+ * When waiting for a character for 'updatetime' K_CURSORHOLD is put in the
+ * input buffer.  "did_cursorhold" is set to avoid retriggering.
+ */
+/*ARGSUSED*/
+    static void
+nv_cursorhold(cap)
+    cmdarg_T	*cap;
+{
+    apply_autocmds(EVENT_CURSORHOLD, NULL, NULL, FALSE, curbuf);
+    did_cursorhold = TRUE;
+    cap->retval |= CA_COMMAND_BUSY;	/* don't call edit() now */
+}
+#endif
--- /dev/null
+++ b/ops.c
@@ -1,0 +1,6379 @@
+/* vi:set ts=8 sts=4 sw=4:
+ *
+ * VIM - Vi IMproved	by Bram Moolenaar
+ *
+ * Do ":help uganda"  in Vim to read copying and usage conditions.
+ * Do ":help credits" in Vim to see a list of people who contributed.
+ * See README.txt for an overview of the Vim source code.
+ */
+
+/*
+ * ops.c: implementation of various operators: op_shift, op_delete, op_tilde,
+ *	  op_change, op_yank, do_put, do_join
+ */
+
+#include "vim.h"
+
+/*
+ * Number of registers.
+ *	0 = unnamed register, for normal yanks and puts
+ *   1..9 = registers '1' to '9', for deletes
+ * 10..35 = registers 'a' to 'z'
+ *     36 = delete register '-'
+ *     37 = Selection register '*'. Only if FEAT_CLIPBOARD defined
+ *     38 = Clipboard register '+'. Only if FEAT_CLIPBOARD and FEAT_X11 defined
+ */
+/*
+ * Symbolic names for some registers.
+ */
+#define DELETION_REGISTER	36
+#ifdef FEAT_CLIPBOARD
+# define STAR_REGISTER		37
+#  ifdef FEAT_X11
+#   define PLUS_REGISTER	38
+#  else
+#   define PLUS_REGISTER	STAR_REGISTER	    /* there is only one */
+#  endif
+#endif
+#ifdef FEAT_DND
+# define TILDE_REGISTER		(PLUS_REGISTER + 1)
+#endif
+
+#ifdef FEAT_CLIPBOARD
+# ifdef FEAT_DND
+#  define NUM_REGISTERS		(TILDE_REGISTER + 1)
+# else
+#  define NUM_REGISTERS		(PLUS_REGISTER + 1)
+# endif
+#else
+# define NUM_REGISTERS		37
+#endif
+
+/*
+ * Each yank register is an array of pointers to lines.
+ */
+static struct yankreg
+{
+    char_u	**y_array;	/* pointer to array of line pointers */
+    linenr_T	y_size;		/* number of lines in y_array */
+    char_u	y_type;		/* MLINE, MCHAR or MBLOCK */
+#ifdef FEAT_VISUAL
+    colnr_T	y_width;	/* only set if y_type == MBLOCK */
+#endif
+} y_regs[NUM_REGISTERS];
+
+static struct yankreg	*y_current;	    /* ptr to current yankreg */
+static int		y_append;	    /* TRUE when appending */
+static struct yankreg	*y_previous = NULL; /* ptr to last written yankreg */
+
+/*
+ * structure used by block_prep, op_delete and op_yank for blockwise operators
+ * also op_change, op_shift, op_insert, op_replace - AKelly
+ */
+struct block_def
+{
+    int		startspaces;	/* 'extra' cols of first char */
+    int		endspaces;	/* 'extra' cols of first char */
+    int		textlen;	/* chars in block */
+    char_u	*textstart;	/* pointer to 1st char in block */
+    colnr_T	textcol;	/* cols of chars (at least part.) in block */
+    colnr_T	start_vcol;	/* start col of 1st char wholly inside block */
+    colnr_T	end_vcol;	/* start col of 1st char wholly after block */
+#ifdef FEAT_VISUALEXTRA
+    int		is_short;	/* TRUE if line is too short to fit in block */
+    int		is_MAX;		/* TRUE if curswant==MAXCOL when starting */
+    int		is_oneChar;	/* TRUE if block within one character */
+    int		pre_whitesp;	/* screen cols of ws before block */
+    int		pre_whitesp_c;	/* chars of ws before block */
+    colnr_T	end_char_vcols;	/* number of vcols of post-block char */
+#endif
+    colnr_T	start_char_vcols; /* number of vcols of pre-block char */
+};
+
+#ifdef FEAT_VISUALEXTRA
+static void shift_block __ARGS((oparg_T *oap, int amount));
+static void block_insert __ARGS((oparg_T *oap, char_u *s, int b_insert, struct block_def*bdp));
+#endif
+static int	stuff_yank __ARGS((int, char_u *));
+static void	put_reedit_in_typebuf __ARGS((int silent));
+static int	put_in_typebuf __ARGS((char_u *s, int esc, int colon,
+								 int silent));
+static void	stuffescaped __ARGS((char_u *arg, int literally));
+#ifdef FEAT_MBYTE
+static void	mb_adjust_opend __ARGS((oparg_T *oap));
+#endif
+static void	free_yank __ARGS((long));
+static void	free_yank_all __ARGS((void));
+static int	yank_copy_line __ARGS((struct block_def *bd, long y_idx));
+#ifdef FEAT_CLIPBOARD
+static void	copy_yank_reg __ARGS((struct yankreg *reg));
+# if defined(FEAT_VISUAL) || defined(FEAT_EVAL)
+static void	may_set_selection __ARGS((void));
+# endif
+#endif
+static void	dis_msg __ARGS((char_u *p, int skip_esc));
+#ifdef FEAT_VISUAL
+static void	block_prep __ARGS((oparg_T *oap, struct block_def *, linenr_T, int));
+#endif
+#if defined(FEAT_CLIPBOARD) || defined(FEAT_EVAL)
+static void	str_to_reg __ARGS((struct yankreg *y_ptr, int type, char_u *str, long len, long blocklen));
+#endif
+static int	ends_in_white __ARGS((linenr_T lnum));
+#ifdef FEAT_COMMENTS
+static int	same_leader __ARGS((linenr_T lnum, int, char_u *, int, char_u *));
+static int	fmt_check_par __ARGS((linenr_T, int *, char_u **, int do_comments));
+#else
+static int	fmt_check_par __ARGS((linenr_T));
+#endif
+
+/*
+ * The names of operators.
+ * IMPORTANT: Index must correspond with defines in vim.h!!!
+ * The third field indicates whether the operator always works on lines.
+ */
+static char opchars[][3] =
+{
+    {NUL, NUL, FALSE},	/* OP_NOP */
+    {'d', NUL, FALSE},	/* OP_DELETE */
+    {'y', NUL, FALSE},	/* OP_YANK */
+    {'c', NUL, FALSE},	/* OP_CHANGE */
+    {'<', NUL, TRUE},	/* OP_LSHIFT */
+    {'>', NUL, TRUE},	/* OP_RSHIFT */
+    {'!', NUL, TRUE},	/* OP_FILTER */
+    {'g', '~', FALSE},	/* OP_TILDE */
+    {'=', NUL, TRUE},	/* OP_INDENT */
+    {'g', 'q', TRUE},	/* OP_FORMAT */
+    {':', NUL, TRUE},	/* OP_COLON */
+    {'g', 'U', FALSE},	/* OP_UPPER */
+    {'g', 'u', FALSE},	/* OP_LOWER */
+    {'J', NUL, TRUE},	/* DO_JOIN */
+    {'g', 'J', TRUE},	/* DO_JOIN_NS */
+    {'g', '?', FALSE},	/* OP_ROT13 */
+    {'r', NUL, FALSE},	/* OP_REPLACE */
+    {'I', NUL, FALSE},	/* OP_INSERT */
+    {'A', NUL, FALSE},	/* OP_APPEND */
+    {'z', 'f', TRUE},	/* OP_FOLD */
+    {'z', 'o', TRUE},	/* OP_FOLDOPEN */
+    {'z', 'O', TRUE},	/* OP_FOLDOPENREC */
+    {'z', 'c', TRUE},	/* OP_FOLDCLOSE */
+    {'z', 'C', TRUE},	/* OP_FOLDCLOSEREC */
+    {'z', 'd', TRUE},	/* OP_FOLDDEL */
+    {'z', 'D', TRUE},	/* OP_FOLDDELREC */
+    {'g', 'w', TRUE},	/* OP_FORMAT2 */
+    {'g', '@', FALSE},	/* OP_FUNCTION */
+};
+
+/*
+ * Translate a command name into an operator type.
+ * Must only be called with a valid operator name!
+ */
+    int
+get_op_type(char1, char2)
+    int		char1;
+    int		char2;
+{
+    int		i;
+
+    if (char1 == 'r')		/* ignore second character */
+	return OP_REPLACE;
+    if (char1 == '~')		/* when tilde is an operator */
+	return OP_TILDE;
+    for (i = 0; ; ++i)
+	if (opchars[i][0] == char1 && opchars[i][1] == char2)
+	    break;
+    return i;
+}
+
+#if defined(FEAT_VISUAL) || defined(PROTO)
+/*
+ * Return TRUE if operator "op" always works on whole lines.
+ */
+    int
+op_on_lines(op)
+    int op;
+{
+    return opchars[op][2];
+}
+#endif
+
+/*
+ * Get first operator command character.
+ * Returns 'g' or 'z' if there is another command character.
+ */
+    int
+get_op_char(optype)
+    int		optype;
+{
+    return opchars[optype][0];
+}
+
+/*
+ * Get second operator command character.
+ */
+    int
+get_extra_op_char(optype)
+    int		optype;
+{
+    return opchars[optype][1];
+}
+
+/*
+ * op_shift - handle a shift operation
+ */
+    void
+op_shift(oap, curs_top, amount)
+    oparg_T	    *oap;
+    int		    curs_top;
+    int		    amount;
+{
+    long	    i;
+    int		    first_char;
+    char_u	    *s;
+#ifdef FEAT_VISUAL
+    int		    block_col = 0;
+#endif
+
+    if (u_save((linenr_T)(oap->start.lnum - 1),
+				       (linenr_T)(oap->end.lnum + 1)) == FAIL)
+	return;
+
+#ifdef FEAT_VISUAL
+    if (oap->block_mode)
+	block_col = curwin->w_cursor.col;
+#endif
+
+    for (i = oap->line_count; --i >= 0; )
+    {
+	first_char = *ml_get_curline();
+	if (first_char == NUL)				/* empty line */
+	    curwin->w_cursor.col = 0;
+#ifdef FEAT_VISUALEXTRA
+	else if (oap->block_mode)
+	    shift_block(oap, amount);
+#endif
+	else
+	    /* Move the line right if it doesn't start with '#', 'smartindent'
+	     * isn't set or 'cindent' isn't set or '#' isn't in 'cino'. */
+#if defined(FEAT_SMARTINDENT) || defined(FEAT_CINDENT)
+	    if (first_char != '#' || !preprocs_left())
+#endif
+	{
+	    shift_line(oap->op_type == OP_LSHIFT, p_sr, amount);
+	}
+	++curwin->w_cursor.lnum;
+    }
+
+    changed_lines(oap->start.lnum, 0, oap->end.lnum + 1, 0L);
+
+#ifdef FEAT_VISUAL
+    if (oap->block_mode)
+    {
+	curwin->w_cursor.lnum = oap->start.lnum;
+	curwin->w_cursor.col = block_col;
+    }
+    else
+#endif
+	if (curs_top)	    /* put cursor on first line, for ">>" */
+    {
+	curwin->w_cursor.lnum = oap->start.lnum;
+	beginline(BL_SOL | BL_FIX);   /* shift_line() may have set cursor.col */
+    }
+    else
+	--curwin->w_cursor.lnum;	/* put cursor on last line, for ":>" */
+
+    if (oap->line_count > p_report)
+    {
+	if (oap->op_type == OP_RSHIFT)
+	    s = (char_u *)">";
+	else
+	    s = (char_u *)"<";
+	if (oap->line_count == 1)
+	{
+	    if (amount == 1)
+		sprintf((char *)IObuff, _("1 line %sed 1 time"), s);
+	    else
+		sprintf((char *)IObuff, _("1 line %sed %d times"), s, amount);
+	}
+	else
+	{
+	    if (amount == 1)
+		sprintf((char *)IObuff, _("%ld lines %sed 1 time"),
+							  oap->line_count, s);
+	    else
+		sprintf((char *)IObuff, _("%ld lines %sed %d times"),
+						  oap->line_count, s, amount);
+	}
+	msg(IObuff);
+    }
+
+    /*
+     * Set "'[" and "']" marks.
+     */
+    curbuf->b_op_start = oap->start;
+    curbuf->b_op_end.lnum = oap->end.lnum;
+    curbuf->b_op_end.col = (colnr_T)STRLEN(ml_get(oap->end.lnum));
+    if (curbuf->b_op_end.col > 0)
+	--curbuf->b_op_end.col;
+}
+
+/*
+ * shift the current line one shiftwidth left (if left != 0) or right
+ * leaves cursor on first blank in the line
+ */
+    void
+shift_line(left, round, amount)
+    int	left;
+    int	round;
+    int	amount;
+{
+    int		count;
+    int		i, j;
+    int		p_sw = (int)curbuf->b_p_sw;
+
+    count = get_indent();	/* get current indent */
+
+    if (round)			/* round off indent */
+    {
+	i = count / p_sw;	/* number of p_sw rounded down */
+	j = count % p_sw;	/* extra spaces */
+	if (j && left)		/* first remove extra spaces */
+	    --amount;
+	if (left)
+	{
+	    i -= amount;
+	    if (i < 0)
+		i = 0;
+	}
+	else
+	    i += amount;
+	count = i * p_sw;
+    }
+    else		/* original vi indent */
+    {
+	if (left)
+	{
+	    count -= p_sw * amount;
+	    if (count < 0)
+		count = 0;
+	}
+	else
+	    count += p_sw * amount;
+    }
+
+    /* Set new indent */
+#ifdef FEAT_VREPLACE
+    if (State & VREPLACE_FLAG)
+	change_indent(INDENT_SET, count, FALSE, NUL);
+    else
+#endif
+	(void)set_indent(count, SIN_CHANGED);
+}
+
+#if defined(FEAT_VISUALEXTRA) || defined(PROTO)
+/*
+ * Shift one line of the current block one shiftwidth right or left.
+ * Leaves cursor on first character in block.
+ */
+    static void
+shift_block(oap, amount)
+    oparg_T	*oap;
+    int		amount;
+{
+    int			left = (oap->op_type == OP_LSHIFT);
+    int			oldstate = State;
+    int			total, split;
+    char_u		*newp, *oldp, *midp, *ptr;
+    int			oldcol = curwin->w_cursor.col;
+    int			p_sw = (int)curbuf->b_p_sw;
+    int			p_ts = (int)curbuf->b_p_ts;
+    struct block_def	bd;
+    int			internal = 0;
+    int			incr;
+    colnr_T		vcol, col = 0, ws_vcol;
+    int			i = 0, j = 0;
+    int			len;
+
+#ifdef FEAT_RIGHTLEFT
+    int			old_p_ri = p_ri;
+
+    p_ri = 0;			/* don't want revins in ident */
+#endif
+
+    State = INSERT;		/* don't want REPLACE for State */
+    block_prep(oap, &bd, curwin->w_cursor.lnum, TRUE);
+    if (bd.is_short)
+	return;
+
+    /* total is number of screen columns to be inserted/removed */
+    total = amount * p_sw;
+    oldp = ml_get_curline();
+
+    if (!left)
+    {
+	/*
+	 *  1. Get start vcol
+	 *  2. Total ws vcols
+	 *  3. Divvy into TABs & spp
+	 *  4. Construct new string
+	 */
+	total += bd.pre_whitesp; /* all virtual WS upto & incl a split TAB */
+	ws_vcol = bd.start_vcol - bd.pre_whitesp;
+	if (bd.startspaces)
+	{
+#ifdef FEAT_MBYTE
+	    if (has_mbyte)
+		bd.textstart += (*mb_ptr2len)(bd.textstart);
+#endif
+	    ++bd.textstart;
+	}
+	for ( ; vim_iswhite(*bd.textstart); )
+	{
+	    incr = lbr_chartabsize_adv(&bd.textstart, (colnr_T)(bd.start_vcol));
+	    total += incr;
+	    bd.start_vcol += incr;
+	}
+	/* OK, now total=all the VWS reqd, and textstart points at the 1st
+	 * non-ws char in the block. */
+	if (!curbuf->b_p_et)
+	    i = ((ws_vcol % p_ts) + total) / p_ts; /* number of tabs */
+	if (i)
+	    j = ((ws_vcol % p_ts) + total) % p_ts; /* number of spp */
+	else
+	    j = total;
+	/* if we're splitting a TAB, allow for it */
+	bd.textcol -= bd.pre_whitesp_c - (bd.startspaces != 0);
+	len = (int)STRLEN(bd.textstart) + 1;
+	newp = alloc_check((unsigned)(bd.textcol + i + j + len));
+	if (newp == NULL)
+	    return;
+	vim_memset(newp, NUL, (size_t)(bd.textcol + i + j + len));
+	mch_memmove(newp, oldp, (size_t)bd.textcol);
+	copy_chars(newp + bd.textcol, (size_t)i, TAB);
+	copy_spaces(newp + bd.textcol + i, (size_t)j);
+	/* the end */
+	mch_memmove(newp + bd.textcol + i + j, bd.textstart, (size_t)len);
+    }
+    else /* left */
+    {
+	vcol = oap->start_vcol;
+	/* walk vcol past ws to be removed */
+	for (midp = oldp + bd.textcol;
+	      vcol < (oap->start_vcol + total) && vim_iswhite(*midp); )
+	{
+	    incr = lbr_chartabsize_adv(&midp, (colnr_T)vcol);
+	    vcol += incr;
+	}
+	/* internal is the block-internal ws replacing a split TAB */
+	if (vcol > (oap->start_vcol + total))
+	{
+	    /* we have to split the TAB *(midp-1) */
+	    internal = vcol - (oap->start_vcol + total);
+	}
+	/* if 'expandtab' is not set, use TABs */
+
+	split = bd.startspaces + internal;
+	if (split > 0)
+	{
+	    if (!curbuf->b_p_et)
+	    {
+		for (ptr = oldp, col = 0; ptr < oldp+bd.textcol; )
+		    col += lbr_chartabsize_adv(&ptr, (colnr_T)col);
+
+		/* col+1 now equals the start col of the first char of the
+		 * block (may be < oap.start_vcol if we're splitting a TAB) */
+		i = ((col % p_ts) + split) / p_ts; /* number of tabs */
+	    }
+	    if (i)
+		j = ((col % p_ts) + split) % p_ts; /* number of spp */
+	    else
+		j = split;
+	}
+
+	newp = alloc_check(bd.textcol + i + j + (unsigned)STRLEN(midp) + 1);
+	if (newp == NULL)
+	    return;
+	vim_memset(newp, NUL, (size_t)(bd.textcol + i + j + STRLEN(midp) + 1));
+
+	/* copy first part we want to keep */
+	mch_memmove(newp, oldp, (size_t)bd.textcol);
+	/* Now copy any TABS and spp to ensure correct alignment! */
+	while (vim_iswhite(*midp))
+	{
+	    if (*midp == TAB)
+		i++;
+	    else /*space */
+		j++;
+	    midp++;
+	}
+	/* We might have an extra TAB worth of spp now! */
+	if (j / p_ts && !curbuf->b_p_et)
+	{
+	    i++;
+	    j -= p_ts;
+	}
+	copy_chars(newp + bd.textcol, (size_t)i, TAB);
+	copy_spaces(newp + bd.textcol + i, (size_t)j);
+
+	/* the end */
+	mch_memmove(newp + STRLEN(newp), midp, (size_t)STRLEN(midp) + 1);
+    }
+    /* replace the line */
+    ml_replace(curwin->w_cursor.lnum, newp, FALSE);
+    changed_bytes(curwin->w_cursor.lnum, (colnr_T)bd.textcol);
+    State = oldstate;
+    curwin->w_cursor.col = oldcol;
+#ifdef FEAT_RIGHTLEFT
+    p_ri = old_p_ri;
+#endif
+}
+#endif
+
+#ifdef FEAT_VISUALEXTRA
+/*
+ * Insert string "s" (b_insert ? before : after) block :AKelly
+ * Caller must prepare for undo.
+ */
+    static void
+block_insert(oap, s, b_insert, bdp)
+    oparg_T		*oap;
+    char_u		*s;
+    int			b_insert;
+    struct block_def	*bdp;
+{
+    int		p_ts;
+    int		count = 0;	/* extra spaces to replace a cut TAB */
+    int		spaces = 0;	/* non-zero if cutting a TAB */
+    colnr_T	offset;		/* pointer along new line */
+    unsigned	s_len;		/* STRLEN(s) */
+    char_u	*newp, *oldp;	/* new, old lines */
+    linenr_T	lnum;		/* loop var */
+    int		oldstate = State;
+
+    State = INSERT;		/* don't want REPLACE for State */
+    s_len = (unsigned)STRLEN(s);
+
+    for (lnum = oap->start.lnum + 1; lnum <= oap->end.lnum; lnum++)
+    {
+	block_prep(oap, bdp, lnum, TRUE);
+	if (bdp->is_short && b_insert)
+	    continue;	/* OP_INSERT, line ends before block start */
+
+	oldp = ml_get(lnum);
+
+	if (b_insert)
+	{
+	    p_ts = bdp->start_char_vcols;
+	    spaces = bdp->startspaces;
+	    if (spaces != 0)
+		count = p_ts - 1; /* we're cutting a TAB */
+	    offset = bdp->textcol;
+	}
+	else /* append */
+	{
+	    p_ts = bdp->end_char_vcols;
+	    if (!bdp->is_short) /* spaces = padding after block */
+	    {
+		spaces = (bdp->endspaces ? p_ts - bdp->endspaces : 0);
+		if (spaces != 0)
+		    count = p_ts - 1; /* we're cutting a TAB */
+		offset = bdp->textcol + bdp->textlen - (spaces != 0);
+	    }
+	    else /* spaces = padding to block edge */
+	    {
+		/* if $ used, just append to EOL (ie spaces==0) */
+		if (!bdp->is_MAX)
+		    spaces = (oap->end_vcol - bdp->end_vcol) + 1;
+		count = spaces;
+		offset = bdp->textcol + bdp->textlen;
+	    }
+	}
+
+	newp = alloc_check((unsigned)(STRLEN(oldp)) + s_len + count + 1);
+	if (newp == NULL)
+	    continue;
+
+	/* copy up to shifted part */
+	mch_memmove(newp, oldp, (size_t)(offset));
+	oldp += offset;
+
+	/* insert pre-padding */
+	copy_spaces(newp + offset, (size_t)spaces);
+
+	/* copy the new text */
+	mch_memmove(newp + offset + spaces, s, (size_t)s_len);
+	offset += s_len;
+
+	if (spaces && !bdp->is_short)
+	{
+	    /* insert post-padding */
+	    copy_spaces(newp + offset + spaces, (size_t)(p_ts - spaces));
+	    /* We're splitting a TAB, don't copy it. */
+	    oldp++;
+	    /* We allowed for that TAB, remember this now */
+	    count++;
+	}
+
+	if (spaces > 0)
+	    offset += count;
+	mch_memmove(newp + offset, oldp, (size_t)(STRLEN(oldp) + 1));
+
+	ml_replace(lnum, newp, FALSE);
+
+	if (lnum == oap->end.lnum)
+	{
+	    /* Set "']" mark to the end of the block instead of the end of
+	     * the insert in the first line.  */
+	    curbuf->b_op_end.lnum = oap->end.lnum;
+	    curbuf->b_op_end.col = offset;
+	}
+    } /* for all lnum */
+
+    changed_lines(oap->start.lnum + 1, 0, oap->end.lnum + 1, 0L);
+
+    State = oldstate;
+}
+#endif
+
+#if defined(FEAT_LISP) || defined(FEAT_CINDENT) || defined(PROTO)
+/*
+ * op_reindent - handle reindenting a block of lines.
+ */
+    void
+op_reindent(oap, how)
+    oparg_T	*oap;
+    int		(*how) __ARGS((void));
+{
+    long	i;
+    char_u	*l;
+    int		count;
+    linenr_T	first_changed = 0;
+    linenr_T	last_changed = 0;
+    linenr_T	start_lnum = curwin->w_cursor.lnum;
+
+    /* Don't even try when 'modifiable' is off. */
+    if (!curbuf->b_p_ma)
+    {
+	EMSG(_(e_modifiable));
+	return;
+    }
+
+    for (i = oap->line_count; --i >= 0 && !got_int; )
+    {
+	/* it's a slow thing to do, so give feedback so there's no worry that
+	 * the computer's just hung. */
+
+	if (i > 1
+		&& (i % 50 == 0 || i == oap->line_count - 1)
+		&& oap->line_count > p_report)
+	    smsg((char_u *)_("%ld lines to indent... "), i);
+
+	/*
+	 * Be vi-compatible: For lisp indenting the first line is not
+	 * indented, unless there is only one line.
+	 */
+#ifdef FEAT_LISP
+	if (i != oap->line_count - 1 || oap->line_count == 1
+						    || how != get_lisp_indent)
+#endif
+	{
+	    l = skipwhite(ml_get_curline());
+	    if (*l == NUL)		    /* empty or blank line */
+		count = 0;
+	    else
+		count = how();		    /* get the indent for this line */
+
+	    if (set_indent(count, SIN_UNDO))
+	    {
+		/* did change the indent, call changed_lines() later */
+		if (first_changed == 0)
+		    first_changed = curwin->w_cursor.lnum;
+		last_changed = curwin->w_cursor.lnum;
+	    }
+	}
+	++curwin->w_cursor.lnum;
+    }
+
+    /* put cursor on first non-blank of indented line */
+    curwin->w_cursor.lnum = start_lnum;
+    beginline(BL_SOL | BL_FIX);
+
+    /* Mark changed lines so that they will be redrawn.  When Visual
+     * highlighting was present, need to continue until the last line.  When
+     * there is no change still need to remove the Visual highlighting. */
+    if (last_changed != 0)
+	changed_lines(first_changed, 0,
+#ifdef FEAT_VISUAL
+		oap->is_VIsual ? start_lnum + oap->line_count :
+#endif
+		last_changed + 1, 0L);
+#ifdef FEAT_VISUAL
+    else if (oap->is_VIsual)
+	redraw_curbuf_later(INVERTED);
+#endif
+
+    if (oap->line_count > p_report)
+    {
+	i = oap->line_count - (i + 1);
+	if (i == 1)
+	    MSG(_("1 line indented "));
+	else
+	    smsg((char_u *)_("%ld lines indented "), i);
+    }
+    /* set '[ and '] marks */
+    curbuf->b_op_start = oap->start;
+    curbuf->b_op_end = oap->end;
+}
+#endif /* defined(FEAT_LISP) || defined(FEAT_CINDENT) */
+
+#if defined(FEAT_EVAL) || defined(PROTO)
+/*
+ * Keep the last expression line here, for repeating.
+ */
+static char_u	*expr_line = NULL;
+
+/*
+ * Get an expression for the "\"=expr1" or "CTRL-R =expr1"
+ * Returns '=' when OK, NUL otherwise.
+ */
+    int
+get_expr_register()
+{
+    char_u	*new_line;
+
+    new_line = getcmdline('=', 0L, 0);
+    if (new_line == NULL)
+	return NUL;
+    if (*new_line == NUL)	/* use previous line */
+	vim_free(new_line);
+    else
+	set_expr_line(new_line);
+    return '=';
+}
+
+/*
+ * Set the expression for the '=' register.
+ * Argument must be an allocated string.
+ */
+    void
+set_expr_line(new_line)
+    char_u	*new_line;
+{
+    vim_free(expr_line);
+    expr_line = new_line;
+}
+
+/*
+ * Get the result of the '=' register expression.
+ * Returns a pointer to allocated memory, or NULL for failure.
+ */
+    char_u *
+get_expr_line()
+{
+    char_u	*expr_copy;
+    char_u	*rv;
+    static int	nested = 0;
+
+    if (expr_line == NULL)
+	return NULL;
+
+    /* Make a copy of the expression, because evaluating it may cause it to be
+     * changed. */
+    expr_copy = vim_strsave(expr_line);
+    if (expr_copy == NULL)
+	return NULL;
+
+    /* When we are invoked recursively limit the evaluation to 10 levels.
+     * Then return the string as-is. */
+    if (nested >= 10)
+	return expr_copy;
+
+    ++nested;
+    rv = eval_to_string(expr_copy, NULL, TRUE);
+    --nested;
+    vim_free(expr_copy);
+    return rv;
+}
+
+/*
+ * Get the '=' register expression itself, without evaluating it.
+ */
+    char_u *
+get_expr_line_src()
+{
+    if (expr_line == NULL)
+	return NULL;
+    return vim_strsave(expr_line);
+}
+#endif /* FEAT_EVAL */
+
+/*
+ * Check if 'regname' is a valid name of a yank register.
+ * Note: There is no check for 0 (default register), caller should do this
+ */
+    int
+valid_yank_reg(regname, writing)
+    int	    regname;
+    int	    writing;	    /* if TRUE check for writable registers */
+{
+    if (       (regname > 0 && ASCII_ISALNUM(regname))
+	    || (!writing && vim_strchr((char_u *)
+#ifdef FEAT_EVAL
+				    "/.%#:="
+#else
+				    "/.%#:"
+#endif
+					, regname) != NULL)
+	    || regname == '"'
+	    || regname == '-'
+	    || regname == '_'
+#ifdef FEAT_CLIPBOARD
+	    || regname == '*'
+	    || regname == '+'
+#endif
+#ifdef FEAT_DND
+	    || (!writing && regname == '~')
+#endif
+							)
+	return TRUE;
+    return FALSE;
+}
+
+/*
+ * Set y_current and y_append, according to the value of "regname".
+ * Cannot handle the '_' register.
+ * Must only be called with a valid register name!
+ *
+ * If regname is 0 and writing, use register 0
+ * If regname is 0 and reading, use previous register
+ */
+    void
+get_yank_register(regname, writing)
+    int	    regname;
+    int	    writing;
+{
+    int	    i;
+
+    y_append = FALSE;
+    if ((regname == 0 || regname == '"') && !writing && y_previous != NULL)
+    {
+	y_current = y_previous;
+	return;
+    }
+    i = regname;
+    if (VIM_ISDIGIT(i))
+	i -= '0';
+    else if (ASCII_ISLOWER(i))
+	i = CharOrdLow(i) + 10;
+    else if (ASCII_ISUPPER(i))
+    {
+	i = CharOrdUp(i) + 10;
+	y_append = TRUE;
+    }
+    else if (regname == '-')
+	i = DELETION_REGISTER;
+#ifdef FEAT_CLIPBOARD
+    /* When selection is not available, use register 0 instead of '*' */
+    else if (clip_star.available && regname == '*')
+	i = STAR_REGISTER;
+    /* When clipboard is not available, use register 0 instead of '+' */
+    else if (clip_plus.available && regname == '+')
+	i = PLUS_REGISTER;
+#endif
+#ifdef FEAT_DND
+    else if (!writing && regname == '~')
+	i = TILDE_REGISTER;
+#endif
+    else		/* not 0-9, a-z, A-Z or '-': use register 0 */
+	i = 0;
+    y_current = &(y_regs[i]);
+    if (writing)	/* remember the register we write into for do_put() */
+	y_previous = y_current;
+}
+
+#if defined(FEAT_CLIPBOARD) || defined(PROTO)
+/*
+ * When "regname" is a clipboard register, obtain the selection.  If it's not
+ * available return zero, otherwise return "regname".
+ */
+    int
+may_get_selection(regname)
+    int regname;
+{
+    if (regname == '*')
+    {
+	if (!clip_star.available)
+	    regname = 0;
+	else
+	    clip_get_selection(&clip_star);
+    }
+    else if (regname == '+')
+    {
+	if (!clip_plus.available)
+	    regname = 0;
+	else
+	    clip_get_selection(&clip_plus);
+    }
+    return regname;
+}
+#endif
+
+#if defined(FEAT_VISUAL) || defined(PROTO)
+/*
+ * Obtain the contents of a "normal" register. The register is made empty.
+ * The returned pointer has allocated memory, use put_register() later.
+ */
+    void *
+get_register(name, copy)
+    int		name;
+    int		copy;	/* make a copy, if FALSE make register empty. */
+{
+    static struct yankreg	*reg;
+    int				i;
+
+#ifdef FEAT_CLIPBOARD
+    /* When Visual area changed, may have to update selection.  Obtain the
+     * selection too. */
+    if (name == '*' && clip_star.available && clip_isautosel())
+    {
+	clip_update_selection();
+	may_get_selection(name);
+    }
+#endif
+
+    get_yank_register(name, 0);
+    reg = (struct yankreg *)alloc((unsigned)sizeof(struct yankreg));
+    if (reg != NULL)
+    {
+	*reg = *y_current;
+	if (copy)
+	{
+	    /* If we run out of memory some or all of the lines are empty. */
+	    if (reg->y_size == 0)
+		reg->y_array = NULL;
+	    else
+		reg->y_array = (char_u **)alloc((unsigned)(sizeof(char_u *)
+							      * reg->y_size));
+	    if (reg->y_array != NULL)
+	    {
+		for (i = 0; i < reg->y_size; ++i)
+		    reg->y_array[i] = vim_strsave(y_current->y_array[i]);
+	    }
+	}
+	else
+	    y_current->y_array = NULL;
+    }
+    return (void *)reg;
+}
+
+/*
+ * Put "reg" into register "name".  Free any previous contents.
+ */
+    void
+put_register(name, reg)
+    int		name;
+    void	*reg;
+{
+    get_yank_register(name, 0);
+    free_yank_all();
+    *y_current = *(struct yankreg *)reg;
+
+# ifdef FEAT_CLIPBOARD
+    /* Send text written to clipboard register to the clipboard. */
+    may_set_selection();
+# endif
+}
+#endif
+
+#if defined(FEAT_MOUSE) || defined(PROTO)
+/*
+ * return TRUE if the current yank register has type MLINE
+ */
+    int
+yank_register_mline(regname)
+    int	    regname;
+{
+    if (regname != 0 && !valid_yank_reg(regname, FALSE))
+	return FALSE;
+    if (regname == '_')		/* black hole is always empty */
+	return FALSE;
+    get_yank_register(regname, FALSE);
+    return (y_current->y_type == MLINE);
+}
+#endif
+
+/*
+ * Start or stop recording into a yank register.
+ *
+ * Return FAIL for failure, OK otherwise.
+ */
+    int
+do_record(c)
+    int c;
+{
+    char_u	    *p;
+    static int	    regname;
+    struct yankreg  *old_y_previous, *old_y_current;
+    int		    retval;
+
+    if (Recording == FALSE)	    /* start recording */
+    {
+			/* registers 0-9, a-z and " are allowed */
+	if (c < 0 || (!ASCII_ISALNUM(c) && c != '"'))
+	    retval = FAIL;
+	else
+	{
+	    Recording = TRUE;
+	    showmode();
+	    regname = c;
+	    retval = OK;
+	}
+    }
+    else			    /* stop recording */
+    {
+	/*
+	 * Get the recorded key hits.  K_SPECIAL and CSI will be escaped, this
+	 * needs to be removed again to put it in a register.  exec_reg then
+	 * adds the escaping back later.
+	 */
+	Recording = FALSE;
+	MSG("");
+	p = get_recorded();
+	if (p == NULL)
+	    retval = FAIL;
+	else
+	{
+	    /* Remove escaping for CSI and K_SPECIAL in multi-byte chars. */
+	    vim_unescape_csi(p);
+
+	    /*
+	     * We don't want to change the default register here, so save and
+	     * restore the current register name.
+	     */
+	    old_y_previous = y_previous;
+	    old_y_current = y_current;
+
+	    retval = stuff_yank(regname, p);
+
+	    y_previous = old_y_previous;
+	    y_current = old_y_current;
+	}
+    }
+    return retval;
+}
+
+/*
+ * Stuff string "p" into yank register "regname" as a single line (append if
+ * uppercase).	"p" must have been alloced.
+ *
+ * return FAIL for failure, OK otherwise
+ */
+    static int
+stuff_yank(regname, p)
+    int		regname;
+    char_u	*p;
+{
+    char_u	*lp;
+    char_u	**pp;
+
+    /* check for read-only register */
+    if (regname != 0 && !valid_yank_reg(regname, TRUE))
+    {
+	vim_free(p);
+	return FAIL;
+    }
+    if (regname == '_')		    /* black hole: don't do anything */
+    {
+	vim_free(p);
+	return OK;
+    }
+    get_yank_register(regname, TRUE);
+    if (y_append && y_current->y_array != NULL)
+    {
+	pp = &(y_current->y_array[y_current->y_size - 1]);
+	lp = lalloc((long_u)(STRLEN(*pp) + STRLEN(p) + 1), TRUE);
+	if (lp == NULL)
+	{
+	    vim_free(p);
+	    return FAIL;
+	}
+	STRCPY(lp, *pp);
+	STRCAT(lp, p);
+	vim_free(p);
+	vim_free(*pp);
+	*pp = lp;
+    }
+    else
+    {
+	free_yank_all();
+	if ((y_current->y_array =
+			(char_u **)alloc((unsigned)sizeof(char_u *))) == NULL)
+	{
+	    vim_free(p);
+	    return FAIL;
+	}
+	y_current->y_array[0] = p;
+	y_current->y_size = 1;
+	y_current->y_type = MCHAR;  /* used to be MLINE, why? */
+    }
+    return OK;
+}
+
+/*
+ * execute a yank register: copy it into the stuff buffer
+ *
+ * return FAIL for failure, OK otherwise
+ */
+    int
+do_execreg(regname, colon, addcr, silent)
+    int	    regname;
+    int	    colon;		/* insert ':' before each line */
+    int	    addcr;		/* always add '\n' to end of line */
+    int	    silent;		/* set "silent" flag in typeahead buffer */
+{
+    static int	lastc = NUL;
+    long	i;
+    char_u	*p;
+    int		retval = OK;
+    int		remap;
+
+    if (regname == '@')			/* repeat previous one */
+    {
+	if (lastc == NUL)
+	{
+	    EMSG(_("E748: No previously used register"));
+	    return FAIL;
+	}
+	regname = lastc;
+    }
+					/* check for valid regname */
+    if (regname == '%' || regname == '#' || !valid_yank_reg(regname, FALSE))
+    {
+	emsg_invreg(regname);
+	return FAIL;
+    }
+    lastc = regname;
+
+#ifdef FEAT_CLIPBOARD
+    regname = may_get_selection(regname);
+#endif
+
+    if (regname == '_')			/* black hole: don't stuff anything */
+	return OK;
+
+#ifdef FEAT_CMDHIST
+    if (regname == ':')			/* use last command line */
+    {
+	if (last_cmdline == NULL)
+	{
+	    EMSG(_(e_nolastcmd));
+	    return FAIL;
+	}
+	vim_free(new_last_cmdline); /* don't keep the cmdline containing @: */
+	new_last_cmdline = NULL;
+	/* Escape all control characters with a CTRL-V */
+	p = vim_strsave_escaped_ext(last_cmdline,
+		(char_u *)"\001\002\003\004\005\006\007\010\011\012\013\014\015\016\017\020\021\022\023\024\025\026\027\030\031\032\033\034\035\036\037", Ctrl_V, FALSE);
+	if (p != NULL)
+	{
+	    /* When in Visual mode "'<,'>" will be prepended to the command.
+	     * Remove it when it's already there. */
+	    if (VIsual_active && STRNCMP(p, "'<,'>", 5) == 0)
+		retval = put_in_typebuf(p + 5, TRUE, TRUE, silent);
+	    else
+		retval = put_in_typebuf(p, TRUE, TRUE, silent);
+	}
+	vim_free(p);
+    }
+#endif
+#ifdef FEAT_EVAL
+    else if (regname == '=')
+    {
+	p = get_expr_line();
+	if (p == NULL)
+	    return FAIL;
+	retval = put_in_typebuf(p, TRUE, colon, silent);
+	vim_free(p);
+    }
+#endif
+    else if (regname == '.')		/* use last inserted text */
+    {
+	p = get_last_insert_save();
+	if (p == NULL)
+	{
+	    EMSG(_(e_noinstext));
+	    return FAIL;
+	}
+	retval = put_in_typebuf(p, FALSE, colon, silent);
+	vim_free(p);
+    }
+    else
+    {
+	get_yank_register(regname, FALSE);
+	if (y_current->y_array == NULL)
+	    return FAIL;
+
+	/* Disallow remaping for ":@r". */
+	remap = colon ? REMAP_NONE : REMAP_YES;
+
+	/*
+	 * Insert lines into typeahead buffer, from last one to first one.
+	 */
+	put_reedit_in_typebuf(silent);
+	for (i = y_current->y_size; --i >= 0; )
+	{
+	    char_u *escaped;
+
+	    /* insert NL between lines and after last line if type is MLINE */
+	    if (y_current->y_type == MLINE || i < y_current->y_size - 1
+								     || addcr)
+	    {
+		if (ins_typebuf((char_u *)"\n", remap, 0, TRUE, silent) == FAIL)
+		    return FAIL;
+	    }
+	    escaped = vim_strsave_escape_csi(y_current->y_array[i]);
+	    if (escaped == NULL)
+		return FAIL;
+	    retval = ins_typebuf(escaped, remap, 0, TRUE, silent);
+	    vim_free(escaped);
+	    if (retval == FAIL)
+		return FAIL;
+	    if (colon && ins_typebuf((char_u *)":", remap, 0, TRUE, silent)
+								      == FAIL)
+		return FAIL;
+	}
+	Exec_reg = TRUE;	/* disable the 'q' command */
+    }
+    return retval;
+}
+
+/*
+ * If "restart_edit" is not zero, put it in the typeahead buffer, so that it's
+ * used only after other typeahead has been processed.
+ */
+    static void
+put_reedit_in_typebuf(silent)
+    int		silent;
+{
+    char_u	buf[3];
+
+    if (restart_edit != NUL)
+    {
+	if (restart_edit == 'V')
+	{
+	    buf[0] = 'g';
+	    buf[1] = 'R';
+	    buf[2] = NUL;
+	}
+	else
+	{
+	    buf[0] = restart_edit == 'I' ? 'i' : restart_edit;
+	    buf[1] = NUL;
+	}
+	if (ins_typebuf(buf, REMAP_NONE, 0, TRUE, silent) == OK)
+	    restart_edit = NUL;
+    }
+}
+
+    static int
+put_in_typebuf(s, esc, colon, silent)
+    char_u	*s;
+    int		esc;	    /* Escape CSI characters */
+    int		colon;	    /* add ':' before the line */
+    int		silent;
+{
+    int		retval = OK;
+
+    put_reedit_in_typebuf(silent);
+    if (colon)
+	retval = ins_typebuf((char_u *)"\n", REMAP_YES, 0, TRUE, silent);
+    if (retval == OK)
+    {
+	char_u	*p;
+
+	if (esc)
+	    p = vim_strsave_escape_csi(s);
+	else
+	    p = s;
+	if (p == NULL)
+	    retval = FAIL;
+	else
+	    retval = ins_typebuf(p, REMAP_YES, 0, TRUE, silent);
+	if (esc)
+	    vim_free(p);
+    }
+    if (colon && retval == OK)
+	retval = ins_typebuf((char_u *)":", REMAP_YES, 0, TRUE, silent);
+    return retval;
+}
+
+/*
+ * Insert a yank register: copy it into the Read buffer.
+ * Used by CTRL-R command and middle mouse button in insert mode.
+ *
+ * return FAIL for failure, OK otherwise
+ */
+    int
+insert_reg(regname, literally)
+    int		regname;
+    int		literally;	/* insert literally, not as if typed */
+{
+    long	i;
+    int		retval = OK;
+    char_u	*arg;
+    int		allocated;
+
+    /*
+     * It is possible to get into an endless loop by having CTRL-R a in
+     * register a and then, in insert mode, doing CTRL-R a.
+     * If you hit CTRL-C, the loop will be broken here.
+     */
+    ui_breakcheck();
+    if (got_int)
+	return FAIL;
+
+    /* check for valid regname */
+    if (regname != NUL && !valid_yank_reg(regname, FALSE))
+	return FAIL;
+
+#ifdef FEAT_CLIPBOARD
+    regname = may_get_selection(regname);
+#endif
+
+    if (regname == '.')			/* insert last inserted text */
+	retval = stuff_inserted(NUL, 1L, TRUE);
+    else if (get_spec_reg(regname, &arg, &allocated, TRUE))
+    {
+	if (arg == NULL)
+	    return FAIL;
+	stuffescaped(arg, literally);
+	if (allocated)
+	    vim_free(arg);
+    }
+    else				/* name or number register */
+    {
+	get_yank_register(regname, FALSE);
+	if (y_current->y_array == NULL)
+	    retval = FAIL;
+	else
+	{
+	    for (i = 0; i < y_current->y_size; ++i)
+	    {
+		stuffescaped(y_current->y_array[i], literally);
+		/*
+		 * Insert a newline between lines and after last line if
+		 * y_type is MLINE.
+		 */
+		if (y_current->y_type == MLINE || i < y_current->y_size - 1)
+		    stuffcharReadbuff('\n');
+	    }
+	}
+    }
+
+    return retval;
+}
+
+/*
+ * Stuff a string into the typeahead buffer, such that edit() will insert it
+ * literally ("literally" TRUE) or interpret is as typed characters.
+ */
+    static void
+stuffescaped(arg, literally)
+    char_u	*arg;
+    int		literally;
+{
+    int		c;
+    char_u	*start;
+
+    while (*arg != NUL)
+    {
+	/* Stuff a sequence of normal ASCII characters, that's fast.  Also
+	 * stuff K_SPECIAL to get the effect of a special key when "literally"
+	 * is TRUE. */
+	start = arg;
+	while ((*arg >= ' '
+#ifndef EBCDIC
+		    && *arg < DEL /* EBCDIC: chars above space are normal */
+#endif
+		    )
+		|| (*arg == K_SPECIAL && !literally))
+	    ++arg;
+	if (arg > start)
+	    stuffReadbuffLen(start, (long)(arg - start));
+
+	/* stuff a single special character */
+	if (*arg != NUL)
+	{
+#ifdef FEAT_MBYTE
+	    if (has_mbyte)
+		c = mb_ptr2char_adv(&arg);
+	    else
+#endif
+		c = *arg++;
+	    if (literally && ((c < ' ' && c != TAB) || c == DEL))
+		stuffcharReadbuff(Ctrl_V);
+	    stuffcharReadbuff(c);
+	}
+    }
+}
+
+/*
+ * If "regname" is a special register, return TRUE and store a pointer to its
+ * value in "argp".
+ */
+    int
+get_spec_reg(regname, argp, allocated, errmsg)
+    int		regname;
+    char_u	**argp;
+    int		*allocated;	/* return: TRUE when value was allocated */
+    int		errmsg;		/* give error message when failing */
+{
+    int		cnt;
+
+    *argp = NULL;
+    *allocated = FALSE;
+    switch (regname)
+    {
+	case '%':		/* file name */
+	    if (errmsg)
+		check_fname();	/* will give emsg if not set */
+	    *argp = curbuf->b_fname;
+	    return TRUE;
+
+	case '#':		/* alternate file name */
+	    *argp = getaltfname(errmsg);	/* may give emsg if not set */
+	    return TRUE;
+
+#ifdef FEAT_EVAL
+	case '=':		/* result of expression */
+	    *argp = get_expr_line();
+	    *allocated = TRUE;
+	    return TRUE;
+#endif
+
+	case ':':		/* last command line */
+	    if (last_cmdline == NULL && errmsg)
+		EMSG(_(e_nolastcmd));
+	    *argp = last_cmdline;
+	    return TRUE;
+
+	case '/':		/* last search-pattern */
+	    if (last_search_pat() == NULL && errmsg)
+		EMSG(_(e_noprevre));
+	    *argp = last_search_pat();
+	    return TRUE;
+
+	case '.':		/* last inserted text */
+	    *argp = get_last_insert_save();
+	    *allocated = TRUE;
+	    if (*argp == NULL && errmsg)
+		EMSG(_(e_noinstext));
+	    return TRUE;
+
+#ifdef FEAT_SEARCHPATH
+	case Ctrl_F:		/* Filename under cursor */
+	case Ctrl_P:		/* Path under cursor, expand via "path" */
+	    if (!errmsg)
+		return FALSE;
+	    *argp = file_name_at_cursor(FNAME_MESS | FNAME_HYP
+			    | (regname == Ctrl_P ? FNAME_EXP : 0), 1L, NULL);
+	    *allocated = TRUE;
+	    return TRUE;
+#endif
+
+	case Ctrl_W:		/* word under cursor */
+	case Ctrl_A:		/* WORD (mnemonic All) under cursor */
+	    if (!errmsg)
+		return FALSE;
+	    cnt = find_ident_under_cursor(argp, regname == Ctrl_W
+				   ?  (FIND_IDENT|FIND_STRING) : FIND_STRING);
+	    *argp = cnt ? vim_strnsave(*argp, cnt) : NULL;
+	    *allocated = TRUE;
+	    return TRUE;
+
+	case '_':		/* black hole: always empty */
+	    *argp = (char_u *)"";
+	    return TRUE;
+    }
+
+    return FALSE;
+}
+
+/*
+ * Paste a yank register into the command line.
+ * Only for non-special registers.
+ * Used by CTRL-R command in command-line mode
+ * insert_reg() can't be used here, because special characters from the
+ * register contents will be interpreted as commands.
+ *
+ * return FAIL for failure, OK otherwise
+ */
+    int
+cmdline_paste_reg(regname, literally, remcr)
+    int regname;
+    int literally;	/* Insert text literally instead of "as typed" */
+    int remcr;		/* don't add trailing CR */
+{
+    long	i;
+
+    get_yank_register(regname, FALSE);
+    if (y_current->y_array == NULL)
+	return FAIL;
+
+    for (i = 0; i < y_current->y_size; ++i)
+    {
+	cmdline_paste_str(y_current->y_array[i], literally);
+
+	/* Insert ^M between lines and after last line if type is MLINE.
+	 * Don't do this when "remcr" is TRUE and the next line is empty. */
+	if (y_current->y_type == MLINE
+		|| (i < y_current->y_size - 1
+		    && !(remcr
+			&& i == y_current->y_size - 2
+			&& *y_current->y_array[i + 1] == NUL)))
+	    cmdline_paste_str((char_u *)"\r", literally);
+
+	/* Check for CTRL-C, in case someone tries to paste a few thousand
+	 * lines and gets bored. */
+	ui_breakcheck();
+	if (got_int)
+	    return FAIL;
+    }
+    return OK;
+}
+
+#if defined(FEAT_CLIPBOARD) || defined(PROTO)
+/*
+ * Adjust the register name pointed to with "rp" for the clipboard being
+ * used always and the clipboard being available.
+ */
+    void
+adjust_clip_reg(rp)
+    int		*rp;
+{
+    /* If no reg. specified, and "unnamed" is in 'clipboard', use '*' reg. */
+    if (*rp == 0 && clip_unnamed)
+	*rp = '*';
+    if (!clip_star.available && *rp == '*')
+	*rp = 0;
+    if (!clip_plus.available && *rp == '+')
+	*rp = 0;
+}
+#endif
+
+/*
+ * op_delete - handle a delete operation
+ *
+ * return FAIL if undo failed, OK otherwise.
+ */
+    int
+op_delete(oap)
+    oparg_T   *oap;
+{
+    int			n;
+    linenr_T		lnum;
+    char_u		*ptr;
+#ifdef FEAT_VISUAL
+    char_u		*newp, *oldp;
+    struct block_def	bd;
+#endif
+    linenr_T		old_lcount = curbuf->b_ml.ml_line_count;
+    int			did_yank = FALSE;
+
+    if (curbuf->b_ml.ml_flags & ML_EMPTY)	    /* nothing to do */
+	return OK;
+
+    /* Nothing to delete, return here.	Do prepare undo, for op_change(). */
+    if (oap->empty)
+	return u_save_cursor();
+
+    if (!curbuf->b_p_ma)
+    {
+	EMSG(_(e_modifiable));
+	return FAIL;
+    }
+
+#ifdef FEAT_CLIPBOARD
+    adjust_clip_reg(&oap->regname);
+#endif
+
+#ifdef FEAT_MBYTE
+    if (has_mbyte)
+	mb_adjust_opend(oap);
+#endif
+
+/*
+ * Imitate the strange Vi behaviour: If the delete spans more than one line
+ * and motion_type == MCHAR and the result is a blank line, make the delete
+ * linewise.  Don't do this for the change command or Visual mode.
+ */
+    if (       oap->motion_type == MCHAR
+#ifdef FEAT_VISUAL
+	    && !oap->is_VIsual
+	    && !oap->block_mode
+#endif
+	    && oap->line_count > 1
+	    && oap->op_type == OP_DELETE)
+    {
+	ptr = ml_get(oap->end.lnum) + oap->end.col + oap->inclusive;
+	ptr = skipwhite(ptr);
+	if (*ptr == NUL && inindent(0))
+	    oap->motion_type = MLINE;
+    }
+
+/*
+ * Check for trying to delete (e.g. "D") in an empty line.
+ * Note: For the change operator it is ok.
+ */
+    if (       oap->motion_type == MCHAR
+	    && oap->line_count == 1
+	    && oap->op_type == OP_DELETE
+	    && *ml_get(oap->start.lnum) == NUL)
+    {
+	/*
+	 * It's an error to operate on an empty region, when 'E' included in
+	 * 'cpoptions' (Vi compatible).
+	 */
+#ifdef FEAT_VIRTUALEDIT
+	if (virtual_op)
+	    /* Virtual editing: Nothing gets deleted, but we set the '[ and ']
+	     * marks as if it happened. */
+	    goto setmarks;
+#endif
+	if (vim_strchr(p_cpo, CPO_EMPTYREGION) != NULL)
+	    beep_flush();
+	return OK;
+    }
+
+/*
+ * Do a yank of whatever we're about to delete.
+ * If a yank register was specified, put the deleted text into that register.
+ * For the black hole register '_' don't yank anything.
+ */
+    if (oap->regname != '_')
+    {
+	if (oap->regname != 0)
+	{
+	    /* check for read-only register */
+	    if (!valid_yank_reg(oap->regname, TRUE))
+	    {
+		beep_flush();
+		return OK;
+	    }
+	    get_yank_register(oap->regname, TRUE); /* yank into specif'd reg. */
+	    if (op_yank(oap, TRUE, FALSE) == OK)   /* yank without message */
+		did_yank = TRUE;
+	}
+
+	/*
+	 * Put deleted text into register 1 and shift number registers if the
+	 * delete contains a line break, or when a regname has been specified.
+	 */
+	if (oap->regname != 0 || oap->motion_type == MLINE
+				   || oap->line_count > 1 || oap->use_reg_one)
+	{
+	    y_current = &y_regs[9];
+	    free_yank_all();			/* free register nine */
+	    for (n = 9; n > 1; --n)
+		y_regs[n] = y_regs[n - 1];
+	    y_previous = y_current = &y_regs[1];
+	    y_regs[1].y_array = NULL;		/* set register one to empty */
+	    if (op_yank(oap, TRUE, FALSE) == OK)
+		did_yank = TRUE;
+	}
+
+	/* Yank into small delete register when no register specified and the
+	 * delete is within one line. */
+	if (oap->regname == 0 && oap->motion_type != MLINE
+						      && oap->line_count == 1)
+	{
+	    oap->regname = '-';
+	    get_yank_register(oap->regname, TRUE);
+	    if (op_yank(oap, TRUE, FALSE) == OK)
+		did_yank = TRUE;
+	    oap->regname = 0;
+	}
+
+	/*
+	 * If there's too much stuff to fit in the yank register, then get a
+	 * confirmation before doing the delete. This is crude, but simple.
+	 * And it avoids doing a delete of something we can't put back if we
+	 * want.
+	 */
+	if (!did_yank)
+	{
+	    int msg_silent_save = msg_silent;
+
+	    msg_silent = 0;	/* must display the prompt */
+	    n = ask_yesno((char_u *)_("cannot yank; delete anyway"), TRUE);
+	    msg_silent = msg_silent_save;
+	    if (n != 'y')
+	    {
+		EMSG(_(e_abort));
+		return FAIL;
+	    }
+	}
+    }
+
+#ifdef FEAT_VISUAL
+/*
+ * block mode delete
+ */
+    if (oap->block_mode)
+    {
+	if (u_save((linenr_T)(oap->start.lnum - 1),
+			       (linenr_T)(oap->end.lnum + 1)) == FAIL)
+	    return FAIL;
+
+	for (lnum = curwin->w_cursor.lnum; lnum <= oap->end.lnum; ++lnum)
+	{
+	    block_prep(oap, &bd, lnum, TRUE);
+	    if (bd.textlen == 0)	/* nothing to delete */
+		continue;
+
+	    /* Adjust cursor position for tab replaced by spaces and 'lbr'. */
+	    if (lnum == curwin->w_cursor.lnum)
+	    {
+		curwin->w_cursor.col = bd.textcol + bd.startspaces;
+# ifdef FEAT_VIRTUALEDIT
+		curwin->w_cursor.coladd = 0;
+# endif
+	    }
+
+	    /* n == number of chars deleted
+	     * If we delete a TAB, it may be replaced by several characters.
+	     * Thus the number of characters may increase!
+	     */
+	    n = bd.textlen - bd.startspaces - bd.endspaces;
+	    oldp = ml_get(lnum);
+	    newp = alloc_check((unsigned)STRLEN(oldp) + 1 - n);
+	    if (newp == NULL)
+		continue;
+	    /* copy up to deleted part */
+	    mch_memmove(newp, oldp, (size_t)bd.textcol);
+	    /* insert spaces */
+	    copy_spaces(newp + bd.textcol,
+				     (size_t)(bd.startspaces + bd.endspaces));
+	    /* copy the part after the deleted part */
+	    oldp += bd.textcol + bd.textlen;
+	    mch_memmove(newp + bd.textcol + bd.startspaces + bd.endspaces,
+						      oldp, STRLEN(oldp) + 1);
+	    /* replace the line */
+	    ml_replace(lnum, newp, FALSE);
+	}
+
+	check_cursor_col();
+	changed_lines(curwin->w_cursor.lnum, curwin->w_cursor.col,
+						       oap->end.lnum + 1, 0L);
+	oap->line_count = 0;	    /* no lines deleted */
+    }
+    else
+#endif
+	if (oap->motion_type == MLINE)
+    {
+	if (oap->op_type == OP_CHANGE)
+	{
+	    /* Delete the lines except the first one.  Temporarily move the
+	     * cursor to the next line.  Save the current line number, if the
+	     * last line is deleted it may be changed.
+	     */
+	    if (oap->line_count > 1)
+	    {
+		lnum = curwin->w_cursor.lnum;
+		++curwin->w_cursor.lnum;
+		del_lines((long)(oap->line_count - 1), TRUE);
+		curwin->w_cursor.lnum = lnum;
+	    }
+	    if (u_save_cursor() == FAIL)
+		return FAIL;
+	    if (curbuf->b_p_ai)		    /* don't delete indent */
+	    {
+		beginline(BL_WHITE);	    /* cursor on first non-white */
+		did_ai = TRUE;		    /* delete the indent when ESC hit */
+		ai_col = curwin->w_cursor.col;
+	    }
+	    else
+		beginline(0);		    /* cursor in column 0 */
+	    truncate_line(FALSE);   /* delete the rest of the line */
+				    /* leave cursor past last char in line */
+	    if (oap->line_count > 1)
+		u_clearline();	    /* "U" command not possible after "2cc" */
+	}
+	else
+	{
+	    del_lines(oap->line_count, TRUE);
+	    beginline(BL_WHITE | BL_FIX);
+	    u_clearline();	/* "U" command not possible after "dd" */
+	}
+    }
+    else
+    {
+#ifdef FEAT_VIRTUALEDIT
+	if (virtual_op)
+	{
+	    int		endcol = 0;
+
+	    /* For virtualedit: break the tabs that are partly included. */
+	    if (gchar_pos(&oap->start) == '\t')
+	    {
+		if (u_save_cursor() == FAIL)	/* save first line for undo */
+		    return FAIL;
+		if (oap->line_count == 1)
+		    endcol = getviscol2(oap->end.col, oap->end.coladd);
+		coladvance_force(getviscol2(oap->start.col, oap->start.coladd));
+		oap->start = curwin->w_cursor;
+		if (oap->line_count == 1)
+		{
+		    coladvance(endcol);
+		    oap->end.col = curwin->w_cursor.col;
+		    oap->end.coladd = curwin->w_cursor.coladd;
+		    curwin->w_cursor = oap->start;
+		}
+	    }
+
+	    /* Break a tab only when it's included in the area. */
+	    if (gchar_pos(&oap->end) == '\t'
+				     && (int)oap->end.coladd < oap->inclusive)
+	    {
+		/* save last line for undo */
+		if (u_save((linenr_T)(oap->end.lnum - 1),
+				       (linenr_T)(oap->end.lnum + 1)) == FAIL)
+		    return FAIL;
+		curwin->w_cursor = oap->end;
+		coladvance_force(getviscol2(oap->end.col, oap->end.coladd));
+		oap->end = curwin->w_cursor;
+		curwin->w_cursor = oap->start;
+	    }
+	}
+#endif
+
+	if (oap->line_count == 1)	/* delete characters within one line */
+	{
+	    if (u_save_cursor() == FAIL)	/* save line for undo */
+		return FAIL;
+
+	    /* if 'cpoptions' contains '$', display '$' at end of change */
+	    if (	   vim_strchr(p_cpo, CPO_DOLLAR) != NULL
+		    && oap->op_type == OP_CHANGE
+		    && oap->end.lnum == curwin->w_cursor.lnum
+#ifdef FEAT_VISUAL
+		    && !oap->is_VIsual
+#endif
+		    )
+		display_dollar(oap->end.col - !oap->inclusive);
+
+	    n = oap->end.col - oap->start.col + 1 - !oap->inclusive;
+
+#ifdef FEAT_VIRTUALEDIT
+	    if (virtual_op)
+	    {
+		/* fix up things for virtualedit-delete:
+		 * break the tabs which are going to get in our way
+		 */
+		char_u		*curline = ml_get_curline();
+		int		len = (int)STRLEN(curline);
+
+		if (oap->end.coladd != 0
+			&& (int)oap->end.col >= len - 1
+			&& !(oap->start.coladd && (int)oap->end.col >= len - 1))
+		    n++;
+		/* Delete at least one char (e.g, when on a control char). */
+		if (n == 0 && oap->start.coladd != oap->end.coladd)
+		    n = 1;
+
+		/* When deleted a char in the line, reset coladd. */
+		if (gchar_cursor() != NUL)
+		    curwin->w_cursor.coladd = 0;
+	    }
+#endif
+	    (void)del_bytes((long)n, !virtual_op, oap->op_type == OP_DELETE
+#ifdef FEAT_VISUAL
+				    && !oap->is_VIsual
+#endif
+							);
+	}
+	else				/* delete characters between lines */
+	{
+	    pos_T   curpos;
+
+	    /* save deleted and changed lines for undo */
+	    if (u_save((linenr_T)(curwin->w_cursor.lnum - 1),
+		 (linenr_T)(curwin->w_cursor.lnum + oap->line_count)) == FAIL)
+		return FAIL;
+
+	    truncate_line(TRUE);	/* delete from cursor to end of line */
+
+	    curpos = curwin->w_cursor;	/* remember curwin->w_cursor */
+	    ++curwin->w_cursor.lnum;
+	    del_lines((long)(oap->line_count - 2), FALSE);
+
+	    /* delete from start of line until op_end */
+	    curwin->w_cursor.col = 0;
+	    (void)del_bytes((long)(oap->end.col + 1 - !oap->inclusive),
+					!virtual_op, oap->op_type == OP_DELETE
+#ifdef FEAT_VISUAL
+					&& !oap->is_VIsual
+#endif
+							    );
+	    curwin->w_cursor = curpos;		/* restore curwin->w_cursor */
+
+	    (void)do_join(FALSE);
+	}
+    }
+
+    msgmore(curbuf->b_ml.ml_line_count - old_lcount);
+
+#ifdef FEAT_VIRTUALEDIT
+setmarks:
+#endif
+#ifdef FEAT_VISUAL
+    if (oap->block_mode)
+    {
+	curbuf->b_op_end.lnum = oap->end.lnum;
+	curbuf->b_op_end.col = oap->start.col;
+    }
+    else
+#endif
+	curbuf->b_op_end = oap->start;
+    curbuf->b_op_start = oap->start;
+
+    return OK;
+}
+
+#ifdef FEAT_MBYTE
+/*
+ * Adjust end of operating area for ending on a multi-byte character.
+ * Used for deletion.
+ */
+    static void
+mb_adjust_opend(oap)
+    oparg_T	*oap;
+{
+    char_u	*p;
+
+    if (oap->inclusive)
+    {
+	p = ml_get(oap->end.lnum);
+	oap->end.col += mb_tail_off(p, p + oap->end.col);
+    }
+}
+#endif
+
+#if defined(FEAT_VISUALEXTRA) || defined(PROTO)
+/*
+ * Replace a whole area with one character.
+ */
+    int
+op_replace(oap, c)
+    oparg_T   *oap;
+    int		c;
+{
+    int			n, numc;
+#ifdef FEAT_MBYTE
+    int			num_chars;
+#endif
+    char_u		*newp, *oldp;
+    size_t		oldlen;
+    struct block_def	bd;
+
+    if ((curbuf->b_ml.ml_flags & ML_EMPTY ) || oap->empty)
+	return OK;	    /* nothing to do */
+
+#ifdef FEAT_MBYTE
+    if (has_mbyte)
+	mb_adjust_opend(oap);
+#endif
+
+    if (u_save((linenr_T)(oap->start.lnum - 1),
+				       (linenr_T)(oap->end.lnum + 1)) == FAIL)
+	return FAIL;
+
+    /*
+     * block mode replace
+     */
+    if (oap->block_mode)
+    {
+	bd.is_MAX = (curwin->w_curswant == MAXCOL);
+	for ( ; curwin->w_cursor.lnum <= oap->end.lnum; ++curwin->w_cursor.lnum)
+	{
+	    block_prep(oap, &bd, curwin->w_cursor.lnum, TRUE);
+	    if (bd.textlen == 0 && (!virtual_op || bd.is_MAX))
+		continue;	    /* nothing to replace */
+
+	    /* n == number of extra chars required
+	     * If we split a TAB, it may be replaced by several characters.
+	     * Thus the number of characters may increase!
+	     */
+#ifdef FEAT_VIRTUALEDIT
+	    /* If the range starts in virtual space, count the initial
+	     * coladd offset as part of "startspaces" */
+	    if (virtual_op && bd.is_short && *bd.textstart == NUL)
+	    {
+		pos_T vpos;
+
+		getvpos(&vpos, oap->start_vcol);
+		bd.startspaces += vpos.coladd;
+		n = bd.startspaces;
+	    }
+	    else
+#endif
+		/* allow for pre spaces */
+		n = (bd.startspaces ? bd.start_char_vcols - 1 : 0);
+
+	    /* allow for post spp */
+	    n += (bd.endspaces
+#ifdef FEAT_VIRTUALEDIT
+		    && !bd.is_oneChar
+#endif
+		    && bd.end_char_vcols > 0) ? bd.end_char_vcols - 1 : 0;
+	    /* Figure out how many characters to replace. */
+	    numc = oap->end_vcol - oap->start_vcol + 1;
+	    if (bd.is_short && (!virtual_op || bd.is_MAX))
+		numc -= (oap->end_vcol - bd.end_vcol) + 1;
+
+#ifdef FEAT_MBYTE
+	    /* A double-wide character can be replaced only up to half the
+	     * times. */
+	    if ((*mb_char2cells)(c) > 1)
+	    {
+		if ((numc & 1) && !bd.is_short)
+		{
+		    ++bd.endspaces;
+		    ++n;
+		}
+		numc = numc / 2;
+	    }
+
+	    /* Compute bytes needed, move character count to num_chars. */
+	    num_chars = numc;
+	    numc *= (*mb_char2len)(c);
+#endif
+	    /* oldlen includes textlen, so don't double count */
+	    n += numc - bd.textlen;
+
+	    oldp = ml_get_curline();
+	    oldlen = STRLEN(oldp);
+	    newp = alloc_check((unsigned)oldlen + 1 + n);
+	    if (newp == NULL)
+		continue;
+	    vim_memset(newp, NUL, (size_t)(oldlen + 1 + n));
+	    /* copy up to deleted part */
+	    mch_memmove(newp, oldp, (size_t)bd.textcol);
+	    oldp += bd.textcol + bd.textlen;
+	    /* insert pre-spaces */
+	    copy_spaces(newp + bd.textcol, (size_t)bd.startspaces);
+	    /* insert replacement chars CHECK FOR ALLOCATED SPACE */
+#ifdef FEAT_MBYTE
+	    if (has_mbyte)
+	    {
+		n = (int)STRLEN(newp);
+		while (--num_chars >= 0)
+		    n += (*mb_char2bytes)(c, newp + n);
+	    }
+	    else
+#endif
+		copy_chars(newp + STRLEN(newp), (size_t)numc, c);
+	    if (!bd.is_short)
+	    {
+		/* insert post-spaces */
+		copy_spaces(newp + STRLEN(newp), (size_t)bd.endspaces);
+		/* copy the part after the changed part */
+		mch_memmove(newp + STRLEN(newp), oldp, STRLEN(oldp) + 1);
+	    }
+	    /* replace the line */
+	    ml_replace(curwin->w_cursor.lnum, newp, FALSE);
+	}
+    }
+    else
+    {
+	/*
+	 * MCHAR and MLINE motion replace.
+	 */
+	if (oap->motion_type == MLINE)
+	{
+	    oap->start.col = 0;
+	    curwin->w_cursor.col = 0;
+	    oap->end.col = (colnr_T)STRLEN(ml_get(oap->end.lnum));
+	    if (oap->end.col)
+		--oap->end.col;
+	}
+	else if (!oap->inclusive)
+	    dec(&(oap->end));
+
+	while (ltoreq(curwin->w_cursor, oap->end))
+	{
+	    n = gchar_cursor();
+	    if (n != NUL)
+	    {
+#ifdef FEAT_MBYTE
+		if ((*mb_char2len)(c) > 1 || (*mb_char2len)(n) > 1)
+		{
+		    /* This is slow, but it handles replacing a single-byte
+		     * with a multi-byte and the other way around. */
+		    oap->end.col += (*mb_char2len)(c) - (*mb_char2len)(n);
+		    n = State;
+		    State = REPLACE;
+		    ins_char(c);
+		    State = n;
+		    /* Backup to the replaced character. */
+		    dec_cursor();
+		}
+		else
+#endif
+		{
+#ifdef FEAT_VIRTUALEDIT
+		    if (n == TAB)
+		    {
+			int end_vcol = 0;
+
+			if (curwin->w_cursor.lnum == oap->end.lnum)
+			{
+			    /* oap->end has to be recalculated when
+			     * the tab breaks */
+			    end_vcol = getviscol2(oap->end.col,
+							     oap->end.coladd);
+			}
+			coladvance_force(getviscol());
+			if (curwin->w_cursor.lnum == oap->end.lnum)
+			    getvpos(&oap->end, end_vcol);
+		    }
+#endif
+		    pchar(curwin->w_cursor, c);
+		}
+	    }
+#ifdef FEAT_VIRTUALEDIT
+	    else if (virtual_op && curwin->w_cursor.lnum == oap->end.lnum)
+	    {
+		int virtcols = oap->end.coladd;
+
+		if (curwin->w_cursor.lnum == oap->start.lnum
+			&& oap->start.col == oap->end.col && oap->start.coladd)
+		    virtcols -= oap->start.coladd;
+
+		/* oap->end has been trimmed so it's effectively inclusive;
+		 * as a result an extra +1 must be counted so we don't
+		 * trample the NUL byte. */
+		coladvance_force(getviscol2(oap->end.col, oap->end.coladd) + 1);
+		curwin->w_cursor.col -= (virtcols + 1);
+		for (; virtcols >= 0; virtcols--)
+		{
+		    pchar(curwin->w_cursor, c);
+		    if (inc(&curwin->w_cursor) == -1)
+			break;
+		}
+	    }
+#endif
+
+	    /* Advance to next character, stop at the end of the file. */
+	    if (inc_cursor() == -1)
+		break;
+	}
+    }
+
+    curwin->w_cursor = oap->start;
+    check_cursor();
+    changed_lines(oap->start.lnum, oap->start.col, oap->end.lnum + 1, 0L);
+
+    /* Set "'[" and "']" marks. */
+    curbuf->b_op_start = oap->start;
+    curbuf->b_op_end = oap->end;
+
+    return OK;
+}
+#endif
+
+/*
+ * Handle the (non-standard vi) tilde operator.  Also for "gu", "gU" and "g?".
+ */
+    void
+op_tilde(oap)
+    oparg_T	*oap;
+{
+    pos_T		pos;
+#ifdef FEAT_VISUAL
+    struct block_def	bd;
+    int			todo;
+#endif
+    int			did_change = 0;
+
+    if (u_save((linenr_T)(oap->start.lnum - 1),
+				       (linenr_T)(oap->end.lnum + 1)) == FAIL)
+	return;
+
+    pos = oap->start;
+#ifdef FEAT_VISUAL
+    if (oap->block_mode)		    /* Visual block mode */
+    {
+	for (; pos.lnum <= oap->end.lnum; ++pos.lnum)
+	{
+	    block_prep(oap, &bd, pos.lnum, FALSE);
+	    pos.col = bd.textcol;
+	    for (todo = bd.textlen; todo > 0; --todo)
+	    {
+# ifdef FEAT_MBYTE
+		if (has_mbyte)
+		    todo -= (*mb_ptr2len)(ml_get_pos(&pos)) - 1;
+# endif
+		did_change |= swapchar(oap->op_type, &pos);
+		if (inc(&pos) == -1)	    /* at end of file */
+		    break;
+	    }
+# ifdef FEAT_NETBEANS_INTG
+	    if (usingNetbeans && did_change)
+	    {
+		char_u *ptr = ml_get_buf(curbuf, pos.lnum, FALSE);
+
+		netbeans_removed(curbuf, pos.lnum, bd.textcol,
+							    (long)bd.textlen);
+		netbeans_inserted(curbuf, pos.lnum, bd.textcol,
+				    &ptr[bd.textcol], bd.textlen);
+	    }
+# endif
+	}
+	if (did_change)
+	    changed_lines(oap->start.lnum, 0, oap->end.lnum + 1, 0L);
+    }
+    else				    /* not block mode */
+#endif
+    {
+	if (oap->motion_type == MLINE)
+	{
+	    oap->start.col = 0;
+	    pos.col = 0;
+	    oap->end.col = (colnr_T)STRLEN(ml_get(oap->end.lnum));
+	    if (oap->end.col)
+		--oap->end.col;
+	}
+	else if (!oap->inclusive)
+	    dec(&(oap->end));
+
+	while (ltoreq(pos, oap->end))
+	{
+	    did_change |= swapchar(oap->op_type, &pos);
+	    if (inc(&pos) == -1)    /* at end of file */
+		break;
+	}
+
+	if (did_change)
+	{
+	    changed_lines(oap->start.lnum, oap->start.col, oap->end.lnum + 1,
+									  0L);
+#ifdef FEAT_NETBEANS_INTG
+	    if (usingNetbeans && did_change)
+	    {
+		char_u *ptr;
+		int count;
+
+		pos = oap->start;
+		while (pos.lnum < oap->end.lnum)
+		{
+		    ptr = ml_get_buf(curbuf, pos.lnum, FALSE);
+		    count = (int)STRLEN(ptr) - pos.col;
+		    netbeans_removed(curbuf, pos.lnum, pos.col, (long)count);
+		    netbeans_inserted(curbuf, pos.lnum, pos.col,
+						 &ptr[pos.col], count);
+		    pos.col = 0;
+		    pos.lnum++;
+		}
+		ptr = ml_get_buf(curbuf, pos.lnum, FALSE);
+		count = oap->end.col - pos.col + 1;
+		netbeans_removed(curbuf, pos.lnum, pos.col, (long)count);
+		netbeans_inserted(curbuf, pos.lnum, pos.col,
+						 &ptr[pos.col], count);
+	    }
+#endif
+	}
+    }
+
+#ifdef FEAT_VISUAL
+    if (!did_change && oap->is_VIsual)
+	/* No change: need to remove the Visual selection */
+	redraw_curbuf_later(INVERTED);
+#endif
+
+    /*
+     * Set '[ and '] marks.
+     */
+    curbuf->b_op_start = oap->start;
+    curbuf->b_op_end = oap->end;
+
+    if (oap->line_count > p_report)
+    {
+	if (oap->line_count == 1)
+	    MSG(_("1 line changed"));
+	else
+	    smsg((char_u *)_("%ld lines changed"), oap->line_count);
+    }
+}
+
+/*
+ * If op_type == OP_UPPER: make uppercase,
+ * if op_type == OP_LOWER: make lowercase,
+ * if op_type == OP_ROT13: do rot13 encoding,
+ * else swap case of character at 'pos'
+ * returns TRUE when something actually changed.
+ */
+    int
+swapchar(op_type, pos)
+    int	    op_type;
+    pos_T    *pos;
+{
+    int	    c;
+    int	    nc;
+
+    c = gchar_pos(pos);
+
+    /* Only do rot13 encoding for ASCII characters. */
+    if (c >= 0x80 && op_type == OP_ROT13)
+	return FALSE;
+
+#ifdef FEAT_MBYTE
+    if (op_type == OP_UPPER && enc_latin1like && c == 0xdf)
+    {
+	pos_T   sp = curwin->w_cursor;
+
+	/* Special handling of German sharp s: change to "SS". */
+	curwin->w_cursor = *pos;
+	del_char(FALSE);
+	ins_char('S');
+	ins_char('S');
+	curwin->w_cursor = sp;
+	inc(pos);
+    }
+
+    if (enc_dbcs != 0 && c >= 0x100)	/* No lower/uppercase letter */
+	return FALSE;
+#endif
+    nc = c;
+    if (MB_ISLOWER(c))
+    {
+	if (op_type == OP_ROT13)
+	    nc = ROT13(c, 'a');
+	else if (op_type != OP_LOWER)
+	    nc = MB_TOUPPER(c);
+    }
+    else if (MB_ISUPPER(c))
+    {
+	if (op_type == OP_ROT13)
+	    nc = ROT13(c, 'A');
+	else if (op_type != OP_UPPER)
+	    nc = MB_TOLOWER(c);
+    }
+    if (nc != c)
+    {
+#ifdef FEAT_MBYTE
+	if (enc_utf8 && (c >= 0x80 || nc >= 0x80))
+	{
+	    pos_T   sp = curwin->w_cursor;
+
+	    curwin->w_cursor = *pos;
+	    del_char(FALSE);
+	    ins_char(nc);
+	    curwin->w_cursor = sp;
+	}
+	else
+#endif
+	    pchar(*pos, nc);
+	return TRUE;
+    }
+    return FALSE;
+}
+
+#if defined(FEAT_VISUALEXTRA) || defined(PROTO)
+/*
+ * op_insert - Insert and append operators for Visual mode.
+ */
+    void
+op_insert(oap, count1)
+    oparg_T	*oap;
+    long	count1;
+{
+    long		ins_len, pre_textlen = 0;
+    char_u		*firstline, *ins_text;
+    struct block_def	bd;
+    int			i;
+
+    /* edit() changes this - record it for OP_APPEND */
+    bd.is_MAX = (curwin->w_curswant == MAXCOL);
+
+    /* vis block is still marked. Get rid of it now. */
+    curwin->w_cursor.lnum = oap->start.lnum;
+    update_screen(INVERTED);
+
+    if (oap->block_mode)
+    {
+#ifdef FEAT_VIRTUALEDIT
+	/* When 'virtualedit' is used, need to insert the extra spaces before
+	 * doing block_prep().  When only "block" is used, virtual edit is
+	 * already disabled, but still need it when calling
+	 * coladvance_force(). */
+	if (curwin->w_cursor.coladd > 0)
+	{
+	    int		old_ve_flags = ve_flags;
+
+	    ve_flags = VE_ALL;
+	    if (u_save_cursor() == FAIL)
+		return;
+	    coladvance_force(oap->op_type == OP_APPEND
+					   ? oap->end_vcol + 1 : getviscol());
+	    if (oap->op_type == OP_APPEND)
+		--curwin->w_cursor.col;
+	    ve_flags = old_ve_flags;
+	}
+#endif
+	/* Get the info about the block before entering the text */
+	block_prep(oap, &bd, oap->start.lnum, TRUE);
+	firstline = ml_get(oap->start.lnum) + bd.textcol;
+	if (oap->op_type == OP_APPEND)
+	    firstline += bd.textlen;
+	pre_textlen = (long)STRLEN(firstline);
+    }
+
+    if (oap->op_type == OP_APPEND)
+    {
+	if (oap->block_mode
+#ifdef FEAT_VIRTUALEDIT
+		&& curwin->w_cursor.coladd == 0
+#endif
+	   )
+	{
+	    /* Move the cursor to the character right of the block. */
+	    curwin->w_set_curswant = TRUE;
+	    while (*ml_get_cursor() != NUL
+		    && (curwin->w_cursor.col < bd.textcol + bd.textlen))
+		++curwin->w_cursor.col;
+	    if (bd.is_short && !bd.is_MAX)
+	    {
+		/* First line was too short, make it longer and adjust the
+		 * values in "bd". */
+		if (u_save_cursor() == FAIL)
+		    return;
+		for (i = 0; i < bd.endspaces; ++i)
+		    ins_char(' ');
+		bd.textlen += bd.endspaces;
+	    }
+	}
+	else
+	{
+	    curwin->w_cursor = oap->end;
+	    check_cursor_col();
+
+	    /* Works just like an 'i'nsert on the next character. */
+	    if (!lineempty(curwin->w_cursor.lnum)
+		    && oap->start_vcol != oap->end_vcol)
+		inc_cursor();
+	}
+    }
+
+    edit(NUL, FALSE, (linenr_T)count1);
+
+    /* if user has moved off this line, we don't know what to do, so do
+     * nothing */
+    if (curwin->w_cursor.lnum != oap->start.lnum)
+	return;
+
+    if (oap->block_mode)
+    {
+	struct block_def	bd2;
+
+	/*
+	 * Spaces and tabs in the indent may have changed to other spaces and
+	 * tabs.  Get the starting column again and correct the lenght.
+	 * Don't do this when "$" used, end-of-line will have changed.
+	 */
+	block_prep(oap, &bd2, oap->start.lnum, TRUE);
+	if (!bd.is_MAX || bd2.textlen < bd.textlen)
+	{
+	    if (oap->op_type == OP_APPEND)
+	    {
+		pre_textlen += bd2.textlen - bd.textlen;
+		if (bd2.endspaces)
+		    --bd2.textlen;
+	    }
+	    bd.textcol = bd2.textcol;
+	    bd.textlen = bd2.textlen;
+	}
+
+	/*
+	 * Subsequent calls to ml_get() flush the firstline data - take a
+	 * copy of the required string.
+	 */
+	firstline = ml_get(oap->start.lnum) + bd.textcol;
+	if (oap->op_type == OP_APPEND)
+	    firstline += bd.textlen;
+	if ((ins_len = (long)STRLEN(firstline) - pre_textlen) > 0)
+	{
+	    ins_text = vim_strnsave(firstline, (int)ins_len);
+	    if (ins_text != NULL)
+	    {
+		/* block handled here */
+		if (u_save(oap->start.lnum,
+					 (linenr_T)(oap->end.lnum + 1)) == OK)
+		    block_insert(oap, ins_text, (oap->op_type == OP_INSERT),
+									 &bd);
+
+		curwin->w_cursor.col = oap->start.col;
+		check_cursor();
+		vim_free(ins_text);
+	    }
+	}
+    }
+}
+#endif
+
+/*
+ * op_change - handle a change operation
+ *
+ * return TRUE if edit() returns because of a CTRL-O command
+ */
+    int
+op_change(oap)
+    oparg_T	*oap;
+{
+    colnr_T		l;
+    int			retval;
+#ifdef FEAT_VISUALEXTRA
+    long		offset;
+    linenr_T		linenr;
+    long		ins_len, pre_textlen = 0;
+    char_u		*firstline;
+    char_u		*ins_text, *newp, *oldp;
+    struct block_def	bd;
+#endif
+
+    l = oap->start.col;
+    if (oap->motion_type == MLINE)
+    {
+	l = 0;
+#ifdef FEAT_SMARTINDENT
+	if (!p_paste && curbuf->b_p_si
+# ifdef FEAT_CINDENT
+		&& !curbuf->b_p_cin
+# endif
+		)
+	    can_si = TRUE;	/* It's like opening a new line, do si */
+#endif
+    }
+
+    /* First delete the text in the region.  In an empty buffer only need to
+     * save for undo */
+    if (curbuf->b_ml.ml_flags & ML_EMPTY)
+    {
+	if (u_save_cursor() == FAIL)
+	    return FALSE;
+    }
+    else if (op_delete(oap) == FAIL)
+	return FALSE;
+
+    if ((l > curwin->w_cursor.col) && !lineempty(curwin->w_cursor.lnum)
+							 && !virtual_op)
+	inc_cursor();
+
+#ifdef FEAT_VISUALEXTRA
+    /* check for still on same line (<CR> in inserted text meaningless) */
+    /* skip blank lines too */
+    if (oap->block_mode)
+    {
+# ifdef FEAT_VIRTUALEDIT
+	/* Add spaces before getting the current line length. */
+	if (virtual_op && (curwin->w_cursor.coladd > 0
+						    || gchar_cursor() == NUL))
+	    coladvance_force(getviscol());
+# endif
+	pre_textlen = (long)STRLEN(ml_get(oap->start.lnum));
+	bd.textcol = curwin->w_cursor.col;
+    }
+#endif
+
+#if defined(FEAT_LISP) || defined(FEAT_CINDENT)
+    if (oap->motion_type == MLINE)
+	fix_indent();
+#endif
+
+    retval = edit(NUL, FALSE, (linenr_T)1);
+
+#ifdef FEAT_VISUALEXTRA
+    /*
+     * In Visual block mode, handle copying the new text to all lines of the
+     * block.
+     */
+    if (oap->block_mode && oap->start.lnum != oap->end.lnum)
+    {
+	firstline = ml_get(oap->start.lnum);
+	/*
+	 * Subsequent calls to ml_get() flush the firstline data - take a
+	 * copy of the required bit.
+	 */
+	if ((ins_len = (long)STRLEN(firstline) - pre_textlen) > 0)
+	{
+	    if ((ins_text = alloc_check((unsigned)(ins_len + 1))) != NULL)
+	    {
+		vim_strncpy(ins_text, firstline + bd.textcol, (size_t)ins_len);
+		for (linenr = oap->start.lnum + 1; linenr <= oap->end.lnum;
+								     linenr++)
+		{
+		    block_prep(oap, &bd, linenr, TRUE);
+		    if (!bd.is_short || virtual_op)
+		    {
+# ifdef FEAT_VIRTUALEDIT
+			pos_T vpos;
+
+			/* If the block starts in virtual space, count the
+			 * initial coladd offset as part of "startspaces" */
+			if (bd.is_short)
+			{
+			    linenr_T lnum = curwin->w_cursor.lnum;
+
+			    curwin->w_cursor.lnum = linenr;
+			    (void)getvpos(&vpos, oap->start_vcol);
+			    curwin->w_cursor.lnum = lnum;
+			}
+			else
+			    vpos.coladd = 0;
+# endif
+			oldp = ml_get(linenr);
+			newp = alloc_check((unsigned)(STRLEN(oldp)
+# ifdef FEAT_VIRTUALEDIT
+							+ vpos.coladd
+# endif
+							      + ins_len + 1));
+			if (newp == NULL)
+			    continue;
+			/* copy up to block start */
+			mch_memmove(newp, oldp, (size_t)bd.textcol);
+			offset = bd.textcol;
+# ifdef FEAT_VIRTUALEDIT
+			copy_spaces(newp + offset, (size_t)vpos.coladd);
+			offset += vpos.coladd;
+# endif
+			mch_memmove(newp + offset, ins_text, (size_t)ins_len);
+			offset += ins_len;
+			oldp += bd.textcol;
+			mch_memmove(newp + offset, oldp, STRLEN(oldp) + 1);
+			ml_replace(linenr, newp, FALSE);
+		    }
+		}
+		check_cursor();
+
+		changed_lines(oap->start.lnum + 1, 0, oap->end.lnum + 1, 0L);
+	    }
+	    vim_free(ins_text);
+	}
+    }
+#endif
+
+    return retval;
+}
+
+/*
+ * set all the yank registers to empty (called from main())
+ */
+    void
+init_yank()
+{
+    int		i;
+
+    for (i = 0; i < NUM_REGISTERS; ++i)
+	y_regs[i].y_array = NULL;
+}
+
+#if defined(EXITFREE) || defined(PROTO)
+    void
+clear_registers()
+{
+    int		i;
+
+    for (i = 0; i < NUM_REGISTERS; ++i)
+    {
+	y_current = &y_regs[i];
+	if (y_current->y_array != NULL)
+	    free_yank_all();
+    }
+}
+#endif
+
+/*
+ * Free "n" lines from the current yank register.
+ * Called for normal freeing and in case of error.
+ */
+    static void
+free_yank(n)
+    long	n;
+{
+    if (y_current->y_array != NULL)
+    {
+	long	    i;
+
+	for (i = n; --i >= 0; )
+	{
+#ifdef AMIGA	    /* only for very slow machines */
+	    if ((i & 1023) == 1023)  /* this may take a while */
+	    {
+		/*
+		 * This message should never cause a hit-return message.
+		 * Overwrite this message with any next message.
+		 */
+		++no_wait_return;
+		smsg((char_u *)_("freeing %ld lines"), i + 1);
+		--no_wait_return;
+		msg_didout = FALSE;
+		msg_col = 0;
+	    }
+#endif
+	    vim_free(y_current->y_array[i]);
+	}
+	vim_free(y_current->y_array);
+	y_current->y_array = NULL;
+#ifdef AMIGA
+	if (n >= 1000)
+	    MSG("");
+#endif
+    }
+}
+
+    static void
+free_yank_all()
+{
+    free_yank(y_current->y_size);
+}
+
+/*
+ * Yank the text between "oap->start" and "oap->end" into a yank register.
+ * If we are to append (uppercase register), we first yank into a new yank
+ * register and then concatenate the old and the new one (so we keep the old
+ * one in case of out-of-memory).
+ *
+ * return FAIL for failure, OK otherwise
+ */
+    int
+op_yank(oap, deleting, mess)
+    oparg_T   *oap;
+    int	    deleting;
+    int	    mess;
+{
+    long		y_idx;		/* index in y_array[] */
+    struct yankreg	*curr;		/* copy of y_current */
+    struct yankreg	newreg;		/* new yank register when appending */
+    char_u		**new_ptr;
+    linenr_T		lnum;		/* current line number */
+    long		j;
+    int			yanktype = oap->motion_type;
+    long		yanklines = oap->line_count;
+    linenr_T		yankendlnum = oap->end.lnum;
+    char_u		*p;
+    char_u		*pnew;
+    struct block_def	bd;
+
+				    /* check for read-only register */
+    if (oap->regname != 0 && !valid_yank_reg(oap->regname, TRUE))
+    {
+	beep_flush();
+	return FAIL;
+    }
+    if (oap->regname == '_')	    /* black hole: nothing to do */
+	return OK;
+
+#ifdef FEAT_CLIPBOARD
+    if (!clip_star.available && oap->regname == '*')
+	oap->regname = 0;
+    else if (!clip_plus.available && oap->regname == '+')
+	oap->regname = 0;
+#endif
+
+    if (!deleting)		    /* op_delete() already set y_current */
+	get_yank_register(oap->regname, TRUE);
+
+    curr = y_current;
+				    /* append to existing contents */
+    if (y_append && y_current->y_array != NULL)
+	y_current = &newreg;
+    else
+	free_yank_all();	    /* free previously yanked lines */
+
+    /*
+     * If the cursor was in column 1 before and after the movement, and the
+     * operator is not inclusive, the yank is always linewise.
+     */
+    if (       oap->motion_type == MCHAR
+	    && oap->start.col == 0
+	    && !oap->inclusive
+#ifdef FEAT_VISUAL
+	    && (!oap->is_VIsual || *p_sel == 'o')
+	    && !oap->block_mode
+#endif
+	    && oap->end.col == 0
+	    && yanklines > 1)
+    {
+	yanktype = MLINE;
+	--yankendlnum;
+	--yanklines;
+    }
+
+    y_current->y_size = yanklines;
+    y_current->y_type = yanktype;   /* set the yank register type */
+#ifdef FEAT_VISUAL
+    y_current->y_width = 0;
+#endif
+    y_current->y_array = (char_u **)lalloc_clear((long_u)(sizeof(char_u *) *
+							    yanklines), TRUE);
+
+    if (y_current->y_array == NULL)
+    {
+	y_current = curr;
+	return FAIL;
+    }
+
+    y_idx = 0;
+    lnum = oap->start.lnum;
+
+#ifdef FEAT_VISUAL
+    if (oap->block_mode)
+    {
+	/* Visual block mode */
+	y_current->y_type = MBLOCK;	    /* set the yank register type */
+	y_current->y_width = oap->end_vcol - oap->start_vcol;
+
+	if (curwin->w_curswant == MAXCOL && y_current->y_width > 0)
+	    y_current->y_width--;
+    }
+#endif
+
+    for ( ; lnum <= yankendlnum; lnum++, y_idx++)
+    {
+	switch (y_current->y_type)
+	{
+#ifdef FEAT_VISUAL
+	    case MBLOCK:
+		block_prep(oap, &bd, lnum, FALSE);
+		if (yank_copy_line(&bd, y_idx) == FAIL)
+		    goto fail;
+		break;
+#endif
+
+	    case MLINE:
+		if ((y_current->y_array[y_idx] =
+			    vim_strsave(ml_get(lnum))) == NULL)
+		    goto fail;
+		break;
+
+	    case MCHAR:
+		{
+		    colnr_T startcol = 0, endcol = MAXCOL;
+#ifdef FEAT_VIRTUALEDIT
+		    int is_oneChar = FALSE;
+		    colnr_T cs, ce;
+#endif
+		    p = ml_get(lnum);
+		    bd.startspaces = 0;
+		    bd.endspaces = 0;
+
+		    if (lnum == oap->start.lnum)
+		    {
+			startcol = oap->start.col;
+#ifdef FEAT_VIRTUALEDIT
+			if (virtual_op)
+			{
+			    getvcol(curwin, &oap->start, &cs, NULL, &ce);
+			    if (ce != cs && oap->start.coladd > 0)
+			    {
+				/* Part of a tab selected -- but don't
+				 * double-count it. */
+				bd.startspaces = (ce - cs + 1)
+							  - oap->start.coladd;
+				startcol++;
+			    }
+			}
+#endif
+		    }
+
+		    if (lnum == oap->end.lnum)
+		    {
+			endcol = oap->end.col;
+#ifdef FEAT_VIRTUALEDIT
+			if (virtual_op)
+			{
+			    getvcol(curwin, &oap->end, &cs, NULL, &ce);
+			    if (p[endcol] == NUL || (cs + oap->end.coladd < ce
+# ifdef FEAT_MBYTE
+					/* Don't add space for double-wide
+					 * char; endcol will be on last byte
+					 * of multi-byte char. */
+					&& (*mb_head_off)(p, p + endcol) == 0
+# endif
+					))
+			    {
+				if (oap->start.lnum == oap->end.lnum
+					    && oap->start.col == oap->end.col)
+				{
+				    /* Special case: inside a single char */
+				    is_oneChar = TRUE;
+				    bd.startspaces = oap->end.coladd
+					 - oap->start.coladd + oap->inclusive;
+				    endcol = startcol;
+				}
+				else
+				{
+				    bd.endspaces = oap->end.coladd
+							     + oap->inclusive;
+				    endcol -= oap->inclusive;
+				}
+			    }
+			}
+#endif
+		    }
+		    if (startcol > endcol
+#ifdef FEAT_VIRTUALEDIT
+			    || is_oneChar
+#endif
+			    )
+			bd.textlen = 0;
+		    else
+		    {
+			if (endcol == MAXCOL)
+			    endcol = (colnr_T)STRLEN(p);
+			bd.textlen = endcol - startcol + oap->inclusive;
+		    }
+		    bd.textstart = p + startcol;
+		    if (yank_copy_line(&bd, y_idx) == FAIL)
+			goto fail;
+		    break;
+		}
+		/* NOTREACHED */
+	}
+    }
+
+    if (curr != y_current)	/* append the new block to the old block */
+    {
+	new_ptr = (char_u **)lalloc((long_u)(sizeof(char_u *) *
+				   (curr->y_size + y_current->y_size)), TRUE);
+	if (new_ptr == NULL)
+	    goto fail;
+	for (j = 0; j < curr->y_size; ++j)
+	    new_ptr[j] = curr->y_array[j];
+	vim_free(curr->y_array);
+	curr->y_array = new_ptr;
+
+	if (yanktype == MLINE)	/* MLINE overrides MCHAR and MBLOCK */
+	    curr->y_type = MLINE;
+
+	/* Concatenate the last line of the old block with the first line of
+	 * the new block, unless being Vi compatible. */
+	if (curr->y_type == MCHAR && vim_strchr(p_cpo, CPO_REGAPPEND) == NULL)
+	{
+	    pnew = lalloc((long_u)(STRLEN(curr->y_array[curr->y_size - 1])
+			      + STRLEN(y_current->y_array[0]) + 1), TRUE);
+	    if (pnew == NULL)
+	    {
+		y_idx = y_current->y_size - 1;
+		goto fail;
+	    }
+	    STRCPY(pnew, curr->y_array[--j]);
+	    STRCAT(pnew, y_current->y_array[0]);
+	    vim_free(curr->y_array[j]);
+	    vim_free(y_current->y_array[0]);
+	    curr->y_array[j++] = pnew;
+	    y_idx = 1;
+	}
+	else
+	    y_idx = 0;
+	while (y_idx < y_current->y_size)
+	    curr->y_array[j++] = y_current->y_array[y_idx++];
+	curr->y_size = j;
+	vim_free(y_current->y_array);
+	y_current = curr;
+    }
+    if (mess)			/* Display message about yank? */
+    {
+	if (yanktype == MCHAR
+#ifdef FEAT_VISUAL
+		&& !oap->block_mode
+#endif
+		&& yanklines == 1)
+	    yanklines = 0;
+	/* Some versions of Vi use ">=" here, some don't...  */
+	if (yanklines > p_report)
+	{
+	    /* redisplay now, so message is not deleted */
+	    update_topline_redraw();
+	    if (yanklines == 1)
+	    {
+#ifdef FEAT_VISUAL
+		if (oap->block_mode)
+		    MSG(_("block of 1 line yanked"));
+		else
+#endif
+		    MSG(_("1 line yanked"));
+	    }
+#ifdef FEAT_VISUAL
+	    else if (oap->block_mode)
+		smsg((char_u *)_("block of %ld lines yanked"), yanklines);
+#endif
+	    else
+		smsg((char_u *)_("%ld lines yanked"), yanklines);
+	}
+    }
+
+    /*
+     * Set "'[" and "']" marks.
+     */
+    curbuf->b_op_start = oap->start;
+    curbuf->b_op_end = oap->end;
+    if (yanktype == MLINE
+#ifdef FEAT_VISUAL
+		&& !oap->block_mode
+#endif
+       )
+    {
+	curbuf->b_op_start.col = 0;
+	curbuf->b_op_end.col = MAXCOL;
+    }
+
+#ifdef FEAT_CLIPBOARD
+    /*
+     * If we were yanking to the '*' register, send result to clipboard.
+     * If no register was specified, and "unnamed" in 'clipboard', make a copy
+     * to the '*' register.
+     */
+    if (clip_star.available
+	    && (curr == &(y_regs[STAR_REGISTER])
+		|| (!deleting && oap->regname == 0 && clip_unnamed)))
+    {
+	if (curr != &(y_regs[STAR_REGISTER]))
+	    /* Copy the text from register 0 to the clipboard register. */
+	    copy_yank_reg(&(y_regs[STAR_REGISTER]));
+
+	clip_own_selection(&clip_star);
+	clip_gen_set_selection(&clip_star);
+    }
+
+# ifdef FEAT_X11
+    /*
+     * If we were yanking to the '+' register, send result to selection.
+     * Also copy to the '*' register, in case auto-select is off.
+     */
+    else if (clip_plus.available && curr == &(y_regs[PLUS_REGISTER]))
+    {
+	/* No need to copy to * register upon 'unnamed' now - see below */
+	clip_own_selection(&clip_plus);
+	clip_gen_set_selection(&clip_plus);
+	if (!clip_isautosel())
+	{
+	    copy_yank_reg(&(y_regs[STAR_REGISTER]));
+	    clip_own_selection(&clip_star);
+	    clip_gen_set_selection(&clip_star);
+	}
+    }
+# endif
+#endif
+
+    return OK;
+
+fail:		/* free the allocated lines */
+    free_yank(y_idx + 1);
+    y_current = curr;
+    return FAIL;
+}
+
+    static int
+yank_copy_line(bd, y_idx)
+    struct block_def	*bd;
+    long		y_idx;
+{
+    char_u	*pnew;
+
+    if ((pnew = alloc(bd->startspaces + bd->endspaces + bd->textlen + 1))
+								      == NULL)
+	return FAIL;
+    y_current->y_array[y_idx] = pnew;
+    copy_spaces(pnew, (size_t)bd->startspaces);
+    pnew += bd->startspaces;
+    mch_memmove(pnew, bd->textstart, (size_t)bd->textlen);
+    pnew += bd->textlen;
+    copy_spaces(pnew, (size_t)bd->endspaces);
+    pnew += bd->endspaces;
+    *pnew = NUL;
+    return OK;
+}
+
+#ifdef FEAT_CLIPBOARD
+/*
+ * Make a copy of the y_current register to register "reg".
+ */
+    static void
+copy_yank_reg(reg)
+    struct yankreg *reg;
+{
+    struct yankreg	*curr = y_current;
+    long		j;
+
+    y_current = reg;
+    free_yank_all();
+    *y_current = *curr;
+    y_current->y_array = (char_u **)lalloc_clear(
+			(long_u)(sizeof(char_u *) * y_current->y_size), TRUE);
+    if (y_current->y_array == NULL)
+	y_current->y_size = 0;
+    else
+	for (j = 0; j < y_current->y_size; ++j)
+	    if ((y_current->y_array[j] = vim_strsave(curr->y_array[j])) == NULL)
+	    {
+		free_yank(j);
+		y_current->y_size = 0;
+		break;
+	    }
+    y_current = curr;
+}
+#endif
+
+/*
+ * Put contents of register "regname" into the text.
+ * Caller must check "regname" to be valid!
+ * "flags": PUT_FIXINDENT	make indent look nice
+ *	    PUT_CURSEND		leave cursor after end of new text
+ *	    PUT_LINE		force linewise put (":put")
+ */
+    void
+do_put(regname, dir, count, flags)
+    int		regname;
+    int		dir;		/* BACKWARD for 'P', FORWARD for 'p' */
+    long	count;
+    int		flags;
+{
+    char_u	*ptr;
+    char_u	*newp, *oldp;
+    int		yanklen;
+    int		totlen = 0;		/* init for gcc */
+    linenr_T	lnum;
+    colnr_T	col;
+    long	i;			/* index in y_array[] */
+    int		y_type;
+    long	y_size;
+#ifdef FEAT_VISUAL
+    int		oldlen;
+    long	y_width = 0;
+    colnr_T	vcol;
+    int		delcount;
+    int		incr = 0;
+    long	j;
+    struct block_def bd;
+#endif
+    char_u	**y_array = NULL;
+    long	nr_lines = 0;
+    pos_T	new_cursor;
+    int		indent;
+    int		orig_indent = 0;	/* init for gcc */
+    int		indent_diff = 0;	/* init for gcc */
+    int		first_indent = TRUE;
+    int		lendiff = 0;
+    pos_T	old_pos;
+    char_u	*insert_string = NULL;
+    int		allocated = FALSE;
+    long	cnt;
+
+#ifdef FEAT_CLIPBOARD
+    /* Adjust register name for "unnamed" in 'clipboard'. */
+    adjust_clip_reg(&regname);
+    (void)may_get_selection(regname);
+#endif
+
+    if (flags & PUT_FIXINDENT)
+	orig_indent = get_indent();
+
+    curbuf->b_op_start = curwin->w_cursor;	/* default for '[ mark */
+    curbuf->b_op_end = curwin->w_cursor;	/* default for '] mark */
+
+    /*
+     * Using inserted text works differently, because the register includes
+     * special characters (newlines, etc.).
+     */
+    if (regname == '.')
+    {
+	(void)stuff_inserted((dir == FORWARD ? (count == -1 ? 'o' : 'a') :
+				    (count == -1 ? 'O' : 'i')), count, FALSE);
+	/* Putting the text is done later, so can't really move the cursor to
+	 * the next character.  Use "l" to simulate it. */
+	if ((flags & PUT_CURSEND) && gchar_cursor() != NUL)
+	    stuffcharReadbuff('l');
+	return;
+    }
+
+    /*
+     * For special registers '%' (file name), '#' (alternate file name) and
+     * ':' (last command line), etc. we have to create a fake yank register.
+     */
+    if (get_spec_reg(regname, &insert_string, &allocated, TRUE))
+    {
+	if (insert_string == NULL)
+	    return;
+    }
+
+    if (insert_string != NULL)
+    {
+	y_type = MCHAR;
+#ifdef FEAT_EVAL
+	if (regname == '=')
+	{
+	    /* For the = register we need to split the string at NL
+	     * characters. */
+	    /* Loop twice: count the number of lines and save them. */
+	    for (;;)
+	    {
+		y_size = 0;
+		ptr = insert_string;
+		while (ptr != NULL)
+		{
+		    if (y_array != NULL)
+			y_array[y_size] = ptr;
+		    ++y_size;
+		    ptr = vim_strchr(ptr, '\n');
+		    if (ptr != NULL)
+		    {
+			if (y_array != NULL)
+			    *ptr = NUL;
+			++ptr;
+			/* A trailing '\n' makes the string linewise */
+			if (*ptr == NUL)
+			{
+			    y_type = MLINE;
+			    break;
+			}
+		    }
+		}
+		if (y_array != NULL)
+		    break;
+		y_array = (char_u **)alloc((unsigned)
+						 (y_size * sizeof(char_u *)));
+		if (y_array == NULL)
+		    goto end;
+	    }
+	}
+	else
+#endif
+	{
+	    y_size = 1;		/* use fake one-line yank register */
+	    y_array = &insert_string;
+	}
+    }
+    else
+    {
+	get_yank_register(regname, FALSE);
+
+	y_type = y_current->y_type;
+#ifdef FEAT_VISUAL
+	y_width = y_current->y_width;
+#endif
+	y_size = y_current->y_size;
+	y_array = y_current->y_array;
+    }
+
+#ifdef FEAT_VISUAL
+    if (y_type == MLINE)
+    {
+	if (flags & PUT_LINE_SPLIT)
+	{
+	    /* "p" or "P" in Visual mode: split the lines to put the text in
+	     * between. */
+	    if (u_save_cursor() == FAIL)
+		goto end;
+	    ptr = vim_strsave(ml_get_cursor());
+	    if (ptr == NULL)
+		goto end;
+	    ml_append(curwin->w_cursor.lnum, ptr, (colnr_T)0, FALSE);
+	    vim_free(ptr);
+
+	    ptr = vim_strnsave(ml_get_curline(), curwin->w_cursor.col);
+	    if (ptr == NULL)
+		goto end;
+	    ml_replace(curwin->w_cursor.lnum, ptr, FALSE);
+	    ++nr_lines;
+	    dir = FORWARD;
+	}
+	if (flags & PUT_LINE_FORWARD)
+	{
+	    /* Must be "p" for a Visual block, put lines below the block. */
+	    curwin->w_cursor = curbuf->b_visual.vi_end;
+	    dir = FORWARD;
+	}
+	curbuf->b_op_start = curwin->w_cursor;	/* default for '[ mark */
+	curbuf->b_op_end = curwin->w_cursor;	/* default for '] mark */
+    }
+#endif
+
+    if (flags & PUT_LINE)	/* :put command or "p" in Visual line mode. */
+	y_type = MLINE;
+
+    if (y_size == 0 || y_array == NULL)
+    {
+	EMSG2(_("E353: Nothing in register %s"),
+		  regname == 0 ? (char_u *)"\"" : transchar(regname));
+	goto end;
+    }
+
+#ifdef FEAT_VISUAL
+    if (y_type == MBLOCK)
+    {
+	lnum = curwin->w_cursor.lnum + y_size + 1;
+	if (lnum > curbuf->b_ml.ml_line_count)
+	    lnum = curbuf->b_ml.ml_line_count + 1;
+	if (u_save(curwin->w_cursor.lnum - 1, lnum) == FAIL)
+	    goto end;
+    }
+    else
+#endif
+	if (y_type == MLINE)
+    {
+	lnum = curwin->w_cursor.lnum;
+#ifdef FEAT_FOLDING
+	/* Correct line number for closed fold.  Don't move the cursor yet,
+	 * u_save() uses it. */
+	if (dir == BACKWARD)
+	    (void)hasFolding(lnum, &lnum, NULL);
+	else
+	    (void)hasFolding(lnum, NULL, &lnum);
+#endif
+	if (dir == FORWARD)
+	    ++lnum;
+	if (u_save(lnum - 1, lnum) == FAIL)
+	    goto end;
+#ifdef FEAT_FOLDING
+	if (dir == FORWARD)
+	    curwin->w_cursor.lnum = lnum - 1;
+	else
+	    curwin->w_cursor.lnum = lnum;
+	curbuf->b_op_start = curwin->w_cursor;	/* for mark_adjust() */
+#endif
+    }
+    else if (u_save_cursor() == FAIL)
+	goto end;
+
+    yanklen = (int)STRLEN(y_array[0]);
+
+#ifdef FEAT_VIRTUALEDIT
+    if (ve_flags == VE_ALL && y_type == MCHAR)
+    {
+	if (gchar_cursor() == TAB)
+	{
+	    /* Don't need to insert spaces when "p" on the last position of a
+	     * tab or "P" on the first position. */
+	    if (dir == FORWARD
+		    ? (int)curwin->w_cursor.coladd < curbuf->b_p_ts - 1
+						: curwin->w_cursor.coladd > 0)
+		coladvance_force(getviscol());
+	    else
+		curwin->w_cursor.coladd = 0;
+	}
+	else if (curwin->w_cursor.coladd > 0 || gchar_cursor() == NUL)
+	    coladvance_force(getviscol() + (dir == FORWARD));
+    }
+#endif
+
+    lnum = curwin->w_cursor.lnum;
+    col = curwin->w_cursor.col;
+
+#ifdef FEAT_VISUAL
+    /*
+     * Block mode
+     */
+    if (y_type == MBLOCK)
+    {
+	char	c = gchar_cursor();
+	colnr_T	endcol2 = 0;
+
+	if (dir == FORWARD && c != NUL)
+	{
+#ifdef FEAT_VIRTUALEDIT
+	    if (ve_flags == VE_ALL)
+		getvcol(curwin, &curwin->w_cursor, &col, NULL, &endcol2);
+	    else
+#endif
+		getvcol(curwin, &curwin->w_cursor, NULL, NULL, &col);
+
+#ifdef FEAT_MBYTE
+	    if (has_mbyte)
+		/* move to start of next multi-byte character */
+		curwin->w_cursor.col += (*mb_ptr2len)(ml_get_cursor());
+	    else
+#endif
+#ifdef FEAT_VIRTUALEDIT
+	    if (c != TAB || ve_flags != VE_ALL)
+#endif
+		++curwin->w_cursor.col;
+	    ++col;
+	}
+	else
+	    getvcol(curwin, &curwin->w_cursor, &col, NULL, &endcol2);
+
+#ifdef FEAT_VIRTUALEDIT
+	col += curwin->w_cursor.coladd;
+	if (ve_flags == VE_ALL && curwin->w_cursor.coladd > 0)
+	{
+	    if (dir == FORWARD && c == NUL)
+		++col;
+	    if (dir != FORWARD && c != NUL)
+		++curwin->w_cursor.col;
+	    if (c == TAB)
+	    {
+		if (dir == BACKWARD && curwin->w_cursor.col)
+		    curwin->w_cursor.col--;
+		if (dir == FORWARD && col - 1 == endcol2)
+		    curwin->w_cursor.col++;
+	    }
+	}
+	curwin->w_cursor.coladd = 0;
+#endif
+	bd.textcol = 0;
+	for (i = 0; i < y_size; ++i)
+	{
+	    int spaces;
+	    char shortline;
+
+	    bd.startspaces = 0;
+	    bd.endspaces = 0;
+	    vcol = 0;
+	    delcount = 0;
+
+	    /* add a new line */
+	    if (curwin->w_cursor.lnum > curbuf->b_ml.ml_line_count)
+	    {
+		if (ml_append(curbuf->b_ml.ml_line_count, (char_u *)"",
+						   (colnr_T)1, FALSE) == FAIL)
+		    break;
+		++nr_lines;
+	    }
+	    /* get the old line and advance to the position to insert at */
+	    oldp = ml_get_curline();
+	    oldlen = (int)STRLEN(oldp);
+	    for (ptr = oldp; vcol < col && *ptr; )
+	    {
+		/* Count a tab for what it's worth (if list mode not on) */
+		incr = lbr_chartabsize_adv(&ptr, (colnr_T)vcol);
+		vcol += incr;
+	    }
+	    bd.textcol = (colnr_T)(ptr - oldp);
+
+	    shortline = (vcol < col) || (vcol == col && !*ptr) ;
+
+	    if (vcol < col) /* line too short, padd with spaces */
+		bd.startspaces = col - vcol;
+	    else if (vcol > col)
+	    {
+		bd.endspaces = vcol - col;
+		bd.startspaces = incr - bd.endspaces;
+		--bd.textcol;
+		delcount = 1;
+#ifdef FEAT_MBYTE
+		if (has_mbyte)
+		    bd.textcol -= (*mb_head_off)(oldp, oldp + bd.textcol);
+#endif
+		if (oldp[bd.textcol] != TAB)
+		{
+		    /* Only a Tab can be split into spaces.  Other
+		     * characters will have to be moved to after the
+		     * block, causing misalignment. */
+		    delcount = 0;
+		    bd.endspaces = 0;
+		}
+	    }
+
+	    yanklen = (int)STRLEN(y_array[i]);
+
+	    /* calculate number of spaces required to fill right side of block*/
+	    spaces = y_width + 1;
+	    for (j = 0; j < yanklen; j++)
+		spaces -= lbr_chartabsize(&y_array[i][j], 0);
+	    if (spaces < 0)
+		spaces = 0;
+
+	    /* insert the new text */
+	    totlen = count * (yanklen + spaces) + bd.startspaces + bd.endspaces;
+	    newp = alloc_check((unsigned)totlen + oldlen + 1);
+	    if (newp == NULL)
+		break;
+	    /* copy part up to cursor to new line */
+	    ptr = newp;
+	    mch_memmove(ptr, oldp, (size_t)bd.textcol);
+	    ptr += bd.textcol;
+	    /* may insert some spaces before the new text */
+	    copy_spaces(ptr, (size_t)bd.startspaces);
+	    ptr += bd.startspaces;
+	    /* insert the new text */
+	    for (j = 0; j < count; ++j)
+	    {
+		mch_memmove(ptr, y_array[i], (size_t)yanklen);
+		ptr += yanklen;
+
+		/* insert block's trailing spaces only if there's text behind */
+		if ((j < count - 1 || !shortline) && spaces)
+		{
+		    copy_spaces(ptr, (size_t)spaces);
+		    ptr += spaces;
+		}
+	    }
+	    /* may insert some spaces after the new text */
+	    copy_spaces(ptr, (size_t)bd.endspaces);
+	    ptr += bd.endspaces;
+	    /* move the text after the cursor to the end of the line. */
+	    mch_memmove(ptr, oldp + bd.textcol + delcount,
+				(size_t)(oldlen - bd.textcol - delcount + 1));
+	    ml_replace(curwin->w_cursor.lnum, newp, FALSE);
+
+	    ++curwin->w_cursor.lnum;
+	    if (i == 0)
+		curwin->w_cursor.col += bd.startspaces;
+	}
+
+	changed_lines(lnum, 0, curwin->w_cursor.lnum, nr_lines);
+
+	/* Set '[ mark. */
+	curbuf->b_op_start = curwin->w_cursor;
+	curbuf->b_op_start.lnum = lnum;
+
+	/* adjust '] mark */
+	curbuf->b_op_end.lnum = curwin->w_cursor.lnum - 1;
+	curbuf->b_op_end.col = bd.textcol + totlen - 1;
+# ifdef FEAT_VIRTUALEDIT
+	curbuf->b_op_end.coladd = 0;
+# endif
+	if (flags & PUT_CURSEND)
+	{
+	    colnr_T len;
+
+	    curwin->w_cursor = curbuf->b_op_end;
+	    curwin->w_cursor.col++;
+
+	    /* in Insert mode we might be after the NUL, correct for that */
+	    len = (colnr_T)STRLEN(ml_get_curline());
+	    if (curwin->w_cursor.col > len)
+		curwin->w_cursor.col = len;
+	}
+	else
+	    curwin->w_cursor.lnum = lnum;
+    }
+    else
+#endif
+    {
+	/*
+	 * Character or Line mode
+	 */
+	if (y_type == MCHAR)
+	{
+	    /* if type is MCHAR, FORWARD is the same as BACKWARD on the next
+	     * char */
+	    if (dir == FORWARD && gchar_cursor() != NUL)
+	    {
+#ifdef FEAT_MBYTE
+		if (has_mbyte)
+		{
+		    int bytelen = (*mb_ptr2len)(ml_get_cursor());
+
+		    /* put it on the next of the multi-byte character. */
+		    col += bytelen;
+		    if (yanklen)
+		    {
+			curwin->w_cursor.col += bytelen;
+			curbuf->b_op_end.col += bytelen;
+		    }
+		}
+		else
+#endif
+		{
+		    ++col;
+		    if (yanklen)
+		    {
+			++curwin->w_cursor.col;
+			++curbuf->b_op_end.col;
+		    }
+		}
+	    }
+	    curbuf->b_op_start = curwin->w_cursor;
+	}
+	/*
+	 * Line mode: BACKWARD is the same as FORWARD on the previous line
+	 */
+	else if (dir == BACKWARD)
+	    --lnum;
+	new_cursor = curwin->w_cursor;
+
+	/*
+	 * simple case: insert into current line
+	 */
+	if (y_type == MCHAR && y_size == 1)
+	{
+	    totlen = count * yanklen;
+	    if (totlen)
+	    {
+		oldp = ml_get(lnum);
+		newp = alloc_check((unsigned)(STRLEN(oldp) + totlen + 1));
+		if (newp == NULL)
+		    goto end;		/* alloc() will give error message */
+		mch_memmove(newp, oldp, (size_t)col);
+		ptr = newp + col;
+		for (i = 0; i < count; ++i)
+		{
+		    mch_memmove(ptr, y_array[0], (size_t)yanklen);
+		    ptr += yanklen;
+		}
+		mch_memmove(ptr, oldp + col, STRLEN(oldp + col) + 1);
+		ml_replace(lnum, newp, FALSE);
+		/* Put cursor on last putted char. */
+		curwin->w_cursor.col += (colnr_T)(totlen - 1);
+	    }
+	    curbuf->b_op_end = curwin->w_cursor;
+	    /* For "CTRL-O p" in Insert mode, put cursor after last char */
+	    if (totlen && (restart_edit != 0 || (flags & PUT_CURSEND)))
+		++curwin->w_cursor.col;
+	    changed_bytes(lnum, col);
+	}
+	else
+	{
+	    /*
+	     * Insert at least one line.  When y_type is MCHAR, break the first
+	     * line in two.
+	     */
+	    for (cnt = 1; cnt <= count; ++cnt)
+	    {
+		i = 0;
+		if (y_type == MCHAR)
+		{
+		    /*
+		     * Split the current line in two at the insert position.
+		     * First insert y_array[size - 1] in front of second line.
+		     * Then append y_array[0] to first line.
+		     */
+		    lnum = new_cursor.lnum;
+		    ptr = ml_get(lnum) + col;
+		    totlen = (int)STRLEN(y_array[y_size - 1]);
+		    newp = alloc_check((unsigned)(STRLEN(ptr) + totlen + 1));
+		    if (newp == NULL)
+			goto error;
+		    STRCPY(newp, y_array[y_size - 1]);
+		    STRCAT(newp, ptr);
+		    /* insert second line */
+		    ml_append(lnum, newp, (colnr_T)0, FALSE);
+		    vim_free(newp);
+
+		    oldp = ml_get(lnum);
+		    newp = alloc_check((unsigned)(col + yanklen + 1));
+		    if (newp == NULL)
+			goto error;
+					    /* copy first part of line */
+		    mch_memmove(newp, oldp, (size_t)col);
+					    /* append to first line */
+		    mch_memmove(newp + col, y_array[0], (size_t)(yanklen + 1));
+		    ml_replace(lnum, newp, FALSE);
+
+		    curwin->w_cursor.lnum = lnum;
+		    i = 1;
+		}
+
+		for (; i < y_size; ++i)
+		{
+		    if ((y_type != MCHAR || i < y_size - 1)
+			    && ml_append(lnum, y_array[i], (colnr_T)0, FALSE)
+								      == FAIL)
+			    goto error;
+		    lnum++;
+		    ++nr_lines;
+		    if (flags & PUT_FIXINDENT)
+		    {
+			old_pos = curwin->w_cursor;
+			curwin->w_cursor.lnum = lnum;
+			ptr = ml_get(lnum);
+			if (cnt == count && i == y_size - 1)
+			    lendiff = (int)STRLEN(ptr);
+#if defined(FEAT_SMARTINDENT) || defined(FEAT_CINDENT)
+			if (*ptr == '#' && preprocs_left())
+			    indent = 0;     /* Leave # lines at start */
+			else
+#endif
+			     if (*ptr == NUL)
+			    indent = 0;     /* Ignore empty lines */
+			else if (first_indent)
+			{
+			    indent_diff = orig_indent - get_indent();
+			    indent = orig_indent;
+			    first_indent = FALSE;
+			}
+			else if ((indent = get_indent() + indent_diff) < 0)
+			    indent = 0;
+			(void)set_indent(indent, 0);
+			curwin->w_cursor = old_pos;
+			/* remember how many chars were removed */
+			if (cnt == count && i == y_size - 1)
+			    lendiff -= (int)STRLEN(ml_get(lnum));
+		    }
+		}
+	    }
+
+error:
+	    /* Adjust marks. */
+	    if (y_type == MLINE)
+	    {
+		curbuf->b_op_start.col = 0;
+		if (dir == FORWARD)
+		    curbuf->b_op_start.lnum++;
+	    }
+	    mark_adjust(curbuf->b_op_start.lnum + (y_type == MCHAR),
+					     (linenr_T)MAXLNUM, nr_lines, 0L);
+
+	    /* note changed text for displaying and folding */
+	    if (y_type == MCHAR)
+		changed_lines(curwin->w_cursor.lnum, col,
+					 curwin->w_cursor.lnum + 1, nr_lines);
+	    else
+		changed_lines(curbuf->b_op_start.lnum, 0,
+					   curbuf->b_op_start.lnum, nr_lines);
+
+	    /* put '] mark at last inserted character */
+	    curbuf->b_op_end.lnum = lnum;
+	    /* correct length for change in indent */
+	    col = (colnr_T)STRLEN(y_array[y_size - 1]) - lendiff;
+	    if (col > 1)
+		curbuf->b_op_end.col = col - 1;
+	    else
+		curbuf->b_op_end.col = 0;
+
+	    if (flags & PUT_CURSLINE)
+	    {
+		/* ":put": put cursor on last inserted line */
+		curwin->w_cursor.lnum = lnum;
+		beginline(BL_WHITE | BL_FIX);
+	    }
+	    else if (flags & PUT_CURSEND)
+	    {
+		/* put cursor after inserted text */
+		if (y_type == MLINE)
+		{
+		    if (lnum >= curbuf->b_ml.ml_line_count)
+			curwin->w_cursor.lnum = curbuf->b_ml.ml_line_count;
+		    else
+			curwin->w_cursor.lnum = lnum + 1;
+		    curwin->w_cursor.col = 0;
+		}
+		else
+		{
+		    curwin->w_cursor.lnum = lnum;
+		    curwin->w_cursor.col = col;
+		}
+	    }
+	    else if (y_type == MLINE)
+	    {
+		/* put cursor on first non-blank in first inserted line */
+		curwin->w_cursor.col = 0;
+		if (dir == FORWARD)
+		    ++curwin->w_cursor.lnum;
+		beginline(BL_WHITE | BL_FIX);
+	    }
+	    else	/* put cursor on first inserted character */
+		curwin->w_cursor = new_cursor;
+	}
+    }
+
+    msgmore(nr_lines);
+    curwin->w_set_curswant = TRUE;
+
+end:
+    if (allocated)
+	vim_free(insert_string);
+    if (regname == '=')
+	vim_free(y_array);
+
+    /* If the cursor is past the end of the line put it at the end. */
+    adjust_cursor_eol();
+}
+
+/*
+ * When the cursor is on the NUL past the end of the line and it should not be
+ * there move it left.
+ */
+    void
+adjust_cursor_eol()
+{
+    if (curwin->w_cursor.col > 0
+	    && gchar_cursor() == NUL
+#ifdef FEAT_VIRTUALEDIT
+	    && (ve_flags & VE_ONEMORE) == 0
+#endif
+	    && !(restart_edit || (State & INSERT)))
+    {
+	/* Put the cursor on the last character in the line. */
+	dec_cursor();
+
+#ifdef FEAT_VIRTUALEDIT
+	if (ve_flags == VE_ALL)
+	{
+	    colnr_T	    scol, ecol;
+
+	    /* Coladd is set to the width of the last character. */
+	    getvcol(curwin, &curwin->w_cursor, &scol, NULL, &ecol);
+	    curwin->w_cursor.coladd = ecol - scol + 1;
+	}
+#endif
+    }
+}
+
+#if defined(FEAT_SMARTINDENT) || defined(FEAT_CINDENT) || defined(PROTO)
+/*
+ * Return TRUE if lines starting with '#' should be left aligned.
+ */
+    int
+preprocs_left()
+{
+    return
+# ifdef FEAT_SMARTINDENT
+#  ifdef FEAT_CINDENT
+	(curbuf->b_p_si && !curbuf->b_p_cin) ||
+#  else
+	curbuf->b_p_si
+#  endif
+# endif
+# ifdef FEAT_CINDENT
+	(curbuf->b_p_cin && in_cinkeys('#', ' ', TRUE))
+# endif
+	;
+}
+#endif
+
+/* Return the character name of the register with the given number */
+    int
+get_register_name(num)
+    int num;
+{
+    if (num == -1)
+	return '"';
+    else if (num < 10)
+	return num + '0';
+    else if (num == DELETION_REGISTER)
+	return '-';
+#ifdef FEAT_CLIPBOARD
+    else if (num == STAR_REGISTER)
+	return '*';
+    else if (num == PLUS_REGISTER)
+	return '+';
+#endif
+    else
+    {
+#ifdef EBCDIC
+	int i;
+
+	/* EBCDIC is really braindead ... */
+	i = 'a' + (num - 10);
+	if (i > 'i')
+	    i += 7;
+	if (i > 'r')
+	    i += 8;
+	return i;
+#else
+	return num + 'a' - 10;
+#endif
+    }
+}
+
+/*
+ * ":dis" and ":registers": Display the contents of the yank registers.
+ */
+    void
+ex_display(eap)
+    exarg_T	*eap;
+{
+    int			i, n;
+    long		j;
+    char_u		*p;
+    struct yankreg	*yb;
+    int			name;
+    int			attr;
+    char_u		*arg = eap->arg;
+#ifdef FEAT_MBYTE
+    int			clen;
+#else
+# define clen 1
+#endif
+
+    if (arg != NULL && *arg == NUL)
+	arg = NULL;
+    attr = hl_attr(HLF_8);
+
+    /* Highlight title */
+    MSG_PUTS_TITLE(_("\n--- Registers ---"));
+    for (i = -1; i < NUM_REGISTERS && !got_int; ++i)
+    {
+	name = get_register_name(i);
+	if (arg != NULL && vim_strchr(arg, name) == NULL)
+	    continue;	    /* did not ask for this register */
+
+#ifdef FEAT_CLIPBOARD
+	/* Adjust register name for "unnamed" in 'clipboard'.
+	 * When it's a clipboard register, fill it with the current contents
+	 * of the clipboard.  */
+	adjust_clip_reg(&name);
+	(void)may_get_selection(name);
+#endif
+
+	if (i == -1)
+	{
+	    if (y_previous != NULL)
+		yb = y_previous;
+	    else
+		yb = &(y_regs[0]);
+	}
+	else
+	    yb = &(y_regs[i]);
+	if (yb->y_array != NULL)
+	{
+	    msg_putchar('\n');
+	    msg_putchar('"');
+	    msg_putchar(name);
+	    MSG_PUTS("   ");
+
+	    n = (int)Columns - 6;
+	    for (j = 0; j < yb->y_size && n > 1; ++j)
+	    {
+		if (j)
+		{
+		    MSG_PUTS_ATTR("^J", attr);
+		    n -= 2;
+		}
+		for (p = yb->y_array[j]; *p && (n -= ptr2cells(p)) >= 0; ++p)
+		{
+#ifdef FEAT_MBYTE
+		    clen = (*mb_ptr2len)(p);
+#endif
+		    msg_outtrans_len(p, clen);
+#ifdef FEAT_MBYTE
+		    p += clen - 1;
+#endif
+		}
+	    }
+	    if (n > 1 && yb->y_type == MLINE)
+		MSG_PUTS_ATTR("^J", attr);
+	    out_flush();		    /* show one line at a time */
+	}
+	ui_breakcheck();
+    }
+
+    /*
+     * display last inserted text
+     */
+    if ((p = get_last_insert()) != NULL
+		 && (arg == NULL || vim_strchr(arg, '.') != NULL) && !got_int)
+    {
+	MSG_PUTS("\n\".   ");
+	dis_msg(p, TRUE);
+    }
+
+    /*
+     * display last command line
+     */
+    if (last_cmdline != NULL && (arg == NULL || vim_strchr(arg, ':') != NULL)
+								  && !got_int)
+    {
+	MSG_PUTS("\n\":   ");
+	dis_msg(last_cmdline, FALSE);
+    }
+
+    /*
+     * display current file name
+     */
+    if (curbuf->b_fname != NULL
+	    && (arg == NULL || vim_strchr(arg, '%') != NULL) && !got_int)
+    {
+	MSG_PUTS("\n\"%   ");
+	dis_msg(curbuf->b_fname, FALSE);
+    }
+
+    /*
+     * display alternate file name
+     */
+    if ((arg == NULL || vim_strchr(arg, '%') != NULL) && !got_int)
+    {
+	char_u	    *fname;
+	linenr_T    dummy;
+
+	if (buflist_name_nr(0, &fname, &dummy) != FAIL)
+	{
+	    MSG_PUTS("\n\"#   ");
+	    dis_msg(fname, FALSE);
+	}
+    }
+
+    /*
+     * display last search pattern
+     */
+    if (last_search_pat() != NULL
+		 && (arg == NULL || vim_strchr(arg, '/') != NULL) && !got_int)
+    {
+	MSG_PUTS("\n\"/   ");
+	dis_msg(last_search_pat(), FALSE);
+    }
+
+#ifdef FEAT_EVAL
+    /*
+     * display last used expression
+     */
+    if (expr_line != NULL && (arg == NULL || vim_strchr(arg, '=') != NULL)
+								  && !got_int)
+    {
+	MSG_PUTS("\n\"=   ");
+	dis_msg(expr_line, FALSE);
+    }
+#endif
+}
+
+/*
+ * display a string for do_dis()
+ * truncate at end of screen line
+ */
+    static void
+dis_msg(p, skip_esc)
+    char_u	*p;
+    int		skip_esc;	    /* if TRUE, ignore trailing ESC */
+{
+    int		n;
+#ifdef FEAT_MBYTE
+    int		l;
+#endif
+
+    n = (int)Columns - 6;
+    while (*p != NUL
+	    && !(*p == ESC && skip_esc && *(p + 1) == NUL)
+	    && (n -= ptr2cells(p)) >= 0)
+    {
+#ifdef FEAT_MBYTE
+	if (has_mbyte && (l = (*mb_ptr2len)(p)) > 1)
+	{
+	    msg_outtrans_len(p, l);
+	    p += l;
+	}
+	else
+#endif
+	    msg_outtrans_len(p++, 1);
+    }
+    ui_breakcheck();
+}
+
+/*
+ * join 'count' lines (minimal 2), including u_save()
+ */
+    void
+do_do_join(count, insert_space)
+    long    count;
+    int	    insert_space;
+{
+    colnr_T	col = MAXCOL;
+
+    if (u_save((linenr_T)(curwin->w_cursor.lnum - 1),
+		    (linenr_T)(curwin->w_cursor.lnum + count)) == FAIL)
+	return;
+
+    while (--count > 0)
+    {
+	line_breakcheck();
+	if (got_int || do_join(insert_space) == FAIL)
+	{
+	    beep_flush();
+	    break;
+	}
+	if (col == MAXCOL && vim_strchr(p_cpo, CPO_JOINCOL) != NULL)
+	    col = curwin->w_cursor.col;
+    }
+
+    /* Vi compatible: use the column of the first join */
+    if (col != MAXCOL && vim_strchr(p_cpo, CPO_JOINCOL) != NULL)
+	curwin->w_cursor.col = col;
+
+#if 0
+    /*
+     * Need to update the screen if the line where the cursor is became too
+     * long to fit on the screen.
+     */
+    update_topline_redraw();
+#endif
+}
+
+/*
+ * Join two lines at the cursor position.
+ * "redraw" is TRUE when the screen should be updated.
+ * Caller must have setup for undo.
+ *
+ * return FAIL for failure, OK otherwise
+ */
+    int
+do_join(insert_space)
+    int		insert_space;
+{
+    char_u	*curr;
+    char_u	*next, *next_start;
+    char_u	*newp;
+    int		endcurr1, endcurr2;
+    int		currsize;	/* size of the current line */
+    int		nextsize;	/* size of the next line */
+    int		spaces;		/* number of spaces to insert */
+    linenr_T	t;
+
+    if (curwin->w_cursor.lnum == curbuf->b_ml.ml_line_count)
+	return FAIL;		/* can't join on last line */
+
+    curr = ml_get_curline();
+    currsize = (int)STRLEN(curr);
+    endcurr1 = endcurr2 = NUL;
+    if (insert_space && currsize > 0)
+    {
+#ifdef FEAT_MBYTE
+	if (has_mbyte)
+	{
+	    next = curr + currsize;
+	    mb_ptr_back(curr, next);
+	    endcurr1 = (*mb_ptr2char)(next);
+	    if (next > curr)
+	    {
+		mb_ptr_back(curr, next);
+		endcurr2 = (*mb_ptr2char)(next);
+	    }
+	}
+	else
+#endif
+	{
+	    endcurr1 = *(curr + currsize - 1);
+	    if (currsize > 1)
+		endcurr2 = *(curr + currsize - 2);
+	}
+    }
+
+    next = next_start = ml_get((linenr_T)(curwin->w_cursor.lnum + 1));
+    spaces = 0;
+    if (insert_space)
+    {
+	next = skipwhite(next);
+	if (*next != ')' && currsize != 0 && endcurr1 != TAB
+#ifdef FEAT_MBYTE
+		&& (!has_format_option(FO_MBYTE_JOIN)
+			|| (mb_ptr2char(next) < 0x100 && endcurr1 < 0x100))
+		&& (!has_format_option(FO_MBYTE_JOIN2)
+			|| mb_ptr2char(next) < 0x100 || endcurr1 < 0x100)
+#endif
+		)
+	{
+	    /* don't add a space if the line is ending in a space */
+	    if (endcurr1 == ' ')
+		endcurr1 = endcurr2;
+	    else
+		++spaces;
+	    /* extra space when 'joinspaces' set and line ends in '.' */
+	    if (       p_js
+		    && (endcurr1 == '.'
+			|| (vim_strchr(p_cpo, CPO_JOINSP) == NULL
+			    && (endcurr1 == '?' || endcurr1 == '!'))))
+		++spaces;
+	}
+    }
+    nextsize = (int)STRLEN(next);
+
+    newp = alloc_check((unsigned)(currsize + nextsize + spaces + 1));
+    if (newp == NULL)
+	return FAIL;
+
+    /*
+     * Insert the next line first, because we already have that pointer.
+     * Curr has to be obtained again, because getting next will have
+     * invalidated it.
+     */
+    mch_memmove(newp + currsize + spaces, next, (size_t)(nextsize + 1));
+
+    curr = ml_get_curline();
+    mch_memmove(newp, curr, (size_t)currsize);
+
+    copy_spaces(newp + currsize, (size_t)spaces);
+
+    ml_replace(curwin->w_cursor.lnum, newp, FALSE);
+
+    /* Only report the change in the first line here, del_lines() will report
+     * the deleted line. */
+    changed_lines(curwin->w_cursor.lnum, currsize,
+					       curwin->w_cursor.lnum + 1, 0L);
+
+    /*
+     * Delete the following line. To do this we move the cursor there
+     * briefly, and then move it back. After del_lines() the cursor may
+     * have moved up (last line deleted), so the current lnum is kept in t.
+     *
+     * Move marks from the deleted line to the joined line, adjusting the
+     * column.  This is not Vi compatible, but Vi deletes the marks, thus that
+     * should not really be a problem.
+     */
+    t = curwin->w_cursor.lnum;
+    mark_col_adjust(t + 1, (colnr_T)0, (linenr_T)-1,
+			     (long)(currsize + spaces - (next - next_start)));
+    ++curwin->w_cursor.lnum;
+    del_lines(1L, FALSE);
+    curwin->w_cursor.lnum = t;
+
+    /*
+     * go to first character of the joined line
+     */
+    curwin->w_cursor.col = currsize;
+    check_cursor_col();
+#ifdef FEAT_VIRTUALEDIT
+    curwin->w_cursor.coladd = 0;
+#endif
+    curwin->w_set_curswant = TRUE;
+
+    return OK;
+}
+
+#ifdef FEAT_COMMENTS
+/*
+ * Return TRUE if the two comment leaders given are the same.  "lnum" is
+ * the first line.  White-space is ignored.  Note that the whole of
+ * 'leader1' must match 'leader2_len' characters from 'leader2' -- webb
+ */
+    static int
+same_leader(lnum, leader1_len, leader1_flags, leader2_len, leader2_flags)
+    linenr_T lnum;
+    int	    leader1_len;
+    char_u  *leader1_flags;
+    int	    leader2_len;
+    char_u  *leader2_flags;
+{
+    int	    idx1 = 0, idx2 = 0;
+    char_u  *p;
+    char_u  *line1;
+    char_u  *line2;
+
+    if (leader1_len == 0)
+	return (leader2_len == 0);
+
+    /*
+     * If first leader has 'f' flag, the lines can be joined only if the
+     * second line does not have a leader.
+     * If first leader has 'e' flag, the lines can never be joined.
+     * If fist leader has 's' flag, the lines can only be joined if there is
+     * some text after it and the second line has the 'm' flag.
+     */
+    if (leader1_flags != NULL)
+    {
+	for (p = leader1_flags; *p && *p != ':'; ++p)
+	{
+	    if (*p == COM_FIRST)
+		return (leader2_len == 0);
+	    if (*p == COM_END)
+		return FALSE;
+	    if (*p == COM_START)
+	    {
+		if (*(ml_get(lnum) + leader1_len) == NUL)
+		    return FALSE;
+		if (leader2_flags == NULL || leader2_len == 0)
+		    return FALSE;
+		for (p = leader2_flags; *p && *p != ':'; ++p)
+		    if (*p == COM_MIDDLE)
+			return TRUE;
+		return FALSE;
+	    }
+	}
+    }
+
+    /*
+     * Get current line and next line, compare the leaders.
+     * The first line has to be saved, only one line can be locked at a time.
+     */
+    line1 = vim_strsave(ml_get(lnum));
+    if (line1 != NULL)
+    {
+	for (idx1 = 0; vim_iswhite(line1[idx1]); ++idx1)
+	    ;
+	line2 = ml_get(lnum + 1);
+	for (idx2 = 0; idx2 < leader2_len; ++idx2)
+	{
+	    if (!vim_iswhite(line2[idx2]))
+	    {
+		if (line1[idx1++] != line2[idx2])
+		    break;
+	    }
+	    else
+		while (vim_iswhite(line1[idx1]))
+		    ++idx1;
+	}
+	vim_free(line1);
+    }
+    return (idx2 == leader2_len && idx1 == leader1_len);
+}
+#endif
+
+/*
+ * implementation of the format operator 'gq'
+ */
+    void
+op_format(oap, keep_cursor)
+    oparg_T	*oap;
+    int		keep_cursor;		/* keep cursor on same text char */
+{
+    long	old_line_count = curbuf->b_ml.ml_line_count;
+
+    /* Place the cursor where the "gq" or "gw" command was given, so that "u"
+     * can put it back there. */
+    curwin->w_cursor = oap->cursor_start;
+
+    if (u_save((linenr_T)(oap->start.lnum - 1),
+				       (linenr_T)(oap->end.lnum + 1)) == FAIL)
+	return;
+    curwin->w_cursor = oap->start;
+
+#ifdef FEAT_VISUAL
+    if (oap->is_VIsual)
+	/* When there is no change: need to remove the Visual selection */
+	redraw_curbuf_later(INVERTED);
+#endif
+
+    /* Set '[ mark at the start of the formatted area */
+    curbuf->b_op_start = oap->start;
+
+    /* For "gw" remember the cursor position and put it back below (adjusted
+     * for joined and split lines). */
+    if (keep_cursor)
+	saved_cursor = oap->cursor_start;
+
+    format_lines(oap->line_count);
+
+    /*
+     * Leave the cursor at the first non-blank of the last formatted line.
+     * If the cursor was moved one line back (e.g. with "Q}") go to the next
+     * line, so "." will do the next lines.
+     */
+    if (oap->end_adjusted && curwin->w_cursor.lnum < curbuf->b_ml.ml_line_count)
+	++curwin->w_cursor.lnum;
+    beginline(BL_WHITE | BL_FIX);
+    old_line_count = curbuf->b_ml.ml_line_count - old_line_count;
+    msgmore(old_line_count);
+
+    /* put '] mark on the end of the formatted area */
+    curbuf->b_op_end = curwin->w_cursor;
+
+    if (keep_cursor)
+    {
+	curwin->w_cursor = saved_cursor;
+	saved_cursor.lnum = 0;
+    }
+
+#ifdef FEAT_VISUAL
+    if (oap->is_VIsual)
+    {
+	win_T	*wp;
+
+	FOR_ALL_WINDOWS(wp)
+	{
+	    if (wp->w_old_cursor_lnum != 0)
+	    {
+		/* When lines have been inserted or deleted, adjust the end of
+		 * the Visual area to be redrawn. */
+		if (wp->w_old_cursor_lnum > wp->w_old_visual_lnum)
+		    wp->w_old_cursor_lnum += old_line_count;
+		else
+		    wp->w_old_visual_lnum += old_line_count;
+	    }
+	}
+    }
+#endif
+}
+
+#if defined(FEAT_EVAL) || defined(PROTO)
+/*
+ * Implementation of the format operator 'gq' for when using 'formatexpr'.
+ */
+    void
+op_formatexpr(oap)
+    oparg_T	*oap;
+{
+# ifdef FEAT_VISUAL
+    if (oap->is_VIsual)
+	/* When there is no change: need to remove the Visual selection */
+	redraw_curbuf_later(INVERTED);
+# endif
+
+    (void)fex_format(oap->start.lnum, oap->line_count, NUL);
+}
+
+    int
+fex_format(lnum, count, c)
+    linenr_T	lnum;
+    long	count;
+    int		c;	/* character to be inserted */
+{
+    int		use_sandbox = was_set_insecurely((char_u *)"formatexpr",
+								   OPT_LOCAL);
+    int		r;
+#ifdef FEAT_MBYTE
+    char_u	buf[MB_MAXBYTES];
+#else
+    char_u	buf[2];
+#endif
+
+    /*
+     * Set v:lnum to the first line number and v:count to the number of lines.
+     * Set v:char to the character to be inserted (can be NUL).
+     */
+    set_vim_var_nr(VV_LNUM, lnum);
+    set_vim_var_nr(VV_COUNT, count);
+
+#ifdef FEAT_MBYTE
+    if (has_mbyte)
+	buf[(*mb_char2bytes)(c, buf)] = NUL;
+    else
+#endif
+    {
+	buf[0] = c;
+	buf[1] = NUL;
+    }
+    set_vim_var_string(VV_CHAR, buf, -1);
+
+    /*
+     * Evaluate the function.
+     */
+    if (use_sandbox)
+	++sandbox;
+    r = eval_to_number(curbuf->b_p_fex);
+    if (use_sandbox)
+	--sandbox;
+
+    set_vim_var_string(VV_CHAR, NULL, -1);
+
+    return r;
+}
+#endif
+
+/*
+ * Format "line_count" lines, starting at the cursor position.
+ * When "line_count" is negative, format until the end of the paragraph.
+ * Lines after the cursor line are saved for undo, caller must have saved the
+ * first line.
+ */
+    void
+format_lines(line_count)
+    linenr_T	line_count;
+{
+    int		max_len;
+    int		is_not_par;		/* current line not part of parag. */
+    int		next_is_not_par;	/* next line not part of paragraph */
+    int		is_end_par;		/* at end of paragraph */
+    int		prev_is_end_par = FALSE;/* prev. line not part of parag. */
+    int		next_is_start_par = FALSE;
+#ifdef FEAT_COMMENTS
+    int		leader_len = 0;		/* leader len of current line */
+    int		next_leader_len;	/* leader len of next line */
+    char_u	*leader_flags = NULL;	/* flags for leader of current line */
+    char_u	*next_leader_flags;	/* flags for leader of next line */
+    int		do_comments;		/* format comments */
+#endif
+    int		advance = TRUE;
+    int		second_indent = -1;
+    int		do_second_indent;
+    int		do_number_indent;
+    int		do_trail_white;
+    int		first_par_line = TRUE;
+    int		smd_save;
+    long	count;
+    int		need_set_indent = TRUE;	/* set indent of next paragraph */
+    int		force_format = FALSE;
+    int		old_State = State;
+
+    /* length of a line to force formatting: 3 * 'tw' */
+    max_len = comp_textwidth(TRUE) * 3;
+
+    /* check for 'q', '2' and '1' in 'formatoptions' */
+#ifdef FEAT_COMMENTS
+    do_comments = has_format_option(FO_Q_COMS);
+#endif
+    do_second_indent = has_format_option(FO_Q_SECOND);
+    do_number_indent = has_format_option(FO_Q_NUMBER);
+    do_trail_white = has_format_option(FO_WHITE_PAR);
+
+    /*
+     * Get info about the previous and current line.
+     */
+    if (curwin->w_cursor.lnum > 1)
+	is_not_par = fmt_check_par(curwin->w_cursor.lnum - 1
+#ifdef FEAT_COMMENTS
+				, &leader_len, &leader_flags, do_comments
+#endif
+				);
+    else
+	is_not_par = TRUE;
+    next_is_not_par = fmt_check_par(curwin->w_cursor.lnum
+#ifdef FEAT_COMMENTS
+			   , &next_leader_len, &next_leader_flags, do_comments
+#endif
+				);
+    is_end_par = (is_not_par || next_is_not_par);
+    if (!is_end_par && do_trail_white)
+	is_end_par = !ends_in_white(curwin->w_cursor.lnum - 1);
+
+    curwin->w_cursor.lnum--;
+    for (count = line_count; count != 0 && !got_int; --count)
+    {
+	/*
+	 * Advance to next paragraph.
+	 */
+	if (advance)
+	{
+	    curwin->w_cursor.lnum++;
+	    prev_is_end_par = is_end_par;
+	    is_not_par = next_is_not_par;
+#ifdef FEAT_COMMENTS
+	    leader_len = next_leader_len;
+	    leader_flags = next_leader_flags;
+#endif
+	}
+
+	/*
+	 * The last line to be formatted.
+	 */
+	if (count == 1 || curwin->w_cursor.lnum == curbuf->b_ml.ml_line_count)
+	{
+	    next_is_not_par = TRUE;
+#ifdef FEAT_COMMENTS
+	    next_leader_len = 0;
+	    next_leader_flags = NULL;
+#endif
+	}
+	else
+	{
+	    next_is_not_par = fmt_check_par(curwin->w_cursor.lnum + 1
+#ifdef FEAT_COMMENTS
+			   , &next_leader_len, &next_leader_flags, do_comments
+#endif
+					);
+	    if (do_number_indent)
+		next_is_start_par =
+			   (get_number_indent(curwin->w_cursor.lnum + 1) > 0);
+	}
+	advance = TRUE;
+	is_end_par = (is_not_par || next_is_not_par || next_is_start_par);
+	if (!is_end_par && do_trail_white)
+	    is_end_par = !ends_in_white(curwin->w_cursor.lnum);
+
+	/*
+	 * Skip lines that are not in a paragraph.
+	 */
+	if (is_not_par)
+	{
+	    if (line_count < 0)
+		break;
+	}
+	else
+	{
+	    /*
+	     * For the first line of a paragraph, check indent of second line.
+	     * Don't do this for comments and empty lines.
+	     */
+	    if (first_par_line
+		    && (do_second_indent || do_number_indent)
+		    && prev_is_end_par
+		    && curwin->w_cursor.lnum < curbuf->b_ml.ml_line_count
+#ifdef FEAT_COMMENTS
+		    && leader_len == 0
+		    && next_leader_len == 0
+#endif
+		    )
+	    {
+		if (do_second_indent
+			&& !lineempty(curwin->w_cursor.lnum + 1))
+		    second_indent = get_indent_lnum(curwin->w_cursor.lnum + 1);
+		else if (do_number_indent)
+		    second_indent = get_number_indent(curwin->w_cursor.lnum);
+	    }
+
+	    /*
+	     * When the comment leader changes, it's the end of the paragraph.
+	     */
+	    if (curwin->w_cursor.lnum >= curbuf->b_ml.ml_line_count
+#ifdef FEAT_COMMENTS
+		    || !same_leader(curwin->w_cursor.lnum,
+					leader_len, leader_flags,
+					  next_leader_len, next_leader_flags)
+#endif
+		    )
+		is_end_par = TRUE;
+
+	    /*
+	     * If we have got to the end of a paragraph, or the line is
+	     * getting long, format it.
+	     */
+	    if (is_end_par || force_format)
+	    {
+		if (need_set_indent)
+		    /* replace indent in first line with minimal number of
+		     * tabs and spaces, according to current options */
+		    (void)set_indent(get_indent(), SIN_CHANGED);
+
+		/* put cursor on last non-space */
+		State = NORMAL;	/* don't go past end-of-line */
+		coladvance((colnr_T)MAXCOL);
+		while (curwin->w_cursor.col && vim_isspace(gchar_cursor()))
+		    dec_cursor();
+
+		/* do the formatting, without 'showmode' */
+		State = INSERT;	/* for open_line() */
+		smd_save = p_smd;
+		p_smd = FALSE;
+		insertchar(NUL, INSCHAR_FORMAT
+#ifdef FEAT_COMMENTS
+			+ (do_comments ? INSCHAR_DO_COM : 0)
+#endif
+			, second_indent);
+		State = old_State;
+		p_smd = smd_save;
+		second_indent = -1;
+		/* at end of par.: need to set indent of next par. */
+		need_set_indent = is_end_par;
+		if (is_end_par)
+		{
+		    /* When called with a negative line count, break at the
+		     * end of the paragraph. */
+		    if (line_count < 0)
+			break;
+		    first_par_line = TRUE;
+		}
+		force_format = FALSE;
+	    }
+
+	    /*
+	     * When still in same paragraph, join the lines together.  But
+	     * first delete the comment leader from the second line.
+	     */
+	    if (!is_end_par)
+	    {
+		advance = FALSE;
+		curwin->w_cursor.lnum++;
+		curwin->w_cursor.col = 0;
+		if (line_count < 0 && u_save_cursor() == FAIL)
+			break;
+#ifdef FEAT_COMMENTS
+		(void)del_bytes((long)next_leader_len, FALSE, FALSE);
+		if (next_leader_len > 0)
+		    mark_col_adjust(curwin->w_cursor.lnum, (colnr_T)0, 0L,
+						      (long)-next_leader_len);
+#endif
+		curwin->w_cursor.lnum--;
+		if (do_join(TRUE) == FAIL)
+		{
+		    beep_flush();
+		    break;
+		}
+		first_par_line = FALSE;
+		/* If the line is getting long, format it next time */
+		if (STRLEN(ml_get_curline()) > (size_t)max_len)
+		    force_format = TRUE;
+		else
+		    force_format = FALSE;
+	    }
+	}
+	line_breakcheck();
+    }
+}
+
+/*
+ * Return TRUE if line "lnum" ends in a white character.
+ */
+    static int
+ends_in_white(lnum)
+    linenr_T	lnum;
+{
+    char_u	*s = ml_get(lnum);
+    size_t	l;
+
+    if (*s == NUL)
+	return FALSE;
+    /* Don't use STRLEN() inside vim_iswhite(), SAS/C complains: "macro
+     * invocation may call function multiple times". */
+    l = STRLEN(s) - 1;
+    return vim_iswhite(s[l]);
+}
+
+/*
+ * Blank lines, and lines containing only the comment leader, are left
+ * untouched by the formatting.  The function returns TRUE in this
+ * case.  It also returns TRUE when a line starts with the end of a comment
+ * ('e' in comment flags), so that this line is skipped, and not joined to the
+ * previous line.  A new paragraph starts after a blank line, or when the
+ * comment leader changes -- webb.
+ */
+#ifdef FEAT_COMMENTS
+    static int
+fmt_check_par(lnum, leader_len, leader_flags, do_comments)
+    linenr_T	lnum;
+    int		*leader_len;
+    char_u	**leader_flags;
+    int		do_comments;
+{
+    char_u	*flags = NULL;	    /* init for GCC */
+    char_u	*ptr;
+
+    ptr = ml_get(lnum);
+    if (do_comments)
+	*leader_len = get_leader_len(ptr, leader_flags, FALSE);
+    else
+	*leader_len = 0;
+
+    if (*leader_len > 0)
+    {
+	/*
+	 * Search for 'e' flag in comment leader flags.
+	 */
+	flags = *leader_flags;
+	while (*flags && *flags != ':' && *flags != COM_END)
+	    ++flags;
+    }
+
+    return (*skipwhite(ptr + *leader_len) == NUL
+	    || (*leader_len > 0 && *flags == COM_END)
+	    || startPS(lnum, NUL, FALSE));
+}
+#else
+    static int
+fmt_check_par(lnum)
+    linenr_T	lnum;
+{
+    return (*skipwhite(ml_get(lnum)) == NUL || startPS(lnum, NUL, FALSE));
+}
+#endif
+
+/*
+ * Return TRUE when a paragraph starts in line "lnum".  Return FALSE when the
+ * previous line is in the same paragraph.  Used for auto-formatting.
+ */
+    int
+paragraph_start(lnum)
+    linenr_T	lnum;
+{
+    char_u	*p;
+#ifdef FEAT_COMMENTS
+    int		leader_len = 0;		/* leader len of current line */
+    char_u	*leader_flags = NULL;	/* flags for leader of current line */
+    int		next_leader_len;	/* leader len of next line */
+    char_u	*next_leader_flags;	/* flags for leader of next line */
+    int		do_comments;		/* format comments */
+#endif
+
+    if (lnum <= 1)
+	return TRUE;		/* start of the file */
+
+    p = ml_get(lnum - 1);
+    if (*p == NUL)
+	return TRUE;		/* after empty line */
+
+#ifdef FEAT_COMMENTS
+    do_comments = has_format_option(FO_Q_COMS);
+#endif
+    if (fmt_check_par(lnum - 1
+#ifdef FEAT_COMMENTS
+				, &leader_len, &leader_flags, do_comments
+#endif
+		))
+	return TRUE;		/* after non-paragraph line */
+
+    if (fmt_check_par(lnum
+#ifdef FEAT_COMMENTS
+			   , &next_leader_len, &next_leader_flags, do_comments
+#endif
+		))
+	return TRUE;		/* "lnum" is not a paragraph line */
+
+    if (has_format_option(FO_WHITE_PAR) && !ends_in_white(lnum - 1))
+	return TRUE;		/* missing trailing space in previous line. */
+
+    if (has_format_option(FO_Q_NUMBER) && (get_number_indent(lnum) > 0))
+	return TRUE;		/* numbered item starts in "lnum". */
+
+#ifdef FEAT_COMMENTS
+    if (!same_leader(lnum - 1, leader_len, leader_flags,
+					  next_leader_len, next_leader_flags))
+	return TRUE;		/* change of comment leader. */
+#endif
+
+    return FALSE;
+}
+
+#ifdef FEAT_VISUAL
+/*
+ * prepare a few things for block mode yank/delete/tilde
+ *
+ * for delete:
+ * - textlen includes the first/last char to be (partly) deleted
+ * - start/endspaces is the number of columns that are taken by the
+ *   first/last deleted char minus the number of columns that have to be
+ *   deleted.  for yank and tilde:
+ * - textlen includes the first/last char to be wholly yanked
+ * - start/endspaces is the number of columns of the first/last yanked char
+ *   that are to be yanked.
+ */
+    static void
+block_prep(oap, bdp, lnum, is_del)
+    oparg_T		*oap;
+    struct block_def	*bdp;
+    linenr_T		lnum;
+    int			is_del;
+{
+    int		incr = 0;
+    char_u	*pend;
+    char_u	*pstart;
+    char_u	*line;
+    char_u	*prev_pstart;
+    char_u	*prev_pend;
+
+    bdp->startspaces = 0;
+    bdp->endspaces = 0;
+    bdp->textlen = 0;
+    bdp->start_vcol = 0;
+    bdp->end_vcol = 0;
+#ifdef FEAT_VISUALEXTRA
+    bdp->is_short = FALSE;
+    bdp->is_oneChar = FALSE;
+    bdp->pre_whitesp = 0;
+    bdp->pre_whitesp_c = 0;
+    bdp->end_char_vcols = 0;
+#endif
+    bdp->start_char_vcols = 0;
+
+    line = ml_get(lnum);
+    pstart = line;
+    prev_pstart = line;
+    while (bdp->start_vcol < oap->start_vcol && *pstart)
+    {
+	/* Count a tab for what it's worth (if list mode not on) */
+	incr = lbr_chartabsize(pstart, (colnr_T)bdp->start_vcol);
+	bdp->start_vcol += incr;
+#ifdef FEAT_VISUALEXTRA
+	if (vim_iswhite(*pstart))
+	{
+	    bdp->pre_whitesp += incr;
+	    bdp->pre_whitesp_c++;
+	}
+	else
+	{
+	    bdp->pre_whitesp = 0;
+	    bdp->pre_whitesp_c = 0;
+	}
+#endif
+	prev_pstart = pstart;
+	mb_ptr_adv(pstart);
+    }
+    bdp->start_char_vcols = incr;
+    if (bdp->start_vcol < oap->start_vcol)	/* line too short */
+    {
+	bdp->end_vcol = bdp->start_vcol;
+#ifdef FEAT_VISUALEXTRA
+	bdp->is_short = TRUE;
+#endif
+	if (!is_del || oap->op_type == OP_APPEND)
+	    bdp->endspaces = oap->end_vcol - oap->start_vcol + 1;
+    }
+    else
+    {
+	/* notice: this converts partly selected Multibyte characters to
+	 * spaces, too. */
+	bdp->startspaces = bdp->start_vcol - oap->start_vcol;
+	if (is_del && bdp->startspaces)
+	    bdp->startspaces = bdp->start_char_vcols - bdp->startspaces;
+	pend = pstart;
+	bdp->end_vcol = bdp->start_vcol;
+	if (bdp->end_vcol > oap->end_vcol)	/* it's all in one character */
+	{
+#ifdef FEAT_VISUALEXTRA
+	    bdp->is_oneChar = TRUE;
+#endif
+	    if (oap->op_type == OP_INSERT)
+		bdp->endspaces = bdp->start_char_vcols - bdp->startspaces;
+	    else if (oap->op_type == OP_APPEND)
+	    {
+		bdp->startspaces += oap->end_vcol - oap->start_vcol + 1;
+		bdp->endspaces = bdp->start_char_vcols - bdp->startspaces;
+	    }
+	    else
+	    {
+		bdp->startspaces = oap->end_vcol - oap->start_vcol + 1;
+		if (is_del && oap->op_type != OP_LSHIFT)
+		{
+		    /* just putting the sum of those two into
+		     * bdp->startspaces doesn't work for Visual replace,
+		     * so we have to split the tab in two */
+		    bdp->startspaces = bdp->start_char_vcols
+					- (bdp->start_vcol - oap->start_vcol);
+		    bdp->endspaces = bdp->end_vcol - oap->end_vcol - 1;
+		}
+	    }
+	}
+	else
+	{
+	    prev_pend = pend;
+	    while (bdp->end_vcol <= oap->end_vcol && *pend != NUL)
+	    {
+		/* Count a tab for what it's worth (if list mode not on) */
+		prev_pend = pend;
+		incr = lbr_chartabsize_adv(&pend, (colnr_T)bdp->end_vcol);
+		bdp->end_vcol += incr;
+	    }
+	    if (bdp->end_vcol <= oap->end_vcol
+		    && (!is_del
+			|| oap->op_type == OP_APPEND
+			|| oap->op_type == OP_REPLACE)) /* line too short */
+	    {
+#ifdef FEAT_VISUALEXTRA
+		bdp->is_short = TRUE;
+#endif
+		/* Alternative: include spaces to fill up the block.
+		 * Disadvantage: can lead to trailing spaces when the line is
+		 * short where the text is put */
+		/* if (!is_del || oap->op_type == OP_APPEND) */
+		if (oap->op_type == OP_APPEND || virtual_op)
+		    bdp->endspaces = oap->end_vcol - bdp->end_vcol
+							     + oap->inclusive;
+		else
+		    bdp->endspaces = 0; /* replace doesn't add characters */
+	    }
+	    else if (bdp->end_vcol > oap->end_vcol)
+	    {
+		bdp->endspaces = bdp->end_vcol - oap->end_vcol - 1;
+		if (!is_del && bdp->endspaces)
+		{
+		    bdp->endspaces = incr - bdp->endspaces;
+		    if (pend != pstart)
+			pend = prev_pend;
+		}
+	    }
+	}
+#ifdef FEAT_VISUALEXTRA
+	bdp->end_char_vcols = incr;
+#endif
+	if (is_del && bdp->startspaces)
+	    pstart = prev_pstart;
+	bdp->textlen = (int)(pend - pstart);
+    }
+    bdp->textcol = (colnr_T) (pstart - line);
+    bdp->textstart = pstart;
+}
+#endif /* FEAT_VISUAL */
+
+#ifdef FEAT_RIGHTLEFT
+static void reverse_line __ARGS((char_u *s));
+
+    static void
+reverse_line(s)
+    char_u *s;
+{
+    int	    i, j;
+    char_u  c;
+
+    if ((i = (int)STRLEN(s) - 1) <= 0)
+	return;
+
+    curwin->w_cursor.col = i - curwin->w_cursor.col;
+    for (j = 0; j < i; j++, i--)
+    {
+	c = s[i]; s[i] = s[j]; s[j] = c;
+    }
+}
+
+# define RLADDSUBFIX(ptr) if (curwin->w_p_rl) reverse_line(ptr);
+#else
+# define RLADDSUBFIX(ptr)
+#endif
+
+/*
+ * add or subtract 'Prenum1' from a number in a line
+ * 'command' is CTRL-A for add, CTRL-X for subtract
+ *
+ * return FAIL for failure, OK otherwise
+ */
+    int
+do_addsub(command, Prenum1)
+    int		command;
+    linenr_T	Prenum1;
+{
+    int		col;
+    char_u	*buf1;
+    char_u	buf2[NUMBUFLEN];
+    int		hex;		/* 'X' or 'x': hex; '0': octal */
+    static int	hexupper = FALSE;	/* 0xABC */
+    unsigned long n;
+    long_u	oldn;
+    char_u	*ptr;
+    int		c;
+    int		length = 0;		/* character length of the number */
+    int		todel;
+    int		dohex;
+    int		dooct;
+    int		doalp;
+    int		firstdigit;
+    int		negative;
+    int		subtract;
+
+    dohex = (vim_strchr(curbuf->b_p_nf, 'x') != NULL);	/* "heX" */
+    dooct = (vim_strchr(curbuf->b_p_nf, 'o') != NULL);	/* "Octal" */
+    doalp = (vim_strchr(curbuf->b_p_nf, 'p') != NULL);	/* "alPha" */
+
+    ptr = ml_get_curline();
+    RLADDSUBFIX(ptr);
+
+    /*
+     * First check if we are on a hexadecimal number, after the "0x".
+     */
+    col = curwin->w_cursor.col;
+    if (dohex)
+	while (col > 0 && vim_isxdigit(ptr[col]))
+	    --col;
+    if (       dohex
+	    && col > 0
+	    && (ptr[col] == 'X'
+		|| ptr[col] == 'x')
+	    && ptr[col - 1] == '0'
+	    && vim_isxdigit(ptr[col + 1]))
+    {
+	/*
+	 * Found hexadecimal number, move to its start.
+	 */
+	--col;
+    }
+    else
+    {
+	/*
+	 * Search forward and then backward to find the start of number.
+	 */
+	col = curwin->w_cursor.col;
+
+	while (ptr[col] != NUL
+		&& !vim_isdigit(ptr[col])
+		&& !(doalp && ASCII_ISALPHA(ptr[col])))
+	    ++col;
+
+	while (col > 0
+		&& vim_isdigit(ptr[col - 1])
+		&& !(doalp && ASCII_ISALPHA(ptr[col])))
+	    --col;
+    }
+
+    /*
+     * If a number was found, and saving for undo works, replace the number.
+     */
+    firstdigit = ptr[col];
+    RLADDSUBFIX(ptr);
+    if ((!VIM_ISDIGIT(firstdigit) && !(doalp && ASCII_ISALPHA(firstdigit)))
+	    || u_save_cursor() != OK)
+    {
+	beep_flush();
+	return FAIL;
+    }
+
+    /* get ptr again, because u_save() may have changed it */
+    ptr = ml_get_curline();
+    RLADDSUBFIX(ptr);
+
+    if (doalp && ASCII_ISALPHA(firstdigit))
+    {
+	/* decrement or increment alphabetic character */
+	if (command == Ctrl_X)
+	{
+	    if (CharOrd(firstdigit) < Prenum1)
+	    {
+		if (isupper(firstdigit))
+		    firstdigit = 'A';
+		else
+		    firstdigit = 'a';
+	    }
+	    else
+#ifdef EBCDIC
+		firstdigit = EBCDIC_CHAR_ADD(firstdigit, -Prenum1);
+#else
+		firstdigit -= Prenum1;
+#endif
+	}
+	else
+	{
+	    if (26 - CharOrd(firstdigit) - 1 < Prenum1)
+	    {
+		if (isupper(firstdigit))
+		    firstdigit = 'Z';
+		else
+		    firstdigit = 'z';
+	    }
+	    else
+#ifdef EBCDIC
+		firstdigit = EBCDIC_CHAR_ADD(firstdigit, Prenum1);
+#else
+		firstdigit += Prenum1;
+#endif
+	}
+	curwin->w_cursor.col = col;
+	(void)del_char(FALSE);
+	ins_char(firstdigit);
+    }
+    else
+    {
+	negative = FALSE;
+	if (col > 0 && ptr[col - 1] == '-')	    /* negative number */
+	{
+	    --col;
+	    negative = TRUE;
+	}
+
+	/* get the number value (unsigned) */
+	vim_str2nr(ptr + col, &hex, &length, dooct, dohex, NULL, &n);
+
+	/* ignore leading '-' for hex and octal numbers */
+	if (hex && negative)
+	{
+	    ++col;
+	    --length;
+	    negative = FALSE;
+	}
+
+	/* add or subtract */
+	subtract = FALSE;
+	if (command == Ctrl_X)
+	    subtract ^= TRUE;
+	if (negative)
+	    subtract ^= TRUE;
+
+	oldn = n;
+	if (subtract)
+	    n -= (unsigned long)Prenum1;
+	else
+	    n += (unsigned long)Prenum1;
+
+	/* handle wraparound for decimal numbers */
+	if (!hex)
+	{
+	    if (subtract)
+	    {
+		if (n > oldn)
+		{
+		    n = 1 + (n ^ (unsigned long)-1);
+		    negative ^= TRUE;
+		}
+	    }
+	    else /* add */
+	    {
+		if (n < oldn)
+		{
+		    n = (n ^ (unsigned long)-1);
+		    negative ^= TRUE;
+		}
+	    }
+	    if (n == 0)
+		negative = FALSE;
+	}
+
+	/*
+	 * Delete the old number.
+	 */
+	curwin->w_cursor.col = col;
+	todel = length;
+	c = gchar_cursor();
+	/*
+	 * Don't include the '-' in the length, only the length of the part
+	 * after it is kept the same.
+	 */
+	if (c == '-')
+	    --length;
+	while (todel-- > 0)
+	{
+	    if (c < 0x100 && isalpha(c))
+	    {
+		if (isupper(c))
+		    hexupper = TRUE;
+		else
+		    hexupper = FALSE;
+	    }
+	    /* del_char() will mark line needing displaying */
+	    (void)del_char(FALSE);
+	    c = gchar_cursor();
+	}
+
+	/*
+	 * Prepare the leading characters in buf1[].
+	 * When there are many leading zeros it could be very long.  Allocate
+	 * a bit too much.
+	 */
+	buf1 = alloc((unsigned)length + NUMBUFLEN);
+	if (buf1 == NULL)
+	    return FAIL;
+	ptr = buf1;
+	if (negative)
+	{
+	    *ptr++ = '-';
+	}
+	if (hex)
+	{
+	    *ptr++ = '0';
+	    --length;
+	}
+	if (hex == 'x' || hex == 'X')
+	{
+	    *ptr++ = hex;
+	    --length;
+	}
+
+	/*
+	 * Put the number characters in buf2[].
+	 */
+	if (hex == 0)
+	    sprintf((char *)buf2, "%lu", n);
+	else if (hex == '0')
+	    sprintf((char *)buf2, "%lo", n);
+	else if (hex && hexupper)
+	    sprintf((char *)buf2, "%lX", n);
+	else
+	    sprintf((char *)buf2, "%lx", n);
+	length -= (int)STRLEN(buf2);
+
+	/*
+	 * Adjust number of zeros to the new number of digits, so the
+	 * total length of the number remains the same.
+	 * Don't do this when
+	 * the result may look like an octal number.
+	 */
+	if (firstdigit == '0' && !(dooct && hex == 0))
+	    while (length-- > 0)
+		*ptr++ = '0';
+	*ptr = NUL;
+	STRCAT(buf1, buf2);
+	ins_str(buf1);		/* insert the new number */
+	vim_free(buf1);
+    }
+    --curwin->w_cursor.col;
+    curwin->w_set_curswant = TRUE;
+#ifdef FEAT_RIGHTLEFT
+    ptr = ml_get_buf(curbuf, curwin->w_cursor.lnum, TRUE);
+    RLADDSUBFIX(ptr);
+#endif
+    return OK;
+}
+
+#ifdef FEAT_VIMINFO
+    int
+read_viminfo_register(virp, force)
+    vir_T	*virp;
+    int		force;
+{
+    int		eof;
+    int		do_it = TRUE;
+    int		size;
+    int		limit;
+    int		i;
+    int		set_prev = FALSE;
+    char_u	*str;
+    char_u	**array = NULL;
+
+    /* We only get here (hopefully) if line[0] == '"' */
+    str = virp->vir_line + 1;
+    if (*str == '"')
+    {
+	set_prev = TRUE;
+	str++;
+    }
+    if (!ASCII_ISALNUM(*str) && *str != '-')
+    {
+	if (viminfo_error("E577: ", _("Illegal register name"), virp->vir_line))
+	    return TRUE;	/* too many errors, pretend end-of-file */
+	do_it = FALSE;
+    }
+    get_yank_register(*str++, FALSE);
+    if (!force && y_current->y_array != NULL)
+	do_it = FALSE;
+    size = 0;
+    limit = 100;	/* Optimized for registers containing <= 100 lines */
+    if (do_it)
+    {
+	if (set_prev)
+	    y_previous = y_current;
+	vim_free(y_current->y_array);
+	array = y_current->y_array =
+		       (char_u **)alloc((unsigned)(limit * sizeof(char_u *)));
+	str = skipwhite(str);
+	if (STRNCMP(str, "CHAR", 4) == 0)
+	    y_current->y_type = MCHAR;
+#ifdef FEAT_VISUAL
+	else if (STRNCMP(str, "BLOCK", 5) == 0)
+	    y_current->y_type = MBLOCK;
+#endif
+	else
+	    y_current->y_type = MLINE;
+	/* get the block width; if it's missing we get a zero, which is OK */
+	str = skipwhite(skiptowhite(str));
+#ifdef FEAT_VISUAL
+	y_current->y_width = getdigits(&str);
+#else
+	(void)getdigits(&str);
+#endif
+    }
+
+    while (!(eof = viminfo_readline(virp))
+		    && (virp->vir_line[0] == TAB || virp->vir_line[0] == '<'))
+    {
+	if (do_it)
+	{
+	    if (size >= limit)
+	    {
+		y_current->y_array = (char_u **)
+			      alloc((unsigned)(limit * 2 * sizeof(char_u *)));
+		for (i = 0; i < limit; i++)
+		    y_current->y_array[i] = array[i];
+		vim_free(array);
+		limit *= 2;
+		array = y_current->y_array;
+	    }
+	    str = viminfo_readstring(virp, 1, TRUE);
+	    if (str != NULL)
+		array[size++] = str;
+	    else
+		do_it = FALSE;
+	}
+    }
+    if (do_it)
+    {
+	if (size == 0)
+	{
+	    vim_free(array);
+	    y_current->y_array = NULL;
+	}
+	else if (size < limit)
+	{
+	    y_current->y_array =
+			(char_u **)alloc((unsigned)(size * sizeof(char_u *)));
+	    for (i = 0; i < size; i++)
+		y_current->y_array[i] = array[i];
+	    vim_free(array);
+	}
+	y_current->y_size = size;
+    }
+    return eof;
+}
+
+    void
+write_viminfo_registers(fp)
+    FILE    *fp;
+{
+    int	    i, j;
+    char_u  *type;
+    char_u  c;
+    int	    num_lines;
+    int	    max_num_lines;
+    int	    max_kbyte;
+    long    len;
+
+    fprintf(fp, _("\n# Registers:\n"));
+
+    /* Get '<' value, use old '"' value if '<' is not found. */
+    max_num_lines = get_viminfo_parameter('<');
+    if (max_num_lines < 0)
+	max_num_lines = get_viminfo_parameter('"');
+    if (max_num_lines == 0)
+	return;
+    max_kbyte = get_viminfo_parameter('s');
+    if (max_kbyte == 0)
+	return;
+    for (i = 0; i < NUM_REGISTERS; i++)
+    {
+	if (y_regs[i].y_array == NULL)
+	    continue;
+#ifdef FEAT_CLIPBOARD
+	/* Skip '*'/'+' register, we don't want them back next time */
+	if (i == STAR_REGISTER || i == PLUS_REGISTER)
+	    continue;
+#endif
+#ifdef FEAT_DND
+	/* Neither do we want the '~' register */
+	if (i == TILDE_REGISTER)
+	    continue;
+#endif
+	/* Skip empty registers. */
+	num_lines = y_regs[i].y_size;
+	if (num_lines == 0
+		|| (num_lines == 1 && y_regs[i].y_type == MCHAR
+					&& STRLEN(y_regs[i].y_array[0]) == 0))
+	    continue;
+
+	if (max_kbyte > 0)
+	{
+	    /* Skip register if there is more text than the maximum size. */
+	    len = 0;
+	    for (j = 0; j < num_lines; j++)
+		len += (long)STRLEN(y_regs[i].y_array[j]) + 1L;
+	    if (len > (long)max_kbyte * 1024L)
+		continue;
+	}
+
+	switch (y_regs[i].y_type)
+	{
+	    case MLINE:
+		type = (char_u *)"LINE";
+		break;
+	    case MCHAR:
+		type = (char_u *)"CHAR";
+		break;
+#ifdef FEAT_VISUAL
+	    case MBLOCK:
+		type = (char_u *)"BLOCK";
+		break;
+#endif
+	    default:
+		sprintf((char *)IObuff, _("E574: Unknown register type %d"),
+							    y_regs[i].y_type);
+		emsg(IObuff);
+		type = (char_u *)"LINE";
+		break;
+	}
+	if (y_previous == &y_regs[i])
+	    fprintf(fp, "\"");
+	c = get_register_name(i);
+	fprintf(fp, "\"%c\t%s\t%d\n", c, type,
+#ifdef FEAT_VISUAL
+		    (int)y_regs[i].y_width
+#else
+		    0
+#endif
+		    );
+
+	/* If max_num_lines < 0, then we save ALL the lines in the register */
+	if (max_num_lines > 0 && num_lines > max_num_lines)
+	    num_lines = max_num_lines;
+	for (j = 0; j < num_lines; j++)
+	{
+	    putc('\t', fp);
+	    viminfo_writestring(fp, y_regs[i].y_array[j]);
+	}
+    }
+}
+#endif /* FEAT_VIMINFO */
+
+#if defined(FEAT_CLIPBOARD) || defined(PROTO)
+/*
+ * SELECTION / PRIMARY ('*')
+ *
+ * Text selection stuff that uses the GUI selection register '*'.  When using a
+ * GUI this may be text from another window, otherwise it is the last text we
+ * had highlighted with VIsual mode.  With mouse support, clicking the middle
+ * button performs the paste, otherwise you will need to do <"*p>. "
+ * If not under X, it is synonymous with the clipboard register '+'.
+ *
+ * X CLIPBOARD ('+')
+ *
+ * Text selection stuff that uses the GUI clipboard register '+'.
+ * Under X, this matches the standard cut/paste buffer CLIPBOARD selection.
+ * It will be used for unnamed cut/pasting is 'clipboard' contains "unnamed",
+ * otherwise you will need to do <"+p>. "
+ * If not under X, it is synonymous with the selection register '*'.
+ */
+
+/*
+ * Routine to export any final X selection we had to the environment
+ * so that the text is still available after vim has exited. X selections
+ * only exist while the owning application exists, so we write to the
+ * permanent (while X runs) store CUT_BUFFER0.
+ * Dump the CLIPBOARD selection if we own it (it's logically the more
+ * 'permanent' of the two), otherwise the PRIMARY one.
+ * For now, use a hard-coded sanity limit of 1Mb of data.
+ */
+#if defined(FEAT_X11) && defined(FEAT_CLIPBOARD)
+    void
+x11_export_final_selection()
+{
+    Display	*dpy;
+    char_u	*str = NULL;
+    long_u	len = 0;
+    int		motion_type = -1;
+
+# ifdef FEAT_GUI
+    if (gui.in_use)
+	dpy = X_DISPLAY;
+    else
+# endif
+# ifdef FEAT_XCLIPBOARD
+	dpy = xterm_dpy;
+# else
+	return;
+# endif
+
+    /* Get selection to export */
+    if (clip_plus.owned)
+	motion_type = clip_convert_selection(&str, &len, &clip_plus);
+    else if (clip_star.owned)
+	motion_type = clip_convert_selection(&str, &len, &clip_star);
+
+    /* Check it's OK */
+    if (dpy != NULL && str != NULL && motion_type >= 0
+					       && len < 1024*1024 && len > 0)
+    {
+	XStoreBuffer(dpy, (char *)str, (int)len, 0);
+	XFlush(dpy);
+    }
+
+    vim_free(str);
+}
+#endif
+
+    void
+clip_free_selection(cbd)
+    VimClipboard	*cbd;
+{
+    struct yankreg *y_ptr = y_current;
+
+    if (cbd == &clip_plus)
+	y_current = &y_regs[PLUS_REGISTER];
+    else
+	y_current = &y_regs[STAR_REGISTER];
+    free_yank_all();
+    y_current->y_size = 0;
+    y_current = y_ptr;
+}
+
+/*
+ * Get the selected text and put it in the gui selection register '*' or '+'.
+ */
+    void
+clip_get_selection(cbd)
+    VimClipboard	*cbd;
+{
+    struct yankreg *old_y_previous, *old_y_current;
+    pos_T	old_cursor;
+#ifdef FEAT_VISUAL
+    pos_T	old_visual;
+    int		old_visual_mode;
+#endif
+    colnr_T	old_curswant;
+    int		old_set_curswant;
+    pos_T	old_op_start, old_op_end;
+    oparg_T	oa;
+    cmdarg_T	ca;
+
+    if (cbd->owned)
+    {
+	if ((cbd == &clip_plus && y_regs[PLUS_REGISTER].y_array != NULL)
+		|| (cbd == &clip_star && y_regs[STAR_REGISTER].y_array != NULL))
+	    return;
+
+	/* Get the text between clip_star.start & clip_star.end */
+	old_y_previous = y_previous;
+	old_y_current = y_current;
+	old_cursor = curwin->w_cursor;
+	old_curswant = curwin->w_curswant;
+	old_set_curswant = curwin->w_set_curswant;
+	old_op_start = curbuf->b_op_start;
+	old_op_end = curbuf->b_op_end;
+#ifdef FEAT_VISUAL
+	old_visual = VIsual;
+	old_visual_mode = VIsual_mode;
+#endif
+	clear_oparg(&oa);
+	oa.regname = (cbd == &clip_plus ? '+' : '*');
+	oa.op_type = OP_YANK;
+	vim_memset(&ca, 0, sizeof(ca));
+	ca.oap = &oa;
+	ca.cmdchar = 'y';
+	ca.count1 = 1;
+	ca.retval = CA_NO_ADJ_OP_END;
+	do_pending_operator(&ca, 0, TRUE);
+	y_previous = old_y_previous;
+	y_current = old_y_current;
+	curwin->w_cursor = old_cursor;
+	changed_cline_bef_curs();   /* need to update w_virtcol et al */
+	curwin->w_curswant = old_curswant;
+	curwin->w_set_curswant = old_set_curswant;
+	curbuf->b_op_start = old_op_start;
+	curbuf->b_op_end = old_op_end;
+#ifdef FEAT_VISUAL
+	VIsual = old_visual;
+	VIsual_mode = old_visual_mode;
+#endif
+    }
+    else
+    {
+	clip_free_selection(cbd);
+
+	/* Try to get selected text from another window */
+	clip_gen_request_selection(cbd);
+    }
+}
+
+/* Convert from the GUI selection string into the '*'/'+' register */
+    void
+clip_yank_selection(type, str, len, cbd)
+    int		type;
+    char_u	*str;
+    long	len;
+    VimClipboard *cbd;
+{
+    struct yankreg *y_ptr;
+
+    if (cbd == &clip_plus)
+	y_ptr = &y_regs[PLUS_REGISTER];
+    else
+	y_ptr = &y_regs[STAR_REGISTER];
+
+    clip_free_selection(cbd);
+
+    str_to_reg(y_ptr, type, str, len, 0L);
+}
+
+/*
+ * Convert the '*'/'+' register into a GUI selection string returned in *str
+ * with length *len.
+ * Returns the motion type, or -1 for failure.
+ */
+    int
+clip_convert_selection(str, len, cbd)
+    char_u	**str;
+    long_u	*len;
+    VimClipboard *cbd;
+{
+    char_u	*p;
+    int		lnum;
+    int		i, j;
+    int_u	eolsize;
+    struct yankreg *y_ptr;
+
+    if (cbd == &clip_plus)
+	y_ptr = &y_regs[PLUS_REGISTER];
+    else
+	y_ptr = &y_regs[STAR_REGISTER];
+
+#ifdef USE_CRNL
+    eolsize = 2;
+#else
+    eolsize = 1;
+#endif
+
+    *str = NULL;
+    *len = 0;
+    if (y_ptr->y_array == NULL)
+	return -1;
+
+    for (i = 0; i < y_ptr->y_size; i++)
+	*len += (long_u)STRLEN(y_ptr->y_array[i]) + eolsize;
+
+    /*
+     * Don't want newline character at end of last line if we're in MCHAR mode.
+     */
+    if (y_ptr->y_type == MCHAR && *len >= eolsize)
+	*len -= eolsize;
+
+    p = *str = lalloc(*len + 1, TRUE);	/* add one to avoid zero */
+    if (p == NULL)
+	return -1;
+    lnum = 0;
+    for (i = 0, j = 0; i < (int)*len; i++, j++)
+    {
+	if (y_ptr->y_array[lnum][j] == '\n')
+	    p[i] = NUL;
+	else if (y_ptr->y_array[lnum][j] == NUL)
+	{
+#ifdef USE_CRNL
+	    p[i++] = '\r';
+#endif
+#ifdef USE_CR
+	    p[i] = '\r';
+#else
+	    p[i] = '\n';
+#endif
+	    lnum++;
+	    j = -1;
+	}
+	else
+	    p[i] = y_ptr->y_array[lnum][j];
+    }
+    return y_ptr->y_type;
+}
+
+
+# if defined(FEAT_VISUAL) || defined(FEAT_EVAL)
+/*
+ * If we have written to a clipboard register, send the text to the clipboard.
+ */
+    static void
+may_set_selection()
+{
+    if (y_current == &(y_regs[STAR_REGISTER]) && clip_star.available)
+    {
+	clip_own_selection(&clip_star);
+	clip_gen_set_selection(&clip_star);
+    }
+    else if (y_current == &(y_regs[PLUS_REGISTER]) && clip_plus.available)
+    {
+	clip_own_selection(&clip_plus);
+	clip_gen_set_selection(&clip_plus);
+    }
+}
+# endif
+
+#endif /* FEAT_CLIPBOARD || PROTO */
+
+
+#if defined(FEAT_DND) || defined(PROTO)
+/*
+ * Replace the contents of the '~' register with str.
+ */
+    void
+dnd_yank_drag_data(str, len)
+    char_u	*str;
+    long	len;
+{
+    struct yankreg *curr;
+
+    curr = y_current;
+    y_current = &y_regs[TILDE_REGISTER];
+    free_yank_all();
+    str_to_reg(y_current, MCHAR, str, len, 0L);
+    y_current = curr;
+}
+#endif
+
+
+#if defined(FEAT_EVAL) || defined(PROTO)
+/*
+ * Return the type of a register.
+ * Used for getregtype()
+ * Returns MAUTO for error.
+ */
+    char_u
+get_reg_type(regname, reglen)
+    int	    regname;
+    long    *reglen;
+{
+    switch (regname)
+    {
+	case '%':		/* file name */
+	case '#':		/* alternate file name */
+	case '=':		/* expression */
+	case ':':		/* last command line */
+	case '/':		/* last search-pattern */
+	case '.':		/* last inserted text */
+#ifdef FEAT_SEARCHPATH
+	case Ctrl_F:		/* Filename under cursor */
+	case Ctrl_P:		/* Path under cursor, expand via "path" */
+#endif
+	case Ctrl_W:		/* word under cursor */
+	case Ctrl_A:		/* WORD (mnemonic All) under cursor */
+	case '_':		/* black hole: always empty */
+	    return MCHAR;
+    }
+
+#ifdef FEAT_CLIPBOARD
+    regname = may_get_selection(regname);
+#endif
+
+    /* Should we check for a valid name? */
+    get_yank_register(regname, FALSE);
+
+    if (y_current->y_array != NULL)
+    {
+#ifdef FEAT_VISUAL
+	if (reglen != NULL && y_current->y_type == MBLOCK)
+	    *reglen = y_current->y_width;
+#endif
+	return y_current->y_type;
+    }
+    return MAUTO;
+}
+
+/*
+ * Return the contents of a register as a single allocated string.
+ * Used for "@r" in expressions and for getreg().
+ * Returns NULL for error.
+ */
+    char_u *
+get_reg_contents(regname, allowexpr, expr_src)
+    int		regname;
+    int		allowexpr;	/* allow "=" register */
+    int		expr_src;	/* get expression for "=" register */
+{
+    long	i;
+    char_u	*retval;
+    int		allocated;
+    long	len;
+
+    /* Don't allow using an expression register inside an expression */
+    if (regname == '=')
+    {
+	if (allowexpr)
+	{
+	    if (expr_src)
+		return get_expr_line_src();
+	    return get_expr_line();
+	}
+	return NULL;
+    }
+
+    if (regname == '@')	    /* "@@" is used for unnamed register */
+	regname = '"';
+
+    /* check for valid regname */
+    if (regname != NUL && !valid_yank_reg(regname, FALSE))
+	return NULL;
+
+#ifdef FEAT_CLIPBOARD
+    regname = may_get_selection(regname);
+#endif
+
+    if (get_spec_reg(regname, &retval, &allocated, FALSE))
+    {
+	if (retval == NULL)
+	    return NULL;
+	if (!allocated)
+	    retval = vim_strsave(retval);
+	return retval;
+    }
+
+    get_yank_register(regname, FALSE);
+    if (y_current->y_array == NULL)
+	return NULL;
+
+    /*
+     * Compute length of resulting string.
+     */
+    len = 0;
+    for (i = 0; i < y_current->y_size; ++i)
+    {
+	len += (long)STRLEN(y_current->y_array[i]);
+	/*
+	 * Insert a newline between lines and after last line if
+	 * y_type is MLINE.
+	 */
+	if (y_current->y_type == MLINE || i < y_current->y_size - 1)
+	    ++len;
+    }
+
+    retval = lalloc(len + 1, TRUE);
+
+    /*
+     * Copy the lines of the yank register into the string.
+     */
+    if (retval != NULL)
+    {
+	len = 0;
+	for (i = 0; i < y_current->y_size; ++i)
+	{
+	    STRCPY(retval + len, y_current->y_array[i]);
+	    len += (long)STRLEN(retval + len);
+
+	    /*
+	     * Insert a NL between lines and after the last line if y_type is
+	     * MLINE.
+	     */
+	    if (y_current->y_type == MLINE || i < y_current->y_size - 1)
+		retval[len++] = '\n';
+	}
+	retval[len] = NUL;
+    }
+
+    return retval;
+}
+
+/*
+ * Store string "str" in register "name".
+ * "maxlen" is the maximum number of bytes to use, -1 for all bytes.
+ * If "must_append" is TRUE, always append to the register.  Otherwise append
+ * if "name" is an uppercase letter.
+ * Note: "maxlen" and "must_append" don't work for the "/" register.
+ * Careful: 'str' is modified, you may have to use a copy!
+ * If "str" ends in '\n' or '\r', use linewise, otherwise use characterwise.
+ */
+    void
+write_reg_contents(name, str, maxlen, must_append)
+    int		name;
+    char_u	*str;
+    int		maxlen;
+    int		must_append;
+{
+    write_reg_contents_ex(name, str, maxlen, must_append, MAUTO, 0L);
+}
+
+    void
+write_reg_contents_ex(name, str, maxlen, must_append, yank_type, block_len)
+    int		name;
+    char_u	*str;
+    int		maxlen;
+    int		must_append;
+    int		yank_type;
+    long	block_len;
+{
+    struct yankreg  *old_y_previous, *old_y_current;
+    long	    len;
+
+    if (maxlen >= 0)
+	len = maxlen;
+    else
+	len = (long)STRLEN(str);
+
+    /* Special case: '/' search pattern */
+    if (name == '/')
+    {
+	set_last_search_pat(str, RE_SEARCH, TRUE, TRUE);
+	return;
+    }
+
+#ifdef FEAT_EVAL
+    if (name == '=')
+    {
+	char_u	    *p, *s;
+
+	p = vim_strnsave(str, (int)len);
+	if (p == NULL)
+	    return;
+	if (must_append)
+	{
+	    s = concat_str(get_expr_line_src(), p);
+	    vim_free(p);
+	    p = s;
+
+	}
+	set_expr_line(p);
+	return;
+    }
+#endif
+
+    if (!valid_yank_reg(name, TRUE))	    /* check for valid reg name */
+    {
+	emsg_invreg(name);
+	return;
+    }
+
+    if (name == '_')	    /* black hole: nothing to do */
+	return;
+
+    /* Don't want to change the current (unnamed) register */
+    old_y_previous = y_previous;
+    old_y_current = y_current;
+
+    get_yank_register(name, TRUE);
+    if (!y_append && !must_append)
+	free_yank_all();
+#ifndef FEAT_VISUAL
+    /* Just in case - make sure we don't use MBLOCK */
+    if (yank_type == MBLOCK)
+	yank_type = MAUTO;
+#endif
+    if (yank_type == MAUTO)
+	yank_type = ((len > 0 && (str[len - 1] == '\n' || str[len - 1] == '\r'))
+							     ? MLINE : MCHAR);
+    str_to_reg(y_current, yank_type, str, len, block_len);
+
+# ifdef FEAT_CLIPBOARD
+    /* Send text of clipboard register to the clipboard. */
+    may_set_selection();
+# endif
+
+    /* ':let @" = "val"' should change the meaning of the "" register */
+    if (name != '"')
+	y_previous = old_y_previous;
+    y_current = old_y_current;
+}
+#endif	/* FEAT_EVAL */
+
+#if defined(FEAT_CLIPBOARD) || defined(FEAT_EVAL)
+/*
+ * Put a string into a register.  When the register is not empty, the string
+ * is appended.
+ */
+    static void
+str_to_reg(y_ptr, type, str, len, blocklen)
+    struct yankreg	*y_ptr;		/* pointer to yank register */
+    int			type;		/* MCHAR, MLINE or MBLOCK */
+    char_u		*str;		/* string to put in register */
+    long		len;		/* length of string */
+    long		blocklen;	/* width of Visual block */
+{
+    int		lnum;
+    long	start;
+    long	i;
+    int		extra;
+    int		newlines;		/* number of lines added */
+    int		extraline = 0;		/* extra line at the end */
+    int		append = FALSE;		/* append to last line in register */
+    char_u	*s;
+    char_u	**pp;
+#ifdef FEAT_VISUAL
+    long	maxlen;
+#endif
+
+    if (y_ptr->y_array == NULL)		/* NULL means emtpy register */
+	y_ptr->y_size = 0;
+
+    /*
+     * Count the number of lines within the string
+     */
+    newlines = 0;
+    for (i = 0; i < len; i++)
+	if (str[i] == '\n')
+	    ++newlines;
+    if (type == MCHAR || len == 0 || str[len - 1] != '\n')
+    {
+	extraline = 1;
+	++newlines;	/* count extra newline at the end */
+    }
+    if (y_ptr->y_size > 0 && y_ptr->y_type == MCHAR)
+    {
+	append = TRUE;
+	--newlines;	/* uncount newline when appending first line */
+    }
+
+    /*
+     * Allocate an array to hold the pointers to the new register lines.
+     * If the register was not empty, move the existing lines to the new array.
+     */
+    pp = (char_u **)lalloc_clear((y_ptr->y_size + newlines)
+						    * sizeof(char_u *), TRUE);
+    if (pp == NULL)	/* out of memory */
+	return;
+    for (lnum = 0; lnum < y_ptr->y_size; ++lnum)
+	pp[lnum] = y_ptr->y_array[lnum];
+    vim_free(y_ptr->y_array);
+    y_ptr->y_array = pp;
+#ifdef FEAT_VISUAL
+    maxlen = 0;
+#endif
+
+    /*
+     * Find the end of each line and save it into the array.
+     */
+    for (start = 0; start < len + extraline; start += i + 1)
+    {
+	for (i = start; i < len; ++i)	/* find the end of the line */
+	    if (str[i] == '\n')
+		break;
+	i -= start;			/* i is now length of line */
+#ifdef FEAT_VISUAL
+	if (i > maxlen)
+	    maxlen = i;
+#endif
+	if (append)
+	{
+	    --lnum;
+	    extra = (int)STRLEN(y_ptr->y_array[lnum]);
+	}
+	else
+	    extra = 0;
+	s = alloc((unsigned)(i + extra + 1));
+	if (s == NULL)
+	    break;
+	if (extra)
+	    mch_memmove(s, y_ptr->y_array[lnum], (size_t)extra);
+	if (append)
+	    vim_free(y_ptr->y_array[lnum]);
+	if (i)
+	    mch_memmove(s + extra, str + start, (size_t)i);
+	extra += i;
+	s[extra] = NUL;
+	y_ptr->y_array[lnum++] = s;
+	while (--extra >= 0)
+	{
+	    if (*s == NUL)
+		*s = '\n';	    /* replace NUL with newline */
+	    ++s;
+	}
+	append = FALSE;		    /* only first line is appended */
+    }
+    y_ptr->y_type = type;
+    y_ptr->y_size = lnum;
+# ifdef FEAT_VISUAL
+    if (type == MBLOCK)
+	y_ptr->y_width = (blocklen < 0 ? maxlen - 1 : blocklen);
+    else
+	y_ptr->y_width = 0;
+# endif
+}
+#endif /* FEAT_CLIPBOARD || FEAT_EVAL || PROTO */
+
+    void
+clear_oparg(oap)
+    oparg_T	*oap;
+{
+    vim_memset(oap, 0, sizeof(oparg_T));
+}
+
+static long	line_count_info __ARGS((char_u *line, long *wc, long *cc, long limit, int eol_size));
+
+/*
+ *  Count the number of bytes, characters and "words" in a line.
+ *
+ *  "Words" are counted by looking for boundaries between non-space and
+ *  space characters.  (it seems to produce results that match 'wc'.)
+ *
+ *  Return value is byte count; word count for the line is added to "*wc".
+ *  Char count is added to "*cc".
+ *
+ *  The function will only examine the first "limit" characters in the
+ *  line, stopping if it encounters an end-of-line (NUL byte).  In that
+ *  case, eol_size will be added to the character count to account for
+ *  the size of the EOL character.
+ */
+    static long
+line_count_info(line, wc, cc, limit, eol_size)
+    char_u	*line;
+    long	*wc;
+    long	*cc;
+    long	limit;
+    int		eol_size;
+{
+    long	i;
+    long	words = 0;
+    long	chars = 0;
+    int		is_word = 0;
+
+    for (i = 0; line[i] && i < limit; )
+    {
+	if (is_word)
+	{
+	    if (vim_isspace(line[i]))
+	    {
+		words++;
+		is_word = 0;
+	    }
+	}
+	else if (!vim_isspace(line[i]))
+	    is_word = 1;
+	++chars;
+#ifdef FEAT_MBYTE
+	i += (*mb_ptr2len)(line + i);
+#else
+	++i;
+#endif
+    }
+
+    if (is_word)
+	words++;
+    *wc += words;
+
+    /* Add eol_size if the end of line was reached before hitting limit. */
+    if (line[i] == NUL && i < limit)
+    {
+	i += eol_size;
+	chars += eol_size;
+    }
+    *cc += chars;
+    return i;
+}
+
+/*
+ * Give some info about the position of the cursor (for "g CTRL-G").
+ * In Visual mode, give some info about the selected region.  (In this case,
+ * the *_count_cursor variables store running totals for the selection.)
+ */
+    void
+cursor_pos_info()
+{
+    char_u	*p;
+    char_u	buf1[50];
+    char_u	buf2[40];
+    linenr_T	lnum;
+    long	byte_count = 0;
+    long	byte_count_cursor = 0;
+    long	char_count = 0;
+    long	char_count_cursor = 0;
+    long	word_count = 0;
+    long	word_count_cursor = 0;
+    int		eol_size;
+    long	last_check = 100000L;
+#ifdef FEAT_VISUAL
+    long	line_count_selected = 0;
+    pos_T	min_pos, max_pos;
+    oparg_T	oparg;
+    struct block_def	bd;
+#endif
+
+    /*
+     * Compute the length of the file in characters.
+     */
+    if (curbuf->b_ml.ml_flags & ML_EMPTY)
+    {
+	MSG(_(no_lines_msg));
+    }
+    else
+    {
+	if (get_fileformat(curbuf) == EOL_DOS)
+	    eol_size = 2;
+	else
+	    eol_size = 1;
+
+#ifdef FEAT_VISUAL
+	if (VIsual_active)
+	{
+	    if (lt(VIsual, curwin->w_cursor))
+	    {
+		min_pos = VIsual;
+		max_pos = curwin->w_cursor;
+	    }
+	    else
+	    {
+		min_pos = curwin->w_cursor;
+		max_pos = VIsual;
+	    }
+	    if (*p_sel == 'e' && max_pos.col > 0)
+		--max_pos.col;
+
+	    if (VIsual_mode == Ctrl_V)
+	    {
+		oparg.is_VIsual = 1;
+		oparg.block_mode = TRUE;
+		oparg.op_type = OP_NOP;
+		getvcols(curwin, &min_pos, &max_pos,
+					  &oparg.start_vcol, &oparg.end_vcol);
+		if (curwin->w_curswant == MAXCOL)
+		    oparg.end_vcol = MAXCOL;
+		/* Swap the start, end vcol if needed */
+		if (oparg.end_vcol < oparg.start_vcol)
+		{
+		    oparg.end_vcol += oparg.start_vcol;
+		    oparg.start_vcol = oparg.end_vcol - oparg.start_vcol;
+		    oparg.end_vcol -= oparg.start_vcol;
+		}
+	    }
+	    line_count_selected = max_pos.lnum - min_pos.lnum + 1;
+	}
+#endif
+
+	for (lnum = 1; lnum <= curbuf->b_ml.ml_line_count; ++lnum)
+	{
+	    /* Check for a CTRL-C every 100000 characters. */
+	    if (byte_count > last_check)
+	    {
+		ui_breakcheck();
+		if (got_int)
+		    return;
+		last_check = byte_count + 100000L;
+	    }
+
+#ifdef FEAT_VISUAL
+	    /* Do extra processing for VIsual mode. */
+	    if (VIsual_active
+		    && lnum >= min_pos.lnum && lnum <= max_pos.lnum)
+	    {
+		char_u	    *s = NULL;
+		long	    len = 0L;
+
+		switch (VIsual_mode)
+		{
+		    case Ctrl_V:
+# ifdef FEAT_VIRTUALEDIT
+			virtual_op = virtual_active();
+# endif
+			block_prep(&oparg, &bd, lnum, 0);
+# ifdef FEAT_VIRTUALEDIT
+			virtual_op = MAYBE;
+# endif
+			s = bd.textstart;
+			len = (long)bd.textlen;
+			break;
+		    case 'V':
+			s = ml_get(lnum);
+			len = MAXCOL;
+			break;
+		    case 'v':
+			{
+			    colnr_T start_col = (lnum == min_pos.lnum)
+							   ? min_pos.col : 0;
+			    colnr_T end_col = (lnum == max_pos.lnum)
+				      ? max_pos.col - start_col + 1 : MAXCOL;
+
+			    s = ml_get(lnum) + start_col;
+			    len = end_col;
+			}
+			break;
+		}
+		if (s != NULL)
+		{
+		    byte_count_cursor += line_count_info(s, &word_count_cursor,
+					   &char_count_cursor, len, eol_size);
+		    if (lnum == curbuf->b_ml.ml_line_count
+			    && !curbuf->b_p_eol
+			    && curbuf->b_p_bin
+			    && (long)STRLEN(s) < len)
+			byte_count_cursor -= eol_size;
+		}
+	    }
+	    else
+#endif
+	    {
+		/* In non-visual mode, check for the line the cursor is on */
+		if (lnum == curwin->w_cursor.lnum)
+		{
+		    word_count_cursor += word_count;
+		    char_count_cursor += char_count;
+		    byte_count_cursor = byte_count +
+			line_count_info(ml_get(lnum),
+				&word_count_cursor, &char_count_cursor,
+				  (long)(curwin->w_cursor.col + 1), eol_size);
+		}
+	    }
+	    /* Add to the running totals */
+	    byte_count += line_count_info(ml_get(lnum), &word_count,
+					 &char_count, (long)MAXCOL, eol_size);
+	}
+
+	/* Correction for when last line doesn't have an EOL. */
+	if (!curbuf->b_p_eol && curbuf->b_p_bin)
+	    byte_count -= eol_size;
+
+#ifdef FEAT_VISUAL
+	if (VIsual_active)
+	{
+	    if (VIsual_mode == Ctrl_V && curwin->w_curswant < MAXCOL)
+	    {
+		getvcols(curwin, &min_pos, &max_pos, &min_pos.col,
+								&max_pos.col);
+		sprintf((char *)buf1, _("%ld Cols; "),
+			(long)(oparg.end_vcol - oparg.start_vcol + 1));
+	    }
+	    else
+		buf1[0] = NUL;
+
+	    if (char_count_cursor == byte_count_cursor
+						  && char_count == byte_count)
+		sprintf((char *)IObuff, _("Selected %s%ld of %ld Lines; %ld of %ld Words; %ld of %ld Bytes"),
+			buf1, line_count_selected,
+			(long)curbuf->b_ml.ml_line_count,
+			word_count_cursor, word_count,
+			byte_count_cursor, byte_count);
+	    else
+		sprintf((char *)IObuff, _("Selected %s%ld of %ld Lines; %ld of %ld Words; %ld of %ld Chars; %ld of %ld Bytes"),
+			buf1, line_count_selected,
+			(long)curbuf->b_ml.ml_line_count,
+			word_count_cursor, word_count,
+			char_count_cursor, char_count,
+			byte_count_cursor, byte_count);
+	}
+	else
+#endif
+	{
+	    p = ml_get_curline();
+	    validate_virtcol();
+	    col_print(buf1, (int)curwin->w_cursor.col + 1,
+		    (int)curwin->w_virtcol + 1);
+	    col_print(buf2, (int)STRLEN(p), linetabsize(p));
+
+	    if (char_count_cursor == byte_count_cursor
+		    && char_count == byte_count)
+		sprintf((char *)IObuff, _("Col %s of %s; Line %ld of %ld; Word %ld of %ld; Byte %ld of %ld"),
+		    (char *)buf1, (char *)buf2,
+		    (long)curwin->w_cursor.lnum,
+		    (long)curbuf->b_ml.ml_line_count,
+		    word_count_cursor, word_count,
+		    byte_count_cursor, byte_count);
+	    else
+		sprintf((char *)IObuff, _("Col %s of %s; Line %ld of %ld; Word %ld of %ld; Char %ld of %ld; Byte %ld of %ld"),
+		    (char *)buf1, (char *)buf2,
+		    (long)curwin->w_cursor.lnum,
+		    (long)curbuf->b_ml.ml_line_count,
+		    word_count_cursor, word_count,
+		    char_count_cursor, char_count,
+		    byte_count_cursor, byte_count);
+	}
+
+#ifdef FEAT_MBYTE
+	byte_count = bomb_size();
+	if (byte_count > 0)
+	    sprintf((char *)IObuff + STRLEN(IObuff), _("(+%ld for BOM)"),
+								  byte_count);
+#endif
+	/* Don't shorten this message, the user asked for it. */
+	p = p_shm;
+	p_shm = (char_u *)"";
+	msg(IObuff);
+	p_shm = p;
+    }
+}
--- /dev/null
+++ b/option.c
@@ -1,0 +1,10647 @@
+/* vi:set ts=8 sts=4 sw=4:
+ *
+ * VIM - Vi IMproved	by Bram Moolenaar
+ *
+ * Do ":help uganda"  in Vim to read copying and usage conditions.
+ * Do ":help credits" in Vim to see a list of people who contributed.
+ * See README.txt for an overview of the Vim source code.
+ */
+
+/*
+ * Code to handle user-settable options. This is all pretty much table-
+ * driven. Checklist for adding a new option:
+ * - Put it in the options array below (copy an existing entry).
+ * - For a global option: Add a variable for it in option.h.
+ * - For a buffer or window local option:
+ *   - Add a PV_XX entry to the enum below.
+ *   - Add a variable to the window or buffer struct in structs.h.
+ *   - For a window option, add some code to copy_winopt().
+ *   - For a buffer option, add some code to buf_copy_options().
+ *   - For a buffer string option, add code to check_buf_options().
+ * - If it's a numeric option, add any necessary bounds checks to do_set().
+ * - If it's a list of flags, add some code in do_set(), search for WW_ALL.
+ * - When adding an option with expansion (P_EXPAND), but with a different
+ *   default for Vi and Vim (no P_VI_DEF), add some code at VIMEXP.
+ * - Add documentation!  One line in doc/help.txt, full description in
+ *   options.txt, and any other related places.
+ * - Add an entry in runtime/optwin.vim.
+ * When making changes:
+ * - Adjust the help for the option in doc/option.txt.
+ * - When an entry has the P_VIM flag, or is lacking the P_VI_DEF flag, add a
+ *   comment at the help for the 'compatible' option.
+ */
+
+#define IN_OPTION_C
+#include "vim.h"
+
+/*
+ * The options that are local to a window or buffer have "indir" set to one of
+ * these values.  Special values:
+ * PV_NONE: global option.
+ * PV_WIN is added: window-local option
+ * PV_BUF is added: buffer-local option
+ * PV_BOTH is added: global option which also has a local value.
+ */
+#define PV_BOTH 0x1000
+#define PV_WIN  0x2000
+#define PV_BUF  0x4000
+#define PV_MASK 0x0fff
+#define OPT_WIN(x)  (idopt_T)(PV_WIN + (int)(x))
+#define OPT_BUF(x)  (idopt_T)(PV_BUF + (int)(x))
+#define OPT_BOTH(x) (idopt_T)(PV_BOTH + (int)(x))
+
+/*
+ * Definition of the PV_ values for buffer-local options.
+ * The BV_ values are defined in option.h.
+ */
+#define PV_AI		OPT_BUF(BV_AI)
+#define PV_AR		OPT_BOTH(OPT_BUF(BV_AR))
+#ifdef FEAT_QUICKFIX
+# define PV_BH		OPT_BUF(BV_BH)
+# define PV_BT		OPT_BUF(BV_BT)
+# define PV_EFM		OPT_BOTH(OPT_BUF(BV_EFM))
+# define PV_GP		OPT_BOTH(OPT_BUF(BV_GP))
+# define PV_MP		OPT_BOTH(OPT_BUF(BV_MP))
+#endif
+#define PV_BIN		OPT_BUF(BV_BIN)
+#define PV_BL		OPT_BUF(BV_BL)
+#ifdef FEAT_MBYTE
+# define PV_BOMB	OPT_BUF(BV_BOMB)
+#endif
+#define PV_CI		OPT_BUF(BV_CI)
+#ifdef FEAT_CINDENT
+# define PV_CIN		OPT_BUF(BV_CIN)
+# define PV_CINK	OPT_BUF(BV_CINK)
+# define PV_CINO	OPT_BUF(BV_CINO)
+#endif
+#if defined(FEAT_SMARTINDENT) || defined(FEAT_CINDENT)
+# define PV_CINW	OPT_BUF(BV_CINW)
+#endif
+#ifdef FEAT_FOLDING
+# define PV_CMS		OPT_BUF(BV_CMS)
+#endif
+#ifdef FEAT_COMMENTS
+# define PV_COM		OPT_BUF(BV_COM)
+#endif
+#ifdef FEAT_INS_EXPAND
+# define PV_CPT		OPT_BUF(BV_CPT)
+# define PV_DICT	OPT_BOTH(OPT_BUF(BV_DICT))
+# define PV_TSR		OPT_BOTH(OPT_BUF(BV_TSR))
+#endif
+#ifdef FEAT_COMPL_FUNC
+# define PV_CFU		OPT_BUF(BV_CFU)
+#endif
+#ifdef FEAT_FIND_ID
+# define PV_DEF		OPT_BOTH(OPT_BUF(BV_DEF))
+# define PV_INC		OPT_BOTH(OPT_BUF(BV_INC))
+#endif
+#define PV_EOL		OPT_BUF(BV_EOL)
+#define PV_EP		OPT_BOTH(OPT_BUF(BV_EP))
+#define PV_ET		OPT_BUF(BV_ET)
+#ifdef FEAT_MBYTE
+# define PV_FENC	OPT_BUF(BV_FENC)
+#endif
+#if defined(FEAT_BEVAL) && defined(FEAT_EVAL)
+# define PV_BEXPR	OPT_BOTH(OPT_BUF(BV_BEXPR))
+#endif
+#ifdef FEAT_EVAL
+# define PV_FEX		OPT_BUF(BV_FEX)
+#endif
+#define PV_FF		OPT_BUF(BV_FF)
+#define PV_FLP		OPT_BUF(BV_FLP)
+#define PV_FO		OPT_BUF(BV_FO)
+#ifdef FEAT_AUTOCMD
+# define PV_FT		OPT_BUF(BV_FT)
+#endif
+#define PV_IMI		OPT_BUF(BV_IMI)
+#define PV_IMS		OPT_BUF(BV_IMS)
+#if defined(FEAT_CINDENT) && defined(FEAT_EVAL)
+# define PV_INDE	OPT_BUF(BV_INDE)
+# define PV_INDK	OPT_BUF(BV_INDK)
+#endif
+#if defined(FEAT_FIND_ID) && defined(FEAT_EVAL)
+# define PV_INEX	OPT_BUF(BV_INEX)
+#endif
+#define PV_INF		OPT_BUF(BV_INF)
+#define PV_ISK		OPT_BUF(BV_ISK)
+#ifdef FEAT_CRYPT
+# define PV_KEY		OPT_BUF(BV_KEY)
+#endif
+#ifdef FEAT_KEYMAP
+# define PV_KMAP	OPT_BUF(BV_KMAP)
+#endif
+#define PV_KP		OPT_BOTH(OPT_BUF(BV_KP))
+#ifdef FEAT_LISP
+# define PV_LISP	OPT_BUF(BV_LISP)
+#endif
+#define PV_MA		OPT_BUF(BV_MA)
+#define PV_ML		OPT_BUF(BV_ML)
+#define PV_MOD		OPT_BUF(BV_MOD)
+#define PV_MPS		OPT_BUF(BV_MPS)
+#define PV_NF		OPT_BUF(BV_NF)
+#ifdef FEAT_OSFILETYPE
+# define PV_OFT		OPT_BUF(BV_OFT)
+#endif
+#ifdef FEAT_COMPL_FUNC
+# define PV_OFU		OPT_BUF(BV_OFU)
+#endif
+#define PV_PATH		OPT_BOTH(OPT_BUF(BV_PATH))
+#define PV_PI		OPT_BUF(BV_PI)
+#ifdef FEAT_TEXTOBJ
+# define PV_QE		OPT_BUF(BV_QE)
+#endif
+#define PV_RO		OPT_BUF(BV_RO)
+#ifdef FEAT_SMARTINDENT
+# define PV_SI		OPT_BUF(BV_SI)
+#endif
+#ifndef SHORT_FNAME
+# define PV_SN		OPT_BUF(BV_SN)
+#endif
+#ifdef FEAT_SYN_HL
+# define PV_SMC		OPT_BUF(BV_SMC)
+# define PV_SYN		OPT_BUF(BV_SYN)
+#endif
+#ifdef FEAT_SPELL
+# define PV_SPC		OPT_BUF(BV_SPC)
+# define PV_SPF		OPT_BUF(BV_SPF)
+# define PV_SPL		OPT_BUF(BV_SPL)
+#endif
+#define PV_STS		OPT_BUF(BV_STS)
+#ifdef FEAT_SEARCHPATH
+# define PV_SUA		OPT_BUF(BV_SUA)
+#endif
+#define PV_SW		OPT_BUF(BV_SW)
+#define PV_SWF		OPT_BUF(BV_SWF)
+#define PV_TAGS		OPT_BOTH(OPT_BUF(BV_TAGS))
+#define PV_TS		OPT_BUF(BV_TS)
+#define PV_TW		OPT_BUF(BV_TW)
+#define PV_TX		OPT_BUF(BV_TX)
+#define PV_WM		OPT_BUF(BV_WM)
+
+/*
+ * Definition of the PV_ values for window-local options.
+ * The WV_ values are defined in option.h.
+ */
+#define PV_LIST		OPT_WIN(WV_LIST)
+#ifdef FEAT_ARABIC
+# define PV_ARAB	OPT_WIN(WV_ARAB)
+#endif
+#ifdef FEAT_DIFF
+# define PV_DIFF	OPT_WIN(WV_DIFF)
+#endif
+#ifdef FEAT_FOLDING
+# define PV_FDC		OPT_WIN(WV_FDC)
+# define PV_FEN		OPT_WIN(WV_FEN)
+# define PV_FDI		OPT_WIN(WV_FDI)
+# define PV_FDL		OPT_WIN(WV_FDL)
+# define PV_FDM		OPT_WIN(WV_FDM)
+# define PV_FML		OPT_WIN(WV_FML)
+# define PV_FDN		OPT_WIN(WV_FDN)
+# ifdef FEAT_EVAL
+#  define PV_FDE	OPT_WIN(WV_FDE)
+#  define PV_FDT	OPT_WIN(WV_FDT)
+# endif
+# define PV_FMR		OPT_WIN(WV_FMR)
+#endif
+#ifdef FEAT_LINEBREAK
+# define PV_LBR		OPT_WIN(WV_LBR)
+#endif
+#define PV_NU		OPT_WIN(WV_NU)
+#ifdef FEAT_LINEBREAK
+# define PV_NUW		OPT_WIN(WV_NUW)
+#endif
+#if defined(FEAT_WINDOWS) && defined(FEAT_QUICKFIX)
+# define PV_PVW		OPT_WIN(WV_PVW)
+#endif
+#ifdef FEAT_RIGHTLEFT
+# define PV_RL		OPT_WIN(WV_RL)
+# define PV_RLC		OPT_WIN(WV_RLC)
+#endif
+#ifdef FEAT_SCROLLBIND
+# define PV_SCBIND	OPT_WIN(WV_SCBIND)
+#endif
+#define PV_SCROLL	OPT_WIN(WV_SCROLL)
+#ifdef FEAT_SPELL
+# define PV_SPELL	OPT_WIN(WV_SPELL)
+#endif
+#ifdef FEAT_SYN_HL
+# define PV_CUC		OPT_WIN(WV_CUC)
+# define PV_CUL		OPT_WIN(WV_CUL)
+#endif
+#ifdef FEAT_STL_OPT
+# define PV_STL		OPT_BOTH(OPT_WIN(WV_STL))
+#endif
+#ifdef FEAT_WINDOWS
+# define PV_WFH		OPT_WIN(WV_WFH)
+#endif
+#ifdef FEAT_VERTSPLIT
+# define PV_WFW		OPT_WIN(WV_WFW)
+#endif
+#define PV_WRAP		OPT_WIN(WV_WRAP)
+
+
+/* WV_ and BV_ values get typecasted to this for the "indir" field */
+typedef enum
+{
+    PV_NONE = 0
+} idopt_T;
+
+/*
+ * Options local to a window have a value local to a buffer and global to all
+ * buffers.  Indicate this by setting "var" to VAR_WIN.
+ */
+#define VAR_WIN ((char_u *)-1)
+
+/*
+ * These are the global values for options which are also local to a buffer.
+ * Only to be used in option.c!
+ */
+static int	p_ai;
+static int	p_bin;
+#ifdef FEAT_MBYTE
+static int	p_bomb;
+#endif
+#if defined(FEAT_QUICKFIX)
+static char_u	*p_bh;
+static char_u	*p_bt;
+#endif
+static int	p_bl;
+static int	p_ci;
+#ifdef FEAT_CINDENT
+static int	p_cin;
+static char_u	*p_cink;
+static char_u	*p_cino;
+#endif
+#if defined(FEAT_SMARTINDENT) || defined(FEAT_CINDENT)
+static char_u	*p_cinw;
+#endif
+#ifdef FEAT_COMMENTS
+static char_u	*p_com;
+#endif
+#ifdef FEAT_FOLDING
+static char_u	*p_cms;
+#endif
+#ifdef FEAT_INS_EXPAND
+static char_u	*p_cpt;
+#endif
+#ifdef FEAT_COMPL_FUNC
+static char_u	*p_cfu;
+static char_u	*p_ofu;
+#endif
+static int	p_eol;
+static int	p_et;
+#ifdef FEAT_MBYTE
+static char_u	*p_fenc;
+#endif
+static char_u	*p_ff;
+static char_u	*p_fo;
+static char_u	*p_flp;
+#ifdef FEAT_AUTOCMD
+static char_u	*p_ft;
+#endif
+static long	p_iminsert;
+static long	p_imsearch;
+#if defined(FEAT_FIND_ID) && defined(FEAT_EVAL)
+static char_u	*p_inex;
+#endif
+#if defined(FEAT_CINDENT) && defined(FEAT_EVAL)
+static char_u	*p_inde;
+static char_u	*p_indk;
+#endif
+#if defined(FEAT_EVAL)
+static char_u	*p_fex;
+#endif
+static int	p_inf;
+static char_u	*p_isk;
+#ifdef FEAT_CRYPT
+static char_u	*p_key;
+#endif
+#ifdef FEAT_LISP
+static int	p_lisp;
+#endif
+static int	p_ml;
+static int	p_ma;
+static int	p_mod;
+static char_u	*p_mps;
+static char_u	*p_nf;
+#ifdef FEAT_OSFILETYPE
+static char_u	*p_oft;
+#endif
+static int	p_pi;
+#ifdef FEAT_TEXTOBJ
+static char_u	*p_qe;
+#endif
+static int	p_ro;
+#ifdef FEAT_SMARTINDENT
+static int	p_si;
+#endif
+#ifndef SHORT_FNAME
+static int	p_sn;
+#endif
+static long	p_sts;
+#if defined(FEAT_SEARCHPATH)
+static char_u	*p_sua;
+#endif
+static long	p_sw;
+static int	p_swf;
+#ifdef FEAT_SYN_HL
+static long	p_smc;
+static char_u	*p_syn;
+#endif
+#ifdef FEAT_SPELL
+static char_u	*p_spc;
+static char_u	*p_spf;
+static char_u	*p_spl;
+#endif
+static long	p_ts;
+static long	p_tw;
+static int	p_tx;
+static long	p_wm;
+#ifdef FEAT_KEYMAP
+static char_u	*p_keymap;
+#endif
+
+/* Saved values for when 'bin' is set. */
+static int	p_et_nobin;
+static int	p_ml_nobin;
+static long	p_tw_nobin;
+static long	p_wm_nobin;
+
+/* Saved values for when 'paste' is set */
+static long	p_tw_nopaste;
+static long	p_wm_nopaste;
+static long	p_sts_nopaste;
+static int	p_ai_nopaste;
+
+struct vimoption
+{
+    char	*fullname;	/* full option name */
+    char	*shortname;	/* permissible abbreviation */
+    long_u	flags;		/* see below */
+    char_u	*var;		/* global option: pointer to variable;
+				 * window-local option: VAR_WIN;
+				 * buffer-local option: global value */
+    idopt_T	indir;		/* global option: PV_NONE;
+				 * local option: indirect option index */
+    char_u	*def_val[2];	/* default values for variable (vi and vim) */
+#ifdef FEAT_EVAL
+    scid_T	scriptID;	/* script in which the option was last set */
+#endif
+};
+
+#define VI_DEFAULT  0	    /* def_val[VI_DEFAULT] is Vi default value */
+#define VIM_DEFAULT 1	    /* def_val[VIM_DEFAULT] is Vim default value */
+
+/*
+ * Flags
+ */
+#define P_BOOL		0x01	/* the option is boolean */
+#define P_NUM		0x02	/* the option is numeric */
+#define P_STRING	0x04	/* the option is a string */
+#define P_ALLOCED	0x08	/* the string option is in allocated memory,
+				    must use vim_free() when assigning new
+				    value. Not set if default is the same. */
+#define P_EXPAND	0x10	/* environment expansion.  NOTE: P_EXPAND can
+				   never be used for local or hidden options! */
+#define P_NODEFAULT	0x40	/* don't set to default value */
+#define P_DEF_ALLOCED	0x80	/* default value is in allocated memory, must
+				    use vim_free() when assigning new value */
+#define P_WAS_SET	0x100	/* option has been set/reset */
+#define P_NO_MKRC	0x200	/* don't include in :mkvimrc output */
+#define P_VI_DEF	0x400	/* Use Vi default for Vim */
+#define P_VIM		0x800	/* Vim option, reset when 'cp' set */
+
+				/* when option changed, what to display: */
+#define P_RSTAT		0x1000	/* redraw status lines */
+#define P_RWIN		0x2000	/* redraw current window */
+#define P_RBUF		0x4000	/* redraw current buffer */
+#define P_RALL		0x6000	/* redraw all windows */
+#define P_RCLR		0x7000	/* clear and redraw all */
+
+#define P_COMMA		0x8000	/* comma separated list */
+#define P_NODUP		0x10000L/* don't allow duplicate strings */
+#define P_FLAGLIST	0x20000L/* list of single-char flags */
+
+#define P_SECURE	0x40000L/* cannot change in modeline or secure mode */
+#define P_GETTEXT	0x80000L/* expand default value with _() */
+#define P_NOGLOB       0x100000L/* do not use local value for global vimrc */
+#define P_NFNAME       0x200000L/* only normal file name chars allowed */
+#define P_INSECURE     0x400000L/* option was set from a modeline */
+
+#define ISK_LATIN1  (char_u *)"@,48-57,_,192-255"
+
+/* 'isprint' for latin1 is also used for MS-Windows cp1252, where 0x80 is used
+ * for the currency sign. */
+#if defined(MSDOS) || defined(MSWIN) || defined(OS2)
+# define ISP_LATIN1 (char_u *)"@,~-255"
+#else
+# define ISP_LATIN1 (char_u *)"@,161-255"
+#endif
+
+/* The 16 bit MS-DOS version is low on space, make the string as short as
+ * possible when compiling with few features. */
+#if defined(FEAT_DIFF) || defined(FEAT_FOLDING) || defined(FEAT_SPELL) \
+	|| defined(FEAT_VERTSPLIT) || defined(FEAT_CLIPBOARD) \
+	|| defined(FEAT_INS_EXPAND) || defined(FEAT_SYN_HL)
+# define HIGHLIGHT_INIT "8:SpecialKey,@:NonText,d:Directory,e:ErrorMsg,i:IncSearch,l:Search,m:MoreMsg,M:ModeMsg,n:LineNr,r:Question,s:StatusLine,S:StatusLineNC,c:VertSplit,t:Title,v:Visual,V:VisualNOS,w:WarningMsg,W:WildMenu,f:Folded,F:FoldColumn,A:DiffAdd,C:DiffChange,D:DiffDelete,T:DiffText,>:SignColumn,B:SpellBad,P:SpellCap,R:SpellRare,L:SpellLocal,+:Pmenu,=:PmenuSel,x:PmenuSbar,X:PmenuThumb,*:TabLine,#:TabLineSel,_:TabLineFill,!:CursorColumn,.:CursorLine"
+#else
+# define HIGHLIGHT_INIT "8:SpecialKey,@:NonText,d:Directory,e:ErrorMsg,i:IncSearch,l:Search,m:MoreMsg,M:ModeMsg,n:LineNr,r:Question,s:StatusLine,S:StatusLineNC,t:Title,v:Visual,w:WarningMsg,W:WildMenu,>:SignColumn,*:TabLine,#:TabLineSel,_:TabLineFill"
+#endif
+
+/*
+ * options[] is initialized here.
+ * The order of the options MUST be alphabetic for ":set all" and findoption().
+ * All option names MUST start with a lowercase letter (for findoption()).
+ * Exception: "t_" options are at the end.
+ * The options with a NULL variable are 'hidden': a set command for them is
+ * ignored and they are not printed.
+ */
+static struct vimoption
+#ifdef FEAT_GUI_W16
+	_far
+#endif
+	options[] =
+{
+    {"aleph",	    "al",   P_NUM|P_VI_DEF,
+#ifdef FEAT_RIGHTLEFT
+			    (char_u *)&p_aleph, PV_NONE,
+#else
+			    (char_u *)NULL, PV_NONE,
+#endif
+			    {
+#if (defined(MSDOS) || defined(WIN3264) || defined(OS2)) && !defined(FEAT_GUI_W32)
+			    (char_u *)128L,
+#else
+			    (char_u *)224L,
+#endif
+					    (char_u *)0L}},
+    {"antialias",   "anti", P_BOOL|P_VI_DEF|P_VIM|P_RCLR,
+#if defined(FEAT_GUI) && defined(MACOS_X)
+			    (char_u *)&p_antialias, PV_NONE,
+			    {(char_u *)FALSE, (char_u *)FALSE}
+#else
+			    (char_u *)NULL, PV_NONE,
+			    {(char_u *)FALSE, (char_u *)FALSE}
+#endif
+			    },
+    {"arabic",	    "arab", P_BOOL|P_VI_DEF|P_VIM,
+#ifdef FEAT_ARABIC
+			    (char_u *)VAR_WIN, PV_ARAB,
+#else
+			    (char_u *)NULL, PV_NONE,
+#endif
+			    {(char_u *)FALSE, (char_u *)0L}},
+    {"arabicshape", "arshape", P_BOOL|P_VI_DEF|P_VIM|P_RCLR,
+#ifdef FEAT_ARABIC
+			    (char_u *)&p_arshape, PV_NONE,
+#else
+			    (char_u *)NULL, PV_NONE,
+#endif
+			    {(char_u *)TRUE, (char_u *)0L}},
+    {"allowrevins", "ari",  P_BOOL|P_VI_DEF|P_VIM,
+#ifdef FEAT_RIGHTLEFT
+			    (char_u *)&p_ari, PV_NONE,
+#else
+			    (char_u *)NULL, PV_NONE,
+#endif
+			    {(char_u *)FALSE, (char_u *)0L}},
+    {"altkeymap",   "akm",  P_BOOL|P_VI_DEF,
+#ifdef FEAT_FKMAP
+			    (char_u *)&p_altkeymap, PV_NONE,
+#else
+			    (char_u *)NULL, PV_NONE,
+#endif
+			    {(char_u *)FALSE, (char_u *)0L}},
+    {"ambiwidth",  "ambw",  P_STRING|P_VI_DEF|P_RCLR,
+#if defined(FEAT_MBYTE)
+			    (char_u *)&p_ambw, PV_NONE,
+			    {(char_u *)"single", (char_u *)0L}
+#else
+			    (char_u *)NULL, PV_NONE,
+			    {(char_u *)0L, (char_u *)0L}
+#endif
+			    },
+#ifdef FEAT_AUTOCHDIR
+    {"autochdir",  "acd",   P_BOOL|P_VI_DEF,
+			    (char_u *)&p_acd, PV_NONE,
+			    {(char_u *)FALSE, (char_u *)0L}},
+#endif
+    {"autoindent",  "ai",   P_BOOL|P_VI_DEF,
+			    (char_u *)&p_ai, PV_AI,
+			    {(char_u *)FALSE, (char_u *)0L}},
+    {"autoprint",   "ap",   P_BOOL|P_VI_DEF,
+			    (char_u *)NULL, PV_NONE,
+			    {(char_u *)FALSE, (char_u *)0L}},
+    {"autoread",    "ar",   P_BOOL|P_VI_DEF,
+			    (char_u *)&p_ar, PV_AR,
+			    {(char_u *)FALSE, (char_u *)0L}},
+    {"autowrite",   "aw",   P_BOOL|P_VI_DEF,
+			    (char_u *)&p_aw, PV_NONE,
+			    {(char_u *)FALSE, (char_u *)0L}},
+    {"autowriteall","awa",  P_BOOL|P_VI_DEF,
+			    (char_u *)&p_awa, PV_NONE,
+			    {(char_u *)FALSE, (char_u *)0L}},
+    {"background",  "bg",   P_STRING|P_VI_DEF|P_RCLR,
+			    (char_u *)&p_bg, PV_NONE,
+			    {
+#if (defined(MSDOS) || defined(OS2) || defined(WIN3264)) && !defined(FEAT_GUI)
+			    (char_u *)"dark",
+#else
+			    (char_u *)"light",
+#endif
+					    (char_u *)0L}},
+    {"backspace",   "bs",   P_STRING|P_VI_DEF|P_VIM|P_COMMA|P_NODUP,
+			    (char_u *)&p_bs, PV_NONE,
+			    {(char_u *)"", (char_u *)0L}},
+    {"backup",	    "bk",   P_BOOL|P_VI_DEF|P_VIM,
+			    (char_u *)&p_bk, PV_NONE,
+			    {(char_u *)FALSE, (char_u *)0L}},
+    {"backupcopy",  "bkc",  P_STRING|P_VIM|P_COMMA|P_NODUP,
+			    (char_u *)&p_bkc, PV_NONE,
+#ifdef UNIX
+			    {(char_u *)"yes", (char_u *)"auto"}
+#else
+			    {(char_u *)"auto", (char_u *)"auto"}
+#endif
+			    },
+    {"backupdir",   "bdir", P_STRING|P_EXPAND|P_VI_DEF|P_COMMA|P_NODUP|P_SECURE,
+			    (char_u *)&p_bdir, PV_NONE,
+			    {(char_u *)DFLT_BDIR, (char_u *)0L}},
+    {"backupext",   "bex",  P_STRING|P_VI_DEF|P_NFNAME,
+			    (char_u *)&p_bex, PV_NONE,
+			    {
+#ifdef VMS
+			    (char_u *)"_",
+#else
+			    (char_u *)"~",
+#endif
+					    (char_u *)0L}},
+    {"backupskip",  "bsk",  P_STRING|P_VI_DEF|P_COMMA,
+#ifdef FEAT_WILDIGN
+			    (char_u *)&p_bsk, PV_NONE,
+			    {(char_u *)"", (char_u *)0L}
+#else
+			    (char_u *)NULL, PV_NONE,
+			    {(char_u *)0L, (char_u *)0L}
+#endif
+			    },
+#ifdef FEAT_BEVAL
+    {"balloondelay","bdlay",P_NUM|P_VI_DEF,
+			    (char_u *)&p_bdlay, PV_NONE,
+			    {(char_u *)600L, (char_u *)0L}},
+    {"ballooneval", "beval",P_BOOL|P_VI_DEF|P_NO_MKRC,
+			    (char_u *)&p_beval, PV_NONE,
+			    {(char_u *)FALSE, (char_u *)0L}},
+# ifdef FEAT_EVAL
+    {"balloonexpr", "bexpr", P_STRING|P_ALLOCED|P_VI_DEF|P_VIM,
+			    (char_u *)&p_bexpr, PV_BEXPR,
+			    {(char_u *)"", (char_u *)0L}},
+# endif
+#endif
+    {"beautify",    "bf",   P_BOOL|P_VI_DEF,
+			    (char_u *)NULL, PV_NONE,
+			    {(char_u *)FALSE, (char_u *)0L}},
+    {"binary",	    "bin",  P_BOOL|P_VI_DEF|P_RSTAT,
+			    (char_u *)&p_bin, PV_BIN,
+			    {(char_u *)FALSE, (char_u *)0L}},
+    {"bioskey",	    "biosk",P_BOOL|P_VI_DEF,
+#ifdef MSDOS
+			    (char_u *)&p_biosk, PV_NONE,
+#else
+			    (char_u *)NULL, PV_NONE,
+#endif
+			    {(char_u *)TRUE, (char_u *)0L}},
+    {"bomb",	    NULL,   P_BOOL|P_NO_MKRC|P_VI_DEF|P_RSTAT,
+#ifdef FEAT_MBYTE
+			    (char_u *)&p_bomb, PV_BOMB,
+#else
+			    (char_u *)NULL, PV_NONE,
+#endif
+			    {(char_u *)FALSE, (char_u *)0L}},
+    {"breakat",	    "brk",  P_STRING|P_VI_DEF|P_RALL|P_FLAGLIST,
+#ifdef FEAT_LINEBREAK
+			    (char_u *)&p_breakat, PV_NONE,
+			    {(char_u *)" \t!@*-+;:,./?", (char_u *)0L}
+#else
+			    (char_u *)NULL, PV_NONE,
+			    {(char_u *)0L, (char_u *)0L}
+#endif
+			    },
+    {"browsedir",   "bsdir",P_STRING|P_VI_DEF,
+#ifdef FEAT_BROWSE
+			    (char_u *)&p_bsdir, PV_NONE,
+			    {(char_u *)"last", (char_u *)0L}
+#else
+			    (char_u *)NULL, PV_NONE,
+			    {(char_u *)0L, (char_u *)0L}
+#endif
+			    },
+    {"bufhidden",   "bh",   P_STRING|P_ALLOCED|P_VI_DEF|P_NOGLOB,
+#if defined(FEAT_QUICKFIX)
+			    (char_u *)&p_bh, PV_BH,
+			    {(char_u *)"", (char_u *)0L}
+#else
+			    (char_u *)NULL, PV_NONE,
+			    {(char_u *)0L, (char_u *)0L}
+#endif
+			    },
+    {"buflisted",   "bl",   P_BOOL|P_VI_DEF|P_NOGLOB,
+			    (char_u *)&p_bl, PV_BL,
+			    {(char_u *)1L, (char_u *)0L}
+			    },
+    {"buftype",	    "bt",   P_STRING|P_ALLOCED|P_VI_DEF|P_NOGLOB,
+#if defined(FEAT_QUICKFIX)
+			    (char_u *)&p_bt, PV_BT,
+			    {(char_u *)"", (char_u *)0L}
+#else
+			    (char_u *)NULL, PV_NONE,
+			    {(char_u *)0L, (char_u *)0L}
+#endif
+			    },
+    {"casemap",	    "cmp",   P_STRING|P_VI_DEF|P_COMMA|P_NODUP,
+#ifdef FEAT_MBYTE
+			    (char_u *)&p_cmp, PV_NONE,
+			    {(char_u *)"internal,keepascii", (char_u *)0L}
+#else
+			    (char_u *)NULL, PV_NONE,
+			    {(char_u *)0L, (char_u *)0L}
+#endif
+			    },
+    {"cdpath",	    "cd",   P_STRING|P_EXPAND|P_VI_DEF|P_COMMA|P_NODUP,
+#ifdef FEAT_SEARCHPATH
+			    (char_u *)&p_cdpath, PV_NONE,
+			    {(char_u *)",,", (char_u *)0L}
+#else
+			    (char_u *)NULL, PV_NONE,
+			    {(char_u *)0L, (char_u *)0L}
+#endif
+			    },
+    {"cedit",	    NULL,   P_STRING,
+#ifdef FEAT_CMDWIN
+			    (char_u *)&p_cedit, PV_NONE,
+			    {(char_u *)"", (char_u *)CTRL_F_STR}
+#else
+			    (char_u *)NULL, PV_NONE,
+			    {(char_u *)0L, (char_u *)0L}
+#endif
+			    },
+    {"charconvert",  "ccv", P_STRING|P_VI_DEF|P_SECURE,
+#if defined(FEAT_MBYTE) && defined(FEAT_EVAL)
+			    (char_u *)&p_ccv, PV_NONE,
+			    {(char_u *)"", (char_u *)0L}
+#else
+			    (char_u *)NULL, PV_NONE,
+			    {(char_u *)0L, (char_u *)0L}
+#endif
+			    },
+    {"cindent",	    "cin",  P_BOOL|P_VI_DEF|P_VIM,
+#ifdef FEAT_CINDENT
+			    (char_u *)&p_cin, PV_CIN,
+#else
+			    (char_u *)NULL, PV_NONE,
+#endif
+			    {(char_u *)FALSE, (char_u *)0L}},
+    {"cinkeys",	    "cink", P_STRING|P_ALLOCED|P_VI_DEF|P_COMMA|P_NODUP,
+#ifdef FEAT_CINDENT
+			    (char_u *)&p_cink, PV_CINK,
+			    {(char_u *)"0{,0},0),:,0#,!^F,o,O,e", (char_u *)0L}
+#else
+			    (char_u *)NULL, PV_NONE,
+			    {(char_u *)0L, (char_u *)0L}
+#endif
+			    },
+    {"cinoptions",  "cino", P_STRING|P_ALLOCED|P_VI_DEF|P_COMMA|P_NODUP,
+#ifdef FEAT_CINDENT
+			    (char_u *)&p_cino, PV_CINO,
+#else
+			    (char_u *)NULL, PV_NONE,
+#endif
+			    {(char_u *)"", (char_u *)0L}},
+    {"cinwords",    "cinw", P_STRING|P_ALLOCED|P_VI_DEF|P_COMMA|P_NODUP,
+#if defined(FEAT_SMARTINDENT) || defined(FEAT_CINDENT)
+			    (char_u *)&p_cinw, PV_CINW,
+			    {(char_u *)"if,else,while,do,for,switch",
+				(char_u *)0L}
+#else
+			    (char_u *)NULL, PV_NONE,
+			    {(char_u *)0L, (char_u *)0L}
+#endif
+			    },
+    {"clipboard",   "cb",   P_STRING|P_VI_DEF|P_COMMA|P_NODUP,
+#ifdef FEAT_CLIPBOARD
+			    (char_u *)&p_cb, PV_NONE,
+# ifdef FEAT_XCLIPBOARD
+			    {(char_u *)"autoselect,exclude:cons\\|linux",
+							       (char_u *)0L}
+# else
+			    {(char_u *)"", (char_u *)0L}
+# endif
+#else
+			    (char_u *)NULL, PV_NONE,
+			    {(char_u *)"", (char_u *)0L}
+#endif
+			    },
+    {"cmdheight",   "ch",   P_NUM|P_VI_DEF|P_RALL,
+			    (char_u *)&p_ch, PV_NONE,
+			    {(char_u *)1L, (char_u *)0L}},
+    {"cmdwinheight", "cwh", P_NUM|P_VI_DEF,
+#ifdef FEAT_CMDWIN
+			    (char_u *)&p_cwh, PV_NONE,
+#else
+			    (char_u *)NULL, PV_NONE,
+#endif
+			    {(char_u *)7L, (char_u *)0L}},
+    {"columns",	    "co",   P_NUM|P_NODEFAULT|P_NO_MKRC|P_VI_DEF|P_RCLR,
+			    (char_u *)&Columns, PV_NONE,
+			    {(char_u *)80L, (char_u *)0L}},
+    {"comments",    "com",  P_STRING|P_ALLOCED|P_VI_DEF|P_COMMA|P_NODUP,
+#ifdef FEAT_COMMENTS
+			    (char_u *)&p_com, PV_COM,
+			    {(char_u *)"s1:/*,mb:*,ex:*/,://,b:#,:%,:XCOMM,n:>,fb:-",
+				(char_u *)0L}
+#else
+			    (char_u *)NULL, PV_NONE,
+			    {(char_u *)0L, (char_u *)0L}
+#endif
+			    },
+    {"commentstring", "cms", P_STRING|P_ALLOCED|P_VI_DEF,
+#ifdef FEAT_FOLDING
+			    (char_u *)&p_cms, PV_CMS,
+			    {(char_u *)"/*%s*/", (char_u *)0L}
+#else
+			    (char_u *)NULL, PV_NONE,
+			    {(char_u *)0L, (char_u *)0L}
+#endif
+			    },
+    {"compatible",  "cp",   P_BOOL|P_RALL,
+			    (char_u *)&p_cp, PV_NONE,
+			    {(char_u *)TRUE, (char_u *)FALSE}},
+    {"complete",    "cpt",  P_STRING|P_ALLOCED|P_VI_DEF|P_COMMA|P_NODUP,
+#ifdef FEAT_INS_EXPAND
+			    (char_u *)&p_cpt, PV_CPT,
+			    {(char_u *)".,w,b,u,t,i", (char_u *)0L}
+#else
+			    (char_u *)NULL, PV_NONE,
+			    {(char_u *)0L, (char_u *)0L}
+#endif
+			    },
+    {"completefunc", "cfu", P_STRING|P_ALLOCED|P_VI_DEF|P_SECURE,
+#ifdef FEAT_COMPL_FUNC
+			    (char_u *)&p_cfu, PV_CFU,
+			    {(char_u *)"", (char_u *)0L}
+#else
+			    (char_u *)NULL, PV_NONE,
+			    {(char_u *)0L, (char_u *)0L}
+#endif
+			    },
+    {"completeopt",   "cot",  P_STRING|P_VI_DEF|P_COMMA|P_NODUP,
+#ifdef FEAT_INS_EXPAND
+			    (char_u *)&p_cot, PV_NONE,
+			    {(char_u *)"menu,preview", (char_u *)0L}
+#else
+			    (char_u *)NULL, PV_NONE,
+			    {(char_u *)0L, (char_u *)0L}
+#endif
+			    },
+    {"confirm",     "cf",   P_BOOL|P_VI_DEF,
+#if defined(FEAT_GUI_DIALOG) || defined(FEAT_CON_DIALOG)
+			    (char_u *)&p_confirm, PV_NONE,
+#else
+			    (char_u *)NULL, PV_NONE,
+#endif
+			    {(char_u *)FALSE, (char_u *)0L}},
+    {"conskey",	    "consk",P_BOOL|P_VI_DEF,
+#ifdef MSDOS
+			    (char_u *)&p_consk, PV_NONE,
+#else
+			    (char_u *)NULL, PV_NONE,
+#endif
+			    {(char_u *)FALSE, (char_u *)0L}},
+    {"copyindent",  "ci",   P_BOOL|P_VI_DEF|P_VIM,
+			    (char_u *)&p_ci, PV_CI,
+			    {(char_u *)FALSE, (char_u *)0L}},
+    {"cpoptions",   "cpo",  P_STRING|P_VIM|P_RALL|P_FLAGLIST,
+			    (char_u *)&p_cpo, PV_NONE,
+			    {(char_u *)CPO_VI, (char_u *)CPO_VIM}},
+    {"cscopepathcomp", "cspc", P_NUM|P_VI_DEF|P_VIM,
+#ifdef FEAT_CSCOPE
+			    (char_u *)&p_cspc, PV_NONE,
+#else
+			    (char_u *)NULL, PV_NONE,
+#endif
+			    {(char_u *)0L, (char_u *)0L}},
+    {"cscopeprg",   "csprg", P_STRING|P_EXPAND|P_VI_DEF|P_SECURE,
+#ifdef FEAT_CSCOPE
+			    (char_u *)&p_csprg, PV_NONE,
+			    {(char_u *)"cscope", (char_u *)0L}
+#else
+			    (char_u *)NULL, PV_NONE,
+			    {(char_u *)0L, (char_u *)0L}
+#endif
+			    },
+    {"cscopequickfix", "csqf", P_STRING|P_VI_DEF|P_COMMA|P_NODUP,
+#if defined(FEAT_CSCOPE) && defined(FEAT_QUICKFIX)
+			    (char_u *)&p_csqf, PV_NONE,
+			    {(char_u *)"", (char_u *)0L}
+#else
+			    (char_u *)NULL, PV_NONE,
+			    {(char_u *)0L, (char_u *)0L}
+#endif
+			    },
+    {"cscopetag",   "cst",  P_BOOL|P_VI_DEF|P_VIM,
+#ifdef FEAT_CSCOPE
+			    (char_u *)&p_cst, PV_NONE,
+#else
+			    (char_u *)NULL, PV_NONE,
+#endif
+			    {(char_u *)0L, (char_u *)0L}},
+    {"cscopetagorder", "csto", P_NUM|P_VI_DEF|P_VIM,
+#ifdef FEAT_CSCOPE
+			    (char_u *)&p_csto, PV_NONE,
+#else
+			    (char_u *)NULL, PV_NONE,
+#endif
+			    {(char_u *)0L, (char_u *)0L}},
+    {"cscopeverbose", "csverb", P_BOOL|P_VI_DEF|P_VIM,
+#ifdef FEAT_CSCOPE
+			    (char_u *)&p_csverbose, PV_NONE,
+#else
+			    (char_u *)NULL, PV_NONE,
+#endif
+			    {(char_u *)0L, (char_u *)0L}},
+    {"cursorcolumn", "cuc", P_BOOL|P_VI_DEF|P_RWIN,
+#ifdef FEAT_SYN_HL
+			    (char_u *)VAR_WIN, PV_CUC,
+#else
+			    (char_u *)NULL, PV_NONE,
+#endif
+			    {(char_u *)FALSE, (char_u *)0L}},
+    {"cursorline",   "cul", P_BOOL|P_VI_DEF|P_RWIN,
+#ifdef FEAT_SYN_HL
+			    (char_u *)VAR_WIN, PV_CUL,
+#else
+			    (char_u *)NULL, PV_NONE,
+#endif
+			    {(char_u *)FALSE, (char_u *)0L}},
+    {"debug",	    NULL,   P_STRING|P_VI_DEF,
+			    (char_u *)&p_debug, PV_NONE,
+			    {(char_u *)"", (char_u *)0L}},
+    {"define",	    "def",  P_STRING|P_ALLOCED|P_VI_DEF,
+#ifdef FEAT_FIND_ID
+			    (char_u *)&p_def, PV_DEF,
+			    {(char_u *)"^\\s*#\\s*define", (char_u *)0L}
+#else
+			    (char_u *)NULL, PV_NONE,
+			    {(char_u *)NULL, (char_u *)0L}
+#endif
+			    },
+    {"delcombine", "deco",  P_BOOL|P_VI_DEF|P_VIM,
+#ifdef FEAT_MBYTE
+			    (char_u *)&p_deco, PV_NONE,
+#else
+			    (char_u *)NULL, PV_NONE,
+#endif
+			    {(char_u *)FALSE, (char_u *)0L}},
+    {"dictionary",  "dict", P_STRING|P_EXPAND|P_VI_DEF|P_COMMA|P_NODUP,
+#ifdef FEAT_INS_EXPAND
+			    (char_u *)&p_dict, PV_DICT,
+#else
+			    (char_u *)NULL, PV_NONE,
+#endif
+			    {(char_u *)"", (char_u *)0L}},
+    {"diff",	    NULL,   P_BOOL|P_VI_DEF|P_RWIN|P_NOGLOB,
+#ifdef FEAT_DIFF
+			    (char_u *)VAR_WIN, PV_DIFF,
+#else
+			    (char_u *)NULL, PV_NONE,
+#endif
+			    {(char_u *)FALSE, (char_u *)0L}},
+    {"diffexpr",    "dex",  P_STRING|P_VI_DEF|P_SECURE,
+#if defined(FEAT_DIFF) && defined(FEAT_EVAL)
+			    (char_u *)&p_dex, PV_NONE,
+			    {(char_u *)"", (char_u *)0L}
+#else
+			    (char_u *)NULL, PV_NONE,
+			    {(char_u *)0L, (char_u *)0L}
+#endif
+			    },
+    {"diffopt",	    "dip",  P_STRING|P_ALLOCED|P_VI_DEF|P_RWIN|P_COMMA|P_NODUP,
+#ifdef FEAT_DIFF
+			    (char_u *)&p_dip, PV_NONE,
+			    {(char_u *)"filler", (char_u *)NULL}
+#else
+			    (char_u *)NULL, PV_NONE,
+			    {(char_u *)"", (char_u *)NULL}
+#endif
+			    },
+    {"digraph",	    "dg",   P_BOOL|P_VI_DEF|P_VIM,
+#ifdef FEAT_DIGRAPHS
+			    (char_u *)&p_dg, PV_NONE,
+#else
+			    (char_u *)NULL, PV_NONE,
+#endif
+			    {(char_u *)FALSE, (char_u *)0L}},
+    {"directory",   "dir",  P_STRING|P_EXPAND|P_VI_DEF|P_COMMA|P_NODUP|P_SECURE,
+			    (char_u *)&p_dir, PV_NONE,
+			    {(char_u *)DFLT_DIR, (char_u *)0L}},
+    {"display",	    "dy",   P_STRING|P_VI_DEF|P_COMMA|P_RALL|P_NODUP,
+			    (char_u *)&p_dy, PV_NONE,
+			    {(char_u *)"", (char_u *)0L}},
+    {"eadirection", "ead",  P_STRING|P_VI_DEF,
+#ifdef FEAT_VERTSPLIT
+			    (char_u *)&p_ead, PV_NONE,
+			    {(char_u *)"both", (char_u *)0L}
+#else
+			    (char_u *)NULL, PV_NONE,
+			    {(char_u *)NULL, (char_u *)0L}
+#endif
+			    },
+    {"edcompatible","ed",   P_BOOL|P_VI_DEF,
+			    (char_u *)&p_ed, PV_NONE,
+			    {(char_u *)FALSE, (char_u *)0L}},
+    {"encoding",    "enc",  P_STRING|P_VI_DEF|P_RCLR,
+#ifdef FEAT_MBYTE
+			    (char_u *)&p_enc, PV_NONE,
+			    {(char_u *)ENC_DFLT, (char_u *)0L}
+#else
+			    (char_u *)NULL, PV_NONE,
+			    {(char_u *)0L, (char_u *)0L}
+#endif
+			    },
+    {"endofline",   "eol",  P_BOOL|P_NO_MKRC|P_VI_DEF|P_RSTAT,
+			    (char_u *)&p_eol, PV_EOL,
+			    {(char_u *)TRUE, (char_u *)0L}},
+    {"equalalways", "ea",   P_BOOL|P_VI_DEF|P_RALL,
+			    (char_u *)&p_ea, PV_NONE,
+			    {(char_u *)TRUE, (char_u *)0L}},
+    {"equalprg",    "ep",   P_STRING|P_EXPAND|P_VI_DEF|P_SECURE,
+			    (char_u *)&p_ep, PV_EP,
+			    {(char_u *)"", (char_u *)0L}},
+    {"errorbells",  "eb",   P_BOOL|P_VI_DEF,
+			    (char_u *)&p_eb, PV_NONE,
+			    {(char_u *)FALSE, (char_u *)0L}},
+    {"errorfile",   "ef",   P_STRING|P_EXPAND|P_VI_DEF|P_SECURE,
+#ifdef FEAT_QUICKFIX
+			    (char_u *)&p_ef, PV_NONE,
+			    {(char_u *)DFLT_ERRORFILE, (char_u *)0L}
+#else
+			    (char_u *)NULL, PV_NONE,
+			    {(char_u *)NULL, (char_u *)0L}
+#endif
+			    },
+    {"errorformat", "efm",  P_STRING|P_VI_DEF|P_COMMA|P_NODUP,
+#ifdef FEAT_QUICKFIX
+			    (char_u *)&p_efm, PV_EFM,
+			    {(char_u *)DFLT_EFM, (char_u *)0L},
+#else
+			    (char_u *)NULL, PV_NONE,
+			    {(char_u *)NULL, (char_u *)0L}
+#endif
+			    },
+    {"esckeys",	    "ek",   P_BOOL|P_VIM,
+			    (char_u *)&p_ek, PV_NONE,
+			    {(char_u *)FALSE, (char_u *)TRUE}},
+    {"eventignore", "ei",   P_STRING|P_VI_DEF|P_COMMA|P_NODUP,
+#ifdef FEAT_AUTOCMD
+			    (char_u *)&p_ei, PV_NONE,
+#else
+			    (char_u *)NULL, PV_NONE,
+#endif
+			    {(char_u *)"", (char_u *)0L}},
+    {"expandtab",   "et",   P_BOOL|P_VI_DEF|P_VIM,
+			    (char_u *)&p_et, PV_ET,
+			    {(char_u *)FALSE, (char_u *)0L}},
+    {"exrc",	    "ex",   P_BOOL|P_VI_DEF|P_SECURE,
+			    (char_u *)&p_exrc, PV_NONE,
+			    {(char_u *)FALSE, (char_u *)0L}},
+    {"fileencoding","fenc", P_STRING|P_ALLOCED|P_VI_DEF|P_RSTAT|P_RBUF|P_NO_MKRC,
+#ifdef FEAT_MBYTE
+			    (char_u *)&p_fenc, PV_FENC,
+			    {(char_u *)"", (char_u *)0L}
+#else
+			    (char_u *)NULL, PV_NONE,
+			    {(char_u *)0L, (char_u *)0L}
+#endif
+			    },
+    {"fileencodings","fencs", P_STRING|P_VI_DEF|P_COMMA,
+#ifdef FEAT_MBYTE
+			    (char_u *)&p_fencs, PV_NONE,
+			    {(char_u *)"ucs-bom", (char_u *)0L}
+#else
+			    (char_u *)NULL, PV_NONE,
+			    {(char_u *)0L, (char_u *)0L}
+#endif
+			    },
+    {"fileformat",  "ff",   P_STRING|P_ALLOCED|P_VI_DEF|P_RSTAT|P_NO_MKRC,
+			    (char_u *)&p_ff, PV_FF,
+			    {(char_u *)DFLT_FF, (char_u *)0L}},
+    {"fileformats", "ffs",  P_STRING|P_VIM|P_COMMA|P_NODUP,
+			    (char_u *)&p_ffs, PV_NONE,
+			    {(char_u *)DFLT_FFS_VI, (char_u *)DFLT_FFS_VIM}},
+    {"filetype",    "ft",   P_STRING|P_ALLOCED|P_VI_DEF|P_NOGLOB|P_NFNAME,
+#ifdef FEAT_AUTOCMD
+			    (char_u *)&p_ft, PV_FT,
+			    {(char_u *)"", (char_u *)0L}
+#else
+			    (char_u *)NULL, PV_NONE,
+			    {(char_u *)0L, (char_u *)0L}
+#endif
+			    },
+    {"fillchars",   "fcs",  P_STRING|P_VI_DEF|P_RALL|P_COMMA|P_NODUP,
+#if defined(FEAT_WINDOWS) || defined(FEAT_FOLDING)
+			    (char_u *)&p_fcs, PV_NONE,
+			    {(char_u *)"vert:|,fold:-", (char_u *)0L}
+#else
+			    (char_u *)NULL, PV_NONE,
+			    {(char_u *)"", (char_u *)0L}
+#endif
+			    },
+    {"fkmap",	    "fk",   P_BOOL|P_VI_DEF,
+#ifdef FEAT_FKMAP
+			    (char_u *)&p_fkmap, PV_NONE,
+#else
+			    (char_u *)NULL, PV_NONE,
+#endif
+			    {(char_u *)FALSE, (char_u *)0L}},
+    {"flash",	    "fl",   P_BOOL|P_VI_DEF,
+			    (char_u *)NULL, PV_NONE,
+			    {(char_u *)FALSE, (char_u *)0L}},
+#ifdef FEAT_FOLDING
+    {"foldclose",   "fcl",  P_STRING|P_VI_DEF|P_COMMA|P_NODUP|P_RWIN,
+			    (char_u *)&p_fcl, PV_NONE,
+			    {(char_u *)"", (char_u *)0L}},
+    {"foldcolumn",  "fdc",  P_NUM|P_VI_DEF|P_RWIN,
+			    (char_u *)VAR_WIN, PV_FDC,
+			    {(char_u *)FALSE, (char_u *)0L}},
+    {"foldenable",  "fen",  P_BOOL|P_VI_DEF|P_RWIN,
+			    (char_u *)VAR_WIN, PV_FEN,
+			    {(char_u *)TRUE, (char_u *)0L}},
+    {"foldexpr",    "fde",  P_STRING|P_ALLOCED|P_VIM|P_VI_DEF|P_RWIN,
+# ifdef FEAT_EVAL
+			    (char_u *)VAR_WIN, PV_FDE,
+			    {(char_u *)"0", (char_u *)NULL}
+# else
+			    (char_u *)NULL, PV_NONE,
+			    {(char_u *)NULL, (char_u *)0L}
+# endif
+			    },
+    {"foldignore",  "fdi",  P_STRING|P_ALLOCED|P_VIM|P_VI_DEF|P_RWIN,
+			    (char_u *)VAR_WIN, PV_FDI,
+			    {(char_u *)"#", (char_u *)NULL}},
+    {"foldlevel",   "fdl",  P_NUM|P_VI_DEF|P_RWIN,
+			    (char_u *)VAR_WIN, PV_FDL,
+			    {(char_u *)0L, (char_u *)0L}},
+    {"foldlevelstart","fdls", P_NUM|P_VI_DEF,
+			    (char_u *)&p_fdls, PV_NONE,
+			    {(char_u *)-1L, (char_u *)0L}},
+    {"foldmarker",  "fmr",  P_STRING|P_ALLOCED|P_VIM|P_VI_DEF|
+						       P_RWIN|P_COMMA|P_NODUP,
+			    (char_u *)VAR_WIN, PV_FMR,
+			    {(char_u *)"{{{,}}}", (char_u *)NULL}},
+    {"foldmethod",  "fdm",  P_STRING|P_ALLOCED|P_VIM|P_VI_DEF|P_RWIN,
+			    (char_u *)VAR_WIN, PV_FDM,
+			    {(char_u *)"manual", (char_u *)NULL}},
+    {"foldminlines","fml",  P_NUM|P_VI_DEF|P_RWIN,
+			    (char_u *)VAR_WIN, PV_FML,
+			    {(char_u *)1L, (char_u *)0L}},
+    {"foldnestmax", "fdn",  P_NUM|P_VI_DEF|P_RWIN,
+			    (char_u *)VAR_WIN, PV_FDN,
+			    {(char_u *)20L, (char_u *)0L}},
+    {"foldopen",    "fdo",  P_STRING|P_VI_DEF|P_COMMA|P_NODUP,
+			    (char_u *)&p_fdo, PV_NONE,
+		 {(char_u *)"block,hor,mark,percent,quickfix,search,tag,undo",
+							       (char_u *)0L}},
+    {"foldtext",    "fdt",  P_STRING|P_ALLOCED|P_VIM|P_VI_DEF|P_RWIN,
+# ifdef FEAT_EVAL
+			    (char_u *)VAR_WIN, PV_FDT,
+			    {(char_u *)"foldtext()", (char_u *)NULL}
+# else
+			    (char_u *)NULL, PV_NONE,
+			    {(char_u *)NULL, (char_u *)0L}
+# endif
+			    },
+#endif
+    {"formatexpr", "fex",   P_STRING|P_ALLOCED|P_VI_DEF|P_VIM,
+#ifdef FEAT_EVAL
+			    (char_u *)&p_fex, PV_FEX,
+			    {(char_u *)"", (char_u *)0L}
+#else
+			    (char_u *)NULL, PV_NONE,
+			    {(char_u *)0L, (char_u *)0L}
+#endif
+			    },
+    {"formatoptions","fo",  P_STRING|P_ALLOCED|P_VIM|P_FLAGLIST,
+			    (char_u *)&p_fo, PV_FO,
+			    {(char_u *)DFLT_FO_VI, (char_u *)DFLT_FO_VIM}},
+    {"formatlistpat","flp", P_STRING|P_ALLOCED|P_VI_DEF,
+			    (char_u *)&p_flp, PV_FLP,
+			    {(char_u *)"^\\s*\\d\\+[\\]:.)}\\t ]\\s*", (char_u *)0L}},
+    {"formatprg",   "fp",   P_STRING|P_EXPAND|P_VI_DEF|P_SECURE,
+			    (char_u *)&p_fp, PV_NONE,
+			    {(char_u *)"", (char_u *)0L}},
+    {"fsync",       "fs",   P_BOOL|P_SECURE|P_VI_DEF,
+#ifdef HAVE_FSYNC
+			    (char_u *)&p_fs, PV_NONE,
+			    {(char_u *)TRUE, (char_u *)0L}
+#else
+			    (char_u *)NULL, PV_NONE,
+			    {(char_u *)FALSE, (char_u *)0L}
+#endif
+			    },
+    {"gdefault",    "gd",   P_BOOL|P_VI_DEF|P_VIM,
+			    (char_u *)&p_gd, PV_NONE,
+			    {(char_u *)FALSE, (char_u *)0L}},
+    {"graphic",	    "gr",   P_BOOL|P_VI_DEF,
+			    (char_u *)NULL, PV_NONE,
+			    {(char_u *)FALSE, (char_u *)0L}},
+    {"grepformat",  "gfm",  P_STRING|P_VI_DEF|P_COMMA|P_NODUP,
+#ifdef FEAT_QUICKFIX
+			    (char_u *)&p_gefm, PV_NONE,
+			    {(char_u *)DFLT_GREPFORMAT, (char_u *)0L},
+#else
+			    (char_u *)NULL, PV_NONE,
+			    {(char_u *)NULL, (char_u *)0L}
+#endif
+			    },
+    {"grepprg",	    "gp",   P_STRING|P_EXPAND|P_VI_DEF|P_SECURE,
+#ifdef FEAT_QUICKFIX
+			    (char_u *)&p_gp, PV_GP,
+			    {
+# ifdef WIN3264
+			    /* may be changed to "grep -n" in os_win32.c */
+			    (char_u *)"findstr /n",
+# else
+#  ifdef UNIX
+			    /* Add an extra file name so that grep will always
+			     * insert a file name in the match line. */
+			    (char_u *)"grep -n $* /dev/null",
+#  else
+#   ifdef VMS
+			    (char_u *)"SEARCH/NUMBERS ",
+#   else
+			    (char_u *)"grep -n ",
+#endif
+#endif
+# endif
+			    (char_u *)0L},
+#else
+			    (char_u *)NULL, PV_NONE,
+			    {(char_u *)NULL, (char_u *)0L}
+#endif
+			    },
+    {"guicursor",    "gcr",  P_STRING|P_VI_DEF|P_COMMA|P_NODUP,
+#ifdef CURSOR_SHAPE
+			    (char_u *)&p_guicursor, PV_NONE,
+			    {
+# ifdef FEAT_GUI
+				(char_u *)"n-v-c:block-Cursor/lCursor,ve:ver35-Cursor,o:hor50-Cursor,i-ci:ver25-Cursor/lCursor,r-cr:hor20-Cursor/lCursor,sm:block-Cursor-blinkwait175-blinkoff150-blinkon175",
+# else	/* MSDOS or Win32 console */
+				(char_u *)"n-v-c:block,o:hor50,i-ci:hor15,r-cr:hor30,sm:block",
+# endif
+				    (char_u *)0L}
+#else
+			    (char_u *)NULL, PV_NONE,
+			    {(char_u *)NULL, (char_u *)0L}
+#endif
+				    },
+    {"guifont",	    "gfn",  P_STRING|P_VI_DEF|P_RCLR|P_COMMA|P_NODUP,
+#ifdef FEAT_GUI
+			    (char_u *)&p_guifont, PV_NONE,
+			    {(char_u *)"", (char_u *)0L}
+#else
+			    (char_u *)NULL, PV_NONE,
+			    {(char_u *)NULL, (char_u *)0L}
+#endif
+				    },
+    {"guifontset",  "gfs",  P_STRING|P_VI_DEF|P_RCLR|P_COMMA,
+#if defined(FEAT_GUI) && defined(FEAT_XFONTSET)
+			    (char_u *)&p_guifontset, PV_NONE,
+			    {(char_u *)"", (char_u *)0L}
+#else
+			    (char_u *)NULL, PV_NONE,
+			    {(char_u *)NULL, (char_u *)0L}
+#endif
+				    },
+    {"guifontwide", "gfw",  P_STRING|P_VI_DEF|P_RCLR|P_COMMA|P_NODUP,
+#if defined(FEAT_GUI) && defined(FEAT_MBYTE)
+			    (char_u *)&p_guifontwide, PV_NONE,
+			    {(char_u *)"", (char_u *)0L}
+#else
+			    (char_u *)NULL, PV_NONE,
+			    {(char_u *)NULL, (char_u *)0L}
+#endif
+				    },
+    {"guiheadroom", "ghr",  P_NUM|P_VI_DEF,
+#if defined(FEAT_GUI_GTK) || defined(FEAT_GUI_X11)
+			    (char_u *)&p_ghr, PV_NONE,
+#else
+			    (char_u *)NULL, PV_NONE,
+#endif
+			    {(char_u *)50L, (char_u *)0L}},
+    {"guioptions",  "go",   P_STRING|P_VI_DEF|P_RALL|P_FLAGLIST,
+#if defined(FEAT_GUI)
+			    (char_u *)&p_go, PV_NONE,
+# if defined(UNIX) && !defined(MACOS)
+			    {(char_u *)"aegimrLtT", (char_u *)0L}
+# else
+			    {(char_u *)"egmrLtT", (char_u *)0L}
+# endif
+#else
+			    (char_u *)NULL, PV_NONE,
+			    {(char_u *)NULL, (char_u *)0L}
+#endif
+				    },
+    {"guipty",	    NULL,   P_BOOL|P_VI_DEF,
+#if defined(FEAT_GUI)
+			    (char_u *)&p_guipty, PV_NONE,
+#else
+			    (char_u *)NULL, PV_NONE,
+#endif
+			    {(char_u *)TRUE, (char_u *)0L}},
+    {"guitablabel",  "gtl", P_STRING|P_VI_DEF|P_RWIN,
+#if defined(FEAT_GUI_TABLINE)
+			    (char_u *)&p_gtl, PV_NONE,
+			    {(char_u *)"", (char_u *)0L}
+#else
+			    (char_u *)NULL, PV_NONE,
+			    {(char_u *)NULL, (char_u *)0L}
+#endif
+				    },
+    {"guitabtooltip",  "gtt", P_STRING|P_VI_DEF|P_RWIN,
+#if defined(FEAT_GUI_TABLINE)
+			    (char_u *)&p_gtt, PV_NONE,
+			    {(char_u *)"", (char_u *)0L}
+#else
+			    (char_u *)NULL, PV_NONE,
+			    {(char_u *)NULL, (char_u *)0L}
+#endif
+				    },
+    {"hardtabs",    "ht",   P_NUM|P_VI_DEF,
+			    (char_u *)NULL, PV_NONE,
+			    {(char_u *)0L, (char_u *)0L}},
+    {"helpfile",    "hf",   P_STRING|P_EXPAND|P_VI_DEF|P_SECURE,
+			    (char_u *)&p_hf, PV_NONE,
+			    {(char_u *)DFLT_HELPFILE, (char_u *)0L}},
+    {"helpheight",  "hh",   P_NUM|P_VI_DEF,
+#ifdef FEAT_WINDOWS
+			    (char_u *)&p_hh, PV_NONE,
+#else
+			    (char_u *)NULL, PV_NONE,
+#endif
+			    {(char_u *)20L, (char_u *)0L}},
+    {"helplang",    "hlg",  P_STRING|P_VI_DEF|P_COMMA,
+#ifdef FEAT_MULTI_LANG
+			    (char_u *)&p_hlg, PV_NONE,
+			    {(char_u *)"", (char_u *)0L}
+#else
+			    (char_u *)NULL, PV_NONE,
+			    {(char_u *)0L, (char_u *)0L}
+#endif
+    },
+    {"hidden",	    "hid",  P_BOOL|P_VI_DEF,
+			    (char_u *)&p_hid, PV_NONE,
+			    {(char_u *)FALSE, (char_u *)0L}},
+    {"highlight",   "hl",   P_STRING|P_VI_DEF|P_RCLR|P_COMMA|P_NODUP,
+			    (char_u *)&p_hl, PV_NONE,
+			    {(char_u *)HIGHLIGHT_INIT, (char_u *)0L}},
+    {"history",	    "hi",   P_NUM|P_VIM,
+			    (char_u *)&p_hi, PV_NONE,
+			    {(char_u *)0L, (char_u *)20L}},
+    {"hkmap",	    "hk",   P_BOOL|P_VI_DEF|P_VIM,
+#ifdef FEAT_RIGHTLEFT
+			    (char_u *)&p_hkmap, PV_NONE,
+#else
+			    (char_u *)NULL, PV_NONE,
+#endif
+			    {(char_u *)FALSE, (char_u *)0L}},
+    {"hkmapp",	    "hkp",  P_BOOL|P_VI_DEF|P_VIM,
+#ifdef FEAT_RIGHTLEFT
+			    (char_u *)&p_hkmapp, PV_NONE,
+#else
+			    (char_u *)NULL, PV_NONE,
+#endif
+			    {(char_u *)FALSE, (char_u *)0L}},
+    {"hlsearch",    "hls",  P_BOOL|P_VI_DEF|P_VIM|P_RALL,
+			    (char_u *)&p_hls, PV_NONE,
+			    {(char_u *)FALSE, (char_u *)0L}},
+    {"icon",	    NULL,   P_BOOL|P_VI_DEF,
+#ifdef FEAT_TITLE
+			    (char_u *)&p_icon, PV_NONE,
+#else
+			    (char_u *)NULL, PV_NONE,
+#endif
+			    {(char_u *)FALSE, (char_u *)0L}},
+    {"iconstring",  NULL,   P_STRING|P_VI_DEF,
+#ifdef FEAT_TITLE
+			    (char_u *)&p_iconstring, PV_NONE,
+#else
+			    (char_u *)NULL, PV_NONE,
+#endif
+			    {(char_u *)"", (char_u *)0L}},
+    {"ignorecase",  "ic",   P_BOOL|P_VI_DEF,
+			    (char_u *)&p_ic, PV_NONE,
+			    {(char_u *)FALSE, (char_u *)0L}},
+    {"imactivatekey","imak",P_STRING|P_VI_DEF,
+#if defined(FEAT_XIM) && defined(FEAT_GUI_GTK)
+			    (char_u *)&p_imak, PV_NONE,
+#else
+			    (char_u *)NULL, PV_NONE,
+#endif
+			    {(char_u *)"", (char_u *)0L}},
+    {"imcmdline",   "imc",  P_BOOL|P_VI_DEF,
+#ifdef USE_IM_CONTROL
+			    (char_u *)&p_imcmdline, PV_NONE,
+#else
+			    (char_u *)NULL, PV_NONE,
+#endif
+			    {(char_u *)FALSE, (char_u *)0L}},
+    {"imdisable",   "imd",  P_BOOL|P_VI_DEF,
+#ifdef USE_IM_CONTROL
+			    (char_u *)&p_imdisable, PV_NONE,
+#else
+			    (char_u *)NULL, PV_NONE,
+#endif
+#ifdef __sgi
+			    {(char_u *)TRUE, (char_u *)0L}
+#else
+			    {(char_u *)FALSE, (char_u *)0L}
+#endif
+			    },
+    {"iminsert",    "imi",  P_NUM|P_VI_DEF,
+			    (char_u *)&p_iminsert, PV_IMI,
+#ifdef B_IMODE_IM
+			    {(char_u *)B_IMODE_IM, (char_u *)0L}
+#else
+			    {(char_u *)B_IMODE_NONE, (char_u *)0L}
+#endif
+			    },
+    {"imsearch",    "ims",  P_NUM|P_VI_DEF,
+			    (char_u *)&p_imsearch, PV_IMS,
+#ifdef B_IMODE_IM
+			    {(char_u *)B_IMODE_IM, (char_u *)0L}
+#else
+			    {(char_u *)B_IMODE_NONE, (char_u *)0L}
+#endif
+			    },
+    {"include",	    "inc",  P_STRING|P_ALLOCED|P_VI_DEF,
+#ifdef FEAT_FIND_ID
+			    (char_u *)&p_inc, PV_INC,
+			    {(char_u *)"^\\s*#\\s*include", (char_u *)0L}
+#else
+			    (char_u *)NULL, PV_NONE,
+			    {(char_u *)0L, (char_u *)0L}
+#endif
+			    },
+    {"includeexpr", "inex", P_STRING|P_ALLOCED|P_VI_DEF,
+#if defined(FEAT_FIND_ID) && defined(FEAT_EVAL)
+			    (char_u *)&p_inex, PV_INEX,
+			    {(char_u *)"", (char_u *)0L}
+#else
+			    (char_u *)NULL, PV_NONE,
+			    {(char_u *)0L, (char_u *)0L}
+#endif
+			    },
+    {"incsearch",   "is",   P_BOOL|P_VI_DEF|P_VIM,
+			    (char_u *)&p_is, PV_NONE,
+			    {(char_u *)FALSE, (char_u *)0L}},
+    {"indentexpr", "inde",  P_STRING|P_ALLOCED|P_VI_DEF|P_VIM,
+#if defined(FEAT_CINDENT) && defined(FEAT_EVAL)
+			    (char_u *)&p_inde, PV_INDE,
+			    {(char_u *)"", (char_u *)0L}
+#else
+			    (char_u *)NULL, PV_NONE,
+			    {(char_u *)0L, (char_u *)0L}
+#endif
+			    },
+    {"indentkeys", "indk",  P_STRING|P_ALLOCED|P_VI_DEF|P_COMMA|P_NODUP,
+#if defined(FEAT_CINDENT) && defined(FEAT_EVAL)
+			    (char_u *)&p_indk, PV_INDK,
+			    {(char_u *)"0{,0},:,0#,!^F,o,O,e", (char_u *)0L}
+#else
+			    (char_u *)NULL, PV_NONE,
+			    {(char_u *)0L, (char_u *)0L}
+#endif
+			    },
+    {"infercase",   "inf",  P_BOOL|P_VI_DEF,
+			    (char_u *)&p_inf, PV_INF,
+			    {(char_u *)FALSE, (char_u *)0L}},
+    {"insertmode",  "im",   P_BOOL|P_VI_DEF|P_VIM,
+			    (char_u *)&p_im, PV_NONE,
+			    {(char_u *)FALSE, (char_u *)0L}},
+    {"isfname",	    "isf",  P_STRING|P_VI_DEF|P_COMMA|P_NODUP,
+			    (char_u *)&p_isf, PV_NONE,
+			    {
+#ifdef BACKSLASH_IN_FILENAME
+				/* Excluded are: & and ^ are special in cmd.exe
+				 * ( and ) are used in text separating fnames */
+			    (char_u *)"@,48-57,/,\\,.,-,_,+,,,#,$,%,{,},[,],:,@-@,!,~,=",
+#else
+# ifdef AMIGA
+			    (char_u *)"@,48-57,/,.,-,_,+,,,$,:",
+# else
+#  ifdef VMS
+			    (char_u *)"@,48-57,/,.,-,_,+,,,#,$,%,<,>,[,],:,;,~",
+#  else /* UNIX et al. */
+#   ifdef EBCDIC
+			    (char_u *)"@,240-249,/,.,-,_,+,,,#,$,%,~,=",
+#   else
+			    (char_u *)"@,48-57,/,.,-,_,+,,,#,$,%,~,=",
+#   endif
+#  endif
+# endif
+#endif
+				(char_u *)0L}},
+    {"isident",	    "isi",  P_STRING|P_VI_DEF|P_COMMA|P_NODUP,
+			    (char_u *)&p_isi, PV_NONE,
+			    {
+#if defined(MSDOS) || defined(MSWIN) || defined(OS2)
+			    (char_u *)"@,48-57,_,128-167,224-235",
+#else
+# ifdef EBCDIC
+			    /* TODO: EBCDIC Check this! @ == isalpha()*/
+			    (char_u *)"@,240-249,_,66-73,81-89,98-105,"
+				    "112-120,128,140-142,156,158,172,"
+				    "174,186,191,203-207,219-225,235-239,"
+				    "251-254",
+# else
+			    (char_u *)"@,48-57,_,192-255",
+# endif
+#endif
+				(char_u *)0L}},
+    {"iskeyword",   "isk",  P_STRING|P_ALLOCED|P_VIM|P_COMMA|P_NODUP,
+			    (char_u *)&p_isk, PV_ISK,
+			    {
+#ifdef EBCDIC
+			     (char_u *)"@,240-249,_",
+			     /* TODO: EBCDIC Check this! @ == isalpha()*/
+			     (char_u *)"@,240-249,_,66-73,81-89,98-105,"
+				    "112-120,128,140-142,156,158,172,"
+				    "174,186,191,203-207,219-225,235-239,"
+				    "251-254",
+#else
+				(char_u *)"@,48-57,_",
+# if defined(MSDOS) || defined(MSWIN) || defined(OS2)
+				(char_u *)"@,48-57,_,128-167,224-235"
+# else
+				ISK_LATIN1
+# endif
+#endif
+				}},
+    {"isprint",	    "isp",  P_STRING|P_VI_DEF|P_RALL|P_COMMA|P_NODUP,
+			    (char_u *)&p_isp, PV_NONE,
+			    {
+#if defined(MSDOS) || defined(MSWIN) || defined(OS2) \
+		|| (defined(MACOS) && !defined(MACOS_X)) \
+		|| defined(VMS)
+			    (char_u *)"@,~-255",
+#else
+# ifdef EBCDIC
+			    /* all chars above 63 are printable */
+			    (char_u *)"63-255",
+# else
+			    ISP_LATIN1,
+# endif
+#endif
+				(char_u *)0L}},
+    {"joinspaces",  "js",   P_BOOL|P_VI_DEF|P_VIM,
+			    (char_u *)&p_js, PV_NONE,
+			    {(char_u *)TRUE, (char_u *)0L}},
+    {"key",	    NULL,   P_STRING|P_ALLOCED|P_VI_DEF|P_NO_MKRC,
+#ifdef FEAT_CRYPT
+			    (char_u *)&p_key, PV_KEY,
+			    {(char_u *)"", (char_u *)0L}
+#else
+			    (char_u *)NULL, PV_NONE,
+			    {(char_u *)0L, (char_u *)0L}
+#endif
+			    },
+    {"keymap",	    "kmp",  P_STRING|P_ALLOCED|P_VI_DEF|P_RBUF|P_RSTAT|P_NFNAME,
+#ifdef FEAT_KEYMAP
+			    (char_u *)&p_keymap, PV_KMAP,
+			    {(char_u *)"", (char_u *)0L}
+#else
+			    (char_u *)NULL, PV_NONE,
+			    {(char_u *)"", (char_u *)0L}
+#endif
+	},
+    {"keymodel",    "km",   P_STRING|P_VI_DEF|P_COMMA|P_NODUP,
+#ifdef FEAT_VISUAL
+			    (char_u *)&p_km, PV_NONE,
+#else
+			    (char_u *)NULL, PV_NONE,
+#endif
+			    {(char_u *)"", (char_u *)0L}},
+    {"keywordprg",  "kp",   P_STRING|P_EXPAND|P_VI_DEF|P_SECURE,
+			    (char_u *)&p_kp, PV_KP,
+			    {
+#if defined(MSDOS) || defined(MSWIN)
+			    (char_u *)":help",
+#else
+#ifdef VMS
+			    (char_u *)"help",
+#else
+# if defined(OS2)
+			    (char_u *)"view /",
+# else
+#  ifdef USEMAN_S
+			    (char_u *)"man -s",
+#  else
+			    (char_u *)"man",
+#  endif
+# endif
+#endif
+#endif
+				(char_u *)0L}},
+    {"langmap",     "lmap", P_STRING|P_VI_DEF|P_COMMA|P_NODUP,
+#ifdef FEAT_LANGMAP
+			    (char_u *)&p_langmap, PV_NONE,
+			    {(char_u *)"",	/* unmatched } */
+#else
+			    (char_u *)NULL, PV_NONE,
+			    {(char_u *)NULL,
+#endif
+				(char_u *)0L}},
+    {"langmenu",    "lm",   P_STRING|P_VI_DEF|P_NFNAME,
+#if defined(FEAT_MENU) && defined(FEAT_MULTI_LANG)
+			    (char_u *)&p_lm, PV_NONE,
+#else
+			    (char_u *)NULL, PV_NONE,
+#endif
+			    {(char_u *)"", (char_u *)0L}},
+    {"laststatus",  "ls",   P_NUM|P_VI_DEF|P_RALL,
+#ifdef FEAT_WINDOWS
+			    (char_u *)&p_ls, PV_NONE,
+#else
+			    (char_u *)NULL, PV_NONE,
+#endif
+			    {(char_u *)1L, (char_u *)0L}},
+    {"lazyredraw",  "lz",   P_BOOL|P_VI_DEF,
+			    (char_u *)&p_lz, PV_NONE,
+			    {(char_u *)FALSE, (char_u *)0L}},
+    {"linebreak",   "lbr",  P_BOOL|P_VI_DEF|P_RWIN,
+#ifdef FEAT_LINEBREAK
+			    (char_u *)VAR_WIN, PV_LBR,
+#else
+			    (char_u *)NULL, PV_NONE,
+#endif
+			    {(char_u *)FALSE, (char_u *)0L}},
+    {"lines",	    NULL,   P_NUM|P_NODEFAULT|P_NO_MKRC|P_VI_DEF|P_RCLR,
+			    (char_u *)&Rows, PV_NONE,
+			    {
+#if defined(MSDOS) || defined(WIN3264) || defined(OS2)
+			    (char_u *)25L,
+#else
+			    (char_u *)24L,
+#endif
+					    (char_u *)0L}},
+    {"linespace",   "lsp",  P_NUM|P_VI_DEF|P_RCLR,
+#ifdef FEAT_GUI
+			    (char_u *)&p_linespace, PV_NONE,
+#else
+			    (char_u *)NULL, PV_NONE,
+#endif
+#ifdef FEAT_GUI_W32
+			    {(char_u *)1L, (char_u *)0L}
+#else
+			    {(char_u *)0L, (char_u *)0L}
+#endif
+			    },
+    {"lisp",	    NULL,   P_BOOL|P_VI_DEF,
+#ifdef FEAT_LISP
+			    (char_u *)&p_lisp, PV_LISP,
+#else
+			    (char_u *)NULL, PV_NONE,
+#endif
+			    {(char_u *)FALSE, (char_u *)0L}},
+    {"lispwords",   "lw",   P_STRING|P_VI_DEF|P_COMMA|P_NODUP,
+#ifdef FEAT_LISP
+			    (char_u *)&p_lispwords, PV_NONE,
+			    {(char_u *)LISPWORD_VALUE, (char_u *)0L}
+#else
+			    (char_u *)NULL, PV_NONE,
+			    {(char_u *)"", (char_u *)0L}
+#endif
+			    },
+    {"list",	    NULL,   P_BOOL|P_VI_DEF|P_RWIN,
+			    (char_u *)VAR_WIN, PV_LIST,
+			    {(char_u *)FALSE, (char_u *)0L}},
+    {"listchars",   "lcs",  P_STRING|P_VI_DEF|P_RALL|P_COMMA|P_NODUP,
+			    (char_u *)&p_lcs, PV_NONE,
+			    {(char_u *)"eol:$", (char_u *)0L}},
+    {"loadplugins", "lpl",  P_BOOL|P_VI_DEF,
+			    (char_u *)&p_lpl, PV_NONE,
+			    {(char_u *)TRUE, (char_u *)0L}},
+#ifdef FEAT_GUI_MAC
+    {"macatsui",    NULL,   P_BOOL|P_VI_DEF|P_RCLR,
+			    (char_u *)&p_macatsui, PV_NONE,
+			    {(char_u *)TRUE, (char_u *)0L}},
+#endif
+    {"magic",	    NULL,   P_BOOL|P_VI_DEF,
+			    (char_u *)&p_magic, PV_NONE,
+			    {(char_u *)TRUE, (char_u *)0L}},
+    {"makeef",	    "mef",  P_STRING|P_EXPAND|P_VI_DEF|P_SECURE,
+#ifdef FEAT_QUICKFIX
+			    (char_u *)&p_mef, PV_NONE,
+			    {(char_u *)"", (char_u *)0L}
+#else
+			    (char_u *)NULL, PV_NONE,
+			    {(char_u *)NULL, (char_u *)0L}
+#endif
+			    },
+    {"makeprg",	    "mp",   P_STRING|P_EXPAND|P_VI_DEF|P_SECURE,
+#ifdef FEAT_QUICKFIX
+			    (char_u *)&p_mp, PV_MP,
+# if defined(VMS)
+			    {(char_u *)"MMS", (char_u *)0L}
+# elif defined(PLAN9)
+			    {(char_u *)"mk", (char_u *)0L}
+# else
+			    {(char_u *)"make", (char_u *)0L}
+# endif
+#else
+			    (char_u *)NULL, PV_NONE,
+			    {(char_u *)NULL, (char_u *)0L}
+#endif
+			    },
+    {"matchpairs",  "mps",  P_STRING|P_ALLOCED|P_VI_DEF|P_COMMA|P_NODUP,
+			    (char_u *)&p_mps, PV_MPS,
+			    {(char_u *)"(:),{:},[:]", (char_u *)0L}},
+    {"matchtime",   "mat",  P_NUM|P_VI_DEF,
+			    (char_u *)&p_mat, PV_NONE,
+			    {(char_u *)5L, (char_u *)0L}},
+    {"maxcombine",  "mco",  P_NUM|P_VI_DEF,
+#ifdef FEAT_MBYTE
+			    (char_u *)&p_mco, PV_NONE,
+#else
+			    (char_u *)NULL, PV_NONE,
+#endif
+			    {(char_u *)2, (char_u *)0L}},
+    {"maxfuncdepth", "mfd", P_NUM|P_VI_DEF,
+#ifdef FEAT_EVAL
+			    (char_u *)&p_mfd, PV_NONE,
+#else
+			    (char_u *)NULL, PV_NONE,
+#endif
+			    {(char_u *)100L, (char_u *)0L}},
+    {"maxmapdepth", "mmd",  P_NUM|P_VI_DEF,
+			    (char_u *)&p_mmd, PV_NONE,
+			    {(char_u *)1000L, (char_u *)0L}},
+    {"maxmem",	    "mm",   P_NUM|P_VI_DEF,
+			    (char_u *)&p_mm, PV_NONE,
+			    {(char_u *)DFLT_MAXMEM, (char_u *)0L}},
+    {"maxmempattern","mmp", P_NUM|P_VI_DEF,
+			    (char_u *)&p_mmp, PV_NONE,
+			    {(char_u *)1000L, (char_u *)0L}},
+    {"maxmemtot",   "mmt",  P_NUM|P_VI_DEF,
+			    (char_u *)&p_mmt, PV_NONE,
+			    {(char_u *)DFLT_MAXMEMTOT, (char_u *)0L}},
+    {"menuitems",   "mis",  P_NUM|P_VI_DEF,
+#ifdef FEAT_MENU
+			    (char_u *)&p_mis, PV_NONE,
+#else
+			    (char_u *)NULL, PV_NONE,
+#endif
+			    {(char_u *)25L, (char_u *)0L}},
+    {"mesg",	    NULL,   P_BOOL|P_VI_DEF,
+			    (char_u *)NULL, PV_NONE,
+			    {(char_u *)FALSE, (char_u *)0L}},
+    {"mkspellmem",  "msm",  P_STRING|P_VI_DEF|P_EXPAND|P_SECURE,
+#ifdef FEAT_SPELL
+			    (char_u *)&p_msm, PV_NONE,
+			    {(char_u *)"460000,2000,500", (char_u *)0L}
+#else
+			    (char_u *)NULL, PV_NONE,
+			    {(char_u *)0L, (char_u *)0L}
+#endif
+    },
+    {"modeline",    "ml",   P_BOOL|P_VIM,
+			    (char_u *)&p_ml, PV_ML,
+			    {(char_u *)FALSE, (char_u *)TRUE}},
+    {"modelines",   "mls",  P_NUM|P_VI_DEF,
+			    (char_u *)&p_mls, PV_NONE,
+			    {(char_u *)5L, (char_u *)0L}},
+    {"modifiable",  "ma",   P_BOOL|P_VI_DEF|P_NOGLOB,
+			    (char_u *)&p_ma, PV_MA,
+			    {(char_u *)TRUE, (char_u *)0L}},
+    {"modified",    "mod",  P_BOOL|P_NO_MKRC|P_VI_DEF|P_RSTAT,
+			    (char_u *)&p_mod, PV_MOD,
+			    {(char_u *)FALSE, (char_u *)0L}},
+    {"more",	    NULL,   P_BOOL|P_VIM,
+			    (char_u *)&p_more, PV_NONE,
+			    {(char_u *)FALSE, (char_u *)TRUE}},
+    {"mouse",	    NULL,   P_STRING|P_VI_DEF|P_FLAGLIST,
+			    (char_u *)&p_mouse, PV_NONE,
+			    {
+#if defined(MSDOS) || defined(WIN3264)
+				(char_u *)"a",
+#else
+				(char_u *)"",
+#endif
+				(char_u *)0L}},
+    {"mousefocus",   "mousef", P_BOOL|P_VI_DEF,
+#ifdef FEAT_GUI
+			    (char_u *)&p_mousef, PV_NONE,
+#else
+			    (char_u *)NULL, PV_NONE,
+#endif
+			    {(char_u *)FALSE, (char_u *)0L}},
+    {"mousehide",   "mh",   P_BOOL|P_VI_DEF,
+#ifdef FEAT_GUI
+			    (char_u *)&p_mh, PV_NONE,
+#else
+			    (char_u *)NULL, PV_NONE,
+#endif
+			    {(char_u *)TRUE, (char_u *)0L}},
+    {"mousemodel",  "mousem", P_STRING|P_VI_DEF,
+			    (char_u *)&p_mousem, PV_NONE,
+			    {
+#if defined(MSDOS) || defined(MSWIN)
+				(char_u *)"popup",
+#else
+# if defined(MACOS)
+				(char_u *)"popup_setpos",
+# else
+				(char_u *)"extend",
+# endif
+#endif
+				(char_u *)0L}},
+    {"mouseshape",  "mouses",  P_STRING|P_VI_DEF|P_COMMA|P_NODUP,
+#ifdef FEAT_MOUSESHAPE
+			    (char_u *)&p_mouseshape, PV_NONE,
+			    {(char_u *)"i-r:beam,s:updown,sd:udsizing,vs:leftright,vd:lrsizing,m:no,ml:up-arrow,v:rightup-arrow", (char_u *)0L}
+#else
+			    (char_u *)NULL, PV_NONE,
+			    {(char_u *)NULL, (char_u *)0L}
+#endif
+			    },
+    {"mousetime",   "mouset",	P_NUM|P_VI_DEF,
+			    (char_u *)&p_mouset, PV_NONE,
+			    {(char_u *)500L, (char_u *)0L}},
+    {"mzquantum",  "mzq",   P_NUM,
+#ifdef FEAT_MZSCHEME
+			    (char_u *)&p_mzq, PV_NONE,
+#else
+			    (char_u *)NULL, PV_NONE,
+#endif
+			    {(char_u *)100L, (char_u *)100L}},
+    {"novice",	    NULL,   P_BOOL|P_VI_DEF,
+			    (char_u *)NULL, PV_NONE,
+			    {(char_u *)FALSE, (char_u *)0L}},
+    {"nrformats",   "nf",   P_STRING|P_ALLOCED|P_VI_DEF|P_COMMA|P_NODUP,
+			    (char_u *)&p_nf, PV_NF,
+			    {(char_u *)"octal,hex", (char_u *)0L}},
+    {"number",	    "nu",   P_BOOL|P_VI_DEF|P_RWIN,
+			    (char_u *)VAR_WIN, PV_NU,
+			    {(char_u *)FALSE, (char_u *)0L}},
+    {"numberwidth", "nuw",  P_NUM|P_RWIN|P_VIM,
+#ifdef FEAT_LINEBREAK
+			    (char_u *)VAR_WIN, PV_NUW,
+#else
+			    (char_u *)NULL, PV_NONE,
+#endif
+			    {(char_u *)8L, (char_u *)4L}},
+    {"omnifunc",    "ofu",  P_STRING|P_ALLOCED|P_VI_DEF|P_SECURE,
+#ifdef FEAT_COMPL_FUNC
+			    (char_u *)&p_ofu, PV_OFU,
+			    {(char_u *)"", (char_u *)0L}
+#else
+			    (char_u *)NULL, PV_NONE,
+			    {(char_u *)0L, (char_u *)0L}
+#endif
+			    },
+    {"open",	    NULL,   P_BOOL|P_VI_DEF,
+			    (char_u *)NULL, PV_NONE,
+			    {(char_u *)FALSE, (char_u *)0L}},
+    {"opendevice",  "odev", P_BOOL|P_VI_DEF,
+#if defined(MSDOS) || defined(MSWIN) || defined(OS2)
+			    (char_u *)&p_odev, PV_NONE,
+#else
+			    (char_u *)NULL, PV_NONE,
+#endif
+			    {(char_u *)FALSE, (char_u *)FALSE}
+			    },
+    {"operatorfunc", "opfunc", P_STRING|P_VI_DEF|P_SECURE,
+			    (char_u *)&p_opfunc, PV_NONE,
+			    {(char_u *)"", (char_u *)0L} },
+    {"optimize",    "opt",  P_BOOL|P_VI_DEF,
+			    (char_u *)NULL, PV_NONE,
+			    {(char_u *)FALSE, (char_u *)0L}},
+    {"osfiletype",  "oft",  P_STRING|P_ALLOCED|P_VI_DEF,
+#ifdef FEAT_OSFILETYPE
+			    (char_u *)&p_oft, PV_OFT,
+			    {(char_u *)DFLT_OFT, (char_u *)0L}
+#else
+			    (char_u *)NULL, PV_NONE,
+			    {(char_u *)0L, (char_u *)0L}
+#endif
+			    },
+    {"paragraphs",  "para", P_STRING|P_VI_DEF,
+			    (char_u *)&p_para, PV_NONE,
+			    {(char_u *)"IPLPPPQPP LIpplpipbp", (char_u *)0L}},
+    {"paste",	    NULL,   P_BOOL|P_VI_DEF,
+			    (char_u *)&p_paste, PV_NONE,
+			    {(char_u *)FALSE, (char_u *)0L}},
+    {"pastetoggle", "pt",   P_STRING|P_VI_DEF,
+			    (char_u *)&p_pt, PV_NONE,
+			    {(char_u *)"", (char_u *)0L}},
+    {"patchexpr",   "pex",  P_STRING|P_VI_DEF|P_SECURE,
+#if defined(FEAT_DIFF) && defined(FEAT_EVAL)
+			    (char_u *)&p_pex, PV_NONE,
+			    {(char_u *)"", (char_u *)0L}
+#else
+			    (char_u *)NULL, PV_NONE,
+			    {(char_u *)0L, (char_u *)0L}
+#endif
+			    },
+    {"patchmode",   "pm",   P_STRING|P_VI_DEF|P_NFNAME,
+			    (char_u *)&p_pm, PV_NONE,
+			    {(char_u *)"", (char_u *)0L}},
+    {"path",	    "pa",   P_STRING|P_EXPAND|P_VI_DEF|P_COMMA|P_NODUP,
+			    (char_u *)&p_path, PV_PATH,
+			    {
+#if defined AMIGA || defined MSDOS || defined MSWIN
+			    (char_u *)".,,",
+#else
+# if defined(__EMX__)
+			    (char_u *)".,/emx/include,,",
+# else /* Unix, probably */
+			    (char_u *)".,/usr/include,,",
+# endif
+#endif
+				(char_u *)0L}},
+    {"preserveindent", "pi", P_BOOL|P_VI_DEF|P_VIM,
+			    (char_u *)&p_pi, PV_PI,
+			    {(char_u *)FALSE, (char_u *)0L}},
+    {"previewheight", "pvh", P_NUM|P_VI_DEF,
+#if defined(FEAT_WINDOWS) && defined(FEAT_QUICKFIX)
+			    (char_u *)&p_pvh, PV_NONE,
+#else
+			    (char_u *)NULL, PV_NONE,
+#endif
+			    {(char_u *)12L, (char_u *)0L}},
+    {"previewwindow", "pvw", P_BOOL|P_VI_DEF|P_RSTAT|P_NOGLOB,
+#if defined(FEAT_WINDOWS) && defined(FEAT_QUICKFIX)
+			    (char_u *)VAR_WIN, PV_PVW,
+#else
+			    (char_u *)NULL, PV_NONE,
+#endif
+			    {(char_u *)FALSE, (char_u *)0L}},
+    {"printdevice", "pdev", P_STRING|P_VI_DEF|P_SECURE,
+#ifdef FEAT_PRINTER
+			    (char_u *)&p_pdev, PV_NONE,
+			    {(char_u *)"", (char_u *)0L}
+#else
+			    (char_u *)NULL, PV_NONE,
+			    {(char_u *)NULL, (char_u *)0L}
+#endif
+			    },
+    {"printencoding", "penc", P_STRING|P_VI_DEF,
+#ifdef FEAT_POSTSCRIPT
+			    (char_u *)&p_penc, PV_NONE,
+			    {(char_u *)"", (char_u *)0L}
+#else
+			    (char_u *)NULL, PV_NONE,
+			    {(char_u *)NULL, (char_u *)0L}
+#endif
+			    },
+    {"printexpr", "pexpr",  P_STRING|P_VI_DEF,
+#ifdef FEAT_POSTSCRIPT
+			    (char_u *)&p_pexpr, PV_NONE,
+			    {(char_u *)"", (char_u *)0L}
+#else
+			    (char_u *)NULL, PV_NONE,
+			    {(char_u *)NULL, (char_u *)0L}
+#endif
+			    },
+    {"printfont", "pfn",    P_STRING|P_VI_DEF,
+#ifdef FEAT_PRINTER
+			    (char_u *)&p_pfn, PV_NONE,
+			    {
+# ifdef MSWIN
+				(char_u *)"Courier_New:h10",
+# else
+				(char_u *)"courier",
+# endif
+				(char_u *)0L}
+#else
+			    (char_u *)NULL, PV_NONE,
+			    {(char_u *)NULL, (char_u *)0L}
+#endif
+			    },
+    {"printheader", "pheader",  P_STRING|P_VI_DEF|P_GETTEXT,
+#ifdef FEAT_PRINTER
+			    (char_u *)&p_header, PV_NONE,
+			    {(char_u *)N_("%<%f%h%m%=Page %N"), (char_u *)0L}
+#else
+			    (char_u *)NULL, PV_NONE,
+			    {(char_u *)NULL, (char_u *)0L}
+#endif
+			    },
+   {"printmbcharset", "pmbcs",  P_STRING|P_VI_DEF,
+#if defined(FEAT_POSTSCRIPT) && defined(FEAT_MBYTE)
+			    (char_u *)&p_pmcs, PV_NONE,
+			    {(char_u *)"", (char_u *)0L}
+#else
+			    (char_u *)NULL, PV_NONE,
+			    {(char_u *)NULL, (char_u *)0L}
+#endif
+			    },
+    {"printmbfont", "pmbfn",  P_STRING|P_VI_DEF,
+#if defined(FEAT_POSTSCRIPT) && defined(FEAT_MBYTE)
+			    (char_u *)&p_pmfn, PV_NONE,
+			    {(char_u *)"", (char_u *)0L}
+#else
+			    (char_u *)NULL, PV_NONE,
+			    {(char_u *)NULL, (char_u *)0L}
+#endif
+			    },
+    {"printoptions", "popt", P_STRING|P_VI_DEF|P_COMMA|P_NODUP,
+#ifdef FEAT_PRINTER
+			    (char_u *)&p_popt, PV_NONE,
+			    {(char_u *)"", (char_u *)0L}
+#else
+			    (char_u *)NULL, PV_NONE,
+			    {(char_u *)NULL, (char_u *)0L}
+#endif
+			    },
+    {"prompt",	    NULL,   P_BOOL|P_VI_DEF,
+			    (char_u *)&p_prompt, PV_NONE,
+			    {(char_u *)TRUE, (char_u *)0L}},
+    {"pumheight",   "ph",   P_NUM|P_VI_DEF,
+#ifdef FEAT_INS_EXPAND
+			    (char_u *)&p_ph, PV_NONE,
+#else
+			    (char_u *)NULL, PV_NONE,
+#endif
+			    {(char_u *)0L, (char_u *)0L}},
+    {"quoteescape", "qe",   P_STRING|P_ALLOCED|P_VI_DEF,
+#ifdef FEAT_TEXTOBJ
+			    (char_u *)&p_qe, PV_QE,
+			    {(char_u *)"\\", (char_u *)0L}
+#else
+			    (char_u *)NULL, PV_NONE,
+			    {(char_u *)NULL, (char_u *)0L}
+#endif
+			    },
+    {"readonly",    "ro",   P_BOOL|P_VI_DEF|P_RSTAT|P_NOGLOB,
+			    (char_u *)&p_ro, PV_RO,
+			    {(char_u *)FALSE, (char_u *)0L}},
+    {"redraw",	    NULL,   P_BOOL|P_VI_DEF,
+			    (char_u *)NULL, PV_NONE,
+			    {(char_u *)FALSE, (char_u *)0L}},
+    {"remap",	    NULL,   P_BOOL|P_VI_DEF,
+			    (char_u *)&p_remap, PV_NONE,
+			    {(char_u *)TRUE, (char_u *)0L}},
+    {"report",	    NULL,   P_NUM|P_VI_DEF,
+			    (char_u *)&p_report, PV_NONE,
+			    {(char_u *)2L, (char_u *)0L}},
+    {"restorescreen", "rs", P_BOOL|P_VI_DEF,
+#ifdef WIN3264
+			    (char_u *)&p_rs, PV_NONE,
+#else
+			    (char_u *)NULL, PV_NONE,
+#endif
+			    {(char_u *)TRUE, (char_u *)0L}},
+    {"revins",	    "ri",   P_BOOL|P_VI_DEF|P_VIM,
+#ifdef FEAT_RIGHTLEFT
+			    (char_u *)&p_ri, PV_NONE,
+#else
+			    (char_u *)NULL, PV_NONE,
+#endif
+			    {(char_u *)FALSE, (char_u *)0L}},
+    {"rightleft",   "rl",   P_BOOL|P_VI_DEF|P_RWIN,
+#ifdef FEAT_RIGHTLEFT
+			    (char_u *)VAR_WIN, PV_RL,
+#else
+			    (char_u *)NULL, PV_NONE,
+#endif
+			    {(char_u *)FALSE, (char_u *)0L}},
+    {"rightleftcmd", "rlc", P_STRING|P_ALLOCED|P_VI_DEF|P_RWIN,
+#ifdef FEAT_RIGHTLEFT
+			    (char_u *)VAR_WIN, PV_RLC,
+			    {(char_u *)"search", (char_u *)NULL}
+#else
+			    (char_u *)NULL, PV_NONE,
+			    {(char_u *)NULL, (char_u *)0L}
+#endif
+			    },
+    {"ruler",	    "ru",   P_BOOL|P_VI_DEF|P_VIM|P_RSTAT,
+#ifdef FEAT_CMDL_INFO
+			    (char_u *)&p_ru, PV_NONE,
+#else
+			    (char_u *)NULL, PV_NONE,
+#endif
+			    {(char_u *)FALSE, (char_u *)0L}},
+    {"rulerformat", "ruf",  P_STRING|P_VI_DEF|P_ALLOCED|P_RSTAT,
+#ifdef FEAT_STL_OPT
+			    (char_u *)&p_ruf, PV_NONE,
+#else
+			    (char_u *)NULL, PV_NONE,
+#endif
+			    {(char_u *)"", (char_u *)0L}},
+    {"runtimepath", "rtp",  P_STRING|P_VI_DEF|P_EXPAND|P_COMMA|P_NODUP|P_SECURE,
+			    (char_u *)&p_rtp, PV_NONE,
+			    {(char_u *)DFLT_RUNTIMEPATH, (char_u *)0L}},
+    {"scroll",	    "scr",  P_NUM|P_NO_MKRC|P_VI_DEF,
+			    (char_u *)VAR_WIN, PV_SCROLL,
+			    {(char_u *)12L, (char_u *)0L}},
+    {"scrollbind",  "scb",  P_BOOL|P_VI_DEF,
+#ifdef FEAT_SCROLLBIND
+			    (char_u *)VAR_WIN, PV_SCBIND,
+#else
+			    (char_u *)NULL, PV_NONE,
+#endif
+			    {(char_u *)FALSE, (char_u *)0L}},
+    {"scrolljump",  "sj",   P_NUM|P_VI_DEF|P_VIM,
+			    (char_u *)&p_sj, PV_NONE,
+			    {(char_u *)1L, (char_u *)0L}},
+    {"scrolloff",   "so",   P_NUM|P_VI_DEF|P_VIM|P_RALL,
+			    (char_u *)&p_so, PV_NONE,
+			    {(char_u *)0L, (char_u *)0L}},
+    {"scrollopt",   "sbo",  P_STRING|P_VI_DEF|P_COMMA|P_NODUP,
+#ifdef FEAT_SCROLLBIND
+			    (char_u *)&p_sbo, PV_NONE,
+			    {(char_u *)"ver,jump", (char_u *)0L}
+#else
+			    (char_u *)NULL, PV_NONE,
+			    {(char_u *)0L, (char_u *)0L}
+#endif
+			    },
+    {"sections",    "sect", P_STRING|P_VI_DEF,
+			    (char_u *)&p_sections, PV_NONE,
+			    {(char_u *)"SHNHH HUnhsh", (char_u *)0L}},
+    {"secure",	    NULL,   P_BOOL|P_VI_DEF|P_SECURE,
+			    (char_u *)&p_secure, PV_NONE,
+			    {(char_u *)FALSE, (char_u *)0L}},
+    {"selection",   "sel",  P_STRING|P_VI_DEF,
+#ifdef FEAT_VISUAL
+			    (char_u *)&p_sel, PV_NONE,
+#else
+			    (char_u *)NULL, PV_NONE,
+#endif
+			    {(char_u *)"inclusive", (char_u *)0L}},
+    {"selectmode",  "slm",  P_STRING|P_VI_DEF|P_COMMA|P_NODUP,
+#ifdef FEAT_VISUAL
+			    (char_u *)&p_slm, PV_NONE,
+#else
+			    (char_u *)NULL, PV_NONE,
+#endif
+			    {(char_u *)"", (char_u *)0L}},
+    {"sessionoptions", "ssop", P_STRING|P_VI_DEF|P_COMMA|P_NODUP,
+#ifdef FEAT_SESSION
+			    (char_u *)&p_ssop, PV_NONE,
+	 {(char_u *)"blank,buffers,curdir,folds,help,options,tabpages,winsize",
+							       (char_u *)0L}
+#else
+			    (char_u *)NULL, PV_NONE,
+			    {(char_u *)0L, (char_u *)0L}
+#endif
+			    },
+    {"shell",	    "sh",   P_STRING|P_EXPAND|P_VI_DEF|P_SECURE,
+			    (char_u *)&p_sh, PV_NONE,
+			    {
+#ifdef VMS
+			    (char_u *)"-",
+#else
+# if defined(MSDOS)
+			    (char_u *)"command",
+# else
+#  if defined(WIN16)
+			    (char_u *)"command.com",
+#  else
+#   if defined(WIN3264)
+			    (char_u *)"",	/* set in set_init_1() */
+#   else
+#    if defined(OS2)
+			    (char_u *)"cmd.exe",
+#    else
+#     if defined(ARCHIE)
+			    (char_u *)"gos",
+#     else
+#      if defined(PLAN9)
+                (char_u *)"rc",
+#      else
+			    (char_u *)"sh",
+#      endif
+#     endif
+#    endif
+#   endif
+#  endif
+# endif
+#endif /* VMS */
+				(char_u *)0L}},
+    {"shellcmdflag","shcf", P_STRING|P_VI_DEF|P_SECURE,
+			    (char_u *)&p_shcf, PV_NONE,
+			    {
+#if defined(MSDOS) || defined(MSWIN)
+			    (char_u *)"/c",
+#else
+# if defined(OS2)
+			    (char_u *)"/c",
+# else
+			    (char_u *)"-c",
+# endif
+#endif
+				(char_u *)0L}},
+    {"shellpipe",   "sp",   P_STRING|P_VI_DEF|P_SECURE,
+#ifdef FEAT_QUICKFIX
+			    (char_u *)&p_sp, PV_NONE,
+			    {
+#if defined(UNIX) || defined(OS2)
+# ifdef ARCHIE
+			    (char_u *)"2>",
+# else
+			    (char_u *)"| tee",
+# endif
+#else
+			    (char_u *)">",
+#endif
+				(char_u *)0L}
+#else
+			    (char_u *)NULL, PV_NONE,
+			    {(char_u *)0L, (char_u *)0L}
+#endif
+    },
+    {"shellquote",  "shq",  P_STRING|P_VI_DEF|P_SECURE,
+			    (char_u *)&p_shq, PV_NONE,
+			    {(char_u *)"", (char_u *)0L}},
+    {"shellredir",  "srr",  P_STRING|P_VI_DEF|P_SECURE,
+			    (char_u *)&p_srr, PV_NONE,
+			    {(char_u *)">", (char_u *)0L}},
+    {"shellslash",  "ssl",   P_BOOL|P_VI_DEF,
+#ifdef BACKSLASH_IN_FILENAME
+			    (char_u *)&p_ssl, PV_NONE,
+#else
+			    (char_u *)NULL, PV_NONE,
+#endif
+			    {(char_u *)FALSE, (char_u *)0L}},
+    {"shelltemp",   "stmp", P_BOOL,
+			    (char_u *)&p_stmp, PV_NONE,
+			    {(char_u *)FALSE, (char_u *)TRUE}},
+    {"shelltype",   "st",   P_NUM|P_VI_DEF,
+#ifdef AMIGA
+			    (char_u *)&p_st, PV_NONE,
+#else
+			    (char_u *)NULL, PV_NONE,
+#endif
+			    {(char_u *)0L, (char_u *)0L}},
+    {"shellxquote", "sxq",  P_STRING|P_VI_DEF|P_SECURE,
+			    (char_u *)&p_sxq, PV_NONE,
+			    {
+#if defined(UNIX) && defined(USE_SYSTEM) && !defined(__EMX__)
+			    (char_u *)"\"",
+#else
+			    (char_u *)"",
+#endif
+				(char_u *)0L}},
+    {"shiftround",  "sr",   P_BOOL|P_VI_DEF|P_VIM,
+			    (char_u *)&p_sr, PV_NONE,
+			    {(char_u *)FALSE, (char_u *)0L}},
+    {"shiftwidth",  "sw",   P_NUM|P_VI_DEF,
+			    (char_u *)&p_sw, PV_SW,
+			    {(char_u *)8L, (char_u *)0L}},
+    {"shortmess",   "shm",  P_STRING|P_VIM|P_FLAGLIST,
+			    (char_u *)&p_shm, PV_NONE,
+			    {(char_u *)"", (char_u *)"filnxtToO"}},
+    {"shortname",   "sn",   P_BOOL|P_VI_DEF,
+#ifdef SHORT_FNAME
+			    (char_u *)NULL, PV_NONE,
+#else
+			    (char_u *)&p_sn, PV_SN,
+#endif
+			    {(char_u *)FALSE, (char_u *)0L}},
+    {"showbreak",   "sbr",  P_STRING|P_VI_DEF|P_RALL,
+#ifdef FEAT_LINEBREAK
+			    (char_u *)&p_sbr, PV_NONE,
+#else
+			    (char_u *)NULL, PV_NONE,
+#endif
+			    {(char_u *)"", (char_u *)0L}},
+    {"showcmd",	    "sc",   P_BOOL|P_VIM,
+#ifdef FEAT_CMDL_INFO
+			    (char_u *)&p_sc, PV_NONE,
+#else
+			    (char_u *)NULL, PV_NONE,
+#endif
+			    {(char_u *)FALSE,
+#ifdef UNIX
+				(char_u *)FALSE
+#else
+				(char_u *)TRUE
+#endif
+				}},
+    {"showfulltag", "sft",  P_BOOL|P_VI_DEF,
+			    (char_u *)&p_sft, PV_NONE,
+			    {(char_u *)FALSE, (char_u *)0L}},
+    {"showmatch",   "sm",   P_BOOL|P_VI_DEF,
+			    (char_u *)&p_sm, PV_NONE,
+			    {(char_u *)FALSE, (char_u *)0L}},
+    {"showmode",    "smd",  P_BOOL|P_VIM,
+			    (char_u *)&p_smd, PV_NONE,
+			    {(char_u *)FALSE, (char_u *)TRUE}},
+    {"showtabline", "stal", P_NUM|P_VI_DEF|P_RALL,
+#ifdef FEAT_WINDOWS
+			    (char_u *)&p_stal, PV_NONE,
+#else
+			    (char_u *)NULL, PV_NONE,
+#endif
+			    {(char_u *)1L, (char_u *)0L}},
+    {"sidescroll",  "ss",   P_NUM|P_VI_DEF,
+			    (char_u *)&p_ss, PV_NONE,
+			    {(char_u *)0L, (char_u *)0L}},
+    {"sidescrolloff", "siso", P_NUM|P_VI_DEF|P_VIM|P_RBUF,
+			    (char_u *)&p_siso, PV_NONE,
+			    {(char_u *)0L, (char_u *)0L}},
+    {"slowopen",    "slow", P_BOOL|P_VI_DEF,
+			    (char_u *)NULL, PV_NONE,
+			    {(char_u *)FALSE, (char_u *)0L}},
+    {"smartcase",   "scs",  P_BOOL|P_VI_DEF|P_VIM,
+			    (char_u *)&p_scs, PV_NONE,
+			    {(char_u *)FALSE, (char_u *)0L}},
+    {"smartindent", "si",   P_BOOL|P_VI_DEF|P_VIM,
+#ifdef FEAT_SMARTINDENT
+			    (char_u *)&p_si, PV_SI,
+#else
+			    (char_u *)NULL, PV_NONE,
+#endif
+			    {(char_u *)FALSE, (char_u *)0L}},
+    {"smarttab",    "sta",  P_BOOL|P_VI_DEF|P_VIM,
+			    (char_u *)&p_sta, PV_NONE,
+			    {(char_u *)FALSE, (char_u *)0L}},
+    {"softtabstop", "sts",  P_NUM|P_VI_DEF|P_VIM,
+			    (char_u *)&p_sts, PV_STS,
+			    {(char_u *)0L, (char_u *)0L}},
+    {"sourceany",   NULL,   P_BOOL|P_VI_DEF,
+			    (char_u *)NULL, PV_NONE,
+			    {(char_u *)FALSE, (char_u *)0L}},
+    {"spell",	    NULL,   P_BOOL|P_VI_DEF|P_RWIN,
+#ifdef FEAT_SPELL
+			    (char_u *)VAR_WIN, PV_SPELL,
+#else
+			    (char_u *)NULL, PV_NONE,
+#endif
+			    {(char_u *)FALSE, (char_u *)0L}},
+    {"spellcapcheck", "spc", P_STRING|P_ALLOCED|P_VI_DEF|P_RBUF,
+#ifdef FEAT_SPELL
+			    (char_u *)&p_spc, PV_SPC,
+			    {(char_u *)"[.?!]\\_[\\])'\"	 ]\\+", (char_u *)0L}
+#else
+			    (char_u *)NULL, PV_NONE,
+			    {(char_u *)0L, (char_u *)0L}
+#endif
+			    },
+    {"spellfile",   "spf",  P_STRING|P_EXPAND|P_ALLOCED|P_VI_DEF|P_SECURE|P_COMMA,
+#ifdef FEAT_SPELL
+			    (char_u *)&p_spf, PV_SPF,
+			    {(char_u *)"", (char_u *)0L}
+#else
+			    (char_u *)NULL, PV_NONE,
+			    {(char_u *)0L, (char_u *)0L}
+#endif
+			    },
+    {"spelllang",   "spl",  P_STRING|P_ALLOCED|P_VI_DEF|P_COMMA|P_RBUF|P_EXPAND,
+#ifdef FEAT_SPELL
+			    (char_u *)&p_spl, PV_SPL,
+			    {(char_u *)"en", (char_u *)0L}
+#else
+			    (char_u *)NULL, PV_NONE,
+			    {(char_u *)0L, (char_u *)0L}
+#endif
+			    },
+    {"spellsuggest", "sps", P_STRING|P_VI_DEF|P_EXPAND|P_SECURE|P_COMMA,
+#ifdef FEAT_SPELL
+			    (char_u *)&p_sps, PV_NONE,
+			    {(char_u *)"best", (char_u *)0L}
+#else
+			    (char_u *)NULL, PV_NONE,
+			    {(char_u *)0L, (char_u *)0L}
+#endif
+    },
+    {"splitbelow",  "sb",   P_BOOL|P_VI_DEF,
+#ifdef FEAT_WINDOWS
+			    (char_u *)&p_sb, PV_NONE,
+#else
+			    (char_u *)NULL, PV_NONE,
+#endif
+			    {(char_u *)FALSE, (char_u *)0L}},
+    {"splitright",  "spr",  P_BOOL|P_VI_DEF,
+#ifdef FEAT_VERTSPLIT
+			    (char_u *)&p_spr, PV_NONE,
+#else
+			    (char_u *)NULL, PV_NONE,
+#endif
+			    {(char_u *)FALSE, (char_u *)0L}},
+    {"startofline", "sol",  P_BOOL|P_VI_DEF|P_VIM,
+			    (char_u *)&p_sol, PV_NONE,
+			    {(char_u *)TRUE, (char_u *)0L}},
+    {"statusline"  ,"stl",  P_STRING|P_VI_DEF|P_ALLOCED|P_RSTAT,
+#ifdef FEAT_STL_OPT
+			    (char_u *)&p_stl, PV_STL,
+#else
+			    (char_u *)NULL, PV_NONE,
+#endif
+			    {(char_u *)"", (char_u *)0L}},
+    {"suffixes",    "su",   P_STRING|P_VI_DEF|P_COMMA|P_NODUP,
+			    (char_u *)&p_su, PV_NONE,
+			    {(char_u *)".bak,~,.o,.h,.info,.swp,.obj",
+				(char_u *)0L}},
+    {"suffixesadd", "sua",  P_STRING|P_VI_DEF|P_ALLOCED|P_COMMA|P_NODUP,
+#ifdef FEAT_SEARCHPATH
+			    (char_u *)&p_sua, PV_SUA,
+			    {(char_u *)"", (char_u *)0L}
+#else
+			    (char_u *)NULL, PV_NONE,
+			    {(char_u *)0L, (char_u *)0L}
+#endif
+			    },
+    {"swapfile",    "swf",  P_BOOL|P_VI_DEF|P_RSTAT,
+			    (char_u *)&p_swf, PV_SWF,
+			    {(char_u *)TRUE, (char_u *)0L}},
+    {"swapsync",    "sws",  P_STRING|P_VI_DEF,
+			    (char_u *)&p_sws, PV_NONE,
+			    {(char_u *)"fsync", (char_u *)0L}},
+    {"switchbuf",   "swb",  P_STRING|P_VI_DEF|P_COMMA|P_NODUP,
+			    (char_u *)&p_swb, PV_NONE,
+			    {(char_u *)"", (char_u *)0L}},
+    {"synmaxcol",   "smc",  P_NUM|P_VI_DEF|P_RBUF,
+#ifdef FEAT_SYN_HL
+			    (char_u *)&p_smc, PV_SMC,
+			    {(char_u *)3000L, (char_u *)0L}
+#else
+			    (char_u *)NULL, PV_NONE,
+			    {(char_u *)0L, (char_u *)0L}
+#endif
+			    },
+    {"syntax",	    "syn",  P_STRING|P_ALLOCED|P_VI_DEF|P_NOGLOB|P_NFNAME,
+#ifdef FEAT_SYN_HL
+			    (char_u *)&p_syn, PV_SYN,
+			    {(char_u *)"", (char_u *)0L}
+#else
+			    (char_u *)NULL, PV_NONE,
+			    {(char_u *)0L, (char_u *)0L}
+#endif
+			    },
+    {"tabline",	    "tal",  P_STRING|P_VI_DEF|P_RALL,
+#ifdef FEAT_STL_OPT
+			    (char_u *)&p_tal, PV_NONE,
+#else
+			    (char_u *)NULL, PV_NONE,
+#endif
+			    {(char_u *)"", (char_u *)0L}},
+    {"tabpagemax",  "tpm",  P_NUM|P_VI_DEF,
+#ifdef FEAT_WINDOWS
+			    (char_u *)&p_tpm, PV_NONE,
+#else
+			    (char_u *)NULL, PV_NONE,
+#endif
+			    {(char_u *)10L, (char_u *)0L}},
+    {"tabstop",	    "ts",   P_NUM|P_VI_DEF|P_RBUF,
+			    (char_u *)&p_ts, PV_TS,
+			    {(char_u *)8L, (char_u *)0L}},
+    {"tagbsearch",  "tbs",   P_BOOL|P_VI_DEF,
+			    (char_u *)&p_tbs, PV_NONE,
+#ifdef VMS	/* binary searching doesn't appear to work on VMS */
+			    {(char_u *)0L, (char_u *)0L}
+#else
+			    {(char_u *)TRUE, (char_u *)0L}
+#endif
+			    },
+    {"taglength",   "tl",   P_NUM|P_VI_DEF,
+			    (char_u *)&p_tl, PV_NONE,
+			    {(char_u *)0L, (char_u *)0L}},
+    {"tagrelative", "tr",   P_BOOL|P_VIM,
+			    (char_u *)&p_tr, PV_NONE,
+			    {(char_u *)FALSE, (char_u *)TRUE}},
+    {"tags",	    "tag",  P_STRING|P_EXPAND|P_VI_DEF|P_COMMA|P_NODUP,
+			    (char_u *)&p_tags, PV_TAGS,
+			    {
+#if defined(FEAT_EMACS_TAGS) && !defined(CASE_INSENSITIVE_FILENAME)
+			    (char_u *)"./tags,./TAGS,tags,TAGS",
+#else
+			    (char_u *)"./tags,tags",
+#endif
+				(char_u *)0L}},
+    {"tagstack",    "tgst", P_BOOL|P_VI_DEF,
+			    (char_u *)&p_tgst, PV_NONE,
+			    {(char_u *)TRUE, (char_u *)0L}},
+    {"term",	    NULL,   P_STRING|P_EXPAND|P_NODEFAULT|P_NO_MKRC|P_VI_DEF|P_RALL,
+			    (char_u *)&T_NAME, PV_NONE,
+			    {(char_u *)"", (char_u *)0L}},
+    {"termbidi", "tbidi",   P_BOOL|P_VI_DEF,
+#ifdef FEAT_ARABIC
+			    (char_u *)&p_tbidi, PV_NONE,
+#else
+			    (char_u *)NULL, PV_NONE,
+#endif
+			    {(char_u *)FALSE, (char_u *)0L}},
+    {"termencoding", "tenc", P_STRING|P_VI_DEF|P_RCLR,
+#ifdef FEAT_MBYTE
+			    (char_u *)&p_tenc, PV_NONE,
+			    {(char_u *)"", (char_u *)0L}
+#else
+			    (char_u *)NULL, PV_NONE,
+			    {(char_u *)0L, (char_u *)0L}
+#endif
+			    },
+    {"terse",	    NULL,   P_BOOL|P_VI_DEF,
+			    (char_u *)&p_terse, PV_NONE,
+			    {(char_u *)FALSE, (char_u *)0L}},
+    {"textauto",    "ta",   P_BOOL|P_VIM,
+			    (char_u *)&p_ta, PV_NONE,
+			    {(char_u *)DFLT_TEXTAUTO, (char_u *)TRUE}},
+    {"textmode",    "tx",   P_BOOL|P_VI_DEF|P_NO_MKRC,
+			    (char_u *)&p_tx, PV_TX,
+			    {
+#ifdef USE_CRNL
+			    (char_u *)TRUE,
+#else
+			    (char_u *)FALSE,
+#endif
+				(char_u *)0L}},
+    {"textwidth",   "tw",   P_NUM|P_VI_DEF|P_VIM,
+			    (char_u *)&p_tw, PV_TW,
+			    {(char_u *)0L, (char_u *)0L}},
+    {"thesaurus",   "tsr",  P_STRING|P_EXPAND|P_VI_DEF|P_COMMA|P_NODUP,
+#ifdef FEAT_INS_EXPAND
+			    (char_u *)&p_tsr, PV_TSR,
+#else
+			    (char_u *)NULL, PV_NONE,
+#endif
+			    {(char_u *)"", (char_u *)0L}},
+    {"tildeop",	    "top",  P_BOOL|P_VI_DEF|P_VIM,
+			    (char_u *)&p_to, PV_NONE,
+			    {(char_u *)FALSE, (char_u *)0L}},
+    {"timeout",	    "to",   P_BOOL|P_VI_DEF,
+			    (char_u *)&p_timeout, PV_NONE,
+			    {(char_u *)TRUE, (char_u *)0L}},
+    {"timeoutlen",  "tm",   P_NUM|P_VI_DEF,
+			    (char_u *)&p_tm, PV_NONE,
+			    {(char_u *)1000L, (char_u *)0L}},
+    {"title",	    NULL,   P_BOOL|P_VI_DEF,
+#ifdef FEAT_TITLE
+			    (char_u *)&p_title, PV_NONE,
+#else
+			    (char_u *)NULL, PV_NONE,
+#endif
+			    {(char_u *)FALSE, (char_u *)0L}},
+    {"titlelen",    NULL,   P_NUM|P_VI_DEF,
+#ifdef FEAT_TITLE
+			    (char_u *)&p_titlelen, PV_NONE,
+#else
+			    (char_u *)NULL, PV_NONE,
+#endif
+			    {(char_u *)85L, (char_u *)0L}},
+    {"titleold",    NULL,   P_STRING|P_VI_DEF|P_GETTEXT|P_SECURE|P_NO_MKRC,
+#ifdef FEAT_TITLE
+			    (char_u *)&p_titleold, PV_NONE,
+			    {(char_u *)N_("Thanks for flying Vim"),
+							       (char_u *)0L}
+#else
+			    (char_u *)NULL, PV_NONE,
+			    {(char_u *)0L, (char_u *)0L}
+#endif
+			    },
+    {"titlestring", NULL,   P_STRING|P_VI_DEF,
+#ifdef FEAT_TITLE
+			    (char_u *)&p_titlestring, PV_NONE,
+#else
+			    (char_u *)NULL, PV_NONE,
+#endif
+			    {(char_u *)"", (char_u *)0L}},
+#if defined(FEAT_TOOLBAR) && !defined(FEAT_GUI_W32)
+    {"toolbar",     "tb",   P_STRING|P_COMMA|P_VI_DEF|P_NODUP,
+			    (char_u *)&p_toolbar, PV_NONE,
+			    {(char_u *)"icons,tooltips", (char_u *)0L}},
+#endif
+#if defined(FEAT_TOOLBAR) && defined(FEAT_GUI_GTK) && defined(HAVE_GTK2)
+    {"toolbariconsize",	"tbis", P_STRING|P_VI_DEF,
+			    (char_u *)&p_tbis, PV_NONE,
+			    {(char_u *)"small", (char_u *)0L}},
+#endif
+    {"ttimeout",    NULL,   P_BOOL|P_VI_DEF|P_VIM,
+			    (char_u *)&p_ttimeout, PV_NONE,
+			    {(char_u *)FALSE, (char_u *)0L}},
+    {"ttimeoutlen", "ttm",  P_NUM|P_VI_DEF,
+			    (char_u *)&p_ttm, PV_NONE,
+			    {(char_u *)-1L, (char_u *)0L}},
+    {"ttybuiltin",  "tbi",  P_BOOL|P_VI_DEF,
+			    (char_u *)&p_tbi, PV_NONE,
+			    {(char_u *)TRUE, (char_u *)0L}},
+    {"ttyfast",	    "tf",   P_BOOL|P_NO_MKRC|P_VI_DEF,
+			    (char_u *)&p_tf, PV_NONE,
+			    {(char_u *)FALSE, (char_u *)0L}},
+    {"ttymouse",    "ttym", P_STRING|P_NODEFAULT|P_NO_MKRC|P_VI_DEF,
+#if defined(FEAT_MOUSE) && (defined(UNIX) || defined(VMS))
+			    (char_u *)&p_ttym, PV_NONE,
+#else
+			    (char_u *)NULL, PV_NONE,
+#endif
+			    {(char_u *)"", (char_u *)0L}},
+    {"ttyscroll",   "tsl",  P_NUM|P_VI_DEF,
+			    (char_u *)&p_ttyscroll, PV_NONE,
+			    {(char_u *)999L, (char_u *)0L}},
+    {"ttytype",	    "tty",  P_STRING|P_EXPAND|P_NODEFAULT|P_NO_MKRC|P_VI_DEF|P_RALL,
+			    (char_u *)&T_NAME, PV_NONE,
+			    {(char_u *)"", (char_u *)0L}},
+    {"undolevels",  "ul",   P_NUM|P_VI_DEF,
+			    (char_u *)&p_ul, PV_NONE,
+			    {
+#if defined(UNIX) || defined(WIN3264) || defined(OS2) || defined(VMS)
+			    (char_u *)1000L,
+#else
+			    (char_u *)100L,
+#endif
+				(char_u *)0L}},
+    {"updatecount", "uc",   P_NUM|P_VI_DEF,
+			    (char_u *)&p_uc, PV_NONE,
+			    {(char_u *)200L, (char_u *)0L}},
+    {"updatetime",  "ut",   P_NUM|P_VI_DEF,
+			    (char_u *)&p_ut, PV_NONE,
+			    {(char_u *)4000L, (char_u *)0L}},
+    {"verbose",	    "vbs",  P_NUM|P_VI_DEF,
+			    (char_u *)&p_verbose, PV_NONE,
+			    {(char_u *)0L, (char_u *)0L}},
+    {"verbosefile", "vfile", P_STRING|P_EXPAND|P_VI_DEF|P_SECURE,
+			    (char_u *)&p_vfile, PV_NONE,
+			    {(char_u *)"", (char_u *)0L}},
+    {"viewdir",     "vdir", P_STRING|P_EXPAND|P_VI_DEF|P_SECURE,
+#ifdef FEAT_SESSION
+			    (char_u *)&p_vdir, PV_NONE,
+			    {(char_u *)DFLT_VDIR, (char_u *)0L}
+#else
+			    (char_u *)NULL, PV_NONE,
+			    {(char_u *)0L, (char_u *)0L}
+#endif
+			    },
+    {"viewoptions", "vop",  P_STRING|P_VI_DEF|P_COMMA|P_NODUP,
+#ifdef FEAT_SESSION
+			    (char_u *)&p_vop, PV_NONE,
+			    {(char_u *)"folds,options,cursor", (char_u *)0L}
+#else
+			    (char_u *)NULL, PV_NONE,
+			    {(char_u *)0L, (char_u *)0L}
+#endif
+			    },
+    {"viminfo",	    "vi",   P_STRING|P_COMMA|P_NODUP|P_SECURE,
+#ifdef FEAT_VIMINFO
+			    (char_u *)&p_viminfo, PV_NONE,
+#if defined(MSDOS) || defined(MSWIN) || defined(OS2)
+			    {(char_u *)"", (char_u *)"'20,<50,s10,h,rA:,rB:"}
+#else
+# ifdef AMIGA
+			    {(char_u *)"",
+				 (char_u *)"'20,<50,s10,h,rdf0:,rdf1:,rdf2:"}
+# else
+			    {(char_u *)"", (char_u *)"'20,<50,s10,h"}
+# endif
+#endif
+#else
+			    (char_u *)NULL, PV_NONE,
+			    {(char_u *)0L, (char_u *)0L}
+#endif
+			    },
+    {"virtualedit", "ve",   P_STRING|P_COMMA|P_NODUP|P_VI_DEF|P_VIM,
+#ifdef FEAT_VIRTUALEDIT
+			    (char_u *)&p_ve, PV_NONE,
+			    {(char_u *)"", (char_u *)""}
+#else
+			    (char_u *)NULL, PV_NONE,
+			    {(char_u *)0L, (char_u *)0L}
+#endif
+			    },
+    {"visualbell",  "vb",   P_BOOL|P_VI_DEF,
+			    (char_u *)&p_vb, PV_NONE,
+			    {(char_u *)FALSE, (char_u *)0L}},
+    {"w300",	    NULL,   P_NUM|P_VI_DEF,
+			    (char_u *)NULL, PV_NONE,
+			    {(char_u *)0L, (char_u *)0L}},
+    {"w1200",	    NULL,   P_NUM|P_VI_DEF,
+			    (char_u *)NULL, PV_NONE,
+			    {(char_u *)0L, (char_u *)0L}},
+    {"w9600",	    NULL,   P_NUM|P_VI_DEF,
+			    (char_u *)NULL, PV_NONE,
+			    {(char_u *)0L, (char_u *)0L}},
+    {"warn",	    NULL,   P_BOOL|P_VI_DEF,
+			    (char_u *)&p_warn, PV_NONE,
+			    {(char_u *)TRUE, (char_u *)0L}},
+    {"weirdinvert", "wiv",  P_BOOL|P_VI_DEF|P_RCLR,
+			    (char_u *)&p_wiv, PV_NONE,
+			    {(char_u *)FALSE, (char_u *)0L}},
+    {"whichwrap",   "ww",   P_STRING|P_VIM|P_COMMA|P_FLAGLIST,
+			    (char_u *)&p_ww, PV_NONE,
+			    {(char_u *)"", (char_u *)"b,s"}},
+    {"wildchar",    "wc",   P_NUM|P_VIM,
+			    (char_u *)&p_wc, PV_NONE,
+			    {(char_u *)(long)Ctrl_E, (char_u *)(long)TAB}},
+    {"wildcharm",   "wcm",   P_NUM|P_VI_DEF,
+			    (char_u *)&p_wcm, PV_NONE,
+			    {(char_u *)0L, (char_u *)0L}},
+    {"wildignore",  "wig",  P_STRING|P_VI_DEF|P_COMMA|P_NODUP,
+#ifdef FEAT_WILDIGN
+			    (char_u *)&p_wig, PV_NONE,
+#else
+			    (char_u *)NULL, PV_NONE,
+#endif
+			    {(char_u *)"", (char_u *)0L}},
+    {"wildmenu",    "wmnu", P_BOOL|P_VI_DEF,
+#ifdef FEAT_WILDMENU
+			    (char_u *)&p_wmnu, PV_NONE,
+#else
+			    (char_u *)NULL, PV_NONE,
+#endif
+			    {(char_u *)FALSE, (char_u *)0L}},
+    {"wildmode",    "wim",  P_STRING|P_VI_DEF|P_COMMA|P_NODUP,
+			    (char_u *)&p_wim, PV_NONE,
+			    {(char_u *)"full", (char_u *)0L}},
+    {"wildoptions", "wop",  P_STRING|P_VI_DEF,
+#ifdef FEAT_CMDL_COMPL
+			    (char_u *)&p_wop, PV_NONE,
+			    {(char_u *)"", (char_u *)0L}
+#else
+			    (char_u *)NULL, PV_NONE,
+			    {(char_u *)NULL, (char_u *)0L}
+#endif
+			    },
+    {"winaltkeys",  "wak",  P_STRING|P_VI_DEF,
+#ifdef FEAT_WAK
+			    (char_u *)&p_wak, PV_NONE,
+			    {(char_u *)"menu", (char_u *)0L}
+#else
+			    (char_u *)NULL, PV_NONE,
+			    {(char_u *)NULL, (char_u *)0L}
+#endif
+			    },
+    {"window",	    "wi",   P_NUM|P_VI_DEF,
+			    (char_u *)&p_window, PV_NONE,
+			    {(char_u *)0L, (char_u *)0L}},
+    {"winheight",   "wh",   P_NUM|P_VI_DEF,
+#ifdef FEAT_WINDOWS
+			    (char_u *)&p_wh, PV_NONE,
+#else
+			    (char_u *)NULL, PV_NONE,
+#endif
+			    {(char_u *)1L, (char_u *)0L}},
+    {"winfixheight", "wfh", P_BOOL|P_VI_DEF|P_RSTAT,
+#ifdef FEAT_WINDOWS
+			    (char_u *)VAR_WIN, PV_WFH,
+#else
+			    (char_u *)NULL, PV_NONE,
+#endif
+			    {(char_u *)FALSE, (char_u *)0L}},
+    {"winfixwidth", "wfw", P_BOOL|P_VI_DEF|P_RSTAT,
+#ifdef FEAT_VERTSPLIT
+			    (char_u *)VAR_WIN, PV_WFW,
+#else
+			    (char_u *)NULL, PV_NONE,
+#endif
+			    {(char_u *)FALSE, (char_u *)0L}},
+    {"winminheight", "wmh", P_NUM|P_VI_DEF,
+#ifdef FEAT_WINDOWS
+			    (char_u *)&p_wmh, PV_NONE,
+#else
+			    (char_u *)NULL, PV_NONE,
+#endif
+			    {(char_u *)1L, (char_u *)0L}},
+    {"winminwidth", "wmw", P_NUM|P_VI_DEF,
+#ifdef FEAT_VERTSPLIT
+			    (char_u *)&p_wmw, PV_NONE,
+#else
+			    (char_u *)NULL, PV_NONE,
+#endif
+			    {(char_u *)1L, (char_u *)0L}},
+    {"winwidth",   "wiw",   P_NUM|P_VI_DEF,
+#ifdef FEAT_VERTSPLIT
+			    (char_u *)&p_wiw, PV_NONE,
+#else
+			    (char_u *)NULL, PV_NONE,
+#endif
+			    {(char_u *)20L, (char_u *)0L}},
+    {"wrap",	    NULL,   P_BOOL|P_VI_DEF|P_RWIN,
+			    (char_u *)VAR_WIN, PV_WRAP,
+			    {(char_u *)TRUE, (char_u *)0L}},
+    {"wrapmargin",  "wm",   P_NUM|P_VI_DEF,
+			    (char_u *)&p_wm, PV_WM,
+			    {(char_u *)0L, (char_u *)0L}},
+    {"wrapscan",    "ws",   P_BOOL|P_VI_DEF,
+			    (char_u *)&p_ws, PV_NONE,
+			    {(char_u *)TRUE, (char_u *)0L}},
+    {"write",	    NULL,   P_BOOL|P_VI_DEF,
+			    (char_u *)&p_write, PV_NONE,
+			    {(char_u *)TRUE, (char_u *)0L}},
+    {"writeany",    "wa",   P_BOOL|P_VI_DEF,
+			    (char_u *)&p_wa, PV_NONE,
+			    {(char_u *)FALSE, (char_u *)0L}},
+    {"writebackup", "wb",   P_BOOL|P_VI_DEF|P_VIM,
+			    (char_u *)&p_wb, PV_NONE,
+			    {
+#ifdef FEAT_WRITEBACKUP
+			    (char_u *)TRUE,
+#else
+			    (char_u *)FALSE,
+#endif
+				(char_u *)0L}},
+    {"writedelay",  "wd",   P_NUM|P_VI_DEF,
+			    (char_u *)&p_wd, PV_NONE,
+			    {(char_u *)0L, (char_u *)0L}},
+
+/* terminal output codes */
+#define p_term(sss, vvv)   {sss, NULL, P_STRING|P_VI_DEF|P_RALL|P_SECURE, \
+			    (char_u *)&vvv, PV_NONE, \
+			    {(char_u *)"", (char_u *)0L}},
+
+    p_term("t_AB", T_CAB)
+    p_term("t_AF", T_CAF)
+    p_term("t_AL", T_CAL)
+    p_term("t_al", T_AL)
+    p_term("t_bc", T_BC)
+    p_term("t_cd", T_CD)
+    p_term("t_ce", T_CE)
+    p_term("t_cl", T_CL)
+    p_term("t_cm", T_CM)
+    p_term("t_Co", T_CCO)
+    p_term("t_CS", T_CCS)
+    p_term("t_cs", T_CS)
+#ifdef FEAT_VERTSPLIT
+    p_term("t_CV", T_CSV)
+#endif
+    p_term("t_ut", T_UT)
+    p_term("t_da", T_DA)
+    p_term("t_db", T_DB)
+    p_term("t_DL", T_CDL)
+    p_term("t_dl", T_DL)
+    p_term("t_fs", T_FS)
+    p_term("t_IE", T_CIE)
+    p_term("t_IS", T_CIS)
+    p_term("t_ke", T_KE)
+    p_term("t_ks", T_KS)
+    p_term("t_le", T_LE)
+    p_term("t_mb", T_MB)
+    p_term("t_md", T_MD)
+    p_term("t_me", T_ME)
+    p_term("t_mr", T_MR)
+    p_term("t_ms", T_MS)
+    p_term("t_nd", T_ND)
+    p_term("t_op", T_OP)
+    p_term("t_RI", T_CRI)
+    p_term("t_RV", T_CRV)
+    p_term("t_Sb", T_CSB)
+    p_term("t_Sf", T_CSF)
+    p_term("t_se", T_SE)
+    p_term("t_so", T_SO)
+    p_term("t_sr", T_SR)
+    p_term("t_ts", T_TS)
+    p_term("t_te", T_TE)
+    p_term("t_ti", T_TI)
+    p_term("t_ue", T_UE)
+    p_term("t_us", T_US)
+    p_term("t_vb", T_VB)
+    p_term("t_ve", T_VE)
+    p_term("t_vi", T_VI)
+    p_term("t_vs", T_VS)
+    p_term("t_WP", T_CWP)
+    p_term("t_WS", T_CWS)
+    p_term("t_SI", T_CSI)
+    p_term("t_EI", T_CEI)
+    p_term("t_xs", T_XS)
+    p_term("t_ZH", T_CZH)
+    p_term("t_ZR", T_CZR)
+
+/* terminal key codes are not in here */
+
+    {NULL, NULL, 0, NULL, PV_NONE, {NULL, NULL}}	/* end marker */
+};
+
+#define PARAM_COUNT (sizeof(options) / sizeof(struct vimoption))
+
+#ifdef FEAT_MBYTE
+static char *(p_ambw_values[]) = {"single", "double", NULL};
+#endif
+static char *(p_bg_values[]) = {"light", "dark", NULL};
+static char *(p_nf_values[]) = {"octal", "hex", "alpha", NULL};
+static char *(p_ff_values[]) = {FF_UNIX, FF_DOS, FF_MAC, NULL};
+#ifdef FEAT_CMDL_COMPL
+static char *(p_wop_values[]) = {"tagfile", NULL};
+#endif
+#ifdef FEAT_WAK
+static char *(p_wak_values[]) = {"yes", "menu", "no", NULL};
+#endif
+static char *(p_mousem_values[]) = {"extend", "popup", "popup_setpos", "mac", NULL};
+#ifdef FEAT_VISUAL
+static char *(p_sel_values[]) = {"inclusive", "exclusive", "old", NULL};
+static char *(p_slm_values[]) = {"mouse", "key", "cmd", NULL};
+#endif
+#ifdef FEAT_VISUAL
+static char *(p_km_values[]) = {"startsel", "stopsel", NULL};
+#endif
+#ifdef FEAT_BROWSE
+static char *(p_bsdir_values[]) = {"current", "last", "buffer", NULL};
+#endif
+#ifdef FEAT_SCROLLBIND
+static char *(p_scbopt_values[]) = {"ver", "hor", "jump", NULL};
+#endif
+static char *(p_swb_values[]) = {"useopen", "usetab", "split", NULL};
+static char *(p_debug_values[]) = {"msg", "throw", "beep", NULL};
+#ifdef FEAT_VERTSPLIT
+static char *(p_ead_values[]) = {"both", "ver", "hor", NULL};
+#endif
+#if defined(FEAT_QUICKFIX)
+# ifdef FEAT_AUTOCMD
+static char *(p_buftype_values[]) = {"nofile", "nowrite", "quickfix", "help", "acwrite", NULL};
+# else
+static char *(p_buftype_values[]) = {"nofile", "nowrite", "quickfix", "help", NULL};
+# endif
+static char *(p_bufhidden_values[]) = {"hide", "unload", "delete", "wipe", NULL};
+#endif
+static char *(p_bs_values[]) = {"indent", "eol", "start", NULL};
+#ifdef FEAT_FOLDING
+static char *(p_fdm_values[]) = {"manual", "expr", "marker", "indent", "syntax",
+# ifdef FEAT_DIFF
+				"diff",
+# endif
+				NULL};
+static char *(p_fcl_values[]) = {"all", NULL};
+#endif
+#ifdef FEAT_INS_EXPAND
+static char *(p_cot_values[]) = {"menu", "menuone", "longest", "preview", NULL};
+#endif
+
+static void set_option_default __ARGS((int, int opt_flags, int compatible));
+static void set_options_default __ARGS((int opt_flags));
+static char_u *term_bg_default __ARGS((void));
+static void did_set_option __ARGS((int opt_idx, int opt_flags, int new_value));
+static char_u *illegal_char __ARGS((char_u *, int));
+static int string_to_key __ARGS((char_u *arg));
+#ifdef FEAT_CMDWIN
+static char_u *check_cedit __ARGS((void));
+#endif
+#ifdef FEAT_TITLE
+static void did_set_title __ARGS((int icon));
+#endif
+static char_u *option_expand __ARGS((int opt_idx, char_u *val));
+static void didset_options __ARGS((void));
+static void check_string_option __ARGS((char_u **pp));
+#if defined(FEAT_EVAL) || defined(PROTO)
+static long_u *insecure_flag __ARGS((int opt_idx, int opt_flags));
+#else
+# define insecure_flag(opt_idx, opt_flags) (&options[opt_idx].flags)
+#endif
+static void set_string_option_global __ARGS((int opt_idx, char_u **varp));
+static void set_string_option __ARGS((int opt_idx, char_u *value, int opt_flags));
+static char_u *did_set_string_option __ARGS((int opt_idx, char_u **varp, int new_value_alloced, char_u *oldval, char_u *errbuf, int opt_flags));
+static char_u *set_chars_option __ARGS((char_u **varp));
+#ifdef FEAT_CLIPBOARD
+static char_u *check_clipboard_option __ARGS((void));
+#endif
+#ifdef FEAT_SPELL
+static char_u *compile_cap_prog __ARGS((buf_T *buf));
+#endif
+#ifdef FEAT_EVAL
+static void set_option_scriptID_idx __ARGS((int opt_idx, int opt_flags, int id));
+#endif
+static char_u *set_bool_option __ARGS((int opt_idx, char_u *varp, int value, int opt_flags));
+static char_u *set_num_option __ARGS((int opt_idx, char_u *varp, long value, char_u *errbuf, size_t errbuflen, int opt_flags));
+static void check_redraw __ARGS((long_u flags));
+static int findoption __ARGS((char_u *));
+static int find_key_option __ARGS((char_u *));
+static void showoptions __ARGS((int all, int opt_flags));
+static int optval_default __ARGS((struct vimoption *, char_u *varp));
+static void showoneopt __ARGS((struct vimoption *, int opt_flags));
+static int put_setstring __ARGS((FILE *fd, char *cmd, char *name, char_u **valuep, int expand));
+static int put_setnum __ARGS((FILE *fd, char *cmd, char *name, long *valuep));
+static int put_setbool __ARGS((FILE *fd, char *cmd, char *name, int value));
+static int  istermoption __ARGS((struct vimoption *));
+static char_u *get_varp_scope __ARGS((struct vimoption *p, int opt_flags));
+static char_u *get_varp __ARGS((struct vimoption *));
+static void option_value2string __ARGS((struct vimoption *, int opt_flags));
+static int wc_use_keyname __ARGS((char_u *varp, long *wcp));
+#ifdef FEAT_LANGMAP
+static void langmap_init __ARGS((void));
+static void langmap_set __ARGS((void));
+#endif
+static void paste_option_changed __ARGS((void));
+static void compatible_set __ARGS((void));
+#ifdef FEAT_LINEBREAK
+static void fill_breakat_flags __ARGS((void));
+#endif
+static int opt_strings_flags __ARGS((char_u *val, char **values, unsigned *flagp, int list));
+static int check_opt_strings __ARGS((char_u *val, char **values, int));
+static int check_opt_wim __ARGS((void));
+
+/*
+ * Initialize the options, first part.
+ *
+ * Called only once from main(), just after creating the first buffer.
+ */
+    void
+set_init_1()
+{
+    char_u	*p;
+    int		opt_idx;
+    long_u	n;
+
+#ifdef FEAT_LANGMAP
+    langmap_init();
+#endif
+
+    /* Be Vi compatible by default */
+    p_cp = TRUE;
+
+    /* Use POSIX compatibility when $VIM_POSIX is set. */
+    if (mch_getenv((char_u *)"VIM_POSIX") != NULL)
+    {
+	set_string_default("cpo", (char_u *)CPO_ALL);
+	set_string_default("shm", (char_u *)"A");
+    }
+
+    /*
+     * Find default value for 'shell' option.
+     * Don't use it if it is empty.
+     */
+    if (((p = mch_getenv((char_u *)"SHELL")) != NULL && *p != NUL)
+#if defined(MSDOS) || defined(MSWIN) || defined(OS2)
+# ifdef __EMX__
+	    || ((p = mch_getenv((char_u *)"EMXSHELL")) != NULL && *p != NUL)
+# endif
+	    || ((p = mch_getenv((char_u *)"COMSPEC")) != NULL && *p != NUL)
+# ifdef WIN3264
+	    || ((p = default_shell()) != NULL && *p != NUL)
+# endif
+#endif
+	    )
+	set_string_default("sh", p);
+
+#ifdef FEAT_WILDIGN
+    /*
+     * Set the default for 'backupskip' to include environment variables for
+     * temp files.
+     */
+    {
+# ifdef UNIX
+	static char	*(names[4]) = {"", "TMPDIR", "TEMP", "TMP"};
+# else
+	static char	*(names[3]) = {"TMPDIR", "TEMP", "TMP"};
+# endif
+	int		len;
+	garray_T	ga;
+	int		mustfree;
+
+	ga_init2(&ga, 1, 100);
+	for (n = 0; n < (long)(sizeof(names) / sizeof(char *)); ++n)
+	{
+	    mustfree = FALSE;
+# ifdef UNIX
+	    if (*names[n] == NUL)
+		p = (char_u *)"/tmp";
+	    else
+# endif
+		p = vim_getenv((char_u *)names[n], &mustfree);
+	    if (p != NULL && *p != NUL)
+	    {
+		/* First time count the NUL, otherwise count the ','. */
+		len = (int)STRLEN(p) + 3;
+		if (ga_grow(&ga, len) == OK)
+		{
+		    if (ga.ga_len > 0)
+			STRCAT(ga.ga_data, ",");
+		    STRCAT(ga.ga_data, p);
+		    add_pathsep(ga.ga_data);
+		    STRCAT(ga.ga_data, "*");
+		    ga.ga_len += len;
+		}
+	    }
+	    if (mustfree)
+		vim_free(p);
+	}
+	if (ga.ga_data != NULL)
+	{
+	    set_string_default("bsk", ga.ga_data);
+	    vim_free(ga.ga_data);
+	}
+    }
+#endif
+
+    /*
+     * 'maxmemtot' and 'maxmem' may have to be adjusted for available memory
+     */
+    opt_idx = findoption((char_u *)"maxmemtot");
+    if (opt_idx >= 0)
+    {
+#if !defined(HAVE_AVAIL_MEM) && !defined(HAVE_TOTAL_MEM)
+	if (options[opt_idx].def_val[VI_DEFAULT] == (char_u *)0L)
+#endif
+	{
+#ifdef HAVE_AVAIL_MEM
+	    /* Use amount of memory available at this moment. */
+	    n = (mch_avail_mem(FALSE) >> 11);
+#else
+# ifdef HAVE_TOTAL_MEM
+	    /* Use amount of memory available to Vim. */
+	    n = (mch_total_mem(FALSE) >> 1);
+# else
+	    n = (0x7fffffff >> 11);
+# endif
+#endif
+	    options[opt_idx].def_val[VI_DEFAULT] = (char_u *)n;
+	    opt_idx = findoption((char_u *)"maxmem");
+	    if (opt_idx >= 0)
+	    {
+#if !defined(HAVE_AVAIL_MEM) && !defined(HAVE_TOTAL_MEM)
+		if ((long)options[opt_idx].def_val[VI_DEFAULT] > n
+			|| (long)options[opt_idx].def_val[VI_DEFAULT] == 0L)
+#endif
+		    options[opt_idx].def_val[VI_DEFAULT] = (char_u *)n;
+	    }
+	}
+    }
+
+#ifdef FEAT_GUI_W32
+    /* force 'shortname' for Win32s */
+    if (gui_is_win32s())
+    {
+	opt_idx = findoption((char_u *)"shortname");
+	if (opt_idx >= 0)
+	    options[opt_idx].def_val[VI_DEFAULT] = (char_u *)TRUE;
+    }
+#endif
+
+#ifdef FEAT_SEARCHPATH
+    {
+	char_u	*cdpath;
+	char_u	*buf;
+	int	i;
+	int	j;
+	int	mustfree = FALSE;
+
+	/* Initialize the 'cdpath' option's default value. */
+	cdpath = vim_getenv((char_u *)"CDPATH", &mustfree);
+	if (cdpath != NULL)
+	{
+	    buf = alloc((unsigned)((STRLEN(cdpath) << 1) + 2));
+	    if (buf != NULL)
+	    {
+		buf[0] = ',';	    /* start with ",", current dir first */
+		j = 1;
+		for (i = 0; cdpath[i] != NUL; ++i)
+		{
+		    if (vim_ispathlistsep(cdpath[i]))
+			buf[j++] = ',';
+		    else
+		    {
+			if (cdpath[i] == ' ' || cdpath[i] == ',')
+			    buf[j++] = '\\';
+			buf[j++] = cdpath[i];
+		    }
+		}
+		buf[j] = NUL;
+		opt_idx = findoption((char_u *)"cdpath");
+		if (opt_idx >= 0)
+		{
+		    options[opt_idx].def_val[VI_DEFAULT] = buf;
+		    options[opt_idx].flags |= P_DEF_ALLOCED;
+		}
+	    }
+	    if (mustfree)
+		vim_free(cdpath);
+	}
+    }
+#endif
+
+#if defined(FEAT_POSTSCRIPT) && (defined(MSWIN) || defined(OS2) || defined(VMS) || defined(EBCDIC) || defined(MAC) || defined(hpux))
+    /* Set print encoding on platforms that don't default to latin1 */
+    set_string_default("penc",
+# if defined(MSWIN) || defined(OS2)
+		       (char_u *)"cp1252"
+# else
+#  ifdef VMS
+		       (char_u *)"dec-mcs"
+#  else
+#   ifdef EBCDIC
+		       (char_u *)"ebcdic-uk"
+#   else
+#    ifdef MAC
+		       (char_u *)"mac-roman"
+#    else /* HPUX */
+		       (char_u *)"hp-roman8"
+#    endif
+#   endif
+#  endif
+# endif
+		       );
+#endif
+
+#ifdef FEAT_POSTSCRIPT
+    /* 'printexpr' must be allocated to be able to evaluate it. */
+    set_string_default("pexpr",
+# if defined(MSWIN) || defined(MSDOS) || defined(OS2)
+	    (char_u *)"system('copy' . ' ' . v:fname_in . (&printdevice == '' ? ' LPT1:' : (' \"' . &printdevice . '\"'))) . delete(v:fname_in)"
+# else
+#  ifdef VMS
+	    (char_u *)"system('print/delete' . (&printdevice == '' ? '' : ' /queue=' . &printdevice) . ' ' . v:fname_in)"
+
+#  else
+	    (char_u *)"system('lpr' . (&printdevice == '' ? '' : ' -P' . &printdevice) . ' ' . v:fname_in) . delete(v:fname_in) + v:shell_error"
+#  endif
+# endif
+	    );
+#endif
+
+    /*
+     * Set all the options (except the terminal options) to their default
+     * value.  Also set the global value for local options.
+     */
+    set_options_default(0);
+
+#ifdef FEAT_GUI
+    if (found_reverse_arg)
+	set_option_value((char_u *)"bg", 0L, (char_u *)"dark", 0);
+#endif
+
+    curbuf->b_p_initialized = TRUE;
+    curbuf->b_p_ar = -1;	/* no local 'autoread' value */
+    check_buf_options(curbuf);
+    check_win_options(curwin);
+    check_options();
+
+    /* Must be before option_expand(), because that one needs vim_isIDc() */
+    didset_options();
+
+#ifdef FEAT_SPELL
+    /* Use the current chartab for the generic chartab. */
+    init_spell_chartab();
+#endif
+
+#ifdef FEAT_LINEBREAK
+    /*
+     * initialize the table for 'breakat'.
+     */
+    fill_breakat_flags();
+#endif
+
+    /*
+     * Expand environment variables and things like "~" for the defaults.
+     * If option_expand() returns non-NULL the variable is expanded.  This can
+     * only happen for non-indirect options.
+     * Also set the default to the expanded value, so ":set" does not list
+     * them.
+     * Don't set the P_ALLOCED flag, because we don't want to free the
+     * default.
+     */
+    for (opt_idx = 0; !istermoption(&options[opt_idx]); opt_idx++)
+    {
+	if ((options[opt_idx].flags & P_GETTEXT)
+					      && options[opt_idx].var != NULL)
+	    p = (char_u *)_(*(char **)options[opt_idx].var);
+	else
+	    p = option_expand(opt_idx, NULL);
+	if (p != NULL && (p = vim_strsave(p)) != NULL)
+	{
+	    *(char_u **)options[opt_idx].var = p;
+	    /* VIMEXP
+	     * Defaults for all expanded options are currently the same for Vi
+	     * and Vim.  When this changes, add some code here!  Also need to
+	     * split P_DEF_ALLOCED in two.
+	     */
+	    if (options[opt_idx].flags & P_DEF_ALLOCED)
+		vim_free(options[opt_idx].def_val[VI_DEFAULT]);
+	    options[opt_idx].def_val[VI_DEFAULT] = p;
+	    options[opt_idx].flags |= P_DEF_ALLOCED;
+	}
+    }
+
+    /* Initialize the highlight_attr[] table. */
+    highlight_changed();
+
+    save_file_ff(curbuf);	/* Buffer is unchanged */
+
+    /* Parse default for 'wildmode'  */
+    check_opt_wim();
+
+#if defined(FEAT_ARABIC)
+    /* Detect use of mlterm.
+     * Mlterm is a terminal emulator akin to xterm that has some special
+     * abilities (bidi namely).
+     * NOTE: mlterm's author is being asked to 'set' a variable
+     *       instead of an environment variable due to inheritance.
+     */
+    if (mch_getenv((char_u *)"MLTERM") != NULL)
+	set_option_value((char_u *)"tbidi", 1L, NULL, 0);
+#endif
+
+#if defined(FEAT_WINDOWS) || defined(FEAT_FOLDING)
+    /* Parse default for 'fillchars'. */
+    (void)set_chars_option(&p_fcs);
+#endif
+
+#ifdef FEAT_CLIPBOARD
+    /* Parse default for 'clipboard' */
+    (void)check_clipboard_option();
+#endif
+
+#ifdef FEAT_MBYTE
+# if defined(WIN3264) && defined(FEAT_GETTEXT)
+    /*
+     * If $LANG isn't set, try to get a good value for it.  This makes the
+     * right language be used automatically.  Don't do this for English.
+     */
+    if (mch_getenv((char_u *)"LANG") == NULL)
+    {
+	char	buf[20];
+
+	/* Could use LOCALE_SISO639LANGNAME, but it's not in Win95.
+	 * LOCALE_SABBREVLANGNAME gives us three letters, like "enu", we use
+	 * only the first two. */
+	n = GetLocaleInfo(LOCALE_USER_DEFAULT, LOCALE_SABBREVLANGNAME,
+							     (LPTSTR)buf, 20);
+	if (n >= 2 && STRNICMP(buf, "en", 2) != 0)
+	{
+	    /* There are a few exceptions (probably more) */
+	    if (STRNICMP(buf, "cht", 3) == 0 || STRNICMP(buf, "zht", 3) == 0)
+		STRCPY(buf, "zh_TW");
+	    else if (STRNICMP(buf, "chs", 3) == 0
+					      || STRNICMP(buf, "zhc", 3) == 0)
+		STRCPY(buf, "zh_CN");
+	    else if (STRNICMP(buf, "jp", 2) == 0)
+		STRCPY(buf, "ja");
+	    else
+		buf[2] = NUL;		/* truncate to two-letter code */
+	    vim_setenv("LANG", buf);
+	}
+    }
+# else
+#  ifdef MACOS_CONVERT
+    if (mch_getenv((char_u *)"LANG") == NULL)
+    {
+	char	buf[20];
+	if (LocaleRefGetPartString(NULL,
+		    kLocaleLanguageMask | kLocaleLanguageVariantMask |
+		    kLocaleRegionMask | kLocaleRegionVariantMask,
+		    sizeof buf, buf) == noErr && *buf)
+	{
+	    vim_setenv((char_u *)"LANG", (char_u *)buf);
+#   ifdef HAVE_LOCALE_H
+	    setlocale(LC_ALL, "");
+#   endif
+	}
+    }
+#  endif
+# endif
+
+    /* enc_locale() will try to find the encoding of the current locale. */
+    p = enc_locale();
+    if (p != NULL)
+    {
+	char_u *save_enc;
+
+	/* Try setting 'encoding' and check if the value is valid.
+	 * If not, go back to the default "latin1". */
+	save_enc = p_enc;
+	p_enc = p;
+	if (STRCMP(p_enc, "gb18030") == 0)
+	{
+	    /* We don't support "gb18030", but "cp936" is a good substitute
+	     * for practical purposes, thus use that.  It's not an alias to
+	     * still support conversion between gb18030 and utf-8. */
+	    p_enc = vim_strsave((char_u *)"cp936");
+	    vim_free(p);
+	}
+	if (mb_init() == NULL)
+	{
+	    opt_idx = findoption((char_u *)"encoding");
+	    if (opt_idx >= 0)
+	    {
+		options[opt_idx].def_val[VI_DEFAULT] = p_enc;
+		options[opt_idx].flags |= P_DEF_ALLOCED;
+	    }
+
+#if defined(MSDOS) || defined(MSWIN) || defined(OS2) || defined(MACOS) \
+		|| defined(VMS)
+	    if (STRCMP(p_enc, "latin1") == 0
+# ifdef FEAT_MBYTE
+		    || enc_utf8
+# endif
+		    )
+	    {
+		/* Adjust the default for 'isprint' and 'iskeyword' to match
+		 * latin1.  Also set the defaults for when 'nocompatible' is
+		 * set. */
+		set_string_option_direct((char_u *)"isp", -1,
+					      ISP_LATIN1, OPT_FREE, SID_NONE);
+		set_string_option_direct((char_u *)"isk", -1,
+					      ISK_LATIN1, OPT_FREE, SID_NONE);
+		opt_idx = findoption((char_u *)"isp");
+		if (opt_idx >= 0)
+		    options[opt_idx].def_val[VIM_DEFAULT] = ISP_LATIN1;
+		opt_idx = findoption((char_u *)"isk");
+		if (opt_idx >= 0)
+		    options[opt_idx].def_val[VIM_DEFAULT] = ISK_LATIN1;
+		(void)init_chartab();
+	    }
+#endif
+
+# if defined(WIN3264) && !defined(FEAT_GUI)
+	    /* Win32 console: When GetACP() returns a different value from
+	     * GetConsoleCP() set 'termencoding'. */
+	    if (GetACP() != GetConsoleCP())
+	    {
+		char	buf[50];
+
+		sprintf(buf, "cp%ld", (long)GetConsoleCP());
+		p_tenc = vim_strsave((char_u *)buf);
+		if (p_tenc != NULL)
+		{
+		    opt_idx = findoption((char_u *)"termencoding");
+		    if (opt_idx >= 0)
+		    {
+			options[opt_idx].def_val[VI_DEFAULT] = p_tenc;
+			options[opt_idx].flags |= P_DEF_ALLOCED;
+		    }
+		    convert_setup(&input_conv, p_tenc, p_enc);
+		    convert_setup(&output_conv, p_enc, p_tenc);
+		}
+		else
+		    p_tenc = empty_option;
+	    }
+# endif
+# if defined(WIN3264) && defined(FEAT_MBYTE)
+	    /* $HOME may have characters in active code page. */
+	    init_homedir();
+# endif
+	}
+	else
+	{
+	    vim_free(p_enc);
+	    p_enc = save_enc;
+	}
+    }
+#endif
+
+#ifdef FEAT_MULTI_LANG
+    /* Set the default for 'helplang'. */
+    set_helplang_default(get_mess_lang());
+#endif
+}
+
+/*
+ * Set an option to its default value.
+ * This does not take care of side effects!
+ */
+    static void
+set_option_default(opt_idx, opt_flags, compatible)
+    int		opt_idx;
+    int		opt_flags;	/* OPT_FREE, OPT_LOCAL and/or OPT_GLOBAL */
+    int		compatible;	/* use Vi default value */
+{
+    char_u	*varp;		/* pointer to variable for current option */
+    int		dvi;		/* index in def_val[] */
+    long_u	flags;
+    long_u	*flagsp;
+    int		both = (opt_flags & (OPT_LOCAL | OPT_GLOBAL)) == 0;
+
+    varp = get_varp_scope(&(options[opt_idx]), both ? OPT_LOCAL : opt_flags);
+    flags = options[opt_idx].flags;
+    if (varp != NULL)	    /* skip hidden option, nothing to do for it */
+    {
+	dvi = ((flags & P_VI_DEF) || compatible) ? VI_DEFAULT : VIM_DEFAULT;
+	if (flags & P_STRING)
+	{
+	    /* Use set_string_option_direct() for local options to handle
+	     * freeing and allocating the value. */
+	    if (options[opt_idx].indir != PV_NONE)
+		set_string_option_direct(NULL, opt_idx,
+				 options[opt_idx].def_val[dvi], opt_flags, 0);
+	    else
+	    {
+		if ((opt_flags & OPT_FREE) && (flags & P_ALLOCED))
+		    free_string_option(*(char_u **)(varp));
+		*(char_u **)varp = options[opt_idx].def_val[dvi];
+		options[opt_idx].flags &= ~P_ALLOCED;
+	    }
+	}
+	else if (flags & P_NUM)
+	{
+	    if (options[opt_idx].indir == PV_SCROLL)
+		win_comp_scroll(curwin);
+	    else
+	    {
+		*(long *)varp = (long)(long_i)options[opt_idx].def_val[dvi];
+		/* May also set global value for local option. */
+		if (both)
+		    *(long *)get_varp_scope(&(options[opt_idx]), OPT_GLOBAL) =
+								*(long *)varp;
+	    }
+	}
+	else	/* P_BOOL */
+	{
+	    /* the cast to long is required for Manx C, long_i is needed for
+	     * MSVC */
+	    *(int *)varp = (int)(long)(long_i)options[opt_idx].def_val[dvi];
+#ifdef UNIX
+	    /* 'modeline' defaults to off for root */
+	    if (options[opt_idx].indir == PV_ML && getuid() == ROOT_UID)
+		*(int *)varp = FALSE;
+#endif
+	    /* May also set global value for local option. */
+	    if (both)
+		*(int *)get_varp_scope(&(options[opt_idx]), OPT_GLOBAL) =
+								*(int *)varp;
+	}
+
+	/* The default value is not insecure. */
+	flagsp = insecure_flag(opt_idx, opt_flags);
+	*flagsp = *flagsp & ~P_INSECURE;
+    }
+
+#ifdef FEAT_EVAL
+    set_option_scriptID_idx(opt_idx, opt_flags, current_SID);
+#endif
+}
+
+/*
+ * Set all options (except terminal options) to their default value.
+ */
+    static void
+set_options_default(opt_flags)
+    int		opt_flags;	/* OPT_FREE, OPT_LOCAL and/or OPT_GLOBAL */
+{
+    int		i;
+#ifdef FEAT_WINDOWS
+    win_T	*wp;
+    tabpage_T	*tp;
+#endif
+
+    for (i = 0; !istermoption(&options[i]); i++)
+	if (!(options[i].flags & P_NODEFAULT))
+	    set_option_default(i, opt_flags, p_cp);
+
+#ifdef FEAT_WINDOWS
+    /* The 'scroll' option must be computed for all windows. */
+    FOR_ALL_TAB_WINDOWS(tp, wp)
+	win_comp_scroll(wp);
+#else
+	win_comp_scroll(curwin);
+#endif
+}
+
+/*
+ * Set the Vi-default value of a string option.
+ * Used for 'sh', 'backupskip' and 'term'.
+ */
+    void
+set_string_default(name, val)
+    char	*name;
+    char_u	*val;
+{
+    char_u	*p;
+    int		opt_idx;
+
+    p = vim_strsave(val);
+    if (p != NULL)		/* we don't want a NULL */
+    {
+	opt_idx = findoption((char_u *)name);
+	if (opt_idx >= 0)
+	{
+	    if (options[opt_idx].flags & P_DEF_ALLOCED)
+		vim_free(options[opt_idx].def_val[VI_DEFAULT]);
+	    options[opt_idx].def_val[VI_DEFAULT] = p;
+	    options[opt_idx].flags |= P_DEF_ALLOCED;
+	}
+    }
+}
+
+/*
+ * Set the Vi-default value of a number option.
+ * Used for 'lines' and 'columns'.
+ */
+    void
+set_number_default(name, val)
+    char	*name;
+    long	val;
+{
+    int		opt_idx;
+
+    opt_idx = findoption((char_u *)name);
+    if (opt_idx >= 0)
+	options[opt_idx].def_val[VI_DEFAULT] = (char_u *)(long_i)val;
+}
+
+#if defined(EXITFREE) || defined(PROTO)
+/*
+ * Free all options.
+ */
+    void
+free_all_options()
+{
+    int		i;
+
+    for (i = 0; !istermoption(&options[i]); i++)
+    {
+	if (options[i].indir == PV_NONE)
+	{
+	    /* global option: free value and default value. */
+	    if (options[i].flags & P_ALLOCED && options[i].var != NULL)
+		free_string_option(*(char_u **)options[i].var);
+	    if (options[i].flags & P_DEF_ALLOCED)
+		free_string_option(options[i].def_val[VI_DEFAULT]);
+	}
+	else if (options[i].var != VAR_WIN
+		&& (options[i].flags & P_STRING))
+	    /* buffer-local option: free global value */
+	    free_string_option(*(char_u **)options[i].var);
+    }
+}
+#endif
+
+
+/*
+ * Initialize the options, part two: After getting Rows and Columns and
+ * setting 'term'.
+ */
+    void
+set_init_2()
+{
+    int		idx;
+
+    /*
+     * 'scroll' defaults to half the window height. Note that this default is
+     * wrong when the window height changes.
+     */
+    set_number_default("scroll", (long)((long_u)Rows >> 1));
+    idx = findoption((char_u *)"scroll");
+    if (idx >= 0 && !(options[idx].flags & P_WAS_SET))
+	set_option_default(idx, OPT_LOCAL, p_cp);
+    comp_col();
+
+    /*
+     * 'window' is only for backwards compatibility with Vi.
+     * Default is Rows - 1.
+     */
+    if (!option_was_set((char_u *)"window"))
+	p_window = Rows - 1;
+    set_number_default("window", Rows - 1);
+
+    /* For DOS console the default is always black. */
+#if !((defined(MSDOS) || defined(OS2) || defined(WIN3264)) && !defined(FEAT_GUI))
+    /*
+     * If 'background' wasn't set by the user, try guessing the value,
+     * depending on the terminal name.  Only need to check for terminals
+     * with a dark background, that can handle color.
+     */
+    idx = findoption((char_u *)"bg");
+    if (idx >= 0 && !(options[idx].flags & P_WAS_SET)
+						 && *term_bg_default() == 'd')
+    {
+	set_string_option_direct(NULL, idx, (char_u *)"dark", OPT_FREE, 0);
+	/* don't mark it as set, when starting the GUI it may be
+	 * changed again */
+	options[idx].flags &= ~P_WAS_SET;
+    }
+#endif
+
+#ifdef CURSOR_SHAPE
+    parse_shape_opt(SHAPE_CURSOR); /* set cursor shapes from 'guicursor' */
+#endif
+#ifdef FEAT_MOUSESHAPE
+    parse_shape_opt(SHAPE_MOUSE);  /* set mouse shapes from 'mouseshape' */
+#endif
+#ifdef FEAT_PRINTER
+    (void)parse_printoptions();	    /* parse 'printoptions' default value */
+#endif
+}
+
+/*
+ * Return "dark" or "light" depending on the kind of terminal.
+ * This is just guessing!  Recognized are:
+ * "linux"	    Linux console
+ * "screen.linux"   Linux console with screen
+ * "cygwin"	    Cygwin shell
+ * "putty"	    Putty program
+ * We also check the COLORFGBG environment variable, which is set by
+ * rxvt and derivatives. This variable contains either two or three
+ * values separated by semicolons; we want the last value in either
+ * case. If this value is 0-6 or 8, our background is dark.
+ */
+    static char_u *
+term_bg_default()
+{
+#if defined(MSDOS) || defined(OS2) || defined(WIN3264)
+    /* DOS console nearly always black */
+    return (char_u *)"dark";
+#else
+    char_u	*p;
+
+    if (STRCMP(T_NAME, "linux") == 0
+	    || STRCMP(T_NAME, "screen.linux") == 0
+	    || STRCMP(T_NAME, "cygwin") == 0
+	    || STRCMP(T_NAME, "putty") == 0
+	    || ((p = mch_getenv((char_u *)"COLORFGBG")) != NULL
+		&& (p = vim_strrchr(p, ';')) != NULL
+		&& ((p[1] >= '0' && p[1] <= '6') || p[1] == '8')
+		&& p[2] == NUL))
+	return (char_u *)"dark";
+    return (char_u *)"light";
+#endif
+}
+
+/*
+ * Initialize the options, part three: After reading the .vimrc
+ */
+    void
+set_init_3()
+{
+#if defined(UNIX) || defined(OS2) || defined(WIN3264)
+/*
+ * Set 'shellpipe' and 'shellredir', depending on the 'shell' option.
+ * This is done after other initializations, where 'shell' might have been
+ * set, but only if they have not been set before.
+ */
+    char_u  *p;
+    int	    idx_srr;
+    int	    do_srr;
+#ifdef FEAT_QUICKFIX
+    int	    idx_sp;
+    int	    do_sp;
+#endif
+
+    idx_srr = findoption((char_u *)"srr");
+    if (idx_srr < 0)
+	do_srr = FALSE;
+    else
+	do_srr = !(options[idx_srr].flags & P_WAS_SET);
+#ifdef FEAT_QUICKFIX
+    idx_sp = findoption((char_u *)"sp");
+    if (idx_sp < 0)
+	do_sp = FALSE;
+    else
+	do_sp = !(options[idx_sp].flags & P_WAS_SET);
+#endif
+
+    /*
+     * Isolate the name of the shell:
+     * - Skip beyond any path.  E.g., "/usr/bin/csh -f" -> "csh -f".
+     * - Remove any argument.  E.g., "csh -f" -> "csh".
+     */
+    p = gettail(p_sh);
+    p = vim_strnsave(p, (int)(skiptowhite(p) - p));
+    if (p != NULL)
+    {
+	/*
+	 * Default for p_sp is "| tee", for p_srr is ">".
+	 * For known shells it is changed here to include stderr.
+	 */
+	if (	   fnamecmp(p, "csh") == 0
+		|| fnamecmp(p, "tcsh") == 0
+# if defined(OS2) || defined(WIN3264)	/* also check with .exe extension */
+		|| fnamecmp(p, "csh.exe") == 0
+		|| fnamecmp(p, "tcsh.exe") == 0
+# endif
+	   )
+	{
+#if defined(FEAT_QUICKFIX)
+	    if (do_sp)
+	    {
+# ifdef WIN3264
+		p_sp = (char_u *)">&";
+# else
+		p_sp = (char_u *)"|& tee";
+# endif
+		options[idx_sp].def_val[VI_DEFAULT] = p_sp;
+	    }
+#endif
+	    if (do_srr)
+	    {
+		p_srr = (char_u *)">&";
+		options[idx_srr].def_val[VI_DEFAULT] = p_srr;
+	    }
+	}
+	else
+# ifndef OS2	/* Always use bourne shell style redirection if we reach this */
+	    if (       fnamecmp(p, "sh") == 0
+		    || fnamecmp(p, "ksh") == 0
+		    || fnamecmp(p, "zsh") == 0
+		    || fnamecmp(p, "zsh-beta") == 0
+		    || fnamecmp(p, "bash") == 0
+#  ifdef WIN3264
+		    || fnamecmp(p, "cmd") == 0
+		    || fnamecmp(p, "sh.exe") == 0
+		    || fnamecmp(p, "ksh.exe") == 0
+		    || fnamecmp(p, "zsh.exe") == 0
+		    || fnamecmp(p, "zsh-beta.exe") == 0
+		    || fnamecmp(p, "bash.exe") == 0
+		    || fnamecmp(p, "cmd.exe") == 0
+#  endif
+		    )
+# endif
+	    {
+#if defined(FEAT_QUICKFIX)
+		if (do_sp)
+		{
+# ifdef WIN3264
+		    p_sp = (char_u *)">%s 2>&1";
+# else
+		    p_sp = (char_u *)"2>&1| tee";
+# endif
+		    options[idx_sp].def_val[VI_DEFAULT] = p_sp;
+		}
+#endif
+		if (do_srr)
+		{
+		    p_srr = (char_u *)">%s 2>&1";
+		    options[idx_srr].def_val[VI_DEFAULT] = p_srr;
+		}
+	    }
+	vim_free(p);
+    }
+#endif
+
+#if defined(MSDOS) || defined(WIN3264) || defined(OS2)
+    /*
+     * Set 'shellcmdflag and 'shellquote' depending on the 'shell' option.
+     * This is done after other initializations, where 'shell' might have been
+     * set, but only if they have not been set before.  Default for p_shcf is
+     * "/c", for p_shq is "".  For "sh" like  shells it is changed here to
+     * "-c" and "\"", but not for DJGPP, because it starts the shell without
+     * command.com.  And for Win32 we need to set p_sxq instead.
+     */
+    if (strstr((char *)gettail(p_sh), "sh") != NULL)
+    {
+	int	idx3;
+
+	idx3 = findoption((char_u *)"shcf");
+	if (idx3 >= 0 && !(options[idx3].flags & P_WAS_SET))
+	{
+	    p_shcf = (char_u *)"-c";
+	    options[idx3].def_val[VI_DEFAULT] = p_shcf;
+	}
+
+# ifndef DJGPP
+#  ifdef WIN3264
+	/* Somehow Win32 requires the quotes around the redirection too */
+	idx3 = findoption((char_u *)"sxq");
+	if (idx3 >= 0 && !(options[idx3].flags & P_WAS_SET))
+	{
+	    p_sxq = (char_u *)"\"";
+	    options[idx3].def_val[VI_DEFAULT] = p_sxq;
+	}
+#  else
+	idx3 = findoption((char_u *)"shq");
+	if (idx3 >= 0 && !(options[idx3].flags & P_WAS_SET))
+	{
+	    p_shq = (char_u *)"\"";
+	    options[idx3].def_val[VI_DEFAULT] = p_shq;
+	}
+#  endif
+# endif
+    }
+#endif
+
+#ifdef FEAT_TITLE
+    set_title_defaults();
+#endif
+}
+
+#if defined(FEAT_MULTI_LANG) || defined(PROTO)
+/*
+ * When 'helplang' is still at its default value, set it to "lang".
+ * Only the first two characters of "lang" are used.
+ */
+    void
+set_helplang_default(lang)
+    char_u	*lang;
+{
+    int		idx;
+
+    if (lang == NULL || STRLEN(lang) < 2)	/* safety check */
+	return;
+    idx = findoption((char_u *)"hlg");
+    if (idx >= 0 && !(options[idx].flags & P_WAS_SET))
+    {
+	if (options[idx].flags & P_ALLOCED)
+	    free_string_option(p_hlg);
+	p_hlg = vim_strsave(lang);
+	if (p_hlg == NULL)
+	    p_hlg = empty_option;
+	else
+	{
+	    /* zh_CN becomes "cn", zh_TW becomes "tw". */
+	    if (STRNICMP(p_hlg, "zh_", 3) == 0 && STRLEN(p_hlg) >= 5)
+	    {
+		p_hlg[0] = TOLOWER_ASC(p_hlg[3]);
+		p_hlg[1] = TOLOWER_ASC(p_hlg[4]);
+	    }
+	    p_hlg[2] = NUL;
+	}
+	options[idx].flags |= P_ALLOCED;
+    }
+}
+#endif
+
+#ifdef FEAT_GUI
+static char_u *gui_bg_default __ARGS((void));
+
+    static char_u *
+gui_bg_default()
+{
+    if (gui_get_lightness(gui.back_pixel) < 127)
+	return (char_u *)"dark";
+    return (char_u *)"light";
+}
+
+/*
+ * Option initializations that can only be done after opening the GUI window.
+ */
+    void
+init_gui_options()
+{
+    /* Set the 'background' option according to the lightness of the
+     * background color, unless the user has set it already. */
+    if (!option_was_set((char_u *)"bg") && STRCMP(p_bg, gui_bg_default()) != 0)
+    {
+	set_option_value((char_u *)"bg", 0L, gui_bg_default(), 0);
+	highlight_changed();
+    }
+}
+#endif
+
+#ifdef FEAT_TITLE
+/*
+ * 'title' and 'icon' only default to true if they have not been set or reset
+ * in .vimrc and we can read the old value.
+ * When 'title' and 'icon' have been reset in .vimrc, we won't even check if
+ * they can be reset.  This reduces startup time when using X on a remote
+ * machine.
+ */
+    void
+set_title_defaults()
+{
+    int	    idx1;
+    long    val;
+
+    /*
+     * If GUI is (going to be) used, we can always set the window title and
+     * icon name.  Saves a bit of time, because the X11 display server does
+     * not need to be contacted.
+     */
+    idx1 = findoption((char_u *)"title");
+    if (idx1 >= 0 && !(options[idx1].flags & P_WAS_SET))
+    {
+#ifdef FEAT_GUI
+	if (gui.starting || gui.in_use)
+	    val = TRUE;
+	else
+#endif
+	    val = mch_can_restore_title();
+	options[idx1].def_val[VI_DEFAULT] = (char_u *)(long_i)val;
+	p_title = val;
+    }
+    idx1 = findoption((char_u *)"icon");
+    if (idx1 >= 0 && !(options[idx1].flags & P_WAS_SET))
+    {
+#ifdef FEAT_GUI
+	if (gui.starting || gui.in_use)
+	    val = TRUE;
+	else
+#endif
+	    val = mch_can_restore_icon();
+	options[idx1].def_val[VI_DEFAULT] = (char_u *)(long_i)val;
+	p_icon = val;
+    }
+}
+#endif
+
+/*
+ * Parse 'arg' for option settings.
+ *
+ * 'arg' may be IObuff, but only when no errors can be present and option
+ * does not need to be expanded with option_expand().
+ * "opt_flags":
+ * 0 for ":set"
+ * OPT_GLOBAL   for ":setglobal"
+ * OPT_LOCAL    for ":setlocal" and a modeline
+ * OPT_MODELINE for a modeline
+ * OPT_WINONLY  to only set window-local options
+ * OPT_NOWIN	to skip setting window-local options
+ *
+ * returns FAIL if an error is detected, OK otherwise
+ */
+    int
+do_set(arg, opt_flags)
+    char_u	*arg;		/* option string (may be written to!) */
+    int		opt_flags;
+{
+    int		opt_idx;
+    char_u	*errmsg;
+    char_u	errbuf[80];
+    char_u	*startarg;
+    int		prefix;	/* 1: nothing, 0: "no", 2: "inv" in front of name */
+    int		nextchar;	    /* next non-white char after option name */
+    int		afterchar;	    /* character just after option name */
+    int		len;
+    int		i;
+    long	value;
+    int		key;
+    long_u	flags;		    /* flags for current option */
+    char_u	*varp = NULL;	    /* pointer to variable for current option */
+    int		did_show = FALSE;   /* already showed one value */
+    int		adding;		    /* "opt+=arg" */
+    int		prepending;	    /* "opt^=arg" */
+    int		removing;	    /* "opt-=arg" */
+    int		cp_val = 0;
+    char_u	key_name[2];
+
+    if (*arg == NUL)
+    {
+	showoptions(0, opt_flags);
+	did_show = TRUE;
+	goto theend;
+    }
+
+    while (*arg != NUL)		/* loop to process all options */
+    {
+	errmsg = NULL;
+	startarg = arg;		/* remember for error message */
+
+	if (STRNCMP(arg, "all", 3) == 0 && !isalpha(arg[3])
+						&& !(opt_flags & OPT_MODELINE))
+	{
+	    /*
+	     * ":set all"  show all options.
+	     * ":set all&" set all options to their default value.
+	     */
+	    arg += 3;
+	    if (*arg == '&')
+	    {
+		++arg;
+		/* Only for :set command set global value of local options. */
+		set_options_default(OPT_FREE | opt_flags);
+	    }
+	    else
+	    {
+		showoptions(1, opt_flags);
+		did_show = TRUE;
+	    }
+	}
+	else if (STRNCMP(arg, "termcap", 7) == 0 && !(opt_flags & OPT_MODELINE))
+	{
+	    showoptions(2, opt_flags);
+	    show_termcodes();
+	    did_show = TRUE;
+	    arg += 7;
+	}
+	else
+	{
+	    prefix = 1;
+	    if (STRNCMP(arg, "no", 2) == 0)
+	    {
+		prefix = 0;
+		arg += 2;
+	    }
+	    else if (STRNCMP(arg, "inv", 3) == 0)
+	    {
+		prefix = 2;
+		arg += 3;
+	    }
+
+	    /* find end of name */
+	    key = 0;
+	    if (*arg == '<')
+	    {
+		nextchar = 0;
+		opt_idx = -1;
+		/* look out for <t_>;> */
+		if (arg[1] == 't' && arg[2] == '_' && arg[3] && arg[4])
+		    len = 5;
+		else
+		{
+		    len = 1;
+		    while (arg[len] != NUL && arg[len] != '>')
+			++len;
+		}
+		if (arg[len] != '>')
+		{
+		    errmsg = e_invarg;
+		    goto skip;
+		}
+		arg[len] = NUL;			    /* put NUL after name */
+		if (arg[1] == 't' && arg[2] == '_') /* could be term code */
+		    opt_idx = findoption(arg + 1);
+		arg[len++] = '>';		    /* restore '>' */
+		if (opt_idx == -1)
+		    key = find_key_option(arg + 1);
+	    }
+	    else
+	    {
+		len = 0;
+		/*
+		 * The two characters after "t_" may not be alphanumeric.
+		 */
+		if (arg[0] == 't' && arg[1] == '_' && arg[2] && arg[3])
+		    len = 4;
+		else
+		    while (ASCII_ISALNUM(arg[len]) || arg[len] == '_')
+			++len;
+		nextchar = arg[len];
+		arg[len] = NUL;			    /* put NUL after name */
+		opt_idx = findoption(arg);
+		arg[len] = nextchar;		    /* restore nextchar */
+		if (opt_idx == -1)
+		    key = find_key_option(arg);
+	    }
+
+	    /* remember character after option name */
+	    afterchar = arg[len];
+
+	    /* skip white space, allow ":set ai  ?" */
+	    while (vim_iswhite(arg[len]))
+		++len;
+
+	    adding = FALSE;
+	    prepending = FALSE;
+	    removing = FALSE;
+	    if (arg[len] != NUL && arg[len + 1] == '=')
+	    {
+		if (arg[len] == '+')
+		{
+		    adding = TRUE;		/* "+=" */
+		    ++len;
+		}
+		else if (arg[len] == '^')
+		{
+		    prepending = TRUE;		/* "^=" */
+		    ++len;
+		}
+		else if (arg[len] == '-')
+		{
+		    removing = TRUE;		/* "-=" */
+		    ++len;
+		}
+	    }
+	    nextchar = arg[len];
+
+	    if (opt_idx == -1 && key == 0)	/* found a mismatch: skip */
+	    {
+		errmsg = (char_u *)N_("E518: Unknown option");
+		goto skip;
+	    }
+
+	    if (opt_idx >= 0)
+	    {
+		if (options[opt_idx].var == NULL)   /* hidden option: skip */
+		{
+		    /* Only give an error message when requesting the value of
+		     * a hidden option, ignore setting it. */
+		    if (vim_strchr((char_u *)"=:!&<", nextchar) == NULL
+			    && (!(options[opt_idx].flags & P_BOOL)
+				|| nextchar == '?'))
+			errmsg = (char_u *)N_("E519: Option not supported");
+		    goto skip;
+		}
+
+		flags = options[opt_idx].flags;
+		varp = get_varp_scope(&(options[opt_idx]), opt_flags);
+	    }
+	    else
+	    {
+		flags = P_STRING;
+		if (key < 0)
+		{
+		    key_name[0] = KEY2TERMCAP0(key);
+		    key_name[1] = KEY2TERMCAP1(key);
+		}
+		else
+		{
+		    key_name[0] = KS_KEY;
+		    key_name[1] = (key & 0xff);
+		}
+	    }
+
+	    /* Skip all options that are not window-local (used when showing
+	     * an already loaded buffer in a window). */
+	    if ((opt_flags & OPT_WINONLY)
+			  && (opt_idx < 0 || options[opt_idx].var != VAR_WIN))
+		goto skip;
+
+	    /* Skip all options that are window-local (used for :vimgrep). */
+	    if ((opt_flags & OPT_NOWIN) && opt_idx >= 0
+					   && options[opt_idx].var == VAR_WIN)
+		goto skip;
+
+	    /* Disallow changing some options from modelines */
+	    if ((opt_flags & OPT_MODELINE) && (flags & P_SECURE))
+	    {
+		errmsg = (char_u *)_("E520: Not allowed in a modeline");
+		goto skip;
+	    }
+
+#ifdef HAVE_SANDBOX
+	    /* Disallow changing some options in the sandbox */
+	    if (sandbox != 0 && (flags & P_SECURE))
+	    {
+		errmsg = (char_u *)_(e_sandbox);
+		goto skip;
+	    }
+#endif
+
+	    if (vim_strchr((char_u *)"?=:!&<", nextchar) != NULL)
+	    {
+		arg += len;
+		cp_val = p_cp;
+		if (nextchar == '&' && arg[1] == 'v' && arg[2] == 'i')
+		{
+		    if (arg[3] == 'm')	/* "opt&vim": set to Vim default */
+		    {
+			cp_val = FALSE;
+			arg += 3;
+		    }
+		    else		/* "opt&vi": set to Vi default */
+		    {
+			cp_val = TRUE;
+			arg += 2;
+		    }
+		}
+		if (vim_strchr((char_u *)"?!&<", nextchar) != NULL
+			&& arg[1] != NUL && !vim_iswhite(arg[1]))
+		{
+		    errmsg = e_trailing;
+		    goto skip;
+		}
+	    }
+
+	    /*
+	     * allow '=' and ':' as MSDOS command.com allows only one
+	     * '=' character per "set" command line. grrr. (jw)
+	     */
+	    if (nextchar == '?'
+		    || (prefix == 1
+			&& vim_strchr((char_u *)"=:&<", nextchar) == NULL
+			&& !(flags & P_BOOL)))
+	    {
+		/*
+		 * print value
+		 */
+		if (did_show)
+		    msg_putchar('\n');	    /* cursor below last one */
+		else
+		{
+		    gotocmdline(TRUE);	    /* cursor at status line */
+		    did_show = TRUE;	    /* remember that we did a line */
+		}
+		if (opt_idx >= 0)
+		{
+		    showoneopt(&options[opt_idx], opt_flags);
+#ifdef FEAT_EVAL
+		    if (p_verbose > 0)
+		    {
+			/* Mention where the option was last set. */
+			if (varp == options[opt_idx].var)
+			    last_set_msg(options[opt_idx].scriptID);
+			else if ((int)options[opt_idx].indir & PV_WIN)
+			    last_set_msg(curwin->w_p_scriptID[
+				      (int)options[opt_idx].indir & PV_MASK]);
+			else if ((int)options[opt_idx].indir & PV_BUF)
+			    last_set_msg(curbuf->b_p_scriptID[
+				      (int)options[opt_idx].indir & PV_MASK]);
+		    }
+#endif
+		}
+		else
+		{
+		    char_u	    *p;
+
+		    p = find_termcode(key_name);
+		    if (p == NULL)
+		    {
+			errmsg = (char_u *)N_("E518: Unknown option");
+			goto skip;
+		    }
+		    else
+			(void)show_one_termcode(key_name, p, TRUE);
+		}
+		if (nextchar != '?'
+			&& nextchar != NUL && !vim_iswhite(afterchar))
+		    errmsg = e_trailing;
+	    }
+	    else
+	    {
+		if (flags & P_BOOL)		    /* boolean */
+		{
+		    if (nextchar == '=' || nextchar == ':')
+		    {
+			errmsg = e_invarg;
+			goto skip;
+		    }
+
+		    /*
+		     * ":set opt!": invert
+		     * ":set opt&": reset to default value
+		     * ":set opt<": reset to global value
+		     */
+		    if (nextchar == '!')
+			value = *(int *)(varp) ^ 1;
+		    else if (nextchar == '&')
+			value = (int)(long)(long_i)options[opt_idx].def_val[
+						((flags & P_VI_DEF) || cp_val)
+						 ?  VI_DEFAULT : VIM_DEFAULT];
+		    else if (nextchar == '<')
+		    {
+			/* For 'autoread' -1 means to use global value. */
+			if ((int *)varp == &curbuf->b_p_ar
+						    && opt_flags == OPT_LOCAL)
+			    value = -1;
+			else
+			    value = *(int *)get_varp_scope(&(options[opt_idx]),
+								  OPT_GLOBAL);
+		    }
+		    else
+		    {
+			/*
+			 * ":set invopt": invert
+			 * ":set opt" or ":set noopt": set or reset
+			 */
+			if (nextchar != NUL && !vim_iswhite(afterchar))
+			{
+			    errmsg = e_trailing;
+			    goto skip;
+			}
+			if (prefix == 2)	/* inv */
+			    value = *(int *)(varp) ^ 1;
+			else
+			    value = prefix;
+		    }
+
+		    errmsg = set_bool_option(opt_idx, varp, (int)value,
+								   opt_flags);
+		}
+		else				    /* numeric or string */
+		{
+		    if (vim_strchr((char_u *)"=:&<", nextchar) == NULL
+							       || prefix != 1)
+		    {
+			errmsg = e_invarg;
+			goto skip;
+		    }
+
+		    if (flags & P_NUM)		    /* numeric */
+		    {
+			/*
+			 * Different ways to set a number option:
+			 * &	    set to default value
+			 * <	    set to global value
+			 * <xx>	    accept special key codes for 'wildchar'
+			 * c	    accept any non-digit for 'wildchar'
+			 * [-]0-9   set number
+			 * other    error
+			 */
+			++arg;
+			if (nextchar == '&')
+			    value = (long)(long_i)options[opt_idx].def_val[
+						((flags & P_VI_DEF) || cp_val)
+						 ?  VI_DEFAULT : VIM_DEFAULT];
+			else if (nextchar == '<')
+			    value = *(long *)get_varp_scope(&(options[opt_idx]),
+								  OPT_GLOBAL);
+			else if (((long *)varp == &p_wc
+				    || (long *)varp == &p_wcm)
+				&& (*arg == '<'
+				    || *arg == '^'
+				    || ((!arg[1] || vim_iswhite(arg[1]))
+					&& !VIM_ISDIGIT(*arg))))
+			{
+			    value = string_to_key(arg);
+			    if (value == 0 && (long *)varp != &p_wcm)
+			    {
+				errmsg = e_invarg;
+				goto skip;
+			    }
+			}
+				/* allow negative numbers (for 'undolevels') */
+			else if (*arg == '-' || VIM_ISDIGIT(*arg))
+			{
+			    i = 0;
+			    if (*arg == '-')
+				i = 1;
+#ifdef HAVE_STRTOL
+			    value = strtol((char *)arg, NULL, 0);
+			    if (arg[i] == '0' && TOLOWER_ASC(arg[i + 1]) == 'x')
+				i += 2;
+#else
+			    value = atol((char *)arg);
+#endif
+			    while (VIM_ISDIGIT(arg[i]))
+				++i;
+			    if (arg[i] != NUL && !vim_iswhite(arg[i]))
+			    {
+				errmsg = e_invarg;
+				goto skip;
+			    }
+			}
+			else
+			{
+			    errmsg = (char_u *)N_("E521: Number required after =");
+			    goto skip;
+			}
+
+			if (adding)
+			    value = *(long *)varp + value;
+			if (prepending)
+			    value = *(long *)varp * value;
+			if (removing)
+			    value = *(long *)varp - value;
+			errmsg = set_num_option(opt_idx, varp, value,
+					   errbuf, sizeof(errbuf), opt_flags);
+		    }
+		    else if (opt_idx >= 0)		    /* string */
+		    {
+			char_u	    *save_arg = NULL;
+			char_u	    *s = NULL;
+			char_u	    *oldval;	/* previous value if *varp */
+			char_u	    *newval;
+			char_u	    *origval;
+			unsigned    newlen;
+			int	    comma;
+			int	    bs;
+			int	    new_value_alloced;	/* new string option
+							   was allocated */
+
+			/* When using ":set opt=val" for a global option
+			 * with a local value the local value will be
+			 * reset, use the global value here. */
+			if ((opt_flags & (OPT_LOCAL | OPT_GLOBAL)) == 0
+				&& ((int)options[opt_idx].indir & PV_BOTH))
+			    varp = options[opt_idx].var;
+
+			/* The old value is kept until we are sure that the
+			 * new value is valid. */
+			oldval = *(char_u **)varp;
+			if (nextchar == '&')	/* set to default val */
+			{
+			    newval = options[opt_idx].def_val[
+						((flags & P_VI_DEF) || cp_val)
+						 ?  VI_DEFAULT : VIM_DEFAULT];
+			    if ((char_u **)varp == &p_bg)
+			    {
+				/* guess the value of 'background' */
+#ifdef FEAT_GUI
+				if (gui.in_use)
+				    newval = gui_bg_default();
+				else
+#endif
+				    newval = term_bg_default();
+			    }
+
+			    /* expand environment variables and ~ (since the
+			     * default value was already expanded, only
+			     * required when an environment variable was set
+			     * later */
+			    if (newval == NULL)
+				newval = empty_option;
+			    else
+			    {
+				s = option_expand(opt_idx, newval);
+				if (s == NULL)
+				    s = newval;
+				newval = vim_strsave(s);
+			    }
+			    new_value_alloced = TRUE;
+			}
+			else if (nextchar == '<')	/* set to global val */
+			{
+			    newval = vim_strsave(*(char_u **)get_varp_scope(
+					     &(options[opt_idx]), OPT_GLOBAL));
+			    new_value_alloced = TRUE;
+			}
+			else
+			{
+			    ++arg;	/* jump to after the '=' or ':' */
+
+			    /*
+			     * Set 'keywordprg' to ":help" if an empty
+			     * value was passed to :set by the user.
+			     * Misuse errbuf[] for the resulting string.
+			     */
+			    if (varp == (char_u *)&p_kp
+					      && (*arg == NUL || *arg == ' '))
+			    {
+				STRCPY(errbuf, ":help");
+				save_arg = arg;
+				arg = errbuf;
+			    }
+			    /*
+			     * Convert 'whichwrap' number to string, for
+			     * backwards compatibility with Vim 3.0.
+			     * Misuse errbuf[] for the resulting string.
+			     */
+			    else if (varp == (char_u *)&p_ww
+							 && VIM_ISDIGIT(*arg))
+			    {
+				*errbuf = NUL;
+				i = getdigits(&arg);
+				if (i & 1)
+				    STRCAT(errbuf, "b,");
+				if (i & 2)
+				    STRCAT(errbuf, "s,");
+				if (i & 4)
+				    STRCAT(errbuf, "h,l,");
+				if (i & 8)
+				    STRCAT(errbuf, "<,>,");
+				if (i & 16)
+				    STRCAT(errbuf, "[,],");
+				if (*errbuf != NUL)	/* remove trailing , */
+				    errbuf[STRLEN(errbuf) - 1] = NUL;
+				save_arg = arg;
+				arg = errbuf;
+			    }
+			    /*
+			     * Remove '>' before 'dir' and 'bdir', for
+			     * backwards compatibility with version 3.0
+			     */
+			    else if (  *arg == '>'
+				    && (varp == (char_u *)&p_dir
+					    || varp == (char_u *)&p_bdir))
+			    {
+				++arg;
+			    }
+
+			    /* When setting the local value of a global
+			     * option, the old value may be the global value. */
+			    if (((int)options[opt_idx].indir & PV_BOTH)
+						   && (opt_flags & OPT_LOCAL))
+				origval = *(char_u **)get_varp(
+							   &options[opt_idx]);
+			    else
+				origval = oldval;
+
+			    /*
+			     * Copy the new string into allocated memory.
+			     * Can't use set_string_option_direct(), because
+			     * we need to remove the backslashes.
+			     */
+			    /* get a bit too much */
+			    newlen = (unsigned)STRLEN(arg) + 1;
+			    if (adding || prepending || removing)
+				newlen += (unsigned)STRLEN(origval) + 1;
+			    newval = alloc(newlen);
+			    if (newval == NULL)  /* out of mem, don't change */
+				break;
+			    s = newval;
+
+			    /*
+			     * Copy the string, skip over escaped chars.
+			     * For MS-DOS and WIN32 backslashes before normal
+			     * file name characters are not removed, and keep
+			     * backslash at start, for "\\machine\path", but
+			     * do remove it for "\\\\machine\\path".
+			     * The reverse is found in ExpandOldSetting().
+			     */
+			    while (*arg && !vim_iswhite(*arg))
+			    {
+				if (*arg == '\\' && arg[1] != NUL
+#ifdef BACKSLASH_IN_FILENAME
+					&& !((flags & P_EXPAND)
+						&& vim_isfilec(arg[1])
+						&& (arg[1] != '\\'
+						    || (s == newval
+							&& arg[2] != '\\')))
+#endif
+								    )
+				    ++arg;	/* remove backslash */
+#ifdef FEAT_MBYTE
+				if (has_mbyte
+					&& (i = (*mb_ptr2len)(arg)) > 1)
+				{
+				    /* copy multibyte char */
+				    mch_memmove(s, arg, (size_t)i);
+				    arg += i;
+				    s += i;
+				}
+				else
+#endif
+				    *s++ = *arg++;
+			    }
+			    *s = NUL;
+
+			    /*
+			     * Expand environment variables and ~.
+			     * Don't do it when adding without inserting a
+			     * comma.
+			     */
+			    if (!(adding || prepending || removing)
+							 || (flags & P_COMMA))
+			    {
+				s = option_expand(opt_idx, newval);
+				if (s != NULL)
+				{
+				    vim_free(newval);
+				    newlen = (unsigned)STRLEN(s) + 1;
+				    if (adding || prepending || removing)
+					newlen += (unsigned)STRLEN(origval) + 1;
+				    newval = alloc(newlen);
+				    if (newval == NULL)
+					break;
+				    STRCPY(newval, s);
+				}
+			    }
+
+			    /* locate newval[] in origval[] when removing it
+			     * and when adding to avoid duplicates */
+			    i = 0;	/* init for GCC */
+			    if (removing || (flags & P_NODUP))
+			    {
+				i = (int)STRLEN(newval);
+				bs = 0;
+				for (s = origval; *s; ++s)
+				{
+				    if ((!(flags & P_COMMA)
+						|| s == origval
+						|| (s[-1] == ',' && !(bs & 1)))
+					    && STRNCMP(s, newval, i) == 0
+					    && (!(flags & P_COMMA)
+						|| s[i] == ','
+						|| s[i] == NUL))
+					break;
+				    /* Count backspaces.  Only a comma with an
+				     * even number of backspaces before it is
+				     * recognized as a separator */
+				    if (s > origval && s[-1] == '\\')
+					++bs;
+				    else
+					bs = 0;
+				}
+
+				/* do not add if already there */
+				if ((adding || prepending) && *s)
+				{
+				    prepending = FALSE;
+				    adding = FALSE;
+				    STRCPY(newval, origval);
+				}
+			    }
+
+			    /* concatenate the two strings; add a ',' if
+			     * needed */
+			    if (adding || prepending)
+			    {
+				comma = ((flags & P_COMMA) && *origval != NUL
+							   && *newval != NUL);
+				if (adding)
+				{
+				    i = (int)STRLEN(origval);
+				    mch_memmove(newval + i + comma, newval,
+							  STRLEN(newval) + 1);
+				    mch_memmove(newval, origval, (size_t)i);
+				}
+				else
+				{
+				    i = (int)STRLEN(newval);
+				    mch_memmove(newval + i + comma, origval,
+							  STRLEN(origval) + 1);
+				}
+				if (comma)
+				    newval[i] = ',';
+			    }
+
+			    /* Remove newval[] from origval[]. (Note: "i" has
+			     * been set above and is used here). */
+			    if (removing)
+			    {
+				STRCPY(newval, origval);
+				if (*s)
+				{
+				    /* may need to remove a comma */
+				    if (flags & P_COMMA)
+				    {
+					if (s == origval)
+					{
+					    /* include comma after string */
+					    if (s[i] == ',')
+						++i;
+					}
+					else
+					{
+					    /* include comma before string */
+					    --s;
+					    ++i;
+					}
+				    }
+				    mch_memmove(newval + (s - origval), s + i,
+							   STRLEN(s + i) + 1);
+				}
+			    }
+
+			    if (flags & P_FLAGLIST)
+			    {
+				/* Remove flags that appear twice. */
+				for (s = newval; *s; ++s)
+				    if ((!(flags & P_COMMA) || *s != ',')
+					    && vim_strchr(s + 1, *s) != NULL)
+				    {
+					STRCPY(s, s + 1);
+					--s;
+				    }
+			    }
+
+			    if (save_arg != NULL)   /* number for 'whichwrap' */
+				arg = save_arg;
+			    new_value_alloced = TRUE;
+			}
+
+			/* Set the new value. */
+			*(char_u **)(varp) = newval;
+
+			/* Handle side effects, and set the global value for
+			 * ":set" on local options. */
+			errmsg = did_set_string_option(opt_idx, (char_u **)varp,
+				new_value_alloced, oldval, errbuf, opt_flags);
+
+			/* If error detected, print the error message. */
+			if (errmsg != NULL)
+			    goto skip;
+		    }
+		    else	    /* key code option */
+		    {
+			char_u	    *p;
+
+			if (nextchar == '&')
+			{
+			    if (add_termcap_entry(key_name, TRUE) == FAIL)
+				errmsg = (char_u *)N_("E522: Not found in termcap");
+			}
+			else
+			{
+			    ++arg; /* jump to after the '=' or ':' */
+			    for (p = arg; *p && !vim_iswhite(*p); ++p)
+				if (*p == '\\' && p[1] != NUL)
+				    ++p;
+			    nextchar = *p;
+			    *p = NUL;
+			    add_termcode(key_name, arg, FALSE);
+			    *p = nextchar;
+			}
+			if (full_screen)
+			    ttest(FALSE);
+			redraw_all_later(CLEAR);
+		    }
+		}
+
+		if (opt_idx >= 0)
+		    did_set_option(opt_idx, opt_flags,
+					 !prepending && !adding && !removing);
+	    }
+
+skip:
+	    /*
+	     * Advance to next argument.
+	     * - skip until a blank found, taking care of backslashes
+	     * - skip blanks
+	     * - skip one "=val" argument (for hidden options ":set gfn =xx")
+	     */
+	    for (i = 0; i < 2 ; ++i)
+	    {
+		while (*arg != NUL && !vim_iswhite(*arg))
+		    if (*arg++ == '\\' && *arg != NUL)
+			++arg;
+		arg = skipwhite(arg);
+		if (*arg != '=')
+		    break;
+	    }
+	}
+
+	if (errmsg != NULL)
+	{
+	    vim_strncpy(IObuff, (char_u *)_(errmsg), IOSIZE - 1);
+	    i = (int)STRLEN(IObuff) + 2;
+	    if (i + (arg - startarg) < IOSIZE)
+	    {
+		/* append the argument with the error */
+		STRCAT(IObuff, ": ");
+		mch_memmove(IObuff + i, startarg, (arg - startarg));
+		IObuff[i + (arg - startarg)] = NUL;
+	    }
+	    /* make sure all characters are printable */
+	    trans_characters(IObuff, IOSIZE);
+
+	    ++no_wait_return;	/* wait_return done later */
+	    emsg(IObuff);	/* show error highlighted */
+	    --no_wait_return;
+
+	    return FAIL;
+	}
+
+	arg = skipwhite(arg);
+    }
+
+theend:
+    if (silent_mode && did_show)
+    {
+	/* After displaying option values in silent mode. */
+	silent_mode = FALSE;
+	info_message = TRUE;	/* use mch_msg(), not mch_errmsg() */
+	msg_putchar('\n');
+	cursor_on();		/* msg_start() switches it off */
+	out_flush();
+	silent_mode = TRUE;
+	info_message = FALSE;	/* use mch_msg(), not mch_errmsg() */
+    }
+
+    return OK;
+}
+
+/*
+ * Call this when an option has been given a new value through a user command.
+ * Sets the P_WAS_SET flag and takes care of the P_INSECURE flag.
+ */
+    static void
+did_set_option(opt_idx, opt_flags, new_value)
+    int	    opt_idx;
+    int	    opt_flags;	    /* possibly with OPT_MODELINE */
+    int	    new_value;	    /* value was replaced completely */
+{
+    long_u	*p;
+
+    options[opt_idx].flags |= P_WAS_SET;
+
+    /* When an option is set in the sandbox, from a modeline or in secure mode
+     * set the P_INSECURE flag.  Otherwise, if a new value is stored reset the
+     * flag. */
+    p = insecure_flag(opt_idx, opt_flags);
+    if (secure
+#ifdef HAVE_SANDBOX
+	    || sandbox != 0
+#endif
+	    || (opt_flags & OPT_MODELINE))
+	*p = *p | P_INSECURE;
+    else if (new_value)
+	*p = *p & ~P_INSECURE;
+}
+
+    static char_u *
+illegal_char(errbuf, c)
+    char_u	*errbuf;
+    int		c;
+{
+    if (errbuf == NULL)
+	return (char_u *)"";
+    sprintf((char *)errbuf, _("E539: Illegal character <%s>"),
+							(char *)transchar(c));
+    return errbuf;
+}
+
+/*
+ * Convert a key name or string into a key value.
+ * Used for 'wildchar' and 'cedit' options.
+ */
+    static int
+string_to_key(arg)
+    char_u	*arg;
+{
+    if (*arg == '<')
+	return find_key_option(arg + 1);
+    if (*arg == '^')
+	return Ctrl_chr(arg[1]);
+    return *arg;
+}
+
+#ifdef FEAT_CMDWIN
+/*
+ * Check value of 'cedit' and set cedit_key.
+ * Returns NULL if value is OK, error message otherwise.
+ */
+    static char_u *
+check_cedit()
+{
+    int n;
+
+    if (*p_cedit == NUL)
+	cedit_key = -1;
+    else
+    {
+	n = string_to_key(p_cedit);
+	if (vim_isprintc(n))
+	    return e_invarg;
+	cedit_key = n;
+    }
+    return NULL;
+}
+#endif
+
+#ifdef FEAT_TITLE
+/*
+ * When changing 'title', 'titlestring', 'icon' or 'iconstring', call
+ * maketitle() to create and display it.
+ * When switching the title or icon off, call mch_restore_title() to get
+ * the old value back.
+ */
+    static void
+did_set_title(icon)
+    int	    icon;	    /* Did set icon instead of title */
+{
+    if (starting != NO_SCREEN
+#ifdef FEAT_GUI
+	    && !gui.starting
+#endif
+				)
+    {
+	maketitle();
+	if (icon)
+	{
+	    if (!p_icon)
+		mch_restore_title(2);
+	}
+	else
+	{
+	    if (!p_title)
+		mch_restore_title(1);
+	}
+    }
+}
+#endif
+
+/*
+ * set_options_bin -  called when 'bin' changes value.
+ */
+    void
+set_options_bin(oldval, newval, opt_flags)
+    int		oldval;
+    int		newval;
+    int		opt_flags;	/* OPT_LOCAL and/or OPT_GLOBAL */
+{
+    /*
+     * The option values that are changed when 'bin' changes are
+     * copied when 'bin is set and restored when 'bin' is reset.
+     */
+    if (newval)
+    {
+	if (!oldval)		/* switched on */
+	{
+	    if (!(opt_flags & OPT_GLOBAL))
+	    {
+		curbuf->b_p_tw_nobin = curbuf->b_p_tw;
+		curbuf->b_p_wm_nobin = curbuf->b_p_wm;
+		curbuf->b_p_ml_nobin = curbuf->b_p_ml;
+		curbuf->b_p_et_nobin = curbuf->b_p_et;
+	    }
+	    if (!(opt_flags & OPT_LOCAL))
+	    {
+		p_tw_nobin = p_tw;
+		p_wm_nobin = p_wm;
+		p_ml_nobin = p_ml;
+		p_et_nobin = p_et;
+	    }
+	}
+
+	if (!(opt_flags & OPT_GLOBAL))
+	{
+	    curbuf->b_p_tw = 0;	/* no automatic line wrap */
+	    curbuf->b_p_wm = 0;	/* no automatic line wrap */
+	    curbuf->b_p_ml = 0;	/* no modelines */
+	    curbuf->b_p_et = 0;	/* no expandtab */
+	}
+	if (!(opt_flags & OPT_LOCAL))
+	{
+	    p_tw = 0;
+	    p_wm = 0;
+	    p_ml = FALSE;
+	    p_et = FALSE;
+	    p_bin = TRUE;	/* needed when called for the "-b" argument */
+	}
+    }
+    else if (oldval)		/* switched off */
+    {
+	if (!(opt_flags & OPT_GLOBAL))
+	{
+	    curbuf->b_p_tw = curbuf->b_p_tw_nobin;
+	    curbuf->b_p_wm = curbuf->b_p_wm_nobin;
+	    curbuf->b_p_ml = curbuf->b_p_ml_nobin;
+	    curbuf->b_p_et = curbuf->b_p_et_nobin;
+	}
+	if (!(opt_flags & OPT_LOCAL))
+	{
+	    p_tw = p_tw_nobin;
+	    p_wm = p_wm_nobin;
+	    p_ml = p_ml_nobin;
+	    p_et = p_et_nobin;
+	}
+    }
+}
+
+#ifdef FEAT_VIMINFO
+/*
+ * Find the parameter represented by the given character (eg ', :, ", or /),
+ * and return its associated value in the 'viminfo' string.
+ * Only works for number parameters, not for 'r' or 'n'.
+ * If the parameter is not specified in the string or there is no following
+ * number, return -1.
+ */
+    int
+get_viminfo_parameter(type)
+    int	    type;
+{
+    char_u  *p;
+
+    p = find_viminfo_parameter(type);
+    if (p != NULL && VIM_ISDIGIT(*p))
+	return atoi((char *)p);
+    return -1;
+}
+
+/*
+ * Find the parameter represented by the given character (eg ''', ':', '"', or
+ * '/') in the 'viminfo' option and return a pointer to the string after it.
+ * Return NULL if the parameter is not specified in the string.
+ */
+    char_u *
+find_viminfo_parameter(type)
+    int	    type;
+{
+    char_u  *p;
+
+    for (p = p_viminfo; *p; ++p)
+    {
+	if (*p == type)
+	    return p + 1;
+	if (*p == 'n')		    /* 'n' is always the last one */
+	    break;
+	p = vim_strchr(p, ',');	    /* skip until next ',' */
+	if (p == NULL)		    /* hit the end without finding parameter */
+	    break;
+    }
+    return NULL;
+}
+#endif
+
+/*
+ * Expand environment variables for some string options.
+ * These string options cannot be indirect!
+ * If "val" is NULL expand the current value of the option.
+ * Return pointer to NameBuff, or NULL when not expanded.
+ */
+    static char_u *
+option_expand(opt_idx, val)
+    int		opt_idx;
+    char_u	*val;
+{
+    /* if option doesn't need expansion nothing to do */
+    if (!(options[opt_idx].flags & P_EXPAND) || options[opt_idx].var == NULL)
+	return NULL;
+
+    /* If val is longer than MAXPATHL no meaningful expansion can be done,
+     * expand_env() would truncate the string. */
+    if (val != NULL && STRLEN(val) > MAXPATHL)
+	return NULL;
+
+    if (val == NULL)
+	val = *(char_u **)options[opt_idx].var;
+
+    /*
+     * Expanding this with NameBuff, expand_env() must not be passed IObuff.
+     * Escape spaces when expanding 'tags', they are used to separate file
+     * names.
+     * For 'spellsuggest' expand after "file:".
+     */
+    expand_env_esc(val, NameBuff, MAXPATHL,
+	    (char_u **)options[opt_idx].var == &p_tags,
+#ifdef FEAT_SPELL
+	    (char_u **)options[opt_idx].var == &p_sps ? (char_u *)"file:" :
+#endif
+				  NULL);
+    if (STRCMP(NameBuff, val) == 0)   /* they are the same */
+	return NULL;
+
+    return NameBuff;
+}
+
+/*
+ * After setting various option values: recompute variables that depend on
+ * option values.
+ */
+    static void
+didset_options()
+{
+    /* initialize the table for 'iskeyword' et.al. */
+    (void)init_chartab();
+
+#ifdef FEAT_MBYTE
+    (void)opt_strings_flags(p_cmp, p_cmp_values, &cmp_flags, TRUE);
+#endif
+    (void)opt_strings_flags(p_bkc, p_bkc_values, &bkc_flags, TRUE);
+#ifdef FEAT_SESSION
+    (void)opt_strings_flags(p_ssop, p_ssop_values, &ssop_flags, TRUE);
+    (void)opt_strings_flags(p_vop, p_ssop_values, &vop_flags, TRUE);
+#endif
+#ifdef FEAT_FOLDING
+    (void)opt_strings_flags(p_fdo, p_fdo_values, &fdo_flags, TRUE);
+#endif
+    (void)opt_strings_flags(p_dy, p_dy_values, &dy_flags, TRUE);
+#ifdef FEAT_VIRTUALEDIT
+    (void)opt_strings_flags(p_ve, p_ve_values, &ve_flags, TRUE);
+#endif
+#if defined(FEAT_MOUSE) && (defined(UNIX) || defined(VMS))
+    (void)opt_strings_flags(p_ttym, p_ttym_values, &ttym_flags, FALSE);
+#endif
+#ifdef FEAT_SPELL
+    (void)spell_check_msm();
+    (void)spell_check_sps();
+    (void)compile_cap_prog(curbuf);
+#endif
+#if defined(FEAT_TOOLBAR) && !defined(FEAT_GUI_W32)
+    (void)opt_strings_flags(p_toolbar, p_toolbar_values, &toolbar_flags, TRUE);
+#endif
+#if defined(FEAT_TOOLBAR) && defined(FEAT_GUI_GTK) && defined(HAVE_GTK2)
+    (void)opt_strings_flags(p_tbis, p_tbis_values, &tbis_flags, FALSE);
+#endif
+#ifdef FEAT_CMDWIN
+    /* set cedit_key */
+    (void)check_cedit();
+#endif
+}
+
+/*
+ * Check for string options that are NULL (normally only termcap options).
+ */
+    void
+check_options()
+{
+    int		opt_idx;
+
+    for (opt_idx = 0; options[opt_idx].fullname != NULL; opt_idx++)
+	if ((options[opt_idx].flags & P_STRING) && options[opt_idx].var != NULL)
+	    check_string_option((char_u **)get_varp(&(options[opt_idx])));
+}
+
+/*
+ * Check string options in a buffer for NULL value.
+ */
+    void
+check_buf_options(buf)
+    buf_T	*buf;
+{
+#if defined(FEAT_QUICKFIX)
+    check_string_option(&buf->b_p_bh);
+    check_string_option(&buf->b_p_bt);
+#endif
+#ifdef FEAT_MBYTE
+    check_string_option(&buf->b_p_fenc);
+#endif
+    check_string_option(&buf->b_p_ff);
+#ifdef FEAT_FIND_ID
+    check_string_option(&buf->b_p_def);
+    check_string_option(&buf->b_p_inc);
+# ifdef FEAT_EVAL
+    check_string_option(&buf->b_p_inex);
+# endif
+#endif
+#if defined(FEAT_CINDENT) && defined(FEAT_EVAL)
+    check_string_option(&buf->b_p_inde);
+    check_string_option(&buf->b_p_indk);
+#endif
+#if defined(FEAT_BEVAL) && defined(FEAT_EVAL)
+    check_string_option(&buf->b_p_bexpr);
+#endif
+#if defined(FEAT_EVAL)
+    check_string_option(&buf->b_p_fex);
+#endif
+#ifdef FEAT_CRYPT
+    check_string_option(&buf->b_p_key);
+#endif
+    check_string_option(&buf->b_p_kp);
+    check_string_option(&buf->b_p_mps);
+    check_string_option(&buf->b_p_fo);
+    check_string_option(&buf->b_p_flp);
+    check_string_option(&buf->b_p_isk);
+#ifdef FEAT_COMMENTS
+    check_string_option(&buf->b_p_com);
+#endif
+#ifdef FEAT_FOLDING
+    check_string_option(&buf->b_p_cms);
+#endif
+    check_string_option(&buf->b_p_nf);
+#ifdef FEAT_TEXTOBJ
+    check_string_option(&buf->b_p_qe);
+#endif
+#ifdef FEAT_SYN_HL
+    check_string_option(&buf->b_p_syn);
+#endif
+#ifdef FEAT_SPELL
+    check_string_option(&buf->b_p_spc);
+    check_string_option(&buf->b_p_spf);
+    check_string_option(&buf->b_p_spl);
+#endif
+#ifdef FEAT_SEARCHPATH
+    check_string_option(&buf->b_p_sua);
+#endif
+#ifdef FEAT_CINDENT
+    check_string_option(&buf->b_p_cink);
+    check_string_option(&buf->b_p_cino);
+#endif
+#ifdef FEAT_AUTOCMD
+    check_string_option(&buf->b_p_ft);
+#endif
+#ifdef FEAT_OSFILETYPE
+    check_string_option(&buf->b_p_oft);
+#endif
+#if defined(FEAT_SMARTINDENT) || defined(FEAT_CINDENT)
+    check_string_option(&buf->b_p_cinw);
+#endif
+#ifdef FEAT_INS_EXPAND
+    check_string_option(&buf->b_p_cpt);
+#endif
+#ifdef FEAT_COMPL_FUNC
+    check_string_option(&buf->b_p_cfu);
+    check_string_option(&buf->b_p_ofu);
+#endif
+#ifdef FEAT_KEYMAP
+    check_string_option(&buf->b_p_keymap);
+#endif
+#ifdef FEAT_QUICKFIX
+    check_string_option(&buf->b_p_gp);
+    check_string_option(&buf->b_p_mp);
+    check_string_option(&buf->b_p_efm);
+#endif
+    check_string_option(&buf->b_p_ep);
+    check_string_option(&buf->b_p_path);
+    check_string_option(&buf->b_p_tags);
+#ifdef FEAT_INS_EXPAND
+    check_string_option(&buf->b_p_dict);
+    check_string_option(&buf->b_p_tsr);
+#endif
+}
+
+/*
+ * Free the string allocated for an option.
+ * Checks for the string being empty_option. This may happen if we're out of
+ * memory, vim_strsave() returned NULL, which was replaced by empty_option by
+ * check_options().
+ * Does NOT check for P_ALLOCED flag!
+ */
+    void
+free_string_option(p)
+    char_u	*p;
+{
+    if (p != empty_option)
+	vim_free(p);
+}
+
+    void
+clear_string_option(pp)
+    char_u	**pp;
+{
+    if (*pp != empty_option)
+	vim_free(*pp);
+    *pp = empty_option;
+}
+
+    static void
+check_string_option(pp)
+    char_u	**pp;
+{
+    if (*pp == NULL)
+	*pp = empty_option;
+}
+
+/*
+ * Mark a terminal option as allocated, found by a pointer into term_strings[].
+ */
+    void
+set_term_option_alloced(p)
+    char_u **p;
+{
+    int		opt_idx;
+
+    for (opt_idx = 1; options[opt_idx].fullname != NULL; opt_idx++)
+	if (options[opt_idx].var == (char_u *)p)
+	{
+	    options[opt_idx].flags |= P_ALLOCED;
+	    return;
+	}
+    return; /* cannot happen: didn't find it! */
+}
+
+#if defined(FEAT_EVAL) || defined(PROTO)
+/*
+ * Return TRUE when option "opt" was set from a modeline or in secure mode.
+ * Return FALSE when it wasn't.
+ * Return -1 for an unknown option.
+ */
+    int
+was_set_insecurely(opt, opt_flags)
+    char_u  *opt;
+    int	    opt_flags;
+{
+    int	    idx = findoption(opt);
+    long_u  *flagp;
+
+    if (idx >= 0)
+    {
+	flagp = insecure_flag(idx, opt_flags);
+	return (*flagp & P_INSECURE) != 0;
+    }
+    EMSG2(_(e_intern2), "was_set_insecurely()");
+    return -1;
+}
+
+/*
+ * Get a pointer to the flags used for the P_INSECURE flag of option
+ * "opt_idx".  For some local options a local flags field is used.
+ */
+    static long_u *
+insecure_flag(opt_idx, opt_flags)
+    int		opt_idx;
+    int		opt_flags;
+{
+    if (opt_flags & OPT_LOCAL)
+	switch ((int)options[opt_idx].indir)
+	{
+#ifdef FEAT_STL_OPT
+	    case PV_STL:	return &curwin->w_p_stl_flags;
+#endif
+#ifdef FEAT_EVAL
+# ifdef FEAT_FOLDING
+	    case PV_FDE:	return &curwin->w_p_fde_flags;
+	    case PV_FDT:	return &curwin->w_p_fdt_flags;
+# endif
+# ifdef FEAT_BEVAL
+	    case PV_BEXPR:	return &curbuf->b_p_bexpr_flags;
+# endif
+# if defined(FEAT_CINDENT)
+	    case PV_INDE:	return &curbuf->b_p_inde_flags;
+# endif
+	    case PV_FEX:	return &curbuf->b_p_fex_flags;
+# ifdef FEAT_FIND_ID
+	    case PV_INEX:	return &curbuf->b_p_inex_flags;
+# endif
+#endif
+	}
+
+    /* Nothing special, return global flags field. */
+    return &options[opt_idx].flags;
+}
+#endif
+
+/*
+ * Set a string option to a new value (without checking the effect).
+ * The string is copied into allocated memory.
+ * if ("opt_idx" == -1) "name" is used, otherwise "opt_idx" is used.
+ * When "set_sid" is zero set the scriptID to current_SID.  When "set_sid" is
+ * SID_NONE don't set the scriptID.  Otherwise set the scriptID to "set_sid".
+ */
+/*ARGSUSED*/
+    void
+set_string_option_direct(name, opt_idx, val, opt_flags, set_sid)
+    char_u	*name;
+    int		opt_idx;
+    char_u	*val;
+    int		opt_flags;	/* OPT_FREE, OPT_LOCAL and/or OPT_GLOBAL */
+    int		set_sid;
+{
+    char_u	*s;
+    char_u	**varp;
+    int		both = (opt_flags & (OPT_LOCAL | OPT_GLOBAL)) == 0;
+    int		idx = opt_idx;
+
+    if (idx == -1)		/* use name */
+    {
+	idx = findoption(name);
+	if (idx < 0)	/* not found (should not happen) */
+	{
+	    EMSG2(_(e_intern2), "set_string_option_direct()");
+	    return;
+	}
+    }
+
+    if (options[idx].var == NULL)	/* can't set hidden option */
+	return;
+
+    s = vim_strsave(val);
+    if (s != NULL)
+    {
+	varp = (char_u **)get_varp_scope(&(options[idx]),
+					       both ? OPT_LOCAL : opt_flags);
+	if ((opt_flags & OPT_FREE) && (options[idx].flags & P_ALLOCED))
+	    free_string_option(*varp);
+	*varp = s;
+
+	/* For buffer/window local option may also set the global value. */
+	if (both)
+	    set_string_option_global(idx, varp);
+
+	options[idx].flags |= P_ALLOCED;
+
+	/* When setting both values of a global option with a local value,
+	 * make the local value empty, so that the global value is used. */
+	if (((int)options[idx].indir & PV_BOTH) && both)
+	{
+	    free_string_option(*varp);
+	    *varp = empty_option;
+	}
+# ifdef FEAT_EVAL
+	if (set_sid != SID_NONE)
+	    set_option_scriptID_idx(idx, opt_flags,
+					set_sid == 0 ? current_SID : set_sid);
+# endif
+    }
+}
+
+/*
+ * Set global value for string option when it's a local option.
+ */
+    static void
+set_string_option_global(opt_idx, varp)
+    int		opt_idx;	/* option index */
+    char_u	**varp;		/* pointer to option variable */
+{
+    char_u	**p, *s;
+
+    /* the global value is always allocated */
+    if (options[opt_idx].var == VAR_WIN)
+	p = (char_u **)GLOBAL_WO(varp);
+    else
+	p = (char_u **)options[opt_idx].var;
+    if (options[opt_idx].indir != PV_NONE
+	    && p != varp
+	    && (s = vim_strsave(*varp)) != NULL)
+    {
+	free_string_option(*p);
+	*p = s;
+    }
+}
+
+/*
+ * Set a string option to a new value, and handle the effects.
+ */
+    static void
+set_string_option(opt_idx, value, opt_flags)
+    int		opt_idx;
+    char_u	*value;
+    int		opt_flags;	/* OPT_LOCAL and/or OPT_GLOBAL */
+{
+    char_u	*s;
+    char_u	**varp;
+    char_u	*oldval;
+
+    if (options[opt_idx].var == NULL)	/* don't set hidden option */
+	return;
+
+    s = vim_strsave(value);
+    if (s != NULL)
+    {
+	varp = (char_u **)get_varp_scope(&(options[opt_idx]),
+		(opt_flags & (OPT_LOCAL | OPT_GLOBAL)) == 0
+		    ? (((int)options[opt_idx].indir & PV_BOTH)
+			? OPT_GLOBAL : OPT_LOCAL)
+		    : opt_flags);
+	oldval = *varp;
+	*varp = s;
+	if (did_set_string_option(opt_idx, varp, TRUE, oldval, NULL,
+							   opt_flags) == NULL)
+	    did_set_option(opt_idx, opt_flags, TRUE);
+    }
+}
+
+/*
+ * Handle string options that need some action to perform when changed.
+ * Returns NULL for success, or an error message for an error.
+ */
+    static char_u *
+did_set_string_option(opt_idx, varp, new_value_alloced, oldval, errbuf,
+								    opt_flags)
+    int		opt_idx;		/* index in options[] table */
+    char_u	**varp;			/* pointer to the option variable */
+    int		new_value_alloced;	/* new value was allocated */
+    char_u	*oldval;		/* previous value of the option */
+    char_u	*errbuf;		/* buffer for errors, or NULL */
+    int		opt_flags;		/* OPT_LOCAL and/or OPT_GLOBAL */
+{
+    char_u	*errmsg = NULL;
+    char_u	*s, *p;
+    int		did_chartab = FALSE;
+    char_u	**gvarp;
+    long_u	free_oldval = (options[opt_idx].flags & P_ALLOCED);
+
+    /* Get the global option to compare with, otherwise we would have to check
+     * two values for all local options. */
+    gvarp = (char_u **)get_varp_scope(&(options[opt_idx]), OPT_GLOBAL);
+
+    /* Disallow changing some options from secure mode */
+    if ((secure
+#ifdef HAVE_SANDBOX
+		|| sandbox != 0
+#endif
+		) && (options[opt_idx].flags & P_SECURE))
+    {
+	errmsg = e_secure;
+    }
+
+    /* Check for a "normal" file name in some options.  Disallow a path
+     * separator (slash and/or backslash), wildcards and characters that are
+     * often illegal in a file name. */
+    else if ((options[opt_idx].flags & P_NFNAME)
+			 && vim_strpbrk(*varp, (char_u *)"/\\*?[|<>") != NULL)
+    {
+	errmsg = e_invarg;
+    }
+
+    /* 'term' */
+    else if (varp == &T_NAME)
+    {
+	if (T_NAME[0] == NUL)
+	    errmsg = (char_u *)N_("E529: Cannot set 'term' to empty string");
+#ifdef FEAT_GUI
+	if (gui.in_use)
+	    errmsg = (char_u *)N_("E530: Cannot change term in GUI");
+	else if (term_is_gui(T_NAME))
+	    errmsg = (char_u *)N_("E531: Use \":gui\" to start the GUI");
+#endif
+	else if (set_termname(T_NAME) == FAIL)
+	    errmsg = (char_u *)N_("E522: Not found in termcap");
+	else
+	    /* Screen colors may have changed. */
+	    redraw_later_clear();
+    }
+
+    /* 'backupcopy' */
+    else if (varp == &p_bkc)
+    {
+	if (opt_strings_flags(p_bkc, p_bkc_values, &bkc_flags, TRUE) != OK)
+	    errmsg = e_invarg;
+	if (((bkc_flags & BKC_AUTO) != 0)
+		+ ((bkc_flags & BKC_YES) != 0)
+		+ ((bkc_flags & BKC_NO) != 0) != 1)
+	{
+	    /* Must have exactly one of "auto", "yes"  and "no". */
+	    (void)opt_strings_flags(oldval, p_bkc_values, &bkc_flags, TRUE);
+	    errmsg = e_invarg;
+	}
+    }
+
+    /* 'backupext' and 'patchmode' */
+    else if (varp == &p_bex || varp == &p_pm)
+    {
+	if (STRCMP(*p_bex == '.' ? p_bex + 1 : p_bex,
+		     *p_pm == '.' ? p_pm + 1 : p_pm) == 0)
+	    errmsg = (char_u *)N_("E589: 'backupext' and 'patchmode' are equal");
+    }
+
+    /*
+     * 'isident', 'iskeyword', 'isprint or 'isfname' option: refill chartab[]
+     * If the new option is invalid, use old value.  'lisp' option: refill
+     * chartab[] for '-' char
+     */
+    else if (  varp == &p_isi
+	    || varp == &(curbuf->b_p_isk)
+	    || varp == &p_isp
+	    || varp == &p_isf)
+    {
+	if (init_chartab() == FAIL)
+	{
+	    did_chartab = TRUE;	    /* need to restore it below */
+	    errmsg = e_invarg;	    /* error in value */
+	}
+    }
+
+    /* 'helpfile' */
+    else if (varp == &p_hf)
+    {
+	/* May compute new values for $VIM and $VIMRUNTIME */
+	if (didset_vim)
+	{
+	    vim_setenv((char_u *)"VIM", (char_u *)"");
+	    didset_vim = FALSE;
+	}
+	if (didset_vimruntime)
+	{
+	    vim_setenv((char_u *)"VIMRUNTIME", (char_u *)"");
+	    didset_vimruntime = FALSE;
+	}
+    }
+
+#ifdef FEAT_MULTI_LANG
+    /* 'helplang' */
+    else if (varp == &p_hlg)
+    {
+	/* Check for "", "ab", "ab,cd", etc. */
+	for (s = p_hlg; *s != NUL; s += 3)
+	{
+	    if (s[1] == NUL || ((s[2] != ',' || s[3] == NUL) && s[2] != NUL))
+	    {
+		errmsg = e_invarg;
+		break;
+	    }
+	    if (s[2] == NUL)
+		break;
+	}
+    }
+#endif
+
+    /* 'highlight' */
+    else if (varp == &p_hl)
+    {
+	if (highlight_changed() == FAIL)
+	    errmsg = e_invarg;	/* invalid flags */
+    }
+
+    /* 'nrformats' */
+    else if (gvarp == &p_nf)
+    {
+	if (check_opt_strings(*varp, p_nf_values, TRUE) != OK)
+	    errmsg = e_invarg;
+    }
+
+#ifdef FEAT_SESSION
+    /* 'sessionoptions' */
+    else if (varp == &p_ssop)
+    {
+	if (opt_strings_flags(p_ssop, p_ssop_values, &ssop_flags, TRUE) != OK)
+	    errmsg = e_invarg;
+	if ((ssop_flags & SSOP_CURDIR) && (ssop_flags & SSOP_SESDIR))
+	{
+	    /* Don't allow both "sesdir" and "curdir". */
+	    (void)opt_strings_flags(oldval, p_ssop_values, &ssop_flags, TRUE);
+	    errmsg = e_invarg;
+	}
+    }
+    /* 'viewoptions' */
+    else if (varp == &p_vop)
+    {
+	if (opt_strings_flags(p_vop, p_ssop_values, &vop_flags, TRUE) != OK)
+	    errmsg = e_invarg;
+    }
+#endif
+
+    /* 'scrollopt' */
+#ifdef FEAT_SCROLLBIND
+    else if (varp == &p_sbo)
+    {
+	if (check_opt_strings(p_sbo, p_scbopt_values, TRUE) != OK)
+	    errmsg = e_invarg;
+    }
+#endif
+
+    /* 'ambiwidth' */
+#ifdef FEAT_MBYTE
+    else if (varp == &p_ambw)
+    {
+	if (check_opt_strings(p_ambw, p_ambw_values, FALSE) != OK)
+	    errmsg = e_invarg;
+    }
+#endif
+
+    /* 'background' */
+    else if (varp == &p_bg)
+    {
+	if (check_opt_strings(p_bg, p_bg_values, FALSE) == OK)
+	{
+#ifdef FEAT_EVAL
+	    int dark = (*p_bg == 'd');
+#endif
+
+	    init_highlight(FALSE, FALSE);
+
+#ifdef FEAT_EVAL
+	    if (dark != (*p_bg == 'd')
+			  && get_var_value((char_u *)"g:colors_name") != NULL)
+	    {
+		/* The color scheme must have set 'background' back to another
+		 * value, that's not what we want here.  Disable the color
+		 * scheme and set the colors again. */
+		do_unlet((char_u *)"g:colors_name", TRUE);
+		free_string_option(p_bg);
+		p_bg = vim_strsave((char_u *)(dark ? "dark" : "light"));
+		check_string_option(&p_bg);
+		init_highlight(FALSE, FALSE);
+	    }
+#endif
+	}
+	else
+	    errmsg = e_invarg;
+    }
+
+    /* 'wildmode' */
+    else if (varp == &p_wim)
+    {
+	if (check_opt_wim() == FAIL)
+	    errmsg = e_invarg;
+    }
+
+#ifdef FEAT_CMDL_COMPL
+    /* 'wildoptions' */
+    else if (varp == &p_wop)
+    {
+	if (check_opt_strings(p_wop, p_wop_values, TRUE) != OK)
+	    errmsg = e_invarg;
+    }
+#endif
+
+#ifdef FEAT_WAK
+    /* 'winaltkeys' */
+    else if (varp == &p_wak)
+    {
+	if (*p_wak == NUL
+		|| check_opt_strings(p_wak, p_wak_values, FALSE) != OK)
+	    errmsg = e_invarg;
+# ifdef FEAT_MENU
+#  ifdef FEAT_GUI_MOTIF
+	else if (gui.in_use)
+	    gui_motif_set_mnemonics(p_wak[0] == 'y' || p_wak[0] == 'm');
+#  else
+#   ifdef FEAT_GUI_GTK
+	else if (gui.in_use)
+	    gui_gtk_set_mnemonics(p_wak[0] == 'y' || p_wak[0] == 'm');
+#   endif
+#  endif
+# endif
+    }
+#endif
+
+#ifdef FEAT_AUTOCMD
+    /* 'eventignore' */
+    else if (varp == &p_ei)
+    {
+	if (check_ei() == FAIL)
+	    errmsg = e_invarg;
+    }
+#endif
+
+#ifdef FEAT_MBYTE
+    /* 'encoding' and 'fileencoding' */
+    else if (varp == &p_enc || gvarp == &p_fenc || varp == &p_tenc)
+    {
+	if (gvarp == &p_fenc)
+	{
+	    if (!curbuf->b_p_ma)
+		errmsg = e_modifiable;
+	    else if (vim_strchr(*varp, ',') != NULL)
+		/* No comma allowed in 'fileencoding'; catches confusing it
+		 * with 'fileencodings'. */
+		errmsg = e_invarg;
+	    else
+	    {
+# ifdef FEAT_TITLE
+		/* May show a "+" in the title now. */
+		need_maketitle = TRUE;
+# endif
+		/* Add 'fileencoding' to the swap file. */
+		ml_setflags(curbuf);
+	    }
+	}
+	if (errmsg == NULL)
+	{
+	    /* canonize the value, so that STRCMP() can be used on it */
+	    p = enc_canonize(*varp);
+	    if (p != NULL)
+	    {
+		vim_free(*varp);
+		*varp = p;
+	    }
+	    if (varp == &p_enc)
+	    {
+		errmsg = mb_init();
+# ifdef FEAT_TITLE
+		need_maketitle = TRUE;
+# endif
+	    }
+	}
+
+# if defined(PLAN9)
+	if (errmsg == NULL && varp == &p_tenc)
+	{
+	    /* Plan 9 uses only a single encoding, and that is UTF-8. */
+	    if (STRCMP(p_tenc, "utf-8") != 0)
+		errmsg = (char_u *)N_("E617: Cannot be changed in Plan 9");
+	}
+# endif
+# if defined(FEAT_GUI_GTK) && defined(HAVE_GTK2)
+	if (errmsg == NULL && varp == &p_tenc && gui.in_use)
+	{
+	    /* GTK+ 2 uses only a single encoding, and that is UTF-8. */
+	    if (STRCMP(p_tenc, "utf-8") != 0)
+		errmsg = (char_u *)N_("E617: Cannot be changed in the GTK+ 2 GUI");
+	}
+# endif
+
+	if (errmsg == NULL)
+	{
+# ifdef FEAT_KEYMAP
+	    /* When 'keymap' is used and 'encoding' changes, reload the keymap
+	     * (with another encoding). */
+	    if (varp == &p_enc && *curbuf->b_p_keymap != NUL)
+		(void)keymap_init();
+# endif
+
+	    /* When 'termencoding' is not empty and 'encoding' changes or when
+	     * 'termencoding' changes, need to setup for keyboard input and
+	     * display output conversion. */
+	    if (((varp == &p_enc && *p_tenc != NUL) || varp == &p_tenc))
+	    {
+		convert_setup(&input_conv, p_tenc, p_enc);
+		convert_setup(&output_conv, p_enc, p_tenc);
+	    }
+
+# if defined(WIN3264) && defined(FEAT_MBYTE)
+	    /* $HOME may have characters in active code page. */
+	    if (varp == &p_enc)
+		init_homedir();
+# endif
+	}
+    }
+#endif
+
+#if defined(FEAT_POSTSCRIPT)
+    else if (varp == &p_penc)
+    {
+	/* Canonize printencoding if VIM standard one */
+	p = enc_canonize(p_penc);
+	if (p != NULL)
+	{
+	    vim_free(p_penc);
+	    p_penc = p;
+	}
+	else
+	{
+	    /* Ensure lower case and '-' for '_' */
+	    for (s = p_penc; *s != NUL; s++)
+	    {
+		if (*s == '_')
+		    *s = '-';
+		else
+		    *s = TOLOWER_ASC(*s);
+	    }
+	}
+    }
+#endif
+
+#if defined(FEAT_XIM) && defined(FEAT_GUI_GTK)
+    else if (varp == &p_imak)
+    {
+	if (gui.in_use && !im_xim_isvalid_imactivate())
+	    errmsg = e_invarg;
+    }
+#endif
+
+#ifdef FEAT_KEYMAP
+    else if (varp == &curbuf->b_p_keymap)
+    {
+	/* load or unload key mapping tables */
+	errmsg = keymap_init();
+
+	/* When successfully installed a new keymap switch on using it. */
+	if (*curbuf->b_p_keymap != NUL && errmsg == NULL)
+	{
+	    curbuf->b_p_iminsert = B_IMODE_LMAP;
+	    if (curbuf->b_p_imsearch != B_IMODE_USE_INSERT)
+		curbuf->b_p_imsearch = B_IMODE_LMAP;
+	    set_iminsert_global();
+	    set_imsearch_global();
+# ifdef FEAT_WINDOWS
+	    status_redraw_curbuf();
+# endif
+	}
+    }
+#endif
+
+    /* 'fileformat' */
+    else if (gvarp == &p_ff)
+    {
+	if (!curbuf->b_p_ma && !(opt_flags & OPT_GLOBAL))
+	    errmsg = e_modifiable;
+	else if (check_opt_strings(*varp, p_ff_values, FALSE) != OK)
+	    errmsg = e_invarg;
+	else
+	{
+	    /* may also change 'textmode' */
+	    if (get_fileformat(curbuf) == EOL_DOS)
+		curbuf->b_p_tx = TRUE;
+	    else
+		curbuf->b_p_tx = FALSE;
+#ifdef FEAT_TITLE
+	    need_maketitle = TRUE;
+#endif
+	    /* update flag in swap file */
+	    ml_setflags(curbuf);
+	}
+    }
+
+    /* 'fileformats' */
+    else if (varp == &p_ffs)
+    {
+	if (check_opt_strings(p_ffs, p_ff_values, TRUE) != OK)
+	    errmsg = e_invarg;
+	else
+	{
+	    /* also change 'textauto' */
+	    if (*p_ffs == NUL)
+		p_ta = FALSE;
+	    else
+		p_ta = TRUE;
+	}
+    }
+
+#if defined(FEAT_CRYPT) && defined(FEAT_CMDHIST)
+    /* 'cryptkey' */
+    else if (gvarp == &p_key)
+    {
+	/* Make sure the ":set" command doesn't show the new value in the
+	 * history. */
+	remove_key_from_history();
+    }
+#endif
+
+    /* 'matchpairs' */
+    else if (gvarp == &p_mps)
+    {
+	/* Check for "x:y,x:y" */
+	for (p = *varp; *p != NUL; p += 4)
+	{
+	    if (p[1] != ':' || p[2] == NUL || (p[3] != NUL && p[3] != ','))
+	    {
+		errmsg = e_invarg;
+		break;
+	    }
+	    if (p[3] == NUL)
+		break;
+	}
+    }
+
+#ifdef FEAT_COMMENTS
+    /* 'comments' */
+    else if (gvarp == &p_com)
+    {
+	for (s = *varp; *s; )
+	{
+	    while (*s && *s != ':')
+	    {
+		if (vim_strchr((char_u *)COM_ALL, *s) == NULL
+					     && !VIM_ISDIGIT(*s) && *s != '-')
+		{
+		    errmsg = illegal_char(errbuf, *s);
+		    break;
+		}
+		++s;
+	    }
+	    if (*s++ == NUL)
+		errmsg = (char_u *)N_("E524: Missing colon");
+	    else if (*s == ',' || *s == NUL)
+		errmsg = (char_u *)N_("E525: Zero length string");
+	    if (errmsg != NULL)
+		break;
+	    while (*s && *s != ',')
+	    {
+		if (*s == '\\' && s[1] != NUL)
+		    ++s;
+		++s;
+	    }
+	    s = skip_to_option_part(s);
+	}
+    }
+#endif
+
+    /* 'listchars' */
+    else if (varp == &p_lcs)
+    {
+	errmsg = set_chars_option(varp);
+    }
+
+#if defined(FEAT_WINDOWS) || defined(FEAT_FOLDING)
+    /* 'fillchars' */
+    else if (varp == &p_fcs)
+    {
+	errmsg = set_chars_option(varp);
+    }
+#endif
+
+#ifdef FEAT_CMDWIN
+    /* 'cedit' */
+    else if (varp == &p_cedit)
+    {
+	errmsg = check_cedit();
+    }
+#endif
+
+    /* 'verbosefile' */
+    else if (varp == &p_vfile)
+    {
+	verbose_stop();
+	if (*p_vfile != NUL && verbose_open() == FAIL)
+	    errmsg = e_invarg;
+    }
+
+#ifdef FEAT_VIMINFO
+    /* 'viminfo' */
+    else if (varp == &p_viminfo)
+    {
+	for (s = p_viminfo; *s;)
+	{
+	    /* Check it's a valid character */
+	    if (vim_strchr((char_u *)"!\"%'/:<@cfhnrs", *s) == NULL)
+	    {
+		errmsg = illegal_char(errbuf, *s);
+		break;
+	    }
+	    if (*s == 'n')	/* name is always last one */
+	    {
+		break;
+	    }
+	    else if (*s == 'r') /* skip until next ',' */
+	    {
+		while (*++s && *s != ',')
+		    ;
+	    }
+	    else if (*s == '%')
+	    {
+		/* optional number */
+		while (vim_isdigit(*++s))
+		    ;
+	    }
+	    else if (*s == '!' || *s == 'h' || *s == 'c')
+		++s;		/* no extra chars */
+	    else		/* must have a number */
+	    {
+		while (vim_isdigit(*++s))
+		    ;
+
+		if (!VIM_ISDIGIT(*(s - 1)))
+		{
+		    if (errbuf != NULL)
+		    {
+			sprintf((char *)errbuf,
+					 _("E526: Missing number after <%s>"),
+						    transchar_byte(*(s - 1)));
+			errmsg = errbuf;
+		    }
+		    else
+			errmsg = (char_u *)"";
+		    break;
+		}
+	    }
+	    if (*s == ',')
+		++s;
+	    else if (*s)
+	    {
+		if (errbuf != NULL)
+		    errmsg = (char_u *)N_("E527: Missing comma");
+		else
+		    errmsg = (char_u *)"";
+		break;
+	    }
+	}
+	if (*p_viminfo && errmsg == NULL && get_viminfo_parameter('\'') < 0)
+	    errmsg = (char_u *)N_("E528: Must specify a ' value");
+    }
+#endif /* FEAT_VIMINFO */
+
+    /* terminal options */
+    else if (istermoption(&options[opt_idx]) && full_screen)
+    {
+	/* ":set t_Co=0" and ":set t_Co=1" do ":set t_Co=" */
+	if (varp == &T_CCO)
+	{
+	    t_colors = atoi((char *)T_CCO);
+	    if (t_colors <= 1)
+	    {
+		if (new_value_alloced)
+		    vim_free(T_CCO);
+		T_CCO = empty_option;
+	    }
+	    /* We now have a different color setup, initialize it again. */
+	    init_highlight(TRUE, FALSE);
+	}
+	ttest(FALSE);
+	if (varp == &T_ME)
+	{
+	    out_str(T_ME);
+	    redraw_later(CLEAR);
+#if defined(MSDOS) || (defined(WIN3264) && !defined(FEAT_GUI_W32))
+	    /* Since t_me has been set, this probably means that the user
+	     * wants to use this as default colors.  Need to reset default
+	     * background/foreground colors. */
+	    mch_set_normal_colors();
+#endif
+	}
+    }
+
+#ifdef FEAT_LINEBREAK
+    /* 'showbreak' */
+    else if (varp == &p_sbr)
+    {
+	for (s = p_sbr; *s; )
+	{
+	    if (ptr2cells(s) != 1)
+		errmsg = (char_u *)N_("E595: contains unprintable or wide character");
+	    mb_ptr_adv(s);
+	}
+    }
+#endif
+
+#ifdef FEAT_GUI
+    /* 'guifont' */
+    else if (varp == &p_guifont)
+    {
+	if (gui.in_use)
+	{
+	    p = p_guifont;
+# if defined(FEAT_GUI_GTK)
+	    /*
+	     * Put up a font dialog and let the user select a new value.
+	     * If this is cancelled go back to the old value but don't
+	     * give an error message.
+	     */
+	    if (STRCMP(p, "*") == 0)
+	    {
+		p = gui_mch_font_dialog(oldval);
+
+		if (new_value_alloced)
+		    free_string_option(p_guifont);
+
+		p_guifont = (p != NULL) ? p : vim_strsave(oldval);
+		new_value_alloced = TRUE;
+	    }
+# endif
+	    if (p != NULL && gui_init_font(p_guifont, FALSE) != OK)
+	    {
+# if defined(FEAT_GUI_MSWIN) || defined(FEAT_GUI_PHOTON)
+		if (STRCMP(p_guifont, "*") == 0)
+		{
+		    /* Dialog was cancelled: Keep the old value without giving
+		     * an error message. */
+		    if (new_value_alloced)
+			free_string_option(p_guifont);
+		    p_guifont = vim_strsave(oldval);
+		    new_value_alloced = TRUE;
+		}
+		else
+# endif
+		    errmsg = (char_u *)N_("E596: Invalid font(s)");
+	    }
+	}
+    }
+# ifdef FEAT_XFONTSET
+    else if (varp == &p_guifontset)
+    {
+	if (STRCMP(p_guifontset, "*") == 0)
+	    errmsg = (char_u *)N_("E597: can't select fontset");
+	else if (gui.in_use && gui_init_font(p_guifontset, TRUE) != OK)
+	    errmsg = (char_u *)N_("E598: Invalid fontset");
+    }
+# endif
+# ifdef FEAT_MBYTE
+    else if (varp == &p_guifontwide)
+    {
+	if (STRCMP(p_guifontwide, "*") == 0)
+	    errmsg = (char_u *)N_("E533: can't select wide font");
+	else if (gui_get_wide_font() == FAIL)
+	    errmsg = (char_u *)N_("E534: Invalid wide font");
+    }
+# endif
+#endif
+
+#ifdef CURSOR_SHAPE
+    /* 'guicursor' */
+    else if (varp == &p_guicursor)
+	errmsg = parse_shape_opt(SHAPE_CURSOR);
+#endif
+
+#ifdef FEAT_MOUSESHAPE
+    /* 'mouseshape' */
+    else if (varp == &p_mouseshape)
+    {
+	errmsg = parse_shape_opt(SHAPE_MOUSE);
+	update_mouseshape(-1);
+    }
+#endif
+
+#ifdef FEAT_PRINTER
+    else if (varp == &p_popt)
+	errmsg = parse_printoptions();
+# if defined(FEAT_MBYTE) && defined(FEAT_POSTSCRIPT)
+    else if (varp == &p_pmfn)
+	errmsg = parse_printmbfont();
+# endif
+#endif
+
+#ifdef FEAT_LANGMAP
+    /* 'langmap' */
+    else if (varp == &p_langmap)
+	langmap_set();
+#endif
+
+#ifdef FEAT_LINEBREAK
+    /* 'breakat' */
+    else if (varp == &p_breakat)
+	fill_breakat_flags();
+#endif
+
+#ifdef FEAT_TITLE
+    /* 'titlestring' and 'iconstring' */
+    else if (varp == &p_titlestring || varp == &p_iconstring)
+    {
+# ifdef FEAT_STL_OPT
+	int	flagval = (varp == &p_titlestring) ? STL_IN_TITLE : STL_IN_ICON;
+
+	/* NULL => statusline syntax */
+	if (vim_strchr(*varp, '%') && check_stl_option(*varp) == NULL)
+	    stl_syntax |= flagval;
+	else
+	    stl_syntax &= ~flagval;
+# endif
+	did_set_title(varp == &p_iconstring);
+
+    }
+#endif
+
+#ifdef FEAT_GUI
+    /* 'guioptions' */
+    else if (varp == &p_go)
+	gui_init_which_components(oldval);
+#endif
+
+#if defined(FEAT_GUI_TABLINE)
+    /* 'guitablabel' */
+    else if (varp == &p_gtl)
+	redraw_tabline = TRUE;
+#endif
+
+#if defined(FEAT_MOUSE_TTY) && (defined(UNIX) || defined(VMS))
+    /* 'ttymouse' */
+    else if (varp == &p_ttym)
+    {
+	/* Switch the mouse off before changing the escape sequences used for
+	 * that. */
+	mch_setmouse(FALSE);
+	if (opt_strings_flags(p_ttym, p_ttym_values, &ttym_flags, FALSE) != OK)
+	    errmsg = e_invarg;
+	else
+	    check_mouse_termcode();
+	if (termcap_active)
+	    setmouse();		/* may switch it on again */
+    }
+#endif
+
+#ifdef FEAT_VISUAL
+    /* 'selection' */
+    else if (varp == &p_sel)
+    {
+	if (*p_sel == NUL
+		|| check_opt_strings(p_sel, p_sel_values, FALSE) != OK)
+	    errmsg = e_invarg;
+    }
+
+    /* 'selectmode' */
+    else if (varp == &p_slm)
+    {
+	if (check_opt_strings(p_slm, p_slm_values, TRUE) != OK)
+	    errmsg = e_invarg;
+    }
+#endif
+
+#ifdef FEAT_BROWSE
+    /* 'browsedir' */
+    else if (varp == &p_bsdir)
+    {
+	if (check_opt_strings(p_bsdir, p_bsdir_values, FALSE) != OK
+		&& !mch_isdir(p_bsdir))
+	    errmsg = e_invarg;
+    }
+#endif
+
+#ifdef FEAT_VISUAL
+    /* 'keymodel' */
+    else if (varp == &p_km)
+    {
+	if (check_opt_strings(p_km, p_km_values, TRUE) != OK)
+	    errmsg = e_invarg;
+	else
+	{
+	    km_stopsel = (vim_strchr(p_km, 'o') != NULL);
+	    km_startsel = (vim_strchr(p_km, 'a') != NULL);
+	}
+    }
+#endif
+
+    /* 'mousemodel' */
+    else if (varp == &p_mousem)
+    {
+	if (check_opt_strings(p_mousem, p_mousem_values, FALSE) != OK)
+	    errmsg = e_invarg;
+#if defined(FEAT_GUI_MOTIF) && defined(FEAT_MENU) && (XmVersion <= 1002)
+	else if (*p_mousem != *oldval)
+	    /* Changed from "extend" to "popup" or "popup_setpos" or vv: need
+	     * to create or delete the popup menus. */
+	    gui_motif_update_mousemodel(root_menu);
+#endif
+    }
+
+    /* 'switchbuf' */
+    else if (varp == &p_swb)
+    {
+	if (check_opt_strings(p_swb, p_swb_values, TRUE) != OK)
+	    errmsg = e_invarg;
+    }
+
+    /* 'debug' */
+    else if (varp == &p_debug)
+    {
+	if (check_opt_strings(p_debug, p_debug_values, TRUE) != OK)
+	    errmsg = e_invarg;
+    }
+
+    /* 'display' */
+    else if (varp == &p_dy)
+    {
+	if (opt_strings_flags(p_dy, p_dy_values, &dy_flags, TRUE) != OK)
+	    errmsg = e_invarg;
+	else
+	    (void)init_chartab();
+
+    }
+
+#ifdef FEAT_VERTSPLIT
+    /* 'eadirection' */
+    else if (varp == &p_ead)
+    {
+	if (check_opt_strings(p_ead, p_ead_values, FALSE) != OK)
+	    errmsg = e_invarg;
+    }
+#endif
+
+#ifdef FEAT_CLIPBOARD
+    /* 'clipboard' */
+    else if (varp == &p_cb)
+	errmsg = check_clipboard_option();
+#endif
+
+#ifdef FEAT_SPELL
+    /* When 'spelllang' or 'spellfile' is set and there is a window for this
+     * buffer in which 'spell' is set load the wordlists. */
+    else if (varp == &(curbuf->b_p_spl) || varp == &(curbuf->b_p_spf))
+    {
+	win_T	    *wp;
+	int	    l;
+
+	if (varp == &(curbuf->b_p_spf))
+	{
+	    l = (int)STRLEN(curbuf->b_p_spf);
+	    if (l > 0 && (l < 4 || STRCMP(curbuf->b_p_spf + l - 4,
+								".add") != 0))
+		errmsg = e_invarg;
+	}
+
+	if (errmsg == NULL)
+	{
+	    FOR_ALL_WINDOWS(wp)
+		if (wp->w_buffer == curbuf && wp->w_p_spell)
+		{
+		    errmsg = did_set_spelllang(curbuf);
+# ifdef FEAT_WINDOWS
+		    break;
+# endif
+		}
+	}
+    }
+    /* When 'spellcapcheck' is set compile the regexp program. */
+    else if (varp == &(curbuf->b_p_spc))
+    {
+	errmsg = compile_cap_prog(curbuf);
+    }
+    /* 'spellsuggest' */
+    else if (varp == &p_sps)
+    {
+	if (spell_check_sps() != OK)
+	    errmsg = e_invarg;
+    }
+    /* 'mkspellmem' */
+    else if (varp == &p_msm)
+    {
+	if (spell_check_msm() != OK)
+	    errmsg = e_invarg;
+    }
+#endif
+
+#ifdef FEAT_QUICKFIX
+    /* When 'bufhidden' is set, check for valid value. */
+    else if (gvarp == &p_bh)
+    {
+	if (check_opt_strings(curbuf->b_p_bh, p_bufhidden_values, FALSE) != OK)
+	    errmsg = e_invarg;
+    }
+
+    /* When 'buftype' is set, check for valid value. */
+    else if (gvarp == &p_bt)
+    {
+	if (check_opt_strings(curbuf->b_p_bt, p_buftype_values, FALSE) != OK)
+	    errmsg = e_invarg;
+	else
+	{
+# ifdef FEAT_WINDOWS
+	    if (curwin->w_status_height)
+	    {
+		curwin->w_redr_status = TRUE;
+		redraw_later(VALID);
+	    }
+# endif
+	    curbuf->b_help = (curbuf->b_p_bt[0] == 'h');
+	}
+    }
+#endif
+
+#ifdef FEAT_STL_OPT
+    /* 'statusline' or 'rulerformat' */
+    else if (gvarp == &p_stl || varp == &p_ruf)
+    {
+	int wid;
+
+	if (varp == &p_ruf)	/* reset ru_wid first */
+	    ru_wid = 0;
+	s = *varp;
+	if (varp == &p_ruf && *s == '%')
+	{
+	    /* set ru_wid if 'ruf' starts with "%99(" */
+	    if (*++s == '-')	/* ignore a '-' */
+		s++;
+	    wid = getdigits(&s);
+	    if (wid && *s == '(' && (errmsg = check_stl_option(p_ruf)) == NULL)
+		ru_wid = wid;
+	    else
+		errmsg = check_stl_option(p_ruf);
+	}
+	/* check 'statusline' only if it doesn't start with "%!" */
+	else if (varp != &p_stl || s[0] != '%' || s[1] != '!')
+	    errmsg = check_stl_option(s);
+	if (varp == &p_ruf && errmsg == NULL)
+	    comp_col();
+    }
+#endif
+
+#ifdef FEAT_INS_EXPAND
+    /* check if it is a valid value for 'complete' -- Acevedo */
+    else if (gvarp == &p_cpt)
+    {
+	for (s = *varp; *s;)
+	{
+	    while(*s == ',' || *s == ' ')
+		s++;
+	    if (!*s)
+		break;
+	    if (vim_strchr((char_u *)".wbuksid]tU", *s) == NULL)
+	    {
+		errmsg = illegal_char(errbuf, *s);
+		break;
+	    }
+	    if (*++s != NUL && *s != ',' && *s != ' ')
+	    {
+		if (s[-1] == 'k' || s[-1] == 's')
+		{
+		    /* skip optional filename after 'k' and 's' */
+		    while (*s && *s != ',' && *s != ' ')
+		    {
+			if (*s == '\\')
+			    ++s;
+			++s;
+		    }
+		}
+		else
+		{
+		    if (errbuf != NULL)
+		    {
+			sprintf((char *)errbuf,
+				     _("E535: Illegal character after <%c>"),
+				     *--s);
+			errmsg = errbuf;
+		    }
+		    else
+			errmsg = (char_u *)"";
+		    break;
+		}
+	    }
+	}
+    }
+
+    /* 'completeopt' */
+    else if (varp == &p_cot)
+    {
+	if (check_opt_strings(p_cot, p_cot_values, TRUE) != OK)
+	    errmsg = e_invarg;
+    }
+#endif /* FEAT_INS_EXPAND */
+
+
+#if defined(FEAT_TOOLBAR) && !defined(FEAT_GUI_W32)
+    else if (varp == &p_toolbar)
+    {
+	if (opt_strings_flags(p_toolbar, p_toolbar_values,
+			      &toolbar_flags, TRUE) != OK)
+	    errmsg = e_invarg;
+	else
+	{
+	    out_flush();
+	    gui_mch_show_toolbar((toolbar_flags &
+				  (TOOLBAR_TEXT | TOOLBAR_ICONS)) != 0);
+	}
+    }
+#endif
+
+#if defined(FEAT_TOOLBAR) && defined(FEAT_GUI_GTK) && defined(HAVE_GTK2)
+    /* 'toolbariconsize': GTK+ 2 only */
+    else if (varp == &p_tbis)
+    {
+	if (opt_strings_flags(p_tbis, p_tbis_values, &tbis_flags, FALSE) != OK)
+	    errmsg = e_invarg;
+	else
+	{
+	    out_flush();
+	    gui_mch_show_toolbar((toolbar_flags &
+				  (TOOLBAR_TEXT | TOOLBAR_ICONS)) != 0);
+	}
+    }
+#endif
+
+    /* 'pastetoggle': translate key codes like in a mapping */
+    else if (varp == &p_pt)
+    {
+	if (*p_pt)
+	{
+	    (void)replace_termcodes(p_pt, &p, TRUE, TRUE, FALSE);
+	    if (p != NULL)
+	    {
+		if (new_value_alloced)
+		    free_string_option(p_pt);
+		p_pt = p;
+		new_value_alloced = TRUE;
+	    }
+	}
+    }
+
+    /* 'backspace' */
+    else if (varp == &p_bs)
+    {
+	if (VIM_ISDIGIT(*p_bs))
+	{
+	    if (*p_bs >'2' || p_bs[1] != NUL)
+		errmsg = e_invarg;
+	}
+	else if (check_opt_strings(p_bs, p_bs_values, TRUE) != OK)
+	    errmsg = e_invarg;
+    }
+
+#ifdef FEAT_MBYTE
+    /* 'casemap' */
+    else if (varp == &p_cmp)
+    {
+	if (opt_strings_flags(p_cmp, p_cmp_values, &cmp_flags, TRUE) != OK)
+	    errmsg = e_invarg;
+    }
+#endif
+
+#ifdef FEAT_DIFF
+    /* 'diffopt' */
+    else if (varp == &p_dip)
+    {
+	if (diffopt_changed() == FAIL)
+	    errmsg = e_invarg;
+    }
+#endif
+
+#ifdef FEAT_FOLDING
+    /* 'foldmethod' */
+    else if (gvarp == &curwin->w_allbuf_opt.wo_fdm)
+    {
+	if (check_opt_strings(*varp, p_fdm_values, FALSE) != OK
+		|| *curwin->w_p_fdm == NUL)
+	    errmsg = e_invarg;
+	else
+	    foldUpdateAll(curwin);
+    }
+# ifdef FEAT_EVAL
+    /* 'foldexpr' */
+    else if (varp == &curwin->w_p_fde)
+    {
+	if (foldmethodIsExpr(curwin))
+	    foldUpdateAll(curwin);
+    }
+# endif
+    /* 'foldmarker' */
+    else if (gvarp == &curwin->w_allbuf_opt.wo_fmr)
+    {
+	p = vim_strchr(*varp, ',');
+	if (p == NULL)
+	    errmsg = (char_u *)N_("E536: comma required");
+	else if (p == *varp || p[1] == NUL)
+	    errmsg = e_invarg;
+	else if (foldmethodIsMarker(curwin))
+	    foldUpdateAll(curwin);
+    }
+    /* 'commentstring' */
+    else if (gvarp == &p_cms)
+    {
+	if (**varp != NUL && strstr((char *)*varp, "%s") == NULL)
+	    errmsg = (char_u *)N_("E537: 'commentstring' must be empty or contain %s");
+    }
+    /* 'foldopen' */
+    else if (varp == &p_fdo)
+    {
+	if (opt_strings_flags(p_fdo, p_fdo_values, &fdo_flags, TRUE) != OK)
+	    errmsg = e_invarg;
+    }
+    /* 'foldclose' */
+    else if (varp == &p_fcl)
+    {
+	if (check_opt_strings(p_fcl, p_fcl_values, TRUE) != OK)
+	    errmsg = e_invarg;
+    }
+    /* 'foldignore' */
+    else if (gvarp == &curwin->w_allbuf_opt.wo_fdi)
+    {
+	if (foldmethodIsIndent(curwin))
+	    foldUpdateAll(curwin);
+    }
+#endif
+
+#ifdef FEAT_VIRTUALEDIT
+    /* 'virtualedit' */
+    else if (varp == &p_ve)
+    {
+	if (opt_strings_flags(p_ve, p_ve_values, &ve_flags, TRUE) != OK)
+	    errmsg = e_invarg;
+	else if (STRCMP(p_ve, oldval) != 0)
+	{
+	    /* Recompute cursor position in case the new 've' setting
+	     * changes something. */
+	    validate_virtcol();
+	    coladvance(curwin->w_virtcol);
+	}
+    }
+#endif
+
+#if defined(FEAT_CSCOPE) && defined(FEAT_QUICKFIX)
+    else if (varp == &p_csqf)
+    {
+	if (p_csqf != NULL)
+	{
+	    p = p_csqf;
+	    while (*p != NUL)
+	    {
+		if (vim_strchr((char_u *)CSQF_CMDS, *p) == NULL
+			|| p[1] == NUL
+			|| vim_strchr((char_u *)CSQF_FLAGS, p[1]) == NULL
+			|| (p[2] != NUL && p[2] != ','))
+		{
+		    errmsg = e_invarg;
+		    break;
+		}
+		else if (p[2] == NUL)
+		    break;
+		else
+		    p += 3;
+	    }
+	}
+    }
+#endif
+
+    /* Options that are a list of flags. */
+    else
+    {
+	p = NULL;
+	if (varp == &p_ww)
+	    p = (char_u *)WW_ALL;
+	if (varp == &p_shm)
+	    p = (char_u *)SHM_ALL;
+	else if (varp == &(p_cpo))
+	    p = (char_u *)CPO_ALL;
+	else if (varp == &(curbuf->b_p_fo))
+	    p = (char_u *)FO_ALL;
+	else if (varp == &p_mouse)
+	{
+#ifdef FEAT_MOUSE
+	    p = (char_u *)MOUSE_ALL;
+#else
+	    if (*p_mouse != NUL)
+		errmsg = (char_u *)N_("E538: No mouse support");
+#endif
+	}
+#if defined(FEAT_GUI)
+	else if (varp == &p_go)
+	    p = (char_u *)GO_ALL;
+#endif
+	if (p != NULL)
+	{
+	    for (s = *varp; *s; ++s)
+		if (vim_strchr(p, *s) == NULL)
+		{
+		    errmsg = illegal_char(errbuf, *s);
+		    break;
+		}
+	}
+    }
+
+    /*
+     * If error detected, restore the previous value.
+     */
+    if (errmsg != NULL)
+    {
+	if (new_value_alloced)
+	    free_string_option(*varp);
+	*varp = oldval;
+	/*
+	 * When resetting some values, need to act on it.
+	 */
+	if (did_chartab)
+	    (void)init_chartab();
+	if (varp == &p_hl)
+	    (void)highlight_changed();
+    }
+    else
+    {
+#ifdef FEAT_EVAL
+	/* Remember where the option was set. */
+	set_option_scriptID_idx(opt_idx, opt_flags, current_SID);
+#endif
+	/*
+	 * Free string options that are in allocated memory.
+	 * Use "free_oldval", because recursiveness may change the flags under
+	 * our fingers (esp. init_highlight()).
+	 */
+	if (free_oldval)
+	    free_string_option(oldval);
+	if (new_value_alloced)
+	    options[opt_idx].flags |= P_ALLOCED;
+	else
+	    options[opt_idx].flags &= ~P_ALLOCED;
+
+	if ((opt_flags & (OPT_LOCAL | OPT_GLOBAL)) == 0
+		&& ((int)options[opt_idx].indir & PV_BOTH))
+	{
+	    /* global option with local value set to use global value; free
+	     * the local value and make it empty */
+	    p = get_varp_scope(&(options[opt_idx]), OPT_LOCAL);
+	    free_string_option(*(char_u **)p);
+	    *(char_u **)p = empty_option;
+	}
+
+	/* May set global value for local option. */
+	else if (!(opt_flags & OPT_LOCAL) && opt_flags != OPT_GLOBAL)
+	    set_string_option_global(opt_idx, varp);
+
+#ifdef FEAT_AUTOCMD
+	/*
+	 * Trigger the autocommand only after setting the flags.
+	 */
+# ifdef FEAT_SYN_HL
+	/* When 'syntax' is set, load the syntax of that name */
+	if (varp == &(curbuf->b_p_syn))
+	{
+	    apply_autocmds(EVENT_SYNTAX, curbuf->b_p_syn,
+					       curbuf->b_fname, TRUE, curbuf);
+	}
+# endif
+	else if (varp == &(curbuf->b_p_ft))
+	{
+	    /* 'filetype' is set, trigger the FileType autocommand */
+	    did_filetype = TRUE;
+	    apply_autocmds(EVENT_FILETYPE, curbuf->b_p_ft,
+					       curbuf->b_fname, TRUE, curbuf);
+	}
+#endif
+#ifdef FEAT_SPELL
+	if (varp == &(curbuf->b_p_spl))
+	{
+	    char_u	fname[200];
+
+	    /*
+	     * Source the spell/LANG.vim in 'runtimepath'.
+	     * They could set 'spellcapcheck' depending on the language.
+	     * Use the first name in 'spelllang' up to '_region' or
+	     * '.encoding'.
+	     */
+	    for (p = curbuf->b_p_spl; *p != NUL; ++p)
+		if (vim_strchr((char_u *)"_.,", *p) != NULL)
+		    break;
+	    vim_snprintf((char *)fname, 200, "spell/%.*s.vim",
+				 (int)(p - curbuf->b_p_spl), curbuf->b_p_spl);
+	    source_runtime(fname, TRUE);
+	}
+#endif
+    }
+
+#ifdef FEAT_MOUSE
+    if (varp == &p_mouse)
+    {
+# ifdef FEAT_MOUSE_TTY
+	if (*p_mouse == NUL)
+	    mch_setmouse(FALSE);    /* switch mouse off */
+	else
+# endif
+	    setmouse();		    /* in case 'mouse' changed */
+    }
+#endif
+
+    if (curwin->w_curswant != MAXCOL)
+	curwin->w_set_curswant = TRUE;  /* in case 'showbreak' changed */
+    check_redraw(options[opt_idx].flags);
+
+    return errmsg;
+}
+
+/*
+ * Handle setting 'listchars' or 'fillchars'.
+ * Returns error message, NULL if it's OK.
+ */
+    static char_u *
+set_chars_option(varp)
+    char_u	**varp;
+{
+    int		round, i, len, entries;
+    char_u	*p, *s;
+    int		c1, c2 = 0;
+    struct charstab
+    {
+	int	*cp;
+	char	*name;
+    };
+#if defined(FEAT_WINDOWS) || defined(FEAT_FOLDING)
+    static struct charstab filltab[] =
+    {
+	{&fill_stl,	"stl"},
+	{&fill_stlnc,	"stlnc"},
+	{&fill_vert,	"vert"},
+	{&fill_fold,	"fold"},
+	{&fill_diff,	"diff"},
+    };
+#endif
+    static struct charstab lcstab[] =
+    {
+	{&lcs_eol,	"eol"},
+	{&lcs_ext,	"extends"},
+	{&lcs_nbsp,	"nbsp"},
+	{&lcs_prec,	"precedes"},
+	{&lcs_tab2,	"tab"},
+	{&lcs_trail,	"trail"},
+    };
+    struct charstab *tab;
+
+#if defined(FEAT_WINDOWS) || defined(FEAT_FOLDING)
+    if (varp == &p_lcs)
+#endif
+    {
+	tab = lcstab;
+	entries = sizeof(lcstab) / sizeof(struct charstab);
+    }
+#if defined(FEAT_WINDOWS) || defined(FEAT_FOLDING)
+    else
+    {
+	tab = filltab;
+	entries = sizeof(filltab) / sizeof(struct charstab);
+    }
+#endif
+
+    /* first round: check for valid value, second round: assign values */
+    for (round = 0; round <= 1; ++round)
+    {
+	if (round)
+	{
+	    /* After checking that the value is valid: set defaults: space for
+	     * 'fillchars', NUL for 'listchars' */
+	    for (i = 0; i < entries; ++i)
+		*(tab[i].cp) = (varp == &p_lcs ? NUL : ' ');
+	    if (varp == &p_lcs)
+		lcs_tab1 = NUL;
+#if defined(FEAT_WINDOWS) || defined(FEAT_FOLDING)
+	    else
+		fill_diff = '-';
+#endif
+	}
+	p = *varp;
+	while (*p)
+	{
+	    for (i = 0; i < entries; ++i)
+	    {
+		len = (int)STRLEN(tab[i].name);
+		if (STRNCMP(p, tab[i].name, len) == 0
+			&& p[len] == ':'
+			&& p[len + 1] != NUL)
+		{
+		    s = p + len + 1;
+#ifdef FEAT_MBYTE
+		    c1 = mb_ptr2char_adv(&s);
+		    if (mb_char2cells(c1) > 1)
+			continue;
+#else
+		    c1 = *s++;
+#endif
+		    if (tab[i].cp == &lcs_tab2)
+		    {
+			if (*s == NUL)
+			    continue;
+#ifdef FEAT_MBYTE
+			c2 = mb_ptr2char_adv(&s);
+			if (mb_char2cells(c2) > 1)
+			    continue;
+#else
+			c2 = *s++;
+#endif
+		    }
+		    if (*s == ',' || *s == NUL)
+		    {
+			if (round)
+			{
+			    if (tab[i].cp == &lcs_tab2)
+			    {
+				lcs_tab1 = c1;
+				lcs_tab2 = c2;
+			    }
+			    else
+				*(tab[i].cp) = c1;
+
+			}
+			p = s;
+			break;
+		    }
+		}
+	    }
+
+	    if (i == entries)
+		return e_invarg;
+	    if (*p == ',')
+		++p;
+	}
+    }
+
+    return NULL;	/* no error */
+}
+
+#ifdef FEAT_STL_OPT
+/*
+ * Check validity of options with the 'statusline' format.
+ * Return error message or NULL.
+ */
+    char_u *
+check_stl_option(s)
+    char_u	*s;
+{
+    int		itemcnt = 0;
+    int		groupdepth = 0;
+    static char_u   errbuf[80];
+
+    while (*s && itemcnt < STL_MAX_ITEM)
+    {
+	/* Check for valid keys after % sequences */
+	while (*s && *s != '%')
+	    s++;
+	if (!*s)
+	    break;
+	s++;
+	if (*s != '%' && *s != ')')
+	    ++itemcnt;
+	if (*s == '%' || *s == STL_TRUNCMARK || *s == STL_MIDDLEMARK)
+	{
+	    s++;
+	    continue;
+	}
+	if (*s == ')')
+	{
+	    s++;
+	    if (--groupdepth < 0)
+		break;
+	    continue;
+	}
+	if (*s == '-')
+	    s++;
+	while (VIM_ISDIGIT(*s))
+	    s++;
+	if (*s == STL_USER_HL)
+	    continue;
+	if (*s == '.')
+	{
+	    s++;
+	    while (*s && VIM_ISDIGIT(*s))
+		s++;
+	}
+	if (*s == '(')
+	{
+	    groupdepth++;
+	    continue;
+	}
+	if (vim_strchr(STL_ALL, *s) == NULL)
+	{
+	    return illegal_char(errbuf, *s);
+	}
+	if (*s == '{')
+	{
+	    s++;
+	    while (*s != '}' && *s)
+		s++;
+	    if (*s != '}')
+		return (char_u *)N_("E540: Unclosed expression sequence");
+	}
+    }
+    if (itemcnt >= STL_MAX_ITEM)
+	return (char_u *)N_("E541: too many items");
+    if (groupdepth != 0)
+	return (char_u *)N_("E542: unbalanced groups");
+    return NULL;
+}
+#endif
+
+#ifdef FEAT_CLIPBOARD
+/*
+ * Extract the items in the 'clipboard' option and set global values.
+ */
+    static char_u *
+check_clipboard_option()
+{
+    int		new_unnamed = FALSE;
+    int		new_autoselect = FALSE;
+    int		new_autoselectml = FALSE;
+    regprog_T	*new_exclude_prog = NULL;
+    char_u	*errmsg = NULL;
+    char_u	*p;
+
+    for (p = p_cb; *p != NUL; )
+    {
+	if (STRNCMP(p, "unnamed", 7) == 0 && (p[7] == ',' || p[7] == NUL))
+	{
+	    new_unnamed = TRUE;
+	    p += 7;
+	}
+	else if (STRNCMP(p, "autoselect", 10) == 0
+					&& (p[10] == ',' || p[10] == NUL))
+	{
+	    new_autoselect = TRUE;
+	    p += 10;
+	}
+	else if (STRNCMP(p, "autoselectml", 12) == 0
+					&& (p[12] == ',' || p[12] == NUL))
+	{
+	    new_autoselectml = TRUE;
+	    p += 12;
+	}
+	else if (STRNCMP(p, "exclude:", 8) == 0 && new_exclude_prog == NULL)
+	{
+	    p += 8;
+	    new_exclude_prog = vim_regcomp(p, RE_MAGIC);
+	    if (new_exclude_prog == NULL)
+		errmsg = e_invarg;
+	    break;
+	}
+	else
+	{
+	    errmsg = e_invarg;
+	    break;
+	}
+	if (*p == ',')
+	    ++p;
+    }
+    if (errmsg == NULL)
+    {
+	clip_unnamed = new_unnamed;
+	clip_autoselect = new_autoselect;
+	clip_autoselectml = new_autoselectml;
+	vim_free(clip_exclude_prog);
+	clip_exclude_prog = new_exclude_prog;
+    }
+    else
+	vim_free(new_exclude_prog);
+
+    return errmsg;
+}
+#endif
+
+#ifdef FEAT_SPELL
+/*
+ * Set curbuf->b_cap_prog to the regexp program for 'spellcapcheck'.
+ * Return error message when failed, NULL when OK.
+ */
+    static char_u *
+compile_cap_prog(buf)
+    buf_T	*buf;
+{
+    regprog_T   *rp = buf->b_cap_prog;
+    char_u	*re;
+
+    if (*buf->b_p_spc == NUL)
+	buf->b_cap_prog = NULL;
+    else
+    {
+	/* Prepend a ^ so that we only match at one column */
+	re = concat_str((char_u *)"^", buf->b_p_spc);
+	if (re != NULL)
+	{
+	    buf->b_cap_prog = vim_regcomp(re, RE_MAGIC);
+	    if (buf->b_cap_prog == NULL)
+	    {
+		buf->b_cap_prog = rp; /* restore the previous program */
+		return e_invarg;
+	    }
+	    vim_free(re);
+	}
+    }
+
+    vim_free(rp);
+    return NULL;
+}
+#endif
+
+#if defined(FEAT_EVAL) || defined(PROTO)
+/*
+ * Set the scriptID for an option, taking care of setting the buffer- or
+ * window-local value.
+ */
+    static void
+set_option_scriptID_idx(opt_idx, opt_flags, id)
+    int	    opt_idx;
+    int	    opt_flags;
+    int	    id;
+{
+    int		both = (opt_flags & (OPT_LOCAL | OPT_GLOBAL)) == 0;
+    int		indir = (int)options[opt_idx].indir;
+
+    /* Remember where the option was set.  For local options need to do that
+     * in the buffer or window structure. */
+    if (both || (opt_flags & OPT_GLOBAL) || (indir & (PV_BUF|PV_WIN)) == 0)
+	options[opt_idx].scriptID = id;
+    if (both || (opt_flags & OPT_LOCAL))
+    {
+	if (indir & PV_BUF)
+	    curbuf->b_p_scriptID[indir & PV_MASK] = id;
+	else if (indir & PV_WIN)
+	    curwin->w_p_scriptID[indir & PV_MASK] = id;
+    }
+}
+#endif
+
+/*
+ * Set the value of a boolean option, and take care of side effects.
+ * Returns NULL for success, or an error message for an error.
+ */
+    static char_u *
+set_bool_option(opt_idx, varp, value, opt_flags)
+    int		opt_idx;		/* index in options[] table */
+    char_u	*varp;			/* pointer to the option variable */
+    int		value;			/* new value */
+    int		opt_flags;		/* OPT_LOCAL and/or OPT_GLOBAL */
+{
+    int		old_value = *(int *)varp;
+
+    /* Disallow changing some options from secure mode */
+    if ((secure
+#ifdef HAVE_SANDBOX
+		|| sandbox != 0
+#endif
+		) && (options[opt_idx].flags & P_SECURE))
+	return e_secure;
+
+    *(int *)varp = value;	    /* set the new value */
+#ifdef FEAT_EVAL
+    /* Remember where the option was set. */
+    set_option_scriptID_idx(opt_idx, opt_flags, current_SID);
+#endif
+
+#ifdef FEAT_GUI
+    need_mouse_correct = TRUE;
+#endif
+
+    /* May set global value for local option. */
+    if ((opt_flags & (OPT_LOCAL | OPT_GLOBAL)) == 0)
+	*(int *)get_varp_scope(&(options[opt_idx]), OPT_GLOBAL) = value;
+
+    /*
+     * Handle side effects of changing a bool option.
+     */
+
+    /* 'compatible' */
+    if ((int *)varp == &p_cp)
+    {
+	compatible_set();
+    }
+
+    else if ((int *)varp == &curbuf->b_p_ro)
+    {
+	/* when 'readonly' is reset globally, also reset readonlymode */
+	if (!curbuf->b_p_ro && (opt_flags & OPT_LOCAL) == 0)
+	    readonlymode = FALSE;
+
+	/* when 'readonly' is set may give W10 again */
+	if (curbuf->b_p_ro)
+	    curbuf->b_did_warn = FALSE;
+
+#ifdef FEAT_TITLE
+	need_maketitle = TRUE;
+#endif
+    }
+
+#ifdef FEAT_TITLE
+    /* when 'modifiable' is changed, redraw the window title */
+    else if ((int *)varp == &curbuf->b_p_ma)
+	need_maketitle = TRUE;
+    /* when 'endofline' is changed, redraw the window title */
+    else if ((int *)varp == &curbuf->b_p_eol)
+	need_maketitle = TRUE;
+#endif
+
+    /* when 'bin' is set also set some other options */
+    else if ((int *)varp == &curbuf->b_p_bin)
+    {
+	set_options_bin(old_value, curbuf->b_p_bin, opt_flags);
+#ifdef FEAT_TITLE
+	need_maketitle = TRUE;
+#endif
+    }
+
+#ifdef FEAT_AUTOCMD
+    /* when 'buflisted' changes, trigger autocommands */
+    else if ((int *)varp == &curbuf->b_p_bl && old_value != curbuf->b_p_bl)
+    {
+	apply_autocmds(curbuf->b_p_bl ? EVENT_BUFADD : EVENT_BUFDELETE,
+						    NULL, NULL, TRUE, curbuf);
+    }
+#endif
+
+    /* when 'swf' is set, create swapfile, when reset remove swapfile */
+    else if ((int *)varp == &curbuf->b_p_swf)
+    {
+	if (curbuf->b_p_swf && p_uc)
+	    ml_open_file(curbuf);		/* create the swap file */
+	else
+	    /* no need to reset curbuf->b_may_swap, ml_open_file() will check
+	     * buf->b_p_swf */
+	    mf_close_file(curbuf, TRUE);	/* remove the swap file */
+    }
+
+    /* when 'terse' is set change 'shortmess' */
+    else if ((int *)varp == &p_terse)
+    {
+	char_u	*p;
+
+	p = vim_strchr(p_shm, SHM_SEARCH);
+
+	/* insert 's' in p_shm */
+	if (p_terse && p == NULL)
+	{
+	    STRCPY(IObuff, p_shm);
+	    STRCAT(IObuff, "s");
+	    set_string_option_direct((char_u *)"shm", -1, IObuff, OPT_FREE, 0);
+	}
+	/* remove 's' from p_shm */
+	else if (!p_terse && p != NULL)
+	    mch_memmove(p, p + 1, STRLEN(p));
+    }
+
+    /* when 'paste' is set or reset also change other options */
+    else if ((int *)varp == &p_paste)
+    {
+	paste_option_changed();
+    }
+
+    /* when 'insertmode' is set from an autocommand need to do work here */
+    else if ((int *)varp == &p_im)
+    {
+	if (p_im)
+	{
+	    if ((State & INSERT) == 0)
+		need_start_insertmode = TRUE;
+	    stop_insert_mode = FALSE;
+	}
+	else
+	{
+	    need_start_insertmode = FALSE;
+	    stop_insert_mode = TRUE;
+	    if (restart_edit != 0 && mode_displayed)
+		clear_cmdline = TRUE;	/* remove "(insert)" */
+	    restart_edit = 0;
+	}
+    }
+
+    /* when 'ignorecase' is set or reset and 'hlsearch' is set, redraw */
+    else if ((int *)varp == &p_ic && p_hls)
+    {
+	redraw_all_later(SOME_VALID);
+    }
+
+#ifdef FEAT_SEARCH_EXTRA
+    /* when 'hlsearch' is set or reset: reset no_hlsearch */
+    else if ((int *)varp == &p_hls)
+    {
+	no_hlsearch = FALSE;
+    }
+#endif
+
+#ifdef FEAT_SCROLLBIND
+    /* when 'scrollbind' is set: snapshot the current position to avoid a jump
+     * at the end of normal_cmd() */
+    else if ((int *)varp == &curwin->w_p_scb)
+    {
+	if (curwin->w_p_scb)
+	    do_check_scrollbind(FALSE);
+    }
+#endif
+
+#if defined(FEAT_WINDOWS) && defined(FEAT_QUICKFIX)
+    /* There can be only one window with 'previewwindow' set. */
+    else if ((int *)varp == &curwin->w_p_pvw)
+    {
+	if (curwin->w_p_pvw)
+	{
+	    win_T	*win;
+
+	    for (win = firstwin; win != NULL; win = win->w_next)
+		if (win->w_p_pvw && win != curwin)
+		{
+		    curwin->w_p_pvw = FALSE;
+		    return (char_u *)N_("E590: A preview window already exists");
+		}
+	}
+    }
+#endif
+
+    /* when 'textmode' is set or reset also change 'fileformat' */
+    else if ((int *)varp == &curbuf->b_p_tx)
+    {
+	set_fileformat(curbuf->b_p_tx ? EOL_DOS : EOL_UNIX, opt_flags);
+    }
+
+    /* when 'textauto' is set or reset also change 'fileformats' */
+    else if ((int *)varp == &p_ta)
+	set_string_option_direct((char_u *)"ffs", -1,
+				 p_ta ? (char_u *)DFLT_FFS_VIM : (char_u *)"",
+						     OPT_FREE | opt_flags, 0);
+
+    /*
+     * When 'lisp' option changes include/exclude '-' in
+     * keyword characters.
+     */
+#ifdef FEAT_LISP
+    else if (varp == (char_u *)&(curbuf->b_p_lisp))
+    {
+	(void)buf_init_chartab(curbuf, FALSE);	    /* ignore errors */
+    }
+#endif
+
+#ifdef FEAT_TITLE
+    /* when 'title' changed, may need to change the title; same for 'icon' */
+    else if ((int *)varp == &p_title)
+    {
+	did_set_title(FALSE);
+    }
+
+    else if ((int *)varp == &p_icon)
+    {
+	did_set_title(TRUE);
+    }
+#endif
+
+    else if ((int *)varp == &curbuf->b_changed)
+    {
+	if (!value)
+	    save_file_ff(curbuf);	/* Buffer is unchanged */
+#ifdef FEAT_TITLE
+	need_maketitle = TRUE;
+#endif
+#ifdef FEAT_AUTOCMD
+	modified_was_set = value;
+#endif
+    }
+
+#ifdef BACKSLASH_IN_FILENAME
+    else if ((int *)varp == &p_ssl)
+    {
+	if (p_ssl)
+	{
+	    psepc = '/';
+	    psepcN = '\\';
+	    pseps[0] = '/';
+	}
+	else
+	{
+	    psepc = '\\';
+	    psepcN = '/';
+	    pseps[0] = '\\';
+	}
+
+	/* need to adjust the file name arguments and buffer names. */
+	buflist_slash_adjust();
+	alist_slash_adjust();
+# ifdef FEAT_EVAL
+	scriptnames_slash_adjust();
+# endif
+    }
+#endif
+
+    /* If 'wrap' is set, set w_leftcol to zero. */
+    else if ((int *)varp == &curwin->w_p_wrap)
+    {
+	if (curwin->w_p_wrap)
+	    curwin->w_leftcol = 0;
+    }
+
+#ifdef FEAT_WINDOWS
+    else if ((int *)varp == &p_ea)
+    {
+	if (p_ea && !old_value)
+	    win_equal(curwin, FALSE, 0);
+    }
+#endif
+
+    else if ((int *)varp == &p_wiv)
+    {
+	/*
+	 * When 'weirdinvert' changed, set/reset 't_xs'.
+	 * Then set 'weirdinvert' according to value of 't_xs'.
+	 */
+	if (p_wiv && !old_value)
+	    T_XS = (char_u *)"y";
+	else if (!p_wiv && old_value)
+	    T_XS = empty_option;
+	p_wiv = (*T_XS != NUL);
+    }
+
+#ifdef FEAT_BEVAL
+    else if ((int *)varp == &p_beval)
+    {
+	if (p_beval == TRUE)
+	    gui_mch_enable_beval_area(balloonEval);
+	else
+	    gui_mch_disable_beval_area(balloonEval);
+    }
+#endif
+
+#ifdef FEAT_AUTOCHDIR
+    else if ((int *)varp == &p_acd)
+    {
+	/* Change directories when the 'acd' option is set now. */
+	DO_AUTOCHDIR
+    }
+#endif
+
+#ifdef FEAT_DIFF
+    /* 'diff' */
+    else if ((int *)varp == &curwin->w_p_diff)
+    {
+	/* May add or remove the buffer from the list of diff buffers. */
+	diff_buf_adjust(curwin);
+# ifdef FEAT_FOLDING
+	if (foldmethodIsDiff(curwin))
+	    foldUpdateAll(curwin);
+# endif
+    }
+#endif
+
+#ifdef USE_IM_CONTROL
+    /* 'imdisable' */
+    else if ((int *)varp == &p_imdisable)
+    {
+	/* Only de-activate it here, it will be enabled when changing mode. */
+	if (p_imdisable)
+	    im_set_active(FALSE);
+    }
+#endif
+
+#ifdef FEAT_SPELL
+    /* 'spell' */
+    else if ((int *)varp == &curwin->w_p_spell)
+    {
+	if (curwin->w_p_spell)
+	{
+	    char_u	*errmsg = did_set_spelllang(curbuf);
+
+	    if (errmsg != NULL)
+		EMSG(_(errmsg));
+	}
+    }
+#endif
+
+#ifdef FEAT_FKMAP
+    else if ((int *)varp == &p_altkeymap)
+    {
+	if (old_value != p_altkeymap)
+	{
+	    if (!p_altkeymap)
+	    {
+		p_hkmap = p_fkmap;
+		p_fkmap = 0;
+	    }
+	    else
+	    {
+		p_fkmap = p_hkmap;
+		p_hkmap = 0;
+	    }
+	    (void)init_chartab();
+	}
+    }
+
+    /*
+     * In case some second language keymapping options have changed, check
+     * and correct the setting in a consistent way.
+     */
+
+    /*
+     * If hkmap or fkmap are set, reset Arabic keymapping.
+     */
+    if ((p_hkmap || p_fkmap) && p_altkeymap)
+    {
+	p_altkeymap = p_fkmap;
+# ifdef FEAT_ARABIC
+	curwin->w_p_arab = FALSE;
+# endif
+	(void)init_chartab();
+    }
+
+    /*
+     * If hkmap set, reset Farsi keymapping.
+     */
+    if (p_hkmap && p_altkeymap)
+    {
+	p_altkeymap = 0;
+	p_fkmap = 0;
+# ifdef FEAT_ARABIC
+	curwin->w_p_arab = FALSE;
+# endif
+	(void)init_chartab();
+    }
+
+    /*
+     * If fkmap set, reset Hebrew keymapping.
+     */
+    if (p_fkmap && !p_altkeymap)
+    {
+	p_altkeymap = 1;
+	p_hkmap = 0;
+# ifdef FEAT_ARABIC
+	curwin->w_p_arab = FALSE;
+# endif
+	(void)init_chartab();
+    }
+#endif
+
+#ifdef FEAT_ARABIC
+    if ((int *)varp == &curwin->w_p_arab)
+    {
+	if (curwin->w_p_arab)
+	{
+	    /*
+	     * 'arabic' is set, handle various sub-settings.
+	     */
+	    if (!p_tbidi)
+	    {
+		/* set rightleft mode */
+		if (!curwin->w_p_rl)
+		{
+		    curwin->w_p_rl = TRUE;
+		    changed_window_setting();
+		}
+
+		/* Enable Arabic shaping (major part of what Arabic requires) */
+		if (!p_arshape)
+		{
+		    p_arshape = TRUE;
+		    redraw_later_clear();
+		}
+	    }
+
+	    /* Arabic requires a utf-8 encoding, inform the user if its not
+	     * set. */
+	    if (STRCMP(p_enc, "utf-8") != 0)
+	    {
+		msg_source(hl_attr(HLF_W));
+		MSG_ATTR(_("W17: Arabic requires UTF-8, do ':set encoding=utf-8'"),
+			hl_attr(HLF_W));
+	    }
+
+# ifdef FEAT_MBYTE
+	    /* set 'delcombine' */
+	    p_deco = TRUE;
+# endif
+
+# ifdef FEAT_KEYMAP
+	    /* Force-set the necessary keymap for arabic */
+	    set_option_value((char_u *)"keymap", 0L, (char_u *)"arabic",
+								   OPT_LOCAL);
+# endif
+# ifdef FEAT_FKMAP
+	    p_altkeymap = 0;
+	    p_hkmap = 0;
+	    p_fkmap = 0;
+	    (void)init_chartab();
+# endif
+	}
+	else
+	{
+	    /*
+	     * 'arabic' is reset, handle various sub-settings.
+	     */
+	    if (!p_tbidi)
+	    {
+		/* reset rightleft mode */
+		if (curwin->w_p_rl)
+		{
+		    curwin->w_p_rl = FALSE;
+		    changed_window_setting();
+		}
+
+		/* 'arabicshape' isn't reset, it is a global option and
+		 * another window may still need it "on". */
+	    }
+
+	    /* 'delcombine' isn't reset, it is a global option and another
+	     * window may still want it "on". */
+
+# ifdef FEAT_KEYMAP
+	    /* Revert to the default keymap */
+	    curbuf->b_p_iminsert = B_IMODE_NONE;
+	    curbuf->b_p_imsearch = B_IMODE_USE_INSERT;
+# endif
+	}
+    }
+#endif
+
+    /*
+     * End of handling side effects for bool options.
+     */
+
+    options[opt_idx].flags |= P_WAS_SET;
+
+    comp_col();			    /* in case 'ruler' or 'showcmd' changed */
+    if (curwin->w_curswant != MAXCOL)
+	curwin->w_set_curswant = TRUE;  /* in case 'list' changed */
+    check_redraw(options[opt_idx].flags);
+
+    return NULL;
+}
+
+/*
+ * Set the value of a number option, and take care of side effects.
+ * Returns NULL for success, or an error message for an error.
+ */
+    static char_u *
+set_num_option(opt_idx, varp, value, errbuf, errbuflen, opt_flags)
+    int		opt_idx;		/* index in options[] table */
+    char_u	*varp;			/* pointer to the option variable */
+    long	value;			/* new value */
+    char_u	*errbuf;		/* buffer for error messages */
+    size_t	errbuflen;		/* length of "errbuf" */
+    int		opt_flags;		/* OPT_LOCAL, OPT_GLOBAL and
+					   OPT_MODELINE */
+{
+    char_u	*errmsg = NULL;
+    long	old_value = *(long *)varp;
+    long	old_Rows = Rows;	/* remember old Rows */
+    long	old_Columns = Columns;	/* remember old Columns */
+    long	*pp = (long *)varp;
+
+    /* Disallow changing some options from secure mode. */
+    if ((secure
+#ifdef HAVE_SANDBOX
+		|| sandbox != 0
+#endif
+		) && (options[opt_idx].flags & P_SECURE))
+	return e_secure;
+
+    *pp = value;
+#ifdef FEAT_EVAL
+    /* Remember where the option was set. */
+    set_option_scriptID_idx(opt_idx, opt_flags, current_SID);
+#endif
+#ifdef FEAT_GUI
+    need_mouse_correct = TRUE;
+#endif
+
+    if (curbuf->b_p_sw <= 0)
+    {
+	errmsg = e_positive;
+	curbuf->b_p_sw = curbuf->b_p_ts;
+    }
+
+    /*
+     * Number options that need some action when changed
+     */
+#ifdef FEAT_WINDOWS
+    if (pp == &p_wh || pp == &p_hh)
+    {
+	if (p_wh < 1)
+	{
+	    errmsg = e_positive;
+	    p_wh = 1;
+	}
+	if (p_wmh > p_wh)
+	{
+	    errmsg = e_winheight;
+	    p_wh = p_wmh;
+	}
+	if (p_hh < 0)
+	{
+	    errmsg = e_positive;
+	    p_hh = 0;
+	}
+
+	/* Change window height NOW */
+	if (lastwin != firstwin)
+	{
+	    if (pp == &p_wh && curwin->w_height < p_wh)
+		win_setheight((int)p_wh);
+	    if (pp == &p_hh && curbuf->b_help && curwin->w_height < p_hh)
+		win_setheight((int)p_hh);
+	}
+    }
+
+    /* 'winminheight' */
+    else if (pp == &p_wmh)
+    {
+	if (p_wmh < 0)
+	{
+	    errmsg = e_positive;
+	    p_wmh = 0;
+	}
+	if (p_wmh > p_wh)
+	{
+	    errmsg = e_winheight;
+	    p_wmh = p_wh;
+	}
+	win_setminheight();
+    }
+
+# ifdef FEAT_VERTSPLIT
+    else if (pp == &p_wiw)
+    {
+	if (p_wiw < 1)
+	{
+	    errmsg = e_positive;
+	    p_wiw = 1;
+	}
+	if (p_wmw > p_wiw)
+	{
+	    errmsg = e_winwidth;
+	    p_wiw = p_wmw;
+	}
+
+	/* Change window width NOW */
+	if (lastwin != firstwin && curwin->w_width < p_wiw)
+	    win_setwidth((int)p_wiw);
+    }
+
+    /* 'winminwidth' */
+    else if (pp == &p_wmw)
+    {
+	if (p_wmw < 0)
+	{
+	    errmsg = e_positive;
+	    p_wmw = 0;
+	}
+	if (p_wmw > p_wiw)
+	{
+	    errmsg = e_winwidth;
+	    p_wmw = p_wiw;
+	}
+	win_setminheight();
+    }
+# endif
+
+#endif
+
+#ifdef FEAT_WINDOWS
+    /* (re)set last window status line */
+    else if (pp == &p_ls)
+    {
+	last_status(FALSE);
+    }
+
+    /* (re)set tab page line */
+    else if (pp == &p_stal)
+    {
+	shell_new_rows();	/* recompute window positions and heights */
+    }
+#endif
+
+#ifdef FEAT_GUI
+    else if (pp == &p_linespace)
+    {
+	/* Recompute gui.char_height and resize the Vim window to keep the
+	 * same number of lines. */
+	if (gui.in_use && gui_mch_adjust_charheight() == OK)
+	    gui_set_shellsize(FALSE, FALSE, RESIZE_VERT);
+    }
+#endif
+
+#ifdef FEAT_FOLDING
+    /* 'foldlevel' */
+    else if (pp == &curwin->w_p_fdl)
+    {
+	if (curwin->w_p_fdl < 0)
+	    curwin->w_p_fdl = 0;
+	newFoldLevel();
+    }
+
+    /* 'foldminlevel' */
+    else if (pp == &curwin->w_p_fml)
+    {
+	foldUpdateAll(curwin);
+    }
+
+    /* 'foldnestmax' */
+    else if (pp == &curwin->w_p_fdn)
+    {
+	if (foldmethodIsSyntax(curwin) || foldmethodIsIndent(curwin))
+	    foldUpdateAll(curwin);
+    }
+
+    /* 'foldcolumn' */
+    else if (pp == &curwin->w_p_fdc)
+    {
+	if (curwin->w_p_fdc < 0)
+	{
+	    errmsg = e_positive;
+	    curwin->w_p_fdc = 0;
+	}
+	else if (curwin->w_p_fdc > 12)
+	{
+	    errmsg = e_invarg;
+	    curwin->w_p_fdc = 12;
+	}
+    }
+
+    /* 'shiftwidth' or 'tabstop' */
+    else if (pp == &curbuf->b_p_sw || pp == &curbuf->b_p_ts)
+    {
+	if (foldmethodIsIndent(curwin))
+	    foldUpdateAll(curwin);
+    }
+#endif /* FEAT_FOLDING */
+
+#ifdef FEAT_MBYTE
+    /* 'maxcombine' */
+    else if (pp == &p_mco)
+    {
+	if (p_mco > MAX_MCO)
+	    p_mco = MAX_MCO;
+	else if (p_mco < 0)
+	    p_mco = 0;
+	screenclear();	    /* will re-allocate the screen */
+    }
+#endif
+
+    else if (pp == &curbuf->b_p_iminsert)
+    {
+	if (curbuf->b_p_iminsert < 0 || curbuf->b_p_iminsert > B_IMODE_LAST)
+	{
+	    errmsg = e_invarg;
+	    curbuf->b_p_iminsert = B_IMODE_NONE;
+	}
+	p_iminsert = curbuf->b_p_iminsert;
+	if (termcap_active)	/* don't do this in the alternate screen */
+	    showmode();
+#if defined(FEAT_WINDOWS) && defined(FEAT_KEYMAP)
+	/* Show/unshow value of 'keymap' in status lines. */
+	status_redraw_curbuf();
+#endif
+    }
+
+    else if (pp == &p_window)
+    {
+	if (p_window < 1)
+	    p_window = 1;
+	else if (p_window >= Rows)
+	    p_window = Rows - 1;
+    }
+
+    else if (pp == &curbuf->b_p_imsearch)
+    {
+	if (curbuf->b_p_imsearch < -1 || curbuf->b_p_imsearch > B_IMODE_LAST)
+	{
+	    errmsg = e_invarg;
+	    curbuf->b_p_imsearch = B_IMODE_NONE;
+	}
+	p_imsearch = curbuf->b_p_imsearch;
+    }
+
+#ifdef FEAT_TITLE
+    /* if 'titlelen' has changed, redraw the title */
+    else if (pp == &p_titlelen)
+    {
+	if (p_titlelen < 0)
+	{
+	    errmsg = e_positive;
+	    p_titlelen = 85;
+	}
+	if (starting != NO_SCREEN && old_value != p_titlelen)
+	    need_maketitle = TRUE;
+    }
+#endif
+
+    /* if p_ch changed value, change the command line height */
+    else if (pp == &p_ch)
+    {
+	if (p_ch < 1)
+	{
+	    errmsg = e_positive;
+	    p_ch = 1;
+	}
+
+	/* Only compute the new window layout when startup has been
+	 * completed. Otherwise the frame sizes may be wrong. */
+	if (p_ch != old_value && full_screen
+#ifdef FEAT_GUI
+		&& !gui.starting
+#endif
+	   )
+	    command_height();
+    }
+
+    /* when 'updatecount' changes from zero to non-zero, open swap files */
+    else if (pp == &p_uc)
+    {
+	if (p_uc < 0)
+	{
+	    errmsg = e_positive;
+	    p_uc = 100;
+	}
+	if (p_uc && !old_value)
+	    ml_open_files();
+    }
+#ifdef MZSCHEME_GUI_THREADS
+    else if (pp == &p_mzq)
+	mzvim_reset_timer();
+#endif
+
+    /* sync undo before 'undolevels' changes */
+    else if (pp == &p_ul)
+    {
+	/* use the old value, otherwise u_sync() may not work properly */
+	p_ul = old_value;
+	u_sync(TRUE);
+	p_ul = value;
+    }
+
+#ifdef FEAT_LINEBREAK
+    /* 'numberwidth' must be positive */
+    else if (pp == &curwin->w_p_nuw)
+    {
+	if (curwin->w_p_nuw < 1)
+	{
+	    errmsg = e_positive;
+	    curwin->w_p_nuw = 1;
+	}
+	if (curwin->w_p_nuw > 10)
+	{
+	    errmsg = e_invarg;
+	    curwin->w_p_nuw = 10;
+	}
+	curwin->w_nrwidth_line_count = 0;
+    }
+#endif
+
+    /*
+     * Check the bounds for numeric options here
+     */
+    if (Rows < min_rows() && full_screen)
+    {
+	if (errbuf != NULL)
+	{
+	    vim_snprintf((char *)errbuf, errbuflen,
+			       _("E593: Need at least %d lines"), min_rows());
+	    errmsg = errbuf;
+	}
+	Rows = min_rows();
+    }
+    if (Columns < MIN_COLUMNS && full_screen)
+    {
+	if (errbuf != NULL)
+	{
+	    vim_snprintf((char *)errbuf, errbuflen,
+			    _("E594: Need at least %d columns"), MIN_COLUMNS);
+	    errmsg = errbuf;
+	}
+	Columns = MIN_COLUMNS;
+    }
+    /* Limit the values to avoid an overflow in Rows * Columns. */
+    if (Columns > 10000)
+	Columns = 10000;
+    if (Rows > 1000)
+	Rows = 1000;
+
+#ifdef DJGPP
+    /* avoid a crash by checking for a too large value of 'columns' */
+    if (old_Columns != Columns && full_screen && term_console)
+	mch_check_columns();
+#endif
+
+    /*
+     * If the screen (shell) height has been changed, assume it is the
+     * physical screenheight.
+     */
+    if (old_Rows != Rows || old_Columns != Columns)
+    {
+	/* Changing the screen size is not allowed while updating the screen. */
+	if (updating_screen)
+	    *pp = old_value;
+	else if (full_screen
+#ifdef FEAT_GUI
+		&& !gui.starting
+#endif
+	    )
+	    set_shellsize((int)Columns, (int)Rows, TRUE);
+	else
+	{
+	    /* Postpone the resizing; check the size and cmdline position for
+	     * messages. */
+	    check_shellsize();
+	    if (cmdline_row > Rows - p_ch && Rows > p_ch)
+		cmdline_row = Rows - p_ch;
+	}
+	if (p_window >= Rows || !option_was_set((char_u *)"window"))
+	    p_window = Rows - 1;
+    }
+
+    if (curbuf->b_p_sts < 0)
+    {
+	errmsg = e_positive;
+	curbuf->b_p_sts = 0;
+    }
+    if (curbuf->b_p_ts <= 0)
+    {
+	errmsg = e_positive;
+	curbuf->b_p_ts = 8;
+    }
+    if (curbuf->b_p_tw < 0)
+    {
+	errmsg = e_positive;
+	curbuf->b_p_tw = 0;
+    }
+    if (p_tm < 0)
+    {
+	errmsg = e_positive;
+	p_tm = 0;
+    }
+    if ((curwin->w_p_scr <= 0
+		|| (curwin->w_p_scr > curwin->w_height
+		    && curwin->w_height > 0))
+	    && full_screen)
+    {
+	if (pp == &(curwin->w_p_scr))
+	{
+	    if (curwin->w_p_scr != 0)
+		errmsg = e_scroll;
+	    win_comp_scroll(curwin);
+	}
+	/* If 'scroll' became invalid because of a side effect silently adjust
+	 * it. */
+	else if (curwin->w_p_scr <= 0)
+	    curwin->w_p_scr = 1;
+	else /* curwin->w_p_scr > curwin->w_height */
+	    curwin->w_p_scr = curwin->w_height;
+    }
+    if (p_report < 0)
+    {
+	errmsg = e_positive;
+	p_report = 1;
+    }
+    if ((p_sj < -100 || p_sj >= Rows) && full_screen)
+    {
+	if (Rows != old_Rows)	/* Rows changed, just adjust p_sj */
+	    p_sj = Rows / 2;
+	else
+	{
+	    errmsg = e_scroll;
+	    p_sj = 1;
+	}
+    }
+    if (p_so < 0 && full_screen)
+    {
+	errmsg = e_scroll;
+	p_so = 0;
+    }
+    if (p_siso < 0 && full_screen)
+    {
+	errmsg = e_positive;
+	p_siso = 0;
+    }
+#ifdef FEAT_CMDWIN
+    if (p_cwh < 1)
+    {
+	errmsg = e_positive;
+	p_cwh = 1;
+    }
+#endif
+    if (p_ut < 0)
+    {
+	errmsg = e_positive;
+	p_ut = 2000;
+    }
+    if (p_ss < 0)
+    {
+	errmsg = e_positive;
+	p_ss = 0;
+    }
+
+    /* May set global value for local option. */
+    if ((opt_flags & (OPT_LOCAL | OPT_GLOBAL)) == 0)
+	*(long *)get_varp_scope(&(options[opt_idx]), OPT_GLOBAL) = *pp;
+
+    options[opt_idx].flags |= P_WAS_SET;
+
+    comp_col();			    /* in case 'columns' or 'ls' changed */
+    if (curwin->w_curswant != MAXCOL)
+	curwin->w_set_curswant = TRUE;  /* in case 'tabstop' changed */
+    check_redraw(options[opt_idx].flags);
+
+    return errmsg;
+}
+
+/*
+ * Called after an option changed: check if something needs to be redrawn.
+ */
+    static void
+check_redraw(flags)
+    long_u	flags;
+{
+    /* Careful: P_RCLR and P_RALL are a combination of other P_ flags */
+    int		clear = (flags & P_RCLR) == P_RCLR;
+    int		all = ((flags & P_RALL) == P_RALL || clear);
+
+#ifdef FEAT_WINDOWS
+    if ((flags & P_RSTAT) || all)	/* mark all status lines dirty */
+	status_redraw_all();
+#endif
+
+    if ((flags & P_RBUF) || (flags & P_RWIN) || all)
+	changed_window_setting();
+    if (flags & P_RBUF)
+	redraw_curbuf_later(NOT_VALID);
+    if (clear)
+	redraw_all_later(CLEAR);
+    else if (all)
+	redraw_all_later(NOT_VALID);
+}
+
+/*
+ * Find index for option 'arg'.
+ * Return -1 if not found.
+ */
+    static int
+findoption(arg)
+    char_u *arg;
+{
+    int		    opt_idx;
+    char	    *s, *p;
+    static short    quick_tab[27] = {0, 0};	/* quick access table */
+    int		    is_term_opt;
+
+    /*
+     * For first call: Initialize the quick-access table.
+     * It contains the index for the first option that starts with a certain
+     * letter.  There are 26 letters, plus the first "t_" option.
+     */
+    if (quick_tab[1] == 0)
+    {
+	p = options[0].fullname;
+	for (opt_idx = 1; (s = options[opt_idx].fullname) != NULL; opt_idx++)
+	{
+	    if (s[0] != p[0])
+	    {
+		if (s[0] == 't' && s[1] == '_')
+		    quick_tab[26] = opt_idx;
+		else
+		    quick_tab[CharOrdLow(s[0])] = opt_idx;
+	    }
+	    p = s;
+	}
+    }
+
+    /*
+     * Check for name starting with an illegal character.
+     */
+#ifdef EBCDIC
+    if (!islower(arg[0]))
+#else
+    if (arg[0] < 'a' || arg[0] > 'z')
+#endif
+	return -1;
+
+    is_term_opt = (arg[0] == 't' && arg[1] == '_');
+    if (is_term_opt)
+	opt_idx = quick_tab[26];
+    else
+	opt_idx = quick_tab[CharOrdLow(arg[0])];
+    for ( ; (s = options[opt_idx].fullname) != NULL; opt_idx++)
+    {
+	if (STRCMP(arg, s) == 0)		    /* match full name */
+	    break;
+    }
+    if (s == NULL && !is_term_opt)
+    {
+	opt_idx = quick_tab[CharOrdLow(arg[0])];
+	for ( ; options[opt_idx].fullname != NULL; opt_idx++)
+	{
+	    s = options[opt_idx].shortname;
+	    if (s != NULL && STRCMP(arg, s) == 0)   /* match short name */
+		break;
+	    s = NULL;
+	}
+    }
+    if (s == NULL)
+	opt_idx = -1;
+    return opt_idx;
+}
+
+#if defined(FEAT_EVAL) || defined(FEAT_TCL) || defined(FEAT_MZSCHEME)
+/*
+ * Get the value for an option.
+ *
+ * Returns:
+ * Number or Toggle option: 1, *numval gets value.
+ *	     String option: 0, *stringval gets allocated string.
+ * Hidden Number or Toggle option: -1.
+ *	     hidden String option: -2.
+ *		   unknown option: -3.
+ */
+    int
+get_option_value(name, numval, stringval, opt_flags)
+    char_u	*name;
+    long	*numval;
+    char_u	**stringval;	    /* NULL when only checking existance */
+    int		opt_flags;
+{
+    int		opt_idx;
+    char_u	*varp;
+
+    opt_idx = findoption(name);
+    if (opt_idx < 0)		    /* unknown option */
+	return -3;
+
+    varp = get_varp_scope(&(options[opt_idx]), opt_flags);
+
+    if (options[opt_idx].flags & P_STRING)
+    {
+	if (varp == NULL)		    /* hidden option */
+	    return -2;
+	if (stringval != NULL)
+	{
+#ifdef FEAT_CRYPT
+	    /* never return the value of the crypt key */
+	    if ((char_u **)varp == &curbuf->b_p_key)
+		*stringval = vim_strsave((char_u *)"*****");
+	    else
+#endif
+		*stringval = vim_strsave(*(char_u **)(varp));
+	}
+	return 0;
+    }
+
+    if (varp == NULL)		    /* hidden option */
+	return -1;
+    if (options[opt_idx].flags & P_NUM)
+	*numval = *(long *)varp;
+    else
+    {
+	/* Special case: 'modified' is b_changed, but we also want to consider
+	 * it set when 'ff' or 'fenc' changed. */
+	if ((int *)varp == &curbuf->b_changed)
+	    *numval = curbufIsChanged();
+	else
+	    *numval = *(int *)varp;
+    }
+    return 1;
+}
+#endif
+
+/*
+ * Set the value of option "name".
+ * Use "string" for string options, use "number" for other options.
+ */
+    void
+set_option_value(name, number, string, opt_flags)
+    char_u	*name;
+    long	number;
+    char_u	*string;
+    int		opt_flags;	/* OPT_LOCAL or 0 (both) */
+{
+    int		opt_idx;
+    char_u	*varp;
+    long_u	flags;
+
+    opt_idx = findoption(name);
+    if (opt_idx < 0)
+	EMSG2(_("E355: Unknown option: %s"), name);
+    else
+    {
+	flags = options[opt_idx].flags;
+#ifdef HAVE_SANDBOX
+	/* Disallow changing some options in the sandbox */
+	if (sandbox > 0 && (flags & P_SECURE))
+	{
+	    EMSG(_(e_sandbox));
+	    return;
+	}
+#endif
+	if (flags & P_STRING)
+	    set_string_option(opt_idx, string, opt_flags);
+	else
+	{
+	    varp = get_varp(&options[opt_idx]);
+	    if (varp != NULL)	/* hidden option is not changed */
+	    {
+		if (flags & P_NUM)
+		    (void)set_num_option(opt_idx, varp, number,
+							  NULL, 0, opt_flags);
+		else
+		    (void)set_bool_option(opt_idx, varp, (int)number,
+								   opt_flags);
+	    }
+	}
+    }
+}
+
+/*
+ * Get the terminal code for a terminal option.
+ * Returns NULL when not found.
+ */
+    char_u *
+get_term_code(tname)
+    char_u	*tname;
+{
+    int	    opt_idx;
+    char_u  *varp;
+
+    if (tname[0] != 't' || tname[1] != '_' ||
+	    tname[2] == NUL || tname[3] == NUL)
+	return NULL;
+    if ((opt_idx = findoption(tname)) >= 0)
+    {
+	varp = get_varp(&(options[opt_idx]));
+	if (varp != NULL)
+	    varp = *(char_u **)(varp);
+	return varp;
+    }
+    return find_termcode(tname + 2);
+}
+
+    char_u *
+get_highlight_default()
+{
+    int i;
+
+    i = findoption((char_u *)"hl");
+    if (i >= 0)
+	return options[i].def_val[VI_DEFAULT];
+    return (char_u *)NULL;
+}
+
+#if defined(FEAT_MBYTE) || defined(PROTO)
+    char_u *
+get_encoding_default()
+{
+    int i;
+
+    i = findoption((char_u *)"enc");
+    if (i >= 0)
+	return options[i].def_val[VI_DEFAULT];
+    return (char_u *)NULL;
+}
+#endif
+
+/*
+ * Translate a string like "t_xx", "<t_xx>" or "<S-Tab>" to a key number.
+ */
+    static int
+find_key_option(arg)
+    char_u *arg;
+{
+    int		key;
+    int		modifiers;
+
+    /*
+     * Don't use get_special_key_code() for t_xx, we don't want it to call
+     * add_termcap_entry().
+     */
+    if (arg[0] == 't' && arg[1] == '_' && arg[2] && arg[3])
+	key = TERMCAP2KEY(arg[2], arg[3]);
+    else
+    {
+	--arg;			    /* put arg at the '<' */
+	modifiers = 0;
+	key = find_special_key(&arg, &modifiers, TRUE);
+	if (modifiers)		    /* can't handle modifiers here */
+	    key = 0;
+    }
+    return key;
+}
+
+/*
+ * if 'all' == 0: show changed options
+ * if 'all' == 1: show all normal options
+ * if 'all' == 2: show all terminal options
+ */
+    static void
+showoptions(all, opt_flags)
+    int		all;
+    int		opt_flags;	/* OPT_LOCAL and/or OPT_GLOBAL */
+{
+    struct vimoption	*p;
+    int			col;
+    int			isterm;
+    char_u		*varp;
+    struct vimoption	**items;
+    int			item_count;
+    int			run;
+    int			row, rows;
+    int			cols;
+    int			i;
+    int			len;
+
+#define INC 20
+#define GAP 3
+
+    items = (struct vimoption **)alloc((unsigned)(sizeof(struct vimoption *) *
+								PARAM_COUNT));
+    if (items == NULL)
+	return;
+
+    /* Highlight title */
+    if (all == 2)
+	MSG_PUTS_TITLE(_("\n--- Terminal codes ---"));
+    else if (opt_flags & OPT_GLOBAL)
+	MSG_PUTS_TITLE(_("\n--- Global option values ---"));
+    else if (opt_flags & OPT_LOCAL)
+	MSG_PUTS_TITLE(_("\n--- Local option values ---"));
+    else
+	MSG_PUTS_TITLE(_("\n--- Options ---"));
+
+    /*
+     * do the loop two times:
+     * 1. display the short items
+     * 2. display the long items (only strings and numbers)
+     */
+    for (run = 1; run <= 2 && !got_int; ++run)
+    {
+	/*
+	 * collect the items in items[]
+	 */
+	item_count = 0;
+	for (p = &options[0]; p->fullname != NULL; p++)
+	{
+	    varp = NULL;
+	    isterm = istermoption(p);
+	    if (opt_flags != 0)
+	    {
+		if (p->indir != PV_NONE && !isterm)
+		    varp = get_varp_scope(p, opt_flags);
+	    }
+	    else
+		varp = get_varp(p);
+	    if (varp != NULL
+		    && ((all == 2 && isterm)
+			|| (all == 1 && !isterm)
+			|| (all == 0 && !optval_default(p, varp))))
+	    {
+		if (p->flags & P_BOOL)
+		    len = 1;		/* a toggle option fits always */
+		else
+		{
+		    option_value2string(p, opt_flags);
+		    len = (int)STRLEN(p->fullname) + vim_strsize(NameBuff) + 1;
+		}
+		if ((len <= INC - GAP && run == 1) ||
+						(len > INC - GAP && run == 2))
+		    items[item_count++] = p;
+	    }
+	}
+
+	/*
+	 * display the items
+	 */
+	if (run == 1)
+	{
+	    cols = (Columns + GAP - 3) / INC;
+	    if (cols == 0)
+		cols = 1;
+	    rows = (item_count + cols - 1) / cols;
+	}
+	else	/* run == 2 */
+	    rows = item_count;
+	for (row = 0; row < rows && !got_int; ++row)
+	{
+	    msg_putchar('\n');			/* go to next line */
+	    if (got_int)			/* 'q' typed in more */
+		break;
+	    col = 0;
+	    for (i = row; i < item_count; i += rows)
+	    {
+		msg_col = col;			/* make columns */
+		showoneopt(items[i], opt_flags);
+		col += INC;
+	    }
+	    out_flush();
+	    ui_breakcheck();
+	}
+    }
+    vim_free(items);
+}
+
+/*
+ * Return TRUE if option "p" has its default value.
+ */
+    static int
+optval_default(p, varp)
+    struct vimoption	*p;
+    char_u		*varp;
+{
+    int		dvi;
+
+    if (varp == NULL)
+	return TRUE;	    /* hidden option is always at default */
+    dvi = ((p->flags & P_VI_DEF) || p_cp) ? VI_DEFAULT : VIM_DEFAULT;
+    if (p->flags & P_NUM)
+	return (*(long *)varp == (long)(long_i)p->def_val[dvi]);
+    if (p->flags & P_BOOL)
+			/* the cast to long is required for Manx C, long_i is
+			 * needed for MSVC */
+	return (*(int *)varp == (int)(long)(long_i)p->def_val[dvi]);
+    /* P_STRING */
+    return (STRCMP(*(char_u **)varp, p->def_val[dvi]) == 0);
+}
+
+/*
+ * showoneopt: show the value of one option
+ * must not be called with a hidden option!
+ */
+    static void
+showoneopt(p, opt_flags)
+    struct vimoption	*p;
+    int			opt_flags;	/* OPT_LOCAL or OPT_GLOBAL */
+{
+    char_u	*varp;
+    int		save_silent = silent_mode;
+
+    silent_mode = FALSE;
+    info_message = TRUE;	/* use mch_msg(), not mch_errmsg() */
+
+    varp = get_varp_scope(p, opt_flags);
+
+    /* for 'modified' we also need to check if 'ff' or 'fenc' changed. */
+    if ((p->flags & P_BOOL) && ((int *)varp == &curbuf->b_changed
+					? !curbufIsChanged() : !*(int *)varp))
+	MSG_PUTS("no");
+    else if ((p->flags & P_BOOL) && *(int *)varp < 0)
+	MSG_PUTS("--");
+    else
+	MSG_PUTS("  ");
+    MSG_PUTS(p->fullname);
+    if (!(p->flags & P_BOOL))
+    {
+	msg_putchar('=');
+	/* put value string in NameBuff */
+	option_value2string(p, opt_flags);
+	msg_outtrans(NameBuff);
+    }
+
+    silent_mode = save_silent;
+    info_message = FALSE;
+}
+
+/*
+ * Write modified options as ":set" commands to a file.
+ *
+ * There are three values for "opt_flags":
+ * OPT_GLOBAL:		   Write global option values and fresh values of
+ *			   buffer-local options (used for start of a session
+ *			   file).
+ * OPT_GLOBAL + OPT_LOCAL: Idem, add fresh values of window-local options for
+ *			   curwin (used for a vimrc file).
+ * OPT_LOCAL:		   Write buffer-local option values for curbuf, fresh
+ *			   and local values for window-local options of
+ *			   curwin.  Local values are also written when at the
+ *			   default value, because a modeline or autocommand
+ *			   may have set them when doing ":edit file" and the
+ *			   user has set them back at the default or fresh
+ *			   value.
+ *			   When "local_only" is TRUE, don't write fresh
+ *			   values, only local values (for ":mkview").
+ * (fresh value = value used for a new buffer or window for a local option).
+ *
+ * Return FAIL on error, OK otherwise.
+ */
+    int
+makeset(fd, opt_flags, local_only)
+    FILE	*fd;
+    int		opt_flags;
+    int		local_only;
+{
+    struct vimoption	*p;
+    char_u		*varp;			/* currently used value */
+    char_u		*varp_fresh;		/* local value */
+    char_u		*varp_local = NULL;	/* fresh value */
+    char		*cmd;
+    int			round;
+
+    /*
+     * The options that don't have a default (terminal name, columns, lines)
+     * are never written.  Terminal options are also not written.
+     */
+    for (p = &options[0]; !istermoption(p); p++)
+	if (!(p->flags & P_NO_MKRC) && !istermoption(p))
+	{
+	    /* skip global option when only doing locals */
+	    if (p->indir == PV_NONE && !(opt_flags & OPT_GLOBAL))
+		continue;
+
+	    /* Do not store options like 'bufhidden' and 'syntax' in a vimrc
+	     * file, they are always buffer-specific. */
+	    if ((opt_flags & OPT_GLOBAL) && (p->flags & P_NOGLOB))
+		continue;
+
+	    /* Global values are only written when not at the default value. */
+	    varp = get_varp_scope(p, opt_flags);
+	    if ((opt_flags & OPT_GLOBAL) && optval_default(p, varp))
+		continue;
+
+	    round = 2;
+	    if (p->indir != PV_NONE)
+	    {
+		if (p->var == VAR_WIN)
+		{
+		    /* skip window-local option when only doing globals */
+		    if (!(opt_flags & OPT_LOCAL))
+			continue;
+		    /* When fresh value of window-local option is not at the
+		     * default, need to write it too. */
+		    if (!(opt_flags & OPT_GLOBAL) && !local_only)
+		    {
+			varp_fresh = get_varp_scope(p, OPT_GLOBAL);
+			if (!optval_default(p, varp_fresh))
+			{
+			    round = 1;
+			    varp_local = varp;
+			    varp = varp_fresh;
+			}
+		    }
+		}
+	    }
+
+	    /* Round 1: fresh value for window-local options.
+	     * Round 2: other values */
+	    for ( ; round <= 2; varp = varp_local, ++round)
+	    {
+		if (round == 1 || (opt_flags & OPT_GLOBAL))
+		    cmd = "set";
+		else
+		    cmd = "setlocal";
+
+		if (p->flags & P_BOOL)
+		{
+		    if (put_setbool(fd, cmd, p->fullname, *(int *)varp) == FAIL)
+			return FAIL;
+		}
+		else if (p->flags & P_NUM)
+		{
+		    if (put_setnum(fd, cmd, p->fullname, (long *)varp) == FAIL)
+			return FAIL;
+		}
+		else    /* P_STRING */
+		{
+#if defined(FEAT_SYN_HL) || defined(FEAT_AUTOCMD)
+		    int		do_endif = FALSE;
+
+		    /* Don't set 'syntax' and 'filetype' again if the value is
+		     * already right, avoids reloading the syntax file. */
+		    if (
+# if defined(FEAT_SYN_HL)
+			    p->indir == PV_SYN
+#  if defined(FEAT_AUTOCMD)
+			    ||
+#  endif
+# endif
+# if defined(FEAT_AUTOCMD)
+			    p->indir == PV_FT)
+# endif
+		    {
+			if (fprintf(fd, "if &%s != '%s'", p->fullname,
+						       *(char_u **)(varp)) < 0
+				|| put_eol(fd) < 0)
+			    return FAIL;
+			do_endif = TRUE;
+		    }
+#endif
+		    if (put_setstring(fd, cmd, p->fullname, (char_u **)varp,
+					  (p->flags & P_EXPAND) != 0) == FAIL)
+			return FAIL;
+#if defined(FEAT_SYN_HL) || defined(FEAT_AUTOCMD)
+		    if (do_endif)
+		    {
+			if (put_line(fd, "endif") == FAIL)
+			    return FAIL;
+		    }
+#endif
+		}
+	    }
+	}
+    return OK;
+}
+
+#if defined(FEAT_FOLDING) || defined(PROTO)
+/*
+ * Generate set commands for the local fold options only.  Used when
+ * 'sessionoptions' or 'viewoptions' contains "folds" but not "options".
+ */
+    int
+makefoldset(fd)
+    FILE	*fd;
+{
+    if (put_setstring(fd, "setlocal", "fdm", &curwin->w_p_fdm, FALSE) == FAIL
+# ifdef FEAT_EVAL
+	    || put_setstring(fd, "setlocal", "fde", &curwin->w_p_fde, FALSE)
+								       == FAIL
+# endif
+	    || put_setstring(fd, "setlocal", "fmr", &curwin->w_p_fmr, FALSE)
+								       == FAIL
+	    || put_setstring(fd, "setlocal", "fdi", &curwin->w_p_fdi, FALSE)
+								       == FAIL
+	    || put_setnum(fd, "setlocal", "fdl", &curwin->w_p_fdl) == FAIL
+	    || put_setnum(fd, "setlocal", "fml", &curwin->w_p_fml) == FAIL
+	    || put_setnum(fd, "setlocal", "fdn", &curwin->w_p_fdn) == FAIL
+	    || put_setbool(fd, "setlocal", "fen", curwin->w_p_fen) == FAIL
+	    )
+	return FAIL;
+
+    return OK;
+}
+#endif
+
+    static int
+put_setstring(fd, cmd, name, valuep, expand)
+    FILE	*fd;
+    char	*cmd;
+    char	*name;
+    char_u	**valuep;
+    int		expand;
+{
+    char_u	*s;
+    char_u	buf[MAXPATHL];
+
+    if (fprintf(fd, "%s %s=", cmd, name) < 0)
+	return FAIL;
+    if (*valuep != NULL)
+    {
+	/* Output 'pastetoggle' as key names.  For other
+	 * options some characters have to be escaped with
+	 * CTRL-V or backslash */
+	if (valuep == &p_pt)
+	{
+	    s = *valuep;
+	    while (*s != NUL)
+		if (fputs((char *)str2special(&s, FALSE), fd) < 0)
+		    return FAIL;
+	}
+	else if (expand)
+	{
+	    home_replace(NULL, *valuep, buf, MAXPATHL, FALSE);
+	    if (put_escstr(fd, buf, 2) == FAIL)
+		return FAIL;
+	}
+	else if (put_escstr(fd, *valuep, 2) == FAIL)
+	    return FAIL;
+    }
+    if (put_eol(fd) < 0)
+	return FAIL;
+    return OK;
+}
+
+    static int
+put_setnum(fd, cmd, name, valuep)
+    FILE	*fd;
+    char	*cmd;
+    char	*name;
+    long	*valuep;
+{
+    long	wc;
+
+    if (fprintf(fd, "%s %s=", cmd, name) < 0)
+	return FAIL;
+    if (wc_use_keyname((char_u *)valuep, &wc))
+    {
+	/* print 'wildchar' and 'wildcharm' as a key name */
+	if (fputs((char *)get_special_key_name((int)wc, 0), fd) < 0)
+	    return FAIL;
+    }
+    else if (fprintf(fd, "%ld", *valuep) < 0)
+	return FAIL;
+    if (put_eol(fd) < 0)
+	return FAIL;
+    return OK;
+}
+
+    static int
+put_setbool(fd, cmd, name, value)
+    FILE	*fd;
+    char	*cmd;
+    char	*name;
+    int		value;
+{
+    if (fprintf(fd, "%s %s%s", cmd, value ? "" : "no", name) < 0
+	    || put_eol(fd) < 0)
+	return FAIL;
+    return OK;
+}
+
+/*
+ * Clear all the terminal options.
+ * If the option has been allocated, free the memory.
+ * Terminal options are never hidden or indirect.
+ */
+    void
+clear_termoptions()
+{
+    /*
+     * Reset a few things before clearing the old options. This may cause
+     * outputting a few things that the terminal doesn't understand, but the
+     * screen will be cleared later, so this is OK.
+     */
+#ifdef FEAT_MOUSE_TTY
+    mch_setmouse(FALSE);	    /* switch mouse off */
+#endif
+#ifdef FEAT_TITLE
+    mch_restore_title(3);	    /* restore window titles */
+#endif
+#if defined(FEAT_XCLIPBOARD) && defined(FEAT_GUI)
+    /* When starting the GUI close the display opened for the clipboard.
+     * After restoring the title, because that will need the display. */
+    if (gui.starting)
+	clear_xterm_clip();
+#endif
+#ifdef WIN3264
+    /*
+     * Check if this is allowed now.
+     */
+    if (can_end_termcap_mode(FALSE) == TRUE)
+#endif
+	stoptermcap();			/* stop termcap mode */
+
+    free_termoptions();
+}
+
+    void
+free_termoptions()
+{
+    struct vimoption   *p;
+
+    for (p = &options[0]; p->fullname != NULL; p++)
+	if (istermoption(p))
+	{
+	    if (p->flags & P_ALLOCED)
+		free_string_option(*(char_u **)(p->var));
+	    if (p->flags & P_DEF_ALLOCED)
+		free_string_option(p->def_val[VI_DEFAULT]);
+	    *(char_u **)(p->var) = empty_option;
+	    p->def_val[VI_DEFAULT] = empty_option;
+	    p->flags &= ~(P_ALLOCED|P_DEF_ALLOCED);
+	}
+    clear_termcodes();
+}
+
+/*
+ * Set the terminal option defaults to the current value.
+ * Used after setting the terminal name.
+ */
+    void
+set_term_defaults()
+{
+    struct vimoption   *p;
+
+    for (p = &options[0]; p->fullname != NULL; p++)
+    {
+	if (istermoption(p) && p->def_val[VI_DEFAULT] != *(char_u **)(p->var))
+	{
+	    if (p->flags & P_DEF_ALLOCED)
+	    {
+		free_string_option(p->def_val[VI_DEFAULT]);
+		p->flags &= ~P_DEF_ALLOCED;
+	    }
+	    p->def_val[VI_DEFAULT] = *(char_u **)(p->var);
+	    if (p->flags & P_ALLOCED)
+	    {
+		p->flags |= P_DEF_ALLOCED;
+		p->flags &= ~P_ALLOCED;	 /* don't free the value now */
+	    }
+	}
+    }
+}
+
+/*
+ * return TRUE if 'p' starts with 't_'
+ */
+    static int
+istermoption(p)
+    struct vimoption *p;
+{
+    return (p->fullname[0] == 't' && p->fullname[1] == '_');
+}
+
+/*
+ * Compute columns for ruler and shown command. 'sc_col' is also used to
+ * decide what the maximum length of a message on the status line can be.
+ * If there is a status line for the last window, 'sc_col' is independent
+ * of 'ru_col'.
+ */
+
+#define COL_RULER 17	    /* columns needed by standard ruler */
+
+    void
+comp_col()
+{
+#if defined(FEAT_CMDL_INFO) && defined(FEAT_WINDOWS)
+    int last_has_status = (p_ls == 2 || (p_ls == 1 && firstwin != lastwin));
+
+    sc_col = 0;
+    ru_col = 0;
+    if (p_ru)
+    {
+#ifdef FEAT_STL_OPT
+	ru_col = (ru_wid ? ru_wid : COL_RULER) + 1;
+#else
+	ru_col = COL_RULER + 1;
+#endif
+	/* no last status line, adjust sc_col */
+	if (!last_has_status)
+	    sc_col = ru_col;
+    }
+    if (p_sc)
+    {
+	sc_col += SHOWCMD_COLS;
+	if (!p_ru || last_has_status)	    /* no need for separating space */
+	    ++sc_col;
+    }
+    sc_col = Columns - sc_col;
+    ru_col = Columns - ru_col;
+    if (sc_col <= 0)		/* screen too narrow, will become a mess */
+	sc_col = 1;
+    if (ru_col <= 0)
+	ru_col = 1;
+#else
+    sc_col = Columns;
+    ru_col = Columns;
+#endif
+}
+
+/*
+ * Get pointer to option variable, depending on local or global scope.
+ */
+    static char_u *
+get_varp_scope(p, opt_flags)
+    struct vimoption	*p;
+    int			opt_flags;
+{
+    if ((opt_flags & OPT_GLOBAL) && p->indir != PV_NONE)
+    {
+	if (p->var == VAR_WIN)
+	    return (char_u *)GLOBAL_WO(get_varp(p));
+	return p->var;
+    }
+    if ((opt_flags & OPT_LOCAL) && ((int)p->indir & PV_BOTH))
+    {
+	switch ((int)p->indir)
+	{
+#ifdef FEAT_QUICKFIX
+	    case PV_EFM:  return (char_u *)&(curbuf->b_p_efm);
+	    case PV_GP:   return (char_u *)&(curbuf->b_p_gp);
+	    case PV_MP:   return (char_u *)&(curbuf->b_p_mp);
+#endif
+	    case PV_EP:   return (char_u *)&(curbuf->b_p_ep);
+	    case PV_KP:   return (char_u *)&(curbuf->b_p_kp);
+	    case PV_PATH: return (char_u *)&(curbuf->b_p_path);
+	    case PV_AR:   return (char_u *)&(curbuf->b_p_ar);
+	    case PV_TAGS: return (char_u *)&(curbuf->b_p_tags);
+#ifdef FEAT_FIND_ID
+	    case PV_DEF:  return (char_u *)&(curbuf->b_p_def);
+	    case PV_INC:  return (char_u *)&(curbuf->b_p_inc);
+#endif
+#ifdef FEAT_INS_EXPAND
+	    case PV_DICT: return (char_u *)&(curbuf->b_p_dict);
+	    case PV_TSR:  return (char_u *)&(curbuf->b_p_tsr);
+#endif
+#if defined(FEAT_BEVAL) && defined(FEAT_EVAL)
+	    case PV_BEXPR: return (char_u *)&(curbuf->b_p_bexpr);
+#endif
+#ifdef FEAT_STL_OPT
+	    case PV_STL:  return (char_u *)&(curwin->w_p_stl);
+#endif
+	}
+	return NULL; /* "cannot happen" */
+    }
+    return get_varp(p);
+}
+
+/*
+ * Get pointer to option variable.
+ */
+    static char_u *
+get_varp(p)
+    struct vimoption	*p;
+{
+    /* hidden option, always return NULL */
+    if (p->var == NULL)
+	return NULL;
+
+    switch ((int)p->indir)
+    {
+	case PV_NONE:	return p->var;
+
+	/* global option with local value: use local value if it's been set */
+	case PV_EP:	return *curbuf->b_p_ep != NUL
+				    ? (char_u *)&curbuf->b_p_ep : p->var;
+	case PV_KP:	return *curbuf->b_p_kp != NUL
+				    ? (char_u *)&curbuf->b_p_kp : p->var;
+	case PV_PATH:	return *curbuf->b_p_path != NUL
+				    ? (char_u *)&(curbuf->b_p_path) : p->var;
+	case PV_AR:	return curbuf->b_p_ar >= 0
+				    ? (char_u *)&(curbuf->b_p_ar) : p->var;
+	case PV_TAGS:	return *curbuf->b_p_tags != NUL
+				    ? (char_u *)&(curbuf->b_p_tags) : p->var;
+#ifdef FEAT_FIND_ID
+	case PV_DEF:	return *curbuf->b_p_def != NUL
+				    ? (char_u *)&(curbuf->b_p_def) : p->var;
+	case PV_INC:	return *curbuf->b_p_inc != NUL
+				    ? (char_u *)&(curbuf->b_p_inc) : p->var;
+#endif
+#ifdef FEAT_INS_EXPAND
+	case PV_DICT:	return *curbuf->b_p_dict != NUL
+				    ? (char_u *)&(curbuf->b_p_dict) : p->var;
+	case PV_TSR:	return *curbuf->b_p_tsr != NUL
+				    ? (char_u *)&(curbuf->b_p_tsr) : p->var;
+#endif
+#ifdef FEAT_QUICKFIX
+	case PV_EFM:	return *curbuf->b_p_efm != NUL
+				    ? (char_u *)&(curbuf->b_p_efm) : p->var;
+	case PV_GP:	return *curbuf->b_p_gp != NUL
+				    ? (char_u *)&(curbuf->b_p_gp) : p->var;
+	case PV_MP:	return *curbuf->b_p_mp != NUL
+				    ? (char_u *)&(curbuf->b_p_mp) : p->var;
+#endif
+#if defined(FEAT_BEVAL) && defined(FEAT_EVAL)
+	case PV_BEXPR:	return *curbuf->b_p_bexpr != NUL
+				    ? (char_u *)&(curbuf->b_p_bexpr) : p->var;
+#endif
+#ifdef FEAT_STL_OPT
+	case PV_STL:	return *curwin->w_p_stl != NUL
+				    ? (char_u *)&(curwin->w_p_stl) : p->var;
+#endif
+
+#ifdef FEAT_ARABIC
+	case PV_ARAB:	return (char_u *)&(curwin->w_p_arab);
+#endif
+	case PV_LIST:	return (char_u *)&(curwin->w_p_list);
+#ifdef FEAT_SPELL
+	case PV_SPELL:	return (char_u *)&(curwin->w_p_spell);
+#endif
+#ifdef FEAT_SYN_HL
+	case PV_CUC:	return (char_u *)&(curwin->w_p_cuc);
+	case PV_CUL:	return (char_u *)&(curwin->w_p_cul);
+#endif
+#ifdef FEAT_DIFF
+	case PV_DIFF:	return (char_u *)&(curwin->w_p_diff);
+#endif
+#ifdef FEAT_FOLDING
+	case PV_FDC:	return (char_u *)&(curwin->w_p_fdc);
+	case PV_FEN:	return (char_u *)&(curwin->w_p_fen);
+	case PV_FDI:	return (char_u *)&(curwin->w_p_fdi);
+	case PV_FDL:	return (char_u *)&(curwin->w_p_fdl);
+	case PV_FDM:	return (char_u *)&(curwin->w_p_fdm);
+	case PV_FML:	return (char_u *)&(curwin->w_p_fml);
+	case PV_FDN:	return (char_u *)&(curwin->w_p_fdn);
+# ifdef FEAT_EVAL
+	case PV_FDE:	return (char_u *)&(curwin->w_p_fde);
+	case PV_FDT:	return (char_u *)&(curwin->w_p_fdt);
+# endif
+	case PV_FMR:	return (char_u *)&(curwin->w_p_fmr);
+#endif
+	case PV_NU:	return (char_u *)&(curwin->w_p_nu);
+#ifdef FEAT_LINEBREAK
+	case PV_NUW:	return (char_u *)&(curwin->w_p_nuw);
+#endif
+#ifdef FEAT_WINDOWS
+	case PV_WFH:	return (char_u *)&(curwin->w_p_wfh);
+#endif
+#ifdef FEAT_VERTSPLIT
+	case PV_WFW:	return (char_u *)&(curwin->w_p_wfw);
+#endif
+#if defined(FEAT_WINDOWS) && defined(FEAT_QUICKFIX)
+	case PV_PVW:	return (char_u *)&(curwin->w_p_pvw);
+#endif
+#ifdef FEAT_RIGHTLEFT
+	case PV_RL:	return (char_u *)&(curwin->w_p_rl);
+	case PV_RLC:	return (char_u *)&(curwin->w_p_rlc);
+#endif
+	case PV_SCROLL:	return (char_u *)&(curwin->w_p_scr);
+	case PV_WRAP:	return (char_u *)&(curwin->w_p_wrap);
+#ifdef FEAT_LINEBREAK
+	case PV_LBR:	return (char_u *)&(curwin->w_p_lbr);
+#endif
+#ifdef FEAT_SCROLLBIND
+	case PV_SCBIND: return (char_u *)&(curwin->w_p_scb);
+#endif
+
+	case PV_AI:	return (char_u *)&(curbuf->b_p_ai);
+	case PV_BIN:	return (char_u *)&(curbuf->b_p_bin);
+#ifdef FEAT_MBYTE
+	case PV_BOMB:	return (char_u *)&(curbuf->b_p_bomb);
+#endif
+#if defined(FEAT_QUICKFIX)
+	case PV_BH:	return (char_u *)&(curbuf->b_p_bh);
+	case PV_BT:	return (char_u *)&(curbuf->b_p_bt);
+#endif
+	case PV_BL:	return (char_u *)&(curbuf->b_p_bl);
+	case PV_CI:	return (char_u *)&(curbuf->b_p_ci);
+#ifdef FEAT_CINDENT
+	case PV_CIN:	return (char_u *)&(curbuf->b_p_cin);
+	case PV_CINK:	return (char_u *)&(curbuf->b_p_cink);
+	case PV_CINO:	return (char_u *)&(curbuf->b_p_cino);
+#endif
+#if defined(FEAT_SMARTINDENT) || defined(FEAT_CINDENT)
+	case PV_CINW:	return (char_u *)&(curbuf->b_p_cinw);
+#endif
+#ifdef FEAT_COMMENTS
+	case PV_COM:	return (char_u *)&(curbuf->b_p_com);
+#endif
+#ifdef FEAT_FOLDING
+	case PV_CMS:	return (char_u *)&(curbuf->b_p_cms);
+#endif
+#ifdef FEAT_INS_EXPAND
+	case PV_CPT:	return (char_u *)&(curbuf->b_p_cpt);
+#endif
+#ifdef FEAT_COMPL_FUNC
+	case PV_CFU:	return (char_u *)&(curbuf->b_p_cfu);
+	case PV_OFU:	return (char_u *)&(curbuf->b_p_ofu);
+#endif
+	case PV_EOL:	return (char_u *)&(curbuf->b_p_eol);
+	case PV_ET:	return (char_u *)&(curbuf->b_p_et);
+#ifdef FEAT_MBYTE
+	case PV_FENC:	return (char_u *)&(curbuf->b_p_fenc);
+#endif
+	case PV_FF:	return (char_u *)&(curbuf->b_p_ff);
+#ifdef FEAT_AUTOCMD
+	case PV_FT:	return (char_u *)&(curbuf->b_p_ft);
+#endif
+	case PV_FO:	return (char_u *)&(curbuf->b_p_fo);
+	case PV_FLP:	return (char_u *)&(curbuf->b_p_flp);
+	case PV_IMI:	return (char_u *)&(curbuf->b_p_iminsert);
+	case PV_IMS:	return (char_u *)&(curbuf->b_p_imsearch);
+	case PV_INF:	return (char_u *)&(curbuf->b_p_inf);
+	case PV_ISK:	return (char_u *)&(curbuf->b_p_isk);
+#ifdef FEAT_FIND_ID
+# ifdef FEAT_EVAL
+	case PV_INEX:	return (char_u *)&(curbuf->b_p_inex);
+# endif
+#endif
+#if defined(FEAT_CINDENT) && defined(FEAT_EVAL)
+	case PV_INDE:	return (char_u *)&(curbuf->b_p_inde);
+	case PV_INDK:	return (char_u *)&(curbuf->b_p_indk);
+#endif
+#ifdef FEAT_EVAL
+	case PV_FEX:	return (char_u *)&(curbuf->b_p_fex);
+#endif
+#ifdef FEAT_CRYPT
+	case PV_KEY:	return (char_u *)&(curbuf->b_p_key);
+#endif
+#ifdef FEAT_LISP
+	case PV_LISP:	return (char_u *)&(curbuf->b_p_lisp);
+#endif
+	case PV_ML:	return (char_u *)&(curbuf->b_p_ml);
+	case PV_MPS:	return (char_u *)&(curbuf->b_p_mps);
+	case PV_MA:	return (char_u *)&(curbuf->b_p_ma);
+	case PV_MOD:	return (char_u *)&(curbuf->b_changed);
+	case PV_NF:	return (char_u *)&(curbuf->b_p_nf);
+#ifdef FEAT_OSFILETYPE
+	case PV_OFT:	return (char_u *)&(curbuf->b_p_oft);
+#endif
+	case PV_PI:	return (char_u *)&(curbuf->b_p_pi);
+#ifdef FEAT_TEXTOBJ
+	case PV_QE:	return (char_u *)&(curbuf->b_p_qe);
+#endif
+	case PV_RO:	return (char_u *)&(curbuf->b_p_ro);
+#ifdef FEAT_SMARTINDENT
+	case PV_SI:	return (char_u *)&(curbuf->b_p_si);
+#endif
+#ifndef SHORT_FNAME
+	case PV_SN:	return (char_u *)&(curbuf->b_p_sn);
+#endif
+	case PV_STS:	return (char_u *)&(curbuf->b_p_sts);
+#ifdef FEAT_SEARCHPATH
+	case PV_SUA:	return (char_u *)&(curbuf->b_p_sua);
+#endif
+	case PV_SWF:	return (char_u *)&(curbuf->b_p_swf);
+#ifdef FEAT_SYN_HL
+	case PV_SMC:	return (char_u *)&(curbuf->b_p_smc);
+	case PV_SYN:	return (char_u *)&(curbuf->b_p_syn);
+#endif
+#ifdef FEAT_SPELL
+	case PV_SPC:	return (char_u *)&(curbuf->b_p_spc);
+	case PV_SPF:	return (char_u *)&(curbuf->b_p_spf);
+	case PV_SPL:	return (char_u *)&(curbuf->b_p_spl);
+#endif
+	case PV_SW:	return (char_u *)&(curbuf->b_p_sw);
+	case PV_TS:	return (char_u *)&(curbuf->b_p_ts);
+	case PV_TW:	return (char_u *)&(curbuf->b_p_tw);
+	case PV_TX:	return (char_u *)&(curbuf->b_p_tx);
+	case PV_WM:	return (char_u *)&(curbuf->b_p_wm);
+#ifdef FEAT_KEYMAP
+	case PV_KMAP:	return (char_u *)&(curbuf->b_p_keymap);
+#endif
+	default:	EMSG(_("E356: get_varp ERROR"));
+    }
+    /* always return a valid pointer to avoid a crash! */
+    return (char_u *)&(curbuf->b_p_wm);
+}
+
+/*
+ * Get the value of 'equalprg', either the buffer-local one or the global one.
+ */
+    char_u *
+get_equalprg()
+{
+    if (*curbuf->b_p_ep == NUL)
+	return p_ep;
+    return curbuf->b_p_ep;
+}
+
+#if defined(FEAT_WINDOWS) || defined(PROTO)
+/*
+ * Copy options from one window to another.
+ * Used when splitting a window.
+ */
+    void
+win_copy_options(wp_from, wp_to)
+    win_T	*wp_from;
+    win_T	*wp_to;
+{
+    copy_winopt(&wp_from->w_onebuf_opt, &wp_to->w_onebuf_opt);
+    copy_winopt(&wp_from->w_allbuf_opt, &wp_to->w_allbuf_opt);
+# ifdef FEAT_RIGHTLEFT
+#  ifdef FEAT_FKMAP
+    /* Is this right? */
+    wp_to->w_farsi = wp_from->w_farsi;
+#  endif
+# endif
+}
+#endif
+
+/*
+ * Copy the options from one winopt_T to another.
+ * Doesn't free the old option values in "to", use clear_winopt() for that.
+ * The 'scroll' option is not copied, because it depends on the window height.
+ * The 'previewwindow' option is reset, there can be only one preview window.
+ */
+    void
+copy_winopt(from, to)
+    winopt_T	*from;
+    winopt_T	*to;
+{
+#ifdef FEAT_ARABIC
+    to->wo_arab = from->wo_arab;
+#endif
+    to->wo_list = from->wo_list;
+    to->wo_nu = from->wo_nu;
+#ifdef FEAT_LINEBREAK
+    to->wo_nuw = from->wo_nuw;
+#endif
+#ifdef FEAT_RIGHTLEFT
+    to->wo_rl  = from->wo_rl;
+    to->wo_rlc = vim_strsave(from->wo_rlc);
+#endif
+#ifdef FEAT_STL_OPT
+    to->wo_stl = vim_strsave(from->wo_stl);
+#endif
+    to->wo_wrap = from->wo_wrap;
+#ifdef FEAT_LINEBREAK
+    to->wo_lbr = from->wo_lbr;
+#endif
+#ifdef FEAT_SCROLLBIND
+    to->wo_scb = from->wo_scb;
+#endif
+#ifdef FEAT_SPELL
+    to->wo_spell = from->wo_spell;
+#endif
+#ifdef FEAT_SYN_HL
+    to->wo_cuc = from->wo_cuc;
+    to->wo_cul = from->wo_cul;
+#endif
+#ifdef FEAT_DIFF
+    to->wo_diff = from->wo_diff;
+#endif
+#ifdef FEAT_FOLDING
+    to->wo_fdc = from->wo_fdc;
+    to->wo_fen = from->wo_fen;
+    to->wo_fdi = vim_strsave(from->wo_fdi);
+    to->wo_fml = from->wo_fml;
+    to->wo_fdl = from->wo_fdl;
+    to->wo_fdm = vim_strsave(from->wo_fdm);
+    to->wo_fdn = from->wo_fdn;
+# ifdef FEAT_EVAL
+    to->wo_fde = vim_strsave(from->wo_fde);
+    to->wo_fdt = vim_strsave(from->wo_fdt);
+# endif
+    to->wo_fmr = vim_strsave(from->wo_fmr);
+#endif
+    check_winopt(to);		/* don't want NULL pointers */
+}
+
+/*
+ * Check string options in a window for a NULL value.
+ */
+    void
+check_win_options(win)
+    win_T	*win;
+{
+    check_winopt(&win->w_onebuf_opt);
+    check_winopt(&win->w_allbuf_opt);
+}
+
+/*
+ * Check for NULL pointers in a winopt_T and replace them with empty_option.
+ */
+/*ARGSUSED*/
+    void
+check_winopt(wop)
+    winopt_T	*wop;
+{
+#ifdef FEAT_FOLDING
+    check_string_option(&wop->wo_fdi);
+    check_string_option(&wop->wo_fdm);
+# ifdef FEAT_EVAL
+    check_string_option(&wop->wo_fde);
+    check_string_option(&wop->wo_fdt);
+# endif
+    check_string_option(&wop->wo_fmr);
+#endif
+#ifdef FEAT_RIGHTLEFT
+    check_string_option(&wop->wo_rlc);
+#endif
+#ifdef FEAT_STL_OPT
+    check_string_option(&wop->wo_stl);
+#endif
+}
+
+/*
+ * Free the allocated memory inside a winopt_T.
+ */
+/*ARGSUSED*/
+    void
+clear_winopt(wop)
+    winopt_T	*wop;
+{
+#ifdef FEAT_FOLDING
+    clear_string_option(&wop->wo_fdi);
+    clear_string_option(&wop->wo_fdm);
+# ifdef FEAT_EVAL
+    clear_string_option(&wop->wo_fde);
+    clear_string_option(&wop->wo_fdt);
+# endif
+    clear_string_option(&wop->wo_fmr);
+#endif
+#ifdef FEAT_RIGHTLEFT
+    clear_string_option(&wop->wo_rlc);
+#endif
+#ifdef FEAT_STL_OPT
+    clear_string_option(&wop->wo_stl);
+#endif
+}
+
+/*
+ * Copy global option values to local options for one buffer.
+ * Used when creating a new buffer and sometimes when entering a buffer.
+ * flags:
+ * BCO_ENTER	We will enter the buf buffer.
+ * BCO_ALWAYS	Always copy the options, but only set b_p_initialized when
+ *		appropriate.
+ * BCO_NOHELP	Don't copy the values to a help buffer.
+ */
+    void
+buf_copy_options(buf, flags)
+    buf_T	*buf;
+    int		flags;
+{
+    int		should_copy = TRUE;
+    char_u	*save_p_isk = NULL;	    /* init for GCC */
+    int		dont_do_help;
+    int		did_isk = FALSE;
+
+    /*
+     * Don't do anything of the buffer is invalid.
+     */
+    if (buf == NULL || !buf_valid(buf))
+	return;
+
+    /*
+     * Skip this when the option defaults have not been set yet.  Happens when
+     * main() allocates the first buffer.
+     */
+    if (p_cpo != NULL)
+    {
+	/*
+	 * Always copy when entering and 'cpo' contains 'S'.
+	 * Don't copy when already initialized.
+	 * Don't copy when 'cpo' contains 's' and not entering.
+	 * 'S'	BCO_ENTER  initialized	's'  should_copy
+	 * yes	  yes	       X	 X	TRUE
+	 * yes	  no	      yes	 X	FALSE
+	 * no	   X	      yes	 X	FALSE
+	 *  X	  no	      no	yes	FALSE
+	 *  X	  no	      no	no	TRUE
+	 * no	  yes	      no	 X	TRUE
+	 */
+	if ((vim_strchr(p_cpo, CPO_BUFOPTGLOB) == NULL || !(flags & BCO_ENTER))
+		&& (buf->b_p_initialized
+		    || (!(flags & BCO_ENTER)
+			&& vim_strchr(p_cpo, CPO_BUFOPT) != NULL)))
+	    should_copy = FALSE;
+
+	if (should_copy || (flags & BCO_ALWAYS))
+	{
+	    /* Don't copy the options specific to a help buffer when
+	     * BCO_NOHELP is given or the options were initialized already
+	     * (jumping back to a help file with CTRL-T or CTRL-O) */
+	    dont_do_help = ((flags & BCO_NOHELP) && buf->b_help)
+						       || buf->b_p_initialized;
+	    if (dont_do_help)		/* don't free b_p_isk */
+	    {
+		save_p_isk = buf->b_p_isk;
+		buf->b_p_isk = NULL;
+	    }
+	    /*
+	     * Always free the allocated strings.
+	     * If not already initialized, set 'readonly' and copy 'fileformat'.
+	     */
+	    if (!buf->b_p_initialized)
+	    {
+		free_buf_options(buf, TRUE);
+		buf->b_p_ro = FALSE;		/* don't copy readonly */
+		buf->b_p_tx = p_tx;
+#ifdef FEAT_MBYTE
+		buf->b_p_fenc = vim_strsave(p_fenc);
+#endif
+		buf->b_p_ff = vim_strsave(p_ff);
+#if defined(FEAT_QUICKFIX)
+		buf->b_p_bh = empty_option;
+		buf->b_p_bt = empty_option;
+#endif
+	    }
+	    else
+		free_buf_options(buf, FALSE);
+
+	    buf->b_p_ai = p_ai;
+	    buf->b_p_ai_nopaste = p_ai_nopaste;
+	    buf->b_p_sw = p_sw;
+	    buf->b_p_tw = p_tw;
+	    buf->b_p_tw_nopaste = p_tw_nopaste;
+	    buf->b_p_tw_nobin = p_tw_nobin;
+	    buf->b_p_wm = p_wm;
+	    buf->b_p_wm_nopaste = p_wm_nopaste;
+	    buf->b_p_wm_nobin = p_wm_nobin;
+	    buf->b_p_bin = p_bin;
+#ifdef FEAT_MBYTE
+	    buf->b_p_bomb = p_bomb;
+#endif
+	    buf->b_p_et = p_et;
+	    buf->b_p_et_nobin = p_et_nobin;
+	    buf->b_p_ml = p_ml;
+	    buf->b_p_ml_nobin = p_ml_nobin;
+	    buf->b_p_inf = p_inf;
+	    buf->b_p_swf = p_swf;
+#ifdef FEAT_INS_EXPAND
+	    buf->b_p_cpt = vim_strsave(p_cpt);
+#endif
+#ifdef FEAT_COMPL_FUNC
+	    buf->b_p_cfu = vim_strsave(p_cfu);
+	    buf->b_p_ofu = vim_strsave(p_ofu);
+#endif
+	    buf->b_p_sts = p_sts;
+	    buf->b_p_sts_nopaste = p_sts_nopaste;
+#ifndef SHORT_FNAME
+	    buf->b_p_sn = p_sn;
+#endif
+#ifdef FEAT_COMMENTS
+	    buf->b_p_com = vim_strsave(p_com);
+#endif
+#ifdef FEAT_FOLDING
+	    buf->b_p_cms = vim_strsave(p_cms);
+#endif
+	    buf->b_p_fo = vim_strsave(p_fo);
+	    buf->b_p_flp = vim_strsave(p_flp);
+	    buf->b_p_nf = vim_strsave(p_nf);
+	    buf->b_p_mps = vim_strsave(p_mps);
+#ifdef FEAT_SMARTINDENT
+	    buf->b_p_si = p_si;
+#endif
+	    buf->b_p_ci = p_ci;
+#ifdef FEAT_CINDENT
+	    buf->b_p_cin = p_cin;
+	    buf->b_p_cink = vim_strsave(p_cink);
+	    buf->b_p_cino = vim_strsave(p_cino);
+#endif
+#ifdef FEAT_AUTOCMD
+	    /* Don't copy 'filetype', it must be detected */
+	    buf->b_p_ft = empty_option;
+#endif
+#ifdef FEAT_OSFILETYPE
+	    buf->b_p_oft = vim_strsave(p_oft);
+#endif
+	    buf->b_p_pi = p_pi;
+#if defined(FEAT_SMARTINDENT) || defined(FEAT_CINDENT)
+	    buf->b_p_cinw = vim_strsave(p_cinw);
+#endif
+#ifdef FEAT_LISP
+	    buf->b_p_lisp = p_lisp;
+#endif
+#ifdef FEAT_SYN_HL
+	    /* Don't copy 'syntax', it must be set */
+	    buf->b_p_syn = empty_option;
+	    buf->b_p_smc = p_smc;
+#endif
+#ifdef FEAT_SPELL
+	    buf->b_p_spc = vim_strsave(p_spc);
+	    (void)compile_cap_prog(buf);
+	    buf->b_p_spf = vim_strsave(p_spf);
+	    buf->b_p_spl = vim_strsave(p_spl);
+#endif
+#if defined(FEAT_CINDENT) && defined(FEAT_EVAL)
+	    buf->b_p_inde = vim_strsave(p_inde);
+	    buf->b_p_indk = vim_strsave(p_indk);
+#endif
+#if defined(FEAT_EVAL)
+	    buf->b_p_fex = vim_strsave(p_fex);
+#endif
+#ifdef FEAT_CRYPT
+	    buf->b_p_key = vim_strsave(p_key);
+#endif
+#ifdef FEAT_SEARCHPATH
+	    buf->b_p_sua = vim_strsave(p_sua);
+#endif
+#ifdef FEAT_KEYMAP
+	    buf->b_p_keymap = vim_strsave(p_keymap);
+	    buf->b_kmap_state |= KEYMAP_INIT;
+#endif
+	    /* This isn't really an option, but copying the langmap and IME
+	     * state from the current buffer is better than resetting it. */
+	    buf->b_p_iminsert = p_iminsert;
+	    buf->b_p_imsearch = p_imsearch;
+
+	    /* options that are normally global but also have a local value
+	     * are not copied, start using the global value */
+	    buf->b_p_ar = -1;
+#ifdef FEAT_QUICKFIX
+	    buf->b_p_gp = empty_option;
+	    buf->b_p_mp = empty_option;
+	    buf->b_p_efm = empty_option;
+#endif
+	    buf->b_p_ep = empty_option;
+	    buf->b_p_kp = empty_option;
+	    buf->b_p_path = empty_option;
+	    buf->b_p_tags = empty_option;
+#ifdef FEAT_FIND_ID
+	    buf->b_p_def = empty_option;
+	    buf->b_p_inc = empty_option;
+# ifdef FEAT_EVAL
+	    buf->b_p_inex = vim_strsave(p_inex);
+# endif
+#endif
+#ifdef FEAT_INS_EXPAND
+	    buf->b_p_dict = empty_option;
+	    buf->b_p_tsr = empty_option;
+#endif
+#ifdef FEAT_TEXTOBJ
+	    buf->b_p_qe = vim_strsave(p_qe);
+#endif
+#if defined(FEAT_BEVAL) && defined(FEAT_EVAL)
+	    buf->b_p_bexpr = empty_option;
+#endif
+
+	    /*
+	     * Don't copy the options set by ex_help(), use the saved values,
+	     * when going from a help buffer to a non-help buffer.
+	     * Don't touch these at all when BCO_NOHELP is used and going from
+	     * or to a help buffer.
+	     */
+	    if (dont_do_help)
+		buf->b_p_isk = save_p_isk;
+	    else
+	    {
+		buf->b_p_isk = vim_strsave(p_isk);
+		did_isk = TRUE;
+		buf->b_p_ts = p_ts;
+		buf->b_help = FALSE;
+#ifdef FEAT_QUICKFIX
+		if (buf->b_p_bt[0] == 'h')
+		    clear_string_option(&buf->b_p_bt);
+#endif
+		buf->b_p_ma = p_ma;
+	    }
+	}
+
+	/*
+	 * When the options should be copied (ignoring BCO_ALWAYS), set the
+	 * flag that indicates that the options have been initialized.
+	 */
+	if (should_copy)
+	    buf->b_p_initialized = TRUE;
+    }
+
+    check_buf_options(buf);	    /* make sure we don't have NULLs */
+    if (did_isk)
+	(void)buf_init_chartab(buf, FALSE);
+}
+
+/*
+ * Reset the 'modifiable' option and its default value.
+ */
+    void
+reset_modifiable()
+{
+    int		opt_idx;
+
+    curbuf->b_p_ma = FALSE;
+    p_ma = FALSE;
+    opt_idx = findoption((char_u *)"ma");
+    if (opt_idx >= 0)
+	options[opt_idx].def_val[VI_DEFAULT] = FALSE;
+}
+
+/*
+ * Set the global value for 'iminsert' to the local value.
+ */
+    void
+set_iminsert_global()
+{
+    p_iminsert = curbuf->b_p_iminsert;
+}
+
+/*
+ * Set the global value for 'imsearch' to the local value.
+ */
+    void
+set_imsearch_global()
+{
+    p_imsearch = curbuf->b_p_imsearch;
+}
+
+#if defined(FEAT_CMDL_COMPL) || defined(PROTO)
+static int expand_option_idx = -1;
+static char_u expand_option_name[5] = {'t', '_', NUL, NUL, NUL};
+static int expand_option_flags = 0;
+
+    void
+set_context_in_set_cmd(xp, arg, opt_flags)
+    expand_T	*xp;
+    char_u	*arg;
+    int		opt_flags;	/* OPT_GLOBAL and/or OPT_LOCAL */
+{
+    int		nextchar;
+    long_u	flags = 0;	/* init for GCC */
+    int		opt_idx = 0;	/* init for GCC */
+    char_u	*p;
+    char_u	*s;
+    int		is_term_option = FALSE;
+    int		key;
+
+    expand_option_flags = opt_flags;
+
+    xp->xp_context = EXPAND_SETTINGS;
+    if (*arg == NUL)
+    {
+	xp->xp_pattern = arg;
+	return;
+    }
+    p = arg + STRLEN(arg) - 1;
+    if (*p == ' ' && *(p - 1) != '\\')
+    {
+	xp->xp_pattern = p + 1;
+	return;
+    }
+    while (p > arg)
+    {
+	s = p;
+	/* count number of backslashes before ' ' or ',' */
+	if (*p == ' ' || *p == ',')
+	{
+	    while (s > arg && *(s - 1) == '\\')
+		--s;
+	}
+	/* break at a space with an even number of backslashes */
+	if (*p == ' ' && ((p - s) & 1) == 0)
+	{
+	    ++p;
+	    break;
+	}
+	--p;
+    }
+    if (STRNCMP(p, "no", 2) == 0)
+    {
+	xp->xp_context = EXPAND_BOOL_SETTINGS;
+	p += 2;
+    }
+    if (STRNCMP(p, "inv", 3) == 0)
+    {
+	xp->xp_context = EXPAND_BOOL_SETTINGS;
+	p += 3;
+    }
+    xp->xp_pattern = arg = p;
+    if (*arg == '<')
+    {
+	while (*p != '>')
+	    if (*p++ == NUL)	    /* expand terminal option name */
+		return;
+	key = get_special_key_code(arg + 1);
+	if (key == 0)		    /* unknown name */
+	{
+	    xp->xp_context = EXPAND_NOTHING;
+	    return;
+	}
+	nextchar = *++p;
+	is_term_option = TRUE;
+	expand_option_name[2] = KEY2TERMCAP0(key);
+	expand_option_name[3] = KEY2TERMCAP1(key);
+    }
+    else
+    {
+	if (p[0] == 't' && p[1] == '_')
+	{
+	    p += 2;
+	    if (*p != NUL)
+		++p;
+	    if (*p == NUL)
+		return;		/* expand option name */
+	    nextchar = *++p;
+	    is_term_option = TRUE;
+	    expand_option_name[2] = p[-2];
+	    expand_option_name[3] = p[-1];
+	}
+	else
+	{
+		/* Allow * wildcard */
+	    while (ASCII_ISALNUM(*p) || *p == '_' || *p == '*')
+		p++;
+	    if (*p == NUL)
+		return;
+	    nextchar = *p;
+	    *p = NUL;
+	    opt_idx = findoption(arg);
+	    *p = nextchar;
+	    if (opt_idx == -1 || options[opt_idx].var == NULL)
+	    {
+		xp->xp_context = EXPAND_NOTHING;
+		return;
+	    }
+	    flags = options[opt_idx].flags;
+	    if (flags & P_BOOL)
+	    {
+		xp->xp_context = EXPAND_NOTHING;
+		return;
+	    }
+	}
+    }
+    /* handle "-=" and "+=" */
+    if ((nextchar == '-' || nextchar == '+' || nextchar == '^') && p[1] == '=')
+    {
+	++p;
+	nextchar = '=';
+    }
+    if ((nextchar != '=' && nextchar != ':')
+				    || xp->xp_context == EXPAND_BOOL_SETTINGS)
+    {
+	xp->xp_context = EXPAND_UNSUCCESSFUL;
+	return;
+    }
+    if (xp->xp_context != EXPAND_BOOL_SETTINGS && p[1] == NUL)
+    {
+	xp->xp_context = EXPAND_OLD_SETTING;
+	if (is_term_option)
+	    expand_option_idx = -1;
+	else
+	    expand_option_idx = opt_idx;
+	xp->xp_pattern = p + 1;
+	return;
+    }
+    xp->xp_context = EXPAND_NOTHING;
+    if (is_term_option || (flags & P_NUM))
+	return;
+
+    xp->xp_pattern = p + 1;
+
+    if (flags & P_EXPAND)
+    {
+	p = options[opt_idx].var;
+	if (p == (char_u *)&p_bdir
+		|| p == (char_u *)&p_dir
+		|| p == (char_u *)&p_path
+		|| p == (char_u *)&p_rtp
+#ifdef FEAT_SEARCHPATH
+		|| p == (char_u *)&p_cdpath
+#endif
+#ifdef FEAT_SESSION
+		|| p == (char_u *)&p_vdir
+#endif
+		)
+	{
+	    xp->xp_context = EXPAND_DIRECTORIES;
+	    if (p == (char_u *)&p_path
+#ifdef FEAT_SEARCHPATH
+		    || p == (char_u *)&p_cdpath
+#endif
+		   )
+		xp->xp_backslash = XP_BS_THREE;
+	    else
+		xp->xp_backslash = XP_BS_ONE;
+	}
+	else
+	{
+	    xp->xp_context = EXPAND_FILES;
+	    /* for 'tags' need three backslashes for a space */
+	    if (p == (char_u *)&p_tags)
+		xp->xp_backslash = XP_BS_THREE;
+	    else
+		xp->xp_backslash = XP_BS_ONE;
+	}
+    }
+
+    /* For an option that is a list of file names, find the start of the
+     * last file name. */
+    for (p = arg + STRLEN(arg) - 1; p > xp->xp_pattern; --p)
+    {
+	/* count number of backslashes before ' ' or ',' */
+	if (*p == ' ' || *p == ',')
+	{
+	    s = p;
+	    while (s > xp->xp_pattern && *(s - 1) == '\\')
+		--s;
+	    if ((*p == ' ' && (xp->xp_backslash == XP_BS_THREE && (p - s) < 3))
+		    || (*p == ',' && (flags & P_COMMA) && ((p - s) & 1) == 0))
+	    {
+		xp->xp_pattern = p + 1;
+		break;
+	    }
+	}
+
+#ifdef FEAT_SPELL
+	/* for 'spellsuggest' start at "file:" */
+	if (options[opt_idx].var == (char_u *)&p_sps
+					       && STRNCMP(p, "file:", 5) == 0)
+	{
+	    xp->xp_pattern = p + 5;
+	    break;
+	}
+#endif
+    }
+
+    return;
+}
+
+    int
+ExpandSettings(xp, regmatch, num_file, file)
+    expand_T	*xp;
+    regmatch_T	*regmatch;
+    int		*num_file;
+    char_u	***file;
+{
+    int		num_normal = 0;	    /* Nr of matching non-term-code settings */
+    int		num_term = 0;	    /* Nr of matching terminal code settings */
+    int		opt_idx;
+    int		match;
+    int		count = 0;
+    char_u	*str;
+    int		loop;
+    int		is_term_opt;
+    char_u	name_buf[MAX_KEY_NAME_LEN];
+    static char *(names[]) = {"all", "termcap"};
+    int		ic = regmatch->rm_ic;	/* remember the ignore-case flag */
+
+    /* do this loop twice:
+     * loop == 0: count the number of matching options
+     * loop == 1: copy the matching options into allocated memory
+     */
+    for (loop = 0; loop <= 1; ++loop)
+    {
+	regmatch->rm_ic = ic;
+	if (xp->xp_context != EXPAND_BOOL_SETTINGS)
+	{
+	    for (match = 0; match < sizeof(names) / sizeof(char *); ++match)
+		if (vim_regexec(regmatch, (char_u *)names[match], (colnr_T)0))
+		{
+		    if (loop == 0)
+			num_normal++;
+		    else
+			(*file)[count++] = vim_strsave((char_u *)names[match]);
+		}
+	}
+	for (opt_idx = 0; (str = (char_u *)options[opt_idx].fullname) != NULL;
+								    opt_idx++)
+	{
+	    if (options[opt_idx].var == NULL)
+		continue;
+	    if (xp->xp_context == EXPAND_BOOL_SETTINGS
+	      && !(options[opt_idx].flags & P_BOOL))
+		continue;
+	    is_term_opt = istermoption(&options[opt_idx]);
+	    if (is_term_opt && num_normal > 0)
+		continue;
+	    match = FALSE;
+	    if (vim_regexec(regmatch, str, (colnr_T)0)
+		    || (options[opt_idx].shortname != NULL
+			&& vim_regexec(regmatch,
+			   (char_u *)options[opt_idx].shortname, (colnr_T)0)))
+		match = TRUE;
+	    else if (is_term_opt)
+	    {
+		name_buf[0] = '<';
+		name_buf[1] = 't';
+		name_buf[2] = '_';
+		name_buf[3] = str[2];
+		name_buf[4] = str[3];
+		name_buf[5] = '>';
+		name_buf[6] = NUL;
+		if (vim_regexec(regmatch, name_buf, (colnr_T)0))
+		{
+		    match = TRUE;
+		    str = name_buf;
+		}
+	    }
+	    if (match)
+	    {
+		if (loop == 0)
+		{
+		    if (is_term_opt)
+			num_term++;
+		    else
+			num_normal++;
+		}
+		else
+		    (*file)[count++] = vim_strsave(str);
+	    }
+	}
+	/*
+	 * Check terminal key codes, these are not in the option table
+	 */
+	if (xp->xp_context != EXPAND_BOOL_SETTINGS  && num_normal == 0)
+	{
+	    for (opt_idx = 0; (str = get_termcode(opt_idx)) != NULL; opt_idx++)
+	    {
+		if (!isprint(str[0]) || !isprint(str[1]))
+		    continue;
+
+		name_buf[0] = 't';
+		name_buf[1] = '_';
+		name_buf[2] = str[0];
+		name_buf[3] = str[1];
+		name_buf[4] = NUL;
+
+		match = FALSE;
+		if (vim_regexec(regmatch, name_buf, (colnr_T)0))
+		    match = TRUE;
+		else
+		{
+		    name_buf[0] = '<';
+		    name_buf[1] = 't';
+		    name_buf[2] = '_';
+		    name_buf[3] = str[0];
+		    name_buf[4] = str[1];
+		    name_buf[5] = '>';
+		    name_buf[6] = NUL;
+
+		    if (vim_regexec(regmatch, name_buf, (colnr_T)0))
+			match = TRUE;
+		}
+		if (match)
+		{
+		    if (loop == 0)
+			num_term++;
+		    else
+			(*file)[count++] = vim_strsave(name_buf);
+		}
+	    }
+
+	    /*
+	     * Check special key names.
+	     */
+	    regmatch->rm_ic = TRUE;		/* ignore case here */
+	    for (opt_idx = 0; (str = get_key_name(opt_idx)) != NULL; opt_idx++)
+	    {
+		name_buf[0] = '<';
+		STRCPY(name_buf + 1, str);
+		STRCAT(name_buf, ">");
+
+		if (vim_regexec(regmatch, name_buf, (colnr_T)0))
+		{
+		    if (loop == 0)
+			num_term++;
+		    else
+			(*file)[count++] = vim_strsave(name_buf);
+		}
+	    }
+	}
+	if (loop == 0)
+	{
+	    if (num_normal > 0)
+		*num_file = num_normal;
+	    else if (num_term > 0)
+		*num_file = num_term;
+	    else
+		return OK;
+	    *file = (char_u **)alloc((unsigned)(*num_file * sizeof(char_u *)));
+	    if (*file == NULL)
+	    {
+		*file = (char_u **)"";
+		return FAIL;
+	    }
+	}
+    }
+    return OK;
+}
+
+    int
+ExpandOldSetting(num_file, file)
+    int	    *num_file;
+    char_u  ***file;
+{
+    char_u  *var = NULL;	/* init for GCC */
+    char_u  *buf;
+
+    *num_file = 0;
+    *file = (char_u **)alloc((unsigned)sizeof(char_u *));
+    if (*file == NULL)
+	return FAIL;
+
+    /*
+     * For a terminal key code expand_option_idx is < 0.
+     */
+    if (expand_option_idx < 0)
+    {
+	var = find_termcode(expand_option_name + 2);
+	if (var == NULL)
+	    expand_option_idx = findoption(expand_option_name);
+    }
+
+    if (expand_option_idx >= 0)
+    {
+	/* put string of option value in NameBuff */
+	option_value2string(&options[expand_option_idx], expand_option_flags);
+	var = NameBuff;
+    }
+    else if (var == NULL)
+	var = (char_u *)"";
+
+    /* A backslash is required before some characters.  This is the reverse of
+     * what happens in do_set(). */
+    buf = vim_strsave_escaped(var, escape_chars);
+
+    if (buf == NULL)
+    {
+	vim_free(*file);
+	*file = NULL;
+	return FAIL;
+    }
+
+#ifdef BACKSLASH_IN_FILENAME
+    /* For MS-Windows et al. we don't double backslashes at the start and
+     * before a file name character. */
+    for (var = buf; *var != NUL; mb_ptr_adv(var))
+	if (var[0] == '\\' && var[1] == '\\'
+		&& expand_option_idx >= 0
+		&& (options[expand_option_idx].flags & P_EXPAND)
+		&& vim_isfilec(var[2])
+		&& (var[2] != '\\' || (var == buf && var[4] != '\\')))
+	    mch_memmove(var, var + 1, STRLEN(var));
+#endif
+
+    *file[0] = buf;
+    *num_file = 1;
+    return OK;
+}
+#endif
+
+/*
+ * Get the value for the numeric or string option *opp in a nice format into
+ * NameBuff[].  Must not be called with a hidden option!
+ */
+    static void
+option_value2string(opp, opt_flags)
+    struct vimoption	*opp;
+    int			opt_flags;	/* OPT_GLOBAL and/or OPT_LOCAL */
+{
+    char_u	*varp;
+
+    varp = get_varp_scope(opp, opt_flags);
+
+    if (opp->flags & P_NUM)
+    {
+	long wc = 0;
+
+	if (wc_use_keyname(varp, &wc))
+	    STRCPY(NameBuff, get_special_key_name((int)wc, 0));
+	else if (wc != 0)
+	    STRCPY(NameBuff, transchar((int)wc));
+	else
+	    sprintf((char *)NameBuff, "%ld", *(long *)varp);
+    }
+    else    /* P_STRING */
+    {
+	varp = *(char_u **)(varp);
+	if (varp == NULL)		    /* just in case */
+	    NameBuff[0] = NUL;
+#ifdef FEAT_CRYPT
+	/* don't show the actual value of 'key', only that it's set */
+	else if (opp->var == (char_u *)&p_key && *varp)
+	    STRCPY(NameBuff, "*****");
+#endif
+	else if (opp->flags & P_EXPAND)
+	    home_replace(NULL, varp, NameBuff, MAXPATHL, FALSE);
+	/* Translate 'pastetoggle' into special key names */
+	else if ((char_u **)opp->var == &p_pt)
+	    str2specialbuf(p_pt, NameBuff, MAXPATHL);
+	else
+	    vim_strncpy(NameBuff, varp, MAXPATHL - 1);
+    }
+}
+
+/*
+ * Return TRUE if "varp" points to 'wildchar' or 'wildcharm' and it can be
+ * printed as a keyname.
+ * "*wcp" is set to the value of the option if it's 'wildchar' or 'wildcharm'.
+ */
+    static int
+wc_use_keyname(varp, wcp)
+    char_u	*varp;
+    long	*wcp;
+{
+    if (((long *)varp == &p_wc) || ((long *)varp == &p_wcm))
+    {
+	*wcp = *(long *)varp;
+	if (IS_SPECIAL(*wcp) || find_special_key_in_table((int)*wcp) >= 0)
+	    return TRUE;
+    }
+    return FALSE;
+}
+
+#ifdef FEAT_LANGMAP
+/*
+ * Any character has an equivalent character.  This is used for keyboards that
+ * have a special language mode that sends characters above 128 (although
+ * other characters can be translated too).
+ */
+
+/*
+ * char_u langmap_mapchar[256];
+ * Normally maps each of the 128 upper chars to an <128 ascii char; used to
+ * "translate" native lang chars in normal mode or some cases of
+ * insert mode without having to tediously switch lang mode back&forth.
+ */
+
+    static void
+langmap_init()
+{
+    int i;
+
+    for (i = 0; i < 256; i++)		/* we init with a-one-to one map */
+	langmap_mapchar[i] = i;
+}
+
+/*
+ * Called when langmap option is set; the language map can be
+ * changed at any time!
+ */
+    static void
+langmap_set()
+{
+    char_u  *p;
+    char_u  *p2;
+    int	    from, to;
+
+    langmap_init();			    /* back to one-to-one map first */
+
+    for (p = p_langmap; p[0] != NUL; )
+    {
+	for (p2 = p; p2[0] != NUL && p2[0] != ',' && p2[0] != ';';
+							       mb_ptr_adv(p2))
+	{
+	    if (p2[0] == '\\' && p2[1] != NUL)
+		++p2;
+	}
+	if (p2[0] == ';')
+	    ++p2;	    /* abcd;ABCD form, p2 points to A */
+	else
+	    p2 = NULL;	    /* aAbBcCdD form, p2 is NULL */
+	while (p[0])
+	{
+	    if (p[0] == '\\' && p[1] != NUL)
+		++p;
+#ifdef FEAT_MBYTE
+	    from = (*mb_ptr2char)(p);
+#else
+	    from = p[0];
+#endif
+	    if (p2 == NULL)
+	    {
+		mb_ptr_adv(p);
+		if (p[0] == '\\')
+		    ++p;
+#ifdef FEAT_MBYTE
+		to = (*mb_ptr2char)(p);
+#else
+		to = p[0];
+#endif
+	    }
+	    else
+	    {
+		if (p2[0] == '\\')
+		    ++p2;
+#ifdef FEAT_MBYTE
+		to = (*mb_ptr2char)(p2);
+#else
+		to = p2[0];
+#endif
+	    }
+	    if (to == NUL)
+	    {
+		EMSG2(_("E357: 'langmap': Matching character missing for %s"),
+							     transchar(from));
+		return;
+	    }
+	    langmap_mapchar[from & 255] = to;
+
+	    /* Advance to next pair */
+	    mb_ptr_adv(p);
+	    if (p2 == NULL)
+	    {
+		if (p[0] == ',')
+		{
+		    ++p;
+		    break;
+		}
+	    }
+	    else
+	    {
+		mb_ptr_adv(p2);
+		if (*p == ';')
+		{
+		    p = p2;
+		    if (p[0] != NUL)
+		    {
+			if (p[0] != ',')
+			{
+			    EMSG2(_("E358: 'langmap': Extra characters after semicolon: %s"), p);
+			    return;
+			}
+			++p;
+		    }
+		    break;
+		}
+	    }
+	}
+    }
+}
+#endif
+
+/*
+ * Return TRUE if format option 'x' is in effect.
+ * Take care of no formatting when 'paste' is set.
+ */
+    int
+has_format_option(x)
+    int		x;
+{
+    if (p_paste)
+	return FALSE;
+    return (vim_strchr(curbuf->b_p_fo, x) != NULL);
+}
+
+/*
+ * Return TRUE if "x" is present in 'shortmess' option, or
+ * 'shortmess' contains 'a' and "x" is present in SHM_A.
+ */
+    int
+shortmess(x)
+    int	    x;
+{
+    return (   vim_strchr(p_shm, x) != NULL
+	    || (vim_strchr(p_shm, 'a') != NULL
+		&& vim_strchr((char_u *)SHM_A, x) != NULL));
+}
+
+/*
+ * paste_option_changed() - Called after p_paste was set or reset.
+ */
+    static void
+paste_option_changed()
+{
+    static int	old_p_paste = FALSE;
+    static int	save_sm = 0;
+#ifdef FEAT_CMDL_INFO
+    static int	save_ru = 0;
+#endif
+#ifdef FEAT_RIGHTLEFT
+    static int	save_ri = 0;
+    static int	save_hkmap = 0;
+#endif
+    buf_T	*buf;
+
+    if (p_paste)
+    {
+	/*
+	 * Paste switched from off to on.
+	 * Save the current values, so they can be restored later.
+	 */
+	if (!old_p_paste)
+	{
+	    /* save options for each buffer */
+	    for (buf = firstbuf; buf != NULL; buf = buf->b_next)
+	    {
+		buf->b_p_tw_nopaste = buf->b_p_tw;
+		buf->b_p_wm_nopaste = buf->b_p_wm;
+		buf->b_p_sts_nopaste = buf->b_p_sts;
+		buf->b_p_ai_nopaste = buf->b_p_ai;
+	    }
+
+	    /* save global options */
+	    save_sm = p_sm;
+#ifdef FEAT_CMDL_INFO
+	    save_ru = p_ru;
+#endif
+#ifdef FEAT_RIGHTLEFT
+	    save_ri = p_ri;
+	    save_hkmap = p_hkmap;
+#endif
+	    /* save global values for local buffer options */
+	    p_tw_nopaste = p_tw;
+	    p_wm_nopaste = p_wm;
+	    p_sts_nopaste = p_sts;
+	    p_ai_nopaste = p_ai;
+	}
+
+	/*
+	 * Always set the option values, also when 'paste' is set when it is
+	 * already on.
+	 */
+	/* set options for each buffer */
+	for (buf = firstbuf; buf != NULL; buf = buf->b_next)
+	{
+	    buf->b_p_tw = 0;	    /* textwidth is 0 */
+	    buf->b_p_wm = 0;	    /* wrapmargin is 0 */
+	    buf->b_p_sts = 0;	    /* softtabstop is 0 */
+	    buf->b_p_ai = 0;	    /* no auto-indent */
+	}
+
+	/* set global options */
+	p_sm = 0;		    /* no showmatch */
+#ifdef FEAT_CMDL_INFO
+# ifdef FEAT_WINDOWS
+	if (p_ru)
+	    status_redraw_all();    /* redraw to remove the ruler */
+# endif
+	p_ru = 0;		    /* no ruler */
+#endif
+#ifdef FEAT_RIGHTLEFT
+	p_ri = 0;		    /* no reverse insert */
+	p_hkmap = 0;		    /* no Hebrew keyboard */
+#endif
+	/* set global values for local buffer options */
+	p_tw = 0;
+	p_wm = 0;
+	p_sts = 0;
+	p_ai = 0;
+    }
+
+    /*
+     * Paste switched from on to off: Restore saved values.
+     */
+    else if (old_p_paste)
+    {
+	/* restore options for each buffer */
+	for (buf = firstbuf; buf != NULL; buf = buf->b_next)
+	{
+	    buf->b_p_tw = buf->b_p_tw_nopaste;
+	    buf->b_p_wm = buf->b_p_wm_nopaste;
+	    buf->b_p_sts = buf->b_p_sts_nopaste;
+	    buf->b_p_ai = buf->b_p_ai_nopaste;
+	}
+
+	/* restore global options */
+	p_sm = save_sm;
+#ifdef FEAT_CMDL_INFO
+# ifdef FEAT_WINDOWS
+	if (p_ru != save_ru)
+	    status_redraw_all();    /* redraw to draw the ruler */
+# endif
+	p_ru = save_ru;
+#endif
+#ifdef FEAT_RIGHTLEFT
+	p_ri = save_ri;
+	p_hkmap = save_hkmap;
+#endif
+	/* set global values for local buffer options */
+	p_tw = p_tw_nopaste;
+	p_wm = p_wm_nopaste;
+	p_sts = p_sts_nopaste;
+	p_ai = p_ai_nopaste;
+    }
+
+    old_p_paste = p_paste;
+}
+
+/*
+ * vimrc_found() - Called when a ".vimrc" or "VIMINIT" has been found.
+ *
+ * Reset 'compatible' and set the values for options that didn't get set yet
+ * to the Vim defaults.
+ * Don't do this if the 'compatible' option has been set or reset before.
+ * When "fname" is not NULL, use it to set $"envname" when it wasn't set yet.
+ */
+    void
+vimrc_found(fname, envname)
+    char_u	*fname;
+    char_u	*envname;
+{
+    int		opt_idx;
+    int		dofree = FALSE;
+    char_u	*p;
+
+    if (!option_was_set((char_u *)"cp"))
+    {
+	p_cp = FALSE;
+	for (opt_idx = 0; !istermoption(&options[opt_idx]); opt_idx++)
+	    if (!(options[opt_idx].flags & (P_WAS_SET|P_VI_DEF)))
+		set_option_default(opt_idx, OPT_FREE, FALSE);
+	didset_options();
+    }
+
+    if (fname != NULL)
+    {
+	p = vim_getenv(envname, &dofree);
+	if (p == NULL)
+	{
+	    /* Set $MYVIMRC to the first vimrc file found. */
+	    p = FullName_save(fname, FALSE);
+	    if (p != NULL)
+	    {
+		vim_setenv(envname, p);
+		vim_free(p);
+	    }
+	}
+	else if (dofree)
+	    vim_free(p);
+    }
+}
+
+/*
+ * Set 'compatible' on or off.  Called for "-C" and "-N" command line arg.
+ */
+    void
+change_compatible(on)
+    int	    on;
+{
+    int	    opt_idx;
+
+    if (p_cp != on)
+    {
+	p_cp = on;
+	compatible_set();
+    }
+    opt_idx = findoption((char_u *)"cp");
+    if (opt_idx >= 0)
+	options[opt_idx].flags |= P_WAS_SET;
+}
+
+/*
+ * Return TRUE when option "name" has been set.
+ */
+    int
+option_was_set(name)
+    char_u	*name;
+{
+    int idx;
+
+    idx = findoption(name);
+    if (idx < 0)	/* unknown option */
+	return FALSE;
+    if (options[idx].flags & P_WAS_SET)
+	return TRUE;
+    return FALSE;
+}
+
+/*
+ * compatible_set() - Called when 'compatible' has been set or unset.
+ *
+ * When 'compatible' set: Set all relevant options (those that have the P_VIM)
+ * flag) to a Vi compatible value.
+ * When 'compatible' is unset: Set all options that have a different default
+ * for Vim (without the P_VI_DEF flag) to that default.
+ */
+    static void
+compatible_set()
+{
+    int	    opt_idx;
+
+    for (opt_idx = 0; !istermoption(&options[opt_idx]); opt_idx++)
+	if (	   ((options[opt_idx].flags & P_VIM) && p_cp)
+		|| (!(options[opt_idx].flags & P_VI_DEF) && !p_cp))
+	    set_option_default(opt_idx, OPT_FREE, p_cp);
+    didset_options();
+}
+
+#ifdef FEAT_LINEBREAK
+
+# if defined(__BORLANDC__) && (__BORLANDC__ < 0x500)
+   /* Borland C++ screws up loop optimisation here (negri) */
+  #pragma option -O-l
+# endif
+
+/*
+ * fill_breakat_flags() -- called when 'breakat' changes value.
+ */
+    static void
+fill_breakat_flags()
+{
+    char_u	*p;
+    int		i;
+
+    for (i = 0; i < 256; i++)
+	breakat_flags[i] = FALSE;
+
+    if (p_breakat != NULL)
+	for (p = p_breakat; *p; p++)
+	    breakat_flags[*p] = TRUE;
+}
+
+# if defined(__BORLANDC__) && (__BORLANDC__ < 0x500)
+  #pragma option -O.l
+# endif
+
+#endif
+
+/*
+ * Check an option that can be a range of string values.
+ *
+ * Return OK for correct value, FAIL otherwise.
+ * Empty is always OK.
+ */
+    static int
+check_opt_strings(val, values, list)
+    char_u	*val;
+    char	**values;
+    int		list;	    /* when TRUE: accept a list of values */
+{
+    return opt_strings_flags(val, values, NULL, list);
+}
+
+/*
+ * Handle an option that can be a range of string values.
+ * Set a flag in "*flagp" for each string present.
+ *
+ * Return OK for correct value, FAIL otherwise.
+ * Empty is always OK.
+ */
+    static int
+opt_strings_flags(val, values, flagp, list)
+    char_u	*val;		/* new value */
+    char	**values;	/* array of valid string values */
+    unsigned	*flagp;
+    int		list;		/* when TRUE: accept a list of values */
+{
+    int		i;
+    int		len;
+    unsigned	new_flags = 0;
+
+    while (*val)
+    {
+	for (i = 0; ; ++i)
+	{
+	    if (values[i] == NULL)	/* val not found in values[] */
+		return FAIL;
+
+	    len = (int)STRLEN(values[i]);
+	    if (STRNCMP(values[i], val, len) == 0
+		    && ((list && val[len] == ',') || val[len] == NUL))
+	    {
+		val += len + (val[len] == ',');
+		new_flags |= (1 << i);
+		break;		/* check next item in val list */
+	    }
+	}
+    }
+    if (flagp != NULL)
+	*flagp = new_flags;
+
+    return OK;
+}
+
+/*
+ * Read the 'wildmode' option, fill wim_flags[].
+ */
+    static int
+check_opt_wim()
+{
+    char_u	new_wim_flags[4];
+    char_u	*p;
+    int		i;
+    int		idx = 0;
+
+    for (i = 0; i < 4; ++i)
+	new_wim_flags[i] = 0;
+
+    for (p = p_wim; *p; ++p)
+    {
+	for (i = 0; ASCII_ISALPHA(p[i]); ++i)
+	    ;
+	if (p[i] != NUL && p[i] != ',' && p[i] != ':')
+	    return FAIL;
+	if (i == 7 && STRNCMP(p, "longest", 7) == 0)
+	    new_wim_flags[idx] |= WIM_LONGEST;
+	else if (i == 4 && STRNCMP(p, "full", 4) == 0)
+	    new_wim_flags[idx] |= WIM_FULL;
+	else if (i == 4 && STRNCMP(p, "list", 4) == 0)
+	    new_wim_flags[idx] |= WIM_LIST;
+	else
+	    return FAIL;
+	p += i;
+	if (*p == NUL)
+	    break;
+	if (*p == ',')
+	{
+	    if (idx == 3)
+		return FAIL;
+	    ++idx;
+	}
+    }
+
+    /* fill remaining entries with last flag */
+    while (idx < 3)
+    {
+	new_wim_flags[idx + 1] = new_wim_flags[idx];
+	++idx;
+    }
+
+    /* only when there are no errors, wim_flags[] is changed */
+    for (i = 0; i < 4; ++i)
+	wim_flags[i] = new_wim_flags[i];
+    return OK;
+}
+
+/*
+ * Check if backspacing over something is allowed.
+ */
+    int
+can_bs(what)
+    int		what;	    /* BS_INDENT, BS_EOL or BS_START */
+{
+    switch (*p_bs)
+    {
+	case '2':	return TRUE;
+	case '1':	return (what != BS_START);
+	case '0':	return FALSE;
+    }
+    return vim_strchr(p_bs, what) != NULL;
+}
+
+/*
+ * Save the current values of 'fileformat' and 'fileencoding', so that we know
+ * the file must be considered changed when the value is different.
+ */
+    void
+save_file_ff(buf)
+    buf_T	*buf;
+{
+    buf->b_start_ffc = *buf->b_p_ff;
+    buf->b_start_eol = buf->b_p_eol;
+#ifdef FEAT_MBYTE
+    /* Only use free/alloc when necessary, they take time. */
+    if (buf->b_start_fenc == NULL
+			     || STRCMP(buf->b_start_fenc, buf->b_p_fenc) != 0)
+    {
+	vim_free(buf->b_start_fenc);
+	buf->b_start_fenc = vim_strsave(buf->b_p_fenc);
+    }
+#endif
+}
+
+/*
+ * Return TRUE if 'fileformat' and/or 'fileencoding' has a different value
+ * from when editing started (save_file_ff() called).
+ * Also when 'endofline' was changed and 'binary' is set.
+ * Don't consider a new, empty buffer to be changed.
+ */
+    int
+file_ff_differs(buf)
+    buf_T	*buf;
+{
+    if ((buf->b_flags & BF_NEW)
+	    && buf->b_ml.ml_line_count == 1
+	    && *ml_get_buf(buf, (linenr_T)1, FALSE) == NUL)
+	return FALSE;
+    if (buf->b_start_ffc != *buf->b_p_ff)
+	return TRUE;
+    if (buf->b_p_bin && buf->b_start_eol != buf->b_p_eol)
+	return TRUE;
+#ifdef FEAT_MBYTE
+    if (buf->b_start_fenc == NULL)
+	return (*buf->b_p_fenc != NUL);
+    return (STRCMP(buf->b_start_fenc, buf->b_p_fenc) != 0);
+#else
+    return FALSE;
+#endif
+}
+
+/*
+ * return OK if "p" is a valid fileformat name, FAIL otherwise.
+ */
+    int
+check_ff_value(p)
+    char_u	*p;
+{
+    return check_opt_strings(p, p_ff_values, FALSE);
+}
--- /dev/null
+++ b/option.h
@@ -1,0 +1,1063 @@
+/* vi:set ts=8 sts=4 sw=4:
+ *
+ * VIM - Vi IMproved	by Bram Moolenaar
+ *
+ * Do ":help uganda"  in Vim to read copying and usage conditions.
+ * Do ":help credits" in Vim to see a list of people who contributed.
+ */
+
+/*
+ * option.h: definition of global variables for settable options
+ */
+
+/*
+ * Default values for 'errorformat'.
+ * The "%f|%l| %m" one is used for when the contents of the quickfix window is
+ * written to a file.
+ */
+#ifdef AMIGA
+# define DFLT_EFM	"%f>%l:%c:%t:%n:%m,%f:%l: %t%*\\D%n: %m,%f %l %t%*\\D%n: %m,%*[^\"]\"%f\"%*\\D%l: %m,%f:%l:%m,%f|%l| %m"
+#else
+# if defined(MSDOS) || defined(WIN3264)
+#  define DFLT_EFM	"%f(%l) : %t%*\\D%n: %m,%*[^\"]\"%f\"%*\\D%l: %m,%f(%l) : %m,%*[^ ] %f %l: %m,%f:%l:%c:%m,%f(%l):%m,%f:%l:%m,%f|%l| %m"
+# else
+#  if defined(__EMX__)	/* put most common here (i.e. gcc format) at front */
+#   define DFLT_EFM	"%f:%l:%c:%m,%f(%l):%m,%f:%l:%m,%*[^\"]\"%f\"%*\\D%l: %m,\"%f\"%*\\D%l: %m,%f(%l:%c) : %m,%f|%l| %m"
+#  else
+#   if defined(__QNX__)
+#    define DFLT_EFM	"%f(%l):%*[^WE]%t%*\\D%n:%m,%f|%l| %m"
+#   else
+#    ifdef VMS
+#     define DFLT_EFM	"%A%p^,%C%%CC-%t-%m,%Cat line number %l in file %f,%f|%l| %m"
+#    else /* Unix, probably */
+#     ifdef EBCDIC
+#define DFLT_EFM	"%*[^ ] %*[^ ] %f:%l%*[ ]%m,%*[^\"]\"%f\"%*\\D%l: %m,\"%f\"%*\\D%l: %m,%f:%l:%c:%m,%f(%l):%m,%f:%l:%m,\"%f\"\\, line %l%*\\D%c%*[^ ] %m,%D%*\\a[%*\\d]: Entering directory `%f',%X%*\\a[%*\\d]: Leaving directory `%f',%DMaking %*\\a in %f,%f|%l| %m"
+#     else
+#define DFLT_EFM	"%*[^\"]\"%f\"%*\\D%l: %m,\"%f\"%*\\D%l: %m,%-G%f:%l: (Each undeclared identifier is reported only once,%-G%f:%l: for each function it appears in.),%f:%l:%c:%m,%f(%l):%m,%f:%l:%m,\"%f\"\\, line %l%*\\D%c%*[^ ] %m,%D%*\\a[%*\\d]: Entering directory `%f',%X%*\\a[%*\\d]: Leaving directory `%f',%D%*\\a: Entering directory `%f',%X%*\\a: Leaving directory `%f',%DMaking %*\\a in %f,%f|%l| %m"
+#     endif
+#    endif
+#   endif
+#  endif
+# endif
+#endif
+
+#define DFLT_GREPFORMAT	"%f:%l:%m,%f:%l%m,%f  %l%m"
+
+/* default values for b_p_ff 'fileformat' and p_ffs 'fileformats' */
+#define FF_DOS		"dos"
+#define FF_MAC		"mac"
+#define FF_UNIX		"unix"
+
+#ifdef USE_CRNL
+# define DFLT_FF	"dos"
+# define DFLT_FFS_VIM	"dos,unix"
+# define DFLT_FFS_VI	"dos,unix"	/* also autodetect in compatible mode */
+# define DFLT_TEXTAUTO	TRUE
+#else
+# ifdef USE_CR
+#  define DFLT_FF	"mac"
+#  define DFLT_FFS_VIM	"mac,unix,dos"
+#  define DFLT_FFS_VI	"mac,unix,dos"
+#  define DFLT_TEXTAUTO	TRUE
+# else
+#  define DFLT_FF	"unix"
+#  define DFLT_FFS_VIM	"unix,dos"
+#  ifdef __CYGWIN__
+#   define DFLT_FFS_VI	"unix,dos"	/* Cygwin always needs file detection */
+#   define DFLT_TEXTAUTO TRUE
+#  else
+#   define DFLT_FFS_VI	""
+#   define DFLT_TEXTAUTO FALSE
+#  endif
+# endif
+#endif
+
+
+#ifdef FEAT_MBYTE
+/* Possible values for 'encoding' */
+# define ENC_UCSBOM	"ucs-bom"	/* check for BOM at start of file */
+
+/* default value for 'encoding' */
+# define ENC_DFLT	"latin1"
+#endif
+
+/* end-of-line style */
+#define EOL_UNKNOWN	-1	/* not defined yet */
+#define EOL_UNIX	0	/* NL */
+#define EOL_DOS		1	/* CR NL */
+#define EOL_MAC		2	/* CR */
+
+/* Formatting options for p_fo 'formatoptions' */
+#define FO_WRAP		't'
+#define FO_WRAP_COMS	'c'
+#define FO_RET_COMS	'r'
+#define FO_OPEN_COMS	'o'
+#define FO_Q_COMS	'q'
+#define FO_Q_NUMBER	'n'
+#define FO_Q_SECOND	'2'
+#define FO_INS_VI	'v'
+#define FO_INS_LONG	'l'
+#define FO_INS_BLANK	'b'
+#define FO_MBYTE_BREAK	'm'	/* break before/after multi-byte char */
+#define FO_MBYTE_JOIN	'M'	/* no space before/after multi-byte char */
+#define FO_MBYTE_JOIN2	'B'	/* no space between multi-byte chars */
+#define FO_ONE_LETTER	'1'
+#define FO_WHITE_PAR	'w'	/* trailing white space continues paragr. */
+#define FO_AUTO		'a'	/* automatic formatting */
+
+#define DFLT_FO_VI	"vt"
+#define DFLT_FO_VIM	"tcq"
+#define FO_ALL		"tcroq2vlb1mMBn,aw"	/* for do_set() */
+
+/* characters for the p_cpo option: */
+#define CPO_ALTREAD	'a'	/* ":read" sets alternate file name */
+#define CPO_ALTWRITE	'A'	/* ":write" sets alternate file name */
+#define CPO_BAR		'b'	/* "\|" ends a mapping */
+#define CPO_BSLASH	'B'	/* backslash in mapping is not special */
+#define CPO_SEARCH	'c'
+#define CPO_CONCAT	'C'	/* Don't concatenate sourced lines */
+#define CPO_DOTTAG	'd'	/* "./tags" in 'tags' is in current dir */
+#define CPO_DIGRAPH	'D'	/* No digraph after "r", "f", etc. */
+#define CPO_EXECBUF	'e'
+#define CPO_EMPTYREGION	'E'	/* operating on empty region is an error */
+#define CPO_FNAMER	'f'	/* set file name for ":r file" */
+#define CPO_FNAMEW	'F'	/* set file name for ":w file" */
+#define CPO_GOTO1	'g'	/* goto line 1 for ":edit" */
+#define CPO_INSEND	'H'	/* "I" inserts before last blank in line */
+#define CPO_INTMOD	'i'	/* interrupt a read makes buffer modified */
+#define CPO_INDENT	'I'	/* remove auto-indent more often */
+#define CPO_JOINSP	'j'	/* only use two spaces for join after '.' */
+#define CPO_ENDOFSENT	'J'	/* need two spaces to detect end of sentence */
+#define CPO_KEYCODE	'k'	/* don't recognize raw key code in mappings */
+#define CPO_KOFFSET	'K'	/* don't wait for key code in mappings */
+#define CPO_LITERAL	'l'	/* take char after backslash in [] literal */
+#define CPO_LISTWM	'L'	/* 'list' changes wrapmargin */
+#define CPO_SHOWMATCH	'm'
+#define CPO_MATCHBSL	'M'	/* "%" ignores use of backslashes */
+#define CPO_NUMCOL	'n'	/* 'number' column also used for text */
+#define CPO_LINEOFF	'o'
+#define CPO_OVERNEW	'O'	/* silently overwrite new file */
+#define CPO_LISP	'p'	/* 'lisp' indenting */
+#define CPO_FNAMEAPP	'P'	/* set file name for ":w >>file" */
+#define CPO_JOINCOL	'q'	/* with "3J" use column after first join */
+#define CPO_REDO	'r'
+#define CPO_REMMARK	'R'	/* remove marks when filtering */
+#define CPO_BUFOPT	's'
+#define CPO_BUFOPTGLOB	'S'
+#define CPO_TAGPAT	't'
+#define CPO_UNDO	'u'	/* "u" undoes itself */
+#define CPO_BACKSPACE	'v'	/* "v" keep deleted text */
+#define CPO_CW		'w'	/* "cw" only changes one blank */
+#define CPO_FWRITE	'W'	/* "w!" doesn't overwrite readonly files */
+#define CPO_ESC		'x'
+#define CPO_REPLCNT	'X'	/* "R" with a count only deletes chars once */
+#define CPO_YANK	'y'
+#define CPO_KEEPRO	'Z'	/* don't reset 'readonly' on ":w!" */
+#define CPO_DOLLAR	'$'
+#define CPO_FILTER	'!'
+#define CPO_MATCH	'%'
+#define CPO_STAR	'*'	/* ":*" means ":@" */
+#define CPO_PLUS	'+'	/* ":write file" resets 'modified' */
+#define CPO_MINUS	'-'	/* "9-" fails at and before line 9 */
+#define CPO_SPECI	'<'	/* don't recognize <> in mappings */
+#define CPO_REGAPPEND	'>'	/* insert NL when appending to a register */
+/* POSIX flags */
+#define CPO_HASH	'#'	/* "D", "o" and "O" do not use a count */
+#define CPO_PARA	'{'	/* "{" is also a paragraph boundary */
+#define CPO_TSIZE	'|'	/* $LINES and $COLUMNS overrule term size */
+#define CPO_PRESERVE	'&'	/* keep swap file after :preserve */
+#define CPO_SUBPERCENT	'/'	/* % in :s string uses previous one */
+#define CPO_BACKSL	'\\'	/* \ is not special in [] */
+#define CPO_CHDIR	'.'	/* don't chdir if buffer is modified */
+/* default values for Vim, Vi and POSIX */
+#define CPO_VIM		"aABceFs"
+#define CPO_VI		"aAbBcCdDeEfFgHiIjJkKlLmMnoOpPqrRsStuvwWxXyZ$!%*-+<>"
+#define CPO_ALL		"aAbBcCdDeEfFgHiIjJkKlLmMnoOpPqrRsStuvwWxXyZ$!%*-+<>#{|&/\\."
+
+/* characters for p_ww option: */
+#define WW_ALL		"bshl<>[],~"
+
+/* characters for p_mouse option: */
+#define MOUSE_NORMAL	'n'		/* use mouse in Normal mode */
+#define MOUSE_VISUAL	'v'		/* use mouse in Visual/Select mode */
+#define MOUSE_INSERT	'i'		/* use mouse in Insert mode */
+#define MOUSE_COMMAND	'c'		/* use mouse in Command-line mode */
+#define MOUSE_HELP	'h'		/* use mouse in help buffers */
+#define MOUSE_RETURN	'r'		/* use mouse for hit-return message */
+#define MOUSE_A		"nvich"		/* used for 'a' flag */
+#define MOUSE_ALL	"anvichr"	/* all possible characters */
+#define MOUSE_NONE	' '		/* don't use Visual selection */
+#define MOUSE_NONEF	'x'		/* forced modeless selection */
+
+/* characters for p_shm option: */
+#define SHM_RO		'r'		/* readonly */
+#define SHM_MOD		'm'		/* modified */
+#define SHM_FILE	'f'		/* (file 1 of 2) */
+#define SHM_LAST	'i'		/* last line incomplete */
+#define SHM_TEXT	'x'		/* tx instead of textmode */
+#define SHM_LINES	'l'		/* "L" instead of "lines" */
+#define SHM_NEW		'n'		/* "[New]" instead of "[New file]" */
+#define SHM_WRI		'w'		/* "[w]" instead of "written" */
+#define SHM_A		"rmfixlnw"	/* represented by 'a' flag */
+#define SHM_WRITE	'W'		/* don't use "written" at all */
+#define SHM_TRUNC	't'		/* trunctate file messages */
+#define SHM_TRUNCALL	'T'		/* trunctate all messages */
+#define SHM_OVER	'o'		/* overwrite file messages */
+#define SHM_OVERALL	'O'		/* overwrite more messages */
+#define SHM_SEARCH	's'		/* no search hit bottom messages */
+#define SHM_ATTENTION	'A'		/* no ATTENTION messages */
+#define SHM_INTRO	'I'		/* intro messages */
+#define SHM_ALL		"rmfixlnwaWtToOsAI" /* all possible flags for 'shm' */
+
+/* characters for p_go: */
+#define GO_ASEL		'a'		/* autoselect */
+#define GO_ASELML	'A'		/* autoselect modeless selection */
+#define GO_BOT		'b'		/* use bottom scrollbar */
+#define GO_CONDIALOG	'c'		/* use console dialog */
+#define GO_TABLINE	'e'		/* may show tabline */
+#define GO_FORG		'f'		/* start GUI in foreground */
+#define GO_GREY		'g'		/* use grey menu items */
+#define GO_HORSCROLL	'h'		/* flexible horizontal scrolling */
+#define GO_ICON		'i'		/* use Vim icon */
+#define GO_LEFT		'l'		/* use left scrollbar */
+#define GO_VLEFT	'L'		/* left scrollbar with vert split */
+#define GO_MENUS	'm'		/* use menu bar */
+#define GO_NOSYSMENU	'M'		/* don't source system menu */
+#define GO_POINTER	'p'		/* pointer enter/leave callbacks */
+#define GO_RIGHT	'r'		/* use right scrollbar */
+#define GO_VRIGHT	'R'		/* right scrollbar with vert split */
+#define GO_TEAROFF	't'		/* add tear-off menu items */
+#define GO_TOOLBAR	'T'		/* add toolbar */
+#define GO_FOOTER	'F'		/* add footer */
+#define GO_VERTICAL	'v'		/* arrange dialog buttons vertically */
+#define GO_ALL		"aAbcefFghilmMprtTv" /* all possible flags for 'go' */
+
+/* flags for 'comments' option */
+#define COM_NEST	'n'		/* comments strings nest */
+#define COM_BLANK	'b'		/* needs blank after string */
+#define COM_START	's'		/* start of comment */
+#define COM_MIDDLE	'm'		/* middle of comment */
+#define COM_END		'e'		/* end of comment */
+#define COM_AUTO_END	'x'		/* last char of end closes comment */
+#define COM_FIRST	'f'		/* first line comment only */
+#define COM_LEFT	'l'		/* left adjusted */
+#define COM_RIGHT	'r'		/* right adjusted */
+#define COM_NOBACK	'O'		/* don't use for "O" command */
+#define COM_ALL		"nbsmexflrO"	/* all flags for 'comments' option */
+#define COM_MAX_LEN	50		/* maximum length of a part */
+
+/* flags for 'statusline' option */
+#define STL_FILEPATH	'f'		/* path of file in buffer */
+#define STL_FULLPATH	'F'		/* full path of file in buffer */
+#define STL_FILENAME	't'		/* last part (tail) of file path */
+#define STL_COLUMN	'c'		/* column og cursor*/
+#define STL_VIRTCOL	'v'		/* virtual column */
+#define STL_VIRTCOL_ALT	'V'		/* - with 'if different' display */
+#define STL_LINE	'l'		/* line number of cursor */
+#define STL_NUMLINES	'L'		/* number of lines in buffer */
+#define STL_BUFNO	'n'		/* current buffer number */
+#define STL_KEYMAP	'k'		/* 'keymap' when active */
+#define STL_OFFSET	'o'		/* offset of character under cursor*/
+#define STL_OFFSET_X	'O'		/* - in hexadecimal */
+#define STL_BYTEVAL	'b'		/* byte value of character */
+#define STL_BYTEVAL_X	'B'		/* - in hexadecimal */
+#define STL_ROFLAG	'r'		/* readonly flag */
+#define STL_ROFLAG_ALT	'R'		/* - other display */
+#define STL_HELPFLAG	'h'		/* window is showing a help file */
+#define STL_HELPFLAG_ALT 'H'		/* - other display */
+#define STL_FILETYPE	'y'		/* 'filetype' */
+#define STL_FILETYPE_ALT 'Y'		/* - other display */
+#define STL_PREVIEWFLAG	'w'		/* window is showing the preview buf */
+#define STL_PREVIEWFLAG_ALT 'W'		/* - other display */
+#define STL_MODIFIED	'm'		/* modified flag */
+#define STL_MODIFIED_ALT 'M'		/* - other display */
+#define STL_PERCENTAGE	'p'		/* percentage through file */
+#define STL_ALTPERCENT	'P'		/* percentage as TOP BOT ALL or NN% */
+#define STL_ARGLISTSTAT	'a'		/* argument list status as (x of y) */
+#define STL_PAGENUM	'N'		/* page number (when printing)*/
+#define STL_VIM_EXPR	'{'		/* start of expression to substitute */
+#define STL_MIDDLEMARK	'='		/* separation between left and right */
+#define STL_TRUNCMARK	'<'		/* truncation mark if line is too long*/
+#define STL_USER_HL	'*'		/* highlight from (User)1..9 or 0 */
+#define STL_HIGHLIGHT	'#'		/* highlight name */
+#define STL_TABPAGENR	'T'		/* tab page label nr */
+#define STL_TABCLOSENR	'X'		/* tab page close nr */
+#define STL_ALL		((char_u *) "fFtcvVlLknoObBrRhHmYyWwMpPaN{#")
+
+/* flags used for parsed 'wildmode' */
+#define WIM_FULL	1
+#define WIM_LONGEST	2
+#define WIM_LIST	4
+
+/* arguments for can_bs() */
+#define BS_INDENT	'i'	/* "Indent" */
+#define BS_EOL		'o'	/* "eOl" */
+#define BS_START	's'	/* "Start" */
+
+#define LISPWORD_VALUE	"defun,define,defmacro,set!,lambda,if,case,let,flet,let*,letrec,do,do*,define-syntax,let-syntax,letrec-syntax,destructuring-bind,defpackage,defparameter,defstruct,deftype,defvar,do-all-symbols,do-external-symbols,do-symbols,dolist,dotimes,ecase,etypecase,eval-when,labels,macrolet,multiple-value-bind,multiple-value-call,multiple-value-prog1,multiple-value-setq,prog1,progv,typecase,unless,unwind-protect,when,with-input-from-string,with-open-file,with-open-stream,with-output-to-string,with-package-iterator,define-condition,handler-bind,handler-case,restart-bind,restart-case,with-simple-restart,store-value,use-value,muffle-warning,abort,continue,with-slots,with-slots*,with-accessors,with-accessors*,defclass,defmethod,print-unreadable-object"
+
+/*
+ * The following are actual variables for the options
+ */
+
+#ifdef FEAT_RIGHTLEFT
+EXTERN long	p_aleph;	/* 'aleph' */
+#endif
+#ifdef FEAT_AUTOCHDIR
+EXTERN int	p_acd;		/* 'autochdir' */
+#endif
+#ifdef FEAT_MBYTE
+EXTERN char_u	*p_ambw;	/* 'ambiwidth' */
+#endif
+#if defined(FEAT_GUI) && defined(MACOS_X)
+EXTERN int	*p_antialias;	/* 'antialias' */
+#endif
+EXTERN int	p_ar;		/* 'autoread' */
+EXTERN int	p_aw;		/* 'autowrite' */
+EXTERN int	p_awa;		/* 'autowriteall' */
+EXTERN char_u	*p_bs;		/* 'backspace' */
+EXTERN char_u	*p_bg;		/* 'background' */
+EXTERN int	p_bk;		/* 'backup' */
+EXTERN char_u	*p_bkc;		/* 'backupcopy' */
+EXTERN unsigned	bkc_flags;
+#ifdef IN_OPTION_C
+static char *(p_bkc_values[]) = {"yes", "auto", "no", "breaksymlink", "breakhardlink", NULL};
+#endif
+# define BKC_YES		0x001
+# define BKC_AUTO		0x002
+# define BKC_NO			0x004
+# define BKC_BREAKSYMLINK	0x008
+# define BKC_BREAKHARDLINK	0x010
+EXTERN char_u	*p_bdir;	/* 'backupdir' */
+EXTERN char_u	*p_bex;		/* 'backupext' */
+#ifdef FEAT_WILDIGN
+EXTERN char_u	*p_bsk;		/* 'backupskip' */
+#endif
+#ifdef FEAT_BEVAL
+EXTERN long	p_bdlay;	/* 'balloondelay' */
+EXTERN int	p_beval;	/* 'ballooneval' */
+# ifdef FEAT_EVAL
+EXTERN char_u	*p_bexpr;
+# endif
+#endif
+#ifdef FEAT_BROWSE
+EXTERN char_u	*p_bsdir;	/* 'browsedir' */
+#endif
+#ifdef MSDOS
+EXTERN int	p_biosk;	/* 'bioskey' */
+EXTERN int	p_consk;	/* 'conskey' */
+#endif
+#ifdef FEAT_LINEBREAK
+EXTERN char_u	*p_breakat;	/* 'breakat' */
+#endif
+#ifdef FEAT_MBYTE
+EXTERN char_u	*p_cmp;		/* 'casemap' */
+EXTERN unsigned	cmp_flags;
+# ifdef IN_OPTION_C
+static char *(p_cmp_values[]) = {"internal", "keepascii", NULL};
+# endif
+# define CMP_INTERNAL		0x001
+# define CMP_KEEPASCII		0x002
+#endif
+#ifdef FEAT_MBYTE
+EXTERN char_u	*p_enc;		/* 'encoding' */
+EXTERN int	p_deco;		/* 'delcombine' */
+# ifdef FEAT_EVAL
+EXTERN char_u	*p_ccv;		/* 'charconvert' */
+# endif
+#endif
+#ifdef FEAT_CMDWIN
+EXTERN char_u	*p_cedit;	/* 'cedit' */
+EXTERN long	p_cwh;		/* 'cmdwinheight' */
+#endif
+#ifdef FEAT_CLIPBOARD
+EXTERN char_u	*p_cb;		/* 'clipboard' */
+#endif
+EXTERN long	p_ch;		/* 'cmdheight' */
+#if defined(FEAT_GUI_DIALOG) || defined(FEAT_CON_DIALOG)
+EXTERN int	p_confirm;	/* 'confirm' */
+#endif
+EXTERN int	p_cp;		/* 'compatible' */
+#ifdef FEAT_INS_EXPAND
+EXTERN char_u	*p_cot;		/* 'completeopt' */
+EXTERN long	p_ph;		/* 'pumheight' */
+#endif
+EXTERN char_u	*p_cpo;		/* 'cpoptions' */
+#ifdef FEAT_CSCOPE
+EXTERN char_u	*p_csprg;	/* 'cscopeprg' */
+# ifdef FEAT_QUICKFIX
+EXTERN char_u	*p_csqf;	/* 'cscopequickfix' */
+#  define	CSQF_CMDS   "sgdctefi"
+#  define	CSQF_FLAGS  "+-0"
+# endif
+EXTERN int	p_cst;		/* 'cscopetag' */
+EXTERN long	p_csto;		/* 'cscopetagorder' */
+EXTERN long	p_cspc;		/* 'cscopepathcomp' */
+EXTERN int	p_csverbose;	/* 'cscopeverbose' */
+#endif
+EXTERN char_u	*p_debug;	/* 'debug' */
+#ifdef FEAT_FIND_ID
+EXTERN char_u	*p_def;		/* 'define' */
+EXTERN char_u	*p_inc;
+#endif
+#ifdef FEAT_DIFF
+EXTERN char_u	*p_dip;		/* 'diffopt' */
+# ifdef FEAT_EVAL
+EXTERN char_u	*p_dex;		/* 'diffexpr' */
+# endif
+#endif
+#ifdef FEAT_INS_EXPAND
+EXTERN char_u	*p_dict;	/* 'dictionary' */
+#endif
+#ifdef FEAT_DIGRAPHS
+EXTERN int	p_dg;		/* 'digraph' */
+#endif
+EXTERN char_u	*p_dir;		/* 'directory' */
+EXTERN char_u	*p_dy;		/* 'display' */
+EXTERN unsigned	dy_flags;
+#ifdef IN_OPTION_C
+static char *(p_dy_values[]) = {"lastline", "uhex", NULL};
+#endif
+#define DY_LASTLINE		0x001
+#define DY_UHEX			0x002
+EXTERN int	p_ed;		/* 'edcompatible' */
+#ifdef FEAT_VERTSPLIT
+EXTERN char_u	*p_ead;		/* 'eadirection' */
+#endif
+EXTERN int	p_ea;		/* 'equalalways' */
+EXTERN char_u	*p_ep;		/* 'equalprg' */
+EXTERN int	p_eb;		/* 'errorbells' */
+#ifdef FEAT_QUICKFIX
+EXTERN char_u	*p_ef;		/* 'errorfile' */
+EXTERN char_u	*p_efm;		/* 'errorformat' */
+EXTERN char_u	*p_gefm;	/* 'grepformat' */
+EXTERN char_u	*p_gp;		/* 'grepprg' */
+#endif
+#ifdef FEAT_AUTOCMD
+EXTERN char_u	*p_ei;		/* 'eventignore' */
+#endif
+EXTERN int	p_ek;		/* 'esckeys' */
+EXTERN int	p_exrc;		/* 'exrc' */
+#ifdef FEAT_MBYTE
+EXTERN char_u	*p_fencs;	/* 'fileencodings' */
+#endif
+EXTERN char_u	*p_ffs;		/* 'fileformats' */
+#ifdef FEAT_FOLDING
+EXTERN char_u	*p_fcl;		/* 'foldclose' */
+EXTERN long	p_fdls;		/* 'foldlevelstart' */
+EXTERN char_u	*p_fdo;		/* 'foldopen' */
+EXTERN unsigned	fdo_flags;
+# ifdef IN_OPTION_C
+static char *(p_fdo_values[]) = {"all", "block", "hor", "mark", "percent",
+				 "quickfix", "search", "tag", "insert",
+				 "undo", "jump", NULL};
+# endif
+# define FDO_ALL		0x001
+# define FDO_BLOCK		0x002
+# define FDO_HOR		0x004
+# define FDO_MARK		0x008
+# define FDO_PERCENT		0x010
+# define FDO_QUICKFIX		0x020
+# define FDO_SEARCH		0x040
+# define FDO_TAG		0x080
+# define FDO_INSERT		0x100
+# define FDO_UNDO		0x200
+# define FDO_JUMP		0x400
+#endif
+EXTERN char_u	*p_fp;		/* 'formatprg' */
+#ifdef HAVE_FSYNC
+EXTERN int	p_fs;		/* 'fsync' */
+#endif
+EXTERN int	p_gd;		/* 'gdefault' */
+#ifdef FEAT_PRINTER
+EXTERN char_u	*p_pdev;	/* 'printdevice' */
+# ifdef FEAT_POSTSCRIPT
+EXTERN char_u	*p_penc;	/* 'printencoding' */
+EXTERN char_u	*p_pexpr;	/* 'printexpr' */
+#   ifdef FEAT_MBYTE
+EXTERN char_u	*p_pmfn;	/* 'printmbfont' */
+EXTERN char_u	*p_pmcs;	/* 'printmbcharset' */
+#   endif
+# endif
+EXTERN char_u	*p_pfn;		/* 'printfont' */
+EXTERN char_u	*p_popt;	/* 'printoptions' */
+EXTERN char_u	*p_header;	/* 'printheader' */
+#endif
+EXTERN int	p_prompt;	/* 'prompt' */
+#ifdef FEAT_GUI
+EXTERN char_u	*p_guifont;	/* 'guifont' */
+# ifdef FEAT_XFONTSET
+EXTERN char_u	*p_guifontset;	/* 'guifontset' */
+# endif
+# ifdef FEAT_MBYTE
+EXTERN char_u	*p_guifontwide;	/* 'guifontwide' */
+# endif
+EXTERN int	p_guipty;	/* 'guipty' */
+#endif
+#if defined(FEAT_GUI_GTK) || defined(FEAT_GUI_X11)
+EXTERN long	p_ghr;		/* 'guiheadroom' */
+#endif
+#ifdef CURSOR_SHAPE
+EXTERN char_u	*p_guicursor;	/* 'guicursor' */
+#endif
+#ifdef FEAT_MOUSESHAPE
+EXTERN char_u	*p_mouseshape;	/* 'mouseshape' */
+#endif
+#if defined(FEAT_GUI)
+EXTERN char_u	*p_go;		/* 'guioptions' */
+#endif
+#if defined(FEAT_GUI_TABLINE)
+EXTERN char_u	*p_gtl;		/* 'guitablabel' */
+EXTERN char_u	*p_gtt;		/* 'guitabtooltip' */
+#endif
+EXTERN char_u	*p_hf;		/* 'helpfile' */
+#ifdef FEAT_WINDOWS
+EXTERN long	p_hh;		/* 'helpheight' */
+#endif
+#ifdef FEAT_MULTI_LANG
+EXTERN char_u	*p_hlg;		/* 'helplang' */
+#endif
+EXTERN int	p_hid;		/* 'hidden' */
+/* Use P_HID to check if a buffer is to be hidden when it is no longer
+ * visible in a window. */
+#ifndef FEAT_QUICKFIX
+# define P_HID(dummy) (p_hid || cmdmod.hide)
+#else
+# define P_HID(buf) (buf_hide(buf))
+#endif
+EXTERN char_u	*p_hl;		/* 'highlight' */
+EXTERN int	p_hls;		/* 'hlsearch' */
+EXTERN long	p_hi;		/* 'history' */
+#ifdef FEAT_RIGHTLEFT
+EXTERN int	p_hkmap;	/* 'hkmap' */
+EXTERN int	p_hkmapp;	/* 'hkmapp' */
+# ifdef FEAT_FKMAP
+EXTERN int	p_fkmap;	/* 'fkmap' */
+EXTERN int	p_altkeymap;	/* 'altkeymap' */
+# endif
+# ifdef FEAT_ARABIC
+EXTERN int	p_arshape;	/* 'arabicshape' */
+# endif
+#endif
+#ifdef FEAT_TITLE
+EXTERN int	p_icon;		/* 'icon' */
+EXTERN char_u	*p_iconstring;	/* 'iconstring' */
+#endif
+EXTERN int	p_ic;		/* 'ignorecase' */
+#if defined(FEAT_XIM) && (defined(FEAT_GUI_GTK))
+EXTERN char_u	*p_imak;	/* 'imactivatekey' */
+#endif
+#ifdef USE_IM_CONTROL
+EXTERN int	p_imcmdline;	/* 'imcmdline' */
+EXTERN int	p_imdisable;	/* 'imdisable' */
+#endif
+EXTERN int	p_is;		/* 'incsearch' */
+EXTERN int	p_im;		/* 'insertmode' */
+EXTERN char_u	*p_isf;		/* 'isfname' */
+EXTERN char_u	*p_isi;		/* 'isident' */
+EXTERN char_u	*p_isp;		/* 'isprint' */
+EXTERN int	p_js;		/* 'joinspaces' */
+EXTERN char_u	*p_kp;		/* 'keywordprg' */
+#ifdef FEAT_VISUAL
+EXTERN char_u	*p_km;		/* 'keymodel' */
+#endif
+#ifdef FEAT_LANGMAP
+EXTERN char_u	*p_langmap;	/* 'langmap'*/
+#endif
+#if defined(FEAT_MENU) && defined(FEAT_MULTI_LANG)
+EXTERN char_u	*p_lm;		/* 'langmenu' */
+#endif
+#ifdef FEAT_GUI
+EXTERN long	p_linespace;	/* 'linespace' */
+#endif
+#ifdef FEAT_LISP
+EXTERN char_u	*p_lispwords;	/* 'lispwords' */
+#endif
+#ifdef FEAT_WINDOWS
+EXTERN long	p_ls;		/* 'laststatus' */
+EXTERN long	p_stal;		/* 'showtabline' */
+#endif
+EXTERN char_u	*p_lcs;		/* 'listchars' */
+
+EXTERN int	p_lz;		/* 'lazyredraw' */
+EXTERN int	p_lpl;		/* 'loadplugins' */
+#ifdef FEAT_GUI_MAC
+EXTERN int	p_macatsui;	/* 'macatsui' */
+#endif
+EXTERN int	p_magic;	/* 'magic' */
+#ifdef FEAT_QUICKFIX
+EXTERN char_u	*p_mef;		/* 'makeef' */
+EXTERN char_u	*p_mp;		/* 'makeprg' */
+#endif
+EXTERN long	p_mat;		/* 'matchtime' */
+#ifdef FEAT_MBYTE
+EXTERN long	p_mco;		/* 'maxcombine' */
+#endif
+#ifdef FEAT_EVAL
+EXTERN long	p_mfd;		/* 'maxfuncdepth' */
+#endif
+EXTERN long	p_mmd;		/* 'maxmapdepth' */
+EXTERN long	p_mm;		/* 'maxmem' */
+EXTERN long	p_mmp;		/* 'maxmempattern' */
+EXTERN long	p_mmt;		/* 'maxmemtot' */
+#ifdef FEAT_MENU
+EXTERN long	p_mis;		/* 'menuitems' */
+#endif
+#ifdef FEAT_SPELL
+EXTERN char_u	*p_msm;		/* 'mkspellmem' */
+#endif
+EXTERN long	p_mls;		/* 'modelines' */
+EXTERN char_u	*p_mouse;	/* 'mouse' */
+#ifdef FEAT_GUI
+EXTERN int	p_mousef;	/* 'mousefocus' */
+EXTERN int	p_mh;		/* 'mousehide' */
+#endif
+EXTERN char_u	*p_mousem;	/* 'mousemodel' */
+EXTERN long	p_mouset;	/* 'mousetime' */
+EXTERN int	p_more;		/* 'more' */
+#ifdef FEAT_MZSCHEME
+EXTERN long	p_mzq;		/* 'mzquantum */
+#endif
+#if defined(MSDOS) || defined(MSWIN) || defined(OS2)
+EXTERN int	p_odev;		/* 'opendevice' */
+#endif
+EXTERN char_u	*p_opfunc;	/* 'operatorfunc' */
+EXTERN char_u	*p_para;	/* 'paragraphs' */
+EXTERN int	p_paste;	/* 'paste' */
+EXTERN char_u	*p_pt;		/* 'pastetoggle' */
+#if defined(FEAT_EVAL) && defined(FEAT_DIFF)
+EXTERN char_u	*p_pex;		/* 'patchexpr' */
+#endif
+EXTERN char_u	*p_pm;		/* 'patchmode' */
+EXTERN char_u	*p_path;	/* 'path' */
+#ifdef FEAT_SEARCHPATH
+EXTERN char_u	*p_cdpath;	/* 'cdpath' */
+#endif
+EXTERN int	p_remap;	/* 'remap' */
+EXTERN long	p_report;	/* 'report' */
+#if defined(FEAT_WINDOWS) && defined(FEAT_QUICKFIX)
+EXTERN long	p_pvh;		/* 'previewheight' */
+#endif
+#ifdef WIN3264
+EXTERN int	p_rs;		/* 'restorescreen' */
+#endif
+#ifdef FEAT_RIGHTLEFT
+EXTERN int	p_ari;		/* 'allowrevins' */
+EXTERN int	p_ri;		/* 'revins' */
+#endif
+#ifdef FEAT_CMDL_INFO
+EXTERN int	p_ru;		/* 'ruler' */
+#endif
+#ifdef FEAT_STL_OPT
+EXTERN char_u	*p_ruf;		/* 'rulerformat' */
+#endif
+EXTERN char_u	*p_rtp;		/* 'runtimepath' */
+EXTERN long	p_sj;		/* 'scrolljump' */
+EXTERN long	p_so;		/* 'scrolloff' */
+#ifdef FEAT_SCROLLBIND
+EXTERN char_u	*p_sbo;		/* 'scrollopt' */
+#endif
+EXTERN char_u	*p_sections;	/* 'sections' */
+EXTERN int	p_secure;	/* 'secure' */
+#ifdef FEAT_VISUAL
+EXTERN char_u	*p_sel;		/* 'selection' */
+EXTERN char_u	*p_slm;		/* 'selectmode' */
+#endif
+#ifdef FEAT_SESSION
+EXTERN char_u	*p_ssop;	/* 'sessionoptions' */
+EXTERN unsigned	ssop_flags;
+# ifdef IN_OPTION_C
+/* Also used for 'viewoptions'! */
+static char *(p_ssop_values[]) = {"buffers", "winpos", "resize", "winsize",
+    "localoptions", "options", "help", "blank", "globals", "slash", "unix",
+    "sesdir", "curdir", "folds", "cursor", "tabpages", NULL};
+# endif
+# define SSOP_BUFFERS		0x001
+# define SSOP_WINPOS		0x002
+# define SSOP_RESIZE		0x004
+# define SSOP_WINSIZE		0x008
+# define SSOP_LOCALOPTIONS	0x010
+# define SSOP_OPTIONS		0x020
+# define SSOP_HELP		0x040
+# define SSOP_BLANK		0x080
+# define SSOP_GLOBALS		0x100
+# define SSOP_SLASH		0x200
+# define SSOP_UNIX		0x400
+# define SSOP_SESDIR		0x800
+# define SSOP_CURDIR		0x1000
+# define SSOP_FOLDS		0x2000
+# define SSOP_CURSOR		0x4000
+# define SSOP_TABPAGES		0x8000
+#endif
+EXTERN char_u	*p_sh;		/* 'shell' */
+EXTERN char_u	*p_shcf;	/* 'shellcmdflag' */
+#ifdef FEAT_QUICKFIX
+EXTERN char_u	*p_sp;		/* 'shellpipe' */
+#endif
+EXTERN char_u	*p_shq;		/* 'shellquote' */
+EXTERN char_u	*p_sxq;		/* 'shellxquote' */
+EXTERN char_u	*p_srr;		/* 'shellredir' */
+#ifdef AMIGA
+EXTERN long	p_st;		/* 'shelltype' */
+#endif
+EXTERN int	p_stmp;		/* 'shelltemp' */
+#ifdef BACKSLASH_IN_FILENAME
+EXTERN int	p_ssl;		/* 'shellslash' */
+#endif
+#ifdef FEAT_STL_OPT
+EXTERN char_u	*p_stl;		/* 'statusline' */
+#endif
+EXTERN int	p_sr;		/* 'shiftround' */
+EXTERN char_u	*p_shm;		/* 'shortmess' */
+#ifdef FEAT_LINEBREAK
+EXTERN char_u	*p_sbr;		/* 'showbreak' */
+#endif
+#ifdef FEAT_CMDL_INFO
+EXTERN int	p_sc;		/* 'showcmd' */
+#endif
+EXTERN int	p_sft;		/* 'showfulltag' */
+EXTERN int	p_sm;		/* 'showmatch' */
+EXTERN int	p_smd;		/* 'showmode' */
+EXTERN long	p_ss;		/* 'sidescroll' */
+EXTERN long	p_siso;		/* 'sidescrolloff' */
+EXTERN int	p_scs;		/* 'smartcase' */
+EXTERN int	p_sta;		/* 'smarttab' */
+#ifdef FEAT_WINDOWS
+EXTERN int	p_sb;		/* 'splitbelow' */
+EXTERN long	p_tpm;		/* 'tabpagemax' */
+# if defined(FEAT_STL_OPT)
+EXTERN char_u	*p_tal;		/* 'tabline' */
+# endif
+#endif
+#ifdef FEAT_SPELL
+EXTERN char_u	*p_sps;		/* 'spellsuggest' */
+#endif
+#ifdef FEAT_VERTSPLIT
+EXTERN int	p_spr;		/* 'splitright' */
+#endif
+EXTERN int	p_sol;		/* 'startofline' */
+EXTERN char_u	*p_su;		/* 'suffixes' */
+EXTERN char_u	*p_sws;		/* 'swapsync' */
+EXTERN char_u	*p_swb;		/* 'switchbuf' */
+EXTERN int	p_tbs;		/* 'tagbsearch' */
+EXTERN long	p_tl;		/* 'taglength' */
+EXTERN int	p_tr;		/* 'tagrelative' */
+EXTERN char_u	*p_tags;	/* 'tags' */
+EXTERN int	p_tgst;		/* 'tagstack' */
+#ifdef FEAT_ARABIC
+EXTERN int	p_tbidi;	/* 'termbidi' */
+#endif
+#ifdef FEAT_MBYTE
+EXTERN char_u	*p_tenc;	/* 'termencoding' */
+#endif
+EXTERN int	p_terse;	/* 'terse' */
+EXTERN int	p_ta;		/* 'textauto' */
+EXTERN int	p_to;		/* 'tildeop' */
+EXTERN int	p_timeout;	/* 'timeout' */
+EXTERN long	p_tm;		/* 'timeoutlen' */
+#ifdef FEAT_TITLE
+EXTERN int	p_title;	/* 'title' */
+EXTERN long	p_titlelen;	/* 'titlelen' */
+EXTERN char_u	*p_titleold;	/* 'titleold' */
+EXTERN char_u	*p_titlestring;	/* 'titlestring' */
+#endif
+#ifdef FEAT_INS_EXPAND
+EXTERN char_u	*p_tsr;		/* 'thesaurus' */
+#endif
+EXTERN int	p_ttimeout;	/* 'ttimeout' */
+EXTERN long	p_ttm;		/* 'ttimeoutlen' */
+EXTERN int	p_tbi;		/* 'ttybuiltin' */
+EXTERN int	p_tf;		/* 'ttyfast' */
+#if defined(FEAT_TOOLBAR) && !defined(FEAT_GUI_W32)
+EXTERN char_u	*p_toolbar;	/* 'toolbar' */
+EXTERN unsigned toolbar_flags;
+# ifdef IN_OPTION_C
+static char *(p_toolbar_values[]) = {"text", "icons", "tooltips", "horiz", NULL};
+# endif
+# define TOOLBAR_TEXT		0x01
+# define TOOLBAR_ICONS		0x02
+# define TOOLBAR_TOOLTIPS	0x04
+# define TOOLBAR_HORIZ		0x08
+#endif
+#if defined(FEAT_TOOLBAR) && defined(FEAT_GUI_GTK) && defined(HAVE_GTK2)
+EXTERN char_u	*p_tbis;	/* 'toolbariconsize' */
+EXTERN unsigned tbis_flags;
+# ifdef IN_OPTION_C
+static char *(p_tbis_values[]) = {"tiny", "small", "medium", "large", NULL};
+# endif
+# define TBIS_TINY		0x01
+# define TBIS_SMALL		0x02
+# define TBIS_MEDIUM		0x04
+# define TBIS_LARGE		0x08
+#endif
+EXTERN long	p_ttyscroll;	/* 'ttyscroll' */
+#if defined(FEAT_MOUSE) && (defined(UNIX) || defined(VMS))
+EXTERN char_u	*p_ttym;	/* 'ttymouse' */
+EXTERN unsigned ttym_flags;
+# ifdef IN_OPTION_C
+static char *(p_ttym_values[]) = {"xterm", "xterm2", "dec", "netterm", "jsbterm", "pterm", NULL};
+# endif
+# define TTYM_XTERM		0x01
+# define TTYM_XTERM2		0x02
+# define TTYM_DEC		0x04
+# define TTYM_NETTERM		0x08
+# define TTYM_JSBTERM		0x10
+# define TTYM_PTERM		0x20
+#endif
+EXTERN long	p_ul;		/* 'undolevels' */
+EXTERN long	p_uc;		/* 'updatecount' */
+EXTERN long	p_ut;		/* 'updatetime' */
+#if defined(FEAT_WINDOWS) || defined(FEAT_FOLDING)
+EXTERN char_u	*p_fcs;		/* 'fillchar' */
+#endif
+#ifdef FEAT_VIMINFO
+EXTERN char_u	*p_viminfo;	/* 'viminfo' */
+#endif
+#ifdef FEAT_SESSION
+EXTERN char_u	*p_vdir;	/* 'viewdir' */
+EXTERN char_u	*p_vop;		/* 'viewoptions' */
+EXTERN unsigned	vop_flags;	/* uses SSOP_ flags */
+#endif
+EXTERN int	p_vb;		/* 'visualbell' */
+#ifdef FEAT_VIRTUALEDIT
+EXTERN char_u	*p_ve;		/* 'virtualedit' */
+EXTERN unsigned ve_flags;
+# ifdef IN_OPTION_C
+static char *(p_ve_values[]) = {"block", "insert", "all", "onemore", NULL};
+# endif
+# define VE_BLOCK	5	/* includes "all" */
+# define VE_INSERT	6	/* includes "all" */
+# define VE_ALL		4
+# define VE_ONEMORE	8
+#endif
+EXTERN long	p_verbose;	/* 'verbose' */
+EXTERN char_u	*p_vfile;	/* 'verbosefile' */
+EXTERN int	p_warn;		/* 'warn' */
+#ifdef FEAT_CMDL_COMPL
+EXTERN char_u	*p_wop;		/* 'wildoptions' */
+#endif
+EXTERN long	p_window;	/* 'window' */
+#if defined(FEAT_GUI_MSWIN) || defined(FEAT_GUI_MOTIF) || defined(LINT) \
+	|| defined (FEAT_GUI_GTK) || defined(FEAT_GUI_PHOTON)
+#define FEAT_WAK
+EXTERN char_u	*p_wak;		/* 'winaltkeys' */
+#endif
+#ifdef FEAT_WILDIGN
+EXTERN char_u	*p_wig;		/* 'wildignore' */
+#endif
+EXTERN int	p_wiv;		/* 'weirdinvert' */
+EXTERN char_u	*p_ww;		/* 'whichwrap' */
+EXTERN long	p_wc;		/* 'wildchar' */
+EXTERN long	p_wcm;		/* 'wildcharm' */
+EXTERN char_u	*p_wim;		/* 'wildmode' */
+#ifdef FEAT_WILDMENU
+EXTERN int	p_wmnu;		/* 'wildmenu' */
+#endif
+#ifdef FEAT_WINDOWS
+EXTERN long	p_wh;		/* 'winheight' */
+EXTERN long	p_wmh;		/* 'winminheight' */
+#endif
+#ifdef FEAT_VERTSPLIT
+EXTERN long	p_wmw;		/* 'winminwidth' */
+EXTERN long	p_wiw;		/* 'winwidth' */
+#endif
+EXTERN int	p_ws;		/* 'wrapscan' */
+EXTERN int	p_write;	/* 'write' */
+EXTERN int	p_wa;		/* 'writeany' */
+EXTERN int	p_wb;		/* 'writebackup' */
+EXTERN long	p_wd;		/* 'writedelay' */
+
+/*
+ * "indir" values for buffer-local opions.
+ * These need to be defined globally, so that the BV_COUNT can be used with
+ * b_p_scriptID[].
+ */
+enum
+{
+    BV_AI = 0
+    , BV_AR
+#ifdef FEAT_QUICKFIX
+    , BV_BH
+    , BV_BT
+    , BV_EFM
+    , BV_GP
+    , BV_MP
+#endif
+    , BV_BIN
+    , BV_BL
+#ifdef FEAT_MBYTE
+    , BV_BOMB
+#endif
+    , BV_CI
+#ifdef FEAT_CINDENT
+    , BV_CIN
+    , BV_CINK
+    , BV_CINO
+#endif
+#if defined(FEAT_SMARTINDENT) || defined(FEAT_CINDENT)
+    , BV_CINW
+#endif
+#ifdef FEAT_FOLDING
+    , BV_CMS
+#endif
+#ifdef FEAT_COMMENTS
+    , BV_COM
+#endif
+#ifdef FEAT_INS_EXPAND
+    , BV_CPT
+    , BV_DICT
+    , BV_TSR
+#endif
+#ifdef FEAT_COMPL_FUNC
+    , BV_CFU
+#endif
+#ifdef FEAT_FIND_ID
+    , BV_DEF
+    , BV_INC
+#endif
+    , BV_EOL
+    , BV_EP
+    , BV_ET
+    , BV_FENC
+#ifdef FEAT_EVAL
+    , BV_BEXPR
+    , BV_FEX
+#endif
+    , BV_FF
+    , BV_FLP
+    , BV_FO
+#ifdef FEAT_AUTOCMD
+    , BV_FT
+#endif
+    , BV_IMI
+    , BV_IMS
+#if defined(FEAT_CINDENT) && defined(FEAT_EVAL)
+    , BV_INDE
+    , BV_INDK
+#endif
+#if defined(FEAT_FIND_ID) && defined(FEAT_EVAL)
+    , BV_INEX
+#endif
+    , BV_INF
+    , BV_ISK
+#ifdef FEAT_CRYPT
+    , BV_KEY
+#endif
+#ifdef FEAT_KEYMAP
+    , BV_KMAP
+#endif
+    , BV_KP
+#ifdef FEAT_LISP
+    , BV_LISP
+#endif
+    , BV_MA
+    , BV_ML
+    , BV_MOD
+    , BV_MPS
+    , BV_NF
+#ifdef FEAT_OSFILETYPE
+    , BV_OFT
+#endif
+#ifdef FEAT_COMPL_FUNC
+    , BV_OFU
+#endif
+    , BV_PATH
+    , BV_PI
+#ifdef FEAT_TEXTOBJ
+    , BV_QE
+#endif
+    , BV_RO
+#ifdef FEAT_SMARTINDENT
+    , BV_SI
+#endif
+#ifndef SHORT_FNAME
+    , BV_SN
+#endif
+#ifdef FEAT_SYN_HL
+    , BV_SMC
+    , BV_SYN
+#endif
+#ifdef FEAT_SPELL
+    , BV_SPC
+    , BV_SPF
+    , BV_SPL
+#endif
+    , BV_STS
+#ifdef FEAT_SEARCHPATH
+    , BV_SUA
+#endif
+    , BV_SW
+    , BV_SWF
+    , BV_TAGS
+    , BV_TS
+    , BV_TW
+    , BV_TX
+    , BV_WM
+    , BV_COUNT	    /* must be the last one */
+};
+
+/*
+ * "indir" values for window-local options.
+ * These need to be defined globally, so that the WV_COUNT can be used in the
+ * window structure.
+ */
+enum
+{
+    WV_LIST = 0
+#ifdef FEAT_ARABIC
+    , WV_ARAB
+#endif
+#ifdef FEAT_DIFF
+    , WV_DIFF
+#endif
+#ifdef FEAT_FOLDING
+    , WV_FDC
+    , WV_FEN
+    , WV_FDI
+    , WV_FDL
+    , WV_FDM
+    , WV_FML
+    , WV_FDN
+# ifdef FEAT_EVAL
+    , WV_FDE
+    , WV_FDT
+# endif
+    , WV_FMR
+#endif
+#ifdef FEAT_LINEBREAK
+    , WV_LBR
+#endif
+    , WV_NU
+#ifdef FEAT_LINEBREAK
+    , WV_NUW
+#endif
+#if defined(FEAT_WINDOWS) && defined(FEAT_QUICKFIX)
+    , WV_PVW
+#endif
+#ifdef FEAT_RIGHTLEFT
+    , WV_RL
+    , WV_RLC
+#endif
+#ifdef FEAT_SCROLLBIND
+    , WV_SCBIND
+#endif
+    , WV_SCROLL
+#ifdef FEAT_SPELL
+    , WV_SPELL
+#endif
+#ifdef FEAT_SYN_HL
+    , WV_CUC
+    , WV_CUL
+#endif
+#ifdef FEAT_STL_OPT
+    , WV_STL
+#endif
+#ifdef FEAT_WINDOWS
+    , WV_WFH
+#endif
+#ifdef FEAT_VERTSPLIT
+    , WV_WFW
+#endif
+    , WV_WRAP
+    , WV_COUNT	    /* must be the last one */
+};
--- /dev/null
+++ b/os_plan9.c
@@ -1,0 +1,1134 @@
+/* vi:set ts=8 sts=4 sw=4:
+ *
+ * VIM - Vi IMproved	by Bram Moolenaar
+ *
+ * Do ":help uganda"  in Vim to read copying and usage conditions.
+ * Do ":help credits" in Vim to see a list of people who contributed.
+ * See README.txt for an overview of the Vim source code.
+ */
+
+/*
+ * os_plan9.c
+ *
+ * Plan 9 system-dependent routines.
+ */
+
+#include <signal.h>
+#include <setjmp.h>
+#include <fcntl.h>
+#include <lib9.h>
+#include <draw.h>
+#include <keyboard.h>
+#include <event.h>
+#include "vim.h"
+
+/* Vim defines Display.  We need it for libdraw. */
+#undef Display
+
+/* We need to access the native Plan 9 alarm() since
+ * it takes milliseconds rather than seconds. */
+extern int _ALARM(unsigned long);
+
+enum {
+    /* Text modes are in sync with term.c */
+    TMODE_NORMAL  = 0,
+    TMODE_REVERSE = 1,
+    TMODE_BOLD    = 2,
+
+    NCOLORS       = 16
+};
+
+static int scr_inited;
+static Point fontsize;
+static Point shellsize;
+static Rectangle scrollregion;
+static int currow; /* TODO use a Point */
+static int curcol;
+static Image *cursorsave;
+static Image *colortab[NCOLORS];
+static Image *fgcolor;
+static Image *bgcolor;
+static Font *normalfont;
+static Font *boldfont;
+static Font *curfont;
+static int curmode; /* TODO remove this, use cterm_normal_fg_color instead for comparing */
+
+/* Timeouts are handled using alarm() and a signal handler.
+ * When an alarm happens during a syscall, the syscall is
+ * interrupted.  We use setjmp() to handle control flow from
+ * interrupted library functions. */
+static int interruptable;
+static jmp_buf timeoutjmpbuf;
+
+static void err9(char *msg) {
+    char errs[256];
+    /* TODO */
+    errstr(errs, sizeof errs);
+    fprintf(stderr, "%s: %s\n", msg, errs);
+    exit(1);
+}
+
+/* Error handler for libdraw */
+static void derr(Display*, char *msg) {
+    if (interruptable && strcmp(msg, "eof on event pipe") == 0) {
+        longjmp(timeoutjmpbuf, 1);
+    }
+    err9(msg);
+}
+
+int mch_has_wildcard(char_u *p) {
+    for (; *p; mb_ptr_adv(p)) {
+        if (*p == '\\' && p[1] != NUL) {
+            ++p;
+        } else if (vim_strchr((char_u *)"*?[{`'$", *p) != NULL ||
+                (*p == '~' && p[1] != NUL)) {
+            return TRUE;
+        }
+    }
+    return FALSE;
+}
+
+int mch_has_exp_wildcard(char_u *p) {
+    for (; *p; mb_ptr_adv(p))
+    {
+        if (*p == '\\' && p[1] != NUL)
+            ++p;
+        else
+            if (vim_strchr((char_u *) "*?[{'", *p) != NULL)
+                return TRUE;
+    }
+    return FALSE;
+}
+
+int mch_expandpath(garray_T *gap, char_u *pat, int flags) {
+    return unix_expandpath(gap, pat, 0, flags, FALSE);
+}
+
+int mch_isdir(char_u *name) {
+    struct stat st;
+    if (stat((char*)name, &st) != 0) {
+        return FALSE;
+    }
+    return S_ISDIR(st.st_mode) ? TRUE : FALSE;
+}
+
+static int executable_file(char_u *name)
+{
+    struct stat	st;
+
+    if (stat((char *)name, &st))
+        return 0;
+    return S_ISREG(st.st_mode) && mch_access((char *)name, X_OK) == 0;
+}
+
+int mch_isFullName(char_u *fname) {
+    return fname[0] == '/' || fname[0] == '#';
+}
+
+int mch_can_exe(char_u *name) {
+    char_u	*buf;
+    char_u	*p, *e;
+    int		retval;
+
+    /* If it's an absolute or relative path don't need to use $path. */
+    if (mch_isFullName(name) || (name[0] == '.' && (name[1] == '/'
+				      || (name[1] == '.' && name[2] == '/'))))
+        return executable_file(name);
+
+    p = (char_u *)getenv("path");
+    if (p == NULL || *p == NUL)
+        return -1;
+    buf = alloc((unsigned)(STRLEN(name) + STRLEN(p) + 2));
+    if (buf == NULL)
+        return -1;
+
+    /*
+     * Walk through all entries in $PATH to check if "name" exists there and
+     * is an executable file.
+     */
+    for (;;)
+    {
+        e = (char_u *)strchr((char *)p, '\01');
+        if (e == NULL)
+            e = p + STRLEN(p);
+        if (e - p <= 1)		/* empty entry means current dir */
+            STRCPY(buf, "./");
+        else
+        {
+            vim_strncpy(buf, p, e - p);
+            add_pathsep(buf);
+        }
+        STRCAT(buf, name);
+        retval = executable_file(buf);
+        if (retval == 1)
+            break;
+
+        if (*e != '\01')
+            break;
+        p = e + 1;
+    }
+
+    vim_free(buf);
+    return retval;
+}
+
+int mch_dirname(char_u *buf, int len) {
+    return (getcwd((char*)buf, len) ? OK : FAIL);
+}
+
+long mch_getperm(char_u *name) {
+    struct stat st;
+    if (stat((char*)name, &st) < 0) {
+        return -1;
+    }
+    return st.st_mode;
+}
+
+int mch_setperm(char_u *name, long perm) {
+    return chmod((char*)name, (mode_t)perm) == 0 ? OK : FAIL;
+}
+
+int mch_remove(char_u *name) {
+    return remove((char*)name);
+}
+
+void mch_hide(char_u*) {
+    /* Do nothing */
+}
+
+/* getuser() and sysname() can be implemented using this. */
+static int read_value_from_file(char *fname, char_u *s, int len) {
+    int fd;
+    int n;
+    fd = open(fname, O_RDONLY);
+    if (fd < 0) {
+        vim_strncpy(s, (char_u*)"none", len - 1);
+        return FAIL;
+    }
+    n = read(fd, s, len - 1);
+    if (n <= 0) {
+        vim_strncpy(s, (char_u*)"none", len - 1);
+    } else {
+        s[n] = '\0';
+    }
+    close(fd);
+    return (n > 0) ? OK : FAIL;
+}
+
+int mch_get_user_name(char_u *s, int len) {
+    return read_value_from_file("/dev/user", s, len);
+}
+
+void mch_get_host_name(char_u *s, int len) {
+    read_value_from_file("/dev/sysname", s, len);
+}
+
+void mch_settmode(int) {
+    /* Do nothing */
+}
+
+int mch_screenmode(char_u*) {
+    /* Always fail */
+    EMSG(_(e_screenmode));
+    return FAIL;
+}
+
+static void scr_stamp_cursor(void) {
+    if (cursorsave) {
+        draw(cursorsave, Rect(0, 0, fontsize.x, fontsize.y),
+                screen, nil, Pt(screen->clipr.min.x + curcol * fontsize.x,
+                    screen->clipr.min.y + currow * fontsize.y));
+        border(screen, Rect(screen->clipr.min.x + curcol * fontsize.x,
+                    screen->clipr.min.y + currow * fontsize.y,
+                    screen->clipr.min.x + (curcol + 1) * fontsize.x,
+                    screen->clipr.min.y + (currow + 1) * fontsize.y),
+                2, colortab[cterm_normal_fg_color - 1], ZP);
+    }
+}
+
+static void scr_unstamp_cursor(void) {
+    if (cursorsave) {
+        Rectangle r;
+        r = Rect(screen->clipr.min.x + curcol * fontsize.x,
+                screen->clipr.min.y + currow * fontsize.y,
+                screen->clipr.min.x + (curcol + 1) * fontsize.x,
+                screen->clipr.min.y + (currow + 1) * fontsize.y);
+        draw(screen, r, cursorsave, nil, ZP);
+    }
+}
+
+static void scr_pos(int row, int col) {
+    currow = row;
+    curcol = col;
+}
+
+static void scr_clear(void) {
+    scr_pos(0, 0);
+    draw(screen, screen->clipr, bgcolor, nil, ZP);
+    draw(cursorsave, Rect(0, 0, fontsize.x, fontsize.y), bgcolor, nil, ZP);
+}
+
+static void scr_scroll_down(int nlines) {
+    Rectangle r;
+    Point pt;
+
+    /* Copy up visible part of scroll region */
+    r = Rect(screen->clipr.min.x + scrollregion.min.x * fontsize.x,
+            screen->clipr.min.y + scrollregion.min.y * fontsize.y,
+            screen->clipr.min.x + scrollregion.max.x * fontsize.x,
+            screen->clipr.min.y + (scrollregion.max.y - nlines) * fontsize.y);
+    pt = Pt(screen->clipr.min.x + scrollregion.min.x * fontsize.x,
+            screen->clipr.min.y + (scrollregion.min.y + nlines) * fontsize.y);
+    draw(screen, r, screen, nil, pt);
+
+    /* Clear newly exposed part of scroll region */
+    r.min.y = r.max.y;
+    r.max.y = screen->clipr.min.y + scrollregion.max.y * fontsize.y;
+    draw(screen, r, bgcolor, nil, ZP);
+}
+
+static void scr_scroll_up(int nlines) {
+    Rectangle r;
+    Point pt;
+
+    /* Copy down visible part of scroll region */
+    r = Rect(screen->clipr.min.x + scrollregion.min.x * fontsize.x,
+            screen->clipr.min.y + (scrollregion.min.y + nlines) * fontsize.y,
+            screen->clipr.min.x + scrollregion.max.x * fontsize.x,
+            screen->clipr.min.y + scrollregion.max.y * fontsize.y);
+    pt = Pt(screen->clipr.min.x + scrollregion.min.x * fontsize.x,
+            screen->clipr.min.y + scrollregion.min.y * fontsize.y);
+    draw(screen, r, screen, nil, pt);
+
+    /* Clear newly exposed part of scroll region */
+    r.max.y = r.min.y;
+    r.min.y = screen->clipr.min.y + scrollregion.min.y * fontsize.y;
+    draw(screen, r, bgcolor, nil, ZP);
+}
+
+static void scr_set_color(Image **cp, int c) {
+    if (c >= 0 && c < NCOLORS) {
+        *cp = colortab[c];
+    }
+}
+
+void mch_set_normal_colors(void) {
+    char_u	*p;
+    int		n;
+
+    if (cterm_normal_fg_color == 0) {
+	cterm_normal_fg_color = 1;
+    }
+    if (cterm_normal_bg_color == 0) {
+	cterm_normal_bg_color = 16;
+    }
+    if (T_ME[0] == ESC && T_ME[1] == '|')
+    {
+	p = T_ME + 2;
+	n = getdigits(&p);
+	if (*p == 'm' && n > 0)
+	{
+	    cterm_normal_fg_color = (n & 0xf) + 1;
+	    cterm_normal_bg_color = ((n >> 4) & 0xf) + 1;
+	}
+    }
+
+    scr_set_color(&bgcolor, cterm_normal_bg_color - 1);
+    scr_set_color(&fgcolor, cterm_normal_fg_color - 1);
+}
+
+static void scr_tmode(int mode) {
+    Image *tmp;
+    if ((curmode & TMODE_REVERSE) != (mode & TMODE_REVERSE)) {
+        tmp = fgcolor;
+        fgcolor = bgcolor;
+        bgcolor = tmp;
+    }
+    if (mode & TMODE_BOLD) {
+        curfont = boldfont;
+    } else {
+        curfont = normalfont;
+    }
+    if (mode == TMODE_NORMAL) {
+	scr_set_color(&bgcolor, cterm_normal_bg_color - 1);
+	scr_set_color(&fgcolor, cterm_normal_fg_color - 1);
+    }
+    curmode = mode;
+}
+
+/* Read a number and return bytes consumed. */
+static int scr_escape_number(char *p, int len, int *n) {
+    int num;
+    int chlen;
+    if (len == 0) {
+        return -1;
+    }
+    num = 0;
+    chlen = 0;
+    while (len && isdigit(*p)) {
+        num = num * 10 + (*p - '0');
+        p++;
+        len--;
+        chlen++;
+    }
+    *n = num;
+    return chlen;
+}
+
+/* Handle escape sequence and return number of bytes consumed. */
+static int scr_escape_sequence(char *p, int len) {
+    int nlines;
+    int n1;
+    int n2;
+    int i;
+    int chlen;
+
+    if (len == 0) {
+        return 0;
+    }
+
+    chlen = 1;
+    switch (*p) {
+        case 'J': /* clear screen */
+            scr_clear();
+            break;
+
+        case '0': case '1': case '2': case '3': case '4':
+        case '5': case '6': case '7': case '8': case '9':
+            n1 = -1;
+            n2 = -1;
+
+            /* First number */
+            i = scr_escape_number(p, len, &n1);
+            if (i == -1) {
+                /* TODO */
+                fprintf(stderr, "scr_escape_sequence: escape at end of string\n");
+                exit(1);
+            }
+            p += i;
+            len -= i;
+            chlen += i;
+
+            /* Optional second number */
+            if (len && *p == ';') {
+                p += 1;
+                len -= 1;
+                chlen += 1;
+                i = scr_escape_number(p, len, &n2);
+                if (i == -1) {
+                    /* TODO */
+                    fprintf(stderr, "scr_escape_sequence: missing second number\n");
+                    exit(1);
+                }
+                p += i;
+                len -= i;
+                chlen += i;
+            }
+
+            if (len == 0) {
+                /* TODO */
+                fprintf(stderr, "scr_escape_sequence: early end of escape sequence\n");
+                exit(1);
+            }
+
+            switch (*p) {
+                case 'b': /* background color */
+                    scr_set_color(&bgcolor, n1);
+                    break;
+
+                case 'f': /* foreground color */
+                    scr_set_color(&fgcolor, n1);
+                    break;
+
+                case 'H': /* cursor motion */
+                    scr_pos(n1, n2);
+                    break;
+
+                case 'm': /* mode */
+                    scr_tmode(n1);
+                    break;
+
+                case 'R': /* scroll region */
+                    scrollregion.min.y = n1;
+                    scrollregion.max.y = n2 + 1;
+                    break;
+
+                case 'V': /* scroll region vertical */
+                    scrollregion.min.x = n1;
+                    scrollregion.max.x = n2 + 1;
+                    break;
+
+                default:
+                    /* TODO */
+                    fprintf(stderr, "scr_escape_sequence: unimplemented (p=%c)\n", *p);
+                    exit(1);
+            }
+            break;
+
+        case 'K': /* clear to end of line */
+            draw(screen, Rect(screen->clipr.min.x + curcol * fontsize.x,
+                        screen->clipr.min.y + currow * fontsize.y,
+                        screen->clipr.max.x,
+                        screen->clipr.min.y + (currow + 1) * fontsize.y),
+                    bgcolor, nil, ZP);
+            break;
+
+        case 'L': /* add new blank line */
+            p++;
+            nlines = 1;
+            while (len >= 3 && p[0] == '\x1b' && p[1] == '[' && p[2] == 'L') {
+                nlines++;
+                len -= 3;
+                p += 3;
+                chlen += 3;
+            }
+            /* TODO what if nlines >= scroll region size */
+            scr_scroll_up(nlines);
+            break;
+
+        default:
+            /* TODO */
+            fprintf(stderr, "scr_escape_sequence: unhandled sequence (p=%c)\n", *p);
+            exit(1);
+    }
+
+    return chlen;
+}
+
+/* Handle special characters. */
+static int write_special(char *p, int len) {
+    int n;
+    int nbytes;
+    if (len == 0) {
+        return 0;
+    }
+    nbytes = 0;
+    while (len > 0) {
+        switch (*p) {
+            case '\a': /* Bell */
+                /* There is no bell on Plan 9. */
+                break;
+
+            case '\b': /* Backspace */
+                if (curcol > scrollregion.min.x) {
+                    scr_pos(currow, curcol - 1);
+                } else if (currow > scrollregion.min.y) {
+                    scr_pos(currow - 1, scrollregion.max.x - 1);
+                }
+                break;
+
+            case '\n': /* New line */
+                for (n = 0; n < len && *p == '\n'; n++) {
+                    p++;
+                }
+                if (currow + n >= scrollregion.max.y) {
+                    scr_scroll_down(currow + n - scrollregion.max.y + 1);
+                    scr_pos(scrollregion.max.y - 1, scrollregion.min.x);
+                } else {
+                    scr_pos(currow + n, scrollregion.min.x);
+                }
+                len -= n;
+                nbytes += n;
+                continue; /* process next character */
+
+            case '\r': /* Carriage return */
+                curcol = scrollregion.min.x;
+                break;
+
+            case '\x1b': /* Escape sequences */
+                if (len > 1 && p[1] == '[') {
+                    n = 2;
+                    n += scr_escape_sequence(p + 2, len - 2);
+                    p += n;
+                    len -= n;
+                    nbytes += n;
+                    continue; /* process next character */
+                }
+                break;
+
+            default: /* Normal character */
+                return nbytes;
+        }
+        p++;
+        len--;
+        nbytes++;
+    }
+    return nbytes;
+}
+
+/* Draw normal characters. */
+static int write_str(char *p, int len) {
+    int nbytes;
+    int n;
+    int m;
+    if (len == 0) {
+        return 0;
+    }
+    for (nbytes = 0; nbytes < len &&
+            p[nbytes] != '\a' && p[nbytes] != '\b' &&
+            p[nbytes] != '\n' && p[nbytes] != '\r' &&
+            p[nbytes] != '\x1b';
+            len--, nbytes++)
+        ;
+    n = nbytes;
+    while (n > 0) {
+        m = (curcol + n >= scrollregion.max.x) ?
+            scrollregion.max.x - curcol : n;
+        if (m == 0) {
+            break;
+        }
+        stringnbg(screen, Pt(screen->clipr.min.x + curcol * fontsize.x,
+                    screen->clipr.min.y + currow * fontsize.y),
+                fgcolor, ZP, curfont, p, m, bgcolor, ZP);
+        curcol += m;
+        if (curcol == scrollregion.max.x) {
+            curcol = scrollregion.min.x;
+            if (currow == scrollregion.max.y - 1) {
+                scr_scroll_down(1);
+            } else {
+                currow++;
+            }
+        }
+        p += m;
+        n -= m;
+    }
+    return nbytes;
+}
+
+void mch_write(char_u *p, int len) {
+    int slen;
+    scr_unstamp_cursor();
+    while (len > 0) {
+        /* Handle special characters. */
+        slen = write_special((char*)p, len);
+        p += slen;
+        len -= slen;
+
+        /* Write as many normal characters as possible. */
+        slen = write_str((char*)p, len);
+        p += slen;
+        len -= slen;
+    }
+    scr_stamp_cursor();
+    flushimage(display, 1);
+}
+
+static void sigalrm(int, char*, void*) {
+    /* Do nothing */
+}
+
+/* Don't allow mouse events to accumulate. */
+static void drain_mouse_events(void) {
+    while (ecanmouse()) {
+        emouse();
+    }
+}
+
+int RealWaitForChar(int, long msec, int*) {
+    Rune rune;
+    char utf[UTFmax];
+    int len;
+
+    drain_mouse_events();
+    if (msec == 0 && !ecankbd()) {
+        return 0;
+    }
+    if (msec > 0) {
+        if (setjmp(timeoutjmpbuf)) {
+            /* We arrive here if the alarm occurred and a library
+             * function called drawerror() due to an interrupted
+             * syscall. */
+            _ALARM(0);
+            interruptable = 0;
+            return 0;
+        }
+        interruptable = 1;
+        _ALARM((unsigned long)msec);
+    }
+    /* TODO garbage collect */
+    rune = ekbd();
+    if (msec > 0) {
+        _ALARM(0);
+        interruptable = 0;
+    }
+    if (rune == Ctrl_C && ctrl_c_interrupts) {
+	got_int = TRUE;
+	return 0;
+    }
+    len = runetochar(utf, &rune);
+    add_to_input_buf_csi((char_u*)utf, len); /* TODO escape K_SPECIAL? */
+    return len > 0;
+}
+
+int mch_inchar(char_u *buf, int maxlen, long msec, int) {
+    if (vim_is_input_buf_empty() && RealWaitForChar(0, msec, NULL) == 0) {
+	return 0;
+    }
+    return read_from_input_buf(buf, maxlen);
+}
+
+int mch_char_avail(void) {
+    return ecankbd();
+}
+
+void mch_delay(long msec, int ignoreinput) {
+    if (ignoreinput) {
+        sleep(msec / 1000);
+    } else {
+        RealWaitForChar(0, msec, NULL);
+    }
+}
+
+int mch_nodetype(char_u *name) {
+    struct stat st;
+    if (stat((char*)name, &st) < 0) {
+        return NODE_NORMAL;
+    }
+    if (S_ISREG(st.st_mode) || S_ISDIR(st.st_mode)) {
+        return NODE_NORMAL;
+    }
+    return NODE_WRITABLE;
+}
+
+int mch_FullName(char_u *fname, char_u *buf, int len, int force) {
+    int		l;
+    char_u	olddir[MAXPATHL];
+    char_u	*p;
+    int		retval = OK;
+
+    /* expand it if forced or not an absolute path */
+    if (force || !mch_isFullName(fname))
+    {
+        /*
+         * If the file name has a path, change to that directory for a moment,
+         * and then do the getwd() (and get back to where we were).
+         * This will get the correct path name with "../" things.
+         */
+        if ((p = vim_strrchr(fname, '/')) != NULL)
+        {
+            /* Only change directory when we are sure we can return to where
+             * we are now.  After doing "su" chdir(".") might not work. */
+            if ( (mch_dirname(olddir, MAXPATHL) == FAIL ||
+                        mch_chdir((char *)olddir) != 0))
+            {
+                p = NULL;	/* can't get current dir: don't chdir */
+                retval = FAIL;
+            }
+            else
+            {
+                /* The directory is copied into buf[], to be able to remove
+                 * the file name without changing it (could be a string in
+                 * read-only memory) */
+                if (p - fname >= len)
+                    retval = FAIL;
+                else
+                {
+                    vim_strncpy(buf, fname, p - fname);
+                    if (mch_chdir((char *)buf))
+                        retval = FAIL;
+                    else
+                        fname = p + 1;
+                    *buf = NUL;
+                }
+            }
+        }
+        if (mch_dirname(buf, len) == FAIL)
+        {
+            retval = FAIL;
+            *buf = NUL;
+        }
+        if (p != NULL)
+        {
+            l = mch_chdir((char *)olddir);
+            if (l != 0)
+                EMSG(_(e_prev_dir));
+        }
+
+        l = STRLEN(buf);
+        if (l >= len)
+            retval = FAIL;
+        else
+        {
+            if (l > 0 && buf[l - 1] != '/' && *fname != NUL
+                    && STRCMP(fname, ".") != 0)
+                STRCAT(buf, "/");
+        }
+    }
+
+    /* Catch file names which are too long. */
+    if (retval == FAIL || STRLEN(buf) + STRLEN(fname) >= len)
+        return FAIL;
+
+    /* Do not append ".", "/dir/." is equal to "/dir". */
+    if (STRCMP(fname, ".") != 0)
+        STRCAT(buf, fname);
+
+    return OK;
+}
+
+long mch_get_pid(void) {
+    return (long)getpid();
+}
+
+int mch_input_isatty(void) {
+    return isatty(0) ? TRUE : FALSE;
+}
+
+int mch_setenv(char *var, char *value, int x) {
+    char buf[100];
+    int fd;
+    int len;
+
+    snprintf(buf, sizeof buf, "/env/%s", var);
+
+    /* Check for overwrite */
+    if (!x) {
+        struct stat st;
+        if (stat(buf, &st) == 0) {
+            return -1;
+        }
+    }
+
+    /* Write the value */
+    fd = creat(buf, 0666);
+    if (fd < 0) {
+        return -1;
+    }
+    len = strlen(value);
+    if (write(fd, value, len) != len) {
+        close(fd);
+        return -1;
+    }
+    close(fd);
+    return 0;
+}
+
+void mch_suspend(void) {
+    suspend_shell();
+}
+
+static void update_shellsize(void) {
+    shellsize = Pt((screen->clipr.max.x - screen->clipr.min.x) / fontsize.x,
+                   (screen->clipr.max.y - screen->clipr.min.y) / fontsize.y);
+}
+
+int mch_get_shellsize(void) {
+    update_shellsize();
+    Rows = shellsize.y;
+    Columns = shellsize.x;
+    scrollregion.min.x = 0;
+    scrollregion.min.y = 0;
+    scrollregion.max.x = shellsize.x;
+    scrollregion.max.y = shellsize.y;
+    return OK;
+}
+
+void mch_set_shellsize(void) {
+    /* Do nothing */
+}
+
+void mch_new_shellsize(void) {
+    /* Do nothing */
+}
+
+void mch_breakcheck(void) {
+    if (scr_inited) {
+	/* Read into input buffer and check for Ctrl-C. */
+	RealWaitForChar(0, 0, NULL);
+    }
+}
+
+/* Called by libevent whenever a resize event occurs. */
+void eresized(int renew) {
+    if (renew) {
+        if (getwindow(display, Refnone) < 0) {
+            err9("resize failed");
+        }
+    }
+    shell_resized();
+}
+
+static void init_colors(void) {
+    int i;
+    int colors[NCOLORS] = {
+        /* Copied from hardcopy.c and adjusted for libdraw. */
+        0x000000ff, 0x0000c0ff, 0x008000ff, 0x004080ff,
+        0xc00000ff, 0xc000c0ff, 0x808000ff, 0xc0c0c0ff,
+        0x808080ff, 0x6060ffff, 0x00ff00ff, 0x00ffffff,
+        0xff8080ff, 0xff40ffff, 0xffff00ff, 0xffffffff
+    };
+    for (i = 0; i < NCOLORS; i++) {
+        colortab[i] = allocimage(display, Rect(0, 0, 1, 1), screen->chan, 1, colors[i]);
+        if (colortab[i] == nil) {
+            err9("allocimage failed");
+        }
+    }
+    mch_set_normal_colors();
+}
+
+static void free_colors(void) {
+    int i;
+    bgcolor = nil;
+    fgcolor = nil;
+    for (i = 0; i < NCOLORS; i++) {
+        freeimage(colortab[i]);
+        colortab[i] = nil;
+    }
+}
+
+static void init_fonts(void) {
+    normalfont = openfont(display, "/lib/font/bit/fixed/unicode.9x18.font");
+    if (normalfont == nil) {
+        err9("openfont normal failed");
+    }
+    boldfont = openfont(display, "/lib/font/bit/fixed/unicode.9x18B.font");
+    if (boldfont == nil) {
+        err9("openfont bold failed");
+    }
+    curfont = normalfont;
+}
+
+static void free_fonts(void) {
+    freefont(normalfont);
+    freefont(boldfont);
+    curfont = nil;
+}
+
+void mch_early_init(void) {
+    rfork(RFENVG | RFNOTEG);
+}
+
+int mch_check_win(int, char**) {
+    return OK;
+}
+
+static void scr_init(void) {
+    if (initdraw(derr, nil, "Vim") == -1) {
+        err9("initdraw failed");
+    }
+
+    init_colors();
+    init_fonts();
+    fontsize = stringsize(curfont, "A");
+    cursorsave = allocimage(display, Rect(0, 0, fontsize.x, fontsize.y), screen->chan, 0, DBlack);
+    mch_get_shellsize();
+    scr_clear();
+    scr_stamp_cursor();
+    flushimage(display, 1);
+
+    /* Mouse events must be enabled to receive window resizes. */
+    einit(Emouse | Ekeyboard);
+    scr_inited = TRUE;
+}
+
+void mch_init(void) {
+    signal(SIGALRM, sigalrm);
+    scr_init();
+
+    /*
+     * Force UTF-8 output no matter what the value of 'encoding' is.
+     * did_set_string_option() in option.c prohibits changing 'termencoding'
+     * to something else than UTF-8.
+     */
+    set_option_value((char_u *)"termencoding", 0L, (char_u *)"utf-8", 0);
+
+#if defined(FEAT_CLIPBOARD)
+    clip_init(TRUE);
+#endif
+}
+
+void mch_exit(int r) {
+    ml_close_all(TRUE);    /* remove all memfiles */
+    /* libdraw shuts down automatically on exit */
+    exit(r);
+}
+
+#if defined(FEAT_TITLE)
+void mch_settitle(char_u *title, char_u *) {
+    int fd;
+    fd = open("/dev/label", O_WRONLY);
+    if (fd < 0) {
+        /* Not running under rio. */
+        return;
+    }
+    write(fd, (char*)title, strlen((char*)title));
+    close(fd);
+}
+
+void mch_restore_title(int) {
+    /* No need to restore - libdraw does this automatically. */
+}
+
+int mch_can_restore_title(void) {
+    return TRUE;
+}
+
+int mch_can_restore_icon(void) {
+    return FALSE;
+}
+#endif
+
+#if defined(FEAT_CLIPBOARD)
+int clip_mch_own_selection(VimClipboard*) {
+    /* We never own the clipboard. */
+    return FAIL;
+}
+
+void clip_mch_lose_selection(VimClipboard*) {
+    /* Do nothing */
+}
+
+void clip_mch_request_selection(VimClipboard *cbd) {
+    int fd;
+    char_u *data;
+    char_u *newdata;
+    long_u len;  /* used length */
+    long_u mlen; /* max allocated length */
+    ssize_t n;
+    int type;
+    fd = open("/dev/snarf", O_RDONLY);
+    if (fd < 0) {
+        /* Not running under rio. */
+        return;
+    }
+    n = 0;
+    len = 0;
+    mlen = 0;
+    data = NULL;
+    do {
+        len += n;
+        mlen += 4096;
+        newdata = vim_realloc(data, mlen);
+        if (!newdata) {
+            n = -1;
+            break;
+        }
+        data = newdata;
+        n = read(fd, data, 4096);
+        /* TODO breakcheck? */
+    } while (n == 4096);
+    if (n >= 0) {
+        len += n;
+        type = memchr(data, '\n', len) ? MLINE : MCHAR;
+        clip_yank_selection(type, data, len, cbd);
+    }
+    vim_free(data);
+    close(fd);
+}
+
+void clip_mch_set_selection(VimClipboard *cbd) {
+    char_u *data;
+    long_u len;
+    int type;
+    int fd;
+
+    /* If the '*' register isn't already filled in, fill it in now. */
+    cbd->owned = TRUE;
+    clip_get_selection(cbd);
+    cbd->owned = FALSE;
+
+    type = clip_convert_selection(&data, &len, cbd);
+    if (type < 0) {
+        return;
+    }
+    fd = open("/dev/snarf", O_WRONLY);
+    if (fd >= 0) {
+        write(fd, data, len);
+        close(fd);
+    }
+    vim_free(data);
+}
+#endif
+
+#if defined(FEAT_MOUSE)
+void mch_setmouse(int) {
+    /* Do nothing.  Mouse needed for clipboard. */
+}
+#endif
+
+static pid_t
+forkwin(int hide){
+	char spec[256];
+	char *wsys;
+	int wfd;
+	pid_t pid;
+
+	/* Fork child. */
+	pid = fork();
+	if(pid != 0)
+	    return pid;
+
+	/* We need a separate namespace from parent process. */
+	rfork(RFNAMEG);
+
+	/* Mounting the window system creates a new window. */
+	wsys = getenv("wsys");
+	if(!wsys){
+		fprintf(stderr, "wsys not set\n");
+		exit(1);
+	}
+	wfd = open(wsys, O_RDWR);
+	if(wfd < 0){
+		fprintf(stderr, "unable to open \"%s\"\n", wsys);
+		exit(1);
+	}
+	snprintf(spec, sizeof spec, "new -pid %d -scroll %s", getpid(), hide ? "-hide" : "");
+	if(mount(wfd, -1, "/mnt/wsys", MREPL, spec) < 0){
+		fprintf(stderr, "unable to mount\n");
+		exit(1);
+	}
+	if(bind("/mnt/wsys", "/dev", MBEFORE) < 0){
+		fprintf(stderr, "unable to bind\n");
+		exit(1);
+	}
+
+	/* Now reopen standard input, output, and error. */
+	freopen("/dev/cons", "r", stdin);
+	setbuf(stdin, NULL);
+	freopen("/dev/cons", "w", stdout);
+	setbuf(stdout, NULL);
+	freopen("/dev/cons", "w", stderr);
+	setbuf(stderr, NULL);
+
+	return pid;
+}
+
+int mch_call_shell(char_u *cmd, int options) {
+    char ch;
+    pid_t pid;
+    int status;
+    int hide;
+
+    /* Non-interactive commands run in a hidden window. */
+    hide = options & SHELL_FILTER || options & SHELL_DOOUT;
+    pid = forkwin(hide);
+    if (pid == -1) {
+	MSG_PUTS(_("\nCannot fork\n"));
+	return -1;
+    }
+    if (pid == 0) {
+	/* Fork again so that we can prompt the user to
+	 * press a key before the window closes. */
+	pid = fork();
+	if (pid == -1) {
+	    exit(255);
+	}
+	if (pid == 0) {
+	    if (cmd) {
+		execl("/bin/rc", "rc", "-c", cmd, NULL);
+	    } else {
+		execl("/bin/rc", "rc", NULL);
+	    }
+	    exit(122); /* same as on UNIX Vim */
+	} else {
+	    waitpid(pid, &status, 0);
+	    if (!hide) {
+		printf("\nPress RETURN to close this window...");
+		read(0, &ch, 1);
+	    }
+	    exit(status);
+	}
+    }
+    waitpid(pid, &status, 0);
+    return status;
+}
--- /dev/null
+++ b/os_plan9.h
@@ -1,0 +1,145 @@
+/* vi:set ts=8 sts=4 sw=4:
+ *
+ * VIM - Vi IMproved	by Bram Moolenaar
+ *
+ * Do ":help uganda"  in Vim to read copying and usage conditions.
+ * Do ":help credits" in Vim to see a list of people who contributed.
+ */
+
+/*
+ * Plan 9 Machine-dependent things
+ */
+
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <time.h>
+#include <dirent.h>
+
+#define SPACE_IN_FILENAME
+#define USE_TERM_CONSOLE
+#define USE_UNIXFILENAME
+
+#define HAVE_STDLIB_H
+#define HAVE_STDARG_H
+#define HAVE_STRING_H
+#define HAVE_FCNTL_H
+#define HAVE_STRCSPN
+#define HAVE_STRFTIME	    /* guessed */
+#define HAVE_SETENV
+#define HAVE_MEMSET
+#define HAVE_PATHDEF
+#define HAVE_QSORT
+#if defined(__DATE__) && defined(__TIME__)
+# define HAVE_DATE_TIME
+#endif
+
+#define DFLT_ERRORFILE		"errors.err"
+
+#define DFLT_RUNTIMEPATH	"$home/lib/vim/vimfiles,$VIM/vimfiles,$VIMRUNTIME,$VIM/vimfiles/after,$home/lib/vim/vimfiles/after"
+
+#if !defined(MAXNAMLEN)
+# define MAXNAMLEN 512		    /* for all other Unix */
+#endif
+
+#define BASENAMELEN	(MAXNAMLEN - 5)
+
+#define TEMPDIRNAMES  "$TMPDIR", "/tmp", ".", "$HOME"
+#define TEMPNAMELEN    256
+
+/*
+ * Names for the EXRC, HELP and temporary files.
+ * Some of these may have been defined in the makefile.
+ */
+#ifndef SYS_VIMRC_FILE
+# define SYS_VIMRC_FILE "$VIM/vimrc"
+#endif
+#ifndef SYS_GVIMRC_FILE
+# define SYS_GVIMRC_FILE "$VIM/gvimrc"
+#endif
+#ifndef SYS_MENU_FILE
+# define SYS_MENU_FILE	"$VIMRUNTIME/menu.vim"
+#endif
+#ifndef DFLT_HELPFILE
+# define DFLT_HELPFILE	"$VIMRUNTIME/doc/help.txt"
+#endif
+#ifndef FILETYPE_FILE
+# define FILETYPE_FILE	"filetype.vim"
+#endif
+#ifndef FTPLUGIN_FILE
+# define FTPLUGIN_FILE	"ftplugin.vim"
+#endif
+#ifndef INDENT_FILE
+# define INDENT_FILE	"indent.vim"
+#endif
+#ifndef FTOFF_FILE
+# define FTOFF_FILE	"ftoff.vim"
+#endif
+#ifndef FTPLUGOF_FILE
+# define FTPLUGOF_FILE	"ftplugof.vim"
+#endif
+#ifndef INDOFF_FILE
+# define INDOFF_FILE	"indoff.vim"
+#endif
+#ifndef SYNTAX_FNAME
+# define SYNTAX_FNAME	"$VIMRUNTIME/syntax/%s.vim"
+#endif
+
+#ifndef USR_EXRC_FILE
+# define USR_EXRC_FILE	"$home/lib/exrc"
+#endif
+
+#ifndef USR_VIMRC_FILE
+# define USR_VIMRC_FILE	"$home/lib/vimrc"
+#endif
+#ifndef EVIM_FILE
+# define EVIM_FILE	"$VIMRUNTIME/evim.vim"
+#endif
+
+#ifndef USR_GVIMRC_FILE
+# define USR_GVIMRC_FILE "$home/lib/gvimrc"
+#endif
+
+#ifdef FEAT_VIMINFO
+# ifndef VIMINFO_FILE
+#  define VIMINFO_FILE	"$home/lib/viminfo"
+# endif
+#endif /* FEAT_VIMINFO */
+
+#ifndef EXRC_FILE
+# define EXRC_FILE	"exrc"
+#endif
+
+#ifndef VIMRC_FILE
+# define VIMRC_FILE	"vimrc"
+#endif
+
+#ifndef GVIMRC_FILE
+# define GVIMRC_FILE	"gvimrc"
+#endif
+
+#ifndef DFLT_BDIR
+#define DFLT_BDIR    ".,/tmp,$home"    /* default for 'backupdir' */
+#endif
+
+#ifndef DFLT_DIR
+# define DFLT_DIR     ".,/tmp" /* default for 'directory' */
+#endif
+
+#ifndef DFLT_VDIR
+# define DFLT_VDIR    "$home/lib/vim/view"       /* default for 'viewdir' */
+#endif
+
+#ifndef DFLT_MAXMEM
+# define DFLT_MAXMEM	(5*1024)	 /* use up to 5 Mbyte for a buffer */
+#endif
+#ifndef DFLT_MAXMEMTOT
+# define DFLT_MAXMEMTOT	(10*1024)    /* use up to 10 Mbyte for Vim */
+#endif
+
+#define mch_rename(src, dst) rename(src, dst)
+#define mch_chdir(s) chdir(s)
+#define vim_mkdir(x, y) mkdir((char*)(x), (y))
+#define mch_rmdir(x) rmdir((char*)(x))
+#define mch_getenv(x) (char_u *)getenv((char *)(x))
--- /dev/null
+++ b/pathdef.c
@@ -1,0 +1,8 @@
+/* pathdef.c */
+#include "vim.h"
+char_u *default_vim_dir = (char_u *)"./lib";
+char_u *default_vimruntime_dir = (char_u *)"./lib/vimfiles";
+char_u *all_cflags = (char_u *)"pcc -c -D_POSIX_SOURCE -DPLAN9 -D_PLAN9_SOURCE -Iproto";
+char_u *all_lflags = (char_u *)"pcc -o 6.vim";
+char_u *compiled_user = (char_u *)"glenda";
+char_u *compiled_sys = (char_u *)"tenshi";
--- /dev/null
+++ b/popupmnu.c
@@ -1,0 +1,603 @@
+/* vi:set ts=8 sts=4 sw=4:
+ *
+ * VIM - Vi IMproved	by Bram Moolenaar
+ *
+ * Do ":help uganda"  in Vim to read copying and usage conditions.
+ * Do ":help credits" in Vim to see a list of people who contributed.
+ * See README.txt for an overview of the Vim source code.
+ */
+
+/*
+ * popupmnu.c: Popup menu (PUM)
+ */
+#include "vim.h"
+
+#if defined(FEAT_INS_EXPAND) || defined(PROTO)
+
+static pumitem_T *pum_array = NULL;	/* items of displayed pum */
+static int pum_size;			/* nr of items in "pum_array" */
+static int pum_selected;		/* index of selected item or -1 */
+static int pum_first = 0;		/* index of top item */
+
+static int pum_height;			/* nr of displayed pum items */
+static int pum_width;			/* width of displayed pum items */
+static int pum_base_width;		/* width of pum items base */
+static int pum_kind_width;		/* width of pum items kind column */
+static int pum_scrollbar;		/* TRUE when scrollbar present */
+
+static int pum_row;			/* top row of pum */
+static int pum_col;			/* left column of pum */
+
+static int pum_do_redraw = FALSE;	/* do redraw anyway */
+
+static int pum_set_selected __ARGS((int n, int repeat));
+
+#define PUM_DEF_HEIGHT 10
+#define PUM_DEF_WIDTH  15
+
+/*
+ * Show the popup menu with items "array[size]".
+ * "array" must remain valid until pum_undisplay() is called!
+ * When possible the leftmost character is aligned with screen column "col".
+ * The menu appears above the screen line "row" or at "row" + "height" - 1.
+ */
+    void
+pum_display(array, size, selected)
+    pumitem_T	*array;
+    int		size;
+    int		selected;	/* index of initially selected item, none if
+				   out of range */
+{
+    int		w;
+    int		def_width;
+    int		max_width;
+    int		kind_width;
+    int		extra_width;
+    int		i;
+    int		top_clear;
+    int		row;
+    int		height;
+    int		col;
+    int		above_row = cmdline_row;
+    int		redo_count = 0;
+
+redo:
+    def_width = PUM_DEF_WIDTH;
+    max_width = 0;
+    kind_width = 0;
+    extra_width = 0;
+
+    /* Pretend the pum is already there to avoid that must_redraw is set when
+     * 'cuc' is on. */
+    pum_array = (pumitem_T *)1;
+    validate_cursor_col();
+    pum_array = NULL;
+
+    row = curwin->w_cline_row + W_WINROW(curwin);
+    height = curwin->w_cline_height;
+    col = curwin->w_wcol + W_WINCOL(curwin) - curwin->w_leftcol;
+
+    if (firstwin->w_p_pvw)
+	top_clear = firstwin->w_height;
+    else
+	top_clear = 0;
+
+    /* When the preview window is at the bottom stop just above it.  Also
+     * avoid drawing over the status line so that it's clear there is a window
+     * boundary. */
+    if (lastwin->w_p_pvw)
+	above_row -= lastwin->w_height + lastwin->w_status_height + 1;
+
+    /*
+     * Figure out the size and position of the pum.
+     */
+    if (size < PUM_DEF_HEIGHT)
+	pum_height = size;
+    else
+	pum_height = PUM_DEF_HEIGHT;
+    if (p_ph > 0 && pum_height > p_ph)
+	pum_height = p_ph;
+
+    /* Put the pum below "row" if possible.  If there are few lines decide on
+     * where there is more room. */
+    if (row >= above_row - pum_height
+			      && row > (above_row - top_clear - height) / 2)
+    {
+	/* pum above "row" */
+	if (row >= size)
+	{
+	    pum_row = row - size;
+	    pum_height = size;
+	}
+	else
+	{
+	    pum_row = 0;
+	    pum_height = row;
+	}
+	if (p_ph > 0 && pum_height > p_ph)
+	{
+	    pum_row += pum_height - p_ph;
+	    pum_height = p_ph;
+	}
+    }
+    else
+    {
+	/* pum below "row" */
+	pum_row = row + height;
+	if (size > above_row - pum_row)
+	    pum_height = above_row - pum_row;
+	else
+	    pum_height = size;
+	if (p_ph > 0 && pum_height > p_ph)
+	    pum_height = p_ph;
+    }
+
+    /* don't display when we only have room for one line */
+    if (pum_height < 1 || (pum_height == 1 && size > 1))
+	return;
+
+    /* If there is a preview window at the top avoid drawing over it. */
+    if (firstwin->w_p_pvw
+	    && pum_row < firstwin->w_height
+	    && pum_height > firstwin->w_height + 4)
+    {
+	pum_row += firstwin->w_height;
+	pum_height -= firstwin->w_height;
+    }
+
+    /* Compute the width of the widest match and the widest extra. */
+    for (i = 0; i < size; ++i)
+    {
+	w = vim_strsize(array[i].pum_text);
+	if (max_width < w)
+	    max_width = w;
+	if (array[i].pum_kind != NULL)
+	{
+	    w = vim_strsize(array[i].pum_kind) + 1;
+	    if (kind_width < w)
+		kind_width = w;
+	}
+	if (array[i].pum_extra != NULL)
+	{
+	    w = vim_strsize(array[i].pum_extra) + 1;
+	    if (extra_width < w)
+		extra_width = w;
+	}
+    }
+    pum_base_width = max_width;
+    pum_kind_width = kind_width;
+
+    /* if there are more items than room we need a scrollbar */
+    if (pum_height < size)
+    {
+	pum_scrollbar = 1;
+	++max_width;
+    }
+    else
+	pum_scrollbar = 0;
+
+    if (def_width < max_width)
+	def_width = max_width;
+
+    if (col < Columns - PUM_DEF_WIDTH || col < Columns - max_width)
+    {
+	/* align pum column with "col" */
+	pum_col = col;
+	pum_width = Columns - pum_col - pum_scrollbar;
+	if (pum_width > max_width + kind_width + extra_width + 1
+						 && pum_width > PUM_DEF_WIDTH)
+	{
+	    pum_width = max_width + kind_width + extra_width + 1;
+	    if (pum_width < PUM_DEF_WIDTH)
+		pum_width = PUM_DEF_WIDTH;
+	}
+    }
+    else if (Columns < def_width)
+    {
+	/* not enough room, will use what we have */
+	pum_col = 0;
+	pum_width = Columns - 1;
+    }
+    else
+    {
+	if (max_width > PUM_DEF_WIDTH)
+	    max_width = PUM_DEF_WIDTH;	/* truncate */
+	pum_col = Columns - max_width;
+	pum_width = max_width - pum_scrollbar;
+    }
+
+    pum_array = array;
+    pum_size = size;
+
+    /* Set selected item and redraw.  If the window size changed need to redo
+     * the positioning.  Limit this to two times, when there is not much
+     * room the window size will keep changing. */
+    if (pum_set_selected(selected, redo_count) && ++redo_count <= 2)
+	goto redo;
+}
+
+/*
+ * Redraw the popup menu, using "pum_first" and "pum_selected".
+ */
+    void
+pum_redraw()
+{
+    int		row = pum_row;
+    int		col;
+    int		attr_norm = highlight_attr[HLF_PNI];
+    int		attr_select = highlight_attr[HLF_PSI];
+    int		attr_scroll = highlight_attr[HLF_PSB];
+    int		attr_thumb = highlight_attr[HLF_PST];
+    int		attr;
+    int		i;
+    int		idx;
+    char_u	*s;
+    char_u	*p = NULL;
+    int		totwidth, width, w;
+    int		thumb_pos = 0;
+    int		thumb_heigth = 1;
+    int		round;
+    int		n;
+
+    if (pum_scrollbar)
+    {
+	thumb_heigth = pum_height * pum_height / pum_size;
+	if (thumb_heigth == 0)
+	    thumb_heigth = 1;
+	thumb_pos = (pum_first * (pum_height - thumb_heigth)
+			    + (pum_size - pum_height) / 2)
+						    / (pum_size - pum_height);
+    }
+
+    for (i = 0; i < pum_height; ++i)
+    {
+	idx = i + pum_first;
+	attr = (idx == pum_selected) ? attr_select : attr_norm;
+
+	/* prepend a space if there is room */
+	if (pum_col > 0)
+	    screen_putchar(' ', row, pum_col - 1, attr);
+
+	/* Display each entry, use two spaces for a Tab.
+	 * Do this 3 times: For the main text, kind and extra info */
+	col = pum_col;
+	totwidth = 0;
+	for (round = 1; round <= 3; ++round)
+	{
+	    width = 0;
+	    s = NULL;
+	    switch (round)
+	    {
+		case 1: p = pum_array[idx].pum_text; break;
+		case 2: p = pum_array[idx].pum_kind; break;
+		case 3: p = pum_array[idx].pum_extra; break;
+	    }
+	    if (p != NULL)
+		for ( ; ; mb_ptr_adv(p))
+		{
+		    if (s == NULL)
+			s = p;
+		    w = ptr2cells(p);
+		    if (*p == NUL || *p == TAB || totwidth + w > pum_width)
+		    {
+			/* Display the text that fits or comes before a Tab.
+			 * First convert it to printable characters. */
+			char_u *st;
+			int  saved = *p;
+
+			*p = NUL;
+			st = transstr(s);
+			*p = saved;
+			if (st != NULL)
+			{
+			    screen_puts_len(st, (int)STRLEN(st), row, col,
+									attr);
+			    vim_free(st);
+			}
+			col += width;
+
+			if (*p != TAB)
+			    break;
+
+			/* Display two spaces for a Tab. */
+			screen_puts_len((char_u *)"  ", 2, row, col, attr);
+			col += 2;
+			totwidth += 2;
+			s = NULL;	    /* start text at next char */
+			width = 0;
+		    }
+		    else
+			width += w;
+		}
+
+	    if (round > 1)
+		n = pum_kind_width + 1;
+	    else
+		n = 1;
+
+	    /* Stop when there is nothing more to display. */
+	    if (round == 3
+		    || (round == 2 && pum_array[idx].pum_extra == NULL)
+		    || (round == 1 && pum_array[idx].pum_kind == NULL
+					  && pum_array[idx].pum_extra == NULL)
+		    || pum_base_width + n >= pum_width)
+		break;
+	    screen_fill(row, row + 1, col, pum_col + pum_base_width + n,
+							      ' ', ' ', attr);
+	    col = pum_col + pum_base_width + n;
+	    totwidth = pum_base_width + n;
+	}
+
+	screen_fill(row, row + 1, col, pum_col + pum_width, ' ', ' ', attr);
+	if (pum_scrollbar > 0)
+	    screen_putchar(' ', row, pum_col + pum_width,
+		    i >= thumb_pos && i < thumb_pos + thumb_heigth
+						  ? attr_thumb : attr_scroll);
+
+	++row;
+    }
+}
+
+#if 0 /* not used yet */
+/*
+ * Return the index of the currently selected item.
+ */
+    int
+pum_get_selected()
+{
+    return pum_selected;
+}
+#endif
+
+/*
+ * Set the index of the currently selected item.  The menu will scroll when
+ * necessary.  When "n" is out of range don't scroll.
+ * This may be repeated when the preview window is used:
+ * "repeat" == 0: open preview window normally
+ * "repeat" == 1: open preview window but don't set the size
+ * "repeat" == 2: don't open preview window
+ * Returns TRUE when the window was resized and the location of the popup menu
+ * must be recomputed.
+ */
+    static int
+pum_set_selected(n, repeat)
+    int	    n;
+    int	    repeat;
+{
+    int	    resized = FALSE;
+    int	    context = pum_height / 2;
+
+    pum_selected = n;
+
+    if (pum_selected >= 0 && pum_selected < pum_size)
+    {
+	if (pum_first > pum_selected - 4)
+	{
+	    /* scroll down; when we did a jump it's probably a PageUp then
+	     * scroll a whole page */
+	    if (pum_first > pum_selected - 2)
+	    {
+		pum_first -= pum_height - 2;
+		if (pum_first < 0)
+		    pum_first = 0;
+		else if (pum_first > pum_selected)
+		    pum_first = pum_selected;
+	    }
+	    else
+		pum_first = pum_selected;
+	}
+	else if (pum_first < pum_selected - pum_height + 5)
+	{
+	    /* scroll up; when we did a jump it's probably a PageDown then
+	     * scroll a whole page */
+	    if (pum_first < pum_selected - pum_height + 1 + 2)
+	    {
+		pum_first += pum_height - 2;
+		if (pum_first < pum_selected - pum_height + 1)
+		    pum_first = pum_selected - pum_height + 1;
+	    }
+	    else
+		pum_first = pum_selected - pum_height + 1;
+	}
+
+	/* Give a few lines of context when possible. */
+	if (context > 3)
+	    context = 3;
+	if (pum_height > 2)
+	{
+	    if (pum_first > pum_selected - context)
+	    {
+		/* scroll down */
+		pum_first = pum_selected - context;
+		if (pum_first < 0)
+		    pum_first = 0;
+	    }
+	    else if (pum_first < pum_selected + context - pum_height + 1)
+	    {
+		/* scroll up */
+		pum_first = pum_selected + context - pum_height + 1;
+	    }
+	}
+
+#if defined(FEAT_WINDOWS) && defined(FEAT_QUICKFIX)
+	/*
+	 * Show extra info in the preview window if there is something and
+	 * 'completeopt' contains "preview".
+	 * Skip this when tried twice already.
+	 * Skip this also when there is not much room.
+	 * NOTE: Be very careful not to sync undo!
+	 */
+	if (pum_array[pum_selected].pum_info != NULL
+		&& Rows > 10
+		&& repeat <= 1
+		&& vim_strchr(p_cot, 'p') != NULL)
+	{
+	    win_T	*curwin_save = curwin;
+	    int		res = OK;
+
+	    /* Open a preview window.  3 lines by default. */
+	    g_do_tagpreview = 3;
+	    resized = prepare_tagpreview(FALSE);
+	    g_do_tagpreview = 0;
+
+	    if (curwin->w_p_pvw)
+	    {
+		if (curbuf->b_fname == NULL
+			&& curbuf->b_p_bt[0] == 'n' && curbuf->b_p_bt[2] == 'f'
+			&& curbuf->b_p_bh[0] == 'w')
+		{
+		    /* Already a "wipeout" buffer, make it empty. */
+		    while (!bufempty())
+			ml_delete((linenr_T)1, FALSE);
+		}
+		else
+		{
+		    /* Don't want to sync undo in the current buffer. */
+		    ++no_u_sync;
+		    res = do_ecmd(0, NULL, NULL, NULL, ECMD_ONE, 0);
+		    --no_u_sync;
+		    if (res == OK)
+		    {
+			/* Edit a new, empty buffer. Set options for a "wipeout"
+			 * buffer. */
+			set_option_value((char_u *)"swf", 0L, NULL, OPT_LOCAL);
+			set_option_value((char_u *)"bt", 0L,
+					       (char_u *)"nofile", OPT_LOCAL);
+			set_option_value((char_u *)"bh", 0L,
+						 (char_u *)"wipe", OPT_LOCAL);
+			set_option_value((char_u *)"diff", 0L,
+						     (char_u *)"", OPT_LOCAL);
+		    }
+		}
+		if (res == OK)
+		{
+		    char_u	*p, *e;
+		    linenr_T	lnum = 0;
+
+		    for (p = pum_array[pum_selected].pum_info; *p != NUL; )
+		    {
+			e = vim_strchr(p, '\n');
+			if (e == NULL)
+			{
+			    ml_append(lnum++, p, 0, FALSE);
+			    break;
+			}
+			else
+			{
+			    *e = NUL;
+			    ml_append(lnum++, p, (int)(e - p + 1), FALSE);
+			    *e = '\n';
+			    p = e + 1;
+			}
+		    }
+
+		    /* Increase the height of the preview window to show the
+		     * text, but no more than 'previewheight' lines. */
+		    if (repeat == 0)
+		    {
+			if (lnum > p_pvh)
+			    lnum = p_pvh;
+			if (curwin->w_height < lnum)
+			{
+			    win_setheight((int)lnum);
+			    resized = TRUE;
+			}
+		    }
+
+		    curbuf->b_changed = 0;
+		    curbuf->b_p_ma = FALSE;
+		    curwin->w_cursor.lnum = 0;
+		    curwin->w_cursor.col = 0;
+
+		    if (curwin != curwin_save && win_valid(curwin_save))
+		    {
+			/* Return cursor to where we were */
+			validate_cursor();
+			redraw_later(SOME_VALID);
+
+			/* When the preview window was resized we need to
+			 * update the view on the buffer.  Only go back to
+			 * the window when needed, otherwise it will always be
+			 * redraw. */
+			if (resized)
+			{
+			    win_enter(curwin_save, TRUE);
+			    update_topline();
+			}
+
+			/* Update the screen before drawing the popup menu.
+			 * Enable updating the status lines. */
+			pum_do_redraw = TRUE;
+			update_screen(0);
+			pum_do_redraw = FALSE;
+
+			if (!resized && win_valid(curwin_save))
+			    win_enter(curwin_save, TRUE);
+
+			/* May need to update the screen again when there are
+			 * autocommands involved. */
+			pum_do_redraw = TRUE;
+			update_screen(0);
+			pum_do_redraw = FALSE;
+		    }
+		}
+	    }
+	}
+#endif
+    }
+
+    /* Never display more than we have */
+    if (pum_first > pum_size - pum_height)
+	pum_first = pum_size - pum_height;
+
+    if (!resized)
+	pum_redraw();
+
+    return resized;
+}
+
+/*
+ * Undisplay the popup menu (later).
+ */
+    void
+pum_undisplay()
+{
+    pum_array = NULL;
+    redraw_all_later(SOME_VALID);
+#ifdef FEAT_WINDOWS
+    redraw_tabline = TRUE;
+#endif
+    status_redraw_all();
+}
+
+/*
+ * Clear the popup menu.  Currently only resets the offset to the first
+ * displayed item.
+ */
+    void
+pum_clear()
+{
+    pum_first = 0;
+}
+
+/*
+ * Return TRUE if the popup menu is displayed.
+ * Overruled when "pum_do_redraw" is set, used to redraw the status lines.
+ */
+    int
+pum_visible()
+{
+    return !pum_do_redraw && pum_array != NULL;
+}
+
+/*
+ * Return the height of the popup menu, the number of entries visible.
+ * Only valid when pum_visible() returns TRUE!
+ */
+    int
+pum_get_height()
+{
+    return pum_height;
+}
+
+#endif
--- /dev/null
+++ b/proto.h
@@ -1,0 +1,270 @@
+/* vi:set ts=8 sts=4 sw=4:
+ *
+ * VIM - Vi IMproved	by Bram Moolenaar
+ *
+ * Do ":help uganda"  in Vim to read copying and usage conditions.
+ * Do ":help credits" in Vim to see a list of people who contributed.
+ */
+
+/*
+ * proto.h: include the (automatically generated) function prototypes
+ */
+
+/*
+ * Don't include these while generating prototypes.  Prevents problems when
+ * files are missing.
+ */
+#if !defined(PROTO) && !defined(NOPROTO)
+
+/*
+ * Machine-dependent routines.
+ */
+/* avoid errors in function prototypes */
+# if !defined(FEAT_X11) && !defined(FEAT_GUI_GTK)
+#  define Display int
+#  define Widget int
+# endif
+# ifndef FEAT_GUI_GTK
+#  define GdkEvent int
+#  define GdkEventKey int
+# endif
+# ifndef FEAT_X11
+#  define XImage int
+# endif
+
+# ifdef AMIGA
+#  include "os_amiga.pro"
+# endif
+# if defined(UNIX) || defined(__EMX__) || defined(VMS)
+#  include "os_unix.pro"
+# endif
+# if defined(MSDOS) || defined(WIN16)
+#  include "os_msdos.pro"
+# endif
+# ifdef WIN16
+   typedef LPSTR LPWSTR;
+   typedef LPCSTR LPCWSTR;
+   typedef int LPBOOL;
+#  include "os_win16.pro"
+#  include "os_mswin.pro"
+# endif
+# ifdef WIN3264
+#  include "os_win32.pro"
+#  include "os_mswin.pro"
+#  if (defined(__GNUC__) && !defined(__MINGW32__)) \
+	|| (defined(__BORLANDC__) && __BORLANDC__ < 0x502)
+extern int _stricoll __ARGS((char *a, char *b));
+#  endif
+# endif
+# ifdef VMS
+#  include "os_vms.pro"
+# endif
+# ifdef __BEOS__
+#  include "os_beos.pro"
+# endif
+# ifdef RISCOS
+#  include "os_riscos.pro"
+# endif
+# ifdef __QNX__
+#  include "os_qnx.pro"
+# endif
+# if defined(PLAN9)
+#  include "os_plan9.pro"
+# endif
+
+# include "buffer.pro"
+# include "charset.pro"
+# ifdef FEAT_CSCOPE
+#  include "if_cscope.pro"
+# endif
+# include "diff.pro"
+# include "digraph.pro"
+# include "edit.pro"
+# include "eval.pro"
+# include "ex_cmds.pro"
+# include "ex_cmds2.pro"
+# include "ex_docmd.pro"
+# include "ex_eval.pro"
+# include "ex_getln.pro"
+# include "fileio.pro"
+# include "fold.pro"
+# include "getchar.pro"
+# ifdef FEAT_HANGULIN
+#  include "hangulin.pro"
+# endif
+# include "hardcopy.pro"
+# include "hashtab.pro"
+# include "main.pro"
+# include "mark.pro"
+# include "memfile.pro"
+# include "memline.pro"
+# ifdef FEAT_MENU
+#  include "menu.pro"
+# endif
+
+# if !defined MESSAGE_FILE || defined(HAVE_STDARG_H)
+    /* These prototypes cannot be produced automatically and conflict with
+     * the old-style prototypes in message.c. */
+int
+#  ifdef __BORLANDC__
+_RTLENTRYF
+#  endif
+smsg __ARGS((char_u *, ...));
+int
+#  ifdef __BORLANDC__
+_RTLENTRYF
+#  endif
+smsg_attr __ARGS((int, char_u *, ...));
+int
+#  ifdef __BORLANDC__
+_RTLENTRYF
+#  endif
+vim_snprintf __ARGS((char *, size_t, char *, ...));
+#  if defined(HAVE_STDARG_H)
+int vim_vsnprintf(char *str, size_t str_m, char *fmt, va_list ap, typval_T *tvs);
+#  endif
+# endif
+
+# include "message.pro"
+# include "misc1.pro"
+# include "misc2.pro"
+#ifndef HAVE_STRPBRK	    /* not generated automatically from misc2.c */
+char_u *vim_strpbrk __ARGS((char_u *s, char_u *charset));
+#endif
+#ifndef HAVE_QSORT
+/* Use our own qsort(), don't define the prototype when not used. */
+void qsort __ARGS((void *base, size_t elm_count, size_t elm_size, int (*cmp)(const void *, const void *)));
+#endif
+# include "move.pro"
+# if defined(FEAT_MBYTE) || defined(FEAT_XIM) || defined(FEAT_KEYMAP) \
+	|| defined(FEAT_POSTSCRIPT)
+#  include "mbyte.pro"
+# endif
+# include "normal.pro"
+# include "ops.pro"
+# include "option.pro"
+# include "popupmnu.pro"
+# ifdef FEAT_QUICKFIX
+#  include "quickfix.pro"
+# endif
+# include "regexp.pro"
+# include "screen.pro"
+# include "search.pro"
+# include "spell.pro"
+# include "syntax.pro"
+# include "tag.pro"
+# include "term.pro"
+# if defined(HAVE_TGETENT) && (defined(AMIGA) || defined(VMS))
+#  include "termlib.pro"
+# endif
+# include "ui.pro"
+# include "undo.pro"
+# include "version.pro"
+# include "window.pro"
+
+# ifdef FEAT_MZSCHEME
+#  include "if_mzsch.pro"
+# endif
+
+# ifdef FEAT_PYTHON
+#  include "if_python.pro"
+# endif
+
+# ifdef FEAT_TCL
+#  include "if_tcl.pro"
+# endif
+
+# ifdef FEAT_RUBY
+#  include "if_ruby.pro"
+# endif
+
+# ifdef FEAT_GUI
+#  include "gui.pro"
+#  if defined(UNIX) || defined(MACOS)
+#   include "pty.pro"
+#  endif
+#  if !defined(HAVE_SETENV) && !defined(HAVE_PUTENV) && !defined(VMS)
+extern int putenv __ARGS((const char *string));		/* from pty.c */
+#   ifdef USE_VIMPTY_GETENV
+extern char_u *vimpty_getenv __ARGS((const char_u *string));	/* from pty.c */
+#   endif
+#  endif
+#  ifdef FEAT_GUI_W16
+#   include "gui_w16.pro"
+#  endif
+    /* Ugly solution for "BalloonEval" not being defined while it's used in
+     * the prototypes. */
+#  ifndef FEAT_BEVAL
+#   define BalloonEval int
+#  endif
+#  ifdef FEAT_GUI_W32
+#   include "gui_w32.pro"
+#  endif
+#  ifdef FEAT_GUI_GTK
+#   include "gui_gtk.pro"
+#   include "gui_gtk_x11.pro"
+#  endif
+#  ifdef FEAT_GUI_MOTIF
+#   include "gui_motif.pro"
+#   include "gui_xmdlg.pro"
+#  endif
+#  ifdef FEAT_GUI_ATHENA
+#   include "gui_athena.pro"
+#   ifdef FEAT_BROWSE
+extern char *vim_SelFile __ARGS((Widget toplevel, char *prompt, char *init_path, int (*show_entry)(), int x, int y, guicolor_T fg, guicolor_T bg, guicolor_T scroll_fg, guicolor_T scroll_bg));
+#   endif
+#  endif
+#  ifdef FEAT_GUI_MAC
+#   include "gui_mac.pro"
+#  endif
+#  ifdef FEAT_GUI_X11
+#   include "gui_x11.pro"
+#  endif
+#  ifdef RISCOS
+#   include "gui_riscos.pro"
+#  endif
+#  ifdef FEAT_GUI_PHOTON
+#   include "gui_photon.pro"
+#  endif
+#  ifdef FEAT_SUN_WORKSHOP
+#   include "workshop.pro"
+#  endif
+#  ifdef FEAT_NETBEANS_INTG
+#   include "netbeans.pro"
+#  endif
+# endif	/* FEAT_GUI */
+
+# ifdef FEAT_OLE
+#  include "if_ole.pro"
+# endif
+# if defined(FEAT_CLIENTSERVER) && defined(FEAT_X11)
+#  include "if_xcmdsrv.pro"
+# endif
+
+/*
+ * The perl include files pollute the namespace, therefore proto.h must be
+ * included before the perl include files.  But then CV is not defined, which
+ * is used in if_perl.pro.  To get around this, the perl prototype files are
+ * not included here for the perl files.  Use a dummy define for CV for the
+ * other files.
+ */
+#if defined(FEAT_PERL) && !defined(IN_PERL_FILE)
+# define CV void
+# ifdef __BORLANDC__
+  #pragma option -pc
+# endif
+# include "if_perl.pro"
+# ifdef __BORLANDC__
+  #pragma option -p.
+# endif
+# include "if_perlsfio.pro"
+#endif
+
+#ifdef MACOS_CONVERT
+# include "os_mac_conv.pro"
+#endif
+
+#ifdef __BORLANDC__
+# define _PROTO_H
+#endif
+#endif /* !PROTO && !NOPROTO */
--- /dev/null
+++ b/proto/buffer.pro
@@ -1,0 +1,70 @@
+/* buffer.c */
+int open_buffer __ARGS((int read_stdin, exarg_T *eap));
+int buf_valid __ARGS((buf_T *buf));
+void close_buffer __ARGS((win_T *win, buf_T *buf, int action));
+void buf_clear_file __ARGS((buf_T *buf));
+void buf_freeall __ARGS((buf_T *buf, int del_buf, int wipe_buf));
+void goto_buffer __ARGS((exarg_T *eap, int start, int dir, int count));
+void handle_swap_exists __ARGS((buf_T *old_curbuf));
+char_u *do_bufdel __ARGS((int command, char_u *arg, int addr_count, int start_bnr, int end_bnr, int forceit));
+int do_buffer __ARGS((int action, int start, int dir, int count, int forceit));
+void set_curbuf __ARGS((buf_T *buf, int action));
+void enter_buffer __ARGS((buf_T *buf));
+void do_autochdir __ARGS((void));
+buf_T *buflist_new __ARGS((char_u *ffname, char_u *sfname, linenr_T lnum, int flags));
+void free_buf_options __ARGS((buf_T *buf, int free_p_ff));
+int buflist_getfile __ARGS((int n, linenr_T lnum, int options, int forceit));
+void buflist_getfpos __ARGS((void));
+buf_T *buflist_findname_exp __ARGS((char_u *fname));
+buf_T *buflist_findname __ARGS((char_u *ffname));
+int buflist_findpat __ARGS((char_u *pattern, char_u *pattern_end, int unlisted, int diffmode));
+int ExpandBufnames __ARGS((char_u *pat, int *num_file, char_u ***file, int options));
+buf_T *buflist_findnr __ARGS((int nr));
+char_u *buflist_nr2name __ARGS((int n, int fullname, int helptail));
+void get_winopts __ARGS((buf_T *buf));
+pos_T *buflist_findfpos __ARGS((buf_T *buf));
+linenr_T buflist_findlnum __ARGS((buf_T *buf));
+void buflist_list __ARGS((exarg_T *eap));
+int buflist_name_nr __ARGS((int fnum, char_u **fname, linenr_T *lnum));
+int setfname __ARGS((buf_T *buf, char_u *ffname, char_u *sfname, int message));
+void buf_set_name __ARGS((int fnum, char_u *name));
+void buf_name_changed __ARGS((buf_T *buf));
+buf_T *setaltfname __ARGS((char_u *ffname, char_u *sfname, linenr_T lnum));
+char_u *getaltfname __ARGS((int errmsg));
+int buflist_add __ARGS((char_u *fname, int flags));
+void buflist_slash_adjust __ARGS((void));
+void buflist_altfpos __ARGS((void));
+int otherfile __ARGS((char_u *ffname));
+void buf_setino __ARGS((buf_T *buf));
+void fileinfo __ARGS((int fullname, int shorthelp, int dont_truncate));
+void col_print __ARGS((char_u *buf, int col, int vcol));
+void maketitle __ARGS((void));
+void resettitle __ARGS((void));
+void free_titles __ARGS((void));
+int build_stl_str_hl __ARGS((win_T *wp, char_u *out, size_t outlen, char_u *fmt, int use_sandbox, int fillchar, int maxwidth, struct stl_hlrec *hltab, struct stl_hlrec *tabtab));
+void get_rel_pos __ARGS((win_T *wp, char_u *str));
+int append_arg_number __ARGS((win_T *wp, char_u *buf, int add_file, int maxlen));
+char_u *fix_fname __ARGS((char_u *fname));
+void fname_expand __ARGS((buf_T *buf, char_u **ffname, char_u **sfname));
+char_u *alist_name __ARGS((aentry_T *aep));
+void do_arg_all __ARGS((int count, int forceit, int keep_tabs));
+void ex_buffer_all __ARGS((exarg_T *eap));
+void do_modelines __ARGS((int flags));
+int read_viminfo_bufferlist __ARGS((vir_T *virp, int writing));
+void write_viminfo_bufferlist __ARGS((FILE *fp));
+char *buf_spname __ARGS((buf_T *buf));
+void buf_addsign __ARGS((buf_T *buf, int id, linenr_T lnum, int typenr));
+int buf_change_sign_type __ARGS((buf_T *buf, int markId, int typenr));
+int_u buf_getsigntype __ARGS((buf_T *buf, linenr_T lnum, int type));
+linenr_T buf_delsign __ARGS((buf_T *buf, int id));
+int buf_findsign __ARGS((buf_T *buf, int id));
+int buf_findsign_id __ARGS((buf_T *buf, linenr_T lnum));
+int buf_findsigntype_id __ARGS((buf_T *buf, linenr_T lnum, int typenr));
+int buf_signcount __ARGS((buf_T *buf, linenr_T lnum));
+void buf_delete_all_signs __ARGS((void));
+void sign_list_placed __ARGS((buf_T *rbuf));
+void sign_mark_adjust __ARGS((linenr_T line1, linenr_T line2, long amount, long amount_after));
+void set_buflisted __ARGS((int on));
+int buf_contents_changed __ARGS((buf_T *buf));
+void wipe_buffer __ARGS((buf_T *buf, int aucmd));
+/* vim: set ft=c : */
--- /dev/null
+++ b/proto/charset.pro
@@ -1,0 +1,56 @@
+/* charset.c */
+int init_chartab __ARGS((void));
+int buf_init_chartab __ARGS((buf_T *buf, int global));
+void trans_characters __ARGS((char_u *buf, int bufsize));
+char_u *transstr __ARGS((char_u *s));
+char_u *str_foldcase __ARGS((char_u *str, int orglen, char_u *buf, int buflen));
+char_u *transchar __ARGS((int c));
+char_u *transchar_byte __ARGS((int c));
+void transchar_nonprint __ARGS((char_u *buf, int c));
+void transchar_hex __ARGS((char_u *buf, int c));
+int byte2cells __ARGS((int b));
+int char2cells __ARGS((int c));
+int ptr2cells __ARGS((char_u *p));
+int vim_strsize __ARGS((char_u *s));
+int vim_strnsize __ARGS((char_u *s, int len));
+int chartabsize __ARGS((char_u *p, colnr_T col));
+int linetabsize __ARGS((char_u *s));
+int win_linetabsize __ARGS((win_T *wp, char_u *p, colnr_T len));
+int vim_isIDc __ARGS((int c));
+int vim_iswordc __ARGS((int c));
+int vim_iswordp __ARGS((char_u *p));
+int vim_iswordc_buf __ARGS((char_u *p, buf_T *buf));
+int vim_isfilec __ARGS((int c));
+int vim_isprintc __ARGS((int c));
+int vim_isprintc_strict __ARGS((int c));
+int lbr_chartabsize __ARGS((unsigned char *s, colnr_T col));
+int lbr_chartabsize_adv __ARGS((char_u **s, colnr_T col));
+int win_lbr_chartabsize __ARGS((win_T *wp, char_u *s, colnr_T col, int *headp));
+int in_win_border __ARGS((win_T *wp, colnr_T vcol));
+void getvcol __ARGS((win_T *wp, pos_T *pos, colnr_T *start, colnr_T *cursor, colnr_T *end));
+colnr_T getvcol_nolist __ARGS((pos_T *posp));
+void getvvcol __ARGS((win_T *wp, pos_T *pos, colnr_T *start, colnr_T *cursor, colnr_T *end));
+void getvcols __ARGS((win_T *wp, pos_T *pos1, pos_T *pos2, colnr_T *left, colnr_T *right));
+char_u *skipwhite __ARGS((char_u *p));
+char_u *skipdigits __ARGS((char_u *p));
+char_u *skiphex __ARGS((char_u *p));
+char_u *skiptodigit __ARGS((char_u *p));
+char_u *skiptohex __ARGS((char_u *p));
+int vim_isdigit __ARGS((int c));
+int vim_isxdigit __ARGS((int c));
+int vim_islower __ARGS((int c));
+int vim_isupper __ARGS((int c));
+int vim_toupper __ARGS((int c));
+int vim_tolower __ARGS((int c));
+char_u *skiptowhite __ARGS((char_u *p));
+char_u *skiptowhite_esc __ARGS((char_u *p));
+long getdigits __ARGS((char_u **pp));
+int vim_isblankline __ARGS((char_u *lbuf));
+void vim_str2nr __ARGS((char_u *start, int *hexp, int *len, int dooct, int dohex, long *nptr, unsigned long *unptr));
+int hex2nr __ARGS((int c));
+int hexhex2nr __ARGS((char_u *p));
+int rem_backslash __ARGS((char_u *str));
+void backslash_halve __ARGS((char_u *p));
+char_u *backslash_halve_save __ARGS((char_u *p));
+void ebcdic2ascii __ARGS((char_u *buffer, int len));
+/* vim: set ft=c : */
--- /dev/null
+++ b/proto/diff.pro
@@ -1,0 +1,26 @@
+/* diff.c */
+void diff_buf_delete __ARGS((buf_T *buf));
+void diff_buf_adjust __ARGS((win_T *win));
+void diff_buf_add __ARGS((buf_T *buf));
+void diff_invalidate __ARGS((buf_T *buf));
+void diff_mark_adjust __ARGS((linenr_T line1, linenr_T line2, long amount, long amount_after));
+void ex_diffupdate __ARGS((exarg_T *eap));
+void ex_diffpatch __ARGS((exarg_T *eap));
+void ex_diffsplit __ARGS((exarg_T *eap));
+void ex_diffthis __ARGS((exarg_T *eap));
+void diff_win_options __ARGS((win_T *wp, int addbuf));
+void ex_diffoff __ARGS((exarg_T *eap));
+void diff_clear __ARGS((tabpage_T *tp));
+int diff_check __ARGS((win_T *wp, linenr_T lnum));
+int diff_check_fill __ARGS((win_T *wp, linenr_T lnum));
+void diff_set_topline __ARGS((win_T *fromwin, win_T *towin));
+int diffopt_changed __ARGS((void));
+int diffopt_horizontal __ARGS((void));
+int diff_find_change __ARGS((win_T *wp, linenr_T lnum, int *startp, int *endp));
+int diff_infold __ARGS((win_T *wp, linenr_T lnum));
+void nv_diffgetput __ARGS((int put));
+void ex_diffgetput __ARGS((exarg_T *eap));
+int diff_mode_buf __ARGS((buf_T *buf));
+int diff_move_to __ARGS((int dir, long count));
+linenr_T diff_lnum_win __ARGS((linenr_T lnum, win_T *wp));
+/* vim: set ft=c : */
--- /dev/null
+++ b/proto/digraph.pro
@@ -1,0 +1,9 @@
+/* digraph.c */
+int do_digraph __ARGS((int c));
+int get_digraph __ARGS((int cmdline));
+int getdigraph __ARGS((int char1, int char2, int meta));
+void putdigraph __ARGS((char_u *str));
+void listdigraphs __ARGS((void));
+char_u *keymap_init __ARGS((void));
+void ex_loadkeymap __ARGS((exarg_T *eap));
+/* vim: set ft=c : */
--- /dev/null
+++ b/proto/edit.pro
@@ -1,0 +1,41 @@
+/* edit.c */
+int edit __ARGS((int cmdchar, int startln, long count));
+void edit_putchar __ARGS((int c, int highlight));
+void edit_unputchar __ARGS((void));
+void display_dollar __ARGS((colnr_T col));
+void change_indent __ARGS((int type, int amount, int round, int replaced));
+void truncate_spaces __ARGS((char_u *line));
+void backspace_until_column __ARGS((int col));
+int vim_is_ctrl_x_key __ARGS((int c));
+int ins_compl_add_infercase __ARGS((char_u *str, int len, int icase, char_u *fname, int dir, int flags));
+void set_completion __ARGS((int startcol, list_T *list));
+void ins_compl_show_pum __ARGS((void));
+char_u *find_word_start __ARGS((char_u *ptr));
+char_u *find_word_end __ARGS((char_u *ptr));
+int ins_compl_active __ARGS((void));
+int ins_compl_add_tv __ARGS((typval_T *tv, int dir));
+void ins_compl_check_keys __ARGS((int frequency));
+int get_literal __ARGS((void));
+void insertchar __ARGS((int c, int flags, int second_indent));
+void auto_format __ARGS((int trailblank, int prev_line));
+int comp_textwidth __ARGS((int ff));
+int stop_arrow __ARGS((void));
+void set_last_insert __ARGS((int c));
+void free_last_insert __ARGS((void));
+char_u *add_char2buf __ARGS((int c, char_u *s));
+void beginline __ARGS((int flags));
+int oneright __ARGS((void));
+int oneleft __ARGS((void));
+int cursor_up __ARGS((long n, int upd_topline));
+int cursor_down __ARGS((long n, int upd_topline));
+int stuff_inserted __ARGS((int c, long count, int no_esc));
+char_u *get_last_insert __ARGS((void));
+char_u *get_last_insert_save __ARGS((void));
+void replace_push __ARGS((int c));
+void fixthisline __ARGS((int (*get_the_indent)(void)));
+void fix_indent __ARGS((void));
+int in_cinkeys __ARGS((int keytyped, int when, int line_is_empty));
+int hkmap __ARGS((int c));
+void ins_scroll __ARGS((void));
+void ins_horscroll __ARGS((void));
+/* vim: set ft=c : */
--- /dev/null
+++ b/proto/eval.pro
@@ -1,0 +1,99 @@
+/* eval.c */
+void eval_init __ARGS((void));
+void eval_clear __ARGS((void));
+char_u *func_name __ARGS((void *cookie));
+linenr_T *func_breakpoint __ARGS((void *cookie));
+int *func_dbg_tick __ARGS((void *cookie));
+int func_level __ARGS((void *cookie));
+int current_func_returned __ARGS((void));
+void set_internal_string_var __ARGS((char_u *name, char_u *value));
+int var_redir_start __ARGS((char_u *name, int append));
+void var_redir_str __ARGS((char_u *value, int value_len));
+void var_redir_stop __ARGS((void));
+int eval_charconvert __ARGS((char_u *enc_from, char_u *enc_to, char_u *fname_from, char_u *fname_to));
+int eval_printexpr __ARGS((char_u *fname, char_u *args));
+void eval_diff __ARGS((char_u *origfile, char_u *newfile, char_u *outfile));
+void eval_patch __ARGS((char_u *origfile, char_u *difffile, char_u *outfile));
+int eval_to_bool __ARGS((char_u *arg, int *error, char_u **nextcmd, int skip));
+char_u *eval_to_string_skip __ARGS((char_u *arg, char_u **nextcmd, int skip));
+int skip_expr __ARGS((char_u **pp));
+char_u *eval_to_string __ARGS((char_u *arg, char_u **nextcmd, int dolist));
+char_u *eval_to_string_safe __ARGS((char_u *arg, char_u **nextcmd, int use_sandbox));
+int eval_to_number __ARGS((char_u *expr));
+list_T *eval_spell_expr __ARGS((char_u *badword, char_u *expr));
+int get_spellword __ARGS((list_T *list, char_u **pp));
+typval_T *eval_expr __ARGS((char_u *arg, char_u **nextcmd));
+void *call_func_retstr __ARGS((char_u *func, int argc, char_u **argv, int safe));
+long call_func_retnr __ARGS((char_u *func, int argc, char_u **argv, int safe));
+void *call_func_retlist __ARGS((char_u *func, int argc, char_u **argv, int safe));
+void *save_funccal __ARGS((void));
+void restore_funccal __ARGS((void *vfc));
+void prof_child_enter __ARGS((proftime_T *tm));
+void prof_child_exit __ARGS((proftime_T *tm));
+int eval_foldexpr __ARGS((char_u *arg, int *cp));
+void ex_let __ARGS((exarg_T *eap));
+void *eval_for_line __ARGS((char_u *arg, int *errp, char_u **nextcmdp, int skip));
+int next_for_item __ARGS((void *fi_void, char_u *arg));
+void free_for_info __ARGS((void *fi_void));
+void set_context_for_expression __ARGS((expand_T *xp, char_u *arg, cmdidx_T cmdidx));
+void ex_call __ARGS((exarg_T *eap));
+void ex_unlet __ARGS((exarg_T *eap));
+void ex_lockvar __ARGS((exarg_T *eap));
+int do_unlet __ARGS((char_u *name, int forceit));
+void del_menutrans_vars __ARGS((void));
+char_u *get_user_var_name __ARGS((expand_T *xp, int idx));
+list_T *list_alloc __ARGS((void));
+void list_unref __ARGS((list_T *l));
+void list_free __ARGS((list_T *l, int recurse));
+dictitem_T *dict_lookup __ARGS((hashitem_T *hi));
+int list_append_dict __ARGS((list_T *list, dict_T *dict));
+int garbage_collect __ARGS((void));
+dict_T *dict_alloc __ARGS((void));
+int dict_add_nr_str __ARGS((dict_T *d, char *key, long nr, char_u *str));
+char_u *get_dict_string __ARGS((dict_T *d, char_u *key, int save));
+long get_dict_number __ARGS((dict_T *d, char_u *key));
+char_u *get_function_name __ARGS((expand_T *xp, int idx));
+char_u *get_expr_name __ARGS((expand_T *xp, int idx));
+long do_searchpair __ARGS((char_u *spat, char_u *mpat, char_u *epat, int dir, char_u *skip, int flags, pos_T *match_pos, linenr_T lnum_stop));
+void set_vim_var_nr __ARGS((int idx, long val));
+long get_vim_var_nr __ARGS((int idx));
+char_u *get_vim_var_str __ARGS((int idx));
+void set_vcount __ARGS((long count, long count1));
+void set_vim_var_string __ARGS((int idx, char_u *val, int len));
+void set_reg_var __ARGS((int c));
+char_u *v_exception __ARGS((char_u *oldval));
+char_u *v_throwpoint __ARGS((char_u *oldval));
+char_u *set_cmdarg __ARGS((exarg_T *eap, char_u *oldarg));
+void free_tv __ARGS((typval_T *varp));
+void clear_tv __ARGS((typval_T *varp));
+long get_tv_number_chk __ARGS((typval_T *varp, int *denote));
+char_u *get_tv_string_chk __ARGS((typval_T *varp));
+char_u *get_var_value __ARGS((char_u *name));
+void new_script_vars __ARGS((scid_T id));
+void init_var_dict __ARGS((dict_T *dict, dictitem_T *dict_var));
+void vars_clear __ARGS((hashtab_T *ht));
+void ex_echo __ARGS((exarg_T *eap));
+void ex_echohl __ARGS((exarg_T *eap));
+void ex_execute __ARGS((exarg_T *eap));
+void ex_function __ARGS((exarg_T *eap));
+void free_all_functions __ARGS((void));
+void func_dump_profile __ARGS((FILE *fd));
+char_u *get_user_func_name __ARGS((expand_T *xp, int idx));
+void ex_delfunction __ARGS((exarg_T *eap));
+void ex_return __ARGS((exarg_T *eap));
+int do_return __ARGS((exarg_T *eap, int reanimate, int is_cmd, void *rettv));
+void discard_pending_return __ARGS((void *rettv));
+char_u *get_return_cmd __ARGS((void *rettv));
+char_u *get_func_line __ARGS((int c, void *cookie, int indent));
+void func_line_start __ARGS((void *cookie));
+void func_line_exec __ARGS((void *cookie));
+void func_line_end __ARGS((void *cookie));
+int func_has_ended __ARGS((void *cookie));
+int func_has_abort __ARGS((void *cookie));
+int read_viminfo_varlist __ARGS((vir_T *virp, int writing));
+void write_viminfo_varlist __ARGS((FILE *fp));
+int store_session_globals __ARGS((FILE *fd));
+void last_set_msg __ARGS((scid_T scriptID));
+int modify_fname __ARGS((char_u *src, int *usedlen, char_u **fnamep, char_u **bufp, int *fnamelen));
+char_u *do_string_sub __ARGS((char_u *str, char_u *pat, char_u *sub, char_u *flags));
+/* vim: set ft=c : */
--- /dev/null
+++ b/proto/ex_cmds.pro
@@ -1,0 +1,59 @@
+/* ex_cmds.c */
+void do_ascii __ARGS((exarg_T *eap));
+void ex_align __ARGS((exarg_T *eap));
+void ex_sort __ARGS((exarg_T *eap));
+void ex_retab __ARGS((exarg_T *eap));
+int do_move __ARGS((linenr_T line1, linenr_T line2, linenr_T dest));
+void ex_copy __ARGS((linenr_T line1, linenr_T line2, linenr_T n));
+void free_prev_shellcmd __ARGS((void));
+void do_bang __ARGS((int addr_count, exarg_T *eap, int forceit, int do_in, int do_out));
+void do_shell __ARGS((char_u *cmd, int flags));
+char_u *make_filter_cmd __ARGS((char_u *cmd, char_u *itmp, char_u *otmp));
+void append_redir __ARGS((char_u *buf, char_u *opt, char_u *fname));
+int viminfo_error __ARGS((char *errnum, char *message, char_u *line));
+int read_viminfo __ARGS((char_u *file, int want_info, int want_marks, int forceit));
+void write_viminfo __ARGS((char_u *file, int forceit));
+int viminfo_readline __ARGS((vir_T *virp));
+char_u *viminfo_readstring __ARGS((vir_T *virp, int off, int convert));
+void viminfo_writestring __ARGS((FILE *fd, char_u *p));
+void do_fixdel __ARGS((exarg_T *eap));
+void print_line_no_prefix __ARGS((linenr_T lnum, int use_number, int list));
+void print_line __ARGS((linenr_T lnum, int use_number, int list));
+void ex_file __ARGS((exarg_T *eap));
+void ex_update __ARGS((exarg_T *eap));
+void ex_write __ARGS((exarg_T *eap));
+int do_write __ARGS((exarg_T *eap));
+void ex_wnext __ARGS((exarg_T *eap));
+void do_wqall __ARGS((exarg_T *eap));
+int not_writing __ARGS((void));
+int getfile __ARGS((int fnum, char_u *ffname, char_u *sfname, int setpm, linenr_T lnum, int forceit));
+int do_ecmd __ARGS((int fnum, char_u *ffname, char_u *sfname, exarg_T *eap, linenr_T newlnum, int flags));
+void ex_append __ARGS((exarg_T *eap));
+void ex_change __ARGS((exarg_T *eap));
+void ex_z __ARGS((exarg_T *eap));
+int check_restricted __ARGS((void));
+int check_secure __ARGS((void));
+void do_sub __ARGS((exarg_T *eap));
+int do_sub_msg __ARGS((int count_only));
+void ex_global __ARGS((exarg_T *eap));
+void global_exe __ARGS((char_u *cmd));
+int read_viminfo_sub_string __ARGS((vir_T *virp, int force));
+void write_viminfo_sub_string __ARGS((FILE *fp));
+void free_old_sub __ARGS((void));
+int prepare_tagpreview __ARGS((int undo_sync));
+void ex_help __ARGS((exarg_T *eap));
+char_u *check_help_lang __ARGS((char_u *arg));
+int help_heuristic __ARGS((char_u *matched_string, int offset, int wrong_case));
+int find_help_tags __ARGS((char_u *arg, int *num_matches, char_u ***matches, int keep_lang));
+void fix_help_buffer __ARGS((void));
+void ex_exusage __ARGS((exarg_T *eap));
+void ex_viusage __ARGS((exarg_T *eap));
+void ex_helptags __ARGS((exarg_T *eap));
+void ex_sign __ARGS((exarg_T *eap));
+void sign_gui_started __ARGS((void));
+int sign_get_attr __ARGS((int typenr, int line));
+char_u *sign_get_text __ARGS((int typenr));
+void *sign_get_image __ARGS((int typenr));
+char_u *sign_typenr2name __ARGS((int typenr));
+void ex_drop __ARGS((exarg_T *eap));
+/* vim: set ft=c : */
--- /dev/null
+++ b/proto/ex_cmds2.pro
@@ -1,0 +1,83 @@
+/* ex_cmds2.c */
+void do_debug __ARGS((char_u *cmd));
+void ex_debug __ARGS((exarg_T *eap));
+void dbg_check_breakpoint __ARGS((exarg_T *eap));
+int dbg_check_skipped __ARGS((exarg_T *eap));
+void ex_breakadd __ARGS((exarg_T *eap));
+void ex_debuggreedy __ARGS((exarg_T *eap));
+void ex_breakdel __ARGS((exarg_T *eap));
+void ex_breaklist __ARGS((exarg_T *eap));
+linenr_T dbg_find_breakpoint __ARGS((int file, char_u *fname, linenr_T after));
+int has_profiling __ARGS((int file, char_u *fname, int *fp));
+void dbg_breakpoint __ARGS((char_u *name, linenr_T lnum));
+void profile_start __ARGS((proftime_T *tm));
+void profile_end __ARGS((proftime_T *tm));
+void profile_sub __ARGS((proftime_T *tm, proftime_T *tm2));
+char *profile_msg __ARGS((proftime_T *tm));
+void profile_zero __ARGS((proftime_T *tm));
+void profile_add __ARGS((proftime_T *tm, proftime_T *tm2));
+void profile_self __ARGS((proftime_T *self, proftime_T *total, proftime_T *children));
+void profile_get_wait __ARGS((proftime_T *tm));
+void profile_sub_wait __ARGS((proftime_T *tm, proftime_T *tma));
+int profile_equal __ARGS((proftime_T *tm1, proftime_T *tm2));
+int profile_cmp __ARGS((proftime_T *tm1, proftime_T *tm2));
+void ex_profile __ARGS((exarg_T *eap));
+void profile_dump __ARGS((void));
+void script_prof_save __ARGS((proftime_T *tm));
+void script_prof_restore __ARGS((proftime_T *tm));
+void prof_inchar_enter __ARGS((void));
+void prof_inchar_exit __ARGS((void));
+int prof_def_func __ARGS((void));
+int autowrite __ARGS((buf_T *buf, int forceit));
+void autowrite_all __ARGS((void));
+int check_changed __ARGS((buf_T *buf, int checkaw, int mult_win, int forceit, int allbuf));
+void browse_save_fname __ARGS((buf_T *buf));
+void dialog_changed __ARGS((buf_T *buf, int checkall));
+int can_abandon __ARGS((buf_T *buf, int forceit));
+int check_changed_any __ARGS((int hidden));
+int check_fname __ARGS((void));
+int buf_write_all __ARGS((buf_T *buf, int forceit));
+int get_arglist __ARGS((garray_T *gap, char_u *str));
+int get_arglist_exp __ARGS((char_u *str, int *fcountp, char_u ***fnamesp));
+void set_arglist __ARGS((char_u *str));
+void check_arg_idx __ARGS((win_T *win));
+void ex_args __ARGS((exarg_T *eap));
+void ex_previous __ARGS((exarg_T *eap));
+void ex_rewind __ARGS((exarg_T *eap));
+void ex_last __ARGS((exarg_T *eap));
+void ex_argument __ARGS((exarg_T *eap));
+void do_argfile __ARGS((exarg_T *eap, int argn));
+void ex_next __ARGS((exarg_T *eap));
+void ex_argedit __ARGS((exarg_T *eap));
+void ex_argadd __ARGS((exarg_T *eap));
+void ex_argdelete __ARGS((exarg_T *eap));
+void ex_listdo __ARGS((exarg_T *eap));
+void ex_compiler __ARGS((exarg_T *eap));
+void ex_runtime __ARGS((exarg_T *eap));
+int source_runtime __ARGS((char_u *name, int all));
+int do_in_runtimepath __ARGS((char_u *name, int all, void (*callback)(char_u *fname, void *ck), void *cookie));
+void ex_options __ARGS((exarg_T *eap));
+void ex_source __ARGS((exarg_T *eap));
+linenr_T *source_breakpoint __ARGS((void *cookie));
+int *source_dbg_tick __ARGS((void *cookie));
+int source_level __ARGS((void *cookie));
+int do_source __ARGS((char_u *fname, int check_other, int is_vimrc));
+void ex_scriptnames __ARGS((exarg_T *eap));
+void scriptnames_slash_adjust __ARGS((void));
+char_u *get_scriptname __ARGS((scid_T id));
+void free_scriptnames __ARGS((void));
+char *fgets_cr __ARGS((char *s, int n, FILE *stream));
+char_u *getsourceline __ARGS((int c, void *cookie, int indent));
+void script_line_start __ARGS((void));
+void script_line_exec __ARGS((void));
+void script_line_end __ARGS((void));
+void ex_scriptencoding __ARGS((exarg_T *eap));
+void ex_finish __ARGS((exarg_T *eap));
+void do_finish __ARGS((exarg_T *eap, int reanimate));
+int source_finished __ARGS((char_u *(*fgetline)(int, void *, int), void *cookie));
+void ex_checktime __ARGS((exarg_T *eap));
+char_u *get_mess_lang __ARGS((void));
+void set_lang_var __ARGS((void));
+void ex_language __ARGS((exarg_T *eap));
+char_u *get_lang_arg __ARGS((expand_T *xp, int idx));
+/* vim: set ft=c : */
--- /dev/null
+++ b/proto/ex_docmd.pro
@@ -1,0 +1,52 @@
+/* ex_docmd.c */
+void do_exmode __ARGS((int improved));
+int do_cmdline_cmd __ARGS((char_u *cmd));
+int do_cmdline __ARGS((char_u *cmdline, char_u *(*getline)(int, void *, int), void *cookie, int flags));
+int getline_equal __ARGS((char_u *(*fgetline)(int, void *, int), void *cookie, char_u *(*func)(int, void *, int)));
+void *getline_cookie __ARGS((char_u *(*fgetline)(int, void *, int), void *cookie));
+int checkforcmd __ARGS((char_u **pp, char *cmd, int len));
+int cmd_exists __ARGS((char_u *name));
+char_u *set_one_cmd_context __ARGS((expand_T *xp, char_u *buff));
+char_u *skip_range __ARGS((char_u *cmd, int *ctx));
+void ex_ni __ARGS((exarg_T *eap));
+int expand_filename __ARGS((exarg_T *eap, char_u **cmdlinep, char_u **errormsgp));
+void separate_nextcmd __ARGS((exarg_T *eap));
+int ends_excmd __ARGS((int c));
+char_u *find_nextcmd __ARGS((char_u *p));
+char_u *check_nextcmd __ARGS((char_u *p));
+char_u *get_command_name __ARGS((expand_T *xp, int idx));
+void ex_comclear __ARGS((exarg_T *eap));
+void uc_clear __ARGS((garray_T *gap));
+char_u *get_user_commands __ARGS((expand_T *xp, int idx));
+char_u *get_user_cmd_flags __ARGS((expand_T *xp, int idx));
+char_u *get_user_cmd_nargs __ARGS((expand_T *xp, int idx));
+char_u *get_user_cmd_complete __ARGS((expand_T *xp, int idx));
+int parse_compl_arg __ARGS((char_u *value, int vallen, int *complp, long *argt, char_u **compl_arg));
+void not_exiting __ARGS((void));
+void tabpage_close __ARGS((int forceit));
+void tabpage_close_other __ARGS((tabpage_T *tp, int forceit));
+void ex_all __ARGS((exarg_T *eap));
+void handle_drop __ARGS((int filec, char_u **filev, int split));
+void alist_clear __ARGS((alist_T *al));
+void alist_init __ARGS((alist_T *al));
+void alist_unlink __ARGS((alist_T *al));
+void alist_new __ARGS((void));
+void alist_expand __ARGS((int *fnum_list, int fnum_len));
+void alist_set __ARGS((alist_T *al, int count, char_u **files, int use_curbuf, int *fnum_list, int fnum_len));
+void alist_add __ARGS((alist_T *al, char_u *fname, int set_fnum));
+void alist_slash_adjust __ARGS((void));
+void ex_splitview __ARGS((exarg_T *eap));
+void tabpage_new __ARGS((void));
+void do_exedit __ARGS((exarg_T *eap, win_T *old_curwin));
+void free_cd_dir __ARGS((void));
+void do_sleep __ARGS((long msec));
+int vim_mkdir_emsg __ARGS((char_u *name, int prot));
+FILE *open_exfile __ARGS((char_u *fname, int forceit, char *mode));
+void update_topline_cursor __ARGS((void));
+void exec_normal_cmd __ARGS((char_u *cmd, int remap, int silent));
+char_u *eval_vars __ARGS((char_u *src, char_u *srcstart, int *usedlen, linenr_T *lnump, char_u **errormsg, int *escaped));
+char_u *expand_sfile __ARGS((char_u *arg));
+int put_eol __ARGS((FILE *fd));
+int put_line __ARGS((FILE *fd, char *s));
+void dialog_msg __ARGS((char_u *buff, char *format, char_u *fname));
+/* vim: set ft=c : */
--- /dev/null
+++ b/proto/ex_eval.pro
@@ -1,0 +1,32 @@
+/* ex_eval.c */
+int aborting __ARGS((void));
+void update_force_abort __ARGS((void));
+int should_abort __ARGS((int retcode));
+int aborted_in_try __ARGS((void));
+int cause_errthrow __ARGS((char_u *mesg, int severe, int *ignore));
+void do_errthrow __ARGS((struct condstack *cstack, char_u *cmdname));
+int do_intthrow __ARGS((struct condstack *cstack));
+void discard_current_exception __ARGS((void));
+void report_make_pending __ARGS((int pending, void *value));
+void report_resume_pending __ARGS((int pending, void *value));
+void report_discard_pending __ARGS((int pending, void *value));
+void ex_if __ARGS((exarg_T *eap));
+void ex_endif __ARGS((exarg_T *eap));
+void ex_else __ARGS((exarg_T *eap));
+void ex_while __ARGS((exarg_T *eap));
+void ex_continue __ARGS((exarg_T *eap));
+void ex_break __ARGS((exarg_T *eap));
+void ex_endwhile __ARGS((exarg_T *eap));
+void ex_throw __ARGS((exarg_T *eap));
+void do_throw __ARGS((struct condstack *cstack));
+void ex_try __ARGS((exarg_T *eap));
+void ex_catch __ARGS((exarg_T *eap));
+void ex_finally __ARGS((exarg_T *eap));
+void ex_endtry __ARGS((exarg_T *eap));
+void enter_cleanup __ARGS((cleanup_T *csp));
+void leave_cleanup __ARGS((cleanup_T *csp));
+int cleanup_conditionals __ARGS((struct condstack *cstack, int searched_cond, int inclusive));
+void rewind_conditionals __ARGS((struct condstack *cstack, int idx, int cond_type, int *cond_level));
+void ex_endfunction __ARGS((exarg_T *eap));
+int has_loop_cmd __ARGS((char_u *p));
+/* vim: set ft=c : */
--- /dev/null
+++ b/proto/ex_getln.pro
@@ -1,0 +1,56 @@
+/* ex_getln.c */
+char_u *getcmdline __ARGS((int firstc, long count, int indent));
+char_u *getcmdline_prompt __ARGS((int firstc, char_u *prompt, int attr, int xp_context, char_u *xp_arg));
+int text_locked __ARGS((void));
+void text_locked_msg __ARGS((void));
+int curbuf_locked __ARGS((void));
+char_u *getexline __ARGS((int c, void *dummy, int indent));
+char_u *getexmodeline __ARGS((int promptc, void *dummy, int indent));
+int cmdline_overstrike __ARGS((void));
+int cmdline_at_end __ARGS((void));
+colnr_T cmdline_getvcol_cursor __ARGS((void));
+void free_cmdline_buf __ARGS((void));
+void putcmdline __ARGS((int c, int shift));
+void unputcmdline __ARGS((void));
+int put_on_cmdline __ARGS((char_u *str, int len, int redraw));
+char_u *save_cmdline_alloc __ARGS((void));
+void restore_cmdline_alloc __ARGS((char_u *p));
+void cmdline_paste_str __ARGS((char_u *s, int literally));
+void redrawcmdline __ARGS((void));
+void redrawcmd __ARGS((void));
+void compute_cmdrow __ARGS((void));
+void gotocmdline __ARGS((int clr));
+char_u *ExpandOne __ARGS((expand_T *xp, char_u *str, char_u *orig, int options, int mode));
+void ExpandInit __ARGS((expand_T *xp));
+void ExpandCleanup __ARGS((expand_T *xp));
+void ExpandEscape __ARGS((expand_T *xp, char_u *str, int numfiles, char_u **files, int options));
+void tilde_replace __ARGS((char_u *orig_pat, int num_files, char_u **files));
+char_u *sm_gettail __ARGS((char_u *s));
+char_u *addstar __ARGS((char_u *fname, int len, int context));
+void set_cmd_context __ARGS((expand_T *xp, char_u *str, int len, int col));
+int expand_cmdline __ARGS((expand_T *xp, char_u *str, int col, int *matchcount, char_u ***matches));
+int ExpandGeneric __ARGS((expand_T *xp, regmatch_T *regmatch, int *num_file, char_u ***file, char_u *((*func)(expand_T *, int))));
+char_u *globpath __ARGS((char_u *path, char_u *file));
+void init_history __ARGS((void));
+int get_histtype __ARGS((char_u *name));
+void add_to_history __ARGS((int histype, char_u *new_entry, int in_map, int sep));
+int get_history_idx __ARGS((int histype));
+char_u *get_cmdline_str __ARGS((void));
+int get_cmdline_pos __ARGS((void));
+int set_cmdline_pos __ARGS((int pos));
+int get_cmdline_type __ARGS((void));
+char_u *get_history_entry __ARGS((int histype, int idx));
+int clr_history __ARGS((int histype));
+int del_history_entry __ARGS((int histype, char_u *str));
+int del_history_idx __ARGS((int histype, int idx));
+void remove_key_from_history __ARGS((void));
+int get_list_range __ARGS((char_u **str, int *num1, int *num2));
+void ex_history __ARGS((exarg_T *eap));
+void prepare_viminfo_history __ARGS((int asklen));
+int read_viminfo_history __ARGS((vir_T *virp));
+void finish_viminfo_history __ARGS((void));
+void write_viminfo_history __ARGS((FILE *fp));
+void cmd_pchar __ARGS((int c, int offset));
+int cmd_gchar __ARGS((int offset));
+char_u *script_get __ARGS((exarg_T *eap, char_u *cmd));
+/* vim: set ft=c : */
--- /dev/null
+++ b/proto/fileio.pro
@@ -1,0 +1,51 @@
+/* fileio.c */
+void filemess __ARGS((buf_T *buf, char_u *name, char_u *s, int attr));
+int readfile __ARGS((char_u *fname, char_u *sfname, linenr_T from, linenr_T lines_to_skip, linenr_T lines_to_read, exarg_T *eap, int flags));
+int prep_exarg __ARGS((exarg_T *eap, buf_T *buf));
+int buf_write __ARGS((buf_T *buf, char_u *fname, char_u *sfname, linenr_T start, linenr_T end, exarg_T *eap, int append, int forceit, int reset_changed, int filtering));
+void msg_add_fname __ARGS((buf_T *buf, char_u *fname));
+void msg_add_lines __ARGS((int insert_space, long lnum, long nchars));
+char_u *shorten_fname __ARGS((char_u *full_path, char_u *dir_name));
+void shorten_fnames __ARGS((int force));
+void shorten_filenames __ARGS((char_u **fnames, int count));
+char_u *modname __ARGS((char_u *fname, char_u *ext, int prepend_dot));
+char_u *buf_modname __ARGS((int shortname, char_u *fname, char_u *ext, int prepend_dot));
+int vim_fgets __ARGS((char_u *buf, int size, FILE *fp));
+int tag_fgets __ARGS((char_u *buf, int size, FILE *fp));
+int vim_rename __ARGS((char_u *from, char_u *to));
+int check_timestamps __ARGS((int focus));
+int buf_check_timestamp __ARGS((buf_T *buf, int focus));
+void buf_reload __ARGS((buf_T *buf, int orig_mode));
+void buf_store_time __ARGS((buf_T *buf, struct stat *st, char_u *fname));
+void write_lnum_adjust __ARGS((linenr_T offset));
+void vim_deltempdir __ARGS((void));
+char_u *vim_tempname __ARGS((int extra_char));
+void forward_slash __ARGS((char_u *fname));
+void aubuflocal_remove __ARGS((buf_T *buf));
+int au_has_group __ARGS((char_u *name));
+void do_augroup __ARGS((char_u *arg, int del_group));
+void free_all_autocmds __ARGS((void));
+int check_ei __ARGS((void));
+char_u *au_event_disable __ARGS((char *what));
+void au_event_restore __ARGS((char_u *old_ei));
+void do_autocmd __ARGS((char_u *arg, int forceit));
+int do_doautocmd __ARGS((char_u *arg, int do_msg));
+void ex_doautoall __ARGS((exarg_T *eap));
+void aucmd_prepbuf __ARGS((aco_save_T *aco, buf_T *buf));
+void aucmd_restbuf __ARGS((aco_save_T *aco));
+int apply_autocmds __ARGS((event_T event, char_u *fname, char_u *fname_io, int force, buf_T *buf));
+int apply_autocmds_retval __ARGS((event_T event, char_u *fname, char_u *fname_io, int force, buf_T *buf, int *retval));
+int has_cursorhold __ARGS((void));
+int trigger_cursorhold __ARGS((void));
+int has_cursormoved __ARGS((void));
+int has_cursormovedI __ARGS((void));
+int has_autocmd __ARGS((event_T event, char_u *sfname, buf_T *buf));
+char_u *get_augroup_name __ARGS((expand_T *xp, int idx));
+char_u *set_context_in_autocmd __ARGS((expand_T *xp, char_u *arg, int doautocmd));
+char_u *get_event_name __ARGS((expand_T *xp, int idx));
+int autocmd_supported __ARGS((char_u *name));
+int au_exists __ARGS((char_u *arg));
+int match_file_pat __ARGS((char_u *pattern, regprog_T *prog, char_u *fname, char_u *sfname, char_u *tail, int allow_dirs));
+int match_file_list __ARGS((char_u *list, char_u *sfname, char_u *ffname));
+char_u *file_pat_to_reg_pat __ARGS((char_u *pat, char_u *pat_end, char *allow_dirs, int no_bslash));
+/* vim: set ft=c : */
--- /dev/null
+++ b/proto/fold.pro
@@ -1,0 +1,41 @@
+/* fold.c */
+void copyFoldingState __ARGS((win_T *wp_from, win_T *wp_to));
+int hasAnyFolding __ARGS((win_T *win));
+int hasFolding __ARGS((linenr_T lnum, linenr_T *firstp, linenr_T *lastp));
+int hasFoldingWin __ARGS((win_T *win, linenr_T lnum, linenr_T *firstp, linenr_T *lastp, int cache, foldinfo_T *infop));
+int foldLevel __ARGS((linenr_T lnum));
+int lineFolded __ARGS((win_T *win, linenr_T lnum));
+long foldedCount __ARGS((win_T *win, linenr_T lnum, foldinfo_T *infop));
+int foldmethodIsManual __ARGS((win_T *wp));
+int foldmethodIsIndent __ARGS((win_T *wp));
+int foldmethodIsExpr __ARGS((win_T *wp));
+int foldmethodIsMarker __ARGS((win_T *wp));
+int foldmethodIsSyntax __ARGS((win_T *wp));
+int foldmethodIsDiff __ARGS((win_T *wp));
+void closeFold __ARGS((linenr_T lnum, long count));
+void closeFoldRecurse __ARGS((linenr_T lnum));
+void opFoldRange __ARGS((linenr_T first, linenr_T last, int opening, int recurse, int had_visual));
+void openFold __ARGS((linenr_T lnum, long count));
+void openFoldRecurse __ARGS((linenr_T lnum));
+void foldOpenCursor __ARGS((void));
+void newFoldLevel __ARGS((void));
+void foldCheckClose __ARGS((void));
+int foldManualAllowed __ARGS((int create));
+void foldCreate __ARGS((linenr_T start, linenr_T end));
+void deleteFold __ARGS((linenr_T start, linenr_T end, int recursive, int had_visual));
+void clearFolding __ARGS((win_T *win));
+void foldUpdate __ARGS((win_T *wp, linenr_T top, linenr_T bot));
+void foldUpdateAll __ARGS((win_T *win));
+int foldMoveTo __ARGS((int updown, int dir, long count));
+void foldInitWin __ARGS((win_T *newwin));
+int find_wl_entry __ARGS((win_T *win, linenr_T lnum));
+void foldAdjustVisual __ARGS((void));
+void foldAdjustCursor __ARGS((void));
+void cloneFoldGrowArray __ARGS((garray_T *from, garray_T *to));
+void deleteFoldRecurse __ARGS((garray_T *gap));
+void foldMarkAdjust __ARGS((win_T *wp, linenr_T line1, linenr_T line2, long amount, long amount_after));
+int getDeepestNesting __ARGS((void));
+char_u *get_foldtext __ARGS((win_T *wp, linenr_T lnum, linenr_T lnume, foldinfo_T *foldinfo, char_u *buf));
+void foldtext_cleanup __ARGS((char_u *str));
+int put_folds __ARGS((FILE *fd, win_T *wp));
+/* vim: set ft=c : */
--- /dev/null
+++ b/proto/getchar.pro
@@ -1,0 +1,66 @@
+/* getchar.c */
+void free_buff __ARGS((struct buffheader *buf));
+char_u *get_recorded __ARGS((void));
+char_u *get_inserted __ARGS((void));
+int stuff_empty __ARGS((void));
+void typeahead_noflush __ARGS((int c));
+void flush_buffers __ARGS((int typeahead));
+void ResetRedobuff __ARGS((void));
+void saveRedobuff __ARGS((void));
+void restoreRedobuff __ARGS((void));
+void AppendToRedobuff __ARGS((char_u *s));
+void AppendToRedobuffLit __ARGS((char_u *str, int len));
+void AppendCharToRedobuff __ARGS((int c));
+void AppendNumberToRedobuff __ARGS((long n));
+void stuffReadbuff __ARGS((char_u *s));
+void stuffReadbuffLen __ARGS((char_u *s, long len));
+void stuffReadbuffSpec __ARGS((char_u *s));
+void stuffcharReadbuff __ARGS((int c));
+void stuffnumReadbuff __ARGS((long n));
+int start_redo __ARGS((long count, int old_redo));
+int start_redo_ins __ARGS((void));
+void stop_redo_ins __ARGS((void));
+int ins_typebuf __ARGS((char_u *str, int noremap, int offset, int nottyped, int silent));
+void ins_char_typebuf __ARGS((int c));
+int typebuf_changed __ARGS((int tb_change_cnt));
+int typebuf_typed __ARGS((void));
+int typebuf_maplen __ARGS((void));
+void del_typebuf __ARGS((int len, int offset));
+int alloc_typebuf __ARGS((void));
+void free_typebuf __ARGS((void));
+int save_typebuf __ARGS((void));
+void save_typeahead __ARGS((tasave_T *tp));
+void restore_typeahead __ARGS((tasave_T *tp));
+void openscript __ARGS((char_u *name, int directly));
+void close_all_scripts __ARGS((void));
+int using_script __ARGS((void));
+void before_blocking __ARGS((void));
+void updatescript __ARGS((int c));
+int vgetc __ARGS((void));
+int safe_vgetc __ARGS((void));
+int vpeekc __ARGS((void));
+int vpeekc_nomap __ARGS((void));
+int vpeekc_any __ARGS((void));
+int char_avail __ARGS((void));
+void vungetc __ARGS((int c));
+int inchar __ARGS((char_u *buf, int maxlen, long wait_time, int tb_change_cnt));
+int fix_input_buffer __ARGS((char_u *buf, int len, int script));
+int input_available __ARGS((void));
+int do_map __ARGS((int maptype, char_u *arg, int mode, int abbrev));
+int get_map_mode __ARGS((char_u **cmdp, int forceit));
+void map_clear __ARGS((char_u *cmdp, char_u *arg, int forceit, int abbr));
+void map_clear_int __ARGS((buf_T *buf, int mode, int local, int abbr));
+int map_to_exists __ARGS((char_u *str, char_u *modechars, int abbr));
+int map_to_exists_mode __ARGS((char_u *rhs, int mode, int abbr));
+char_u *set_context_in_map_cmd __ARGS((expand_T *xp, char_u *cmd, char_u *arg, int forceit, int isabbrev, int isunmap, cmdidx_T cmdidx));
+int ExpandMappings __ARGS((regmatch_T *regmatch, int *num_file, char_u ***file));
+int check_abbr __ARGS((int c, char_u *ptr, int col, int mincol));
+char_u *vim_strsave_escape_csi __ARGS((char_u *p));
+void vim_unescape_csi __ARGS((char_u *p));
+int makemap __ARGS((FILE *fd, buf_T *buf));
+int put_escstr __ARGS((FILE *fd, char_u *strstart, int what));
+void check_map_keycodes __ARGS((void));
+char_u *check_map __ARGS((char_u *keys, int mode, int exact, int ign_mod, int abbr));
+void init_mappings __ARGS((void));
+void add_map __ARGS((char_u *map, int mode));
+/* vim: set ft=c : */
--- /dev/null
+++ b/proto/gui.pro
@@ -1,0 +1,65 @@
+/* gui.c */
+void gui_start __ARGS((void));
+void gui_prepare __ARGS((int *argc, char **argv));
+int gui_init_check __ARGS((void));
+void gui_init __ARGS((void));
+void gui_exit __ARGS((int rc));
+void gui_shell_closed __ARGS((void));
+int gui_init_font __ARGS((char_u *font_list, int fontset));
+int gui_get_wide_font __ARGS((void));
+void gui_set_cursor __ARGS((int row, int col));
+void gui_update_cursor __ARGS((int force, int clear_selection));
+void gui_position_menu __ARGS((void));
+int gui_get_base_width __ARGS((void));
+int gui_get_base_height __ARGS((void));
+void gui_resize_shell __ARGS((int pixel_width, int pixel_height));
+void gui_may_resize_shell __ARGS((void));
+int gui_get_shellsize __ARGS((void));
+void gui_set_shellsize __ARGS((int mustset, int fit_to_display, int direction));
+void gui_new_shellsize __ARGS((void));
+void gui_reset_scroll_region __ARGS((void));
+void gui_start_highlight __ARGS((int mask));
+void gui_stop_highlight __ARGS((int mask));
+void gui_clear_block __ARGS((int row1, int col1, int row2, int col2));
+void gui_update_cursor_later __ARGS((void));
+void gui_write __ARGS((char_u *s, int len));
+void gui_dont_update_cursor __ARGS((void));
+void gui_can_update_cursor __ARGS((void));
+int gui_outstr_nowrap __ARGS((char_u *s, int len, int flags, guicolor_T fg, guicolor_T bg, int back));
+void gui_undraw_cursor __ARGS((void));
+void gui_redraw __ARGS((int x, int y, int w, int h));
+int gui_redraw_block __ARGS((int row1, int col1, int row2, int col2, int flags));
+int gui_wait_for_chars __ARGS((long wtime));
+void gui_send_mouse_event __ARGS((int button, int x, int y, int repeated_click, int_u modifiers));
+int gui_xy2colrow __ARGS((int x, int y, int *colp));
+void gui_menu_cb __ARGS((vimmenu_T *menu));
+void gui_init_which_components __ARGS((char_u *oldval));
+int gui_use_tabline __ARGS((void));
+void gui_update_tabline __ARGS((void));
+void get_tabline_label __ARGS((tabpage_T *tp, int tooltip));
+int send_tabline_event __ARGS((int nr));
+void send_tabline_menu_event __ARGS((int tabidx, int event));
+void gui_remove_scrollbars __ARGS((void));
+void gui_create_scrollbar __ARGS((scrollbar_T *sb, int type, win_T *wp));
+scrollbar_T *gui_find_scrollbar __ARGS((long ident));
+void gui_drag_scrollbar __ARGS((scrollbar_T *sb, long value, int still_dragging));
+void gui_update_scrollbars __ARGS((int force));
+int gui_do_scroll __ARGS((void));
+int gui_do_horiz_scroll __ARGS((void));
+void gui_check_colors __ARGS((void));
+guicolor_T gui_get_color __ARGS((char_u *name));
+int gui_get_lightness __ARGS((guicolor_T pixel));
+void gui_new_scrollbar_colors __ARGS((void));
+void gui_focus_change __ARGS((int in_focus));
+void gui_mouse_moved __ARGS((int x, int y));
+void gui_mouse_correct __ARGS((void));
+void ex_gui __ARGS((exarg_T *eap));
+int gui_find_bitmap __ARGS((char_u *name, char_u *buffer, char *ext));
+void gui_find_iconfile __ARGS((char_u *name, char_u *buffer, char *ext));
+void display_errors __ARGS((void));
+int no_console_input __ARGS((void));
+void gui_update_screen __ARGS((void));
+char_u *get_find_dialog_text __ARGS((char_u *arg, int *wwordp, int *mcasep));
+int gui_do_findrepl __ARGS((int flags, char_u *find_text, char_u *repl_text, int down));
+void gui_handle_drop __ARGS((int x, int y, int_u modifiers, char_u **fnames, int count));
+/* vim: set ft=c : */
--- /dev/null
+++ b/proto/gui_beval.pro
@@ -1,0 +1,11 @@
+/* gui_beval.c */
+void general_beval_cb __ARGS((BalloonEval *beval, int state));
+BalloonEval *gui_mch_create_beval_area __ARGS((void *target, char_u *mesg, void (*mesgCB)(BalloonEval *, int), void *clientData));
+void gui_mch_destroy_beval_area __ARGS((BalloonEval *beval));
+void gui_mch_enable_beval_area __ARGS((BalloonEval *beval));
+void gui_mch_disable_beval_area __ARGS((BalloonEval *beval));
+BalloonEval *gui_mch_currently_showing_beval __ARGS((void));
+int get_beval_info __ARGS((BalloonEval *beval, int getword, win_T **winp, linenr_T *lnump, char_u **textp, int *colp));
+void gui_mch_post_balloon __ARGS((BalloonEval *beval, char_u *mesg));
+void gui_mch_unpost_balloon __ARGS((BalloonEval *beval));
+/* vim: set ft=c : */
--- /dev/null
+++ b/proto/hardcopy.pro
@@ -1,0 +1,20 @@
+/* hardcopy.c */
+char_u *parse_printoptions __ARGS((void));
+char_u *parse_printmbfont __ARGS((void));
+int prt_header_height __ARGS((void));
+int prt_use_number __ARGS((void));
+int prt_get_unit __ARGS((int idx));
+void ex_hardcopy __ARGS((exarg_T *eap));
+void mch_print_cleanup __ARGS((void));
+int mch_print_init __ARGS((prt_settings_T *psettings, char_u *jobname, int forceit));
+int mch_print_begin __ARGS((prt_settings_T *psettings));
+void mch_print_end __ARGS((prt_settings_T *psettings));
+int mch_print_end_page __ARGS((void));
+int mch_print_begin_page __ARGS((char_u *str));
+int mch_print_blank_page __ARGS((void));
+void mch_print_start_line __ARGS((int margin, int page_line));
+int mch_print_text_out __ARGS((char_u *p, int len));
+void mch_print_set_font __ARGS((int iBold, int iItalic, int iUnderline));
+void mch_print_set_bg __ARGS((long_u bgcol));
+void mch_print_set_fg __ARGS((long_u fgcol));
+/* vim: set ft=c : */
--- /dev/null
+++ b/proto/hashtab.pro
@@ -1,0 +1,14 @@
+/* hashtab.c */
+void hash_init __ARGS((hashtab_T *ht));
+void hash_clear __ARGS((hashtab_T *ht));
+void hash_clear_all __ARGS((hashtab_T *ht, int off));
+hashitem_T *hash_find __ARGS((hashtab_T *ht, char_u *key));
+hashitem_T *hash_lookup __ARGS((hashtab_T *ht, char_u *key, hash_T hash));
+void hash_debug_results __ARGS((void));
+int hash_add __ARGS((hashtab_T *ht, char_u *key));
+int hash_add_item __ARGS((hashtab_T *ht, hashitem_T *hi, char_u *key, hash_T hash));
+void hash_remove __ARGS((hashtab_T *ht, hashitem_T *hi));
+void hash_lock __ARGS((hashtab_T *ht));
+void hash_unlock __ARGS((hashtab_T *ht));
+hash_T hash_hash __ARGS((char_u *key));
+/* vim: set ft=c : */
--- /dev/null
+++ b/proto/main.pro
@@ -1,0 +1,26 @@
+/* main.c */
+void main_loop __ARGS((int cmdwin, int noexmode));
+void getout_preserve_modified __ARGS((int exitval));
+void getout __ARGS((int exitval));
+int process_env __ARGS((char_u *env, int is_viminit));
+void mainerr_arg_missing __ARGS((char_u *str));
+void time_push __ARGS((void *tv_rel, void *tv_start));
+void time_pop __ARGS((void *tp));
+void time_msg __ARGS((char *msg, void *tv_start));
+void server_to_input_buf __ARGS((char_u *str));
+char_u *eval_client_expr_to_string __ARGS((char_u *expr));
+char_u *serverConvert __ARGS((char_u *client_enc, char_u *data, char_u **tofree));
+int toF_TyA __ARGS((int c));
+int fkmap __ARGS((int c));
+void conv_to_pvim __ARGS((void));
+void conv_to_pstd __ARGS((void));
+char_u *lrswap __ARGS((char_u *ibuf));
+char_u *lrFswap __ARGS((char_u *cmdbuf, int len));
+char_u *lrF_sub __ARGS((char_u *ibuf));
+int cmdl_fkmap __ARGS((int c));
+int F_isalpha __ARGS((int c));
+int F_isdigit __ARGS((int c));
+int F_ischar __ARGS((int c));
+void farsi_fkey __ARGS((cmdarg_T *cap));
+int arabic_shape __ARGS((int c, int *ccp, int *c1p, int prev_c, int prev_c1, int next_c));
+/* vim: set ft=c : */
--- /dev/null
+++ b/proto/mark.pro
@@ -1,0 +1,30 @@
+/* mark.c */
+int setmark __ARGS((int c));
+int setmark_pos __ARGS((int c, pos_T *pos, int fnum));
+void setpcmark __ARGS((void));
+void checkpcmark __ARGS((void));
+pos_T *movemark __ARGS((int count));
+pos_T *movechangelist __ARGS((int count));
+pos_T *getmark __ARGS((int c, int changefile));
+pos_T *getmark_fnum __ARGS((int c, int changefile, int *fnum));
+pos_T *getnextmark __ARGS((pos_T *startpos, int dir, int begin_line));
+void fmarks_check_names __ARGS((buf_T *buf));
+int check_mark __ARGS((pos_T *pos));
+void clrallmarks __ARGS((buf_T *buf));
+char_u *fm_getname __ARGS((fmark_T *fmark, int lead_len));
+void do_marks __ARGS((exarg_T *eap));
+void ex_delmarks __ARGS((exarg_T *eap));
+void ex_jumps __ARGS((exarg_T *eap));
+void ex_changes __ARGS((exarg_T *eap));
+void mark_adjust __ARGS((linenr_T line1, linenr_T line2, long amount, long amount_after));
+void mark_col_adjust __ARGS((linenr_T lnum, colnr_T mincol, long lnum_amount, long col_amount));
+void copy_jumplist __ARGS((win_T *from, win_T *to));
+void free_jumplist __ARGS((win_T *wp));
+void set_last_cursor __ARGS((win_T *win));
+void free_all_marks __ARGS((void));
+int read_viminfo_filemark __ARGS((vir_T *virp, int force));
+void write_viminfo_filemarks __ARGS((FILE *fp));
+int removable __ARGS((char_u *name));
+int write_viminfo_marks __ARGS((FILE *fp_out));
+void copy_viminfo_marks __ARGS((vir_T *virp, FILE *fp_out, int count, int eof));
+/* vim: set ft=c : */
--- /dev/null
+++ b/proto/mbyte.pro
@@ -1,0 +1,91 @@
+/* mbyte.c */
+int enc_canon_props __ARGS((char_u *name));
+char_u *mb_init __ARGS((void));
+int bomb_size __ARGS((void));
+int mb_get_class __ARGS((char_u *p));
+int dbcs_class __ARGS((unsigned lead, unsigned trail));
+int latin_char2len __ARGS((int c));
+int latin_char2bytes __ARGS((int c, char_u *buf));
+int latin_ptr2len __ARGS((char_u *p));
+int utf_char2cells __ARGS((int c));
+int latin_ptr2cells __ARGS((char_u *p));
+int utf_ptr2cells __ARGS((char_u *p));
+int dbcs_ptr2cells __ARGS((char_u *p));
+int latin_char2cells __ARGS((int c));
+int latin_off2cells __ARGS((unsigned off));
+int dbcs_off2cells __ARGS((unsigned off));
+int utf_off2cells __ARGS((unsigned off));
+int latin_ptr2char __ARGS((char_u *p));
+int utf_ptr2char __ARGS((char_u *p));
+int mb_ptr2char_adv __ARGS((char_u **pp));
+int mb_cptr2char_adv __ARGS((char_u **pp));
+int arabic_combine __ARGS((int one, int two));
+int arabic_maycombine __ARGS((int two));
+int utf_composinglike __ARGS((char_u *p1, char_u *p2));
+int utfc_ptr2char __ARGS((char_u *p, int *pcc));
+int utfc_ptr2char_len __ARGS((char_u *p, int *pcc, int maxlen));
+int utfc_char2bytes __ARGS((int off, char_u *buf));
+int utf_ptr2len __ARGS((char_u *p));
+int utf_byte2len __ARGS((int b));
+int utf_ptr2len_len __ARGS((char_u *p, int size));
+int utfc_ptr2len __ARGS((char_u *p));
+int utfc_ptr2len_len __ARGS((char_u *p, int size));
+int utf_char2len __ARGS((int c));
+int utf_char2bytes __ARGS((int c, char_u *buf));
+int utf_iscomposing __ARGS((int c));
+int utf_printable __ARGS((int c));
+int utf_class __ARGS((int c));
+int utf_fold __ARGS((int a));
+int utf_toupper __ARGS((int a));
+int utf_islower __ARGS((int a));
+int utf_tolower __ARGS((int a));
+int utf_isupper __ARGS((int a));
+int mb_strnicmp __ARGS((char_u *s1, char_u *s2, size_t nn));
+void show_utf8 __ARGS((void));
+int latin_head_off __ARGS((char_u *base, char_u *p));
+int dbcs_head_off __ARGS((char_u *base, char_u *p));
+int dbcs_screen_head_off __ARGS((char_u *base, char_u *p));
+int utf_head_off __ARGS((char_u *base, char_u *p));
+void mb_copy_char __ARGS((char_u **fp, char_u **tp));
+int mb_off_next __ARGS((char_u *base, char_u *p));
+int mb_tail_off __ARGS((char_u *base, char_u *p));
+void utf_find_illegal __ARGS((void));
+int utf_valid_string __ARGS((char_u *s, char_u *end));
+int dbcs_screen_tail_off __ARGS((char_u *base, char_u *p));
+void mb_adjust_cursor __ARGS((void));
+void mb_adjustpos __ARGS((pos_T *lp));
+char_u *mb_prevptr __ARGS((char_u *line, char_u *p));
+int mb_charlen __ARGS((char_u *str));
+int mb_charlen_len __ARGS((char_u *str, int len));
+char_u *mb_unescape __ARGS((char_u **pp));
+int mb_lefthalve __ARGS((int row, int col));
+int mb_fix_col __ARGS((int col, int row));
+char_u *enc_skip __ARGS((char_u *p));
+char_u *enc_canonize __ARGS((char_u *enc));
+char_u *enc_locale __ARGS((void));
+int encname2codepage __ARGS((char_u *name));
+void *my_iconv_open __ARGS((char_u *to, char_u *from));
+int iconv_enabled __ARGS((int verbose));
+void iconv_end __ARGS((void));
+int im_xim_isvalid_imactivate __ARGS((void));
+void im_set_active __ARGS((int active));
+void xim_set_focus __ARGS((int focus));
+void im_set_position __ARGS((int row, int col));
+void xim_set_preedit __ARGS((void));
+void xim_set_status_area __ARGS((void));
+void xim_init __ARGS((void));
+void xim_decide_input_style __ARGS((void));
+int im_get_feedback_attr __ARGS((int col));
+void xim_reset __ARGS((void));
+int xim_queue_key_press_event __ARGS((GdkEventKey *event, int down));
+void xim_init __ARGS((void));
+void im_shutdown __ARGS((void));
+int xim_get_status_area_height __ARGS((void));
+int im_get_status __ARGS((void));
+int im_is_preediting __ARGS((void));
+int convert_setup __ARGS((vimconv_T *vcp, char_u *from, char_u *to));
+int convert_input __ARGS((char_u *ptr, int len, int maxlen));
+int convert_input_safe __ARGS((char_u *ptr, int len, int maxlen, char_u **restp, int *restlenp));
+char_u *string_convert __ARGS((vimconv_T *vcp, char_u *ptr, int *lenp));
+char_u *string_convert_ext __ARGS((vimconv_T *vcp, char_u *ptr, int *lenp, int *unconvlenp));
+/* vim: set ft=c : */
--- /dev/null
+++ b/proto/memfile.pro
@@ -1,0 +1,18 @@
+/* memfile.c */
+memfile_T *mf_open __ARGS((char_u *fname, int flags));
+int mf_open_file __ARGS((memfile_T *mfp, char_u *fname));
+void mf_close __ARGS((memfile_T *mfp, int del_file));
+void mf_close_file __ARGS((buf_T *buf, int getlines));
+void mf_new_page_size __ARGS((memfile_T *mfp, unsigned new_size));
+bhdr_T *mf_new __ARGS((memfile_T *mfp, int negative, int page_count));
+bhdr_T *mf_get __ARGS((memfile_T *mfp, blocknr_T nr, int page_count));
+void mf_put __ARGS((memfile_T *mfp, bhdr_T *hp, int dirty, int infile));
+void mf_free __ARGS((memfile_T *mfp, bhdr_T *hp));
+int mf_sync __ARGS((memfile_T *mfp, int flags));
+void mf_set_dirty __ARGS((memfile_T *mfp));
+int mf_release_all __ARGS((void));
+blocknr_T mf_trans_del __ARGS((memfile_T *mfp, blocknr_T old_nr));
+void mf_set_ffname __ARGS((memfile_T *mfp));
+void mf_fullname __ARGS((memfile_T *mfp));
+int mf_need_trans __ARGS((memfile_T *mfp));
+/* vim: set ft=c : */
--- /dev/null
+++ b/proto/memline.pro
@@ -1,0 +1,33 @@
+/* memline.c */
+int ml_open __ARGS((buf_T *buf));
+void ml_setname __ARGS((buf_T *buf));
+void ml_open_files __ARGS((void));
+void ml_open_file __ARGS((buf_T *buf));
+void check_need_swap __ARGS((int newfile));
+void ml_close __ARGS((buf_T *buf, int del_file));
+void ml_close_all __ARGS((int del_file));
+void ml_close_notmod __ARGS((void));
+void ml_timestamp __ARGS((buf_T *buf));
+void ml_recover __ARGS((void));
+int recover_names __ARGS((char_u **fname, int list, int nr));
+void ml_sync_all __ARGS((int check_file, int check_char));
+void ml_preserve __ARGS((buf_T *buf, int message));
+char_u *ml_get __ARGS((linenr_T lnum));
+char_u *ml_get_pos __ARGS((pos_T *pos));
+char_u *ml_get_curline __ARGS((void));
+char_u *ml_get_cursor __ARGS((void));
+char_u *ml_get_buf __ARGS((buf_T *buf, linenr_T lnum, int will_change));
+int ml_line_alloced __ARGS((void));
+int ml_append __ARGS((linenr_T lnum, char_u *line, colnr_T len, int newfile));
+int ml_append_buf __ARGS((buf_T *buf, linenr_T lnum, char_u *line, colnr_T len, int newfile));
+int ml_replace __ARGS((linenr_T lnum, char_u *line, int copy));
+int ml_delete __ARGS((linenr_T lnum, int message));
+void ml_setmarked __ARGS((linenr_T lnum));
+linenr_T ml_firstmarked __ARGS((void));
+void ml_clearmarked __ARGS((void));
+char_u *makeswapname __ARGS((char_u *fname, char_u *ffname, buf_T *buf, char_u *dir_name));
+char_u *get_file_in_dir __ARGS((char_u *fname, char_u *dname));
+void ml_setflags __ARGS((buf_T *buf));
+long ml_find_line_or_offset __ARGS((buf_T *buf, linenr_T lnum, long *offp));
+void goto_byte __ARGS((long cnt));
+/* vim: set ft=c : */
--- /dev/null
+++ b/proto/menu.pro
@@ -1,0 +1,22 @@
+/* menu.c */
+void ex_menu __ARGS((exarg_T *eap));
+char_u *set_context_in_menu_cmd __ARGS((expand_T *xp, char_u *cmd, char_u *arg, int forceit));
+char_u *get_menu_name __ARGS((expand_T *xp, int idx));
+char_u *get_menu_names __ARGS((expand_T *xp, int idx));
+char_u *menu_name_skip __ARGS((char_u *name));
+int get_menu_index __ARGS((vimmenu_T *menu, int state));
+int menu_is_menubar __ARGS((char_u *name));
+int menu_is_popup __ARGS((char_u *name));
+int menu_is_child_of_popup __ARGS((vimmenu_T *menu));
+int menu_is_toolbar __ARGS((char_u *name));
+int menu_is_separator __ARGS((char_u *name));
+int check_menu_pointer __ARGS((vimmenu_T *root, vimmenu_T *menu_to_check));
+void gui_create_initial_menus __ARGS((vimmenu_T *menu));
+void gui_update_menus __ARGS((int modes));
+int gui_is_menu_shortcut __ARGS((int key));
+void gui_show_popupmenu __ARGS((void));
+void gui_mch_toggle_tearoffs __ARGS((int enable));
+void ex_emenu __ARGS((exarg_T *eap));
+vimmenu_T *gui_find_menu __ARGS((char_u *path_name));
+void ex_menutranslate __ARGS((exarg_T *eap));
+/* vim: set ft=c : */
--- /dev/null
+++ b/proto/message.pro
@@ -1,0 +1,71 @@
+/* message.c */
+int msg __ARGS((char_u *s));
+int verb_msg __ARGS((char_u *s));
+int msg_attr __ARGS((char_u *s, int attr));
+int msg_attr_keep __ARGS((char_u *s, int attr, int keep));
+char_u *msg_strtrunc __ARGS((char_u *s, int force));
+void trunc_string __ARGS((char_u *s, char_u *buf, int room));
+void reset_last_sourcing __ARGS((void));
+void msg_source __ARGS((int attr));
+int emsg_not_now __ARGS((void));
+int emsg __ARGS((char_u *s));
+int emsg2 __ARGS((char_u *s, char_u *a1));
+void emsg_invreg __ARGS((int name));
+char_u *msg_trunc_attr __ARGS((char_u *s, int force, int attr));
+char_u *msg_may_trunc __ARGS((int force, char_u *s));
+int delete_first_msg __ARGS((void));
+void ex_messages __ARGS((exarg_T *eap));
+void msg_end_prompt __ARGS((void));
+void wait_return __ARGS((int redraw));
+void set_keep_msg __ARGS((char_u *s, int attr));
+void set_keep_msg_from_hist __ARGS((void));
+void msg_start __ARGS((void));
+void msg_starthere __ARGS((void));
+void msg_putchar __ARGS((int c));
+void msg_putchar_attr __ARGS((int c, int attr));
+void msg_outnum __ARGS((long n));
+void msg_home_replace __ARGS((char_u *fname));
+void msg_home_replace_hl __ARGS((char_u *fname));
+int msg_outtrans __ARGS((char_u *str));
+int msg_outtrans_attr __ARGS((char_u *str, int attr));
+int msg_outtrans_len __ARGS((char_u *str, int len));
+char_u *msg_outtrans_one __ARGS((char_u *p, int attr));
+int msg_outtrans_len_attr __ARGS((char_u *msgstr, int len, int attr));
+void msg_make __ARGS((char_u *arg));
+int msg_outtrans_special __ARGS((char_u *strstart, int from));
+char_u *str2special __ARGS((char_u **sp, int from));
+void str2specialbuf __ARGS((char_u *sp, char_u *buf, int len));
+void msg_prt_line __ARGS((char_u *s, int list));
+void msg_puts __ARGS((char_u *s));
+void msg_puts_title __ARGS((char_u *s));
+void msg_puts_long_attr __ARGS((char_u *longstr, int attr));
+void msg_puts_long_len_attr __ARGS((char_u *longstr, int len, int attr));
+void msg_puts_attr __ARGS((char_u *s, int attr));
+void may_clear_sb_text __ARGS((void));
+void clear_sb_text __ARGS((void));
+void show_sb_text __ARGS((void));
+int msg_use_printf __ARGS((void));
+void mch_errmsg __ARGS((char *str));
+void mch_msg __ARGS((char *str));
+void msg_moremsg __ARGS((int full));
+void repeat_message __ARGS((void));
+void msg_clr_eos __ARGS((void));
+void msg_clr_eos_force __ARGS((void));
+void msg_clr_cmdline __ARGS((void));
+int msg_end __ARGS((void));
+void msg_check __ARGS((void));
+void verbose_enter __ARGS((void));
+void verbose_leave __ARGS((void));
+void verbose_enter_scroll __ARGS((void));
+void verbose_leave_scroll __ARGS((void));
+void verbose_stop __ARGS((void));
+int verbose_open __ARGS((void));
+void give_warning __ARGS((char_u *message, int hl));
+void msg_advance __ARGS((int col));
+int do_dialog __ARGS((int type, char_u *title, char_u *message, char_u *buttons, int dfltbutton, char_u *textfield));
+void display_confirm_msg __ARGS((void));
+int vim_dialog_yesno __ARGS((int type, char_u *title, char_u *message, int dflt));
+int vim_dialog_yesnocancel __ARGS((int type, char_u *title, char_u *message, int dflt));
+int vim_dialog_yesnoallcancel __ARGS((int type, char_u *title, char_u *message, int dflt));
+char_u *do_browse __ARGS((int flags, char_u *title, char_u *dflt, char_u *ext, char_u *initdir, char_u *filter, buf_T *buf));
+/* vim: set ft=c : */
--- /dev/null
+++ b/proto/misc1.pro
@@ -1,0 +1,95 @@
+/* misc1.c */
+int get_indent __ARGS((void));
+int get_indent_lnum __ARGS((linenr_T lnum));
+int get_indent_buf __ARGS((buf_T *buf, linenr_T lnum));
+int get_indent_str __ARGS((char_u *ptr, int ts));
+int set_indent __ARGS((int size, int flags));
+int get_number_indent __ARGS((linenr_T lnum));
+int open_line __ARGS((int dir, int flags, int old_indent));
+int get_leader_len __ARGS((char_u *line, char_u **flags, int backward));
+int plines __ARGS((linenr_T lnum));
+int plines_win __ARGS((win_T *wp, linenr_T lnum, int winheight));
+int plines_nofill __ARGS((linenr_T lnum));
+int plines_win_nofill __ARGS((win_T *wp, linenr_T lnum, int winheight));
+int plines_win_nofold __ARGS((win_T *wp, linenr_T lnum));
+int plines_win_col __ARGS((win_T *wp, linenr_T lnum, long column));
+int plines_m_win __ARGS((win_T *wp, linenr_T first, linenr_T last));
+void ins_bytes __ARGS((char_u *p));
+void ins_bytes_len __ARGS((char_u *p, int len));
+void ins_char __ARGS((int c));
+void ins_char_bytes __ARGS((char_u *buf, int charlen));
+void ins_str __ARGS((char_u *s));
+int del_char __ARGS((int fixpos));
+int del_chars __ARGS((long count, int fixpos));
+int del_bytes __ARGS((long count, int fixpos_arg, int use_delcombine));
+int truncate_line __ARGS((int fixpos));
+void del_lines __ARGS((long nlines, int undo));
+int gchar_pos __ARGS((pos_T *pos));
+int gchar_cursor __ARGS((void));
+void pchar_cursor __ARGS((int c));
+int inindent __ARGS((int extra));
+char_u *skip_to_option_part __ARGS((char_u *p));
+void changed __ARGS((void));
+void changed_bytes __ARGS((linenr_T lnum, colnr_T col));
+void appended_lines __ARGS((linenr_T lnum, long count));
+void appended_lines_mark __ARGS((linenr_T lnum, long count));
+void deleted_lines __ARGS((linenr_T lnum, long count));
+void deleted_lines_mark __ARGS((linenr_T lnum, long count));
+void changed_lines __ARGS((linenr_T lnum, colnr_T col, linenr_T lnume, long xtra));
+void unchanged __ARGS((buf_T *buf, int ff));
+void check_status __ARGS((buf_T *buf));
+void change_warning __ARGS((int col));
+int ask_yesno __ARGS((char_u *str, int direct));
+int get_keystroke __ARGS((void));
+int get_number __ARGS((int colon, int *mouse_used));
+int prompt_for_number __ARGS((int *mouse_used));
+void msgmore __ARGS((long n));
+void beep_flush __ARGS((void));
+void vim_beep __ARGS((void));
+void init_homedir __ARGS((void));
+void free_homedir __ARGS((void));
+void expand_env __ARGS((char_u *src, char_u *dst, int dstlen));
+void expand_env_esc __ARGS((char_u *srcp, char_u *dst, int dstlen, int esc, char_u *startstr));
+char_u *vim_getenv __ARGS((char_u *name, int *mustfree));
+char_u *expand_env_save __ARGS((char_u *src));
+void vim_setenv __ARGS((char_u *name, char_u *val));
+char_u *get_env_name __ARGS((expand_T *xp, int idx));
+void home_replace __ARGS((buf_T *buf, char_u *src, char_u *dst, int dstlen, int one));
+char_u *home_replace_save __ARGS((buf_T *buf, char_u *src));
+int fullpathcmp __ARGS((char_u *s1, char_u *s2, int checkname));
+char_u *gettail __ARGS((char_u *fname));
+char_u *gettail_sep __ARGS((char_u *fname));
+char_u *getnextcomp __ARGS((char_u *fname));
+char_u *get_past_head __ARGS((char_u *path));
+int vim_ispathsep __ARGS((int c));
+int vim_ispathlistsep __ARGS((int c));
+void shorten_dir __ARGS((char_u *str));
+int dir_of_file_exists __ARGS((char_u *fname));
+int vim_fnamecmp __ARGS((char_u *x, char_u *y));
+int vim_fnamencmp __ARGS((char_u *x, char_u *y, size_t len));
+char_u *concat_fnames __ARGS((char_u *fname1, char_u *fname2, int sep));
+char_u *concat_str __ARGS((char_u *str1, char_u *str2));
+void add_pathsep __ARGS((char_u *p));
+char_u *FullName_save __ARGS((char_u *fname, int force));
+pos_T *find_start_comment __ARGS((int ind_maxcomment));
+void do_c_expr_indent __ARGS((void));
+int cin_islabel __ARGS((int ind_maxcomment));
+int cin_iscase __ARGS((char_u *s));
+int cin_isscopedecl __ARGS((char_u *s));
+int get_c_indent __ARGS((void));
+int get_expr_indent __ARGS((void));
+int get_lisp_indent __ARGS((void));
+void prepare_to_exit __ARGS((void));
+void preserve_exit __ARGS((void));
+int vim_fexists __ARGS((char_u *fname));
+void line_breakcheck __ARGS((void));
+void fast_breakcheck __ARGS((void));
+int expand_wildcards __ARGS((int num_pat, char_u **pat, int *num_file, char_u ***file, int flags));
+int match_suffix __ARGS((char_u *fname));
+int unix_expandpath __ARGS((garray_T *gap, char_u *path, int wildoff, int flags, int didstar));
+int gen_expand_wildcards __ARGS((int num_pat, char_u **pat, int *num_file, char_u ***file, int flags));
+void addfile __ARGS((garray_T *gap, char_u *f, int flags));
+char_u *get_cmd_output __ARGS((char_u *cmd, char_u *infile, int flags));
+void FreeWild __ARGS((int count, char_u **files));
+int goto_im __ARGS((void));
+/* vim: set ft=c : */
--- /dev/null
+++ b/proto/misc2.pro
@@ -1,0 +1,100 @@
+/* misc2.c */
+int virtual_active __ARGS((void));
+int getviscol __ARGS((void));
+int getviscol2 __ARGS((colnr_T col, colnr_T coladd));
+int coladvance_force __ARGS((colnr_T wcol));
+int coladvance __ARGS((colnr_T wcol));
+int getvpos __ARGS((pos_T *pos, colnr_T wcol));
+int inc_cursor __ARGS((void));
+int inc __ARGS((pos_T *lp));
+int incl __ARGS((pos_T *lp));
+int dec_cursor __ARGS((void));
+int dec __ARGS((pos_T *lp));
+int decl __ARGS((pos_T *lp));
+void check_cursor_lnum __ARGS((void));
+void check_cursor_col __ARGS((void));
+void check_cursor __ARGS((void));
+void adjust_cursor_col __ARGS((void));
+int leftcol_changed __ARGS((void));
+void vim_mem_profile_dump __ARGS((void));
+char_u *alloc __ARGS((unsigned size));
+char_u *alloc_clear __ARGS((unsigned size));
+char_u *alloc_check __ARGS((unsigned size));
+char_u *lalloc_clear __ARGS((long_u size, int message));
+char_u *lalloc __ARGS((long_u size, int message));
+void *mem_realloc __ARGS((void *ptr, size_t size));
+void do_outofmem_msg __ARGS((long_u size));
+void free_all_mem __ARGS((void));
+char_u *vim_strsave __ARGS((char_u *string));
+char_u *vim_strnsave __ARGS((char_u *string, int len));
+char_u *vim_strsave_escaped __ARGS((char_u *string, char_u *esc_chars));
+char_u *vim_strsave_escaped_ext __ARGS((char_u *string, char_u *esc_chars, int cc, int bsl));
+char_u *vim_strsave_shellescape __ARGS((char_u *string));
+char_u *vim_strsave_up __ARGS((char_u *string));
+char_u *vim_strnsave_up __ARGS((char_u *string, int len));
+void vim_strup __ARGS((char_u *p));
+char_u *strup_save __ARGS((char_u *orig));
+void copy_spaces __ARGS((char_u *ptr, size_t count));
+void copy_chars __ARGS((char_u *ptr, size_t count, int c));
+void del_trailing_spaces __ARGS((char_u *ptr));
+void vim_strncpy __ARGS((char_u *to, char_u *from, size_t len));
+int copy_option_part __ARGS((char_u **option, char_u *buf, int maxlen, char *sep_chars));
+void vim_free __ARGS((void *x));
+int vim_stricmp __ARGS((char *s1, char *s2));
+int vim_strnicmp __ARGS((char *s1, char *s2, size_t len));
+char_u *vim_strchr __ARGS((char_u *string, int c));
+char_u *vim_strbyte __ARGS((char_u *string, int c));
+char_u *vim_strrchr __ARGS((char_u *string, int c));
+int vim_isspace __ARGS((int x));
+void ga_clear __ARGS((garray_T *gap));
+void ga_clear_strings __ARGS((garray_T *gap));
+void ga_init __ARGS((garray_T *gap));
+void ga_init2 __ARGS((garray_T *gap, int itemsize, int growsize));
+int ga_grow __ARGS((garray_T *gap, int n));
+void ga_concat __ARGS((garray_T *gap, char_u *s));
+void ga_append __ARGS((garray_T *gap, int c));
+int name_to_mod_mask __ARGS((int c));
+int simplify_key __ARGS((int key, int *modifiers));
+int handle_x_keys __ARGS((int key));
+char_u *get_special_key_name __ARGS((int c, int modifiers));
+int trans_special __ARGS((char_u **srcp, char_u *dst, int keycode));
+int find_special_key __ARGS((char_u **srcp, int *modp, int keycode));
+int extract_modifiers __ARGS((int key, int *modp));
+int find_special_key_in_table __ARGS((int c));
+int get_special_key_code __ARGS((char_u *name));
+char_u *get_key_name __ARGS((int i));
+int get_mouse_button __ARGS((int code, int *is_click, int *is_drag));
+int get_pseudo_mouse_code __ARGS((int button, int is_click, int is_drag));
+int get_fileformat __ARGS((buf_T *buf));
+int get_fileformat_force __ARGS((buf_T *buf, exarg_T *eap));
+void set_fileformat __ARGS((int t, int opt_flags));
+int default_fileformat __ARGS((void));
+int call_shell __ARGS((char_u *cmd, int opt));
+int get_real_state __ARGS((void));
+int after_pathsep __ARGS((char_u *b, char_u *p));
+int same_directory __ARGS((char_u *f1, char_u *f2));
+int vim_chdirfile __ARGS((char_u *fname));
+int illegal_slash __ARGS((char *name));
+char_u *parse_shape_opt __ARGS((int what));
+int get_shape_idx __ARGS((int mouse));
+void update_mouseshape __ARGS((int shape_idx));
+int decrypt_byte __ARGS((void));
+int update_keys __ARGS((int c));
+void crypt_init_keys __ARGS((char_u *passwd));
+char_u *get_crypt_key __ARGS((int store, int twice));
+void *vim_findfile_init __ARGS((char_u *path, char_u *filename, char_u *stopdirs, int level, int free_visited, int need_dir, void *search_ctx, int tagfile, char_u *rel_fname));
+char_u *vim_findfile_stopdir __ARGS((char_u *buf));
+void vim_findfile_cleanup __ARGS((void *ctx));
+char_u *vim_findfile __ARGS((void *search_ctx));
+void vim_findfile_free_visited __ARGS((void *search_ctx));
+char_u *find_file_in_path __ARGS((char_u *ptr, int len, int options, int first, char_u *rel_fname));
+char_u *find_directory_in_path __ARGS((char_u *ptr, int len, int options, char_u *rel_fname));
+char_u *find_file_in_path_option __ARGS((char_u *ptr, int len, int options, int first, char_u *path_option, int need_dir, char_u *rel_fname, char_u *suffixes));
+int vim_chdir __ARGS((char_u *new_dir));
+int get_user_name __ARGS((char_u *buf, int len));
+void sort_strings __ARGS((char_u **files, int count));
+int pathcmp __ARGS((const char *p, const char *q, int maxlen));
+int filewritable __ARGS((char_u *fname));
+int emsg3 __ARGS((char_u *s, char_u *a1, char_u *a2));
+int emsgn __ARGS((char_u *s, long n));
+/* vim: set ft=c : */
--- /dev/null
+++ b/proto/move.pro
@@ -1,0 +1,40 @@
+/* move.c */
+void update_topline_redraw __ARGS((void));
+void update_topline __ARGS((void));
+void update_curswant __ARGS((void));
+void check_cursor_moved __ARGS((win_T *wp));
+void changed_window_setting __ARGS((void));
+void changed_window_setting_win __ARGS((win_T *wp));
+void set_topline __ARGS((win_T *wp, linenr_T lnum));
+void changed_cline_bef_curs __ARGS((void));
+void changed_cline_bef_curs_win __ARGS((win_T *wp));
+void changed_line_abv_curs __ARGS((void));
+void changed_line_abv_curs_win __ARGS((win_T *wp));
+void validate_botline __ARGS((void));
+void invalidate_botline __ARGS((void));
+void invalidate_botline_win __ARGS((win_T *wp));
+void approximate_botline_win __ARGS((win_T *wp));
+int cursor_valid __ARGS((void));
+void validate_cursor __ARGS((void));
+void validate_cline_row __ARGS((void));
+void validate_virtcol __ARGS((void));
+void validate_virtcol_win __ARGS((win_T *wp));
+void validate_cursor_col __ARGS((void));
+int win_col_off __ARGS((win_T *wp));
+int curwin_col_off __ARGS((void));
+int win_col_off2 __ARGS((win_T *wp));
+int curwin_col_off2 __ARGS((void));
+void curs_columns __ARGS((int scroll));
+void scrolldown __ARGS((long line_count, int byfold));
+void scrollup __ARGS((long line_count, int byfold));
+void check_topfill __ARGS((win_T *wp, int down));
+void scrolldown_clamp __ARGS((void));
+void scrollup_clamp __ARGS((void));
+void scroll_cursor_top __ARGS((int min_scroll, int always));
+void set_empty_rows __ARGS((win_T *wp, int used));
+void scroll_cursor_bot __ARGS((int min_scroll, int set_topbot));
+void scroll_cursor_halfway __ARGS((int atend));
+void cursor_correct __ARGS((void));
+int onepage __ARGS((int dir, long count));
+void halfpage __ARGS((int flag, linenr_T Prenum));
+/* vim: set ft=c : */
--- /dev/null
+++ b/proto/netbeans.pro
@@ -1,0 +1,25 @@
+/* netbeans.c */
+void messageFromNetbeansW32 __ARGS((void));
+int isNetbeansBuffer __ARGS((buf_T *bufp));
+int isNetbeansModified __ARGS((buf_T *bufp));
+void netbeans_end __ARGS((void));
+void ex_nbkey __ARGS((exarg_T *eap));
+void netbeans_beval_cb __ARGS((BalloonEval *beval, int state));
+void netbeans_startup_done __ARGS((void));
+void netbeans_send_disconnect __ARGS((void));
+void netbeans_frame_moved __ARGS((int new_x, int new_y));
+void netbeans_file_activated __ARGS((buf_T *bufp));
+void netbeans_file_opened __ARGS((buf_T *bufp));
+void netbeans_file_closed __ARGS((buf_T *bufp));
+void netbeans_inserted __ARGS((buf_T *bufp, linenr_T linenr, colnr_T col, char_u *txt, int newlen));
+void netbeans_removed __ARGS((buf_T *bufp, linenr_T linenr, colnr_T col, long len));
+void netbeans_unmodified __ARGS((buf_T *bufp));
+void netbeans_button_release __ARGS((int button));
+void netbeans_keycommand __ARGS((int key));
+void netbeans_save_buffer __ARGS((buf_T *bufp));
+void netbeans_deleted_all_lines __ARGS((buf_T *bufp));
+int netbeans_is_guarded __ARGS((linenr_T top, linenr_T bot));
+void netbeans_draw_multisign_indicator __ARGS((int row));
+void netbeans_draw_multisign_indicator __ARGS((int row));
+void netbeans_gutter_click __ARGS((linenr_T lnum));
+/* vim: set ft=c : */
--- /dev/null
+++ b/proto/normal.pro
@@ -1,0 +1,26 @@
+/* normal.c */
+void init_normal_cmds __ARGS((void));
+void normal_cmd __ARGS((oparg_T *oap, int toplevel));
+void do_pending_operator __ARGS((cmdarg_T *cap, int old_col, int gui_yank));
+int do_mouse __ARGS((oparg_T *oap, int c, int dir, long count, int fixindent));
+void check_visual_highlight __ARGS((void));
+void end_visual_mode __ARGS((void));
+void reset_VIsual_and_resel __ARGS((void));
+void reset_VIsual __ARGS((void));
+int find_ident_under_cursor __ARGS((char_u **string, int find_type));
+int find_ident_at_pos __ARGS((win_T *wp, linenr_T lnum, colnr_T startcol, char_u **string, int find_type));
+void clear_showcmd __ARGS((void));
+int add_to_showcmd __ARGS((int c));
+void add_to_showcmd_c __ARGS((int c));
+void push_showcmd __ARGS((void));
+void pop_showcmd __ARGS((void));
+void do_check_scrollbind __ARGS((int check));
+void check_scrollbind __ARGS((linenr_T topline_diff, long leftcol_diff));
+int find_decl __ARGS((char_u *ptr, int len, int locally, int thisblock, int searchflags));
+void scroll_redraw __ARGS((int up, long count));
+void handle_tabmenu __ARGS((void));
+void do_nv_ident __ARGS((int c1, int c2));
+int get_visual_text __ARGS((cmdarg_T *cap, char_u **pp, int *lenp));
+void start_selection __ARGS((void));
+void may_start_select __ARGS((int c));
+/* vim: set ft=c : */
--- /dev/null
+++ b/proto/ops.pro
@@ -1,0 +1,61 @@
+/* ops.c */
+int get_op_type __ARGS((int char1, int char2));
+int op_on_lines __ARGS((int op));
+int get_op_char __ARGS((int optype));
+int get_extra_op_char __ARGS((int optype));
+void op_shift __ARGS((oparg_T *oap, int curs_top, int amount));
+void shift_line __ARGS((int left, int round, int amount));
+void op_reindent __ARGS((oparg_T *oap, int (*how)(void)));
+int get_expr_register __ARGS((void));
+void set_expr_line __ARGS((char_u *new_line));
+char_u *get_expr_line __ARGS((void));
+char_u *get_expr_line_src __ARGS((void));
+int valid_yank_reg __ARGS((int regname, int writing));
+void get_yank_register __ARGS((int regname, int writing));
+int may_get_selection __ARGS((int regname));
+void *get_register __ARGS((int name, int copy));
+void put_register __ARGS((int name, void *reg));
+int yank_register_mline __ARGS((int regname));
+int do_record __ARGS((int c));
+int do_execreg __ARGS((int regname, int colon, int addcr, int silent));
+int insert_reg __ARGS((int regname, int literally));
+int get_spec_reg __ARGS((int regname, char_u **argp, int *allocated, int errmsg));
+int cmdline_paste_reg __ARGS((int regname, int literally, int remcr));
+void adjust_clip_reg __ARGS((int *rp));
+int op_delete __ARGS((oparg_T *oap));
+int op_replace __ARGS((oparg_T *oap, int c));
+void op_tilde __ARGS((oparg_T *oap));
+int swapchar __ARGS((int op_type, pos_T *pos));
+void op_insert __ARGS((oparg_T *oap, long count1));
+int op_change __ARGS((oparg_T *oap));
+void init_yank __ARGS((void));
+void clear_registers __ARGS((void));
+int op_yank __ARGS((oparg_T *oap, int deleting, int mess));
+void do_put __ARGS((int regname, int dir, long count, int flags));
+void adjust_cursor_eol __ARGS((void));
+int preprocs_left __ARGS((void));
+int get_register_name __ARGS((int num));
+void ex_display __ARGS((exarg_T *eap));
+void do_do_join __ARGS((long count, int insert_space));
+int do_join __ARGS((int insert_space));
+void op_format __ARGS((oparg_T *oap, int keep_cursor));
+void op_formatexpr __ARGS((oparg_T *oap));
+int fex_format __ARGS((linenr_T lnum, long count, int c));
+void format_lines __ARGS((linenr_T line_count));
+int paragraph_start __ARGS((linenr_T lnum));
+int do_addsub __ARGS((int command, linenr_T Prenum1));
+int read_viminfo_register __ARGS((vir_T *virp, int force));
+void write_viminfo_registers __ARGS((FILE *fp));
+void x11_export_final_selection __ARGS((void));
+void clip_free_selection __ARGS((VimClipboard *cbd));
+void clip_get_selection __ARGS((VimClipboard *cbd));
+void clip_yank_selection __ARGS((int type, char_u *str, long len, VimClipboard *cbd));
+int clip_convert_selection __ARGS((char_u **str, long_u *len, VimClipboard *cbd));
+void dnd_yank_drag_data __ARGS((char_u *str, long len));
+char_u get_reg_type __ARGS((int regname, long *reglen));
+char_u *get_reg_contents __ARGS((int regname, int allowexpr, int expr_src));
+void write_reg_contents __ARGS((int name, char_u *str, int maxlen, int must_append));
+void write_reg_contents_ex __ARGS((int name, char_u *str, int maxlen, int must_append, int yank_type, long block_len));
+void clear_oparg __ARGS((oparg_T *oap));
+void cursor_pos_info __ARGS((void));
+/* vim: set ft=c : */
--- /dev/null
+++ b/proto/option.pro
@@ -1,0 +1,56 @@
+/* option.c */
+void set_init_1 __ARGS((void));
+void set_string_default __ARGS((char *name, char_u *val));
+void set_number_default __ARGS((char *name, long val));
+void free_all_options __ARGS((void));
+void set_init_2 __ARGS((void));
+void set_init_3 __ARGS((void));
+void set_helplang_default __ARGS((char_u *lang));
+void init_gui_options __ARGS((void));
+void set_title_defaults __ARGS((void));
+int do_set __ARGS((char_u *arg, int opt_flags));
+void set_options_bin __ARGS((int oldval, int newval, int opt_flags));
+int get_viminfo_parameter __ARGS((int type));
+char_u *find_viminfo_parameter __ARGS((int type));
+void check_options __ARGS((void));
+void check_buf_options __ARGS((buf_T *buf));
+void free_string_option __ARGS((char_u *p));
+void clear_string_option __ARGS((char_u **pp));
+void set_term_option_alloced __ARGS((char_u **p));
+int was_set_insecurely __ARGS((char_u *opt, int opt_flags));
+void set_string_option_direct __ARGS((char_u *name, int opt_idx, char_u *val, int opt_flags, int set_sid));
+char_u *check_stl_option __ARGS((char_u *s));
+int get_option_value __ARGS((char_u *name, long *numval, char_u **stringval, int opt_flags));
+void set_option_value __ARGS((char_u *name, long number, char_u *string, int opt_flags));
+char_u *get_term_code __ARGS((char_u *tname));
+char_u *get_highlight_default __ARGS((void));
+char_u *get_encoding_default __ARGS((void));
+int makeset __ARGS((FILE *fd, int opt_flags, int local_only));
+int makefoldset __ARGS((FILE *fd));
+void clear_termoptions __ARGS((void));
+void free_termoptions __ARGS((void));
+void set_term_defaults __ARGS((void));
+void comp_col __ARGS((void));
+char_u *get_equalprg __ARGS((void));
+void win_copy_options __ARGS((win_T *wp_from, win_T *wp_to));
+void copy_winopt __ARGS((winopt_T *from, winopt_T *to));
+void check_win_options __ARGS((win_T *win));
+void check_winopt __ARGS((winopt_T *wop));
+void clear_winopt __ARGS((winopt_T *wop));
+void buf_copy_options __ARGS((buf_T *buf, int flags));
+void reset_modifiable __ARGS((void));
+void set_iminsert_global __ARGS((void));
+void set_imsearch_global __ARGS((void));
+void set_context_in_set_cmd __ARGS((expand_T *xp, char_u *arg, int opt_flags));
+int ExpandSettings __ARGS((expand_T *xp, regmatch_T *regmatch, int *num_file, char_u ***file));
+int ExpandOldSetting __ARGS((int *num_file, char_u ***file));
+int has_format_option __ARGS((int x));
+int shortmess __ARGS((int x));
+void vimrc_found __ARGS((char_u *fname, char_u *envname));
+void change_compatible __ARGS((int on));
+int option_was_set __ARGS((char_u *name));
+int can_bs __ARGS((int what));
+void save_file_ff __ARGS((buf_T *buf));
+int file_ff_differs __ARGS((buf_T *buf));
+int check_ff_value __ARGS((char_u *p));
+/* vim: set ft=c : */
--- /dev/null
+++ b/proto/os_plan9.pro
@@ -1,0 +1,47 @@
+/* os_plan9.c */
+void mch_write __ARGS((char_u *s, int len));
+int mch_inchar __ARGS((char_u *buf, int maxlen, long wtime, int tb_change_cnt));
+int mch_char_avail __ARGS((void));
+void mch_delay __ARGS((long msec, int ignoreinput));
+void mch_suspend __ARGS((void));
+void mch_init __ARGS((void));
+int mch_check_win __ARGS((int argc, char **argv));
+int mch_input_isatty __ARGS((void));
+int mch_can_restore_title __ARGS((void));
+int mch_can_restore_icon __ARGS((void));
+void mch_settitle __ARGS((char_u *title, char_u *icon));
+void mch_restore_title __ARGS((int which));
+int mch_get_user_name __ARGS((char_u *s, int len));
+void mch_get_host_name __ARGS((char_u *s, int len));
+long mch_get_pid __ARGS((void));
+int mch_dirname __ARGS((char_u *buf, int len));
+int mch_FullName __ARGS((char_u *fname, char_u *buf, int len, int force));
+int mch_isFullName __ARGS((char_u *fname));
+long mch_getperm __ARGS((char_u *name));
+int mch_setperm __ARGS((char_u *name, long perm));
+void mch_hide __ARGS((char_u *name));
+int mch_isdir __ARGS((char_u *name));
+int mch_can_exe __ARGS((char_u *name));
+int mch_nodetype __ARGS((char_u *name));
+void mch_early_init __ARGS((void));
+void mch_exit __ARGS((int r));
+void mch_settmode __ARGS((int tmode));
+void mch_setmouse __ARGS((int on));
+int mch_screenmode __ARGS((char_u *arg));
+int mch_get_shellsize __ARGS((void));
+void mch_set_shellsize __ARGS((void));
+void mch_new_shellsize __ARGS((void));
+int mch_call_shell __ARGS((char_u *cmd, int options));
+void mch_breakcheck __ARGS((void));
+int mch_expandpath __ARGS((garray_T *gap, char_u *path, int flags));
+int mch_has_exp_wildcard __ARGS((char_u *p));
+int mch_has_wildcard __ARGS((char_u *p));
+int mch_remove __ARGS((char_u *name));
+int mch_setenv __ARGS((char *var, char *value, int x));
+int clip_mch_own_selection __ARGS((VimClipboard *cbd));
+void clip_mch_lose_selection __ARGS((VimClipboard *cbd));
+void clip_mch_request_selection __ARGS((VimClipboard *cbd));
+void clip_mch_set_selection __ARGS((VimClipboard *cbd));
+void mch_set_normal_colors __ARGS((void));
+int RealWaitForChar __ARGS((int, long msec, int*));
+/* vim: set ft=c : */
--- /dev/null
+++ b/proto/popupmnu.pro
@@ -1,0 +1,8 @@
+/* popupmnu.c */
+void pum_display __ARGS((pumitem_T *array, int size, int selected));
+void pum_redraw __ARGS((void));
+void pum_undisplay __ARGS((void));
+void pum_clear __ARGS((void));
+int pum_visible __ARGS((void));
+int pum_get_height __ARGS((void));
+/* vim: set ft=c : */
--- /dev/null
+++ b/proto/quickfix.pro
@@ -1,0 +1,30 @@
+/* quickfix.c */
+int qf_init __ARGS((win_T *wp, char_u *efile, char_u *errorformat, int newlist));
+void qf_free_all __ARGS((win_T *wp));
+void copy_loclist __ARGS((win_T *from, win_T *to));
+void qf_jump __ARGS((qf_info_T *qi, int dir, int errornr, int forceit));
+void qf_list __ARGS((exarg_T *eap));
+void qf_age __ARGS((exarg_T *eap));
+void qf_mark_adjust __ARGS((win_T *wp, linenr_T line1, linenr_T line2, long amount, long amount_after));
+void ex_cwindow __ARGS((exarg_T *eap));
+void ex_cclose __ARGS((exarg_T *eap));
+void ex_copen __ARGS((exarg_T *eap));
+linenr_T qf_current_entry __ARGS((win_T *wp));
+int bt_quickfix __ARGS((buf_T *buf));
+int bt_nofile __ARGS((buf_T *buf));
+int bt_dontwrite __ARGS((buf_T *buf));
+int bt_dontwrite_msg __ARGS((buf_T *buf));
+int buf_hide __ARGS((buf_T *buf));
+int grep_internal __ARGS((cmdidx_T cmdidx));
+void ex_make __ARGS((exarg_T *eap));
+void ex_cc __ARGS((exarg_T *eap));
+void ex_cnext __ARGS((exarg_T *eap));
+void ex_cfile __ARGS((exarg_T *eap));
+void ex_vimgrep __ARGS((exarg_T *eap));
+char_u *skip_vimgrep_pat __ARGS((char_u *p, char_u **s, int *flags));
+int get_errorlist __ARGS((win_T *wp, list_T *list));
+int set_errorlist __ARGS((win_T *wp, list_T *list, int action));
+void ex_cbuffer __ARGS((exarg_T *eap));
+void ex_cexpr __ARGS((exarg_T *eap));
+void ex_helpgrep __ARGS((exarg_T *eap));
+/* vim: set ft=c : */
--- /dev/null
+++ b/proto/regexp.pro
@@ -1,0 +1,17 @@
+/* regexp.c */
+void free_regexp_stuff __ARGS((void));
+int re_multiline __ARGS((regprog_T *prog));
+int re_lookbehind __ARGS((regprog_T *prog));
+char_u *skip_regexp __ARGS((char_u *startp, int dirc, int magic, char_u **newp));
+regprog_T *vim_regcomp __ARGS((char_u *expr, int re_flags));
+int vim_regcomp_had_eol __ARGS((void));
+int vim_regexec __ARGS((regmatch_T *rmp, char_u *line, colnr_T col));
+int vim_regexec_nl __ARGS((regmatch_T *rmp, char_u *line, colnr_T col));
+long vim_regexec_multi __ARGS((regmmatch_T *rmp, win_T *win, buf_T *buf, linenr_T lnum, colnr_T col));
+reg_extmatch_T *ref_extmatch __ARGS((reg_extmatch_T *em));
+void unref_extmatch __ARGS((reg_extmatch_T *em));
+char_u *regtilde __ARGS((char_u *source, int magic));
+int vim_regsub __ARGS((regmatch_T *rmp, char_u *source, char_u *dest, int copy, int magic, int backslash));
+int vim_regsub_multi __ARGS((regmmatch_T *rmp, linenr_T lnum, char_u *source, char_u *dest, int copy, int magic, int backslash));
+char_u *reg_submatch __ARGS((int no));
+/* vim: set ft=c : */
--- /dev/null
+++ b/proto/screen.pro
@@ -1,0 +1,50 @@
+/* screen.c */
+void redraw_later __ARGS((int type));
+void redraw_win_later __ARGS((win_T *wp, int type));
+void redraw_later_clear __ARGS((void));
+void redraw_all_later __ARGS((int type));
+void redraw_curbuf_later __ARGS((int type));
+void redraw_buf_later __ARGS((buf_T *buf, int type));
+void redrawWinline __ARGS((linenr_T lnum, int invalid));
+void update_curbuf __ARGS((int type));
+void update_screen __ARGS((int type));
+void update_debug_sign __ARGS((buf_T *buf, linenr_T lnum));
+void updateWindow __ARGS((win_T *wp));
+void rl_mirror __ARGS((char_u *str));
+void status_redraw_all __ARGS((void));
+void status_redraw_curbuf __ARGS((void));
+void redraw_statuslines __ARGS((void));
+void win_redraw_last_status __ARGS((frame_T *frp));
+void win_redr_status_matches __ARGS((expand_T *xp, int num_matches, char_u **matches, int match, int showtail));
+void win_redr_status __ARGS((win_T *wp));
+int stl_connected __ARGS((win_T *wp));
+int get_keymap_str __ARGS((win_T *wp, char_u *buf, int len));
+void screen_putchar __ARGS((int c, int row, int col, int attr));
+void screen_getbytes __ARGS((int row, int col, char_u *bytes, int *attrp));
+void screen_puts __ARGS((char_u *text, int row, int col, int attr));
+void screen_puts_len __ARGS((char_u *text, int len, int row, int col, int attr));
+void screen_stop_highlight __ARGS((void));
+void reset_cterm_colors __ARGS((void));
+void screen_draw_rectangle __ARGS((int row, int col, int height, int width, int invert));
+void screen_fill __ARGS((int start_row, int end_row, int start_col, int end_col, int c1, int c2, int attr));
+void check_for_delay __ARGS((int check_msg_scroll));
+int screen_valid __ARGS((int clear));
+void screenalloc __ARGS((int clear));
+void free_screenlines __ARGS((void));
+void screenclear __ARGS((void));
+int can_clear __ARGS((char_u *p));
+void screen_start __ARGS((void));
+void windgoto __ARGS((int row, int col));
+void setcursor __ARGS((void));
+int win_ins_lines __ARGS((win_T *wp, int row, int line_count, int invalid, int mayclear));
+int win_del_lines __ARGS((win_T *wp, int row, int line_count, int invalid, int mayclear));
+int screen_ins_lines __ARGS((int off, int row, int line_count, int end, win_T *wp));
+int screen_del_lines __ARGS((int off, int row, int line_count, int end, int force, win_T *wp));
+int showmode __ARGS((void));
+void unshowmode __ARGS((int force));
+void get_trans_bufname __ARGS((buf_T *buf));
+int redrawing __ARGS((void));
+int messaging __ARGS((void));
+void showruler __ARGS((int always));
+int number_width __ARGS((win_T *wp));
+/* vim: set ft=c : */
--- /dev/null
+++ b/proto/search.pro
@@ -1,0 +1,36 @@
+/* search.c */
+int search_regcomp __ARGS((char_u *pat, int pat_save, int pat_use, int options, regmmatch_T *regmatch));
+char_u *get_search_pat __ARGS((void));
+void save_search_patterns __ARGS((void));
+void restore_search_patterns __ARGS((void));
+void free_search_patterns __ARGS((void));
+int ignorecase __ARGS((char_u *pat));
+char_u *last_search_pat __ARGS((void));
+void reset_search_dir __ARGS((void));
+void set_last_search_pat __ARGS((char_u *s, int idx, int magic, int setlast));
+void last_pat_prog __ARGS((regmmatch_T *regmatch));
+int searchit __ARGS((win_T *win, buf_T *buf, pos_T *pos, int dir, char_u *pat, long count, int options, int pat_use, linenr_T stop_lnum));
+int do_search __ARGS((oparg_T *oap, int dirc, char_u *pat, long count, int options));
+int search_for_exact_line __ARGS((buf_T *buf, pos_T *pos, int dir, char_u *pat));
+int searchc __ARGS((cmdarg_T *cap, int t_cmd));
+pos_T *findmatch __ARGS((oparg_T *oap, int initc));
+pos_T *findmatchlimit __ARGS((oparg_T *oap, int initc, int flags, int maxtravel));
+void showmatch __ARGS((int c));
+int findsent __ARGS((int dir, long count));
+int findpar __ARGS((int *pincl, int dir, long count, int what, int both));
+int startPS __ARGS((linenr_T lnum, int para, int both));
+int fwd_word __ARGS((long count, int bigword, int eol));
+int bck_word __ARGS((long count, int bigword, int stop));
+int end_word __ARGS((long count, int bigword, int stop, int empty));
+int bckend_word __ARGS((long count, int bigword, int eol));
+int current_word __ARGS((oparg_T *oap, long count, int include, int bigword));
+int current_sent __ARGS((oparg_T *oap, long count, int include));
+int current_block __ARGS((oparg_T *oap, long count, int include, int what, int other));
+int current_tagblock __ARGS((oparg_T *oap, long count_arg, int include));
+int current_par __ARGS((oparg_T *oap, long count, int include, int type));
+int current_quote __ARGS((oparg_T *oap, long count, int include, int quotechar));
+int linewhite __ARGS((linenr_T lnum));
+void find_pattern_in_path __ARGS((char_u *ptr, int dir, int len, int whole, int skip_comments, int type, long count, int action, linenr_T start_lnum, linenr_T end_lnum));
+int read_viminfo_search_pattern __ARGS((vir_T *virp, int force));
+void write_viminfo_search_pattern __ARGS((FILE *fp));
+/* vim: set ft=c : */
--- /dev/null
+++ b/proto/spell.pro
@@ -1,0 +1,26 @@
+/* spell.c */
+int spell_check __ARGS((win_T *wp, char_u *ptr, hlf_T *attrp, int *capcol, int docount));
+int spell_move_to __ARGS((win_T *wp, int dir, int allwords, int curline, hlf_T *attrp));
+void spell_cat_line __ARGS((char_u *buf, char_u *line, int maxlen));
+char_u *did_set_spelllang __ARGS((buf_T *buf));
+void spell_free_all __ARGS((void));
+void spell_reload __ARGS((void));
+int spell_check_msm __ARGS((void));
+void put_bytes __ARGS((FILE *fd, long_u nr, int len));
+void ex_mkspell __ARGS((exarg_T *eap));
+void ex_spell __ARGS((exarg_T *eap));
+void spell_add_word __ARGS((char_u *word, int len, int bad, int idx, int undo));
+void init_spell_chartab __ARGS((void));
+int spell_check_sps __ARGS((void));
+void spell_suggest __ARGS((int count));
+void ex_spellrepall __ARGS((exarg_T *eap));
+void spell_suggest_list __ARGS((garray_T *gap, char_u *word, int maxcount, int need_cap, int interactive));
+char_u *eval_soundfold __ARGS((char_u *word));
+void ex_spellinfo __ARGS((exarg_T *eap));
+void ex_spelldump __ARGS((exarg_T *eap));
+void spell_dump_compl __ARGS((buf_T *buf, char_u *pat, int ic, int *dir, int dumpflags_arg));
+char_u *spell_to_word_end __ARGS((char_u *start, buf_T *buf));
+int spell_word_start __ARGS((int startcol));
+void spell_expand_check_cap __ARGS((colnr_T col));
+int expand_spelling __ARGS((linenr_T lnum, int col, char_u *pat, char_u ***matchp));
+/* vim: set ft=c : */
--- /dev/null
+++ b/proto/syntax.pro
@@ -1,0 +1,47 @@
+/* syntax.c */
+void syntax_start __ARGS((win_T *wp, linenr_T lnum));
+void syn_stack_free_all __ARGS((buf_T *buf));
+void syn_stack_apply_changes __ARGS((buf_T *buf));
+void syntax_end_parsing __ARGS((linenr_T lnum));
+int syntax_check_changed __ARGS((linenr_T lnum));
+int get_syntax_attr __ARGS((colnr_T col, int *can_spell));
+void syntax_clear __ARGS((buf_T *buf));
+void ex_syntax __ARGS((exarg_T *eap));
+int syntax_present __ARGS((buf_T *buf));
+void set_context_in_syntax_cmd __ARGS((expand_T *xp, char_u *arg));
+char_u *get_syntax_name __ARGS((expand_T *xp, int idx));
+int syn_get_id __ARGS((win_T *wp, long lnum, colnr_T col, int trans, int *spellp));
+int syn_get_foldlevel __ARGS((win_T *wp, long lnum));
+void init_highlight __ARGS((int both, int reset));
+int load_colors __ARGS((char_u *name));
+void do_highlight __ARGS((char_u *line, int forceit, int init));
+void free_highlight __ARGS((void));
+void restore_cterm_colors __ARGS((void));
+void set_normal_colors __ARGS((void));
+char_u *hl_get_font_name __ARGS((void));
+void hl_set_font_name __ARGS((char_u *font_name));
+void hl_set_bg_color_name __ARGS((char_u *name));
+void hl_set_fg_color_name __ARGS((char_u *name));
+void clear_hl_tables __ARGS((void));
+int hl_combine_attr __ARGS((int char_attr, int prim_attr));
+attrentry_T *syn_gui_attr2entry __ARGS((int attr));
+int syn_attr2attr __ARGS((int attr));
+attrentry_T *syn_term_attr2entry __ARGS((int attr));
+attrentry_T *syn_cterm_attr2entry __ARGS((int attr));
+char_u *highlight_has_attr __ARGS((int id, int flag, int modec));
+char_u *highlight_color __ARGS((int id, char_u *what, int modec));
+long_u highlight_gui_color_rgb __ARGS((int id, int fg));
+int syn_name2id __ARGS((char_u *name));
+int highlight_exists __ARGS((char_u *name));
+char_u *syn_id2name __ARGS((int id));
+int syn_namen2id __ARGS((char_u *linep, int len));
+int syn_check_group __ARGS((char_u *pp, int len));
+int syn_id2attr __ARGS((int hl_id));
+int syn_id2colors __ARGS((int hl_id, guicolor_T *fgp, guicolor_T *bgp));
+int syn_get_final_id __ARGS((int hl_id));
+void highlight_gui_started __ARGS((void));
+int highlight_changed __ARGS((void));
+void set_context_in_highlight_cmd __ARGS((expand_T *xp, char_u *arg));
+char_u *get_highlight_name __ARGS((expand_T *xp, int idx));
+void free_highlight_fonts __ARGS((void));
+/* vim: set ft=c : */
--- /dev/null
+++ b/proto/tag.pro
@@ -1,0 +1,12 @@
+/* tag.c */
+int do_tag __ARGS((char_u *tag, int type, int count, int forceit, int verbose));
+void tag_freematch __ARGS((void));
+void do_tags __ARGS((exarg_T *eap));
+int find_tags __ARGS((char_u *pat, int *num_matches, char_u ***matchesp, int flags, int mincount, char_u *buf_ffname));
+void free_tag_stuff __ARGS((void));
+int get_tagfname __ARGS((tagname_T *tnp, int first, char_u *buf));
+void tagname_free __ARGS((tagname_T *tnp));
+void simplify_filename __ARGS((char_u *filename));
+int expand_tags __ARGS((int tagnames, char_u *pat, int *num_file, char_u ***file));
+int get_tags __ARGS((list_T *list, char_u *pat));
+/* vim: set ft=c : */
--- /dev/null
+++ b/proto/term.pro
@@ -1,0 +1,60 @@
+/* term.c */
+int set_termname __ARGS((char_u *term));
+void set_mouse_termcode __ARGS((int n, char_u *s));
+void del_mouse_termcode __ARGS((int n));
+void getlinecol __ARGS((long *cp, long *rp));
+int add_termcap_entry __ARGS((char_u *name, int force));
+int term_is_8bit __ARGS((char_u *name));
+int term_is_gui __ARGS((char_u *name));
+char_u *tltoa __ARGS((unsigned long i));
+void termcapinit __ARGS((char_u *name));
+void out_flush __ARGS((void));
+void out_flush_check __ARGS((void));
+void out_trash __ARGS((void));
+void out_char __ARGS((unsigned c));
+void out_str_nf __ARGS((char_u *s));
+void out_str __ARGS((char_u *s));
+void term_windgoto __ARGS((int row, int col));
+void term_cursor_right __ARGS((int i));
+void term_append_lines __ARGS((int line_count));
+void term_delete_lines __ARGS((int line_count));
+void term_set_winpos __ARGS((int x, int y));
+void term_set_winsize __ARGS((int width, int height));
+void term_fg_color __ARGS((int n));
+void term_bg_color __ARGS((int n));
+void term_settitle __ARGS((char_u *title));
+void ttest __ARGS((int pairs));
+void add_long_to_buf __ARGS((long_u val, char_u *dst));
+void check_shellsize __ARGS((void));
+void win_new_shellsize __ARGS((void));
+void shell_resized __ARGS((void));
+void shell_resized_check __ARGS((void));
+void set_shellsize __ARGS((int width, int height, int mustset));
+void settmode __ARGS((int tmode));
+void starttermcap __ARGS((void));
+void stoptermcap __ARGS((void));
+void may_req_termresponse __ARGS((void));
+int swapping_screen __ARGS((void));
+void setmouse __ARGS((void));
+int mouse_has __ARGS((int c));
+int mouse_model_popup __ARGS((void));
+void scroll_start __ARGS((void));
+void cursor_on __ARGS((void));
+void cursor_off __ARGS((void));
+void term_cursor_shape __ARGS((void));
+void scroll_region_set __ARGS((win_T *wp, int off));
+void scroll_region_reset __ARGS((void));
+void clear_termcodes __ARGS((void));
+void add_termcode __ARGS((char_u *name, char_u *string, int flags));
+char_u *find_termcode __ARGS((char_u *name));
+char_u *get_termcode __ARGS((int i));
+void del_termcode __ARGS((char_u *name));
+void set_mouse_topline __ARGS((win_T *wp));
+int check_termcode __ARGS((int max_offset, char_u *buf, int buflen));
+char_u *replace_termcodes __ARGS((char_u *from, char_u **bufp, int from_part, int do_lt, int special));
+int find_term_bykeys __ARGS((char_u *src));
+void show_termcodes __ARGS((void));
+int show_one_termcode __ARGS((char_u *name, char_u *code, int printit));
+char_u *translate_mapping __ARGS((char_u *str, int expmap));
+void update_tcap __ARGS((int attr));
+/* vim: set ft=c : */
--- /dev/null
+++ b/proto/termlib.pro
@@ -1,0 +1,8 @@
+/* termlib.c */
+int tgetent __ARGS((char *tbuf, char *term));
+int tgetflag __ARGS((char *id));
+int tgetnum __ARGS((char *id));
+char *tgetstr __ARGS((char *id, char **buf));
+char *tgoto __ARGS((char *cm, int col, int line));
+int tputs __ARGS((char *cp, int affcnt, void (*outc)(unsigned int)));
+/* vim: set ft=c : */
--- /dev/null
+++ b/proto/ui.pro
@@ -1,0 +1,61 @@
+/* ui.c */
+void ui_write __ARGS((char_u *s, int len));
+void ui_inchar_undo __ARGS((char_u *s, int len));
+int ui_inchar __ARGS((char_u *buf, int maxlen, long wtime, int tb_change_cnt));
+int ui_char_avail __ARGS((void));
+void ui_delay __ARGS((long msec, int ignoreinput));
+void ui_suspend __ARGS((void));
+void suspend_shell __ARGS((void));
+int ui_get_shellsize __ARGS((void));
+void ui_set_shellsize __ARGS((int mustset));
+void ui_new_shellsize __ARGS((void));
+void ui_breakcheck __ARGS((void));
+void clip_init __ARGS((int can_use));
+void clip_update_selection __ARGS((void));
+void clip_own_selection __ARGS((VimClipboard *cbd));
+void clip_lose_selection __ARGS((VimClipboard *cbd));
+void clip_copy_selection __ARGS((void));
+void clip_auto_select __ARGS((void));
+int clip_isautosel __ARGS((void));
+void clip_modeless __ARGS((int button, int is_click, int is_drag));
+void clip_start_selection __ARGS((int col, int row, int repeated_click));
+void clip_process_selection __ARGS((int button, int col, int row, int_u repeated_click));
+void clip_may_redraw_selection __ARGS((int row, int col, int len));
+void clip_clear_selection __ARGS((void));
+void clip_may_clear_selection __ARGS((int row1, int row2));
+void clip_scroll_selection __ARGS((int rows));
+void clip_copy_modeless_selection __ARGS((int both));
+int clip_gen_own_selection __ARGS((VimClipboard *cbd));
+void clip_gen_lose_selection __ARGS((VimClipboard *cbd));
+void clip_gen_set_selection __ARGS((VimClipboard *cbd));
+void clip_gen_request_selection __ARGS((VimClipboard *cbd));
+int vim_is_input_buf_full __ARGS((void));
+int vim_is_input_buf_empty __ARGS((void));
+int vim_free_in_input_buf __ARGS((void));
+int vim_used_in_input_buf __ARGS((void));
+char_u *get_input_buf __ARGS((void));
+void set_input_buf __ARGS((char_u *p));
+void add_to_input_buf __ARGS((char_u *s, int len));
+void add_to_input_buf_csi __ARGS((char_u *str, int len));
+void push_raw_key __ARGS((char_u *s, int len));
+void trash_input_buf __ARGS((void));
+int read_from_input_buf __ARGS((char_u *buf, long maxlen));
+void fill_input_buf __ARGS((int exit_on_error));
+void read_error_exit __ARGS((void));
+void ui_cursor_shape __ARGS((void));
+int check_col __ARGS((int col));
+int check_row __ARGS((int row));
+void open_app_context __ARGS((void));
+void x11_setup_atoms __ARGS((Display *dpy));
+void clip_x11_request_selection __ARGS((Widget myShell, Display *dpy, VimClipboard *cbd));
+void clip_x11_lose_selection __ARGS((Widget myShell, VimClipboard *cbd));
+int clip_x11_own_selection __ARGS((Widget myShell, VimClipboard *cbd));
+void clip_x11_set_selection __ARGS((VimClipboard *cbd));
+int jump_to_mouse __ARGS((int flags, int *inclusive, int which_button));
+int mouse_comp_pos __ARGS((win_T *win, int *rowp, int *colp, linenr_T *lnump));
+win_T *mouse_find_win __ARGS((int *rowp, int *colp));
+int get_fpos_of_mouse __ARGS((pos_T *mpos));
+int vcol2col __ARGS((win_T *wp, linenr_T lnum, int vcol));
+void ui_focus_change __ARGS((int in_focus));
+void im_save_status __ARGS((long *psave));
+/* vim: set ft=c : */
--- /dev/null
+++ b/proto/undo.pro
@@ -1,0 +1,22 @@
+/* undo.c */
+int u_save_cursor __ARGS((void));
+int u_save __ARGS((linenr_T top, linenr_T bot));
+int u_savesub __ARGS((linenr_T lnum));
+int u_inssub __ARGS((linenr_T lnum));
+int u_savedel __ARGS((linenr_T lnum, long nlines));
+int undo_allowed __ARGS((void));
+void u_undo __ARGS((int count));
+void u_redo __ARGS((int count));
+void undo_time __ARGS((long step, int sec, int absolute));
+void u_sync __ARGS((int force));
+void ex_undolist __ARGS((exarg_T *eap));
+void ex_undojoin __ARGS((exarg_T *eap));
+void u_unchanged __ARGS((buf_T *buf));
+void u_clearall __ARGS((buf_T *buf));
+void u_saveline __ARGS((linenr_T lnum));
+void u_clearline __ARGS((void));
+void u_undoline __ARGS((void));
+void u_blockfree __ARGS((buf_T *buf));
+int bufIsChanged __ARGS((buf_T *buf));
+int curbufIsChanged __ARGS((void));
+/* vim: set ft=c : */
--- /dev/null
+++ b/proto/version.pro
@@ -1,0 +1,9 @@
+/* version.c */
+void make_version __ARGS((void));
+int highest_patch __ARGS((void));
+int has_patch __ARGS((int n));
+void ex_version __ARGS((exarg_T *eap));
+void list_version __ARGS((void));
+void intro_message __ARGS((int colon));
+void ex_intro __ARGS((exarg_T *eap));
+/* vim: set ft=c : */
--- /dev/null
+++ b/proto/window.pro
@@ -1,0 +1,62 @@
+/* window.c */
+void do_window __ARGS((int nchar, long Prenum, int xchar));
+int win_split __ARGS((int size, int flags));
+int win_valid __ARGS((win_T *win));
+int win_count __ARGS((void));
+int make_windows __ARGS((int count, int vertical));
+void win_move_after __ARGS((win_T *win1, win_T *win2));
+void win_equal __ARGS((win_T *next_curwin, int current, int dir));
+void close_windows __ARGS((buf_T *buf, int keep_curwin));
+void win_close __ARGS((win_T *win, int free_buf));
+void win_close_othertab __ARGS((win_T *win, int free_buf, tabpage_T *tp));
+void win_free_all __ARGS((void));
+void close_others __ARGS((int message, int forceit));
+void curwin_init __ARGS((void));
+int win_alloc_first __ARGS((void));
+void win_init_size __ARGS((void));
+void free_tabpage __ARGS((tabpage_T *tp));
+int win_new_tabpage __ARGS((int after));
+int may_open_tabpage __ARGS((void));
+int make_tabpages __ARGS((int maxcount));
+int valid_tabpage __ARGS((tabpage_T *tpc));
+tabpage_T *find_tabpage __ARGS((int n));
+int tabpage_index __ARGS((tabpage_T *ftp));
+void goto_tabpage __ARGS((int n));
+void goto_tabpage_tp __ARGS((tabpage_T *tp));
+void goto_tabpage_win __ARGS((tabpage_T *tp, win_T *wp));
+void tabpage_move __ARGS((int nr));
+void win_goto __ARGS((win_T *wp));
+win_T *win_find_nr __ARGS((int winnr));
+void win_enter __ARGS((win_T *wp, int undo_sync));
+win_T *buf_jump_open_win __ARGS((buf_T *buf));
+win_T *buf_jump_open_tab __ARGS((buf_T *buf));
+int win_alloc_lines __ARGS((win_T *wp));
+void win_free_lsize __ARGS((win_T *wp));
+void shell_new_rows __ARGS((void));
+void shell_new_columns __ARGS((void));
+void win_size_save __ARGS((garray_T *gap));
+void win_size_restore __ARGS((garray_T *gap));
+int win_comp_pos __ARGS((void));
+void win_setheight __ARGS((int height));
+void win_setheight_win __ARGS((int height, win_T *win));
+void win_setwidth __ARGS((int width));
+void win_setwidth_win __ARGS((int width, win_T *wp));
+void win_setminheight __ARGS((void));
+void win_drag_status_line __ARGS((win_T *dragwin, int offset));
+void win_drag_vsep_line __ARGS((win_T *dragwin, int offset));
+void win_comp_scroll __ARGS((win_T *wp));
+void command_height __ARGS((void));
+void last_status __ARGS((int morewin));
+int tabline_height __ARGS((void));
+char_u *grab_file_name __ARGS((long count, linenr_T *file_lnum));
+char_u *file_name_at_cursor __ARGS((int options, long count, linenr_T *file_lnum));
+char_u *file_name_in_line __ARGS((char_u *line, int col, int options, long count, char_u *rel_fname, linenr_T *file_lnum));
+char_u *find_file_name_in_path __ARGS((char_u *ptr, int len, int options, long count, char_u *rel_fname));
+int path_with_url __ARGS((char_u *fname));
+int vim_isAbsName __ARGS((char_u *name));
+int vim_FullName __ARGS((char_u *fname, char_u *buf, int len, int force));
+int min_rows __ARGS((void));
+int only_one_window __ARGS((void));
+void check_lnums __ARGS((int do_curwin));
+int win_hasvertsplit __ARGS((void));
+/* vim: set ft=c : */
--- /dev/null
+++ b/quickfix.c
@@ -1,0 +1,3849 @@
+/* vi:set ts=8 sts=4 sw=4:
+ *
+ * VIM - Vi IMproved	by Bram Moolenaar
+ *
+ * Do ":help uganda"  in Vim to read copying and usage conditions.
+ * Do ":help credits" in Vim to see a list of people who contributed.
+ * See README.txt for an overview of the Vim source code.
+ */
+
+/*
+ * quickfix.c: functions for quickfix mode, using a file with error messages
+ */
+
+#include "vim.h"
+
+#if defined(FEAT_QUICKFIX) || defined(PROTO)
+
+struct dir_stack_T
+{
+    struct dir_stack_T	*next;
+    char_u		*dirname;
+};
+
+static struct dir_stack_T   *dir_stack = NULL;
+
+/*
+ * For each error the next struct is allocated and linked in a list.
+ */
+typedef struct qfline_S qfline_T;
+struct qfline_S
+{
+    qfline_T	*qf_next;	/* pointer to next error in the list */
+    qfline_T	*qf_prev;	/* pointer to previous error in the list */
+    linenr_T	qf_lnum;	/* line number where the error occurred */
+    int		qf_fnum;	/* file number for the line */
+    int		qf_col;		/* column where the error occurred */
+    int		qf_nr;		/* error number */
+    char_u	*qf_pattern;	/* search pattern for the error */
+    char_u	*qf_text;	/* description of the error */
+    char_u	qf_viscol;	/* set to TRUE if qf_col is screen column */
+    char_u	qf_cleared;	/* set to TRUE if line has been deleted */
+    char_u	qf_type;	/* type of the error (mostly 'E'); 1 for
+				   :helpgrep */
+    char_u	qf_valid;	/* valid error message detected */
+};
+
+/*
+ * There is a stack of error lists.
+ */
+#define LISTCOUNT   10
+
+typedef struct qf_list_S
+{
+    qfline_T	*qf_start;	/* pointer to the first error */
+    qfline_T	*qf_ptr;	/* pointer to the current error */
+    int		qf_count;	/* number of errors (0 means no error list) */
+    int		qf_index;	/* current index in the error list */
+    int		qf_nonevalid;	/* TRUE if not a single valid entry found */
+} qf_list_T;
+
+struct qf_info_S
+{
+    /*
+     * Count of references to this list. Used only for location lists.
+     * When a location list window reference this list, qf_refcount
+     * will be 2. Otherwise, qf_refcount will be 1. When qf_refcount
+     * reaches 0, the list is freed.
+     */
+    int		qf_refcount;
+    int		qf_listcount;	    /* current number of lists */
+    int		qf_curlist;	    /* current error list */
+    qf_list_T	qf_lists[LISTCOUNT];
+};
+
+static qf_info_T ql_info;	/* global quickfix list */
+
+#define FMT_PATTERNS 10		/* maximum number of % recognized */
+
+/*
+ * Structure used to hold the info of one part of 'errorformat'
+ */
+typedef struct efm_S efm_T;
+struct efm_S
+{
+    regprog_T	    *prog;	/* pre-formatted part of 'errorformat' */
+    efm_T	    *next;	/* pointer to next (NULL if last) */
+    char_u	    addr[FMT_PATTERNS]; /* indices of used % patterns */
+    char_u	    prefix;	/* prefix of this format line: */
+				/*   'D' enter directory */
+				/*   'X' leave directory */
+				/*   'A' start of multi-line message */
+				/*   'E' error message */
+				/*   'W' warning message */
+				/*   'I' informational message */
+				/*   'C' continuation line */
+				/*   'Z' end of multi-line message */
+				/*   'G' general, unspecific message */
+				/*   'P' push file (partial) message */
+				/*   'Q' pop/quit file (partial) message */
+				/*   'O' overread (partial) message */
+    char_u	    flags;	/* additional flags given in prefix */
+				/*   '-' do not include this line */
+				/*   '+' include whole line in message */
+    int		    conthere;	/* %> used */
+};
+
+static int	qf_init_ext __ARGS((qf_info_T *qi, char_u *efile, buf_T *buf, typval_T *tv, char_u *errorformat, int newlist, linenr_T lnumfirst, linenr_T lnumlast));
+static void	qf_new_list __ARGS((qf_info_T *qi));
+static int	qf_add_entry __ARGS((qf_info_T *qi, qfline_T **prevp, char_u *dir, char_u *fname, int bufnum, char_u *mesg, long lnum, int col, int vis_col, char_u *pattern, int nr, int type, int valid));
+static void	qf_msg __ARGS((qf_info_T *qi));
+static void	qf_free __ARGS((qf_info_T *qi, int idx));
+static char_u	*qf_types __ARGS((int, int));
+static int	qf_get_fnum __ARGS((char_u *, char_u *));
+static char_u	*qf_push_dir __ARGS((char_u *, struct dir_stack_T **));
+static char_u	*qf_pop_dir __ARGS((struct dir_stack_T **));
+static char_u	*qf_guess_filepath __ARGS((char_u *));
+static void	qf_fmt_text __ARGS((char_u *text, char_u *buf, int bufsize));
+static void	qf_clean_dir_stack __ARGS((struct dir_stack_T **));
+#ifdef FEAT_WINDOWS
+static int	qf_win_pos_update __ARGS((qf_info_T *qi, int old_qf_index));
+static int	is_qf_win __ARGS((win_T *win, qf_info_T *qi));
+static win_T	*qf_find_win __ARGS((qf_info_T *qi));
+static buf_T	*qf_find_buf __ARGS((qf_info_T *qi));
+static void	qf_update_buffer __ARGS((qf_info_T *qi));
+static void	qf_fill_buffer __ARGS((qf_info_T *qi));
+#endif
+static char_u	*get_mef_name __ARGS((void));
+static buf_T	*load_dummy_buffer __ARGS((char_u *fname));
+static void	wipe_dummy_buffer __ARGS((buf_T *buf));
+static void	unload_dummy_buffer __ARGS((buf_T *buf));
+static qf_info_T *ll_get_or_alloc_list __ARGS((win_T *));
+
+/* Quickfix window check helper macro */
+#define IS_QF_WINDOW(wp) (bt_quickfix(wp->w_buffer) && wp->w_llist_ref == NULL)
+/* Location list window check helper macro */
+#define IS_LL_WINDOW(wp) (bt_quickfix(wp->w_buffer) && wp->w_llist_ref != NULL)
+/*
+ * Return location list for window 'wp'
+ * For location list window, return the referenced location list
+ */
+#define GET_LOC_LIST(wp) (IS_LL_WINDOW(wp) ? wp->w_llist_ref : wp->w_llist)
+
+/*
+ * Read the errorfile "efile" into memory, line by line, building the error
+ * list.
+ * Return -1 for error, number of errors for success.
+ */
+    int
+qf_init(wp, efile, errorformat, newlist)
+    win_T	    *wp;
+    char_u	    *efile;
+    char_u	    *errorformat;
+    int		    newlist;		/* TRUE: start a new error list */
+{
+    qf_info_T	    *qi = &ql_info;
+
+    if (efile == NULL)
+	return FAIL;
+
+    if (wp != NULL)
+    {
+	qi = ll_get_or_alloc_list(wp);
+	if (qi == NULL)
+	    return FAIL;
+    }
+
+    return qf_init_ext(qi, efile, curbuf, NULL, errorformat, newlist,
+						    (linenr_T)0, (linenr_T)0);
+}
+
+/*
+ * Read the errorfile "efile" into memory, line by line, building the error
+ * list.
+ * Alternative: when "efile" is null read errors from buffer "buf".
+ * Always use 'errorformat' from "buf" if there is a local value.
+ * Then lnumfirst and lnumlast specify the range of lines to use.
+ * Return -1 for error, number of errors for success.
+ */
+    static int
+qf_init_ext(qi, efile, buf, tv, errorformat, newlist, lnumfirst, lnumlast)
+    qf_info_T	    *qi;
+    char_u	    *efile;
+    buf_T	    *buf;
+    typval_T	    *tv;
+    char_u	    *errorformat;
+    int		    newlist;		/* TRUE: start a new error list */
+    linenr_T	    lnumfirst;		/* first line number to use */
+    linenr_T	    lnumlast;		/* last line number to use */
+{
+    char_u	    *namebuf;
+    char_u	    *errmsg;
+    char_u	    *pattern;
+    char_u	    *fmtstr = NULL;
+    int		    col = 0;
+    char_u	    use_viscol = FALSE;
+    int		    type = 0;
+    int		    valid;
+    linenr_T	    buflnum = lnumfirst;
+    long	    lnum = 0L;
+    int		    enr = 0;
+    FILE	    *fd = NULL;
+    qfline_T	    *qfprev = NULL;	/* init to make SASC shut up */
+    char_u	    *efmp;
+    efm_T	    *fmt_first = NULL;
+    efm_T	    *fmt_last = NULL;
+    efm_T	    *fmt_ptr;
+    efm_T	    *fmt_start = NULL;
+    char_u	    *efm;
+    char_u	    *ptr;
+    char_u	    *srcptr;
+    int		    len;
+    int		    i;
+    int		    round;
+    int		    idx = 0;
+    int		    multiline = FALSE;
+    int		    multiignore = FALSE;
+    int		    multiscan = FALSE;
+    int		    retval = -1;	/* default: return error flag */
+    char_u	    *directory = NULL;
+    char_u	    *currfile = NULL;
+    char_u	    *tail = NULL;
+    char_u	    *p_str = NULL;
+    listitem_T	    *p_li = NULL;
+    struct dir_stack_T  *file_stack = NULL;
+    regmatch_T	    regmatch;
+    static struct fmtpattern
+    {
+	char_u	convchar;
+	char	*pattern;
+    }		    fmt_pat[FMT_PATTERNS] =
+		    {
+			{'f', ".\\+"},	    /* only used when at end */
+			{'n', "\\d\\+"},
+			{'l', "\\d\\+"},
+			{'c', "\\d\\+"},
+			{'t', "."},
+			{'m', ".\\+"},
+			{'r', ".*"},
+			{'p', "[- .]*"},
+			{'v', "\\d\\+"},
+			{'s', ".\\+"}
+		    };
+
+    namebuf = alloc(CMDBUFFSIZE + 1);
+    errmsg = alloc(CMDBUFFSIZE + 1);
+    pattern = alloc(CMDBUFFSIZE + 1);
+    if (namebuf == NULL || errmsg == NULL || pattern == NULL)
+	goto qf_init_end;
+
+    if (efile != NULL && (fd = mch_fopen((char *)efile, "r")) == NULL)
+    {
+	EMSG2(_(e_openerrf), efile);
+	goto qf_init_end;
+    }
+
+    if (newlist || qi->qf_curlist == qi->qf_listcount)
+	/* make place for a new list */
+	qf_new_list(qi);
+    else if (qi->qf_lists[qi->qf_curlist].qf_count > 0)
+	/* Adding to existing list, find last entry. */
+	for (qfprev = qi->qf_lists[qi->qf_curlist].qf_start;
+			    qfprev->qf_next != qfprev; qfprev = qfprev->qf_next)
+	    ;
+
+/*
+ * Each part of the format string is copied and modified from errorformat to
+ * regex prog.  Only a few % characters are allowed.
+ */
+    /* Use the local value of 'errorformat' if it's set. */
+    if (errorformat == p_efm && tv == NULL && *buf->b_p_efm != NUL)
+	efm = buf->b_p_efm;
+    else
+	efm = errorformat;
+    /*
+     * Get some space to modify the format string into.
+     */
+    i = (FMT_PATTERNS * 3) + ((int)STRLEN(efm) << 2);
+    for (round = FMT_PATTERNS; round > 0; )
+	i += (int)STRLEN(fmt_pat[--round].pattern);
+#ifdef COLON_IN_FILENAME
+    i += 12; /* "%f" can become twelve chars longer */
+#else
+    i += 2; /* "%f" can become two chars longer */
+#endif
+    if ((fmtstr = alloc(i)) == NULL)
+	goto error2;
+
+    while (efm[0] != NUL)
+    {
+	/*
+	 * Allocate a new eformat structure and put it at the end of the list
+	 */
+	fmt_ptr = (efm_T *)alloc_clear((unsigned)sizeof(efm_T));
+	if (fmt_ptr == NULL)
+	    goto error2;
+	if (fmt_first == NULL)	    /* first one */
+	    fmt_first = fmt_ptr;
+	else
+	    fmt_last->next = fmt_ptr;
+	fmt_last = fmt_ptr;
+
+	/*
+	 * Isolate one part in the 'errorformat' option
+	 */
+	for (len = 0; efm[len] != NUL && efm[len] != ','; ++len)
+	    if (efm[len] == '\\' && efm[len + 1] != NUL)
+		++len;
+
+	/*
+	 * Build regexp pattern from current 'errorformat' option
+	 */
+	ptr = fmtstr;
+	*ptr++ = '^';
+	round = 0;
+	for (efmp = efm; efmp < efm + len; ++efmp)
+	{
+	    if (*efmp == '%')
+	    {
+		++efmp;
+		for (idx = 0; idx < FMT_PATTERNS; ++idx)
+		    if (fmt_pat[idx].convchar == *efmp)
+			break;
+		if (idx < FMT_PATTERNS)
+		{
+		    if (fmt_ptr->addr[idx])
+		    {
+			sprintf((char *)errmsg,
+				_("E372: Too many %%%c in format string"), *efmp);
+			EMSG(errmsg);
+			goto error2;
+		    }
+		    if ((idx
+				&& idx < 6
+				&& vim_strchr((char_u *)"DXOPQ",
+						     fmt_ptr->prefix) != NULL)
+			    || (idx == 6
+				&& vim_strchr((char_u *)"OPQ",
+						    fmt_ptr->prefix) == NULL))
+		    {
+			sprintf((char *)errmsg,
+				_("E373: Unexpected %%%c in format string"), *efmp);
+			EMSG(errmsg);
+			goto error2;
+		    }
+		    fmt_ptr->addr[idx] = (char_u)++round;
+		    *ptr++ = '\\';
+		    *ptr++ = '(';
+#ifdef BACKSLASH_IN_FILENAME
+		    if (*efmp == 'f')
+		    {
+			/* Also match "c:" in the file name, even when
+			 * checking for a colon next: "%f:".
+			 * "\%(\a:\)\=" */
+			STRCPY(ptr, "\\%(\\a:\\)\\=");
+			ptr += 10;
+		    }
+#endif
+		    if (*efmp == 'f' && efmp[1] != NUL)
+		    {
+			if (efmp[1] != '\\' && efmp[1] != '%')
+			{
+			    /* A file name may contain spaces, but this isn't
+			     * in "\f".  For "%f:%l:%m" there may be a ":" in
+			     * the file name.  Use ".\{-1,}x" instead (x is
+			     * the next character), the requirement that :999:
+			     * follows should work. */
+			    STRCPY(ptr, ".\\{-1,}");
+			    ptr += 7;
+			}
+			else
+			{
+			    /* File name followed by '\\' or '%': include as
+			     * many file name chars as possible. */
+			    STRCPY(ptr, "\\f\\+");
+			    ptr += 4;
+			}
+		    }
+		    else
+		    {
+			srcptr = (char_u *)fmt_pat[idx].pattern;
+			while ((*ptr = *srcptr++) != NUL)
+			    ++ptr;
+		    }
+		    *ptr++ = '\\';
+		    *ptr++ = ')';
+		}
+		else if (*efmp == '*')
+		{
+		    if (*++efmp == '[' || *efmp == '\\')
+		    {
+			if ((*ptr++ = *efmp) == '[')	/* %*[^a-z0-9] etc. */
+			{
+			    if (efmp[1] == '^')
+				*ptr++ = *++efmp;
+			    if (efmp < efm + len)
+			    {
+				*ptr++ = *++efmp;	    /* could be ']' */
+				while (efmp < efm + len
+					&& (*ptr++ = *++efmp) != ']')
+				    /* skip */;
+				if (efmp == efm + len)
+				{
+				    EMSG(_("E374: Missing ] in format string"));
+				    goto error2;
+				}
+			    }
+			}
+			else if (efmp < efm + len)	/* %*\D, %*\s etc. */
+			    *ptr++ = *++efmp;
+			*ptr++ = '\\';
+			*ptr++ = '+';
+		    }
+		    else
+		    {
+			/* TODO: scanf()-like: %*ud, %*3c, %*f, ... ? */
+			sprintf((char *)errmsg,
+				_("E375: Unsupported %%%c in format string"), *efmp);
+			EMSG(errmsg);
+			goto error2;
+		    }
+		}
+		else if (vim_strchr((char_u *)"%\\.^$~[", *efmp) != NULL)
+		    *ptr++ = *efmp;		/* regexp magic characters */
+		else if (*efmp == '#')
+		    *ptr++ = '*';
+		else if (*efmp == '>')
+		    fmt_ptr->conthere = TRUE;
+		else if (efmp == efm + 1)		/* analyse prefix */
+		{
+		    if (vim_strchr((char_u *)"+-", *efmp) != NULL)
+			fmt_ptr->flags = *efmp++;
+		    if (vim_strchr((char_u *)"DXAEWICZGOPQ", *efmp) != NULL)
+			fmt_ptr->prefix = *efmp;
+		    else
+		    {
+			sprintf((char *)errmsg,
+				_("E376: Invalid %%%c in format string prefix"), *efmp);
+			EMSG(errmsg);
+			goto error2;
+		    }
+		}
+		else
+		{
+		    sprintf((char *)errmsg,
+			    _("E377: Invalid %%%c in format string"), *efmp);
+		    EMSG(errmsg);
+		    goto error2;
+		}
+	    }
+	    else			/* copy normal character */
+	    {
+		if (*efmp == '\\' && efmp + 1 < efm + len)
+		    ++efmp;
+		else if (vim_strchr((char_u *)".*^$~[", *efmp) != NULL)
+		    *ptr++ = '\\';	/* escape regexp atoms */
+		if (*efmp)
+		    *ptr++ = *efmp;
+	    }
+	}
+	*ptr++ = '$';
+	*ptr = NUL;
+	if ((fmt_ptr->prog = vim_regcomp(fmtstr, RE_MAGIC + RE_STRING)) == NULL)
+	    goto error2;
+	/*
+	 * Advance to next part
+	 */
+	efm = skip_to_option_part(efm + len);	/* skip comma and spaces */
+    }
+    if (fmt_first == NULL)	/* nothing found */
+    {
+	EMSG(_("E378: 'errorformat' contains no pattern"));
+	goto error2;
+    }
+
+    /*
+     * got_int is reset here, because it was probably set when killing the
+     * ":make" command, but we still want to read the errorfile then.
+     */
+    got_int = FALSE;
+
+    /* Always ignore case when looking for a matching error. */
+    regmatch.rm_ic = TRUE;
+
+    if (tv != NULL)
+    {
+	if (tv->v_type == VAR_STRING)
+	    p_str = tv->vval.v_string;
+	else if (tv->v_type == VAR_LIST)
+	    p_li = tv->vval.v_list->lv_first;
+    }
+
+    /*
+     * Read the lines in the error file one by one.
+     * Try to recognize one of the error formats in each line.
+     */
+    while (!got_int)
+    {
+	/* Get the next line. */
+	if (fd == NULL)
+	{
+	    if (tv != NULL)
+	    {
+		if (tv->v_type == VAR_STRING)
+		{
+		    /* Get the next line from the supplied string */
+		    char_u *p;
+
+		    if (!*p_str) /* Reached the end of the string */
+			break;
+
+		    p = vim_strchr(p_str, '\n');
+		    if (p)
+			len = (int)(p - p_str + 1);
+		    else
+			len = (int)STRLEN(p_str);
+
+		    if (len > CMDBUFFSIZE - 2)
+			vim_strncpy(IObuff, p_str, CMDBUFFSIZE - 2);
+		    else
+			vim_strncpy(IObuff, p_str, len);
+
+		    p_str += len;
+		}
+		else if (tv->v_type == VAR_LIST)
+		{
+		    /* Get the next line from the supplied list */
+		    while (p_li && p_li->li_tv.v_type != VAR_STRING)
+			p_li = p_li->li_next;	/* Skip non-string items */
+
+		    if (!p_li)			/* End of the list */
+			break;
+
+		    len = (int)STRLEN(p_li->li_tv.vval.v_string);
+		    if (len > CMDBUFFSIZE - 2)
+			len = CMDBUFFSIZE - 2;
+
+		    vim_strncpy(IObuff, p_li->li_tv.vval.v_string, len);
+
+		    p_li = p_li->li_next;	/* next item */
+		}
+	    }
+	    else
+	    {
+		/* Get the next line from the supplied buffer */
+		if (buflnum > lnumlast)
+		    break;
+		vim_strncpy(IObuff, ml_get_buf(buf, buflnum++, FALSE),
+			    CMDBUFFSIZE - 2);
+	    }
+	}
+	else if (fgets((char *)IObuff, CMDBUFFSIZE - 2, fd) == NULL)
+	    break;
+
+	IObuff[CMDBUFFSIZE - 2] = NUL;  /* for very long lines */
+	if ((efmp = vim_strrchr(IObuff, '\n')) != NULL)
+	    *efmp = NUL;
+#ifdef USE_CRNL
+	if ((efmp = vim_strrchr(IObuff, '\r')) != NULL)
+	    *efmp = NUL;
+#endif
+
+	/* If there was no %> item start at the first pattern */
+	if (fmt_start == NULL)
+	    fmt_ptr = fmt_first;
+	else
+	{
+	    fmt_ptr = fmt_start;
+	    fmt_start = NULL;
+	}
+
+	/*
+	 * Try to match each part of 'errorformat' until we find a complete
+	 * match or no match.
+	 */
+	valid = TRUE;
+restofline:
+	for ( ; fmt_ptr != NULL; fmt_ptr = fmt_ptr->next)
+	{
+	    idx = fmt_ptr->prefix;
+	    if (multiscan && vim_strchr((char_u *)"OPQ", idx) == NULL)
+		continue;
+	    namebuf[0] = NUL;
+	    pattern[0] = NUL;
+	    if (!multiscan)
+		errmsg[0] = NUL;
+	    lnum = 0;
+	    col = 0;
+	    use_viscol = FALSE;
+	    enr = -1;
+	    type = 0;
+	    tail = NULL;
+
+	    regmatch.regprog = fmt_ptr->prog;
+	    if (vim_regexec(&regmatch, IObuff, (colnr_T)0))
+	    {
+		if ((idx == 'C' || idx == 'Z') && !multiline)
+		    continue;
+		if (vim_strchr((char_u *)"EWI", idx) != NULL)
+		    type = idx;
+		else
+		    type = 0;
+		/*
+		 * Extract error message data from matched line.
+		 * We check for an actual submatch, because "\[" and "\]" in
+		 * the 'errorformat' may cause the wrong submatch to be used.
+		 */
+		if ((i = (int)fmt_ptr->addr[0]) > 0)		/* %f */
+		{
+		    int c;
+
+		    if (regmatch.startp[i] == NULL || regmatch.endp[i] == NULL)
+			continue;
+
+		    /* Expand ~/file and $HOME/file to full path. */
+		    c = *regmatch.endp[i];
+		    *regmatch.endp[i] = NUL;
+		    expand_env(regmatch.startp[i], namebuf, CMDBUFFSIZE);
+		    *regmatch.endp[i] = c;
+
+		    if (vim_strchr((char_u *)"OPQ", idx) != NULL
+						&& mch_getperm(namebuf) == -1)
+			continue;
+		}
+		if ((i = (int)fmt_ptr->addr[1]) > 0)		/* %n */
+		{
+		    if (regmatch.startp[i] == NULL)
+			continue;
+		    enr = (int)atol((char *)regmatch.startp[i]);
+		}
+		if ((i = (int)fmt_ptr->addr[2]) > 0)		/* %l */
+		{
+		    if (regmatch.startp[i] == NULL)
+			continue;
+		    lnum = atol((char *)regmatch.startp[i]);
+		}
+		if ((i = (int)fmt_ptr->addr[3]) > 0)		/* %c */
+		{
+		    if (regmatch.startp[i] == NULL)
+			continue;
+		    col = (int)atol((char *)regmatch.startp[i]);
+		}
+		if ((i = (int)fmt_ptr->addr[4]) > 0)		/* %t */
+		{
+		    if (regmatch.startp[i] == NULL)
+			continue;
+		    type = *regmatch.startp[i];
+		}
+		if (fmt_ptr->flags == '+' && !multiscan)	/* %+ */
+		    STRCPY(errmsg, IObuff);
+		else if ((i = (int)fmt_ptr->addr[5]) > 0)	/* %m */
+		{
+		    if (regmatch.startp[i] == NULL || regmatch.endp[i] == NULL)
+			continue;
+		    len = (int)(regmatch.endp[i] - regmatch.startp[i]);
+		    vim_strncpy(errmsg, regmatch.startp[i], len);
+		}
+		if ((i = (int)fmt_ptr->addr[6]) > 0)		/* %r */
+		{
+		    if (regmatch.startp[i] == NULL)
+			continue;
+		    tail = regmatch.startp[i];
+		}
+		if ((i = (int)fmt_ptr->addr[7]) > 0)		/* %p */
+		{
+		    if (regmatch.startp[i] == NULL || regmatch.endp[i] == NULL)
+			continue;
+		    col = (int)(regmatch.endp[i] - regmatch.startp[i] + 1);
+		    if (*((char_u *)regmatch.startp[i]) != TAB)
+			use_viscol = TRUE;
+		}
+		if ((i = (int)fmt_ptr->addr[8]) > 0)		/* %v */
+		{
+		    if (regmatch.startp[i] == NULL)
+			continue;
+		    col = (int)atol((char *)regmatch.startp[i]);
+		    use_viscol = TRUE;
+		}
+		if ((i = (int)fmt_ptr->addr[9]) > 0)		/* %s */
+		{
+		    if (regmatch.startp[i] == NULL || regmatch.endp[i] == NULL)
+			continue;
+		    len = (int)(regmatch.endp[i] - regmatch.startp[i]);
+		    if (len > CMDBUFFSIZE - 5)
+			len = CMDBUFFSIZE - 5;
+		    STRCPY(pattern, "^\\V");
+		    STRNCAT(pattern, regmatch.startp[i], len);
+		    pattern[len + 3] = '\\';
+		    pattern[len + 4] = '$';
+		    pattern[len + 5] = NUL;
+		}
+		break;
+	    }
+	}
+	multiscan = FALSE;
+
+	if (fmt_ptr == NULL || idx == 'D' || idx == 'X')
+	{
+	    if (fmt_ptr != NULL)
+	    {
+		if (idx == 'D')				/* enter directory */
+		{
+		    if (*namebuf == NUL)
+		    {
+			EMSG(_("E379: Missing or empty directory name"));
+			goto error2;
+		    }
+		    if ((directory = qf_push_dir(namebuf, &dir_stack)) == NULL)
+			goto error2;
+		}
+		else if (idx == 'X')			/* leave directory */
+		    directory = qf_pop_dir(&dir_stack);
+	    }
+	    namebuf[0] = NUL;		/* no match found, remove file name */
+	    lnum = 0;			/* don't jump to this line */
+	    valid = FALSE;
+	    STRCPY(errmsg, IObuff);	/* copy whole line to error message */
+	    if (fmt_ptr == NULL)
+		multiline = multiignore = FALSE;
+	}
+	else if (fmt_ptr != NULL)
+	{
+	    /* honor %> item */
+	    if (fmt_ptr->conthere)
+		fmt_start = fmt_ptr;
+
+	    if (vim_strchr((char_u *)"AEWI", idx) != NULL)
+		multiline = TRUE;	/* start of a multi-line message */
+	    else if (vim_strchr((char_u *)"CZ", idx) != NULL)
+	    {				/* continuation of multi-line msg */
+		if (qfprev == NULL)
+		    goto error2;
+		if (*errmsg && !multiignore)
+		{
+		    len = (int)STRLEN(qfprev->qf_text);
+		    if ((ptr = alloc((unsigned)(len + STRLEN(errmsg) + 2)))
+								    == NULL)
+			goto error2;
+		    STRCPY(ptr, qfprev->qf_text);
+		    vim_free(qfprev->qf_text);
+		    qfprev->qf_text = ptr;
+		    *(ptr += len) = '\n';
+		    STRCPY(++ptr, errmsg);
+		}
+		if (qfprev->qf_nr == -1)
+		    qfprev->qf_nr = enr;
+		if (vim_isprintc(type) && !qfprev->qf_type)
+		    qfprev->qf_type = type;  /* only printable chars allowed */
+		if (!qfprev->qf_lnum)
+		    qfprev->qf_lnum = lnum;
+		if (!qfprev->qf_col)
+		    qfprev->qf_col = col;
+		qfprev->qf_viscol = use_viscol;
+		if (!qfprev->qf_fnum)
+		    qfprev->qf_fnum = qf_get_fnum(directory,
+					*namebuf || directory ? namebuf
+					  : currfile && valid ? currfile : 0);
+		if (idx == 'Z')
+		    multiline = multiignore = FALSE;
+		line_breakcheck();
+		continue;
+	    }
+	    else if (vim_strchr((char_u *)"OPQ", idx) != NULL)
+	    {
+		/* global file names */
+		valid = FALSE;
+		if (*namebuf == NUL || mch_getperm(namebuf) >= 0)
+		{
+		    if (*namebuf && idx == 'P')
+			currfile = qf_push_dir(namebuf, &file_stack);
+		    else if (idx == 'Q')
+			currfile = qf_pop_dir(&file_stack);
+		    *namebuf = NUL;
+		    if (tail && *tail)
+		    {
+			STRCPY(IObuff, skipwhite(tail));
+			multiscan = TRUE;
+			goto restofline;
+		    }
+		}
+	    }
+	    if (fmt_ptr->flags == '-')	/* generally exclude this line */
+	    {
+		if (multiline)
+		    multiignore = TRUE;	/* also exclude continuation lines */
+		continue;
+	    }
+	}
+
+	if (qf_add_entry(qi, &qfprev,
+			directory,
+			(*namebuf || directory)
+			    ? namebuf
+			    : ((currfile && valid) ? currfile : (char_u *)NULL),
+			0,
+			errmsg,
+			lnum,
+			col,
+			use_viscol,
+			pattern,
+			enr,
+			type,
+			valid) == FAIL)
+	    goto error2;
+	line_breakcheck();
+    }
+    if (fd == NULL || !ferror(fd))
+    {
+	if (qi->qf_lists[qi->qf_curlist].qf_index == 0)
+	{
+	    /* no valid entry found */
+	    qi->qf_lists[qi->qf_curlist].qf_ptr =
+		qi->qf_lists[qi->qf_curlist].qf_start;
+	    qi->qf_lists[qi->qf_curlist].qf_index = 1;
+	    qi->qf_lists[qi->qf_curlist].qf_nonevalid = TRUE;
+	}
+	else
+	{
+	    qi->qf_lists[qi->qf_curlist].qf_nonevalid = FALSE;
+	    if (qi->qf_lists[qi->qf_curlist].qf_ptr == NULL)
+		qi->qf_lists[qi->qf_curlist].qf_ptr =
+		    qi->qf_lists[qi->qf_curlist].qf_start;
+	}
+	/* return number of matches */
+	retval = qi->qf_lists[qi->qf_curlist].qf_count;
+	goto qf_init_ok;
+    }
+    EMSG(_(e_readerrf));
+error2:
+    qf_free(qi, qi->qf_curlist);
+    qi->qf_listcount--;
+    if (qi->qf_curlist > 0)
+	--qi->qf_curlist;
+qf_init_ok:
+    if (fd != NULL)
+	fclose(fd);
+    for (fmt_ptr = fmt_first; fmt_ptr != NULL; fmt_ptr = fmt_first)
+    {
+	fmt_first = fmt_ptr->next;
+	vim_free(fmt_ptr->prog);
+	vim_free(fmt_ptr);
+    }
+    qf_clean_dir_stack(&dir_stack);
+    qf_clean_dir_stack(&file_stack);
+qf_init_end:
+    vim_free(namebuf);
+    vim_free(errmsg);
+    vim_free(pattern);
+    vim_free(fmtstr);
+
+#ifdef FEAT_WINDOWS
+    qf_update_buffer(qi);
+#endif
+
+    return retval;
+}
+
+/*
+ * Prepare for adding a new quickfix list.
+ */
+    static void
+qf_new_list(qi)
+    qf_info_T	*qi;
+{
+    int		i;
+
+    /*
+     * If the current entry is not the last entry, delete entries below
+     * the current entry.  This makes it possible to browse in a tree-like
+     * way with ":grep'.
+     */
+    while (qi->qf_listcount > qi->qf_curlist + 1)
+	qf_free(qi, --qi->qf_listcount);
+
+    /*
+     * When the stack is full, remove to oldest entry
+     * Otherwise, add a new entry.
+     */
+    if (qi->qf_listcount == LISTCOUNT)
+    {
+	qf_free(qi, 0);
+	for (i = 1; i < LISTCOUNT; ++i)
+	    qi->qf_lists[i - 1] = qi->qf_lists[i];
+	qi->qf_curlist = LISTCOUNT - 1;
+    }
+    else
+	qi->qf_curlist = qi->qf_listcount++;
+    qi->qf_lists[qi->qf_curlist].qf_index = 0;
+    qi->qf_lists[qi->qf_curlist].qf_count = 0;
+}
+
+/*
+ * Free a location list
+ */
+    static void
+ll_free_all(pqi)
+    qf_info_T	**pqi;
+{
+    int		i;
+    qf_info_T	*qi;
+
+    qi = *pqi;
+    if (qi == NULL)
+	return;
+    *pqi = NULL;	/* Remove reference to this list */
+
+    qi->qf_refcount--;
+    if (qi->qf_refcount < 1)
+    {
+	/* No references to this location list */
+	for (i = 0; i < qi->qf_listcount; ++i)
+	    qf_free(qi, i);
+	vim_free(qi);
+    }
+}
+
+    void
+qf_free_all(wp)
+    win_T	*wp;
+{
+    int		i;
+    qf_info_T	*qi = &ql_info;
+
+    if (wp != NULL)
+    {
+	/* location list */
+	ll_free_all(&wp->w_llist);
+	ll_free_all(&wp->w_llist_ref);
+    }
+    else
+	/* quickfix list */
+	for (i = 0; i < qi->qf_listcount; ++i)
+	    qf_free(qi, i);
+}
+
+/*
+ * Add an entry to the end of the list of errors.
+ * Returns OK or FAIL.
+ */
+    static int
+qf_add_entry(qi, prevp, dir, fname, bufnum, mesg, lnum, col, vis_col, pattern,
+	     nr, type, valid)
+    qf_info_T	*qi;		/* quickfix list */
+    qfline_T	**prevp;	/* pointer to previously added entry or NULL */
+    char_u	*dir;		/* optional directory name */
+    char_u	*fname;		/* file name or NULL */
+    int		bufnum;		/* buffer number or zero */
+    char_u	*mesg;		/* message */
+    long	lnum;		/* line number */
+    int		col;		/* column */
+    int		vis_col;	/* using visual column */
+    char_u	*pattern;	/* search pattern */
+    int		nr;		/* error number */
+    int		type;		/* type character */
+    int		valid;		/* valid entry */
+{
+    qfline_T	*qfp;
+
+    if ((qfp = (qfline_T *)alloc((unsigned)sizeof(qfline_T))) == NULL)
+	return FAIL;
+    if (bufnum != 0)
+	qfp->qf_fnum = bufnum;
+    else
+	qfp->qf_fnum = qf_get_fnum(dir, fname);
+    if ((qfp->qf_text = vim_strsave(mesg)) == NULL)
+    {
+	vim_free(qfp);
+	return FAIL;
+    }
+    qfp->qf_lnum = lnum;
+    qfp->qf_col = col;
+    qfp->qf_viscol = vis_col;
+    if (pattern == NULL || *pattern == NUL)
+	qfp->qf_pattern = NULL;
+    else if ((qfp->qf_pattern = vim_strsave(pattern)) == NULL)
+    {
+	vim_free(qfp->qf_text);
+	vim_free(qfp);
+	return FAIL;
+    }
+    qfp->qf_nr = nr;
+    if (type != 1 && !vim_isprintc(type)) /* only printable chars allowed */
+	type = 0;
+    qfp->qf_type = type;
+    qfp->qf_valid = valid;
+
+    if (qi->qf_lists[qi->qf_curlist].qf_count == 0)
+				/* first element in the list */
+    {
+	qi->qf_lists[qi->qf_curlist].qf_start = qfp;
+	qfp->qf_prev = qfp;	/* first element points to itself */
+    }
+    else
+    {
+	qfp->qf_prev = *prevp;
+	(*prevp)->qf_next = qfp;
+    }
+    qfp->qf_next = qfp;	/* last element points to itself */
+    qfp->qf_cleared = FALSE;
+    *prevp = qfp;
+    ++qi->qf_lists[qi->qf_curlist].qf_count;
+    if (qi->qf_lists[qi->qf_curlist].qf_index == 0 && qfp->qf_valid)
+				/* first valid entry */
+    {
+	qi->qf_lists[qi->qf_curlist].qf_index =
+	    qi->qf_lists[qi->qf_curlist].qf_count;
+	qi->qf_lists[qi->qf_curlist].qf_ptr = qfp;
+    }
+
+    return OK;
+}
+
+/*
+ * Allocate a new location list
+ */
+    static qf_info_T *
+ll_new_list()
+{
+    qf_info_T *qi;
+
+    qi = (qf_info_T *)alloc((unsigned)sizeof(qf_info_T));
+    if (qi != NULL)
+    {
+	vim_memset(qi, 0, (size_t)(sizeof(qf_info_T)));
+	qi->qf_refcount++;
+    }
+
+    return qi;
+}
+
+/*
+ * Return the location list for window 'wp'.
+ * If not present, allocate a location list
+ */
+    static qf_info_T *
+ll_get_or_alloc_list(wp)
+    win_T   *wp;
+{
+    if (IS_LL_WINDOW(wp))
+	/* For a location list window, use the referenced location list */
+	return wp->w_llist_ref;
+
+    /*
+     * For a non-location list window, w_llist_ref should not point to a
+     * location list.
+     */
+    ll_free_all(&wp->w_llist_ref);
+
+    if (wp->w_llist == NULL)
+	wp->w_llist = ll_new_list();	    /* new location list */
+    return wp->w_llist;
+}
+
+/*
+ * Copy the location list from window "from" to window "to".
+ */
+    void
+copy_loclist(from, to)
+    win_T	*from;
+    win_T	*to;
+{
+    qf_info_T	*qi;
+    int		idx;
+    int		i;
+
+    /*
+     * When copying from a location list window, copy the referenced
+     * location list. For other windows, copy the location list for
+     * that window.
+     */
+    if (IS_LL_WINDOW(from))
+	qi = from->w_llist_ref;
+    else
+	qi = from->w_llist;
+
+    if (qi == NULL)		    /* no location list to copy */
+	return;
+
+    /* allocate a new location list */
+    if ((to->w_llist = ll_new_list()) == NULL)
+	return;
+
+    to->w_llist->qf_listcount = qi->qf_listcount;
+
+    /* Copy the location lists one at a time */
+    for (idx = 0; idx < qi->qf_listcount; idx++)
+    {
+	qf_list_T   *from_qfl;
+	qf_list_T   *to_qfl;
+
+	to->w_llist->qf_curlist = idx;
+
+	from_qfl = &qi->qf_lists[idx];
+	to_qfl = &to->w_llist->qf_lists[idx];
+
+	/* Some of the fields are populated by qf_add_entry() */
+	to_qfl->qf_nonevalid = from_qfl->qf_nonevalid;
+	to_qfl->qf_count = 0;
+	to_qfl->qf_index = 0;
+	to_qfl->qf_start = NULL;
+	to_qfl->qf_ptr = NULL;
+
+	if (from_qfl->qf_count)
+	{
+	    qfline_T    *from_qfp;
+	    qfline_T    *prevp = NULL;
+
+	    /* copy all the location entries in this list */
+	    for (i = 0, from_qfp = from_qfl->qf_start; i < from_qfl->qf_count;
+		 ++i, from_qfp = from_qfp->qf_next)
+	    {
+		if (qf_add_entry(to->w_llist, &prevp,
+				 NULL,
+				 NULL,
+				 0,
+				 from_qfp->qf_text,
+				 from_qfp->qf_lnum,
+				 from_qfp->qf_col,
+				 from_qfp->qf_viscol,
+				 from_qfp->qf_pattern,
+				 from_qfp->qf_nr,
+				 0,
+				 from_qfp->qf_valid) == FAIL)
+		{
+		    qf_free_all(to);
+		    return;
+		}
+		/*
+		 * qf_add_entry() will not set the qf_num field, as the
+		 * directory and file names are not supplied. So the qf_fnum
+		 * field is copied here.
+		 */
+		prevp->qf_fnum = from_qfp->qf_fnum; /* file number */
+		prevp->qf_type = from_qfp->qf_type; /* error type */
+		if (from_qfl->qf_ptr == from_qfp)
+		    to_qfl->qf_ptr = prevp;	    /* current location */
+	    }
+	}
+
+	to_qfl->qf_index = from_qfl->qf_index;	/* current index in the list */
+
+	/* When no valid entries are present in the list, qf_ptr points to
+	 * the first item in the list */
+	if (to_qfl->qf_nonevalid == TRUE)
+	    to_qfl->qf_ptr = to_qfl->qf_start;
+    }
+
+    to->w_llist->qf_curlist = qi->qf_curlist;	/* current list */
+}
+
+/*
+ * get buffer number for file "dir.name"
+ */
+    static int
+qf_get_fnum(directory, fname)
+    char_u   *directory;
+    char_u   *fname;
+{
+    if (fname == NULL || *fname == NUL)		/* no file name */
+	return 0;
+    {
+#ifdef RISCOS
+	/* Name is reported as `main.c', but file is `c.main' */
+	return ro_buflist_add(fname);
+#else
+	char_u	    *ptr;
+	int	    fnum;
+
+# ifdef VMS
+	vms_remove_version(fname);
+# endif
+# ifdef BACKSLASH_IN_FILENAME
+	if (directory != NULL)
+	    slash_adjust(directory);
+	slash_adjust(fname);
+# endif
+	if (directory != NULL && !vim_isAbsName(fname)
+		&& (ptr = concat_fnames(directory, fname, TRUE)) != NULL)
+	{
+	    /*
+	     * Here we check if the file really exists.
+	     * This should normally be true, but if make works without
+	     * "leaving directory"-messages we might have missed a
+	     * directory change.
+	     */
+	    if (mch_getperm(ptr) < 0)
+	    {
+		vim_free(ptr);
+		directory = qf_guess_filepath(fname);
+		if (directory)
+		    ptr = concat_fnames(directory, fname, TRUE);
+		else
+		    ptr = vim_strsave(fname);
+	    }
+	    /* Use concatenated directory name and file name */
+	    fnum = buflist_add(ptr, 0);
+	    vim_free(ptr);
+	    return fnum;
+	}
+	return buflist_add(fname, 0);
+#endif
+    }
+}
+
+/*
+ * push dirbuf onto the directory stack and return pointer to actual dir or
+ * NULL on error
+ */
+    static char_u *
+qf_push_dir(dirbuf, stackptr)
+    char_u		*dirbuf;
+    struct dir_stack_T	**stackptr;
+{
+    struct dir_stack_T  *ds_new;
+    struct dir_stack_T  *ds_ptr;
+
+    /* allocate new stack element and hook it in */
+    ds_new = (struct dir_stack_T *)alloc((unsigned)sizeof(struct dir_stack_T));
+    if (ds_new == NULL)
+	return NULL;
+
+    ds_new->next = *stackptr;
+    *stackptr = ds_new;
+
+    /* store directory on the stack */
+    if (vim_isAbsName(dirbuf)
+	    || (*stackptr)->next == NULL
+	    || (*stackptr && dir_stack != *stackptr))
+	(*stackptr)->dirname = vim_strsave(dirbuf);
+    else
+    {
+	/* Okay we don't have an absolute path.
+	 * dirbuf must be a subdir of one of the directories on the stack.
+	 * Let's search...
+	 */
+	ds_new = (*stackptr)->next;
+	(*stackptr)->dirname = NULL;
+	while (ds_new)
+	{
+	    vim_free((*stackptr)->dirname);
+	    (*stackptr)->dirname = concat_fnames(ds_new->dirname, dirbuf,
+		    TRUE);
+	    if (mch_isdir((*stackptr)->dirname) == TRUE)
+		break;
+
+	    ds_new = ds_new->next;
+	}
+
+	/* clean up all dirs we already left */
+	while ((*stackptr)->next != ds_new)
+	{
+	    ds_ptr = (*stackptr)->next;
+	    (*stackptr)->next = (*stackptr)->next->next;
+	    vim_free(ds_ptr->dirname);
+	    vim_free(ds_ptr);
+	}
+
+	/* Nothing found -> it must be on top level */
+	if (ds_new == NULL)
+	{
+	    vim_free((*stackptr)->dirname);
+	    (*stackptr)->dirname = vim_strsave(dirbuf);
+	}
+    }
+
+    if ((*stackptr)->dirname != NULL)
+	return (*stackptr)->dirname;
+    else
+    {
+	ds_ptr = *stackptr;
+	*stackptr = (*stackptr)->next;
+	vim_free(ds_ptr);
+	return NULL;
+    }
+}
+
+
+/*
+ * pop dirbuf from the directory stack and return previous directory or NULL if
+ * stack is empty
+ */
+    static char_u *
+qf_pop_dir(stackptr)
+    struct dir_stack_T	**stackptr;
+{
+    struct dir_stack_T  *ds_ptr;
+
+    /* TODO: Should we check if dirbuf is the directory on top of the stack?
+     * What to do if it isn't? */
+
+    /* pop top element and free it */
+    if (*stackptr != NULL)
+    {
+	ds_ptr = *stackptr;
+	*stackptr = (*stackptr)->next;
+	vim_free(ds_ptr->dirname);
+	vim_free(ds_ptr);
+    }
+
+    /* return NEW top element as current dir or NULL if stack is empty*/
+    return *stackptr ? (*stackptr)->dirname : NULL;
+}
+
+/*
+ * clean up directory stack
+ */
+    static void
+qf_clean_dir_stack(stackptr)
+    struct dir_stack_T	**stackptr;
+{
+    struct dir_stack_T  *ds_ptr;
+
+    while ((ds_ptr = *stackptr) != NULL)
+    {
+	*stackptr = (*stackptr)->next;
+	vim_free(ds_ptr->dirname);
+	vim_free(ds_ptr);
+    }
+}
+
+/*
+ * Check in which directory of the directory stack the given file can be
+ * found.
+ * Returns a pointer to the directory name or NULL if not found
+ * Cleans up intermediate directory entries.
+ *
+ * TODO: How to solve the following problem?
+ * If we have the this directory tree:
+ *     ./
+ *     ./aa
+ *     ./aa/bb
+ *     ./bb
+ *     ./bb/x.c
+ * and make says:
+ *     making all in aa
+ *     making all in bb
+ *     x.c:9: Error
+ * Then qf_push_dir thinks we are in ./aa/bb, but we are in ./bb.
+ * qf_guess_filepath will return NULL.
+ */
+    static char_u *
+qf_guess_filepath(filename)
+    char_u *filename;
+{
+    struct dir_stack_T     *ds_ptr;
+    struct dir_stack_T     *ds_tmp;
+    char_u		   *fullname;
+
+    /* no dirs on the stack - there's nothing we can do */
+    if (dir_stack == NULL)
+	return NULL;
+
+    ds_ptr = dir_stack->next;
+    fullname = NULL;
+    while (ds_ptr)
+    {
+	vim_free(fullname);
+	fullname = concat_fnames(ds_ptr->dirname, filename, TRUE);
+
+	/* If concat_fnames failed, just go on. The worst thing that can happen
+	 * is that we delete the entire stack.
+	 */
+	if ((fullname != NULL) && (mch_getperm(fullname) >= 0))
+	    break;
+
+	ds_ptr = ds_ptr->next;
+    }
+
+    vim_free(fullname);
+
+    /* clean up all dirs we already left */
+    while (dir_stack->next != ds_ptr)
+    {
+	ds_tmp = dir_stack->next;
+	dir_stack->next = dir_stack->next->next;
+	vim_free(ds_tmp->dirname);
+	vim_free(ds_tmp);
+    }
+
+    return ds_ptr==NULL? NULL: ds_ptr->dirname;
+
+}
+
+/*
+ * jump to a quickfix line
+ * if dir == FORWARD go "errornr" valid entries forward
+ * if dir == BACKWARD go "errornr" valid entries backward
+ * if dir == FORWARD_FILE go "errornr" valid entries files backward
+ * if dir == BACKWARD_FILE go "errornr" valid entries files backward
+ * else if "errornr" is zero, redisplay the same line
+ * else go to entry "errornr"
+ */
+    void
+qf_jump(qi, dir, errornr, forceit)
+    qf_info_T	*qi;
+    int		dir;
+    int		errornr;
+    int		forceit;
+{
+    qf_info_T		*ll_ref;
+    qfline_T		*qf_ptr;
+    qfline_T		*old_qf_ptr;
+    int			qf_index;
+    int			old_qf_fnum;
+    int			old_qf_index;
+    int			prev_index;
+    static char_u	*e_no_more_items = (char_u *)N_("E553: No more items");
+    char_u		*err = e_no_more_items;
+    linenr_T		i;
+    buf_T		*old_curbuf;
+    linenr_T		old_lnum;
+    colnr_T		screen_col;
+    colnr_T		char_col;
+    char_u		*line;
+#ifdef FEAT_WINDOWS
+    char_u		*old_swb = p_swb;
+    int			opened_window = FALSE;
+    win_T		*win;
+    win_T		*altwin;
+#endif
+    int			print_message = TRUE;
+    int			len;
+#ifdef FEAT_FOLDING
+    int			old_KeyTyped = KeyTyped; /* getting file may reset it */
+#endif
+    int			ok = OK;
+    int			usable_win;
+
+    if (qi == NULL)
+	qi = &ql_info;
+
+    if (qi->qf_curlist >= qi->qf_listcount
+	|| qi->qf_lists[qi->qf_curlist].qf_count == 0)
+    {
+	EMSG(_(e_quickfix));
+	return;
+    }
+
+    qf_ptr = qi->qf_lists[qi->qf_curlist].qf_ptr;
+    old_qf_ptr = qf_ptr;
+    qf_index = qi->qf_lists[qi->qf_curlist].qf_index;
+    old_qf_index = qf_index;
+    if (dir == FORWARD || dir == FORWARD_FILE)	    /* next valid entry */
+    {
+	while (errornr--)
+	{
+	    old_qf_ptr = qf_ptr;
+	    prev_index = qf_index;
+	    old_qf_fnum = qf_ptr->qf_fnum;
+	    do
+	    {
+		if (qf_index == qi->qf_lists[qi->qf_curlist].qf_count
+						   || qf_ptr->qf_next == NULL)
+		{
+		    qf_ptr = old_qf_ptr;
+		    qf_index = prev_index;
+		    if (err != NULL)
+		    {
+			EMSG(_(err));
+			goto theend;
+		    }
+		    errornr = 0;
+		    break;
+		}
+		++qf_index;
+		qf_ptr = qf_ptr->qf_next;
+	    } while ((!qi->qf_lists[qi->qf_curlist].qf_nonevalid
+		      && !qf_ptr->qf_valid)
+		  || (dir == FORWARD_FILE && qf_ptr->qf_fnum == old_qf_fnum));
+	    err = NULL;
+	}
+    }
+    else if (dir == BACKWARD || dir == BACKWARD_FILE)  /* prev. valid entry */
+    {
+	while (errornr--)
+	{
+	    old_qf_ptr = qf_ptr;
+	    prev_index = qf_index;
+	    old_qf_fnum = qf_ptr->qf_fnum;
+	    do
+	    {
+		if (qf_index == 1 || qf_ptr->qf_prev == NULL)
+		{
+		    qf_ptr = old_qf_ptr;
+		    qf_index = prev_index;
+		    if (err != NULL)
+		    {
+			EMSG(_(err));
+			goto theend;
+		    }
+		    errornr = 0;
+		    break;
+		}
+		--qf_index;
+		qf_ptr = qf_ptr->qf_prev;
+	    } while ((!qi->qf_lists[qi->qf_curlist].qf_nonevalid
+		      && !qf_ptr->qf_valid)
+		  || (dir == BACKWARD_FILE && qf_ptr->qf_fnum == old_qf_fnum));
+	    err = NULL;
+	}
+    }
+    else if (errornr != 0)	/* go to specified number */
+    {
+	while (errornr < qf_index && qf_index > 1 && qf_ptr->qf_prev != NULL)
+	{
+	    --qf_index;
+	    qf_ptr = qf_ptr->qf_prev;
+	}
+	while (errornr > qf_index && qf_index <
+				    qi->qf_lists[qi->qf_curlist].qf_count
+						   && qf_ptr->qf_next != NULL)
+	{
+	    ++qf_index;
+	    qf_ptr = qf_ptr->qf_next;
+	}
+    }
+
+#ifdef FEAT_WINDOWS
+    qi->qf_lists[qi->qf_curlist].qf_index = qf_index;
+    if (qf_win_pos_update(qi, old_qf_index))
+	/* No need to print the error message if it's visible in the error
+	 * window */
+	print_message = FALSE;
+
+    /*
+     * For ":helpgrep" find a help window or open one.
+     */
+    if (qf_ptr->qf_type == 1 && (!curwin->w_buffer->b_help || cmdmod.tab != 0))
+    {
+	win_T	*wp;
+	int	n;
+
+	if (cmdmod.tab != 0)
+	    wp = NULL;
+	else
+	    for (wp = firstwin; wp != NULL; wp = wp->w_next)
+		if (wp->w_buffer != NULL && wp->w_buffer->b_help)
+		    break;
+	if (wp != NULL && wp->w_buffer->b_nwindows > 0)
+	    win_enter(wp, TRUE);
+	else
+	{
+	    /*
+	     * Split off help window; put it at far top if no position
+	     * specified, the current window is vertically split and narrow.
+	     */
+	    n = WSP_HELP;
+# ifdef FEAT_VERTSPLIT
+	    if (cmdmod.split == 0 && curwin->w_width != Columns
+						      && curwin->w_width < 80)
+		n |= WSP_TOP;
+# endif
+	    if (win_split(0, n) == FAIL)
+		goto theend;
+	    opened_window = TRUE;	/* close it when fail */
+
+	    if (curwin->w_height < p_hh)
+		win_setheight((int)p_hh);
+
+	    if (qi != &ql_info)	    /* not a quickfix list */
+	    {
+		/* The new window should use the supplied location list */
+		qf_free_all(curwin);
+		curwin->w_llist = qi;
+		qi->qf_refcount++;
+	    }
+	}
+
+	if (!p_im)
+	    restart_edit = 0;	    /* don't want insert mode in help file */
+    }
+
+    /*
+     * If currently in the quickfix window, find another window to show the
+     * file in.
+     */
+    if (bt_quickfix(curbuf) && !opened_window)
+    {
+	/*
+	 * If there is no file specified, we don't know where to go.
+	 * But do advance, otherwise ":cn" gets stuck.
+	 */
+	if (qf_ptr->qf_fnum == 0)
+	    goto theend;
+
+	/* Locate a window showing a normal buffer */
+	usable_win = 0;
+	FOR_ALL_WINDOWS(win)
+	    if (win->w_buffer->b_p_bt[0] == NUL)
+	    {
+		usable_win = 1;
+		break;
+	    }
+
+	/*
+	 * If no usable window is found and 'switchbuf' is set to 'usetab'
+	 * then search in other tabs.
+	 */
+	if (!usable_win && vim_strchr(p_swb, 'a') != NULL)
+	{
+	    tabpage_T	*tp;
+	    win_T	*wp;
+
+	    FOR_ALL_TAB_WINDOWS(tp, wp)
+	    {
+		if (wp->w_buffer->b_fnum == qf_ptr->qf_fnum)
+		{
+		    goto_tabpage_win(tp, wp);
+		    usable_win = 1;
+		    break;
+		}
+	    }
+	}
+
+	/*
+	 * If there is only one window and is the quickfix window, create a new
+	 * one above the quickfix window.
+	 */
+	if (((firstwin == lastwin) && bt_quickfix(curbuf)) || !usable_win)
+	{
+	    ll_ref = curwin->w_llist_ref;
+
+	    if (win_split(0, WSP_ABOVE) == FAIL)
+		goto failed;		/* not enough room for window */
+	    opened_window = TRUE;	/* close it when fail */
+	    p_swb = empty_option;	/* don't split again */
+# ifdef FEAT_SCROLLBIND
+	    curwin->w_p_scb = FALSE;
+# endif
+	    if (ll_ref != NULL)
+	    {
+		/* The new window should use the location list from the
+		 * location list window */
+		qf_free_all(curwin);
+		curwin->w_llist = ll_ref;
+		ll_ref->qf_refcount++;
+	    }
+	}
+	else
+	{
+	    if (curwin->w_llist_ref != NULL)
+	    {
+		/* In a location window */
+		ll_ref = curwin->w_llist_ref;
+
+		/* Find the window with the same location list */
+		FOR_ALL_WINDOWS(win)
+		    if (win->w_llist == ll_ref)
+			break;
+		if (win == NULL)
+		{
+		    /* Find the window showing the selected file */
+		    FOR_ALL_WINDOWS(win)
+			if (win->w_buffer->b_fnum == qf_ptr->qf_fnum)
+			    break;
+		    if (win == NULL)
+		    {
+			/* Find a previous usable window */
+			win = curwin;
+			do
+			{
+			    if (win->w_buffer->b_p_bt[0] == NUL)
+				break;
+			    if (win->w_prev == NULL)
+				win = lastwin;	/* wrap around the top */
+			    else
+				win = win->w_prev; /* go to previous window */
+			} while (win != curwin);
+		    }
+		}
+		win_goto(win);
+
+		/* If the location list for the window is not set, then set it
+		 * to the location list from the location window */
+		if (win->w_llist == NULL)
+		{
+		    win->w_llist = ll_ref;
+		    ll_ref->qf_refcount++;
+		}
+	    }
+	    else
+	    {
+
+	    /*
+	     * Try to find a window that shows the right buffer.
+	     * Default to the window just above the quickfix buffer.
+	     */
+	    win = curwin;
+	    altwin = NULL;
+	    for (;;)
+	    {
+		if (win->w_buffer->b_fnum == qf_ptr->qf_fnum)
+		    break;
+		if (win->w_prev == NULL)
+		    win = lastwin;	/* wrap around the top */
+		else
+		    win = win->w_prev;	/* go to previous window */
+
+		if (IS_QF_WINDOW(win))
+		{
+		    /* Didn't find it, go to the window before the quickfix
+		     * window. */
+		    if (altwin != NULL)
+			win = altwin;
+		    else if (curwin->w_prev != NULL)
+			win = curwin->w_prev;
+		    else
+			win = curwin->w_next;
+		    break;
+		}
+
+		/* Remember a usable window. */
+		if (altwin == NULL && !win->w_p_pvw
+					   && win->w_buffer->b_p_bt[0] == NUL)
+		    altwin = win;
+	    }
+
+	    win_goto(win);
+	    }
+	}
+    }
+#endif
+
+    /*
+     * If there is a file name,
+     * read the wanted file if needed, and check autowrite etc.
+     */
+    old_curbuf = curbuf;
+    old_lnum = curwin->w_cursor.lnum;
+
+    if (qf_ptr->qf_fnum != 0)
+    {
+	if (qf_ptr->qf_type == 1)
+	{
+	    /* Open help file (do_ecmd() will set b_help flag, readfile() will
+	     * set b_p_ro flag). */
+	    if (!can_abandon(curbuf, forceit))
+	    {
+		EMSG(_(e_nowrtmsg));
+		ok = FALSE;
+	    }
+	    else
+		ok = do_ecmd(qf_ptr->qf_fnum, NULL, NULL, NULL, (linenr_T)1,
+						   ECMD_HIDE + ECMD_SET_HELP);
+	}
+	else
+	    ok = buflist_getfile(qf_ptr->qf_fnum,
+			    (linenr_T)1, GETF_SETMARK | GETF_SWITCH, forceit);
+    }
+
+    if (ok == OK)
+    {
+	/* When not switched to another buffer, still need to set pc mark */
+	if (curbuf == old_curbuf)
+	    setpcmark();
+
+	if (qf_ptr->qf_pattern == NULL)
+	{
+	    /*
+	     * Go to line with error, unless qf_lnum is 0.
+	     */
+	    i = qf_ptr->qf_lnum;
+	    if (i > 0)
+	    {
+		if (i > curbuf->b_ml.ml_line_count)
+		    i = curbuf->b_ml.ml_line_count;
+		curwin->w_cursor.lnum = i;
+	    }
+	    if (qf_ptr->qf_col > 0)
+	    {
+		curwin->w_cursor.col = qf_ptr->qf_col - 1;
+		if (qf_ptr->qf_viscol == TRUE)
+		{
+		    /*
+		     * Check each character from the beginning of the error
+		     * line up to the error column.  For each tab character
+		     * found, reduce the error column value by the length of
+		     * a tab character.
+		     */
+		    line = ml_get_curline();
+		    screen_col = 0;
+		    for (char_col = 0; char_col < curwin->w_cursor.col; ++char_col)
+		    {
+			if (*line == NUL)
+			    break;
+			if (*line++ == '\t')
+			{
+			    curwin->w_cursor.col -= 7 - (screen_col % 8);
+			    screen_col += 8 - (screen_col % 8);
+			}
+			else
+			    ++screen_col;
+		    }
+		}
+		check_cursor();
+	    }
+	    else
+		beginline(BL_WHITE | BL_FIX);
+	}
+	else
+	{
+	    pos_T save_cursor;
+
+	    /* Move the cursor to the first line in the buffer */
+	    save_cursor = curwin->w_cursor;
+	    curwin->w_cursor.lnum = 0;
+	    if (!do_search(NULL, '/', qf_ptr->qf_pattern, (long)1, SEARCH_KEEP))
+		curwin->w_cursor = save_cursor;
+	}
+
+#ifdef FEAT_FOLDING
+	if ((fdo_flags & FDO_QUICKFIX) && old_KeyTyped)
+	    foldOpenCursor();
+#endif
+	if (print_message)
+	{
+	    /* Update the screen before showing the message */
+	    update_topline_redraw();
+	    sprintf((char *)IObuff, _("(%d of %d)%s%s: "), qf_index,
+		    qi->qf_lists[qi->qf_curlist].qf_count,
+		    qf_ptr->qf_cleared ? _(" (line deleted)") : "",
+		    (char *)qf_types(qf_ptr->qf_type, qf_ptr->qf_nr));
+	    /* Add the message, skipping leading whitespace and newlines. */
+	    len = (int)STRLEN(IObuff);
+	    qf_fmt_text(skipwhite(qf_ptr->qf_text), IObuff + len, IOSIZE - len);
+
+	    /* Output the message.  Overwrite to avoid scrolling when the 'O'
+	     * flag is present in 'shortmess'; But when not jumping, print the
+	     * whole message. */
+	    i = msg_scroll;
+	    if (curbuf == old_curbuf && curwin->w_cursor.lnum == old_lnum)
+		msg_scroll = TRUE;
+	    else if (!msg_scrolled && shortmess(SHM_OVERALL))
+		msg_scroll = FALSE;
+	    msg_attr_keep(IObuff, 0, TRUE);
+	    msg_scroll = i;
+	}
+    }
+    else
+    {
+#ifdef FEAT_WINDOWS
+	if (opened_window)
+	    win_close(curwin, TRUE);    /* Close opened window */
+#endif
+	if (qf_ptr->qf_fnum != 0)
+	{
+	    /*
+	     * Couldn't open file, so put index back where it was.  This could
+	     * happen if the file was readonly and we changed something.
+	     */
+#ifdef FEAT_WINDOWS
+failed:
+#endif
+	    qf_ptr = old_qf_ptr;
+	    qf_index = old_qf_index;
+	}
+    }
+theend:
+    qi->qf_lists[qi->qf_curlist].qf_ptr = qf_ptr;
+    qi->qf_lists[qi->qf_curlist].qf_index = qf_index;
+#ifdef FEAT_WINDOWS
+    if (p_swb != old_swb && opened_window)
+    {
+	/* Restore old 'switchbuf' value, but not when an autocommand or
+	 * modeline has changed the value. */
+	if (p_swb == empty_option)
+	    p_swb = old_swb;
+	else
+	    free_string_option(old_swb);
+    }
+#endif
+}
+
+/*
+ * ":clist": list all errors
+ * ":llist": list all locations
+ */
+    void
+qf_list(eap)
+    exarg_T	*eap;
+{
+    buf_T	*buf;
+    char_u	*fname;
+    qfline_T	*qfp;
+    int		i;
+    int		idx1 = 1;
+    int		idx2 = -1;
+    int		need_return = TRUE;
+    char_u	*arg = eap->arg;
+    int		all = eap->forceit;	/* if not :cl!, only show
+						   recognised errors */
+    qf_info_T	*qi = &ql_info;
+
+    if (eap->cmdidx == CMD_llist)
+    {
+	qi = GET_LOC_LIST(curwin);
+	if (qi == NULL)
+	{
+	    EMSG(_(e_loclist));
+	    return;
+	}
+    }
+
+    if (qi->qf_curlist >= qi->qf_listcount
+	|| qi->qf_lists[qi->qf_curlist].qf_count == 0)
+    {
+	EMSG(_(e_quickfix));
+	return;
+    }
+    if (!get_list_range(&arg, &idx1, &idx2) || *arg != NUL)
+    {
+	EMSG(_(e_trailing));
+	return;
+    }
+    i = qi->qf_lists[qi->qf_curlist].qf_count;
+    if (idx1 < 0)
+	idx1 = (-idx1 > i) ? 0 : idx1 + i + 1;
+    if (idx2 < 0)
+	idx2 = (-idx2 > i) ? 0 : idx2 + i + 1;
+
+    if (qi->qf_lists[qi->qf_curlist].qf_nonevalid)
+	all = TRUE;
+    qfp = qi->qf_lists[qi->qf_curlist].qf_start;
+    for (i = 1; !got_int && i <= qi->qf_lists[qi->qf_curlist].qf_count; )
+    {
+	if ((qfp->qf_valid || all) && idx1 <= i && i <= idx2)
+	{
+	    if (need_return)
+	    {
+		msg_putchar('\n');
+		if (got_int)
+		    break;
+		need_return = FALSE;
+	    }
+
+	    fname = NULL;
+	    if (qfp->qf_fnum != 0
+			      && (buf = buflist_findnr(qfp->qf_fnum)) != NULL)
+	    {
+		fname = buf->b_fname;
+		if (qfp->qf_type == 1)	/* :helpgrep */
+		    fname = gettail(fname);
+	    }
+	    if (fname == NULL)
+		sprintf((char *)IObuff, "%2d", i);
+	    else
+		vim_snprintf((char *)IObuff, IOSIZE, "%2d %s",
+							    i, (char *)fname);
+	    msg_outtrans_attr(IObuff, i == qi->qf_lists[qi->qf_curlist].qf_index
+					   ? hl_attr(HLF_L) : hl_attr(HLF_D));
+	    if (qfp->qf_lnum == 0)
+		IObuff[0] = NUL;
+	    else if (qfp->qf_col == 0)
+		sprintf((char *)IObuff, ":%ld", qfp->qf_lnum);
+	    else
+		sprintf((char *)IObuff, ":%ld col %d",
+						   qfp->qf_lnum, qfp->qf_col);
+	    sprintf((char *)IObuff + STRLEN(IObuff), "%s:",
+				  (char *)qf_types(qfp->qf_type, qfp->qf_nr));
+	    msg_puts_attr(IObuff, hl_attr(HLF_N));
+	    if (qfp->qf_pattern != NULL)
+	    {
+		qf_fmt_text(qfp->qf_pattern, IObuff, IOSIZE);
+		STRCAT(IObuff, ":");
+		msg_puts(IObuff);
+	    }
+	    msg_puts((char_u *)" ");
+
+	    /* Remove newlines and leading whitespace from the text.  For an
+	     * unrecognized line keep the indent, the compiler may mark a word
+	     * with ^^^^. */
+	    qf_fmt_text((fname != NULL || qfp->qf_lnum != 0)
+				     ? skipwhite(qfp->qf_text) : qfp->qf_text,
+							      IObuff, IOSIZE);
+	    msg_prt_line(IObuff, FALSE);
+	    out_flush();		/* show one line at a time */
+	    need_return = TRUE;
+	}
+
+	qfp = qfp->qf_next;
+	++i;
+	ui_breakcheck();
+    }
+}
+
+/*
+ * Remove newlines and leading whitespace from an error message.
+ * Put the result in "buf[bufsize]".
+ */
+    static void
+qf_fmt_text(text, buf, bufsize)
+    char_u	*text;
+    char_u	*buf;
+    int		bufsize;
+{
+    int		i;
+    char_u	*p = text;
+
+    for (i = 0; *p != NUL && i < bufsize - 1; ++i)
+    {
+	if (*p == '\n')
+	{
+	    buf[i] = ' ';
+	    while (*++p != NUL)
+		if (!vim_iswhite(*p) && *p != '\n')
+		    break;
+	}
+	else
+	    buf[i] = *p++;
+    }
+    buf[i] = NUL;
+}
+
+/*
+ * ":colder [count]": Up in the quickfix stack.
+ * ":cnewer [count]": Down in the quickfix stack.
+ * ":lolder [count]": Up in the location list stack.
+ * ":lnewer [count]": Down in the location list stack.
+ */
+    void
+qf_age(eap)
+    exarg_T	*eap;
+{
+    qf_info_T	*qi = &ql_info;
+    int		count;
+
+    if (eap->cmdidx == CMD_lolder || eap->cmdidx == CMD_lnewer)
+    {
+	qi = GET_LOC_LIST(curwin);
+	if (qi == NULL)
+	{
+	    EMSG(_(e_loclist));
+	    return;
+	}
+    }
+
+    if (eap->addr_count != 0)
+	count = eap->line2;
+    else
+	count = 1;
+    while (count--)
+    {
+	if (eap->cmdidx == CMD_colder || eap->cmdidx == CMD_lolder)
+	{
+	    if (qi->qf_curlist == 0)
+	    {
+		EMSG(_("E380: At bottom of quickfix stack"));
+		return;
+	    }
+	    --qi->qf_curlist;
+	}
+	else
+	{
+	    if (qi->qf_curlist >= qi->qf_listcount - 1)
+	    {
+		EMSG(_("E381: At top of quickfix stack"));
+		return;
+	    }
+	    ++qi->qf_curlist;
+	}
+    }
+    qf_msg(qi);
+
+}
+
+    static void
+qf_msg(qi)
+    qf_info_T	*qi;
+{
+    smsg((char_u *)_("error list %d of %d; %d errors"),
+	    qi->qf_curlist + 1, qi->qf_listcount,
+	    qi->qf_lists[qi->qf_curlist].qf_count);
+#ifdef FEAT_WINDOWS
+    qf_update_buffer(qi);
+#endif
+}
+
+/*
+ * Free error list "idx".
+ */
+    static void
+qf_free(qi, idx)
+    qf_info_T	*qi;
+    int		idx;
+{
+    qfline_T	*qfp;
+
+    while (qi->qf_lists[idx].qf_count)
+    {
+	qfp = qi->qf_lists[idx].qf_start->qf_next;
+	vim_free(qi->qf_lists[idx].qf_start->qf_text);
+	vim_free(qi->qf_lists[idx].qf_start->qf_pattern);
+	vim_free(qi->qf_lists[idx].qf_start);
+	qi->qf_lists[idx].qf_start = qfp;
+	--qi->qf_lists[idx].qf_count;
+    }
+}
+
+/*
+ * qf_mark_adjust: adjust marks
+ */
+   void
+qf_mark_adjust(wp, line1, line2, amount, amount_after)
+    win_T	*wp;
+    linenr_T	line1;
+    linenr_T	line2;
+    long	amount;
+    long	amount_after;
+{
+    int		i;
+    qfline_T	*qfp;
+    int		idx;
+    qf_info_T	*qi = &ql_info;
+
+    if (wp != NULL)
+    {
+	if (wp->w_llist == NULL)
+	    return;
+	qi = wp->w_llist;
+    }
+
+    for (idx = 0; idx < qi->qf_listcount; ++idx)
+	if (qi->qf_lists[idx].qf_count)
+	    for (i = 0, qfp = qi->qf_lists[idx].qf_start;
+		       i < qi->qf_lists[idx].qf_count; ++i, qfp = qfp->qf_next)
+		if (qfp->qf_fnum == curbuf->b_fnum)
+		{
+		    if (qfp->qf_lnum >= line1 && qfp->qf_lnum <= line2)
+		    {
+			if (amount == MAXLNUM)
+			    qfp->qf_cleared = TRUE;
+			else
+			    qfp->qf_lnum += amount;
+		    }
+		    else if (amount_after && qfp->qf_lnum > line2)
+			qfp->qf_lnum += amount_after;
+		}
+}
+
+/*
+ * Make a nice message out of the error character and the error number:
+ *  char    number	message
+ *  e or E    0		" error"
+ *  w or W    0		" warning"
+ *  i or I    0		" info"
+ *  0	      0		""
+ *  other     0		" c"
+ *  e or E    n		" error n"
+ *  w or W    n		" warning n"
+ *  i or I    n		" info n"
+ *  0	      n		" error n"
+ *  other     n		" c n"
+ *  1	      x		""	:helpgrep
+ */
+    static char_u *
+qf_types(c, nr)
+    int c, nr;
+{
+    static char_u	buf[20];
+    static char_u	cc[3];
+    char_u		*p;
+
+    if (c == 'W' || c == 'w')
+	p = (char_u *)" warning";
+    else if (c == 'I' || c == 'i')
+	p = (char_u *)" info";
+    else if (c == 'E' || c == 'e' || (c == 0 && nr > 0))
+	p = (char_u *)" error";
+    else if (c == 0 || c == 1)
+	p = (char_u *)"";
+    else
+    {
+	cc[0] = ' ';
+	cc[1] = c;
+	cc[2] = NUL;
+	p = cc;
+    }
+
+    if (nr <= 0)
+	return p;
+
+    sprintf((char *)buf, "%s %3d", (char *)p, nr);
+    return buf;
+}
+
+#if defined(FEAT_WINDOWS) || defined(PROTO)
+/*
+ * ":cwindow": open the quickfix window if we have errors to display,
+ *	       close it if not.
+ * ":lwindow": open the location list window if we have locations to display,
+ *	       close it if not.
+ */
+    void
+ex_cwindow(eap)
+    exarg_T	*eap;
+{
+    qf_info_T	*qi = &ql_info;
+    win_T	*win;
+
+    if (eap->cmdidx == CMD_lwindow)
+    {
+	qi = GET_LOC_LIST(curwin);
+	if (qi == NULL)
+	    return;
+    }
+
+    /* Look for an existing quickfix window.  */
+    win = qf_find_win(qi);
+
+    /*
+     * If a quickfix window is open but we have no errors to display,
+     * close the window.  If a quickfix window is not open, then open
+     * it if we have errors; otherwise, leave it closed.
+     */
+    if (qi->qf_lists[qi->qf_curlist].qf_nonevalid
+	    || qi->qf_curlist >= qi->qf_listcount)
+    {
+	if (win != NULL)
+	    ex_cclose(eap);
+    }
+    else if (win == NULL)
+	ex_copen(eap);
+}
+
+/*
+ * ":cclose": close the window showing the list of errors.
+ * ":lclose": close the window showing the location list
+ */
+/*ARGSUSED*/
+    void
+ex_cclose(eap)
+    exarg_T	*eap;
+{
+    win_T	*win = NULL;
+    qf_info_T	*qi = &ql_info;
+
+    if (eap->cmdidx == CMD_lclose || eap->cmdidx == CMD_lwindow)
+    {
+	qi = GET_LOC_LIST(curwin);
+	if (qi == NULL)
+	    return;
+    }
+
+    /* Find existing quickfix window and close it. */
+    win = qf_find_win(qi);
+    if (win != NULL)
+	win_close(win, FALSE);
+}
+
+/*
+ * ":copen": open a window that shows the list of errors.
+ * ":lopen": open a window that shows the location list.
+ */
+    void
+ex_copen(eap)
+    exarg_T	*eap;
+{
+    qf_info_T	*qi = &ql_info;
+    int		height;
+    win_T	*win;
+    tabpage_T	*prevtab = curtab;
+    buf_T	*qf_buf;
+
+    if (eap->cmdidx == CMD_lopen || eap->cmdidx == CMD_lwindow)
+    {
+	qi = GET_LOC_LIST(curwin);
+	if (qi == NULL)
+	{
+	    EMSG(_(e_loclist));
+	    return;
+	}
+    }
+
+    if (eap->addr_count != 0)
+	height = eap->line2;
+    else
+	height = QF_WINHEIGHT;
+
+#ifdef FEAT_VISUAL
+    reset_VIsual_and_resel();			/* stop Visual mode */
+#endif
+#ifdef FEAT_GUI
+    need_mouse_correct = TRUE;
+#endif
+
+    /*
+     * Find existing quickfix window, or open a new one.
+     */
+    win = qf_find_win(qi);
+
+    if (win != NULL && cmdmod.tab == 0)
+	win_goto(win);
+    else
+    {
+	qf_buf = qf_find_buf(qi);
+
+	/* The current window becomes the previous window afterwards. */
+	win = curwin;
+
+	if (eap->cmdidx == CMD_copen || eap->cmdidx == CMD_cwindow)
+	    /* Create the new window at the very bottom. */
+	    win_goto(lastwin);
+	if (win_split(height, WSP_BELOW) == FAIL)
+	    return;		/* not enough room for window */
+#ifdef FEAT_SCROLLBIND
+	curwin->w_p_scb = FALSE;
+#endif
+
+	/* Remove the location list for the quickfix window */
+	qf_free_all(curwin);
+
+	if (eap->cmdidx == CMD_lopen || eap->cmdidx == CMD_lwindow)
+	{
+	    /*
+	     * For the location list window, create a reference to the
+	     * location list from the window 'win'.
+	     */
+	    curwin->w_llist_ref = win->w_llist;
+	    win->w_llist->qf_refcount++;
+	}
+
+	if (qf_buf != NULL)
+	    /* Use the existing quickfix buffer */
+	    (void)do_ecmd(qf_buf->b_fnum, NULL, NULL, NULL, ECMD_ONE,
+						     ECMD_HIDE + ECMD_OLDBUF);
+	else
+	{
+	    /* Create a new quickfix buffer */
+	    (void)do_ecmd(0, NULL, NULL, NULL, ECMD_ONE, ECMD_HIDE);
+	    /* switch off 'swapfile' */
+	    set_option_value((char_u *)"swf", 0L, NULL, OPT_LOCAL);
+	    set_option_value((char_u *)"bt", 0L, (char_u *)"quickfix",
+								   OPT_LOCAL);
+	    set_option_value((char_u *)"bh", 0L, (char_u *)"wipe", OPT_LOCAL);
+	    set_option_value((char_u *)"diff", 0L, (char_u *)"", OPT_LOCAL);
+	}
+
+	/* Only set the height when still in the same tab page and there is no
+	 * window to the side. */
+	if (curtab == prevtab
+#ifdef FEAT_VERTSPLIT
+		&& curwin->w_width == Columns
+#endif
+	   )
+	    win_setheight(height);
+	curwin->w_p_wfh = TRUE;	    /* set 'winfixheight' */
+	if (win_valid(win))
+	    prevwin = win;
+    }
+
+    /*
+     * Fill the buffer with the quickfix list.
+     */
+    qf_fill_buffer(qi);
+
+    curwin->w_cursor.lnum = qi->qf_lists[qi->qf_curlist].qf_index;
+    curwin->w_cursor.col = 0;
+    check_cursor();
+    update_topline();		/* scroll to show the line */
+}
+
+/*
+ * Return the number of the current entry (line number in the quickfix
+ * window).
+ */
+     linenr_T
+qf_current_entry(wp)
+    win_T	*wp;
+{
+    qf_info_T	*qi = &ql_info;
+
+    if (IS_LL_WINDOW(wp))
+	/* In the location list window, use the referenced location list */
+	qi = wp->w_llist_ref;
+
+    return qi->qf_lists[qi->qf_curlist].qf_index;
+}
+
+/*
+ * Update the cursor position in the quickfix window to the current error.
+ * Return TRUE if there is a quickfix window.
+ */
+    static int
+qf_win_pos_update(qi, old_qf_index)
+    qf_info_T	*qi;
+    int		old_qf_index;	/* previous qf_index or zero */
+{
+    win_T	*win;
+    int		qf_index = qi->qf_lists[qi->qf_curlist].qf_index;
+
+    /*
+     * Put the cursor on the current error in the quickfix window, so that
+     * it's viewable.
+     */
+    win = qf_find_win(qi);
+    if (win != NULL
+	    && qf_index <= win->w_buffer->b_ml.ml_line_count
+	    && old_qf_index != qf_index)
+    {
+	win_T	*old_curwin = curwin;
+
+	curwin = win;
+	curbuf = win->w_buffer;
+	if (qf_index > old_qf_index)
+	{
+	    curwin->w_redraw_top = old_qf_index;
+	    curwin->w_redraw_bot = qf_index;
+	}
+	else
+	{
+	    curwin->w_redraw_top = qf_index;
+	    curwin->w_redraw_bot = old_qf_index;
+	}
+	curwin->w_cursor.lnum = qf_index;
+	curwin->w_cursor.col = 0;
+	update_topline();		/* scroll to show the line */
+	redraw_later(VALID);
+	curwin->w_redr_status = TRUE;	/* update ruler */
+	curwin = old_curwin;
+	curbuf = curwin->w_buffer;
+    }
+    return win != NULL;
+}
+
+/*
+ * Check whether the given window is displaying the specified quickfix/location
+ * list buffer
+ */
+    static int
+is_qf_win(win, qi)
+    win_T	*win;
+    qf_info_T	*qi;
+{
+    /*
+     * A window displaying the quickfix buffer will have the w_llist_ref field
+     * set to NULL.
+     * A window displaying a location list buffer will have the w_llist_ref
+     * pointing to the location list.
+     */
+    if (bt_quickfix(win->w_buffer))
+	if ((qi == &ql_info && win->w_llist_ref == NULL)
+		|| (qi != &ql_info && win->w_llist_ref == qi))
+	    return TRUE;
+
+    return FALSE;
+}
+
+/*
+ * Find a window displaying the quickfix/location list 'qi'
+ * Searches in only the windows opened in the current tab.
+ */
+    static win_T *
+qf_find_win(qi)
+    qf_info_T	*qi;
+{
+    win_T	*win;
+
+    FOR_ALL_WINDOWS(win)
+	if (is_qf_win(win, qi))
+	    break;
+
+    return win;
+}
+
+/*
+ * Find a quickfix buffer.
+ * Searches in windows opened in all the tabs.
+ */
+    static buf_T *
+qf_find_buf(qi)
+    qf_info_T	*qi;
+{
+    tabpage_T	*tp;
+    win_T	*win;
+
+    FOR_ALL_TAB_WINDOWS(tp, win)
+	if (is_qf_win(win, qi))
+	    return win->w_buffer;
+
+    return NULL;
+}
+
+/*
+ * Find the quickfix buffer.  If it exists, update the contents.
+ */
+    static void
+qf_update_buffer(qi)
+    qf_info_T	*qi;
+{
+    buf_T	*buf;
+    aco_save_T	aco;
+
+    /* Check if a buffer for the quickfix list exists.  Update it. */
+    buf = qf_find_buf(qi);
+    if (buf != NULL)
+    {
+	/* set curwin/curbuf to buf and save a few things */
+	aucmd_prepbuf(&aco, buf);
+
+	qf_fill_buffer(qi);
+
+	/* restore curwin/curbuf and a few other things */
+	aucmd_restbuf(&aco);
+
+	(void)qf_win_pos_update(qi, 0);
+    }
+}
+
+/*
+ * Fill current buffer with quickfix errors, replacing any previous contents.
+ * curbuf must be the quickfix buffer!
+ */
+    static void
+qf_fill_buffer(qi)
+    qf_info_T	*qi;
+{
+    linenr_T	lnum;
+    qfline_T	*qfp;
+    buf_T	*errbuf;
+    int		len;
+    int		old_KeyTyped = KeyTyped;
+
+    /* delete all existing lines */
+    while ((curbuf->b_ml.ml_flags & ML_EMPTY) == 0)
+	(void)ml_delete((linenr_T)1, FALSE);
+
+    /* Check if there is anything to display */
+    if (qi->qf_curlist < qi->qf_listcount)
+    {
+	/* Add one line for each error */
+	qfp = qi->qf_lists[qi->qf_curlist].qf_start;
+	for (lnum = 0; lnum < qi->qf_lists[qi->qf_curlist].qf_count; ++lnum)
+	{
+	    if (qfp->qf_fnum != 0
+		    && (errbuf = buflist_findnr(qfp->qf_fnum)) != NULL
+		    && errbuf->b_fname != NULL)
+	    {
+		if (qfp->qf_type == 1)	/* :helpgrep */
+		    STRCPY(IObuff, gettail(errbuf->b_fname));
+		else
+		    STRCPY(IObuff, errbuf->b_fname);
+		len = (int)STRLEN(IObuff);
+	    }
+	    else
+		len = 0;
+	    IObuff[len++] = '|';
+
+	    if (qfp->qf_lnum > 0)
+	    {
+		sprintf((char *)IObuff + len, "%ld", qfp->qf_lnum);
+		len += (int)STRLEN(IObuff + len);
+
+		if (qfp->qf_col > 0)
+		{
+		    sprintf((char *)IObuff + len, " col %d", qfp->qf_col);
+		    len += (int)STRLEN(IObuff + len);
+		}
+
+		sprintf((char *)IObuff + len, "%s",
+				  (char *)qf_types(qfp->qf_type, qfp->qf_nr));
+		len += (int)STRLEN(IObuff + len);
+	    }
+	    else if (qfp->qf_pattern != NULL)
+	    {
+		qf_fmt_text(qfp->qf_pattern, IObuff + len, IOSIZE - len);
+		len += (int)STRLEN(IObuff + len);
+	    }
+	    IObuff[len++] = '|';
+	    IObuff[len++] = ' ';
+
+	    /* Remove newlines and leading whitespace from the text.
+	     * For an unrecognized line keep the indent, the compiler may
+	     * mark a word with ^^^^. */
+	    qf_fmt_text(len > 3 ? skipwhite(qfp->qf_text) : qfp->qf_text,
+						  IObuff + len, IOSIZE - len);
+
+	    if (ml_append(lnum, IObuff, (colnr_T)STRLEN(IObuff) + 1, FALSE)
+								      == FAIL)
+		break;
+	    qfp = qfp->qf_next;
+	}
+	/* Delete the empty line which is now at the end */
+	(void)ml_delete(lnum + 1, FALSE);
+    }
+
+    /* correct cursor position */
+    check_lnums(TRUE);
+
+    /* Set the 'filetype' to "qf" each time after filling the buffer.  This
+     * resembles reading a file into a buffer, it's more logical when using
+     * autocommands. */
+    set_option_value((char_u *)"ft", 0L, (char_u *)"qf", OPT_LOCAL);
+    curbuf->b_p_ma = FALSE;
+
+#ifdef FEAT_AUTOCMD
+    apply_autocmds(EVENT_BUFREADPOST, (char_u *)"quickfix", NULL,
+							       FALSE, curbuf);
+    apply_autocmds(EVENT_BUFWINENTER, (char_u *)"quickfix", NULL,
+							       FALSE, curbuf);
+#endif
+
+    /* make sure it will be redrawn */
+    redraw_curbuf_later(NOT_VALID);
+
+    /* Restore KeyTyped, setting 'filetype' may reset it. */
+    KeyTyped = old_KeyTyped;
+}
+
+#endif /* FEAT_WINDOWS */
+
+/*
+ * Return TRUE if "buf" is the quickfix buffer.
+ */
+    int
+bt_quickfix(buf)
+    buf_T	*buf;
+{
+    return (buf->b_p_bt[0] == 'q');
+}
+
+/*
+ * Return TRUE if "buf" is a "nofile" or "acwrite" buffer.
+ * This means the buffer name is not a file name.
+ */
+    int
+bt_nofile(buf)
+    buf_T	*buf;
+{
+    return (buf->b_p_bt[0] == 'n' && buf->b_p_bt[2] == 'f')
+	    || buf->b_p_bt[0] == 'a';
+}
+
+/*
+ * Return TRUE if "buf" is a "nowrite" or "nofile" buffer.
+ */
+    int
+bt_dontwrite(buf)
+    buf_T	*buf;
+{
+    return (buf->b_p_bt[0] == 'n');
+}
+
+    int
+bt_dontwrite_msg(buf)
+    buf_T	*buf;
+{
+    if (bt_dontwrite(buf))
+    {
+	EMSG(_("E382: Cannot write, 'buftype' option is set"));
+	return TRUE;
+    }
+    return FALSE;
+}
+
+/*
+ * Return TRUE if the buffer should be hidden, according to 'hidden', ":hide"
+ * and 'bufhidden'.
+ */
+    int
+buf_hide(buf)
+    buf_T	*buf;
+{
+    /* 'bufhidden' overrules 'hidden' and ":hide", check it first */
+    switch (buf->b_p_bh[0])
+    {
+	case 'u':		    /* "unload" */
+	case 'w':		    /* "wipe" */
+	case 'd': return FALSE;	    /* "delete" */
+	case 'h': return TRUE;	    /* "hide" */
+    }
+    return (p_hid || cmdmod.hide);
+}
+
+/*
+ * Return TRUE when using ":vimgrep" for ":grep".
+ */
+    int
+grep_internal(cmdidx)
+    cmdidx_T	cmdidx;
+{
+    return ((cmdidx == CMD_grep
+		|| cmdidx == CMD_lgrep
+		|| cmdidx == CMD_grepadd
+		|| cmdidx == CMD_lgrepadd)
+	    && STRCMP("internal",
+			*curbuf->b_p_gp == NUL ? p_gp : curbuf->b_p_gp) == 0);
+}
+
+/*
+ * Used for ":make", ":lmake", ":grep", ":lgrep", ":grepadd", and ":lgrepadd"
+ */
+    void
+ex_make(eap)
+    exarg_T	*eap;
+{
+    char_u	*fname;
+    char_u	*cmd;
+    unsigned	len;
+    win_T	*wp = NULL;
+    qf_info_T	*qi = &ql_info;
+    int		res;
+#ifdef FEAT_AUTOCMD
+    char_u	*au_name = NULL;
+
+    switch (eap->cmdidx)
+    {
+	case CMD_make:	    au_name = (char_u *)"make"; break;
+	case CMD_lmake:	    au_name = (char_u *)"lmake"; break;
+	case CMD_grep:	    au_name = (char_u *)"grep"; break;
+	case CMD_lgrep:	    au_name = (char_u *)"lgrep"; break;
+	case CMD_grepadd:   au_name = (char_u *)"grepadd"; break;
+	case CMD_lgrepadd:  au_name = (char_u *)"lgrepadd"; break;
+	default: break;
+    }
+    if (au_name != NULL)
+    {
+	apply_autocmds(EVENT_QUICKFIXCMDPRE, au_name,
+					       curbuf->b_fname, TRUE, curbuf);
+# ifdef FEAT_EVAL
+	if (did_throw || force_abort)
+	    return;
+# endif
+    }
+#endif
+
+    /* Redirect ":grep" to ":vimgrep" if 'grepprg' is "internal". */
+    if (grep_internal(eap->cmdidx))
+    {
+	ex_vimgrep(eap);
+	return;
+    }
+
+    if (eap->cmdidx == CMD_lmake || eap->cmdidx == CMD_lgrep
+	|| eap->cmdidx == CMD_lgrepadd)
+	wp = curwin;
+
+    autowrite_all();
+    fname = get_mef_name();
+    if (fname == NULL)
+	return;
+    mch_remove(fname);	    /* in case it's not unique */
+
+    /*
+     * If 'shellpipe' empty: don't redirect to 'errorfile'.
+     */
+    len = (unsigned)STRLEN(p_shq) * 2 + (unsigned)STRLEN(eap->arg) + 1;
+    if (*p_sp != NUL)
+	len += (unsigned)STRLEN(p_sp) + (unsigned)STRLEN(fname) + 3;
+    cmd = alloc(len);
+    if (cmd == NULL)
+	return;
+    sprintf((char *)cmd, "%s%s%s", (char *)p_shq, (char *)eap->arg,
+							       (char *)p_shq);
+    if (*p_sp != NUL)
+	append_redir(cmd, p_sp, fname);
+    /*
+     * Output a newline if there's something else than the :make command that
+     * was typed (in which case the cursor is in column 0).
+     */
+    if (msg_col == 0)
+	msg_didout = FALSE;
+    msg_start();
+    MSG_PUTS(":!");
+    msg_outtrans(cmd);		/* show what we are doing */
+
+    /* let the shell know if we are redirecting output or not */
+    do_shell(cmd, *p_sp != NUL ? SHELL_DOOUT : 0);
+
+#ifdef AMIGA
+    out_flush();
+		/* read window status report and redraw before message */
+    (void)char_avail();
+#endif
+
+    res = qf_init(wp, fname, (eap->cmdidx != CMD_make
+			    && eap->cmdidx != CMD_lmake) ? p_gefm : p_efm,
+					   (eap->cmdidx != CMD_grepadd
+					    && eap->cmdidx != CMD_lgrepadd));
+#ifdef FEAT_AUTOCMD
+    if (au_name != NULL)
+	apply_autocmds(EVENT_QUICKFIXCMDPOST, au_name,
+					       curbuf->b_fname, TRUE, curbuf);
+#endif
+    if (res > 0 && !eap->forceit)
+    {
+	if (wp != NULL)
+	    qi = GET_LOC_LIST(wp);
+	qf_jump(qi, 0, 0, FALSE);		/* display first error */
+    }
+
+    mch_remove(fname);
+    vim_free(fname);
+    vim_free(cmd);
+}
+
+/*
+ * Return the name for the errorfile, in allocated memory.
+ * Find a new unique name when 'makeef' contains "##".
+ * Returns NULL for error.
+ */
+    static char_u *
+get_mef_name()
+{
+    char_u	*p;
+    char_u	*name;
+    static int	start = -1;
+    static int	off = 0;
+#ifdef HAVE_LSTAT
+    struct stat	sb;
+#endif
+
+    if (*p_mef == NUL)
+    {
+	name = vim_tempname('e');
+	if (name == NULL)
+	    EMSG(_(e_notmp));
+	return name;
+    }
+
+    for (p = p_mef; *p; ++p)
+	if (p[0] == '#' && p[1] == '#')
+	    break;
+
+    if (*p == NUL)
+	return vim_strsave(p_mef);
+
+    /* Keep trying until the name doesn't exist yet. */
+    for (;;)
+    {
+	if (start == -1)
+	    start = mch_get_pid();
+	else
+	    off += 19;
+
+	name = alloc((unsigned)STRLEN(p_mef) + 30);
+	if (name == NULL)
+	    break;
+	STRCPY(name, p_mef);
+	sprintf((char *)name + (p - p_mef), "%d%d", start, off);
+	STRCAT(name, p + 2);
+	if (mch_getperm(name) < 0
+#ifdef HAVE_LSTAT
+		    /* Don't accept a symbolic link, its a security risk. */
+		    && mch_lstat((char *)name, &sb) < 0
+#endif
+		)
+	    break;
+	vim_free(name);
+    }
+    return name;
+}
+
+/*
+ * ":cc", ":crewind", ":cfirst" and ":clast".
+ * ":ll", ":lrewind", ":lfirst" and ":llast".
+ */
+    void
+ex_cc(eap)
+    exarg_T	*eap;
+{
+    qf_info_T	*qi = &ql_info;
+
+    if (eap->cmdidx == CMD_ll
+	    || eap->cmdidx == CMD_lrewind
+	    || eap->cmdidx == CMD_lfirst
+	    || eap->cmdidx == CMD_llast)
+    {
+	qi = GET_LOC_LIST(curwin);
+	if (qi == NULL)
+	{
+	    EMSG(_(e_loclist));
+	    return;
+	}
+    }
+
+    qf_jump(qi, 0,
+	    eap->addr_count > 0
+	    ? (int)eap->line2
+	    : (eap->cmdidx == CMD_cc || eap->cmdidx == CMD_ll)
+		? 0
+		: (eap->cmdidx == CMD_crewind || eap->cmdidx == CMD_lrewind
+		   || eap->cmdidx == CMD_cfirst || eap->cmdidx == CMD_lfirst)
+		    ? 1
+		    : 32767,
+	    eap->forceit);
+}
+
+/*
+ * ":cnext", ":cnfile", ":cNext" and ":cprevious".
+ * ":lnext", ":lNext", ":lprevious", ":lnfile", ":lNfile" and ":lpfile".
+ */
+    void
+ex_cnext(eap)
+    exarg_T	*eap;
+{
+    qf_info_T	*qi = &ql_info;
+
+    if (eap->cmdidx == CMD_lnext
+	    || eap->cmdidx == CMD_lNext
+	    || eap->cmdidx == CMD_lprevious
+	    || eap->cmdidx == CMD_lnfile
+	    || eap->cmdidx == CMD_lNfile
+	    || eap->cmdidx == CMD_lpfile)
+    {
+	qi = GET_LOC_LIST(curwin);
+	if (qi == NULL)
+	{
+	    EMSG(_(e_loclist));
+	    return;
+	}
+    }
+
+    qf_jump(qi, (eap->cmdidx == CMD_cnext || eap->cmdidx == CMD_lnext)
+	    ? FORWARD
+	    : (eap->cmdidx == CMD_cnfile || eap->cmdidx == CMD_lnfile)
+		? FORWARD_FILE
+		: (eap->cmdidx == CMD_cpfile || eap->cmdidx == CMD_lpfile
+		   || eap->cmdidx == CMD_cNfile || eap->cmdidx == CMD_lNfile)
+		    ? BACKWARD_FILE
+		    : BACKWARD,
+	    eap->addr_count > 0 ? (int)eap->line2 : 1, eap->forceit);
+}
+
+/*
+ * ":cfile"/":cgetfile"/":caddfile" commands.
+ * ":lfile"/":lgetfile"/":laddfile" commands.
+ */
+    void
+ex_cfile(eap)
+    exarg_T	*eap;
+{
+    win_T	*wp = NULL;
+    qf_info_T	*qi = &ql_info;
+
+    if (eap->cmdidx == CMD_lfile || eap->cmdidx == CMD_lgetfile
+	|| eap->cmdidx == CMD_laddfile)
+	wp = curwin;
+
+    if (*eap->arg != NUL)
+	set_string_option_direct((char_u *)"ef", -1, eap->arg, OPT_FREE, 0);
+
+    /*
+     * This function is used by the :cfile, :cgetfile and :caddfile
+     * commands.
+     * :cfile always creates a new quickfix list and jumps to the
+     * first error.
+     * :cgetfile creates a new quickfix list but doesn't jump to the
+     * first error.
+     * :caddfile adds to an existing quickfix list. If there is no
+     * quickfix list then a new list is created.
+     */
+    if (qf_init(wp, p_ef, p_efm, (eap->cmdidx != CMD_caddfile
+				  && eap->cmdidx != CMD_laddfile)) > 0
+				  && (eap->cmdidx == CMD_cfile
+					     || eap->cmdidx == CMD_lfile))
+    {
+	if (wp != NULL)
+	    qi = GET_LOC_LIST(wp);
+	qf_jump(qi, 0, 0, eap->forceit);	/* display first error */
+    }
+}
+
+/*
+ * ":vimgrep {pattern} file(s)"
+ * ":vimgrepadd {pattern} file(s)"
+ * ":lvimgrep {pattern} file(s)"
+ * ":lvimgrepadd {pattern} file(s)"
+ */
+    void
+ex_vimgrep(eap)
+    exarg_T	*eap;
+{
+    regmmatch_T	regmatch;
+    int		fcount;
+    char_u	**fnames;
+    char_u	*s;
+    char_u	*p;
+    int		fi;
+    qf_info_T	*qi = &ql_info;
+    qfline_T	*prevp = NULL;
+    long	lnum;
+    buf_T	*buf;
+    int		duplicate_name = FALSE;
+    int		using_dummy;
+    int		found_match;
+    buf_T	*first_match_buf = NULL;
+    time_t	seconds = 0;
+    int		save_mls;
+#if defined(FEAT_AUTOCMD) && defined(FEAT_SYN_HL)
+    char_u	*save_ei = NULL;
+#endif
+    aco_save_T	aco;
+#ifdef FEAT_AUTOCMD
+    char_u	*au_name =  NULL;
+    int		flags = 0;
+    colnr_T	col;
+    long	tomatch;
+
+    switch (eap->cmdidx)
+    {
+	case CMD_vimgrep: au_name = (char_u *)"vimgrep"; break;
+	case CMD_lvimgrep: au_name = (char_u *)"lvimgrep"; break;
+	case CMD_vimgrepadd: au_name = (char_u *)"vimgrepadd"; break;
+	case CMD_lvimgrepadd: au_name = (char_u *)"lvimgrepadd"; break;
+	default: break;
+    }
+    if (au_name != NULL)
+    {
+	apply_autocmds(EVENT_QUICKFIXCMDPRE, au_name,
+					       curbuf->b_fname, TRUE, curbuf);
+	if (did_throw || force_abort)
+	    return;
+    }
+#endif
+
+    if (eap->cmdidx == CMD_lgrep
+	    || eap->cmdidx == CMD_lvimgrep
+	    || eap->cmdidx == CMD_lgrepadd
+	    || eap->cmdidx == CMD_lvimgrepadd)
+    {
+	qi = ll_get_or_alloc_list(curwin);
+	if (qi == NULL)
+	    return;
+    }
+
+    if (eap->addr_count > 0)
+	tomatch = eap->line2;
+    else
+	tomatch = MAXLNUM;
+
+    /* Get the search pattern: either white-separated or enclosed in // */
+    regmatch.regprog = NULL;
+    p = skip_vimgrep_pat(eap->arg, &s, &flags);
+    if (p == NULL)
+    {
+	EMSG(_(e_invalpat));
+	goto theend;
+    }
+    regmatch.regprog = vim_regcomp(s, RE_MAGIC);
+    if (regmatch.regprog == NULL)
+	goto theend;
+    regmatch.rmm_ic = p_ic;
+    regmatch.rmm_maxcol = 0;
+
+    p = skipwhite(p);
+    if (*p == NUL)
+    {
+	EMSG(_("E683: File name missing or invalid pattern"));
+	goto theend;
+    }
+
+    if ((eap->cmdidx != CMD_grepadd && eap->cmdidx != CMD_lgrepadd &&
+	 eap->cmdidx != CMD_vimgrepadd && eap->cmdidx != CMD_lvimgrepadd)
+					|| qi->qf_curlist == qi->qf_listcount)
+	/* make place for a new list */
+	qf_new_list(qi);
+    else if (qi->qf_lists[qi->qf_curlist].qf_count > 0)
+	/* Adding to existing list, find last entry. */
+	for (prevp = qi->qf_lists[qi->qf_curlist].qf_start;
+			    prevp->qf_next != prevp; prevp = prevp->qf_next)
+	    ;
+
+    /* parse the list of arguments */
+    if (get_arglist_exp(p, &fcount, &fnames) == FAIL)
+	goto theend;
+    if (fcount == 0)
+    {
+	EMSG(_(e_nomatch));
+	goto theend;
+    }
+
+    seconds = (time_t)0;
+    for (fi = 0; fi < fcount && !got_int && tomatch > 0; ++fi)
+    {
+	if (time(NULL) > seconds)
+	{
+	    /* Display the file name every second or so. */
+	    seconds = time(NULL);
+	    msg_start();
+	    p = msg_strtrunc(fnames[fi], TRUE);
+	    if (p == NULL)
+		msg_outtrans(fnames[fi]);
+	    else
+	    {
+		msg_outtrans(p);
+		vim_free(p);
+	    }
+	    msg_clr_eos();
+	    msg_didout = FALSE;	    /* overwrite this message */
+	    msg_nowait = TRUE;	    /* don't wait for this message */
+	    msg_col = 0;
+	    out_flush();
+	}
+
+	buf = buflist_findname_exp(fnames[fi]);
+	if (buf == NULL || buf->b_ml.ml_mfp == NULL)
+	{
+	    /* Remember that a buffer with this name already exists. */
+	    duplicate_name = (buf != NULL);
+	    using_dummy = TRUE;
+
+#if defined(FEAT_AUTOCMD) && defined(FEAT_SYN_HL)
+	    /* Don't do Filetype autocommands to avoid loading syntax and
+	     * indent scripts, a great speed improvement. */
+	    save_ei = au_event_disable(",Filetype");
+#endif
+	    /* Don't use modelines here, it's useless. */
+	    save_mls = p_mls;
+	    p_mls = 0;
+
+	    /* Load file into a buffer, so that 'fileencoding' is detected,
+	     * autocommands applied, etc. */
+	    buf = load_dummy_buffer(fnames[fi]);
+
+	    p_mls = save_mls;
+#if defined(FEAT_AUTOCMD) && defined(FEAT_SYN_HL)
+	    au_event_restore(save_ei);
+#endif
+	}
+	else
+	    /* Use existing, loaded buffer. */
+	    using_dummy = FALSE;
+
+	if (buf == NULL)
+	{
+	    if (!got_int)
+		smsg((char_u *)_("Cannot open file \"%s\""), fnames[fi]);
+	}
+	else
+	{
+	    /* Try for a match in all lines of the buffer.
+	     * For ":1vimgrep" look for first match only. */
+	    found_match = FALSE;
+	    for (lnum = 1; lnum <= buf->b_ml.ml_line_count && tomatch > 0;
+								       ++lnum)
+	    {
+		col = 0;
+		while (vim_regexec_multi(&regmatch, curwin, buf, lnum,
+								     col) > 0)
+		{
+		    if (qf_add_entry(qi, &prevp,
+				NULL,       /* dir */
+				fnames[fi],
+				0,
+				ml_get_buf(buf,
+				     regmatch.startpos[0].lnum + lnum, FALSE),
+				regmatch.startpos[0].lnum + lnum,
+				regmatch.startpos[0].col + 1,
+				FALSE,      /* vis_col */
+				NULL,	    /* search pattern */
+				0,	    /* nr */
+				0,	    /* type */
+				TRUE	    /* valid */
+				) == FAIL)
+		    {
+			got_int = TRUE;
+			break;
+		    }
+		    found_match = TRUE;
+		    if (--tomatch == 0)
+			break;
+		    if ((flags & VGR_GLOBAL) == 0
+					       || regmatch.endpos[0].lnum > 0)
+			break;
+		    col = regmatch.endpos[0].col
+					    + (col == regmatch.endpos[0].col);
+		    if (col > STRLEN(ml_get_buf(buf, lnum, FALSE)))
+			break;
+		}
+		line_breakcheck();
+		if (got_int)
+		    break;
+	    }
+
+	    if (using_dummy)
+	    {
+		if (found_match && first_match_buf == NULL)
+		    first_match_buf = buf;
+		if (duplicate_name)
+		{
+		    /* Never keep a dummy buffer if there is another buffer
+		     * with the same name. */
+		    wipe_dummy_buffer(buf);
+		    buf = NULL;
+		}
+		else if (!cmdmod.hide
+			    || buf->b_p_bh[0] == 'u'	/* "unload" */
+			    || buf->b_p_bh[0] == 'w'	/* "wipe" */
+			    || buf->b_p_bh[0] == 'd')	/* "delete" */
+		{
+		    /* When no match was found we don't need to remember the
+		     * buffer, wipe it out.  If there was a match and it
+		     * wasn't the first one or we won't jump there: only
+		     * unload the buffer.
+		     * Ignore 'hidden' here, because it may lead to having too
+		     * many swap files. */
+		    if (!found_match)
+		    {
+			wipe_dummy_buffer(buf);
+			buf = NULL;
+		    }
+		    else if (buf != first_match_buf || (flags & VGR_NOJUMP))
+		    {
+			unload_dummy_buffer(buf);
+			buf = NULL;
+		    }
+		}
+
+		if (buf != NULL)
+		{
+		    /* The buffer is still loaded, the Filetype autocommands
+		     * need to be done now, in that buffer.  And the modelines
+		     * need to be done (again).  But not the window-local
+		     * options! */
+		    aucmd_prepbuf(&aco, buf);
+#if defined(FEAT_AUTOCMD) && defined(FEAT_SYN_HL)
+		    apply_autocmds(EVENT_FILETYPE, buf->b_p_ft,
+						     buf->b_fname, TRUE, buf);
+#endif
+		    do_modelines(OPT_NOWIN);
+		    aucmd_restbuf(&aco);
+		}
+	    }
+	}
+    }
+
+    FreeWild(fcount, fnames);
+
+    qi->qf_lists[qi->qf_curlist].qf_nonevalid = FALSE;
+    qi->qf_lists[qi->qf_curlist].qf_ptr = qi->qf_lists[qi->qf_curlist].qf_start;
+    qi->qf_lists[qi->qf_curlist].qf_index = 1;
+
+#ifdef FEAT_WINDOWS
+    qf_update_buffer(qi);
+#endif
+
+#ifdef FEAT_AUTOCMD
+    if (au_name != NULL)
+	apply_autocmds(EVENT_QUICKFIXCMDPOST, au_name,
+					       curbuf->b_fname, TRUE, curbuf);
+#endif
+
+    /* Jump to first match. */
+    if (qi->qf_lists[qi->qf_curlist].qf_count > 0)
+    {
+	if ((flags & VGR_NOJUMP) == 0)
+	    qf_jump(qi, 0, 0, eap->forceit);
+    }
+    else
+	EMSG2(_(e_nomatch2), s);
+
+theend:
+    vim_free(regmatch.regprog);
+}
+
+/*
+ * Skip over the pattern argument of ":vimgrep /pat/[g][j]".
+ * Put the start of the pattern in "*s", unless "s" is NULL.
+ * If "flags" is not NULL put the flags in it: VGR_GLOBAL, VGR_NOJUMP.
+ * If "s" is not NULL terminate the pattern with a NUL.
+ * Return a pointer to the char just past the pattern plus flags.
+ */
+    char_u *
+skip_vimgrep_pat(p, s, flags)
+    char_u  *p;
+    char_u  **s;
+    int	    *flags;
+{
+    int		c;
+
+    if (vim_isIDc(*p))
+    {
+	/* ":vimgrep pattern fname" */
+	if (s != NULL)
+	    *s = p;
+	p = skiptowhite(p);
+	if (s != NULL && *p != NUL)
+	    *p++ = NUL;
+    }
+    else
+    {
+	/* ":vimgrep /pattern/[g][j] fname" */
+	if (s != NULL)
+	    *s = p + 1;
+	c = *p;
+	p = skip_regexp(p + 1, c, TRUE, NULL);
+	if (*p != c)
+	    return NULL;
+
+	/* Truncate the pattern. */
+	if (s != NULL)
+	    *p = NUL;
+	++p;
+
+	/* Find the flags */
+	while (*p == 'g' || *p == 'j')
+	{
+	    if (flags != NULL)
+	    {
+		if (*p == 'g')
+		    *flags |= VGR_GLOBAL;
+		else
+		    *flags |= VGR_NOJUMP;
+	    }
+	    ++p;
+	}
+    }
+    return p;
+}
+
+/*
+ * Load file "fname" into a dummy buffer and return the buffer pointer.
+ * Returns NULL if it fails.
+ * Must call unload_dummy_buffer() or wipe_dummy_buffer() later!
+ */
+    static buf_T *
+load_dummy_buffer(fname)
+    char_u	*fname;
+{
+    buf_T	*newbuf;
+    int		failed = TRUE;
+    aco_save_T	aco;
+
+    /* Allocate a buffer without putting it in the buffer list. */
+    newbuf = buflist_new(NULL, NULL, (linenr_T)1, BLN_DUMMY);
+    if (newbuf == NULL)
+	return NULL;
+
+    /* Init the options. */
+    buf_copy_options(newbuf, BCO_ENTER | BCO_NOHELP);
+
+    /* set curwin/curbuf to buf and save a few things */
+    aucmd_prepbuf(&aco, newbuf);
+
+    /* Need to set the filename for autocommands. */
+    (void)setfname(curbuf, fname, NULL, FALSE);
+
+    if (ml_open(curbuf) == OK)
+    {
+	/* Create swap file now to avoid the ATTENTION message. */
+	check_need_swap(TRUE);
+
+	/* Remove the "dummy" flag, otherwise autocommands may not
+	 * work. */
+	curbuf->b_flags &= ~BF_DUMMY;
+
+	if (readfile(fname, NULL,
+		    (linenr_T)0, (linenr_T)0, (linenr_T)MAXLNUM,
+		    NULL, READ_NEW | READ_DUMMY) == OK
+		&& !got_int
+		&& !(curbuf->b_flags & BF_NEW))
+	{
+	    failed = FALSE;
+	    if (curbuf != newbuf)
+	    {
+		/* Bloody autocommands changed the buffer! */
+		if (buf_valid(newbuf))
+		    wipe_buffer(newbuf, FALSE);
+		newbuf = curbuf;
+	    }
+	}
+    }
+
+    /* restore curwin/curbuf and a few other things */
+    aucmd_restbuf(&aco);
+
+    if (!buf_valid(newbuf))
+	return NULL;
+    if (failed)
+    {
+	wipe_dummy_buffer(newbuf);
+	return NULL;
+    }
+    return newbuf;
+}
+
+/*
+ * Wipe out the dummy buffer that load_dummy_buffer() created.
+ */
+    static void
+wipe_dummy_buffer(buf)
+    buf_T	*buf;
+{
+    if (curbuf != buf)		/* safety check */
+    {
+#if defined(FEAT_AUTOCMD) && defined(FEAT_EVAL)
+	cleanup_T   cs;
+
+	/* Reset the error/interrupt/exception state here so that aborting()
+	 * returns FALSE when wiping out the buffer.  Otherwise it doesn't
+	 * work when got_int is set. */
+	enter_cleanup(&cs);
+#endif
+
+	wipe_buffer(buf, FALSE);
+
+#if defined(FEAT_AUTOCMD) && defined(FEAT_EVAL)
+	/* Restore the error/interrupt/exception state if not discarded by a
+	 * new aborting error, interrupt, or uncaught exception. */
+	leave_cleanup(&cs);
+#endif
+    }
+}
+
+/*
+ * Unload the dummy buffer that load_dummy_buffer() created.
+ */
+    static void
+unload_dummy_buffer(buf)
+    buf_T	*buf;
+{
+    if (curbuf != buf)		/* safety check */
+	close_buffer(NULL, buf, DOBUF_UNLOAD);
+}
+
+#if defined(FEAT_EVAL) || defined(PROTO)
+/*
+ * Add each quickfix error to list "list" as a dictionary.
+ */
+    int
+get_errorlist(wp, list)
+    win_T	*wp;
+    list_T	*list;
+{
+    qf_info_T	*qi = &ql_info;
+    dict_T	*dict;
+    char_u	buf[2];
+    qfline_T	*qfp;
+    int		i;
+    int		bufnum;
+
+    if (wp != NULL)
+    {
+	qi = GET_LOC_LIST(wp);
+	if (qi == NULL)
+	    return FAIL;
+    }
+
+    if (qi->qf_curlist >= qi->qf_listcount
+	    || qi->qf_lists[qi->qf_curlist].qf_count == 0)
+	return FAIL;
+
+    qfp = qi->qf_lists[qi->qf_curlist].qf_start;
+    for (i = 1; !got_int && i <= qi->qf_lists[qi->qf_curlist].qf_count; ++i)
+    {
+	/* Handle entries with a non-existing buffer number. */
+	bufnum = qfp->qf_fnum;
+	if (bufnum != 0 && (buflist_findnr(bufnum) == NULL))
+	    bufnum = 0;
+
+	if ((dict = dict_alloc()) == NULL)
+	    return FAIL;
+	if (list_append_dict(list, dict) == FAIL)
+	    return FAIL;
+
+	buf[0] = qfp->qf_type;
+	buf[1] = NUL;
+	if ( dict_add_nr_str(dict, "bufnr", (long)bufnum, NULL) == FAIL
+	  || dict_add_nr_str(dict, "lnum",  (long)qfp->qf_lnum, NULL) == FAIL
+	  || dict_add_nr_str(dict, "col",   (long)qfp->qf_col, NULL) == FAIL
+	  || dict_add_nr_str(dict, "vcol",  (long)qfp->qf_viscol, NULL) == FAIL
+	  || dict_add_nr_str(dict, "nr",    (long)qfp->qf_nr, NULL) == FAIL
+	  || dict_add_nr_str(dict, "pattern",  0L,
+	     qfp->qf_pattern == NULL ? (char_u *)"" : qfp->qf_pattern) == FAIL
+	  || dict_add_nr_str(dict, "text",  0L,
+		   qfp->qf_text == NULL ? (char_u *)"" : qfp->qf_text) == FAIL
+	  || dict_add_nr_str(dict, "type",  0L, buf) == FAIL
+	  || dict_add_nr_str(dict, "valid", (long)qfp->qf_valid, NULL) == FAIL)
+	    return FAIL;
+
+	qfp = qfp->qf_next;
+    }
+    return OK;
+}
+
+/*
+ * Populate the quickfix list with the items supplied in the list
+ * of dictionaries.
+ */
+    int
+set_errorlist(wp, list, action)
+    win_T	*wp;
+    list_T	*list;
+    int		action;
+{
+    listitem_T	*li;
+    dict_T	*d;
+    char_u	*filename, *pattern, *text, *type;
+    int		bufnum;
+    long	lnum;
+    int		col, nr;
+    int		vcol;
+    qfline_T	*prevp = NULL;
+    int		valid, status;
+    int		retval = OK;
+    qf_info_T	*qi = &ql_info;
+    int		did_bufnr_emsg = FALSE;
+
+    if (wp != NULL)
+    {
+	qi = ll_get_or_alloc_list(wp);
+	if (qi == NULL)
+	    return FAIL;
+    }
+
+    if (action == ' ' || qi->qf_curlist == qi->qf_listcount)
+	/* make place for a new list */
+	qf_new_list(qi);
+    else if (action == 'a' && qi->qf_lists[qi->qf_curlist].qf_count > 0)
+	/* Adding to existing list, find last entry. */
+	for (prevp = qi->qf_lists[qi->qf_curlist].qf_start;
+	     prevp->qf_next != prevp; prevp = prevp->qf_next)
+	    ;
+    else if (action == 'r')
+	qf_free(qi, qi->qf_curlist);
+
+    for (li = list->lv_first; li != NULL; li = li->li_next)
+    {
+	if (li->li_tv.v_type != VAR_DICT)
+	    continue; /* Skip non-dict items */
+
+	d = li->li_tv.vval.v_dict;
+	if (d == NULL)
+	    continue;
+
+	filename = get_dict_string(d, (char_u *)"filename", TRUE);
+	bufnum = get_dict_number(d, (char_u *)"bufnr");
+	lnum = get_dict_number(d, (char_u *)"lnum");
+	col = get_dict_number(d, (char_u *)"col");
+	vcol = get_dict_number(d, (char_u *)"vcol");
+	nr = get_dict_number(d, (char_u *)"nr");
+	type = get_dict_string(d, (char_u *)"type", TRUE);
+	pattern = get_dict_string(d, (char_u *)"pattern", TRUE);
+	text = get_dict_string(d, (char_u *)"text", TRUE);
+	if (text == NULL)
+	    text = vim_strsave((char_u *)"");
+
+	valid = TRUE;
+	if ((filename == NULL && bufnum == 0) || (lnum == 0 && pattern == NULL))
+	    valid = FALSE;
+
+	/* Mark entries with non-existing buffer number as not valid. Give the
+	 * error message only once. */
+	if (bufnum != 0 && (buflist_findnr(bufnum) == NULL))
+	{
+	    if (!did_bufnr_emsg)
+	    {
+		did_bufnr_emsg = TRUE;
+		EMSGN(_("E92: Buffer %ld not found"), bufnum);
+	    }
+	    valid = FALSE;
+	    bufnum = 0;
+	}
+
+	status =  qf_add_entry(qi, &prevp,
+			       NULL,	    /* dir */
+			       filename,
+			       bufnum,
+			       text,
+			       lnum,
+			       col,
+			       vcol,	    /* vis_col */
+			       pattern,	    /* search pattern */
+			       nr,
+			       type == NULL ? NUL : *type,
+			       valid);
+
+	vim_free(filename);
+	vim_free(pattern);
+	vim_free(text);
+	vim_free(type);
+
+	if (status == FAIL)
+	{
+	    retval = FAIL;
+	    break;
+	}
+    }
+
+    qi->qf_lists[qi->qf_curlist].qf_nonevalid = FALSE;
+    qi->qf_lists[qi->qf_curlist].qf_ptr = qi->qf_lists[qi->qf_curlist].qf_start;
+    qi->qf_lists[qi->qf_curlist].qf_index = 1;
+
+#ifdef FEAT_WINDOWS
+    qf_update_buffer(qi);
+#endif
+
+    return retval;
+}
+#endif
+
+/*
+ * ":[range]cbuffer [bufnr]" command.
+ * ":[range]caddbuffer [bufnr]" command.
+ * ":[range]cgetbuffer [bufnr]" command.
+ * ":[range]lbuffer [bufnr]" command.
+ * ":[range]laddbuffer [bufnr]" command.
+ * ":[range]lgetbuffer [bufnr]" command.
+ */
+    void
+ex_cbuffer(eap)
+    exarg_T   *eap;
+{
+    buf_T	*buf = NULL;
+    qf_info_T	*qi = &ql_info;
+
+    if (eap->cmdidx == CMD_lbuffer || eap->cmdidx == CMD_lgetbuffer
+	    || eap->cmdidx == CMD_laddbuffer)
+    {
+	qi = ll_get_or_alloc_list(curwin);
+	if (qi == NULL)
+	    return;
+    }
+
+    if (*eap->arg == NUL)
+	buf = curbuf;
+    else if (*skipwhite(skipdigits(eap->arg)) == NUL)
+	buf = buflist_findnr(atoi((char *)eap->arg));
+    if (buf == NULL)
+	EMSG(_(e_invarg));
+    else if (buf->b_ml.ml_mfp == NULL)
+	EMSG(_("E681: Buffer is not loaded"));
+    else
+    {
+	if (eap->addr_count == 0)
+	{
+	    eap->line1 = 1;
+	    eap->line2 = buf->b_ml.ml_line_count;
+	}
+	if (eap->line1 < 1 || eap->line1 > buf->b_ml.ml_line_count
+		|| eap->line2 < 1 || eap->line2 > buf->b_ml.ml_line_count)
+	    EMSG(_(e_invrange));
+	else
+	{
+	    if (qf_init_ext(qi, NULL, buf, NULL, p_efm,
+			    (eap->cmdidx != CMD_caddbuffer
+			     && eap->cmdidx != CMD_laddbuffer),
+						   eap->line1, eap->line2) > 0
+		    && (eap->cmdidx == CMD_cbuffer
+			|| eap->cmdidx == CMD_lbuffer))
+		qf_jump(qi, 0, 0, eap->forceit);  /* display first error */
+	}
+    }
+}
+
+#if defined(FEAT_EVAL) || defined(PROTO)
+/*
+ * ":cexpr {expr}", ":cgetexpr {expr}", ":caddexpr {expr}" command.
+ * ":lexpr {expr}", ":lgetexpr {expr}", ":laddexpr {expr}" command.
+ */
+    void
+ex_cexpr(eap)
+    exarg_T	*eap;
+{
+    typval_T	*tv;
+    qf_info_T	*qi = &ql_info;
+
+    if (eap->cmdidx == CMD_lexpr || eap->cmdidx == CMD_lgetexpr
+	    || eap->cmdidx == CMD_laddexpr)
+    {
+	qi = ll_get_or_alloc_list(curwin);
+	if (qi == NULL)
+	    return;
+    }
+
+    /* Evaluate the expression.  When the result is a string or a list we can
+     * use it to fill the errorlist. */
+    tv = eval_expr(eap->arg, NULL);
+    if (tv != NULL)
+    {
+	if ((tv->v_type == VAR_STRING && tv->vval.v_string != NULL)
+		|| (tv->v_type == VAR_LIST && tv->vval.v_list != NULL))
+	{
+	    if (qf_init_ext(qi, NULL, NULL, tv, p_efm,
+			    (eap->cmdidx != CMD_caddexpr
+			     && eap->cmdidx != CMD_laddexpr),
+						 (linenr_T)0, (linenr_T)0) > 0
+		    && (eap->cmdidx == CMD_cexpr
+			|| eap->cmdidx == CMD_lexpr))
+		qf_jump(qi, 0, 0, eap->forceit);  /* display first error */
+	}
+	else
+	    EMSG(_("E777: String or List expected"));
+	free_tv(tv);
+    }
+}
+#endif
+
+/*
+ * ":helpgrep {pattern}"
+ */
+    void
+ex_helpgrep(eap)
+    exarg_T	*eap;
+{
+    regmatch_T	regmatch;
+    char_u	*save_cpo;
+    char_u	*p;
+    int		fcount;
+    char_u	**fnames;
+    FILE	*fd;
+    int		fi;
+    qfline_T	*prevp = NULL;
+    long	lnum;
+#ifdef FEAT_MULTI_LANG
+    char_u	*lang;
+#endif
+    qf_info_T	*qi = &ql_info;
+    int		new_qi = FALSE;
+    win_T	*wp;
+
+    /* Make 'cpoptions' empty, the 'l' flag should not be used here. */
+    save_cpo = p_cpo;
+    p_cpo = (char_u *)"";
+
+#ifdef FEAT_MULTI_LANG
+    /* Check for a specified language */
+    lang = check_help_lang(eap->arg);
+#endif
+
+    if (eap->cmdidx == CMD_lhelpgrep)
+    {
+	/* Find an existing help window */
+	FOR_ALL_WINDOWS(wp)
+	    if (wp->w_buffer != NULL && wp->w_buffer->b_help)
+		break;
+
+	if (wp == NULL)	    /* Help window not found */
+	    qi = NULL;
+	else
+	    qi = wp->w_llist;
+
+	if (qi == NULL)
+	{
+	    /* Allocate a new location list for help text matches */
+	    if ((qi = ll_new_list()) == NULL)
+		return;
+	    new_qi = TRUE;
+	}
+    }
+
+    regmatch.regprog = vim_regcomp(eap->arg, RE_MAGIC + RE_STRING);
+    regmatch.rm_ic = FALSE;
+    if (regmatch.regprog != NULL)
+    {
+	/* create a new quickfix list */
+	qf_new_list(qi);
+
+	/* Go through all directories in 'runtimepath' */
+	p = p_rtp;
+	while (*p != NUL && !got_int)
+	{
+	    copy_option_part(&p, NameBuff, MAXPATHL, ",");
+
+	    /* Find all "*.txt" and "*.??x" files in the "doc" directory. */
+	    add_pathsep(NameBuff);
+	    STRCAT(NameBuff, "doc/*.\\(txt\\|??x\\)");
+	    if (gen_expand_wildcards(1, &NameBuff, &fcount,
+					     &fnames, EW_FILE|EW_SILENT) == OK
+		    && fcount > 0)
+	    {
+		for (fi = 0; fi < fcount && !got_int; ++fi)
+		{
+#ifdef FEAT_MULTI_LANG
+		    /* Skip files for a different language. */
+		    if (lang != NULL
+			    && STRNICMP(lang, fnames[fi]
+					    + STRLEN(fnames[fi]) - 3, 2) != 0
+			    && !(STRNICMP(lang, "en", 2) == 0
+				&& STRNICMP("txt", fnames[fi]
+					   + STRLEN(fnames[fi]) - 3, 3) == 0))
+			    continue;
+#endif
+		    fd = mch_fopen((char *)fnames[fi], "r");
+		    if (fd != NULL)
+		    {
+			lnum = 1;
+			while (!vim_fgets(IObuff, IOSIZE, fd) && !got_int)
+			{
+			    if (vim_regexec(&regmatch, IObuff, (colnr_T)0))
+			    {
+				int	l = (int)STRLEN(IObuff);
+
+				/* remove trailing CR, LF, spaces, etc. */
+				while (l > 0 && IObuff[l - 1] <= ' ')
+				     IObuff[--l] = NUL;
+
+				if (qf_add_entry(qi, &prevp,
+					    NULL,	/* dir */
+					    fnames[fi],
+					    0,
+					    IObuff,
+					    lnum,
+					    (int)(regmatch.startp[0] - IObuff)
+								+ 1, /* col */
+					    FALSE,	/* vis_col */
+					    NULL,	/* search pattern */
+					    0,		/* nr */
+					    1,		/* type */
+					    TRUE	/* valid */
+					    ) == FAIL)
+				{
+				    got_int = TRUE;
+				    break;
+				}
+			    }
+			    ++lnum;
+			    line_breakcheck();
+			}
+			fclose(fd);
+		    }
+		}
+		FreeWild(fcount, fnames);
+	    }
+	}
+	vim_free(regmatch.regprog);
+
+	qi->qf_lists[qi->qf_curlist].qf_nonevalid = FALSE;
+	qi->qf_lists[qi->qf_curlist].qf_ptr =
+	    qi->qf_lists[qi->qf_curlist].qf_start;
+	qi->qf_lists[qi->qf_curlist].qf_index = 1;
+    }
+
+    p_cpo = save_cpo;
+
+#ifdef FEAT_WINDOWS
+    qf_update_buffer(qi);
+#endif
+
+    /* Jump to first match. */
+    if (qi->qf_lists[qi->qf_curlist].qf_count > 0)
+	qf_jump(qi, 0, 0, FALSE);
+    else
+	EMSG2(_(e_nomatch2), eap->arg);
+
+    if (eap->cmdidx == CMD_lhelpgrep)
+    {
+	/* If the help window is not opened or if it already points to the
+	 * correct location list, then free the new location list. */
+	if (!curwin->w_buffer->b_help || curwin->w_llist == qi)
+	{
+	    if (new_qi)
+		ll_free_all(&qi);
+	}
+	else if (curwin->w_llist == NULL)
+	    curwin->w_llist = qi;
+    }
+}
+
+#endif /* FEAT_QUICKFIX */
--- /dev/null
+++ b/regexp.c
@@ -1,0 +1,7142 @@
+/* vi:set ts=8 sts=4 sw=4:
+ *
+ * Handling of regular expressions: vim_regcomp(), vim_regexec(), vim_regsub()
+ *
+ * NOTICE:
+ *
+ * This is NOT the original regular expression code as written by Henry
+ * Spencer.  This code has been modified specifically for use with the VIM
+ * editor, and should not be used separately from Vim.  If you want a good
+ * regular expression library, get the original code.  The copyright notice
+ * that follows is from the original.
+ *
+ * END NOTICE
+ *
+ *	Copyright (c) 1986 by University of Toronto.
+ *	Written by Henry Spencer.  Not derived from licensed software.
+ *
+ *	Permission is granted to anyone to use this software for any
+ *	purpose on any computer system, and to redistribute it freely,
+ *	subject to the following restrictions:
+ *
+ *	1. The author is not responsible for the consequences of use of
+ *		this software, no matter how awful, even if they arise
+ *		from defects in it.
+ *
+ *	2. The origin of this software must not be misrepresented, either
+ *		by explicit claim or by omission.
+ *
+ *	3. Altered versions must be plainly marked as such, and must not
+ *		be misrepresented as being the original software.
+ *
+ * Beware that some of this code is subtly aware of the way operator
+ * precedence is structured in regular expressions.  Serious changes in
+ * regular-expression syntax might require a total rethink.
+ *
+ * Changes have been made by Tony Andrews, Olaf 'Rhialto' Seibert, Robert
+ * Webb, Ciaran McCreesh and Bram Moolenaar.
+ * Named character class support added by Walter Briscoe (1998 Jul 01)
+ */
+
+#include "vim.h"
+
+#undef DEBUG
+
+/*
+ * The "internal use only" fields in regexp.h are present to pass info from
+ * compile to execute that permits the execute phase to run lots faster on
+ * simple cases.  They are:
+ *
+ * regstart	char that must begin a match; NUL if none obvious; Can be a
+ *		multi-byte character.
+ * reganch	is the match anchored (at beginning-of-line only)?
+ * regmust	string (pointer into program) that match must include, or NULL
+ * regmlen	length of regmust string
+ * regflags	RF_ values or'ed together
+ *
+ * Regstart and reganch permit very fast decisions on suitable starting points
+ * for a match, cutting down the work a lot.  Regmust permits fast rejection
+ * of lines that cannot possibly match.  The regmust tests are costly enough
+ * that vim_regcomp() supplies a regmust only if the r.e. contains something
+ * potentially expensive (at present, the only such thing detected is * or +
+ * at the start of the r.e., which can involve a lot of backup).  Regmlen is
+ * supplied because the test in vim_regexec() needs it and vim_regcomp() is
+ * computing it anyway.
+ */
+
+/*
+ * Structure for regexp "program".  This is essentially a linear encoding
+ * of a nondeterministic finite-state machine (aka syntax charts or
+ * "railroad normal form" in parsing technology).  Each node is an opcode
+ * plus a "next" pointer, possibly plus an operand.  "Next" pointers of
+ * all nodes except BRANCH and BRACES_COMPLEX implement concatenation; a "next"
+ * pointer with a BRANCH on both ends of it is connecting two alternatives.
+ * (Here we have one of the subtle syntax dependencies:	an individual BRANCH
+ * (as opposed to a collection of them) is never concatenated with anything
+ * because of operator precedence).  The "next" pointer of a BRACES_COMPLEX
+ * node points to the node after the stuff to be repeated.
+ * The operand of some types of node is a literal string; for others, it is a
+ * node leading into a sub-FSM.  In particular, the operand of a BRANCH node
+ * is the first node of the branch.
+ * (NB this is *not* a tree structure: the tail of the branch connects to the
+ * thing following the set of BRANCHes.)
+ *
+ * pattern	is coded like:
+ *
+ *			  +-----------------+
+ *			  |		    V
+ * <aa>\|<bb>	BRANCH <aa> BRANCH <bb> --> END
+ *		     |	    ^	 |	    ^
+ *		     +------+	 +----------+
+ *
+ *
+ *		       +------------------+
+ *		       V		  |
+ * <aa>*	BRANCH BRANCH <aa> --> BACK BRANCH --> NOTHING --> END
+ *		     |	    |		    ^			   ^
+ *		     |	    +---------------+			   |
+ *		     +---------------------------------------------+
+ *
+ *
+ *		       +----------------------+
+ *		       V		      |
+ * <aa>\+	BRANCH <aa> --> BRANCH --> BACK  BRANCH --> NOTHING --> END
+ *		     |		     |		 ^			^
+ *		     |		     +-----------+			|
+ *		     +--------------------------------------------------+
+ *
+ *
+ *					+-------------------------+
+ *					V			  |
+ * <aa>\{}	BRANCH BRACE_LIMITS --> BRACE_COMPLEX <aa> --> BACK  END
+ *		     |				    |		     ^
+ *		     |				    +----------------+
+ *		     +-----------------------------------------------+
+ *
+ *
+ * <aa>\@!<bb>	BRANCH NOMATCH <aa> --> END  <bb> --> END
+ *		     |	     |		      ^       ^
+ *		     |	     +----------------+       |
+ *		     +--------------------------------+
+ *
+ *						      +---------+
+ *						      |		V
+ * \z[abc]	BRANCH BRANCH  a  BRANCH  b  BRANCH  c	BRANCH	NOTHING --> END
+ *		     |	    |	       |	  |	^		    ^
+ *		     |	    |	       |	  +-----+		    |
+ *		     |	    |	       +----------------+		    |
+ *		     |	    +---------------------------+		    |
+ *		     +------------------------------------------------------+
+ *
+ * They all start with a BRANCH for "\|" alternatives, even when there is only
+ * one alternative.
+ */
+
+/*
+ * The opcodes are:
+ */
+
+/* definition	number		   opnd?    meaning */
+#define END		0	/*	End of program or NOMATCH operand. */
+#define BOL		1	/*	Match "" at beginning of line. */
+#define EOL		2	/*	Match "" at end of line. */
+#define BRANCH		3	/* node Match this alternative, or the
+				 *	next... */
+#define BACK		4	/*	Match "", "next" ptr points backward. */
+#define EXACTLY		5	/* str	Match this string. */
+#define NOTHING		6	/*	Match empty string. */
+#define STAR		7	/* node Match this (simple) thing 0 or more
+				 *	times. */
+#define PLUS		8	/* node Match this (simple) thing 1 or more
+				 *	times. */
+#define MATCH		9	/* node match the operand zero-width */
+#define NOMATCH		10	/* node check for no match with operand */
+#define BEHIND		11	/* node look behind for a match with operand */
+#define NOBEHIND	12	/* node look behind for no match with operand */
+#define SUBPAT		13	/* node match the operand here */
+#define BRACE_SIMPLE	14	/* node Match this (simple) thing between m and
+				 *	n times (\{m,n\}). */
+#define BOW		15	/*	Match "" after [^a-zA-Z0-9_] */
+#define EOW		16	/*	Match "" at    [^a-zA-Z0-9_] */
+#define BRACE_LIMITS	17	/* nr nr  define the min & max for BRACE_SIMPLE
+				 *	and BRACE_COMPLEX. */
+#define NEWL		18	/*	Match line-break */
+#define BHPOS		19	/*	End position for BEHIND or NOBEHIND */
+
+
+/* character classes: 20-48 normal, 50-78 include a line-break */
+#define ADD_NL		30
+#define FIRST_NL	ANY + ADD_NL
+#define ANY		20	/*	Match any one character. */
+#define ANYOF		21	/* str	Match any character in this string. */
+#define ANYBUT		22	/* str	Match any character not in this
+				 *	string. */
+#define IDENT		23	/*	Match identifier char */
+#define SIDENT		24	/*	Match identifier char but no digit */
+#define KWORD		25	/*	Match keyword char */
+#define SKWORD		26	/*	Match word char but no digit */
+#define FNAME		27	/*	Match file name char */
+#define SFNAME		28	/*	Match file name char but no digit */
+#define PRINT		29	/*	Match printable char */
+#define SPRINT		30	/*	Match printable char but no digit */
+#define WHITE		31	/*	Match whitespace char */
+#define NWHITE		32	/*	Match non-whitespace char */
+#define DIGIT		33	/*	Match digit char */
+#define NDIGIT		34	/*	Match non-digit char */
+#define HEX		35	/*	Match hex char */
+#define NHEX		36	/*	Match non-hex char */
+#define OCTAL		37	/*	Match octal char */
+#define NOCTAL		38	/*	Match non-octal char */
+#define WORD		39	/*	Match word char */
+#define NWORD		40	/*	Match non-word char */
+#define HEAD		41	/*	Match head char */
+#define NHEAD		42	/*	Match non-head char */
+#define ALPHA		43	/*	Match alpha char */
+#define NALPHA		44	/*	Match non-alpha char */
+#define LOWER		45	/*	Match lowercase char */
+#define NLOWER		46	/*	Match non-lowercase char */
+#define UPPER		47	/*	Match uppercase char */
+#define NUPPER		48	/*	Match non-uppercase char */
+#define LAST_NL		NUPPER + ADD_NL
+#define WITH_NL(op)	((op) >= FIRST_NL && (op) <= LAST_NL)
+
+#define MOPEN		80  /* -89	 Mark this point in input as start of
+				 *	 \( subexpr.  MOPEN + 0 marks start of
+				 *	 match. */
+#define MCLOSE		90  /* -99	 Analogous to MOPEN.  MCLOSE + 0 marks
+				 *	 end of match. */
+#define BACKREF		100 /* -109 node Match same string again \1-\9 */
+
+#ifdef FEAT_SYN_HL
+# define ZOPEN		110 /* -119	 Mark this point in input as start of
+				 *	 \z( subexpr. */
+# define ZCLOSE		120 /* -129	 Analogous to ZOPEN. */
+# define ZREF		130 /* -139 node Match external submatch \z1-\z9 */
+#endif
+
+#define BRACE_COMPLEX	140 /* -149 node Match nodes between m & n times */
+
+#define NOPEN		150	/*	Mark this point in input as start of
+					\%( subexpr. */
+#define NCLOSE		151	/*	Analogous to NOPEN. */
+
+#define MULTIBYTECODE	200	/* mbc	Match one multi-byte character */
+#define RE_BOF		201	/*	Match "" at beginning of file. */
+#define RE_EOF		202	/*	Match "" at end of file. */
+#define CURSOR		203	/*	Match location of cursor. */
+
+#define RE_LNUM		204	/* nr cmp  Match line number */
+#define RE_COL		205	/* nr cmp  Match column number */
+#define RE_VCOL		206	/* nr cmp  Match virtual column number */
+
+#define RE_MARK		207	/* mark cmp  Match mark position */
+#define RE_VISUAL	208	/*	Match Visual area */
+
+/*
+ * Magic characters have a special meaning, they don't match literally.
+ * Magic characters are negative.  This separates them from literal characters
+ * (possibly multi-byte).  Only ASCII characters can be Magic.
+ */
+#define Magic(x)	((int)(x) - 256)
+#define un_Magic(x)	((x) + 256)
+#define is_Magic(x)	((x) < 0)
+
+static int no_Magic __ARGS((int x));
+static int toggle_Magic __ARGS((int x));
+
+    static int
+no_Magic(x)
+    int		x;
+{
+    if (is_Magic(x))
+	return un_Magic(x);
+    return x;
+}
+
+    static int
+toggle_Magic(x)
+    int		x;
+{
+    if (is_Magic(x))
+	return un_Magic(x);
+    return Magic(x);
+}
+
+/*
+ * The first byte of the regexp internal "program" is actually this magic
+ * number; the start node begins in the second byte.  It's used to catch the
+ * most severe mutilation of the program by the caller.
+ */
+
+#define REGMAGIC	0234
+
+/*
+ * Opcode notes:
+ *
+ * BRANCH	The set of branches constituting a single choice are hooked
+ *		together with their "next" pointers, since precedence prevents
+ *		anything being concatenated to any individual branch.  The
+ *		"next" pointer of the last BRANCH in a choice points to the
+ *		thing following the whole choice.  This is also where the
+ *		final "next" pointer of each individual branch points; each
+ *		branch starts with the operand node of a BRANCH node.
+ *
+ * BACK		Normal "next" pointers all implicitly point forward; BACK
+ *		exists to make loop structures possible.
+ *
+ * STAR,PLUS	'=', and complex '*' and '+', are implemented as circular
+ *		BRANCH structures using BACK.  Simple cases (one character
+ *		per match) are implemented with STAR and PLUS for speed
+ *		and to minimize recursive plunges.
+ *
+ * BRACE_LIMITS	This is always followed by a BRACE_SIMPLE or BRACE_COMPLEX
+ *		node, and defines the min and max limits to be used for that
+ *		node.
+ *
+ * MOPEN,MCLOSE	...are numbered at compile time.
+ * ZOPEN,ZCLOSE	...ditto
+ */
+
+/*
+ * A node is one char of opcode followed by two chars of "next" pointer.
+ * "Next" pointers are stored as two 8-bit bytes, high order first.  The
+ * value is a positive offset from the opcode of the node containing it.
+ * An operand, if any, simply follows the node.  (Note that much of the
+ * code generation knows about this implicit relationship.)
+ *
+ * Using two bytes for the "next" pointer is vast overkill for most things,
+ * but allows patterns to get big without disasters.
+ */
+#define OP(p)		((int)*(p))
+#define NEXT(p)		(((*((p) + 1) & 0377) << 8) + (*((p) + 2) & 0377))
+#define OPERAND(p)	((p) + 3)
+/* Obtain an operand that was stored as four bytes, MSB first. */
+#define OPERAND_MIN(p)	(((long)(p)[3] << 24) + ((long)(p)[4] << 16) \
+			+ ((long)(p)[5] << 8) + (long)(p)[6])
+/* Obtain a second operand stored as four bytes. */
+#define OPERAND_MAX(p)	OPERAND_MIN((p) + 4)
+/* Obtain a second single-byte operand stored after a four bytes operand. */
+#define OPERAND_CMP(p)	(p)[7]
+
+/*
+ * Utility definitions.
+ */
+#define UCHARAT(p)	((int)*(char_u *)(p))
+
+/* Used for an error (down from) vim_regcomp(): give the error message, set
+ * rc_did_emsg and return NULL */
+#define EMSG_RET_NULL(m) return (EMSG(m), rc_did_emsg = TRUE, (void *)NULL)
+#define EMSG_M_RET_NULL(m, c) return (EMSG2((m), (c) ? "" : "\\"), rc_did_emsg = TRUE, (void *)NULL)
+#define EMSG_RET_FAIL(m) return (EMSG(m), rc_did_emsg = TRUE, FAIL)
+#define EMSG_ONE_RET_NULL EMSG_M_RET_NULL(_("E369: invalid item in %s%%[]"), reg_magic == MAGIC_ALL)
+
+#define MAX_LIMIT	(32767L << 16L)
+
+static int re_multi_type __ARGS((int));
+static int cstrncmp __ARGS((char_u *s1, char_u *s2, int *n));
+static char_u *cstrchr __ARGS((char_u *, int));
+
+#ifdef DEBUG
+static void	regdump __ARGS((char_u *, regprog_T *));
+static char_u	*regprop __ARGS((char_u *));
+#endif
+
+#define NOT_MULTI	0
+#define MULTI_ONE	1
+#define MULTI_MULT	2
+/*
+ * Return NOT_MULTI if c is not a "multi" operator.
+ * Return MULTI_ONE if c is a single "multi" operator.
+ * Return MULTI_MULT if c is a multi "multi" operator.
+ */
+    static int
+re_multi_type(c)
+    int c;
+{
+    if (c == Magic('@') || c == Magic('=') || c == Magic('?'))
+	return MULTI_ONE;
+    if (c == Magic('*') || c == Magic('+') || c == Magic('{'))
+	return MULTI_MULT;
+    return NOT_MULTI;
+}
+
+/*
+ * Flags to be passed up and down.
+ */
+#define HASWIDTH	0x1	/* Known never to match null string. */
+#define SIMPLE		0x2	/* Simple enough to be STAR/PLUS operand. */
+#define SPSTART		0x4	/* Starts with * or +. */
+#define HASNL		0x8	/* Contains some \n. */
+#define HASLOOKBH	0x10	/* Contains "\@<=" or "\@<!". */
+#define WORST		0	/* Worst case. */
+
+/*
+ * When regcode is set to this value, code is not emitted and size is computed
+ * instead.
+ */
+#define JUST_CALC_SIZE	((char_u *) -1)
+
+static char_u		*reg_prev_sub = NULL;
+
+#if defined(EXITFREE) || defined(PROTO)
+    void
+free_regexp_stuff()
+{
+    vim_free(reg_prev_sub);
+}
+#endif
+
+/*
+ * REGEXP_INRANGE contains all characters which are always special in a []
+ * range after '\'.
+ * REGEXP_ABBR contains all characters which act as abbreviations after '\'.
+ * These are:
+ *  \n	- New line (NL).
+ *  \r	- Carriage Return (CR).
+ *  \t	- Tab (TAB).
+ *  \e	- Escape (ESC).
+ *  \b	- Backspace (Ctrl_H).
+ *  \d  - Character code in decimal, eg \d123
+ *  \o	- Character code in octal, eg \o80
+ *  \x	- Character code in hex, eg \x4a
+ *  \u	- Multibyte character code, eg \u20ac
+ *  \U	- Long multibyte character code, eg \U12345678
+ */
+static char_u REGEXP_INRANGE[] = "]^-n\\";
+static char_u REGEXP_ABBR[] = "nrtebdoxuU";
+
+static int	backslash_trans __ARGS((int c));
+static int	get_char_class __ARGS((char_u **pp));
+static int	get_equi_class __ARGS((char_u **pp));
+static void	reg_equi_class __ARGS((int c));
+static int	get_coll_element __ARGS((char_u **pp));
+static char_u	*skip_anyof __ARGS((char_u *p));
+static void	init_class_tab __ARGS((void));
+
+/*
+ * Translate '\x' to its control character, except "\n", which is Magic.
+ */
+    static int
+backslash_trans(c)
+    int		c;
+{
+    switch (c)
+    {
+	case 'r':   return CAR;
+	case 't':   return TAB;
+	case 'e':   return ESC;
+	case 'b':   return BS;
+    }
+    return c;
+}
+
+/*
+ * Check for a character class name "[:name:]".  "pp" points to the '['.
+ * Returns one of the CLASS_ items. CLASS_NONE means that no item was
+ * recognized.  Otherwise "pp" is advanced to after the item.
+ */
+    static int
+get_char_class(pp)
+    char_u	**pp;
+{
+    static const char *(class_names[]) =
+    {
+	"alnum:]",
+#define CLASS_ALNUM 0
+	"alpha:]",
+#define CLASS_ALPHA 1
+	"blank:]",
+#define CLASS_BLANK 2
+	"cntrl:]",
+#define CLASS_CNTRL 3
+	"digit:]",
+#define CLASS_DIGIT 4
+	"graph:]",
+#define CLASS_GRAPH 5
+	"lower:]",
+#define CLASS_LOWER 6
+	"print:]",
+#define CLASS_PRINT 7
+	"punct:]",
+#define CLASS_PUNCT 8
+	"space:]",
+#define CLASS_SPACE 9
+	"upper:]",
+#define CLASS_UPPER 10
+	"xdigit:]",
+#define CLASS_XDIGIT 11
+	"tab:]",
+#define CLASS_TAB 12
+	"return:]",
+#define CLASS_RETURN 13
+	"backspace:]",
+#define CLASS_BACKSPACE 14
+	"escape:]",
+#define CLASS_ESCAPE 15
+    };
+#define CLASS_NONE 99
+    int i;
+
+    if ((*pp)[1] == ':')
+    {
+	for (i = 0; i < sizeof(class_names) / sizeof(*class_names); ++i)
+	    if (STRNCMP(*pp + 2, class_names[i], STRLEN(class_names[i])) == 0)
+	    {
+		*pp += STRLEN(class_names[i]) + 2;
+		return i;
+	    }
+    }
+    return CLASS_NONE;
+}
+
+/*
+ * Specific version of character class functions.
+ * Using a table to keep this fast.
+ */
+static short	class_tab[256];
+
+#define	    RI_DIGIT	0x01
+#define	    RI_HEX	0x02
+#define	    RI_OCTAL	0x04
+#define	    RI_WORD	0x08
+#define	    RI_HEAD	0x10
+#define	    RI_ALPHA	0x20
+#define	    RI_LOWER	0x40
+#define	    RI_UPPER	0x80
+#define	    RI_WHITE	0x100
+
+    static void
+init_class_tab()
+{
+    int		i;
+    static int	done = FALSE;
+
+    if (done)
+	return;
+
+    for (i = 0; i < 256; ++i)
+    {
+	if (i >= '0' && i <= '7')
+	    class_tab[i] = RI_DIGIT + RI_HEX + RI_OCTAL + RI_WORD;
+	else if (i >= '8' && i <= '9')
+	    class_tab[i] = RI_DIGIT + RI_HEX + RI_WORD;
+	else if (i >= 'a' && i <= 'f')
+	    class_tab[i] = RI_HEX + RI_WORD + RI_HEAD + RI_ALPHA + RI_LOWER;
+#ifdef EBCDIC
+	else if ((i >= 'g' && i <= 'i') || (i >= 'j' && i <= 'r')
+						    || (i >= 's' && i <= 'z'))
+#else
+	else if (i >= 'g' && i <= 'z')
+#endif
+	    class_tab[i] = RI_WORD + RI_HEAD + RI_ALPHA + RI_LOWER;
+	else if (i >= 'A' && i <= 'F')
+	    class_tab[i] = RI_HEX + RI_WORD + RI_HEAD + RI_ALPHA + RI_UPPER;
+#ifdef EBCDIC
+	else if ((i >= 'G' && i <= 'I') || ( i >= 'J' && i <= 'R')
+						    || (i >= 'S' && i <= 'Z'))
+#else
+	else if (i >= 'G' && i <= 'Z')
+#endif
+	    class_tab[i] = RI_WORD + RI_HEAD + RI_ALPHA + RI_UPPER;
+	else if (i == '_')
+	    class_tab[i] = RI_WORD + RI_HEAD;
+	else
+	    class_tab[i] = 0;
+    }
+    class_tab[' '] |= RI_WHITE;
+    class_tab['\t'] |= RI_WHITE;
+    done = TRUE;
+}
+
+#ifdef FEAT_MBYTE
+# define ri_digit(c)	(c < 0x100 && (class_tab[c] & RI_DIGIT))
+# define ri_hex(c)	(c < 0x100 && (class_tab[c] & RI_HEX))
+# define ri_octal(c)	(c < 0x100 && (class_tab[c] & RI_OCTAL))
+# define ri_word(c)	(c < 0x100 && (class_tab[c] & RI_WORD))
+# define ri_head(c)	(c < 0x100 && (class_tab[c] & RI_HEAD))
+# define ri_alpha(c)	(c < 0x100 && (class_tab[c] & RI_ALPHA))
+# define ri_lower(c)	(c < 0x100 && (class_tab[c] & RI_LOWER))
+# define ri_upper(c)	(c < 0x100 && (class_tab[c] & RI_UPPER))
+# define ri_white(c)	(c < 0x100 && (class_tab[c] & RI_WHITE))
+#else
+# define ri_digit(c)	(class_tab[c] & RI_DIGIT)
+# define ri_hex(c)	(class_tab[c] & RI_HEX)
+# define ri_octal(c)	(class_tab[c] & RI_OCTAL)
+# define ri_word(c)	(class_tab[c] & RI_WORD)
+# define ri_head(c)	(class_tab[c] & RI_HEAD)
+# define ri_alpha(c)	(class_tab[c] & RI_ALPHA)
+# define ri_lower(c)	(class_tab[c] & RI_LOWER)
+# define ri_upper(c)	(class_tab[c] & RI_UPPER)
+# define ri_white(c)	(class_tab[c] & RI_WHITE)
+#endif
+
+/* flags for regflags */
+#define RF_ICASE    1	/* ignore case */
+#define RF_NOICASE  2	/* don't ignore case */
+#define RF_HASNL    4	/* can match a NL */
+#define RF_ICOMBINE 8	/* ignore combining characters */
+#define RF_LOOKBH   16	/* uses "\@<=" or "\@<!" */
+
+/*
+ * Global work variables for vim_regcomp().
+ */
+
+static char_u	*regparse;	/* Input-scan pointer. */
+static int	prevchr_len;	/* byte length of previous char */
+static int	num_complex_braces; /* Complex \{...} count */
+static int	regnpar;	/* () count. */
+#ifdef FEAT_SYN_HL
+static int	regnzpar;	/* \z() count. */
+static int	re_has_z;	/* \z item detected */
+#endif
+static char_u	*regcode;	/* Code-emit pointer, or JUST_CALC_SIZE */
+static long	regsize;	/* Code size. */
+static char_u	had_endbrace[NSUBEXP];	/* flags, TRUE if end of () found */
+static unsigned	regflags;	/* RF_ flags for prog */
+static long	brace_min[10];	/* Minimums for complex brace repeats */
+static long	brace_max[10];	/* Maximums for complex brace repeats */
+static int	brace_count[10]; /* Current counts for complex brace repeats */
+#if defined(FEAT_SYN_HL) || defined(PROTO)
+static int	had_eol;	/* TRUE when EOL found by vim_regcomp() */
+#endif
+static int	one_exactly = FALSE;	/* only do one char for EXACTLY */
+
+static int	reg_magic;	/* magicness of the pattern: */
+#define MAGIC_NONE	1	/* "\V" very unmagic */
+#define MAGIC_OFF	2	/* "\M" or 'magic' off */
+#define MAGIC_ON	3	/* "\m" or 'magic' */
+#define MAGIC_ALL	4	/* "\v" very magic */
+
+static int	reg_string;	/* matching with a string instead of a buffer
+				   line */
+static int	reg_strict;	/* "[abc" is illegal */
+
+/*
+ * META contains all characters that may be magic, except '^' and '$'.
+ */
+
+#ifdef EBCDIC
+static char_u META[] = "%&()*+.123456789<=>?@ACDFHIKLMOPSUVWX[_acdfhiklmnopsuvwxz{|~";
+#else
+/* META[] is used often enough to justify turning it into a table. */
+static char_u META_flags[] = {
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+/*		   %  &     (  )  *  +	      .    */
+    0, 0, 0, 0, 0, 1, 1, 0, 1, 1, 1, 1, 0, 0, 1, 0,
+/*     1  2  3	4  5  6  7  8  9	<  =  >  ? */
+    0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1,
+/*  @  A     C	D     F     H  I     K	L  M	 O */
+    1, 1, 0, 1, 1, 0, 1, 0, 1, 1, 0, 1, 1, 1, 0, 1,
+/*  P	     S	   U  V  W  X	  Z  [		 _ */
+    1, 0, 0, 1, 0, 1, 1, 1, 1, 0, 1, 1, 0, 0, 0, 1,
+/*     a     c	d     f     h  i     k	l  m  n  o */
+    0, 1, 0, 1, 1, 0, 1, 0, 1, 1, 0, 1, 1, 1, 1, 1,
+/*  p	     s	   u  v  w  x	  z  {	|     ~    */
+    1, 0, 0, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 0, 1
+};
+#endif
+
+static int	curchr;
+
+/* arguments for reg() */
+#define REG_NOPAREN	0	/* toplevel reg() */
+#define REG_PAREN	1	/* \(\) */
+#define REG_ZPAREN	2	/* \z(\) */
+#define REG_NPAREN	3	/* \%(\) */
+
+/*
+ * Forward declarations for vim_regcomp()'s friends.
+ */
+static void	initchr __ARGS((char_u *));
+static int	getchr __ARGS((void));
+static void	skipchr_keepstart __ARGS((void));
+static int	peekchr __ARGS((void));
+static void	skipchr __ARGS((void));
+static void	ungetchr __ARGS((void));
+static int	gethexchrs __ARGS((int maxinputlen));
+static int	getoctchrs __ARGS((void));
+static int	getdecchrs __ARGS((void));
+static int	coll_get_char __ARGS((void));
+static void	regcomp_start __ARGS((char_u *expr, int flags));
+static char_u	*reg __ARGS((int, int *));
+static char_u	*regbranch __ARGS((int *flagp));
+static char_u	*regconcat __ARGS((int *flagp));
+static char_u	*regpiece __ARGS((int *));
+static char_u	*regatom __ARGS((int *));
+static char_u	*regnode __ARGS((int));
+#ifdef FEAT_MBYTE
+static int	use_multibytecode __ARGS((int c));
+#endif
+static int	prog_magic_wrong __ARGS((void));
+static char_u	*regnext __ARGS((char_u *));
+static void	regc __ARGS((int b));
+#ifdef FEAT_MBYTE
+static void	regmbc __ARGS((int c));
+#else
+# define regmbc(c) regc(c)
+#endif
+static void	reginsert __ARGS((int, char_u *));
+static void	reginsert_limits __ARGS((int, long, long, char_u *));
+static char_u	*re_put_long __ARGS((char_u *pr, long_u val));
+static int	read_limits __ARGS((long *, long *));
+static void	regtail __ARGS((char_u *, char_u *));
+static void	regoptail __ARGS((char_u *, char_u *));
+
+/*
+ * Return TRUE if compiled regular expression "prog" can match a line break.
+ */
+    int
+re_multiline(prog)
+    regprog_T *prog;
+{
+    return (prog->regflags & RF_HASNL);
+}
+
+/*
+ * Return TRUE if compiled regular expression "prog" looks before the start
+ * position (pattern contains "\@<=" or "\@<!").
+ */
+    int
+re_lookbehind(prog)
+    regprog_T *prog;
+{
+    return (prog->regflags & RF_LOOKBH);
+}
+
+/*
+ * Check for an equivalence class name "[=a=]".  "pp" points to the '['.
+ * Returns a character representing the class. Zero means that no item was
+ * recognized.  Otherwise "pp" is advanced to after the item.
+ */
+    static int
+get_equi_class(pp)
+    char_u	**pp;
+{
+    int		c;
+    int		l = 1;
+    char_u	*p = *pp;
+
+    if (p[1] == '=')
+    {
+#ifdef FEAT_MBYTE
+	if (has_mbyte)
+	    l = (*mb_ptr2len)(p + 2);
+#endif
+	if (p[l + 2] == '=' && p[l + 3] == ']')
+	{
+#ifdef FEAT_MBYTE
+	    if (has_mbyte)
+		c = mb_ptr2char(p + 2);
+	    else
+#endif
+		c = p[2];
+	    *pp += l + 4;
+	    return c;
+	}
+    }
+    return 0;
+}
+
+/*
+ * Produce the bytes for equivalence class "c".
+ * Currently only handles latin1, latin9 and utf-8.
+ */
+    static void
+reg_equi_class(c)
+    int	    c;
+{
+#ifdef FEAT_MBYTE
+    if (enc_utf8 || STRCMP(p_enc, "latin1") == 0
+					 || STRCMP(p_enc, "iso-8859-15") == 0)
+#endif
+    {
+	switch (c)
+	{
+	    case 'A': case '\300': case '\301': case '\302':
+	    case '\303': case '\304': case '\305':
+		      regmbc('A'); regmbc('\300'); regmbc('\301');
+		      regmbc('\302'); regmbc('\303'); regmbc('\304');
+		      regmbc('\305');
+		      return;
+	    case 'C': case '\307':
+		      regmbc('C'); regmbc('\307');
+		      return;
+	    case 'E': case '\310': case '\311': case '\312': case '\313':
+		      regmbc('E'); regmbc('\310'); regmbc('\311');
+		      regmbc('\312'); regmbc('\313');
+		      return;
+	    case 'I': case '\314': case '\315': case '\316': case '\317':
+		      regmbc('I'); regmbc('\314'); regmbc('\315');
+		      regmbc('\316'); regmbc('\317');
+		      return;
+	    case 'N': case '\321':
+		      regmbc('N'); regmbc('\321');
+		      return;
+	    case 'O': case '\322': case '\323': case '\324': case '\325':
+	    case '\326':
+		      regmbc('O'); regmbc('\322'); regmbc('\323');
+		      regmbc('\324'); regmbc('\325'); regmbc('\326');
+		      return;
+	    case 'U': case '\331': case '\332': case '\333': case '\334':
+		      regmbc('U'); regmbc('\331'); regmbc('\332');
+		      regmbc('\333'); regmbc('\334');
+		      return;
+	    case 'Y': case '\335':
+		      regmbc('Y'); regmbc('\335');
+		      return;
+	    case 'a': case '\340': case '\341': case '\342':
+	    case '\343': case '\344': case '\345':
+		      regmbc('a'); regmbc('\340'); regmbc('\341');
+		      regmbc('\342'); regmbc('\343'); regmbc('\344');
+		      regmbc('\345');
+		      return;
+	    case 'c': case '\347':
+		      regmbc('c'); regmbc('\347');
+		      return;
+	    case 'e': case '\350': case '\351': case '\352': case '\353':
+		      regmbc('e'); regmbc('\350'); regmbc('\351');
+		      regmbc('\352'); regmbc('\353');
+		      return;
+	    case 'i': case '\354': case '\355': case '\356': case '\357':
+		      regmbc('i'); regmbc('\354'); regmbc('\355');
+		      regmbc('\356'); regmbc('\357');
+		      return;
+	    case 'n': case '\361':
+		      regmbc('n'); regmbc('\361');
+		      return;
+	    case 'o': case '\362': case '\363': case '\364': case '\365':
+	    case '\366':
+		      regmbc('o'); regmbc('\362'); regmbc('\363');
+		      regmbc('\364'); regmbc('\365'); regmbc('\366');
+		      return;
+	    case 'u': case '\371': case '\372': case '\373': case '\374':
+		      regmbc('u'); regmbc('\371'); regmbc('\372');
+		      regmbc('\373'); regmbc('\374');
+		      return;
+	    case 'y': case '\375': case '\377':
+		      regmbc('y'); regmbc('\375'); regmbc('\377');
+		      return;
+	}
+    }
+    regmbc(c);
+}
+
+/*
+ * Check for a collating element "[.a.]".  "pp" points to the '['.
+ * Returns a character. Zero means that no item was recognized.  Otherwise
+ * "pp" is advanced to after the item.
+ * Currently only single characters are recognized!
+ */
+    static int
+get_coll_element(pp)
+    char_u	**pp;
+{
+    int		c;
+    int		l = 1;
+    char_u	*p = *pp;
+
+    if (p[1] == '.')
+    {
+#ifdef FEAT_MBYTE
+	if (has_mbyte)
+	    l = (*mb_ptr2len)(p + 2);
+#endif
+	if (p[l + 2] == '.' && p[l + 3] == ']')
+	{
+#ifdef FEAT_MBYTE
+	    if (has_mbyte)
+		c = mb_ptr2char(p + 2);
+	    else
+#endif
+		c = p[2];
+	    *pp += l + 4;
+	    return c;
+	}
+    }
+    return 0;
+}
+
+
+/*
+ * Skip over a "[]" range.
+ * "p" must point to the character after the '['.
+ * The returned pointer is on the matching ']', or the terminating NUL.
+ */
+    static char_u *
+skip_anyof(p)
+    char_u	*p;
+{
+    int		cpo_lit;	/* 'cpoptions' contains 'l' flag */
+    int		cpo_bsl;	/* 'cpoptions' contains '\' flag */
+#ifdef FEAT_MBYTE
+    int		l;
+#endif
+
+    cpo_lit = vim_strchr(p_cpo, CPO_LITERAL) != NULL;
+    cpo_bsl = vim_strchr(p_cpo, CPO_BACKSL) != NULL;
+
+    if (*p == '^')	/* Complement of range. */
+	++p;
+    if (*p == ']' || *p == '-')
+	++p;
+    while (*p != NUL && *p != ']')
+    {
+#ifdef FEAT_MBYTE
+	if (has_mbyte && (l = (*mb_ptr2len)(p)) > 1)
+	    p += l;
+	else
+#endif
+	    if (*p == '-')
+	    {
+		++p;
+		if (*p != ']' && *p != NUL)
+		    mb_ptr_adv(p);
+	    }
+	else if (*p == '\\'
+		&& !cpo_bsl
+		&& (vim_strchr(REGEXP_INRANGE, p[1]) != NULL
+		    || (!cpo_lit && vim_strchr(REGEXP_ABBR, p[1]) != NULL)))
+	    p += 2;
+	else if (*p == '[')
+	{
+	    if (get_char_class(&p) == CLASS_NONE
+		    && get_equi_class(&p) == 0
+		    && get_coll_element(&p) == 0)
+		++p; /* It was not a class name */
+	}
+	else
+	    ++p;
+    }
+
+    return p;
+}
+
+/*
+ * Skip past regular expression.
+ * Stop at end of "startp" or where "dirc" is found ('/', '?', etc).
+ * Take care of characters with a backslash in front of it.
+ * Skip strings inside [ and ].
+ * When "newp" is not NULL and "dirc" is '?', make an allocated copy of the
+ * expression and change "\?" to "?".  If "*newp" is not NULL the expression
+ * is changed in-place.
+ */
+    char_u *
+skip_regexp(startp, dirc, magic, newp)
+    char_u	*startp;
+    int		dirc;
+    int		magic;
+    char_u	**newp;
+{
+    int		mymagic;
+    char_u	*p = startp;
+
+    if (magic)
+	mymagic = MAGIC_ON;
+    else
+	mymagic = MAGIC_OFF;
+
+    for (; p[0] != NUL; mb_ptr_adv(p))
+    {
+	if (p[0] == dirc)	/* found end of regexp */
+	    break;
+	if ((p[0] == '[' && mymagic >= MAGIC_ON)
+		|| (p[0] == '\\' && p[1] == '[' && mymagic <= MAGIC_OFF))
+	{
+	    p = skip_anyof(p + 1);
+	    if (p[0] == NUL)
+		break;
+	}
+	else if (p[0] == '\\' && p[1] != NUL)
+	{
+	    if (dirc == '?' && newp != NULL && p[1] == '?')
+	    {
+		/* change "\?" to "?", make a copy first. */
+		if (*newp == NULL)
+		{
+		    *newp = vim_strsave(startp);
+		    if (*newp != NULL)
+			p = *newp + (p - startp);
+		}
+		if (*newp != NULL)
+		    mch_memmove(p, p + 1, STRLEN(p));
+		else
+		    ++p;
+	    }
+	    else
+		++p;    /* skip next character */
+	    if (*p == 'v')
+		mymagic = MAGIC_ALL;
+	    else if (*p == 'V')
+		mymagic = MAGIC_NONE;
+	}
+    }
+    return p;
+}
+
+/*
+ * vim_regcomp() - compile a regular expression into internal code
+ * Returns the program in allocated space.  Returns NULL for an error.
+ *
+ * We can't allocate space until we know how big the compiled form will be,
+ * but we can't compile it (and thus know how big it is) until we've got a
+ * place to put the code.  So we cheat:  we compile it twice, once with code
+ * generation turned off and size counting turned on, and once "for real".
+ * This also means that we don't allocate space until we are sure that the
+ * thing really will compile successfully, and we never have to move the
+ * code and thus invalidate pointers into it.  (Note that it has to be in
+ * one piece because vim_free() must be able to free it all.)
+ *
+ * Whether upper/lower case is to be ignored is decided when executing the
+ * program, it does not matter here.
+ *
+ * Beware that the optimization-preparation code in here knows about some
+ * of the structure of the compiled regexp.
+ * "re_flags": RE_MAGIC and/or RE_STRING.
+ */
+    regprog_T *
+vim_regcomp(expr, re_flags)
+    char_u	*expr;
+    int		re_flags;
+{
+    regprog_T	*r;
+    char_u	*scan;
+    char_u	*longest;
+    int		len;
+    int		flags;
+
+    if (expr == NULL)
+	EMSG_RET_NULL(_(e_null));
+
+    init_class_tab();
+
+    /*
+     * First pass: determine size, legality.
+     */
+    regcomp_start(expr, re_flags);
+    regcode = JUST_CALC_SIZE;
+    regc(REGMAGIC);
+    if (reg(REG_NOPAREN, &flags) == NULL)
+	return NULL;
+
+    /* Small enough for pointer-storage convention? */
+#ifdef SMALL_MALLOC		/* 16 bit storage allocation */
+    if (regsize >= 65536L - 256L)
+	EMSG_RET_NULL(_("E339: Pattern too long"));
+#endif
+
+    /* Allocate space. */
+    r = (regprog_T *)lalloc(sizeof(regprog_T) + regsize, TRUE);
+    if (r == NULL)
+	return NULL;
+
+    /*
+     * Second pass: emit code.
+     */
+    regcomp_start(expr, re_flags);
+    regcode = r->program;
+    regc(REGMAGIC);
+    if (reg(REG_NOPAREN, &flags) == NULL)
+    {
+	vim_free(r);
+	return NULL;
+    }
+
+    /* Dig out information for optimizations. */
+    r->regstart = NUL;		/* Worst-case defaults. */
+    r->reganch = 0;
+    r->regmust = NULL;
+    r->regmlen = 0;
+    r->regflags = regflags;
+    if (flags & HASNL)
+	r->regflags |= RF_HASNL;
+    if (flags & HASLOOKBH)
+	r->regflags |= RF_LOOKBH;
+#ifdef FEAT_SYN_HL
+    /* Remember whether this pattern has any \z specials in it. */
+    r->reghasz = re_has_z;
+#endif
+    scan = r->program + 1;	/* First BRANCH. */
+    if (OP(regnext(scan)) == END)   /* Only one top-level choice. */
+    {
+	scan = OPERAND(scan);
+
+	/* Starting-point info. */
+	if (OP(scan) == BOL || OP(scan) == RE_BOF)
+	{
+	    r->reganch++;
+	    scan = regnext(scan);
+	}
+
+	if (OP(scan) == EXACTLY)
+	{
+#ifdef FEAT_MBYTE
+	    if (has_mbyte)
+		r->regstart = (*mb_ptr2char)(OPERAND(scan));
+	    else
+#endif
+		r->regstart = *OPERAND(scan);
+	}
+	else if ((OP(scan) == BOW
+		    || OP(scan) == EOW
+		    || OP(scan) == NOTHING
+		    || OP(scan) == MOPEN + 0 || OP(scan) == NOPEN
+		    || OP(scan) == MCLOSE + 0 || OP(scan) == NCLOSE)
+		 && OP(regnext(scan)) == EXACTLY)
+	{
+#ifdef FEAT_MBYTE
+	    if (has_mbyte)
+		r->regstart = (*mb_ptr2char)(OPERAND(regnext(scan)));
+	    else
+#endif
+		r->regstart = *OPERAND(regnext(scan));
+	}
+
+	/*
+	 * If there's something expensive in the r.e., find the longest
+	 * literal string that must appear and make it the regmust.  Resolve
+	 * ties in favor of later strings, since the regstart check works
+	 * with the beginning of the r.e. and avoiding duplication
+	 * strengthens checking.  Not a strong reason, but sufficient in the
+	 * absence of others.
+	 */
+	/*
+	 * When the r.e. starts with BOW, it is faster to look for a regmust
+	 * first. Used a lot for "#" and "*" commands. (Added by mool).
+	 */
+	if ((flags & SPSTART || OP(scan) == BOW || OP(scan) == EOW)
+							  && !(flags & HASNL))
+	{
+	    longest = NULL;
+	    len = 0;
+	    for (; scan != NULL; scan = regnext(scan))
+		if (OP(scan) == EXACTLY && STRLEN(OPERAND(scan)) >= (size_t)len)
+		{
+		    longest = OPERAND(scan);
+		    len = (int)STRLEN(OPERAND(scan));
+		}
+	    r->regmust = longest;
+	    r->regmlen = len;
+	}
+    }
+#ifdef DEBUG
+    regdump(expr, r);
+#endif
+    return r;
+}
+
+/*
+ * Setup to parse the regexp.  Used once to get the length and once to do it.
+ */
+    static void
+regcomp_start(expr, re_flags)
+    char_u	*expr;
+    int		re_flags;	    /* see vim_regcomp() */
+{
+    initchr(expr);
+    if (re_flags & RE_MAGIC)
+	reg_magic = MAGIC_ON;
+    else
+	reg_magic = MAGIC_OFF;
+    reg_string = (re_flags & RE_STRING);
+    reg_strict = (re_flags & RE_STRICT);
+
+    num_complex_braces = 0;
+    regnpar = 1;
+    vim_memset(had_endbrace, 0, sizeof(had_endbrace));
+#ifdef FEAT_SYN_HL
+    regnzpar = 1;
+    re_has_z = 0;
+#endif
+    regsize = 0L;
+    regflags = 0;
+#if defined(FEAT_SYN_HL) || defined(PROTO)
+    had_eol = FALSE;
+#endif
+}
+
+#if defined(FEAT_SYN_HL) || defined(PROTO)
+/*
+ * Check if during the previous call to vim_regcomp the EOL item "$" has been
+ * found.  This is messy, but it works fine.
+ */
+    int
+vim_regcomp_had_eol()
+{
+    return had_eol;
+}
+#endif
+
+/*
+ * reg - regular expression, i.e. main body or parenthesized thing
+ *
+ * Caller must absorb opening parenthesis.
+ *
+ * Combining parenthesis handling with the base level of regular expression
+ * is a trifle forced, but the need to tie the tails of the branches to what
+ * follows makes it hard to avoid.
+ */
+    static char_u *
+reg(paren, flagp)
+    int		paren;	/* REG_NOPAREN, REG_PAREN, REG_NPAREN or REG_ZPAREN */
+    int		*flagp;
+{
+    char_u	*ret;
+    char_u	*br;
+    char_u	*ender;
+    int		parno = 0;
+    int		flags;
+
+    *flagp = HASWIDTH;		/* Tentatively. */
+
+#ifdef FEAT_SYN_HL
+    if (paren == REG_ZPAREN)
+    {
+	/* Make a ZOPEN node. */
+	if (regnzpar >= NSUBEXP)
+	    EMSG_RET_NULL(_("E50: Too many \\z("));
+	parno = regnzpar;
+	regnzpar++;
+	ret = regnode(ZOPEN + parno);
+    }
+    else
+#endif
+	if (paren == REG_PAREN)
+    {
+	/* Make a MOPEN node. */
+	if (regnpar >= NSUBEXP)
+	    EMSG_M_RET_NULL(_("E51: Too many %s("), reg_magic == MAGIC_ALL);
+	parno = regnpar;
+	++regnpar;
+	ret = regnode(MOPEN + parno);
+    }
+    else if (paren == REG_NPAREN)
+    {
+	/* Make a NOPEN node. */
+	ret = regnode(NOPEN);
+    }
+    else
+	ret = NULL;
+
+    /* Pick up the branches, linking them together. */
+    br = regbranch(&flags);
+    if (br == NULL)
+	return NULL;
+    if (ret != NULL)
+	regtail(ret, br);	/* [MZ]OPEN -> first. */
+    else
+	ret = br;
+    /* If one of the branches can be zero-width, the whole thing can.
+     * If one of the branches has * at start or matches a line-break, the
+     * whole thing can. */
+    if (!(flags & HASWIDTH))
+	*flagp &= ~HASWIDTH;
+    *flagp |= flags & (SPSTART | HASNL | HASLOOKBH);
+    while (peekchr() == Magic('|'))
+    {
+	skipchr();
+	br = regbranch(&flags);
+	if (br == NULL)
+	    return NULL;
+	regtail(ret, br);	/* BRANCH -> BRANCH. */
+	if (!(flags & HASWIDTH))
+	    *flagp &= ~HASWIDTH;
+	*flagp |= flags & (SPSTART | HASNL | HASLOOKBH);
+    }
+
+    /* Make a closing node, and hook it on the end. */
+    ender = regnode(
+#ifdef FEAT_SYN_HL
+	    paren == REG_ZPAREN ? ZCLOSE + parno :
+#endif
+	    paren == REG_PAREN ? MCLOSE + parno :
+	    paren == REG_NPAREN ? NCLOSE : END);
+    regtail(ret, ender);
+
+    /* Hook the tails of the branches to the closing node. */
+    for (br = ret; br != NULL; br = regnext(br))
+	regoptail(br, ender);
+
+    /* Check for proper termination. */
+    if (paren != REG_NOPAREN && getchr() != Magic(')'))
+    {
+#ifdef FEAT_SYN_HL
+	if (paren == REG_ZPAREN)
+	    EMSG_RET_NULL(_("E52: Unmatched \\z("));
+	else
+#endif
+	    if (paren == REG_NPAREN)
+	    EMSG_M_RET_NULL(_("E53: Unmatched %s%%("), reg_magic == MAGIC_ALL);
+	else
+	    EMSG_M_RET_NULL(_("E54: Unmatched %s("), reg_magic == MAGIC_ALL);
+    }
+    else if (paren == REG_NOPAREN && peekchr() != NUL)
+    {
+	if (curchr == Magic(')'))
+	    EMSG_M_RET_NULL(_("E55: Unmatched %s)"), reg_magic == MAGIC_ALL);
+	else
+	    EMSG_RET_NULL(_(e_trailing));	/* "Can't happen". */
+	/* NOTREACHED */
+    }
+    /*
+     * Here we set the flag allowing back references to this set of
+     * parentheses.
+     */
+    if (paren == REG_PAREN)
+	had_endbrace[parno] = TRUE;	/* have seen the close paren */
+    return ret;
+}
+
+/*
+ * regbranch - one alternative of an | operator
+ *
+ * Implements the & operator.
+ */
+    static char_u *
+regbranch(flagp)
+    int		*flagp;
+{
+    char_u	*ret;
+    char_u	*chain = NULL;
+    char_u	*latest;
+    int		flags;
+
+    *flagp = WORST | HASNL;		/* Tentatively. */
+
+    ret = regnode(BRANCH);
+    for (;;)
+    {
+	latest = regconcat(&flags);
+	if (latest == NULL)
+	    return NULL;
+	/* If one of the branches has width, the whole thing has.  If one of
+	 * the branches anchors at start-of-line, the whole thing does.
+	 * If one of the branches uses look-behind, the whole thing does. */
+	*flagp |= flags & (HASWIDTH | SPSTART | HASLOOKBH);
+	/* If one of the branches doesn't match a line-break, the whole thing
+	 * doesn't. */
+	*flagp &= ~HASNL | (flags & HASNL);
+	if (chain != NULL)
+	    regtail(chain, latest);
+	if (peekchr() != Magic('&'))
+	    break;
+	skipchr();
+	regtail(latest, regnode(END)); /* operand ends */
+	reginsert(MATCH, latest);
+	chain = latest;
+    }
+
+    return ret;
+}
+
+/*
+ * regbranch - one alternative of an | or & operator
+ *
+ * Implements the concatenation operator.
+ */
+    static char_u *
+regconcat(flagp)
+    int		*flagp;
+{
+    char_u	*first = NULL;
+    char_u	*chain = NULL;
+    char_u	*latest;
+    int		flags;
+    int		cont = TRUE;
+
+    *flagp = WORST;		/* Tentatively. */
+
+    while (cont)
+    {
+	switch (peekchr())
+	{
+	    case NUL:
+	    case Magic('|'):
+	    case Magic('&'):
+	    case Magic(')'):
+			    cont = FALSE;
+			    break;
+	    case Magic('Z'):
+#ifdef FEAT_MBYTE
+			    regflags |= RF_ICOMBINE;
+#endif
+			    skipchr_keepstart();
+			    break;
+	    case Magic('c'):
+			    regflags |= RF_ICASE;
+			    skipchr_keepstart();
+			    break;
+	    case Magic('C'):
+			    regflags |= RF_NOICASE;
+			    skipchr_keepstart();
+			    break;
+	    case Magic('v'):
+			    reg_magic = MAGIC_ALL;
+			    skipchr_keepstart();
+			    curchr = -1;
+			    break;
+	    case Magic('m'):
+			    reg_magic = MAGIC_ON;
+			    skipchr_keepstart();
+			    curchr = -1;
+			    break;
+	    case Magic('M'):
+			    reg_magic = MAGIC_OFF;
+			    skipchr_keepstart();
+			    curchr = -1;
+			    break;
+	    case Magic('V'):
+			    reg_magic = MAGIC_NONE;
+			    skipchr_keepstart();
+			    curchr = -1;
+			    break;
+	    default:
+			    latest = regpiece(&flags);
+			    if (latest == NULL)
+				return NULL;
+			    *flagp |= flags & (HASWIDTH | HASNL | HASLOOKBH);
+			    if (chain == NULL)	/* First piece. */
+				*flagp |= flags & SPSTART;
+			    else
+				regtail(chain, latest);
+			    chain = latest;
+			    if (first == NULL)
+				first = latest;
+			    break;
+	}
+    }
+    if (first == NULL)		/* Loop ran zero times. */
+	first = regnode(NOTHING);
+    return first;
+}
+
+/*
+ * regpiece - something followed by possible [*+=]
+ *
+ * Note that the branching code sequences used for = and the general cases
+ * of * and + are somewhat optimized:  they use the same NOTHING node as
+ * both the endmarker for their branch list and the body of the last branch.
+ * It might seem that this node could be dispensed with entirely, but the
+ * endmarker role is not redundant.
+ */
+    static char_u *
+regpiece(flagp)
+    int		    *flagp;
+{
+    char_u	    *ret;
+    int		    op;
+    char_u	    *next;
+    int		    flags;
+    long	    minval;
+    long	    maxval;
+
+    ret = regatom(&flags);
+    if (ret == NULL)
+	return NULL;
+
+    op = peekchr();
+    if (re_multi_type(op) == NOT_MULTI)
+    {
+	*flagp = flags;
+	return ret;
+    }
+    /* default flags */
+    *flagp = (WORST | SPSTART | (flags & (HASNL | HASLOOKBH)));
+
+    skipchr();
+    switch (op)
+    {
+	case Magic('*'):
+	    if (flags & SIMPLE)
+		reginsert(STAR, ret);
+	    else
+	    {
+		/* Emit x* as (x&|), where & means "self". */
+		reginsert(BRANCH, ret); /* Either x */
+		regoptail(ret, regnode(BACK));	/* and loop */
+		regoptail(ret, ret);	/* back */
+		regtail(ret, regnode(BRANCH));	/* or */
+		regtail(ret, regnode(NOTHING)); /* null. */
+	    }
+	    break;
+
+	case Magic('+'):
+	    if (flags & SIMPLE)
+		reginsert(PLUS, ret);
+	    else
+	    {
+		/* Emit x+ as x(&|), where & means "self". */
+		next = regnode(BRANCH); /* Either */
+		regtail(ret, next);
+		regtail(regnode(BACK), ret);	/* loop back */
+		regtail(next, regnode(BRANCH)); /* or */
+		regtail(ret, regnode(NOTHING)); /* null. */
+	    }
+	    *flagp = (WORST | HASWIDTH | (flags & (HASNL | HASLOOKBH)));
+	    break;
+
+	case Magic('@'):
+	    {
+		int	lop = END;
+
+		switch (no_Magic(getchr()))
+		{
+		    case '=': lop = MATCH; break;		  /* \@= */
+		    case '!': lop = NOMATCH; break;		  /* \@! */
+		    case '>': lop = SUBPAT; break;		  /* \@> */
+		    case '<': switch (no_Magic(getchr()))
+			      {
+				  case '=': lop = BEHIND; break;   /* \@<= */
+				  case '!': lop = NOBEHIND; break; /* \@<! */
+			      }
+		}
+		if (lop == END)
+		    EMSG_M_RET_NULL(_("E59: invalid character after %s@"),
+						      reg_magic == MAGIC_ALL);
+		/* Look behind must match with behind_pos. */
+		if (lop == BEHIND || lop == NOBEHIND)
+		{
+		    regtail(ret, regnode(BHPOS));
+		    *flagp |= HASLOOKBH;
+		}
+		regtail(ret, regnode(END)); /* operand ends */
+		reginsert(lop, ret);
+		break;
+	    }
+
+	case Magic('?'):
+	case Magic('='):
+	    /* Emit x= as (x|) */
+	    reginsert(BRANCH, ret);		/* Either x */
+	    regtail(ret, regnode(BRANCH));	/* or */
+	    next = regnode(NOTHING);		/* null. */
+	    regtail(ret, next);
+	    regoptail(ret, next);
+	    break;
+
+	case Magic('{'):
+	    if (!read_limits(&minval, &maxval))
+		return NULL;
+	    if (flags & SIMPLE)
+	    {
+		reginsert(BRACE_SIMPLE, ret);
+		reginsert_limits(BRACE_LIMITS, minval, maxval, ret);
+	    }
+	    else
+	    {
+		if (num_complex_braces >= 10)
+		    EMSG_M_RET_NULL(_("E60: Too many complex %s{...}s"),
+						      reg_magic == MAGIC_ALL);
+		reginsert(BRACE_COMPLEX + num_complex_braces, ret);
+		regoptail(ret, regnode(BACK));
+		regoptail(ret, ret);
+		reginsert_limits(BRACE_LIMITS, minval, maxval, ret);
+		++num_complex_braces;
+	    }
+	    if (minval > 0 && maxval > 0)
+		*flagp = (HASWIDTH | (flags & (HASNL | HASLOOKBH)));
+	    break;
+    }
+    if (re_multi_type(peekchr()) != NOT_MULTI)
+    {
+	/* Can't have a multi follow a multi. */
+	if (peekchr() == Magic('*'))
+	    sprintf((char *)IObuff, _("E61: Nested %s*"),
+					    reg_magic >= MAGIC_ON ? "" : "\\");
+	else
+	    sprintf((char *)IObuff, _("E62: Nested %s%c"),
+		reg_magic == MAGIC_ALL ? "" : "\\", no_Magic(peekchr()));
+	EMSG_RET_NULL(IObuff);
+    }
+
+    return ret;
+}
+
+/*
+ * regatom - the lowest level
+ *
+ * Optimization:  gobbles an entire sequence of ordinary characters so that
+ * it can turn them into a single node, which is smaller to store and
+ * faster to run.  Don't do this when one_exactly is set.
+ */
+    static char_u *
+regatom(flagp)
+    int		   *flagp;
+{
+    char_u	    *ret;
+    int		    flags;
+    int		    cpo_lit;	    /* 'cpoptions' contains 'l' flag */
+    int		    cpo_bsl;	    /* 'cpoptions' contains '\' flag */
+    int		    c;
+    static char_u   *classchars = (char_u *)".iIkKfFpPsSdDxXoOwWhHaAlLuU";
+    static int	    classcodes[] = {ANY, IDENT, SIDENT, KWORD, SKWORD,
+				    FNAME, SFNAME, PRINT, SPRINT,
+				    WHITE, NWHITE, DIGIT, NDIGIT,
+				    HEX, NHEX, OCTAL, NOCTAL,
+				    WORD, NWORD, HEAD, NHEAD,
+				    ALPHA, NALPHA, LOWER, NLOWER,
+				    UPPER, NUPPER
+				    };
+    char_u	    *p;
+    int		    extra = 0;
+
+    *flagp = WORST;		/* Tentatively. */
+    cpo_lit = vim_strchr(p_cpo, CPO_LITERAL) != NULL;
+    cpo_bsl = vim_strchr(p_cpo, CPO_BACKSL) != NULL;
+
+    c = getchr();
+    switch (c)
+    {
+      case Magic('^'):
+	ret = regnode(BOL);
+	break;
+
+      case Magic('$'):
+	ret = regnode(EOL);
+#if defined(FEAT_SYN_HL) || defined(PROTO)
+	had_eol = TRUE;
+#endif
+	break;
+
+      case Magic('<'):
+	ret = regnode(BOW);
+	break;
+
+      case Magic('>'):
+	ret = regnode(EOW);
+	break;
+
+      case Magic('_'):
+	c = no_Magic(getchr());
+	if (c == '^')		/* "\_^" is start-of-line */
+	{
+	    ret = regnode(BOL);
+	    break;
+	}
+	if (c == '$')		/* "\_$" is end-of-line */
+	{
+	    ret = regnode(EOL);
+#if defined(FEAT_SYN_HL) || defined(PROTO)
+	    had_eol = TRUE;
+#endif
+	    break;
+	}
+
+	extra = ADD_NL;
+	*flagp |= HASNL;
+
+	/* "\_[" is character range plus newline */
+	if (c == '[')
+	    goto collection;
+
+	/* "\_x" is character class plus newline */
+	/*FALLTHROUGH*/
+
+	/*
+	 * Character classes.
+	 */
+      case Magic('.'):
+      case Magic('i'):
+      case Magic('I'):
+      case Magic('k'):
+      case Magic('K'):
+      case Magic('f'):
+      case Magic('F'):
+      case Magic('p'):
+      case Magic('P'):
+      case Magic('s'):
+      case Magic('S'):
+      case Magic('d'):
+      case Magic('D'):
+      case Magic('x'):
+      case Magic('X'):
+      case Magic('o'):
+      case Magic('O'):
+      case Magic('w'):
+      case Magic('W'):
+      case Magic('h'):
+      case Magic('H'):
+      case Magic('a'):
+      case Magic('A'):
+      case Magic('l'):
+      case Magic('L'):
+      case Magic('u'):
+      case Magic('U'):
+	p = vim_strchr(classchars, no_Magic(c));
+	if (p == NULL)
+	    EMSG_RET_NULL(_("E63: invalid use of \\_"));
+#ifdef FEAT_MBYTE
+	/* When '.' is followed by a composing char ignore the dot, so that
+	 * the composing char is matched here. */
+	if (enc_utf8 && c == Magic('.') && utf_iscomposing(peekchr()))
+	{
+	    c = getchr();
+	    goto do_multibyte;
+	}
+#endif
+	ret = regnode(classcodes[p - classchars] + extra);
+	*flagp |= HASWIDTH | SIMPLE;
+	break;
+
+      case Magic('n'):
+	if (reg_string)
+	{
+	    /* In a string "\n" matches a newline character. */
+	    ret = regnode(EXACTLY);
+	    regc(NL);
+	    regc(NUL);
+	    *flagp |= HASWIDTH | SIMPLE;
+	}
+	else
+	{
+	    /* In buffer text "\n" matches the end of a line. */
+	    ret = regnode(NEWL);
+	    *flagp |= HASWIDTH | HASNL;
+	}
+	break;
+
+      case Magic('('):
+	if (one_exactly)
+	    EMSG_ONE_RET_NULL;
+	ret = reg(REG_PAREN, &flags);
+	if (ret == NULL)
+	    return NULL;
+	*flagp |= flags & (HASWIDTH | SPSTART | HASNL | HASLOOKBH);
+	break;
+
+      case NUL:
+      case Magic('|'):
+      case Magic('&'):
+      case Magic(')'):
+	EMSG_RET_NULL(_(e_internal));	/* Supposed to be caught earlier. */
+	/* NOTREACHED */
+
+      case Magic('='):
+      case Magic('?'):
+      case Magic('+'):
+      case Magic('@'):
+      case Magic('{'):
+      case Magic('*'):
+	c = no_Magic(c);
+	sprintf((char *)IObuff, _("E64: %s%c follows nothing"),
+		(c == '*' ? reg_magic >= MAGIC_ON : reg_magic == MAGIC_ALL)
+		? "" : "\\", c);
+	EMSG_RET_NULL(IObuff);
+	/* NOTREACHED */
+
+      case Magic('~'):		/* previous substitute pattern */
+	    if (reg_prev_sub != NULL)
+	    {
+		char_u	    *lp;
+
+		ret = regnode(EXACTLY);
+		lp = reg_prev_sub;
+		while (*lp != NUL)
+		    regc(*lp++);
+		regc(NUL);
+		if (*reg_prev_sub != NUL)
+		{
+		    *flagp |= HASWIDTH;
+		    if ((lp - reg_prev_sub) == 1)
+			*flagp |= SIMPLE;
+		}
+	    }
+	    else
+		EMSG_RET_NULL(_(e_nopresub));
+	    break;
+
+      case Magic('1'):
+      case Magic('2'):
+      case Magic('3'):
+      case Magic('4'):
+      case Magic('5'):
+      case Magic('6'):
+      case Magic('7'):
+      case Magic('8'):
+      case Magic('9'):
+	    {
+		int		    refnum;
+
+		refnum = c - Magic('0');
+		/*
+		 * Check if the back reference is legal. We must have seen the
+		 * close brace.
+		 * TODO: Should also check that we don't refer to something
+		 * that is repeated (+*=): what instance of the repetition
+		 * should we match?
+		 */
+		if (!had_endbrace[refnum])
+		{
+		    /* Trick: check if "@<=" or "@<!" follows, in which case
+		     * the \1 can appear before the referenced match. */
+		    for (p = regparse; *p != NUL; ++p)
+			if (p[0] == '@' && p[1] == '<'
+					      && (p[2] == '!' || p[2] == '='))
+			    break;
+		    if (*p == NUL)
+			EMSG_RET_NULL(_("E65: Illegal back reference"));
+		}
+		ret = regnode(BACKREF + refnum);
+	    }
+	    break;
+
+      case Magic('z'):
+	{
+	    c = no_Magic(getchr());
+	    switch (c)
+	    {
+#ifdef FEAT_SYN_HL
+		case '(': if (reg_do_extmatch != REX_SET)
+			      EMSG_RET_NULL(_("E66: \\z( not allowed here"));
+			  if (one_exactly)
+			      EMSG_ONE_RET_NULL;
+			  ret = reg(REG_ZPAREN, &flags);
+			  if (ret == NULL)
+			      return NULL;
+			  *flagp |= flags & (HASWIDTH|SPSTART|HASNL|HASLOOKBH);
+			  re_has_z = REX_SET;
+			  break;
+
+		case '1':
+		case '2':
+		case '3':
+		case '4':
+		case '5':
+		case '6':
+		case '7':
+		case '8':
+		case '9': if (reg_do_extmatch != REX_USE)
+			      EMSG_RET_NULL(_("E67: \\z1 et al. not allowed here"));
+			  ret = regnode(ZREF + c - '0');
+			  re_has_z = REX_USE;
+			  break;
+#endif
+
+		case 's': ret = regnode(MOPEN + 0);
+			  break;
+
+		case 'e': ret = regnode(MCLOSE + 0);
+			  break;
+
+		default:  EMSG_RET_NULL(_("E68: Invalid character after \\z"));
+	    }
+	}
+	break;
+
+      case Magic('%'):
+	{
+	    c = no_Magic(getchr());
+	    switch (c)
+	    {
+		/* () without a back reference */
+		case '(':
+		    if (one_exactly)
+			EMSG_ONE_RET_NULL;
+		    ret = reg(REG_NPAREN, &flags);
+		    if (ret == NULL)
+			return NULL;
+		    *flagp |= flags & (HASWIDTH | SPSTART | HASNL | HASLOOKBH);
+		    break;
+
+		/* Catch \%^ and \%$ regardless of where they appear in the
+		 * pattern -- regardless of whether or not it makes sense. */
+		case '^':
+		    ret = regnode(RE_BOF);
+		    break;
+
+		case '$':
+		    ret = regnode(RE_EOF);
+		    break;
+
+		case '#':
+		    ret = regnode(CURSOR);
+		    break;
+
+		case 'V':
+		    ret = regnode(RE_VISUAL);
+		    break;
+
+		/* \%[abc]: Emit as a list of branches, all ending at the last
+		 * branch which matches nothing. */
+		case '[':
+			  if (one_exactly)	/* doesn't nest */
+			      EMSG_ONE_RET_NULL;
+			  {
+			      char_u	*lastbranch;
+			      char_u	*lastnode = NULL;
+			      char_u	*br;
+
+			      ret = NULL;
+			      while ((c = getchr()) != ']')
+			      {
+				  if (c == NUL)
+				      EMSG_M_RET_NULL(_("E69: Missing ] after %s%%["),
+						      reg_magic == MAGIC_ALL);
+				  br = regnode(BRANCH);
+				  if (ret == NULL)
+				      ret = br;
+				  else
+				      regtail(lastnode, br);
+
+				  ungetchr();
+				  one_exactly = TRUE;
+				  lastnode = regatom(flagp);
+				  one_exactly = FALSE;
+				  if (lastnode == NULL)
+				      return NULL;
+			      }
+			      if (ret == NULL)
+				  EMSG_M_RET_NULL(_("E70: Empty %s%%[]"),
+						      reg_magic == MAGIC_ALL);
+			      lastbranch = regnode(BRANCH);
+			      br = regnode(NOTHING);
+			      if (ret != JUST_CALC_SIZE)
+			      {
+				  regtail(lastnode, br);
+				  regtail(lastbranch, br);
+				  /* connect all branches to the NOTHING
+				   * branch at the end */
+				  for (br = ret; br != lastnode; )
+				  {
+				      if (OP(br) == BRANCH)
+				      {
+					  regtail(br, lastbranch);
+					  br = OPERAND(br);
+				      }
+				      else
+					  br = regnext(br);
+				  }
+			      }
+			      *flagp &= ~HASWIDTH;
+			      break;
+			  }
+
+		case 'd':   /* %d123 decimal */
+		case 'o':   /* %o123 octal */
+		case 'x':   /* %xab hex 2 */
+		case 'u':   /* %uabcd hex 4 */
+		case 'U':   /* %U1234abcd hex 8 */
+			  {
+			      int i;
+
+			      switch (c)
+			      {
+				  case 'd': i = getdecchrs(); break;
+				  case 'o': i = getoctchrs(); break;
+				  case 'x': i = gethexchrs(2); break;
+				  case 'u': i = gethexchrs(4); break;
+				  case 'U': i = gethexchrs(8); break;
+				  default:  i = -1; break;
+			      }
+
+			      if (i < 0)
+				  EMSG_M_RET_NULL(
+					_("E678: Invalid character after %s%%[dxouU]"),
+					reg_magic == MAGIC_ALL);
+#ifdef FEAT_MBYTE
+			      if (use_multibytecode(i))
+				  ret = regnode(MULTIBYTECODE);
+			      else
+#endif
+				  ret = regnode(EXACTLY);
+			      if (i == 0)
+				  regc(0x0a);
+			      else
+#ifdef FEAT_MBYTE
+				  regmbc(i);
+#else
+				  regc(i);
+#endif
+			      regc(NUL);
+			      *flagp |= HASWIDTH;
+			      break;
+			  }
+
+		default:
+			  if (VIM_ISDIGIT(c) || c == '<' || c == '>'
+								 || c == '\'')
+			  {
+			      long_u	n = 0;
+			      int	cmp;
+
+			      cmp = c;
+			      if (cmp == '<' || cmp == '>')
+				  c = getchr();
+			      while (VIM_ISDIGIT(c))
+			      {
+				  n = n * 10 + (c - '0');
+				  c = getchr();
+			      }
+			      if (c == '\'' && n == 0)
+			      {
+				  /* "\%'m", "\%<'m" and "\%>'m": Mark */
+				  c = getchr();
+				  ret = regnode(RE_MARK);
+				  if (ret == JUST_CALC_SIZE)
+				      regsize += 2;
+				  else
+				  {
+				      *regcode++ = c;
+				      *regcode++ = cmp;
+				  }
+				  break;
+			      }
+			      else if (c == 'l' || c == 'c' || c == 'v')
+			      {
+				  if (c == 'l')
+				      ret = regnode(RE_LNUM);
+				  else if (c == 'c')
+				      ret = regnode(RE_COL);
+				  else
+				      ret = regnode(RE_VCOL);
+				  if (ret == JUST_CALC_SIZE)
+				      regsize += 5;
+				  else
+				  {
+				      /* put the number and the optional
+				       * comparator after the opcode */
+				      regcode = re_put_long(regcode, n);
+				      *regcode++ = cmp;
+				  }
+				  break;
+			      }
+			  }
+
+			  EMSG_M_RET_NULL(_("E71: Invalid character after %s%%"),
+						      reg_magic == MAGIC_ALL);
+	    }
+	}
+	break;
+
+      case Magic('['):
+collection:
+	{
+	    char_u	*lp;
+
+	    /*
+	     * If there is no matching ']', we assume the '[' is a normal
+	     * character.  This makes 'incsearch' and ":help [" work.
+	     */
+	    lp = skip_anyof(regparse);
+	    if (*lp == ']')	/* there is a matching ']' */
+	    {
+		int	startc = -1;	/* > 0 when next '-' is a range */
+		int	endc;
+
+		/*
+		 * In a character class, different parsing rules apply.
+		 * Not even \ is special anymore, nothing is.
+		 */
+		if (*regparse == '^')	    /* Complement of range. */
+		{
+		    ret = regnode(ANYBUT + extra);
+		    regparse++;
+		}
+		else
+		    ret = regnode(ANYOF + extra);
+
+		/* At the start ']' and '-' mean the literal character. */
+		if (*regparse == ']' || *regparse == '-')
+		{
+		    startc = *regparse;
+		    regc(*regparse++);
+		}
+
+		while (*regparse != NUL && *regparse != ']')
+		{
+		    if (*regparse == '-')
+		    {
+			++regparse;
+			/* The '-' is not used for a range at the end and
+			 * after or before a '\n'. */
+			if (*regparse == ']' || *regparse == NUL
+				|| startc == -1
+				|| (regparse[0] == '\\' && regparse[1] == 'n'))
+			{
+			    regc('-');
+			    startc = '-';	/* [--x] is a range */
+			}
+			else
+			{
+			    /* Also accept "a-[.z.]" */
+			    endc = 0;
+			    if (*regparse == '[')
+				endc = get_coll_element(&regparse);
+			    if (endc == 0)
+			    {
+#ifdef FEAT_MBYTE
+				if (has_mbyte)
+				    endc = mb_ptr2char_adv(&regparse);
+				else
+#endif
+				    endc = *regparse++;
+			    }
+
+			    /* Handle \o40, \x20 and \u20AC style sequences */
+			    if (endc == '\\' && !cpo_lit && !cpo_bsl)
+				endc = coll_get_char();
+
+			    if (startc > endc)
+				EMSG_RET_NULL(_(e_invrange));
+#ifdef FEAT_MBYTE
+			    if (has_mbyte && ((*mb_char2len)(startc) > 1
+						 || (*mb_char2len)(endc) > 1))
+			    {
+				/* Limit to a range of 256 chars */
+				if (endc > startc + 256)
+				    EMSG_RET_NULL(_(e_invrange));
+				while (++startc <= endc)
+				    regmbc(startc);
+			    }
+			    else
+#endif
+			    {
+#ifdef EBCDIC
+				int	alpha_only = FALSE;
+
+				/* for alphabetical range skip the gaps
+				 * 'i'-'j', 'r'-'s', 'I'-'J' and 'R'-'S'.  */
+				if (isalpha(startc) && isalpha(endc))
+				    alpha_only = TRUE;
+#endif
+				while (++startc <= endc)
+#ifdef EBCDIC
+				    if (!alpha_only || isalpha(startc))
+#endif
+					regc(startc);
+			    }
+			    startc = -1;
+			}
+		    }
+		    /*
+		     * Only "\]", "\^", "\]" and "\\" are special in Vi.  Vim
+		     * accepts "\t", "\e", etc., but only when the 'l' flag in
+		     * 'cpoptions' is not included.
+		     * Posix doesn't recognize backslash at all.
+		     */
+		    else if (*regparse == '\\'
+			    && !cpo_bsl
+			    && (vim_strchr(REGEXP_INRANGE, regparse[1]) != NULL
+				|| (!cpo_lit
+				    && vim_strchr(REGEXP_ABBR,
+						       regparse[1]) != NULL)))
+		    {
+			regparse++;
+			if (*regparse == 'n')
+			{
+			    /* '\n' in range: also match NL */
+			    if (ret != JUST_CALC_SIZE)
+			    {
+				if (*ret == ANYBUT)
+				    *ret = ANYBUT + ADD_NL;
+				else if (*ret == ANYOF)
+				    *ret = ANYOF + ADD_NL;
+				/* else: must have had a \n already */
+			    }
+			    *flagp |= HASNL;
+			    regparse++;
+			    startc = -1;
+			}
+			else if (*regparse == 'd'
+				|| *regparse == 'o'
+				|| *regparse == 'x'
+				|| *regparse == 'u'
+				|| *regparse == 'U')
+			{
+			    startc = coll_get_char();
+			    if (startc == 0)
+				regc(0x0a);
+			    else
+#ifdef FEAT_MBYTE
+				regmbc(startc);
+#else
+				regc(startc);
+#endif
+			}
+			else
+			{
+			    startc = backslash_trans(*regparse++);
+			    regc(startc);
+			}
+		    }
+		    else if (*regparse == '[')
+		    {
+			int c_class;
+			int cu;
+
+			c_class = get_char_class(&regparse);
+			startc = -1;
+			/* Characters assumed to be 8 bits! */
+			switch (c_class)
+			{
+			    case CLASS_NONE:
+				c_class = get_equi_class(&regparse);
+				if (c_class != 0)
+				{
+				    /* produce equivalence class */
+				    reg_equi_class(c_class);
+				}
+				else if ((c_class =
+					    get_coll_element(&regparse)) != 0)
+				{
+				    /* produce a collating element */
+				    regmbc(c_class);
+				}
+				else
+				{
+				    /* literal '[', allow [[-x] as a range */
+				    startc = *regparse++;
+				    regc(startc);
+				}
+				break;
+			    case CLASS_ALNUM:
+				for (cu = 1; cu <= 255; cu++)
+				    if (isalnum(cu))
+					regc(cu);
+				break;
+			    case CLASS_ALPHA:
+				for (cu = 1; cu <= 255; cu++)
+				    if (isalpha(cu))
+					regc(cu);
+				break;
+			    case CLASS_BLANK:
+				regc(' ');
+				regc('\t');
+				break;
+			    case CLASS_CNTRL:
+				for (cu = 1; cu <= 255; cu++)
+				    if (iscntrl(cu))
+					regc(cu);
+				break;
+			    case CLASS_DIGIT:
+				for (cu = 1; cu <= 255; cu++)
+				    if (VIM_ISDIGIT(cu))
+					regc(cu);
+				break;
+			    case CLASS_GRAPH:
+				for (cu = 1; cu <= 255; cu++)
+				    if (isgraph(cu))
+					regc(cu);
+				break;
+			    case CLASS_LOWER:
+				for (cu = 1; cu <= 255; cu++)
+				    if (islower(cu))
+					regc(cu);
+				break;
+			    case CLASS_PRINT:
+				for (cu = 1; cu <= 255; cu++)
+				    if (vim_isprintc(cu))
+					regc(cu);
+				break;
+			    case CLASS_PUNCT:
+				for (cu = 1; cu <= 255; cu++)
+				    if (ispunct(cu))
+					regc(cu);
+				break;
+			    case CLASS_SPACE:
+				for (cu = 9; cu <= 13; cu++)
+				    regc(cu);
+				regc(' ');
+				break;
+			    case CLASS_UPPER:
+				for (cu = 1; cu <= 255; cu++)
+				    if (isupper(cu))
+					regc(cu);
+				break;
+			    case CLASS_XDIGIT:
+				for (cu = 1; cu <= 255; cu++)
+				    if (vim_isxdigit(cu))
+					regc(cu);
+				break;
+			    case CLASS_TAB:
+				regc('\t');
+				break;
+			    case CLASS_RETURN:
+				regc('\r');
+				break;
+			    case CLASS_BACKSPACE:
+				regc('\b');
+				break;
+			    case CLASS_ESCAPE:
+				regc('\033');
+				break;
+			}
+		    }
+		    else
+		    {
+#ifdef FEAT_MBYTE
+			if (has_mbyte)
+			{
+			    int	len;
+
+			    /* produce a multibyte character, including any
+			     * following composing characters */
+			    startc = mb_ptr2char(regparse);
+			    len = (*mb_ptr2len)(regparse);
+			    if (enc_utf8 && utf_char2len(startc) != len)
+				startc = -1;	/* composing chars */
+			    while (--len >= 0)
+				regc(*regparse++);
+			}
+			else
+#endif
+			{
+			    startc = *regparse++;
+			    regc(startc);
+			}
+		    }
+		}
+		regc(NUL);
+		prevchr_len = 1;	/* last char was the ']' */
+		if (*regparse != ']')
+		    EMSG_RET_NULL(_(e_toomsbra));	/* Cannot happen? */
+		skipchr();	    /* let's be friends with the lexer again */
+		*flagp |= HASWIDTH | SIMPLE;
+		break;
+	    }
+	    else if (reg_strict)
+		EMSG_M_RET_NULL(_("E769: Missing ] after %s["),
+						       reg_magic > MAGIC_OFF);
+	}
+	/* FALLTHROUGH */
+
+      default:
+	{
+	    int		len;
+
+#ifdef FEAT_MBYTE
+	    /* A multi-byte character is handled as a separate atom if it's
+	     * before a multi and when it's a composing char. */
+	    if (use_multibytecode(c))
+	    {
+do_multibyte:
+		ret = regnode(MULTIBYTECODE);
+		regmbc(c);
+		*flagp |= HASWIDTH | SIMPLE;
+		break;
+	    }
+#endif
+
+	    ret = regnode(EXACTLY);
+
+	    /*
+	     * Append characters as long as:
+	     * - there is no following multi, we then need the character in
+	     *   front of it as a single character operand
+	     * - not running into a Magic character
+	     * - "one_exactly" is not set
+	     * But always emit at least one character.  Might be a Multi,
+	     * e.g., a "[" without matching "]".
+	     */
+	    for (len = 0; c != NUL && (len == 0
+			|| (re_multi_type(peekchr()) == NOT_MULTI
+			    && !one_exactly
+			    && !is_Magic(c))); ++len)
+	    {
+		c = no_Magic(c);
+#ifdef FEAT_MBYTE
+		if (has_mbyte)
+		{
+		    regmbc(c);
+		    if (enc_utf8)
+		    {
+			int	l;
+
+			/* Need to get composing character too. */
+			for (;;)
+			{
+			    l = utf_ptr2len(regparse);
+			    if (!UTF_COMPOSINGLIKE(regparse, regparse + l))
+				break;
+			    regmbc(utf_ptr2char(regparse));
+			    skipchr();
+			}
+		    }
+		}
+		else
+#endif
+		    regc(c);
+		c = getchr();
+	    }
+	    ungetchr();
+
+	    regc(NUL);
+	    *flagp |= HASWIDTH;
+	    if (len == 1)
+		*flagp |= SIMPLE;
+	}
+	break;
+    }
+
+    return ret;
+}
+
+#ifdef FEAT_MBYTE
+/*
+ * Return TRUE if MULTIBYTECODE should be used instead of EXACTLY for
+ * character "c".
+ */
+    static int
+use_multibytecode(c)
+    int c;
+{
+    return has_mbyte && (*mb_char2len)(c) > 1
+		     && (re_multi_type(peekchr()) != NOT_MULTI
+			     || (enc_utf8 && utf_iscomposing(c)));
+}
+#endif
+
+/*
+ * emit a node
+ * Return pointer to generated code.
+ */
+    static char_u *
+regnode(op)
+    int		op;
+{
+    char_u  *ret;
+
+    ret = regcode;
+    if (ret == JUST_CALC_SIZE)
+	regsize += 3;
+    else
+    {
+	*regcode++ = op;
+	*regcode++ = NUL;		/* Null "next" pointer. */
+	*regcode++ = NUL;
+    }
+    return ret;
+}
+
+/*
+ * Emit (if appropriate) a byte of code
+ */
+    static void
+regc(b)
+    int		b;
+{
+    if (regcode == JUST_CALC_SIZE)
+	regsize++;
+    else
+	*regcode++ = b;
+}
+
+#ifdef FEAT_MBYTE
+/*
+ * Emit (if appropriate) a multi-byte character of code
+ */
+    static void
+regmbc(c)
+    int		c;
+{
+    if (regcode == JUST_CALC_SIZE)
+	regsize += (*mb_char2len)(c);
+    else
+	regcode += (*mb_char2bytes)(c, regcode);
+}
+#endif
+
+/*
+ * reginsert - insert an operator in front of already-emitted operand
+ *
+ * Means relocating the operand.
+ */
+    static void
+reginsert(op, opnd)
+    int		op;
+    char_u     *opnd;
+{
+    char_u	*src;
+    char_u	*dst;
+    char_u	*place;
+
+    if (regcode == JUST_CALC_SIZE)
+    {
+	regsize += 3;
+	return;
+    }
+    src = regcode;
+    regcode += 3;
+    dst = regcode;
+    while (src > opnd)
+	*--dst = *--src;
+
+    place = opnd;		/* Op node, where operand used to be. */
+    *place++ = op;
+    *place++ = NUL;
+    *place = NUL;
+}
+
+/*
+ * reginsert_limits - insert an operator in front of already-emitted operand.
+ * The operator has the given limit values as operands.  Also set next pointer.
+ *
+ * Means relocating the operand.
+ */
+    static void
+reginsert_limits(op, minval, maxval, opnd)
+    int		op;
+    long	minval;
+    long	maxval;
+    char_u	*opnd;
+{
+    char_u	*src;
+    char_u	*dst;
+    char_u	*place;
+
+    if (regcode == JUST_CALC_SIZE)
+    {
+	regsize += 11;
+	return;
+    }
+    src = regcode;
+    regcode += 11;
+    dst = regcode;
+    while (src > opnd)
+	*--dst = *--src;
+
+    place = opnd;		/* Op node, where operand used to be. */
+    *place++ = op;
+    *place++ = NUL;
+    *place++ = NUL;
+    place = re_put_long(place, (long_u)minval);
+    place = re_put_long(place, (long_u)maxval);
+    regtail(opnd, place);
+}
+
+/*
+ * Write a long as four bytes at "p" and return pointer to the next char.
+ */
+    static char_u *
+re_put_long(p, val)
+    char_u	*p;
+    long_u	val;
+{
+    *p++ = (char_u) ((val >> 24) & 0377);
+    *p++ = (char_u) ((val >> 16) & 0377);
+    *p++ = (char_u) ((val >> 8) & 0377);
+    *p++ = (char_u) (val & 0377);
+    return p;
+}
+
+/*
+ * regtail - set the next-pointer at the end of a node chain
+ */
+    static void
+regtail(p, val)
+    char_u	*p;
+    char_u	*val;
+{
+    char_u	*scan;
+    char_u	*temp;
+    int		offset;
+
+    if (p == JUST_CALC_SIZE)
+	return;
+
+    /* Find last node. */
+    scan = p;
+    for (;;)
+    {
+	temp = regnext(scan);
+	if (temp == NULL)
+	    break;
+	scan = temp;
+    }
+
+    if (OP(scan) == BACK)
+	offset = (int)(scan - val);
+    else
+	offset = (int)(val - scan);
+    *(scan + 1) = (char_u) (((unsigned)offset >> 8) & 0377);
+    *(scan + 2) = (char_u) (offset & 0377);
+}
+
+/*
+ * regoptail - regtail on item after a BRANCH; nop if none
+ */
+    static void
+regoptail(p, val)
+    char_u	*p;
+    char_u	*val;
+{
+    /* When op is neither BRANCH nor BRACE_COMPLEX0-9, it is "operandless" */
+    if (p == NULL || p == JUST_CALC_SIZE
+	    || (OP(p) != BRANCH
+		&& (OP(p) < BRACE_COMPLEX || OP(p) > BRACE_COMPLEX + 9)))
+	return;
+    regtail(OPERAND(p), val);
+}
+
+/*
+ * getchr() - get the next character from the pattern. We know about
+ * magic and such, so therefore we need a lexical analyzer.
+ */
+
+/* static int	    curchr; */
+static int	prevprevchr;
+static int	prevchr;
+static int	nextchr;    /* used for ungetchr() */
+/*
+ * Note: prevchr is sometimes -1 when we are not at the start,
+ * eg in /[ ^I]^ the pattern was never found even if it existed, because ^ was
+ * taken to be magic -- webb
+ */
+static int	at_start;	/* True when on the first character */
+static int	prev_at_start;  /* True when on the second character */
+
+    static void
+initchr(str)
+    char_u *str;
+{
+    regparse = str;
+    prevchr_len = 0;
+    curchr = prevprevchr = prevchr = nextchr = -1;
+    at_start = TRUE;
+    prev_at_start = FALSE;
+}
+
+    static int
+peekchr()
+{
+    static int	after_slash = FALSE;
+
+    if (curchr == -1)
+    {
+	switch (curchr = regparse[0])
+	{
+	case '.':
+	case '[':
+	case '~':
+	    /* magic when 'magic' is on */
+	    if (reg_magic >= MAGIC_ON)
+		curchr = Magic(curchr);
+	    break;
+	case '(':
+	case ')':
+	case '{':
+	case '%':
+	case '+':
+	case '=':
+	case '?':
+	case '@':
+	case '!':
+	case '&':
+	case '|':
+	case '<':
+	case '>':
+	case '#':	/* future ext. */
+	case '"':	/* future ext. */
+	case '\'':	/* future ext. */
+	case ',':	/* future ext. */
+	case '-':	/* future ext. */
+	case ':':	/* future ext. */
+	case ';':	/* future ext. */
+	case '`':	/* future ext. */
+	case '/':	/* Can't be used in / command */
+	    /* magic only after "\v" */
+	    if (reg_magic == MAGIC_ALL)
+		curchr = Magic(curchr);
+	    break;
+	case '*':
+	    /* * is not magic as the very first character, eg "?*ptr", when
+	     * after '^', eg "/^*ptr" and when after "\(", "\|", "\&".  But
+	     * "\(\*" is not magic, thus must be magic if "after_slash" */
+	    if (reg_magic >= MAGIC_ON
+		    && !at_start
+		    && !(prev_at_start && prevchr == Magic('^'))
+		    && (after_slash
+			|| (prevchr != Magic('(')
+			    && prevchr != Magic('&')
+			    && prevchr != Magic('|'))))
+		curchr = Magic('*');
+	    break;
+	case '^':
+	    /* '^' is only magic as the very first character and if it's after
+	     * "\(", "\|", "\&' or "\n" */
+	    if (reg_magic >= MAGIC_OFF
+		    && (at_start
+			|| reg_magic == MAGIC_ALL
+			|| prevchr == Magic('(')
+			|| prevchr == Magic('|')
+			|| prevchr == Magic('&')
+			|| prevchr == Magic('n')
+			|| (no_Magic(prevchr) == '('
+			    && prevprevchr == Magic('%'))))
+	    {
+		curchr = Magic('^');
+		at_start = TRUE;
+		prev_at_start = FALSE;
+	    }
+	    break;
+	case '$':
+	    /* '$' is only magic as the very last char and if it's in front of
+	     * either "\|", "\)", "\&", or "\n" */
+	    if (reg_magic >= MAGIC_OFF)
+	    {
+		char_u *p = regparse + 1;
+
+		/* ignore \c \C \m and \M after '$' */
+		while (p[0] == '\\' && (p[1] == 'c' || p[1] == 'C'
+				|| p[1] == 'm' || p[1] == 'M' || p[1] == 'Z'))
+		    p += 2;
+		if (p[0] == NUL
+			|| (p[0] == '\\'
+			    && (p[1] == '|' || p[1] == '&' || p[1] == ')'
+				|| p[1] == 'n'))
+			|| reg_magic == MAGIC_ALL)
+		    curchr = Magic('$');
+	    }
+	    break;
+	case '\\':
+	    {
+		int c = regparse[1];
+
+		if (c == NUL)
+		    curchr = '\\';	/* trailing '\' */
+		else if (
+#ifdef EBCDIC
+			vim_strchr(META, c)
+#else
+			c <= '~' && META_flags[c]
+#endif
+			)
+		{
+		    /*
+		     * META contains everything that may be magic sometimes,
+		     * except ^ and $ ("\^" and "\$" are only magic after
+		     * "\v").  We now fetch the next character and toggle its
+		     * magicness.  Therefore, \ is so meta-magic that it is
+		     * not in META.
+		     */
+		    curchr = -1;
+		    prev_at_start = at_start;
+		    at_start = FALSE;	/* be able to say "/\*ptr" */
+		    ++regparse;
+		    ++after_slash;
+		    peekchr();
+		    --regparse;
+		    --after_slash;
+		    curchr = toggle_Magic(curchr);
+		}
+		else if (vim_strchr(REGEXP_ABBR, c))
+		{
+		    /*
+		     * Handle abbreviations, like "\t" for TAB -- webb
+		     */
+		    curchr = backslash_trans(c);
+		}
+		else if (reg_magic == MAGIC_NONE && (c == '$' || c == '^'))
+		    curchr = toggle_Magic(c);
+		else
+		{
+		    /*
+		     * Next character can never be (made) magic?
+		     * Then backslashing it won't do anything.
+		     */
+#ifdef FEAT_MBYTE
+		    if (has_mbyte)
+			curchr = (*mb_ptr2char)(regparse + 1);
+		    else
+#endif
+			curchr = c;
+		}
+		break;
+	    }
+
+#ifdef FEAT_MBYTE
+	default:
+	    if (has_mbyte)
+		curchr = (*mb_ptr2char)(regparse);
+#endif
+	}
+    }
+
+    return curchr;
+}
+
+/*
+ * Eat one lexed character.  Do this in a way that we can undo it.
+ */
+    static void
+skipchr()
+{
+    /* peekchr() eats a backslash, do the same here */
+    if (*regparse == '\\')
+	prevchr_len = 1;
+    else
+	prevchr_len = 0;
+    if (regparse[prevchr_len] != NUL)
+    {
+#ifdef FEAT_MBYTE
+	if (enc_utf8)
+	    prevchr_len += utf_char2len(mb_ptr2char(regparse + prevchr_len));
+	else if (has_mbyte)
+	    prevchr_len += (*mb_ptr2len)(regparse + prevchr_len);
+	else
+#endif
+	    ++prevchr_len;
+    }
+    regparse += prevchr_len;
+    prev_at_start = at_start;
+    at_start = FALSE;
+    prevprevchr = prevchr;
+    prevchr = curchr;
+    curchr = nextchr;	    /* use previously unget char, or -1 */
+    nextchr = -1;
+}
+
+/*
+ * Skip a character while keeping the value of prev_at_start for at_start.
+ * prevchr and prevprevchr are also kept.
+ */
+    static void
+skipchr_keepstart()
+{
+    int as = prev_at_start;
+    int pr = prevchr;
+    int prpr = prevprevchr;
+
+    skipchr();
+    at_start = as;
+    prevchr = pr;
+    prevprevchr = prpr;
+}
+
+    static int
+getchr()
+{
+    int chr = peekchr();
+
+    skipchr();
+    return chr;
+}
+
+/*
+ * put character back.  Works only once!
+ */
+    static void
+ungetchr()
+{
+    nextchr = curchr;
+    curchr = prevchr;
+    prevchr = prevprevchr;
+    at_start = prev_at_start;
+    prev_at_start = FALSE;
+
+    /* Backup regparse, so that it's at the same position as before the
+     * getchr(). */
+    regparse -= prevchr_len;
+}
+
+/*
+ * Get and return the value of the hex string at the current position.
+ * Return -1 if there is no valid hex number.
+ * The position is updated:
+ *     blahblah\%x20asdf
+ *	   before-^ ^-after
+ * The parameter controls the maximum number of input characters. This will be
+ * 2 when reading a \%x20 sequence and 4 when reading a \%u20AC sequence.
+ */
+    static int
+gethexchrs(maxinputlen)
+    int		maxinputlen;
+{
+    int		nr = 0;
+    int		c;
+    int		i;
+
+    for (i = 0; i < maxinputlen; ++i)
+    {
+	c = regparse[0];
+	if (!vim_isxdigit(c))
+	    break;
+	nr <<= 4;
+	nr |= hex2nr(c);
+	++regparse;
+    }
+
+    if (i == 0)
+	return -1;
+    return nr;
+}
+
+/*
+ * get and return the value of the decimal string immediately after the
+ * current position. Return -1 for invalid.  Consumes all digits.
+ */
+    static int
+getdecchrs()
+{
+    int		nr = 0;
+    int		c;
+    int		i;
+
+    for (i = 0; ; ++i)
+    {
+	c = regparse[0];
+	if (c < '0' || c > '9')
+	    break;
+	nr *= 10;
+	nr += c - '0';
+	++regparse;
+    }
+
+    if (i == 0)
+	return -1;
+    return nr;
+}
+
+/*
+ * get and return the value of the octal string immediately after the current
+ * position. Return -1 for invalid, or 0-255 for valid. Smart enough to handle
+ * numbers > 377 correctly (for example, 400 is treated as 40) and doesn't
+ * treat 8 or 9 as recognised characters. Position is updated:
+ *     blahblah\%o210asdf
+ *	   before-^  ^-after
+ */
+    static int
+getoctchrs()
+{
+    int		nr = 0;
+    int		c;
+    int		i;
+
+    for (i = 0; i < 3 && nr < 040; ++i)
+    {
+	c = regparse[0];
+	if (c < '0' || c > '7')
+	    break;
+	nr <<= 3;
+	nr |= hex2nr(c);
+	++regparse;
+    }
+
+    if (i == 0)
+	return -1;
+    return nr;
+}
+
+/*
+ * Get a number after a backslash that is inside [].
+ * When nothing is recognized return a backslash.
+ */
+    static int
+coll_get_char()
+{
+    int	    nr = -1;
+
+    switch (*regparse++)
+    {
+	case 'd': nr = getdecchrs(); break;
+	case 'o': nr = getoctchrs(); break;
+	case 'x': nr = gethexchrs(2); break;
+	case 'u': nr = gethexchrs(4); break;
+	case 'U': nr = gethexchrs(8); break;
+    }
+    if (nr < 0)
+    {
+	/* If getting the number fails be backwards compatible: the character
+	 * is a backslash. */
+	--regparse;
+	nr = '\\';
+    }
+    return nr;
+}
+
+/*
+ * read_limits - Read two integers to be taken as a minimum and maximum.
+ * If the first character is '-', then the range is reversed.
+ * Should end with 'end'.  If minval is missing, zero is default, if maxval is
+ * missing, a very big number is the default.
+ */
+    static int
+read_limits(minval, maxval)
+    long	*minval;
+    long	*maxval;
+{
+    int		reverse = FALSE;
+    char_u	*first_char;
+    long	tmp;
+
+    if (*regparse == '-')
+    {
+	/* Starts with '-', so reverse the range later */
+	regparse++;
+	reverse = TRUE;
+    }
+    first_char = regparse;
+    *minval = getdigits(&regparse);
+    if (*regparse == ',')	    /* There is a comma */
+    {
+	if (vim_isdigit(*++regparse))
+	    *maxval = getdigits(&regparse);
+	else
+	    *maxval = MAX_LIMIT;
+    }
+    else if (VIM_ISDIGIT(*first_char))
+	*maxval = *minval;	    /* It was \{n} or \{-n} */
+    else
+	*maxval = MAX_LIMIT;	    /* It was \{} or \{-} */
+    if (*regparse == '\\')
+	regparse++;	/* Allow either \{...} or \{...\} */
+    if (*regparse != '}')
+    {
+	sprintf((char *)IObuff, _("E554: Syntax error in %s{...}"),
+					  reg_magic == MAGIC_ALL ? "" : "\\");
+	EMSG_RET_FAIL(IObuff);
+    }
+
+    /*
+     * Reverse the range if there was a '-', or make sure it is in the right
+     * order otherwise.
+     */
+    if ((!reverse && *minval > *maxval) || (reverse && *minval < *maxval))
+    {
+	tmp = *minval;
+	*minval = *maxval;
+	*maxval = tmp;
+    }
+    skipchr();		/* let's be friends with the lexer again */
+    return OK;
+}
+
+/*
+ * vim_regexec and friends
+ */
+
+/*
+ * Global work variables for vim_regexec().
+ */
+
+/* The current match-position is remembered with these variables: */
+static linenr_T	reglnum;	/* line number, relative to first line */
+static char_u	*regline;	/* start of current line */
+static char_u	*reginput;	/* current input, points into "regline" */
+
+static int	need_clear_subexpr;	/* subexpressions still need to be
+					 * cleared */
+#ifdef FEAT_SYN_HL
+static int	need_clear_zsubexpr = FALSE;	/* extmatch subexpressions
+						 * still need to be cleared */
+#endif
+
+/*
+ * Structure used to save the current input state, when it needs to be
+ * restored after trying a match.  Used by reg_save() and reg_restore().
+ * Also stores the length of "backpos".
+ */
+typedef struct
+{
+    union
+    {
+	char_u	*ptr;	/* reginput pointer, for single-line regexp */
+	lpos_T	pos;	/* reginput pos, for multi-line regexp */
+    } rs_u;
+    int		rs_len;
+} regsave_T;
+
+/* struct to save start/end pointer/position in for \(\) */
+typedef struct
+{
+    union
+    {
+	char_u	*ptr;
+	lpos_T	pos;
+    } se_u;
+} save_se_T;
+
+static char_u	*reg_getline __ARGS((linenr_T lnum));
+static long	vim_regexec_both __ARGS((char_u *line, colnr_T col));
+static long	regtry __ARGS((regprog_T *prog, colnr_T col));
+static void	cleanup_subexpr __ARGS((void));
+#ifdef FEAT_SYN_HL
+static void	cleanup_zsubexpr __ARGS((void));
+#endif
+static void	reg_nextline __ARGS((void));
+static void	reg_save __ARGS((regsave_T *save, garray_T *gap));
+static void	reg_restore __ARGS((regsave_T *save, garray_T *gap));
+static int	reg_save_equal __ARGS((regsave_T *save));
+static void	save_se_multi __ARGS((save_se_T *savep, lpos_T *posp));
+static void	save_se_one __ARGS((save_se_T *savep, char_u **pp));
+
+/* Save the sub-expressions before attempting a match. */
+#define save_se(savep, posp, pp) \
+    REG_MULTI ? save_se_multi((savep), (posp)) : save_se_one((savep), (pp))
+
+/* After a failed match restore the sub-expressions. */
+#define restore_se(savep, posp, pp) { \
+    if (REG_MULTI) \
+	*(posp) = (savep)->se_u.pos; \
+    else \
+	*(pp) = (savep)->se_u.ptr; }
+
+static int	re_num_cmp __ARGS((long_u val, char_u *scan));
+static int	regmatch __ARGS((char_u *prog));
+static int	regrepeat __ARGS((char_u *p, long maxcount));
+
+#ifdef DEBUG
+int		regnarrate = 0;
+#endif
+
+/*
+ * Internal copy of 'ignorecase'.  It is set at each call to vim_regexec().
+ * Normally it gets the value of "rm_ic" or "rmm_ic", but when the pattern
+ * contains '\c' or '\C' the value is overruled.
+ */
+static int	ireg_ic;
+
+#ifdef FEAT_MBYTE
+/*
+ * Similar to ireg_ic, but only for 'combining' characters.  Set with \Z flag
+ * in the regexp.  Defaults to false, always.
+ */
+static int	ireg_icombine;
+#endif
+
+/*
+ * Copy of "rmm_maxcol": maximum column to search for a match.  Zero when
+ * there is no maximum.
+ */
+static colnr_T	ireg_maxcol;
+
+/*
+ * Sometimes need to save a copy of a line.  Since alloc()/free() is very
+ * slow, we keep one allocated piece of memory and only re-allocate it when
+ * it's too small.  It's freed in vim_regexec_both() when finished.
+ */
+static char_u	*reg_tofree;
+static unsigned	reg_tofreelen;
+
+/*
+ * These variables are set when executing a regexp to speed up the execution.
+ * Which ones are set depends on whether a single-line or multi-line match is
+ * done:
+ *			single-line		multi-line
+ * reg_match		&regmatch_T		NULL
+ * reg_mmatch		NULL			&regmmatch_T
+ * reg_startp		reg_match->startp	<invalid>
+ * reg_endp		reg_match->endp		<invalid>
+ * reg_startpos		<invalid>		reg_mmatch->startpos
+ * reg_endpos		<invalid>		reg_mmatch->endpos
+ * reg_win		NULL			window in which to search
+ * reg_buf		<invalid>		buffer in which to search
+ * reg_firstlnum	<invalid>		first line in which to search
+ * reg_maxline		0			last line nr
+ * reg_line_lbr		FALSE or TRUE		FALSE
+ */
+static regmatch_T	*reg_match;
+static regmmatch_T	*reg_mmatch;
+static char_u		**reg_startp = NULL;
+static char_u		**reg_endp = NULL;
+static lpos_T		*reg_startpos = NULL;
+static lpos_T		*reg_endpos = NULL;
+static win_T		*reg_win;
+static buf_T		*reg_buf;
+static linenr_T		reg_firstlnum;
+static linenr_T		reg_maxline;
+static int		reg_line_lbr;	    /* "\n" in string is line break */
+
+/* Values for rs_state in regitem_T. */
+typedef enum regstate_E
+{
+    RS_NOPEN = 0	/* NOPEN and NCLOSE */
+    , RS_MOPEN		/* MOPEN + [0-9] */
+    , RS_MCLOSE		/* MCLOSE + [0-9] */
+#ifdef FEAT_SYN_HL
+    , RS_ZOPEN		/* ZOPEN + [0-9] */
+    , RS_ZCLOSE		/* ZCLOSE + [0-9] */
+#endif
+    , RS_BRANCH		/* BRANCH */
+    , RS_BRCPLX_MORE	/* BRACE_COMPLEX and trying one more match */
+    , RS_BRCPLX_LONG	/* BRACE_COMPLEX and trying longest match */
+    , RS_BRCPLX_SHORT	/* BRACE_COMPLEX and trying shortest match */
+    , RS_NOMATCH	/* NOMATCH */
+    , RS_BEHIND1	/* BEHIND / NOBEHIND matching rest */
+    , RS_BEHIND2	/* BEHIND / NOBEHIND matching behind part */
+    , RS_STAR_LONG	/* STAR/PLUS/BRACE_SIMPLE longest match */
+    , RS_STAR_SHORT	/* STAR/PLUS/BRACE_SIMPLE shortest match */
+} regstate_T;
+
+/*
+ * When there are alternatives a regstate_T is put on the regstack to remember
+ * what we are doing.
+ * Before it may be another type of item, depending on rs_state, to remember
+ * more things.
+ */
+typedef struct regitem_S
+{
+    regstate_T	rs_state;	/* what we are doing, one of RS_ above */
+    char_u	*rs_scan;	/* current node in program */
+    union
+    {
+	save_se_T  sesave;
+	regsave_T  regsave;
+    } rs_un;			/* room for saving reginput */
+    short	rs_no;		/* submatch nr */
+} regitem_T;
+
+static regitem_T *regstack_push __ARGS((regstate_T state, char_u *scan));
+static void regstack_pop __ARGS((char_u **scan));
+
+/* used for BEHIND and NOBEHIND matching */
+typedef struct regbehind_S
+{
+    regsave_T	save_after;
+    regsave_T	save_behind;
+} regbehind_T;
+
+/* used for STAR, PLUS and BRACE_SIMPLE matching */
+typedef struct regstar_S
+{
+    int		nextb;		/* next byte */
+    int		nextb_ic;	/* next byte reverse case */
+    long	count;
+    long	minval;
+    long	maxval;
+} regstar_T;
+
+/* used to store input position when a BACK was encountered, so that we now if
+ * we made any progress since the last time. */
+typedef struct backpos_S
+{
+    char_u	*bp_scan;	/* "scan" where BACK was encountered */
+    regsave_T	bp_pos;		/* last input position */
+} backpos_T;
+
+/*
+ * regstack and backpos are used by regmatch().  They are kept over calls to
+ * avoid invoking malloc() and free() often.
+ */
+static garray_T	regstack;	/* stack with regitem_T items, sometimes
+				   preceded by regstar_T or regbehind_T. */
+static garray_T	backpos;	/* table with backpos_T for BACK */
+
+/*
+ * Get pointer to the line "lnum", which is relative to "reg_firstlnum".
+ */
+    static char_u *
+reg_getline(lnum)
+    linenr_T	lnum;
+{
+    /* when looking behind for a match/no-match lnum is negative.  But we
+     * can't go before line 1 */
+    if (reg_firstlnum + lnum < 1)
+	return NULL;
+    if (lnum > reg_maxline)
+	/* Must have matched the "\n" in the last line. */
+	return (char_u *)"";
+    return ml_get_buf(reg_buf, reg_firstlnum + lnum, FALSE);
+}
+
+static regsave_T behind_pos;
+
+#ifdef FEAT_SYN_HL
+static char_u	*reg_startzp[NSUBEXP];	/* Workspace to mark beginning */
+static char_u	*reg_endzp[NSUBEXP];	/*   and end of \z(...\) matches */
+static lpos_T	reg_startzpos[NSUBEXP];	/* idem, beginning pos */
+static lpos_T	reg_endzpos[NSUBEXP];	/* idem, end pos */
+#endif
+
+/* TRUE if using multi-line regexp. */
+#define REG_MULTI	(reg_match == NULL)
+
+/*
+ * Match a regexp against a string.
+ * "rmp->regprog" is a compiled regexp as returned by vim_regcomp().
+ * Uses curbuf for line count and 'iskeyword'.
+ *
+ * Return TRUE if there is a match, FALSE if not.
+ */
+    int
+vim_regexec(rmp, line, col)
+    regmatch_T	*rmp;
+    char_u	*line;	/* string to match against */
+    colnr_T	col;	/* column to start looking for match */
+{
+    reg_match = rmp;
+    reg_mmatch = NULL;
+    reg_maxline = 0;
+    reg_line_lbr = FALSE;
+    reg_win = NULL;
+    ireg_ic = rmp->rm_ic;
+#ifdef FEAT_MBYTE
+    ireg_icombine = FALSE;
+#endif
+    ireg_maxcol = 0;
+    return (vim_regexec_both(line, col) != 0);
+}
+
+#if defined(FEAT_MODIFY_FNAME) || defined(FEAT_EVAL) \
+	|| defined(FIND_REPLACE_DIALOG) || defined(PROTO)
+/*
+ * Like vim_regexec(), but consider a "\n" in "line" to be a line break.
+ */
+    int
+vim_regexec_nl(rmp, line, col)
+    regmatch_T	*rmp;
+    char_u	*line;	/* string to match against */
+    colnr_T	col;	/* column to start looking for match */
+{
+    reg_match = rmp;
+    reg_mmatch = NULL;
+    reg_maxline = 0;
+    reg_line_lbr = TRUE;
+    reg_win = NULL;
+    ireg_ic = rmp->rm_ic;
+#ifdef FEAT_MBYTE
+    ireg_icombine = FALSE;
+#endif
+    ireg_maxcol = 0;
+    return (vim_regexec_both(line, col) != 0);
+}
+#endif
+
+/*
+ * Match a regexp against multiple lines.
+ * "rmp->regprog" is a compiled regexp as returned by vim_regcomp().
+ * Uses curbuf for line count and 'iskeyword'.
+ *
+ * Return zero if there is no match.  Return number of lines contained in the
+ * match otherwise.
+ */
+    long
+vim_regexec_multi(rmp, win, buf, lnum, col)
+    regmmatch_T	*rmp;
+    win_T	*win;		/* window in which to search or NULL */
+    buf_T	*buf;		/* buffer in which to search */
+    linenr_T	lnum;		/* nr of line to start looking for match */
+    colnr_T	col;		/* column to start looking for match */
+{
+    long	r;
+    buf_T	*save_curbuf = curbuf;
+
+    reg_match = NULL;
+    reg_mmatch = rmp;
+    reg_buf = buf;
+    reg_win = win;
+    reg_firstlnum = lnum;
+    reg_maxline = reg_buf->b_ml.ml_line_count - lnum;
+    reg_line_lbr = FALSE;
+    ireg_ic = rmp->rmm_ic;
+#ifdef FEAT_MBYTE
+    ireg_icombine = FALSE;
+#endif
+    ireg_maxcol = rmp->rmm_maxcol;
+
+    /* Need to switch to buffer "buf" to make vim_iswordc() work. */
+    curbuf = buf;
+    r = vim_regexec_both(NULL, col);
+    curbuf = save_curbuf;
+
+    return r;
+}
+
+/*
+ * Match a regexp against a string ("line" points to the string) or multiple
+ * lines ("line" is NULL, use reg_getline()).
+ */
+    static long
+vim_regexec_both(line, col)
+    char_u	*line;
+    colnr_T	col;		/* column to start looking for match */
+{
+    regprog_T	*prog;
+    char_u	*s;
+    long	retval = 0L;
+
+    reg_tofree = NULL;
+
+    /* Init the regstack empty.  Use an item size of 1 byte, since we push
+     * different things onto it.  Use a large grow size to avoid reallocating
+     * it too often. */
+    ga_init2(&regstack, 1, 10000);
+
+    /* Init the backpos table empty. */
+    ga_init2(&backpos, sizeof(backpos_T), 10);
+
+    if (REG_MULTI)
+    {
+	prog = reg_mmatch->regprog;
+	line = reg_getline((linenr_T)0);
+	reg_startpos = reg_mmatch->startpos;
+	reg_endpos = reg_mmatch->endpos;
+    }
+    else
+    {
+	prog = reg_match->regprog;
+	reg_startp = reg_match->startp;
+	reg_endp = reg_match->endp;
+    }
+
+    /* Be paranoid... */
+    if (prog == NULL || line == NULL)
+    {
+	EMSG(_(e_null));
+	goto theend;
+    }
+
+    /* Check validity of program. */
+    if (prog_magic_wrong())
+	goto theend;
+
+    /* If the start column is past the maximum column: no need to try. */
+    if (ireg_maxcol > 0 && col >= ireg_maxcol)
+	goto theend;
+
+    /* If pattern contains "\c" or "\C": overrule value of ireg_ic */
+    if (prog->regflags & RF_ICASE)
+	ireg_ic = TRUE;
+    else if (prog->regflags & RF_NOICASE)
+	ireg_ic = FALSE;
+
+#ifdef FEAT_MBYTE
+    /* If pattern contains "\Z" overrule value of ireg_icombine */
+    if (prog->regflags & RF_ICOMBINE)
+	ireg_icombine = TRUE;
+#endif
+
+    /* If there is a "must appear" string, look for it. */
+    if (prog->regmust != NULL)
+    {
+	int c;
+
+#ifdef FEAT_MBYTE
+	if (has_mbyte)
+	    c = (*mb_ptr2char)(prog->regmust);
+	else
+#endif
+	    c = *prog->regmust;
+	s = line + col;
+
+	/*
+	 * This is used very often, esp. for ":global".  Use three versions of
+	 * the loop to avoid overhead of conditions.
+	 */
+	if (!ireg_ic
+#ifdef FEAT_MBYTE
+		&& !has_mbyte
+#endif
+		)
+	    while ((s = vim_strbyte(s, c)) != NULL)
+	    {
+		if (cstrncmp(s, prog->regmust, &prog->regmlen) == 0)
+		    break;		/* Found it. */
+		++s;
+	    }
+#ifdef FEAT_MBYTE
+	else if (!ireg_ic || (!enc_utf8 && mb_char2len(c) > 1))
+	    while ((s = vim_strchr(s, c)) != NULL)
+	    {
+		if (cstrncmp(s, prog->regmust, &prog->regmlen) == 0)
+		    break;		/* Found it. */
+		mb_ptr_adv(s);
+	    }
+#endif
+	else
+	    while ((s = cstrchr(s, c)) != NULL)
+	    {
+		if (cstrncmp(s, prog->regmust, &prog->regmlen) == 0)
+		    break;		/* Found it. */
+		mb_ptr_adv(s);
+	    }
+	if (s == NULL)		/* Not present. */
+	    goto theend;
+    }
+
+    regline = line;
+    reglnum = 0;
+
+    /* Simplest case: Anchored match need be tried only once. */
+    if (prog->reganch)
+    {
+	int	c;
+
+#ifdef FEAT_MBYTE
+	if (has_mbyte)
+	    c = (*mb_ptr2char)(regline + col);
+	else
+#endif
+	    c = regline[col];
+	if (prog->regstart == NUL
+		|| prog->regstart == c
+		|| (ireg_ic && ((
+#ifdef FEAT_MBYTE
+			(enc_utf8 && utf_fold(prog->regstart) == utf_fold(c)))
+			|| (c < 255 && prog->regstart < 255 &&
+#endif
+			    TOLOWER_LOC(prog->regstart) == TOLOWER_LOC(c)))))
+	    retval = regtry(prog, col);
+	else
+	    retval = 0;
+    }
+    else
+    {
+	/* Messy cases:  unanchored match. */
+	while (!got_int)
+	{
+	    if (prog->regstart != NUL)
+	    {
+		/* Skip until the char we know it must start with.
+		 * Used often, do some work to avoid call overhead. */
+		if (!ireg_ic
+#ifdef FEAT_MBYTE
+			    && !has_mbyte
+#endif
+			    )
+		    s = vim_strbyte(regline + col, prog->regstart);
+		else
+		    s = cstrchr(regline + col, prog->regstart);
+		if (s == NULL)
+		{
+		    retval = 0;
+		    break;
+		}
+		col = (int)(s - regline);
+	    }
+
+	    /* Check for maximum column to try. */
+	    if (ireg_maxcol > 0 && col >= ireg_maxcol)
+	    {
+		retval = 0;
+		break;
+	    }
+
+	    retval = regtry(prog, col);
+	    if (retval > 0)
+		break;
+
+	    /* if not currently on the first line, get it again */
+	    if (reglnum != 0)
+	    {
+		reglnum = 0;
+		regline = reg_getline((linenr_T)0);
+	    }
+	    if (regline[col] == NUL)
+		break;
+#ifdef FEAT_MBYTE
+	    if (has_mbyte)
+		col += (*mb_ptr2len)(regline + col);
+	    else
+#endif
+		++col;
+	}
+    }
+
+theend:
+    vim_free(reg_tofree);
+    ga_clear(&regstack);
+    ga_clear(&backpos);
+
+    return retval;
+}
+
+#ifdef FEAT_SYN_HL
+static reg_extmatch_T *make_extmatch __ARGS((void));
+
+/*
+ * Create a new extmatch and mark it as referenced once.
+ */
+    static reg_extmatch_T *
+make_extmatch()
+{
+    reg_extmatch_T	*em;
+
+    em = (reg_extmatch_T *)alloc_clear((unsigned)sizeof(reg_extmatch_T));
+    if (em != NULL)
+	em->refcnt = 1;
+    return em;
+}
+
+/*
+ * Add a reference to an extmatch.
+ */
+    reg_extmatch_T *
+ref_extmatch(em)
+    reg_extmatch_T	*em;
+{
+    if (em != NULL)
+	em->refcnt++;
+    return em;
+}
+
+/*
+ * Remove a reference to an extmatch.  If there are no references left, free
+ * the info.
+ */
+    void
+unref_extmatch(em)
+    reg_extmatch_T	*em;
+{
+    int i;
+
+    if (em != NULL && --em->refcnt <= 0)
+    {
+	for (i = 0; i < NSUBEXP; ++i)
+	    vim_free(em->matches[i]);
+	vim_free(em);
+    }
+}
+#endif
+
+/*
+ * regtry - try match of "prog" with at regline["col"].
+ * Returns 0 for failure, number of lines contained in the match otherwise.
+ */
+    static long
+regtry(prog, col)
+    regprog_T	*prog;
+    colnr_T	col;
+{
+    reginput = regline + col;
+    need_clear_subexpr = TRUE;
+#ifdef FEAT_SYN_HL
+    /* Clear the external match subpointers if necessary. */
+    if (prog->reghasz == REX_SET)
+	need_clear_zsubexpr = TRUE;
+#endif
+
+    if (regmatch(prog->program + 1) == 0)
+	return 0;
+
+    cleanup_subexpr();
+    if (REG_MULTI)
+    {
+	if (reg_startpos[0].lnum < 0)
+	{
+	    reg_startpos[0].lnum = 0;
+	    reg_startpos[0].col = col;
+	}
+	if (reg_endpos[0].lnum < 0)
+	{
+	    reg_endpos[0].lnum = reglnum;
+	    reg_endpos[0].col = (int)(reginput - regline);
+	}
+	else
+	    /* Use line number of "\ze". */
+	    reglnum = reg_endpos[0].lnum;
+    }
+    else
+    {
+	if (reg_startp[0] == NULL)
+	    reg_startp[0] = regline + col;
+	if (reg_endp[0] == NULL)
+	    reg_endp[0] = reginput;
+    }
+#ifdef FEAT_SYN_HL
+    /* Package any found \z(...\) matches for export. Default is none. */
+    unref_extmatch(re_extmatch_out);
+    re_extmatch_out = NULL;
+
+    if (prog->reghasz == REX_SET)
+    {
+	int		i;
+
+	cleanup_zsubexpr();
+	re_extmatch_out = make_extmatch();
+	for (i = 0; i < NSUBEXP; i++)
+	{
+	    if (REG_MULTI)
+	    {
+		/* Only accept single line matches. */
+		if (reg_startzpos[i].lnum >= 0
+			&& reg_endzpos[i].lnum == reg_startzpos[i].lnum)
+		    re_extmatch_out->matches[i] =
+			vim_strnsave(reg_getline(reg_startzpos[i].lnum)
+						       + reg_startzpos[i].col,
+				   reg_endzpos[i].col - reg_startzpos[i].col);
+	    }
+	    else
+	    {
+		if (reg_startzp[i] != NULL && reg_endzp[i] != NULL)
+		    re_extmatch_out->matches[i] =
+			    vim_strnsave(reg_startzp[i],
+					(int)(reg_endzp[i] - reg_startzp[i]));
+	    }
+	}
+    }
+#endif
+    return 1 + reglnum;
+}
+
+#ifdef FEAT_MBYTE
+static int reg_prev_class __ARGS((void));
+
+/*
+ * Get class of previous character.
+ */
+    static int
+reg_prev_class()
+{
+    if (reginput > regline)
+	return mb_get_class(reginput - 1
+				     - (*mb_head_off)(regline, reginput - 1));
+    return -1;
+}
+
+#endif
+#define ADVANCE_REGINPUT() mb_ptr_adv(reginput)
+
+/*
+ * The arguments from BRACE_LIMITS are stored here.  They are actually local
+ * to regmatch(), but they are here to reduce the amount of stack space used
+ * (it can be called recursively many times).
+ */
+static long	bl_minval;
+static long	bl_maxval;
+
+/*
+ * regmatch - main matching routine
+ *
+ * Conceptually the strategy is simple: Check to see whether the current node
+ * matches, push an item onto the regstack and loop to see whether the rest
+ * matches, and then act accordingly.  In practice we make some effort to
+ * avoid using the regstack, in particular by going through "ordinary" nodes
+ * (that don't need to know whether the rest of the match failed) by a nested
+ * loop.
+ *
+ * Returns TRUE when there is a match.  Leaves reginput and reglnum just after
+ * the last matched character.
+ * Returns FALSE when there is no match.  Leaves reginput and reglnum in an
+ * undefined state!
+ */
+    static int
+regmatch(scan)
+    char_u	*scan;		/* Current node. */
+{
+  char_u	*next;		/* Next node. */
+  int		op;
+  int		c;
+  regitem_T	*rp;
+  int		no;
+  int		status;		/* one of the RA_ values: */
+#define RA_FAIL		1	/* something failed, abort */
+#define RA_CONT		2	/* continue in inner loop */
+#define RA_BREAK	3	/* break inner loop */
+#define RA_MATCH	4	/* successful match */
+#define RA_NOMATCH	5	/* didn't match */
+
+  /* Init the regstack and backpos table empty.  They are initialized and
+   * freed in vim_regexec_both() to reduce malloc()/free() calls. */
+  regstack.ga_len = 0;
+  backpos.ga_len = 0;
+
+  /*
+   * Repeat until "regstack" is empty.
+   */
+  for (;;)
+  {
+    /* Some patterns my cause a long time to match, even though they are not
+     * illegal.  E.g., "\([a-z]\+\)\+Q".  Allow breaking them with CTRL-C. */
+    fast_breakcheck();
+
+#ifdef DEBUG
+    if (scan != NULL && regnarrate)
+    {
+	mch_errmsg(regprop(scan));
+	mch_errmsg("(\n");
+    }
+#endif
+
+    /*
+     * Repeat for items that can be matched sequentially, without using the
+     * regstack.
+     */
+    for (;;)
+    {
+	if (got_int || scan == NULL)
+	{
+	    status = RA_FAIL;
+	    break;
+	}
+	status = RA_CONT;
+
+#ifdef DEBUG
+	if (regnarrate)
+	{
+	    mch_errmsg(regprop(scan));
+	    mch_errmsg("...\n");
+# ifdef FEAT_SYN_HL
+	    if (re_extmatch_in != NULL)
+	    {
+		int i;
+
+		mch_errmsg(_("External submatches:\n"));
+		for (i = 0; i < NSUBEXP; i++)
+		{
+		    mch_errmsg("    \"");
+		    if (re_extmatch_in->matches[i] != NULL)
+			mch_errmsg(re_extmatch_in->matches[i]);
+		    mch_errmsg("\"\n");
+		}
+	    }
+# endif
+	}
+#endif
+	next = regnext(scan);
+
+	op = OP(scan);
+	/* Check for character class with NL added. */
+	if (!reg_line_lbr && WITH_NL(op) && REG_MULTI
+				&& *reginput == NUL && reglnum <= reg_maxline)
+	{
+	    reg_nextline();
+	}
+	else if (reg_line_lbr && WITH_NL(op) && *reginput == '\n')
+	{
+	    ADVANCE_REGINPUT();
+	}
+	else
+	{
+	  if (WITH_NL(op))
+	      op -= ADD_NL;
+#ifdef FEAT_MBYTE
+	  if (has_mbyte)
+	      c = (*mb_ptr2char)(reginput);
+	  else
+#endif
+	      c = *reginput;
+	  switch (op)
+	  {
+	  case BOL:
+	    if (reginput != regline)
+		status = RA_NOMATCH;
+	    break;
+
+	  case EOL:
+	    if (c != NUL)
+		status = RA_NOMATCH;
+	    break;
+
+	  case RE_BOF:
+	    /* Passing -1 to the getline() function provided for the search
+	     * should always return NULL if the current line is the first
+	     * line of the file. */
+	    if (reglnum != 0 || reginput != regline
+			|| (REG_MULTI && reg_getline((linenr_T)-1) != NULL))
+		status = RA_NOMATCH;
+	    break;
+
+	  case RE_EOF:
+	    if (reglnum != reg_maxline || c != NUL)
+		status = RA_NOMATCH;
+	    break;
+
+	  case CURSOR:
+	    /* Check if the buffer is in a window and compare the
+	     * reg_win->w_cursor position to the match position. */
+	    if (reg_win == NULL
+		    || (reglnum + reg_firstlnum != reg_win->w_cursor.lnum)
+		    || ((colnr_T)(reginput - regline) != reg_win->w_cursor.col))
+		status = RA_NOMATCH;
+	    break;
+
+	  case RE_MARK:
+	    /* Compare the mark position to the match position.  NOTE: Always
+	     * uses the current buffer. */
+	    {
+		int	mark = OPERAND(scan)[0];
+		int	cmp = OPERAND(scan)[1];
+		pos_T	*pos;
+
+		pos = getmark(mark, FALSE);
+		if (pos == NULL		     /* mark doesn't exist */
+			|| pos->lnum <= 0    /* mark isn't set (in curbuf) */
+			|| (pos->lnum == reglnum + reg_firstlnum
+				? (pos->col == (colnr_T)(reginput - regline)
+				    ? (cmp == '<' || cmp == '>')
+				    : (pos->col < (colnr_T)(reginput - regline)
+					? cmp != '>'
+					: cmp != '<'))
+				: (pos->lnum < reglnum + reg_firstlnum
+				    ? cmp != '>'
+				    : cmp != '<')))
+		    status = RA_NOMATCH;
+	    }
+	    break;
+
+	  case RE_VISUAL:
+#ifdef FEAT_VISUAL
+	    /* Check if the buffer is the current buffer. and whether the
+	     * position is inside the Visual area. */
+	    if (reg_buf != curbuf || VIsual.lnum == 0)
+		status = RA_NOMATCH;
+	    else
+	    {
+		pos_T	    top, bot;
+		linenr_T    lnum;
+		colnr_T	    col;
+		win_T	    *wp = reg_win == NULL ? curwin : reg_win;
+		int	    mode;
+
+		if (VIsual_active)
+		{
+		    if (lt(VIsual, wp->w_cursor))
+		    {
+			top = VIsual;
+			bot = wp->w_cursor;
+		    }
+		    else
+		    {
+			top = wp->w_cursor;
+			bot = VIsual;
+		    }
+		    mode = VIsual_mode;
+		}
+		else
+		{
+		    if (lt(curbuf->b_visual.vi_start, curbuf->b_visual.vi_end))
+		    {
+			top = curbuf->b_visual.vi_start;
+			bot = curbuf->b_visual.vi_end;
+		    }
+		    else
+		    {
+			top = curbuf->b_visual.vi_end;
+			bot = curbuf->b_visual.vi_start;
+		    }
+		    mode = curbuf->b_visual.vi_mode;
+		}
+		lnum = reglnum + reg_firstlnum;
+		col = (colnr_T)(reginput - regline);
+		if (lnum < top.lnum || lnum > bot.lnum)
+		    status = RA_NOMATCH;
+		else if (mode == 'v')
+		{
+		    if ((lnum == top.lnum && col < top.col)
+			    || (lnum == bot.lnum
+					 && col >= bot.col + (*p_sel != 'e')))
+			status = RA_NOMATCH;
+		}
+		else if (mode == Ctrl_V)
+		{
+		    colnr_T	    start, end;
+		    colnr_T	    start2, end2;
+		    colnr_T	    cols;
+
+		    getvvcol(wp, &top, &start, NULL, &end);
+		    getvvcol(wp, &bot, &start2, NULL, &end2);
+		    if (start2 < start)
+			start = start2;
+		    if (end2 > end)
+			end = end2;
+		    if (top.col == MAXCOL || bot.col == MAXCOL)
+			end = MAXCOL;
+		    cols = win_linetabsize(wp,
+				      regline, (colnr_T)(reginput - regline));
+		    if (cols < start || cols > end - (*p_sel == 'e'))
+			status = RA_NOMATCH;
+		}
+	    }
+#else
+	    status = RA_NOMATCH;
+#endif
+	    break;
+
+	  case RE_LNUM:
+	    if (!REG_MULTI || !re_num_cmp((long_u)(reglnum + reg_firstlnum),
+									scan))
+		status = RA_NOMATCH;
+	    break;
+
+	  case RE_COL:
+	    if (!re_num_cmp((long_u)(reginput - regline) + 1, scan))
+		status = RA_NOMATCH;
+	    break;
+
+	  case RE_VCOL:
+	    if (!re_num_cmp((long_u)win_linetabsize(
+			    reg_win == NULL ? curwin : reg_win,
+			    regline, (colnr_T)(reginput - regline)) + 1, scan))
+		status = RA_NOMATCH;
+	    break;
+
+	  case BOW:	/* \<word; reginput points to w */
+	    if (c == NUL)	/* Can't match at end of line */
+		status = RA_NOMATCH;
+#ifdef FEAT_MBYTE
+	    else if (has_mbyte)
+	    {
+		int this_class;
+
+		/* Get class of current and previous char (if it exists). */
+		this_class = mb_get_class(reginput);
+		if (this_class <= 1)
+		    status = RA_NOMATCH;  /* not on a word at all */
+		else if (reg_prev_class() == this_class)
+		    status = RA_NOMATCH;  /* previous char is in same word */
+	    }
+#endif
+	    else
+	    {
+		if (!vim_iswordc(c)
+			|| (reginput > regline && vim_iswordc(reginput[-1])))
+		    status = RA_NOMATCH;
+	    }
+	    break;
+
+	  case EOW:	/* word\>; reginput points after d */
+	    if (reginput == regline)    /* Can't match at start of line */
+		status = RA_NOMATCH;
+#ifdef FEAT_MBYTE
+	    else if (has_mbyte)
+	    {
+		int this_class, prev_class;
+
+		/* Get class of current and previous char (if it exists). */
+		this_class = mb_get_class(reginput);
+		prev_class = reg_prev_class();
+		if (this_class == prev_class
+			|| prev_class == 0 || prev_class == 1)
+		    status = RA_NOMATCH;
+	    }
+#endif
+	    else
+	    {
+		if (!vim_iswordc(reginput[-1])
+			|| (reginput[0] != NUL && vim_iswordc(c)))
+		    status = RA_NOMATCH;
+	    }
+	    break; /* Matched with EOW */
+
+	  case ANY:
+	    if (c == NUL)
+		status = RA_NOMATCH;
+	    else
+		ADVANCE_REGINPUT();
+	    break;
+
+	  case IDENT:
+	    if (!vim_isIDc(c))
+		status = RA_NOMATCH;
+	    else
+		ADVANCE_REGINPUT();
+	    break;
+
+	  case SIDENT:
+	    if (VIM_ISDIGIT(*reginput) || !vim_isIDc(c))
+		status = RA_NOMATCH;
+	    else
+		ADVANCE_REGINPUT();
+	    break;
+
+	  case KWORD:
+	    if (!vim_iswordp(reginput))
+		status = RA_NOMATCH;
+	    else
+		ADVANCE_REGINPUT();
+	    break;
+
+	  case SKWORD:
+	    if (VIM_ISDIGIT(*reginput) || !vim_iswordp(reginput))
+		status = RA_NOMATCH;
+	    else
+		ADVANCE_REGINPUT();
+	    break;
+
+	  case FNAME:
+	    if (!vim_isfilec(c))
+		status = RA_NOMATCH;
+	    else
+		ADVANCE_REGINPUT();
+	    break;
+
+	  case SFNAME:
+	    if (VIM_ISDIGIT(*reginput) || !vim_isfilec(c))
+		status = RA_NOMATCH;
+	    else
+		ADVANCE_REGINPUT();
+	    break;
+
+	  case PRINT:
+	    if (ptr2cells(reginput) != 1)
+		status = RA_NOMATCH;
+	    else
+		ADVANCE_REGINPUT();
+	    break;
+
+	  case SPRINT:
+	    if (VIM_ISDIGIT(*reginput) || ptr2cells(reginput) != 1)
+		status = RA_NOMATCH;
+	    else
+		ADVANCE_REGINPUT();
+	    break;
+
+	  case WHITE:
+	    if (!vim_iswhite(c))
+		status = RA_NOMATCH;
+	    else
+		ADVANCE_REGINPUT();
+	    break;
+
+	  case NWHITE:
+	    if (c == NUL || vim_iswhite(c))
+		status = RA_NOMATCH;
+	    else
+		ADVANCE_REGINPUT();
+	    break;
+
+	  case DIGIT:
+	    if (!ri_digit(c))
+		status = RA_NOMATCH;
+	    else
+		ADVANCE_REGINPUT();
+	    break;
+
+	  case NDIGIT:
+	    if (c == NUL || ri_digit(c))
+		status = RA_NOMATCH;
+	    else
+		ADVANCE_REGINPUT();
+	    break;
+
+	  case HEX:
+	    if (!ri_hex(c))
+		status = RA_NOMATCH;
+	    else
+		ADVANCE_REGINPUT();
+	    break;
+
+	  case NHEX:
+	    if (c == NUL || ri_hex(c))
+		status = RA_NOMATCH;
+	    else
+		ADVANCE_REGINPUT();
+	    break;
+
+	  case OCTAL:
+	    if (!ri_octal(c))
+		status = RA_NOMATCH;
+	    else
+		ADVANCE_REGINPUT();
+	    break;
+
+	  case NOCTAL:
+	    if (c == NUL || ri_octal(c))
+		status = RA_NOMATCH;
+	    else
+		ADVANCE_REGINPUT();
+	    break;
+
+	  case WORD:
+	    if (!ri_word(c))
+		status = RA_NOMATCH;
+	    else
+		ADVANCE_REGINPUT();
+	    break;
+
+	  case NWORD:
+	    if (c == NUL || ri_word(c))
+		status = RA_NOMATCH;
+	    else
+		ADVANCE_REGINPUT();
+	    break;
+
+	  case HEAD:
+	    if (!ri_head(c))
+		status = RA_NOMATCH;
+	    else
+		ADVANCE_REGINPUT();
+	    break;
+
+	  case NHEAD:
+	    if (c == NUL || ri_head(c))
+		status = RA_NOMATCH;
+	    else
+		ADVANCE_REGINPUT();
+	    break;
+
+	  case ALPHA:
+	    if (!ri_alpha(c))
+		status = RA_NOMATCH;
+	    else
+		ADVANCE_REGINPUT();
+	    break;
+
+	  case NALPHA:
+	    if (c == NUL || ri_alpha(c))
+		status = RA_NOMATCH;
+	    else
+		ADVANCE_REGINPUT();
+	    break;
+
+	  case LOWER:
+	    if (!ri_lower(c))
+		status = RA_NOMATCH;
+	    else
+		ADVANCE_REGINPUT();
+	    break;
+
+	  case NLOWER:
+	    if (c == NUL || ri_lower(c))
+		status = RA_NOMATCH;
+	    else
+		ADVANCE_REGINPUT();
+	    break;
+
+	  case UPPER:
+	    if (!ri_upper(c))
+		status = RA_NOMATCH;
+	    else
+		ADVANCE_REGINPUT();
+	    break;
+
+	  case NUPPER:
+	    if (c == NUL || ri_upper(c))
+		status = RA_NOMATCH;
+	    else
+		ADVANCE_REGINPUT();
+	    break;
+
+	  case EXACTLY:
+	    {
+		int	len;
+		char_u	*opnd;
+
+		opnd = OPERAND(scan);
+		/* Inline the first byte, for speed. */
+		if (*opnd != *reginput
+			&& (!ireg_ic || (
+#ifdef FEAT_MBYTE
+			    !enc_utf8 &&
+#endif
+			    TOLOWER_LOC(*opnd) != TOLOWER_LOC(*reginput))))
+		    status = RA_NOMATCH;
+		else if (*opnd == NUL)
+		{
+		    /* match empty string always works; happens when "~" is
+		     * empty. */
+		}
+		else if (opnd[1] == NUL
+#ifdef FEAT_MBYTE
+			    && !(enc_utf8 && ireg_ic)
+#endif
+			)
+		    ++reginput;		/* matched a single char */
+		else
+		{
+		    len = (int)STRLEN(opnd);
+		    /* Need to match first byte again for multi-byte. */
+		    if (cstrncmp(opnd, reginput, &len) != 0)
+			status = RA_NOMATCH;
+#ifdef FEAT_MBYTE
+		    /* Check for following composing character. */
+		    else if (enc_utf8
+			       && UTF_COMPOSINGLIKE(reginput, reginput + len))
+		    {
+			/* raaron: This code makes a composing character get
+			 * ignored, which is the correct behavior (sometimes)
+			 * for voweled Hebrew texts. */
+			if (!ireg_icombine)
+			    status = RA_NOMATCH;
+		    }
+#endif
+		    else
+			reginput += len;
+		}
+	    }
+	    break;
+
+	  case ANYOF:
+	  case ANYBUT:
+	    if (c == NUL)
+		status = RA_NOMATCH;
+	    else if ((cstrchr(OPERAND(scan), c) == NULL) == (op == ANYOF))
+		status = RA_NOMATCH;
+	    else
+		ADVANCE_REGINPUT();
+	    break;
+
+#ifdef FEAT_MBYTE
+	  case MULTIBYTECODE:
+	    if (has_mbyte)
+	    {
+		int	i, len;
+		char_u	*opnd;
+		int	opndc = 0, inpc;
+
+		opnd = OPERAND(scan);
+		/* Safety check (just in case 'encoding' was changed since
+		 * compiling the program). */
+		if ((len = (*mb_ptr2len)(opnd)) < 2)
+		{
+		    status = RA_NOMATCH;
+		    break;
+		}
+		if (enc_utf8)
+		    opndc = mb_ptr2char(opnd);
+		if (enc_utf8 && utf_iscomposing(opndc))
+		{
+		    /* When only a composing char is given match at any
+		     * position where that composing char appears. */
+		    status = RA_NOMATCH;
+		    for (i = 0; reginput[i] != NUL; i += utf_char2len(inpc))
+		    {
+			inpc = mb_ptr2char(reginput + i);
+			if (!utf_iscomposing(inpc))
+			{
+			    if (i > 0)
+				break;
+			}
+			else if (opndc == inpc)
+			{
+			    /* Include all following composing chars. */
+			    len = i + mb_ptr2len(reginput + i);
+			    status = RA_MATCH;
+			    break;
+			}
+		    }
+		}
+		else
+		    for (i = 0; i < len; ++i)
+			if (opnd[i] != reginput[i])
+			{
+			    status = RA_NOMATCH;
+			    break;
+			}
+		reginput += len;
+	    }
+	    else
+		status = RA_NOMATCH;
+	    break;
+#endif
+
+	  case NOTHING:
+	    break;
+
+	  case BACK:
+	    {
+		int		i;
+		backpos_T	*bp;
+
+		/*
+		 * When we run into BACK we need to check if we don't keep
+		 * looping without matching any input.  The second and later
+		 * times a BACK is encountered it fails if the input is still
+		 * at the same position as the previous time.
+		 * The positions are stored in "backpos" and found by the
+		 * current value of "scan", the position in the RE program.
+		 */
+		bp = (backpos_T *)backpos.ga_data;
+		for (i = 0; i < backpos.ga_len; ++i)
+		    if (bp[i].bp_scan == scan)
+			break;
+		if (i == backpos.ga_len)
+		{
+		    /* First time at this BACK, make room to store the pos. */
+		    if (ga_grow(&backpos, 1) == FAIL)
+			status = RA_FAIL;
+		    else
+		    {
+			/* get "ga_data" again, it may have changed */
+			bp = (backpos_T *)backpos.ga_data;
+			bp[i].bp_scan = scan;
+			++backpos.ga_len;
+		    }
+		}
+		else if (reg_save_equal(&bp[i].bp_pos))
+		    /* Still at same position as last time, fail. */
+		    status = RA_NOMATCH;
+
+		if (status != RA_FAIL && status != RA_NOMATCH)
+		    reg_save(&bp[i].bp_pos, &backpos);
+	    }
+	    break;
+
+	  case MOPEN + 0:   /* Match start: \zs */
+	  case MOPEN + 1:   /* \( */
+	  case MOPEN + 2:
+	  case MOPEN + 3:
+	  case MOPEN + 4:
+	  case MOPEN + 5:
+	  case MOPEN + 6:
+	  case MOPEN + 7:
+	  case MOPEN + 8:
+	  case MOPEN + 9:
+	    {
+		no = op - MOPEN;
+		cleanup_subexpr();
+		rp = regstack_push(RS_MOPEN, scan);
+		if (rp == NULL)
+		    status = RA_FAIL;
+		else
+		{
+		    rp->rs_no = no;
+		    save_se(&rp->rs_un.sesave, &reg_startpos[no],
+							     &reg_startp[no]);
+		    /* We simply continue and handle the result when done. */
+		}
+	    }
+	    break;
+
+	  case NOPEN:	    /* \%( */
+	  case NCLOSE:	    /* \) after \%( */
+		if (regstack_push(RS_NOPEN, scan) == NULL)
+		    status = RA_FAIL;
+		/* We simply continue and handle the result when done. */
+		break;
+
+#ifdef FEAT_SYN_HL
+	  case ZOPEN + 1:
+	  case ZOPEN + 2:
+	  case ZOPEN + 3:
+	  case ZOPEN + 4:
+	  case ZOPEN + 5:
+	  case ZOPEN + 6:
+	  case ZOPEN + 7:
+	  case ZOPEN + 8:
+	  case ZOPEN + 9:
+	    {
+		no = op - ZOPEN;
+		cleanup_zsubexpr();
+		rp = regstack_push(RS_ZOPEN, scan);
+		if (rp == NULL)
+		    status = RA_FAIL;
+		else
+		{
+		    rp->rs_no = no;
+		    save_se(&rp->rs_un.sesave, &reg_startzpos[no],
+							     &reg_startzp[no]);
+		    /* We simply continue and handle the result when done. */
+		}
+	    }
+	    break;
+#endif
+
+	  case MCLOSE + 0:  /* Match end: \ze */
+	  case MCLOSE + 1:  /* \) */
+	  case MCLOSE + 2:
+	  case MCLOSE + 3:
+	  case MCLOSE + 4:
+	  case MCLOSE + 5:
+	  case MCLOSE + 6:
+	  case MCLOSE + 7:
+	  case MCLOSE + 8:
+	  case MCLOSE + 9:
+	    {
+		no = op - MCLOSE;
+		cleanup_subexpr();
+		rp = regstack_push(RS_MCLOSE, scan);
+		if (rp == NULL)
+		    status = RA_FAIL;
+		else
+		{
+		    rp->rs_no = no;
+		    save_se(&rp->rs_un.sesave, &reg_endpos[no], &reg_endp[no]);
+		    /* We simply continue and handle the result when done. */
+		}
+	    }
+	    break;
+
+#ifdef FEAT_SYN_HL
+	  case ZCLOSE + 1:  /* \) after \z( */
+	  case ZCLOSE + 2:
+	  case ZCLOSE + 3:
+	  case ZCLOSE + 4:
+	  case ZCLOSE + 5:
+	  case ZCLOSE + 6:
+	  case ZCLOSE + 7:
+	  case ZCLOSE + 8:
+	  case ZCLOSE + 9:
+	    {
+		no = op - ZCLOSE;
+		cleanup_zsubexpr();
+		rp = regstack_push(RS_ZCLOSE, scan);
+		if (rp == NULL)
+		    status = RA_FAIL;
+		else
+		{
+		    rp->rs_no = no;
+		    save_se(&rp->rs_un.sesave, &reg_endzpos[no],
+							      &reg_endzp[no]);
+		    /* We simply continue and handle the result when done. */
+		}
+	    }
+	    break;
+#endif
+
+	  case BACKREF + 1:
+	  case BACKREF + 2:
+	  case BACKREF + 3:
+	  case BACKREF + 4:
+	  case BACKREF + 5:
+	  case BACKREF + 6:
+	  case BACKREF + 7:
+	  case BACKREF + 8:
+	  case BACKREF + 9:
+	    {
+		int		len;
+		linenr_T	clnum;
+		colnr_T		ccol;
+		char_u		*p;
+
+		no = op - BACKREF;
+		cleanup_subexpr();
+		if (!REG_MULTI)		/* Single-line regexp */
+		{
+		    if (reg_endp[no] == NULL)
+		    {
+			/* Backref was not set: Match an empty string. */
+			len = 0;
+		    }
+		    else
+		    {
+			/* Compare current input with back-ref in the same
+			 * line. */
+			len = (int)(reg_endp[no] - reg_startp[no]);
+			if (cstrncmp(reg_startp[no], reginput, &len) != 0)
+			    status = RA_NOMATCH;
+		    }
+		}
+		else				/* Multi-line regexp */
+		{
+		    if (reg_endpos[no].lnum < 0)
+		    {
+			/* Backref was not set: Match an empty string. */
+			len = 0;
+		    }
+		    else
+		    {
+			if (reg_startpos[no].lnum == reglnum
+				&& reg_endpos[no].lnum == reglnum)
+			{
+			    /* Compare back-ref within the current line. */
+			    len = reg_endpos[no].col - reg_startpos[no].col;
+			    if (cstrncmp(regline + reg_startpos[no].col,
+							  reginput, &len) != 0)
+				status = RA_NOMATCH;
+			}
+			else
+			{
+			    /* Messy situation: Need to compare between two
+			     * lines. */
+			    ccol = reg_startpos[no].col;
+			    clnum = reg_startpos[no].lnum;
+			    for (;;)
+			    {
+				/* Since getting one line may invalidate
+				 * the other, need to make copy.  Slow! */
+				if (regline != reg_tofree)
+				{
+				    len = (int)STRLEN(regline);
+				    if (reg_tofree == NULL
+						 || len >= (int)reg_tofreelen)
+				    {
+					len += 50;	/* get some extra */
+					vim_free(reg_tofree);
+					reg_tofree = alloc(len);
+					if (reg_tofree == NULL)
+					{
+					    status = RA_FAIL; /* outof memory!*/
+					    break;
+					}
+					reg_tofreelen = len;
+				    }
+				    STRCPY(reg_tofree, regline);
+				    reginput = reg_tofree
+						       + (reginput - regline);
+				    regline = reg_tofree;
+				}
+
+				/* Get the line to compare with. */
+				p = reg_getline(clnum);
+				if (clnum == reg_endpos[no].lnum)
+				    len = reg_endpos[no].col - ccol;
+				else
+				    len = (int)STRLEN(p + ccol);
+
+				if (cstrncmp(p + ccol, reginput, &len) != 0)
+				{
+				    status = RA_NOMATCH;  /* doesn't match */
+				    break;
+				}
+				if (clnum == reg_endpos[no].lnum)
+				    break;		/* match and at end! */
+				if (reglnum >= reg_maxline)
+				{
+				    status = RA_NOMATCH;  /* text too short */
+				    break;
+				}
+
+				/* Advance to next line. */
+				reg_nextline();
+				++clnum;
+				ccol = 0;
+				if (got_int)
+				{
+				    status = RA_FAIL;
+				    break;
+				}
+			    }
+
+			    /* found a match!  Note that regline may now point
+			     * to a copy of the line, that should not matter. */
+			}
+		    }
+		}
+
+		/* Matched the backref, skip over it. */
+		reginput += len;
+	    }
+	    break;
+
+#ifdef FEAT_SYN_HL
+	  case ZREF + 1:
+	  case ZREF + 2:
+	  case ZREF + 3:
+	  case ZREF + 4:
+	  case ZREF + 5:
+	  case ZREF + 6:
+	  case ZREF + 7:
+	  case ZREF + 8:
+	  case ZREF + 9:
+	    {
+		int	len;
+
+		cleanup_zsubexpr();
+		no = op - ZREF;
+		if (re_extmatch_in != NULL
+			&& re_extmatch_in->matches[no] != NULL)
+		{
+		    len = (int)STRLEN(re_extmatch_in->matches[no]);
+		    if (cstrncmp(re_extmatch_in->matches[no],
+							  reginput, &len) != 0)
+			status = RA_NOMATCH;
+		    else
+			reginput += len;
+		}
+		else
+		{
+		    /* Backref was not set: Match an empty string. */
+		}
+	    }
+	    break;
+#endif
+
+	  case BRANCH:
+	    {
+		if (OP(next) != BRANCH) /* No choice. */
+		    next = OPERAND(scan);	/* Avoid recursion. */
+		else
+		{
+		    rp = regstack_push(RS_BRANCH, scan);
+		    if (rp == NULL)
+			status = RA_FAIL;
+		    else
+			status = RA_BREAK;	/* rest is below */
+		}
+	    }
+	    break;
+
+	  case BRACE_LIMITS:
+	    {
+		if (OP(next) == BRACE_SIMPLE)
+		{
+		    bl_minval = OPERAND_MIN(scan);
+		    bl_maxval = OPERAND_MAX(scan);
+		}
+		else if (OP(next) >= BRACE_COMPLEX
+			&& OP(next) < BRACE_COMPLEX + 10)
+		{
+		    no = OP(next) - BRACE_COMPLEX;
+		    brace_min[no] = OPERAND_MIN(scan);
+		    brace_max[no] = OPERAND_MAX(scan);
+		    brace_count[no] = 0;
+		}
+		else
+		{
+		    EMSG(_(e_internal));	    /* Shouldn't happen */
+		    status = RA_FAIL;
+		}
+	    }
+	    break;
+
+	  case BRACE_COMPLEX + 0:
+	  case BRACE_COMPLEX + 1:
+	  case BRACE_COMPLEX + 2:
+	  case BRACE_COMPLEX + 3:
+	  case BRACE_COMPLEX + 4:
+	  case BRACE_COMPLEX + 5:
+	  case BRACE_COMPLEX + 6:
+	  case BRACE_COMPLEX + 7:
+	  case BRACE_COMPLEX + 8:
+	  case BRACE_COMPLEX + 9:
+	    {
+		no = op - BRACE_COMPLEX;
+		++brace_count[no];
+
+		/* If not matched enough times yet, try one more */
+		if (brace_count[no] <= (brace_min[no] <= brace_max[no]
+					     ? brace_min[no] : brace_max[no]))
+		{
+		    rp = regstack_push(RS_BRCPLX_MORE, scan);
+		    if (rp == NULL)
+			status = RA_FAIL;
+		    else
+		    {
+			rp->rs_no = no;
+			reg_save(&rp->rs_un.regsave, &backpos);
+			next = OPERAND(scan);
+			/* We continue and handle the result when done. */
+		    }
+		    break;
+		}
+
+		/* If matched enough times, may try matching some more */
+		if (brace_min[no] <= brace_max[no])
+		{
+		    /* Range is the normal way around, use longest match */
+		    if (brace_count[no] <= brace_max[no])
+		    {
+			rp = regstack_push(RS_BRCPLX_LONG, scan);
+			if (rp == NULL)
+			    status = RA_FAIL;
+			else
+			{
+			    rp->rs_no = no;
+			    reg_save(&rp->rs_un.regsave, &backpos);
+			    next = OPERAND(scan);
+			    /* We continue and handle the result when done. */
+			}
+		    }
+		}
+		else
+		{
+		    /* Range is backwards, use shortest match first */
+		    if (brace_count[no] <= brace_min[no])
+		    {
+			rp = regstack_push(RS_BRCPLX_SHORT, scan);
+			if (rp == NULL)
+			    status = RA_FAIL;
+			else
+			{
+			    reg_save(&rp->rs_un.regsave, &backpos);
+			    /* We continue and handle the result when done. */
+			}
+		    }
+		}
+	    }
+	    break;
+
+	  case BRACE_SIMPLE:
+	  case STAR:
+	  case PLUS:
+	    {
+		regstar_T	rst;
+
+		/*
+		 * Lookahead to avoid useless match attempts when we know
+		 * what character comes next.
+		 */
+		if (OP(next) == EXACTLY)
+		{
+		    rst.nextb = *OPERAND(next);
+		    if (ireg_ic)
+		    {
+			if (isupper(rst.nextb))
+			    rst.nextb_ic = TOLOWER_LOC(rst.nextb);
+			else
+			    rst.nextb_ic = TOUPPER_LOC(rst.nextb);
+		    }
+		    else
+			rst.nextb_ic = rst.nextb;
+		}
+		else
+		{
+		    rst.nextb = NUL;
+		    rst.nextb_ic = NUL;
+		}
+		if (op != BRACE_SIMPLE)
+		{
+		    rst.minval = (op == STAR) ? 0 : 1;
+		    rst.maxval = MAX_LIMIT;
+		}
+		else
+		{
+		    rst.minval = bl_minval;
+		    rst.maxval = bl_maxval;
+		}
+
+		/*
+		 * When maxval > minval, try matching as much as possible, up
+		 * to maxval.  When maxval < minval, try matching at least the
+		 * minimal number (since the range is backwards, that's also
+		 * maxval!).
+		 */
+		rst.count = regrepeat(OPERAND(scan), rst.maxval);
+		if (got_int)
+		{
+		    status = RA_FAIL;
+		    break;
+		}
+		if (rst.minval <= rst.maxval
+			  ? rst.count >= rst.minval : rst.count >= rst.maxval)
+		{
+		    /* It could match.  Prepare for trying to match what
+		     * follows.  The code is below.  Parameters are stored in
+		     * a regstar_T on the regstack. */
+		    if ((long)((unsigned)regstack.ga_len >> 10) >= p_mmp)
+		    {
+			EMSG(_(e_maxmempat));
+			status = RA_FAIL;
+		    }
+		    else if (ga_grow(&regstack, sizeof(regstar_T)) == FAIL)
+			status = RA_FAIL;
+		    else
+		    {
+			regstack.ga_len += sizeof(regstar_T);
+			rp = regstack_push(rst.minval <= rst.maxval
+					? RS_STAR_LONG : RS_STAR_SHORT, scan);
+			if (rp == NULL)
+			    status = RA_FAIL;
+			else
+			{
+			    *(((regstar_T *)rp) - 1) = rst;
+			    status = RA_BREAK;	    /* skip the restore bits */
+			}
+		    }
+		}
+		else
+		    status = RA_NOMATCH;
+
+	    }
+	    break;
+
+	  case NOMATCH:
+	  case MATCH:
+	  case SUBPAT:
+	    rp = regstack_push(RS_NOMATCH, scan);
+	    if (rp == NULL)
+		status = RA_FAIL;
+	    else
+	    {
+		rp->rs_no = op;
+		reg_save(&rp->rs_un.regsave, &backpos);
+		next = OPERAND(scan);
+		/* We continue and handle the result when done. */
+	    }
+	    break;
+
+	  case BEHIND:
+	  case NOBEHIND:
+	    /* Need a bit of room to store extra positions. */
+	    if ((long)((unsigned)regstack.ga_len >> 10) >= p_mmp)
+	    {
+		EMSG(_(e_maxmempat));
+		status = RA_FAIL;
+	    }
+	    else if (ga_grow(&regstack, sizeof(regbehind_T)) == FAIL)
+		status = RA_FAIL;
+	    else
+	    {
+		regstack.ga_len += sizeof(regbehind_T);
+		rp = regstack_push(RS_BEHIND1, scan);
+		if (rp == NULL)
+		    status = RA_FAIL;
+		else
+		{
+		    rp->rs_no = op;
+		    reg_save(&rp->rs_un.regsave, &backpos);
+		    /* First try if what follows matches.  If it does then we
+		     * check the behind match by looping. */
+		}
+	    }
+	    break;
+
+	  case BHPOS:
+	    if (REG_MULTI)
+	    {
+		if (behind_pos.rs_u.pos.col != (colnr_T)(reginput - regline)
+			|| behind_pos.rs_u.pos.lnum != reglnum)
+		    status = RA_NOMATCH;
+	    }
+	    else if (behind_pos.rs_u.ptr != reginput)
+		status = RA_NOMATCH;
+	    break;
+
+	  case NEWL:
+	    if ((c != NUL || !REG_MULTI || reglnum > reg_maxline
+			     || reg_line_lbr) && (c != '\n' || !reg_line_lbr))
+		status = RA_NOMATCH;
+	    else if (reg_line_lbr)
+		ADVANCE_REGINPUT();
+	    else
+		reg_nextline();
+	    break;
+
+	  case END:
+	    status = RA_MATCH;	/* Success! */
+	    break;
+
+	  default:
+	    EMSG(_(e_re_corr));
+#ifdef DEBUG
+	    printf("Illegal op code %d\n", op);
+#endif
+	    status = RA_FAIL;
+	    break;
+	  }
+	}
+
+	/* If we can't continue sequentially, break the inner loop. */
+	if (status != RA_CONT)
+	    break;
+
+	/* Continue in inner loop, advance to next item. */
+	scan = next;
+
+    } /* end of inner loop */
+
+    /*
+     * If there is something on the regstack execute the code for the state.
+     * If the state is popped then loop and use the older state.
+     */
+    while (regstack.ga_len > 0 && status != RA_FAIL)
+    {
+	rp = (regitem_T *)((char *)regstack.ga_data + regstack.ga_len) - 1;
+	switch (rp->rs_state)
+	{
+	  case RS_NOPEN:
+	    /* Result is passed on as-is, simply pop the state. */
+	    regstack_pop(&scan);
+	    break;
+
+	  case RS_MOPEN:
+	    /* Pop the state.  Restore pointers when there is no match. */
+	    if (status == RA_NOMATCH)
+		restore_se(&rp->rs_un.sesave, &reg_startpos[rp->rs_no],
+						  &reg_startp[rp->rs_no]);
+	    regstack_pop(&scan);
+	    break;
+
+#ifdef FEAT_SYN_HL
+	  case RS_ZOPEN:
+	    /* Pop the state.  Restore pointers when there is no match. */
+	    if (status == RA_NOMATCH)
+		restore_se(&rp->rs_un.sesave, &reg_startzpos[rp->rs_no],
+						 &reg_startzp[rp->rs_no]);
+	    regstack_pop(&scan);
+	    break;
+#endif
+
+	  case RS_MCLOSE:
+	    /* Pop the state.  Restore pointers when there is no match. */
+	    if (status == RA_NOMATCH)
+		restore_se(&rp->rs_un.sesave, &reg_endpos[rp->rs_no],
+						    &reg_endp[rp->rs_no]);
+	    regstack_pop(&scan);
+	    break;
+
+#ifdef FEAT_SYN_HL
+	  case RS_ZCLOSE:
+	    /* Pop the state.  Restore pointers when there is no match. */
+	    if (status == RA_NOMATCH)
+		restore_se(&rp->rs_un.sesave, &reg_endzpos[rp->rs_no],
+						   &reg_endzp[rp->rs_no]);
+	    regstack_pop(&scan);
+	    break;
+#endif
+
+	  case RS_BRANCH:
+	    if (status == RA_MATCH)
+		/* this branch matched, use it */
+		regstack_pop(&scan);
+	    else
+	    {
+		if (status != RA_BREAK)
+		{
+		    /* After a non-matching branch: try next one. */
+		    reg_restore(&rp->rs_un.regsave, &backpos);
+		    scan = rp->rs_scan;
+		}
+		if (scan == NULL || OP(scan) != BRANCH)
+		{
+		    /* no more branches, didn't find a match */
+		    status = RA_NOMATCH;
+		    regstack_pop(&scan);
+		}
+		else
+		{
+		    /* Prepare to try a branch. */
+		    rp->rs_scan = regnext(scan);
+		    reg_save(&rp->rs_un.regsave, &backpos);
+		    scan = OPERAND(scan);
+		}
+	    }
+	    break;
+
+	  case RS_BRCPLX_MORE:
+	    /* Pop the state.  Restore pointers when there is no match. */
+	    if (status == RA_NOMATCH)
+	    {
+		reg_restore(&rp->rs_un.regsave, &backpos);
+		--brace_count[rp->rs_no];	/* decrement match count */
+	    }
+	    regstack_pop(&scan);
+	    break;
+
+	  case RS_BRCPLX_LONG:
+	    /* Pop the state.  Restore pointers when there is no match. */
+	    if (status == RA_NOMATCH)
+	    {
+		/* There was no match, but we did find enough matches. */
+		reg_restore(&rp->rs_un.regsave, &backpos);
+		--brace_count[rp->rs_no];
+		/* continue with the items after "\{}" */
+		status = RA_CONT;
+	    }
+	    regstack_pop(&scan);
+	    if (status == RA_CONT)
+		scan = regnext(scan);
+	    break;
+
+	  case RS_BRCPLX_SHORT:
+	    /* Pop the state.  Restore pointers when there is no match. */
+	    if (status == RA_NOMATCH)
+		/* There was no match, try to match one more item. */
+		reg_restore(&rp->rs_un.regsave, &backpos);
+	    regstack_pop(&scan);
+	    if (status == RA_NOMATCH)
+	    {
+		scan = OPERAND(scan);
+		status = RA_CONT;
+	    }
+	    break;
+
+	  case RS_NOMATCH:
+	    /* Pop the state.  If the operand matches for NOMATCH or
+	     * doesn't match for MATCH/SUBPAT, we fail.  Otherwise backup,
+	     * except for SUBPAT, and continue with the next item. */
+	    if (status == (rp->rs_no == NOMATCH ? RA_MATCH : RA_NOMATCH))
+		status = RA_NOMATCH;
+	    else
+	    {
+		status = RA_CONT;
+		if (rp->rs_no != SUBPAT)	/* zero-width */
+		    reg_restore(&rp->rs_un.regsave, &backpos);
+	    }
+	    regstack_pop(&scan);
+	    if (status == RA_CONT)
+		scan = regnext(scan);
+	    break;
+
+	  case RS_BEHIND1:
+	    if (status == RA_NOMATCH)
+	    {
+		regstack_pop(&scan);
+		regstack.ga_len -= sizeof(regbehind_T);
+	    }
+	    else
+	    {
+		/* The stuff after BEHIND/NOBEHIND matches.  Now try if
+		 * the behind part does (not) match before the current
+		 * position in the input.  This must be done at every
+		 * position in the input and checking if the match ends at
+		 * the current position. */
+
+		/* save the position after the found match for next */
+		reg_save(&(((regbehind_T *)rp) - 1)->save_after, &backpos);
+
+		/* start looking for a match with operand at the current
+		 * position.  Go back one character until we find the
+		 * result, hitting the start of the line or the previous
+		 * line (for multi-line matching).
+		 * Set behind_pos to where the match should end, BHPOS
+		 * will match it.  Save the current value. */
+		(((regbehind_T *)rp) - 1)->save_behind = behind_pos;
+		behind_pos = rp->rs_un.regsave;
+
+		rp->rs_state = RS_BEHIND2;
+
+		reg_restore(&rp->rs_un.regsave, &backpos);
+		scan = OPERAND(rp->rs_scan);
+	    }
+	    break;
+
+	  case RS_BEHIND2:
+	    /*
+	     * Looping for BEHIND / NOBEHIND match.
+	     */
+	    if (status == RA_MATCH && reg_save_equal(&behind_pos))
+	    {
+		/* found a match that ends where "next" started */
+		behind_pos = (((regbehind_T *)rp) - 1)->save_behind;
+		if (rp->rs_no == BEHIND)
+		    reg_restore(&(((regbehind_T *)rp) - 1)->save_after,
+								    &backpos);
+		else
+		    /* But we didn't want a match. */
+		    status = RA_NOMATCH;
+		regstack_pop(&scan);
+		regstack.ga_len -= sizeof(regbehind_T);
+	    }
+	    else
+	    {
+		/* No match: Go back one character.  May go to previous
+		 * line once. */
+		no = OK;
+		if (REG_MULTI)
+		{
+		    if (rp->rs_un.regsave.rs_u.pos.col == 0)
+		    {
+			if (rp->rs_un.regsave.rs_u.pos.lnum
+					< behind_pos.rs_u.pos.lnum
+				|| reg_getline(
+					--rp->rs_un.regsave.rs_u.pos.lnum)
+								  == NULL)
+			    no = FAIL;
+			else
+			{
+			    reg_restore(&rp->rs_un.regsave, &backpos);
+			    rp->rs_un.regsave.rs_u.pos.col =
+						 (colnr_T)STRLEN(regline);
+			}
+		    }
+		    else
+			--rp->rs_un.regsave.rs_u.pos.col;
+		}
+		else
+		{
+		    if (rp->rs_un.regsave.rs_u.ptr == regline)
+			no = FAIL;
+		    else
+			--rp->rs_un.regsave.rs_u.ptr;
+		}
+		if (no == OK)
+		{
+		    /* Advanced, prepare for finding match again. */
+		    reg_restore(&rp->rs_un.regsave, &backpos);
+		    scan = OPERAND(rp->rs_scan);
+		}
+		else
+		{
+		    /* Can't advance.  For NOBEHIND that's a match. */
+		    behind_pos = (((regbehind_T *)rp) - 1)->save_behind;
+		    if (rp->rs_no == NOBEHIND)
+		    {
+			reg_restore(&(((regbehind_T *)rp) - 1)->save_after,
+								    &backpos);
+			status = RA_MATCH;
+		    }
+		    else
+			status = RA_NOMATCH;
+		    regstack_pop(&scan);
+		    regstack.ga_len -= sizeof(regbehind_T);
+		}
+	    }
+	    break;
+
+	  case RS_STAR_LONG:
+	  case RS_STAR_SHORT:
+	    {
+		regstar_T	    *rst = ((regstar_T *)rp) - 1;
+
+		if (status == RA_MATCH)
+		{
+		    regstack_pop(&scan);
+		    regstack.ga_len -= sizeof(regstar_T);
+		    break;
+		}
+
+		/* Tried once already, restore input pointers. */
+		if (status != RA_BREAK)
+		    reg_restore(&rp->rs_un.regsave, &backpos);
+
+		/* Repeat until we found a position where it could match. */
+		for (;;)
+		{
+		    if (status != RA_BREAK)
+		    {
+			/* Tried first position already, advance. */
+			if (rp->rs_state == RS_STAR_LONG)
+			{
+			    /* Trying for longest match, but couldn't or
+			     * didn't match -- back up one char. */
+			    if (--rst->count < rst->minval)
+				break;
+			    if (reginput == regline)
+			    {
+				/* backup to last char of previous line */
+				--reglnum;
+				regline = reg_getline(reglnum);
+				/* Just in case regrepeat() didn't count
+				 * right. */
+				if (regline == NULL)
+				    break;
+				reginput = regline + STRLEN(regline);
+				fast_breakcheck();
+			    }
+			    else
+				mb_ptr_back(regline, reginput);
+			}
+			else
+			{
+			    /* Range is backwards, use shortest match first.
+			     * Careful: maxval and minval are exchanged!
+			     * Couldn't or didn't match: try advancing one
+			     * char. */
+			    if (rst->count == rst->minval
+				  || regrepeat(OPERAND(rp->rs_scan), 1L) == 0)
+				break;
+			    ++rst->count;
+			}
+			if (got_int)
+			    break;
+		    }
+		    else
+			status = RA_NOMATCH;
+
+		    /* If it could match, try it. */
+		    if (rst->nextb == NUL || *reginput == rst->nextb
+					     || *reginput == rst->nextb_ic)
+		    {
+			reg_save(&rp->rs_un.regsave, &backpos);
+			scan = regnext(rp->rs_scan);
+			status = RA_CONT;
+			break;
+		    }
+		}
+		if (status != RA_CONT)
+		{
+		    /* Failed. */
+		    regstack_pop(&scan);
+		    regstack.ga_len -= sizeof(regstar_T);
+		    status = RA_NOMATCH;
+		}
+	    }
+	    break;
+	}
+
+	/* If we want to continue the inner loop or didn't pop a state
+	 * continue matching loop */
+	if (status == RA_CONT || rp == (regitem_T *)
+			     ((char *)regstack.ga_data + regstack.ga_len) - 1)
+	    break;
+    }
+
+    /* May need to continue with the inner loop, starting at "scan". */
+    if (status == RA_CONT)
+	continue;
+
+    /*
+     * If the regstack is empty or something failed we are done.
+     */
+    if (regstack.ga_len == 0 || status == RA_FAIL)
+    {
+	if (scan == NULL)
+	{
+	    /*
+	     * We get here only if there's trouble -- normally "case END" is
+	     * the terminating point.
+	     */
+	    EMSG(_(e_re_corr));
+#ifdef DEBUG
+	    printf("Premature EOL\n");
+#endif
+	}
+	if (status == RA_FAIL)
+	    got_int = TRUE;
+	return (status == RA_MATCH);
+    }
+
+  } /* End of loop until the regstack is empty. */
+
+  /* NOTREACHED */
+}
+
+/*
+ * Push an item onto the regstack.
+ * Returns pointer to new item.  Returns NULL when out of memory.
+ */
+    static regitem_T *
+regstack_push(state, scan)
+    regstate_T	state;
+    char_u	*scan;
+{
+    regitem_T	*rp;
+
+    if ((long)((unsigned)regstack.ga_len >> 10) >= p_mmp)
+    {
+	EMSG(_(e_maxmempat));
+	return NULL;
+    }
+    if (ga_grow(&regstack, sizeof(regitem_T)) == FAIL)
+	return NULL;
+
+    rp = (regitem_T *)((char *)regstack.ga_data + regstack.ga_len);
+    rp->rs_state = state;
+    rp->rs_scan = scan;
+
+    regstack.ga_len += sizeof(regitem_T);
+    return rp;
+}
+
+/*
+ * Pop an item from the regstack.
+ */
+    static void
+regstack_pop(scan)
+    char_u	**scan;
+{
+    regitem_T	*rp;
+
+    rp = (regitem_T *)((char *)regstack.ga_data + regstack.ga_len) - 1;
+    *scan = rp->rs_scan;
+
+    regstack.ga_len -= sizeof(regitem_T);
+}
+
+/*
+ * regrepeat - repeatedly match something simple, return how many.
+ * Advances reginput (and reglnum) to just after the matched chars.
+ */
+    static int
+regrepeat(p, maxcount)
+    char_u	*p;
+    long	maxcount;   /* maximum number of matches allowed */
+{
+    long	count = 0;
+    char_u	*scan;
+    char_u	*opnd;
+    int		mask;
+    int		testval = 0;
+
+    scan = reginput;	    /* Make local copy of reginput for speed. */
+    opnd = OPERAND(p);
+    switch (OP(p))
+    {
+      case ANY:
+      case ANY + ADD_NL:
+	while (count < maxcount)
+	{
+	    /* Matching anything means we continue until end-of-line (or
+	     * end-of-file for ANY + ADD_NL), only limited by maxcount. */
+	    while (*scan != NUL && count < maxcount)
+	    {
+		++count;
+		mb_ptr_adv(scan);
+	    }
+	    if (!REG_MULTI || !WITH_NL(OP(p)) || reglnum > reg_maxline
+					 || reg_line_lbr || count == maxcount)
+		break;
+	    ++count;		/* count the line-break */
+	    reg_nextline();
+	    scan = reginput;
+	    if (got_int)
+		break;
+	}
+	break;
+
+      case IDENT:
+      case IDENT + ADD_NL:
+	testval = TRUE;
+	/*FALLTHROUGH*/
+      case SIDENT:
+      case SIDENT + ADD_NL:
+	while (count < maxcount)
+	{
+	    if (vim_isIDc(*scan) && (testval || !VIM_ISDIGIT(*scan)))
+	    {
+		mb_ptr_adv(scan);
+	    }
+	    else if (*scan == NUL)
+	    {
+		if (!REG_MULTI || !WITH_NL(OP(p)) || reglnum > reg_maxline
+							      || reg_line_lbr)
+		    break;
+		reg_nextline();
+		scan = reginput;
+		if (got_int)
+		    break;
+	    }
+	    else if (reg_line_lbr && *scan == '\n' && WITH_NL(OP(p)))
+		++scan;
+	    else
+		break;
+	    ++count;
+	}
+	break;
+
+      case KWORD:
+      case KWORD + ADD_NL:
+	testval = TRUE;
+	/*FALLTHROUGH*/
+      case SKWORD:
+      case SKWORD + ADD_NL:
+	while (count < maxcount)
+	{
+	    if (vim_iswordp(scan) && (testval || !VIM_ISDIGIT(*scan)))
+	    {
+		mb_ptr_adv(scan);
+	    }
+	    else if (*scan == NUL)
+	    {
+		if (!REG_MULTI || !WITH_NL(OP(p)) || reglnum > reg_maxline
+							      || reg_line_lbr)
+		    break;
+		reg_nextline();
+		scan = reginput;
+		if (got_int)
+		    break;
+	    }
+	    else if (reg_line_lbr && *scan == '\n' && WITH_NL(OP(p)))
+		++scan;
+	    else
+		break;
+	    ++count;
+	}
+	break;
+
+      case FNAME:
+      case FNAME + ADD_NL:
+	testval = TRUE;
+	/*FALLTHROUGH*/
+      case SFNAME:
+      case SFNAME + ADD_NL:
+	while (count < maxcount)
+	{
+	    if (vim_isfilec(*scan) && (testval || !VIM_ISDIGIT(*scan)))
+	    {
+		mb_ptr_adv(scan);
+	    }
+	    else if (*scan == NUL)
+	    {
+		if (!REG_MULTI || !WITH_NL(OP(p)) || reglnum > reg_maxline
+							      || reg_line_lbr)
+		    break;
+		reg_nextline();
+		scan = reginput;
+		if (got_int)
+		    break;
+	    }
+	    else if (reg_line_lbr && *scan == '\n' && WITH_NL(OP(p)))
+		++scan;
+	    else
+		break;
+	    ++count;
+	}
+	break;
+
+      case PRINT:
+      case PRINT + ADD_NL:
+	testval = TRUE;
+	/*FALLTHROUGH*/
+      case SPRINT:
+      case SPRINT + ADD_NL:
+	while (count < maxcount)
+	{
+	    if (*scan == NUL)
+	    {
+		if (!REG_MULTI || !WITH_NL(OP(p)) || reglnum > reg_maxline
+							      || reg_line_lbr)
+		    break;
+		reg_nextline();
+		scan = reginput;
+		if (got_int)
+		    break;
+	    }
+	    else if (ptr2cells(scan) == 1 && (testval || !VIM_ISDIGIT(*scan)))
+	    {
+		mb_ptr_adv(scan);
+	    }
+	    else if (reg_line_lbr && *scan == '\n' && WITH_NL(OP(p)))
+		++scan;
+	    else
+		break;
+	    ++count;
+	}
+	break;
+
+      case WHITE:
+      case WHITE + ADD_NL:
+	testval = mask = RI_WHITE;
+do_class:
+	while (count < maxcount)
+	{
+#ifdef FEAT_MBYTE
+	    int		l;
+#endif
+	    if (*scan == NUL)
+	    {
+		if (!REG_MULTI || !WITH_NL(OP(p)) || reglnum > reg_maxline
+							      || reg_line_lbr)
+		    break;
+		reg_nextline();
+		scan = reginput;
+		if (got_int)
+		    break;
+	    }
+#ifdef FEAT_MBYTE
+	    else if (has_mbyte && (l = (*mb_ptr2len)(scan)) > 1)
+	    {
+		if (testval != 0)
+		    break;
+		scan += l;
+	    }
+#endif
+	    else if ((class_tab[*scan] & mask) == testval)
+		++scan;
+	    else if (reg_line_lbr && *scan == '\n' && WITH_NL(OP(p)))
+		++scan;
+	    else
+		break;
+	    ++count;
+	}
+	break;
+
+      case NWHITE:
+      case NWHITE + ADD_NL:
+	mask = RI_WHITE;
+	goto do_class;
+      case DIGIT:
+      case DIGIT + ADD_NL:
+	testval = mask = RI_DIGIT;
+	goto do_class;
+      case NDIGIT:
+      case NDIGIT + ADD_NL:
+	mask = RI_DIGIT;
+	goto do_class;
+      case HEX:
+      case HEX + ADD_NL:
+	testval = mask = RI_HEX;
+	goto do_class;
+      case NHEX:
+      case NHEX + ADD_NL:
+	mask = RI_HEX;
+	goto do_class;
+      case OCTAL:
+      case OCTAL + ADD_NL:
+	testval = mask = RI_OCTAL;
+	goto do_class;
+      case NOCTAL:
+      case NOCTAL + ADD_NL:
+	mask = RI_OCTAL;
+	goto do_class;
+      case WORD:
+      case WORD + ADD_NL:
+	testval = mask = RI_WORD;
+	goto do_class;
+      case NWORD:
+      case NWORD + ADD_NL:
+	mask = RI_WORD;
+	goto do_class;
+      case HEAD:
+      case HEAD + ADD_NL:
+	testval = mask = RI_HEAD;
+	goto do_class;
+      case NHEAD:
+      case NHEAD + ADD_NL:
+	mask = RI_HEAD;
+	goto do_class;
+      case ALPHA:
+      case ALPHA + ADD_NL:
+	testval = mask = RI_ALPHA;
+	goto do_class;
+      case NALPHA:
+      case NALPHA + ADD_NL:
+	mask = RI_ALPHA;
+	goto do_class;
+      case LOWER:
+      case LOWER + ADD_NL:
+	testval = mask = RI_LOWER;
+	goto do_class;
+      case NLOWER:
+      case NLOWER + ADD_NL:
+	mask = RI_LOWER;
+	goto do_class;
+      case UPPER:
+      case UPPER + ADD_NL:
+	testval = mask = RI_UPPER;
+	goto do_class;
+      case NUPPER:
+      case NUPPER + ADD_NL:
+	mask = RI_UPPER;
+	goto do_class;
+
+      case EXACTLY:
+	{
+	    int	    cu, cl;
+
+	    /* This doesn't do a multi-byte character, because a MULTIBYTECODE
+	     * would have been used for it. */
+	    if (ireg_ic)
+	    {
+		cu = TOUPPER_LOC(*opnd);
+		cl = TOLOWER_LOC(*opnd);
+		while (count < maxcount && (*scan == cu || *scan == cl))
+		{
+		    count++;
+		    scan++;
+		}
+	    }
+	    else
+	    {
+		cu = *opnd;
+		while (count < maxcount && *scan == cu)
+		{
+		    count++;
+		    scan++;
+		}
+	    }
+	    break;
+	}
+
+#ifdef FEAT_MBYTE
+      case MULTIBYTECODE:
+	{
+	    int		i, len, cf = 0;
+
+	    /* Safety check (just in case 'encoding' was changed since
+	     * compiling the program). */
+	    if ((len = (*mb_ptr2len)(opnd)) > 1)
+	    {
+		if (ireg_ic && enc_utf8)
+		    cf = utf_fold(utf_ptr2char(opnd));
+		while (count < maxcount)
+		{
+		    for (i = 0; i < len; ++i)
+			if (opnd[i] != scan[i])
+			    break;
+		    if (i < len && (!ireg_ic || !enc_utf8
+					|| utf_fold(utf_ptr2char(scan)) != cf))
+			break;
+		    scan += len;
+		    ++count;
+		}
+	    }
+	}
+	break;
+#endif
+
+      case ANYOF:
+      case ANYOF + ADD_NL:
+	testval = TRUE;
+	/*FALLTHROUGH*/
+
+      case ANYBUT:
+      case ANYBUT + ADD_NL:
+	while (count < maxcount)
+	{
+#ifdef FEAT_MBYTE
+	    int len;
+#endif
+	    if (*scan == NUL)
+	    {
+		if (!REG_MULTI || !WITH_NL(OP(p)) || reglnum > reg_maxline
+							      || reg_line_lbr)
+		    break;
+		reg_nextline();
+		scan = reginput;
+		if (got_int)
+		    break;
+	    }
+	    else if (reg_line_lbr && *scan == '\n' && WITH_NL(OP(p)))
+		++scan;
+#ifdef FEAT_MBYTE
+	    else if (has_mbyte && (len = (*mb_ptr2len)(scan)) > 1)
+	    {
+		if ((cstrchr(opnd, (*mb_ptr2char)(scan)) == NULL) == testval)
+		    break;
+		scan += len;
+	    }
+#endif
+	    else
+	    {
+		if ((cstrchr(opnd, *scan) == NULL) == testval)
+		    break;
+		++scan;
+	    }
+	    ++count;
+	}
+	break;
+
+      case NEWL:
+	while (count < maxcount
+		&& ((*scan == NUL && reglnum <= reg_maxline && !reg_line_lbr
+			    && REG_MULTI) || (*scan == '\n' && reg_line_lbr)))
+	{
+	    count++;
+	    if (reg_line_lbr)
+		ADVANCE_REGINPUT();
+	    else
+		reg_nextline();
+	    scan = reginput;
+	    if (got_int)
+		break;
+	}
+	break;
+
+      default:			/* Oh dear.  Called inappropriately. */
+	EMSG(_(e_re_corr));
+#ifdef DEBUG
+	printf("Called regrepeat with op code %d\n", OP(p));
+#endif
+	break;
+    }
+
+    reginput = scan;
+
+    return (int)count;
+}
+
+/*
+ * regnext - dig the "next" pointer out of a node
+ */
+    static char_u *
+regnext(p)
+    char_u  *p;
+{
+    int	    offset;
+
+    if (p == JUST_CALC_SIZE)
+	return NULL;
+
+    offset = NEXT(p);
+    if (offset == 0)
+	return NULL;
+
+    if (OP(p) == BACK)
+	return p - offset;
+    else
+	return p + offset;
+}
+
+/*
+ * Check the regexp program for its magic number.
+ * Return TRUE if it's wrong.
+ */
+    static int
+prog_magic_wrong()
+{
+    if (UCHARAT(REG_MULTI
+		? reg_mmatch->regprog->program
+		: reg_match->regprog->program) != REGMAGIC)
+    {
+	EMSG(_(e_re_corr));
+	return TRUE;
+    }
+    return FALSE;
+}
+
+/*
+ * Cleanup the subexpressions, if this wasn't done yet.
+ * This construction is used to clear the subexpressions only when they are
+ * used (to increase speed).
+ */
+    static void
+cleanup_subexpr()
+{
+    if (need_clear_subexpr)
+    {
+	if (REG_MULTI)
+	{
+	    /* Use 0xff to set lnum to -1 */
+	    vim_memset(reg_startpos, 0xff, sizeof(lpos_T) * NSUBEXP);
+	    vim_memset(reg_endpos, 0xff, sizeof(lpos_T) * NSUBEXP);
+	}
+	else
+	{
+	    vim_memset(reg_startp, 0, sizeof(char_u *) * NSUBEXP);
+	    vim_memset(reg_endp, 0, sizeof(char_u *) * NSUBEXP);
+	}
+	need_clear_subexpr = FALSE;
+    }
+}
+
+#ifdef FEAT_SYN_HL
+    static void
+cleanup_zsubexpr()
+{
+    if (need_clear_zsubexpr)
+    {
+	if (REG_MULTI)
+	{
+	    /* Use 0xff to set lnum to -1 */
+	    vim_memset(reg_startzpos, 0xff, sizeof(lpos_T) * NSUBEXP);
+	    vim_memset(reg_endzpos, 0xff, sizeof(lpos_T) * NSUBEXP);
+	}
+	else
+	{
+	    vim_memset(reg_startzp, 0, sizeof(char_u *) * NSUBEXP);
+	    vim_memset(reg_endzp, 0, sizeof(char_u *) * NSUBEXP);
+	}
+	need_clear_zsubexpr = FALSE;
+    }
+}
+#endif
+
+/*
+ * Advance reglnum, regline and reginput to the next line.
+ */
+    static void
+reg_nextline()
+{
+    regline = reg_getline(++reglnum);
+    reginput = regline;
+    fast_breakcheck();
+}
+
+/*
+ * Save the input line and position in a regsave_T.
+ */
+    static void
+reg_save(save, gap)
+    regsave_T	*save;
+    garray_T	*gap;
+{
+    if (REG_MULTI)
+    {
+	save->rs_u.pos.col = (colnr_T)(reginput - regline);
+	save->rs_u.pos.lnum = reglnum;
+    }
+    else
+	save->rs_u.ptr = reginput;
+    save->rs_len = gap->ga_len;
+}
+
+/*
+ * Restore the input line and position from a regsave_T.
+ */
+    static void
+reg_restore(save, gap)
+    regsave_T	*save;
+    garray_T	*gap;
+{
+    if (REG_MULTI)
+    {
+	if (reglnum != save->rs_u.pos.lnum)
+	{
+	    /* only call reg_getline() when the line number changed to save
+	     * a bit of time */
+	    reglnum = save->rs_u.pos.lnum;
+	    regline = reg_getline(reglnum);
+	}
+	reginput = regline + save->rs_u.pos.col;
+    }
+    else
+	reginput = save->rs_u.ptr;
+    gap->ga_len = save->rs_len;
+}
+
+/*
+ * Return TRUE if current position is equal to saved position.
+ */
+    static int
+reg_save_equal(save)
+    regsave_T	*save;
+{
+    if (REG_MULTI)
+	return reglnum == save->rs_u.pos.lnum
+				  && reginput == regline + save->rs_u.pos.col;
+    return reginput == save->rs_u.ptr;
+}
+
+/*
+ * Tentatively set the sub-expression start to the current position (after
+ * calling regmatch() they will have changed).  Need to save the existing
+ * values for when there is no match.
+ * Use se_save() to use pointer (save_se_multi()) or position (save_se_one()),
+ * depending on REG_MULTI.
+ */
+    static void
+save_se_multi(savep, posp)
+    save_se_T	*savep;
+    lpos_T	*posp;
+{
+    savep->se_u.pos = *posp;
+    posp->lnum = reglnum;
+    posp->col = (colnr_T)(reginput - regline);
+}
+
+    static void
+save_se_one(savep, pp)
+    save_se_T	*savep;
+    char_u	**pp;
+{
+    savep->se_u.ptr = *pp;
+    *pp = reginput;
+}
+
+/*
+ * Compare a number with the operand of RE_LNUM, RE_COL or RE_VCOL.
+ */
+    static int
+re_num_cmp(val, scan)
+    long_u	val;
+    char_u	*scan;
+{
+    long_u  n = OPERAND_MIN(scan);
+
+    if (OPERAND_CMP(scan) == '>')
+	return val > n;
+    if (OPERAND_CMP(scan) == '<')
+	return val < n;
+    return val == n;
+}
+
+
+#ifdef DEBUG
+
+/*
+ * regdump - dump a regexp onto stdout in vaguely comprehensible form
+ */
+    static void
+regdump(pattern, r)
+    char_u	*pattern;
+    regprog_T	*r;
+{
+    char_u  *s;
+    int	    op = EXACTLY;	/* Arbitrary non-END op. */
+    char_u  *next;
+    char_u  *end = NULL;
+
+    printf("\r\nregcomp(%s):\r\n", pattern);
+
+    s = r->program + 1;
+    /*
+     * Loop until we find the END that isn't before a referred next (an END
+     * can also appear in a NOMATCH operand).
+     */
+    while (op != END || s <= end)
+    {
+	op = OP(s);
+	printf("%2d%s", (int)(s - r->program), regprop(s)); /* Where, what. */
+	next = regnext(s);
+	if (next == NULL)	/* Next ptr. */
+	    printf("(0)");
+	else
+	    printf("(%d)", (int)((s - r->program) + (next - s)));
+	if (end < next)
+	    end = next;
+	if (op == BRACE_LIMITS)
+	{
+	    /* Two short ints */
+	    printf(" minval %ld, maxval %ld", OPERAND_MIN(s), OPERAND_MAX(s));
+	    s += 8;
+	}
+	s += 3;
+	if (op == ANYOF || op == ANYOF + ADD_NL
+		|| op == ANYBUT || op == ANYBUT + ADD_NL
+		|| op == EXACTLY)
+	{
+	    /* Literal string, where present. */
+	    while (*s != NUL)
+		printf("%c", *s++);
+	    s++;
+	}
+	printf("\r\n");
+    }
+
+    /* Header fields of interest. */
+    if (r->regstart != NUL)
+	printf("start `%s' 0x%x; ", r->regstart < 256
+		? (char *)transchar(r->regstart)
+		: "multibyte", r->regstart);
+    if (r->reganch)
+	printf("anchored; ");
+    if (r->regmust != NULL)
+	printf("must have \"%s\"", r->regmust);
+    printf("\r\n");
+}
+
+/*
+ * regprop - printable representation of opcode
+ */
+    static char_u *
+regprop(op)
+    char_u	   *op;
+{
+    char_u	    *p;
+    static char_u   buf[50];
+
+    (void) strcpy(buf, ":");
+
+    switch (OP(op))
+    {
+      case BOL:
+	p = "BOL";
+	break;
+      case EOL:
+	p = "EOL";
+	break;
+      case RE_BOF:
+	p = "BOF";
+	break;
+      case RE_EOF:
+	p = "EOF";
+	break;
+      case CURSOR:
+	p = "CURSOR";
+	break;
+      case RE_VISUAL:
+	p = "RE_VISUAL";
+	break;
+      case RE_LNUM:
+	p = "RE_LNUM";
+	break;
+      case RE_MARK:
+	p = "RE_MARK";
+	break;
+      case RE_COL:
+	p = "RE_COL";
+	break;
+      case RE_VCOL:
+	p = "RE_VCOL";
+	break;
+      case BOW:
+	p = "BOW";
+	break;
+      case EOW:
+	p = "EOW";
+	break;
+      case ANY:
+	p = "ANY";
+	break;
+      case ANY + ADD_NL:
+	p = "ANY+NL";
+	break;
+      case ANYOF:
+	p = "ANYOF";
+	break;
+      case ANYOF + ADD_NL:
+	p = "ANYOF+NL";
+	break;
+      case ANYBUT:
+	p = "ANYBUT";
+	break;
+      case ANYBUT + ADD_NL:
+	p = "ANYBUT+NL";
+	break;
+      case IDENT:
+	p = "IDENT";
+	break;
+      case IDENT + ADD_NL:
+	p = "IDENT+NL";
+	break;
+      case SIDENT:
+	p = "SIDENT";
+	break;
+      case SIDENT + ADD_NL:
+	p = "SIDENT+NL";
+	break;
+      case KWORD:
+	p = "KWORD";
+	break;
+      case KWORD + ADD_NL:
+	p = "KWORD+NL";
+	break;
+      case SKWORD:
+	p = "SKWORD";
+	break;
+      case SKWORD + ADD_NL:
+	p = "SKWORD+NL";
+	break;
+      case FNAME:
+	p = "FNAME";
+	break;
+      case FNAME + ADD_NL:
+	p = "FNAME+NL";
+	break;
+      case SFNAME:
+	p = "SFNAME";
+	break;
+      case SFNAME + ADD_NL:
+	p = "SFNAME+NL";
+	break;
+      case PRINT:
+	p = "PRINT";
+	break;
+      case PRINT + ADD_NL:
+	p = "PRINT+NL";
+	break;
+      case SPRINT:
+	p = "SPRINT";
+	break;
+      case SPRINT + ADD_NL:
+	p = "SPRINT+NL";
+	break;
+      case WHITE:
+	p = "WHITE";
+	break;
+      case WHITE + ADD_NL:
+	p = "WHITE+NL";
+	break;
+      case NWHITE:
+	p = "NWHITE";
+	break;
+      case NWHITE + ADD_NL:
+	p = "NWHITE+NL";
+	break;
+      case DIGIT:
+	p = "DIGIT";
+	break;
+      case DIGIT + ADD_NL:
+	p = "DIGIT+NL";
+	break;
+      case NDIGIT:
+	p = "NDIGIT";
+	break;
+      case NDIGIT + ADD_NL:
+	p = "NDIGIT+NL";
+	break;
+      case HEX:
+	p = "HEX";
+	break;
+      case HEX + ADD_NL:
+	p = "HEX+NL";
+	break;
+      case NHEX:
+	p = "NHEX";
+	break;
+      case NHEX + ADD_NL:
+	p = "NHEX+NL";
+	break;
+      case OCTAL:
+	p = "OCTAL";
+	break;
+      case OCTAL + ADD_NL:
+	p = "OCTAL+NL";
+	break;
+      case NOCTAL:
+	p = "NOCTAL";
+	break;
+      case NOCTAL + ADD_NL:
+	p = "NOCTAL+NL";
+	break;
+      case WORD:
+	p = "WORD";
+	break;
+      case WORD + ADD_NL:
+	p = "WORD+NL";
+	break;
+      case NWORD:
+	p = "NWORD";
+	break;
+      case NWORD + ADD_NL:
+	p = "NWORD+NL";
+	break;
+      case HEAD:
+	p = "HEAD";
+	break;
+      case HEAD + ADD_NL:
+	p = "HEAD+NL";
+	break;
+      case NHEAD:
+	p = "NHEAD";
+	break;
+      case NHEAD + ADD_NL:
+	p = "NHEAD+NL";
+	break;
+      case ALPHA:
+	p = "ALPHA";
+	break;
+      case ALPHA + ADD_NL:
+	p = "ALPHA+NL";
+	break;
+      case NALPHA:
+	p = "NALPHA";
+	break;
+      case NALPHA + ADD_NL:
+	p = "NALPHA+NL";
+	break;
+      case LOWER:
+	p = "LOWER";
+	break;
+      case LOWER + ADD_NL:
+	p = "LOWER+NL";
+	break;
+      case NLOWER:
+	p = "NLOWER";
+	break;
+      case NLOWER + ADD_NL:
+	p = "NLOWER+NL";
+	break;
+      case UPPER:
+	p = "UPPER";
+	break;
+      case UPPER + ADD_NL:
+	p = "UPPER+NL";
+	break;
+      case NUPPER:
+	p = "NUPPER";
+	break;
+      case NUPPER + ADD_NL:
+	p = "NUPPER+NL";
+	break;
+      case BRANCH:
+	p = "BRANCH";
+	break;
+      case EXACTLY:
+	p = "EXACTLY";
+	break;
+      case NOTHING:
+	p = "NOTHING";
+	break;
+      case BACK:
+	p = "BACK";
+	break;
+      case END:
+	p = "END";
+	break;
+      case MOPEN + 0:
+	p = "MATCH START";
+	break;
+      case MOPEN + 1:
+      case MOPEN + 2:
+      case MOPEN + 3:
+      case MOPEN + 4:
+      case MOPEN + 5:
+      case MOPEN + 6:
+      case MOPEN + 7:
+      case MOPEN + 8:
+      case MOPEN + 9:
+	sprintf(buf + STRLEN(buf), "MOPEN%d", OP(op) - MOPEN);
+	p = NULL;
+	break;
+      case MCLOSE + 0:
+	p = "MATCH END";
+	break;
+      case MCLOSE + 1:
+      case MCLOSE + 2:
+      case MCLOSE + 3:
+      case MCLOSE + 4:
+      case MCLOSE + 5:
+      case MCLOSE + 6:
+      case MCLOSE + 7:
+      case MCLOSE + 8:
+      case MCLOSE + 9:
+	sprintf(buf + STRLEN(buf), "MCLOSE%d", OP(op) - MCLOSE);
+	p = NULL;
+	break;
+      case BACKREF + 1:
+      case BACKREF + 2:
+      case BACKREF + 3:
+      case BACKREF + 4:
+      case BACKREF + 5:
+      case BACKREF + 6:
+      case BACKREF + 7:
+      case BACKREF + 8:
+      case BACKREF + 9:
+	sprintf(buf + STRLEN(buf), "BACKREF%d", OP(op) - BACKREF);
+	p = NULL;
+	break;
+      case NOPEN:
+	p = "NOPEN";
+	break;
+      case NCLOSE:
+	p = "NCLOSE";
+	break;
+#ifdef FEAT_SYN_HL
+      case ZOPEN + 1:
+      case ZOPEN + 2:
+      case ZOPEN + 3:
+      case ZOPEN + 4:
+      case ZOPEN + 5:
+      case ZOPEN + 6:
+      case ZOPEN + 7:
+      case ZOPEN + 8:
+      case ZOPEN + 9:
+	sprintf(buf + STRLEN(buf), "ZOPEN%d", OP(op) - ZOPEN);
+	p = NULL;
+	break;
+      case ZCLOSE + 1:
+      case ZCLOSE + 2:
+      case ZCLOSE + 3:
+      case ZCLOSE + 4:
+      case ZCLOSE + 5:
+      case ZCLOSE + 6:
+      case ZCLOSE + 7:
+      case ZCLOSE + 8:
+      case ZCLOSE + 9:
+	sprintf(buf + STRLEN(buf), "ZCLOSE%d", OP(op) - ZCLOSE);
+	p = NULL;
+	break;
+      case ZREF + 1:
+      case ZREF + 2:
+      case ZREF + 3:
+      case ZREF + 4:
+      case ZREF + 5:
+      case ZREF + 6:
+      case ZREF + 7:
+      case ZREF + 8:
+      case ZREF + 9:
+	sprintf(buf + STRLEN(buf), "ZREF%d", OP(op) - ZREF);
+	p = NULL;
+	break;
+#endif
+      case STAR:
+	p = "STAR";
+	break;
+      case PLUS:
+	p = "PLUS";
+	break;
+      case NOMATCH:
+	p = "NOMATCH";
+	break;
+      case MATCH:
+	p = "MATCH";
+	break;
+      case BEHIND:
+	p = "BEHIND";
+	break;
+      case NOBEHIND:
+	p = "NOBEHIND";
+	break;
+      case SUBPAT:
+	p = "SUBPAT";
+	break;
+      case BRACE_LIMITS:
+	p = "BRACE_LIMITS";
+	break;
+      case BRACE_SIMPLE:
+	p = "BRACE_SIMPLE";
+	break;
+      case BRACE_COMPLEX + 0:
+      case BRACE_COMPLEX + 1:
+      case BRACE_COMPLEX + 2:
+      case BRACE_COMPLEX + 3:
+      case BRACE_COMPLEX + 4:
+      case BRACE_COMPLEX + 5:
+      case BRACE_COMPLEX + 6:
+      case BRACE_COMPLEX + 7:
+      case BRACE_COMPLEX + 8:
+      case BRACE_COMPLEX + 9:
+	sprintf(buf + STRLEN(buf), "BRACE_COMPLEX%d", OP(op) - BRACE_COMPLEX);
+	p = NULL;
+	break;
+#ifdef FEAT_MBYTE
+      case MULTIBYTECODE:
+	p = "MULTIBYTECODE";
+	break;
+#endif
+      case NEWL:
+	p = "NEWL";
+	break;
+      default:
+	sprintf(buf + STRLEN(buf), "corrupt %d", OP(op));
+	p = NULL;
+	break;
+    }
+    if (p != NULL)
+	(void) strcat(buf, p);
+    return buf;
+}
+#endif
+
+#ifdef FEAT_MBYTE
+static void mb_decompose __ARGS((int c, int *c1, int *c2, int *c3));
+
+typedef struct
+{
+    int a, b, c;
+} decomp_T;
+
+
+/* 0xfb20 - 0xfb4f */
+static decomp_T decomp_table[0xfb4f-0xfb20+1] =
+{
+    {0x5e2,0,0},		/* 0xfb20	alt ayin */
+    {0x5d0,0,0},		/* 0xfb21	alt alef */
+    {0x5d3,0,0},		/* 0xfb22	alt dalet */
+    {0x5d4,0,0},		/* 0xfb23	alt he */
+    {0x5db,0,0},		/* 0xfb24	alt kaf */
+    {0x5dc,0,0},		/* 0xfb25	alt lamed */
+    {0x5dd,0,0},		/* 0xfb26	alt mem-sofit */
+    {0x5e8,0,0},		/* 0xfb27	alt resh */
+    {0x5ea,0,0},		/* 0xfb28	alt tav */
+    {'+', 0, 0},		/* 0xfb29	alt plus */
+    {0x5e9, 0x5c1, 0},		/* 0xfb2a	shin+shin-dot */
+    {0x5e9, 0x5c2, 0},		/* 0xfb2b	shin+sin-dot */
+    {0x5e9, 0x5c1, 0x5bc},	/* 0xfb2c	shin+shin-dot+dagesh */
+    {0x5e9, 0x5c2, 0x5bc},	/* 0xfb2d	shin+sin-dot+dagesh */
+    {0x5d0, 0x5b7, 0},		/* 0xfb2e	alef+patah */
+    {0x5d0, 0x5b8, 0},		/* 0xfb2f	alef+qamats */
+    {0x5d0, 0x5b4, 0},		/* 0xfb30	alef+hiriq */
+    {0x5d1, 0x5bc, 0},		/* 0xfb31	bet+dagesh */
+    {0x5d2, 0x5bc, 0},		/* 0xfb32	gimel+dagesh */
+    {0x5d3, 0x5bc, 0},		/* 0xfb33	dalet+dagesh */
+    {0x5d4, 0x5bc, 0},		/* 0xfb34	he+dagesh */
+    {0x5d5, 0x5bc, 0},		/* 0xfb35	vav+dagesh */
+    {0x5d6, 0x5bc, 0},		/* 0xfb36	zayin+dagesh */
+    {0xfb37, 0, 0},		/* 0xfb37 -- UNUSED */
+    {0x5d8, 0x5bc, 0},		/* 0xfb38	tet+dagesh */
+    {0x5d9, 0x5bc, 0},		/* 0xfb39	yud+dagesh */
+    {0x5da, 0x5bc, 0},		/* 0xfb3a	kaf sofit+dagesh */
+    {0x5db, 0x5bc, 0},		/* 0xfb3b	kaf+dagesh */
+    {0x5dc, 0x5bc, 0},		/* 0xfb3c	lamed+dagesh */
+    {0xfb3d, 0, 0},		/* 0xfb3d -- UNUSED */
+    {0x5de, 0x5bc, 0},		/* 0xfb3e	mem+dagesh */
+    {0xfb3f, 0, 0},		/* 0xfb3f -- UNUSED */
+    {0x5e0, 0x5bc, 0},		/* 0xfb40	nun+dagesh */
+    {0x5e1, 0x5bc, 0},		/* 0xfb41	samech+dagesh */
+    {0xfb42, 0, 0},		/* 0xfb42 -- UNUSED */
+    {0x5e3, 0x5bc, 0},		/* 0xfb43	pe sofit+dagesh */
+    {0x5e4, 0x5bc,0},		/* 0xfb44	pe+dagesh */
+    {0xfb45, 0, 0},		/* 0xfb45 -- UNUSED */
+    {0x5e6, 0x5bc, 0},		/* 0xfb46	tsadi+dagesh */
+    {0x5e7, 0x5bc, 0},		/* 0xfb47	qof+dagesh */
+    {0x5e8, 0x5bc, 0},		/* 0xfb48	resh+dagesh */
+    {0x5e9, 0x5bc, 0},		/* 0xfb49	shin+dagesh */
+    {0x5ea, 0x5bc, 0},		/* 0xfb4a	tav+dagesh */
+    {0x5d5, 0x5b9, 0},		/* 0xfb4b	vav+holam */
+    {0x5d1, 0x5bf, 0},		/* 0xfb4c	bet+rafe */
+    {0x5db, 0x5bf, 0},		/* 0xfb4d	kaf+rafe */
+    {0x5e4, 0x5bf, 0},		/* 0xfb4e	pe+rafe */
+    {0x5d0, 0x5dc, 0}		/* 0xfb4f	alef-lamed */
+};
+
+    static void
+mb_decompose(c, c1, c2, c3)
+    int c, *c1, *c2, *c3;
+{
+    decomp_T d;
+
+    if (c >= 0x4b20 && c <= 0xfb4f)
+    {
+	d = decomp_table[c - 0xfb20];
+	*c1 = d.a;
+	*c2 = d.b;
+	*c3 = d.c;
+    }
+    else
+    {
+	*c1 = c;
+	*c2 = *c3 = 0;
+    }
+}
+#endif
+
+/*
+ * Compare two strings, ignore case if ireg_ic set.
+ * Return 0 if strings match, non-zero otherwise.
+ * Correct the length "*n" when composing characters are ignored.
+ */
+    static int
+cstrncmp(s1, s2, n)
+    char_u	*s1, *s2;
+    int		*n;
+{
+    int		result;
+
+    if (!ireg_ic)
+	result = STRNCMP(s1, s2, *n);
+    else
+	result = MB_STRNICMP(s1, s2, *n);
+
+#ifdef FEAT_MBYTE
+    /* if it failed and it's utf8 and we want to combineignore: */
+    if (result != 0 && enc_utf8 && ireg_icombine)
+    {
+	char_u	*str1, *str2;
+	int	c1, c2, c11, c12;
+	int	junk;
+
+	/* we have to handle the strcmp ourselves, since it is necessary to
+	 * deal with the composing characters by ignoring them: */
+	str1 = s1;
+	str2 = s2;
+	c1 = c2 = 0;
+	while ((int)(str1 - s1) < *n)
+	{
+	    c1 = mb_ptr2char_adv(&str1);
+	    c2 = mb_ptr2char_adv(&str2);
+
+	    /* decompose the character if necessary, into 'base' characters
+	     * because I don't care about Arabic, I will hard-code the Hebrew
+	     * which I *do* care about!  So sue me... */
+	    if (c1 != c2 && (!ireg_ic || utf_fold(c1) != utf_fold(c2)))
+	    {
+		/* decomposition necessary? */
+		mb_decompose(c1, &c11, &junk, &junk);
+		mb_decompose(c2, &c12, &junk, &junk);
+		c1 = c11;
+		c2 = c12;
+		if (c11 != c12 && (!ireg_ic || utf_fold(c11) != utf_fold(c12)))
+		    break;
+	    }
+	}
+	result = c2 - c1;
+	if (result == 0)
+	    *n = (int)(str2 - s2);
+    }
+#endif
+
+    return result;
+}
+
+/*
+ * cstrchr: This function is used a lot for simple searches, keep it fast!
+ */
+    static char_u *
+cstrchr(s, c)
+    char_u	*s;
+    int		c;
+{
+    char_u	*p;
+    int		cc;
+
+    if (!ireg_ic
+#ifdef FEAT_MBYTE
+	    || (!enc_utf8 && mb_char2len(c) > 1)
+#endif
+	    )
+	return vim_strchr(s, c);
+
+    /* tolower() and toupper() can be slow, comparing twice should be a lot
+     * faster (esp. when using MS Visual C++!).
+     * For UTF-8 need to use folded case. */
+#ifdef FEAT_MBYTE
+    if (enc_utf8 && c > 0x80)
+	cc = utf_fold(c);
+    else
+#endif
+	 if (isupper(c))
+	cc = TOLOWER_LOC(c);
+    else if (islower(c))
+	cc = TOUPPER_LOC(c);
+    else
+	return vim_strchr(s, c);
+
+#ifdef FEAT_MBYTE
+    if (has_mbyte)
+    {
+	for (p = s; *p != NUL; p += (*mb_ptr2len)(p))
+	{
+	    if (enc_utf8 && c > 0x80)
+	    {
+		if (utf_fold(utf_ptr2char(p)) == cc)
+		    return p;
+	    }
+	    else if (*p == c || *p == cc)
+		return p;
+	}
+    }
+    else
+#endif
+	/* Faster version for when there are no multi-byte characters. */
+	for (p = s; *p != NUL; ++p)
+	    if (*p == c || *p == cc)
+		return p;
+
+    return NULL;
+}
+
+/***************************************************************
+ *		      regsub stuff			       *
+ ***************************************************************/
+
+/* This stuff below really confuses cc on an SGI -- webb */
+#ifdef __sgi
+# undef __ARGS
+# define __ARGS(x)  ()
+#endif
+
+/*
+ * We should define ftpr as a pointer to a function returning a pointer to
+ * a function returning a pointer to a function ...
+ * This is impossible, so we declare a pointer to a function returning a
+ * pointer to a function returning void. This should work for all compilers.
+ */
+typedef void (*(*fptr_T) __ARGS((int *, int)))();
+
+static fptr_T do_upper __ARGS((int *, int));
+static fptr_T do_Upper __ARGS((int *, int));
+static fptr_T do_lower __ARGS((int *, int));
+static fptr_T do_Lower __ARGS((int *, int));
+
+static int vim_regsub_both __ARGS((char_u *source, char_u *dest, int copy, int magic, int backslash));
+
+    static fptr_T
+do_upper(d, c)
+    int		*d;
+    int		c;
+{
+    *d = MB_TOUPPER(c);
+
+    return (fptr_T)NULL;
+}
+
+    static fptr_T
+do_Upper(d, c)
+    int		*d;
+    int		c;
+{
+    *d = MB_TOUPPER(c);
+
+    return (fptr_T)do_Upper;
+}
+
+    static fptr_T
+do_lower(d, c)
+    int		*d;
+    int		c;
+{
+    *d = MB_TOLOWER(c);
+
+    return (fptr_T)NULL;
+}
+
+    static fptr_T
+do_Lower(d, c)
+    int		*d;
+    int		c;
+{
+    *d = MB_TOLOWER(c);
+
+    return (fptr_T)do_Lower;
+}
+
+/*
+ * regtilde(): Replace tildes in the pattern by the old pattern.
+ *
+ * Short explanation of the tilde: It stands for the previous replacement
+ * pattern.  If that previous pattern also contains a ~ we should go back a
+ * step further...  But we insert the previous pattern into the current one
+ * and remember that.
+ * This still does not handle the case where "magic" changes.  So require the
+ * user to keep his hands off of "magic".
+ *
+ * The tildes are parsed once before the first call to vim_regsub().
+ */
+    char_u *
+regtilde(source, magic)
+    char_u	*source;
+    int		magic;
+{
+    char_u	*newsub = source;
+    char_u	*tmpsub;
+    char_u	*p;
+    int		len;
+    int		prevlen;
+
+    for (p = newsub; *p; ++p)
+    {
+	if ((*p == '~' && magic) || (*p == '\\' && *(p + 1) == '~' && !magic))
+	{
+	    if (reg_prev_sub != NULL)
+	    {
+		/* length = len(newsub) - 1 + len(prev_sub) + 1 */
+		prevlen = (int)STRLEN(reg_prev_sub);
+		tmpsub = alloc((unsigned)(STRLEN(newsub) + prevlen));
+		if (tmpsub != NULL)
+		{
+		    /* copy prefix */
+		    len = (int)(p - newsub);	/* not including ~ */
+		    mch_memmove(tmpsub, newsub, (size_t)len);
+		    /* interpret tilde */
+		    mch_memmove(tmpsub + len, reg_prev_sub, (size_t)prevlen);
+		    /* copy postfix */
+		    if (!magic)
+			++p;			/* back off \ */
+		    STRCPY(tmpsub + len + prevlen, p + 1);
+
+		    if (newsub != source)	/* already allocated newsub */
+			vim_free(newsub);
+		    newsub = tmpsub;
+		    p = newsub + len + prevlen;
+		}
+	    }
+	    else if (magic)
+		STRCPY(p, p + 1);		/* remove '~' */
+	    else
+		STRCPY(p, p + 2);		/* remove '\~' */
+	    --p;
+	}
+	else
+	{
+	    if (*p == '\\' && p[1])		/* skip escaped characters */
+		++p;
+#ifdef FEAT_MBYTE
+	    if (has_mbyte)
+		p += (*mb_ptr2len)(p) - 1;
+#endif
+	}
+    }
+
+    vim_free(reg_prev_sub);
+    if (newsub != source)	/* newsub was allocated, just keep it */
+	reg_prev_sub = newsub;
+    else			/* no ~ found, need to save newsub  */
+	reg_prev_sub = vim_strsave(newsub);
+    return newsub;
+}
+
+#ifdef FEAT_EVAL
+static int can_f_submatch = FALSE;	/* TRUE when submatch() can be used */
+
+/* These pointers are used instead of reg_match and reg_mmatch for
+ * reg_submatch().  Needed for when the substitution string is an expression
+ * that contains a call to substitute() and submatch(). */
+static regmatch_T	*submatch_match;
+static regmmatch_T	*submatch_mmatch;
+#endif
+
+#if defined(FEAT_MODIFY_FNAME) || defined(FEAT_EVAL) || defined(PROTO)
+/*
+ * vim_regsub() - perform substitutions after a vim_regexec() or
+ * vim_regexec_multi() match.
+ *
+ * If "copy" is TRUE really copy into "dest".
+ * If "copy" is FALSE nothing is copied, this is just to find out the length
+ * of the result.
+ *
+ * If "backslash" is TRUE, a backslash will be removed later, need to double
+ * them to keep them, and insert a backslash before a CR to avoid it being
+ * replaced with a line break later.
+ *
+ * Note: The matched text must not change between the call of
+ * vim_regexec()/vim_regexec_multi() and vim_regsub()!  It would make the back
+ * references invalid!
+ *
+ * Returns the size of the replacement, including terminating NUL.
+ */
+    int
+vim_regsub(rmp, source, dest, copy, magic, backslash)
+    regmatch_T	*rmp;
+    char_u	*source;
+    char_u	*dest;
+    int		copy;
+    int		magic;
+    int		backslash;
+{
+    reg_match = rmp;
+    reg_mmatch = NULL;
+    reg_maxline = 0;
+    return vim_regsub_both(source, dest, copy, magic, backslash);
+}
+#endif
+
+    int
+vim_regsub_multi(rmp, lnum, source, dest, copy, magic, backslash)
+    regmmatch_T	*rmp;
+    linenr_T	lnum;
+    char_u	*source;
+    char_u	*dest;
+    int		copy;
+    int		magic;
+    int		backslash;
+{
+    reg_match = NULL;
+    reg_mmatch = rmp;
+    reg_buf = curbuf;		/* always works on the current buffer! */
+    reg_firstlnum = lnum;
+    reg_maxline = curbuf->b_ml.ml_line_count - lnum;
+    return vim_regsub_both(source, dest, copy, magic, backslash);
+}
+
+    static int
+vim_regsub_both(source, dest, copy, magic, backslash)
+    char_u	*source;
+    char_u	*dest;
+    int		copy;
+    int		magic;
+    int		backslash;
+{
+    char_u	*src;
+    char_u	*dst;
+    char_u	*s;
+    int		c;
+    int		cc;
+    int		no = -1;
+    fptr_T	func = (fptr_T)NULL;
+    linenr_T	clnum = 0;	/* init for GCC */
+    int		len = 0;	/* init for GCC */
+#ifdef FEAT_EVAL
+    static char_u *eval_result = NULL;
+#endif
+
+    /* Be paranoid... */
+    if (source == NULL || dest == NULL)
+    {
+	EMSG(_(e_null));
+	return 0;
+    }
+    if (prog_magic_wrong())
+	return 0;
+    src = source;
+    dst = dest;
+
+    /*
+     * When the substitute part starts with "\=" evaluate it as an expression.
+     */
+    if (source[0] == '\\' && source[1] == '='
+#ifdef FEAT_EVAL
+	    && !can_f_submatch	    /* can't do this recursively */
+#endif
+	    )
+    {
+#ifdef FEAT_EVAL
+	/* To make sure that the length doesn't change between checking the
+	 * length and copying the string, and to speed up things, the
+	 * resulting string is saved from the call with "copy" == FALSE to the
+	 * call with "copy" == TRUE. */
+	if (copy)
+	{
+	    if (eval_result != NULL)
+	    {
+		STRCPY(dest, eval_result);
+		dst += STRLEN(eval_result);
+		vim_free(eval_result);
+		eval_result = NULL;
+	    }
+	}
+	else
+	{
+	    linenr_T	save_reg_maxline;
+	    win_T	*save_reg_win;
+	    int		save_ireg_ic;
+
+	    vim_free(eval_result);
+
+	    /* The expression may contain substitute(), which calls us
+	     * recursively.  Make sure submatch() gets the text from the first
+	     * level.  Don't need to save "reg_buf", because
+	     * vim_regexec_multi() can't be called recursively. */
+	    submatch_match = reg_match;
+	    submatch_mmatch = reg_mmatch;
+	    save_reg_maxline = reg_maxline;
+	    save_reg_win = reg_win;
+	    save_ireg_ic = ireg_ic;
+	    can_f_submatch = TRUE;
+
+	    eval_result = eval_to_string(source + 2, NULL, TRUE);
+	    if (eval_result != NULL)
+	    {
+		for (s = eval_result; *s != NUL; mb_ptr_adv(s))
+		{
+		    /* Change NL to CR, so that it becomes a line break.
+		     * Skip over a backslashed character. */
+		    if (*s == NL)
+			*s = CAR;
+		    else if (*s == '\\' && s[1] != NUL)
+			++s;
+		}
+
+		dst += STRLEN(eval_result);
+	    }
+
+	    reg_match = submatch_match;
+	    reg_mmatch = submatch_mmatch;
+	    reg_maxline = save_reg_maxline;
+	    reg_win = save_reg_win;
+	    ireg_ic = save_ireg_ic;
+	    can_f_submatch = FALSE;
+	}
+#endif
+    }
+    else
+      while ((c = *src++) != NUL)
+      {
+	if (c == '&' && magic)
+	    no = 0;
+	else if (c == '\\' && *src != NUL)
+	{
+	    if (*src == '&' && !magic)
+	    {
+		++src;
+		no = 0;
+	    }
+	    else if ('0' <= *src && *src <= '9')
+	    {
+		no = *src++ - '0';
+	    }
+	    else if (vim_strchr((char_u *)"uUlLeE", *src))
+	    {
+		switch (*src++)
+		{
+		case 'u':   func = (fptr_T)do_upper;
+			    continue;
+		case 'U':   func = (fptr_T)do_Upper;
+			    continue;
+		case 'l':   func = (fptr_T)do_lower;
+			    continue;
+		case 'L':   func = (fptr_T)do_Lower;
+			    continue;
+		case 'e':
+		case 'E':   func = (fptr_T)NULL;
+			    continue;
+		}
+	    }
+	}
+	if (no < 0)	      /* Ordinary character. */
+	{
+	    if (c == K_SPECIAL && src[0] != NUL && src[1] != NUL)
+	    {
+		/* Copy a special key as-is. */
+		if (copy)
+		{
+		    *dst++ = c;
+		    *dst++ = *src++;
+		    *dst++ = *src++;
+		}
+		else
+		{
+		    dst += 3;
+		    src += 2;
+		}
+		continue;
+	    }
+
+	    if (c == '\\' && *src != NUL)
+	    {
+		/* Check for abbreviations -- webb */
+		switch (*src)
+		{
+		    case 'r':	c = CAR;	++src;	break;
+		    case 'n':	c = NL;		++src;	break;
+		    case 't':	c = TAB;	++src;	break;
+		 /* Oh no!  \e already has meaning in subst pat :-( */
+		 /* case 'e':   c = ESC;	++src;	break; */
+		    case 'b':	c = Ctrl_H;	++src;	break;
+
+		    /* If "backslash" is TRUE the backslash will be removed
+		     * later.  Used to insert a literal CR. */
+		    default:	if (backslash)
+				{
+				    if (copy)
+					*dst = '\\';
+				    ++dst;
+				}
+				c = *src++;
+		}
+	    }
+#ifdef FEAT_MBYTE
+	    else if (has_mbyte)
+		c = mb_ptr2char(src - 1);
+#endif
+
+	    /* Write to buffer, if copy is set. */
+	    if (func == (fptr_T)NULL)	/* just copy */
+		cc = c;
+	    else
+		/* Turbo C complains without the typecast */
+		func = (fptr_T)(func(&cc, c));
+
+#ifdef FEAT_MBYTE
+	    if (has_mbyte)
+	    {
+		src += mb_ptr2len(src - 1) - 1;
+		if (copy)
+		    mb_char2bytes(cc, dst);
+		dst += mb_char2len(cc) - 1;
+	    }
+	    else
+#endif
+		if (copy)
+		    *dst = cc;
+	    dst++;
+	}
+	else
+	{
+	    if (REG_MULTI)
+	    {
+		clnum = reg_mmatch->startpos[no].lnum;
+		if (clnum < 0 || reg_mmatch->endpos[no].lnum < 0)
+		    s = NULL;
+		else
+		{
+		    s = reg_getline(clnum) + reg_mmatch->startpos[no].col;
+		    if (reg_mmatch->endpos[no].lnum == clnum)
+			len = reg_mmatch->endpos[no].col
+					       - reg_mmatch->startpos[no].col;
+		    else
+			len = (int)STRLEN(s);
+		}
+	    }
+	    else
+	    {
+		s = reg_match->startp[no];
+		if (reg_match->endp[no] == NULL)
+		    s = NULL;
+		else
+		    len = (int)(reg_match->endp[no] - s);
+	    }
+	    if (s != NULL)
+	    {
+		for (;;)
+		{
+		    if (len == 0)
+		    {
+			if (REG_MULTI)
+			{
+			    if (reg_mmatch->endpos[no].lnum == clnum)
+				break;
+			    if (copy)
+				*dst = CAR;
+			    ++dst;
+			    s = reg_getline(++clnum);
+			    if (reg_mmatch->endpos[no].lnum == clnum)
+				len = reg_mmatch->endpos[no].col;
+			    else
+				len = (int)STRLEN(s);
+			}
+			else
+			    break;
+		    }
+		    else if (*s == NUL) /* we hit NUL. */
+		    {
+			if (copy)
+			    EMSG(_(e_re_damg));
+			goto exit;
+		    }
+		    else
+		    {
+			if (backslash && (*s == CAR || *s == '\\'))
+			{
+			    /*
+			     * Insert a backslash in front of a CR, otherwise
+			     * it will be replaced by a line break.
+			     * Number of backslashes will be halved later,
+			     * double them here.
+			     */
+			    if (copy)
+			    {
+				dst[0] = '\\';
+				dst[1] = *s;
+			    }
+			    dst += 2;
+			}
+			else
+			{
+#ifdef FEAT_MBYTE
+			    if (has_mbyte)
+				c = mb_ptr2char(s);
+			    else
+#endif
+				c = *s;
+
+			    if (func == (fptr_T)NULL)	/* just copy */
+				cc = c;
+			    else
+				/* Turbo C complains without the typecast */
+				func = (fptr_T)(func(&cc, c));
+
+#ifdef FEAT_MBYTE
+			    if (has_mbyte)
+			    {
+				int l = mb_ptr2len(s) - 1;
+
+				s += l;
+				len -= l;
+				if (copy)
+				    mb_char2bytes(cc, dst);
+				dst += mb_char2len(cc) - 1;
+			    }
+			    else
+#endif
+				if (copy)
+				    *dst = cc;
+			    dst++;
+			}
+
+			++s;
+			--len;
+		    }
+		}
+	    }
+	    no = -1;
+	}
+      }
+    if (copy)
+	*dst = NUL;
+
+exit:
+    return (int)((dst - dest) + 1);
+}
+
+#ifdef FEAT_EVAL
+/*
+ * Used for the submatch() function: get the string from the n'th submatch in
+ * allocated memory.
+ * Returns NULL when not in a ":s" command and for a non-existing submatch.
+ */
+    char_u *
+reg_submatch(no)
+    int		no;
+{
+    char_u	*retval = NULL;
+    char_u	*s;
+    int		len;
+    int		round;
+    linenr_T	lnum;
+
+    if (!can_f_submatch || no < 0)
+	return NULL;
+
+    if (submatch_match == NULL)
+    {
+	/*
+	 * First round: compute the length and allocate memory.
+	 * Second round: copy the text.
+	 */
+	for (round = 1; round <= 2; ++round)
+	{
+	    lnum = submatch_mmatch->startpos[no].lnum;
+	    if (lnum < 0 || submatch_mmatch->endpos[no].lnum < 0)
+		return NULL;
+
+	    s = reg_getline(lnum) + submatch_mmatch->startpos[no].col;
+	    if (s == NULL)  /* anti-crash check, cannot happen? */
+		break;
+	    if (submatch_mmatch->endpos[no].lnum == lnum)
+	    {
+		/* Within one line: take form start to end col. */
+		len = submatch_mmatch->endpos[no].col
+					  - submatch_mmatch->startpos[no].col;
+		if (round == 2)
+		    vim_strncpy(retval, s, len);
+		++len;
+	    }
+	    else
+	    {
+		/* Multiple lines: take start line from start col, middle
+		 * lines completely and end line up to end col. */
+		len = (int)STRLEN(s);
+		if (round == 2)
+		{
+		    STRCPY(retval, s);
+		    retval[len] = '\n';
+		}
+		++len;
+		++lnum;
+		while (lnum < submatch_mmatch->endpos[no].lnum)
+		{
+		    s = reg_getline(lnum++);
+		    if (round == 2)
+			STRCPY(retval + len, s);
+		    len += (int)STRLEN(s);
+		    if (round == 2)
+			retval[len] = '\n';
+		    ++len;
+		}
+		if (round == 2)
+		    STRNCPY(retval + len, reg_getline(lnum),
+					     submatch_mmatch->endpos[no].col);
+		len += submatch_mmatch->endpos[no].col;
+		if (round == 2)
+		    retval[len] = NUL;
+		++len;
+	    }
+
+	    if (retval == NULL)
+	    {
+		retval = lalloc((long_u)len, TRUE);
+		if (retval == NULL)
+		    return NULL;
+	    }
+	}
+    }
+    else
+    {
+	if (submatch_match->endp[no] == NULL)
+	    retval = NULL;
+	else
+	{
+	    s = submatch_match->startp[no];
+	    retval = vim_strnsave(s, (int)(submatch_match->endp[no] - s));
+	}
+    }
+
+    return retval;
+}
+#endif
--- /dev/null
+++ b/regexp.h
@@ -1,0 +1,81 @@
+/* vi:set ts=8 sts=4 sw=4:
+ *
+ * NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE
+ *
+ * This is NOT the original regular expression code as written by Henry
+ * Spencer.  This code has been modified specifically for use with Vim, and
+ * should not be used apart from compiling Vim.  If you want a good regular
+ * expression library, get the original code.
+ *
+ * NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE
+ */
+
+#ifndef _REGEXP_H
+#define _REGEXP_H
+
+/*
+ * The number of sub-matches is limited to 10.
+ * The first one (index 0) is the whole match, referenced with "\0".
+ * The second one (index 1) is the first sub-match, referenced with "\1".
+ * This goes up to the tenth (index 9), referenced with "\9".
+ */
+#define NSUBEXP  10
+
+/*
+ * Structure returned by vim_regcomp() to pass on to vim_regexec().
+ * These fields are only to be used in regexp.c!
+ * See regep.c for an explanation.
+ */
+typedef struct
+{
+    int			regstart;
+    char_u		reganch;
+    char_u		*regmust;
+    int			regmlen;
+    unsigned		regflags;
+    char_u		reghasz;
+    char_u		program[1];		/* actually longer.. */
+} regprog_T;
+
+/*
+ * Structure to be used for single-line matching.
+ * Sub-match "no" starts at "startp[no]" and ends just before "endp[no]".
+ * When there is no match, the pointer is NULL.
+ */
+typedef struct
+{
+    regprog_T		*regprog;
+    char_u		*startp[NSUBEXP];
+    char_u		*endp[NSUBEXP];
+    int			rm_ic;
+} regmatch_T;
+
+/*
+ * Structure to be used for multi-line matching.
+ * Sub-match "no" starts in line "startpos[no].lnum" column "startpos[no].col"
+ * and ends in line "endpos[no].lnum" just before column "endpos[no].col".
+ * The line numbers are relative to the first line, thus startpos[0].lnum is
+ * always 0.
+ * When there is no match, the line number is -1.
+ */
+typedef struct
+{
+    regprog_T		*regprog;
+    lpos_T		startpos[NSUBEXP];
+    lpos_T		endpos[NSUBEXP];
+    int			rmm_ic;
+    colnr_T		rmm_maxcol;	/* when not zero: maximum column */
+} regmmatch_T;
+
+/*
+ * Structure used to store external references: "\z\(\)" to "\z\1".
+ * Use a reference count to avoid the need to copy this around.  When it goes
+ * from 1 to zero the matches need to be freed.
+ */
+typedef struct
+{
+    short		refcnt;
+    char_u		*matches[NSUBEXP];
+} reg_extmatch_T;
+
+#endif	/* _REGEXP_H */
--- /dev/null
+++ b/screen.c
@@ -1,0 +1,9417 @@
+/* vi:set ts=8 sts=4 sw=4:
+ *
+ * VIM - Vi IMproved	by Bram Moolenaar
+ *
+ * Do ":help uganda"  in Vim to read copying and usage conditions.
+ * Do ":help credits" in Vim to see a list of people who contributed.
+ * See README.txt for an overview of the Vim source code.
+ */
+
+/*
+ * screen.c: code for displaying on the screen
+ *
+ * Output to the screen (console, terminal emulator or GUI window) is minimized
+ * by remembering what is already on the screen, and only updating the parts
+ * that changed.
+ *
+ * ScreenLines[off]  Contains a copy of the whole screen, as it is currently
+ *		     displayed (excluding text written by external commands).
+ * ScreenAttrs[off]  Contains the associated attributes.
+ * LineOffset[row]   Contains the offset into ScreenLines*[] and ScreenAttrs[]
+ *		     for each line.
+ * LineWraps[row]    Flag for each line whether it wraps to the next line.
+ *
+ * For double-byte characters, two consecutive bytes in ScreenLines[] can form
+ * one character which occupies two display cells.
+ * For UTF-8 a multi-byte character is converted to Unicode and stored in
+ * ScreenLinesUC[].  ScreenLines[] contains the first byte only.  For an ASCII
+ * character without composing chars ScreenLinesUC[] will be 0.  When the
+ * character occupies two display cells the next byte in ScreenLines[] is 0.
+ * ScreenLinesC[][] contain up to 'maxcombine' composing characters
+ * (drawn on top of the first character).  They are 0 when not used.
+ * ScreenLines2[] is only used for euc-jp to store the second byte if the
+ * first byte is 0x8e (single-width character).
+ *
+ * The screen_*() functions write to the screen and handle updating
+ * ScreenLines[].
+ *
+ * update_screen() is the function that updates all windows and status lines.
+ * It is called form the main loop when must_redraw is non-zero.  It may be
+ * called from other places when an immediate screen update is needed.
+ *
+ * The part of the buffer that is displayed in a window is set with:
+ * - w_topline (first buffer line in window)
+ * - w_topfill (filler line above the first line)
+ * - w_leftcol (leftmost window cell in window),
+ * - w_skipcol (skipped window cells of first line)
+ *
+ * Commands that only move the cursor around in a window, do not need to take
+ * action to update the display.  The main loop will check if w_topline is
+ * valid and update it (scroll the window) when needed.
+ *
+ * Commands that scroll a window change w_topline and must call
+ * check_cursor() to move the cursor into the visible part of the window, and
+ * call redraw_later(VALID) to have the window displayed by update_screen()
+ * later.
+ *
+ * Commands that change text in the buffer must call changed_bytes() or
+ * changed_lines() to mark the area that changed and will require updating
+ * later.  The main loop will call update_screen(), which will update each
+ * window that shows the changed buffer.  This assumes text above the change
+ * can remain displayed as it is.  Text after the change may need updating for
+ * scrolling, folding and syntax highlighting.
+ *
+ * Commands that change how a window is displayed (e.g., setting 'list') or
+ * invalidate the contents of a window in another way (e.g., change fold
+ * settings), must call redraw_later(NOT_VALID) to have the whole window
+ * redisplayed by update_screen() later.
+ *
+ * Commands that change how a buffer is displayed (e.g., setting 'tabstop')
+ * must call redraw_curbuf_later(NOT_VALID) to have all the windows for the
+ * buffer redisplayed by update_screen() later.
+ *
+ * Commands that change highlighting and possibly cause a scroll too must call
+ * redraw_later(SOME_VALID) to update the whole window but still use scrolling
+ * to avoid redrawing everything.  But the length of displayed lines must not
+ * change, use NOT_VALID then.
+ *
+ * Commands that move the window position must call redraw_later(NOT_VALID).
+ * TODO: should minimize redrawing by scrolling when possible.
+ *
+ * Commands that change everything (e.g., resizing the screen) must call
+ * redraw_all_later(NOT_VALID) or redraw_all_later(CLEAR).
+ *
+ * Things that are handled indirectly:
+ * - When messages scroll the screen up, msg_scrolled will be set and
+ *   update_screen() called to redraw.
+ */
+
+#include "vim.h"
+
+/*
+ * The attributes that are actually active for writing to the screen.
+ */
+static int	screen_attr = 0;
+
+/*
+ * Positioning the cursor is reduced by remembering the last position.
+ * Mostly used by windgoto() and screen_char().
+ */
+static int	screen_cur_row, screen_cur_col;	/* last known cursor position */
+
+#ifdef FEAT_SEARCH_EXTRA
+/*
+ * Struct used for highlighting 'hlsearch' matches for the last use search
+ * pattern or a ":match" item.
+ * For 'hlsearch' there is one pattern for all windows.  For ":match" there is
+ * a different pattern for each window.
+ */
+typedef struct
+{
+    regmmatch_T	rm;	/* points to the regexp program; contains last found
+			   match (may continue in next line) */
+    buf_T	*buf;	/* the buffer to search for a match */
+    linenr_T	lnum;	/* the line to search for a match */
+    int		attr;	/* attributes to be used for a match */
+    int		attr_cur; /* attributes currently active in win_line() */
+    linenr_T	first_lnum;	/* first lnum to search for multi-line pat */
+    colnr_T	startcol; /* in win_line() points to char where HL starts */
+    colnr_T	endcol;	 /* in win_line() points to char where HL ends */
+} match_T;
+
+static match_T search_hl;	/* used for 'hlsearch' highlight matching */
+static match_T match_hl[3];	/* used for ":match" highlight matching */
+#endif
+
+#ifdef FEAT_FOLDING
+static foldinfo_T win_foldinfo;	/* info for 'foldcolumn' */
+#endif
+
+/*
+ * Buffer for one screen line (characters and attributes).
+ */
+static schar_T	*current_ScreenLine;
+
+static void win_update __ARGS((win_T *wp));
+static void win_draw_end __ARGS((win_T *wp, int c1, int c2, int row, int endrow, hlf_T hl));
+#ifdef FEAT_FOLDING
+static void fold_line __ARGS((win_T *wp, long fold_count, foldinfo_T *foldinfo, linenr_T lnum, int row));
+static void fill_foldcolumn __ARGS((char_u *p, win_T *wp, int closed, linenr_T lnum));
+static void copy_text_attr __ARGS((int off, char_u *buf, int len, int attr));
+#endif
+static int win_line __ARGS((win_T *, linenr_T, int, int, int nochange));
+static int char_needs_redraw __ARGS((int off_from, int off_to, int cols));
+#ifdef FEAT_RIGHTLEFT
+static void screen_line __ARGS((int row, int coloff, int endcol, int clear_width, int rlflag));
+# define SCREEN_LINE(r, o, e, c, rl)    screen_line((r), (o), (e), (c), (rl))
+#else
+static void screen_line __ARGS((int row, int coloff, int endcol, int clear_width));
+# define SCREEN_LINE(r, o, e, c, rl)    screen_line((r), (o), (e), (c))
+#endif
+#ifdef FEAT_VERTSPLIT
+static void draw_vsep_win __ARGS((win_T *wp, int row));
+#endif
+#ifdef FEAT_STL_OPT
+static void redraw_custum_statusline __ARGS((win_T *wp));
+#endif
+#ifdef FEAT_SEARCH_EXTRA
+static void start_search_hl __ARGS((void));
+static void end_search_hl __ARGS((void));
+static void prepare_search_hl __ARGS((win_T *wp, linenr_T lnum));
+static void next_search_hl __ARGS((win_T *win, match_T *shl, linenr_T lnum, colnr_T mincol));
+#endif
+static void screen_start_highlight __ARGS((int attr));
+static void screen_char __ARGS((unsigned off, int row, int col));
+#ifdef FEAT_MBYTE
+static void screen_char_2 __ARGS((unsigned off, int row, int col));
+#endif
+static void screenclear2 __ARGS((void));
+static void lineclear __ARGS((unsigned off, int width));
+static void lineinvalid __ARGS((unsigned off, int width));
+#ifdef FEAT_VERTSPLIT
+static void linecopy __ARGS((int to, int from, win_T *wp));
+static void redraw_block __ARGS((int row, int end, win_T *wp));
+#endif
+static int win_do_lines __ARGS((win_T *wp, int row, int line_count, int mayclear, int del));
+static void win_rest_invalid __ARGS((win_T *wp));
+static void msg_pos_mode __ARGS((void));
+#if defined(FEAT_WINDOWS)
+static void draw_tabline __ARGS((void));
+#endif
+#if defined(FEAT_WINDOWS) || defined(FEAT_WILDMENU) || defined(FEAT_STL_OPT)
+static int fillchar_status __ARGS((int *attr, int is_curwin));
+#endif
+#ifdef FEAT_VERTSPLIT
+static int fillchar_vsep __ARGS((int *attr));
+#endif
+#ifdef FEAT_STL_OPT
+static void win_redr_custom __ARGS((win_T *wp, int draw_ruler));
+#endif
+#ifdef FEAT_CMDL_INFO
+static void win_redr_ruler __ARGS((win_T *wp, int always));
+#endif
+
+#if defined(FEAT_CLIPBOARD) || defined(FEAT_VERTSPLIT)
+/* Ugly global: overrule attribute used by screen_char() */
+static int screen_char_attr = 0;
+#endif
+
+/*
+ * Redraw the current window later, with update_screen(type).
+ * Set must_redraw only if not already set to a higher value.
+ * e.g. if must_redraw is CLEAR, type NOT_VALID will do nothing.
+ */
+    void
+redraw_later(type)
+    int		type;
+{
+    redraw_win_later(curwin, type);
+}
+
+    void
+redraw_win_later(wp, type)
+    win_T	*wp;
+    int		type;
+{
+    if (wp->w_redr_type < type)
+    {
+	wp->w_redr_type = type;
+	if (type >= NOT_VALID)
+	    wp->w_lines_valid = 0;
+	if (must_redraw < type)	/* must_redraw is the maximum of all windows */
+	    must_redraw = type;
+    }
+}
+
+/*
+ * Force a complete redraw later.  Also resets the highlighting.  To be used
+ * after executing a shell command that messes up the screen.
+ */
+    void
+redraw_later_clear()
+{
+    redraw_all_later(CLEAR);
+#ifdef FEAT_GUI
+    if (gui.in_use)
+	/* Use a code that will reset gui.highlight_mask in
+	 * gui_stop_highlight(). */
+	screen_attr = HL_ALL + 1;
+    else
+#endif
+	/* Use attributes that is very unlikely to appear in text. */
+	screen_attr = HL_BOLD | HL_UNDERLINE | HL_INVERSE;
+}
+
+/*
+ * Mark all windows to be redrawn later.
+ */
+    void
+redraw_all_later(type)
+    int		type;
+{
+    win_T	*wp;
+
+    FOR_ALL_WINDOWS(wp)
+    {
+	redraw_win_later(wp, type);
+    }
+}
+
+/*
+ * Mark all windows that are editing the current buffer to be updated later.
+ */
+    void
+redraw_curbuf_later(type)
+    int		type;
+{
+    redraw_buf_later(curbuf, type);
+}
+
+    void
+redraw_buf_later(buf, type)
+    buf_T	*buf;
+    int		type;
+{
+    win_T	*wp;
+
+    FOR_ALL_WINDOWS(wp)
+    {
+	if (wp->w_buffer == buf)
+	    redraw_win_later(wp, type);
+    }
+}
+
+/*
+ * Changed something in the current window, at buffer line "lnum", that
+ * requires that line and possibly other lines to be redrawn.
+ * Used when entering/leaving Insert mode with the cursor on a folded line.
+ * Used to remove the "$" from a change command.
+ * Note that when also inserting/deleting lines w_redraw_top and w_redraw_bot
+ * may become invalid and the whole window will have to be redrawn.
+ */
+/*ARGSUSED*/
+    void
+redrawWinline(lnum, invalid)
+    linenr_T	lnum;
+    int		invalid;	/* window line height is invalid now */
+{
+#ifdef FEAT_FOLDING
+    int		i;
+#endif
+
+    if (curwin->w_redraw_top == 0 || curwin->w_redraw_top > lnum)
+	curwin->w_redraw_top = lnum;
+    if (curwin->w_redraw_bot == 0 || curwin->w_redraw_bot < lnum)
+	curwin->w_redraw_bot = lnum;
+    redraw_later(VALID);
+
+#ifdef FEAT_FOLDING
+    if (invalid)
+    {
+	/* A w_lines[] entry for this lnum has become invalid. */
+	i = find_wl_entry(curwin, lnum);
+	if (i >= 0)
+	    curwin->w_lines[i].wl_valid = FALSE;
+    }
+#endif
+}
+
+/*
+ * update all windows that are editing the current buffer
+ */
+    void
+update_curbuf(type)
+    int		type;
+{
+    redraw_curbuf_later(type);
+    update_screen(type);
+}
+
+/*
+ * update_screen()
+ *
+ * Based on the current value of curwin->w_topline, transfer a screenfull
+ * of stuff from Filemem to ScreenLines[], and update curwin->w_botline.
+ */
+    void
+update_screen(type)
+    int		type;
+{
+    win_T	*wp;
+    static int	did_intro = FALSE;
+#if defined(FEAT_SEARCH_EXTRA) || defined(FEAT_CLIPBOARD)
+    int		did_one;
+#endif
+
+    if (!screen_valid(TRUE))
+	return;
+
+    if (must_redraw)
+    {
+	if (type < must_redraw)	    /* use maximal type */
+	    type = must_redraw;
+	must_redraw = 0;
+    }
+
+    /* Need to update w_lines[]. */
+    if (curwin->w_lines_valid == 0 && type < NOT_VALID)
+	type = NOT_VALID;
+
+    if (!redrawing())
+    {
+	redraw_later(type);		/* remember type for next time */
+	must_redraw = type;
+	if (type > INVERTED_ALL)
+	    curwin->w_lines_valid = 0;	/* don't use w_lines[].wl_size now */
+	return;
+    }
+
+    updating_screen = TRUE;
+#ifdef FEAT_SYN_HL
+    ++display_tick;	    /* let syntax code know we're in a next round of
+			     * display updating */
+#endif
+
+    /*
+     * if the screen was scrolled up when displaying a message, scroll it down
+     */
+    if (msg_scrolled)
+    {
+	clear_cmdline = TRUE;
+	if (msg_scrolled > Rows - 5)	    /* clearing is faster */
+	    type = CLEAR;
+	else if (type != CLEAR)
+	{
+	    check_for_delay(FALSE);
+	    if (screen_ins_lines(0, 0, msg_scrolled, (int)Rows, NULL) == FAIL)
+		type = CLEAR;
+	    FOR_ALL_WINDOWS(wp)
+	    {
+		if (W_WINROW(wp) < msg_scrolled)
+		{
+		    if (W_WINROW(wp) + wp->w_height > msg_scrolled
+			    && wp->w_redr_type < REDRAW_TOP
+			    && wp->w_lines_valid > 0
+			    && wp->w_topline == wp->w_lines[0].wl_lnum)
+		    {
+			wp->w_upd_rows = msg_scrolled - W_WINROW(wp);
+			wp->w_redr_type = REDRAW_TOP;
+		    }
+		    else
+		    {
+			wp->w_redr_type = NOT_VALID;
+#ifdef FEAT_WINDOWS
+			if (W_WINROW(wp) + wp->w_height + W_STATUS_HEIGHT(wp)
+				<= msg_scrolled)
+			    wp->w_redr_status = TRUE;
+#endif
+		    }
+		}
+	    }
+	    redraw_cmdline = TRUE;
+#ifdef FEAT_WINDOWS
+	    redraw_tabline = TRUE;
+#endif
+	}
+	msg_scrolled = 0;
+	need_wait_return = FALSE;
+    }
+
+    /* reset cmdline_row now (may have been changed temporarily) */
+    compute_cmdrow();
+
+    /* Check for changed highlighting */
+    if (need_highlight_changed)
+	highlight_changed();
+
+    if (type == CLEAR)		/* first clear screen */
+    {
+	screenclear();		/* will reset clear_cmdline */
+	type = NOT_VALID;
+    }
+
+    if (clear_cmdline)		/* going to clear cmdline (done below) */
+	check_for_delay(FALSE);
+
+#ifdef FEAT_LINEBREAK
+    /* Force redraw when width of 'number' column changes. */
+    if (curwin->w_redr_type < NOT_VALID
+	   && curwin->w_nrwidth != (curwin->w_p_nu ? number_width(curwin) : 0))
+	curwin->w_redr_type = NOT_VALID;
+#endif
+
+    /*
+     * Only start redrawing if there is really something to do.
+     */
+    if (type == INVERTED)
+	update_curswant();
+    if (curwin->w_redr_type < type
+	    && !((type == VALID
+		    && curwin->w_lines[0].wl_valid
+#ifdef FEAT_DIFF
+		    && curwin->w_topfill == curwin->w_old_topfill
+		    && curwin->w_botfill == curwin->w_old_botfill
+#endif
+		    && curwin->w_topline == curwin->w_lines[0].wl_lnum)
+#ifdef FEAT_VISUAL
+		|| (type == INVERTED
+		    && VIsual_active
+		    && curwin->w_old_cursor_lnum == curwin->w_cursor.lnum
+		    && curwin->w_old_visual_mode == VIsual_mode
+		    && (curwin->w_valid & VALID_VIRTCOL)
+		    && curwin->w_old_curswant == curwin->w_curswant)
+#endif
+		))
+	curwin->w_redr_type = type;
+
+#ifdef FEAT_WINDOWS
+    /* Redraw the tab pages line if needed. */
+    if (redraw_tabline || type >= NOT_VALID)
+	draw_tabline();
+#endif
+
+#ifdef FEAT_SYN_HL
+    /*
+     * Correct stored syntax highlighting info for changes in each displayed
+     * buffer.  Each buffer must only be done once.
+     */
+    FOR_ALL_WINDOWS(wp)
+    {
+	if (wp->w_buffer->b_mod_set)
+	{
+# ifdef FEAT_WINDOWS
+	    win_T	*wwp;
+
+	    /* Check if we already did this buffer. */
+	    for (wwp = firstwin; wwp != wp; wwp = wwp->w_next)
+		if (wwp->w_buffer == wp->w_buffer)
+		    break;
+# endif
+	    if (
+# ifdef FEAT_WINDOWS
+		    wwp == wp &&
+# endif
+		    syntax_present(wp->w_buffer))
+		syn_stack_apply_changes(wp->w_buffer);
+	}
+    }
+#endif
+
+    /*
+     * Go from top to bottom through the windows, redrawing the ones that need
+     * it.
+     */
+#if defined(FEAT_SEARCH_EXTRA) || defined(FEAT_CLIPBOARD)
+    did_one = FALSE;
+#endif
+#ifdef FEAT_SEARCH_EXTRA
+    search_hl.rm.regprog = NULL;
+#endif
+    FOR_ALL_WINDOWS(wp)
+    {
+	if (wp->w_redr_type != 0)
+	{
+	    cursor_off();
+#if defined(FEAT_SEARCH_EXTRA) || defined(FEAT_CLIPBOARD)
+	    if (!did_one)
+	    {
+		did_one = TRUE;
+# ifdef FEAT_SEARCH_EXTRA
+		start_search_hl();
+# endif
+# ifdef FEAT_CLIPBOARD
+		/* When Visual area changed, may have to update selection. */
+		if (clip_star.available && clip_isautosel())
+		    clip_update_selection();
+# endif
+#ifdef FEAT_GUI
+		/* Remove the cursor before starting to do anything, because
+		 * scrolling may make it difficult to redraw the text under
+		 * it. */
+		if (gui.in_use)
+		    gui_undraw_cursor();
+#endif
+	    }
+#endif
+	    win_update(wp);
+	}
+
+#ifdef FEAT_WINDOWS
+	/* redraw status line after the window to minimize cursor movement */
+	if (wp->w_redr_status)
+	{
+	    cursor_off();
+	    win_redr_status(wp);
+	}
+#endif
+    }
+#if defined(FEAT_SEARCH_EXTRA)
+    end_search_hl();
+#endif
+
+#ifdef FEAT_WINDOWS
+    /* Reset b_mod_set flags.  Going through all windows is probably faster
+     * than going through all buffers (there could be many buffers). */
+    for (wp = firstwin; wp != NULL; wp = wp->w_next)
+	wp->w_buffer->b_mod_set = FALSE;
+#else
+	curbuf->b_mod_set = FALSE;
+#endif
+
+    updating_screen = FALSE;
+#ifdef FEAT_GUI
+    gui_may_resize_shell();
+#endif
+
+    /* Clear or redraw the command line.  Done last, because scrolling may
+     * mess up the command line. */
+    if (clear_cmdline || redraw_cmdline)
+	showmode();
+
+    /* May put up an introductory message when not editing a file */
+    if (!did_intro && bufempty()
+	    && curbuf->b_fname == NULL
+#ifdef FEAT_WINDOWS
+	    && firstwin->w_next == NULL
+#endif
+	    && vim_strchr(p_shm, SHM_INTRO) == NULL)
+	intro_message(FALSE);
+    did_intro = TRUE;
+
+#ifdef FEAT_GUI
+    /* Redraw the cursor and update the scrollbars when all screen updating is
+     * done. */
+    if (gui.in_use)
+    {
+	out_flush();	/* required before updating the cursor */
+	if (did_one)
+	    gui_update_cursor(FALSE, FALSE);
+	gui_update_scrollbars(FALSE);
+    }
+#endif
+}
+
+#if defined(FEAT_SIGNS) || defined(FEAT_GUI)
+static void update_prepare __ARGS((void));
+static void update_finish __ARGS((void));
+
+/*
+ * Prepare for updating one or more windows.
+ */
+    static void
+update_prepare()
+{
+    cursor_off();
+    updating_screen = TRUE;
+#ifdef FEAT_GUI
+    /* Remove the cursor before starting to do anything, because scrolling may
+     * make it difficult to redraw the text under it. */
+    if (gui.in_use)
+	gui_undraw_cursor();
+#endif
+#ifdef FEAT_SEARCH_EXTRA
+    start_search_hl();
+#endif
+}
+
+/*
+ * Finish updating one or more windows.
+ */
+    static void
+update_finish()
+{
+    if (redraw_cmdline)
+	showmode();
+
+# ifdef FEAT_SEARCH_EXTRA
+    end_search_hl();
+# endif
+
+    updating_screen = FALSE;
+
+# ifdef FEAT_GUI
+    gui_may_resize_shell();
+
+    /* Redraw the cursor and update the scrollbars when all screen updating is
+     * done. */
+    if (gui.in_use)
+    {
+	out_flush();	/* required before updating the cursor */
+	gui_update_cursor(FALSE, FALSE);
+	gui_update_scrollbars(FALSE);
+    }
+# endif
+}
+#endif
+
+#if defined(FEAT_SIGNS) || defined(PROTO)
+    void
+update_debug_sign(buf, lnum)
+    buf_T	*buf;
+    linenr_T	lnum;
+{
+    win_T	*wp;
+    int		doit = FALSE;
+
+# ifdef FEAT_FOLDING
+    win_foldinfo.fi_level = 0;
+# endif
+
+    /* update/delete a specific mark */
+    FOR_ALL_WINDOWS(wp)
+    {
+	if (buf != NULL && lnum > 0)
+	{
+	    if (wp->w_buffer == buf && lnum >= wp->w_topline
+						      && lnum < wp->w_botline)
+	    {
+		if (wp->w_redraw_top == 0 || wp->w_redraw_top > lnum)
+		    wp->w_redraw_top = lnum;
+		if (wp->w_redraw_bot == 0 || wp->w_redraw_bot < lnum)
+		    wp->w_redraw_bot = lnum;
+		redraw_win_later(wp, VALID);
+	    }
+	}
+	else
+	    redraw_win_later(wp, VALID);
+	if (wp->w_redr_type != 0)
+	    doit = TRUE;
+    }
+
+    if (!doit)
+	return;
+
+    /* update all windows that need updating */
+    update_prepare();
+
+# ifdef FEAT_WINDOWS
+    for (wp = firstwin; wp; wp = wp->w_next)
+    {
+	if (wp->w_redr_type != 0)
+	    win_update(wp);
+	if (wp->w_redr_status)
+	    win_redr_status(wp);
+    }
+# else
+    if (curwin->w_redr_type != 0)
+	win_update(curwin);
+# endif
+
+    update_finish();
+}
+#endif
+
+
+#if defined(FEAT_GUI) || defined(PROTO)
+/*
+ * Update a single window, its status line and maybe the command line msg.
+ * Used for the GUI scrollbar.
+ */
+    void
+updateWindow(wp)
+    win_T	*wp;
+{
+    update_prepare();
+
+#ifdef FEAT_CLIPBOARD
+    /* When Visual area changed, may have to update selection. */
+    if (clip_star.available && clip_isautosel())
+	clip_update_selection();
+#endif
+
+    win_update(wp);
+
+#ifdef FEAT_WINDOWS
+    /* When the screen was cleared redraw the tab pages line. */
+    if (redraw_tabline)
+	draw_tabline();
+
+    if (wp->w_redr_status
+# ifdef FEAT_CMDL_INFO
+	    || p_ru
+# endif
+# ifdef FEAT_STL_OPT
+	    || *p_stl != NUL || *wp->w_p_stl != NUL
+# endif
+	    )
+	win_redr_status(wp);
+#endif
+
+    update_finish();
+}
+#endif
+
+/*
+ * Update a single window.
+ *
+ * This may cause the windows below it also to be redrawn (when clearing the
+ * screen or scrolling lines).
+ *
+ * How the window is redrawn depends on wp->w_redr_type.  Each type also
+ * implies the one below it.
+ * NOT_VALID	redraw the whole window
+ * SOME_VALID	redraw the whole window but do scroll when possible
+ * REDRAW_TOP	redraw the top w_upd_rows window lines, otherwise like VALID
+ * INVERTED	redraw the changed part of the Visual area
+ * INVERTED_ALL	redraw the whole Visual area
+ * VALID	1. scroll up/down to adjust for a changed w_topline
+ *		2. update lines at the top when scrolled down
+ *		3. redraw changed text:
+ *		   - if wp->w_buffer->b_mod_set set, update lines between
+ *		     b_mod_top and b_mod_bot.
+ *		   - if wp->w_redraw_top non-zero, redraw lines between
+ *		     wp->w_redraw_top and wp->w_redr_bot.
+ *		   - continue redrawing when syntax status is invalid.
+ *		4. if scrolled up, update lines at the bottom.
+ * This results in three areas that may need updating:
+ * top:	from first row to top_end (when scrolled down)
+ * mid: from mid_start to mid_end (update inversion or changed text)
+ * bot: from bot_start to last row (when scrolled up)
+ */
+    static void
+win_update(wp)
+    win_T	*wp;
+{
+    buf_T	*buf = wp->w_buffer;
+    int		type;
+    int		top_end = 0;	/* Below last row of the top area that needs
+				   updating.  0 when no top area updating. */
+    int		mid_start = 999;/* first row of the mid area that needs
+				   updating.  999 when no mid area updating. */
+    int		mid_end = 0;	/* Below last row of the mid area that needs
+				   updating.  0 when no mid area updating. */
+    int		bot_start = 999;/* first row of the bot area that needs
+				   updating.  999 when no bot area updating */
+#ifdef FEAT_VISUAL
+    int		scrolled_down = FALSE;	/* TRUE when scrolled down when
+					   w_topline got smaller a bit */
+#endif
+#ifdef FEAT_SEARCH_EXTRA
+    int		top_to_mod = FALSE;    /* redraw above mod_top */
+#endif
+
+    int		row;		/* current window row to display */
+    linenr_T	lnum;		/* current buffer lnum to display */
+    int		idx;		/* current index in w_lines[] */
+    int		srow;		/* starting row of the current line */
+
+    int		eof = FALSE;	/* if TRUE, we hit the end of the file */
+    int		didline = FALSE; /* if TRUE, we finished the last line */
+    int		i;
+    long	j;
+    static int	recursive = FALSE;	/* being called recursively */
+    int		old_botline = wp->w_botline;
+#ifdef FEAT_FOLDING
+    long	fold_count;
+#endif
+#ifdef FEAT_SYN_HL
+    /* remember what happened to the previous line, to know if
+     * check_visual_highlight() can be used */
+#define DID_NONE 1	/* didn't update a line */
+#define DID_LINE 2	/* updated a normal line */
+#define DID_FOLD 3	/* updated a folded line */
+    int		did_update = DID_NONE;
+    linenr_T	syntax_last_parsed = 0;		/* last parsed text line */
+#endif
+    linenr_T	mod_top = 0;
+    linenr_T	mod_bot = 0;
+#if defined(FEAT_SYN_HL) || defined(FEAT_SEARCH_EXTRA)
+    int		save_got_int;
+#endif
+
+    type = wp->w_redr_type;
+
+    if (type == NOT_VALID)
+    {
+#ifdef FEAT_WINDOWS
+	wp->w_redr_status = TRUE;
+#endif
+	wp->w_lines_valid = 0;
+    }
+
+    /* Window is zero-height: nothing to draw. */
+    if (wp->w_height == 0)
+    {
+	wp->w_redr_type = 0;
+	return;
+    }
+
+#ifdef FEAT_VERTSPLIT
+    /* Window is zero-width: Only need to draw the separator. */
+    if (wp->w_width == 0)
+    {
+	/* draw the vertical separator right of this window */
+	draw_vsep_win(wp, 0);
+	wp->w_redr_type = 0;
+	return;
+    }
+#endif
+
+#ifdef FEAT_SEARCH_EXTRA
+    /* Setup for ":match" and 'hlsearch' highlighting.  Disable any previous
+     * match */
+    for (i = 0; i < 3; ++i)
+    {
+	match_hl[i].rm = wp->w_match[i];
+	if (wp->w_match_id[i] == 0)
+	    match_hl[i].attr = 0;
+	else
+	    match_hl[i].attr = syn_id2attr(wp->w_match_id[i]);
+	match_hl[i].buf = buf;
+	match_hl[i].lnum = 0;
+	match_hl[i].first_lnum = 0;
+    }
+    search_hl.buf = buf;
+    search_hl.lnum = 0;
+    search_hl.first_lnum = 0;
+#endif
+
+#ifdef FEAT_LINEBREAK
+    /* Force redraw when width of 'number' column changes. */
+    i = wp->w_p_nu ? number_width(wp) : 0;
+    if (wp->w_nrwidth != i)
+    {
+	type = NOT_VALID;
+	wp->w_nrwidth = i;
+    }
+    else
+#endif
+
+    if (buf->b_mod_set && buf->b_mod_xlines != 0 && wp->w_redraw_top != 0)
+    {
+	/*
+	 * When there are both inserted/deleted lines and specific lines to be
+	 * redrawn, w_redraw_top and w_redraw_bot may be invalid, just redraw
+	 * everything (only happens when redrawing is off for while).
+	 */
+	type = NOT_VALID;
+    }
+    else
+    {
+	/*
+	 * Set mod_top to the first line that needs displaying because of
+	 * changes.  Set mod_bot to the first line after the changes.
+	 */
+	mod_top = wp->w_redraw_top;
+	if (wp->w_redraw_bot != 0)
+	    mod_bot = wp->w_redraw_bot + 1;
+	else
+	    mod_bot = 0;
+	wp->w_redraw_top = 0;	/* reset for next time */
+	wp->w_redraw_bot = 0;
+	if (buf->b_mod_set)
+	{
+	    if (mod_top == 0 || mod_top > buf->b_mod_top)
+	    {
+		mod_top = buf->b_mod_top;
+#ifdef FEAT_SYN_HL
+		/* Need to redraw lines above the change that may be included
+		 * in a pattern match. */
+		if (syntax_present(buf))
+		{
+		    mod_top -= buf->b_syn_sync_linebreaks;
+		    if (mod_top < 1)
+			mod_top = 1;
+		}
+#endif
+	    }
+	    if (mod_bot == 0 || mod_bot < buf->b_mod_bot)
+		mod_bot = buf->b_mod_bot;
+
+#ifdef FEAT_SEARCH_EXTRA
+	    /* When 'hlsearch' is on and using a multi-line search pattern, a
+	     * change in one line may make the Search highlighting in a
+	     * previous line invalid.  Simple solution: redraw all visible
+	     * lines above the change.
+	     * Same for a ":match" pattern.
+	     */
+	    if (search_hl.rm.regprog != NULL
+					&& re_multiline(search_hl.rm.regprog))
+		top_to_mod = TRUE;
+	    else
+		for (i = 0; i < 3; ++i)
+		    if (match_hl[i].rm.regprog != NULL
+				      && re_multiline(match_hl[i].rm.regprog))
+		    {
+			top_to_mod = TRUE;
+			break;
+		    }
+#endif
+	}
+#ifdef FEAT_FOLDING
+	if (mod_top != 0 && hasAnyFolding(wp))
+	{
+	    linenr_T	lnumt, lnumb;
+
+	    /*
+	     * A change in a line can cause lines above it to become folded or
+	     * unfolded.  Find the top most buffer line that may be affected.
+	     * If the line was previously folded and displayed, get the first
+	     * line of that fold.  If the line is folded now, get the first
+	     * folded line.  Use the minimum of these two.
+	     */
+
+	    /* Find last valid w_lines[] entry above mod_top.  Set lnumt to
+	     * the line below it.  If there is no valid entry, use w_topline.
+	     * Find the first valid w_lines[] entry below mod_bot.  Set lnumb
+	     * to this line.  If there is no valid entry, use MAXLNUM. */
+	    lnumt = wp->w_topline;
+	    lnumb = MAXLNUM;
+	    for (i = 0; i < wp->w_lines_valid; ++i)
+		if (wp->w_lines[i].wl_valid)
+		{
+		    if (wp->w_lines[i].wl_lastlnum < mod_top)
+			lnumt = wp->w_lines[i].wl_lastlnum + 1;
+		    if (lnumb == MAXLNUM && wp->w_lines[i].wl_lnum >= mod_bot)
+		    {
+			lnumb = wp->w_lines[i].wl_lnum;
+			/* When there is a fold column it might need updating
+			 * in the next line ("J" just above an open fold). */
+			if (wp->w_p_fdc > 0)
+			    ++lnumb;
+		    }
+		}
+
+	    (void)hasFoldingWin(wp, mod_top, &mod_top, NULL, TRUE, NULL);
+	    if (mod_top > lnumt)
+		mod_top = lnumt;
+
+	    /* Now do the same for the bottom line (one above mod_bot). */
+	    --mod_bot;
+	    (void)hasFoldingWin(wp, mod_bot, NULL, &mod_bot, TRUE, NULL);
+	    ++mod_bot;
+	    if (mod_bot < lnumb)
+		mod_bot = lnumb;
+	}
+#endif
+
+	/* When a change starts above w_topline and the end is below
+	 * w_topline, start redrawing at w_topline.
+	 * If the end of the change is above w_topline: do like no change was
+	 * made, but redraw the first line to find changes in syntax. */
+	if (mod_top != 0 && mod_top < wp->w_topline)
+	{
+	    if (mod_bot > wp->w_topline)
+		mod_top = wp->w_topline;
+#ifdef FEAT_SYN_HL
+	    else if (syntax_present(buf))
+		top_end = 1;
+#endif
+	}
+
+	/* When line numbers are displayed need to redraw all lines below
+	 * inserted/deleted lines. */
+	if (mod_top != 0 && buf->b_mod_xlines != 0 && wp->w_p_nu)
+	    mod_bot = MAXLNUM;
+    }
+
+    /*
+     * When only displaying the lines at the top, set top_end.  Used when
+     * window has scrolled down for msg_scrolled.
+     */
+    if (type == REDRAW_TOP)
+    {
+	j = 0;
+	for (i = 0; i < wp->w_lines_valid; ++i)
+	{
+	    j += wp->w_lines[i].wl_size;
+	    if (j >= wp->w_upd_rows)
+	    {
+		top_end = j;
+		break;
+	    }
+	}
+	if (top_end == 0)
+	    /* not found (cannot happen?): redraw everything */
+	    type = NOT_VALID;
+	else
+	    /* top area defined, the rest is VALID */
+	    type = VALID;
+    }
+
+    /*
+     * If there are no changes on the screen that require a complete redraw,
+     * handle three cases:
+     * 1: we are off the top of the screen by a few lines: scroll down
+     * 2: wp->w_topline is below wp->w_lines[0].wl_lnum: may scroll up
+     * 3: wp->w_topline is wp->w_lines[0].wl_lnum: find first entry in
+     *    w_lines[] that needs updating.
+     */
+    if ((type == VALID || type == SOME_VALID
+				  || type == INVERTED || type == INVERTED_ALL)
+#ifdef FEAT_DIFF
+	    && !wp->w_botfill && !wp->w_old_botfill
+#endif
+	    )
+    {
+	if (mod_top != 0 && wp->w_topline == mod_top)
+	{
+	    /*
+	     * w_topline is the first changed line, the scrolling will be done
+	     * further down.
+	     */
+	}
+	else if (wp->w_lines[0].wl_valid
+		&& (wp->w_topline < wp->w_lines[0].wl_lnum
+#ifdef FEAT_DIFF
+		    || (wp->w_topline == wp->w_lines[0].wl_lnum
+			&& wp->w_topfill > wp->w_old_topfill)
+#endif
+		   ))
+	{
+	    /*
+	     * New topline is above old topline: May scroll down.
+	     */
+#ifdef FEAT_FOLDING
+	    if (hasAnyFolding(wp))
+	    {
+		linenr_T ln;
+
+		/* count the number of lines we are off, counting a sequence
+		 * of folded lines as one */
+		j = 0;
+		for (ln = wp->w_topline; ln < wp->w_lines[0].wl_lnum; ++ln)
+		{
+		    ++j;
+		    if (j >= wp->w_height - 2)
+			break;
+		    (void)hasFoldingWin(wp, ln, NULL, &ln, TRUE, NULL);
+		}
+	    }
+	    else
+#endif
+		j = wp->w_lines[0].wl_lnum - wp->w_topline;
+	    if (j < wp->w_height - 2)		/* not too far off */
+	    {
+		i = plines_m_win(wp, wp->w_topline, wp->w_lines[0].wl_lnum - 1);
+#ifdef FEAT_DIFF
+		/* insert extra lines for previously invisible filler lines */
+		if (wp->w_lines[0].wl_lnum != wp->w_topline)
+		    i += diff_check_fill(wp, wp->w_lines[0].wl_lnum)
+							  - wp->w_old_topfill;
+#endif
+		if (i < wp->w_height - 2)	/* less than a screen off */
+		{
+		    /*
+		     * Try to insert the correct number of lines.
+		     * If not the last window, delete the lines at the bottom.
+		     * win_ins_lines may fail when the terminal can't do it.
+		     */
+		    if (i > 0)
+			check_for_delay(FALSE);
+		    if (win_ins_lines(wp, 0, i, FALSE, wp == firstwin) == OK)
+		    {
+			if (wp->w_lines_valid != 0)
+			{
+			    /* Need to update rows that are new, stop at the
+			     * first one that scrolled down. */
+			    top_end = i;
+#ifdef FEAT_VISUAL
+			    scrolled_down = TRUE;
+#endif
+
+			    /* Move the entries that were scrolled, disable
+			     * the entries for the lines to be redrawn. */
+			    if ((wp->w_lines_valid += j) > wp->w_height)
+				wp->w_lines_valid = wp->w_height;
+			    for (idx = wp->w_lines_valid; idx - j >= 0; idx--)
+				wp->w_lines[idx] = wp->w_lines[idx - j];
+			    while (idx >= 0)
+				wp->w_lines[idx--].wl_valid = FALSE;
+			}
+		    }
+		    else
+			mid_start = 0;		/* redraw all lines */
+		}
+		else
+		    mid_start = 0;		/* redraw all lines */
+	    }
+	    else
+		mid_start = 0;		/* redraw all lines */
+	}
+	else
+	{
+	    /*
+	     * New topline is at or below old topline: May scroll up.
+	     * When topline didn't change, find first entry in w_lines[] that
+	     * needs updating.
+	     */
+
+	    /* try to find wp->w_topline in wp->w_lines[].wl_lnum */
+	    j = -1;
+	    row = 0;
+	    for (i = 0; i < wp->w_lines_valid; i++)
+	    {
+		if (wp->w_lines[i].wl_valid
+			&& wp->w_lines[i].wl_lnum == wp->w_topline)
+		{
+		    j = i;
+		    break;
+		}
+		row += wp->w_lines[i].wl_size;
+	    }
+	    if (j == -1)
+	    {
+		/* if wp->w_topline is not in wp->w_lines[].wl_lnum redraw all
+		 * lines */
+		mid_start = 0;
+	    }
+	    else
+	    {
+		/*
+		 * Try to delete the correct number of lines.
+		 * wp->w_topline is at wp->w_lines[i].wl_lnum.
+		 */
+#ifdef FEAT_DIFF
+		/* If the topline didn't change, delete old filler lines,
+		 * otherwise delete filler lines of the new topline... */
+		if (wp->w_lines[0].wl_lnum == wp->w_topline)
+		    row += wp->w_old_topfill;
+		else
+		    row += diff_check_fill(wp, wp->w_topline);
+		/* ... but don't delete new filler lines. */
+		row -= wp->w_topfill;
+#endif
+		if (row > 0)
+		{
+		    check_for_delay(FALSE);
+		    if (win_del_lines(wp, 0, row, FALSE, wp == firstwin) == OK)
+			bot_start = wp->w_height - row;
+		    else
+			mid_start = 0;		/* redraw all lines */
+		}
+		if ((row == 0 || bot_start < 999) && wp->w_lines_valid != 0)
+		{
+		    /*
+		     * Skip the lines (below the deleted lines) that are still
+		     * valid and don't need redrawing.	Copy their info
+		     * upwards, to compensate for the deleted lines.  Set
+		     * bot_start to the first row that needs redrawing.
+		     */
+		    bot_start = 0;
+		    idx = 0;
+		    for (;;)
+		    {
+			wp->w_lines[idx] = wp->w_lines[j];
+			/* stop at line that didn't fit, unless it is still
+			 * valid (no lines deleted) */
+			if (row > 0 && bot_start + row
+				 + (int)wp->w_lines[j].wl_size > wp->w_height)
+			{
+			    wp->w_lines_valid = idx + 1;
+			    break;
+			}
+			bot_start += wp->w_lines[idx++].wl_size;
+
+			/* stop at the last valid entry in w_lines[].wl_size */
+			if (++j >= wp->w_lines_valid)
+			{
+			    wp->w_lines_valid = idx;
+			    break;
+			}
+		    }
+#ifdef FEAT_DIFF
+		    /* Correct the first entry for filler lines at the top
+		     * when it won't get updated below. */
+		    if (wp->w_p_diff && bot_start > 0)
+			wp->w_lines[0].wl_size =
+			    plines_win_nofill(wp, wp->w_topline, TRUE)
+							      + wp->w_topfill;
+#endif
+		}
+	    }
+	}
+
+	/* When starting redraw in the first line, redraw all lines.  When
+	 * there is only one window it's probably faster to clear the screen
+	 * first. */
+	if (mid_start == 0)
+	{
+	    mid_end = wp->w_height;
+	    if (lastwin == firstwin)
+	    {
+		screenclear();
+#ifdef FEAT_WINDOWS
+		/* The screen was cleared, redraw the tab pages line. */
+		if (redraw_tabline)
+		    draw_tabline();
+#endif
+	    }
+	}
+    }
+    else
+    {
+	/* Not VALID or INVERTED: redraw all lines. */
+	mid_start = 0;
+	mid_end = wp->w_height;
+    }
+
+    if (type == SOME_VALID)
+    {
+	/* SOME_VALID: redraw all lines. */
+	mid_start = 0;
+	mid_end = wp->w_height;
+	type = NOT_VALID;
+    }
+
+#ifdef FEAT_VISUAL
+    /* check if we are updating or removing the inverted part */
+    if ((VIsual_active && buf == curwin->w_buffer)
+	    || (wp->w_old_cursor_lnum != 0 && type != NOT_VALID))
+    {
+	linenr_T    from, to;
+
+	if (VIsual_active)
+	{
+	    if (VIsual_active
+		    && (VIsual_mode != wp->w_old_visual_mode
+			|| type == INVERTED_ALL))
+	    {
+		/*
+		 * If the type of Visual selection changed, redraw the whole
+		 * selection.  Also when the ownership of the X selection is
+		 * gained or lost.
+		 */
+		if (curwin->w_cursor.lnum < VIsual.lnum)
+		{
+		    from = curwin->w_cursor.lnum;
+		    to = VIsual.lnum;
+		}
+		else
+		{
+		    from = VIsual.lnum;
+		    to = curwin->w_cursor.lnum;
+		}
+		/* redraw more when the cursor moved as well */
+		if (wp->w_old_cursor_lnum < from)
+		    from = wp->w_old_cursor_lnum;
+		if (wp->w_old_cursor_lnum > to)
+		    to = wp->w_old_cursor_lnum;
+		if (wp->w_old_visual_lnum < from)
+		    from = wp->w_old_visual_lnum;
+		if (wp->w_old_visual_lnum > to)
+		    to = wp->w_old_visual_lnum;
+	    }
+	    else
+	    {
+		/*
+		 * Find the line numbers that need to be updated: The lines
+		 * between the old cursor position and the current cursor
+		 * position.  Also check if the Visual position changed.
+		 */
+		if (curwin->w_cursor.lnum < wp->w_old_cursor_lnum)
+		{
+		    from = curwin->w_cursor.lnum;
+		    to = wp->w_old_cursor_lnum;
+		}
+		else
+		{
+		    from = wp->w_old_cursor_lnum;
+		    to = curwin->w_cursor.lnum;
+		    if (from == 0)	/* Visual mode just started */
+			from = to;
+		}
+
+		if (VIsual.lnum != wp->w_old_visual_lnum
+					|| VIsual.col != wp->w_old_visual_col)
+		{
+		    if (wp->w_old_visual_lnum < from
+						&& wp->w_old_visual_lnum != 0)
+			from = wp->w_old_visual_lnum;
+		    if (wp->w_old_visual_lnum > to)
+			to = wp->w_old_visual_lnum;
+		    if (VIsual.lnum < from)
+			from = VIsual.lnum;
+		    if (VIsual.lnum > to)
+			to = VIsual.lnum;
+		}
+	    }
+
+	    /*
+	     * If in block mode and changed column or curwin->w_curswant:
+	     * update all lines.
+	     * First compute the actual start and end column.
+	     */
+	    if (VIsual_mode == Ctrl_V)
+	    {
+		colnr_T	fromc, toc;
+
+		getvcols(wp, &VIsual, &curwin->w_cursor, &fromc, &toc);
+		++toc;
+		if (curwin->w_curswant == MAXCOL)
+		    toc = MAXCOL;
+
+		if (fromc != wp->w_old_cursor_fcol
+			|| toc != wp->w_old_cursor_lcol)
+		{
+		    if (from > VIsual.lnum)
+			from = VIsual.lnum;
+		    if (to < VIsual.lnum)
+			to = VIsual.lnum;
+		}
+		wp->w_old_cursor_fcol = fromc;
+		wp->w_old_cursor_lcol = toc;
+	    }
+	}
+	else
+	{
+	    /* Use the line numbers of the old Visual area. */
+	    if (wp->w_old_cursor_lnum < wp->w_old_visual_lnum)
+	    {
+		from = wp->w_old_cursor_lnum;
+		to = wp->w_old_visual_lnum;
+	    }
+	    else
+	    {
+		from = wp->w_old_visual_lnum;
+		to = wp->w_old_cursor_lnum;
+	    }
+	}
+
+	/*
+	 * There is no need to update lines above the top of the window.
+	 */
+	if (from < wp->w_topline)
+	    from = wp->w_topline;
+
+	/*
+	 * If we know the value of w_botline, use it to restrict the update to
+	 * the lines that are visible in the window.
+	 */
+	if (wp->w_valid & VALID_BOTLINE)
+	{
+	    if (from >= wp->w_botline)
+		from = wp->w_botline - 1;
+	    if (to >= wp->w_botline)
+		to = wp->w_botline - 1;
+	}
+
+	/*
+	 * Find the minimal part to be updated.
+	 * Watch out for scrolling that made entries in w_lines[] invalid.
+	 * E.g., CTRL-U makes the first half of w_lines[] invalid and sets
+	 * top_end; need to redraw from top_end to the "to" line.
+	 * A middle mouse click with a Visual selection may change the text
+	 * above the Visual area and reset wl_valid, do count these for
+	 * mid_end (in srow).
+	 */
+	if (mid_start > 0)
+	{
+	    lnum = wp->w_topline;
+	    idx = 0;
+	    srow = 0;
+	    if (scrolled_down)
+		mid_start = top_end;
+	    else
+		mid_start = 0;
+	    while (lnum < from && idx < wp->w_lines_valid)	/* find start */
+	    {
+		if (wp->w_lines[idx].wl_valid)
+		    mid_start += wp->w_lines[idx].wl_size;
+		else if (!scrolled_down)
+		    srow += wp->w_lines[idx].wl_size;
+		++idx;
+# ifdef FEAT_FOLDING
+		if (idx < wp->w_lines_valid && wp->w_lines[idx].wl_valid)
+		    lnum = wp->w_lines[idx].wl_lnum;
+		else
+# endif
+		    ++lnum;
+	    }
+	    srow += mid_start;
+	    mid_end = wp->w_height;
+	    for ( ; idx < wp->w_lines_valid; ++idx)		/* find end */
+	    {
+		if (wp->w_lines[idx].wl_valid
+			&& wp->w_lines[idx].wl_lnum >= to + 1)
+		{
+		    /* Only update until first row of this line */
+		    mid_end = srow;
+		    break;
+		}
+		srow += wp->w_lines[idx].wl_size;
+	    }
+	}
+    }
+
+    if (VIsual_active && buf == curwin->w_buffer)
+    {
+	wp->w_old_visual_mode = VIsual_mode;
+	wp->w_old_cursor_lnum = curwin->w_cursor.lnum;
+	wp->w_old_visual_lnum = VIsual.lnum;
+	wp->w_old_visual_col = VIsual.col;
+	wp->w_old_curswant = curwin->w_curswant;
+    }
+    else
+    {
+	wp->w_old_visual_mode = 0;
+	wp->w_old_cursor_lnum = 0;
+	wp->w_old_visual_lnum = 0;
+	wp->w_old_visual_col = 0;
+    }
+#endif /* FEAT_VISUAL */
+
+#if defined(FEAT_SYN_HL) || defined(FEAT_SEARCH_EXTRA)
+    /* reset got_int, otherwise regexp won't work */
+    save_got_int = got_int;
+    got_int = 0;
+#endif
+#ifdef FEAT_FOLDING
+    win_foldinfo.fi_level = 0;
+#endif
+
+    /*
+     * Update all the window rows.
+     */
+    idx = 0;		/* first entry in w_lines[].wl_size */
+    row = 0;
+    srow = 0;
+    lnum = wp->w_topline;	/* first line shown in window */
+    for (;;)
+    {
+	/* stop updating when reached the end of the window (check for _past_
+	 * the end of the window is at the end of the loop) */
+	if (row == wp->w_height)
+	{
+	    didline = TRUE;
+	    break;
+	}
+
+	/* stop updating when hit the end of the file */
+	if (lnum > buf->b_ml.ml_line_count)
+	{
+	    eof = TRUE;
+	    break;
+	}
+
+	/* Remember the starting row of the line that is going to be dealt
+	 * with.  It is used further down when the line doesn't fit. */
+	srow = row;
+
+	/*
+	 * Update a line when it is in an area that needs updating, when it
+	 * has changes or w_lines[idx] is invalid.
+	 * bot_start may be halfway a wrapped line after using
+	 * win_del_lines(), check if the current line includes it.
+	 * When syntax folding is being used, the saved syntax states will
+	 * already have been updated, we can't see where the syntax state is
+	 * the same again, just update until the end of the window.
+	 */
+	if (row < top_end
+		|| (row >= mid_start && row < mid_end)
+#ifdef FEAT_SEARCH_EXTRA
+		|| top_to_mod
+#endif
+		|| idx >= wp->w_lines_valid
+		|| (row + wp->w_lines[idx].wl_size > bot_start)
+		|| (mod_top != 0
+		    && (lnum == mod_top
+			|| (lnum >= mod_top
+			    && (lnum < mod_bot
+#ifdef FEAT_SYN_HL
+				|| did_update == DID_FOLD
+				|| (did_update == DID_LINE
+				    && syntax_present(buf)
+				    && (
+# ifdef FEAT_FOLDING
+					(foldmethodIsSyntax(wp)
+						      && hasAnyFolding(wp)) ||
+# endif
+					syntax_check_changed(lnum)))
+#endif
+				)))))
+	{
+#ifdef FEAT_SEARCH_EXTRA
+	    if (lnum == mod_top)
+		top_to_mod = FALSE;
+#endif
+
+	    /*
+	     * When at start of changed lines: May scroll following lines
+	     * up or down to minimize redrawing.
+	     * Don't do this when the change continues until the end.
+	     * Don't scroll when dollar_vcol is non-zero, keep the "$".
+	     */
+	    if (lnum == mod_top
+		    && mod_bot != MAXLNUM
+		    && !(dollar_vcol != 0 && mod_bot == mod_top + 1))
+	    {
+		int		old_rows = 0;
+		int		new_rows = 0;
+		int		xtra_rows;
+		linenr_T	l;
+
+		/* Count the old number of window rows, using w_lines[], which
+		 * should still contain the sizes for the lines as they are
+		 * currently displayed. */
+		for (i = idx; i < wp->w_lines_valid; ++i)
+		{
+		    /* Only valid lines have a meaningful wl_lnum.  Invalid
+		     * lines are part of the changed area. */
+		    if (wp->w_lines[i].wl_valid
+			    && wp->w_lines[i].wl_lnum == mod_bot)
+			break;
+		    old_rows += wp->w_lines[i].wl_size;
+#ifdef FEAT_FOLDING
+		    if (wp->w_lines[i].wl_valid
+			    && wp->w_lines[i].wl_lastlnum + 1 == mod_bot)
+		    {
+			/* Must have found the last valid entry above mod_bot.
+			 * Add following invalid entries. */
+			++i;
+			while (i < wp->w_lines_valid
+						  && !wp->w_lines[i].wl_valid)
+			    old_rows += wp->w_lines[i++].wl_size;
+			break;
+		    }
+#endif
+		}
+
+		if (i >= wp->w_lines_valid)
+		{
+		    /* We can't find a valid line below the changed lines,
+		     * need to redraw until the end of the window.
+		     * Inserting/deleting lines has no use. */
+		    bot_start = 0;
+		}
+		else
+		{
+		    /* Able to count old number of rows: Count new window
+		     * rows, and may insert/delete lines */
+		    j = idx;
+		    for (l = lnum; l < mod_bot; ++l)
+		    {
+#ifdef FEAT_FOLDING
+			if (hasFoldingWin(wp, l, NULL, &l, TRUE, NULL))
+			    ++new_rows;
+			else
+#endif
+#ifdef FEAT_DIFF
+			    if (l == wp->w_topline)
+			    new_rows += plines_win_nofill(wp, l, TRUE)
+							      + wp->w_topfill;
+			else
+#endif
+			    new_rows += plines_win(wp, l, TRUE);
+			++j;
+			if (new_rows > wp->w_height - row - 2)
+			{
+			    /* it's getting too much, must redraw the rest */
+			    new_rows = 9999;
+			    break;
+			}
+		    }
+		    xtra_rows = new_rows - old_rows;
+		    if (xtra_rows < 0)
+		    {
+			/* May scroll text up.  If there is not enough
+			 * remaining text or scrolling fails, must redraw the
+			 * rest.  If scrolling works, must redraw the text
+			 * below the scrolled text. */
+			if (row - xtra_rows >= wp->w_height - 2)
+			    mod_bot = MAXLNUM;
+			else
+			{
+			    check_for_delay(FALSE);
+			    if (win_del_lines(wp, row,
+					    -xtra_rows, FALSE, FALSE) == FAIL)
+				mod_bot = MAXLNUM;
+			    else
+				bot_start = wp->w_height + xtra_rows;
+			}
+		    }
+		    else if (xtra_rows > 0)
+		    {
+			/* May scroll text down.  If there is not enough
+			 * remaining text of scrolling fails, must redraw the
+			 * rest. */
+			if (row + xtra_rows >= wp->w_height - 2)
+			    mod_bot = MAXLNUM;
+			else
+			{
+			    check_for_delay(FALSE);
+			    if (win_ins_lines(wp, row + old_rows,
+					     xtra_rows, FALSE, FALSE) == FAIL)
+				mod_bot = MAXLNUM;
+			    else if (top_end > row + old_rows)
+				/* Scrolled the part at the top that requires
+				 * updating down. */
+				top_end += xtra_rows;
+			}
+		    }
+
+		    /* When not updating the rest, may need to move w_lines[]
+		     * entries. */
+		    if (mod_bot != MAXLNUM && i != j)
+		    {
+			if (j < i)
+			{
+			    int x = row + new_rows;
+
+			    /* move entries in w_lines[] upwards */
+			    for (;;)
+			    {
+				/* stop at last valid entry in w_lines[] */
+				if (i >= wp->w_lines_valid)
+				{
+				    wp->w_lines_valid = j;
+				    break;
+				}
+				wp->w_lines[j] = wp->w_lines[i];
+				/* stop at a line that won't fit */
+				if (x + (int)wp->w_lines[j].wl_size
+							   > wp->w_height)
+				{
+				    wp->w_lines_valid = j + 1;
+				    break;
+				}
+				x += wp->w_lines[j++].wl_size;
+				++i;
+			    }
+			    if (bot_start > x)
+				bot_start = x;
+			}
+			else /* j > i */
+			{
+			    /* move entries in w_lines[] downwards */
+			    j -= i;
+			    wp->w_lines_valid += j;
+			    if (wp->w_lines_valid > wp->w_height)
+				wp->w_lines_valid = wp->w_height;
+			    for (i = wp->w_lines_valid; i - j >= idx; --i)
+				wp->w_lines[i] = wp->w_lines[i - j];
+
+			    /* The w_lines[] entries for inserted lines are
+			     * now invalid, but wl_size may be used above.
+			     * Reset to zero. */
+			    while (i >= idx)
+			    {
+				wp->w_lines[i].wl_size = 0;
+				wp->w_lines[i--].wl_valid = FALSE;
+			    }
+			}
+		    }
+		}
+	    }
+
+#ifdef FEAT_FOLDING
+	    /*
+	     * When lines are folded, display one line for all of them.
+	     * Otherwise, display normally (can be several display lines when
+	     * 'wrap' is on).
+	     */
+	    fold_count = foldedCount(wp, lnum, &win_foldinfo);
+	    if (fold_count != 0)
+	    {
+		fold_line(wp, fold_count, &win_foldinfo, lnum, row);
+		++row;
+		--fold_count;
+		wp->w_lines[idx].wl_folded = TRUE;
+		wp->w_lines[idx].wl_lastlnum = lnum + fold_count;
+# ifdef FEAT_SYN_HL
+		did_update = DID_FOLD;
+# endif
+	    }
+	    else
+#endif
+	    if (idx < wp->w_lines_valid
+		    && wp->w_lines[idx].wl_valid
+		    && wp->w_lines[idx].wl_lnum == lnum
+		    && lnum > wp->w_topline
+		    && !(dy_flags & DY_LASTLINE)
+		    && srow + wp->w_lines[idx].wl_size > wp->w_height
+#ifdef FEAT_DIFF
+		    && diff_check_fill(wp, lnum) == 0
+#endif
+		    )
+	    {
+		/* This line is not going to fit.  Don't draw anything here,
+		 * will draw "@  " lines below. */
+		row = wp->w_height + 1;
+	    }
+	    else
+	    {
+#ifdef FEAT_SEARCH_EXTRA
+		prepare_search_hl(wp, lnum);
+#endif
+#ifdef FEAT_SYN_HL
+		/* Let the syntax stuff know we skipped a few lines. */
+		if (syntax_last_parsed != 0 && syntax_last_parsed + 1 < lnum
+						       && syntax_present(buf))
+		    syntax_end_parsing(syntax_last_parsed + 1);
+#endif
+
+		/*
+		 * Display one line.
+		 */
+		row = win_line(wp, lnum, srow, wp->w_height, mod_top == 0);
+
+#ifdef FEAT_FOLDING
+		wp->w_lines[idx].wl_folded = FALSE;
+		wp->w_lines[idx].wl_lastlnum = lnum;
+#endif
+#ifdef FEAT_SYN_HL
+		did_update = DID_LINE;
+		syntax_last_parsed = lnum;
+#endif
+	    }
+
+	    wp->w_lines[idx].wl_lnum = lnum;
+	    wp->w_lines[idx].wl_valid = TRUE;
+	    if (row > wp->w_height)	/* past end of screen */
+	    {
+		/* we may need the size of that too long line later on */
+		if (dollar_vcol == 0)
+		    wp->w_lines[idx].wl_size = plines_win(wp, lnum, TRUE);
+		++idx;
+		break;
+	    }
+	    if (dollar_vcol == 0)
+		wp->w_lines[idx].wl_size = row - srow;
+	    ++idx;
+#ifdef FEAT_FOLDING
+	    lnum += fold_count + 1;
+#else
+	    ++lnum;
+#endif
+	}
+	else
+	{
+	    /* This line does not need updating, advance to the next one */
+	    row += wp->w_lines[idx++].wl_size;
+	    if (row > wp->w_height)	/* past end of screen */
+		break;
+#ifdef FEAT_FOLDING
+	    lnum = wp->w_lines[idx - 1].wl_lastlnum + 1;
+#else
+	    ++lnum;
+#endif
+#ifdef FEAT_SYN_HL
+	    did_update = DID_NONE;
+#endif
+	}
+
+	if (lnum > buf->b_ml.ml_line_count)
+	{
+	    eof = TRUE;
+	    break;
+	}
+    }
+    /*
+     * End of loop over all window lines.
+     */
+
+
+    if (idx > wp->w_lines_valid)
+	wp->w_lines_valid = idx;
+
+#ifdef FEAT_SYN_HL
+    /*
+     * Let the syntax stuff know we stop parsing here.
+     */
+    if (syntax_last_parsed != 0 && syntax_present(buf))
+	syntax_end_parsing(syntax_last_parsed + 1);
+#endif
+
+    /*
+     * If we didn't hit the end of the file, and we didn't finish the last
+     * line we were working on, then the line didn't fit.
+     */
+    wp->w_empty_rows = 0;
+#ifdef FEAT_DIFF
+    wp->w_filler_rows = 0;
+#endif
+    if (!eof && !didline)
+    {
+	if (lnum == wp->w_topline)
+	{
+	    /*
+	     * Single line that does not fit!
+	     * Don't overwrite it, it can be edited.
+	     */
+	    wp->w_botline = lnum + 1;
+	}
+#ifdef FEAT_DIFF
+	else if (diff_check_fill(wp, lnum) >= wp->w_height - srow)
+	{
+	    /* Window ends in filler lines. */
+	    wp->w_botline = lnum;
+	    wp->w_filler_rows = wp->w_height - srow;
+	}
+#endif
+	else if (dy_flags & DY_LASTLINE)	/* 'display' has "lastline" */
+	{
+	    /*
+	     * Last line isn't finished: Display "@@@" at the end.
+	     */
+	    screen_fill(W_WINROW(wp) + wp->w_height - 1,
+		    W_WINROW(wp) + wp->w_height,
+		    (int)W_ENDCOL(wp) - 3, (int)W_ENDCOL(wp),
+		    '@', '@', hl_attr(HLF_AT));
+	    set_empty_rows(wp, srow);
+	    wp->w_botline = lnum;
+	}
+	else
+	{
+	    win_draw_end(wp, '@', ' ', srow, wp->w_height, HLF_AT);
+	    wp->w_botline = lnum;
+	}
+    }
+    else
+    {
+#ifdef FEAT_VERTSPLIT
+	draw_vsep_win(wp, row);
+#endif
+	if (eof)		/* we hit the end of the file */
+	{
+	    wp->w_botline = buf->b_ml.ml_line_count + 1;
+#ifdef FEAT_DIFF
+	    j = diff_check_fill(wp, wp->w_botline);
+	    if (j > 0 && !wp->w_botfill)
+	    {
+		/*
+		 * Display filler lines at the end of the file
+		 */
+		if (char2cells(fill_diff) > 1)
+		    i = '-';
+		else
+		    i = fill_diff;
+		if (row + j > wp->w_height)
+		    j = wp->w_height - row;
+		win_draw_end(wp, i, i, row, row + (int)j, HLF_DED);
+		row += j;
+	    }
+#endif
+	}
+	else if (dollar_vcol == 0)
+	    wp->w_botline = lnum;
+
+	/* make sure the rest of the screen is blank */
+	/* put '~'s on rows that aren't part of the file. */
+	win_draw_end(wp, '~', ' ', row, wp->w_height, HLF_AT);
+    }
+
+    /* Reset the type of redrawing required, the window has been updated. */
+    wp->w_redr_type = 0;
+#ifdef FEAT_DIFF
+    wp->w_old_topfill = wp->w_topfill;
+    wp->w_old_botfill = wp->w_botfill;
+#endif
+
+    if (dollar_vcol == 0)
+    {
+	/*
+	 * There is a trick with w_botline.  If we invalidate it on each
+	 * change that might modify it, this will cause a lot of expensive
+	 * calls to plines() in update_topline() each time.  Therefore the
+	 * value of w_botline is often approximated, and this value is used to
+	 * compute the value of w_topline.  If the value of w_botline was
+	 * wrong, check that the value of w_topline is correct (cursor is on
+	 * the visible part of the text).  If it's not, we need to redraw
+	 * again.  Mostly this just means scrolling up a few lines, so it
+	 * doesn't look too bad.  Only do this for the current window (where
+	 * changes are relevant).
+	 */
+	wp->w_valid |= VALID_BOTLINE;
+	if (wp == curwin && wp->w_botline != old_botline && !recursive)
+	{
+	    recursive = TRUE;
+	    curwin->w_valid &= ~VALID_TOPLINE;
+	    update_topline();	/* may invalidate w_botline again */
+	    if (must_redraw != 0)
+	    {
+		/* Don't update for changes in buffer again. */
+		i = curbuf->b_mod_set;
+		curbuf->b_mod_set = FALSE;
+		win_update(curwin);
+		must_redraw = 0;
+		curbuf->b_mod_set = i;
+	    }
+	    recursive = FALSE;
+	}
+    }
+
+#if defined(FEAT_SYN_HL) || defined(FEAT_SEARCH_EXTRA)
+    /* restore got_int, unless CTRL-C was hit while redrawing */
+    if (!got_int)
+	got_int = save_got_int;
+#endif
+}
+
+#ifdef FEAT_SIGNS
+static int draw_signcolumn __ARGS((win_T *wp));
+
+/*
+ * Return TRUE when window "wp" has a column to draw signs in.
+ */
+    static int
+draw_signcolumn(wp)
+    win_T *wp;
+{
+    return (wp->w_buffer->b_signlist != NULL
+# ifdef FEAT_NETBEANS_INTG
+			    || usingNetbeans
+# endif
+		    );
+}
+#endif
+
+/*
+ * Clear the rest of the window and mark the unused lines with "c1".  use "c2"
+ * as the filler character.
+ */
+    static void
+win_draw_end(wp, c1, c2, row, endrow, hl)
+    win_T	*wp;
+    int		c1;
+    int		c2;
+    int		row;
+    int		endrow;
+    hlf_T	hl;
+{
+#if defined(FEAT_FOLDING) || defined(FEAT_SIGNS) || defined(FEAT_CMDWIN)
+    int		n = 0;
+# define FDC_OFF n
+#else
+# define FDC_OFF 0
+#endif
+
+#ifdef FEAT_RIGHTLEFT
+    if (wp->w_p_rl)
+    {
+	/* No check for cmdline window: should never be right-left. */
+# ifdef FEAT_FOLDING
+	n = wp->w_p_fdc;
+
+	if (n > 0)
+	{
+	    /* draw the fold column at the right */
+	    if (n > W_WIDTH(wp))
+		n = W_WIDTH(wp);
+	    screen_fill(W_WINROW(wp) + row, W_WINROW(wp) + endrow,
+		    W_ENDCOL(wp) - n, (int)W_ENDCOL(wp),
+		    ' ', ' ', hl_attr(HLF_FC));
+	}
+# endif
+# ifdef FEAT_SIGNS
+	if (draw_signcolumn(wp))
+	{
+	    int nn = n + 2;
+
+	    /* draw the sign column left of the fold column */
+	    if (nn > W_WIDTH(wp))
+		nn = W_WIDTH(wp);
+	    screen_fill(W_WINROW(wp) + row, W_WINROW(wp) + endrow,
+		    W_ENDCOL(wp) - nn, (int)W_ENDCOL(wp) - n,
+		    ' ', ' ', hl_attr(HLF_SC));
+	    n = nn;
+	}
+# endif
+	screen_fill(W_WINROW(wp) + row, W_WINROW(wp) + endrow,
+		W_WINCOL(wp), W_ENDCOL(wp) - 1 - FDC_OFF,
+		c2, c2, hl_attr(hl));
+	screen_fill(W_WINROW(wp) + row, W_WINROW(wp) + endrow,
+		W_ENDCOL(wp) - 1 - FDC_OFF, W_ENDCOL(wp) - FDC_OFF,
+		c1, c2, hl_attr(hl));
+    }
+    else
+#endif
+    {
+#ifdef FEAT_CMDWIN
+	if (cmdwin_type != 0 && wp == curwin)
+	{
+	    /* draw the cmdline character in the leftmost column */
+	    n = 1;
+	    if (n > wp->w_width)
+		n = wp->w_width;
+	    screen_fill(W_WINROW(wp) + row, W_WINROW(wp) + endrow,
+		    W_WINCOL(wp), (int)W_WINCOL(wp) + n,
+		    cmdwin_type, ' ', hl_attr(HLF_AT));
+	}
+#endif
+#ifdef FEAT_FOLDING
+	if (wp->w_p_fdc > 0)
+	{
+	    int	    nn = n + wp->w_p_fdc;
+
+	    /* draw the fold column at the left */
+	    if (nn > W_WIDTH(wp))
+		nn = W_WIDTH(wp);
+	    screen_fill(W_WINROW(wp) + row, W_WINROW(wp) + endrow,
+		    W_WINCOL(wp) + n, (int)W_WINCOL(wp) + nn,
+		    ' ', ' ', hl_attr(HLF_FC));
+	    n = nn;
+	}
+#endif
+#ifdef FEAT_SIGNS
+	if (draw_signcolumn(wp))
+	{
+	    int	    nn = n + 2;
+
+	    /* draw the sign column after the fold column */
+	    if (nn > W_WIDTH(wp))
+		nn = W_WIDTH(wp);
+	    screen_fill(W_WINROW(wp) + row, W_WINROW(wp) + endrow,
+		    W_WINCOL(wp) + n, (int)W_WINCOL(wp) + nn,
+		    ' ', ' ', hl_attr(HLF_SC));
+	    n = nn;
+	}
+#endif
+	screen_fill(W_WINROW(wp) + row, W_WINROW(wp) + endrow,
+		W_WINCOL(wp) + FDC_OFF, (int)W_ENDCOL(wp),
+		c1, c2, hl_attr(hl));
+    }
+    set_empty_rows(wp, row);
+}
+
+#ifdef FEAT_FOLDING
+/*
+ * Display one folded line.
+ */
+    static void
+fold_line(wp, fold_count, foldinfo, lnum, row)
+    win_T	*wp;
+    long	fold_count;
+    foldinfo_T	*foldinfo;
+    linenr_T	lnum;
+    int		row;
+{
+    char_u	buf[51];
+    pos_T	*top, *bot;
+    linenr_T	lnume = lnum + fold_count - 1;
+    int		len;
+    char_u	*text;
+    int		fdc;
+    int		col;
+    int		txtcol;
+    int		off = (int)(current_ScreenLine - ScreenLines);
+    int		ri;
+
+    /* Build the fold line:
+     * 1. Add the cmdwin_type for the command-line window
+     * 2. Add the 'foldcolumn'
+     * 3. Add the 'number' column
+     * 4. Compose the text
+     * 5. Add the text
+     * 6. set highlighting for the Visual area an other text
+     */
+    col = 0;
+
+    /*
+     * 1. Add the cmdwin_type for the command-line window
+     * Ignores 'rightleft', this window is never right-left.
+     */
+#ifdef FEAT_CMDWIN
+    if (cmdwin_type != 0 && wp == curwin)
+    {
+	ScreenLines[off] = cmdwin_type;
+	ScreenAttrs[off] = hl_attr(HLF_AT);
+#ifdef FEAT_MBYTE
+	if (enc_utf8)
+	    ScreenLinesUC[off] = 0;
+#endif
+	++col;
+    }
+#endif
+
+    /*
+     * 2. Add the 'foldcolumn'
+     */
+    fdc = wp->w_p_fdc;
+    if (fdc > W_WIDTH(wp) - col)
+	fdc = W_WIDTH(wp) - col;
+    if (fdc > 0)
+    {
+	fill_foldcolumn(buf, wp, TRUE, lnum);
+#ifdef FEAT_RIGHTLEFT
+	if (wp->w_p_rl)
+	{
+	    int		i;
+
+	    copy_text_attr(off + W_WIDTH(wp) - fdc - col, buf, fdc,
+							     hl_attr(HLF_FC));
+	    /* reverse the fold column */
+	    for (i = 0; i < fdc; ++i)
+		ScreenLines[off + W_WIDTH(wp) - i - 1 - col] = buf[i];
+	}
+	else
+#endif
+	    copy_text_attr(off + col, buf, fdc, hl_attr(HLF_FC));
+	col += fdc;
+    }
+
+#ifdef FEAT_RIGHTLEFT
+# define RL_MEMSET(p, v, l)  if (wp->w_p_rl) \
+				for (ri = 0; ri < l; ++ri) \
+				   ScreenAttrs[off + (W_WIDTH(wp) - (p) - (l)) + ri] = v; \
+			     else \
+				for (ri = 0; ri < l; ++ri) \
+				   ScreenAttrs[off + (p) + ri] = v
+#else
+# define RL_MEMSET(p, v, l)   for (ri = 0; ri < l; ++ri) \
+				 ScreenAttrs[off + (p) + ri] = v
+#endif
+
+    /* Set all attributes of the 'number' column and the text */
+    RL_MEMSET(col, hl_attr(HLF_FL), W_WIDTH(wp) - col);
+
+#ifdef FEAT_SIGNS
+    /* If signs are being displayed, add two spaces. */
+    if (draw_signcolumn(wp))
+    {
+	len = W_WIDTH(wp) - col;
+	if (len > 0)
+	{
+	    if (len > 2)
+		len = 2;
+# ifdef FEAT_RIGHTLEFT
+	    if (wp->w_p_rl)
+		/* the line number isn't reversed */
+		copy_text_attr(off + W_WIDTH(wp) - len - col,
+					(char_u *)"  ", len, hl_attr(HLF_FL));
+	    else
+# endif
+		copy_text_attr(off + col, (char_u *)"  ", len, hl_attr(HLF_FL));
+	    col += len;
+	}
+    }
+#endif
+
+    /*
+     * 3. Add the 'number' column
+     */
+    if (wp->w_p_nu)
+    {
+	len = W_WIDTH(wp) - col;
+	if (len > 0)
+	{
+	    int	    w = number_width(wp);
+
+	    if (len > w + 1)
+		len = w + 1;
+	    sprintf((char *)buf, "%*ld ", w, (long)lnum);
+#ifdef FEAT_RIGHTLEFT
+	    if (wp->w_p_rl)
+		/* the line number isn't reversed */
+		copy_text_attr(off + W_WIDTH(wp) - len - col, buf, len,
+							     hl_attr(HLF_FL));
+	    else
+#endif
+		copy_text_attr(off + col, buf, len, hl_attr(HLF_FL));
+	    col += len;
+	}
+    }
+
+    /*
+     * 4. Compose the folded-line string with 'foldtext', if set.
+     */
+    text = get_foldtext(wp, lnum, lnume, foldinfo, buf);
+
+    txtcol = col;	/* remember where text starts */
+
+    /*
+     * 5. move the text to current_ScreenLine.  Fill up with "fill_fold".
+     *    Right-left text is put in columns 0 - number-col, normal text is put
+     *    in columns number-col - window-width.
+     */
+#ifdef FEAT_MBYTE
+    if (has_mbyte)
+    {
+	int	cells;
+	int	u8c, u8cc[MAX_MCO];
+	int	i;
+	int	idx;
+	int	c_len;
+	char_u	*p;
+# ifdef FEAT_ARABIC
+	int	prev_c = 0;		/* previous Arabic character */
+	int	prev_c1 = 0;		/* first composing char for prev_c */
+# endif
+
+# ifdef FEAT_RIGHTLEFT
+	if (wp->w_p_rl)
+	    idx = off;
+	else
+# endif
+	    idx = off + col;
+
+	/* Store multibyte characters in ScreenLines[] et al. correctly. */
+	for (p = text; *p != NUL; )
+	{
+	    cells = (*mb_ptr2cells)(p);
+	    c_len = (*mb_ptr2len)(p);
+	    if (col + cells > W_WIDTH(wp)
+# ifdef FEAT_RIGHTLEFT
+		    - (wp->w_p_rl ? col : 0)
+# endif
+		    )
+		break;
+	    ScreenLines[idx] = *p;
+	    if (enc_utf8)
+	    {
+		u8c = utfc_ptr2char(p, u8cc);
+		if (*p < 0x80 && u8cc[0] == 0)
+		{
+		    ScreenLinesUC[idx] = 0;
+#ifdef FEAT_ARABIC
+		    prev_c = u8c;
+#endif
+		}
+		else
+		{
+#ifdef FEAT_ARABIC
+		    if (p_arshape && !p_tbidi && ARABIC_CHAR(u8c))
+		    {
+			/* Do Arabic shaping. */
+			int	pc, pc1, nc;
+			int	pcc[MAX_MCO];
+			int	firstbyte = *p;
+
+			/* The idea of what is the previous and next
+			 * character depends on 'rightleft'. */
+			if (wp->w_p_rl)
+			{
+			    pc = prev_c;
+			    pc1 = prev_c1;
+			    nc = utf_ptr2char(p + c_len);
+			    prev_c1 = u8cc[0];
+			}
+			else
+			{
+			    pc = utfc_ptr2char(p + c_len, pcc);
+			    nc = prev_c;
+			    pc1 = pcc[0];
+			}
+			prev_c = u8c;
+
+			u8c = arabic_shape(u8c, &firstbyte, &u8cc[0],
+								 pc, pc1, nc);
+			ScreenLines[idx] = firstbyte;
+		    }
+		    else
+			prev_c = u8c;
+#endif
+		    /* Non-BMP character: display as ? or fullwidth ?. */
+		    if (u8c >= 0x10000)
+			ScreenLinesUC[idx] = (cells == 2) ? 0xff1f : (int)'?';
+		    else
+			ScreenLinesUC[idx] = u8c;
+		    for (i = 0; i < Screen_mco; ++i)
+		    {
+			ScreenLinesC[i][idx] = u8cc[i];
+			if (u8cc[i] == 0)
+			    break;
+		    }
+		}
+		if (cells > 1)
+		    ScreenLines[idx + 1] = 0;
+	    }
+	    else if (cells > 1)	    /* double-byte character */
+	    {
+		if (enc_dbcs == DBCS_JPNU && *p == 0x8e)
+		    ScreenLines2[idx] = p[1];
+		else
+		    ScreenLines[idx + 1] = p[1];
+	    }
+	    col += cells;
+	    idx += cells;
+	    p += c_len;
+	}
+    }
+    else
+#endif
+    {
+	len = (int)STRLEN(text);
+	if (len > W_WIDTH(wp) - col)
+	    len = W_WIDTH(wp) - col;
+	if (len > 0)
+	{
+#ifdef FEAT_RIGHTLEFT
+	    if (wp->w_p_rl)
+		STRNCPY(current_ScreenLine, text, len);
+	    else
+#endif
+		STRNCPY(current_ScreenLine + col, text, len);
+	    col += len;
+	}
+    }
+
+    /* Fill the rest of the line with the fold filler */
+#ifdef FEAT_RIGHTLEFT
+    if (wp->w_p_rl)
+	col -= txtcol;
+#endif
+    while (col < W_WIDTH(wp)
+#ifdef FEAT_RIGHTLEFT
+		    - (wp->w_p_rl ? txtcol : 0)
+#endif
+	    )
+    {
+#ifdef FEAT_MBYTE
+	if (enc_utf8)
+	{
+	    if (fill_fold >= 0x80)
+	    {
+		ScreenLinesUC[off + col] = fill_fold;
+		ScreenLinesC[0][off + col] = 0;
+	    }
+	    else
+		ScreenLinesUC[off + col] = 0;
+	}
+#endif
+	ScreenLines[off + col++] = fill_fold;
+    }
+
+    if (text != buf)
+	vim_free(text);
+
+    /*
+     * 6. set highlighting for the Visual area an other text.
+     * If all folded lines are in the Visual area, highlight the line.
+     */
+#ifdef FEAT_VISUAL
+    if (VIsual_active && wp->w_buffer == curwin->w_buffer)
+    {
+	if (ltoreq(curwin->w_cursor, VIsual))
+	{
+	    /* Visual is after curwin->w_cursor */
+	    top = &curwin->w_cursor;
+	    bot = &VIsual;
+	}
+	else
+	{
+	    /* Visual is before curwin->w_cursor */
+	    top = &VIsual;
+	    bot = &curwin->w_cursor;
+	}
+	if (lnum >= top->lnum
+		&& lnume <= bot->lnum
+		&& (VIsual_mode != 'v'
+		    || ((lnum > top->lnum
+			    || (lnum == top->lnum
+				&& top->col == 0))
+			&& (lnume < bot->lnum
+			    || (lnume == bot->lnum
+				&& (bot->col - (*p_sel == 'e'))
+		>= STRLEN(ml_get_buf(wp->w_buffer, lnume, FALSE)))))))
+	{
+	    if (VIsual_mode == Ctrl_V)
+	    {
+		/* Visual block mode: highlight the chars part of the block */
+		if (wp->w_old_cursor_fcol + txtcol < (colnr_T)W_WIDTH(wp))
+		{
+		    if (wp->w_old_cursor_lcol + txtcol < (colnr_T)W_WIDTH(wp))
+			len = wp->w_old_cursor_lcol;
+		    else
+			len = W_WIDTH(wp) - txtcol;
+		    RL_MEMSET(wp->w_old_cursor_fcol + txtcol, hl_attr(HLF_V),
+					    len - (int)wp->w_old_cursor_fcol);
+		}
+	    }
+	    else
+	    {
+		/* Set all attributes of the text */
+		RL_MEMSET(txtcol, hl_attr(HLF_V), W_WIDTH(wp) - txtcol);
+	    }
+	}
+    }
+#endif
+
+#ifdef FEAT_SYN_HL
+    /* Show 'cursorcolumn' in the fold line. */
+    if (wp->w_p_cuc && (int)wp->w_virtcol + txtcol < W_WIDTH(wp))
+	ScreenAttrs[off + wp->w_virtcol + txtcol] = hl_combine_attr(
+		 ScreenAttrs[off + wp->w_virtcol + txtcol], hl_attr(HLF_CUC));
+#endif
+
+    SCREEN_LINE(row + W_WINROW(wp), W_WINCOL(wp), (int)W_WIDTH(wp),
+						     (int)W_WIDTH(wp), FALSE);
+
+    /*
+     * Update w_cline_height and w_cline_folded if the cursor line was
+     * updated (saves a call to plines() later).
+     */
+    if (wp == curwin
+	    && lnum <= curwin->w_cursor.lnum
+	    && lnume >= curwin->w_cursor.lnum)
+    {
+	curwin->w_cline_row = row;
+	curwin->w_cline_height = 1;
+	curwin->w_cline_folded = TRUE;
+	curwin->w_valid |= (VALID_CHEIGHT|VALID_CROW);
+    }
+}
+
+/*
+ * Copy "buf[len]" to ScreenLines["off"] and set attributes to "attr".
+ */
+    static void
+copy_text_attr(off, buf, len, attr)
+    int		off;
+    char_u	*buf;
+    int		len;
+    int		attr;
+{
+    int		i;
+
+    mch_memmove(ScreenLines + off, buf, (size_t)len);
+# ifdef FEAT_MBYTE
+    if (enc_utf8)
+	vim_memset(ScreenLinesUC + off, 0, sizeof(u8char_T) * (size_t)len);
+# endif
+    for (i = 0; i < len; ++i)
+	ScreenAttrs[off + i] = attr;
+}
+
+/*
+ * Fill the foldcolumn at "p" for window "wp".
+ * Only to be called when 'foldcolumn' > 0.
+ */
+    static void
+fill_foldcolumn(p, wp, closed, lnum)
+    char_u	*p;
+    win_T	*wp;
+    int		closed;		/* TRUE of FALSE */
+    linenr_T	lnum;		/* current line number */
+{
+    int		i = 0;
+    int		level;
+    int		first_level;
+    int		empty;
+
+    /* Init to all spaces. */
+    copy_spaces(p, (size_t)wp->w_p_fdc);
+
+    level = win_foldinfo.fi_level;
+    if (level > 0)
+    {
+	/* If there is only one column put more info in it. */
+	empty = (wp->w_p_fdc == 1) ? 0 : 1;
+
+	/* If the column is too narrow, we start at the lowest level that
+	 * fits and use numbers to indicated the depth. */
+	first_level = level - wp->w_p_fdc - closed + 1 + empty;
+	if (first_level < 1)
+	    first_level = 1;
+
+	for (i = 0; i + empty < wp->w_p_fdc; ++i)
+	{
+	    if (win_foldinfo.fi_lnum == lnum
+			      && first_level + i >= win_foldinfo.fi_low_level)
+		p[i] = '-';
+	    else if (first_level == 1)
+		p[i] = '|';
+	    else if (first_level + i <= 9)
+		p[i] = '0' + first_level + i;
+	    else
+		p[i] = '>';
+	    if (first_level + i == level)
+		break;
+	}
+    }
+    if (closed)
+	p[i >= wp->w_p_fdc ? i - 1 : i] = '+';
+}
+#endif /* FEAT_FOLDING */
+
+/*
+ * Display line "lnum" of window 'wp' on the screen.
+ * Start at row "startrow", stop when "endrow" is reached.
+ * wp->w_virtcol needs to be valid.
+ *
+ * Return the number of last row the line occupies.
+ */
+/* ARGSUSED */
+    static int
+win_line(wp, lnum, startrow, endrow, nochange)
+    win_T	*wp;
+    linenr_T	lnum;
+    int		startrow;
+    int		endrow;
+    int		nochange;		/* not updating for changed text */
+{
+    int		col;			/* visual column on screen */
+    unsigned	off;			/* offset in ScreenLines/ScreenAttrs */
+    int		c = 0;			/* init for GCC */
+    long	vcol = 0;		/* virtual column (for tabs) */
+    long	vcol_prev = -1;		/* "vcol" of previous character */
+    char_u	*line;			/* current line */
+    char_u	*ptr;			/* current position in "line" */
+    int		row;			/* row in the window, excl w_winrow */
+    int		screen_row;		/* row on the screen, incl w_winrow */
+
+    char_u	extra[18];		/* "%ld" and 'fdc' must fit in here */
+    int		n_extra = 0;		/* number of extra chars */
+    char_u	*p_extra = NULL;	/* string of extra chars */
+    int		c_extra = NUL;		/* extra chars, all the same */
+    int		extra_attr = 0;		/* attributes when n_extra != 0 */
+    static char_u *at_end_str = (char_u *)""; /* used for p_extra when
+					   displaying lcs_eol at end-of-line */
+    int		lcs_eol_one = lcs_eol;	/* lcs_eol until it's been used */
+    int		lcs_prec_todo = lcs_prec;   /* lcs_prec until it's been used */
+
+    /* saved "extra" items for when draw_state becomes WL_LINE (again) */
+    int		saved_n_extra = 0;
+    char_u	*saved_p_extra = NULL;
+    int		saved_c_extra = 0;
+    int		saved_char_attr = 0;
+
+    int		n_attr = 0;		/* chars with special attr */
+    int		saved_attr2 = 0;	/* char_attr saved for n_attr */
+    int		n_attr3 = 0;		/* chars with overruling special attr */
+    int		saved_attr3 = 0;	/* char_attr saved for n_attr3 */
+
+    int		n_skip = 0;		/* nr of chars to skip for 'nowrap' */
+
+    int		fromcol, tocol;		/* start/end of inverting */
+    int		fromcol_prev = -2;	/* start of inverting after cursor */
+    int		noinvcur = FALSE;	/* don't invert the cursor */
+#ifdef FEAT_VISUAL
+    pos_T	*top, *bot;
+#endif
+    pos_T	pos;
+    long	v;
+
+    int		char_attr = 0;		/* attributes for next character */
+    int		attr_pri = FALSE;	/* char_attr has priority */
+    int		area_highlighting = FALSE; /* Visual or incsearch highlighting
+					      in this line */
+    int		attr = 0;		/* attributes for area highlighting */
+    int		area_attr = 0;		/* attributes desired by highlighting */
+    int		search_attr = 0;	/* attributes desired by 'hlsearch' */
+#ifdef FEAT_SYN_HL
+    int		vcol_save_attr = 0;	/* saved attr for 'cursorcolumn' */
+    int		syntax_attr = 0;	/* attributes desired by syntax */
+    int		has_syntax = FALSE;	/* this buffer has syntax highl. */
+    int		save_did_emsg;
+#endif
+#ifdef FEAT_SPELL
+    int		has_spell = FALSE;	/* this buffer has spell checking */
+# define SPWORDLEN 150
+    char_u	nextline[SPWORDLEN * 2];/* text with start of the next line */
+    int		nextlinecol = 0;	/* column where nextline[] starts */
+    int		nextline_idx = 0;	/* index in nextline[] where next line
+					   starts */
+    int		spell_attr = 0;		/* attributes desired by spelling */
+    int		word_end = 0;		/* last byte with same spell_attr */
+    static linenr_T  checked_lnum = 0;	/* line number for "checked_col" */
+    static int	checked_col = 0;	/* column in "checked_lnum" up to which
+					 * there are no spell errors */
+    static int	cap_col = -1;		/* column to check for Cap word */
+    static linenr_T capcol_lnum = 0;	/* line number where "cap_col" used */
+    int		cur_checked_col = 0;	/* checked column for current line */
+#endif
+    int		extra_check;		/* has syntax or linebreak */
+#ifdef FEAT_MBYTE
+    int		multi_attr = 0;		/* attributes desired by multibyte */
+    int		mb_l = 1;		/* multi-byte byte length */
+    int		mb_c = 0;		/* decoded multi-byte character */
+    int		mb_utf8 = FALSE;	/* screen char is UTF-8 char */
+    int		u8cc[MAX_MCO];		/* composing UTF-8 chars */
+#endif
+#ifdef FEAT_DIFF
+    int		filler_lines;		/* nr of filler lines to be drawn */
+    int		filler_todo;		/* nr of filler lines still to do + 1 */
+    hlf_T	diff_hlf = (hlf_T)0;	/* type of diff highlighting */
+    int		change_start = MAXCOL;	/* first col of changed area */
+    int		change_end = -1;	/* last col of changed area */
+#endif
+    colnr_T	trailcol = MAXCOL;	/* start of trailing spaces */
+#ifdef FEAT_LINEBREAK
+    int		need_showbreak = FALSE;
+#endif
+#if defined(FEAT_SIGNS) || (defined(FEAT_QUICKFIX) && defined(FEAT_WINDOWS)) \
+	|| defined(FEAT_SYN_HL) || defined(FEAT_DIFF)
+# define LINE_ATTR
+    int		line_attr = 0;		/* atrribute for the whole line */
+#endif
+#ifdef FEAT_SEARCH_EXTRA
+    match_T	*shl;			/* points to search_hl or match_hl */
+#endif
+#if defined(FEAT_SEARCH_EXTRA) || defined(FEAT_MBYTE)
+    int		i;
+#endif
+#ifdef FEAT_ARABIC
+    int		prev_c = 0;		/* previous Arabic character */
+    int		prev_c1 = 0;		/* first composing char for prev_c */
+#endif
+#if defined(LINE_ATTR)
+    int		did_line_attr = 0;
+#endif
+
+    /* draw_state: items that are drawn in sequence: */
+#define WL_START	0		/* nothing done yet */
+#ifdef FEAT_CMDWIN
+# define WL_CMDLINE	WL_START + 1	/* cmdline window column */
+#else
+# define WL_CMDLINE	WL_START
+#endif
+#ifdef FEAT_FOLDING
+# define WL_FOLD	WL_CMDLINE + 1	/* 'foldcolumn' */
+#else
+# define WL_FOLD	WL_CMDLINE
+#endif
+#ifdef FEAT_SIGNS
+# define WL_SIGN	WL_FOLD + 1	/* column for signs */
+#else
+# define WL_SIGN	WL_FOLD		/* column for signs */
+#endif
+#define WL_NR		WL_SIGN + 1	/* line number */
+#if defined(FEAT_LINEBREAK) || defined(FEAT_DIFF)
+# define WL_SBR		WL_NR + 1	/* 'showbreak' or 'diff' */
+#else
+# define WL_SBR		WL_NR
+#endif
+#define WL_LINE		WL_SBR + 1	/* text in the line */
+    int		draw_state = WL_START;	/* what to draw next */
+#if defined(FEAT_XIM) && defined(FEAT_GUI_GTK)
+    int		feedback_col = 0;
+    int		feedback_old_attr = -1;
+#endif
+
+
+    if (startrow > endrow)		/* past the end already! */
+	return startrow;
+
+    row = startrow;
+    screen_row = row + W_WINROW(wp);
+
+    /*
+     * To speed up the loop below, set extra_check when there is linebreak,
+     * trailing white space and/or syntax processing to be done.
+     */
+#ifdef FEAT_LINEBREAK
+    extra_check = wp->w_p_lbr;
+#else
+    extra_check = 0;
+#endif
+#ifdef FEAT_SYN_HL
+    if (syntax_present(wp->w_buffer) && !wp->w_buffer->b_syn_error)
+    {
+	/* Prepare for syntax highlighting in this line.  When there is an
+	 * error, stop syntax highlighting. */
+	save_did_emsg = did_emsg;
+	did_emsg = FALSE;
+	syntax_start(wp, lnum);
+	if (did_emsg)
+	    wp->w_buffer->b_syn_error = TRUE;
+	else
+	{
+	    did_emsg = save_did_emsg;
+	    has_syntax = TRUE;
+	    extra_check = TRUE;
+	}
+    }
+#endif
+
+#ifdef FEAT_SPELL
+    if (wp->w_p_spell
+	    && *wp->w_buffer->b_p_spl != NUL
+	    && wp->w_buffer->b_langp.ga_len > 0
+	    && *(char **)(wp->w_buffer->b_langp.ga_data) != NULL)
+    {
+	/* Prepare for spell checking. */
+	has_spell = TRUE;
+	extra_check = TRUE;
+
+	/* Get the start of the next line, so that words that wrap to the next
+	 * line are found too: "et<line-break>al.".
+	 * Trick: skip a few chars for C/shell/Vim comments */
+	nextline[SPWORDLEN] = NUL;
+	if (lnum < wp->w_buffer->b_ml.ml_line_count)
+	{
+	    line = ml_get_buf(wp->w_buffer, lnum + 1, FALSE);
+	    spell_cat_line(nextline + SPWORDLEN, line, SPWORDLEN);
+	}
+
+	/* When a word wrapped from the previous line the start of the current
+	 * line is valid. */
+	if (lnum == checked_lnum)
+	    cur_checked_col = checked_col;
+	checked_lnum = 0;
+
+	/* When there was a sentence end in the previous line may require a
+	 * word starting with capital in this line.  In line 1 always check
+	 * the first word. */
+	if (lnum != capcol_lnum)
+	    cap_col = -1;
+	if (lnum == 1)
+	    cap_col = 0;
+	capcol_lnum = 0;
+    }
+#endif
+
+    /*
+     * handle visual active in this window
+     */
+    fromcol = -10;
+    tocol = MAXCOL;
+#ifdef FEAT_VISUAL
+    if (VIsual_active && wp->w_buffer == curwin->w_buffer)
+    {
+					/* Visual is after curwin->w_cursor */
+	if (ltoreq(curwin->w_cursor, VIsual))
+	{
+	    top = &curwin->w_cursor;
+	    bot = &VIsual;
+	}
+	else				/* Visual is before curwin->w_cursor */
+	{
+	    top = &VIsual;
+	    bot = &curwin->w_cursor;
+	}
+	if (VIsual_mode == Ctrl_V)	/* block mode */
+	{
+	    if (lnum >= top->lnum && lnum <= bot->lnum)
+	    {
+		fromcol = wp->w_old_cursor_fcol;
+		tocol = wp->w_old_cursor_lcol;
+	    }
+	}
+	else				/* non-block mode */
+	{
+	    if (lnum > top->lnum && lnum <= bot->lnum)
+		fromcol = 0;
+	    else if (lnum == top->lnum)
+	    {
+		if (VIsual_mode == 'V')	/* linewise */
+		    fromcol = 0;
+		else
+		{
+		    getvvcol(wp, top, (colnr_T *)&fromcol, NULL, NULL);
+		    if (gchar_pos(top) == NUL)
+			tocol = fromcol + 1;
+		}
+	    }
+	    if (VIsual_mode != 'V' && lnum == bot->lnum)
+	    {
+		if (*p_sel == 'e' && bot->col == 0
+#ifdef FEAT_VIRTUALEDIT
+			&& bot->coladd == 0
+#endif
+		   )
+		{
+		    fromcol = -10;
+		    tocol = MAXCOL;
+		}
+		else if (bot->col == MAXCOL)
+		    tocol = MAXCOL;
+		else
+		{
+		    pos = *bot;
+		    if (*p_sel == 'e')
+			getvvcol(wp, &pos, (colnr_T *)&tocol, NULL, NULL);
+		    else
+		    {
+			getvvcol(wp, &pos, NULL, NULL, (colnr_T *)&tocol);
+			++tocol;
+		    }
+		}
+	    }
+	}
+
+#ifndef MSDOS
+	/* Check if the character under the cursor should not be inverted */
+	if (!highlight_match && lnum == curwin->w_cursor.lnum && wp == curwin
+# ifdef FEAT_GUI
+		&& !gui.in_use
+# endif
+		)
+	    noinvcur = TRUE;
+#endif
+
+	/* if inverting in this line set area_highlighting */
+	if (fromcol >= 0)
+	{
+	    area_highlighting = TRUE;
+	    attr = hl_attr(HLF_V);
+#if defined(FEAT_CLIPBOARD) && defined(FEAT_X11)
+	    if (clip_star.available && !clip_star.owned && clip_isautosel())
+		attr = hl_attr(HLF_VNC);
+#endif
+	}
+    }
+
+    /*
+     * handle 'incsearch' and ":s///c" highlighting
+     */
+    else
+#endif /* FEAT_VISUAL */
+	if (highlight_match
+	    && wp == curwin
+	    && lnum >= curwin->w_cursor.lnum
+	    && lnum <= curwin->w_cursor.lnum + search_match_lines)
+    {
+	if (lnum == curwin->w_cursor.lnum)
+	    getvcol(curwin, &(curwin->w_cursor),
+					     (colnr_T *)&fromcol, NULL, NULL);
+	else
+	    fromcol = 0;
+	if (lnum == curwin->w_cursor.lnum + search_match_lines)
+	{
+	    pos.lnum = lnum;
+	    pos.col = search_match_endcol;
+	    getvcol(curwin, &pos, (colnr_T *)&tocol, NULL, NULL);
+	}
+	else
+	    tocol = MAXCOL;
+	if (fromcol == tocol)		/* do at least one character */
+	    tocol = fromcol + 1;	/* happens when past end of line */
+	area_highlighting = TRUE;
+	attr = hl_attr(HLF_I);
+    }
+
+#ifdef FEAT_DIFF
+    filler_lines = diff_check(wp, lnum);
+    if (filler_lines < 0)
+    {
+	if (filler_lines == -1)
+	{
+	    if (diff_find_change(wp, lnum, &change_start, &change_end))
+		diff_hlf = HLF_ADD;	/* added line */
+	    else if (change_start == 0)
+		diff_hlf = HLF_TXD;	/* changed text */
+	    else
+		diff_hlf = HLF_CHD;	/* changed line */
+	}
+	else
+	    diff_hlf = HLF_ADD;		/* added line */
+	filler_lines = 0;
+	area_highlighting = TRUE;
+    }
+    if (lnum == wp->w_topline)
+	filler_lines = wp->w_topfill;
+    filler_todo = filler_lines;
+#endif
+
+#ifdef LINE_ATTR
+# ifdef FEAT_SIGNS
+    /* If this line has a sign with line highlighting set line_attr. */
+    v = buf_getsigntype(wp->w_buffer, lnum, SIGN_LINEHL);
+    if (v != 0)
+	line_attr = sign_get_attr((int)v, TRUE);
+# endif
+# if defined(FEAT_QUICKFIX) && defined(FEAT_WINDOWS)
+    /* Highlight the current line in the quickfix window. */
+    if (bt_quickfix(wp->w_buffer) && qf_current_entry(wp) == lnum)
+	line_attr = hl_attr(HLF_L);
+# endif
+    if (line_attr != 0)
+	area_highlighting = TRUE;
+#endif
+
+    line = ml_get_buf(wp->w_buffer, lnum, FALSE);
+    ptr = line;
+
+#ifdef FEAT_SPELL
+    if (has_spell)
+    {
+	/* For checking first word with a capital skip white space. */
+	if (cap_col == 0)
+	    cap_col = (int)(skipwhite(line) - line);
+
+	/* To be able to spell-check over line boundaries copy the end of the
+	 * current line into nextline[].  Above the start of the next line was
+	 * copied to nextline[SPWORDLEN]. */
+	if (nextline[SPWORDLEN] == NUL)
+	{
+	    /* No next line or it is empty. */
+	    nextlinecol = MAXCOL;
+	    nextline_idx = 0;
+	}
+	else
+	{
+	    v = (long)STRLEN(line);
+	    if (v < SPWORDLEN)
+	    {
+		/* Short line, use it completely and append the start of the
+		 * next line. */
+		nextlinecol = 0;
+		mch_memmove(nextline, line, (size_t)v);
+		mch_memmove(nextline + v, nextline + SPWORDLEN,
+					    STRLEN(nextline + SPWORDLEN) + 1);
+		nextline_idx = v + 1;
+	    }
+	    else
+	    {
+		/* Long line, use only the last SPWORDLEN bytes. */
+		nextlinecol = v - SPWORDLEN;
+		mch_memmove(nextline, line + nextlinecol, SPWORDLEN);
+		nextline_idx = SPWORDLEN + 1;
+	    }
+	}
+    }
+#endif
+
+    /* find start of trailing whitespace */
+    if (wp->w_p_list && lcs_trail)
+    {
+	trailcol = (colnr_T)STRLEN(ptr);
+	while (trailcol > (colnr_T)0 && vim_iswhite(ptr[trailcol - 1]))
+	    --trailcol;
+	trailcol += (colnr_T) (ptr - line);
+	extra_check = TRUE;
+    }
+
+    /*
+     * 'nowrap' or 'wrap' and a single line that doesn't fit: Advance to the
+     * first character to be displayed.
+     */
+    if (wp->w_p_wrap)
+	v = wp->w_skipcol;
+    else
+	v = wp->w_leftcol;
+    if (v > 0)
+    {
+#ifdef FEAT_MBYTE
+	char_u	*prev_ptr = ptr;
+#endif
+	while (vcol < v && *ptr != NUL)
+	{
+	    c = win_lbr_chartabsize(wp, ptr, (colnr_T)vcol, NULL);
+	    vcol += c;
+#ifdef FEAT_MBYTE
+	    prev_ptr = ptr;
+#endif
+	    mb_ptr_adv(ptr);
+	}
+
+#ifdef FEAT_VIRTUALEDIT
+	/* When 'virtualedit' is set the end of the line may be before the
+	 * start of the displayed part. */
+	if (vcol < v && *ptr == NUL && virtual_active())
+	    vcol = v;
+#endif
+
+	/* Handle a character that's not completely on the screen: Put ptr at
+	 * that character but skip the first few screen characters. */
+	if (vcol > v)
+	{
+	    vcol -= c;
+#ifdef FEAT_MBYTE
+	    ptr = prev_ptr;
+#else
+	    --ptr;
+#endif
+	    n_skip = v - vcol;
+	}
+
+	/*
+	 * Adjust for when the inverted text is before the screen,
+	 * and when the start of the inverted text is before the screen.
+	 */
+	if (tocol <= vcol)
+	    fromcol = 0;
+	else if (fromcol >= 0 && fromcol < vcol)
+	    fromcol = vcol;
+
+#ifdef FEAT_LINEBREAK
+	/* When w_skipcol is non-zero, first line needs 'showbreak' */
+	if (wp->w_p_wrap)
+	    need_showbreak = TRUE;
+#endif
+#ifdef FEAT_SPELL
+	/* When spell checking a word we need to figure out the start of the
+	 * word and if it's badly spelled or not. */
+	if (has_spell)
+	{
+	    int		len;
+	    hlf_T	spell_hlf = HLF_COUNT;
+
+	    pos = wp->w_cursor;
+	    wp->w_cursor.lnum = lnum;
+	    wp->w_cursor.col = (colnr_T)(ptr - line);
+	    len = spell_move_to(wp, FORWARD, TRUE, TRUE, &spell_hlf);
+	    if (len == 0 || (int)wp->w_cursor.col > ptr - line)
+	    {
+		/* no bad word found at line start, don't check until end of a
+		 * word */
+		spell_hlf = HLF_COUNT;
+		word_end = (int)(spell_to_word_end(ptr, wp->w_buffer) - line + 1);
+	    }
+	    else
+	    {
+		/* bad word found, use attributes until end of word */
+		word_end = wp->w_cursor.col + len + 1;
+
+		/* Turn index into actual attributes. */
+		if (spell_hlf != HLF_COUNT)
+		    spell_attr = highlight_attr[spell_hlf];
+	    }
+	    wp->w_cursor = pos;
+
+# ifdef FEAT_SYN_HL
+	    /* Need to restart syntax highlighting for this line. */
+	    if (has_syntax)
+		syntax_start(wp, lnum);
+# endif
+	}
+#endif
+    }
+
+    /*
+     * Correct highlighting for cursor that can't be disabled.
+     * Avoids having to check this for each character.
+     */
+    if (fromcol >= 0)
+    {
+	if (noinvcur)
+	{
+	    if ((colnr_T)fromcol == wp->w_virtcol)
+	    {
+		/* highlighting starts at cursor, let it start just after the
+		 * cursor */
+		fromcol_prev = fromcol;
+		fromcol = -1;
+	    }
+	    else if ((colnr_T)fromcol < wp->w_virtcol)
+		/* restart highlighting after the cursor */
+		fromcol_prev = wp->w_virtcol;
+	}
+	if (fromcol >= tocol)
+	    fromcol = -1;
+    }
+
+#ifdef FEAT_SEARCH_EXTRA
+    /*
+     * Handle highlighting the last used search pattern and ":match".
+     * Do this for both search_hl and match_hl[3].
+     */
+    for (i = 3; i >= 0; --i)
+    {
+	shl = (i == 3) ? &search_hl : &match_hl[i];
+	shl->startcol = MAXCOL;
+	shl->endcol = MAXCOL;
+	shl->attr_cur = 0;
+	if (shl->rm.regprog != NULL)
+	{
+	    v = (long)(ptr - line);
+	    next_search_hl(wp, shl, lnum, (colnr_T)v);
+
+	    /* Need to get the line again, a multi-line regexp may have made it
+	     * invalid. */
+	    line = ml_get_buf(wp->w_buffer, lnum, FALSE);
+	    ptr = line + v;
+
+	    if (shl->lnum != 0 && shl->lnum <= lnum)
+	    {
+		if (shl->lnum == lnum)
+		    shl->startcol = shl->rm.startpos[0].col;
+		else
+		    shl->startcol = 0;
+		if (lnum == shl->lnum + shl->rm.endpos[0].lnum
+						  - shl->rm.startpos[0].lnum)
+		    shl->endcol = shl->rm.endpos[0].col;
+		else
+		    shl->endcol = MAXCOL;
+		/* Highlight one character for an empty match. */
+		if (shl->startcol == shl->endcol)
+		{
+#ifdef FEAT_MBYTE
+		    if (has_mbyte && line[shl->endcol] != NUL)
+			shl->endcol += (*mb_ptr2len)(line + shl->endcol);
+		    else
+#endif
+			++shl->endcol;
+		}
+		if ((long)shl->startcol < v)  /* match at leftcol */
+		{
+		    shl->attr_cur = shl->attr;
+		    search_attr = shl->attr;
+		}
+		area_highlighting = TRUE;
+	    }
+	}
+    }
+#endif
+
+#ifdef FEAT_SYN_HL
+    /* Cursor line highlighting for 'cursorline'.  Not when Visual mode is
+     * active, because it's not clear what is selected then. */
+    if (wp->w_p_cul && lnum == wp->w_cursor.lnum && !VIsual_active)
+    {
+	line_attr = hl_attr(HLF_CUL);
+	area_highlighting = TRUE;
+    }
+#endif
+
+    off = (unsigned)(current_ScreenLine - ScreenLines);
+    col = 0;
+#ifdef FEAT_RIGHTLEFT
+    if (wp->w_p_rl)
+    {
+	/* Rightleft window: process the text in the normal direction, but put
+	 * it in current_ScreenLine[] from right to left.  Start at the
+	 * rightmost column of the window. */
+	col = W_WIDTH(wp) - 1;
+	off += col;
+    }
+#endif
+
+    /*
+     * Repeat for the whole displayed line.
+     */
+    for (;;)
+    {
+	/* Skip this quickly when working on the text. */
+	if (draw_state != WL_LINE)
+	{
+#ifdef FEAT_CMDWIN
+	    if (draw_state == WL_CMDLINE - 1 && n_extra == 0)
+	    {
+		draw_state = WL_CMDLINE;
+		if (cmdwin_type != 0 && wp == curwin)
+		{
+		    /* Draw the cmdline character. */
+		    *extra = cmdwin_type;
+		    n_extra = 1;
+		    p_extra = extra;
+		    c_extra = NUL;
+		    char_attr = hl_attr(HLF_AT);
+		}
+	    }
+#endif
+
+#ifdef FEAT_FOLDING
+	    if (draw_state == WL_FOLD - 1 && n_extra == 0)
+	    {
+		draw_state = WL_FOLD;
+		if (wp->w_p_fdc > 0)
+		{
+		    /* Draw the 'foldcolumn'. */
+		    fill_foldcolumn(extra, wp, FALSE, lnum);
+		    n_extra = wp->w_p_fdc;
+		    p_extra = extra;
+		    c_extra = NUL;
+		    char_attr = hl_attr(HLF_FC);
+		}
+	    }
+#endif
+
+#ifdef FEAT_SIGNS
+	    if (draw_state == WL_SIGN - 1 && n_extra == 0)
+	    {
+		draw_state = WL_SIGN;
+		/* Show the sign column when there are any signs in this
+		 * buffer or when using Netbeans. */
+		if (draw_signcolumn(wp)
+# ifdef FEAT_DIFF
+			&& filler_todo <= 0
+# endif
+		   )
+		{
+		    int_u	text_sign;
+# ifdef FEAT_SIGN_ICONS
+		    int_u	icon_sign;
+# endif
+
+		    /* Draw two cells with the sign value or blank. */
+		    c_extra = ' ';
+		    char_attr = hl_attr(HLF_SC);
+		    n_extra = 2;
+
+		    if (row == startrow)
+		    {
+			text_sign = buf_getsigntype(wp->w_buffer, lnum,
+								   SIGN_TEXT);
+# ifdef FEAT_SIGN_ICONS
+			icon_sign = buf_getsigntype(wp->w_buffer, lnum,
+								   SIGN_ICON);
+			if (gui.in_use && icon_sign != 0)
+			{
+			    /* Use the image in this position. */
+			    c_extra = SIGN_BYTE;
+#  ifdef FEAT_NETBEANS_INTG
+			    if (buf_signcount(wp->w_buffer, lnum) > 1)
+				c_extra = MULTISIGN_BYTE;
+#  endif
+			    char_attr = icon_sign;
+			}
+			else
+# endif
+			    if (text_sign != 0)
+			{
+			    p_extra = sign_get_text(text_sign);
+			    if (p_extra != NULL)
+			    {
+				c_extra = NUL;
+				n_extra = (int)STRLEN(p_extra);
+			    }
+			    char_attr = sign_get_attr(text_sign, FALSE);
+			}
+		    }
+		}
+	    }
+#endif
+
+	    if (draw_state == WL_NR - 1 && n_extra == 0)
+	    {
+		draw_state = WL_NR;
+		/* Display the line number.  After the first fill with blanks
+		 * when the 'n' flag isn't in 'cpo' */
+		if (wp->w_p_nu
+			&& (row == startrow
+#ifdef FEAT_DIFF
+			    + filler_lines
+#endif
+			    || vim_strchr(p_cpo, CPO_NUMCOL) == NULL))
+		{
+		    /* Draw the line number (empty space after wrapping). */
+		    if (row == startrow
+#ifdef FEAT_DIFF
+			    + filler_lines
+#endif
+			    )
+		    {
+			sprintf((char *)extra, "%*ld ",
+						number_width(wp), (long)lnum);
+			if (wp->w_skipcol > 0)
+			    for (p_extra = extra; *p_extra == ' '; ++p_extra)
+				*p_extra = '-';
+#ifdef FEAT_RIGHTLEFT
+			if (wp->w_p_rl)		    /* reverse line numbers */
+			    rl_mirror(extra);
+#endif
+			p_extra = extra;
+			c_extra = NUL;
+		    }
+		    else
+			c_extra = ' ';
+		    n_extra = number_width(wp) + 1;
+		    char_attr = hl_attr(HLF_N);
+#ifdef FEAT_SYN_HL
+		    /* When 'cursorline' is set highlight the line number of
+		     * the current line differently. */
+		    if (wp->w_p_cul && lnum == wp->w_cursor.lnum)
+			char_attr = hl_combine_attr(hl_attr(HLF_CUL), char_attr);
+#endif
+		}
+	    }
+
+#if defined(FEAT_LINEBREAK) || defined(FEAT_DIFF)
+	    if (draw_state == WL_SBR - 1 && n_extra == 0)
+	    {
+		draw_state = WL_SBR;
+# ifdef FEAT_DIFF
+		if (filler_todo > 0)
+		{
+		    /* Draw "deleted" diff line(s). */
+		    if (char2cells(fill_diff) > 1)
+			c_extra = '-';
+		    else
+			c_extra = fill_diff;
+#  ifdef FEAT_RIGHTLEFT
+		    if (wp->w_p_rl)
+			n_extra = col + 1;
+		    else
+#  endif
+			n_extra = W_WIDTH(wp) - col;
+		    char_attr = hl_attr(HLF_DED);
+		}
+# endif
+# ifdef FEAT_LINEBREAK
+		if (*p_sbr != NUL && need_showbreak)
+		{
+		    /* Draw 'showbreak' at the start of each broken line. */
+		    p_extra = p_sbr;
+		    c_extra = NUL;
+		    n_extra = (int)STRLEN(p_sbr);
+		    char_attr = hl_attr(HLF_AT);
+		    need_showbreak = FALSE;
+		    /* Correct end of highlighted area for 'showbreak',
+		     * required when 'linebreak' is also set. */
+		    if (tocol == vcol)
+			tocol += n_extra;
+		}
+# endif
+	    }
+#endif
+
+	    if (draw_state == WL_LINE - 1 && n_extra == 0)
+	    {
+		draw_state = WL_LINE;
+		if (saved_n_extra)
+		{
+		    /* Continue item from end of wrapped line. */
+		    n_extra = saved_n_extra;
+		    c_extra = saved_c_extra;
+		    p_extra = saved_p_extra;
+		    char_attr = saved_char_attr;
+		}
+		else
+		    char_attr = 0;
+	    }
+	}
+
+	/* When still displaying '$' of change command, stop at cursor */
+	if (dollar_vcol != 0 && wp == curwin
+		   && lnum == wp->w_cursor.lnum && vcol >= (long)wp->w_virtcol
+#ifdef FEAT_DIFF
+				   && filler_todo <= 0
+#endif
+		)
+	{
+	    SCREEN_LINE(screen_row, W_WINCOL(wp), col, -(int)W_WIDTH(wp),
+								  wp->w_p_rl);
+	    /* Pretend we have finished updating the window.  Except when
+	     * 'cursorcolumn' is set. */
+#ifdef FEAT_SYN_HL
+	    if (wp->w_p_cuc)
+		row = wp->w_cline_row + wp->w_cline_height;
+	    else
+#endif
+		row = wp->w_height;
+	    break;
+	}
+
+	if (draw_state == WL_LINE && area_highlighting)
+	{
+	    /* handle Visual or match highlighting in this line */
+	    if (vcol == fromcol
+#ifdef FEAT_MBYTE
+		    || (has_mbyte && vcol + 1 == fromcol && n_extra == 0
+			&& (*mb_ptr2cells)(ptr) > 1)
+#endif
+		    || ((int)vcol_prev == fromcol_prev
+			&& vcol < tocol))
+		area_attr = attr;		/* start highlighting */
+	    else if (area_attr != 0
+		    && (vcol == tocol
+			|| (noinvcur && (colnr_T)vcol == wp->w_virtcol)))
+		area_attr = 0;			/* stop highlighting */
+
+#ifdef FEAT_SEARCH_EXTRA
+	    if (!n_extra)
+	    {
+		/*
+		 * Check for start/end of search pattern match.
+		 * After end, check for start/end of next match.
+		 * When another match, have to check for start again.
+		 * Watch out for matching an empty string!
+		 * Do this first for search_hl, then for match_hl, so that
+		 * ":match" overrules 'hlsearch'.
+		 */
+		v = (long)(ptr - line);
+		for (i = 3; i >= 0; --i)
+		{
+		    shl = (i == 3) ? &search_hl : &match_hl[i];
+		    while (shl->rm.regprog != NULL)
+		    {
+			if (shl->startcol != MAXCOL
+				&& v >= (long)shl->startcol
+				&& v < (long)shl->endcol)
+			{
+			    shl->attr_cur = shl->attr;
+			}
+			else if (v == (long)shl->endcol)
+			{
+			    shl->attr_cur = 0;
+
+			    next_search_hl(wp, shl, lnum, (colnr_T)v);
+
+			    /* Need to get the line again, a multi-line regexp
+			     * may have made it invalid. */
+			    line = ml_get_buf(wp->w_buffer, lnum, FALSE);
+			    ptr = line + v;
+
+			    if (shl->lnum == lnum)
+			    {
+				shl->startcol = shl->rm.startpos[0].col;
+				if (shl->rm.endpos[0].lnum == 0)
+				    shl->endcol = shl->rm.endpos[0].col;
+				else
+				    shl->endcol = MAXCOL;
+
+				if (shl->startcol == shl->endcol)
+				{
+				    /* highlight empty match, try again after
+				     * it */
+#ifdef FEAT_MBYTE
+				    if (has_mbyte)
+					shl->endcol += (*mb_ptr2len)(line
+							       + shl->endcol);
+				    else
+#endif
+					++shl->endcol;
+				}
+
+				/* Loop to check if the match starts at the
+				 * current position */
+				continue;
+			    }
+			}
+			break;
+		    }
+		}
+
+		/* ":match" highlighting overrules 'hlsearch' */
+		for (i = 0; i <= 3; ++i)
+		    if (i == 3)
+			search_attr = search_hl.attr_cur;
+		    else if (match_hl[i].attr_cur != 0)
+		    {
+			search_attr = match_hl[i].attr_cur;
+			break;
+		    }
+	    }
+#endif
+
+#ifdef FEAT_DIFF
+	    if (diff_hlf != (hlf_T)0)
+	    {
+		if (diff_hlf == HLF_CHD && ptr - line >= change_start)
+		    diff_hlf = HLF_TXD;		/* changed text */
+		if (diff_hlf == HLF_TXD && ptr - line > change_end)
+		    diff_hlf = HLF_CHD;		/* changed line */
+		line_attr = hl_attr(diff_hlf);
+	    }
+#endif
+
+	    /* Decide which of the highlight attributes to use. */
+	    attr_pri = TRUE;
+	    if (area_attr != 0)
+		char_attr = area_attr;
+	    else if (search_attr != 0)
+		char_attr = search_attr;
+#ifdef LINE_ATTR
+		/* Use line_attr when not in the Visual or 'incsearch' area
+		 * (area_attr may be 0 when "noinvcur" is set). */
+	    else if (line_attr != 0 && ((fromcol == -10 && tocol == MAXCOL)
+					|| (vcol < fromcol || vcol >= tocol)))
+		char_attr = line_attr;
+#endif
+	    else
+	    {
+		attr_pri = FALSE;
+#ifdef FEAT_SYN_HL
+		if (has_syntax)
+		    char_attr = syntax_attr;
+		else
+#endif
+		    char_attr = 0;
+	    }
+	}
+
+	/*
+	 * Get the next character to put on the screen.
+	 */
+	/*
+	 * The 'extra' array contains the extra stuff that is inserted to
+	 * represent special characters (non-printable stuff).  When all
+	 * characters are the same, c_extra is used.
+	 * For the '$' of the 'list' option, n_extra == 1, p_extra == "".
+	 */
+	if (n_extra > 0)
+	{
+	    if (c_extra != NUL)
+	    {
+		c = c_extra;
+#ifdef FEAT_MBYTE
+		mb_c = c;	/* doesn't handle non-utf-8 multi-byte! */
+		if (enc_utf8 && (*mb_char2len)(c) > 1)
+		{
+		    mb_utf8 = TRUE;
+		    u8cc[0] = 0;
+		    c = 0xc0;
+		}
+		else
+		    mb_utf8 = FALSE;
+#endif
+	    }
+	    else
+	    {
+		c = *p_extra;
+#ifdef FEAT_MBYTE
+		if (has_mbyte)
+		{
+		    mb_c = c;
+		    if (enc_utf8)
+		    {
+			/* If the UTF-8 character is more than one byte:
+			 * Decode it into "mb_c". */
+			mb_l = (*mb_ptr2len)(p_extra);
+			mb_utf8 = FALSE;
+			if (mb_l > n_extra)
+			    mb_l = 1;
+			else if (mb_l > 1)
+			{
+			    mb_c = utfc_ptr2char(p_extra, u8cc);
+			    mb_utf8 = TRUE;
+			    c = 0xc0;
+			}
+		    }
+		    else
+		    {
+			/* if this is a DBCS character, put it in "mb_c" */
+			mb_l = MB_BYTE2LEN(c);
+			if (mb_l >= n_extra)
+			    mb_l = 1;
+			else if (mb_l > 1)
+			    mb_c = (c << 8) + p_extra[1];
+		    }
+		    if (mb_l == 0)  /* at the NUL at end-of-line */
+			mb_l = 1;
+
+		    /* If a double-width char doesn't fit display a '>' in the
+		     * last column. */
+		    if ((
+# ifdef FEAT_RIGHTLEFT
+			    wp->w_p_rl ? (col <= 0) :
+# endif
+				    (col >= W_WIDTH(wp) - 1))
+			    && (*mb_char2cells)(mb_c) == 2)
+		    {
+			c = '>';
+			mb_c = c;
+			mb_l = 1;
+			mb_utf8 = FALSE;
+			multi_attr = hl_attr(HLF_AT);
+			/* put the pointer back to output the double-width
+			 * character at the start of the next line. */
+			++n_extra;
+			--p_extra;
+		    }
+		    else
+		    {
+			n_extra -= mb_l - 1;
+			p_extra += mb_l - 1;
+		    }
+		}
+#endif
+		++p_extra;
+	    }
+	    --n_extra;
+	}
+	else
+	{
+	    /*
+	     * Get a character from the line itself.
+	     */
+	    c = *ptr;
+#ifdef FEAT_MBYTE
+	    if (has_mbyte)
+	    {
+		mb_c = c;
+		if (enc_utf8)
+		{
+		    /* If the UTF-8 character is more than one byte: Decode it
+		     * into "mb_c". */
+		    mb_l = (*mb_ptr2len)(ptr);
+		    mb_utf8 = FALSE;
+		    if (mb_l > 1)
+		    {
+			mb_c = utfc_ptr2char(ptr, u8cc);
+			/* Overlong encoded ASCII or ASCII with composing char
+			 * is displayed normally, except a NUL. */
+			if (mb_c < 0x80)
+			    c = mb_c;
+			mb_utf8 = TRUE;
+
+			/* At start of the line we can have a composing char.
+			 * Draw it as a space with a composing char. */
+			if (utf_iscomposing(mb_c))
+			{
+			    for (i = Screen_mco - 1; i > 0; --i)
+				u8cc[i] = u8cc[i - 1];
+			    u8cc[0] = mb_c;
+			    mb_c = ' ';
+			}
+		    }
+
+		    if ((mb_l == 1 && c >= 0x80)
+			    || (mb_l >= 1 && mb_c == 0)
+			    || (mb_l > 1 && (!vim_isprintc(mb_c)
+							 || mb_c >= 0x10000)))
+		    {
+			/*
+			 * Illegal UTF-8 byte: display as <xx>.
+			 * Non-BMP character : display as ? or fullwidth ?.
+			 */
+			if (mb_c < 0x10000)
+			{
+			    transchar_hex(extra, mb_c);
+# ifdef FEAT_RIGHTLEFT
+			    if (wp->w_p_rl)		/* reverse */
+				rl_mirror(extra);
+# endif
+			}
+			else if (utf_char2cells(mb_c) != 2)
+			    STRCPY(extra, "?");
+			else
+			    /* 0xff1f in UTF-8: full-width '?' */
+			    STRCPY(extra, "\357\274\237");
+
+			p_extra = extra;
+			c = *p_extra;
+			mb_c = mb_ptr2char_adv(&p_extra);
+			mb_utf8 = (c >= 0x80);
+			n_extra = (int)STRLEN(p_extra);
+			c_extra = NUL;
+			if (area_attr == 0 && search_attr == 0)
+			{
+			    n_attr = n_extra + 1;
+			    extra_attr = hl_attr(HLF_8);
+			    saved_attr2 = char_attr; /* save current attr */
+			}
+		    }
+		    else if (mb_l == 0)  /* at the NUL at end-of-line */
+			mb_l = 1;
+#ifdef FEAT_ARABIC
+		    else if (p_arshape && !p_tbidi && ARABIC_CHAR(mb_c))
+		    {
+			/* Do Arabic shaping. */
+			int	pc, pc1, nc;
+			int	pcc[MAX_MCO];
+
+			/* The idea of what is the previous and next
+			 * character depends on 'rightleft'. */
+			if (wp->w_p_rl)
+			{
+			    pc = prev_c;
+			    pc1 = prev_c1;
+			    nc = utf_ptr2char(ptr + mb_l);
+			    prev_c1 = u8cc[0];
+			}
+			else
+			{
+			    pc = utfc_ptr2char(ptr + mb_l, pcc);
+			    nc = prev_c;
+			    pc1 = pcc[0];
+			}
+			prev_c = mb_c;
+
+			mb_c = arabic_shape(mb_c, &c, &u8cc[0], pc, pc1, nc);
+		    }
+		    else
+			prev_c = mb_c;
+#endif
+		}
+		else	/* enc_dbcs */
+		{
+		    mb_l = MB_BYTE2LEN(c);
+		    if (mb_l == 0)  /* at the NUL at end-of-line */
+			mb_l = 1;
+		    else if (mb_l > 1)
+		    {
+			/* We assume a second byte below 32 is illegal.
+			 * Hopefully this is OK for all double-byte encodings!
+			 */
+			if (ptr[1] >= 32)
+			    mb_c = (c << 8) + ptr[1];
+			else
+			{
+			    if (ptr[1] == NUL)
+			    {
+				/* head byte at end of line */
+				mb_l = 1;
+				transchar_nonprint(extra, c);
+			    }
+			    else
+			    {
+				/* illegal tail byte */
+				mb_l = 2;
+				STRCPY(extra, "XX");
+			    }
+			    p_extra = extra;
+			    n_extra = (int)STRLEN(extra) - 1;
+			    c_extra = NUL;
+			    c = *p_extra++;
+			    if (area_attr == 0 && search_attr == 0)
+			    {
+				n_attr = n_extra + 1;
+				extra_attr = hl_attr(HLF_8);
+				saved_attr2 = char_attr; /* save current attr */
+			    }
+			    mb_c = c;
+			}
+		    }
+		}
+		/* If a double-width char doesn't fit display a '>' in the
+		 * last column; the character is displayed at the start of the
+		 * next line. */
+		if ((
+# ifdef FEAT_RIGHTLEFT
+			    wp->w_p_rl ? (col <= 0) :
+# endif
+				(col >= W_WIDTH(wp) - 1))
+			&& (*mb_char2cells)(mb_c) == 2)
+		{
+		    c = '>';
+		    mb_c = c;
+		    mb_utf8 = FALSE;
+		    mb_l = 1;
+		    multi_attr = hl_attr(HLF_AT);
+		    /* Put pointer back so that the character will be
+		     * displayed at the start of the next line. */
+		    --ptr;
+		}
+		else if (*ptr != NUL)
+		    ptr += mb_l - 1;
+
+		/* If a double-width char doesn't fit at the left side display
+		 * a '<' in the first column. */
+		if (n_skip > 0 && mb_l > 1)
+		{
+		    extra[0] = '<';
+		    p_extra = extra;
+		    n_extra = 1;
+		    c_extra = NUL;
+		    c = ' ';
+		    if (area_attr == 0 && search_attr == 0)
+		    {
+			n_attr = n_extra + 1;
+			extra_attr = hl_attr(HLF_AT);
+			saved_attr2 = char_attr; /* save current attr */
+		    }
+		    mb_c = c;
+		    mb_utf8 = FALSE;
+		    mb_l = 1;
+		}
+
+	    }
+#endif
+	    ++ptr;
+
+	    /* 'list' : change char 160 to lcs_nbsp. */
+	    if (wp->w_p_list && (c == 160
+#ifdef FEAT_MBYTE
+			|| (mb_utf8 && mb_c == 160)
+#endif
+			) && lcs_nbsp)
+	    {
+		c = lcs_nbsp;
+		if (area_attr == 0 && search_attr == 0)
+		{
+		    n_attr = 1;
+		    extra_attr = hl_attr(HLF_8);
+		    saved_attr2 = char_attr; /* save current attr */
+		}
+#ifdef FEAT_MBYTE
+		mb_c = c;
+		if (enc_utf8 && (*mb_char2len)(c) > 1)
+		{
+		    mb_utf8 = TRUE;
+		    u8cc[0] = 0;
+		    c = 0xc0;
+		}
+		else
+		    mb_utf8 = FALSE;
+#endif
+	    }
+
+	    if (extra_check)
+	    {
+#ifdef FEAT_SPELL
+		int	can_spell = TRUE;
+#endif
+
+#ifdef FEAT_SYN_HL
+		/* Get syntax attribute, unless still at the start of the line
+		 * (double-wide char that doesn't fit). */
+		v = (long)(ptr - line);
+		if (has_syntax && v > 0)
+		{
+		    /* Get the syntax attribute for the character.  If there
+		     * is an error, disable syntax highlighting. */
+		    save_did_emsg = did_emsg;
+		    did_emsg = FALSE;
+
+		    syntax_attr = get_syntax_attr((colnr_T)v - 1,
+# ifdef FEAT_SPELL
+					       has_spell ? &can_spell :
+# endif
+					       NULL);
+
+		    if (did_emsg)
+		    {
+			wp->w_buffer->b_syn_error = TRUE;
+			has_syntax = FALSE;
+		    }
+		    else
+			did_emsg = save_did_emsg;
+
+		    /* Need to get the line again, a multi-line regexp may
+		     * have made it invalid. */
+		    line = ml_get_buf(wp->w_buffer, lnum, FALSE);
+		    ptr = line + v;
+
+		    if (!attr_pri)
+			char_attr = syntax_attr;
+		    else
+			char_attr = hl_combine_attr(syntax_attr, char_attr);
+		}
+#endif
+
+#ifdef FEAT_SPELL
+		/* Check spelling (unless at the end of the line).
+		 * Only do this when there is no syntax highlighting, the
+		 * @Spell cluster is not used or the current syntax item
+		 * contains the @Spell cluster. */
+		if (has_spell && v >= word_end && v > cur_checked_col)
+		{
+		    spell_attr = 0;
+# ifdef FEAT_SYN_HL
+		    if (!attr_pri)
+			char_attr = syntax_attr;
+# endif
+		    if (c != 0 && (
+# ifdef FEAT_SYN_HL
+				!has_syntax ||
+# endif
+				can_spell))
+		    {
+			char_u	*prev_ptr, *p;
+			int	len;
+			hlf_T	spell_hlf = HLF_COUNT;
+# ifdef FEAT_MBYTE
+			if (has_mbyte)
+			{
+			    prev_ptr = ptr - mb_l;
+			    v -= mb_l - 1;
+			}
+			else
+# endif
+			    prev_ptr = ptr - 1;
+
+			/* Use nextline[] if possible, it has the start of the
+			 * next line concatenated. */
+			if ((prev_ptr - line) - nextlinecol >= 0)
+			    p = nextline + (prev_ptr - line) - nextlinecol;
+			else
+			    p = prev_ptr;
+			cap_col -= (int)(prev_ptr - line);
+			len = spell_check(wp, p, &spell_hlf, &cap_col,
+								    nochange);
+			word_end = v + len;
+
+			/* In Insert mode only highlight a word that
+			 * doesn't touch the cursor. */
+			if (spell_hlf != HLF_COUNT
+				&& (State & INSERT) != 0
+				&& wp->w_cursor.lnum == lnum
+				&& wp->w_cursor.col >=
+						    (colnr_T)(prev_ptr - line)
+				&& wp->w_cursor.col < (colnr_T)word_end)
+			{
+			    spell_hlf = HLF_COUNT;
+			    spell_redraw_lnum = lnum;
+			}
+
+			if (spell_hlf == HLF_COUNT && p != prev_ptr
+				       && (p - nextline) + len > nextline_idx)
+			{
+			    /* Remember that the good word continues at the
+			     * start of the next line. */
+			    checked_lnum = lnum + 1;
+			    checked_col = (int)((p - nextline) + len - nextline_idx);
+			}
+
+			/* Turn index into actual attributes. */
+			if (spell_hlf != HLF_COUNT)
+			    spell_attr = highlight_attr[spell_hlf];
+
+			if (cap_col > 0)
+			{
+			    if (p != prev_ptr
+				   && (p - nextline) + cap_col >= nextline_idx)
+			    {
+				/* Remember that the word in the next line
+				 * must start with a capital. */
+				capcol_lnum = lnum + 1;
+				cap_col = (int)((p - nextline) + cap_col
+							       - nextline_idx);
+			    }
+			    else
+				/* Compute the actual column. */
+				cap_col += (int)(prev_ptr - line);
+			}
+		    }
+		}
+		if (spell_attr != 0)
+		{
+		    if (!attr_pri)
+			char_attr = hl_combine_attr(char_attr, spell_attr);
+		    else
+			char_attr = hl_combine_attr(spell_attr, char_attr);
+		}
+#endif
+#ifdef FEAT_LINEBREAK
+		/*
+		 * Found last space before word: check for line break.
+		 */
+		if (wp->w_p_lbr && vim_isbreak(c) && !vim_isbreak(*ptr)
+							     && !wp->w_p_list)
+		{
+		    n_extra = win_lbr_chartabsize(wp, ptr - (
+# ifdef FEAT_MBYTE
+				has_mbyte ? mb_l :
+# endif
+				1), (colnr_T)vcol, NULL) - 1;
+		    c_extra = ' ';
+		    if (vim_iswhite(c))
+			c = ' ';
+		}
+#endif
+
+		if (trailcol != MAXCOL && ptr > line + trailcol && c == ' ')
+		{
+		    c = lcs_trail;
+		    if (!attr_pri)
+		    {
+			n_attr = 1;
+			extra_attr = hl_attr(HLF_8);
+			saved_attr2 = char_attr; /* save current attr */
+		    }
+#ifdef FEAT_MBYTE
+		    mb_c = c;
+		    if (enc_utf8 && (*mb_char2len)(c) > 1)
+		    {
+			mb_utf8 = TRUE;
+			u8cc[0] = 0;
+			c = 0xc0;
+		    }
+		    else
+			mb_utf8 = FALSE;
+#endif
+		}
+	    }
+
+	    /*
+	     * Handling of non-printable characters.
+	     */
+	    if (!(chartab[c & 0xff] & CT_PRINT_CHAR))
+	    {
+		/*
+		 * when getting a character from the file, we may have to
+		 * turn it into something else on the way to putting it
+		 * into "ScreenLines".
+		 */
+		if (c == TAB && (!wp->w_p_list || lcs_tab1))
+		{
+		    /* tab amount depends on current column */
+		    n_extra = (int)wp->w_buffer->b_p_ts
+				   - vcol % (int)wp->w_buffer->b_p_ts - 1;
+#ifdef FEAT_MBYTE
+		    mb_utf8 = FALSE;	/* don't draw as UTF-8 */
+#endif
+		    if (wp->w_p_list)
+		    {
+			c = lcs_tab1;
+			c_extra = lcs_tab2;
+			n_attr = n_extra + 1;
+			extra_attr = hl_attr(HLF_8);
+			saved_attr2 = char_attr; /* save current attr */
+#ifdef FEAT_MBYTE
+			mb_c = c;
+			if (enc_utf8 && (*mb_char2len)(c) > 1)
+			{
+			    mb_utf8 = TRUE;
+			    u8cc[0] = 0;
+			    c = 0xc0;
+			}
+#endif
+		    }
+		    else
+		    {
+			c_extra = ' ';
+			c = ' ';
+		    }
+		}
+		else if (c == NUL
+			&& ((wp->w_p_list && lcs_eol > 0)
+			    || ((fromcol >= 0 || fromcol_prev >= 0)
+				&& tocol > vcol
+#ifdef FEAT_VISUAL
+				&& VIsual_mode != Ctrl_V
+#endif
+				&& (
+# ifdef FEAT_RIGHTLEFT
+				    wp->w_p_rl ? (col >= 0) :
+# endif
+				    (col < W_WIDTH(wp)))
+				&& !(noinvcur
+				    && (colnr_T)vcol == wp->w_virtcol)))
+			&& lcs_eol_one >= 0)
+		{
+		    /* Display a '$' after the line or highlight an extra
+		     * character if the line break is included. */
+#if defined(FEAT_DIFF) || defined(LINE_ATTR)
+		    /* For a diff line the highlighting continues after the
+		     * "$". */
+		    if (
+# ifdef FEAT_DIFF
+			    diff_hlf == (hlf_T)0
+#  ifdef LINE_ATTR
+			    &&
+#  endif
+# endif
+# ifdef LINE_ATTR
+			    line_attr == 0
+# endif
+		       )
+#endif
+		    {
+#ifdef FEAT_VIRTUALEDIT
+			/* In virtualedit, visual selections may extend
+			 * beyond end of line. */
+			if (area_highlighting && virtual_active()
+				&& tocol != MAXCOL && vcol < tocol)
+			    n_extra = 0;
+			else
+#endif
+			{
+			    p_extra = at_end_str;
+			    n_extra = 1;
+			    c_extra = NUL;
+			}
+		    }
+		    if (wp->w_p_list)
+			c = lcs_eol;
+		    else
+			c = ' ';
+		    lcs_eol_one = -1;
+		    --ptr;	    /* put it back at the NUL */
+		    if (!attr_pri)
+		    {
+			extra_attr = hl_attr(HLF_AT);
+			n_attr = 1;
+		    }
+#ifdef FEAT_MBYTE
+		    mb_c = c;
+		    if (enc_utf8 && (*mb_char2len)(c) > 1)
+		    {
+			mb_utf8 = TRUE;
+			u8cc[0] = 0;
+			c = 0xc0;
+		    }
+		    else
+			mb_utf8 = FALSE;	/* don't draw as UTF-8 */
+#endif
+		}
+		else if (c != NUL)
+		{
+		    p_extra = transchar(c);
+#ifdef FEAT_RIGHTLEFT
+		    if ((dy_flags & DY_UHEX) && wp->w_p_rl)
+			rl_mirror(p_extra);	/* reverse "<12>" */
+#endif
+		    n_extra = byte2cells(c) - 1;
+		    c_extra = NUL;
+		    c = *p_extra++;
+		    if (!attr_pri)
+		    {
+			n_attr = n_extra + 1;
+			extra_attr = hl_attr(HLF_8);
+			saved_attr2 = char_attr; /* save current attr */
+		    }
+#ifdef FEAT_MBYTE
+		    mb_utf8 = FALSE;	/* don't draw as UTF-8 */
+#endif
+		}
+#ifdef FEAT_VIRTUALEDIT
+		else if (VIsual_active
+			 && (VIsual_mode == Ctrl_V
+			     || VIsual_mode == 'v')
+			 && virtual_active()
+			 && tocol != MAXCOL
+			 && vcol < tocol
+			 && (
+# ifdef FEAT_RIGHTLEFT
+			    wp->w_p_rl ? (col >= 0) :
+# endif
+			    (col < W_WIDTH(wp))))
+		{
+		    c = ' ';
+		    --ptr;	    /* put it back at the NUL */
+		}
+#endif
+#if defined(LINE_ATTR)
+		else if ((
+# ifdef FEAT_DIFF
+			    diff_hlf != (hlf_T)0 ||
+# endif
+			    line_attr != 0
+			) && (
+# ifdef FEAT_RIGHTLEFT
+			    wp->w_p_rl ? (col >= 0) :
+# endif
+			    (col < W_WIDTH(wp))))
+		{
+		    /* Highlight until the right side of the window */
+		    c = ' ';
+		    --ptr;	    /* put it back at the NUL */
+
+		    /* Remember we do the char for line highlighting. */
+		    ++did_line_attr;
+
+		    /* don't do search HL for the rest of the line */
+		    if (line_attr != 0 && char_attr == search_attr && col > 0)
+			char_attr = line_attr;
+# ifdef FEAT_DIFF
+		    if (diff_hlf == HLF_TXD)
+		    {
+			diff_hlf = HLF_CHD;
+			if (attr == 0 || char_attr != attr)
+			    char_attr = hl_attr(diff_hlf);
+		    }
+# endif
+		}
+#endif
+	    }
+	}
+
+	/* Don't override visual selection highlighting. */
+	if (n_attr > 0
+		&& draw_state == WL_LINE
+		&& !attr_pri)
+	    char_attr = extra_attr;
+
+#if defined(FEAT_XIM) && defined(FEAT_GUI_GTK)
+	/* XIM don't send preedit_start and preedit_end, but they send
+	 * preedit_changed and commit.  Thus Vim can't set "im_is_active", use
+	 * im_is_preediting() here. */
+	if (xic != NULL
+		&& lnum == curwin->w_cursor.lnum
+		&& (State & INSERT)
+		&& !p_imdisable
+		&& im_is_preediting()
+		&& draw_state == WL_LINE)
+	{
+	    colnr_T tcol;
+
+	    if (preedit_end_col == MAXCOL)
+		getvcol(curwin, &(curwin->w_cursor), &tcol, NULL, NULL);
+	    else
+		tcol = preedit_end_col;
+	    if ((long)preedit_start_col <= vcol && vcol < (long)tcol)
+	    {
+		if (feedback_old_attr < 0)
+		{
+		    feedback_col = 0;
+		    feedback_old_attr = char_attr;
+		}
+		char_attr = im_get_feedback_attr(feedback_col);
+		if (char_attr < 0)
+		    char_attr = feedback_old_attr;
+		feedback_col++;
+	    }
+	    else if (feedback_old_attr >= 0)
+	    {
+		char_attr = feedback_old_attr;
+		feedback_old_attr = -1;
+		feedback_col = 0;
+	    }
+	}
+#endif
+	/*
+	 * Handle the case where we are in column 0 but not on the first
+	 * character of the line and the user wants us to show us a
+	 * special character (via 'listchars' option "precedes:<char>".
+	 */
+	if (lcs_prec_todo != NUL
+		&& (wp->w_p_wrap ? wp->w_skipcol > 0 : wp->w_leftcol > 0)
+#ifdef FEAT_DIFF
+		&& filler_todo <= 0
+#endif
+		&& draw_state > WL_NR
+		&& c != NUL)
+	{
+	    c = lcs_prec;
+	    lcs_prec_todo = NUL;
+#ifdef FEAT_MBYTE
+	    mb_c = c;
+	    if (enc_utf8 && (*mb_char2len)(c) > 1)
+	    {
+		mb_utf8 = TRUE;
+		u8cc[0] = 0;
+		c = 0xc0;
+	    }
+	    else
+		mb_utf8 = FALSE;	/* don't draw as UTF-8 */
+#endif
+	    if (!attr_pri)
+	    {
+		saved_attr3 = char_attr; /* save current attr */
+		char_attr = hl_attr(HLF_AT); /* later copied to char_attr */
+		n_attr3 = 1;
+	    }
+	}
+
+	/*
+	 * At end of the text line or just after the last character.
+	 */
+	if (c == NUL
+#if defined(LINE_ATTR)
+		|| did_line_attr == 1
+#endif
+		)
+	{
+#ifdef FEAT_SEARCH_EXTRA
+	    long prevcol = (long)(ptr - line) - (c == NUL);
+#endif
+
+	    /* invert at least one char, used for Visual and empty line or
+	     * highlight match at end of line. If it's beyond the last
+	     * char on the screen, just overwrite that one (tricky!)  Not
+	     * needed when a '$' was displayed for 'list'. */
+	    if (lcs_eol == lcs_eol_one
+		    && ((area_attr != 0 && vcol == fromcol && c == NUL)
+#ifdef FEAT_SEARCH_EXTRA
+			/* highlight 'hlsearch' match at end of line */
+			|| ((prevcol == (long)search_hl.startcol
+				|| prevcol == (long)match_hl[0].startcol
+				|| prevcol == (long)match_hl[1].startcol
+				|| prevcol == (long)match_hl[2].startcol)
+# if defined(LINE_ATTR)
+			    && did_line_attr <= 1
+# endif
+			   )
+#endif
+		       ))
+	    {
+		int n = 0;
+
+#ifdef FEAT_RIGHTLEFT
+		if (wp->w_p_rl)
+		{
+		    if (col < 0)
+			n = 1;
+		}
+		else
+#endif
+		{
+		    if (col >= W_WIDTH(wp))
+			n = -1;
+		}
+		if (n != 0)
+		{
+		    /* At the window boundary, highlight the last character
+		     * instead (better than nothing). */
+		    off += n;
+		    col += n;
+		}
+		else
+		{
+		    /* Add a blank character to highlight. */
+		    ScreenLines[off] = ' ';
+#ifdef FEAT_MBYTE
+		    if (enc_utf8)
+			ScreenLinesUC[off] = 0;
+#endif
+		}
+#ifdef FEAT_SEARCH_EXTRA
+		if (area_attr == 0)
+		{
+		    for (i = 0; i <= 3; ++i)
+		    {
+			if (i == 3)
+			    char_attr = search_hl.attr;
+			else if ((ptr - line) - 1 == (long)match_hl[i].startcol)
+			{
+			    char_attr = match_hl[i].attr;
+			    break;
+			}
+		    }
+		}
+#endif
+		ScreenAttrs[off] = char_attr;
+#ifdef FEAT_RIGHTLEFT
+		if (wp->w_p_rl)
+		    --col;
+		else
+#endif
+		    ++col;
+		++vcol;
+	    }
+	}
+
+	/*
+	 * At end of the text line.
+	 */
+	if (c == NUL)
+	{
+#ifdef FEAT_SYN_HL
+	    /* Highlight 'cursorcolumn' past end of the line. */
+	    if (wp->w_p_wrap)
+		v = wp->w_skipcol;
+	    else
+		v = wp->w_leftcol;
+	    /* check if line ends before left margin */
+	    if (vcol < v + col - win_col_off(wp))
+
+		vcol = v + col - win_col_off(wp);
+	    if (wp->w_p_cuc
+		    && (int)wp->w_virtcol >= vcol
+		    && (int)wp->w_virtcol < W_WIDTH(wp) * (row - startrow + 1)
+									   + v
+		    && lnum != wp->w_cursor.lnum
+# ifdef FEAT_RIGHTLEFT
+		    && !wp->w_p_rl
+# endif
+		    )
+	    {
+		while (col < W_WIDTH(wp))
+		{
+		    ScreenLines[off] = ' ';
+#ifdef FEAT_MBYTE
+		    if (enc_utf8)
+			ScreenLinesUC[off] = 0;
+#endif
+		    ++col;
+		    if (vcol == (long)wp->w_virtcol)
+		    {
+			ScreenAttrs[off] = hl_attr(HLF_CUC);
+			break;
+		    }
+		    ScreenAttrs[off++] = 0;
+		    ++vcol;
+		}
+	    }
+#endif
+
+	    SCREEN_LINE(screen_row, W_WINCOL(wp), col, (int)W_WIDTH(wp),
+								  wp->w_p_rl);
+	    row++;
+
+	    /*
+	     * Update w_cline_height and w_cline_folded if the cursor line was
+	     * updated (saves a call to plines() later).
+	     */
+	    if (wp == curwin && lnum == curwin->w_cursor.lnum)
+	    {
+		curwin->w_cline_row = startrow;
+		curwin->w_cline_height = row - startrow;
+#ifdef FEAT_FOLDING
+		curwin->w_cline_folded = FALSE;
+#endif
+		curwin->w_valid |= (VALID_CHEIGHT|VALID_CROW);
+	    }
+
+	    break;
+	}
+
+	/* line continues beyond line end */
+	if (lcs_ext
+		&& !wp->w_p_wrap
+#ifdef FEAT_DIFF
+		&& filler_todo <= 0
+#endif
+		&& (
+#ifdef FEAT_RIGHTLEFT
+		    wp->w_p_rl ? col == 0 :
+#endif
+		    col == W_WIDTH(wp) - 1)
+		&& (*ptr != NUL
+		    || (wp->w_p_list && lcs_eol != NUL && p_extra != at_end_str)
+		    || (n_extra && (c_extra != NUL || *p_extra != NUL))))
+	{
+	    c = lcs_ext;
+	    char_attr = hl_attr(HLF_AT);
+#ifdef FEAT_MBYTE
+	    mb_c = c;
+	    if (enc_utf8 && (*mb_char2len)(c) > 1)
+	    {
+		mb_utf8 = TRUE;
+		u8cc[0] = 0;
+		c = 0xc0;
+	    }
+	    else
+		mb_utf8 = FALSE;
+#endif
+	}
+
+#ifdef FEAT_SYN_HL
+	/* Highlight the cursor column if 'cursorcolumn' is set.  But don't
+	 * highlight the cursor position itself. */
+	if (wp->w_p_cuc && vcol == (long)wp->w_virtcol
+		&& lnum != wp->w_cursor.lnum
+		&& draw_state == WL_LINE)
+	{
+	    vcol_save_attr = char_attr;
+	    char_attr = hl_combine_attr(char_attr, hl_attr(HLF_CUC));
+	}
+	else
+	    vcol_save_attr = -1;
+#endif
+
+	/*
+	 * Store character to be displayed.
+	 * Skip characters that are left of the screen for 'nowrap'.
+	 */
+	vcol_prev = vcol;
+	if (draw_state < WL_LINE || n_skip <= 0)
+	{
+	    /*
+	     * Store the character.
+	     */
+#if defined(FEAT_RIGHTLEFT) && defined(FEAT_MBYTE)
+	    if (has_mbyte && wp->w_p_rl && (*mb_char2cells)(mb_c) > 1)
+	    {
+		/* A double-wide character is: put first halve in left cell. */
+		--off;
+		--col;
+	    }
+#endif
+	    ScreenLines[off] = c;
+#ifdef FEAT_MBYTE
+	    if (enc_dbcs == DBCS_JPNU)
+		ScreenLines2[off] = mb_c & 0xff;
+	    else if (enc_utf8)
+	    {
+		if (mb_utf8)
+		{
+		    ScreenLinesUC[off] = mb_c;
+		    if ((c & 0xff) == 0)
+			ScreenLines[off] = 0x80;   /* avoid storing zero */
+		    for (i = 0; i < Screen_mco; ++i)
+		    {
+			ScreenLinesC[i][off] = u8cc[i];
+			if (u8cc[i] == 0)
+			    break;
+		    }
+		}
+		else
+		    ScreenLinesUC[off] = 0;
+	    }
+	    if (multi_attr)
+	    {
+		ScreenAttrs[off] = multi_attr;
+		multi_attr = 0;
+	    }
+	    else
+#endif
+		ScreenAttrs[off] = char_attr;
+
+#ifdef FEAT_MBYTE
+	    if (has_mbyte && (*mb_char2cells)(mb_c) > 1)
+	    {
+		/* Need to fill two screen columns. */
+		++off;
+		++col;
+		if (enc_utf8)
+		    /* UTF-8: Put a 0 in the second screen char. */
+		    ScreenLines[off] = 0;
+		else
+		    /* DBCS: Put second byte in the second screen char. */
+		    ScreenLines[off] = mb_c & 0xff;
+		++vcol;
+		/* When "tocol" is halfway a character, set it to the end of
+		 * the character, otherwise highlighting won't stop. */
+		if (tocol == vcol)
+		    ++tocol;
+#ifdef FEAT_RIGHTLEFT
+		if (wp->w_p_rl)
+		{
+		    /* now it's time to backup one cell */
+		    --off;
+		    --col;
+		}
+#endif
+	    }
+#endif
+#ifdef FEAT_RIGHTLEFT
+	    if (wp->w_p_rl)
+	    {
+		--off;
+		--col;
+	    }
+	    else
+#endif
+	    {
+		++off;
+		++col;
+	    }
+	}
+	else
+	    --n_skip;
+
+	/* Only advance the "vcol" when after the 'number' column. */
+	if (draw_state >= WL_SBR
+#ifdef FEAT_DIFF
+		&& filler_todo <= 0
+#endif
+		)
+	    ++vcol;
+
+#ifdef FEAT_SYN_HL
+	if (vcol_save_attr >= 0)
+	    char_attr = vcol_save_attr;
+#endif
+
+	/* restore attributes after "predeces" in 'listchars' */
+	if (draw_state > WL_NR && n_attr3 > 0 && --n_attr3 == 0)
+	    char_attr = saved_attr3;
+
+	/* restore attributes after last 'listchars' or 'number' char */
+	if (n_attr > 0 && draw_state == WL_LINE && --n_attr == 0)
+	    char_attr = saved_attr2;
+
+	/*
+	 * At end of screen line and there is more to come: Display the line
+	 * so far.  If there is no more to display it is catched above.
+	 */
+	if ((
+#ifdef FEAT_RIGHTLEFT
+	    wp->w_p_rl ? (col < 0) :
+#endif
+				    (col >= W_WIDTH(wp)))
+		&& (*ptr != NUL
+#ifdef FEAT_DIFF
+		    || filler_todo > 0
+#endif
+		    || (wp->w_p_list && lcs_eol != NUL && p_extra != at_end_str)
+		    || (n_extra != 0 && (c_extra != NUL || *p_extra != NUL)))
+		)
+	{
+	    SCREEN_LINE(screen_row, W_WINCOL(wp), col, (int)W_WIDTH(wp),
+								  wp->w_p_rl);
+	    ++row;
+	    ++screen_row;
+
+	    /* When not wrapping and finished diff lines, or when displayed
+	     * '$' and highlighting until last column, break here. */
+	    if ((!wp->w_p_wrap
+#ifdef FEAT_DIFF
+		    && filler_todo <= 0
+#endif
+		    ) || lcs_eol_one == -1)
+		break;
+
+	    /* When the window is too narrow draw all "@" lines. */
+	    if (draw_state != WL_LINE
+#ifdef FEAT_DIFF
+		    && filler_todo <= 0
+#endif
+		    )
+	    {
+		win_draw_end(wp, '@', ' ', row, wp->w_height, HLF_AT);
+#ifdef FEAT_VERTSPLIT
+		draw_vsep_win(wp, row);
+#endif
+		row = endrow;
+	    }
+
+	    /* When line got too long for screen break here. */
+	    if (row == endrow)
+	    {
+		++row;
+		break;
+	    }
+
+	    if (screen_cur_row == screen_row - 1
+#ifdef FEAT_DIFF
+		     && filler_todo <= 0
+#endif
+		     && W_WIDTH(wp) == Columns)
+	    {
+		/* Remember that the line wraps, used for modeless copy. */
+		LineWraps[screen_row - 1] = TRUE;
+
+		/*
+		 * Special trick to make copy/paste of wrapped lines work with
+		 * xterm/screen: write an extra character beyond the end of
+		 * the line. This will work with all terminal types
+		 * (regardless of the xn,am settings).
+		 * Only do this on a fast tty.
+		 * Only do this if the cursor is on the current line
+		 * (something has been written in it).
+		 * Don't do this for the GUI.
+		 * Don't do this for double-width characters.
+		 * Don't do this for a window not at the right screen border.
+		 */
+		if (p_tf
+#ifdef FEAT_GUI
+			 && !gui.in_use
+#endif
+#ifdef FEAT_MBYTE
+			 && !(has_mbyte
+			     && ((*mb_off2cells)(LineOffset[screen_row]) == 2
+				 || (*mb_off2cells)(LineOffset[screen_row - 1]
+							+ (int)Columns - 2) == 2))
+#endif
+		   )
+		{
+		    /* First make sure we are at the end of the screen line,
+		     * then output the same character again to let the
+		     * terminal know about the wrap.  If the terminal doesn't
+		     * auto-wrap, we overwrite the character. */
+		    if (screen_cur_col != W_WIDTH(wp))
+			screen_char(LineOffset[screen_row - 1]
+						      + (unsigned)Columns - 1,
+					  screen_row - 1, (int)(Columns - 1));
+
+#ifdef FEAT_MBYTE
+		    /* When there is a multi-byte character, just output a
+		     * space to keep it simple. */
+		    if (has_mbyte && MB_BYTE2LEN(ScreenLines[LineOffset[
+					screen_row - 1] + (Columns - 1)]) > 1)
+			out_char(' ');
+		    else
+#endif
+			out_char(ScreenLines[LineOffset[screen_row - 1]
+							    + (Columns - 1)]);
+		    /* force a redraw of the first char on the next line */
+		    ScreenAttrs[LineOffset[screen_row]] = (sattr_T)-1;
+		    screen_start();	/* don't know where cursor is now */
+		}
+	    }
+
+	    col = 0;
+	    off = (unsigned)(current_ScreenLine - ScreenLines);
+#ifdef FEAT_RIGHTLEFT
+	    if (wp->w_p_rl)
+	    {
+		col = W_WIDTH(wp) - 1;	/* col is not used if breaking! */
+		off += col;
+	    }
+#endif
+
+	    /* reset the drawing state for the start of a wrapped line */
+	    draw_state = WL_START;
+	    saved_n_extra = n_extra;
+	    saved_p_extra = p_extra;
+	    saved_c_extra = c_extra;
+	    saved_char_attr = char_attr;
+	    n_extra = 0;
+	    lcs_prec_todo = lcs_prec;
+#ifdef FEAT_LINEBREAK
+# ifdef FEAT_DIFF
+	    if (filler_todo <= 0)
+# endif
+		need_showbreak = TRUE;
+#endif
+#ifdef FEAT_DIFF
+	    --filler_todo;
+	    /* When the filler lines are actually below the last line of the
+	     * file, don't draw the line itself, break here. */
+	    if (filler_todo == 0 && wp->w_botfill)
+		break;
+#endif
+	}
+
+    }	/* for every character in the line */
+
+#ifdef FEAT_SPELL
+    /* After an empty line check first word for capital. */
+    if (*skipwhite(line) == NUL)
+    {
+	capcol_lnum = lnum + 1;
+	cap_col = 0;
+    }
+#endif
+
+    return row;
+}
+
+#ifdef FEAT_MBYTE
+static int comp_char_differs __ARGS((int, int));
+
+/*
+ * Return if the composing characters at "off_from" and "off_to" differ.
+ */
+    static int
+comp_char_differs(off_from, off_to)
+    int	    off_from;
+    int	    off_to;
+{
+    int	    i;
+
+    for (i = 0; i < Screen_mco; ++i)
+    {
+	if (ScreenLinesC[i][off_from] != ScreenLinesC[i][off_to])
+	    return TRUE;
+	if (ScreenLinesC[i][off_from] == 0)
+	    break;
+    }
+    return FALSE;
+}
+#endif
+
+/*
+ * Check whether the given character needs redrawing:
+ * - the (first byte of the) character is different
+ * - the attributes are different
+ * - the character is multi-byte and the next byte is different
+ */
+    static int
+char_needs_redraw(off_from, off_to, cols)
+    int		off_from;
+    int		off_to;
+    int		cols;
+{
+    if (cols > 0
+	    && ((ScreenLines[off_from] != ScreenLines[off_to]
+		    || ScreenAttrs[off_from] != ScreenAttrs[off_to])
+
+#ifdef FEAT_MBYTE
+		|| (enc_dbcs != 0
+		    && MB_BYTE2LEN(ScreenLines[off_from]) > 1
+		    && (enc_dbcs == DBCS_JPNU && ScreenLines[off_from] == 0x8e
+			? ScreenLines2[off_from] != ScreenLines2[off_to]
+			: (cols > 1 && ScreenLines[off_from + 1]
+						 != ScreenLines[off_to + 1])))
+		|| (enc_utf8
+		    && (ScreenLinesUC[off_from] != ScreenLinesUC[off_to]
+			|| (ScreenLinesUC[off_from] != 0
+			    && comp_char_differs(off_from, off_to))))
+#endif
+	       ))
+	return TRUE;
+    return FALSE;
+}
+
+/*
+ * Move one "cooked" screen line to the screen, but only the characters that
+ * have actually changed.  Handle insert/delete character.
+ * "coloff" gives the first column on the screen for this line.
+ * "endcol" gives the columns where valid characters are.
+ * "clear_width" is the width of the window.  It's > 0 if the rest of the line
+ * needs to be cleared, negative otherwise.
+ * "rlflag" is TRUE in a rightleft window:
+ *    When TRUE and "clear_width" > 0, clear columns 0 to "endcol"
+ *    When FALSE and "clear_width" > 0, clear columns "endcol" to "clear_width"
+ */
+    static void
+screen_line(row, coloff, endcol, clear_width
+#ifdef FEAT_RIGHTLEFT
+				    , rlflag
+#endif
+						)
+    int	    row;
+    int	    coloff;
+    int	    endcol;
+    int	    clear_width;
+#ifdef FEAT_RIGHTLEFT
+    int	    rlflag;
+#endif
+{
+    unsigned	    off_from;
+    unsigned	    off_to;
+    int		    col = 0;
+#if defined(FEAT_GUI) || defined(UNIX) || defined(FEAT_VERTSPLIT)
+    int		    hl;
+#endif
+    int		    force = FALSE;	/* force update rest of the line */
+    int		    redraw_this		/* bool: does character need redraw? */
+#ifdef FEAT_GUI
+				= TRUE	/* For GUI when while-loop empty */
+#endif
+				;
+    int		    redraw_next;	/* redraw_this for next character */
+#ifdef FEAT_MBYTE
+    int		    clear_next = FALSE;
+    int		    char_cells;		/* 1: normal char */
+					/* 2: occupies two display cells */
+# define CHAR_CELLS char_cells
+#else
+# define CHAR_CELLS 1
+#endif
+
+# ifdef FEAT_CLIPBOARD
+    clip_may_clear_selection(row, row);
+# endif
+
+    off_from = (unsigned)(current_ScreenLine - ScreenLines);
+    off_to = LineOffset[row] + coloff;
+
+#ifdef FEAT_RIGHTLEFT
+    if (rlflag)
+    {
+	/* Clear rest first, because it's left of the text. */
+	if (clear_width > 0)
+	{
+	    while (col <= endcol && ScreenLines[off_to] == ' '
+		    && ScreenAttrs[off_to] == 0
+# ifdef FEAT_MBYTE
+				  && (!enc_utf8 || ScreenLinesUC[off_to] == 0)
+# endif
+						  )
+	    {
+		++off_to;
+		++col;
+	    }
+	    if (col <= endcol)
+		screen_fill(row, row + 1, col + coloff,
+					    endcol + coloff + 1, ' ', ' ', 0);
+	}
+	col = endcol + 1;
+	off_to = LineOffset[row] + col + coloff;
+	off_from += col;
+	endcol = (clear_width > 0 ? clear_width : -clear_width);
+    }
+#endif /* FEAT_RIGHTLEFT */
+
+    redraw_next = char_needs_redraw(off_from, off_to, endcol - col);
+
+    while (col < endcol)
+    {
+#ifdef FEAT_MBYTE
+	if (has_mbyte && (col + 1 < endcol))
+	    char_cells = (*mb_off2cells)(off_from);
+	else
+	    char_cells = 1;
+#endif
+
+	redraw_this = redraw_next;
+	redraw_next = force || char_needs_redraw(off_from + CHAR_CELLS,
+			      off_to + CHAR_CELLS, endcol - col - CHAR_CELLS);
+
+#ifdef FEAT_GUI
+	/* If the next character was bold, then redraw the current character to
+	 * remove any pixels that might have spilt over into us.  This only
+	 * happens in the GUI.
+	 */
+	if (redraw_next && gui.in_use)
+	{
+	    hl = ScreenAttrs[off_to + CHAR_CELLS];
+	    if (hl > HL_ALL)
+		hl = syn_attr2attr(hl);
+	    if (hl & HL_BOLD)
+		redraw_this = TRUE;
+	}
+#endif
+
+	if (redraw_this)
+	{
+	    /*
+	     * Special handling when 'xs' termcap flag set (hpterm):
+	     * Attributes for characters are stored at the position where the
+	     * cursor is when writing the highlighting code.  The
+	     * start-highlighting code must be written with the cursor on the
+	     * first highlighted character.  The stop-highlighting code must
+	     * be written with the cursor just after the last highlighted
+	     * character.
+	     * Overwriting a character doesn't remove it's highlighting.  Need
+	     * to clear the rest of the line, and force redrawing it
+	     * completely.
+	     */
+	    if (       p_wiv
+		    && !force
+#ifdef FEAT_GUI
+		    && !gui.in_use
+#endif
+		    && ScreenAttrs[off_to] != 0
+		    && ScreenAttrs[off_from] != ScreenAttrs[off_to])
+	    {
+		/*
+		 * Need to remove highlighting attributes here.
+		 */
+		windgoto(row, col + coloff);
+		out_str(T_CE);		/* clear rest of this screen line */
+		screen_start();		/* don't know where cursor is now */
+		force = TRUE;		/* force redraw of rest of the line */
+		redraw_next = TRUE;	/* or else next char would miss out */
+
+		/*
+		 * If the previous character was highlighted, need to stop
+		 * highlighting at this character.
+		 */
+		if (col + coloff > 0 && ScreenAttrs[off_to - 1] != 0)
+		{
+		    screen_attr = ScreenAttrs[off_to - 1];
+		    term_windgoto(row, col + coloff);
+		    screen_stop_highlight();
+		}
+		else
+		    screen_attr = 0;	    /* highlighting has stopped */
+	    }
+#ifdef FEAT_MBYTE
+	    if (enc_dbcs != 0)
+	    {
+		/* Check if overwriting a double-byte with a single-byte or
+		 * the other way around requires another character to be
+		 * redrawn.  For UTF-8 this isn't needed, because comparing
+		 * ScreenLinesUC[] is sufficient. */
+		if (char_cells == 1
+			&& col + 1 < endcol
+			&& (*mb_off2cells)(off_to) > 1)
+		{
+		    /* Writing a single-cell character over a double-cell
+		     * character: need to redraw the next cell. */
+		    ScreenLines[off_to + 1] = 0;
+		    redraw_next = TRUE;
+		}
+		else if (char_cells == 2
+			&& col + 2 < endcol
+			&& (*mb_off2cells)(off_to) == 1
+			&& (*mb_off2cells)(off_to + 1) > 1)
+		{
+		    /* Writing the second half of a double-cell character over
+		     * a double-cell character: need to redraw the second
+		     * cell. */
+		    ScreenLines[off_to + 2] = 0;
+		    redraw_next = TRUE;
+		}
+
+		if (enc_dbcs == DBCS_JPNU)
+		    ScreenLines2[off_to] = ScreenLines2[off_from];
+	    }
+	    /* When writing a single-width character over a double-width
+	     * character and at the end of the redrawn text, need to clear out
+	     * the right halve of the old character.
+	     * Also required when writing the right halve of a double-width
+	     * char over the left halve of an existing one. */
+	    if (has_mbyte && col + char_cells == endcol
+		    && ((char_cells == 1
+			    && (*mb_off2cells)(off_to) > 1)
+			|| (char_cells == 2
+			    && (*mb_off2cells)(off_to) == 1
+			    && (*mb_off2cells)(off_to + 1) > 1)))
+		clear_next = TRUE;
+#endif
+
+	    ScreenLines[off_to] = ScreenLines[off_from];
+#ifdef FEAT_MBYTE
+	    if (enc_utf8)
+	    {
+		ScreenLinesUC[off_to] = ScreenLinesUC[off_from];
+		if (ScreenLinesUC[off_from] != 0)
+		{
+		    int	    i;
+
+		    for (i = 0; i < Screen_mco; ++i)
+			ScreenLinesC[i][off_to] = ScreenLinesC[i][off_from];
+		}
+	    }
+	    if (char_cells == 2)
+		ScreenLines[off_to + 1] = ScreenLines[off_from + 1];
+#endif
+
+#if defined(FEAT_GUI) || defined(UNIX)
+	    /* The bold trick makes a single row of pixels appear in the next
+	     * character.  When a bold character is removed, the next
+	     * character should be redrawn too.  This happens for our own GUI
+	     * and for some xterms. */
+	    if (
+# ifdef FEAT_GUI
+		    gui.in_use
+# endif
+# if defined(FEAT_GUI) && defined(UNIX)
+		    ||
+# endif
+# ifdef UNIX
+		    term_is_xterm
+# endif
+		    )
+	    {
+		hl = ScreenAttrs[off_to];
+		if (hl > HL_ALL)
+		    hl = syn_attr2attr(hl);
+		if (hl & HL_BOLD)
+		    redraw_next = TRUE;
+	    }
+#endif
+	    ScreenAttrs[off_to] = ScreenAttrs[off_from];
+#ifdef FEAT_MBYTE
+	    /* For simplicity set the attributes of second half of a
+	     * double-wide character equal to the first half. */
+	    if (char_cells == 2)
+		ScreenAttrs[off_to + 1] = ScreenAttrs[off_from];
+
+	    if (enc_dbcs != 0 && char_cells == 2)
+		screen_char_2(off_to, row, col + coloff);
+	    else
+#endif
+		screen_char(off_to, row, col + coloff);
+	}
+	else if (  p_wiv
+#ifdef FEAT_GUI
+		&& !gui.in_use
+#endif
+		&& col + coloff > 0)
+	{
+	    if (ScreenAttrs[off_to] == ScreenAttrs[off_to - 1])
+	    {
+		/*
+		 * Don't output stop-highlight when moving the cursor, it will
+		 * stop the highlighting when it should continue.
+		 */
+		screen_attr = 0;
+	    }
+	    else if (screen_attr != 0)
+		screen_stop_highlight();
+	}
+
+	off_to += CHAR_CELLS;
+	off_from += CHAR_CELLS;
+	col += CHAR_CELLS;
+    }
+
+#ifdef FEAT_MBYTE
+    if (clear_next)
+    {
+	/* Clear the second half of a double-wide character of which the left
+	 * half was overwritten with a single-wide character. */
+	ScreenLines[off_to] = ' ';
+	if (enc_utf8)
+	    ScreenLinesUC[off_to] = 0;
+	screen_char(off_to, row, col + coloff);
+    }
+#endif
+
+    if (clear_width > 0
+#ifdef FEAT_RIGHTLEFT
+		    && !rlflag
+#endif
+				   )
+    {
+#ifdef FEAT_GUI
+	int startCol = col;
+#endif
+
+	/* blank out the rest of the line */
+	while (col < clear_width && ScreenLines[off_to] == ' '
+						  && ScreenAttrs[off_to] == 0
+#ifdef FEAT_MBYTE
+				  && (!enc_utf8 || ScreenLinesUC[off_to] == 0)
+#endif
+						  )
+	{
+	    ++off_to;
+	    ++col;
+	}
+	if (col < clear_width)
+	{
+#ifdef FEAT_GUI
+	    /*
+	     * In the GUI, clearing the rest of the line may leave pixels
+	     * behind if the first character cleared was bold.  Some bold
+	     * fonts spill over the left.  In this case we redraw the previous
+	     * character too.  If we didn't skip any blanks above, then we
+	     * only redraw if the character wasn't already redrawn anyway.
+	     */
+	    if (gui.in_use && (col > startCol || !redraw_this))
+	    {
+		hl = ScreenAttrs[off_to];
+		if (hl > HL_ALL || (hl & HL_BOLD))
+		{
+		    int prev_cells = 1;
+# ifdef FEAT_MBYTE
+		    if (enc_utf8)
+			/* for utf-8, ScreenLines[char_offset + 1] == 0 means
+			 * that its width is 2. */
+			prev_cells = ScreenLines[off_to - 1] == 0 ? 2 : 1;
+		    else if (enc_dbcs != 0)
+		    {
+			/* find previous character by counting from first
+			 * column and get its width. */
+			unsigned off = LineOffset[row];
+
+			while (off < off_to)
+			{
+			    prev_cells = (*mb_off2cells)(off);
+			    off += prev_cells;
+			}
+		    }
+
+		    if (enc_dbcs != 0 && prev_cells > 1)
+			screen_char_2(off_to - prev_cells, row,
+						   col + coloff - prev_cells);
+		    else
+# endif
+			screen_char(off_to - prev_cells, row,
+						   col + coloff - prev_cells);
+		}
+	    }
+#endif
+	    screen_fill(row, row + 1, col + coloff, clear_width + coloff,
+								 ' ', ' ', 0);
+#ifdef FEAT_VERTSPLIT
+	    off_to += clear_width - col;
+	    col = clear_width;
+#endif
+	}
+    }
+
+    if (clear_width > 0)
+    {
+#ifdef FEAT_VERTSPLIT
+	/* For a window that's left of another, draw the separator char. */
+	if (col + coloff < Columns)
+	{
+	    int c;
+
+	    c = fillchar_vsep(&hl);
+	    if (ScreenLines[off_to] != c
+# ifdef FEAT_MBYTE
+		    || (enc_utf8 && (int)ScreenLinesUC[off_to]
+						       != (c >= 0x80 ? c : 0))
+# endif
+		    || ScreenAttrs[off_to] != hl)
+	    {
+		ScreenLines[off_to] = c;
+		ScreenAttrs[off_to] = hl;
+# ifdef FEAT_MBYTE
+		if (enc_utf8)
+		{
+		    if (c >= 0x80)
+		    {
+			ScreenLinesUC[off_to] = c;
+			ScreenLinesC[0][off_to] = 0;
+		    }
+		    else
+			ScreenLinesUC[off_to] = 0;
+		}
+# endif
+		screen_char(off_to, row, col + coloff);
+	    }
+	}
+	else
+#endif
+	    LineWraps[row] = FALSE;
+    }
+}
+
+#if defined(FEAT_RIGHTLEFT) || defined(PROTO)
+/*
+ * Mirror text "str" for right-left displaying.
+ * Only works for single-byte characters (e.g., numbers).
+ */
+    void
+rl_mirror(str)
+    char_u	*str;
+{
+    char_u	*p1, *p2;
+    int		t;
+
+    for (p1 = str, p2 = str + STRLEN(str) - 1; p1 < p2; ++p1, --p2)
+    {
+	t = *p1;
+	*p1 = *p2;
+	*p2 = t;
+    }
+}
+#endif
+
+#if defined(FEAT_WINDOWS) || defined(PROTO)
+/*
+ * mark all status lines for redraw; used after first :cd
+ */
+    void
+status_redraw_all()
+{
+    win_T	*wp;
+
+    for (wp = firstwin; wp; wp = wp->w_next)
+	if (wp->w_status_height)
+	{
+	    wp->w_redr_status = TRUE;
+	    redraw_later(VALID);
+	}
+}
+
+/*
+ * mark all status lines of the current buffer for redraw
+ */
+    void
+status_redraw_curbuf()
+{
+    win_T	*wp;
+
+    for (wp = firstwin; wp; wp = wp->w_next)
+	if (wp->w_status_height != 0 && wp->w_buffer == curbuf)
+	{
+	    wp->w_redr_status = TRUE;
+	    redraw_later(VALID);
+	}
+}
+
+/*
+ * Redraw all status lines that need to be redrawn.
+ */
+    void
+redraw_statuslines()
+{
+    win_T	*wp;
+
+    for (wp = firstwin; wp; wp = wp->w_next)
+	if (wp->w_redr_status)
+	    win_redr_status(wp);
+    if (redraw_tabline)
+	draw_tabline();
+}
+#endif
+
+#if (defined(FEAT_WILDMENU) && defined(FEAT_VERTSPLIT)) || defined(PROTO)
+/*
+ * Redraw all status lines at the bottom of frame "frp".
+ */
+    void
+win_redraw_last_status(frp)
+    frame_T	*frp;
+{
+    if (frp->fr_layout == FR_LEAF)
+	frp->fr_win->w_redr_status = TRUE;
+    else if (frp->fr_layout == FR_ROW)
+    {
+	for (frp = frp->fr_child; frp != NULL; frp = frp->fr_next)
+	    win_redraw_last_status(frp);
+    }
+    else /* frp->fr_layout == FR_COL */
+    {
+	frp = frp->fr_child;
+	while (frp->fr_next != NULL)
+	    frp = frp->fr_next;
+	win_redraw_last_status(frp);
+    }
+}
+#endif
+
+#ifdef FEAT_VERTSPLIT
+/*
+ * Draw the verticap separator right of window "wp" starting with line "row".
+ */
+    static void
+draw_vsep_win(wp, row)
+    win_T	*wp;
+    int		row;
+{
+    int		hl;
+    int		c;
+
+    if (wp->w_vsep_width)
+    {
+	/* draw the vertical separator right of this window */
+	c = fillchar_vsep(&hl);
+	screen_fill(W_WINROW(wp) + row, W_WINROW(wp) + wp->w_height,
+		W_ENDCOL(wp), W_ENDCOL(wp) + 1,
+		c, ' ', hl);
+    }
+}
+#endif
+
+#ifdef FEAT_WILDMENU
+static int status_match_len __ARGS((expand_T *xp, char_u *s));
+static int skip_status_match_char __ARGS((expand_T *xp, char_u *s));
+
+/*
+ * Get the lenght of an item as it will be shown in the status line.
+ */
+    static int
+status_match_len(xp, s)
+    expand_T	*xp;
+    char_u	*s;
+{
+    int	len = 0;
+
+#ifdef FEAT_MENU
+    int emenu = (xp->xp_context == EXPAND_MENUS
+	    || xp->xp_context == EXPAND_MENUNAMES);
+
+    /* Check for menu separators - replace with '|'. */
+    if (emenu && menu_is_separator(s))
+	return 1;
+#endif
+
+    while (*s != NUL)
+    {
+	if (skip_status_match_char(xp, s))
+	    ++s;
+	len += ptr2cells(s);
+	mb_ptr_adv(s);
+    }
+
+    return len;
+}
+
+/*
+ * Return TRUE for characters that are not displayed in a status match.
+ * These are backslashes used for escaping.  Do show backslashes in help tags.
+ */
+    static int
+skip_status_match_char(xp, s)
+    expand_T	*xp;
+    char_u	*s;
+{
+    return ((rem_backslash(s) && xp->xp_context != EXPAND_HELP)
+#ifdef FEAT_MENU
+	    || ((xp->xp_context == EXPAND_MENUS
+		    || xp->xp_context == EXPAND_MENUNAMES)
+			  && (s[0] == '\t' || (s[0] == '\\' && s[1] != NUL)))
+#endif
+	   );
+}
+
+/*
+ * Show wildchar matches in the status line.
+ * Show at least the "match" item.
+ * We start at item 'first_match' in the list and show all matches that fit.
+ *
+ * If inversion is possible we use it. Else '=' characters are used.
+ */
+    void
+win_redr_status_matches(xp, num_matches, matches, match, showtail)
+    expand_T	*xp;
+    int		num_matches;
+    char_u	**matches;	/* list of matches */
+    int		match;
+    int		showtail;
+{
+#define L_MATCH(m) (showtail ? sm_gettail(matches[m]) : matches[m])
+    int		row;
+    char_u	*buf;
+    int		len;
+    int		clen;		/* lenght in screen cells */
+    int		fillchar;
+    int		attr;
+    int		i;
+    int		highlight = TRUE;
+    char_u	*selstart = NULL;
+    int		selstart_col = 0;
+    char_u	*selend = NULL;
+    static int	first_match = 0;
+    int		add_left = FALSE;
+    char_u	*s;
+#ifdef FEAT_MENU
+    int		emenu;
+#endif
+#if defined(FEAT_MBYTE) || defined(FEAT_MENU)
+    int		l;
+#endif
+
+    if (matches == NULL)	/* interrupted completion? */
+	return;
+
+#ifdef FEAT_MBYTE
+    if (has_mbyte)
+	buf = alloc((unsigned)Columns * MB_MAXBYTES + 1);
+    else
+#endif
+	buf = alloc((unsigned)Columns + 1);
+    if (buf == NULL)
+	return;
+
+    if (match == -1)	/* don't show match but original text */
+    {
+	match = 0;
+	highlight = FALSE;
+    }
+    /* count 1 for the ending ">" */
+    clen = status_match_len(xp, L_MATCH(match)) + 3;
+    if (match == 0)
+	first_match = 0;
+    else if (match < first_match)
+    {
+	/* jumping left, as far as we can go */
+	first_match = match;
+	add_left = TRUE;
+    }
+    else
+    {
+	/* check if match fits on the screen */
+	for (i = first_match; i < match; ++i)
+	    clen += status_match_len(xp, L_MATCH(i)) + 2;
+	if (first_match > 0)
+	    clen += 2;
+	/* jumping right, put match at the left */
+	if ((long)clen > Columns)
+	{
+	    first_match = match;
+	    /* if showing the last match, we can add some on the left */
+	    clen = 2;
+	    for (i = match; i < num_matches; ++i)
+	    {
+		clen += status_match_len(xp, L_MATCH(i)) + 2;
+		if ((long)clen >= Columns)
+		    break;
+	    }
+	    if (i == num_matches)
+		add_left = TRUE;
+	}
+    }
+    if (add_left)
+	while (first_match > 0)
+	{
+	    clen += status_match_len(xp, L_MATCH(first_match - 1)) + 2;
+	    if ((long)clen >= Columns)
+		break;
+	    --first_match;
+	}
+
+    fillchar = fillchar_status(&attr, TRUE);
+
+    if (first_match == 0)
+    {
+	*buf = NUL;
+	len = 0;
+    }
+    else
+    {
+	STRCPY(buf, "< ");
+	len = 2;
+    }
+    clen = len;
+
+    i = first_match;
+    while ((long)(clen + status_match_len(xp, L_MATCH(i)) + 2) < Columns)
+    {
+	if (i == match)
+	{
+	    selstart = buf + len;
+	    selstart_col = clen;
+	}
+
+	s = L_MATCH(i);
+	/* Check for menu separators - replace with '|' */
+#ifdef FEAT_MENU
+	emenu = (xp->xp_context == EXPAND_MENUS
+		|| xp->xp_context == EXPAND_MENUNAMES);
+	if (emenu && menu_is_separator(s))
+	{
+	    STRCPY(buf + len, transchar('|'));
+	    l = (int)STRLEN(buf + len);
+	    len += l;
+	    clen += l;
+	}
+	else
+#endif
+	    for ( ; *s != NUL; ++s)
+	{
+	    if (skip_status_match_char(xp, s))
+		++s;
+	    clen += ptr2cells(s);
+#ifdef FEAT_MBYTE
+	    if (has_mbyte && (l = (*mb_ptr2len)(s)) > 1)
+	    {
+		STRNCPY(buf + len, s, l);
+		s += l - 1;
+		len += l;
+	    }
+	    else
+#endif
+	    {
+		STRCPY(buf + len, transchar_byte(*s));
+		len += (int)STRLEN(buf + len);
+	    }
+	}
+	if (i == match)
+	    selend = buf + len;
+
+	*(buf + len++) = ' ';
+	*(buf + len++) = ' ';
+	clen += 2;
+	if (++i == num_matches)
+		break;
+    }
+
+    if (i != num_matches)
+    {
+	*(buf + len++) = '>';
+	++clen;
+    }
+
+    buf[len] = NUL;
+
+    row = cmdline_row - 1;
+    if (row >= 0)
+    {
+	if (wild_menu_showing == 0)
+	{
+	    if (msg_scrolled > 0)
+	    {
+		/* Put the wildmenu just above the command line.  If there is
+		 * no room, scroll the screen one line up. */
+		if (cmdline_row == Rows - 1)
+		{
+		    screen_del_lines(0, 0, 1, (int)Rows, TRUE, NULL);
+		    ++msg_scrolled;
+		}
+		else
+		{
+		    ++cmdline_row;
+		    ++row;
+		}
+		wild_menu_showing = WM_SCROLLED;
+	    }
+	    else
+	    {
+		/* Create status line if needed by setting 'laststatus' to 2.
+		 * Set 'winminheight' to zero to avoid that the window is
+		 * resized. */
+		if (lastwin->w_status_height == 0)
+		{
+		    save_p_ls = p_ls;
+		    save_p_wmh = p_wmh;
+		    p_ls = 2;
+		    p_wmh = 0;
+		    last_status(FALSE);
+		}
+		wild_menu_showing = WM_SHOWN;
+	    }
+	}
+
+	screen_puts(buf, row, 0, attr);
+	if (selstart != NULL && highlight)
+	{
+	    *selend = NUL;
+	    screen_puts(selstart, row, selstart_col, hl_attr(HLF_WM));
+	}
+
+	screen_fill(row, row + 1, clen, (int)Columns, fillchar, fillchar, attr);
+    }
+
+#ifdef FEAT_VERTSPLIT
+    win_redraw_last_status(topframe);
+#else
+    lastwin->w_redr_status = TRUE;
+#endif
+    vim_free(buf);
+}
+#endif
+
+#if defined(FEAT_WINDOWS) || defined(PROTO)
+/*
+ * Redraw the status line of window wp.
+ *
+ * If inversion is possible we use it. Else '=' characters are used.
+ */
+    void
+win_redr_status(wp)
+    win_T	*wp;
+{
+    int		row;
+    char_u	*p;
+    int		len;
+    int		fillchar;
+    int		attr;
+    int		this_ru_col;
+
+    wp->w_redr_status = FALSE;
+    if (wp->w_status_height == 0)
+    {
+	/* no status line, can only be last window */
+	redraw_cmdline = TRUE;
+    }
+    else if (!redrawing()
+#ifdef FEAT_INS_EXPAND
+	    /* don't update status line when popup menu is visible and may be
+	     * drawn over it */
+	    || pum_visible()
+#endif
+	    )
+    {
+	/* Don't redraw right now, do it later. */
+	wp->w_redr_status = TRUE;
+    }
+#ifdef FEAT_STL_OPT
+    else if (*p_stl != NUL || *wp->w_p_stl != NUL)
+    {
+	/* redraw custom status line */
+	redraw_custum_statusline(wp);
+    }
+#endif
+    else
+    {
+	fillchar = fillchar_status(&attr, wp == curwin);
+
+	get_trans_bufname(wp->w_buffer);
+	p = NameBuff;
+	len = (int)STRLEN(p);
+
+	if (wp->w_buffer->b_help
+#ifdef FEAT_QUICKFIX
+		|| wp->w_p_pvw
+#endif
+		|| bufIsChanged(wp->w_buffer)
+		|| wp->w_buffer->b_p_ro)
+	    *(p + len++) = ' ';
+	if (wp->w_buffer->b_help)
+	{
+	    STRCPY(p + len, _("[Help]"));
+	    len += (int)STRLEN(p + len);
+	}
+#ifdef FEAT_QUICKFIX
+	if (wp->w_p_pvw)
+	{
+	    STRCPY(p + len, _("[Preview]"));
+	    len += (int)STRLEN(p + len);
+	}
+#endif
+	if (bufIsChanged(wp->w_buffer))
+	{
+	    STRCPY(p + len, "[+]");
+	    len += 3;
+	}
+	if (wp->w_buffer->b_p_ro)
+	{
+	    STRCPY(p + len, "[RO]");
+	    len += 4;
+	}
+
+#ifndef FEAT_VERTSPLIT
+	this_ru_col = ru_col;
+	if (this_ru_col < (Columns + 1) / 2)
+	    this_ru_col = (Columns + 1) / 2;
+#else
+	this_ru_col = ru_col - (Columns - W_WIDTH(wp));
+	if (this_ru_col < (W_WIDTH(wp) + 1) / 2)
+	    this_ru_col = (W_WIDTH(wp) + 1) / 2;
+	if (this_ru_col <= 1)
+	{
+	    p = (char_u *)"<";		/* No room for file name! */
+	    len = 1;
+	}
+	else
+#endif
+#ifdef FEAT_MBYTE
+	    if (has_mbyte)
+	    {
+		int	clen = 0, i;
+
+		/* Count total number of display cells. */
+		for (i = 0; p[i] != NUL; i += (*mb_ptr2len)(p + i))
+		    clen += (*mb_ptr2cells)(p + i);
+		/* Find first character that will fit.
+		 * Going from start to end is much faster for DBCS. */
+		for (i = 0; p[i] != NUL && clen >= this_ru_col - 1;
+					      i += (*mb_ptr2len)(p + i))
+		    clen -= (*mb_ptr2cells)(p + i);
+		len = clen;
+		if (i > 0)
+		{
+		    p = p + i - 1;
+		    *p = '<';
+		    ++len;
+		}
+
+	    }
+	    else
+#endif
+	    if (len > this_ru_col - 1)
+	    {
+		p += len - (this_ru_col - 1);
+		*p = '<';
+		len = this_ru_col - 1;
+	    }
+
+	row = W_WINROW(wp) + wp->w_height;
+	screen_puts(p, row, W_WINCOL(wp), attr);
+	screen_fill(row, row + 1, len + W_WINCOL(wp),
+			this_ru_col + W_WINCOL(wp), fillchar, fillchar, attr);
+
+	if (get_keymap_str(wp, NameBuff, MAXPATHL)
+		&& (int)(this_ru_col - len) > (int)(STRLEN(NameBuff) + 1))
+	    screen_puts(NameBuff, row, (int)(this_ru_col - STRLEN(NameBuff)
+						   - 1 + W_WINCOL(wp)), attr);
+
+#ifdef FEAT_CMDL_INFO
+	win_redr_ruler(wp, TRUE);
+#endif
+    }
+
+#ifdef FEAT_VERTSPLIT
+    /*
+     * May need to draw the character below the vertical separator.
+     */
+    if (wp->w_vsep_width != 0 && wp->w_status_height != 0 && redrawing())
+    {
+	if (stl_connected(wp))
+	    fillchar = fillchar_status(&attr, wp == curwin);
+	else
+	    fillchar = fillchar_vsep(&attr);
+	screen_putchar(fillchar, W_WINROW(wp) + wp->w_height, W_ENDCOL(wp),
+									attr);
+    }
+#endif
+}
+
+#ifdef FEAT_STL_OPT
+/*
+ * Redraw the status line according to 'statusline' and take care of any
+ * errors encountered.
+ */
+    static void
+redraw_custum_statusline(wp)
+    win_T	    *wp;
+{
+    int	save_called_emsg = called_emsg;
+
+    called_emsg = FALSE;
+    win_redr_custom(wp, FALSE);
+    if (called_emsg)
+	set_string_option_direct((char_u *)"statusline", -1,
+		(char_u *)"", OPT_FREE | (*wp->w_p_stl != NUL
+					? OPT_LOCAL : OPT_GLOBAL), SID_ERROR);
+    called_emsg |= save_called_emsg;
+}
+#endif
+
+# ifdef FEAT_VERTSPLIT
+/*
+ * Return TRUE if the status line of window "wp" is connected to the status
+ * line of the window right of it.  If not, then it's a vertical separator.
+ * Only call if (wp->w_vsep_width != 0).
+ */
+    int
+stl_connected(wp)
+    win_T	*wp;
+{
+    frame_T	*fr;
+
+    fr = wp->w_frame;
+    while (fr->fr_parent != NULL)
+    {
+	if (fr->fr_parent->fr_layout == FR_COL)
+	{
+	    if (fr->fr_next != NULL)
+		break;
+	}
+	else
+	{
+	    if (fr->fr_next != NULL)
+		return TRUE;
+	}
+	fr = fr->fr_parent;
+    }
+    return FALSE;
+}
+# endif
+
+#endif /* FEAT_WINDOWS */
+
+#if defined(FEAT_WINDOWS) || defined(FEAT_STL_OPT) || defined(PROTO)
+/*
+ * Get the value to show for the language mappings, active 'keymap'.
+ */
+    int
+get_keymap_str(wp, buf, len)
+    win_T	*wp;
+    char_u	*buf;	    /* buffer for the result */
+    int		len;	    /* length of buffer */
+{
+    char_u	*p;
+
+    if (wp->w_buffer->b_p_iminsert != B_IMODE_LMAP)
+	return FALSE;
+
+    {
+#ifdef FEAT_EVAL
+	buf_T	*old_curbuf = curbuf;
+	win_T	*old_curwin = curwin;
+	char_u	*s;
+
+	curbuf = wp->w_buffer;
+	curwin = wp;
+	STRCPY(buf, "b:keymap_name");	/* must be writable */
+	++emsg_skip;
+	s = p = eval_to_string(buf, NULL, FALSE);
+	--emsg_skip;
+	curbuf = old_curbuf;
+	curwin = old_curwin;
+	if (p == NULL || *p == NUL)
+#endif
+	{
+#ifdef FEAT_KEYMAP
+	    if (wp->w_buffer->b_kmap_state & KEYMAP_LOADED)
+		p = wp->w_buffer->b_p_keymap;
+	    else
+#endif
+		p = (char_u *)"lang";
+	}
+	if ((int)(STRLEN(p) + 3) < len)
+	    sprintf((char *)buf, "<%s>", p);
+	else
+	    buf[0] = NUL;
+#ifdef FEAT_EVAL
+	vim_free(s);
+#endif
+    }
+    return buf[0] != NUL;
+}
+#endif
+
+#if defined(FEAT_STL_OPT) || defined(PROTO)
+/*
+ * Redraw the status line or ruler of window "wp".
+ * When "wp" is NULL redraw the tab pages line from 'tabline'.
+ */
+    static void
+win_redr_custom(wp, draw_ruler)
+    win_T	*wp;
+    int		draw_ruler;	/* TRUE or FALSE */
+{
+    int		attr;
+    int		curattr;
+    int		row;
+    int		col = 0;
+    int		maxwidth;
+    int		width;
+    int		n;
+    int		len;
+    int		fillchar;
+    char_u	buf[MAXPATHL];
+    char_u	*p;
+    struct	stl_hlrec hltab[STL_MAX_ITEM];
+    struct	stl_hlrec tabtab[STL_MAX_ITEM];
+    int		use_sandbox = FALSE;
+
+    /* setup environment for the task at hand */
+    if (wp == NULL)
+    {
+	/* Use 'tabline'.  Always at the first line of the screen. */
+	p = p_tal;
+	row = 0;
+	fillchar = ' ';
+	attr = hl_attr(HLF_TPF);
+	maxwidth = Columns;
+# ifdef FEAT_EVAL
+	use_sandbox = was_set_insecurely((char_u *)"tabline", 0);
+# endif
+    }
+    else
+    {
+	row = W_WINROW(wp) + wp->w_height;
+	fillchar = fillchar_status(&attr, wp == curwin);
+	maxwidth = W_WIDTH(wp);
+
+	if (draw_ruler)
+	{
+	    p = p_ruf;
+	    /* advance past any leading group spec - implicit in ru_col */
+	    if (*p == '%')
+	    {
+		if (*++p == '-')
+		    p++;
+		if (atoi((char *) p))
+		    while (VIM_ISDIGIT(*p))
+			p++;
+		if (*p++ != '(')
+		    p = p_ruf;
+	    }
+#ifdef FEAT_VERTSPLIT
+	    col = ru_col - (Columns - W_WIDTH(wp));
+	    if (col < (W_WIDTH(wp) + 1) / 2)
+		col = (W_WIDTH(wp) + 1) / 2;
+#else
+	    col = ru_col;
+	    if (col > (Columns + 1) / 2)
+		col = (Columns + 1) / 2;
+#endif
+	    maxwidth = W_WIDTH(wp) - col;
+#ifdef FEAT_WINDOWS
+	    if (!wp->w_status_height)
+#endif
+	    {
+		row = Rows - 1;
+		--maxwidth;	/* writing in last column may cause scrolling */
+		fillchar = ' ';
+		attr = 0;
+	    }
+
+# ifdef FEAT_EVAL
+	    use_sandbox = was_set_insecurely((char_u *)"rulerformat", 0);
+# endif
+	}
+	else
+	{
+	    if (*wp->w_p_stl != NUL)
+		p = wp->w_p_stl;
+	    else
+		p = p_stl;
+# ifdef FEAT_EVAL
+	    use_sandbox = was_set_insecurely((char_u *)"statusline",
+					 *wp->w_p_stl == NUL ? 0 : OPT_LOCAL);
+# endif
+	}
+
+#ifdef FEAT_VERTSPLIT
+	col += W_WINCOL(wp);
+#endif
+    }
+
+    if (maxwidth <= 0)
+	return;
+
+    width = build_stl_str_hl(wp == NULL ? curwin : wp,
+				buf, sizeof(buf),
+				p, use_sandbox,
+				fillchar, maxwidth, hltab, tabtab);
+    len = (int)STRLEN(buf);
+
+    while (width < maxwidth && len < sizeof(buf) - 1)
+    {
+#ifdef FEAT_MBYTE
+	len += (*mb_char2bytes)(fillchar, buf + len);
+#else
+	buf[len++] = fillchar;
+#endif
+	++width;
+    }
+    buf[len] = NUL;
+
+    /*
+     * Draw each snippet with the specified highlighting.
+     */
+    curattr = attr;
+    p = buf;
+    for (n = 0; hltab[n].start != NULL; n++)
+    {
+	len = (int)(hltab[n].start - p);
+	screen_puts_len(p, len, row, col, curattr);
+	col += vim_strnsize(p, len);
+	p = hltab[n].start;
+
+	if (hltab[n].userhl == 0)
+	    curattr = attr;
+	else if (hltab[n].userhl < 0)
+	    curattr = syn_id2attr(-hltab[n].userhl);
+#ifdef FEAT_WINDOWS
+	else if (wp != NULL && wp != curwin && wp->w_status_height != 0)
+	    curattr = highlight_stlnc[hltab[n].userhl - 1];
+#endif
+	else
+	    curattr = highlight_user[hltab[n].userhl - 1];
+    }
+    screen_puts(p, row, col, curattr);
+
+    if (wp == NULL)
+    {
+	/* Fill the TabPageIdxs[] array for clicking in the tab pagesline. */
+	col = 0;
+	len = 0;
+	p = buf;
+	fillchar = 0;
+	for (n = 0; tabtab[n].start != NULL; n++)
+	{
+	    len += vim_strnsize(p, (int)(tabtab[n].start - p));
+	    while (col < len)
+		TabPageIdxs[col++] = fillchar;
+	    p = tabtab[n].start;
+	    fillchar = tabtab[n].userhl;
+	}
+	while (col < Columns)
+	    TabPageIdxs[col++] = fillchar;
+    }
+}
+
+#endif /* FEAT_STL_OPT */
+
+/*
+ * Output a single character directly to the screen and update ScreenLines.
+ */
+    void
+screen_putchar(c, row, col, attr)
+    int	    c;
+    int	    row, col;
+    int	    attr;
+{
+#ifdef FEAT_MBYTE
+    char_u	buf[MB_MAXBYTES + 1];
+
+    buf[(*mb_char2bytes)(c, buf)] = NUL;
+#else
+    char_u	buf[2];
+
+    buf[0] = c;
+    buf[1] = NUL;
+#endif
+    screen_puts(buf, row, col, attr);
+}
+
+/*
+ * Get a single character directly from ScreenLines into "bytes[]".
+ * Also return its attribute in *attrp;
+ */
+    void
+screen_getbytes(row, col, bytes, attrp)
+    int	    row, col;
+    char_u  *bytes;
+    int	    *attrp;
+{
+    unsigned off;
+
+    /* safety check */
+    if (ScreenLines != NULL && row < screen_Rows && col < screen_Columns)
+    {
+	off = LineOffset[row] + col;
+	*attrp = ScreenAttrs[off];
+	bytes[0] = ScreenLines[off];
+	bytes[1] = NUL;
+
+#ifdef FEAT_MBYTE
+	if (enc_utf8 && ScreenLinesUC[off] != 0)
+	    bytes[utfc_char2bytes(off, bytes)] = NUL;
+	else if (enc_dbcs == DBCS_JPNU && ScreenLines[off] == 0x8e)
+	{
+	    bytes[0] = ScreenLines[off];
+	    bytes[1] = ScreenLines2[off];
+	    bytes[2] = NUL;
+	}
+	else if (enc_dbcs && MB_BYTE2LEN(bytes[0]) > 1)
+	{
+	    bytes[1] = ScreenLines[off + 1];
+	    bytes[2] = NUL;
+	}
+#endif
+    }
+}
+
+#ifdef FEAT_MBYTE
+static int screen_comp_differs __ARGS((int, int*));
+
+/*
+ * Return TRUE if composing characters for screen posn "off" differs from
+ * composing characters in "u8cc".
+ */
+    static int
+screen_comp_differs(off, u8cc)
+    int	    off;
+    int	    *u8cc;
+{
+    int	    i;
+
+    for (i = 0; i < Screen_mco; ++i)
+    {
+	if (ScreenLinesC[i][off] != (u8char_T)u8cc[i])
+	    return TRUE;
+	if (u8cc[i] == 0)
+	    break;
+    }
+    return FALSE;
+}
+#endif
+
+/*
+ * Put string '*text' on the screen at position 'row' and 'col', with
+ * attributes 'attr', and update ScreenLines[] and ScreenAttrs[].
+ * Note: only outputs within one row, message is truncated at screen boundary!
+ * Note: if ScreenLines[], row and/or col is invalid, nothing is done.
+ */
+    void
+screen_puts(text, row, col, attr)
+    char_u	*text;
+    int		row;
+    int		col;
+    int		attr;
+{
+    screen_puts_len(text, -1, row, col, attr);
+}
+
+/*
+ * Like screen_puts(), but output "text[len]".  When "len" is -1 output up to
+ * a NUL.
+ */
+    void
+screen_puts_len(text, len, row, col, attr)
+    char_u	*text;
+    int		len;
+    int		row;
+    int		col;
+    int		attr;
+{
+    unsigned	off;
+    char_u	*ptr = text;
+    int		c;
+#ifdef FEAT_MBYTE
+    int		mbyte_blen = 1;
+    int		mbyte_cells = 1;
+    int		u8c = 0;
+    int		u8cc[MAX_MCO];
+    int		clear_next_cell = FALSE;
+# ifdef FEAT_ARABIC
+    int		prev_c = 0;		/* previous Arabic character */
+    int		pc, nc, nc1;
+    int		pcc[MAX_MCO];
+# endif
+#endif
+
+    if (ScreenLines == NULL || row >= screen_Rows)	/* safety check */
+	return;
+
+    off = LineOffset[row] + col;
+    while (*ptr != NUL && col < screen_Columns
+				      && (len < 0 || (int)(ptr - text) < len))
+    {
+	c = *ptr;
+#ifdef FEAT_MBYTE
+	/* check if this is the first byte of a multibyte */
+	if (has_mbyte)
+	{
+	    if (enc_utf8 && len > 0)
+		mbyte_blen = utfc_ptr2len_len(ptr, (int)((text + len) - ptr));
+	    else
+		mbyte_blen = (*mb_ptr2len)(ptr);
+	    if (enc_dbcs == DBCS_JPNU && c == 0x8e)
+		mbyte_cells = 1;
+	    else if (enc_dbcs != 0)
+		mbyte_cells = mbyte_blen;
+	    else	/* enc_utf8 */
+	    {
+		if (len >= 0)
+		    u8c = utfc_ptr2char_len(ptr, u8cc,
+						   (int)((text + len) - ptr));
+		else
+		    u8c = utfc_ptr2char(ptr, u8cc);
+		mbyte_cells = utf_char2cells(u8c);
+		/* Non-BMP character: display as ? or fullwidth ?. */
+		if (u8c >= 0x10000)
+		{
+		    u8c = (mbyte_cells == 2) ? 0xff1f : (int)'?';
+		    if (attr == 0)
+			attr = hl_attr(HLF_8);
+		}
+# ifdef FEAT_ARABIC
+		if (p_arshape && !p_tbidi && ARABIC_CHAR(u8c))
+		{
+		    /* Do Arabic shaping. */
+		    if (len >= 0 && (int)(ptr - text) + mbyte_blen >= len)
+		    {
+			/* Past end of string to be displayed. */
+			nc = NUL;
+			nc1 = NUL;
+		    }
+		    else
+		    {
+			nc = utfc_ptr2char(ptr + mbyte_blen, pcc);
+			nc1 = pcc[0];
+		    }
+		    pc = prev_c;
+		    prev_c = u8c;
+		    u8c = arabic_shape(u8c, &c, &u8cc[0], nc, nc1, pc);
+		}
+		else
+		    prev_c = u8c;
+# endif
+	    }
+	}
+#endif
+
+	if (ScreenLines[off] != c
+#ifdef FEAT_MBYTE
+		|| (mbyte_cells == 2
+		    && ScreenLines[off + 1] != (enc_dbcs ? ptr[1] : 0))
+		|| (enc_dbcs == DBCS_JPNU
+		    && c == 0x8e
+		    && ScreenLines2[off] != ptr[1])
+		|| (enc_utf8
+		    && (ScreenLinesUC[off] != (u8char_T)u8c
+			|| screen_comp_differs(off, u8cc)))
+#endif
+		|| ScreenAttrs[off] != attr
+		|| exmode_active
+		)
+	{
+#if defined(FEAT_GUI) || defined(UNIX)
+	    /* The bold trick makes a single row of pixels appear in the next
+	     * character.  When a bold character is removed, the next
+	     * character should be redrawn too.  This happens for our own GUI
+	     * and for some xterms.
+	     * Force the redraw by setting the attribute to a different value
+	     * than "attr", the contents of ScreenLines[] may be needed by
+	     * mb_off2cells() further on.
+	     * Don't do this for the last drawn character, because the next
+	     * character may not be redrawn. */
+	    if (
+# ifdef FEAT_GUI
+		    gui.in_use
+# endif
+# if defined(FEAT_GUI) && defined(UNIX)
+		    ||
+# endif
+# ifdef UNIX
+		    term_is_xterm
+# endif
+	       )
+	    {
+		int		n;
+
+		n = ScreenAttrs[off];
+# ifdef FEAT_MBYTE
+		if (col + mbyte_cells < screen_Columns
+			&& (n > HL_ALL || (n & HL_BOLD))
+			&& (len < 0 ? ptr[mbyte_blen] != NUL
+					     : ptr + mbyte_blen < text + len))
+		    ScreenAttrs[off + mbyte_cells] = attr + 1;
+# else
+		if (col + 1 < screen_Columns
+			&& (n > HL_ALL || (n & HL_BOLD))
+			&& (len < 0 ? ptr[1] != NUL : ptr + 1 < text + len))
+		    ScreenLines[off + 1] = 0;
+# endif
+	    }
+#endif
+#ifdef FEAT_MBYTE
+	    /* When at the end of the text and overwriting a two-cell
+	     * character with a one-cell character, need to clear the next
+	     * cell.  Also when overwriting the left halve of a two-cell char
+	     * with the right halve of a two-cell char.  Do this only once
+	     * (mb_off2cells() may return 2 on the right halve). */
+	    if (clear_next_cell)
+		clear_next_cell = FALSE;
+	    else if (has_mbyte
+		    && (len < 0 ? ptr[mbyte_blen] == NUL
+					     : ptr + mbyte_blen >= text + len)
+		    && ((mbyte_cells == 1 && (*mb_off2cells)(off) > 1)
+			|| (mbyte_cells == 2
+			    && (*mb_off2cells)(off) == 1
+			    && (*mb_off2cells)(off + 1) > 1)))
+		clear_next_cell = TRUE;
+
+	    /* Make sure we never leave a second byte of a double-byte behind,
+	     * it confuses mb_off2cells(). */
+	    if (enc_dbcs
+		    && ((mbyte_cells == 1 && (*mb_off2cells)(off) > 1)
+			|| (mbyte_cells == 2
+			    && (*mb_off2cells)(off) == 1
+			    && (*mb_off2cells)(off + 1) > 1)))
+		ScreenLines[off + mbyte_blen] = 0;
+#endif
+	    ScreenLines[off] = c;
+	    ScreenAttrs[off] = attr;
+#ifdef FEAT_MBYTE
+	    if (enc_utf8)
+	    {
+		if (c < 0x80 && u8cc[0] == 0)
+		    ScreenLinesUC[off] = 0;
+		else
+		{
+		    int	    i;
+
+		    ScreenLinesUC[off] = u8c;
+		    for (i = 0; i < Screen_mco; ++i)
+		    {
+			ScreenLinesC[i][off] = u8cc[i];
+			if (u8cc[i] == 0)
+			    break;
+		    }
+		}
+		if (mbyte_cells == 2)
+		{
+		    ScreenLines[off + 1] = 0;
+		    ScreenAttrs[off + 1] = attr;
+		}
+		screen_char(off, row, col);
+	    }
+	    else if (mbyte_cells == 2)
+	    {
+		ScreenLines[off + 1] = ptr[1];
+		ScreenAttrs[off + 1] = attr;
+		screen_char_2(off, row, col);
+	    }
+	    else if (enc_dbcs == DBCS_JPNU && c == 0x8e)
+	    {
+		ScreenLines2[off] = ptr[1];
+		screen_char(off, row, col);
+	    }
+	    else
+#endif
+		screen_char(off, row, col);
+	}
+#ifdef FEAT_MBYTE
+	if (has_mbyte)
+	{
+	    off += mbyte_cells;
+	    col += mbyte_cells;
+	    ptr += mbyte_blen;
+	    if (clear_next_cell)
+		ptr = (char_u *)" ";
+	}
+	else
+#endif
+	{
+	    ++off;
+	    ++col;
+	    ++ptr;
+	}
+    }
+}
+
+#ifdef FEAT_SEARCH_EXTRA
+/*
+ * Prepare for 'searchhl' highlighting.
+ */
+    static void
+start_search_hl()
+{
+    if (p_hls && !no_hlsearch)
+    {
+	last_pat_prog(&search_hl.rm);
+	search_hl.attr = hl_attr(HLF_L);
+    }
+}
+
+/*
+ * Clean up for 'searchhl' highlighting.
+ */
+    static void
+end_search_hl()
+{
+    if (search_hl.rm.regprog != NULL)
+    {
+	vim_free(search_hl.rm.regprog);
+	search_hl.rm.regprog = NULL;
+    }
+}
+
+/*
+ * Advance to the match in window "wp" line "lnum" or past it.
+ */
+    static void
+prepare_search_hl(wp, lnum)
+    win_T	*wp;
+    linenr_T	lnum;
+{
+    match_T	*shl;		/* points to search_hl or match_hl */
+    int		n;
+    int		i;
+
+    /*
+     * When using a multi-line pattern, start searching at the top
+     * of the window or just after a closed fold.
+     * Do this both for search_hl and match_hl[3].
+     */
+    for (i = 3; i >= 0; --i)
+    {
+	shl = (i == 3) ? &search_hl : &match_hl[i];
+	if (shl->rm.regprog != NULL
+		&& shl->lnum == 0
+		&& re_multiline(shl->rm.regprog))
+	{
+	    if (shl->first_lnum == 0)
+	    {
+# ifdef FEAT_FOLDING
+		for (shl->first_lnum = lnum;
+			   shl->first_lnum > wp->w_topline; --shl->first_lnum)
+		    if (hasFoldingWin(wp, shl->first_lnum - 1,
+						      NULL, NULL, TRUE, NULL))
+			break;
+# else
+		shl->first_lnum = wp->w_topline;
+# endif
+	    }
+	    n = 0;
+	    while (shl->first_lnum < lnum && shl->rm.regprog != NULL)
+	    {
+		next_search_hl(wp, shl, shl->first_lnum, (colnr_T)n);
+		if (shl->lnum != 0)
+		{
+		    shl->first_lnum = shl->lnum
+				    + shl->rm.endpos[0].lnum
+				    - shl->rm.startpos[0].lnum;
+		    n = shl->rm.endpos[0].col;
+		}
+		else
+		{
+		    ++shl->first_lnum;
+		    n = 0;
+		}
+	    }
+	}
+    }
+}
+
+/*
+ * Search for a next 'searchl' or ":match" match.
+ * Uses shl->buf.
+ * Sets shl->lnum and shl->rm contents.
+ * Note: Assumes a previous match is always before "lnum", unless
+ * shl->lnum is zero.
+ * Careful: Any pointers for buffer lines will become invalid.
+ */
+    static void
+next_search_hl(win, shl, lnum, mincol)
+    win_T	*win;
+    match_T	*shl;		/* points to search_hl or match_hl */
+    linenr_T	lnum;
+    colnr_T	mincol;		/* minimal column for a match */
+{
+    linenr_T	l;
+    colnr_T	matchcol;
+    long	nmatched;
+
+    if (shl->lnum != 0)
+    {
+	/* Check for three situations:
+	 * 1. If the "lnum" is below a previous match, start a new search.
+	 * 2. If the previous match includes "mincol", use it.
+	 * 3. Continue after the previous match.
+	 */
+	l = shl->lnum + shl->rm.endpos[0].lnum - shl->rm.startpos[0].lnum;
+	if (lnum > l)
+	    shl->lnum = 0;
+	else if (lnum < l || shl->rm.endpos[0].col > mincol)
+	    return;
+    }
+
+    /*
+     * Repeat searching for a match until one is found that includes "mincol"
+     * or none is found in this line.
+     */
+    called_emsg = FALSE;
+    for (;;)
+    {
+	/* Three situations:
+	 * 1. No useful previous match: search from start of line.
+	 * 2. Not Vi compatible or empty match: continue at next character.
+	 *    Break the loop if this is beyond the end of the line.
+	 * 3. Vi compatible searching: continue at end of previous match.
+	 */
+	if (shl->lnum == 0)
+	    matchcol = 0;
+	else if (vim_strchr(p_cpo, CPO_SEARCH) == NULL
+		|| (shl->rm.endpos[0].lnum == 0
+		    && shl->rm.endpos[0].col <= shl->rm.startpos[0].col))
+	{
+	    char_u	*ml;
+
+	    matchcol = shl->rm.startpos[0].col;
+	    ml = ml_get_buf(shl->buf, lnum, FALSE) + matchcol;
+	    if (*ml == NUL)
+	    {
+		++matchcol;
+		shl->lnum = 0;
+		break;
+	    }
+#ifdef FEAT_MBYTE
+	    if (has_mbyte)
+		matchcol += mb_ptr2len(ml);
+	    else
+#endif
+		++matchcol;
+	}
+	else
+	    matchcol = shl->rm.endpos[0].col;
+
+	shl->lnum = lnum;
+	nmatched = vim_regexec_multi(&shl->rm, win, shl->buf, lnum, matchcol);
+	if (called_emsg)
+	{
+	    /* Error while handling regexp: stop using this regexp. */
+	    if (shl == &search_hl)
+	    {
+		/* don't free the regprog in match_hl[], it's a copy */
+		vim_free(shl->rm.regprog);
+		no_hlsearch = TRUE;
+	    }
+	    shl->rm.regprog = NULL;
+	    shl->lnum = 0;
+	    got_int = FALSE;  /* avoid the "Type :quit to exit Vim" message */
+	    break;
+	}
+	if (nmatched == 0)
+	{
+	    shl->lnum = 0;		/* no match found */
+	    break;
+	}
+	if (shl->rm.startpos[0].lnum > 0
+		|| shl->rm.startpos[0].col >= mincol
+		|| nmatched > 1
+		|| shl->rm.endpos[0].col > mincol)
+	{
+	    shl->lnum += shl->rm.startpos[0].lnum;
+	    break;			/* useful match found */
+	}
+    }
+}
+#endif
+
+      static void
+screen_start_highlight(attr)
+      int	attr;
+{
+    attrentry_T *aep = NULL;
+
+    screen_attr = attr;
+    if (full_screen
+#ifdef WIN3264
+		    && termcap_active
+#endif
+				       )
+    {
+#ifdef FEAT_GUI
+	if (gui.in_use)
+	{
+	    char	buf[20];
+
+	    /* The GUI handles this internally. */
+	    sprintf(buf, IF_EB("\033|%dh", ESC_STR "|%dh"), attr);
+	    OUT_STR(buf);
+	}
+	else
+#endif
+	{
+	    if (attr > HL_ALL)				/* special HL attr. */
+	    {
+		if (t_colors > 1)
+		    aep = syn_cterm_attr2entry(attr);
+		else
+		    aep = syn_term_attr2entry(attr);
+		if (aep == NULL)	    /* did ":syntax clear" */
+		    attr = 0;
+		else
+		    attr = aep->ae_attr;
+	    }
+	    if ((attr & HL_BOLD) && T_MD != NULL)	/* bold */
+		out_str(T_MD);
+	    else if (aep != NULL && t_colors > 1 && aep->ae_u.cterm.fg_color
+						      && cterm_normal_fg_bold)
+		/* If the Normal FG color has BOLD attribute and the new HL
+		 * has a FG color defined, clear BOLD. */
+		out_str(T_ME);
+	    if ((attr & HL_STANDOUT) && T_SO != NULL)	/* standout */
+		out_str(T_SO);
+	    if ((attr & (HL_UNDERLINE | HL_UNDERCURL)) && T_US != NULL)
+						   /* underline or undercurl */
+		out_str(T_US);
+	    if ((attr & HL_ITALIC) && T_CZH != NULL)	/* italic */
+		out_str(T_CZH);
+	    if ((attr & HL_INVERSE) && T_MR != NULL)	/* inverse (reverse) */
+		out_str(T_MR);
+
+	    /*
+	     * Output the color or start string after bold etc., in case the
+	     * bold etc. override the color setting.
+	     */
+	    if (aep != NULL)
+	    {
+		if (t_colors > 1)
+		{
+		    if (aep->ae_u.cterm.fg_color)
+			term_fg_color(aep->ae_u.cterm.fg_color - 1);
+		    if (aep->ae_u.cterm.bg_color)
+			term_bg_color(aep->ae_u.cterm.bg_color - 1);
+		}
+		else
+		{
+		    if (aep->ae_u.term.start != NULL)
+			out_str(aep->ae_u.term.start);
+		}
+	    }
+	}
+    }
+}
+
+      void
+screen_stop_highlight()
+{
+    int	    do_ME = FALSE;	    /* output T_ME code */
+
+    if (screen_attr != 0
+#ifdef WIN3264
+			&& termcap_active
+#endif
+					   )
+    {
+#ifdef FEAT_GUI
+	if (gui.in_use)
+	{
+	    char	buf[20];
+
+	    /* use internal GUI code */
+	    sprintf(buf, IF_EB("\033|%dH", ESC_STR "|%dH"), screen_attr);
+	    OUT_STR(buf);
+	}
+	else
+#endif
+	{
+	    if (screen_attr > HL_ALL)			/* special HL attr. */
+	    {
+		attrentry_T *aep;
+
+		if (t_colors > 1)
+		{
+		    /*
+		     * Assume that t_me restores the original colors!
+		     */
+		    aep = syn_cterm_attr2entry(screen_attr);
+		    if (aep != NULL && (aep->ae_u.cterm.fg_color
+						 || aep->ae_u.cterm.bg_color))
+			do_ME = TRUE;
+		}
+		else
+		{
+		    aep = syn_term_attr2entry(screen_attr);
+		    if (aep != NULL && aep->ae_u.term.stop != NULL)
+		    {
+			if (STRCMP(aep->ae_u.term.stop, T_ME) == 0)
+			    do_ME = TRUE;
+			else
+			    out_str(aep->ae_u.term.stop);
+		    }
+		}
+		if (aep == NULL)	    /* did ":syntax clear" */
+		    screen_attr = 0;
+		else
+		    screen_attr = aep->ae_attr;
+	    }
+
+	    /*
+	     * Often all ending-codes are equal to T_ME.  Avoid outputting the
+	     * same sequence several times.
+	     */
+	    if (screen_attr & HL_STANDOUT)
+	    {
+		if (STRCMP(T_SE, T_ME) == 0)
+		    do_ME = TRUE;
+		else
+		    out_str(T_SE);
+	    }
+	    if (screen_attr & (HL_UNDERLINE | HL_UNDERCURL))
+	    {
+		if (STRCMP(T_UE, T_ME) == 0)
+		    do_ME = TRUE;
+		else
+		    out_str(T_UE);
+	    }
+	    if (screen_attr & HL_ITALIC)
+	    {
+		if (STRCMP(T_CZR, T_ME) == 0)
+		    do_ME = TRUE;
+		else
+		    out_str(T_CZR);
+	    }
+	    if (do_ME || (screen_attr & (HL_BOLD | HL_INVERSE)))
+		out_str(T_ME);
+
+	    if (t_colors > 1)
+	    {
+		/* set Normal cterm colors */
+		if (cterm_normal_fg_color != 0)
+		    term_fg_color(cterm_normal_fg_color - 1);
+		if (cterm_normal_bg_color != 0)
+		    term_bg_color(cterm_normal_bg_color - 1);
+		if (cterm_normal_fg_bold)
+		    out_str(T_MD);
+	    }
+	}
+    }
+    screen_attr = 0;
+}
+
+/*
+ * Reset the colors for a cterm.  Used when leaving Vim.
+ * The machine specific code may override this again.
+ */
+    void
+reset_cterm_colors()
+{
+    if (t_colors > 1)
+    {
+	/* set Normal cterm colors */
+	if (cterm_normal_fg_color > 0 || cterm_normal_bg_color > 0)
+	{
+	    out_str(T_OP);
+	    screen_attr = -1;
+	}
+	if (cterm_normal_fg_bold)
+	{
+	    out_str(T_ME);
+	    screen_attr = -1;
+	}
+    }
+}
+
+/*
+ * Put character ScreenLines["off"] on the screen at position "row" and "col",
+ * using the attributes from ScreenAttrs["off"].
+ */
+    static void
+screen_char(off, row, col)
+    unsigned	off;
+    int		row;
+    int		col;
+{
+    int		attr;
+
+    /* Check for illegal values, just in case (could happen just after
+     * resizing). */
+    if (row >= screen_Rows || col >= screen_Columns)
+	return;
+
+    /* Outputting the last character on the screen may scrollup the screen.
+     * Don't to it!  Mark the character invalid (update it when scrolled up) */
+    if (row == screen_Rows - 1 && col == screen_Columns - 1
+#ifdef FEAT_RIGHTLEFT
+	    /* account for first command-line character in rightleft mode */
+	    && !cmdmsg_rl
+#endif
+       )
+    {
+	ScreenAttrs[off] = (sattr_T)-1;
+	return;
+    }
+
+    /*
+     * Stop highlighting first, so it's easier to move the cursor.
+     */
+#if defined(FEAT_CLIPBOARD) || defined(FEAT_VERTSPLIT)
+    if (screen_char_attr != 0)
+	attr = screen_char_attr;
+    else
+#endif
+	attr = ScreenAttrs[off];
+    if (screen_attr != attr)
+	screen_stop_highlight();
+
+    windgoto(row, col);
+
+    if (screen_attr != attr)
+	screen_start_highlight(attr);
+
+#ifdef FEAT_MBYTE
+    if (enc_utf8 && ScreenLinesUC[off] != 0)
+    {
+	char_u	    buf[MB_MAXBYTES + 1];
+
+	/* Convert UTF-8 character to bytes and write it. */
+
+	buf[utfc_char2bytes(off, buf)] = NUL;
+
+	out_str(buf);
+	if (utf_char2cells(ScreenLinesUC[off]) > 1)
+	    ++screen_cur_col;
+    }
+    else
+#endif
+    {
+#ifdef FEAT_MBYTE
+	out_flush_check();
+#endif
+	out_char(ScreenLines[off]);
+#ifdef FEAT_MBYTE
+	/* double-byte character in single-width cell */
+	if (enc_dbcs == DBCS_JPNU && ScreenLines[off] == 0x8e)
+	    out_char(ScreenLines2[off]);
+#endif
+    }
+
+    screen_cur_col++;
+}
+
+#ifdef FEAT_MBYTE
+
+/*
+ * Used for enc_dbcs only: Put one double-wide character at ScreenLines["off"]
+ * on the screen at position 'row' and 'col'.
+ * The attributes of the first byte is used for all.  This is required to
+ * output the two bytes of a double-byte character with nothing in between.
+ */
+    static void
+screen_char_2(off, row, col)
+    unsigned	off;
+    int		row;
+    int		col;
+{
+    /* Check for illegal values (could be wrong when screen was resized). */
+    if (off + 1 >= (unsigned)(screen_Rows * screen_Columns))
+	return;
+
+    /* Outputting the last character on the screen may scrollup the screen.
+     * Don't to it!  Mark the character invalid (update it when scrolled up) */
+    if (row == screen_Rows - 1 && col >= screen_Columns - 2)
+    {
+	ScreenAttrs[off] = (sattr_T)-1;
+	return;
+    }
+
+    /* Output the first byte normally (positions the cursor), then write the
+     * second byte directly. */
+    screen_char(off, row, col);
+    out_char(ScreenLines[off + 1]);
+    ++screen_cur_col;
+}
+#endif
+
+#if defined(FEAT_CLIPBOARD) || defined(FEAT_VERTSPLIT) || defined(PROTO)
+/*
+ * Draw a rectangle of the screen, inverted when "invert" is TRUE.
+ * This uses the contents of ScreenLines[] and doesn't change it.
+ */
+    void
+screen_draw_rectangle(row, col, height, width, invert)
+    int		row;
+    int		col;
+    int		height;
+    int		width;
+    int		invert;
+{
+    int		r, c;
+    int		off;
+
+    /* Can't use ScreenLines unless initialized */
+    if (ScreenLines == NULL)
+	return;
+
+    if (invert)
+	screen_char_attr = HL_INVERSE;
+    for (r = row; r < row + height; ++r)
+    {
+	off = LineOffset[r];
+	for (c = col; c < col + width; ++c)
+	{
+#ifdef FEAT_MBYTE
+	    if (enc_dbcs != 0 && dbcs_off2cells(off + c) > 1)
+	    {
+		screen_char_2(off + c, r, c);
+		++c;
+	    }
+	    else
+#endif
+	    {
+		screen_char(off + c, r, c);
+#ifdef FEAT_MBYTE
+		if (utf_off2cells(off + c) > 1)
+		    ++c;
+#endif
+	    }
+	}
+    }
+    screen_char_attr = 0;
+}
+#endif
+
+#ifdef FEAT_VERTSPLIT
+/*
+ * Redraw the characters for a vertically split window.
+ */
+    static void
+redraw_block(row, end, wp)
+    int		row;
+    int		end;
+    win_T	*wp;
+{
+    int		col;
+    int		width;
+
+# ifdef FEAT_CLIPBOARD
+    clip_may_clear_selection(row, end - 1);
+# endif
+
+    if (wp == NULL)
+    {
+	col = 0;
+	width = Columns;
+    }
+    else
+    {
+	col = wp->w_wincol;
+	width = wp->w_width;
+    }
+    screen_draw_rectangle(row, col, end - row, width, FALSE);
+}
+#endif
+
+/*
+ * Fill the screen from 'start_row' to 'end_row', from 'start_col' to 'end_col'
+ * with character 'c1' in first column followed by 'c2' in the other columns.
+ * Use attributes 'attr'.
+ */
+    void
+screen_fill(start_row, end_row, start_col, end_col, c1, c2, attr)
+    int	    start_row, end_row;
+    int	    start_col, end_col;
+    int	    c1, c2;
+    int	    attr;
+{
+    int		    row;
+    int		    col;
+    int		    off;
+    int		    end_off;
+    int		    did_delete;
+    int		    c;
+    int		    norm_term;
+#if defined(FEAT_GUI) || defined(UNIX)
+    int		    force_next = FALSE;
+#endif
+
+    if (end_row > screen_Rows)		/* safety check */
+	end_row = screen_Rows;
+    if (end_col > screen_Columns)	/* safety check */
+	end_col = screen_Columns;
+    if (ScreenLines == NULL
+	    || start_row >= end_row
+	    || start_col >= end_col)	/* nothing to do */
+	return;
+
+    /* it's a "normal" terminal when not in a GUI or cterm */
+    norm_term = (
+#ifdef FEAT_GUI
+	    !gui.in_use &&
+#endif
+			    t_colors <= 1);
+    for (row = start_row; row < end_row; ++row)
+    {
+	/*
+	 * Try to use delete-line termcap code, when no attributes or in a
+	 * "normal" terminal, where a bold/italic space is just a
+	 * space.
+	 */
+	did_delete = FALSE;
+	if (c2 == ' '
+		&& end_col == Columns
+		&& can_clear(T_CE)
+		&& (attr == 0
+		    || (norm_term
+			&& attr <= HL_ALL
+			&& ((attr & ~(HL_BOLD | HL_ITALIC)) == 0))))
+	{
+	    /*
+	     * check if we really need to clear something
+	     */
+	    col = start_col;
+	    if (c1 != ' ')			/* don't clear first char */
+		++col;
+
+	    off = LineOffset[row] + col;
+	    end_off = LineOffset[row] + end_col;
+
+	    /* skip blanks (used often, keep it fast!) */
+#ifdef FEAT_MBYTE
+	    if (enc_utf8)
+		while (off < end_off && ScreenLines[off] == ' '
+			  && ScreenAttrs[off] == 0 && ScreenLinesUC[off] == 0)
+		    ++off;
+	    else
+#endif
+		while (off < end_off && ScreenLines[off] == ' '
+						     && ScreenAttrs[off] == 0)
+		    ++off;
+	    if (off < end_off)		/* something to be cleared */
+	    {
+		col = off - LineOffset[row];
+		screen_stop_highlight();
+		term_windgoto(row, col);/* clear rest of this screen line */
+		out_str(T_CE);
+		screen_start();		/* don't know where cursor is now */
+		col = end_col - col;
+		while (col--)		/* clear chars in ScreenLines */
+		{
+		    ScreenLines[off] = ' ';
+#ifdef FEAT_MBYTE
+		    if (enc_utf8)
+			ScreenLinesUC[off] = 0;
+#endif
+		    ScreenAttrs[off] = 0;
+		    ++off;
+		}
+	    }
+	    did_delete = TRUE;		/* the chars are cleared now */
+	}
+
+	off = LineOffset[row] + start_col;
+	c = c1;
+	for (col = start_col; col < end_col; ++col)
+	{
+	    if (ScreenLines[off] != c
+#ifdef FEAT_MBYTE
+		    || (enc_utf8 && (int)ScreenLinesUC[off]
+						       != (c >= 0x80 ? c : 0))
+#endif
+		    || ScreenAttrs[off] != attr
+#if defined(FEAT_GUI) || defined(UNIX)
+		    || force_next
+#endif
+		    )
+	    {
+#if defined(FEAT_GUI) || defined(UNIX)
+		/* The bold trick may make a single row of pixels appear in
+		 * the next character.  When a bold character is removed, the
+		 * next character should be redrawn too.  This happens for our
+		 * own GUI and for some xterms.  */
+		if (
+# ifdef FEAT_GUI
+			gui.in_use
+# endif
+# if defined(FEAT_GUI) && defined(UNIX)
+			||
+# endif
+# ifdef UNIX
+			term_is_xterm
+# endif
+		   )
+		{
+		    if (ScreenLines[off] != ' '
+			    && (ScreenAttrs[off] > HL_ALL
+				|| ScreenAttrs[off] & HL_BOLD))
+			force_next = TRUE;
+		    else
+			force_next = FALSE;
+		}
+#endif
+		ScreenLines[off] = c;
+#ifdef FEAT_MBYTE
+		if (enc_utf8)
+		{
+		    if (c >= 0x80)
+		    {
+			ScreenLinesUC[off] = c;
+			ScreenLinesC[0][off] = 0;
+		    }
+		    else
+			ScreenLinesUC[off] = 0;
+		}
+#endif
+		ScreenAttrs[off] = attr;
+		if (!did_delete || c != ' ')
+		    screen_char(off, row, col);
+	    }
+	    ++off;
+	    if (col == start_col)
+	    {
+		if (did_delete)
+		    break;
+		c = c2;
+	    }
+	}
+	if (end_col == Columns)
+	    LineWraps[row] = FALSE;
+	if (row == Rows - 1)		/* overwritten the command line */
+	{
+	    redraw_cmdline = TRUE;
+	    if (c1 == ' ' && c2 == ' ')
+		clear_cmdline = FALSE;	/* command line has been cleared */
+	    if (start_col == 0)
+		mode_displayed = FALSE; /* mode cleared or overwritten */
+	}
+    }
+}
+
+/*
+ * Check if there should be a delay.  Used before clearing or redrawing the
+ * screen or the command line.
+ */
+    void
+check_for_delay(check_msg_scroll)
+    int	    check_msg_scroll;
+{
+    if ((emsg_on_display || (check_msg_scroll && msg_scroll))
+	    && !did_wait_return
+	    && emsg_silent == 0)
+    {
+	out_flush();
+	ui_delay(1000L, TRUE);
+	emsg_on_display = FALSE;
+	if (check_msg_scroll)
+	    msg_scroll = FALSE;
+    }
+}
+
+/*
+ * screen_valid -  allocate screen buffers if size changed
+ *   If "clear" is TRUE: clear screen if it has been resized.
+ *	Returns TRUE if there is a valid screen to write to.
+ *	Returns FALSE when starting up and screen not initialized yet.
+ */
+    int
+screen_valid(clear)
+    int	    clear;
+{
+    screenalloc(clear);	    /* allocate screen buffers if size changed */
+    return (ScreenLines != NULL);
+}
+
+/*
+ * Resize the shell to Rows and Columns.
+ * Allocate ScreenLines[] and associated items.
+ *
+ * There may be some time between setting Rows and Columns and (re)allocating
+ * ScreenLines[].  This happens when starting up and when (manually) changing
+ * the shell size.  Always use screen_Rows and screen_Columns to access items
+ * in ScreenLines[].  Use Rows and Columns for positioning text etc. where the
+ * final size of the shell is needed.
+ */
+    void
+screenalloc(clear)
+    int	    clear;
+{
+    int		    new_row, old_row;
+#ifdef FEAT_GUI
+    int		    old_Rows;
+#endif
+    win_T	    *wp;
+    int		    outofmem = FALSE;
+    int		    len;
+    schar_T	    *new_ScreenLines;
+#ifdef FEAT_MBYTE
+    u8char_T	    *new_ScreenLinesUC = NULL;
+    u8char_T	    *new_ScreenLinesC[MAX_MCO];
+    schar_T	    *new_ScreenLines2 = NULL;
+    int		    i;
+#endif
+    sattr_T	    *new_ScreenAttrs;
+    unsigned	    *new_LineOffset;
+    char_u	    *new_LineWraps;
+#ifdef FEAT_WINDOWS
+    short	    *new_TabPageIdxs;
+    tabpage_T	    *tp;
+#endif
+    static int	    entered = FALSE;		/* avoid recursiveness */
+    static int	    done_outofmem_msg = FALSE;	/* did outofmem message */
+
+    /*
+     * Allocation of the screen buffers is done only when the size changes and
+     * when Rows and Columns have been set and we have started doing full
+     * screen stuff.
+     */
+    if ((ScreenLines != NULL
+		&& Rows == screen_Rows
+		&& Columns == screen_Columns
+#ifdef FEAT_MBYTE
+		&& enc_utf8 == (ScreenLinesUC != NULL)
+		&& (enc_dbcs == DBCS_JPNU) == (ScreenLines2 != NULL)
+		&& p_mco == Screen_mco
+#endif
+		)
+	    || Rows == 0
+	    || Columns == 0
+	    || (!full_screen && ScreenLines == NULL))
+	return;
+
+    /*
+     * It's possible that we produce an out-of-memory message below, which
+     * will cause this function to be called again.  To break the loop, just
+     * return here.
+     */
+    if (entered)
+	return;
+    entered = TRUE;
+
+    /*
+     * Note that the window sizes are updated before reallocating the arrays,
+     * thus we must not redraw here!
+     */
+    ++RedrawingDisabled;
+
+    win_new_shellsize();    /* fit the windows in the new sized shell */
+
+    comp_col();		/* recompute columns for shown command and ruler */
+
+    /*
+     * We're changing the size of the screen.
+     * - Allocate new arrays for ScreenLines and ScreenAttrs.
+     * - Move lines from the old arrays into the new arrays, clear extra
+     *	 lines (unless the screen is going to be cleared).
+     * - Free the old arrays.
+     *
+     * If anything fails, make ScreenLines NULL, so we don't do anything!
+     * Continuing with the old ScreenLines may result in a crash, because the
+     * size is wrong.
+     */
+    FOR_ALL_TAB_WINDOWS(tp, wp)
+	win_free_lsize(wp);
+
+    new_ScreenLines = (schar_T *)lalloc((long_u)(
+			      (Rows + 1) * Columns * sizeof(schar_T)), FALSE);
+#ifdef FEAT_MBYTE
+    vim_memset(new_ScreenLinesC, 0, sizeof(u8char_T) * MAX_MCO);
+    if (enc_utf8)
+    {
+	new_ScreenLinesUC = (u8char_T *)lalloc((long_u)(
+			     (Rows + 1) * Columns * sizeof(u8char_T)), FALSE);
+	for (i = 0; i < p_mco; ++i)
+	    new_ScreenLinesC[i] = (u8char_T *)lalloc((long_u)(
+			     (Rows + 1) * Columns * sizeof(u8char_T)), FALSE);
+    }
+    if (enc_dbcs == DBCS_JPNU)
+	new_ScreenLines2 = (schar_T *)lalloc((long_u)(
+			     (Rows + 1) * Columns * sizeof(schar_T)), FALSE);
+#endif
+    new_ScreenAttrs = (sattr_T *)lalloc((long_u)(
+			      (Rows + 1) * Columns * sizeof(sattr_T)), FALSE);
+    new_LineOffset = (unsigned *)lalloc((long_u)(
+					 Rows * sizeof(unsigned)), FALSE);
+    new_LineWraps = (char_u *)lalloc((long_u)(Rows * sizeof(char_u)), FALSE);
+#ifdef FEAT_WINDOWS
+    new_TabPageIdxs = (short *)lalloc((long_u)(Columns * sizeof(short)), FALSE);
+#endif
+
+    FOR_ALL_TAB_WINDOWS(tp, wp)
+    {
+	if (win_alloc_lines(wp) == FAIL)
+	{
+	    outofmem = TRUE;
+#ifdef FEAT_WINDOWS
+	    break;
+#endif
+	}
+    }
+
+#ifdef FEAT_MBYTE
+    for (i = 0; i < p_mco; ++i)
+	if (new_ScreenLinesC[i] == NULL)
+	    break;
+#endif
+    if (new_ScreenLines == NULL
+#ifdef FEAT_MBYTE
+	    || (enc_utf8 && (new_ScreenLinesUC == NULL || i != p_mco))
+	    || (enc_dbcs == DBCS_JPNU && new_ScreenLines2 == NULL)
+#endif
+	    || new_ScreenAttrs == NULL
+	    || new_LineOffset == NULL
+	    || new_LineWraps == NULL
+#ifdef FEAT_WINDOWS
+	    || new_TabPageIdxs == NULL
+#endif
+	    || outofmem)
+    {
+	if (ScreenLines != NULL || !done_outofmem_msg)
+	{
+	    /* guess the size */
+	    do_outofmem_msg((long_u)((Rows + 1) * Columns));
+
+	    /* Remember we did this to avoid getting outofmem messages over
+	     * and over again. */
+	    done_outofmem_msg = TRUE;
+	}
+	vim_free(new_ScreenLines);
+	new_ScreenLines = NULL;
+#ifdef FEAT_MBYTE
+	vim_free(new_ScreenLinesUC);
+	new_ScreenLinesUC = NULL;
+	for (i = 0; i < p_mco; ++i)
+	{
+	    vim_free(new_ScreenLinesC[i]);
+	    new_ScreenLinesC[i] = NULL;
+	}
+	vim_free(new_ScreenLines2);
+	new_ScreenLines2 = NULL;
+#endif
+	vim_free(new_ScreenAttrs);
+	new_ScreenAttrs = NULL;
+	vim_free(new_LineOffset);
+	new_LineOffset = NULL;
+	vim_free(new_LineWraps);
+	new_LineWraps = NULL;
+#ifdef FEAT_WINDOWS
+	vim_free(new_TabPageIdxs);
+	new_TabPageIdxs = NULL;
+#endif
+    }
+    else
+    {
+	done_outofmem_msg = FALSE;
+
+	for (new_row = 0; new_row < Rows; ++new_row)
+	{
+	    new_LineOffset[new_row] = new_row * Columns;
+	    new_LineWraps[new_row] = FALSE;
+
+	    /*
+	     * If the screen is not going to be cleared, copy as much as
+	     * possible from the old screen to the new one and clear the rest
+	     * (used when resizing the window at the "--more--" prompt or when
+	     * executing an external command, for the GUI).
+	     */
+	    if (!clear)
+	    {
+		(void)vim_memset(new_ScreenLines + new_row * Columns,
+				      ' ', (size_t)Columns * sizeof(schar_T));
+#ifdef FEAT_MBYTE
+		if (enc_utf8)
+		{
+		    (void)vim_memset(new_ScreenLinesUC + new_row * Columns,
+				       0, (size_t)Columns * sizeof(u8char_T));
+		    for (i = 0; i < p_mco; ++i)
+			(void)vim_memset(new_ScreenLinesC[i]
+							  + new_row * Columns,
+				       0, (size_t)Columns * sizeof(u8char_T));
+		}
+		if (enc_dbcs == DBCS_JPNU)
+		    (void)vim_memset(new_ScreenLines2 + new_row * Columns,
+				       0, (size_t)Columns * sizeof(schar_T));
+#endif
+		(void)vim_memset(new_ScreenAttrs + new_row * Columns,
+					0, (size_t)Columns * sizeof(sattr_T));
+		old_row = new_row + (screen_Rows - Rows);
+		if (old_row >= 0 && ScreenLines != NULL)
+		{
+		    if (screen_Columns < Columns)
+			len = screen_Columns;
+		    else
+			len = Columns;
+#ifdef FEAT_MBYTE
+		    /* When switching to utf-8 don't copy characters, they
+		     * may be invalid now.  Also when p_mco changes. */
+		    if (!(enc_utf8 && ScreenLinesUC == NULL)
+						       && p_mco == Screen_mco)
+#endif
+			mch_memmove(new_ScreenLines + new_LineOffset[new_row],
+				ScreenLines + LineOffset[old_row],
+				(size_t)len * sizeof(schar_T));
+#ifdef FEAT_MBYTE
+		    if (enc_utf8 && ScreenLinesUC != NULL
+						       && p_mco == Screen_mco)
+		    {
+			mch_memmove(new_ScreenLinesUC + new_LineOffset[new_row],
+				ScreenLinesUC + LineOffset[old_row],
+				(size_t)len * sizeof(u8char_T));
+			for (i = 0; i < p_mco; ++i)
+			    mch_memmove(new_ScreenLinesC[i]
+						    + new_LineOffset[new_row],
+				ScreenLinesC[i] + LineOffset[old_row],
+				(size_t)len * sizeof(u8char_T));
+		    }
+		    if (enc_dbcs == DBCS_JPNU && ScreenLines2 != NULL)
+			mch_memmove(new_ScreenLines2 + new_LineOffset[new_row],
+				ScreenLines2 + LineOffset[old_row],
+				(size_t)len * sizeof(schar_T));
+#endif
+		    mch_memmove(new_ScreenAttrs + new_LineOffset[new_row],
+			    ScreenAttrs + LineOffset[old_row],
+			    (size_t)len * sizeof(sattr_T));
+		}
+	    }
+	}
+	/* Use the last line of the screen for the current line. */
+	current_ScreenLine = new_ScreenLines + Rows * Columns;
+    }
+
+    free_screenlines();
+
+    ScreenLines = new_ScreenLines;
+#ifdef FEAT_MBYTE
+    ScreenLinesUC = new_ScreenLinesUC;
+    for (i = 0; i < p_mco; ++i)
+	ScreenLinesC[i] = new_ScreenLinesC[i];
+    Screen_mco = p_mco;
+    ScreenLines2 = new_ScreenLines2;
+#endif
+    ScreenAttrs = new_ScreenAttrs;
+    LineOffset = new_LineOffset;
+    LineWraps = new_LineWraps;
+#ifdef FEAT_WINDOWS
+    TabPageIdxs = new_TabPageIdxs;
+#endif
+
+    /* It's important that screen_Rows and screen_Columns reflect the actual
+     * size of ScreenLines[].  Set them before calling anything. */
+#ifdef FEAT_GUI
+    old_Rows = screen_Rows;
+#endif
+    screen_Rows = Rows;
+    screen_Columns = Columns;
+
+    must_redraw = CLEAR;	/* need to clear the screen later */
+    if (clear)
+	screenclear2();
+
+#ifdef FEAT_GUI
+    else if (gui.in_use
+	    && !gui.starting
+	    && ScreenLines != NULL
+	    && old_Rows != Rows)
+    {
+	(void)gui_redraw_block(0, 0, (int)Rows - 1, (int)Columns - 1, 0);
+	/*
+	 * Adjust the position of the cursor, for when executing an external
+	 * command.
+	 */
+	if (msg_row >= Rows)		/* Rows got smaller */
+	    msg_row = Rows - 1;		/* put cursor at last row */
+	else if (Rows > old_Rows)	/* Rows got bigger */
+	    msg_row += Rows - old_Rows; /* put cursor in same place */
+	if (msg_col >= Columns)		/* Columns got smaller */
+	    msg_col = Columns - 1;	/* put cursor at last column */
+    }
+#endif
+
+    entered = FALSE;
+    --RedrawingDisabled;
+
+#ifdef FEAT_AUTOCMD
+    if (starting == 0)
+	apply_autocmds(EVENT_VIMRESIZED, NULL, NULL, FALSE, curbuf);
+#endif
+}
+
+    void
+free_screenlines()
+{
+#ifdef FEAT_MBYTE
+    int		i;
+
+    vim_free(ScreenLinesUC);
+    for (i = 0; i < Screen_mco; ++i)
+	vim_free(ScreenLinesC[i]);
+    vim_free(ScreenLines2);
+#endif
+    vim_free(ScreenLines);
+    vim_free(ScreenAttrs);
+    vim_free(LineOffset);
+    vim_free(LineWraps);
+#ifdef FEAT_WINDOWS
+    vim_free(TabPageIdxs);
+#endif
+}
+
+    void
+screenclear()
+{
+    check_for_delay(FALSE);
+    screenalloc(FALSE);	    /* allocate screen buffers if size changed */
+    screenclear2();	    /* clear the screen */
+}
+
+    static void
+screenclear2()
+{
+    int	    i;
+
+    if (starting == NO_SCREEN || ScreenLines == NULL
+#ifdef FEAT_GUI
+	    || (gui.in_use && gui.starting)
+#endif
+	    )
+	return;
+
+#ifdef FEAT_GUI
+    if (!gui.in_use)
+#endif
+	screen_attr = -1;	/* force setting the Normal colors */
+    screen_stop_highlight();	/* don't want highlighting here */
+
+#ifdef FEAT_CLIPBOARD
+    /* disable selection without redrawing it */
+    clip_scroll_selection(9999);
+#endif
+
+    /* blank out ScreenLines */
+    for (i = 0; i < Rows; ++i)
+    {
+	lineclear(LineOffset[i], (int)Columns);
+	LineWraps[i] = FALSE;
+    }
+
+    if (can_clear(T_CL))
+    {
+	out_str(T_CL);		/* clear the display */
+	clear_cmdline = FALSE;
+	mode_displayed = FALSE;
+    }
+    else
+    {
+	/* can't clear the screen, mark all chars with invalid attributes */
+	for (i = 0; i < Rows; ++i)
+	    lineinvalid(LineOffset[i], (int)Columns);
+	clear_cmdline = TRUE;
+    }
+
+    screen_cleared = TRUE;	/* can use contents of ScreenLines now */
+
+    win_rest_invalid(firstwin);
+    redraw_cmdline = TRUE;
+#ifdef FEAT_WINDOWS
+    redraw_tabline = TRUE;
+#endif
+    if (must_redraw == CLEAR)	/* no need to clear again */
+	must_redraw = NOT_VALID;
+    compute_cmdrow();
+    msg_row = cmdline_row;	/* put cursor on last line for messages */
+    msg_col = 0;
+    screen_start();		/* don't know where cursor is now */
+    msg_scrolled = 0;		/* can't scroll back */
+    msg_didany = FALSE;
+    msg_didout = FALSE;
+}
+
+/*
+ * Clear one line in ScreenLines.
+ */
+    static void
+lineclear(off, width)
+    unsigned	off;
+    int		width;
+{
+    (void)vim_memset(ScreenLines + off, ' ', (size_t)width * sizeof(schar_T));
+#ifdef FEAT_MBYTE
+    if (enc_utf8)
+	(void)vim_memset(ScreenLinesUC + off, 0,
+					  (size_t)width * sizeof(u8char_T));
+#endif
+    (void)vim_memset(ScreenAttrs + off, 0, (size_t)width * sizeof(sattr_T));
+}
+
+/*
+ * Mark one line in ScreenLines invalid by setting the attributes to an
+ * invalid value.
+ */
+    static void
+lineinvalid(off, width)
+    unsigned	off;
+    int		width;
+{
+    (void)vim_memset(ScreenAttrs + off, -1, (size_t)width * sizeof(sattr_T));
+}
+
+#ifdef FEAT_VERTSPLIT
+/*
+ * Copy part of a Screenline for vertically split window "wp".
+ */
+    static void
+linecopy(to, from, wp)
+    int		to;
+    int		from;
+    win_T	*wp;
+{
+    unsigned	off_to = LineOffset[to] + wp->w_wincol;
+    unsigned	off_from = LineOffset[from] + wp->w_wincol;
+
+    mch_memmove(ScreenLines + off_to, ScreenLines + off_from,
+	    wp->w_width * sizeof(schar_T));
+# ifdef FEAT_MBYTE
+    if (enc_utf8)
+    {
+	int	i;
+
+	mch_memmove(ScreenLinesUC + off_to, ScreenLinesUC + off_from,
+		wp->w_width * sizeof(u8char_T));
+	for (i = 0; i < p_mco; ++i)
+	    mch_memmove(ScreenLinesC[i] + off_to, ScreenLinesC[i] + off_from,
+		    wp->w_width * sizeof(u8char_T));
+    }
+    if (enc_dbcs == DBCS_JPNU)
+	mch_memmove(ScreenLines2 + off_to, ScreenLines2 + off_from,
+		wp->w_width * sizeof(schar_T));
+# endif
+    mch_memmove(ScreenAttrs + off_to, ScreenAttrs + off_from,
+	    wp->w_width * sizeof(sattr_T));
+}
+#endif
+
+/*
+ * Return TRUE if clearing with term string "p" would work.
+ * It can't work when the string is empty or it won't set the right background.
+ */
+    int
+can_clear(p)
+    char_u	*p;
+{
+    return (*p != NUL && (t_colors <= 1
+#ifdef FEAT_GUI
+		|| gui.in_use
+#endif
+		|| cterm_normal_bg_color == 0 || *T_UT != NUL));
+}
+
+/*
+ * Reset cursor position. Use whenever cursor was moved because of outputting
+ * something directly to the screen (shell commands) or a terminal control
+ * code.
+ */
+    void
+screen_start()
+{
+    screen_cur_row = screen_cur_col = 9999;
+}
+
+/*
+ * Move the cursor to position "row","col" in the screen.
+ * This tries to find the most efficient way to move, minimizing the number of
+ * characters sent to the terminal.
+ */
+    void
+windgoto(row, col)
+    int	    row;
+    int	    col;
+{
+    sattr_T	    *p;
+    int		    i;
+    int		    plan;
+    int		    cost;
+    int		    wouldbe_col;
+    int		    noinvcurs;
+    char_u	    *bs;
+    int		    goto_cost;
+    int		    attr;
+
+#define GOTO_COST   7	/* assume a term_windgoto() takes about 7 chars */
+#define HIGHL_COST  5	/* assume unhighlight takes 5 chars */
+
+#define PLAN_LE	    1
+#define PLAN_CR	    2
+#define PLAN_NL	    3
+#define PLAN_WRITE  4
+    /* Can't use ScreenLines unless initialized */
+    if (ScreenLines == NULL)
+	return;
+
+    if (col != screen_cur_col || row != screen_cur_row)
+    {
+	/* Check for valid position. */
+	if (row < 0)	/* window without text lines? */
+	    row = 0;
+	if (row >= screen_Rows)
+	    row = screen_Rows - 1;
+	if (col >= screen_Columns)
+	    col = screen_Columns - 1;
+
+	/* check if no cursor movement is allowed in highlight mode */
+	if (screen_attr && *T_MS == NUL)
+	    noinvcurs = HIGHL_COST;
+	else
+	    noinvcurs = 0;
+	goto_cost = GOTO_COST + noinvcurs;
+
+	/*
+	 * Plan how to do the positioning:
+	 * 1. Use CR to move it to column 0, same row.
+	 * 2. Use T_LE to move it a few columns to the left.
+	 * 3. Use NL to move a few lines down, column 0.
+	 * 4. Move a few columns to the right with T_ND or by writing chars.
+	 *
+	 * Don't do this if the cursor went beyond the last column, the cursor
+	 * position is unknown then (some terminals wrap, some don't )
+	 *
+	 * First check if the highlighting attributes allow us to write
+	 * characters to move the cursor to the right.
+	 */
+	if (row >= screen_cur_row && screen_cur_col < Columns)
+	{
+	    /*
+	     * If the cursor is in the same row, bigger col, we can use CR
+	     * or T_LE.
+	     */
+	    bs = NULL;			    /* init for GCC */
+	    attr = screen_attr;
+	    if (row == screen_cur_row && col < screen_cur_col)
+	    {
+		/* "le" is preferred over "bc", because "bc" is obsolete */
+		if (*T_LE)
+		    bs = T_LE;		    /* "cursor left" */
+		else
+		    bs = T_BC;		    /* "backspace character (old) */
+		if (*bs)
+		    cost = (screen_cur_col - col) * (int)STRLEN(bs);
+		else
+		    cost = 999;
+		if (col + 1 < cost)	    /* using CR is less characters */
+		{
+		    plan = PLAN_CR;
+		    wouldbe_col = 0;
+		    cost = 1;		    /* CR is just one character */
+		}
+		else
+		{
+		    plan = PLAN_LE;
+		    wouldbe_col = col;
+		}
+		if (noinvcurs)		    /* will stop highlighting */
+		{
+		    cost += noinvcurs;
+		    attr = 0;
+		}
+	    }
+
+	    /*
+	     * If the cursor is above where we want to be, we can use CR LF.
+	     */
+	    else if (row > screen_cur_row)
+	    {
+		plan = PLAN_NL;
+		wouldbe_col = 0;
+		cost = (row - screen_cur_row) * 2;  /* CR LF */
+		if (noinvcurs)		    /* will stop highlighting */
+		{
+		    cost += noinvcurs;
+		    attr = 0;
+		}
+	    }
+
+	    /*
+	     * If the cursor is in the same row, smaller col, just use write.
+	     */
+	    else
+	    {
+		plan = PLAN_WRITE;
+		wouldbe_col = screen_cur_col;
+		cost = 0;
+	    }
+
+	    /*
+	     * Check if any characters that need to be written have the
+	     * correct attributes.  Also avoid UTF-8 characters.
+	     */
+	    i = col - wouldbe_col;
+	    if (i > 0)
+		cost += i;
+	    if (cost < goto_cost && i > 0)
+	    {
+		/*
+		 * Check if the attributes are correct without additionally
+		 * stopping highlighting.
+		 */
+		p = ScreenAttrs + LineOffset[row] + wouldbe_col;
+		while (i && *p++ == attr)
+		    --i;
+		if (i != 0)
+		{
+		    /*
+		     * Try if it works when highlighting is stopped here.
+		     */
+		    if (*--p == 0)
+		    {
+			cost += noinvcurs;
+			while (i && *p++ == 0)
+			    --i;
+		    }
+		    if (i != 0)
+			cost = 999;	/* different attributes, don't do it */
+		}
+#ifdef FEAT_MBYTE
+		if (enc_utf8)
+		{
+		    /* Don't use an UTF-8 char for positioning, it's slow. */
+		    for (i = wouldbe_col; i < col; ++i)
+			if (ScreenLinesUC[LineOffset[row] + i] != 0)
+			{
+			    cost = 999;
+			    break;
+			}
+		}
+#endif
+	    }
+
+	    /*
+	     * We can do it without term_windgoto()!
+	     */
+	    if (cost < goto_cost)
+	    {
+		if (plan == PLAN_LE)
+		{
+		    if (noinvcurs)
+			screen_stop_highlight();
+		    while (screen_cur_col > col)
+		    {
+			out_str(bs);
+			--screen_cur_col;
+		    }
+		}
+		else if (plan == PLAN_CR)
+		{
+		    if (noinvcurs)
+			screen_stop_highlight();
+		    out_char('\r');
+		    screen_cur_col = 0;
+		}
+		else if (plan == PLAN_NL)
+		{
+		    if (noinvcurs)
+			screen_stop_highlight();
+		    while (screen_cur_row < row)
+		    {
+			out_char('\n');
+			++screen_cur_row;
+		    }
+		    screen_cur_col = 0;
+		}
+
+		i = col - screen_cur_col;
+		if (i > 0)
+		{
+		    /*
+		     * Use cursor-right if it's one character only.  Avoids
+		     * removing a line of pixels from the last bold char, when
+		     * using the bold trick in the GUI.
+		     */
+		    if (T_ND[0] != NUL && T_ND[1] == NUL)
+		    {
+			while (i-- > 0)
+			    out_char(*T_ND);
+		    }
+		    else
+		    {
+			int	off;
+
+			off = LineOffset[row] + screen_cur_col;
+			while (i-- > 0)
+			{
+			    if (ScreenAttrs[off] != screen_attr)
+				screen_stop_highlight();
+#ifdef FEAT_MBYTE
+			    out_flush_check();
+#endif
+			    out_char(ScreenLines[off]);
+#ifdef FEAT_MBYTE
+			    if (enc_dbcs == DBCS_JPNU
+						  && ScreenLines[off] == 0x8e)
+				out_char(ScreenLines2[off]);
+#endif
+			    ++off;
+			}
+		    }
+		}
+	    }
+	}
+	else
+	    cost = 999;
+
+	if (cost >= goto_cost)
+	{
+	    if (noinvcurs)
+		screen_stop_highlight();
+	    if (row == screen_cur_row && (col > screen_cur_col) &&
+								*T_CRI != NUL)
+		term_cursor_right(col - screen_cur_col);
+	    else
+		term_windgoto(row, col);
+	}
+	screen_cur_row = row;
+	screen_cur_col = col;
+    }
+}
+
+/*
+ * Set cursor to its position in the current window.
+ */
+    void
+setcursor()
+{
+    if (redrawing())
+    {
+	validate_cursor();
+	windgoto(W_WINROW(curwin) + curwin->w_wrow,
+		W_WINCOL(curwin) + (
+#ifdef FEAT_RIGHTLEFT
+		curwin->w_p_rl ? ((int)W_WIDTH(curwin) - curwin->w_wcol - (
+# ifdef FEAT_MBYTE
+			has_mbyte ? (*mb_ptr2cells)(ml_get_cursor()) :
+# endif
+			1)) :
+#endif
+							    curwin->w_wcol));
+    }
+}
+
+
+/*
+ * insert 'line_count' lines at 'row' in window 'wp'
+ * if 'invalid' is TRUE the wp->w_lines[].wl_lnum is invalidated.
+ * if 'mayclear' is TRUE the screen will be cleared if it is faster than
+ * scrolling.
+ * Returns FAIL if the lines are not inserted, OK for success.
+ */
+    int
+win_ins_lines(wp, row, line_count, invalid, mayclear)
+    win_T	*wp;
+    int		row;
+    int		line_count;
+    int		invalid;
+    int		mayclear;
+{
+    int		did_delete;
+    int		nextrow;
+    int		lastrow;
+    int		retval;
+
+    if (invalid)
+	wp->w_lines_valid = 0;
+
+    if (wp->w_height < 5)
+	return FAIL;
+
+    if (line_count > wp->w_height - row)
+	line_count = wp->w_height - row;
+
+    retval = win_do_lines(wp, row, line_count, mayclear, FALSE);
+    if (retval != MAYBE)
+	return retval;
+
+    /*
+     * If there is a next window or a status line, we first try to delete the
+     * lines at the bottom to avoid messing what is after the window.
+     * If this fails and there are following windows, don't do anything to avoid
+     * messing up those windows, better just redraw.
+     */
+    did_delete = FALSE;
+#ifdef FEAT_WINDOWS
+    if (wp->w_next != NULL || wp->w_status_height)
+    {
+	if (screen_del_lines(0, W_WINROW(wp) + wp->w_height - line_count,
+				    line_count, (int)Rows, FALSE, NULL) == OK)
+	    did_delete = TRUE;
+	else if (wp->w_next)
+	    return FAIL;
+    }
+#endif
+    /*
+     * if no lines deleted, blank the lines that will end up below the window
+     */
+    if (!did_delete)
+    {
+#ifdef FEAT_WINDOWS
+	wp->w_redr_status = TRUE;
+#endif
+	redraw_cmdline = TRUE;
+	nextrow = W_WINROW(wp) + wp->w_height + W_STATUS_HEIGHT(wp);
+	lastrow = nextrow + line_count;
+	if (lastrow > Rows)
+	    lastrow = Rows;
+	screen_fill(nextrow - line_count, lastrow - line_count,
+		  W_WINCOL(wp), (int)W_ENDCOL(wp),
+		  ' ', ' ', 0);
+    }
+
+    if (screen_ins_lines(0, W_WINROW(wp) + row, line_count, (int)Rows, NULL)
+								      == FAIL)
+    {
+	    /* deletion will have messed up other windows */
+	if (did_delete)
+	{
+#ifdef FEAT_WINDOWS
+	    wp->w_redr_status = TRUE;
+#endif
+	    win_rest_invalid(W_NEXT(wp));
+	}
+	return FAIL;
+    }
+
+    return OK;
+}
+
+/*
+ * delete "line_count" window lines at "row" in window "wp"
+ * If "invalid" is TRUE curwin->w_lines[] is invalidated.
+ * If "mayclear" is TRUE the screen will be cleared if it is faster than
+ * scrolling
+ * Return OK for success, FAIL if the lines are not deleted.
+ */
+    int
+win_del_lines(wp, row, line_count, invalid, mayclear)
+    win_T	*wp;
+    int		row;
+    int		line_count;
+    int		invalid;
+    int		mayclear;
+{
+    int		retval;
+
+    if (invalid)
+	wp->w_lines_valid = 0;
+
+    if (line_count > wp->w_height - row)
+	line_count = wp->w_height - row;
+
+    retval = win_do_lines(wp, row, line_count, mayclear, TRUE);
+    if (retval != MAYBE)
+	return retval;
+
+    if (screen_del_lines(0, W_WINROW(wp) + row, line_count,
+					      (int)Rows, FALSE, NULL) == FAIL)
+	return FAIL;
+
+#ifdef FEAT_WINDOWS
+    /*
+     * If there are windows or status lines below, try to put them at the
+     * correct place. If we can't do that, they have to be redrawn.
+     */
+    if (wp->w_next || wp->w_status_height || cmdline_row < Rows - 1)
+    {
+	if (screen_ins_lines(0, W_WINROW(wp) + wp->w_height - line_count,
+					 line_count, (int)Rows, NULL) == FAIL)
+	{
+	    wp->w_redr_status = TRUE;
+	    win_rest_invalid(wp->w_next);
+	}
+    }
+    /*
+     * If this is the last window and there is no status line, redraw the
+     * command line later.
+     */
+    else
+#endif
+	redraw_cmdline = TRUE;
+    return OK;
+}
+
+/*
+ * Common code for win_ins_lines() and win_del_lines().
+ * Returns OK or FAIL when the work has been done.
+ * Returns MAYBE when not finished yet.
+ */
+    static int
+win_do_lines(wp, row, line_count, mayclear, del)
+    win_T	*wp;
+    int		row;
+    int		line_count;
+    int		mayclear;
+    int		del;
+{
+    int		retval;
+
+    if (!redrawing() || line_count <= 0)
+	return FAIL;
+
+    /* only a few lines left: redraw is faster */
+    if (mayclear && Rows - line_count < 5
+#ifdef FEAT_VERTSPLIT
+	    && wp->w_width == Columns
+#endif
+	    )
+    {
+	screenclear();	    /* will set wp->w_lines_valid to 0 */
+	return FAIL;
+    }
+
+    /*
+     * Delete all remaining lines
+     */
+    if (row + line_count >= wp->w_height)
+    {
+	screen_fill(W_WINROW(wp) + row, W_WINROW(wp) + wp->w_height,
+		W_WINCOL(wp), (int)W_ENDCOL(wp),
+		' ', ' ', 0);
+	return OK;
+    }
+
+    /*
+     * when scrolling, the message on the command line should be cleared,
+     * otherwise it will stay there forever.
+     */
+    clear_cmdline = TRUE;
+
+    /*
+     * If the terminal can set a scroll region, use that.
+     * Always do this in a vertically split window.  This will redraw from
+     * ScreenLines[] when t_CV isn't defined.  That's faster than using
+     * win_line().
+     * Don't use a scroll region when we are going to redraw the text, writing
+     * a character in the lower right corner of the scroll region causes a
+     * scroll-up in the DJGPP version.
+     */
+    if (scroll_region
+#ifdef FEAT_VERTSPLIT
+	    || W_WIDTH(wp) != Columns
+#endif
+	    )
+    {
+#ifdef FEAT_VERTSPLIT
+	if (scroll_region && (wp->w_width == Columns || *T_CSV != NUL))
+#endif
+	    scroll_region_set(wp, row);
+	if (del)
+	    retval = screen_del_lines(W_WINROW(wp) + row, 0, line_count,
+					       wp->w_height - row, FALSE, wp);
+	else
+	    retval = screen_ins_lines(W_WINROW(wp) + row, 0, line_count,
+						      wp->w_height - row, wp);
+#ifdef FEAT_VERTSPLIT
+	if (scroll_region && (wp->w_width == Columns || *T_CSV != NUL))
+#endif
+	    scroll_region_reset();
+	return retval;
+    }
+
+#ifdef FEAT_WINDOWS
+    if (wp->w_next != NULL && p_tf) /* don't delete/insert on fast terminal */
+	return FAIL;
+#endif
+
+    return MAYBE;
+}
+
+/*
+ * window 'wp' and everything after it is messed up, mark it for redraw
+ */
+    static void
+win_rest_invalid(wp)
+    win_T	*wp;
+{
+#ifdef FEAT_WINDOWS
+    while (wp != NULL)
+#else
+    if (wp != NULL)
+#endif
+    {
+	redraw_win_later(wp, NOT_VALID);
+#ifdef FEAT_WINDOWS
+	wp->w_redr_status = TRUE;
+	wp = wp->w_next;
+#endif
+    }
+    redraw_cmdline = TRUE;
+}
+
+/*
+ * The rest of the routines in this file perform screen manipulations. The
+ * given operation is performed physically on the screen. The corresponding
+ * change is also made to the internal screen image. In this way, the editor
+ * anticipates the effect of editing changes on the appearance of the screen.
+ * That way, when we call screenupdate a complete redraw isn't usually
+ * necessary. Another advantage is that we can keep adding code to anticipate
+ * screen changes, and in the meantime, everything still works.
+ */
+
+/*
+ * types for inserting or deleting lines
+ */
+#define USE_T_CAL   1
+#define USE_T_CDL   2
+#define USE_T_AL    3
+#define USE_T_CE    4
+#define USE_T_DL    5
+#define USE_T_SR    6
+#define USE_NL	    7
+#define USE_T_CD    8
+#define USE_REDRAW  9
+
+/*
+ * insert lines on the screen and update ScreenLines[]
+ * 'end' is the line after the scrolled part. Normally it is Rows.
+ * When scrolling region used 'off' is the offset from the top for the region.
+ * 'row' and 'end' are relative to the start of the region.
+ *
+ * return FAIL for failure, OK for success.
+ */
+    int
+screen_ins_lines(off, row, line_count, end, wp)
+    int		off;
+    int		row;
+    int		line_count;
+    int		end;
+    win_T	*wp;	    /* NULL or window to use width from */
+{
+    int		i;
+    int		j;
+    unsigned	temp;
+    int		cursor_row;
+    int		type;
+    int		result_empty;
+    int		can_ce = can_clear(T_CE);
+
+    /*
+     * FAIL if
+     * - there is no valid screen
+     * - the screen has to be redrawn completely
+     * - the line count is less than one
+     * - the line count is more than 'ttyscroll'
+     */
+    if (!screen_valid(TRUE) || line_count <= 0 || line_count > p_ttyscroll)
+	return FAIL;
+
+    /*
+     * There are seven ways to insert lines:
+     * 0. When in a vertically split window and t_CV isn't set, redraw the
+     *    characters from ScreenLines[].
+     * 1. Use T_CD (clear to end of display) if it exists and the result of
+     *	  the insert is just empty lines
+     * 2. Use T_CAL (insert multiple lines) if it exists and T_AL is not
+     *	  present or line_count > 1. It looks better if we do all the inserts
+     *	  at once.
+     * 3. Use T_CDL (delete multiple lines) if it exists and the result of the
+     *	  insert is just empty lines and T_CE is not present or line_count >
+     *	  1.
+     * 4. Use T_AL (insert line) if it exists.
+     * 5. Use T_CE (erase line) if it exists and the result of the insert is
+     *	  just empty lines.
+     * 6. Use T_DL (delete line) if it exists and the result of the insert is
+     *	  just empty lines.
+     * 7. Use T_SR (scroll reverse) if it exists and inserting at row 0 and
+     *	  the 'da' flag is not set or we have clear line capability.
+     * 8. redraw the characters from ScreenLines[].
+     *
+     * Careful: In a hpterm scroll reverse doesn't work as expected, it moves
+     * the scrollbar for the window. It does have insert line, use that if it
+     * exists.
+     */
+    result_empty = (row + line_count >= end);
+#ifdef FEAT_VERTSPLIT
+    if (wp != NULL && wp->w_width != Columns && *T_CSV == NUL)
+	type = USE_REDRAW;
+    else
+#endif
+    if (can_clear(T_CD) && result_empty)
+	type = USE_T_CD;
+    else if (*T_CAL != NUL && (line_count > 1 || *T_AL == NUL))
+	type = USE_T_CAL;
+    else if (*T_CDL != NUL && result_empty && (line_count > 1 || !can_ce))
+	type = USE_T_CDL;
+    else if (*T_AL != NUL)
+	type = USE_T_AL;
+    else if (can_ce && result_empty)
+	type = USE_T_CE;
+    else if (*T_DL != NUL && result_empty)
+	type = USE_T_DL;
+    else if (*T_SR != NUL && row == 0 && (*T_DA == NUL || can_ce))
+	type = USE_T_SR;
+    else
+	return FAIL;
+
+    /*
+     * For clearing the lines screen_del_lines() is used. This will also take
+     * care of t_db if necessary.
+     */
+    if (type == USE_T_CD || type == USE_T_CDL ||
+					 type == USE_T_CE || type == USE_T_DL)
+	return screen_del_lines(off, row, line_count, end, FALSE, wp);
+
+    /*
+     * If text is retained below the screen, first clear or delete as many
+     * lines at the bottom of the window as are about to be inserted so that
+     * the deleted lines won't later surface during a screen_del_lines.
+     */
+    if (*T_DB)
+	screen_del_lines(off, end - line_count, line_count, end, FALSE, wp);
+
+#ifdef FEAT_CLIPBOARD
+    /* Remove a modeless selection when inserting lines halfway the screen
+     * or not the full width of the screen. */
+    if (off + row > 0
+# ifdef FEAT_VERTSPLIT
+	    || (wp != NULL && wp->w_width != Columns)
+# endif
+       )
+	clip_clear_selection();
+    else
+	clip_scroll_selection(-line_count);
+#endif
+
+#ifdef FEAT_GUI
+    /* Don't update the GUI cursor here, ScreenLines[] is invalid until the
+     * scrolling is actually carried out. */
+    gui_dont_update_cursor();
+#endif
+
+    if (*T_CCS != NUL)	   /* cursor relative to region */
+	cursor_row = row;
+    else
+	cursor_row = row + off;
+
+    /*
+     * Shift LineOffset[] line_count down to reflect the inserted lines.
+     * Clear the inserted lines in ScreenLines[].
+     */
+    row += off;
+    end += off;
+    for (i = 0; i < line_count; ++i)
+    {
+#ifdef FEAT_VERTSPLIT
+	if (wp != NULL && wp->w_width != Columns)
+	{
+	    /* need to copy part of a line */
+	    j = end - 1 - i;
+	    while ((j -= line_count) >= row)
+		linecopy(j + line_count, j, wp);
+	    j += line_count;
+	    if (can_clear((char_u *)" "))
+		lineclear(LineOffset[j] + wp->w_wincol, wp->w_width);
+	    else
+		lineinvalid(LineOffset[j] + wp->w_wincol, wp->w_width);
+	    LineWraps[j] = FALSE;
+	}
+	else
+#endif
+	{
+	    j = end - 1 - i;
+	    temp = LineOffset[j];
+	    while ((j -= line_count) >= row)
+	    {
+		LineOffset[j + line_count] = LineOffset[j];
+		LineWraps[j + line_count] = LineWraps[j];
+	    }
+	    LineOffset[j + line_count] = temp;
+	    LineWraps[j + line_count] = FALSE;
+	    if (can_clear((char_u *)" "))
+		lineclear(temp, (int)Columns);
+	    else
+		lineinvalid(temp, (int)Columns);
+	}
+    }
+
+    screen_stop_highlight();
+    windgoto(cursor_row, 0);
+
+#ifdef FEAT_VERTSPLIT
+    /* redraw the characters */
+    if (type == USE_REDRAW)
+	redraw_block(row, end, wp);
+    else
+#endif
+	if (type == USE_T_CAL)
+    {
+	term_append_lines(line_count);
+	screen_start();		/* don't know where cursor is now */
+    }
+    else
+    {
+	for (i = 0; i < line_count; i++)
+	{
+	    if (type == USE_T_AL)
+	    {
+		if (i && cursor_row != 0)
+		    windgoto(cursor_row, 0);
+		out_str(T_AL);
+	    }
+	    else  /* type == USE_T_SR */
+		out_str(T_SR);
+	    screen_start();	    /* don't know where cursor is now */
+	}
+    }
+
+    /*
+     * With scroll-reverse and 'da' flag set we need to clear the lines that
+     * have been scrolled down into the region.
+     */
+    if (type == USE_T_SR && *T_DA)
+    {
+	for (i = 0; i < line_count; ++i)
+	{
+	    windgoto(off + i, 0);
+	    out_str(T_CE);
+	    screen_start();	    /* don't know where cursor is now */
+	}
+    }
+
+#ifdef FEAT_GUI
+    gui_can_update_cursor();
+    if (gui.in_use)
+	out_flush();	/* always flush after a scroll */
+#endif
+    return OK;
+}
+
+/*
+ * delete lines on the screen and update ScreenLines[]
+ * 'end' is the line after the scrolled part. Normally it is Rows.
+ * When scrolling region used 'off' is the offset from the top for the region.
+ * 'row' and 'end' are relative to the start of the region.
+ *
+ * Return OK for success, FAIL if the lines are not deleted.
+ */
+/*ARGSUSED*/
+    int
+screen_del_lines(off, row, line_count, end, force, wp)
+    int		off;
+    int		row;
+    int		line_count;
+    int		end;
+    int		force;		/* even when line_count > p_ttyscroll */
+    win_T	*wp;		/* NULL or window to use width from */
+{
+    int		j;
+    int		i;
+    unsigned	temp;
+    int		cursor_row;
+    int		cursor_end;
+    int		result_empty;	/* result is empty until end of region */
+    int		can_delete;	/* deleting line codes can be used */
+    int		type;
+
+    /*
+     * FAIL if
+     * - there is no valid screen
+     * - the screen has to be redrawn completely
+     * - the line count is less than one
+     * - the line count is more than 'ttyscroll'
+     */
+    if (!screen_valid(TRUE) || line_count <= 0 ||
+					 (!force && line_count > p_ttyscroll))
+	return FAIL;
+
+    /*
+     * Check if the rest of the current region will become empty.
+     */
+    result_empty = row + line_count >= end;
+
+    /*
+     * We can delete lines only when 'db' flag not set or when 'ce' option
+     * available.
+     */
+    can_delete = (*T_DB == NUL || can_clear(T_CE));
+
+    /*
+     * There are six ways to delete lines:
+     * 0. When in a vertically split window and t_CV isn't set, redraw the
+     *    characters from ScreenLines[].
+     * 1. Use T_CD if it exists and the result is empty.
+     * 2. Use newlines if row == 0 and count == 1 or T_CDL does not exist.
+     * 3. Use T_CDL (delete multiple lines) if it exists and line_count > 1 or
+     *	  none of the other ways work.
+     * 4. Use T_CE (erase line) if the result is empty.
+     * 5. Use T_DL (delete line) if it exists.
+     * 6. redraw the characters from ScreenLines[].
+     */
+#ifdef FEAT_VERTSPLIT
+    if (wp != NULL && wp->w_width != Columns && *T_CSV == NUL)
+	type = USE_REDRAW;
+    else
+#endif
+    if (can_clear(T_CD) && result_empty)
+	type = USE_T_CD;
+#if defined(__BEOS__) && defined(BEOS_DR8)
+    /*
+     * USE_NL does not seem to work in Terminal of DR8 so we set T_DB="" in
+     * its internal termcap... this works okay for tests which test *T_DB !=
+     * NUL.  It has the disadvantage that the user cannot use any :set t_*
+     * command to get T_DB (back) to empty_option, only :set term=... will do
+     * the trick...
+     * Anyway, this hack will hopefully go away with the next OS release.
+     * (Olaf Seibert)
+     */
+    else if (row == 0 && T_DB == empty_option
+					&& (line_count == 1 || *T_CDL == NUL))
+#else
+    else if (row == 0 && (
+#ifndef AMIGA
+	/* On the Amiga, somehow '\n' on the last line doesn't always scroll
+	 * up, so use delete-line command */
+			    line_count == 1 ||
+#endif
+						*T_CDL == NUL))
+#endif
+	type = USE_NL;
+    else if (*T_CDL != NUL && line_count > 1 && can_delete)
+	type = USE_T_CDL;
+    else if (can_clear(T_CE) && result_empty
+#ifdef FEAT_VERTSPLIT
+	    && (wp == NULL || wp->w_width == Columns)
+#endif
+	    )
+	type = USE_T_CE;
+    else if (*T_DL != NUL && can_delete)
+	type = USE_T_DL;
+    else if (*T_CDL != NUL && can_delete)
+	type = USE_T_CDL;
+    else
+	return FAIL;
+
+#ifdef FEAT_CLIPBOARD
+    /* Remove a modeless selection when deleting lines halfway the screen or
+     * not the full width of the screen. */
+    if (off + row > 0
+# ifdef FEAT_VERTSPLIT
+	    || (wp != NULL && wp->w_width != Columns)
+# endif
+       )
+	clip_clear_selection();
+    else
+	clip_scroll_selection(line_count);
+#endif
+
+#ifdef FEAT_GUI
+    /* Don't update the GUI cursor here, ScreenLines[] is invalid until the
+     * scrolling is actually carried out. */
+    gui_dont_update_cursor();
+#endif
+
+    if (*T_CCS != NUL)	    /* cursor relative to region */
+    {
+	cursor_row = row;
+	cursor_end = end;
+    }
+    else
+    {
+	cursor_row = row + off;
+	cursor_end = end + off;
+    }
+
+    /*
+     * Now shift LineOffset[] line_count up to reflect the deleted lines.
+     * Clear the inserted lines in ScreenLines[].
+     */
+    row += off;
+    end += off;
+    for (i = 0; i < line_count; ++i)
+    {
+#ifdef FEAT_VERTSPLIT
+	if (wp != NULL && wp->w_width != Columns)
+	{
+	    /* need to copy part of a line */
+	    j = row + i;
+	    while ((j += line_count) <= end - 1)
+		linecopy(j - line_count, j, wp);
+	    j -= line_count;
+	    if (can_clear((char_u *)" "))
+		lineclear(LineOffset[j] + wp->w_wincol, wp->w_width);
+	    else
+		lineinvalid(LineOffset[j] + wp->w_wincol, wp->w_width);
+	    LineWraps[j] = FALSE;
+	}
+	else
+#endif
+	{
+	    /* whole width, moving the line pointers is faster */
+	    j = row + i;
+	    temp = LineOffset[j];
+	    while ((j += line_count) <= end - 1)
+	    {
+		LineOffset[j - line_count] = LineOffset[j];
+		LineWraps[j - line_count] = LineWraps[j];
+	    }
+	    LineOffset[j - line_count] = temp;
+	    LineWraps[j - line_count] = FALSE;
+	    if (can_clear((char_u *)" "))
+		lineclear(temp, (int)Columns);
+	    else
+		lineinvalid(temp, (int)Columns);
+	}
+    }
+
+    screen_stop_highlight();
+
+#ifdef FEAT_VERTSPLIT
+    /* redraw the characters */
+    if (type == USE_REDRAW)
+	redraw_block(row, end, wp);
+    else
+#endif
+	if (type == USE_T_CD)	/* delete the lines */
+    {
+	windgoto(cursor_row, 0);
+	out_str(T_CD);
+	screen_start();			/* don't know where cursor is now */
+    }
+    else if (type == USE_T_CDL)
+    {
+	windgoto(cursor_row, 0);
+	term_delete_lines(line_count);
+	screen_start();			/* don't know where cursor is now */
+    }
+    /*
+     * Deleting lines at top of the screen or scroll region: Just scroll
+     * the whole screen (scroll region) up by outputting newlines on the
+     * last line.
+     */
+    else if (type == USE_NL)
+    {
+	windgoto(cursor_end - 1, 0);
+	for (i = line_count; --i >= 0; )
+	    out_char('\n');		/* cursor will remain on same line */
+    }
+    else
+    {
+	for (i = line_count; --i >= 0; )
+	{
+	    if (type == USE_T_DL)
+	    {
+		windgoto(cursor_row, 0);
+		out_str(T_DL);		/* delete a line */
+	    }
+	    else /* type == USE_T_CE */
+	    {
+		windgoto(cursor_row + i, 0);
+		out_str(T_CE);		/* erase a line */
+	    }
+	    screen_start();		/* don't know where cursor is now */
+	}
+    }
+
+    /*
+     * If the 'db' flag is set, we need to clear the lines that have been
+     * scrolled up at the bottom of the region.
+     */
+    if (*T_DB && (type == USE_T_DL || type == USE_T_CDL))
+    {
+	for (i = line_count; i > 0; --i)
+	{
+	    windgoto(cursor_end - i, 0);
+	    out_str(T_CE);		/* erase a line */
+	    screen_start();		/* don't know where cursor is now */
+	}
+    }
+
+#ifdef FEAT_GUI
+    gui_can_update_cursor();
+    if (gui.in_use)
+	out_flush();	/* always flush after a scroll */
+#endif
+
+    return OK;
+}
+
+/*
+ * show the current mode and ruler
+ *
+ * If clear_cmdline is TRUE, clear the rest of the cmdline.
+ * If clear_cmdline is FALSE there may be a message there that needs to be
+ * cleared only if a mode is shown.
+ * Return the length of the message (0 if no message).
+ */
+    int
+showmode()
+{
+    int		need_clear;
+    int		length = 0;
+    int		do_mode;
+    int		attr;
+    int		nwr_save;
+#ifdef FEAT_INS_EXPAND
+    int		sub_attr;
+#endif
+
+    do_mode = ((p_smd && msg_silent == 0)
+	    && ((State & INSERT)
+		|| restart_edit
+#ifdef FEAT_VISUAL
+		|| VIsual_active
+#endif
+		));
+    if (do_mode || Recording)
+    {
+	/*
+	 * Don't show mode right now, when not redrawing or inside a mapping.
+	 * Call char_avail() only when we are going to show something, because
+	 * it takes a bit of time.
+	 */
+	if (!redrawing() || (char_avail() && !KeyTyped) || msg_silent != 0)
+	{
+	    redraw_cmdline = TRUE;		/* show mode later */
+	    return 0;
+	}
+
+	nwr_save = need_wait_return;
+
+	/* wait a bit before overwriting an important message */
+	check_for_delay(FALSE);
+
+	/* if the cmdline is more than one line high, erase top lines */
+	need_clear = clear_cmdline;
+	if (clear_cmdline && cmdline_row < Rows - 1)
+	    msg_clr_cmdline();			/* will reset clear_cmdline */
+
+	/* Position on the last line in the window, column 0 */
+	msg_pos_mode();
+	cursor_off();
+	attr = hl_attr(HLF_CM);			/* Highlight mode */
+	if (do_mode)
+	{
+	    MSG_PUTS_ATTR("--", attr);
+#if defined(FEAT_XIM)
+	    if (xic != NULL && im_get_status() && !p_imdisable
+					&& curbuf->b_p_iminsert == B_IMODE_IM)
+# ifdef HAVE_GTK2 /* most of the time, it's not XIM being used */
+		MSG_PUTS_ATTR(" IM", attr);
+# else
+		MSG_PUTS_ATTR(" XIM", attr);
+# endif
+#endif
+#if defined(FEAT_HANGULIN) && defined(FEAT_GUI)
+	    if (gui.in_use)
+	    {
+		if (hangul_input_state_get())
+		    MSG_PUTS_ATTR(" \307\321\261\333", attr);   /* HANGUL */
+	    }
+#endif
+#ifdef FEAT_INS_EXPAND
+	    if (edit_submode != NULL)		/* CTRL-X in Insert mode */
+	    {
+		/* These messages can get long, avoid a wrap in a narrow
+		 * window.  Prefer showing edit_submode_extra. */
+		length = (Rows - msg_row) * Columns - 3;
+		if (edit_submode_extra != NULL)
+		    length -= vim_strsize(edit_submode_extra);
+		if (length > 0)
+		{
+		    if (edit_submode_pre != NULL)
+			length -= vim_strsize(edit_submode_pre);
+		    if (length - vim_strsize(edit_submode) > 0)
+		    {
+			if (edit_submode_pre != NULL)
+			    msg_puts_attr(edit_submode_pre, attr);
+			msg_puts_attr(edit_submode, attr);
+		    }
+		    if (edit_submode_extra != NULL)
+		    {
+			MSG_PUTS_ATTR(" ", attr);  /* add a space in between */
+			if ((int)edit_submode_highl < (int)HLF_COUNT)
+			    sub_attr = hl_attr(edit_submode_highl);
+			else
+			    sub_attr = attr;
+			msg_puts_attr(edit_submode_extra, sub_attr);
+		    }
+		}
+		length = 0;
+	    }
+	    else
+#endif
+	    {
+#ifdef FEAT_VREPLACE
+		if (State & VREPLACE_FLAG)
+		    MSG_PUTS_ATTR(_(" VREPLACE"), attr);
+		else
+#endif
+		    if (State & REPLACE_FLAG)
+		    MSG_PUTS_ATTR(_(" REPLACE"), attr);
+		else if (State & INSERT)
+		{
+#ifdef FEAT_RIGHTLEFT
+		    if (p_ri)
+			MSG_PUTS_ATTR(_(" REVERSE"), attr);
+#endif
+		    MSG_PUTS_ATTR(_(" INSERT"), attr);
+		}
+		else if (restart_edit == 'I')
+		    MSG_PUTS_ATTR(_(" (insert)"), attr);
+		else if (restart_edit == 'R')
+		    MSG_PUTS_ATTR(_(" (replace)"), attr);
+		else if (restart_edit == 'V')
+		    MSG_PUTS_ATTR(_(" (vreplace)"), attr);
+#ifdef FEAT_RIGHTLEFT
+		if (p_hkmap)
+		    MSG_PUTS_ATTR(_(" Hebrew"), attr);
+# ifdef FEAT_FKMAP
+		if (p_fkmap)
+		    MSG_PUTS_ATTR(farsi_text_5, attr);
+# endif
+#endif
+#ifdef FEAT_KEYMAP
+		if (State & LANGMAP)
+		{
+# ifdef FEAT_ARABIC
+		    if (curwin->w_p_arab)
+			MSG_PUTS_ATTR(_(" Arabic"), attr);
+		    else
+# endif
+			MSG_PUTS_ATTR(_(" (lang)"), attr);
+		}
+#endif
+		if ((State & INSERT) && p_paste)
+		    MSG_PUTS_ATTR(_(" (paste)"), attr);
+
+#ifdef FEAT_VISUAL
+		if (VIsual_active)
+		{
+		    char *p;
+
+		    /* Don't concatenate separate words to avoid translation
+		     * problems. */
+		    switch ((VIsual_select ? 4 : 0)
+			    + (VIsual_mode == Ctrl_V) * 2
+			    + (VIsual_mode == 'V'))
+		    {
+			case 0:	p = N_(" VISUAL"); break;
+			case 1: p = N_(" VISUAL LINE"); break;
+			case 2: p = N_(" VISUAL BLOCK"); break;
+			case 4: p = N_(" SELECT"); break;
+			case 5: p = N_(" SELECT LINE"); break;
+			default: p = N_(" SELECT BLOCK"); break;
+		    }
+		    MSG_PUTS_ATTR(_(p), attr);
+		}
+#endif
+		MSG_PUTS_ATTR(" --", attr);
+	    }
+
+	    need_clear = TRUE;
+	}
+	if (Recording
+#ifdef FEAT_INS_EXPAND
+		&& edit_submode == NULL	    /* otherwise it gets too long */
+#endif
+		)
+	{
+	    MSG_PUTS_ATTR(_("recording"), attr);
+	    need_clear = TRUE;
+	}
+
+	mode_displayed = TRUE;
+	if (need_clear || clear_cmdline)
+	    msg_clr_eos();
+	msg_didout = FALSE;		/* overwrite this message */
+	length = msg_col;
+	msg_col = 0;
+	need_wait_return = nwr_save;	/* never ask for hit-return for this */
+    }
+    else if (clear_cmdline && msg_silent == 0)
+	/* Clear the whole command line.  Will reset "clear_cmdline". */
+	msg_clr_cmdline();
+
+#ifdef FEAT_CMDL_INFO
+# ifdef FEAT_VISUAL
+    /* In Visual mode the size of the selected area must be redrawn. */
+    if (VIsual_active)
+	clear_showcmd();
+# endif
+
+    /* If the last window has no status line, the ruler is after the mode
+     * message and must be redrawn */
+    if (redrawing()
+# ifdef FEAT_WINDOWS
+	    && lastwin->w_status_height == 0
+# endif
+       )
+	win_redr_ruler(lastwin, TRUE);
+#endif
+    redraw_cmdline = FALSE;
+    clear_cmdline = FALSE;
+
+    return length;
+}
+
+/*
+ * Position for a mode message.
+ */
+    static void
+msg_pos_mode()
+{
+    msg_col = 0;
+    msg_row = Rows - 1;
+}
+
+/*
+ * Delete mode message.  Used when ESC is typed which is expected to end
+ * Insert mode (but Insert mode didn't end yet!).
+ * Caller should check "mode_displayed".
+ */
+    void
+unshowmode(force)
+    int	    force;
+{
+    /*
+     * Don't delete it right now, when not redrawing or insided a mapping.
+     */
+    if (!redrawing() || (!force && char_avail() && !KeyTyped))
+	redraw_cmdline = TRUE;		/* delete mode later */
+    else
+    {
+	msg_pos_mode();
+	if (Recording)
+	    MSG_PUTS_ATTR(_("recording"), hl_attr(HLF_CM));
+	msg_clr_eos();
+    }
+}
+
+#if defined(FEAT_WINDOWS)
+/*
+ * Draw the tab pages line at the top of the Vim window.
+ */
+    static void
+draw_tabline()
+{
+    int		tabcount = 0;
+    tabpage_T	*tp;
+    int		tabwidth;
+    int		col = 0;
+    int		scol = 0;
+    int		attr;
+    win_T	*wp;
+    win_T	*cwp;
+    int		wincount;
+    int		modified;
+    int		c;
+    int		len;
+    int		attr_sel = hl_attr(HLF_TPS);
+    int		attr_nosel = hl_attr(HLF_TP);
+    int		attr_fill = hl_attr(HLF_TPF);
+    char_u	*p;
+    int		room;
+    int		use_sep_chars = (t_colors < 8
+#ifdef FEAT_GUI
+					    && !gui.in_use
+#endif
+					    );
+
+    redraw_tabline = FALSE;
+
+#ifdef FEAT_GUI_TABLINE
+    /* Take care of a GUI tabline. */
+    if (gui_use_tabline())
+    {
+	gui_update_tabline();
+	return;
+    }
+#endif
+
+    if (tabline_height() < 1)
+	return;
+
+#if defined(FEAT_STL_OPT)
+
+    /* Init TabPageIdxs[] to zero: Clicking outside of tabs has no effect. */
+    for (scol = 0; scol < Columns; ++scol)
+	TabPageIdxs[scol] = 0;
+
+    /* Use the 'tabline' option if it's set. */
+    if (*p_tal != NUL)
+    {
+	int	save_called_emsg = called_emsg;
+
+	/* Check for an error.  If there is one we would loop in redrawing the
+	 * screen.  Avoid that by making 'tabline' empty. */
+	called_emsg = FALSE;
+	win_redr_custom(NULL, FALSE);
+	if (called_emsg)
+	    set_string_option_direct((char_u *)"tabline", -1,
+					   (char_u *)"", OPT_FREE, SID_ERROR);
+	called_emsg |= save_called_emsg;
+    }
+    else
+#endif
+    {
+	for (tp = first_tabpage; tp != NULL; tp = tp->tp_next)
+	    ++tabcount;
+
+	tabwidth = (Columns - 1 + tabcount / 2) / tabcount;
+	if (tabwidth < 6)
+	    tabwidth = 6;
+
+	attr = attr_nosel;
+	tabcount = 0;
+	scol = 0;
+	for (tp = first_tabpage; tp != NULL && col < Columns - 4;
+							     tp = tp->tp_next)
+	{
+	    scol = col;
+
+	    if (tp->tp_topframe == topframe)
+		attr = attr_sel;
+	    if (use_sep_chars && col > 0)
+		screen_putchar('|', 0, col++, attr);
+
+	    if (tp->tp_topframe != topframe)
+		attr = attr_nosel;
+
+	    screen_putchar(' ', 0, col++, attr);
+
+	    if (tp == curtab)
+	    {
+		cwp = curwin;
+		wp = firstwin;
+	    }
+	    else
+	    {
+		cwp = tp->tp_curwin;
+		wp = tp->tp_firstwin;
+	    }
+
+	    modified = FALSE;
+	    for (wincount = 0; wp != NULL; wp = wp->w_next, ++wincount)
+		if (bufIsChanged(wp->w_buffer))
+		    modified = TRUE;
+	    if (modified || wincount > 1)
+	    {
+		if (wincount > 1)
+		{
+		    vim_snprintf((char *)NameBuff, MAXPATHL, "%d", wincount);
+		    len = (int)STRLEN(NameBuff);
+		    if (col + len >= Columns - 3)
+			break;
+		    screen_puts_len(NameBuff, len, 0, col,
+#if defined(FEAT_SYN_HL)
+					   hl_combine_attr(attr, hl_attr(HLF_T))
+#else
+					   attr
+#endif
+					       );
+		    col += len;
+		}
+		if (modified)
+		    screen_puts_len((char_u *)"+", 1, 0, col++, attr);
+		screen_putchar(' ', 0, col++, attr);
+	    }
+
+	    room = scol - col + tabwidth - 1;
+	    if (room > 0)
+	    {
+		/* Get buffer name in NameBuff[] */
+		get_trans_bufname(cwp->w_buffer);
+		shorten_dir(NameBuff);
+		len = vim_strsize(NameBuff);
+		p = NameBuff;
+#ifdef FEAT_MBYTE
+		if (has_mbyte)
+		    while (len > room)
+		    {
+			len -= ptr2cells(p);
+			mb_ptr_adv(p);
+		    }
+		else
+#endif
+		    if (len > room)
+		{
+		    p += len - room;
+		    len = room;
+		}
+		if (len > Columns - col - 1)
+		    len = Columns - col - 1;
+
+		screen_puts_len(p, (int)STRLEN(p), 0, col, attr);
+		col += len;
+	    }
+	    screen_putchar(' ', 0, col++, attr);
+
+	    /* Store the tab page number in TabPageIdxs[], so that
+	     * jump_to_mouse() knows where each one is. */
+	    ++tabcount;
+	    while (scol < col)
+		TabPageIdxs[scol++] = tabcount;
+	}
+
+	if (use_sep_chars)
+	    c = '_';
+	else
+	    c = ' ';
+	screen_fill(0, 1, col, (int)Columns, c, c, attr_fill);
+
+	/* Put an "X" for closing the current tab if there are several. */
+	if (first_tabpage->tp_next != NULL)
+	{
+	    screen_putchar('X', 0, (int)Columns - 1, attr_nosel);
+	    TabPageIdxs[Columns - 1] = -999;
+	}
+    }
+
+    /* Reset the flag here again, in case evaluating 'tabline' causes it to be
+     * set. */
+    redraw_tabline = FALSE;
+}
+
+/*
+ * Get buffer name for "buf" into NameBuff[].
+ * Takes care of special buffer names and translates special characters.
+ */
+    void
+get_trans_bufname(buf)
+    buf_T	*buf;
+{
+    if (buf_spname(buf) != NULL)
+	STRCPY(NameBuff, buf_spname(buf));
+    else
+	home_replace(buf, buf->b_fname, NameBuff, MAXPATHL, TRUE);
+    trans_characters(NameBuff, MAXPATHL);
+}
+#endif
+
+#if defined(FEAT_WINDOWS) || defined(FEAT_WILDMENU) || defined(FEAT_STL_OPT)
+/*
+ * Get the character to use in a status line.  Get its attributes in "*attr".
+ */
+    static int
+fillchar_status(attr, is_curwin)
+    int		*attr;
+    int		is_curwin;
+{
+    int fill;
+    if (is_curwin)
+    {
+	*attr = hl_attr(HLF_S);
+	fill = fill_stl;
+    }
+    else
+    {
+	*attr = hl_attr(HLF_SNC);
+	fill = fill_stlnc;
+    }
+    /* Use fill when there is highlighting, and highlighting of current
+     * window differs, or the fillchars differ, or this is not the
+     * current window */
+    if (*attr != 0 && ((hl_attr(HLF_S) != hl_attr(HLF_SNC)
+			|| !is_curwin || firstwin == lastwin)
+		    || (fill_stl != fill_stlnc)))
+	return fill;
+    if (is_curwin)
+	return '^';
+    return '=';
+}
+#endif
+
+#ifdef FEAT_VERTSPLIT
+/*
+ * Get the character to use in a separator between vertically split windows.
+ * Get its attributes in "*attr".
+ */
+    static int
+fillchar_vsep(attr)
+    int	    *attr;
+{
+    *attr = hl_attr(HLF_C);
+    if (*attr == 0 && fill_vert == ' ')
+	return '|';
+    else
+	return fill_vert;
+}
+#endif
+
+/*
+ * Return TRUE if redrawing should currently be done.
+ */
+    int
+redrawing()
+{
+    return (!RedrawingDisabled
+		       && !(p_lz && char_avail() && !KeyTyped && !do_redraw));
+}
+
+/*
+ * Return TRUE if printing messages should currently be done.
+ */
+    int
+messaging()
+{
+    return (!(p_lz && char_avail() && !KeyTyped));
+}
+
+/*
+ * Show current status info in ruler and various other places
+ * If always is FALSE, only show ruler if position has changed.
+ */
+    void
+showruler(always)
+    int	    always;
+{
+    if (!always && !redrawing())
+	return;
+#ifdef FEAT_INS_EXPAND
+    if (pum_visible())
+    {
+# ifdef FEAT_WINDOWS
+	/* Don't redraw right now, do it later. */
+	curwin->w_redr_status = TRUE;
+# endif
+	return;
+    }
+#endif
+#if defined(FEAT_STL_OPT) && defined(FEAT_WINDOWS)
+    if ((*p_stl != NUL || *curwin->w_p_stl != NUL) && curwin->w_status_height)
+    {
+	redraw_custum_statusline(curwin);
+    }
+    else
+#endif
+#ifdef FEAT_CMDL_INFO
+	win_redr_ruler(curwin, always);
+#endif
+
+#ifdef FEAT_TITLE
+    if (need_maketitle
+# ifdef FEAT_STL_OPT
+	    || (p_icon && (stl_syntax & STL_IN_ICON))
+	    || (p_title && (stl_syntax & STL_IN_TITLE))
+# endif
+       )
+	maketitle();
+#endif
+}
+
+#ifdef FEAT_CMDL_INFO
+    static void
+win_redr_ruler(wp, always)
+    win_T	*wp;
+    int		always;
+{
+    char_u	buffer[70];
+    int		row;
+    int		fillchar;
+    int		attr;
+    int		empty_line = FALSE;
+    colnr_T	virtcol;
+    int		i;
+    int		o;
+#ifdef FEAT_VERTSPLIT
+    int		this_ru_col;
+    int		off = 0;
+    int		width = Columns;
+# define WITH_OFF(x) x
+# define WITH_WIDTH(x) x
+#else
+# define WITH_OFF(x) 0
+# define WITH_WIDTH(x) Columns
+# define this_ru_col ru_col
+#endif
+
+    /* If 'ruler' off or redrawing disabled, don't do anything */
+    if (!p_ru)
+	return;
+
+    /*
+     * Check if cursor.lnum is valid, since win_redr_ruler() may be called
+     * after deleting lines, before cursor.lnum is corrected.
+     */
+    if (wp->w_cursor.lnum > wp->w_buffer->b_ml.ml_line_count)
+	return;
+
+#ifdef FEAT_INS_EXPAND
+    /* Don't draw the ruler while doing insert-completion, it might overwrite
+     * the (long) mode message. */
+# ifdef FEAT_WINDOWS
+    if (wp == lastwin && lastwin->w_status_height == 0)
+# endif
+	if (edit_submode != NULL)
+	    return;
+    /* Don't draw the ruler when the popup menu is visible, it may overlap. */
+    if (pum_visible())
+	return;
+#endif
+
+#ifdef FEAT_STL_OPT
+    if (*p_ruf)
+    {
+	int	save_called_emsg = called_emsg;
+
+	called_emsg = FALSE;
+	win_redr_custom(wp, TRUE);
+	if (called_emsg)
+	    set_string_option_direct((char_u *)"rulerformat", -1,
+					   (char_u *)"", OPT_FREE, SID_ERROR);
+	called_emsg |= save_called_emsg;
+	return;
+    }
+#endif
+
+    /*
+     * Check if not in Insert mode and the line is empty (will show "0-1").
+     */
+    if (!(State & INSERT)
+		&& *ml_get_buf(wp->w_buffer, wp->w_cursor.lnum, FALSE) == NUL)
+	empty_line = TRUE;
+
+    /*
+     * Only draw the ruler when something changed.
+     */
+    validate_virtcol_win(wp);
+    if (       redraw_cmdline
+	    || always
+	    || wp->w_cursor.lnum != wp->w_ru_cursor.lnum
+	    || wp->w_cursor.col != wp->w_ru_cursor.col
+	    || wp->w_virtcol != wp->w_ru_virtcol
+#ifdef FEAT_VIRTUALEDIT
+	    || wp->w_cursor.coladd != wp->w_ru_cursor.coladd
+#endif
+	    || wp->w_topline != wp->w_ru_topline
+	    || wp->w_buffer->b_ml.ml_line_count != wp->w_ru_line_count
+#ifdef FEAT_DIFF
+	    || wp->w_topfill != wp->w_ru_topfill
+#endif
+	    || empty_line != wp->w_ru_empty)
+    {
+	cursor_off();
+#ifdef FEAT_WINDOWS
+	if (wp->w_status_height)
+	{
+	    row = W_WINROW(wp) + wp->w_height;
+	    fillchar = fillchar_status(&attr, wp == curwin);
+# ifdef FEAT_VERTSPLIT
+	    off = W_WINCOL(wp);
+	    width = W_WIDTH(wp);
+# endif
+	}
+	else
+#endif
+	{
+	    row = Rows - 1;
+	    fillchar = ' ';
+	    attr = 0;
+#ifdef FEAT_VERTSPLIT
+	    width = Columns;
+	    off = 0;
+#endif
+	}
+
+	/* In list mode virtcol needs to be recomputed */
+	virtcol = wp->w_virtcol;
+	if (wp->w_p_list && lcs_tab1 == NUL)
+	{
+	    wp->w_p_list = FALSE;
+	    getvvcol(wp, &wp->w_cursor, NULL, &virtcol, NULL);
+	    wp->w_p_list = TRUE;
+	}
+
+	/*
+	 * Some sprintfs return the length, some return a pointer.
+	 * To avoid portability problems we use strlen() here.
+	 */
+	sprintf((char *)buffer, "%ld,",
+		(wp->w_buffer->b_ml.ml_flags & ML_EMPTY)
+		    ? 0L
+		    : (long)(wp->w_cursor.lnum));
+	col_print(buffer + STRLEN(buffer),
+			empty_line ? 0 : (int)wp->w_cursor.col + 1,
+			(int)virtcol + 1);
+
+	/*
+	 * Add a "50%" if there is room for it.
+	 * On the last line, don't print in the last column (scrolls the
+	 * screen up on some terminals).
+	 */
+	i = (int)STRLEN(buffer);
+	get_rel_pos(wp, buffer + i + 1);
+	o = i + vim_strsize(buffer + i + 1);
+#ifdef FEAT_WINDOWS
+	if (wp->w_status_height == 0)	/* can't use last char of screen */
+#endif
+	    ++o;
+#ifdef FEAT_VERTSPLIT
+	this_ru_col = ru_col - (Columns - width);
+	if (this_ru_col < 0)
+	    this_ru_col = 0;
+#endif
+	/* Never use more than half the window/screen width, leave the other
+	 * half for the filename. */
+	if (this_ru_col < (WITH_WIDTH(width) + 1) / 2)
+	    this_ru_col = (WITH_WIDTH(width) + 1) / 2;
+	if (this_ru_col + o < WITH_WIDTH(width))
+	{
+	    while (this_ru_col + o < WITH_WIDTH(width))
+	    {
+#ifdef FEAT_MBYTE
+		if (has_mbyte)
+		    i += (*mb_char2bytes)(fillchar, buffer + i);
+		else
+#endif
+		    buffer[i++] = fillchar;
+		++o;
+	    }
+	    get_rel_pos(wp, buffer + i);
+	}
+	/* Truncate at window boundary. */
+#ifdef FEAT_MBYTE
+	if (has_mbyte)
+	{
+	    o = 0;
+	    for (i = 0; buffer[i] != NUL; i += (*mb_ptr2len)(buffer + i))
+	    {
+		o += (*mb_ptr2cells)(buffer + i);
+		if (this_ru_col + o > WITH_WIDTH(width))
+		{
+		    buffer[i] = NUL;
+		    break;
+		}
+	    }
+	}
+	else
+#endif
+	if (this_ru_col + (int)STRLEN(buffer) > WITH_WIDTH(width))
+	    buffer[WITH_WIDTH(width) - this_ru_col] = NUL;
+
+	screen_puts(buffer, row, this_ru_col + WITH_OFF(off), attr);
+	i = redraw_cmdline;
+	screen_fill(row, row + 1,
+		this_ru_col + WITH_OFF(off) + (int)STRLEN(buffer),
+		(int)(WITH_OFF(off) + WITH_WIDTH(width)),
+		fillchar, fillchar, attr);
+	/* don't redraw the cmdline because of showing the ruler */
+	redraw_cmdline = i;
+	wp->w_ru_cursor = wp->w_cursor;
+	wp->w_ru_virtcol = wp->w_virtcol;
+	wp->w_ru_empty = empty_line;
+	wp->w_ru_topline = wp->w_topline;
+	wp->w_ru_line_count = wp->w_buffer->b_ml.ml_line_count;
+#ifdef FEAT_DIFF
+	wp->w_ru_topfill = wp->w_topfill;
+#endif
+    }
+}
+#endif
+
+#if defined(FEAT_LINEBREAK) || defined(PROTO)
+/*
+ * Return the width of the 'number' column.
+ * Caller may need to check if 'number' is set.
+ * Otherwise it depends on 'numberwidth' and the line count.
+ */
+    int
+number_width(wp)
+    win_T	*wp;
+{
+    int		n;
+    linenr_T	lnum;
+
+    lnum = wp->w_buffer->b_ml.ml_line_count;
+    if (lnum == wp->w_nrwidth_line_count)
+	return wp->w_nrwidth_width;
+    wp->w_nrwidth_line_count = lnum;
+
+    n = 0;
+    do
+    {
+	lnum /= 10;
+	++n;
+    } while (lnum > 0);
+
+    /* 'numberwidth' gives the minimal width plus one */
+    if (n < wp->w_p_nuw - 1)
+	n = wp->w_p_nuw - 1;
+
+    wp->w_nrwidth_width = n;
+    return n;
+}
+#endif
--- /dev/null
+++ b/search.c
@@ -1,0 +1,5296 @@
+/* vi:set ts=8 sts=4 sw=4:
+ *
+ * VIM - Vi IMproved	by Bram Moolenaar
+ *
+ * Do ":help uganda"  in Vim to read copying and usage conditions.
+ * Do ":help credits" in Vim to see a list of people who contributed.
+ * See README.txt for an overview of the Vim source code.
+ */
+/*
+ * search.c: code for normal mode searching commands
+ */
+
+#include "vim.h"
+
+static void save_re_pat __ARGS((int idx, char_u *pat, int magic));
+#ifdef FEAT_EVAL
+static int first_submatch __ARGS((regmmatch_T *rp));
+#endif
+static int check_prevcol __ARGS((char_u *linep, int col, int ch, int *prevcol));
+static int inmacro __ARGS((char_u *, char_u *));
+static int check_linecomment __ARGS((char_u *line));
+static int cls __ARGS((void));
+static int skip_chars __ARGS((int, int));
+#ifdef FEAT_TEXTOBJ
+static void back_in_line __ARGS((void));
+static void find_first_blank __ARGS((pos_T *));
+static void findsent_forward __ARGS((long count, int at_start_sent));
+#endif
+#ifdef FEAT_FIND_ID
+static void show_pat_in_path __ARGS((char_u *, int,
+					 int, int, FILE *, linenr_T *, long));
+#endif
+#ifdef FEAT_VIMINFO
+static void wvsp_one __ARGS((FILE *fp, int idx, char *s, int sc));
+#endif
+
+/*
+ * This file contains various searching-related routines. These fall into
+ * three groups:
+ * 1. string searches (for /, ?, n, and N)
+ * 2. character searches within a single line (for f, F, t, T, etc)
+ * 3. "other" kinds of searches like the '%' command, and 'word' searches.
+ */
+
+/*
+ * String searches
+ *
+ * The string search functions are divided into two levels:
+ * lowest:  searchit(); uses an pos_T for starting position and found match.
+ * Highest: do_search(); uses curwin->w_cursor; calls searchit().
+ *
+ * The last search pattern is remembered for repeating the same search.
+ * This pattern is shared between the :g, :s, ? and / commands.
+ * This is in search_regcomp().
+ *
+ * The actual string matching is done using a heavily modified version of
+ * Henry Spencer's regular expression library.  See regexp.c.
+ */
+
+/* The offset for a search command is store in a soff struct */
+/* Note: only spats[0].off is really used */
+struct soffset
+{
+    int		dir;		/* search direction */
+    int		line;		/* search has line offset */
+    int		end;		/* search set cursor at end */
+    long	off;		/* line or char offset */
+};
+
+/* A search pattern and its attributes are stored in a spat struct */
+struct spat
+{
+    char_u	    *pat;	/* the pattern (in allocated memory) or NULL */
+    int		    magic;	/* magicness of the pattern */
+    int		    no_scs;	/* no smarcase for this pattern */
+    struct soffset  off;
+};
+
+/*
+ * Two search patterns are remembered: One for the :substitute command and
+ * one for other searches.  last_idx points to the one that was used the last
+ * time.
+ */
+static struct spat spats[2] =
+{
+    {NULL, TRUE, FALSE, {'/', 0, 0, 0L}},	/* last used search pat */
+    {NULL, TRUE, FALSE, {'/', 0, 0, 0L}}	/* last used substitute pat */
+};
+
+static int last_idx = 0;	/* index in spats[] for RE_LAST */
+
+#if defined(FEAT_AUTOCMD) || defined(FEAT_EVAL) || defined(PROTO)
+/* copy of spats[], for keeping the search patterns while executing autocmds */
+static struct spat  saved_spats[2];
+static int	    saved_last_idx = 0;
+# ifdef FEAT_SEARCH_EXTRA
+static int	    saved_no_hlsearch = 0;
+# endif
+#endif
+
+static char_u	    *mr_pattern = NULL;	/* pattern used by search_regcomp() */
+#ifdef FEAT_RIGHTLEFT
+static int	    mr_pattern_alloced = FALSE; /* mr_pattern was allocated */
+static char_u	    *reverse_text __ARGS((char_u *s));
+#endif
+
+#ifdef FEAT_FIND_ID
+/*
+ * Type used by find_pattern_in_path() to remember which included files have
+ * been searched already.
+ */
+typedef struct SearchedFile
+{
+    FILE	*fp;		/* File pointer */
+    char_u	*name;		/* Full name of file */
+    linenr_T	lnum;		/* Line we were up to in file */
+    int		matched;	/* Found a match in this file */
+} SearchedFile;
+#endif
+
+/*
+ * translate search pattern for vim_regcomp()
+ *
+ * pat_save == RE_SEARCH: save pat in spats[RE_SEARCH].pat (normal search cmd)
+ * pat_save == RE_SUBST: save pat in spats[RE_SUBST].pat (:substitute command)
+ * pat_save == RE_BOTH: save pat in both patterns (:global command)
+ * pat_use  == RE_SEARCH: use previous search pattern if "pat" is NULL
+ * pat_use  == RE_SUBST: use previous substitute pattern if "pat" is NULL
+ * pat_use  == RE_LAST: use last used pattern if "pat" is NULL
+ * options & SEARCH_HIS: put search string in history
+ * options & SEARCH_KEEP: keep previous search pattern
+ *
+ * returns FAIL if failed, OK otherwise.
+ */
+    int
+search_regcomp(pat, pat_save, pat_use, options, regmatch)
+    char_u	*pat;
+    int		pat_save;
+    int		pat_use;
+    int		options;
+    regmmatch_T	*regmatch;	/* return: pattern and ignore-case flag */
+{
+    int		magic;
+    int		i;
+
+    rc_did_emsg = FALSE;
+    magic = p_magic;
+
+    /*
+     * If no pattern given, use a previously defined pattern.
+     */
+    if (pat == NULL || *pat == NUL)
+    {
+	if (pat_use == RE_LAST)
+	    i = last_idx;
+	else
+	    i = pat_use;
+	if (spats[i].pat == NULL)	/* pattern was never defined */
+	{
+	    if (pat_use == RE_SUBST)
+		EMSG(_(e_nopresub));
+	    else
+		EMSG(_(e_noprevre));
+	    rc_did_emsg = TRUE;
+	    return FAIL;
+	}
+	pat = spats[i].pat;
+	magic = spats[i].magic;
+	no_smartcase = spats[i].no_scs;
+    }
+#ifdef FEAT_CMDHIST
+    else if (options & SEARCH_HIS)	/* put new pattern in history */
+	add_to_history(HIST_SEARCH, pat, TRUE, NUL);
+#endif
+
+#ifdef FEAT_RIGHTLEFT
+    if (mr_pattern_alloced)
+    {
+	vim_free(mr_pattern);
+	mr_pattern_alloced = FALSE;
+    }
+
+    if (curwin->w_p_rl && *curwin->w_p_rlc == 's')
+    {
+	char_u *rev_pattern;
+
+	rev_pattern = reverse_text(pat);
+	if (rev_pattern == NULL)
+	    mr_pattern = pat;	    /* out of memory, keep normal pattern. */
+	else
+	{
+	    mr_pattern = rev_pattern;
+	    mr_pattern_alloced = TRUE;
+	}
+    }
+    else
+#endif
+	mr_pattern = pat;
+
+    /*
+     * Save the currently used pattern in the appropriate place,
+     * unless the pattern should not be remembered.
+     */
+    if (!(options & SEARCH_KEEP))
+    {
+	/* search or global command */
+	if (pat_save == RE_SEARCH || pat_save == RE_BOTH)
+	    save_re_pat(RE_SEARCH, pat, magic);
+	/* substitute or global command */
+	if (pat_save == RE_SUBST || pat_save == RE_BOTH)
+	    save_re_pat(RE_SUBST, pat, magic);
+    }
+
+    regmatch->rmm_ic = ignorecase(pat);
+    regmatch->rmm_maxcol = 0;
+    regmatch->regprog = vim_regcomp(pat, magic ? RE_MAGIC : 0);
+    if (regmatch->regprog == NULL)
+	return FAIL;
+    return OK;
+}
+
+/*
+ * Get search pattern used by search_regcomp().
+ */
+    char_u *
+get_search_pat()
+{
+    return mr_pattern;
+}
+
+#ifdef FEAT_RIGHTLEFT
+/*
+ * Reverse text into allocated memory.
+ * Returns the allocated string, NULL when out of memory.
+ */
+    static char_u *
+reverse_text(s)
+    char_u *s;
+{
+    unsigned	len;
+    unsigned	s_i, rev_i;
+    char_u	*rev;
+
+    /*
+     * Reverse the pattern.
+     */
+    len = (unsigned)STRLEN(s);
+    rev = alloc(len + 1);
+    if (rev != NULL)
+    {
+	rev_i = len;
+	for (s_i = 0; s_i < len; ++s_i)
+	{
+# ifdef FEAT_MBYTE
+	    if (has_mbyte)
+	    {
+		int	mb_len;
+
+		mb_len = (*mb_ptr2len)(s + s_i);
+		rev_i -= mb_len;
+		mch_memmove(rev + rev_i, s + s_i, mb_len);
+		s_i += mb_len - 1;
+	    }
+	    else
+# endif
+		rev[--rev_i] = s[s_i];
+
+	}
+	rev[len] = NUL;
+    }
+    return rev;
+}
+#endif
+
+    static void
+save_re_pat(idx, pat, magic)
+    int		idx;
+    char_u	*pat;
+    int		magic;
+{
+    if (spats[idx].pat != pat)
+    {
+	vim_free(spats[idx].pat);
+	spats[idx].pat = vim_strsave(pat);
+	spats[idx].magic = magic;
+	spats[idx].no_scs = no_smartcase;
+	last_idx = idx;
+#ifdef FEAT_SEARCH_EXTRA
+	/* If 'hlsearch' set and search pat changed: need redraw. */
+	if (p_hls)
+	    redraw_all_later(SOME_VALID);
+	no_hlsearch = FALSE;
+#endif
+    }
+}
+
+#if defined(FEAT_AUTOCMD) || defined(FEAT_EVAL) || defined(PROTO)
+/*
+ * Save the search patterns, so they can be restored later.
+ * Used before/after executing autocommands and user functions.
+ */
+static int save_level = 0;
+
+    void
+save_search_patterns()
+{
+    if (save_level++ == 0)
+    {
+	saved_spats[0] = spats[0];
+	if (spats[0].pat != NULL)
+	    saved_spats[0].pat = vim_strsave(spats[0].pat);
+	saved_spats[1] = spats[1];
+	if (spats[1].pat != NULL)
+	    saved_spats[1].pat = vim_strsave(spats[1].pat);
+	saved_last_idx = last_idx;
+# ifdef FEAT_SEARCH_EXTRA
+	saved_no_hlsearch = no_hlsearch;
+# endif
+    }
+}
+
+    void
+restore_search_patterns()
+{
+    if (--save_level == 0)
+    {
+	vim_free(spats[0].pat);
+	spats[0] = saved_spats[0];
+	vim_free(spats[1].pat);
+	spats[1] = saved_spats[1];
+	last_idx = saved_last_idx;
+# ifdef FEAT_SEARCH_EXTRA
+	no_hlsearch = saved_no_hlsearch;
+# endif
+    }
+}
+#endif
+
+#if defined(EXITFREE) || defined(PROTO)
+    void
+free_search_patterns()
+{
+    vim_free(spats[0].pat);
+    vim_free(spats[1].pat);
+}
+#endif
+
+/*
+ * Return TRUE when case should be ignored for search pattern "pat".
+ * Uses the 'ignorecase' and 'smartcase' options.
+ */
+    int
+ignorecase(pat)
+    char_u	*pat;
+{
+    char_u	*p;
+    int		ic;
+
+    ic = p_ic;
+    if (ic && !no_smartcase && p_scs
+#ifdef FEAT_INS_EXPAND
+				&& !(ctrl_x_mode && curbuf->b_p_inf)
+#endif
+								    )
+    {
+	/* don't ignore case if pattern has uppercase */
+	for (p = pat; *p; )
+	{
+#ifdef FEAT_MBYTE
+	    int		l;
+
+	    if (has_mbyte && (l = (*mb_ptr2len)(p)) > 1)
+	    {
+		if (enc_utf8 && utf_isupper(utf_ptr2char(p)))
+		{
+		    ic = FALSE;
+		    break;
+		}
+		p += l;
+	    }
+	    else
+#endif
+		if (*p == '\\' && p[1] != NUL)	/* skip "\S" et al. */
+		    p += 2;
+		else if (isupper(*p))
+		{
+		    ic = FALSE;
+		    break;
+		}
+		else
+		    ++p;
+	}
+    }
+    no_smartcase = FALSE;
+
+    return ic;
+}
+
+    char_u *
+last_search_pat()
+{
+    return spats[last_idx].pat;
+}
+
+/*
+ * Reset search direction to forward.  For "gd" and "gD" commands.
+ */
+    void
+reset_search_dir()
+{
+    spats[0].off.dir = '/';
+}
+
+#if defined(FEAT_EVAL) || defined(FEAT_VIMINFO)
+/*
+ * Set the last search pattern.  For ":let @/ =" and viminfo.
+ * Also set the saved search pattern, so that this works in an autocommand.
+ */
+    void
+set_last_search_pat(s, idx, magic, setlast)
+    char_u	*s;
+    int		idx;
+    int		magic;
+    int		setlast;
+{
+    vim_free(spats[idx].pat);
+    /* An empty string means that nothing should be matched. */
+    if (*s == NUL)
+	spats[idx].pat = NULL;
+    else
+	spats[idx].pat = vim_strsave(s);
+    spats[idx].magic = magic;
+    spats[idx].no_scs = FALSE;
+    spats[idx].off.dir = '/';
+    spats[idx].off.line = FALSE;
+    spats[idx].off.end = FALSE;
+    spats[idx].off.off = 0;
+    if (setlast)
+	last_idx = idx;
+    if (save_level)
+    {
+	vim_free(saved_spats[idx].pat);
+	saved_spats[idx] = spats[0];
+	if (spats[idx].pat == NULL)
+	    saved_spats[idx].pat = NULL;
+	else
+	    saved_spats[idx].pat = vim_strsave(spats[idx].pat);
+	saved_last_idx = last_idx;
+    }
+# ifdef FEAT_SEARCH_EXTRA
+    /* If 'hlsearch' set and search pat changed: need redraw. */
+    if (p_hls && idx == last_idx && !no_hlsearch)
+	redraw_all_later(SOME_VALID);
+# endif
+}
+#endif
+
+#ifdef FEAT_SEARCH_EXTRA
+/*
+ * Get a regexp program for the last used search pattern.
+ * This is used for highlighting all matches in a window.
+ * Values returned in regmatch->regprog and regmatch->rmm_ic.
+ */
+    void
+last_pat_prog(regmatch)
+    regmmatch_T	*regmatch;
+{
+    if (spats[last_idx].pat == NULL)
+    {
+	regmatch->regprog = NULL;
+	return;
+    }
+    ++emsg_off;		/* So it doesn't beep if bad expr */
+    (void)search_regcomp((char_u *)"", 0, last_idx, SEARCH_KEEP, regmatch);
+    --emsg_off;
+}
+#endif
+
+/*
+ * lowest level search function.
+ * Search for 'count'th occurrence of pattern 'pat' in direction 'dir'.
+ * Start at position 'pos' and return the found position in 'pos'.
+ *
+ * if (options & SEARCH_MSG) == 0 don't give any messages
+ * if (options & SEARCH_MSG) == SEARCH_NFMSG don't give 'notfound' messages
+ * if (options & SEARCH_MSG) == SEARCH_MSG give all messages
+ * if (options & SEARCH_HIS) put search pattern in history
+ * if (options & SEARCH_END) return position at end of match
+ * if (options & SEARCH_START) accept match at pos itself
+ * if (options & SEARCH_KEEP) keep previous search pattern
+ * if (options & SEARCH_FOLD) match only once in a closed fold
+ * if (options & SEARCH_PEEK) check for typed char, cancel search
+ *
+ * Return FAIL (zero) for failure, non-zero for success.
+ * When FEAT_EVAL is defined, returns the index of the first matching
+ * subpattern plus one; one if there was none.
+ */
+    int
+searchit(win, buf, pos, dir, pat, count, options, pat_use, stop_lnum)
+    win_T	*win;		/* window to search in; can be NULL for a
+				   buffer without a window! */
+    buf_T	*buf;
+    pos_T	*pos;
+    int		dir;
+    char_u	*pat;
+    long	count;
+    int		options;
+    int		pat_use;	/* which pattern to use when "pat" is empty */
+    linenr_T	stop_lnum;	/* stop after this line number when != 0 */
+{
+    int		found;
+    linenr_T	lnum;		/* no init to shut up Apollo cc */
+    regmmatch_T	regmatch;
+    char_u	*ptr;
+    colnr_T	matchcol;
+    lpos_T	endpos;
+    lpos_T	matchpos;
+    int		loop;
+    pos_T	start_pos;
+    int		at_first_line;
+    int		extra_col;
+    int		match_ok;
+    long	nmatched;
+    int		submatch = 0;
+    int		save_called_emsg = called_emsg;
+#ifdef FEAT_SEARCH_EXTRA
+    int		break_loop = FALSE;
+#else
+# define break_loop FALSE
+#endif
+
+    if (search_regcomp(pat, RE_SEARCH, pat_use,
+		   (options & (SEARCH_HIS + SEARCH_KEEP)), &regmatch) == FAIL)
+    {
+	if ((options & SEARCH_MSG) && !rc_did_emsg)
+	    EMSG2(_("E383: Invalid search string: %s"), mr_pattern);
+	return FAIL;
+    }
+
+    if (options & SEARCH_START)
+	extra_col = 0;
+#ifdef FEAT_MBYTE
+    /* Watch out for the "col" being MAXCOL - 2, used in a closed fold. */
+    else if (has_mbyte && pos->lnum >= 1 && pos->lnum <= buf->b_ml.ml_line_count
+						     && pos->col < MAXCOL - 2)
+    {
+	ptr = ml_get_buf(buf, pos->lnum, FALSE) + pos->col;
+	if (*ptr == NUL)
+	    extra_col = 1;
+	else
+	    extra_col = (*mb_ptr2len)(ptr);
+    }
+#endif
+    else
+	extra_col = 1;
+
+    /*
+     * find the string
+     */
+    called_emsg = FALSE;
+    do	/* loop for count */
+    {
+	start_pos = *pos;	/* remember start pos for detecting no match */
+	found = 0;		/* default: not found */
+	at_first_line = TRUE;	/* default: start in first line */
+	if (pos->lnum == 0)	/* correct lnum for when starting in line 0 */
+	{
+	    pos->lnum = 1;
+	    pos->col = 0;
+	    at_first_line = FALSE;  /* not in first line now */
+	}
+
+	/*
+	 * Start searching in current line, unless searching backwards and
+	 * we're in column 0.
+	 */
+	if (dir == BACKWARD && start_pos.col == 0)
+	{
+	    lnum = pos->lnum - 1;
+	    at_first_line = FALSE;
+	}
+	else
+	    lnum = pos->lnum;
+
+	for (loop = 0; loop <= 1; ++loop)   /* loop twice if 'wrapscan' set */
+	{
+	    for ( ; lnum > 0 && lnum <= buf->b_ml.ml_line_count;
+					   lnum += dir, at_first_line = FALSE)
+	    {
+		/* Stop after checking "stop_lnum", if it's set. */
+		if (stop_lnum != 0 && (dir == FORWARD
+				       ? lnum > stop_lnum : lnum < stop_lnum))
+		    break;
+
+		/*
+		 * Look for a match somewhere in line "lnum".
+		 */
+		nmatched = vim_regexec_multi(&regmatch, win, buf,
+							    lnum, (colnr_T)0);
+		/* Abort searching on an error (e.g., out of stack). */
+		if (called_emsg)
+		    break;
+		if (nmatched > 0)
+		{
+		    /* match may actually be in another line when using \zs */
+		    matchpos = regmatch.startpos[0];
+		    endpos = regmatch.endpos[0];
+# ifdef FEAT_EVAL
+		    submatch = first_submatch(&regmatch);
+# endif
+		    /* Line me be past end of buffer for "\n\zs". */
+		    if (lnum + matchpos.lnum > buf->b_ml.ml_line_count)
+			ptr = (char_u *)"";
+		    else
+			ptr = ml_get_buf(buf, lnum + matchpos.lnum, FALSE);
+
+		    /*
+		     * Forward search in the first line: match should be after
+		     * the start position. If not, continue at the end of the
+		     * match (this is vi compatible) or on the next char.
+		     */
+		    if (dir == FORWARD && at_first_line)
+		    {
+			match_ok = TRUE;
+			/*
+			 * When the match starts in a next line it's certainly
+			 * past the start position.
+			 * When match lands on a NUL the cursor will be put
+			 * one back afterwards, compare with that position,
+			 * otherwise "/$" will get stuck on end of line.
+			 */
+			while (matchpos.lnum == 0
+				&& ((options & SEARCH_END)
+				    ?  (nmatched == 1
+					&& (int)endpos.col - 1
+					     < (int)start_pos.col + extra_col)
+				    : ((int)matchpos.col
+						  - (ptr[matchpos.col] == NUL)
+					    < (int)start_pos.col + extra_col)))
+			{
+			    /*
+			     * If vi-compatible searching, continue at the end
+			     * of the match, otherwise continue one position
+			     * forward.
+			     */
+			    if (vim_strchr(p_cpo, CPO_SEARCH) != NULL)
+			    {
+				if (nmatched > 1)
+				{
+				    /* end is in next line, thus no match in
+				     * this line */
+				    match_ok = FALSE;
+				    break;
+				}
+				matchcol = endpos.col;
+				/* for empty match: advance one char */
+				if (matchcol == matchpos.col
+						      && ptr[matchcol] != NUL)
+				{
+#ifdef FEAT_MBYTE
+				    if (has_mbyte)
+					matchcol +=
+					  (*mb_ptr2len)(ptr + matchcol);
+				    else
+#endif
+					++matchcol;
+				}
+			    }
+			    else
+			    {
+				matchcol = matchpos.col;
+				if (ptr[matchcol] != NUL)
+				{
+#ifdef FEAT_MBYTE
+				    if (has_mbyte)
+					matchcol += (*mb_ptr2len)(ptr
+								  + matchcol);
+				    else
+#endif
+					++matchcol;
+				}
+			    }
+			    if (ptr[matchcol] == NUL
+				    || (nmatched = vim_regexec_multi(&regmatch,
+					      win, buf, lnum + matchpos.lnum,
+					      matchcol)) == 0)
+			    {
+				match_ok = FALSE;
+				break;
+			    }
+			    matchpos = regmatch.startpos[0];
+			    endpos = regmatch.endpos[0];
+# ifdef FEAT_EVAL
+			    submatch = first_submatch(&regmatch);
+# endif
+
+			    /* Need to get the line pointer again, a
+			     * multi-line search may have made it invalid. */
+			    ptr = ml_get_buf(buf, lnum + matchpos.lnum, FALSE);
+			}
+			if (!match_ok)
+			    continue;
+		    }
+		    if (dir == BACKWARD)
+		    {
+			/*
+			 * Now, if there are multiple matches on this line,
+			 * we have to get the last one. Or the last one before
+			 * the cursor, if we're on that line.
+			 * When putting the new cursor at the end, compare
+			 * relative to the end of the match.
+			 */
+			match_ok = FALSE;
+			for (;;)
+			{
+			    /* Remember a position that is before the start
+			     * position, we use it if it's the last match in
+			     * the line.  Always accept a position after
+			     * wrapping around. */
+			    if (loop
+				|| ((options & SEARCH_END)
+				    ? (lnum + regmatch.endpos[0].lnum
+							      < start_pos.lnum
+					|| (lnum + regmatch.endpos[0].lnum
+							     == start_pos.lnum
+					     && (int)regmatch.endpos[0].col - 1
+								   + extra_col
+							<= (int)start_pos.col))
+				    : (lnum + regmatch.startpos[0].lnum
+							      < start_pos.lnum
+					|| (lnum + regmatch.startpos[0].lnum
+							     == start_pos.lnum
+					     && (int)regmatch.startpos[0].col
+								   + extra_col
+						      <= (int)start_pos.col))))
+			    {
+				match_ok = TRUE;
+				matchpos = regmatch.startpos[0];
+				endpos = regmatch.endpos[0];
+# ifdef FEAT_EVAL
+				submatch = first_submatch(&regmatch);
+# endif
+			    }
+			    else
+				break;
+
+			    /*
+			     * We found a valid match, now check if there is
+			     * another one after it.
+			     * If vi-compatible searching, continue at the end
+			     * of the match, otherwise continue one position
+			     * forward.
+			     */
+			    if (vim_strchr(p_cpo, CPO_SEARCH) != NULL)
+			    {
+				if (nmatched > 1)
+				    break;
+				matchcol = endpos.col;
+				/* for empty match: advance one char */
+				if (matchcol == matchpos.col
+						      && ptr[matchcol] != NUL)
+				{
+#ifdef FEAT_MBYTE
+				    if (has_mbyte)
+					matchcol +=
+					  (*mb_ptr2len)(ptr + matchcol);
+				    else
+#endif
+					++matchcol;
+				}
+			    }
+			    else
+			    {
+				/* Stop when the match is in a next line. */
+				if (matchpos.lnum > 0)
+				    break;
+				matchcol = matchpos.col;
+				if (ptr[matchcol] != NUL)
+				{
+#ifdef FEAT_MBYTE
+				    if (has_mbyte)
+					matchcol +=
+					  (*mb_ptr2len)(ptr + matchcol);
+				    else
+#endif
+					++matchcol;
+				}
+			    }
+			    if (ptr[matchcol] == NUL
+				    || (nmatched = vim_regexec_multi(&regmatch,
+					      win, buf, lnum + matchpos.lnum,
+							      matchcol)) == 0)
+				break;
+
+			    /* Need to get the line pointer again, a
+			     * multi-line search may have made it invalid. */
+			    ptr = ml_get_buf(buf, lnum + matchpos.lnum, FALSE);
+			}
+
+			/*
+			 * If there is only a match after the cursor, skip
+			 * this match.
+			 */
+			if (!match_ok)
+			    continue;
+		    }
+
+		    if (options & SEARCH_END && !(options & SEARCH_NOOF))
+		    {
+			pos->lnum = lnum + endpos.lnum;
+			pos->col = endpos.col - 1;
+#ifdef FEAT_MBYTE
+			if (has_mbyte)
+			{
+			    /* 'e' offset may put us just below the last line */
+			    if (pos->lnum > buf->b_ml.ml_line_count)
+				ptr = (char_u *)"";
+			    else
+				ptr = ml_get_buf(buf, pos->lnum, FALSE);
+			    pos->col -= (*mb_head_off)(ptr, ptr + pos->col);
+			}
+#endif
+		    }
+		    else
+		    {
+			pos->lnum = lnum + matchpos.lnum;
+			pos->col = matchpos.col;
+		    }
+#ifdef FEAT_VIRTUALEDIT
+		    pos->coladd = 0;
+#endif
+		    found = 1;
+
+		    /* Set variables used for 'incsearch' highlighting. */
+		    search_match_lines = endpos.lnum - matchpos.lnum;
+		    search_match_endcol = endpos.col;
+		    break;
+		}
+		line_breakcheck();	/* stop if ctrl-C typed */
+		if (got_int)
+		    break;
+
+#ifdef FEAT_SEARCH_EXTRA
+		/* Cancel searching if a character was typed.  Used for
+		 * 'incsearch'.  Don't check too often, that would slowdown
+		 * searching too much. */
+		if ((options & SEARCH_PEEK)
+			&& ((lnum - pos->lnum) & 0x3f) == 0
+			&& char_avail())
+		{
+		    break_loop = TRUE;
+		    break;
+		}
+#endif
+
+		if (loop && lnum == start_pos.lnum)
+		    break;	    /* if second loop, stop where started */
+	    }
+	    at_first_line = FALSE;
+
+	    /*
+	     * Stop the search if wrapscan isn't set, "stop_lnum" is
+	     * specified, after an interrupt, after a match and after looping
+	     * twice.
+	     */
+	    if (!p_ws || stop_lnum != 0 || got_int || called_emsg
+					       || break_loop || found || loop)
+		break;
+
+	    /*
+	     * If 'wrapscan' is set we continue at the other end of the file.
+	     * If 'shortmess' does not contain 's', we give a message.
+	     * This message is also remembered in keep_msg for when the screen
+	     * is redrawn. The keep_msg is cleared whenever another message is
+	     * written.
+	     */
+	    if (dir == BACKWARD)    /* start second loop at the other end */
+		lnum = buf->b_ml.ml_line_count;
+	    else
+		lnum = 1;
+	    if (!shortmess(SHM_SEARCH) && (options & SEARCH_MSG))
+		give_warning((char_u *)_(dir == BACKWARD
+					  ? top_bot_msg : bot_top_msg), TRUE);
+	}
+	if (got_int || called_emsg || break_loop)
+	    break;
+    }
+    while (--count > 0 && found);   /* stop after count matches or no match */
+
+    vim_free(regmatch.regprog);
+
+    called_emsg |= save_called_emsg;
+
+    if (!found)		    /* did not find it */
+    {
+	if (got_int)
+	    EMSG(_(e_interr));
+	else if ((options & SEARCH_MSG) == SEARCH_MSG)
+	{
+	    if (p_ws)
+		EMSG2(_(e_patnotf2), mr_pattern);
+	    else if (lnum == 0)
+		EMSG2(_("E384: search hit TOP without match for: %s"),
+								  mr_pattern);
+	    else
+		EMSG2(_("E385: search hit BOTTOM without match for: %s"),
+								  mr_pattern);
+	}
+	return FAIL;
+    }
+
+    /* A pattern like "\n\zs" may go past the last line. */
+    if (pos->lnum > buf->b_ml.ml_line_count)
+    {
+	pos->lnum = buf->b_ml.ml_line_count;
+	pos->col = (int)STRLEN(ml_get_buf(buf, pos->lnum, FALSE));
+	if (pos->col > 0)
+	    --pos->col;
+    }
+
+    return submatch + 1;
+}
+
+#ifdef FEAT_EVAL
+/*
+ * Return the number of the first subpat that matched.
+ */
+    static int
+first_submatch(rp)
+    regmmatch_T	*rp;
+{
+    int		submatch;
+
+    for (submatch = 1; ; ++submatch)
+    {
+	if (rp->startpos[submatch].lnum >= 0)
+	    break;
+	if (submatch == 9)
+	{
+	    submatch = 0;
+	    break;
+	}
+    }
+    return submatch;
+}
+#endif
+
+/*
+ * Highest level string search function.
+ * Search for the 'count'th occurrence of pattern 'pat' in direction 'dirc'
+ *		  If 'dirc' is 0: use previous dir.
+ *    If 'pat' is NULL or empty : use previous string.
+ *    If 'options & SEARCH_REV' : go in reverse of previous dir.
+ *    If 'options & SEARCH_ECHO': echo the search command and handle options
+ *    If 'options & SEARCH_MSG' : may give error message
+ *    If 'options & SEARCH_OPT' : interpret optional flags
+ *    If 'options & SEARCH_HIS' : put search pattern in history
+ *    If 'options & SEARCH_NOOF': don't add offset to position
+ *    If 'options & SEARCH_MARK': set previous context mark
+ *    If 'options & SEARCH_KEEP': keep previous search pattern
+ *    If 'options & SEARCH_START': accept match at curpos itself
+ *    If 'options & SEARCH_PEEK': check for typed char, cancel search
+ *
+ * Careful: If spats[0].off.line == TRUE and spats[0].off.off == 0 this
+ * makes the movement linewise without moving the match position.
+ *
+ * return 0 for failure, 1 for found, 2 for found and line offset added
+ */
+    int
+do_search(oap, dirc, pat, count, options)
+    oparg_T	    *oap;	/* can be NULL */
+    int		    dirc;	/* '/' or '?' */
+    char_u	   *pat;
+    long	    count;
+    int		    options;
+{
+    pos_T	    pos;	/* position of the last match */
+    char_u	    *searchstr;
+    struct soffset  old_off;
+    int		    retval;	/* Return value */
+    char_u	    *p;
+    long	    c;
+    char_u	    *dircp;
+    char_u	    *strcopy = NULL;
+    char_u	    *ps;
+
+    /*
+     * A line offset is not remembered, this is vi compatible.
+     */
+    if (spats[0].off.line && vim_strchr(p_cpo, CPO_LINEOFF) != NULL)
+    {
+	spats[0].off.line = FALSE;
+	spats[0].off.off = 0;
+    }
+
+    /*
+     * Save the values for when (options & SEARCH_KEEP) is used.
+     * (there is no "if ()" around this because gcc wants them initialized)
+     */
+    old_off = spats[0].off;
+
+    pos = curwin->w_cursor;	/* start searching at the cursor position */
+
+    /*
+     * Find out the direction of the search.
+     */
+    if (dirc == 0)
+	dirc = spats[0].off.dir;
+    else
+	spats[0].off.dir = dirc;
+    if (options & SEARCH_REV)
+    {
+#ifdef WIN32
+	/* There is a bug in the Visual C++ 2.2 compiler which means that
+	 * dirc always ends up being '/' */
+	dirc = (dirc == '/')  ?  '?'  :  '/';
+#else
+	if (dirc == '/')
+	    dirc = '?';
+	else
+	    dirc = '/';
+#endif
+    }
+
+#ifdef FEAT_FOLDING
+    /* If the cursor is in a closed fold, don't find another match in the same
+     * fold. */
+    if (dirc == '/')
+    {
+	if (hasFolding(pos.lnum, NULL, &pos.lnum))
+	    pos.col = MAXCOL - 2;	/* avoid overflow when adding 1 */
+    }
+    else
+    {
+	if (hasFolding(pos.lnum, &pos.lnum, NULL))
+	    pos.col = 0;
+    }
+#endif
+
+#ifdef FEAT_SEARCH_EXTRA
+    /*
+     * Turn 'hlsearch' highlighting back on.
+     */
+    if (no_hlsearch && !(options & SEARCH_KEEP))
+    {
+	redraw_all_later(SOME_VALID);
+	no_hlsearch = FALSE;
+    }
+#endif
+
+    /*
+     * Repeat the search when pattern followed by ';', e.g. "/foo/;?bar".
+     */
+    for (;;)
+    {
+	searchstr = pat;
+	dircp = NULL;
+					    /* use previous pattern */
+	if (pat == NULL || *pat == NUL || *pat == dirc)
+	{
+	    if (spats[RE_SEARCH].pat == NULL)	    /* no previous pattern */
+	    {
+		EMSG(_(e_noprevre));
+		retval = 0;
+		goto end_do_search;
+	    }
+	    /* make search_regcomp() use spats[RE_SEARCH].pat */
+	    searchstr = (char_u *)"";
+	}
+
+	if (pat != NULL && *pat != NUL)	/* look for (new) offset */
+	{
+	    /*
+	     * Find end of regular expression.
+	     * If there is a matching '/' or '?', toss it.
+	     */
+	    ps = strcopy;
+	    p = skip_regexp(pat, dirc, (int)p_magic, &strcopy);
+	    if (strcopy != ps)
+	    {
+		/* made a copy of "pat" to change "\?" to "?" */
+		searchcmdlen += (int)(STRLEN(pat) - STRLEN(strcopy));
+		pat = strcopy;
+		searchstr = strcopy;
+	    }
+	    if (*p == dirc)
+	    {
+		dircp = p;	/* remember where we put the NUL */
+		*p++ = NUL;
+	    }
+	    spats[0].off.line = FALSE;
+	    spats[0].off.end = FALSE;
+	    spats[0].off.off = 0;
+	    /*
+	     * Check for a line offset or a character offset.
+	     * For get_address (echo off) we don't check for a character
+	     * offset, because it is meaningless and the 's' could be a
+	     * substitute command.
+	     */
+	    if (*p == '+' || *p == '-' || VIM_ISDIGIT(*p))
+		spats[0].off.line = TRUE;
+	    else if ((options & SEARCH_OPT) &&
+					(*p == 'e' || *p == 's' || *p == 'b'))
+	    {
+		if (*p == 'e')		/* end */
+		    spats[0].off.end = SEARCH_END;
+		++p;
+	    }
+	    if (VIM_ISDIGIT(*p) || *p == '+' || *p == '-')  /* got an offset */
+	    {
+					    /* 'nr' or '+nr' or '-nr' */
+		if (VIM_ISDIGIT(*p) || VIM_ISDIGIT(*(p + 1)))
+		    spats[0].off.off = atol((char *)p);
+		else if (*p == '-')	    /* single '-' */
+		    spats[0].off.off = -1;
+		else			    /* single '+' */
+		    spats[0].off.off = 1;
+		++p;
+		while (VIM_ISDIGIT(*p))	    /* skip number */
+		    ++p;
+	    }
+
+	    /* compute length of search command for get_address() */
+	    searchcmdlen += (int)(p - pat);
+
+	    pat = p;			    /* put pat after search command */
+	}
+
+	if ((options & SEARCH_ECHO) && messaging()
+					    && !cmd_silent && msg_silent == 0)
+	{
+	    char_u	*msgbuf;
+	    char_u	*trunc;
+
+	    if (*searchstr == NUL)
+		p = spats[last_idx].pat;
+	    else
+		p = searchstr;
+	    msgbuf = alloc((unsigned)(STRLEN(p) + 40));
+	    if (msgbuf != NULL)
+	    {
+		msgbuf[0] = dirc;
+#ifdef FEAT_MBYTE
+		if (enc_utf8 && utf_iscomposing(utf_ptr2char(p)))
+		{
+		    /* Use a space to draw the composing char on. */
+		    msgbuf[1] = ' ';
+		    STRCPY(msgbuf + 2, p);
+		}
+		else
+#endif
+		    STRCPY(msgbuf + 1, p);
+		if (spats[0].off.line || spats[0].off.end || spats[0].off.off)
+		{
+		    p = msgbuf + STRLEN(msgbuf);
+		    *p++ = dirc;
+		    if (spats[0].off.end)
+			*p++ = 'e';
+		    else if (!spats[0].off.line)
+			*p++ = 's';
+		    if (spats[0].off.off > 0 || spats[0].off.line)
+			*p++ = '+';
+		    if (spats[0].off.off != 0 || spats[0].off.line)
+			sprintf((char *)p, "%ld", spats[0].off.off);
+		    else
+			*p = NUL;
+		}
+
+		msg_start();
+		trunc = msg_strtrunc(msgbuf, FALSE);
+
+#ifdef FEAT_RIGHTLEFT
+		/* The search pattern could be shown on the right in rightleft
+		 * mode, but the 'ruler' and 'showcmd' area use it too, thus
+		 * it would be blanked out again very soon.  Show it on the
+		 * left, but do reverse the text. */
+		if (curwin->w_p_rl && *curwin->w_p_rlc == 's')
+		{
+		    char_u *r;
+
+		    r = reverse_text(trunc != NULL ? trunc : msgbuf);
+		    if (r != NULL)
+		    {
+			vim_free(trunc);
+			trunc = r;
+		    }
+		}
+#endif
+		if (trunc != NULL)
+		{
+		    msg_outtrans(trunc);
+		    vim_free(trunc);
+		}
+		else
+		    msg_outtrans(msgbuf);
+		msg_clr_eos();
+		msg_check();
+		vim_free(msgbuf);
+
+		gotocmdline(FALSE);
+		out_flush();
+		msg_nowait = TRUE;	    /* don't wait for this message */
+	    }
+	}
+
+	/*
+	 * If there is a character offset, subtract it from the current
+	 * position, so we don't get stuck at "?pat?e+2" or "/pat/s-2".
+	 * Skip this if pos.col is near MAXCOL (closed fold).
+	 * This is not done for a line offset, because then we would not be vi
+	 * compatible.
+	 */
+	if (!spats[0].off.line && spats[0].off.off && pos.col < MAXCOL - 2)
+	{
+	    if (spats[0].off.off > 0)
+	    {
+		for (c = spats[0].off.off; c; --c)
+		    if (decl(&pos) == -1)
+			break;
+		if (c)			/* at start of buffer */
+		{
+		    pos.lnum = 0;	/* allow lnum == 0 here */
+		    pos.col = MAXCOL;
+		}
+	    }
+	    else
+	    {
+		for (c = spats[0].off.off; c; ++c)
+		    if (incl(&pos) == -1)
+			break;
+		if (c)			/* at end of buffer */
+		{
+		    pos.lnum = curbuf->b_ml.ml_line_count + 1;
+		    pos.col = 0;
+		}
+	    }
+	}
+
+#ifdef FEAT_FKMAP	/* when in Farsi mode, reverse the character flow */
+	if (p_altkeymap && curwin->w_p_rl)
+	     lrFswap(searchstr,0);
+#endif
+
+	c = searchit(curwin, curbuf, &pos, dirc == '/' ? FORWARD : BACKWARD,
+		searchstr, count, spats[0].off.end + (options &
+		       (SEARCH_KEEP + SEARCH_PEEK + SEARCH_HIS
+			+ SEARCH_MSG + SEARCH_START
+			+ ((pat != NULL && *pat == ';') ? 0 : SEARCH_NOOF))),
+		RE_LAST, (linenr_T)0);
+
+	if (dircp != NULL)
+	    *dircp = dirc;	/* restore second '/' or '?' for normal_cmd() */
+	if (c == FAIL)
+	{
+	    retval = 0;
+	    goto end_do_search;
+	}
+	if (spats[0].off.end && oap != NULL)
+	    oap->inclusive = TRUE;  /* 'e' includes last character */
+
+	retval = 1;		    /* pattern found */
+
+	/*
+	 * Add character and/or line offset
+	 */
+	if (!(options & SEARCH_NOOF) || (pat != NULL && *pat == ';'))
+	{
+	    if (spats[0].off.line)	/* Add the offset to the line number. */
+	    {
+		c = pos.lnum + spats[0].off.off;
+		if (c < 1)
+		    pos.lnum = 1;
+		else if (c > curbuf->b_ml.ml_line_count)
+		    pos.lnum = curbuf->b_ml.ml_line_count;
+		else
+		    pos.lnum = c;
+		pos.col = 0;
+
+		retval = 2;	    /* pattern found, line offset added */
+	    }
+	    else if (pos.col < MAXCOL - 2)	/* just in case */
+	    {
+		/* to the right, check for end of file */
+		if (spats[0].off.off > 0)
+		{
+		    for (c = spats[0].off.off; c; --c)
+			if (incl(&pos) == -1)
+			    break;
+		}
+		/* to the left, check for start of file */
+		else
+		{
+		    if ((c = pos.col + spats[0].off.off) >= 0)
+			pos.col = c;
+		    else
+			for (c = spats[0].off.off; c; ++c)
+			    if (decl(&pos) == -1)
+				break;
+		}
+	    }
+	}
+
+	/*
+	 * The search command can be followed by a ';' to do another search.
+	 * For example: "/pat/;/foo/+3;?bar"
+	 * This is like doing another search command, except:
+	 * - The remembered direction '/' or '?' is from the first search.
+	 * - When an error happens the cursor isn't moved at all.
+	 * Don't do this when called by get_address() (it handles ';' itself).
+	 */
+	if (!(options & SEARCH_OPT) || pat == NULL || *pat != ';')
+	    break;
+
+	dirc = *++pat;
+	if (dirc != '?' && dirc != '/')
+	{
+	    retval = 0;
+	    EMSG(_("E386: Expected '?' or '/'  after ';'"));
+	    goto end_do_search;
+	}
+	++pat;
+    }
+
+    if (options & SEARCH_MARK)
+	setpcmark();
+    curwin->w_cursor = pos;
+    curwin->w_set_curswant = TRUE;
+
+end_do_search:
+    if (options & SEARCH_KEEP)
+	spats[0].off = old_off;
+    vim_free(strcopy);
+
+    return retval;
+}
+
+#if defined(FEAT_INS_EXPAND) || defined(PROTO)
+/*
+ * search_for_exact_line(buf, pos, dir, pat)
+ *
+ * Search for a line starting with the given pattern (ignoring leading
+ * white-space), starting from pos and going in direction dir.	pos will
+ * contain the position of the match found.    Blank lines match only if
+ * ADDING is set.  if p_ic is set then the pattern must be in lowercase.
+ * Return OK for success, or FAIL if no line found.
+ */
+    int
+search_for_exact_line(buf, pos, dir, pat)
+    buf_T	*buf;
+    pos_T	*pos;
+    int		dir;
+    char_u	*pat;
+{
+    linenr_T	start = 0;
+    char_u	*ptr;
+    char_u	*p;
+
+    if (buf->b_ml.ml_line_count == 0)
+	return FAIL;
+    for (;;)
+    {
+	pos->lnum += dir;
+	if (pos->lnum < 1)
+	{
+	    if (p_ws)
+	    {
+		pos->lnum = buf->b_ml.ml_line_count;
+		if (!shortmess(SHM_SEARCH))
+		    give_warning((char_u *)_(top_bot_msg), TRUE);
+	    }
+	    else
+	    {
+		pos->lnum = 1;
+		break;
+	    }
+	}
+	else if (pos->lnum > buf->b_ml.ml_line_count)
+	{
+	    if (p_ws)
+	    {
+		pos->lnum = 1;
+		if (!shortmess(SHM_SEARCH))
+		    give_warning((char_u *)_(bot_top_msg), TRUE);
+	    }
+	    else
+	    {
+		pos->lnum = 1;
+		break;
+	    }
+	}
+	if (pos->lnum == start)
+	    break;
+	if (start == 0)
+	    start = pos->lnum;
+	ptr = ml_get_buf(buf, pos->lnum, FALSE);
+	p = skipwhite(ptr);
+	pos->col = (colnr_T) (p - ptr);
+
+	/* when adding lines the matching line may be empty but it is not
+	 * ignored because we are interested in the next line -- Acevedo */
+	if ((compl_cont_status & CONT_ADDING)
+					   && !(compl_cont_status & CONT_SOL))
+	{
+	    if ((p_ic ? MB_STRICMP(p, pat) : STRCMP(p, pat)) == 0)
+		return OK;
+	}
+	else if (*p != NUL)	/* ignore empty lines */
+	{	/* expanding lines or words */
+	    if ((p_ic ? MB_STRNICMP(p, pat, compl_length)
+				   : STRNCMP(p, pat, compl_length)) == 0)
+		return OK;
+	}
+    }
+    return FAIL;
+}
+#endif /* FEAT_INS_EXPAND */
+
+/*
+ * Character Searches
+ */
+
+/*
+ * Search for a character in a line.  If "t_cmd" is FALSE, move to the
+ * position of the character, otherwise move to just before the char.
+ * Do this "cap->count1" times.
+ * Return FAIL or OK.
+ */
+    int
+searchc(cap, t_cmd)
+    cmdarg_T	*cap;
+    int		t_cmd;
+{
+    int			c = cap->nchar;	/* char to search for */
+    int			dir = cap->arg;	/* TRUE for searching forward */
+    long		count = cap->count1;	/* repeat count */
+    static int		lastc = NUL;	/* last character searched for */
+    static int		lastcdir;	/* last direction of character search */
+    static int		last_t_cmd;	/* last search t_cmd */
+    int			col;
+    char_u		*p;
+    int			len;
+#ifdef FEAT_MBYTE
+    static char_u	bytes[MB_MAXBYTES];
+    static int		bytelen = 1;	/* >1 for multi-byte char */
+#endif
+
+    if (c != NUL)	/* normal search: remember args for repeat */
+    {
+	if (!KeyStuffed)    /* don't remember when redoing */
+	{
+	    lastc = c;
+	    lastcdir = dir;
+	    last_t_cmd = t_cmd;
+#ifdef FEAT_MBYTE
+	    bytelen = (*mb_char2bytes)(c, bytes);
+	    if (cap->ncharC1 != 0)
+	    {
+		bytelen += (*mb_char2bytes)(cap->ncharC1, bytes + bytelen);
+		if (cap->ncharC2 != 0)
+		    bytelen += (*mb_char2bytes)(cap->ncharC2, bytes + bytelen);
+	    }
+#endif
+	}
+    }
+    else		/* repeat previous search */
+    {
+	if (lastc == NUL)
+	    return FAIL;
+	if (dir)	/* repeat in opposite direction */
+	    dir = -lastcdir;
+	else
+	    dir = lastcdir;
+	t_cmd = last_t_cmd;
+	c = lastc;
+	/* For multi-byte re-use last bytes[] and bytelen. */
+    }
+
+    if (dir == BACKWARD)
+	cap->oap->inclusive = FALSE;
+    else
+	cap->oap->inclusive = TRUE;
+
+    p = ml_get_curline();
+    col = curwin->w_cursor.col;
+    len = (int)STRLEN(p);
+
+    while (count--)
+    {
+#ifdef FEAT_MBYTE
+	if (has_mbyte)
+	{
+	    for (;;)
+	    {
+		if (dir > 0)
+		{
+		    col += (*mb_ptr2len)(p + col);
+		    if (col >= len)
+			return FAIL;
+		}
+		else
+		{
+		    if (col == 0)
+			return FAIL;
+		    col -= (*mb_head_off)(p, p + col - 1) + 1;
+		}
+		if (bytelen == 1)
+		{
+		    if (p[col] == c)
+			break;
+		}
+		else
+		{
+		    if (vim_memcmp(p + col, bytes, bytelen) == 0)
+			break;
+		}
+	    }
+	}
+	else
+#endif
+	{
+	    for (;;)
+	    {
+		if ((col += dir) < 0 || col >= len)
+		    return FAIL;
+		if (p[col] == c)
+		    break;
+	    }
+	}
+    }
+
+    if (t_cmd)
+    {
+	/* backup to before the character (possibly double-byte) */
+	col -= dir;
+#ifdef FEAT_MBYTE
+	if (has_mbyte)
+	{
+	    if (dir < 0)
+		/* Landed on the search char which is bytelen long */
+		col += bytelen - 1;
+	    else
+		/* To previous char, which may be multi-byte. */
+		col -= (*mb_head_off)(p, p + col);
+	}
+#endif
+    }
+    curwin->w_cursor.col = col;
+
+    return OK;
+}
+
+/*
+ * "Other" Searches
+ */
+
+/*
+ * findmatch - find the matching paren or brace
+ *
+ * Improvement over vi: Braces inside quotes are ignored.
+ */
+    pos_T *
+findmatch(oap, initc)
+    oparg_T   *oap;
+    int	    initc;
+{
+    return findmatchlimit(oap, initc, 0, 0);
+}
+
+/*
+ * Return TRUE if the character before "linep[col]" equals "ch".
+ * Return FALSE if "col" is zero.
+ * Update "*prevcol" to the column of the previous character, unless "prevcol"
+ * is NULL.
+ * Handles multibyte string correctly.
+ */
+    static int
+check_prevcol(linep, col, ch, prevcol)
+    char_u	*linep;
+    int		col;
+    int		ch;
+    int		*prevcol;
+{
+    --col;
+#ifdef FEAT_MBYTE
+    if (col > 0 && has_mbyte)
+	col -= (*mb_head_off)(linep, linep + col);
+#endif
+    if (prevcol)
+	*prevcol = col;
+    return (col >= 0 && linep[col] == ch) ? TRUE : FALSE;
+}
+
+/*
+ * findmatchlimit -- find the matching paren or brace, if it exists within
+ * maxtravel lines of here.  A maxtravel of 0 means search until falling off
+ * the edge of the file.
+ *
+ * "initc" is the character to find a match for.  NUL means to find the
+ * character at or after the cursor.
+ *
+ * flags: FM_BACKWARD	search backwards (when initc is '/', '*' or '#')
+ *	  FM_FORWARD	search forwards (when initc is '/', '*' or '#')
+ *	  FM_BLOCKSTOP	stop at start/end of block ({ or } in column 0)
+ *	  FM_SKIPCOMM	skip comments (not implemented yet!)
+ *
+ * "oap" is only used to set oap->motion_type for a linewise motion, it be
+ * NULL
+ */
+
+    pos_T *
+findmatchlimit(oap, initc, flags, maxtravel)
+    oparg_T	*oap;
+    int		initc;
+    int		flags;
+    int		maxtravel;
+{
+    static pos_T pos;			/* current search position */
+    int		findc = 0;		/* matching brace */
+    int		c;
+    int		count = 0;		/* cumulative number of braces */
+    int		backwards = FALSE;	/* init for gcc */
+    int		inquote = FALSE;	/* TRUE when inside quotes */
+    char_u	*linep;			/* pointer to current line */
+    char_u	*ptr;
+    int		do_quotes;		/* check for quotes in current line */
+    int		at_start;		/* do_quotes value at start position */
+    int		hash_dir = 0;		/* Direction searched for # things */
+    int		comment_dir = 0;	/* Direction searched for comments */
+    pos_T	match_pos;		/* Where last slash-star was found */
+    int		start_in_quotes;	/* start position is in quotes */
+    int		traveled = 0;		/* how far we've searched so far */
+    int		ignore_cend = FALSE;    /* ignore comment end */
+    int		cpo_match;		/* vi compatible matching */
+    int		cpo_bsl;		/* don't recognize backslashes */
+    int		match_escaped = 0;	/* search for escaped match */
+    int		dir;			/* Direction to search */
+    int		comment_col = MAXCOL;   /* start of / / comment */
+#ifdef FEAT_LISP
+    int		lispcomm = FALSE;	/* inside of Lisp-style comment */
+    int		lisp = curbuf->b_p_lisp; /* engage Lisp-specific hacks ;) */
+#endif
+
+    pos = curwin->w_cursor;
+    linep = ml_get(pos.lnum);
+
+    cpo_match = (vim_strchr(p_cpo, CPO_MATCH) != NULL);
+    cpo_bsl = (vim_strchr(p_cpo, CPO_MATCHBSL) != NULL);
+
+    /* Direction to search when initc is '/', '*' or '#' */
+    if (flags & FM_BACKWARD)
+	dir = BACKWARD;
+    else if (flags & FM_FORWARD)
+	dir = FORWARD;
+    else
+	dir = 0;
+
+    /*
+     * if initc given, look in the table for the matching character
+     * '/' and '*' are special cases: look for start or end of comment.
+     * When '/' is used, we ignore running backwards into an star-slash, for
+     * "[*" command, we just want to find any comment.
+     */
+    if (initc == '/' || initc == '*')
+    {
+	comment_dir = dir;
+	if (initc == '/')
+	    ignore_cend = TRUE;
+	backwards = (dir == FORWARD) ? FALSE : TRUE;
+	initc = NUL;
+    }
+    else if (initc != '#' && initc != NUL)
+    {
+	/* 'matchpairs' is "x:y,x:y" */
+	for (ptr = curbuf->b_p_mps; *ptr; ptr += 2)
+	{
+	    if (*ptr == initc)
+	    {
+		findc = initc;
+		initc = ptr[2];
+		backwards = TRUE;
+		break;
+	    }
+	    ptr += 2;
+	    if (*ptr == initc)
+	    {
+		findc = initc;
+		initc = ptr[-2];
+		backwards = FALSE;
+		break;
+	    }
+	    if (ptr[1] != ',')
+		break;
+	}
+	if (!findc)		/* invalid initc! */
+	    return NULL;
+    }
+    /*
+     * Either initc is '#', or no initc was given and we need to look under the
+     * cursor.
+     */
+    else
+    {
+	if (initc == '#')
+	{
+	    hash_dir = dir;
+	}
+	else
+	{
+	    /*
+	     * initc was not given, must look for something to match under
+	     * or near the cursor.
+	     * Only check for special things when 'cpo' doesn't have '%'.
+	     */
+	    if (!cpo_match)
+	    {
+		/* Are we before or at #if, #else etc.? */
+		ptr = skipwhite(linep);
+		if (*ptr == '#' && pos.col <= (colnr_T)(ptr - linep))
+		{
+		    ptr = skipwhite(ptr + 1);
+		    if (   STRNCMP(ptr, "if", 2) == 0
+			|| STRNCMP(ptr, "endif", 5) == 0
+			|| STRNCMP(ptr, "el", 2) == 0)
+			hash_dir = 1;
+		}
+
+		/* Are we on a comment? */
+		else if (linep[pos.col] == '/')
+		{
+		    if (linep[pos.col + 1] == '*')
+		    {
+			comment_dir = FORWARD;
+			backwards = FALSE;
+			pos.col++;
+		    }
+		    else if (pos.col > 0 && linep[pos.col - 1] == '*')
+		    {
+			comment_dir = BACKWARD;
+			backwards = TRUE;
+			pos.col--;
+		    }
+		}
+		else if (linep[pos.col] == '*')
+		{
+		    if (linep[pos.col + 1] == '/')
+		    {
+			comment_dir = BACKWARD;
+			backwards = TRUE;
+		    }
+		    else if (pos.col > 0 && linep[pos.col - 1] == '/')
+		    {
+			comment_dir = FORWARD;
+			backwards = FALSE;
+		    }
+		}
+	    }
+
+	    /*
+	     * If we are not on a comment or the # at the start of a line, then
+	     * look for brace anywhere on this line after the cursor.
+	     */
+	    if (!hash_dir && !comment_dir)
+	    {
+		/*
+		 * Find the brace under or after the cursor.
+		 * If beyond the end of the line, use the last character in
+		 * the line.
+		 */
+		if (linep[pos.col] == NUL && pos.col)
+		    --pos.col;
+		for (;;)
+		{
+		    initc = linep[pos.col];
+		    if (initc == NUL)
+			break;
+
+		    for (ptr = curbuf->b_p_mps; *ptr; ++ptr)
+		    {
+			if (*ptr == initc)
+			{
+			    findc = ptr[2];
+			    backwards = FALSE;
+			    break;
+			}
+			ptr += 2;
+			if (*ptr == initc)
+			{
+			    findc = ptr[-2];
+			    backwards = TRUE;
+			    break;
+			}
+			if (!*++ptr)
+			    break;
+		    }
+		    if (findc)
+			break;
+#ifdef FEAT_MBYTE
+		    if (has_mbyte)
+			pos.col += (*mb_ptr2len)(linep + pos.col);
+		    else
+#endif
+			++pos.col;
+		}
+		if (!findc)
+		{
+		    /* no brace in the line, maybe use "  #if" then */
+		    if (!cpo_match && *skipwhite(linep) == '#')
+			hash_dir = 1;
+		    else
+			return NULL;
+		}
+		else if (!cpo_bsl)
+		{
+		    int col, bslcnt = 0;
+
+		    /* Set "match_escaped" if there are an odd number of
+		     * backslashes. */
+		    for (col = pos.col; check_prevcol(linep, col, '\\', &col);)
+			bslcnt++;
+		    match_escaped = (bslcnt & 1);
+		}
+	    }
+	}
+	if (hash_dir)
+	{
+	    /*
+	     * Look for matching #if, #else, #elif, or #endif
+	     */
+	    if (oap != NULL)
+		oap->motion_type = MLINE;   /* Linewise for this case only */
+	    if (initc != '#')
+	    {
+		ptr = skipwhite(skipwhite(linep) + 1);
+		if (STRNCMP(ptr, "if", 2) == 0 || STRNCMP(ptr, "el", 2) == 0)
+		    hash_dir = 1;
+		else if (STRNCMP(ptr, "endif", 5) == 0)
+		    hash_dir = -1;
+		else
+		    return NULL;
+	    }
+	    pos.col = 0;
+	    while (!got_int)
+	    {
+		if (hash_dir > 0)
+		{
+		    if (pos.lnum == curbuf->b_ml.ml_line_count)
+			break;
+		}
+		else if (pos.lnum == 1)
+		    break;
+		pos.lnum += hash_dir;
+		linep = ml_get(pos.lnum);
+		line_breakcheck();	/* check for CTRL-C typed */
+		ptr = skipwhite(linep);
+		if (*ptr != '#')
+		    continue;
+		pos.col = (colnr_T) (ptr - linep);
+		ptr = skipwhite(ptr + 1);
+		if (hash_dir > 0)
+		{
+		    if (STRNCMP(ptr, "if", 2) == 0)
+			count++;
+		    else if (STRNCMP(ptr, "el", 2) == 0)
+		    {
+			if (count == 0)
+			    return &pos;
+		    }
+		    else if (STRNCMP(ptr, "endif", 5) == 0)
+		    {
+			if (count == 0)
+			    return &pos;
+			count--;
+		    }
+		}
+		else
+		{
+		    if (STRNCMP(ptr, "if", 2) == 0)
+		    {
+			if (count == 0)
+			    return &pos;
+			count--;
+		    }
+		    else if (initc == '#' && STRNCMP(ptr, "el", 2) == 0)
+		    {
+			if (count == 0)
+			    return &pos;
+		    }
+		    else if (STRNCMP(ptr, "endif", 5) == 0)
+			count++;
+		}
+	    }
+	    return NULL;
+	}
+    }
+
+#ifdef FEAT_RIGHTLEFT
+    /* This is just guessing: when 'rightleft' is set, search for a maching
+     * paren/brace in the other direction. */
+    if (curwin->w_p_rl && vim_strchr((char_u *)"()[]{}<>", initc) != NULL)
+	backwards = !backwards;
+#endif
+
+    do_quotes = -1;
+    start_in_quotes = MAYBE;
+    clearpos(&match_pos);
+
+    /* backward search: Check if this line contains a single-line comment */
+    if ((backwards && comment_dir)
+#ifdef FEAT_LISP
+	    || lisp
+#endif
+	    )
+	comment_col = check_linecomment(linep);
+#ifdef FEAT_LISP
+    if (lisp && comment_col != MAXCOL && pos.col > (colnr_T)comment_col)
+	lispcomm = TRUE;    /* find match inside this comment */
+#endif
+    while (!got_int)
+    {
+	/*
+	 * Go to the next position, forward or backward. We could use
+	 * inc() and dec() here, but that is much slower
+	 */
+	if (backwards)
+	{
+#ifdef FEAT_LISP
+	    /* char to match is inside of comment, don't search outside */
+	    if (lispcomm && pos.col < (colnr_T)comment_col)
+		break;
+#endif
+	    if (pos.col == 0)		/* at start of line, go to prev. one */
+	    {
+		if (pos.lnum == 1)	/* start of file */
+		    break;
+		--pos.lnum;
+
+		if (maxtravel > 0 && ++traveled > maxtravel)
+		    break;
+
+		linep = ml_get(pos.lnum);
+		pos.col = (colnr_T)STRLEN(linep); /* pos.col on trailing NUL */
+		do_quotes = -1;
+		line_breakcheck();
+
+		/* Check if this line contains a single-line comment */
+		if (comment_dir
+#ifdef FEAT_LISP
+			|| lisp
+#endif
+			)
+		    comment_col = check_linecomment(linep);
+#ifdef FEAT_LISP
+		/* skip comment */
+		if (lisp && comment_col != MAXCOL)
+		    pos.col = comment_col;
+#endif
+	    }
+	    else
+	    {
+		--pos.col;
+#ifdef FEAT_MBYTE
+		if (has_mbyte)
+		    pos.col -= (*mb_head_off)(linep, linep + pos.col);
+#endif
+	    }
+	}
+	else				/* forward search */
+	{
+	    if (linep[pos.col] == NUL
+		    /* at end of line, go to next one */
+#ifdef FEAT_LISP
+		    /* don't search for match in comment */
+		    || (lisp && comment_col != MAXCOL
+					   && pos.col == (colnr_T)comment_col)
+#endif
+		    )
+	    {
+		if (pos.lnum == curbuf->b_ml.ml_line_count  /* end of file */
+#ifdef FEAT_LISP
+			/* line is exhausted and comment with it,
+			 * don't search for match in code */
+			 || lispcomm
+#endif
+			 )
+		    break;
+		++pos.lnum;
+
+		if (maxtravel && traveled++ > maxtravel)
+		    break;
+
+		linep = ml_get(pos.lnum);
+		pos.col = 0;
+		do_quotes = -1;
+		line_breakcheck();
+#ifdef FEAT_LISP
+		if (lisp)   /* find comment pos in new line */
+		    comment_col = check_linecomment(linep);
+#endif
+	    }
+	    else
+	    {
+#ifdef FEAT_MBYTE
+		if (has_mbyte)
+		    pos.col += (*mb_ptr2len)(linep + pos.col);
+		else
+#endif
+		    ++pos.col;
+	    }
+	}
+
+	/*
+	 * If FM_BLOCKSTOP given, stop at a '{' or '}' in column 0.
+	 */
+	if (pos.col == 0 && (flags & FM_BLOCKSTOP) &&
+					 (linep[0] == '{' || linep[0] == '}'))
+	{
+	    if (linep[0] == findc && count == 0)	/* match! */
+		return &pos;
+	    break;					/* out of scope */
+	}
+
+	if (comment_dir)
+	{
+	    /* Note: comments do not nest, and we ignore quotes in them */
+	    /* TODO: ignore comment brackets inside strings */
+	    if (comment_dir == FORWARD)
+	    {
+		if (linep[pos.col] == '*' && linep[pos.col + 1] == '/')
+		{
+		    pos.col++;
+		    return &pos;
+		}
+	    }
+	    else    /* Searching backwards */
+	    {
+		/*
+		 * A comment may contain / * or / /, it may also start or end
+		 * with / * /.	Ignore a / * after / /.
+		 */
+		if (pos.col == 0)
+		    continue;
+		else if (  linep[pos.col - 1] == '/'
+			&& linep[pos.col] == '*'
+			&& (int)pos.col < comment_col)
+		{
+		    count++;
+		    match_pos = pos;
+		    match_pos.col--;
+		}
+		else if (linep[pos.col - 1] == '*' && linep[pos.col] == '/')
+		{
+		    if (count > 0)
+			pos = match_pos;
+		    else if (pos.col > 1 && linep[pos.col - 2] == '/'
+					       && (int)pos.col <= comment_col)
+			pos.col -= 2;
+		    else if (ignore_cend)
+			continue;
+		    else
+			return NULL;
+		    return &pos;
+		}
+	    }
+	    continue;
+	}
+
+	/*
+	 * If smart matching ('cpoptions' does not contain '%'), braces inside
+	 * of quotes are ignored, but only if there is an even number of
+	 * quotes in the line.
+	 */
+	if (cpo_match)
+	    do_quotes = 0;
+	else if (do_quotes == -1)
+	{
+	    /*
+	     * Count the number of quotes in the line, skipping \" and '"'.
+	     * Watch out for "\\".
+	     */
+	    at_start = do_quotes;
+	    for (ptr = linep; *ptr; ++ptr)
+	    {
+		if (ptr == linep + pos.col + backwards)
+		    at_start = (do_quotes & 1);
+		if (*ptr == '"'
+			&& (ptr == linep || ptr[-1] != '\'' || ptr[1] != '\''))
+		    ++do_quotes;
+		if (*ptr == '\\' && ptr[1] != NUL)
+		    ++ptr;
+	    }
+	    do_quotes &= 1;	    /* result is 1 with even number of quotes */
+
+	    /*
+	     * If we find an uneven count, check current line and previous
+	     * one for a '\' at the end.
+	     */
+	    if (!do_quotes)
+	    {
+		inquote = FALSE;
+		if (ptr[-1] == '\\')
+		{
+		    do_quotes = 1;
+		    if (start_in_quotes == MAYBE)
+		    {
+			/* Do we need to use at_start here? */
+			inquote = TRUE;
+			start_in_quotes = TRUE;
+		    }
+		    else if (backwards)
+			inquote = TRUE;
+		}
+		if (pos.lnum > 1)
+		{
+		    ptr = ml_get(pos.lnum - 1);
+		    if (*ptr && *(ptr + STRLEN(ptr) - 1) == '\\')
+		    {
+			do_quotes = 1;
+			if (start_in_quotes == MAYBE)
+			{
+			    inquote = at_start;
+			    if (inquote)
+				start_in_quotes = TRUE;
+			}
+			else if (!backwards)
+			    inquote = TRUE;
+		    }
+		}
+	    }
+	}
+	if (start_in_quotes == MAYBE)
+	    start_in_quotes = FALSE;
+
+	/*
+	 * If 'smartmatch' is set:
+	 *   Things inside quotes are ignored by setting 'inquote'.  If we
+	 *   find a quote without a preceding '\' invert 'inquote'.  At the
+	 *   end of a line not ending in '\' we reset 'inquote'.
+	 *
+	 *   In lines with an uneven number of quotes (without preceding '\')
+	 *   we do not know which part to ignore. Therefore we only set
+	 *   inquote if the number of quotes in a line is even, unless this
+	 *   line or the previous one ends in a '\'.  Complicated, isn't it?
+	 */
+	switch (c = linep[pos.col])
+	{
+	case NUL:
+	    /* at end of line without trailing backslash, reset inquote */
+	    if (pos.col == 0 || linep[pos.col - 1] != '\\')
+	    {
+		inquote = FALSE;
+		start_in_quotes = FALSE;
+	    }
+	    break;
+
+	case '"':
+	    /* a quote that is preceded with an odd number of backslashes is
+	     * ignored */
+	    if (do_quotes)
+	    {
+		int col;
+
+		for (col = pos.col - 1; col >= 0; --col)
+		    if (linep[col] != '\\')
+			break;
+		if ((((int)pos.col - 1 - col) & 1) == 0)
+		{
+		    inquote = !inquote;
+		    start_in_quotes = FALSE;
+		}
+	    }
+	    break;
+
+	/*
+	 * If smart matching ('cpoptions' does not contain '%'):
+	 *   Skip things in single quotes: 'x' or '\x'.  Be careful for single
+	 *   single quotes, eg jon's.  Things like '\233' or '\x3f' are not
+	 *   skipped, there is never a brace in them.
+	 *   Ignore this when finding matches for `'.
+	 */
+	case '\'':
+	    if (!cpo_match && initc != '\'' && findc != '\'')
+	    {
+		if (backwards)
+		{
+		    if (pos.col > 1)
+		    {
+			if (linep[pos.col - 2] == '\'')
+			{
+			    pos.col -= 2;
+			    break;
+			}
+			else if (linep[pos.col - 2] == '\\' &&
+				    pos.col > 2 && linep[pos.col - 3] == '\'')
+			{
+			    pos.col -= 3;
+			    break;
+			}
+		    }
+		}
+		else if (linep[pos.col + 1])	/* forward search */
+		{
+		    if (linep[pos.col + 1] == '\\' &&
+			    linep[pos.col + 2] && linep[pos.col + 3] == '\'')
+		    {
+			pos.col += 3;
+			break;
+		    }
+		    else if (linep[pos.col + 2] == '\'')
+		    {
+			pos.col += 2;
+			break;
+		    }
+		}
+	    }
+	    /* FALLTHROUGH */
+
+	default:
+#ifdef FEAT_LISP
+	    /*
+	     * For Lisp skip over backslashed (), {} and [].
+	     * (actually, we skip #\( et al)
+	     */
+	    if (curbuf->b_p_lisp
+		    && vim_strchr((char_u *)"(){}[]", c) != NULL
+		    && pos.col > 1
+		    && check_prevcol(linep, pos.col, '\\', NULL)
+		    && check_prevcol(linep, pos.col - 1, '#', NULL))
+		break;
+#endif
+
+	    /* Check for match outside of quotes, and inside of
+	     * quotes when the start is also inside of quotes. */
+	    if ((!inquote || start_in_quotes == TRUE)
+		    && (c == initc || c == findc))
+	    {
+		int	col, bslcnt = 0;
+
+		if (!cpo_bsl)
+		{
+		    for (col = pos.col; check_prevcol(linep, col, '\\', &col);)
+			bslcnt++;
+		}
+		/* Only accept a match when 'M' is in 'cpo' or when ecaping is
+		 * what we expect. */
+		if (cpo_bsl || (bslcnt & 1) == match_escaped)
+		{
+		    if (c == initc)
+			count++;
+		    else
+		    {
+			if (count == 0)
+			    return &pos;
+			count--;
+		    }
+		}
+	    }
+	}
+    }
+
+    if (comment_dir == BACKWARD && count > 0)
+    {
+	pos = match_pos;
+	return &pos;
+    }
+    return (pos_T *)NULL;	/* never found it */
+}
+
+/*
+ * Check if line[] contains a / / comment.
+ * Return MAXCOL if not, otherwise return the column.
+ * TODO: skip strings.
+ */
+    static int
+check_linecomment(line)
+    char_u	*line;
+{
+    char_u  *p;
+
+    p = line;
+#ifdef FEAT_LISP
+    /* skip Lispish one-line comments */
+    if (curbuf->b_p_lisp)
+    {
+	if (vim_strchr(p, ';') != NULL) /* there may be comments */
+	{
+	    int instr = FALSE;	/* inside of string */
+
+	    p = line;		/* scan from start */
+	    while ((p = vim_strpbrk(p, (char_u *)"\";")) != NULL)
+	    {
+		if (*p == '"')
+		{
+		    if (instr)
+		    {
+			if (*(p - 1) != '\\') /* skip escaped quote */
+			    instr = FALSE;
+		    }
+		    else if (p == line || ((p - line) >= 2
+				      /* skip #\" form */
+				      && *(p - 1) != '\\' && *(p - 2) != '#'))
+			instr = TRUE;
+		}
+		else if (!instr && ((p - line) < 2
+				    || (*(p - 1) != '\\' && *(p - 2) != '#')))
+		    break;	/* found! */
+		++p;
+	    }
+	}
+	else
+	    p = NULL;
+    }
+    else
+#endif
+    while ((p = vim_strchr(p, '/')) != NULL)
+    {
+	if (p[1] == '/')
+	    break;
+	++p;
+    }
+
+    if (p == NULL)
+	return MAXCOL;
+    return (int)(p - line);
+}
+
+/*
+ * Move cursor briefly to character matching the one under the cursor.
+ * Used for Insert mode and "r" command.
+ * Show the match only if it is visible on the screen.
+ * If there isn't a match, then beep.
+ */
+    void
+showmatch(c)
+    int		c;	    /* char to show match for */
+{
+    pos_T	*lpos, save_cursor;
+    pos_T	mpos;
+    colnr_T	vcol;
+    long	save_so;
+    long	save_siso;
+#ifdef CURSOR_SHAPE
+    int		save_state;
+#endif
+    colnr_T	save_dollar_vcol;
+    char_u	*p;
+
+    /*
+     * Only show match for chars in the 'matchpairs' option.
+     */
+    /* 'matchpairs' is "x:y,x:y" */
+    for (p = curbuf->b_p_mps; *p != NUL; p += 2)
+    {
+#ifdef FEAT_RIGHTLEFT
+	if (*p == c && (curwin->w_p_rl ^ p_ri))
+	    break;
+#endif
+	p += 2;
+	if (*p == c
+#ifdef FEAT_RIGHTLEFT
+		&& !(curwin->w_p_rl ^ p_ri)
+#endif
+	   )
+	    break;
+	if (p[1] != ',')
+	    return;
+    }
+
+    if ((lpos = findmatch(NULL, NUL)) == NULL)	    /* no match, so beep */
+	vim_beep();
+    else if (lpos->lnum >= curwin->w_topline)
+    {
+	if (!curwin->w_p_wrap)
+	    getvcol(curwin, lpos, NULL, &vcol, NULL);
+	if (curwin->w_p_wrap || (vcol >= curwin->w_leftcol
+			       && vcol < curwin->w_leftcol + W_WIDTH(curwin)))
+	{
+	    mpos = *lpos;    /* save the pos, update_screen() may change it */
+	    save_cursor = curwin->w_cursor;
+	    save_so = p_so;
+	    save_siso = p_siso;
+	    /* Handle "$" in 'cpo': If the ')' is typed on top of the "$",
+	     * stop displaying the "$". */
+	    if (dollar_vcol > 0 && dollar_vcol == curwin->w_virtcol)
+		dollar_vcol = 0;
+	    ++curwin->w_virtcol;	/* do display ')' just before "$" */
+	    update_screen(VALID);	/* show the new char first */
+
+	    save_dollar_vcol = dollar_vcol;
+#ifdef CURSOR_SHAPE
+	    save_state = State;
+	    State = SHOWMATCH;
+	    ui_cursor_shape();		/* may show different cursor shape */
+#endif
+	    curwin->w_cursor = mpos;	/* move to matching char */
+	    p_so = 0;			/* don't use 'scrolloff' here */
+	    p_siso = 0;			/* don't use 'sidescrolloff' here */
+	    showruler(FALSE);
+	    setcursor();
+	    cursor_on();		/* make sure that the cursor is shown */
+	    out_flush();
+#ifdef FEAT_GUI
+	    if (gui.in_use)
+	    {
+		gui_update_cursor(TRUE, FALSE);
+		gui_mch_flush();
+	    }
+#endif
+	    /* Restore dollar_vcol(), because setcursor() may call curs_rows()
+	     * which resets it if the matching position is in a previous line
+	     * and has a higher column number. */
+	    dollar_vcol = save_dollar_vcol;
+
+	    /*
+	     * brief pause, unless 'm' is present in 'cpo' and a character is
+	     * available.
+	     */
+	    if (vim_strchr(p_cpo, CPO_SHOWMATCH) != NULL)
+		ui_delay(p_mat * 100L, TRUE);
+	    else if (!char_avail())
+		ui_delay(p_mat * 100L, FALSE);
+	    curwin->w_cursor = save_cursor;	/* restore cursor position */
+	    p_so = save_so;
+	    p_siso = save_siso;
+#ifdef CURSOR_SHAPE
+	    State = save_state;
+	    ui_cursor_shape();		/* may show different cursor shape */
+#endif
+	}
+    }
+}
+
+/*
+ * findsent(dir, count) - Find the start of the next sentence in direction
+ * "dir" Sentences are supposed to end in ".", "!" or "?" followed by white
+ * space or a line break. Also stop at an empty line.
+ * Return OK if the next sentence was found.
+ */
+    int
+findsent(dir, count)
+    int		dir;
+    long	count;
+{
+    pos_T	pos, tpos;
+    int		c;
+    int		(*func) __ARGS((pos_T *));
+    int		startlnum;
+    int		noskip = FALSE;	    /* do not skip blanks */
+    int		cpo_J;
+    int		found_dot;
+
+    pos = curwin->w_cursor;
+    if (dir == FORWARD)
+	func = incl;
+    else
+	func = decl;
+
+    while (count--)
+    {
+	/*
+	 * if on an empty line, skip upto a non-empty line
+	 */
+	if (gchar_pos(&pos) == NUL)
+	{
+	    do
+		if ((*func)(&pos) == -1)
+		    break;
+	    while (gchar_pos(&pos) == NUL);
+	    if (dir == FORWARD)
+		goto found;
+	}
+	/*
+	 * if on the start of a paragraph or a section and searching forward,
+	 * go to the next line
+	 */
+	else if (dir == FORWARD && pos.col == 0 &&
+						startPS(pos.lnum, NUL, FALSE))
+	{
+	    if (pos.lnum == curbuf->b_ml.ml_line_count)
+		return FAIL;
+	    ++pos.lnum;
+	    goto found;
+	}
+	else if (dir == BACKWARD)
+	    decl(&pos);
+
+	/* go back to the previous non-blank char */
+	found_dot = FALSE;
+	while ((c = gchar_pos(&pos)) == ' ' || c == '\t' ||
+	     (dir == BACKWARD && vim_strchr((char_u *)".!?)]\"'", c) != NULL))
+	{
+	    if (vim_strchr((char_u *)".!?", c) != NULL)
+	    {
+		/* Only skip over a '.', '!' and '?' once. */
+		if (found_dot)
+		    break;
+		found_dot = TRUE;
+	    }
+	    if (decl(&pos) == -1)
+		break;
+	    /* when going forward: Stop in front of empty line */
+	    if (lineempty(pos.lnum) && dir == FORWARD)
+	    {
+		incl(&pos);
+		goto found;
+	    }
+	}
+
+	/* remember the line where the search started */
+	startlnum = pos.lnum;
+	cpo_J = vim_strchr(p_cpo, CPO_ENDOFSENT) != NULL;
+
+	for (;;)		/* find end of sentence */
+	{
+	    c = gchar_pos(&pos);
+	    if (c == NUL || (pos.col == 0 && startPS(pos.lnum, NUL, FALSE)))
+	    {
+		if (dir == BACKWARD && pos.lnum != startlnum)
+		    ++pos.lnum;
+		break;
+	    }
+	    if (c == '.' || c == '!' || c == '?')
+	    {
+		tpos = pos;
+		do
+		    if ((c = inc(&tpos)) == -1)
+			break;
+		while (vim_strchr((char_u *)")]\"'", c = gchar_pos(&tpos))
+			!= NULL);
+		if (c == -1  || (!cpo_J && (c == ' ' || c == '\t')) || c == NUL
+		    || (cpo_J && (c == ' ' && inc(&tpos) >= 0
+			      && gchar_pos(&tpos) == ' ')))
+		{
+		    pos = tpos;
+		    if (gchar_pos(&pos) == NUL) /* skip NUL at EOL */
+			inc(&pos);
+		    break;
+		}
+	    }
+	    if ((*func)(&pos) == -1)
+	    {
+		if (count)
+		    return FAIL;
+		noskip = TRUE;
+		break;
+	    }
+	}
+found:
+	    /* skip white space */
+	while (!noskip && ((c = gchar_pos(&pos)) == ' ' || c == '\t'))
+	    if (incl(&pos) == -1)
+		break;
+    }
+
+    setpcmark();
+    curwin->w_cursor = pos;
+    return OK;
+}
+
+/*
+ * Find the next paragraph or section in direction 'dir'.
+ * Paragraphs are currently supposed to be separated by empty lines.
+ * If 'what' is NUL we go to the next paragraph.
+ * If 'what' is '{' or '}' we go to the next section.
+ * If 'both' is TRUE also stop at '}'.
+ * Return TRUE if the next paragraph or section was found.
+ */
+    int
+findpar(pincl, dir, count, what, both)
+    int		*pincl;	    /* Return: TRUE if last char is to be included */
+    int		dir;
+    long	count;
+    int		what;
+    int		both;
+{
+    linenr_T	curr;
+    int		did_skip;   /* TRUE after separating lines have been skipped */
+    int		first;	    /* TRUE on first line */
+    int		posix = (vim_strchr(p_cpo, CPO_PARA) != NULL);
+#ifdef FEAT_FOLDING
+    linenr_T	fold_first; /* first line of a closed fold */
+    linenr_T	fold_last;  /* last line of a closed fold */
+    int		fold_skipped; /* TRUE if a closed fold was skipped this
+				 iteration */
+#endif
+
+    curr = curwin->w_cursor.lnum;
+
+    while (count--)
+    {
+	did_skip = FALSE;
+	for (first = TRUE; ; first = FALSE)
+	{
+	    if (*ml_get(curr) != NUL)
+		did_skip = TRUE;
+
+#ifdef FEAT_FOLDING
+	    /* skip folded lines */
+	    fold_skipped = FALSE;
+	    if (first && hasFolding(curr, &fold_first, &fold_last))
+	    {
+		curr = ((dir > 0) ? fold_last : fold_first) + dir;
+		fold_skipped = TRUE;
+	    }
+#endif
+
+	    /* POSIX has it's own ideas of what a paragraph boundary is and it
+	     * doesn't match historical Vi: It also stops at a "{" in the
+	     * first column and at an empty line. */
+	    if (!first && did_skip && (startPS(curr, what, both)
+			   || (posix && what == NUL && *ml_get(curr) == '{')))
+		break;
+
+#ifdef FEAT_FOLDING
+	    if (fold_skipped)
+		curr -= dir;
+#endif
+	    if ((curr += dir) < 1 || curr > curbuf->b_ml.ml_line_count)
+	    {
+		if (count)
+		    return FALSE;
+		curr -= dir;
+		break;
+	    }
+	}
+    }
+    setpcmark();
+    if (both && *ml_get(curr) == '}')	/* include line with '}' */
+	++curr;
+    curwin->w_cursor.lnum = curr;
+    if (curr == curbuf->b_ml.ml_line_count && what != '}')
+    {
+	if ((curwin->w_cursor.col = (colnr_T)STRLEN(ml_get(curr))) != 0)
+	{
+	    --curwin->w_cursor.col;
+	    *pincl = TRUE;
+	}
+    }
+    else
+	curwin->w_cursor.col = 0;
+    return TRUE;
+}
+
+/*
+ * check if the string 's' is a nroff macro that is in option 'opt'
+ */
+    static int
+inmacro(opt, s)
+    char_u	*opt;
+    char_u	*s;
+{
+    char_u	*macro;
+
+    for (macro = opt; macro[0]; ++macro)
+    {
+	/* Accept two characters in the option being equal to two characters
+	 * in the line.  A space in the option matches with a space in the
+	 * line or the line having ended. */
+	if (       (macro[0] == s[0]
+		    || (macro[0] == ' '
+			&& (s[0] == NUL || s[0] == ' ')))
+		&& (macro[1] == s[1]
+		    || ((macro[1] == NUL || macro[1] == ' ')
+			&& (s[0] == NUL || s[1] == NUL || s[1] == ' '))))
+	    break;
+	++macro;
+	if (macro[0] == NUL)
+	    break;
+    }
+    return (macro[0] != NUL);
+}
+
+/*
+ * startPS: return TRUE if line 'lnum' is the start of a section or paragraph.
+ * If 'para' is '{' or '}' only check for sections.
+ * If 'both' is TRUE also stop at '}'
+ */
+    int
+startPS(lnum, para, both)
+    linenr_T	lnum;
+    int		para;
+    int		both;
+{
+    char_u	*s;
+
+    s = ml_get(lnum);
+    if (*s == para || *s == '\f' || (both && *s == '}'))
+	return TRUE;
+    if (*s == '.' && (inmacro(p_sections, s + 1) ||
+					   (!para && inmacro(p_para, s + 1))))
+	return TRUE;
+    return FALSE;
+}
+
+/*
+ * The following routines do the word searches performed by the 'w', 'W',
+ * 'b', 'B', 'e', and 'E' commands.
+ */
+
+/*
+ * To perform these searches, characters are placed into one of three
+ * classes, and transitions between classes determine word boundaries.
+ *
+ * The classes are:
+ *
+ * 0 - white space
+ * 1 - punctuation
+ * 2 or higher - keyword characters (letters, digits and underscore)
+ */
+
+static int	cls_bigword;	/* TRUE for "W", "B" or "E" */
+
+/*
+ * cls() - returns the class of character at curwin->w_cursor
+ *
+ * If a 'W', 'B', or 'E' motion is being done (cls_bigword == TRUE), chars
+ * from class 2 and higher are reported as class 1 since only white space
+ * boundaries are of interest.
+ */
+    static int
+cls()
+{
+    int	    c;
+
+    c = gchar_cursor();
+#ifdef FEAT_FKMAP	/* when 'akm' (Farsi mode), take care of Farsi blank */
+    if (p_altkeymap && c == F_BLANK)
+	return 0;
+#endif
+    if (c == ' ' || c == '\t' || c == NUL)
+	return 0;
+#ifdef FEAT_MBYTE
+    if (enc_dbcs != 0 && c > 0xFF)
+    {
+	/* If cls_bigword, report multi-byte chars as class 1. */
+	if (enc_dbcs == DBCS_KOR && cls_bigword)
+	    return 1;
+
+	/* process code leading/trailing bytes */
+	return dbcs_class(((unsigned)c >> 8), (c & 0xFF));
+    }
+    if (enc_utf8)
+    {
+	c = utf_class(c);
+	if (c != 0 && cls_bigword)
+	    return 1;
+	return c;
+    }
+#endif
+
+    /* If cls_bigword is TRUE, report all non-blanks as class 1. */
+    if (cls_bigword)
+	return 1;
+
+    if (vim_iswordc(c))
+	return 2;
+    return 1;
+}
+
+
+/*
+ * fwd_word(count, type, eol) - move forward one word
+ *
+ * Returns FAIL if the cursor was already at the end of the file.
+ * If eol is TRUE, last word stops at end of line (for operators).
+ */
+    int
+fwd_word(count, bigword, eol)
+    long	count;
+    int		bigword;    /* "W", "E" or "B" */
+    int		eol;
+{
+    int		sclass;	    /* starting class */
+    int		i;
+    int		last_line;
+
+#ifdef FEAT_VIRTUALEDIT
+    curwin->w_cursor.coladd = 0;
+#endif
+    cls_bigword = bigword;
+    while (--count >= 0)
+    {
+#ifdef FEAT_FOLDING
+	/* When inside a range of folded lines, move to the last char of the
+	 * last line. */
+	if (hasFolding(curwin->w_cursor.lnum, NULL, &curwin->w_cursor.lnum))
+	    coladvance((colnr_T)MAXCOL);
+#endif
+	sclass = cls();
+
+	/*
+	 * We always move at least one character, unless on the last
+	 * character in the buffer.
+	 */
+	last_line = (curwin->w_cursor.lnum == curbuf->b_ml.ml_line_count);
+	i = inc_cursor();
+	if (i == -1 || (i >= 1 && last_line)) /* started at last char in file */
+	    return FAIL;
+	if (i == 1 && eol && count == 0)      /* started at last char in line */
+	    return OK;
+
+	/*
+	 * Go one char past end of current word (if any)
+	 */
+	if (sclass != 0)
+	    while (cls() == sclass)
+	    {
+		i = inc_cursor();
+		if (i == -1 || (i >= 1 && eol && count == 0))
+		    return OK;
+	    }
+
+	/*
+	 * go to next non-white
+	 */
+	while (cls() == 0)
+	{
+	    /*
+	     * We'll stop if we land on a blank line
+	     */
+	    if (curwin->w_cursor.col == 0 && *ml_get_curline() == NUL)
+		break;
+
+	    i = inc_cursor();
+	    if (i == -1 || (i >= 1 && eol && count == 0))
+		return OK;
+	}
+    }
+    return OK;
+}
+
+/*
+ * bck_word() - move backward 'count' words
+ *
+ * If stop is TRUE and we are already on the start of a word, move one less.
+ *
+ * Returns FAIL if top of the file was reached.
+ */
+    int
+bck_word(count, bigword, stop)
+    long	count;
+    int		bigword;
+    int		stop;
+{
+    int		sclass;	    /* starting class */
+
+#ifdef FEAT_VIRTUALEDIT
+    curwin->w_cursor.coladd = 0;
+#endif
+    cls_bigword = bigword;
+    while (--count >= 0)
+    {
+#ifdef FEAT_FOLDING
+	/* When inside a range of folded lines, move to the first char of the
+	 * first line. */
+	if (hasFolding(curwin->w_cursor.lnum, &curwin->w_cursor.lnum, NULL))
+	    curwin->w_cursor.col = 0;
+#endif
+	sclass = cls();
+	if (dec_cursor() == -1)		/* started at start of file */
+	    return FAIL;
+
+	if (!stop || sclass == cls() || sclass == 0)
+	{
+	    /*
+	     * Skip white space before the word.
+	     * Stop on an empty line.
+	     */
+	    while (cls() == 0)
+	    {
+		if (curwin->w_cursor.col == 0
+				      && lineempty(curwin->w_cursor.lnum))
+		    goto finished;
+		if (dec_cursor() == -1) /* hit start of file, stop here */
+		    return OK;
+	    }
+
+	    /*
+	     * Move backward to start of this word.
+	     */
+	    if (skip_chars(cls(), BACKWARD))
+		return OK;
+	}
+
+	inc_cursor();			/* overshot - forward one */
+finished:
+	stop = FALSE;
+    }
+    return OK;
+}
+
+/*
+ * end_word() - move to the end of the word
+ *
+ * There is an apparent bug in the 'e' motion of the real vi. At least on the
+ * System V Release 3 version for the 80386. Unlike 'b' and 'w', the 'e'
+ * motion crosses blank lines. When the real vi crosses a blank line in an
+ * 'e' motion, the cursor is placed on the FIRST character of the next
+ * non-blank line. The 'E' command, however, works correctly. Since this
+ * appears to be a bug, I have not duplicated it here.
+ *
+ * Returns FAIL if end of the file was reached.
+ *
+ * If stop is TRUE and we are already on the end of a word, move one less.
+ * If empty is TRUE stop on an empty line.
+ */
+    int
+end_word(count, bigword, stop, empty)
+    long	count;
+    int		bigword;
+    int		stop;
+    int		empty;
+{
+    int		sclass;	    /* starting class */
+
+#ifdef FEAT_VIRTUALEDIT
+    curwin->w_cursor.coladd = 0;
+#endif
+    cls_bigword = bigword;
+    while (--count >= 0)
+    {
+#ifdef FEAT_FOLDING
+	/* When inside a range of folded lines, move to the last char of the
+	 * last line. */
+	if (hasFolding(curwin->w_cursor.lnum, NULL, &curwin->w_cursor.lnum))
+	    coladvance((colnr_T)MAXCOL);
+#endif
+	sclass = cls();
+	if (inc_cursor() == -1)
+	    return FAIL;
+
+	/*
+	 * If we're in the middle of a word, we just have to move to the end
+	 * of it.
+	 */
+	if (cls() == sclass && sclass != 0)
+	{
+	    /*
+	     * Move forward to end of the current word
+	     */
+	    if (skip_chars(sclass, FORWARD))
+		return FAIL;
+	}
+	else if (!stop || sclass == 0)
+	{
+	    /*
+	     * We were at the end of a word. Go to the end of the next word.
+	     * First skip white space, if 'empty' is TRUE, stop at empty line.
+	     */
+	    while (cls() == 0)
+	    {
+		if (empty && curwin->w_cursor.col == 0
+					  && lineempty(curwin->w_cursor.lnum))
+		    goto finished;
+		if (inc_cursor() == -1)	    /* hit end of file, stop here */
+		    return FAIL;
+	    }
+
+	    /*
+	     * Move forward to the end of this word.
+	     */
+	    if (skip_chars(cls(), FORWARD))
+		return FAIL;
+	}
+	dec_cursor();			/* overshot - one char backward */
+finished:
+	stop = FALSE;			/* we move only one word less */
+    }
+    return OK;
+}
+
+/*
+ * Move back to the end of the word.
+ *
+ * Returns FAIL if start of the file was reached.
+ */
+    int
+bckend_word(count, bigword, eol)
+    long	count;
+    int		bigword;    /* TRUE for "B" */
+    int		eol;	    /* TRUE: stop at end of line. */
+{
+    int		sclass;	    /* starting class */
+    int		i;
+
+#ifdef FEAT_VIRTUALEDIT
+    curwin->w_cursor.coladd = 0;
+#endif
+    cls_bigword = bigword;
+    while (--count >= 0)
+    {
+	sclass = cls();
+	if ((i = dec_cursor()) == -1)
+	    return FAIL;
+	if (eol && i == 1)
+	    return OK;
+
+	/*
+	 * Move backward to before the start of this word.
+	 */
+	if (sclass != 0)
+	{
+	    while (cls() == sclass)
+		if ((i = dec_cursor()) == -1 || (eol && i == 1))
+		    return OK;
+	}
+
+	/*
+	 * Move backward to end of the previous word
+	 */
+	while (cls() == 0)
+	{
+	    if (curwin->w_cursor.col == 0 && lineempty(curwin->w_cursor.lnum))
+		break;
+	    if ((i = dec_cursor()) == -1 || (eol && i == 1))
+		return OK;
+	}
+    }
+    return OK;
+}
+
+/*
+ * Skip a row of characters of the same class.
+ * Return TRUE when end-of-file reached, FALSE otherwise.
+ */
+    static int
+skip_chars(cclass, dir)
+    int		cclass;
+    int		dir;
+{
+    while (cls() == cclass)
+	if ((dir == FORWARD ? inc_cursor() : dec_cursor()) == -1)
+	    return TRUE;
+    return FALSE;
+}
+
+#ifdef FEAT_TEXTOBJ
+/*
+ * Go back to the start of the word or the start of white space
+ */
+    static void
+back_in_line()
+{
+    int		sclass;		    /* starting class */
+
+    sclass = cls();
+    for (;;)
+    {
+	if (curwin->w_cursor.col == 0)	    /* stop at start of line */
+	    break;
+	dec_cursor();
+	if (cls() != sclass)		    /* stop at start of word */
+	{
+	    inc_cursor();
+	    break;
+	}
+    }
+}
+
+    static void
+find_first_blank(posp)
+    pos_T    *posp;
+{
+    int	    c;
+
+    while (decl(posp) != -1)
+    {
+	c = gchar_pos(posp);
+	if (!vim_iswhite(c))
+	{
+	    incl(posp);
+	    break;
+	}
+    }
+}
+
+/*
+ * Skip count/2 sentences and count/2 separating white spaces.
+ */
+    static void
+findsent_forward(count, at_start_sent)
+    long    count;
+    int	    at_start_sent;	/* cursor is at start of sentence */
+{
+    while (count--)
+    {
+	findsent(FORWARD, 1L);
+	if (at_start_sent)
+	    find_first_blank(&curwin->w_cursor);
+	if (count == 0 || at_start_sent)
+	    decl(&curwin->w_cursor);
+	at_start_sent = !at_start_sent;
+    }
+}
+
+/*
+ * Find word under cursor, cursor at end.
+ * Used while an operator is pending, and in Visual mode.
+ */
+    int
+current_word(oap, count, include, bigword)
+    oparg_T	*oap;
+    long	count;
+    int		include;	/* TRUE: include word and white space */
+    int		bigword;	/* FALSE == word, TRUE == WORD */
+{
+    pos_T	start_pos;
+    pos_T	pos;
+    int		inclusive = TRUE;
+    int		include_white = FALSE;
+
+    cls_bigword = bigword;
+    clearpos(&start_pos);
+
+#ifdef FEAT_VISUAL
+    /* Correct cursor when 'selection' is exclusive */
+    if (VIsual_active && *p_sel == 'e' && lt(VIsual, curwin->w_cursor))
+	dec_cursor();
+
+    /*
+     * When Visual mode is not active, or when the VIsual area is only one
+     * character, select the word and/or white space under the cursor.
+     */
+    if (!VIsual_active || equalpos(curwin->w_cursor, VIsual))
+#endif
+    {
+	/*
+	 * Go to start of current word or white space.
+	 */
+	back_in_line();
+	start_pos = curwin->w_cursor;
+
+	/*
+	 * If the start is on white space, and white space should be included
+	 * ("	word"), or start is not on white space, and white space should
+	 * not be included ("word"), find end of word.
+	 */
+	if ((cls() == 0) == include)
+	{
+	    if (end_word(1L, bigword, TRUE, TRUE) == FAIL)
+		return FAIL;
+	}
+	else
+	{
+	    /*
+	     * If the start is not on white space, and white space should be
+	     * included ("word	 "), or start is on white space and white
+	     * space should not be included ("	 "), find start of word.
+	     * If we end up in the first column of the next line (single char
+	     * word) back up to end of the line.
+	     */
+	    fwd_word(1L, bigword, TRUE);
+	    if (curwin->w_cursor.col == 0)
+		decl(&curwin->w_cursor);
+	    else
+		oneleft();
+
+	    if (include)
+		include_white = TRUE;
+	}
+
+#ifdef FEAT_VISUAL
+	if (VIsual_active)
+	{
+	    /* should do something when inclusive == FALSE ! */
+	    VIsual = start_pos;
+	    redraw_curbuf_later(INVERTED);	/* update the inversion */
+	}
+	else
+#endif
+	{
+	    oap->start = start_pos;
+	    oap->motion_type = MCHAR;
+	}
+	--count;
+    }
+
+    /*
+     * When count is still > 0, extend with more objects.
+     */
+    while (count > 0)
+    {
+	inclusive = TRUE;
+#ifdef FEAT_VISUAL
+	if (VIsual_active && lt(curwin->w_cursor, VIsual))
+	{
+	    /*
+	     * In Visual mode, with cursor at start: move cursor back.
+	     */
+	    if (decl(&curwin->w_cursor) == -1)
+		return FAIL;
+	    if (include != (cls() != 0))
+	    {
+		if (bck_word(1L, bigword, TRUE) == FAIL)
+		    return FAIL;
+	    }
+	    else
+	    {
+		if (bckend_word(1L, bigword, TRUE) == FAIL)
+		    return FAIL;
+		(void)incl(&curwin->w_cursor);
+	    }
+	}
+	else
+#endif
+	{
+	    /*
+	     * Move cursor forward one word and/or white area.
+	     */
+	    if (incl(&curwin->w_cursor) == -1)
+		return FAIL;
+	    if (include != (cls() == 0))
+	    {
+		if (fwd_word(1L, bigword, TRUE) == FAIL && count > 1)
+		    return FAIL;
+		/*
+		 * If end is just past a new-line, we don't want to include
+		 * the first character on the line.
+		 * Put cursor on last char of white.
+		 */
+		if (oneleft() == FAIL)
+		    inclusive = FALSE;
+	    }
+	    else
+	    {
+		if (end_word(1L, bigword, TRUE, TRUE) == FAIL)
+		    return FAIL;
+	    }
+	}
+	--count;
+    }
+
+    if (include_white && (cls() != 0
+		 || (curwin->w_cursor.col == 0 && !inclusive)))
+    {
+	/*
+	 * If we don't include white space at the end, move the start
+	 * to include some white space there. This makes "daw" work
+	 * better on the last word in a sentence (and "2daw" on last-but-one
+	 * word).  Also when "2daw" deletes "word." at the end of the line
+	 * (cursor is at start of next line).
+	 * But don't delete white space at start of line (indent).
+	 */
+	pos = curwin->w_cursor;	/* save cursor position */
+	curwin->w_cursor = start_pos;
+	if (oneleft() == OK)
+	{
+	    back_in_line();
+	    if (cls() == 0 && curwin->w_cursor.col > 0)
+	    {
+#ifdef FEAT_VISUAL
+		if (VIsual_active)
+		    VIsual = curwin->w_cursor;
+		else
+#endif
+		    oap->start = curwin->w_cursor;
+	    }
+	}
+	curwin->w_cursor = pos;	/* put cursor back at end */
+    }
+
+#ifdef FEAT_VISUAL
+    if (VIsual_active)
+    {
+	if (*p_sel == 'e' && inclusive && ltoreq(VIsual, curwin->w_cursor))
+	    inc_cursor();
+	if (VIsual_mode == 'V')
+	{
+	    VIsual_mode = 'v';
+	    redraw_cmdline = TRUE;		/* show mode later */
+	}
+    }
+    else
+#endif
+	oap->inclusive = inclusive;
+
+    return OK;
+}
+
+/*
+ * Find sentence(s) under the cursor, cursor at end.
+ * When Visual active, extend it by one or more sentences.
+ */
+    int
+current_sent(oap, count, include)
+    oparg_T	*oap;
+    long	count;
+    int		include;
+{
+    pos_T	start_pos;
+    pos_T	pos;
+    int		start_blank;
+    int		c;
+    int		at_start_sent;
+    long	ncount;
+
+    start_pos = curwin->w_cursor;
+    pos = start_pos;
+    findsent(FORWARD, 1L);	/* Find start of next sentence. */
+
+#ifdef FEAT_VISUAL
+    /*
+     * When visual area is bigger than one character: Extend it.
+     */
+    if (VIsual_active && !equalpos(start_pos, VIsual))
+    {
+extend:
+	if (lt(start_pos, VIsual))
+	{
+	    /*
+	     * Cursor at start of Visual area.
+	     * Find out where we are:
+	     * - in the white space before a sentence
+	     * - in a sentence or just after it
+	     * - at the start of a sentence
+	     */
+	    at_start_sent = TRUE;
+	    decl(&pos);
+	    while (lt(pos, curwin->w_cursor))
+	    {
+		c = gchar_pos(&pos);
+		if (!vim_iswhite(c))
+		{
+		    at_start_sent = FALSE;
+		    break;
+		}
+		incl(&pos);
+	    }
+	    if (!at_start_sent)
+	    {
+		findsent(BACKWARD, 1L);
+		if (equalpos(curwin->w_cursor, start_pos))
+		    at_start_sent = TRUE;  /* exactly at start of sentence */
+		else
+		    /* inside a sentence, go to its end (start of next) */
+		    findsent(FORWARD, 1L);
+	    }
+	    if (include)	/* "as" gets twice as much as "is" */
+		count *= 2;
+	    while (count--)
+	    {
+		if (at_start_sent)
+		    find_first_blank(&curwin->w_cursor);
+		c = gchar_cursor();
+		if (!at_start_sent || (!include && !vim_iswhite(c)))
+		    findsent(BACKWARD, 1L);
+		at_start_sent = !at_start_sent;
+	    }
+	}
+	else
+	{
+	    /*
+	     * Cursor at end of Visual area.
+	     * Find out where we are:
+	     * - just before a sentence
+	     * - just before or in the white space before a sentence
+	     * - in a sentence
+	     */
+	    incl(&pos);
+	    at_start_sent = TRUE;
+	    if (!equalpos(pos, curwin->w_cursor)) /* not just before a sentence */
+	    {
+		at_start_sent = FALSE;
+		while (lt(pos, curwin->w_cursor))
+		{
+		    c = gchar_pos(&pos);
+		    if (!vim_iswhite(c))
+		    {
+			at_start_sent = TRUE;
+			break;
+		    }
+		    incl(&pos);
+		}
+		if (at_start_sent)	/* in the sentence */
+		    findsent(BACKWARD, 1L);
+		else		/* in/before white before a sentence */
+		    curwin->w_cursor = start_pos;
+	    }
+
+	    if (include)	/* "as" gets twice as much as "is" */
+		count *= 2;
+	    findsent_forward(count, at_start_sent);
+	    if (*p_sel == 'e')
+		++curwin->w_cursor.col;
+	}
+	return OK;
+    }
+#endif
+
+    /*
+     * If cursor started on blank, check if it is just before the start of the
+     * next sentence.
+     */
+    while (c = gchar_pos(&pos), vim_iswhite(c))	/* vim_iswhite() is a macro */
+	incl(&pos);
+    if (equalpos(pos, curwin->w_cursor))
+    {
+	start_blank = TRUE;
+	find_first_blank(&start_pos);	/* go back to first blank */
+    }
+    else
+    {
+	start_blank = FALSE;
+	findsent(BACKWARD, 1L);
+	start_pos = curwin->w_cursor;
+    }
+    if (include)
+	ncount = count * 2;
+    else
+    {
+	ncount = count;
+	if (start_blank)
+	    --ncount;
+    }
+    if (ncount > 0)
+	findsent_forward(ncount, TRUE);
+    else
+	decl(&curwin->w_cursor);
+
+    if (include)
+    {
+	/*
+	 * If the blank in front of the sentence is included, exclude the
+	 * blanks at the end of the sentence, go back to the first blank.
+	 * If there are no trailing blanks, try to include leading blanks.
+	 */
+	if (start_blank)
+	{
+	    find_first_blank(&curwin->w_cursor);
+	    c = gchar_pos(&curwin->w_cursor);	/* vim_iswhite() is a macro */
+	    if (vim_iswhite(c))
+		decl(&curwin->w_cursor);
+	}
+	else if (c = gchar_cursor(), !vim_iswhite(c))
+	    find_first_blank(&start_pos);
+    }
+
+#ifdef FEAT_VISUAL
+    if (VIsual_active)
+    {
+	/* avoid getting stuck with "is" on a single space before a sent. */
+	if (equalpos(start_pos, curwin->w_cursor))
+	    goto extend;
+	if (*p_sel == 'e')
+	    ++curwin->w_cursor.col;
+	VIsual = start_pos;
+	VIsual_mode = 'v';
+	redraw_curbuf_later(INVERTED);	/* update the inversion */
+    }
+    else
+#endif
+    {
+	/* include a newline after the sentence, if there is one */
+	if (incl(&curwin->w_cursor) == -1)
+	    oap->inclusive = TRUE;
+	else
+	    oap->inclusive = FALSE;
+	oap->start = start_pos;
+	oap->motion_type = MCHAR;
+    }
+    return OK;
+}
+
+/*
+ * Find block under the cursor, cursor at end.
+ * "what" and "other" are two matching parenthesis/paren/etc.
+ */
+    int
+current_block(oap, count, include, what, other)
+    oparg_T	*oap;
+    long	count;
+    int		include;	/* TRUE == include white space */
+    int		what;		/* '(', '{', etc. */
+    int		other;		/* ')', '}', etc. */
+{
+    pos_T	old_pos;
+    pos_T	*pos = NULL;
+    pos_T	start_pos;
+    pos_T	*end_pos;
+    pos_T	old_start, old_end;
+    char_u	*save_cpo;
+    int		sol = FALSE;		/* '{' at start of line */
+
+    old_pos = curwin->w_cursor;
+    old_end = curwin->w_cursor;		/* remember where we started */
+    old_start = old_end;
+
+    /*
+     * If we start on '(', '{', ')', '}', etc., use the whole block inclusive.
+     */
+#ifdef FEAT_VISUAL
+    if (!VIsual_active || equalpos(VIsual, curwin->w_cursor))
+#endif
+    {
+	setpcmark();
+	if (what == '{')		/* ignore indent */
+	    while (inindent(1))
+		if (inc_cursor() != 0)
+		    break;
+	if (gchar_cursor() == what)
+	    /* cursor on '(' or '{', move cursor just after it */
+	    ++curwin->w_cursor.col;
+    }
+#ifdef FEAT_VISUAL
+    else if (lt(VIsual, curwin->w_cursor))
+    {
+	old_start = VIsual;
+	curwin->w_cursor = VIsual;	    /* cursor at low end of Visual */
+    }
+    else
+	old_end = VIsual;
+#endif
+
+    /*
+     * Search backwards for unclosed '(', '{', etc..
+     * Put this position in start_pos.
+     * Ignore quotes here.
+     */
+    save_cpo = p_cpo;
+    p_cpo = (char_u *)"%";
+    while (count-- > 0)
+    {
+	if ((pos = findmatch(NULL, what)) == NULL)
+	    break;
+	curwin->w_cursor = *pos;
+	start_pos = *pos;   /* the findmatch for end_pos will overwrite *pos */
+    }
+    p_cpo = save_cpo;
+
+    /*
+     * Search for matching ')', '}', etc.
+     * Put this position in curwin->w_cursor.
+     */
+    if (pos == NULL || (end_pos = findmatch(NULL, other)) == NULL)
+    {
+	curwin->w_cursor = old_pos;
+	return FAIL;
+    }
+    curwin->w_cursor = *end_pos;
+
+    /*
+     * Try to exclude the '(', '{', ')', '}', etc. when "include" is FALSE.
+     * If the ending '}' is only preceded by indent, skip that indent.
+     * But only if the resulting area is not smaller than what we started with.
+     */
+    while (!include)
+    {
+	incl(&start_pos);
+	sol = (curwin->w_cursor.col == 0);
+	decl(&curwin->w_cursor);
+	if (what == '{')
+	    while (inindent(1))
+	    {
+		sol = TRUE;
+		if (decl(&curwin->w_cursor) != 0)
+		    break;
+	    }
+#ifdef FEAT_VISUAL
+	/*
+	 * In Visual mode, when the resulting area is not bigger than what we
+	 * started with, extend it to the next block, and then exclude again.
+	 */
+	if (!lt(start_pos, old_start) && !lt(old_end, curwin->w_cursor)
+		&& VIsual_active)
+	{
+	    curwin->w_cursor = old_start;
+	    decl(&curwin->w_cursor);
+	    if ((pos = findmatch(NULL, what)) == NULL)
+	    {
+		curwin->w_cursor = old_pos;
+		return FAIL;
+	    }
+	    start_pos = *pos;
+	    curwin->w_cursor = *pos;
+	    if ((end_pos = findmatch(NULL, other)) == NULL)
+	    {
+		curwin->w_cursor = old_pos;
+		return FAIL;
+	    }
+	    curwin->w_cursor = *end_pos;
+	}
+	else
+#endif
+	    break;
+    }
+
+#ifdef FEAT_VISUAL
+    if (VIsual_active)
+    {
+	if (*p_sel == 'e')
+	    ++curwin->w_cursor.col;
+	if (sol && gchar_cursor() != NUL)
+	    inc(&curwin->w_cursor);	/* include the line break */
+	VIsual = start_pos;
+	VIsual_mode = 'v';
+	redraw_curbuf_later(INVERTED);	/* update the inversion */
+	showmode();
+    }
+    else
+#endif
+    {
+	oap->start = start_pos;
+	oap->motion_type = MCHAR;
+	if (sol)
+	{
+	    incl(&curwin->w_cursor);
+	    oap->inclusive = FALSE;
+	}
+	else
+	    oap->inclusive = TRUE;
+    }
+
+    return OK;
+}
+
+static int in_html_tag __ARGS((int));
+
+/*
+ * Return TRUE if the cursor is on a "<aaa>" tag.  Ignore "<aaa/>".
+ * When "end_tag" is TRUE return TRUE if the cursor is on "</aaa>".
+ */
+    static int
+in_html_tag(end_tag)
+    int		end_tag;
+{
+    char_u	*line = ml_get_curline();
+    char_u	*p;
+    int		c;
+    int		lc = NUL;
+    pos_T	pos;
+
+#ifdef FEAT_MBYTE
+    if (enc_dbcs)
+    {
+	char_u	*lp = NULL;
+
+	/* We search forward until the cursor, because searching backwards is
+	 * very slow for DBCS encodings. */
+	for (p = line; p < line + curwin->w_cursor.col; mb_ptr_adv(p))
+	    if (*p == '>' || *p == '<')
+	    {
+		lc = *p;
+		lp = p;
+	    }
+	if (*p != '<')	    /* check for '<' under cursor */
+	{
+	    if (lc != '<')
+		return FALSE;
+	    p = lp;
+	}
+    }
+    else
+#endif
+    {
+	for (p = line + curwin->w_cursor.col; p > line; )
+	{
+	    if (*p == '<')	/* find '<' under/before cursor */
+		break;
+	    mb_ptr_back(line, p);
+	    if (*p == '>')	/* find '>' before cursor */
+		break;
+	}
+	if (*p != '<')
+	    return FALSE;
+    }
+
+    pos.lnum = curwin->w_cursor.lnum;
+    pos.col = (colnr_T)(p - line);
+
+    mb_ptr_adv(p);
+    if (end_tag)
+	/* check that there is a '/' after the '<' */
+	return *p == '/';
+
+    /* check that there is no '/' after the '<' */
+    if (*p == '/')
+	return FALSE;
+
+    /* check that the matching '>' is not preceded by '/' */
+    for (;;)
+    {
+	if (inc(&pos) < 0)
+	    return FALSE;
+	c = *ml_get_pos(&pos);
+	if (c == '>')
+	    break;
+	lc = c;
+    }
+    return lc != '/';
+}
+
+/*
+ * Find tag block under the cursor, cursor at end.
+ */
+    int
+current_tagblock(oap, count_arg, include)
+    oparg_T	*oap;
+    long	count_arg;
+    int		include;	/* TRUE == include white space */
+{
+    long	count = count_arg;
+    long	n;
+    pos_T	old_pos;
+    pos_T	start_pos;
+    pos_T	end_pos;
+    pos_T	old_start, old_end;
+    char_u	*spat, *epat;
+    char_u	*p;
+    char_u	*cp;
+    int		len;
+    int		r;
+    int		do_include = include;
+    int		save_p_ws = p_ws;
+    int		retval = FAIL;
+
+    p_ws = FALSE;
+
+    old_pos = curwin->w_cursor;
+    old_end = curwin->w_cursor;		    /* remember where we started */
+    old_start = old_end;
+
+    /*
+     * If we start on "<aaa>" select that block.
+     */
+#ifdef FEAT_VISUAL
+    if (!VIsual_active || equalpos(VIsual, curwin->w_cursor))
+#endif
+    {
+	setpcmark();
+
+	/* ignore indent */
+	while (inindent(1))
+	    if (inc_cursor() != 0)
+		break;
+
+	if (in_html_tag(FALSE))
+	{
+	    /* cursor on start tag, move to just after it */
+	    while (*ml_get_cursor() != '>')
+		if (inc_cursor() < 0)
+		    break;
+	}
+	else if (in_html_tag(TRUE))
+	{
+	    /* cursor on end tag, move to just before it */
+	    while (*ml_get_cursor() != '<')
+		if (dec_cursor() < 0)
+		    break;
+	    dec_cursor();
+	    old_end = curwin->w_cursor;
+	}
+    }
+#ifdef FEAT_VISUAL
+    else if (lt(VIsual, curwin->w_cursor))
+    {
+	old_start = VIsual;
+	curwin->w_cursor = VIsual;	    /* cursor at low end of Visual */
+    }
+    else
+	old_end = VIsual;
+#endif
+
+again:
+    /*
+     * Search backwards for unclosed "<aaa>".
+     * Put this position in start_pos.
+     */
+    for (n = 0; n < count; ++n)
+    {
+	if (do_searchpair((char_u *)"<[^ \t>/!]\\+\\%(\\_s\\_[^>]\\{-}[^/]>\\|$\\|\\_s\\=>\\)",
+		    (char_u *)"",
+		    (char_u *)"</[^>]*>", BACKWARD, (char_u *)"", 0,
+						      NULL, (linenr_T)0) <= 0)
+	{
+	    curwin->w_cursor = old_pos;
+	    goto theend;
+	}
+    }
+    start_pos = curwin->w_cursor;
+
+    /*
+     * Search for matching "</aaa>".  First isolate the "aaa".
+     */
+    inc_cursor();
+    p = ml_get_cursor();
+    for (cp = p; *cp != NUL && *cp != '>' && !vim_iswhite(*cp); mb_ptr_adv(cp))
+	;
+    len = (int)(cp - p);
+    if (len == 0)
+    {
+	curwin->w_cursor = old_pos;
+	goto theend;
+    }
+    spat = alloc(len + 29);
+    epat = alloc(len + 9);
+    if (spat == NULL || epat == NULL)
+    {
+	vim_free(spat);
+	vim_free(epat);
+	curwin->w_cursor = old_pos;
+	goto theend;
+    }
+    sprintf((char *)spat, "<%.*s\\%%(\\_[^>]\\{-}[^/]>\\|>\\)\\c", len, p);
+    sprintf((char *)epat, "</%.*s>\\c", len, p);
+
+    r = do_searchpair(spat, (char_u *)"", epat, FORWARD, (char_u *)"",
+						       0, NULL, (linenr_T)0);
+
+    vim_free(spat);
+    vim_free(epat);
+
+    if (r < 1 || lt(curwin->w_cursor, old_end))
+    {
+	/* Can't find other end or it's before the previous end.  Could be a
+	 * HTML tag that doesn't have a matching end.  Search backwards for
+	 * another starting tag. */
+	count = 1;
+	curwin->w_cursor = start_pos;
+	goto again;
+    }
+
+    if (do_include || r < 1)
+    {
+	/* Include up to the '>'. */
+	while (*ml_get_cursor() != '>')
+	    if (inc_cursor() < 0)
+		break;
+    }
+    else
+    {
+	/* Exclude the '<' of the end tag. */
+	if (*ml_get_cursor() == '<')
+	    dec_cursor();
+    }
+    end_pos = curwin->w_cursor;
+
+    if (!do_include)
+    {
+	/* Exclude the start tag. */
+	curwin->w_cursor = start_pos;
+	while (inc_cursor() >= 0)
+	    if (*ml_get_cursor() == '>' && lt(curwin->w_cursor, end_pos))
+	    {
+		inc_cursor();
+		start_pos = curwin->w_cursor;
+		break;
+	    }
+	curwin->w_cursor = end_pos;
+
+	/* If we now have the same text as before reset "do_include" and try
+	 * again. */
+	if (equalpos(start_pos, old_start) && equalpos(end_pos, old_end))
+	{
+	    do_include = TRUE;
+	    curwin->w_cursor = old_start;
+	    count = count_arg;
+	    goto again;
+	}
+    }
+
+#ifdef FEAT_VISUAL
+    if (VIsual_active)
+    {
+	if (*p_sel == 'e')
+	    ++curwin->w_cursor.col;
+	VIsual = start_pos;
+	VIsual_mode = 'v';
+	redraw_curbuf_later(INVERTED);	/* update the inversion */
+	showmode();
+    }
+    else
+#endif
+    {
+	oap->start = start_pos;
+	oap->motion_type = MCHAR;
+	oap->inclusive = TRUE;
+    }
+    retval = OK;
+
+theend:
+    p_ws = save_p_ws;
+    return retval;
+}
+
+    int
+current_par(oap, count, include, type)
+    oparg_T	*oap;
+    long	count;
+    int		include;	/* TRUE == include white space */
+    int		type;		/* 'p' for paragraph, 'S' for section */
+{
+    linenr_T	start_lnum;
+    linenr_T	end_lnum;
+    int		white_in_front;
+    int		dir;
+    int		start_is_white;
+    int		prev_start_is_white;
+    int		retval = OK;
+    int		do_white = FALSE;
+    int		t;
+    int		i;
+
+    if (type == 'S')	    /* not implemented yet */
+	return FAIL;
+
+    start_lnum = curwin->w_cursor.lnum;
+
+#ifdef FEAT_VISUAL
+    /*
+     * When visual area is more than one line: extend it.
+     */
+    if (VIsual_active && start_lnum != VIsual.lnum)
+    {
+extend:
+	if (start_lnum < VIsual.lnum)
+	    dir = BACKWARD;
+	else
+	    dir = FORWARD;
+	for (i = count; --i >= 0; )
+	{
+	    if (start_lnum ==
+			   (dir == BACKWARD ? 1 : curbuf->b_ml.ml_line_count))
+	    {
+		retval = FAIL;
+		break;
+	    }
+
+	    prev_start_is_white = -1;
+	    for (t = 0; t < 2; ++t)
+	    {
+		start_lnum += dir;
+		start_is_white = linewhite(start_lnum);
+		if (prev_start_is_white == start_is_white)
+		{
+		    start_lnum -= dir;
+		    break;
+		}
+		for (;;)
+		{
+		    if (start_lnum == (dir == BACKWARD
+					    ? 1 : curbuf->b_ml.ml_line_count))
+			break;
+		    if (start_is_white != linewhite(start_lnum + dir)
+			    || (!start_is_white
+				    && startPS(start_lnum + (dir > 0
+							     ? 1 : 0), 0, 0)))
+			break;
+		    start_lnum += dir;
+		}
+		if (!include)
+		    break;
+		if (start_lnum == (dir == BACKWARD
+					    ? 1 : curbuf->b_ml.ml_line_count))
+		    break;
+		prev_start_is_white = start_is_white;
+	    }
+	}
+	curwin->w_cursor.lnum = start_lnum;
+	curwin->w_cursor.col = 0;
+	return retval;
+    }
+#endif
+
+    /*
+     * First move back to the start_lnum of the paragraph or white lines
+     */
+    white_in_front = linewhite(start_lnum);
+    while (start_lnum > 1)
+    {
+	if (white_in_front)	    /* stop at first white line */
+	{
+	    if (!linewhite(start_lnum - 1))
+		break;
+	}
+	else		/* stop at first non-white line of start of paragraph */
+	{
+	    if (linewhite(start_lnum - 1) || startPS(start_lnum, 0, 0))
+		break;
+	}
+	--start_lnum;
+    }
+
+    /*
+     * Move past the end of any white lines.
+     */
+    end_lnum = start_lnum;
+    while (end_lnum <= curbuf->b_ml.ml_line_count && linewhite(end_lnum))
+	++end_lnum;
+
+    --end_lnum;
+    i = count;
+    if (!include && white_in_front)
+	--i;
+    while (i--)
+    {
+	if (end_lnum == curbuf->b_ml.ml_line_count)
+	    return FAIL;
+
+	if (!include)
+	    do_white = linewhite(end_lnum + 1);
+
+	if (include || !do_white)
+	{
+	    ++end_lnum;
+	    /*
+	     * skip to end of paragraph
+	     */
+	    while (end_lnum < curbuf->b_ml.ml_line_count
+		    && !linewhite(end_lnum + 1)
+		    && !startPS(end_lnum + 1, 0, 0))
+		++end_lnum;
+	}
+
+	if (i == 0 && white_in_front && include)
+	    break;
+
+	/*
+	 * skip to end of white lines after paragraph
+	 */
+	if (include || do_white)
+	    while (end_lnum < curbuf->b_ml.ml_line_count
+						   && linewhite(end_lnum + 1))
+		++end_lnum;
+    }
+
+    /*
+     * If there are no empty lines at the end, try to find some empty lines at
+     * the start (unless that has been done already).
+     */
+    if (!white_in_front && !linewhite(end_lnum) && include)
+	while (start_lnum > 1 && linewhite(start_lnum - 1))
+	    --start_lnum;
+
+#ifdef FEAT_VISUAL
+    if (VIsual_active)
+    {
+	/* Problem: when doing "Vipipip" nothing happens in a single white
+	 * line, we get stuck there.  Trap this here. */
+	if (VIsual_mode == 'V' && start_lnum == curwin->w_cursor.lnum)
+	    goto extend;
+	VIsual.lnum = start_lnum;
+	VIsual_mode = 'V';
+	redraw_curbuf_later(INVERTED);	/* update the inversion */
+	showmode();
+    }
+    else
+#endif
+    {
+	oap->start.lnum = start_lnum;
+	oap->start.col = 0;
+	oap->motion_type = MLINE;
+    }
+    curwin->w_cursor.lnum = end_lnum;
+    curwin->w_cursor.col = 0;
+
+    return OK;
+}
+
+static int find_next_quote __ARGS((char_u *top_ptr, int col, int quotechar, char_u *escape));
+static int find_prev_quote __ARGS((char_u *line, int col_start, int quotechar, char_u *escape));
+
+/*
+ * Search quote char from string line[col].
+ * Quote character escaped by one of the characters in "escape" is not counted
+ * as a quote.
+ * Returns column number of "quotechar" or -1 when not found.
+ */
+    static int
+find_next_quote(line, col, quotechar, escape)
+    char_u	*line;
+    int		col;
+    int		quotechar;
+    char_u	*escape;	/* escape characters, can be NULL */
+{
+    int		c;
+
+    for (;;)
+    {
+	c = line[col];
+	if (c == NUL)
+	    return -1;
+	else if (escape != NULL && vim_strchr(escape, c))
+	    ++col;
+	else if (c == quotechar)
+	    break;
+#ifdef FEAT_MBYTE
+	if (has_mbyte)
+	    col += (*mb_ptr2len)(line + col);
+	else
+#endif
+	    ++col;
+    }
+    return col;
+}
+
+/*
+ * Search backwards in "line" from column "col_start" to find "quotechar".
+ * Quote character escaped by one of the characters in "escape" is not counted
+ * as a quote.
+ * Return the found column or zero.
+ */
+    static int
+find_prev_quote(line, col_start, quotechar, escape)
+    char_u	*line;
+    int		col_start;
+    int		quotechar;
+    char_u	*escape;	/* escape characters, can be NULL */
+{
+    int		n;
+
+    while (col_start > 0)
+    {
+	--col_start;
+#ifdef FEAT_MBYTE
+	col_start -= (*mb_head_off)(line, line + col_start);
+#endif
+	n = 0;
+	if (escape != NULL)
+	    while (col_start - n > 0 && vim_strchr(escape,
+					     line[col_start - n - 1]) != NULL)
+	    ++n;
+	if (n & 1)
+	    col_start -= n;	/* uneven number of escape chars, skip it */
+	else if (line[col_start] == quotechar)
+	    break;
+    }
+    return col_start;
+}
+
+/*
+ * Find quote under the cursor, cursor at end.
+ * Returns TRUE if found, else FALSE.
+ */
+    int
+current_quote(oap, count, include, quotechar)
+    oparg_T	*oap;
+    long	count;
+    int		include;	/* TRUE == include quote char */
+    int		quotechar;	/* Quote character */
+{
+    char_u	*line = ml_get_curline();
+    int		col_end;
+    int		col_start = curwin->w_cursor.col;
+    int		inclusive = FALSE;
+#ifdef FEAT_VISUAL
+    int		vis_empty = TRUE;	/* Visual selection <= 1 char */
+    int		vis_bef_curs = FALSE;	/* Visual starts before cursor */
+    int		inside_quotes = FALSE;	/* Looks like "i'" done before */
+    int		selected_quote = FALSE;	/* Has quote inside selection */
+    int		i;
+
+    /* Correct cursor when 'selection' is exclusive */
+    if (VIsual_active)
+    {
+	vis_bef_curs = lt(VIsual, curwin->w_cursor);
+	if (*p_sel == 'e' && vis_bef_curs)
+	    dec_cursor();
+	vis_empty = equalpos(VIsual, curwin->w_cursor);
+    }
+
+    if (!vis_empty)
+    {
+	/* Check if the existing selection exactly spans the text inside
+	 * quotes. */
+	if (vis_bef_curs)
+	{
+	    inside_quotes = VIsual.col > 0
+			&& line[VIsual.col - 1] == quotechar
+			&& line[curwin->w_cursor.col] != NUL
+			&& line[curwin->w_cursor.col + 1] == quotechar;
+	    i = VIsual.col;
+	    col_end = curwin->w_cursor.col;
+	}
+	else
+	{
+	    inside_quotes = curwin->w_cursor.col > 0
+			&& line[curwin->w_cursor.col - 1] == quotechar
+			&& line[VIsual.col] != NUL
+			&& line[VIsual.col + 1] == quotechar;
+	    i = curwin->w_cursor.col;
+	    col_end = VIsual.col;
+	}
+
+	/* Find out if we have a quote in the selection. */
+	while (i <= col_end)
+	    if (line[i++] == quotechar)
+	    {
+		selected_quote = TRUE;
+		break;
+	    }
+    }
+
+    if (!vis_empty && line[col_start] == quotechar)
+    {
+	/* Already selecting something and on a quote character.  Find the
+	 * next quoted string. */
+	if (vis_bef_curs)
+	{
+	    /* Assume we are on a closing quote: move to after the next
+	     * opening quote. */
+	    col_start = find_next_quote(line, col_start + 1, quotechar, NULL);
+	    if (col_start < 0)
+		return FALSE;
+	    col_end = find_next_quote(line, col_start + 1, quotechar,
+							      curbuf->b_p_qe);
+	    if (col_end < 0)
+	    {
+		/* We were on a starting quote perhaps? */
+		col_end = col_start;
+		col_start = curwin->w_cursor.col;
+	    }
+	}
+	else
+	{
+	    col_end = find_prev_quote(line, col_start, quotechar, NULL);
+	    if (line[col_end] != quotechar)
+		return FALSE;
+	    col_start = find_prev_quote(line, col_end, quotechar,
+							      curbuf->b_p_qe);
+	    if (line[col_start] != quotechar)
+	    {
+		/* We were on an ending quote perhaps? */
+		col_start = col_end;
+		col_end = curwin->w_cursor.col;
+	    }
+	}
+    }
+    else
+#endif
+
+    if (line[col_start] == quotechar
+#ifdef FEAT_VISUAL
+	    || !vis_empty
+#endif
+	    )
+    {
+	int	first_col = col_start;
+
+#ifdef FEAT_VISUAL
+	if (!vis_empty)
+	{
+	    if (vis_bef_curs)
+		first_col = find_next_quote(line, col_start, quotechar, NULL);
+	    else
+		first_col = find_prev_quote(line, col_start, quotechar, NULL);
+	}
+#endif
+	/* The cursor is on a quote, we don't know if it's the opening or
+	 * closing quote.  Search from the start of the line to find out.
+	 * Also do this when there is a Visual area, a' may leave the cursor
+	 * in between two strings. */
+	col_start = 0;
+	for (;;)
+	{
+	    /* Find open quote character. */
+	    col_start = find_next_quote(line, col_start, quotechar, NULL);
+	    if (col_start < 0 || col_start > first_col)
+		return FALSE;
+	    /* Find close quote character. */
+	    col_end = find_next_quote(line, col_start + 1, quotechar,
+							      curbuf->b_p_qe);
+	    if (col_end < 0)
+		return FALSE;
+	    /* If is cursor between start and end quote character, it is
+	     * target text object. */
+	    if (col_start <= first_col && first_col <= col_end)
+		break;
+	    col_start = col_end + 1;
+	}
+    }
+    else
+    {
+	/* Search backward for a starting quote. */
+	col_start = find_prev_quote(line, col_start, quotechar, curbuf->b_p_qe);
+	if (line[col_start] != quotechar)
+	{
+	    /* No quote before the cursor, look after the cursor. */
+	    col_start = find_next_quote(line, col_start, quotechar, NULL);
+	    if (col_start < 0)
+		return FALSE;
+	}
+
+	/* Find close quote character. */
+	col_end = find_next_quote(line, col_start + 1, quotechar,
+							      curbuf->b_p_qe);
+	if (col_end < 0)
+	    return FALSE;
+    }
+
+    /* When "include" is TRUE, include spaces after closing quote or before
+     * the starting quote. */
+    if (include)
+    {
+	if (vim_iswhite(line[col_end + 1]))
+	    while (vim_iswhite(line[col_end + 1]))
+		++col_end;
+	else
+	    while (col_start > 0 && vim_iswhite(line[col_start - 1]))
+		--col_start;
+    }
+
+    /* Set start position.  After vi" another i" must include the ".
+     * For v2i" include the quotes. */
+    if (!include && count < 2
+#ifdef FEAT_VISUAL
+	    && (vis_empty || !inside_quotes)
+#endif
+	    )
+	++col_start;
+    curwin->w_cursor.col = col_start;
+#ifdef FEAT_VISUAL
+    if (VIsual_active)
+    {
+	/* Set the start of the Visual area when the Visual area was empty, we
+	 * were just inside quotes or the Visual area didn't start at a quote
+	 * and didn't include a quote.
+	 */
+	if (vis_empty
+		|| (vis_bef_curs
+		    && !selected_quote
+		    && (inside_quotes
+			|| (line[VIsual.col] != quotechar
+			    && (VIsual.col == 0
+				|| line[VIsual.col - 1] != quotechar)))))
+	{
+	    VIsual = curwin->w_cursor;
+	    redraw_curbuf_later(INVERTED);
+	}
+    }
+    else
+#endif
+    {
+	oap->start = curwin->w_cursor;
+	oap->motion_type = MCHAR;
+    }
+
+    /* Set end position. */
+    curwin->w_cursor.col = col_end;
+    if ((include || count > 1
+#ifdef FEAT_VISUAL
+		/* After vi" another i" must include the ". */
+		|| (!vis_empty && inside_quotes)
+#endif
+	) && inc_cursor() == 2)
+	inclusive = TRUE;
+#ifdef FEAT_VISUAL
+    if (VIsual_active)
+    {
+	if (vis_empty || vis_bef_curs)
+	{
+	    /* decrement cursor when 'selection' is not exclusive */
+	    if (*p_sel != 'e')
+		dec_cursor();
+	}
+	else
+	{
+	    /* Cursor is at start of Visual area.  Set the end of the Visual
+	     * area when it was just inside quotes or it didn't end at a
+	     * quote. */
+	    if (inside_quotes
+		    || (!selected_quote
+			&& line[VIsual.col] != quotechar
+			&& (line[VIsual.col] == NUL
+			    || line[VIsual.col + 1] != quotechar)))
+	    {
+		dec_cursor();
+		VIsual = curwin->w_cursor;
+	    }
+	    curwin->w_cursor.col = col_start;
+	}
+	if (VIsual_mode == 'V')
+	{
+	    VIsual_mode = 'v';
+	    redraw_cmdline = TRUE;		/* show mode later */
+	}
+    }
+    else
+#endif
+    {
+	/* Set inclusive and other oap's flags. */
+	oap->inclusive = inclusive;
+    }
+
+    return OK;
+}
+
+#endif /* FEAT_TEXTOBJ */
+
+#if defined(FEAT_LISP) || defined(FEAT_CINDENT) || defined(FEAT_TEXTOBJ) \
+	|| defined(PROTO)
+/*
+ * return TRUE if line 'lnum' is empty or has white chars only.
+ */
+    int
+linewhite(lnum)
+    linenr_T	lnum;
+{
+    char_u  *p;
+
+    p = skipwhite(ml_get(lnum));
+    return (*p == NUL);
+}
+#endif
+
+#if defined(FEAT_FIND_ID) || defined(PROTO)
+/*
+ * Find identifiers or defines in included files.
+ * if p_ic && (compl_cont_status & CONT_SOL) then ptr must be in lowercase.
+ */
+/*ARGSUSED*/
+    void
+find_pattern_in_path(ptr, dir, len, whole, skip_comments,
+				    type, count, action, start_lnum, end_lnum)
+    char_u	*ptr;		/* pointer to search pattern */
+    int		dir;		/* direction of expansion */
+    int		len;		/* length of search pattern */
+    int		whole;		/* match whole words only */
+    int		skip_comments;	/* don't match inside comments */
+    int		type;		/* Type of search; are we looking for a type?
+				   a macro? */
+    long	count;
+    int		action;		/* What to do when we find it */
+    linenr_T	start_lnum;	/* first line to start searching */
+    linenr_T	end_lnum;	/* last line for searching */
+{
+    SearchedFile *files;		/* Stack of included files */
+    SearchedFile *bigger;		/* When we need more space */
+    int		max_path_depth = 50;
+    long	match_count = 1;
+
+    char_u	*pat;
+    char_u	*new_fname;
+    char_u	*curr_fname = curbuf->b_fname;
+    char_u	*prev_fname = NULL;
+    linenr_T	lnum;
+    int		depth;
+    int		depth_displayed;	/* For type==CHECK_PATH */
+    int		old_files;
+    int		already_searched;
+    char_u	*file_line;
+    char_u	*line;
+    char_u	*p;
+    char_u	save_char;
+    int		define_matched;
+    regmatch_T	regmatch;
+    regmatch_T	incl_regmatch;
+    regmatch_T	def_regmatch;
+    int		matched = FALSE;
+    int		did_show = FALSE;
+    int		found = FALSE;
+    int		i;
+    char_u	*already = NULL;
+    char_u	*startp = NULL;
+    char_u	*inc_opt = NULL;
+#ifdef RISCOS
+    int		previous_munging = __riscosify_control;
+#endif
+#if defined(FEAT_WINDOWS) && defined(FEAT_QUICKFIX)
+    win_T	*curwin_save = NULL;
+#endif
+
+    regmatch.regprog = NULL;
+    incl_regmatch.regprog = NULL;
+    def_regmatch.regprog = NULL;
+
+    file_line = alloc(LSIZE);
+    if (file_line == NULL)
+	return;
+
+#ifdef RISCOS
+    /* UnixLib knows best how to munge c file names - turn munging back on. */
+    int __riscosify_control = 0;
+#endif
+
+    if (type != CHECK_PATH && type != FIND_DEFINE
+#ifdef FEAT_INS_EXPAND
+	/* when CONT_SOL is set compare "ptr" with the beginning of the line
+	 * is faster than quote_meta/regcomp/regexec "ptr" -- Acevedo */
+	    && !(compl_cont_status & CONT_SOL)
+#endif
+       )
+    {
+	pat = alloc(len + 5);
+	if (pat == NULL)
+	    goto fpip_end;
+	sprintf((char *)pat, whole ? "\\<%.*s\\>" : "%.*s", len, ptr);
+	/* ignore case according to p_ic, p_scs and pat */
+	regmatch.rm_ic = ignorecase(pat);
+	regmatch.regprog = vim_regcomp(pat, p_magic ? RE_MAGIC : 0);
+	vim_free(pat);
+	if (regmatch.regprog == NULL)
+	    goto fpip_end;
+    }
+    inc_opt = (*curbuf->b_p_inc == NUL) ? p_inc : curbuf->b_p_inc;
+    if (*inc_opt != NUL)
+    {
+	incl_regmatch.regprog = vim_regcomp(inc_opt, p_magic ? RE_MAGIC : 0);
+	if (incl_regmatch.regprog == NULL)
+	    goto fpip_end;
+	incl_regmatch.rm_ic = FALSE;	/* don't ignore case in incl. pat. */
+    }
+    if (type == FIND_DEFINE && (*curbuf->b_p_def != NUL || *p_def != NUL))
+    {
+	def_regmatch.regprog = vim_regcomp(*curbuf->b_p_def == NUL
+			   ? p_def : curbuf->b_p_def, p_magic ? RE_MAGIC : 0);
+	if (def_regmatch.regprog == NULL)
+	    goto fpip_end;
+	def_regmatch.rm_ic = FALSE;	/* don't ignore case in define pat. */
+    }
+    files = (SearchedFile *)lalloc_clear((long_u)
+			       (max_path_depth * sizeof(SearchedFile)), TRUE);
+    if (files == NULL)
+	goto fpip_end;
+    old_files = max_path_depth;
+    depth = depth_displayed = -1;
+
+    lnum = start_lnum;
+    if (end_lnum > curbuf->b_ml.ml_line_count)
+	end_lnum = curbuf->b_ml.ml_line_count;
+    if (lnum > end_lnum)		/* do at least one line */
+	lnum = end_lnum;
+    line = ml_get(lnum);
+
+    for (;;)
+    {
+	if (incl_regmatch.regprog != NULL
+		&& vim_regexec(&incl_regmatch, line, (colnr_T)0))
+	{
+	    char_u *p_fname = (curr_fname == curbuf->b_fname)
+					      ? curbuf->b_ffname : curr_fname;
+
+	    if (inc_opt != NULL && strstr((char *)inc_opt, "\\zs") != NULL)
+		/* Use text from '\zs' to '\ze' (or end) of 'include'. */
+		new_fname = find_file_name_in_path(incl_regmatch.startp[0],
+			      (int)(incl_regmatch.endp[0] - incl_regmatch.startp[0]),
+				 FNAME_EXP|FNAME_INCL|FNAME_REL, 1L, p_fname);
+	    else
+		/* Use text after match with 'include'. */
+		new_fname = file_name_in_line(incl_regmatch.endp[0], 0,
+			     FNAME_EXP|FNAME_INCL|FNAME_REL, 1L, p_fname, NULL);
+	    already_searched = FALSE;
+	    if (new_fname != NULL)
+	    {
+		/* Check whether we have already searched in this file */
+		for (i = 0;; i++)
+		{
+		    if (i == depth + 1)
+			i = old_files;
+		    if (i == max_path_depth)
+			break;
+		    if (fullpathcmp(new_fname, files[i].name, TRUE) & FPC_SAME)
+		    {
+			if (type != CHECK_PATH &&
+				action == ACTION_SHOW_ALL && files[i].matched)
+			{
+			    msg_putchar('\n');	    /* cursor below last one */
+			    if (!got_int)	    /* don't display if 'q'
+						       typed at "--more--"
+						       mesage */
+			    {
+				msg_home_replace_hl(new_fname);
+				MSG_PUTS(_(" (includes previously listed match)"));
+				prev_fname = NULL;
+			    }
+			}
+			vim_free(new_fname);
+			new_fname = NULL;
+			already_searched = TRUE;
+			break;
+		    }
+		}
+	    }
+
+	    if (type == CHECK_PATH && (action == ACTION_SHOW_ALL
+				 || (new_fname == NULL && !already_searched)))
+	    {
+		if (did_show)
+		    msg_putchar('\n');	    /* cursor below last one */
+		else
+		{
+		    gotocmdline(TRUE);	    /* cursor at status line */
+		    MSG_PUTS_TITLE(_("--- Included files "));
+		    if (action != ACTION_SHOW_ALL)
+			MSG_PUTS_TITLE(_("not found "));
+		    MSG_PUTS_TITLE(_("in path ---\n"));
+		}
+		did_show = TRUE;
+		while (depth_displayed < depth && !got_int)
+		{
+		    ++depth_displayed;
+		    for (i = 0; i < depth_displayed; i++)
+			MSG_PUTS("  ");
+		    msg_home_replace(files[depth_displayed].name);
+		    MSG_PUTS(" -->\n");
+		}
+		if (!got_int)		    /* don't display if 'q' typed
+					       for "--more--" message */
+		{
+		    for (i = 0; i <= depth_displayed; i++)
+			MSG_PUTS("  ");
+		    if (new_fname != NULL)
+		    {
+			/* using "new_fname" is more reliable, e.g., when
+			 * 'includeexpr' is set. */
+			msg_outtrans_attr(new_fname, hl_attr(HLF_D));
+		    }
+		    else
+		    {
+			/*
+			 * Isolate the file name.
+			 * Include the surrounding "" or <> if present.
+			 */
+			for (p = incl_regmatch.endp[0]; !vim_isfilec(*p); p++)
+			    ;
+			for (i = 0; vim_isfilec(p[i]); i++)
+			    ;
+			if (i == 0)
+			{
+			    /* Nothing found, use the rest of the line. */
+			    p = incl_regmatch.endp[0];
+			    i = (int)STRLEN(p);
+			}
+			else
+			{
+			    if (p[-1] == '"' || p[-1] == '<')
+			    {
+				--p;
+				++i;
+			    }
+			    if (p[i] == '"' || p[i] == '>')
+				++i;
+			}
+			save_char = p[i];
+			p[i] = NUL;
+			msg_outtrans_attr(p, hl_attr(HLF_D));
+			p[i] = save_char;
+		    }
+
+		    if (new_fname == NULL && action == ACTION_SHOW_ALL)
+		    {
+			if (already_searched)
+			    MSG_PUTS(_("  (Already listed)"));
+			else
+			    MSG_PUTS(_("  NOT FOUND"));
+		    }
+		}
+		out_flush();	    /* output each line directly */
+	    }
+
+	    if (new_fname != NULL)
+	    {
+		/* Push the new file onto the file stack */
+		if (depth + 1 == old_files)
+		{
+		    bigger = (SearchedFile *)lalloc((long_u)(
+			    max_path_depth * 2 * sizeof(SearchedFile)), TRUE);
+		    if (bigger != NULL)
+		    {
+			for (i = 0; i <= depth; i++)
+			    bigger[i] = files[i];
+			for (i = depth + 1; i < old_files + max_path_depth; i++)
+			{
+			    bigger[i].fp = NULL;
+			    bigger[i].name = NULL;
+			    bigger[i].lnum = 0;
+			    bigger[i].matched = FALSE;
+			}
+			for (i = old_files; i < max_path_depth; i++)
+			    bigger[i + max_path_depth] = files[i];
+			old_files += max_path_depth;
+			max_path_depth *= 2;
+			vim_free(files);
+			files = bigger;
+		    }
+		}
+		if ((files[depth + 1].fp = mch_fopen((char *)new_fname, "r"))
+								    == NULL)
+		    vim_free(new_fname);
+		else
+		{
+		    if (++depth == old_files)
+		    {
+			/*
+			 * lalloc() for 'bigger' must have failed above.  We
+			 * will forget one of our already visited files now.
+			 */
+			vim_free(files[old_files].name);
+			++old_files;
+		    }
+		    files[depth].name = curr_fname = new_fname;
+		    files[depth].lnum = 0;
+		    files[depth].matched = FALSE;
+#ifdef FEAT_INS_EXPAND
+		    if (action == ACTION_EXPAND)
+		    {
+			msg_hist_off = TRUE;	/* reset in msg_trunc_attr() */
+			vim_snprintf((char*)IObuff, IOSIZE,
+				_("Scanning included file: %s"),
+				(char *)new_fname);
+			msg_trunc_attr(IObuff, TRUE, hl_attr(HLF_R));
+		    }
+		    else
+#endif
+			 if (p_verbose >= 5)
+		    {
+			verbose_enter();
+			smsg((char_u *)_("Searching included file %s"),
+							   (char *)new_fname);
+			verbose_leave();
+		    }
+
+		}
+	    }
+	}
+	else
+	{
+	    /*
+	     * Check if the line is a define (type == FIND_DEFINE)
+	     */
+	    p = line;
+search_line:
+	    define_matched = FALSE;
+	    if (def_regmatch.regprog != NULL
+			      && vim_regexec(&def_regmatch, line, (colnr_T)0))
+	    {
+		/*
+		 * Pattern must be first identifier after 'define', so skip
+		 * to that position before checking for match of pattern.  Also
+		 * don't let it match beyond the end of this identifier.
+		 */
+		p = def_regmatch.endp[0];
+		while (*p && !vim_iswordc(*p))
+		    p++;
+		define_matched = TRUE;
+	    }
+
+	    /*
+	     * Look for a match.  Don't do this if we are looking for a
+	     * define and this line didn't match define_prog above.
+	     */
+	    if (def_regmatch.regprog == NULL || define_matched)
+	    {
+		if (define_matched
+#ifdef FEAT_INS_EXPAND
+			|| (compl_cont_status & CONT_SOL)
+#endif
+		    )
+		{
+		    /* compare the first "len" chars from "ptr" */
+		    startp = skipwhite(p);
+		    if (p_ic)
+			matched = !MB_STRNICMP(startp, ptr, len);
+		    else
+			matched = !STRNCMP(startp, ptr, len);
+		    if (matched && define_matched && whole
+						  && vim_iswordc(startp[len]))
+			matched = FALSE;
+		}
+		else if (regmatch.regprog != NULL
+			 && vim_regexec(&regmatch, line, (colnr_T)(p - line)))
+		{
+		    matched = TRUE;
+		    startp = regmatch.startp[0];
+		    /*
+		     * Check if the line is not a comment line (unless we are
+		     * looking for a define).  A line starting with "# define"
+		     * is not considered to be a comment line.
+		     */
+		    if (!define_matched && skip_comments)
+		    {
+#ifdef FEAT_COMMENTS
+			if ((*line != '#' ||
+				STRNCMP(skipwhite(line + 1), "define", 6) != 0)
+				&& get_leader_len(line, NULL, FALSE))
+			    matched = FALSE;
+
+			/*
+			 * Also check for a "/ *" or "/ /" before the match.
+			 * Skips lines like "int backwards;  / * normal index
+			 * * /" when looking for "normal".
+			 * Note: Doesn't skip "/ *" in comments.
+			 */
+			p = skipwhite(line);
+			if (matched
+				|| (p[0] == '/' && p[1] == '*') || p[0] == '*')
+#endif
+			    for (p = line; *p && p < startp; ++p)
+			    {
+				if (matched
+					&& p[0] == '/'
+					&& (p[1] == '*' || p[1] == '/'))
+				{
+				    matched = FALSE;
+				    /* After "//" all text is comment */
+				    if (p[1] == '/')
+					break;
+				    ++p;
+				}
+				else if (!matched && p[0] == '*' && p[1] == '/')
+				{
+				    /* Can find match after "* /". */
+				    matched = TRUE;
+				    ++p;
+				}
+			    }
+		    }
+		}
+	    }
+	}
+	if (matched)
+	{
+#ifdef FEAT_INS_EXPAND
+	    if (action == ACTION_EXPAND)
+	    {
+		int	reuse = 0;
+		int	add_r;
+		char_u	*aux;
+
+		if (depth == -1 && lnum == curwin->w_cursor.lnum)
+		    break;
+		found = TRUE;
+		aux = p = startp;
+		if (compl_cont_status & CONT_ADDING)
+		{
+		    p += compl_length;
+		    if (vim_iswordp(p))
+			goto exit_matched;
+		    p = find_word_start(p);
+		}
+		p = find_word_end(p);
+		i = (int)(p - aux);
+
+		if ((compl_cont_status & CONT_ADDING) && i == compl_length)
+		{
+		    /* IOSIZE > compl_length, so the STRNCPY works */
+		    STRNCPY(IObuff, aux, i);
+
+		    /* Get the next line: when "depth" < 0  from the current
+		     * buffer, otherwise from the included file.  Jump to
+		     * exit_matched when past the last line. */
+		    if (depth < 0)
+		    {
+			if (lnum >= end_lnum)
+			    goto exit_matched;
+			line = ml_get(++lnum);
+		    }
+		    else if (vim_fgets(line = file_line,
+						      LSIZE, files[depth].fp))
+			goto exit_matched;
+
+		    /* we read a line, set "already" to check this "line" later
+		     * if depth >= 0 we'll increase files[depth].lnum far
+		     * bellow  -- Acevedo */
+		    already = aux = p = skipwhite(line);
+		    p = find_word_start(p);
+		    p = find_word_end(p);
+		    if (p > aux)
+		    {
+			if (*aux != ')' && IObuff[i-1] != TAB)
+			{
+			    if (IObuff[i-1] != ' ')
+				IObuff[i++] = ' ';
+			    /* IObuf =~ "\(\k\|\i\).* ", thus i >= 2*/
+			    if (p_js
+				&& (IObuff[i-2] == '.'
+				    || (vim_strchr(p_cpo, CPO_JOINSP) == NULL
+					&& (IObuff[i-2] == '?'
+					    || IObuff[i-2] == '!'))))
+				IObuff[i++] = ' ';
+			}
+			/* copy as much as posible of the new word */
+			if (p - aux >= IOSIZE - i)
+			    p = aux + IOSIZE - i - 1;
+			STRNCPY(IObuff + i, aux, p - aux);
+			i += (int)(p - aux);
+			reuse |= CONT_S_IPOS;
+		    }
+		    IObuff[i] = NUL;
+		    aux = IObuff;
+
+		    if (i == compl_length)
+			goto exit_matched;
+		}
+
+		add_r = ins_compl_add_infercase(aux, i, p_ic,
+			curr_fname == curbuf->b_fname ? NULL : curr_fname,
+			dir, reuse);
+		if (add_r == OK)
+		    /* if dir was BACKWARD then honor it just once */
+		    dir = FORWARD;
+		else if (add_r == FAIL)
+		    break;
+	    }
+	    else
+#endif
+		 if (action == ACTION_SHOW_ALL)
+	    {
+		found = TRUE;
+		if (!did_show)
+		    gotocmdline(TRUE);		/* cursor at status line */
+		if (curr_fname != prev_fname)
+		{
+		    if (did_show)
+			msg_putchar('\n');	/* cursor below last one */
+		    if (!got_int)		/* don't display if 'q' typed
+						    at "--more--" mesage */
+			msg_home_replace_hl(curr_fname);
+		    prev_fname = curr_fname;
+		}
+		did_show = TRUE;
+		if (!got_int)
+		    show_pat_in_path(line, type, TRUE, action,
+			    (depth == -1) ? NULL : files[depth].fp,
+			    (depth == -1) ? &lnum : &files[depth].lnum,
+			    match_count++);
+
+		/* Set matched flag for this file and all the ones that
+		 * include it */
+		for (i = 0; i <= depth; ++i)
+		    files[i].matched = TRUE;
+	    }
+	    else if (--count <= 0)
+	    {
+		found = TRUE;
+		if (depth == -1 && lnum == curwin->w_cursor.lnum
+#if defined(FEAT_WINDOWS) && defined(FEAT_QUICKFIX)
+						      && g_do_tagpreview == 0
+#endif
+						      )
+		    EMSG(_("E387: Match is on current line"));
+		else if (action == ACTION_SHOW)
+		{
+		    show_pat_in_path(line, type, did_show, action,
+			(depth == -1) ? NULL : files[depth].fp,
+			(depth == -1) ? &lnum : &files[depth].lnum, 1L);
+		    did_show = TRUE;
+		}
+		else
+		{
+#ifdef FEAT_GUI
+		    need_mouse_correct = TRUE;
+#endif
+#if defined(FEAT_WINDOWS) && defined(FEAT_QUICKFIX)
+		    /* ":psearch" uses the preview window */
+		    if (g_do_tagpreview != 0)
+		    {
+			curwin_save = curwin;
+			prepare_tagpreview(TRUE);
+		    }
+#endif
+		    if (action == ACTION_SPLIT)
+		    {
+#ifdef FEAT_WINDOWS
+			if (win_split(0, 0) == FAIL)
+#endif
+			    break;
+#ifdef FEAT_SCROLLBIND
+			curwin->w_p_scb = FALSE;
+#endif
+		    }
+		    if (depth == -1)
+		    {
+			/* match in current file */
+#if defined(FEAT_WINDOWS) && defined(FEAT_QUICKFIX)
+			if (g_do_tagpreview != 0)
+			{
+			    if (getfile(0, curwin_save->w_buffer->b_fname,
+						 NULL, TRUE, lnum, FALSE) > 0)
+				break;	/* failed to jump to file */
+			}
+			else
+#endif
+			    setpcmark();
+			curwin->w_cursor.lnum = lnum;
+		    }
+		    else
+		    {
+			if (getfile(0, files[depth].name, NULL, TRUE,
+						files[depth].lnum, FALSE) > 0)
+			    break;	/* failed to jump to file */
+			/* autocommands may have changed the lnum, we don't
+			 * want that here */
+			curwin->w_cursor.lnum = files[depth].lnum;
+		    }
+		}
+		if (action != ACTION_SHOW)
+		{
+		    curwin->w_cursor.col = (colnr_T) (startp - line);
+		    curwin->w_set_curswant = TRUE;
+		}
+
+#if defined(FEAT_WINDOWS) && defined(FEAT_QUICKFIX)
+		if (g_do_tagpreview != 0
+			   && curwin != curwin_save && win_valid(curwin_save))
+		{
+		    /* Return cursor to where we were */
+		    validate_cursor();
+		    redraw_later(VALID);
+		    win_enter(curwin_save, TRUE);
+		}
+#endif
+		break;
+	    }
+#ifdef FEAT_INS_EXPAND
+exit_matched:
+#endif
+	    matched = FALSE;
+	    /* look for other matches in the rest of the line if we
+	     * are not at the end of it already */
+	    if (def_regmatch.regprog == NULL
+#ifdef FEAT_INS_EXPAND
+		    && action == ACTION_EXPAND
+		    && !(compl_cont_status & CONT_SOL)
+#endif
+		    && *(p = startp + 1))
+		goto search_line;
+	}
+	line_breakcheck();
+#ifdef FEAT_INS_EXPAND
+	if (action == ACTION_EXPAND)
+	    ins_compl_check_keys(30);
+	if (got_int || compl_interrupted)
+#else
+	if (got_int)
+#endif
+	    break;
+
+	/*
+	 * Read the next line.  When reading an included file and encountering
+	 * end-of-file, close the file and continue in the file that included
+	 * it.
+	 */
+	while (depth >= 0 && !already
+		&& vim_fgets(line = file_line, LSIZE, files[depth].fp))
+	{
+	    fclose(files[depth].fp);
+	    --old_files;
+	    files[old_files].name = files[depth].name;
+	    files[old_files].matched = files[depth].matched;
+	    --depth;
+	    curr_fname = (depth == -1) ? curbuf->b_fname
+				       : files[depth].name;
+	    if (depth < depth_displayed)
+		depth_displayed = depth;
+	}
+	if (depth >= 0)		/* we could read the line */
+	    files[depth].lnum++;
+	else if (!already)
+	{
+	    if (++lnum > end_lnum)
+		break;
+	    line = ml_get(lnum);
+	}
+	already = NULL;
+    }
+    /* End of big for (;;) loop. */
+
+    /* Close any files that are still open. */
+    for (i = 0; i <= depth; i++)
+    {
+	fclose(files[i].fp);
+	vim_free(files[i].name);
+    }
+    for (i = old_files; i < max_path_depth; i++)
+	vim_free(files[i].name);
+    vim_free(files);
+
+    if (type == CHECK_PATH)
+    {
+	if (!did_show)
+	{
+	    if (action != ACTION_SHOW_ALL)
+		MSG(_("All included files were found"));
+	    else
+		MSG(_("No included files"));
+	}
+    }
+    else if (!found
+#ifdef FEAT_INS_EXPAND
+		    && action != ACTION_EXPAND
+#endif
+						)
+    {
+#ifdef FEAT_INS_EXPAND
+	if (got_int || compl_interrupted)
+#else
+	if (got_int)
+#endif
+	    EMSG(_(e_interr));
+	else if (type == FIND_DEFINE)
+	    EMSG(_("E388: Couldn't find definition"));
+	else
+	    EMSG(_("E389: Couldn't find pattern"));
+    }
+    if (action == ACTION_SHOW || action == ACTION_SHOW_ALL)
+	msg_end();
+
+fpip_end:
+    vim_free(file_line);
+    vim_free(regmatch.regprog);
+    vim_free(incl_regmatch.regprog);
+    vim_free(def_regmatch.regprog);
+
+#ifdef RISCOS
+   /* Restore previous file munging state. */
+    __riscosify_control = previous_munging;
+#endif
+}
+
+    static void
+show_pat_in_path(line, type, did_show, action, fp, lnum, count)
+    char_u  *line;
+    int	    type;
+    int	    did_show;
+    int	    action;
+    FILE    *fp;
+    linenr_T *lnum;
+    long    count;
+{
+    char_u  *p;
+
+    if (did_show)
+	msg_putchar('\n');	/* cursor below last one */
+    else if (!msg_silent)
+	gotocmdline(TRUE);	/* cursor at status line */
+    if (got_int)		/* 'q' typed at "--more--" message */
+	return;
+    for (;;)
+    {
+	p = line + STRLEN(line) - 1;
+	if (fp != NULL)
+	{
+	    /* We used fgets(), so get rid of newline at end */
+	    if (p >= line && *p == '\n')
+		--p;
+	    if (p >= line && *p == '\r')
+		--p;
+	    *(p + 1) = NUL;
+	}
+	if (action == ACTION_SHOW_ALL)
+	{
+	    sprintf((char *)IObuff, "%3ld: ", count);	/* show match nr */
+	    msg_puts(IObuff);
+	    sprintf((char *)IObuff, "%4ld", *lnum);	/* show line nr */
+						/* Highlight line numbers */
+	    msg_puts_attr(IObuff, hl_attr(HLF_N));
+	    MSG_PUTS(" ");
+	}
+	msg_prt_line(line, FALSE);
+	out_flush();			/* show one line at a time */
+
+	/* Definition continues until line that doesn't end with '\' */
+	if (got_int || type != FIND_DEFINE || p < line || *p != '\\')
+	    break;
+
+	if (fp != NULL)
+	{
+	    if (vim_fgets(line, LSIZE, fp)) /* end of file */
+		break;
+	    ++*lnum;
+	}
+	else
+	{
+	    if (++*lnum > curbuf->b_ml.ml_line_count)
+		break;
+	    line = ml_get(*lnum);
+	}
+	msg_putchar('\n');
+    }
+}
+#endif
+
+#ifdef FEAT_VIMINFO
+    int
+read_viminfo_search_pattern(virp, force)
+    vir_T	*virp;
+    int		force;
+{
+    char_u	*lp;
+    int		idx = -1;
+    int		magic = FALSE;
+    int		no_scs = FALSE;
+    int		off_line = FALSE;
+    int		off_end = 0;
+    long	off = 0;
+    int		setlast = FALSE;
+#ifdef FEAT_SEARCH_EXTRA
+    static int	hlsearch_on = FALSE;
+#endif
+    char_u	*val;
+
+    /*
+     * Old line types:
+     * "/pat", "&pat": search/subst. pat
+     * "~/pat", "~&pat": last used search/subst. pat
+     * New line types:
+     * "~h", "~H": hlsearch highlighting off/on
+     * "~<magic><smartcase><line><end><off><last><which>pat"
+     * <magic>: 'm' off, 'M' on
+     * <smartcase>: 's' off, 'S' on
+     * <line>: 'L' line offset, 'l' char offset
+     * <end>: 'E' from end, 'e' from start
+     * <off>: decimal, offset
+     * <last>: '~' last used pattern
+     * <which>: '/' search pat, '&' subst. pat
+     */
+    lp = virp->vir_line;
+    if (lp[0] == '~' && (lp[1] == 'm' || lp[1] == 'M'))	/* new line type */
+    {
+	if (lp[1] == 'M')		/* magic on */
+	    magic = TRUE;
+	if (lp[2] == 's')
+	    no_scs = TRUE;
+	if (lp[3] == 'L')
+	    off_line = TRUE;
+	if (lp[4] == 'E')
+	    off_end = SEARCH_END;
+	lp += 5;
+	off = getdigits(&lp);
+    }
+    if (lp[0] == '~')		/* use this pattern for last-used pattern */
+    {
+	setlast = TRUE;
+	lp++;
+    }
+    if (lp[0] == '/')
+	idx = RE_SEARCH;
+    else if (lp[0] == '&')
+	idx = RE_SUBST;
+#ifdef FEAT_SEARCH_EXTRA
+    else if (lp[0] == 'h')	/* ~h: 'hlsearch' highlighting off */
+	hlsearch_on = FALSE;
+    else if (lp[0] == 'H')	/* ~H: 'hlsearch' highlighting on */
+	hlsearch_on = TRUE;
+#endif
+    if (idx >= 0)
+    {
+	if (force || spats[idx].pat == NULL)
+	{
+	    val = viminfo_readstring(virp, (int)(lp - virp->vir_line + 1),
+									TRUE);
+	    if (val != NULL)
+	    {
+		set_last_search_pat(val, idx, magic, setlast);
+		vim_free(val);
+		spats[idx].no_scs = no_scs;
+		spats[idx].off.line = off_line;
+		spats[idx].off.end = off_end;
+		spats[idx].off.off = off;
+#ifdef FEAT_SEARCH_EXTRA
+		if (setlast)
+		    no_hlsearch = !hlsearch_on;
+#endif
+	    }
+	}
+    }
+    return viminfo_readline(virp);
+}
+
+    void
+write_viminfo_search_pattern(fp)
+    FILE	*fp;
+{
+    if (get_viminfo_parameter('/') != 0)
+    {
+#ifdef FEAT_SEARCH_EXTRA
+	fprintf(fp, "\n# hlsearch on (H) or off (h):\n~%c",
+	    (no_hlsearch || find_viminfo_parameter('h') != NULL) ? 'h' : 'H');
+#endif
+	wvsp_one(fp, RE_SEARCH, "", '/');
+	wvsp_one(fp, RE_SUBST, "Substitute ", '&');
+    }
+}
+
+    static void
+wvsp_one(fp, idx, s, sc)
+    FILE	*fp;	/* file to write to */
+    int		idx;	/* spats[] index */
+    char	*s;	/* search pat */
+    int		sc;	/* dir char */
+{
+    if (spats[idx].pat != NULL)
+    {
+	fprintf(fp, _("\n# Last %sSearch Pattern:\n~"), s);
+	/* off.dir is not stored, it's reset to forward */
+	fprintf(fp, "%c%c%c%c%ld%s%c",
+		spats[idx].magic    ? 'M' : 'm',	/* magic */
+		spats[idx].no_scs   ? 's' : 'S',	/* smartcase */
+		spats[idx].off.line ? 'L' : 'l',	/* line offset */
+		spats[idx].off.end  ? 'E' : 'e',	/* offset from end */
+		spats[idx].off.off,			/* offset */
+		last_idx == idx	    ? "~" : "",		/* last used pat */
+		sc);
+	viminfo_writestring(fp, spats[idx].pat);
+    }
+}
+#endif /* FEAT_VIMINFO */
--- /dev/null
+++ b/spell.c
@@ -1,0 +1,15924 @@
+/* vi:set ts=8 sts=4 sw=4:
+ *
+ * VIM - Vi IMproved	by Bram Moolenaar
+ *
+ * Do ":help uganda"  in Vim to read copying and usage conditions.
+ * Do ":help credits" in Vim to see a list of people who contributed.
+ * See README.txt for an overview of the Vim source code.
+ */
+
+/*
+ * spell.c: code for spell checking
+ *
+ * The spell checking mechanism uses a tree (aka trie).  Each node in the tree
+ * has a list of bytes that can appear (siblings).  For each byte there is a
+ * pointer to the node with the byte that follows in the word (child).
+ *
+ * A NUL byte is used where the word may end.  The bytes are sorted, so that
+ * binary searching can be used and the NUL bytes are at the start.  The
+ * number of possible bytes is stored before the list of bytes.
+ *
+ * The tree uses two arrays: "byts" stores the characters, "idxs" stores
+ * either the next index or flags.  The tree starts at index 0.  For example,
+ * to lookup "vi" this sequence is followed:
+ *	i = 0
+ *	len = byts[i]
+ *	n = where "v" appears in byts[i + 1] to byts[i + len]
+ *	i = idxs[n]
+ *	len = byts[i]
+ *	n = where "i" appears in byts[i + 1] to byts[i + len]
+ *	i = idxs[n]
+ *	len = byts[i]
+ *	find that byts[i + 1] is 0, idxs[i + 1] has flags for "vi".
+ *
+ * There are two word trees: one with case-folded words and one with words in
+ * original case.  The second one is only used for keep-case words and is
+ * usually small.
+ *
+ * There is one additional tree for when not all prefixes are applied when
+ * generating the .spl file.  This tree stores all the possible prefixes, as
+ * if they were words.  At each word (prefix) end the prefix nr is stored, the
+ * following word must support this prefix nr.  And the condition nr is
+ * stored, used to lookup the condition that the word must match with.
+ *
+ * Thanks to Olaf Seibert for providing an example implementation of this tree
+ * and the compression mechanism.
+ * LZ trie ideas:
+ *	http://www.irb.hr/hr/home/ristov/papers/RistovLZtrieRevision1.pdf
+ * More papers: http://www-igm.univ-mlv.fr/~laporte/publi_en.html
+ *
+ * Matching involves checking the caps type: Onecap ALLCAP KeepCap.
+ *
+ * Why doesn't Vim use aspell/ispell/myspell/etc.?
+ * See ":help develop-spell".
+ */
+
+/* Use SPELL_PRINTTREE for debugging: dump the word tree after adding a word.
+ * Only use it for small word lists! */
+#if 0
+# define SPELL_PRINTTREE
+#endif
+
+/* Use DEBUG_TRIEWALK to print the changes made in suggest_trie_walk() for a
+ * specific word. */
+#if 0
+# define DEBUG_TRIEWALK
+#endif
+
+/*
+ * Use this to adjust the score after finding suggestions, based on the
+ * suggested word sounding like the bad word.  This is much faster than doing
+ * it for every possible suggestion.
+ * Disadvantage: When "the" is typed as "hte" it sounds quite different ("@"
+ * vs "ht") and goes down in the list.
+ * Used when 'spellsuggest' is set to "best".
+ */
+#define RESCORE(word_score, sound_score) ((3 * word_score + sound_score) / 4)
+
+/*
+ * Do the opposite: based on a maximum end score and a known sound score,
+ * compute the the maximum word score that can be used.
+ */
+#define MAXSCORE(word_score, sound_score) ((4 * word_score - sound_score) / 3)
+
+/*
+ * Vim spell file format: <HEADER>
+ *			  <SECTIONS>
+ *			  <LWORDTREE>
+ *			  <KWORDTREE>
+ *			  <PREFIXTREE>
+ *
+ * <HEADER>: <fileID> <versionnr>
+ *
+ * <fileID>     8 bytes    "VIMspell"
+ * <versionnr>  1 byte	    VIMSPELLVERSION
+ *
+ *
+ * Sections make it possible to add information to the .spl file without
+ * making it incompatible with previous versions.  There are two kinds of
+ * sections:
+ * 1. Not essential for correct spell checking.  E.g. for making suggestions.
+ *    These are skipped when not supported.
+ * 2. Optional information, but essential for spell checking when present.
+ *    E.g. conditions for affixes.  When this section is present but not
+ *    supported an error message is given.
+ *
+ * <SECTIONS>: <section> ... <sectionend>
+ *
+ * <section>: <sectionID> <sectionflags> <sectionlen> (section contents)
+ *
+ * <sectionID>	  1 byte    number from 0 to 254 identifying the section
+ *
+ * <sectionflags> 1 byte    SNF_REQUIRED: this section is required for correct
+ *					    spell checking
+ *
+ * <sectionlen>   4 bytes   length of section contents, MSB first
+ *
+ * <sectionend>	  1 byte    SN_END
+ *
+ *
+ * sectionID == SN_INFO: <infotext>
+ * <infotext>	 N bytes    free format text with spell file info (version,
+ *			    website, etc)
+ *
+ * sectionID == SN_REGION: <regionname> ...
+ * <regionname>	 2 bytes    Up to 8 region names: ca, au, etc.  Lower case.
+ *			    First <regionname> is region 1.
+ *
+ * sectionID == SN_CHARFLAGS: <charflagslen> <charflags>
+ *				<folcharslen> <folchars>
+ * <charflagslen> 1 byte    Number of bytes in <charflags> (should be 128).
+ * <charflags>  N bytes     List of flags (first one is for character 128):
+ *			    0x01  word character	CF_WORD
+ *			    0x02  upper-case character	CF_UPPER
+ * <folcharslen>  2 bytes   Number of bytes in <folchars>.
+ * <folchars>     N bytes   Folded characters, first one is for character 128.
+ *
+ * sectionID == SN_MIDWORD: <midword>
+ * <midword>     N bytes    Characters that are word characters only when used
+ *			    in the middle of a word.
+ *
+ * sectionID == SN_PREFCOND: <prefcondcnt> <prefcond> ...
+ * <prefcondcnt> 2 bytes    Number of <prefcond> items following.
+ * <prefcond> : <condlen> <condstr>
+ * <condlen>	1 byte	    Length of <condstr>.
+ * <condstr>	N bytes	    Condition for the prefix.
+ *
+ * sectionID == SN_REP: <repcount> <rep> ...
+ * <repcount>	 2 bytes    number of <rep> items, MSB first.
+ * <rep> : <repfromlen> <repfrom> <reptolen> <repto>
+ * <repfromlen>	 1 byte	    length of <repfrom>
+ * <repfrom>	 N bytes    "from" part of replacement
+ * <reptolen>	 1 byte	    length of <repto>
+ * <repto>	 N bytes    "to" part of replacement
+ *
+ * sectionID == SN_REPSAL: <repcount> <rep> ...
+ *   just like SN_REP but for soundfolded words
+ *
+ * sectionID == SN_SAL: <salflags> <salcount> <sal> ...
+ * <salflags>	 1 byte	    flags for soundsalike conversion:
+ *			    SAL_F0LLOWUP
+ *			    SAL_COLLAPSE
+ *			    SAL_REM_ACCENTS
+ * <salcount>    2 bytes    number of <sal> items following
+ * <sal> : <salfromlen> <salfrom> <saltolen> <salto>
+ * <salfromlen>	 1 byte	    length of <salfrom>
+ * <salfrom>	 N bytes    "from" part of soundsalike
+ * <saltolen>	 1 byte	    length of <salto>
+ * <salto>	 N bytes    "to" part of soundsalike
+ *
+ * sectionID == SN_SOFO: <sofofromlen> <sofofrom> <sofotolen> <sofoto>
+ * <sofofromlen> 2 bytes    length of <sofofrom>
+ * <sofofrom>	 N bytes    "from" part of soundfold
+ * <sofotolen>	 2 bytes    length of <sofoto>
+ * <sofoto>	 N bytes    "to" part of soundfold
+ *
+ * sectionID == SN_SUGFILE: <timestamp>
+ * <timestamp>   8 bytes    time in seconds that must match with .sug file
+ *
+ * sectionID == SN_NOSPLITSUGS: nothing
+ *
+ * sectionID == SN_WORDS: <word> ...
+ * <word>	 N bytes    NUL terminated common word
+ *
+ * sectionID == SN_MAP: <mapstr>
+ * <mapstr>	 N bytes    String with sequences of similar characters,
+ *			    separated by slashes.
+ *
+ * sectionID == SN_COMPOUND: <compmax> <compminlen> <compsylmax> <compoptions>
+ *				<comppatcount> <comppattern> ... <compflags>
+ * <compmax>     1 byte	    Maximum nr of words in compound word.
+ * <compminlen>  1 byte	    Minimal word length for compounding.
+ * <compsylmax>  1 byte	    Maximum nr of syllables in compound word.
+ * <compoptions> 2 bytes    COMP_ flags.
+ * <comppatcount> 2 bytes   number of <comppattern> following
+ * <compflags>   N bytes    Flags from COMPOUNDRULE items, separated by
+ *			    slashes.
+ *
+ * <comppattern>: <comppatlen> <comppattext>
+ * <comppatlen>	 1 byte	    length of <comppattext>
+ * <comppattext> N bytes    end or begin chars from CHECKCOMPOUNDPATTERN
+ *
+ * sectionID == SN_NOBREAK: (empty, its presence is what matters)
+ *
+ * sectionID == SN_SYLLABLE: <syllable>
+ * <syllable>    N bytes    String from SYLLABLE item.
+ *
+ * <LWORDTREE>: <wordtree>
+ *
+ * <KWORDTREE>: <wordtree>
+ *
+ * <PREFIXTREE>: <wordtree>
+ *
+ *
+ * <wordtree>: <nodecount> <nodedata> ...
+ *
+ * <nodecount>	4 bytes	    Number of nodes following.  MSB first.
+ *
+ * <nodedata>: <siblingcount> <sibling> ...
+ *
+ * <siblingcount> 1 byte    Number of siblings in this node.  The siblings
+ *			    follow in sorted order.
+ *
+ * <sibling>: <byte> [ <nodeidx> <xbyte>
+ *		      | <flags> [<flags2>] [<region>] [<affixID>]
+ *		      | [<pflags>] <affixID> <prefcondnr> ]
+ *
+ * <byte>	1 byte	    Byte value of the sibling.  Special cases:
+ *			    BY_NOFLAGS: End of word without flags and for all
+ *					regions.
+ *					For PREFIXTREE <affixID> and
+ *					<prefcondnr> follow.
+ *			    BY_FLAGS:   End of word, <flags> follow.
+ *					For PREFIXTREE <pflags>, <affixID>
+ *					and <prefcondnr> follow.
+ *			    BY_FLAGS2:  End of word, <flags> and <flags2>
+ *					follow.  Not used in PREFIXTREE.
+ *			    BY_INDEX:   Child of sibling is shared, <nodeidx>
+ *					and <xbyte> follow.
+ *
+ * <nodeidx>	3 bytes	    Index of child for this sibling, MSB first.
+ *
+ * <xbyte>	1 byte	    byte value of the sibling.
+ *
+ * <flags>	1 byte	    bitmask of:
+ *			    WF_ALLCAP	word must have only capitals
+ *			    WF_ONECAP   first char of word must be capital
+ *			    WF_KEEPCAP	keep-case word
+ *			    WF_FIXCAP   keep-case word, all caps not allowed
+ *			    WF_RARE	rare word
+ *			    WF_BANNED	bad word
+ *			    WF_REGION	<region> follows
+ *			    WF_AFX	<affixID> follows
+ *
+ * <flags2>	1 byte	    Bitmask of:
+ *			    WF_HAS_AFF >> 8   word includes affix
+ *			    WF_NEEDCOMP >> 8  word only valid in compound
+ *			    WF_NOSUGGEST >> 8  word not used for suggestions
+ *			    WF_COMPROOT >> 8  word already a compound
+ *			    WF_NOCOMPBEF >> 8 no compounding before this word
+ *			    WF_NOCOMPAFT >> 8 no compounding after this word
+ *
+ * <pflags>	1 byte	    bitmask of:
+ *			    WFP_RARE	rare prefix
+ *			    WFP_NC	non-combining prefix
+ *			    WFP_UP	letter after prefix made upper case
+ *
+ * <region>	1 byte	    Bitmask for regions in which word is valid.  When
+ *			    omitted it's valid in all regions.
+ *			    Lowest bit is for region 1.
+ *
+ * <affixID>	1 byte	    ID of affix that can be used with this word.  In
+ *			    PREFIXTREE used for the required prefix ID.
+ *
+ * <prefcondnr>	2 bytes	    Prefix condition number, index in <prefcond> list
+ *			    from HEADER.
+ *
+ * All text characters are in 'encoding', but stored as single bytes.
+ */
+
+/*
+ * Vim .sug file format:  <SUGHEADER>
+ *			  <SUGWORDTREE>
+ *			  <SUGTABLE>
+ *
+ * <SUGHEADER>: <fileID> <versionnr> <timestamp>
+ *
+ * <fileID>     6 bytes     "VIMsug"
+ * <versionnr>  1 byte      VIMSUGVERSION
+ * <timestamp>  8 bytes     timestamp that must match with .spl file
+ *
+ *
+ * <SUGWORDTREE>: <wordtree>  (see above, no flags or region used)
+ *
+ *
+ * <SUGTABLE>: <sugwcount> <sugline> ...
+ *
+ * <sugwcount>	4 bytes	    number of <sugline> following
+ *
+ * <sugline>: <sugnr> ... NUL
+ *
+ * <sugnr>:     X bytes     word number that results in this soundfolded word,
+ *			    stored as an offset to the previous number in as
+ *			    few bytes as possible, see offset2bytes())
+ */
+
+#if defined(MSDOS) || defined(WIN16) || defined(WIN32) || defined(_WIN64)
+# include "vimio.h"	/* for lseek(), must be before vim.h */
+#endif
+
+#include "vim.h"
+
+#if defined(FEAT_SPELL) || defined(PROTO)
+
+#ifdef HAVE_FCNTL_H
+# include <fcntl.h>
+#endif
+
+#ifndef UNIX		/* it's in os_unix.h for Unix */
+# include <time.h>	/* for time_t */
+#endif
+
+#define MAXWLEN 250		/* Assume max. word len is this many bytes.
+				   Some places assume a word length fits in a
+				   byte, thus it can't be above 255. */
+
+/* Type used for indexes in the word tree need to be at least 4 bytes.  If int
+ * is 8 bytes we could use something smaller, but what? */
+#if SIZEOF_INT > 3
+typedef int idx_T;
+#else
+typedef long idx_T;
+#endif
+
+/* Flags used for a word.  Only the lowest byte can be used, the region byte
+ * comes above it. */
+#define WF_REGION   0x01	/* region byte follows */
+#define WF_ONECAP   0x02	/* word with one capital (or all capitals) */
+#define WF_ALLCAP   0x04	/* word must be all capitals */
+#define WF_RARE	    0x08	/* rare word */
+#define WF_BANNED   0x10	/* bad word */
+#define WF_AFX	    0x20	/* affix ID follows */
+#define WF_FIXCAP   0x40	/* keep-case word, allcap not allowed */
+#define WF_KEEPCAP  0x80	/* keep-case word */
+
+/* for <flags2>, shifted up one byte to be used in wn_flags */
+#define WF_HAS_AFF  0x0100	/* word includes affix */
+#define WF_NEEDCOMP 0x0200	/* word only valid in compound */
+#define WF_NOSUGGEST 0x0400	/* word not to be suggested */
+#define WF_COMPROOT 0x0800	/* already compounded word, COMPOUNDROOT */
+#define WF_NOCOMPBEF 0x1000	/* no compounding before this word */
+#define WF_NOCOMPAFT 0x2000	/* no compounding after this word */
+
+/* only used for su_badflags */
+#define WF_MIXCAP   0x20	/* mix of upper and lower case: macaRONI */
+
+#define WF_CAPMASK (WF_ONECAP | WF_ALLCAP | WF_KEEPCAP | WF_FIXCAP)
+
+/* flags for <pflags> */
+#define WFP_RARE	    0x01	/* rare prefix */
+#define WFP_NC		    0x02	/* prefix is not combining */
+#define WFP_UP		    0x04	/* to-upper prefix */
+#define WFP_COMPPERMIT	    0x08	/* prefix with COMPOUNDPERMITFLAG */
+#define WFP_COMPFORBID	    0x10	/* prefix with COMPOUNDFORBIDFLAG */
+
+/* Flags for postponed prefixes in "sl_pidxs".  Must be above affixID (one
+ * byte) and prefcondnr (two bytes). */
+#define WF_RAREPFX  (WFP_RARE << 24)	/* rare postponed prefix */
+#define WF_PFX_NC   (WFP_NC << 24)	/* non-combining postponed prefix */
+#define WF_PFX_UP   (WFP_UP << 24)	/* to-upper postponed prefix */
+#define WF_PFX_COMPPERMIT (WFP_COMPPERMIT << 24) /* postponed prefix with
+						  * COMPOUNDPERMITFLAG */
+#define WF_PFX_COMPFORBID (WFP_COMPFORBID << 24) /* postponed prefix with
+						  * COMPOUNDFORBIDFLAG */
+
+
+/* flags for <compoptions> */
+#define COMP_CHECKDUP		1	/* CHECKCOMPOUNDDUP */
+#define COMP_CHECKREP		2	/* CHECKCOMPOUNDREP */
+#define COMP_CHECKCASE		4	/* CHECKCOMPOUNDCASE */
+#define COMP_CHECKTRIPLE	8	/* CHECKCOMPOUNDTRIPLE */
+
+/* Special byte values for <byte>.  Some are only used in the tree for
+ * postponed prefixes, some only in the other trees.  This is a bit messy... */
+#define BY_NOFLAGS	0	/* end of word without flags or region; for
+				 * postponed prefix: no <pflags> */
+#define BY_INDEX	1	/* child is shared, index follows */
+#define BY_FLAGS	2	/* end of word, <flags> byte follows; for
+				 * postponed prefix: <pflags> follows */
+#define BY_FLAGS2	3	/* end of word, <flags> and <flags2> bytes
+				 * follow; never used in prefix tree */
+#define BY_SPECIAL  BY_FLAGS2	/* highest special byte value */
+
+/* Info from "REP", "REPSAL" and "SAL" entries in ".aff" file used in si_rep,
+ * si_repsal, sl_rep, and si_sal.  Not for sl_sal!
+ * One replacement: from "ft_from" to "ft_to". */
+typedef struct fromto_S
+{
+    char_u	*ft_from;
+    char_u	*ft_to;
+} fromto_T;
+
+/* Info from "SAL" entries in ".aff" file used in sl_sal.
+ * The info is split for quick processing by spell_soundfold().
+ * Note that "sm_oneof" and "sm_rules" point into sm_lead. */
+typedef struct salitem_S
+{
+    char_u	*sm_lead;	/* leading letters */
+    int		sm_leadlen;	/* length of "sm_lead" */
+    char_u	*sm_oneof;	/* letters from () or NULL */
+    char_u	*sm_rules;	/* rules like ^, $, priority */
+    char_u	*sm_to;		/* replacement. */
+#ifdef FEAT_MBYTE
+    int		*sm_lead_w;	/* wide character copy of "sm_lead" */
+    int		*sm_oneof_w;	/* wide character copy of "sm_oneof" */
+    int		*sm_to_w;	/* wide character copy of "sm_to" */
+#endif
+} salitem_T;
+
+#ifdef FEAT_MBYTE
+typedef int salfirst_T;
+#else
+typedef short salfirst_T;
+#endif
+
+/* Values for SP_*ERROR are negative, positive values are used by
+ * read_cnt_string(). */
+#define	SP_TRUNCERROR	-1	/* spell file truncated error */
+#define	SP_FORMERROR	-2	/* format error in spell file */
+#define SP_OTHERERROR	-3	/* other error while reading spell file */
+
+/*
+ * Structure used to store words and other info for one language, loaded from
+ * a .spl file.
+ * The main access is through the tree in "sl_fbyts/sl_fidxs", storing the
+ * case-folded words.  "sl_kbyts/sl_kidxs" is for keep-case words.
+ *
+ * The "byts" array stores the possible bytes in each tree node, preceded by
+ * the number of possible bytes, sorted on byte value:
+ *	<len> <byte1> <byte2> ...
+ * The "idxs" array stores the index of the child node corresponding to the
+ * byte in "byts".
+ * Exception: when the byte is zero, the word may end here and "idxs" holds
+ * the flags, region mask and affixID for the word.  There may be several
+ * zeros in sequence for alternative flag/region/affixID combinations.
+ */
+typedef struct slang_S slang_T;
+struct slang_S
+{
+    slang_T	*sl_next;	/* next language */
+    char_u	*sl_name;	/* language name "en", "en.rare", "nl", etc. */
+    char_u	*sl_fname;	/* name of .spl file */
+    int		sl_add;		/* TRUE if it's a .add file. */
+
+    char_u	*sl_fbyts;	/* case-folded word bytes */
+    idx_T	*sl_fidxs;	/* case-folded word indexes */
+    char_u	*sl_kbyts;	/* keep-case word bytes */
+    idx_T	*sl_kidxs;	/* keep-case word indexes */
+    char_u	*sl_pbyts;	/* prefix tree word bytes */
+    idx_T	*sl_pidxs;	/* prefix tree word indexes */
+
+    char_u	*sl_info;	/* infotext string or NULL */
+
+    char_u	sl_regions[17];	/* table with up to 8 region names plus NUL */
+
+    char_u	*sl_midword;	/* MIDWORD string or NULL */
+
+    hashtab_T	sl_wordcount;	/* hashtable with word count, wordcount_T */
+
+    int		sl_compmax;	/* COMPOUNDWORDMAX (default: MAXWLEN) */
+    int		sl_compminlen;	/* COMPOUNDMIN (default: 0) */
+    int		sl_compsylmax;	/* COMPOUNDSYLMAX (default: MAXWLEN) */
+    int		sl_compoptions;	/* COMP_* flags */
+    garray_T	sl_comppat;	/* CHECKCOMPOUNDPATTERN items */
+    regprog_T	*sl_compprog;	/* COMPOUNDRULE turned into a regexp progrm
+				 * (NULL when no compounding) */
+    char_u	*sl_compstartflags; /* flags for first compound word */
+    char_u	*sl_compallflags; /* all flags for compound words */
+    char_u	sl_nobreak;	/* When TRUE: no spaces between words */
+    char_u	*sl_syllable;	/* SYLLABLE repeatable chars or NULL */
+    garray_T	sl_syl_items;	/* syllable items */
+
+    int		sl_prefixcnt;	/* number of items in "sl_prefprog" */
+    regprog_T	**sl_prefprog;	/* table with regprogs for prefixes */
+
+    garray_T	sl_rep;		/* list of fromto_T entries from REP lines */
+    short	sl_rep_first[256];  /* indexes where byte first appears, -1 if
+				       there is none */
+    garray_T	sl_sal;		/* list of salitem_T entries from SAL lines */
+    salfirst_T	sl_sal_first[256];  /* indexes where byte first appears, -1 if
+				       there is none */
+    int		sl_followup;	/* SAL followup */
+    int		sl_collapse;	/* SAL collapse_result */
+    int		sl_rem_accents;	/* SAL remove_accents */
+    int		sl_sofo;	/* SOFOFROM and SOFOTO instead of SAL items:
+				 * "sl_sal_first" maps chars, when has_mbyte
+				 * "sl_sal" is a list of wide char lists. */
+    garray_T	sl_repsal;	/* list of fromto_T entries from REPSAL lines */
+    short	sl_repsal_first[256];  /* sl_rep_first for REPSAL lines */
+    int		sl_nosplitsugs;	/* don't suggest splitting a word */
+
+    /* Info from the .sug file.  Loaded on demand. */
+    time_t	sl_sugtime;	/* timestamp for .sug file */
+    char_u	*sl_sbyts;	/* soundfolded word bytes */
+    idx_T	*sl_sidxs;	/* soundfolded word indexes */
+    buf_T	*sl_sugbuf;	/* buffer with word number table */
+    int		sl_sugloaded;	/* TRUE when .sug file was loaded or failed to
+				   load */
+
+    int		sl_has_map;	/* TRUE if there is a MAP line */
+#ifdef FEAT_MBYTE
+    hashtab_T	sl_map_hash;	/* MAP for multi-byte chars */
+    int		sl_map_array[256]; /* MAP for first 256 chars */
+#else
+    char_u	sl_map_array[256]; /* MAP for first 256 chars */
+#endif
+    hashtab_T	sl_sounddone;	/* table with soundfolded words that have
+				   handled, see add_sound_suggest() */
+};
+
+/* First language that is loaded, start of the linked list of loaded
+ * languages. */
+static slang_T *first_lang = NULL;
+
+/* Flags used in .spl file for soundsalike flags. */
+#define SAL_F0LLOWUP		1
+#define SAL_COLLAPSE		2
+#define SAL_REM_ACCENTS		4
+
+/*
+ * Structure used in "b_langp", filled from 'spelllang'.
+ */
+typedef struct langp_S
+{
+    slang_T	*lp_slang;	/* info for this language */
+    slang_T	*lp_sallang;	/* language used for sound folding or NULL */
+    slang_T	*lp_replang;	/* language used for REP items or NULL */
+    int		lp_region;	/* bitmask for region or REGION_ALL */
+} langp_T;
+
+#define LANGP_ENTRY(ga, i)	(((langp_T *)(ga).ga_data) + (i))
+
+#define REGION_ALL 0xff		/* word valid in all regions */
+
+#define VIMSPELLMAGIC "VIMspell"  /* string at start of Vim spell file */
+#define VIMSPELLMAGICL 8
+#define VIMSPELLVERSION 50
+
+#define VIMSUGMAGIC "VIMsug"	/* string at start of Vim .sug file */
+#define VIMSUGMAGICL 6
+#define VIMSUGVERSION 1
+
+/* Section IDs.  Only renumber them when VIMSPELLVERSION changes! */
+#define SN_REGION	0	/* <regionname> section */
+#define SN_CHARFLAGS	1	/* charflags section */
+#define SN_MIDWORD	2	/* <midword> section */
+#define SN_PREFCOND	3	/* <prefcond> section */
+#define SN_REP		4	/* REP items section */
+#define SN_SAL		5	/* SAL items section */
+#define SN_SOFO		6	/* soundfolding section */
+#define SN_MAP		7	/* MAP items section */
+#define SN_COMPOUND	8	/* compound words section */
+#define SN_SYLLABLE	9	/* syllable section */
+#define SN_NOBREAK	10	/* NOBREAK section */
+#define SN_SUGFILE	11	/* timestamp for .sug file */
+#define SN_REPSAL	12	/* REPSAL items section */
+#define SN_WORDS	13	/* common words */
+#define SN_NOSPLITSUGS	14	/* don't split word for suggestions */
+#define SN_INFO		15	/* info section */
+#define SN_END		255	/* end of sections */
+
+#define SNF_REQUIRED	1	/* <sectionflags>: required section */
+
+/* Result values.  Lower number is accepted over higher one. */
+#define SP_BANNED	-1
+#define SP_OK		0
+#define SP_RARE		1
+#define SP_LOCAL	2
+#define SP_BAD		3
+
+/* file used for "zG" and "zW" */
+static char_u	*int_wordlist = NULL;
+
+typedef struct wordcount_S
+{
+    short_u	wc_count;	    /* nr of times word was seen */
+    char_u	wc_word[1];	    /* word, actually longer */
+} wordcount_T;
+
+static wordcount_T dumwc;
+#define WC_KEY_OFF  (unsigned)(dumwc.wc_word - (char_u *)&dumwc)
+#define HI2WC(hi)     ((wordcount_T *)((hi)->hi_key - WC_KEY_OFF))
+#define MAXWORDCOUNT 0xffff
+
+/*
+ * Information used when looking for suggestions.
+ */
+typedef struct suginfo_S
+{
+    garray_T	su_ga;		    /* suggestions, contains "suggest_T" */
+    int		su_maxcount;	    /* max. number of suggestions displayed */
+    int		su_maxscore;	    /* maximum score for adding to su_ga */
+    int		su_sfmaxscore;	    /* idem, for when doing soundfold words */
+    garray_T	su_sga;		    /* like su_ga, sound-folded scoring */
+    char_u	*su_badptr;	    /* start of bad word in line */
+    int		su_badlen;	    /* length of detected bad word in line */
+    int		su_badflags;	    /* caps flags for bad word */
+    char_u	su_badword[MAXWLEN]; /* bad word truncated at su_badlen */
+    char_u	su_fbadword[MAXWLEN]; /* su_badword case-folded */
+    char_u	su_sal_badword[MAXWLEN]; /* su_badword soundfolded */
+    hashtab_T	su_banned;	    /* table with banned words */
+    slang_T	*su_sallang;	    /* default language for sound folding */
+} suginfo_T;
+
+/* One word suggestion.  Used in "si_ga". */
+typedef struct suggest_S
+{
+    char_u	*st_word;	/* suggested word, allocated string */
+    int		st_wordlen;	/* STRLEN(st_word) */
+    int		st_orglen;	/* length of replaced text */
+    int		st_score;	/* lower is better */
+    int		st_altscore;	/* used when st_score compares equal */
+    int		st_salscore;	/* st_score is for soundalike */
+    int		st_had_bonus;	/* bonus already included in score */
+    slang_T	*st_slang;	/* language used for sound folding */
+} suggest_T;
+
+#define SUG(ga, i) (((suggest_T *)(ga).ga_data)[i])
+
+/* TRUE if a word appears in the list of banned words.  */
+#define WAS_BANNED(su, word) (!HASHITEM_EMPTY(hash_find(&su->su_banned, word)))
+
+/* Number of suggestions kept when cleaning up.  we need to keep more than
+ * what is displayed, because when rescore_suggestions() is called the score
+ * may change and wrong suggestions may be removed later. */
+#define SUG_CLEAN_COUNT(su)    ((su)->su_maxcount < 130 ? 150 : (su)->su_maxcount + 20)
+
+/* Threshold for sorting and cleaning up suggestions.  Don't want to keep lots
+ * of suggestions that are not going to be displayed. */
+#define SUG_MAX_COUNT(su)	(SUG_CLEAN_COUNT(su) + 50)
+
+/* score for various changes */
+#define SCORE_SPLIT	149	/* split bad word */
+#define SCORE_SPLIT_NO	249	/* split bad word with NOSPLITSUGS */
+#define SCORE_ICASE	52	/* slightly different case */
+#define SCORE_REGION	200	/* word is for different region */
+#define SCORE_RARE	180	/* rare word */
+#define SCORE_SWAP	75	/* swap two characters */
+#define SCORE_SWAP3	110	/* swap two characters in three */
+#define SCORE_REP	65	/* REP replacement */
+#define SCORE_SUBST	93	/* substitute a character */
+#define SCORE_SIMILAR	33	/* substitute a similar character */
+#define SCORE_SUBCOMP	33	/* substitute a composing character */
+#define SCORE_DEL	94	/* delete a character */
+#define SCORE_DELDUP	66	/* delete a duplicated character */
+#define SCORE_DELCOMP	28	/* delete a composing character */
+#define SCORE_INS	96	/* insert a character */
+#define SCORE_INSDUP	67	/* insert a duplicate character */
+#define SCORE_INSCOMP	30	/* insert a composing character */
+#define SCORE_NONWORD	103	/* change non-word to word char */
+
+#define SCORE_FILE	30	/* suggestion from a file */
+#define SCORE_MAXINIT	350	/* Initial maximum score: higher == slower.
+				 * 350 allows for about three changes. */
+
+#define SCORE_COMMON1	30	/* subtracted for words seen before */
+#define SCORE_COMMON2	40	/* subtracted for words often seen */
+#define SCORE_COMMON3	50	/* subtracted for words very often seen */
+#define SCORE_THRES2	10	/* word count threshold for COMMON2 */
+#define SCORE_THRES3	100	/* word count threshold for COMMON3 */
+
+/* When trying changed soundfold words it becomes slow when trying more than
+ * two changes.  With less then two changes it's slightly faster but we miss a
+ * few good suggestions.  In rare cases we need to try three of four changes.
+ */
+#define SCORE_SFMAX1	200	/* maximum score for first try */
+#define SCORE_SFMAX2	300	/* maximum score for second try */
+#define SCORE_SFMAX3	400	/* maximum score for third try */
+
+#define SCORE_BIG	SCORE_INS * 3	/* big difference */
+#define SCORE_MAXMAX	999999		/* accept any score */
+#define SCORE_LIMITMAX	350		/* for spell_edit_score_limit() */
+
+/* for spell_edit_score_limit() we need to know the minimum value of
+ * SCORE_ICASE, SCORE_SWAP, SCORE_DEL, SCORE_SIMILAR and SCORE_INS */
+#define SCORE_EDIT_MIN	SCORE_SIMILAR
+
+/*
+ * Structure to store info for word matching.
+ */
+typedef struct matchinf_S
+{
+    langp_T	*mi_lp;			/* info for language and region */
+
+    /* pointers to original text to be checked */
+    char_u	*mi_word;		/* start of word being checked */
+    char_u	*mi_end;		/* end of matching word so far */
+    char_u	*mi_fend;		/* next char to be added to mi_fword */
+    char_u	*mi_cend;		/* char after what was used for
+					   mi_capflags */
+
+    /* case-folded text */
+    char_u	mi_fword[MAXWLEN + 1];	/* mi_word case-folded */
+    int		mi_fwordlen;		/* nr of valid bytes in mi_fword */
+
+    /* for when checking word after a prefix */
+    int		mi_prefarridx;		/* index in sl_pidxs with list of
+					   affixID/condition */
+    int		mi_prefcnt;		/* number of entries at mi_prefarridx */
+    int		mi_prefixlen;		/* byte length of prefix */
+#ifdef FEAT_MBYTE
+    int		mi_cprefixlen;		/* byte length of prefix in original
+					   case */
+#else
+# define mi_cprefixlen mi_prefixlen	/* it's the same value */
+#endif
+
+    /* for when checking a compound word */
+    int		mi_compoff;		/* start of following word offset */
+    char_u	mi_compflags[MAXWLEN];	/* flags for compound words used */
+    int		mi_complen;		/* nr of compound words used */
+    int		mi_compextra;		/* nr of COMPOUNDROOT words */
+
+    /* others */
+    int		mi_result;		/* result so far: SP_BAD, SP_OK, etc. */
+    int		mi_capflags;		/* WF_ONECAP WF_ALLCAP WF_KEEPCAP */
+    buf_T	*mi_buf;		/* buffer being checked */
+
+    /* for NOBREAK */
+    int		mi_result2;		/* "mi_resul" without following word */
+    char_u	*mi_end2;		/* "mi_end" without following word */
+} matchinf_T;
+
+/*
+ * The tables used for recognizing word characters according to spelling.
+ * These are only used for the first 256 characters of 'encoding'.
+ */
+typedef struct spelltab_S
+{
+    char_u  st_isw[256];	/* flags: is word char */
+    char_u  st_isu[256];	/* flags: is uppercase char */
+    char_u  st_fold[256];	/* chars: folded case */
+    char_u  st_upper[256];	/* chars: upper case */
+} spelltab_T;
+
+static spelltab_T   spelltab;
+static int	    did_set_spelltab;
+
+#define CF_WORD		0x01
+#define CF_UPPER	0x02
+
+static void clear_spell_chartab __ARGS((spelltab_T *sp));
+static int set_spell_finish __ARGS((spelltab_T	*new_st));
+static int spell_iswordp __ARGS((char_u *p, buf_T *buf));
+static int spell_iswordp_nmw __ARGS((char_u *p));
+#ifdef FEAT_MBYTE
+static int spell_iswordp_w __ARGS((int *p, buf_T *buf));
+#endif
+static int write_spell_prefcond __ARGS((FILE *fd, garray_T *gap));
+
+/*
+ * For finding suggestions: At each node in the tree these states are tried:
+ */
+typedef enum
+{
+    STATE_START = 0,	/* At start of node check for NUL bytes (goodword
+			 * ends); if badword ends there is a match, otherwise
+			 * try splitting word. */
+    STATE_NOPREFIX,	/* try without prefix */
+    STATE_SPLITUNDO,	/* Undo splitting. */
+    STATE_ENDNUL,	/* Past NUL bytes at start of the node. */
+    STATE_PLAIN,	/* Use each byte of the node. */
+    STATE_DEL,		/* Delete a byte from the bad word. */
+    STATE_INS_PREP,	/* Prepare for inserting bytes. */
+    STATE_INS,		/* Insert a byte in the bad word. */
+    STATE_SWAP,		/* Swap two bytes. */
+    STATE_UNSWAP,	/* Undo swap two characters. */
+    STATE_SWAP3,	/* Swap two characters over three. */
+    STATE_UNSWAP3,	/* Undo Swap two characters over three. */
+    STATE_UNROT3L,	/* Undo rotate three characters left */
+    STATE_UNROT3R,	/* Undo rotate three characters right */
+    STATE_REP_INI,	/* Prepare for using REP items. */
+    STATE_REP,		/* Use matching REP items from the .aff file. */
+    STATE_REP_UNDO,	/* Undo a REP item replacement. */
+    STATE_FINAL		/* End of this node. */
+} state_T;
+
+/*
+ * Struct to keep the state at each level in suggest_try_change().
+ */
+typedef struct trystate_S
+{
+    state_T	ts_state;	/* state at this level, STATE_ */
+    int		ts_score;	/* score */
+    idx_T	ts_arridx;	/* index in tree array, start of node */
+    short	ts_curi;	/* index in list of child nodes */
+    char_u	ts_fidx;	/* index in fword[], case-folded bad word */
+    char_u	ts_fidxtry;	/* ts_fidx at which bytes may be changed */
+    char_u	ts_twordlen;	/* valid length of tword[] */
+    char_u	ts_prefixdepth;	/* stack depth for end of prefix or
+				 * PFD_PREFIXTREE or PFD_NOPREFIX */
+    char_u	ts_flags;	/* TSF_ flags */
+#ifdef FEAT_MBYTE
+    char_u	ts_tcharlen;	/* number of bytes in tword character */
+    char_u	ts_tcharidx;	/* current byte index in tword character */
+    char_u	ts_isdiff;	/* DIFF_ values */
+    char_u	ts_fcharstart;	/* index in fword where badword char started */
+#endif
+    char_u	ts_prewordlen;	/* length of word in "preword[]" */
+    char_u	ts_splitoff;	/* index in "tword" after last split */
+    char_u	ts_splitfidx;	/* "ts_fidx" at word split */
+    char_u	ts_complen;	/* nr of compound words used */
+    char_u	ts_compsplit;	/* index for "compflags" where word was spit */
+    char_u	ts_save_badflags;   /* su_badflags saved here */
+    char_u	ts_delidx;	/* index in fword for char that was deleted,
+				   valid when "ts_flags" has TSF_DIDDEL */
+} trystate_T;
+
+/* values for ts_isdiff */
+#define DIFF_NONE	0	/* no different byte (yet) */
+#define DIFF_YES	1	/* different byte found */
+#define DIFF_INSERT	2	/* inserting character */
+
+/* values for ts_flags */
+#define TSF_PREFIXOK	1	/* already checked that prefix is OK */
+#define TSF_DIDSPLIT	2	/* tried split at this point */
+#define TSF_DIDDEL	4	/* did a delete, "ts_delidx" has index */
+
+/* special values ts_prefixdepth */
+#define PFD_NOPREFIX	0xff	/* not using prefixes */
+#define PFD_PREFIXTREE	0xfe	/* walking through the prefix tree */
+#define PFD_NOTSPECIAL	0xfd	/* highest value that's not special */
+
+/* mode values for find_word */
+#define FIND_FOLDWORD	    0	/* find word case-folded */
+#define FIND_KEEPWORD	    1	/* find keep-case word */
+#define FIND_PREFIX	    2	/* find word after prefix */
+#define FIND_COMPOUND	    3	/* find case-folded compound word */
+#define FIND_KEEPCOMPOUND   4	/* find keep-case compound word */
+
+static slang_T *slang_alloc __ARGS((char_u *lang));
+static void slang_free __ARGS((slang_T *lp));
+static void slang_clear __ARGS((slang_T *lp));
+static void slang_clear_sug __ARGS((slang_T *lp));
+static void find_word __ARGS((matchinf_T *mip, int mode));
+static int can_compound __ARGS((slang_T *slang, char_u *word, char_u *flags));
+static int valid_word_prefix __ARGS((int totprefcnt, int arridx, int flags, char_u *word, slang_T *slang, int cond_req));
+static void find_prefix __ARGS((matchinf_T *mip, int mode));
+static int fold_more __ARGS((matchinf_T *mip));
+static int spell_valid_case __ARGS((int wordflags, int treeflags));
+static int no_spell_checking __ARGS((win_T *wp));
+static void spell_load_lang __ARGS((char_u *lang));
+static char_u *spell_enc __ARGS((void));
+static void int_wordlist_spl __ARGS((char_u *fname));
+static void spell_load_cb __ARGS((char_u *fname, void *cookie));
+static slang_T *spell_load_file __ARGS((char_u *fname, char_u *lang, slang_T *old_lp, int silent));
+static int get2c __ARGS((FILE *fd));
+static int get3c __ARGS((FILE *fd));
+static int get4c __ARGS((FILE *fd));
+static time_t get8c __ARGS((FILE *fd));
+static char_u *read_cnt_string __ARGS((FILE *fd, int cnt_bytes, int *lenp));
+static char_u *read_string __ARGS((FILE *fd, int cnt));
+static int read_region_section __ARGS((FILE *fd, slang_T *slang, int len));
+static int read_charflags_section __ARGS((FILE *fd));
+static int read_prefcond_section __ARGS((FILE *fd, slang_T *lp));
+static int read_rep_section __ARGS((FILE *fd, garray_T *gap, short *first));
+static int read_sal_section __ARGS((FILE *fd, slang_T *slang));
+static int read_words_section __ARGS((FILE *fd, slang_T *lp, int len));
+static void count_common_word __ARGS((slang_T *lp, char_u *word, int len, int count));
+static int score_wordcount_adj __ARGS((slang_T *slang, int score, char_u *word, int split));
+static int read_sofo_section __ARGS((FILE *fd, slang_T *slang));
+static int read_compound __ARGS((FILE *fd, slang_T *slang, int len));
+static int byte_in_str __ARGS((char_u *str, int byte));
+static int init_syl_tab __ARGS((slang_T *slang));
+static int count_syllables __ARGS((slang_T *slang, char_u *word));
+static int set_sofo __ARGS((slang_T *lp, char_u *from, char_u *to));
+static void set_sal_first __ARGS((slang_T *lp));
+#ifdef FEAT_MBYTE
+static int *mb_str2wide __ARGS((char_u *s));
+#endif
+static int spell_read_tree __ARGS((FILE *fd, char_u **bytsp, idx_T **idxsp, int prefixtree, int prefixcnt));
+static idx_T read_tree_node __ARGS((FILE *fd, char_u *byts, idx_T *idxs, int maxidx, idx_T startidx, int prefixtree, int maxprefcondnr));
+static void clear_midword __ARGS((buf_T *buf));
+static void use_midword __ARGS((slang_T *lp, buf_T *buf));
+static int find_region __ARGS((char_u *rp, char_u *region));
+static int captype __ARGS((char_u *word, char_u *end));
+static int badword_captype __ARGS((char_u *word, char_u *end));
+static void spell_reload_one __ARGS((char_u *fname, int added_word));
+static void set_spell_charflags __ARGS((char_u *flags, int cnt, char_u *upp));
+static int set_spell_chartab __ARGS((char_u *fol, char_u *low, char_u *upp));
+static int spell_casefold __ARGS((char_u *p, int len, char_u *buf, int buflen));
+static int check_need_cap __ARGS((linenr_T lnum, colnr_T col));
+static void spell_find_suggest __ARGS((char_u *badptr, int badlen, suginfo_T *su, int maxcount, int banbadword, int need_cap, int interactive));
+#ifdef FEAT_EVAL
+static void spell_suggest_expr __ARGS((suginfo_T *su, char_u *expr));
+#endif
+static void spell_suggest_file __ARGS((suginfo_T *su, char_u *fname));
+static void spell_suggest_intern __ARGS((suginfo_T *su, int interactive));
+static void suggest_load_files __ARGS((void));
+static void tree_count_words __ARGS((char_u *byts, idx_T *idxs));
+static void spell_find_cleanup __ARGS((suginfo_T *su));
+static void onecap_copy __ARGS((char_u *word, char_u *wcopy, int upper));
+static void allcap_copy __ARGS((char_u *word, char_u *wcopy));
+static void suggest_try_special __ARGS((suginfo_T *su));
+static void suggest_try_change __ARGS((suginfo_T *su));
+static void suggest_trie_walk __ARGS((suginfo_T *su, langp_T *lp, char_u *fword, int soundfold));
+static void go_deeper __ARGS((trystate_T *stack, int depth, int score_add));
+#ifdef FEAT_MBYTE
+static int nofold_len __ARGS((char_u *fword, int flen, char_u *word));
+#endif
+static void find_keepcap_word __ARGS((slang_T *slang, char_u *fword, char_u *kword));
+static void score_comp_sal __ARGS((suginfo_T *su));
+static void score_combine __ARGS((suginfo_T *su));
+static int stp_sal_score __ARGS((suggest_T *stp, suginfo_T *su, slang_T *slang, char_u *badsound));
+static void suggest_try_soundalike_prep __ARGS((void));
+static void suggest_try_soundalike __ARGS((suginfo_T *su));
+static void suggest_try_soundalike_finish __ARGS((void));
+static void add_sound_suggest __ARGS((suginfo_T *su, char_u *goodword, int score, langp_T *lp));
+static int soundfold_find __ARGS((slang_T *slang, char_u *word));
+static void make_case_word __ARGS((char_u *fword, char_u *cword, int flags));
+static void set_map_str __ARGS((slang_T *lp, char_u *map));
+static int similar_chars __ARGS((slang_T *slang, int c1, int c2));
+static void add_suggestion __ARGS((suginfo_T *su, garray_T *gap, char_u *goodword, int badlen, int score, int altscore, int had_bonus, slang_T *slang, int maxsf));
+static void check_suggestions __ARGS((suginfo_T *su, garray_T *gap));
+static void add_banned __ARGS((suginfo_T *su, char_u *word));
+static void rescore_suggestions __ARGS((suginfo_T *su));
+static void rescore_one __ARGS((suginfo_T *su, suggest_T *stp));
+static int cleanup_suggestions __ARGS((garray_T *gap, int maxscore, int keep));
+static void spell_soundfold __ARGS((slang_T *slang, char_u *inword, int folded, char_u *res));
+static void spell_soundfold_sofo __ARGS((slang_T *slang, char_u *inword, char_u *res));
+static void spell_soundfold_sal __ARGS((slang_T *slang, char_u *inword, char_u *res));
+#ifdef FEAT_MBYTE
+static void spell_soundfold_wsal __ARGS((slang_T *slang, char_u *inword, char_u *res));
+#endif
+static int soundalike_score __ARGS((char_u *goodsound, char_u *badsound));
+static int spell_edit_score __ARGS((slang_T *slang, char_u *badword, char_u *goodword));
+static int spell_edit_score_limit __ARGS((slang_T *slang, char_u *badword, char_u *goodword, int limit));
+#ifdef FEAT_MBYTE
+static int spell_edit_score_limit_w __ARGS((slang_T *slang, char_u *badword, char_u *goodword, int limit));
+#endif
+static void dump_word __ARGS((slang_T *slang, char_u *word, char_u *pat, int *dir, int round, int flags, linenr_T lnum));
+static linenr_T dump_prefixes __ARGS((slang_T *slang, char_u *word, char_u *pat, int *dir, int round, int flags, linenr_T startlnum));
+static buf_T *open_spellbuf __ARGS((void));
+static void close_spellbuf __ARGS((buf_T *buf));
+
+/*
+ * Use our own character-case definitions, because the current locale may
+ * differ from what the .spl file uses.
+ * These must not be called with negative number!
+ */
+#ifndef FEAT_MBYTE
+/* Non-multi-byte implementation. */
+# define SPELL_TOFOLD(c) ((c) < 256 ? spelltab.st_fold[c] : (c))
+# define SPELL_TOUPPER(c) ((c) < 256 ? spelltab.st_upper[c] : (c))
+# define SPELL_ISUPPER(c) ((c) < 256 ? spelltab.st_isu[c] : FALSE)
+#else
+# if defined(HAVE_WCHAR_H)
+#  include <wchar.h>	    /* for towupper() and towlower() */
+# endif
+/* Multi-byte implementation.  For Unicode we can call utf_*(), but don't do
+ * that for ASCII, because we don't want to use 'casemap' here.  Otherwise use
+ * the "w" library function for characters above 255 if available. */
+# ifdef HAVE_TOWLOWER
+#  define SPELL_TOFOLD(c) (enc_utf8 && (c) >= 128 ? utf_fold(c) \
+	    : (c) < 256 ? spelltab.st_fold[c] : towlower(c))
+# else
+#  define SPELL_TOFOLD(c) (enc_utf8 && (c) >= 128 ? utf_fold(c) \
+	    : (c) < 256 ? spelltab.st_fold[c] : (c))
+# endif
+
+# ifdef HAVE_TOWUPPER
+#  define SPELL_TOUPPER(c) (enc_utf8 && (c) >= 128 ? utf_toupper(c) \
+	    : (c) < 256 ? spelltab.st_upper[c] : towupper(c))
+# else
+#  define SPELL_TOUPPER(c) (enc_utf8 && (c) >= 128 ? utf_toupper(c) \
+	    : (c) < 256 ? spelltab.st_upper[c] : (c))
+# endif
+
+# ifdef HAVE_ISWUPPER
+#  define SPELL_ISUPPER(c) (enc_utf8 && (c) >= 128 ? utf_isupper(c) \
+	    : (c) < 256 ? spelltab.st_isu[c] : iswupper(c))
+# else
+#  define SPELL_ISUPPER(c) (enc_utf8 && (c) >= 128 ? utf_isupper(c) \
+	    : (c) < 256 ? spelltab.st_isu[c] : (FALSE))
+# endif
+#endif
+
+
+static char *e_format = N_("E759: Format error in spell file");
+static char *e_spell_trunc = N_("E758: Truncated spell file");
+static char *e_afftrailing = N_("Trailing text in %s line %d: %s");
+static char *e_affname = N_("Affix name too long in %s line %d: %s");
+static char *e_affform = N_("E761: Format error in affix file FOL, LOW or UPP");
+static char *e_affrange = N_("E762: Character in FOL, LOW or UPP is out of range");
+static char *msg_compressing = N_("Compressing word tree...");
+
+/* Remember what "z?" replaced. */
+static char_u	*repl_from = NULL;
+static char_u	*repl_to = NULL;
+
+/*
+ * Main spell-checking function.
+ * "ptr" points to a character that could be the start of a word.
+ * "*attrp" is set to the highlight index for a badly spelled word.  For a
+ * non-word or when it's OK it remains unchanged.
+ * This must only be called when 'spelllang' is not empty.
+ *
+ * "capcol" is used to check for a Capitalised word after the end of a
+ * sentence.  If it's zero then perform the check.  Return the column where to
+ * check next, or -1 when no sentence end was found.  If it's NULL then don't
+ * worry.
+ *
+ * Returns the length of the word in bytes, also when it's OK, so that the
+ * caller can skip over the word.
+ */
+    int
+spell_check(wp, ptr, attrp, capcol, docount)
+    win_T	*wp;		/* current window */
+    char_u	*ptr;
+    hlf_T	*attrp;
+    int		*capcol;	/* column to check for Capital */
+    int		docount;	/* count good words */
+{
+    matchinf_T	mi;		/* Most things are put in "mi" so that it can
+				   be passed to functions quickly. */
+    int		nrlen = 0;	/* found a number first */
+    int		c;
+    int		wrongcaplen = 0;
+    int		lpi;
+    int		count_word = docount;
+
+    /* A word never starts at a space or a control character.  Return quickly
+     * then, skipping over the character. */
+    if (*ptr <= ' ')
+	return 1;
+
+    /* Return here when loading language files failed. */
+    if (wp->w_buffer->b_langp.ga_len == 0)
+	return 1;
+
+    vim_memset(&mi, 0, sizeof(matchinf_T));
+
+    /* A number is always OK.  Also skip hexadecimal numbers 0xFF99 and
+     * 0X99FF.  But always do check spelling to find "3GPP" and "11
+     * julifeest". */
+    if (*ptr >= '0' && *ptr <= '9')
+    {
+	if (*ptr == '0' && (ptr[1] == 'x' || ptr[1] == 'X'))
+	    mi.mi_end = skiphex(ptr + 2);
+	else
+	    mi.mi_end = skipdigits(ptr);
+	nrlen = (int)(mi.mi_end - ptr);
+    }
+
+    /* Find the normal end of the word (until the next non-word character). */
+    mi.mi_word = ptr;
+    mi.mi_fend = ptr;
+    if (spell_iswordp(mi.mi_fend, wp->w_buffer))
+    {
+	do
+	{
+	    mb_ptr_adv(mi.mi_fend);
+	} while (*mi.mi_fend != NUL && spell_iswordp(mi.mi_fend, wp->w_buffer));
+
+	if (capcol != NULL && *capcol == 0 && wp->w_buffer->b_cap_prog != NULL)
+	{
+	    /* Check word starting with capital letter. */
+	    c = PTR2CHAR(ptr);
+	    if (!SPELL_ISUPPER(c))
+		wrongcaplen = (int)(mi.mi_fend - ptr);
+	}
+    }
+    if (capcol != NULL)
+	*capcol = -1;
+
+    /* We always use the characters up to the next non-word character,
+     * also for bad words. */
+    mi.mi_end = mi.mi_fend;
+
+    /* Check caps type later. */
+    mi.mi_buf = wp->w_buffer;
+
+    /* case-fold the word with one non-word character, so that we can check
+     * for the word end. */
+    if (*mi.mi_fend != NUL)
+	mb_ptr_adv(mi.mi_fend);
+
+    (void)spell_casefold(ptr, (int)(mi.mi_fend - ptr), mi.mi_fword,
+							     MAXWLEN + 1);
+    mi.mi_fwordlen = (int)STRLEN(mi.mi_fword);
+
+    /* The word is bad unless we recognize it. */
+    mi.mi_result = SP_BAD;
+    mi.mi_result2 = SP_BAD;
+
+    /*
+     * Loop over the languages specified in 'spelllang'.
+     * We check them all, because a word may be matched longer in another
+     * language.
+     */
+    for (lpi = 0; lpi < wp->w_buffer->b_langp.ga_len; ++lpi)
+    {
+	mi.mi_lp = LANGP_ENTRY(wp->w_buffer->b_langp, lpi);
+
+	/* If reloading fails the language is still in the list but everything
+	 * has been cleared. */
+	if (mi.mi_lp->lp_slang->sl_fidxs == NULL)
+	    continue;
+
+	/* Check for a matching word in case-folded words. */
+	find_word(&mi, FIND_FOLDWORD);
+
+	/* Check for a matching word in keep-case words. */
+	find_word(&mi, FIND_KEEPWORD);
+
+	/* Check for matching prefixes. */
+	find_prefix(&mi, FIND_FOLDWORD);
+
+	/* For a NOBREAK language, may want to use a word without a following
+	 * word as a backup. */
+	if (mi.mi_lp->lp_slang->sl_nobreak && mi.mi_result == SP_BAD
+						   && mi.mi_result2 != SP_BAD)
+	{
+	    mi.mi_result = mi.mi_result2;
+	    mi.mi_end = mi.mi_end2;
+	}
+
+	/* Count the word in the first language where it's found to be OK. */
+	if (count_word && mi.mi_result == SP_OK)
+	{
+	    count_common_word(mi.mi_lp->lp_slang, ptr,
+						   (int)(mi.mi_end - ptr), 1);
+	    count_word = FALSE;
+	}
+    }
+
+    if (mi.mi_result != SP_OK)
+    {
+	/* If we found a number skip over it.  Allows for "42nd".  Do flag
+	 * rare and local words, e.g., "3GPP". */
+	if (nrlen > 0)
+	{
+	    if (mi.mi_result == SP_BAD || mi.mi_result == SP_BANNED)
+		return nrlen;
+	}
+
+	/* When we are at a non-word character there is no error, just
+	 * skip over the character (try looking for a word after it). */
+	else if (!spell_iswordp_nmw(ptr))
+	{
+	    if (capcol != NULL && wp->w_buffer->b_cap_prog != NULL)
+	    {
+		regmatch_T	regmatch;
+
+		/* Check for end of sentence. */
+		regmatch.regprog = wp->w_buffer->b_cap_prog;
+		regmatch.rm_ic = FALSE;
+		if (vim_regexec(&regmatch, ptr, 0))
+		    *capcol = (int)(regmatch.endp[0] - ptr);
+	    }
+
+#ifdef FEAT_MBYTE
+	    if (has_mbyte)
+		return (*mb_ptr2len)(ptr);
+#endif
+	    return 1;
+	}
+	else if (mi.mi_end == ptr)
+	    /* Always include at least one character.  Required for when there
+	     * is a mixup in "midword". */
+	    mb_ptr_adv(mi.mi_end);
+	else if (mi.mi_result == SP_BAD
+		&& LANGP_ENTRY(wp->w_buffer->b_langp, 0)->lp_slang->sl_nobreak)
+	{
+	    char_u	*p, *fp;
+	    int		save_result = mi.mi_result;
+
+	    /* First language in 'spelllang' is NOBREAK.  Find first position
+	     * at which any word would be valid. */
+	    mi.mi_lp = LANGP_ENTRY(wp->w_buffer->b_langp, 0);
+	    if (mi.mi_lp->lp_slang->sl_fidxs != NULL)
+	    {
+		p = mi.mi_word;
+		fp = mi.mi_fword;
+		for (;;)
+		{
+		    mb_ptr_adv(p);
+		    mb_ptr_adv(fp);
+		    if (p >= mi.mi_end)
+			break;
+		    mi.mi_compoff = (int)(fp - mi.mi_fword);
+		    find_word(&mi, FIND_COMPOUND);
+		    if (mi.mi_result != SP_BAD)
+		    {
+			mi.mi_end = p;
+			break;
+		    }
+		}
+		mi.mi_result = save_result;
+	    }
+	}
+
+	if (mi.mi_result == SP_BAD || mi.mi_result == SP_BANNED)
+	    *attrp = HLF_SPB;
+	else if (mi.mi_result == SP_RARE)
+	    *attrp = HLF_SPR;
+	else
+	    *attrp = HLF_SPL;
+    }
+
+    if (wrongcaplen > 0 && (mi.mi_result == SP_OK || mi.mi_result == SP_RARE))
+    {
+	/* Report SpellCap only when the word isn't badly spelled. */
+	*attrp = HLF_SPC;
+	return wrongcaplen;
+    }
+
+    return (int)(mi.mi_end - ptr);
+}
+
+/*
+ * Check if the word at "mip->mi_word" is in the tree.
+ * When "mode" is FIND_FOLDWORD check in fold-case word tree.
+ * When "mode" is FIND_KEEPWORD check in keep-case word tree.
+ * When "mode" is FIND_PREFIX check for word after prefix in fold-case word
+ * tree.
+ *
+ * For a match mip->mi_result is updated.
+ */
+    static void
+find_word(mip, mode)
+    matchinf_T	*mip;
+    int		mode;
+{
+    idx_T	arridx = 0;
+    int		endlen[MAXWLEN];    /* length at possible word endings */
+    idx_T	endidx[MAXWLEN];    /* possible word endings */
+    int		endidxcnt = 0;
+    int		len;
+    int		wlen = 0;
+    int		flen;
+    int		c;
+    char_u	*ptr;
+    idx_T	lo, hi, m;
+#ifdef FEAT_MBYTE
+    char_u	*s;
+#endif
+    char_u	*p;
+    int		res = SP_BAD;
+    slang_T	*slang = mip->mi_lp->lp_slang;
+    unsigned	flags;
+    char_u	*byts;
+    idx_T	*idxs;
+    int		word_ends;
+    int		prefix_found;
+    int		nobreak_result;
+
+    if (mode == FIND_KEEPWORD || mode == FIND_KEEPCOMPOUND)
+    {
+	/* Check for word with matching case in keep-case tree. */
+	ptr = mip->mi_word;
+	flen = 9999;		    /* no case folding, always enough bytes */
+	byts = slang->sl_kbyts;
+	idxs = slang->sl_kidxs;
+
+	if (mode == FIND_KEEPCOMPOUND)
+	    /* Skip over the previously found word(s). */
+	    wlen += mip->mi_compoff;
+    }
+    else
+    {
+	/* Check for case-folded in case-folded tree. */
+	ptr = mip->mi_fword;
+	flen = mip->mi_fwordlen;    /* available case-folded bytes */
+	byts = slang->sl_fbyts;
+	idxs = slang->sl_fidxs;
+
+	if (mode == FIND_PREFIX)
+	{
+	    /* Skip over the prefix. */
+	    wlen = mip->mi_prefixlen;
+	    flen -= mip->mi_prefixlen;
+	}
+	else if (mode == FIND_COMPOUND)
+	{
+	    /* Skip over the previously found word(s). */
+	    wlen = mip->mi_compoff;
+	    flen -= mip->mi_compoff;
+	}
+
+    }
+
+    if (byts == NULL)
+	return;			/* array is empty */
+
+    /*
+     * Repeat advancing in the tree until:
+     * - there is a byte that doesn't match,
+     * - we reach the end of the tree,
+     * - or we reach the end of the line.
+     */
+    for (;;)
+    {
+	if (flen <= 0 && *mip->mi_fend != NUL)
+	    flen = fold_more(mip);
+
+	len = byts[arridx++];
+
+	/* If the first possible byte is a zero the word could end here.
+	 * Remember this index, we first check for the longest word. */
+	if (byts[arridx] == 0)
+	{
+	    if (endidxcnt == MAXWLEN)
+	    {
+		/* Must be a corrupted spell file. */
+		EMSG(_(e_format));
+		return;
+	    }
+	    endlen[endidxcnt] = wlen;
+	    endidx[endidxcnt++] = arridx++;
+	    --len;
+
+	    /* Skip over the zeros, there can be several flag/region
+	     * combinations. */
+	    while (len > 0 && byts[arridx] == 0)
+	    {
+		++arridx;
+		--len;
+	    }
+	    if (len == 0)
+		break;	    /* no children, word must end here */
+	}
+
+	/* Stop looking at end of the line. */
+	if (ptr[wlen] == NUL)
+	    break;
+
+	/* Perform a binary search in the list of accepted bytes. */
+	c = ptr[wlen];
+	if (c == TAB)	    /* <Tab> is handled like <Space> */
+	    c = ' ';
+	lo = arridx;
+	hi = arridx + len - 1;
+	while (lo < hi)
+	{
+	    m = (lo + hi) / 2;
+	    if (byts[m] > c)
+		hi = m - 1;
+	    else if (byts[m] < c)
+		lo = m + 1;
+	    else
+	    {
+		lo = hi = m;
+		break;
+	    }
+	}
+
+	/* Stop if there is no matching byte. */
+	if (hi < lo || byts[lo] != c)
+	    break;
+
+	/* Continue at the child (if there is one). */
+	arridx = idxs[lo];
+	++wlen;
+	--flen;
+
+	/* One space in the good word may stand for several spaces in the
+	 * checked word. */
+	if (c == ' ')
+	{
+	    for (;;)
+	    {
+		if (flen <= 0 && *mip->mi_fend != NUL)
+		    flen = fold_more(mip);
+		if (ptr[wlen] != ' ' && ptr[wlen] != TAB)
+		    break;
+		++wlen;
+		--flen;
+	    }
+	}
+    }
+
+    /*
+     * Verify that one of the possible endings is valid.  Try the longest
+     * first.
+     */
+    while (endidxcnt > 0)
+    {
+	--endidxcnt;
+	arridx = endidx[endidxcnt];
+	wlen = endlen[endidxcnt];
+
+#ifdef FEAT_MBYTE
+	if ((*mb_head_off)(ptr, ptr + wlen) > 0)
+	    continue;	    /* not at first byte of character */
+#endif
+	if (spell_iswordp(ptr + wlen, mip->mi_buf))
+	{
+	    if (slang->sl_compprog == NULL && !slang->sl_nobreak)
+		continue;	    /* next char is a word character */
+	    word_ends = FALSE;
+	}
+	else
+	    word_ends = TRUE;
+	/* The prefix flag is before compound flags.  Once a valid prefix flag
+	 * has been found we try compound flags. */
+	prefix_found = FALSE;
+
+#ifdef FEAT_MBYTE
+	if (mode != FIND_KEEPWORD && has_mbyte)
+	{
+	    /* Compute byte length in original word, length may change
+	     * when folding case.  This can be slow, take a shortcut when the
+	     * case-folded word is equal to the keep-case word. */
+	    p = mip->mi_word;
+	    if (STRNCMP(ptr, p, wlen) != 0)
+	    {
+		for (s = ptr; s < ptr + wlen; mb_ptr_adv(s))
+		    mb_ptr_adv(p);
+		wlen = (int)(p - mip->mi_word);
+	    }
+	}
+#endif
+
+	/* Check flags and region.  For FIND_PREFIX check the condition and
+	 * prefix ID.
+	 * Repeat this if there are more flags/region alternatives until there
+	 * is a match. */
+	res = SP_BAD;
+	for (len = byts[arridx - 1]; len > 0 && byts[arridx] == 0;
+							      --len, ++arridx)
+	{
+	    flags = idxs[arridx];
+
+	    /* For the fold-case tree check that the case of the checked word
+	     * matches with what the word in the tree requires.
+	     * For keep-case tree the case is always right.  For prefixes we
+	     * don't bother to check. */
+	    if (mode == FIND_FOLDWORD)
+	    {
+		if (mip->mi_cend != mip->mi_word + wlen)
+		{
+		    /* mi_capflags was set for a different word length, need
+		     * to do it again. */
+		    mip->mi_cend = mip->mi_word + wlen;
+		    mip->mi_capflags = captype(mip->mi_word, mip->mi_cend);
+		}
+
+		if (mip->mi_capflags == WF_KEEPCAP
+				|| !spell_valid_case(mip->mi_capflags, flags))
+		    continue;
+	    }
+
+	    /* When mode is FIND_PREFIX the word must support the prefix:
+	     * check the prefix ID and the condition.  Do that for the list at
+	     * mip->mi_prefarridx that find_prefix() filled. */
+	    else if (mode == FIND_PREFIX && !prefix_found)
+	    {
+		c = valid_word_prefix(mip->mi_prefcnt, mip->mi_prefarridx,
+				    flags,
+				    mip->mi_word + mip->mi_cprefixlen, slang,
+				    FALSE);
+		if (c == 0)
+		    continue;
+
+		/* Use the WF_RARE flag for a rare prefix. */
+		if (c & WF_RAREPFX)
+		    flags |= WF_RARE;
+		prefix_found = TRUE;
+	    }
+
+	    if (slang->sl_nobreak)
+	    {
+		if ((mode == FIND_COMPOUND || mode == FIND_KEEPCOMPOUND)
+			&& (flags & WF_BANNED) == 0)
+		{
+		    /* NOBREAK: found a valid following word.  That's all we
+		     * need to know, so return. */
+		    mip->mi_result = SP_OK;
+		    break;
+		}
+	    }
+
+	    else if ((mode == FIND_COMPOUND || mode == FIND_KEEPCOMPOUND
+								|| !word_ends))
+	    {
+		/* If there is no compound flag or the word is shorter than
+		 * COMPOUNDMIN reject it quickly.
+		 * Makes you wonder why someone puts a compound flag on a word
+		 * that's too short...  Myspell compatibility requires this
+		 * anyway. */
+		if (((unsigned)flags >> 24) == 0
+			     || wlen - mip->mi_compoff < slang->sl_compminlen)
+		    continue;
+#ifdef FEAT_MBYTE
+		/* For multi-byte chars check character length against
+		 * COMPOUNDMIN. */
+		if (has_mbyte
+			&& slang->sl_compminlen > 0
+			&& mb_charlen_len(mip->mi_word + mip->mi_compoff,
+				wlen - mip->mi_compoff) < slang->sl_compminlen)
+			continue;
+#endif
+
+		/* Limit the number of compound words to COMPOUNDWORDMAX if no
+		 * maximum for syllables is specified. */
+		if (!word_ends && mip->mi_complen + mip->mi_compextra + 2
+							   > slang->sl_compmax
+					   && slang->sl_compsylmax == MAXWLEN)
+		    continue;
+
+		/* Don't allow compounding on a side where an affix was added,
+		 * unless COMPOUNDPERMITFLAG was used. */
+		if (mip->mi_complen > 0 && (flags & WF_NOCOMPBEF))
+		    continue;
+		if (!word_ends && (flags & WF_NOCOMPAFT))
+		    continue;
+
+		/* Quickly check if compounding is possible with this flag. */
+		if (!byte_in_str(mip->mi_complen == 0
+					? slang->sl_compstartflags
+					: slang->sl_compallflags,
+					    ((unsigned)flags >> 24)))
+		    continue;
+
+		if (mode == FIND_COMPOUND)
+		{
+		    int	    capflags;
+
+		    /* Need to check the caps type of the appended compound
+		     * word. */
+#ifdef FEAT_MBYTE
+		    if (has_mbyte && STRNCMP(ptr, mip->mi_word,
+							mip->mi_compoff) != 0)
+		    {
+			/* case folding may have changed the length */
+			p = mip->mi_word;
+			for (s = ptr; s < ptr + mip->mi_compoff; mb_ptr_adv(s))
+			    mb_ptr_adv(p);
+		    }
+		    else
+#endif
+			p = mip->mi_word + mip->mi_compoff;
+		    capflags = captype(p, mip->mi_word + wlen);
+		    if (capflags == WF_KEEPCAP || (capflags == WF_ALLCAP
+						 && (flags & WF_FIXCAP) != 0))
+			continue;
+
+		    if (capflags != WF_ALLCAP)
+		    {
+			/* When the character before the word is a word
+			 * character we do not accept a Onecap word.  We do
+			 * accept a no-caps word, even when the dictionary
+			 * word specifies ONECAP. */
+			mb_ptr_back(mip->mi_word, p);
+			if (spell_iswordp_nmw(p)
+				? capflags == WF_ONECAP
+				: (flags & WF_ONECAP) != 0
+						     && capflags != WF_ONECAP)
+			    continue;
+		    }
+		}
+
+		/* If the word ends the sequence of compound flags of the
+		 * words must match with one of the COMPOUNDRULE items and
+		 * the number of syllables must not be too large. */
+		mip->mi_compflags[mip->mi_complen] = ((unsigned)flags >> 24);
+		mip->mi_compflags[mip->mi_complen + 1] = NUL;
+		if (word_ends)
+		{
+		    char_u	fword[MAXWLEN];
+
+		    if (slang->sl_compsylmax < MAXWLEN)
+		    {
+			/* "fword" is only needed for checking syllables. */
+			if (ptr == mip->mi_word)
+			    (void)spell_casefold(ptr, wlen, fword, MAXWLEN);
+			else
+			    vim_strncpy(fword, ptr, endlen[endidxcnt]);
+		    }
+		    if (!can_compound(slang, fword, mip->mi_compflags))
+			continue;
+		}
+	    }
+
+	    /* Check NEEDCOMPOUND: can't use word without compounding. */
+	    else if (flags & WF_NEEDCOMP)
+		continue;
+
+	    nobreak_result = SP_OK;
+
+	    if (!word_ends)
+	    {
+		int	save_result = mip->mi_result;
+		char_u	*save_end = mip->mi_end;
+		langp_T	*save_lp = mip->mi_lp;
+		int	lpi;
+
+		/* Check that a valid word follows.  If there is one and we
+		 * are compounding, it will set "mi_result", thus we are
+		 * always finished here.  For NOBREAK we only check that a
+		 * valid word follows.
+		 * Recursive! */
+		if (slang->sl_nobreak)
+		    mip->mi_result = SP_BAD;
+
+		/* Find following word in case-folded tree. */
+		mip->mi_compoff = endlen[endidxcnt];
+#ifdef FEAT_MBYTE
+		if (has_mbyte && mode == FIND_KEEPWORD)
+		{
+		    /* Compute byte length in case-folded word from "wlen":
+		     * byte length in keep-case word.  Length may change when
+		     * folding case.  This can be slow, take a shortcut when
+		     * the case-folded word is equal to the keep-case word. */
+		    p = mip->mi_fword;
+		    if (STRNCMP(ptr, p, wlen) != 0)
+		    {
+			for (s = ptr; s < ptr + wlen; mb_ptr_adv(s))
+			    mb_ptr_adv(p);
+			mip->mi_compoff = (int)(p - mip->mi_fword);
+		    }
+		}
+#endif
+		c = mip->mi_compoff;
+		++mip->mi_complen;
+		if (flags & WF_COMPROOT)
+		    ++mip->mi_compextra;
+
+		/* For NOBREAK we need to try all NOBREAK languages, at least
+		 * to find the ".add" file(s). */
+		for (lpi = 0; lpi < mip->mi_buf->b_langp.ga_len; ++lpi)
+		{
+		    if (slang->sl_nobreak)
+		    {
+			mip->mi_lp = LANGP_ENTRY(mip->mi_buf->b_langp, lpi);
+			if (mip->mi_lp->lp_slang->sl_fidxs == NULL
+					 || !mip->mi_lp->lp_slang->sl_nobreak)
+			    continue;
+		    }
+
+		    find_word(mip, FIND_COMPOUND);
+
+		    /* When NOBREAK any word that matches is OK.  Otherwise we
+		     * need to find the longest match, thus try with keep-case
+		     * and prefix too. */
+		    if (!slang->sl_nobreak || mip->mi_result == SP_BAD)
+		    {
+			/* Find following word in keep-case tree. */
+			mip->mi_compoff = wlen;
+			find_word(mip, FIND_KEEPCOMPOUND);
+
+#if 0	    /* Disabled, a prefix must not appear halfway a compound word,
+	       unless the COMPOUNDPERMITFLAG is used and then it can't be a
+	       postponed prefix. */
+			if (!slang->sl_nobreak || mip->mi_result == SP_BAD)
+			{
+			    /* Check for following word with prefix. */
+			    mip->mi_compoff = c;
+			    find_prefix(mip, FIND_COMPOUND);
+			}
+#endif
+		    }
+
+		    if (!slang->sl_nobreak)
+			break;
+		}
+		--mip->mi_complen;
+		if (flags & WF_COMPROOT)
+		    --mip->mi_compextra;
+		mip->mi_lp = save_lp;
+
+		if (slang->sl_nobreak)
+		{
+		    nobreak_result = mip->mi_result;
+		    mip->mi_result = save_result;
+		    mip->mi_end = save_end;
+		}
+		else
+		{
+		    if (mip->mi_result == SP_OK)
+			break;
+		    continue;
+		}
+	    }
+
+	    if (flags & WF_BANNED)
+		res = SP_BANNED;
+	    else if (flags & WF_REGION)
+	    {
+		/* Check region. */
+		if ((mip->mi_lp->lp_region & (flags >> 16)) != 0)
+		    res = SP_OK;
+		else
+		    res = SP_LOCAL;
+	    }
+	    else if (flags & WF_RARE)
+		res = SP_RARE;
+	    else
+		res = SP_OK;
+
+	    /* Always use the longest match and the best result.  For NOBREAK
+	     * we separately keep the longest match without a following good
+	     * word as a fall-back. */
+	    if (nobreak_result == SP_BAD)
+	    {
+		if (mip->mi_result2 > res)
+		{
+		    mip->mi_result2 = res;
+		    mip->mi_end2 = mip->mi_word + wlen;
+		}
+		else if (mip->mi_result2 == res
+					&& mip->mi_end2 < mip->mi_word + wlen)
+		    mip->mi_end2 = mip->mi_word + wlen;
+	    }
+	    else if (mip->mi_result > res)
+	    {
+		mip->mi_result = res;
+		mip->mi_end = mip->mi_word + wlen;
+	    }
+	    else if (mip->mi_result == res && mip->mi_end < mip->mi_word + wlen)
+		mip->mi_end = mip->mi_word + wlen;
+
+	    if (mip->mi_result == SP_OK)
+		break;
+	}
+
+	if (mip->mi_result == SP_OK)
+	    break;
+    }
+}
+
+/*
+ * Return TRUE if "flags" is a valid sequence of compound flags and "word"
+ * does not have too many syllables.
+ */
+    static int
+can_compound(slang, word, flags)
+    slang_T	*slang;
+    char_u	*word;
+    char_u	*flags;
+{
+    regmatch_T	regmatch;
+#ifdef FEAT_MBYTE
+    char_u	uflags[MAXWLEN * 2];
+    int		i;
+#endif
+    char_u	*p;
+
+    if (slang->sl_compprog == NULL)
+	return FALSE;
+#ifdef FEAT_MBYTE
+    if (enc_utf8)
+    {
+	/* Need to convert the single byte flags to utf8 characters. */
+	p = uflags;
+	for (i = 0; flags[i] != NUL; ++i)
+	    p += mb_char2bytes(flags[i], p);
+	*p = NUL;
+	p = uflags;
+    }
+    else
+#endif
+	p = flags;
+    regmatch.regprog = slang->sl_compprog;
+    regmatch.rm_ic = FALSE;
+    if (!vim_regexec(&regmatch, p, 0))
+	return FALSE;
+
+    /* Count the number of syllables.  This may be slow, do it last.  If there
+     * are too many syllables AND the number of compound words is above
+     * COMPOUNDWORDMAX then compounding is not allowed. */
+    if (slang->sl_compsylmax < MAXWLEN
+		       && count_syllables(slang, word) > slang->sl_compsylmax)
+	return (int)STRLEN(flags) < slang->sl_compmax;
+    return TRUE;
+}
+
+/*
+ * Return non-zero if the prefix indicated by "arridx" matches with the prefix
+ * ID in "flags" for the word "word".
+ * The WF_RAREPFX flag is included in the return value for a rare prefix.
+ */
+    static int
+valid_word_prefix(totprefcnt, arridx, flags, word, slang, cond_req)
+    int		totprefcnt;	/* nr of prefix IDs */
+    int		arridx;		/* idx in sl_pidxs[] */
+    int		flags;
+    char_u	*word;
+    slang_T	*slang;
+    int		cond_req;	/* only use prefixes with a condition */
+{
+    int		prefcnt;
+    int		pidx;
+    regprog_T	*rp;
+    regmatch_T	regmatch;
+    int		prefid;
+
+    prefid = (unsigned)flags >> 24;
+    for (prefcnt = totprefcnt - 1; prefcnt >= 0; --prefcnt)
+    {
+	pidx = slang->sl_pidxs[arridx + prefcnt];
+
+	/* Check the prefix ID. */
+	if (prefid != (pidx & 0xff))
+	    continue;
+
+	/* Check if the prefix doesn't combine and the word already has a
+	 * suffix. */
+	if ((flags & WF_HAS_AFF) && (pidx & WF_PFX_NC))
+	    continue;
+
+	/* Check the condition, if there is one.  The condition index is
+	 * stored in the two bytes above the prefix ID byte.  */
+	rp = slang->sl_prefprog[((unsigned)pidx >> 8) & 0xffff];
+	if (rp != NULL)
+	{
+	    regmatch.regprog = rp;
+	    regmatch.rm_ic = FALSE;
+	    if (!vim_regexec(&regmatch, word, 0))
+		continue;
+	}
+	else if (cond_req)
+	    continue;
+
+	/* It's a match!  Return the WF_ flags. */
+	return pidx;
+    }
+    return 0;
+}
+
+/*
+ * Check if the word at "mip->mi_word" has a matching prefix.
+ * If it does, then check the following word.
+ *
+ * If "mode" is "FIND_COMPOUND" then do the same after another word, find a
+ * prefix in a compound word.
+ *
+ * For a match mip->mi_result is updated.
+ */
+    static void
+find_prefix(mip, mode)
+    matchinf_T	*mip;
+    int		mode;
+{
+    idx_T	arridx = 0;
+    int		len;
+    int		wlen = 0;
+    int		flen;
+    int		c;
+    char_u	*ptr;
+    idx_T	lo, hi, m;
+    slang_T	*slang = mip->mi_lp->lp_slang;
+    char_u	*byts;
+    idx_T	*idxs;
+
+    byts = slang->sl_pbyts;
+    if (byts == NULL)
+	return;			/* array is empty */
+
+    /* We use the case-folded word here, since prefixes are always
+     * case-folded. */
+    ptr = mip->mi_fword;
+    flen = mip->mi_fwordlen;    /* available case-folded bytes */
+    if (mode == FIND_COMPOUND)
+    {
+	/* Skip over the previously found word(s). */
+	ptr += mip->mi_compoff;
+	flen -= mip->mi_compoff;
+    }
+    idxs = slang->sl_pidxs;
+
+    /*
+     * Repeat advancing in the tree until:
+     * - there is a byte that doesn't match,
+     * - we reach the end of the tree,
+     * - or we reach the end of the line.
+     */
+    for (;;)
+    {
+	if (flen == 0 && *mip->mi_fend != NUL)
+	    flen = fold_more(mip);
+
+	len = byts[arridx++];
+
+	/* If the first possible byte is a zero the prefix could end here.
+	 * Check if the following word matches and supports the prefix. */
+	if (byts[arridx] == 0)
+	{
+	    /* There can be several prefixes with different conditions.  We
+	     * try them all, since we don't know which one will give the
+	     * longest match.  The word is the same each time, pass the list
+	     * of possible prefixes to find_word(). */
+	    mip->mi_prefarridx = arridx;
+	    mip->mi_prefcnt = len;
+	    while (len > 0 && byts[arridx] == 0)
+	    {
+		++arridx;
+		--len;
+	    }
+	    mip->mi_prefcnt -= len;
+
+	    /* Find the word that comes after the prefix. */
+	    mip->mi_prefixlen = wlen;
+	    if (mode == FIND_COMPOUND)
+		/* Skip over the previously found word(s). */
+		mip->mi_prefixlen += mip->mi_compoff;
+
+#ifdef FEAT_MBYTE
+	    if (has_mbyte)
+	    {
+		/* Case-folded length may differ from original length. */
+		mip->mi_cprefixlen = nofold_len(mip->mi_fword,
+					     mip->mi_prefixlen, mip->mi_word);
+	    }
+	    else
+		mip->mi_cprefixlen = mip->mi_prefixlen;
+#endif
+	    find_word(mip, FIND_PREFIX);
+
+
+	    if (len == 0)
+		break;	    /* no children, word must end here */
+	}
+
+	/* Stop looking at end of the line. */
+	if (ptr[wlen] == NUL)
+	    break;
+
+	/* Perform a binary search in the list of accepted bytes. */
+	c = ptr[wlen];
+	lo = arridx;
+	hi = arridx + len - 1;
+	while (lo < hi)
+	{
+	    m = (lo + hi) / 2;
+	    if (byts[m] > c)
+		hi = m - 1;
+	    else if (byts[m] < c)
+		lo = m + 1;
+	    else
+	    {
+		lo = hi = m;
+		break;
+	    }
+	}
+
+	/* Stop if there is no matching byte. */
+	if (hi < lo || byts[lo] != c)
+	    break;
+
+	/* Continue at the child (if there is one). */
+	arridx = idxs[lo];
+	++wlen;
+	--flen;
+    }
+}
+
+/*
+ * Need to fold at least one more character.  Do until next non-word character
+ * for efficiency.  Include the non-word character too.
+ * Return the length of the folded chars in bytes.
+ */
+    static int
+fold_more(mip)
+    matchinf_T	*mip;
+{
+    int		flen;
+    char_u	*p;
+
+    p = mip->mi_fend;
+    do
+    {
+	mb_ptr_adv(mip->mi_fend);
+    } while (*mip->mi_fend != NUL && spell_iswordp(mip->mi_fend, mip->mi_buf));
+
+    /* Include the non-word character so that we can check for the word end. */
+    if (*mip->mi_fend != NUL)
+	mb_ptr_adv(mip->mi_fend);
+
+    (void)spell_casefold(p, (int)(mip->mi_fend - p),
+			     mip->mi_fword + mip->mi_fwordlen,
+			     MAXWLEN - mip->mi_fwordlen);
+    flen = (int)STRLEN(mip->mi_fword + mip->mi_fwordlen);
+    mip->mi_fwordlen += flen;
+    return flen;
+}
+
+/*
+ * Check case flags for a word.  Return TRUE if the word has the requested
+ * case.
+ */
+    static int
+spell_valid_case(wordflags, treeflags)
+    int	    wordflags;	    /* flags for the checked word. */
+    int	    treeflags;	    /* flags for the word in the spell tree */
+{
+    return ((wordflags == WF_ALLCAP && (treeflags & WF_FIXCAP) == 0)
+	    || ((treeflags & (WF_ALLCAP | WF_KEEPCAP)) == 0
+		&& ((treeflags & WF_ONECAP) == 0
+					   || (wordflags & WF_ONECAP) != 0)));
+}
+
+/*
+ * Return TRUE if spell checking is not enabled.
+ */
+    static int
+no_spell_checking(wp)
+    win_T	*wp;
+{
+    if (!wp->w_p_spell || *wp->w_buffer->b_p_spl == NUL
+					 || wp->w_buffer->b_langp.ga_len == 0)
+    {
+	EMSG(_("E756: Spell checking is not enabled"));
+	return TRUE;
+    }
+    return FALSE;
+}
+
+/*
+ * Move to next spell error.
+ * "curline" is FALSE for "[s", "]s", "[S" and "]S".
+ * "curline" is TRUE to find word under/after cursor in the same line.
+ * For Insert mode completion "dir" is BACKWARD and "curline" is TRUE: move
+ * to after badly spelled word before the cursor.
+ * Return 0 if not found, length of the badly spelled word otherwise.
+ */
+    int
+spell_move_to(wp, dir, allwords, curline, attrp)
+    win_T	*wp;
+    int		dir;		/* FORWARD or BACKWARD */
+    int		allwords;	/* TRUE for "[s"/"]s", FALSE for "[S"/"]S" */
+    int		curline;
+    hlf_T	*attrp;		/* return: attributes of bad word or NULL
+				   (only when "dir" is FORWARD) */
+{
+    linenr_T	lnum;
+    pos_T	found_pos;
+    int		found_len = 0;
+    char_u	*line;
+    char_u	*p;
+    char_u	*endp;
+    hlf_T	attr;
+    int		len;
+# ifdef FEAT_SYN_HL
+    int		has_syntax = syntax_present(wp->w_buffer);
+# endif
+    int		col;
+    int		can_spell;
+    char_u	*buf = NULL;
+    int		buflen = 0;
+    int		skip = 0;
+    int		capcol = -1;
+    int		found_one = FALSE;
+    int		wrapped = FALSE;
+
+    if (no_spell_checking(wp))
+	return 0;
+
+    /*
+     * Start looking for bad word at the start of the line, because we can't
+     * start halfway a word, we don't know where it starts or ends.
+     *
+     * When searching backwards, we continue in the line to find the last
+     * bad word (in the cursor line: before the cursor).
+     *
+     * We concatenate the start of the next line, so that wrapped words work
+     * (e.g. "et<line-break>cetera").  Doesn't work when searching backwards
+     * though...
+     */
+    lnum = wp->w_cursor.lnum;
+    clearpos(&found_pos);
+
+    while (!got_int)
+    {
+	line = ml_get_buf(wp->w_buffer, lnum, FALSE);
+
+	len = (int)STRLEN(line);
+	if (buflen < len + MAXWLEN + 2)
+	{
+	    vim_free(buf);
+	    buflen = len + MAXWLEN + 2;
+	    buf = alloc(buflen);
+	    if (buf == NULL)
+		break;
+	}
+
+	/* In first line check first word for Capital. */
+	if (lnum == 1)
+	    capcol = 0;
+
+	/* For checking first word with a capital skip white space. */
+	if (capcol == 0)
+	    capcol = (int)(skipwhite(line) - line);
+	else if (curline && wp == curwin)
+	{
+	    /* For spellbadword(): check if first word needs a capital. */
+	    col = (int)(skipwhite(line) - line);
+	    if (check_need_cap(lnum, col))
+		capcol = col;
+
+	    /* Need to get the line again, may have looked at the previous
+	     * one. */
+	    line = ml_get_buf(wp->w_buffer, lnum, FALSE);
+	}
+
+	/* Copy the line into "buf" and append the start of the next line if
+	 * possible. */
+	STRCPY(buf, line);
+	if (lnum < wp->w_buffer->b_ml.ml_line_count)
+	    spell_cat_line(buf + STRLEN(buf),
+			  ml_get_buf(wp->w_buffer, lnum + 1, FALSE), MAXWLEN);
+
+	p = buf + skip;
+	endp = buf + len;
+	while (p < endp)
+	{
+	    /* When searching backward don't search after the cursor.  Unless
+	     * we wrapped around the end of the buffer. */
+	    if (dir == BACKWARD
+		    && lnum == wp->w_cursor.lnum
+		    && !wrapped
+		    && (colnr_T)(p - buf) >= wp->w_cursor.col)
+		break;
+
+	    /* start of word */
+	    attr = HLF_COUNT;
+	    len = spell_check(wp, p, &attr, &capcol, FALSE);
+
+	    if (attr != HLF_COUNT)
+	    {
+		/* We found a bad word.  Check the attribute. */
+		if (allwords || attr == HLF_SPB)
+		{
+		    /* When searching forward only accept a bad word after
+		     * the cursor. */
+		    if (dir == BACKWARD
+			    || lnum != wp->w_cursor.lnum
+			    || (lnum == wp->w_cursor.lnum
+				&& (wrapped
+				    || (colnr_T)(curline ? p - buf + len
+						     : p - buf)
+						  > wp->w_cursor.col)))
+		    {
+# ifdef FEAT_SYN_HL
+			if (has_syntax)
+			{
+			    col = (int)(p - buf);
+			    (void)syn_get_id(wp, lnum, (colnr_T)col,
+						       FALSE, &can_spell);
+			    if (!can_spell)
+				attr = HLF_COUNT;
+			}
+			else
+#endif
+			    can_spell = TRUE;
+
+			if (can_spell)
+			{
+			    found_one = TRUE;
+			    found_pos.lnum = lnum;
+			    found_pos.col = (int)(p - buf);
+#ifdef FEAT_VIRTUALEDIT
+			    found_pos.coladd = 0;
+#endif
+			    if (dir == FORWARD)
+			    {
+				/* No need to search further. */
+				wp->w_cursor = found_pos;
+				vim_free(buf);
+				if (attrp != NULL)
+				    *attrp = attr;
+				return len;
+			    }
+			    else if (curline)
+				/* Insert mode completion: put cursor after
+				 * the bad word. */
+				found_pos.col += len;
+			    found_len = len;
+			}
+		    }
+		    else
+			found_one = TRUE;
+		}
+	    }
+
+	    /* advance to character after the word */
+	    p += len;
+	    capcol -= len;
+	}
+
+	if (dir == BACKWARD && found_pos.lnum != 0)
+	{
+	    /* Use the last match in the line (before the cursor). */
+	    wp->w_cursor = found_pos;
+	    vim_free(buf);
+	    return found_len;
+	}
+
+	if (curline)
+	    break;	/* only check cursor line */
+
+	/* Advance to next line. */
+	if (dir == BACKWARD)
+	{
+	    /* If we are back at the starting line and searched it again there
+	     * is no match, give up. */
+	    if (lnum == wp->w_cursor.lnum && wrapped)
+		break;
+
+	    if (lnum > 1)
+		--lnum;
+	    else if (!p_ws)
+		break;	    /* at first line and 'nowrapscan' */
+	    else
+	    {
+		/* Wrap around to the end of the buffer.  May search the
+		 * starting line again and accept the last match. */
+		lnum = wp->w_buffer->b_ml.ml_line_count;
+		wrapped = TRUE;
+		if (!shortmess(SHM_SEARCH))
+		    give_warning((char_u *)_(top_bot_msg), TRUE);
+	    }
+	    capcol = -1;
+	}
+	else
+	{
+	    if (lnum < wp->w_buffer->b_ml.ml_line_count)
+		++lnum;
+	    else if (!p_ws)
+		break;	    /* at first line and 'nowrapscan' */
+	    else
+	    {
+		/* Wrap around to the start of the buffer.  May search the
+		 * starting line again and accept the first match. */
+		lnum = 1;
+		wrapped = TRUE;
+		if (!shortmess(SHM_SEARCH))
+		    give_warning((char_u *)_(bot_top_msg), TRUE);
+	    }
+
+	    /* If we are back at the starting line and there is no match then
+	     * give up. */
+	    if (lnum == wp->w_cursor.lnum && !found_one)
+		break;
+
+	    /* Skip the characters at the start of the next line that were
+	     * included in a match crossing line boundaries. */
+	    if (attr == HLF_COUNT)
+		skip = (int)(p - endp);
+	    else
+		skip = 0;
+
+	    /* Capcol skips over the inserted space. */
+	    --capcol;
+
+	    /* But after empty line check first word in next line */
+	    if (*skipwhite(line) == NUL)
+		capcol = 0;
+	}
+
+	line_breakcheck();
+    }
+
+    vim_free(buf);
+    return 0;
+}
+
+/*
+ * For spell checking: concatenate the start of the following line "line" into
+ * "buf", blanking-out special characters.  Copy less then "maxlen" bytes.
+ */
+    void
+spell_cat_line(buf, line, maxlen)
+    char_u	*buf;
+    char_u	*line;
+    int		maxlen;
+{
+    char_u	*p;
+    int		n;
+
+    p = skipwhite(line);
+    while (vim_strchr((char_u *)"*#/\"\t", *p) != NULL)
+	p = skipwhite(p + 1);
+
+    if (*p != NUL)
+    {
+	*buf = ' ';
+	vim_strncpy(buf + 1, line, maxlen - 2);
+	n = (int)(p - line);
+	if (n >= maxlen)
+	    n = maxlen - 1;
+	vim_memset(buf + 1, ' ', n);
+    }
+}
+
+/*
+ * Structure used for the cookie argument of do_in_runtimepath().
+ */
+typedef struct spelload_S
+{
+    char_u  sl_lang[MAXWLEN + 1];	/* language name */
+    slang_T *sl_slang;			/* resulting slang_T struct */
+    int	    sl_nobreak;			/* NOBREAK language found */
+} spelload_T;
+
+/*
+ * Load word list(s) for "lang" from Vim spell file(s).
+ * "lang" must be the language without the region: e.g., "en".
+ */
+    static void
+spell_load_lang(lang)
+    char_u	*lang;
+{
+    char_u	fname_enc[85];
+    int		r;
+    spelload_T	sl;
+#ifdef FEAT_AUTOCMD
+    int		round;
+#endif
+
+    /* Copy the language name to pass it to spell_load_cb() as a cookie.
+     * It's truncated when an error is detected. */
+    STRCPY(sl.sl_lang, lang);
+    sl.sl_slang = NULL;
+    sl.sl_nobreak = FALSE;
+
+#ifdef FEAT_AUTOCMD
+    /* We may retry when no spell file is found for the language, an
+     * autocommand may load it then. */
+    for (round = 1; round <= 2; ++round)
+#endif
+    {
+	/*
+	 * Find the first spell file for "lang" in 'runtimepath' and load it.
+	 */
+	vim_snprintf((char *)fname_enc, sizeof(fname_enc) - 5,
+					"spell/%s.%s.spl", lang, spell_enc());
+	r = do_in_runtimepath(fname_enc, FALSE, spell_load_cb, &sl);
+
+	if (r == FAIL && *sl.sl_lang != NUL)
+	{
+	    /* Try loading the ASCII version. */
+	    vim_snprintf((char *)fname_enc, sizeof(fname_enc) - 5,
+						  "spell/%s.ascii.spl", lang);
+	    r = do_in_runtimepath(fname_enc, FALSE, spell_load_cb, &sl);
+
+#ifdef FEAT_AUTOCMD
+	    if (r == FAIL && *sl.sl_lang != NUL && round == 1
+		    && apply_autocmds(EVENT_SPELLFILEMISSING, lang,
+					      curbuf->b_fname, FALSE, curbuf))
+		continue;
+	    break;
+#endif
+	}
+#ifdef FEAT_AUTOCMD
+	break;
+#endif
+    }
+
+    if (r == FAIL)
+    {
+	smsg((char_u *)_("Warning: Cannot find word list \"%s.%s.spl\" or \"%s.ascii.spl\""),
+						     lang, spell_enc(), lang);
+    }
+    else if (sl.sl_slang != NULL)
+    {
+	/* At least one file was loaded, now load ALL the additions. */
+	STRCPY(fname_enc + STRLEN(fname_enc) - 3, "add.spl");
+	do_in_runtimepath(fname_enc, TRUE, spell_load_cb, &sl);
+    }
+}
+
+/*
+ * Return the encoding used for spell checking: Use 'encoding', except that we
+ * use "latin1" for "latin9".  And limit to 60 characters (just in case).
+ */
+    static char_u *
+spell_enc()
+{
+
+#ifdef FEAT_MBYTE
+    if (STRLEN(p_enc) < 60 && STRCMP(p_enc, "iso-8859-15") != 0)
+	return p_enc;
+#endif
+    return (char_u *)"latin1";
+}
+
+/*
+ * Get the name of the .spl file for the internal wordlist into
+ * "fname[MAXPATHL]".
+ */
+    static void
+int_wordlist_spl(fname)
+    char_u	    *fname;
+{
+    vim_snprintf((char *)fname, MAXPATHL, "%s.%s.spl",
+						  int_wordlist, spell_enc());
+}
+
+/*
+ * Allocate a new slang_T for language "lang".  "lang" can be NULL.
+ * Caller must fill "sl_next".
+ */
+    static slang_T *
+slang_alloc(lang)
+    char_u	*lang;
+{
+    slang_T *lp;
+
+    lp = (slang_T *)alloc_clear(sizeof(slang_T));
+    if (lp != NULL)
+    {
+	if (lang != NULL)
+	    lp->sl_name = vim_strsave(lang);
+	ga_init2(&lp->sl_rep, sizeof(fromto_T), 10);
+	ga_init2(&lp->sl_repsal, sizeof(fromto_T), 10);
+	lp->sl_compmax = MAXWLEN;
+	lp->sl_compsylmax = MAXWLEN;
+	hash_init(&lp->sl_wordcount);
+    }
+
+    return lp;
+}
+
+/*
+ * Free the contents of an slang_T and the structure itself.
+ */
+    static void
+slang_free(lp)
+    slang_T	*lp;
+{
+    vim_free(lp->sl_name);
+    vim_free(lp->sl_fname);
+    slang_clear(lp);
+    vim_free(lp);
+}
+
+/*
+ * Clear an slang_T so that the file can be reloaded.
+ */
+    static void
+slang_clear(lp)
+    slang_T	*lp;
+{
+    garray_T	*gap;
+    fromto_T	*ftp;
+    salitem_T	*smp;
+    int		i;
+    int		round;
+
+    vim_free(lp->sl_fbyts);
+    lp->sl_fbyts = NULL;
+    vim_free(lp->sl_kbyts);
+    lp->sl_kbyts = NULL;
+    vim_free(lp->sl_pbyts);
+    lp->sl_pbyts = NULL;
+
+    vim_free(lp->sl_fidxs);
+    lp->sl_fidxs = NULL;
+    vim_free(lp->sl_kidxs);
+    lp->sl_kidxs = NULL;
+    vim_free(lp->sl_pidxs);
+    lp->sl_pidxs = NULL;
+
+    for (round = 1; round <= 2; ++round)
+    {
+	gap = round == 1 ? &lp->sl_rep : &lp->sl_repsal;
+	while (gap->ga_len > 0)
+	{
+	    ftp = &((fromto_T *)gap->ga_data)[--gap->ga_len];
+	    vim_free(ftp->ft_from);
+	    vim_free(ftp->ft_to);
+	}
+	ga_clear(gap);
+    }
+
+    gap = &lp->sl_sal;
+    if (lp->sl_sofo)
+    {
+	/* "ga_len" is set to 1 without adding an item for latin1 */
+	if (gap->ga_data != NULL)
+	    /* SOFOFROM and SOFOTO items: free lists of wide characters. */
+	    for (i = 0; i < gap->ga_len; ++i)
+		vim_free(((int **)gap->ga_data)[i]);
+    }
+    else
+	/* SAL items: free salitem_T items */
+	while (gap->ga_len > 0)
+	{
+	    smp = &((salitem_T *)gap->ga_data)[--gap->ga_len];
+	    vim_free(smp->sm_lead);
+	    /* Don't free sm_oneof and sm_rules, they point into sm_lead. */
+	    vim_free(smp->sm_to);
+#ifdef FEAT_MBYTE
+	    vim_free(smp->sm_lead_w);
+	    vim_free(smp->sm_oneof_w);
+	    vim_free(smp->sm_to_w);
+#endif
+	}
+    ga_clear(gap);
+
+    for (i = 0; i < lp->sl_prefixcnt; ++i)
+	vim_free(lp->sl_prefprog[i]);
+    lp->sl_prefixcnt = 0;
+    vim_free(lp->sl_prefprog);
+    lp->sl_prefprog = NULL;
+
+    vim_free(lp->sl_info);
+    lp->sl_info = NULL;
+
+    vim_free(lp->sl_midword);
+    lp->sl_midword = NULL;
+
+    vim_free(lp->sl_compprog);
+    vim_free(lp->sl_compstartflags);
+    vim_free(lp->sl_compallflags);
+    lp->sl_compprog = NULL;
+    lp->sl_compstartflags = NULL;
+    lp->sl_compallflags = NULL;
+
+    vim_free(lp->sl_syllable);
+    lp->sl_syllable = NULL;
+    ga_clear(&lp->sl_syl_items);
+
+    ga_clear_strings(&lp->sl_comppat);
+
+    hash_clear_all(&lp->sl_wordcount, WC_KEY_OFF);
+    hash_init(&lp->sl_wordcount);
+
+#ifdef FEAT_MBYTE
+    hash_clear_all(&lp->sl_map_hash, 0);
+#endif
+
+    /* Clear info from .sug file. */
+    slang_clear_sug(lp);
+
+    lp->sl_compmax = MAXWLEN;
+    lp->sl_compminlen = 0;
+    lp->sl_compsylmax = MAXWLEN;
+    lp->sl_regions[0] = NUL;
+}
+
+/*
+ * Clear the info from the .sug file in "lp".
+ */
+    static void
+slang_clear_sug(lp)
+    slang_T	*lp;
+{
+    vim_free(lp->sl_sbyts);
+    lp->sl_sbyts = NULL;
+    vim_free(lp->sl_sidxs);
+    lp->sl_sidxs = NULL;
+    close_spellbuf(lp->sl_sugbuf);
+    lp->sl_sugbuf = NULL;
+    lp->sl_sugloaded = FALSE;
+    lp->sl_sugtime = 0;
+}
+
+/*
+ * Load one spell file and store the info into a slang_T.
+ * Invoked through do_in_runtimepath().
+ */
+    static void
+spell_load_cb(fname, cookie)
+    char_u	*fname;
+    void	*cookie;
+{
+    spelload_T	*slp = (spelload_T *)cookie;
+    slang_T	*slang;
+
+    slang = spell_load_file(fname, slp->sl_lang, NULL, FALSE);
+    if (slang != NULL)
+    {
+	/* When a previously loaded file has NOBREAK also use it for the
+	 * ".add" files. */
+	if (slp->sl_nobreak && slang->sl_add)
+	    slang->sl_nobreak = TRUE;
+	else if (slang->sl_nobreak)
+	    slp->sl_nobreak = TRUE;
+
+	slp->sl_slang = slang;
+    }
+}
+
+/*
+ * Load one spell file and store the info into a slang_T.
+ *
+ * This is invoked in three ways:
+ * - From spell_load_cb() to load a spell file for the first time.  "lang" is
+ *   the language name, "old_lp" is NULL.  Will allocate an slang_T.
+ * - To reload a spell file that was changed.  "lang" is NULL and "old_lp"
+ *   points to the existing slang_T.
+ * - Just after writing a .spl file; it's read back to produce the .sug file.
+ *   "old_lp" is NULL and "lang" is NULL.  Will allocate an slang_T.
+ *
+ * Returns the slang_T the spell file was loaded into.  NULL for error.
+ */
+    static slang_T *
+spell_load_file(fname, lang, old_lp, silent)
+    char_u	*fname;
+    char_u	*lang;
+    slang_T	*old_lp;
+    int		silent;		/* no error if file doesn't exist */
+{
+    FILE	*fd;
+    char_u	buf[VIMSPELLMAGICL];
+    char_u	*p;
+    int		i;
+    int		n;
+    int		len;
+    char_u	*save_sourcing_name = sourcing_name;
+    linenr_T	save_sourcing_lnum = sourcing_lnum;
+    slang_T	*lp = NULL;
+    int		c = 0;
+    int		res;
+
+    fd = mch_fopen((char *)fname, "r");
+    if (fd == NULL)
+    {
+	if (!silent)
+	    EMSG2(_(e_notopen), fname);
+	else if (p_verbose > 2)
+	{
+	    verbose_enter();
+	    smsg((char_u *)e_notopen, fname);
+	    verbose_leave();
+	}
+	goto endFAIL;
+    }
+    if (p_verbose > 2)
+    {
+	verbose_enter();
+	smsg((char_u *)_("Reading spell file \"%s\""), fname);
+	verbose_leave();
+    }
+
+    if (old_lp == NULL)
+    {
+	lp = slang_alloc(lang);
+	if (lp == NULL)
+	    goto endFAIL;
+
+	/* Remember the file name, used to reload the file when it's updated. */
+	lp->sl_fname = vim_strsave(fname);
+	if (lp->sl_fname == NULL)
+	    goto endFAIL;
+
+	/* Check for .add.spl. */
+	lp->sl_add = strstr((char *)gettail(fname), ".add.") != NULL;
+    }
+    else
+	lp = old_lp;
+
+    /* Set sourcing_name, so that error messages mention the file name. */
+    sourcing_name = fname;
+    sourcing_lnum = 0;
+
+    /*
+     * <HEADER>: <fileID>
+     */
+    for (i = 0; i < VIMSPELLMAGICL; ++i)
+	buf[i] = getc(fd);				/* <fileID> */
+    if (STRNCMP(buf, VIMSPELLMAGIC, VIMSPELLMAGICL) != 0)
+    {
+	EMSG(_("E757: This does not look like a spell file"));
+	goto endFAIL;
+    }
+    c = getc(fd);					/* <versionnr> */
+    if (c < VIMSPELLVERSION)
+    {
+	EMSG(_("E771: Old spell file, needs to be updated"));
+	goto endFAIL;
+    }
+    else if (c > VIMSPELLVERSION)
+    {
+	EMSG(_("E772: Spell file is for newer version of Vim"));
+	goto endFAIL;
+    }
+
+
+    /*
+     * <SECTIONS>: <section> ... <sectionend>
+     * <section>: <sectionID> <sectionflags> <sectionlen> (section contents)
+     */
+    for (;;)
+    {
+	n = getc(fd);			    /* <sectionID> or <sectionend> */
+	if (n == SN_END)
+	    break;
+	c = getc(fd);					/* <sectionflags> */
+	len = get4c(fd);				/* <sectionlen> */
+	if (len < 0)
+	    goto truncerr;
+
+	res = 0;
+	switch (n)
+	{
+	    case SN_INFO:
+		lp->sl_info = read_string(fd, len);	/* <infotext> */
+		if (lp->sl_info == NULL)
+		    goto endFAIL;
+		break;
+
+	    case SN_REGION:
+		res = read_region_section(fd, lp, len);
+		break;
+
+	    case SN_CHARFLAGS:
+		res = read_charflags_section(fd);
+		break;
+
+	    case SN_MIDWORD:
+		lp->sl_midword = read_string(fd, len);	/* <midword> */
+		if (lp->sl_midword == NULL)
+		    goto endFAIL;
+		break;
+
+	    case SN_PREFCOND:
+		res = read_prefcond_section(fd, lp);
+		break;
+
+	    case SN_REP:
+		res = read_rep_section(fd, &lp->sl_rep, lp->sl_rep_first);
+		break;
+
+	    case SN_REPSAL:
+		res = read_rep_section(fd, &lp->sl_repsal, lp->sl_repsal_first);
+		break;
+
+	    case SN_SAL:
+		res = read_sal_section(fd, lp);
+		break;
+
+	    case SN_SOFO:
+		res = read_sofo_section(fd, lp);
+		break;
+
+	    case SN_MAP:
+		p = read_string(fd, len);		/* <mapstr> */
+		if (p == NULL)
+		    goto endFAIL;
+		set_map_str(lp, p);
+		vim_free(p);
+		break;
+
+	    case SN_WORDS:
+		res = read_words_section(fd, lp, len);
+		break;
+
+	    case SN_SUGFILE:
+		lp->sl_sugtime = get8c(fd);		/* <timestamp> */
+		break;
+
+	    case SN_NOSPLITSUGS:
+		lp->sl_nosplitsugs = TRUE;		/* <timestamp> */
+		break;
+
+	    case SN_COMPOUND:
+		res = read_compound(fd, lp, len);
+		break;
+
+	    case SN_NOBREAK:
+		lp->sl_nobreak = TRUE;
+		break;
+
+	    case SN_SYLLABLE:
+		lp->sl_syllable = read_string(fd, len);	/* <syllable> */
+		if (lp->sl_syllable == NULL)
+		    goto endFAIL;
+		if (init_syl_tab(lp) == FAIL)
+		    goto endFAIL;
+		break;
+
+	    default:
+		/* Unsupported section.  When it's required give an error
+		 * message.  When it's not required skip the contents. */
+		if (c & SNF_REQUIRED)
+		{
+		    EMSG(_("E770: Unsupported section in spell file"));
+		    goto endFAIL;
+		}
+		while (--len >= 0)
+		    if (getc(fd) < 0)
+			goto truncerr;
+		break;
+	}
+someerror:
+	if (res == SP_FORMERROR)
+	{
+	    EMSG(_(e_format));
+	    goto endFAIL;
+	}
+	if (res == SP_TRUNCERROR)
+	{
+truncerr:
+	    EMSG(_(e_spell_trunc));
+	    goto endFAIL;
+	}
+	if (res == SP_OTHERERROR)
+	    goto endFAIL;
+    }
+
+    /* <LWORDTREE> */
+    res = spell_read_tree(fd, &lp->sl_fbyts, &lp->sl_fidxs, FALSE, 0);
+    if (res != 0)
+	goto someerror;
+
+    /* <KWORDTREE> */
+    res = spell_read_tree(fd, &lp->sl_kbyts, &lp->sl_kidxs, FALSE, 0);
+    if (res != 0)
+	goto someerror;
+
+    /* <PREFIXTREE> */
+    res = spell_read_tree(fd, &lp->sl_pbyts, &lp->sl_pidxs, TRUE,
+							    lp->sl_prefixcnt);
+    if (res != 0)
+	goto someerror;
+
+    /* For a new file link it in the list of spell files. */
+    if (old_lp == NULL && lang != NULL)
+    {
+	lp->sl_next = first_lang;
+	first_lang = lp;
+    }
+
+    goto endOK;
+
+endFAIL:
+    if (lang != NULL)
+	/* truncating the name signals the error to spell_load_lang() */
+	*lang = NUL;
+    if (lp != NULL && old_lp == NULL)
+	slang_free(lp);
+    lp = NULL;
+
+endOK:
+    if (fd != NULL)
+	fclose(fd);
+    sourcing_name = save_sourcing_name;
+    sourcing_lnum = save_sourcing_lnum;
+
+    return lp;
+}
+
+/*
+ * Read 2 bytes from "fd" and turn them into an int, MSB first.
+ */
+    static int
+get2c(fd)
+    FILE	*fd;
+{
+    long	n;
+
+    n = getc(fd);
+    n = (n << 8) + getc(fd);
+    return n;
+}
+
+/*
+ * Read 3 bytes from "fd" and turn them into an int, MSB first.
+ */
+    static int
+get3c(fd)
+    FILE	*fd;
+{
+    long	n;
+
+    n = getc(fd);
+    n = (n << 8) + getc(fd);
+    n = (n << 8) + getc(fd);
+    return n;
+}
+
+/*
+ * Read 4 bytes from "fd" and turn them into an int, MSB first.
+ */
+    static int
+get4c(fd)
+    FILE	*fd;
+{
+    long	n;
+
+    n = getc(fd);
+    n = (n << 8) + getc(fd);
+    n = (n << 8) + getc(fd);
+    n = (n << 8) + getc(fd);
+    return n;
+}
+
+/*
+ * Read 8 bytes from "fd" and turn them into a time_t, MSB first.
+ */
+    static time_t
+get8c(fd)
+    FILE	*fd;
+{
+    time_t	n = 0;
+    int		i;
+
+    for (i = 0; i < 8; ++i)
+	n = (n << 8) + getc(fd);
+    return n;
+}
+
+/*
+ * Read a length field from "fd" in "cnt_bytes" bytes.
+ * Allocate memory, read the string into it and add a NUL at the end.
+ * Returns NULL when the count is zero.
+ * Sets "*cntp" to SP_*ERROR when there is an error, length of the result
+ * otherwise.
+ */
+    static char_u *
+read_cnt_string(fd, cnt_bytes, cntp)
+    FILE	*fd;
+    int		cnt_bytes;
+    int		*cntp;
+{
+    int		cnt = 0;
+    int		i;
+    char_u	*str;
+
+    /* read the length bytes, MSB first */
+    for (i = 0; i < cnt_bytes; ++i)
+	cnt = (cnt << 8) + getc(fd);
+    if (cnt < 0)
+    {
+	*cntp = SP_TRUNCERROR;
+	return NULL;
+    }
+    *cntp = cnt;
+    if (cnt == 0)
+	return NULL;	    /* nothing to read, return NULL */
+
+    str = read_string(fd, cnt);
+    if (str == NULL)
+	*cntp = SP_OTHERERROR;
+    return str;
+}
+
+/*
+ * Read a string of length "cnt" from "fd" into allocated memory.
+ * Returns NULL when out of memory.
+ */
+    static char_u *
+read_string(fd, cnt)
+    FILE	*fd;
+    int		cnt;
+{
+    char_u	*str;
+    int		i;
+
+    /* allocate memory */
+    str = alloc((unsigned)cnt + 1);
+    if (str != NULL)
+    {
+	/* Read the string.  Doesn't check for truncated file. */
+	for (i = 0; i < cnt; ++i)
+	    str[i] = getc(fd);
+	str[i] = NUL;
+    }
+    return str;
+}
+
+/*
+ * Read SN_REGION: <regionname> ...
+ * Return SP_*ERROR flags.
+ */
+    static int
+read_region_section(fd, lp, len)
+    FILE	*fd;
+    slang_T	*lp;
+    int		len;
+{
+    int		i;
+
+    if (len > 16)
+	return SP_FORMERROR;
+    for (i = 0; i < len; ++i)
+	lp->sl_regions[i] = getc(fd);			/* <regionname> */
+    lp->sl_regions[len] = NUL;
+    return 0;
+}
+
+/*
+ * Read SN_CHARFLAGS section: <charflagslen> <charflags>
+ *				<folcharslen> <folchars>
+ * Return SP_*ERROR flags.
+ */
+    static int
+read_charflags_section(fd)
+    FILE	*fd;
+{
+    char_u	*flags;
+    char_u	*fol;
+    int		flagslen, follen;
+
+    /* <charflagslen> <charflags> */
+    flags = read_cnt_string(fd, 1, &flagslen);
+    if (flagslen < 0)
+	return flagslen;
+
+    /* <folcharslen> <folchars> */
+    fol = read_cnt_string(fd, 2, &follen);
+    if (follen < 0)
+    {
+	vim_free(flags);
+	return follen;
+    }
+
+    /* Set the word-char flags and fill SPELL_ISUPPER() table. */
+    if (flags != NULL && fol != NULL)
+	set_spell_charflags(flags, flagslen, fol);
+
+    vim_free(flags);
+    vim_free(fol);
+
+    /* When <charflagslen> is zero then <fcharlen> must also be zero. */
+    if ((flags == NULL) != (fol == NULL))
+	return SP_FORMERROR;
+    return 0;
+}
+
+/*
+ * Read SN_PREFCOND section.
+ * Return SP_*ERROR flags.
+ */
+    static int
+read_prefcond_section(fd, lp)
+    FILE	*fd;
+    slang_T	*lp;
+{
+    int		cnt;
+    int		i;
+    int		n;
+    char_u	*p;
+    char_u	buf[MAXWLEN + 1];
+
+    /* <prefcondcnt> <prefcond> ... */
+    cnt = get2c(fd);					/* <prefcondcnt> */
+    if (cnt <= 0)
+	return SP_FORMERROR;
+
+    lp->sl_prefprog = (regprog_T **)alloc_clear(
+					 (unsigned)sizeof(regprog_T *) * cnt);
+    if (lp->sl_prefprog == NULL)
+	return SP_OTHERERROR;
+    lp->sl_prefixcnt = cnt;
+
+    for (i = 0; i < cnt; ++i)
+    {
+	/* <prefcond> : <condlen> <condstr> */
+	n = getc(fd);					/* <condlen> */
+	if (n < 0 || n >= MAXWLEN)
+	    return SP_FORMERROR;
+
+	/* When <condlen> is zero we have an empty condition.  Otherwise
+	 * compile the regexp program used to check for the condition. */
+	if (n > 0)
+	{
+	    buf[0] = '^';	    /* always match at one position only */
+	    p = buf + 1;
+	    while (n-- > 0)
+		*p++ = getc(fd);			/* <condstr> */
+	    *p = NUL;
+	    lp->sl_prefprog[i] = vim_regcomp(buf, RE_MAGIC + RE_STRING);
+	}
+    }
+    return 0;
+}
+
+/*
+ * Read REP or REPSAL items section from "fd": <repcount> <rep> ...
+ * Return SP_*ERROR flags.
+ */
+    static int
+read_rep_section(fd, gap, first)
+    FILE	*fd;
+    garray_T	*gap;
+    short	*first;
+{
+    int		cnt;
+    fromto_T	*ftp;
+    int		i;
+
+    cnt = get2c(fd);					/* <repcount> */
+    if (cnt < 0)
+	return SP_TRUNCERROR;
+
+    if (ga_grow(gap, cnt) == FAIL)
+	return SP_OTHERERROR;
+
+    /* <rep> : <repfromlen> <repfrom> <reptolen> <repto> */
+    for (; gap->ga_len < cnt; ++gap->ga_len)
+    {
+	ftp = &((fromto_T *)gap->ga_data)[gap->ga_len];
+	ftp->ft_from = read_cnt_string(fd, 1, &i);
+	if (i < 0)
+	    return i;
+	if (i == 0)
+	    return SP_FORMERROR;
+	ftp->ft_to = read_cnt_string(fd, 1, &i);
+	if (i <= 0)
+	{
+	    vim_free(ftp->ft_from);
+	    if (i < 0)
+		return i;
+	    return SP_FORMERROR;
+	}
+    }
+
+    /* Fill the first-index table. */
+    for (i = 0; i < 256; ++i)
+	first[i] = -1;
+    for (i = 0; i < gap->ga_len; ++i)
+    {
+	ftp = &((fromto_T *)gap->ga_data)[i];
+	if (first[*ftp->ft_from] == -1)
+	    first[*ftp->ft_from] = i;
+    }
+    return 0;
+}
+
+/*
+ * Read SN_SAL section: <salflags> <salcount> <sal> ...
+ * Return SP_*ERROR flags.
+ */
+    static int
+read_sal_section(fd, slang)
+    FILE	*fd;
+    slang_T	*slang;
+{
+    int		i;
+    int		cnt;
+    garray_T	*gap;
+    salitem_T	*smp;
+    int		ccnt;
+    char_u	*p;
+    int		c = NUL;
+
+    slang->sl_sofo = FALSE;
+
+    i = getc(fd);				/* <salflags> */
+    if (i & SAL_F0LLOWUP)
+	slang->sl_followup = TRUE;
+    if (i & SAL_COLLAPSE)
+	slang->sl_collapse = TRUE;
+    if (i & SAL_REM_ACCENTS)
+	slang->sl_rem_accents = TRUE;
+
+    cnt = get2c(fd);				/* <salcount> */
+    if (cnt < 0)
+	return SP_TRUNCERROR;
+
+    gap = &slang->sl_sal;
+    ga_init2(gap, sizeof(salitem_T), 10);
+    if (ga_grow(gap, cnt + 1) == FAIL)
+	return SP_OTHERERROR;
+
+    /* <sal> : <salfromlen> <salfrom> <saltolen> <salto> */
+    for (; gap->ga_len < cnt; ++gap->ga_len)
+    {
+	smp = &((salitem_T *)gap->ga_data)[gap->ga_len];
+	ccnt = getc(fd);			/* <salfromlen> */
+	if (ccnt < 0)
+	    return SP_TRUNCERROR;
+	if ((p = alloc(ccnt + 2)) == NULL)
+	    return SP_OTHERERROR;
+	smp->sm_lead = p;
+
+	/* Read up to the first special char into sm_lead. */
+	for (i = 0; i < ccnt; ++i)
+	{
+	    c = getc(fd);			/* <salfrom> */
+	    if (vim_strchr((char_u *)"0123456789(-<^$", c) != NULL)
+		break;
+	    *p++ = c;
+	}
+	smp->sm_leadlen = (int)(p - smp->sm_lead);
+	*p++ = NUL;
+
+	/* Put (abc) chars in sm_oneof, if any. */
+	if (c == '(')
+	{
+	    smp->sm_oneof = p;
+	    for (++i; i < ccnt; ++i)
+	    {
+		c = getc(fd);			/* <salfrom> */
+		if (c == ')')
+		    break;
+		*p++ = c;
+	    }
+	    *p++ = NUL;
+	    if (++i < ccnt)
+		c = getc(fd);
+	}
+	else
+	    smp->sm_oneof = NULL;
+
+	/* Any following chars go in sm_rules. */
+	smp->sm_rules = p;
+	if (i < ccnt)
+	    /* store the char we got while checking for end of sm_lead */
+	    *p++ = c;
+	for (++i; i < ccnt; ++i)
+	    *p++ = getc(fd);			/* <salfrom> */
+	*p++ = NUL;
+
+	/* <saltolen> <salto> */
+	smp->sm_to = read_cnt_string(fd, 1, &ccnt);
+	if (ccnt < 0)
+	{
+	    vim_free(smp->sm_lead);
+	    return ccnt;
+	}
+
+#ifdef FEAT_MBYTE
+	if (has_mbyte)
+	{
+	    /* convert the multi-byte strings to wide char strings */
+	    smp->sm_lead_w = mb_str2wide(smp->sm_lead);
+	    smp->sm_leadlen = mb_charlen(smp->sm_lead);
+	    if (smp->sm_oneof == NULL)
+		smp->sm_oneof_w = NULL;
+	    else
+		smp->sm_oneof_w = mb_str2wide(smp->sm_oneof);
+	    if (smp->sm_to == NULL)
+		smp->sm_to_w = NULL;
+	    else
+		smp->sm_to_w = mb_str2wide(smp->sm_to);
+	    if (smp->sm_lead_w == NULL
+		    || (smp->sm_oneof_w == NULL && smp->sm_oneof != NULL)
+		    || (smp->sm_to_w == NULL && smp->sm_to != NULL))
+	    {
+		vim_free(smp->sm_lead);
+		vim_free(smp->sm_to);
+		vim_free(smp->sm_lead_w);
+		vim_free(smp->sm_oneof_w);
+		vim_free(smp->sm_to_w);
+		return SP_OTHERERROR;
+	    }
+	}
+#endif
+    }
+
+    if (gap->ga_len > 0)
+    {
+	/* Add one extra entry to mark the end with an empty sm_lead.  Avoids
+	 * that we need to check the index every time. */
+	smp = &((salitem_T *)gap->ga_data)[gap->ga_len];
+	if ((p = alloc(1)) == NULL)
+	    return SP_OTHERERROR;
+	p[0] = NUL;
+	smp->sm_lead = p;
+	smp->sm_leadlen = 0;
+	smp->sm_oneof = NULL;
+	smp->sm_rules = p;
+	smp->sm_to = NULL;
+#ifdef FEAT_MBYTE
+	if (has_mbyte)
+	{
+	    smp->sm_lead_w = mb_str2wide(smp->sm_lead);
+	    smp->sm_leadlen = 0;
+	    smp->sm_oneof_w = NULL;
+	    smp->sm_to_w = NULL;
+	}
+#endif
+	++gap->ga_len;
+    }
+
+    /* Fill the first-index table. */
+    set_sal_first(slang);
+
+    return 0;
+}
+
+/*
+ * Read SN_WORDS: <word> ...
+ * Return SP_*ERROR flags.
+ */
+    static int
+read_words_section(fd, lp, len)
+    FILE	*fd;
+    slang_T	*lp;
+    int		len;
+{
+    int		done = 0;
+    int		i;
+    char_u	word[MAXWLEN];
+
+    while (done < len)
+    {
+	/* Read one word at a time. */
+	for (i = 0; ; ++i)
+	{
+	    word[i] = getc(fd);
+	    if (word[i] == NUL)
+		break;
+	    if (i == MAXWLEN - 1)
+		return SP_FORMERROR;
+	}
+
+	/* Init the count to 10. */
+	count_common_word(lp, word, -1, 10);
+	done += i + 1;
+    }
+    return 0;
+}
+
+/*
+ * Add a word to the hashtable of common words.
+ * If it's already there then the counter is increased.
+ */
+    static void
+count_common_word(lp, word, len, count)
+    slang_T	*lp;
+    char_u	*word;
+    int		len;	    /* word length, -1 for upto NUL */
+    int		count;	    /* 1 to count once, 10 to init */
+{
+    hash_T	hash;
+    hashitem_T	*hi;
+    wordcount_T	*wc;
+    char_u	buf[MAXWLEN];
+    char_u	*p;
+
+    if (len == -1)
+	p = word;
+    else
+    {
+	vim_strncpy(buf, word, len);
+	p = buf;
+    }
+
+    hash = hash_hash(p);
+    hi = hash_lookup(&lp->sl_wordcount, p, hash);
+    if (HASHITEM_EMPTY(hi))
+    {
+	wc = (wordcount_T *)alloc((unsigned)(sizeof(wordcount_T) + STRLEN(p)));
+	if (wc == NULL)
+	    return;
+	STRCPY(wc->wc_word, p);
+	wc->wc_count = count;
+	hash_add_item(&lp->sl_wordcount, hi, wc->wc_word, hash);
+    }
+    else
+    {
+	wc = HI2WC(hi);
+	if ((wc->wc_count += count) < (unsigned)count)	/* check for overflow */
+	    wc->wc_count = MAXWORDCOUNT;
+    }
+}
+
+/*
+ * Adjust the score of common words.
+ */
+    static int
+score_wordcount_adj(slang, score, word, split)
+    slang_T	*slang;
+    int		score;
+    char_u	*word;
+    int		split;	    /* word was split, less bonus */
+{
+    hashitem_T	*hi;
+    wordcount_T	*wc;
+    int		bonus;
+    int		newscore;
+
+    hi = hash_find(&slang->sl_wordcount, word);
+    if (!HASHITEM_EMPTY(hi))
+    {
+	wc = HI2WC(hi);
+	if (wc->wc_count < SCORE_THRES2)
+	    bonus = SCORE_COMMON1;
+	else if (wc->wc_count < SCORE_THRES3)
+	    bonus = SCORE_COMMON2;
+	else
+	    bonus = SCORE_COMMON3;
+	if (split)
+	    newscore = score - bonus / 2;
+	else
+	    newscore = score - bonus;
+	if (newscore < 0)
+	    return 0;
+	return newscore;
+    }
+    return score;
+}
+
+/*
+ * SN_SOFO: <sofofromlen> <sofofrom> <sofotolen> <sofoto>
+ * Return SP_*ERROR flags.
+ */
+    static int
+read_sofo_section(fd, slang)
+    FILE	*fd;
+    slang_T	*slang;
+{
+    int		cnt;
+    char_u	*from, *to;
+    int		res;
+
+    slang->sl_sofo = TRUE;
+
+    /* <sofofromlen> <sofofrom> */
+    from = read_cnt_string(fd, 2, &cnt);
+    if (cnt < 0)
+	return cnt;
+
+    /* <sofotolen> <sofoto> */
+    to = read_cnt_string(fd, 2, &cnt);
+    if (cnt < 0)
+    {
+	vim_free(from);
+	return cnt;
+    }
+
+    /* Store the info in slang->sl_sal and/or slang->sl_sal_first. */
+    if (from != NULL && to != NULL)
+	res = set_sofo(slang, from, to);
+    else if (from != NULL || to != NULL)
+	res = SP_FORMERROR;    /* only one of two strings is an error */
+    else
+	res = 0;
+
+    vim_free(from);
+    vim_free(to);
+    return res;
+}
+
+/*
+ * Read the compound section from the .spl file:
+ *	<compmax> <compminlen> <compsylmax> <compoptions> <compflags>
+ * Returns SP_*ERROR flags.
+ */
+    static int
+read_compound(fd, slang, len)
+    FILE	*fd;
+    slang_T	*slang;
+    int		len;
+{
+    int		todo = len;
+    int		c;
+    int		atstart;
+    char_u	*pat;
+    char_u	*pp;
+    char_u	*cp;
+    char_u	*ap;
+    int		cnt;
+    garray_T	*gap;
+
+    if (todo < 2)
+	return SP_FORMERROR;	/* need at least two bytes */
+
+    --todo;
+    c = getc(fd);					/* <compmax> */
+    if (c < 2)
+	c = MAXWLEN;
+    slang->sl_compmax = c;
+
+    --todo;
+    c = getc(fd);					/* <compminlen> */
+    if (c < 1)
+	c = 0;
+    slang->sl_compminlen = c;
+
+    --todo;
+    c = getc(fd);					/* <compsylmax> */
+    if (c < 1)
+	c = MAXWLEN;
+    slang->sl_compsylmax = c;
+
+    c = getc(fd);					/* <compoptions> */
+    if (c != 0)
+	ungetc(c, fd);	    /* be backwards compatible with Vim 7.0b */
+    else
+    {
+	--todo;
+	c = getc(fd);	    /* only use the lower byte for now */
+	--todo;
+	slang->sl_compoptions = c;
+
+	gap = &slang->sl_comppat;
+	c = get2c(fd);					/* <comppatcount> */
+	todo -= 2;
+	ga_init2(gap, sizeof(char_u *), c);
+	if (ga_grow(gap, c) == OK)
+	    while (--c >= 0)
+	    {
+		((char_u **)(gap->ga_data))[gap->ga_len++] =
+						 read_cnt_string(fd, 1, &cnt);
+					    /* <comppatlen> <comppattext> */
+		if (cnt < 0)
+		    return cnt;
+		todo -= cnt + 1;
+	    }
+    }
+    if (todo < 0)
+	return SP_FORMERROR;
+
+    /* Turn the COMPOUNDRULE items into a regexp pattern:
+     * "a[bc]/a*b+" -> "^\(a[bc]\|a*b\+\)$".
+     * Inserting backslashes may double the length, "^\(\)$<Nul>" is 7 bytes.
+     * Conversion to utf-8 may double the size. */
+    c = todo * 2 + 7;
+#ifdef FEAT_MBYTE
+    if (enc_utf8)
+	c += todo * 2;
+#endif
+    pat = alloc((unsigned)c);
+    if (pat == NULL)
+	return SP_OTHERERROR;
+
+    /* We also need a list of all flags that can appear at the start and one
+     * for all flags. */
+    cp = alloc(todo + 1);
+    if (cp == NULL)
+    {
+	vim_free(pat);
+	return SP_OTHERERROR;
+    }
+    slang->sl_compstartflags = cp;
+    *cp = NUL;
+
+    ap = alloc(todo + 1);
+    if (ap == NULL)
+    {
+	vim_free(pat);
+	return SP_OTHERERROR;
+    }
+    slang->sl_compallflags = ap;
+    *ap = NUL;
+
+    pp = pat;
+    *pp++ = '^';
+    *pp++ = '\\';
+    *pp++ = '(';
+
+    atstart = 1;
+    while (todo-- > 0)
+    {
+	c = getc(fd);					/* <compflags> */
+
+	/* Add all flags to "sl_compallflags". */
+	if (vim_strchr((char_u *)"+*[]/", c) == NULL
+		&& !byte_in_str(slang->sl_compallflags, c))
+	{
+	    *ap++ = c;
+	    *ap = NUL;
+	}
+
+	if (atstart != 0)
+	{
+	    /* At start of item: copy flags to "sl_compstartflags".  For a
+	     * [abc] item set "atstart" to 2 and copy up to the ']'. */
+	    if (c == '[')
+		atstart = 2;
+	    else if (c == ']')
+		atstart = 0;
+	    else
+	    {
+		if (!byte_in_str(slang->sl_compstartflags, c))
+		{
+		    *cp++ = c;
+		    *cp = NUL;
+		}
+		if (atstart == 1)
+		    atstart = 0;
+	    }
+	}
+	if (c == '/')	    /* slash separates two items */
+	{
+	    *pp++ = '\\';
+	    *pp++ = '|';
+	    atstart = 1;
+	}
+	else		    /* normal char, "[abc]" and '*' are copied as-is */
+	{
+	    if (c == '+' || c == '~')
+		*pp++ = '\\';	    /* "a+" becomes "a\+" */
+#ifdef FEAT_MBYTE
+	    if (enc_utf8)
+		pp += mb_char2bytes(c, pp);
+	    else
+#endif
+		*pp++ = c;
+	}
+    }
+
+    *pp++ = '\\';
+    *pp++ = ')';
+    *pp++ = '$';
+    *pp = NUL;
+
+    slang->sl_compprog = vim_regcomp(pat, RE_MAGIC + RE_STRING + RE_STRICT);
+    vim_free(pat);
+    if (slang->sl_compprog == NULL)
+	return SP_FORMERROR;
+
+    return 0;
+}
+
+/*
+ * Return TRUE if byte "n" appears in "str".
+ * Like strchr() but independent of locale.
+ */
+    static int
+byte_in_str(str, n)
+    char_u	*str;
+    int		n;
+{
+    char_u	*p;
+
+    for (p = str; *p != NUL; ++p)
+	if (*p == n)
+	    return TRUE;
+    return FALSE;
+}
+
+#define SY_MAXLEN   30
+typedef struct syl_item_S
+{
+    char_u	sy_chars[SY_MAXLEN];	    /* the sequence of chars */
+    int		sy_len;
+} syl_item_T;
+
+/*
+ * Truncate "slang->sl_syllable" at the first slash and put the following items
+ * in "slang->sl_syl_items".
+ */
+    static int
+init_syl_tab(slang)
+    slang_T	*slang;
+{
+    char_u	*p;
+    char_u	*s;
+    int		l;
+    syl_item_T	*syl;
+
+    ga_init2(&slang->sl_syl_items, sizeof(syl_item_T), 4);
+    p = vim_strchr(slang->sl_syllable, '/');
+    while (p != NULL)
+    {
+	*p++ = NUL;
+	if (*p == NUL)	    /* trailing slash */
+	    break;
+	s = p;
+	p = vim_strchr(p, '/');
+	if (p == NULL)
+	    l = (int)STRLEN(s);
+	else
+	    l = (int)(p - s);
+	if (l >= SY_MAXLEN)
+	    return SP_FORMERROR;
+	if (ga_grow(&slang->sl_syl_items, 1) == FAIL)
+	    return SP_OTHERERROR;
+	syl = ((syl_item_T *)slang->sl_syl_items.ga_data)
+					       + slang->sl_syl_items.ga_len++;
+	vim_strncpy(syl->sy_chars, s, l);
+	syl->sy_len = l;
+    }
+    return OK;
+}
+
+/*
+ * Count the number of syllables in "word".
+ * When "word" contains spaces the syllables after the last space are counted.
+ * Returns zero if syllables are not defines.
+ */
+    static int
+count_syllables(slang, word)
+    slang_T	*slang;
+    char_u	*word;
+{
+    int		cnt = 0;
+    int		skip = FALSE;
+    char_u	*p;
+    int		len;
+    int		i;
+    syl_item_T	*syl;
+    int		c;
+
+    if (slang->sl_syllable == NULL)
+	return 0;
+
+    for (p = word; *p != NUL; p += len)
+    {
+	/* When running into a space reset counter. */
+	if (*p == ' ')
+	{
+	    len = 1;
+	    cnt = 0;
+	    continue;
+	}
+
+	/* Find longest match of syllable items. */
+	len = 0;
+	for (i = 0; i < slang->sl_syl_items.ga_len; ++i)
+	{
+	    syl = ((syl_item_T *)slang->sl_syl_items.ga_data) + i;
+	    if (syl->sy_len > len
+			       && STRNCMP(p, syl->sy_chars, syl->sy_len) == 0)
+		len = syl->sy_len;
+	}
+	if (len != 0)	/* found a match, count syllable  */
+	{
+	    ++cnt;
+	    skip = FALSE;
+	}
+	else
+	{
+	    /* No recognized syllable item, at least a syllable char then? */
+#ifdef FEAT_MBYTE
+	    c = mb_ptr2char(p);
+	    len = (*mb_ptr2len)(p);
+#else
+	    c = *p;
+	    len = 1;
+#endif
+	    if (vim_strchr(slang->sl_syllable, c) == NULL)
+		skip = FALSE;	    /* No, search for next syllable */
+	    else if (!skip)
+	    {
+		++cnt;		    /* Yes, count it */
+		skip = TRUE;	    /* don't count following syllable chars */
+	    }
+	}
+    }
+    return cnt;
+}
+
+/*
+ * Set the SOFOFROM and SOFOTO items in language "lp".
+ * Returns SP_*ERROR flags when there is something wrong.
+ */
+    static int
+set_sofo(lp, from, to)
+    slang_T	*lp;
+    char_u	*from;
+    char_u	*to;
+{
+    int		i;
+
+#ifdef FEAT_MBYTE
+    garray_T	*gap;
+    char_u	*s;
+    char_u	*p;
+    int		c;
+    int		*inp;
+
+    if (has_mbyte)
+    {
+	/* Use "sl_sal" as an array with 256 pointers to a list of wide
+	 * characters.  The index is the low byte of the character.
+	 * The list contains from-to pairs with a terminating NUL.
+	 * sl_sal_first[] is used for latin1 "from" characters. */
+	gap = &lp->sl_sal;
+	ga_init2(gap, sizeof(int *), 1);
+	if (ga_grow(gap, 256) == FAIL)
+	    return SP_OTHERERROR;
+	vim_memset(gap->ga_data, 0, sizeof(int *) * 256);
+	gap->ga_len = 256;
+
+	/* First count the number of items for each list.  Temporarily use
+	 * sl_sal_first[] for this. */
+	for (p = from, s = to; *p != NUL && *s != NUL; )
+	{
+	    c = mb_cptr2char_adv(&p);
+	    mb_cptr_adv(s);
+	    if (c >= 256)
+		++lp->sl_sal_first[c & 0xff];
+	}
+	if (*p != NUL || *s != NUL)	    /* lengths differ */
+	    return SP_FORMERROR;
+
+	/* Allocate the lists. */
+	for (i = 0; i < 256; ++i)
+	    if (lp->sl_sal_first[i] > 0)
+	    {
+		p = alloc(sizeof(int) * (lp->sl_sal_first[i] * 2 + 1));
+		if (p == NULL)
+		    return SP_OTHERERROR;
+		((int **)gap->ga_data)[i] = (int *)p;
+		*(int *)p = 0;
+	    }
+
+	/* Put the characters up to 255 in sl_sal_first[] the rest in a sl_sal
+	 * list. */
+	vim_memset(lp->sl_sal_first, 0, sizeof(salfirst_T) * 256);
+	for (p = from, s = to; *p != NUL && *s != NUL; )
+	{
+	    c = mb_cptr2char_adv(&p);
+	    i = mb_cptr2char_adv(&s);
+	    if (c >= 256)
+	    {
+		/* Append the from-to chars at the end of the list with
+		 * the low byte. */
+		inp = ((int **)gap->ga_data)[c & 0xff];
+		while (*inp != 0)
+		    ++inp;
+		*inp++ = c;		/* from char */
+		*inp++ = i;		/* to char */
+		*inp++ = NUL;		/* NUL at the end */
+	    }
+	    else
+		/* mapping byte to char is done in sl_sal_first[] */
+		lp->sl_sal_first[c] = i;
+	}
+    }
+    else
+#endif
+    {
+	/* mapping bytes to bytes is done in sl_sal_first[] */
+	if (STRLEN(from) != STRLEN(to))
+	    return SP_FORMERROR;
+
+	for (i = 0; to[i] != NUL; ++i)
+	    lp->sl_sal_first[from[i]] = to[i];
+	lp->sl_sal.ga_len = 1;		/* indicates we have soundfolding */
+    }
+
+    return 0;
+}
+
+/*
+ * Fill the first-index table for "lp".
+ */
+    static void
+set_sal_first(lp)
+    slang_T	*lp;
+{
+    salfirst_T	*sfirst;
+    int		i;
+    salitem_T	*smp;
+    int		c;
+    garray_T	*gap = &lp->sl_sal;
+
+    sfirst = lp->sl_sal_first;
+    for (i = 0; i < 256; ++i)
+	sfirst[i] = -1;
+    smp = (salitem_T *)gap->ga_data;
+    for (i = 0; i < gap->ga_len; ++i)
+    {
+#ifdef FEAT_MBYTE
+	if (has_mbyte)
+	    /* Use the lowest byte of the first character.  For latin1 it's
+	     * the character, for other encodings it should differ for most
+	     * characters. */
+	    c = *smp[i].sm_lead_w & 0xff;
+	else
+#endif
+	    c = *smp[i].sm_lead;
+	if (sfirst[c] == -1)
+	{
+	    sfirst[c] = i;
+#ifdef FEAT_MBYTE
+	    if (has_mbyte)
+	    {
+		int		n;
+
+		/* Make sure all entries with this byte are following each
+		 * other.  Move the ones that are in the wrong position.  Do
+		 * keep the same ordering! */
+		while (i + 1 < gap->ga_len
+				       && (*smp[i + 1].sm_lead_w & 0xff) == c)
+		    /* Skip over entry with same index byte. */
+		    ++i;
+
+		for (n = 1; i + n < gap->ga_len; ++n)
+		    if ((*smp[i + n].sm_lead_w & 0xff) == c)
+		    {
+			salitem_T  tsal;
+
+			/* Move entry with same index byte after the entries
+			 * we already found. */
+			++i;
+			--n;
+			tsal = smp[i + n];
+			mch_memmove(smp + i + 1, smp + i,
+						       sizeof(salitem_T) * n);
+			smp[i] = tsal;
+		    }
+	    }
+#endif
+	}
+    }
+}
+
+#ifdef FEAT_MBYTE
+/*
+ * Turn a multi-byte string into a wide character string.
+ * Return it in allocated memory (NULL for out-of-memory)
+ */
+    static int *
+mb_str2wide(s)
+    char_u	*s;
+{
+    int		*res;
+    char_u	*p;
+    int		i = 0;
+
+    res = (int *)alloc(sizeof(int) * (mb_charlen(s) + 1));
+    if (res != NULL)
+    {
+	for (p = s; *p != NUL; )
+	    res[i++] = mb_ptr2char_adv(&p);
+	res[i] = NUL;
+    }
+    return res;
+}
+#endif
+
+/*
+ * Read a tree from the .spl or .sug file.
+ * Allocates the memory and stores pointers in "bytsp" and "idxsp".
+ * This is skipped when the tree has zero length.
+ * Returns zero when OK, SP_ value for an error.
+ */
+    static int
+spell_read_tree(fd, bytsp, idxsp, prefixtree, prefixcnt)
+    FILE	*fd;
+    char_u	**bytsp;
+    idx_T	**idxsp;
+    int		prefixtree;	/* TRUE for the prefix tree */
+    int		prefixcnt;	/* when "prefixtree" is TRUE: prefix count */
+{
+    int		len;
+    int		idx;
+    char_u	*bp;
+    idx_T	*ip;
+
+    /* The tree size was computed when writing the file, so that we can
+     * allocate it as one long block. <nodecount> */
+    len = get4c(fd);
+    if (len < 0)
+	return SP_TRUNCERROR;
+    if (len > 0)
+    {
+	/* Allocate the byte array. */
+	bp = lalloc((long_u)len, TRUE);
+	if (bp == NULL)
+	    return SP_OTHERERROR;
+	*bytsp = bp;
+
+	/* Allocate the index array. */
+	ip = (idx_T *)lalloc_clear((long_u)(len * sizeof(int)), TRUE);
+	if (ip == NULL)
+	    return SP_OTHERERROR;
+	*idxsp = ip;
+
+	/* Recursively read the tree and store it in the array. */
+	idx = read_tree_node(fd, bp, ip, len, 0, prefixtree, prefixcnt);
+	if (idx < 0)
+	    return idx;
+    }
+    return 0;
+}
+
+/*
+ * Read one row of siblings from the spell file and store it in the byte array
+ * "byts" and index array "idxs".  Recursively read the children.
+ *
+ * NOTE: The code here must match put_node()!
+ *
+ * Returns the index (>= 0) following the siblings.
+ * Returns SP_TRUNCERROR if the file is shorter than expected.
+ * Returns SP_FORMERROR if there is a format error.
+ */
+    static idx_T
+read_tree_node(fd, byts, idxs, maxidx, startidx, prefixtree, maxprefcondnr)
+    FILE	*fd;
+    char_u	*byts;
+    idx_T	*idxs;
+    int		maxidx;		    /* size of arrays */
+    idx_T	startidx;	    /* current index in "byts" and "idxs" */
+    int		prefixtree;	    /* TRUE for reading PREFIXTREE */
+    int		maxprefcondnr;	    /* maximum for <prefcondnr> */
+{
+    int		len;
+    int		i;
+    int		n;
+    idx_T	idx = startidx;
+    int		c;
+    int		c2;
+#define SHARED_MASK	0x8000000
+
+    len = getc(fd);					/* <siblingcount> */
+    if (len <= 0)
+	return SP_TRUNCERROR;
+
+    if (startidx + len >= maxidx)
+	return SP_FORMERROR;
+    byts[idx++] = len;
+
+    /* Read the byte values, flag/region bytes and shared indexes. */
+    for (i = 1; i <= len; ++i)
+    {
+	c = getc(fd);					/* <byte> */
+	if (c < 0)
+	    return SP_TRUNCERROR;
+	if (c <= BY_SPECIAL)
+	{
+	    if (c == BY_NOFLAGS && !prefixtree)
+	    {
+		/* No flags, all regions. */
+		idxs[idx] = 0;
+		c = 0;
+	    }
+	    else if (c != BY_INDEX)
+	    {
+		if (prefixtree)
+		{
+		    /* Read the optional pflags byte, the prefix ID and the
+		     * condition nr.  In idxs[] store the prefix ID in the low
+		     * byte, the condition index shifted up 8 bits, the flags
+		     * shifted up 24 bits. */
+		    if (c == BY_FLAGS)
+			c = getc(fd) << 24;		/* <pflags> */
+		    else
+			c = 0;
+
+		    c |= getc(fd);			/* <affixID> */
+
+		    n = get2c(fd);			/* <prefcondnr> */
+		    if (n >= maxprefcondnr)
+			return SP_FORMERROR;
+		    c |= (n << 8);
+		}
+		else /* c must be BY_FLAGS or BY_FLAGS2 */
+		{
+		    /* Read flags and optional region and prefix ID.  In
+		     * idxs[] the flags go in the low two bytes, region above
+		     * that and prefix ID above the region. */
+		    c2 = c;
+		    c = getc(fd);			/* <flags> */
+		    if (c2 == BY_FLAGS2)
+			c = (getc(fd) << 8) + c;	/* <flags2> */
+		    if (c & WF_REGION)
+			c = (getc(fd) << 16) + c;	/* <region> */
+		    if (c & WF_AFX)
+			c = (getc(fd) << 24) + c;	/* <affixID> */
+		}
+
+		idxs[idx] = c;
+		c = 0;
+	    }
+	    else /* c == BY_INDEX */
+	    {
+							/* <nodeidx> */
+		n = get3c(fd);
+		if (n < 0 || n >= maxidx)
+		    return SP_FORMERROR;
+		idxs[idx] = n + SHARED_MASK;
+		c = getc(fd);				/* <xbyte> */
+	    }
+	}
+	byts[idx++] = c;
+    }
+
+    /* Recursively read the children for non-shared siblings.
+     * Skip the end-of-word ones (zero byte value) and the shared ones (and
+     * remove SHARED_MASK) */
+    for (i = 1; i <= len; ++i)
+	if (byts[startidx + i] != 0)
+	{
+	    if (idxs[startidx + i] & SHARED_MASK)
+		idxs[startidx + i] &= ~SHARED_MASK;
+	    else
+	    {
+		idxs[startidx + i] = idx;
+		idx = read_tree_node(fd, byts, idxs, maxidx, idx,
+						     prefixtree, maxprefcondnr);
+		if (idx < 0)
+		    break;
+	    }
+	}
+
+    return idx;
+}
+
+/*
+ * Parse 'spelllang' and set buf->b_langp accordingly.
+ * Returns NULL if it's OK, an error message otherwise.
+ */
+    char_u *
+did_set_spelllang(buf)
+    buf_T	*buf;
+{
+    garray_T	ga;
+    char_u	*splp;
+    char_u	*region;
+    char_u	region_cp[3];
+    int		filename;
+    int		region_mask;
+    slang_T	*slang;
+    int		c;
+    char_u	lang[MAXWLEN + 1];
+    char_u	spf_name[MAXPATHL];
+    int		len;
+    char_u	*p;
+    int		round;
+    char_u	*spf;
+    char_u	*use_region = NULL;
+    int		dont_use_region = FALSE;
+    int		nobreak = FALSE;
+    int		i, j;
+    langp_T	*lp, *lp2;
+    static int	recursive = FALSE;
+    char_u	*ret_msg = NULL;
+    char_u	*spl_copy;
+
+    /* We don't want to do this recursively.  May happen when a language is
+     * not available and the SpellFileMissing autocommand opens a new buffer
+     * in which 'spell' is set. */
+    if (recursive)
+	return NULL;
+    recursive = TRUE;
+
+    ga_init2(&ga, sizeof(langp_T), 2);
+    clear_midword(buf);
+
+    /* Make a copy of 'spellang', the SpellFileMissing autocommands may change
+     * it under our fingers. */
+    spl_copy = vim_strsave(buf->b_p_spl);
+    if (spl_copy == NULL)
+	goto theend;
+
+    /* loop over comma separated language names. */
+    for (splp = spl_copy; *splp != NUL; )
+    {
+	/* Get one language name. */
+	copy_option_part(&splp, lang, MAXWLEN, ",");
+
+	region = NULL;
+	len = (int)STRLEN(lang);
+
+	/* If the name ends in ".spl" use it as the name of the spell file.
+	 * If there is a region name let "region" point to it and remove it
+	 * from the name. */
+	if (len > 4 && fnamecmp(lang + len - 4, ".spl") == 0)
+	{
+	    filename = TRUE;
+
+	    /* Locate a region and remove it from the file name. */
+	    p = vim_strchr(gettail(lang), '_');
+	    if (p != NULL && ASCII_ISALPHA(p[1]) && ASCII_ISALPHA(p[2])
+						      && !ASCII_ISALPHA(p[3]))
+	    {
+		vim_strncpy(region_cp, p + 1, 2);
+		mch_memmove(p, p + 3, len - (p - lang) - 2);
+		len -= 3;
+		region = region_cp;
+	    }
+	    else
+		dont_use_region = TRUE;
+
+	    /* Check if we loaded this language before. */
+	    for (slang = first_lang; slang != NULL; slang = slang->sl_next)
+		if (fullpathcmp(lang, slang->sl_fname, FALSE) == FPC_SAME)
+		    break;
+	}
+	else
+	{
+	    filename = FALSE;
+	    if (len > 3 && lang[len - 3] == '_')
+	    {
+		region = lang + len - 2;
+		len -= 3;
+		lang[len] = NUL;
+	    }
+	    else
+		dont_use_region = TRUE;
+
+	    /* Check if we loaded this language before. */
+	    for (slang = first_lang; slang != NULL; slang = slang->sl_next)
+		if (STRICMP(lang, slang->sl_name) == 0)
+		    break;
+	}
+
+	if (region != NULL)
+	{
+	    /* If the region differs from what was used before then don't
+	     * use it for 'spellfile'. */
+	    if (use_region != NULL && STRCMP(region, use_region) != 0)
+		dont_use_region = TRUE;
+	    use_region = region;
+	}
+
+	/* If not found try loading the language now. */
+	if (slang == NULL)
+	{
+	    if (filename)
+		(void)spell_load_file(lang, lang, NULL, FALSE);
+	    else
+	    {
+		spell_load_lang(lang);
+#ifdef FEAT_AUTOCMD
+		/* SpellFileMissing autocommands may do anything, including
+		 * destroying the buffer we are using... */
+		if (!buf_valid(buf))
+		{
+		    ret_msg = (char_u *)"E797: SpellFileMissing autocommand deleted buffer";
+		    goto theend;
+		}
+#endif
+	    }
+	}
+
+	/*
+	 * Loop over the languages, there can be several files for "lang".
+	 */
+	for (slang = first_lang; slang != NULL; slang = slang->sl_next)
+	    if (filename ? fullpathcmp(lang, slang->sl_fname, FALSE) == FPC_SAME
+			 : STRICMP(lang, slang->sl_name) == 0)
+	    {
+		region_mask = REGION_ALL;
+		if (!filename && region != NULL)
+		{
+		    /* find region in sl_regions */
+		    c = find_region(slang->sl_regions, region);
+		    if (c == REGION_ALL)
+		    {
+			if (slang->sl_add)
+			{
+			    if (*slang->sl_regions != NUL)
+				/* This addition file is for other regions. */
+				region_mask = 0;
+			}
+			else
+			    /* This is probably an error.  Give a warning and
+			     * accept the words anyway. */
+			    smsg((char_u *)
+				    _("Warning: region %s not supported"),
+								      region);
+		    }
+		    else
+			region_mask = 1 << c;
+		}
+
+		if (region_mask != 0)
+		{
+		    if (ga_grow(&ga, 1) == FAIL)
+		    {
+			ga_clear(&ga);
+			ret_msg = e_outofmem;
+			goto theend;
+		    }
+		    LANGP_ENTRY(ga, ga.ga_len)->lp_slang = slang;
+		    LANGP_ENTRY(ga, ga.ga_len)->lp_region = region_mask;
+		    ++ga.ga_len;
+		    use_midword(slang, buf);
+		    if (slang->sl_nobreak)
+			nobreak = TRUE;
+		}
+	    }
+    }
+
+    /* round 0: load int_wordlist, if possible.
+     * round 1: load first name in 'spellfile'.
+     * round 2: load second name in 'spellfile.
+     * etc. */
+    spf = buf->b_p_spf;
+    for (round = 0; round == 0 || *spf != NUL; ++round)
+    {
+	if (round == 0)
+	{
+	    /* Internal wordlist, if there is one. */
+	    if (int_wordlist == NULL)
+		continue;
+	    int_wordlist_spl(spf_name);
+	}
+	else
+	{
+	    /* One entry in 'spellfile'. */
+	    copy_option_part(&spf, spf_name, MAXPATHL - 5, ",");
+	    STRCAT(spf_name, ".spl");
+
+	    /* If it was already found above then skip it. */
+	    for (c = 0; c < ga.ga_len; ++c)
+	    {
+		p = LANGP_ENTRY(ga, c)->lp_slang->sl_fname;
+		if (p != NULL && fullpathcmp(spf_name, p, FALSE) == FPC_SAME)
+		    break;
+	    }
+	    if (c < ga.ga_len)
+		continue;
+	}
+
+	/* Check if it was loaded already. */
+	for (slang = first_lang; slang != NULL; slang = slang->sl_next)
+	    if (fullpathcmp(spf_name, slang->sl_fname, FALSE) == FPC_SAME)
+		break;
+	if (slang == NULL)
+	{
+	    /* Not loaded, try loading it now.  The language name includes the
+	     * region name, the region is ignored otherwise.  for int_wordlist
+	     * use an arbitrary name. */
+	    if (round == 0)
+		STRCPY(lang, "internal wordlist");
+	    else
+	    {
+		vim_strncpy(lang, gettail(spf_name), MAXWLEN);
+		p = vim_strchr(lang, '.');
+		if (p != NULL)
+		    *p = NUL;	/* truncate at ".encoding.add" */
+	    }
+	    slang = spell_load_file(spf_name, lang, NULL, TRUE);
+
+	    /* If one of the languages has NOBREAK we assume the addition
+	     * files also have this. */
+	    if (slang != NULL && nobreak)
+		slang->sl_nobreak = TRUE;
+	}
+	if (slang != NULL && ga_grow(&ga, 1) == OK)
+	{
+	    region_mask = REGION_ALL;
+	    if (use_region != NULL && !dont_use_region)
+	    {
+		/* find region in sl_regions */
+		c = find_region(slang->sl_regions, use_region);
+		if (c != REGION_ALL)
+		    region_mask = 1 << c;
+		else if (*slang->sl_regions != NUL)
+		    /* This spell file is for other regions. */
+		    region_mask = 0;
+	    }
+
+	    if (region_mask != 0)
+	    {
+		LANGP_ENTRY(ga, ga.ga_len)->lp_slang = slang;
+		LANGP_ENTRY(ga, ga.ga_len)->lp_sallang = NULL;
+		LANGP_ENTRY(ga, ga.ga_len)->lp_replang = NULL;
+		LANGP_ENTRY(ga, ga.ga_len)->lp_region = region_mask;
+		++ga.ga_len;
+		use_midword(slang, buf);
+	    }
+	}
+    }
+
+    /* Everything is fine, store the new b_langp value. */
+    ga_clear(&buf->b_langp);
+    buf->b_langp = ga;
+
+    /* For each language figure out what language to use for sound folding and
+     * REP items.  If the language doesn't support it itself use another one
+     * with the same name.  E.g. for "en-math" use "en". */
+    for (i = 0; i < ga.ga_len; ++i)
+    {
+	lp = LANGP_ENTRY(ga, i);
+
+	/* sound folding */
+	if (lp->lp_slang->sl_sal.ga_len > 0)
+	    /* language does sound folding itself */
+	    lp->lp_sallang = lp->lp_slang;
+	else
+	    /* find first similar language that does sound folding */
+	    for (j = 0; j < ga.ga_len; ++j)
+	    {
+		lp2 = LANGP_ENTRY(ga, j);
+		if (lp2->lp_slang->sl_sal.ga_len > 0
+			&& STRNCMP(lp->lp_slang->sl_name,
+					      lp2->lp_slang->sl_name, 2) == 0)
+		{
+		    lp->lp_sallang = lp2->lp_slang;
+		    break;
+		}
+	    }
+
+	/* REP items */
+	if (lp->lp_slang->sl_rep.ga_len > 0)
+	    /* language has REP items itself */
+	    lp->lp_replang = lp->lp_slang;
+	else
+	    /* find first similar language that has REP items */
+	    for (j = 0; j < ga.ga_len; ++j)
+	    {
+		lp2 = LANGP_ENTRY(ga, j);
+		if (lp2->lp_slang->sl_rep.ga_len > 0
+			&& STRNCMP(lp->lp_slang->sl_name,
+					      lp2->lp_slang->sl_name, 2) == 0)
+		{
+		    lp->lp_replang = lp2->lp_slang;
+		    break;
+		}
+	    }
+    }
+
+theend:
+    vim_free(spl_copy);
+    recursive = FALSE;
+    return ret_msg;
+}
+
+/*
+ * Clear the midword characters for buffer "buf".
+ */
+    static void
+clear_midword(buf)
+    buf_T	*buf;
+{
+    vim_memset(buf->b_spell_ismw, 0, 256);
+#ifdef FEAT_MBYTE
+    vim_free(buf->b_spell_ismw_mb);
+    buf->b_spell_ismw_mb = NULL;
+#endif
+}
+
+/*
+ * Use the "sl_midword" field of language "lp" for buffer "buf".
+ * They add up to any currently used midword characters.
+ */
+    static void
+use_midword(lp, buf)
+    slang_T	*lp;
+    buf_T	*buf;
+{
+    char_u	*p;
+
+    if (lp->sl_midword == NULL)	    /* there aren't any */
+	return;
+
+    for (p = lp->sl_midword; *p != NUL; )
+#ifdef FEAT_MBYTE
+	if (has_mbyte)
+	{
+	    int	    c, l, n;
+	    char_u  *bp;
+
+	    c = mb_ptr2char(p);
+	    l = (*mb_ptr2len)(p);
+	    if (c < 256 && l <= 2)
+		buf->b_spell_ismw[c] = TRUE;
+	    else if (buf->b_spell_ismw_mb == NULL)
+		/* First multi-byte char in "b_spell_ismw_mb". */
+		buf->b_spell_ismw_mb = vim_strnsave(p, l);
+	    else
+	    {
+		/* Append multi-byte chars to "b_spell_ismw_mb". */
+		n = (int)STRLEN(buf->b_spell_ismw_mb);
+		bp = vim_strnsave(buf->b_spell_ismw_mb, n + l);
+		if (bp != NULL)
+		{
+		    vim_free(buf->b_spell_ismw_mb);
+		    buf->b_spell_ismw_mb = bp;
+		    vim_strncpy(bp + n, p, l);
+		}
+	    }
+	    p += l;
+	}
+	else
+#endif
+	    buf->b_spell_ismw[*p++] = TRUE;
+}
+
+/*
+ * Find the region "region[2]" in "rp" (points to "sl_regions").
+ * Each region is simply stored as the two characters of it's name.
+ * Returns the index if found (first is 0), REGION_ALL if not found.
+ */
+    static int
+find_region(rp, region)
+    char_u	*rp;
+    char_u	*region;
+{
+    int		i;
+
+    for (i = 0; ; i += 2)
+    {
+	if (rp[i] == NUL)
+	    return REGION_ALL;
+	if (rp[i] == region[0] && rp[i + 1] == region[1])
+	    break;
+    }
+    return i / 2;
+}
+
+/*
+ * Return case type of word:
+ * w word	0
+ * Word		WF_ONECAP
+ * W WORD	WF_ALLCAP
+ * WoRd	wOrd	WF_KEEPCAP
+ */
+    static int
+captype(word, end)
+    char_u	*word;
+    char_u	*end;	    /* When NULL use up to NUL byte. */
+{
+    char_u	*p;
+    int		c;
+    int		firstcap;
+    int		allcap;
+    int		past_second = FALSE;	/* past second word char */
+
+    /* find first letter */
+    for (p = word; !spell_iswordp_nmw(p); mb_ptr_adv(p))
+	if (end == NULL ? *p == NUL : p >= end)
+	    return 0;	    /* only non-word characters, illegal word */
+#ifdef FEAT_MBYTE
+    if (has_mbyte)
+	c = mb_ptr2char_adv(&p);
+    else
+#endif
+	c = *p++;
+    firstcap = allcap = SPELL_ISUPPER(c);
+
+    /*
+     * Need to check all letters to find a word with mixed upper/lower.
+     * But a word with an upper char only at start is a ONECAP.
+     */
+    for ( ; end == NULL ? *p != NUL : p < end; mb_ptr_adv(p))
+	if (spell_iswordp_nmw(p))
+	{
+	    c = PTR2CHAR(p);
+	    if (!SPELL_ISUPPER(c))
+	    {
+		/* UUl -> KEEPCAP */
+		if (past_second && allcap)
+		    return WF_KEEPCAP;
+		allcap = FALSE;
+	    }
+	    else if (!allcap)
+		/* UlU -> KEEPCAP */
+		return WF_KEEPCAP;
+	    past_second = TRUE;
+	}
+
+    if (allcap)
+	return WF_ALLCAP;
+    if (firstcap)
+	return WF_ONECAP;
+    return 0;
+}
+
+/*
+ * Like captype() but for a KEEPCAP word add ONECAP if the word starts with a
+ * capital.  So that make_case_word() can turn WOrd into Word.
+ * Add ALLCAP for "WOrD".
+ */
+    static int
+badword_captype(word, end)
+    char_u	*word;
+    char_u	*end;
+{
+    int		flags = captype(word, end);
+    int		c;
+    int		l, u;
+    int		first;
+    char_u	*p;
+
+    if (flags & WF_KEEPCAP)
+    {
+	/* Count the number of UPPER and lower case letters. */
+	l = u = 0;
+	first = FALSE;
+	for (p = word; p < end; mb_ptr_adv(p))
+	{
+	    c = PTR2CHAR(p);
+	    if (SPELL_ISUPPER(c))
+	    {
+		++u;
+		if (p == word)
+		    first = TRUE;
+	    }
+	    else
+		++l;
+	}
+
+	/* If there are more UPPER than lower case letters suggest an
+	 * ALLCAP word.  Otherwise, if the first letter is UPPER then
+	 * suggest ONECAP.  Exception: "ALl" most likely should be "All",
+	 * require three upper case letters. */
+	if (u > l && u > 2)
+	    flags |= WF_ALLCAP;
+	else if (first)
+	    flags |= WF_ONECAP;
+
+	if (u >= 2 && l >= 2)	/* maCARONI maCAroni */
+	    flags |= WF_MIXCAP;
+    }
+    return flags;
+}
+
+# if defined(FEAT_MBYTE) || defined(EXITFREE) || defined(PROTO)
+/*
+ * Free all languages.
+ */
+    void
+spell_free_all()
+{
+    slang_T	*slang;
+    buf_T	*buf;
+    char_u	fname[MAXPATHL];
+
+    /* Go through all buffers and handle 'spelllang'. */
+    for (buf = firstbuf; buf != NULL; buf = buf->b_next)
+	ga_clear(&buf->b_langp);
+
+    while (first_lang != NULL)
+    {
+	slang = first_lang;
+	first_lang = slang->sl_next;
+	slang_free(slang);
+    }
+
+    if (int_wordlist != NULL)
+    {
+	/* Delete the internal wordlist and its .spl file */
+	mch_remove(int_wordlist);
+	int_wordlist_spl(fname);
+	mch_remove(fname);
+	vim_free(int_wordlist);
+	int_wordlist = NULL;
+    }
+
+    init_spell_chartab();
+
+    vim_free(repl_to);
+    repl_to = NULL;
+    vim_free(repl_from);
+    repl_from = NULL;
+}
+# endif
+
+# if defined(FEAT_MBYTE) || defined(PROTO)
+/*
+ * Clear all spelling tables and reload them.
+ * Used after 'encoding' is set and when ":mkspell" was used.
+ */
+    void
+spell_reload()
+{
+    buf_T	*buf;
+    win_T	*wp;
+
+    /* Initialize the table for spell_iswordp(). */
+    init_spell_chartab();
+
+    /* Unload all allocated memory. */
+    spell_free_all();
+
+    /* Go through all buffers and handle 'spelllang'. */
+    for (buf = firstbuf; buf != NULL; buf = buf->b_next)
+    {
+	/* Only load the wordlists when 'spelllang' is set and there is a
+	 * window for this buffer in which 'spell' is set. */
+	if (*buf->b_p_spl != NUL)
+	{
+	    FOR_ALL_WINDOWS(wp)
+		if (wp->w_buffer == buf && wp->w_p_spell)
+		{
+		    (void)did_set_spelllang(buf);
+# ifdef FEAT_WINDOWS
+		    break;
+# endif
+		}
+	}
+    }
+}
+# endif
+
+/*
+ * Reload the spell file "fname" if it's loaded.
+ */
+    static void
+spell_reload_one(fname, added_word)
+    char_u	*fname;
+    int		added_word;	/* invoked through "zg" */
+{
+    slang_T	*slang;
+    int		didit = FALSE;
+
+    for (slang = first_lang; slang != NULL; slang = slang->sl_next)
+    {
+	if (fullpathcmp(fname, slang->sl_fname, FALSE) == FPC_SAME)
+	{
+	    slang_clear(slang);
+	    if (spell_load_file(fname, NULL, slang, FALSE) == NULL)
+		/* reloading failed, clear the language */
+		slang_clear(slang);
+	    redraw_all_later(SOME_VALID);
+	    didit = TRUE;
+	}
+    }
+
+    /* When "zg" was used and the file wasn't loaded yet, should redo
+     * 'spelllang' to load it now. */
+    if (added_word && !didit)
+	did_set_spelllang(curbuf);
+}
+
+
+/*
+ * Functions for ":mkspell".
+ */
+
+#define MAXLINELEN  500		/* Maximum length in bytes of a line in a .aff
+				   and .dic file. */
+/*
+ * Main structure to store the contents of a ".aff" file.
+ */
+typedef struct afffile_S
+{
+    char_u	*af_enc;	/* "SET", normalized, alloc'ed string or NULL */
+    int		af_flagtype;	/* AFT_CHAR, AFT_LONG, AFT_NUM or AFT_CAPLONG */
+    unsigned	af_rare;	/* RARE ID for rare word */
+    unsigned	af_keepcase;	/* KEEPCASE ID for keep-case word */
+    unsigned	af_bad;		/* BAD ID for banned word */
+    unsigned	af_needaffix;	/* NEEDAFFIX ID */
+    unsigned	af_circumfix;	/* CIRCUMFIX ID */
+    unsigned	af_needcomp;	/* NEEDCOMPOUND ID */
+    unsigned	af_comproot;	/* COMPOUNDROOT ID */
+    unsigned	af_compforbid;	/* COMPOUNDFORBIDFLAG ID */
+    unsigned	af_comppermit;	/* COMPOUNDPERMITFLAG ID */
+    unsigned	af_nosuggest;	/* NOSUGGEST ID */
+    int		af_pfxpostpone;	/* postpone prefixes without chop string and
+				   without flags */
+    hashtab_T	af_pref;	/* hashtable for prefixes, affheader_T */
+    hashtab_T	af_suff;	/* hashtable for suffixes, affheader_T */
+    hashtab_T	af_comp;	/* hashtable for compound flags, compitem_T */
+} afffile_T;
+
+#define AFT_CHAR	0	/* flags are one character */
+#define AFT_LONG	1	/* flags are two characters */
+#define AFT_CAPLONG	2	/* flags are one or two characters */
+#define AFT_NUM		3	/* flags are numbers, comma separated */
+
+typedef struct affentry_S affentry_T;
+/* Affix entry from ".aff" file.  Used for prefixes and suffixes. */
+struct affentry_S
+{
+    affentry_T	*ae_next;	/* next affix with same name/number */
+    char_u	*ae_chop;	/* text to chop off basic word (can be NULL) */
+    char_u	*ae_add;	/* text to add to basic word (can be NULL) */
+    char_u	*ae_flags;	/* flags on the affix (can be NULL) */
+    char_u	*ae_cond;	/* condition (NULL for ".") */
+    regprog_T	*ae_prog;	/* regexp program for ae_cond or NULL */
+    char	ae_compforbid;	/* COMPOUNDFORBIDFLAG found */
+    char	ae_comppermit;	/* COMPOUNDPERMITFLAG found */
+};
+
+#ifdef FEAT_MBYTE
+# define AH_KEY_LEN 17		/* 2 x 8 bytes + NUL */
+#else
+# define AH_KEY_LEN 7		/* 6 digits + NUL */
+#endif
+
+/* Affix header from ".aff" file.  Used for af_pref and af_suff. */
+typedef struct affheader_S
+{
+    char_u	ah_key[AH_KEY_LEN]; /* key for hashtab == name of affix */
+    unsigned	ah_flag;	/* affix name as number, uses "af_flagtype" */
+    int		ah_newID;	/* prefix ID after renumbering; 0 if not used */
+    int		ah_combine;	/* suffix may combine with prefix */
+    int		ah_follows;	/* another affix block should be following */
+    affentry_T	*ah_first;	/* first affix entry */
+} affheader_T;
+
+#define HI2AH(hi)   ((affheader_T *)(hi)->hi_key)
+
+/* Flag used in compound items. */
+typedef struct compitem_S
+{
+    char_u	ci_key[AH_KEY_LEN]; /* key for hashtab == name of compound */
+    unsigned	ci_flag;	/* affix name as number, uses "af_flagtype" */
+    int		ci_newID;	/* affix ID after renumbering. */
+} compitem_T;
+
+#define HI2CI(hi)   ((compitem_T *)(hi)->hi_key)
+
+/*
+ * Structure that is used to store the items in the word tree.  This avoids
+ * the need to keep track of each allocated thing, everything is freed all at
+ * once after ":mkspell" is done.
+ */
+#define  SBLOCKSIZE 16000	/* size of sb_data */
+typedef struct sblock_S sblock_T;
+struct sblock_S
+{
+    sblock_T	*sb_next;	/* next block in list */
+    int		sb_used;	/* nr of bytes already in use */
+    char_u	sb_data[1];	/* data, actually longer */
+};
+
+/*
+ * A node in the tree.
+ */
+typedef struct wordnode_S wordnode_T;
+struct wordnode_S
+{
+    union   /* shared to save space */
+    {
+	char_u	hashkey[6];	/* the hash key, only used while compressing */
+	int	index;		/* index in written nodes (valid after first
+				   round) */
+    } wn_u1;
+    union   /* shared to save space */
+    {
+	wordnode_T *next;	/* next node with same hash key */
+	wordnode_T *wnode;	/* parent node that will write this node */
+    } wn_u2;
+    wordnode_T	*wn_child;	/* child (next byte in word) */
+    wordnode_T  *wn_sibling;	/* next sibling (alternate byte in word,
+				   always sorted) */
+    int		wn_refs;	/* Nr. of references to this node.  Only
+				   relevant for first node in a list of
+				   siblings, in following siblings it is
+				   always one. */
+    char_u	wn_byte;	/* Byte for this node. NUL for word end */
+
+    /* Info for when "wn_byte" is NUL.
+     * In PREFIXTREE "wn_region" is used for the prefcondnr.
+     * In the soundfolded word tree "wn_flags" has the MSW of the wordnr and
+     * "wn_region" the LSW of the wordnr. */
+    char_u	wn_affixID;	/* supported/required prefix ID or 0 */
+    short_u	wn_flags;	/* WF_ flags */
+    short	wn_region;	/* region mask */
+
+#ifdef SPELL_PRINTTREE
+    int		wn_nr;		/* sequence nr for printing */
+#endif
+};
+
+#define WN_MASK	 0xffff		/* mask relevant bits of "wn_flags" */
+
+#define HI2WN(hi)    (wordnode_T *)((hi)->hi_key)
+
+/*
+ * Info used while reading the spell files.
+ */
+typedef struct spellinfo_S
+{
+    wordnode_T	*si_foldroot;	/* tree with case-folded words */
+    long	si_foldwcount;	/* nr of words in si_foldroot */
+
+    wordnode_T	*si_keeproot;	/* tree with keep-case words */
+    long	si_keepwcount;	/* nr of words in si_keeproot */
+
+    wordnode_T	*si_prefroot;	/* tree with postponed prefixes */
+
+    long	si_sugtree;	/* creating the soundfolding trie */
+
+    sblock_T	*si_blocks;	/* memory blocks used */
+    long	si_blocks_cnt;	/* memory blocks allocated */
+    long	si_compress_cnt;    /* words to add before lowering
+				       compression limit */
+    wordnode_T	*si_first_free; /* List of nodes that have been freed during
+				   compression, linked by "wn_child" field. */
+    long	si_free_count;	/* number of nodes in si_first_free */
+#ifdef SPELL_PRINTTREE
+    int		si_wordnode_nr;	/* sequence nr for nodes */
+#endif
+    buf_T	*si_spellbuf;	/* buffer used to store soundfold word table */
+
+    int		si_ascii;	/* handling only ASCII words */
+    int		si_add;		/* addition file */
+    int		si_clear_chartab;   /* when TRUE clear char tables */
+    int		si_region;	/* region mask */
+    vimconv_T	si_conv;	/* for conversion to 'encoding' */
+    int		si_memtot;	/* runtime memory used */
+    int		si_verbose;	/* verbose messages */
+    int		si_msg_count;	/* number of words added since last message */
+    char_u	*si_info;	/* info text chars or NULL  */
+    int		si_region_count; /* number of regions supported (1 when there
+				    are no regions) */
+    char_u	si_region_name[16]; /* region names; used only if
+				     * si_region_count > 1) */
+
+    garray_T	si_rep;		/* list of fromto_T entries from REP lines */
+    garray_T	si_repsal;	/* list of fromto_T entries from REPSAL lines */
+    garray_T	si_sal;		/* list of fromto_T entries from SAL lines */
+    char_u	*si_sofofr;	/* SOFOFROM text */
+    char_u	*si_sofoto;	/* SOFOTO text */
+    int		si_nosugfile;	/* NOSUGFILE item found */
+    int		si_nosplitsugs;	/* NOSPLITSUGS item found */
+    int		si_followup;	/* soundsalike: ? */
+    int		si_collapse;	/* soundsalike: ? */
+    hashtab_T	si_commonwords;	/* hashtable for common words */
+    time_t	si_sugtime;	/* timestamp for .sug file */
+    int		si_rem_accents;	/* soundsalike: remove accents */
+    garray_T	si_map;		/* MAP info concatenated */
+    char_u	*si_midword;	/* MIDWORD chars or NULL  */
+    int		si_compmax;	/* max nr of words for compounding */
+    int		si_compminlen;	/* minimal length for compounding */
+    int		si_compsylmax;	/* max nr of syllables for compounding */
+    int		si_compoptions;	/* COMP_ flags */
+    garray_T	si_comppat;	/* CHECKCOMPOUNDPATTERN items, each stored as
+				   a string */
+    char_u	*si_compflags;	/* flags used for compounding */
+    char_u	si_nobreak;	/* NOBREAK */
+    char_u	*si_syllable;	/* syllable string */
+    garray_T	si_prefcond;	/* table with conditions for postponed
+				 * prefixes, each stored as a string */
+    int		si_newprefID;	/* current value for ah_newID */
+    int		si_newcompID;	/* current value for compound ID */
+} spellinfo_T;
+
+static afffile_T *spell_read_aff __ARGS((spellinfo_T *spin, char_u *fname));
+static void aff_process_flags __ARGS((afffile_T *affile, affentry_T *entry));
+static int spell_info_item __ARGS((char_u *s));
+static unsigned affitem2flag __ARGS((int flagtype, char_u *item, char_u	*fname, int lnum));
+static unsigned get_affitem __ARGS((int flagtype, char_u **pp));
+static void process_compflags __ARGS((spellinfo_T *spin, afffile_T *aff, char_u *compflags));
+static void check_renumber __ARGS((spellinfo_T *spin));
+static int flag_in_afflist __ARGS((int flagtype, char_u *afflist, unsigned flag));
+static void aff_check_number __ARGS((int spinval, int affval, char *name));
+static void aff_check_string __ARGS((char_u *spinval, char_u *affval, char *name));
+static int str_equal __ARGS((char_u *s1, char_u	*s2));
+static void add_fromto __ARGS((spellinfo_T *spin, garray_T *gap, char_u	*from, char_u *to));
+static int sal_to_bool __ARGS((char_u *s));
+static int has_non_ascii __ARGS((char_u *s));
+static void spell_free_aff __ARGS((afffile_T *aff));
+static int spell_read_dic __ARGS((spellinfo_T *spin, char_u *fname, afffile_T *affile));
+static int get_affix_flags __ARGS((afffile_T *affile, char_u *afflist));
+static int get_pfxlist __ARGS((afffile_T *affile, char_u *afflist, char_u *store_afflist));
+static void get_compflags __ARGS((afffile_T *affile, char_u *afflist, char_u *store_afflist));
+static int store_aff_word __ARGS((spellinfo_T *spin, char_u *word, char_u *afflist, afffile_T *affile, hashtab_T *ht, hashtab_T *xht, int condit, int flags, char_u *pfxlist, int pfxlen));
+static int spell_read_wordfile __ARGS((spellinfo_T *spin, char_u *fname));
+static void *getroom __ARGS((spellinfo_T *spin, size_t len, int align));
+static char_u *getroom_save __ARGS((spellinfo_T *spin, char_u *s));
+static void free_blocks __ARGS((sblock_T *bl));
+static wordnode_T *wordtree_alloc __ARGS((spellinfo_T *spin));
+static int store_word __ARGS((spellinfo_T *spin, char_u *word, int flags, int region, char_u *pfxlist, int need_affix));
+static int tree_add_word __ARGS((spellinfo_T *spin, char_u *word, wordnode_T *tree, int flags, int region, int affixID));
+static wordnode_T *get_wordnode __ARGS((spellinfo_T *spin));
+static int deref_wordnode __ARGS((spellinfo_T *spin, wordnode_T *node));
+static void free_wordnode __ARGS((spellinfo_T *spin, wordnode_T *n));
+static void wordtree_compress __ARGS((spellinfo_T *spin, wordnode_T *root));
+static int node_compress __ARGS((spellinfo_T *spin, wordnode_T *node, hashtab_T *ht, int *tot));
+static int node_equal __ARGS((wordnode_T *n1, wordnode_T *n2));
+static void put_sugtime __ARGS((spellinfo_T *spin, FILE *fd));
+static int write_vim_spell __ARGS((spellinfo_T *spin, char_u *fname));
+static void clear_node __ARGS((wordnode_T *node));
+static int put_node __ARGS((FILE *fd, wordnode_T *node, int index, int regionmask, int prefixtree));
+static void spell_make_sugfile __ARGS((spellinfo_T *spin, char_u *wfname));
+static int sug_filltree __ARGS((spellinfo_T *spin, slang_T *slang));
+static int sug_maketable __ARGS((spellinfo_T *spin));
+static int sug_filltable __ARGS((spellinfo_T *spin, wordnode_T *node, int startwordnr, garray_T *gap));
+static int offset2bytes __ARGS((int nr, char_u *buf));
+static int bytes2offset __ARGS((char_u **pp));
+static void sug_write __ARGS((spellinfo_T *spin, char_u *fname));
+static void mkspell __ARGS((int fcount, char_u **fnames, int ascii, int overwrite, int added_word));
+static void spell_message __ARGS((spellinfo_T *spin, char_u *str));
+static void init_spellfile __ARGS((void));
+
+/* In the postponed prefixes tree wn_flags is used to store the WFP_ flags,
+ * but it must be negative to indicate the prefix tree to tree_add_word().
+ * Use a negative number with the lower 8 bits zero. */
+#define PFX_FLAGS	-256
+
+/* flags for "condit" argument of store_aff_word() */
+#define CONDIT_COMB	1	/* affix must combine */
+#define CONDIT_CFIX	2	/* affix must have CIRCUMFIX flag */
+#define CONDIT_SUF	4	/* add a suffix for matching flags */
+#define CONDIT_AFF	8	/* word already has an affix */
+
+/*
+ * Tunable parameters for when the tree is compressed.  See 'mkspellmem'.
+ */
+static long compress_start = 30000;	/* memory / SBLOCKSIZE */
+static long compress_inc = 100;		/* memory / SBLOCKSIZE */
+static long compress_added = 500000;	/* word count */
+
+#ifdef SPELL_PRINTTREE
+/*
+ * For debugging the tree code: print the current tree in a (more or less)
+ * readable format, so that we can see what happens when adding a word and/or
+ * compressing the tree.
+ * Based on code from Olaf Seibert.
+ */
+#define PRINTLINESIZE	1000
+#define PRINTWIDTH	6
+
+#define PRINTSOME(l, depth, fmt, a1, a2) vim_snprintf(l + depth * PRINTWIDTH, \
+	    PRINTLINESIZE - PRINTWIDTH * depth, fmt, a1, a2)
+
+static char line1[PRINTLINESIZE];
+static char line2[PRINTLINESIZE];
+static char line3[PRINTLINESIZE];
+
+    static void
+spell_clear_flags(wordnode_T *node)
+{
+    wordnode_T	*np;
+
+    for (np = node; np != NULL; np = np->wn_sibling)
+    {
+	np->wn_u1.index = FALSE;
+	spell_clear_flags(np->wn_child);
+    }
+}
+
+    static void
+spell_print_node(wordnode_T *node, int depth)
+{
+    if (node->wn_u1.index)
+    {
+	/* Done this node before, print the reference. */
+	PRINTSOME(line1, depth, "(%d)", node->wn_nr, 0);
+	PRINTSOME(line2, depth, "    ", 0, 0);
+	PRINTSOME(line3, depth, "    ", 0, 0);
+	msg(line1);
+	msg(line2);
+	msg(line3);
+    }
+    else
+    {
+	node->wn_u1.index = TRUE;
+
+	if (node->wn_byte != NUL)
+	{
+	    if (node->wn_child != NULL)
+		PRINTSOME(line1, depth, " %c -> ", node->wn_byte, 0);
+	    else
+		/* Cannot happen? */
+		PRINTSOME(line1, depth, " %c ???", node->wn_byte, 0);
+	}
+	else
+	    PRINTSOME(line1, depth, " $    ", 0, 0);
+
+	PRINTSOME(line2, depth, "%d/%d    ", node->wn_nr, node->wn_refs);
+
+	if (node->wn_sibling != NULL)
+	    PRINTSOME(line3, depth, " |    ", 0, 0);
+	else
+	    PRINTSOME(line3, depth, "      ", 0, 0);
+
+	if (node->wn_byte == NUL)
+	{
+	    msg(line1);
+	    msg(line2);
+	    msg(line3);
+	}
+
+	/* do the children */
+	if (node->wn_byte != NUL && node->wn_child != NULL)
+	    spell_print_node(node->wn_child, depth + 1);
+
+	/* do the siblings */
+	if (node->wn_sibling != NULL)
+	{
+	    /* get rid of all parent details except | */
+	    STRCPY(line1, line3);
+	    STRCPY(line2, line3);
+	    spell_print_node(node->wn_sibling, depth);
+	}
+    }
+}
+
+    static void
+spell_print_tree(wordnode_T *root)
+{
+    if (root != NULL)
+    {
+	/* Clear the "wn_u1.index" fields, used to remember what has been
+	 * done. */
+	spell_clear_flags(root);
+
+	/* Recursively print the tree. */
+	spell_print_node(root, 0);
+    }
+}
+#endif /* SPELL_PRINTTREE */
+
+/*
+ * Read the affix file "fname".
+ * Returns an afffile_T, NULL for complete failure.
+ */
+    static afffile_T *
+spell_read_aff(spin, fname)
+    spellinfo_T	*spin;
+    char_u	*fname;
+{
+    FILE	*fd;
+    afffile_T	*aff;
+    char_u	rline[MAXLINELEN];
+    char_u	*line;
+    char_u	*pc = NULL;
+#define MAXITEMCNT  30
+    char_u	*(items[MAXITEMCNT]);
+    int		itemcnt;
+    char_u	*p;
+    int		lnum = 0;
+    affheader_T	*cur_aff = NULL;
+    int		did_postpone_prefix = FALSE;
+    int		aff_todo = 0;
+    hashtab_T	*tp;
+    char_u	*low = NULL;
+    char_u	*fol = NULL;
+    char_u	*upp = NULL;
+    int		do_rep;
+    int		do_repsal;
+    int		do_sal;
+    int		do_mapline;
+    int		found_map = FALSE;
+    hashitem_T	*hi;
+    int		l;
+    int		compminlen = 0;		/* COMPOUNDMIN value */
+    int		compsylmax = 0;		/* COMPOUNDSYLMAX value */
+    int		compoptions = 0;	/* COMP_ flags */
+    int		compmax = 0;		/* COMPOUNDWORDMAX value */
+    char_u	*compflags = NULL;	/* COMPOUNDFLAG and COMPOUNDRULE
+					   concatenated */
+    char_u	*midword = NULL;	/* MIDWORD value */
+    char_u	*syllable = NULL;	/* SYLLABLE value */
+    char_u	*sofofrom = NULL;	/* SOFOFROM value */
+    char_u	*sofoto = NULL;		/* SOFOTO value */
+
+    /*
+     * Open the file.
+     */
+    fd = mch_fopen((char *)fname, "r");
+    if (fd == NULL)
+    {
+	EMSG2(_(e_notopen), fname);
+	return NULL;
+    }
+
+    vim_snprintf((char *)IObuff, IOSIZE, _("Reading affix file %s ..."), fname);
+    spell_message(spin, IObuff);
+
+    /* Only do REP lines when not done in another .aff file already. */
+    do_rep = spin->si_rep.ga_len == 0;
+
+    /* Only do REPSAL lines when not done in another .aff file already. */
+    do_repsal = spin->si_repsal.ga_len == 0;
+
+    /* Only do SAL lines when not done in another .aff file already. */
+    do_sal = spin->si_sal.ga_len == 0;
+
+    /* Only do MAP lines when not done in another .aff file already. */
+    do_mapline = spin->si_map.ga_len == 0;
+
+    /*
+     * Allocate and init the afffile_T structure.
+     */
+    aff = (afffile_T *)getroom(spin, sizeof(afffile_T), TRUE);
+    if (aff == NULL)
+    {
+	fclose(fd);
+	return NULL;
+    }
+    hash_init(&aff->af_pref);
+    hash_init(&aff->af_suff);
+    hash_init(&aff->af_comp);
+
+    /*
+     * Read all the lines in the file one by one.
+     */
+    while (!vim_fgets(rline, MAXLINELEN, fd) && !got_int)
+    {
+	line_breakcheck();
+	++lnum;
+
+	/* Skip comment lines. */
+	if (*rline == '#')
+	    continue;
+
+	/* Convert from "SET" to 'encoding' when needed. */
+	vim_free(pc);
+#ifdef FEAT_MBYTE
+	if (spin->si_conv.vc_type != CONV_NONE)
+	{
+	    pc = string_convert(&spin->si_conv, rline, NULL);
+	    if (pc == NULL)
+	    {
+		smsg((char_u *)_("Conversion failure for word in %s line %d: %s"),
+							   fname, lnum, rline);
+		continue;
+	    }
+	    line = pc;
+	}
+	else
+#endif
+	{
+	    pc = NULL;
+	    line = rline;
+	}
+
+	/* Split the line up in white separated items.  Put a NUL after each
+	 * item. */
+	itemcnt = 0;
+	for (p = line; ; )
+	{
+	    while (*p != NUL && *p <= ' ')  /* skip white space and CR/NL */
+		++p;
+	    if (*p == NUL)
+		break;
+	    if (itemcnt == MAXITEMCNT)	    /* too many items */
+		break;
+	    items[itemcnt++] = p;
+	    /* A few items have arbitrary text argument, don't split them. */
+	    if (itemcnt == 2 && spell_info_item(items[0]))
+		while (*p >= ' ' || *p == TAB)    /* skip until CR/NL */
+		    ++p;
+	    else
+		while (*p > ' ')    /* skip until white space or CR/NL */
+		    ++p;
+	    if (*p == NUL)
+		break;
+	    *p++ = NUL;
+	}
+
+	/* Handle non-empty lines. */
+	if (itemcnt > 0)
+	{
+	    if (STRCMP(items[0], "SET") == 0 && itemcnt == 2
+						       && aff->af_enc == NULL)
+	    {
+#ifdef FEAT_MBYTE
+		/* Setup for conversion from "ENC" to 'encoding'. */
+		aff->af_enc = enc_canonize(items[1]);
+		if (aff->af_enc != NULL && !spin->si_ascii
+			&& convert_setup(&spin->si_conv, aff->af_enc,
+							       p_enc) == FAIL)
+		    smsg((char_u *)_("Conversion in %s not supported: from %s to %s"),
+					       fname, aff->af_enc, p_enc);
+		spin->si_conv.vc_fail = TRUE;
+#else
+		    smsg((char_u *)_("Conversion in %s not supported"), fname);
+#endif
+	    }
+	    else if (STRCMP(items[0], "FLAG") == 0 && itemcnt == 2
+					      && aff->af_flagtype == AFT_CHAR)
+	    {
+		if (STRCMP(items[1], "long") == 0)
+		    aff->af_flagtype = AFT_LONG;
+		else if (STRCMP(items[1], "num") == 0)
+		    aff->af_flagtype = AFT_NUM;
+		else if (STRCMP(items[1], "caplong") == 0)
+		    aff->af_flagtype = AFT_CAPLONG;
+		else
+		    smsg((char_u *)_("Invalid value for FLAG in %s line %d: %s"),
+			    fname, lnum, items[1]);
+		if (aff->af_rare != 0
+			|| aff->af_keepcase != 0
+			|| aff->af_bad != 0
+			|| aff->af_needaffix != 0
+			|| aff->af_circumfix != 0
+			|| aff->af_needcomp != 0
+			|| aff->af_comproot != 0
+			|| aff->af_nosuggest != 0
+			|| compflags != NULL
+			|| aff->af_suff.ht_used > 0
+			|| aff->af_pref.ht_used > 0)
+		    smsg((char_u *)_("FLAG after using flags in %s line %d: %s"),
+			    fname, lnum, items[1]);
+	    }
+	    else if (spell_info_item(items[0]))
+	    {
+		    p = (char_u *)getroom(spin,
+			    (spin->si_info == NULL ? 0 : STRLEN(spin->si_info))
+			    + STRLEN(items[0])
+			    + STRLEN(items[1]) + 3, FALSE);
+		    if (p != NULL)
+		    {
+			if (spin->si_info != NULL)
+			{
+			    STRCPY(p, spin->si_info);
+			    STRCAT(p, "\n");
+			}
+			STRCAT(p, items[0]);
+			STRCAT(p, " ");
+			STRCAT(p, items[1]);
+			spin->si_info = p;
+		    }
+	    }
+	    else if (STRCMP(items[0], "MIDWORD") == 0 && itemcnt == 2
+							   && midword == NULL)
+	    {
+		midword = getroom_save(spin, items[1]);
+	    }
+	    else if (STRCMP(items[0], "TRY") == 0 && itemcnt == 2)
+	    {
+		/* ignored, we look in the tree for what chars may appear */
+	    }
+	    /* TODO: remove "RAR" later */
+	    else if ((STRCMP(items[0], "RAR") == 0
+			|| STRCMP(items[0], "RARE") == 0) && itemcnt == 2
+						       && aff->af_rare == 0)
+	    {
+		aff->af_rare = affitem2flag(aff->af_flagtype, items[1],
+								 fname, lnum);
+	    }
+	    /* TODO: remove "KEP" later */
+	    else if ((STRCMP(items[0], "KEP") == 0
+		    || STRCMP(items[0], "KEEPCASE") == 0) && itemcnt == 2
+						     && aff->af_keepcase == 0)
+	    {
+		aff->af_keepcase = affitem2flag(aff->af_flagtype, items[1],
+								 fname, lnum);
+	    }
+	    else if (STRCMP(items[0], "BAD") == 0 && itemcnt == 2
+						       && aff->af_bad == 0)
+	    {
+		aff->af_bad = affitem2flag(aff->af_flagtype, items[1],
+								 fname, lnum);
+	    }
+	    else if (STRCMP(items[0], "NEEDAFFIX") == 0 && itemcnt == 2
+						    && aff->af_needaffix == 0)
+	    {
+		aff->af_needaffix = affitem2flag(aff->af_flagtype, items[1],
+								 fname, lnum);
+	    }
+	    else if (STRCMP(items[0], "CIRCUMFIX") == 0 && itemcnt == 2
+						    && aff->af_circumfix == 0)
+	    {
+		aff->af_circumfix = affitem2flag(aff->af_flagtype, items[1],
+								 fname, lnum);
+	    }
+	    else if (STRCMP(items[0], "NOSUGGEST") == 0 && itemcnt == 2
+						    && aff->af_nosuggest == 0)
+	    {
+		aff->af_nosuggest = affitem2flag(aff->af_flagtype, items[1],
+								 fname, lnum);
+	    }
+	    else if (STRCMP(items[0], "NEEDCOMPOUND") == 0 && itemcnt == 2
+						     && aff->af_needcomp == 0)
+	    {
+		aff->af_needcomp = affitem2flag(aff->af_flagtype, items[1],
+								 fname, lnum);
+	    }
+	    else if (STRCMP(items[0], "COMPOUNDROOT") == 0 && itemcnt == 2
+						     && aff->af_comproot == 0)
+	    {
+		aff->af_comproot = affitem2flag(aff->af_flagtype, items[1],
+								 fname, lnum);
+	    }
+	    else if (STRCMP(items[0], "COMPOUNDFORBIDFLAG") == 0
+				   && itemcnt == 2 && aff->af_compforbid == 0)
+	    {
+		aff->af_compforbid = affitem2flag(aff->af_flagtype, items[1],
+								 fname, lnum);
+		if (aff->af_pref.ht_used > 0)
+		    smsg((char_u *)_("Defining COMPOUNDFORBIDFLAG after PFX item may give wrong results in %s line %d"),
+			    fname, lnum);
+	    }
+	    else if (STRCMP(items[0], "COMPOUNDPERMITFLAG") == 0
+				   && itemcnt == 2 && aff->af_comppermit == 0)
+	    {
+		aff->af_comppermit = affitem2flag(aff->af_flagtype, items[1],
+								 fname, lnum);
+		if (aff->af_pref.ht_used > 0)
+		    smsg((char_u *)_("Defining COMPOUNDPERMITFLAG after PFX item may give wrong results in %s line %d"),
+			    fname, lnum);
+	    }
+	    else if (STRCMP(items[0], "COMPOUNDFLAG") == 0 && itemcnt == 2
+							 && compflags == NULL)
+	    {
+		/* Turn flag "c" into COMPOUNDRULE compatible string "c+",
+		 * "Na" into "Na+", "1234" into "1234+". */
+		p = getroom(spin, STRLEN(items[1]) + 2, FALSE);
+		if (p != NULL)
+		{
+		    STRCPY(p, items[1]);
+		    STRCAT(p, "+");
+		    compflags = p;
+		}
+	    }
+	    else if (STRCMP(items[0], "COMPOUNDRULE") == 0 && itemcnt == 2)
+	    {
+		/* Concatenate this string to previously defined ones, using a
+		 * slash to separate them. */
+		l = (int)STRLEN(items[1]) + 1;
+		if (compflags != NULL)
+		    l += (int)STRLEN(compflags) + 1;
+		p = getroom(spin, l, FALSE);
+		if (p != NULL)
+		{
+		    if (compflags != NULL)
+		    {
+			STRCPY(p, compflags);
+			STRCAT(p, "/");
+		    }
+		    STRCAT(p, items[1]);
+		    compflags = p;
+		}
+	    }
+	    else if (STRCMP(items[0], "COMPOUNDWORDMAX") == 0 && itemcnt == 2
+							      && compmax == 0)
+	    {
+		compmax = atoi((char *)items[1]);
+		if (compmax == 0)
+		    smsg((char_u *)_("Wrong COMPOUNDWORDMAX value in %s line %d: %s"),
+						       fname, lnum, items[1]);
+	    }
+	    else if (STRCMP(items[0], "COMPOUNDMIN") == 0 && itemcnt == 2
+							   && compminlen == 0)
+	    {
+		compminlen = atoi((char *)items[1]);
+		if (compminlen == 0)
+		    smsg((char_u *)_("Wrong COMPOUNDMIN value in %s line %d: %s"),
+						       fname, lnum, items[1]);
+	    }
+	    else if (STRCMP(items[0], "COMPOUNDSYLMAX") == 0 && itemcnt == 2
+							   && compsylmax == 0)
+	    {
+		compsylmax = atoi((char *)items[1]);
+		if (compsylmax == 0)
+		    smsg((char_u *)_("Wrong COMPOUNDSYLMAX value in %s line %d: %s"),
+						       fname, lnum, items[1]);
+	    }
+	    else if (STRCMP(items[0], "CHECKCOMPOUNDDUP") == 0 && itemcnt == 1)
+	    {
+		compoptions |= COMP_CHECKDUP;
+	    }
+	    else if (STRCMP(items[0], "CHECKCOMPOUNDREP") == 0 && itemcnt == 1)
+	    {
+		compoptions |= COMP_CHECKREP;
+	    }
+	    else if (STRCMP(items[0], "CHECKCOMPOUNDCASE") == 0 && itemcnt == 1)
+	    {
+		compoptions |= COMP_CHECKCASE;
+	    }
+	    else if (STRCMP(items[0], "CHECKCOMPOUNDTRIPLE") == 0
+							      && itemcnt == 1)
+	    {
+		compoptions |= COMP_CHECKTRIPLE;
+	    }
+	    else if (STRCMP(items[0], "CHECKCOMPOUNDPATTERN") == 0
+							      && itemcnt == 2)
+	    {
+		if (atoi((char *)items[1]) == 0)
+		    smsg((char_u *)_("Wrong CHECKCOMPOUNDPATTERN value in %s line %d: %s"),
+						       fname, lnum, items[1]);
+	    }
+	    else if (STRCMP(items[0], "CHECKCOMPOUNDPATTERN") == 0
+							      && itemcnt == 3)
+	    {
+		garray_T    *gap = &spin->si_comppat;
+		int	    i;
+
+		/* Only add the couple if it isn't already there. */
+		for (i = 0; i < gap->ga_len - 1; i += 2)
+		    if (STRCMP(((char_u **)(gap->ga_data))[i], items[1]) == 0
+			    && STRCMP(((char_u **)(gap->ga_data))[i + 1],
+							       items[2]) == 0)
+			break;
+		if (i >= gap->ga_len && ga_grow(gap, 2) == OK)
+		{
+		    ((char_u **)(gap->ga_data))[gap->ga_len++]
+					       = getroom_save(spin, items[1]);
+		    ((char_u **)(gap->ga_data))[gap->ga_len++]
+					       = getroom_save(spin, items[2]);
+		}
+	    }
+	    else if (STRCMP(items[0], "SYLLABLE") == 0 && itemcnt == 2
+							  && syllable == NULL)
+	    {
+		syllable = getroom_save(spin, items[1]);
+	    }
+	    else if (STRCMP(items[0], "NOBREAK") == 0 && itemcnt == 1)
+	    {
+		spin->si_nobreak = TRUE;
+	    }
+	    else if (STRCMP(items[0], "NOSPLITSUGS") == 0 && itemcnt == 1)
+	    {
+		spin->si_nosplitsugs = TRUE;
+	    }
+	    else if (STRCMP(items[0], "NOSUGFILE") == 0 && itemcnt == 1)
+	    {
+		spin->si_nosugfile = TRUE;
+	    }
+	    else if (STRCMP(items[0], "PFXPOSTPONE") == 0 && itemcnt == 1)
+	    {
+		aff->af_pfxpostpone = TRUE;
+	    }
+	    else if ((STRCMP(items[0], "PFX") == 0
+					      || STRCMP(items[0], "SFX") == 0)
+		    && aff_todo == 0
+		    && itemcnt >= 4)
+	    {
+		int	lasti = 4;
+		char_u	key[AH_KEY_LEN];
+
+		if (*items[0] == 'P')
+		    tp = &aff->af_pref;
+		else
+		    tp = &aff->af_suff;
+
+		/* Myspell allows the same affix name to be used multiple
+		 * times.  The affix files that do this have an undocumented
+		 * "S" flag on all but the last block, thus we check for that
+		 * and store it in ah_follows. */
+		vim_strncpy(key, items[1], AH_KEY_LEN - 1);
+		hi = hash_find(tp, key);
+		if (!HASHITEM_EMPTY(hi))
+		{
+		    cur_aff = HI2AH(hi);
+		    if (cur_aff->ah_combine != (*items[2] == 'Y'))
+			smsg((char_u *)_("Different combining flag in continued affix block in %s line %d: %s"),
+						   fname, lnum, items[1]);
+		    if (!cur_aff->ah_follows)
+			smsg((char_u *)_("Duplicate affix in %s line %d: %s"),
+						       fname, lnum, items[1]);
+		}
+		else
+		{
+		    /* New affix letter. */
+		    cur_aff = (affheader_T *)getroom(spin,
+						   sizeof(affheader_T), TRUE);
+		    if (cur_aff == NULL)
+			break;
+		    cur_aff->ah_flag = affitem2flag(aff->af_flagtype, items[1],
+								 fname, lnum);
+		    if (cur_aff->ah_flag == 0 || STRLEN(items[1]) >= AH_KEY_LEN)
+			break;
+		    if (cur_aff->ah_flag == aff->af_bad
+			    || cur_aff->ah_flag == aff->af_rare
+			    || cur_aff->ah_flag == aff->af_keepcase
+			    || cur_aff->ah_flag == aff->af_needaffix
+			    || cur_aff->ah_flag == aff->af_circumfix
+			    || cur_aff->ah_flag == aff->af_nosuggest
+			    || cur_aff->ah_flag == aff->af_needcomp
+			    || cur_aff->ah_flag == aff->af_comproot)
+			smsg((char_u *)_("Affix also used for BAD/RARE/KEEPCASE/NEEDAFFIX/NEEDCOMPOUND/NOSUGGEST in %s line %d: %s"),
+						       fname, lnum, items[1]);
+		    STRCPY(cur_aff->ah_key, items[1]);
+		    hash_add(tp, cur_aff->ah_key);
+
+		    cur_aff->ah_combine = (*items[2] == 'Y');
+		}
+
+		/* Check for the "S" flag, which apparently means that another
+		 * block with the same affix name is following. */
+		if (itemcnt > lasti && STRCMP(items[lasti], "S") == 0)
+		{
+		    ++lasti;
+		    cur_aff->ah_follows = TRUE;
+		}
+		else
+		    cur_aff->ah_follows = FALSE;
+
+		/* Myspell allows extra text after the item, but that might
+		 * mean mistakes go unnoticed.  Require a comment-starter. */
+		if (itemcnt > lasti && *items[lasti] != '#')
+		    smsg((char_u *)_(e_afftrailing), fname, lnum, items[lasti]);
+
+		if (STRCMP(items[2], "Y") != 0 && STRCMP(items[2], "N") != 0)
+		    smsg((char_u *)_("Expected Y or N in %s line %d: %s"),
+						       fname, lnum, items[2]);
+
+		if (*items[0] == 'P' && aff->af_pfxpostpone)
+		{
+		    if (cur_aff->ah_newID == 0)
+		    {
+			/* Use a new number in the .spl file later, to be able
+			 * to handle multiple .aff files. */
+			check_renumber(spin);
+			cur_aff->ah_newID = ++spin->si_newprefID;
+
+			/* We only really use ah_newID if the prefix is
+			 * postponed.  We know that only after handling all
+			 * the items. */
+			did_postpone_prefix = FALSE;
+		    }
+		    else
+			/* Did use the ID in a previous block. */
+			did_postpone_prefix = TRUE;
+		}
+
+		aff_todo = atoi((char *)items[3]);
+	    }
+	    else if ((STRCMP(items[0], "PFX") == 0
+					      || STRCMP(items[0], "SFX") == 0)
+		    && aff_todo > 0
+		    && STRCMP(cur_aff->ah_key, items[1]) == 0
+		    && itemcnt >= 5)
+	    {
+		affentry_T	*aff_entry;
+		int		upper = FALSE;
+		int		lasti = 5;
+
+		/* Myspell allows extra text after the item, but that might
+		 * mean mistakes go unnoticed.  Require a comment-starter.
+		 * Hunspell uses a "-" item. */
+		if (itemcnt > lasti && *items[lasti] != '#'
+			&& (STRCMP(items[lasti], "-") != 0
+						     || itemcnt != lasti + 1))
+		    smsg((char_u *)_(e_afftrailing), fname, lnum, items[lasti]);
+
+		/* New item for an affix letter. */
+		--aff_todo;
+		aff_entry = (affentry_T *)getroom(spin,
+						    sizeof(affentry_T), TRUE);
+		if (aff_entry == NULL)
+		    break;
+
+		if (STRCMP(items[2], "0") != 0)
+		    aff_entry->ae_chop = getroom_save(spin, items[2]);
+		if (STRCMP(items[3], "0") != 0)
+		{
+		    aff_entry->ae_add = getroom_save(spin, items[3]);
+
+		    /* Recognize flags on the affix: abcd/XYZ */
+		    aff_entry->ae_flags = vim_strchr(aff_entry->ae_add, '/');
+		    if (aff_entry->ae_flags != NULL)
+		    {
+			*aff_entry->ae_flags++ = NUL;
+			aff_process_flags(aff, aff_entry);
+		    }
+		}
+
+		/* Don't use an affix entry with non-ASCII characters when
+		 * "spin->si_ascii" is TRUE. */
+		if (!spin->si_ascii || !(has_non_ascii(aff_entry->ae_chop)
+					  || has_non_ascii(aff_entry->ae_add)))
+		{
+		    aff_entry->ae_next = cur_aff->ah_first;
+		    cur_aff->ah_first = aff_entry;
+
+		    if (STRCMP(items[4], ".") != 0)
+		    {
+			char_u	buf[MAXLINELEN];
+
+			aff_entry->ae_cond = getroom_save(spin, items[4]);
+			if (*items[0] == 'P')
+			    sprintf((char *)buf, "^%s", items[4]);
+			else
+			    sprintf((char *)buf, "%s$", items[4]);
+			aff_entry->ae_prog = vim_regcomp(buf,
+					    RE_MAGIC + RE_STRING + RE_STRICT);
+			if (aff_entry->ae_prog == NULL)
+			    smsg((char_u *)_("Broken condition in %s line %d: %s"),
+						       fname, lnum, items[4]);
+		    }
+
+		    /* For postponed prefixes we need an entry in si_prefcond
+		     * for the condition.  Use an existing one if possible.
+		     * Can't be done for an affix with flags, ignoring
+		     * COMPOUNDFORBIDFLAG and COMPOUNDPERMITFLAG. */
+		    if (*items[0] == 'P' && aff->af_pfxpostpone
+					       && aff_entry->ae_flags == NULL)
+		    {
+			/* When the chop string is one lower-case letter and
+			 * the add string ends in the upper-case letter we set
+			 * the "upper" flag, clear "ae_chop" and remove the
+			 * letters from "ae_add".  The condition must either
+			 * be empty or start with the same letter. */
+			if (aff_entry->ae_chop != NULL
+				&& aff_entry->ae_add != NULL
+#ifdef FEAT_MBYTE
+				&& aff_entry->ae_chop[(*mb_ptr2len)(
+						   aff_entry->ae_chop)] == NUL
+#else
+				&& aff_entry->ae_chop[1] == NUL
+#endif
+				)
+			{
+			    int		c, c_up;
+
+			    c = PTR2CHAR(aff_entry->ae_chop);
+			    c_up = SPELL_TOUPPER(c);
+			    if (c_up != c
+				    && (aff_entry->ae_cond == NULL
+					|| PTR2CHAR(aff_entry->ae_cond) == c))
+			    {
+				p = aff_entry->ae_add
+						  + STRLEN(aff_entry->ae_add);
+				mb_ptr_back(aff_entry->ae_add, p);
+				if (PTR2CHAR(p) == c_up)
+				{
+				    upper = TRUE;
+				    aff_entry->ae_chop = NULL;
+				    *p = NUL;
+
+				    /* The condition is matched with the
+				     * actual word, thus must check for the
+				     * upper-case letter. */
+				    if (aff_entry->ae_cond != NULL)
+				    {
+					char_u	buf[MAXLINELEN];
+#ifdef FEAT_MBYTE
+					if (has_mbyte)
+					{
+					    onecap_copy(items[4], buf, TRUE);
+					    aff_entry->ae_cond = getroom_save(
+								   spin, buf);
+					}
+					else
+#endif
+					    *aff_entry->ae_cond = c_up;
+					if (aff_entry->ae_cond != NULL)
+					{
+					    sprintf((char *)buf, "^%s",
+							  aff_entry->ae_cond);
+					    vim_free(aff_entry->ae_prog);
+					    aff_entry->ae_prog = vim_regcomp(
+						    buf, RE_MAGIC + RE_STRING);
+					}
+				    }
+				}
+			    }
+			}
+
+			if (aff_entry->ae_chop == NULL
+					       && aff_entry->ae_flags == NULL)
+			{
+			    int		idx;
+			    char_u	**pp;
+			    int		n;
+
+			    /* Find a previously used condition. */
+			    for (idx = spin->si_prefcond.ga_len - 1; idx >= 0;
+									--idx)
+			    {
+				p = ((char_u **)spin->si_prefcond.ga_data)[idx];
+				if (str_equal(p, aff_entry->ae_cond))
+				    break;
+			    }
+			    if (idx < 0 && ga_grow(&spin->si_prefcond, 1) == OK)
+			    {
+				/* Not found, add a new condition. */
+				idx = spin->si_prefcond.ga_len++;
+				pp = ((char_u **)spin->si_prefcond.ga_data)
+									+ idx;
+				if (aff_entry->ae_cond == NULL)
+				    *pp = NULL;
+				else
+				    *pp = getroom_save(spin,
+							  aff_entry->ae_cond);
+			    }
+
+			    /* Add the prefix to the prefix tree. */
+			    if (aff_entry->ae_add == NULL)
+				p = (char_u *)"";
+			    else
+				p = aff_entry->ae_add;
+
+			    /* PFX_FLAGS is a negative number, so that
+			     * tree_add_word() knows this is the prefix tree. */
+			    n = PFX_FLAGS;
+			    if (!cur_aff->ah_combine)
+				n |= WFP_NC;
+			    if (upper)
+				n |= WFP_UP;
+			    if (aff_entry->ae_comppermit)
+				n |= WFP_COMPPERMIT;
+			    if (aff_entry->ae_compforbid)
+				n |= WFP_COMPFORBID;
+			    tree_add_word(spin, p, spin->si_prefroot, n,
+						      idx, cur_aff->ah_newID);
+			    did_postpone_prefix = TRUE;
+			}
+
+			/* Didn't actually use ah_newID, backup si_newprefID. */
+			if (aff_todo == 0 && !did_postpone_prefix)
+			{
+			    --spin->si_newprefID;
+			    cur_aff->ah_newID = 0;
+			}
+		    }
+		}
+	    }
+	    else if (STRCMP(items[0], "FOL") == 0 && itemcnt == 2
+							       && fol == NULL)
+	    {
+		fol = vim_strsave(items[1]);
+	    }
+	    else if (STRCMP(items[0], "LOW") == 0 && itemcnt == 2
+							       && low == NULL)
+	    {
+		low = vim_strsave(items[1]);
+	    }
+	    else if (STRCMP(items[0], "UPP") == 0 && itemcnt == 2
+							       && upp == NULL)
+	    {
+		upp = vim_strsave(items[1]);
+	    }
+	    else if ((STRCMP(items[0], "REP") == 0
+			|| STRCMP(items[0], "REPSAL") == 0)
+		    && itemcnt == 2)
+	    {
+		/* Ignore REP/REPSAL count */;
+		if (!isdigit(*items[1]))
+		    smsg((char_u *)_("Expected REP(SAL) count in %s line %d"),
+								 fname, lnum);
+	    }
+	    else if ((STRCMP(items[0], "REP") == 0
+			|| STRCMP(items[0], "REPSAL") == 0)
+		    && itemcnt >= 3)
+	    {
+		/* REP/REPSAL item */
+		/* Myspell ignores extra arguments, we require it starts with
+		 * # to detect mistakes. */
+		if (itemcnt > 3 && items[3][0] != '#')
+		    smsg((char_u *)_(e_afftrailing), fname, lnum, items[3]);
+		if (items[0][3] == 'S' ? do_repsal : do_rep)
+		{
+		    /* Replace underscore with space (can't include a space
+		     * directly). */
+		    for (p = items[1]; *p != NUL; mb_ptr_adv(p))
+			if (*p == '_')
+			    *p = ' ';
+		    for (p = items[2]; *p != NUL; mb_ptr_adv(p))
+			if (*p == '_')
+			    *p = ' ';
+		    add_fromto(spin, items[0][3] == 'S'
+					 ? &spin->si_repsal
+					 : &spin->si_rep, items[1], items[2]);
+		}
+	    }
+	    else if (STRCMP(items[0], "MAP") == 0 && itemcnt == 2)
+	    {
+		/* MAP item or count */
+		if (!found_map)
+		{
+		    /* First line contains the count. */
+		    found_map = TRUE;
+		    if (!isdigit(*items[1]))
+			smsg((char_u *)_("Expected MAP count in %s line %d"),
+								 fname, lnum);
+		}
+		else if (do_mapline)
+		{
+		    int		c;
+
+		    /* Check that every character appears only once. */
+		    for (p = items[1]; *p != NUL; )
+		    {
+#ifdef FEAT_MBYTE
+			c = mb_ptr2char_adv(&p);
+#else
+			c = *p++;
+#endif
+			if ((spin->si_map.ga_len > 0
+				    && vim_strchr(spin->si_map.ga_data, c)
+								      != NULL)
+				|| vim_strchr(p, c) != NULL)
+			    smsg((char_u *)_("Duplicate character in MAP in %s line %d"),
+								 fname, lnum);
+		    }
+
+		    /* We simply concatenate all the MAP strings, separated by
+		     * slashes. */
+		    ga_concat(&spin->si_map, items[1]);
+		    ga_append(&spin->si_map, '/');
+		}
+	    }
+	    /* Accept "SAL from to" and "SAL from to # comment". */
+	    else if (STRCMP(items[0], "SAL") == 0
+		    && (itemcnt == 3 || (itemcnt > 3 && items[3][0] == '#')))
+	    {
+		if (do_sal)
+		{
+		    /* SAL item (sounds-a-like)
+		     * Either one of the known keys or a from-to pair. */
+		    if (STRCMP(items[1], "followup") == 0)
+			spin->si_followup = sal_to_bool(items[2]);
+		    else if (STRCMP(items[1], "collapse_result") == 0)
+			spin->si_collapse = sal_to_bool(items[2]);
+		    else if (STRCMP(items[1], "remove_accents") == 0)
+			spin->si_rem_accents = sal_to_bool(items[2]);
+		    else
+			/* when "to" is "_" it means empty */
+			add_fromto(spin, &spin->si_sal, items[1],
+				     STRCMP(items[2], "_") == 0 ? (char_u *)""
+								: items[2]);
+		}
+	    }
+	    else if (STRCMP(items[0], "SOFOFROM") == 0 && itemcnt == 2
+							  && sofofrom == NULL)
+	    {
+		sofofrom = getroom_save(spin, items[1]);
+	    }
+	    else if (STRCMP(items[0], "SOFOTO") == 0 && itemcnt == 2
+							    && sofoto == NULL)
+	    {
+		sofoto = getroom_save(spin, items[1]);
+	    }
+	    else if (STRCMP(items[0], "COMMON") == 0)
+	    {
+		int	i;
+
+		for (i = 1; i < itemcnt; ++i)
+		{
+		    if (HASHITEM_EMPTY(hash_find(&spin->si_commonwords,
+								   items[i])))
+		    {
+			p = vim_strsave(items[i]);
+			if (p == NULL)
+			    break;
+			hash_add(&spin->si_commonwords, p);
+		    }
+		}
+	    }
+	    else
+		smsg((char_u *)_("Unrecognized or duplicate item in %s line %d: %s"),
+						       fname, lnum, items[0]);
+	}
+    }
+
+    if (fol != NULL || low != NULL || upp != NULL)
+    {
+	if (spin->si_clear_chartab)
+	{
+	    /* Clear the char type tables, don't want to use any of the
+	     * currently used spell properties. */
+	    init_spell_chartab();
+	    spin->si_clear_chartab = FALSE;
+	}
+
+	/*
+	 * Don't write a word table for an ASCII file, so that we don't check
+	 * for conflicts with a word table that matches 'encoding'.
+	 * Don't write one for utf-8 either, we use utf_*() and
+	 * mb_get_class(), the list of chars in the file will be incomplete.
+	 */
+	if (!spin->si_ascii
+#ifdef FEAT_MBYTE
+		&& !enc_utf8
+#endif
+		)
+	{
+	    if (fol == NULL || low == NULL || upp == NULL)
+		smsg((char_u *)_("Missing FOL/LOW/UPP line in %s"), fname);
+	    else
+		(void)set_spell_chartab(fol, low, upp);
+	}
+
+	vim_free(fol);
+	vim_free(low);
+	vim_free(upp);
+    }
+
+    /* Use compound specifications of the .aff file for the spell info. */
+    if (compmax != 0)
+    {
+	aff_check_number(spin->si_compmax, compmax, "COMPOUNDWORDMAX");
+	spin->si_compmax = compmax;
+    }
+
+    if (compminlen != 0)
+    {
+	aff_check_number(spin->si_compminlen, compminlen, "COMPOUNDMIN");
+	spin->si_compminlen = compminlen;
+    }
+
+    if (compsylmax != 0)
+    {
+	if (syllable == NULL)
+	    smsg((char_u *)_("COMPOUNDSYLMAX used without SYLLABLE"));
+	aff_check_number(spin->si_compsylmax, compsylmax, "COMPOUNDSYLMAX");
+	spin->si_compsylmax = compsylmax;
+    }
+
+    if (compoptions != 0)
+    {
+	aff_check_number(spin->si_compoptions, compoptions, "COMPOUND options");
+	spin->si_compoptions |= compoptions;
+    }
+
+    if (compflags != NULL)
+	process_compflags(spin, aff, compflags);
+
+    /* Check that we didn't use too many renumbered flags. */
+    if (spin->si_newcompID < spin->si_newprefID)
+    {
+	if (spin->si_newcompID == 127 || spin->si_newcompID == 255)
+	    MSG(_("Too many postponed prefixes"));
+	else if (spin->si_newprefID == 0 || spin->si_newprefID == 127)
+	    MSG(_("Too many compound flags"));
+	else
+	    MSG(_("Too many posponed prefixes and/or compound flags"));
+    }
+
+    if (syllable != NULL)
+    {
+	aff_check_string(spin->si_syllable, syllable, "SYLLABLE");
+	spin->si_syllable = syllable;
+    }
+
+    if (sofofrom != NULL || sofoto != NULL)
+    {
+	if (sofofrom == NULL || sofoto == NULL)
+	    smsg((char_u *)_("Missing SOFO%s line in %s"),
+				     sofofrom == NULL ? "FROM" : "TO", fname);
+	else if (spin->si_sal.ga_len > 0)
+	    smsg((char_u *)_("Both SAL and SOFO lines in %s"), fname);
+	else
+	{
+	    aff_check_string(spin->si_sofofr, sofofrom, "SOFOFROM");
+	    aff_check_string(spin->si_sofoto, sofoto, "SOFOTO");
+	    spin->si_sofofr = sofofrom;
+	    spin->si_sofoto = sofoto;
+	}
+    }
+
+    if (midword != NULL)
+    {
+	aff_check_string(spin->si_midword, midword, "MIDWORD");
+	spin->si_midword = midword;
+    }
+
+    vim_free(pc);
+    fclose(fd);
+    return aff;
+}
+
+/*
+ * For affix "entry" move COMPOUNDFORBIDFLAG and COMPOUNDPERMITFLAG from
+ * ae_flags to ae_comppermit and ae_compforbid.
+ */
+    static void
+aff_process_flags(affile, entry)
+    afffile_T	*affile;
+    affentry_T	*entry;
+{
+    char_u	*p;
+    char_u	*prevp;
+    unsigned	flag;
+
+    if (entry->ae_flags != NULL
+		&& (affile->af_compforbid != 0 || affile->af_comppermit != 0))
+    {
+	for (p = entry->ae_flags; *p != NUL; )
+	{
+	    prevp = p;
+	    flag = get_affitem(affile->af_flagtype, &p);
+	    if (flag == affile->af_comppermit || flag == affile->af_compforbid)
+	    {
+		mch_memmove(prevp, p, STRLEN(p) + 1);
+		p = prevp;
+		if (flag == affile->af_comppermit)
+		    entry->ae_comppermit = TRUE;
+		else
+		    entry->ae_compforbid = TRUE;
+	    }
+	    if (affile->af_flagtype == AFT_NUM && *p == ',')
+		++p;
+	}
+	if (*entry->ae_flags == NUL)
+	    entry->ae_flags = NULL;	/* nothing left */
+    }
+}
+
+/*
+ * Return TRUE if "s" is the name of an info item in the affix file.
+ */
+    static int
+spell_info_item(s)
+    char_u	*s;
+{
+    return STRCMP(s, "NAME") == 0
+	|| STRCMP(s, "HOME") == 0
+	|| STRCMP(s, "VERSION") == 0
+	|| STRCMP(s, "AUTHOR") == 0
+	|| STRCMP(s, "EMAIL") == 0
+	|| STRCMP(s, "COPYRIGHT") == 0;
+}
+
+/*
+ * Turn an affix flag name into a number, according to the FLAG type.
+ * returns zero for failure.
+ */
+    static unsigned
+affitem2flag(flagtype, item, fname, lnum)
+    int		flagtype;
+    char_u	*item;
+    char_u	*fname;
+    int		lnum;
+{
+    unsigned	res;
+    char_u	*p = item;
+
+    res = get_affitem(flagtype, &p);
+    if (res == 0)
+    {
+	if (flagtype == AFT_NUM)
+	    smsg((char_u *)_("Flag is not a number in %s line %d: %s"),
+							   fname, lnum, item);
+	else
+	    smsg((char_u *)_("Illegal flag in %s line %d: %s"),
+							   fname, lnum, item);
+    }
+    if (*p != NUL)
+    {
+	smsg((char_u *)_(e_affname), fname, lnum, item);
+	return 0;
+    }
+
+    return res;
+}
+
+/*
+ * Get one affix name from "*pp" and advance the pointer.
+ * Returns zero for an error, still advances the pointer then.
+ */
+    static unsigned
+get_affitem(flagtype, pp)
+    int		flagtype;
+    char_u	**pp;
+{
+    int		res;
+
+    if (flagtype == AFT_NUM)
+    {
+	if (!VIM_ISDIGIT(**pp))
+	{
+	    ++*pp;	/* always advance, avoid getting stuck */
+	    return 0;
+	}
+	res = getdigits(pp);
+    }
+    else
+    {
+#ifdef FEAT_MBYTE
+	res = mb_ptr2char_adv(pp);
+#else
+	res = *(*pp)++;
+#endif
+	if (flagtype == AFT_LONG || (flagtype == AFT_CAPLONG
+						 && res >= 'A' && res <= 'Z'))
+	{
+	    if (**pp == NUL)
+		return 0;
+#ifdef FEAT_MBYTE
+	    res = mb_ptr2char_adv(pp) + (res << 16);
+#else
+	    res = *(*pp)++ + (res << 16);
+#endif
+	}
+    }
+    return res;
+}
+
+/*
+ * Process the "compflags" string used in an affix file and append it to
+ * spin->si_compflags.
+ * The processing involves changing the affix names to ID numbers, so that
+ * they fit in one byte.
+ */
+    static void
+process_compflags(spin, aff, compflags)
+    spellinfo_T	*spin;
+    afffile_T	*aff;
+    char_u	*compflags;
+{
+    char_u	*p;
+    char_u	*prevp;
+    unsigned	flag;
+    compitem_T	*ci;
+    int		id;
+    int		len;
+    char_u	*tp;
+    char_u	key[AH_KEY_LEN];
+    hashitem_T	*hi;
+
+    /* Make room for the old and the new compflags, concatenated with a / in
+     * between.  Processing it makes it shorter, but we don't know by how
+     * much, thus allocate the maximum. */
+    len = (int)STRLEN(compflags) + 1;
+    if (spin->si_compflags != NULL)
+	len += (int)STRLEN(spin->si_compflags) + 1;
+    p = getroom(spin, len, FALSE);
+    if (p == NULL)
+	return;
+    if (spin->si_compflags != NULL)
+    {
+	STRCPY(p, spin->si_compflags);
+	STRCAT(p, "/");
+    }
+    spin->si_compflags = p;
+    tp = p + STRLEN(p);
+
+    for (p = compflags; *p != NUL; )
+    {
+	if (vim_strchr((char_u *)"/*+[]", *p) != NULL)
+	    /* Copy non-flag characters directly. */
+	    *tp++ = *p++;
+	else
+	{
+	    /* First get the flag number, also checks validity. */
+	    prevp = p;
+	    flag = get_affitem(aff->af_flagtype, &p);
+	    if (flag != 0)
+	    {
+		/* Find the flag in the hashtable.  If it was used before, use
+		 * the existing ID.  Otherwise add a new entry. */
+		vim_strncpy(key, prevp, p - prevp);
+		hi = hash_find(&aff->af_comp, key);
+		if (!HASHITEM_EMPTY(hi))
+		    id = HI2CI(hi)->ci_newID;
+		else
+		{
+		    ci = (compitem_T *)getroom(spin, sizeof(compitem_T), TRUE);
+		    if (ci == NULL)
+			break;
+		    STRCPY(ci->ci_key, key);
+		    ci->ci_flag = flag;
+		    /* Avoid using a flag ID that has a special meaning in a
+		     * regexp (also inside []). */
+		    do
+		    {
+			check_renumber(spin);
+			id = spin->si_newcompID--;
+		    } while (vim_strchr((char_u *)"/+*[]\\-^", id) != NULL);
+		    ci->ci_newID = id;
+		    hash_add(&aff->af_comp, ci->ci_key);
+		}
+		*tp++ = id;
+	    }
+	    if (aff->af_flagtype == AFT_NUM && *p == ',')
+		++p;
+	}
+    }
+
+    *tp = NUL;
+}
+
+/*
+ * Check that the new IDs for postponed affixes and compounding don't overrun
+ * each other.  We have almost 255 available, but start at 0-127 to avoid
+ * using two bytes for utf-8.  When the 0-127 range is used up go to 128-255.
+ * When that is used up an error message is given.
+ */
+    static void
+check_renumber(spin)
+    spellinfo_T	*spin;
+{
+    if (spin->si_newprefID == spin->si_newcompID && spin->si_newcompID < 128)
+    {
+	spin->si_newprefID = 127;
+	spin->si_newcompID = 255;
+    }
+}
+
+/*
+ * Return TRUE if flag "flag" appears in affix list "afflist".
+ */
+    static int
+flag_in_afflist(flagtype, afflist, flag)
+    int		flagtype;
+    char_u	*afflist;
+    unsigned	flag;
+{
+    char_u	*p;
+    unsigned	n;
+
+    switch (flagtype)
+    {
+	case AFT_CHAR:
+	    return vim_strchr(afflist, flag) != NULL;
+
+	case AFT_CAPLONG:
+	case AFT_LONG:
+	    for (p = afflist; *p != NUL; )
+	    {
+#ifdef FEAT_MBYTE
+		n = mb_ptr2char_adv(&p);
+#else
+		n = *p++;
+#endif
+		if ((flagtype == AFT_LONG || (n >= 'A' && n <= 'Z'))
+								 && *p != NUL)
+#ifdef FEAT_MBYTE
+		    n = mb_ptr2char_adv(&p) + (n << 16);
+#else
+		    n = *p++ + (n << 16);
+#endif
+		if (n == flag)
+		    return TRUE;
+	    }
+	    break;
+
+	case AFT_NUM:
+	    for (p = afflist; *p != NUL; )
+	    {
+		n = getdigits(&p);
+		if (n == flag)
+		    return TRUE;
+		if (*p != NUL)	/* skip over comma */
+		    ++p;
+	    }
+	    break;
+    }
+    return FALSE;
+}
+
+/*
+ * Give a warning when "spinval" and "affval" numbers are set and not the same.
+ */
+    static void
+aff_check_number(spinval, affval, name)
+    int	    spinval;
+    int	    affval;
+    char    *name;
+{
+    if (spinval != 0 && spinval != affval)
+	smsg((char_u *)_("%s value differs from what is used in another .aff file"), name);
+}
+
+/*
+ * Give a warning when "spinval" and "affval" strings are set and not the same.
+ */
+    static void
+aff_check_string(spinval, affval, name)
+    char_u	*spinval;
+    char_u	*affval;
+    char	*name;
+{
+    if (spinval != NULL && STRCMP(spinval, affval) != 0)
+	smsg((char_u *)_("%s value differs from what is used in another .aff file"), name);
+}
+
+/*
+ * Return TRUE if strings "s1" and "s2" are equal.  Also consider both being
+ * NULL as equal.
+ */
+    static int
+str_equal(s1, s2)
+    char_u	*s1;
+    char_u	*s2;
+{
+    if (s1 == NULL || s2 == NULL)
+	return s1 == s2;
+    return STRCMP(s1, s2) == 0;
+}
+
+/*
+ * Add a from-to item to "gap".  Used for REP and SAL items.
+ * They are stored case-folded.
+ */
+    static void
+add_fromto(spin, gap, from, to)
+    spellinfo_T	*spin;
+    garray_T	*gap;
+    char_u	*from;
+    char_u	*to;
+{
+    fromto_T	*ftp;
+    char_u	word[MAXWLEN];
+
+    if (ga_grow(gap, 1) == OK)
+    {
+	ftp = ((fromto_T *)gap->ga_data) + gap->ga_len;
+	(void)spell_casefold(from, (int)STRLEN(from), word, MAXWLEN);
+	ftp->ft_from = getroom_save(spin, word);
+	(void)spell_casefold(to, (int)STRLEN(to), word, MAXWLEN);
+	ftp->ft_to = getroom_save(spin, word);
+	++gap->ga_len;
+    }
+}
+
+/*
+ * Convert a boolean argument in a SAL line to TRUE or FALSE;
+ */
+    static int
+sal_to_bool(s)
+    char_u	*s;
+{
+    return STRCMP(s, "1") == 0 || STRCMP(s, "true") == 0;
+}
+
+/*
+ * Return TRUE if string "s" contains a non-ASCII character (128 or higher).
+ * When "s" is NULL FALSE is returned.
+ */
+    static int
+has_non_ascii(s)
+    char_u	*s;
+{
+    char_u	*p;
+
+    if (s != NULL)
+	for (p = s; *p != NUL; ++p)
+	    if (*p >= 128)
+		return TRUE;
+    return FALSE;
+}
+
+/*
+ * Free the structure filled by spell_read_aff().
+ */
+    static void
+spell_free_aff(aff)
+    afffile_T	*aff;
+{
+    hashtab_T	*ht;
+    hashitem_T	*hi;
+    int		todo;
+    affheader_T	*ah;
+    affentry_T	*ae;
+
+    vim_free(aff->af_enc);
+
+    /* All this trouble to free the "ae_prog" items... */
+    for (ht = &aff->af_pref; ; ht = &aff->af_suff)
+    {
+	todo = (int)ht->ht_used;
+	for (hi = ht->ht_array; todo > 0; ++hi)
+	{
+	    if (!HASHITEM_EMPTY(hi))
+	    {
+		--todo;
+		ah = HI2AH(hi);
+		for (ae = ah->ah_first; ae != NULL; ae = ae->ae_next)
+		    vim_free(ae->ae_prog);
+	    }
+	}
+	if (ht == &aff->af_suff)
+	    break;
+    }
+
+    hash_clear(&aff->af_pref);
+    hash_clear(&aff->af_suff);
+    hash_clear(&aff->af_comp);
+}
+
+/*
+ * Read dictionary file "fname".
+ * Returns OK or FAIL;
+ */
+    static int
+spell_read_dic(spin, fname, affile)
+    spellinfo_T	*spin;
+    char_u	*fname;
+    afffile_T	*affile;
+{
+    hashtab_T	ht;
+    char_u	line[MAXLINELEN];
+    char_u	*p;
+    char_u	*afflist;
+    char_u	store_afflist[MAXWLEN];
+    int		pfxlen;
+    int		need_affix;
+    char_u	*dw;
+    char_u	*pc;
+    char_u	*w;
+    int		l;
+    hash_T	hash;
+    hashitem_T	*hi;
+    FILE	*fd;
+    int		lnum = 1;
+    int		non_ascii = 0;
+    int		retval = OK;
+    char_u	message[MAXLINELEN + MAXWLEN];
+    int		flags;
+    int		duplicate = 0;
+
+    /*
+     * Open the file.
+     */
+    fd = mch_fopen((char *)fname, "r");
+    if (fd == NULL)
+    {
+	EMSG2(_(e_notopen), fname);
+	return FAIL;
+    }
+
+    /* The hashtable is only used to detect duplicated words. */
+    hash_init(&ht);
+
+    vim_snprintf((char *)IObuff, IOSIZE,
+				  _("Reading dictionary file %s ..."), fname);
+    spell_message(spin, IObuff);
+
+    /* start with a message for the first line */
+    spin->si_msg_count = 999999;
+
+    /* Read and ignore the first line: word count. */
+    (void)vim_fgets(line, MAXLINELEN, fd);
+    if (!vim_isdigit(*skipwhite(line)))
+	EMSG2(_("E760: No word count in %s"), fname);
+
+    /*
+     * Read all the lines in the file one by one.
+     * The words are converted to 'encoding' here, before being added to
+     * the hashtable.
+     */
+    while (!vim_fgets(line, MAXLINELEN, fd) && !got_int)
+    {
+	line_breakcheck();
+	++lnum;
+	if (line[0] == '#' || line[0] == '/')
+	    continue;	/* comment line */
+
+	/* Remove CR, LF and white space from the end.  White space halfway
+	 * the word is kept to allow e.g., "et al.". */
+	l = (int)STRLEN(line);
+	while (l > 0 && line[l - 1] <= ' ')
+	    --l;
+	if (l == 0)
+	    continue;	/* empty line */
+	line[l] = NUL;
+
+#ifdef FEAT_MBYTE
+	/* Convert from "SET" to 'encoding' when needed. */
+	if (spin->si_conv.vc_type != CONV_NONE)
+	{
+	    pc = string_convert(&spin->si_conv, line, NULL);
+	    if (pc == NULL)
+	    {
+		smsg((char_u *)_("Conversion failure for word in %s line %d: %s"),
+						       fname, lnum, line);
+		continue;
+	    }
+	    w = pc;
+	}
+	else
+#endif
+	{
+	    pc = NULL;
+	    w = line;
+	}
+
+	/* Truncate the word at the "/", set "afflist" to what follows.
+	 * Replace "\/" by "/" and "\\" by "\". */
+	afflist = NULL;
+	for (p = w; *p != NUL; mb_ptr_adv(p))
+	{
+	    if (*p == '\\' && (p[1] == '\\' || p[1] == '/'))
+		mch_memmove(p, p + 1, STRLEN(p));
+	    else if (*p == '/')
+	    {
+		*p = NUL;
+		afflist = p + 1;
+		break;
+	    }
+	}
+
+	/* Skip non-ASCII words when "spin->si_ascii" is TRUE. */
+	if (spin->si_ascii && has_non_ascii(w))
+	{
+	    ++non_ascii;
+	    vim_free(pc);
+	    continue;
+	}
+
+	/* This takes time, print a message every 10000 words. */
+	if (spin->si_verbose && spin->si_msg_count > 10000)
+	{
+	    spin->si_msg_count = 0;
+	    vim_snprintf((char *)message, sizeof(message),
+		    _("line %6d, word %6d - %s"),
+		       lnum, spin->si_foldwcount + spin->si_keepwcount, w);
+	    msg_start();
+	    msg_puts_long_attr(message, 0);
+	    msg_clr_eos();
+	    msg_didout = FALSE;
+	    msg_col = 0;
+	    out_flush();
+	}
+
+	/* Store the word in the hashtable to be able to find duplicates. */
+	dw = (char_u *)getroom_save(spin, w);
+	if (dw == NULL)
+	{
+	    retval = FAIL;
+	    vim_free(pc);
+	    break;
+	}
+
+	hash = hash_hash(dw);
+	hi = hash_lookup(&ht, dw, hash);
+	if (!HASHITEM_EMPTY(hi))
+	{
+	    if (p_verbose > 0)
+		smsg((char_u *)_("Duplicate word in %s line %d: %s"),
+							     fname, lnum, dw);
+	    else if (duplicate == 0)
+		smsg((char_u *)_("First duplicate word in %s line %d: %s"),
+							     fname, lnum, dw);
+	    ++duplicate;
+	}
+	else
+	    hash_add_item(&ht, hi, dw, hash);
+
+	flags = 0;
+	store_afflist[0] = NUL;
+	pfxlen = 0;
+	need_affix = FALSE;
+	if (afflist != NULL)
+	{
+	    /* Extract flags from the affix list. */
+	    flags |= get_affix_flags(affile, afflist);
+
+	    if (affile->af_needaffix != 0 && flag_in_afflist(
+			  affile->af_flagtype, afflist, affile->af_needaffix))
+		need_affix = TRUE;
+
+	    if (affile->af_pfxpostpone)
+		/* Need to store the list of prefix IDs with the word. */
+		pfxlen = get_pfxlist(affile, afflist, store_afflist);
+
+	    if (spin->si_compflags != NULL)
+		/* Need to store the list of compound flags with the word.
+		 * Concatenate them to the list of prefix IDs. */
+		get_compflags(affile, afflist, store_afflist + pfxlen);
+	}
+
+	/* Add the word to the word tree(s). */
+	if (store_word(spin, dw, flags, spin->si_region,
+					   store_afflist, need_affix) == FAIL)
+	    retval = FAIL;
+
+	if (afflist != NULL)
+	{
+	    /* Find all matching suffixes and add the resulting words.
+	     * Additionally do matching prefixes that combine. */
+	    if (store_aff_word(spin, dw, afflist, affile,
+			   &affile->af_suff, &affile->af_pref,
+			    CONDIT_SUF, flags, store_afflist, pfxlen) == FAIL)
+		retval = FAIL;
+
+	    /* Find all matching prefixes and add the resulting words. */
+	    if (store_aff_word(spin, dw, afflist, affile,
+			  &affile->af_pref, NULL,
+			    CONDIT_SUF, flags, store_afflist, pfxlen) == FAIL)
+		retval = FAIL;
+	}
+
+	vim_free(pc);
+    }
+
+    if (duplicate > 0)
+	smsg((char_u *)_("%d duplicate word(s) in %s"), duplicate, fname);
+    if (spin->si_ascii && non_ascii > 0)
+	smsg((char_u *)_("Ignored %d word(s) with non-ASCII characters in %s"),
+							    non_ascii, fname);
+    hash_clear(&ht);
+
+    fclose(fd);
+    return retval;
+}
+
+/*
+ * Check for affix flags in "afflist" that are turned into word flags.
+ * Return WF_ flags.
+ */
+    static int
+get_affix_flags(affile, afflist)
+    afffile_T	*affile;
+    char_u	*afflist;
+{
+    int		flags = 0;
+
+    if (affile->af_keepcase != 0 && flag_in_afflist(
+			   affile->af_flagtype, afflist, affile->af_keepcase))
+	flags |= WF_KEEPCAP | WF_FIXCAP;
+    if (affile->af_rare != 0 && flag_in_afflist(
+			       affile->af_flagtype, afflist, affile->af_rare))
+	flags |= WF_RARE;
+    if (affile->af_bad != 0 && flag_in_afflist(
+				affile->af_flagtype, afflist, affile->af_bad))
+	flags |= WF_BANNED;
+    if (affile->af_needcomp != 0 && flag_in_afflist(
+			   affile->af_flagtype, afflist, affile->af_needcomp))
+	flags |= WF_NEEDCOMP;
+    if (affile->af_comproot != 0 && flag_in_afflist(
+			   affile->af_flagtype, afflist, affile->af_comproot))
+	flags |= WF_COMPROOT;
+    if (affile->af_nosuggest != 0 && flag_in_afflist(
+			  affile->af_flagtype, afflist, affile->af_nosuggest))
+	flags |= WF_NOSUGGEST;
+    return flags;
+}
+
+/*
+ * Get the list of prefix IDs from the affix list "afflist".
+ * Used for PFXPOSTPONE.
+ * Put the resulting flags in "store_afflist[MAXWLEN]" with a terminating NUL
+ * and return the number of affixes.
+ */
+    static int
+get_pfxlist(affile, afflist, store_afflist)
+    afffile_T	*affile;
+    char_u	*afflist;
+    char_u	*store_afflist;
+{
+    char_u	*p;
+    char_u	*prevp;
+    int		cnt = 0;
+    int		id;
+    char_u	key[AH_KEY_LEN];
+    hashitem_T	*hi;
+
+    for (p = afflist; *p != NUL; )
+    {
+	prevp = p;
+	if (get_affitem(affile->af_flagtype, &p) != 0)
+	{
+	    /* A flag is a postponed prefix flag if it appears in "af_pref"
+	     * and it's ID is not zero. */
+	    vim_strncpy(key, prevp, p - prevp);
+	    hi = hash_find(&affile->af_pref, key);
+	    if (!HASHITEM_EMPTY(hi))
+	    {
+		id = HI2AH(hi)->ah_newID;
+		if (id != 0)
+		    store_afflist[cnt++] = id;
+	    }
+	}
+	if (affile->af_flagtype == AFT_NUM && *p == ',')
+	    ++p;
+    }
+
+    store_afflist[cnt] = NUL;
+    return cnt;
+}
+
+/*
+ * Get the list of compound IDs from the affix list "afflist" that are used
+ * for compound words.
+ * Puts the flags in "store_afflist[]".
+ */
+    static void
+get_compflags(affile, afflist, store_afflist)
+    afffile_T	*affile;
+    char_u	*afflist;
+    char_u	*store_afflist;
+{
+    char_u	*p;
+    char_u	*prevp;
+    int		cnt = 0;
+    char_u	key[AH_KEY_LEN];
+    hashitem_T	*hi;
+
+    for (p = afflist; *p != NUL; )
+    {
+	prevp = p;
+	if (get_affitem(affile->af_flagtype, &p) != 0)
+	{
+	    /* A flag is a compound flag if it appears in "af_comp". */
+	    vim_strncpy(key, prevp, p - prevp);
+	    hi = hash_find(&affile->af_comp, key);
+	    if (!HASHITEM_EMPTY(hi))
+		store_afflist[cnt++] = HI2CI(hi)->ci_newID;
+	}
+	if (affile->af_flagtype == AFT_NUM && *p == ',')
+	    ++p;
+    }
+
+    store_afflist[cnt] = NUL;
+}
+
+/*
+ * Apply affixes to a word and store the resulting words.
+ * "ht" is the hashtable with affentry_T that need to be applied, either
+ * prefixes or suffixes.
+ * "xht", when not NULL, is the prefix hashtable, to be used additionally on
+ * the resulting words for combining affixes.
+ *
+ * Returns FAIL when out of memory.
+ */
+    static int
+store_aff_word(spin, word, afflist, affile, ht, xht, condit, flags,
+							      pfxlist, pfxlen)
+    spellinfo_T	*spin;		/* spell info */
+    char_u	*word;		/* basic word start */
+    char_u	*afflist;	/* list of names of supported affixes */
+    afffile_T	*affile;
+    hashtab_T	*ht;
+    hashtab_T	*xht;
+    int		condit;		/* CONDIT_SUF et al. */
+    int		flags;		/* flags for the word */
+    char_u	*pfxlist;	/* list of prefix IDs */
+    int		pfxlen;		/* nr of flags in "pfxlist" for prefixes, rest
+				 * is compound flags */
+{
+    int		todo;
+    hashitem_T	*hi;
+    affheader_T	*ah;
+    affentry_T	*ae;
+    regmatch_T	regmatch;
+    char_u	newword[MAXWLEN];
+    int		retval = OK;
+    int		i, j;
+    char_u	*p;
+    int		use_flags;
+    char_u	*use_pfxlist;
+    int		use_pfxlen;
+    int		need_affix;
+    char_u	store_afflist[MAXWLEN];
+    char_u	pfx_pfxlist[MAXWLEN];
+    size_t	wordlen = STRLEN(word);
+    int		use_condit;
+
+    todo = (int)ht->ht_used;
+    for (hi = ht->ht_array; todo > 0 && retval == OK; ++hi)
+    {
+	if (!HASHITEM_EMPTY(hi))
+	{
+	    --todo;
+	    ah = HI2AH(hi);
+
+	    /* Check that the affix combines, if required, and that the word
+	     * supports this affix. */
+	    if (((condit & CONDIT_COMB) == 0 || ah->ah_combine)
+		    && flag_in_afflist(affile->af_flagtype, afflist,
+								 ah->ah_flag))
+	    {
+		/* Loop over all affix entries with this name. */
+		for (ae = ah->ah_first; ae != NULL; ae = ae->ae_next)
+		{
+		    /* Check the condition.  It's not logical to match case
+		     * here, but it is required for compatibility with
+		     * Myspell.
+		     * Another requirement from Myspell is that the chop
+		     * string is shorter than the word itself.
+		     * For prefixes, when "PFXPOSTPONE" was used, only do
+		     * prefixes with a chop string and/or flags.
+		     * When a previously added affix had CIRCUMFIX this one
+		     * must have it too, if it had not then this one must not
+		     * have one either. */
+		    regmatch.regprog = ae->ae_prog;
+		    regmatch.rm_ic = FALSE;
+		    if ((xht != NULL || !affile->af_pfxpostpone
+				|| ae->ae_chop != NULL
+				|| ae->ae_flags != NULL)
+			    && (ae->ae_chop == NULL
+				|| STRLEN(ae->ae_chop) < wordlen)
+			    && (ae->ae_prog == NULL
+				|| vim_regexec(&regmatch, word, (colnr_T)0))
+			    && (((condit & CONDIT_CFIX) == 0)
+				== ((condit & CONDIT_AFF) == 0
+				    || ae->ae_flags == NULL
+				    || !flag_in_afflist(affile->af_flagtype,
+					ae->ae_flags, affile->af_circumfix))))
+		    {
+			/* Match.  Remove the chop and add the affix. */
+			if (xht == NULL)
+			{
+			    /* prefix: chop/add at the start of the word */
+			    if (ae->ae_add == NULL)
+				*newword = NUL;
+			    else
+				STRCPY(newword, ae->ae_add);
+			    p = word;
+			    if (ae->ae_chop != NULL)
+			    {
+				/* Skip chop string. */
+#ifdef FEAT_MBYTE
+				if (has_mbyte)
+				{
+				    i = mb_charlen(ae->ae_chop);
+				    for ( ; i > 0; --i)
+					mb_ptr_adv(p);
+				}
+				else
+#endif
+				    p += STRLEN(ae->ae_chop);
+			    }
+			    STRCAT(newword, p);
+			}
+			else
+			{
+			    /* suffix: chop/add at the end of the word */
+			    STRCPY(newword, word);
+			    if (ae->ae_chop != NULL)
+			    {
+				/* Remove chop string. */
+				p = newword + STRLEN(newword);
+				i = (int)MB_CHARLEN(ae->ae_chop);
+				for ( ; i > 0; --i)
+				    mb_ptr_back(newword, p);
+				*p = NUL;
+			    }
+			    if (ae->ae_add != NULL)
+				STRCAT(newword, ae->ae_add);
+			}
+
+			use_flags = flags;
+			use_pfxlist = pfxlist;
+			use_pfxlen = pfxlen;
+			need_affix = FALSE;
+			use_condit = condit | CONDIT_COMB | CONDIT_AFF;
+			if (ae->ae_flags != NULL)
+			{
+			    /* Extract flags from the affix list. */
+			    use_flags |= get_affix_flags(affile, ae->ae_flags);
+
+			    if (affile->af_needaffix != 0 && flag_in_afflist(
+					affile->af_flagtype, ae->ae_flags,
+							affile->af_needaffix))
+				need_affix = TRUE;
+
+			    /* When there is a CIRCUMFIX flag the other affix
+			     * must also have it and we don't add the word
+			     * with one affix. */
+			    if (affile->af_circumfix != 0 && flag_in_afflist(
+					affile->af_flagtype, ae->ae_flags,
+							affile->af_circumfix))
+			    {
+				use_condit |= CONDIT_CFIX;
+				if ((condit & CONDIT_CFIX) == 0)
+				    need_affix = TRUE;
+			    }
+
+			    if (affile->af_pfxpostpone
+						|| spin->si_compflags != NULL)
+			    {
+				if (affile->af_pfxpostpone)
+				    /* Get prefix IDS from the affix list. */
+				    use_pfxlen = get_pfxlist(affile,
+						 ae->ae_flags, store_afflist);
+				else
+				    use_pfxlen = 0;
+				use_pfxlist = store_afflist;
+
+				/* Combine the prefix IDs. Avoid adding the
+				 * same ID twice. */
+				for (i = 0; i < pfxlen; ++i)
+				{
+				    for (j = 0; j < use_pfxlen; ++j)
+					if (pfxlist[i] == use_pfxlist[j])
+					    break;
+				    if (j == use_pfxlen)
+					use_pfxlist[use_pfxlen++] = pfxlist[i];
+				}
+
+				if (spin->si_compflags != NULL)
+				    /* Get compound IDS from the affix list. */
+				    get_compflags(affile, ae->ae_flags,
+						  use_pfxlist + use_pfxlen);
+
+				/* Combine the list of compound flags.
+				 * Concatenate them to the prefix IDs list.
+				 * Avoid adding the same ID twice. */
+				for (i = pfxlen; pfxlist[i] != NUL; ++i)
+				{
+				    for (j = use_pfxlen;
+						   use_pfxlist[j] != NUL; ++j)
+					if (pfxlist[i] == use_pfxlist[j])
+					    break;
+				    if (use_pfxlist[j] == NUL)
+				    {
+					use_pfxlist[j++] = pfxlist[i];
+					use_pfxlist[j] = NUL;
+				    }
+				}
+			    }
+			}
+
+			/* Obey a "COMPOUNDFORBIDFLAG" of the affix: don't
+			 * use the compound flags. */
+			if (use_pfxlist != NULL && ae->ae_compforbid)
+			{
+			    vim_strncpy(pfx_pfxlist, use_pfxlist, use_pfxlen);
+			    use_pfxlist = pfx_pfxlist;
+			}
+
+			/* When there are postponed prefixes... */
+			if (spin->si_prefroot != NULL
+				&& spin->si_prefroot->wn_sibling != NULL)
+			{
+			    /* ... add a flag to indicate an affix was used. */
+			    use_flags |= WF_HAS_AFF;
+
+			    /* ... don't use a prefix list if combining
+			     * affixes is not allowed.  But do use the
+			     * compound flags after them. */
+			    if (!ah->ah_combine && use_pfxlist != NULL)
+				use_pfxlist += use_pfxlen;
+			}
+
+			/* When compounding is supported and there is no
+			 * "COMPOUNDPERMITFLAG" then forbid compounding on the
+			 * side where the affix is applied. */
+			if (spin->si_compflags != NULL && !ae->ae_comppermit)
+			{
+			    if (xht != NULL)
+				use_flags |= WF_NOCOMPAFT;
+			    else
+				use_flags |= WF_NOCOMPBEF;
+			}
+
+			/* Store the modified word. */
+			if (store_word(spin, newword, use_flags,
+						 spin->si_region, use_pfxlist,
+							  need_affix) == FAIL)
+			    retval = FAIL;
+
+			/* When added a prefix or a first suffix and the affix
+			 * has flags may add a(nother) suffix.  RECURSIVE! */
+			if ((condit & CONDIT_SUF) && ae->ae_flags != NULL)
+			    if (store_aff_word(spin, newword, ae->ae_flags,
+					affile, &affile->af_suff, xht,
+					   use_condit & (xht == NULL
+							? ~0 :  ~CONDIT_SUF),
+				      use_flags, use_pfxlist, pfxlen) == FAIL)
+				retval = FAIL;
+
+			/* When added a suffix and combining is allowed also
+			 * try adding a prefix additionally.  Both for the
+			 * word flags and for the affix flags.  RECURSIVE! */
+			if (xht != NULL && ah->ah_combine)
+			{
+			    if (store_aff_word(spin, newword,
+					afflist, affile,
+					xht, NULL, use_condit,
+					use_flags, use_pfxlist,
+					pfxlen) == FAIL
+				    || (ae->ae_flags != NULL
+					&& store_aff_word(spin, newword,
+					    ae->ae_flags, affile,
+					    xht, NULL, use_condit,
+					    use_flags, use_pfxlist,
+					    pfxlen) == FAIL))
+				retval = FAIL;
+			}
+		    }
+		}
+	    }
+	}
+    }
+
+    return retval;
+}
+
+/*
+ * Read a file with a list of words.
+ */
+    static int
+spell_read_wordfile(spin, fname)
+    spellinfo_T	*spin;
+    char_u	*fname;
+{
+    FILE	*fd;
+    long	lnum = 0;
+    char_u	rline[MAXLINELEN];
+    char_u	*line;
+    char_u	*pc = NULL;
+    char_u	*p;
+    int		l;
+    int		retval = OK;
+    int		did_word = FALSE;
+    int		non_ascii = 0;
+    int		flags;
+    int		regionmask;
+
+    /*
+     * Open the file.
+     */
+    fd = mch_fopen((char *)fname, "r");
+    if (fd == NULL)
+    {
+	EMSG2(_(e_notopen), fname);
+	return FAIL;
+    }
+
+    vim_snprintf((char *)IObuff, IOSIZE, _("Reading word file %s ..."), fname);
+    spell_message(spin, IObuff);
+
+    /*
+     * Read all the lines in the file one by one.
+     */
+    while (!vim_fgets(rline, MAXLINELEN, fd) && !got_int)
+    {
+	line_breakcheck();
+	++lnum;
+
+	/* Skip comment lines. */
+	if (*rline == '#')
+	    continue;
+
+	/* Remove CR, LF and white space from the end. */
+	l = (int)STRLEN(rline);
+	while (l > 0 && rline[l - 1] <= ' ')
+	    --l;
+	if (l == 0)
+	    continue;	/* empty or blank line */
+	rline[l] = NUL;
+
+	/* Convert from "/encoding={encoding}" to 'encoding' when needed. */
+	vim_free(pc);
+#ifdef FEAT_MBYTE
+	if (spin->si_conv.vc_type != CONV_NONE)
+	{
+	    pc = string_convert(&spin->si_conv, rline, NULL);
+	    if (pc == NULL)
+	    {
+		smsg((char_u *)_("Conversion failure for word in %s line %d: %s"),
+							   fname, lnum, rline);
+		continue;
+	    }
+	    line = pc;
+	}
+	else
+#endif
+	{
+	    pc = NULL;
+	    line = rline;
+	}
+
+	if (*line == '/')
+	{
+	    ++line;
+	    if (STRNCMP(line, "encoding=", 9) == 0)
+	    {
+		if (spin->si_conv.vc_type != CONV_NONE)
+		    smsg((char_u *)_("Duplicate /encoding= line ignored in %s line %d: %s"),
+						       fname, lnum, line - 1);
+		else if (did_word)
+		    smsg((char_u *)_("/encoding= line after word ignored in %s line %d: %s"),
+						       fname, lnum, line - 1);
+		else
+		{
+#ifdef FEAT_MBYTE
+		    char_u	*enc;
+
+		    /* Setup for conversion to 'encoding'. */
+		    line += 9;
+		    enc = enc_canonize(line);
+		    if (enc != NULL && !spin->si_ascii
+			    && convert_setup(&spin->si_conv, enc,
+							       p_enc) == FAIL)
+			smsg((char_u *)_("Conversion in %s not supported: from %s to %s"),
+							  fname, line, p_enc);
+		    vim_free(enc);
+		    spin->si_conv.vc_fail = TRUE;
+#else
+		    smsg((char_u *)_("Conversion in %s not supported"), fname);
+#endif
+		}
+		continue;
+	    }
+
+	    if (STRNCMP(line, "regions=", 8) == 0)
+	    {
+		if (spin->si_region_count > 1)
+		    smsg((char_u *)_("Duplicate /regions= line ignored in %s line %d: %s"),
+						       fname, lnum, line);
+		else
+		{
+		    line += 8;
+		    if (STRLEN(line) > 16)
+			smsg((char_u *)_("Too many regions in %s line %d: %s"),
+						       fname, lnum, line);
+		    else
+		    {
+			spin->si_region_count = (int)STRLEN(line) / 2;
+			STRCPY(spin->si_region_name, line);
+
+			/* Adjust the mask for a word valid in all regions. */
+			spin->si_region = (1 << spin->si_region_count) - 1;
+		    }
+		}
+		continue;
+	    }
+
+	    smsg((char_u *)_("/ line ignored in %s line %d: %s"),
+						       fname, lnum, line - 1);
+	    continue;
+	}
+
+	flags = 0;
+	regionmask = spin->si_region;
+
+	/* Check for flags and region after a slash. */
+	p = vim_strchr(line, '/');
+	if (p != NULL)
+	{
+	    *p++ = NUL;
+	    while (*p != NUL)
+	    {
+		if (*p == '=')		/* keep-case word */
+		    flags |= WF_KEEPCAP | WF_FIXCAP;
+		else if (*p == '!')	/* Bad, bad, wicked word. */
+		    flags |= WF_BANNED;
+		else if (*p == '?')	/* Rare word. */
+		    flags |= WF_RARE;
+		else if (VIM_ISDIGIT(*p)) /* region number(s) */
+		{
+		    if ((flags & WF_REGION) == 0)   /* first one */
+			regionmask = 0;
+		    flags |= WF_REGION;
+
+		    l = *p - '0';
+		    if (l > spin->si_region_count)
+		    {
+			smsg((char_u *)_("Invalid region nr in %s line %d: %s"),
+							  fname, lnum, p);
+			break;
+		    }
+		    regionmask |= 1 << (l - 1);
+		}
+		else
+		{
+		    smsg((char_u *)_("Unrecognized flags in %s line %d: %s"),
+							      fname, lnum, p);
+		    break;
+		}
+		++p;
+	    }
+	}
+
+	/* Skip non-ASCII words when "spin->si_ascii" is TRUE. */
+	if (spin->si_ascii && has_non_ascii(line))
+	{
+	    ++non_ascii;
+	    continue;
+	}
+
+	/* Normal word: store it. */
+	if (store_word(spin, line, flags, regionmask, NULL, FALSE) == FAIL)
+	{
+	    retval = FAIL;
+	    break;
+	}
+	did_word = TRUE;
+    }
+
+    vim_free(pc);
+    fclose(fd);
+
+    if (spin->si_ascii && non_ascii > 0)
+    {
+	vim_snprintf((char *)IObuff, IOSIZE,
+		  _("Ignored %d words with non-ASCII characters"), non_ascii);
+	spell_message(spin, IObuff);
+    }
+
+    return retval;
+}
+
+/*
+ * Get part of an sblock_T, "len" bytes long.
+ * This avoids calling free() for every little struct we use (and keeping
+ * track of them).
+ * The memory is cleared to all zeros.
+ * Returns NULL when out of memory.
+ */
+    static void *
+getroom(spin, len, align)
+    spellinfo_T *spin;
+    size_t	len;		/* length needed */
+    int		align;		/* align for pointer */
+{
+    char_u	*p;
+    sblock_T	*bl = spin->si_blocks;
+
+    if (align && bl != NULL)
+	/* Round size up for alignment.  On some systems structures need to be
+	 * aligned to the size of a pointer (e.g., SPARC). */
+	bl->sb_used = (bl->sb_used + sizeof(char *) - 1)
+						      & ~(sizeof(char *) - 1);
+
+    if (bl == NULL || bl->sb_used + len > SBLOCKSIZE)
+    {
+	/* Allocate a block of memory. This is not freed until much later. */
+	bl = (sblock_T *)alloc_clear((unsigned)(sizeof(sblock_T) + SBLOCKSIZE));
+	if (bl == NULL)
+	    return NULL;
+	bl->sb_next = spin->si_blocks;
+	spin->si_blocks = bl;
+	bl->sb_used = 0;
+	++spin->si_blocks_cnt;
+    }
+
+    p = bl->sb_data + bl->sb_used;
+    bl->sb_used += (int)len;
+
+    return p;
+}
+
+/*
+ * Make a copy of a string into memory allocated with getroom().
+ */
+    static char_u *
+getroom_save(spin, s)
+    spellinfo_T	*spin;
+    char_u	*s;
+{
+    char_u	*sc;
+
+    sc = (char_u *)getroom(spin, STRLEN(s) + 1, FALSE);
+    if (sc != NULL)
+	STRCPY(sc, s);
+    return sc;
+}
+
+
+/*
+ * Free the list of allocated sblock_T.
+ */
+    static void
+free_blocks(bl)
+    sblock_T	*bl;
+{
+    sblock_T	*next;
+
+    while (bl != NULL)
+    {
+	next = bl->sb_next;
+	vim_free(bl);
+	bl = next;
+    }
+}
+
+/*
+ * Allocate the root of a word tree.
+ */
+    static wordnode_T *
+wordtree_alloc(spin)
+    spellinfo_T *spin;
+{
+    return (wordnode_T *)getroom(spin, sizeof(wordnode_T), TRUE);
+}
+
+/*
+ * Store a word in the tree(s).
+ * Always store it in the case-folded tree.  For a keep-case word this is
+ * useful when the word can also be used with all caps (no WF_FIXCAP flag) and
+ * used to find suggestions.
+ * For a keep-case word also store it in the keep-case tree.
+ * When "pfxlist" is not NULL store the word for each postponed prefix ID and
+ * compound flag.
+ */
+    static int
+store_word(spin, word, flags, region, pfxlist, need_affix)
+    spellinfo_T	*spin;
+    char_u	*word;
+    int		flags;		/* extra flags, WF_BANNED */
+    int		region;		/* supported region(s) */
+    char_u	*pfxlist;	/* list of prefix IDs or NULL */
+    int		need_affix;	/* only store word with affix ID */
+{
+    int		len = (int)STRLEN(word);
+    int		ct = captype(word, word + len);
+    char_u	foldword[MAXWLEN];
+    int		res = OK;
+    char_u	*p;
+
+    (void)spell_casefold(word, len, foldword, MAXWLEN);
+    for (p = pfxlist; res == OK; ++p)
+    {
+	if (!need_affix || (p != NULL && *p != NUL))
+	    res = tree_add_word(spin, foldword, spin->si_foldroot, ct | flags,
+						  region, p == NULL ? 0 : *p);
+	if (p == NULL || *p == NUL)
+	    break;
+    }
+    ++spin->si_foldwcount;
+
+    if (res == OK && (ct == WF_KEEPCAP || (flags & WF_KEEPCAP)))
+    {
+	for (p = pfxlist; res == OK; ++p)
+	{
+	    if (!need_affix || (p != NULL && *p != NUL))
+		res = tree_add_word(spin, word, spin->si_keeproot, flags,
+						  region, p == NULL ? 0 : *p);
+	    if (p == NULL || *p == NUL)
+		break;
+	}
+	++spin->si_keepwcount;
+    }
+    return res;
+}
+
+/*
+ * Add word "word" to a word tree at "root".
+ * When "flags" < 0 we are adding to the prefix tree where "flags" is used for
+ * "rare" and "region" is the condition nr.
+ * Returns FAIL when out of memory.
+ */
+    static int
+tree_add_word(spin, word, root, flags, region, affixID)
+    spellinfo_T	*spin;
+    char_u	*word;
+    wordnode_T	*root;
+    int		flags;
+    int		region;
+    int		affixID;
+{
+    wordnode_T	*node = root;
+    wordnode_T	*np;
+    wordnode_T	*copyp, **copyprev;
+    wordnode_T	**prev = NULL;
+    int		i;
+
+    /* Add each byte of the word to the tree, including the NUL at the end. */
+    for (i = 0; ; ++i)
+    {
+	/* When there is more than one reference to this node we need to make
+	 * a copy, so that we can modify it.  Copy the whole list of siblings
+	 * (we don't optimize for a partly shared list of siblings). */
+	if (node != NULL && node->wn_refs > 1)
+	{
+	    --node->wn_refs;
+	    copyprev = prev;
+	    for (copyp = node; copyp != NULL; copyp = copyp->wn_sibling)
+	    {
+		/* Allocate a new node and copy the info. */
+		np = get_wordnode(spin);
+		if (np == NULL)
+		    return FAIL;
+		np->wn_child = copyp->wn_child;
+		if (np->wn_child != NULL)
+		    ++np->wn_child->wn_refs;	/* child gets extra ref */
+		np->wn_byte = copyp->wn_byte;
+		if (np->wn_byte == NUL)
+		{
+		    np->wn_flags = copyp->wn_flags;
+		    np->wn_region = copyp->wn_region;
+		    np->wn_affixID = copyp->wn_affixID;
+		}
+
+		/* Link the new node in the list, there will be one ref. */
+		np->wn_refs = 1;
+		if (copyprev != NULL)
+		    *copyprev = np;
+		copyprev = &np->wn_sibling;
+
+		/* Let "node" point to the head of the copied list. */
+		if (copyp == node)
+		    node = np;
+	    }
+	}
+
+	/* Look for the sibling that has the same character.  They are sorted
+	 * on byte value, thus stop searching when a sibling is found with a
+	 * higher byte value.  For zero bytes (end of word) the sorting is
+	 * done on flags and then on affixID. */
+	while (node != NULL
+		&& (node->wn_byte < word[i]
+		    || (node->wn_byte == NUL
+			&& (flags < 0
+			    ? node->wn_affixID < (unsigned)affixID
+			    : (node->wn_flags < (unsigned)(flags & WN_MASK)
+				|| (node->wn_flags == (flags & WN_MASK)
+				    && (spin->si_sugtree
+					? (node->wn_region & 0xffff) < region
+					: node->wn_affixID
+						    < (unsigned)affixID)))))))
+	{
+	    prev = &node->wn_sibling;
+	    node = *prev;
+	}
+	if (node == NULL
+		|| node->wn_byte != word[i]
+		|| (word[i] == NUL
+		    && (flags < 0
+			|| spin->si_sugtree
+			|| node->wn_flags != (flags & WN_MASK)
+			|| node->wn_affixID != affixID)))
+	{
+	    /* Allocate a new node. */
+	    np = get_wordnode(spin);
+	    if (np == NULL)
+		return FAIL;
+	    np->wn_byte = word[i];
+
+	    /* If "node" is NULL this is a new child or the end of the sibling
+	     * list: ref count is one.  Otherwise use ref count of sibling and
+	     * make ref count of sibling one (matters when inserting in front
+	     * of the list of siblings). */
+	    if (node == NULL)
+		np->wn_refs = 1;
+	    else
+	    {
+		np->wn_refs = node->wn_refs;
+		node->wn_refs = 1;
+	    }
+	    *prev = np;
+	    np->wn_sibling = node;
+	    node = np;
+	}
+
+	if (word[i] == NUL)
+	{
+	    node->wn_flags = flags;
+	    node->wn_region |= region;
+	    node->wn_affixID = affixID;
+	    break;
+	}
+	prev = &node->wn_child;
+	node = *prev;
+    }
+#ifdef SPELL_PRINTTREE
+    smsg("Added \"%s\"", word);
+    spell_print_tree(root->wn_sibling);
+#endif
+
+    /* count nr of words added since last message */
+    ++spin->si_msg_count;
+
+    if (spin->si_compress_cnt > 1)
+    {
+	if (--spin->si_compress_cnt == 1)
+	    /* Did enough words to lower the block count limit. */
+	    spin->si_blocks_cnt += compress_inc;
+    }
+
+    /*
+     * When we have allocated lots of memory we need to compress the word tree
+     * to free up some room.  But compression is slow, and we might actually
+     * need that room, thus only compress in the following situations:
+     * 1. When not compressed before (si_compress_cnt == 0): when using
+     *    "compress_start" blocks.
+     * 2. When compressed before and used "compress_inc" blocks before
+     *    adding "compress_added" words (si_compress_cnt > 1).
+     * 3. When compressed before, added "compress_added" words
+     *    (si_compress_cnt == 1) and the number of free nodes drops below the
+     *    maximum word length.
+     */
+#ifndef SPELL_PRINTTREE
+    if (spin->si_compress_cnt == 1
+	    ? spin->si_free_count < MAXWLEN
+	    : spin->si_blocks_cnt >= compress_start)
+#endif
+    {
+	/* Decrement the block counter.  The effect is that we compress again
+	 * when the freed up room has been used and another "compress_inc"
+	 * blocks have been allocated.  Unless "compress_added" words have
+	 * been added, then the limit is put back again. */
+	spin->si_blocks_cnt -= compress_inc;
+	spin->si_compress_cnt = compress_added;
+
+	if (spin->si_verbose)
+	{
+	    msg_start();
+	    msg_puts((char_u *)_(msg_compressing));
+	    msg_clr_eos();
+	    msg_didout = FALSE;
+	    msg_col = 0;
+	    out_flush();
+	}
+
+	/* Compress both trees.  Either they both have many nodes, which makes
+	 * compression useful, or one of them is small, which means
+	 * compression goes fast.  But when filling the souldfold word tree
+	 * there is no keep-case tree. */
+	wordtree_compress(spin, spin->si_foldroot);
+	if (affixID >= 0)
+	    wordtree_compress(spin, spin->si_keeproot);
+    }
+
+    return OK;
+}
+
+/*
+ * Check the 'mkspellmem' option.  Return FAIL if it's wrong.
+ * Sets "sps_flags".
+ */
+    int
+spell_check_msm()
+{
+    char_u	*p = p_msm;
+    long	start = 0;
+    long	incr = 0;
+    long	added = 0;
+
+    if (!VIM_ISDIGIT(*p))
+	return FAIL;
+    /* block count = (value * 1024) / SBLOCKSIZE (but avoid overflow)*/
+    start = (getdigits(&p) * 10) / (SBLOCKSIZE / 102);
+    if (*p != ',')
+	return FAIL;
+    ++p;
+    if (!VIM_ISDIGIT(*p))
+	return FAIL;
+    incr = (getdigits(&p) * 102) / (SBLOCKSIZE / 10);
+    if (*p != ',')
+	return FAIL;
+    ++p;
+    if (!VIM_ISDIGIT(*p))
+	return FAIL;
+    added = getdigits(&p) * 1024;
+    if (*p != NUL)
+	return FAIL;
+
+    if (start == 0 || incr == 0 || added == 0 || incr > start)
+	return FAIL;
+
+    compress_start = start;
+    compress_inc = incr;
+    compress_added = added;
+    return OK;
+}
+
+
+/*
+ * Get a wordnode_T, either from the list of previously freed nodes or
+ * allocate a new one.
+ */
+    static wordnode_T *
+get_wordnode(spin)
+    spellinfo_T	    *spin;
+{
+    wordnode_T *n;
+
+    if (spin->si_first_free == NULL)
+	n = (wordnode_T *)getroom(spin, sizeof(wordnode_T), TRUE);
+    else
+    {
+	n = spin->si_first_free;
+	spin->si_first_free = n->wn_child;
+	vim_memset(n, 0, sizeof(wordnode_T));
+	--spin->si_free_count;
+    }
+#ifdef SPELL_PRINTTREE
+    n->wn_nr = ++spin->si_wordnode_nr;
+#endif
+    return n;
+}
+
+/*
+ * Decrement the reference count on a node (which is the head of a list of
+ * siblings).  If the reference count becomes zero free the node and its
+ * siblings.
+ * Returns the number of nodes actually freed.
+ */
+    static int
+deref_wordnode(spin, node)
+    spellinfo_T *spin;
+    wordnode_T  *node;
+{
+    wordnode_T	*np;
+    int		cnt = 0;
+
+    if (--node->wn_refs == 0)
+    {
+	for (np = node; np != NULL; np = np->wn_sibling)
+	{
+	    if (np->wn_child != NULL)
+		cnt += deref_wordnode(spin, np->wn_child);
+	    free_wordnode(spin, np);
+	    ++cnt;
+	}
+	++cnt;	    /* length field */
+    }
+    return cnt;
+}
+
+/*
+ * Free a wordnode_T for re-use later.
+ * Only the "wn_child" field becomes invalid.
+ */
+    static void
+free_wordnode(spin, n)
+    spellinfo_T	*spin;
+    wordnode_T  *n;
+{
+    n->wn_child = spin->si_first_free;
+    spin->si_first_free = n;
+    ++spin->si_free_count;
+}
+
+/*
+ * Compress a tree: find tails that are identical and can be shared.
+ */
+    static void
+wordtree_compress(spin, root)
+    spellinfo_T	    *spin;
+    wordnode_T	    *root;
+{
+    hashtab_T	    ht;
+    int		    n;
+    int		    tot = 0;
+    int		    perc;
+
+    /* Skip the root itself, it's not actually used.  The first sibling is the
+     * start of the tree. */
+    if (root->wn_sibling != NULL)
+    {
+	hash_init(&ht);
+	n = node_compress(spin, root->wn_sibling, &ht, &tot);
+
+#ifndef SPELL_PRINTTREE
+	if (spin->si_verbose || p_verbose > 2)
+#endif
+	{
+	    if (tot > 1000000)
+		perc = (tot - n) / (tot / 100);
+	    else if (tot == 0)
+		perc = 0;
+	    else
+		perc = (tot - n) * 100 / tot;
+	    vim_snprintf((char *)IObuff, IOSIZE,
+			  _("Compressed %d of %d nodes; %d (%d%%) remaining"),
+						       n, tot, tot - n, perc);
+	    spell_message(spin, IObuff);
+	}
+#ifdef SPELL_PRINTTREE
+	spell_print_tree(root->wn_sibling);
+#endif
+	hash_clear(&ht);
+    }
+}
+
+/*
+ * Compress a node, its siblings and its children, depth first.
+ * Returns the number of compressed nodes.
+ */
+    static int
+node_compress(spin, node, ht, tot)
+    spellinfo_T	*spin;
+    wordnode_T	*node;
+    hashtab_T	*ht;
+    int		*tot;	    /* total count of nodes before compressing,
+			       incremented while going through the tree */
+{
+    wordnode_T	*np;
+    wordnode_T	*tp;
+    wordnode_T	*child;
+    hash_T	hash;
+    hashitem_T	*hi;
+    int		len = 0;
+    unsigned	nr, n;
+    int		compressed = 0;
+
+    /*
+     * Go through the list of siblings.  Compress each child and then try
+     * finding an identical child to replace it.
+     * Note that with "child" we mean not just the node that is pointed to,
+     * but the whole list of siblings of which the child node is the first.
+     */
+    for (np = node; np != NULL && !got_int; np = np->wn_sibling)
+    {
+	++len;
+	if ((child = np->wn_child) != NULL)
+	{
+	    /* Compress the child first.  This fills hashkey. */
+	    compressed += node_compress(spin, child, ht, tot);
+
+	    /* Try to find an identical child. */
+	    hash = hash_hash(child->wn_u1.hashkey);
+	    hi = hash_lookup(ht, child->wn_u1.hashkey, hash);
+	    if (!HASHITEM_EMPTY(hi))
+	    {
+		/* There are children we encountered before with a hash value
+		 * identical to the current child.  Now check if there is one
+		 * that is really identical. */
+		for (tp = HI2WN(hi); tp != NULL; tp = tp->wn_u2.next)
+		    if (node_equal(child, tp))
+		    {
+			/* Found one!  Now use that child in place of the
+			 * current one.  This means the current child and all
+			 * its siblings is unlinked from the tree. */
+			++tp->wn_refs;
+			compressed += deref_wordnode(spin, child);
+			np->wn_child = tp;
+			break;
+		    }
+		if (tp == NULL)
+		{
+		    /* No other child with this hash value equals the child of
+		     * the node, add it to the linked list after the first
+		     * item. */
+		    tp = HI2WN(hi);
+		    child->wn_u2.next = tp->wn_u2.next;
+		    tp->wn_u2.next = child;
+		}
+	    }
+	    else
+		/* No other child has this hash value, add it to the
+		 * hashtable. */
+		hash_add_item(ht, hi, child->wn_u1.hashkey, hash);
+	}
+    }
+    *tot += len + 1;	/* add one for the node that stores the length */
+
+    /*
+     * Make a hash key for the node and its siblings, so that we can quickly
+     * find a lookalike node.  This must be done after compressing the sibling
+     * list, otherwise the hash key would become invalid by the compression.
+     */
+    node->wn_u1.hashkey[0] = len;
+    nr = 0;
+    for (np = node; np != NULL; np = np->wn_sibling)
+    {
+	if (np->wn_byte == NUL)
+	    /* end node: use wn_flags, wn_region and wn_affixID */
+	    n = np->wn_flags + (np->wn_region << 8) + (np->wn_affixID << 16);
+	else
+	    /* byte node: use the byte value and the child pointer */
+	    n = (unsigned)(np->wn_byte + ((long_u)np->wn_child << 8));
+	nr = nr * 101 + n;
+    }
+
+    /* Avoid NUL bytes, it terminates the hash key. */
+    n = nr & 0xff;
+    node->wn_u1.hashkey[1] = n == 0 ? 1 : n;
+    n = (nr >> 8) & 0xff;
+    node->wn_u1.hashkey[2] = n == 0 ? 1 : n;
+    n = (nr >> 16) & 0xff;
+    node->wn_u1.hashkey[3] = n == 0 ? 1 : n;
+    n = (nr >> 24) & 0xff;
+    node->wn_u1.hashkey[4] = n == 0 ? 1 : n;
+    node->wn_u1.hashkey[5] = NUL;
+
+    /* Check for CTRL-C pressed now and then. */
+    fast_breakcheck();
+
+    return compressed;
+}
+
+/*
+ * Return TRUE when two nodes have identical siblings and children.
+ */
+    static int
+node_equal(n1, n2)
+    wordnode_T	*n1;
+    wordnode_T	*n2;
+{
+    wordnode_T	*p1;
+    wordnode_T	*p2;
+
+    for (p1 = n1, p2 = n2; p1 != NULL && p2 != NULL;
+				     p1 = p1->wn_sibling, p2 = p2->wn_sibling)
+	if (p1->wn_byte != p2->wn_byte
+		|| (p1->wn_byte == NUL
+		    ? (p1->wn_flags != p2->wn_flags
+			|| p1->wn_region != p2->wn_region
+			|| p1->wn_affixID != p2->wn_affixID)
+		    : (p1->wn_child != p2->wn_child)))
+	    break;
+
+    return p1 == NULL && p2 == NULL;
+}
+
+/*
+ * Write a number to file "fd", MSB first, in "len" bytes.
+ */
+    void
+put_bytes(fd, nr, len)
+    FILE    *fd;
+    long_u  nr;
+    int	    len;
+{
+    int	    i;
+
+    for (i = len - 1; i >= 0; --i)
+	putc((int)(nr >> (i * 8)), fd);
+}
+
+#ifdef _MSC_VER
+# if (_MSC_VER <= 1200)
+/* This line is required for VC6 without the service pack.  Also see the
+ * matching #pragma below. */
+/* # pragma optimize("", off) */
+# endif
+#endif
+
+/*
+ * Write spin->si_sugtime to file "fd".
+ */
+    static void
+put_sugtime(spin, fd)
+    spellinfo_T *spin;
+    FILE	*fd;
+{
+    int		c;
+    int		i;
+
+    /* time_t can be up to 8 bytes in size, more than long_u, thus we
+     * can't use put_bytes() here. */
+    for (i = 7; i >= 0; --i)
+	if (i + 1 > sizeof(time_t))
+	    /* ">>" doesn't work well when shifting more bits than avail */
+	    putc(0, fd);
+	else
+	{
+	    c = (unsigned)spin->si_sugtime >> (i * 8);
+	    putc(c, fd);
+	}
+}
+
+#ifdef _MSC_VER
+# if (_MSC_VER <= 1200)
+/* # pragma optimize("", on) */
+# endif
+#endif
+
+static int
+#ifdef __BORLANDC__
+_RTLENTRYF
+#endif
+rep_compare __ARGS((const void *s1, const void *s2));
+
+/*
+ * Function given to qsort() to sort the REP items on "from" string.
+ */
+    static int
+#ifdef __BORLANDC__
+_RTLENTRYF
+#endif
+rep_compare(s1, s2)
+    const void	*s1;
+    const void	*s2;
+{
+    fromto_T	*p1 = (fromto_T *)s1;
+    fromto_T	*p2 = (fromto_T *)s2;
+
+    return STRCMP(p1->ft_from, p2->ft_from);
+}
+
+/*
+ * Write the Vim .spl file "fname".
+ * Return FAIL or OK;
+ */
+    static int
+write_vim_spell(spin, fname)
+    spellinfo_T	*spin;
+    char_u	*fname;
+{
+    FILE	*fd;
+    int		regionmask;
+    int		round;
+    wordnode_T	*tree;
+    int		nodecount;
+    int		i;
+    int		l;
+    garray_T	*gap;
+    fromto_T	*ftp;
+    char_u	*p;
+    int		rr;
+    int		retval = OK;
+
+    fd = mch_fopen((char *)fname, "w");
+    if (fd == NULL)
+    {
+	EMSG2(_(e_notopen), fname);
+	return FAIL;
+    }
+
+    /* <HEADER>: <fileID> <versionnr> */
+							    /* <fileID> */
+    if (fwrite(VIMSPELLMAGIC, VIMSPELLMAGICL, (size_t)1, fd) != 1)
+    {
+	EMSG(_(e_write));
+	retval = FAIL;
+    }
+    putc(VIMSPELLVERSION, fd);				    /* <versionnr> */
+
+    /*
+     * <SECTIONS>: <section> ... <sectionend>
+     */
+
+    /* SN_INFO: <infotext> */
+    if (spin->si_info != NULL)
+    {
+	putc(SN_INFO, fd);				/* <sectionID> */
+	putc(0, fd);					/* <sectionflags> */
+
+	i = (int)STRLEN(spin->si_info);
+	put_bytes(fd, (long_u)i, 4);			/* <sectionlen> */
+	fwrite(spin->si_info, (size_t)i, (size_t)1, fd); /* <infotext> */
+    }
+
+    /* SN_REGION: <regionname> ...
+     * Write the region names only if there is more than one. */
+    if (spin->si_region_count > 1)
+    {
+	putc(SN_REGION, fd);				/* <sectionID> */
+	putc(SNF_REQUIRED, fd);				/* <sectionflags> */
+	l = spin->si_region_count * 2;
+	put_bytes(fd, (long_u)l, 4);			/* <sectionlen> */
+	fwrite(spin->si_region_name, (size_t)l, (size_t)1, fd);
+							/* <regionname> ... */
+	regionmask = (1 << spin->si_region_count) - 1;
+    }
+    else
+	regionmask = 0;
+
+    /* SN_CHARFLAGS: <charflagslen> <charflags> <folcharslen> <folchars>
+     *
+     * The table with character flags and the table for case folding.
+     * This makes sure the same characters are recognized as word characters
+     * when generating an when using a spell file.
+     * Skip this for ASCII, the table may conflict with the one used for
+     * 'encoding'.
+     * Also skip this for an .add.spl file, the main spell file must contain
+     * the table (avoids that it conflicts).  File is shorter too.
+     */
+    if (!spin->si_ascii && !spin->si_add)
+    {
+	char_u	folchars[128 * 8];
+	int	flags;
+
+	putc(SN_CHARFLAGS, fd);				/* <sectionID> */
+	putc(SNF_REQUIRED, fd);				/* <sectionflags> */
+
+	/* Form the <folchars> string first, we need to know its length. */
+	l = 0;
+	for (i = 128; i < 256; ++i)
+	{
+#ifdef FEAT_MBYTE
+	    if (has_mbyte)
+		l += mb_char2bytes(spelltab.st_fold[i], folchars + l);
+	    else
+#endif
+		folchars[l++] = spelltab.st_fold[i];
+	}
+	put_bytes(fd, (long_u)(1 + 128 + 2 + l), 4);	/* <sectionlen> */
+
+	fputc(128, fd);					/* <charflagslen> */
+	for (i = 128; i < 256; ++i)
+	{
+	    flags = 0;
+	    if (spelltab.st_isw[i])
+		flags |= CF_WORD;
+	    if (spelltab.st_isu[i])
+		flags |= CF_UPPER;
+	    fputc(flags, fd);				/* <charflags> */
+	}
+
+	put_bytes(fd, (long_u)l, 2);			/* <folcharslen> */
+	fwrite(folchars, (size_t)l, (size_t)1, fd);	/* <folchars> */
+    }
+
+    /* SN_MIDWORD: <midword> */
+    if (spin->si_midword != NULL)
+    {
+	putc(SN_MIDWORD, fd);				/* <sectionID> */
+	putc(SNF_REQUIRED, fd);				/* <sectionflags> */
+
+	i = (int)STRLEN(spin->si_midword);
+	put_bytes(fd, (long_u)i, 4);			/* <sectionlen> */
+	fwrite(spin->si_midword, (size_t)i, (size_t)1, fd); /* <midword> */
+    }
+
+    /* SN_PREFCOND: <prefcondcnt> <prefcond> ... */
+    if (spin->si_prefcond.ga_len > 0)
+    {
+	putc(SN_PREFCOND, fd);				/* <sectionID> */
+	putc(SNF_REQUIRED, fd);				/* <sectionflags> */
+
+	l = write_spell_prefcond(NULL, &spin->si_prefcond);
+	put_bytes(fd, (long_u)l, 4);			/* <sectionlen> */
+
+	write_spell_prefcond(fd, &spin->si_prefcond);
+    }
+
+    /* SN_REP: <repcount> <rep> ...
+     * SN_SAL: <salflags> <salcount> <sal> ...
+     * SN_REPSAL: <repcount> <rep> ... */
+
+    /* round 1: SN_REP section
+     * round 2: SN_SAL section (unless SN_SOFO is used)
+     * round 3: SN_REPSAL section */
+    for (round = 1; round <= 3; ++round)
+    {
+	if (round == 1)
+	    gap = &spin->si_rep;
+	else if (round == 2)
+	{
+	    /* Don't write SN_SAL when using a SN_SOFO section */
+	    if (spin->si_sofofr != NULL && spin->si_sofoto != NULL)
+		continue;
+	    gap = &spin->si_sal;
+	}
+	else
+	    gap = &spin->si_repsal;
+
+	/* Don't write the section if there are no items. */
+	if (gap->ga_len == 0)
+	    continue;
+
+	/* Sort the REP/REPSAL items. */
+	if (round != 2)
+	    qsort(gap->ga_data, (size_t)gap->ga_len,
+					       sizeof(fromto_T), rep_compare);
+
+	i = round == 1 ? SN_REP : (round == 2 ? SN_SAL : SN_REPSAL);
+	putc(i, fd);					/* <sectionID> */
+
+	/* This is for making suggestions, section is not required. */
+	putc(0, fd);					/* <sectionflags> */
+
+	/* Compute the length of what follows. */
+	l = 2;	    /* count <repcount> or <salcount> */
+	for (i = 0; i < gap->ga_len; ++i)
+	{
+	    ftp = &((fromto_T *)gap->ga_data)[i];
+	    l += 1 + (int)STRLEN(ftp->ft_from);  /* count <*fromlen> and <*from> */
+	    l += 1 + (int)STRLEN(ftp->ft_to);    /* count <*tolen> and <*to> */
+	}
+	if (round == 2)
+	    ++l;	/* count <salflags> */
+	put_bytes(fd, (long_u)l, 4);			/* <sectionlen> */
+
+	if (round == 2)
+	{
+	    i = 0;
+	    if (spin->si_followup)
+		i |= SAL_F0LLOWUP;
+	    if (spin->si_collapse)
+		i |= SAL_COLLAPSE;
+	    if (spin->si_rem_accents)
+		i |= SAL_REM_ACCENTS;
+	    putc(i, fd);			/* <salflags> */
+	}
+
+	put_bytes(fd, (long_u)gap->ga_len, 2);	/* <repcount> or <salcount> */
+	for (i = 0; i < gap->ga_len; ++i)
+	{
+	    /* <rep> : <repfromlen> <repfrom> <reptolen> <repto> */
+	    /* <sal> : <salfromlen> <salfrom> <saltolen> <salto> */
+	    ftp = &((fromto_T *)gap->ga_data)[i];
+	    for (rr = 1; rr <= 2; ++rr)
+	    {
+		p = rr == 1 ? ftp->ft_from : ftp->ft_to;
+		l = (int)STRLEN(p);
+		putc(l, fd);
+		fwrite(p, l, (size_t)1, fd);
+	    }
+	}
+
+    }
+
+    /* SN_SOFO: <sofofromlen> <sofofrom> <sofotolen> <sofoto>
+     * This is for making suggestions, section is not required. */
+    if (spin->si_sofofr != NULL && spin->si_sofoto != NULL)
+    {
+	putc(SN_SOFO, fd);				/* <sectionID> */
+	putc(0, fd);					/* <sectionflags> */
+
+	l = (int)STRLEN(spin->si_sofofr);
+	put_bytes(fd, (long_u)(l + STRLEN(spin->si_sofoto) + 4), 4);
+							/* <sectionlen> */
+
+	put_bytes(fd, (long_u)l, 2);			/* <sofofromlen> */
+	fwrite(spin->si_sofofr, l, (size_t)1, fd);	/* <sofofrom> */
+
+	l = (int)STRLEN(spin->si_sofoto);
+	put_bytes(fd, (long_u)l, 2);			/* <sofotolen> */
+	fwrite(spin->si_sofoto, l, (size_t)1, fd);	/* <sofoto> */
+    }
+
+    /* SN_WORDS: <word> ...
+     * This is for making suggestions, section is not required. */
+    if (spin->si_commonwords.ht_used > 0)
+    {
+	putc(SN_WORDS, fd);				/* <sectionID> */
+	putc(0, fd);					/* <sectionflags> */
+
+	/* round 1: count the bytes
+	 * round 2: write the bytes */
+	for (round = 1; round <= 2; ++round)
+	{
+	    int		todo;
+	    int		len = 0;
+	    hashitem_T	*hi;
+
+	    todo = (int)spin->si_commonwords.ht_used;
+	    for (hi = spin->si_commonwords.ht_array; todo > 0; ++hi)
+		if (!HASHITEM_EMPTY(hi))
+		{
+		    l = (int)STRLEN(hi->hi_key) + 1;
+		    len += l;
+		    if (round == 2)			/* <word> */
+			fwrite(hi->hi_key, (size_t)l, (size_t)1, fd);
+		    --todo;
+		}
+	    if (round == 1)
+		put_bytes(fd, (long_u)len, 4);		/* <sectionlen> */
+	}
+    }
+
+    /* SN_MAP: <mapstr>
+     * This is for making suggestions, section is not required. */
+    if (spin->si_map.ga_len > 0)
+    {
+	putc(SN_MAP, fd);				/* <sectionID> */
+	putc(0, fd);					/* <sectionflags> */
+	l = spin->si_map.ga_len;
+	put_bytes(fd, (long_u)l, 4);			/* <sectionlen> */
+	fwrite(spin->si_map.ga_data, (size_t)l, (size_t)1, fd);
+							/* <mapstr> */
+    }
+
+    /* SN_SUGFILE: <timestamp>
+     * This is used to notify that a .sug file may be available and at the
+     * same time allows for checking that a .sug file that is found matches
+     * with this .spl file.  That's because the word numbers must be exactly
+     * right. */
+    if (!spin->si_nosugfile
+	    && (spin->si_sal.ga_len > 0
+		     || (spin->si_sofofr != NULL && spin->si_sofoto != NULL)))
+    {
+	putc(SN_SUGFILE, fd);				/* <sectionID> */
+	putc(0, fd);					/* <sectionflags> */
+	put_bytes(fd, (long_u)8, 4);			/* <sectionlen> */
+
+	/* Set si_sugtime and write it to the file. */
+	spin->si_sugtime = time(NULL);
+	put_sugtime(spin, fd);				/* <timestamp> */
+    }
+
+    /* SN_NOSPLITSUGS: nothing
+     * This is used to notify that no suggestions with word splits are to be
+     * made. */
+    if (spin->si_nosplitsugs)
+    {
+	putc(SN_NOSPLITSUGS, fd);			/* <sectionID> */
+	putc(0, fd);					/* <sectionflags> */
+	put_bytes(fd, (long_u)0, 4);			/* <sectionlen> */
+    }
+
+    /* SN_COMPOUND: compound info.
+     * We don't mark it required, when not supported all compound words will
+     * be bad words. */
+    if (spin->si_compflags != NULL)
+    {
+	putc(SN_COMPOUND, fd);				/* <sectionID> */
+	putc(0, fd);					/* <sectionflags> */
+
+	l = (int)STRLEN(spin->si_compflags);
+	for (i = 0; i < spin->si_comppat.ga_len; ++i)
+	    l += (int)STRLEN(((char_u **)(spin->si_comppat.ga_data))[i]) + 1;
+	put_bytes(fd, (long_u)(l + 7), 4);		/* <sectionlen> */
+
+	putc(spin->si_compmax, fd);			/* <compmax> */
+	putc(spin->si_compminlen, fd);			/* <compminlen> */
+	putc(spin->si_compsylmax, fd);			/* <compsylmax> */
+	putc(0, fd);		/* for Vim 7.0b compatibility */
+	putc(spin->si_compoptions, fd);			/* <compoptions> */
+	put_bytes(fd, (long_u)spin->si_comppat.ga_len, 2);
+							/* <comppatcount> */
+	for (i = 0; i < spin->si_comppat.ga_len; ++i)
+	{
+	    p = ((char_u **)(spin->si_comppat.ga_data))[i];
+	    putc((int)STRLEN(p), fd);			/* <comppatlen> */
+	    fwrite(p, (size_t)STRLEN(p), (size_t)1, fd);/* <comppattext> */
+	}
+							/* <compflags> */
+	fwrite(spin->si_compflags, (size_t)STRLEN(spin->si_compflags),
+							       (size_t)1, fd);
+    }
+
+    /* SN_NOBREAK: NOBREAK flag */
+    if (spin->si_nobreak)
+    {
+	putc(SN_NOBREAK, fd);				/* <sectionID> */
+	putc(0, fd);					/* <sectionflags> */
+
+	/* It's empty, the presence of the section flags the feature. */
+	put_bytes(fd, (long_u)0, 4);			/* <sectionlen> */
+    }
+
+    /* SN_SYLLABLE: syllable info.
+     * We don't mark it required, when not supported syllables will not be
+     * counted. */
+    if (spin->si_syllable != NULL)
+    {
+	putc(SN_SYLLABLE, fd);				/* <sectionID> */
+	putc(0, fd);					/* <sectionflags> */
+
+	l = (int)STRLEN(spin->si_syllable);
+	put_bytes(fd, (long_u)l, 4);			/* <sectionlen> */
+	fwrite(spin->si_syllable, (size_t)l, (size_t)1, fd); /* <syllable> */
+    }
+
+    /* end of <SECTIONS> */
+    putc(SN_END, fd);					/* <sectionend> */
+
+
+    /*
+     * <LWORDTREE>  <KWORDTREE>  <PREFIXTREE>
+     */
+    spin->si_memtot = 0;
+    for (round = 1; round <= 3; ++round)
+    {
+	if (round == 1)
+	    tree = spin->si_foldroot->wn_sibling;
+	else if (round == 2)
+	    tree = spin->si_keeproot->wn_sibling;
+	else
+	    tree = spin->si_prefroot->wn_sibling;
+
+	/* Clear the index and wnode fields in the tree. */
+	clear_node(tree);
+
+	/* Count the number of nodes.  Needed to be able to allocate the
+	 * memory when reading the nodes.  Also fills in index for shared
+	 * nodes. */
+	nodecount = put_node(NULL, tree, 0, regionmask, round == 3);
+
+	/* number of nodes in 4 bytes */
+	put_bytes(fd, (long_u)nodecount, 4);	/* <nodecount> */
+	spin->si_memtot += nodecount + nodecount * sizeof(int);
+
+	/* Write the nodes. */
+	(void)put_node(fd, tree, 0, regionmask, round == 3);
+    }
+
+    /* Write another byte to check for errors. */
+    if (putc(0, fd) == EOF)
+	retval = FAIL;
+
+    if (fclose(fd) == EOF)
+	retval = FAIL;
+
+    return retval;
+}
+
+/*
+ * Clear the index and wnode fields of "node", it siblings and its
+ * children.  This is needed because they are a union with other items to save
+ * space.
+ */
+    static void
+clear_node(node)
+    wordnode_T	*node;
+{
+    wordnode_T	*np;
+
+    if (node != NULL)
+	for (np = node; np != NULL; np = np->wn_sibling)
+	{
+	    np->wn_u1.index = 0;
+	    np->wn_u2.wnode = NULL;
+
+	    if (np->wn_byte != NUL)
+		clear_node(np->wn_child);
+	}
+}
+
+
+/*
+ * Dump a word tree at node "node".
+ *
+ * This first writes the list of possible bytes (siblings).  Then for each
+ * byte recursively write the children.
+ *
+ * NOTE: The code here must match the code in read_tree_node(), since
+ * assumptions are made about the indexes (so that we don't have to write them
+ * in the file).
+ *
+ * Returns the number of nodes used.
+ */
+    static int
+put_node(fd, node, idx, regionmask, prefixtree)
+    FILE	*fd;		/* NULL when only counting */
+    wordnode_T	*node;
+    int		idx;
+    int		regionmask;
+    int		prefixtree;	/* TRUE for PREFIXTREE */
+{
+    int		newindex = idx;
+    int		siblingcount = 0;
+    wordnode_T	*np;
+    int		flags;
+
+    /* If "node" is zero the tree is empty. */
+    if (node == NULL)
+	return 0;
+
+    /* Store the index where this node is written. */
+    node->wn_u1.index = idx;
+
+    /* Count the number of siblings. */
+    for (np = node; np != NULL; np = np->wn_sibling)
+	++siblingcount;
+
+    /* Write the sibling count. */
+    if (fd != NULL)
+	putc(siblingcount, fd);				/* <siblingcount> */
+
+    /* Write each sibling byte and optionally extra info. */
+    for (np = node; np != NULL; np = np->wn_sibling)
+    {
+	if (np->wn_byte == 0)
+	{
+	    if (fd != NULL)
+	    {
+		/* For a NUL byte (end of word) write the flags etc. */
+		if (prefixtree)
+		{
+		    /* In PREFIXTREE write the required affixID and the
+		     * associated condition nr (stored in wn_region).  The
+		     * byte value is misused to store the "rare" and "not
+		     * combining" flags */
+		    if (np->wn_flags == (short_u)PFX_FLAGS)
+			putc(BY_NOFLAGS, fd);		/* <byte> */
+		    else
+		    {
+			putc(BY_FLAGS, fd);		/* <byte> */
+			putc(np->wn_flags, fd);		/* <pflags> */
+		    }
+		    putc(np->wn_affixID, fd);		/* <affixID> */
+		    put_bytes(fd, (long_u)np->wn_region, 2); /* <prefcondnr> */
+		}
+		else
+		{
+		    /* For word trees we write the flag/region items. */
+		    flags = np->wn_flags;
+		    if (regionmask != 0 && np->wn_region != regionmask)
+			flags |= WF_REGION;
+		    if (np->wn_affixID != 0)
+			flags |= WF_AFX;
+		    if (flags == 0)
+		    {
+			/* word without flags or region */
+			putc(BY_NOFLAGS, fd);			/* <byte> */
+		    }
+		    else
+		    {
+			if (np->wn_flags >= 0x100)
+			{
+			    putc(BY_FLAGS2, fd);		/* <byte> */
+			    putc(flags, fd);			/* <flags> */
+			    putc((unsigned)flags >> 8, fd);	/* <flags2> */
+			}
+			else
+			{
+			    putc(BY_FLAGS, fd);			/* <byte> */
+			    putc(flags, fd);			/* <flags> */
+			}
+			if (flags & WF_REGION)
+			    putc(np->wn_region, fd);		/* <region> */
+			if (flags & WF_AFX)
+			    putc(np->wn_affixID, fd);		/* <affixID> */
+		    }
+		}
+	    }
+	}
+	else
+	{
+	    if (np->wn_child->wn_u1.index != 0
+					 && np->wn_child->wn_u2.wnode != node)
+	    {
+		/* The child is written elsewhere, write the reference. */
+		if (fd != NULL)
+		{
+		    putc(BY_INDEX, fd);			/* <byte> */
+							/* <nodeidx> */
+		    put_bytes(fd, (long_u)np->wn_child->wn_u1.index, 3);
+		}
+	    }
+	    else if (np->wn_child->wn_u2.wnode == NULL)
+		/* We will write the child below and give it an index. */
+		np->wn_child->wn_u2.wnode = node;
+
+	    if (fd != NULL)
+		if (putc(np->wn_byte, fd) == EOF) /* <byte> or <xbyte> */
+		{
+		    EMSG(_(e_write));
+		    return 0;
+		}
+	}
+    }
+
+    /* Space used in the array when reading: one for each sibling and one for
+     * the count. */
+    newindex += siblingcount + 1;
+
+    /* Recursively dump the children of each sibling. */
+    for (np = node; np != NULL; np = np->wn_sibling)
+	if (np->wn_byte != 0 && np->wn_child->wn_u2.wnode == node)
+	    newindex = put_node(fd, np->wn_child, newindex, regionmask,
+								  prefixtree);
+
+    return newindex;
+}
+
+
+/*
+ * ":mkspell [-ascii] outfile  infile ..."
+ * ":mkspell [-ascii] addfile"
+ */
+    void
+ex_mkspell(eap)
+    exarg_T *eap;
+{
+    int		fcount;
+    char_u	**fnames;
+    char_u	*arg = eap->arg;
+    int		ascii = FALSE;
+
+    if (STRNCMP(arg, "-ascii", 6) == 0)
+    {
+	ascii = TRUE;
+	arg = skipwhite(arg + 6);
+    }
+
+    /* Expand all the remaining arguments (e.g., $VIMRUNTIME). */
+    if (get_arglist_exp(arg, &fcount, &fnames) == OK)
+    {
+	mkspell(fcount, fnames, ascii, eap->forceit, FALSE);
+	FreeWild(fcount, fnames);
+    }
+}
+
+/*
+ * Create the .sug file.
+ * Uses the soundfold info in "spin".
+ * Writes the file with the name "wfname", with ".spl" changed to ".sug".
+ */
+    static void
+spell_make_sugfile(spin, wfname)
+    spellinfo_T	*spin;
+    char_u	*wfname;
+{
+    char_u	fname[MAXPATHL];
+    int		len;
+    slang_T	*slang;
+    int		free_slang = FALSE;
+
+    /*
+     * Read back the .spl file that was written.  This fills the required
+     * info for soundfolding.  This also uses less memory than the
+     * pointer-linked version of the trie.  And it avoids having two versions
+     * of the code for the soundfolding stuff.
+     * It might have been done already by spell_reload_one().
+     */
+    for (slang = first_lang; slang != NULL; slang = slang->sl_next)
+	if (fullpathcmp(wfname, slang->sl_fname, FALSE) == FPC_SAME)
+	    break;
+    if (slang == NULL)
+    {
+	spell_message(spin, (char_u *)_("Reading back spell file..."));
+	slang = spell_load_file(wfname, NULL, NULL, FALSE);
+	if (slang == NULL)
+	    return;
+	free_slang = TRUE;
+    }
+
+    /*
+     * Clear the info in "spin" that is used.
+     */
+    spin->si_blocks = NULL;
+    spin->si_blocks_cnt = 0;
+    spin->si_compress_cnt = 0;	    /* will stay at 0 all the time*/
+    spin->si_free_count = 0;
+    spin->si_first_free = NULL;
+    spin->si_foldwcount = 0;
+
+    /*
+     * Go through the trie of good words, soundfold each word and add it to
+     * the soundfold trie.
+     */
+    spell_message(spin, (char_u *)_("Performing soundfolding..."));
+    if (sug_filltree(spin, slang) == FAIL)
+	goto theend;
+
+    /*
+     * Create the table which links each soundfold word with a list of the
+     * good words it may come from.  Creates buffer "spin->si_spellbuf".
+     * This also removes the wordnr from the NUL byte entries to make
+     * compression possible.
+     */
+    if (sug_maketable(spin) == FAIL)
+	goto theend;
+
+    smsg((char_u *)_("Number of words after soundfolding: %ld"),
+				 (long)spin->si_spellbuf->b_ml.ml_line_count);
+
+    /*
+     * Compress the soundfold trie.
+     */
+    spell_message(spin, (char_u *)_(msg_compressing));
+    wordtree_compress(spin, spin->si_foldroot);
+
+    /*
+     * Write the .sug file.
+     * Make the file name by changing ".spl" to ".sug".
+     */
+    STRCPY(fname, wfname);
+    len = (int)STRLEN(fname);
+    fname[len - 2] = 'u';
+    fname[len - 1] = 'g';
+    sug_write(spin, fname);
+
+theend:
+    if (free_slang)
+	slang_free(slang);
+    free_blocks(spin->si_blocks);
+    close_spellbuf(spin->si_spellbuf);
+}
+
+/*
+ * Build the soundfold trie for language "slang".
+ */
+    static int
+sug_filltree(spin, slang)
+    spellinfo_T	*spin;
+    slang_T	*slang;
+{
+    char_u	*byts;
+    idx_T	*idxs;
+    int		depth;
+    idx_T	arridx[MAXWLEN];
+    int		curi[MAXWLEN];
+    char_u	tword[MAXWLEN];
+    char_u	tsalword[MAXWLEN];
+    int		c;
+    idx_T	n;
+    unsigned	words_done = 0;
+    int		wordcount[MAXWLEN];
+
+    /* We use si_foldroot for the souldfolded trie. */
+    spin->si_foldroot = wordtree_alloc(spin);
+    if (spin->si_foldroot == NULL)
+	return FAIL;
+
+    /* let tree_add_word() know we're adding to the soundfolded tree */
+    spin->si_sugtree = TRUE;
+
+    /*
+     * Go through the whole case-folded tree, soundfold each word and put it
+     * in the trie.
+     */
+    byts = slang->sl_fbyts;
+    idxs = slang->sl_fidxs;
+
+    arridx[0] = 0;
+    curi[0] = 1;
+    wordcount[0] = 0;
+
+    depth = 0;
+    while (depth >= 0 && !got_int)
+    {
+	if (curi[depth] > byts[arridx[depth]])
+	{
+	    /* Done all bytes at this node, go up one level. */
+	    idxs[arridx[depth]] = wordcount[depth];
+	    if (depth > 0)
+		wordcount[depth - 1] += wordcount[depth];
+
+	    --depth;
+	    line_breakcheck();
+	}
+	else
+	{
+
+	    /* Do one more byte at this node. */
+	    n = arridx[depth] + curi[depth];
+	    ++curi[depth];
+
+	    c = byts[n];
+	    if (c == 0)
+	    {
+		/* Sound-fold the word. */
+		tword[depth] = NUL;
+		spell_soundfold(slang, tword, TRUE, tsalword);
+
+		/* We use the "flags" field for the MSB of the wordnr,
+		 * "region" for the LSB of the wordnr.  */
+		if (tree_add_word(spin, tsalword, spin->si_foldroot,
+				words_done >> 16, words_done & 0xffff,
+							   0) == FAIL)
+		    return FAIL;
+
+		++words_done;
+		++wordcount[depth];
+
+		/* Reset the block count each time to avoid compression
+		 * kicking in. */
+		spin->si_blocks_cnt = 0;
+
+		/* Skip over any other NUL bytes (same word with different
+		 * flags). */
+		while (byts[n + 1] == 0)
+		{
+		    ++n;
+		    ++curi[depth];
+		}
+	    }
+	    else
+	    {
+		/* Normal char, go one level deeper. */
+		tword[depth++] = c;
+		arridx[depth] = idxs[n];
+		curi[depth] = 1;
+		wordcount[depth] = 0;
+	    }
+	}
+    }
+
+    smsg((char_u *)_("Total number of words: %d"), words_done);
+
+    return OK;
+}
+
+/*
+ * Make the table that links each word in the soundfold trie to the words it
+ * can be produced from.
+ * This is not unlike lines in a file, thus use a memfile to be able to access
+ * the table efficiently.
+ * Returns FAIL when out of memory.
+ */
+    static int
+sug_maketable(spin)
+    spellinfo_T	*spin;
+{
+    garray_T	ga;
+    int		res = OK;
+
+    /* Allocate a buffer, open a memline for it and create the swap file
+     * (uses a temp file, not a .swp file). */
+    spin->si_spellbuf = open_spellbuf();
+    if (spin->si_spellbuf == NULL)
+	return FAIL;
+
+    /* Use a buffer to store the line info, avoids allocating many small
+     * pieces of memory. */
+    ga_init2(&ga, 1, 100);
+
+    /* recursively go through the tree */
+    if (sug_filltable(spin, spin->si_foldroot->wn_sibling, 0, &ga) == -1)
+	res = FAIL;
+
+    ga_clear(&ga);
+    return res;
+}
+
+/*
+ * Fill the table for one node and its children.
+ * Returns the wordnr at the start of the node.
+ * Returns -1 when out of memory.
+ */
+    static int
+sug_filltable(spin, node, startwordnr, gap)
+    spellinfo_T	*spin;
+    wordnode_T	*node;
+    int		startwordnr;
+    garray_T	*gap;	    /* place to store line of numbers */
+{
+    wordnode_T	*p, *np;
+    int		wordnr = startwordnr;
+    int		nr;
+    int		prev_nr;
+
+    for (p = node; p != NULL; p = p->wn_sibling)
+    {
+	if (p->wn_byte == NUL)
+	{
+	    gap->ga_len = 0;
+	    prev_nr = 0;
+	    for (np = p; np != NULL && np->wn_byte == NUL; np = np->wn_sibling)
+	    {
+		if (ga_grow(gap, 10) == FAIL)
+		    return -1;
+
+		nr = (np->wn_flags << 16) + (np->wn_region & 0xffff);
+		/* Compute the offset from the previous nr and store the
+		 * offset in a way that it takes a minimum number of bytes.
+		 * It's a bit like utf-8, but without the need to mark
+		 * following bytes. */
+		nr -= prev_nr;
+		prev_nr += nr;
+		gap->ga_len += offset2bytes(nr,
+					 (char_u *)gap->ga_data + gap->ga_len);
+	    }
+
+	    /* add the NUL byte */
+	    ((char_u *)gap->ga_data)[gap->ga_len++] = NUL;
+
+	    if (ml_append_buf(spin->si_spellbuf, (linenr_T)wordnr,
+				     gap->ga_data, gap->ga_len, TRUE) == FAIL)
+		return -1;
+	    ++wordnr;
+
+	    /* Remove extra NUL entries, we no longer need them. We don't
+	     * bother freeing the nodes, the won't be reused anyway. */
+	    while (p->wn_sibling != NULL && p->wn_sibling->wn_byte == NUL)
+		p->wn_sibling = p->wn_sibling->wn_sibling;
+
+	    /* Clear the flags on the remaining NUL node, so that compression
+	     * works a lot better. */
+	    p->wn_flags = 0;
+	    p->wn_region = 0;
+	}
+	else
+	{
+	    wordnr = sug_filltable(spin, p->wn_child, wordnr, gap);
+	    if (wordnr == -1)
+		return -1;
+	}
+    }
+    return wordnr;
+}
+
+/*
+ * Convert an offset into a minimal number of bytes.
+ * Similar to utf_char2byters, but use 8 bits in followup bytes and avoid NUL
+ * bytes.
+ */
+    static int
+offset2bytes(nr, buf)
+    int	    nr;
+    char_u  *buf;
+{
+    int	    rem;
+    int	    b1, b2, b3, b4;
+
+    /* Split the number in parts of base 255.  We need to avoid NUL bytes. */
+    b1 = nr % 255 + 1;
+    rem = nr / 255;
+    b2 = rem % 255 + 1;
+    rem = rem / 255;
+    b3 = rem % 255 + 1;
+    b4 = rem / 255 + 1;
+
+    if (b4 > 1 || b3 > 0x1f)	/* 4 bytes */
+    {
+	buf[0] = 0xe0 + b4;
+	buf[1] = b3;
+	buf[2] = b2;
+	buf[3] = b1;
+	return 4;
+    }
+    if (b3 > 1 || b2 > 0x3f )	/* 3 bytes */
+    {
+	buf[0] = 0xc0 + b3;
+	buf[1] = b2;
+	buf[2] = b1;
+	return 3;
+    }
+    if (b2 > 1 || b1 > 0x7f )	/* 2 bytes */
+    {
+	buf[0] = 0x80 + b2;
+	buf[1] = b1;
+	return 2;
+    }
+				/* 1 byte */
+    buf[0] = b1;
+    return 1;
+}
+
+/*
+ * Opposite of offset2bytes().
+ * "pp" points to the bytes and is advanced over it.
+ * Returns the offset.
+ */
+    static int
+bytes2offset(pp)
+    char_u	**pp;
+{
+    char_u	*p = *pp;
+    int		nr;
+    int		c;
+
+    c = *p++;
+    if ((c & 0x80) == 0x00)		/* 1 byte */
+    {
+	nr = c - 1;
+    }
+    else if ((c & 0xc0) == 0x80)	/* 2 bytes */
+    {
+	nr = (c & 0x3f) - 1;
+	nr = nr * 255 + (*p++ - 1);
+    }
+    else if ((c & 0xe0) == 0xc0)	/* 3 bytes */
+    {
+	nr = (c & 0x1f) - 1;
+	nr = nr * 255 + (*p++ - 1);
+	nr = nr * 255 + (*p++ - 1);
+    }
+    else				/* 4 bytes */
+    {
+	nr = (c & 0x0f) - 1;
+	nr = nr * 255 + (*p++ - 1);
+	nr = nr * 255 + (*p++ - 1);
+	nr = nr * 255 + (*p++ - 1);
+    }
+
+    *pp = p;
+    return nr;
+}
+
+/*
+ * Write the .sug file in "fname".
+ */
+    static void
+sug_write(spin, fname)
+    spellinfo_T	*spin;
+    char_u	*fname;
+{
+    FILE	*fd;
+    wordnode_T	*tree;
+    int		nodecount;
+    int		wcount;
+    char_u	*line;
+    linenr_T	lnum;
+    int		len;
+
+    /* Create the file.  Note that an existing file is silently overwritten! */
+    fd = mch_fopen((char *)fname, "w");
+    if (fd == NULL)
+    {
+	EMSG2(_(e_notopen), fname);
+	return;
+    }
+
+    vim_snprintf((char *)IObuff, IOSIZE,
+				  _("Writing suggestion file %s ..."), fname);
+    spell_message(spin, IObuff);
+
+    /*
+     * <SUGHEADER>: <fileID> <versionnr> <timestamp>
+     */
+    if (fwrite(VIMSUGMAGIC, VIMSUGMAGICL, (size_t)1, fd) != 1) /* <fileID> */
+    {
+	EMSG(_(e_write));
+	goto theend;
+    }
+    putc(VIMSUGVERSION, fd);				/* <versionnr> */
+
+    /* Write si_sugtime to the file. */
+    put_sugtime(spin, fd);				/* <timestamp> */
+
+    /*
+     * <SUGWORDTREE>
+     */
+    spin->si_memtot = 0;
+    tree = spin->si_foldroot->wn_sibling;
+
+    /* Clear the index and wnode fields in the tree. */
+    clear_node(tree);
+
+    /* Count the number of nodes.  Needed to be able to allocate the
+     * memory when reading the nodes.  Also fills in index for shared
+     * nodes. */
+    nodecount = put_node(NULL, tree, 0, 0, FALSE);
+
+    /* number of nodes in 4 bytes */
+    put_bytes(fd, (long_u)nodecount, 4);	/* <nodecount> */
+    spin->si_memtot += nodecount + nodecount * sizeof(int);
+
+    /* Write the nodes. */
+    (void)put_node(fd, tree, 0, 0, FALSE);
+
+    /*
+     * <SUGTABLE>: <sugwcount> <sugline> ...
+     */
+    wcount = spin->si_spellbuf->b_ml.ml_line_count;
+    put_bytes(fd, (long_u)wcount, 4);	/* <sugwcount> */
+
+    for (lnum = 1; lnum <= (linenr_T)wcount; ++lnum)
+    {
+	/* <sugline>: <sugnr> ... NUL */
+	line = ml_get_buf(spin->si_spellbuf, lnum, FALSE);
+	len = (int)STRLEN(line) + 1;
+	if (fwrite(line, (size_t)len, (size_t)1, fd) == 0)
+	{
+	    EMSG(_(e_write));
+	    goto theend;
+	}
+	spin->si_memtot += len;
+    }
+
+    /* Write another byte to check for errors. */
+    if (putc(0, fd) == EOF)
+	EMSG(_(e_write));
+
+    vim_snprintf((char *)IObuff, IOSIZE,
+		 _("Estimated runtime memory use: %d bytes"), spin->si_memtot);
+    spell_message(spin, IObuff);
+
+theend:
+    /* close the file */
+    fclose(fd);
+}
+
+/*
+ * Open a spell buffer.  This is a nameless buffer that is not in the buffer
+ * list and only contains text lines.  Can use a swapfile to reduce memory
+ * use.
+ * Most other fields are invalid!  Esp. watch out for string options being
+ * NULL and there is no undo info.
+ * Returns NULL when out of memory.
+ */
+    static buf_T *
+open_spellbuf()
+{
+    buf_T	*buf;
+
+    buf = (buf_T *)alloc_clear(sizeof(buf_T));
+    if (buf != NULL)
+    {
+	buf->b_spell = TRUE;
+	buf->b_p_swf = TRUE;	/* may create a swap file */
+	ml_open(buf);
+	ml_open_file(buf);	/* create swap file now */
+    }
+    return buf;
+}
+
+/*
+ * Close the buffer used for spell info.
+ */
+    static void
+close_spellbuf(buf)
+    buf_T	*buf;
+{
+    if (buf != NULL)
+    {
+	ml_close(buf, TRUE);
+	vim_free(buf);
+    }
+}
+
+
+/*
+ * Create a Vim spell file from one or more word lists.
+ * "fnames[0]" is the output file name.
+ * "fnames[fcount - 1]" is the last input file name.
+ * Exception: when "fnames[0]" ends in ".add" it's used as the input file name
+ * and ".spl" is appended to make the output file name.
+ */
+    static void
+mkspell(fcount, fnames, ascii, overwrite, added_word)
+    int		fcount;
+    char_u	**fnames;
+    int		ascii;		    /* -ascii argument given */
+    int		overwrite;	    /* overwrite existing output file */
+    int		added_word;	    /* invoked through "zg" */
+{
+    char_u	fname[MAXPATHL];
+    char_u	wfname[MAXPATHL];
+    char_u	**innames;
+    int		incount;
+    afffile_T	*(afile[8]);
+    int		i;
+    int		len;
+    struct stat	st;
+    int		error = FALSE;
+    spellinfo_T spin;
+
+    vim_memset(&spin, 0, sizeof(spin));
+    spin.si_verbose = !added_word;
+    spin.si_ascii = ascii;
+    spin.si_followup = TRUE;
+    spin.si_rem_accents = TRUE;
+    ga_init2(&spin.si_rep, (int)sizeof(fromto_T), 20);
+    ga_init2(&spin.si_repsal, (int)sizeof(fromto_T), 20);
+    ga_init2(&spin.si_sal, (int)sizeof(fromto_T), 20);
+    ga_init2(&spin.si_map, (int)sizeof(char_u), 100);
+    ga_init2(&spin.si_comppat, (int)sizeof(char_u *), 20);
+    ga_init2(&spin.si_prefcond, (int)sizeof(char_u *), 50);
+    hash_init(&spin.si_commonwords);
+    spin.si_newcompID = 127;	/* start compound ID at first maximum */
+
+    /* default: fnames[0] is output file, following are input files */
+    innames = &fnames[1];
+    incount = fcount - 1;
+
+    if (fcount >= 1)
+    {
+	len = (int)STRLEN(fnames[0]);
+	if (fcount == 1 && len > 4 && STRCMP(fnames[0] + len - 4, ".add") == 0)
+	{
+	    /* For ":mkspell path/en.latin1.add" output file is
+	     * "path/en.latin1.add.spl". */
+	    innames = &fnames[0];
+	    incount = 1;
+	    vim_snprintf((char *)wfname, sizeof(wfname), "%s.spl", fnames[0]);
+	}
+	else if (fcount == 1)
+	{
+	    /* For ":mkspell path/vim" output file is "path/vim.latin1.spl". */
+	    innames = &fnames[0];
+	    incount = 1;
+	    vim_snprintf((char *)wfname, sizeof(wfname), "%s.%s.spl", fnames[0],
+			     spin.si_ascii ? (char_u *)"ascii" : spell_enc());
+	}
+	else if (len > 4 && STRCMP(fnames[0] + len - 4, ".spl") == 0)
+	{
+	    /* Name ends in ".spl", use as the file name. */
+	    vim_strncpy(wfname, fnames[0], sizeof(wfname) - 1);
+	}
+	else
+	    /* Name should be language, make the file name from it. */
+	    vim_snprintf((char *)wfname, sizeof(wfname), "%s.%s.spl", fnames[0],
+			     spin.si_ascii ? (char_u *)"ascii" : spell_enc());
+
+	/* Check for .ascii.spl. */
+	if (strstr((char *)gettail(wfname), ".ascii.") != NULL)
+	    spin.si_ascii = TRUE;
+
+	/* Check for .add.spl. */
+	if (strstr((char *)gettail(wfname), ".add.") != NULL)
+	    spin.si_add = TRUE;
+    }
+
+    if (incount <= 0)
+	EMSG(_(e_invarg));	/* need at least output and input names */
+    else if (vim_strchr(gettail(wfname), '_') != NULL)
+	EMSG(_("E751: Output file name must not have region name"));
+    else if (incount > 8)
+	EMSG(_("E754: Only up to 8 regions supported"));
+    else
+    {
+	/* Check for overwriting before doing things that may take a lot of
+	 * time. */
+	if (!overwrite && mch_stat((char *)wfname, &st) >= 0)
+	{
+	    EMSG(_(e_exists));
+	    return;
+	}
+	if (mch_isdir(wfname))
+	{
+	    EMSG2(_(e_isadir2), wfname);
+	    return;
+	}
+
+	/*
+	 * Init the aff and dic pointers.
+	 * Get the region names if there are more than 2 arguments.
+	 */
+	for (i = 0; i < incount; ++i)
+	{
+	    afile[i] = NULL;
+
+	    if (incount > 1)
+	    {
+		len = (int)STRLEN(innames[i]);
+		if (STRLEN(gettail(innames[i])) < 5
+						|| innames[i][len - 3] != '_')
+		{
+		    EMSG2(_("E755: Invalid region in %s"), innames[i]);
+		    return;
+		}
+		spin.si_region_name[i * 2] = TOLOWER_ASC(innames[i][len - 2]);
+		spin.si_region_name[i * 2 + 1] =
+					     TOLOWER_ASC(innames[i][len - 1]);
+	    }
+	}
+	spin.si_region_count = incount;
+
+	spin.si_foldroot = wordtree_alloc(&spin);
+	spin.si_keeproot = wordtree_alloc(&spin);
+	spin.si_prefroot = wordtree_alloc(&spin);
+	if (spin.si_foldroot == NULL
+		|| spin.si_keeproot == NULL
+		|| spin.si_prefroot == NULL)
+	{
+	    free_blocks(spin.si_blocks);
+	    return;
+	}
+
+	/* When not producing a .add.spl file clear the character table when
+	 * we encounter one in the .aff file.  This means we dump the current
+	 * one in the .spl file if the .aff file doesn't define one.  That's
+	 * better than guessing the contents, the table will match a
+	 * previously loaded spell file. */
+	if (!spin.si_add)
+	    spin.si_clear_chartab = TRUE;
+
+	/*
+	 * Read all the .aff and .dic files.
+	 * Text is converted to 'encoding'.
+	 * Words are stored in the case-folded and keep-case trees.
+	 */
+	for (i = 0; i < incount && !error; ++i)
+	{
+	    spin.si_conv.vc_type = CONV_NONE;
+	    spin.si_region = 1 << i;
+
+	    vim_snprintf((char *)fname, sizeof(fname), "%s.aff", innames[i]);
+	    if (mch_stat((char *)fname, &st) >= 0)
+	    {
+		/* Read the .aff file.  Will init "spin->si_conv" based on the
+		 * "SET" line. */
+		afile[i] = spell_read_aff(&spin, fname);
+		if (afile[i] == NULL)
+		    error = TRUE;
+		else
+		{
+		    /* Read the .dic file and store the words in the trees. */
+		    vim_snprintf((char *)fname, sizeof(fname), "%s.dic",
+								  innames[i]);
+		    if (spell_read_dic(&spin, fname, afile[i]) == FAIL)
+			error = TRUE;
+		}
+	    }
+	    else
+	    {
+		/* No .aff file, try reading the file as a word list.  Store
+		 * the words in the trees. */
+		if (spell_read_wordfile(&spin, innames[i]) == FAIL)
+		    error = TRUE;
+	    }
+
+#ifdef FEAT_MBYTE
+	    /* Free any conversion stuff. */
+	    convert_setup(&spin.si_conv, NULL, NULL);
+#endif
+	}
+
+	if (spin.si_compflags != NULL && spin.si_nobreak)
+	    MSG(_("Warning: both compounding and NOBREAK specified"));
+
+	if (!error && !got_int)
+	{
+	    /*
+	     * Combine tails in the tree.
+	     */
+	    spell_message(&spin, (char_u *)_(msg_compressing));
+	    wordtree_compress(&spin, spin.si_foldroot);
+	    wordtree_compress(&spin, spin.si_keeproot);
+	    wordtree_compress(&spin, spin.si_prefroot);
+	}
+
+	if (!error && !got_int)
+	{
+	    /*
+	     * Write the info in the spell file.
+	     */
+	    vim_snprintf((char *)IObuff, IOSIZE,
+				      _("Writing spell file %s ..."), wfname);
+	    spell_message(&spin, IObuff);
+
+	    error = write_vim_spell(&spin, wfname) == FAIL;
+
+	    spell_message(&spin, (char_u *)_("Done!"));
+	    vim_snprintf((char *)IObuff, IOSIZE,
+		 _("Estimated runtime memory use: %d bytes"), spin.si_memtot);
+	    spell_message(&spin, IObuff);
+
+	    /*
+	     * If the file is loaded need to reload it.
+	     */
+	    if (!error)
+		spell_reload_one(wfname, added_word);
+	}
+
+	/* Free the allocated memory. */
+	ga_clear(&spin.si_rep);
+	ga_clear(&spin.si_repsal);
+	ga_clear(&spin.si_sal);
+	ga_clear(&spin.si_map);
+	ga_clear(&spin.si_comppat);
+	ga_clear(&spin.si_prefcond);
+	hash_clear_all(&spin.si_commonwords, 0);
+
+	/* Free the .aff file structures. */
+	for (i = 0; i < incount; ++i)
+	    if (afile[i] != NULL)
+		spell_free_aff(afile[i]);
+
+	/* Free all the bits and pieces at once. */
+	free_blocks(spin.si_blocks);
+
+	/*
+	 * If there is soundfolding info and no NOSUGFILE item create the
+	 * .sug file with the soundfolded word trie.
+	 */
+	if (spin.si_sugtime != 0 && !error && !got_int)
+	    spell_make_sugfile(&spin, wfname);
+
+    }
+}
+
+/*
+ * Display a message for spell file processing when 'verbose' is set or using
+ * ":mkspell".  "str" can be IObuff.
+ */
+    static void
+spell_message(spin, str)
+    spellinfo_T *spin;
+    char_u	*str;
+{
+    if (spin->si_verbose || p_verbose > 2)
+    {
+	if (!spin->si_verbose)
+	    verbose_enter();
+	MSG(str);
+	out_flush();
+	if (!spin->si_verbose)
+	    verbose_leave();
+    }
+}
+
+/*
+ * ":[count]spellgood  {word}"
+ * ":[count]spellwrong  {word}"
+ * ":[count]spellundo  {word}"
+ */
+    void
+ex_spell(eap)
+    exarg_T *eap;
+{
+    spell_add_word(eap->arg, (int)STRLEN(eap->arg), eap->cmdidx == CMD_spellwrong,
+				   eap->forceit ? 0 : (int)eap->line2,
+				   eap->cmdidx == CMD_spellundo);
+}
+
+/*
+ * Add "word[len]" to 'spellfile' as a good or bad word.
+ */
+    void
+spell_add_word(word, len, bad, idx, undo)
+    char_u	*word;
+    int		len;
+    int		bad;
+    int		idx;	    /* "zG" and "zW": zero, otherwise index in
+			       'spellfile' */
+    int		undo;	    /* TRUE for "zug", "zuG", "zuw" and "zuW" */
+{
+    FILE	*fd = NULL;
+    buf_T	*buf = NULL;
+    int		new_spf = FALSE;
+    char_u	*fname;
+    char_u	fnamebuf[MAXPATHL];
+    char_u	line[MAXWLEN * 2];
+    long	fpos, fpos_next = 0;
+    int		i;
+    char_u	*spf;
+
+    if (idx == 0)	    /* use internal wordlist */
+    {
+	if (int_wordlist == NULL)
+	{
+	    int_wordlist = vim_tempname('s');
+	    if (int_wordlist == NULL)
+		return;
+	}
+	fname = int_wordlist;
+    }
+    else
+    {
+	/* If 'spellfile' isn't set figure out a good default value. */
+	if (*curbuf->b_p_spf == NUL)
+	{
+	    init_spellfile();
+	    new_spf = TRUE;
+	}
+
+	if (*curbuf->b_p_spf == NUL)
+	{
+	    EMSG2(_(e_notset), "spellfile");
+	    return;
+	}
+
+	for (spf = curbuf->b_p_spf, i = 1; *spf != NUL; ++i)
+	{
+	    copy_option_part(&spf, fnamebuf, MAXPATHL, ",");
+	    if (i == idx)
+		break;
+	    if (*spf == NUL)
+	    {
+		EMSGN(_("E765: 'spellfile' does not have %ld entries"), idx);
+		return;
+	    }
+	}
+
+	/* Check that the user isn't editing the .add file somewhere. */
+	buf = buflist_findname_exp(fnamebuf);
+	if (buf != NULL && buf->b_ml.ml_mfp == NULL)
+	    buf = NULL;
+	if (buf != NULL && bufIsChanged(buf))
+	{
+	    EMSG(_(e_bufloaded));
+	    return;
+	}
+
+	fname = fnamebuf;
+    }
+
+    if (bad || undo)
+    {
+	/* When the word appears as good word we need to remove that one,
+	 * since its flags sort before the one with WF_BANNED. */
+	fd = mch_fopen((char *)fname, "r");
+	if (fd != NULL)
+	{
+	    while (!vim_fgets(line, MAXWLEN * 2, fd))
+	    {
+		fpos = fpos_next;
+		fpos_next = ftell(fd);
+		if (STRNCMP(word, line, len) == 0
+			&& (line[len] == '/' || line[len] < ' '))
+		{
+		    /* Found duplicate word.  Remove it by writing a '#' at
+		     * the start of the line.  Mixing reading and writing
+		     * doesn't work for all systems, close the file first. */
+		    fclose(fd);
+		    fd = mch_fopen((char *)fname, "r+");
+		    if (fd == NULL)
+			break;
+		    if (fseek(fd, fpos, SEEK_SET) == 0)
+		    {
+			fputc('#', fd);
+			if (undo)
+			{
+			    home_replace(NULL, fname, NameBuff, MAXPATHL, TRUE);
+			    smsg((char_u *)_("Word removed from %s"), NameBuff);
+			}
+		    }
+		    fseek(fd, fpos_next, SEEK_SET);
+		}
+	    }
+	    fclose(fd);
+	}
+    }
+
+    if (!undo)
+    {
+	fd = mch_fopen((char *)fname, "a");
+	if (fd == NULL && new_spf)
+	{
+	    char_u *p;
+
+	    /* We just initialized the 'spellfile' option and can't open the
+	     * file.  We may need to create the "spell" directory first.  We
+	     * already checked the runtime directory is writable in
+	     * init_spellfile(). */
+	    if (!dir_of_file_exists(fname) && (p = gettail_sep(fname)) != fname)
+	    {
+		int c = *p;
+
+		/* The directory doesn't exist.  Try creating it and opening
+		 * the file again. */
+		*p = NUL;
+		vim_mkdir(fname, 0755);
+		*p = c;
+		fd = mch_fopen((char *)fname, "a");
+	    }
+	}
+
+	if (fd == NULL)
+	    EMSG2(_(e_notopen), fname);
+	else
+	{
+	    if (bad)
+		fprintf(fd, "%.*s/!\n", len, word);
+	    else
+		fprintf(fd, "%.*s\n", len, word);
+	    fclose(fd);
+
+	    home_replace(NULL, fname, NameBuff, MAXPATHL, TRUE);
+	    smsg((char_u *)_("Word added to %s"), NameBuff);
+	}
+    }
+
+    if (fd != NULL)
+    {
+	/* Update the .add.spl file. */
+	mkspell(1, &fname, FALSE, TRUE, TRUE);
+
+	/* If the .add file is edited somewhere, reload it. */
+	if (buf != NULL)
+	    buf_reload(buf, buf->b_orig_mode);
+
+	redraw_all_later(SOME_VALID);
+    }
+}
+
+/*
+ * Initialize 'spellfile' for the current buffer.
+ */
+    static void
+init_spellfile()
+{
+    char_u	buf[MAXPATHL];
+    int		l;
+    char_u	*fname;
+    char_u	*rtp;
+    char_u	*lend;
+    int		aspath = FALSE;
+    char_u	*lstart = curbuf->b_p_spl;
+
+    if (*curbuf->b_p_spl != NUL && curbuf->b_langp.ga_len > 0)
+    {
+	/* Find the end of the language name.  Exclude the region.  If there
+	 * is a path separator remember the start of the tail. */
+	for (lend = curbuf->b_p_spl; *lend != NUL
+			&& vim_strchr((char_u *)",._", *lend) == NULL; ++lend)
+	    if (vim_ispathsep(*lend))
+	    {
+		aspath = TRUE;
+		lstart = lend + 1;
+	    }
+
+	/* Loop over all entries in 'runtimepath'.  Use the first one where we
+	 * are allowed to write. */
+	rtp = p_rtp;
+	while (*rtp != NUL)
+	{
+	    if (aspath)
+		/* Use directory of an entry with path, e.g., for
+		 * "/dir/lg.utf-8.spl" use "/dir". */
+		vim_strncpy(buf, curbuf->b_p_spl, lstart - curbuf->b_p_spl - 1);
+	    else
+		/* Copy the path from 'runtimepath' to buf[]. */
+		copy_option_part(&rtp, buf, MAXPATHL, ",");
+	    if (filewritable(buf) == 2)
+	    {
+		/* Use the first language name from 'spelllang' and the
+		 * encoding used in the first loaded .spl file. */
+		if (aspath)
+		    vim_strncpy(buf, curbuf->b_p_spl, lend - curbuf->b_p_spl);
+		else
+		{
+		    /* Create the "spell" directory if it doesn't exist yet. */
+		    l = (int)STRLEN(buf);
+		    vim_snprintf((char *)buf + l, MAXPATHL - l, "/spell");
+		    if (!filewritable(buf) != 2)
+			vim_mkdir(buf, 0755);
+
+		    l = (int)STRLEN(buf);
+		    vim_snprintf((char *)buf + l, MAXPATHL - l,
+				 "/%.*s", (int)(lend - lstart), lstart);
+		}
+		l = (int)STRLEN(buf);
+		fname = LANGP_ENTRY(curbuf->b_langp, 0)->lp_slang->sl_fname;
+		vim_snprintf((char *)buf + l, MAXPATHL - l, ".%s.add",
+			fname != NULL
+			  && strstr((char *)gettail(fname), ".ascii.") != NULL
+				       ? (char_u *)"ascii" : spell_enc());
+		set_option_value((char_u *)"spellfile", 0L, buf, OPT_LOCAL);
+		break;
+	    }
+	    aspath = FALSE;
+	}
+    }
+}
+
+
+/*
+ * Init the chartab used for spelling for ASCII.
+ * EBCDIC is not supported!
+ */
+    static void
+clear_spell_chartab(sp)
+    spelltab_T	*sp;
+{
+    int		i;
+
+    /* Init everything to FALSE. */
+    vim_memset(sp->st_isw, FALSE, sizeof(sp->st_isw));
+    vim_memset(sp->st_isu, FALSE, sizeof(sp->st_isu));
+    for (i = 0; i < 256; ++i)
+    {
+	sp->st_fold[i] = i;
+	sp->st_upper[i] = i;
+    }
+
+    /* We include digits.  A word shouldn't start with a digit, but handling
+     * that is done separately. */
+    for (i = '0'; i <= '9'; ++i)
+	sp->st_isw[i] = TRUE;
+    for (i = 'A'; i <= 'Z'; ++i)
+    {
+	sp->st_isw[i] = TRUE;
+	sp->st_isu[i] = TRUE;
+	sp->st_fold[i] = i + 0x20;
+    }
+    for (i = 'a'; i <= 'z'; ++i)
+    {
+	sp->st_isw[i] = TRUE;
+	sp->st_upper[i] = i - 0x20;
+    }
+}
+
+/*
+ * Init the chartab used for spelling.  Only depends on 'encoding'.
+ * Called once while starting up and when 'encoding' changes.
+ * The default is to use isalpha(), but the spell file should define the word
+ * characters to make it possible that 'encoding' differs from the current
+ * locale.  For utf-8 we don't use isalpha() but our own functions.
+ */
+    void
+init_spell_chartab()
+{
+    int	    i;
+
+    did_set_spelltab = FALSE;
+    clear_spell_chartab(&spelltab);
+#ifdef FEAT_MBYTE
+    if (enc_dbcs)
+    {
+	/* DBCS: assume double-wide characters are word characters. */
+	for (i = 128; i <= 255; ++i)
+	    if (MB_BYTE2LEN(i) == 2)
+		spelltab.st_isw[i] = TRUE;
+    }
+    else if (enc_utf8)
+    {
+	for (i = 128; i < 256; ++i)
+	{
+	    spelltab.st_isu[i] = utf_isupper(i);
+	    spelltab.st_isw[i] = spelltab.st_isu[i] || utf_islower(i);
+	    spelltab.st_fold[i] = utf_fold(i);
+	    spelltab.st_upper[i] = utf_toupper(i);
+	}
+    }
+    else
+#endif
+    {
+	/* Rough guess: use locale-dependent library functions. */
+	for (i = 128; i < 256; ++i)
+	{
+	    if (MB_ISUPPER(i))
+	    {
+		spelltab.st_isw[i] = TRUE;
+		spelltab.st_isu[i] = TRUE;
+		spelltab.st_fold[i] = MB_TOLOWER(i);
+	    }
+	    else if (MB_ISLOWER(i))
+	    {
+		spelltab.st_isw[i] = TRUE;
+		spelltab.st_upper[i] = MB_TOUPPER(i);
+	    }
+	}
+    }
+}
+
+/*
+ * Set the spell character tables from strings in the affix file.
+ */
+    static int
+set_spell_chartab(fol, low, upp)
+    char_u	*fol;
+    char_u	*low;
+    char_u	*upp;
+{
+    /* We build the new tables here first, so that we can compare with the
+     * previous one. */
+    spelltab_T	new_st;
+    char_u	*pf = fol, *pl = low, *pu = upp;
+    int		f, l, u;
+
+    clear_spell_chartab(&new_st);
+
+    while (*pf != NUL)
+    {
+	if (*pl == NUL || *pu == NUL)
+	{
+	    EMSG(_(e_affform));
+	    return FAIL;
+	}
+#ifdef FEAT_MBYTE
+	f = mb_ptr2char_adv(&pf);
+	l = mb_ptr2char_adv(&pl);
+	u = mb_ptr2char_adv(&pu);
+#else
+	f = *pf++;
+	l = *pl++;
+	u = *pu++;
+#endif
+	/* Every character that appears is a word character. */
+	if (f < 256)
+	    new_st.st_isw[f] = TRUE;
+	if (l < 256)
+	    new_st.st_isw[l] = TRUE;
+	if (u < 256)
+	    new_st.st_isw[u] = TRUE;
+
+	/* if "LOW" and "FOL" are not the same the "LOW" char needs
+	 * case-folding */
+	if (l < 256 && l != f)
+	{
+	    if (f >= 256)
+	    {
+		EMSG(_(e_affrange));
+		return FAIL;
+	    }
+	    new_st.st_fold[l] = f;
+	}
+
+	/* if "UPP" and "FOL" are not the same the "UPP" char needs
+	 * case-folding, it's upper case and the "UPP" is the upper case of
+	 * "FOL" . */
+	if (u < 256 && u != f)
+	{
+	    if (f >= 256)
+	    {
+		EMSG(_(e_affrange));
+		return FAIL;
+	    }
+	    new_st.st_fold[u] = f;
+	    new_st.st_isu[u] = TRUE;
+	    new_st.st_upper[f] = u;
+	}
+    }
+
+    if (*pl != NUL || *pu != NUL)
+    {
+	EMSG(_(e_affform));
+	return FAIL;
+    }
+
+    return set_spell_finish(&new_st);
+}
+
+/*
+ * Set the spell character tables from strings in the .spl file.
+ */
+    static void
+set_spell_charflags(flags, cnt, fol)
+    char_u	*flags;
+    int		cnt;	    /* length of "flags" */
+    char_u	*fol;
+{
+    /* We build the new tables here first, so that we can compare with the
+     * previous one. */
+    spelltab_T	new_st;
+    int		i;
+    char_u	*p = fol;
+    int		c;
+
+    clear_spell_chartab(&new_st);
+
+    for (i = 0; i < 128; ++i)
+    {
+	if (i < cnt)
+	{
+	    new_st.st_isw[i + 128] = (flags[i] & CF_WORD) != 0;
+	    new_st.st_isu[i + 128] = (flags[i] & CF_UPPER) != 0;
+	}
+
+	if (*p != NUL)
+	{
+#ifdef FEAT_MBYTE
+	    c = mb_ptr2char_adv(&p);
+#else
+	    c = *p++;
+#endif
+	    new_st.st_fold[i + 128] = c;
+	    if (i + 128 != c && new_st.st_isu[i + 128] && c < 256)
+		new_st.st_upper[c] = i + 128;
+	}
+    }
+
+    (void)set_spell_finish(&new_st);
+}
+
+    static int
+set_spell_finish(new_st)
+    spelltab_T	*new_st;
+{
+    int		i;
+
+    if (did_set_spelltab)
+    {
+	/* check that it's the same table */
+	for (i = 0; i < 256; ++i)
+	{
+	    if (spelltab.st_isw[i] != new_st->st_isw[i]
+		    || spelltab.st_isu[i] != new_st->st_isu[i]
+		    || spelltab.st_fold[i] != new_st->st_fold[i]
+		    || spelltab.st_upper[i] != new_st->st_upper[i])
+	    {
+		EMSG(_("E763: Word characters differ between spell files"));
+		return FAIL;
+	    }
+	}
+    }
+    else
+    {
+	/* copy the new spelltab into the one being used */
+	spelltab = *new_st;
+	did_set_spelltab = TRUE;
+    }
+
+    return OK;
+}
+
+/*
+ * Return TRUE if "p" points to a word character.
+ * As a special case we see "midword" characters as word character when it is
+ * followed by a word character.  This finds they'there but not 'they there'.
+ * Thus this only works properly when past the first character of the word.
+ */
+    static int
+spell_iswordp(p, buf)
+    char_u	*p;
+    buf_T	*buf;	    /* buffer used */
+{
+#ifdef FEAT_MBYTE
+    char_u	*s;
+    int		l;
+    int		c;
+
+    if (has_mbyte)
+    {
+	l = MB_BYTE2LEN(*p);
+	s = p;
+	if (l == 1)
+	{
+	    /* be quick for ASCII */
+	    if (buf->b_spell_ismw[*p])
+	    {
+		s = p + 1;		/* skip a mid-word character */
+		l = MB_BYTE2LEN(*s);
+	    }
+	}
+	else
+	{
+	    c = mb_ptr2char(p);
+	    if (c < 256 ? buf->b_spell_ismw[c]
+		    : (buf->b_spell_ismw_mb != NULL
+			   && vim_strchr(buf->b_spell_ismw_mb, c) != NULL))
+	    {
+		s = p + l;
+		l = MB_BYTE2LEN(*s);
+	    }
+	}
+
+	c = mb_ptr2char(s);
+	if (c > 255)
+	    return mb_get_class(s) >= 2;
+	return spelltab.st_isw[c];
+    }
+#endif
+
+    return spelltab.st_isw[buf->b_spell_ismw[*p] ? p[1] : p[0]];
+}
+
+/*
+ * Return TRUE if "p" points to a word character.
+ * Unlike spell_iswordp() this doesn't check for "midword" characters.
+ */
+    static int
+spell_iswordp_nmw(p)
+    char_u	*p;
+{
+#ifdef FEAT_MBYTE
+    int		c;
+
+    if (has_mbyte)
+    {
+	c = mb_ptr2char(p);
+	if (c > 255)
+	    return mb_get_class(p) >= 2;
+	return spelltab.st_isw[c];
+    }
+#endif
+    return spelltab.st_isw[*p];
+}
+
+#ifdef FEAT_MBYTE
+/*
+ * Return TRUE if "p" points to a word character.
+ * Wide version of spell_iswordp().
+ */
+    static int
+spell_iswordp_w(p, buf)
+    int		*p;
+    buf_T	*buf;
+{
+    int		*s;
+
+    if (*p < 256 ? buf->b_spell_ismw[*p]
+		 : (buf->b_spell_ismw_mb != NULL
+			     && vim_strchr(buf->b_spell_ismw_mb, *p) != NULL))
+	s = p + 1;
+    else
+	s = p;
+
+    if (*s > 255)
+    {
+	if (enc_utf8)
+	    return utf_class(*s) >= 2;
+	if (enc_dbcs)
+	    return dbcs_class((unsigned)*s >> 8, *s & 0xff) >= 2;
+	return 0;
+    }
+    return spelltab.st_isw[*s];
+}
+#endif
+
+/*
+ * Write the table with prefix conditions to the .spl file.
+ * When "fd" is NULL only count the length of what is written.
+ */
+    static int
+write_spell_prefcond(fd, gap)
+    FILE	*fd;
+    garray_T	*gap;
+{
+    int		i;
+    char_u	*p;
+    int		len;
+    int		totlen;
+
+    if (fd != NULL)
+	put_bytes(fd, (long_u)gap->ga_len, 2);	    /* <prefcondcnt> */
+
+    totlen = 2 + gap->ga_len; /* length of <prefcondcnt> and <condlen> bytes */
+
+    for (i = 0; i < gap->ga_len; ++i)
+    {
+	/* <prefcond> : <condlen> <condstr> */
+	p = ((char_u **)gap->ga_data)[i];
+	if (p != NULL)
+	{
+	    len = (int)STRLEN(p);
+	    if (fd != NULL)
+	    {
+		fputc(len, fd);
+		fwrite(p, (size_t)len, (size_t)1, fd);
+	    }
+	    totlen += len;
+	}
+	else if (fd != NULL)
+	    fputc(0, fd);
+    }
+
+    return totlen;
+}
+
+/*
+ * Case-fold "str[len]" into "buf[buflen]".  The result is NUL terminated.
+ * Uses the character definitions from the .spl file.
+ * When using a multi-byte 'encoding' the length may change!
+ * Returns FAIL when something wrong.
+ */
+    static int
+spell_casefold(str, len, buf, buflen)
+    char_u	*str;
+    int		len;
+    char_u	*buf;
+    int		buflen;
+{
+    int		i;
+
+    if (len >= buflen)
+    {
+	buf[0] = NUL;
+	return FAIL;		/* result will not fit */
+    }
+
+#ifdef FEAT_MBYTE
+    if (has_mbyte)
+    {
+	int	outi = 0;
+	char_u	*p;
+	int	c;
+
+	/* Fold one character at a time. */
+	for (p = str; p < str + len; )
+	{
+	    if (outi + MB_MAXBYTES > buflen)
+	    {
+		buf[outi] = NUL;
+		return FAIL;
+	    }
+	    c = mb_cptr2char_adv(&p);
+	    outi += mb_char2bytes(SPELL_TOFOLD(c), buf + outi);
+	}
+	buf[outi] = NUL;
+    }
+    else
+#endif
+    {
+	/* Be quick for non-multibyte encodings. */
+	for (i = 0; i < len; ++i)
+	    buf[i] = spelltab.st_fold[str[i]];
+	buf[i] = NUL;
+    }
+
+    return OK;
+}
+
+/* values for sps_flags */
+#define SPS_BEST    1
+#define SPS_FAST    2
+#define SPS_DOUBLE  4
+
+static int sps_flags = SPS_BEST;	/* flags from 'spellsuggest' */
+static int sps_limit = 9999;		/* max nr of suggestions given */
+
+/*
+ * Check the 'spellsuggest' option.  Return FAIL if it's wrong.
+ * Sets "sps_flags" and "sps_limit".
+ */
+    int
+spell_check_sps()
+{
+    char_u	*p;
+    char_u	*s;
+    char_u	buf[MAXPATHL];
+    int		f;
+
+    sps_flags = 0;
+    sps_limit = 9999;
+
+    for (p = p_sps; *p != NUL; )
+    {
+	copy_option_part(&p, buf, MAXPATHL, ",");
+
+	f = 0;
+	if (VIM_ISDIGIT(*buf))
+	{
+	    s = buf;
+	    sps_limit = getdigits(&s);
+	    if (*s != NUL && !VIM_ISDIGIT(*s))
+		f = -1;
+	}
+	else if (STRCMP(buf, "best") == 0)
+	    f = SPS_BEST;
+	else if (STRCMP(buf, "fast") == 0)
+	    f = SPS_FAST;
+	else if (STRCMP(buf, "double") == 0)
+	    f = SPS_DOUBLE;
+	else if (STRNCMP(buf, "expr:", 5) != 0
+		&& STRNCMP(buf, "file:", 5) != 0)
+	    f = -1;
+
+	if (f == -1 || (sps_flags != 0 && f != 0))
+	{
+	    sps_flags = SPS_BEST;
+	    sps_limit = 9999;
+	    return FAIL;
+	}
+	if (f != 0)
+	    sps_flags = f;
+    }
+
+    if (sps_flags == 0)
+	sps_flags = SPS_BEST;
+
+    return OK;
+}
+
+/*
+ * "z?": Find badly spelled word under or after the cursor.
+ * Give suggestions for the properly spelled word.
+ * In Visual mode use the highlighted word as the bad word.
+ * When "count" is non-zero use that suggestion.
+ */
+    void
+spell_suggest(count)
+    int		count;
+{
+    char_u	*line;
+    pos_T	prev_cursor = curwin->w_cursor;
+    char_u	wcopy[MAXWLEN + 2];
+    char_u	*p;
+    int		i;
+    int		c;
+    suginfo_T	sug;
+    suggest_T	*stp;
+    int		mouse_used;
+    int		need_cap;
+    int		limit;
+    int		selected = count;
+    int		badlen = 0;
+
+    if (no_spell_checking(curwin))
+	return;
+
+#ifdef FEAT_VISUAL
+    if (VIsual_active)
+    {
+	/* Use the Visually selected text as the bad word.  But reject
+	 * a multi-line selection. */
+	if (curwin->w_cursor.lnum != VIsual.lnum)
+	{
+	    vim_beep();
+	    return;
+	}
+	badlen = (int)curwin->w_cursor.col - (int)VIsual.col;
+	if (badlen < 0)
+	    badlen = -badlen;
+	else
+	    curwin->w_cursor.col = VIsual.col;
+	++badlen;
+	end_visual_mode();
+    }
+    else
+#endif
+	/* Find the start of the badly spelled word. */
+	if (spell_move_to(curwin, FORWARD, TRUE, TRUE, NULL) == 0
+	    || curwin->w_cursor.col > prev_cursor.col)
+    {
+	/* No bad word or it starts after the cursor: use the word under the
+	 * cursor. */
+	curwin->w_cursor = prev_cursor;
+	line = ml_get_curline();
+	p = line + curwin->w_cursor.col;
+	/* Backup to before start of word. */
+	while (p > line && spell_iswordp_nmw(p))
+	    mb_ptr_back(line, p);
+	/* Forward to start of word. */
+	while (*p != NUL && !spell_iswordp_nmw(p))
+	    mb_ptr_adv(p);
+
+	if (!spell_iswordp_nmw(p))		/* No word found. */
+	{
+	    beep_flush();
+	    return;
+	}
+	curwin->w_cursor.col = (colnr_T)(p - line);
+    }
+
+    /* Get the word and its length. */
+
+    /* Figure out if the word should be capitalised. */
+    need_cap = check_need_cap(curwin->w_cursor.lnum, curwin->w_cursor.col);
+
+    line = ml_get_curline();
+
+    /* Get the list of suggestions.  Limit to 'lines' - 2 or the number in
+     * 'spellsuggest', whatever is smaller. */
+    if (sps_limit > (int)Rows - 2)
+	limit = (int)Rows - 2;
+    else
+	limit = sps_limit;
+    spell_find_suggest(line + curwin->w_cursor.col, badlen, &sug, limit,
+							TRUE, need_cap, TRUE);
+
+    if (sug.su_ga.ga_len == 0)
+	MSG(_("Sorry, no suggestions"));
+    else if (count > 0)
+    {
+	if (count > sug.su_ga.ga_len)
+	    smsg((char_u *)_("Sorry, only %ld suggestions"),
+						      (long)sug.su_ga.ga_len);
+    }
+    else
+    {
+	vim_free(repl_from);
+	repl_from = NULL;
+	vim_free(repl_to);
+	repl_to = NULL;
+
+#ifdef FEAT_RIGHTLEFT
+	/* When 'rightleft' is set the list is drawn right-left. */
+	cmdmsg_rl = curwin->w_p_rl;
+	if (cmdmsg_rl)
+	    msg_col = Columns - 1;
+#endif
+
+	/* List the suggestions. */
+	msg_start();
+	msg_row = Rows - 1;	/* for when 'cmdheight' > 1 */
+	lines_left = Rows;	/* avoid more prompt */
+	vim_snprintf((char *)IObuff, IOSIZE, _("Change \"%.*s\" to:"),
+						sug.su_badlen, sug.su_badptr);
+#ifdef FEAT_RIGHTLEFT
+	if (cmdmsg_rl && STRNCMP(IObuff, "Change", 6) == 0)
+	{
+	    /* And now the rabbit from the high hat: Avoid showing the
+	     * untranslated message rightleft. */
+	    vim_snprintf((char *)IObuff, IOSIZE, ":ot \"%.*s\" egnahC",
+						sug.su_badlen, sug.su_badptr);
+	}
+#endif
+	msg_puts(IObuff);
+	msg_clr_eos();
+	msg_putchar('\n');
+
+	msg_scroll = TRUE;
+	for (i = 0; i < sug.su_ga.ga_len; ++i)
+	{
+	    stp = &SUG(sug.su_ga, i);
+
+	    /* The suggested word may replace only part of the bad word, add
+	     * the not replaced part. */
+	    STRCPY(wcopy, stp->st_word);
+	    if (sug.su_badlen > stp->st_orglen)
+		vim_strncpy(wcopy + stp->st_wordlen,
+					       sug.su_badptr + stp->st_orglen,
+					      sug.su_badlen - stp->st_orglen);
+	    vim_snprintf((char *)IObuff, IOSIZE, "%2d", i + 1);
+#ifdef FEAT_RIGHTLEFT
+	    if (cmdmsg_rl)
+		rl_mirror(IObuff);
+#endif
+	    msg_puts(IObuff);
+
+	    vim_snprintf((char *)IObuff, IOSIZE, " \"%s\"", wcopy);
+	    msg_puts(IObuff);
+
+	    /* The word may replace more than "su_badlen". */
+	    if (sug.su_badlen < stp->st_orglen)
+	    {
+		vim_snprintf((char *)IObuff, IOSIZE, _(" < \"%.*s\""),
+					       stp->st_orglen, sug.su_badptr);
+		msg_puts(IObuff);
+	    }
+
+	    if (p_verbose > 0)
+	    {
+		/* Add the score. */
+		if (sps_flags & (SPS_DOUBLE | SPS_BEST))
+		    vim_snprintf((char *)IObuff, IOSIZE, " (%s%d - %d)",
+			stp->st_salscore ? "s " : "",
+			stp->st_score, stp->st_altscore);
+		else
+		    vim_snprintf((char *)IObuff, IOSIZE, " (%d)",
+			    stp->st_score);
+#ifdef FEAT_RIGHTLEFT
+		if (cmdmsg_rl)
+		    /* Mirror the numbers, but keep the leading space. */
+		    rl_mirror(IObuff + 1);
+#endif
+		msg_advance(30);
+		msg_puts(IObuff);
+	    }
+	    msg_putchar('\n');
+	}
+
+#ifdef FEAT_RIGHTLEFT
+	cmdmsg_rl = FALSE;
+	msg_col = 0;
+#endif
+	/* Ask for choice. */
+	selected = prompt_for_number(&mouse_used);
+	if (mouse_used)
+	    selected -= lines_left;
+	lines_left = Rows;	/* avoid more prompt */
+    }
+
+    if (selected > 0 && selected <= sug.su_ga.ga_len && u_save_cursor() == OK)
+    {
+	/* Save the from and to text for :spellrepall. */
+	stp = &SUG(sug.su_ga, selected - 1);
+	if (sug.su_badlen > stp->st_orglen)
+	{
+	    /* Replacing less than "su_badlen", append the remainder to
+	     * repl_to. */
+	    repl_from = vim_strnsave(sug.su_badptr, sug.su_badlen);
+	    vim_snprintf((char *)IObuff, IOSIZE, "%s%.*s", stp->st_word,
+		    sug.su_badlen - stp->st_orglen,
+					      sug.su_badptr + stp->st_orglen);
+	    repl_to = vim_strsave(IObuff);
+	}
+	else
+	{
+	    /* Replacing su_badlen or more, use the whole word. */
+	    repl_from = vim_strnsave(sug.su_badptr, stp->st_orglen);
+	    repl_to = vim_strsave(stp->st_word);
+	}
+
+	/* Replace the word. */
+	p = alloc((unsigned)STRLEN(line) - stp->st_orglen + stp->st_wordlen + 1);
+	if (p != NULL)
+	{
+	    c = (int)(sug.su_badptr - line);
+	    mch_memmove(p, line, c);
+	    STRCPY(p + c, stp->st_word);
+	    STRCAT(p, sug.su_badptr + stp->st_orglen);
+	    ml_replace(curwin->w_cursor.lnum, p, FALSE);
+	    curwin->w_cursor.col = c;
+
+	    /* For redo we use a change-word command. */
+	    ResetRedobuff();
+	    AppendToRedobuff((char_u *)"ciw");
+	    AppendToRedobuffLit(p + c,
+			    stp->st_wordlen + sug.su_badlen - stp->st_orglen);
+	    AppendCharToRedobuff(ESC);
+
+	    /* After this "p" may be invalid. */
+	    changed_bytes(curwin->w_cursor.lnum, c);
+	}
+    }
+    else
+	curwin->w_cursor = prev_cursor;
+
+    spell_find_cleanup(&sug);
+}
+
+/*
+ * Check if the word at line "lnum" column "col" is required to start with a
+ * capital.  This uses 'spellcapcheck' of the current buffer.
+ */
+    static int
+check_need_cap(lnum, col)
+    linenr_T	lnum;
+    colnr_T	col;
+{
+    int		need_cap = FALSE;
+    char_u	*line;
+    char_u	*line_copy = NULL;
+    char_u	*p;
+    colnr_T	endcol;
+    regmatch_T	regmatch;
+
+    if (curbuf->b_cap_prog == NULL)
+	return FALSE;
+
+    line = ml_get_curline();
+    endcol = 0;
+    if ((int)(skipwhite(line) - line) >= (int)col)
+    {
+	/* At start of line, check if previous line is empty or sentence
+	 * ends there. */
+	if (lnum == 1)
+	    need_cap = TRUE;
+	else
+	{
+	    line = ml_get(lnum - 1);
+	    if (*skipwhite(line) == NUL)
+		need_cap = TRUE;
+	    else
+	    {
+		/* Append a space in place of the line break. */
+		line_copy = concat_str(line, (char_u *)" ");
+		line = line_copy;
+		endcol = (colnr_T)STRLEN(line);
+	    }
+	}
+    }
+    else
+	endcol = col;
+
+    if (endcol > 0)
+    {
+	/* Check if sentence ends before the bad word. */
+	regmatch.regprog = curbuf->b_cap_prog;
+	regmatch.rm_ic = FALSE;
+	p = line + endcol;
+	for (;;)
+	{
+	    mb_ptr_back(line, p);
+	    if (p == line || spell_iswordp_nmw(p))
+		break;
+	    if (vim_regexec(&regmatch, p, 0)
+					 && regmatch.endp[0] == line + endcol)
+	    {
+		need_cap = TRUE;
+		break;
+	    }
+	}
+    }
+
+    vim_free(line_copy);
+
+    return need_cap;
+}
+
+
+/*
+ * ":spellrepall"
+ */
+/*ARGSUSED*/
+    void
+ex_spellrepall(eap)
+    exarg_T *eap;
+{
+    pos_T	pos = curwin->w_cursor;
+    char_u	*frompat;
+    int		addlen;
+    char_u	*line;
+    char_u	*p;
+    int		save_ws = p_ws;
+    linenr_T	prev_lnum = 0;
+
+    if (repl_from == NULL || repl_to == NULL)
+    {
+	EMSG(_("E752: No previous spell replacement"));
+	return;
+    }
+    addlen = (int)(STRLEN(repl_to) - STRLEN(repl_from));
+
+    frompat = alloc((unsigned)STRLEN(repl_from) + 7);
+    if (frompat == NULL)
+	return;
+    sprintf((char *)frompat, "\\V\\<%s\\>", repl_from);
+    p_ws = FALSE;
+
+    sub_nsubs = 0;
+    sub_nlines = 0;
+    curwin->w_cursor.lnum = 0;
+    while (!got_int)
+    {
+	if (do_search(NULL, '/', frompat, 1L, SEARCH_KEEP) == 0
+						   || u_save_cursor() == FAIL)
+	    break;
+
+	/* Only replace when the right word isn't there yet.  This happens
+	 * when changing "etc" to "etc.". */
+	line = ml_get_curline();
+	if (addlen <= 0 || STRNCMP(line + curwin->w_cursor.col,
+					       repl_to, STRLEN(repl_to)) != 0)
+	{
+	    p = alloc((unsigned)STRLEN(line) + addlen + 1);
+	    if (p == NULL)
+		break;
+	    mch_memmove(p, line, curwin->w_cursor.col);
+	    STRCPY(p + curwin->w_cursor.col, repl_to);
+	    STRCAT(p, line + curwin->w_cursor.col + STRLEN(repl_from));
+	    ml_replace(curwin->w_cursor.lnum, p, FALSE);
+	    changed_bytes(curwin->w_cursor.lnum, curwin->w_cursor.col);
+
+	    if (curwin->w_cursor.lnum != prev_lnum)
+	    {
+		++sub_nlines;
+		prev_lnum = curwin->w_cursor.lnum;
+	    }
+	    ++sub_nsubs;
+	}
+	curwin->w_cursor.col += (colnr_T)STRLEN(repl_to);
+    }
+
+    p_ws = save_ws;
+    curwin->w_cursor = pos;
+    vim_free(frompat);
+
+    if (sub_nsubs == 0)
+	EMSG2(_("E753: Not found: %s"), repl_from);
+    else
+	do_sub_msg(FALSE);
+}
+
+/*
+ * Find spell suggestions for "word".  Return them in the growarray "*gap" as
+ * a list of allocated strings.
+ */
+    void
+spell_suggest_list(gap, word, maxcount, need_cap, interactive)
+    garray_T	*gap;
+    char_u	*word;
+    int		maxcount;	/* maximum nr of suggestions */
+    int		need_cap;	/* 'spellcapcheck' matched */
+    int		interactive;
+{
+    suginfo_T	sug;
+    int		i;
+    suggest_T	*stp;
+    char_u	*wcopy;
+
+    spell_find_suggest(word, 0, &sug, maxcount, FALSE, need_cap, interactive);
+
+    /* Make room in "gap". */
+    ga_init2(gap, sizeof(char_u *), sug.su_ga.ga_len + 1);
+    if (ga_grow(gap, sug.su_ga.ga_len) == OK)
+    {
+	for (i = 0; i < sug.su_ga.ga_len; ++i)
+	{
+	    stp = &SUG(sug.su_ga, i);
+
+	    /* The suggested word may replace only part of "word", add the not
+	     * replaced part. */
+	    wcopy = alloc(stp->st_wordlen
+		      + (unsigned)STRLEN(sug.su_badptr + stp->st_orglen) + 1);
+	    if (wcopy == NULL)
+		break;
+	    STRCPY(wcopy, stp->st_word);
+	    STRCPY(wcopy + stp->st_wordlen, sug.su_badptr + stp->st_orglen);
+	    ((char_u **)gap->ga_data)[gap->ga_len++] = wcopy;
+	}
+    }
+
+    spell_find_cleanup(&sug);
+}
+
+/*
+ * Find spell suggestions for the word at the start of "badptr".
+ * Return the suggestions in "su->su_ga".
+ * The maximum number of suggestions is "maxcount".
+ * Note: does use info for the current window.
+ * This is based on the mechanisms of Aspell, but completely reimplemented.
+ */
+    static void
+spell_find_suggest(badptr, badlen, su, maxcount, banbadword, need_cap, interactive)
+    char_u	*badptr;
+    int		badlen;		/* length of bad word or 0 if unknown */
+    suginfo_T	*su;
+    int		maxcount;
+    int		banbadword;	/* don't include badword in suggestions */
+    int		need_cap;	/* word should start with capital */
+    int		interactive;
+{
+    hlf_T	attr = HLF_COUNT;
+    char_u	buf[MAXPATHL];
+    char_u	*p;
+    int		do_combine = FALSE;
+    char_u	*sps_copy;
+#ifdef FEAT_EVAL
+    static int	expr_busy = FALSE;
+#endif
+    int		c;
+    int		i;
+    langp_T	*lp;
+
+    /*
+     * Set the info in "*su".
+     */
+    vim_memset(su, 0, sizeof(suginfo_T));
+    ga_init2(&su->su_ga, (int)sizeof(suggest_T), 10);
+    ga_init2(&su->su_sga, (int)sizeof(suggest_T), 10);
+    if (*badptr == NUL)
+	return;
+    hash_init(&su->su_banned);
+
+    su->su_badptr = badptr;
+    if (badlen != 0)
+	su->su_badlen = badlen;
+    else
+	su->su_badlen = spell_check(curwin, su->su_badptr, &attr, NULL, FALSE);
+    su->su_maxcount = maxcount;
+    su->su_maxscore = SCORE_MAXINIT;
+
+    if (su->su_badlen >= MAXWLEN)
+	su->su_badlen = MAXWLEN - 1;	/* just in case */
+    vim_strncpy(su->su_badword, su->su_badptr, su->su_badlen);
+    (void)spell_casefold(su->su_badptr, su->su_badlen,
+						    su->su_fbadword, MAXWLEN);
+    /* get caps flags for bad word */
+    su->su_badflags = badword_captype(su->su_badptr,
+					       su->su_badptr + su->su_badlen);
+    if (need_cap)
+	su->su_badflags |= WF_ONECAP;
+
+    /* Find the default language for sound folding.  We simply use the first
+     * one in 'spelllang' that supports sound folding.  That's good for when
+     * using multiple files for one language, it's not that bad when mixing
+     * languages (e.g., "pl,en"). */
+    for (i = 0; i < curbuf->b_langp.ga_len; ++i)
+    {
+	lp = LANGP_ENTRY(curbuf->b_langp, i);
+	if (lp->lp_sallang != NULL)
+	{
+	    su->su_sallang = lp->lp_sallang;
+	    break;
+	}
+    }
+
+    /* Soundfold the bad word with the default sound folding, so that we don't
+     * have to do this many times. */
+    if (su->su_sallang != NULL)
+	spell_soundfold(su->su_sallang, su->su_fbadword, TRUE,
+							  su->su_sal_badword);
+
+    /* If the word is not capitalised and spell_check() doesn't consider the
+     * word to be bad then it might need to be capitalised.  Add a suggestion
+     * for that. */
+    c = PTR2CHAR(su->su_badptr);
+    if (!SPELL_ISUPPER(c) && attr == HLF_COUNT)
+    {
+	make_case_word(su->su_badword, buf, WF_ONECAP);
+	add_suggestion(su, &su->su_ga, buf, su->su_badlen, SCORE_ICASE,
+					      0, TRUE, su->su_sallang, FALSE);
+    }
+
+    /* Ban the bad word itself.  It may appear in another region. */
+    if (banbadword)
+	add_banned(su, su->su_badword);
+
+    /* Make a copy of 'spellsuggest', because the expression may change it. */
+    sps_copy = vim_strsave(p_sps);
+    if (sps_copy == NULL)
+	return;
+
+    /* Loop over the items in 'spellsuggest'. */
+    for (p = sps_copy; *p != NUL; )
+    {
+	copy_option_part(&p, buf, MAXPATHL, ",");
+
+	if (STRNCMP(buf, "expr:", 5) == 0)
+	{
+#ifdef FEAT_EVAL
+	    /* Evaluate an expression.  Skip this when called recursively,
+	     * when using spellsuggest() in the expression. */
+	    if (!expr_busy)
+	    {
+		expr_busy = TRUE;
+		spell_suggest_expr(su, buf + 5);
+		expr_busy = FALSE;
+	    }
+#endif
+	}
+	else if (STRNCMP(buf, "file:", 5) == 0)
+	    /* Use list of suggestions in a file. */
+	    spell_suggest_file(su, buf + 5);
+	else
+	{
+	    /* Use internal method. */
+	    spell_suggest_intern(su, interactive);
+	    if (sps_flags & SPS_DOUBLE)
+		do_combine = TRUE;
+	}
+    }
+
+    vim_free(sps_copy);
+
+    if (do_combine)
+	/* Combine the two list of suggestions.  This must be done last,
+	 * because sorting changes the order again. */
+	score_combine(su);
+}
+
+#ifdef FEAT_EVAL
+/*
+ * Find suggestions by evaluating expression "expr".
+ */
+    static void
+spell_suggest_expr(su, expr)
+    suginfo_T	*su;
+    char_u	*expr;
+{
+    list_T	*list;
+    listitem_T	*li;
+    int		score;
+    char_u	*p;
+
+    /* The work is split up in a few parts to avoid having to export
+     * suginfo_T.
+     * First evaluate the expression and get the resulting list. */
+    list = eval_spell_expr(su->su_badword, expr);
+    if (list != NULL)
+    {
+	/* Loop over the items in the list. */
+	for (li = list->lv_first; li != NULL; li = li->li_next)
+	    if (li->li_tv.v_type == VAR_LIST)
+	    {
+		/* Get the word and the score from the items. */
+		score = get_spellword(li->li_tv.vval.v_list, &p);
+		if (score >= 0 && score <= su->su_maxscore)
+		    add_suggestion(su, &su->su_ga, p, su->su_badlen,
+				       score, 0, TRUE, su->su_sallang, FALSE);
+	    }
+	list_unref(list);
+    }
+
+    /* Remove bogus suggestions, sort and truncate at "maxcount". */
+    check_suggestions(su, &su->su_ga);
+    (void)cleanup_suggestions(&su->su_ga, su->su_maxscore, su->su_maxcount);
+}
+#endif
+
+/*
+ * Find suggestions in file "fname".  Used for "file:" in 'spellsuggest'.
+ */
+    static void
+spell_suggest_file(su, fname)
+    suginfo_T	*su;
+    char_u	*fname;
+{
+    FILE	*fd;
+    char_u	line[MAXWLEN * 2];
+    char_u	*p;
+    int		len;
+    char_u	cword[MAXWLEN];
+
+    /* Open the file. */
+    fd = mch_fopen((char *)fname, "r");
+    if (fd == NULL)
+    {
+	EMSG2(_(e_notopen), fname);
+	return;
+    }
+
+    /* Read it line by line. */
+    while (!vim_fgets(line, MAXWLEN * 2, fd) && !got_int)
+    {
+	line_breakcheck();
+
+	p = vim_strchr(line, '/');
+	if (p == NULL)
+	    continue;	    /* No Tab found, just skip the line. */
+	*p++ = NUL;
+	if (STRICMP(su->su_badword, line) == 0)
+	{
+	    /* Match!  Isolate the good word, until CR or NL. */
+	    for (len = 0; p[len] >= ' '; ++len)
+		;
+	    p[len] = NUL;
+
+	    /* If the suggestion doesn't have specific case duplicate the case
+	     * of the bad word. */
+	    if (captype(p, NULL) == 0)
+	    {
+		make_case_word(p, cword, su->su_badflags);
+		p = cword;
+	    }
+
+	    add_suggestion(su, &su->su_ga, p, su->su_badlen,
+				  SCORE_FILE, 0, TRUE, su->su_sallang, FALSE);
+	}
+    }
+
+    fclose(fd);
+
+    /* Remove bogus suggestions, sort and truncate at "maxcount". */
+    check_suggestions(su, &su->su_ga);
+    (void)cleanup_suggestions(&su->su_ga, su->su_maxscore, su->su_maxcount);
+}
+
+/*
+ * Find suggestions for the internal method indicated by "sps_flags".
+ */
+    static void
+spell_suggest_intern(su, interactive)
+    suginfo_T	*su;
+    int		interactive;
+{
+    /*
+     * Load the .sug file(s) that are available and not done yet.
+     */
+    suggest_load_files();
+
+    /*
+     * 1. Try special cases, such as repeating a word: "the the" -> "the".
+     *
+     * Set a maximum score to limit the combination of operations that is
+     * tried.
+     */
+    suggest_try_special(su);
+
+    /*
+     * 2. Try inserting/deleting/swapping/changing a letter, use REP entries
+     *    from the .aff file and inserting a space (split the word).
+     */
+    suggest_try_change(su);
+
+    /* For the resulting top-scorers compute the sound-a-like score. */
+    if (sps_flags & SPS_DOUBLE)
+	score_comp_sal(su);
+
+    /*
+     * 3. Try finding sound-a-like words.
+     */
+    if ((sps_flags & SPS_FAST) == 0)
+    {
+	if (sps_flags & SPS_BEST)
+	    /* Adjust the word score for the suggestions found so far for how
+	     * they sounds like. */
+	    rescore_suggestions(su);
+
+	/*
+	 * While going throught the soundfold tree "su_maxscore" is the score
+	 * for the soundfold word, limits the changes that are being tried,
+	 * and "su_sfmaxscore" the rescored score, which is set by
+	 * cleanup_suggestions().
+	 * First find words with a small edit distance, because this is much
+	 * faster and often already finds the top-N suggestions.  If we didn't
+	 * find many suggestions try again with a higher edit distance.
+	 * "sl_sounddone" is used to avoid doing the same word twice.
+	 */
+	suggest_try_soundalike_prep();
+	su->su_maxscore = SCORE_SFMAX1;
+	su->su_sfmaxscore = SCORE_MAXINIT * 3;
+	suggest_try_soundalike(su);
+	if (su->su_ga.ga_len < SUG_CLEAN_COUNT(su))
+	{
+	    /* We didn't find enough matches, try again, allowing more
+	     * changes to the soundfold word. */
+	    su->su_maxscore = SCORE_SFMAX2;
+	    suggest_try_soundalike(su);
+	    if (su->su_ga.ga_len < SUG_CLEAN_COUNT(su))
+	    {
+		/* Still didn't find enough matches, try again, allowing even
+		 * more changes to the soundfold word. */
+		su->su_maxscore = SCORE_SFMAX3;
+		suggest_try_soundalike(su);
+	    }
+	}
+	su->su_maxscore = su->su_sfmaxscore;
+	suggest_try_soundalike_finish();
+    }
+
+    /* When CTRL-C was hit while searching do show the results.  Only clear
+     * got_int when using a command, not for spellsuggest(). */
+    ui_breakcheck();
+    if (interactive && got_int)
+    {
+	(void)vgetc();
+	got_int = FALSE;
+    }
+
+    if ((sps_flags & SPS_DOUBLE) == 0 && su->su_ga.ga_len != 0)
+    {
+	if (sps_flags & SPS_BEST)
+	    /* Adjust the word score for how it sounds like. */
+	    rescore_suggestions(su);
+
+	/* Remove bogus suggestions, sort and truncate at "maxcount". */
+	check_suggestions(su, &su->su_ga);
+	(void)cleanup_suggestions(&su->su_ga, su->su_maxscore, su->su_maxcount);
+    }
+}
+
+/*
+ * Load the .sug files for languages that have one and weren't loaded yet.
+ */
+    static void
+suggest_load_files()
+{
+    langp_T	*lp;
+    int		lpi;
+    slang_T	*slang;
+    char_u	*dotp;
+    FILE	*fd;
+    char_u	buf[MAXWLEN];
+    int		i;
+    time_t	timestamp;
+    int		wcount;
+    int		wordnr;
+    garray_T	ga;
+    int		c;
+
+    /* Do this for all languages that support sound folding. */
+    for (lpi = 0; lpi < curbuf->b_langp.ga_len; ++lpi)
+    {
+	lp = LANGP_ENTRY(curbuf->b_langp, lpi);
+	slang = lp->lp_slang;
+	if (slang->sl_sugtime != 0 && !slang->sl_sugloaded)
+	{
+	    /* Change ".spl" to ".sug" and open the file.  When the file isn't
+	     * found silently skip it.  Do set "sl_sugloaded" so that we
+	     * don't try again and again. */
+	    slang->sl_sugloaded = TRUE;
+
+	    dotp = vim_strrchr(slang->sl_fname, '.');
+	    if (dotp == NULL || fnamecmp(dotp, ".spl") != 0)
+		continue;
+	    STRCPY(dotp, ".sug");
+	    fd = mch_fopen((char *)slang->sl_fname, "r");
+	    if (fd == NULL)
+		goto nextone;
+
+	    /*
+	     * <SUGHEADER>: <fileID> <versionnr> <timestamp>
+	     */
+	    for (i = 0; i < VIMSUGMAGICL; ++i)
+		buf[i] = getc(fd);			/* <fileID> */
+	    if (STRNCMP(buf, VIMSUGMAGIC, VIMSUGMAGICL) != 0)
+	    {
+		EMSG2(_("E778: This does not look like a .sug file: %s"),
+							     slang->sl_fname);
+		goto nextone;
+	    }
+	    c = getc(fd);				/* <versionnr> */
+	    if (c < VIMSUGVERSION)
+	    {
+		EMSG2(_("E779: Old .sug file, needs to be updated: %s"),
+							     slang->sl_fname);
+		goto nextone;
+	    }
+	    else if (c > VIMSUGVERSION)
+	    {
+		EMSG2(_("E780: .sug file is for newer version of Vim: %s"),
+							     slang->sl_fname);
+		goto nextone;
+	    }
+
+	    /* Check the timestamp, it must be exactly the same as the one in
+	     * the .spl file.  Otherwise the word numbers won't match. */
+	    timestamp = get8c(fd);			/* <timestamp> */
+	    if (timestamp != slang->sl_sugtime)
+	    {
+		EMSG2(_("E781: .sug file doesn't match .spl file: %s"),
+							     slang->sl_fname);
+		goto nextone;
+	    }
+
+	    /*
+	     * <SUGWORDTREE>: <wordtree>
+	     * Read the trie with the soundfolded words.
+	     */
+	    if (spell_read_tree(fd, &slang->sl_sbyts, &slang->sl_sidxs,
+							       FALSE, 0) != 0)
+	    {
+someerror:
+		EMSG2(_("E782: error while reading .sug file: %s"),
+							     slang->sl_fname);
+		slang_clear_sug(slang);
+		goto nextone;
+	    }
+
+	    /*
+	     * <SUGTABLE>: <sugwcount> <sugline> ...
+	     *
+	     * Read the table with word numbers.  We use a file buffer for
+	     * this, because it's so much like a file with lines.  Makes it
+	     * possible to swap the info and save on memory use.
+	     */
+	    slang->sl_sugbuf = open_spellbuf();
+	    if (slang->sl_sugbuf == NULL)
+		goto someerror;
+							    /* <sugwcount> */
+	    wcount = get4c(fd);
+	    if (wcount < 0)
+		goto someerror;
+
+	    /* Read all the wordnr lists into the buffer, one NUL terminated
+	     * list per line. */
+	    ga_init2(&ga, 1, 100);
+	    for (wordnr = 0; wordnr < wcount; ++wordnr)
+	    {
+		ga.ga_len = 0;
+		for (;;)
+		{
+		    c = getc(fd);			    /* <sugline> */
+		    if (c < 0 || ga_grow(&ga, 1) == FAIL)
+			goto someerror;
+		    ((char_u *)ga.ga_data)[ga.ga_len++] = c;
+		    if (c == NUL)
+			break;
+		}
+		if (ml_append_buf(slang->sl_sugbuf, (linenr_T)wordnr,
+					 ga.ga_data, ga.ga_len, TRUE) == FAIL)
+		    goto someerror;
+	    }
+	    ga_clear(&ga);
+
+	    /*
+	     * Need to put word counts in the word tries, so that we can find
+	     * a word by its number.
+	     */
+	    tree_count_words(slang->sl_fbyts, slang->sl_fidxs);
+	    tree_count_words(slang->sl_sbyts, slang->sl_sidxs);
+
+nextone:
+	    if (fd != NULL)
+		fclose(fd);
+	    STRCPY(dotp, ".spl");
+	}
+    }
+}
+
+
+/*
+ * Fill in the wordcount fields for a trie.
+ * Returns the total number of words.
+ */
+    static void
+tree_count_words(byts, idxs)
+    char_u	*byts;
+    idx_T	*idxs;
+{
+    int		depth;
+    idx_T	arridx[MAXWLEN];
+    int		curi[MAXWLEN];
+    int		c;
+    idx_T	n;
+    int		wordcount[MAXWLEN];
+
+    arridx[0] = 0;
+    curi[0] = 1;
+    wordcount[0] = 0;
+    depth = 0;
+    while (depth >= 0 && !got_int)
+    {
+	if (curi[depth] > byts[arridx[depth]])
+	{
+	    /* Done all bytes at this node, go up one level. */
+	    idxs[arridx[depth]] = wordcount[depth];
+	    if (depth > 0)
+		wordcount[depth - 1] += wordcount[depth];
+
+	    --depth;
+	    fast_breakcheck();
+	}
+	else
+	{
+	    /* Do one more byte at this node. */
+	    n = arridx[depth] + curi[depth];
+	    ++curi[depth];
+
+	    c = byts[n];
+	    if (c == 0)
+	    {
+		/* End of word, count it. */
+		++wordcount[depth];
+
+		/* Skip over any other NUL bytes (same word with different
+		 * flags). */
+		while (byts[n + 1] == 0)
+		{
+		    ++n;
+		    ++curi[depth];
+		}
+	    }
+	    else
+	    {
+		/* Normal char, go one level deeper to count the words. */
+		++depth;
+		arridx[depth] = idxs[n];
+		curi[depth] = 1;
+		wordcount[depth] = 0;
+	    }
+	}
+    }
+}
+
+/*
+ * Free the info put in "*su" by spell_find_suggest().
+ */
+    static void
+spell_find_cleanup(su)
+    suginfo_T	*su;
+{
+    int		i;
+
+    /* Free the suggestions. */
+    for (i = 0; i < su->su_ga.ga_len; ++i)
+	vim_free(SUG(su->su_ga, i).st_word);
+    ga_clear(&su->su_ga);
+    for (i = 0; i < su->su_sga.ga_len; ++i)
+	vim_free(SUG(su->su_sga, i).st_word);
+    ga_clear(&su->su_sga);
+
+    /* Free the banned words. */
+    hash_clear_all(&su->su_banned, 0);
+}
+
+/*
+ * Make a copy of "word", with the first letter upper or lower cased, to
+ * "wcopy[MAXWLEN]".  "word" must not be empty.
+ * The result is NUL terminated.
+ */
+    static void
+onecap_copy(word, wcopy, upper)
+    char_u	*word;
+    char_u	*wcopy;
+    int		upper;	    /* TRUE: first letter made upper case */
+{
+    char_u	*p;
+    int		c;
+    int		l;
+
+    p = word;
+#ifdef FEAT_MBYTE
+    if (has_mbyte)
+	c = mb_cptr2char_adv(&p);
+    else
+#endif
+	c = *p++;
+    if (upper)
+	c = SPELL_TOUPPER(c);
+    else
+	c = SPELL_TOFOLD(c);
+#ifdef FEAT_MBYTE
+    if (has_mbyte)
+	l = mb_char2bytes(c, wcopy);
+    else
+#endif
+    {
+	l = 1;
+	wcopy[0] = c;
+    }
+    vim_strncpy(wcopy + l, p, MAXWLEN - l - 1);
+}
+
+/*
+ * Make a copy of "word" with all the letters upper cased into
+ * "wcopy[MAXWLEN]".  The result is NUL terminated.
+ */
+    static void
+allcap_copy(word, wcopy)
+    char_u	*word;
+    char_u	*wcopy;
+{
+    char_u	*s;
+    char_u	*d;
+    int		c;
+
+    d = wcopy;
+    for (s = word; *s != NUL; )
+    {
+#ifdef FEAT_MBYTE
+	if (has_mbyte)
+	    c = mb_cptr2char_adv(&s);
+	else
+#endif
+	    c = *s++;
+
+#ifdef FEAT_MBYTE
+	/* We only change � to SS when we are certain latin1 is used.  It
+	 * would cause weird errors in other 8-bit encodings. */
+	if (enc_latin1like && c == 0xdf)
+	{
+	    c = 'S';
+	    if (d - wcopy >= MAXWLEN - 1)
+		break;
+	    *d++ = c;
+	}
+	else
+#endif
+	    c = SPELL_TOUPPER(c);
+
+#ifdef FEAT_MBYTE
+	if (has_mbyte)
+	{
+	    if (d - wcopy >= MAXWLEN - MB_MAXBYTES)
+		break;
+	    d += mb_char2bytes(c, d);
+	}
+	else
+#endif
+	{
+	    if (d - wcopy >= MAXWLEN - 1)
+		break;
+	    *d++ = c;
+	}
+    }
+    *d = NUL;
+}
+
+/*
+ * Try finding suggestions by recognizing specific situations.
+ */
+    static void
+suggest_try_special(su)
+    suginfo_T	*su;
+{
+    char_u	*p;
+    size_t	len;
+    int		c;
+    char_u	word[MAXWLEN];
+
+    /*
+     * Recognize a word that is repeated: "the the".
+     */
+    p = skiptowhite(su->su_fbadword);
+    len = p - su->su_fbadword;
+    p = skipwhite(p);
+    if (STRLEN(p) == len && STRNCMP(su->su_fbadword, p, len) == 0)
+    {
+	/* Include badflags: if the badword is onecap or allcap
+	 * use that for the goodword too: "The the" -> "The". */
+	c = su->su_fbadword[len];
+	su->su_fbadword[len] = NUL;
+	make_case_word(su->su_fbadword, word, su->su_badflags);
+	su->su_fbadword[len] = c;
+
+	/* Give a soundalike score of 0, compute the score as if deleting one
+	 * character. */
+	add_suggestion(su, &su->su_ga, word, su->su_badlen,
+		       RESCORE(SCORE_REP, 0), 0, TRUE, su->su_sallang, FALSE);
+    }
+}
+
+/*
+ * Try finding suggestions by adding/removing/swapping letters.
+ */
+    static void
+suggest_try_change(su)
+    suginfo_T	*su;
+{
+    char_u	fword[MAXWLEN];	    /* copy of the bad word, case-folded */
+    int		n;
+    char_u	*p;
+    int		lpi;
+    langp_T	*lp;
+
+    /* We make a copy of the case-folded bad word, so that we can modify it
+     * to find matches (esp. REP items).  Append some more text, changing
+     * chars after the bad word may help. */
+    STRCPY(fword, su->su_fbadword);
+    n = (int)STRLEN(fword);
+    p = su->su_badptr + su->su_badlen;
+    (void)spell_casefold(p, (int)STRLEN(p), fword + n, MAXWLEN - n);
+
+    for (lpi = 0; lpi < curbuf->b_langp.ga_len; ++lpi)
+    {
+	lp = LANGP_ENTRY(curbuf->b_langp, lpi);
+
+	/* If reloading a spell file fails it's still in the list but
+	 * everything has been cleared. */
+	if (lp->lp_slang->sl_fbyts == NULL)
+	    continue;
+
+	/* Try it for this language.  Will add possible suggestions. */
+	suggest_trie_walk(su, lp, fword, FALSE);
+    }
+}
+
+/* Check the maximum score, if we go over it we won't try this change. */
+#define TRY_DEEPER(su, stack, depth, add) \
+		(stack[depth].ts_score + (add) < su->su_maxscore)
+
+/*
+ * Try finding suggestions by adding/removing/swapping letters.
+ *
+ * This uses a state machine.  At each node in the tree we try various
+ * operations.  When trying if an operation works "depth" is increased and the
+ * stack[] is used to store info.  This allows combinations, thus insert one
+ * character, replace one and delete another.  The number of changes is
+ * limited by su->su_maxscore.
+ *
+ * After implementing this I noticed an article by Kemal Oflazer that
+ * describes something similar: "Error-tolerant Finite State Recognition with
+ * Applications to Morphological Analysis and Spelling Correction" (1996).
+ * The implementation in the article is simplified and requires a stack of
+ * unknown depth.  The implementation here only needs a stack depth equal to
+ * the length of the word.
+ *
+ * This is also used for the sound-folded word, "soundfold" is TRUE then.
+ * The mechanism is the same, but we find a match with a sound-folded word
+ * that comes from one or more original words.  Each of these words may be
+ * added, this is done by add_sound_suggest().
+ * Don't use:
+ *	the prefix tree or the keep-case tree
+ *	"su->su_badlen"
+ *	anything to do with upper and lower case
+ *	anything to do with word or non-word characters ("spell_iswordp()")
+ *	banned words
+ *	word flags (rare, region, compounding)
+ *	word splitting for now
+ *	"similar_chars()"
+ *	use "slang->sl_repsal" instead of "lp->lp_replang->sl_rep"
+ */
+    static void
+suggest_trie_walk(su, lp, fword, soundfold)
+    suginfo_T	*su;
+    langp_T	*lp;
+    char_u	*fword;
+    int		soundfold;
+{
+    char_u	tword[MAXWLEN];	    /* good word collected so far */
+    trystate_T	stack[MAXWLEN];
+    char_u	preword[MAXWLEN * 3]; /* word found with proper case;
+				       * concatanation of prefix compound
+				       * words and split word.  NUL terminated
+				       * when going deeper but not when coming
+				       * back. */
+    char_u	compflags[MAXWLEN];	/* compound flags, one for each word */
+    trystate_T	*sp;
+    int		newscore;
+    int		score;
+    char_u	*byts, *fbyts, *pbyts;
+    idx_T	*idxs, *fidxs, *pidxs;
+    int		depth;
+    int		c, c2, c3;
+    int		n = 0;
+    int		flags;
+    garray_T	*gap;
+    idx_T	arridx;
+    int		len;
+    char_u	*p;
+    fromto_T	*ftp;
+    int		fl = 0, tl;
+    int		repextra = 0;	    /* extra bytes in fword[] from REP item */
+    slang_T	*slang = lp->lp_slang;
+    int		fword_ends;
+    int		goodword_ends;
+#ifdef DEBUG_TRIEWALK
+    /* Stores the name of the change made at each level. */
+    char_u	changename[MAXWLEN][80];
+#endif
+    int		breakcheckcount = 1000;
+    int		compound_ok;
+
+    /*
+     * Go through the whole case-fold tree, try changes at each node.
+     * "tword[]" contains the word collected from nodes in the tree.
+     * "fword[]" the word we are trying to match with (initially the bad
+     * word).
+     */
+    depth = 0;
+    sp = &stack[0];
+    vim_memset(sp, 0, sizeof(trystate_T));
+    sp->ts_curi = 1;
+
+    if (soundfold)
+    {
+	/* Going through the soundfold tree. */
+	byts = fbyts = slang->sl_sbyts;
+	idxs = fidxs = slang->sl_sidxs;
+	pbyts = NULL;
+	pidxs = NULL;
+	sp->ts_prefixdepth = PFD_NOPREFIX;
+	sp->ts_state = STATE_START;
+    }
+    else
+    {
+	/*
+	 * When there are postponed prefixes we need to use these first.  At
+	 * the end of the prefix we continue in the case-fold tree.
+	 */
+	fbyts = slang->sl_fbyts;
+	fidxs = slang->sl_fidxs;
+	pbyts = slang->sl_pbyts;
+	pidxs = slang->sl_pidxs;
+	if (pbyts != NULL)
+	{
+	    byts = pbyts;
+	    idxs = pidxs;
+	    sp->ts_prefixdepth = PFD_PREFIXTREE;
+	    sp->ts_state = STATE_NOPREFIX;	/* try without prefix first */
+	}
+	else
+	{
+	    byts = fbyts;
+	    idxs = fidxs;
+	    sp->ts_prefixdepth = PFD_NOPREFIX;
+	    sp->ts_state = STATE_START;
+	}
+    }
+
+    /*
+     * Loop to find all suggestions.  At each round we either:
+     * - For the current state try one operation, advance "ts_curi",
+     *   increase "depth".
+     * - When a state is done go to the next, set "ts_state".
+     * - When all states are tried decrease "depth".
+     */
+    while (depth >= 0 && !got_int)
+    {
+	sp = &stack[depth];
+	switch (sp->ts_state)
+	{
+	case STATE_START:
+	case STATE_NOPREFIX:
+	    /*
+	     * Start of node: Deal with NUL bytes, which means
+	     * tword[] may end here.
+	     */
+	    arridx = sp->ts_arridx;	    /* current node in the tree */
+	    len = byts[arridx];		    /* bytes in this node */
+	    arridx += sp->ts_curi;	    /* index of current byte */
+
+	    if (sp->ts_prefixdepth == PFD_PREFIXTREE)
+	    {
+		/* Skip over the NUL bytes, we use them later. */
+		for (n = 0; n < len && byts[arridx + n] == 0; ++n)
+		    ;
+		sp->ts_curi += n;
+
+		/* Always past NUL bytes now. */
+		n = (int)sp->ts_state;
+		sp->ts_state = STATE_ENDNUL;
+		sp->ts_save_badflags = su->su_badflags;
+
+		/* At end of a prefix or at start of prefixtree: check for
+		 * following word. */
+		if (byts[arridx] == 0 || n == (int)STATE_NOPREFIX)
+		{
+		    /* Set su->su_badflags to the caps type at this position.
+		     * Use the caps type until here for the prefix itself. */
+#ifdef FEAT_MBYTE
+		    if (has_mbyte)
+			n = nofold_len(fword, sp->ts_fidx, su->su_badptr);
+		    else
+#endif
+			n = sp->ts_fidx;
+		    flags = badword_captype(su->su_badptr, su->su_badptr + n);
+		    su->su_badflags = badword_captype(su->su_badptr + n,
+					       su->su_badptr + su->su_badlen);
+#ifdef DEBUG_TRIEWALK
+		    sprintf(changename[depth], "prefix");
+#endif
+		    go_deeper(stack, depth, 0);
+		    ++depth;
+		    sp = &stack[depth];
+		    sp->ts_prefixdepth = depth - 1;
+		    byts = fbyts;
+		    idxs = fidxs;
+		    sp->ts_arridx = 0;
+
+		    /* Move the prefix to preword[] with the right case
+		     * and make find_keepcap_word() works. */
+		    tword[sp->ts_twordlen] = NUL;
+		    make_case_word(tword + sp->ts_splitoff,
+					  preword + sp->ts_prewordlen, flags);
+		    sp->ts_prewordlen = (char_u)STRLEN(preword);
+		    sp->ts_splitoff = sp->ts_twordlen;
+		}
+		break;
+	    }
+
+	    if (sp->ts_curi > len || byts[arridx] != 0)
+	    {
+		/* Past bytes in node and/or past NUL bytes. */
+		sp->ts_state = STATE_ENDNUL;
+		sp->ts_save_badflags = su->su_badflags;
+		break;
+	    }
+
+	    /*
+	     * End of word in tree.
+	     */
+	    ++sp->ts_curi;		/* eat one NUL byte */
+
+	    flags = (int)idxs[arridx];
+
+	    /* Skip words with the NOSUGGEST flag. */
+	    if (flags & WF_NOSUGGEST)
+		break;
+
+	    fword_ends = (fword[sp->ts_fidx] == NUL
+			   || (soundfold
+			       ? vim_iswhite(fword[sp->ts_fidx])
+			       : !spell_iswordp(fword + sp->ts_fidx, curbuf)));
+	    tword[sp->ts_twordlen] = NUL;
+
+	    if (sp->ts_prefixdepth <= PFD_NOTSPECIAL
+					&& (sp->ts_flags & TSF_PREFIXOK) == 0)
+	    {
+		/* There was a prefix before the word.  Check that the prefix
+		 * can be used with this word. */
+		/* Count the length of the NULs in the prefix.  If there are
+		 * none this must be the first try without a prefix.  */
+		n = stack[sp->ts_prefixdepth].ts_arridx;
+		len = pbyts[n++];
+		for (c = 0; c < len && pbyts[n + c] == 0; ++c)
+		    ;
+		if (c > 0)
+		{
+		    c = valid_word_prefix(c, n, flags,
+				       tword + sp->ts_splitoff, slang, FALSE);
+		    if (c == 0)
+			break;
+
+		    /* Use the WF_RARE flag for a rare prefix. */
+		    if (c & WF_RAREPFX)
+			flags |= WF_RARE;
+
+		    /* Tricky: when checking for both prefix and compounding
+		     * we run into the prefix flag first.
+		     * Remember that it's OK, so that we accept the prefix
+		     * when arriving at a compound flag. */
+		    sp->ts_flags |= TSF_PREFIXOK;
+		}
+	    }
+
+	    /* Check NEEDCOMPOUND: can't use word without compounding.  Do try
+	     * appending another compound word below. */
+	    if (sp->ts_complen == sp->ts_compsplit && fword_ends
+						     && (flags & WF_NEEDCOMP))
+		goodword_ends = FALSE;
+	    else
+		goodword_ends = TRUE;
+
+	    p = NULL;
+	    compound_ok = TRUE;
+	    if (sp->ts_complen > sp->ts_compsplit)
+	    {
+		if (slang->sl_nobreak)
+		{
+		    /* There was a word before this word.  When there was no
+		     * change in this word (it was correct) add the first word
+		     * as a suggestion.  If this word was corrected too, we
+		     * need to check if a correct word follows. */
+		    if (sp->ts_fidx - sp->ts_splitfidx
+					  == sp->ts_twordlen - sp->ts_splitoff
+			    && STRNCMP(fword + sp->ts_splitfidx,
+					tword + sp->ts_splitoff,
+					 sp->ts_fidx - sp->ts_splitfidx) == 0)
+		    {
+			preword[sp->ts_prewordlen] = NUL;
+			newscore = score_wordcount_adj(slang, sp->ts_score,
+						 preword + sp->ts_prewordlen,
+						 sp->ts_prewordlen > 0);
+			/* Add the suggestion if the score isn't too bad. */
+			if (newscore <= su->su_maxscore)
+			    add_suggestion(su, &su->su_ga, preword,
+				    sp->ts_splitfidx - repextra,
+				    newscore, 0, FALSE,
+				    lp->lp_sallang, FALSE);
+			break;
+		    }
+		}
+		else
+		{
+		    /* There was a compound word before this word.  If this
+		     * word does not support compounding then give up
+		     * (splitting is tried for the word without compound
+		     * flag). */
+		    if (((unsigned)flags >> 24) == 0
+			    || sp->ts_twordlen - sp->ts_splitoff
+						       < slang->sl_compminlen)
+			break;
+#ifdef FEAT_MBYTE
+		    /* For multi-byte chars check character length against
+		     * COMPOUNDMIN. */
+		    if (has_mbyte
+			    && slang->sl_compminlen > 0
+			    && mb_charlen(tword + sp->ts_splitoff)
+						       < slang->sl_compminlen)
+			break;
+#endif
+
+		    compflags[sp->ts_complen] = ((unsigned)flags >> 24);
+		    compflags[sp->ts_complen + 1] = NUL;
+		    vim_strncpy(preword + sp->ts_prewordlen,
+			    tword + sp->ts_splitoff,
+			    sp->ts_twordlen - sp->ts_splitoff);
+		    p = preword;
+		    while (*skiptowhite(p) != NUL)
+			p = skipwhite(skiptowhite(p));
+		    if (fword_ends && !can_compound(slang, p,
+						compflags + sp->ts_compsplit))
+			/* Compound is not allowed.  But it may still be
+			 * possible if we add another (short) word. */
+			compound_ok = FALSE;
+
+		    /* Get pointer to last char of previous word. */
+		    p = preword + sp->ts_prewordlen;
+		    mb_ptr_back(preword, p);
+		}
+	    }
+
+	    /*
+	     * Form the word with proper case in preword.
+	     * If there is a word from a previous split, append.
+	     * For the soundfold tree don't change the case, simply append.
+	     */
+	    if (soundfold)
+		STRCPY(preword + sp->ts_prewordlen, tword + sp->ts_splitoff);
+	    else if (flags & WF_KEEPCAP)
+		/* Must find the word in the keep-case tree. */
+		find_keepcap_word(slang, tword + sp->ts_splitoff,
+						 preword + sp->ts_prewordlen);
+	    else
+	    {
+		/* Include badflags: If the badword is onecap or allcap
+		 * use that for the goodword too.  But if the badword is
+		 * allcap and it's only one char long use onecap. */
+		c = su->su_badflags;
+		if ((c & WF_ALLCAP)
+#ifdef FEAT_MBYTE
+			&& su->su_badlen == (*mb_ptr2len)(su->su_badptr)
+#else
+			&& su->su_badlen == 1
+#endif
+			)
+		    c = WF_ONECAP;
+		c |= flags;
+
+		/* When appending a compound word after a word character don't
+		 * use Onecap. */
+		if (p != NULL && spell_iswordp_nmw(p))
+		    c &= ~WF_ONECAP;
+		make_case_word(tword + sp->ts_splitoff,
+					      preword + sp->ts_prewordlen, c);
+	    }
+
+	    if (!soundfold)
+	    {
+		/* Don't use a banned word.  It may appear again as a good
+		 * word, thus remember it. */
+		if (flags & WF_BANNED)
+		{
+		    add_banned(su, preword + sp->ts_prewordlen);
+		    break;
+		}
+		if ((sp->ts_complen == sp->ts_compsplit
+			    && WAS_BANNED(su, preword + sp->ts_prewordlen))
+						   || WAS_BANNED(su, preword))
+		{
+		    if (slang->sl_compprog == NULL)
+			break;
+		    /* the word so far was banned but we may try compounding */
+		    goodword_ends = FALSE;
+		}
+	    }
+
+	    newscore = 0;
+	    if (!soundfold)	/* soundfold words don't have flags */
+	    {
+		if ((flags & WF_REGION)
+			    && (((unsigned)flags >> 16) & lp->lp_region) == 0)
+		    newscore += SCORE_REGION;
+		if (flags & WF_RARE)
+		    newscore += SCORE_RARE;
+
+		if (!spell_valid_case(su->su_badflags,
+				  captype(preword + sp->ts_prewordlen, NULL)))
+		    newscore += SCORE_ICASE;
+	    }
+
+	    /* TODO: how about splitting in the soundfold tree? */
+	    if (fword_ends
+		    && goodword_ends
+		    && sp->ts_fidx >= sp->ts_fidxtry
+		    && compound_ok)
+	    {
+		/* The badword also ends: add suggestions. */
+#ifdef DEBUG_TRIEWALK
+		if (soundfold && STRCMP(preword, "smwrd") == 0)
+		{
+		    int	    j;
+
+		    /* print the stack of changes that brought us here */
+		    smsg("------ %s -------", fword);
+		    for (j = 0; j < depth; ++j)
+			smsg("%s", changename[j]);
+		}
+#endif
+		if (soundfold)
+		{
+		    /* For soundfolded words we need to find the original
+		     * words, the edit distance and then add them. */
+		    add_sound_suggest(su, preword, sp->ts_score, lp);
+		}
+		else
+		{
+		    /* Give a penalty when changing non-word char to word
+		     * char, e.g., "thes," -> "these". */
+		    p = fword + sp->ts_fidx;
+		    mb_ptr_back(fword, p);
+		    if (!spell_iswordp(p, curbuf))
+		    {
+			p = preword + STRLEN(preword);
+			mb_ptr_back(preword, p);
+			if (spell_iswordp(p, curbuf))
+			    newscore += SCORE_NONWORD;
+		    }
+
+		    /* Give a bonus to words seen before. */
+		    score = score_wordcount_adj(slang,
+						sp->ts_score + newscore,
+						preword + sp->ts_prewordlen,
+						sp->ts_prewordlen > 0);
+
+		    /* Add the suggestion if the score isn't too bad. */
+		    if (score <= su->su_maxscore)
+		    {
+			add_suggestion(su, &su->su_ga, preword,
+				    sp->ts_fidx - repextra,
+				    score, 0, FALSE, lp->lp_sallang, FALSE);
+
+			if (su->su_badflags & WF_MIXCAP)
+			{
+			    /* We really don't know if the word should be
+			     * upper or lower case, add both. */
+			    c = captype(preword, NULL);
+			    if (c == 0 || c == WF_ALLCAP)
+			    {
+				make_case_word(tword + sp->ts_splitoff,
+					      preword + sp->ts_prewordlen,
+						      c == 0 ? WF_ALLCAP : 0);
+
+				add_suggestion(su, &su->su_ga, preword,
+					sp->ts_fidx - repextra,
+					score + SCORE_ICASE, 0, FALSE,
+					lp->lp_sallang, FALSE);
+			    }
+			}
+		    }
+		}
+	    }
+
+	    /*
+	     * Try word split and/or compounding.
+	     */
+	    if ((sp->ts_fidx >= sp->ts_fidxtry || fword_ends)
+#ifdef FEAT_MBYTE
+		    /* Don't split halfway a character. */
+		    && (!has_mbyte || sp->ts_tcharlen == 0)
+#endif
+		    )
+	    {
+		int	try_compound;
+		int	try_split;
+
+		/* If past the end of the bad word don't try a split.
+		 * Otherwise try changing the next word.  E.g., find
+		 * suggestions for "the the" where the second "the" is
+		 * different.  It's done like a split.
+		 * TODO: word split for soundfold words */
+		try_split = (sp->ts_fidx - repextra < su->su_badlen)
+								&& !soundfold;
+
+		/* Get here in several situations:
+		 * 1. The word in the tree ends:
+		 *    If the word allows compounding try that.  Otherwise try
+		 *    a split by inserting a space.  For both check that a
+		 *    valid words starts at fword[sp->ts_fidx].
+		 *    For NOBREAK do like compounding to be able to check if
+		 *    the next word is valid.
+		 * 2. The badword does end, but it was due to a change (e.g.,
+		 *    a swap).  No need to split, but do check that the
+		 *    following word is valid.
+		 * 3. The badword and the word in the tree end.  It may still
+		 *    be possible to compound another (short) word.
+		 */
+		try_compound = FALSE;
+		if (!soundfold
+			&& slang->sl_compprog != NULL
+			&& ((unsigned)flags >> 24) != 0
+			&& sp->ts_twordlen - sp->ts_splitoff
+						       >= slang->sl_compminlen
+#ifdef FEAT_MBYTE
+			&& (!has_mbyte
+			    || slang->sl_compminlen == 0
+			    || mb_charlen(tword + sp->ts_splitoff)
+						      >= slang->sl_compminlen)
+#endif
+			&& (slang->sl_compsylmax < MAXWLEN
+			    || sp->ts_complen + 1 - sp->ts_compsplit
+							  < slang->sl_compmax)
+			&& (byte_in_str(sp->ts_complen == sp->ts_compsplit
+					    ? slang->sl_compstartflags
+					    : slang->sl_compallflags,
+						    ((unsigned)flags >> 24))))
+		{
+		    try_compound = TRUE;
+		    compflags[sp->ts_complen] = ((unsigned)flags >> 24);
+		    compflags[sp->ts_complen + 1] = NUL;
+		}
+
+		/* For NOBREAK we never try splitting, it won't make any word
+		 * valid. */
+		if (slang->sl_nobreak)
+		    try_compound = TRUE;
+
+		/* If we could add a compound word, and it's also possible to
+		 * split at this point, do the split first and set
+		 * TSF_DIDSPLIT to avoid doing it again. */
+		else if (!fword_ends
+			&& try_compound
+			&& (sp->ts_flags & TSF_DIDSPLIT) == 0)
+		{
+		    try_compound = FALSE;
+		    sp->ts_flags |= TSF_DIDSPLIT;
+		    --sp->ts_curi;	    /* do the same NUL again */
+		    compflags[sp->ts_complen] = NUL;
+		}
+		else
+		    sp->ts_flags &= ~TSF_DIDSPLIT;
+
+		if (try_split || try_compound)
+		{
+		    if (!try_compound && (!fword_ends || !goodword_ends))
+		    {
+			/* If we're going to split need to check that the
+			 * words so far are valid for compounding.  If there
+			 * is only one word it must not have the NEEDCOMPOUND
+			 * flag. */
+			if (sp->ts_complen == sp->ts_compsplit
+						     && (flags & WF_NEEDCOMP))
+			    break;
+			p = preword;
+			while (*skiptowhite(p) != NUL)
+			    p = skipwhite(skiptowhite(p));
+			if (sp->ts_complen > sp->ts_compsplit
+				&& !can_compound(slang, p,
+						compflags + sp->ts_compsplit))
+			    break;
+
+			if (slang->sl_nosplitsugs)
+			    newscore += SCORE_SPLIT_NO;
+			else
+			    newscore += SCORE_SPLIT;
+
+			/* Give a bonus to words seen before. */
+			newscore = score_wordcount_adj(slang, newscore,
+					   preword + sp->ts_prewordlen, TRUE);
+		    }
+
+		    if (TRY_DEEPER(su, stack, depth, newscore))
+		    {
+			go_deeper(stack, depth, newscore);
+#ifdef DEBUG_TRIEWALK
+			if (!try_compound && !fword_ends)
+			    sprintf(changename[depth], "%.*s-%s: split",
+				 sp->ts_twordlen, tword, fword + sp->ts_fidx);
+			else
+			    sprintf(changename[depth], "%.*s-%s: compound",
+				 sp->ts_twordlen, tword, fword + sp->ts_fidx);
+#endif
+			/* Save things to be restored at STATE_SPLITUNDO. */
+			sp->ts_save_badflags = su->su_badflags;
+			sp->ts_state = STATE_SPLITUNDO;
+
+			++depth;
+			sp = &stack[depth];
+
+			/* Append a space to preword when splitting. */
+			if (!try_compound && !fword_ends)
+			    STRCAT(preword, " ");
+			sp->ts_prewordlen = (char_u)STRLEN(preword);
+			sp->ts_splitoff = sp->ts_twordlen;
+			sp->ts_splitfidx = sp->ts_fidx;
+
+			/* If the badword has a non-word character at this
+			 * position skip it.  That means replacing the
+			 * non-word character with a space.  Always skip a
+			 * character when the word ends.  But only when the
+			 * good word can end. */
+			if (((!try_compound && !spell_iswordp_nmw(fword
+							       + sp->ts_fidx))
+				    || fword_ends)
+				&& fword[sp->ts_fidx] != NUL
+				&& goodword_ends)
+			{
+			    int	    l;
+
+#ifdef FEAT_MBYTE
+			    if (has_mbyte)
+				l = MB_BYTE2LEN(fword[sp->ts_fidx]);
+			    else
+#endif
+				l = 1;
+			    if (fword_ends)
+			    {
+				/* Copy the skipped character to preword. */
+				mch_memmove(preword + sp->ts_prewordlen,
+						      fword + sp->ts_fidx, l);
+				sp->ts_prewordlen += l;
+				preword[sp->ts_prewordlen] = NUL;
+			    }
+			    else
+				sp->ts_score -= SCORE_SPLIT - SCORE_SUBST;
+			    sp->ts_fidx += l;
+			}
+
+			/* When compounding include compound flag in
+			 * compflags[] (already set above).  When splitting we
+			 * may start compounding over again.  */
+			if (try_compound)
+			    ++sp->ts_complen;
+			else
+			    sp->ts_compsplit = sp->ts_complen;
+			sp->ts_prefixdepth = PFD_NOPREFIX;
+
+			/* set su->su_badflags to the caps type at this
+			 * position */
+#ifdef FEAT_MBYTE
+			if (has_mbyte)
+			    n = nofold_len(fword, sp->ts_fidx, su->su_badptr);
+			else
+#endif
+			    n = sp->ts_fidx;
+			su->su_badflags = badword_captype(su->su_badptr + n,
+					       su->su_badptr + su->su_badlen);
+
+			/* Restart at top of the tree. */
+			sp->ts_arridx = 0;
+
+			/* If there are postponed prefixes, try these too. */
+			if (pbyts != NULL)
+			{
+			    byts = pbyts;
+			    idxs = pidxs;
+			    sp->ts_prefixdepth = PFD_PREFIXTREE;
+			    sp->ts_state = STATE_NOPREFIX;
+			}
+		    }
+		}
+	    }
+	    break;
+
+	case STATE_SPLITUNDO:
+	    /* Undo the changes done for word split or compound word. */
+	    su->su_badflags = sp->ts_save_badflags;
+
+	    /* Continue looking for NUL bytes. */
+	    sp->ts_state = STATE_START;
+
+	    /* In case we went into the prefix tree. */
+	    byts = fbyts;
+	    idxs = fidxs;
+	    break;
+
+	case STATE_ENDNUL:
+	    /* Past the NUL bytes in the node. */
+	    su->su_badflags = sp->ts_save_badflags;
+	    if (fword[sp->ts_fidx] == NUL
+#ifdef FEAT_MBYTE
+		    && sp->ts_tcharlen == 0
+#endif
+	       )
+	    {
+		/* The badword ends, can't use STATE_PLAIN. */
+		sp->ts_state = STATE_DEL;
+		break;
+	    }
+	    sp->ts_state = STATE_PLAIN;
+	    /*FALLTHROUGH*/
+
+	case STATE_PLAIN:
+	    /*
+	     * Go over all possible bytes at this node, add each to tword[]
+	     * and use child node.  "ts_curi" is the index.
+	     */
+	    arridx = sp->ts_arridx;
+	    if (sp->ts_curi > byts[arridx])
+	    {
+		/* Done all bytes at this node, do next state.  When still at
+		 * already changed bytes skip the other tricks. */
+		if (sp->ts_fidx >= sp->ts_fidxtry)
+		    sp->ts_state = STATE_DEL;
+		else
+		    sp->ts_state = STATE_FINAL;
+	    }
+	    else
+	    {
+		arridx += sp->ts_curi++;
+		c = byts[arridx];
+
+		/* Normal byte, go one level deeper.  If it's not equal to the
+		 * byte in the bad word adjust the score.  But don't even try
+		 * when the byte was already changed.  And don't try when we
+		 * just deleted this byte, accepting it is always cheaper then
+		 * delete + substitute. */
+		if (c == fword[sp->ts_fidx]
+#ifdef FEAT_MBYTE
+			|| (sp->ts_tcharlen > 0 && sp->ts_isdiff != DIFF_NONE)
+#endif
+			)
+		    newscore = 0;
+		else
+		    newscore = SCORE_SUBST;
+		if ((newscore == 0
+			    || (sp->ts_fidx >= sp->ts_fidxtry
+				&& ((sp->ts_flags & TSF_DIDDEL) == 0
+				    || c != fword[sp->ts_delidx])))
+			&& TRY_DEEPER(su, stack, depth, newscore))
+		{
+		    go_deeper(stack, depth, newscore);
+#ifdef DEBUG_TRIEWALK
+		    if (newscore > 0)
+			sprintf(changename[depth], "%.*s-%s: subst %c to %c",
+				sp->ts_twordlen, tword, fword + sp->ts_fidx,
+				fword[sp->ts_fidx], c);
+		    else
+			sprintf(changename[depth], "%.*s-%s: accept %c",
+				sp->ts_twordlen, tword, fword + sp->ts_fidx,
+				fword[sp->ts_fidx]);
+#endif
+		    ++depth;
+		    sp = &stack[depth];
+		    ++sp->ts_fidx;
+		    tword[sp->ts_twordlen++] = c;
+		    sp->ts_arridx = idxs[arridx];
+#ifdef FEAT_MBYTE
+		    if (newscore == SCORE_SUBST)
+			sp->ts_isdiff = DIFF_YES;
+		    if (has_mbyte)
+		    {
+			/* Multi-byte characters are a bit complicated to
+			 * handle: They differ when any of the bytes differ
+			 * and then their length may also differ. */
+			if (sp->ts_tcharlen == 0)
+			{
+			    /* First byte. */
+			    sp->ts_tcharidx = 0;
+			    sp->ts_tcharlen = MB_BYTE2LEN(c);
+			    sp->ts_fcharstart = sp->ts_fidx - 1;
+			    sp->ts_isdiff = (newscore != 0)
+						       ? DIFF_YES : DIFF_NONE;
+			}
+			else if (sp->ts_isdiff == DIFF_INSERT)
+			    /* When inserting trail bytes don't advance in the
+			     * bad word. */
+			    --sp->ts_fidx;
+			if (++sp->ts_tcharidx == sp->ts_tcharlen)
+			{
+			    /* Last byte of character. */
+			    if (sp->ts_isdiff == DIFF_YES)
+			    {
+				/* Correct ts_fidx for the byte length of the
+				 * character (we didn't check that before). */
+				sp->ts_fidx = sp->ts_fcharstart
+					    + MB_BYTE2LEN(
+						    fword[sp->ts_fcharstart]);
+
+				/* For changing a composing character adjust
+				 * the score from SCORE_SUBST to
+				 * SCORE_SUBCOMP. */
+				if (enc_utf8
+					&& utf_iscomposing(
+					    mb_ptr2char(tword
+						+ sp->ts_twordlen
+							   - sp->ts_tcharlen))
+					&& utf_iscomposing(
+					    mb_ptr2char(fword
+							+ sp->ts_fcharstart)))
+				    sp->ts_score -=
+						  SCORE_SUBST - SCORE_SUBCOMP;
+
+				/* For a similar character adjust score from
+				 * SCORE_SUBST to SCORE_SIMILAR. */
+				else if (!soundfold
+					&& slang->sl_has_map
+					&& similar_chars(slang,
+					    mb_ptr2char(tword
+						+ sp->ts_twordlen
+							   - sp->ts_tcharlen),
+					    mb_ptr2char(fword
+							+ sp->ts_fcharstart)))
+				    sp->ts_score -=
+						  SCORE_SUBST - SCORE_SIMILAR;
+			    }
+			    else if (sp->ts_isdiff == DIFF_INSERT
+					 && sp->ts_twordlen > sp->ts_tcharlen)
+			    {
+				p = tword + sp->ts_twordlen - sp->ts_tcharlen;
+				c = mb_ptr2char(p);
+				if (enc_utf8 && utf_iscomposing(c))
+				{
+				    /* Inserting a composing char doesn't
+				     * count that much. */
+				    sp->ts_score -= SCORE_INS - SCORE_INSCOMP;
+				}
+				else
+				{
+				    /* If the previous character was the same,
+				     * thus doubling a character, give a bonus
+				     * to the score.  Also for the soundfold
+				     * tree (might seem illogical but does
+				     * give better scores). */
+				    mb_ptr_back(tword, p);
+				    if (c == mb_ptr2char(p))
+					sp->ts_score -= SCORE_INS
+							       - SCORE_INSDUP;
+				}
+			    }
+
+			    /* Starting a new char, reset the length. */
+			    sp->ts_tcharlen = 0;
+			}
+		    }
+		    else
+#endif
+		    {
+			/* If we found a similar char adjust the score.
+			 * We do this after calling go_deeper() because
+			 * it's slow. */
+			if (newscore != 0
+				&& !soundfold
+				&& slang->sl_has_map
+				&& similar_chars(slang,
+						   c, fword[sp->ts_fidx - 1]))
+			    sp->ts_score -= SCORE_SUBST - SCORE_SIMILAR;
+		    }
+		}
+	    }
+	    break;
+
+	case STATE_DEL:
+#ifdef FEAT_MBYTE
+	    /* When past the first byte of a multi-byte char don't try
+	     * delete/insert/swap a character. */
+	    if (has_mbyte && sp->ts_tcharlen > 0)
+	    {
+		sp->ts_state = STATE_FINAL;
+		break;
+	    }
+#endif
+	    /*
+	     * Try skipping one character in the bad word (delete it).
+	     */
+	    sp->ts_state = STATE_INS_PREP;
+	    sp->ts_curi = 1;
+	    if (soundfold && sp->ts_fidx == 0 && fword[sp->ts_fidx] == '*')
+		/* Deleting a vowel at the start of a word counts less, see
+		 * soundalike_score(). */
+		newscore = 2 * SCORE_DEL / 3;
+	    else
+		newscore = SCORE_DEL;
+	    if (fword[sp->ts_fidx] != NUL
+				    && TRY_DEEPER(su, stack, depth, newscore))
+	    {
+		go_deeper(stack, depth, newscore);
+#ifdef DEBUG_TRIEWALK
+		sprintf(changename[depth], "%.*s-%s: delete %c",
+			sp->ts_twordlen, tword, fword + sp->ts_fidx,
+			fword[sp->ts_fidx]);
+#endif
+		++depth;
+
+		/* Remember what character we deleted, so that we can avoid
+		 * inserting it again. */
+		stack[depth].ts_flags |= TSF_DIDDEL;
+		stack[depth].ts_delidx = sp->ts_fidx;
+
+		/* Advance over the character in fword[].  Give a bonus to the
+		 * score if the same character is following "nn" -> "n".  It's
+		 * a bit illogical for soundfold tree but it does give better
+		 * results. */
+#ifdef FEAT_MBYTE
+		if (has_mbyte)
+		{
+		    c = mb_ptr2char(fword + sp->ts_fidx);
+		    stack[depth].ts_fidx += MB_BYTE2LEN(fword[sp->ts_fidx]);
+		    if (enc_utf8 && utf_iscomposing(c))
+			stack[depth].ts_score -= SCORE_DEL - SCORE_DELCOMP;
+		    else if (c == mb_ptr2char(fword + stack[depth].ts_fidx))
+			stack[depth].ts_score -= SCORE_DEL - SCORE_DELDUP;
+		}
+		else
+#endif
+		{
+		    ++stack[depth].ts_fidx;
+		    if (fword[sp->ts_fidx] == fword[sp->ts_fidx + 1])
+			stack[depth].ts_score -= SCORE_DEL - SCORE_DELDUP;
+		}
+		break;
+	    }
+	    /*FALLTHROUGH*/
+
+	case STATE_INS_PREP:
+	    if (sp->ts_flags & TSF_DIDDEL)
+	    {
+		/* If we just deleted a byte then inserting won't make sense,
+		 * a substitute is always cheaper. */
+		sp->ts_state = STATE_SWAP;
+		break;
+	    }
+
+	    /* skip over NUL bytes */
+	    n = sp->ts_arridx;
+	    for (;;)
+	    {
+		if (sp->ts_curi > byts[n])
+		{
+		    /* Only NUL bytes at this node, go to next state. */
+		    sp->ts_state = STATE_SWAP;
+		    break;
+		}
+		if (byts[n + sp->ts_curi] != NUL)
+		{
+		    /* Found a byte to insert. */
+		    sp->ts_state = STATE_INS;
+		    break;
+		}
+		++sp->ts_curi;
+	    }
+	    break;
+
+	    /*FALLTHROUGH*/
+
+	case STATE_INS:
+	    /* Insert one byte.  Repeat this for each possible byte at this
+	     * node. */
+	    n = sp->ts_arridx;
+	    if (sp->ts_curi > byts[n])
+	    {
+		/* Done all bytes at this node, go to next state. */
+		sp->ts_state = STATE_SWAP;
+		break;
+	    }
+
+	    /* Do one more byte at this node, but:
+	     * - Skip NUL bytes.
+	     * - Skip the byte if it's equal to the byte in the word,
+	     *   accepting that byte is always better.
+	     */
+	    n += sp->ts_curi++;
+	    c = byts[n];
+	    if (soundfold && sp->ts_twordlen == 0 && c == '*')
+		/* Inserting a vowel at the start of a word counts less,
+		 * see soundalike_score(). */
+		newscore = 2 * SCORE_INS / 3;
+	    else
+		newscore = SCORE_INS;
+	    if (c != fword[sp->ts_fidx]
+				    && TRY_DEEPER(su, stack, depth, newscore))
+	    {
+		go_deeper(stack, depth, newscore);
+#ifdef DEBUG_TRIEWALK
+		sprintf(changename[depth], "%.*s-%s: insert %c",
+			sp->ts_twordlen, tword, fword + sp->ts_fidx,
+			c);
+#endif
+		++depth;
+		sp = &stack[depth];
+		tword[sp->ts_twordlen++] = c;
+		sp->ts_arridx = idxs[n];
+#ifdef FEAT_MBYTE
+		if (has_mbyte)
+		{
+		    fl = MB_BYTE2LEN(c);
+		    if (fl > 1)
+		    {
+			/* There are following bytes for the same character.
+			 * We must find all bytes before trying
+			 * delete/insert/swap/etc. */
+			sp->ts_tcharlen = fl;
+			sp->ts_tcharidx = 1;
+			sp->ts_isdiff = DIFF_INSERT;
+		    }
+		}
+		else
+		    fl = 1;
+		if (fl == 1)
+#endif
+		{
+		    /* If the previous character was the same, thus doubling a
+		     * character, give a bonus to the score.  Also for
+		     * soundfold words (illogical but does give a better
+		     * score). */
+		    if (sp->ts_twordlen >= 2
+					   && tword[sp->ts_twordlen - 2] == c)
+			sp->ts_score -= SCORE_INS - SCORE_INSDUP;
+		}
+	    }
+	    break;
+
+	case STATE_SWAP:
+	    /*
+	     * Swap two bytes in the bad word: "12" -> "21".
+	     * We change "fword" here, it's changed back afterwards at
+	     * STATE_UNSWAP.
+	     */
+	    p = fword + sp->ts_fidx;
+	    c = *p;
+	    if (c == NUL)
+	    {
+		/* End of word, can't swap or replace. */
+		sp->ts_state = STATE_FINAL;
+		break;
+	    }
+
+	    /* Don't swap if the first character is not a word character.
+	     * SWAP3 etc. also don't make sense then. */
+	    if (!soundfold && !spell_iswordp(p, curbuf))
+	    {
+		sp->ts_state = STATE_REP_INI;
+		break;
+	    }
+
+#ifdef FEAT_MBYTE
+	    if (has_mbyte)
+	    {
+		n = mb_cptr2len(p);
+		c = mb_ptr2char(p);
+		if (!soundfold && !spell_iswordp(p + n, curbuf))
+		    c2 = c; /* don't swap non-word char */
+		else
+		    c2 = mb_ptr2char(p + n);
+	    }
+	    else
+#endif
+	    {
+		if (!soundfold && !spell_iswordp(p + 1, curbuf))
+		    c2 = c; /* don't swap non-word char */
+		else
+		    c2 = p[1];
+	    }
+
+	    /* When characters are identical, swap won't do anything.
+	     * Also get here if the second char is not a word character. */
+	    if (c == c2)
+	    {
+		sp->ts_state = STATE_SWAP3;
+		break;
+	    }
+	    if (c2 != NUL && TRY_DEEPER(su, stack, depth, SCORE_SWAP))
+	    {
+		go_deeper(stack, depth, SCORE_SWAP);
+#ifdef DEBUG_TRIEWALK
+		sprintf(changename[depth], "%.*s-%s: swap %c and %c",
+			sp->ts_twordlen, tword, fword + sp->ts_fidx,
+			c, c2);
+#endif
+		sp->ts_state = STATE_UNSWAP;
+		++depth;
+#ifdef FEAT_MBYTE
+		if (has_mbyte)
+		{
+		    fl = mb_char2len(c2);
+		    mch_memmove(p, p + n, fl);
+		    mb_char2bytes(c, p + fl);
+		    stack[depth].ts_fidxtry = sp->ts_fidx + n + fl;
+		}
+		else
+#endif
+		{
+		    p[0] = c2;
+		    p[1] = c;
+		    stack[depth].ts_fidxtry = sp->ts_fidx + 2;
+		}
+	    }
+	    else
+		/* If this swap doesn't work then SWAP3 won't either. */
+		sp->ts_state = STATE_REP_INI;
+	    break;
+
+	case STATE_UNSWAP:
+	    /* Undo the STATE_SWAP swap: "21" -> "12". */
+	    p = fword + sp->ts_fidx;
+#ifdef FEAT_MBYTE
+	    if (has_mbyte)
+	    {
+		n = MB_BYTE2LEN(*p);
+		c = mb_ptr2char(p + n);
+		mch_memmove(p + MB_BYTE2LEN(p[n]), p, n);
+		mb_char2bytes(c, p);
+	    }
+	    else
+#endif
+	    {
+		c = *p;
+		*p = p[1];
+		p[1] = c;
+	    }
+	    /*FALLTHROUGH*/
+
+	case STATE_SWAP3:
+	    /* Swap two bytes, skipping one: "123" -> "321".  We change
+	     * "fword" here, it's changed back afterwards at STATE_UNSWAP3. */
+	    p = fword + sp->ts_fidx;
+#ifdef FEAT_MBYTE
+	    if (has_mbyte)
+	    {
+		n = mb_cptr2len(p);
+		c = mb_ptr2char(p);
+		fl = mb_cptr2len(p + n);
+		c2 = mb_ptr2char(p + n);
+		if (!soundfold && !spell_iswordp(p + n + fl, curbuf))
+		    c3 = c;	/* don't swap non-word char */
+		else
+		    c3 = mb_ptr2char(p + n + fl);
+	    }
+	    else
+#endif
+	    {
+		c = *p;
+		c2 = p[1];
+		if (!soundfold && !spell_iswordp(p + 2, curbuf))
+		    c3 = c;	/* don't swap non-word char */
+		else
+		    c3 = p[2];
+	    }
+
+	    /* When characters are identical: "121" then SWAP3 result is
+	     * identical, ROT3L result is same as SWAP: "211", ROT3L result is
+	     * same as SWAP on next char: "112".  Thus skip all swapping.
+	     * Also skip when c3 is NUL.
+	     * Also get here when the third character is not a word character.
+	     * Second character may any char: "a.b" -> "b.a" */
+	    if (c == c3 || c3 == NUL)
+	    {
+		sp->ts_state = STATE_REP_INI;
+		break;
+	    }
+	    if (TRY_DEEPER(su, stack, depth, SCORE_SWAP3))
+	    {
+		go_deeper(stack, depth, SCORE_SWAP3);
+#ifdef DEBUG_TRIEWALK
+		sprintf(changename[depth], "%.*s-%s: swap3 %c and %c",
+			sp->ts_twordlen, tword, fword + sp->ts_fidx,
+			c, c3);
+#endif
+		sp->ts_state = STATE_UNSWAP3;
+		++depth;
+#ifdef FEAT_MBYTE
+		if (has_mbyte)
+		{
+		    tl = mb_char2len(c3);
+		    mch_memmove(p, p + n + fl, tl);
+		    mb_char2bytes(c2, p + tl);
+		    mb_char2bytes(c, p + fl + tl);
+		    stack[depth].ts_fidxtry = sp->ts_fidx + n + fl + tl;
+		}
+		else
+#endif
+		{
+		    p[0] = p[2];
+		    p[2] = c;
+		    stack[depth].ts_fidxtry = sp->ts_fidx + 3;
+		}
+	    }
+	    else
+		sp->ts_state = STATE_REP_INI;
+	    break;
+
+	case STATE_UNSWAP3:
+	    /* Undo STATE_SWAP3: "321" -> "123" */
+	    p = fword + sp->ts_fidx;
+#ifdef FEAT_MBYTE
+	    if (has_mbyte)
+	    {
+		n = MB_BYTE2LEN(*p);
+		c2 = mb_ptr2char(p + n);
+		fl = MB_BYTE2LEN(p[n]);
+		c = mb_ptr2char(p + n + fl);
+		tl = MB_BYTE2LEN(p[n + fl]);
+		mch_memmove(p + fl + tl, p, n);
+		mb_char2bytes(c, p);
+		mb_char2bytes(c2, p + tl);
+		p = p + tl;
+	    }
+	    else
+#endif
+	    {
+		c = *p;
+		*p = p[2];
+		p[2] = c;
+		++p;
+	    }
+
+	    if (!soundfold && !spell_iswordp(p, curbuf))
+	    {
+		/* Middle char is not a word char, skip the rotate.  First and
+		 * third char were already checked at swap and swap3. */
+		sp->ts_state = STATE_REP_INI;
+		break;
+	    }
+
+	    /* Rotate three characters left: "123" -> "231".  We change
+	     * "fword" here, it's changed back afterwards at STATE_UNROT3L. */
+	    if (TRY_DEEPER(su, stack, depth, SCORE_SWAP3))
+	    {
+		go_deeper(stack, depth, SCORE_SWAP3);
+#ifdef DEBUG_TRIEWALK
+		p = fword + sp->ts_fidx;
+		sprintf(changename[depth], "%.*s-%s: rotate left %c%c%c",
+			sp->ts_twordlen, tword, fword + sp->ts_fidx,
+			p[0], p[1], p[2]);
+#endif
+		sp->ts_state = STATE_UNROT3L;
+		++depth;
+		p = fword + sp->ts_fidx;
+#ifdef FEAT_MBYTE
+		if (has_mbyte)
+		{
+		    n = mb_cptr2len(p);
+		    c = mb_ptr2char(p);
+		    fl = mb_cptr2len(p + n);
+		    fl += mb_cptr2len(p + n + fl);
+		    mch_memmove(p, p + n, fl);
+		    mb_char2bytes(c, p + fl);
+		    stack[depth].ts_fidxtry = sp->ts_fidx + n + fl;
+		}
+		else
+#endif
+		{
+		    c = *p;
+		    *p = p[1];
+		    p[1] = p[2];
+		    p[2] = c;
+		    stack[depth].ts_fidxtry = sp->ts_fidx + 3;
+		}
+	    }
+	    else
+		sp->ts_state = STATE_REP_INI;
+	    break;
+
+	case STATE_UNROT3L:
+	    /* Undo ROT3L: "231" -> "123" */
+	    p = fword + sp->ts_fidx;
+#ifdef FEAT_MBYTE
+	    if (has_mbyte)
+	    {
+		n = MB_BYTE2LEN(*p);
+		n += MB_BYTE2LEN(p[n]);
+		c = mb_ptr2char(p + n);
+		tl = MB_BYTE2LEN(p[n]);
+		mch_memmove(p + tl, p, n);
+		mb_char2bytes(c, p);
+	    }
+	    else
+#endif
+	    {
+		c = p[2];
+		p[2] = p[1];
+		p[1] = *p;
+		*p = c;
+	    }
+
+	    /* Rotate three bytes right: "123" -> "312".  We change "fword"
+	     * here, it's changed back afterwards at STATE_UNROT3R. */
+	    if (TRY_DEEPER(su, stack, depth, SCORE_SWAP3))
+	    {
+		go_deeper(stack, depth, SCORE_SWAP3);
+#ifdef DEBUG_TRIEWALK
+		p = fword + sp->ts_fidx;
+		sprintf(changename[depth], "%.*s-%s: rotate right %c%c%c",
+			sp->ts_twordlen, tword, fword + sp->ts_fidx,
+			p[0], p[1], p[2]);
+#endif
+		sp->ts_state = STATE_UNROT3R;
+		++depth;
+		p = fword + sp->ts_fidx;
+#ifdef FEAT_MBYTE
+		if (has_mbyte)
+		{
+		    n = mb_cptr2len(p);
+		    n += mb_cptr2len(p + n);
+		    c = mb_ptr2char(p + n);
+		    tl = mb_cptr2len(p + n);
+		    mch_memmove(p + tl, p, n);
+		    mb_char2bytes(c, p);
+		    stack[depth].ts_fidxtry = sp->ts_fidx + n + tl;
+		}
+		else
+#endif
+		{
+		    c = p[2];
+		    p[2] = p[1];
+		    p[1] = *p;
+		    *p = c;
+		    stack[depth].ts_fidxtry = sp->ts_fidx + 3;
+		}
+	    }
+	    else
+		sp->ts_state = STATE_REP_INI;
+	    break;
+
+	case STATE_UNROT3R:
+	    /* Undo ROT3R: "312" -> "123" */
+	    p = fword + sp->ts_fidx;
+#ifdef FEAT_MBYTE
+	    if (has_mbyte)
+	    {
+		c = mb_ptr2char(p);
+		tl = MB_BYTE2LEN(*p);
+		n = MB_BYTE2LEN(p[tl]);
+		n += MB_BYTE2LEN(p[tl + n]);
+		mch_memmove(p, p + tl, n);
+		mb_char2bytes(c, p + n);
+	    }
+	    else
+#endif
+	    {
+		c = *p;
+		*p = p[1];
+		p[1] = p[2];
+		p[2] = c;
+	    }
+	    /*FALLTHROUGH*/
+
+	case STATE_REP_INI:
+	    /* Check if matching with REP items from the .aff file would work.
+	     * Quickly skip if:
+	     * - there are no REP items and we are not in the soundfold trie
+	     * - the score is going to be too high anyway
+	     * - already applied a REP item or swapped here  */
+	    if ((lp->lp_replang == NULL && !soundfold)
+		    || sp->ts_score + SCORE_REP >= su->su_maxscore
+		    || sp->ts_fidx < sp->ts_fidxtry)
+	    {
+		sp->ts_state = STATE_FINAL;
+		break;
+	    }
+
+	    /* Use the first byte to quickly find the first entry that may
+	     * match.  If the index is -1 there is none. */
+	    if (soundfold)
+		sp->ts_curi = slang->sl_repsal_first[fword[sp->ts_fidx]];
+	    else
+		sp->ts_curi = lp->lp_replang->sl_rep_first[fword[sp->ts_fidx]];
+
+	    if (sp->ts_curi < 0)
+	    {
+		sp->ts_state = STATE_FINAL;
+		break;
+	    }
+
+	    sp->ts_state = STATE_REP;
+	    /*FALLTHROUGH*/
+
+	case STATE_REP:
+	    /* Try matching with REP items from the .aff file.  For each match
+	     * replace the characters and check if the resulting word is
+	     * valid. */
+	    p = fword + sp->ts_fidx;
+
+	    if (soundfold)
+		gap = &slang->sl_repsal;
+	    else
+		gap = &lp->lp_replang->sl_rep;
+	    while (sp->ts_curi < gap->ga_len)
+	    {
+		ftp = (fromto_T *)gap->ga_data + sp->ts_curi++;
+		if (*ftp->ft_from != *p)
+		{
+		    /* past possible matching entries */
+		    sp->ts_curi = gap->ga_len;
+		    break;
+		}
+		if (STRNCMP(ftp->ft_from, p, STRLEN(ftp->ft_from)) == 0
+			&& TRY_DEEPER(su, stack, depth, SCORE_REP))
+		{
+		    go_deeper(stack, depth, SCORE_REP);
+#ifdef DEBUG_TRIEWALK
+		    sprintf(changename[depth], "%.*s-%s: replace %s with %s",
+			    sp->ts_twordlen, tword, fword + sp->ts_fidx,
+			    ftp->ft_from, ftp->ft_to);
+#endif
+		    /* Need to undo this afterwards. */
+		    sp->ts_state = STATE_REP_UNDO;
+
+		    /* Change the "from" to the "to" string. */
+		    ++depth;
+		    fl = (int)STRLEN(ftp->ft_from);
+		    tl = (int)STRLEN(ftp->ft_to);
+		    if (fl != tl)
+		    {
+			mch_memmove(p + tl, p + fl, STRLEN(p + fl) + 1);
+			repextra += tl - fl;
+		    }
+		    mch_memmove(p, ftp->ft_to, tl);
+		    stack[depth].ts_fidxtry = sp->ts_fidx + tl;
+#ifdef FEAT_MBYTE
+		    stack[depth].ts_tcharlen = 0;
+#endif
+		    break;
+		}
+	    }
+
+	    if (sp->ts_curi >= gap->ga_len && sp->ts_state == STATE_REP)
+		/* No (more) matches. */
+		sp->ts_state = STATE_FINAL;
+
+	    break;
+
+	case STATE_REP_UNDO:
+	    /* Undo a REP replacement and continue with the next one. */
+	    if (soundfold)
+		gap = &slang->sl_repsal;
+	    else
+		gap = &lp->lp_replang->sl_rep;
+	    ftp = (fromto_T *)gap->ga_data + sp->ts_curi - 1;
+	    fl = (int)STRLEN(ftp->ft_from);
+	    tl = (int)STRLEN(ftp->ft_to);
+	    p = fword + sp->ts_fidx;
+	    if (fl != tl)
+	    {
+		mch_memmove(p + fl, p + tl, STRLEN(p + tl) + 1);
+		repextra -= tl - fl;
+	    }
+	    mch_memmove(p, ftp->ft_from, fl);
+	    sp->ts_state = STATE_REP;
+	    break;
+
+	default:
+	    /* Did all possible states at this level, go up one level. */
+	    --depth;
+
+	    if (depth >= 0 && stack[depth].ts_prefixdepth == PFD_PREFIXTREE)
+	    {
+		/* Continue in or go back to the prefix tree. */
+		byts = pbyts;
+		idxs = pidxs;
+	    }
+
+	    /* Don't check for CTRL-C too often, it takes time. */
+	    if (--breakcheckcount == 0)
+	    {
+		ui_breakcheck();
+		breakcheckcount = 1000;
+	    }
+	}
+    }
+}
+
+
+/*
+ * Go one level deeper in the tree.
+ */
+    static void
+go_deeper(stack, depth, score_add)
+    trystate_T	*stack;
+    int		depth;
+    int		score_add;
+{
+    stack[depth + 1] = stack[depth];
+    stack[depth + 1].ts_state = STATE_START;
+    stack[depth + 1].ts_score = stack[depth].ts_score + score_add;
+    stack[depth + 1].ts_curi = 1;	/* start just after length byte */
+    stack[depth + 1].ts_flags = 0;
+}
+
+#ifdef FEAT_MBYTE
+/*
+ * Case-folding may change the number of bytes: Count nr of chars in
+ * fword[flen] and return the byte length of that many chars in "word".
+ */
+    static int
+nofold_len(fword, flen, word)
+    char_u	*fword;
+    int		flen;
+    char_u	*word;
+{
+    char_u	*p;
+    int		i = 0;
+
+    for (p = fword; p < fword + flen; mb_ptr_adv(p))
+	++i;
+    for (p = word; i > 0; mb_ptr_adv(p))
+	--i;
+    return (int)(p - word);
+}
+#endif
+
+/*
+ * "fword" is a good word with case folded.  Find the matching keep-case
+ * words and put it in "kword".
+ * Theoretically there could be several keep-case words that result in the
+ * same case-folded word, but we only find one...
+ */
+    static void
+find_keepcap_word(slang, fword, kword)
+    slang_T	*slang;
+    char_u	*fword;
+    char_u	*kword;
+{
+    char_u	uword[MAXWLEN];		/* "fword" in upper-case */
+    int		depth;
+    idx_T	tryidx;
+
+    /* The following arrays are used at each depth in the tree. */
+    idx_T	arridx[MAXWLEN];
+    int		round[MAXWLEN];
+    int		fwordidx[MAXWLEN];
+    int		uwordidx[MAXWLEN];
+    int		kwordlen[MAXWLEN];
+
+    int		flen, ulen;
+    int		l;
+    int		len;
+    int		c;
+    idx_T	lo, hi, m;
+    char_u	*p;
+    char_u	*byts = slang->sl_kbyts;    /* array with bytes of the words */
+    idx_T	*idxs = slang->sl_kidxs;    /* array with indexes */
+
+    if (byts == NULL)
+    {
+	/* array is empty: "cannot happen" */
+	*kword = NUL;
+	return;
+    }
+
+    /* Make an all-cap version of "fword". */
+    allcap_copy(fword, uword);
+
+    /*
+     * Each character needs to be tried both case-folded and upper-case.
+     * All this gets very complicated if we keep in mind that changing case
+     * may change the byte length of a multi-byte character...
+     */
+    depth = 0;
+    arridx[0] = 0;
+    round[0] = 0;
+    fwordidx[0] = 0;
+    uwordidx[0] = 0;
+    kwordlen[0] = 0;
+    while (depth >= 0)
+    {
+	if (fword[fwordidx[depth]] == NUL)
+	{
+	    /* We are at the end of "fword".  If the tree allows a word to end
+	     * here we have found a match. */
+	    if (byts[arridx[depth] + 1] == 0)
+	    {
+		kword[kwordlen[depth]] = NUL;
+		return;
+	    }
+
+	    /* kword is getting too long, continue one level up */
+	    --depth;
+	}
+	else if (++round[depth] > 2)
+	{
+	    /* tried both fold-case and upper-case character, continue one
+	     * level up */
+	    --depth;
+	}
+	else
+	{
+	    /*
+	     * round[depth] == 1: Try using the folded-case character.
+	     * round[depth] == 2: Try using the upper-case character.
+	     */
+#ifdef FEAT_MBYTE
+	    if (has_mbyte)
+	    {
+		flen = mb_cptr2len(fword + fwordidx[depth]);
+		ulen = mb_cptr2len(uword + uwordidx[depth]);
+	    }
+	    else
+#endif
+		ulen = flen = 1;
+	    if (round[depth] == 1)
+	    {
+		p = fword + fwordidx[depth];
+		l = flen;
+	    }
+	    else
+	    {
+		p = uword + uwordidx[depth];
+		l = ulen;
+	    }
+
+	    for (tryidx = arridx[depth]; l > 0; --l)
+	    {
+		/* Perform a binary search in the list of accepted bytes. */
+		len = byts[tryidx++];
+		c = *p++;
+		lo = tryidx;
+		hi = tryidx + len - 1;
+		while (lo < hi)
+		{
+		    m = (lo + hi) / 2;
+		    if (byts[m] > c)
+			hi = m - 1;
+		    else if (byts[m] < c)
+			lo = m + 1;
+		    else
+		    {
+			lo = hi = m;
+			break;
+		    }
+		}
+
+		/* Stop if there is no matching byte. */
+		if (hi < lo || byts[lo] != c)
+		    break;
+
+		/* Continue at the child (if there is one). */
+		tryidx = idxs[lo];
+	    }
+
+	    if (l == 0)
+	    {
+		/*
+		 * Found the matching char.  Copy it to "kword" and go a
+		 * level deeper.
+		 */
+		if (round[depth] == 1)
+		{
+		    STRNCPY(kword + kwordlen[depth], fword + fwordidx[depth],
+									flen);
+		    kwordlen[depth + 1] = kwordlen[depth] + flen;
+		}
+		else
+		{
+		    STRNCPY(kword + kwordlen[depth], uword + uwordidx[depth],
+									ulen);
+		    kwordlen[depth + 1] = kwordlen[depth] + ulen;
+		}
+		fwordidx[depth + 1] = fwordidx[depth] + flen;
+		uwordidx[depth + 1] = uwordidx[depth] + ulen;
+
+		++depth;
+		arridx[depth] = tryidx;
+		round[depth] = 0;
+	    }
+	}
+    }
+
+    /* Didn't find it: "cannot happen". */
+    *kword = NUL;
+}
+
+/*
+ * Compute the sound-a-like score for suggestions in su->su_ga and add them to
+ * su->su_sga.
+ */
+    static void
+score_comp_sal(su)
+    suginfo_T	*su;
+{
+    langp_T	*lp;
+    char_u	badsound[MAXWLEN];
+    int		i;
+    suggest_T   *stp;
+    suggest_T   *sstp;
+    int		score;
+    int		lpi;
+
+    if (ga_grow(&su->su_sga, su->su_ga.ga_len) == FAIL)
+	return;
+
+    /*	Use the sound-folding of the first language that supports it. */
+    for (lpi = 0; lpi < curbuf->b_langp.ga_len; ++lpi)
+    {
+	lp = LANGP_ENTRY(curbuf->b_langp, lpi);
+	if (lp->lp_slang->sl_sal.ga_len > 0)
+	{
+	    /* soundfold the bad word */
+	    spell_soundfold(lp->lp_slang, su->su_fbadword, TRUE, badsound);
+
+	    for (i = 0; i < su->su_ga.ga_len; ++i)
+	    {
+		stp = &SUG(su->su_ga, i);
+
+		/* Case-fold the suggested word, sound-fold it and compute the
+		 * sound-a-like score. */
+		score = stp_sal_score(stp, su, lp->lp_slang, badsound);
+		if (score < SCORE_MAXMAX)
+		{
+		    /* Add the suggestion. */
+		    sstp = &SUG(su->su_sga, su->su_sga.ga_len);
+		    sstp->st_word = vim_strsave(stp->st_word);
+		    if (sstp->st_word != NULL)
+		    {
+			sstp->st_wordlen = stp->st_wordlen;
+			sstp->st_score = score;
+			sstp->st_altscore = 0;
+			sstp->st_orglen = stp->st_orglen;
+			++su->su_sga.ga_len;
+		    }
+		}
+	    }
+	    break;
+	}
+    }
+}
+
+/*
+ * Combine the list of suggestions in su->su_ga and su->su_sga.
+ * They are intwined.
+ */
+    static void
+score_combine(su)
+    suginfo_T	*su;
+{
+    int		i;
+    int		j;
+    garray_T	ga;
+    garray_T	*gap;
+    langp_T	*lp;
+    suggest_T	*stp;
+    char_u	*p;
+    char_u	badsound[MAXWLEN];
+    int		round;
+    int		lpi;
+    slang_T	*slang = NULL;
+
+    /* Add the alternate score to su_ga. */
+    for (lpi = 0; lpi < curbuf->b_langp.ga_len; ++lpi)
+    {
+	lp = LANGP_ENTRY(curbuf->b_langp, lpi);
+	if (lp->lp_slang->sl_sal.ga_len > 0)
+	{
+	    /* soundfold the bad word */
+	    slang = lp->lp_slang;
+	    spell_soundfold(slang, su->su_fbadword, TRUE, badsound);
+
+	    for (i = 0; i < su->su_ga.ga_len; ++i)
+	    {
+		stp = &SUG(su->su_ga, i);
+		stp->st_altscore = stp_sal_score(stp, su, slang, badsound);
+		if (stp->st_altscore == SCORE_MAXMAX)
+		    stp->st_score = (stp->st_score * 3 + SCORE_BIG) / 4;
+		else
+		    stp->st_score = (stp->st_score * 3
+						  + stp->st_altscore) / 4;
+		stp->st_salscore = FALSE;
+	    }
+	    break;
+	}
+    }
+
+    if (slang == NULL)	/* Using "double" without sound folding. */
+    {
+	(void)cleanup_suggestions(&su->su_ga, su->su_maxscore,
+							     su->su_maxcount);
+	return;
+    }
+
+    /* Add the alternate score to su_sga. */
+    for (i = 0; i < su->su_sga.ga_len; ++i)
+    {
+	stp = &SUG(su->su_sga, i);
+	stp->st_altscore = spell_edit_score(slang,
+						su->su_badword, stp->st_word);
+	if (stp->st_score == SCORE_MAXMAX)
+	    stp->st_score = (SCORE_BIG * 7 + stp->st_altscore) / 8;
+	else
+	    stp->st_score = (stp->st_score * 7 + stp->st_altscore) / 8;
+	stp->st_salscore = TRUE;
+    }
+
+    /* Remove bad suggestions, sort the suggestions and truncate at "maxcount"
+     * for both lists. */
+    check_suggestions(su, &su->su_ga);
+    (void)cleanup_suggestions(&su->su_ga, su->su_maxscore, su->su_maxcount);
+    check_suggestions(su, &su->su_sga);
+    (void)cleanup_suggestions(&su->su_sga, su->su_maxscore, su->su_maxcount);
+
+    ga_init2(&ga, (int)sizeof(suginfo_T), 1);
+    if (ga_grow(&ga, su->su_ga.ga_len + su->su_sga.ga_len) == FAIL)
+	return;
+
+    stp = &SUG(ga, 0);
+    for (i = 0; i < su->su_ga.ga_len || i < su->su_sga.ga_len; ++i)
+    {
+	/* round 1: get a suggestion from su_ga
+	 * round 2: get a suggestion from su_sga */
+	for (round = 1; round <= 2; ++round)
+	{
+	    gap = round == 1 ? &su->su_ga : &su->su_sga;
+	    if (i < gap->ga_len)
+	    {
+		/* Don't add a word if it's already there. */
+		p = SUG(*gap, i).st_word;
+		for (j = 0; j < ga.ga_len; ++j)
+		    if (STRCMP(stp[j].st_word, p) == 0)
+			break;
+		if (j == ga.ga_len)
+		    stp[ga.ga_len++] = SUG(*gap, i);
+		else
+		    vim_free(p);
+	    }
+	}
+    }
+
+    ga_clear(&su->su_ga);
+    ga_clear(&su->su_sga);
+
+    /* Truncate the list to the number of suggestions that will be displayed. */
+    if (ga.ga_len > su->su_maxcount)
+    {
+	for (i = su->su_maxcount; i < ga.ga_len; ++i)
+	    vim_free(stp[i].st_word);
+	ga.ga_len = su->su_maxcount;
+    }
+
+    su->su_ga = ga;
+}
+
+/*
+ * For the goodword in "stp" compute the soundalike score compared to the
+ * badword.
+ */
+    static int
+stp_sal_score(stp, su, slang, badsound)
+    suggest_T	*stp;
+    suginfo_T	*su;
+    slang_T	*slang;
+    char_u	*badsound;	/* sound-folded badword */
+{
+    char_u	*p;
+    char_u	*pbad;
+    char_u	*pgood;
+    char_u	badsound2[MAXWLEN];
+    char_u	fword[MAXWLEN];
+    char_u	goodsound[MAXWLEN];
+    char_u	goodword[MAXWLEN];
+    int		lendiff;
+
+    lendiff = (int)(su->su_badlen - stp->st_orglen);
+    if (lendiff >= 0)
+	pbad = badsound;
+    else
+    {
+	/* soundfold the bad word with more characters following */
+	(void)spell_casefold(su->su_badptr, stp->st_orglen, fword, MAXWLEN);
+
+	/* When joining two words the sound often changes a lot.  E.g., "t he"
+	 * sounds like "t h" while "the" sounds like "@".  Avoid that by
+	 * removing the space.  Don't do it when the good word also contains a
+	 * space. */
+	if (vim_iswhite(su->su_badptr[su->su_badlen])
+					 && *skiptowhite(stp->st_word) == NUL)
+	    for (p = fword; *(p = skiptowhite(p)) != NUL; )
+		mch_memmove(p, p + 1, STRLEN(p));
+
+	spell_soundfold(slang, fword, TRUE, badsound2);
+	pbad = badsound2;
+    }
+
+    if (lendiff > 0)
+    {
+	/* Add part of the bad word to the good word, so that we soundfold
+	 * what replaces the bad word. */
+	STRCPY(goodword, stp->st_word);
+	vim_strncpy(goodword + stp->st_wordlen,
+			    su->su_badptr + su->su_badlen - lendiff, lendiff);
+	pgood = goodword;
+    }
+    else
+	pgood = stp->st_word;
+
+    /* Sound-fold the word and compute the score for the difference. */
+    spell_soundfold(slang, pgood, FALSE, goodsound);
+
+    return soundalike_score(goodsound, pbad);
+}
+
+/* structure used to store soundfolded words that add_sound_suggest() has
+ * handled already. */
+typedef struct
+{
+    short	sft_score;	/* lowest score used */
+    char_u	sft_word[1];    /* soundfolded word, actually longer */
+} sftword_T;
+
+static sftword_T dumsft;
+#define HIKEY2SFT(p)  ((sftword_T *)(p - (dumsft.sft_word - (char_u *)&dumsft)))
+#define HI2SFT(hi)     HIKEY2SFT((hi)->hi_key)
+
+/*
+ * Prepare for calling suggest_try_soundalike().
+ */
+    static void
+suggest_try_soundalike_prep()
+{
+    langp_T	*lp;
+    int		lpi;
+    slang_T	*slang;
+
+    /* Do this for all languages that support sound folding and for which a
+     * .sug file has been loaded. */
+    for (lpi = 0; lpi < curbuf->b_langp.ga_len; ++lpi)
+    {
+	lp = LANGP_ENTRY(curbuf->b_langp, lpi);
+	slang = lp->lp_slang;
+	if (slang->sl_sal.ga_len > 0 && slang->sl_sbyts != NULL)
+	    /* prepare the hashtable used by add_sound_suggest() */
+	    hash_init(&slang->sl_sounddone);
+    }
+}
+
+/*
+ * Find suggestions by comparing the word in a sound-a-like form.
+ * Note: This doesn't support postponed prefixes.
+ */
+    static void
+suggest_try_soundalike(su)
+    suginfo_T	*su;
+{
+    char_u	salword[MAXWLEN];
+    langp_T	*lp;
+    int		lpi;
+    slang_T	*slang;
+
+    /* Do this for all languages that support sound folding and for which a
+     * .sug file has been loaded. */
+    for (lpi = 0; lpi < curbuf->b_langp.ga_len; ++lpi)
+    {
+	lp = LANGP_ENTRY(curbuf->b_langp, lpi);
+	slang = lp->lp_slang;
+	if (slang->sl_sal.ga_len > 0 && slang->sl_sbyts != NULL)
+	{
+	    /* soundfold the bad word */
+	    spell_soundfold(slang, su->su_fbadword, TRUE, salword);
+
+	    /* try all kinds of inserts/deletes/swaps/etc. */
+	    /* TODO: also soundfold the next words, so that we can try joining
+	     * and splitting */
+	    suggest_trie_walk(su, lp, salword, TRUE);
+	}
+    }
+}
+
+/*
+ * Finish up after calling suggest_try_soundalike().
+ */
+    static void
+suggest_try_soundalike_finish()
+{
+    langp_T	*lp;
+    int		lpi;
+    slang_T	*slang;
+    int		todo;
+    hashitem_T	*hi;
+
+    /* Do this for all languages that support sound folding and for which a
+     * .sug file has been loaded. */
+    for (lpi = 0; lpi < curbuf->b_langp.ga_len; ++lpi)
+    {
+	lp = LANGP_ENTRY(curbuf->b_langp, lpi);
+	slang = lp->lp_slang;
+	if (slang->sl_sal.ga_len > 0 && slang->sl_sbyts != NULL)
+	{
+	    /* Free the info about handled words. */
+	    todo = (int)slang->sl_sounddone.ht_used;
+	    for (hi = slang->sl_sounddone.ht_array; todo > 0; ++hi)
+		if (!HASHITEM_EMPTY(hi))
+		{
+		    vim_free(HI2SFT(hi));
+		    --todo;
+		}
+
+	    /* Clear the hashtable, it may also be used by another region. */
+	    hash_clear(&slang->sl_sounddone);
+	    hash_init(&slang->sl_sounddone);
+	}
+    }
+}
+
+/*
+ * A match with a soundfolded word is found.  Add the good word(s) that
+ * produce this soundfolded word.
+ */
+    static void
+add_sound_suggest(su, goodword, score, lp)
+    suginfo_T	*su;
+    char_u	*goodword;
+    int		score;		/* soundfold score  */
+    langp_T	*lp;
+{
+    slang_T	*slang = lp->lp_slang;	/* language for sound folding */
+    int		sfwordnr;
+    char_u	*nrline;
+    int		orgnr;
+    char_u	theword[MAXWLEN];
+    int		i;
+    int		wlen;
+    char_u	*byts;
+    idx_T	*idxs;
+    int		n;
+    int		wordcount;
+    int		wc;
+    int		goodscore;
+    hash_T	hash;
+    hashitem_T  *hi;
+    sftword_T	*sft;
+    int		bc, gc;
+    int		limit;
+
+    /*
+     * It's very well possible that the same soundfold word is found several
+     * times with different scores.  Since the following is quite slow only do
+     * the words that have a better score than before.  Use a hashtable to
+     * remember the words that have been done.
+     */
+    hash = hash_hash(goodword);
+    hi = hash_lookup(&slang->sl_sounddone, goodword, hash);
+    if (HASHITEM_EMPTY(hi))
+    {
+	sft = (sftword_T *)alloc((unsigned)(sizeof(sftword_T)
+							 + STRLEN(goodword)));
+	if (sft != NULL)
+	{
+	    sft->sft_score = score;
+	    STRCPY(sft->sft_word, goodword);
+	    hash_add_item(&slang->sl_sounddone, hi, sft->sft_word, hash);
+	}
+    }
+    else
+    {
+	sft = HI2SFT(hi);
+	if (score >= sft->sft_score)
+	    return;
+	sft->sft_score = score;
+    }
+
+    /*
+     * Find the word nr in the soundfold tree.
+     */
+    sfwordnr = soundfold_find(slang, goodword);
+    if (sfwordnr < 0)
+    {
+	EMSG2(_(e_intern2), "add_sound_suggest()");
+	return;
+    }
+
+    /*
+     * go over the list of good words that produce this soundfold word
+     */
+    nrline = ml_get_buf(slang->sl_sugbuf, (linenr_T)(sfwordnr + 1), FALSE);
+    orgnr = 0;
+    while (*nrline != NUL)
+    {
+	/* The wordnr was stored in a minimal nr of bytes as an offset to the
+	 * previous wordnr. */
+	orgnr += bytes2offset(&nrline);
+
+	byts = slang->sl_fbyts;
+	idxs = slang->sl_fidxs;
+
+	/* Lookup the word "orgnr" one of the two tries. */
+	n = 0;
+	wlen = 0;
+	wordcount = 0;
+	for (;;)
+	{
+	    i = 1;
+	    if (wordcount == orgnr && byts[n + 1] == NUL)
+		break;	/* found end of word */
+
+	    if (byts[n + 1] == NUL)
+		++wordcount;
+
+	    /* skip over the NUL bytes */
+	    for ( ; byts[n + i] == NUL; ++i)
+		if (i > byts[n])	/* safety check */
+		{
+		    STRCPY(theword + wlen, "BAD");
+		    goto badword;
+		}
+
+	    /* One of the siblings must have the word. */
+	    for ( ; i < byts[n]; ++i)
+	    {
+		wc = idxs[idxs[n + i]];	/* nr of words under this byte */
+		if (wordcount + wc > orgnr)
+		    break;
+		wordcount += wc;
+	    }
+
+	    theword[wlen++] = byts[n + i];
+	    n = idxs[n + i];
+	}
+badword:
+	theword[wlen] = NUL;
+
+	/* Go over the possible flags and regions. */
+	for (; i <= byts[n] && byts[n + i] == NUL; ++i)
+	{
+	    char_u	cword[MAXWLEN];
+	    char_u	*p;
+	    int		flags = (int)idxs[n + i];
+
+	    /* Skip words with the NOSUGGEST flag */
+	    if (flags & WF_NOSUGGEST)
+		continue;
+
+	    if (flags & WF_KEEPCAP)
+	    {
+		/* Must find the word in the keep-case tree. */
+		find_keepcap_word(slang, theword, cword);
+		p = cword;
+	    }
+	    else
+	    {
+		flags |= su->su_badflags;
+		if ((flags & WF_CAPMASK) != 0)
+		{
+		    /* Need to fix case according to "flags". */
+		    make_case_word(theword, cword, flags);
+		    p = cword;
+		}
+		else
+		    p = theword;
+	    }
+
+	    /* Add the suggestion. */
+	    if (sps_flags & SPS_DOUBLE)
+	    {
+		/* Add the suggestion if the score isn't too bad. */
+		if (score <= su->su_maxscore)
+		    add_suggestion(su, &su->su_sga, p, su->su_badlen,
+					       score, 0, FALSE, slang, FALSE);
+	    }
+	    else
+	    {
+		/* Add a penalty for words in another region. */
+		if ((flags & WF_REGION)
+			    && (((unsigned)flags >> 16) & lp->lp_region) == 0)
+		    goodscore = SCORE_REGION;
+		else
+		    goodscore = 0;
+
+		/* Add a small penalty for changing the first letter from
+		 * lower to upper case.  Helps for "tath" -> "Kath", which is
+		 * less common thatn "tath" -> "path".  Don't do it when the
+		 * letter is the same, that has already been counted. */
+		gc = PTR2CHAR(p);
+		if (SPELL_ISUPPER(gc))
+		{
+		    bc = PTR2CHAR(su->su_badword);
+		    if (!SPELL_ISUPPER(bc)
+				      && SPELL_TOFOLD(bc) != SPELL_TOFOLD(gc))
+			goodscore += SCORE_ICASE / 2;
+		}
+
+		/* Compute the score for the good word.  This only does letter
+		 * insert/delete/swap/replace.  REP items are not considered,
+		 * which may make the score a bit higher.
+		 * Use a limit for the score to make it work faster.  Use
+		 * MAXSCORE(), because RESCORE() will change the score.
+		 * If the limit is very high then the iterative method is
+		 * inefficient, using an array is quicker. */
+		limit = MAXSCORE(su->su_sfmaxscore - goodscore, score);
+		if (limit > SCORE_LIMITMAX)
+		    goodscore += spell_edit_score(slang, su->su_badword, p);
+		else
+		    goodscore += spell_edit_score_limit(slang, su->su_badword,
+								    p, limit);
+
+		/* When going over the limit don't bother to do the rest. */
+		if (goodscore < SCORE_MAXMAX)
+		{
+		    /* Give a bonus to words seen before. */
+		    goodscore = score_wordcount_adj(slang, goodscore, p, FALSE);
+
+		    /* Add the suggestion if the score isn't too bad. */
+		    goodscore = RESCORE(goodscore, score);
+		    if (goodscore <= su->su_sfmaxscore)
+			add_suggestion(su, &su->su_ga, p, su->su_badlen,
+					 goodscore, score, TRUE, slang, TRUE);
+		}
+	    }
+	}
+	/* smsg("word %s (%d): %s (%d)", sftword, sftnr, theword, orgnr); */
+    }
+}
+
+/*
+ * Find word "word" in fold-case tree for "slang" and return the word number.
+ */
+    static int
+soundfold_find(slang, word)
+    slang_T	*slang;
+    char_u	*word;
+{
+    idx_T	arridx = 0;
+    int		len;
+    int		wlen = 0;
+    int		c;
+    char_u	*ptr = word;
+    char_u	*byts;
+    idx_T	*idxs;
+    int		wordnr = 0;
+
+    byts = slang->sl_sbyts;
+    idxs = slang->sl_sidxs;
+
+    for (;;)
+    {
+	/* First byte is the number of possible bytes. */
+	len = byts[arridx++];
+
+	/* If the first possible byte is a zero the word could end here.
+	 * If the word ends we found the word.  If not skip the NUL bytes. */
+	c = ptr[wlen];
+	if (byts[arridx] == NUL)
+	{
+	    if (c == NUL)
+		break;
+
+	    /* Skip over the zeros, there can be several. */
+	    while (len > 0 && byts[arridx] == NUL)
+	    {
+		++arridx;
+		--len;
+	    }
+	    if (len == 0)
+		return -1;    /* no children, word should have ended here */
+	    ++wordnr;
+	}
+
+	/* If the word ends we didn't find it. */
+	if (c == NUL)
+	    return -1;
+
+	/* Perform a binary search in the list of accepted bytes. */
+	if (c == TAB)	    /* <Tab> is handled like <Space> */
+	    c = ' ';
+	while (byts[arridx] < c)
+	{
+	    /* The word count is in the first idxs[] entry of the child. */
+	    wordnr += idxs[idxs[arridx]];
+	    ++arridx;
+	    if (--len == 0)	/* end of the bytes, didn't find it */
+		return -1;
+	}
+	if (byts[arridx] != c)	/* didn't find the byte */
+	    return -1;
+
+	/* Continue at the child (if there is one). */
+	arridx = idxs[arridx];
+	++wlen;
+
+	/* One space in the good word may stand for several spaces in the
+	 * checked word. */
+	if (c == ' ')
+	    while (ptr[wlen] == ' ' || ptr[wlen] == TAB)
+		++wlen;
+    }
+
+    return wordnr;
+}
+
+/*
+ * Copy "fword" to "cword", fixing case according to "flags".
+ */
+    static void
+make_case_word(fword, cword, flags)
+    char_u	*fword;
+    char_u	*cword;
+    int		flags;
+{
+    if (flags & WF_ALLCAP)
+	/* Make it all upper-case */
+	allcap_copy(fword, cword);
+    else if (flags & WF_ONECAP)
+	/* Make the first letter upper-case */
+	onecap_copy(fword, cword, TRUE);
+    else
+	/* Use goodword as-is. */
+	STRCPY(cword, fword);
+}
+
+/*
+ * Use map string "map" for languages "lp".
+ */
+    static void
+set_map_str(lp, map)
+    slang_T	*lp;
+    char_u	*map;
+{
+    char_u	*p;
+    int		headc = 0;
+    int		c;
+    int		i;
+
+    if (*map == NUL)
+    {
+	lp->sl_has_map = FALSE;
+	return;
+    }
+    lp->sl_has_map = TRUE;
+
+    /* Init the array and hash tables empty. */
+    for (i = 0; i < 256; ++i)
+	lp->sl_map_array[i] = 0;
+#ifdef FEAT_MBYTE
+    hash_init(&lp->sl_map_hash);
+#endif
+
+    /*
+     * The similar characters are stored separated with slashes:
+     * "aaa/bbb/ccc/".  Fill sl_map_array[c] with the character before c and
+     * before the same slash.  For characters above 255 sl_map_hash is used.
+     */
+    for (p = map; *p != NUL; )
+    {
+#ifdef FEAT_MBYTE
+	c = mb_cptr2char_adv(&p);
+#else
+	c = *p++;
+#endif
+	if (c == '/')
+	    headc = 0;
+	else
+	{
+	    if (headc == 0)
+		 headc = c;
+
+#ifdef FEAT_MBYTE
+	    /* Characters above 255 don't fit in sl_map_array[], put them in
+	     * the hash table.  Each entry is the char, a NUL the headchar and
+	     * a NUL. */
+	    if (c >= 256)
+	    {
+		int	    cl = mb_char2len(c);
+		int	    headcl = mb_char2len(headc);
+		char_u	    *b;
+		hash_T	    hash;
+		hashitem_T  *hi;
+
+		b = alloc((unsigned)(cl + headcl + 2));
+		if (b == NULL)
+		    return;
+		mb_char2bytes(c, b);
+		b[cl] = NUL;
+		mb_char2bytes(headc, b + cl + 1);
+		b[cl + 1 + headcl] = NUL;
+		hash = hash_hash(b);
+		hi = hash_lookup(&lp->sl_map_hash, b, hash);
+		if (HASHITEM_EMPTY(hi))
+		    hash_add_item(&lp->sl_map_hash, hi, b, hash);
+		else
+		{
+		    /* This should have been checked when generating the .spl
+		     * file. */
+		    EMSG(_("E783: duplicate char in MAP entry"));
+		    vim_free(b);
+		}
+	    }
+	    else
+#endif
+		lp->sl_map_array[c] = headc;
+	}
+    }
+}
+
+/*
+ * Return TRUE if "c1" and "c2" are similar characters according to the MAP
+ * lines in the .aff file.
+ */
+    static int
+similar_chars(slang, c1, c2)
+    slang_T	*slang;
+    int		c1;
+    int		c2;
+{
+    int		m1, m2;
+#ifdef FEAT_MBYTE
+    char_u	buf[MB_MAXBYTES];
+    hashitem_T  *hi;
+
+    if (c1 >= 256)
+    {
+	buf[mb_char2bytes(c1, buf)] = 0;
+	hi = hash_find(&slang->sl_map_hash, buf);
+	if (HASHITEM_EMPTY(hi))
+	    m1 = 0;
+	else
+	    m1 = mb_ptr2char(hi->hi_key + STRLEN(hi->hi_key) + 1);
+    }
+    else
+#endif
+	m1 = slang->sl_map_array[c1];
+    if (m1 == 0)
+	return FALSE;
+
+
+#ifdef FEAT_MBYTE
+    if (c2 >= 256)
+    {
+	buf[mb_char2bytes(c2, buf)] = 0;
+	hi = hash_find(&slang->sl_map_hash, buf);
+	if (HASHITEM_EMPTY(hi))
+	    m2 = 0;
+	else
+	    m2 = mb_ptr2char(hi->hi_key + STRLEN(hi->hi_key) + 1);
+    }
+    else
+#endif
+	m2 = slang->sl_map_array[c2];
+
+    return m1 == m2;
+}
+
+/*
+ * Add a suggestion to the list of suggestions.
+ * For a suggestion that is already in the list the lowest score is remembered.
+ */
+    static void
+add_suggestion(su, gap, goodword, badlenarg, score, altscore, had_bonus,
+								 slang, maxsf)
+    suginfo_T	*su;
+    garray_T	*gap;		/* either su_ga or su_sga */
+    char_u	*goodword;
+    int		badlenarg;	/* len of bad word replaced with "goodword" */
+    int		score;
+    int		altscore;
+    int		had_bonus;	/* value for st_had_bonus */
+    slang_T	*slang;		/* language for sound folding */
+    int		maxsf;		/* su_maxscore applies to soundfold score,
+				   su_sfmaxscore to the total score. */
+{
+    int		goodlen;	/* len of goodword changed */
+    int		badlen;		/* len of bad word changed */
+    suggest_T   *stp;
+    suggest_T   new_sug;
+    int		i;
+    char_u	*pgood, *pbad;
+
+    /* Minimize "badlen" for consistency.  Avoids that changing "the the" to
+     * "thee the" is added next to changing the first "the" the "thee".  */
+    pgood = goodword + STRLEN(goodword);
+    pbad = su->su_badptr + badlenarg;
+    for (;;)
+    {
+	goodlen = (int)(pgood - goodword);
+	badlen = (int)(pbad - su->su_badptr);
+	if (goodlen <= 0 || badlen <= 0)
+	    break;
+	mb_ptr_back(goodword, pgood);
+	mb_ptr_back(su->su_badptr, pbad);
+#ifdef FEAT_MBYTE
+	if (has_mbyte)
+	{
+	    if (mb_ptr2char(pgood) != mb_ptr2char(pbad))
+		break;
+	}
+	else
+#endif
+	    if (*pgood != *pbad)
+		break;
+    }
+
+    if (badlen == 0 && goodlen == 0)
+	/* goodword doesn't change anything; may happen for "the the" changing
+	 * the first "the" to itself. */
+	return;
+
+    if (gap->ga_len == 0)
+	i = -1;
+    else
+    {
+	/* Check if the word is already there.  Also check the length that is
+	 * being replaced "thes," -> "these" is a different suggestion from
+	 * "thes" -> "these". */
+	stp = &SUG(*gap, 0);
+	for (i = gap->ga_len; --i >= 0; ++stp)
+	    if (stp->st_wordlen == goodlen
+		    && stp->st_orglen == badlen
+		    && STRNCMP(stp->st_word, goodword, goodlen) == 0)
+	    {
+		/*
+		 * Found it.  Remember the word with the lowest score.
+		 */
+		if (stp->st_slang == NULL)
+		    stp->st_slang = slang;
+
+		new_sug.st_score = score;
+		new_sug.st_altscore = altscore;
+		new_sug.st_had_bonus = had_bonus;
+
+		if (stp->st_had_bonus != had_bonus)
+		{
+		    /* Only one of the two had the soundalike score computed.
+		     * Need to do that for the other one now, otherwise the
+		     * scores can't be compared.  This happens because
+		     * suggest_try_change() doesn't compute the soundalike
+		     * word to keep it fast, while some special methods set
+		     * the soundalike score to zero. */
+		    if (had_bonus)
+			rescore_one(su, stp);
+		    else
+		    {
+			new_sug.st_word = stp->st_word;
+			new_sug.st_wordlen = stp->st_wordlen;
+			new_sug.st_slang = stp->st_slang;
+			new_sug.st_orglen = badlen;
+			rescore_one(su, &new_sug);
+		    }
+		}
+
+		if (stp->st_score > new_sug.st_score)
+		{
+		    stp->st_score = new_sug.st_score;
+		    stp->st_altscore = new_sug.st_altscore;
+		    stp->st_had_bonus = new_sug.st_had_bonus;
+		}
+		break;
+	    }
+    }
+
+    if (i < 0 && ga_grow(gap, 1) == OK)
+    {
+	/* Add a suggestion. */
+	stp = &SUG(*gap, gap->ga_len);
+	stp->st_word = vim_strnsave(goodword, goodlen);
+	if (stp->st_word != NULL)
+	{
+	    stp->st_wordlen = goodlen;
+	    stp->st_score = score;
+	    stp->st_altscore = altscore;
+	    stp->st_had_bonus = had_bonus;
+	    stp->st_orglen = badlen;
+	    stp->st_slang = slang;
+	    ++gap->ga_len;
+
+	    /* If we have too many suggestions now, sort the list and keep
+	     * the best suggestions. */
+	    if (gap->ga_len > SUG_MAX_COUNT(su))
+	    {
+		if (maxsf)
+		    su->su_sfmaxscore = cleanup_suggestions(gap,
+				      su->su_sfmaxscore, SUG_CLEAN_COUNT(su));
+		else
+		{
+		    i = su->su_maxscore;
+		    su->su_maxscore = cleanup_suggestions(gap,
+					su->su_maxscore, SUG_CLEAN_COUNT(su));
+		}
+	    }
+	}
+    }
+}
+
+/*
+ * Suggestions may in fact be flagged as errors.  Esp. for banned words and
+ * for split words, such as "the the".  Remove these from the list here.
+ */
+    static void
+check_suggestions(su, gap)
+    suginfo_T	*su;
+    garray_T	*gap;		    /* either su_ga or su_sga */
+{
+    suggest_T   *stp;
+    int		i;
+    char_u	longword[MAXWLEN + 1];
+    int		len;
+    hlf_T	attr;
+
+    stp = &SUG(*gap, 0);
+    for (i = gap->ga_len - 1; i >= 0; --i)
+    {
+	/* Need to append what follows to check for "the the". */
+	STRCPY(longword, stp[i].st_word);
+	len = stp[i].st_wordlen;
+	vim_strncpy(longword + len, su->su_badptr + stp[i].st_orglen,
+							       MAXWLEN - len);
+	attr = HLF_COUNT;
+	(void)spell_check(curwin, longword, &attr, NULL, FALSE);
+	if (attr != HLF_COUNT)
+	{
+	    /* Remove this entry. */
+	    vim_free(stp[i].st_word);
+	    --gap->ga_len;
+	    if (i < gap->ga_len)
+		mch_memmove(stp + i, stp + i + 1,
+				       sizeof(suggest_T) * (gap->ga_len - i));
+	}
+    }
+}
+
+
+/*
+ * Add a word to be banned.
+ */
+    static void
+add_banned(su, word)
+    suginfo_T	*su;
+    char_u	*word;
+{
+    char_u	*s;
+    hash_T	hash;
+    hashitem_T	*hi;
+
+    hash = hash_hash(word);
+    hi = hash_lookup(&su->su_banned, word, hash);
+    if (HASHITEM_EMPTY(hi))
+    {
+	s = vim_strsave(word);
+	if (s != NULL)
+	    hash_add_item(&su->su_banned, hi, s, hash);
+    }
+}
+
+/*
+ * Recompute the score for all suggestions if sound-folding is possible.  This
+ * is slow, thus only done for the final results.
+ */
+    static void
+rescore_suggestions(su)
+    suginfo_T	*su;
+{
+    int		i;
+
+    if (su->su_sallang != NULL)
+	for (i = 0; i < su->su_ga.ga_len; ++i)
+	    rescore_one(su, &SUG(su->su_ga, i));
+}
+
+/*
+ * Recompute the score for one suggestion if sound-folding is possible.
+ */
+    static void
+rescore_one(su, stp)
+    suginfo_T	*su;
+    suggest_T	*stp;
+{
+    slang_T	*slang = stp->st_slang;
+    char_u	sal_badword[MAXWLEN];
+    char_u	*p;
+
+    /* Only rescore suggestions that have no sal score yet and do have a
+     * language. */
+    if (slang != NULL && slang->sl_sal.ga_len > 0 && !stp->st_had_bonus)
+    {
+	if (slang == su->su_sallang)
+	    p = su->su_sal_badword;
+	else
+	{
+	    spell_soundfold(slang, su->su_fbadword, TRUE, sal_badword);
+	    p = sal_badword;
+	}
+
+	stp->st_altscore = stp_sal_score(stp, su, slang, p);
+	if (stp->st_altscore == SCORE_MAXMAX)
+	    stp->st_altscore = SCORE_BIG;
+	stp->st_score = RESCORE(stp->st_score, stp->st_altscore);
+	stp->st_had_bonus = TRUE;
+    }
+}
+
+static int
+#ifdef __BORLANDC__
+_RTLENTRYF
+#endif
+sug_compare __ARGS((const void *s1, const void *s2));
+
+/*
+ * Function given to qsort() to sort the suggestions on st_score.
+ * First on "st_score", then "st_altscore" then alphabetically.
+ */
+    static int
+#ifdef __BORLANDC__
+_RTLENTRYF
+#endif
+sug_compare(s1, s2)
+    const void	*s1;
+    const void	*s2;
+{
+    suggest_T	*p1 = (suggest_T *)s1;
+    suggest_T	*p2 = (suggest_T *)s2;
+    int		n = p1->st_score - p2->st_score;
+
+    if (n == 0)
+    {
+	n = p1->st_altscore - p2->st_altscore;
+	if (n == 0)
+	    n = STRICMP(p1->st_word, p2->st_word);
+    }
+    return n;
+}
+
+/*
+ * Cleanup the suggestions:
+ * - Sort on score.
+ * - Remove words that won't be displayed.
+ * Returns the maximum score in the list or "maxscore" unmodified.
+ */
+    static int
+cleanup_suggestions(gap, maxscore, keep)
+    garray_T	*gap;
+    int		maxscore;
+    int		keep;		/* nr of suggestions to keep */
+{
+    suggest_T   *stp = &SUG(*gap, 0);
+    int		i;
+
+    /* Sort the list. */
+    qsort(gap->ga_data, (size_t)gap->ga_len, sizeof(suggest_T), sug_compare);
+
+    /* Truncate the list to the number of suggestions that will be displayed. */
+    if (gap->ga_len > keep)
+    {
+	for (i = keep; i < gap->ga_len; ++i)
+	    vim_free(stp[i].st_word);
+	gap->ga_len = keep;
+	return stp[keep - 1].st_score;
+    }
+    return maxscore;
+}
+
+#if defined(FEAT_EVAL) || defined(PROTO)
+/*
+ * Soundfold a string, for soundfold().
+ * Result is in allocated memory, NULL for an error.
+ */
+    char_u *
+eval_soundfold(word)
+    char_u	*word;
+{
+    langp_T	*lp;
+    char_u	sound[MAXWLEN];
+    int		lpi;
+
+    if (curwin->w_p_spell && *curbuf->b_p_spl != NUL)
+	/* Use the sound-folding of the first language that supports it. */
+	for (lpi = 0; lpi < curbuf->b_langp.ga_len; ++lpi)
+	{
+	    lp = LANGP_ENTRY(curbuf->b_langp, lpi);
+	    if (lp->lp_slang->sl_sal.ga_len > 0)
+	    {
+		/* soundfold the word */
+		spell_soundfold(lp->lp_slang, word, FALSE, sound);
+		return vim_strsave(sound);
+	    }
+	}
+
+    /* No language with sound folding, return word as-is. */
+    return vim_strsave(word);
+}
+#endif
+
+/*
+ * Turn "inword" into its sound-a-like equivalent in "res[MAXWLEN]".
+ *
+ * There are many ways to turn a word into a sound-a-like representation.  The
+ * oldest is Soundex (1918!).   A nice overview can be found in "Approximate
+ * swedish name matching - survey and test of different algorithms" by Klas
+ * Erikson.
+ *
+ * We support two methods:
+ * 1. SOFOFROM/SOFOTO do a simple character mapping.
+ * 2. SAL items define a more advanced sound-folding (and much slower).
+ */
+    static void
+spell_soundfold(slang, inword, folded, res)
+    slang_T	*slang;
+    char_u	*inword;
+    int		folded;	    /* "inword" is already case-folded */
+    char_u	*res;
+{
+    char_u	fword[MAXWLEN];
+    char_u	*word;
+
+    if (slang->sl_sofo)
+	/* SOFOFROM and SOFOTO used */
+	spell_soundfold_sofo(slang, inword, res);
+    else
+    {
+	/* SAL items used.  Requires the word to be case-folded. */
+	if (folded)
+	    word = inword;
+	else
+	{
+	    (void)spell_casefold(inword, (int)STRLEN(inword), fword, MAXWLEN);
+	    word = fword;
+	}
+
+#ifdef FEAT_MBYTE
+	if (has_mbyte)
+	    spell_soundfold_wsal(slang, word, res);
+	else
+#endif
+	    spell_soundfold_sal(slang, word, res);
+    }
+}
+
+/*
+ * Perform sound folding of "inword" into "res" according to SOFOFROM and
+ * SOFOTO lines.
+ */
+    static void
+spell_soundfold_sofo(slang, inword, res)
+    slang_T	*slang;
+    char_u	*inword;
+    char_u	*res;
+{
+    char_u	*s;
+    int		ri = 0;
+    int		c;
+
+#ifdef FEAT_MBYTE
+    if (has_mbyte)
+    {
+	int	prevc = 0;
+	int	*ip;
+
+	/* The sl_sal_first[] table contains the translation for chars up to
+	 * 255, sl_sal the rest. */
+	for (s = inword; *s != NUL; )
+	{
+	    c = mb_cptr2char_adv(&s);
+	    if (enc_utf8 ? utf_class(c) == 0 : vim_iswhite(c))
+		c = ' ';
+	    else if (c < 256)
+		c = slang->sl_sal_first[c];
+	    else
+	    {
+		ip = ((int **)slang->sl_sal.ga_data)[c & 0xff];
+		if (ip == NULL)		/* empty list, can't match */
+		    c = NUL;
+		else
+		    for (;;)		/* find "c" in the list */
+		    {
+			if (*ip == 0)	/* not found */
+			{
+			    c = NUL;
+			    break;
+			}
+			if (*ip == c)	/* match! */
+			{
+			    c = ip[1];
+			    break;
+			}
+			ip += 2;
+		    }
+	    }
+
+	    if (c != NUL && c != prevc)
+	    {
+		ri += mb_char2bytes(c, res + ri);
+		if (ri + MB_MAXBYTES > MAXWLEN)
+		    break;
+		prevc = c;
+	    }
+	}
+    }
+    else
+#endif
+    {
+	/* The sl_sal_first[] table contains the translation. */
+	for (s = inword; (c = *s) != NUL; ++s)
+	{
+	    if (vim_iswhite(c))
+		c = ' ';
+	    else
+		c = slang->sl_sal_first[c];
+	    if (c != NUL && (ri == 0 || res[ri - 1] != c))
+		res[ri++] = c;
+	}
+    }
+
+    res[ri] = NUL;
+}
+
+    static void
+spell_soundfold_sal(slang, inword, res)
+    slang_T	*slang;
+    char_u	*inword;
+    char_u	*res;
+{
+    salitem_T	*smp;
+    char_u	word[MAXWLEN];
+    char_u	*s = inword;
+    char_u	*t;
+    char_u	*pf;
+    int		i, j, z;
+    int		reslen;
+    int		n, k = 0;
+    int		z0;
+    int		k0;
+    int		n0;
+    int		c;
+    int		pri;
+    int		p0 = -333;
+    int		c0;
+
+    /* Remove accents, if wanted.  We actually remove all non-word characters.
+     * But keep white space.  We need a copy, the word may be changed here. */
+    if (slang->sl_rem_accents)
+    {
+	t = word;
+	while (*s != NUL)
+	{
+	    if (vim_iswhite(*s))
+	    {
+		*t++ = ' ';
+		s = skipwhite(s);
+	    }
+	    else
+	    {
+		if (spell_iswordp_nmw(s))
+		    *t++ = *s;
+		++s;
+	    }
+	}
+	*t = NUL;
+    }
+    else
+	STRCPY(word, s);
+
+    smp = (salitem_T *)slang->sl_sal.ga_data;
+
+    /*
+     * This comes from Aspell phonet.cpp.  Converted from C++ to C.
+     * Changed to keep spaces.
+     */
+    i = reslen = z = 0;
+    while ((c = word[i]) != NUL)
+    {
+	/* Start with the first rule that has the character in the word. */
+	n = slang->sl_sal_first[c];
+	z0 = 0;
+
+	if (n >= 0)
+	{
+	    /* check all rules for the same letter */
+	    for (; (s = smp[n].sm_lead)[0] == c; ++n)
+	    {
+		/* Quickly skip entries that don't match the word.  Most
+		 * entries are less then three chars, optimize for that. */
+		k = smp[n].sm_leadlen;
+		if (k > 1)
+		{
+		    if (word[i + 1] != s[1])
+			continue;
+		    if (k > 2)
+		    {
+			for (j = 2; j < k; ++j)
+			    if (word[i + j] != s[j])
+				break;
+			if (j < k)
+			    continue;
+		    }
+		}
+
+		if ((pf = smp[n].sm_oneof) != NULL)
+		{
+		    /* Check for match with one of the chars in "sm_oneof". */
+		    while (*pf != NUL && *pf != word[i + k])
+			++pf;
+		    if (*pf == NUL)
+			continue;
+		    ++k;
+		}
+		s = smp[n].sm_rules;
+		pri = 5;    /* default priority */
+
+		p0 = *s;
+		k0 = k;
+		while (*s == '-' && k > 1)
+		{
+		    k--;
+		    s++;
+		}
+		if (*s == '<')
+		    s++;
+		if (VIM_ISDIGIT(*s))
+		{
+		    /* determine priority */
+		    pri = *s - '0';
+		    s++;
+		}
+		if (*s == '^' && *(s + 1) == '^')
+		    s++;
+
+		if (*s == NUL
+			|| (*s == '^'
+			    && (i == 0 || !(word[i - 1] == ' '
+				      || spell_iswordp(word + i - 1, curbuf)))
+			    && (*(s + 1) != '$'
+				|| (!spell_iswordp(word + i + k0, curbuf))))
+			|| (*s == '$' && i > 0
+			    && spell_iswordp(word + i - 1, curbuf)
+			    && (!spell_iswordp(word + i + k0, curbuf))))
+		{
+		    /* search for followup rules, if:    */
+		    /* followup and k > 1  and  NO '-' in searchstring */
+		    c0 = word[i + k - 1];
+		    n0 = slang->sl_sal_first[c0];
+
+		    if (slang->sl_followup && k > 1 && n0 >= 0
+					   && p0 != '-' && word[i + k] != NUL)
+		    {
+			/* test follow-up rule for "word[i + k]" */
+			for ( ; (s = smp[n0].sm_lead)[0] == c0; ++n0)
+			{
+			    /* Quickly skip entries that don't match the word.
+			     * */
+			    k0 = smp[n0].sm_leadlen;
+			    if (k0 > 1)
+			    {
+				if (word[i + k] != s[1])
+				    continue;
+				if (k0 > 2)
+				{
+				    pf = word + i + k + 1;
+				    for (j = 2; j < k0; ++j)
+					if (*pf++ != s[j])
+					    break;
+				    if (j < k0)
+					continue;
+				}
+			    }
+			    k0 += k - 1;
+
+			    if ((pf = smp[n0].sm_oneof) != NULL)
+			    {
+				/* Check for match with one of the chars in
+				 * "sm_oneof". */
+				while (*pf != NUL && *pf != word[i + k0])
+				    ++pf;
+				if (*pf == NUL)
+				    continue;
+				++k0;
+			    }
+
+			    p0 = 5;
+			    s = smp[n0].sm_rules;
+			    while (*s == '-')
+			    {
+				/* "k0" gets NOT reduced because
+				 * "if (k0 == k)" */
+				s++;
+			    }
+			    if (*s == '<')
+				s++;
+			    if (VIM_ISDIGIT(*s))
+			    {
+				p0 = *s - '0';
+				s++;
+			    }
+
+			    if (*s == NUL
+				    /* *s == '^' cuts */
+				    || (*s == '$'
+					    && !spell_iswordp(word + i + k0,
+								     curbuf)))
+			    {
+				if (k0 == k)
+				    /* this is just a piece of the string */
+				    continue;
+
+				if (p0 < pri)
+				    /* priority too low */
+				    continue;
+				/* rule fits; stop search */
+				break;
+			    }
+			}
+
+			if (p0 >= pri && smp[n0].sm_lead[0] == c0)
+			    continue;
+		    }
+
+		    /* replace string */
+		    s = smp[n].sm_to;
+		    if (s == NULL)
+			s = (char_u *)"";
+		    pf = smp[n].sm_rules;
+		    p0 = (vim_strchr(pf, '<') != NULL) ? 1 : 0;
+		    if (p0 == 1 && z == 0)
+		    {
+			/* rule with '<' is used */
+			if (reslen > 0 && *s != NUL && (res[reslen - 1] == c
+						    || res[reslen - 1] == *s))
+			    reslen--;
+			z0 = 1;
+			z = 1;
+			k0 = 0;
+			while (*s != NUL && word[i + k0] != NUL)
+			{
+			    word[i + k0] = *s;
+			    k0++;
+			    s++;
+			}
+			if (k > k0)
+			    mch_memmove(word + i + k0, word + i + k,
+						    STRLEN(word + i + k) + 1);
+
+			/* new "actual letter" */
+			c = word[i];
+		    }
+		    else
+		    {
+			/* no '<' rule used */
+			i += k - 1;
+			z = 0;
+			while (*s != NUL && s[1] != NUL && reslen < MAXWLEN)
+			{
+			    if (reslen == 0 || res[reslen - 1] != *s)
+				res[reslen++] = *s;
+			    s++;
+			}
+			/* new "actual letter" */
+			c = *s;
+			if (strstr((char *)pf, "^^") != NULL)
+			{
+			    if (c != NUL)
+				res[reslen++] = c;
+			    mch_memmove(word, word + i + 1,
+						    STRLEN(word + i + 1) + 1);
+			    i = 0;
+			    z0 = 1;
+			}
+		    }
+		    break;
+		}
+	    }
+	}
+	else if (vim_iswhite(c))
+	{
+	    c = ' ';
+	    k = 1;
+	}
+
+	if (z0 == 0)
+	{
+	    if (k && !p0 && reslen < MAXWLEN && c != NUL
+		    && (!slang->sl_collapse || reslen == 0
+						     || res[reslen - 1] != c))
+		/* condense only double letters */
+		res[reslen++] = c;
+
+	    i++;
+	    z = 0;
+	    k = 0;
+	}
+    }
+
+    res[reslen] = NUL;
+}
+
+#ifdef FEAT_MBYTE
+/*
+ * Turn "inword" into its sound-a-like equivalent in "res[MAXWLEN]".
+ * Multi-byte version of spell_soundfold().
+ */
+    static void
+spell_soundfold_wsal(slang, inword, res)
+    slang_T	*slang;
+    char_u	*inword;
+    char_u	*res;
+{
+    salitem_T	*smp = (salitem_T *)slang->sl_sal.ga_data;
+    int		word[MAXWLEN];
+    int		wres[MAXWLEN];
+    int		l;
+    char_u	*s;
+    int		*ws;
+    char_u	*t;
+    int		*pf;
+    int		i, j, z;
+    int		reslen;
+    int		n, k = 0;
+    int		z0;
+    int		k0;
+    int		n0;
+    int		c;
+    int		pri;
+    int		p0 = -333;
+    int		c0;
+    int		did_white = FALSE;
+
+    /*
+     * Convert the multi-byte string to a wide-character string.
+     * Remove accents, if wanted.  We actually remove all non-word characters.
+     * But keep white space.
+     */
+    n = 0;
+    for (s = inword; *s != NUL; )
+    {
+	t = s;
+	c = mb_cptr2char_adv(&s);
+	if (slang->sl_rem_accents)
+	{
+	    if (enc_utf8 ? utf_class(c) == 0 : vim_iswhite(c))
+	    {
+		if (did_white)
+		    continue;
+		c = ' ';
+		did_white = TRUE;
+	    }
+	    else
+	    {
+		did_white = FALSE;
+		if (!spell_iswordp_nmw(t))
+		    continue;
+	    }
+	}
+	word[n++] = c;
+    }
+    word[n] = NUL;
+
+    /*
+     * This comes from Aspell phonet.cpp.
+     * Converted from C++ to C.  Added support for multi-byte chars.
+     * Changed to keep spaces.
+     */
+    i = reslen = z = 0;
+    while ((c = word[i]) != NUL)
+    {
+	/* Start with the first rule that has the character in the word. */
+	n = slang->sl_sal_first[c & 0xff];
+	z0 = 0;
+
+	if (n >= 0)
+	{
+	    /* check all rules for the same index byte */
+	    for (; ((ws = smp[n].sm_lead_w)[0] & 0xff) == (c & 0xff); ++n)
+	    {
+		/* Quickly skip entries that don't match the word.  Most
+		 * entries are less then three chars, optimize for that. */
+		if (c != ws[0])
+		    continue;
+		k = smp[n].sm_leadlen;
+		if (k > 1)
+		{
+		    if (word[i + 1] != ws[1])
+			continue;
+		    if (k > 2)
+		    {
+			for (j = 2; j < k; ++j)
+			    if (word[i + j] != ws[j])
+				break;
+			if (j < k)
+			    continue;
+		    }
+		}
+
+		if ((pf = smp[n].sm_oneof_w) != NULL)
+		{
+		    /* Check for match with one of the chars in "sm_oneof". */
+		    while (*pf != NUL && *pf != word[i + k])
+			++pf;
+		    if (*pf == NUL)
+			continue;
+		    ++k;
+		}
+		s = smp[n].sm_rules;
+		pri = 5;    /* default priority */
+
+		p0 = *s;
+		k0 = k;
+		while (*s == '-' && k > 1)
+		{
+		    k--;
+		    s++;
+		}
+		if (*s == '<')
+		    s++;
+		if (VIM_ISDIGIT(*s))
+		{
+		    /* determine priority */
+		    pri = *s - '0';
+		    s++;
+		}
+		if (*s == '^' && *(s + 1) == '^')
+		    s++;
+
+		if (*s == NUL
+			|| (*s == '^'
+			    && (i == 0 || !(word[i - 1] == ' '
+				    || spell_iswordp_w(word + i - 1, curbuf)))
+			    && (*(s + 1) != '$'
+				|| (!spell_iswordp_w(word + i + k0, curbuf))))
+			|| (*s == '$' && i > 0
+			    && spell_iswordp_w(word + i - 1, curbuf)
+			    && (!spell_iswordp_w(word + i + k0, curbuf))))
+		{
+		    /* search for followup rules, if:    */
+		    /* followup and k > 1  and  NO '-' in searchstring */
+		    c0 = word[i + k - 1];
+		    n0 = slang->sl_sal_first[c0 & 0xff];
+
+		    if (slang->sl_followup && k > 1 && n0 >= 0
+					   && p0 != '-' && word[i + k] != NUL)
+		    {
+			/* Test follow-up rule for "word[i + k]"; loop over
+			 * all entries with the same index byte. */
+			for ( ; ((ws = smp[n0].sm_lead_w)[0] & 0xff)
+							 == (c0 & 0xff); ++n0)
+			{
+			    /* Quickly skip entries that don't match the word.
+			     */
+			    if (c0 != ws[0])
+				continue;
+			    k0 = smp[n0].sm_leadlen;
+			    if (k0 > 1)
+			    {
+				if (word[i + k] != ws[1])
+				    continue;
+				if (k0 > 2)
+				{
+				    pf = word + i + k + 1;
+				    for (j = 2; j < k0; ++j)
+					if (*pf++ != ws[j])
+					    break;
+				    if (j < k0)
+					continue;
+				}
+			    }
+			    k0 += k - 1;
+
+			    if ((pf = smp[n0].sm_oneof_w) != NULL)
+			    {
+				/* Check for match with one of the chars in
+				 * "sm_oneof". */
+				while (*pf != NUL && *pf != word[i + k0])
+				    ++pf;
+				if (*pf == NUL)
+				    continue;
+				++k0;
+			    }
+
+			    p0 = 5;
+			    s = smp[n0].sm_rules;
+			    while (*s == '-')
+			    {
+				/* "k0" gets NOT reduced because
+				 * "if (k0 == k)" */
+				s++;
+			    }
+			    if (*s == '<')
+				s++;
+			    if (VIM_ISDIGIT(*s))
+			    {
+				p0 = *s - '0';
+				s++;
+			    }
+
+			    if (*s == NUL
+				    /* *s == '^' cuts */
+				    || (*s == '$'
+					 && !spell_iswordp_w(word + i + k0,
+								     curbuf)))
+			    {
+				if (k0 == k)
+				    /* this is just a piece of the string */
+				    continue;
+
+				if (p0 < pri)
+				    /* priority too low */
+				    continue;
+				/* rule fits; stop search */
+				break;
+			    }
+			}
+
+			if (p0 >= pri && (smp[n0].sm_lead_w[0] & 0xff)
+							       == (c0 & 0xff))
+			    continue;
+		    }
+
+		    /* replace string */
+		    ws = smp[n].sm_to_w;
+		    s = smp[n].sm_rules;
+		    p0 = (vim_strchr(s, '<') != NULL) ? 1 : 0;
+		    if (p0 == 1 && z == 0)
+		    {
+			/* rule with '<' is used */
+			if (reslen > 0 && ws != NULL && *ws != NUL
+				&& (wres[reslen - 1] == c
+						    || wres[reslen - 1] == *ws))
+			    reslen--;
+			z0 = 1;
+			z = 1;
+			k0 = 0;
+			if (ws != NULL)
+			    while (*ws != NUL && word[i + k0] != NUL)
+			    {
+				word[i + k0] = *ws;
+				k0++;
+				ws++;
+			    }
+			if (k > k0)
+			    mch_memmove(word + i + k0, word + i + k,
+				    sizeof(int) * (STRLEN(word + i + k) + 1));
+
+			/* new "actual letter" */
+			c = word[i];
+		    }
+		    else
+		    {
+			/* no '<' rule used */
+			i += k - 1;
+			z = 0;
+			if (ws != NULL)
+			    while (*ws != NUL && ws[1] != NUL
+							  && reslen < MAXWLEN)
+			    {
+				if (reslen == 0 || wres[reslen - 1] != *ws)
+				    wres[reslen++] = *ws;
+				ws++;
+			    }
+			/* new "actual letter" */
+			if (ws == NULL)
+			    c = NUL;
+			else
+			    c = *ws;
+			if (strstr((char *)s, "^^") != NULL)
+			{
+			    if (c != NUL)
+				wres[reslen++] = c;
+			    mch_memmove(word, word + i + 1,
+				    sizeof(int) * (STRLEN(word + i + 1) + 1));
+			    i = 0;
+			    z0 = 1;
+			}
+		    }
+		    break;
+		}
+	    }
+	}
+	else if (vim_iswhite(c))
+	{
+	    c = ' ';
+	    k = 1;
+	}
+
+	if (z0 == 0)
+	{
+	    if (k && !p0 && reslen < MAXWLEN && c != NUL
+		    && (!slang->sl_collapse || reslen == 0
+						     || wres[reslen - 1] != c))
+		/* condense only double letters */
+		wres[reslen++] = c;
+
+	    i++;
+	    z = 0;
+	    k = 0;
+	}
+    }
+
+    /* Convert wide characters in "wres" to a multi-byte string in "res". */
+    l = 0;
+    for (n = 0; n < reslen; ++n)
+    {
+	l += mb_char2bytes(wres[n], res + l);
+	if (l + MB_MAXBYTES > MAXWLEN)
+	    break;
+    }
+    res[l] = NUL;
+}
+#endif
+
+/*
+ * Compute a score for two sound-a-like words.
+ * This permits up to two inserts/deletes/swaps/etc. to keep things fast.
+ * Instead of a generic loop we write out the code.  That keeps it fast by
+ * avoiding checks that will not be possible.
+ */
+    static int
+soundalike_score(goodstart, badstart)
+    char_u	*goodstart;	/* sound-folded good word */
+    char_u	*badstart;	/* sound-folded bad word */
+{
+    char_u	*goodsound = goodstart;
+    char_u	*badsound = badstart;
+    int		goodlen;
+    int		badlen;
+    int		n;
+    char_u	*pl, *ps;
+    char_u	*pl2, *ps2;
+    int		score = 0;
+
+    /* adding/inserting "*" at the start (word starts with vowel) shouldn't be
+     * counted so much, vowels halfway the word aren't counted at all. */
+    if ((*badsound == '*' || *goodsound == '*') && *badsound != *goodsound)
+    {
+	if (badsound[1] == goodsound[1]
+		|| (badsound[1] != NUL
+		    && goodsound[1] != NUL
+		    && badsound[2] == goodsound[2]))
+	{
+	    /* handle like a substitute */
+	}
+	else
+	{
+	    score = 2 * SCORE_DEL / 3;
+	    if (*badsound == '*')
+		++badsound;
+	    else
+		++goodsound;
+	}
+    }
+
+    goodlen = (int)STRLEN(goodsound);
+    badlen = (int)STRLEN(badsound);
+
+    /* Return quickly if the lengths are too different to be fixed by two
+     * changes. */
+    n = goodlen - badlen;
+    if (n < -2 || n > 2)
+	return SCORE_MAXMAX;
+
+    if (n > 0)
+    {
+	pl = goodsound;	    /* goodsound is longest */
+	ps = badsound;
+    }
+    else
+    {
+	pl = badsound;	    /* badsound is longest */
+	ps = goodsound;
+    }
+
+    /* Skip over the identical part. */
+    while (*pl == *ps && *pl != NUL)
+    {
+	++pl;
+	++ps;
+    }
+
+    switch (n)
+    {
+	case -2:
+	case 2:
+	    /*
+	     * Must delete two characters from "pl".
+	     */
+	    ++pl;	/* first delete */
+	    while (*pl == *ps)
+	    {
+		++pl;
+		++ps;
+	    }
+	    /* strings must be equal after second delete */
+	    if (STRCMP(pl + 1, ps) == 0)
+		return score + SCORE_DEL * 2;
+
+	    /* Failed to compare. */
+	    break;
+
+	case -1:
+	case 1:
+	    /*
+	     * Minimal one delete from "pl" required.
+	     */
+
+	    /* 1: delete */
+	    pl2 = pl + 1;
+	    ps2 = ps;
+	    while (*pl2 == *ps2)
+	    {
+		if (*pl2 == NUL)	/* reached the end */
+		    return score + SCORE_DEL;
+		++pl2;
+		++ps2;
+	    }
+
+	    /* 2: delete then swap, then rest must be equal */
+	    if (pl2[0] == ps2[1] && pl2[1] == ps2[0]
+					     && STRCMP(pl2 + 2, ps2 + 2) == 0)
+		return score + SCORE_DEL + SCORE_SWAP;
+
+	    /* 3: delete then substitute, then the rest must be equal */
+	    if (STRCMP(pl2 + 1, ps2 + 1) == 0)
+		return score + SCORE_DEL + SCORE_SUBST;
+
+	    /* 4: first swap then delete */
+	    if (pl[0] == ps[1] && pl[1] == ps[0])
+	    {
+		pl2 = pl + 2;	    /* swap, skip two chars */
+		ps2 = ps + 2;
+		while (*pl2 == *ps2)
+		{
+		    ++pl2;
+		    ++ps2;
+		}
+		/* delete a char and then strings must be equal */
+		if (STRCMP(pl2 + 1, ps2) == 0)
+		    return score + SCORE_SWAP + SCORE_DEL;
+	    }
+
+	    /* 5: first substitute then delete */
+	    pl2 = pl + 1;	    /* substitute, skip one char */
+	    ps2 = ps + 1;
+	    while (*pl2 == *ps2)
+	    {
+		++pl2;
+		++ps2;
+	    }
+	    /* delete a char and then strings must be equal */
+	    if (STRCMP(pl2 + 1, ps2) == 0)
+		return score + SCORE_SUBST + SCORE_DEL;
+
+	    /* Failed to compare. */
+	    break;
+
+	case 0:
+	    /*
+	     * Lenghts are equal, thus changes must result in same length: An
+	     * insert is only possible in combination with a delete.
+	     * 1: check if for identical strings
+	     */
+	    if (*pl == NUL)
+		return score;
+
+	    /* 2: swap */
+	    if (pl[0] == ps[1] && pl[1] == ps[0])
+	    {
+		pl2 = pl + 2;	    /* swap, skip two chars */
+		ps2 = ps + 2;
+		while (*pl2 == *ps2)
+		{
+		    if (*pl2 == NUL)	/* reached the end */
+			return score + SCORE_SWAP;
+		    ++pl2;
+		    ++ps2;
+		}
+		/* 3: swap and swap again */
+		if (pl2[0] == ps2[1] && pl2[1] == ps2[0]
+					     && STRCMP(pl2 + 2, ps2 + 2) == 0)
+		    return score + SCORE_SWAP + SCORE_SWAP;
+
+		/* 4: swap and substitute */
+		if (STRCMP(pl2 + 1, ps2 + 1) == 0)
+		    return score + SCORE_SWAP + SCORE_SUBST;
+	    }
+
+	    /* 5: substitute */
+	    pl2 = pl + 1;
+	    ps2 = ps + 1;
+	    while (*pl2 == *ps2)
+	    {
+		if (*pl2 == NUL)	/* reached the end */
+		    return score + SCORE_SUBST;
+		++pl2;
+		++ps2;
+	    }
+
+	    /* 6: substitute and swap */
+	    if (pl2[0] == ps2[1] && pl2[1] == ps2[0]
+					     && STRCMP(pl2 + 2, ps2 + 2) == 0)
+		return score + SCORE_SUBST + SCORE_SWAP;
+
+	    /* 7: substitute and substitute */
+	    if (STRCMP(pl2 + 1, ps2 + 1) == 0)
+		return score + SCORE_SUBST + SCORE_SUBST;
+
+	    /* 8: insert then delete */
+	    pl2 = pl;
+	    ps2 = ps + 1;
+	    while (*pl2 == *ps2)
+	    {
+		++pl2;
+		++ps2;
+	    }
+	    if (STRCMP(pl2 + 1, ps2) == 0)
+		return score + SCORE_INS + SCORE_DEL;
+
+	    /* 9: delete then insert */
+	    pl2 = pl + 1;
+	    ps2 = ps;
+	    while (*pl2 == *ps2)
+	    {
+		++pl2;
+		++ps2;
+	    }
+	    if (STRCMP(pl2, ps2 + 1) == 0)
+		return score + SCORE_INS + SCORE_DEL;
+
+	    /* Failed to compare. */
+	    break;
+    }
+
+    return SCORE_MAXMAX;
+}
+
+/*
+ * Compute the "edit distance" to turn "badword" into "goodword".  The less
+ * deletes/inserts/substitutes/swaps are required the lower the score.
+ *
+ * The algorithm is described by Du and Chang, 1992.
+ * The implementation of the algorithm comes from Aspell editdist.cpp,
+ * edit_distance().  It has been converted from C++ to C and modified to
+ * support multi-byte characters.
+ */
+    static int
+spell_edit_score(slang, badword, goodword)
+    slang_T	*slang;
+    char_u	*badword;
+    char_u	*goodword;
+{
+    int		*cnt;
+    int		badlen, goodlen;	/* lengths including NUL */
+    int		j, i;
+    int		t;
+    int		bc, gc;
+    int		pbc, pgc;
+#ifdef FEAT_MBYTE
+    char_u	*p;
+    int		wbadword[MAXWLEN];
+    int		wgoodword[MAXWLEN];
+
+    if (has_mbyte)
+    {
+	/* Get the characters from the multi-byte strings and put them in an
+	 * int array for easy access. */
+	for (p = badword, badlen = 0; *p != NUL; )
+	    wbadword[badlen++] = mb_cptr2char_adv(&p);
+	wbadword[badlen++] = 0;
+	for (p = goodword, goodlen = 0; *p != NUL; )
+	    wgoodword[goodlen++] = mb_cptr2char_adv(&p);
+	wgoodword[goodlen++] = 0;
+    }
+    else
+#endif
+    {
+	badlen = (int)STRLEN(badword) + 1;
+	goodlen = (int)STRLEN(goodword) + 1;
+    }
+
+    /* We use "cnt" as an array: CNT(badword_idx, goodword_idx). */
+#define CNT(a, b)   cnt[(a) + (b) * (badlen + 1)]
+    cnt = (int *)lalloc((long_u)(sizeof(int) * (badlen + 1) * (goodlen + 1)),
+									TRUE);
+    if (cnt == NULL)
+	return 0;	/* out of memory */
+
+    CNT(0, 0) = 0;
+    for (j = 1; j <= goodlen; ++j)
+	CNT(0, j) = CNT(0, j - 1) + SCORE_INS;
+
+    for (i = 1; i <= badlen; ++i)
+    {
+	CNT(i, 0) = CNT(i - 1, 0) + SCORE_DEL;
+	for (j = 1; j <= goodlen; ++j)
+	{
+#ifdef FEAT_MBYTE
+	    if (has_mbyte)
+	    {
+		bc = wbadword[i - 1];
+		gc = wgoodword[j - 1];
+	    }
+	    else
+#endif
+	    {
+		bc = badword[i - 1];
+		gc = goodword[j - 1];
+	    }
+	    if (bc == gc)
+		CNT(i, j) = CNT(i - 1, j - 1);
+	    else
+	    {
+		/* Use a better score when there is only a case difference. */
+		if (SPELL_TOFOLD(bc) == SPELL_TOFOLD(gc))
+		    CNT(i, j) = SCORE_ICASE + CNT(i - 1, j - 1);
+		else
+		{
+		    /* For a similar character use SCORE_SIMILAR. */
+		    if (slang != NULL
+			    && slang->sl_has_map
+			    && similar_chars(slang, gc, bc))
+			CNT(i, j) = SCORE_SIMILAR + CNT(i - 1, j - 1);
+		    else
+			CNT(i, j) = SCORE_SUBST + CNT(i - 1, j - 1);
+		}
+
+		if (i > 1 && j > 1)
+		{
+#ifdef FEAT_MBYTE
+		    if (has_mbyte)
+		    {
+			pbc = wbadword[i - 2];
+			pgc = wgoodword[j - 2];
+		    }
+		    else
+#endif
+		    {
+			pbc = badword[i - 2];
+			pgc = goodword[j - 2];
+		    }
+		    if (bc == pgc && pbc == gc)
+		    {
+			t = SCORE_SWAP + CNT(i - 2, j - 2);
+			if (t < CNT(i, j))
+			    CNT(i, j) = t;
+		    }
+		}
+		t = SCORE_DEL + CNT(i - 1, j);
+		if (t < CNT(i, j))
+		    CNT(i, j) = t;
+		t = SCORE_INS + CNT(i, j - 1);
+		if (t < CNT(i, j))
+		    CNT(i, j) = t;
+	    }
+	}
+    }
+
+    i = CNT(badlen - 1, goodlen - 1);
+    vim_free(cnt);
+    return i;
+}
+
+typedef struct
+{
+    int		badi;
+    int		goodi;
+    int		score;
+} limitscore_T;
+
+/*
+ * Like spell_edit_score(), but with a limit on the score to make it faster.
+ * May return SCORE_MAXMAX when the score is higher than "limit".
+ *
+ * This uses a stack for the edits still to be tried.
+ * The idea comes from Aspell leditdist.cpp.  Rewritten in C and added support
+ * for multi-byte characters.
+ */
+    static int
+spell_edit_score_limit(slang, badword, goodword, limit)
+    slang_T	*slang;
+    char_u	*badword;
+    char_u	*goodword;
+    int		limit;
+{
+    limitscore_T    stack[10];		/* allow for over 3 * 2 edits */
+    int		    stackidx;
+    int		    bi, gi;
+    int		    bi2, gi2;
+    int		    bc, gc;
+    int		    score;
+    int		    score_off;
+    int		    minscore;
+    int		    round;
+
+#ifdef FEAT_MBYTE
+    /* Multi-byte characters require a bit more work, use a different function
+     * to avoid testing "has_mbyte" quite often. */
+    if (has_mbyte)
+	return spell_edit_score_limit_w(slang, badword, goodword, limit);
+#endif
+
+    /*
+     * The idea is to go from start to end over the words.  So long as
+     * characters are equal just continue, this always gives the lowest score.
+     * When there is a difference try several alternatives.  Each alternative
+     * increases "score" for the edit distance.  Some of the alternatives are
+     * pushed unto a stack and tried later, some are tried right away.  At the
+     * end of the word the score for one alternative is known.  The lowest
+     * possible score is stored in "minscore".
+     */
+    stackidx = 0;
+    bi = 0;
+    gi = 0;
+    score = 0;
+    minscore = limit + 1;
+
+    for (;;)
+    {
+	/* Skip over an equal part, score remains the same. */
+	for (;;)
+	{
+	    bc = badword[bi];
+	    gc = goodword[gi];
+	    if (bc != gc)	/* stop at a char that's different */
+		break;
+	    if (bc == NUL)	/* both words end */
+	    {
+		if (score < minscore)
+		    minscore = score;
+		goto pop;	/* do next alternative */
+	    }
+	    ++bi;
+	    ++gi;
+	}
+
+	if (gc == NUL)    /* goodword ends, delete badword chars */
+	{
+	    do
+	    {
+		if ((score += SCORE_DEL) >= minscore)
+		    goto pop;	    /* do next alternative */
+	    } while (badword[++bi] != NUL);
+	    minscore = score;
+	}
+	else if (bc == NUL) /* badword ends, insert badword chars */
+	{
+	    do
+	    {
+		if ((score += SCORE_INS) >= minscore)
+		    goto pop;	    /* do next alternative */
+	    } while (goodword[++gi] != NUL);
+	    minscore = score;
+	}
+	else			/* both words continue */
+	{
+	    /* If not close to the limit, perform a change.  Only try changes
+	     * that may lead to a lower score than "minscore".
+	     * round 0: try deleting a char from badword
+	     * round 1: try inserting a char in badword */
+	    for (round = 0; round <= 1; ++round)
+	    {
+		score_off = score + (round == 0 ? SCORE_DEL : SCORE_INS);
+		if (score_off < minscore)
+		{
+		    if (score_off + SCORE_EDIT_MIN >= minscore)
+		    {
+			/* Near the limit, rest of the words must match.  We
+			 * can check that right now, no need to push an item
+			 * onto the stack. */
+			bi2 = bi + 1 - round;
+			gi2 = gi + round;
+			while (goodword[gi2] == badword[bi2])
+			{
+			    if (goodword[gi2] == NUL)
+			    {
+				minscore = score_off;
+				break;
+			    }
+			    ++bi2;
+			    ++gi2;
+			}
+		    }
+		    else
+		    {
+			/* try deleting/inserting a character later */
+			stack[stackidx].badi = bi + 1 - round;
+			stack[stackidx].goodi = gi + round;
+			stack[stackidx].score = score_off;
+			++stackidx;
+		    }
+		}
+	    }
+
+	    if (score + SCORE_SWAP < minscore)
+	    {
+		/* If swapping two characters makes a match then the
+		 * substitution is more expensive, thus there is no need to
+		 * try both. */
+		if (gc == badword[bi + 1] && bc == goodword[gi + 1])
+		{
+		    /* Swap two characters, that is: skip them. */
+		    gi += 2;
+		    bi += 2;
+		    score += SCORE_SWAP;
+		    continue;
+		}
+	    }
+
+	    /* Substitute one character for another which is the same
+	     * thing as deleting a character from both goodword and badword.
+	     * Use a better score when there is only a case difference. */
+	    if (SPELL_TOFOLD(bc) == SPELL_TOFOLD(gc))
+		score += SCORE_ICASE;
+	    else
+	    {
+		/* For a similar character use SCORE_SIMILAR. */
+		if (slang != NULL
+			&& slang->sl_has_map
+			&& similar_chars(slang, gc, bc))
+		    score += SCORE_SIMILAR;
+		else
+		    score += SCORE_SUBST;
+	    }
+
+	    if (score < minscore)
+	    {
+		/* Do the substitution. */
+		++gi;
+		++bi;
+		continue;
+	    }
+	}
+pop:
+	/*
+	 * Get here to try the next alternative, pop it from the stack.
+	 */
+	if (stackidx == 0)		/* stack is empty, finished */
+	    break;
+
+	/* pop an item from the stack */
+	--stackidx;
+	gi = stack[stackidx].goodi;
+	bi = stack[stackidx].badi;
+	score = stack[stackidx].score;
+    }
+
+    /* When the score goes over "limit" it may actually be much higher.
+     * Return a very large number to avoid going below the limit when giving a
+     * bonus. */
+    if (minscore > limit)
+	return SCORE_MAXMAX;
+    return minscore;
+}
+
+#ifdef FEAT_MBYTE
+/*
+ * Multi-byte version of spell_edit_score_limit().
+ * Keep it in sync with the above!
+ */
+    static int
+spell_edit_score_limit_w(slang, badword, goodword, limit)
+    slang_T	*slang;
+    char_u	*badword;
+    char_u	*goodword;
+    int		limit;
+{
+    limitscore_T    stack[10];		/* allow for over 3 * 2 edits */
+    int		    stackidx;
+    int		    bi, gi;
+    int		    bi2, gi2;
+    int		    bc, gc;
+    int		    score;
+    int		    score_off;
+    int		    minscore;
+    int		    round;
+    char_u	    *p;
+    int		    wbadword[MAXWLEN];
+    int		    wgoodword[MAXWLEN];
+
+    /* Get the characters from the multi-byte strings and put them in an
+     * int array for easy access. */
+    bi = 0;
+    for (p = badword; *p != NUL; )
+	wbadword[bi++] = mb_cptr2char_adv(&p);
+    wbadword[bi++] = 0;
+    gi = 0;
+    for (p = goodword; *p != NUL; )
+	wgoodword[gi++] = mb_cptr2char_adv(&p);
+    wgoodword[gi++] = 0;
+
+    /*
+     * The idea is to go from start to end over the words.  So long as
+     * characters are equal just continue, this always gives the lowest score.
+     * When there is a difference try several alternatives.  Each alternative
+     * increases "score" for the edit distance.  Some of the alternatives are
+     * pushed unto a stack and tried later, some are tried right away.  At the
+     * end of the word the score for one alternative is known.  The lowest
+     * possible score is stored in "minscore".
+     */
+    stackidx = 0;
+    bi = 0;
+    gi = 0;
+    score = 0;
+    minscore = limit + 1;
+
+    for (;;)
+    {
+	/* Skip over an equal part, score remains the same. */
+	for (;;)
+	{
+	    bc = wbadword[bi];
+	    gc = wgoodword[gi];
+
+	    if (bc != gc)	/* stop at a char that's different */
+		break;
+	    if (bc == NUL)	/* both words end */
+	    {
+		if (score < minscore)
+		    minscore = score;
+		goto pop;	/* do next alternative */
+	    }
+	    ++bi;
+	    ++gi;
+	}
+
+	if (gc == NUL)    /* goodword ends, delete badword chars */
+	{
+	    do
+	    {
+		if ((score += SCORE_DEL) >= minscore)
+		    goto pop;	    /* do next alternative */
+	    } while (wbadword[++bi] != NUL);
+	    minscore = score;
+	}
+	else if (bc == NUL) /* badword ends, insert badword chars */
+	{
+	    do
+	    {
+		if ((score += SCORE_INS) >= minscore)
+		    goto pop;	    /* do next alternative */
+	    } while (wgoodword[++gi] != NUL);
+	    minscore = score;
+	}
+	else			/* both words continue */
+	{
+	    /* If not close to the limit, perform a change.  Only try changes
+	     * that may lead to a lower score than "minscore".
+	     * round 0: try deleting a char from badword
+	     * round 1: try inserting a char in badword */
+	    for (round = 0; round <= 1; ++round)
+	    {
+		score_off = score + (round == 0 ? SCORE_DEL : SCORE_INS);
+		if (score_off < minscore)
+		{
+		    if (score_off + SCORE_EDIT_MIN >= minscore)
+		    {
+			/* Near the limit, rest of the words must match.  We
+			 * can check that right now, no need to push an item
+			 * onto the stack. */
+			bi2 = bi + 1 - round;
+			gi2 = gi + round;
+			while (wgoodword[gi2] == wbadword[bi2])
+			{
+			    if (wgoodword[gi2] == NUL)
+			    {
+				minscore = score_off;
+				break;
+			    }
+			    ++bi2;
+			    ++gi2;
+			}
+		    }
+		    else
+		    {
+			/* try deleting a character from badword later */
+			stack[stackidx].badi = bi + 1 - round;
+			stack[stackidx].goodi = gi + round;
+			stack[stackidx].score = score_off;
+			++stackidx;
+		    }
+		}
+	    }
+
+	    if (score + SCORE_SWAP < minscore)
+	    {
+		/* If swapping two characters makes a match then the
+		 * substitution is more expensive, thus there is no need to
+		 * try both. */
+		if (gc == wbadword[bi + 1] && bc == wgoodword[gi + 1])
+		{
+		    /* Swap two characters, that is: skip them. */
+		    gi += 2;
+		    bi += 2;
+		    score += SCORE_SWAP;
+		    continue;
+		}
+	    }
+
+	    /* Substitute one character for another which is the same
+	     * thing as deleting a character from both goodword and badword.
+	     * Use a better score when there is only a case difference. */
+	    if (SPELL_TOFOLD(bc) == SPELL_TOFOLD(gc))
+		score += SCORE_ICASE;
+	    else
+	    {
+		/* For a similar character use SCORE_SIMILAR. */
+		if (slang != NULL
+			&& slang->sl_has_map
+			&& similar_chars(slang, gc, bc))
+		    score += SCORE_SIMILAR;
+		else
+		    score += SCORE_SUBST;
+	    }
+
+	    if (score < minscore)
+	    {
+		/* Do the substitution. */
+		++gi;
+		++bi;
+		continue;
+	    }
+	}
+pop:
+	/*
+	 * Get here to try the next alternative, pop it from the stack.
+	 */
+	if (stackidx == 0)		/* stack is empty, finished */
+	    break;
+
+	/* pop an item from the stack */
+	--stackidx;
+	gi = stack[stackidx].goodi;
+	bi = stack[stackidx].badi;
+	score = stack[stackidx].score;
+    }
+
+    /* When the score goes over "limit" it may actually be much higher.
+     * Return a very large number to avoid going below the limit when giving a
+     * bonus. */
+    if (minscore > limit)
+	return SCORE_MAXMAX;
+    return minscore;
+}
+#endif
+
+/*
+ * ":spellinfo"
+ */
+/*ARGSUSED*/
+    void
+ex_spellinfo(eap)
+    exarg_T *eap;
+{
+    int		lpi;
+    langp_T	*lp;
+    char_u	*p;
+
+    if (no_spell_checking(curwin))
+	return;
+
+    msg_start();
+    for (lpi = 0; lpi < curbuf->b_langp.ga_len && !got_int; ++lpi)
+    {
+	lp = LANGP_ENTRY(curbuf->b_langp, lpi);
+	msg_puts((char_u *)"file: ");
+	msg_puts(lp->lp_slang->sl_fname);
+	msg_putchar('\n');
+	p = lp->lp_slang->sl_info;
+	if (p != NULL)
+	{
+	    msg_puts(p);
+	    msg_putchar('\n');
+	}
+    }
+    msg_end();
+}
+
+#define DUMPFLAG_KEEPCASE   1	/* round 2: keep-case tree */
+#define DUMPFLAG_COUNT	    2	/* include word count */
+#define DUMPFLAG_ICASE	    4	/* ignore case when finding matches */
+#define DUMPFLAG_ONECAP	    8	/* pattern starts with capital */
+#define DUMPFLAG_ALLCAP	    16	/* pattern is all capitals */
+
+/*
+ * ":spelldump"
+ */
+    void
+ex_spelldump(eap)
+    exarg_T *eap;
+{
+    buf_T	*buf = curbuf;
+
+    if (no_spell_checking(curwin))
+	return;
+
+    /* Create a new empty buffer by splitting the window. */
+    do_cmdline_cmd((char_u *)"new");
+    if (!bufempty() || !buf_valid(buf))
+	return;
+
+    spell_dump_compl(buf, NULL, 0, NULL, eap->forceit ? DUMPFLAG_COUNT : 0);
+
+    /* Delete the empty line that we started with. */
+    if (curbuf->b_ml.ml_line_count > 1)
+	ml_delete(curbuf->b_ml.ml_line_count, FALSE);
+
+    redraw_later(NOT_VALID);
+}
+
+/*
+ * Go through all possible words and:
+ * 1. When "pat" is NULL: dump a list of all words in the current buffer.
+ *	"ic" and "dir" are not used.
+ * 2. When "pat" is not NULL: add matching words to insert mode completion.
+ */
+    void
+spell_dump_compl(buf, pat, ic, dir, dumpflags_arg)
+    buf_T	*buf;	    /* buffer with spell checking */
+    char_u	*pat;	    /* leading part of the word */
+    int		ic;	    /* ignore case */
+    int		*dir;	    /* direction for adding matches */
+    int		dumpflags_arg;	/* DUMPFLAG_* */
+{
+    langp_T	*lp;
+    slang_T	*slang;
+    idx_T	arridx[MAXWLEN];
+    int		curi[MAXWLEN];
+    char_u	word[MAXWLEN];
+    int		c;
+    char_u	*byts;
+    idx_T	*idxs;
+    linenr_T	lnum = 0;
+    int		round;
+    int		depth;
+    int		n;
+    int		flags;
+    char_u	*region_names = NULL;	    /* region names being used */
+    int		do_region = TRUE;	    /* dump region names and numbers */
+    char_u	*p;
+    int		lpi;
+    int		dumpflags = dumpflags_arg;
+    int		patlen;
+
+    /* When ignoring case or when the pattern starts with capital pass this on
+     * to dump_word(). */
+    if (pat != NULL)
+    {
+	if (ic)
+	    dumpflags |= DUMPFLAG_ICASE;
+	else
+	{
+	    n = captype(pat, NULL);
+	    if (n == WF_ONECAP)
+		dumpflags |= DUMPFLAG_ONECAP;
+	    else if (n == WF_ALLCAP
+#ifdef FEAT_MBYTE
+		    && (int)STRLEN(pat) > mb_ptr2len(pat)
+#else
+		    && (int)STRLEN(pat) > 1
+#endif
+		    )
+		dumpflags |= DUMPFLAG_ALLCAP;
+	}
+    }
+
+    /* Find out if we can support regions: All languages must support the same
+     * regions or none at all. */
+    for (lpi = 0; lpi < buf->b_langp.ga_len; ++lpi)
+    {
+	lp = LANGP_ENTRY(buf->b_langp, lpi);
+	p = lp->lp_slang->sl_regions;
+	if (p[0] != 0)
+	{
+	    if (region_names == NULL)	    /* first language with regions */
+		region_names = p;
+	    else if (STRCMP(region_names, p) != 0)
+	    {
+		do_region = FALSE;	    /* region names are different */
+		break;
+	    }
+	}
+    }
+
+    if (do_region && region_names != NULL)
+    {
+	if (pat == NULL)
+	{
+	    vim_snprintf((char *)IObuff, IOSIZE, "/regions=%s", region_names);
+	    ml_append(lnum++, IObuff, (colnr_T)0, FALSE);
+	}
+    }
+    else
+	do_region = FALSE;
+
+    /*
+     * Loop over all files loaded for the entries in 'spelllang'.
+     */
+    for (lpi = 0; lpi < buf->b_langp.ga_len; ++lpi)
+    {
+	lp = LANGP_ENTRY(buf->b_langp, lpi);
+	slang = lp->lp_slang;
+	if (slang->sl_fbyts == NULL)	    /* reloading failed */
+	    continue;
+
+	if (pat == NULL)
+	{
+	    vim_snprintf((char *)IObuff, IOSIZE, "# file: %s", slang->sl_fname);
+	    ml_append(lnum++, IObuff, (colnr_T)0, FALSE);
+	}
+
+	/* When matching with a pattern and there are no prefixes only use
+	 * parts of the tree that match "pat". */
+	if (pat != NULL && slang->sl_pbyts == NULL)
+	    patlen = (int)STRLEN(pat);
+	else
+	    patlen = -1;
+
+	/* round 1: case-folded tree
+	 * round 2: keep-case tree */
+	for (round = 1; round <= 2; ++round)
+	{
+	    if (round == 1)
+	    {
+		dumpflags &= ~DUMPFLAG_KEEPCASE;
+		byts = slang->sl_fbyts;
+		idxs = slang->sl_fidxs;
+	    }
+	    else
+	    {
+		dumpflags |= DUMPFLAG_KEEPCASE;
+		byts = slang->sl_kbyts;
+		idxs = slang->sl_kidxs;
+	    }
+	    if (byts == NULL)
+		continue;		/* array is empty */
+
+	    depth = 0;
+	    arridx[0] = 0;
+	    curi[0] = 1;
+	    while (depth >= 0 && !got_int
+				       && (pat == NULL || !compl_interrupted))
+	    {
+		if (curi[depth] > byts[arridx[depth]])
+		{
+		    /* Done all bytes at this node, go up one level. */
+		    --depth;
+		    line_breakcheck();
+		    ins_compl_check_keys(50);
+		}
+		else
+		{
+		    /* Do one more byte at this node. */
+		    n = arridx[depth] + curi[depth];
+		    ++curi[depth];
+		    c = byts[n];
+		    if (c == 0)
+		    {
+			/* End of word, deal with the word.
+			 * Don't use keep-case words in the fold-case tree,
+			 * they will appear in the keep-case tree.
+			 * Only use the word when the region matches. */
+			flags = (int)idxs[n];
+			if ((round == 2 || (flags & WF_KEEPCAP) == 0)
+				&& (flags & WF_NEEDCOMP) == 0
+				&& (do_region
+				    || (flags & WF_REGION) == 0
+				    || (((unsigned)flags >> 16)
+						       & lp->lp_region) != 0))
+			{
+			    word[depth] = NUL;
+			    if (!do_region)
+				flags &= ~WF_REGION;
+
+			    /* Dump the basic word if there is no prefix or
+			     * when it's the first one. */
+			    c = (unsigned)flags >> 24;
+			    if (c == 0 || curi[depth] == 2)
+			    {
+				dump_word(slang, word, pat, dir,
+						      dumpflags, flags, lnum);
+				if (pat == NULL)
+				    ++lnum;
+			    }
+
+			    /* Apply the prefix, if there is one. */
+			    if (c != 0)
+				lnum = dump_prefixes(slang, word, pat, dir,
+						      dumpflags, flags, lnum);
+			}
+		    }
+		    else
+		    {
+			/* Normal char, go one level deeper. */
+			word[depth++] = c;
+			arridx[depth] = idxs[n];
+			curi[depth] = 1;
+
+			/* Check if this characters matches with the pattern.
+			 * If not skip the whole tree below it.
+			 * Always ignore case here, dump_word() will check
+			 * proper case later.  This isn't exactly right when
+			 * length changes for multi-byte characters with
+			 * ignore case... */
+			if (depth <= patlen
+					&& MB_STRNICMP(word, pat, depth) != 0)
+			    --depth;
+		    }
+		}
+	    }
+	}
+    }
+}
+
+/*
+ * Dump one word: apply case modifications and append a line to the buffer.
+ * When "lnum" is zero add insert mode completion.
+ */
+    static void
+dump_word(slang, word, pat, dir, dumpflags, wordflags, lnum)
+    slang_T	*slang;
+    char_u	*word;
+    char_u	*pat;
+    int		*dir;
+    int		dumpflags;
+    int		wordflags;
+    linenr_T	lnum;
+{
+    int		keepcap = FALSE;
+    char_u	*p;
+    char_u	*tw;
+    char_u	cword[MAXWLEN];
+    char_u	badword[MAXWLEN + 10];
+    int		i;
+    int		flags = wordflags;
+
+    if (dumpflags & DUMPFLAG_ONECAP)
+	flags |= WF_ONECAP;
+    if (dumpflags & DUMPFLAG_ALLCAP)
+	flags |= WF_ALLCAP;
+
+    if ((dumpflags & DUMPFLAG_KEEPCASE) == 0 && (flags & WF_CAPMASK) != 0)
+    {
+	/* Need to fix case according to "flags". */
+	make_case_word(word, cword, flags);
+	p = cword;
+    }
+    else
+    {
+	p = word;
+	if ((dumpflags & DUMPFLAG_KEEPCASE)
+		&& ((captype(word, NULL) & WF_KEEPCAP) == 0
+						 || (flags & WF_FIXCAP) != 0))
+	    keepcap = TRUE;
+    }
+    tw = p;
+
+    if (pat == NULL)
+    {
+	/* Add flags and regions after a slash. */
+	if ((flags & (WF_BANNED | WF_RARE | WF_REGION)) || keepcap)
+	{
+	    STRCPY(badword, p);
+	    STRCAT(badword, "/");
+	    if (keepcap)
+		STRCAT(badword, "=");
+	    if (flags & WF_BANNED)
+		STRCAT(badword, "!");
+	    else if (flags & WF_RARE)
+		STRCAT(badword, "?");
+	    if (flags & WF_REGION)
+		for (i = 0; i < 7; ++i)
+		    if (flags & (0x10000 << i))
+			sprintf((char *)badword + STRLEN(badword), "%d", i + 1);
+	    p = badword;
+	}
+
+	if (dumpflags & DUMPFLAG_COUNT)
+	{
+	    hashitem_T  *hi;
+
+	    /* Include the word count for ":spelldump!". */
+	    hi = hash_find(&slang->sl_wordcount, tw);
+	    if (!HASHITEM_EMPTY(hi))
+	    {
+		vim_snprintf((char *)IObuff, IOSIZE, "%s\t%d",
+						     tw, HI2WC(hi)->wc_count);
+		p = IObuff;
+	    }
+	}
+
+	ml_append(lnum, p, (colnr_T)0, FALSE);
+    }
+    else if (((dumpflags & DUMPFLAG_ICASE)
+		    ? MB_STRNICMP(p, pat, STRLEN(pat)) == 0
+		    : STRNCMP(p, pat, STRLEN(pat)) == 0)
+		&& ins_compl_add_infercase(p, (int)STRLEN(p),
+					  p_ic, NULL, *dir, 0) == OK)
+	/* if dir was BACKWARD then honor it just once */
+	*dir = FORWARD;
+}
+
+/*
+ * For ":spelldump": Find matching prefixes for "word".  Prepend each to
+ * "word" and append a line to the buffer.
+ * When "lnum" is zero add insert mode completion.
+ * Return the updated line number.
+ */
+    static linenr_T
+dump_prefixes(slang, word, pat, dir, dumpflags, flags, startlnum)
+    slang_T	*slang;
+    char_u	*word;	    /* case-folded word */
+    char_u	*pat;
+    int		*dir;
+    int		dumpflags;
+    int		flags;	    /* flags with prefix ID */
+    linenr_T	startlnum;
+{
+    idx_T	arridx[MAXWLEN];
+    int		curi[MAXWLEN];
+    char_u	prefix[MAXWLEN];
+    char_u	word_up[MAXWLEN];
+    int		has_word_up = FALSE;
+    int		c;
+    char_u	*byts;
+    idx_T	*idxs;
+    linenr_T	lnum = startlnum;
+    int		depth;
+    int		n;
+    int		len;
+    int		i;
+
+    /* If the word starts with a lower-case letter make the word with an
+     * upper-case letter in word_up[]. */
+    c = PTR2CHAR(word);
+    if (SPELL_TOUPPER(c) != c)
+    {
+	onecap_copy(word, word_up, TRUE);
+	has_word_up = TRUE;
+    }
+
+    byts = slang->sl_pbyts;
+    idxs = slang->sl_pidxs;
+    if (byts != NULL)		/* array not is empty */
+    {
+	/*
+	 * Loop over all prefixes, building them byte-by-byte in prefix[].
+	 * When at the end of a prefix check that it supports "flags".
+	 */
+	depth = 0;
+	arridx[0] = 0;
+	curi[0] = 1;
+	while (depth >= 0 && !got_int)
+	{
+	    n = arridx[depth];
+	    len = byts[n];
+	    if (curi[depth] > len)
+	    {
+		/* Done all bytes at this node, go up one level. */
+		--depth;
+		line_breakcheck();
+	    }
+	    else
+	    {
+		/* Do one more byte at this node. */
+		n += curi[depth];
+		++curi[depth];
+		c = byts[n];
+		if (c == 0)
+		{
+		    /* End of prefix, find out how many IDs there are. */
+		    for (i = 1; i < len; ++i)
+			if (byts[n + i] != 0)
+			    break;
+		    curi[depth] += i - 1;
+
+		    c = valid_word_prefix(i, n, flags, word, slang, FALSE);
+		    if (c != 0)
+		    {
+			vim_strncpy(prefix + depth, word, MAXWLEN - depth - 1);
+			dump_word(slang, prefix, pat, dir, dumpflags,
+				(c & WF_RAREPFX) ? (flags | WF_RARE)
+							       : flags, lnum);
+			if (lnum != 0)
+			    ++lnum;
+		    }
+
+		    /* Check for prefix that matches the word when the
+		     * first letter is upper-case, but only if the prefix has
+		     * a condition. */
+		    if (has_word_up)
+		    {
+			c = valid_word_prefix(i, n, flags, word_up, slang,
+									TRUE);
+			if (c != 0)
+			{
+			    vim_strncpy(prefix + depth, word_up,
+							 MAXWLEN - depth - 1);
+			    dump_word(slang, prefix, pat, dir, dumpflags,
+				    (c & WF_RAREPFX) ? (flags | WF_RARE)
+							       : flags, lnum);
+			    if (lnum != 0)
+				++lnum;
+			}
+		    }
+		}
+		else
+		{
+		    /* Normal char, go one level deeper. */
+		    prefix[depth++] = c;
+		    arridx[depth] = idxs[n];
+		    curi[depth] = 1;
+		}
+	    }
+	}
+    }
+
+    return lnum;
+}
+
+/*
+ * Move "p" to the end of word "start".
+ * Uses the spell-checking word characters.
+ */
+    char_u *
+spell_to_word_end(start, buf)
+    char_u  *start;
+    buf_T   *buf;
+{
+    char_u  *p = start;
+
+    while (*p != NUL && spell_iswordp(p, buf))
+	mb_ptr_adv(p);
+    return p;
+}
+
+#if defined(FEAT_INS_EXPAND) || defined(PROTO)
+/*
+ * For Insert mode completion CTRL-X s:
+ * Find start of the word in front of column "startcol".
+ * We don't check if it is badly spelled, with completion we can only change
+ * the word in front of the cursor.
+ * Returns the column number of the word.
+ */
+    int
+spell_word_start(startcol)
+    int		startcol;
+{
+    char_u	*line;
+    char_u	*p;
+    int		col = 0;
+
+    if (no_spell_checking(curwin))
+	return startcol;
+
+    /* Find a word character before "startcol". */
+    line = ml_get_curline();
+    for (p = line + startcol; p > line; )
+    {
+	mb_ptr_back(line, p);
+	if (spell_iswordp_nmw(p))
+	    break;
+    }
+
+    /* Go back to start of the word. */
+    while (p > line)
+    {
+	col = (int)(p - line);
+	mb_ptr_back(line, p);
+	if (!spell_iswordp(p, curbuf))
+	    break;
+	col = 0;
+    }
+
+    return col;
+}
+
+/*
+ * Need to check for 'spellcapcheck' now, the word is removed before
+ * expand_spelling() is called.  Therefore the ugly global variable.
+ */
+static int spell_expand_need_cap;
+
+    void
+spell_expand_check_cap(col)
+    colnr_T col;
+{
+    spell_expand_need_cap = check_need_cap(curwin->w_cursor.lnum, col);
+}
+
+/*
+ * Get list of spelling suggestions.
+ * Used for Insert mode completion CTRL-X ?.
+ * Returns the number of matches.  The matches are in "matchp[]", array of
+ * allocated strings.
+ */
+/*ARGSUSED*/
+    int
+expand_spelling(lnum, col, pat, matchp)
+    linenr_T	lnum;
+    int		col;
+    char_u	*pat;
+    char_u	***matchp;
+{
+    garray_T	ga;
+
+    spell_suggest_list(&ga, pat, 100, spell_expand_need_cap, TRUE);
+    *matchp = ga.ga_data;
+    return ga.ga_len;
+}
+#endif
+
+#endif  /* FEAT_SPELL */
--- /dev/null
+++ b/structs.h
@@ -1,0 +1,2315 @@
+/* vi:set ts=8 sts=4 sw=4:
+ *
+ * VIM - Vi IMproved	by Bram Moolenaar
+ *
+ * Do ":help uganda"  in Vim to read copying and usage conditions.
+ * Do ":help credits" in Vim to see a list of people who contributed.
+ */
+
+/*
+ * This file contains various definitions of structures that are used by Vim
+ */
+
+/*
+ * There is something wrong in the SAS compiler that makes typedefs not
+ * valid in include files.  Has been fixed in version 6.58.
+ */
+#if defined(SASC) && SASC < 658
+typedef long		linenr_T;
+typedef unsigned	colnr_T;
+typedef unsigned short	short_u;
+#endif
+
+/*
+ * position in file or buffer
+ */
+typedef struct
+{
+    linenr_T	lnum;	/* line number */
+    colnr_T	col;	/* column number */
+#ifdef FEAT_VIRTUALEDIT
+    colnr_T	coladd;
+#endif
+} pos_T;
+
+#ifdef FEAT_VIRTUALEDIT
+# define INIT_POS_T {0, 0, 0}
+#else
+# define INIT_POS_T {0, 0}
+#endif
+
+/*
+ * Same, but without coladd.
+ */
+typedef struct
+{
+    linenr_T	lnum;	/* line number */
+    colnr_T	col;	/* column number */
+} lpos_T;
+
+/*
+ * Structure used for growing arrays.
+ * This is used to store information that only grows, is deleted all at
+ * once, and needs to be accessed by index.  See ga_clear() and ga_grow().
+ */
+typedef struct growarray
+{
+    int	    ga_len;		    /* current number of items used */
+    int	    ga_maxlen;		    /* maximum number of items possible */
+    int	    ga_itemsize;	    /* sizeof(item) */
+    int	    ga_growsize;	    /* number of items to grow each time */
+    void    *ga_data;		    /* pointer to the first item */
+} garray_T;
+
+#define GA_EMPTY    {0, 0, 0, 0, NULL}
+
+/*
+ * This is here because regexp.h needs pos_T and below regprog_T is used.
+ */
+#include "regexp.h"
+
+typedef struct window_S		win_T;
+typedef struct wininfo_S	wininfo_T;
+typedef struct frame_S		frame_T;
+typedef int			scid_T;		/* script ID */
+
+/*
+ * This is here because gui.h needs the pos_T and win_T, and win_T needs gui.h
+ * for scrollbar_T.
+ */
+#ifdef FEAT_GUI
+# include "gui.h"
+#else
+# ifdef FEAT_XCLIPBOARD
+#  include <X11/Intrinsic.h>
+# endif
+# define guicolor_T int		/* avoid error in prototypes */
+#endif
+
+/*
+ * marks: positions in a file
+ * (a normal mark is a lnum/col pair, the same as a file position)
+ */
+
+/* (Note: for EBCDIC there are more than 26, because there are gaps in the
+ * alphabet coding.  To minimize changes to the code, I decided to just
+ * increase the number of possible marks. */
+#define NMARKS		('z' - 'a' + 1)	/* max. # of named marks */
+#define JUMPLISTSIZE	100		/* max. # of marks in jump list */
+#define TAGSTACKSIZE	20		/* max. # of tags in tag stack */
+
+typedef struct filemark
+{
+    pos_T	mark;		/* cursor position */
+    int		fnum;		/* file number */
+} fmark_T;
+
+/* Xtended file mark: also has a file name */
+typedef struct xfilemark
+{
+    fmark_T	fmark;
+    char_u	*fname;		/* file name, used when fnum == 0 */
+} xfmark_T;
+
+/*
+ * The taggy struct is used to store the information about a :tag command.
+ */
+typedef struct taggy
+{
+    char_u	*tagname;	/* tag name */
+    fmark_T	fmark;		/* cursor position BEFORE ":tag" */
+    int		cur_match;	/* match number */
+    int		cur_fnum;	/* buffer number used for cur_match */
+} taggy_T;
+
+/*
+ * Structure that contains all options that are local to a window.
+ * Used twice in a window: for the current buffer and for all buffers.
+ * Also used in wininfo_T.
+ */
+typedef struct
+{
+#ifdef FEAT_ARABIC
+    int		wo_arab;
+# define w_p_arab w_onebuf_opt.wo_arab	/* 'arabic' */
+#endif
+#ifdef FEAT_DIFF
+    int		wo_diff;
+# define w_p_diff w_onebuf_opt.wo_diff	/* 'diff' */
+#endif
+#ifdef FEAT_FOLDING
+    long	wo_fdc;
+# define w_p_fdc w_onebuf_opt.wo_fdc	/* 'foldcolumn' */
+    int		wo_fen;
+# define w_p_fen w_onebuf_opt.wo_fen	/* 'foldenable' */
+    char_u	*wo_fdi;
+# define w_p_fdi w_onebuf_opt.wo_fdi	/* 'foldignore' */
+    long	wo_fdl;
+# define w_p_fdl w_onebuf_opt.wo_fdl	/* 'foldlevel' */
+    char_u	*wo_fdm;
+# define w_p_fdm w_onebuf_opt.wo_fdm	/* 'foldmethod' */
+    long	wo_fml;
+# define w_p_fml w_onebuf_opt.wo_fml	/* 'foldminlines' */
+    long	wo_fdn;
+# define w_p_fdn w_onebuf_opt.wo_fdn	/* 'foldnestmax' */
+# ifdef FEAT_EVAL
+    char_u	*wo_fde;
+# define w_p_fde w_onebuf_opt.wo_fde	/* 'foldexpr' */
+    char_u	*wo_fdt;
+#  define w_p_fdt w_onebuf_opt.wo_fdt	/* 'foldtext' */
+# endif
+    char_u	*wo_fmr;
+# define w_p_fmr w_onebuf_opt.wo_fmr	/* 'foldmarker' */
+#endif
+#ifdef FEAT_LINEBREAK
+    int		wo_lbr;
+# define w_p_lbr w_onebuf_opt.wo_lbr	/* 'linebreak' */
+#endif
+    int		wo_list;
+#define w_p_list w_onebuf_opt.wo_list	/* 'list' */
+    int		wo_nu;
+#define w_p_nu w_onebuf_opt.wo_nu	/* 'number' */
+#ifdef FEAT_LINEBREAK
+    long	wo_nuw;
+# define w_p_nuw w_onebuf_opt.wo_nuw	/* 'numberwidth' */
+#endif
+#if defined(FEAT_WINDOWS)
+    int		wo_wfh;
+# define w_p_wfh w_onebuf_opt.wo_wfh	/* 'winfixheight' */
+    int		wo_wfw;
+# define w_p_wfw w_onebuf_opt.wo_wfw	/* 'winfixwidth' */
+#endif
+#if defined(FEAT_WINDOWS) && defined(FEAT_QUICKFIX)
+    int		wo_pvw;
+# define w_p_pvw w_onebuf_opt.wo_pvw	/* 'previewwindow' */
+#endif
+#ifdef FEAT_RIGHTLEFT
+    int		wo_rl;
+# define w_p_rl w_onebuf_opt.wo_rl	/* 'rightleft' */
+    char_u	*wo_rlc;
+# define w_p_rlc w_onebuf_opt.wo_rlc	/* 'rightleftcmd' */
+#endif
+    long	wo_scr;
+#define w_p_scr w_onebuf_opt.wo_scr	/* 'scroll' */
+#ifdef FEAT_SPELL
+    int		wo_spell;
+# define w_p_spell w_onebuf_opt.wo_spell /* 'spell' */
+#endif
+#ifdef FEAT_SYN_HL
+    int		wo_cuc;
+# define w_p_cuc w_onebuf_opt.wo_cuc	/* 'cursorcolumn' */
+    int		wo_cul;
+# define w_p_cul w_onebuf_opt.wo_cul	/* 'cursorline' */
+#endif
+#ifdef FEAT_STL_OPT
+    char_u	*wo_stl;
+#define w_p_stl w_onebuf_opt.wo_stl	/* 'statusline' */
+#endif
+#ifdef FEAT_SCROLLBIND
+    int		wo_scb;
+# define w_p_scb w_onebuf_opt.wo_scb	/* 'scrollbind' */
+#endif
+    int		wo_wrap;
+#define w_p_wrap w_onebuf_opt.wo_wrap	/* 'wrap' */
+
+#ifdef FEAT_EVAL
+    int		wo_scriptID[WV_COUNT];	/* SIDs for window-local options */
+# define w_p_scriptID w_onebuf_opt.wo_scriptID
+#endif
+} winopt_T;
+
+/*
+ * Window info stored with a buffer.
+ *
+ * Two types of info are kept for a buffer which are associated with a
+ * specific window:
+ * 1. Each window can have a different line number associated with a buffer.
+ * 2. The window-local options for a buffer work in a similar way.
+ * The window-info is kept in a list at b_wininfo.  It is kept in
+ * most-recently-used order.
+ */
+struct wininfo_S
+{
+    wininfo_T	*wi_next;	/* next entry or NULL for last entry */
+    wininfo_T	*wi_prev;	/* previous entry or NULL for first entry */
+    win_T	*wi_win;	/* pointer to window that did set wi_lnum */
+    pos_T	wi_fpos;	/* last cursor position in the file */
+    int		wi_optset;	/* TRUE when wi_opt has useful values */
+    winopt_T	wi_opt;		/* local window options */
+#ifdef FEAT_FOLDING
+    int		wi_fold_manual;	/* copy of w_fold_manual */
+    garray_T	wi_folds;	/* clone of w_folds */
+#endif
+};
+
+/*
+ * Info used to pass info about a fold from the fold-detection code to the
+ * code that displays the foldcolumn.
+ */
+typedef struct foldinfo
+{
+    int		fi_level;	/* level of the fold; when this is zero the
+				   other fields are invalid */
+    int		fi_lnum;	/* line number where fold starts */
+    int		fi_low_level;	/* lowest fold level that starts in the same
+				   line */
+} foldinfo_T;
+
+/* Structure to store info about the Visual area. */
+typedef struct
+{
+    pos_T	vi_start;	/* start pos of last VIsual */
+    pos_T	vi_end;		/* end position of last VIsual */
+    int		vi_mode;	/* VIsual_mode of last VIsual */
+    colnr_T	vi_curswant;	/* MAXCOL from w_curswant */
+} visualinfo_T;
+
+/*
+ * structures used for undo
+ */
+
+typedef struct u_entry u_entry_T;
+typedef struct u_header u_header_T;
+struct u_entry
+{
+    u_entry_T	*ue_next;	/* pointer to next entry in list */
+    linenr_T	ue_top;		/* number of line above undo block */
+    linenr_T	ue_bot;		/* number of line below undo block */
+    linenr_T	ue_lcount;	/* linecount when u_save called */
+    char_u	**ue_array;	/* array of lines in undo block */
+    long	ue_size;	/* number of lines in ue_array */
+};
+
+struct u_header
+{
+    u_header_T	*uh_next;	/* pointer to next undo header in list */
+    u_header_T	*uh_prev;	/* pointer to previous header in list */
+    u_header_T	*uh_alt_next;	/* pointer to next header for alt. redo */
+    u_header_T	*uh_alt_prev;	/* pointer to previous header for alt. redo */
+    long	uh_seq;		/* sequence number, higher == newer undo */
+    int		uh_walk;	/* used by undo_time() */
+    u_entry_T	*uh_entry;	/* pointer to first entry */
+    u_entry_T	*uh_getbot_entry; /* pointer to where ue_bot must be set */
+    pos_T	uh_cursor;	/* cursor position before saving */
+#ifdef FEAT_VIRTUALEDIT
+    long	uh_cursor_vcol;
+#endif
+    int		uh_flags;	/* see below */
+    pos_T	uh_namedm[NMARKS];	/* marks before undo/after redo */
+#ifdef FEAT_VISUAL
+    visualinfo_T uh_visual;	/* Visual areas before undo/after redo */
+#endif
+    time_t	uh_time;	/* timestamp when the change was made */
+};
+
+/* values for uh_flags */
+#define UH_CHANGED  0x01	/* b_changed flag before undo/after redo */
+#define UH_EMPTYBUF 0x02	/* buffer was empty */
+
+/*
+ * structures used in undo.c
+ */
+#if SIZEOF_INT > 2
+# define ALIGN_LONG	/* longword alignment and use filler byte */
+# define ALIGN_SIZE (sizeof(long))
+#else
+# define ALIGN_SIZE (sizeof(short))
+#endif
+
+#define ALIGN_MASK (ALIGN_SIZE - 1)
+
+typedef struct m_info minfo_T;
+
+/*
+ * stucture used to link chunks in one of the free chunk lists.
+ */
+struct m_info
+{
+#ifdef ALIGN_LONG
+    long_u	m_size;		/* size of the chunk (including m_info) */
+#else
+    short_u	m_size;		/* size of the chunk (including m_info) */
+#endif
+    minfo_T	*m_next;	/* pointer to next free chunk in the list */
+};
+
+/*
+ * structure used to link blocks in the list of allocated blocks.
+ */
+typedef struct m_block mblock_T;
+struct m_block
+{
+    mblock_T	*mb_next;	/* pointer to next allocated block */
+    size_t	mb_size;	/* total size of all chunks in this block */
+    size_t	mb_maxsize;	/* size of largest fee chunk */
+    minfo_T	mb_info;	/* head of free chunk list for this block */
+};
+
+/*
+ * things used in memfile.c
+ */
+
+typedef struct block_hdr    bhdr_T;
+typedef struct memfile	    memfile_T;
+typedef long		    blocknr_T;
+
+/*
+ * for each (previously) used block in the memfile there is one block header.
+ *
+ * The block may be linked in the used list OR in the free list.
+ * The used blocks are also kept in hash lists.
+ *
+ * The used list is a doubly linked list, most recently used block first.
+ *	The blocks in the used list have a block of memory allocated.
+ *	mf_used_count is the number of pages in the used list.
+ * The hash lists are used to quickly find a block in the used list.
+ * The free list is a single linked list, not sorted.
+ *	The blocks in the free list have no block of memory allocated and
+ *	the contents of the block in the file (if any) is irrelevant.
+ */
+
+struct block_hdr
+{
+    bhdr_T	*bh_next;	    /* next block_hdr in free or used list */
+    bhdr_T	*bh_prev;	    /* previous block_hdr in used list */
+    bhdr_T	*bh_hash_next;	    /* next block_hdr in hash list */
+    bhdr_T	*bh_hash_prev;	    /* previous block_hdr in hash list */
+    blocknr_T	bh_bnum;		/* block number */
+    char_u	*bh_data;	    /* pointer to memory (for used block) */
+    int		bh_page_count;	    /* number of pages in this block */
+
+#define BH_DIRTY    1
+#define BH_LOCKED   2
+    char	bh_flags;	    /* BH_DIRTY or BH_LOCKED */
+};
+
+/*
+ * when a block with a negative number is flushed to the file, it gets
+ * a positive number. Because the reference to the block is still the negative
+ * number, we remember the translation to the new positive number in the
+ * double linked trans lists. The structure is the same as the hash lists.
+ */
+typedef struct nr_trans NR_TRANS;
+
+struct nr_trans
+{
+    NR_TRANS	*nt_next;		/* next nr_trans in hash list */
+    NR_TRANS	*nt_prev;		/* previous nr_trans in hash list */
+    blocknr_T	nt_old_bnum;		/* old, negative, number */
+    blocknr_T	nt_new_bnum;		/* new, positive, number */
+};
+
+/*
+ * structure used to store one block of the stuff/redo/recording buffers
+ */
+struct buffblock
+{
+    struct buffblock	*b_next;	/* pointer to next buffblock */
+    char_u		b_str[1];	/* contents (actually longer) */
+};
+
+/*
+ * header used for the stuff buffer and the redo buffer
+ */
+struct buffheader
+{
+    struct buffblock	bh_first;	/* first (dummy) block of list */
+    struct buffblock	*bh_curr;	/* buffblock for appending */
+    int			bh_index;	/* index for reading */
+    int			bh_space;	/* space in bh_curr for appending */
+};
+
+/*
+ * used for completion on the command line
+ */
+typedef struct expand
+{
+    int		xp_context;		/* type of expansion */
+    char_u	*xp_pattern;		/* start of item to expand */
+#if defined(FEAT_USR_CMDS) && defined(FEAT_EVAL) && defined(FEAT_CMDL_COMPL)
+    char_u	*xp_arg;		/* completion function */
+    int		xp_scriptID;		/* SID for completion function */
+#endif
+    int		xp_backslash;		/* one of the XP_BS_ values */
+#ifndef BACKSLASH_IN_FILENAME
+    int		xp_shell;		/* for a shell command more characters
+					   need to be escaped */
+#endif
+    int		xp_numfiles;		/* number of files found by
+						    file name completion */
+    char_u	**xp_files;		/* list of files */
+} expand_T;
+
+/* values for xp_backslash */
+#define XP_BS_NONE	0	/* nothing special for backslashes */
+#define XP_BS_ONE	1	/* uses one backslash before a space */
+#define XP_BS_THREE	2	/* uses three backslashes before a space */
+
+/*
+ * Command modifiers ":vertical", ":browse", ":confirm" and ":hide" set a flag.
+ * This needs to be saved for recursive commands, put them in a structure for
+ * easy manipulation.
+ */
+typedef struct
+{
+    int		hide;			/* TRUE when ":hide" was used */
+# ifdef FEAT_BROWSE
+    int		browse;			/* TRUE to invoke file dialog */
+# endif
+# ifdef FEAT_WINDOWS
+    int		split;			/* flags for win_split() */
+    int		tab;			/* > 0 when ":tab" was used */
+# endif
+# if defined(FEAT_GUI_DIALOG) || defined(FEAT_CON_DIALOG)
+    int		confirm;		/* TRUE to invoke yes/no dialog */
+# endif
+    int		keepalt;		/* TRUE when ":keepalt" was used */
+    int		keepmarks;		/* TRUE when ":keepmarks" was used */
+    int		keepjumps;		/* TRUE when ":keepjumps" was used */
+    int		lockmarks;		/* TRUE when ":lockmarks" was used */
+# ifdef FEAT_AUTOCMD
+    char_u	*save_ei;		/* saved value of 'eventignore' */
+# endif
+} cmdmod_T;
+
+/*
+ * Simplistic hashing scheme to quickly locate the blocks in the used list.
+ * 64 blocks are found directly (64 * 4K = 256K, most files are smaller).
+ */
+#define MEMHASHSIZE	64
+#define MEMHASH(nr)	((nr) & (MEMHASHSIZE - 1))
+
+struct memfile
+{
+    char_u	*mf_fname;		/* name of the file */
+    char_u	*mf_ffname;		/* idem, full path */
+    int		mf_fd;			/* file descriptor */
+    bhdr_T	*mf_free_first;		/* first block_hdr in free list */
+    bhdr_T	*mf_used_first;		/* mru block_hdr in used list */
+    bhdr_T	*mf_used_last;		/* lru block_hdr in used list */
+    unsigned	mf_used_count;		/* number of pages in used list */
+    unsigned	mf_used_count_max;	/* maximum number of pages in memory */
+    bhdr_T	*mf_hash[MEMHASHSIZE];	/* array of hash lists */
+    NR_TRANS	*mf_trans[MEMHASHSIZE];	/* array of trans lists */
+    blocknr_T	mf_blocknr_max;		/* highest positive block number + 1*/
+    blocknr_T	mf_blocknr_min;		/* lowest negative block number - 1 */
+    blocknr_T	mf_neg_count;		/* number of negative blocks numbers */
+    blocknr_T	mf_infile_count;	/* number of pages in the file */
+    unsigned	mf_page_size;		/* number of bytes in a page */
+    int		mf_dirty;		/* TRUE if there are dirty blocks */
+};
+
+/*
+ * things used in memline.c
+ */
+/*
+ * When searching for a specific line, we remember what blocks in the tree
+ * are the branches leading to that block. This is stored in ml_stack.  Each
+ * entry is a pointer to info in a block (may be data block or pointer block)
+ */
+typedef struct info_pointer
+{
+    blocknr_T	ip_bnum;	/* block number */
+    linenr_T	ip_low;		/* lowest lnum in this block */
+    linenr_T	ip_high;	/* highest lnum in this block */
+    int		ip_index;	/* index for block with current lnum */
+} infoptr_T;	/* block/index pair */
+
+#ifdef FEAT_BYTEOFF
+typedef struct ml_chunksize
+{
+    int		mlcs_numlines;
+    long	mlcs_totalsize;
+} chunksize_T;
+
+ /* Flags when calling ml_updatechunk() */
+
+#define ML_CHNK_ADDLINE 1
+#define ML_CHNK_DELLINE 2
+#define ML_CHNK_UPDLINE 3
+#endif
+
+/*
+ * the memline structure holds all the information about a memline
+ */
+typedef struct memline
+{
+    linenr_T	ml_line_count;	/* number of lines in the buffer */
+
+    memfile_T	*ml_mfp;	/* pointer to associated memfile */
+
+#define ML_EMPTY	1	/* empty buffer */
+#define ML_LINE_DIRTY	2	/* cached line was changed and allocated */
+#define ML_LOCKED_DIRTY	4	/* ml_locked was changed */
+#define ML_LOCKED_POS	8	/* ml_locked needs positive block number */
+    int		ml_flags;
+
+    infoptr_T	*ml_stack;	/* stack of pointer blocks (array of IPTRs) */
+    int		ml_stack_top;	/* current top if ml_stack */
+    int		ml_stack_size;	/* total number of entries in ml_stack */
+
+    linenr_T	ml_line_lnum;	/* line number of cached line, 0 if not valid */
+    char_u	*ml_line_ptr;	/* pointer to cached line */
+
+    bhdr_T	*ml_locked;	/* block used by last ml_get */
+    linenr_T	ml_locked_low;	/* first line in ml_locked */
+    linenr_T	ml_locked_high;	/* last line in ml_locked */
+    int		ml_locked_lineadd;  /* number of lines inserted in ml_locked */
+#ifdef FEAT_BYTEOFF
+    chunksize_T *ml_chunksize;
+    int		ml_numchunks;
+    int		ml_usedchunks;
+#endif
+} memline_T;
+
+#if defined(FEAT_SIGNS) || defined(PROTO)
+typedef struct signlist signlist_T;
+
+struct signlist
+{
+    int		id;		/* unique identifier for each placed sign */
+    linenr_T	lnum;		/* line number which has this sign */
+    int		typenr;		/* typenr of sign */
+    signlist_T	*next;		/* next signlist entry */
+# ifdef FEAT_NETBEANS_INTG
+    signlist_T  *prev;		/* previous entry -- for easy reordering */
+# endif
+};
+
+/* type argument for buf_getsigntype() */
+#define SIGN_ANY	0
+#define SIGN_LINEHL	1
+#define SIGN_ICON	2
+#define SIGN_TEXT	3
+#endif
+
+/*
+ * Argument list: Array of file names.
+ * Used for the global argument list and the argument lists local to a window.
+ */
+typedef struct arglist
+{
+    garray_T	al_ga;		/* growarray with the array of file names */
+    int		al_refcount;	/* number of windows using this arglist */
+} alist_T;
+
+/*
+ * For each argument remember the file name as it was given, and the buffer
+ * number that contains the expanded file name (required for when ":cd" is
+ * used.
+ */
+typedef struct argentry
+{
+    char_u	*ae_fname;	/* file name as specified */
+    int		ae_fnum;	/* buffer number with expanded file name */
+} aentry_T;
+
+#ifdef FEAT_WINDOWS
+# define ALIST(win) (win)->w_alist
+#else
+# define ALIST(win) (&global_alist)
+#endif
+#define GARGLIST	((aentry_T *)global_alist.al_ga.ga_data)
+#define ARGLIST		((aentry_T *)ALIST(curwin)->al_ga.ga_data)
+#define WARGLIST(wp)	((aentry_T *)ALIST(wp)->al_ga.ga_data)
+#define AARGLIST(al)	((aentry_T *)((al)->al_ga.ga_data))
+#define GARGCOUNT	(global_alist.al_ga.ga_len)
+#define ARGCOUNT	(ALIST(curwin)->al_ga.ga_len)
+#define WARGCOUNT(wp)	(ALIST(wp)->al_ga.ga_len)
+
+/*
+ * A list used for saving values of "emsg_silent".  Used by ex_try() to save the
+ * value of "emsg_silent" if it was non-zero.  When this is done, the CSF_SILENT
+ * flag below is set.
+ */
+
+typedef struct eslist_elem eslist_T;
+struct eslist_elem
+{
+    int		saved_emsg_silent;	/* saved value of "emsg_silent" */
+    eslist_T	*next;			/* next element on the list */
+};
+
+/*
+ * For conditional commands a stack is kept of nested conditionals.
+ * When cs_idx < 0, there is no conditional command.
+ */
+#define CSTACK_LEN	50
+
+struct condstack
+{
+    short	cs_flags[CSTACK_LEN];	/* CSF_ flags */
+    char	cs_pending[CSTACK_LEN];	/* CSTP_: what's pending in ":finally"*/
+    union {
+	void	*csp_rv[CSTACK_LEN];	/* return typeval for pending return */
+	void	*csp_ex[CSTACK_LEN];	/* exception for pending throw */
+    }		cs_pend;
+    void	*cs_forinfo[CSTACK_LEN]; /* info used by ":for" */
+    int		cs_line[CSTACK_LEN];	/* line nr of ":while"/":for" line */
+    int		cs_idx;			/* current entry, or -1 if none */
+    int		cs_looplevel;		/* nr of nested ":while"s and ":for"s */
+    int		cs_trylevel;		/* nr of nested ":try"s */
+    eslist_T	*cs_emsg_silent_list;	/* saved values of "emsg_silent" */
+    char	cs_lflags;		/* loop flags: CSL_ flags */
+};
+# define cs_rettv	cs_pend.csp_rv
+# define cs_exception	cs_pend.csp_ex
+
+/* There is no CSF_IF, the lack of CSF_WHILE, CSF_FOR and CSF_TRY means ":if"
+ * was used. */
+# define CSF_TRUE	0x0001	/* condition was TRUE */
+# define CSF_ACTIVE	0x0002	/* current state is active */
+# define CSF_ELSE	0x0004	/* ":else" has been passed */
+# define CSF_WHILE	0x0008	/* is a ":while" */
+# define CSF_FOR	0x0010	/* is a ":for" */
+
+# define CSF_TRY	0x0100	/* is a ":try" */
+# define CSF_FINALLY	0x0200	/* ":finally" has been passed */
+# define CSF_THROWN	0x0400	/* exception thrown to this try conditional */
+# define CSF_CAUGHT	0x0800  /* exception caught by this try conditional */
+# define CSF_SILENT	0x1000	/* "emsg_silent" reset by ":try" */
+/* Note that CSF_ELSE is only used when CSF_TRY and CSF_WHILE are unset
+ * (an ":if"), and CSF_SILENT is only used when CSF_TRY is set. */
+
+/*
+ * What's pending for being reactivated at the ":endtry" of this try
+ * conditional:
+ */
+# define CSTP_NONE	0	/* nothing pending in ":finally" clause */
+# define CSTP_ERROR	1	/* an error is pending */
+# define CSTP_INTERRUPT	2	/* an interrupt is pending */
+# define CSTP_THROW	4	/* a throw is pending */
+# define CSTP_BREAK	8	/* ":break" is pending */
+# define CSTP_CONTINUE	16	/* ":continue" is pending */
+# define CSTP_RETURN	24	/* ":return" is pending */
+# define CSTP_FINISH	32	/* ":finish" is pending */
+
+/*
+ * Flags for the cs_lflags item in struct condstack.
+ */
+# define CSL_HAD_LOOP	 1	/* just found ":while" or ":for" */
+# define CSL_HAD_ENDLOOP 2	/* just found ":endwhile" or ":endfor" */
+# define CSL_HAD_CONT	 4	/* just found ":continue" */
+# define CSL_HAD_FINA	 8	/* just found ":finally" */
+
+/*
+ * A list of error messages that can be converted to an exception.  "throw_msg"
+ * is only set in the first element of the list.  Usually, it points to the
+ * original message stored in that element, but sometimes it points to a later
+ * message in the list.  See cause_errthrow() below.
+ */
+struct msglist
+{
+    char_u		*msg;		/* original message */
+    char_u		*throw_msg;	/* msg to throw: usually original one */
+    struct msglist	*next;		/* next of several messages in a row */
+};
+
+/*
+ * Structure describing an exception.
+ * (don't use "struct exception", it's used by the math library).
+ */
+typedef struct vim_exception except_T;
+struct vim_exception
+{
+    int			type;		/* exception type */
+    char_u		*value;		/* exception value */
+    struct msglist	*messages;	/* message(s) causing error exception */
+    char_u		*throw_name;	/* name of the throw point */
+    linenr_T		throw_lnum;	/* line number of the throw point */
+    except_T		*caught;	/* next exception on the caught stack */
+};
+
+/*
+ * The exception types.
+ */
+#define ET_USER		0	/* exception caused by ":throw" command */
+#define ET_ERROR	1	/* error exception */
+#define ET_INTERRUPT	2	/* interrupt exception triggered by Ctrl-C */
+
+/*
+ * Structure to save the error/interrupt/exception state between calls to
+ * enter_cleanup() and leave_cleanup().  Must be allocated as an automatic
+ * variable by the (common) caller of these functions.
+ */
+typedef struct cleanup_stuff cleanup_T;
+struct cleanup_stuff
+{
+    int pending;		/* error/interrupt/exception state */
+    except_T *exception;	/* exception value */
+};
+
+#ifdef FEAT_SYN_HL
+/* struct passed to in_id_list() */
+struct sp_syn
+{
+    int		inc_tag;	/* ":syn include" unique tag */
+    short	id;		/* highlight group ID of item */
+    short	*cont_in_list;	/* cont.in group IDs, if non-zero */
+};
+
+/*
+ * Each keyword has one keyentry, which is linked in a hash list.
+ */
+typedef struct keyentry keyentry_T;
+
+struct keyentry
+{
+    keyentry_T	*ke_next;	/* next entry with identical "keyword[]" */
+    struct sp_syn k_syn;	/* struct passed to in_id_list() */
+    short	*next_list;	/* ID list for next match (if non-zero) */
+    short	flags;		/* see syntax.c */
+    char_u	keyword[1];	/* actually longer */
+};
+
+/*
+ * Struct used to store one state of the state stack.
+ */
+typedef struct buf_state
+{
+    int		    bs_idx;	 /* index of pattern */
+    long	    bs_flags;	 /* flags for pattern */
+    reg_extmatch_T *bs_extmatch; /* external matches from start pattern */
+} bufstate_T;
+
+/*
+ * syn_state contains the syntax state stack for the start of one line.
+ * Used by b_sst_array[].
+ */
+typedef struct syn_state synstate_T;
+
+struct syn_state
+{
+    synstate_T	*sst_next;	/* next entry in used or free list */
+    linenr_T	sst_lnum;	/* line number for this state */
+    union
+    {
+	bufstate_T	sst_stack[SST_FIX_STATES]; /* short state stack */
+	garray_T	sst_ga;	/* growarray for long state stack */
+    } sst_union;
+    int		sst_next_flags;	/* flags for sst_next_list */
+    short	*sst_next_list;	/* "nextgroup" list in this state
+				 * (this is a copy, don't free it! */
+    short	sst_stacksize;	/* number of states on the stack */
+    disptick_T	sst_tick;	/* tick when last displayed */
+    linenr_T	sst_change_lnum;/* when non-zero, change in this line
+				 * may have made the state invalid */
+};
+#endif /* FEAT_SYN_HL */
+
+/*
+ * Structure shared between syntax.c, screen.c and gui_x11.c.
+ */
+typedef struct attr_entry
+{
+    short	    ae_attr;		/* HL_BOLD, etc. */
+    union
+    {
+	struct
+	{
+	    char_u	    *start;	/* start escape sequence */
+	    char_u	    *stop;	/* stop escape sequence */
+	} term;
+	struct
+	{
+	    /* These colors need to be > 8 bits to hold 256. */
+	    short_u	    fg_color;	/* foreground color number */
+	    short_u	    bg_color;	/* background color number */
+	} cterm;
+# ifdef FEAT_GUI
+	struct
+	{
+	    guicolor_T	    fg_color;	/* foreground color handle */
+	    guicolor_T	    bg_color;	/* background color handle */
+	    guicolor_T	    sp_color;	/* special color handle */
+	    GuiFont	    font;	/* font handle */
+#  ifdef FEAT_XFONTSET
+	    GuiFontset	    fontset;	/* fontset handle */
+#  endif
+	} gui;
+# endif
+    } ae_u;
+} attrentry_T;
+
+#ifdef USE_ICONV
+# ifdef HAVE_ICONV_H
+#  include <iconv.h>
+# else
+#  if defined(MACOS_X)
+#   include <sys/errno.h>
+#   define EILSEQ ENOENT /* MacOS X does not have EILSEQ */
+typedef struct _iconv_t *iconv_t;
+#  else
+#   if defined(MACOS_CLASSIC)
+typedef struct _iconv_t *iconv_t;
+#    define EINVAL	22
+#    define E2BIG	7
+#    define ENOENT	2
+#    define EFAULT	14
+#    define EILSEQ	123
+#   else
+#    include <errno.h>
+#   endif
+#  endif
+typedef void *iconv_t;
+# endif
+#endif
+
+/*
+ * Used for the typeahead buffer: typebuf.
+ */
+typedef struct
+{
+    char_u	*tb_buf;	/* buffer for typed characters */
+    char_u	*tb_noremap;	/* mapping flags for characters in tb_buf[] */
+    int		tb_buflen;	/* size of tb_buf[] */
+    int		tb_off;		/* current position in tb_buf[] */
+    int		tb_len;		/* number of valid bytes in tb_buf[] */
+    int		tb_maplen;	/* nr of mapped bytes in tb_buf[] */
+    int		tb_silent;	/* nr of silently mapped bytes in tb_buf[] */
+    int		tb_no_abbr_cnt; /* nr of bytes without abbrev. in tb_buf[] */
+    int		tb_change_cnt;	/* nr of time tb_buf was changed; never zero */
+} typebuf_T;
+
+/* Struct to hold the saved typeahead for save_typeahead(). */
+typedef struct
+{
+    typebuf_T		save_typebuf;
+    int			typebuf_valid;	    /* TRUE when save_typebuf valid */
+    struct buffheader	save_stuffbuff;
+#ifdef USE_INPUT_BUF
+    char_u		*save_inputbuf;
+#endif
+} tasave_T;
+
+/*
+ * Used for conversion of terminal I/O and script files.
+ */
+typedef struct
+{
+    int		vc_type;	/* zero or one of the CONV_ values */
+    int		vc_factor;	/* max. expansion factor */
+# ifdef WIN3264
+    int		vc_cpfrom;	/* codepage to convert from (CONV_CODEPAGE) */
+    int		vc_cpto;	/* codepage to convert to (CONV_CODEPAGE) */
+# endif
+# ifdef USE_ICONV
+    iconv_t	vc_fd;		/* for CONV_ICONV */
+# endif
+    int		vc_fail;	/* fail for invalid char, don't use '?' */
+} vimconv_T;
+
+/*
+ * Structure used for reading from the viminfo file.
+ */
+typedef struct
+{
+    char_u	*vir_line;	/* text of the current line */
+    FILE	*vir_fd;	/* file descriptor */
+#ifdef FEAT_MBYTE
+    vimconv_T	vir_conv;	/* encoding conversion */
+#endif
+} vir_T;
+
+#define CONV_NONE		0
+#define CONV_TO_UTF8		1
+#define CONV_9_TO_UTF8		2
+#define CONV_TO_LATIN1		3
+#define CONV_TO_LATIN9		4
+#define CONV_ICONV		5
+#ifdef WIN3264
+# define CONV_CODEPAGE		10	/* codepage -> codepage */
+#endif
+#ifdef MACOS_X
+# define CONV_MAC_LATIN1	20
+# define CONV_LATIN1_MAC	21
+# define CONV_MAC_UTF8		22
+# define CONV_UTF8_MAC		23
+#endif
+
+/*
+ * Structure used for mappings and abbreviations.
+ */
+typedef struct mapblock mapblock_T;
+struct mapblock
+{
+    mapblock_T	*m_next;	/* next mapblock in list */
+    char_u	*m_keys;	/* mapped from */
+    int		m_keylen;	/* strlen(m_keys) */
+    char_u	*m_str;		/* mapped to */
+    int		m_mode;		/* valid mode */
+    int		m_noremap;	/* if non-zero no re-mapping for m_str */
+    char	m_silent;	/* <silent> used, don't echo commands */
+#ifdef FEAT_EVAL
+    char	m_expr;		/* <expr> used, m_str is an expression */
+    scid_T	m_script_ID;	/* ID of script where map was defined */
+#endif
+};
+
+/*
+ * Used for highlighting in the status line.
+ */
+struct stl_hlrec
+{
+    char_u	*start;
+    int		userhl;		/* 0: no HL, 1-9: User HL, < 0 for syn ID */
+};
+
+/* Item for a hashtable.  "hi_key" can be one of three values:
+ * NULL:	   Never been used
+ * HI_KEY_REMOVED: Entry was removed
+ * Otherwise:	   Used item, pointer to the actual key; this usually is
+ *		   inside the item, subtract an offset to locate the item.
+ *		   This reduces the size of hashitem by 1/3.
+ */
+typedef struct hashitem_S
+{
+    long_u	hi_hash;	/* cached hash number of hi_key */
+    char_u	*hi_key;
+} hashitem_T;
+
+/* The address of "hash_removed" is used as a magic number for hi_key to
+ * indicate a removed item. */
+#define HI_KEY_REMOVED &hash_removed
+#define HASHITEM_EMPTY(hi) ((hi)->hi_key == NULL || (hi)->hi_key == &hash_removed)
+
+/* Initial size for a hashtable.  Our items are relatively small and growing
+ * is expensive, thus use 16 as a start.  Must be a power of 2. */
+#define HT_INIT_SIZE 16
+
+typedef struct hashtable_S
+{
+    long_u	ht_mask;	/* mask used for hash value (nr of items in
+				 * array is "ht_mask" + 1) */
+    long_u	ht_used;	/* number of items used */
+    long_u	ht_filled;	/* number of items used + removed */
+    int		ht_locked;	/* counter for hash_lock() */
+    int		ht_error;	/* when set growing failed, can't add more
+				   items before growing works */
+    hashitem_T	*ht_array;	/* points to the array, allocated when it's
+				   not "ht_smallarray" */
+    hashitem_T	ht_smallarray[HT_INIT_SIZE];   /* initial array */
+} hashtab_T;
+
+typedef long_u hash_T;		/* Type for hi_hash */
+
+
+#if SIZEOF_INT <= 3		/* use long if int is smaller than 32 bits */
+typedef long	varnumber_T;
+#else
+typedef int	varnumber_T;
+#endif
+
+typedef struct listvar_S list_T;
+typedef struct dictvar_S dict_T;
+
+/*
+ * Structure to hold an internal variable without a name.
+ */
+typedef struct
+{
+    char	v_type;	    /* see below: VAR_NUMBER, VAR_STRING, etc. */
+    char	v_lock;	    /* see below: VAR_LOCKED, VAR_FIXED */
+    union
+    {
+	varnumber_T	v_number;	/* number value */
+	char_u		*v_string;	/* string value (can be NULL!) */
+	list_T		*v_list;	/* list value (can be NULL!) */
+	dict_T		*v_dict;	/* dict value (can be NULL!) */
+    }		vval;
+} typval_T;
+
+/* Values for "v_type". */
+#define VAR_UNKNOWN 0
+#define VAR_NUMBER  1	/* "v_number" is used */
+#define VAR_STRING  2	/* "v_string" is used */
+#define VAR_FUNC    3	/* "v_string" is function name */
+#define VAR_LIST    4	/* "v_list" is used */
+#define VAR_DICT    5	/* "v_dict" is used */
+
+/* Values for "v_lock". */
+#define VAR_LOCKED  1	/* locked with lock(), can use unlock() */
+#define VAR_FIXED   2	/* locked forever */
+
+/*
+ * Structure to hold an item of a list: an internal variable without a name.
+ */
+typedef struct listitem_S listitem_T;
+
+struct listitem_S
+{
+    listitem_T	*li_next;	/* next item in list */
+    listitem_T	*li_prev;	/* previous item in list */
+    typval_T	li_tv;		/* type and value of the variable */
+};
+
+/*
+ * Struct used by those that are using an item in a list.
+ */
+typedef struct listwatch_S listwatch_T;
+
+struct listwatch_S
+{
+    listitem_T		*lw_item;	/* item being watched */
+    listwatch_T		*lw_next;	/* next watcher */
+};
+
+/*
+ * Structure to hold info about a list.
+ */
+struct listvar_S
+{
+    listitem_T	*lv_first;	/* first item, NULL if none */
+    listitem_T	*lv_last;	/* last item, NULL if none */
+    int		lv_refcount;	/* reference count */
+    int		lv_len;		/* number of items */
+    listwatch_T	*lv_watch;	/* first watcher, NULL if none */
+    int		lv_idx;		/* cached index of an item */
+    listitem_T	*lv_idx_item;	/* when not NULL item at index "lv_idx" */
+    int		lv_copyID;	/* ID used by deepcopy() */
+    list_T	*lv_copylist;	/* copied list used by deepcopy() */
+    char	lv_lock;	/* zero, VAR_LOCKED, VAR_FIXED */
+    list_T	*lv_used_next;	/* next list in used lists list */
+    list_T	*lv_used_prev;	/* previous list in used lists list */
+};
+
+/*
+ * Structure to hold an item of a Dictionary.
+ * Also used for a variable.
+ * The key is copied into "di_key" to avoid an extra alloc/free for it.
+ */
+struct dictitem_S
+{
+    typval_T	di_tv;		/* type and value of the variable */
+    char_u	di_flags;	/* flags (only used for variable) */
+    char_u	di_key[1];	/* key (actually longer!) */
+};
+
+typedef struct dictitem_S dictitem_T;
+
+#define DI_FLAGS_RO	1 /* "di_flags" value: read-only variable */
+#define DI_FLAGS_RO_SBX 2 /* "di_flags" value: read-only in the sandbox */
+#define DI_FLAGS_FIX	4 /* "di_flags" value: fixed variable, not allocated */
+#define DI_FLAGS_LOCK	8 /* "di_flags" value: locked variable */
+
+/*
+ * Structure to hold info about a Dictionary.
+ */
+struct dictvar_S
+{
+    int		dv_refcount;	/* reference count */
+    hashtab_T	dv_hashtab;	/* hashtab that refers to the items */
+    int		dv_copyID;	/* ID used by deepcopy() */
+    dict_T	*dv_copydict;	/* copied dict used by deepcopy() */
+    char	dv_lock;	/* zero, VAR_LOCKED, VAR_FIXED */
+    dict_T	*dv_used_next;	/* next dict in used dicts list */
+    dict_T	*dv_used_prev;	/* previous dict in used dicts list */
+};
+
+/* values for b_syn_spell: what to do with toplevel text */
+#define SYNSPL_DEFAULT	0	/* spell check if @Spell not defined */
+#define SYNSPL_TOP	1	/* spell check toplevel text */
+#define SYNSPL_NOTOP	2	/* don't spell check toplevel text */
+
+/* avoid #ifdefs for when b_spell is not available */
+#ifdef FEAT_SPELL
+# define B_SPELL(buf)  ((buf)->b_spell)
+#else
+# define B_SPELL(buf)  (0)
+#endif
+
+#ifdef FEAT_QUICKFIX
+typedef struct qf_info_S qf_info_T;
+#endif
+
+/*
+ * buffer: structure that holds information about one file
+ *
+ * Several windows can share a single Buffer
+ * A buffer is unallocated if there is no memfile for it.
+ * A buffer is new if the associated file has never been loaded yet.
+ */
+
+typedef struct file_buffer buf_T;
+
+struct file_buffer
+{
+    memline_T	b_ml;		/* associated memline (also contains line
+				   count) */
+
+    buf_T	*b_next;	/* links in list of buffers */
+    buf_T	*b_prev;
+
+    int		b_nwindows;	/* nr of windows open on this buffer */
+
+    int		b_flags;	/* various BF_ flags */
+
+    /*
+     * b_ffname has the full path of the file (NULL for no name).
+     * b_sfname is the name as the user typed it (or NULL).
+     * b_fname is the same as b_sfname, unless ":cd" has been done,
+     *		then it is the same as b_ffname (NULL for no name).
+     */
+    char_u	*b_ffname;	/* full path file name */
+    char_u	*b_sfname;	/* short file name */
+    char_u	*b_fname;	/* current file name */
+
+#ifdef UNIX
+    int		b_dev;		/* device number (-1 if not set) */
+    ino_t	b_ino;		/* inode number */
+#endif
+#ifdef FEAT_CW_EDITOR
+    FSSpec	b_FSSpec;	/* MacOS File Identification */
+#endif
+#ifdef VMS
+    char	 b_fab_rfm;	/* Record format    */
+    char	 b_fab_rat;	/* Record attribute */
+    unsigned int b_fab_mrs;	/* Max record size  */
+#endif
+#ifdef FEAT_SNIFF
+    int		b_sniff;	/* file was loaded through Sniff */
+#endif
+
+    int		b_fnum;		/* buffer number for this file. */
+
+    int		b_changed;	/* 'modified': Set to TRUE if something in the
+				   file has been changed and not written out. */
+    int		b_changedtick;	/* incremented for each change, also for undo */
+
+    int		b_saving;	/* Set to TRUE if we are in the middle of
+				   saving the buffer. */
+
+    /*
+     * Changes to a buffer require updating of the display.  To minimize the
+     * work, remember changes made and update everything at once.
+     */
+    int		b_mod_set;	/* TRUE when there are changes since the last
+				   time the display was updated */
+    linenr_T	b_mod_top;	/* topmost lnum that was changed */
+    linenr_T	b_mod_bot;	/* lnum below last changed line, AFTER the
+				   change */
+    long	b_mod_xlines;	/* number of extra buffer lines inserted;
+				   negative when lines were deleted */
+
+    wininfo_T	*b_wininfo;	/* list of last used info for each window */
+
+    long	b_mtime;	/* last change time of original file */
+    long	b_mtime_read;	/* last change time when reading */
+    size_t	b_orig_size;	/* size of original file in bytes */
+    int		b_orig_mode;	/* mode of original file */
+
+    pos_T	b_namedm[NMARKS]; /* current named marks (mark.c) */
+
+#ifdef FEAT_VISUAL
+    /* These variables are set when VIsual_active becomes FALSE */
+    visualinfo_T b_visual;
+# ifdef FEAT_EVAL
+    int		b_visual_mode_eval;  /* b_visual.vi_mode for visualmode() */
+# endif
+#endif
+
+    pos_T	b_last_cursor;	/* cursor position when last unloading this
+				   buffer */
+    pos_T	b_last_insert;	/* where Insert mode was left */
+    pos_T	b_last_change;	/* position of last change: '. mark */
+
+#ifdef FEAT_JUMPLIST
+    /*
+     * the changelist contains old change positions
+     */
+    pos_T	b_changelist[JUMPLISTSIZE];
+    int		b_changelistlen;	/* number of active entries */
+    int		b_new_change;		/* set by u_savecommon() */
+#endif
+
+    /*
+     * Character table, only used in charset.c for 'iskeyword'
+     * 32 bytes of 8 bits: 1 bit per character 0-255.
+     */
+    char_u	b_chartab[32];
+
+#ifdef FEAT_LOCALMAP
+    /* Table used for mappings local to a buffer. */
+    mapblock_T	*(b_maphash[256]);
+
+    /* First abbreviation local to a buffer. */
+    mapblock_T	*b_first_abbr;
+#endif
+#ifdef FEAT_USR_CMDS
+    /* User commands local to the buffer. */
+    garray_T	b_ucmds;
+#endif
+    /*
+     * start and end of an operator, also used for '[ and ']
+     */
+    pos_T	b_op_start;
+    pos_T	b_op_end;
+
+#ifdef FEAT_VIMINFO
+    int		b_marks_read;	/* Have we read viminfo marks yet? */
+#endif
+
+    /*
+     * The following only used in undo.c.
+     */
+    u_header_T	*b_u_oldhead;	/* pointer to oldest header */
+    u_header_T	*b_u_newhead;	/* pointer to newest header; may not be valid
+				   if b_u_curhead is not NULL */
+    u_header_T	*b_u_curhead;	/* pointer to current header */
+    int		b_u_numhead;	/* current number of headers */
+    int		b_u_synced;	/* entry lists are synced */
+    long	b_u_seq_last;	/* last used undo sequence number */
+    long	b_u_seq_cur;	/* hu_seq of header below which we are now */
+    time_t	b_u_seq_time;	/* uh_time of header below which we are now */
+
+    /*
+     * variables for "U" command in undo.c
+     */
+    char_u	*b_u_line_ptr;	/* saved line for "U" command */
+    linenr_T	b_u_line_lnum;	/* line number of line in u_line */
+    colnr_T	b_u_line_colnr;	/* optional column number */
+
+    /*
+     * The following only used in undo.c
+     */
+    mblock_T	b_block_head;	/* head of allocated memory block list */
+    minfo_T	*b_m_search;	/* pointer to chunk before previously
+				   allocated/freed chunk */
+    mblock_T	*b_mb_current;	/* block where m_search points in */
+
+#ifdef FEAT_INS_EXPAND
+    int		b_scanned;	/* ^N/^P have scanned this buffer */
+#endif
+
+    /* flags for use of ":lmap" and IM control */
+    long	b_p_iminsert;	/* input mode for insert */
+    long	b_p_imsearch;	/* input mode for search */
+#define B_IMODE_USE_INSERT -1	/*	Use b_p_iminsert value for search */
+#define B_IMODE_NONE 0		/*	Input via none */
+#define B_IMODE_LMAP 1		/*	Input via langmap */
+#ifndef USE_IM_CONTROL
+# define B_IMODE_LAST 1
+#else
+# define B_IMODE_IM 2		/*	Input via input method */
+# define B_IMODE_LAST 2
+#endif
+
+#ifdef FEAT_KEYMAP
+    short	b_kmap_state;	/* using "lmap" mappings */
+# define KEYMAP_INIT	1	/* 'keymap' was set, call keymap_init() */
+# define KEYMAP_LOADED	2	/* 'keymap' mappings have been loaded */
+    garray_T	b_kmap_ga;	/* the keymap table */
+#endif
+
+    /*
+     * Options local to a buffer.
+     * They are here because their value depends on the type of file
+     * or contents of the file being edited.
+     */
+    int		b_p_initialized;	/* set when options initialized */
+
+#ifdef FEAT_EVAL
+    int		b_p_scriptID[BV_COUNT];	/* SIDs for buffer-local options */
+#endif
+
+    int		b_p_ai;		/* 'autoindent' */
+    int		b_p_ai_nopaste;	/* b_p_ai saved for paste mode */
+    int		b_p_ci;		/* 'copyindent' */
+    int		b_p_bin;	/* 'binary' */
+#ifdef FEAT_MBYTE
+    int		b_p_bomb;	/* 'bomb' */
+#endif
+#if defined(FEAT_QUICKFIX)
+    char_u	*b_p_bh;	/* 'bufhidden' */
+    char_u	*b_p_bt;	/* 'buftype' */
+#endif
+    int		b_p_bl;		/* 'buflisted' */
+#ifdef FEAT_CINDENT
+    int		b_p_cin;	/* 'cindent' */
+    char_u	*b_p_cino;	/* 'cinoptions' */
+    char_u	*b_p_cink;	/* 'cinkeys' */
+#endif
+#if defined(FEAT_CINDENT) || defined(FEAT_SMARTINDENT)
+    char_u	*b_p_cinw;	/* 'cinwords' */
+#endif
+#ifdef FEAT_COMMENTS
+    char_u	*b_p_com;	/* 'comments' */
+#endif
+#ifdef FEAT_FOLDING
+    char_u	*b_p_cms;	/* 'commentstring' */
+#endif
+#ifdef FEAT_INS_EXPAND
+    char_u	*b_p_cpt;	/* 'complete' */
+#endif
+#ifdef FEAT_COMPL_FUNC
+    char_u	*b_p_cfu;	/* 'completefunc' */
+    char_u	*b_p_ofu;	/* 'omnifunc' */
+#endif
+    int		b_p_eol;	/* 'endofline' */
+    int		b_p_et;		/* 'expandtab' */
+    int		b_p_et_nobin;	/* b_p_et saved for binary mode */
+#ifdef FEAT_MBYTE
+    char_u	*b_p_fenc;	/* 'fileencoding' */
+#endif
+    char_u	*b_p_ff;	/* 'fileformat' */
+#ifdef FEAT_AUTOCMD
+    char_u	*b_p_ft;	/* 'filetype' */
+#endif
+    char_u	*b_p_fo;	/* 'formatoptions' */
+    char_u	*b_p_flp;	/* 'formatlistpat' */
+    int		b_p_inf;	/* 'infercase' */
+    char_u	*b_p_isk;	/* 'iskeyword' */
+#ifdef FEAT_FIND_ID
+    char_u	*b_p_def;	/* 'define' local value */
+    char_u	*b_p_inc;	/* 'include' */
+# ifdef FEAT_EVAL
+    char_u	*b_p_inex;	/* 'includeexpr' */
+    long_u	b_p_inex_flags;	/* flags for 'includeexpr' */
+# endif
+#endif
+#if defined(FEAT_CINDENT) && defined(FEAT_EVAL)
+    char_u	*b_p_inde;	/* 'indentexpr' */
+    long_u	b_p_inde_flags;	/* flags for 'indentexpr' */
+    char_u	*b_p_indk;	/* 'indentkeys' */
+#endif
+#if defined(FEAT_EVAL)
+    char_u	*b_p_fex;	/* 'formatexpr' */
+    long_u	b_p_fex_flags;	/* flags for 'formatexpr' */
+#endif
+#ifdef FEAT_CRYPT
+    char_u	*b_p_key;	/* 'key' */
+#endif
+    char_u	*b_p_kp;	/* 'keywordprg' */
+#ifdef FEAT_LISP
+    int		b_p_lisp;	/* 'lisp' */
+#endif
+    char_u	*b_p_mps;	/* 'matchpairs' */
+    int		b_p_ml;		/* 'modeline' */
+    int		b_p_ml_nobin;	/* b_p_ml saved for binary mode */
+    int		b_p_ma;		/* 'modifiable' */
+    char_u	*b_p_nf;	/* 'nrformats' */
+#ifdef FEAT_OSFILETYPE
+    char_u	*b_p_oft;	/* 'osfiletype' */
+#endif
+    int		b_p_pi;		/* 'preserveindent' */
+#ifdef FEAT_TEXTOBJ
+    char_u	*b_p_qe;	/* 'quoteescape' */
+#endif
+    int		b_p_ro;		/* 'readonly' */
+    long	b_p_sw;		/* 'shiftwidth' */
+#ifndef SHORT_FNAME
+    int		b_p_sn;		/* 'shortname' */
+#endif
+#ifdef FEAT_SMARTINDENT
+    int		b_p_si;		/* 'smartindent' */
+#endif
+    long	b_p_sts;	/* 'softtabstop' */
+    long	b_p_sts_nopaste; /* b_p_sts saved for paste mode */
+#ifdef FEAT_SEARCHPATH
+    char_u	*b_p_sua;	/* 'suffixesadd' */
+#endif
+    int		b_p_swf;	/* 'swapfile' */
+#ifdef FEAT_SYN_HL
+    long	b_p_smc;	/* 'synmaxcol' */
+    char_u	*b_p_syn;	/* 'syntax' */
+#endif
+#ifdef FEAT_SPELL
+    char_u	*b_p_spc;	/* 'spellcapcheck' */
+    regprog_T	*b_cap_prog;	/* program for 'spellcapcheck' */
+    char_u	*b_p_spf;	/* 'spellfile' */
+    char_u	*b_p_spl;	/* 'spelllang' */
+#endif
+    long	b_p_ts;		/* 'tabstop' */
+    int		b_p_tx;		/* 'textmode' */
+    long	b_p_tw;		/* 'textwidth' */
+    long	b_p_tw_nobin;	/* b_p_tw saved for binary mode */
+    long	b_p_tw_nopaste;	/* b_p_tw saved for paste mode */
+    long	b_p_wm;		/* 'wrapmargin' */
+    long	b_p_wm_nobin;	/* b_p_wm saved for binary mode */
+    long	b_p_wm_nopaste;	/* b_p_wm saved for paste mode */
+#ifdef FEAT_KEYMAP
+    char_u	*b_p_keymap;	/* 'keymap' */
+#endif
+
+    /* local values for options which are normally global */
+#ifdef FEAT_QUICKFIX
+    char_u	*b_p_gp;	/* 'grepprg' local value */
+    char_u	*b_p_mp;	/* 'makeprg' local value */
+    char_u	*b_p_efm;	/* 'errorformat' local value */
+#endif
+    char_u	*b_p_ep;	/* 'equalprg' local value */
+    char_u	*b_p_path;	/* 'path' local value */
+    int		b_p_ar;		/* 'autoread' local value */
+    char_u	*b_p_tags;	/* 'tags' local value */
+#ifdef FEAT_INS_EXPAND
+    char_u	*b_p_dict;	/* 'dictionary' local value */
+    char_u	*b_p_tsr;	/* 'thesaurus' local value */
+#endif
+
+    /* end of buffer options */
+
+    int		b_start_eol;	/* last line had eol when it was read */
+    int		b_start_ffc;	/* first char of 'ff' when edit started */
+#ifdef FEAT_MBYTE
+    char_u	*b_start_fenc;	/* 'fileencoding' when edit started or NULL */
+    int		b_bad_char;	/* "++bad=" argument when edit started or 0 */
+#endif
+
+#ifdef FEAT_EVAL
+    dictitem_T	b_bufvar;	/* variable for "b:" Dictionary */
+    dict_T	b_vars;		/* internal variables, local to buffer */
+#endif
+
+#if defined(FEAT_BEVAL) && defined(FEAT_EVAL)
+    char_u	*b_p_bexpr;	/* 'balloonexpr' local value */
+    long_u	b_p_bexpr_flags;/* flags for 'balloonexpr' */
+#endif
+
+    /* When a buffer is created, it starts without a swap file.  b_may_swap is
+     * then set to indicate that a swap file may be opened later.  It is reset
+     * if a swap file could not be opened.
+     */
+    int		b_may_swap;
+    int		b_did_warn;	/* Set to 1 if user has been warned on first
+				   change of a read-only file */
+
+    /* Two special kinds of buffers:
+     * help buffer  - used for help files, won't use a swap file.
+     * spell buffer - used for spell info, never displayed and doesn't have a
+     *		      file name.
+     */
+    int		b_help;		/* TRUE for help file buffer (when set b_p_bt
+				   is "help") */
+#ifdef FEAT_SPELL
+    int		b_spell;	/* TRUE for a spell file buffer, most fields
+				   are not used!  Use the B_SPELL macro to
+				   access b_spell without #ifdef. */
+#endif
+
+#ifndef SHORT_FNAME
+    int		b_shortname;	/* this file has an 8.3 file name */
+#endif
+
+#ifdef FEAT_MZSCHEME
+    void	*b_mzscheme_ref; /* The MzScheme reference to this buffer */
+#endif
+
+#ifdef FEAT_PERL
+    void	*b_perl_private;
+#endif
+
+#ifdef FEAT_PYTHON
+    void	*b_python_ref;	/* The Python reference to this buffer */
+#endif
+
+#ifdef FEAT_TCL
+    void	*b_tcl_ref;
+#endif
+
+#ifdef FEAT_RUBY
+    void	*b_ruby_ref;
+#endif
+
+#ifdef FEAT_SYN_HL
+    hashtab_T	b_keywtab;		/* syntax keywords hash table */
+    hashtab_T	b_keywtab_ic;		/* idem, ignore case */
+    int		b_syn_error;		/* TRUE when error occured in HL */
+    int		b_syn_ic;		/* ignore case for :syn cmds */
+    int		b_syn_spell;		/* SYNSPL_ values */
+    garray_T	b_syn_patterns;		/* table for syntax patterns */
+    garray_T	b_syn_clusters;		/* table for syntax clusters */
+    int		b_spell_cluster_id;	/* @Spell cluster ID or 0 */
+    int		b_nospell_cluster_id;	/* @NoSpell cluster ID or 0 */
+    int		b_syn_containedin;	/* TRUE when there is an item with a
+					   "containedin" argument */
+    int		b_syn_sync_flags;	/* flags about how to sync */
+    short	b_syn_sync_id;		/* group to sync on */
+    long	b_syn_sync_minlines;	/* minimal sync lines offset */
+    long	b_syn_sync_maxlines;	/* maximal sync lines offset */
+    long	b_syn_sync_linebreaks;	/* offset for multi-line pattern */
+    char_u	*b_syn_linecont_pat;	/* line continuation pattern */
+    regprog_T	*b_syn_linecont_prog;	/* line continuation program */
+    int		b_syn_linecont_ic;	/* ignore-case flag for above */
+    int		b_syn_topgrp;		/* for ":syntax include" */
+# ifdef FEAT_FOLDING
+    int		b_syn_folditems;	/* number of patterns with the HL_FOLD
+					   flag set */
+# endif
+/*
+ * b_sst_array[] contains the state stack for a number of lines, for the start
+ * of that line (col == 0).  This avoids having to recompute the syntax state
+ * too often.
+ * b_sst_array[] is allocated to hold the state for all displayed lines, and
+ * states for 1 out of about 20 other lines.
+ * b_sst_array		pointer to an array of synstate_T
+ * b_sst_len		number of entries in b_sst_array[]
+ * b_sst_first		pointer to first used entry in b_sst_array[] or NULL
+ * b_sst_firstfree	pointer to first free entry in b_sst_array[] or NULL
+ * b_sst_freecount	number of free entries in b_sst_array[]
+ * b_sst_check_lnum	entries after this lnum need to be checked for
+ *			validity (MAXLNUM means no check needed)
+ */
+    synstate_T	*b_sst_array;
+    int		b_sst_len;
+    synstate_T	*b_sst_first;
+    synstate_T	*b_sst_firstfree;
+    int		b_sst_freecount;
+    linenr_T	b_sst_check_lnum;
+    short_u	b_sst_lasttick;	/* last display tick */
+#endif /* FEAT_SYN_HL */
+
+#ifdef FEAT_SPELL
+    /* for spell checking */
+    garray_T	b_langp;	/* list of pointers to slang_T, see spell.c */
+    char_u	b_spell_ismw[256];/* flags: is midword char */
+# ifdef FEAT_MBYTE
+    char_u	*b_spell_ismw_mb; /* multi-byte midword chars */
+# endif
+#endif
+
+#ifdef FEAT_SIGNS
+    signlist_T	*b_signlist;	/* list of signs to draw */
+#endif
+
+#ifdef FEAT_NETBEANS_INTG
+    int		b_netbeans_file;    /* TRUE when buffer is owned by NetBeans */
+    int		b_was_netbeans_file;/* TRUE if b_netbeans_file was once set */
+#endif
+
+};
+
+
+#ifdef FEAT_DIFF
+/*
+ * Stuff for diff mode.
+ */
+# define DB_COUNT 4	/* up to four buffers can be diff'ed */
+
+/*
+ * Each diffblock defines where a block of lines starts in each of the buffers
+ * and how many lines it occupies in that buffer.  When the lines are missing
+ * in the buffer the df_count[] is zero.  This is all counted in
+ * buffer lines.
+ * There is always at least one unchanged line in between the diffs.
+ * Otherwise it would have been included in the diff above or below it.
+ * df_lnum[] + df_count[] is the lnum below the change.  When in one buffer
+ * lines have been inserted, in the other buffer df_lnum[] is the line below
+ * the insertion and df_count[] is zero.  When appending lines at the end of
+ * the buffer, df_lnum[] is one beyond the end!
+ * This is using a linked list, because the number of differences is expected
+ * to be reasonable small.  The list is sorted on lnum.
+ */
+typedef struct diffblock_S diff_T;
+struct diffblock_S
+{
+    diff_T	*df_next;
+    linenr_T	df_lnum[DB_COUNT];	/* line number in buffer */
+    linenr_T	df_count[DB_COUNT];	/* nr of inserted/changed lines */
+};
+#endif
+
+/*
+ * Tab pages point to the top frame of each tab page.
+ * Note: Most values are NOT valid for the current tab page!  Use "curwin",
+ * "firstwin", etc. for that.  "tp_topframe" is always valid and can be
+ * compared against "topframe" to find the current tab page.
+ */
+typedef struct tabpage_S tabpage_T;
+struct tabpage_S
+{
+    tabpage_T	    *tp_next;	    /* next tabpage or NULL */
+    frame_T	    *tp_topframe;   /* topframe for the windows */
+    win_T	    *tp_curwin;	    /* current window in this Tab page */
+    win_T	    *tp_prevwin;    /* previous window in this Tab page */
+    win_T	    *tp_firstwin;   /* first window in this Tab page */
+    win_T	    *tp_lastwin;    /* last window in this Tab page */
+    long	    tp_old_Rows;    /* Rows when Tab page was left */
+    long	    tp_old_Columns; /* Columns when Tab page was left */
+    long	    tp_ch_used;	    /* value of 'cmdheight' when frame size
+				       was set */
+#ifdef FEAT_GUI
+    int		    tp_prev_which_scrollbars[3];
+				    /* previous value of which_scrollbars */
+#endif
+#ifdef FEAT_DIFF
+    diff_T	    *tp_first_diff;
+    buf_T	    *(tp_diffbuf[DB_COUNT]);
+    int		    tp_diff_invalid;	/* list of diffs is outdated */
+#endif
+    frame_T	    *tp_snapshot;    /* window layout snapshot */
+#ifdef FEAT_EVAL
+    dictitem_T	    tp_winvar;	    /* variable for "t:" Dictionary */
+    dict_T	    tp_vars;	    /* internal variables, local to tab page */
+#endif
+};
+
+/*
+ * Structure to cache info for displayed lines in w_lines[].
+ * Each logical line has one entry.
+ * The entry tells how the logical line is currently displayed in the window.
+ * This is updated when displaying the window.
+ * When the display is changed (e.g., when clearing the screen) w_lines_valid
+ * is changed to exclude invalid entries.
+ * When making changes to the buffer, wl_valid is reset to indicate wl_size
+ * may not reflect what is actually in the buffer.  When wl_valid is FALSE,
+ * the entries can only be used to count the number of displayed lines used.
+ * wl_lnum and wl_lastlnum are invalid too.
+ */
+typedef struct w_line
+{
+    linenr_T	wl_lnum;	/* buffer line number for logical line */
+    short_u	wl_size;	/* height in screen lines */
+    char	wl_valid;	/* TRUE values are valid for text in buffer */
+#ifdef FEAT_FOLDING
+    char	wl_folded;	/* TRUE when this is a range of folded lines */
+    linenr_T	wl_lastlnum;	/* last buffer line number for logical line */
+#endif
+} wline_T;
+
+/*
+ * Windows are kept in a tree of frames.  Each frame has a column (FR_COL)
+ * or row (FR_ROW) layout or is a leaf, which has a window.
+ */
+struct frame_S
+{
+    char	fr_layout;	/* FR_LEAF, FR_COL or FR_ROW */
+#ifdef FEAT_VERTSPLIT
+    int		fr_width;
+    int		fr_newwidth;	/* new width used in win_equal_rec() */
+#endif
+    int		fr_height;
+    int		fr_newheight;	/* new height used in win_equal_rec() */
+    frame_T	*fr_parent;	/* containing frame or NULL */
+    frame_T	*fr_next;	/* frame right or below in same parent, NULL
+				   for first */
+    frame_T	*fr_prev;	/* frame left or above in same parent, NULL
+				   for last */
+    /* fr_child and fr_win are mutually exclusive */
+    frame_T	*fr_child;	/* first contained frame */
+    win_T	*fr_win;	/* window that fills this frame */
+};
+
+#define FR_LEAF	0	/* frame is a leaf */
+#define FR_ROW	1	/* frame with a row of windows */
+#define FR_COL	2	/* frame with a column of windows */
+
+/*
+ * Structure which contains all information that belongs to a window
+ *
+ * All row numbers are relative to the start of the window, except w_winrow.
+ */
+struct window_S
+{
+    buf_T	*w_buffer;	    /* buffer we are a window into (used
+				       often, keep it the first item!) */
+
+#ifdef FEAT_WINDOWS
+    win_T	*w_prev;	    /* link to previous window */
+    win_T	*w_next;	    /* link to next window */
+#endif
+
+    frame_T	*w_frame;	    /* frame containing this window */
+
+    pos_T	w_cursor;	    /* cursor position in buffer */
+
+    colnr_T	w_curswant;	    /* The column we'd like to be at.  This is
+				       used to try to stay in the same column
+				       for up/down cursor motions. */
+
+    int		w_set_curswant;	    /* If set, then update w_curswant the next
+				       time through cursupdate() to the
+				       current virtual column */
+
+#ifdef FEAT_VISUAL
+    /*
+     * the next six are used to update the visual part
+     */
+    char	w_old_visual_mode;  /* last known VIsual_mode */
+    linenr_T	w_old_cursor_lnum;  /* last known end of visual part */
+    colnr_T	w_old_cursor_fcol;  /* first column for block visual part */
+    colnr_T	w_old_cursor_lcol;  /* last column for block visual part */
+    linenr_T	w_old_visual_lnum;  /* last known start of visual part */
+    colnr_T	w_old_visual_col;   /* last known start of visual part */
+    colnr_T	w_old_curswant;	    /* last known value of Curswant */
+#endif
+
+    /*
+     * The next three specify the offsets for displaying the buffer:
+     */
+    linenr_T	w_topline;	    /* buffer line number of the line at the
+				       top of the window */
+#ifdef FEAT_DIFF
+    int		w_topfill;	    /* number of filler lines above w_topline */
+    int		w_old_topfill;	    /* w_topfill at last redraw */
+    int		w_botfill;	    /* TRUE when filler lines are actually
+				       below w_topline (at end of file) */
+    int		w_old_botfill;	    /* w_botfill at last redraw */
+#endif
+    colnr_T	w_leftcol;	    /* window column number of the left most
+				       character in the window; used when
+				       'wrap' is off */
+    colnr_T	w_skipcol;	    /* starting column when a single line
+				       doesn't fit in the window */
+
+    /*
+     * Layout of the window in the screen.
+     * May need to add "msg_scrolled" to "w_winrow" in rare situations.
+     */
+#ifdef FEAT_WINDOWS
+    int		w_winrow;	    /* first row of window in screen */
+#endif
+    int		w_height;	    /* number of rows in window, excluding
+				       status/command line(s) */
+#ifdef FEAT_WINDOWS
+    int		w_status_height;    /* number of status lines (0 or 1) */
+#endif
+#ifdef FEAT_VERTSPLIT
+    int		w_wincol;	    /* Leftmost column of window in screen.
+				       use W_WINCOL() */
+    int		w_width;	    /* Width of window, excluding separation.
+				       use W_WIDTH() */
+    int		w_vsep_width;	    /* Number of separator columns (0 or 1).
+				       use W_VSEP_WIDTH() */
+#endif
+
+    /*
+     * === start of cached values ====
+     */
+    /*
+     * Recomputing is minimized by storing the result of computations.
+     * Use functions in screen.c to check if they are valid and to update.
+     * w_valid is a bitfield of flags, which indicate if specific values are
+     * valid or need to be recomputed.	See screen.c for values.
+     */
+    int		w_valid;
+    pos_T	w_valid_cursor;	    /* last known position of w_cursor, used
+				       to adjust w_valid */
+    colnr_T	w_valid_leftcol;    /* last known w_leftcol */
+
+    /*
+     * w_cline_height is the number of physical lines taken by the buffer line
+     * that the cursor is on.  We use this to avoid extra calls to plines().
+     */
+    int		w_cline_height;	    /* current size of cursor line */
+#ifdef FEAT_FOLDING
+    int		w_cline_folded;	    /* cursor line is folded */
+#endif
+
+    int		w_cline_row;	    /* starting row of the cursor line */
+
+    colnr_T	w_virtcol;	    /* column number of the cursor in the
+				       buffer line, as opposed to the column
+				       number we're at on the screen.  This
+				       makes a difference on lines which span
+				       more than one screen line or when
+				       w_leftcol is non-zero */
+
+    /*
+     * w_wrow and w_wcol specify the cursor position in the window.
+     * This is related to positions in the window, not in the display or
+     * buffer, thus w_wrow is relative to w_winrow.
+     */
+    int		w_wrow, w_wcol;	    /* cursor position in window */
+
+    linenr_T	w_botline;	    /* number of the line below the bottom of
+				       the screen */
+    int		w_empty_rows;	    /* number of ~ rows in window */
+#ifdef FEAT_DIFF
+    int		w_filler_rows;	    /* number of filler rows at the end of the
+				       window */
+#endif
+
+    /*
+     * Info about the lines currently in the window is remembered to avoid
+     * recomputing it every time.  The allocated size of w_lines[] is Rows.
+     * Only the w_lines_valid entries are actually valid.
+     * When the display is up-to-date w_lines[0].wl_lnum is equal to w_topline
+     * and w_lines[w_lines_valid - 1].wl_lnum is equal to w_botline.
+     * Between changing text and updating the display w_lines[] represents
+     * what is currently displayed.  wl_valid is reset to indicated this.
+     * This is used for efficient redrawing.
+     */
+    int		w_lines_valid;	    /* number of valid entries */
+    wline_T	*w_lines;
+
+#ifdef FEAT_FOLDING
+    garray_T	w_folds;	    /* array of nested folds */
+    char	w_fold_manual;	    /* when TRUE: some folds are opened/closed
+				       manually */
+    char	w_foldinvalid;	    /* when TRUE: folding needs to be
+				       recomputed */
+#endif
+#ifdef FEAT_LINEBREAK
+    int		w_nrwidth;	    /* width of 'number' column being used */
+#endif
+
+    /*
+     * === end of cached values ===
+     */
+
+    int		w_redr_type;	    /* type of redraw to be performed on win */
+    int		w_upd_rows;	    /* number of window lines to update when
+				       w_redr_type is REDRAW_TOP */
+    linenr_T	w_redraw_top;	    /* when != 0: first line needing redraw */
+    linenr_T	w_redraw_bot;	    /* when != 0: last line needing redraw */
+#ifdef FEAT_WINDOWS
+    int		w_redr_status;	    /* if TRUE status line must be redrawn */
+#endif
+
+#ifdef FEAT_CMDL_INFO
+    /* remember what is shown in the ruler for this window (if 'ruler' set) */
+    pos_T	w_ru_cursor;	    /* cursor position shown in ruler */
+    colnr_T	w_ru_virtcol;	    /* virtcol shown in ruler */
+    linenr_T	w_ru_topline;	    /* topline shown in ruler */
+    linenr_T	w_ru_line_count;    /* line count used for ruler */
+# ifdef FEAT_DIFF
+    int		w_ru_topfill;	    /* topfill shown in ruler */
+# endif
+    char	w_ru_empty;	    /* TRUE if ruler shows 0-1 (empty line) */
+#endif
+
+    int		w_alt_fnum;	    /* alternate file (for # and CTRL-^) */
+
+#ifdef FEAT_WINDOWS
+    alist_T	*w_alist;	    /* pointer to arglist for this window */
+#endif
+    int		w_arg_idx;	    /* current index in argument list (can be
+				       out of range!) */
+    int		w_arg_idx_invalid;  /* editing another file than w_arg_idx */
+
+    char_u	*w_localdir;	    /* absolute path of local directory or
+				       NULL */
+    /*
+     * Options local to a window.
+     * They are local because they influence the layout of the window or
+     * depend on the window layout.
+     * There are two values: w_onebuf_opt is local to the buffer currently in
+     * this window, w_allbuf_opt is for all buffers in this window.
+     */
+    winopt_T	w_onebuf_opt;
+    winopt_T	w_allbuf_opt;
+
+    /* A few options have local flags for P_INSECURE. */
+#ifdef FEAT_STL_OPT
+    long_u	w_p_stl_flags;	    /* flags for 'statusline' */
+#endif
+#ifdef FEAT_EVAL
+    long_u	w_p_fde_flags;	    /* flags for 'foldexpr' */
+    long_u	w_p_fdt_flags;	    /* flags for 'foldtext' */
+#endif
+
+    /* transform a pointer to a "onebuf" option into a "allbuf" option */
+#define GLOBAL_WO(p)	((char *)p + sizeof(winopt_T))
+
+#ifdef FEAT_SCROLLBIND
+    long	w_scbind_pos;
+#endif
+
+#ifdef FEAT_EVAL
+    dictitem_T	w_winvar;	/* variable for "w:" Dictionary */
+    dict_T	w_vars;		/* internal variables, local to window */
+#endif
+
+#if defined(FEAT_RIGHTLEFT) && defined(FEAT_FKMAP)
+    int		w_farsi;	/* for the window dependent Farsi functions */
+#endif
+
+    /*
+     * The w_prev_pcmark field is used to check whether we really did jump to
+     * a new line after setting the w_pcmark.  If not, then we revert to
+     * using the previous w_pcmark.
+     */
+    pos_T	w_pcmark;	/* previous context mark */
+    pos_T	w_prev_pcmark;	/* previous w_pcmark */
+
+#ifdef FEAT_JUMPLIST
+    /*
+     * the jumplist contains old cursor positions
+     */
+    xfmark_T	w_jumplist[JUMPLISTSIZE];
+    int		w_jumplistlen;		/* number of active entries */
+    int		w_jumplistidx;		/* current position */
+
+    int		w_changelistidx;	/* current position in b_changelist */
+#endif
+
+#ifdef FEAT_SEARCH_EXTRA
+    regmmatch_T	w_match[3];	    /* regexp programs for ":match" */
+    char_u	*(w_match_pat[3]);  /* patterns for ":match" */
+    int		w_match_id[3];	    /* highlight IDs for ":match" */
+#endif
+
+    /*
+     * the tagstack grows from 0 upwards:
+     * entry 0: older
+     * entry 1: newer
+     * entry 2: newest
+     */
+    taggy_T	w_tagstack[TAGSTACKSIZE];	/* the tag stack */
+    int		w_tagstackidx;		/* idx just below active entry */
+    int		w_tagstacklen;		/* number of tags on stack */
+
+    /*
+     * w_fraction is the fractional row of the cursor within the window, from
+     * 0 at the top row to FRACTION_MULT at the last row.
+     * w_prev_fraction_row was the actual cursor row when w_fraction was last
+     * calculated.
+     */
+    int		w_fraction;
+    int		w_prev_fraction_row;
+
+#ifdef FEAT_GUI
+    scrollbar_T	w_scrollbars[2];	/* vert. Scrollbars for this window */
+#endif
+#ifdef FEAT_LINEBREAK
+    linenr_T	w_nrwidth_line_count;	/* line count when ml_nrwidth_width
+					 * was computed. */
+    int		w_nrwidth_width;	/* nr of chars to print line count. */
+#endif
+
+#ifdef FEAT_QUICKFIX
+    qf_info_T	*w_llist;		/* Location list for this window */
+    /*
+     * Location list reference used in the location list window.
+     * In a non-location list window, w_llist_ref is NULL.
+     */
+    qf_info_T	*w_llist_ref;
+#endif
+
+
+#ifdef FEAT_MZSCHEME
+    void	*w_mzscheme_ref;	/* The MzScheme value for this window */
+#endif
+
+#ifdef FEAT_PERL
+    void	*w_perl_private;
+#endif
+
+#ifdef FEAT_PYTHON
+    void	*w_python_ref;		/* The Python value for this window */
+#endif
+
+#ifdef FEAT_TCL
+    void	*w_tcl_ref;
+#endif
+
+#ifdef FEAT_RUBY
+    void	*w_ruby_ref;
+#endif
+};
+
+/*
+ * Arguments for operators.
+ */
+typedef struct oparg_S
+{
+    int		op_type;	/* current pending operator type */
+    int		regname;	/* register to use for the operator */
+    int		motion_type;	/* type of the current cursor motion */
+    int		motion_force;	/* force motion type: 'v', 'V' or CTRL-V */
+    int		use_reg_one;	/* TRUE if delete uses reg 1 even when not
+				   linewise */
+    int		inclusive;	/* TRUE if char motion is inclusive (only
+				   valid when motion_type is MCHAR */
+    int		end_adjusted;	/* backuped b_op_end one char (only used by
+				   do_format()) */
+    pos_T	start;		/* start of the operator */
+    pos_T	end;		/* end of the operator */
+    pos_T	cursor_start;	/* cursor position before motion for "gw" */
+
+    long	line_count;	/* number of lines from op_start to op_end
+				   (inclusive) */
+    int		empty;		/* op_start and op_end the same (only used by
+				   do_change()) */
+#ifdef FEAT_VISUAL
+    int		is_VIsual;	/* operator on Visual area */
+    int		block_mode;	/* current operator is Visual block mode */
+#endif
+    colnr_T	start_vcol;	/* start col for block mode operator */
+    colnr_T	end_vcol;	/* end col for block mode operator */
+} oparg_T;
+
+/*
+ * Arguments for Normal mode commands.
+ */
+typedef struct cmdarg_S
+{
+    oparg_T	*oap;		/* Operator arguments */
+    int		prechar;	/* prefix character (optional, always 'g') */
+    int		cmdchar;	/* command character */
+    int		nchar;		/* next command character (optional) */
+#ifdef FEAT_MBYTE
+    int		ncharC1;	/* first composing character (optional) */
+    int		ncharC2;	/* second composing character (optional) */
+#endif
+    int		extra_char;	/* yet another character (optional) */
+    long	opcount;	/* count before an operator */
+    long	count0;		/* count before command, default 0 */
+    long	count1;		/* count before command, default 1 */
+    int		arg;		/* extra argument from nv_cmds[] */
+    int		retval;		/* return: CA_* values */
+    char_u	*searchbuf;	/* return: pointer to search pattern or NULL */
+} cmdarg_T;
+
+/* values for retval: */
+#define CA_COMMAND_BUSY	    1	/* skip restarting edit() once */
+#define CA_NO_ADJ_OP_END    2	/* don't adjust operator end */
+
+#ifdef CURSOR_SHAPE
+/*
+ * struct to store values from 'guicursor' and 'mouseshape'
+ */
+/* Indexes in shape_table[] */
+#define SHAPE_IDX_N	0	/* Normal mode */
+#define SHAPE_IDX_V	1	/* Visual mode */
+#define SHAPE_IDX_I	2	/* Insert mode */
+#define SHAPE_IDX_R	3	/* Replace mode */
+#define SHAPE_IDX_C	4	/* Command line Normal mode */
+#define SHAPE_IDX_CI	5	/* Command line Insert mode */
+#define SHAPE_IDX_CR	6	/* Command line Replace mode */
+#define SHAPE_IDX_O	7	/* Operator-pending mode */
+#define SHAPE_IDX_VE	8	/* Visual mode with 'seleciton' exclusive */
+#define SHAPE_IDX_CLINE	9	/* On command line */
+#define SHAPE_IDX_STATUS 10	/* A status line */
+#define SHAPE_IDX_SDRAG 11	/* dragging a status line */
+#define SHAPE_IDX_VSEP	12	/* A vertical separator line */
+#define SHAPE_IDX_VDRAG 13	/* dragging a vertical separator line */
+#define SHAPE_IDX_MORE	14	/* Hit-return or More */
+#define SHAPE_IDX_MOREL	15	/* Hit-return or More in last line */
+#define SHAPE_IDX_SM	16	/* showing matching paren */
+#define SHAPE_IDX_COUNT	17
+
+#define SHAPE_BLOCK	0	/* block cursor */
+#define SHAPE_HOR	1	/* horizontal bar cursor */
+#define SHAPE_VER	2	/* vertical bar cursor */
+
+#define MSHAPE_NUMBERED	1000	/* offset for shapes identified by number */
+#define MSHAPE_HIDE	1	/* hide mouse pointer */
+
+#define SHAPE_MOUSE	1	/* used for mouse pointer shape */
+#define SHAPE_CURSOR	2	/* used for text cursor shape */
+
+typedef struct cursor_entry
+{
+    int		shape;		/* one of the SHAPE_ defines */
+    int		mshape;		/* one of the MSHAPE defines */
+    int		percentage;	/* percentage of cell for bar */
+    long	blinkwait;	/* blinking, wait time before blinking starts */
+    long	blinkon;	/* blinking, on time */
+    long	blinkoff;	/* blinking, off time */
+    int		id;		/* highlight group ID */
+    int		id_lm;		/* highlight group ID for :lmap mode */
+    char	*name;		/* mode name (fixed) */
+    char	used_for;	/* SHAPE_MOUSE and/or SHAPE_CURSOR */
+} cursorentry_T;
+#endif /* CURSOR_SHAPE */
+
+#ifdef FEAT_MENU
+
+/* Indices into vimmenu_T->strings[] and vimmenu_T->noremap[] for each mode */
+#define MENU_INDEX_INVALID	-1
+#define MENU_INDEX_NORMAL	0
+#define MENU_INDEX_VISUAL	1
+#define MENU_INDEX_SELECT	2
+#define MENU_INDEX_OP_PENDING	3
+#define MENU_INDEX_INSERT	4
+#define MENU_INDEX_CMDLINE	5
+#define MENU_INDEX_TIP		6
+#define MENU_MODES		7
+
+/* Menu modes */
+#define MENU_NORMAL_MODE	(1 << MENU_INDEX_NORMAL)
+#define MENU_VISUAL_MODE	(1 << MENU_INDEX_VISUAL)
+#define MENU_SELECT_MODE	(1 << MENU_INDEX_SELECT)
+#define MENU_OP_PENDING_MODE	(1 << MENU_INDEX_OP_PENDING)
+#define MENU_INSERT_MODE	(1 << MENU_INDEX_INSERT)
+#define MENU_CMDLINE_MODE	(1 << MENU_INDEX_CMDLINE)
+#define MENU_TIP_MODE		(1 << MENU_INDEX_TIP)
+#define MENU_ALL_MODES		((1 << MENU_INDEX_TIP) - 1)
+/*note MENU_INDEX_TIP is not a 'real' mode*/
+
+/* Start a menu name with this to not include it on the main menu bar */
+#define MNU_HIDDEN_CHAR		']'
+
+typedef struct VimMenu vimmenu_T;
+
+struct VimMenu
+{
+    int		modes;		    /* Which modes is this menu visible for? */
+    int		enabled;	    /* for which modes the menu is enabled */
+    char_u	*name;		    /* Name of menu */
+    char_u	*dname;		    /* Displayed Name (without '&') */
+    int		mnemonic;	    /* mnemonic key (after '&') */
+    char_u	*actext;	    /* accelerator text (after TAB) */
+    int		priority;	    /* Menu order priority */
+#ifdef FEAT_GUI
+    void	(*cb) __ARGS((vimmenu_T *));	    /* Call-back routine */
+#endif
+#ifdef FEAT_TOOLBAR
+    char_u	*iconfile;	    /* name of file for icon or NULL */
+    int		iconidx;	    /* icon index (-1 if not set) */
+    int		icon_builtin;	    /* icon names is BuiltIn{nr} */
+#endif
+    char_u	*strings[MENU_MODES]; /* Mapped string for each mode */
+    int		noremap[MENU_MODES]; /* A REMAP_ flag for each mode */
+    char	silent[MENU_MODES]; /* A silent flag for each mode */
+    vimmenu_T	*children;	    /* Children of sub-menu */
+    vimmenu_T	*parent;	    /* Parent of menu */
+    vimmenu_T	*next;		    /* Next item in menu */
+#ifdef FEAT_GUI_X11
+    Widget	id;		    /* Manage this to enable item */
+    Widget	submenu_id;	    /* If this is submenu, add children here */
+#endif
+#ifdef FEAT_GUI_GTK
+    GtkWidget	*id;		    /* Manage this to enable item */
+    GtkWidget	*submenu_id;	    /* If this is submenu, add children here */
+    GtkWidget	*tearoff_handle;
+    GtkWidget   *label;		    /* Used by "set wak=" code. */
+#endif
+#ifdef FEAT_GUI_MOTIF
+    int		sensitive;	    /* turn button on/off */
+    char	**xpm;		    /* pixmap data */
+    char	*xpm_fname;	    /* file with pixmap data */
+#endif
+#ifdef FEAT_GUI_ATHENA
+    Pixmap	image;		    /* Toolbar image */
+#endif
+#ifdef FEAT_BEVAL_TIP
+    BalloonEval *tip;		    /* tooltip for this menu item */
+#endif
+#ifdef FEAT_GUI_W16
+    UINT	id;		    /* Id of menu item */
+    HMENU	submenu_id;	    /* If this is submenu, add children here */
+#endif
+#ifdef FEAT_GUI_W32
+    UINT	id;		    /* Id of menu item */
+    HMENU	submenu_id;	    /* If this is submenu, add children here */
+    HWND	tearoff_handle;	    /* hWnd of tearoff if created */
+#endif
+#ifdef FEAT_GUI_MAC
+/*  MenuHandle	id; */
+/*  short	index;	*/	    /* the item index within the father menu */
+    short	menu_id;	    /* the menu id to which this item belong */
+    short	submenu_id;	    /* the menu id of the children (could be
+				       get throught some tricks) */
+    MenuHandle	menu_handle;
+    MenuHandle	submenu_handle;
+#endif
+#ifdef RISCOS
+    int		*id;		    /* Not used, but gui.c needs it */
+    int		greyed_out;	    /* Flag */
+    int		hidden;
+#endif
+#ifdef FEAT_GUI_PHOTON
+    PtWidget_t	*id;
+    PtWidget_t	*submenu_id;
+#endif
+};
+#else
+/* For generating prototypes when FEAT_MENU isn't defined. */
+typedef int vimmenu_T;
+
+#endif /* FEAT_MENU */
+
+/*
+ * Struct to save values in before executing autocommands for a buffer that is
+ * not the current buffer.  Without FEAT_AUTOCMD only "curbuf" is remembered.
+ */
+typedef struct
+{
+    buf_T	*save_buf;	/* saved curbuf */
+#ifdef FEAT_AUTOCMD
+    buf_T	*new_curbuf;	/* buffer to be used */
+    win_T	*save_curwin;	/* saved curwin, NULL if it didn't change */
+    win_T	*new_curwin;	/* new curwin if save_curwin != NULL */
+    pos_T	save_cursor;	/* saved cursor pos of save_curwin */
+    linenr_T	save_topline;	/* saved topline of save_curwin */
+# ifdef FEAT_DIFF
+    int		save_topfill;	/* saved topfill of save_curwin */
+# endif
+#endif
+} aco_save_T;
+
+/*
+ * Generic option table item, only used for printer at the moment.
+ */
+typedef struct
+{
+    const char	*name;
+    int		hasnum;
+    long	number;
+    char_u	*string;	/* points into option string */
+    int		strlen;
+    int		present;
+} option_table_T;
+
+/*
+ * Structure to hold printing color and font attributes.
+ */
+typedef struct
+{
+    long_u	fg_color;
+    long_u	bg_color;
+    int		bold;
+    int		italic;
+    int		underline;
+    int		undercurl;
+} prt_text_attr_T;
+
+/*
+ * Structure passed back to the generic printer code.
+ */
+typedef struct
+{
+    int		n_collated_copies;
+    int		n_uncollated_copies;
+    int		duplex;
+    int		chars_per_line;
+    int		lines_per_page;
+    int		has_color;
+    prt_text_attr_T number;
+#ifdef FEAT_SYN_HL
+    int		modec;
+    int		do_syntax;
+#endif
+    int		user_abort;
+    char_u	*jobname;
+#ifdef FEAT_POSTSCRIPT
+    char_u	*outfile;
+    char_u	*arguments;
+#endif
+} prt_settings_T;
+
+#define PRINT_NUMBER_WIDTH 8
+
+/*
+ * Used for popup menu items.
+ */
+typedef struct
+{
+    char_u	*pum_text;	/* main menu text */
+    char_u	*pum_kind;	/* extra kind text (may be truncated) */
+    char_u	*pum_extra;	/* extra menu text (may be truncated) */
+    char_u	*pum_info;	/* extra info */
+} pumitem_T;
+
+/*
+ * Structure used for get_tagfname().
+ */
+typedef struct
+{
+    char_u	*tn_tags;	/* value of 'tags' when starting */
+    char_u	*tn_np;		/* current position in tn_tags */
+    int		tn_did_filefind_init;
+    int		tn_hf_idx;
+    void	*tn_search_ctx;
+} tagname_T;
+
+/*
+ * Array indexes used for cptext argument of ins_compl_add().
+ */
+#define CPT_ABBR    0	/* "abbr" */
+#define CPT_MENU    1	/* "menu" */
+#define CPT_KIND    2	/* "kind" */
+#define CPT_INFO    3	/* "info" */
+#define CPT_COUNT   4	/* Number of entries */
--- /dev/null
+++ b/syntax.c
@@ -1,0 +1,9106 @@
+/* vi:set ts=8 sts=4 sw=4:
+ *
+ * VIM - Vi IMproved	by Bram Moolenaar
+ *
+ * Do ":help uganda"  in Vim to read copying and usage conditions.
+ * Do ":help credits" in Vim to see a list of people who contributed.
+ * See README.txt for an overview of the Vim source code.
+ */
+
+/*
+ * syntax.c: code for syntax highlighting
+ */
+
+#include "vim.h"
+
+/*
+ * Structure that stores information about a highlight group.
+ * The ID of a highlight group is also called group ID.  It is the index in
+ * the highlight_ga array PLUS ONE.
+ */
+struct hl_group
+{
+    char_u	*sg_name;	/* highlight group name */
+    char_u	*sg_name_u;	/* uppercase of sg_name */
+/* for normal terminals */
+    int		sg_term;	/* "term=" highlighting attributes */
+    char_u	*sg_start;	/* terminal string for start highl */
+    char_u	*sg_stop;	/* terminal string for stop highl */
+    int		sg_term_attr;	/* Screen attr for term mode */
+/* for color terminals */
+    int		sg_cterm;	/* "cterm=" highlighting attr */
+    int		sg_cterm_bold;	/* bold attr was set for light color */
+    int		sg_cterm_fg;	/* terminal fg color number + 1 */
+    int		sg_cterm_bg;	/* terminal bg color number + 1 */
+    int		sg_cterm_attr;	/* Screen attr for color term mode */
+#ifdef FEAT_GUI
+/* for when using the GUI */
+    int		sg_gui;		/* "gui=" highlighting attributes */
+    guicolor_T	sg_gui_fg;	/* GUI foreground color handle */
+    char_u	*sg_gui_fg_name;/* GUI foreground color name */
+    guicolor_T	sg_gui_bg;	/* GUI background color handle */
+    char_u	*sg_gui_bg_name;/* GUI background color name */
+    guicolor_T	sg_gui_sp;	/* GUI special color handle */
+    char_u	*sg_gui_sp_name;/* GUI special color name */
+    GuiFont	sg_font;	/* GUI font handle */
+#ifdef FEAT_XFONTSET
+    GuiFontset	sg_fontset;	/* GUI fontset handle */
+#endif
+    char_u	*sg_font_name;  /* GUI font or fontset name */
+    int		sg_gui_attr;    /* Screen attr for GUI mode */
+#endif
+    int		sg_link;	/* link to this highlight group ID */
+    int		sg_set;		/* combination of SG_* flags */
+#ifdef FEAT_EVAL
+    scid_T	sg_scriptID;	/* script in which the group was last set */
+#endif
+};
+
+#define SG_TERM		1	/* term has been set */
+#define SG_CTERM	2	/* cterm has been set */
+#define SG_GUI		4	/* gui has been set */
+#define SG_LINK		8	/* link has been set */
+
+static garray_T highlight_ga;	/* highlight groups for 'highlight' option */
+
+#define HL_TABLE() ((struct hl_group *)((highlight_ga.ga_data)))
+
+#ifdef FEAT_CMDL_COMPL
+static int include_default = FALSE;	/* include "default" for expansion */
+static int include_link = FALSE;	/* include "link" for expansion */
+#endif
+
+/*
+ * The "term", "cterm" and "gui" arguments can be any combination of the
+ * following names, separated by commas (but no spaces!).
+ */
+static char *(hl_name_table[]) =
+    {"bold", "standout", "underline", "undercurl",
+				      "italic", "reverse", "inverse", "NONE"};
+static int hl_attr_table[] =
+    {HL_BOLD, HL_STANDOUT, HL_UNDERLINE, HL_UNDERCURL, HL_ITALIC, HL_INVERSE, HL_INVERSE, 0};
+
+static int get_attr_entry  __ARGS((garray_T *table, attrentry_T *aep));
+static void syn_unadd_group __ARGS((void));
+static void set_hl_attr __ARGS((int idx));
+static void highlight_list_one __ARGS((int id));
+static int highlight_list_arg __ARGS((int id, int didh, int type, int iarg, char_u *sarg, char *name));
+static int syn_add_group __ARGS((char_u *name));
+static int syn_list_header __ARGS((int did_header, int outlen, int id));
+static int hl_has_settings __ARGS((int idx, int check_link));
+static void highlight_clear __ARGS((int idx));
+
+#ifdef FEAT_GUI
+static void gui_do_one_color __ARGS((int idx, int do_menu, int do_tooltip));
+static int  set_group_colors __ARGS((char_u *name, guicolor_T *fgp, guicolor_T *bgp, int do_menu, int use_norm, int do_tooltip));
+static guicolor_T color_name2handle __ARGS((char_u *name));
+static GuiFont font_name2handle __ARGS((char_u *name));
+# ifdef FEAT_XFONTSET
+static GuiFontset fontset_name2handle __ARGS((char_u *name, int fixed_width));
+# endif
+static void hl_do_font __ARGS((int idx, char_u *arg, int do_normal, int do_menu, int do_tooltip));
+#endif
+
+/*
+ * An attribute number is the index in attr_table plus ATTR_OFF.
+ */
+#define ATTR_OFF (HL_ALL + 1)
+
+#if defined(FEAT_SYN_HL) || defined(PROTO)
+
+#define SYN_NAMELEN	50		/* maximum length of a syntax name */
+
+/* different types of offsets that are possible */
+#define SPO_MS_OFF	0	/* match  start offset */
+#define SPO_ME_OFF	1	/* match  end	offset */
+#define SPO_HS_OFF	2	/* highl. start offset */
+#define SPO_HE_OFF	3	/* highl. end	offset */
+#define SPO_RS_OFF	4	/* region start offset */
+#define SPO_RE_OFF	5	/* region end	offset */
+#define SPO_LC_OFF	6	/* leading context offset */
+#define SPO_COUNT	7
+
+static char *(spo_name_tab[SPO_COUNT]) =
+	    {"ms=", "me=", "hs=", "he=", "rs=", "re=", "lc="};
+
+/*
+ * The patterns that are being searched for are stored in a syn_pattern.
+ * A match item consists of one pattern.
+ * A start/end item consists of n start patterns and m end patterns.
+ * A start/skip/end item consists of n start patterns, one skip pattern and m
+ * end patterns.
+ * For the latter two, the patterns are always consecutive: start-skip-end.
+ *
+ * A character offset can be given for the matched text (_m_start and _m_end)
+ * and for the actually highlighted text (_h_start and _h_end).
+ */
+typedef struct syn_pattern
+{
+    char	 sp_type;		/* see SPTYPE_ defines below */
+    char	 sp_syncing;		/* this item used for syncing */
+    short	 sp_flags;		/* see HL_ defines below */
+    struct sp_syn sp_syn;		/* struct passed to in_id_list() */
+    short	 sp_syn_match_id;	/* highlight group ID of pattern */
+    char_u	*sp_pattern;		/* regexp to match, pattern */
+    regprog_T	*sp_prog;		/* regexp to match, program */
+    int		 sp_ic;			/* ignore-case flag for sp_prog */
+    short	 sp_off_flags;		/* see below */
+    int		 sp_offsets[SPO_COUNT];	/* offsets */
+    short	*sp_cont_list;		/* cont. group IDs, if non-zero */
+    short	*sp_next_list;		/* next group IDs, if non-zero */
+    int		 sp_sync_idx;		/* sync item index (syncing only) */
+    int		 sp_line_id;		/* ID of last line where tried */
+    int		 sp_startcol;		/* next match in sp_line_id line */
+} synpat_T;
+
+/* The sp_off_flags are computed like this:
+ * offset from the start of the matched text: (1 << SPO_XX_OFF)
+ * offset from the end	 of the matched text: (1 << (SPO_XX_OFF + SPO_COUNT))
+ * When both are present, only one is used.
+ */
+
+#define SPTYPE_MATCH	1	/* match keyword with this group ID */
+#define SPTYPE_START	2	/* match a regexp, start of item */
+#define SPTYPE_END	3	/* match a regexp, end of item */
+#define SPTYPE_SKIP	4	/* match a regexp, skip within item */
+
+#define HL_CONTAINED	0x01	/* not used on toplevel */
+#define HL_TRANSP	0x02	/* has no highlighting	*/
+#define HL_ONELINE	0x04	/* match within one line only */
+#define HL_HAS_EOL	0x08	/* end pattern that matches with $ */
+#define HL_SYNC_HERE	0x10	/* sync point after this item (syncing only) */
+#define HL_SYNC_THERE	0x20	/* sync point at current line (syncing only) */
+#define HL_MATCH	0x40	/* use match ID instead of item ID */
+#define HL_SKIPNL	0x80	/* nextgroup can skip newlines */
+#define HL_SKIPWHITE	0x100	/* nextgroup can skip white space */
+#define HL_SKIPEMPTY	0x200	/* nextgroup can skip empty lines */
+#define HL_KEEPEND	0x400	/* end match always kept */
+#define HL_EXCLUDENL	0x800	/* exclude NL from match */
+#define HL_DISPLAY	0x1000	/* only used for displaying, not syncing */
+#define HL_FOLD		0x2000	/* define fold */
+#define HL_EXTEND	0x4000	/* ignore a keepend */
+/* These don't fit in a short, thus can't be used for syntax items, only for
+ * si_flags and bs_flags. */
+#define HL_MATCHCONT	0x8000	/* match continued from previous line */
+#define HL_TRANS_CONT	0x10000L /* transparent item without contains arg */
+
+#define SYN_ITEMS(buf)	((synpat_T *)((buf)->b_syn_patterns.ga_data))
+
+#define NONE_IDX	-2	/* value of sp_sync_idx for "NONE" */
+
+/*
+ * Flags for b_syn_sync_flags:
+ */
+#define SF_CCOMMENT	0x01	/* sync on a C-style comment */
+#define SF_MATCH	0x02	/* sync by matching a pattern */
+
+#define SYN_STATE_P(ssp)    ((bufstate_T *)((ssp)->ga_data))
+
+#define MAXKEYWLEN	80	    /* maximum length of a keyword */
+
+/*
+ * The attributes of the syntax item that has been recognized.
+ */
+static int current_attr = 0;	    /* attr of current syntax word */
+#ifdef FEAT_EVAL
+static int current_id = 0;	    /* ID of current char for syn_get_id() */
+static int current_trans_id = 0;    /* idem, transparancy removed */
+#endif
+
+typedef struct syn_cluster_S
+{
+    char_u	    *scl_name;	    /* syntax cluster name */
+    char_u	    *scl_name_u;    /* uppercase of scl_name */
+    short	    *scl_list;	    /* IDs in this syntax cluster */
+} syn_cluster_T;
+
+/*
+ * Methods of combining two clusters
+ */
+#define CLUSTER_REPLACE	    1	/* replace first list with second */
+#define CLUSTER_ADD	    2	/* add second list to first */
+#define CLUSTER_SUBTRACT    3	/* subtract second list from first */
+
+#define SYN_CLSTR(buf)	((syn_cluster_T *)((buf)->b_syn_clusters.ga_data))
+
+/*
+ * Syntax group IDs have different types:
+ *     0 -  9999  normal syntax groups
+ * 10000 - 14999  ALLBUT indicator (current_syn_inc_tag added)
+ * 15000 - 19999  TOP indicator (current_syn_inc_tag added)
+ * 20000 - 24999  CONTAINED indicator (current_syn_inc_tag added)
+ * >= 25000	  cluster IDs (subtract SYNID_CLUSTER for the cluster ID)
+ */
+#define SYNID_ALLBUT	10000	    /* syntax group ID for contains=ALLBUT */
+#define SYNID_TOP	15000	    /* syntax group ID for contains=TOP */
+#define SYNID_CONTAINED	20000	    /* syntax group ID for contains=CONTAINED */
+#define SYNID_CLUSTER	25000	    /* first syntax group ID for clusters */
+
+/*
+ * Annoying Hack(TM):  ":syn include" needs this pointer to pass to
+ * expand_filename().  Most of the other syntax commands don't need it, so
+ * instead of passing it to them, we stow it here.
+ */
+static char_u **syn_cmdlinep;
+
+/*
+ * Another Annoying Hack(TM):  To prevent rules from other ":syn include"'d
+ * files from from leaking into ALLBUT lists, we assign a unique ID to the
+ * rules in each ":syn include"'d file.
+ */
+static int current_syn_inc_tag = 0;
+static int running_syn_inc_tag = 0;
+
+/*
+ * In a hashtable item "hi_key" points to "keyword" in a keyentry.
+ * This avoids adding a pointer to the hashtable item.
+ * KE2HIKEY() converts a var pointer to a hashitem key pointer.
+ * HIKEY2KE() converts a hashitem key pointer to a var pointer.
+ * HI2KE() converts a hashitem pointer to a var pointer.
+ */
+static keyentry_T dumkey;
+#define KE2HIKEY(kp)  ((kp)->keyword)
+#define HIKEY2KE(p)   ((keyentry_T *)((p) - (dumkey.keyword - (char_u *)&dumkey)))
+#define HI2KE(hi)      HIKEY2KE((hi)->hi_key)
+
+/*
+ * To reduce the time spent in keepend(), remember at which level in the state
+ * stack the first item with "keepend" is present.  When "-1", there is no
+ * "keepend" on the stack.
+ */
+static int keepend_level = -1;
+
+/*
+ * For the current state we need to remember more than just the idx.
+ * When si_m_endpos.lnum is 0, the items other than si_idx are unknown.
+ * (The end positions have the column number of the next char)
+ */
+typedef struct state_item
+{
+    int		si_idx;			/* index of syntax pattern */
+    int		si_id;			/* highlight group ID for keywords */
+    int		si_trans_id;		/* idem, transparancy removed */
+    int		si_m_lnum;		/* lnum of the match */
+    int		si_m_startcol;		/* starting column of the match */
+    lpos_T	si_m_endpos;		/* just after end posn of the match */
+    lpos_T	si_h_startpos;		/* start position of the highlighting */
+    lpos_T	si_h_endpos;		/* end position of the highlighting */
+    lpos_T	si_eoe_pos;		/* end position of end pattern */
+    int		si_end_idx;		/* group ID for end pattern or zero */
+    int		si_ends;		/* if match ends before si_m_endpos */
+    int		si_attr;		/* attributes in this state */
+    long	si_flags;		/* HL_HAS_EOL flag in this state, and
+					 * HL_SKIP* for si_next_list */
+    short	*si_cont_list;		/* list of contained groups */
+    short	*si_next_list;		/* nextgroup IDs after this item ends */
+    reg_extmatch_T *si_extmatch;	/* \z(...\) matches from start
+					 * pattern */
+} stateitem_T;
+
+#define KEYWORD_IDX	-1	    /* value of si_idx for keywords */
+#define ID_LIST_ALL	(short *)-1 /* valid of si_cont_list for containing all
+				       but contained groups */
+
+/*
+ * Struct to reduce the number of arguments to get_syn_options(), it's used
+ * very often.
+ */
+typedef struct
+{
+    int		flags;		/* flags for contained and transparent */
+    int		keyword;	/* TRUE for ":syn keyword" */
+    int		*sync_idx;	/* syntax item for "grouphere" argument, NULL
+				   if not allowed */
+    char	has_cont_list;	/* TRUE if "cont_list" can be used */
+    short	*cont_list;	/* group IDs for "contains" argument */
+    short	*cont_in_list;	/* group IDs for "containedin" argument */
+    short	*next_list;	/* group IDs for "nextgroup" argument */
+} syn_opt_arg_T;
+
+/*
+ * The next possible match in the current line for any pattern is remembered,
+ * to avoid having to try for a match in each column.
+ * If next_match_idx == -1, not tried (in this line) yet.
+ * If next_match_col == MAXCOL, no match found in this line.
+ * (All end positions have the column of the char after the end)
+ */
+static int next_match_col;		/* column for start of next match */
+static lpos_T next_match_m_endpos;	/* position for end of next match */
+static lpos_T next_match_h_startpos;  /* pos. for highl. start of next match */
+static lpos_T next_match_h_endpos;	/* pos. for highl. end of next match */
+static int next_match_idx;		/* index of matched item */
+static long next_match_flags;		/* flags for next match */
+static lpos_T next_match_eos_pos;	/* end of start pattn (start region) */
+static lpos_T next_match_eoe_pos;	/* pos. for end of end pattern */
+static int next_match_end_idx;		/* ID of group for end pattn or zero */
+static reg_extmatch_T *next_match_extmatch = NULL;
+
+/*
+ * A state stack is an array of integers or stateitem_T, stored in a
+ * garray_T.  A state stack is invalid if it's itemsize entry is zero.
+ */
+#define INVALID_STATE(ssp)  ((ssp)->ga_itemsize == 0)
+#define VALID_STATE(ssp)    ((ssp)->ga_itemsize != 0)
+
+/*
+ * The current state (within the line) of the recognition engine.
+ * When current_state.ga_itemsize is 0 the current state is invalid.
+ */
+static win_T	*syn_win;		/* current window for highlighting */
+static buf_T	*syn_buf;		/* current buffer for highlighting */
+static linenr_T current_lnum = 0;	/* lnum of current state */
+static colnr_T	current_col = 0;	/* column of current state */
+static int	current_state_stored = 0; /* TRUE if stored current state
+					   * after setting current_finished */
+static int	current_finished = 0;	/* current line has been finished */
+static garray_T current_state		/* current stack of state_items */
+		= {0, 0, 0, 0, NULL};
+static short	*current_next_list = NULL; /* when non-zero, nextgroup list */
+static int	current_next_flags = 0; /* flags for current_next_list */
+static int	current_line_id = 0;	/* unique number for current line */
+
+#define CUR_STATE(idx)	((stateitem_T *)(current_state.ga_data))[idx]
+
+static void syn_sync __ARGS((win_T *wp, linenr_T lnum, synstate_T *last_valid));
+static int syn_match_linecont __ARGS((linenr_T lnum));
+static void syn_start_line __ARGS((void));
+static void syn_update_ends __ARGS((int startofline));
+static void syn_stack_alloc __ARGS((void));
+static int syn_stack_cleanup __ARGS((void));
+static void syn_stack_free_entry __ARGS((buf_T *buf, synstate_T *p));
+static synstate_T *syn_stack_find_entry __ARGS((linenr_T lnum));
+static synstate_T *store_current_state __ARGS((synstate_T *sp));
+static void load_current_state __ARGS((synstate_T *from));
+static void invalidate_current_state __ARGS((void));
+static int syn_stack_equal __ARGS((synstate_T *sp));
+static void validate_current_state __ARGS((void));
+static int syn_finish_line __ARGS((int syncing));
+static int syn_current_attr __ARGS((int syncing, int displaying, int *can_spell));
+static int did_match_already __ARGS((int idx, garray_T *gap));
+static stateitem_T *push_next_match __ARGS((stateitem_T *cur_si));
+static void check_state_ends __ARGS((void));
+static void update_si_attr __ARGS((int idx));
+static void check_keepend __ARGS((void));
+static void update_si_end __ARGS((stateitem_T *sip, int startcol, int force));
+static short *copy_id_list __ARGS((short *list));
+static int in_id_list __ARGS((stateitem_T *item, short *cont_list, struct sp_syn *ssp, int contained));
+static int push_current_state __ARGS((int idx));
+static void pop_current_state __ARGS((void));
+
+static void find_endpos __ARGS((int idx, lpos_T *startpos, lpos_T *m_endpos, lpos_T *hl_endpos, long *flagsp, lpos_T *end_endpos, int *end_idx, reg_extmatch_T *start_ext));
+static void clear_syn_state __ARGS((synstate_T *p));
+static void clear_current_state __ARGS((void));
+
+static void limit_pos __ARGS((lpos_T *pos, lpos_T *limit));
+static void limit_pos_zero __ARGS((lpos_T *pos, lpos_T *limit));
+static void syn_add_end_off __ARGS((lpos_T *result, regmmatch_T *regmatch, synpat_T *spp, int idx, int extra));
+static void syn_add_start_off __ARGS((lpos_T *result, regmmatch_T *regmatch, synpat_T *spp, int idx, int extra));
+static char_u *syn_getcurline __ARGS((void));
+static int syn_regexec __ARGS((regmmatch_T *rmp, linenr_T lnum, colnr_T col));
+static int check_keyword_id __ARGS((char_u *line, int startcol, int *endcol, long *flags, short **next_list, stateitem_T *cur_si));
+static void syn_cmd_case __ARGS((exarg_T *eap, int syncing));
+static void syn_cmd_spell __ARGS((exarg_T *eap, int syncing));
+static void syntax_sync_clear __ARGS((void));
+static void syn_remove_pattern __ARGS((buf_T *buf, int idx));
+static void syn_clear_pattern __ARGS((buf_T *buf, int i));
+static void syn_clear_cluster __ARGS((buf_T *buf, int i));
+static void syn_cmd_clear __ARGS((exarg_T *eap, int syncing));
+static void syn_clear_one __ARGS((int id, int syncing));
+static void syn_cmd_on __ARGS((exarg_T *eap, int syncing));
+static void syn_cmd_enable __ARGS((exarg_T *eap, int syncing));
+static void syn_cmd_reset __ARGS((exarg_T *eap, int syncing));
+static void syn_cmd_manual __ARGS((exarg_T *eap, int syncing));
+static void syn_cmd_off __ARGS((exarg_T *eap, int syncing));
+static void syn_cmd_onoff __ARGS((exarg_T *eap, char *name));
+static void syn_cmd_list __ARGS((exarg_T *eap, int syncing));
+static void syn_lines_msg __ARGS((void));
+static void syn_match_msg __ARGS((void));
+static void syn_list_one __ARGS((int id, int syncing, int link_only));
+static void syn_list_cluster __ARGS((int id));
+static void put_id_list __ARGS((char_u *name, short *list, int attr));
+static void put_pattern __ARGS((char *s, int c, synpat_T *spp, int attr));
+static int syn_list_keywords __ARGS((int id, hashtab_T *ht, int did_header, int attr));
+static void syn_clear_keyword __ARGS((int id, hashtab_T *ht));
+static void clear_keywtab __ARGS((hashtab_T *ht));
+static void add_keyword __ARGS((char_u *name, int id, int flags, short *cont_in_list, short *next_list));
+static char_u *get_group_name __ARGS((char_u *arg, char_u **name_end));
+static char_u *get_syn_options __ARGS((char_u *arg, syn_opt_arg_T *opt));
+static void syn_cmd_include __ARGS((exarg_T *eap, int syncing));
+static void syn_cmd_keyword __ARGS((exarg_T *eap, int syncing));
+static void syn_cmd_match __ARGS((exarg_T *eap, int syncing));
+static void syn_cmd_region __ARGS((exarg_T *eap, int syncing));
+#ifdef __BORLANDC__
+static int _RTLENTRYF syn_compare_stub __ARGS((const void *v1, const void *v2));
+#else
+static int syn_compare_stub __ARGS((const void *v1, const void *v2));
+#endif
+static void syn_cmd_cluster __ARGS((exarg_T *eap, int syncing));
+static int syn_scl_name2id __ARGS((char_u *name));
+static int syn_scl_namen2id __ARGS((char_u *linep, int len));
+static int syn_check_cluster __ARGS((char_u *pp, int len));
+static int syn_add_cluster __ARGS((char_u *name));
+static void init_syn_patterns __ARGS((void));
+static char_u *get_syn_pattern __ARGS((char_u *arg, synpat_T *ci));
+static void syn_cmd_sync __ARGS((exarg_T *eap, int syncing));
+static int get_id_list __ARGS((char_u **arg, int keylen, short **list));
+static void syn_combine_list __ARGS((short **clstr1, short **clstr2, int list_op));
+static void syn_incl_toplevel __ARGS((int id, int *flagsp));
+
+/*
+ * Start the syntax recognition for a line.  This function is normally called
+ * from the screen updating, once for each displayed line.
+ * The buffer is remembered in syn_buf, because get_syntax_attr() doesn't get
+ * it.	Careful: curbuf and curwin are likely to point to another buffer and
+ * window.
+ */
+    void
+syntax_start(wp, lnum)
+    win_T	*wp;
+    linenr_T	lnum;
+{
+    synstate_T	*p;
+    synstate_T	*last_valid = NULL;
+    synstate_T	*last_min_valid = NULL;
+    synstate_T	*sp, *prev;
+    linenr_T	parsed_lnum;
+    linenr_T	first_stored;
+    int		dist;
+    static int	changedtick = 0;	/* remember the last change ID */
+
+    /*
+     * After switching buffers, invalidate current_state.
+     * Also do this when a change was made, the current state may be invalid
+     * then.
+     */
+    if (syn_buf != wp->w_buffer || changedtick != syn_buf->b_changedtick)
+    {
+	invalidate_current_state();
+	syn_buf = wp->w_buffer;
+    }
+    changedtick = syn_buf->b_changedtick;
+    syn_win = wp;
+
+    /*
+     * Allocate syntax stack when needed.
+     */
+    syn_stack_alloc();
+    if (syn_buf->b_sst_array == NULL)
+	return;		/* out of memory */
+    syn_buf->b_sst_lasttick = display_tick;
+
+    /*
+     * If the state of the end of the previous line is useful, store it.
+     */
+    if (VALID_STATE(&current_state)
+	    && current_lnum < lnum
+	    && current_lnum < syn_buf->b_ml.ml_line_count)
+    {
+	(void)syn_finish_line(FALSE);
+	if (!current_state_stored)
+	{
+	    ++current_lnum;
+	    (void)store_current_state(NULL);
+	}
+
+	/*
+	 * If the current_lnum is now the same as "lnum", keep the current
+	 * state (this happens very often!).  Otherwise invalidate
+	 * current_state and figure it out below.
+	 */
+	if (current_lnum != lnum)
+	    invalidate_current_state();
+    }
+    else
+	invalidate_current_state();
+
+    /*
+     * Try to synchronize from a saved state in b_sst_array[].
+     * Only do this if lnum is not before and not to far beyond a saved state.
+     */
+    if (INVALID_STATE(&current_state) && syn_buf->b_sst_array != NULL)
+    {
+	/* Find last valid saved state before start_lnum. */
+	for (p = syn_buf->b_sst_first; p != NULL; p = p->sst_next)
+	{
+	    if (p->sst_lnum > lnum)
+		break;
+	    if (p->sst_lnum <= lnum && p->sst_change_lnum == 0)
+	    {
+		last_valid = p;
+		if (p->sst_lnum >= lnum - syn_buf->b_syn_sync_minlines)
+		    last_min_valid = p;
+	    }
+	}
+	if (last_min_valid != NULL)
+	    load_current_state(last_min_valid);
+    }
+
+    /*
+     * If "lnum" is before or far beyond a line with a saved state, need to
+     * re-synchronize.
+     */
+    if (INVALID_STATE(&current_state))
+    {
+	syn_sync(wp, lnum, last_valid);
+	first_stored = current_lnum + syn_buf->b_syn_sync_minlines;
+    }
+    else
+	first_stored = current_lnum;
+
+    /*
+     * Advance from the sync point or saved state until the current line.
+     * Save some entries for syncing with later on.
+     */
+    if (syn_buf->b_sst_len <= Rows)
+	dist = 999999;
+    else
+	dist = syn_buf->b_ml.ml_line_count / (syn_buf->b_sst_len - Rows) + 1;
+    prev = syn_stack_find_entry(current_lnum);
+    while (current_lnum < lnum)
+    {
+	syn_start_line();
+	(void)syn_finish_line(FALSE);
+	++current_lnum;
+
+	/* If we parsed at least "minlines" lines or started at a valid
+	 * state, the current state is considered valid. */
+	if (current_lnum >= first_stored)
+	{
+	    /* Check if the saved state entry is for the current line and is
+	     * equal to the current state.  If so, then validate all saved
+	     * states that depended on a change before the parsed line. */
+	    if (prev == NULL)
+		sp = syn_buf->b_sst_first;
+	    else
+		sp = prev->sst_next;
+	    if (sp != NULL
+		    && sp->sst_lnum == current_lnum
+		    && syn_stack_equal(sp))
+	    {
+		parsed_lnum = current_lnum;
+		prev = sp;
+		while (sp != NULL && sp->sst_change_lnum <= parsed_lnum)
+		{
+		    if (sp->sst_lnum <= lnum)
+			/* valid state before desired line, use this one */
+			prev = sp;
+		    else if (sp->sst_change_lnum == 0)
+			/* past saved states depending on change, break here. */
+			break;
+		    sp->sst_change_lnum = 0;
+		    sp = sp->sst_next;
+		}
+		load_current_state(prev);
+	    }
+	    /* Store the state at this line when it's the first one, the line
+	     * where we start parsing, or some distance from the previously
+	     * saved state.  But only when parsed at least 'minlines'. */
+	    else if (prev == NULL
+			|| current_lnum == lnum
+			|| current_lnum >= prev->sst_lnum + dist)
+		prev = store_current_state(prev);
+	}
+
+	/* This can take a long time: break when CTRL-C pressed.  The current
+	 * state will be wrong then. */
+	line_breakcheck();
+	if (got_int)
+	{
+	    current_lnum = lnum;
+	    break;
+	}
+    }
+
+    syn_start_line();
+}
+
+/*
+ * We cannot simply discard growarrays full of state_items or buf_states; we
+ * have to manually release their extmatch pointers first.
+ */
+    static void
+clear_syn_state(p)
+    synstate_T *p;
+{
+    int		i;
+    garray_T	*gap;
+
+    if (p->sst_stacksize > SST_FIX_STATES)
+    {
+	gap = &(p->sst_union.sst_ga);
+	for (i = 0; i < gap->ga_len; i++)
+	    unref_extmatch(SYN_STATE_P(gap)[i].bs_extmatch);
+	ga_clear(gap);
+    }
+    else
+    {
+	for (i = 0; i < p->sst_stacksize; i++)
+	    unref_extmatch(p->sst_union.sst_stack[i].bs_extmatch);
+    }
+}
+
+/*
+ * Cleanup the current_state stack.
+ */
+    static void
+clear_current_state()
+{
+    int		i;
+    stateitem_T	*sip;
+
+    sip = (stateitem_T *)(current_state.ga_data);
+    for (i = 0; i < current_state.ga_len; i++)
+	unref_extmatch(sip[i].si_extmatch);
+    ga_clear(&current_state);
+}
+
+/*
+ * Try to find a synchronisation point for line "lnum".
+ *
+ * This sets current_lnum and the current state.  One of three methods is
+ * used:
+ * 1. Search backwards for the end of a C-comment.
+ * 2. Search backwards for given sync patterns.
+ * 3. Simply start on a given number of lines above "lnum".
+ */
+    static void
+syn_sync(wp, start_lnum, last_valid)
+    win_T	*wp;
+    linenr_T	start_lnum;
+    synstate_T	*last_valid;
+{
+    buf_T	*curbuf_save;
+    win_T	*curwin_save;
+    pos_T	cursor_save;
+    int		idx;
+    linenr_T	lnum;
+    linenr_T	end_lnum;
+    linenr_T	break_lnum;
+    int		had_sync_point;
+    stateitem_T	*cur_si;
+    synpat_T	*spp;
+    char_u	*line;
+    int		found_flags = 0;
+    int		found_match_idx = 0;
+    linenr_T	found_current_lnum = 0;
+    int		found_current_col= 0;
+    lpos_T	found_m_endpos;
+    colnr_T	prev_current_col;
+
+    /*
+     * Clear any current state that might be hanging around.
+     */
+    invalidate_current_state();
+
+    /*
+     * Start at least "minlines" back.  Default starting point for parsing is
+     * there.
+     * Start further back, to avoid that scrolling backwards will result in
+     * resyncing for every line.  Now it resyncs only one out of N lines,
+     * where N is minlines * 1.5, or minlines * 2 if minlines is small.
+     * Watch out for overflow when minlines is MAXLNUM.
+     */
+    if (syn_buf->b_syn_sync_minlines > start_lnum)
+	start_lnum = 1;
+    else
+    {
+	if (syn_buf->b_syn_sync_minlines == 1)
+	    lnum = 1;
+	else if (syn_buf->b_syn_sync_minlines < 10)
+	    lnum = syn_buf->b_syn_sync_minlines * 2;
+	else
+	    lnum = syn_buf->b_syn_sync_minlines * 3 / 2;
+	if (syn_buf->b_syn_sync_maxlines != 0
+				       && lnum > syn_buf->b_syn_sync_maxlines)
+	    lnum = syn_buf->b_syn_sync_maxlines;
+	if (lnum >= start_lnum)
+	    start_lnum = 1;
+	else
+	    start_lnum -= lnum;
+    }
+    current_lnum = start_lnum;
+
+    /*
+     * 1. Search backwards for the end of a C-style comment.
+     */
+    if (syn_buf->b_syn_sync_flags & SF_CCOMMENT)
+    {
+	/* Need to make syn_buf the current buffer for a moment, to be able to
+	 * use find_start_comment(). */
+	curwin_save = curwin;
+	curwin = wp;
+	curbuf_save = curbuf;
+	curbuf = syn_buf;
+
+	/*
+	 * Skip lines that end in a backslash.
+	 */
+	for ( ; start_lnum > 1; --start_lnum)
+	{
+	    line = ml_get(start_lnum - 1);
+	    if (*line == NUL || *(line + STRLEN(line) - 1) != '\\')
+		break;
+	}
+	current_lnum = start_lnum;
+
+	/* set cursor to start of search */
+	cursor_save = wp->w_cursor;
+	wp->w_cursor.lnum = start_lnum;
+	wp->w_cursor.col = 0;
+
+	/*
+	 * If the line is inside a comment, need to find the syntax item that
+	 * defines the comment.
+	 * Restrict the search for the end of a comment to b_syn_sync_maxlines.
+	 */
+	if (find_start_comment((int)syn_buf->b_syn_sync_maxlines) != NULL)
+	{
+	    for (idx = syn_buf->b_syn_patterns.ga_len; --idx >= 0; )
+		if (SYN_ITEMS(syn_buf)[idx].sp_syn.id == syn_buf->b_syn_sync_id
+			&& SYN_ITEMS(syn_buf)[idx].sp_type == SPTYPE_START)
+		{
+		    validate_current_state();
+		    if (push_current_state(idx) == OK)
+			update_si_attr(current_state.ga_len - 1);
+		    break;
+		}
+	}
+
+	/* restore cursor and buffer */
+	wp->w_cursor = cursor_save;
+	curwin = curwin_save;
+	curbuf = curbuf_save;
+    }
+
+    /*
+     * 2. Search backwards for given sync patterns.
+     */
+    else if (syn_buf->b_syn_sync_flags & SF_MATCH)
+    {
+	if (syn_buf->b_syn_sync_maxlines != 0
+				 && start_lnum > syn_buf->b_syn_sync_maxlines)
+	    break_lnum = start_lnum - syn_buf->b_syn_sync_maxlines;
+	else
+	    break_lnum = 0;
+
+	found_m_endpos.lnum = 0;
+	found_m_endpos.col = 0;
+	end_lnum = start_lnum;
+	lnum = start_lnum;
+	while (--lnum > break_lnum)
+	{
+	    /* This can take a long time: break when CTRL-C pressed. */
+	    line_breakcheck();
+	    if (got_int)
+	    {
+		invalidate_current_state();
+		current_lnum = start_lnum;
+		break;
+	    }
+
+	    /* Check if we have run into a valid saved state stack now. */
+	    if (last_valid != NULL && lnum == last_valid->sst_lnum)
+	    {
+		load_current_state(last_valid);
+		break;
+	    }
+
+	    /*
+	     * Check if the previous line has the line-continuation pattern.
+	     */
+	    if (lnum > 1 && syn_match_linecont(lnum - 1))
+		continue;
+
+	    /*
+	     * Start with nothing on the state stack
+	     */
+	    validate_current_state();
+
+	    for (current_lnum = lnum; current_lnum < end_lnum; ++current_lnum)
+	    {
+		syn_start_line();
+		for (;;)
+		{
+		    had_sync_point = syn_finish_line(TRUE);
+		    /*
+		     * When a sync point has been found, remember where, and
+		     * continue to look for another one, further on in the line.
+		     */
+		    if (had_sync_point && current_state.ga_len)
+		    {
+			cur_si = &CUR_STATE(current_state.ga_len - 1);
+			if (cur_si->si_m_endpos.lnum > start_lnum)
+			{
+			    /* ignore match that goes to after where started */
+			    current_lnum = end_lnum;
+			    break;
+			}
+			spp = &(SYN_ITEMS(syn_buf)[cur_si->si_idx]);
+			found_flags = spp->sp_flags;
+			found_match_idx = spp->sp_sync_idx;
+			found_current_lnum = current_lnum;
+			found_current_col = current_col;
+			found_m_endpos = cur_si->si_m_endpos;
+			/*
+			 * Continue after the match (be aware of a zero-length
+			 * match).
+			 */
+			if (found_m_endpos.lnum > current_lnum)
+			{
+			    current_lnum = found_m_endpos.lnum;
+			    current_col = found_m_endpos.col;
+			    if (current_lnum >= end_lnum)
+				break;
+			}
+			else if (found_m_endpos.col > current_col)
+			    current_col = found_m_endpos.col;
+			else
+			    ++current_col;
+
+			/* syn_current_attr() will have skipped the check for
+			 * an item that ends here, need to do that now.  Be
+			 * careful not to go past the NUL. */
+			prev_current_col = current_col;
+			if (syn_getcurline()[current_col] != NUL)
+			    ++current_col;
+			check_state_ends();
+			current_col = prev_current_col;
+		    }
+		    else
+			break;
+		}
+	    }
+
+	    /*
+	     * If a sync point was encountered, break here.
+	     */
+	    if (found_flags)
+	    {
+		/*
+		 * Put the item that was specified by the sync point on the
+		 * state stack.  If there was no item specified, make the
+		 * state stack empty.
+		 */
+		clear_current_state();
+		if (found_match_idx >= 0
+			&& push_current_state(found_match_idx) == OK)
+		    update_si_attr(current_state.ga_len - 1);
+
+		/*
+		 * When using "grouphere", continue from the sync point
+		 * match, until the end of the line.  Parsing starts at
+		 * the next line.
+		 * For "groupthere" the parsing starts at start_lnum.
+		 */
+		if (found_flags & HL_SYNC_HERE)
+		{
+		    if (current_state.ga_len)
+		    {
+			cur_si = &CUR_STATE(current_state.ga_len - 1);
+			cur_si->si_h_startpos.lnum = found_current_lnum;
+			cur_si->si_h_startpos.col = found_current_col;
+			update_si_end(cur_si, (int)current_col, TRUE);
+			check_keepend();
+		    }
+		    current_col = found_m_endpos.col;
+		    current_lnum = found_m_endpos.lnum;
+		    (void)syn_finish_line(FALSE);
+		    ++current_lnum;
+		}
+		else
+		    current_lnum = start_lnum;
+
+		break;
+	    }
+
+	    end_lnum = lnum;
+	    invalidate_current_state();
+	}
+
+	/* Ran into start of the file or exceeded maximum number of lines */
+	if (lnum <= break_lnum)
+	{
+	    invalidate_current_state();
+	    current_lnum = break_lnum + 1;
+	}
+    }
+
+    validate_current_state();
+}
+
+/*
+ * Return TRUE if the line-continuation pattern matches in line "lnum".
+ */
+    static int
+syn_match_linecont(lnum)
+    linenr_T	lnum;
+{
+    regmmatch_T regmatch;
+
+    if (syn_buf->b_syn_linecont_prog != NULL)
+    {
+	regmatch.rmm_ic = syn_buf->b_syn_linecont_ic;
+	regmatch.regprog = syn_buf->b_syn_linecont_prog;
+	return syn_regexec(&regmatch, lnum, (colnr_T)0);
+    }
+    return FALSE;
+}
+
+/*
+ * Prepare the current state for the start of a line.
+ */
+    static void
+syn_start_line()
+{
+    current_finished = FALSE;
+    current_col = 0;
+
+    /*
+     * Need to update the end of a start/skip/end that continues from the
+     * previous line and regions that have "keepend".
+     */
+    if (current_state.ga_len > 0)
+	syn_update_ends(TRUE);
+
+    next_match_idx = -1;
+    ++current_line_id;
+}
+
+/*
+ * Check for items in the stack that need their end updated.
+ * When "startofline" is TRUE the last item is always updated.
+ * When "startofline" is FALSE the item with "keepend" is forcefully updated.
+ */
+    static void
+syn_update_ends(startofline)
+    int		startofline;
+{
+    stateitem_T	*cur_si;
+    int		i;
+    int		seen_keepend;
+
+    if (startofline)
+    {
+	/* Check for a match carried over from a previous line with a
+	 * contained region.  The match ends as soon as the region ends. */
+	for (i = 0; i < current_state.ga_len; ++i)
+	{
+	    cur_si = &CUR_STATE(i);
+	    if (cur_si->si_idx >= 0
+		    && (SYN_ITEMS(syn_buf)[cur_si->si_idx]).sp_type
+							       == SPTYPE_MATCH
+		    && cur_si->si_m_endpos.lnum < current_lnum)
+	    {
+		cur_si->si_flags |= HL_MATCHCONT;
+		cur_si->si_m_endpos.lnum = 0;
+		cur_si->si_m_endpos.col = 0;
+		cur_si->si_h_endpos = cur_si->si_m_endpos;
+		cur_si->si_ends = TRUE;
+	    }
+	}
+    }
+
+    /*
+     * Need to update the end of a start/skip/end that continues from the
+     * previous line.  And regions that have "keepend", because they may
+     * influence contained items.  If we've just removed "extend"
+     * (startofline == 0) then we should update ends of normal regions
+     * contained inside "keepend" because "extend" could have extended
+     * these "keepend" regions as well as contained normal regions.
+     * Then check for items ending in column 0.
+     */
+    i = current_state.ga_len - 1;
+    if (keepend_level >= 0)
+	for ( ; i > keepend_level; --i)
+	    if (CUR_STATE(i).si_flags & HL_EXTEND)
+		break;
+
+    seen_keepend = FALSE;
+    for ( ; i < current_state.ga_len; ++i)
+    {
+	cur_si = &CUR_STATE(i);
+	if ((cur_si->si_flags & HL_KEEPEND)
+			    || (seen_keepend && !startofline)
+			    || (i == current_state.ga_len - 1 && startofline))
+	{
+	    cur_si->si_h_startpos.col = 0;	/* start highl. in col 0 */
+	    cur_si->si_h_startpos.lnum = current_lnum;
+
+	    if (!(cur_si->si_flags & HL_MATCHCONT))
+		update_si_end(cur_si, (int)current_col, !startofline);
+
+	    if (!startofline && (cur_si->si_flags & HL_KEEPEND))
+		seen_keepend = TRUE;
+	}
+    }
+    check_keepend();
+    check_state_ends();
+}
+
+/****************************************
+ * Handling of the state stack cache.
+ */
+
+/*
+ * EXPLANATION OF THE SYNTAX STATE STACK CACHE
+ *
+ * To speed up syntax highlighting, the state stack for the start of some
+ * lines is cached.  These entries can be used to start parsing at that point.
+ *
+ * The stack is kept in b_sst_array[] for each buffer.  There is a list of
+ * valid entries.  b_sst_first points to the first one, then follow sst_next.
+ * The entries are sorted on line number.  The first entry is often for line 2
+ * (line 1 always starts with an empty stack).
+ * There is also a list for free entries.  This construction is used to avoid
+ * having to allocate and free memory blocks too often.
+ *
+ * When making changes to the buffer, this is logged in b_mod_*.  When calling
+ * update_screen() to update the display, it will call
+ * syn_stack_apply_changes() for each displayed buffer to adjust the cached
+ * entries.  The entries which are inside the changed area are removed,
+ * because they must be recomputed.  Entries below the changed have their line
+ * number adjusted for deleted/inserted lines, and have their sst_change_lnum
+ * set to indicate that a check must be made if the changed lines would change
+ * the cached entry.
+ *
+ * When later displaying lines, an entry is stored for each line.  Displayed
+ * lines are likely to be displayed again, in which case the state at the
+ * start of the line is needed.
+ * For not displayed lines, an entry is stored for every so many lines.  These
+ * entries will be used e.g., when scrolling backwards.  The distance between
+ * entries depends on the number of lines in the buffer.  For small buffers
+ * the distance is fixed at SST_DIST, for large buffers there is a fixed
+ * number of entries SST_MAX_ENTRIES, and the distance is computed.
+ */
+
+/*
+ * Free b_sst_array[] for buffer "buf".
+ * Used when syntax items changed to force resyncing everywhere.
+ */
+    void
+syn_stack_free_all(buf)
+    buf_T	*buf;
+{
+    synstate_T	*p;
+    win_T	*wp;
+
+    if (buf->b_sst_array != NULL)
+    {
+	for (p = buf->b_sst_first; p != NULL; p = p->sst_next)
+	    clear_syn_state(p);
+	vim_free(buf->b_sst_array);
+	buf->b_sst_array = NULL;
+	buf->b_sst_len = 0;
+    }
+#ifdef FEAT_FOLDING
+    /* When using "syntax" fold method, must update all folds. */
+    FOR_ALL_WINDOWS(wp)
+    {
+	if (wp->w_buffer == buf && foldmethodIsSyntax(wp))
+	    foldUpdateAll(wp);
+    }
+#endif
+}
+
+/*
+ * Allocate the syntax state stack for syn_buf when needed.
+ * If the number of entries in b_sst_array[] is much too big or a bit too
+ * small, reallocate it.
+ * Also used to allocate b_sst_array[] for the first time.
+ */
+    static void
+syn_stack_alloc()
+{
+    long	len;
+    synstate_T	*to, *from;
+    synstate_T	*sstp;
+
+    len = syn_buf->b_ml.ml_line_count / SST_DIST + Rows * 2;
+    if (len < SST_MIN_ENTRIES)
+	len = SST_MIN_ENTRIES;
+    else if (len > SST_MAX_ENTRIES)
+	len = SST_MAX_ENTRIES;
+    if (syn_buf->b_sst_len > len * 2 || syn_buf->b_sst_len < len)
+    {
+	/* Allocate 50% too much, to avoid reallocating too often. */
+	len = syn_buf->b_ml.ml_line_count;
+	len = (len + len / 2) / SST_DIST + Rows * 2;
+	if (len < SST_MIN_ENTRIES)
+	    len = SST_MIN_ENTRIES;
+	else if (len > SST_MAX_ENTRIES)
+	    len = SST_MAX_ENTRIES;
+
+	if (syn_buf->b_sst_array != NULL)
+	{
+	    /* When shrinking the array, cleanup the existing stack.
+	     * Make sure that all valid entries fit in the new array. */
+	    while (syn_buf->b_sst_len - syn_buf->b_sst_freecount + 2 > len
+		    && syn_stack_cleanup())
+		;
+	    if (len < syn_buf->b_sst_len - syn_buf->b_sst_freecount + 2)
+		len = syn_buf->b_sst_len - syn_buf->b_sst_freecount + 2;
+	}
+
+	sstp = (synstate_T *)alloc_clear((unsigned)(len * sizeof(synstate_T)));
+	if (sstp == NULL)	/* out of memory! */
+	    return;
+
+	to = sstp - 1;
+	if (syn_buf->b_sst_array != NULL)
+	{
+	    /* Move the states from the old array to the new one. */
+	    for (from = syn_buf->b_sst_first; from != NULL;
+							from = from->sst_next)
+	    {
+		++to;
+		*to = *from;
+		to->sst_next = to + 1;
+	    }
+	}
+	if (to != sstp - 1)
+	{
+	    to->sst_next = NULL;
+	    syn_buf->b_sst_first = sstp;
+	    syn_buf->b_sst_freecount = len - (int)(to - sstp) - 1;
+	}
+	else
+	{
+	    syn_buf->b_sst_first = NULL;
+	    syn_buf->b_sst_freecount = len;
+	}
+
+	/* Create the list of free entries. */
+	syn_buf->b_sst_firstfree = to + 1;
+	while (++to < sstp + len)
+	    to->sst_next = to + 1;
+	(sstp + len - 1)->sst_next = NULL;
+
+	vim_free(syn_buf->b_sst_array);
+	syn_buf->b_sst_array = sstp;
+	syn_buf->b_sst_len = len;
+    }
+}
+
+/*
+ * Check for changes in a buffer to affect stored syntax states.  Uses the
+ * b_mod_* fields.
+ * Called from update_screen(), before screen is being updated, once for each
+ * displayed buffer.
+ */
+    void
+syn_stack_apply_changes(buf)
+    buf_T	*buf;
+{
+    synstate_T	*p, *prev, *np;
+    linenr_T	n;
+
+    if (buf->b_sst_array == NULL)	/* nothing to do */
+	return;
+
+    prev = NULL;
+    for (p = buf->b_sst_first; p != NULL; )
+    {
+	if (p->sst_lnum + buf->b_syn_sync_linebreaks > buf->b_mod_top)
+	{
+	    n = p->sst_lnum + buf->b_mod_xlines;
+	    if (n <= buf->b_mod_bot)
+	    {
+		/* this state is inside the changed area, remove it */
+		np = p->sst_next;
+		if (prev == NULL)
+		    buf->b_sst_first = np;
+		else
+		    prev->sst_next = np;
+		syn_stack_free_entry(buf, p);
+		p = np;
+		continue;
+	    }
+	    /* This state is below the changed area.  Remember the line
+	     * that needs to be parsed before this entry can be made valid
+	     * again. */
+	    if (p->sst_change_lnum != 0 && p->sst_change_lnum > buf->b_mod_top)
+	    {
+		if (p->sst_change_lnum + buf->b_mod_xlines > buf->b_mod_top)
+		    p->sst_change_lnum += buf->b_mod_xlines;
+		else
+		    p->sst_change_lnum = buf->b_mod_top;
+	    }
+	    if (p->sst_change_lnum == 0
+		    || p->sst_change_lnum < buf->b_mod_bot)
+		p->sst_change_lnum = buf->b_mod_bot;
+
+	    p->sst_lnum = n;
+	}
+	prev = p;
+	p = p->sst_next;
+    }
+}
+
+/*
+ * Reduce the number of entries in the state stack for syn_buf.
+ * Returns TRUE if at least one entry was freed.
+ */
+    static int
+syn_stack_cleanup()
+{
+    synstate_T	*p, *prev;
+    disptick_T	tick;
+    int		above;
+    int		dist;
+    int		retval = FALSE;
+
+    if (syn_buf->b_sst_array == NULL || syn_buf->b_sst_first == NULL)
+	return retval;
+
+    /* Compute normal distance between non-displayed entries. */
+    if (syn_buf->b_sst_len <= Rows)
+	dist = 999999;
+    else
+	dist = syn_buf->b_ml.ml_line_count / (syn_buf->b_sst_len - Rows) + 1;
+
+    /*
+     * Go throught the list to find the "tick" for the oldest entry that can
+     * be removed.  Set "above" when the "tick" for the oldest entry is above
+     * "b_sst_lasttick" (the display tick wraps around).
+     */
+    tick = syn_buf->b_sst_lasttick;
+    above = FALSE;
+    prev = syn_buf->b_sst_first;
+    for (p = prev->sst_next; p != NULL; prev = p, p = p->sst_next)
+    {
+	if (prev->sst_lnum + dist > p->sst_lnum)
+	{
+	    if (p->sst_tick > syn_buf->b_sst_lasttick)
+	    {
+		if (!above || p->sst_tick < tick)
+		    tick = p->sst_tick;
+		above = TRUE;
+	    }
+	    else if (!above && p->sst_tick < tick)
+		tick = p->sst_tick;
+	}
+    }
+
+    /*
+     * Go through the list to make the entries for the oldest tick at an
+     * interval of several lines.
+     */
+    prev = syn_buf->b_sst_first;
+    for (p = prev->sst_next; p != NULL; prev = p, p = p->sst_next)
+    {
+	if (p->sst_tick == tick && prev->sst_lnum + dist > p->sst_lnum)
+	{
+	    /* Move this entry from used list to free list */
+	    prev->sst_next = p->sst_next;
+	    syn_stack_free_entry(syn_buf, p);
+	    p = prev;
+	    retval = TRUE;
+	}
+    }
+    return retval;
+}
+
+/*
+ * Free the allocated memory for a syn_state item.
+ * Move the entry into the free list.
+ */
+    static void
+syn_stack_free_entry(buf, p)
+    buf_T	*buf;
+    synstate_T	*p;
+{
+    clear_syn_state(p);
+    p->sst_next = buf->b_sst_firstfree;
+    buf->b_sst_firstfree = p;
+    ++buf->b_sst_freecount;
+}
+
+/*
+ * Find an entry in the list of state stacks at or before "lnum".
+ * Returns NULL when there is no entry or the first entry is after "lnum".
+ */
+    static synstate_T *
+syn_stack_find_entry(lnum)
+    linenr_T	lnum;
+{
+    synstate_T	*p, *prev;
+
+    prev = NULL;
+    for (p = syn_buf->b_sst_first; p != NULL; prev = p, p = p->sst_next)
+    {
+	if (p->sst_lnum == lnum)
+	    return p;
+	if (p->sst_lnum > lnum)
+	    break;
+    }
+    return prev;
+}
+
+/*
+ * Try saving the current state in b_sst_array[].
+ * The current state must be valid for the start of the current_lnum line!
+ */
+    static synstate_T *
+store_current_state(sp)
+    synstate_T	*sp;	/* at or before where state is to be saved or
+				   NULL */
+{
+    int		i;
+    synstate_T	*p;
+    bufstate_T	*bp;
+    stateitem_T	*cur_si;
+
+    if (sp == NULL)
+	sp = syn_stack_find_entry(current_lnum);
+
+    /*
+     * If the current state contains a start or end pattern that continues
+     * from the previous line, we can't use it.  Don't store it then.
+     */
+    for (i = current_state.ga_len - 1; i >= 0; --i)
+    {
+	cur_si = &CUR_STATE(i);
+	if (cur_si->si_h_startpos.lnum >= current_lnum
+		|| cur_si->si_m_endpos.lnum >= current_lnum
+		|| cur_si->si_h_endpos.lnum >= current_lnum
+		|| (cur_si->si_end_idx
+		    && cur_si->si_eoe_pos.lnum >= current_lnum))
+	    break;
+    }
+    if (i >= 0)
+    {
+	if (sp != NULL)
+	{
+	    /* find "sp" in the list and remove it */
+	    if (syn_buf->b_sst_first == sp)
+		/* it's the first entry */
+		syn_buf->b_sst_first = sp->sst_next;
+	    else
+	    {
+		/* find the entry just before this one to adjust sst_next */
+		for (p = syn_buf->b_sst_first; p != NULL; p = p->sst_next)
+		    if (p->sst_next == sp)
+			break;
+		if (p != NULL)	/* just in case */
+		    p->sst_next = sp->sst_next;
+	    }
+	    syn_stack_free_entry(syn_buf, sp);
+	    sp = NULL;
+	}
+    }
+    else if (sp == NULL || sp->sst_lnum != current_lnum)
+    {
+	/*
+	 * Add a new entry
+	 */
+	/* If no free items, cleanup the array first. */
+	if (syn_buf->b_sst_freecount == 0)
+	{
+	    (void)syn_stack_cleanup();
+	    /* "sp" may have been moved to the freelist now */
+	    sp = syn_stack_find_entry(current_lnum);
+	}
+	/* Still no free items?  Must be a strange problem... */
+	if (syn_buf->b_sst_freecount == 0)
+	    sp = NULL;
+	else
+	{
+	    /* Take the first item from the free list and put it in the used
+	     * list, after *sp */
+	    p = syn_buf->b_sst_firstfree;
+	    syn_buf->b_sst_firstfree = p->sst_next;
+	    --syn_buf->b_sst_freecount;
+	    if (sp == NULL)
+	    {
+		/* Insert in front of the list */
+		p->sst_next = syn_buf->b_sst_first;
+		syn_buf->b_sst_first = p;
+	    }
+	    else
+	    {
+		/* insert in list after *sp */
+		p->sst_next = sp->sst_next;
+		sp->sst_next = p;
+	    }
+	    sp = p;
+	    sp->sst_stacksize = 0;
+	    sp->sst_lnum = current_lnum;
+	}
+    }
+    if (sp != NULL)
+    {
+	/* When overwriting an existing state stack, clear it first */
+	clear_syn_state(sp);
+	sp->sst_stacksize = current_state.ga_len;
+	if (current_state.ga_len > SST_FIX_STATES)
+	{
+	    /* Need to clear it, might be something remaining from when the
+	     * length was less than SST_FIX_STATES. */
+	    ga_init2(&sp->sst_union.sst_ga, (int)sizeof(bufstate_T), 1);
+	    if (ga_grow(&sp->sst_union.sst_ga, current_state.ga_len) == FAIL)
+		sp->sst_stacksize = 0;
+	    else
+		sp->sst_union.sst_ga.ga_len = current_state.ga_len;
+	    bp = SYN_STATE_P(&(sp->sst_union.sst_ga));
+	}
+	else
+	    bp = sp->sst_union.sst_stack;
+	for (i = 0; i < sp->sst_stacksize; ++i)
+	{
+	    bp[i].bs_idx = CUR_STATE(i).si_idx;
+	    bp[i].bs_flags = CUR_STATE(i).si_flags;
+	    bp[i].bs_extmatch = ref_extmatch(CUR_STATE(i).si_extmatch);
+	}
+	sp->sst_next_flags = current_next_flags;
+	sp->sst_next_list = current_next_list;
+	sp->sst_tick = display_tick;
+	sp->sst_change_lnum = 0;
+    }
+    current_state_stored = TRUE;
+    return sp;
+}
+
+/*
+ * Copy a state stack from "from" in b_sst_array[] to current_state;
+ */
+    static void
+load_current_state(from)
+    synstate_T	*from;
+{
+    int		i;
+    bufstate_T	*bp;
+
+    clear_current_state();
+    validate_current_state();
+    keepend_level = -1;
+    if (from->sst_stacksize
+	    && ga_grow(&current_state, from->sst_stacksize) != FAIL)
+    {
+	if (from->sst_stacksize > SST_FIX_STATES)
+	    bp = SYN_STATE_P(&(from->sst_union.sst_ga));
+	else
+	    bp = from->sst_union.sst_stack;
+	for (i = 0; i < from->sst_stacksize; ++i)
+	{
+	    CUR_STATE(i).si_idx = bp[i].bs_idx;
+	    CUR_STATE(i).si_flags = bp[i].bs_flags;
+	    CUR_STATE(i).si_extmatch = ref_extmatch(bp[i].bs_extmatch);
+	    if (keepend_level < 0 && (CUR_STATE(i).si_flags & HL_KEEPEND))
+		keepend_level = i;
+	    CUR_STATE(i).si_ends = FALSE;
+	    CUR_STATE(i).si_m_lnum = 0;
+	    if (CUR_STATE(i).si_idx >= 0)
+		CUR_STATE(i).si_next_list =
+		       (SYN_ITEMS(syn_buf)[CUR_STATE(i).si_idx]).sp_next_list;
+	    else
+		CUR_STATE(i).si_next_list = NULL;
+	    update_si_attr(i);
+	}
+	current_state.ga_len = from->sst_stacksize;
+    }
+    current_next_list = from->sst_next_list;
+    current_next_flags = from->sst_next_flags;
+    current_lnum = from->sst_lnum;
+}
+
+/*
+ * Compare saved state stack "*sp" with the current state.
+ * Return TRUE when they are equal.
+ */
+    static int
+syn_stack_equal(sp)
+    synstate_T *sp;
+{
+    int		i, j;
+    bufstate_T	*bp;
+    reg_extmatch_T	*six, *bsx;
+
+    /* First a quick check if the stacks have the same size end nextlist. */
+    if (sp->sst_stacksize == current_state.ga_len
+	    && sp->sst_next_list == current_next_list)
+    {
+	/* Need to compare all states on both stacks. */
+	if (sp->sst_stacksize > SST_FIX_STATES)
+	    bp = SYN_STATE_P(&(sp->sst_union.sst_ga));
+	else
+	    bp = sp->sst_union.sst_stack;
+
+	for (i = current_state.ga_len; --i >= 0; )
+	{
+	    /* If the item has another index the state is different. */
+	    if (bp[i].bs_idx != CUR_STATE(i).si_idx)
+		break;
+	    if (bp[i].bs_extmatch != CUR_STATE(i).si_extmatch)
+	    {
+		/* When the extmatch pointers are different, the strings in
+		 * them can still be the same.  Check if the extmatch
+		 * references are equal. */
+		bsx = bp[i].bs_extmatch;
+		six = CUR_STATE(i).si_extmatch;
+		/* If one of the extmatch pointers is NULL the states are
+		 * different. */
+		if (bsx == NULL || six == NULL)
+		    break;
+		for (j = 0; j < NSUBEXP; ++j)
+		{
+		    /* Check each referenced match string. They must all be
+		     * equal. */
+		    if (bsx->matches[j] != six->matches[j])
+		    {
+			/* If the pointer is different it can still be the
+			 * same text.  Compare the strings, ignore case when
+			 * the start item has the sp_ic flag set. */
+			if (bsx->matches[j] == NULL
+				|| six->matches[j] == NULL)
+			    break;
+			if ((SYN_ITEMS(syn_buf)[CUR_STATE(i).si_idx]).sp_ic
+				? MB_STRICMP(bsx->matches[j],
+							 six->matches[j]) != 0
+				: STRCMP(bsx->matches[j], six->matches[j]) != 0)
+			    break;
+		    }
+		}
+		if (j != NSUBEXP)
+		    break;
+	    }
+	}
+	if (i < 0)
+	    return TRUE;
+    }
+    return FALSE;
+}
+
+/*
+ * We stop parsing syntax above line "lnum".  If the stored state at or below
+ * this line depended on a change before it, it now depends on the line below
+ * the last parsed line.
+ * The window looks like this:
+ *	    line which changed
+ *	    displayed line
+ *	    displayed line
+ * lnum ->  line below window
+ */
+    void
+syntax_end_parsing(lnum)
+    linenr_T	lnum;
+{
+    synstate_T	*sp;
+
+    sp = syn_stack_find_entry(lnum);
+    if (sp != NULL && sp->sst_lnum < lnum)
+	sp = sp->sst_next;
+
+    if (sp != NULL && sp->sst_change_lnum != 0)
+	sp->sst_change_lnum = lnum;
+}
+
+/*
+ * End of handling of the state stack.
+ ****************************************/
+
+    static void
+invalidate_current_state()
+{
+    clear_current_state();
+    current_state.ga_itemsize = 0;	/* mark current_state invalid */
+    current_next_list = NULL;
+    keepend_level = -1;
+}
+
+    static void
+validate_current_state()
+{
+    current_state.ga_itemsize = sizeof(stateitem_T);
+    current_state.ga_growsize = 3;
+}
+
+/*
+ * Return TRUE if the syntax at start of lnum changed since last time.
+ * This will only be called just after get_syntax_attr() for the previous
+ * line, to check if the next line needs to be redrawn too.
+ */
+    int
+syntax_check_changed(lnum)
+    linenr_T	lnum;
+{
+    int		retval = TRUE;
+    synstate_T	*sp;
+
+    /*
+     * Check the state stack when:
+     * - lnum is just below the previously syntaxed line.
+     * - lnum is not before the lines with saved states.
+     * - lnum is not past the lines with saved states.
+     * - lnum is at or before the last changed line.
+     */
+    if (VALID_STATE(&current_state) && lnum == current_lnum + 1)
+    {
+	sp = syn_stack_find_entry(lnum);
+	if (sp != NULL && sp->sst_lnum == lnum)
+	{
+	    /*
+	     * finish the previous line (needed when not all of the line was
+	     * drawn)
+	     */
+	    (void)syn_finish_line(FALSE);
+
+	    /*
+	     * Compare the current state with the previously saved state of
+	     * the line.
+	     */
+	    if (syn_stack_equal(sp))
+		retval = FALSE;
+
+	    /*
+	     * Store the current state in b_sst_array[] for later use.
+	     */
+	    ++current_lnum;
+	    (void)store_current_state(NULL);
+	}
+    }
+
+    return retval;
+}
+
+/*
+ * Finish the current line.
+ * This doesn't return any attributes, it only gets the state at the end of
+ * the line.  It can start anywhere in the line, as long as the current state
+ * is valid.
+ */
+    static int
+syn_finish_line(syncing)
+    int	    syncing;		/* called for syncing */
+{
+    stateitem_T	*cur_si;
+    colnr_T	prev_current_col;
+
+    if (!current_finished)
+    {
+	while (!current_finished)
+	{
+	    (void)syn_current_attr(syncing, FALSE, NULL);
+	    /*
+	     * When syncing, and found some item, need to check the item.
+	     */
+	    if (syncing && current_state.ga_len)
+	    {
+		/*
+		 * Check for match with sync item.
+		 */
+		cur_si = &CUR_STATE(current_state.ga_len - 1);
+		if (cur_si->si_idx >= 0
+			&& (SYN_ITEMS(syn_buf)[cur_si->si_idx].sp_flags
+					      & (HL_SYNC_HERE|HL_SYNC_THERE)))
+		    return TRUE;
+
+		/* syn_current_attr() will have skipped the check for an item
+		 * that ends here, need to do that now.  Be careful not to go
+		 * past the NUL. */
+		prev_current_col = current_col;
+		if (syn_getcurline()[current_col] != NUL)
+		    ++current_col;
+		check_state_ends();
+		current_col = prev_current_col;
+	    }
+	    ++current_col;
+	}
+    }
+    return FALSE;
+}
+
+/*
+ * Return highlight attributes for next character.
+ * Must first call syntax_start() once for the line.
+ * "col" is normally 0 for the first use in a line, and increments by one each
+ * time.  It's allowed to skip characters and to stop before the end of the
+ * line.  But only a "col" after a previously used column is allowed.
+ * When "can_spell" is not NULL set it to TRUE when spell-checking should be
+ * done.
+ */
+    int
+get_syntax_attr(col, can_spell)
+    colnr_T	col;
+    int		*can_spell;
+{
+    int	    attr = 0;
+
+    /* check for out of memory situation */
+    if (syn_buf->b_sst_array == NULL)
+	return 0;
+
+    /* After 'synmaxcol' the attribute is always zero. */
+    if (syn_buf->b_p_smc > 0 && col >= (colnr_T)syn_buf->b_p_smc)
+    {
+	clear_current_state();
+#ifdef FEAT_EVAL
+	current_id = 0;
+	current_trans_id = 0;
+#endif
+	return 0;
+    }
+
+    /* Make sure current_state is valid */
+    if (INVALID_STATE(&current_state))
+	validate_current_state();
+
+    /*
+     * Skip from the current column to "col", get the attributes for "col".
+     */
+    while (current_col <= col)
+    {
+	attr = syn_current_attr(FALSE, TRUE, can_spell);
+	++current_col;
+    }
+
+    return attr;
+}
+
+/*
+ * Get syntax attributes for current_lnum, current_col.
+ */
+    static int
+syn_current_attr(syncing, displaying, can_spell)
+    int		syncing;		/* When 1: called for syncing */
+    int		displaying;		/* result will be displayed */
+    int		*can_spell;		/* return: do spell checking */
+{
+    int		syn_id;
+    lpos_T	endpos;		/* was: char_u *endp; */
+    lpos_T	hl_startpos;	/* was: int hl_startcol; */
+    lpos_T	hl_endpos;
+    lpos_T	eos_pos;	/* end-of-start match (start region) */
+    lpos_T	eoe_pos;	/* end-of-end pattern */
+    int		end_idx;	/* group ID for end pattern */
+    int		idx;
+    synpat_T	*spp;
+    stateitem_T	*cur_si, *sip = NULL;
+    int		startcol;
+    int		endcol;
+    long	flags;
+    short	*next_list;
+    int		found_match;		    /* found usable match */
+    static int	try_next_column = FALSE;    /* must try in next col */
+    int		do_keywords;
+    regmmatch_T	regmatch;
+    lpos_T	pos;
+    int		lc_col;
+    reg_extmatch_T *cur_extmatch = NULL;
+    char_u	*line;		/* current line.  NOTE: becomes invalid after
+				   looking for a pattern match! */
+
+    /* variables for zero-width matches that have a "nextgroup" argument */
+    int		keep_next_list;
+    int		zero_width_next_list = FALSE;
+    garray_T	zero_width_next_ga;
+
+    /*
+     * No character, no attributes!  Past end of line?
+     * Do try matching with an empty line (could be the start of a region).
+     */
+    line = syn_getcurline();
+    if (line[current_col] == NUL && current_col != 0)
+    {
+	/*
+	 * If we found a match after the last column, use it.
+	 */
+	if (next_match_idx >= 0 && next_match_col >= (int)current_col
+						  && next_match_col != MAXCOL)
+	    (void)push_next_match(NULL);
+
+	current_finished = TRUE;
+	current_state_stored = FALSE;
+	return 0;
+    }
+
+    /* if the current or next character is NUL, we will finish the line now */
+    if (line[current_col] == NUL || line[current_col + 1] == NUL)
+    {
+	current_finished = TRUE;
+	current_state_stored = FALSE;
+    }
+
+    /*
+     * When in the previous column there was a match but it could not be used
+     * (empty match or already matched in this column) need to try again in
+     * the next column.
+     */
+    if (try_next_column)
+    {
+	next_match_idx = -1;
+	try_next_column = FALSE;
+    }
+
+    /* Only check for keywords when not syncing and there are some. */
+    do_keywords = !syncing
+		    && (syn_buf->b_keywtab.ht_used > 0
+			    || syn_buf->b_keywtab_ic.ht_used > 0);
+
+    /* Init the list of zero-width matches with a nextlist.  This is used to
+     * avoid matching the same item in the same position twice. */
+    ga_init2(&zero_width_next_ga, (int)sizeof(int), 10);
+
+    /*
+     * Repeat matching keywords and patterns, to find contained items at the
+     * same column.  This stops when there are no extra matches at the current
+     * column.
+     */
+    do
+    {
+	found_match = FALSE;
+	keep_next_list = FALSE;
+	syn_id = 0;
+
+	/*
+	 * 1. Check for a current state.
+	 *    Only when there is no current state, or if the current state may
+	 *    contain other things, we need to check for keywords and patterns.
+	 *    Always need to check for contained items if some item has the
+	 *    "containedin" argument (takes extra time!).
+	 */
+	if (current_state.ga_len)
+	    cur_si = &CUR_STATE(current_state.ga_len - 1);
+	else
+	    cur_si = NULL;
+
+	if (syn_buf->b_syn_containedin || cur_si == NULL
+					      || cur_si->si_cont_list != NULL)
+	{
+	    /*
+	     * 2. Check for keywords, if on a keyword char after a non-keyword
+	     *	  char.  Don't do this when syncing.
+	     */
+	    if (do_keywords)
+	    {
+	      line = syn_getcurline();
+	      if (vim_iswordc_buf(line + current_col, syn_buf)
+		      && (current_col == 0
+			  || !vim_iswordc_buf(line + current_col - 1
+#ifdef FEAT_MBYTE
+			      - (has_mbyte
+				  ? (*mb_head_off)(line, line + current_col - 1)
+				  : 0)
+#endif
+			       , syn_buf)))
+	      {
+		syn_id = check_keyword_id(line, (int)current_col,
+					 &endcol, &flags, &next_list, cur_si);
+		if (syn_id != 0)
+		{
+		    if (push_current_state(KEYWORD_IDX) == OK)
+		    {
+			cur_si = &CUR_STATE(current_state.ga_len - 1);
+			cur_si->si_m_startcol = current_col;
+			cur_si->si_h_startpos.lnum = current_lnum;
+			cur_si->si_h_startpos.col = 0;	/* starts right away */
+			cur_si->si_m_endpos.lnum = current_lnum;
+			cur_si->si_m_endpos.col = endcol;
+			cur_si->si_h_endpos.lnum = current_lnum;
+			cur_si->si_h_endpos.col = endcol;
+			cur_si->si_ends = TRUE;
+			cur_si->si_end_idx = 0;
+			cur_si->si_flags = flags;
+			cur_si->si_id = syn_id;
+			cur_si->si_trans_id = syn_id;
+			if (flags & HL_TRANSP)
+			{
+			    if (current_state.ga_len < 2)
+			    {
+				cur_si->si_attr = 0;
+				cur_si->si_trans_id = 0;
+			    }
+			    else
+			    {
+				cur_si->si_attr = CUR_STATE(
+					current_state.ga_len - 2).si_attr;
+				cur_si->si_trans_id = CUR_STATE(
+					current_state.ga_len - 2).si_trans_id;
+			    }
+			}
+			else
+			    cur_si->si_attr = syn_id2attr(syn_id);
+			cur_si->si_cont_list = NULL;
+			cur_si->si_next_list = next_list;
+			check_keepend();
+		    }
+		    else
+			vim_free(next_list);
+		}
+	      }
+	    }
+
+	    /*
+	     * 3. Check for patterns (only if no keyword found).
+	     */
+	    if (syn_id == 0 && syn_buf->b_syn_patterns.ga_len)
+	    {
+		/*
+		 * If we didn't check for a match yet, or we are past it, check
+		 * for any match with a pattern.
+		 */
+		if (next_match_idx < 0 || next_match_col < (int)current_col)
+		{
+		    /*
+		     * Check all relevant patterns for a match at this
+		     * position.  This is complicated, because matching with a
+		     * pattern takes quite a bit of time, thus we want to
+		     * avoid doing it when it's not needed.
+		     */
+		    next_match_idx = 0;		/* no match in this line yet */
+		    next_match_col = MAXCOL;
+		    for (idx = syn_buf->b_syn_patterns.ga_len; --idx >= 0; )
+		    {
+			spp = &(SYN_ITEMS(syn_buf)[idx]);
+			if (	   spp->sp_syncing == syncing
+				&& (displaying || !(spp->sp_flags & HL_DISPLAY))
+				&& (spp->sp_type == SPTYPE_MATCH
+				    || spp->sp_type == SPTYPE_START)
+				&& (current_next_list != NULL
+				    ? in_id_list(NULL, current_next_list,
+							      &spp->sp_syn, 0)
+				    : (cur_si == NULL
+					? !(spp->sp_flags & HL_CONTAINED)
+					: in_id_list(cur_si,
+					    cur_si->si_cont_list, &spp->sp_syn,
+					    spp->sp_flags & HL_CONTAINED))))
+			{
+			    /* If we already tried matching in this line, and
+			     * there isn't a match before next_match_col, skip
+			     * this item. */
+			    if (spp->sp_line_id == current_line_id
+				    && spp->sp_startcol >= next_match_col)
+				continue;
+			    spp->sp_line_id = current_line_id;
+
+			    lc_col = current_col - spp->sp_offsets[SPO_LC_OFF];
+			    if (lc_col < 0)
+				lc_col = 0;
+
+			    regmatch.rmm_ic = spp->sp_ic;
+			    regmatch.regprog = spp->sp_prog;
+			    if (!syn_regexec(&regmatch, current_lnum,
+							     (colnr_T)lc_col))
+			    {
+				/* no match in this line, try another one */
+				spp->sp_startcol = MAXCOL;
+				continue;
+			    }
+
+			    /*
+			     * Compute the first column of the match.
+			     */
+			    syn_add_start_off(&pos, &regmatch,
+							 spp, SPO_MS_OFF, -1);
+			    if (pos.lnum > current_lnum)
+			    {
+				/* must have used end of match in a next line,
+				 * we can't handle that */
+				spp->sp_startcol = MAXCOL;
+				continue;
+			    }
+			    startcol = pos.col;
+
+			    /* remember the next column where this pattern
+			     * matches in the current line */
+			    spp->sp_startcol = startcol;
+
+			    /*
+			     * If a previously found match starts at a lower
+			     * column number, don't use this one.
+			     */
+			    if (startcol >= next_match_col)
+				continue;
+
+			    /*
+			     * If we matched this pattern at this position
+			     * before, skip it.  Must retry in the next
+			     * column, because it may match from there.
+			     */
+			    if (did_match_already(idx, &zero_width_next_ga))
+			    {
+				try_next_column = TRUE;
+				continue;
+			    }
+
+			    endpos.lnum = regmatch.endpos[0].lnum;
+			    endpos.col = regmatch.endpos[0].col;
+
+			    /* Compute the highlight start. */
+			    syn_add_start_off(&hl_startpos, &regmatch,
+							 spp, SPO_HS_OFF, -1);
+
+			    /* Compute the region start. */
+			    /* Default is to use the end of the match. */
+			    syn_add_end_off(&eos_pos, &regmatch,
+							 spp, SPO_RS_OFF, 0);
+
+			    /*
+			     * Grab the external submatches before they get
+			     * overwritten.  Reference count doesn't change.
+			     */
+			    unref_extmatch(cur_extmatch);
+			    cur_extmatch = re_extmatch_out;
+			    re_extmatch_out = NULL;
+
+			    flags = 0;
+			    eoe_pos.lnum = 0;	/* avoid warning */
+			    eoe_pos.col = 0;
+			    end_idx = 0;
+			    hl_endpos.lnum = 0;
+
+			    /*
+			     * For a "oneline" the end must be found in the
+			     * same line too.  Search for it after the end of
+			     * the match with the start pattern.  Set the
+			     * resulting end positions at the same time.
+			     */
+			    if (spp->sp_type == SPTYPE_START
+					      && (spp->sp_flags & HL_ONELINE))
+			    {
+				lpos_T	startpos;
+
+				startpos = endpos;
+				find_endpos(idx, &startpos, &endpos, &hl_endpos,
+				    &flags, &eoe_pos, &end_idx, cur_extmatch);
+				if (endpos.lnum == 0)
+				    continue;	    /* not found */
+			    }
+
+			    /*
+			     * For a "match" the size must be > 0 after the
+			     * end offset needs has been added.  Except when
+			     * syncing.
+			     */
+			    else if (spp->sp_type == SPTYPE_MATCH)
+			    {
+				syn_add_end_off(&hl_endpos, &regmatch, spp,
+							       SPO_HE_OFF, 0);
+				syn_add_end_off(&endpos, &regmatch, spp,
+							       SPO_ME_OFF, 0);
+				if (endpos.lnum == current_lnum
+				      && (int)endpos.col + syncing < startcol)
+				{
+				    /*
+				     * If an empty string is matched, may need
+				     * to try matching again at next column.
+				     */
+				    if (regmatch.startpos[0].col
+						    == regmatch.endpos[0].col)
+					try_next_column = TRUE;
+				    continue;
+				}
+			    }
+
+			    /*
+			     * keep the best match so far in next_match_*
+			     */
+			    /* Highlighting must start after startpos and end
+			     * before endpos. */
+			    if (hl_startpos.lnum == current_lnum
+					   && (int)hl_startpos.col < startcol)
+				hl_startpos.col = startcol;
+			    limit_pos_zero(&hl_endpos, &endpos);
+
+			    next_match_idx = idx;
+			    next_match_col = startcol;
+			    next_match_m_endpos = endpos;
+			    next_match_h_endpos = hl_endpos;
+			    next_match_h_startpos = hl_startpos;
+			    next_match_flags = flags;
+			    next_match_eos_pos = eos_pos;
+			    next_match_eoe_pos = eoe_pos;
+			    next_match_end_idx = end_idx;
+			    unref_extmatch(next_match_extmatch);
+			    next_match_extmatch = cur_extmatch;
+			    cur_extmatch = NULL;
+			}
+		    }
+		}
+
+		/*
+		 * If we found a match at the current column, use it.
+		 */
+		if (next_match_idx >= 0 && next_match_col == (int)current_col)
+		{
+		    synpat_T	*lspp;
+
+		    /* When a zero-width item matched which has a nextgroup,
+		     * don't push the item but set nextgroup. */
+		    lspp = &(SYN_ITEMS(syn_buf)[next_match_idx]);
+		    if (next_match_m_endpos.lnum == current_lnum
+			    && next_match_m_endpos.col == current_col
+			    && lspp->sp_next_list != NULL)
+		    {
+			current_next_list = lspp->sp_next_list;
+			current_next_flags = lspp->sp_flags;
+			keep_next_list = TRUE;
+			zero_width_next_list = TRUE;
+
+			/* Add the index to a list, so that we can check
+			 * later that we don't match it again (and cause an
+			 * endless loop). */
+			if (ga_grow(&zero_width_next_ga, 1) == OK)
+			{
+			    ((int *)(zero_width_next_ga.ga_data))
+				[zero_width_next_ga.ga_len++] = next_match_idx;
+			}
+			next_match_idx = -1;
+		    }
+		    else
+			cur_si = push_next_match(cur_si);
+		    found_match = TRUE;
+		}
+	    }
+	}
+
+	/*
+	 * Handle searching for nextgroup match.
+	 */
+	if (current_next_list != NULL && !keep_next_list)
+	{
+	    /*
+	     * If a nextgroup was not found, continue looking for one if:
+	     * - this is an empty line and the "skipempty" option was given
+	     * - we are on white space and the "skipwhite" option was given
+	     */
+	    if (!found_match)
+	    {
+		line = syn_getcurline();
+		if (((current_next_flags & HL_SKIPWHITE)
+			    && vim_iswhite(line[current_col]))
+			|| ((current_next_flags & HL_SKIPEMPTY)
+			    && *line == NUL))
+		    break;
+	    }
+
+	    /*
+	     * If a nextgroup was found: Use it, and continue looking for
+	     * contained matches.
+	     * If a nextgroup was not found: Continue looking for a normal
+	     * match.
+	     * When did set current_next_list for a zero-width item and no
+	     * match was found don't loop (would get stuck).
+	     */
+	    current_next_list = NULL;
+	    next_match_idx = -1;
+	    if (!zero_width_next_list)
+		found_match = TRUE;
+	}
+
+    } while (found_match);
+
+    /*
+     * Use attributes from the current state, if within its highlighting.
+     * If not, use attributes from the current-but-one state, etc.
+     */
+    current_attr = 0;
+#ifdef FEAT_EVAL
+    current_id = 0;
+    current_trans_id = 0;
+#endif
+    if (cur_si != NULL)
+    {
+#ifndef FEAT_EVAL
+	int	current_trans_id = 0;
+#endif
+	for (idx = current_state.ga_len - 1; idx >= 0; --idx)
+	{
+	    sip = &CUR_STATE(idx);
+	    if ((current_lnum > sip->si_h_startpos.lnum
+			|| (current_lnum == sip->si_h_startpos.lnum
+			    && current_col >= sip->si_h_startpos.col))
+		    && (sip->si_h_endpos.lnum == 0
+			|| current_lnum < sip->si_h_endpos.lnum
+			|| (current_lnum == sip->si_h_endpos.lnum
+			    && current_col < sip->si_h_endpos.col)))
+	    {
+		current_attr = sip->si_attr;
+#ifdef FEAT_EVAL
+		current_id = sip->si_id;
+#endif
+		current_trans_id = sip->si_trans_id;
+		break;
+	    }
+	}
+
+	if (can_spell != NULL)
+	{
+	    struct sp_syn   sps;
+
+	    /*
+	     * set "can_spell" to TRUE if spell checking is supposed to be
+	     * done in the current item.
+	     */
+	    if (syn_buf->b_spell_cluster_id == 0)
+	    {
+		/* There is no @Spell cluster: Do spelling for items without
+		 * @NoSpell cluster. */
+		if (syn_buf->b_nospell_cluster_id == 0 || current_trans_id == 0)
+		    *can_spell = (syn_buf->b_syn_spell != SYNSPL_NOTOP);
+		else
+		{
+		    sps.inc_tag = 0;
+		    sps.id = syn_buf->b_nospell_cluster_id;
+		    sps.cont_in_list = NULL;
+		    *can_spell = !in_id_list(sip, sip->si_cont_list, &sps, 0);
+		}
+	    }
+	    else
+	    {
+		/* The @Spell cluster is defined: Do spelling in items with
+		 * the @Spell cluster.  But not when @NoSpell is also there.
+		 * At the toplevel only spell check when ":syn spell toplevel"
+		 * was used. */
+		if (current_trans_id == 0)
+		    *can_spell = (syn_buf->b_syn_spell == SYNSPL_TOP);
+		else
+		{
+		    sps.inc_tag = 0;
+		    sps.id = syn_buf->b_spell_cluster_id;
+		    sps.cont_in_list = NULL;
+		    *can_spell = in_id_list(sip, sip->si_cont_list, &sps, 0);
+
+		    if (syn_buf->b_nospell_cluster_id != 0)
+		    {
+			sps.id = syn_buf->b_nospell_cluster_id;
+			if (in_id_list(sip, sip->si_cont_list, &sps, 0))
+			    *can_spell = FALSE;
+		    }
+		}
+	    }
+	}
+
+
+	/*
+	 * Check for end of current state (and the states before it) at the
+	 * next column.  Don't do this for syncing, because we would miss a
+	 * single character match.
+	 * First check if the current state ends at the current column.  It
+	 * may be for an empty match and a containing item might end in the
+	 * current column.
+	 */
+	if (!syncing)
+	{
+	    check_state_ends();
+	    if (current_state.ga_len > 0
+				      && syn_getcurline()[current_col] != NUL)
+	    {
+		++current_col;
+		check_state_ends();
+		--current_col;
+	    }
+	}
+    }
+    else if (can_spell != NULL)
+	/* Default: Only do spelling when there is no @Spell cluster or when
+	 * ":syn spell toplevel" was used. */
+	*can_spell = syn_buf->b_syn_spell == SYNSPL_DEFAULT
+		    ? (syn_buf->b_spell_cluster_id == 0)
+		    : (syn_buf->b_syn_spell == SYNSPL_TOP);
+
+    /* nextgroup ends at end of line, unless "skipnl" or "skipemtpy" present */
+    if (current_next_list != NULL
+	    && syn_getcurline()[current_col + 1] == NUL
+	    && !(current_next_flags & (HL_SKIPNL | HL_SKIPEMPTY)))
+	current_next_list = NULL;
+
+    if (zero_width_next_ga.ga_len > 0)
+	ga_clear(&zero_width_next_ga);
+
+    /* No longer need external matches.  But keep next_match_extmatch. */
+    unref_extmatch(re_extmatch_out);
+    re_extmatch_out = NULL;
+    unref_extmatch(cur_extmatch);
+
+    return current_attr;
+}
+
+
+/*
+ * Check if we already matched pattern "idx" at the current column.
+ */
+    static int
+did_match_already(idx, gap)
+    int		idx;
+    garray_T	*gap;
+{
+    int		i;
+
+    for (i = current_state.ga_len; --i >= 0; )
+	if (CUR_STATE(i).si_m_startcol == (int)current_col
+		&& CUR_STATE(i).si_m_lnum == (int)current_lnum
+		&& CUR_STATE(i).si_idx == idx)
+	    return TRUE;
+
+    /* Zero-width matches with a nextgroup argument are not put on the syntax
+     * stack, and can only be matched once anyway. */
+    for (i = gap->ga_len; --i >= 0; )
+	if (((int *)(gap->ga_data))[i] == idx)
+	    return TRUE;
+
+    return FALSE;
+}
+
+/*
+ * Push the next match onto the stack.
+ */
+    static stateitem_T *
+push_next_match(cur_si)
+    stateitem_T	*cur_si;
+{
+    synpat_T	*spp;
+
+    spp = &(SYN_ITEMS(syn_buf)[next_match_idx]);
+
+    /*
+     * Push the item in current_state stack;
+     */
+    if (push_current_state(next_match_idx) == OK)
+    {
+	/*
+	 * If it's a start-skip-end type that crosses lines, figure out how
+	 * much it continues in this line.  Otherwise just fill in the length.
+	 */
+	cur_si = &CUR_STATE(current_state.ga_len - 1);
+	cur_si->si_h_startpos = next_match_h_startpos;
+	cur_si->si_m_startcol = current_col;
+	cur_si->si_m_lnum = current_lnum;
+	cur_si->si_flags = spp->sp_flags;
+	cur_si->si_next_list = spp->sp_next_list;
+	cur_si->si_extmatch = ref_extmatch(next_match_extmatch);
+	if (spp->sp_type == SPTYPE_START && !(spp->sp_flags & HL_ONELINE))
+	{
+	    /* Try to find the end pattern in the current line */
+	    update_si_end(cur_si, (int)(next_match_m_endpos.col), TRUE);
+	    check_keepend();
+	}
+	else
+	{
+	    cur_si->si_m_endpos = next_match_m_endpos;
+	    cur_si->si_h_endpos = next_match_h_endpos;
+	    cur_si->si_ends = TRUE;
+	    cur_si->si_flags |= next_match_flags;
+	    cur_si->si_eoe_pos = next_match_eoe_pos;
+	    cur_si->si_end_idx = next_match_end_idx;
+	}
+	if (keepend_level < 0 && (cur_si->si_flags & HL_KEEPEND))
+	    keepend_level = current_state.ga_len - 1;
+	check_keepend();
+	update_si_attr(current_state.ga_len - 1);
+
+	/*
+	 * If the start pattern has another highlight group, push another item
+	 * on the stack for the start pattern.
+	 */
+	if (	   spp->sp_type == SPTYPE_START
+		&& spp->sp_syn_match_id != 0
+		&& push_current_state(next_match_idx) == OK)
+	{
+	    cur_si = &CUR_STATE(current_state.ga_len - 1);
+	    cur_si->si_h_startpos = next_match_h_startpos;
+	    cur_si->si_m_startcol = current_col;
+	    cur_si->si_m_lnum = current_lnum;
+	    cur_si->si_m_endpos = next_match_eos_pos;
+	    cur_si->si_h_endpos = next_match_eos_pos;
+	    cur_si->si_ends = TRUE;
+	    cur_si->si_end_idx = 0;
+	    cur_si->si_flags = HL_MATCH;
+	    cur_si->si_next_list = NULL;
+	    check_keepend();
+	    update_si_attr(current_state.ga_len - 1);
+	}
+    }
+
+    next_match_idx = -1;	/* try other match next time */
+
+    return cur_si;
+}
+
+/*
+ * Check for end of current state (and the states before it).
+ */
+    static void
+check_state_ends()
+{
+    stateitem_T	*cur_si;
+    int		had_extend = FALSE;
+
+    cur_si = &CUR_STATE(current_state.ga_len - 1);
+    for (;;)
+    {
+	if (cur_si->si_ends
+		&& (cur_si->si_m_endpos.lnum < current_lnum
+		    || (cur_si->si_m_endpos.lnum == current_lnum
+			&& cur_si->si_m_endpos.col <= current_col)))
+	{
+	    /*
+	     * If there is an end pattern group ID, highlight the end pattern
+	     * now.  No need to pop the current item from the stack.
+	     * Only do this if the end pattern continues beyond the current
+	     * position.
+	     */
+	    if (cur_si->si_end_idx
+		    && (cur_si->si_eoe_pos.lnum > current_lnum
+			|| (cur_si->si_eoe_pos.lnum == current_lnum
+			    && cur_si->si_eoe_pos.col > current_col)))
+	    {
+		cur_si->si_idx = cur_si->si_end_idx;
+		cur_si->si_end_idx = 0;
+		cur_si->si_m_endpos = cur_si->si_eoe_pos;
+		cur_si->si_h_endpos = cur_si->si_eoe_pos;
+		cur_si->si_flags |= HL_MATCH;
+		update_si_attr(current_state.ga_len - 1);
+
+		/* what matches next may be different now, clear it */
+		next_match_idx = 0;
+		next_match_col = MAXCOL;
+		break;
+	    }
+	    else
+	    {
+		/* handle next_list, unless at end of line and no "skipnl" or
+		 * "skipempty" */
+		current_next_list = cur_si->si_next_list;
+		current_next_flags = cur_si->si_flags;
+		if (!(current_next_flags & (HL_SKIPNL | HL_SKIPEMPTY))
+			&& syn_getcurline()[current_col] == NUL)
+		    current_next_list = NULL;
+
+		/* When the ended item has "extend", another item with
+		 * "keepend" now needs to check for its end. */
+		 if (cur_si->si_flags & HL_EXTEND)
+		     had_extend = TRUE;
+
+		pop_current_state();
+
+		if (current_state.ga_len == 0)
+		    break;
+
+		if (had_extend)
+		{
+		    syn_update_ends(FALSE);
+		    if (current_state.ga_len == 0)
+			break;
+		}
+
+		cur_si = &CUR_STATE(current_state.ga_len - 1);
+
+		/*
+		 * Only for a region the search for the end continues after
+		 * the end of the contained item.  If the contained match
+		 * included the end-of-line, break here, the region continues.
+		 * Don't do this when:
+		 * - "keepend" is used for the contained item
+		 * - not at the end of the line (could be end="x$"me=e-1).
+		 * - "excludenl" is used (HL_HAS_EOL won't be set)
+		 */
+		if (cur_si->si_idx >= 0
+			&& SYN_ITEMS(syn_buf)[cur_si->si_idx].sp_type
+							       == SPTYPE_START
+			&& !(cur_si->si_flags & (HL_MATCH | HL_KEEPEND)))
+		{
+		    update_si_end(cur_si, (int)current_col, TRUE);
+		    check_keepend();
+		    if ((current_next_flags & HL_HAS_EOL)
+			    && keepend_level < 0
+			    && syn_getcurline()[current_col] == NUL)
+			break;
+		}
+	    }
+	}
+	else
+	    break;
+    }
+}
+
+/*
+ * Update an entry in the current_state stack for a match or region.  This
+ * fills in si_attr, si_next_list and si_cont_list.
+ */
+    static void
+update_si_attr(idx)
+    int	    idx;
+{
+    stateitem_T	*sip = &CUR_STATE(idx);
+    synpat_T	*spp;
+
+    spp = &(SYN_ITEMS(syn_buf)[sip->si_idx]);
+    if (sip->si_flags & HL_MATCH)
+	sip->si_id = spp->sp_syn_match_id;
+    else
+	sip->si_id = spp->sp_syn.id;
+    sip->si_attr = syn_id2attr(sip->si_id);
+    sip->si_trans_id = sip->si_id;
+    if (sip->si_flags & HL_MATCH)
+	sip->si_cont_list = NULL;
+    else
+	sip->si_cont_list = spp->sp_cont_list;
+
+    /*
+     * For transparent items, take attr from outer item.
+     * Also take cont_list, if there is none.
+     * Don't do this for the matchgroup of a start or end pattern.
+     */
+    if ((spp->sp_flags & HL_TRANSP) && !(sip->si_flags & HL_MATCH))
+    {
+	if (idx == 0)
+	{
+	    sip->si_attr = 0;
+	    sip->si_trans_id = 0;
+	    if (sip->si_cont_list == NULL)
+		sip->si_cont_list = ID_LIST_ALL;
+	}
+	else
+	{
+	    sip->si_attr = CUR_STATE(idx - 1).si_attr;
+	    sip->si_trans_id = CUR_STATE(idx - 1).si_trans_id;
+	    sip->si_h_startpos = CUR_STATE(idx - 1).si_h_startpos;
+	    sip->si_h_endpos = CUR_STATE(idx - 1).si_h_endpos;
+	    if (sip->si_cont_list == NULL)
+	    {
+		sip->si_flags |= HL_TRANS_CONT;
+		sip->si_cont_list = CUR_STATE(idx - 1).si_cont_list;
+	    }
+	}
+    }
+}
+
+/*
+ * Check the current stack for patterns with "keepend" flag.
+ * Propagate the match-end to contained items, until a "skipend" item is found.
+ */
+    static void
+check_keepend()
+{
+    int		i;
+    lpos_T	maxpos;
+    lpos_T	maxpos_h;
+    stateitem_T	*sip;
+
+    /*
+     * This check can consume a lot of time; only do it from the level where
+     * there really is a keepend.
+     */
+    if (keepend_level < 0)
+	return;
+
+    /*
+     * Find the last index of an "extend" item.  "keepend" items before that
+     * won't do anything.  If there is no "extend" item "i" will be
+     * "keepend_level" and all "keepend" items will work normally.
+     */
+    for (i = current_state.ga_len - 1; i > keepend_level; --i)
+	if (CUR_STATE(i).si_flags & HL_EXTEND)
+	    break;
+
+    maxpos.lnum = 0;
+    maxpos_h.lnum = 0;
+    for ( ; i < current_state.ga_len; ++i)
+    {
+	sip = &CUR_STATE(i);
+	if (maxpos.lnum != 0)
+	{
+	    limit_pos_zero(&sip->si_m_endpos, &maxpos);
+	    limit_pos_zero(&sip->si_h_endpos, &maxpos_h);
+	    limit_pos_zero(&sip->si_eoe_pos, &maxpos);
+	    sip->si_ends = TRUE;
+	}
+	if (sip->si_ends && (sip->si_flags & HL_KEEPEND))
+	{
+	    if (maxpos.lnum == 0
+		    || maxpos.lnum > sip->si_m_endpos.lnum
+		    || (maxpos.lnum == sip->si_m_endpos.lnum
+			&& maxpos.col > sip->si_m_endpos.col))
+		maxpos = sip->si_m_endpos;
+	    if (maxpos_h.lnum == 0
+		    || maxpos_h.lnum > sip->si_h_endpos.lnum
+		    || (maxpos_h.lnum == sip->si_h_endpos.lnum
+			&& maxpos_h.col > sip->si_h_endpos.col))
+		maxpos_h = sip->si_h_endpos;
+	}
+    }
+}
+
+/*
+ * Update an entry in the current_state stack for a start-skip-end pattern.
+ * This finds the end of the current item, if it's in the current line.
+ *
+ * Return the flags for the matched END.
+ */
+    static void
+update_si_end(sip, startcol, force)
+    stateitem_T	*sip;
+    int		startcol;   /* where to start searching for the end */
+    int		force;	    /* when TRUE overrule a previous end */
+{
+    lpos_T	startpos;
+    lpos_T	endpos;
+    lpos_T	hl_endpos;
+    lpos_T	end_endpos;
+    int		end_idx;
+
+    /* Don't update when it's already done.  Can be a match of an end pattern
+     * that started in a previous line.  Watch out: can also be a "keepend"
+     * from a containing item. */
+    if (!force && sip->si_m_endpos.lnum >= current_lnum)
+	return;
+
+    /*
+     * We need to find the end of the region.  It may continue in the next
+     * line.
+     */
+    end_idx = 0;
+    startpos.lnum = current_lnum;
+    startpos.col = startcol;
+    find_endpos(sip->si_idx, &startpos, &endpos, &hl_endpos,
+		   &(sip->si_flags), &end_endpos, &end_idx, sip->si_extmatch);
+
+    if (endpos.lnum == 0)
+    {
+	/* No end pattern matched. */
+	if (SYN_ITEMS(syn_buf)[sip->si_idx].sp_flags & HL_ONELINE)
+	{
+	    /* a "oneline" never continues in the next line */
+	    sip->si_ends = TRUE;
+	    sip->si_m_endpos.lnum = current_lnum;
+	    sip->si_m_endpos.col = (colnr_T)STRLEN(syn_getcurline());
+	}
+	else
+	{
+	    /* continues in the next line */
+	    sip->si_ends = FALSE;
+	    sip->si_m_endpos.lnum = 0;
+	}
+	sip->si_h_endpos = sip->si_m_endpos;
+    }
+    else
+    {
+	/* match within this line */
+	sip->si_m_endpos = endpos;
+	sip->si_h_endpos = hl_endpos;
+	sip->si_eoe_pos = end_endpos;
+	sip->si_ends = TRUE;
+	sip->si_end_idx = end_idx;
+    }
+}
+
+/*
+ * Add a new state to the current state stack.
+ * It is cleared and the index set to "idx".
+ * Return FAIL if it's not possible (out of memory).
+ */
+    static int
+push_current_state(idx)
+    int	    idx;
+{
+    if (ga_grow(&current_state, 1) == FAIL)
+	return FAIL;
+    vim_memset(&CUR_STATE(current_state.ga_len), 0, sizeof(stateitem_T));
+    CUR_STATE(current_state.ga_len).si_idx = idx;
+    ++current_state.ga_len;
+    return OK;
+}
+
+/*
+ * Remove a state from the current_state stack.
+ */
+    static void
+pop_current_state()
+{
+    if (current_state.ga_len)
+    {
+	unref_extmatch(CUR_STATE(current_state.ga_len - 1).si_extmatch);
+	--current_state.ga_len;
+    }
+    /* after the end of a pattern, try matching a keyword or pattern */
+    next_match_idx = -1;
+
+    /* if first state with "keepend" is popped, reset keepend_level */
+    if (keepend_level >= current_state.ga_len)
+	keepend_level = -1;
+}
+
+/*
+ * Find the end of a start/skip/end syntax region after "startpos".
+ * Only checks one line.
+ * Also handles a match item that continued from a previous line.
+ * If not found, the syntax item continues in the next line.  m_endpos->lnum
+ * will be 0.
+ * If found, the end of the region and the end of the highlighting is
+ * computed.
+ */
+    static void
+find_endpos(idx, startpos, m_endpos, hl_endpos, flagsp, end_endpos,
+							   end_idx, start_ext)
+    int		idx;		/* index of the pattern */
+    lpos_T	*startpos;	/* where to start looking for an END match */
+    lpos_T	*m_endpos;	/* return: end of match */
+    lpos_T	*hl_endpos;	/* return: end of highlighting */
+    long	*flagsp;	/* return: flags of matching END */
+    lpos_T	*end_endpos;	/* return: end of end pattern match */
+    int		*end_idx;	/* return: group ID for end pat. match, or 0 */
+    reg_extmatch_T *start_ext;	/* submatches from the start pattern */
+{
+    colnr_T	matchcol;
+    synpat_T	*spp, *spp_skip;
+    int		start_idx;
+    int		best_idx;
+    regmmatch_T	regmatch;
+    regmmatch_T	best_regmatch;	    /* startpos/endpos of best match */
+    lpos_T	pos;
+    char_u	*line;
+    int		had_match = FALSE;
+
+    /*
+     * Check for being called with a START pattern.
+     * Can happen with a match that continues to the next line, because it
+     * contained a region.
+     */
+    spp = &(SYN_ITEMS(syn_buf)[idx]);
+    if (spp->sp_type != SPTYPE_START)
+    {
+	*hl_endpos = *startpos;
+	return;
+    }
+
+    /*
+     * Find the SKIP or first END pattern after the last START pattern.
+     */
+    for (;;)
+    {
+	spp = &(SYN_ITEMS(syn_buf)[idx]);
+	if (spp->sp_type != SPTYPE_START)
+	    break;
+	++idx;
+    }
+
+    /*
+     *	Lookup the SKIP pattern (if present)
+     */
+    if (spp->sp_type == SPTYPE_SKIP)
+    {
+	spp_skip = spp;
+	++idx;
+    }
+    else
+	spp_skip = NULL;
+
+    /* Setup external matches for syn_regexec(). */
+    unref_extmatch(re_extmatch_in);
+    re_extmatch_in = ref_extmatch(start_ext);
+
+    matchcol = startpos->col;	/* start looking for a match at sstart */
+    start_idx = idx;		/* remember the first END pattern. */
+    best_regmatch.startpos[0].col = 0;		/* avoid compiler warning */
+    for (;;)
+    {
+	/*
+	 * Find end pattern that matches first after "matchcol".
+	 */
+	best_idx = -1;
+	for (idx = start_idx; idx < syn_buf->b_syn_patterns.ga_len; ++idx)
+	{
+	    int lc_col = matchcol;
+
+	    spp = &(SYN_ITEMS(syn_buf)[idx]);
+	    if (spp->sp_type != SPTYPE_END)	/* past last END pattern */
+		break;
+	    lc_col -= spp->sp_offsets[SPO_LC_OFF];
+	    if (lc_col < 0)
+		lc_col = 0;
+
+	    regmatch.rmm_ic = spp->sp_ic;
+	    regmatch.regprog = spp->sp_prog;
+	    if (syn_regexec(&regmatch, startpos->lnum, lc_col))
+	    {
+		if (best_idx == -1 || regmatch.startpos[0].col
+					      < best_regmatch.startpos[0].col)
+		{
+		    best_idx = idx;
+		    best_regmatch.startpos[0] = regmatch.startpos[0];
+		    best_regmatch.endpos[0] = regmatch.endpos[0];
+		}
+	    }
+	}
+
+	/*
+	 * If all end patterns have been tried, and there is no match, the
+	 * item continues until end-of-line.
+	 */
+	if (best_idx == -1)
+	    break;
+
+	/*
+	 * If the skip pattern matches before the end pattern,
+	 * continue searching after the skip pattern.
+	 */
+	if (spp_skip != NULL)
+	{
+	    int lc_col = matchcol - spp_skip->sp_offsets[SPO_LC_OFF];
+
+	    if (lc_col < 0)
+		lc_col = 0;
+	    regmatch.rmm_ic = spp_skip->sp_ic;
+	    regmatch.regprog = spp_skip->sp_prog;
+	    if (syn_regexec(&regmatch, startpos->lnum, lc_col)
+		    && regmatch.startpos[0].col
+					     <= best_regmatch.startpos[0].col)
+	    {
+		/* Add offset to skip pattern match */
+		syn_add_end_off(&pos, &regmatch, spp_skip, SPO_ME_OFF, 1);
+
+		/* If the skip pattern goes on to the next line, there is no
+		 * match with an end pattern in this line. */
+		if (pos.lnum > startpos->lnum)
+		    break;
+
+		line = ml_get_buf(syn_buf, startpos->lnum, FALSE);
+
+		/* take care of an empty match or negative offset */
+		if (pos.col <= matchcol)
+		    ++matchcol;
+		else if (pos.col <= regmatch.endpos[0].col)
+		    matchcol = pos.col;
+		else
+		    /* Be careful not to jump over the NUL at the end-of-line */
+		    for (matchcol = regmatch.endpos[0].col;
+			    line[matchcol] != NUL && matchcol < pos.col;
+								   ++matchcol)
+			;
+
+		/* if the skip pattern includes end-of-line, break here */
+		if (line[matchcol] == NUL)
+		    break;
+
+		continue;	    /* start with first end pattern again */
+	    }
+	}
+
+	/*
+	 * Match from start pattern to end pattern.
+	 * Correct for match and highlight offset of end pattern.
+	 */
+	spp = &(SYN_ITEMS(syn_buf)[best_idx]);
+	syn_add_end_off(m_endpos, &best_regmatch, spp, SPO_ME_OFF, 1);
+	/* can't end before the start */
+	if (m_endpos->lnum == startpos->lnum && m_endpos->col < startpos->col)
+	    m_endpos->col = startpos->col;
+
+	syn_add_end_off(end_endpos, &best_regmatch, spp, SPO_HE_OFF, 1);
+	/* can't end before the start */
+	if (end_endpos->lnum == startpos->lnum
+					   && end_endpos->col < startpos->col)
+	    end_endpos->col = startpos->col;
+	/* can't end after the match */
+	limit_pos(end_endpos, m_endpos);
+
+	/*
+	 * If the end group is highlighted differently, adjust the pointers.
+	 */
+	if (spp->sp_syn_match_id != spp->sp_syn.id && spp->sp_syn_match_id != 0)
+	{
+	    *end_idx = best_idx;
+	    if (spp->sp_off_flags & (1 << (SPO_RE_OFF + SPO_COUNT)))
+	    {
+		hl_endpos->lnum = best_regmatch.endpos[0].lnum;
+		hl_endpos->col = best_regmatch.endpos[0].col;
+	    }
+	    else
+	    {
+		hl_endpos->lnum = best_regmatch.startpos[0].lnum;
+		hl_endpos->col = best_regmatch.startpos[0].col;
+	    }
+	    hl_endpos->col += spp->sp_offsets[SPO_RE_OFF];
+
+	    /* can't end before the start */
+	    if (hl_endpos->lnum == startpos->lnum
+					    && hl_endpos->col < startpos->col)
+		hl_endpos->col = startpos->col;
+	    limit_pos(hl_endpos, m_endpos);
+
+	    /* now the match ends where the highlighting ends, it is turned
+	     * into the matchgroup for the end */
+	    *m_endpos = *hl_endpos;
+	}
+	else
+	{
+	    *end_idx = 0;
+	    *hl_endpos = *end_endpos;
+	}
+
+	*flagsp = spp->sp_flags;
+
+	had_match = TRUE;
+	break;
+    }
+
+    /* no match for an END pattern in this line */
+    if (!had_match)
+	m_endpos->lnum = 0;
+
+    /* Remove external matches. */
+    unref_extmatch(re_extmatch_in);
+    re_extmatch_in = NULL;
+}
+
+/*
+ * Limit "pos" not to be after "limit".
+ */
+    static void
+limit_pos(pos, limit)
+    lpos_T	*pos;
+    lpos_T	*limit;
+{
+    if (pos->lnum > limit->lnum)
+	*pos = *limit;
+    else if (pos->lnum == limit->lnum && pos->col > limit->col)
+	pos->col = limit->col;
+}
+
+/*
+ * Limit "pos" not to be after "limit", unless pos->lnum is zero.
+ */
+    static void
+limit_pos_zero(pos, limit)
+    lpos_T	*pos;
+    lpos_T	*limit;
+{
+    if (pos->lnum == 0)
+	*pos = *limit;
+    else
+	limit_pos(pos, limit);
+}
+
+/*
+ * Add offset to matched text for end of match or highlight.
+ */
+    static void
+syn_add_end_off(result, regmatch, spp, idx, extra)
+    lpos_T	*result;	/* returned position */
+    regmmatch_T	*regmatch;	/* start/end of match */
+    synpat_T	*spp;		/* matched pattern */
+    int		idx;		/* index of offset */
+    int		extra;		/* extra chars for offset to start */
+{
+    int		col;
+    int		len;
+
+    if (spp->sp_off_flags & (1 << idx))
+    {
+	result->lnum = regmatch->startpos[0].lnum;
+	col = regmatch->startpos[0].col + extra;
+    }
+    else
+    {
+	result->lnum = regmatch->endpos[0].lnum;
+	col = regmatch->endpos[0].col;
+    }
+    col += spp->sp_offsets[idx];
+    if (col < 0)
+	result->col = 0;
+    else
+    {
+	/* Don't go past the end of the line.  Matters for "rs=e+2" when there
+	 * is a matchgroup. Watch out for match with last NL in the buffer. */
+	if (result->lnum > syn_buf->b_ml.ml_line_count)
+	    len = 0;
+	else
+	    len = (int)STRLEN(ml_get_buf(syn_buf, result->lnum, FALSE));
+	if (col > len)
+	    result->col = len;
+	else
+	    result->col = col;
+    }
+}
+
+/*
+ * Add offset to matched text for start of match or highlight.
+ * Avoid resulting column to become negative.
+ */
+    static void
+syn_add_start_off(result, regmatch, spp, idx, extra)
+    lpos_T	*result;	/* returned position */
+    regmmatch_T	*regmatch;	/* start/end of match */
+    synpat_T	*spp;
+    int		idx;
+    int		extra;	    /* extra chars for offset to end */
+{
+    int		col;
+
+    if (spp->sp_off_flags & (1 << (idx + SPO_COUNT)))
+    {
+	result->lnum = regmatch->endpos[0].lnum;
+	col = regmatch->endpos[0].col + extra;
+    }
+    else
+    {
+	result->lnum = regmatch->startpos[0].lnum;
+	col = regmatch->startpos[0].col;
+    }
+    col += spp->sp_offsets[idx];
+    if (col < 0)
+	result->col = 0;
+    else
+	result->col = col;
+}
+
+/*
+ * Get current line in syntax buffer.
+ */
+    static char_u *
+syn_getcurline()
+{
+    return ml_get_buf(syn_buf, current_lnum, FALSE);
+}
+
+/*
+ * Call vim_regexec() to find a match with "rmp" in "syn_buf".
+ * Returns TRUE when there is a match.
+ */
+    static int
+syn_regexec(rmp, lnum, col)
+    regmmatch_T	*rmp;
+    linenr_T	lnum;
+    colnr_T	col;
+{
+    rmp->rmm_maxcol = syn_buf->b_p_smc;
+    if (vim_regexec_multi(rmp, syn_win, syn_buf, lnum, col) > 0)
+    {
+	rmp->startpos[0].lnum += lnum;
+	rmp->endpos[0].lnum += lnum;
+	return TRUE;
+    }
+    return FALSE;
+}
+
+/*
+ * Check one position in a line for a matching keyword.
+ * The caller must check if a keyword can start at startcol.
+ * Return it's ID if found, 0 otherwise.
+ */
+    static int
+check_keyword_id(line, startcol, endcolp, flagsp, next_listp, cur_si)
+    char_u	*line;
+    int		startcol;	/* position in line to check for keyword */
+    int		*endcolp;	/* return: character after found keyword */
+    long	*flagsp;	/* return: flags of matching keyword */
+    short	**next_listp;	/* return: next_list of matching keyword */
+    stateitem_T	*cur_si;	/* item at the top of the stack */
+{
+    keyentry_T	*kp;
+    char_u	*kwp;
+    int		round;
+    int		kwlen;
+    char_u	keyword[MAXKEYWLEN + 1]; /* assume max. keyword len is 80 */
+    hashtab_T	*ht;
+    hashitem_T	*hi;
+
+    /* Find first character after the keyword.  First character was already
+     * checked. */
+    kwp = line + startcol;
+    kwlen = 0;
+    do
+    {
+#ifdef FEAT_MBYTE
+	if (has_mbyte)
+	    kwlen += (*mb_ptr2len)(kwp + kwlen);
+	else
+#endif
+	    ++kwlen;
+    }
+    while (vim_iswordc_buf(kwp + kwlen, syn_buf));
+
+    if (kwlen > MAXKEYWLEN)
+	return 0;
+
+    /*
+     * Must make a copy of the keyword, so we can add a NUL and make it
+     * lowercase.
+     */
+    vim_strncpy(keyword, kwp, kwlen);
+
+    /*
+     * Try twice:
+     * 1. matching case
+     * 2. ignoring case
+     */
+    for (round = 1; round <= 2; ++round)
+    {
+	ht = round == 1 ? &syn_buf->b_keywtab : &syn_buf->b_keywtab_ic;
+	if (ht->ht_used == 0)
+	    continue;
+	if (round == 2)	/* ignore case */
+	    (void)str_foldcase(kwp, kwlen, keyword, MAXKEYWLEN + 1);
+
+	/*
+	 * Find keywords that match.  There can be several with different
+	 * attributes.
+	 * When current_next_list is non-zero accept only that group, otherwise:
+	 *  Accept a not-contained keyword at toplevel.
+	 *  Accept a keyword at other levels only if it is in the contains list.
+	 */
+	hi = hash_find(ht, keyword);
+	if (!HASHITEM_EMPTY(hi))
+	    for (kp = HI2KE(hi); kp != NULL; kp = kp->ke_next)
+	    {
+		if (current_next_list != 0
+			? in_id_list(NULL, current_next_list, &kp->k_syn, 0)
+			: (cur_si == NULL
+			    ? !(kp->flags & HL_CONTAINED)
+			    : in_id_list(cur_si, cur_si->si_cont_list,
+				      &kp->k_syn, kp->flags & HL_CONTAINED)))
+		{
+		    *endcolp = startcol + kwlen;
+		    *flagsp = kp->flags;
+		    *next_listp = kp->next_list;
+		    return kp->k_syn.id;
+		}
+	    }
+    }
+    return 0;
+}
+
+/*
+ * Handle ":syntax case" command.
+ */
+/* ARGSUSED */
+    static void
+syn_cmd_case(eap, syncing)
+    exarg_T	*eap;
+    int		syncing;	    /* not used */
+{
+    char_u	*arg = eap->arg;
+    char_u	*next;
+
+    eap->nextcmd = find_nextcmd(arg);
+    if (eap->skip)
+	return;
+
+    next = skiptowhite(arg);
+    if (STRNICMP(arg, "match", 5) == 0 && next - arg == 5)
+	curbuf->b_syn_ic = FALSE;
+    else if (STRNICMP(arg, "ignore", 6) == 0 && next - arg == 6)
+	curbuf->b_syn_ic = TRUE;
+    else
+	EMSG2(_("E390: Illegal argument: %s"), arg);
+}
+
+/*
+ * Handle ":syntax spell" command.
+ */
+/* ARGSUSED */
+    static void
+syn_cmd_spell(eap, syncing)
+    exarg_T	*eap;
+    int		syncing;	    /* not used */
+{
+    char_u	*arg = eap->arg;
+    char_u	*next;
+
+    eap->nextcmd = find_nextcmd(arg);
+    if (eap->skip)
+	return;
+
+    next = skiptowhite(arg);
+    if (STRNICMP(arg, "toplevel", 8) == 0 && next - arg == 8)
+	curbuf->b_syn_spell = SYNSPL_TOP;
+    else if (STRNICMP(arg, "notoplevel", 10) == 0 && next - arg == 10)
+	curbuf->b_syn_spell = SYNSPL_NOTOP;
+    else if (STRNICMP(arg, "default", 7) == 0 && next - arg == 7)
+	curbuf->b_syn_spell = SYNSPL_DEFAULT;
+    else
+	EMSG2(_("E390: Illegal argument: %s"), arg);
+}
+
+/*
+ * Clear all syntax info for one buffer.
+ */
+    void
+syntax_clear(buf)
+    buf_T	*buf;
+{
+    int i;
+
+    buf->b_syn_error = FALSE;	    /* clear previous error */
+    buf->b_syn_ic = FALSE;	    /* Use case, by default */
+    buf->b_syn_spell = SYNSPL_DEFAULT; /* default spell checking */
+    buf->b_syn_containedin = FALSE;
+
+    /* free the keywords */
+    clear_keywtab(&buf->b_keywtab);
+    clear_keywtab(&buf->b_keywtab_ic);
+
+    /* free the syntax patterns */
+    for (i = buf->b_syn_patterns.ga_len; --i >= 0; )
+	syn_clear_pattern(buf, i);
+    ga_clear(&buf->b_syn_patterns);
+
+    /* free the syntax clusters */
+    for (i = buf->b_syn_clusters.ga_len; --i >= 0; )
+	syn_clear_cluster(buf, i);
+    ga_clear(&buf->b_syn_clusters);
+    buf->b_spell_cluster_id = 0;
+    buf->b_nospell_cluster_id = 0;
+
+    buf->b_syn_sync_flags = 0;
+    buf->b_syn_sync_minlines = 0;
+    buf->b_syn_sync_maxlines = 0;
+    buf->b_syn_sync_linebreaks = 0;
+
+    vim_free(buf->b_syn_linecont_prog);
+    buf->b_syn_linecont_prog = NULL;
+    vim_free(buf->b_syn_linecont_pat);
+    buf->b_syn_linecont_pat = NULL;
+#ifdef FEAT_FOLDING
+    buf->b_syn_folditems = 0;
+#endif
+
+    /* free the stored states */
+    syn_stack_free_all(buf);
+    invalidate_current_state();
+}
+
+/*
+ * Clear syncing info for one buffer.
+ */
+    static void
+syntax_sync_clear()
+{
+    int i;
+
+    /* free the syntax patterns */
+    for (i = curbuf->b_syn_patterns.ga_len; --i >= 0; )
+	if (SYN_ITEMS(curbuf)[i].sp_syncing)
+	    syn_remove_pattern(curbuf, i);
+
+    curbuf->b_syn_sync_flags = 0;
+    curbuf->b_syn_sync_minlines = 0;
+    curbuf->b_syn_sync_maxlines = 0;
+    curbuf->b_syn_sync_linebreaks = 0;
+
+    vim_free(curbuf->b_syn_linecont_prog);
+    curbuf->b_syn_linecont_prog = NULL;
+    vim_free(curbuf->b_syn_linecont_pat);
+    curbuf->b_syn_linecont_pat = NULL;
+
+    syn_stack_free_all(curbuf);		/* Need to recompute all syntax. */
+}
+
+/*
+ * Remove one pattern from the buffer's pattern list.
+ */
+    static void
+syn_remove_pattern(buf, idx)
+    buf_T	*buf;
+    int		idx;
+{
+    synpat_T	*spp;
+
+    spp = &(SYN_ITEMS(buf)[idx]);
+#ifdef FEAT_FOLDING
+    if (spp->sp_flags & HL_FOLD)
+	--buf->b_syn_folditems;
+#endif
+    syn_clear_pattern(buf, idx);
+    mch_memmove(spp, spp + 1,
+		   sizeof(synpat_T) * (buf->b_syn_patterns.ga_len - idx - 1));
+    --buf->b_syn_patterns.ga_len;
+}
+
+/*
+ * Clear and free one syntax pattern.  When clearing all, must be called from
+ * last to first!
+ */
+    static void
+syn_clear_pattern(buf, i)
+    buf_T	*buf;
+    int		i;
+{
+    vim_free(SYN_ITEMS(buf)[i].sp_pattern);
+    vim_free(SYN_ITEMS(buf)[i].sp_prog);
+    /* Only free sp_cont_list and sp_next_list of first start pattern */
+    if (i == 0 || SYN_ITEMS(buf)[i - 1].sp_type != SPTYPE_START)
+    {
+	vim_free(SYN_ITEMS(buf)[i].sp_cont_list);
+	vim_free(SYN_ITEMS(buf)[i].sp_next_list);
+    }
+}
+
+/*
+ * Clear and free one syntax cluster.
+ */
+    static void
+syn_clear_cluster(buf, i)
+    buf_T	*buf;
+    int		i;
+{
+    vim_free(SYN_CLSTR(buf)[i].scl_name);
+    vim_free(SYN_CLSTR(buf)[i].scl_name_u);
+    vim_free(SYN_CLSTR(buf)[i].scl_list);
+}
+
+/*
+ * Handle ":syntax clear" command.
+ */
+    static void
+syn_cmd_clear(eap, syncing)
+    exarg_T	*eap;
+    int		syncing;
+{
+    char_u	*arg = eap->arg;
+    char_u	*arg_end;
+    int		id;
+
+    eap->nextcmd = find_nextcmd(arg);
+    if (eap->skip)
+	return;
+
+    /*
+     * We have to disable this within ":syn include @group filename",
+     * because otherwise @group would get deleted.
+     * Only required for Vim 5.x syntax files, 6.0 ones don't contain ":syn
+     * clear".
+     */
+    if (curbuf->b_syn_topgrp != 0)
+	return;
+
+    if (ends_excmd(*arg))
+    {
+	/*
+	 * No argument: Clear all syntax items.
+	 */
+	if (syncing)
+	    syntax_sync_clear();
+	else
+	{
+	    syntax_clear(curbuf);
+	    do_unlet((char_u *)"b:current_syntax", TRUE);
+	}
+    }
+    else
+    {
+	/*
+	 * Clear the group IDs that are in the argument.
+	 */
+	while (!ends_excmd(*arg))
+	{
+	    arg_end = skiptowhite(arg);
+	    if (*arg == '@')
+	    {
+		id = syn_scl_namen2id(arg + 1, (int)(arg_end - arg - 1));
+		if (id == 0)
+		{
+		    EMSG2(_("E391: No such syntax cluster: %s"), arg);
+		    break;
+		}
+		else
+		{
+		    /*
+		     * We can't physically delete a cluster without changing
+		     * the IDs of other clusters, so we do the next best thing
+		     * and make it empty.
+		     */
+		    short scl_id = id - SYNID_CLUSTER;
+
+		    vim_free(SYN_CLSTR(curbuf)[scl_id].scl_list);
+		    SYN_CLSTR(curbuf)[scl_id].scl_list = NULL;
+		}
+	    }
+	    else
+	    {
+		id = syn_namen2id(arg, (int)(arg_end - arg));
+		if (id == 0)
+		{
+		    EMSG2(_(e_nogroup), arg);
+		    break;
+		}
+		else
+		    syn_clear_one(id, syncing);
+	    }
+	    arg = skipwhite(arg_end);
+	}
+    }
+    redraw_curbuf_later(SOME_VALID);
+    syn_stack_free_all(curbuf);		/* Need to recompute all syntax. */
+}
+
+/*
+ * Clear one syntax group for the current buffer.
+ */
+    static void
+syn_clear_one(id, syncing)
+    int		id;
+    int		syncing;
+{
+    synpat_T	*spp;
+    int		idx;
+
+    /* Clear keywords only when not ":syn sync clear group-name" */
+    if (!syncing)
+    {
+	(void)syn_clear_keyword(id, &curbuf->b_keywtab);
+	(void)syn_clear_keyword(id, &curbuf->b_keywtab_ic);
+    }
+
+    /* clear the patterns for "id" */
+    for (idx = curbuf->b_syn_patterns.ga_len; --idx >= 0; )
+    {
+	spp = &(SYN_ITEMS(curbuf)[idx]);
+	if (spp->sp_syn.id != id || spp->sp_syncing != syncing)
+	    continue;
+	syn_remove_pattern(curbuf, idx);
+    }
+}
+
+/*
+ * Handle ":syntax on" command.
+ */
+/* ARGSUSED */
+    static void
+syn_cmd_on(eap, syncing)
+    exarg_T	*eap;
+    int		syncing;	/* not used */
+{
+    syn_cmd_onoff(eap, "syntax");
+}
+
+/*
+ * Handle ":syntax enable" command.
+ */
+/* ARGSUSED */
+    static void
+syn_cmd_enable(eap, syncing)
+    exarg_T	*eap;
+    int		syncing;	/* not used */
+{
+    set_internal_string_var((char_u *)"syntax_cmd", (char_u *)"enable");
+    syn_cmd_onoff(eap, "syntax");
+    do_unlet((char_u *)"g:syntax_cmd", TRUE);
+}
+
+/*
+ * Handle ":syntax reset" command.
+ */
+/* ARGSUSED */
+    static void
+syn_cmd_reset(eap, syncing)
+    exarg_T	*eap;
+    int		syncing;	/* not used */
+{
+    eap->nextcmd = check_nextcmd(eap->arg);
+    if (!eap->skip)
+    {
+	set_internal_string_var((char_u *)"syntax_cmd", (char_u *)"reset");
+	do_cmdline_cmd((char_u *)"runtime! syntax/syncolor.vim");
+	do_unlet((char_u *)"g:syntax_cmd", TRUE);
+    }
+}
+
+/*
+ * Handle ":syntax manual" command.
+ */
+/* ARGSUSED */
+    static void
+syn_cmd_manual(eap, syncing)
+    exarg_T	*eap;
+    int		syncing;	/* not used */
+{
+    syn_cmd_onoff(eap, "manual");
+}
+
+/*
+ * Handle ":syntax off" command.
+ */
+/* ARGSUSED */
+    static void
+syn_cmd_off(eap, syncing)
+    exarg_T	*eap;
+    int		syncing;	/* not used */
+{
+    syn_cmd_onoff(eap, "nosyntax");
+}
+
+    static void
+syn_cmd_onoff(eap, name)
+    exarg_T	*eap;
+    char	*name;
+{
+    char_u	buf[100];
+
+    eap->nextcmd = check_nextcmd(eap->arg);
+    if (!eap->skip)
+    {
+	STRCPY(buf, "so ");
+	vim_snprintf((char *)buf + 3, sizeof(buf) - 3, SYNTAX_FNAME, name);
+	do_cmdline_cmd(buf);
+    }
+}
+
+/*
+ * Handle ":syntax [list]" command: list current syntax words.
+ */
+    static void
+syn_cmd_list(eap, syncing)
+    exarg_T	*eap;
+    int		syncing;	    /* when TRUE: list syncing items */
+{
+    char_u	*arg = eap->arg;
+    int		id;
+    char_u	*arg_end;
+
+    eap->nextcmd = find_nextcmd(arg);
+    if (eap->skip)
+	return;
+
+    if (!syntax_present(curbuf))
+    {
+	MSG(_("No Syntax items defined for this buffer"));
+	return;
+    }
+
+    if (syncing)
+    {
+	if (curbuf->b_syn_sync_flags & SF_CCOMMENT)
+	{
+	    MSG_PUTS(_("syncing on C-style comments"));
+	    syn_lines_msg();
+	    syn_match_msg();
+	    return;
+	}
+	else if (!(curbuf->b_syn_sync_flags & SF_MATCH))
+	{
+	    if (curbuf->b_syn_sync_minlines == 0)
+		MSG_PUTS(_("no syncing"));
+	    else
+	    {
+		MSG_PUTS(_("syncing starts "));
+		msg_outnum(curbuf->b_syn_sync_minlines);
+		MSG_PUTS(_(" lines before top line"));
+		syn_match_msg();
+	    }
+	    return;
+	}
+	MSG_PUTS_TITLE(_("\n--- Syntax sync items ---"));
+	if (curbuf->b_syn_sync_minlines > 0
+		|| curbuf->b_syn_sync_maxlines > 0
+		|| curbuf->b_syn_sync_linebreaks > 0)
+	{
+	    MSG_PUTS(_("\nsyncing on items"));
+	    syn_lines_msg();
+	    syn_match_msg();
+	}
+    }
+    else
+	MSG_PUTS_TITLE(_("\n--- Syntax items ---"));
+    if (ends_excmd(*arg))
+    {
+	/*
+	 * No argument: List all group IDs and all syntax clusters.
+	 */
+	for (id = 1; id <= highlight_ga.ga_len && !got_int; ++id)
+	    syn_list_one(id, syncing, FALSE);
+	for (id = 0; id < curbuf->b_syn_clusters.ga_len && !got_int; ++id)
+	    syn_list_cluster(id);
+    }
+    else
+    {
+	/*
+	 * List the group IDs and syntax clusters that are in the argument.
+	 */
+	while (!ends_excmd(*arg) && !got_int)
+	{
+	    arg_end = skiptowhite(arg);
+	    if (*arg == '@')
+	    {
+		id = syn_scl_namen2id(arg + 1, (int)(arg_end - arg - 1));
+		if (id == 0)
+		    EMSG2(_("E392: No such syntax cluster: %s"), arg);
+		else
+		    syn_list_cluster(id - SYNID_CLUSTER);
+	    }
+	    else
+	    {
+		id = syn_namen2id(arg, (int)(arg_end - arg));
+		if (id == 0)
+		    EMSG2(_(e_nogroup), arg);
+		else
+		    syn_list_one(id, syncing, TRUE);
+	    }
+	    arg = skipwhite(arg_end);
+	}
+    }
+    eap->nextcmd = check_nextcmd(arg);
+}
+
+    static void
+syn_lines_msg()
+{
+    if (curbuf->b_syn_sync_maxlines > 0 || curbuf->b_syn_sync_minlines > 0)
+    {
+	MSG_PUTS("; ");
+	if (curbuf->b_syn_sync_minlines > 0)
+	{
+	    MSG_PUTS(_("minimal "));
+	    msg_outnum(curbuf->b_syn_sync_minlines);
+	    if (curbuf->b_syn_sync_maxlines)
+		MSG_PUTS(", ");
+	}
+	if (curbuf->b_syn_sync_maxlines > 0)
+	{
+	    MSG_PUTS(_("maximal "));
+	    msg_outnum(curbuf->b_syn_sync_maxlines);
+	}
+	MSG_PUTS(_(" lines before top line"));
+    }
+}
+
+    static void
+syn_match_msg()
+{
+    if (curbuf->b_syn_sync_linebreaks > 0)
+    {
+	MSG_PUTS(_("; match "));
+	msg_outnum(curbuf->b_syn_sync_linebreaks);
+	MSG_PUTS(_(" line breaks"));
+    }
+}
+
+static int  last_matchgroup;
+
+struct name_list
+{
+    int		flag;
+    char	*name;
+};
+
+static void syn_list_flags __ARGS((struct name_list *nl, int flags, int attr));
+
+/*
+ * List one syntax item, for ":syntax" or "syntax list syntax_name".
+ */
+    static void
+syn_list_one(id, syncing, link_only)
+    int		id;
+    int		syncing;	    /* when TRUE: list syncing items */
+    int		link_only;	    /* when TRUE; list link-only too */
+{
+    int		attr;
+    int		idx;
+    int		did_header = FALSE;
+    synpat_T	*spp;
+    static struct name_list namelist1[] =
+		{
+		    {HL_DISPLAY, "display"},
+		    {HL_CONTAINED, "contained"},
+		    {HL_ONELINE, "oneline"},
+		    {HL_KEEPEND, "keepend"},
+		    {HL_EXTEND, "extend"},
+		    {HL_EXCLUDENL, "excludenl"},
+		    {HL_TRANSP, "transparent"},
+		    {HL_FOLD, "fold"},
+		    {0, NULL}
+		};
+    static struct name_list namelist2[] =
+		{
+		    {HL_SKIPWHITE, "skipwhite"},
+		    {HL_SKIPNL, "skipnl"},
+		    {HL_SKIPEMPTY, "skipempty"},
+		    {0, NULL}
+		};
+
+    attr = hl_attr(HLF_D);		/* highlight like directories */
+
+    /* list the keywords for "id" */
+    if (!syncing)
+    {
+	did_header = syn_list_keywords(id, &curbuf->b_keywtab, FALSE, attr);
+	did_header = syn_list_keywords(id, &curbuf->b_keywtab_ic,
+							    did_header, attr);
+    }
+
+    /* list the patterns for "id" */
+    for (idx = 0; idx < curbuf->b_syn_patterns.ga_len && !got_int; ++idx)
+    {
+	spp = &(SYN_ITEMS(curbuf)[idx]);
+	if (spp->sp_syn.id != id || spp->sp_syncing != syncing)
+	    continue;
+
+	(void)syn_list_header(did_header, 999, id);
+	did_header = TRUE;
+	last_matchgroup = 0;
+	if (spp->sp_type == SPTYPE_MATCH)
+	{
+	    put_pattern("match", ' ', spp, attr);
+	    msg_putchar(' ');
+	}
+	else if (spp->sp_type == SPTYPE_START)
+	{
+	    while (SYN_ITEMS(curbuf)[idx].sp_type == SPTYPE_START)
+		put_pattern("start", '=', &SYN_ITEMS(curbuf)[idx++], attr);
+	    if (SYN_ITEMS(curbuf)[idx].sp_type == SPTYPE_SKIP)
+		put_pattern("skip", '=', &SYN_ITEMS(curbuf)[idx++], attr);
+	    while (idx < curbuf->b_syn_patterns.ga_len
+			      && SYN_ITEMS(curbuf)[idx].sp_type == SPTYPE_END)
+		put_pattern("end", '=', &SYN_ITEMS(curbuf)[idx++], attr);
+	    --idx;
+	    msg_putchar(' ');
+	}
+	syn_list_flags(namelist1, spp->sp_flags, attr);
+
+	if (spp->sp_cont_list != NULL)
+	    put_id_list((char_u *)"contains", spp->sp_cont_list, attr);
+
+	if (spp->sp_syn.cont_in_list != NULL)
+	    put_id_list((char_u *)"containedin",
+					      spp->sp_syn.cont_in_list, attr);
+
+	if (spp->sp_next_list != NULL)
+	{
+	    put_id_list((char_u *)"nextgroup", spp->sp_next_list, attr);
+	    syn_list_flags(namelist2, spp->sp_flags, attr);
+	}
+	if (spp->sp_flags & (HL_SYNC_HERE|HL_SYNC_THERE))
+	{
+	    if (spp->sp_flags & HL_SYNC_HERE)
+		msg_puts_attr((char_u *)"grouphere", attr);
+	    else
+		msg_puts_attr((char_u *)"groupthere", attr);
+	    msg_putchar(' ');
+	    if (spp->sp_sync_idx >= 0)
+		msg_outtrans(HL_TABLE()[SYN_ITEMS(curbuf)
+				   [spp->sp_sync_idx].sp_syn.id - 1].sg_name);
+	    else
+		MSG_PUTS("NONE");
+	    msg_putchar(' ');
+	}
+    }
+
+    /* list the link, if there is one */
+    if (HL_TABLE()[id - 1].sg_link && (did_header || link_only) && !got_int)
+    {
+	(void)syn_list_header(did_header, 999, id);
+	msg_puts_attr((char_u *)"links to", attr);
+	msg_putchar(' ');
+	msg_outtrans(HL_TABLE()[HL_TABLE()[id - 1].sg_link - 1].sg_name);
+    }
+}
+
+    static void
+syn_list_flags(nl, flags, attr)
+    struct name_list	*nl;
+    int			flags;
+    int			attr;
+{
+    int		i;
+
+    for (i = 0; nl[i].flag != 0; ++i)
+	if (flags & nl[i].flag)
+	{
+	    msg_puts_attr((char_u *)nl[i].name, attr);
+	    msg_putchar(' ');
+	}
+}
+
+/*
+ * List one syntax cluster, for ":syntax" or "syntax list syntax_name".
+ */
+    static void
+syn_list_cluster(id)
+    int id;
+{
+    int	    endcol = 15;
+
+    /* slight hack:  roughly duplicate the guts of syn_list_header() */
+    msg_putchar('\n');
+    msg_outtrans(SYN_CLSTR(curbuf)[id].scl_name);
+
+    if (msg_col >= endcol)	/* output at least one space */
+	endcol = msg_col + 1;
+    if (Columns <= endcol)	/* avoid hang for tiny window */
+	endcol = Columns - 1;
+
+    msg_advance(endcol);
+    if (SYN_CLSTR(curbuf)[id].scl_list != NULL)
+    {
+	put_id_list((char_u *)"cluster", SYN_CLSTR(curbuf)[id].scl_list,
+		    hl_attr(HLF_D));
+    }
+    else
+    {
+	msg_puts_attr((char_u *)"cluster", hl_attr(HLF_D));
+	msg_puts((char_u *)"=NONE");
+    }
+}
+
+    static void
+put_id_list(name, list, attr)
+    char_u	*name;
+    short	*list;
+    int		attr;
+{
+    short		*p;
+
+    msg_puts_attr(name, attr);
+    msg_putchar('=');
+    for (p = list; *p; ++p)
+    {
+	if (*p >= SYNID_ALLBUT && *p < SYNID_TOP)
+	{
+	    if (p[1])
+		MSG_PUTS("ALLBUT");
+	    else
+		MSG_PUTS("ALL");
+	}
+	else if (*p >= SYNID_TOP && *p < SYNID_CONTAINED)
+	{
+	    MSG_PUTS("TOP");
+	}
+	else if (*p >= SYNID_CONTAINED && *p < SYNID_CLUSTER)
+	{
+	    MSG_PUTS("CONTAINED");
+	}
+	else if (*p >= SYNID_CLUSTER)
+	{
+	    short scl_id = *p - SYNID_CLUSTER;
+
+	    msg_putchar('@');
+	    msg_outtrans(SYN_CLSTR(curbuf)[scl_id].scl_name);
+	}
+	else
+	    msg_outtrans(HL_TABLE()[*p - 1].sg_name);
+	if (p[1])
+	    msg_putchar(',');
+    }
+    msg_putchar(' ');
+}
+
+    static void
+put_pattern(s, c, spp, attr)
+    char	*s;
+    int		c;
+    synpat_T	*spp;
+    int		attr;
+{
+    long	n;
+    int		mask;
+    int		first;
+    static char	*sepchars = "/+=-#@\"|'^&";
+    int		i;
+
+    /* May have to write "matchgroup=group" */
+    if (last_matchgroup != spp->sp_syn_match_id)
+    {
+	last_matchgroup = spp->sp_syn_match_id;
+	msg_puts_attr((char_u *)"matchgroup", attr);
+	msg_putchar('=');
+	if (last_matchgroup == 0)
+	    msg_outtrans((char_u *)"NONE");
+	else
+	    msg_outtrans(HL_TABLE()[last_matchgroup - 1].sg_name);
+	msg_putchar(' ');
+    }
+
+    /* output the name of the pattern and an '=' or ' ' */
+    msg_puts_attr((char_u *)s, attr);
+    msg_putchar(c);
+
+    /* output the pattern, in between a char that is not in the pattern */
+    for (i = 0; vim_strchr(spp->sp_pattern, sepchars[i]) != NULL; )
+	if (sepchars[++i] == NUL)
+	{
+	    i = 0;	/* no good char found, just use the first one */
+	    break;
+	}
+    msg_putchar(sepchars[i]);
+    msg_outtrans(spp->sp_pattern);
+    msg_putchar(sepchars[i]);
+
+    /* output any pattern options */
+    first = TRUE;
+    for (i = 0; i < SPO_COUNT; ++i)
+    {
+	mask = (1 << i);
+	if (spp->sp_off_flags & (mask + (mask << SPO_COUNT)))
+	{
+	    if (!first)
+		msg_putchar(',');	/* separate with commas */
+	    msg_puts((char_u *)spo_name_tab[i]);
+	    n = spp->sp_offsets[i];
+	    if (i != SPO_LC_OFF)
+	    {
+		if (spp->sp_off_flags & mask)
+		    msg_putchar('s');
+		else
+		    msg_putchar('e');
+		if (n > 0)
+		    msg_putchar('+');
+	    }
+	    if (n || i == SPO_LC_OFF)
+		msg_outnum(n);
+	    first = FALSE;
+	}
+    }
+    msg_putchar(' ');
+}
+
+/*
+ * List or clear the keywords for one syntax group.
+ * Return TRUE if the header has been printed.
+ */
+    static int
+syn_list_keywords(id, ht, did_header, attr)
+    int		id;
+    hashtab_T	*ht;
+    int		did_header;		/* header has already been printed */
+    int		attr;
+{
+    int		outlen;
+    hashitem_T	*hi;
+    keyentry_T	*kp;
+    int		todo;
+    int		prev_contained = 0;
+    short	*prev_next_list = NULL;
+    short	*prev_cont_in_list = NULL;
+    int		prev_skipnl = 0;
+    int		prev_skipwhite = 0;
+    int		prev_skipempty = 0;
+
+    /*
+     * Unfortunately, this list of keywords is not sorted on alphabet but on
+     * hash value...
+     */
+    todo = (int)ht->ht_used;
+    for (hi = ht->ht_array; todo > 0 && !got_int; ++hi)
+    {
+	if (!HASHITEM_EMPTY(hi))
+	{
+	    --todo;
+	    for (kp = HI2KE(hi); kp != NULL && !got_int; kp = kp->ke_next)
+	    {
+		if (kp->k_syn.id == id)
+		{
+		    if (prev_contained != (kp->flags & HL_CONTAINED)
+			    || prev_skipnl != (kp->flags & HL_SKIPNL)
+			    || prev_skipwhite != (kp->flags & HL_SKIPWHITE)
+			    || prev_skipempty != (kp->flags & HL_SKIPEMPTY)
+			    || prev_cont_in_list != kp->k_syn.cont_in_list
+			    || prev_next_list != kp->next_list)
+			outlen = 9999;
+		    else
+			outlen = (int)STRLEN(kp->keyword);
+		    /* output "contained" and "nextgroup" on each line */
+		    if (syn_list_header(did_header, outlen, id))
+		    {
+			prev_contained = 0;
+			prev_next_list = NULL;
+			prev_cont_in_list = NULL;
+			prev_skipnl = 0;
+			prev_skipwhite = 0;
+			prev_skipempty = 0;
+		    }
+		    did_header = TRUE;
+		    if (prev_contained != (kp->flags & HL_CONTAINED))
+		    {
+			msg_puts_attr((char_u *)"contained", attr);
+			msg_putchar(' ');
+			prev_contained = (kp->flags & HL_CONTAINED);
+		    }
+		    if (kp->k_syn.cont_in_list != prev_cont_in_list)
+		    {
+			put_id_list((char_u *)"containedin",
+						kp->k_syn.cont_in_list, attr);
+			msg_putchar(' ');
+			prev_cont_in_list = kp->k_syn.cont_in_list;
+		    }
+		    if (kp->next_list != prev_next_list)
+		    {
+			put_id_list((char_u *)"nextgroup", kp->next_list, attr);
+			msg_putchar(' ');
+			prev_next_list = kp->next_list;
+			if (kp->flags & HL_SKIPNL)
+			{
+			    msg_puts_attr((char_u *)"skipnl", attr);
+			    msg_putchar(' ');
+			    prev_skipnl = (kp->flags & HL_SKIPNL);
+			}
+			if (kp->flags & HL_SKIPWHITE)
+			{
+			    msg_puts_attr((char_u *)"skipwhite", attr);
+			    msg_putchar(' ');
+			    prev_skipwhite = (kp->flags & HL_SKIPWHITE);
+			}
+			if (kp->flags & HL_SKIPEMPTY)
+			{
+			    msg_puts_attr((char_u *)"skipempty", attr);
+			    msg_putchar(' ');
+			    prev_skipempty = (kp->flags & HL_SKIPEMPTY);
+			}
+		    }
+		    msg_outtrans(kp->keyword);
+		}
+	    }
+	}
+    }
+
+    return did_header;
+}
+
+    static void
+syn_clear_keyword(id, ht)
+    int		id;
+    hashtab_T	*ht;
+{
+    hashitem_T	*hi;
+    keyentry_T	*kp;
+    keyentry_T	*kp_prev;
+    keyentry_T	*kp_next;
+    int		todo;
+
+    hash_lock(ht);
+    todo = (int)ht->ht_used;
+    for (hi = ht->ht_array; todo > 0; ++hi)
+    {
+	if (!HASHITEM_EMPTY(hi))
+	{
+	    --todo;
+	    kp_prev = NULL;
+	    for (kp = HI2KE(hi); kp != NULL; )
+	    {
+		if (kp->k_syn.id == id)
+		{
+		    kp_next = kp->ke_next;
+		    if (kp_prev == NULL)
+		    {
+			if (kp_next == NULL)
+			    hash_remove(ht, hi);
+			else
+			    hi->hi_key = KE2HIKEY(kp_next);
+		    }
+		    else
+			kp_prev->ke_next = kp_next;
+		    vim_free(kp->next_list);
+		    vim_free(kp->k_syn.cont_in_list);
+		    vim_free(kp);
+		    kp = kp_next;
+		}
+		else
+		{
+		    kp_prev = kp;
+		    kp = kp->ke_next;
+		}
+	    }
+	}
+    }
+    hash_unlock(ht);
+}
+
+/*
+ * Clear a whole keyword table.
+ */
+    static void
+clear_keywtab(ht)
+    hashtab_T	*ht;
+{
+    hashitem_T	*hi;
+    int		todo;
+    keyentry_T	*kp;
+    keyentry_T	*kp_next;
+
+    todo = (int)ht->ht_used;
+    for (hi = ht->ht_array; todo > 0; ++hi)
+    {
+	if (!HASHITEM_EMPTY(hi))
+	{
+	    --todo;
+	    kp = HI2KE(hi);
+	    for (kp = HI2KE(hi); kp != NULL; kp = kp_next)
+	    {
+		kp_next = kp->ke_next;
+		vim_free(kp->next_list);
+		vim_free(kp->k_syn.cont_in_list);
+		vim_free(kp);
+	    }
+	}
+    }
+    hash_clear(ht);
+    hash_init(ht);
+}
+
+/*
+ * Add a keyword to the list of keywords.
+ */
+    static void
+add_keyword(name, id, flags, cont_in_list, next_list)
+    char_u	*name;	    /* name of keyword */
+    int		id;	    /* group ID for this keyword */
+    int		flags;	    /* flags for this keyword */
+    short	*cont_in_list; /* containedin for this keyword */
+    short	*next_list; /* nextgroup for this keyword */
+{
+    keyentry_T	*kp;
+    hashtab_T	*ht;
+    hashitem_T	*hi;
+    char_u	*name_ic;
+    long_u	hash;
+    char_u	name_folded[MAXKEYWLEN + 1];
+
+    if (curbuf->b_syn_ic)
+	name_ic = str_foldcase(name, (int)STRLEN(name),
+						 name_folded, MAXKEYWLEN + 1);
+    else
+	name_ic = name;
+    kp = (keyentry_T *)alloc((int)(sizeof(keyentry_T) + STRLEN(name_ic)));
+    if (kp == NULL)
+	return;
+    STRCPY(kp->keyword, name_ic);
+    kp->k_syn.id = id;
+    kp->k_syn.inc_tag = current_syn_inc_tag;
+    kp->flags = flags;
+    kp->k_syn.cont_in_list = copy_id_list(cont_in_list);
+    if (cont_in_list != NULL)
+	curbuf->b_syn_containedin = TRUE;
+    kp->next_list = copy_id_list(next_list);
+
+    if (curbuf->b_syn_ic)
+	ht = &curbuf->b_keywtab_ic;
+    else
+	ht = &curbuf->b_keywtab;
+
+    hash = hash_hash(kp->keyword);
+    hi = hash_lookup(ht, kp->keyword, hash);
+    if (HASHITEM_EMPTY(hi))
+    {
+	/* new keyword, add to hashtable */
+	kp->ke_next = NULL;
+	hash_add_item(ht, hi, kp->keyword, hash);
+    }
+    else
+    {
+	/* keyword already exists, prepend to list */
+	kp->ke_next = HI2KE(hi);
+	hi->hi_key = KE2HIKEY(kp);
+    }
+}
+
+/*
+ * Get the start and end of the group name argument.
+ * Return a pointer to the first argument.
+ * Return NULL if the end of the command was found instead of further args.
+ */
+    static char_u *
+get_group_name(arg, name_end)
+    char_u	*arg;		/* start of the argument */
+    char_u	**name_end;	/* pointer to end of the name */
+{
+    char_u	*rest;
+
+    *name_end = skiptowhite(arg);
+    rest = skipwhite(*name_end);
+
+    /*
+     * Check if there are enough arguments.  The first argument may be a
+     * pattern, where '|' is allowed, so only check for NUL.
+     */
+    if (ends_excmd(*arg) || *rest == NUL)
+	return NULL;
+    return rest;
+}
+
+/*
+ * Check for syntax command option arguments.
+ * This can be called at any place in the list of arguments, and just picks
+ * out the arguments that are known.  Can be called several times in a row to
+ * collect all options in between other arguments.
+ * Return a pointer to the next argument (which isn't an option).
+ * Return NULL for any error;
+ */
+    static char_u *
+get_syn_options(arg, opt)
+    char_u	    *arg;		/* next argument to be checked */
+    syn_opt_arg_T   *opt;		/* various things */
+{
+    char_u	*gname_start, *gname;
+    int		syn_id;
+    int		len;
+    char	*p;
+    int		i;
+    int		fidx;
+    static struct flag
+    {
+	char	*name;
+	int	argtype;
+	int	flags;
+    } flagtab[] = { {"cCoOnNtTaAiInNeEdD",	0,	HL_CONTAINED},
+		    {"oOnNeElLiInNeE",		0,	HL_ONELINE},
+		    {"kKeEeEpPeEnNdD",		0,	HL_KEEPEND},
+		    {"eExXtTeEnNdD",		0,	HL_EXTEND},
+		    {"eExXcClLuUdDeEnNlL",	0,	HL_EXCLUDENL},
+		    {"tTrRaAnNsSpPaArReEnNtT",	0,	HL_TRANSP},
+		    {"sSkKiIpPnNlL",		0,	HL_SKIPNL},
+		    {"sSkKiIpPwWhHiItTeE",	0,	HL_SKIPWHITE},
+		    {"sSkKiIpPeEmMpPtTyY",	0,	HL_SKIPEMPTY},
+		    {"gGrRoOuUpPhHeErReE",	0,	HL_SYNC_HERE},
+		    {"gGrRoOuUpPtThHeErReE",	0,	HL_SYNC_THERE},
+		    {"dDiIsSpPlLaAyY",		0,	HL_DISPLAY},
+		    {"fFoOlLdD",		0,	HL_FOLD},
+		    {"cCoOnNtTaAiInNsS",	1,	0},
+		    {"cCoOnNtTaAiInNeEdDiInN",	2,	0},
+		    {"nNeExXtTgGrRoOuUpP",	3,	0},
+		};
+    static char *first_letters = "cCoOkKeEtTsSgGdDfFnN";
+
+    if (arg == NULL)		/* already detected error */
+	return NULL;
+
+    for (;;)
+    {
+	/*
+	 * This is used very often when a large number of keywords is defined.
+	 * Need to skip quickly when no option name is found.
+	 * Also avoid tolower(), it's slow.
+	 */
+	if (strchr(first_letters, *arg) == NULL)
+	    break;
+
+	for (fidx = sizeof(flagtab) / sizeof(struct flag); --fidx >= 0; )
+	{
+	    p = flagtab[fidx].name;
+	    for (i = 0, len = 0; p[i] != NUL; i += 2, ++len)
+		if (arg[len] != p[i] && arg[len] != p[i + 1])
+		    break;
+	    if (p[i] == NUL && (vim_iswhite(arg[len])
+				    || (flagtab[fidx].argtype > 0
+					 ? arg[len] == '='
+					 : ends_excmd(arg[len]))))
+	    {
+		if (opt->keyword
+			&& (flagtab[fidx].flags == HL_DISPLAY
+			    || flagtab[fidx].flags == HL_FOLD
+			    || flagtab[fidx].flags == HL_EXTEND))
+		    /* treat "display", "fold" and "extend" as a keyword */
+		    fidx = -1;
+		break;
+	    }
+	}
+	if (fidx < 0)	    /* no match found */
+	    break;
+
+	if (flagtab[fidx].argtype == 1)
+	{
+	    if (!opt->has_cont_list)
+	    {
+		EMSG(_("E395: contains argument not accepted here"));
+		return NULL;
+	    }
+	    if (get_id_list(&arg, 8, &opt->cont_list) == FAIL)
+		return NULL;
+	}
+	else if (flagtab[fidx].argtype == 2)
+	{
+#if 0	    /* cannot happen */
+	    if (opt->cont_in_list == NULL)
+	    {
+		EMSG(_("E396: containedin argument not accepted here"));
+		return NULL;
+	    }
+#endif
+	    if (get_id_list(&arg, 11, &opt->cont_in_list) == FAIL)
+		return NULL;
+	}
+	else if (flagtab[fidx].argtype == 3)
+	{
+	    if (get_id_list(&arg, 9, &opt->next_list) == FAIL)
+		return NULL;
+	}
+	else
+	{
+	    opt->flags |= flagtab[fidx].flags;
+	    arg = skipwhite(arg + len);
+
+	    if (flagtab[fidx].flags == HL_SYNC_HERE
+		    || flagtab[fidx].flags == HL_SYNC_THERE)
+	    {
+		if (opt->sync_idx == NULL)
+		{
+		    EMSG(_("E393: group[t]here not accepted here"));
+		    return NULL;
+		}
+		gname_start = arg;
+		arg = skiptowhite(arg);
+		if (gname_start == arg)
+		    return NULL;
+		gname = vim_strnsave(gname_start, (int)(arg - gname_start));
+		if (gname == NULL)
+		    return NULL;
+		if (STRCMP(gname, "NONE") == 0)
+		    *opt->sync_idx = NONE_IDX;
+		else
+		{
+		    syn_id = syn_name2id(gname);
+		    for (i = curbuf->b_syn_patterns.ga_len; --i >= 0; )
+			if (SYN_ITEMS(curbuf)[i].sp_syn.id == syn_id
+			      && SYN_ITEMS(curbuf)[i].sp_type == SPTYPE_START)
+			{
+			    *opt->sync_idx = i;
+			    break;
+			}
+		    if (i < 0)
+		    {
+			EMSG2(_("E394: Didn't find region item for %s"), gname);
+			vim_free(gname);
+			return NULL;
+		    }
+		}
+
+		vim_free(gname);
+		arg = skipwhite(arg);
+	    }
+#ifdef FEAT_FOLDING
+	    else if (flagtab[fidx].flags == HL_FOLD
+						&& foldmethodIsSyntax(curwin))
+		/* Need to update folds later. */
+		foldUpdateAll(curwin);
+#endif
+	}
+    }
+
+    return arg;
+}
+
+/*
+ * Adjustments to syntax item when declared in a ":syn include"'d file.
+ * Set the contained flag, and if the item is not already contained, add it
+ * to the specified top-level group, if any.
+ */
+    static void
+syn_incl_toplevel(id, flagsp)
+    int		id;
+    int		*flagsp;
+{
+    if ((*flagsp & HL_CONTAINED) || curbuf->b_syn_topgrp == 0)
+	return;
+    *flagsp |= HL_CONTAINED;
+    if (curbuf->b_syn_topgrp >= SYNID_CLUSTER)
+    {
+	/* We have to alloc this, because syn_combine_list() will free it. */
+	short	    *grp_list = (short *)alloc((unsigned)(2 * sizeof(short)));
+	int	    tlg_id = curbuf->b_syn_topgrp - SYNID_CLUSTER;
+
+	if (grp_list != NULL)
+	{
+	    grp_list[0] = id;
+	    grp_list[1] = 0;
+	    syn_combine_list(&SYN_CLSTR(curbuf)[tlg_id].scl_list, &grp_list,
+			 CLUSTER_ADD);
+	}
+    }
+}
+
+/*
+ * Handle ":syntax include [@{group-name}] filename" command.
+ */
+/* ARGSUSED */
+    static void
+syn_cmd_include(eap, syncing)
+    exarg_T	*eap;
+    int		syncing;	    /* not used */
+{
+    char_u	*arg = eap->arg;
+    int		sgl_id = 1;
+    char_u	*group_name_end;
+    char_u	*rest;
+    char_u	*errormsg = NULL;
+    int		prev_toplvl_grp;
+    int		prev_syn_inc_tag;
+    int		source = FALSE;
+
+    eap->nextcmd = find_nextcmd(arg);
+    if (eap->skip)
+	return;
+
+    if (arg[0] == '@')
+    {
+	++arg;
+	rest = get_group_name(arg, &group_name_end);
+	if (rest == NULL)
+	{
+	    EMSG((char_u *)_("E397: Filename required"));
+	    return;
+	}
+	sgl_id = syn_check_cluster(arg, (int)(group_name_end - arg));
+	/* separate_nextcmd() and expand_filename() depend on this */
+	eap->arg = rest;
+    }
+
+    /*
+     * Everything that's left, up to the next command, should be the
+     * filename to include.
+     */
+    eap->argt |= (XFILE | NOSPC);
+    separate_nextcmd(eap);
+    if (*eap->arg == '<' || *eap->arg == '$' || mch_isFullName(eap->arg))
+    {
+	/* For an absolute path, "$VIM/..." or "<sfile>.." we ":source" the
+	 * file.  Need to expand the file name first.  In other cases
+	 * ":runtime!" is used. */
+	source = TRUE;
+	if (expand_filename(eap, syn_cmdlinep, &errormsg) == FAIL)
+	{
+	    if (errormsg != NULL)
+		EMSG(errormsg);
+	    return;
+	}
+    }
+
+    /*
+     * Save and restore the existing top-level grouplist id and ":syn
+     * include" tag around the actual inclusion.
+     */
+    prev_syn_inc_tag = current_syn_inc_tag;
+    current_syn_inc_tag = ++running_syn_inc_tag;
+    prev_toplvl_grp = curbuf->b_syn_topgrp;
+    curbuf->b_syn_topgrp = sgl_id;
+    if (source ? do_source(eap->arg, FALSE, FALSE) == FAIL
+				: source_runtime(eap->arg, DOSO_NONE) == FAIL)
+	EMSG2(_(e_notopen), eap->arg);
+    curbuf->b_syn_topgrp = prev_toplvl_grp;
+    current_syn_inc_tag = prev_syn_inc_tag;
+}
+
+/*
+ * Handle ":syntax keyword {group-name} [{option}] keyword .." command.
+ */
+/* ARGSUSED */
+    static void
+syn_cmd_keyword(eap, syncing)
+    exarg_T	*eap;
+    int		syncing;	    /* not used */
+{
+    char_u	*arg = eap->arg;
+    char_u	*group_name_end;
+    int		syn_id;
+    char_u	*rest;
+    char_u	*keyword_copy;
+    char_u	*p;
+    char_u	*kw;
+    syn_opt_arg_T syn_opt_arg;
+    int		cnt;
+
+    rest = get_group_name(arg, &group_name_end);
+
+    if (rest != NULL)
+    {
+	syn_id = syn_check_group(arg, (int)(group_name_end - arg));
+
+	/* allocate a buffer, for removing the backslashes in the keyword */
+	keyword_copy = alloc((unsigned)STRLEN(rest) + 1);
+	if (keyword_copy != NULL)
+	{
+	    syn_opt_arg.flags = 0;
+	    syn_opt_arg.keyword = TRUE;
+	    syn_opt_arg.sync_idx = NULL;
+	    syn_opt_arg.has_cont_list = FALSE;
+	    syn_opt_arg.cont_in_list = NULL;
+	    syn_opt_arg.next_list = NULL;
+
+	    /*
+	     * The options given apply to ALL keywords, so all options must be
+	     * found before keywords can be created.
+	     * 1: collect the options and copy the keywords to keyword_copy.
+	     */
+	    cnt = 0;
+	    p = keyword_copy;
+	    for ( ; rest != NULL && !ends_excmd(*rest); rest = skipwhite(rest))
+	    {
+		rest = get_syn_options(rest, &syn_opt_arg);
+		if (rest == NULL || ends_excmd(*rest))
+		    break;
+		/* Copy the keyword, removing backslashes, and add a NUL. */
+		while (*rest != NUL && !vim_iswhite(*rest))
+		{
+		    if (*rest == '\\' && rest[1] != NUL)
+			++rest;
+		    *p++ = *rest++;
+		}
+		*p++ = NUL;
+		++cnt;
+	    }
+
+	    if (!eap->skip)
+	    {
+		/* Adjust flags for use of ":syn include". */
+		syn_incl_toplevel(syn_id, &syn_opt_arg.flags);
+
+		/*
+		 * 2: Add an entry for each keyword.
+		 */
+		for (kw = keyword_copy; --cnt >= 0; kw += STRLEN(kw) + 1)
+		{
+		    for (p = vim_strchr(kw, '['); ; )
+		    {
+			if (p != NULL)
+			    *p = NUL;
+			add_keyword(kw, syn_id, syn_opt_arg.flags,
+						     syn_opt_arg.cont_in_list,
+						       syn_opt_arg.next_list);
+			if (p == NULL)
+			    break;
+			if (p[1] == NUL)
+			{
+			    EMSG2(_("E789: Missing ']': %s"), kw);
+			    kw = p + 2;		/* skip over the NUL */
+			    break;
+			}
+			if (p[1] == ']')
+			{
+			    kw = p + 1;		/* skip over the "]" */
+			    break;
+			}
+#ifdef FEAT_MBYTE
+			if (has_mbyte)
+			{
+			    int l = (*mb_ptr2len)(p + 1);
+
+			    mch_memmove(p, p + 1, l);
+			    p += l;
+			}
+			else
+#endif
+			{
+			    p[0] = p[1];
+			    ++p;
+			}
+		    }
+		}
+	    }
+
+	    vim_free(keyword_copy);
+	    vim_free(syn_opt_arg.cont_in_list);
+	    vim_free(syn_opt_arg.next_list);
+	}
+    }
+
+    if (rest != NULL)
+	eap->nextcmd = check_nextcmd(rest);
+    else
+	EMSG2(_(e_invarg2), arg);
+
+    redraw_curbuf_later(SOME_VALID);
+    syn_stack_free_all(curbuf);		/* Need to recompute all syntax. */
+}
+
+/*
+ * Handle ":syntax match {name} [{options}] {pattern} [{options}]".
+ *
+ * Also ":syntax sync match {name} [[grouphere | groupthere] {group-name}] .."
+ */
+    static void
+syn_cmd_match(eap, syncing)
+    exarg_T	*eap;
+    int		syncing;	    /* TRUE for ":syntax sync match .. " */
+{
+    char_u	*arg = eap->arg;
+    char_u	*group_name_end;
+    char_u	*rest;
+    synpat_T	item;		/* the item found in the line */
+    int		syn_id;
+    int		idx;
+    syn_opt_arg_T syn_opt_arg;
+    int		sync_idx = 0;
+
+    /* Isolate the group name, check for validity */
+    rest = get_group_name(arg, &group_name_end);
+
+    /* Get options before the pattern */
+    syn_opt_arg.flags = 0;
+    syn_opt_arg.keyword = FALSE;
+    syn_opt_arg.sync_idx = syncing ? &sync_idx : NULL;
+    syn_opt_arg.has_cont_list = TRUE;
+    syn_opt_arg.cont_list = NULL;
+    syn_opt_arg.cont_in_list = NULL;
+    syn_opt_arg.next_list = NULL;
+    rest = get_syn_options(rest, &syn_opt_arg);
+
+    /* get the pattern. */
+    init_syn_patterns();
+    vim_memset(&item, 0, sizeof(item));
+    rest = get_syn_pattern(rest, &item);
+    if (vim_regcomp_had_eol() && !(syn_opt_arg.flags & HL_EXCLUDENL))
+	syn_opt_arg.flags |= HL_HAS_EOL;
+
+    /* Get options after the pattern */
+    rest = get_syn_options(rest, &syn_opt_arg);
+
+    if (rest != NULL)		/* all arguments are valid */
+    {
+	/*
+	 * Check for trailing command and illegal trailing arguments.
+	 */
+	eap->nextcmd = check_nextcmd(rest);
+	if (!ends_excmd(*rest) || eap->skip)
+	    rest = NULL;
+	else if (ga_grow(&curbuf->b_syn_patterns, 1) != FAIL
+		&& (syn_id = syn_check_group(arg,
+					   (int)(group_name_end - arg))) != 0)
+	{
+	    syn_incl_toplevel(syn_id, &syn_opt_arg.flags);
+	    /*
+	     * Store the pattern in the syn_items list
+	     */
+	    idx = curbuf->b_syn_patterns.ga_len;
+	    SYN_ITEMS(curbuf)[idx] = item;
+	    SYN_ITEMS(curbuf)[idx].sp_syncing = syncing;
+	    SYN_ITEMS(curbuf)[idx].sp_type = SPTYPE_MATCH;
+	    SYN_ITEMS(curbuf)[idx].sp_syn.id = syn_id;
+	    SYN_ITEMS(curbuf)[idx].sp_syn.inc_tag = current_syn_inc_tag;
+	    SYN_ITEMS(curbuf)[idx].sp_flags = syn_opt_arg.flags;
+	    SYN_ITEMS(curbuf)[idx].sp_sync_idx = sync_idx;
+	    SYN_ITEMS(curbuf)[idx].sp_cont_list = syn_opt_arg.cont_list;
+	    SYN_ITEMS(curbuf)[idx].sp_syn.cont_in_list =
+						     syn_opt_arg.cont_in_list;
+	    if (syn_opt_arg.cont_in_list != NULL)
+		curbuf->b_syn_containedin = TRUE;
+	    SYN_ITEMS(curbuf)[idx].sp_next_list = syn_opt_arg.next_list;
+	    ++curbuf->b_syn_patterns.ga_len;
+
+	    /* remember that we found a match for syncing on */
+	    if (syn_opt_arg.flags & (HL_SYNC_HERE|HL_SYNC_THERE))
+		curbuf->b_syn_sync_flags |= SF_MATCH;
+#ifdef FEAT_FOLDING
+	    if (syn_opt_arg.flags & HL_FOLD)
+		++curbuf->b_syn_folditems;
+#endif
+
+	    redraw_curbuf_later(SOME_VALID);
+	    syn_stack_free_all(curbuf);	/* Need to recompute all syntax. */
+	    return;	/* don't free the progs and patterns now */
+	}
+    }
+
+    /*
+     * Something failed, free the allocated memory.
+     */
+    vim_free(item.sp_prog);
+    vim_free(item.sp_pattern);
+    vim_free(syn_opt_arg.cont_list);
+    vim_free(syn_opt_arg.cont_in_list);
+    vim_free(syn_opt_arg.next_list);
+
+    if (rest == NULL)
+	EMSG2(_(e_invarg2), arg);
+}
+
+/*
+ * Handle ":syntax region {group-name} [matchgroup={group-name}]
+ *		start {start} .. [skip {skip}] end {end} .. [{options}]".
+ */
+    static void
+syn_cmd_region(eap, syncing)
+    exarg_T	*eap;
+    int		syncing;	    /* TRUE for ":syntax sync region .." */
+{
+    char_u		*arg = eap->arg;
+    char_u		*group_name_end;
+    char_u		*rest;			/* next arg, NULL on error */
+    char_u		*key_end;
+    char_u		*key = NULL;
+    char_u		*p;
+    int			item;
+#define ITEM_START	    0
+#define ITEM_SKIP	    1
+#define ITEM_END	    2
+#define ITEM_MATCHGROUP	    3
+    struct pat_ptr
+    {
+	synpat_T	*pp_synp;		/* pointer to syn_pattern */
+	int		pp_matchgroup_id;	/* matchgroup ID */
+	struct pat_ptr	*pp_next;		/* pointer to next pat_ptr */
+    }			*(pat_ptrs[3]);
+					/* patterns found in the line */
+    struct pat_ptr	*ppp;
+    struct pat_ptr	*ppp_next;
+    int			pat_count = 0;		/* nr of syn_patterns found */
+    int			syn_id;
+    int			matchgroup_id = 0;
+    int			not_enough = FALSE;	/* not enough arguments */
+    int			illegal = FALSE;	/* illegal arguments */
+    int			success = FALSE;
+    int			idx;
+    syn_opt_arg_T	syn_opt_arg;
+
+    /* Isolate the group name, check for validity */
+    rest = get_group_name(arg, &group_name_end);
+
+    pat_ptrs[0] = NULL;
+    pat_ptrs[1] = NULL;
+    pat_ptrs[2] = NULL;
+
+    init_syn_patterns();
+
+    syn_opt_arg.flags = 0;
+    syn_opt_arg.keyword = FALSE;
+    syn_opt_arg.sync_idx = NULL;
+    syn_opt_arg.has_cont_list = TRUE;
+    syn_opt_arg.cont_list = NULL;
+    syn_opt_arg.cont_in_list = NULL;
+    syn_opt_arg.next_list = NULL;
+
+    /*
+     * get the options, patterns and matchgroup.
+     */
+    while (rest != NULL && !ends_excmd(*rest))
+    {
+	/* Check for option arguments */
+	rest = get_syn_options(rest, &syn_opt_arg);
+	if (rest == NULL || ends_excmd(*rest))
+	    break;
+
+	/* must be a pattern or matchgroup then */
+	key_end = rest;
+	while (*key_end && !vim_iswhite(*key_end) && *key_end != '=')
+	    ++key_end;
+	vim_free(key);
+	key = vim_strnsave_up(rest, (int)(key_end - rest));
+	if (key == NULL)			/* out of memory */
+	{
+	    rest = NULL;
+	    break;
+	}
+	if (STRCMP(key, "MATCHGROUP") == 0)
+	    item = ITEM_MATCHGROUP;
+	else if (STRCMP(key, "START") == 0)
+	    item = ITEM_START;
+	else if (STRCMP(key, "END") == 0)
+	    item = ITEM_END;
+	else if (STRCMP(key, "SKIP") == 0)
+	{
+	    if (pat_ptrs[ITEM_SKIP] != NULL)	/* one skip pattern allowed */
+	    {
+		illegal = TRUE;
+		break;
+	    }
+	    item = ITEM_SKIP;
+	}
+	else
+	    break;
+	rest = skipwhite(key_end);
+	if (*rest != '=')
+	{
+	    rest = NULL;
+	    EMSG2(_("E398: Missing '=': %s"), arg);
+	    break;
+	}
+	rest = skipwhite(rest + 1);
+	if (*rest == NUL)
+	{
+	    not_enough = TRUE;
+	    break;
+	}
+
+	if (item == ITEM_MATCHGROUP)
+	{
+	    p = skiptowhite(rest);
+	    if ((p - rest == 4 && STRNCMP(rest, "NONE", 4) == 0) || eap->skip)
+		matchgroup_id = 0;
+	    else
+	    {
+		matchgroup_id = syn_check_group(rest, (int)(p - rest));
+		if (matchgroup_id == 0)
+		{
+		    illegal = TRUE;
+		    break;
+		}
+	    }
+	    rest = skipwhite(p);
+	}
+	else
+	{
+	    /*
+	     * Allocate room for a syn_pattern, and link it in the list of
+	     * syn_patterns for this item, at the start (because the list is
+	     * used from end to start).
+	     */
+	    ppp = (struct pat_ptr *)alloc((unsigned)sizeof(struct pat_ptr));
+	    if (ppp == NULL)
+	    {
+		rest = NULL;
+		break;
+	    }
+	    ppp->pp_next = pat_ptrs[item];
+	    pat_ptrs[item] = ppp;
+	    ppp->pp_synp = (synpat_T *)alloc_clear((unsigned)sizeof(synpat_T));
+	    if (ppp->pp_synp == NULL)
+	    {
+		rest = NULL;
+		break;
+	    }
+
+	    /*
+	     * Get the syntax pattern and the following offset(s).
+	     */
+	    /* Enable the appropriate \z specials. */
+	    if (item == ITEM_START)
+		reg_do_extmatch = REX_SET;
+	    else if (item == ITEM_SKIP || item == ITEM_END)
+		reg_do_extmatch = REX_USE;
+	    rest = get_syn_pattern(rest, ppp->pp_synp);
+	    reg_do_extmatch = 0;
+	    if (item == ITEM_END && vim_regcomp_had_eol()
+				       && !(syn_opt_arg.flags & HL_EXCLUDENL))
+		ppp->pp_synp->sp_flags |= HL_HAS_EOL;
+	    ppp->pp_matchgroup_id = matchgroup_id;
+	    ++pat_count;
+	}
+    }
+    vim_free(key);
+    if (illegal || not_enough)
+	rest = NULL;
+
+    /*
+     * Must have a "start" and "end" pattern.
+     */
+    if (rest != NULL && (pat_ptrs[ITEM_START] == NULL ||
+						  pat_ptrs[ITEM_END] == NULL))
+    {
+	not_enough = TRUE;
+	rest = NULL;
+    }
+
+    if (rest != NULL)
+    {
+	/*
+	 * Check for trailing garbage or command.
+	 * If OK, add the item.
+	 */
+	eap->nextcmd = check_nextcmd(rest);
+	if (!ends_excmd(*rest) || eap->skip)
+	    rest = NULL;
+	else if (ga_grow(&(curbuf->b_syn_patterns), pat_count) != FAIL
+		&& (syn_id = syn_check_group(arg,
+					   (int)(group_name_end - arg))) != 0)
+	{
+	    syn_incl_toplevel(syn_id, &syn_opt_arg.flags);
+	    /*
+	     * Store the start/skip/end in the syn_items list
+	     */
+	    idx = curbuf->b_syn_patterns.ga_len;
+	    for (item = ITEM_START; item <= ITEM_END; ++item)
+	    {
+		for (ppp = pat_ptrs[item]; ppp != NULL; ppp = ppp->pp_next)
+		{
+		    SYN_ITEMS(curbuf)[idx] = *(ppp->pp_synp);
+		    SYN_ITEMS(curbuf)[idx].sp_syncing = syncing;
+		    SYN_ITEMS(curbuf)[idx].sp_type =
+			    (item == ITEM_START) ? SPTYPE_START :
+			    (item == ITEM_SKIP) ? SPTYPE_SKIP : SPTYPE_END;
+		    SYN_ITEMS(curbuf)[idx].sp_flags |= syn_opt_arg.flags;
+		    SYN_ITEMS(curbuf)[idx].sp_syn.id = syn_id;
+		    SYN_ITEMS(curbuf)[idx].sp_syn.inc_tag = current_syn_inc_tag;
+		    SYN_ITEMS(curbuf)[idx].sp_syn_match_id =
+							ppp->pp_matchgroup_id;
+		    if (item == ITEM_START)
+		    {
+			SYN_ITEMS(curbuf)[idx].sp_cont_list =
+							syn_opt_arg.cont_list;
+			SYN_ITEMS(curbuf)[idx].sp_syn.cont_in_list =
+						     syn_opt_arg.cont_in_list;
+			if (syn_opt_arg.cont_in_list != NULL)
+			    curbuf->b_syn_containedin = TRUE;
+			SYN_ITEMS(curbuf)[idx].sp_next_list =
+							syn_opt_arg.next_list;
+		    }
+		    ++curbuf->b_syn_patterns.ga_len;
+		    ++idx;
+#ifdef FEAT_FOLDING
+		    if (syn_opt_arg.flags & HL_FOLD)
+			++curbuf->b_syn_folditems;
+#endif
+		}
+	    }
+
+	    redraw_curbuf_later(SOME_VALID);
+	    syn_stack_free_all(curbuf);	/* Need to recompute all syntax. */
+	    success = TRUE;	    /* don't free the progs and patterns now */
+	}
+    }
+
+    /*
+     * Free the allocated memory.
+     */
+    for (item = ITEM_START; item <= ITEM_END; ++item)
+	for (ppp = pat_ptrs[item]; ppp != NULL; ppp = ppp_next)
+	{
+	    if (!success)
+	    {
+		vim_free(ppp->pp_synp->sp_prog);
+		vim_free(ppp->pp_synp->sp_pattern);
+	    }
+	    vim_free(ppp->pp_synp);
+	    ppp_next = ppp->pp_next;
+	    vim_free(ppp);
+	}
+
+    if (!success)
+    {
+	vim_free(syn_opt_arg.cont_list);
+	vim_free(syn_opt_arg.cont_in_list);
+	vim_free(syn_opt_arg.next_list);
+	if (not_enough)
+	    EMSG2(_("E399: Not enough arguments: syntax region %s"), arg);
+	else if (illegal || rest == NULL)
+	    EMSG2(_(e_invarg2), arg);
+    }
+}
+
+/*
+ * A simple syntax group ID comparison function suitable for use in qsort()
+ */
+    static int
+#ifdef __BORLANDC__
+_RTLENTRYF
+#endif
+syn_compare_stub(v1, v2)
+    const void	*v1;
+    const void	*v2;
+{
+    const short	*s1 = v1;
+    const short	*s2 = v2;
+
+    return (*s1 > *s2 ? 1 : *s1 < *s2 ? -1 : 0);
+}
+
+/*
+ * Combines lists of syntax clusters.
+ * *clstr1 and *clstr2 must both be allocated memory; they will be consumed.
+ */
+    static void
+syn_combine_list(clstr1, clstr2, list_op)
+    short	**clstr1;
+    short	**clstr2;
+    int		list_op;
+{
+    int		count1 = 0;
+    int		count2 = 0;
+    short	*g1;
+    short	*g2;
+    short	*clstr = NULL;
+    int		count;
+    int		round;
+
+    /*
+     * Handle degenerate cases.
+     */
+    if (*clstr2 == NULL)
+	return;
+    if (*clstr1 == NULL || list_op == CLUSTER_REPLACE)
+    {
+	if (list_op == CLUSTER_REPLACE)
+	    vim_free(*clstr1);
+	if (list_op == CLUSTER_REPLACE || list_op == CLUSTER_ADD)
+	    *clstr1 = *clstr2;
+	else
+	    vim_free(*clstr2);
+	return;
+    }
+
+    for (g1 = *clstr1; *g1; g1++)
+	++count1;
+    for (g2 = *clstr2; *g2; g2++)
+	++count2;
+
+    /*
+     * For speed purposes, sort both lists.
+     */
+    qsort(*clstr1, (size_t)count1, sizeof(short), syn_compare_stub);
+    qsort(*clstr2, (size_t)count2, sizeof(short), syn_compare_stub);
+
+    /*
+     * We proceed in two passes; in round 1, we count the elements to place
+     * in the new list, and in round 2, we allocate and populate the new
+     * list.  For speed, we use a mergesort-like method, adding the smaller
+     * of the current elements in each list to the new list.
+     */
+    for (round = 1; round <= 2; round++)
+    {
+	g1 = *clstr1;
+	g2 = *clstr2;
+	count = 0;
+
+	/*
+	 * First, loop through the lists until one of them is empty.
+	 */
+	while (*g1 && *g2)
+	{
+	    /*
+	     * We always want to add from the first list.
+	     */
+	    if (*g1 < *g2)
+	    {
+		if (round == 2)
+		    clstr[count] = *g1;
+		count++;
+		g1++;
+		continue;
+	    }
+	    /*
+	     * We only want to add from the second list if we're adding the
+	     * lists.
+	     */
+	    if (list_op == CLUSTER_ADD)
+	    {
+		if (round == 2)
+		    clstr[count] = *g2;
+		count++;
+	    }
+	    if (*g1 == *g2)
+		g1++;
+	    g2++;
+	}
+
+	/*
+	 * Now add the leftovers from whichever list didn't get finished
+	 * first.  As before, we only want to add from the second list if
+	 * we're adding the lists.
+	 */
+	for (; *g1; g1++, count++)
+	    if (round == 2)
+		clstr[count] = *g1;
+	if (list_op == CLUSTER_ADD)
+	    for (; *g2; g2++, count++)
+		if (round == 2)
+		    clstr[count] = *g2;
+
+	if (round == 1)
+	{
+	    /*
+	     * If the group ended up empty, we don't need to allocate any
+	     * space for it.
+	     */
+	    if (count == 0)
+	    {
+		clstr = NULL;
+		break;
+	    }
+	    clstr = (short *)alloc((unsigned)((count + 1) * sizeof(short)));
+	    if (clstr == NULL)
+		break;
+	    clstr[count] = 0;
+	}
+    }
+
+    /*
+     * Finally, put the new list in place.
+     */
+    vim_free(*clstr1);
+    vim_free(*clstr2);
+    *clstr1 = clstr;
+}
+
+/*
+ * Lookup a syntax cluster name and return it's ID.
+ * If it is not found, 0 is returned.
+ */
+    static int
+syn_scl_name2id(name)
+    char_u	*name;
+{
+    int		i;
+    char_u	*name_u;
+
+    /* Avoid using stricmp() too much, it's slow on some systems */
+    name_u = vim_strsave_up(name);
+    if (name_u == NULL)
+	return 0;
+    for (i = curbuf->b_syn_clusters.ga_len; --i >= 0; )
+	if (SYN_CLSTR(curbuf)[i].scl_name_u != NULL
+		&& STRCMP(name_u, SYN_CLSTR(curbuf)[i].scl_name_u) == 0)
+	    break;
+    vim_free(name_u);
+    return (i < 0 ? 0 : i + SYNID_CLUSTER);
+}
+
+/*
+ * Like syn_scl_name2id(), but take a pointer + length argument.
+ */
+    static int
+syn_scl_namen2id(linep, len)
+    char_u  *linep;
+    int	    len;
+{
+    char_u  *name;
+    int	    id = 0;
+
+    name = vim_strnsave(linep, len);
+    if (name != NULL)
+    {
+	id = syn_scl_name2id(name);
+	vim_free(name);
+    }
+    return id;
+}
+
+/*
+ * Find syntax cluster name in the table and return it's ID.
+ * The argument is a pointer to the name and the length of the name.
+ * If it doesn't exist yet, a new entry is created.
+ * Return 0 for failure.
+ */
+    static int
+syn_check_cluster(pp, len)
+    char_u	*pp;
+    int		len;
+{
+    int		id;
+    char_u	*name;
+
+    name = vim_strnsave(pp, len);
+    if (name == NULL)
+	return 0;
+
+    id = syn_scl_name2id(name);
+    if (id == 0)			/* doesn't exist yet */
+	id = syn_add_cluster(name);
+    else
+	vim_free(name);
+    return id;
+}
+
+/*
+ * Add new syntax cluster and return it's ID.
+ * "name" must be an allocated string, it will be consumed.
+ * Return 0 for failure.
+ */
+    static int
+syn_add_cluster(name)
+    char_u	*name;
+{
+    int		len;
+
+    /*
+     * First call for this growarray: init growing array.
+     */
+    if (curbuf->b_syn_clusters.ga_data == NULL)
+    {
+	curbuf->b_syn_clusters.ga_itemsize = sizeof(syn_cluster_T);
+	curbuf->b_syn_clusters.ga_growsize = 10;
+    }
+
+    /*
+     * Make room for at least one other cluster entry.
+     */
+    if (ga_grow(&curbuf->b_syn_clusters, 1) == FAIL)
+    {
+	vim_free(name);
+	return 0;
+    }
+    len = curbuf->b_syn_clusters.ga_len;
+
+    vim_memset(&(SYN_CLSTR(curbuf)[len]), 0, sizeof(syn_cluster_T));
+    SYN_CLSTR(curbuf)[len].scl_name = name;
+    SYN_CLSTR(curbuf)[len].scl_name_u = vim_strsave_up(name);
+    SYN_CLSTR(curbuf)[len].scl_list = NULL;
+    ++curbuf->b_syn_clusters.ga_len;
+
+    if (STRICMP(name, "Spell") == 0)
+	curbuf->b_spell_cluster_id = len + SYNID_CLUSTER;
+    if (STRICMP(name, "NoSpell") == 0)
+	curbuf->b_nospell_cluster_id = len + SYNID_CLUSTER;
+
+    return len + SYNID_CLUSTER;
+}
+
+/*
+ * Handle ":syntax cluster {cluster-name} [contains={groupname},..]
+ *		[add={groupname},..] [remove={groupname},..]".
+ */
+/* ARGSUSED */
+    static void
+syn_cmd_cluster(eap, syncing)
+    exarg_T	*eap;
+    int		syncing;	    /* not used */
+{
+    char_u	*arg = eap->arg;
+    char_u	*group_name_end;
+    char_u	*rest;
+    int		scl_id;
+    short	*clstr_list;
+    int		got_clstr = FALSE;
+    int		opt_len;
+    int		list_op;
+
+    eap->nextcmd = find_nextcmd(arg);
+    if (eap->skip)
+	return;
+
+    rest = get_group_name(arg, &group_name_end);
+
+    if (rest != NULL)
+    {
+	scl_id = syn_check_cluster(arg, (int)(group_name_end - arg))
+							      - SYNID_CLUSTER;
+
+	for (;;)
+	{
+	    if (STRNICMP(rest, "add", 3) == 0
+		    && (vim_iswhite(rest[3]) || rest[3] == '='))
+	    {
+		opt_len = 3;
+		list_op = CLUSTER_ADD;
+	    }
+	    else if (STRNICMP(rest, "remove", 6) == 0
+		    && (vim_iswhite(rest[6]) || rest[6] == '='))
+	    {
+		opt_len = 6;
+		list_op = CLUSTER_SUBTRACT;
+	    }
+	    else if (STRNICMP(rest, "contains", 8) == 0
+			&& (vim_iswhite(rest[8]) || rest[8] == '='))
+	    {
+		opt_len = 8;
+		list_op = CLUSTER_REPLACE;
+	    }
+	    else
+		break;
+
+	    clstr_list = NULL;
+	    if (get_id_list(&rest, opt_len, &clstr_list) == FAIL)
+	    {
+		EMSG2(_(e_invarg2), rest);
+		break;
+	    }
+	    syn_combine_list(&SYN_CLSTR(curbuf)[scl_id].scl_list,
+			     &clstr_list, list_op);
+	    got_clstr = TRUE;
+	}
+
+	if (got_clstr)
+	{
+	    redraw_curbuf_later(SOME_VALID);
+	    syn_stack_free_all(curbuf);	/* Need to recompute all syntax. */
+	}
+    }
+
+    if (!got_clstr)
+	EMSG(_("E400: No cluster specified"));
+    if (rest == NULL || !ends_excmd(*rest))
+	EMSG2(_(e_invarg2), arg);
+}
+
+/*
+ * On first call for current buffer: Init growing array.
+ */
+    static void
+init_syn_patterns()
+{
+    curbuf->b_syn_patterns.ga_itemsize = sizeof(synpat_T);
+    curbuf->b_syn_patterns.ga_growsize = 10;
+}
+
+/*
+ * Get one pattern for a ":syntax match" or ":syntax region" command.
+ * Stores the pattern and program in a synpat_T.
+ * Returns a pointer to the next argument, or NULL in case of an error.
+ */
+    static char_u *
+get_syn_pattern(arg, ci)
+    char_u	*arg;
+    synpat_T	*ci;
+{
+    char_u	*end;
+    int		*p;
+    int		idx;
+    char_u	*cpo_save;
+
+    /* need at least three chars */
+    if (arg == NULL || arg[1] == NUL || arg[2] == NUL)
+	return NULL;
+
+    end = skip_regexp(arg + 1, *arg, TRUE, NULL);
+    if (*end != *arg)			    /* end delimiter not found */
+    {
+	EMSG2(_("E401: Pattern delimiter not found: %s"), arg);
+	return NULL;
+    }
+    /* store the pattern and compiled regexp program */
+    if ((ci->sp_pattern = vim_strnsave(arg + 1, (int)(end - arg - 1))) == NULL)
+	return NULL;
+
+    /* Make 'cpoptions' empty, to avoid the 'l' flag */
+    cpo_save = p_cpo;
+    p_cpo = (char_u *)"";
+    ci->sp_prog = vim_regcomp(ci->sp_pattern, RE_MAGIC);
+    p_cpo = cpo_save;
+
+    if (ci->sp_prog == NULL)
+	return NULL;
+    ci->sp_ic = curbuf->b_syn_ic;
+
+    /*
+     * Check for a match, highlight or region offset.
+     */
+    ++end;
+    do
+    {
+	for (idx = SPO_COUNT; --idx >= 0; )
+	    if (STRNCMP(end, spo_name_tab[idx], 3) == 0)
+		break;
+	if (idx >= 0)
+	{
+	    p = &(ci->sp_offsets[idx]);
+	    if (idx != SPO_LC_OFF)
+		switch (end[3])
+		{
+		    case 's':   break;
+		    case 'b':   break;
+		    case 'e':   idx += SPO_COUNT; break;
+		    default:    idx = -1; break;
+		}
+	    if (idx >= 0)
+	    {
+		ci->sp_off_flags |= (1 << idx);
+		if (idx == SPO_LC_OFF)	    /* lc=99 */
+		{
+		    end += 3;
+		    *p = getdigits(&end);
+
+		    /* "lc=" offset automatically sets "ms=" offset */
+		    if (!(ci->sp_off_flags & (1 << SPO_MS_OFF)))
+		    {
+			ci->sp_off_flags |= (1 << SPO_MS_OFF);
+			ci->sp_offsets[SPO_MS_OFF] = *p;
+		    }
+		}
+		else			    /* yy=x+99 */
+		{
+		    end += 4;
+		    if (*end == '+')
+		    {
+			++end;
+			*p = getdigits(&end);		/* positive offset */
+		    }
+		    else if (*end == '-')
+		    {
+			++end;
+			*p = -getdigits(&end);		/* negative offset */
+		    }
+		}
+		if (*end != ',')
+		    break;
+		++end;
+	    }
+	}
+    } while (idx >= 0);
+
+    if (!ends_excmd(*end) && !vim_iswhite(*end))
+    {
+	EMSG2(_("E402: Garbage after pattern: %s"), arg);
+	return NULL;
+    }
+    return skipwhite(end);
+}
+
+/*
+ * Handle ":syntax sync .." command.
+ */
+/* ARGSUSED */
+    static void
+syn_cmd_sync(eap, syncing)
+    exarg_T	*eap;
+    int		syncing;	    /* not used */
+{
+    char_u	*arg_start = eap->arg;
+    char_u	*arg_end;
+    char_u	*key = NULL;
+    char_u	*next_arg;
+    int		illegal = FALSE;
+    int		finished = FALSE;
+    long	n;
+    char_u	*cpo_save;
+
+    if (ends_excmd(*arg_start))
+    {
+	syn_cmd_list(eap, TRUE);
+	return;
+    }
+
+    while (!ends_excmd(*arg_start))
+    {
+	arg_end = skiptowhite(arg_start);
+	next_arg = skipwhite(arg_end);
+	vim_free(key);
+	key = vim_strnsave_up(arg_start, (int)(arg_end - arg_start));
+	if (STRCMP(key, "CCOMMENT") == 0)
+	{
+	    if (!eap->skip)
+		curbuf->b_syn_sync_flags |= SF_CCOMMENT;
+	    if (!ends_excmd(*next_arg))
+	    {
+		arg_end = skiptowhite(next_arg);
+		if (!eap->skip)
+		    curbuf->b_syn_sync_id = syn_check_group(next_arg,
+						   (int)(arg_end - next_arg));
+		next_arg = skipwhite(arg_end);
+	    }
+	    else if (!eap->skip)
+		curbuf->b_syn_sync_id = syn_name2id((char_u *)"Comment");
+	}
+	else if (  STRNCMP(key, "LINES", 5) == 0
+		|| STRNCMP(key, "MINLINES", 8) == 0
+		|| STRNCMP(key, "MAXLINES", 8) == 0
+		|| STRNCMP(key, "LINEBREAKS", 10) == 0)
+	{
+	    if (key[4] == 'S')
+		arg_end = key + 6;
+	    else if (key[0] == 'L')
+		arg_end = key + 11;
+	    else
+		arg_end = key + 9;
+	    if (arg_end[-1] != '=' || !VIM_ISDIGIT(*arg_end))
+	    {
+		illegal = TRUE;
+		break;
+	    }
+	    n = getdigits(&arg_end);
+	    if (!eap->skip)
+	    {
+		if (key[4] == 'B')
+		    curbuf->b_syn_sync_linebreaks = n;
+		else if (key[1] == 'A')
+		    curbuf->b_syn_sync_maxlines = n;
+		else
+		    curbuf->b_syn_sync_minlines = n;
+	    }
+	}
+	else if (STRCMP(key, "FROMSTART") == 0)
+	{
+	    if (!eap->skip)
+	    {
+		curbuf->b_syn_sync_minlines = MAXLNUM;
+		curbuf->b_syn_sync_maxlines = 0;
+	    }
+	}
+	else if (STRCMP(key, "LINECONT") == 0)
+	{
+	    if (curbuf->b_syn_linecont_pat != NULL)
+	    {
+		EMSG(_("E403: syntax sync: line continuations pattern specified twice"));
+		finished = TRUE;
+		break;
+	    }
+	    arg_end = skip_regexp(next_arg + 1, *next_arg, TRUE, NULL);
+	    if (*arg_end != *next_arg)	    /* end delimiter not found */
+	    {
+		illegal = TRUE;
+		break;
+	    }
+
+	    if (!eap->skip)
+	    {
+		/* store the pattern and compiled regexp program */
+		if ((curbuf->b_syn_linecont_pat = vim_strnsave(next_arg + 1,
+				      (int)(arg_end - next_arg - 1))) == NULL)
+		{
+		    finished = TRUE;
+		    break;
+		}
+		curbuf->b_syn_linecont_ic = curbuf->b_syn_ic;
+
+		/* Make 'cpoptions' empty, to avoid the 'l' flag */
+		cpo_save = p_cpo;
+		p_cpo = (char_u *)"";
+		curbuf->b_syn_linecont_prog =
+			    vim_regcomp(curbuf->b_syn_linecont_pat, RE_MAGIC);
+		p_cpo = cpo_save;
+
+		if (curbuf->b_syn_linecont_prog == NULL)
+		{
+		    vim_free(curbuf->b_syn_linecont_pat);
+		    curbuf->b_syn_linecont_pat = NULL;
+		    finished = TRUE;
+		    break;
+		}
+	    }
+	    next_arg = skipwhite(arg_end + 1);
+	}
+	else
+	{
+	    eap->arg = next_arg;
+	    if (STRCMP(key, "MATCH") == 0)
+		syn_cmd_match(eap, TRUE);
+	    else if (STRCMP(key, "REGION") == 0)
+		syn_cmd_region(eap, TRUE);
+	    else if (STRCMP(key, "CLEAR") == 0)
+		syn_cmd_clear(eap, TRUE);
+	    else
+		illegal = TRUE;
+	    finished = TRUE;
+	    break;
+	}
+	arg_start = next_arg;
+    }
+    vim_free(key);
+    if (illegal)
+	EMSG2(_("E404: Illegal arguments: %s"), arg_start);
+    else if (!finished)
+    {
+	eap->nextcmd = check_nextcmd(arg_start);
+	redraw_curbuf_later(SOME_VALID);
+	syn_stack_free_all(curbuf);	/* Need to recompute all syntax. */
+    }
+}
+
+/*
+ * Convert a line of highlight group names into a list of group ID numbers.
+ * "arg" should point to the "contains" or "nextgroup" keyword.
+ * "arg" is advanced to after the last group name.
+ * Careful: the argument is modified (NULs added).
+ * returns FAIL for some error, OK for success.
+ */
+    static int
+get_id_list(arg, keylen, list)
+    char_u	**arg;
+    int		keylen;		/* length of keyword */
+    short	**list;		/* where to store the resulting list, if not
+				   NULL, the list is silently skipped! */
+{
+    char_u	*p = NULL;
+    char_u	*end;
+    int		round;
+    int		count;
+    int		total_count = 0;
+    short	*retval = NULL;
+    char_u	*name;
+    regmatch_T	regmatch;
+    int		id;
+    int		i;
+    int		failed = FALSE;
+
+    /*
+     * We parse the list twice:
+     * round == 1: count the number of items, allocate the array.
+     * round == 2: fill the array with the items.
+     * In round 1 new groups may be added, causing the number of items to
+     * grow when a regexp is used.  In that case round 1 is done once again.
+     */
+    for (round = 1; round <= 2; ++round)
+    {
+	/*
+	 * skip "contains"
+	 */
+	p = skipwhite(*arg + keylen);
+	if (*p != '=')
+	{
+	    EMSG2(_("E405: Missing equal sign: %s"), *arg);
+	    break;
+	}
+	p = skipwhite(p + 1);
+	if (ends_excmd(*p))
+	{
+	    EMSG2(_("E406: Empty argument: %s"), *arg);
+	    break;
+	}
+
+	/*
+	 * parse the arguments after "contains"
+	 */
+	count = 0;
+	while (!ends_excmd(*p))
+	{
+	    for (end = p; *end && !vim_iswhite(*end) && *end != ','; ++end)
+		;
+	    name = alloc((int)(end - p + 3));	    /* leave room for "^$" */
+	    if (name == NULL)
+	    {
+		failed = TRUE;
+		break;
+	    }
+	    vim_strncpy(name + 1, p, end - p);
+	    if (       STRCMP(name + 1, "ALLBUT") == 0
+		    || STRCMP(name + 1, "ALL") == 0
+		    || STRCMP(name + 1, "TOP") == 0
+		    || STRCMP(name + 1, "CONTAINED") == 0)
+	    {
+		if (TOUPPER_ASC(**arg) != 'C')
+		{
+		    EMSG2(_("E407: %s not allowed here"), name + 1);
+		    failed = TRUE;
+		    vim_free(name);
+		    break;
+		}
+		if (count != 0)
+		{
+		    EMSG2(_("E408: %s must be first in contains list"), name + 1);
+		    failed = TRUE;
+		    vim_free(name);
+		    break;
+		}
+		if (name[1] == 'A')
+		    id = SYNID_ALLBUT;
+		else if (name[1] == 'T')
+		    id = SYNID_TOP;
+		else
+		    id = SYNID_CONTAINED;
+		id += current_syn_inc_tag;
+	    }
+	    else if (name[1] == '@')
+	    {
+		id = syn_check_cluster(name + 2, (int)(end - p - 1));
+	    }
+	    else
+	    {
+		/*
+		 * Handle full group name.
+		 */
+		if (vim_strpbrk(name + 1, (char_u *)"\\.*^$~[") == NULL)
+		    id = syn_check_group(name + 1, (int)(end - p));
+		else
+		{
+		    /*
+		     * Handle match of regexp with group names.
+		     */
+		    *name = '^';
+		    STRCAT(name, "$");
+		    regmatch.regprog = vim_regcomp(name, RE_MAGIC);
+		    if (regmatch.regprog == NULL)
+		    {
+			failed = TRUE;
+			vim_free(name);
+			break;
+		    }
+
+		    regmatch.rm_ic = TRUE;
+		    id = 0;
+		    for (i = highlight_ga.ga_len; --i >= 0; )
+		    {
+			if (vim_regexec(&regmatch, HL_TABLE()[i].sg_name,
+								  (colnr_T)0))
+			{
+			    if (round == 2)
+			    {
+				/* Got more items than expected; can happen
+				 * when adding items that match:
+				 * "contains=a.*b,axb".
+				 * Go back to first round */
+				if (count >= total_count)
+				{
+				    vim_free(retval);
+				    round = 1;
+				}
+				else
+				    retval[count] = i + 1;
+			    }
+			    ++count;
+			    id = -1;	    /* remember that we found one */
+			}
+		    }
+		    vim_free(regmatch.regprog);
+		}
+	    }
+	    vim_free(name);
+	    if (id == 0)
+	    {
+		EMSG2(_("E409: Unknown group name: %s"), p);
+		failed = TRUE;
+		break;
+	    }
+	    if (id > 0)
+	    {
+		if (round == 2)
+		{
+		    /* Got more items than expected, go back to first round */
+		    if (count >= total_count)
+		    {
+			vim_free(retval);
+			round = 1;
+		    }
+		    else
+			retval[count] = id;
+		}
+		++count;
+	    }
+	    p = skipwhite(end);
+	    if (*p != ',')
+		break;
+	    p = skipwhite(p + 1);	/* skip comma in between arguments */
+	}
+	if (failed)
+	    break;
+	if (round == 1)
+	{
+	    retval = (short *)alloc((unsigned)((count + 1) * sizeof(short)));
+	    if (retval == NULL)
+		break;
+	    retval[count] = 0;	    /* zero means end of the list */
+	    total_count = count;
+	}
+    }
+
+    *arg = p;
+    if (failed || retval == NULL)
+    {
+	vim_free(retval);
+	return FAIL;
+    }
+
+    if (*list == NULL)
+	*list = retval;
+    else
+	vim_free(retval);	/* list already found, don't overwrite it */
+
+    return OK;
+}
+
+/*
+ * Make a copy of an ID list.
+ */
+    static short *
+copy_id_list(list)
+    short   *list;
+{
+    int	    len;
+    int	    count;
+    short   *retval;
+
+    if (list == NULL)
+	return NULL;
+
+    for (count = 0; list[count]; ++count)
+	;
+    len = (count + 1) * sizeof(short);
+    retval = (short *)alloc((unsigned)len);
+    if (retval != NULL)
+	mch_memmove(retval, list, (size_t)len);
+
+    return retval;
+}
+
+/*
+ * Check if syntax group "ssp" is in the ID list "list" of "cur_si".
+ * "cur_si" can be NULL if not checking the "containedin" list.
+ * Used to check if a syntax item is in the "contains" or "nextgroup" list of
+ * the current item.
+ * This function is called very often, keep it fast!!
+ */
+    static int
+in_id_list(cur_si, list, ssp, contained)
+    stateitem_T	*cur_si;	/* current item or NULL */
+    short	*list;		/* id list */
+    struct sp_syn *ssp;		/* group id and ":syn include" tag of group */
+    int		contained;	/* group id is contained */
+{
+    int		retval;
+    short	*scl_list;
+    short	item;
+    short	id = ssp->id;
+    static int	depth = 0;
+    int		r;
+
+    /* If spp has a "containedin" list and "cur_si" is in it, return TRUE. */
+    if (cur_si != NULL && ssp->cont_in_list != NULL
+					    && !(cur_si->si_flags & HL_MATCH))
+    {
+	/* Ignore transparent items without a contains argument.  Double check
+	 * that we don't go back past the first one. */
+	while ((cur_si->si_flags & HL_TRANS_CONT)
+		&& cur_si > (stateitem_T *)(current_state.ga_data))
+	    --cur_si;
+	/* cur_si->si_idx is -1 for keywords, these never contain anything. */
+	if (cur_si->si_idx >= 0 && in_id_list(NULL, ssp->cont_in_list,
+		&(SYN_ITEMS(syn_buf)[cur_si->si_idx].sp_syn),
+		  SYN_ITEMS(syn_buf)[cur_si->si_idx].sp_flags & HL_CONTAINED))
+	    return TRUE;
+    }
+
+    if (list == NULL)
+	return FALSE;
+
+    /*
+     * If list is ID_LIST_ALL, we are in a transparent item that isn't
+     * inside anything.  Only allow not-contained groups.
+     */
+    if (list == ID_LIST_ALL)
+	return !contained;
+
+    /*
+     * If the first item is "ALLBUT", return TRUE if "id" is NOT in the
+     * contains list.  We also require that "id" is at the same ":syn include"
+     * level as the list.
+     */
+    item = *list;
+    if (item >= SYNID_ALLBUT && item < SYNID_CLUSTER)
+    {
+	if (item < SYNID_TOP)
+	{
+	    /* ALL or ALLBUT: accept all groups in the same file */
+	    if (item - SYNID_ALLBUT != ssp->inc_tag)
+		return FALSE;
+	}
+	else if (item < SYNID_CONTAINED)
+	{
+	    /* TOP: accept all not-contained groups in the same file */
+	    if (item - SYNID_TOP != ssp->inc_tag || contained)
+		return FALSE;
+	}
+	else
+	{
+	    /* CONTAINED: accept all contained groups in the same file */
+	    if (item - SYNID_CONTAINED != ssp->inc_tag || !contained)
+		return FALSE;
+	}
+	item = *++list;
+	retval = FALSE;
+    }
+    else
+	retval = TRUE;
+
+    /*
+     * Return "retval" if id is in the contains list.
+     */
+    while (item != 0)
+    {
+	if (item == id)
+	    return retval;
+	if (item >= SYNID_CLUSTER)
+	{
+	    scl_list = SYN_CLSTR(syn_buf)[item - SYNID_CLUSTER].scl_list;
+	    /* restrict recursiveness to 30 to avoid an endless loop for a
+	     * cluster that includes itself (indirectly) */
+	    if (scl_list != NULL && depth < 30)
+	    {
+		++depth;
+		r = in_id_list(NULL, scl_list, ssp, contained);
+		--depth;
+		if (r)
+		    return retval;
+	    }
+	}
+	item = *++list;
+    }
+    return !retval;
+}
+
+struct subcommand
+{
+    char    *name;				/* subcommand name */
+    void    (*func)__ARGS((exarg_T *, int));	/* function to call */
+};
+
+static struct subcommand subcommands[] =
+{
+    {"case",		syn_cmd_case},
+    {"clear",		syn_cmd_clear},
+    {"cluster",		syn_cmd_cluster},
+    {"enable",		syn_cmd_enable},
+    {"include",		syn_cmd_include},
+    {"keyword",		syn_cmd_keyword},
+    {"list",		syn_cmd_list},
+    {"manual",		syn_cmd_manual},
+    {"match",		syn_cmd_match},
+    {"on",		syn_cmd_on},
+    {"off",		syn_cmd_off},
+    {"region",		syn_cmd_region},
+    {"reset",		syn_cmd_reset},
+    {"spell",		syn_cmd_spell},
+    {"sync",		syn_cmd_sync},
+    {"",		syn_cmd_list},
+    {NULL, NULL}
+};
+
+/*
+ * ":syntax".
+ * This searches the subcommands[] table for the subcommand name, and calls a
+ * syntax_subcommand() function to do the rest.
+ */
+    void
+ex_syntax(eap)
+    exarg_T	*eap;
+{
+    char_u	*arg = eap->arg;
+    char_u	*subcmd_end;
+    char_u	*subcmd_name;
+    int		i;
+
+    syn_cmdlinep = eap->cmdlinep;
+
+    /* isolate subcommand name */
+    for (subcmd_end = arg; ASCII_ISALPHA(*subcmd_end); ++subcmd_end)
+	;
+    subcmd_name = vim_strnsave(arg, (int)(subcmd_end - arg));
+    if (subcmd_name != NULL)
+    {
+	if (eap->skip)		/* skip error messages for all subcommands */
+	    ++emsg_skip;
+	for (i = 0; ; ++i)
+	{
+	    if (subcommands[i].name == NULL)
+	    {
+		EMSG2(_("E410: Invalid :syntax subcommand: %s"), subcmd_name);
+		break;
+	    }
+	    if (STRCMP(subcmd_name, (char_u *)subcommands[i].name) == 0)
+	    {
+		eap->arg = skipwhite(subcmd_end);
+		(subcommands[i].func)(eap, FALSE);
+		break;
+	    }
+	}
+	vim_free(subcmd_name);
+	if (eap->skip)
+	    --emsg_skip;
+    }
+}
+
+    int
+syntax_present(buf)
+    buf_T	*buf;
+{
+    return (buf->b_syn_patterns.ga_len != 0
+	    || buf->b_syn_clusters.ga_len != 0
+	    || curbuf->b_keywtab.ht_used > 0
+	    || curbuf->b_keywtab_ic.ht_used > 0);
+}
+
+#if defined(FEAT_CMDL_COMPL) || defined(PROTO)
+
+static enum
+{
+    EXP_SUBCMD,	    /* expand ":syn" sub-commands */
+    EXP_CASE	    /* expand ":syn case" arguments */
+} expand_what;
+
+
+/*
+ * Handle command line completion for :syntax command.
+ */
+    void
+set_context_in_syntax_cmd(xp, arg)
+    expand_T	*xp;
+    char_u	*arg;
+{
+    char_u	*p;
+
+    /* Default: expand subcommands */
+    xp->xp_context = EXPAND_SYNTAX;
+    expand_what = EXP_SUBCMD;
+    xp->xp_pattern = arg;
+    include_link = FALSE;
+    include_default = FALSE;
+
+    /* (part of) subcommand already typed */
+    if (*arg != NUL)
+    {
+	p = skiptowhite(arg);
+	if (*p != NUL)		    /* past first word */
+	{
+	    xp->xp_pattern = skipwhite(p);
+	    if (*skiptowhite(xp->xp_pattern) != NUL)
+		xp->xp_context = EXPAND_NOTHING;
+	    else if (STRNICMP(arg, "case", p - arg) == 0)
+		expand_what = EXP_CASE;
+	    else if (  STRNICMP(arg, "keyword", p - arg) == 0
+		    || STRNICMP(arg, "region", p - arg) == 0
+		    || STRNICMP(arg, "match", p - arg) == 0
+		    || STRNICMP(arg, "list", p - arg) == 0)
+		xp->xp_context = EXPAND_HIGHLIGHT;
+	    else
+		xp->xp_context = EXPAND_NOTHING;
+	}
+    }
+}
+
+static char *(case_args[]) = {"match", "ignore", NULL};
+
+/*
+ * Function given to ExpandGeneric() to obtain the list syntax names for
+ * expansion.
+ */
+/*ARGSUSED*/
+    char_u *
+get_syntax_name(xp, idx)
+    expand_T	*xp;
+    int		idx;
+{
+    if (expand_what == EXP_SUBCMD)
+	return (char_u *)subcommands[idx].name;
+    return (char_u *)case_args[idx];
+}
+
+#endif /* FEAT_CMDL_COMPL */
+
+/*
+ * Function called for expression evaluation: get syntax ID at file position.
+ */
+    int
+syn_get_id(wp, lnum, col, trans, spellp)
+    win_T	*wp;
+    long	lnum;
+    colnr_T	col;
+    int		trans;	    /* remove transparancy */
+    int		*spellp;    /* return: can do spell checking */
+{
+    /* When the position is not after the current position and in the same
+     * line of the same buffer, need to restart parsing. */
+    if (wp->w_buffer != syn_buf
+	    || lnum != current_lnum
+	    || col < current_col)
+	syntax_start(wp, lnum);
+
+    (void)get_syntax_attr(col, spellp);
+
+    return (trans ? current_trans_id : current_id);
+}
+
+#if defined(FEAT_FOLDING) || defined(PROTO)
+/*
+ * Function called to get folding level for line "lnum" in window "wp".
+ */
+    int
+syn_get_foldlevel(wp, lnum)
+    win_T	*wp;
+    long	lnum;
+{
+    int		level = 0;
+    int		i;
+
+    /* Return quickly when there are no fold items at all. */
+    if (wp->w_buffer->b_syn_folditems != 0)
+    {
+	syntax_start(wp, lnum);
+
+	for (i = 0; i < current_state.ga_len; ++i)
+	    if (CUR_STATE(i).si_flags & HL_FOLD)
+		++level;
+    }
+    if (level > wp->w_p_fdn)
+    {
+	level = wp->w_p_fdn;
+	if (level < 0)
+	    level = 0;
+    }
+    return level;
+}
+#endif
+
+#endif /* FEAT_SYN_HL */
+
+
+/**************************************
+ *  Highlighting stuff		      *
+ **************************************/
+
+/*
+ * The default highlight groups.  These are compiled-in for fast startup and
+ * they still work when the runtime files can't be found.
+ * When making changes here, also change runtime/colors/default.vim!
+ * The #ifdefs are needed to reduce the amount of static data.  Helps to make
+ * the 16 bit DOS (museum) version compile.
+ */
+#ifdef FEAT_GUI
+# define CENT(a, b) b
+#else
+# define CENT(a, b) a
+#endif
+static char *(highlight_init_both[]) =
+    {
+	CENT("ErrorMsg term=standout ctermbg=DarkRed ctermfg=White",
+	     "ErrorMsg term=standout ctermbg=DarkRed ctermfg=White guibg=Red guifg=White"),
+#ifdef FEAT_SEARCH_EXTRA
+	CENT("IncSearch term=reverse cterm=reverse",
+	     "IncSearch term=reverse cterm=reverse gui=reverse"),
+#endif
+	CENT("ModeMsg term=bold cterm=bold",
+	     "ModeMsg term=bold cterm=bold gui=bold"),
+	CENT("NonText term=bold ctermfg=Blue",
+	     "NonText term=bold ctermfg=Blue gui=bold guifg=Blue"),
+	CENT("StatusLine term=reverse,bold cterm=reverse,bold",
+	     "StatusLine term=reverse,bold cterm=reverse,bold gui=reverse,bold"),
+	CENT("StatusLineNC term=reverse cterm=reverse",
+	     "StatusLineNC term=reverse cterm=reverse gui=reverse"),
+#ifdef FEAT_VERTSPLIT
+	CENT("VertSplit term=reverse cterm=reverse",
+	     "VertSplit term=reverse cterm=reverse gui=reverse"),
+#endif
+#ifdef FEAT_CLIPBOARD
+	CENT("VisualNOS term=underline,bold cterm=underline,bold",
+	     "VisualNOS term=underline,bold cterm=underline,bold gui=underline,bold"),
+#endif
+#ifdef FEAT_DIFF
+	CENT("DiffText term=reverse cterm=bold ctermbg=Red",
+	     "DiffText term=reverse cterm=bold ctermbg=Red gui=bold guibg=Red"),
+#endif
+#ifdef FEAT_INS_EXPAND
+	CENT("PmenuThumb cterm=reverse",
+	     "PmenuThumb cterm=reverse gui=reverse"),
+	CENT("PmenuSbar ctermbg=Grey",
+	     "PmenuSbar ctermbg=Grey guibg=Grey"),
+#endif
+#ifdef FEAT_WINDOWS
+	CENT("TabLineSel term=bold cterm=bold",
+	     "TabLineSel term=bold cterm=bold gui=bold"),
+	CENT("TabLineFill term=reverse cterm=reverse",
+	     "TabLineFill term=reverse cterm=reverse gui=reverse"),
+#endif
+#ifdef FEAT_GUI
+	"Cursor guibg=fg guifg=bg",
+	"lCursor guibg=fg guifg=bg", /* should be different, but what? */
+#endif
+	NULL
+    };
+
+static char *(highlight_init_light[]) =
+    {
+	CENT("Directory term=bold ctermfg=DarkBlue",
+	     "Directory term=bold ctermfg=DarkBlue guifg=Blue"),
+	CENT("LineNr term=underline ctermfg=Brown",
+	     "LineNr term=underline ctermfg=Brown guifg=Brown"),
+	CENT("MoreMsg term=bold ctermfg=DarkGreen",
+	     "MoreMsg term=bold ctermfg=DarkGreen gui=bold guifg=SeaGreen"),
+	CENT("Question term=standout ctermfg=DarkGreen",
+	     "Question term=standout ctermfg=DarkGreen gui=bold guifg=SeaGreen"),
+	CENT("Search term=reverse ctermbg=Yellow ctermfg=NONE",
+	     "Search term=reverse ctermbg=Yellow ctermfg=NONE guibg=Yellow guifg=NONE"),
+#ifdef FEAT_SPELL
+	CENT("SpellBad term=reverse ctermbg=LightRed",
+	     "SpellBad term=reverse ctermbg=LightRed guisp=Red gui=undercurl"),
+	CENT("SpellCap term=reverse ctermbg=LightBlue",
+	     "SpellCap term=reverse ctermbg=LightBlue guisp=Blue gui=undercurl"),
+	CENT("SpellRare term=reverse ctermbg=LightMagenta",
+	     "SpellRare term=reverse ctermbg=LightMagenta guisp=Magenta gui=undercurl"),
+	CENT("SpellLocal term=underline ctermbg=Cyan",
+	     "SpellLocal term=underline ctermbg=Cyan guisp=DarkCyan gui=undercurl"),
+#endif
+#ifdef FEAT_INS_EXPAND
+	CENT("Pmenu ctermbg=LightMagenta",
+	     "Pmenu ctermbg=LightMagenta guibg=LightMagenta"),
+	CENT("PmenuSel ctermbg=LightGrey",
+	     "PmenuSel ctermbg=LightGrey guibg=Grey"),
+#endif
+	CENT("SpecialKey term=bold ctermfg=DarkBlue",
+	     "SpecialKey term=bold ctermfg=DarkBlue guifg=Blue"),
+	CENT("Title term=bold ctermfg=DarkMagenta",
+	     "Title term=bold ctermfg=DarkMagenta gui=bold guifg=Magenta"),
+	CENT("WarningMsg term=standout ctermfg=DarkRed",
+	     "WarningMsg term=standout ctermfg=DarkRed guifg=Red"),
+#ifdef FEAT_WILDMENU
+	CENT("WildMenu term=standout ctermbg=Yellow ctermfg=Black",
+	     "WildMenu term=standout ctermbg=Yellow ctermfg=Black guibg=Yellow guifg=Black"),
+#endif
+#ifdef FEAT_FOLDING
+	CENT("Folded term=standout ctermbg=Grey ctermfg=DarkBlue",
+	     "Folded term=standout ctermbg=Grey ctermfg=DarkBlue guibg=LightGrey guifg=DarkBlue"),
+	CENT("FoldColumn term=standout ctermbg=Grey ctermfg=DarkBlue",
+	     "FoldColumn term=standout ctermbg=Grey ctermfg=DarkBlue guibg=Grey guifg=DarkBlue"),
+#endif
+#ifdef FEAT_SIGNS
+	CENT("SignColumn term=standout ctermbg=Grey ctermfg=DarkBlue",
+	     "SignColumn term=standout ctermbg=Grey ctermfg=DarkBlue guibg=Grey guifg=DarkBlue"),
+#endif
+#ifdef FEAT_VISUAL
+	CENT("Visual term=reverse",
+	     "Visual term=reverse guibg=LightGrey"),
+#endif
+#ifdef FEAT_DIFF
+	CENT("DiffAdd term=bold ctermbg=LightBlue",
+	     "DiffAdd term=bold ctermbg=LightBlue guibg=LightBlue"),
+	CENT("DiffChange term=bold ctermbg=LightMagenta",
+	     "DiffChange term=bold ctermbg=LightMagenta guibg=LightMagenta"),
+	CENT("DiffDelete term=bold ctermfg=Blue ctermbg=LightCyan",
+	     "DiffDelete term=bold ctermfg=Blue ctermbg=LightCyan gui=bold guifg=Blue guibg=LightCyan"),
+#endif
+#ifdef FEAT_WINDOWS
+	CENT("TabLine term=underline cterm=underline ctermfg=black ctermbg=LightGrey",
+	     "TabLine term=underline cterm=underline ctermfg=black ctermbg=LightGrey gui=underline guibg=LightGrey"),
+#endif
+#ifdef FEAT_SYN_HL
+	CENT("CursorColumn term=reverse ctermbg=LightGrey",
+	     "CursorColumn term=reverse ctermbg=LightGrey guibg=Grey90"),
+	CENT("CursorLine term=underline cterm=underline",
+	     "CursorLine term=underline cterm=underline guibg=Grey90"),
+#endif
+#ifdef FEAT_AUTOCMD
+	CENT("MatchParen term=reverse ctermbg=Cyan",
+	     "MatchParen term=reverse ctermbg=Cyan guibg=Cyan"),
+#endif
+#ifdef FEAT_GUI
+	"Normal gui=NONE",
+#endif
+	NULL
+    };
+
+static char *(highlight_init_dark[]) =
+    {
+	CENT("Directory term=bold ctermfg=LightCyan",
+	     "Directory term=bold ctermfg=LightCyan guifg=Cyan"),
+	CENT("LineNr term=underline ctermfg=Yellow",
+	     "LineNr term=underline ctermfg=Yellow guifg=Yellow"),
+	CENT("MoreMsg term=bold ctermfg=LightGreen",
+	     "MoreMsg term=bold ctermfg=LightGreen gui=bold guifg=SeaGreen"),
+	CENT("Question term=standout ctermfg=LightGreen",
+	     "Question term=standout ctermfg=LightGreen gui=bold guifg=Green"),
+	CENT("Search term=reverse ctermbg=Yellow ctermfg=Black",
+	     "Search term=reverse ctermbg=Yellow ctermfg=Black guibg=Yellow guifg=Black"),
+	CENT("SpecialKey term=bold ctermfg=LightBlue",
+	     "SpecialKey term=bold ctermfg=LightBlue guifg=Cyan"),
+#ifdef FEAT_SPELL
+	CENT("SpellBad term=reverse ctermbg=Red",
+	     "SpellBad term=reverse ctermbg=Red guisp=Red gui=undercurl"),
+	CENT("SpellCap term=reverse ctermbg=Blue",
+	     "SpellCap term=reverse ctermbg=Blue guisp=Blue gui=undercurl"),
+	CENT("SpellRare term=reverse ctermbg=Magenta",
+	     "SpellRare term=reverse ctermbg=Magenta guisp=Magenta gui=undercurl"),
+	CENT("SpellLocal term=underline ctermbg=Cyan",
+	     "SpellLocal term=underline ctermbg=Cyan guisp=Cyan gui=undercurl"),
+#endif
+#ifdef FEAT_INS_EXPAND
+	CENT("Pmenu ctermbg=Magenta",
+	     "Pmenu ctermbg=Magenta guibg=Magenta"),
+	CENT("PmenuSel ctermbg=DarkGrey",
+	     "PmenuSel ctermbg=DarkGrey guibg=DarkGrey"),
+#endif
+	CENT("Title term=bold ctermfg=LightMagenta",
+	     "Title term=bold ctermfg=LightMagenta gui=bold guifg=Magenta"),
+	CENT("WarningMsg term=standout ctermfg=LightRed",
+	     "WarningMsg term=standout ctermfg=LightRed guifg=Red"),
+#ifdef FEAT_WILDMENU
+	CENT("WildMenu term=standout ctermbg=Yellow ctermfg=Black",
+	     "WildMenu term=standout ctermbg=Yellow ctermfg=Black guibg=Yellow guifg=Black"),
+#endif
+#ifdef FEAT_FOLDING
+	CENT("Folded term=standout ctermbg=DarkGrey ctermfg=Cyan",
+	     "Folded term=standout ctermbg=DarkGrey ctermfg=Cyan guibg=DarkGrey guifg=Cyan"),
+	CENT("FoldColumn term=standout ctermbg=DarkGrey ctermfg=Cyan",
+	     "FoldColumn term=standout ctermbg=DarkGrey ctermfg=Cyan guibg=Grey guifg=Cyan"),
+#endif
+#ifdef FEAT_SIGNS
+	CENT("SignColumn term=standout ctermbg=DarkGrey ctermfg=Cyan",
+	     "SignColumn term=standout ctermbg=DarkGrey ctermfg=Cyan guibg=Grey guifg=Cyan"),
+#endif
+#ifdef FEAT_VISUAL
+	CENT("Visual term=reverse",
+	     "Visual term=reverse guibg=DarkGrey"),
+#endif
+#ifdef FEAT_DIFF
+	CENT("DiffAdd term=bold ctermbg=DarkBlue",
+	     "DiffAdd term=bold ctermbg=DarkBlue guibg=DarkBlue"),
+	CENT("DiffChange term=bold ctermbg=DarkMagenta",
+	     "DiffChange term=bold ctermbg=DarkMagenta guibg=DarkMagenta"),
+	CENT("DiffDelete term=bold ctermfg=Blue ctermbg=DarkCyan",
+	     "DiffDelete term=bold ctermfg=Blue ctermbg=DarkCyan gui=bold guifg=Blue guibg=DarkCyan"),
+#endif
+#ifdef FEAT_WINDOWS
+	CENT("TabLine term=underline cterm=underline ctermfg=white ctermbg=DarkGrey",
+	     "TabLine term=underline cterm=underline ctermfg=white ctermbg=DarkGrey gui=underline guibg=DarkGrey"),
+#endif
+#ifdef FEAT_SYN_HL
+	CENT("CursorColumn term=reverse ctermbg=DarkGrey",
+	     "CursorColumn term=reverse ctermbg=DarkGrey guibg=Grey40"),
+	CENT("CursorLine term=underline cterm=underline",
+	     "CursorLine term=underline cterm=underline guibg=Grey40"),
+#endif
+#ifdef FEAT_AUTOCMD
+	CENT("MatchParen term=reverse ctermbg=DarkCyan",
+	     "MatchParen term=reverse ctermbg=DarkCyan guibg=DarkCyan"),
+#endif
+#ifdef FEAT_GUI
+	"Normal gui=NONE",
+#endif
+	NULL
+    };
+
+    void
+init_highlight(both, reset)
+    int		both;	    /* include groups where 'bg' doesn't matter */
+    int		reset;	    /* clear group first */
+{
+    int		i;
+    char	**pp;
+    static int	had_both = FALSE;
+#ifdef FEAT_EVAL
+    char_u	*p;
+
+    /*
+     * Try finding the color scheme file.  Used when a color file was loaded
+     * and 'background' or 't_Co' is changed.
+     */
+    p = get_var_value((char_u *)"g:colors_name");
+    if (p != NULL && load_colors(p) == OK)
+	return;
+#endif
+
+    /*
+     * Didn't use a color file, use the compiled-in colors.
+     */
+    if (both)
+    {
+	had_both = TRUE;
+	pp = highlight_init_both;
+	for (i = 0; pp[i] != NULL; ++i)
+	    do_highlight((char_u *)pp[i], reset, TRUE);
+    }
+    else if (!had_both)
+	/* Don't do anything before the call with both == TRUE from main().
+	 * Not everything has been setup then, and that call will overrule
+	 * everything anyway. */
+	return;
+
+    if (*p_bg == 'l')
+	pp = highlight_init_light;
+    else
+	pp = highlight_init_dark;
+    for (i = 0; pp[i] != NULL; ++i)
+	do_highlight((char_u *)pp[i], reset, TRUE);
+
+    /* Reverse looks ugly, but grey may not work for 8 colors.  Thus let it
+     * depend on the number of colors available.
+     * With 8 colors brown is equal to yellow, need to use black for Search fg
+     * to avoid Statement highlighted text disappears. */
+    if (t_colors > 8)
+	do_highlight((char_u *)(*p_bg == 'l' ? "Visual ctermbg=LightGrey"
+				   : "Visual ctermbg=DarkGrey"), FALSE, TRUE);
+    else
+    {
+	do_highlight((char_u *)"Visual cterm=reverse", FALSE, TRUE);
+	if (*p_bg == 'l')
+	    do_highlight((char_u *)"Search ctermfg=black", FALSE, TRUE);
+    }
+
+#ifdef FEAT_SYN_HL
+    /*
+     * If syntax highlighting is enabled load the highlighting for it.
+     */
+    if (get_var_value((char_u *)"g:syntax_on") != NULL)
+    {
+	static int	recursive = 0;
+
+	if (recursive >= 5)
+	    EMSG(_("E679: recursive loop loading syncolor.vim"));
+	else
+	{
+	    ++recursive;
+	    (void)source_runtime((char_u *)"syntax/syncolor.vim", TRUE);
+	    --recursive;
+	}
+    }
+#endif
+}
+
+/*
+ * Load color file "name".
+ * Return OK for success, FAIL for failure.
+ */
+    int
+load_colors(name)
+    char_u	*name;
+{
+    char_u	*buf;
+    int		retval = FAIL;
+    static int	recursive = FALSE;
+
+    /* When being called recursively, this is probably because setting
+     * 'background' caused the highlighting to be reloaded.  This means it is
+     * working, thus we should return OK. */
+    if (recursive)
+	return OK;
+
+    recursive = TRUE;
+    buf = alloc((unsigned)(STRLEN(name) + 12));
+    if (buf != NULL)
+    {
+	sprintf((char *)buf, "colors/%s.vim", name);
+	retval = source_runtime(buf, FALSE);
+	vim_free(buf);
+#ifdef FEAT_AUTOCMD
+	apply_autocmds(EVENT_COLORSCHEME, NULL, NULL, FALSE, curbuf);
+#endif
+    }
+    recursive = FALSE;
+
+    return retval;
+}
+
+/*
+ * Handle the ":highlight .." command.
+ * When using ":hi clear" this is called recursively for each group with
+ * "forceit" and "init" both TRUE.
+ */
+    void
+do_highlight(line, forceit, init)
+    char_u	*line;
+    int		forceit;
+    int		init;	    /* TRUE when called for initializing */
+{
+    char_u	*name_end;
+    char_u	*p;
+    char_u	*linep;
+    char_u	*key_start;
+    char_u	*arg_start;
+    char_u	*key = NULL, *arg = NULL;
+    long	i;
+    int		off;
+    int		len;
+    int		attr;
+    int		id;
+    int		idx;
+    int		dodefault = FALSE;
+    int		doclear = FALSE;
+    int		dolink = FALSE;
+    int		error = FALSE;
+    int		color;
+    int		is_normal_group = FALSE;	/* "Normal" group */
+#ifdef FEAT_GUI_X11
+    int		is_menu_group = FALSE;		/* "Menu" group */
+    int		is_scrollbar_group = FALSE;	/* "Scrollbar" group */
+    int		is_tooltip_group = FALSE;	/* "Tooltip" group */
+    int		do_colors = FALSE;		/* need to update colors? */
+#else
+# define is_menu_group 0
+# define is_tooltip_group 0
+#endif
+
+    /*
+     * If no argument, list current highlighting.
+     */
+    if (ends_excmd(*line))
+    {
+	for (i = 1; i <= highlight_ga.ga_len && !got_int; ++i)
+	    /* TODO: only call when the group has attributes set */
+	    highlight_list_one((int)i);
+	return;
+    }
+
+    /*
+     * Isolate the name.
+     */
+    name_end = skiptowhite(line);
+    linep = skipwhite(name_end);
+
+    /*
+     * Check for "default" argument.
+     */
+    if (STRNCMP(line, "default", name_end - line) == 0)
+    {
+	dodefault = TRUE;
+	line = linep;
+	name_end = skiptowhite(line);
+	linep = skipwhite(name_end);
+    }
+
+    /*
+     * Check for "clear" or "link" argument.
+     */
+    if (STRNCMP(line, "clear", name_end - line) == 0)
+	doclear = TRUE;
+    if (STRNCMP(line, "link", name_end - line) == 0)
+	dolink = TRUE;
+
+    /*
+     * ":highlight {group-name}": list highlighting for one group.
+     */
+    if (!doclear && !dolink && ends_excmd(*linep))
+    {
+	id = syn_namen2id(line, (int)(name_end - line));
+	if (id == 0)
+	    EMSG2(_("E411: highlight group not found: %s"), line);
+	else
+	    highlight_list_one(id);
+	return;
+    }
+
+    /*
+     * Handle ":highlight link {from} {to}" command.
+     */
+    if (dolink)
+    {
+	char_u	    *from_start = linep;
+	char_u	    *from_end;
+	char_u	    *to_start;
+	char_u	    *to_end;
+	int	    from_id;
+	int	    to_id;
+
+	from_end = skiptowhite(from_start);
+	to_start = skipwhite(from_end);
+	to_end	 = skiptowhite(to_start);
+
+	if (ends_excmd(*from_start) || ends_excmd(*to_start))
+	{
+	    EMSG2(_("E412: Not enough arguments: \":highlight link %s\""),
+								  from_start);
+	    return;
+	}
+
+	if (!ends_excmd(*skipwhite(to_end)))
+	{
+	    EMSG2(_("E413: Too many arguments: \":highlight link %s\""), from_start);
+	    return;
+	}
+
+	from_id = syn_check_group(from_start, (int)(from_end - from_start));
+	if (STRNCMP(to_start, "NONE", 4) == 0)
+	    to_id = 0;
+	else
+	    to_id = syn_check_group(to_start, (int)(to_end - to_start));
+
+	if (from_id > 0 && (!init || HL_TABLE()[from_id - 1].sg_set == 0))
+	{
+	    /*
+	     * Don't allow a link when there already is some highlighting
+	     * for the group, unless '!' is used
+	     */
+	    if (to_id > 0 && !forceit && !init
+				   && hl_has_settings(from_id - 1, dodefault))
+	    {
+		if (sourcing_name == NULL && !dodefault)
+		    EMSG(_("E414: group has settings, highlight link ignored"));
+	    }
+	    else
+	    {
+		if (!init)
+		    HL_TABLE()[from_id - 1].sg_set |= SG_LINK;
+		HL_TABLE()[from_id - 1].sg_link = to_id;
+#ifdef FEAT_EVAL
+		HL_TABLE()[from_id - 1].sg_scriptID = current_SID;
+#endif
+		redraw_all_later(SOME_VALID);
+	    }
+	}
+
+	/* Only call highlight_changed() once, after sourcing a syntax file */
+	need_highlight_changed = TRUE;
+
+	return;
+    }
+
+    if (doclear)
+    {
+	/*
+	 * ":highlight clear [group]" command.
+	 */
+	line = linep;
+	if (ends_excmd(*line))
+	{
+#ifdef FEAT_GUI
+	    /* First, we do not destroy the old values, but allocate the new
+	     * ones and update the display. THEN we destroy the old values.
+	     * If we destroy the old values first, then the old values
+	     * (such as GuiFont's or GuiFontset's) will still be displayed but
+	     * invalid because they were free'd.
+	     */
+	    if (gui.in_use)
+	    {
+# ifdef FEAT_BEVAL_TIP
+		gui_init_tooltip_font();
+# endif
+# if defined(FEAT_MENU) && (defined(FEAT_GUI_ATHENA) || defined(FEAT_GUI_MOTIF))
+		gui_init_menu_font();
+# endif
+	    }
+# if defined(FEAT_GUI_MSWIN) || defined(FEAT_GUI_X11)
+	    gui_mch_def_colors();
+# endif
+# ifdef FEAT_GUI_X11
+#  ifdef FEAT_MENU
+
+	    /* This only needs to be done when there is no Menu highlight
+	     * group defined by default, which IS currently the case.
+	     */
+	    gui_mch_new_menu_colors();
+#  endif
+	    if (gui.in_use)
+	    {
+		gui_new_scrollbar_colors();
+#  ifdef FEAT_BEVAL
+		gui_mch_new_tooltip_colors();
+#  endif
+#  ifdef FEAT_MENU
+		gui_mch_new_menu_font();
+#  endif
+	    }
+# endif
+
+	    /* Ok, we're done allocating the new default graphics items.
+	     * The screen should already be refreshed at this point.
+	     * It is now Ok to clear out the old data.
+	     */
+#endif
+#ifdef FEAT_EVAL
+	    do_unlet((char_u *)"colors_name", TRUE);
+#endif
+	    restore_cterm_colors();
+
+	    /*
+	     * Clear all default highlight groups and load the defaults.
+	     */
+	    for (idx = 0; idx < highlight_ga.ga_len; ++idx)
+		highlight_clear(idx);
+	    init_highlight(TRUE, TRUE);
+#ifdef FEAT_GUI
+	    if (gui.in_use)
+		highlight_gui_started();
+#endif
+	    highlight_changed();
+	    redraw_later_clear();
+	    return;
+	}
+	name_end = skiptowhite(line);
+	linep = skipwhite(name_end);
+    }
+
+    /*
+     * Find the group name in the table.  If it does not exist yet, add it.
+     */
+    id = syn_check_group(line, (int)(name_end - line));
+    if (id == 0)			/* failed (out of memory) */
+	return;
+    idx = id - 1;			/* index is ID minus one */
+
+    /* Return if "default" was used and the group already has settings. */
+    if (dodefault && hl_has_settings(idx, TRUE))
+	return;
+
+    if (STRCMP(HL_TABLE()[idx].sg_name_u, "NORMAL") == 0)
+	is_normal_group = TRUE;
+#ifdef FEAT_GUI_X11
+    else if (STRCMP(HL_TABLE()[idx].sg_name_u, "MENU") == 0)
+	is_menu_group = TRUE;
+    else if (STRCMP(HL_TABLE()[idx].sg_name_u, "SCROLLBAR") == 0)
+	is_scrollbar_group = TRUE;
+    else if (STRCMP(HL_TABLE()[idx].sg_name_u, "TOOLTIP") == 0)
+	is_tooltip_group = TRUE;
+#endif
+
+    /* Clear the highlighting for ":hi clear {group}" and ":hi clear". */
+    if (doclear || (forceit && init))
+    {
+	highlight_clear(idx);
+	if (!doclear)
+	    HL_TABLE()[idx].sg_set = 0;
+    }
+
+    if (!doclear)
+      while (!ends_excmd(*linep))
+      {
+	key_start = linep;
+	if (*linep == '=')
+	{
+	    EMSG2(_("E415: unexpected equal sign: %s"), key_start);
+	    error = TRUE;
+	    break;
+	}
+
+	/*
+	 * Isolate the key ("term", "ctermfg", "ctermbg", "font", "guifg" or
+	 * "guibg").
+	 */
+	while (*linep && !vim_iswhite(*linep) && *linep != '=')
+	    ++linep;
+	vim_free(key);
+	key = vim_strnsave_up(key_start, (int)(linep - key_start));
+	if (key == NULL)
+	{
+	    error = TRUE;
+	    break;
+	}
+	linep = skipwhite(linep);
+
+	if (STRCMP(key, "NONE") == 0)
+	{
+	    if (!init || HL_TABLE()[idx].sg_set == 0)
+	    {
+		if (!init)
+		    HL_TABLE()[idx].sg_set |= SG_TERM+SG_CTERM+SG_GUI;
+		highlight_clear(idx);
+	    }
+	    continue;
+	}
+
+	/*
+	 * Check for the equal sign.
+	 */
+	if (*linep != '=')
+	{
+	    EMSG2(_("E416: missing equal sign: %s"), key_start);
+	    error = TRUE;
+	    break;
+	}
+	++linep;
+
+	/*
+	 * Isolate the argument.
+	 */
+	linep = skipwhite(linep);
+	if (*linep == '\'')		/* guifg='color name' */
+	{
+	    arg_start = ++linep;
+	    linep = vim_strchr(linep, '\'');
+	    if (linep == NULL)
+	    {
+		EMSG2(_(e_invarg2), key_start);
+		error = TRUE;
+		break;
+	    }
+	}
+	else
+	{
+	    arg_start = linep;
+	    linep = skiptowhite(linep);
+	}
+	if (linep == arg_start)
+	{
+	    EMSG2(_("E417: missing argument: %s"), key_start);
+	    error = TRUE;
+	    break;
+	}
+	vim_free(arg);
+	arg = vim_strnsave(arg_start, (int)(linep - arg_start));
+	if (arg == NULL)
+	{
+	    error = TRUE;
+	    break;
+	}
+	if (*linep == '\'')
+	    ++linep;
+
+	/*
+	 * Store the argument.
+	 */
+	if (  STRCMP(key, "TERM") == 0
+		|| STRCMP(key, "CTERM") == 0
+		|| STRCMP(key, "GUI") == 0)
+	{
+	    attr = 0;
+	    off = 0;
+	    while (arg[off] != NUL)
+	    {
+		for (i = sizeof(hl_attr_table) / sizeof(int); --i >= 0; )
+		{
+		    len = (int)STRLEN(hl_name_table[i]);
+		    if (STRNICMP(arg + off, hl_name_table[i], len) == 0)
+		    {
+			attr |= hl_attr_table[i];
+			off += len;
+			break;
+		    }
+		}
+		if (i < 0)
+		{
+		    EMSG2(_("E418: Illegal value: %s"), arg);
+		    error = TRUE;
+		    break;
+		}
+		if (arg[off] == ',')		/* another one follows */
+		    ++off;
+	    }
+	    if (error)
+		break;
+	    if (*key == 'T')
+	    {
+		if (!init || !(HL_TABLE()[idx].sg_set & SG_TERM))
+		{
+		    if (!init)
+			HL_TABLE()[idx].sg_set |= SG_TERM;
+		    HL_TABLE()[idx].sg_term = attr;
+		}
+	    }
+	    else if (*key == 'C')
+	    {
+		if (!init || !(HL_TABLE()[idx].sg_set & SG_CTERM))
+		{
+		    if (!init)
+			HL_TABLE()[idx].sg_set |= SG_CTERM;
+		    HL_TABLE()[idx].sg_cterm = attr;
+		    HL_TABLE()[idx].sg_cterm_bold = FALSE;
+		}
+	    }
+#ifdef FEAT_GUI
+	    else
+	    {
+		if (!init || !(HL_TABLE()[idx].sg_set & SG_GUI))
+		{
+		    if (!init)
+			HL_TABLE()[idx].sg_set |= SG_GUI;
+		    HL_TABLE()[idx].sg_gui = attr;
+		}
+	    }
+#endif
+	}
+	else if (STRCMP(key, "FONT") == 0)
+	{
+	    /* in non-GUI fonts are simply ignored */
+#ifdef FEAT_GUI
+	    if (!gui.shell_created)
+	    {
+		/* GUI not started yet, always accept the name. */
+		vim_free(HL_TABLE()[idx].sg_font_name);
+		HL_TABLE()[idx].sg_font_name = vim_strsave(arg);
+	    }
+	    else
+	    {
+		GuiFont temp_sg_font = HL_TABLE()[idx].sg_font;
+# ifdef FEAT_XFONTSET
+		GuiFontset temp_sg_fontset = HL_TABLE()[idx].sg_fontset;
+# endif
+		/* First, save the current font/fontset.
+		 * Then try to allocate the font/fontset.
+		 * If the allocation fails, HL_TABLE()[idx].sg_font OR
+		 * sg_fontset will be set to NOFONT or NOFONTSET respectively.
+		 */
+
+		HL_TABLE()[idx].sg_font = NOFONT;
+# ifdef FEAT_XFONTSET
+		HL_TABLE()[idx].sg_fontset = NOFONTSET;
+# endif
+		hl_do_font(idx, arg, is_normal_group, is_menu_group,
+							    is_tooltip_group);
+
+# ifdef FEAT_XFONTSET
+		if (HL_TABLE()[idx].sg_fontset != NOFONTSET)
+		{
+		    /* New fontset was accepted. Free the old one, if there was
+		     * one.
+		     */
+		    gui_mch_free_fontset(temp_sg_fontset);
+		    vim_free(HL_TABLE()[idx].sg_font_name);
+		    HL_TABLE()[idx].sg_font_name = vim_strsave(arg);
+		}
+		else
+		    HL_TABLE()[idx].sg_fontset = temp_sg_fontset;
+# endif
+		if (HL_TABLE()[idx].sg_font != NOFONT)
+		{
+		    /* New font was accepted. Free the old one, if there was
+		     * one.
+		     */
+		    gui_mch_free_font(temp_sg_font);
+		    vim_free(HL_TABLE()[idx].sg_font_name);
+		    HL_TABLE()[idx].sg_font_name = vim_strsave(arg);
+		}
+		else
+		    HL_TABLE()[idx].sg_font = temp_sg_font;
+	    }
+#endif
+	}
+	else if (STRCMP(key, "CTERMFG") == 0 || STRCMP(key, "CTERMBG") == 0)
+	{
+	  if (!init || !(HL_TABLE()[idx].sg_set & SG_CTERM))
+	  {
+	    if (!init)
+		HL_TABLE()[idx].sg_set |= SG_CTERM;
+
+	    /* When setting the foreground color, and previously the "bold"
+	     * flag was set for a light color, reset it now */
+	    if (key[5] == 'F' && HL_TABLE()[idx].sg_cterm_bold)
+	    {
+		HL_TABLE()[idx].sg_cterm &= ~HL_BOLD;
+		HL_TABLE()[idx].sg_cterm_bold = FALSE;
+	    }
+
+	    if (VIM_ISDIGIT(*arg))
+		color = atoi((char *)arg);
+	    else if (STRICMP(arg, "fg") == 0)
+	    {
+		if (cterm_normal_fg_color)
+		    color = cterm_normal_fg_color - 1;
+		else
+		{
+		    EMSG(_("E419: FG color unknown"));
+		    error = TRUE;
+		    break;
+		}
+	    }
+	    else if (STRICMP(arg, "bg") == 0)
+	    {
+		if (cterm_normal_bg_color > 0)
+		    color = cterm_normal_bg_color - 1;
+		else
+		{
+		    EMSG(_("E420: BG color unknown"));
+		    error = TRUE;
+		    break;
+		}
+	    }
+	    else
+	    {
+		static char *(color_names[28]) = {
+			    "Black", "DarkBlue", "DarkGreen", "DarkCyan",
+			    "DarkRed", "DarkMagenta", "Brown", "DarkYellow",
+			    "Gray", "Grey",
+			    "LightGray", "LightGrey", "DarkGray", "DarkGrey",
+			    "Blue", "LightBlue", "Green", "LightGreen",
+			    "Cyan", "LightCyan", "Red", "LightRed", "Magenta",
+			    "LightMagenta", "Yellow", "LightYellow", "White", "NONE"};
+		static int color_numbers_16[28] = {0, 1, 2, 3,
+						 4, 5, 6, 6,
+						 7, 7,
+						 7, 7, 8, 8,
+						 9, 9, 10, 10,
+						 11, 11, 12, 12, 13,
+						 13, 14, 14, 15, -1};
+		/* for xterm with 88 colors... */
+		static int color_numbers_88[28] = {0, 4, 2, 6,
+						 1, 5, 32, 72,
+						 84, 84,
+						 7, 7, 82, 82,
+						 12, 43, 10, 61,
+						 14, 63, 9, 74, 13,
+						 75, 11, 78, 15, -1};
+		/* for xterm with 256 colors... */
+		static int color_numbers_256[28] = {0, 4, 2, 6,
+						 1, 5, 130, 130,
+						 248, 248,
+						 7, 7, 242, 242,
+						 12, 81, 10, 121,
+						 14, 159, 9, 224, 13,
+						 225, 11, 229, 15, -1};
+		/* for terminals with less than 16 colors... */
+		static int color_numbers_8[28] = {0, 4, 2, 6,
+						 1, 5, 3, 3,
+						 7, 7,
+						 7, 7, 0+8, 0+8,
+						 4+8, 4+8, 2+8, 2+8,
+						 6+8, 6+8, 1+8, 1+8, 5+8,
+						 5+8, 3+8, 3+8, 7+8, -1};
+#if defined(__QNXNTO__)
+		static int *color_numbers_8_qansi = color_numbers_8;
+		/* On qnx, the 8 & 16 color arrays are the same */
+		if (STRNCMP(T_NAME, "qansi", 5) == 0)
+		    color_numbers_8_qansi = color_numbers_16;
+#endif
+
+		/* reduce calls to STRICMP a bit, it can be slow */
+		off = TOUPPER_ASC(*arg);
+		for (i = (sizeof(color_names) / sizeof(char *)); --i >= 0; )
+		    if (off == color_names[i][0]
+				 && STRICMP(arg + 1, color_names[i] + 1) == 0)
+			break;
+		if (i < 0)
+		{
+		    EMSG2(_("E421: Color name or number not recognized: %s"), key_start);
+		    error = TRUE;
+		    break;
+		}
+
+		/* Use the _16 table to check if its a valid color name. */
+		color = color_numbers_16[i];
+		if (color >= 0)
+		{
+		    if (t_colors == 8)
+		    {
+			/* t_Co is 8: use the 8 colors table */
+#if defined(__QNXNTO__)
+			color = color_numbers_8_qansi[i];
+#else
+			color = color_numbers_8[i];
+#endif
+			if (key[5] == 'F')
+			{
+			    /* set/reset bold attribute to get light foreground
+			     * colors (on some terminals, e.g. "linux") */
+			    if (color & 8)
+			    {
+				HL_TABLE()[idx].sg_cterm |= HL_BOLD;
+				HL_TABLE()[idx].sg_cterm_bold = TRUE;
+			    }
+			    else
+				HL_TABLE()[idx].sg_cterm &= ~HL_BOLD;
+			}
+			color &= 7;	/* truncate to 8 colors */
+		    }
+		    else if (t_colors == 16 || t_colors == 88
+							   || t_colors == 256)
+		    {
+			/*
+			 * Guess: if the termcap entry ends in 'm', it is
+			 * probably an xterm-like terminal.  Use the changed
+			 * order for colors.
+			 */
+			if (*T_CAF != NUL)
+			    p = T_CAF;
+			else
+			    p = T_CSF;
+			if (*p != NUL && *(p + STRLEN(p) - 1) == 'm')
+			    switch (t_colors)
+			    {
+				case 16:
+				    color = color_numbers_8[i];
+				    break;
+				case 88:
+				    color = color_numbers_88[i];
+				    break;
+				case 256:
+				    color = color_numbers_256[i];
+				    break;
+			    }
+		    }
+		}
+	    }
+	    /* Add one to the argument, to avoid zero */
+	    if (key[5] == 'F')
+	    {
+		HL_TABLE()[idx].sg_cterm_fg = color + 1;
+		if (is_normal_group)
+		{
+		    cterm_normal_fg_color = color + 1;
+		    cterm_normal_fg_bold = (HL_TABLE()[idx].sg_cterm & HL_BOLD);
+#ifdef FEAT_GUI
+		    /* Don't do this if the GUI is used. */
+		    if (!gui.in_use && !gui.starting)
+#endif
+		    {
+			must_redraw = CLEAR;
+			if (termcap_active)
+			    term_fg_color(color);
+		    }
+		}
+	    }
+	    else
+	    {
+		HL_TABLE()[idx].sg_cterm_bg = color + 1;
+		if (is_normal_group)
+		{
+		    cterm_normal_bg_color = color + 1;
+#ifdef FEAT_GUI
+		    /* Don't mess with 'background' if the GUI is used. */
+		    if (!gui.in_use && !gui.starting)
+#endif
+		    {
+			must_redraw = CLEAR;
+			if (termcap_active)
+			    term_bg_color(color);
+			if (t_colors < 16)
+			    i = (color == 0 || color == 4);
+			else
+			    i = (color < 7 || color == 8);
+			/* Set the 'background' option if the value is wrong. */
+			if (i != (*p_bg == 'd'))
+			    set_option_value((char_u *)"bg", 0L,
+				 i ? (char_u *)"dark" : (char_u *)"light", 0);
+		    }
+		}
+	    }
+	  }
+	}
+	else if (STRCMP(key, "GUIFG") == 0)
+	{
+#ifdef FEAT_GUI	    /* in non-GUI guifg colors are simply ignored */
+	    if (!init || !(HL_TABLE()[idx].sg_set & SG_GUI))
+	    {
+		if (!init)
+		    HL_TABLE()[idx].sg_set |= SG_GUI;
+
+		i = color_name2handle(arg);
+		if (i != INVALCOLOR || STRCMP(arg, "NONE") == 0 || !gui.in_use)
+		{
+		    HL_TABLE()[idx].sg_gui_fg = i;
+		    vim_free(HL_TABLE()[idx].sg_gui_fg_name);
+		    if (STRCMP(arg, "NONE"))
+			HL_TABLE()[idx].sg_gui_fg_name = vim_strsave(arg);
+		    else
+			HL_TABLE()[idx].sg_gui_fg_name = NULL;
+# ifdef FEAT_GUI_X11
+		    if (is_menu_group)
+			gui.menu_fg_pixel = i;
+		    if (is_scrollbar_group)
+			gui.scroll_fg_pixel = i;
+#  ifdef FEAT_BEVAL
+		    if (is_tooltip_group)
+			gui.tooltip_fg_pixel = i;
+#  endif
+		    do_colors = TRUE;
+# endif
+		}
+	    }
+#endif
+	}
+	else if (STRCMP(key, "GUIBG") == 0)
+	{
+#ifdef FEAT_GUI	    /* in non-GUI guibg colors are simply ignored */
+	    if (!init || !(HL_TABLE()[idx].sg_set & SG_GUI))
+	    {
+		if (!init)
+		    HL_TABLE()[idx].sg_set |= SG_GUI;
+
+		i = color_name2handle(arg);
+		if (i != INVALCOLOR || STRCMP(arg, "NONE") == 0 || !gui.in_use)
+		{
+		    HL_TABLE()[idx].sg_gui_bg = i;
+		    vim_free(HL_TABLE()[idx].sg_gui_bg_name);
+		    if (STRCMP(arg, "NONE") != 0)
+			HL_TABLE()[idx].sg_gui_bg_name = vim_strsave(arg);
+		    else
+			HL_TABLE()[idx].sg_gui_bg_name = NULL;
+# ifdef FEAT_GUI_X11
+		    if (is_menu_group)
+			gui.menu_bg_pixel = i;
+		    if (is_scrollbar_group)
+			gui.scroll_bg_pixel = i;
+#  ifdef FEAT_BEVAL
+		    if (is_tooltip_group)
+			gui.tooltip_bg_pixel = i;
+#  endif
+		    do_colors = TRUE;
+# endif
+		}
+	    }
+#endif
+	}
+	else if (STRCMP(key, "GUISP") == 0)
+	{
+#ifdef FEAT_GUI	    /* in non-GUI guisp colors are simply ignored */
+	    if (!init || !(HL_TABLE()[idx].sg_set & SG_GUI))
+	    {
+		if (!init)
+		    HL_TABLE()[idx].sg_set |= SG_GUI;
+
+		i = color_name2handle(arg);
+		if (i != INVALCOLOR || STRCMP(arg, "NONE") == 0 || !gui.in_use)
+		{
+		    HL_TABLE()[idx].sg_gui_sp = i;
+		    vim_free(HL_TABLE()[idx].sg_gui_sp_name);
+		    if (STRCMP(arg, "NONE") != 0)
+			HL_TABLE()[idx].sg_gui_sp_name = vim_strsave(arg);
+		    else
+			HL_TABLE()[idx].sg_gui_sp_name = NULL;
+		}
+	    }
+#endif
+	}
+	else if (STRCMP(key, "START") == 0 || STRCMP(key, "STOP") == 0)
+	{
+	    char_u	buf[100];
+	    char_u	*tname;
+
+	    if (!init)
+		HL_TABLE()[idx].sg_set |= SG_TERM;
+
+	    /*
+	     * The "start" and "stop"  arguments can be a literal escape
+	     * sequence, or a comma separated list of terminal codes.
+	     */
+	    if (STRNCMP(arg, "t_", 2) == 0)
+	    {
+		off = 0;
+		buf[0] = 0;
+		while (arg[off] != NUL)
+		{
+		    /* Isolate one termcap name */
+		    for (len = 0; arg[off + len] &&
+						 arg[off + len] != ','; ++len)
+			;
+		    tname = vim_strnsave(arg + off, len);
+		    if (tname == NULL)		/* out of memory */
+		    {
+			error = TRUE;
+			break;
+		    }
+		    /* lookup the escape sequence for the item */
+		    p = get_term_code(tname);
+		    vim_free(tname);
+		    if (p == NULL)	    /* ignore non-existing things */
+			p = (char_u *)"";
+
+		    /* Append it to the already found stuff */
+		    if ((int)(STRLEN(buf) + STRLEN(p)) >= 99)
+		    {
+			EMSG2(_("E422: terminal code too long: %s"), arg);
+			error = TRUE;
+			break;
+		    }
+		    STRCAT(buf, p);
+
+		    /* Advance to the next item */
+		    off += len;
+		    if (arg[off] == ',')	    /* another one follows */
+			++off;
+		}
+	    }
+	    else
+	    {
+		/*
+		 * Copy characters from arg[] to buf[], translating <> codes.
+		 */
+		for (p = arg, off = 0; off < 100 && *p; )
+		{
+		    len = trans_special(&p, buf + off, FALSE);
+		    if (len)		    /* recognized special char */
+			off += len;
+		    else		    /* copy as normal char */
+			buf[off++] = *p++;
+		}
+		buf[off] = NUL;
+	    }
+	    if (error)
+		break;
+
+	    if (STRCMP(buf, "NONE") == 0)	/* resetting the value */
+		p = NULL;
+	    else
+		p = vim_strsave(buf);
+	    if (key[2] == 'A')
+	    {
+		vim_free(HL_TABLE()[idx].sg_start);
+		HL_TABLE()[idx].sg_start = p;
+	    }
+	    else
+	    {
+		vim_free(HL_TABLE()[idx].sg_stop);
+		HL_TABLE()[idx].sg_stop = p;
+	    }
+	}
+	else
+	{
+	    EMSG2(_("E423: Illegal argument: %s"), key_start);
+	    error = TRUE;
+	    break;
+	}
+
+	/*
+	 * When highlighting has been given for a group, don't link it.
+	 */
+	if (!init || !(HL_TABLE()[idx].sg_set & SG_LINK))
+	    HL_TABLE()[idx].sg_link = 0;
+
+	/*
+	 * Continue with next argument.
+	 */
+	linep = skipwhite(linep);
+      }
+
+    /*
+     * If there is an error, and it's a new entry, remove it from the table.
+     */
+    if (error && idx == highlight_ga.ga_len)
+	syn_unadd_group();
+    else
+    {
+	if (is_normal_group)
+	{
+	    HL_TABLE()[idx].sg_term_attr = 0;
+	    HL_TABLE()[idx].sg_cterm_attr = 0;
+#ifdef FEAT_GUI
+	    HL_TABLE()[idx].sg_gui_attr = 0;
+	    /*
+	     * Need to update all groups, because they might be using "bg"
+	     * and/or "fg", which have been changed now.
+	     */
+	    if (gui.in_use)
+		highlight_gui_started();
+#endif
+	}
+#ifdef FEAT_GUI_X11
+# ifdef FEAT_MENU
+	else if (is_menu_group)
+	{
+	    if (gui.in_use && do_colors)
+		gui_mch_new_menu_colors();
+	}
+# endif
+	else if (is_scrollbar_group)
+	{
+	    if (gui.in_use && do_colors)
+		gui_new_scrollbar_colors();
+	}
+# ifdef FEAT_BEVAL
+	else if (is_tooltip_group)
+	{
+	    if (gui.in_use && do_colors)
+		gui_mch_new_tooltip_colors();
+	}
+# endif
+#endif
+	else
+	    set_hl_attr(idx);
+#ifdef FEAT_EVAL
+	HL_TABLE()[idx].sg_scriptID = current_SID;
+#endif
+	redraw_all_later(NOT_VALID);
+    }
+    vim_free(key);
+    vim_free(arg);
+
+    /* Only call highlight_changed() once, after sourcing a syntax file */
+    need_highlight_changed = TRUE;
+}
+
+#if defined(EXITFREE) || defined(PROTO)
+    void
+free_highlight()
+{
+    int	    i;
+
+    for (i = 0; i < highlight_ga.ga_len; ++i)
+    {
+	highlight_clear(i);
+	vim_free(HL_TABLE()[i].sg_name);
+	vim_free(HL_TABLE()[i].sg_name_u);
+    }
+    ga_clear(&highlight_ga);
+}
+#endif
+
+/*
+ * Reset the cterm colors to what they were before Vim was started, if
+ * possible.  Otherwise reset them to zero.
+ */
+    void
+restore_cterm_colors()
+{
+#if defined(MSDOS) || (defined(WIN3264) && !defined(FEAT_GUI_W32)) || defined(PLAN9)
+    /* Since t_me has been set, this probably means that the user
+     * wants to use this as default colors.  Need to reset default
+     * background/foreground colors. */
+    mch_set_normal_colors();
+#else
+    cterm_normal_fg_color = 0;
+    cterm_normal_fg_bold = 0;
+    cterm_normal_bg_color = 0;
+#endif
+}
+
+/*
+ * Return TRUE if highlight group "idx" has any settings.
+ * When "check_link" is TRUE also check for an existing link.
+ */
+    static int
+hl_has_settings(idx, check_link)
+    int		idx;
+    int		check_link;
+{
+    return (   HL_TABLE()[idx].sg_term_attr != 0
+	    || HL_TABLE()[idx].sg_cterm_attr != 0
+#ifdef FEAT_GUI
+	    || HL_TABLE()[idx].sg_gui_attr != 0
+#endif
+	    || (check_link && (HL_TABLE()[idx].sg_set & SG_LINK)));
+}
+
+/*
+ * Clear highlighting for one group.
+ */
+    static void
+highlight_clear(idx)
+    int idx;
+{
+    HL_TABLE()[idx].sg_term = 0;
+    vim_free(HL_TABLE()[idx].sg_start);
+    HL_TABLE()[idx].sg_start = NULL;
+    vim_free(HL_TABLE()[idx].sg_stop);
+    HL_TABLE()[idx].sg_stop = NULL;
+    HL_TABLE()[idx].sg_term_attr = 0;
+    HL_TABLE()[idx].sg_cterm = 0;
+    HL_TABLE()[idx].sg_cterm_bold = FALSE;
+    HL_TABLE()[idx].sg_cterm_fg = 0;
+    HL_TABLE()[idx].sg_cterm_bg = 0;
+    HL_TABLE()[idx].sg_cterm_attr = 0;
+#ifdef FEAT_GUI	    /* in non-GUI fonts are simply ignored */
+    HL_TABLE()[idx].sg_gui = 0;
+    HL_TABLE()[idx].sg_gui_fg = INVALCOLOR;
+    vim_free(HL_TABLE()[idx].sg_gui_fg_name);
+    HL_TABLE()[idx].sg_gui_fg_name = NULL;
+    HL_TABLE()[idx].sg_gui_bg = INVALCOLOR;
+    vim_free(HL_TABLE()[idx].sg_gui_bg_name);
+    HL_TABLE()[idx].sg_gui_bg_name = NULL;
+    HL_TABLE()[idx].sg_gui_sp = INVALCOLOR;
+    vim_free(HL_TABLE()[idx].sg_gui_sp_name);
+    HL_TABLE()[idx].sg_gui_sp_name = NULL;
+    gui_mch_free_font(HL_TABLE()[idx].sg_font);
+    HL_TABLE()[idx].sg_font = NOFONT;
+# ifdef FEAT_XFONTSET
+    gui_mch_free_fontset(HL_TABLE()[idx].sg_fontset);
+    HL_TABLE()[idx].sg_fontset = NOFONTSET;
+# endif
+    vim_free(HL_TABLE()[idx].sg_font_name);
+    HL_TABLE()[idx].sg_font_name = NULL;
+    HL_TABLE()[idx].sg_gui_attr = 0;
+#endif
+#ifdef FEAT_EVAL
+    /* Clear the script ID only when there is no link, since that is not
+     * cleared. */
+    if (HL_TABLE()[idx].sg_link == 0)
+	HL_TABLE()[idx].sg_scriptID = 0;
+#endif
+}
+
+#if defined(FEAT_GUI) || defined(PROTO)
+/*
+ * Set the normal foreground and background colors according to the "Normal"
+ * highlighighting group.  For X11 also set "Menu", "Scrollbar", and
+ * "Tooltip" colors.
+ */
+    void
+set_normal_colors()
+{
+    if (set_group_colors((char_u *)"Normal",
+			     &gui.norm_pixel, &gui.back_pixel,
+			     FALSE, TRUE, FALSE))
+    {
+	gui_mch_new_colors();
+	must_redraw = CLEAR;
+    }
+#ifdef FEAT_GUI_X11
+    if (set_group_colors((char_u *)"Menu",
+			 &gui.menu_fg_pixel, &gui.menu_bg_pixel,
+			 TRUE, FALSE, FALSE))
+    {
+# ifdef FEAT_MENU
+	gui_mch_new_menu_colors();
+# endif
+	must_redraw = CLEAR;
+    }
+# ifdef FEAT_BEVAL
+    if (set_group_colors((char_u *)"Tooltip",
+			 &gui.tooltip_fg_pixel, &gui.tooltip_bg_pixel,
+			 FALSE, FALSE, TRUE))
+    {
+# ifdef FEAT_TOOLBAR
+	gui_mch_new_tooltip_colors();
+# endif
+	must_redraw = CLEAR;
+    }
+#endif
+    if (set_group_colors((char_u *)"Scrollbar",
+		    &gui.scroll_fg_pixel, &gui.scroll_bg_pixel,
+		    FALSE, FALSE, FALSE))
+    {
+	gui_new_scrollbar_colors();
+	must_redraw = CLEAR;
+    }
+#endif
+}
+
+/*
+ * Set the colors for "Normal", "Menu", "Tooltip" or "Scrollbar".
+ */
+    static int
+set_group_colors(name, fgp, bgp, do_menu, use_norm, do_tooltip)
+    char_u	*name;
+    guicolor_T	*fgp;
+    guicolor_T	*bgp;
+    int		do_menu;
+    int		use_norm;
+    int		do_tooltip;
+{
+    int		idx;
+
+    idx = syn_name2id(name) - 1;
+    if (idx >= 0)
+    {
+	gui_do_one_color(idx, do_menu, do_tooltip);
+
+	if (HL_TABLE()[idx].sg_gui_fg != INVALCOLOR)
+	    *fgp = HL_TABLE()[idx].sg_gui_fg;
+	else if (use_norm)
+	    *fgp = gui.def_norm_pixel;
+	if (HL_TABLE()[idx].sg_gui_bg != INVALCOLOR)
+	    *bgp = HL_TABLE()[idx].sg_gui_bg;
+	else if (use_norm)
+	    *bgp = gui.def_back_pixel;
+	return TRUE;
+    }
+    return FALSE;
+}
+
+/*
+ * Get the font of the "Normal" group.
+ * Returns "" when it's not found or not set.
+ */
+    char_u *
+hl_get_font_name()
+{
+    int		id;
+    char_u	*s;
+
+    id = syn_name2id((char_u *)"Normal");
+    if (id > 0)
+    {
+	s = HL_TABLE()[id - 1].sg_font_name;
+	if (s != NULL)
+	    return s;
+    }
+    return (char_u *)"";
+}
+
+/*
+ * Set font for "Normal" group.  Called by gui_mch_init_font() when a font has
+ * actually chosen to be used.
+ */
+    void
+hl_set_font_name(font_name)
+    char_u	*font_name;
+{
+    int	    id;
+
+    id = syn_name2id((char_u *)"Normal");
+    if (id > 0)
+    {
+	vim_free(HL_TABLE()[id - 1].sg_font_name);
+	HL_TABLE()[id - 1].sg_font_name = vim_strsave(font_name);
+    }
+}
+
+/*
+ * Set background color for "Normal" group.  Called by gui_set_bg_color()
+ * when the color is known.
+ */
+    void
+hl_set_bg_color_name(name)
+    char_u  *name;	    /* must have been allocated */
+{
+    int	    id;
+
+    if (name != NULL)
+    {
+	id = syn_name2id((char_u *)"Normal");
+	if (id > 0)
+	{
+	    vim_free(HL_TABLE()[id - 1].sg_gui_bg_name);
+	    HL_TABLE()[id - 1].sg_gui_bg_name = name;
+	}
+    }
+}
+
+/*
+ * Set foreground color for "Normal" group.  Called by gui_set_fg_color()
+ * when the color is known.
+ */
+    void
+hl_set_fg_color_name(name)
+    char_u  *name;	    /* must have been allocated */
+{
+    int	    id;
+
+    if (name != NULL)
+    {
+	id = syn_name2id((char_u *)"Normal");
+	if (id > 0)
+	{
+	    vim_free(HL_TABLE()[id - 1].sg_gui_fg_name);
+	    HL_TABLE()[id - 1].sg_gui_fg_name = name;
+	}
+    }
+}
+
+/*
+ * Return the handle for a color name.
+ * Returns INVALCOLOR when failed.
+ */
+    static guicolor_T
+color_name2handle(name)
+    char_u  *name;
+{
+    if (STRCMP(name, "NONE") == 0)
+	return INVALCOLOR;
+
+    if (STRICMP(name, "fg") == 0 || STRICMP(name, "foreground") == 0)
+	return gui.norm_pixel;
+    if (STRICMP(name, "bg") == 0 || STRICMP(name, "background") == 0)
+	return gui.back_pixel;
+
+    return gui_get_color(name);
+}
+
+/*
+ * Return the handle for a font name.
+ * Returns NOFONT when failed.
+ */
+    static GuiFont
+font_name2handle(name)
+    char_u  *name;
+{
+    if (STRCMP(name, "NONE") == 0)
+	return NOFONT;
+
+    return gui_mch_get_font(name, TRUE);
+}
+
+# ifdef FEAT_XFONTSET
+/*
+ * Return the handle for a fontset name.
+ * Returns NOFONTSET when failed.
+ */
+    static GuiFontset
+fontset_name2handle(name, fixed_width)
+    char_u	*name;
+    int		fixed_width;
+{
+    if (STRCMP(name, "NONE") == 0)
+	return NOFONTSET;
+
+    return gui_mch_get_fontset(name, TRUE, fixed_width);
+}
+# endif
+
+/*
+ * Get the font or fontset for one highlight group.
+ */
+/*ARGSUSED*/
+    static void
+hl_do_font(idx, arg, do_normal, do_menu, do_tooltip)
+    int		idx;
+    char_u	*arg;
+    int		do_normal;	/* set normal font */
+    int		do_menu;	/* set menu font */
+    int		do_tooltip;	/* set tooltip font */
+{
+# ifdef FEAT_XFONTSET
+    /* If 'guifontset' is not empty, first try using the name as a
+     * fontset.  If that doesn't work, use it as a font name. */
+    if (*p_guifontset != NUL
+#  ifdef FONTSET_ALWAYS
+	|| do_menu
+#  endif
+#  ifdef FEAT_BEVAL_TIP
+	/* In Athena & Motif, the Tooltip highlight group is always a fontset */
+	|| do_tooltip
+#  endif
+	    )
+	HL_TABLE()[idx].sg_fontset = fontset_name2handle(arg, 0
+#  ifdef FONTSET_ALWAYS
+		|| do_menu
+#  endif
+#  ifdef FEAT_BEVAL_TIP
+		|| do_tooltip
+#  endif
+		);
+    if (HL_TABLE()[idx].sg_fontset != NOFONTSET)
+    {
+	/* If it worked and it's the Normal group, use it as the
+	 * normal fontset.  Same for the Menu group. */
+	if (do_normal)
+	    gui_init_font(arg, TRUE);
+#   if (defined(FEAT_GUI_MOTIF) || defined(FEAT_GUI_ATHENA)) && defined(FEAT_MENU)
+	if (do_menu)
+	{
+#    ifdef FONTSET_ALWAYS
+	    gui.menu_fontset = HL_TABLE()[idx].sg_fontset;
+#    else
+	    /* YIKES!  This is a bug waiting to crash the program */
+	    gui.menu_font = HL_TABLE()[idx].sg_fontset;
+#    endif
+	    gui_mch_new_menu_font();
+	}
+#    ifdef FEAT_BEVAL
+	if (do_tooltip)
+	{
+	    /* The Athena widget set cannot currently handle switching between
+	     * displaying a single font and a fontset.
+	     * If the XtNinternational resource is set to True at widget
+	     * creation, then a fontset is always used, otherwise an
+	     * XFontStruct is used.
+	     */
+	    gui.tooltip_fontset = (XFontSet)HL_TABLE()[idx].sg_fontset;
+	    gui_mch_new_tooltip_font();
+	}
+#    endif
+#   endif
+    }
+    else
+# endif
+    {
+	HL_TABLE()[idx].sg_font = font_name2handle(arg);
+	/* If it worked and it's the Normal group, use it as the
+	 * normal font.  Same for the Menu group. */
+	if (HL_TABLE()[idx].sg_font != NOFONT)
+	{
+	    if (do_normal)
+		gui_init_font(arg, FALSE);
+#ifndef FONTSET_ALWAYS
+# if (defined(FEAT_GUI_MOTIF) || defined(FEAT_GUI_ATHENA)) && defined(FEAT_MENU)
+	    if (do_menu)
+	    {
+		gui.menu_font = HL_TABLE()[idx].sg_font;
+		gui_mch_new_menu_font();
+	    }
+# endif
+#endif
+	}
+    }
+}
+
+#endif /* FEAT_GUI */
+
+/*
+ * Table with the specifications for an attribute number.
+ * Note that this table is used by ALL buffers.  This is required because the
+ * GUI can redraw at any time for any buffer.
+ */
+static garray_T	term_attr_table = {0, 0, 0, 0, NULL};
+
+#define TERM_ATTR_ENTRY(idx) ((attrentry_T *)term_attr_table.ga_data)[idx]
+
+static garray_T	cterm_attr_table = {0, 0, 0, 0, NULL};
+
+#define CTERM_ATTR_ENTRY(idx) ((attrentry_T *)cterm_attr_table.ga_data)[idx]
+
+#ifdef FEAT_GUI
+static garray_T	gui_attr_table = {0, 0, 0, 0, NULL};
+
+#define GUI_ATTR_ENTRY(idx) ((attrentry_T *)gui_attr_table.ga_data)[idx]
+#endif
+
+/*
+ * Return the attr number for a set of colors and font.
+ * Add a new entry to the term_attr_table, cterm_attr_table or gui_attr_table
+ * if the combination is new.
+ * Return 0 for error (no more room).
+ */
+    static int
+get_attr_entry(table, aep)
+    garray_T	*table;
+    attrentry_T	*aep;
+{
+    int		i;
+    attrentry_T	*taep;
+    static int	recursive = FALSE;
+
+    /*
+     * Init the table, in case it wasn't done yet.
+     */
+    table->ga_itemsize = sizeof(attrentry_T);
+    table->ga_growsize = 7;
+
+    /*
+     * Try to find an entry with the same specifications.
+     */
+    for (i = 0; i < table->ga_len; ++i)
+    {
+	taep = &(((attrentry_T *)table->ga_data)[i]);
+	if (	   aep->ae_attr == taep->ae_attr
+		&& (
+#ifdef FEAT_GUI
+		       (table == &gui_attr_table
+			&& (aep->ae_u.gui.fg_color == taep->ae_u.gui.fg_color
+			    && aep->ae_u.gui.bg_color
+						    == taep->ae_u.gui.bg_color
+			    && aep->ae_u.gui.sp_color
+						    == taep->ae_u.gui.sp_color
+			    && aep->ae_u.gui.font == taep->ae_u.gui.font
+#  ifdef FEAT_XFONTSET
+			    && aep->ae_u.gui.fontset == taep->ae_u.gui.fontset
+#  endif
+			    ))
+		    ||
+#endif
+		       (table == &term_attr_table
+			&& (aep->ae_u.term.start == NULL)
+					    == (taep->ae_u.term.start == NULL)
+			&& (aep->ae_u.term.start == NULL
+			    || STRCMP(aep->ae_u.term.start,
+						  taep->ae_u.term.start) == 0)
+			&& (aep->ae_u.term.stop == NULL)
+					     == (taep->ae_u.term.stop == NULL)
+			&& (aep->ae_u.term.stop == NULL
+			    || STRCMP(aep->ae_u.term.stop,
+						  taep->ae_u.term.stop) == 0))
+		    || (table == &cterm_attr_table
+			    && aep->ae_u.cterm.fg_color
+						  == taep->ae_u.cterm.fg_color
+			    && aep->ae_u.cterm.bg_color
+						 == taep->ae_u.cterm.bg_color)
+		     ))
+
+	return i + ATTR_OFF;
+    }
+
+    if (table->ga_len + ATTR_OFF > MAX_TYPENR)
+    {
+	/*
+	 * Running out of attribute entries!  remove all attributes, and
+	 * compute new ones for all groups.
+	 * When called recursively, we are really out of numbers.
+	 */
+	if (recursive)
+	{
+	    EMSG(_("E424: Too many different highlighting attributes in use"));
+	    return 0;
+	}
+	recursive = TRUE;
+
+	clear_hl_tables();
+
+	must_redraw = CLEAR;
+
+	for (i = 0; i < highlight_ga.ga_len; ++i)
+	    set_hl_attr(i);
+
+	recursive = FALSE;
+    }
+
+    /*
+     * This is a new combination of colors and font, add an entry.
+     */
+    if (ga_grow(table, 1) == FAIL)
+	return 0;
+
+    taep = &(((attrentry_T *)table->ga_data)[table->ga_len]);
+    vim_memset(taep, 0, sizeof(attrentry_T));
+    taep->ae_attr = aep->ae_attr;
+#ifdef FEAT_GUI
+    if (table == &gui_attr_table)
+    {
+	taep->ae_u.gui.fg_color = aep->ae_u.gui.fg_color;
+	taep->ae_u.gui.bg_color = aep->ae_u.gui.bg_color;
+	taep->ae_u.gui.sp_color = aep->ae_u.gui.sp_color;
+	taep->ae_u.gui.font = aep->ae_u.gui.font;
+# ifdef FEAT_XFONTSET
+	taep->ae_u.gui.fontset = aep->ae_u.gui.fontset;
+# endif
+    }
+#endif
+    if (table == &term_attr_table)
+    {
+	if (aep->ae_u.term.start == NULL)
+	    taep->ae_u.term.start = NULL;
+	else
+	    taep->ae_u.term.start = vim_strsave(aep->ae_u.term.start);
+	if (aep->ae_u.term.stop == NULL)
+	    taep->ae_u.term.stop = NULL;
+	else
+	    taep->ae_u.term.stop = vim_strsave(aep->ae_u.term.stop);
+    }
+    else if (table == &cterm_attr_table)
+    {
+	taep->ae_u.cterm.fg_color = aep->ae_u.cterm.fg_color;
+	taep->ae_u.cterm.bg_color = aep->ae_u.cterm.bg_color;
+    }
+    ++table->ga_len;
+    return (table->ga_len - 1 + ATTR_OFF);
+}
+
+/*
+ * Clear all highlight tables.
+ */
+    void
+clear_hl_tables()
+{
+    int		i;
+    attrentry_T	*taep;
+
+#ifdef FEAT_GUI
+    ga_clear(&gui_attr_table);
+#endif
+    for (i = 0; i < term_attr_table.ga_len; ++i)
+    {
+	taep = &(((attrentry_T *)term_attr_table.ga_data)[i]);
+	vim_free(taep->ae_u.term.start);
+	vim_free(taep->ae_u.term.stop);
+    }
+    ga_clear(&term_attr_table);
+    ga_clear(&cterm_attr_table);
+}
+
+#if defined(FEAT_SYN_HL) || defined(FEAT_SPELL) || defined(PROTO)
+/*
+ * Combine special attributes (e.g., for spelling) with other attributes
+ * (e.g., for syntax highlighting).
+ * "prim_attr" overrules "char_attr".
+ * This creates a new group when required.
+ * Since we expect there to be few spelling mistakes we don't cache the
+ * result.
+ * Return the resulting attributes.
+ */
+    int
+hl_combine_attr(char_attr, prim_attr)
+    int	    char_attr;
+    int	    prim_attr;
+{
+    attrentry_T *char_aep = NULL;
+    attrentry_T *spell_aep;
+    attrentry_T new_en;
+
+    if (char_attr == 0)
+	return prim_attr;
+    if (char_attr <= HL_ALL && prim_attr <= HL_ALL)
+	return char_attr | prim_attr;
+#ifdef FEAT_GUI
+    if (gui.in_use)
+    {
+	if (char_attr > HL_ALL)
+	    char_aep = syn_gui_attr2entry(char_attr);
+	if (char_aep != NULL)
+	    new_en = *char_aep;
+	else
+	{
+	    vim_memset(&new_en, 0, sizeof(new_en));
+	    new_en.ae_u.gui.fg_color = INVALCOLOR;
+	    new_en.ae_u.gui.bg_color = INVALCOLOR;
+	    new_en.ae_u.gui.sp_color = INVALCOLOR;
+	    if (char_attr <= HL_ALL)
+		new_en.ae_attr = char_attr;
+	}
+
+	if (prim_attr <= HL_ALL)
+	    new_en.ae_attr |= prim_attr;
+	else
+	{
+	    spell_aep = syn_gui_attr2entry(prim_attr);
+	    if (spell_aep != NULL)
+	    {
+		new_en.ae_attr |= spell_aep->ae_attr;
+		if (spell_aep->ae_u.gui.fg_color != INVALCOLOR)
+		    new_en.ae_u.gui.fg_color = spell_aep->ae_u.gui.fg_color;
+		if (spell_aep->ae_u.gui.bg_color != INVALCOLOR)
+		    new_en.ae_u.gui.bg_color = spell_aep->ae_u.gui.bg_color;
+		if (spell_aep->ae_u.gui.sp_color != INVALCOLOR)
+		    new_en.ae_u.gui.sp_color = spell_aep->ae_u.gui.sp_color;
+		if (spell_aep->ae_u.gui.font != NOFONT)
+		    new_en.ae_u.gui.font = spell_aep->ae_u.gui.font;
+# ifdef FEAT_XFONTSET
+		if (spell_aep->ae_u.gui.fontset != NOFONTSET)
+		    new_en.ae_u.gui.fontset = spell_aep->ae_u.gui.fontset;
+# endif
+	    }
+	}
+	return get_attr_entry(&gui_attr_table, &new_en);
+    }
+#endif
+
+    if (t_colors > 1)
+    {
+	if (char_attr > HL_ALL)
+	    char_aep = syn_cterm_attr2entry(char_attr);
+	if (char_aep != NULL)
+	    new_en = *char_aep;
+	else
+	{
+	    vim_memset(&new_en, 0, sizeof(new_en));
+	    if (char_attr <= HL_ALL)
+		new_en.ae_attr = char_attr;
+	}
+
+	if (prim_attr <= HL_ALL)
+	    new_en.ae_attr |= prim_attr;
+	else
+	{
+	    spell_aep = syn_cterm_attr2entry(prim_attr);
+	    if (spell_aep != NULL)
+	    {
+		new_en.ae_attr |= spell_aep->ae_attr;
+		if (spell_aep->ae_u.cterm.fg_color > 0)
+		    new_en.ae_u.cterm.fg_color = spell_aep->ae_u.cterm.fg_color;
+		if (spell_aep->ae_u.cterm.bg_color > 0)
+		    new_en.ae_u.cterm.bg_color = spell_aep->ae_u.cterm.bg_color;
+	    }
+	}
+	return get_attr_entry(&cterm_attr_table, &new_en);
+    }
+
+    if (char_attr > HL_ALL)
+	char_aep = syn_term_attr2entry(char_attr);
+    if (char_aep != NULL)
+	new_en = *char_aep;
+    else
+    {
+	vim_memset(&new_en, 0, sizeof(new_en));
+	if (char_attr <= HL_ALL)
+	    new_en.ae_attr = char_attr;
+    }
+
+    if (prim_attr <= HL_ALL)
+	new_en.ae_attr |= prim_attr;
+    else
+    {
+	spell_aep = syn_term_attr2entry(prim_attr);
+	if (spell_aep != NULL)
+	{
+	    new_en.ae_attr |= spell_aep->ae_attr;
+	    if (spell_aep->ae_u.term.start != NULL)
+	    {
+		new_en.ae_u.term.start = spell_aep->ae_u.term.start;
+		new_en.ae_u.term.stop = spell_aep->ae_u.term.stop;
+	    }
+	}
+    }
+    return get_attr_entry(&term_attr_table, &new_en);
+}
+#endif
+
+#ifdef FEAT_GUI
+
+    attrentry_T *
+syn_gui_attr2entry(attr)
+    int		    attr;
+{
+    attr -= ATTR_OFF;
+    if (attr >= gui_attr_table.ga_len)	    /* did ":syntax clear" */
+	return NULL;
+    return &(GUI_ATTR_ENTRY(attr));
+}
+#endif /* FEAT_GUI */
+
+/*
+ * Get the highlight attributes (HL_BOLD etc.) from an attribute nr.
+ * Only to be used when "attr" > HL_ALL.
+ */
+    int
+syn_attr2attr(attr)
+    int	    attr;
+{
+    attrentry_T	*aep;
+
+#ifdef FEAT_GUI
+    if (gui.in_use)
+	aep = syn_gui_attr2entry(attr);
+    else
+#endif
+	if (t_colors > 1)
+	aep = syn_cterm_attr2entry(attr);
+    else
+	aep = syn_term_attr2entry(attr);
+
+    if (aep == NULL)	    /* highlighting not set */
+	return 0;
+    return aep->ae_attr;
+}
+
+
+    attrentry_T *
+syn_term_attr2entry(attr)
+    int		    attr;
+{
+    attr -= ATTR_OFF;
+    if (attr >= term_attr_table.ga_len)	    /* did ":syntax clear" */
+	return NULL;
+    return &(TERM_ATTR_ENTRY(attr));
+}
+
+    attrentry_T *
+syn_cterm_attr2entry(attr)
+    int		    attr;
+{
+    attr -= ATTR_OFF;
+    if (attr >= cterm_attr_table.ga_len)	/* did ":syntax clear" */
+	return NULL;
+    return &(CTERM_ATTR_ENTRY(attr));
+}
+
+#define LIST_ATTR   1
+#define LIST_STRING 2
+#define LIST_INT    3
+
+    static void
+highlight_list_one(id)
+    int		id;
+{
+    struct hl_group	*sgp;
+    int			didh = FALSE;
+
+    sgp = &HL_TABLE()[id - 1];	    /* index is ID minus one */
+
+    didh = highlight_list_arg(id, didh, LIST_ATTR,
+				    sgp->sg_term, NULL, "term");
+    didh = highlight_list_arg(id, didh, LIST_STRING,
+				    0, sgp->sg_start, "start");
+    didh = highlight_list_arg(id, didh, LIST_STRING,
+				    0, sgp->sg_stop, "stop");
+
+    didh = highlight_list_arg(id, didh, LIST_ATTR,
+				    sgp->sg_cterm, NULL, "cterm");
+    didh = highlight_list_arg(id, didh, LIST_INT,
+				    sgp->sg_cterm_fg, NULL, "ctermfg");
+    didh = highlight_list_arg(id, didh, LIST_INT,
+				    sgp->sg_cterm_bg, NULL, "ctermbg");
+
+#ifdef FEAT_GUI
+    didh = highlight_list_arg(id, didh, LIST_ATTR,
+				    sgp->sg_gui, NULL, "gui");
+    didh = highlight_list_arg(id, didh, LIST_STRING,
+				    0, sgp->sg_gui_fg_name, "guifg");
+    didh = highlight_list_arg(id, didh, LIST_STRING,
+				    0, sgp->sg_gui_bg_name, "guibg");
+    didh = highlight_list_arg(id, didh, LIST_STRING,
+				    0, sgp->sg_gui_sp_name, "guisp");
+    didh = highlight_list_arg(id, didh, LIST_STRING,
+				    0, sgp->sg_font_name, "font");
+#endif
+
+    if (sgp->sg_link && !got_int)
+    {
+	(void)syn_list_header(didh, 9999, id);
+	didh = TRUE;
+	msg_puts_attr((char_u *)"links to", hl_attr(HLF_D));
+	msg_putchar(' ');
+	msg_outtrans(HL_TABLE()[HL_TABLE()[id - 1].sg_link - 1].sg_name);
+    }
+
+    if (!didh)
+	highlight_list_arg(id, didh, LIST_STRING, 0, (char_u *)"cleared", "");
+#ifdef FEAT_EVAL
+    if (p_verbose > 0)
+	last_set_msg(sgp->sg_scriptID);
+#endif
+}
+
+    static int
+highlight_list_arg(id, didh, type, iarg, sarg, name)
+    int		id;
+    int		didh;
+    int		type;
+    int		iarg;
+    char_u	*sarg;
+    char	*name;
+{
+    char_u	buf[100];
+    char_u	*ts;
+    int		i;
+
+    if (got_int)
+	return FALSE;
+    if (type == LIST_STRING ? (sarg != NULL) : (iarg != 0))
+    {
+	ts = buf;
+	if (type == LIST_INT)
+	    sprintf((char *)buf, "%d", iarg - 1);
+	else if (type == LIST_STRING)
+	    ts = sarg;
+	else /* type == LIST_ATTR */
+	{
+	    buf[0] = NUL;
+	    for (i = 0; hl_attr_table[i] != 0; ++i)
+	    {
+		if (iarg & hl_attr_table[i])
+		{
+		    if (buf[0] != NUL)
+			STRCAT(buf, ",");
+		    STRCAT(buf, hl_name_table[i]);
+		    iarg &= ~hl_attr_table[i];	    /* don't want "inverse" */
+		}
+	    }
+	}
+
+	(void)syn_list_header(didh,
+			       (int)(vim_strsize(ts) + STRLEN(name) + 1), id);
+	didh = TRUE;
+	if (!got_int)
+	{
+	    if (*name != NUL)
+	    {
+		MSG_PUTS_ATTR(name, hl_attr(HLF_D));
+		MSG_PUTS_ATTR("=", hl_attr(HLF_D));
+	    }
+	    msg_outtrans(ts);
+	}
+    }
+    return didh;
+}
+
+#if (((defined(FEAT_EVAL) || defined(FEAT_PRINTER))) && defined(FEAT_SYN_HL)) || defined(PROTO)
+/*
+ * Return "1" if highlight group "id" has attribute "flag".
+ * Return NULL otherwise.
+ */
+    char_u *
+highlight_has_attr(id, flag, modec)
+    int		id;
+    int		flag;
+    int		modec;	/* 'g' for GUI, 'c' for cterm, 't' for term */
+{
+    int		attr;
+
+    if (id <= 0 || id > highlight_ga.ga_len)
+	return NULL;
+
+#ifdef FEAT_GUI
+    if (modec == 'g')
+	attr = HL_TABLE()[id - 1].sg_gui;
+    else
+#endif
+	 if (modec == 'c')
+	attr = HL_TABLE()[id - 1].sg_cterm;
+    else
+	attr = HL_TABLE()[id - 1].sg_term;
+
+    if (attr & flag)
+	return (char_u *)"1";
+    return NULL;
+}
+#endif
+
+#if (defined(FEAT_SYN_HL) && defined(FEAT_EVAL)) || defined(PROTO)
+/*
+ * Return color name of highlight group "id".
+ */
+    char_u *
+highlight_color(id, what, modec)
+    int		id;
+    char_u	*what;	/* "fg", "bg", "sp", "fg#", "bg#" or "sp#" */
+    int		modec;	/* 'g' for GUI, 'c' for cterm, 't' for term */
+{
+    static char_u	name[20];
+    int			n;
+    int			fg = FALSE;
+# ifdef FEAT_GUI
+    int			sp = FALSE;
+# endif
+
+    if (id <= 0 || id > highlight_ga.ga_len)
+	return NULL;
+
+    if (TOLOWER_ASC(what[0]) == 'f')
+	fg = TRUE;
+# ifdef FEAT_GUI
+    else if (TOLOWER_ASC(what[0]) == 's')
+	sp = TRUE;
+    if (modec == 'g')
+    {
+	/* return #RRGGBB form (only possible when GUI is running) */
+	if (gui.in_use && what[1] && what[2] == '#')
+	{
+	    guicolor_T		color;
+	    long_u		rgb;
+	    static char_u	buf[10];
+
+	    if (fg)
+		color = HL_TABLE()[id - 1].sg_gui_fg;
+	    else if (sp)
+		color = HL_TABLE()[id - 1].sg_gui_sp;
+	    else
+		color = HL_TABLE()[id - 1].sg_gui_bg;
+	    if (color == INVALCOLOR)
+		return NULL;
+	    rgb = gui_mch_get_rgb(color);
+	    sprintf((char *)buf, "#%02x%02x%02x",
+				      (unsigned)(rgb >> 16),
+				      (unsigned)(rgb >> 8) & 255,
+				      (unsigned)rgb & 255);
+	    return buf;
+	}
+	if (fg)
+	    return (HL_TABLE()[id - 1].sg_gui_fg_name);
+	if (sp)
+	    return (HL_TABLE()[id - 1].sg_gui_sp_name);
+	return (HL_TABLE()[id - 1].sg_gui_bg_name);
+    }
+# endif
+    if (modec == 'c')
+    {
+	if (fg)
+	    n = HL_TABLE()[id - 1].sg_cterm_fg - 1;
+	else
+	    n = HL_TABLE()[id - 1].sg_cterm_bg - 1;
+	sprintf((char *)name, "%d", n);
+	return name;
+    }
+    /* term doesn't have color */
+    return NULL;
+}
+#endif
+
+#if (defined(FEAT_SYN_HL) && defined(FEAT_GUI) && defined(FEAT_PRINTER)) \
+	|| defined(PROTO)
+/*
+ * Return color name of highlight group "id" as RGB value.
+ */
+    long_u
+highlight_gui_color_rgb(id, fg)
+    int		id;
+    int		fg;	/* TRUE = fg, FALSE = bg */
+{
+    guicolor_T	color;
+
+    if (id <= 0 || id > highlight_ga.ga_len)
+	return 0L;
+
+    if (fg)
+	color = HL_TABLE()[id - 1].sg_gui_fg;
+    else
+	color = HL_TABLE()[id - 1].sg_gui_bg;
+
+    if (color == INVALCOLOR)
+	return 0L;
+
+    return gui_mch_get_rgb(color);
+}
+#endif
+
+/*
+ * Output the syntax list header.
+ * Return TRUE when started a new line.
+ */
+    static int
+syn_list_header(did_header, outlen, id)
+    int	    did_header;		/* did header already */
+    int	    outlen;		/* length of string that comes */
+    int	    id;			/* highlight group id */
+{
+    int	    endcol = 19;
+    int	    newline = TRUE;
+
+    if (!did_header)
+    {
+	msg_putchar('\n');
+	if (got_int)
+	    return TRUE;
+	msg_outtrans(HL_TABLE()[id - 1].sg_name);
+	endcol = 15;
+    }
+    else if (msg_col + outlen + 1 >= Columns)
+    {
+	msg_putchar('\n');
+	if (got_int)
+	    return TRUE;
+    }
+    else
+    {
+	if (msg_col >= endcol)	/* wrap around is like starting a new line */
+	    newline = FALSE;
+    }
+
+    if (msg_col >= endcol)	/* output at least one space */
+	endcol = msg_col + 1;
+    if (Columns <= endcol)	/* avoid hang for tiny window */
+	endcol = Columns - 1;
+
+    msg_advance(endcol);
+
+    /* Show "xxx" with the attributes. */
+    if (!did_header)
+    {
+	msg_puts_attr((char_u *)"xxx", syn_id2attr(id));
+	msg_putchar(' ');
+    }
+
+    return newline;
+}
+
+/*
+ * Set the attribute numbers for a highlight group.
+ * Called after one of the attributes has changed.
+ */
+    static void
+set_hl_attr(idx)
+    int		idx;	    /* index in array */
+{
+    attrentry_T		at_en;
+    struct hl_group	*sgp = HL_TABLE() + idx;
+
+    /* The "Normal" group doesn't need an attribute number */
+    if (sgp->sg_name_u != NULL && STRCMP(sgp->sg_name_u, "NORMAL") == 0)
+	return;
+
+#ifdef FEAT_GUI
+    /*
+     * For the GUI mode: If there are other than "normal" highlighting
+     * attributes, need to allocate an attr number.
+     */
+    if (sgp->sg_gui_fg == INVALCOLOR
+	    && sgp->sg_gui_bg == INVALCOLOR
+	    && sgp->sg_gui_sp == INVALCOLOR
+	    && sgp->sg_font == NOFONT
+# ifdef FEAT_XFONTSET
+	    && sgp->sg_fontset == NOFONTSET
+# endif
+	    )
+    {
+	sgp->sg_gui_attr = sgp->sg_gui;
+    }
+    else
+    {
+	at_en.ae_attr = sgp->sg_gui;
+	at_en.ae_u.gui.fg_color = sgp->sg_gui_fg;
+	at_en.ae_u.gui.bg_color = sgp->sg_gui_bg;
+	at_en.ae_u.gui.sp_color = sgp->sg_gui_sp;
+	at_en.ae_u.gui.font = sgp->sg_font;
+# ifdef FEAT_XFONTSET
+	at_en.ae_u.gui.fontset = sgp->sg_fontset;
+# endif
+	sgp->sg_gui_attr = get_attr_entry(&gui_attr_table, &at_en);
+    }
+#endif
+    /*
+     * For the term mode: If there are other than "normal" highlighting
+     * attributes, need to allocate an attr number.
+     */
+    if (sgp->sg_start == NULL && sgp->sg_stop == NULL)
+	sgp->sg_term_attr = sgp->sg_term;
+    else
+    {
+	at_en.ae_attr = sgp->sg_term;
+	at_en.ae_u.term.start = sgp->sg_start;
+	at_en.ae_u.term.stop = sgp->sg_stop;
+	sgp->sg_term_attr = get_attr_entry(&term_attr_table, &at_en);
+    }
+
+    /*
+     * For the color term mode: If there are other than "normal"
+     * highlighting attributes, need to allocate an attr number.
+     */
+    if (sgp->sg_cterm_fg == 0 && sgp->sg_cterm_bg == 0)
+	sgp->sg_cterm_attr = sgp->sg_cterm;
+    else
+    {
+	at_en.ae_attr = sgp->sg_cterm;
+	at_en.ae_u.cterm.fg_color = sgp->sg_cterm_fg;
+	at_en.ae_u.cterm.bg_color = sgp->sg_cterm_bg;
+	sgp->sg_cterm_attr = get_attr_entry(&cterm_attr_table, &at_en);
+    }
+}
+
+/*
+ * Lookup a highlight group name and return it's ID.
+ * If it is not found, 0 is returned.
+ */
+    int
+syn_name2id(name)
+    char_u	*name;
+{
+    int		i;
+    char_u	name_u[200];
+
+    /* Avoid using stricmp() too much, it's slow on some systems */
+    /* Avoid alloc()/free(), these are slow too.  ID names over 200 chars
+     * don't deserve to be found! */
+    vim_strncpy(name_u, name, 199);
+    vim_strup(name_u);
+    for (i = highlight_ga.ga_len; --i >= 0; )
+	if (HL_TABLE()[i].sg_name_u != NULL
+		&& STRCMP(name_u, HL_TABLE()[i].sg_name_u) == 0)
+	    break;
+    return i + 1;
+}
+
+#if defined(FEAT_EVAL) || defined(PROTO)
+/*
+ * Return TRUE if highlight group "name" exists.
+ */
+    int
+highlight_exists(name)
+    char_u	*name;
+{
+    return (syn_name2id(name) > 0);
+}
+
+# if defined(FEAT_SEARCH_EXTRA) || defined(PROTO)
+/*
+ * Return the name of highlight group "id".
+ * When not a valid ID return an empty string.
+ */
+    char_u *
+syn_id2name(id)
+    int		id;
+{
+    if (id <= 0 || id >= highlight_ga.ga_len)
+	return (char_u *)"";
+    return HL_TABLE()[id - 1].sg_name;
+}
+# endif
+#endif
+
+/*
+ * Like syn_name2id(), but take a pointer + length argument.
+ */
+    int
+syn_namen2id(linep, len)
+    char_u  *linep;
+    int	    len;
+{
+    char_u  *name;
+    int	    id = 0;
+
+    name = vim_strnsave(linep, len);
+    if (name != NULL)
+    {
+	id = syn_name2id(name);
+	vim_free(name);
+    }
+    return id;
+}
+
+/*
+ * Find highlight group name in the table and return it's ID.
+ * The argument is a pointer to the name and the length of the name.
+ * If it doesn't exist yet, a new entry is created.
+ * Return 0 for failure.
+ */
+    int
+syn_check_group(pp, len)
+    char_u		*pp;
+    int			len;
+{
+    int	    id;
+    char_u  *name;
+
+    name = vim_strnsave(pp, len);
+    if (name == NULL)
+	return 0;
+
+    id = syn_name2id(name);
+    if (id == 0)			/* doesn't exist yet */
+	id = syn_add_group(name);
+    else
+	vim_free(name);
+    return id;
+}
+
+/*
+ * Add new highlight group and return it's ID.
+ * "name" must be an allocated string, it will be consumed.
+ * Return 0 for failure.
+ */
+    static int
+syn_add_group(name)
+    char_u	*name;
+{
+    char_u	*p;
+
+    /* Check that the name is ASCII letters, digits and underscore. */
+    for (p = name; *p != NUL; ++p)
+    {
+	if (!vim_isprintc(*p))
+	{
+	    EMSG(_("E669: Unprintable character in group name"));
+	    return 0;
+	}
+	else if (!ASCII_ISALNUM(*p) && *p != '_')
+	{
+	    /* This is an error, but since there previously was no check only
+	     * give a warning. */
+	    msg_source(hl_attr(HLF_W));
+	    MSG(_("W18: Invalid character in group name"));
+	    break;
+	}
+    }
+
+    /*
+     * First call for this growarray: init growing array.
+     */
+    if (highlight_ga.ga_data == NULL)
+    {
+	highlight_ga.ga_itemsize = sizeof(struct hl_group);
+	highlight_ga.ga_growsize = 10;
+    }
+
+    /*
+     * Make room for at least one other syntax_highlight entry.
+     */
+    if (ga_grow(&highlight_ga, 1) == FAIL)
+    {
+	vim_free(name);
+	return 0;
+    }
+
+    vim_memset(&(HL_TABLE()[highlight_ga.ga_len]), 0, sizeof(struct hl_group));
+    HL_TABLE()[highlight_ga.ga_len].sg_name = name;
+    HL_TABLE()[highlight_ga.ga_len].sg_name_u = vim_strsave_up(name);
+#ifdef FEAT_GUI
+    HL_TABLE()[highlight_ga.ga_len].sg_gui_bg = INVALCOLOR;
+    HL_TABLE()[highlight_ga.ga_len].sg_gui_fg = INVALCOLOR;
+    HL_TABLE()[highlight_ga.ga_len].sg_gui_sp = INVALCOLOR;
+#endif
+    ++highlight_ga.ga_len;
+
+    return highlight_ga.ga_len;		    /* ID is index plus one */
+}
+
+/*
+ * When, just after calling syn_add_group(), an error is discovered, this
+ * function deletes the new name.
+ */
+    static void
+syn_unadd_group()
+{
+    --highlight_ga.ga_len;
+    vim_free(HL_TABLE()[highlight_ga.ga_len].sg_name);
+    vim_free(HL_TABLE()[highlight_ga.ga_len].sg_name_u);
+}
+
+/*
+ * Translate a group ID to highlight attributes.
+ */
+    int
+syn_id2attr(hl_id)
+    int			hl_id;
+{
+    int			attr;
+    struct hl_group	*sgp;
+
+    hl_id = syn_get_final_id(hl_id);
+    sgp = &HL_TABLE()[hl_id - 1];	    /* index is ID minus one */
+
+#ifdef FEAT_GUI
+    /*
+     * Only use GUI attr when the GUI is being used.
+     */
+    if (gui.in_use)
+	attr = sgp->sg_gui_attr;
+    else
+#endif
+	if (t_colors > 1)
+	    attr = sgp->sg_cterm_attr;
+	else
+	    attr = sgp->sg_term_attr;
+
+    return attr;
+}
+
+#ifdef FEAT_GUI
+/*
+ * Get the GUI colors and attributes for a group ID.
+ * NOTE: the colors will be INVALCOLOR when not set, the color otherwise.
+ */
+    int
+syn_id2colors(hl_id, fgp, bgp)
+    int		hl_id;
+    guicolor_T	*fgp;
+    guicolor_T	*bgp;
+{
+    struct hl_group	*sgp;
+
+    hl_id = syn_get_final_id(hl_id);
+    sgp = &HL_TABLE()[hl_id - 1];	    /* index is ID minus one */
+
+    *fgp = sgp->sg_gui_fg;
+    *bgp = sgp->sg_gui_bg;
+    return sgp->sg_gui;
+}
+#endif
+
+/*
+ * Translate a group ID to the final group ID (following links).
+ */
+    int
+syn_get_final_id(hl_id)
+    int			hl_id;
+{
+    int			count;
+    struct hl_group	*sgp;
+
+    if (hl_id > highlight_ga.ga_len || hl_id < 1)
+	return 0;			/* Can be called from eval!! */
+
+    /*
+     * Follow links until there is no more.
+     * Look out for loops!  Break after 100 links.
+     */
+    for (count = 100; --count >= 0; )
+    {
+	sgp = &HL_TABLE()[hl_id - 1];	    /* index is ID minus one */
+	if (sgp->sg_link == 0 || sgp->sg_link > highlight_ga.ga_len)
+	    break;
+	hl_id = sgp->sg_link;
+    }
+
+    return hl_id;
+}
+
+#ifdef FEAT_GUI
+/*
+ * Call this function just after the GUI has started.
+ * It finds the font and color handles for the highlighting groups.
+ */
+    void
+highlight_gui_started()
+{
+    int	    idx;
+
+    /* First get the colors from the "Normal" and "Menu" group, if set */
+    set_normal_colors();
+
+    for (idx = 0; idx < highlight_ga.ga_len; ++idx)
+	gui_do_one_color(idx, FALSE, FALSE);
+
+    highlight_changed();
+}
+
+    static void
+gui_do_one_color(idx, do_menu, do_tooltip)
+    int		idx;
+    int		do_menu;	/* TRUE: might set the menu font */
+    int		do_tooltip;	/* TRUE: might set the tooltip font */
+{
+    int		didit = FALSE;
+
+    if (HL_TABLE()[idx].sg_font_name != NULL)
+    {
+	hl_do_font(idx, HL_TABLE()[idx].sg_font_name, FALSE, do_menu,
+		   do_tooltip);
+	didit = TRUE;
+    }
+    if (HL_TABLE()[idx].sg_gui_fg_name != NULL)
+    {
+	HL_TABLE()[idx].sg_gui_fg =
+			    color_name2handle(HL_TABLE()[idx].sg_gui_fg_name);
+	didit = TRUE;
+    }
+    if (HL_TABLE()[idx].sg_gui_bg_name != NULL)
+    {
+	HL_TABLE()[idx].sg_gui_bg =
+			    color_name2handle(HL_TABLE()[idx].sg_gui_bg_name);
+	didit = TRUE;
+    }
+    if (HL_TABLE()[idx].sg_gui_sp_name != NULL)
+    {
+	HL_TABLE()[idx].sg_gui_sp =
+			    color_name2handle(HL_TABLE()[idx].sg_gui_sp_name);
+	didit = TRUE;
+    }
+    if (didit)	/* need to get a new attr number */
+	set_hl_attr(idx);
+}
+
+#endif
+
+/*
+ * Translate the 'highlight' option into attributes in highlight_attr[] and
+ * set up the user highlights User1..9.  If FEAT_STL_OPT is in use, a set of
+ * corresponding highlights to use on top of HLF_SNC is computed.
+ * Called only when the 'highlight' option has been changed and upon first
+ * screen redraw after any :highlight command.
+ * Return FAIL when an invalid flag is found in 'highlight'.  OK otherwise.
+ */
+    int
+highlight_changed()
+{
+    int		hlf;
+    int		i;
+    char_u	*p;
+    int		attr;
+    char_u	*end;
+    int		id;
+#ifdef USER_HIGHLIGHT
+    char_u      userhl[10];
+# ifdef FEAT_STL_OPT
+    int		id_SNC = -1;
+    int		id_S = -1;
+    int		hlcnt;
+# endif
+#endif
+    static int	hl_flags[HLF_COUNT] = HL_FLAGS;
+
+    need_highlight_changed = FALSE;
+
+    /*
+     * Clear all attributes.
+     */
+    for (hlf = 0; hlf < (int)HLF_COUNT; ++hlf)
+	highlight_attr[hlf] = 0;
+
+    /*
+     * First set all attributes to their default value.
+     * Then use the attributes from the 'highlight' option.
+     */
+    for (i = 0; i < 2; ++i)
+    {
+	if (i)
+	    p = p_hl;
+	else
+	    p = get_highlight_default();
+	if (p == NULL)	    /* just in case */
+	    continue;
+
+	while (*p)
+	{
+	    for (hlf = 0; hlf < (int)HLF_COUNT; ++hlf)
+		if (hl_flags[hlf] == *p)
+		    break;
+	    ++p;
+	    if (hlf == (int)HLF_COUNT || *p == NUL)
+		return FAIL;
+
+	    /*
+	     * Allow several hl_flags to be combined, like "bu" for
+	     * bold-underlined.
+	     */
+	    attr = 0;
+	    for ( ; *p && *p != ','; ++p)	    /* parse upto comma */
+	    {
+		if (vim_iswhite(*p))		    /* ignore white space */
+		    continue;
+
+		if (attr > HL_ALL)  /* Combination with ':' is not allowed. */
+		    return FAIL;
+
+		switch (*p)
+		{
+		    case 'b':	attr |= HL_BOLD;
+				break;
+		    case 'i':	attr |= HL_ITALIC;
+				break;
+		    case '-':
+		    case 'n':			    /* no highlighting */
+				break;
+		    case 'r':	attr |= HL_INVERSE;
+				break;
+		    case 's':	attr |= HL_STANDOUT;
+				break;
+		    case 'u':	attr |= HL_UNDERLINE;
+				break;
+		    case 'c':	attr |= HL_UNDERCURL;
+				break;
+		    case ':':	++p;		    /* highlight group name */
+				if (attr || *p == NUL)	 /* no combinations */
+				    return FAIL;
+				end = vim_strchr(p, ',');
+				if (end == NULL)
+				    end = p + STRLEN(p);
+				id = syn_check_group(p, (int)(end - p));
+				if (id == 0)
+				    return FAIL;
+				attr = syn_id2attr(id);
+				p = end - 1;
+#if defined(FEAT_STL_OPT) && defined(USER_HIGHLIGHT)
+				if (hlf == (int)HLF_SNC)
+				    id_SNC = syn_get_final_id(id);
+				else if (hlf == (int)HLF_S)
+				    id_S = syn_get_final_id(id);
+#endif
+				break;
+		    default:	return FAIL;
+		}
+	    }
+	    highlight_attr[hlf] = attr;
+
+	    p = skip_to_option_part(p);	    /* skip comma and spaces */
+	}
+    }
+
+#ifdef USER_HIGHLIGHT
+    /* Setup the user highlights
+     *
+     * Temporarily  utilize 10 more hl entries.  Have to be in there
+     * simultaneously in case of table overflows in get_attr_entry()
+     */
+# ifdef FEAT_STL_OPT
+    if (ga_grow(&highlight_ga, 10) == FAIL)
+	return FAIL;
+    hlcnt = highlight_ga.ga_len;
+    if (id_S == 0)
+    {		    /* Make sure id_S is always valid to simplify code below */
+	memset(&HL_TABLE()[hlcnt + 9], 0, sizeof(struct hl_group));
+	HL_TABLE()[hlcnt + 9].sg_term = highlight_attr[HLF_S];
+	id_S = hlcnt + 10;
+    }
+# endif
+    for (i = 0; i < 9; i++)
+    {
+	sprintf((char *)userhl, "User%d", i + 1);
+	id = syn_name2id(userhl);
+	if (id == 0)
+	{
+	    highlight_user[i] = 0;
+# ifdef FEAT_STL_OPT
+	    highlight_stlnc[i] = 0;
+# endif
+	}
+	else
+	{
+# ifdef FEAT_STL_OPT
+	    struct hl_group *hlt = HL_TABLE();
+# endif
+
+	    highlight_user[i] = syn_id2attr(id);
+# ifdef FEAT_STL_OPT
+	    if (id_SNC == 0)
+	    {
+		memset(&hlt[hlcnt + i], 0, sizeof(struct hl_group));
+		hlt[hlcnt + i].sg_term = highlight_attr[HLF_SNC];
+		hlt[hlcnt + i].sg_cterm = highlight_attr[HLF_SNC];
+#  ifdef FEAT_GUI
+		hlt[hlcnt + i].sg_gui = highlight_attr[HLF_SNC];
+#  endif
+	    }
+	    else
+		mch_memmove(&hlt[hlcnt + i],
+			    &hlt[id_SNC - 1],
+			    sizeof(struct hl_group));
+	    hlt[hlcnt + i].sg_link = 0;
+
+	    /* Apply difference between UserX and HLF_S to HLF_SNC */
+	    hlt[hlcnt + i].sg_term ^=
+		hlt[id - 1].sg_term ^ hlt[id_S - 1].sg_term;
+	    if (hlt[id - 1].sg_start != hlt[id_S - 1].sg_start)
+		hlt[hlcnt + i].sg_start = hlt[id - 1].sg_start;
+	    if (hlt[id - 1].sg_stop != hlt[id_S - 1].sg_stop)
+		hlt[hlcnt + i].sg_stop = hlt[id - 1].sg_stop;
+	    hlt[hlcnt + i].sg_cterm ^=
+		hlt[id - 1].sg_cterm ^ hlt[id_S - 1].sg_cterm;
+	    if (hlt[id - 1].sg_cterm_fg != hlt[id_S - 1].sg_cterm_fg)
+		hlt[hlcnt + i].sg_cterm_fg = hlt[id - 1].sg_cterm_fg;
+	    if (hlt[id - 1].sg_cterm_bg != hlt[id_S - 1].sg_cterm_bg)
+		hlt[hlcnt + i].sg_cterm_bg = hlt[id - 1].sg_cterm_bg;
+#  ifdef FEAT_GUI
+	    hlt[hlcnt + i].sg_gui ^=
+		hlt[id - 1].sg_gui ^ hlt[id_S - 1].sg_gui;
+	    if (hlt[id - 1].sg_gui_fg != hlt[id_S - 1].sg_gui_fg)
+		hlt[hlcnt + i].sg_gui_fg = hlt[id - 1].sg_gui_fg;
+	    if (hlt[id - 1].sg_gui_bg != hlt[id_S - 1].sg_gui_bg)
+		hlt[hlcnt + i].sg_gui_bg = hlt[id - 1].sg_gui_bg;
+	    if (hlt[id - 1].sg_gui_sp != hlt[id_S - 1].sg_gui_sp)
+		hlt[hlcnt + i].sg_gui_sp = hlt[id - 1].sg_gui_sp;
+	    if (hlt[id - 1].sg_font != hlt[id_S - 1].sg_font)
+		hlt[hlcnt + i].sg_font = hlt[id - 1].sg_font;
+#   ifdef FEAT_XFONTSET
+	    if (hlt[id - 1].sg_fontset != hlt[id_S - 1].sg_fontset)
+		hlt[hlcnt + i].sg_fontset = hlt[id - 1].sg_fontset;
+#   endif
+#  endif
+	    highlight_ga.ga_len = hlcnt + i + 1;
+	    set_hl_attr(hlcnt + i);	/* At long last we can apply */
+	    highlight_stlnc[i] = syn_id2attr(hlcnt + i + 1);
+# endif
+	}
+    }
+# ifdef FEAT_STL_OPT
+    highlight_ga.ga_len = hlcnt;
+# endif
+
+#endif /* USER_HIGHLIGHT */
+
+    return OK;
+}
+
+#ifdef FEAT_CMDL_COMPL
+
+static void highlight_list __ARGS((void));
+static void highlight_list_two __ARGS((int cnt, int attr));
+
+/*
+ * Handle command line completion for :highlight command.
+ */
+    void
+set_context_in_highlight_cmd(xp, arg)
+    expand_T	*xp;
+    char_u	*arg;
+{
+    char_u	*p;
+
+    /* Default: expand group names */
+    xp->xp_context = EXPAND_HIGHLIGHT;
+    xp->xp_pattern = arg;
+    include_link = TRUE;
+    include_default = TRUE;
+
+    /* (part of) subcommand already typed */
+    if (*arg != NUL)
+    {
+	p = skiptowhite(arg);
+	if (*p != NUL)			/* past "default" or group name */
+	{
+	    include_default = FALSE;
+	    if (STRNCMP("default", arg, p - arg) == 0)
+	    {
+		arg = skipwhite(p);
+		xp->xp_pattern = arg;
+		p = skiptowhite(arg);
+	    }
+	    if (*p != NUL)			/* past group name */
+	    {
+		include_link = FALSE;
+		if (arg[1] == 'i' && arg[0] == 'N')
+		    highlight_list();
+		if (STRNCMP("link", arg, p - arg) == 0
+			|| STRNCMP("clear", arg, p - arg) == 0)
+		{
+		    xp->xp_pattern = skipwhite(p);
+		    p = skiptowhite(xp->xp_pattern);
+		    if (*p != NUL)		/* past first group name */
+		    {
+			xp->xp_pattern = skipwhite(p);
+			p = skiptowhite(xp->xp_pattern);
+		    }
+		}
+		if (*p != NUL)			/* past group name(s) */
+		    xp->xp_context = EXPAND_NOTHING;
+	    }
+	}
+    }
+}
+
+/*
+ * List highlighting matches in a nice way.
+ */
+    static void
+highlight_list()
+{
+    int		i;
+
+    for (i = 10; --i >= 0; )
+	highlight_list_two(i, hl_attr(HLF_D));
+    for (i = 40; --i >= 0; )
+	highlight_list_two(99, 0);
+}
+
+    static void
+highlight_list_two(cnt, attr)
+    int	    cnt;
+    int	    attr;
+{
+    msg_puts_attr((char_u *)("N \bI \b!  \b" + cnt / 11), attr);
+    msg_clr_eos();
+    out_flush();
+    ui_delay(cnt == 99 ? 40L : (long)cnt * 50L, FALSE);
+}
+
+#endif /* FEAT_CMDL_COMPL */
+
+#if defined(FEAT_CMDL_COMPL) || (defined(FEAT_SYN_HL) && defined(FEAT_EVAL)) \
+    || defined(FEAT_SIGNS) || defined(PROTO)
+/*
+ * Function given to ExpandGeneric() to obtain the list of group names.
+ * Also used for synIDattr() function.
+ */
+/*ARGSUSED*/
+    char_u *
+get_highlight_name(xp, idx)
+    expand_T	*xp;
+    int		idx;
+{
+    if (idx == highlight_ga.ga_len
+#ifdef FEAT_CMDL_COMPL
+	    && include_link
+#endif
+	    )
+	return (char_u *)"link";
+    if (idx == highlight_ga.ga_len + 1
+#ifdef FEAT_CMDL_COMPL
+	    && include_link
+#endif
+	    )
+	return (char_u *)"clear";
+    if (idx == highlight_ga.ga_len + 2
+#ifdef FEAT_CMDL_COMPL
+	    && include_default
+#endif
+	    )
+	return (char_u *)"default";
+    if (idx < 0 || idx >= highlight_ga.ga_len)
+	return NULL;
+    return HL_TABLE()[idx].sg_name;
+}
+#endif
+
+#ifdef FEAT_GUI
+/*
+ * Free all the highlight group fonts.
+ * Used when quitting for systems which need it.
+ */
+    void
+free_highlight_fonts()
+{
+    int	    idx;
+
+    for (idx = 0; idx < highlight_ga.ga_len; ++idx)
+    {
+	gui_mch_free_font(HL_TABLE()[idx].sg_font);
+	HL_TABLE()[idx].sg_font = NOFONT;
+# ifdef FEAT_XFONTSET
+	gui_mch_free_fontset(HL_TABLE()[idx].sg_fontset);
+	HL_TABLE()[idx].sg_fontset = NOFONTSET;
+# endif
+    }
+
+    gui_mch_free_font(gui.norm_font);
+# ifdef FEAT_XFONTSET
+    gui_mch_free_fontset(gui.fontset);
+# endif
+# ifndef HAVE_GTK2
+    gui_mch_free_font(gui.bold_font);
+    gui_mch_free_font(gui.ital_font);
+    gui_mch_free_font(gui.boldital_font);
+# endif
+}
+#endif
+
+/**************************************
+ *  End of Highlighting stuff	      *
+ **************************************/
--- /dev/null
+++ b/tag.c
@@ -1,0 +1,3875 @@
+/* vi:set ts=8 sts=4 sw=4:
+ *
+ * VIM - Vi IMproved	by Bram Moolenaar
+ *
+ * Do ":help uganda"  in Vim to read copying and usage conditions.
+ * Do ":help credits" in Vim to see a list of people who contributed.
+ * See README.txt for an overview of the Vim source code.
+ */
+
+/*
+ * Code to handle tags and the tag stack
+ */
+
+#if defined MSDOS || defined WIN32 || defined(_WIN64)
+# include "vimio.h"	/* for lseek(), must be before vim.h */
+#endif
+
+#include "vim.h"
+
+#ifdef HAVE_FCNTL_H
+# include <fcntl.h>	/* for lseek() */
+#endif
+
+/*
+ * Structure to hold pointers to various items in a tag line.
+ */
+typedef struct tag_pointers
+{
+    /* filled in by parse_tag_line(): */
+    char_u	*tagname;	/* start of tag name (skip "file:") */
+    char_u	*tagname_end;	/* char after tag name */
+    char_u	*fname;		/* first char of file name */
+    char_u	*fname_end;	/* char after file name */
+    char_u	*command;	/* first char of command */
+    /* filled in by parse_match(): */
+    char_u	*command_end;	/* first char after command */
+    char_u	*tag_fname;	/* file name of the tags file */
+#ifdef FEAT_EMACS_TAGS
+    int		is_etag;	/* TRUE for emacs tag */
+#endif
+    char_u	*tagkind;	/* "kind:" value */
+    char_u	*tagkind_end;	/* end of tagkind */
+} tagptrs_T;
+
+/*
+ * The matching tags are first stored in ga_match[].  In which one depends on
+ * the priority of the match.
+ * At the end, the matches from ga_match[] are concatenated, to make a list
+ * sorted on priority.
+ */
+#define MT_ST_CUR	0		/* static match in current file */
+#define MT_GL_CUR	1		/* global match in current file */
+#define MT_GL_OTH	2		/* global match in other file */
+#define MT_ST_OTH	3		/* static match in other file */
+#define MT_IC_ST_CUR	4		/* icase static match in current file */
+#define MT_IC_GL_CUR	5		/* icase global match in current file */
+#define MT_IC_GL_OTH	6		/* icase global match in other file */
+#define MT_IC_ST_OTH	7		/* icase static match in other file */
+#define MT_IC_OFF	4		/* add for icase match */
+#define MT_RE_OFF	8		/* add for regexp match */
+#define MT_MASK		7		/* mask for printing priority */
+#define MT_COUNT	16
+
+static char	*mt_names[MT_COUNT/2] =
+		{"FSC", "F C", "F  ", "FS ", " SC", "  C", "   ", " S "};
+
+#define NOTAGFILE	99		/* return value for jumpto_tag */
+static char_u	*nofile_fname = NULL;	/* fname for NOTAGFILE error */
+
+static void taglen_advance __ARGS((int l));
+
+static int jumpto_tag __ARGS((char_u *lbuf, int forceit, int keep_help));
+#ifdef FEAT_EMACS_TAGS
+static int parse_tag_line __ARGS((char_u *lbuf, int is_etag, tagptrs_T *tagp));
+#else
+static int parse_tag_line __ARGS((char_u *lbuf, tagptrs_T *tagp));
+#endif
+static int test_for_static __ARGS((tagptrs_T *));
+static int parse_match __ARGS((char_u *lbuf, tagptrs_T *tagp));
+static char_u *tag_full_fname __ARGS((tagptrs_T *tagp));
+static char_u *expand_tag_fname __ARGS((char_u *fname, char_u *tag_fname, int expand));
+#ifdef FEAT_EMACS_TAGS
+static int test_for_current __ARGS((int, char_u *, char_u *, char_u *, char_u *));
+#else
+static int test_for_current __ARGS((char_u *, char_u *, char_u *, char_u *));
+#endif
+static int find_extra __ARGS((char_u **pp));
+
+static char_u *bottommsg = (char_u *)N_("E555: at bottom of tag stack");
+static char_u *topmsg = (char_u *)N_("E556: at top of tag stack");
+
+static char_u	*tagmatchname = NULL;	/* name of last used tag */
+
+/*
+ * We use ftello() here, if available.  It returns off_t instead of long,
+ * which helps if long is 32 bit and off_t is 64 bit.
+ */
+#ifdef HAVE_FTELLO
+# define ftell ftello
+#endif
+
+#if defined(FEAT_WINDOWS) && defined(FEAT_QUICKFIX)
+/*
+ * Tag for preview window is remembered separately, to avoid messing up the
+ * normal tagstack.
+ */
+static taggy_T ptag_entry = {NULL};
+#endif
+
+/*
+ * Jump to tag; handling of tag commands and tag stack
+ *
+ * *tag != NUL: ":tag {tag}", jump to new tag, add to tag stack
+ *
+ * type == DT_TAG:	":tag [tag]", jump to newer position or same tag again
+ * type == DT_HELP:	like DT_TAG, but don't use regexp.
+ * type == DT_POP:	":pop" or CTRL-T, jump to old position
+ * type == DT_NEXT:	jump to next match of same tag
+ * type == DT_PREV:	jump to previous match of same tag
+ * type == DT_FIRST:	jump to first match of same tag
+ * type == DT_LAST:	jump to last match of same tag
+ * type == DT_SELECT:	":tselect [tag]", select tag from a list of all matches
+ * type == DT_JUMP:	":tjump [tag]", jump to tag or select tag from a list
+ * type == DT_CSCOPE:	use cscope to find the tag
+ * type == DT_LTAG:	use location list for displaying tag matches
+ * type == DT_FREE:	free cached matches
+ *
+ * for cscope, returns TRUE if we jumped to tag or aborted, FALSE otherwise
+ */
+    int
+do_tag(tag, type, count, forceit, verbose)
+    char_u	*tag;		/* tag (pattern) to jump to */
+    int		type;
+    int		count;
+    int		forceit;	/* :ta with ! */
+    int		verbose;	/* print "tag not found" message */
+{
+    taggy_T	*tagstack = curwin->w_tagstack;
+    int		tagstackidx = curwin->w_tagstackidx;
+    int		tagstacklen = curwin->w_tagstacklen;
+    int		cur_match = 0;
+    int		cur_fnum = curbuf->b_fnum;
+    int		oldtagstackidx = tagstackidx;
+    int		prevtagstackidx = tagstackidx;
+    int		prev_num_matches;
+    int		new_tag = FALSE;
+    int		other_name;
+    int		i, j, k;
+    int		idx;
+    int		ic;
+    char_u	*p;
+    char_u	*name;
+    int		no_regexp = FALSE;
+    int		error_cur_match = 0;
+    char_u	*command_end;
+    int		save_pos = FALSE;
+    fmark_T	saved_fmark;
+    int		taglen;
+#ifdef FEAT_CSCOPE
+    int		jumped_to_tag = FALSE;
+#endif
+    tagptrs_T	tagp, tagp2;
+    int		new_num_matches;
+    char_u	**new_matches;
+    int		attr;
+    int		use_tagstack;
+    int		skip_msg = FALSE;
+    char_u	*buf_ffname = curbuf->b_ffname;	    /* name to use for
+						       priority computation */
+
+    /* remember the matches for the last used tag */
+    static int		num_matches = 0;
+    static int		max_num_matches = 0;  /* limit used for match search */
+    static char_u	**matches = NULL;
+    static int		flags;
+
+#ifdef EXITFREE
+    if (type == DT_FREE)
+    {
+	/* remove the list of matches */
+	FreeWild(num_matches, matches);
+# ifdef FEAT_CSCOPE
+	cs_free_tags();
+# endif
+	num_matches = 0;
+	return FALSE;
+    }
+#endif
+
+    if (type == DT_HELP)
+    {
+	type = DT_TAG;
+	no_regexp = TRUE;
+    }
+
+    prev_num_matches = num_matches;
+    free_string_option(nofile_fname);
+    nofile_fname = NULL;
+
+    clearpos(&saved_fmark.mark);	/* shutup gcc 4.0 */
+    saved_fmark.fnum = 0;
+
+    /*
+     * Don't add a tag to the tagstack if 'tagstack' has been reset.
+     */
+    if ((!p_tgst && *tag != NUL))
+    {
+	use_tagstack = FALSE;
+	new_tag = TRUE;
+    }
+    else
+    {
+#if defined(FEAT_WINDOWS) && defined(FEAT_QUICKFIX)
+	if (g_do_tagpreview)
+	    use_tagstack = FALSE;
+	else
+#endif
+	    use_tagstack = TRUE;
+
+	/* new pattern, add to the tag stack */
+	if (*tag != NUL
+		&& (type == DT_TAG || type == DT_SELECT || type == DT_JUMP
+#ifdef FEAT_QUICKFIX
+		    || type == DT_LTAG
+#endif
+#ifdef FEAT_CSCOPE
+		    || type == DT_CSCOPE
+#endif
+		    ))
+	{
+#if defined(FEAT_WINDOWS) && defined(FEAT_QUICKFIX)
+	    if (g_do_tagpreview)
+	    {
+		if (ptag_entry.tagname != NULL
+			&& STRCMP(ptag_entry.tagname, tag) == 0)
+		{
+		    /* Jumping to same tag: keep the current match, so that
+		     * the CursorHold autocommand example works. */
+		    cur_match = ptag_entry.cur_match;
+		    cur_fnum = ptag_entry.cur_fnum;
+		}
+		else
+		{
+		    vim_free(ptag_entry.tagname);
+		    if ((ptag_entry.tagname = vim_strsave(tag)) == NULL)
+			goto end_do_tag;
+		}
+	    }
+	    else
+#endif
+	    {
+		/*
+		 * If the last used entry is not at the top, delete all tag
+		 * stack entries above it.
+		 */
+		while (tagstackidx < tagstacklen)
+		    vim_free(tagstack[--tagstacklen].tagname);
+
+		/* if the tagstack is full: remove oldest entry */
+		if (++tagstacklen > TAGSTACKSIZE)
+		{
+		    tagstacklen = TAGSTACKSIZE;
+		    vim_free(tagstack[0].tagname);
+		    for (i = 1; i < tagstacklen; ++i)
+			tagstack[i - 1] = tagstack[i];
+		    --tagstackidx;
+		}
+
+		/*
+		 * put the tag name in the tag stack
+		 */
+		if ((tagstack[tagstackidx].tagname = vim_strsave(tag)) == NULL)
+		{
+		    curwin->w_tagstacklen = tagstacklen - 1;
+		    goto end_do_tag;
+		}
+		curwin->w_tagstacklen = tagstacklen;
+
+		save_pos = TRUE;	/* save the cursor position below */
+	    }
+
+	    new_tag = TRUE;
+	}
+	else
+	{
+	    if (
+#if defined(FEAT_WINDOWS) && defined(FEAT_QUICKFIX)
+		    g_do_tagpreview ? ptag_entry.tagname == NULL :
+#endif
+		    tagstacklen == 0)
+	    {
+		/* empty stack */
+		EMSG(_(e_tagstack));
+		goto end_do_tag;
+	    }
+
+	    if (type == DT_POP)		/* go to older position */
+	    {
+#ifdef FEAT_FOLDING
+		int	old_KeyTyped = KeyTyped;
+#endif
+		if ((tagstackidx -= count) < 0)
+		{
+		    EMSG(_(bottommsg));
+		    if (tagstackidx + count == 0)
+		    {
+			/* We did [num]^T from the bottom of the stack */
+			tagstackidx = 0;
+			goto end_do_tag;
+		    }
+		    /* We weren't at the bottom of the stack, so jump all the
+		     * way to the bottom now.
+		     */
+		    tagstackidx = 0;
+		}
+		else if (tagstackidx >= tagstacklen)    /* count == 0? */
+		{
+		    EMSG(_(topmsg));
+		    goto end_do_tag;
+		}
+
+		/* Make a copy of the fmark, autocommands may invalidate the
+		 * tagstack before it's used. */
+		saved_fmark = tagstack[tagstackidx].fmark;
+		if (saved_fmark.fnum != curbuf->b_fnum)
+		{
+		    /*
+		     * Jump to other file. If this fails (e.g. because the
+		     * file was changed) keep original position in tag stack.
+		     */
+		    if (buflist_getfile(saved_fmark.fnum, saved_fmark.mark.lnum,
+					       GETF_SETMARK, forceit) == FAIL)
+		    {
+			tagstackidx = oldtagstackidx;  /* back to old posn */
+			goto end_do_tag;
+		    }
+		    /* An BufReadPost autocommand may jump to the '" mark, but
+		     * we don't what that here. */
+		    curwin->w_cursor.lnum = saved_fmark.mark.lnum;
+		}
+		else
+		{
+		    setpcmark();
+		    curwin->w_cursor.lnum = saved_fmark.mark.lnum;
+		}
+		curwin->w_cursor.col = saved_fmark.mark.col;
+		curwin->w_set_curswant = TRUE;
+		check_cursor();
+#ifdef FEAT_FOLDING
+		if ((fdo_flags & FDO_TAG) && old_KeyTyped)
+		    foldOpenCursor();
+#endif
+
+		/* remove the old list of matches */
+		FreeWild(num_matches, matches);
+#ifdef FEAT_CSCOPE
+		cs_free_tags();
+#endif
+		num_matches = 0;
+		tag_freematch();
+		goto end_do_tag;
+	    }
+
+	    if (type == DT_TAG
+#if defined(FEAT_QUICKFIX)
+		    || type == DT_LTAG
+#endif
+	       )
+	    {
+#if defined(FEAT_WINDOWS) && defined(FEAT_QUICKFIX)
+		if (g_do_tagpreview)
+		{
+		    cur_match = ptag_entry.cur_match;
+		    cur_fnum = ptag_entry.cur_fnum;
+		}
+		else
+#endif
+		{
+		    /* ":tag" (no argument): go to newer pattern */
+		    save_pos = TRUE;	/* save the cursor position below */
+		    if ((tagstackidx += count - 1) >= tagstacklen)
+		    {
+			/*
+			 * Beyond the last one, just give an error message and
+			 * go to the last one.  Don't store the cursor
+			 * position.
+			 */
+			tagstackidx = tagstacklen - 1;
+			EMSG(_(topmsg));
+			save_pos = FALSE;
+		    }
+		    else if (tagstackidx < 0)	/* must have been count == 0 */
+		    {
+			EMSG(_(bottommsg));
+			tagstackidx = 0;
+			goto end_do_tag;
+		    }
+		    cur_match = tagstack[tagstackidx].cur_match;
+		    cur_fnum = tagstack[tagstackidx].cur_fnum;
+		}
+		new_tag = TRUE;
+	    }
+	    else				/* go to other matching tag */
+	    {
+		/* Save index for when selection is cancelled. */
+		prevtagstackidx = tagstackidx;
+
+#if defined(FEAT_WINDOWS) && defined(FEAT_QUICKFIX)
+		if (g_do_tagpreview)
+		{
+		    cur_match = ptag_entry.cur_match;
+		    cur_fnum = ptag_entry.cur_fnum;
+		}
+		else
+#endif
+		{
+		    if (--tagstackidx < 0)
+			tagstackidx = 0;
+		    cur_match = tagstack[tagstackidx].cur_match;
+		    cur_fnum = tagstack[tagstackidx].cur_fnum;
+		}
+		switch (type)
+		{
+		    case DT_FIRST: cur_match = count - 1; break;
+		    case DT_SELECT:
+		    case DT_JUMP:
+#ifdef FEAT_CSCOPE
+		    case DT_CSCOPE:
+#endif
+		    case DT_LAST:  cur_match = MAXCOL - 1; break;
+		    case DT_NEXT:  cur_match += count; break;
+		    case DT_PREV:  cur_match -= count; break;
+		}
+		if (cur_match >= MAXCOL)
+		    cur_match = MAXCOL - 1;
+		else if (cur_match < 0)
+		{
+		    EMSG(_("E425: Cannot go before first matching tag"));
+		    skip_msg = TRUE;
+		    cur_match = 0;
+		    cur_fnum = curbuf->b_fnum;
+		}
+	    }
+	}
+
+#if defined(FEAT_WINDOWS) && defined(FEAT_QUICKFIX)
+	if (g_do_tagpreview)
+	{
+	    if (type != DT_SELECT && type != DT_JUMP)
+	    {
+		ptag_entry.cur_match = cur_match;
+		ptag_entry.cur_fnum = cur_fnum;
+	    }
+	}
+	else
+#endif
+	{
+	    /*
+	     * For ":tag [arg]" or ":tselect" remember position before the jump.
+	     */
+	    saved_fmark = tagstack[tagstackidx].fmark;
+	    if (save_pos)
+	    {
+		tagstack[tagstackidx].fmark.mark = curwin->w_cursor;
+		tagstack[tagstackidx].fmark.fnum = curbuf->b_fnum;
+	    }
+
+	    /* Curwin will change in the call to jumpto_tag() if ":stag" was
+	     * used or an autocommand jumps to another window; store value of
+	     * tagstackidx now. */
+	    curwin->w_tagstackidx = tagstackidx;
+	    if (type != DT_SELECT && type != DT_JUMP)
+	    {
+		curwin->w_tagstack[tagstackidx].cur_match = cur_match;
+		curwin->w_tagstack[tagstackidx].cur_fnum = cur_fnum;
+	    }
+	}
+    }
+
+    /* When not using the current buffer get the name of buffer "cur_fnum".
+     * Makes sure that the tag order doesn't change when using a remembered
+     * position for "cur_match". */
+    if (cur_fnum != curbuf->b_fnum)
+    {
+	buf_T *buf = buflist_findnr(cur_fnum);
+
+	if (buf != NULL)
+	    buf_ffname = buf->b_ffname;
+    }
+
+    /*
+     * Repeat searching for tags, when a file has not been found.
+     */
+    for (;;)
+    {
+	/*
+	 * When desired match not found yet, try to find it (and others).
+	 */
+	if (use_tagstack)
+	    name = tagstack[tagstackidx].tagname;
+#if defined(FEAT_WINDOWS) && defined(FEAT_QUICKFIX)
+	else if (g_do_tagpreview)
+	    name = ptag_entry.tagname;
+#endif
+	else
+	    name = tag;
+	other_name = (tagmatchname == NULL || STRCMP(tagmatchname, name) != 0);
+	if (new_tag
+		|| (cur_match >= num_matches && max_num_matches != MAXCOL)
+		|| other_name)
+	{
+	    if (other_name)
+	    {
+		vim_free(tagmatchname);
+		tagmatchname = vim_strsave(name);
+	    }
+
+	    /*
+	     * If a count is supplied to the ":tag <name>" command, then
+	     * jump to count'th matching tag.
+	     */
+	    if (type == DT_TAG && count > 0)
+		cur_match = count - 1;
+
+	    if (type == DT_SELECT || type == DT_JUMP
+#if defined(FEAT_QUICKFIX)
+		|| type == DT_LTAG
+#endif
+		)
+		cur_match = MAXCOL - 1;
+	    max_num_matches = cur_match + 1;
+
+	    /* when the argument starts with '/', use it as a regexp */
+	    if (!no_regexp && *name == '/')
+	    {
+		flags = TAG_REGEXP;
+		++name;
+	    }
+	    else
+		flags = TAG_NOIC;
+
+#ifdef FEAT_CSCOPE
+	    if (type == DT_CSCOPE)
+		flags = TAG_CSCOPE;
+#endif
+	    if (verbose)
+		flags |= TAG_VERBOSE;
+	    if (find_tags(name, &new_num_matches, &new_matches, flags,
+					    max_num_matches, buf_ffname) == OK
+		    && new_num_matches < max_num_matches)
+		max_num_matches = MAXCOL; /* If less than max_num_matches
+					     found: all matches found. */
+
+	    /* If there already were some matches for the same name, move them
+	     * to the start.  Avoids that the order changes when using
+	     * ":tnext" and jumping to another file. */
+	    if (!new_tag && !other_name)
+	    {
+		/* Find the position of each old match in the new list.  Need
+		 * to use parse_match() to find the tag line. */
+		idx = 0;
+		for (j = 0; j < num_matches; ++j)
+		{
+		    parse_match(matches[j], &tagp);
+		    for (i = idx; i < new_num_matches; ++i)
+		    {
+			parse_match(new_matches[i], &tagp2);
+			if (STRCMP(tagp.tagname, tagp2.tagname) == 0)
+			{
+			    p = new_matches[i];
+			    for (k = i; k > idx; --k)
+				new_matches[k] = new_matches[k - 1];
+			    new_matches[idx++] = p;
+			    break;
+			}
+		    }
+		}
+	    }
+	    FreeWild(num_matches, matches);
+	    num_matches = new_num_matches;
+	    matches = new_matches;
+	}
+
+	if (num_matches <= 0)
+	{
+	    if (verbose)
+		EMSG2(_("E426: tag not found: %s"), name);
+#if defined(FEAT_WINDOWS) && defined(FEAT_QUICKFIX)
+	    g_do_tagpreview = 0;
+#endif
+	}
+	else
+	{
+	    int ask_for_selection = FALSE;
+
+#ifdef FEAT_CSCOPE
+	    if (type == DT_CSCOPE && num_matches > 1)
+	    {
+		cs_print_tags();
+		ask_for_selection = TRUE;
+	    }
+	    else
+#endif
+	    if (type == DT_SELECT || (type == DT_JUMP && num_matches > 1))
+	    {
+		/*
+		 * List all the matching tags.
+		 * Assume that the first match indicates how long the tags can
+		 * be, and align the file names to that.
+		 */
+		parse_match(matches[0], &tagp);
+		taglen = (int)(tagp.tagname_end - tagp.tagname + 2);
+		if (taglen < 18)
+		    taglen = 18;
+		if (taglen > Columns - 25)
+		    taglen = MAXCOL;
+		if (msg_col == 0)
+		    msg_didout = FALSE;	/* overwrite previous message */
+		msg_start();
+		MSG_PUTS_ATTR(_("  # pri kind tag"), hl_attr(HLF_T));
+		msg_clr_eos();
+		taglen_advance(taglen);
+		MSG_PUTS_ATTR(_("file\n"), hl_attr(HLF_T));
+
+		for (i = 0; i < num_matches; ++i)
+		{
+		    parse_match(matches[i], &tagp);
+		    if (!new_tag && (
+#if defined(FEAT_WINDOWS) && defined(FEAT_QUICKFIX)
+				(g_do_tagpreview
+				 && i == ptag_entry.cur_match) ||
+#endif
+				(use_tagstack
+				 && i == tagstack[tagstackidx].cur_match)))
+			*IObuff = '>';
+		    else
+			*IObuff = ' ';
+		    vim_snprintf((char *)IObuff + 1, IOSIZE - 1,
+			    "%2d %s ", i + 1,
+					   mt_names[matches[i][0] & MT_MASK]);
+		    msg_puts(IObuff);
+		    if (tagp.tagkind != NULL)
+			msg_outtrans_len(tagp.tagkind,
+				      (int)(tagp.tagkind_end - tagp.tagkind));
+		    msg_advance(13);
+		    msg_outtrans_len_attr(tagp.tagname,
+				       (int)(tagp.tagname_end - tagp.tagname),
+							      hl_attr(HLF_T));
+		    msg_putchar(' ');
+		    taglen_advance(taglen);
+
+		    /* Find out the actual file name. If it is long, truncate
+		     * it and put "..." in the middle */
+		    p = tag_full_fname(&tagp);
+		    if (p != NULL)
+		    {
+			msg_puts_long_attr(p, hl_attr(HLF_D));
+			vim_free(p);
+		    }
+		    if (msg_col > 0)
+			msg_putchar('\n');
+		    msg_advance(15);
+
+		    /* print any extra fields */
+		    command_end = tagp.command_end;
+		    if (command_end != NULL)
+		    {
+			p = command_end + 3;
+			while (*p && *p != '\r' && *p != '\n')
+			{
+			    while (*p == TAB)
+				++p;
+
+			    /* skip "file:" without a value (static tag) */
+			    if (STRNCMP(p, "file:", 5) == 0
+							 && vim_isspace(p[5]))
+			    {
+				p += 5;
+				continue;
+			    }
+			    /* skip "kind:<kind>" and "<kind>" */
+			    if (p == tagp.tagkind
+				    || (p + 5 == tagp.tagkind
+					    && STRNCMP(p, "kind:", 5) == 0))
+			    {
+				p = tagp.tagkind_end;
+				continue;
+			    }
+			    /* print all other extra fields */
+			    attr = hl_attr(HLF_CM);
+			    while (*p && *p != '\r' && *p != '\n')
+			    {
+				if (msg_col + ptr2cells(p) >= Columns)
+				{
+				    msg_putchar('\n');
+				    msg_advance(15);
+				}
+				p = msg_outtrans_one(p, attr);
+				if (*p == TAB)
+				{
+				    msg_puts_attr((char_u *)" ", attr);
+				    break;
+				}
+				if (*p == ':')
+				    attr = 0;
+			    }
+			}
+			if (msg_col > 15)
+			{
+			    msg_putchar('\n');
+			    msg_advance(15);
+			}
+		    }
+		    else
+		    {
+			for (p = tagp.command;
+					  *p && *p != '\r' && *p != '\n'; ++p)
+			    ;
+			command_end = p;
+		    }
+
+		    /*
+		     * Put the info (in several lines) at column 15.
+		     * Don't display "/^" and "?^".
+		     */
+		    p = tagp.command;
+		    if (*p == '/' || *p == '?')
+		    {
+			++p;
+			if (*p == '^')
+			    ++p;
+		    }
+		    /* Remove leading whitespace from pattern */
+		    while (p != command_end && vim_isspace(*p))
+			++p;
+
+		    while (p != command_end)
+		    {
+			if (msg_col + (*p == TAB ? 1 : ptr2cells(p)) > Columns)
+			    msg_putchar('\n');
+			msg_advance(15);
+
+			/* skip backslash used for escaping command char */
+			if (*p == '\\' && *(p + 1) == *tagp.command)
+			    ++p;
+
+			if (*p == TAB)
+			{
+			    msg_putchar(' ');
+			    ++p;
+			}
+			else
+			    p = msg_outtrans_one(p, 0);
+
+			/* don't display the "$/;\"" and "$?;\"" */
+			if (p == command_end - 2 && *p == '$'
+						 && *(p + 1) == *tagp.command)
+			    break;
+			/* don't display matching '/' or '?' */
+			if (p == command_end - 1 && *p == *tagp.command
+						 && (*p == '/' || *p == '?'))
+			    break;
+		    }
+		    if (msg_col)
+			msg_putchar('\n');
+		    ui_breakcheck();
+		    if (got_int)
+		    {
+			got_int = FALSE;	/* only stop the listing */
+			break;
+		    }
+		}
+		ask_for_selection = TRUE;
+	    }
+#if defined(FEAT_QUICKFIX) && defined(FEAT_EVAL)
+	    else if (type == DT_LTAG)
+	    {
+		list_T	*list;
+		char_u	tag_name[128 + 1];
+		char_u	fname[MAXPATHL + 1];
+		char_u	cmd[CMDBUFFSIZE + 1];
+
+		/*
+		 * Add the matching tags to the location list for the current
+		 * window.
+		 */
+
+		list = list_alloc();
+		if (list == NULL)
+		    goto end_do_tag;
+
+		for (i = 0; i < num_matches; ++i)
+		{
+		    int	    len, cmd_len;
+		    long    lnum;
+		    dict_T  *dict;
+
+		    parse_match(matches[i], &tagp);
+
+		    /* Save the tag name */
+		    len = (int)(tagp.tagname_end - tagp.tagname);
+		    if (len > 128)
+			len = 128;
+		    vim_strncpy(tag_name, tagp.tagname, len);
+		    tag_name[len] = NUL;
+
+		    /* Save the tag file name */
+		    p = tag_full_fname(&tagp);
+		    if (p == NULL)
+			continue;
+		    STRCPY(fname, p);
+		    vim_free(p);
+
+		    /*
+		     * Get the line number or the search pattern used to locate
+		     * the tag.
+		     */
+		    lnum = 0;
+		    if (isdigit(*tagp.command))
+			/* Line number is used to locate the tag */
+			lnum = atol((char *)tagp.command);
+		    else
+		    {
+			char_u *cmd_start, *cmd_end;
+
+			/* Search pattern is used to locate the tag */
+
+			/* Locate the end of the command */
+			cmd_start = tagp.command;
+			cmd_end = tagp.command_end;
+			if (cmd_end == NULL)
+			{
+			    for (p = tagp.command;
+				 *p && *p != '\r' && *p != '\n'; ++p)
+				;
+			    cmd_end = p;
+			}
+
+			/*
+			 * Now, cmd_end points to the character after the
+			 * command. Adjust it to point to the last
+			 * character of the command.
+			 */
+			cmd_end--;
+
+			/*
+			 * Skip the '/' and '?' characters at the
+			 * beginning and end of the search pattern.
+			 */
+			if (*cmd_start == '/' || *cmd_start == '?')
+			    cmd_start++;
+
+			if (*cmd_end == '/' || *cmd_end == '?')
+			    cmd_end--;
+
+			len = 0;
+			cmd[0] = NUL;
+
+			/*
+			 * If "^" is present in the tag search pattern, then
+			 * copy it first.
+			 */
+			if (*cmd_start == '^')
+			{
+			    STRCPY(cmd, "^");
+			    cmd_start++;
+			    len++;
+			}
+
+			/*
+			 * Precede the tag pattern with \V to make it very
+			 * nomagic.
+			 */
+			STRCAT(cmd, "\\V");
+			len += 2;
+
+			cmd_len = (int)(cmd_end - cmd_start + 1);
+			if (cmd_len > (CMDBUFFSIZE - 5))
+			    cmd_len = CMDBUFFSIZE - 5;
+			STRNCAT(cmd, cmd_start, cmd_len);
+			len += cmd_len;
+
+			if (cmd[len - 1] == '$')
+			{
+			    /*
+			     * Replace '$' at the end of the search pattern
+			     * with '\$'
+			     */
+			    cmd[len - 1] = '\\';
+			    cmd[len] = '$';
+			    len++;
+			}
+
+			cmd[len] = NUL;
+		    }
+
+		    if ((dict = dict_alloc()) == NULL)
+			continue;
+		    if (list_append_dict(list, dict) == FAIL)
+		    {
+			vim_free(dict);
+			continue;
+		    }
+
+		    dict_add_nr_str(dict, "text", 0L, tag_name);
+		    dict_add_nr_str(dict, "filename", 0L, fname);
+		    dict_add_nr_str(dict, "lnum", lnum, NULL);
+		    if (lnum == 0)
+			dict_add_nr_str(dict, "pattern", 0L, cmd);
+		}
+
+		set_errorlist(curwin, list, ' ');
+
+		list_free(list, TRUE);
+
+		cur_match = 0;		/* Jump to the first tag */
+	    }
+#endif
+
+	    if (ask_for_selection == TRUE)
+	    {
+		/*
+		 * Ask to select a tag from the list.
+		 */
+		i = prompt_for_number(NULL);
+		if (i <= 0 || i > num_matches || got_int)
+		{
+		    /* no valid choice: don't change anything */
+		    if (use_tagstack)
+		    {
+			tagstack[tagstackidx].fmark = saved_fmark;
+			tagstackidx = prevtagstackidx;
+		    }
+#ifdef FEAT_CSCOPE
+		    cs_free_tags();
+		    jumped_to_tag = TRUE;
+#endif
+		    break;
+		}
+		cur_match = i - 1;
+	    }
+
+	    if (cur_match >= num_matches)
+	    {
+		/* Avoid giving this error when a file wasn't found and we're
+		 * looking for a match in another file, which wasn't found.
+		 * There will be an EMSG("file doesn't exist") below then. */
+		if ((type == DT_NEXT || type == DT_FIRST)
+						      && nofile_fname == NULL)
+		{
+		    if (num_matches == 1)
+			EMSG(_("E427: There is only one matching tag"));
+		    else
+			EMSG(_("E428: Cannot go beyond last matching tag"));
+		    skip_msg = TRUE;
+		}
+		cur_match = num_matches - 1;
+	    }
+	    if (use_tagstack)
+	    {
+		tagstack[tagstackidx].cur_match = cur_match;
+		tagstack[tagstackidx].cur_fnum = cur_fnum;
+		++tagstackidx;
+	    }
+#if defined(FEAT_WINDOWS) && defined(FEAT_QUICKFIX)
+	    else if (g_do_tagpreview)
+	    {
+		ptag_entry.cur_match = cur_match;
+		ptag_entry.cur_fnum = cur_fnum;
+	    }
+#endif
+
+	    /*
+	     * Only when going to try the next match, report that the previous
+	     * file didn't exist.  Otherwise an EMSG() is given below.
+	     */
+	    if (nofile_fname != NULL && error_cur_match != cur_match)
+		smsg((char_u *)_("File \"%s\" does not exist"), nofile_fname);
+
+
+	    ic = (matches[cur_match][0] & MT_IC_OFF);
+	    if (type != DT_SELECT && type != DT_JUMP
+#ifdef FEAT_CSCOPE
+		&& type != DT_CSCOPE
+#endif
+		&& (num_matches > 1 || ic)
+		&& !skip_msg)
+	    {
+		/* Give an indication of the number of matching tags */
+		sprintf((char *)IObuff, _("tag %d of %d%s"),
+				cur_match + 1,
+				num_matches,
+				max_num_matches != MAXCOL ? _(" or more") : "");
+		if (ic)
+		    STRCAT(IObuff, _("  Using tag with different case!"));
+		if ((num_matches > prev_num_matches || new_tag)
+							   && num_matches > 1)
+		{
+		    if (ic)
+			msg_attr(IObuff, hl_attr(HLF_W));
+		    else
+			msg(IObuff);
+		    msg_scroll = TRUE;	/* don't overwrite this message */
+		}
+		else
+		    give_warning(IObuff, ic);
+		if (ic && !msg_scrolled && msg_silent == 0)
+		{
+		    out_flush();
+		    ui_delay(1000L, TRUE);
+		}
+	    }
+
+#ifdef FEAT_AUTOCMD
+	    /* Let the SwapExists event know what tag we are jumping to. */
+	    vim_snprintf((char *)IObuff, IOSIZE, ":ta %s\r", name);
+	    set_vim_var_string(VV_SWAPCOMMAND, IObuff, -1);
+#endif
+
+	    /*
+	     * Jump to the desired match.
+	     */
+	    i = jumpto_tag(matches[cur_match], forceit, type != DT_CSCOPE);
+
+#ifdef FEAT_AUTOCMD
+	    set_vim_var_string(VV_SWAPCOMMAND, NULL, -1);
+#endif
+
+	    if (i == NOTAGFILE)
+	    {
+		/* File not found: try again with another matching tag */
+		if ((type == DT_PREV && cur_match > 0)
+			|| ((type == DT_TAG || type == DT_NEXT
+							  || type == DT_FIRST)
+			    && (max_num_matches != MAXCOL
+					     || cur_match < num_matches - 1)))
+		{
+		    error_cur_match = cur_match;
+		    if (use_tagstack)
+			--tagstackidx;
+		    if (type == DT_PREV)
+			--cur_match;
+		    else
+		    {
+			type = DT_NEXT;
+			++cur_match;
+		    }
+		    continue;
+		}
+		EMSG2(_("E429: File \"%s\" does not exist"), nofile_fname);
+	    }
+	    else
+	    {
+		/* We may have jumped to another window, check that
+		 * tagstackidx is still valid. */
+		if (use_tagstack && tagstackidx > curwin->w_tagstacklen)
+		    tagstackidx = curwin->w_tagstackidx;
+#ifdef FEAT_CSCOPE
+		jumped_to_tag = TRUE;
+#endif
+	    }
+	}
+	break;
+    }
+
+end_do_tag:
+    /* Only store the new index when using the tagstack and it's valid. */
+    if (use_tagstack && tagstackidx <= curwin->w_tagstacklen)
+	curwin->w_tagstackidx = tagstackidx;
+#ifdef FEAT_WINDOWS
+    postponed_split = 0;	/* don't split next time */
+#endif
+
+#ifdef FEAT_CSCOPE
+    return jumped_to_tag;
+#else
+    return FALSE;
+#endif
+}
+
+/*
+ * Free cached tags.
+ */
+    void
+tag_freematch()
+{
+    vim_free(tagmatchname);
+    tagmatchname = NULL;
+}
+
+    static void
+taglen_advance(l)
+    int		l;
+{
+    if (l == MAXCOL)
+    {
+	msg_putchar('\n');
+	msg_advance(24);
+    }
+    else
+	msg_advance(13 + l);
+}
+
+/*
+ * Print the tag stack
+ */
+/*ARGSUSED*/
+    void
+do_tags(eap)
+    exarg_T	*eap;
+{
+    int		i;
+    char_u	*name;
+    taggy_T	*tagstack = curwin->w_tagstack;
+    int		tagstackidx = curwin->w_tagstackidx;
+    int		tagstacklen = curwin->w_tagstacklen;
+
+    /* Highlight title */
+    MSG_PUTS_TITLE(_("\n  # TO tag         FROM line  in file/text"));
+    for (i = 0; i < tagstacklen; ++i)
+    {
+	if (tagstack[i].tagname != NULL)
+	{
+	    name = fm_getname(&(tagstack[i].fmark), 30);
+	    if (name == NULL)	    /* file name not available */
+		continue;
+
+	    msg_putchar('\n');
+	    sprintf((char *)IObuff, "%c%2d %2d %-15s %5ld  ",
+		i == tagstackidx ? '>' : ' ',
+		i + 1,
+		tagstack[i].cur_match + 1,
+		tagstack[i].tagname,
+		tagstack[i].fmark.mark.lnum);
+	    msg_outtrans(IObuff);
+	    msg_outtrans_attr(name, tagstack[i].fmark.fnum == curbuf->b_fnum
+							? hl_attr(HLF_D) : 0);
+	    vim_free(name);
+	}
+	out_flush();		    /* show one line at a time */
+    }
+    if (tagstackidx == tagstacklen)	/* idx at top of stack */
+	MSG_PUTS("\n>");
+}
+
+/* When not using a CR for line separator, use vim_fgets() to read tag lines.
+ * For the Mac use tag_fgets().  It can handle any line separator, but is much
+ * slower than vim_fgets().
+ */
+#ifndef USE_CR
+# define tag_fgets vim_fgets
+#endif
+
+#ifdef FEAT_TAG_BINS
+static int tag_strnicmp __ARGS((char_u *s1, char_u *s2, size_t len));
+
+/*
+ * Compare two strings, for length "len", ignoring case the ASCII way.
+ * return 0 for match, < 0 for smaller, > 0 for bigger
+ * Make sure case is folded to uppercase in comparison (like for 'sort -f')
+ */
+    static int
+tag_strnicmp(s1, s2, len)
+    char_u	*s1;
+    char_u	*s2;
+    size_t	len;
+{
+    int		i;
+
+    while (len > 0)
+    {
+	i = (int)TOUPPER_ASC(*s1) - (int)TOUPPER_ASC(*s2);
+	if (i != 0)
+	    return i;			/* this character different */
+	if (*s1 == NUL)
+	    break;			/* strings match until NUL */
+	++s1;
+	++s2;
+	--len;
+    }
+    return 0;				/* strings match */
+}
+#endif
+
+/*
+ * Structure to hold info about the tag pattern being used.
+ */
+typedef struct
+{
+    char_u	*pat;		/* the pattern */
+    int		len;		/* length of pat[] */
+    char_u	*head;		/* start of pattern head */
+    int		headlen;	/* length of head[] */
+    regmatch_T	regmatch;	/* regexp program, may be NULL */
+} pat_T;
+
+static void prepare_pats __ARGS((pat_T *pats, int has_re));
+
+/*
+ * Extract info from the tag search pattern "pats->pat".
+ */
+    static void
+prepare_pats(pats, has_re)
+    pat_T	*pats;
+    int		has_re;
+{
+    pats->head = pats->pat;
+    pats->headlen = pats->len;
+    if (has_re)
+    {
+	/* When the pattern starts with '^' or "\\<", binary searching can be
+	 * used (much faster). */
+	if (pats->pat[0] == '^')
+	    pats->head = pats->pat + 1;
+	else if (pats->pat[0] == '\\' && pats->pat[1] == '<')
+	    pats->head = pats->pat + 2;
+	if (pats->head == pats->pat)
+	    pats->headlen = 0;
+	else
+	    for (pats->headlen = 0; pats->head[pats->headlen] != NUL;
+							      ++pats->headlen)
+		if (vim_strchr((char_u *)(p_magic ? ".[~*\\$" : "\\$"),
+					   pats->head[pats->headlen]) != NULL)
+		    break;
+	if (p_tl != 0 && pats->headlen > p_tl)	/* adjust for 'taglength' */
+	    pats->headlen = p_tl;
+    }
+
+    if (has_re)
+	pats->regmatch.regprog = vim_regcomp(pats->pat, p_magic ? RE_MAGIC : 0);
+    else
+	pats->regmatch.regprog = NULL;
+}
+
+/*
+ * find_tags() - search for tags in tags files
+ *
+ * Return FAIL if search completely failed (*num_matches will be 0, *matchesp
+ * will be NULL), OK otherwise.
+ *
+ * There is a priority in which type of tag is recognized.
+ *
+ *  6.	A static or global tag with a full matching tag for the current file.
+ *  5.	A global tag with a full matching tag for another file.
+ *  4.	A static tag with a full matching tag for another file.
+ *  3.	A static or global tag with an ignore-case matching tag for the
+ *	current file.
+ *  2.	A global tag with an ignore-case matching tag for another file.
+ *  1.	A static tag with an ignore-case matching tag for another file.
+ *
+ * Tags in an emacs-style tags file are always global.
+ *
+ * flags:
+ * TAG_HELP	  only search for help tags
+ * TAG_NAMES	  only return name of tag
+ * TAG_REGEXP	  use "pat" as a regexp
+ * TAG_NOIC	  don't always ignore case
+ * TAG_KEEP_LANG  keep language
+ */
+    int
+find_tags(pat, num_matches, matchesp, flags, mincount, buf_ffname)
+    char_u	*pat;			/* pattern to search for */
+    int		*num_matches;		/* return: number of matches found */
+    char_u	***matchesp;		/* return: array of matches found */
+    int		flags;
+    int		mincount;		/*  MAXCOL: find all matches
+					     other: minimal number of matches */
+    char_u	*buf_ffname;		/* name of buffer for priority */
+{
+    FILE       *fp;
+    char_u     *lbuf;			/* line buffer */
+    char_u     *tag_fname;		/* name of tag file */
+    tagname_T	tn;			/* info for get_tagfname() */
+    int		first_file;		/* trying first tag file */
+    tagptrs_T	tagp;
+    int		did_open = FALSE;	/* did open a tag file */
+    int		stop_searching = FALSE;	/* stop when match found or error */
+    int		retval = FAIL;		/* return value */
+    int		is_static;		/* current tag line is static */
+    int		is_current;		/* file name matches */
+    int		eof = FALSE;		/* found end-of-file */
+    char_u	*p;
+    char_u	*s;
+    int		i;
+#ifdef FEAT_TAG_BINS
+    struct tag_search_info	/* Binary search file offsets */
+    {
+	off_t	low_offset;	/* offset for first char of first line that
+				   could match */
+	off_t	high_offset;	/* offset of char after last line that could
+				   match */
+	off_t	curr_offset;	/* Current file offset in search range */
+	off_t	curr_offset_used; /* curr_offset used when skipping back */
+	off_t	match_offset;	/* Where the binary search found a tag */
+	int	low_char;	/* first char at low_offset */
+	int	high_char;	/* first char at high_offset */
+    } search_info;
+    off_t	filesize;
+    int		tagcmp;
+    off_t	offset;
+    int		round;
+#endif
+    enum
+    {
+	TS_START,		/* at start of file */
+	TS_LINEAR		/* linear searching forward, till EOF */
+#ifdef FEAT_TAG_BINS
+	, TS_BINARY,		/* binary searching */
+	TS_SKIP_BACK,		/* skipping backwards */
+	TS_STEP_FORWARD		/* stepping forwards */
+#endif
+    }	state;			/* Current search state */
+
+    int		cmplen;
+    int		match;		/* matches */
+    int		match_no_ic = 0;/* matches with rm_ic == FALSE */
+    int		match_re;	/* match with regexp */
+    int		matchoff = 0;
+
+#ifdef FEAT_EMACS_TAGS
+    /*
+     * Stack for included emacs-tags file.
+     * It has a fixed size, to truncate cyclic includes. jw
+     */
+# define INCSTACK_SIZE 42
+    struct
+    {
+	FILE	*fp;
+	char_u	*etag_fname;
+    } incstack[INCSTACK_SIZE];
+
+    int		incstack_idx = 0;	/* index in incstack */
+    char_u     *ebuf;			/* additional buffer for etag fname */
+    int		is_etag;		/* current file is emaces style */
+#endif
+
+    struct match_found
+    {
+	int	len;		/* nr of chars of match[] to be compared */
+	char_u	match[1];	/* actually longer */
+    } *mfp, *mfp2;
+    garray_T	ga_match[MT_COUNT];
+    int		match_count = 0;		/* number of matches found */
+    char_u	**matches;
+    int		mtt;
+    int		len;
+    int		help_save;
+#ifdef FEAT_MULTI_LANG
+    int		help_pri = 0;
+    char_u	*help_lang_find = NULL;		/* lang to be found */
+    char_u	help_lang[3];			/* lang of current tags file */
+    char_u	*saved_pat = NULL;		/* copy of pat[] */
+#endif
+
+    /* Use two sets of variables for the pattern: "orgpat" holds the values
+     * for the original pattern and "convpat" converted from 'encoding' to
+     * encoding of the tags file.  "pats" point to either one of these. */
+    pat_T	*pats;
+    pat_T	orgpat;			/* holds unconverted pattern info */
+#ifdef FEAT_MBYTE
+    pat_T	convpat;		/* holds converted pattern info */
+    vimconv_T	vimconv;
+#endif
+
+#ifdef FEAT_TAG_BINS
+    int		findall = (mincount == MAXCOL || mincount == TAG_MANY);
+						/* find all matching tags */
+    int		sort_error = FALSE;		/* tags file not sorted */
+    int		linear;				/* do a linear search */
+    int		sortic = FALSE;			/* tag file sorted in nocase */
+#endif
+    int		line_error = FALSE;		/* syntax error */
+    int		has_re = (flags & TAG_REGEXP);	/* regexp used */
+    int		help_only = (flags & TAG_HELP);
+    int		name_only = (flags & TAG_NAMES);
+    int		noic = (flags & TAG_NOIC);
+    int		get_it_again = FALSE;
+#ifdef FEAT_CSCOPE
+    int		use_cscope = (flags & TAG_CSCOPE);
+#endif
+    int		verbose = (flags & TAG_VERBOSE);
+
+    help_save = curbuf->b_help;
+    orgpat.pat = pat;
+    pats = &orgpat;
+#ifdef FEAT_MBYTE
+    vimconv.vc_type = CONV_NONE;
+#endif
+
+/*
+ * Allocate memory for the buffers that are used
+ */
+    lbuf = alloc(LSIZE);
+    tag_fname = alloc(MAXPATHL + 1);
+#ifdef FEAT_EMACS_TAGS
+    ebuf = alloc(LSIZE);
+#endif
+    for (mtt = 0; mtt < MT_COUNT; ++mtt)
+	ga_init2(&ga_match[mtt], (int)sizeof(struct match_found *), 100);
+
+    /* check for out of memory situation */
+    if (lbuf == NULL || tag_fname == NULL
+#ifdef FEAT_EMACS_TAGS
+					 || ebuf == NULL
+#endif
+							)
+	goto findtag_end;
+
+#ifdef FEAT_CSCOPE
+    STRCPY(tag_fname, "from cscope");		/* for error messages */
+#endif
+
+    /*
+     * Initialize a few variables
+     */
+    if (help_only)				/* want tags from help file */
+	curbuf->b_help = TRUE;			/* will be restored later */
+
+    pats->len = (int)STRLEN(pat);
+#ifdef FEAT_MULTI_LANG
+    if (curbuf->b_help)
+    {
+	/* When "@ab" is specified use only the "ab" language, otherwise
+	 * search all languages. */
+	if (pats->len > 3 && pat[pats->len - 3] == '@'
+					  && ASCII_ISALPHA(pat[pats->len - 2])
+					 && ASCII_ISALPHA(pat[pats->len - 1]))
+	{
+	    saved_pat = vim_strnsave(pat, pats->len - 3);
+	    if (saved_pat != NULL)
+	    {
+		help_lang_find = &pat[pats->len - 2];
+		pats->pat = saved_pat;
+		pats->len -= 3;
+	    }
+	}
+    }
+#endif
+    if (p_tl != 0 && pats->len > p_tl)		/* adjust for 'taglength' */
+	pats->len = p_tl;
+
+    prepare_pats(pats, has_re);
+
+#ifdef FEAT_TAG_BINS
+    /* This is only to avoid a compiler warning for using search_info
+     * uninitialised. */
+    vim_memset(&search_info, 0, (size_t)1);
+#endif
+
+    /*
+     * When finding a specified number of matches, first try with matching
+     * case, so binary search can be used, and try ignore-case matches in a
+     * second loop.
+     * When finding all matches, 'tagbsearch' is off, or there is no fixed
+     * string to look for, ignore case right away to avoid going though the
+     * tags files twice.
+     * When the tag file is case-fold sorted, it is either one or the other.
+     * Only ignore case when TAG_NOIC not used or 'ignorecase' set.
+     */
+#ifdef FEAT_TAG_BINS
+    pats->regmatch.rm_ic = ((p_ic || !noic)
+				&& (findall || pats->headlen == 0 || !p_tbs));
+    for (round = 1; round <= 2; ++round)
+    {
+      linear = (pats->headlen == 0 || !p_tbs || round == 2);
+#else
+      pats->regmatch.rm_ic = (p_ic || !noic);
+#endif
+
+      /*
+       * Try tag file names from tags option one by one.
+       */
+      for (first_file = TRUE;
+#ifdef FEAT_CSCOPE
+	    use_cscope ||
+#endif
+		get_tagfname(&tn, first_file, tag_fname) == OK;
+							   first_file = FALSE)
+      {
+	/*
+	 * A file that doesn't exist is silently ignored.  Only when not a
+	 * single file is found, an error message is given (further on).
+	 */
+#ifdef FEAT_CSCOPE
+	if (use_cscope)
+	    fp = NULL;	    /* avoid GCC warning */
+	else
+#endif
+	{
+#ifdef FEAT_MULTI_LANG
+	    if (curbuf->b_help)
+	    {
+		/* Prefer help tags according to 'helplang'.  Put the
+		 * two-letter language name in help_lang[]. */
+		i = (int)STRLEN(tag_fname);
+		if (i > 3 && tag_fname[i - 3] == '-')
+		    STRCPY(help_lang, tag_fname + i - 2);
+		else
+		    STRCPY(help_lang, "en");
+
+		/* When searching for a specific language skip tags files
+		 * for other languages. */
+		if (help_lang_find != NULL
+				   && STRICMP(help_lang, help_lang_find) != 0)
+		    continue;
+
+		/* For CTRL-] in a help file prefer a match with the same
+		 * language. */
+		if ((flags & TAG_KEEP_LANG)
+			&& help_lang_find == NULL
+			&& curbuf->b_fname != NULL
+			&& (i = (int)STRLEN(curbuf->b_fname)) > 4
+			&& curbuf->b_fname[i - 1] == 'x'
+			&& curbuf->b_fname[i - 4] == '.'
+			&& STRNICMP(curbuf->b_fname + i - 3, help_lang, 2) == 0)
+		    help_pri = 0;
+		else
+		{
+		    help_pri = 1;
+		    for (s = p_hlg; *s != NUL; ++s)
+		    {
+			if (STRNICMP(s, help_lang, 2) == 0)
+			    break;
+			++help_pri;
+			if ((s = vim_strchr(s, ',')) == NULL)
+			    break;
+		    }
+		    if (s == NULL || *s == NUL)
+		    {
+			/* Language not in 'helplang': use last, prefer English,
+			 * unless found already. */
+			++help_pri;
+			if (STRICMP(help_lang, "en") != 0)
+			    ++help_pri;
+		    }
+		}
+	    }
+#endif
+
+	    if ((fp = mch_fopen((char *)tag_fname, "r")) == NULL)
+		continue;
+
+	    if (p_verbose >= 5)
+	    {
+		verbose_enter();
+		smsg((char_u *)_("Searching tags file %s"), tag_fname);
+		verbose_leave();
+	    }
+	}
+	did_open = TRUE;    /* remember that we found at least one file */
+
+	state = TS_START;   /* we're at the start of the file */
+#ifdef FEAT_EMACS_TAGS
+	is_etag = 0;	    /* default is: not emacs style */
+#endif
+
+	/*
+	 * Read and parse the lines in the file one by one
+	 */
+	for (;;)
+	{
+	    line_breakcheck();	    /* check for CTRL-C typed */
+#ifdef FEAT_INS_EXPAND
+	    if ((flags & TAG_INS_COMP))	/* Double brackets for gcc */
+		ins_compl_check_keys(30);
+	    if (got_int || compl_interrupted)
+#else
+	    if (got_int)
+#endif
+	    {
+		stop_searching = TRUE;
+		break;
+	    }
+	    /* When mincount is TAG_MANY, stop when enough matches have been
+	     * found (for completion). */
+	    if (mincount == TAG_MANY && match_count >= TAG_MANY)
+	    {
+		stop_searching = TRUE;
+		retval = OK;
+		break;
+	    }
+	    if (get_it_again)
+		goto line_read_in;
+#ifdef FEAT_TAG_BINS
+	    /*
+	     * For binary search: compute the next offset to use.
+	     */
+	    if (state == TS_BINARY)
+	    {
+		offset = search_info.low_offset + ((search_info.high_offset
+					       - search_info.low_offset) / 2);
+		if (offset == search_info.curr_offset)
+		    break;	/* End the binary search without a match. */
+		else
+		    search_info.curr_offset = offset;
+	    }
+
+	    /*
+	     * Skipping back (after a match during binary search).
+	     */
+	    else if (state == TS_SKIP_BACK)
+	    {
+		search_info.curr_offset -= LSIZE * 2;
+		if (search_info.curr_offset < 0)
+		{
+		    search_info.curr_offset = 0;
+		    rewind(fp);
+		    state = TS_STEP_FORWARD;
+		}
+	    }
+
+	    /*
+	     * When jumping around in the file, first read a line to find the
+	     * start of the next line.
+	     */
+	    if (state == TS_BINARY || state == TS_SKIP_BACK)
+	    {
+		/* Adjust the search file offset to the correct position */
+		search_info.curr_offset_used = search_info.curr_offset;
+#ifdef HAVE_FSEEKO
+		fseeko(fp, search_info.curr_offset, SEEK_SET);
+#else
+		fseek(fp, (long)search_info.curr_offset, SEEK_SET);
+#endif
+		eof = tag_fgets(lbuf, LSIZE, fp);
+		if (!eof && search_info.curr_offset != 0)
+		{
+		    /* The explicit cast is to work around a bug in gcc 3.4.2
+		     * (repeated below). */
+		    search_info.curr_offset = ftell(fp);
+		    if (search_info.curr_offset == search_info.high_offset)
+		    {
+			/* oops, gone a bit too far; try from low offset */
+#ifdef HAVE_FSEEKO
+			fseeko(fp, search_info.low_offset, SEEK_SET);
+#else
+			fseek(fp, (long)search_info.low_offset, SEEK_SET);
+#endif
+			search_info.curr_offset = search_info.low_offset;
+		    }
+		    eof = tag_fgets(lbuf, LSIZE, fp);
+		}
+		/* skip empty and blank lines */
+		while (!eof && vim_isblankline(lbuf))
+		{
+		    search_info.curr_offset = ftell(fp);
+		    eof = tag_fgets(lbuf, LSIZE, fp);
+		}
+		if (eof)
+		{
+		    /* Hit end of file.  Skip backwards. */
+		    state = TS_SKIP_BACK;
+		    search_info.match_offset = ftell(fp);
+		    search_info.curr_offset = search_info.curr_offset_used;
+		    continue;
+		}
+	    }
+
+	    /*
+	     * Not jumping around in the file: Read the next line.
+	     */
+	    else
+#endif
+	    {
+		/* skip empty and blank lines */
+		do
+		{
+#ifdef FEAT_CSCOPE
+		    if (use_cscope)
+			eof = cs_fgets(lbuf, LSIZE);
+		    else
+#endif
+			eof = tag_fgets(lbuf, LSIZE, fp);
+		} while (!eof && vim_isblankline(lbuf));
+
+		if (eof)
+		{
+#ifdef FEAT_EMACS_TAGS
+		    if (incstack_idx)	/* this was an included file */
+		    {
+			--incstack_idx;
+			fclose(fp);	/* end of this file ... */
+			fp = incstack[incstack_idx].fp;
+			STRCPY(tag_fname, incstack[incstack_idx].etag_fname);
+			vim_free(incstack[incstack_idx].etag_fname);
+			is_etag = 1;	/* (only etags can include) */
+			continue;	/* ... continue with parent file */
+		    }
+		    else
+#endif
+			break;			    /* end of file */
+		}
+	    }
+line_read_in:
+
+#ifdef FEAT_EMACS_TAGS
+	    /*
+	     * Emacs tags line with CTRL-L: New file name on next line.
+	     * The file name is followed by a ','.
+	     */
+	    if (*lbuf == Ctrl_L)	/* remember etag file name in ebuf */
+	    {
+		is_etag = 1;		/* in case at the start */
+		state = TS_LINEAR;
+		if (!tag_fgets(ebuf, LSIZE, fp))
+		{
+		    for (p = ebuf; *p && *p != ','; p++)
+			;
+		    *p = NUL;
+
+		    /*
+		     * atoi(p+1) is the number of bytes before the next ^L
+		     * unless it is an include statement.
+		     */
+		    if (STRNCMP(p + 1, "include", 7) == 0
+					      && incstack_idx < INCSTACK_SIZE)
+		    {
+			/* Save current "fp" and "tag_fname" in the stack. */
+			if ((incstack[incstack_idx].etag_fname =
+					      vim_strsave(tag_fname)) != NULL)
+			{
+			    char_u *fullpath_ebuf;
+
+			    incstack[incstack_idx].fp = fp;
+			    fp = NULL;
+
+			    /* Figure out "tag_fname" and "fp" to use for
+			     * included file. */
+			    fullpath_ebuf = expand_tag_fname(ebuf,
+							    tag_fname, FALSE);
+			    if (fullpath_ebuf != NULL)
+			    {
+				fp = mch_fopen((char *)fullpath_ebuf, "r");
+				if (fp != NULL)
+				{
+				    if (STRLEN(fullpath_ebuf) > LSIZE)
+					  EMSG2(_("E430: Tag file path truncated for %s\n"), ebuf);
+				    vim_strncpy(tag_fname, fullpath_ebuf,
+								    MAXPATHL);
+				    ++incstack_idx;
+				    is_etag = 0; /* we can include anything */
+				}
+				vim_free(fullpath_ebuf);
+			    }
+			    if (fp == NULL)
+			    {
+				/* Can't open the included file, skip it and
+				 * restore old value of "fp". */
+				fp = incstack[incstack_idx].fp;
+				vim_free(incstack[incstack_idx].etag_fname);
+			    }
+			}
+		    }
+		}
+		continue;
+	    }
+#endif
+
+	    /*
+	     * When still at the start of the file, check for Emacs tags file
+	     * format, and for "not sorted" flag.
+	     */
+	    if (state == TS_START)
+	    {
+#ifdef FEAT_TAG_BINS
+		/*
+		 * When there is no tag head, or ignoring case, need to do a
+		 * linear search.
+		 * When no "!_TAG_" is found, default to binary search.  If
+		 * the tag file isn't sorted, the second loop will find it.
+		 * When "!_TAG_FILE_SORTED" found: start binary search if
+		 * flag set.
+		 * For cscope, it's always linear.
+		 */
+# ifdef FEAT_CSCOPE
+		if (linear || use_cscope)
+# else
+		if (linear)
+# endif
+		    state = TS_LINEAR;
+		else if (STRNCMP(lbuf, "!_TAG_", 6) > 0)
+		    state = TS_BINARY;
+		else if (STRNCMP(lbuf, "!_TAG_FILE_SORTED\t", 18) == 0)
+		{
+		    /* Check sorted flag */
+		    if (lbuf[18] == '1')
+			state = TS_BINARY;
+		    else if (lbuf[18] == '2')
+		    {
+			state = TS_BINARY;
+			sortic = TRUE;
+			pats->regmatch.rm_ic = (p_ic || !noic);
+		    }
+		    else
+			state = TS_LINEAR;
+		}
+
+		if (state == TS_BINARY && pats->regmatch.rm_ic && !sortic)
+		{
+		    /* binary search won't work for ignoring case, use linear
+		     * search. */
+		    linear = TRUE;
+		    state = TS_LINEAR;
+		}
+#else
+		state = TS_LINEAR;
+#endif
+
+#ifdef FEAT_TAG_BINS
+		/*
+		 * When starting a binary search, get the size of the file and
+		 * compute the first offset.
+		 */
+		if (state == TS_BINARY)
+		{
+		    /* Get the tag file size (don't use mch_fstat(), it's not
+		     * portable). */
+		    if ((filesize = lseek(fileno(fp),
+						   (off_t)0L, SEEK_END)) <= 0)
+			state = TS_LINEAR;
+		    else
+		    {
+			lseek(fileno(fp), (off_t)0L, SEEK_SET);
+
+			/* Calculate the first read offset in the file.  Start
+			 * the search in the middle of the file. */
+			search_info.low_offset = 0;
+			search_info.low_char = 0;
+			search_info.high_offset = filesize;
+			search_info.curr_offset = 0;
+			search_info.high_char = 0xff;
+		    }
+		    continue;
+		}
+#endif
+	    }
+
+#ifdef FEAT_MBYTE
+	    if (lbuf[0] == '!' && pats == &orgpat
+			   && STRNCMP(lbuf, "!_TAG_FILE_ENCODING\t", 20) == 0)
+	    {
+		/* Convert the search pattern from 'encoding' to the
+		 * specified encoding. */
+		for (p = lbuf + 20; *p > ' ' && *p < 127; ++p)
+		    ;
+		*p = NUL;
+		convert_setup(&vimconv, p_enc, lbuf + 20);
+		if (vimconv.vc_type != CONV_NONE)
+		{
+		    convpat.pat = string_convert(&vimconv, pats->pat, NULL);
+		    if (convpat.pat != NULL)
+		    {
+			pats = &convpat;
+			pats->len = (int)STRLEN(pats->pat);
+			prepare_pats(pats, has_re);
+			pats->regmatch.rm_ic = orgpat.regmatch.rm_ic;
+		    }
+		}
+
+		/* Prepare for converting a match the other way around. */
+		convert_setup(&vimconv, lbuf + 20, p_enc);
+		continue;
+	    }
+#endif
+
+	    /*
+	     * Figure out where the different strings are in this line.
+	     * For "normal" tags: Do a quick check if the tag matches.
+	     * This speeds up tag searching a lot!
+	     */
+	    if (pats->headlen
+#ifdef FEAT_EMACS_TAGS
+			    && !is_etag
+#endif
+					)
+	    {
+		tagp.tagname = lbuf;
+#ifdef FEAT_TAG_ANYWHITE
+		tagp.tagname_end = skiptowhite(lbuf);
+		if (*tagp.tagname_end == NUL)	    /* corrupted tag line */
+#else
+		tagp.tagname_end = vim_strchr(lbuf, TAB);
+		if (tagp.tagname_end == NULL)	    /* corrupted tag line */
+#endif
+		{
+		    line_error = TRUE;
+		    break;
+		}
+
+#ifdef FEAT_TAG_OLDSTATIC
+		/*
+		 * Check for old style static tag: "file:tag file .."
+		 */
+		tagp.fname = NULL;
+		for (p = lbuf; p < tagp.tagname_end; ++p)
+		{
+		    if (*p == ':')
+		    {
+			if (tagp.fname == NULL)
+#ifdef FEAT_TAG_ANYWHITE
+			    tagp.fname = skipwhite(tagp.tagname_end);
+#else
+			    tagp.fname = tagp.tagname_end + 1;
+#endif
+			if (	   fnamencmp(lbuf, tagp.fname, p - lbuf) == 0
+#ifdef FEAT_TAG_ANYWHITE
+				&& vim_iswhite(tagp.fname[p - lbuf])
+#else
+				&& tagp.fname[p - lbuf] == TAB
+#endif
+				    )
+			{
+			    /* found one */
+			    tagp.tagname = p + 1;
+			    break;
+			}
+		    }
+		}
+#endif
+
+		/*
+		 * Skip this line if the length of the tag is different and
+		 * there is no regexp, or the tag is too short.
+		 */
+		cmplen = (int)(tagp.tagname_end - tagp.tagname);
+		if (p_tl != 0 && cmplen > p_tl)	    /* adjust for 'taglength' */
+		    cmplen = p_tl;
+		if (has_re && pats->headlen < cmplen)
+		    cmplen = pats->headlen;
+		else if (state == TS_LINEAR && pats->headlen != cmplen)
+		    continue;
+
+#ifdef FEAT_TAG_BINS
+		if (state == TS_BINARY)
+		{
+		    /*
+		     * Simplistic check for unsorted tags file.
+		     */
+		    i = (int)tagp.tagname[0];
+		    if (sortic)
+			i = (int)TOUPPER_ASC(tagp.tagname[0]);
+		    if (i < search_info.low_char || i > search_info.high_char)
+			sort_error = TRUE;
+
+		    /*
+		     * Compare the current tag with the searched tag.
+		     */
+		    if (sortic)
+			tagcmp = tag_strnicmp(tagp.tagname, pats->head,
+							      (size_t)cmplen);
+		    else
+			tagcmp = STRNCMP(tagp.tagname, pats->head, cmplen);
+
+		    /*
+		     * A match with a shorter tag means to search forward.
+		     * A match with a longer tag means to search backward.
+		     */
+		    if (tagcmp == 0)
+		    {
+			if (cmplen < pats->headlen)
+			    tagcmp = -1;
+			else if (cmplen > pats->headlen)
+			    tagcmp = 1;
+		    }
+
+		    if (tagcmp == 0)
+		    {
+			/* We've located the tag, now skip back and search
+			 * forward until the first matching tag is found.
+			 */
+			state = TS_SKIP_BACK;
+			search_info.match_offset = search_info.curr_offset;
+			continue;
+		    }
+		    if (tagcmp < 0)
+		    {
+			search_info.curr_offset = ftell(fp);
+			if (search_info.curr_offset < search_info.high_offset)
+			{
+			    search_info.low_offset = search_info.curr_offset;
+			    if (sortic)
+				search_info.low_char =
+						 TOUPPER_ASC(tagp.tagname[0]);
+			    else
+				search_info.low_char = tagp.tagname[0];
+			    continue;
+			}
+		    }
+		    if (tagcmp > 0
+			&& search_info.curr_offset != search_info.high_offset)
+		    {
+			search_info.high_offset = search_info.curr_offset;
+			if (sortic)
+			    search_info.high_char =
+						 TOUPPER_ASC(tagp.tagname[0]);
+			else
+			    search_info.high_char = tagp.tagname[0];
+			continue;
+		    }
+
+		    /* No match yet and are at the end of the binary search. */
+		    break;
+		}
+		else if (state == TS_SKIP_BACK)
+		{
+		    if (MB_STRNICMP(tagp.tagname, pats->head, cmplen) != 0)
+			state = TS_STEP_FORWARD;
+		    else
+			/* Have to skip back more.  Restore the curr_offset
+			 * used, otherwise we get stuck at a long line. */
+			search_info.curr_offset = search_info.curr_offset_used;
+		    continue;
+		}
+		else if (state == TS_STEP_FORWARD)
+		{
+		    if (MB_STRNICMP(tagp.tagname, pats->head, cmplen) != 0)
+		    {
+			if ((off_t)ftell(fp) > search_info.match_offset)
+			    break;	/* past last match */
+			else
+			    continue;	/* before first match */
+		    }
+		}
+		else
+#endif
+		    /* skip this match if it can't match */
+		    if (MB_STRNICMP(tagp.tagname, pats->head, cmplen) != 0)
+		    continue;
+
+		/*
+		 * Can be a matching tag, isolate the file name and command.
+		 */
+#ifdef FEAT_TAG_OLDSTATIC
+		if (tagp.fname == NULL)
+#endif
+#ifdef FEAT_TAG_ANYWHITE
+		    tagp.fname = skipwhite(tagp.tagname_end);
+#else
+		    tagp.fname = tagp.tagname_end + 1;
+#endif
+#ifdef FEAT_TAG_ANYWHITE
+		tagp.fname_end = skiptowhite(tagp.fname);
+		tagp.command = skipwhite(tagp.fname_end);
+		if (*tagp.command == NUL)
+#else
+		tagp.fname_end = vim_strchr(tagp.fname, TAB);
+		tagp.command = tagp.fname_end + 1;
+		if (tagp.fname_end == NULL)
+#endif
+		    i = FAIL;
+		else
+		    i = OK;
+	    }
+	    else
+		i = parse_tag_line(lbuf,
+#ifdef FEAT_EMACS_TAGS
+				       is_etag,
+#endif
+					       &tagp);
+	    if (i == FAIL)
+	    {
+		line_error = TRUE;
+		break;
+	    }
+
+#ifdef FEAT_EMACS_TAGS
+	    if (is_etag)
+		tagp.fname = ebuf;
+#endif
+	    /*
+	     * First try matching with the pattern literally (also when it is
+	     * a regexp).
+	     */
+	    cmplen = (int)(tagp.tagname_end - tagp.tagname);
+	    if (p_tl != 0 && cmplen > p_tl)	    /* adjust for 'taglength' */
+		cmplen = p_tl;
+	    /* if tag length does not match, don't try comparing */
+	    if (pats->len != cmplen)
+		match = FALSE;
+	    else
+	    {
+		if (pats->regmatch.rm_ic)
+		{
+		    match = (MB_STRNICMP(tagp.tagname, pats->pat, cmplen) == 0);
+		    if (match)
+			match_no_ic = (STRNCMP(tagp.tagname, pats->pat,
+								cmplen) == 0);
+		}
+		else
+		    match = (STRNCMP(tagp.tagname, pats->pat, cmplen) == 0);
+	    }
+
+	    /*
+	     * Has a regexp: Also find tags matching regexp.
+	     */
+	    match_re = FALSE;
+	    if (!match && pats->regmatch.regprog != NULL)
+	    {
+		int	cc;
+
+		cc = *tagp.tagname_end;
+		*tagp.tagname_end = NUL;
+		match = vim_regexec(&pats->regmatch, tagp.tagname, (colnr_T)0);
+		if (match)
+		{
+		    matchoff = (int)(pats->regmatch.startp[0] - tagp.tagname);
+		    if (pats->regmatch.rm_ic)
+		    {
+			pats->regmatch.rm_ic = FALSE;
+			match_no_ic = vim_regexec(&pats->regmatch, tagp.tagname,
+								  (colnr_T)0);
+			pats->regmatch.rm_ic = TRUE;
+		    }
+		}
+		*tagp.tagname_end = cc;
+		match_re = TRUE;
+	    }
+
+	    /*
+	     * If a match is found, add it to ga_match[].
+	     */
+	    if (match)
+	    {
+#ifdef FEAT_CSCOPE
+		if (use_cscope)
+		{
+		    /* Don't change the ordering, always use the same table. */
+		    mtt = MT_GL_OTH;
+		}
+		else
+#endif
+		{
+		    /* Decide in which array to store this match. */
+		    is_current = test_for_current(
+#ifdef FEAT_EMACS_TAGS
+			    is_etag,
+#endif
+				     tagp.fname, tagp.fname_end, tag_fname,
+				     buf_ffname);
+#ifdef FEAT_EMACS_TAGS
+		    is_static = FALSE;
+		    if (!is_etag)	/* emacs tags are never static */
+#endif
+		    {
+#ifdef FEAT_TAG_OLDSTATIC
+			if (tagp.tagname != lbuf)
+			    is_static = TRUE;	/* detected static tag before */
+			else
+#endif
+			    is_static = test_for_static(&tagp);
+		    }
+
+		    /* decide in which of the sixteen tables to store this
+		     * match */
+		    if (is_static)
+		    {
+			if (is_current)
+			    mtt = MT_ST_CUR;
+			else
+			    mtt = MT_ST_OTH;
+		    }
+		    else
+		    {
+			if (is_current)
+			    mtt = MT_GL_CUR;
+			else
+			    mtt = MT_GL_OTH;
+		    }
+		    if (pats->regmatch.rm_ic && !match_no_ic)
+			mtt += MT_IC_OFF;
+		    if (match_re)
+			mtt += MT_RE_OFF;
+		}
+
+		/*
+		 * Add the found match in ga_match[mtt], avoiding duplicates.
+		 * Store the info we need later, which depends on the kind of
+		 * tags we are dealing with.
+		 */
+		if (ga_grow(&ga_match[mtt], 1) == OK)
+		{
+#ifdef FEAT_MBYTE
+		    char_u	*conv_line = NULL;
+		    char_u	*lbuf_line = lbuf;
+
+		    if (vimconv.vc_type != CONV_NONE)
+		    {
+			/* Convert the tag line from the encoding of the tags
+			 * file to 'encoding'.  Then parse the line again. */
+			conv_line = string_convert(&vimconv, lbuf, NULL);
+			if (conv_line != NULL)
+			{
+			    if (parse_tag_line(conv_line,
+#ifdef FEAT_EMACS_TAGS
+					is_etag,
+#endif
+					&tagp) == OK)
+				lbuf_line = conv_line;
+			    else
+				/* doesn't work, go back to unconverted line. */
+				(void)parse_tag_line(lbuf,
+#ifdef FEAT_EMACS_TAGS
+						     is_etag,
+#endif
+						     &tagp);
+			}
+		    }
+#else
+# define lbuf_line lbuf
+#endif
+		    if (help_only)
+		    {
+#ifdef FEAT_MULTI_LANG
+# define ML_EXTRA 3
+#else
+# define ML_EXTRA 0
+#endif
+			/*
+			 * Append the help-heuristic number after the
+			 * tagname, for sorting it later.
+			 */
+			*tagp.tagname_end = NUL;
+			len = (int)(tagp.tagname_end - tagp.tagname);
+			mfp = (struct match_found *)
+				 alloc((int)sizeof(struct match_found) + len
+							     + 10 + ML_EXTRA);
+			if (mfp != NULL)
+			{
+			    /* "len" includes the language and the NUL, but
+			     * not the priority. */
+			    mfp->len = len + ML_EXTRA + 1;
+#define ML_HELP_LEN 6
+			    p = mfp->match;
+			    STRCPY(p, tagp.tagname);
+#ifdef FEAT_MULTI_LANG
+			    p[len] = '@';
+			    STRCPY(p + len + 1, help_lang);
+#endif
+			    sprintf((char *)p + len + 1 + ML_EXTRA, "%06d",
+				    help_heuristic(tagp.tagname,
+					match_re ? matchoff : 0, !match_no_ic)
+#ifdef FEAT_MULTI_LANG
+				    + help_pri
+#endif
+				    );
+			}
+			*tagp.tagname_end = TAB;
+		    }
+		    else if (name_only)
+		    {
+			if (get_it_again)
+			{
+			    char_u *temp_end = tagp.command;
+
+			    if (*temp_end == '/')
+				while (*temp_end && *temp_end != '\r'
+					&& *temp_end != '\n'
+					&& *temp_end != '$')
+				    temp_end++;
+
+			    if (tagp.command + 2 < temp_end)
+			    {
+				len = (int)(temp_end - tagp.command - 2);
+				mfp = (struct match_found *)alloc(
+					(int)sizeof(struct match_found) + len);
+				if (mfp != NULL)
+				{
+				    mfp->len = len + 1; /* include the NUL */
+				    p = mfp->match;
+				    vim_strncpy(p, tagp.command + 2, len);
+				}
+			    }
+			    else
+				mfp = NULL;
+			    get_it_again = FALSE;
+			}
+			else
+			{
+			    len = (int)(tagp.tagname_end - tagp.tagname);
+			    mfp = (struct match_found *)alloc(
+				       (int)sizeof(struct match_found) + len);
+			    if (mfp != NULL)
+			    {
+				mfp->len = len + 1; /* include the NUL */
+				p = mfp->match;
+				vim_strncpy(p, tagp.tagname, len);
+			    }
+
+			    /* if wanted, re-read line to get long form too */
+			    if (State & INSERT)
+				get_it_again = p_sft;
+			}
+		    }
+		    else
+		    {
+			/* Save the tag in a buffer.
+			 * Emacs tag: <mtt><tag_fname><NUL><ebuf><NUL><lbuf>
+			 * other tag: <mtt><tag_fname><NUL><NUL><lbuf>
+			 * without Emacs tags: <mtt><tag_fname><NUL><lbuf>
+			 */
+			len = (int)STRLEN(tag_fname)
+						 + (int)STRLEN(lbuf_line) + 3;
+#ifdef FEAT_EMACS_TAGS
+			if (is_etag)
+			    len += (int)STRLEN(ebuf) + 1;
+			else
+			    ++len;
+#endif
+			mfp = (struct match_found *)alloc(
+				       (int)sizeof(struct match_found) + len);
+			if (mfp != NULL)
+			{
+			    mfp->len = len;
+			    p = mfp->match;
+			    p[0] = mtt;
+			    STRCPY(p + 1, tag_fname);
+#ifdef BACKSLASH_IN_FILENAME
+			    /* Ignore differences in slashes, avoid adding
+			     * both path/file and path\file. */
+			    slash_adjust(p + 1);
+#endif
+			    s = p + 1 + STRLEN(tag_fname) + 1;
+#ifdef FEAT_EMACS_TAGS
+			    if (is_etag)
+			    {
+				STRCPY(s, ebuf);
+				s += STRLEN(ebuf) + 1;
+			    }
+			    else
+				*s++ = NUL;
+#endif
+			    STRCPY(s, lbuf_line);
+			}
+		    }
+
+		    if (mfp != NULL)
+		    {
+			/*
+			 * Don't add identical matches.
+			 * This can take a lot of time when finding many
+			 * matches, check for CTRL-C now and then.
+			 * Add all cscope tags, because they are all listed.
+			 */
+#ifdef FEAT_CSCOPE
+			if (use_cscope)
+			    i = -1;
+			else
+#endif
+			  for (i = ga_match[mtt].ga_len; --i >= 0 && !got_int; )
+			  {
+			      mfp2 = ((struct match_found **)
+						  (ga_match[mtt].ga_data))[i];
+			      if (mfp2->len == mfp->len
+				      && vim_memcmp(mfp2->match, mfp->match,
+						       (size_t)mfp->len) == 0)
+				  break;
+			      line_breakcheck();
+			  }
+			if (i < 0)
+			{
+			    ((struct match_found **)(ga_match[mtt].ga_data))
+					       [ga_match[mtt].ga_len++] = mfp;
+			    ++match_count;
+			}
+			else
+			    vim_free(mfp);
+		    }
+#ifdef FEAT_MBYTE
+		    /* Note: this makes the values in "tagp" invalid! */
+		    vim_free(conv_line);
+#endif
+		}
+		else    /* Out of memory! Just forget about the rest. */
+		{
+		    retval = OK;
+		    stop_searching = TRUE;
+		    break;
+		}
+	    }
+#ifdef FEAT_CSCOPE
+	    if (use_cscope && eof)
+		break;
+#endif
+	} /* forever */
+
+	if (line_error)
+	{
+	    EMSG2(_("E431: Format error in tags file \"%s\""), tag_fname);
+#ifdef FEAT_CSCOPE
+	    if (!use_cscope)
+#endif
+		EMSGN(_("Before byte %ld"), (long)ftell(fp));
+	    stop_searching = TRUE;
+	    line_error = FALSE;
+	}
+
+#ifdef FEAT_CSCOPE
+	if (!use_cscope)
+#endif
+	    fclose(fp);
+#ifdef FEAT_EMACS_TAGS
+	while (incstack_idx)
+	{
+	    --incstack_idx;
+	    fclose(incstack[incstack_idx].fp);
+	    vim_free(incstack[incstack_idx].etag_fname);
+	}
+#endif
+#ifdef FEAT_MBYTE
+	if (pats == &convpat)
+	{
+	    /* Go back from converted pattern to original pattern. */
+	    vim_free(pats->pat);
+	    vim_free(pats->regmatch.regprog);
+	    orgpat.regmatch.rm_ic = pats->regmatch.rm_ic;
+	    pats = &orgpat;
+	}
+	if (vimconv.vc_type != CONV_NONE)
+	    convert_setup(&vimconv, NULL, NULL);
+#endif
+
+#ifdef FEAT_TAG_BINS
+	if (sort_error)
+	{
+	    EMSG2(_("E432: Tags file not sorted: %s"), tag_fname);
+	    sort_error = FALSE;
+	}
+#endif
+
+	/*
+	 * Stop searching if sufficient tags have been found.
+	 */
+	if (match_count >= mincount)
+	{
+	    retval = OK;
+	    stop_searching = TRUE;
+	}
+
+#ifdef FEAT_CSCOPE
+	if (stop_searching || use_cscope)
+#else
+	if (stop_searching)
+#endif
+	    break;
+
+      } /* end of for-each-file loop */
+
+#ifdef FEAT_CSCOPE
+	if (!use_cscope)
+#endif
+	    tagname_free(&tn);
+
+#ifdef FEAT_TAG_BINS
+      /* stop searching when already did a linear search, or when TAG_NOIC
+       * used, and 'ignorecase' not set or already did case-ignore search */
+      if (stop_searching || linear || (!p_ic && noic) || pats->regmatch.rm_ic)
+	  break;
+# ifdef FEAT_CSCOPE
+      if (use_cscope)
+	  break;
+# endif
+      pats->regmatch.rm_ic = TRUE;	/* try another time while ignoring case */
+    }
+#endif
+
+    if (!stop_searching)
+    {
+	if (!did_open && verbose)	/* never opened any tags file */
+	    EMSG(_("E433: No tags file"));
+	retval = OK;		/* It's OK even when no tag found */
+    }
+
+findtag_end:
+    vim_free(lbuf);
+    vim_free(pats->regmatch.regprog);
+    vim_free(tag_fname);
+#ifdef FEAT_EMACS_TAGS
+    vim_free(ebuf);
+#endif
+
+    /*
+     * Move the matches from the ga_match[] arrays into one list of
+     * matches.  When retval == FAIL, free the matches.
+     */
+    if (retval == FAIL)
+	match_count = 0;
+
+    if (match_count > 0)
+	matches = (char_u **)lalloc((long_u)(match_count * sizeof(char_u *)),
+									TRUE);
+    else
+	matches = NULL;
+    match_count = 0;
+    for (mtt = 0; mtt < MT_COUNT; ++mtt)
+    {
+	for (i = 0; i < ga_match[mtt].ga_len; ++i)
+	{
+	    mfp = ((struct match_found **)(ga_match[mtt].ga_data))[i];
+	    if (matches == NULL)
+		vim_free(mfp);
+	    else
+	    {
+		/* To avoid allocating memory again we turn the struct
+		 * match_found into a string.  For help the priority was not
+		 * included in the length. */
+		mch_memmove(mfp, mfp->match,
+			 (size_t)(mfp->len + (help_only ? ML_HELP_LEN : 0)));
+		matches[match_count++] = (char_u *)mfp;
+	    }
+	}
+	ga_clear(&ga_match[mtt]);
+    }
+
+    *matchesp = matches;
+    *num_matches = match_count;
+
+    curbuf->b_help = help_save;
+#ifdef FEAT_MULTI_LANG
+    vim_free(saved_pat);
+#endif
+
+    return retval;
+}
+
+static garray_T tag_fnames = GA_EMPTY;
+static void found_tagfile_cb __ARGS((char_u *fname, void *cookie));
+
+/*
+ * Callback function for finding all "tags" and "tags-??" files in
+ * 'runtimepath' doc directories.
+ */
+/*ARGSUSED*/
+    static void
+found_tagfile_cb(fname, cookie)
+    char_u	*fname;
+    void	*cookie;
+{
+    if (ga_grow(&tag_fnames, 1) == OK)
+	((char_u **)(tag_fnames.ga_data))[tag_fnames.ga_len++] =
+							   vim_strsave(fname);
+}
+
+#if defined(EXITFREE) || defined(PROTO)
+    void
+free_tag_stuff()
+{
+    ga_clear_strings(&tag_fnames);
+    do_tag(NULL, DT_FREE, 0, 0, 0);
+}
+#endif
+
+/*
+ * Get the next name of a tag file from the tag file list.
+ * For help files, use "tags" file only.
+ *
+ * Return FAIL if no more tag file names, OK otherwise.
+ */
+    int
+get_tagfname(tnp, first, buf)
+    tagname_T	*tnp;	/* holds status info */
+    int		first;	/* TRUE when first file name is wanted */
+    char_u	*buf;	/* pointer to buffer of MAXPATHL chars */
+{
+    char_u		*fname = NULL;
+    char_u		*r_ptr;
+
+    if (first)
+	vim_memset(tnp, 0, sizeof(tagname_T));
+
+    if (curbuf->b_help)
+    {
+	/*
+	 * For help files it's done in a completely different way:
+	 * Find "doc/tags" and "doc/tags-??" in all directories in
+	 * 'runtimepath'.
+	 */
+	if (first)
+	{
+	    ga_clear_strings(&tag_fnames);
+	    ga_init2(&tag_fnames, (int)sizeof(char_u *), 10);
+	    do_in_runtimepath((char_u *)
+#ifdef FEAT_MULTI_LANG
+# ifdef VMS
+		    /* Functions decc$to_vms() and decc$translate_vms() crash
+		     * on some VMS systems with wildcards "??".  Seems ECO
+		     * patches do fix the problem in C RTL, but we can't use
+		     * an #ifdef for that. */
+		    "doc/tags doc/tags-*"
+# else
+		    "doc/tags doc/tags-??"
+# endif
+#else
+		    "doc/tags"
+#endif
+					      , TRUE, found_tagfile_cb, NULL);
+	}
+
+	if (tnp->tn_hf_idx >= tag_fnames.ga_len)
+	{
+	    /* Not found in 'runtimepath', use 'helpfile', if it exists and
+	     * wasn't used yet, replacing "help.txt" with "tags". */
+	    if (tnp->tn_hf_idx > tag_fnames.ga_len || *p_hf == NUL)
+		return FAIL;
+	    ++tnp->tn_hf_idx;
+	    STRCPY(buf, p_hf);
+	    STRCPY(gettail(buf), "tags");
+	}
+	else
+	    vim_strncpy(buf, ((char_u **)(tag_fnames.ga_data))[
+					     tnp->tn_hf_idx++], MAXPATHL - 1);
+	return OK;
+    }
+
+    if (first)
+    {
+	/* Init.  We make a copy of 'tags', because autocommands may change
+	 * the value without notifying us. */
+	tnp->tn_tags = vim_strsave((*curbuf->b_p_tags != NUL)
+						 ? curbuf->b_p_tags : p_tags);
+	if (tnp->tn_tags == NULL)
+	    return FAIL;
+	tnp->tn_np = tnp->tn_tags;
+    }
+
+    /*
+     * Loop until we have found a file name that can be used.
+     * There are two states:
+     * tnp->tn_did_filefind_init == FALSE: setup for next part in 'tags'.
+     * tnp->tn_did_filefind_init == TRUE: find next file in this part.
+     */
+    for (;;)
+    {
+	if (tnp->tn_did_filefind_init)
+	{
+	    fname = vim_findfile(tnp->tn_search_ctx);
+	    if (fname != NULL)
+		break;
+
+	    tnp->tn_did_filefind_init = FALSE;
+	}
+	else
+	{
+	    char_u  *filename = NULL;
+
+	    /* Stop when used all parts of 'tags'. */
+	    if (*tnp->tn_np == NUL)
+	    {
+		vim_findfile_cleanup(tnp->tn_search_ctx);
+		tnp->tn_search_ctx = NULL;
+		return FAIL;
+	    }
+
+	    /*
+	     * Copy next file name into buf.
+	     */
+	    buf[0] = NUL;
+	    (void)copy_option_part(&tnp->tn_np, buf, MAXPATHL - 1, " ,");
+
+#ifdef FEAT_PATH_EXTRA
+	    r_ptr = vim_findfile_stopdir(buf);
+#else
+	    r_ptr = NULL;
+#endif
+	    /* move the filename one char forward and truncate the
+	     * filepath with a NUL */
+	    filename = gettail(buf);
+	    mch_memmove(filename + 1, filename, STRLEN(filename) + 1);
+	    *filename++ = NUL;
+
+	    tnp->tn_search_ctx = vim_findfile_init(buf, filename,
+		    r_ptr, 100,
+		    FALSE, /* don't free visited list */
+		    FALSE, /* we search for a file */
+		    tnp->tn_search_ctx, TRUE, curbuf->b_ffname);
+	    if (tnp->tn_search_ctx != NULL)
+		tnp->tn_did_filefind_init = TRUE;
+	}
+    }
+
+    STRCPY(buf, fname);
+    vim_free(fname);
+    return OK;
+}
+
+/*
+ * Free the contents of a tagname_T that was filled by get_tagfname().
+ */
+    void
+tagname_free(tnp)
+    tagname_T	*tnp;
+{
+    vim_free(tnp->tn_tags);
+    vim_findfile_cleanup(tnp->tn_search_ctx);
+    ga_clear_strings(&tag_fnames);
+}
+
+/*
+ * Parse one line from the tags file. Find start/end of tag name, start/end of
+ * file name and start of search pattern.
+ *
+ * If is_etag is TRUE, tagp->fname and tagp->fname_end are not set.
+ *
+ * Return FAIL if there is a format error in this line, OK otherwise.
+ */
+    static int
+parse_tag_line(lbuf,
+#ifdef FEAT_EMACS_TAGS
+		    is_etag,
+#endif
+			      tagp)
+    char_u	*lbuf;		/* line to be parsed */
+#ifdef FEAT_EMACS_TAGS
+    int		is_etag;
+#endif
+    tagptrs_T	*tagp;
+{
+    char_u	*p;
+
+#ifdef FEAT_EMACS_TAGS
+    char_u	*p_7f;
+
+    if (is_etag)
+    {
+	/*
+	 * There are two formats for an emacs tag line:
+	 * 1:  struct EnvBase ^?EnvBase^A139,4627
+	 * 2: #define	ARPB_WILD_WORLD ^?153,5194
+	 */
+	p_7f = vim_strchr(lbuf, 0x7f);
+	if (p_7f == NULL)
+	    return FAIL;
+
+	/* Find ^A.  If not found the line number is after the 0x7f */
+	p = vim_strchr(p_7f, Ctrl_A);
+	if (p == NULL)
+	    p = p_7f + 1;
+	else
+	    ++p;
+
+	if (!VIM_ISDIGIT(*p))	    /* check for start of line number */
+	    return FAIL;
+	tagp->command = p;
+
+
+	if (p[-1] == Ctrl_A)	    /* first format: explicit tagname given */
+	{
+	    tagp->tagname = p_7f + 1;
+	    tagp->tagname_end = p - 1;
+	}
+	else			    /* second format: isolate tagname */
+	{
+	    /* find end of tagname */
+	    for (p = p_7f - 1; !vim_iswordc(*p); --p)
+		if (p == lbuf)
+		    return FAIL;
+	    tagp->tagname_end = p + 1;
+	    while (p >= lbuf && vim_iswordc(*p))
+		--p;
+	    tagp->tagname = p + 1;
+	}
+    }
+    else	/* not an Emacs tag */
+    {
+#endif
+	/* Isolate the tagname, from lbuf up to the first white */
+	tagp->tagname = lbuf;
+#ifdef FEAT_TAG_ANYWHITE
+	p = skiptowhite(lbuf);
+#else
+	p = vim_strchr(lbuf, TAB);
+	if (p == NULL)
+	    return FAIL;
+#endif
+	tagp->tagname_end = p;
+
+	/* Isolate file name, from first to second white space */
+#ifdef FEAT_TAG_ANYWHITE
+	p = skipwhite(p);
+#else
+	if (*p != NUL)
+	    ++p;
+#endif
+	tagp->fname = p;
+#ifdef FEAT_TAG_ANYWHITE
+	p = skiptowhite(p);
+#else
+	p = vim_strchr(p, TAB);
+	if (p == NULL)
+	    return FAIL;
+#endif
+	tagp->fname_end = p;
+
+	/* find start of search command, after second white space */
+#ifdef FEAT_TAG_ANYWHITE
+	p = skipwhite(p);
+#else
+	if (*p != NUL)
+	    ++p;
+#endif
+	if (*p == NUL)
+	    return FAIL;
+	tagp->command = p;
+#ifdef FEAT_EMACS_TAGS
+    }
+#endif
+
+    return OK;
+}
+
+/*
+ * Check if tagname is a static tag
+ *
+ * Static tags produced by the older ctags program have the format:
+ *	'file:tag  file  /pattern'.
+ * This is only recognized when both occurrence of 'file' are the same, to
+ * avoid recognizing "string::string" or ":exit".
+ *
+ * Static tags produced by the new ctags program have the format:
+ *	'tag  file  /pattern/;"<Tab>file:'	    "
+ *
+ * Return TRUE if it is a static tag and adjust *tagname to the real tag.
+ * Return FALSE if it is not a static tag.
+ */
+    static int
+test_for_static(tagp)
+    tagptrs_T	*tagp;
+{
+    char_u	*p;
+
+#ifdef FEAT_TAG_OLDSTATIC
+    int		len;
+
+    /*
+     * Check for old style static tag: "file:tag file .."
+     */
+    len = (int)(tagp->fname_end - tagp->fname);
+    p = tagp->tagname + len;
+    if (       p < tagp->tagname_end
+	    && *p == ':'
+	    && fnamencmp(tagp->tagname, tagp->fname, len) == 0)
+    {
+	tagp->tagname = p + 1;
+	return TRUE;
+    }
+#endif
+
+    /*
+     * Check for new style static tag ":...<Tab>file:[<Tab>...]"
+     */
+    p = tagp->command;
+    while ((p = vim_strchr(p, '\t')) != NULL)
+    {
+	++p;
+	if (STRNCMP(p, "file:", 5) == 0)
+	    return TRUE;
+    }
+
+    return FALSE;
+}
+
+/*
+ * Parse a line from a matching tag.  Does not change the line itself.
+ *
+ * The line that we get looks like this:
+ * Emacs tag: <mtt><tag_fname><NUL><ebuf><NUL><lbuf>
+ * other tag: <mtt><tag_fname><NUL><NUL><lbuf>
+ * without Emacs tags: <mtt><tag_fname><NUL><lbuf>
+ *
+ * Return OK or FAIL.
+ */
+    static int
+parse_match(lbuf, tagp)
+    char_u	*lbuf;	    /* input: matching line */
+    tagptrs_T	*tagp;	    /* output: pointers into the line */
+{
+    int		retval;
+    char_u	*p;
+    char_u	*pc, *pt;
+
+    tagp->tag_fname = lbuf + 1;
+    lbuf += STRLEN(tagp->tag_fname) + 2;
+#ifdef FEAT_EMACS_TAGS
+    if (*lbuf)
+    {
+	tagp->is_etag = TRUE;
+	tagp->fname = lbuf;
+	lbuf += STRLEN(lbuf);
+	tagp->fname_end = lbuf++;
+    }
+    else
+    {
+	tagp->is_etag = FALSE;
+	++lbuf;
+    }
+#endif
+
+    /* Find search pattern and the file name for non-etags. */
+    retval = parse_tag_line(lbuf,
+#ifdef FEAT_EMACS_TAGS
+			tagp->is_etag,
+#endif
+			tagp);
+
+    tagp->tagkind = NULL;
+    tagp->command_end = NULL;
+
+    if (retval == OK)
+    {
+	/* Try to find a kind field: "kind:<kind>" or just "<kind>"*/
+	p = tagp->command;
+	if (find_extra(&p) == OK)
+	{
+	    tagp->command_end = p;
+	    p += 2;	/* skip ";\"" */
+	    if (*p++ == TAB)
+		while (ASCII_ISALPHA(*p))
+		{
+		    if (STRNCMP(p, "kind:", 5) == 0)
+		    {
+			tagp->tagkind = p + 5;
+			break;
+		    }
+		    pc = vim_strchr(p, ':');
+		    pt = vim_strchr(p, '\t');
+		    if (pc == NULL || (pt != NULL && pc > pt))
+		    {
+			tagp->tagkind = p;
+			break;
+		    }
+		    if (pt == NULL)
+			break;
+		    p = pt + 1;
+		}
+	}
+	if (tagp->tagkind != NULL)
+	{
+	    for (p = tagp->tagkind;
+			    *p && *p != '\t' && *p != '\r' && *p != '\n'; ++p)
+		;
+	    tagp->tagkind_end = p;
+	}
+    }
+    return retval;
+}
+
+/*
+ * Find out the actual file name of a tag.  Concatenate the tags file name
+ * with the matching tag file name.
+ * Returns an allocated string or NULL (out of memory).
+ */
+    static char_u *
+tag_full_fname(tagp)
+    tagptrs_T	*tagp;
+{
+    char_u	*fullname;
+    int		c;
+
+#ifdef FEAT_EMACS_TAGS
+    if (tagp->is_etag)
+	c = 0;	    /* to shut up GCC */
+    else
+#endif
+    {
+	c = *tagp->fname_end;
+	*tagp->fname_end = NUL;
+    }
+    fullname = expand_tag_fname(tagp->fname, tagp->tag_fname, FALSE);
+
+#ifdef FEAT_EMACS_TAGS
+    if (!tagp->is_etag)
+#endif
+	*tagp->fname_end = c;
+
+    return fullname;
+}
+
+/*
+ * Jump to a tag that has been found in one of the tag files
+ *
+ * returns OK for success, NOTAGFILE when file not found, FAIL otherwise.
+ */
+    static int
+jumpto_tag(lbuf, forceit, keep_help)
+    char_u	*lbuf;		/* line from the tags file for this tag */
+    int		forceit;	/* :ta with ! */
+    int		keep_help;	/* keep help flag (FALSE for cscope) */
+{
+    int		save_secure;
+    int		save_magic;
+    int		save_p_ws, save_p_scs, save_p_ic;
+    linenr_T	save_lnum;
+    int		csave = 0;
+    char_u	*str;
+    char_u	*pbuf;			/* search pattern buffer */
+    char_u	*pbuf_end;
+    char_u	*tofree_fname = NULL;
+    char_u	*fname;
+    tagptrs_T	tagp;
+    int		retval = FAIL;
+    int		getfile_result;
+    int		search_options;
+#ifdef FEAT_SEARCH_EXTRA
+    int		save_no_hlsearch;
+#endif
+#if defined(FEAT_WINDOWS) && defined(FEAT_QUICKFIX)
+    win_T	*curwin_save = NULL;
+#endif
+    char_u	*full_fname = NULL;
+#ifdef FEAT_FOLDING
+    int		old_KeyTyped = KeyTyped;    /* getting the file may reset it */
+#endif
+
+    pbuf = alloc(LSIZE);
+
+    /* parse the match line into the tagp structure */
+    if (pbuf == NULL || parse_match(lbuf, &tagp) == FAIL)
+    {
+	tagp.fname_end = NULL;
+	goto erret;
+    }
+
+    /* truncate the file name, so it can be used as a string */
+    csave = *tagp.fname_end;
+    *tagp.fname_end = NUL;
+    fname = tagp.fname;
+
+    /* copy the command to pbuf[], remove trailing CR/NL */
+    str = tagp.command;
+    for (pbuf_end = pbuf; *str && *str != '\n' && *str != '\r'; )
+    {
+#ifdef FEAT_EMACS_TAGS
+	if (tagp.is_etag && *str == ',')/* stop at ',' after line number */
+	    break;
+#endif
+	*pbuf_end++ = *str++;
+    }
+    *pbuf_end = NUL;
+
+#ifdef FEAT_EMACS_TAGS
+    if (!tagp.is_etag)
+#endif
+    {
+	/*
+	 * Remove the "<Tab>fieldname:value" stuff; we don't need it here.
+	 */
+	str = pbuf;
+	if (find_extra(&str) == OK)
+	{
+	    pbuf_end = str;
+	    *pbuf_end = NUL;
+	}
+    }
+
+    /*
+     * Expand file name, when needed (for environment variables).
+     * If 'tagrelative' option set, may change file name.
+     */
+    fname = expand_tag_fname(fname, tagp.tag_fname, TRUE);
+    if (fname == NULL)
+	goto erret;
+    tofree_fname = fname;	/* free() it later */
+
+    /*
+     * Check if the file with the tag exists before abandoning the current
+     * file.  Also accept a file name for which there is a matching BufReadCmd
+     * autocommand event (e.g., http://sys/file).
+     */
+    if (mch_getperm(fname) < 0
+#ifdef FEAT_AUTOCMD
+	    && !has_autocmd(EVENT_BUFREADCMD, fname, NULL)
+#endif
+       )
+    {
+	retval = NOTAGFILE;
+	vim_free(nofile_fname);
+	nofile_fname = vim_strsave(fname);
+	if (nofile_fname == NULL)
+	    nofile_fname = empty_option;
+	goto erret;
+    }
+
+    ++RedrawingDisabled;
+
+#ifdef FEAT_GUI
+    need_mouse_correct = TRUE;
+#endif
+
+#if defined(FEAT_WINDOWS) && defined(FEAT_QUICKFIX)
+    if (g_do_tagpreview)
+    {
+	postponed_split = 0;	/* don't split again below */
+	curwin_save = curwin;	/* Save current window */
+
+	/*
+	 * If we are reusing a window, we may change dir when
+	 * entering it (autocommands) so turn the tag filename
+	 * into a fullpath
+	 */
+	if (!curwin->w_p_pvw)
+	{
+	    full_fname = FullName_save(fname, FALSE);
+	    fname = full_fname;
+
+	    /*
+	     * Make the preview window the current window.
+	     * Open a preview window when needed.
+	     */
+	    prepare_tagpreview(TRUE);
+	}
+    }
+
+    /* If it was a CTRL-W CTRL-] command split window now.  For ":tab tag"
+     * open a new tab page. */
+    if (postponed_split || cmdmod.tab != 0)
+    {
+	win_split(postponed_split > 0 ? postponed_split : 0,
+						       postponed_split_flags);
+# ifdef FEAT_SCROLLBIND
+	curwin->w_p_scb = FALSE;
+# endif
+    }
+#endif
+
+    if (keep_help)
+    {
+	/* A :ta from a help file will keep the b_help flag set.  For ":ptag"
+	 * we need to use the flag from the window where we came from. */
+#if defined(FEAT_WINDOWS) && defined(FEAT_QUICKFIX)
+	if (g_do_tagpreview)
+	    keep_help_flag = curwin_save->w_buffer->b_help;
+	else
+#endif
+	    keep_help_flag = curbuf->b_help;
+    }
+    getfile_result = getfile(0, fname, NULL, TRUE, (linenr_T)0, forceit);
+    keep_help_flag = FALSE;
+
+    if (getfile_result <= 0)		/* got to the right file */
+    {
+	curwin->w_set_curswant = TRUE;
+#ifdef FEAT_WINDOWS
+	postponed_split = 0;
+#endif
+
+	save_secure = secure;
+	secure = 1;
+#ifdef HAVE_SANDBOX
+	++sandbox;
+#endif
+	save_magic = p_magic;
+	p_magic = FALSE;	/* always execute with 'nomagic' */
+#ifdef FEAT_SEARCH_EXTRA
+	/* Save value of no_hlsearch, jumping to a tag is not a real search */
+	save_no_hlsearch = no_hlsearch;
+#endif
+
+	/*
+	 * If 'cpoptions' contains 't', store the search pattern for the "n"
+	 * command.  If 'cpoptions' does not contain 't', the search pattern
+	 * is not stored.
+	 */
+	if (vim_strchr(p_cpo, CPO_TAGPAT) != NULL)
+	    search_options = 0;
+	else
+	    search_options = SEARCH_KEEP;
+
+	/*
+	 * If the command is a search, try here.
+	 *
+	 * Reset 'smartcase' for the search, since the search pattern was not
+	 * typed by the user.
+	 * Only use do_search() when there is a full search command, without
+	 * anything following.
+	 */
+	str = pbuf;
+	if (pbuf[0] == '/' || pbuf[0] == '?')
+	    str = skip_regexp(pbuf + 1, pbuf[0], FALSE, NULL) + 1;
+	if (str > pbuf_end - 1)	/* search command with nothing following */
+	{
+	    save_p_ws = p_ws;
+	    save_p_ic = p_ic;
+	    save_p_scs = p_scs;
+	    p_ws = TRUE;	/* need 'wrapscan' for backward searches */
+	    p_ic = FALSE;	/* don't ignore case now */
+	    p_scs = FALSE;
+#if 0	/* disabled for now */
+#ifdef FEAT_CMDHIST
+	    /* put pattern in search history */
+	    add_to_history(HIST_SEARCH, pbuf + 1, TRUE, pbuf[0]);
+#endif
+#endif
+	    save_lnum = curwin->w_cursor.lnum;
+	    curwin->w_cursor.lnum = 0;	/* start search before first line */
+	    if (do_search(NULL, pbuf[0], pbuf + 1, (long)1, search_options))
+		retval = OK;
+	    else
+	    {
+		int	found = 1;
+		int	cc;
+
+		/*
+		 * try again, ignore case now
+		 */
+		p_ic = TRUE;
+		if (!do_search(NULL, pbuf[0], pbuf + 1, (long)1,
+							      search_options))
+		{
+		    /*
+		     * Failed to find pattern, take a guess: "^func  ("
+		     */
+		    found = 2;
+		    (void)test_for_static(&tagp);
+		    cc = *tagp.tagname_end;
+		    *tagp.tagname_end = NUL;
+		    sprintf((char *)pbuf, "^%s\\s\\*(", tagp.tagname);
+		    if (!do_search(NULL, '/', pbuf, (long)1, search_options))
+		    {
+			/* Guess again: "^char * \<func  (" */
+			sprintf((char *)pbuf, "^\\[#a-zA-Z_]\\.\\*\\<%s\\s\\*(",
+								tagp.tagname);
+			if (!do_search(NULL, '/', pbuf, (long)1,
+							      search_options))
+			    found = 0;
+		    }
+		    *tagp.tagname_end = cc;
+		}
+		if (found == 0)
+		{
+		    EMSG(_("E434: Can't find tag pattern"));
+		    curwin->w_cursor.lnum = save_lnum;
+		}
+		else
+		{
+		    /*
+		     * Only give a message when really guessed, not when 'ic'
+		     * is set and match found while ignoring case.
+		     */
+		    if (found == 2 || !save_p_ic)
+		    {
+			MSG(_("E435: Couldn't find tag, just guessing!"));
+			if (!msg_scrolled && msg_silent == 0)
+			{
+			    out_flush();
+			    ui_delay(1000L, TRUE);
+			}
+		    }
+		    retval = OK;
+		}
+	    }
+	    p_ws = save_p_ws;
+	    p_ic = save_p_ic;
+	    p_scs = save_p_scs;
+
+	    /* A search command may have positioned the cursor beyond the end
+	     * of the line.  May need to correct that here. */
+	    check_cursor();
+	}
+	else
+	{
+	    curwin->w_cursor.lnum = 1;		/* start command in line 1 */
+	    do_cmdline_cmd(pbuf);
+	    retval = OK;
+	}
+
+	/*
+	 * When the command has done something that is not allowed make sure
+	 * the error message can be seen.
+	 */
+	if (secure == 2)
+	    wait_return(TRUE);
+	secure = save_secure;
+	p_magic = save_magic;
+#ifdef HAVE_SANDBOX
+	--sandbox;
+#endif
+#ifdef FEAT_SEARCH_EXTRA
+	/* restore no_hlsearch when keeping the old search pattern */
+	if (search_options)
+	    no_hlsearch = save_no_hlsearch;
+#endif
+
+	/* Return OK if jumped to another file (at least we found the file!). */
+	if (getfile_result == -1)
+	    retval = OK;
+
+	if (retval == OK)
+	{
+	    /*
+	     * For a help buffer: Put the cursor line at the top of the window,
+	     * the help subject will be below it.
+	     */
+	    if (curbuf->b_help)
+		set_topline(curwin, curwin->w_cursor.lnum);
+#ifdef FEAT_FOLDING
+	    if ((fdo_flags & FDO_TAG) && old_KeyTyped)
+		foldOpenCursor();
+#endif
+	}
+
+#if defined(FEAT_WINDOWS) && defined(FEAT_QUICKFIX)
+	if (g_do_tagpreview && curwin != curwin_save && win_valid(curwin_save))
+	{
+	    /* Return cursor to where we were */
+	    validate_cursor();
+	    redraw_later(VALID);
+	    win_enter(curwin_save, TRUE);
+	}
+#endif
+
+	--RedrawingDisabled;
+    }
+    else
+    {
+	--RedrawingDisabled;
+#ifdef FEAT_WINDOWS
+	if (postponed_split)		/* close the window */
+	{
+	    win_close(curwin, FALSE);
+	    postponed_split = 0;
+	}
+#endif
+    }
+
+erret:
+#if defined(FEAT_WINDOWS) && defined(FEAT_QUICKFIX)
+    g_do_tagpreview = 0; /* For next time */
+#endif
+    if (tagp.fname_end != NULL)
+	*tagp.fname_end = csave;
+    vim_free(pbuf);
+    vim_free(tofree_fname);
+    vim_free(full_fname);
+
+    return retval;
+}
+
+/*
+ * If "expand" is TRUE, expand wildcards in fname.
+ * If 'tagrelative' option set, change fname (name of file containing tag)
+ * according to tag_fname (name of tag file containing fname).
+ * Returns a pointer to allocated memory (or NULL when out of memory).
+ */
+    static char_u *
+expand_tag_fname(fname, tag_fname, expand)
+    char_u	*fname;
+    char_u	*tag_fname;
+    int		expand;
+{
+    char_u	*p;
+    char_u	*retval;
+    char_u	*expanded_fname = NULL;
+    expand_T	xpc;
+
+    /*
+     * Expand file name (for environment variables) when needed.
+     */
+    if (expand && mch_has_wildcard(fname))
+    {
+	ExpandInit(&xpc);
+	xpc.xp_context = EXPAND_FILES;
+	expanded_fname = ExpandOne(&xpc, (char_u *)fname, NULL,
+			    WILD_LIST_NOTFOUND|WILD_SILENT, WILD_EXPAND_FREE);
+	if (expanded_fname != NULL)
+	    fname = expanded_fname;
+    }
+
+    if ((p_tr || curbuf->b_help)
+	    && !vim_isAbsName(fname)
+	    && (p = gettail(tag_fname)) != tag_fname)
+    {
+	retval = alloc(MAXPATHL);
+	if (retval != NULL)
+	{
+	    STRCPY(retval, tag_fname);
+	    vim_strncpy(retval + (p - tag_fname), fname,
+					      MAXPATHL - (p - tag_fname) - 1);
+	    /*
+	     * Translate names like "src/a/../b/file.c" into "src/b/file.c".
+	     */
+	    simplify_filename(retval);
+	}
+    }
+    else
+	retval = vim_strsave(fname);
+
+    vim_free(expanded_fname);
+
+    return retval;
+}
+
+/*
+ * Moves the tail part of the path (including the terminating NUL) pointed to
+ * by "tail" to the new location pointed to by "here". This should accomodate
+ * an overlapping move.
+ */
+#define movetail(here, tail)  mch_memmove(here, tail, STRLEN(tail) + (size_t)1)
+
+/*
+ * Converts a file name into a canonical form. It simplifies a file name into
+ * its simplest form by stripping out unneeded components, if any.  The
+ * resulting file name is simplified in place and will either be the same
+ * length as that supplied, or shorter.
+ */
+    void
+simplify_filename(filename)
+    char_u	*filename;
+{
+#ifndef AMIGA	    /* Amiga doesn't have "..", it uses "/" */
+    int		components = 0;
+    char_u	*p, *tail, *start;
+    int		stripping_disabled = FALSE;
+    int		relative = TRUE;
+
+    p = filename;
+#ifdef BACKSLASH_IN_FILENAME
+    if (p[1] == ':')	    /* skip "x:" */
+	p += 2;
+#endif
+
+    if (vim_ispathsep(*p))
+    {
+	relative = FALSE;
+	do
+	    ++p;
+	while (vim_ispathsep(*p));
+    }
+    start = p;	    /* remember start after "c:/" or "/" or "///" */
+
+    do
+    {
+	/* At this point "p" is pointing to the char following a single "/"
+	 * or "p" is at the "start" of the (absolute or relative) path name. */
+#ifdef VMS
+	/* VMS allows device:[path] - don't strip the [ in directory  */
+	if ((*p == '[' || *p == '<') && p > filename && p[-1] == ':')
+	{
+	    /* :[ or :< composition: vms directory component */
+	    ++components;
+	    p = getnextcomp(p + 1);
+	}
+	/* allow remote calls as host"user passwd"::device:[path] */
+	else if (p[0] == ':' && p[1] == ':' && p > filename && p[-1] == '"' )
+	{
+	    /* ":: composition: vms host/passwd component */
+	    ++components;
+	    p = getnextcomp(p + 2);
+	}
+	else
+#endif
+	  if (vim_ispathsep(*p))
+	    movetail(p, p + 1);		/* remove duplicate "/" */
+	else if (p[0] == '.' && (vim_ispathsep(p[1]) || p[1] == NUL))
+	{
+	    if (p == start && relative)
+		p += 1 + (p[1] != NUL);	/* keep single "." or leading "./" */
+	    else
+	    {
+		/* Strip "./" or ".///".  If we are at the end of the file name
+		 * and there is no trailing path separator, either strip "/." if
+		 * we are after "start", or strip "." if we are at the beginning
+		 * of an absolute path name . */
+		tail = p + 1;
+		if (p[1] != NUL)
+		    while (vim_ispathsep(*tail))
+			mb_ptr_adv(tail);
+		else if (p > start)
+		    --p;		/* strip preceding path separator */
+		movetail(p, tail);
+	    }
+	}
+	else if (p[0] == '.' && p[1] == '.' &&
+	    (vim_ispathsep(p[2]) || p[2] == NUL))
+	{
+	    /* Skip to after ".." or "../" or "..///". */
+	    tail = p + 2;
+	    while (vim_ispathsep(*tail))
+		mb_ptr_adv(tail);
+
+	    if (components > 0)		/* strip one preceding component */
+	    {
+		int		do_strip = FALSE;
+		char_u		saved_char;
+		struct stat	st;
+
+		/* Don't strip for an erroneous file name. */
+		if (!stripping_disabled)
+		{
+		    /* If the preceding component does not exist in the file
+		     * system, we strip it.  On Unix, we don't accept a symbolic
+		     * link that refers to a non-existent file. */
+		    saved_char = p[-1];
+		    p[-1] = NUL;
+#ifdef UNIX
+		    if (mch_lstat((char *)filename, &st) < 0)
+#else
+			if (mch_stat((char *)filename, &st) < 0)
+#endif
+			    do_strip = TRUE;
+		    p[-1] = saved_char;
+
+		    --p;
+		    /* Skip back to after previous '/'. */
+		    while (p > start && !after_pathsep(start, p))
+			mb_ptr_back(start, p);
+
+		    if (!do_strip)
+		    {
+			/* If the component exists in the file system, check
+			 * that stripping it won't change the meaning of the
+			 * file name.  First get information about the
+			 * unstripped file name.  This may fail if the component
+			 * to strip is not a searchable directory (but a regular
+			 * file, for instance), since the trailing "/.." cannot
+			 * be applied then.  We don't strip it then since we
+			 * don't want to replace an erroneous file name by
+			 * a valid one, and we disable stripping of later
+			 * components. */
+			saved_char = *tail;
+			*tail = NUL;
+			if (mch_stat((char *)filename, &st) >= 0)
+			    do_strip = TRUE;
+			else
+			    stripping_disabled = TRUE;
+			*tail = saved_char;
+#ifdef UNIX
+			if (do_strip)
+			{
+			    struct stat	new_st;
+
+			    /* On Unix, the check for the unstripped file name
+			     * above works also for a symbolic link pointing to
+			     * a searchable directory.  But then the parent of
+			     * the directory pointed to by the link must be the
+			     * same as the stripped file name.  (The latter
+			     * exists in the file system since it is the
+			     * component's parent directory.) */
+			    if (p == start && relative)
+				(void)mch_stat(".", &new_st);
+			    else
+			    {
+				saved_char = *p;
+				*p = NUL;
+				(void)mch_stat((char *)filename, &new_st);
+				*p = saved_char;
+			    }
+
+			    if (new_st.st_ino != st.st_ino ||
+				new_st.st_dev != st.st_dev)
+			    {
+				do_strip = FALSE;
+				/* We don't disable stripping of later
+				 * components since the unstripped path name is
+				 * still valid. */
+			    }
+			}
+#endif
+		    }
+		}
+
+		if (!do_strip)
+		{
+		    /* Skip the ".." or "../" and reset the counter for the
+		     * components that might be stripped later on. */
+		    p = tail;
+		    components = 0;
+		}
+		else
+		{
+		    /* Strip previous component.  If the result would get empty
+		     * and there is no trailing path separator, leave a single
+		     * "." instead.  If we are at the end of the file name and
+		     * there is no trailing path separator and a preceding
+		     * component is left after stripping, strip its trailing
+		     * path separator as well. */
+		    if (p == start && relative && tail[-1] == '.')
+		    {
+			*p++ = '.';
+			*p = NUL;
+		    }
+		    else
+		    {
+			if (p > start && tail[-1] == '.')
+			    --p;
+			movetail(p, tail);	/* strip previous component */
+		    }
+
+		    --components;
+		}
+	    }
+	    else if (p == start && !relative)	/* leading "/.." or "/../" */
+		movetail(p, tail);		/* strip ".." or "../" */
+	    else
+	    {
+		if (p == start + 2 && p[-2] == '.')	/* leading "./../" */
+		{
+		    movetail(p - 2, p);			/* strip leading "./" */
+		    tail -= 2;
+		}
+		p = tail;		/* skip to char after ".." or "../" */
+	    }
+	}
+	else
+	{
+	    ++components;		/* simple path component */
+	    p = getnextcomp(p);
+	}
+    } while (*p != NUL);
+#endif /* !AMIGA */
+}
+
+/*
+ * Check if we have a tag for the buffer with name "buf_ffname".
+ * This is a bit slow, because of the full path compare in fullpathcmp().
+ * Return TRUE if tag for file "fname" if tag file "tag_fname" is for current
+ * file.
+ */
+    static int
+#ifdef FEAT_EMACS_TAGS
+test_for_current(is_etag, fname, fname_end, tag_fname, buf_ffname)
+    int	    is_etag;
+#else
+test_for_current(fname, fname_end, tag_fname, buf_ffname)
+#endif
+    char_u  *fname;
+    char_u  *fname_end;
+    char_u  *tag_fname;
+    char_u  *buf_ffname;
+{
+    int	    c;
+    int	    retval = FALSE;
+    char_u  *fullname;
+
+    if (buf_ffname != NULL)	/* if the buffer has a name */
+    {
+#ifdef FEAT_EMACS_TAGS
+	if (is_etag)
+	    c = 0;	    /* to shut up GCC */
+	else
+#endif
+	{
+	    c = *fname_end;
+	    *fname_end = NUL;
+	}
+	fullname = expand_tag_fname(fname, tag_fname, TRUE);
+	if (fullname != NULL)
+	{
+	    retval = (fullpathcmp(fullname, buf_ffname, TRUE) & FPC_SAME);
+	    vim_free(fullname);
+	}
+#ifdef FEAT_EMACS_TAGS
+	if (!is_etag)
+#endif
+	    *fname_end = c;
+    }
+
+    return retval;
+}
+
+/*
+ * Find the end of the tagaddress.
+ * Return OK if ";\"" is following, FAIL otherwise.
+ */
+    static int
+find_extra(pp)
+    char_u	**pp;
+{
+    char_u	*str = *pp;
+
+    /* Repeat for addresses separated with ';' */
+    for (;;)
+    {
+	if (VIM_ISDIGIT(*str))
+	    str = skipdigits(str);
+	else if (*str == '/' || *str == '?')
+	{
+	    str = skip_regexp(str + 1, *str, FALSE, NULL);
+	    if (*str != **pp)
+		str = NULL;
+	    else
+		++str;
+	}
+	else
+	    str = NULL;
+	if (str == NULL || *str != ';'
+		  || !(VIM_ISDIGIT(str[1]) || str[1] == '/' || str[1] == '?'))
+	    break;
+	++str;	/* skip ';' */
+    }
+
+    if (str != NULL && STRNCMP(str, ";\"", 2) == 0)
+    {
+	*pp = str;
+	return OK;
+    }
+    return FAIL;
+}
+
+#if defined(FEAT_CMDL_COMPL) || defined(PROTO)
+    int
+expand_tags(tagnames, pat, num_file, file)
+    int		tagnames;	/* expand tag names */
+    char_u	*pat;
+    int		*num_file;
+    char_u	***file;
+{
+    int		i;
+    int		c;
+    int		tagnmflag;
+    char_u      tagnm[100];
+    tagptrs_T	t_p;
+    int		ret;
+
+    if (tagnames)
+	tagnmflag = TAG_NAMES;
+    else
+	tagnmflag = 0;
+    if (pat[0] == '/')
+	ret = find_tags(pat + 1, num_file, file,
+		TAG_REGEXP | tagnmflag | TAG_VERBOSE,
+		TAG_MANY, curbuf->b_ffname);
+    else
+	ret = find_tags(pat, num_file, file,
+		TAG_REGEXP | tagnmflag | TAG_VERBOSE | TAG_NOIC,
+		TAG_MANY, curbuf->b_ffname);
+    if (ret == OK && !tagnames)
+    {
+	 /* Reorganize the tags for display and matching as strings of:
+	  * "<tagname>\0<kind>\0<filename>\0"
+	  */
+	 for (i = 0; i < *num_file; i++)
+	 {
+	     parse_match((*file)[i], &t_p);
+	     c = (int)(t_p.tagname_end - t_p.tagname);
+	     mch_memmove(tagnm, t_p.tagname, (size_t)c);
+	     tagnm[c++] = 0;
+	     tagnm[c++] = (t_p.tagkind != NULL && *t_p.tagkind)
+							 ? *t_p.tagkind : 'f';
+	     tagnm[c++] = 0;
+	     mch_memmove((*file)[i] + c, t_p.fname, t_p.fname_end - t_p.fname);
+	     (*file)[i][c + (t_p.fname_end - t_p.fname)] = 0;
+	     mch_memmove((*file)[i], tagnm, (size_t)c);
+	}
+    }
+    return ret;
+}
+#endif
+
+#if defined(FEAT_EVAL) || defined(PROTO)
+static int add_tag_field __ARGS((dict_T *dict, char *field_name, char_u *start, char_u *end));
+
+/*
+ * Add a tag field to the dictionary "dict"
+ */
+    static int
+add_tag_field(dict, field_name, start, end)
+    dict_T  *dict;
+    char    *field_name;
+    char_u  *start;		/* start of the value */
+    char_u  *end;		/* after the value; can be NULL */
+{
+    char_u	buf[MAXPATHL];
+    int		len = 0;
+
+    if (start != NULL)
+    {
+	if (end == NULL)
+	{
+	    end = start + STRLEN(start);
+	    while (end > start && (end[-1] == '\r' || end[-1] == '\n'))
+		--end;
+	}
+	len = (int)(end - start);
+	if (len > sizeof(buf) - 1)
+	    len = sizeof(buf) - 1;
+	vim_strncpy(buf, start, len);
+    }
+    buf[len] = NUL;
+    return dict_add_nr_str(dict, field_name, 0L, buf);
+}
+
+/*
+ * Add the tags matching the specified pattern to the list "list"
+ * as a dictionary
+ */
+    int
+get_tags(list, pat)
+    list_T *list;
+    char_u *pat;
+{
+    int		num_matches, i, ret;
+    char_u	**matches, *p;
+    char_u	*full_fname;
+    dict_T	*dict;
+    tagptrs_T	tp;
+    long	is_static;
+
+    ret = find_tags(pat, &num_matches, &matches,
+				    TAG_REGEXP | TAG_NOIC, (int)MAXCOL, NULL);
+    if (ret == OK && num_matches > 0)
+    {
+	for (i = 0; i < num_matches; ++i)
+	{
+	    parse_match(matches[i], &tp);
+	    is_static = test_for_static(&tp);
+
+	    /* Skip pseudo-tag lines. */
+	    if (STRNCMP(tp.tagname, "!_TAG_", 6) == 0)
+		continue;
+
+	    if ((dict = dict_alloc()) == NULL)
+		ret = FAIL;
+	    if (list_append_dict(list, dict) == FAIL)
+		ret = FAIL;
+
+	    full_fname = tag_full_fname(&tp);
+	    if (add_tag_field(dict, "name", tp.tagname, tp.tagname_end) == FAIL
+		    || add_tag_field(dict, "filename", full_fname,
+							 NULL) == FAIL
+		    || add_tag_field(dict, "cmd", tp.command,
+						       tp.command_end) == FAIL
+		    || add_tag_field(dict, "kind", tp.tagkind,
+						      tp.tagkind_end) == FAIL
+		    || dict_add_nr_str(dict, "static", is_static, NULL) == FAIL)
+		ret = FAIL;
+
+	    vim_free(full_fname);
+
+	    if (tp.command_end != NULL)
+	    {
+		for (p = tp.command_end + 3;
+				   *p != NUL && *p != '\n' && *p != '\r'; ++p)
+		{
+		    if (p == tp.tagkind || (p + 5 == tp.tagkind
+					      && STRNCMP(p, "kind:", 5) == 0))
+			/* skip "kind:<kind>" and "<kind>" */
+			p = tp.tagkind_end - 1;
+		    else if (STRNCMP(p, "file:", 5) == 0)
+			/* skip "file:" (static tag) */
+			p += 4;
+		    else if (!vim_iswhite(*p))
+		    {
+			char_u	*s, *n;
+			int	len;
+
+			/* Add extra field as a dict entry.  Fields are
+			 * separated by Tabs. */
+			n = p;
+			while (*p != NUL && *p >= ' ' && *p < 127 && *p != ':')
+			    ++p;
+			len = (int)(p - n);
+			if (*p == ':' && len > 0)
+			{
+			    s = ++p;
+			    while (*p != NUL && *p >= ' ')
+				++p;
+			    n[len] = NUL;
+			    if (add_tag_field(dict, (char *)n, s, p) == FAIL)
+				ret = FAIL;
+			    n[len] = ':';
+			}
+			else
+			    /* Skip field without colon. */
+			    while (*p != NUL && *p >= ' ')
+				++p;
+		    }
+		}
+	    }
+
+	    vim_free(matches[i]);
+	}
+	vim_free(matches);
+    }
+    return ret;
+}
+#endif
--- /dev/null
+++ b/term.c
@@ -1,0 +1,5691 @@
+/* vi:set ts=8 sts=4 sw=4:
+ *
+ * VIM - Vi IMproved	by Bram Moolenaar
+ *
+ * Do ":help uganda"  in Vim to read copying and usage conditions.
+ * Do ":help credits" in Vim to see a list of people who contributed.
+ * See README.txt for an overview of the Vim source code.
+ */
+/*
+ *
+ * term.c: functions for controlling the terminal
+ *
+ * primitive termcap support for Amiga, MSDOS, and Win32 included
+ *
+ * NOTE: padding and variable substitution is not performed,
+ * when compiling without HAVE_TGETENT, we use tputs() and tgoto() dummies.
+ */
+
+/*
+ * Some systems have a prototype for tgetstr() with (char *) instead of
+ * (char **). This define removes that prototype. We include our own prototype
+ * below.
+ */
+
+#define tgetstr tgetstr_defined_wrong
+#include "vim.h"
+
+#ifdef HAVE_TGETENT
+# ifdef HAVE_TERMIOS_H
+#  include <termios.h>	    /* seems to be required for some Linux */
+# endif
+# ifdef HAVE_TERMCAP_H
+#  include <termcap.h>
+# endif
+
+/*
+ * A few linux systems define outfuntype in termcap.h to be used as the third
+ * argument for tputs().
+ */
+# ifdef VMS
+#  define TPUTSFUNCAST
+# else
+#  ifdef HAVE_OUTFUNTYPE
+#   define TPUTSFUNCAST (outfuntype)
+#  else
+#   define TPUTSFUNCAST (int (*)())
+#  endif
+# endif
+#endif
+
+#undef tgetstr
+
+/*
+ * Here are the builtin termcap entries.  They are not stored as complete
+ * Tcarr structures, as such a structure is too big.
+ *
+ * The entries are compact, therefore they normally are included even when
+ * HAVE_TGETENT is defined. When HAVE_TGETENT is defined, the builtin entries
+ * can be accessed with "builtin_amiga", "builtin_ansi", "builtin_debug", etc.
+ *
+ * Each termcap is a list of builtin_term structures. It always starts with
+ * KS_NAME, which separates the entries.  See parse_builtin_tcap() for all
+ * details.
+ * bt_entry is either a KS_xxx code (>= 0), or a K_xxx code.
+ *
+ * Entries marked with "guessed" may be wrong.
+ */
+struct builtin_term
+{
+    int		bt_entry;
+    char	*bt_string;
+};
+
+/* start of keys that are not directly used by Vim but can be mapped */
+#define BT_EXTRA_KEYS	0x101
+
+static struct builtin_term *find_builtin_term __ARGS((char_u *name));
+static void parse_builtin_tcap __ARGS((char_u *s));
+static void term_color __ARGS((char_u *s, int n));
+static void gather_termleader __ARGS((void));
+#ifdef FEAT_TERMRESPONSE
+static void req_codes_from_term __ARGS((void));
+static void req_more_codes_from_term __ARGS((void));
+static void got_code_from_term __ARGS((char_u *code, int len));
+static void check_for_codes_from_term __ARGS((void));
+#endif
+#if defined(FEAT_GUI) \
+    || (defined(FEAT_MOUSE) && (!defined(UNIX) || defined(FEAT_MOUSE_XTERM)))
+static int get_bytes_from_buf __ARGS((char_u *, char_u *, int));
+#endif
+static void del_termcode_idx __ARGS((int idx));
+static int term_is_builtin __ARGS((char_u *name));
+static int term_7to8bit __ARGS((char_u *p));
+#ifdef FEAT_TERMRESPONSE
+static void switch_to_8bit __ARGS((void));
+#endif
+
+#ifdef HAVE_TGETENT
+static char_u *tgetent_error __ARGS((char_u *, char_u *));
+
+/*
+ * Here is our own prototype for tgetstr(), any prototypes from the include
+ * files have been disabled by the define at the start of this file.
+ */
+char		*tgetstr __ARGS((char *, char **));
+
+# ifdef FEAT_TERMRESPONSE
+/* Request Terminal Version status: */
+#  define CRV_GET	1	/* send T_CRV when switched to RAW mode */
+#  define CRV_SENT	2	/* did send T_CRV, waiting for answer */
+#  define CRV_GOT	3	/* received T_CRV response */
+static int crv_status = CRV_GET;
+# endif
+
+/*
+ * Don't declare these variables if termcap.h contains them.
+ * Autoconf checks if these variables should be declared extern (not all
+ * systems have them).
+ * Some versions define ospeed to be speed_t, but that is incompatible with
+ * BSD, where ospeed is short and speed_t is long.
+ */
+# ifndef HAVE_OSPEED
+#  ifdef OSPEED_EXTERN
+extern short ospeed;
+#   else
+short ospeed;
+#   endif
+# endif
+# ifndef HAVE_UP_BC_PC
+#  ifdef UP_BC_PC_EXTERN
+extern char *UP, *BC, PC;
+#  else
+char *UP, *BC, PC;
+#  endif
+# endif
+
+# define TGETSTR(s, p)	vim_tgetstr((s), (p))
+# define TGETENT(b, t)	tgetent((char *)(b), (char *)(t))
+static char_u *vim_tgetstr __ARGS((char *s, char_u **pp));
+#endif /* HAVE_TGETENT */
+
+static int  detected_8bit = FALSE;	/* detected 8-bit terminal */
+
+static struct builtin_term builtin_termcaps[] =
+{
+
+#if defined(FEAT_GUI)
+/*
+ * GUI pseudo term-cap.
+ */
+    {(int)KS_NAME,	"gui"},
+    {(int)KS_CE,	IF_EB("\033|$", ESC_STR "|$")},
+    {(int)KS_AL,	IF_EB("\033|i", ESC_STR "|i")},
+# ifdef TERMINFO
+    {(int)KS_CAL,	IF_EB("\033|%p1%dI", ESC_STR "|%p1%dI")},
+# else
+    {(int)KS_CAL,	IF_EB("\033|%dI", ESC_STR "|%dI")},
+# endif
+    {(int)KS_DL,	IF_EB("\033|d", ESC_STR "|d")},
+# ifdef TERMINFO
+    {(int)KS_CDL,	IF_EB("\033|%p1%dD", ESC_STR "|%p1%dD")},
+    {(int)KS_CS,	IF_EB("\033|%p1%d;%p2%dR", ESC_STR "|%p1%d;%p2%dR")},
+#  ifdef FEAT_VERTSPLIT
+    {(int)KS_CSV,	IF_EB("\033|%p1%d;%p2%dV", ESC_STR "|%p1%d;%p2%dV")},
+#  endif
+# else
+    {(int)KS_CDL,	IF_EB("\033|%dD", ESC_STR "|%dD")},
+    {(int)KS_CS,	IF_EB("\033|%d;%dR", ESC_STR "|%d;%dR")},
+#  ifdef FEAT_VERTSPLIT
+    {(int)KS_CSV,	IF_EB("\033|%d;%dV", ESC_STR "|%d;%dV")},
+#  endif
+# endif
+    {(int)KS_CL,	IF_EB("\033|C", ESC_STR "|C")},
+			/* attributes switched on with 'h', off with * 'H' */
+    {(int)KS_ME,	IF_EB("\033|31H", ESC_STR "|31H")}, /* HL_ALL */
+    {(int)KS_MR,	IF_EB("\033|1h", ESC_STR "|1h")},   /* HL_INVERSE */
+    {(int)KS_MD,	IF_EB("\033|2h", ESC_STR "|2h")},   /* HL_BOLD */
+    {(int)KS_SE,	IF_EB("\033|16H", ESC_STR "|16H")}, /* HL_STANDOUT */
+    {(int)KS_SO,	IF_EB("\033|16h", ESC_STR "|16h")}, /* HL_STANDOUT */
+    {(int)KS_UE,	IF_EB("\033|8H", ESC_STR "|8H")},   /* HL_UNDERLINE */
+    {(int)KS_US,	IF_EB("\033|8h", ESC_STR "|8h")},   /* HL_UNDERLINE */
+    {(int)KS_UCE,	IF_EB("\033|8C", ESC_STR "|8C")},   /* HL_UNDERCURL */
+    {(int)KS_UCS,	IF_EB("\033|8c", ESC_STR "|8c")},   /* HL_UNDERCURL */
+    {(int)KS_CZR,	IF_EB("\033|4H", ESC_STR "|4H")},   /* HL_ITALIC */
+    {(int)KS_CZH,	IF_EB("\033|4h", ESC_STR "|4h")},   /* HL_ITALIC */
+    {(int)KS_VB,	IF_EB("\033|f", ESC_STR "|f")},
+    {(int)KS_MS,	"y"},
+    {(int)KS_UT,	"y"},
+    {(int)KS_LE,	"\b"},		/* cursor-left = BS */
+    {(int)KS_ND,	"\014"},	/* cursor-right = CTRL-L */
+# ifdef TERMINFO
+    {(int)KS_CM,	IF_EB("\033|%p1%d;%p2%dM", ESC_STR "|%p1%d;%p2%dM")},
+# else
+    {(int)KS_CM,	IF_EB("\033|%d;%dM", ESC_STR "|%d;%dM")},
+# endif
+	/* there are no key sequences here, the GUI sequences are recognized
+	 * in check_termcode() */
+#endif
+
+#ifndef NO_BUILTIN_TCAPS
+# if defined(RISCOS) || defined(ALL_BUILTIN_TCAPS)
+/*
+ * Default for the Acorn.
+ */
+    {(int)KS_NAME,	"riscos"},
+    {(int)KS_CL,	"\014"},		/* Cls and Home Cursor */
+    {(int)KS_CM,	"\001%d\001%d\002"},	/* Position cursor */
+
+    {(int)KS_CCO,	"16"},			/* Allow 16 colors */
+
+    {(int)KS_CAF,	"\001%d\021"},		/* Set foreground colour */
+    {(int)KS_CAB,	"\001%d\022"},		/* Set background colour */
+
+
+    {(int)KS_ME,	"\004"},		/* Normal mode */
+    {(int)KS_MR,	"\005"},		/* Reverse */
+
+    {(int)KS_VI,	"\016"},		/* Cursor invisible */
+    {(int)KS_VE,	"\017"},		/* Cursor visible */
+    {(int)KS_VS,	"\020"},		/* Cursor very visible */
+
+    {(int)KS_CS,	"\001%d\001%d\003"},	/* Set scroll region */
+    {(int)KS_SR,	"\023"},		/* Scroll text down */
+    {K_UP,		"\217"},
+    {K_DOWN,		"\216"},
+    {K_LEFT,		"\214"},
+    {K_RIGHT,		"\215"},
+    {K_S_UP,		"\237"},
+    {K_S_DOWN,		"\236"},
+    {K_S_LEFT,		"\234"},
+    {K_S_RIGHT,		"\235"},
+
+    {K_F1,		"\201"},
+    {K_F2,		"\202"},
+    {K_F3,		"\203"},
+    {K_F4,		"\204"},
+    {K_F5,		"\205"},
+    {K_F6,		"\206"},
+    {K_F7,		"\207"},
+    {K_F8,		"\210"},
+    {K_F9,		"\211"},
+    {K_F10,		"\312"},
+    {K_F11,		"\313"},
+    {K_F12,		"\314"},
+    {K_S_F1,		"\221"},
+    {K_S_F2,		"\222"},
+    {K_S_F3,		"\223"},
+    {K_S_F4,		"\224"},
+    {K_S_F5,		"\225"},
+    {K_S_F6,		"\226"},
+    {K_S_F7,		"\227"},
+    {K_S_F8,		"\230"},
+    {K_S_F9,		"\231"},
+    {K_S_F10,		"\332"},
+    {K_S_F11,		"\333"},
+    {K_S_F12,		"\334"},
+    {K_BS,		"\010"},
+    {K_INS,		"\315"},
+    {K_DEL,		"\177"},
+    {K_HOME,		"\036"},
+    {K_END,		"\213"},
+    {K_PAGEUP,		"\237"},
+    {K_PAGEDOWN,	"\236"},
+# endif	/* Acorn terminal */
+
+
+# if defined(AMIGA) || defined(ALL_BUILTIN_TCAPS)
+/*
+ * Amiga console window, default for Amiga
+ */
+    {(int)KS_NAME,	"amiga"},
+    {(int)KS_CE,	"\033[K"},
+    {(int)KS_CD,	"\033[J"},
+    {(int)KS_AL,	"\033[L"},
+#  ifdef TERMINFO
+    {(int)KS_CAL,	"\033[%p1%dL"},
+#  else
+    {(int)KS_CAL,	"\033[%dL"},
+#  endif
+    {(int)KS_DL,	"\033[M"},
+#  ifdef TERMINFO
+    {(int)KS_CDL,	"\033[%p1%dM"},
+#  else
+    {(int)KS_CDL,	"\033[%dM"},
+#  endif
+    {(int)KS_CL,	"\014"},
+    {(int)KS_VI,	"\033[0 p"},
+    {(int)KS_VE,	"\033[1 p"},
+    {(int)KS_ME,	"\033[0m"},
+    {(int)KS_MR,	"\033[7m"},
+    {(int)KS_MD,	"\033[1m"},
+    {(int)KS_SE,	"\033[0m"},
+    {(int)KS_SO,	"\033[33m"},
+    {(int)KS_US,	"\033[4m"},
+    {(int)KS_UE,	"\033[0m"},
+    {(int)KS_CZH,	"\033[3m"},
+    {(int)KS_CZR,	"\033[0m"},
+#if defined(__MORPHOS__) || defined(__AROS__)
+    {(int)KS_CCO,	"8"},		/* allow 8 colors */
+#  ifdef TERMINFO
+    {(int)KS_CAB,	"\033[4%p1%dm"},/* set background color */
+    {(int)KS_CAF,	"\033[3%p1%dm"},/* set foreground color */
+#  else
+    {(int)KS_CAB,	"\033[4%dm"},	/* set background color */
+    {(int)KS_CAF,	"\033[3%dm"},	/* set foreground color */
+#  endif
+    {(int)KS_OP,	"\033[m"},	/* reset colors */
+#endif
+    {(int)KS_MS,	"y"},
+    {(int)KS_UT,	"y"},		/* guessed */
+    {(int)KS_LE,	"\b"},
+#  ifdef TERMINFO
+    {(int)KS_CM,	"\033[%i%p1%d;%p2%dH"},
+#  else
+    {(int)KS_CM,	"\033[%i%d;%dH"},
+#  endif
+#if defined(__MORPHOS__)
+    {(int)KS_SR,	"\033M"},
+#endif
+#  ifdef TERMINFO
+    {(int)KS_CRI,	"\033[%p1%dC"},
+#  else
+    {(int)KS_CRI,	"\033[%dC"},
+#  endif
+    {K_UP,		"\233A"},
+    {K_DOWN,		"\233B"},
+    {K_LEFT,		"\233D"},
+    {K_RIGHT,		"\233C"},
+    {K_S_UP,		"\233T"},
+    {K_S_DOWN,		"\233S"},
+    {K_S_LEFT,		"\233 A"},
+    {K_S_RIGHT,		"\233 @"},
+    {K_S_TAB,		"\233Z"},
+    {K_F1,		"\233\060~"},/* some compilers don't dig "\2330" */
+    {K_F2,		"\233\061~"},
+    {K_F3,		"\233\062~"},
+    {K_F4,		"\233\063~"},
+    {K_F5,		"\233\064~"},
+    {K_F6,		"\233\065~"},
+    {K_F7,		"\233\066~"},
+    {K_F8,		"\233\067~"},
+    {K_F9,		"\233\070~"},
+    {K_F10,		"\233\071~"},
+    {K_S_F1,		"\233\061\060~"},
+    {K_S_F2,		"\233\061\061~"},
+    {K_S_F3,		"\233\061\062~"},
+    {K_S_F4,		"\233\061\063~"},
+    {K_S_F5,		"\233\061\064~"},
+    {K_S_F6,		"\233\061\065~"},
+    {K_S_F7,		"\233\061\066~"},
+    {K_S_F8,		"\233\061\067~"},
+    {K_S_F9,		"\233\061\070~"},
+    {K_S_F10,		"\233\061\071~"},
+    {K_HELP,		"\233?~"},
+    {K_INS,		"\233\064\060~"},	/* 101 key keyboard */
+    {K_PAGEUP,		"\233\064\061~"},	/* 101 key keyboard */
+    {K_PAGEDOWN,	"\233\064\062~"},	/* 101 key keyboard */
+    {K_HOME,		"\233\064\064~"},	/* 101 key keyboard */
+    {K_END,		"\233\064\065~"},	/* 101 key keyboard */
+
+    {BT_EXTRA_KEYS,	""},
+    {TERMCAP2KEY('#', '2'), "\233\065\064~"},	/* shifted home key */
+    {TERMCAP2KEY('#', '3'), "\233\065\060~"},	/* shifted insert key */
+    {TERMCAP2KEY('*', '7'), "\233\065\065~"},	/* shifted end key */
+# endif
+
+# if defined(__BEOS__) || defined(ALL_BUILTIN_TCAPS)
+/*
+ * almost standard ANSI terminal, default for bebox
+ */
+    {(int)KS_NAME,	"beos-ansi"},
+    {(int)KS_CE,	"\033[K"},
+    {(int)KS_CD,	"\033[J"},
+    {(int)KS_AL,	"\033[L"},
+#  ifdef TERMINFO
+    {(int)KS_CAL,	"\033[%p1%dL"},
+#  else
+    {(int)KS_CAL,	"\033[%dL"},
+#  endif
+    {(int)KS_DL,	"\033[M"},
+#  ifdef TERMINFO
+    {(int)KS_CDL,	"\033[%p1%dM"},
+#  else
+    {(int)KS_CDL,	"\033[%dM"},
+#  endif
+#ifdef BEOS_PR_OR_BETTER
+#  ifdef TERMINFO
+    {(int)KS_CS,	"\033[%i%p1%d;%p2%dr"},
+#  else
+    {(int)KS_CS,	"\033[%i%d;%dr"},	/* scroll region */
+#  endif
+#endif
+    {(int)KS_CL,	"\033[H\033[2J"},
+#ifdef notyet
+    {(int)KS_VI,	"[VI]"}, /* cursor invisible, VT320: CSI ? 25 l */
+    {(int)KS_VE,	"[VE]"}, /* cursor visible, VT320: CSI ? 25 h */
+#endif
+    {(int)KS_ME,	"\033[m"},	/* normal mode */
+    {(int)KS_MR,	"\033[7m"},	/* reverse */
+    {(int)KS_MD,	"\033[1m"},	/* bold */
+    {(int)KS_SO,	"\033[31m"},	/* standout mode: red */
+    {(int)KS_SE,	"\033[m"},	/* standout end */
+    {(int)KS_CZH,	"\033[35m"},	/* italic: purple */
+    {(int)KS_CZR,	"\033[m"},	/* italic end */
+    {(int)KS_US,	"\033[4m"},	/* underscore mode */
+    {(int)KS_UE,	"\033[m"},	/* underscore end */
+    {(int)KS_CCO,	"8"},		/* allow 8 colors */
+#  ifdef TERMINFO
+    {(int)KS_CAB,	"\033[4%p1%dm"},/* set background color */
+    {(int)KS_CAF,	"\033[3%p1%dm"},/* set foreground color */
+#  else
+    {(int)KS_CAB,	"\033[4%dm"},	/* set background color */
+    {(int)KS_CAF,	"\033[3%dm"},	/* set foreground color */
+#  endif
+    {(int)KS_OP,	"\033[m"},	/* reset colors */
+    {(int)KS_MS,	"y"},		/* safe to move cur in reverse mode */
+    {(int)KS_UT,	"y"},		/* guessed */
+    {(int)KS_LE,	"\b"},
+#  ifdef TERMINFO
+    {(int)KS_CM,	"\033[%i%p1%d;%p2%dH"},
+#  else
+    {(int)KS_CM,	"\033[%i%d;%dH"},
+#  endif
+    {(int)KS_SR,	"\033M"},
+#  ifdef TERMINFO
+    {(int)KS_CRI,	"\033[%p1%dC"},
+#  else
+    {(int)KS_CRI,	"\033[%dC"},
+#  endif
+#if defined(BEOS_DR8)
+    {(int)KS_DB,	""},		/* hack! see screen.c */
+#endif
+
+    {K_UP,		"\033[A"},
+    {K_DOWN,		"\033[B"},
+    {K_LEFT,		"\033[D"},
+    {K_RIGHT,		"\033[C"},
+# endif
+
+# if defined(UNIX) || defined(ALL_BUILTIN_TCAPS) || defined(SOME_BUILTIN_TCAPS) || defined(__EMX__)
+/*
+ * standard ANSI terminal, default for unix
+ */
+    {(int)KS_NAME,	"ansi"},
+    {(int)KS_CE,	IF_EB("\033[K", ESC_STR "[K")},
+    {(int)KS_AL,	IF_EB("\033[L", ESC_STR "[L")},
+#  ifdef TERMINFO
+    {(int)KS_CAL,	IF_EB("\033[%p1%dL", ESC_STR "[%p1%dL")},
+#  else
+    {(int)KS_CAL,	IF_EB("\033[%dL", ESC_STR "[%dL")},
+#  endif
+    {(int)KS_DL,	IF_EB("\033[M", ESC_STR "[M")},
+#  ifdef TERMINFO
+    {(int)KS_CDL,	IF_EB("\033[%p1%dM", ESC_STR "[%p1%dM")},
+#  else
+    {(int)KS_CDL,	IF_EB("\033[%dM", ESC_STR "[%dM")},
+#  endif
+    {(int)KS_CL,	IF_EB("\033[H\033[2J", ESC_STR "[H" ESC_STR_nc "[2J")},
+    {(int)KS_ME,	IF_EB("\033[0m", ESC_STR "[0m")},
+    {(int)KS_MR,	IF_EB("\033[7m", ESC_STR "[7m")},
+    {(int)KS_MS,	"y"},
+    {(int)KS_UT,	"y"},		/* guessed */
+    {(int)KS_LE,	"\b"},
+#  ifdef TERMINFO
+    {(int)KS_CM,	IF_EB("\033[%i%p1%d;%p2%dH", ESC_STR "[%i%p1%d;%p2%dH")},
+#  else
+    {(int)KS_CM,	IF_EB("\033[%i%d;%dH", ESC_STR "[%i%d;%dH")},
+#  endif
+#  ifdef TERMINFO
+    {(int)KS_CRI,	IF_EB("\033[%p1%dC", ESC_STR "[%p1%dC")},
+#  else
+    {(int)KS_CRI,	IF_EB("\033[%dC", ESC_STR "[%dC")},
+#  endif
+# endif
+
+# if defined(MSDOS) || defined(ALL_BUILTIN_TCAPS) || defined(__EMX__)
+/*
+ * These codes are valid when nansi.sys or equivalent has been installed.
+ * Function keys on a PC are preceded with a NUL. These are converted into
+ * K_NUL '\316' in mch_inchar(), because we cannot handle NULs in key codes.
+ * CTRL-arrow is used instead of SHIFT-arrow.
+ */
+#ifdef __EMX__
+    {(int)KS_NAME,	"os2ansi"},
+#else
+    {(int)KS_NAME,	"pcansi"},
+    {(int)KS_DL,	"\033[M"},
+    {(int)KS_AL,	"\033[L"},
+#endif
+    {(int)KS_CE,	"\033[K"},
+    {(int)KS_CL,	"\033[2J"},
+    {(int)KS_ME,	"\033[0m"},
+    {(int)KS_MR,	"\033[5m"},	/* reverse: black on lightgrey */
+    {(int)KS_MD,	"\033[1m"},	/* bold: white text */
+    {(int)KS_SE,	"\033[0m"},	/* standout end */
+    {(int)KS_SO,	"\033[31m"},	/* standout: white on blue */
+    {(int)KS_CZH,	"\033[34;43m"},	/* italic mode: blue text on yellow */
+    {(int)KS_CZR,	"\033[0m"},	/* italic mode end */
+    {(int)KS_US,	"\033[36;41m"},	/* underscore mode: cyan text on red */
+    {(int)KS_UE,	"\033[0m"},	/* underscore mode end */
+    {(int)KS_CCO,	"8"},		/* allow 8 colors */
+#  ifdef TERMINFO
+    {(int)KS_CAB,	"\033[4%p1%dm"},/* set background color */
+    {(int)KS_CAF,	"\033[3%p1%dm"},/* set foreground color */
+#  else
+    {(int)KS_CAB,	"\033[4%dm"},	/* set background color */
+    {(int)KS_CAF,	"\033[3%dm"},	/* set foreground color */
+#  endif
+    {(int)KS_OP,	"\033[0m"},	/* reset colors */
+    {(int)KS_MS,	"y"},
+    {(int)KS_UT,	"y"},		/* guessed */
+    {(int)KS_LE,	"\b"},
+#  ifdef TERMINFO
+    {(int)KS_CM,	"\033[%i%p1%d;%p2%dH"},
+#  else
+    {(int)KS_CM,	"\033[%i%d;%dH"},
+#  endif
+#  ifdef TERMINFO
+    {(int)KS_CRI,	"\033[%p1%dC"},
+#  else
+    {(int)KS_CRI,	"\033[%dC"},
+#  endif
+    {K_UP,		"\316H"},
+    {K_DOWN,		"\316P"},
+    {K_LEFT,		"\316K"},
+    {K_RIGHT,		"\316M"},
+    {K_S_LEFT,		"\316s"},
+    {K_S_RIGHT,		"\316t"},
+    {K_F1,		"\316;"},
+    {K_F2,		"\316<"},
+    {K_F3,		"\316="},
+    {K_F4,		"\316>"},
+    {K_F5,		"\316?"},
+    {K_F6,		"\316@"},
+    {K_F7,		"\316A"},
+    {K_F8,		"\316B"},
+    {K_F9,		"\316C"},
+    {K_F10,		"\316D"},
+    {K_F11,		"\316\205"},	/* guessed */
+    {K_F12,		"\316\206"},	/* guessed */
+    {K_S_F1,		"\316T"},
+    {K_S_F2,		"\316U"},
+    {K_S_F3,		"\316V"},
+    {K_S_F4,		"\316W"},
+    {K_S_F5,		"\316X"},
+    {K_S_F6,		"\316Y"},
+    {K_S_F7,		"\316Z"},
+    {K_S_F8,		"\316["},
+    {K_S_F9,		"\316\\"},
+    {K_S_F10,		"\316]"},
+    {K_S_F11,		"\316\207"},	/* guessed */
+    {K_S_F12,		"\316\210"},	/* guessed */
+    {K_INS,		"\316R"},
+    {K_DEL,		"\316S"},
+    {K_HOME,		"\316G"},
+    {K_END,		"\316O"},
+    {K_PAGEDOWN,	"\316Q"},
+    {K_PAGEUP,		"\316I"},
+# endif
+
+# if defined(MSDOS)
+/*
+ * These codes are valid for the pc video.  The entries that start with ESC |
+ * are translated into conio calls in os_msdos.c. Default for MSDOS.
+ */
+    {(int)KS_NAME,	"pcterm"},
+    {(int)KS_CE,	"\033|K"},
+    {(int)KS_AL,	"\033|L"},
+    {(int)KS_DL,	"\033|M"},
+#  ifdef TERMINFO
+    {(int)KS_CS,	"\033|%i%p1%d;%p2%dr"},
+#   ifdef FEAT_VERTSPLIT
+    {(int)KS_CSV,	"\033|%i%p1%d;%p2%dV"},
+#   endif
+#  else
+    {(int)KS_CS,	"\033|%i%d;%dr"},
+#   ifdef FEAT_VERTSPLIT
+    {(int)KS_CSV,	"\033|%i%d;%dV"},
+#   endif
+#  endif
+    {(int)KS_CL,	"\033|J"},
+    {(int)KS_ME,	"\033|0m"},	/* normal */
+    {(int)KS_MR,	"\033|112m"},	/* reverse: black on lightgrey */
+    {(int)KS_MD,	"\033|15m"},	/* bold: white text */
+    {(int)KS_SE,	"\033|0m"},	/* standout end */
+    {(int)KS_SO,	"\033|31m"},	/* standout: white on blue */
+    {(int)KS_CZH,	"\033|225m"},	/* italic mode: blue text on yellow */
+    {(int)KS_CZR,	"\033|0m"},	/* italic mode end */
+    {(int)KS_US,	"\033|67m"},	/* underscore mode: cyan text on red */
+    {(int)KS_UE,	"\033|0m"},	/* underscore mode end */
+    {(int)KS_CCO,	"16"},		/* allow 16 colors */
+#  ifdef TERMINFO
+    {(int)KS_CAB,	"\033|%p1%db"},	/* set background color */
+    {(int)KS_CAF,	"\033|%p1%df"},	/* set foreground color */
+#  else
+    {(int)KS_CAB,	"\033|%db"},	/* set background color */
+    {(int)KS_CAF,	"\033|%df"},	/* set foreground color */
+#  endif
+    {(int)KS_MS,	"y"},
+    {(int)KS_UT,	"y"},
+    {(int)KS_LE,	"\b"},
+#  ifdef TERMINFO
+    {(int)KS_CM,	"\033|%i%p1%d;%p2%dH"},
+#  else
+    {(int)KS_CM,	"\033|%i%d;%dH"},
+#  endif
+#ifdef DJGPP
+    {(int)KS_VB,	"\033|B"},	/* visual bell */
+#endif
+    {K_UP,		"\316H"},
+    {K_DOWN,		"\316P"},
+    {K_LEFT,		"\316K"},
+    {K_RIGHT,		"\316M"},
+    {K_S_LEFT,		"\316s"},
+    {K_S_RIGHT,		"\316t"},
+    {K_S_TAB,		"\316\017"},
+    {K_F1,		"\316;"},
+    {K_F2,		"\316<"},
+    {K_F3,		"\316="},
+    {K_F4,		"\316>"},
+    {K_F5,		"\316?"},
+    {K_F6,		"\316@"},
+    {K_F7,		"\316A"},
+    {K_F8,		"\316B"},
+    {K_F9,		"\316C"},
+    {K_F10,		"\316D"},
+    {K_F11,		"\316\205"},
+    {K_F12,		"\316\206"},
+    {K_S_F1,		"\316T"},
+    {K_S_F2,		"\316U"},
+    {K_S_F3,		"\316V"},
+    {K_S_F4,		"\316W"},
+    {K_S_F5,		"\316X"},
+    {K_S_F6,		"\316Y"},
+    {K_S_F7,		"\316Z"},
+    {K_S_F8,		"\316["},
+    {K_S_F9,		"\316\\"},
+    {K_S_F10,		"\316]"},
+    {K_S_F11,		"\316\207"},
+    {K_S_F12,		"\316\210"},
+    {K_INS,		"\316R"},
+    {K_DEL,		"\316S"},
+    {K_HOME,		"\316G"},
+    {K_END,		"\316O"},
+    {K_PAGEDOWN,	"\316Q"},
+    {K_PAGEUP,		"\316I"},
+    {K_KPLUS,		"\316N"},
+    {K_KMINUS,		"\316J"},
+    {K_KMULTIPLY,	"\3167"},
+    {K_K0,		"\316\332"},
+    {K_K1,		"\316\336"},
+    {K_K2,		"\316\342"},
+    {K_K3,		"\316\346"},
+    {K_K4,		"\316\352"},
+    {K_K5,		"\316\356"},
+    {K_K6,		"\316\362"},
+    {K_K7,		"\316\366"},
+    {K_K8,		"\316\372"},
+    {K_K9,		"\316\376"},
+# endif
+
+# if defined(WIN3264) || defined(ALL_BUILTIN_TCAPS) || defined(__EMX__)
+/*
+ * These codes are valid for the Win32 Console .  The entries that start with
+ * ESC | are translated into console calls in os_win32.c.  The function keys
+ * are also translated in os_win32.c.
+ */
+    {(int)KS_NAME,	"win32"},
+    {(int)KS_CE,	"\033|K"},	/* clear to end of line */
+    {(int)KS_AL,	"\033|L"},	/* add new blank line */
+#  ifdef TERMINFO
+    {(int)KS_CAL,	"\033|%p1%dL"},	/* add number of new blank lines */
+#  else
+    {(int)KS_CAL,	"\033|%dL"},	/* add number of new blank lines */
+#  endif
+    {(int)KS_DL,	"\033|M"},	/* delete line */
+#  ifdef TERMINFO
+    {(int)KS_CDL,	"\033|%p1%dM"},	/* delete number of lines */
+#  else
+    {(int)KS_CDL,	"\033|%dM"},	/* delete number of lines */
+#  endif
+    {(int)KS_CL,	"\033|J"},	/* clear screen */
+    {(int)KS_CD,	"\033|j"},	/* clear to end of display */
+    {(int)KS_VI,	"\033|v"},	/* cursor invisible */
+    {(int)KS_VE,	"\033|V"},	/* cursor visible */
+
+    {(int)KS_ME,	"\033|0m"},	/* normal */
+    {(int)KS_MR,	"\033|112m"},	/* reverse: black on lightgray */
+    {(int)KS_MD,	"\033|15m"},	/* bold: white on black */
+#if 1
+    {(int)KS_SO,	"\033|31m"},	/* standout: white on blue */
+    {(int)KS_SE,	"\033|0m"},	/* standout end */
+#else
+    {(int)KS_SO,	"\033|F"},	/* standout: high intensity */
+    {(int)KS_SE,	"\033|f"},	/* standout end */
+#endif
+    {(int)KS_CZH,	"\033|225m"},	/* italic: blue text on yellow */
+    {(int)KS_CZR,	"\033|0m"},	/* italic end */
+    {(int)KS_US,	"\033|67m"},	/* underscore: cyan text on red */
+    {(int)KS_UE,	"\033|0m"},	/* underscore end */
+    {(int)KS_CCO,	"16"},		/* allow 16 colors */
+#  ifdef TERMINFO
+    {(int)KS_CAB,	"\033|%p1%db"},	/* set background color */
+    {(int)KS_CAF,	"\033|%p1%df"},	/* set foreground color */
+#  else
+    {(int)KS_CAB,	"\033|%db"},	/* set background color */
+    {(int)KS_CAF,	"\033|%df"},	/* set foreground color */
+#  endif
+
+    {(int)KS_MS,	"y"},		/* save to move cur in reverse mode */
+    {(int)KS_UT,	"y"},
+    {(int)KS_LE,	"\b"},
+#  ifdef TERMINFO
+    {(int)KS_CM,	"\033|%i%p1%d;%p2%dH"},/* cursor motion */
+#  else
+    {(int)KS_CM,	"\033|%i%d;%dH"},/* cursor motion */
+#  endif
+    {(int)KS_VB,	"\033|B"},	/* visual bell */
+    {(int)KS_TI,	"\033|S"},	/* put terminal in termcap mode */
+    {(int)KS_TE,	"\033|E"},	/* out of termcap mode */
+#  ifdef TERMINFO
+    {(int)KS_CS,	"\033|%i%p1%d;%p2%dr"},/* scroll region */
+#  else
+    {(int)KS_CS,	"\033|%i%d;%dr"},/* scroll region */
+#  endif
+
+    {K_UP,		"\316H"},
+    {K_DOWN,		"\316P"},
+    {K_LEFT,		"\316K"},
+    {K_RIGHT,		"\316M"},
+    {K_S_UP,		"\316\304"},
+    {K_S_DOWN,		"\316\317"},
+    {K_S_LEFT,		"\316\311"},
+    {K_C_LEFT,		"\316s"},
+    {K_S_RIGHT,		"\316\313"},
+    {K_C_RIGHT,		"\316t"},
+    {K_S_TAB,		"\316\017"},
+    {K_F1,		"\316;"},
+    {K_F2,		"\316<"},
+    {K_F3,		"\316="},
+    {K_F4,		"\316>"},
+    {K_F5,		"\316?"},
+    {K_F6,		"\316@"},
+    {K_F7,		"\316A"},
+    {K_F8,		"\316B"},
+    {K_F9,		"\316C"},
+    {K_F10,		"\316D"},
+    {K_F11,		"\316\205"},
+    {K_F12,		"\316\206"},
+    {K_S_F1,		"\316T"},
+    {K_S_F2,		"\316U"},
+    {K_S_F3,		"\316V"},
+    {K_S_F4,		"\316W"},
+    {K_S_F5,		"\316X"},
+    {K_S_F6,		"\316Y"},
+    {K_S_F7,		"\316Z"},
+    {K_S_F8,		"\316["},
+    {K_S_F9,		"\316\\"},
+    {K_S_F10,		"\316]"},
+    {K_S_F11,		"\316\207"},
+    {K_S_F12,		"\316\210"},
+    {K_INS,		"\316R"},
+    {K_DEL,		"\316S"},
+    {K_HOME,		"\316G"},
+    {K_S_HOME,		"\316\302"},
+    {K_C_HOME,		"\316w"},
+    {K_END,		"\316O"},
+    {K_S_END,		"\316\315"},
+    {K_C_END,		"\316u"},
+    {K_PAGEDOWN,	"\316Q"},
+    {K_PAGEUP,		"\316I"},
+    {K_KPLUS,		"\316N"},
+    {K_KMINUS,		"\316J"},
+    {K_KMULTIPLY,	"\316\067"},
+    {K_K0,		"\316\332"},
+    {K_K1,		"\316\336"},
+    {K_K2,		"\316\342"},
+    {K_K3,		"\316\346"},
+    {K_K4,		"\316\352"},
+    {K_K5,		"\316\356"},
+    {K_K6,		"\316\362"},
+    {K_K7,		"\316\366"},
+    {K_K8,		"\316\372"},
+    {K_K9,		"\316\376"},
+# endif
+
+# if defined(VMS) || defined(ALL_BUILTIN_TCAPS)
+/*
+ * VT320 is working as an ANSI terminal compatible DEC terminal.
+ * (it covers VT1x0, VT2x0 and VT3x0 up to VT320 on VMS as well)
+ * Note: K_F1...K_F5 are for internal use, should not be defined.
+ * TODO:- rewrite ESC[ codes to CSI
+ *      - keyboard languages (CSI ? 26 n)
+ */
+    {(int)KS_NAME,	"vt320"},
+    {(int)KS_CE,	IF_EB("\033[K", ESC_STR "[K")},
+    {(int)KS_AL,	IF_EB("\033[L", ESC_STR "[L")},
+#  ifdef TERMINFO
+    {(int)KS_CAL,	IF_EB("\033[%p1%dL", ESC_STR "[%p1%dL")},
+#  else
+    {(int)KS_CAL,	IF_EB("\033[%dL", ESC_STR "[%dL")},
+#  endif
+    {(int)KS_DL,	IF_EB("\033[M", ESC_STR "[M")},
+#  ifdef TERMINFO
+    {(int)KS_CDL,	IF_EB("\033[%p1%dM", ESC_STR "[%p1%dM")},
+#  else
+    {(int)KS_CDL,	IF_EB("\033[%dM", ESC_STR "[%dM")},
+#  endif
+    {(int)KS_CL,	IF_EB("\033[H\033[2J", ESC_STR "[H" ESC_STR_nc "[2J")},
+    {(int)KS_CD,	IF_EB("\033[J", ESC_STR "[J")},
+    {(int)KS_CCO,	"8"},			/* allow 8 colors */
+    {(int)KS_ME,	IF_EB("\033[0m", ESC_STR "[0m")},
+    {(int)KS_MR,	IF_EB("\033[7m", ESC_STR "[7m")},
+    {(int)KS_MD,	IF_EB("\033[1m", ESC_STR "[1m")},  /* bold mode */
+    {(int)KS_SE,	IF_EB("\033[22m", ESC_STR "[22m")},/* normal mode */
+    {(int)KS_UE,	IF_EB("\033[24m", ESC_STR "[24m")},/* exit underscore mode */
+    {(int)KS_US,	IF_EB("\033[4m", ESC_STR "[4m")},  /* underscore mode */
+    {(int)KS_CZH,	IF_EB("\033[34;43m", ESC_STR "[34;43m")},  /* italic mode: blue text on yellow */
+    {(int)KS_CZR,	IF_EB("\033[0m", ESC_STR "[0m")},	    /* italic mode end */
+    {(int)KS_CAB,	IF_EB("\033[4%dm", ESC_STR "[4%dm")},	    /* set background color (ANSI) */
+    {(int)KS_CAF,	IF_EB("\033[3%dm", ESC_STR "[3%dm")},	    /* set foreground color (ANSI) */
+    {(int)KS_CSB,	IF_EB("\033[102;%dm", ESC_STR "[102;%dm")},	/* set screen background color */
+    {(int)KS_CSF,	IF_EB("\033[101;%dm", ESC_STR "[101;%dm")},	/* set screen foreground color */
+    {(int)KS_MS,	"y"},
+    {(int)KS_UT,	"y"},
+    {(int)KS_LE,	"\b"},
+#  ifdef TERMINFO
+    {(int)KS_CM,	IF_EB("\033[%i%p1%d;%p2%dH",
+						  ESC_STR "[%i%p1%d;%p2%dH")},
+#  else
+    {(int)KS_CM,	IF_EB("\033[%i%d;%dH", ESC_STR "[%i%d;%dH")},
+#  endif
+#  ifdef TERMINFO
+    {(int)KS_CRI,	IF_EB("\033[%p1%dC", ESC_STR "[%p1%dC")},
+#  else
+    {(int)KS_CRI,	IF_EB("\033[%dC", ESC_STR "[%dC")},
+#  endif
+    {K_UP,		IF_EB("\033[A", ESC_STR "[A")},
+    {K_DOWN,		IF_EB("\033[B", ESC_STR "[B")},
+    {K_RIGHT,		IF_EB("\033[C", ESC_STR "[C")},
+    {K_LEFT,		IF_EB("\033[D", ESC_STR "[D")},
+    {K_F1,		IF_EB("\033[11~", ESC_STR "[11~")},
+    {K_F2,		IF_EB("\033[12~", ESC_STR "[12~")},
+    {K_F3,		IF_EB("\033[13~", ESC_STR "[13~")},
+    {K_F4,		IF_EB("\033[14~", ESC_STR "[14~")},
+    {K_F5,		IF_EB("\033[15~", ESC_STR "[15~")},
+    {K_F6,		IF_EB("\033[17~", ESC_STR "[17~")},
+    {K_F7,		IF_EB("\033[18~", ESC_STR "[18~")},
+    {K_F8,		IF_EB("\033[19~", ESC_STR "[19~")},
+    {K_F9,		IF_EB("\033[20~", ESC_STR "[20~")},
+    {K_F10,		IF_EB("\033[21~", ESC_STR "[21~")},
+    {K_F11,		IF_EB("\033[23~", ESC_STR "[23~")},
+    {K_F12,		IF_EB("\033[24~", ESC_STR "[24~")},
+    {K_F13,		IF_EB("\033[25~", ESC_STR "[25~")},
+    {K_F14,		IF_EB("\033[26~", ESC_STR "[26~")},
+    {K_F15,		IF_EB("\033[28~", ESC_STR "[28~")},	/* Help */
+    {K_F16,		IF_EB("\033[29~", ESC_STR "[29~")},	/* Select */
+    {K_F17,		IF_EB("\033[31~", ESC_STR "[31~")},
+    {K_F18,		IF_EB("\033[32~", ESC_STR "[32~")},
+    {K_F19,		IF_EB("\033[33~", ESC_STR "[33~")},
+    {K_F20,		IF_EB("\033[34~", ESC_STR "[34~")},
+    {K_INS,		IF_EB("\033[2~", ESC_STR "[2~")},
+    {K_DEL,		IF_EB("\033[3~", ESC_STR "[3~")},
+    {K_HOME,		IF_EB("\033[1~", ESC_STR "[1~")},
+    {K_END,		IF_EB("\033[4~", ESC_STR "[4~")},
+    {K_PAGEUP,		IF_EB("\033[5~", ESC_STR "[5~")},
+    {K_PAGEDOWN,	IF_EB("\033[6~", ESC_STR "[6~")},
+    {K_KPLUS,		IF_EB("\033Ok", ESC_STR "Ok")},	/* keypad plus */
+    {K_KMINUS,		IF_EB("\033Om", ESC_STR "Om")},	/* keypad minus */
+    {K_KDIVIDE,		IF_EB("\033Oo", ESC_STR "Oo")},	/* keypad / */
+    {K_KMULTIPLY,	IF_EB("\033Oj", ESC_STR "Oj")},	/* keypad * */
+    {K_KENTER,		IF_EB("\033OM", ESC_STR "OM")},	/* keypad Enter */
+    {K_BS,		"\x7f"},	/* for some reason 0177 doesn't work */
+# endif
+
+# if defined(ALL_BUILTIN_TCAPS) || defined(__MINT__)
+/*
+ * Ordinary vt52
+ */
+    {(int)KS_NAME,	"vt52"},
+    {(int)KS_CE,	IF_EB("\033K", ESC_STR "K")},
+    {(int)KS_CD,	IF_EB("\033J", ESC_STR "J")},
+    {(int)KS_CM,	IF_EB("\033Y%+ %+ ", ESC_STR "Y%+ %+ ")},
+    {(int)KS_LE,	"\b"},
+#  ifdef __MINT__
+    {(int)KS_AL,	IF_EB("\033L", ESC_STR "L")},
+    {(int)KS_DL,	IF_EB("\033M", ESC_STR "M")},
+    {(int)KS_CL,	IF_EB("\033E", ESC_STR "E")},
+    {(int)KS_SR,	IF_EB("\033I", ESC_STR "I")},
+    {(int)KS_VE,	IF_EB("\033e", ESC_STR "e")},
+    {(int)KS_VI,	IF_EB("\033f", ESC_STR "f")},
+    {(int)KS_SO,	IF_EB("\033p", ESC_STR "p")},
+    {(int)KS_SE,	IF_EB("\033q", ESC_STR "q")},
+    {K_UP,		IF_EB("\033A", ESC_STR "A")},
+    {K_DOWN,		IF_EB("\033B", ESC_STR "B")},
+    {K_LEFT,		IF_EB("\033D", ESC_STR "D")},
+    {K_RIGHT,		IF_EB("\033C", ESC_STR "C")},
+    {K_S_UP,		IF_EB("\033a", ESC_STR "a")},
+    {K_S_DOWN,		IF_EB("\033b", ESC_STR "b")},
+    {K_S_LEFT,		IF_EB("\033d", ESC_STR "d")},
+    {K_S_RIGHT,		IF_EB("\033c", ESC_STR "c")},
+    {K_F1,		IF_EB("\033P", ESC_STR "P")},
+    {K_F2,		IF_EB("\033Q", ESC_STR "Q")},
+    {K_F3,		IF_EB("\033R", ESC_STR "R")},
+    {K_F4,		IF_EB("\033S", ESC_STR "S")},
+    {K_F5,		IF_EB("\033T", ESC_STR "T")},
+    {K_F6,		IF_EB("\033U", ESC_STR "U")},
+    {K_F7,		IF_EB("\033V", ESC_STR "V")},
+    {K_F8,		IF_EB("\033W", ESC_STR "W")},
+    {K_F9,		IF_EB("\033X", ESC_STR "X")},
+    {K_F10,		IF_EB("\033Y", ESC_STR "Y")},
+    {K_S_F1,		IF_EB("\033p", ESC_STR "p")},
+    {K_S_F2,		IF_EB("\033q", ESC_STR "q")},
+    {K_S_F3,		IF_EB("\033r", ESC_STR "r")},
+    {K_S_F4,		IF_EB("\033s", ESC_STR "s")},
+    {K_S_F5,		IF_EB("\033t", ESC_STR "t")},
+    {K_S_F6,		IF_EB("\033u", ESC_STR "u")},
+    {K_S_F7,		IF_EB("\033v", ESC_STR "v")},
+    {K_S_F8,		IF_EB("\033w", ESC_STR "w")},
+    {K_S_F9,		IF_EB("\033x", ESC_STR "x")},
+    {K_S_F10,		IF_EB("\033y", ESC_STR "y")},
+    {K_INS,		IF_EB("\033I", ESC_STR "I")},
+    {K_HOME,		IF_EB("\033E", ESC_STR "E")},
+    {K_PAGEDOWN,	IF_EB("\033b", ESC_STR "b")},
+    {K_PAGEUP,		IF_EB("\033a", ESC_STR "a")},
+#  else
+    {(int)KS_AL,	IF_EB("\033T", ESC_STR "T")},
+    {(int)KS_DL,	IF_EB("\033U", ESC_STR "U")},
+    {(int)KS_CL,	IF_EB("\033H\033J", ESC_STR "H" ESC_STR_nc "J")},
+    {(int)KS_ME,	IF_EB("\033SO", ESC_STR "SO")},
+    {(int)KS_MR,	IF_EB("\033S2", ESC_STR "S2")},
+    {(int)KS_MS,	"y"},
+#  endif
+# endif
+
+# if defined(UNIX) || defined(ALL_BUILTIN_TCAPS) || defined(SOME_BUILTIN_TCAPS) || defined(__EMX__)
+    {(int)KS_NAME,	"xterm"},
+    {(int)KS_CE,	IF_EB("\033[K", ESC_STR "[K")},
+    {(int)KS_AL,	IF_EB("\033[L", ESC_STR "[L")},
+#  ifdef TERMINFO
+    {(int)KS_CAL,	IF_EB("\033[%p1%dL", ESC_STR "[%p1%dL")},
+#  else
+    {(int)KS_CAL,	IF_EB("\033[%dL", ESC_STR "[%dL")},
+#  endif
+    {(int)KS_DL,	IF_EB("\033[M", ESC_STR "[M")},
+#  ifdef TERMINFO
+    {(int)KS_CDL,	IF_EB("\033[%p1%dM", ESC_STR "[%p1%dM")},
+#  else
+    {(int)KS_CDL,	IF_EB("\033[%dM", ESC_STR "[%dM")},
+#  endif
+#  ifdef TERMINFO
+    {(int)KS_CS,	IF_EB("\033[%i%p1%d;%p2%dr",
+						  ESC_STR "[%i%p1%d;%p2%dr")},
+#  else
+    {(int)KS_CS,	IF_EB("\033[%i%d;%dr", ESC_STR "[%i%d;%dr")},
+#  endif
+    {(int)KS_CL,	IF_EB("\033[H\033[2J", ESC_STR "[H" ESC_STR_nc "[2J")},
+    {(int)KS_CD,	IF_EB("\033[J", ESC_STR "[J")},
+    {(int)KS_ME,	IF_EB("\033[m", ESC_STR "[m")},
+    {(int)KS_MR,	IF_EB("\033[7m", ESC_STR "[7m")},
+    {(int)KS_MD,	IF_EB("\033[1m", ESC_STR "[1m")},
+    {(int)KS_UE,	IF_EB("\033[m", ESC_STR "[m")},
+    {(int)KS_US,	IF_EB("\033[4m", ESC_STR "[4m")},
+    {(int)KS_MS,	"y"},
+    {(int)KS_UT,	"y"},
+    {(int)KS_LE,	"\b"},
+#  ifdef TERMINFO
+    {(int)KS_CM,	IF_EB("\033[%i%p1%d;%p2%dH",
+						  ESC_STR "[%i%p1%d;%p2%dH")},
+#  else
+    {(int)KS_CM,	IF_EB("\033[%i%d;%dH", ESC_STR "[%i%d;%dH")},
+#  endif
+    {(int)KS_SR,	IF_EB("\033M", ESC_STR "M")},
+#  ifdef TERMINFO
+    {(int)KS_CRI,	IF_EB("\033[%p1%dC", ESC_STR "[%p1%dC")},
+#  else
+    {(int)KS_CRI,	IF_EB("\033[%dC", ESC_STR "[%dC")},
+#  endif
+    {(int)KS_KS,	IF_EB("\033[?1h\033=", ESC_STR "[?1h" ESC_STR_nc "=")},
+    {(int)KS_KE,	IF_EB("\033[?1l\033>", ESC_STR "[?1l" ESC_STR_nc ">")},
+#  ifdef FEAT_XTERM_SAVE
+    {(int)KS_TI,	IF_EB("\0337\033[?47h", ESC_STR "7" ESC_STR_nc "[?47h")},
+    {(int)KS_TE,	IF_EB("\033[2J\033[?47l\0338",
+				  ESC_STR "[2J" ESC_STR_nc "[?47l" ESC_STR_nc "8")},
+#  endif
+    {(int)KS_CIS,	IF_EB("\033]1;", ESC_STR "]1;")},
+    {(int)KS_CIE,	"\007"},
+    {(int)KS_TS,	IF_EB("\033]2;", ESC_STR "]2;")},
+    {(int)KS_FS,	"\007"},
+#  ifdef TERMINFO
+    {(int)KS_CWS,	IF_EB("\033[8;%p1%d;%p2%dt",
+						  ESC_STR "[8;%p1%d;%p2%dt")},
+    {(int)KS_CWP,	IF_EB("\033[3;%p1%d;%p2%dt",
+						  ESC_STR "[3;%p1%d;%p2%dt")},
+#  else
+    {(int)KS_CWS,	IF_EB("\033[8;%d;%dt", ESC_STR "[8;%d;%dt")},
+    {(int)KS_CWP,	IF_EB("\033[3;%d;%dt", ESC_STR "[3;%d;%dt")},
+#  endif
+    {(int)KS_CRV,	IF_EB("\033[>c", ESC_STR "[>c")},
+
+    {K_UP,		IF_EB("\033O*A", ESC_STR "O*A")},
+    {K_DOWN,		IF_EB("\033O*B", ESC_STR "O*B")},
+    {K_RIGHT,		IF_EB("\033O*C", ESC_STR "O*C")},
+    {K_LEFT,		IF_EB("\033O*D", ESC_STR "O*D")},
+    /* An extra set of cursor keys for vt100 mode */
+    {K_XUP,		IF_EB("\033[1;*A", ESC_STR "[1;*A")},
+    {K_XDOWN,		IF_EB("\033[1;*B", ESC_STR "[1;*B")},
+    {K_XRIGHT,		IF_EB("\033[1;*C", ESC_STR "[1;*C")},
+    {K_XLEFT,		IF_EB("\033[1;*D", ESC_STR "[1;*D")},
+    /* An extra set of function keys for vt100 mode */
+    {K_XF1,		IF_EB("\033O*P", ESC_STR "O*P")},
+    {K_XF2,		IF_EB("\033O*Q", ESC_STR "O*Q")},
+    {K_XF3,		IF_EB("\033O*R", ESC_STR "O*R")},
+    {K_XF4,		IF_EB("\033O*S", ESC_STR "O*S")},
+    {K_F1,		IF_EB("\033[11;*~", ESC_STR "[11;*~")},
+    {K_F2,		IF_EB("\033[12;*~", ESC_STR "[12;*~")},
+    {K_F3,		IF_EB("\033[13;*~", ESC_STR "[13;*~")},
+    {K_F4,		IF_EB("\033[14;*~", ESC_STR "[14;*~")},
+    {K_F5,		IF_EB("\033[15;*~", ESC_STR "[15;*~")},
+    {K_F6,		IF_EB("\033[17;*~", ESC_STR "[17;*~")},
+    {K_F7,		IF_EB("\033[18;*~", ESC_STR "[18;*~")},
+    {K_F8,		IF_EB("\033[19;*~", ESC_STR "[19;*~")},
+    {K_F9,		IF_EB("\033[20;*~", ESC_STR "[20;*~")},
+    {K_F10,		IF_EB("\033[21;*~", ESC_STR "[21;*~")},
+    {K_F11,		IF_EB("\033[23;*~", ESC_STR "[23;*~")},
+    {K_F12,		IF_EB("\033[24;*~", ESC_STR "[24;*~")},
+    {K_S_TAB,		IF_EB("\033[Z", ESC_STR "[Z")},
+    {K_HELP,		IF_EB("\033[28;*~", ESC_STR "[28;*~")},
+    {K_UNDO,		IF_EB("\033[26;*~", ESC_STR "[26;*~")},
+    {K_INS,		IF_EB("\033[2;*~", ESC_STR "[2;*~")},
+    {K_HOME,		IF_EB("\033[1;*H", ESC_STR "[1;*H")},
+    /* {K_S_HOME,		IF_EB("\033O2H", ESC_STR "O2H")}, */
+    /* {K_C_HOME,		IF_EB("\033O5H", ESC_STR "O5H")}, */
+    {K_KHOME,		IF_EB("\033[1;*~", ESC_STR "[1;*~")},
+    {K_XHOME,		IF_EB("\033O*H", ESC_STR "O*H")},	/* other Home */
+    {K_ZHOME,		IF_EB("\033[7;*~", ESC_STR "[7;*~")},	/* other Home */
+    {K_END,		IF_EB("\033[1;*F", ESC_STR "[1;*F")},
+    /* {K_S_END,		IF_EB("\033O2F", ESC_STR "O2F")}, */
+    /* {K_C_END,		IF_EB("\033O5F", ESC_STR "O5F")}, */
+    {K_KEND,		IF_EB("\033[4;*~", ESC_STR "[4;*~")},
+    {K_XEND,		IF_EB("\033O*F", ESC_STR "O*F")},	/* other End */
+    {K_ZEND,		IF_EB("\033[8;*~", ESC_STR "[8;*~")},
+    {K_PAGEUP,		IF_EB("\033[5;*~", ESC_STR "[5;*~")},
+    {K_PAGEDOWN,	IF_EB("\033[6;*~", ESC_STR "[6;*~")},
+    {K_KPLUS,		IF_EB("\033O*k", ESC_STR "O*k")},	/* keypad plus */
+    {K_KMINUS,		IF_EB("\033O*m", ESC_STR "O*m")},	/* keypad minus */
+    {K_KDIVIDE,		IF_EB("\033O*o", ESC_STR "O*o")},	/* keypad / */
+    {K_KMULTIPLY,	IF_EB("\033O*j", ESC_STR "O*j")},	/* keypad * */
+    {K_KENTER,		IF_EB("\033O*M", ESC_STR "O*M")},	/* keypad Enter */
+    {K_KPOINT,		IF_EB("\033O*n", ESC_STR "O*n")},	/* keypad . */
+    {K_KDEL,		IF_EB("\033[3;*~", ESC_STR "[3;*~")},	/* keypad Del */
+
+    {BT_EXTRA_KEYS,   ""},
+    {TERMCAP2KEY('k', '0'), IF_EB("\033[10;*~", ESC_STR "[10;*~")}, /* F0 */
+    {TERMCAP2KEY('F', '3'), IF_EB("\033[25;*~", ESC_STR "[25;*~")}, /* F13 */
+    /* F14 and F15 are missing, because they send the same codes as the undo
+     * and help key, although they don't work on all keyboards. */
+    {TERMCAP2KEY('F', '6'), IF_EB("\033[29;*~", ESC_STR "[29;*~")}, /* F16 */
+    {TERMCAP2KEY('F', '7'), IF_EB("\033[31;*~", ESC_STR "[31;*~")}, /* F17 */
+    {TERMCAP2KEY('F', '8'), IF_EB("\033[32;*~", ESC_STR "[32;*~")}, /* F18 */
+    {TERMCAP2KEY('F', '9'), IF_EB("\033[33;*~", ESC_STR "[33;*~")}, /* F19 */
+    {TERMCAP2KEY('F', 'A'), IF_EB("\033[34;*~", ESC_STR "[34;*~")}, /* F20 */
+
+    {TERMCAP2KEY('F', 'B'), IF_EB("\033[42;*~", ESC_STR "[42;*~")}, /* F21 */
+    {TERMCAP2KEY('F', 'C'), IF_EB("\033[43;*~", ESC_STR "[43;*~")}, /* F22 */
+    {TERMCAP2KEY('F', 'D'), IF_EB("\033[44;*~", ESC_STR "[44;*~")}, /* F23 */
+    {TERMCAP2KEY('F', 'E'), IF_EB("\033[45;*~", ESC_STR "[45;*~")}, /* F24 */
+    {TERMCAP2KEY('F', 'F'), IF_EB("\033[46;*~", ESC_STR "[46;*~")}, /* F25 */
+    {TERMCAP2KEY('F', 'G'), IF_EB("\033[47;*~", ESC_STR "[47;*~")}, /* F26 */
+    {TERMCAP2KEY('F', 'H'), IF_EB("\033[48;*~", ESC_STR "[48;*~")}, /* F27 */
+    {TERMCAP2KEY('F', 'I'), IF_EB("\033[49;*~", ESC_STR "[49;*~")}, /* F28 */
+    {TERMCAP2KEY('F', 'J'), IF_EB("\033[50;*~", ESC_STR "[50;*~")}, /* F29 */
+    {TERMCAP2KEY('F', 'K'), IF_EB("\033[51;*~", ESC_STR "[51;*~")}, /* F30 */
+
+    {TERMCAP2KEY('F', 'L'), IF_EB("\033[52;*~", ESC_STR "[52;*~")}, /* F31 */
+    {TERMCAP2KEY('F', 'M'), IF_EB("\033[53;*~", ESC_STR "[53;*~")}, /* F32 */
+    {TERMCAP2KEY('F', 'N'), IF_EB("\033[54;*~", ESC_STR "[54;*~")}, /* F33 */
+    {TERMCAP2KEY('F', 'O'), IF_EB("\033[55;*~", ESC_STR "[55;*~")}, /* F34 */
+    {TERMCAP2KEY('F', 'P'), IF_EB("\033[56;*~", ESC_STR "[56;*~")}, /* F35 */
+    {TERMCAP2KEY('F', 'Q'), IF_EB("\033[57;*~", ESC_STR "[57;*~")}, /* F36 */
+    {TERMCAP2KEY('F', 'R'), IF_EB("\033[58;*~", ESC_STR "[58;*~")}, /* F37 */
+# endif
+
+# if defined(UNIX) || defined(ALL_BUILTIN_TCAPS)
+/*
+ * iris-ansi for Silicon Graphics machines.
+ */
+    {(int)KS_NAME,	"iris-ansi"},
+    {(int)KS_CE,	"\033[K"},
+    {(int)KS_CD,	"\033[J"},
+    {(int)KS_AL,	"\033[L"},
+#  ifdef TERMINFO
+    {(int)KS_CAL,	"\033[%p1%dL"},
+#  else
+    {(int)KS_CAL,	"\033[%dL"},
+#  endif
+    {(int)KS_DL,	"\033[M"},
+#  ifdef TERMINFO
+    {(int)KS_CDL,	"\033[%p1%dM"},
+#  else
+    {(int)KS_CDL,	"\033[%dM"},
+#  endif
+#if 0	/* The scroll region is not working as Vim expects. */
+#  ifdef TERMINFO
+    {(int)KS_CS,	"\033[%i%p1%d;%p2%dr"},
+#  else
+    {(int)KS_CS,	"\033[%i%d;%dr"},
+#  endif
+#endif
+    {(int)KS_CL,	"\033[H\033[2J"},
+    {(int)KS_VE,	"\033[9/y\033[12/y"},	/* These aren't documented */
+    {(int)KS_VS,	"\033[10/y\033[=1h\033[=2l"}, /* These aren't documented */
+    {(int)KS_TI,	"\033[=6h"},
+    {(int)KS_TE,	"\033[=6l"},
+    {(int)KS_SE,	"\033[21;27m"},
+    {(int)KS_SO,	"\033[1;7m"},
+    {(int)KS_ME,	"\033[m"},
+    {(int)KS_MR,	"\033[7m"},
+    {(int)KS_MD,	"\033[1m"},
+    {(int)KS_CCO,	"8"},			/* allow 8 colors */
+    {(int)KS_CZH,	"\033[3m"},		/* italic mode on */
+    {(int)KS_CZR,	"\033[23m"},		/* italic mode off */
+    {(int)KS_US,	"\033[4m"},		/* underline on */
+    {(int)KS_UE,	"\033[24m"},		/* underline off */
+#  ifdef TERMINFO
+    {(int)KS_CAB,	"\033[4%p1%dm"},    /* set background color (ANSI) */
+    {(int)KS_CAF,	"\033[3%p1%dm"},    /* set foreground color (ANSI) */
+    {(int)KS_CSB,	"\033[102;%p1%dm"}, /* set screen background color */
+    {(int)KS_CSF,	"\033[101;%p1%dm"}, /* set screen foreground color */
+#  else
+    {(int)KS_CAB,	"\033[4%dm"},	    /* set background color (ANSI) */
+    {(int)KS_CAF,	"\033[3%dm"},	    /* set foreground color (ANSI) */
+    {(int)KS_CSB,	"\033[102;%dm"},    /* set screen background color */
+    {(int)KS_CSF,	"\033[101;%dm"},    /* set screen foreground color */
+#  endif
+    {(int)KS_MS,	"y"},		/* guessed */
+    {(int)KS_UT,	"y"},		/* guessed */
+    {(int)KS_LE,	"\b"},
+#  ifdef TERMINFO
+    {(int)KS_CM,	"\033[%i%p1%d;%p2%dH"},
+#  else
+    {(int)KS_CM,	"\033[%i%d;%dH"},
+#  endif
+    {(int)KS_SR,	"\033M"},
+#  ifdef TERMINFO
+    {(int)KS_CRI,	"\033[%p1%dC"},
+#  else
+    {(int)KS_CRI,	"\033[%dC"},
+#  endif
+    {(int)KS_CIS,	"\033P3.y"},
+    {(int)KS_CIE,	"\234"},    /* ST "String Terminator" */
+    {(int)KS_TS,	"\033P1.y"},
+    {(int)KS_FS,	"\234"},    /* ST "String Terminator" */
+#  ifdef TERMINFO
+    {(int)KS_CWS,	"\033[203;%p1%d;%p2%d/y"},
+    {(int)KS_CWP,	"\033[205;%p1%d;%p2%d/y"},
+#  else
+    {(int)KS_CWS,	"\033[203;%d;%d/y"},
+    {(int)KS_CWP,	"\033[205;%d;%d/y"},
+#  endif
+    {K_UP,		"\033[A"},
+    {K_DOWN,		"\033[B"},
+    {K_LEFT,		"\033[D"},
+    {K_RIGHT,		"\033[C"},
+    {K_S_UP,		"\033[161q"},
+    {K_S_DOWN,		"\033[164q"},
+    {K_S_LEFT,		"\033[158q"},
+    {K_S_RIGHT,		"\033[167q"},
+    {K_F1,		"\033[001q"},
+    {K_F2,		"\033[002q"},
+    {K_F3,		"\033[003q"},
+    {K_F4,		"\033[004q"},
+    {K_F5,		"\033[005q"},
+    {K_F6,		"\033[006q"},
+    {K_F7,		"\033[007q"},
+    {K_F8,		"\033[008q"},
+    {K_F9,		"\033[009q"},
+    {K_F10,		"\033[010q"},
+    {K_F11,		"\033[011q"},
+    {K_F12,		"\033[012q"},
+    {K_S_F1,		"\033[013q"},
+    {K_S_F2,		"\033[014q"},
+    {K_S_F3,		"\033[015q"},
+    {K_S_F4,		"\033[016q"},
+    {K_S_F5,		"\033[017q"},
+    {K_S_F6,		"\033[018q"},
+    {K_S_F7,		"\033[019q"},
+    {K_S_F8,		"\033[020q"},
+    {K_S_F9,		"\033[021q"},
+    {K_S_F10,		"\033[022q"},
+    {K_S_F11,		"\033[023q"},
+    {K_S_F12,		"\033[024q"},
+    {K_INS,		"\033[139q"},
+    {K_HOME,		"\033[H"},
+    {K_END,		"\033[146q"},
+    {K_PAGEUP,		"\033[150q"},
+    {K_PAGEDOWN,	"\033[154q"},
+# endif
+
+# if defined(PLAN9)
+/*
+ * Plan 9 does not have cursor positioning, this terminal defines
+ * a convenient interface for implementing a virtual terminal.
+ */
+    {(int)KS_NAME,	"plan9"},
+    {(int)KS_CE,	"\033[K"},
+    {(int)KS_AL,	"\033[L"},
+    {(int)KS_CL,	"\033[J"},
+    {(int)KS_ME,	"\033[0m"},	/* normal */
+    {(int)KS_MR,	"\033[1m"},	/* reverse */
+    {(int)KS_MD,	"\033[2m"},	/* bold */
+    {(int)KS_CCO,	"16"},		/* allow 16 colors */
+    {(int)KS_CAB,	"\033[%db"},	/* set background color */
+    {(int)KS_CAF,	"\033[%df"},	/* set foreground color */
+    {(int)KS_MS,	"y"},
+    {(int)KS_UT,	"y"},
+    {(int)KS_LE,	"\b"},		/* cursor left (mostly backspace) */
+    {(int)KS_CM,	"\033[%d;%dH"}, /* cursor motion */
+    {(int)KS_CS,	"\033[%d;%dR"},	/* scroll region */
+#  ifdef FEAT_VERTSPLIT
+    {(int)KS_CSV,	"\033[%d;%dV"},	/* scroll region vertical */
+#  endif
+    {K_UP,          "\xef\x80\xfeX\x8e"},
+    {K_DOWN,        "\xef\xa0\x80\xfeX"},
+    {K_LEFT,        "\xef\x80\xfeX\x91"},
+    {K_RIGHT,       "\xef\x80\xfeX\x92"},
+    {K_HOME,        "\xef\x80\xfeX\x8d"},
+    {K_END,         "\xef\x80\xfeX\x98"},
+    {K_PAGEUP,      "\xef\x80\xfeX\x8f"},
+    {K_PAGEDOWN,    "\xef\x80\xfeX\x93"},
+    {K_INS,         "\xef\x80\xfeX\x94"},
+    /* I couldn't get Plan 9 to report the F1-F12 keys. */
+# endif
+
+# if defined(DEBUG) || defined(ALL_BUILTIN_TCAPS)
+/*
+ * for debugging
+ */
+    {(int)KS_NAME,	"debug"},
+    {(int)KS_CE,	"[CE]"},
+    {(int)KS_CD,	"[CD]"},
+    {(int)KS_AL,	"[AL]"},
+#  ifdef TERMINFO
+    {(int)KS_CAL,	"[CAL%p1%d]"},
+#  else
+    {(int)KS_CAL,	"[CAL%d]"},
+#  endif
+    {(int)KS_DL,	"[DL]"},
+#  ifdef TERMINFO
+    {(int)KS_CDL,	"[CDL%p1%d]"},
+#  else
+    {(int)KS_CDL,	"[CDL%d]"},
+#  endif
+#  ifdef TERMINFO
+    {(int)KS_CS,	"[%p1%dCS%p2%d]"},
+#  else
+    {(int)KS_CS,	"[%dCS%d]"},
+#  endif
+#  ifdef FEAT_VERTSPLIT
+#   ifdef TERMINFO
+    {(int)KS_CSV,	"[%p1%dCSV%p2%d]"},
+#   else
+    {(int)KS_CSV,	"[%dCSV%d]"},
+#   endif
+#  endif
+#  ifdef TERMINFO
+    {(int)KS_CAB,	"[CAB%p1%d]"},
+    {(int)KS_CAF,	"[CAF%p1%d]"},
+    {(int)KS_CSB,	"[CSB%p1%d]"},
+    {(int)KS_CSF,	"[CSF%p1%d]"},
+#  else
+    {(int)KS_CAB,	"[CAB%d]"},
+    {(int)KS_CAF,	"[CAF%d]"},
+    {(int)KS_CSB,	"[CSB%d]"},
+    {(int)KS_CSF,	"[CSF%d]"},
+#  endif
+    {(int)KS_OP,	"[OP]"},
+    {(int)KS_LE,	"[LE]"},
+    {(int)KS_CL,	"[CL]"},
+    {(int)KS_VI,	"[VI]"},
+    {(int)KS_VE,	"[VE]"},
+    {(int)KS_VS,	"[VS]"},
+    {(int)KS_ME,	"[ME]"},
+    {(int)KS_MR,	"[MR]"},
+    {(int)KS_MB,	"[MB]"},
+    {(int)KS_MD,	"[MD]"},
+    {(int)KS_SE,	"[SE]"},
+    {(int)KS_SO,	"[SO]"},
+    {(int)KS_UE,	"[UE]"},
+    {(int)KS_US,	"[US]"},
+    {(int)KS_UCE,	"[UCE]"},
+    {(int)KS_UCS,	"[UCS]"},
+    {(int)KS_MS,	"[MS]"},
+    {(int)KS_UT,	"[UT]"},
+#  ifdef TERMINFO
+    {(int)KS_CM,	"[%p1%dCM%p2%d]"},
+#  else
+    {(int)KS_CM,	"[%dCM%d]"},
+#  endif
+    {(int)KS_SR,	"[SR]"},
+#  ifdef TERMINFO
+    {(int)KS_CRI,	"[CRI%p1%d]"},
+#  else
+    {(int)KS_CRI,	"[CRI%d]"},
+#  endif
+    {(int)KS_VB,	"[VB]"},
+    {(int)KS_KS,	"[KS]"},
+    {(int)KS_KE,	"[KE]"},
+    {(int)KS_TI,	"[TI]"},
+    {(int)KS_TE,	"[TE]"},
+    {(int)KS_CIS,	"[CIS]"},
+    {(int)KS_CIE,	"[CIE]"},
+    {(int)KS_TS,	"[TS]"},
+    {(int)KS_FS,	"[FS]"},
+#  ifdef TERMINFO
+    {(int)KS_CWS,	"[%p1%dCWS%p2%d]"},
+    {(int)KS_CWP,	"[%p1%dCWP%p2%d]"},
+#  else
+    {(int)KS_CWS,	"[%dCWS%d]"},
+    {(int)KS_CWP,	"[%dCWP%d]"},
+#  endif
+    {(int)KS_CRV,	"[CRV]"},
+    {K_UP,		"[KU]"},
+    {K_DOWN,		"[KD]"},
+    {K_LEFT,		"[KL]"},
+    {K_RIGHT,		"[KR]"},
+    {K_XUP,		"[xKU]"},
+    {K_XDOWN,		"[xKD]"},
+    {K_XLEFT,		"[xKL]"},
+    {K_XRIGHT,		"[xKR]"},
+    {K_S_UP,		"[S-KU]"},
+    {K_S_DOWN,		"[S-KD]"},
+    {K_S_LEFT,		"[S-KL]"},
+    {K_C_LEFT,		"[C-KL]"},
+    {K_S_RIGHT,		"[S-KR]"},
+    {K_C_RIGHT,		"[C-KR]"},
+    {K_F1,		"[F1]"},
+    {K_XF1,		"[xF1]"},
+    {K_F2,		"[F2]"},
+    {K_XF2,		"[xF2]"},
+    {K_F3,		"[F3]"},
+    {K_XF3,		"[xF3]"},
+    {K_F4,		"[F4]"},
+    {K_XF4,		"[xF4]"},
+    {K_F5,		"[F5]"},
+    {K_F6,		"[F6]"},
+    {K_F7,		"[F7]"},
+    {K_F8,		"[F8]"},
+    {K_F9,		"[F9]"},
+    {K_F10,		"[F10]"},
+    {K_F11,		"[F11]"},
+    {K_F12,		"[F12]"},
+    {K_S_F1,		"[S-F1]"},
+    {K_S_XF1,		"[S-xF1]"},
+    {K_S_F2,		"[S-F2]"},
+    {K_S_XF2,		"[S-xF2]"},
+    {K_S_F3,		"[S-F3]"},
+    {K_S_XF3,		"[S-xF3]"},
+    {K_S_F4,		"[S-F4]"},
+    {K_S_XF4,		"[S-xF4]"},
+    {K_S_F5,		"[S-F5]"},
+    {K_S_F6,		"[S-F6]"},
+    {K_S_F7,		"[S-F7]"},
+    {K_S_F8,		"[S-F8]"},
+    {K_S_F9,		"[S-F9]"},
+    {K_S_F10,		"[S-F10]"},
+    {K_S_F11,		"[S-F11]"},
+    {K_S_F12,		"[S-F12]"},
+    {K_HELP,		"[HELP]"},
+    {K_UNDO,		"[UNDO]"},
+    {K_BS,		"[BS]"},
+    {K_INS,		"[INS]"},
+    {K_KINS,		"[KINS]"},
+    {K_DEL,		"[DEL]"},
+    {K_KDEL,		"[KDEL]"},
+    {K_HOME,		"[HOME]"},
+    {K_S_HOME,		"[C-HOME]"},
+    {K_C_HOME,		"[C-HOME]"},
+    {K_KHOME,		"[KHOME]"},
+    {K_XHOME,		"[XHOME]"},
+    {K_ZHOME,		"[ZHOME]"},
+    {K_END,		"[END]"},
+    {K_S_END,		"[C-END]"},
+    {K_C_END,		"[C-END]"},
+    {K_KEND,		"[KEND]"},
+    {K_XEND,		"[XEND]"},
+    {K_ZEND,		"[ZEND]"},
+    {K_PAGEUP,		"[PAGEUP]"},
+    {K_PAGEDOWN,	"[PAGEDOWN]"},
+    {K_KPAGEUP,		"[KPAGEUP]"},
+    {K_KPAGEDOWN,	"[KPAGEDOWN]"},
+    {K_MOUSE,		"[MOUSE]"},
+    {K_KPLUS,		"[KPLUS]"},
+    {K_KMINUS,		"[KMINUS]"},
+    {K_KDIVIDE,		"[KDIVIDE]"},
+    {K_KMULTIPLY,	"[KMULTIPLY]"},
+    {K_KENTER,		"[KENTER]"},
+    {K_KPOINT,		"[KPOINT]"},
+    {K_K0,		"[K0]"},
+    {K_K1,		"[K1]"},
+    {K_K2,		"[K2]"},
+    {K_K3,		"[K3]"},
+    {K_K4,		"[K4]"},
+    {K_K5,		"[K5]"},
+    {K_K6,		"[K6]"},
+    {K_K7,		"[K7]"},
+    {K_K8,		"[K8]"},
+    {K_K9,		"[K9]"},
+# endif
+
+#endif /* NO_BUILTIN_TCAPS */
+
+/*
+ * The most minimal terminal: only clear screen and cursor positioning
+ * Always included.
+ */
+    {(int)KS_NAME,	"dumb"},
+    {(int)KS_CL,	"\014"},
+#ifdef TERMINFO
+    {(int)KS_CM,	IF_EB("\033[%i%p1%d;%p2%dH",
+						  ESC_STR "[%i%p1%d;%p2%dH")},
+#else
+    {(int)KS_CM,	IF_EB("\033[%i%d;%dH", ESC_STR "[%i%d;%dH")},
+#endif
+
+/*
+ * end marker
+ */
+    {(int)KS_NAME,	NULL}
+
+};	/* end of builtin_termcaps */
+
+/*
+ * DEFAULT_TERM is used, when no terminal is specified with -T option or $TERM.
+ */
+#ifdef RISCOS
+# define DEFAULT_TERM	(char_u *)"riscos"
+#endif
+
+#ifdef AMIGA
+# define DEFAULT_TERM	(char_u *)"amiga"
+#endif
+
+#ifdef MSWIN
+# define DEFAULT_TERM	(char_u *)"win32"
+#endif
+
+#ifdef MSDOS
+# define DEFAULT_TERM	(char_u *)"pcterm"
+#endif
+
+#if defined(UNIX) && !defined(__MINT__)
+# define DEFAULT_TERM	(char_u *)"ansi"
+#endif
+
+#ifdef __MINT__
+# define DEFAULT_TERM	(char_u *)"vt52"
+#endif
+
+#ifdef __EMX__
+# define DEFAULT_TERM	(char_u *)"os2ansi"
+#endif
+
+#ifdef VMS
+# define DEFAULT_TERM	(char_u *)"vt320"
+#endif
+
+#ifdef __BEOS__
+# undef DEFAULT_TERM
+# define DEFAULT_TERM	(char_u *)"beos-ansi"
+#endif
+
+#ifdef PLAN9
+# define DEFAULT_TERM	(char_u *)"plan9"
+#endif
+
+#ifndef DEFAULT_TERM
+# define DEFAULT_TERM	(char_u *)"dumb"
+#endif
+
+/*
+ * Term_strings contains currently used terminal output strings.
+ * It is initialized with the default values by parse_builtin_tcap().
+ * The values can be changed by setting the option with the same name.
+ */
+char_u *(term_strings[(int)KS_LAST + 1]);
+
+static int	need_gather = FALSE;	    /* need to fill termleader[] */
+static char_u	termleader[256 + 1];	    /* for check_termcode() */
+#ifdef FEAT_TERMRESPONSE
+static int	check_for_codes = FALSE;    /* check for key code response */
+#endif
+
+    static struct builtin_term *
+find_builtin_term(term)
+    char_u	*term;
+{
+    struct builtin_term *p;
+
+    p = builtin_termcaps;
+    while (p->bt_string != NULL)
+    {
+	if (p->bt_entry == (int)KS_NAME)
+	{
+#ifdef UNIX
+	    if (STRCMP(p->bt_string, "iris-ansi") == 0 && vim_is_iris(term))
+		return p;
+	    else if (STRCMP(p->bt_string, "xterm") == 0 && vim_is_xterm(term))
+		return p;
+	    else
+#endif
+#ifdef VMS
+		if (STRCMP(p->bt_string, "vt320") == 0 && vim_is_vt300(term))
+		    return p;
+		else
+#endif
+		  if (STRCMP(term, p->bt_string) == 0)
+		    return p;
+	}
+	++p;
+    }
+    return p;
+}
+
+/*
+ * Parsing of the builtin termcap entries.
+ * Caller should check if 'name' is a valid builtin term.
+ * The terminal's name is not set, as this is already done in termcapinit().
+ */
+    static void
+parse_builtin_tcap(term)
+    char_u  *term;
+{
+    struct builtin_term	    *p;
+    char_u		    name[2];
+    int			    term_8bit;
+
+    p = find_builtin_term(term);
+    term_8bit = term_is_8bit(term);
+
+    /* Do not parse if builtin term not found */
+    if (p->bt_string == NULL)
+	return;
+
+    for (++p; p->bt_entry != (int)KS_NAME && p->bt_entry != BT_EXTRA_KEYS; ++p)
+    {
+	if ((int)p->bt_entry >= 0)	/* KS_xx entry */
+	{
+	    /* Only set the value if it wasn't set yet. */
+	    if (term_strings[p->bt_entry] == NULL
+				 || term_strings[p->bt_entry] == empty_option)
+	    {
+		/* 8bit terminal: use CSI instead of <Esc>[ */
+		if (term_8bit && term_7to8bit((char_u *)p->bt_string) != 0)
+		{
+		    char_u  *s, *t;
+
+		    s = vim_strsave((char_u *)p->bt_string);
+		    if (s != NULL)
+		    {
+			for (t = s; *t; ++t)
+			    if (term_7to8bit(t))
+			    {
+				*t = term_7to8bit(t);
+				STRCPY(t + 1, t + 2);
+			    }
+			term_strings[p->bt_entry] = s;
+			set_term_option_alloced(&term_strings[p->bt_entry]);
+		    }
+		}
+		else
+		    term_strings[p->bt_entry] = (char_u *)p->bt_string;
+	    }
+	}
+	else
+	{
+	    name[0] = KEY2TERMCAP0((int)p->bt_entry);
+	    name[1] = KEY2TERMCAP1((int)p->bt_entry);
+	    if (find_termcode(name) == NULL)
+		add_termcode(name, (char_u *)p->bt_string, term_8bit);
+	}
+    }
+}
+#if defined(HAVE_TGETENT) || defined(FEAT_TERMRESPONSE)
+static void set_color_count __ARGS((int nr));
+
+/*
+ * Set number of colors.
+ * Store it as a number in t_colors.
+ * Store it as a string in T_CCO (using nr_colors[]).
+ */
+    static void
+set_color_count(nr)
+    int		nr;
+{
+    char_u	nr_colors[20];		/* string for number of colors */
+
+    t_colors = nr;
+    if (t_colors > 1)
+	sprintf((char *)nr_colors, "%d", t_colors);
+    else
+	*nr_colors = NUL;
+    set_string_option_direct((char_u *)"t_Co", -1, nr_colors, OPT_FREE, 0);
+}
+#endif
+
+#ifdef HAVE_TGETENT
+static char *(key_names[]) =
+{
+#ifdef FEAT_TERMRESPONSE
+    /* Do this one first, it may cause a screen redraw. */
+    "Co",
+#endif
+    "ku", "kd", "kr", "kl",
+# ifdef ARCHIE
+    "su", "sd",		/* Termcap code made up! */
+# endif
+    "#2", "#4", "%i", "*7",
+    "k1", "k2", "k3", "k4", "k5", "k6",
+    "k7", "k8", "k9", "k;", "F1", "F2",
+    "%1", "&8", "kb", "kI", "kD", "kh",
+    "@7", "kP", "kN", "K1", "K3", "K4", "K5", "kB",
+    NULL
+};
+#endif
+
+/*
+ * Set terminal options for terminal "term".
+ * Return OK if terminal 'term' was found in a termcap, FAIL otherwise.
+ *
+ * While doing this, until ttest(), some options may be NULL, be careful.
+ */
+    int
+set_termname(term)
+    char_u *term;
+{
+    struct builtin_term *termp;
+#ifdef HAVE_TGETENT
+    int		builtin_first = p_tbi;
+    int		try;
+    int		termcap_cleared = FALSE;
+#endif
+    int		width = 0, height = 0;
+    char_u	*error_msg = NULL;
+    char_u	*bs_p, *del_p;
+
+    /* In silect mode (ex -s) we don't use the 'term' option. */
+    if (silent_mode)
+	return OK;
+
+    detected_8bit = FALSE;		/* reset 8-bit detection */
+
+    if (term_is_builtin(term))
+    {
+	term += 8;
+#ifdef HAVE_TGETENT
+	builtin_first = 1;
+#endif
+    }
+
+/*
+ * If HAVE_TGETENT is not defined, only the builtin termcap is used, otherwise:
+ *   If builtin_first is TRUE:
+ *     0. try builtin termcap
+ *     1. try external termcap
+ *     2. if both fail default to a builtin terminal
+ *   If builtin_first is FALSE:
+ *     1. try external termcap
+ *     2. try builtin termcap, if both fail default to a builtin terminal
+ */
+#ifdef HAVE_TGETENT
+    for (try = builtin_first ? 0 : 1; try < 3; ++try)
+    {
+	/*
+	 * Use external termcap
+	 */
+	if (try == 1)
+	{
+	    char_u	    *p;
+	    static char_u   tstrbuf[TBUFSZ];
+	    int		    i;
+	    char_u	    tbuf[TBUFSZ];
+	    char_u	    *tp;
+	    static struct {
+			    enum SpecialKey dest; /* index in term_strings[] */
+			    char *name;		  /* termcap name for string */
+			  } string_names[] =
+			    {	{KS_CE, "ce"}, {KS_AL, "al"}, {KS_CAL,"AL"},
+				{KS_DL, "dl"}, {KS_CDL,"DL"}, {KS_CS, "cs"},
+				{KS_CL, "cl"}, {KS_CD, "cd"},
+				{KS_VI, "vi"}, {KS_VE, "ve"}, {KS_MB, "mb"},
+				{KS_VS, "vs"}, {KS_ME, "me"}, {KS_MR, "mr"},
+				{KS_MD, "md"}, {KS_SE, "se"}, {KS_SO, "so"},
+				{KS_CZH,"ZH"}, {KS_CZR,"ZR"}, {KS_UE, "ue"},
+				{KS_US, "us"}, {KS_UCE, "Ce"}, {KS_UCS, "Cs"},
+				{KS_CM, "cm"}, {KS_SR, "sr"},
+				{KS_CRI,"RI"}, {KS_VB, "vb"}, {KS_KS, "ks"},
+				{KS_KE, "ke"}, {KS_TI, "ti"}, {KS_TE, "te"},
+				{KS_BC, "bc"}, {KS_CSB,"Sb"}, {KS_CSF,"Sf"},
+				{KS_CAB,"AB"}, {KS_CAF,"AF"}, {KS_LE, "le"},
+				{KS_ND, "nd"}, {KS_OP, "op"}, {KS_CRV, "RV"},
+				{KS_CIS, "IS"}, {KS_CIE, "IE"},
+				{KS_TS, "ts"}, {KS_FS, "fs"},
+				{KS_CWP, "WP"}, {KS_CWS, "WS"},
+				{KS_CSI, "SI"}, {KS_CEI, "EI"},
+				{(enum SpecialKey)0, NULL}
+			    };
+
+	    /*
+	     * If the external termcap does not have a matching entry, try the
+	     * builtin ones.
+	     */
+	    if ((error_msg = tgetent_error(tbuf, term)) == NULL)
+	    {
+		tp = tstrbuf;
+		if (!termcap_cleared)
+		{
+		    clear_termoptions();	/* clear old options */
+		    termcap_cleared = TRUE;
+		}
+
+	    /* get output strings */
+		for (i = 0; string_names[i].name != NULL; ++i)
+		{
+		    if (term_str(string_names[i].dest) == NULL
+			    || term_str(string_names[i].dest) == empty_option)
+			term_str(string_names[i].dest) =
+					   TGETSTR(string_names[i].name, &tp);
+		}
+
+		/* tgetflag() returns 1 if the flag is present, 0 if not and
+		 * possibly -1 if the flag doesn't exist. */
+		if ((T_MS == NULL || T_MS == empty_option)
+							&& tgetflag("ms") > 0)
+		    T_MS = (char_u *)"y";
+		if ((T_XS == NULL || T_XS == empty_option)
+							&& tgetflag("xs") > 0)
+		    T_XS = (char_u *)"y";
+		if ((T_DB == NULL || T_DB == empty_option)
+							&& tgetflag("db") > 0)
+		    T_DB = (char_u *)"y";
+		if ((T_DA == NULL || T_DA == empty_option)
+							&& tgetflag("da") > 0)
+		    T_DA = (char_u *)"y";
+		if ((T_UT == NULL || T_UT == empty_option)
+							&& tgetflag("ut") > 0)
+		    T_UT = (char_u *)"y";
+
+
+		/*
+		 * get key codes
+		 */
+		for (i = 0; key_names[i] != NULL; ++i)
+		{
+		    if (find_termcode((char_u *)key_names[i]) == NULL)
+		    {
+			p = TGETSTR(key_names[i], &tp);
+			/* if cursor-left == backspace, ignore it (televideo
+			 * 925) */
+			if (p != NULL
+				&& (*p != Ctrl_H
+				    || key_names[i][0] != 'k'
+				    || key_names[i][1] != 'l'))
+			    add_termcode((char_u *)key_names[i], p, FALSE);
+		    }
+		}
+
+		if (height == 0)
+		    height = tgetnum("li");
+		if (width == 0)
+		    width = tgetnum("co");
+
+		/*
+		 * Get number of colors (if not done already).
+		 */
+		if (term_str(KS_CCO) == NULL
+			|| term_str(KS_CCO) == empty_option)
+		    set_color_count(tgetnum("Co"));
+
+# ifndef hpux
+		BC = (char *)TGETSTR("bc", &tp);
+		UP = (char *)TGETSTR("up", &tp);
+		p = TGETSTR("pc", &tp);
+		if (p)
+		    PC = *p;
+# endif /* hpux */
+	    }
+	}
+	else	    /* try == 0 || try == 2 */
+#endif /* HAVE_TGETENT */
+	/*
+	 * Use builtin termcap
+	 */
+	{
+#ifdef HAVE_TGETENT
+	    /*
+	     * If builtin termcap was already used, there is no need to search
+	     * for the builtin termcap again, quit now.
+	     */
+	    if (try == 2 && builtin_first && termcap_cleared)
+		break;
+#endif
+	    /*
+	     * search for 'term' in builtin_termcaps[]
+	     */
+	    termp = find_builtin_term(term);
+	    if (termp->bt_string == NULL)	/* did not find it */
+	    {
+#ifdef HAVE_TGETENT
+		/*
+		 * If try == 0, first try the external termcap. If that is not
+		 * found we'll get back here with try == 2.
+		 * If termcap_cleared is set we used the external termcap,
+		 * don't complain about not finding the term in the builtin
+		 * termcap.
+		 */
+		if (try == 0)			/* try external one */
+		    continue;
+		if (termcap_cleared)		/* found in external termcap */
+		    break;
+#endif
+
+		mch_errmsg("\r\n");
+		if (error_msg != NULL)
+		{
+		    mch_errmsg((char *)error_msg);
+		    mch_errmsg("\r\n");
+		}
+		mch_errmsg("'");
+		mch_errmsg((char *)term);
+		mch_errmsg(_("' not known. Available builtin terminals are:"));
+		mch_errmsg("\r\n");
+		for (termp = &(builtin_termcaps[0]); termp->bt_string != NULL;
+								      ++termp)
+		{
+		    if (termp->bt_entry == (int)KS_NAME)
+		    {
+#ifdef HAVE_TGETENT
+			mch_errmsg("    builtin_");
+#else
+			mch_errmsg("    ");
+#endif
+			mch_errmsg(termp->bt_string);
+			mch_errmsg("\r\n");
+		    }
+		}
+		/* when user typed :set term=xxx, quit here */
+		if (starting != NO_SCREEN)
+		{
+		    screen_start();	/* don't know where cursor is now */
+		    wait_return(TRUE);
+		    return FAIL;
+		}
+		term = DEFAULT_TERM;
+		mch_errmsg(_("defaulting to '"));
+		mch_errmsg((char *)term);
+		mch_errmsg("'\r\n");
+		if (emsg_silent == 0)
+		{
+		    screen_start();	/* don't know where cursor is now */
+		    out_flush();
+		    ui_delay(2000L, TRUE);
+		}
+		set_string_option_direct((char_u *)"term", -1, term,
+								 OPT_FREE, 0);
+		display_errors();
+	    }
+	    out_flush();
+#ifdef HAVE_TGETENT
+	    if (!termcap_cleared)
+	    {
+#endif
+		clear_termoptions();	    /* clear old options */
+#ifdef HAVE_TGETENT
+		termcap_cleared = TRUE;
+	    }
+#endif
+	    parse_builtin_tcap(term);
+#ifdef FEAT_GUI
+	    if (term_is_gui(term))
+	    {
+		out_flush();
+		gui_init();
+		/* If starting the GUI failed, don't do any of the other
+		 * things for this terminal */
+		if (!gui.in_use)
+		    return FAIL;
+#ifdef HAVE_TGETENT
+		break;		/* don't try using external termcap */
+#endif
+	    }
+#endif /* FEAT_GUI */
+	}
+#ifdef HAVE_TGETENT
+    }
+#endif
+
+/*
+ * special: There is no info in the termcap about whether the cursor
+ * positioning is relative to the start of the screen or to the start of the
+ * scrolling region.  We just guess here. Only msdos pcterm is known to do it
+ * relative.
+ */
+    if (STRCMP(term, "pcterm") == 0)
+	T_CCS = (char_u *)"yes";
+    else
+	T_CCS = empty_option;
+
+#ifdef UNIX
+/*
+ * Any "stty" settings override the default for t_kb from the termcap.
+ * This is in os_unix.c, because it depends a lot on the version of unix that
+ * is being used.
+ * Don't do this when the GUI is active, it uses "t_kb" and "t_kD" directly.
+ */
+#ifdef FEAT_GUI
+    if (!gui.in_use)
+#endif
+	get_stty();
+#endif
+
+/*
+ * If the termcap has no entry for 'bs' and/or 'del' and the ioctl() also
+ * didn't work, use the default CTRL-H
+ * The default for t_kD is DEL, unless t_kb is DEL.
+ * The vim_strsave'd strings are probably lost forever, well it's only two
+ * bytes.  Don't do this when the GUI is active, it uses "t_kb" and "t_kD"
+ * directly.
+ */
+#ifdef FEAT_GUI
+    if (!gui.in_use)
+#endif
+    {
+	bs_p = find_termcode((char_u *)"kb");
+	del_p = find_termcode((char_u *)"kD");
+	if (bs_p == NULL || *bs_p == NUL)
+	    add_termcode((char_u *)"kb", (bs_p = (char_u *)CTRL_H_STR), FALSE);
+	if ((del_p == NULL || *del_p == NUL) &&
+					    (bs_p == NULL || *bs_p != DEL))
+	    add_termcode((char_u *)"kD", (char_u *)DEL_STR, FALSE);
+    }
+
+#if defined(UNIX) || defined(VMS)
+    term_is_xterm = vim_is_xterm(term);
+#endif
+
+#ifdef FEAT_MOUSE
+# if defined(UNIX) || defined(VMS)
+#  ifdef FEAT_MOUSE_TTY
+    /*
+     * For Unix, set the 'ttymouse' option to the type of mouse to be used.
+     * The termcode for the mouse is added as a side effect in option.c.
+     */
+    {
+	char_u	*p;
+
+	p = (char_u *)"";
+#  ifdef FEAT_MOUSE_XTERM
+#   ifdef FEAT_CLIPBOARD
+#    ifdef FEAT_GUI
+	if (!gui.in_use)
+#    endif
+	    clip_init(FALSE);
+#   endif
+	if (term_is_xterm)
+	{
+	    if (use_xterm_mouse())
+		p = NULL;	/* keep existing value, might be "xterm2" */
+	    else
+		p = (char_u *)"xterm";
+	}
+#  endif
+	if (p != NULL)
+	    set_option_value((char_u *)"ttym", 0L, p, 0);
+	if (p == NULL
+#   ifdef FEAT_GUI
+		|| gui.in_use
+#   endif
+		)
+	    check_mouse_termcode();	/* set mouse termcode anyway */
+    }
+#  endif
+# else
+    set_mouse_termcode(KS_MOUSE, (char_u *)"\233M");
+# endif
+#endif	/* FEAT_MOUSE */
+
+#ifdef FEAT_SNIFF
+    {
+	char_u	name[2];
+
+	name[0] = (int)KS_EXTRA;
+	name[1] = (int)KE_SNIFF;
+	add_termcode(name, (char_u *)"\233sniff", FALSE);
+    }
+#endif
+
+#ifdef USE_TERM_CONSOLE
+    /* DEFAULT_TERM indicates that it is the machine console. */
+    if (STRCMP(term, DEFAULT_TERM) != 0)
+	term_console = FALSE;
+    else
+    {
+	term_console = TRUE;
+# ifdef AMIGA
+	win_resize_on();	/* enable window resizing reports */
+# endif
+    }
+#endif
+
+#if defined(UNIX) || defined(VMS)
+    /*
+     * 'ttyfast' is default on for xterm, iris-ansi and a few others.
+     */
+    if (vim_is_fastterm(term))
+	p_tf = TRUE;
+#endif
+#ifdef USE_TERM_CONSOLE
+    /*
+     * 'ttyfast' is default on consoles
+     */
+    if (term_console)
+	p_tf = TRUE;
+#endif
+
+    ttest(TRUE);	/* make sure we have a valid set of terminal codes */
+
+    full_screen = TRUE;		/* we can use termcap codes from now on */
+    set_term_defaults();	/* use current values as defaults */
+#ifdef FEAT_TERMRESPONSE
+    crv_status = CRV_GET;	/* Get terminal version later */
+#endif
+
+    /*
+     * Initialize the terminal with the appropriate termcap codes.
+     * Set the mouse and window title if possible.
+     * Don't do this when starting, need to parse the .vimrc first, because it
+     * may redefine t_TI etc.
+     */
+    if (starting != NO_SCREEN)
+    {
+	starttermcap();		/* may change terminal mode */
+#ifdef FEAT_MOUSE
+	setmouse();		/* may start using the mouse */
+#endif
+#ifdef FEAT_TITLE
+	maketitle();		/* may display window title */
+#endif
+    }
+
+	/* display initial screen after ttest() checking. jw. */
+    if (width <= 0 || height <= 0)
+    {
+	/* termcap failed to report size */
+	/* set defaults, in case ui_get_shellsize() also fails */
+	width = 80;
+#if defined(MSDOS) || defined(WIN3264)
+	height = 25;	    /* console is often 25 lines */
+#else
+	height = 24;	    /* most terminals are 24 lines */
+#endif
+    }
+    set_shellsize(width, height, FALSE);	/* may change Rows */
+    if (starting != NO_SCREEN)
+    {
+	if (scroll_region)
+	    scroll_region_reset();		/* In case Rows changed */
+	check_map_keycodes();	/* check mappings for terminal codes used */
+
+#ifdef FEAT_AUTOCMD
+	{
+	    buf_T	*old_curbuf;
+
+	    /*
+	     * Execute the TermChanged autocommands for each buffer that is
+	     * loaded.
+	     */
+	    old_curbuf = curbuf;
+	    for (curbuf = firstbuf; curbuf != NULL; curbuf = curbuf->b_next)
+	    {
+		if (curbuf->b_ml.ml_mfp != NULL)
+		    apply_autocmds(EVENT_TERMCHANGED, NULL, NULL, FALSE,
+								      curbuf);
+	    }
+	    if (buf_valid(old_curbuf))
+		curbuf = old_curbuf;
+	}
+#endif
+    }
+
+#ifdef FEAT_TERMRESPONSE
+    may_req_termresponse();
+#endif
+
+    return OK;
+}
+
+#if defined(FEAT_MOUSE) || defined(PROTO)
+
+# ifdef FEAT_MOUSE_TTY
+#  define HMT_NORMAL	1
+#  define HMT_NETTERM	2
+#  define HMT_DEC	4
+#  define HMT_JSBTERM	8
+#  define HMT_PTERM	16
+static int has_mouse_termcode = 0;
+# endif
+
+# if (!defined(UNIX) || defined(FEAT_MOUSE_XTERM) || defined(FEAT_MOUSE_NET) \
+	|| defined(FEAT_MOUSE_DEC)) || defined(FEAT_MOUSE_JSB) \
+	|| defined(FEAT_MOUSE_PTERM) || defined(PROTO)
+    void
+set_mouse_termcode(n, s)
+    int		n;	/* KS_MOUSE, KS_NETTERM_MOUSE or KS_DEC_MOUSE */
+    char_u	*s;
+{
+    char_u	name[2];
+
+    name[0] = n;
+    name[1] = KE_FILLER;
+    add_termcode(name, s, FALSE);
+#  ifdef FEAT_MOUSE_TTY
+#   ifdef FEAT_MOUSE_JSB
+    if (n == KS_JSBTERM_MOUSE)
+	has_mouse_termcode |= HMT_JSBTERM;
+    else
+#   endif
+#   ifdef FEAT_MOUSE_NET
+    if (n == KS_NETTERM_MOUSE)
+	has_mouse_termcode |= HMT_NETTERM;
+    else
+#   endif
+#   ifdef FEAT_MOUSE_DEC
+    if (n == KS_DEC_MOUSE)
+	has_mouse_termcode |= HMT_DEC;
+    else
+#   endif
+#   ifdef FEAT_MOUSE_PTERM
+    if (n == KS_PTERM_MOUSE)
+	has_mouse_termcode |= HMT_PTERM;
+    else
+#   endif
+	has_mouse_termcode |= HMT_NORMAL;
+#  endif
+}
+# endif
+
+# if ((defined(UNIX) || defined(VMS) || defined(OS2)) \
+	&& (defined(FEAT_MOUSE_XTERM) || defined(FEAT_MOUSE_DEC) \
+	    || defined(FEAT_MOUSE_GPM) || defined(FEAT_MOUSE_PTERM))) \
+	    || defined(PROTO)
+    void
+del_mouse_termcode(n)
+    int		n;	/* KS_MOUSE, KS_NETTERM_MOUSE or KS_DEC_MOUSE */
+{
+    char_u	name[2];
+
+    name[0] = n;
+    name[1] = KE_FILLER;
+    del_termcode(name);
+#  ifdef FEAT_MOUSE_TTY
+#   ifdef FEAT_MOUSE_JSB
+    if (n == KS_JSBTERM_MOUSE)
+	has_mouse_termcode &= ~HMT_JSBTERM;
+    else
+#   endif
+#   ifdef FEAT_MOUSE_NET
+    if (n == KS_NETTERM_MOUSE)
+	has_mouse_termcode &= ~HMT_NETTERM;
+    else
+#   endif
+#   ifdef FEAT_MOUSE_DEC
+    if (n == KS_DEC_MOUSE)
+	has_mouse_termcode &= ~HMT_DEC;
+    else
+#   endif
+#   ifdef FEAT_MOUSE_PTERM
+    if (n == KS_PTERM_MOUSE)
+	has_mouse_termcode &= ~HMT_PTERM;
+    else
+#   endif
+	has_mouse_termcode &= ~HMT_NORMAL;
+#  endif
+}
+# endif
+#endif
+
+#ifdef HAVE_TGETENT
+/*
+ * Call tgetent()
+ * Return error message if it fails, NULL if it's OK.
+ */
+    static char_u *
+tgetent_error(tbuf, term)
+    char_u  *tbuf;
+    char_u  *term;
+{
+    int	    i;
+
+    i = TGETENT(tbuf, term);
+    if (i < 0		    /* -1 is always an error */
+# ifdef TGETENT_ZERO_ERR
+	    || i == 0	    /* sometimes zero is also an error */
+# endif
+       )
+    {
+	/* On FreeBSD tputs() gets a SEGV after a tgetent() which fails.  Call
+	 * tgetent() with the always existing "dumb" entry to avoid a crash or
+	 * hang. */
+	(void)TGETENT(tbuf, "dumb");
+
+	if (i < 0)
+# ifdef TGETENT_ZERO_ERR
+	    return (char_u *)_("E557: Cannot open termcap file");
+	if (i == 0)
+# endif
+#ifdef TERMINFO
+	    return (char_u *)_("E558: Terminal entry not found in terminfo");
+#else
+	    return (char_u *)_("E559: Terminal entry not found in termcap");
+#endif
+    }
+    return NULL;
+}
+
+/*
+ * Some versions of tgetstr() have been reported to return -1 instead of NULL.
+ * Fix that here.
+ */
+    static char_u *
+vim_tgetstr(s, pp)
+    char	*s;
+    char_u	**pp;
+{
+    char	*p;
+
+    p = tgetstr(s, (char **)pp);
+    if (p == (char *)-1)
+	p = NULL;
+    return (char_u *)p;
+}
+#endif /* HAVE_TGETENT */
+
+#if defined(HAVE_TGETENT) && (defined(UNIX) || defined(__EMX__) || defined(VMS) || defined(MACOS_X))
+/*
+ * Get Columns and Rows from the termcap. Used after a window signal if the
+ * ioctl() fails. It doesn't make sense to call tgetent each time if the "co"
+ * and "li" entries never change. But on some systems this works.
+ * Errors while getting the entries are ignored.
+ */
+    void
+getlinecol(cp, rp)
+    long	*cp;	/* pointer to columns */
+    long	*rp;	/* pointer to rows */
+{
+    char_u	tbuf[TBUFSZ];
+
+    if (T_NAME != NULL && *T_NAME != NUL && tgetent_error(tbuf, T_NAME) == NULL)
+    {
+	if (*cp == 0)
+	    *cp = tgetnum("co");
+	if (*rp == 0)
+	    *rp = tgetnum("li");
+    }
+}
+#endif /* defined(HAVE_TGETENT) && defined(UNIX) */
+
+/*
+ * Get a string entry from the termcap and add it to the list of termcodes.
+ * Used for <t_xx> special keys.
+ * Give an error message for failure when not sourcing.
+ * If force given, replace an existing entry.
+ * Return FAIL if the entry was not found, OK if the entry was added.
+ */
+    int
+add_termcap_entry(name, force)
+    char_u  *name;
+    int	    force;
+{
+    char_u  *term;
+    int	    key;
+    struct builtin_term *termp;
+#ifdef HAVE_TGETENT
+    char_u  *string;
+    int	    i;
+    int	    builtin_first;
+    char_u  tbuf[TBUFSZ];
+    char_u  tstrbuf[TBUFSZ];
+    char_u  *tp = tstrbuf;
+    char_u  *error_msg = NULL;
+#endif
+
+/*
+ * If the GUI is running or will start in a moment, we only support the keys
+ * that the GUI can produce.
+ */
+#ifdef FEAT_GUI
+    if (gui.in_use || gui.starting)
+	return gui_mch_haskey(name);
+#endif
+
+    if (!force && find_termcode(name) != NULL)	    /* it's already there */
+	return OK;
+
+    term = T_NAME;
+    if (term == NULL || *term == NUL)	    /* 'term' not defined yet */
+	return FAIL;
+
+    if (term_is_builtin(term))		    /* name starts with "builtin_" */
+    {
+	term += 8;
+#ifdef HAVE_TGETENT
+	builtin_first = TRUE;
+#endif
+    }
+#ifdef HAVE_TGETENT
+    else
+	builtin_first = p_tbi;
+#endif
+
+#ifdef HAVE_TGETENT
+/*
+ * We can get the entry from the builtin termcap and from the external one.
+ * If 'ttybuiltin' is on or the terminal name starts with "builtin_", try
+ * builtin termcap first.
+ * If 'ttybuiltin' is off, try external termcap first.
+ */
+    for (i = 0; i < 2; ++i)
+    {
+	if (!builtin_first == i)
+#endif
+	/*
+	 * Search in builtin termcap
+	 */
+	{
+	    termp = find_builtin_term(term);
+	    if (termp->bt_string != NULL)	/* found it */
+	    {
+		key = TERMCAP2KEY(name[0], name[1]);
+		while (termp->bt_entry != (int)KS_NAME)
+		{
+		    if ((int)termp->bt_entry == key)
+		    {
+			add_termcode(name, (char_u *)termp->bt_string,
+							  term_is_8bit(term));
+			return OK;
+		    }
+		    ++termp;
+		}
+	    }
+	}
+#ifdef HAVE_TGETENT
+	else
+	/*
+	 * Search in external termcap
+	 */
+	{
+	    error_msg = tgetent_error(tbuf, term);
+	    if (error_msg == NULL)
+	    {
+		string = TGETSTR((char *)name, &tp);
+		if (string != NULL && *string != NUL)
+		{
+		    add_termcode(name, string, FALSE);
+		    return OK;
+		}
+	    }
+	}
+    }
+#endif
+
+    if (sourcing_name == NULL)
+    {
+#ifdef HAVE_TGETENT
+	if (error_msg != NULL)
+	    EMSG(error_msg);
+	else
+#endif
+	    EMSG2(_("E436: No \"%s\" entry in termcap"), name);
+    }
+    return FAIL;
+}
+
+    static int
+term_is_builtin(name)
+    char_u  *name;
+{
+    return (STRNCMP(name, "builtin_", (size_t)8) == 0);
+}
+
+/*
+ * Return TRUE if terminal "name" uses CSI instead of <Esc>[.
+ * Assume that the terminal is using 8-bit controls when the name contains
+ * "8bit", like in "xterm-8bit".
+ */
+    int
+term_is_8bit(name)
+    char_u  *name;
+{
+    return (detected_8bit || strstr((char *)name, "8bit") != NULL);
+}
+
+/*
+ * Translate terminal control chars from 7-bit to 8-bit:
+ * <Esc>[ -> CSI
+ * <Esc>] -> <M-C-]>
+ * <Esc>O -> <M-C-O>
+ */
+    static int
+term_7to8bit(p)
+    char_u  *p;
+{
+    if (*p == ESC)
+    {
+	if (p[1] == '[')
+	    return CSI;
+	if (p[1] == ']')
+	    return 0x9d;
+	if (p[1] == 'O')
+	    return 0x8f;
+    }
+    return 0;
+}
+
+#ifdef FEAT_GUI
+    int
+term_is_gui(name)
+    char_u  *name;
+{
+    return (STRCMP(name, "builtin_gui") == 0 || STRCMP(name, "gui") == 0);
+}
+#endif
+
+#if !defined(HAVE_TGETENT) || defined(AMIGA) || defined(PROTO)
+
+    char_u *
+tltoa(i)
+    unsigned long i;
+{
+    static char_u buf[16];
+    char_u	*p;
+
+    p = buf + 15;
+    *p = '\0';
+    do
+    {
+	--p;
+	*p = (char_u) (i % 10 + '0');
+	i /= 10;
+    }
+    while (i > 0 && p > buf);
+    return p;
+}
+#endif
+
+#ifndef HAVE_TGETENT
+
+/*
+ * minimal tgoto() implementation.
+ * no padding and we only parse for %i %d and %+char
+ */
+static char *tgoto __ARGS((char *, int, int));
+
+    static char *
+tgoto(cm, x, y)
+    char *cm;
+    int x, y;
+{
+    static char buf[30];
+    char *p, *s, *e;
+
+    if (!cm)
+	return "OOPS";
+    e = buf + 29;
+    for (s = buf; s < e && *cm; cm++)
+    {
+	if (*cm != '%')
+	{
+	    *s++ = *cm;
+	    continue;
+	}
+	switch (*++cm)
+	{
+	case 'd':
+	    p = (char *)tltoa((unsigned long)y);
+	    y = x;
+	    while (*p)
+		*s++ = *p++;
+	    break;
+	case 'i':
+	    x++;
+	    y++;
+	    break;
+	case '+':
+	    *s++ = (char)(*++cm + y);
+	    y = x;
+	    break;
+	case '%':
+	    *s++ = *cm;
+	    break;
+	default:
+	    return "OOPS";
+	}
+    }
+    *s = '\0';
+    return buf;
+}
+
+#endif /* HAVE_TGETENT */
+
+/*
+ * Set the terminal name and initialize the terminal options.
+ * If "name" is NULL or empty, get the terminal name from the environment.
+ * If that fails, use the default terminal name.
+ */
+    void
+termcapinit(name)
+    char_u *name;
+{
+    char_u	*term;
+
+    if (name != NULL && *name == NUL)
+	name = NULL;	    /* empty name is equal to no name */
+    term = name;
+
+#ifdef __BEOS__
+    /*
+     * TERM environment variable is normally set to 'ansi' on the Bebox;
+     * Since the BeBox doesn't quite support full ANSI yet, we use our
+     * own custom 'ansi-beos' termcap instead, unless the -T option has
+     * been given on the command line.
+     */
+    if (term == NULL
+		 && strcmp((char *)mch_getenv((char_u *)"TERM"), "ansi") == 0)
+	term = DEFAULT_TERM;
+#endif
+#ifndef MSWIN
+    if (term == NULL)
+	term = mch_getenv((char_u *)"TERM");
+#endif
+    if (term == NULL || *term == NUL)
+	term = DEFAULT_TERM;
+    set_string_option_direct((char_u *)"term", -1, term, OPT_FREE, 0);
+
+    /* Set the default terminal name. */
+    set_string_default("term", term);
+    set_string_default("ttytype", term);
+
+    /*
+     * Avoid using "term" here, because the next mch_getenv() may overwrite it.
+     */
+    set_termname(T_NAME != NULL ? T_NAME : term);
+}
+
+/*
+ * the number of calls to ui_write is reduced by using the buffer "out_buf"
+ */
+#ifdef DOS16
+# define OUT_SIZE	255		/* only have 640K total... */
+#else
+# ifdef FEAT_GUI_W16
+#  define OUT_SIZE	1023		/* Save precious 1K near data */
+# else
+#  define OUT_SIZE	2047
+# endif
+#endif
+	    /* Add one to allow mch_write() in os_win32.c to append a NUL */
+static char_u		out_buf[OUT_SIZE + 1];
+static int		out_pos = 0;	/* number of chars in out_buf */
+
+/*
+ * out_flush(): flush the output buffer
+ */
+    void
+out_flush()
+{
+    int	    len;
+
+    if (out_pos != 0)
+    {
+	/* set out_pos to 0 before ui_write, to avoid recursiveness */
+	len = out_pos;
+	out_pos = 0;
+	ui_write(out_buf, len);
+    }
+}
+
+#if defined(FEAT_MBYTE) || defined(PROTO)
+/*
+ * Sometimes a byte out of a multi-byte character is written with out_char().
+ * To avoid flushing half of the character, call this function first.
+ */
+    void
+out_flush_check()
+{
+    if (enc_dbcs != 0 && out_pos >= OUT_SIZE - MB_MAXBYTES)
+	out_flush();
+}
+#endif
+
+#ifdef FEAT_GUI
+/*
+ * out_trash(): Throw away the contents of the output buffer
+ */
+    void
+out_trash()
+{
+    out_pos = 0;
+}
+#endif
+
+/*
+ * out_char(c): put a byte into the output buffer.
+ *		Flush it if it becomes full.
+ * This should not be used for outputting text on the screen (use functions
+ * like msg_puts() and screen_putchar() for that).
+ */
+    void
+out_char(c)
+    unsigned	c;
+{
+#if defined(UNIX) || defined(VMS) || defined(AMIGA) || defined(MACOS_X_UNIX)
+    if (c == '\n')	/* turn LF into CR-LF (CRMOD doesn't seem to do this) */
+	out_char('\r');
+#endif
+
+    out_buf[out_pos++] = c;
+
+    /* For testing we flush each time. */
+    if (out_pos >= OUT_SIZE || p_wd)
+	out_flush();
+}
+
+static void out_char_nf __ARGS((unsigned));
+
+/*
+ * out_char_nf(c): like out_char(), but don't flush when p_wd is set
+ */
+    static void
+out_char_nf(c)
+    unsigned	c;
+{
+#if defined(UNIX) || defined(VMS) || defined(AMIGA) || defined(MACOS_X_UNIX)
+    if (c == '\n')	/* turn LF into CR-LF (CRMOD doesn't seem to do this) */
+	out_char_nf('\r');
+#endif
+
+    out_buf[out_pos++] = c;
+
+    if (out_pos >= OUT_SIZE)
+	out_flush();
+}
+
+/*
+ * A never-padding out_str.
+ * use this whenever you don't want to run the string through tputs.
+ * tputs above is harmless, but tputs from the termcap library
+ * is likely to strip off leading digits, that it mistakes for padding
+ * information, and "%i", "%d", etc.
+ * This should only be used for writing terminal codes, not for outputting
+ * normal text (use functions like msg_puts() and screen_putchar() for that).
+ */
+    void
+out_str_nf(s)
+    char_u *s;
+{
+    if (out_pos > OUT_SIZE - 20)  /* avoid terminal strings being split up */
+	out_flush();
+    while (*s)
+	out_char_nf(*s++);
+
+    /* For testing we write one string at a time. */
+    if (p_wd)
+	out_flush();
+}
+
+/*
+ * out_str(s): Put a character string a byte at a time into the output buffer.
+ * If HAVE_TGETENT is defined use the termcap parser. (jw)
+ * This should only be used for writing terminal codes, not for outputting
+ * normal text (use functions like msg_puts() and screen_putchar() for that).
+ */
+    void
+out_str(s)
+    char_u	 *s;
+{
+    if (s != NULL && *s)
+    {
+#ifdef FEAT_GUI
+	/* Don't use tputs() when GUI is used, ncurses crashes. */
+	if (gui.in_use)
+	{
+	    out_str_nf(s);
+	    return;
+	}
+#endif
+	/* avoid terminal strings being split up */
+	if (out_pos > OUT_SIZE - 20)
+	    out_flush();
+#ifdef HAVE_TGETENT
+	tputs((char *)s, 1, TPUTSFUNCAST out_char_nf);
+#else
+	while (*s)
+	    out_char_nf(*s++);
+#endif
+
+	/* For testing we write one string at a time. */
+	if (p_wd)
+	    out_flush();
+    }
+}
+
+/*
+ * cursor positioning using termcap parser. (jw)
+ */
+    void
+term_windgoto(row, col)
+    int	    row;
+    int	    col;
+{
+    OUT_STR(tgoto((char *)T_CM, col, row));
+}
+
+    void
+term_cursor_right(i)
+    int	    i;
+{
+    OUT_STR(tgoto((char *)T_CRI, 0, i));
+}
+
+    void
+term_append_lines(line_count)
+    int	    line_count;
+{
+    OUT_STR(tgoto((char *)T_CAL, 0, line_count));
+}
+
+    void
+term_delete_lines(line_count)
+    int	    line_count;
+{
+    OUT_STR(tgoto((char *)T_CDL, 0, line_count));
+}
+
+#if defined(HAVE_TGETENT) || defined(PROTO)
+    void
+term_set_winpos(x, y)
+    int	    x;
+    int	    y;
+{
+    /* Can't handle a negative value here */
+    if (x < 0)
+	x = 0;
+    if (y < 0)
+	y = 0;
+    OUT_STR(tgoto((char *)T_CWP, y, x));
+}
+
+    void
+term_set_winsize(width, height)
+    int	    width;
+    int	    height;
+{
+    OUT_STR(tgoto((char *)T_CWS, height, width));
+}
+#endif
+
+    void
+term_fg_color(n)
+    int	    n;
+{
+    /* Use "AF" termcap entry if present, "Sf" entry otherwise */
+    if (*T_CAF)
+	term_color(T_CAF, n);
+    else if (*T_CSF)
+	term_color(T_CSF, n);
+}
+
+    void
+term_bg_color(n)
+    int	    n;
+{
+    /* Use "AB" termcap entry if present, "Sb" entry otherwise */
+    if (*T_CAB)
+	term_color(T_CAB, n);
+    else if (*T_CSB)
+	term_color(T_CSB, n);
+}
+
+    static void
+term_color(s, n)
+    char_u	*s;
+    int		n;
+{
+    char	buf[20];
+    int i = 2;	/* index in s[] just after <Esc>[ or CSI */
+
+    /* Special handling of 16 colors, because termcap can't handle it */
+    /* Also accept "\e[3%dm" for TERMINFO, it is sometimes used */
+    /* Also accept CSI instead of <Esc>[ */
+    if (n >= 8 && t_colors >= 16
+	      && ((s[0] == ESC && s[1] == '[') || (s[0] == CSI && (i = 1) == 1))
+	      && s[i] != NUL
+	      && (STRCMP(s + i + 1, "%p1%dm") == 0
+		  || STRCMP(s + i + 1, "%dm") == 0)
+	      && (s[i] == '3' || s[i] == '4'))
+    {
+	sprintf(buf,
+#ifdef TERMINFO
+		"%s%s%%p1%%dm",
+#else
+		"%s%s%%dm",
+#endif
+		i == 2 ? IF_EB("\033[", ESC_STR "[") : "\233",
+		s[i] == '3' ? (n >= 16 ? "38;5;" : "9")
+			    : (n >= 16 ? "48;5;" : "10"));
+	OUT_STR(tgoto(buf, 0, n >= 16 ? n : n - 8));
+    }
+    else
+	OUT_STR(tgoto((char *)s, 0, n));
+}
+
+#if (defined(FEAT_TITLE) && (defined(UNIX) || defined(OS2) || defined(VMS) || defined(MACOS_X))) || defined(PROTO)
+/*
+ * Generic function to set window title, using t_ts and t_fs.
+ */
+    void
+term_settitle(title)
+    char_u	*title;
+{
+    /* t_ts takes one argument: column in status line */
+    OUT_STR(tgoto((char *)T_TS, 0, 0));	/* set title start */
+    out_str_nf(title);
+    out_str(T_FS);			/* set title end */
+    out_flush();
+}
+#endif
+
+/*
+ * Make sure we have a valid set or terminal options.
+ * Replace all entries that are NULL by empty_option
+ */
+    void
+ttest(pairs)
+    int	pairs;
+{
+    check_options();		    /* make sure no options are NULL */
+
+    /*
+     * MUST have "cm": cursor motion.
+     */
+    if (*T_CM == NUL)
+	EMSG(_("E437: terminal capability \"cm\" required"));
+
+    /*
+     * if "cs" defined, use a scroll region, it's faster.
+     */
+    if (*T_CS != NUL)
+	scroll_region = TRUE;
+    else
+	scroll_region = FALSE;
+
+    if (pairs)
+    {
+	/*
+	 * optional pairs
+	 */
+	/* TP goes to normal mode for TI (invert) and TB (bold) */
+	if (*T_ME == NUL)
+	    T_ME = T_MR = T_MD = T_MB = empty_option;
+	if (*T_SO == NUL || *T_SE == NUL)
+	    T_SO = T_SE = empty_option;
+	if (*T_US == NUL || *T_UE == NUL)
+	    T_US = T_UE = empty_option;
+	if (*T_CZH == NUL || *T_CZR == NUL)
+	    T_CZH = T_CZR = empty_option;
+
+	/* T_VE is needed even though T_VI is not defined */
+	if (*T_VE == NUL)
+	    T_VI = empty_option;
+
+	/* if 'mr' or 'me' is not defined use 'so' and 'se' */
+	if (*T_ME == NUL)
+	{
+	    T_ME = T_SE;
+	    T_MR = T_SO;
+	    T_MD = T_SO;
+	}
+
+	/* if 'so' or 'se' is not defined use 'mr' and 'me' */
+	if (*T_SO == NUL)
+	{
+	    T_SE = T_ME;
+	    if (*T_MR == NUL)
+		T_SO = T_MD;
+	    else
+		T_SO = T_MR;
+	}
+
+	/* if 'ZH' or 'ZR' is not defined use 'mr' and 'me' */
+	if (*T_CZH == NUL)
+	{
+	    T_CZR = T_ME;
+	    if (*T_MR == NUL)
+		T_CZH = T_MD;
+	    else
+		T_CZH = T_MR;
+	}
+
+	/* "Sb" and "Sf" come in pairs */
+	if (*T_CSB == NUL || *T_CSF == NUL)
+	{
+	    T_CSB = empty_option;
+	    T_CSF = empty_option;
+	}
+
+	/* "AB" and "AF" come in pairs */
+	if (*T_CAB == NUL || *T_CAF == NUL)
+	{
+	    T_CAB = empty_option;
+	    T_CAF = empty_option;
+	}
+
+	/* if 'Sb' and 'AB' are not defined, reset "Co" */
+	if (*T_CSB == NUL && *T_CAB == NUL)
+	    T_CCO = empty_option;
+
+	/* Set 'weirdinvert' according to value of 't_xs' */
+	p_wiv = (*T_XS != NUL);
+    }
+    need_gather = TRUE;
+
+    /* Set t_colors to the value of t_Co. */
+    t_colors = atoi((char *)T_CCO);
+}
+
+#if (defined(FEAT_GUI) && (defined(FEAT_MENU) || !defined(USE_ON_FLY_SCROLL))) \
+	|| defined(PROTO)
+/*
+ * Represent the given long_u as individual bytes, with the most significant
+ * byte first, and store them in dst.
+ */
+    void
+add_long_to_buf(val, dst)
+    long_u  val;
+    char_u  *dst;
+{
+    int	    i;
+    int	    shift;
+
+    for (i = 1; i <= sizeof(long_u); i++)
+    {
+	shift = 8 * (sizeof(long_u) - i);
+	dst[i - 1] = (char_u) ((val >> shift) & 0xff);
+    }
+}
+
+static int get_long_from_buf __ARGS((char_u *buf, long_u *val));
+
+/*
+ * Interpret the next string of bytes in buf as a long integer, with the most
+ * significant byte first.  Note that it is assumed that buf has been through
+ * inchar(), so that NUL and K_SPECIAL will be represented as three bytes each.
+ * Puts result in val, and returns the number of bytes read from buf
+ * (between sizeof(long_u) and 2 * sizeof(long_u)), or -1 if not enough bytes
+ * were present.
+ */
+    static int
+get_long_from_buf(buf, val)
+    char_u  *buf;
+    long_u  *val;
+{
+    int	    len;
+    char_u  bytes[sizeof(long_u)];
+    int	    i;
+    int	    shift;
+
+    *val = 0;
+    len = get_bytes_from_buf(buf, bytes, (int)sizeof(long_u));
+    if (len != -1)
+    {
+	for (i = 0; i < sizeof(long_u); i++)
+	{
+	    shift = 8 * (sizeof(long_u) - 1 - i);
+	    *val += (long_u)bytes[i] << shift;
+	}
+    }
+    return len;
+}
+#endif
+
+#if defined(FEAT_GUI) \
+    || (defined(FEAT_MOUSE) && (!defined(UNIX) || defined(FEAT_MOUSE_XTERM)))
+/*
+ * Read the next num_bytes bytes from buf, and store them in bytes.  Assume
+ * that buf has been through inchar().	Returns the actual number of bytes used
+ * from buf (between num_bytes and num_bytes*2), or -1 if not enough bytes were
+ * available.
+ */
+    static int
+get_bytes_from_buf(buf, bytes, num_bytes)
+    char_u  *buf;
+    char_u  *bytes;
+    int	    num_bytes;
+{
+    int	    len = 0;
+    int	    i;
+    char_u  c;
+
+    for (i = 0; i < num_bytes; i++)
+    {
+	if ((c = buf[len++]) == NUL)
+	    return -1;
+	if (c == K_SPECIAL)
+	{
+	    if (buf[len] == NUL || buf[len + 1] == NUL)	    /* cannot happen? */
+		return -1;
+	    if (buf[len++] == (int)KS_ZERO)
+		c = NUL;
+	    ++len;	/* skip KE_FILLER */
+	    /* else it should be KS_SPECIAL, and c already equals K_SPECIAL */
+	}
+	else if (c == CSI && buf[len] == KS_EXTRA
+					       && buf[len + 1] == (int)KE_CSI)
+	    /* CSI is stored as CSI KS_SPECIAL KE_CSI to avoid confusion with
+	     * the start of a special key, see add_to_input_buf_csi(). */
+	    len += 2;
+	bytes[i] = c;
+    }
+    return len;
+}
+#endif
+
+/*
+ * Check if the new shell size is valid, correct it if it's too small.
+ */
+    void
+check_shellsize()
+{
+    if (Columns < MIN_COLUMNS)
+	Columns = MIN_COLUMNS;
+    if (Rows < min_rows())	/* need room for one window and command line */
+	Rows = min_rows();
+}
+
+/*
+ * Invoked just before the screen structures are going to be (re)allocated.
+ */
+    void
+win_new_shellsize()
+{
+    static int	old_Rows = 0;
+    static int	old_Columns = 0;
+
+    if (old_Rows != Rows || old_Columns != Columns)
+	ui_new_shellsize();
+    if (old_Rows != Rows)
+    {
+	/* if 'window' uses the whole screen, keep it using that */
+	if (p_window == old_Rows - 1 || old_Rows == 0)
+	    p_window = Rows - 1;
+	old_Rows = Rows;
+	shell_new_rows();	/* update window sizes */
+    }
+    if (old_Columns != Columns)
+    {
+	old_Columns = Columns;
+#ifdef FEAT_VERTSPLIT
+	shell_new_columns();	/* update window sizes */
+#endif
+    }
+}
+
+/*
+ * Call this function when the Vim shell has been resized in any way.
+ * Will obtain the current size and redraw (also when size didn't change).
+ */
+    void
+shell_resized()
+{
+    set_shellsize(0, 0, FALSE);
+}
+
+/*
+ * Check if the shell size changed.  Handle a resize.
+ * When the size didn't change, nothing happens.
+ */
+    void
+shell_resized_check()
+{
+    int		old_Rows = Rows;
+    int		old_Columns = Columns;
+
+    (void)ui_get_shellsize();
+    check_shellsize();
+    if (old_Rows != Rows || old_Columns != Columns)
+	shell_resized();
+}
+
+/*
+ * Set size of the Vim shell.
+ * If 'mustset' is TRUE, we must set Rows and Columns, do not get the real
+ * window size (this is used for the :win command).
+ * If 'mustset' is FALSE, we may try to get the real window size and if
+ * it fails use 'width' and 'height'.
+ */
+    void
+set_shellsize(width, height, mustset)
+    int	    width, height;
+    int	    mustset;
+{
+    static int		busy = FALSE;
+
+    /*
+     * Avoid recursiveness, can happen when setting the window size causes
+     * another window-changed signal.
+     */
+    if (busy)
+	return;
+
+    if (width < 0 || height < 0)    /* just checking... */
+	return;
+
+    if (State == HITRETURN || State == SETWSIZE) /* postpone the resizing */
+    {
+	State = SETWSIZE;
+	return;
+    }
+
+    ++busy;
+
+#ifdef AMIGA
+    out_flush();	    /* must do this before mch_get_shellsize() for
+			       some obscure reason */
+#endif
+
+    if (mustset || (ui_get_shellsize() == FAIL && height != 0))
+    {
+	Rows = height;
+	Columns = width;
+	check_shellsize();
+	ui_set_shellsize(mustset);
+    }
+    else
+	check_shellsize();
+
+    /* The window layout used to be adjusted here, but it now happens in
+     * screenalloc() (also invoked from screenclear()).  That is because the
+     * "busy" check above may skip this, but not screenalloc(). */
+
+    if (State != ASKMORE && State != EXTERNCMD && State != CONFIRM)
+	screenclear();
+    else
+	screen_start();	    /* don't know where cursor is now */
+
+    if (starting != NO_SCREEN)
+    {
+#ifdef FEAT_TITLE
+	maketitle();
+#endif
+	changed_line_abv_curs();
+	invalidate_botline();
+
+	/*
+	 * We only redraw when it's needed:
+	 * - While at the more prompt or executing an external command, don't
+	 *   redraw, but position the cursor.
+	 * - While editing the command line, only redraw that.
+	 * - in Ex mode, don't redraw anything.
+	 * - Otherwise, redraw right now, and position the cursor.
+	 * Always need to call update_screen() or screenalloc(), to make
+	 * sure Rows/Columns and the size of ScreenLines[] is correct!
+	 */
+	if (State == ASKMORE || State == EXTERNCMD || State == CONFIRM
+							     || exmode_active)
+	{
+	    screenalloc(FALSE);
+	    repeat_message();
+	}
+	else
+	{
+#ifdef FEAT_SCROLLBIND
+	    if (curwin->w_p_scb)
+		do_check_scrollbind(TRUE);
+#endif
+	    if (State & CMDLINE)
+	    {
+		update_screen(NOT_VALID);
+		redrawcmdline();
+	    }
+	    else
+	    {
+		update_topline();
+#if defined(FEAT_INS_EXPAND)
+		if (pum_visible())
+		{
+		    redraw_later(NOT_VALID);
+		    ins_compl_show_pum(); /* This includes the redraw. */
+		}
+		else
+#endif
+		    update_screen(NOT_VALID);
+		if (redrawing())
+		    setcursor();
+	    }
+	}
+	cursor_on();	    /* redrawing may have switched it off */
+    }
+    out_flush();
+    --busy;
+}
+
+/*
+ * Set the terminal to TMODE_RAW (for Normal mode) or TMODE_COOK (for external
+ * commands and Ex mode).
+ */
+    void
+settmode(tmode)
+    int	 tmode;
+{
+#ifdef FEAT_GUI
+    /* don't set the term where gvim was started to any mode */
+    if (gui.in_use)
+	return;
+#endif
+
+    if (full_screen)
+    {
+	/*
+	 * When returning after calling a shell we want to really set the
+	 * terminal to raw mode, even though we think it already is, because
+	 * the shell program may have reset the terminal mode.
+	 * When we think the terminal is normal, don't try to set it to
+	 * normal again, because that causes problems (logout!) on some
+	 * machines.
+	 */
+	if (tmode != TMODE_COOK || cur_tmode != TMODE_COOK)
+	{
+#ifdef FEAT_TERMRESPONSE
+	    /* May need to check for T_CRV response and termcodes, it doesn't
+	     * work in Cooked mode, an external program may get them. */
+	    if (tmode != TMODE_RAW && crv_status == CRV_SENT)
+		(void)vpeekc_nomap();
+	    check_for_codes_from_term();
+#endif
+#ifdef FEAT_MOUSE_TTY
+	    if (tmode != TMODE_RAW)
+		mch_setmouse(FALSE);		/* switch mouse off */
+#endif
+	    out_flush();
+	    mch_settmode(tmode);    /* machine specific function */
+	    cur_tmode = tmode;
+#ifdef FEAT_MOUSE
+	    if (tmode == TMODE_RAW)
+		setmouse();			/* may switch mouse on */
+#endif
+	    out_flush();
+	}
+#ifdef FEAT_TERMRESPONSE
+	may_req_termresponse();
+#endif
+    }
+}
+
+    void
+starttermcap()
+{
+    if (full_screen && !termcap_active)
+    {
+	out_str(T_TI);			/* start termcap mode */
+	out_str(T_KS);			/* start "keypad transmit" mode */
+	out_flush();
+	termcap_active = TRUE;
+	screen_start();			/* don't know where cursor is now */
+#ifdef FEAT_TERMRESPONSE
+	may_req_termresponse();
+	/* Immediately check for a response.  If t_Co changes, we don't want
+	 * to redraw with wrong colors first. */
+	check_for_codes_from_term();
+#endif
+    }
+}
+
+    void
+stoptermcap()
+{
+    screen_stop_highlight();
+    reset_cterm_colors();
+    if (termcap_active)
+    {
+#ifdef FEAT_TERMRESPONSE
+	/* May need to check for T_CRV response. */
+	if (crv_status == CRV_SENT)
+	    (void)vpeekc_nomap();
+	/* Check for termcodes first, otherwise an external program may get
+	 * them. */
+	check_for_codes_from_term();
+#endif
+	out_str(T_KE);			/* stop "keypad transmit" mode */
+	out_flush();
+	termcap_active = FALSE;
+	cursor_on();			/* just in case it is still off */
+	out_str(T_TE);			/* stop termcap mode */
+	screen_start();			/* don't know where cursor is now */
+	out_flush();
+    }
+}
+
+#if defined(FEAT_TERMRESPONSE) || defined(PROTO)
+/*
+ * Request version string (for xterm) when needed.
+ * Only do this after switching to raw mode, otherwise the result will be
+ * echoed.
+ * Only do this after startup has finished, to avoid that the response comes
+ * while executing "-c !cmd" or even after "-c quit".
+ * Only do this after termcap mode has been started, otherwise the codes for
+ * the cursor keys may be wrong.
+ * Only do this when 'esckeys' is on, otherwise the response causes trouble in
+ * Insert mode.
+ * On Unix only do it when both output and input are a tty (avoid writing
+ * request to terminal while reading from a file).
+ * The result is caught in check_termcode().
+ */
+    void
+may_req_termresponse()
+{
+    if (crv_status == CRV_GET
+	    && cur_tmode == TMODE_RAW
+	    && starting == 0
+	    && termcap_active
+	    && p_ek
+# ifdef UNIX
+	    && isatty(1)
+	    && isatty(read_cmd_fd)
+# endif
+	    && *T_CRV != NUL)
+    {
+	out_str(T_CRV);
+	crv_status = CRV_SENT;
+	/* check for the characters now, otherwise they might be eaten by
+	 * get_keystroke() */
+	out_flush();
+	(void)vpeekc_nomap();
+    }
+}
+#endif
+
+/*
+ * Return TRUE when saving and restoring the screen.
+ */
+    int
+swapping_screen()
+{
+    return (full_screen && *T_TI != NUL);
+}
+
+#ifdef FEAT_MOUSE
+/*
+ * setmouse() - switch mouse on/off depending on current mode and 'mouse'
+ */
+    void
+setmouse()
+{
+# ifdef FEAT_MOUSE_TTY
+    int	    checkfor;
+# endif
+
+# ifdef FEAT_MOUSESHAPE
+    update_mouseshape(-1);
+# endif
+
+# ifdef FEAT_MOUSE_TTY /* Should be outside proc, but may break MOUSESHAPE */
+#  ifdef FEAT_GUI
+    /* In the GUI the mouse is always enabled. */
+    if (gui.in_use)
+	return;
+#  endif
+    /* be quick when mouse is off */
+    if (*p_mouse == NUL || has_mouse_termcode == 0)
+	return;
+
+    /* don't switch mouse on when not in raw mode (Ex mode) */
+    if (cur_tmode != TMODE_RAW)
+    {
+	mch_setmouse(FALSE);
+	return;
+    }
+
+#  ifdef FEAT_VISUAL
+    if (VIsual_active)
+	checkfor = MOUSE_VISUAL;
+    else
+#  endif
+	if (State == HITRETURN || State == ASKMORE || State == SETWSIZE)
+	checkfor = MOUSE_RETURN;
+    else if (State & INSERT)
+	checkfor = MOUSE_INSERT;
+    else if (State & CMDLINE)
+	checkfor = MOUSE_COMMAND;
+    else if (State == CONFIRM || State == EXTERNCMD)
+	checkfor = ' '; /* don't use mouse for ":confirm" or ":!cmd" */
+    else
+	checkfor = MOUSE_NORMAL;    /* assume normal mode */
+
+    if (mouse_has(checkfor))
+	mch_setmouse(TRUE);
+    else
+	mch_setmouse(FALSE);
+# endif
+}
+
+/*
+ * Return TRUE if
+ * - "c" is in 'mouse', or
+ * - 'a' is in 'mouse' and "c" is in MOUSE_A, or
+ * - the current buffer is a help file and 'h' is in 'mouse' and we are in a
+ *   normal editing mode (not at hit-return message).
+ */
+    int
+mouse_has(c)
+    int	    c;
+{
+    char_u	*p;
+
+    for (p = p_mouse; *p; ++p)
+	switch (*p)
+	{
+	    case 'a': if (vim_strchr((char_u *)MOUSE_A, c) != NULL)
+			  return TRUE;
+		      break;
+	    case MOUSE_HELP: if (c != MOUSE_RETURN && curbuf->b_help)
+				 return TRUE;
+			     break;
+	    default: if (c == *p) return TRUE; break;
+	}
+    return FALSE;
+}
+
+/*
+ * Return TRUE when 'mousemodel' is set to "popup" or "popup_setpos".
+ */
+    int
+mouse_model_popup()
+{
+    return (p_mousem[0] == 'p');
+}
+#endif
+
+/*
+ * By outputting the 'cursor very visible' termcap code, for some windowed
+ * terminals this makes the screen scrolled to the correct position.
+ * Used when starting Vim or returning from a shell.
+ */
+    void
+scroll_start()
+{
+    if (*T_VS != NUL)
+    {
+	out_str(T_VS);
+	out_str(T_VE);
+	screen_start();			/* don't know where cursor is now */
+    }
+}
+
+static int cursor_is_off = FALSE;
+
+/*
+ * Enable the cursor.
+ */
+    void
+cursor_on()
+{
+    if (cursor_is_off)
+    {
+	out_str(T_VE);
+	cursor_is_off = FALSE;
+    }
+}
+
+/*
+ * Disable the cursor.
+ */
+    void
+cursor_off()
+{
+    if (full_screen)
+    {
+	if (!cursor_is_off)
+	    out_str(T_VI);	    /* disable cursor */
+	cursor_is_off = TRUE;
+    }
+}
+
+#if defined(CURSOR_SHAPE) || defined(PROTO)
+/*
+ * Set cursor shape to match Insert mode.
+ */
+    void
+term_cursor_shape()
+{
+    static int showing_insert_mode = MAYBE;
+
+    if (!full_screen || *T_CSI == NUL || *T_CEI == NUL)
+	return;
+
+    if (State & INSERT)
+    {
+	if (showing_insert_mode != TRUE)
+	    out_str(T_CSI);	    /* Insert mode cursor */
+	showing_insert_mode = TRUE;
+    }
+    else
+    {
+	if (showing_insert_mode != FALSE)
+	    out_str(T_CEI);	    /* non-Insert mode cursor */
+	showing_insert_mode = FALSE;
+    }
+}
+#endif
+
+/*
+ * Set scrolling region for window 'wp'.
+ * The region starts 'off' lines from the start of the window.
+ * Also set the vertical scroll region for a vertically split window.  Always
+ * the full width of the window, excluding the vertical separator.
+ */
+    void
+scroll_region_set(wp, off)
+    win_T	*wp;
+    int		off;
+{
+    OUT_STR(tgoto((char *)T_CS, W_WINROW(wp) + wp->w_height - 1,
+							 W_WINROW(wp) + off));
+#ifdef FEAT_VERTSPLIT
+    if (*T_CSV != NUL && wp->w_width != Columns)
+	OUT_STR(tgoto((char *)T_CSV, W_WINCOL(wp) + wp->w_width - 1,
+							       W_WINCOL(wp)));
+#endif
+    screen_start();		    /* don't know where cursor is now */
+}
+
+/*
+ * Reset scrolling region to the whole screen.
+ */
+    void
+scroll_region_reset()
+{
+    OUT_STR(tgoto((char *)T_CS, (int)Rows - 1, 0));
+#ifdef FEAT_VERTSPLIT
+    if (*T_CSV != NUL)
+	OUT_STR(tgoto((char *)T_CSV, (int)Columns - 1, 0));
+#endif
+    screen_start();		    /* don't know where cursor is now */
+}
+
+
+/*
+ * List of terminal codes that are currently recognized.
+ */
+
+static struct termcode
+{
+    char_u  name[2];	    /* termcap name of entry */
+    char_u  *code;	    /* terminal code (in allocated memory) */
+    int	    len;	    /* STRLEN(code) */
+    int	    modlen;	    /* length of part before ";*~". */
+} *termcodes = NULL;
+
+static int  tc_max_len = 0; /* number of entries that termcodes[] can hold */
+static int  tc_len = 0;	    /* current number of entries in termcodes[] */
+
+static int termcode_star __ARGS((char_u *code, int len));
+
+    void
+clear_termcodes()
+{
+    while (tc_len > 0)
+	vim_free(termcodes[--tc_len].code);
+    vim_free(termcodes);
+    termcodes = NULL;
+    tc_max_len = 0;
+
+#ifdef HAVE_TGETENT
+    BC = (char *)empty_option;
+    UP = (char *)empty_option;
+    PC = NUL;			/* set pad character to NUL */
+    ospeed = 0;
+#endif
+
+    need_gather = TRUE;		/* need to fill termleader[] */
+}
+
+#define ATC_FROM_TERM 55
+
+/*
+ * Add a new entry to the list of terminal codes.
+ * The list is kept alphabetical for ":set termcap"
+ * "flags" is TRUE when replacing 7-bit by 8-bit controls is desired.
+ * "flags" can also be ATC_FROM_TERM for got_code_from_term().
+ */
+    void
+add_termcode(name, string, flags)
+    char_u	*name;
+    char_u	*string;
+    int		flags;
+{
+    struct termcode *new_tc;
+    int		    i, j;
+    char_u	    *s;
+    int		    len;
+
+    if (string == NULL || *string == NUL)
+    {
+	del_termcode(name);
+	return;
+    }
+
+    s = vim_strsave(string);
+    if (s == NULL)
+	return;
+
+    /* Change leading <Esc>[ to CSI, change <Esc>O to <M-O>. */
+    if (flags != 0 && flags != ATC_FROM_TERM && term_7to8bit(string) != 0)
+    {
+	mch_memmove(s, s + 1, STRLEN(s));
+	s[0] = term_7to8bit(string);
+    }
+    len = (int)STRLEN(s);
+
+    need_gather = TRUE;		/* need to fill termleader[] */
+
+    /*
+     * need to make space for more entries
+     */
+    if (tc_len == tc_max_len)
+    {
+	tc_max_len += 20;
+	new_tc = (struct termcode *)alloc(
+			    (unsigned)(tc_max_len * sizeof(struct termcode)));
+	if (new_tc == NULL)
+	{
+	    tc_max_len -= 20;
+	    return;
+	}
+	for (i = 0; i < tc_len; ++i)
+	    new_tc[i] = termcodes[i];
+	vim_free(termcodes);
+	termcodes = new_tc;
+    }
+
+    /*
+     * Look for existing entry with the same name, it is replaced.
+     * Look for an existing entry that is alphabetical higher, the new entry
+     * is inserted in front of it.
+     */
+    for (i = 0; i < tc_len; ++i)
+    {
+	if (termcodes[i].name[0] < name[0])
+	    continue;
+	if (termcodes[i].name[0] == name[0])
+	{
+	    if (termcodes[i].name[1] < name[1])
+		continue;
+	    /*
+	     * Exact match: May replace old code.
+	     */
+	    if (termcodes[i].name[1] == name[1])
+	    {
+		if (flags == ATC_FROM_TERM && (j = termcode_star(
+				    termcodes[i].code, termcodes[i].len)) > 0)
+		{
+		    /* Don't replace ESC[123;*X or ESC O*X with another when
+		     * invoked from got_code_from_term(). */
+		    if (len == termcodes[i].len - j
+			    && STRNCMP(s, termcodes[i].code, len - 1) == 0
+			    && s[len - 1]
+				   == termcodes[i].code[termcodes[i].len - 1])
+		    {
+			/* They are equal but for the ";*": don't add it. */
+			vim_free(s);
+			return;
+		    }
+		}
+		else
+		{
+		    /* Replace old code. */
+		    vim_free(termcodes[i].code);
+		    --tc_len;
+		    break;
+		}
+	    }
+	}
+	/*
+	 * Found alphabetical larger entry, move rest to insert new entry
+	 */
+	for (j = tc_len; j > i; --j)
+	    termcodes[j] = termcodes[j - 1];
+	break;
+    }
+
+    termcodes[i].name[0] = name[0];
+    termcodes[i].name[1] = name[1];
+    termcodes[i].code = s;
+    termcodes[i].len = len;
+
+    /* For xterm we recognize special codes like "ESC[42;*X" and "ESC O*X" that
+     * accept modifiers. */
+    termcodes[i].modlen = 0;
+    j = termcode_star(s, len);
+    if (j > 0)
+	termcodes[i].modlen = len - 1 - j;
+    ++tc_len;
+}
+
+/*
+ * Check termcode "code[len]" for ending in ;*X, <Esc>O*X or <M-O>*X.
+ * The "X" can be any character.
+ * Return 0 if not found, 2 for ;*X and 1 for O*X and <M-O>*X.
+ */
+    static int
+termcode_star(code, len)
+    char_u	*code;
+    int		len;
+{
+    /* Shortest is <M-O>*X.  With ; shortest is <CSI>1;*X */
+    if (len >= 3 && code[len - 2] == '*')
+    {
+	if (len >= 5 && code[len - 3] == ';')
+	    return 2;
+	if ((len >= 4 && code[len - 3] == 'O') || code[len - 3] == 'O' + 128)
+	    return 1;
+    }
+    return 0;
+}
+
+    char_u  *
+find_termcode(name)
+    char_u  *name;
+{
+    int	    i;
+
+    for (i = 0; i < tc_len; ++i)
+	if (termcodes[i].name[0] == name[0] && termcodes[i].name[1] == name[1])
+	    return termcodes[i].code;
+    return NULL;
+}
+
+#if defined(FEAT_CMDL_COMPL) || defined(PROTO)
+    char_u *
+get_termcode(i)
+    int	    i;
+{
+    if (i >= tc_len)
+	return NULL;
+    return &termcodes[i].name[0];
+}
+#endif
+
+    void
+del_termcode(name)
+    char_u  *name;
+{
+    int	    i;
+
+    if (termcodes == NULL)	/* nothing there yet */
+	return;
+
+    need_gather = TRUE;		/* need to fill termleader[] */
+
+    for (i = 0; i < tc_len; ++i)
+	if (termcodes[i].name[0] == name[0] && termcodes[i].name[1] == name[1])
+	{
+	    del_termcode_idx(i);
+	    return;
+	}
+    /* not found. Give error message? */
+}
+
+    static void
+del_termcode_idx(idx)
+    int		idx;
+{
+    int		i;
+
+    vim_free(termcodes[idx].code);
+    --tc_len;
+    for (i = idx; i < tc_len; ++i)
+	termcodes[i] = termcodes[i + 1];
+}
+
+#ifdef FEAT_TERMRESPONSE
+/*
+ * Called when detected that the terminal sends 8-bit codes.
+ * Convert all 7-bit codes to their 8-bit equivalent.
+ */
+    static void
+switch_to_8bit()
+{
+    int		i;
+    int		c;
+
+    /* Only need to do something when not already using 8-bit codes. */
+    if (!term_is_8bit(T_NAME))
+    {
+	for (i = 0; i < tc_len; ++i)
+	{
+	    c = term_7to8bit(termcodes[i].code);
+	    if (c != 0)
+	    {
+		mch_memmove(termcodes[i].code + 1, termcodes[i].code + 2,
+					       STRLEN(termcodes[i].code + 1));
+		termcodes[i].code[0] = c;
+	    }
+	}
+	need_gather = TRUE;		/* need to fill termleader[] */
+    }
+    detected_8bit = TRUE;
+}
+#endif
+
+#ifdef CHECK_DOUBLE_CLICK
+static linenr_T orig_topline = 0;
+# ifdef FEAT_DIFF
+static int orig_topfill = 0;
+# endif
+#endif
+#if (defined(FEAT_WINDOWS) && defined(CHECK_DOUBLE_CLICK)) || defined(PROTO)
+/*
+ * Checking for double clicks ourselves.
+ * "orig_topline" is used to avoid detecting a double-click when the window
+ * contents scrolled (e.g., when 'scrolloff' is non-zero).
+ */
+/*
+ * Set orig_topline.  Used when jumping to another window, so that a double
+ * click still works.
+ */
+    void
+set_mouse_topline(wp)
+    win_T	*wp;
+{
+    orig_topline = wp->w_topline;
+# ifdef FEAT_DIFF
+    orig_topfill = wp->w_topfill;
+# endif
+}
+#endif
+
+/*
+ * Check if typebuf.tb_buf[] contains a terminal key code.
+ * Check from typebuf.tb_buf[typebuf.tb_off] to typebuf.tb_buf[typebuf.tb_off
+ * + max_offset].
+ * Return 0 for no match, -1 for partial match, > 0 for full match.
+ * With a match, the match is removed, the replacement code is inserted in
+ * typebuf.tb_buf[] and the number of characters in typebuf.tb_buf[] is
+ * returned.
+ * When "buf" is not NULL, it is used instead of typebuf.tb_buf[]. "buflen" is
+ * then the length of the string in buf[].
+ */
+    int
+check_termcode(max_offset, buf, buflen)
+    int		max_offset;
+    char_u	*buf;
+    int		buflen;
+{
+    char_u	*tp;
+    char_u	*p;
+    int		slen = 0;	/* init for GCC */
+    int		modslen;
+    int		len;
+    int		offset;
+    char_u	key_name[2];
+    int		modifiers;
+    int		key;
+    int		new_slen;
+    int		extra;
+    char_u	string[MAX_KEY_CODE_LEN + 1];
+    int		i, j;
+    int		idx = 0;
+#ifdef FEAT_MOUSE
+# if !defined(UNIX) || defined(FEAT_MOUSE_XTERM) || defined(FEAT_GUI)
+    char_u	bytes[6];
+    int		num_bytes;
+# endif
+    int		mouse_code = 0;	    /* init for GCC */
+    int		is_click, is_drag;
+    int		wheel_code = 0;
+    int		current_button;
+    static int	held_button = MOUSE_RELEASE;
+    static int	orig_num_clicks = 1;
+    static int	orig_mouse_code = 0x0;
+# ifdef CHECK_DOUBLE_CLICK
+    static int	orig_mouse_col = 0;
+    static int	orig_mouse_row = 0;
+    static struct timeval  orig_mouse_time = {0, 0};
+					/* time of previous mouse click */
+    struct timeval  mouse_time;		/* time of current mouse click */
+    long	timediff;		/* elapsed time in msec */
+# endif
+#endif
+    int		cpo_koffset;
+#ifdef FEAT_MOUSE_GPM
+    extern int	gpm_flag; /* gpm library variable */
+#endif
+
+    cpo_koffset = (vim_strchr(p_cpo, CPO_KOFFSET) != NULL);
+
+    /*
+     * Speed up the checks for terminal codes by gathering all first bytes
+     * used in termleader[].  Often this is just a single <Esc>.
+     */
+    if (need_gather)
+	gather_termleader();
+
+    /*
+     * Check at several positions in typebuf.tb_buf[], to catch something like
+     * "x<Up>" that can be mapped. Stop at max_offset, because characters
+     * after that cannot be used for mapping, and with @r commands
+     * typebuf.tb_buf[]
+     * can become very long.
+     * This is used often, KEEP IT FAST!
+     */
+    for (offset = 0; offset < max_offset; ++offset)
+    {
+	if (buf == NULL)
+	{
+	    if (offset >= typebuf.tb_len)
+		break;
+	    tp = typebuf.tb_buf + typebuf.tb_off + offset;
+	    len = typebuf.tb_len - offset;	/* length of the input */
+	}
+	else
+	{
+	    if (offset >= buflen)
+		break;
+	    tp = buf + offset;
+	    len = buflen - offset;
+	}
+
+	/*
+	 * Don't check characters after K_SPECIAL, those are already
+	 * translated terminal chars (avoid translating ~@^Hx).
+	 */
+	if (*tp == K_SPECIAL)
+	{
+	    offset += 2;	/* there are always 2 extra characters */
+	    continue;
+	}
+
+	/*
+	 * Skip this position if the character does not appear as the first
+	 * character in term_strings. This speeds up a lot, since most
+	 * termcodes start with the same character (ESC or CSI).
+	 */
+	i = *tp;
+	for (p = termleader; *p && *p != i; ++p)
+	    ;
+	if (*p == NUL)
+	    continue;
+
+	/*
+	 * Skip this position if p_ek is not set and tp[0] is an ESC and we
+	 * are in Insert mode.
+	 */
+	if (*tp == ESC && !p_ek && (State & INSERT))
+	    continue;
+
+	key_name[0] = NUL;	/* no key name found yet */
+	key_name[1] = NUL;	/* no key name found yet */
+	modifiers = 0;		/* no modifiers yet */
+
+#ifdef FEAT_GUI
+	if (gui.in_use)
+	{
+	    /*
+	     * GUI special key codes are all of the form [CSI xx].
+	     */
+	    if (*tp == CSI)	    /* Special key from GUI */
+	    {
+		if (len < 3)
+		    return -1;	    /* Shouldn't happen */
+		slen = 3;
+		key_name[0] = tp[1];
+		key_name[1] = tp[2];
+	    }
+	}
+	else
+#endif /* FEAT_GUI */
+	{
+	    for (idx = 0; idx < tc_len; ++idx)
+	    {
+		/*
+		 * Ignore the entry if we are not at the start of
+		 * typebuf.tb_buf[]
+		 * and there are not enough characters to make a match.
+		 * But only when the 'K' flag is in 'cpoptions'.
+		 */
+		slen = termcodes[idx].len;
+		if (cpo_koffset && offset && len < slen)
+		    continue;
+		if (STRNCMP(termcodes[idx].code, tp,
+				     (size_t)(slen > len ? len : slen)) == 0)
+		{
+		    if (len < slen)		/* got a partial sequence */
+			return -1;		/* need to get more chars */
+
+		    /*
+		     * When found a keypad key, check if there is another key
+		     * that matches and use that one.  This makes <Home> to be
+		     * found instead of <kHome> when they produce the same
+		     * key code.
+		     */
+		    if (termcodes[idx].name[0] == 'K'
+				       && VIM_ISDIGIT(termcodes[idx].name[1]))
+		    {
+			for (j = idx + 1; j < tc_len; ++j)
+			    if (termcodes[j].len == slen &&
+				    STRNCMP(termcodes[idx].code,
+					    termcodes[j].code, slen) == 0)
+			    {
+				idx = j;
+				break;
+			    }
+		    }
+
+		    key_name[0] = termcodes[idx].name[0];
+		    key_name[1] = termcodes[idx].name[1];
+		    break;
+		}
+
+		/*
+		 * Check for code with modifier, like xterm uses:
+		 * <Esc>[123;*X  (modslen == slen - 3)
+		 * Also <Esc>O*X and <M-O>*X (modslen == slen - 2).
+		 * When there is a modifier the * matches a number.
+		 * When there is no modifier the ;* or * is omitted.
+		 */
+		if (termcodes[idx].modlen > 0)
+		{
+		    modslen = termcodes[idx].modlen;
+		    if (cpo_koffset && offset && len < modslen)
+			continue;
+		    if (STRNCMP(termcodes[idx].code, tp,
+				(size_t)(modslen > len ? len : modslen)) == 0)
+		    {
+			int	    n;
+
+			if (len <= modslen)	/* got a partial sequence */
+			    return -1;		/* need to get more chars */
+
+			if (tp[modslen] == termcodes[idx].code[slen - 1])
+			    slen = modslen + 1;	/* no modifiers */
+			else if (tp[modslen] != ';' && modslen == slen - 3)
+			    continue;	/* no match */
+			else
+			{
+			    /* Skip over the digits, the final char must
+			     * follow. */
+			    for (j = slen - 2; j < len && isdigit(tp[j]); ++j)
+				;
+			    ++j;
+			    if (len < j)	/* got a partial sequence */
+				return -1;	/* need to get more chars */
+			    if (tp[j - 1] != termcodes[idx].code[slen - 1])
+				continue;	/* no match */
+
+			    /* Match!  Convert modifier bits. */
+			    n = atoi((char *)tp + slen - 2) - 1;
+			    if (n & 1)
+				modifiers |= MOD_MASK_SHIFT;
+			    if (n & 2)
+				modifiers |= MOD_MASK_ALT;
+			    if (n & 4)
+				modifiers |= MOD_MASK_CTRL;
+			    if (n & 8)
+				modifiers |= MOD_MASK_META;
+
+			    slen = j;
+			}
+			key_name[0] = termcodes[idx].name[0];
+			key_name[1] = termcodes[idx].name[1];
+			break;
+		    }
+		}
+	    }
+	}
+
+#ifdef FEAT_TERMRESPONSE
+	if (key_name[0] == NUL)
+	{
+	    /* Check for xterm version string: "<Esc>[>{x};{vers};{y}c".  Also
+	     * eat other possible responses to t_RV, rxvt returns
+	     * "<Esc>[?1;2c".  Also accept CSI instead of <Esc>[. */
+	    if (*T_CRV != NUL && ((tp[0] == ESC && tp[1] == '[' && len >= 3)
+					       || (tp[0] == CSI && len >= 2)))
+	    {
+		j = 0;
+		extra = 0;
+		for (i = 2 + (tp[0] != CSI);
+			i < len && (VIM_ISDIGIT(tp[i])
+			    || tp[i] == ';' || tp[i] == '.'); ++i)
+		    if (tp[i] == ';' && ++j == 1)
+			extra = atoi((char *)tp + i + 1);
+		if (i == len)
+		    return -1;		/* not enough characters */
+
+		/* eat it when at least one digit and ending in 'c' */
+		if (i > 2 + (tp[0] != CSI) && tp[i] == 'c')
+		{
+		    crv_status = CRV_GOT;
+
+		    /* If this code starts with CSI, you can bet that the
+		     * terminal uses 8-bit codes. */
+		    if (tp[0] == CSI)
+			switch_to_8bit();
+
+		    /* rxvt sends its version number: "20703" is 2.7.3.
+		     * Ignore it for when the user has set 'term' to xterm,
+		     * even though it's an rxvt. */
+		    if (extra > 20000)
+			extra = 0;
+
+		    if (tp[1 + (tp[0] != CSI)] == '>' && j == 2)
+		    {
+			/* if xterm version >= 95 use mouse dragging */
+			if (extra >= 95)
+			    set_option_value((char_u *)"ttym", 0L,
+						       (char_u *)"xterm2", 0);
+			/* if xterm version >= 141 try to get termcap codes */
+			if (extra >= 141)
+			{
+			    check_for_codes = TRUE;
+			    need_gather = TRUE;
+			    req_codes_from_term();
+			}
+		    }
+# ifdef FEAT_EVAL
+		    set_vim_var_string(VV_TERMRESPONSE, tp, i + 1);
+# endif
+# ifdef FEAT_AUTOCMD
+		    apply_autocmds(EVENT_TERMRESPONSE,
+						   NULL, NULL, FALSE, curbuf);
+# endif
+		    key_name[0] = (int)KS_EXTRA;
+		    key_name[1] = (int)KE_IGNORE;
+		    slen = i + 1;
+		}
+	    }
+
+	    /* Check for '<Esc>P1+r<hex bytes><Esc>\'.  A "0" instead of the
+	     * "1" means an invalid request. */
+	    else if (check_for_codes
+		    && ((tp[0] == ESC && tp[1] == 'P' && len >= 2)
+			|| tp[0] == DCS))
+	    {
+		j = 1 + (tp[0] != DCS);
+		for (i = j; i < len; ++i)
+		    if ((tp[i] == ESC && tp[i + 1] == '\\' && i + 1 < len)
+			    || tp[i] == STERM)
+		    {
+			if (i - j >= 3 && tp[j + 1] == '+' && tp[j + 2] == 'r')
+			    got_code_from_term(tp + j, i);
+			key_name[0] = (int)KS_EXTRA;
+			key_name[1] = (int)KE_IGNORE;
+			slen = i + 1 + (tp[i] == ESC);
+			break;
+		    }
+
+		if (i == len)
+		    return -1;		/* not enough characters */
+	    }
+	}
+#endif
+
+	if (key_name[0] == NUL)
+	    continue;	    /* No match at this position, try next one */
+
+	/* We only get here when we have a complete termcode match */
+
+#ifdef FEAT_MOUSE
+# ifdef FEAT_GUI
+	/*
+	 * Only in the GUI: Fetch the pointer coordinates of the scroll event
+	 * so that we know which window to scroll later.
+	 */
+	if (gui.in_use
+		&& key_name[0] == (int)KS_EXTRA
+		&& (key_name[1] == (int)KE_X1MOUSE
+		    || key_name[1] == (int)KE_X2MOUSE
+		    || key_name[1] == (int)KE_MOUSEDOWN
+		    || key_name[1] == (int)KE_MOUSEUP))
+	{
+	    num_bytes = get_bytes_from_buf(tp + slen, bytes, 4);
+	    if (num_bytes == -1)	/* not enough coordinates */
+		return -1;
+	    mouse_col = 128 * (bytes[0] - ' ' - 1) + bytes[1] - ' ' - 1;
+	    mouse_row = 128 * (bytes[2] - ' ' - 1) + bytes[3] - ' ' - 1;
+	    slen += num_bytes;
+	}
+	else
+# endif
+	/*
+	 * If it is a mouse click, get the coordinates.
+	 */
+	if (key_name[0] == (int)KS_MOUSE
+# ifdef FEAT_MOUSE_JSB
+		|| key_name[0] == (int)KS_JSBTERM_MOUSE
+# endif
+# ifdef FEAT_MOUSE_NET
+		|| key_name[0] == (int)KS_NETTERM_MOUSE
+# endif
+# ifdef FEAT_MOUSE_DEC
+		|| key_name[0] == (int)KS_DEC_MOUSE
+# endif
+# ifdef FEAT_MOUSE_PTERM
+		|| key_name[0] == (int)KS_PTERM_MOUSE
+# endif
+		)
+	{
+	    is_click = is_drag = FALSE;
+
+# if !defined(UNIX) || defined(FEAT_MOUSE_XTERM) || defined(FEAT_GUI)
+	    if (key_name[0] == (int)KS_MOUSE)
+	    {
+		/*
+		 * For xterm and MSDOS we get "<t_mouse>scr", where
+		 *  s == encoded button state:
+		 *	   0x20 = left button down
+		 *	   0x21 = middle button down
+		 *	   0x22 = right button down
+		 *	   0x23 = any button release
+		 *	   0x60 = button 4 down (scroll wheel down)
+		 *	   0x61 = button 5 down (scroll wheel up)
+		 *	add 0x04 for SHIFT
+		 *	add 0x08 for ALT
+		 *	add 0x10 for CTRL
+		 *	add 0x20 for mouse drag (0x40 is drag with left button)
+		 *  c == column + ' ' + 1 == column + 33
+		 *  r == row + ' ' + 1 == row + 33
+		 *
+		 * The coordinates are passed on through global variables.
+		 * Ugly, but this avoids trouble with mouse clicks at an
+		 * unexpected moment and allows for mapping them.
+		 */
+		for (;;)
+		{
+#ifdef FEAT_GUI
+		    if (gui.in_use)
+		    {
+			/* GUI uses more bits for columns > 223 */
+			num_bytes = get_bytes_from_buf(tp + slen, bytes, 5);
+			if (num_bytes == -1)	/* not enough coordinates */
+			    return -1;
+			mouse_code = bytes[0];
+			mouse_col = 128 * (bytes[1] - ' ' - 1)
+							 + bytes[2] - ' ' - 1;
+			mouse_row = 128 * (bytes[3] - ' ' - 1)
+							 + bytes[4] - ' ' - 1;
+		    }
+		    else
+#endif
+		    {
+			num_bytes = get_bytes_from_buf(tp + slen, bytes, 3);
+			if (num_bytes == -1)	/* not enough coordinates */
+			    return -1;
+			mouse_code = bytes[0];
+			mouse_col = bytes[1] - ' ' - 1;
+			mouse_row = bytes[2] - ' ' - 1;
+		    }
+		    slen += num_bytes;
+
+		    /* If the following bytes is also a mouse code and it has
+		     * the same code, dump this one and get the next.  This
+		     * makes dragging a whole lot faster. */
+#ifdef FEAT_GUI
+		    if (gui.in_use)
+			j = 3;
+		    else
+#endif
+			j = termcodes[idx].len;
+		    if (STRNCMP(tp, tp + slen, (size_t)j) == 0
+			    && tp[slen + j] == mouse_code
+			    && tp[slen + j + 1] != NUL
+			    && tp[slen + j + 2] != NUL
+#ifdef FEAT_GUI
+			    && (!gui.in_use
+				|| (tp[slen + j + 3] != NUL
+					&& tp[slen + j + 4] != NUL))
+#endif
+			    )
+			slen += j;
+		    else
+			break;
+		}
+
+#  if !defined(MSWIN) && !defined(MSDOS)
+		/*
+		 * Handle mouse events.
+		 * Recognize the xterm mouse wheel, but not in the GUI, the
+		 * Linux console with GPM and the MS-DOS or Win32 console
+		 * (multi-clicks use >= 0x60).
+		 */
+		if (mouse_code >= MOUSEWHEEL_LOW
+#   ifdef FEAT_GUI
+			&& !gui.in_use
+#   endif
+#   ifdef FEAT_MOUSE_GPM
+			&& gpm_flag == 0
+#   endif
+			)
+		{
+		    /* Keep the mouse_code before it's changed, so that we
+		     * remember that it was a mouse wheel click. */
+		    wheel_code = mouse_code;
+		}
+#   ifdef FEAT_MOUSE_XTERM
+		else if (held_button == MOUSE_RELEASE
+#    ifdef FEAT_GUI
+			&& !gui.in_use
+#    endif
+			&& (mouse_code == 0x23 || mouse_code == 0x24))
+		{
+		    /* Apparently used by rxvt scroll wheel. */
+		    wheel_code = mouse_code - 0x23 + MOUSEWHEEL_LOW;
+		}
+#   endif
+
+#   if defined(UNIX) && defined(FEAT_MOUSE_TTY)
+		else if (use_xterm_mouse() > 1)
+		{
+		    if (mouse_code & MOUSE_DRAG_XTERM)
+			mouse_code |= MOUSE_DRAG;
+		}
+#   endif
+#   ifdef FEAT_XCLIPBOARD
+		else if (!(mouse_code & MOUSE_DRAG & ~MOUSE_CLICK_MASK))
+		{
+		    if ((mouse_code & MOUSE_RELEASE) == MOUSE_RELEASE)
+			stop_xterm_trace();
+		    else
+			start_xterm_trace(mouse_code);
+		}
+#   endif
+#  endif
+	    }
+# endif /* !UNIX || FEAT_MOUSE_XTERM */
+# ifdef FEAT_MOUSE_NET
+	    if (key_name[0] == (int)KS_NETTERM_MOUSE)
+	    {
+		int mc, mr;
+
+		/* expect a rather limited sequence like: balancing {
+		 * \033}6,45\r
+		 * '6' is the row, 45 is the column
+		 */
+		p = tp + slen;
+		mr = getdigits(&p);
+		if (*p++ != ',')
+		    return -1;
+		mc = getdigits(&p);
+		if (*p++ != '\r')
+		    return -1;
+
+		mouse_col = mc - 1;
+		mouse_row = mr - 1;
+		mouse_code = MOUSE_LEFT;
+		slen += (int)(p - (tp + slen));
+	    }
+# endif	/* FEAT_MOUSE_NET */
+# ifdef FEAT_MOUSE_JSB
+	    if (key_name[0] == (int)KS_JSBTERM_MOUSE)
+	    {
+		int mult, val, iter, button, status;
+
+		/* JSBTERM Input Model
+		 * \033[0~zw uniq escape sequence
+		 * (L-x)  Left button pressed - not pressed x not reporting
+		 * (M-x)  Middle button pressed - not pressed x not reporting
+		 * (R-x)  Right button pressed - not pressed x not reporting
+		 * (SDmdu)  Single , Double click, m mouse move d button down
+		 *						   u button up
+		 *  ###   X cursor position padded to 3 digits
+		 *  ###   Y cursor position padded to 3 digits
+		 * (s-x)  SHIFT key pressed - not pressed x not reporting
+		 * (c-x)  CTRL key pressed - not pressed x not reporting
+		 * \033\\ terminateing sequence
+		 */
+
+		p = tp + slen;
+		button = mouse_code = 0;
+		switch (*p++)
+		{
+		    case 'L': button = 1; break;
+		    case '-': break;
+		    case 'x': break; /* ignore sequence */
+		    default:  return -1; /* Unknown Result */
+		}
+		switch (*p++)
+		{
+		    case 'M': button |= 2; break;
+		    case '-': break;
+		    case 'x': break; /* ignore sequence */
+		    default:  return -1; /* Unknown Result */
+		}
+		switch (*p++)
+		{
+		    case 'R': button |= 4; break;
+		    case '-': break;
+		    case 'x': break; /* ignore sequence */
+		    default:  return -1; /* Unknown Result */
+		}
+		status = *p++;
+		for (val = 0, mult = 100, iter = 0; iter < 3; iter++,
+							      mult /= 10, p++)
+		    if (*p >= '0' && *p <= '9')
+			val += (*p - '0') * mult;
+		    else
+			return -1;
+		mouse_col = val;
+		for (val = 0, mult = 100, iter = 0; iter < 3; iter++,
+							      mult /= 10, p++)
+		    if (*p >= '0' && *p <= '9')
+			val += (*p - '0') * mult;
+		    else
+			return -1;
+		mouse_row = val;
+		switch (*p++)
+		{
+		    case 's': button |= 8; break;  /* SHIFT key Pressed */
+		    case '-': break;  /* Not Pressed */
+		    case 'x': break;  /* Not Reporting */
+		    default:  return -1; /* Unknown Result */
+		}
+		switch (*p++)
+		{
+		    case 'c': button |= 16; break;  /* CTRL key Pressed */
+		    case '-': break;  /* Not Pressed */
+		    case 'x': break;  /* Not Reporting */
+		    default:  return -1; /* Unknown Result */
+		}
+		if (*p++ != '\033')
+		    return -1;
+		if (*p++ != '\\')
+		    return -1;
+		switch (status)
+		{
+		    case 'D': /* Double Click */
+		    case 'S': /* Single Click */
+			if (button & 1) mouse_code |= MOUSE_LEFT;
+			if (button & 2) mouse_code |= MOUSE_MIDDLE;
+			if (button & 4) mouse_code |= MOUSE_RIGHT;
+			if (button & 8) mouse_code |= MOUSE_SHIFT;
+			if (button & 16) mouse_code |= MOUSE_CTRL;
+			break;
+		    case 'm': /* Mouse move */
+			if (button & 1) mouse_code |= MOUSE_LEFT;
+			if (button & 2) mouse_code |= MOUSE_MIDDLE;
+			if (button & 4) mouse_code |= MOUSE_RIGHT;
+			if (button & 8) mouse_code |= MOUSE_SHIFT;
+			if (button & 16) mouse_code |= MOUSE_CTRL;
+			if ((button & 7) != 0)
+			{
+			    held_button = mouse_code;
+			    mouse_code |= MOUSE_DRAG;
+			}
+			is_drag = TRUE;
+			showmode();
+			break;
+		    case 'd': /* Button Down */
+			if (button & 1) mouse_code |= MOUSE_LEFT;
+			if (button & 2) mouse_code |= MOUSE_MIDDLE;
+			if (button & 4) mouse_code |= MOUSE_RIGHT;
+			if (button & 8) mouse_code |= MOUSE_SHIFT;
+			if (button & 16) mouse_code |= MOUSE_CTRL;
+			break;
+		    case 'u': /* Button Up */
+			if (button & 1)
+			    mouse_code |= MOUSE_LEFT | MOUSE_RELEASE;
+			if (button & 2)
+			    mouse_code |= MOUSE_MIDDLE | MOUSE_RELEASE;
+			if (button & 4)
+			    mouse_code |= MOUSE_RIGHT | MOUSE_RELEASE;
+			if (button & 8)
+			    mouse_code |= MOUSE_SHIFT;
+			if (button & 16)
+			    mouse_code |= MOUSE_CTRL;
+			break;
+		    default: return -1; /* Unknown Result */
+		}
+
+		slen += (p - (tp + slen));
+	    }
+# endif /* FEAT_MOUSE_JSB */
+# ifdef FEAT_MOUSE_DEC
+	    if (key_name[0] == (int)KS_DEC_MOUSE)
+	    {
+	       /* The DEC Locator Input Model
+		* Netterm delivers the code sequence:
+		*  \033[2;4;24;80&w  (left button down)
+		*  \033[3;0;24;80&w  (left button up)
+		*  \033[6;1;24;80&w  (right button down)
+		*  \033[7;0;24;80&w  (right button up)
+		* CSI Pe ; Pb ; Pr ; Pc ; Pp & w
+		* Pe is the event code
+		* Pb is the button code
+		* Pr is the row coordinate
+		* Pc is the column coordinate
+		* Pp is the third coordinate (page number)
+		* Pe, the event code indicates what event caused this report
+		*    The following event codes are defined:
+		*    0 - request, the terminal received an explicit request
+		*	 for a locator report, but the locator is unavailable
+		*    1 - request, the terminal received an explicit request
+		*	 for a locator report
+		*    2 - left button down
+		*    3 - left button up
+		*    4 - middle button down
+		*    5 - middle button up
+		*    6 - right button down
+		*    7 - right button up
+		*    8 - fourth button down
+		*    9 - fourth button up
+		*    10 - locator outside filter rectangle
+		* Pb, the button code, ASCII decimal 0-15 indicating which
+		*   buttons are down if any. The state of the four buttons
+		*   on the locator correspond to the low four bits of the
+		*   decimal value,
+		*   "1" means button depressed
+		*   0 - no buttons down,
+		*   1 - right,
+		*   2 - middle,
+		*   4 - left,
+		*   8 - fourth
+		* Pr is the row coordinate of the locator position in the page,
+		*   encoded as an ASCII decimal value.
+		*   If Pr is omitted, the locator position is undefined
+		*   (outside the terminal window for example).
+		* Pc is the column coordinate of the locator position in the
+		*   page, encoded as an ASCII decimal value.
+		*   If Pc is omitted, the locator position is undefined
+		*   (outside the terminal window for example).
+		* Pp is the page coordinate of the locator position
+		*   encoded as an ASCII decimal value.
+		*   The page coordinate may be omitted if the locator is on
+		*   page one (the default).  We ignore it anyway.
+		*/
+		int Pe, Pb, Pr, Pc;
+
+		p = tp + slen;
+
+		/* get event status */
+		Pe = getdigits(&p);
+		if (*p++ != ';')
+		    return -1;
+
+		/* get button status */
+		Pb = getdigits(&p);
+		if (*p++ != ';')
+		    return -1;
+
+		/* get row status */
+		Pr = getdigits(&p);
+		if (*p++ != ';')
+		    return -1;
+
+		/* get column status */
+		Pc = getdigits(&p);
+
+		/* the page parameter is optional */
+		if (*p == ';')
+		{
+		    p++;
+		    (void)getdigits(&p);
+		}
+		if (*p++ != '&')
+		    return -1;
+		if (*p++ != 'w')
+		    return -1;
+
+		mouse_code = 0;
+		switch (Pe)
+		{
+		case  0: return -1; /* position request while unavailable */
+		case  1: /* a response to a locator position request includes
+			    the status of all buttons */
+			 Pb &= 7;   /* mask off and ignore fourth button */
+			 if (Pb & 4)
+			     mouse_code  = MOUSE_LEFT;
+			 if (Pb & 2)
+			     mouse_code  = MOUSE_MIDDLE;
+			 if (Pb & 1)
+			     mouse_code  = MOUSE_RIGHT;
+			 if (Pb)
+			 {
+			     held_button = mouse_code;
+			     mouse_code |= MOUSE_DRAG;
+			     WantQueryMouse = TRUE;
+			 }
+			 is_drag = TRUE;
+			 showmode();
+			 break;
+		case  2: mouse_code = MOUSE_LEFT;
+			 WantQueryMouse = TRUE;
+			 break;
+		case  3: mouse_code = MOUSE_RELEASE | MOUSE_LEFT;
+			 break;
+		case  4: mouse_code = MOUSE_MIDDLE;
+			 WantQueryMouse = TRUE;
+			 break;
+		case  5: mouse_code = MOUSE_RELEASE | MOUSE_MIDDLE;
+			 break;
+		case  6: mouse_code = MOUSE_RIGHT;
+			 WantQueryMouse = TRUE;
+			 break;
+		case  7: mouse_code = MOUSE_RELEASE | MOUSE_RIGHT;
+			 break;
+		case  8: return -1; /* fourth button down */
+		case  9: return -1; /* fourth button up */
+		case 10: return -1; /* mouse outside of filter rectangle */
+		default: return -1; /* should never occur */
+		}
+
+		mouse_col = Pc - 1;
+		mouse_row = Pr - 1;
+
+		slen += (int)(p - (tp + slen));
+	    }
+# endif /* FEAT_MOUSE_DEC */
+# ifdef FEAT_MOUSE_PTERM
+	    if (key_name[0] == (int)KS_PTERM_MOUSE)
+	    {
+		int button, num_clicks, action, mc, mr;
+
+		p = tp + slen;
+
+		action = getdigits(&p);
+		if (*p++ != ';')
+		    return -1;
+
+		mouse_row = getdigits(&p);
+		if (*p++ != ';')
+		    return -1;
+		mouse_col = getdigits(&p);
+		if (*p++ != ';')
+		    return -1;
+
+		button = getdigits(&p);
+		mouse_code = 0;
+
+		switch( button )
+		{
+		    case 4: mouse_code = MOUSE_LEFT; break;
+		    case 1: mouse_code = MOUSE_RIGHT; break;
+		    case 2: mouse_code = MOUSE_MIDDLE; break;
+		    default: return -1;
+		}
+
+		switch( action )
+		{
+		    case 31: /* Initial press */
+			if (*p++ != ';')
+			    return -1;
+
+			num_clicks = getdigits(&p); /* Not used */
+			break;
+
+		    case 32: /* Release */
+			mouse_code |= MOUSE_RELEASE;
+			break;
+
+		    case 33: /* Drag */
+			held_button = mouse_code;
+			mouse_code |= MOUSE_DRAG;
+			break;
+
+		    default:
+			return -1;
+		}
+
+		if (*p++ != 't')
+		    return -1;
+
+		slen += (p - (tp + slen));
+	    }
+# endif /* FEAT_MOUSE_PTERM */
+
+	    /* Interpret the mouse code */
+	    current_button = (mouse_code & MOUSE_CLICK_MASK);
+	    if (current_button == MOUSE_RELEASE
+# ifdef FEAT_MOUSE_XTERM
+		    && wheel_code == 0
+# endif
+		    )
+	    {
+		/*
+		 * If we get a mouse drag or release event when
+		 * there is no mouse button held down (held_button ==
+		 * MOUSE_RELEASE), produce a K_IGNORE below.
+		 * (can happen when you hold down two buttons
+		 * and then let them go, or click in the menu bar, but not
+		 * on a menu, and drag into the text).
+		 */
+		if ((mouse_code & MOUSE_DRAG) == MOUSE_DRAG)
+		    is_drag = TRUE;
+		current_button = held_button;
+	    }
+	    else if (wheel_code == 0)
+	    {
+# ifdef CHECK_DOUBLE_CLICK
+#  ifdef FEAT_MOUSE_GPM
+#   ifdef FEAT_GUI
+		/*
+		 * Only for Unix, when GUI or gpm is not active, we handle
+		 * multi-clicks here.
+		 */
+		if (gpm_flag == 0 && !gui.in_use)
+#   else
+		if (gpm_flag == 0)
+#   endif
+#  else
+#   ifdef FEAT_GUI
+		if (!gui.in_use)
+#   endif
+#  endif
+		{
+		    /*
+		     * Compute the time elapsed since the previous mouse click.
+		     */
+		    gettimeofday(&mouse_time, NULL);
+		    timediff = (mouse_time.tv_usec
+					    - orig_mouse_time.tv_usec) / 1000;
+		    if (timediff < 0)
+			--orig_mouse_time.tv_sec;
+		    timediff += (mouse_time.tv_sec
+					     - orig_mouse_time.tv_sec) * 1000;
+		    orig_mouse_time = mouse_time;
+		    if (mouse_code == orig_mouse_code
+			    && timediff < p_mouset
+			    && orig_num_clicks != 4
+			    && orig_mouse_col == mouse_col
+			    && orig_mouse_row == mouse_row
+			    && ((orig_topline == curwin->w_topline
+#ifdef FEAT_DIFF
+				    && orig_topfill == curwin->w_topfill
+#endif
+				)
+#ifdef FEAT_WINDOWS
+				/* Double click in tab pages line also works
+				 * when window contents changes. */
+				|| (mouse_row == 0 && firstwin->w_winrow > 0)
+#endif
+			       )
+			    )
+			++orig_num_clicks;
+		    else
+			orig_num_clicks = 1;
+		    orig_mouse_col = mouse_col;
+		    orig_mouse_row = mouse_row;
+		    orig_topline = curwin->w_topline;
+#ifdef FEAT_DIFF
+		    orig_topfill = curwin->w_topfill;
+#endif
+		}
+#  if defined(FEAT_GUI) || defined(FEAT_MOUSE_GPM)
+		else
+		    orig_num_clicks = NUM_MOUSE_CLICKS(mouse_code);
+#  endif
+# else
+		orig_num_clicks = NUM_MOUSE_CLICKS(mouse_code);
+# endif
+		is_click = TRUE;
+		orig_mouse_code = mouse_code;
+	    }
+	    if (!is_drag)
+		held_button = mouse_code & MOUSE_CLICK_MASK;
+
+	    /*
+	     * Translate the actual mouse event into a pseudo mouse event.
+	     * First work out what modifiers are to be used.
+	     */
+	    if (orig_mouse_code & MOUSE_SHIFT)
+		modifiers |= MOD_MASK_SHIFT;
+	    if (orig_mouse_code & MOUSE_CTRL)
+		modifiers |= MOD_MASK_CTRL;
+	    if (orig_mouse_code & MOUSE_ALT)
+		modifiers |= MOD_MASK_ALT;
+	    if (orig_num_clicks == 2)
+		modifiers |= MOD_MASK_2CLICK;
+	    else if (orig_num_clicks == 3)
+		modifiers |= MOD_MASK_3CLICK;
+	    else if (orig_num_clicks == 4)
+		modifiers |= MOD_MASK_4CLICK;
+
+	    /* Work out our pseudo mouse event */
+	    key_name[0] = (int)KS_EXTRA;
+	    if (wheel_code != 0)
+		key_name[1] = (wheel_code & 1)
+					? (int)KE_MOUSEUP : (int)KE_MOUSEDOWN;
+	    else
+		key_name[1] = get_pseudo_mouse_code(current_button,
+							   is_click, is_drag);
+	}
+#endif /* FEAT_MOUSE */
+
+#ifdef FEAT_GUI
+	/*
+	 * If using the GUI, then we get menu and scrollbar events.
+	 *
+	 * A menu event is encoded as K_SPECIAL, KS_MENU, KE_FILLER followed by
+	 * four bytes which are to be taken as a pointer to the vimmenu_T
+	 * structure.
+	 *
+	 * A tab line event is encoded as K_SPECIAL KS_TABLINE nr, where "nr"
+	 * is one byte with the tab index.
+	 *
+	 * A scrollbar event is K_SPECIAL, KS_VER_SCROLLBAR, KE_FILLER followed
+	 * by one byte representing the scrollbar number, and then four bytes
+	 * representing a long_u which is the new value of the scrollbar.
+	 *
+	 * A horizontal scrollbar event is K_SPECIAL, KS_HOR_SCROLLBAR,
+	 * KE_FILLER followed by four bytes representing a long_u which is the
+	 * new value of the scrollbar.
+	 */
+# ifdef FEAT_MENU
+	else if (key_name[0] == (int)KS_MENU)
+	{
+	    long_u	val;
+
+	    num_bytes = get_long_from_buf(tp + slen, &val);
+	    if (num_bytes == -1)
+		return -1;
+	    current_menu = (vimmenu_T *)val;
+	    slen += num_bytes;
+
+	    /* The menu may have been deleted right after it was used, check
+	     * for that. */
+	    if (check_menu_pointer(root_menu, current_menu) == FAIL)
+	    {
+		key_name[0] = KS_EXTRA;
+		key_name[1] = (int)KE_IGNORE;
+	    }
+	}
+# endif
+# ifdef FEAT_GUI_TABLINE
+	else if (key_name[0] == (int)KS_TABLINE)
+	{
+	    /* Selecting tabline tab or using its menu. */
+	    num_bytes = get_bytes_from_buf(tp + slen, bytes, 1);
+	    if (num_bytes == -1)
+		return -1;
+	    current_tab = (int)bytes[0];
+	    slen += num_bytes;
+	}
+	else if (key_name[0] == (int)KS_TABMENU)
+	{
+	    /* Selecting tabline tab or using its menu. */
+	    num_bytes = get_bytes_from_buf(tp + slen, bytes, 2);
+	    if (num_bytes == -1)
+		return -1;
+	    current_tab = (int)bytes[0];
+	    current_tabmenu = (int)bytes[1];
+	    slen += num_bytes;
+	}
+# endif
+# ifndef USE_ON_FLY_SCROLL
+	else if (key_name[0] == (int)KS_VER_SCROLLBAR)
+	{
+	    long_u	val;
+
+	    /* Get the last scrollbar event in the queue of the same type */
+	    j = 0;
+	    for (i = 0; tp[j] == CSI && tp[j + 1] == KS_VER_SCROLLBAR
+						     && tp[j + 2] != NUL; ++i)
+	    {
+		j += 3;
+		num_bytes = get_bytes_from_buf(tp + j, bytes, 1);
+		if (num_bytes == -1)
+		    break;
+		if (i == 0)
+		    current_scrollbar = (int)bytes[0];
+		else if (current_scrollbar != (int)bytes[0])
+		    break;
+		j += num_bytes;
+		num_bytes = get_long_from_buf(tp + j, &val);
+		if (num_bytes == -1)
+		    break;
+		scrollbar_value = val;
+		j += num_bytes;
+		slen = j;
+	    }
+	    if (i == 0)		/* not enough characters to make one */
+		return -1;
+	}
+	else if (key_name[0] == (int)KS_HOR_SCROLLBAR)
+	{
+	    long_u	val;
+
+	    /* Get the last horiz. scrollbar event in the queue */
+	    j = 0;
+	    for (i = 0; tp[j] == CSI && tp[j + 1] == KS_HOR_SCROLLBAR
+						     && tp[j + 2] != NUL; ++i)
+	    {
+		j += 3;
+		num_bytes = get_long_from_buf(tp + j, &val);
+		if (num_bytes == -1)
+		    break;
+		scrollbar_value = val;
+		j += num_bytes;
+		slen = j;
+	    }
+	    if (i == 0)		/* not enough characters to make one */
+		return -1;
+	}
+# endif /* !USE_ON_FLY_SCROLL */
+#endif /* FEAT_GUI */
+
+	/*
+	 * Change <xHome> to <Home>, <xUp> to <Up>, etc.
+	 */
+	key = handle_x_keys(TERMCAP2KEY(key_name[0], key_name[1]));
+
+	/*
+	 * Add any modifier codes to our string.
+	 */
+	new_slen = 0;		/* Length of what will replace the termcode */
+	if (modifiers != 0)
+	{
+	    /* Some keys have the modifier included.  Need to handle that here
+	     * to make mappings work. */
+	    key = simplify_key(key, &modifiers);
+	    if (modifiers != 0)
+	    {
+		string[new_slen++] = K_SPECIAL;
+		string[new_slen++] = (int)KS_MODIFIER;
+		string[new_slen++] = modifiers;
+	    }
+	}
+
+	/* Finally, add the special key code to our string */
+	key_name[0] = KEY2TERMCAP0(key);
+	key_name[1] = KEY2TERMCAP1(key);
+	if (key_name[0] == KS_KEY)
+	    string[new_slen++] = key_name[1];	/* from ":set <M-b>=xx" */
+	else
+	{
+	    string[new_slen++] = K_SPECIAL;
+	    string[new_slen++] = key_name[0];
+	    string[new_slen++] = key_name[1];
+	}
+	string[new_slen] = NUL;
+	extra = new_slen - slen;
+	if (buf == NULL)
+	{
+	    if (extra < 0)
+		/* remove matched chars, taking care of noremap */
+		del_typebuf(-extra, offset);
+	    else if (extra > 0)
+		/* insert the extra space we need */
+		ins_typebuf(string + slen, REMAP_YES, offset, FALSE, FALSE);
+
+	    /*
+	     * Careful: del_typebuf() and ins_typebuf() may have reallocated
+	     * typebuf.tb_buf[]!
+	     */
+	    mch_memmove(typebuf.tb_buf + typebuf.tb_off + offset, string,
+							    (size_t)new_slen);
+	}
+	else
+	{
+	    if (extra < 0)
+		/* remove matched characters */
+		mch_memmove(buf + offset, buf + offset - extra,
+					   (size_t)(buflen + offset + extra));
+	    else if (extra > 0)
+		/* insert the extra space we need */
+		mch_memmove(buf + offset + extra, buf + offset,
+						   (size_t)(buflen - offset));
+	    mch_memmove(buf + offset, string, (size_t)new_slen);
+	}
+	return (len + extra + offset);
+    }
+
+    return 0;			    /* no match found */
+}
+
+/*
+ * Replace any terminal code strings in from[] with the equivalent internal
+ * vim representation.	This is used for the "from" and "to" part of a
+ * mapping, and the "to" part of a menu command.
+ * Any strings like "<C-UP>" are also replaced, unless 'cpoptions' contains
+ * '<'.
+ * K_SPECIAL by itself is replaced by K_SPECIAL KS_SPECIAL KE_FILLER.
+ *
+ * The replacement is done in result[] and finally copied into allocated
+ * memory. If this all works well *bufp is set to the allocated memory and a
+ * pointer to it is returned. If something fails *bufp is set to NULL and from
+ * is returned.
+ *
+ * CTRL-V characters are removed.  When "from_part" is TRUE, a trailing CTRL-V
+ * is included, otherwise it is removed (for ":map xx ^V", maps xx to
+ * nothing).  When 'cpoptions' does not contain 'B', a backslash can be used
+ * instead of a CTRL-V.
+ */
+    char_u *
+replace_termcodes(from, bufp, from_part, do_lt, special)
+    char_u	*from;
+    char_u	**bufp;
+    int		from_part;
+    int		do_lt;		/* also translate <lt> */
+    int		special;	/* always accept <key> notation */
+{
+    int		i;
+    int		slen;
+    int		key;
+    int		dlen = 0;
+    char_u	*src;
+    int		do_backslash;	/* backslash is a special character */
+    int		do_special;	/* recognize <> key codes */
+    int		do_key_code;	/* recognize raw key codes */
+    char_u	*result;	/* buffer for resulting string */
+
+    do_backslash = (vim_strchr(p_cpo, CPO_BSLASH) == NULL);
+    do_special = (vim_strchr(p_cpo, CPO_SPECI) == NULL) || special;
+    do_key_code = (vim_strchr(p_cpo, CPO_KEYCODE) == NULL);
+
+    /*
+     * Allocate space for the translation.  Worst case a single character is
+     * replaced by 6 bytes (shifted special key), plus a NUL at the end.
+     */
+    result = alloc((unsigned)STRLEN(from) * 6 + 1);
+    if (result == NULL)		/* out of memory */
+    {
+	*bufp = NULL;
+	return from;
+    }
+
+    src = from;
+
+    /*
+     * Check for #n at start only: function key n
+     */
+    if (from_part && src[0] == '#' && VIM_ISDIGIT(src[1]))  /* function key */
+    {
+	result[dlen++] = K_SPECIAL;
+	result[dlen++] = 'k';
+	if (src[1] == '0')
+	    result[dlen++] = ';';	/* #0 is F10 is "k;" */
+	else
+	    result[dlen++] = src[1];	/* #3 is F3 is "k3" */
+	src += 2;
+    }
+
+    /*
+     * Copy each byte from *from to result[dlen]
+     */
+    while (*src != NUL)
+    {
+	/*
+	 * If 'cpoptions' does not contain '<', check for special key codes,
+	 * like "<C-S-MouseLeft>"
+	 */
+	if (do_special && (do_lt || STRNCMP(src, "<lt>", 4) != 0))
+	{
+#ifdef FEAT_EVAL
+	    /*
+	     * Replace <SID> by K_SNR <script-nr> _.
+	     * (room: 5 * 6 = 30 bytes; needed: 3 + <nr> + 1 <= 14)
+	     */
+	    if (STRNICMP(src, "<SID>", 5) == 0)
+	    {
+		if (current_SID <= 0)
+		    EMSG(_(e_usingsid));
+		else
+		{
+		    src += 5;
+		    result[dlen++] = K_SPECIAL;
+		    result[dlen++] = (int)KS_EXTRA;
+		    result[dlen++] = (int)KE_SNR;
+		    sprintf((char *)result + dlen, "%ld", (long)current_SID);
+		    dlen += (int)STRLEN(result + dlen);
+		    result[dlen++] = '_';
+		    continue;
+		}
+	    }
+#endif
+
+	    slen = trans_special(&src, result + dlen, TRUE);
+	    if (slen)
+	    {
+		dlen += slen;
+		continue;
+	    }
+	}
+
+	/*
+	 * If 'cpoptions' does not contain 'k', see if it's an actual key-code.
+	 * Note that this is also checked after replacing the <> form.
+	 * Single character codes are NOT replaced (e.g. ^H or DEL), because
+	 * it could be a character in the file.
+	 */
+	if (do_key_code)
+	{
+	    i = find_term_bykeys(src);
+	    if (i >= 0)
+	    {
+		result[dlen++] = K_SPECIAL;
+		result[dlen++] = termcodes[i].name[0];
+		result[dlen++] = termcodes[i].name[1];
+		src += termcodes[i].len;
+		/* If terminal code matched, continue after it. */
+		continue;
+	    }
+	}
+
+#ifdef FEAT_EVAL
+	if (do_special)
+	{
+	    char_u	*p, *s, len;
+
+	    /*
+	     * Replace <Leader> by the value of "mapleader".
+	     * Replace <LocalLeader> by the value of "maplocalleader".
+	     * If "mapleader" or "maplocalleader" isn't set use a backslash.
+	     */
+	    if (STRNICMP(src, "<Leader>", 8) == 0)
+	    {
+		len = 8;
+		p = get_var_value((char_u *)"g:mapleader");
+	    }
+	    else if (STRNICMP(src, "<LocalLeader>", 13) == 0)
+	    {
+		len = 13;
+		p = get_var_value((char_u *)"g:maplocalleader");
+	    }
+	    else
+	    {
+		len = 0;
+		p = NULL;
+	    }
+	    if (len != 0)
+	    {
+		/* Allow up to 8 * 6 characters for "mapleader". */
+		if (p == NULL || *p == NUL || STRLEN(p) > 8 * 6)
+		    s = (char_u *)"\\";
+		else
+		    s = p;
+		while (*s != NUL)
+		    result[dlen++] = *s++;
+		src += len;
+		continue;
+	    }
+	}
+#endif
+
+	/*
+	 * Remove CTRL-V and ignore the next character.
+	 * For "from" side the CTRL-V at the end is included, for the "to"
+	 * part it is removed.
+	 * If 'cpoptions' does not contain 'B', also accept a backslash.
+	 */
+	key = *src;
+	if (key == Ctrl_V || (do_backslash && key == '\\'))
+	{
+	    ++src;				/* skip CTRL-V or backslash */
+	    if (*src == NUL)
+	    {
+		if (from_part)
+		    result[dlen++] = key;
+		break;
+	    }
+	}
+
+#ifdef FEAT_MBYTE
+	/* skip multibyte char correctly */
+	for (i = (*mb_ptr2len)(src); i > 0; --i)
+#endif
+	{
+	    /*
+	     * If the character is K_SPECIAL, replace it with K_SPECIAL
+	     * KS_SPECIAL KE_FILLER.
+	     * If compiled with the GUI replace CSI with K_CSI.
+	     */
+	    if (*src == K_SPECIAL)
+	    {
+		result[dlen++] = K_SPECIAL;
+		result[dlen++] = KS_SPECIAL;
+		result[dlen++] = KE_FILLER;
+	    }
+# ifdef FEAT_GUI
+	    else if (*src == CSI)
+	    {
+		result[dlen++] = K_SPECIAL;
+		result[dlen++] = KS_EXTRA;
+		result[dlen++] = (int)KE_CSI;
+	    }
+# endif
+	    else
+		result[dlen++] = *src;
+	    ++src;
+	}
+    }
+    result[dlen] = NUL;
+
+    /*
+     * Copy the new string to allocated memory.
+     * If this fails, just return from.
+     */
+    if ((*bufp = vim_strsave(result)) != NULL)
+	from = *bufp;
+    vim_free(result);
+    return from;
+}
+
+/*
+ * Find a termcode with keys 'src' (must be NUL terminated).
+ * Return the index in termcodes[], or -1 if not found.
+ */
+    int
+find_term_bykeys(src)
+    char_u	*src;
+{
+    int		i;
+    int		slen;
+
+    for (i = 0; i < tc_len; ++i)
+    {
+	slen = termcodes[i].len;
+	if (slen > 1 && STRNCMP(termcodes[i].code, src, (size_t)slen) == 0)
+	    return i;
+    }
+    return -1;
+}
+
+/*
+ * Gather the first characters in the terminal key codes into a string.
+ * Used to speed up check_termcode().
+ */
+    static void
+gather_termleader()
+{
+    int	    i;
+    int	    len = 0;
+
+#ifdef FEAT_GUI
+    if (gui.in_use)
+	termleader[len++] = CSI;    /* the GUI codes are not in termcodes[] */
+#endif
+#ifdef FEAT_TERMRESPONSE
+    if (check_for_codes)
+	termleader[len++] = DCS;    /* the termcode response starts with DCS
+				       in 8-bit mode */
+#endif
+    termleader[len] = NUL;
+
+    for (i = 0; i < tc_len; ++i)
+	if (vim_strchr(termleader, termcodes[i].code[0]) == NULL)
+	{
+	    termleader[len++] = termcodes[i].code[0];
+	    termleader[len] = NUL;
+	}
+
+    need_gather = FALSE;
+}
+
+/*
+ * Show all termcodes (for ":set termcap")
+ * This code looks a lot like showoptions(), but is different.
+ */
+    void
+show_termcodes()
+{
+    int		col;
+    int		*items;
+    int		item_count;
+    int		run;
+    int		row, rows;
+    int		cols;
+    int		i;
+    int		len;
+
+#define INC3 27	    /* try to make three columns */
+#define INC2 40	    /* try to make two columns */
+#define GAP 2	    /* spaces between columns */
+
+    if (tc_len == 0)	    /* no terminal codes (must be GUI) */
+	return;
+    items = (int *)alloc((unsigned)(sizeof(int) * tc_len));
+    if (items == NULL)
+	return;
+
+    /* Highlight title */
+    MSG_PUTS_TITLE(_("\n--- Terminal keys ---"));
+
+    /*
+     * do the loop two times:
+     * 1. display the short items (non-strings and short strings)
+     * 2. display the medium items (medium length strings)
+     * 3. display the long items (remaining strings)
+     */
+    for (run = 1; run <= 3 && !got_int; ++run)
+    {
+	/*
+	 * collect the items in items[]
+	 */
+	item_count = 0;
+	for (i = 0; i < tc_len; i++)
+	{
+	    len = show_one_termcode(termcodes[i].name,
+						    termcodes[i].code, FALSE);
+	    if (len <= INC3 - GAP ? run == 1
+			: len <= INC2 - GAP ? run == 2
+			: run == 3)
+		items[item_count++] = i;
+	}
+
+	/*
+	 * display the items
+	 */
+	if (run <= 2)
+	{
+	    cols = (Columns + GAP) / (run == 1 ? INC3 : INC2);
+	    if (cols == 0)
+		cols = 1;
+	    rows = (item_count + cols - 1) / cols;
+	}
+	else	/* run == 3 */
+	    rows = item_count;
+	for (row = 0; row < rows && !got_int; ++row)
+	{
+	    msg_putchar('\n');			/* go to next line */
+	    if (got_int)			/* 'q' typed in more */
+		break;
+	    col = 0;
+	    for (i = row; i < item_count; i += rows)
+	    {
+		msg_col = col;			/* make columns */
+		show_one_termcode(termcodes[items[i]].name,
+					      termcodes[items[i]].code, TRUE);
+		if (run == 2)
+		    col += INC2;
+		else
+		    col += INC3;
+	    }
+	    out_flush();
+	    ui_breakcheck();
+	}
+    }
+    vim_free(items);
+}
+
+/*
+ * Show one termcode entry.
+ * Output goes into IObuff[]
+ */
+    int
+show_one_termcode(name, code, printit)
+    char_u  *name;
+    char_u  *code;
+    int	    printit;
+{
+    char_u	*p;
+    int		len;
+
+    if (name[0] > '~')
+    {
+	IObuff[0] = ' ';
+	IObuff[1] = ' ';
+	IObuff[2] = ' ';
+	IObuff[3] = ' ';
+    }
+    else
+    {
+	IObuff[0] = 't';
+	IObuff[1] = '_';
+	IObuff[2] = name[0];
+	IObuff[3] = name[1];
+    }
+    IObuff[4] = ' ';
+
+    p = get_special_key_name(TERMCAP2KEY(name[0], name[1]), 0);
+    if (p[1] != 't')
+	STRCPY(IObuff + 5, p);
+    else
+	IObuff[5] = NUL;
+    len = (int)STRLEN(IObuff);
+    do
+	IObuff[len++] = ' ';
+    while (len < 17);
+    IObuff[len] = NUL;
+    if (code == NULL)
+	len += 4;
+    else
+	len += vim_strsize(code);
+
+    if (printit)
+    {
+	msg_puts(IObuff);
+	if (code == NULL)
+	    msg_puts((char_u *)"NULL");
+	else
+	    msg_outtrans(code);
+    }
+    return len;
+}
+
+#if defined(FEAT_TERMRESPONSE) || defined(PROTO)
+/*
+ * For Xterm >= 140 compiled with OPT_TCAP_QUERY: Obtain the actually used
+ * termcap codes from the terminal itself.
+ * We get them one by one to avoid a very long response string.
+ */
+static int xt_index_in = 0;
+static int xt_index_out = 0;
+
+    static void
+req_codes_from_term()
+{
+    xt_index_out = 0;
+    xt_index_in = 0;
+    req_more_codes_from_term();
+}
+
+    static void
+req_more_codes_from_term()
+{
+    char	buf[11];
+    int		old_idx = xt_index_out;
+
+    /* Don't do anything when going to exit. */
+    if (exiting)
+	return;
+
+    /* Send up to 10 more requests out than we received.  Avoid sending too
+     * many, there can be a buffer overflow somewhere. */
+    while (xt_index_out < xt_index_in + 10 && key_names[xt_index_out] != NULL)
+    {
+	sprintf(buf, "\033P+q%02x%02x\033\\",
+		      key_names[xt_index_out][0], key_names[xt_index_out][1]);
+	out_str_nf((char_u *)buf);
+	++xt_index_out;
+    }
+
+    /* Send the codes out right away. */
+    if (xt_index_out != old_idx)
+	out_flush();
+}
+
+/*
+ * Decode key code response from xterm: '<Esc>P1+r<name>=<string><Esc>\'.
+ * A "0" instead of the "1" indicates a code that isn't supported.
+ * Both <name> and <string> are encoded in hex.
+ * "code" points to the "0" or "1".
+ */
+    static void
+got_code_from_term(code, len)
+    char_u	*code;
+    int		len;
+{
+#define XT_LEN 100
+    char_u	name[3];
+    char_u	str[XT_LEN];
+    int		i;
+    int		j = 0;
+    int		c;
+
+    /* A '1' means the code is supported, a '0' means it isn't.
+     * When half the length is > XT_LEN we can't use it.
+     * Our names are currently all 2 characters. */
+    if (code[0] == '1' && code[7] == '=' && len / 2 < XT_LEN)
+    {
+	/* Get the name from the response and find it in the table. */
+	name[0] = hexhex2nr(code + 3);
+	name[1] = hexhex2nr(code + 5);
+	name[2] = NUL;
+	for (i = 0; key_names[i] != NULL; ++i)
+	{
+	    if (STRCMP(key_names[i], name) == 0)
+	    {
+		xt_index_in = i;
+		break;
+	    }
+	}
+	if (key_names[i] != NULL)
+	{
+	    for (i = 8; (c = hexhex2nr(code + i)) >= 0; i += 2)
+		str[j++] = c;
+	    str[j] = NUL;
+	    if (name[0] == 'C' && name[1] == 'o')
+	    {
+		/* Color count is not a key code. */
+		i = atoi((char *)str);
+		if (i != t_colors)
+		{
+		    /* Nr of colors changed, initialize highlighting and
+		     * redraw everything.  This causes a redraw, which usually
+		     * clears the message.  Try keeping the message if it
+		     * might work. */
+		    set_keep_msg_from_hist();
+		    set_color_count(i);
+		    init_highlight(TRUE, FALSE);
+		    redraw_later(CLEAR);
+		}
+	    }
+	    else
+	    {
+		/* First delete any existing entry with the same code. */
+		i = find_term_bykeys(str);
+		if (i >= 0)
+		    del_termcode_idx(i);
+		add_termcode(name, str, ATC_FROM_TERM);
+	    }
+	}
+    }
+
+    /* May request more codes now that we received one. */
+    ++xt_index_in;
+    req_more_codes_from_term();
+}
+
+/*
+ * Check if there are any unanswered requests and deal with them.
+ * This is called before starting an external program or getting direct
+ * keyboard input.  We don't want responses to be send to that program or
+ * handled as typed text.
+ */
+    static void
+check_for_codes_from_term()
+{
+    int		c;
+
+    /* If no codes requested or all are answered, no need to wait. */
+    if (xt_index_out == 0 || xt_index_out == xt_index_in)
+	return;
+
+    /* Vgetc() will check for and handle any response.
+     * Keep calling vpeekc() until we don't get any responses. */
+    ++no_mapping;
+    ++allow_keys;
+    for (;;)
+    {
+	c = vpeekc();
+	if (c == NUL)	    /* nothing available */
+	    break;
+
+	/* If a response is recognized it's replaced with K_IGNORE, must read
+	 * it from the input stream.  If there is no K_IGNORE we can't do
+	 * anything, break here (there might be some responses further on, but
+	 * we don't want to throw away any typed chars). */
+	if (c != K_SPECIAL && c != K_IGNORE)
+	    break;
+	c = vgetc();
+	if (c != K_IGNORE)
+	{
+	    vungetc(c);
+	    break;
+	}
+    }
+    --no_mapping;
+    --allow_keys;
+}
+#endif
+
+#if defined(FEAT_CMDL_COMPL) || defined(PROTO)
+/*
+ * Translate an internal mapping/abbreviation representation into the
+ * corresponding external one recognized by :map/:abbrev commands;
+ * respects the current B/k/< settings of 'cpoption'.
+ *
+ * This function is called when expanding mappings/abbreviations on the
+ * command-line, and for building the "Ambiguous mapping..." error mess�ge.
+ *
+ * It uses a growarray to build the translation string since the
+ * latter can be wider than the original description. The caller has to
+ * free the string afterwards.
+ *
+ * Returns NULL when there is a problem.
+ */
+    char_u *
+translate_mapping(str, expmap)
+    char_u	*str;
+    int		expmap;  /* TRUE when expanding mappings on command-line */
+{
+    garray_T	ga;
+    int		c;
+    int		modifiers;
+    int		cpo_bslash;
+    int		cpo_special;
+    int		cpo_keycode;
+
+    ga_init(&ga);
+    ga.ga_itemsize = 1;
+    ga.ga_growsize = 40;
+
+    cpo_bslash = (vim_strchr(p_cpo, CPO_BSLASH) != NULL);
+    cpo_special = (vim_strchr(p_cpo, CPO_SPECI) != NULL);
+    cpo_keycode = (vim_strchr(p_cpo, CPO_KEYCODE) == NULL);
+
+    for (; *str; ++str)
+    {
+	c = *str;
+	if (c == K_SPECIAL && str[1] != NUL && str[2] != NUL)
+	{
+	    modifiers = 0;
+	    if (str[1] == KS_MODIFIER)
+	    {
+		str++;
+		modifiers = *++str;
+		c = *++str;
+	    }
+	    if (cpo_special && cpo_keycode && c == K_SPECIAL && !modifiers)
+	    {
+		int	i;
+
+		/* try to find special key in termcodes */
+		for (i = 0; i < tc_len; ++i)
+		    if (termcodes[i].name[0] == str[1]
+					    && termcodes[i].name[1] == str[2])
+			break;
+		if (i < tc_len)
+		{
+		    ga_concat(&ga, termcodes[i].code);
+		    str += 2;
+		    continue; /* for (str) */
+		}
+	    }
+	    if (c == K_SPECIAL && str[1] != NUL && str[2] != NUL)
+	    {
+		if (expmap && cpo_special)
+		{
+		    ga_clear(&ga);
+		    return NULL;
+		}
+		c = TO_SPECIAL(str[1], str[2]);
+		if (c == K_ZERO)	/* display <Nul> as ^@ */
+		    c = NUL;
+		str += 2;
+	    }
+	    if (IS_SPECIAL(c) || modifiers)	/* special key */
+	    {
+		if (expmap && cpo_special)
+		{
+		    ga_clear(&ga);
+		    return NULL;
+		}
+		ga_concat(&ga, get_special_key_name(c, modifiers));
+		continue; /* for (str) */
+	    }
+	}
+	if (c == ' ' || c == '\t' || c == Ctrl_J || c == Ctrl_V
+	    || (c == '<' && !cpo_special) || (c == '\\' && !cpo_bslash))
+	    ga_append(&ga, cpo_bslash ? Ctrl_V : '\\');
+	if (c)
+	    ga_append(&ga, c);
+    }
+    ga_append(&ga, NUL);
+    return (char_u *)(ga.ga_data);
+}
+#endif
+
+#if (defined(WIN3264) && !defined(FEAT_GUI)) || defined(PROTO)
+static char ksme_str[20];
+static char ksmr_str[20];
+static char ksmd_str[20];
+
+/*
+ * For Win32 console: update termcap codes for existing console attributes.
+ */
+    void
+update_tcap(attr)
+    int attr;
+{
+    struct builtin_term *p;
+
+    p = find_builtin_term(DEFAULT_TERM);
+    sprintf(ksme_str, IF_EB("\033|%dm", ESC_STR "|%dm"), attr);
+    sprintf(ksmd_str, IF_EB("\033|%dm", ESC_STR "|%dm"),
+				     attr | 0x08);  /* FOREGROUND_INTENSITY */
+    sprintf(ksmr_str, IF_EB("\033|%dm", ESC_STR "|%dm"),
+				 ((attr & 0x0F) << 4) | ((attr & 0xF0) >> 4));
+
+    while (p->bt_string != NULL)
+    {
+      if (p->bt_entry == (int)KS_ME)
+	  p->bt_string = &ksme_str[0];
+      else if (p->bt_entry == (int)KS_MR)
+	  p->bt_string = &ksmr_str[0];
+      else if (p->bt_entry == (int)KS_MD)
+	  p->bt_string = &ksmd_str[0];
+      ++p;
+    }
+}
+#endif
--- /dev/null
+++ b/term.h
@@ -1,0 +1,164 @@
+/* vi:set ts=8 sts=4 sw=4:
+ *
+ * VIM - Vi IMproved	by Bram Moolenaar
+ *
+ * Do ":help uganda"  in Vim to read copying and usage conditions.
+ * Do ":help credits" in Vim to see a list of people who contributed.
+ */
+
+/*
+ * This file contains the defines for the machine dependent escape sequences
+ * that the editor needs to perform various operations. All of the sequences
+ * here are optional, except "cm" (cursor motion).
+ */
+
+#if defined(SASC) && SASC < 658
+/*
+ * The SAS C compiler has a bug that makes typedefs being forgot in include
+ * files.  Has been fixed in version 6.58.
+ */
+typedef unsigned char char_u;
+#endif
+
+/*
+ * Index of the termcap codes in the term_strings array.
+ */
+enum SpecialKey
+{
+    KS_NAME = 0,/* name of this terminal entry */
+    KS_CE,	/* clear to end of line */
+    KS_AL,	/* add new blank line */
+    KS_CAL,	/* add number of blank lines */
+    KS_DL,	/* delete line */
+    KS_CDL,	/* delete number of lines */
+    KS_CS,	/* scroll region */
+    KS_CL,	/* clear screen */
+    KS_CD,	/* clear to end of display */
+    KS_UT,	/* clearing uses current background color */
+    KS_DA,	/* text may be scrolled down from up */
+    KS_DB,	/* text may be scrolled up from down */
+    KS_VI,	/* cursor invisible */
+    KS_VE,	/* cursor visible */
+    KS_VS,	/* cursor very visible */
+    KS_ME,	/* normal mode */
+    KS_MR,	/* reverse mode */
+    KS_MD,	/* bold mode */
+    KS_SE,	/* normal mode */
+    KS_SO,	/* standout mode */
+    KS_CZH,	/* italic mode start */
+    KS_CZR,	/* italic mode end */
+    KS_UE,	/* exit underscore (underline) mode */
+    KS_US,	/* underscore (underline) mode */
+    KS_UCE,	/* exit undercurl mode */
+    KS_UCS,	/* undercurl mode */
+    KS_MS,	/* save to move cur in reverse mode */
+    KS_CM,	/* cursor motion */
+    KS_SR,	/* scroll reverse (backward) */
+    KS_CRI,	/* cursor number of chars right */
+    KS_VB,	/* visual bell */
+    KS_KS,	/* put term in "keypad transmit" mode */
+    KS_KE,	/* out of "keypad transmit" mode */
+    KS_TI,	/* put terminal in termcap mode */
+    KS_TE,	/* out of termcap mode */
+    KS_BC,	/* backspace character (cursor left) */
+    KS_CCS,	/* cur is relative to scroll region */
+    KS_CCO,	/* number of colors */
+    KS_CSF,	/* set foreground color */
+    KS_CSB,	/* set background color */
+    KS_XS,	/* standout not erased by overwriting (hpterm) */
+    KS_MB,	/* blink mode */
+    KS_CAF,	/* set foreground color (ANSI) */
+    KS_CAB,	/* set background color (ANSI) */
+    KS_LE,	/* cursor left (mostly backspace) */
+    KS_ND,	/* cursor right */
+    KS_CIS,	/* set icon text start */
+    KS_CIE,	/* set icon text end */
+    KS_TS,	/* set window title start (to status line)*/
+    KS_FS,	/* set window title end (from status line) */
+    KS_CWP,	/* set window position in pixels */
+    KS_CWS,	/* set window size in characters */
+    KS_CRV,	/* request version string */
+    KS_CSI,	/* start insert mode (bar cursor) */
+    KS_CEI,	/* end insert mode (block cursor) */
+#ifdef FEAT_VERTSPLIT
+    KS_CSV,	/* scroll region vertical */
+#endif
+    KS_OP	/* original color pair */
+};
+
+#define KS_LAST	    KS_OP
+
+/*
+ * the terminal capabilities are stored in this array
+ * IMPORTANT: When making changes, note the following:
+ * - there should be an entry for each code in the builtin termcaps
+ * - there should be an option for each code in option.c
+ * - there should be code in term.c to obtain the value from the termcap
+ */
+
+extern char_u *(term_strings[]);    /* current terminal strings */
+
+/*
+ * strings used for terminal
+ */
+#define T_NAME	(term_str(KS_NAME))	/* terminal name */
+#define T_CE	(term_str(KS_CE))	/* clear to end of line */
+#define T_AL	(term_str(KS_AL))	/* add new blank line */
+#define T_CAL	(term_str(KS_CAL))	/* add number of blank lines */
+#define T_DL	(term_str(KS_DL))	/* delete line */
+#define T_CDL	(term_str(KS_CDL))	/* delete number of lines */
+#define T_CS	(term_str(KS_CS))	/* scroll region */
+#define T_CSV	(term_str(KS_CSV))	/* scroll region vertical */
+#define T_CL	(term_str(KS_CL))	/* clear screen */
+#define T_CD	(term_str(KS_CD))	/* clear to end of display */
+#define T_UT	(term_str(KS_UT))	/* clearing uses background color */
+#define T_DA	(term_str(KS_DA))	/* text may be scrolled down from up */
+#define T_DB	(term_str(KS_DB))	/* text may be scrolled up from down */
+#define T_VI	(term_str(KS_VI))	/* cursor invisible */
+#define T_VE	(term_str(KS_VE))	/* cursor visible */
+#define T_VS	(term_str(KS_VS))	/* cursor very visible */
+#define T_ME	(term_str(KS_ME))	/* normal mode */
+#define T_MR	(term_str(KS_MR))	/* reverse mode */
+#define T_MD	(term_str(KS_MD))	/* bold mode */
+#define T_SE	(term_str(KS_SE))	/* normal mode */
+#define T_SO	(term_str(KS_SO))	/* standout mode */
+#define T_CZH	(term_str(KS_CZH))	/* italic mode start */
+#define T_CZR	(term_str(KS_CZR))	/* italic mode end */
+#define T_UE	(term_str(KS_UE))	/* exit underscore (underline) mode */
+#define T_US	(term_str(KS_US))	/* underscore (underline) mode */
+#define T_UCE	(term_str(KS_UCE))	/* exit undercurl mode */
+#define T_UCS	(term_str(KS_UCS))	/* undercurl mode */
+#define T_MS	(term_str(KS_MS))	/* save to move cur in reverse mode */
+#define T_CM	(term_str(KS_CM))	/* cursor motion */
+#define T_SR	(term_str(KS_SR))	/* scroll reverse (backward) */
+#define T_CRI	(term_str(KS_CRI))	/* cursor number of chars right */
+#define T_VB	(term_str(KS_VB))	/* visual bell */
+#define T_KS	(term_str(KS_KS))	/* put term in "keypad transmit" mode */
+#define T_KE	(term_str(KS_KE))	/* out of "keypad transmit" mode */
+#define T_TI	(term_str(KS_TI))	/* put terminal in termcap mode */
+#define T_TE	(term_str(KS_TE))	/* out of termcap mode */
+#define T_BC	(term_str(KS_BC))	/* backspace character */
+#define T_CCS	(term_str(KS_CCS))	/* cur is relative to scroll region */
+#define T_CCO	(term_str(KS_CCO))	/* number of colors */
+#define T_CSF	(term_str(KS_CSF))	/* set foreground color */
+#define T_CSB	(term_str(KS_CSB))	/* set background color */
+#define T_XS	(term_str(KS_XS))	/* standout not erased by overwriting */
+#define T_MB	(term_str(KS_MB))	/* blink mode */
+#define T_CAF	(term_str(KS_CAF))	/* set foreground color (ANSI) */
+#define T_CAB	(term_str(KS_CAB))	/* set background color (ANSI) */
+#define T_LE	(term_str(KS_LE))	/* cursor left */
+#define T_ND	(term_str(KS_ND))	/* cursor right */
+#define T_CIS	(term_str(KS_CIS))	/* set icon text start */
+#define T_CIE	(term_str(KS_CIE))	/* set icon text end */
+#define T_TS	(term_str(KS_TS))	/* set window title start */
+#define T_FS	(term_str(KS_FS))	/* set window title end */
+#define T_CWP	(term_str(KS_CWP))	/* window position */
+#define T_CWS	(term_str(KS_CWS))	/* window size */
+#define T_CSI	(term_str(KS_CSI))	/* start insert mode */
+#define T_CEI	(term_str(KS_CEI))	/* end insert mode */
+#define T_CRV	(term_str(KS_CRV))	/* request version string */
+#define T_OP	(term_str(KS_OP))	/* original color pair */
+
+#define TMODE_COOK  0	/* terminal mode for external cmds and Ex mode */
+#define TMODE_SLEEP 1	/* terminal mode for sleeping (cooked but no echo) */
+#define TMODE_RAW   2	/* terminal mode for Normal and Insert mode */
--- /dev/null
+++ b/termlib.c
@@ -1,0 +1,628 @@
+/* vi:set ts=8 sts=4 sw=4: */
+/*
+ * The following software is (C) 1984 Peter da Silva, the Mad Australian, in
+ * the public domain. It may be re-distributed for any purpose with the
+ * inclusion of this notice.
+ */
+
+/* Modified by Bram Moolenaar for use with VIM - Vi Improved. */
+/* A few bugs removed by Olaf 'Rhialto' Seibert. */
+
+/* TERMLIB: Terminal independent database. */
+
+#include "vim.h"
+#include "termlib.pro"
+
+#if !defined(AMIGA) && !defined(VMS) && !defined(MACOS) && !defined(RISCOS)
+# include <sgtty.h>
+#endif
+
+static int  getent __ARGS((char *, char *, FILE *, int));
+static int  nextent __ARGS((char *, FILE *, int));
+static int  _match __ARGS((char *, char *));
+static char *_addfmt __ARGS((char *, char *, int));
+static char *_find __ARGS((char *, char *));
+
+/*
+ * Global variables for termlib
+ */
+
+char	*tent;		      /* Pointer to terminal entry, set by tgetent */
+char	PC = 0;		      /* Pad character, default NULL */
+char	*UP = 0, *BC = 0;     /* Pointers to UP and BC strings from database */
+short	ospeed;		      /* Baud rate (1-16, 1=300, 16=19200), as in stty */
+
+/*
+ * Module: tgetent
+ *
+ * Purpose: Get termcap entry for <term> into buffer at <tbuf>.
+ *
+ * Calling conventions: char tbuf[TBUFSZ+], term=canonical name for terminal.
+ *
+ * Returned values: 1 = success, -1 = can't open file,
+ *	    0 = can't find terminal.
+ *
+ * Notes:
+ * - Should probably supply static buffer.
+ * - Uses environment variables "TERM" and "TERMCAP". If TERM = term (that is,
+ *   if the argument matches the environment) then it looks at TERMCAP.
+ * - If TERMCAP begins with a slash, then it assumes this is the file to
+ *   search rather than /etc/termcap.
+ * - If TERMCAP does not begin with a slash, and it matches TERM, then this is
+ *   used as the entry.
+ * - This could be simplified considerably for non-UNIX systems.
+ */
+
+#ifndef TERMCAPFILE
+# ifdef AMIGA
+#  define TERMCAPFILE "s:termcap"
+# else
+#  ifdef VMS
+#   define TERMCAPFILE "VIMRUNTIME:termcap"
+#  else
+#   define TERMCAPFILE "/etc/termcap"
+#  endif
+# endif
+#endif
+
+    int
+tgetent(tbuf, term)
+    char    *tbuf;		/* Buffer to hold termcap entry, TBUFSZ bytes max */
+    char    *term;		/* Name of terminal */
+{
+    char    tcbuf[32];		/* Temp buffer to handle */
+    char    *tcptr = tcbuf;	/* extended entries */
+    char    *tcap = TERMCAPFILE; /* Default termcap file */
+    char    *tmp;
+    FILE    *termcap;
+    int	    retval = 0;
+    int	    len;
+
+    if ((tmp = (char *)mch_getenv((char_u *)"TERMCAP")) != NULL)
+    {
+	if (*tmp == '/')		/* TERMCAP = name of termcap file */
+	{
+	    tcap = tmp ;
+#if defined(AMIGA)
+	    /* Convert /usr/share/lib/termcap to usr:share/lib/termcap */
+	    tcap++;
+	    tmp = strchr(tcap, '/');
+	    if (tmp)
+		*tmp = ':';
+#endif
+	}
+	else				/* TERMCAP = termcap entry itself */
+	{
+	    int tlen = strlen(term);
+
+	    while (*tmp && *tmp != ':')		/* Check if TERM matches */
+	    {
+		char *nexttmp;
+
+		while (*tmp == '|')
+		    tmp++;
+		nexttmp  = _find(tmp, ":|");	/* Rhialto */
+		if (tmp+tlen == nexttmp && _match(tmp, term) == tlen)
+		{
+		    strcpy(tbuf, tmp);
+		    tent = tbuf;
+		    return 1;
+		}
+		else
+		    tmp = nexttmp;
+	    }
+	}
+    }
+    if (!(termcap = mch_fopen(tcap, "r")))
+    {
+	strcpy(tbuf, tcap);
+	return -1;
+    }
+
+    len = 0;
+    while (getent(tbuf + len, term, termcap, TBUFSZ - len))
+    {
+	tcptr = tcbuf;				/* Rhialto */
+	if ((term = tgetstr("tc", &tcptr)))	/* extended entry */
+	{
+	    rewind(termcap);
+	    len = strlen(tbuf);
+	}
+	else
+	{
+	    retval = 1;
+	    tent = tbuf;	/* reset it back to the beginning */
+	    break;
+	}
+    }
+    fclose(termcap);
+    return retval;
+}
+
+    static int
+getent(tbuf, term, termcap, buflen)
+    char    *tbuf, *term;
+    FILE    *termcap;
+    int	    buflen;
+{
+    char    *tptr;
+    int	    tlen = strlen(term);
+
+    while (nextent(tbuf, termcap, buflen))	/* For each possible entry */
+    {
+	tptr = tbuf;
+	while (*tptr && *tptr != ':')		/* : terminates name field */
+	{
+	    char    *nexttptr;
+
+	    while (*tptr == '|')		/* | separates names */
+		tptr++;
+	    nexttptr = _find(tptr, ":|");	/* Rhialto */
+	    if (tptr + tlen == nexttptr &&
+		_match(tptr, term) == tlen)	/* FOUND! */
+	    {
+		tent = tbuf;
+		return 1;
+	    }
+	    else				/* Look for next name */
+		tptr = nexttptr;
+	}
+    }
+    return 0;
+}
+
+    static int
+nextent(tbuf, termcap, buflen)		/* Read 1 entry from TERMCAP file */
+    char    *tbuf;
+    FILE    *termcap;
+    int	    buflen;
+{
+    char *lbuf = tbuf;				/* lbuf=line buffer */
+				/* read lines straight into buffer */
+
+    while (lbuf < tbuf+buflen &&		/* There's room and */
+	  fgets(lbuf, (int)(tbuf+buflen-lbuf), termcap)) /* another line */
+    {
+	int llen = strlen(lbuf);
+
+	if (*lbuf == '#')			/* eat comments */
+	    continue;
+	if (lbuf[-1] == ':' &&			/* and whitespace */
+	    lbuf[0] == '\t' &&
+	    lbuf[1] == ':')
+	{
+	    strcpy(lbuf, lbuf+2);
+	    llen -= 2;
+	}
+	if (lbuf[llen-2] == '\\')		/* and continuations */
+	    lbuf += llen-2;
+	else
+	{
+	    lbuf[llen-1]=0;			/* no continuation, return */
+	    return 1;
+	}
+    }
+
+    return 0;					/* ran into end of file */
+}
+
+/*
+ * Module: tgetflag
+ *
+ * Purpose: returns flag true or false as to the existence of a given entry.
+ * used with 'bs', 'am', etc...
+ *
+ * Calling conventions: id is the 2 character capability id.
+ *
+ * Returned values: 1 for success, 0 for failure.
+ */
+
+    int
+tgetflag(id)
+    char *id;
+{
+    char    buf[256], *ptr = buf;
+
+    return tgetstr(id, &ptr) ? 1 : 0;
+}
+
+/*
+ * Module: tgetnum
+ *
+ * Purpose: get numeric value such as 'li' or 'co' from termcap.
+ *
+ * Calling conventions: id = 2 character id.
+ *
+ * Returned values: -1 for failure, else numerical value.
+ */
+
+    int
+tgetnum(id)
+    char *id;
+{
+    char *ptr, buf[256];
+    ptr = buf;
+
+    if (tgetstr(id, &ptr))
+	return atoi(buf);
+    else
+	return 0;
+}
+
+/*
+ * Module: tgetstr
+ *
+ * Purpose: get terminal capability string from database.
+ *
+ * Calling conventions: id is the two character capability id.
+ *	    (*buf) points into a hold buffer for the
+ *	    id. the capability is copied into the buffer
+ *	    and (*buf) is advanced to point to the next
+ *	    free byte in the buffer.
+ *
+ * Returned values: 0 = no such entry, otherwise returns original
+ *	    (*buf) (now a pointer to the string).
+ *
+ * Notes
+ *	It also decodes certain escape sequences in the buffer.
+ *  they should be obvious from the code:
+ *	\E = escape.
+ *	\n, \r, \t, \f, \b match the 'c' escapes.
+ *	^x matches control-x (^@...^_).
+ *	\nnn matches nnn octal.
+ *	\x, where x is anything else, matches x. I differ
+ *  from the standard library here, in that I allow ^: to match
+ *  :.
+ *
+ */
+
+    char *
+tgetstr(id, buf)
+    char	*id, **buf;
+{
+    int		len = strlen(id);
+    char	*tmp=tent;
+    char	*hold;
+    int		i;
+
+    do {
+	tmp = _find(tmp, ":");			/* For each field */
+	while (*tmp == ':')			/* skip empty fields */
+	    tmp++;
+	if (!*tmp)
+	    break;
+
+	if (_match(id, tmp) == len) {
+	    tmp += len;				/* find '=' '@' or '#' */
+	    if (*tmp == '@')			/* :xx@: entry for tc */
+		return 0;			/* deleted entry */
+	    hold= *buf;
+	    while (*++tmp && *tmp != ':') {	/* not at end of field */
+		switch(*tmp) {
+		case '\\':			/* Expand escapes here */
+		    switch(*++tmp) {
+		    case 0:			/* ignore backslashes */
+			tmp--;			/* at end of entry */
+			break;			/* shouldn't happen */
+		    case 'e':
+		    case 'E':			/* ESC */
+			*(*buf)++ = ESC;
+			break;
+		    case 'n':			/* \n */
+			*(*buf)++ = '\n';
+			break;
+		    case 'r':			/* \r */
+			*(*buf)++ = '\r';
+			break;
+		    case 't':			/* \t */
+			*(*buf)++ = '\t';
+			break;
+		    case 'b':			/* \b */
+			*(*buf)++ = '\b';
+			break;
+		    case 'f':			/* \f */
+			*(*buf)++ = '\f';
+			break;
+		    case '0':			/* \nnn */
+		    case '1':
+		    case '2':
+		    case '3':
+		    case '4':
+		    case '5':
+		    case '6':
+		    case '7':
+		    case '8':
+		    case '9':
+			**buf = 0;
+			    /* get up to three digits */
+			for (i = 0; i < 3 && VIM_ISDIGIT(*tmp); ++i)
+			    **buf = **buf * 8 + *tmp++ - '0';
+			(*buf)++;
+			tmp--;
+			break;
+		    default:			/* \x, for all other x */
+			*(*buf)++= *tmp;
+		    }
+		    break;
+		case '^':			/* control characters */
+		    ++tmp;
+		    *(*buf)++ = Ctrl_chr(*tmp);
+		    break;
+		default:
+		    *(*buf)++ = *tmp;
+		}
+	    }
+	    *(*buf)++ = 0;
+	    return hold;
+	}
+    } while (*tmp);
+
+    return 0;
+}
+
+/*
+ * Module: tgoto
+ *
+ * Purpose: decode cm cursor motion string.
+ *
+ * Calling conventions: cm is cursor motion string.  line, col, are the
+ * desired destination.
+ *
+ * Returned values: a string pointing to the decoded string, or "OOPS" if it
+ * cannot be decoded.
+ *
+ * Notes
+ *	The accepted escapes are:
+ *	%d	 as in printf, 0 origin.
+ *	%2, %3   like %02d, %03d in printf.
+ *	%.	 like %c
+ *	%+x	 adds <x> to value, then %.
+ *	%>xy     if value>x, adds y. No output.
+ *	%i	 increments line& col, no output.
+ *	%r	 reverses order of line&col. No output.
+ *	%%	 prints as a single %.
+ *	%n	 exclusive or row & col with 0140.
+ *	%B	 BCD, no output.
+ *	%D	 reverse coding (x-2*(x%16)), no output.
+ */
+
+    char *
+tgoto(cm, col, line)
+    char	*cm;				/* cm string, from termcap */
+    int col,					/* column, x position */
+    line;					/* line, y position */
+{
+    char    gx, gy,				/* x, y */
+	*ptr,					/* pointer in 'cm' */
+	reverse = 0,				/* reverse flag */
+	*bufp,					/* pointer in returned string */
+	addup = 0,				/* add upline */
+	addbak = 0,				/* add backup */
+	c;
+    static char buffer[32];
+
+    if (!cm)
+	return "OOPS";				/* Kludge, but standard */
+
+    bufp = buffer;
+    ptr = cm;
+
+    while (*ptr) {
+	if ((c = *ptr++) != '%') {		/* normal char */
+	    *bufp++ = c;
+	} else {				/* % escape */
+	    switch(c = *ptr++) {
+	    case 'd':				/* decimal */
+		bufp = _addfmt(bufp, "%d", line);
+		line = col;
+		break;
+	    case '2':				/* 2 digit decimal */
+		bufp = _addfmt(bufp, "%02d", line);
+		line = col;
+		break;
+	    case '3':				/* 3 digit decimal */
+		bufp = _addfmt(bufp, "%03d", line);
+		line = col;
+		break;
+	    case '>':				/* %>xy: if >x, add y */
+		gx = *ptr++;
+		gy = *ptr++;
+		if (col>gx) col += gy;
+		if (line>gx) line += gy;
+		break;
+	    case '+':				/* %+c: add c */
+		line += *ptr++;
+	    case '.':				/* print x/y */
+		if (line == '\t' ||		/* these are */
+		   line == '\n' ||		/* chars that */
+		   line == '\004' ||		/* UNIX hates */
+		   line == '\0') {
+		    line++;			/* so go to next pos */
+		    if (reverse == (line == col))
+			addup=1;		/* and mark UP */
+		    else
+			addbak=1;		/* or BC */
+		}
+		*bufp++=line;
+		line = col;
+		break;
+	    case 'r':				/* r: reverse */
+		gx = line;
+		line = col;
+		col = gx;
+		reverse = 1;
+		break;
+	    case 'i':			/* increment (1-origin screen) */
+		col++;
+		line++;
+		break;
+	    case '%':				/* %%=% literally */
+		*bufp++='%';
+		break;
+	    case 'n':				/* magic DM2500 code */
+		line ^= 0140;
+		col ^= 0140;
+		break;
+	    case 'B':				/* bcd encoding */
+		line = line/10<<4+line%10;
+		col = col/10<<4+col%10;
+		break;
+	    case 'D':				/* magic Delta Data code */
+		line = line-2*(line&15);
+		col = col-2*(col&15);
+		break;
+	    default:				/* Unknown escape */
+		return "OOPS";
+	    }
+	}
+    }
+
+    if (addup)					/* add upline */
+	if (UP) {
+	    ptr=UP;
+	    while (VIM_ISDIGIT(*ptr) || *ptr == '.')
+		ptr++;
+	    if (*ptr == '*')
+		ptr++;
+	    while (*ptr)
+		*bufp++ = *ptr++;
+	}
+
+    if (addbak)					/* add backspace */
+	if (BC) {
+	    ptr=BC;
+	    while (VIM_ISDIGIT(*ptr) || *ptr == '.')
+		ptr++;
+	    if (*ptr == '*')
+		ptr++;
+	    while (*ptr)
+		*bufp++ = *ptr++;
+	}
+	else
+	    *bufp++='\b';
+
+    *bufp = 0;
+
+    return(buffer);
+}
+
+/*
+ * Module: tputs
+ *
+ * Purpose: decode padding information
+ *
+ * Calling conventions: cp = string to be padded, affcnt = # of items affected
+ *	(lines, characters, whatever), outc = routine to output 1 character.
+ *
+ * Returned values: none
+ *
+ * Notes
+ *	cp has padding information ahead of it, in the form
+ *  nnnTEXT or nnn*TEXT. nnn is the number of milliseconds to delay,
+ *  and may be a decimal (nnn.mmm). If the asterisk is given, then
+ *  the delay is multiplied by afcnt. The delay is produced by outputting
+ *  a number of nulls (or other padding char) after printing the
+ *  TEXT.
+ *
+ */
+
+long _bauds[16]={
+    0,	50, 75,	110,
+    134,    150,    200,    300,
+    600,    1200,   1800,   2400,
+    4800,   9600,   19200,  19200 };
+
+    int
+tputs(cp, affcnt, outc)
+    char *cp;				/* string to print */
+    int affcnt;				/* Number of lines affected */
+    void (*outc) __ARGS((unsigned int));/* routine to output 1 character */
+{
+    long    frac,			/* 10^(#digits after decimal point) */
+	counter,			/* digits */
+	atol __ARGS((const char *));
+
+    if (VIM_ISDIGIT(*cp)) {
+	counter = 0;
+	frac = 1000;
+	while (VIM_ISDIGIT(*cp))
+	    counter = counter * 10L + (long)(*cp++ - '0');
+	if (*cp == '.')
+	    while (VIM_ISDIGIT(*++cp)) {
+		counter = counter * 10L + (long)(*cp++ - '0');
+		frac = frac * 10;
+	    }
+	if (*cp!='*') {			/* multiply by affected lines */
+	    if (affcnt>1) affcnt = 1;
+	}
+	else
+	    cp++;
+
+	/* Calculate number of characters for padding counter/frac ms delay */
+	if (ospeed)
+	    counter = (counter * _bauds[ospeed] * (long)affcnt) / frac;
+
+	while (*cp)			/* output string */
+	    (*outc)(*cp++);
+	if (ospeed)
+	    while (counter--)		/* followed by pad characters */
+		(*outc)(PC);
+    }
+    else
+	while (*cp)
+	    (*outc)(*cp++);
+    return 0;
+}
+
+/*
+ * Module: tutil.c
+ *
+ * Purpose: Utility routines for TERMLIB functions.
+ *
+ */
+    static int
+_match(s1, s2)		/* returns length of text common to s1 and s2 */
+    char *s1, *s2;
+{
+    int i = 0;
+
+    while (s1[i] && s1[i] == s2[i])
+	i++;
+
+    return i;
+}
+
+/*
+ * finds next c in s that's a member of set, returns pointer
+ */
+    static char *
+_find(s, set)
+    char *s, *set;
+{
+    for(; *s; s++)
+    {
+	char	*ptr = set;
+
+	while (*ptr && *s != *ptr)
+	    ptr++;
+
+	if (*ptr)
+	    return s;
+    }
+
+    return s;
+}
+
+/*
+ * add val to buf according to format fmt
+ */
+    static char *
+_addfmt(buf, fmt, val)
+    char *buf, *fmt;
+    int val;
+{
+    sprintf(buf, fmt, val);
+    while (*buf)
+	buf++;
+    return buf;
+}
--- /dev/null
+++ b/testdir/dotest.in
@@ -1,0 +1,3 @@
+:set cp
+:map dotest /^STARTTEST
j:set ff=unix cpo-=A
:.,/ENDTEST/-1w! Xdotest
:set ff& cpo+=A
nj0:so! Xdotest
dotest
+dotest
--- /dev/null
+++ b/testdir/main.aap
@@ -1,0 +1,58 @@
+#
+# Makefile to run al tests for Vim
+#
+
+VimProg ?= ../vim
+
+Scripts = test1.out test2.out test3.out test4.out test5.out test6.out
+		test7.out test8.out test9.out test10.out test11.out
+		test12.out  test13.out test14.out test15.out test17.out
+		test18.out test19.out test20.out test21.out test22.out
+		test23.out test24.out test25.out test26.out test27.out
+		test28.out test29.out test30.out test31.out test32.out
+		test33.out test34.out test35.out test36.out test37.out
+		test38.out test39.out test40.out test41.out test42.out
+		test43.out test44.out test45.out test46.out test47.out
+		test48.out test49.out
+
+ScriptsGUI = test16.out
+
+# Build "nongui" when no target was specified.
+nongui:	newlog $Scripts
+	:print
+	:cat test.log
+	:print ALL DONE
+
+# Build "ngui" when specified.
+gui:	newlog $Scripts $ScriptsGUI
+	:print
+	:cat test.log
+	:print ALL DONE
+
+$Scripts $ScriptsGUI: $VimProg
+
+clean:
+	:del {r}{force} *.out test.log tiny.vim small.vim mbyte.vim test.ok X*
+
+# test1 is special, it checks for features
+test1.out: test1.in
+	:del {force} test1.failed tiny.vim small.vim mbyte.vim
+	:sys {i} $VimProg -u unix.vim -U NONE --noplugin -s dotest.in test1.in
+	@if os.system("diff test.out test1.ok") != 0:
+		:error test1 FAILED - Something basic is wrong
+	:move {force} test.out test1.out
+	:del {r}{force} X*
+
+:rule %.out : %.in
+	:del {force} $(match).failed test.ok
+	:copy $(match).ok test.ok
+	:sys {i} $VimProg -u unix.vim -U NONE --noplugin -s dotest.in $(match).in
+	@if os.system("diff test.out " + match + ".ok") != 0:
+		:print $match FAILED >>test.log
+		:move {force} test.out $(match).failed
+	@else:
+		:move {force} test.out $(match).out
+	:del {r}{force} X* test.ok
+
+newlog:
+	:print Test results: >! test.log
--- /dev/null
+++ b/testdir/test1.in
@@ -1,0 +1,40 @@
+
+First a simple test to check if the test script works.
+
+If Vim was not compiled with the +eval feature, the small.vim script will be
+set to copy the test.ok file to test.out, so that it looks like the test
+succeeded.  Otherwise an empty small.vim is written.  small.vim is sourced by
+tests that require the +eval feature or other features that are missing in the
+small version.
+
+If Vim was not compiled with the +windows feature, the tiny.vim script will be
+set like small.vim above.  tiny.vim is sourced by tests that require the
++windows feature or other features that are missing in the tiny version.
+
+If Vim was not compiled with the +multi_byte feature, the mbyte.vim script will be set like small.vim above.  mbyte.vim is sourced by tests that require the
++multi_byte feature.
+
+STARTTEST
+:" Write a single line to test.out to check if testing works at all.
+:%d
+athis is a test:w! test.out
+:" Create small.vim and tiny.vim empty, create mbyte.vim to skip the test.
+0D:w! small.vim
+:w! tiny.vim
+ae! test.ok
+w! test.out
+qa!
+:w! mbyte.vim
+:" If +multi_byte feature supported, make mbyte.vim empty.
+:if has("multi_byte") | sp another | w! mbyte.vim | q | endif
+:" If +eval feature supported quit here, leaving tiny.vim and small.vim empty.
+:" Otherwise write small.vim to skip the test.
+:if 1 | q! | endif
+:w! small.vim
+:" If +windows feature not supported :sp will fail and tiny.vim will be
+:" written to skip the test.
+:sp another
+:wq! tiny.vim
+:qa!
+ENDTEST
+
--- /dev/null
+++ b/testdir/test1.ok
@@ -1,0 +1,1 @@
+this is a test
--- /dev/null
+++ b/testdir/test10.in
@@ -1,0 +1,57 @@
+Test for 'errorformat'.  This will fail if the quickfix feature was disabled.
+
+STARTTEST
+:so small.vim
+:/start of errorfile/,/end of errorfile/w! Xerrorfile
+:/start of testfile/,/end of testfile/w! Xtestfile
+:cf Xerrorfile
+rA
+:cn
+rB
+:cn
+rC
+:cn
+rD
+:cn
+rE
+:w! test.out             " Write contents of this file
+:qa!
+ENDTEST
+
+start of errorfile
+"Xtestfile", line 4.12: 1506-045 (S) Undeclared identifier fd_set.
+"Xtestfile", line 7 col 19; this is an error
+gcc -c -DHAVE_CONFIsing-prototypes -I/usr/X11R6/include  version.c
+Xtestfile:13: parse error before `asd'
+make: *** [vim] Error 1
+in file "Xtestfile" linenr 16: there is an error
+
+2 returned
+"Xtestfile", linenr 19: yet another problem
+
+Does anyone know what is the problem and how to correction it?
+end of errorfile
+
+start of testfile
+line 2  xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
+line 3  xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
+line 4  xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
+line 5  xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
+line 6  xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
+line 7  xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
+line 8  xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
+line 9  xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
+line 10 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
+line 11 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
+line 12 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
+line 13 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
+line 14 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
+line 15 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
+line 16 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
+line 17 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
+line 18 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
+line 19 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
+line 20 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
+line 21 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
+line 22 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
+end of testfile
--- /dev/null
+++ b/testdir/test10.ok
@@ -1,0 +1,23 @@
+start of testfile
+line 2  xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
+line 3  xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
+line 4  xxxAxxxxxxxxxxxxxxxxxxxxxxxxxx
+line 5  xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
+line 6  xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
+line 7  xxxxxxxxxxBxxxxxxxxxxxxxxxxxxx
+line 8  xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
+line 9  xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
+line 10 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
+line 11 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
+line 12 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
+Cine 13 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
+line 14 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
+line 15 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
+Dine 16 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
+line 17 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
+line 18 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
+Eine 19 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
+line 20 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
+line 21 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
+line 22 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
+end of testfile
--- /dev/null
+++ b/testdir/test10a.in
@@ -1,0 +1,73 @@
+Test for 'errorformat'.
+
+STARTTEST
+:so small.vim
+:/start of errorfile/,/end of errorfile/w! Xerrorfile
+:/start of testfile/,/end of testfile/w! Xtestfile
+:cf Xerrorfile
+rA
+:cn
+rB
+:cn
+rC
+:cn
+rD
+:cn
+rE
+:w! test.out             " Write contents of this file
+:qa!
+ENDTEST
+
+start of errorfile
+
+                  printf(" %d \n", (number/other)%10 );
+..................^
+%CC-E-NOSEMI, Missing ";".
+at line number 4 in file SYS$DISK:XTESTFILE
+
+             other=10000000;
+.............^
+%CC-E-UNDECLARED, In this statement, "oszt" is not declared.
+at line number 7 in file SYS$DISK:XTESTFILE
+
+             for (i = 0; i<7 ; i++ ){
+..................^
+%CC-E-UNDECLARED, In this statement, "i" is not declared.
+at line number 16 in file SYS$DISK:XTESTFILE
+
+some other error somewhere here.
+...........................^
+%CC-W-WARRING, Sorry, but no expalnation for such an warring.
+at line number 19 in file SYS$DISK:XTESTFILE
+
+and finally some other error exactly here.
+.....................................^
+%CC-I-INFORMATIONAL, It should be some informational message.
+at line number 20 in file SYS$DISK:XTESTFILE
+
+Does anyone know what is the problem and how to correct ??  :)
+end of errorfile
+
+start of testfile
+01234567890123456789012345678901234567
+line 3  xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
+line 4  xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
+line 5  xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
+line 6  xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
+line 7  xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
+line 8  xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
+line 9  xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
+line 10 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
+line 11 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
+line 12 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
+line 13 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
+line 14 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
+line 15 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
+line 16 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
+line 17 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
+line 18 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
+line 19 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
+line 20 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
+line 21 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
+line 22 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
+end of testfile
--- /dev/null
+++ b/testdir/test10a.ok
@@ -1,0 +1,23 @@
+start of testfile
+01234567890123456789012345678901234567
+line 3  xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
+line 4  xxxxxxxxxxAxxxxxxxxxxxxxxxxxxx
+line 5  xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
+line 6  xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
+line 7  xxxxxBxxxxxxxxxxxxxxxxxxxxxxxx
+line 8  xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
+line 9  xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
+line 10 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
+line 11 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
+line 12 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
+line 13 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
+line 14 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
+line 15 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
+line 16 xxxxxxxxxxCxxxxxxxxxxxxxxxxxxx
+line 17 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
+line 18 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
+line 19 xxxxxxxxxxxxxxxxxxxDxxxxxxxxxx
+line 20 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxE
+line 21 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
+line 22 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
+end of testfile
--- /dev/null
+++ b/testdir/test11.in
@@ -1,0 +1,78 @@
+Tests for autocommands:
+- FileWritePre		writing a compressed file
+- FileReadPost		reading a compressed file
+- BufNewFile		reading a file template
+- BufReadPre		decompressing the file to be read
+- FilterReadPre		substituting characters in the temp file
+- FilterReadPost	substituting characters after filtering
+- FileReadPre		set options for decompression
+- FileReadPost		decompress the file
+
+Note: This test will fail if "gzip" is not available.
+$GZIP is made empty, "-v" would cause trouble.
+Use a FileChangedShell autocommand to avoid a prompt for "Xtestfile.gz" being
+modified outside of Vim (noticed on Solaris).
+
+STARTTEST
+:so small.vim
+:let $GZIP = ""
+:au FileChangedShell * echo "caught FileChangedShell"
+:set bin
+:au FileWritePre    *.gz   '[,']!gzip
+:au FileWritePost   *.gz   undo
+:/^start of testfile/,/^end of testfile/w! Xtestfile.gz
+:au FileReadPost    *.gz   '[,']!gzip -d
+:$r Xtestfile.gz                " Read and decompress the testfile
+:?startstart?,$w! test.out      " Write contents of this file
+:au BufNewFile      *.c    read Xtest.c
+:/^start of test.c/+1,/^end of test.c/-1w! Xtest.c
+:e! foo.c                       " Will load Xtest.c
+:au FileAppendPre   *.out  '[,']s/new/NEW/
+:au FileAppendPost  *.out  !cat Xtest.c >>test.out
+:w>>test.out                    " Append it to the output file
+:au! FileAppendPre
+:" setup autocommands to decompress before reading and re-compress afterwards
+:au BufReadPre      *.gz   !gzip -d <afile>
+:au BufReadPre      *.gz   call rename(expand("<afile>:r"), expand("<afile>"))
+:au BufReadPost     *.gz   call rename(expand("<afile>"), expand("<afile>:r"))
+:au BufReadPost     *.gz   !gzip <afile>:r
+:e! Xtestfile.gz                " Edit compressed file
+:w>>test.out                    " Append it to the output file
+:set shelltemp                  " need temp files here
+:au FilterReadPre   *.out  call rename(expand("<afile>"), expand("<afile>").".t")
+:au FilterReadPre   *.out  !sed s/e/E/ <afile>.t ><afile>
+:au FilterReadPre   *.out  !rm <afile>.t
+:au FilterReadPost  *.out  '[,']s/x/X/g
+:e! test.out                    " Edit the output file
+:23,$!cat
+:23,$s/\r$//                 " remove CR for when sed adds them
+:au! FileReadPre    *.gz   !gzip -d <afile>
+:au  FileReadPre    *.gz   call rename(expand("<afile>:r"), expand("<afile>"))
+:au! FileReadPost   *.gz   '[,']s/l/L/
+:$r Xtestfile.gz             " Read compressed file
+:w                           " write it, after filtering
+:au!             " remove all autocommands
+:e               " Edit test.out again
+:set nobin ff&   " use the default fileformat for writing
+:w
+:qa!
+ENDTEST
+
+startstart
+start of testfile
+line 2	Abcdefghijklmnopqrstuvwxyz
+line 3	xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
+line 4	Abcdefghijklmnopqrstuvwxyz
+line 5	xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
+line 6	Abcdefghijklmnopqrstuvwxyz
+line 7	xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
+line 8	Abcdefghijklmnopqrstuvwxyz
+line 9	xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
+line 10 Abcdefghijklmnopqrstuvwxyz
+end of testfile
+
+start of test.c
+/*
+ * Here is a new .c file
+ */
+end of test.c
--- /dev/null
+++ b/testdir/test11.ok
@@ -1,0 +1,61 @@
+startstart
+start of testfile
+line 2	Abcdefghijklmnopqrstuvwxyz
+line 3	xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
+line 4	Abcdefghijklmnopqrstuvwxyz
+line 5	xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
+line 6	Abcdefghijklmnopqrstuvwxyz
+line 7	xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
+line 8	Abcdefghijklmnopqrstuvwxyz
+line 9	xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
+line 10 Abcdefghijklmnopqrstuvwxyz
+end of testfile
+
+start of test.c
+/*
+ * Here is a new .c file
+ */
+end of test.c
+start of testfile
+line 2	Abcdefghijklmnopqrstuvwxyz
+line 3	xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
+line 4	Abcdefghijklmnopqrstuvwxyz
+linE 5	XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
+linE 6	AbcdefghijklmnopqrstuvwXyz
+linE 7	XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
+linE 8	AbcdefghijklmnopqrstuvwXyz
+linE 9	XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
+linE 10 AbcdefghijklmnopqrstuvwXyz
+End of testfile
+
+/*
+ * HEre is a NEW .c file
+ */
+/*
+ * HEre is a new .c file
+ */
+start of tEstfile
+linE 2	AbcdefghijklmnopqrstuvwXyz
+linE 3	XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
+linE 4	AbcdefghijklmnopqrstuvwXyz
+linE 5	XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
+linE 6	AbcdefghijklmnopqrstuvwXyz
+linE 7	XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
+linE 8	AbcdefghijklmnopqrstuvwXyz
+linE 9	XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
+linE 10 AbcdefghijklmnopqrstuvwXyz
+End of testfile
+/*
+ * HEre is a new .c file
+ */
+start of testfiLe
+Line 2	Abcdefghijklmnopqrstuvwxyz
+Line 3	xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
+Line 4	Abcdefghijklmnopqrstuvwxyz
+Line 5	xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
+Line 6	Abcdefghijklmnopqrstuvwxyz
+Line 7	xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
+Line 8	Abcdefghijklmnopqrstuvwxyz
+Line 9	xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
+Line 10 Abcdefghijklmnopqrstuvwxyz
+end of testfiLe
--- /dev/null
+++ b/testdir/test12.in
@@ -1,0 +1,52 @@
+Tests for 'directory' option.
+- ".", in same dir as file
+- "./dir", in directory relative to file
+- "dir", in directory relative to current dir
+
+STARTTEST
+:so small.vim
+:set nocompatible viminfo+=nviminfo
+:set dir=.,~
+:/start of testfile/,/end of testfile/w! Xtest1
+:" do an ls of the current dir to find the swap file (should not be there)
+:if has("unix")
+:  !ls .X*.swp >test.out
+:else
+:  r !ls X*.swp >test.out
+:endif
+:!echo first line >>test.out
+:e Xtest1
+:if has("unix")
+:" Do an ls of the current dir to find the swap file, remove the leading dot
+:" to make the result the same for all systems.
+:  r!ls .X*.swp
+:  s/\.*X/X/
+:  .w >>test.out
+:  undo
+:else
+:  !ls X*.swp >>test.out
+:endif
+:!echo under Xtest1.swp >>test.out
+:!mkdir Xtest2
+:set dir=./Xtest2,.,~
+:e Xtest1
+:!ls X*.swp >>test.out
+:!echo under under >>test.out
+:!ls Xtest2 >>test.out
+:!echo under Xtest1.swp >>test.out
+:!mkdir Xtest.je
+:/start of testfile/,/end of testfile/w! Xtest2/Xtest3
+:set dir=Xtest.je,~
+:e Xtest2/Xtest3
+:swap
+:!ls Xtest2 >>test.out
+:!echo under Xtest3 >>test.out
+:!ls Xtest.je >>test.out
+:!echo under Xtest3.swp >>test.out
+:qa!
+ENDTEST
+
+start of testfile
+line 2 Abcdefghij
+line 3 Abcdefghij
+end of testfile
--- /dev/null
+++ b/testdir/test12.ok
@@ -1,0 +1,10 @@
+first line
+Xtest1.swp
+under Xtest1.swp
+under under
+Xtest1.swp
+under Xtest1.swp
+Xtest3
+under Xtest3
+Xtest3.swp
+under Xtest3.swp
--- /dev/null
+++ b/testdir/test13.in
@@ -1,0 +1,58 @@
+Tests for autocommands on :close command
+
+Write three files and open them, each in a window.
+Then go to next window, with autocommand that deletes the previous one.
+Do this twice, writing the file.
+
+Also test deleting the buffer on a Unload event.  If this goes wrong there
+will be the ATTENTION prompt.
+
+Also test changing buffers in a BufDel autocommand.  If this goes wrong there
+are ml_line errors and/or a Crash.
+
+STARTTEST
+:so small.vim
+:/^start of testfile/,/^end of testfile/w! Xtestje1
+:/^start of testfile/,/^end of testfile/w! Xtestje2
+:/^start of testfile/,/^end of testfile/w! Xtestje3
+:e Xtestje1
+otestje1
+:w
+:sp Xtestje2
+otestje2
+:w
+:sp Xtestje3
+otestje3
+:w
+
+:au WinLeave Xtestje2 bwipe
+
+:w! test.out
+:au WinLeave Xtestje1 bwipe Xtestje3
+:close
+:w >>test.out
+:e Xtestje1
+:bwipe Xtestje2 Xtestje3 test.out
+:au!
+:au! BufUnload Xtestje1 bwipe
+:e Xtestje3
+:w >>test.out
+:e Xtestje2
+:sp Xtestje1
+:e
+:w >>test.out
+:au!
+:only
+:e Xtestje1
+:bwipe Xtestje2 Xtestje3 test.out test13.in
+:au BufWipeout Xtestje1 buf Xtestje1
+:bwipe
+:w >>test.out
+:qa!
+ENDTEST
+
+start of testfile
+	contents
+	contents
+	contents
+end of testfile
--- /dev/null
+++ b/testdir/test13.ok
@@ -1,0 +1,30 @@
+start of testfile
+testje1
+	contents
+	contents
+	contents
+end of testfile
+start of testfile
+testje1
+	contents
+	contents
+	contents
+end of testfile
+start of testfile
+testje3
+	contents
+	contents
+	contents
+end of testfile
+start of testfile
+testje2
+	contents
+	contents
+	contents
+end of testfile
+start of testfile
+testje1
+	contents
+	contents
+	contents
+end of testfile
--- /dev/null
+++ b/testdir/test14.in
@@ -1,0 +1,65 @@
+Tests for "vaBiB", end could be wrong.
+Also test ":s/pat/sub/" with different ~s in sub.
+Also test for ^Vxff and ^Vo123 in Insert mode.
+Also test "[m", "]m", "[M" and "]M"
+
+STARTTEST
+:so small.vim
+/Start cursor here
+vaBiBD:?Bug?,/Piece/-2w! test.out
+/^- Bug
+:s/u/~u~/
+:s/i/~u~/
+:s/o/~~~/
+:.w >>test.out
+:if has("ebcdic")
+: let tt = "o\<C-V>193\<C-V>xc2\<C-V>o303 \<C-V>90a\<C-V>xfg\<C-V>o578\<Esc>"
+:else
+: let tt = "o\<C-V>65\<C-V>x42\<C-V>o103 \<C-V>33a\<C-V>xfg\<C-V>o78\<Esc>"
+:endif
+:exe "normal " . tt
+:.w >>test.out
+:set vb
+/^Piece
+2]maA:.w >>test.out
+j]maB:.w >>test.out
+]maC:.w >>test.out
+[maD:.w >>test.out
+k2[maE:.w >>test.out
+3[maF:.w >>test.out
+]MaG:.w >>test.out
+j2]MaH:.w >>test.out
+]M]MaI:.w >>test.out
+2[MaJ:.w >>test.out
+k[MaK:.w >>test.out
+3[MaL:.w >>test.out
+:qa!
+ENDTEST
+
+- Bug in "vPPPP" on this text (Webb):
+	{
+		cmd;
+		{
+			cmd;	/* <-- Start cursor here */
+			{
+			}
+		}
+	}
+
+Piece of Java
+{
+	tt m1 {
+		t1;
+	} e1
+
+	tt m2 {
+		t2;
+	} e2
+
+	tt m3 {
+		if (x)
+		{
+			t3;
+		}
+	} e3
+}
--- /dev/null
+++ b/testdir/test14.ok
@@ -1,0 +1,17 @@
+- Bug in "vPPPP" on this text (Webb):
+	{
+	}
+- Bug uuun "vPPPP" uuuuuuuuun this text (Webb):
+ABC !ag8
+	tt m1 {A
+	tt m2 {B
+	tt m3 {C
+	tt m3 {DC
+	tt m1 {EA
+{F
+	}G e1
+	}H e3
+}I
+	}JH e3
+	}K e2
+{LF
--- /dev/null
+++ b/testdir/test15.in
@@ -1,0 +1,136 @@
+Tests for :right on text with embedded TAB.
+Also test formatting a paragraph.
+Also test undo after ":%s" and formatting.
+
+STARTTEST
+:so small.vim
+:set tw=65
+
+:/^\s*test for :left/,/^\s*test for :center/ left
+:/^\s*test for :center/,/^\s*test for :right/ center
+:/^\s*test for :right/,/^xxx/-1 right
+:set fo+=tcroql tw=72
+/xxxxxxxx$
+0gq6kk
+:set nocp viminfo+=nviminfo
+:" undo/redo here to make the next undo only work on the following changes
+u
+:map gg :.,.+2s/^/x/<CR>kk:set tw=3<CR>gqq
+/^aa
+ggu
+:?test for :left?,$w! test.out
+:qa!
+ENDTEST
+
+	test for :left
+	  a		a
+	    fa		a
+	  dfa		a
+	        sdfa		a
+	  asdfa		a
+	        xasdfa		a
+asxxdfa		a
+
+	test for :center
+	  a		a
+	    fa		afd asdf
+	  dfa		a
+	        sdfa		afd asdf
+	  asdfa		a
+	        xasdfa		asdfasdfasdfasdfasdf
+asxxdfa		a
+
+	test for :right
+	a		a
+	fa		a
+	dfa		a
+	sdfa		a
+	asdfa		a
+	xasdfa		a
+	asxxdfa		a
+	asxa;ofa		a
+	asdfaqwer		a
+	a		ax
+	fa		ax
+	dfa		ax
+	sdfa		ax
+	asdfa		ax
+	xasdfa		ax
+	asxxdfa		ax
+	asxa;ofa		ax
+	asdfaqwer		ax
+	a		axx
+	fa		axx
+	dfa		axx
+	sdfa		axx
+	asdfa		axx
+	xasdfa		axx
+	asxxdfa		axx
+	asxa;ofa		axx
+	asdfaqwer		axx
+	a		axxx
+	fa		axxx
+	dfa		axxx
+	sdfa		axxx
+	asdfa		axxx
+	xasdfa		axxx
+	asxxdfa		axxx
+	asxa;ofa		axxx
+	asdfaqwer		axxx
+	a		axxxo
+	fa		axxxo
+	dfa		axxxo
+	sdfa		axxxo
+	asdfa		axxxo
+	xasdfa		axxxo
+	asxxdfa		axxxo
+	asxa;ofa		axxxo
+	asdfaqwer		axxxo
+	a		axxxoi
+	fa		axxxoi
+	dfa		axxxoi
+	sdfa		axxxoi
+	asdfa		axxxoi
+	xasdfa		axxxoi
+	asxxdfa		axxxoi
+	asxa;ofa		axxxoi
+	asdfaqwer		axxxoi
+	a		axxxoik
+	fa		axxxoik
+	dfa		axxxoik
+	sdfa		axxxoik
+	asdfa		axxxoik
+	xasdfa		axxxoik
+	asxxdfa		axxxoik
+	asxa;ofa		axxxoik
+	asdfaqwer		axxxoik
+	a		axxxoike
+	fa		axxxoike
+	dfa		axxxoike
+	sdfa		axxxoike
+	asdfa		axxxoike
+	xasdfa		axxxoike
+	asxxdfa		axxxoike
+	asxa;ofa		axxxoike
+	asdfaqwer		axxxoike
+	a		axxxoikey
+	fa		axxxoikey
+	dfa		axxxoikey
+	sdfa		axxxoikey
+	asdfa		axxxoikey
+	xasdfa		axxxoikey
+	asxxdfa		axxxoikey
+	asxa;ofa		axxxoikey
+	asdfaqwer		axxxoikey
+
+xxxxx xx xxxxxx 
+xxxxxxx xxxxxxxxx xxx xxxx xxxxx xxxxx xxx xx
+xxxxxxxxxxxxxxxxxx xxxxx xxxx, xxxx xxxx xxxx xxxx xxx xx xx
+xx xxxxxxx. xxxx xxxx.
+
+> xx xx, xxxx xxxx xxx xxxx xxx xxxxx xxx xxx xxxxxxx xxx xxxxx
+> xxxxxx xxxxxxx: xxxx xxxxxxx, xx xxxxxx xxxx xxxxxxxxxx
+
+aa aa aa aa
+bb bb bb bb
+cc cc cc cc
--- /dev/null
+++ b/testdir/test15.ok
@@ -1,0 +1,111 @@
+test for :left
+a		a
+fa		a
+dfa		a
+sdfa		a
+asdfa		a
+xasdfa		a
+asxxdfa		a
+
+			test for :center
+			 a		a
+		      fa		afd asdf
+			 dfa		a
+		    sdfa		afd asdf
+			 asdfa		a
+	      xasdfa		asdfasdfasdfasdfasdf
+			asxxdfa		a
+
+						  test for :right
+						      a		a
+						     fa		a
+						    dfa		a
+						   sdfa		a
+						  asdfa		a
+						 xasdfa		a
+						asxxdfa		a
+					       asxa;ofa		a
+					      asdfaqwer		a
+					      a		ax
+					     fa		ax
+					    dfa		ax
+					   sdfa		ax
+					  asdfa		ax
+					 xasdfa		ax
+					asxxdfa		ax
+				       asxa;ofa		ax
+				      asdfaqwer		ax
+					      a		axx
+					     fa		axx
+					    dfa		axx
+					   sdfa		axx
+					  asdfa		axx
+					 xasdfa		axx
+					asxxdfa		axx
+				       asxa;ofa		axx
+				      asdfaqwer		axx
+					      a		axxx
+					     fa		axxx
+					    dfa		axxx
+					   sdfa		axxx
+					  asdfa		axxx
+					 xasdfa		axxx
+					asxxdfa		axxx
+				       asxa;ofa		axxx
+				      asdfaqwer		axxx
+					      a		axxxo
+					     fa		axxxo
+					    dfa		axxxo
+					   sdfa		axxxo
+					  asdfa		axxxo
+					 xasdfa		axxxo
+					asxxdfa		axxxo
+				       asxa;ofa		axxxo
+				      asdfaqwer		axxxo
+					      a		axxxoi
+					     fa		axxxoi
+					    dfa		axxxoi
+					   sdfa		axxxoi
+					  asdfa		axxxoi
+					 xasdfa		axxxoi
+					asxxdfa		axxxoi
+				       asxa;ofa		axxxoi
+				      asdfaqwer		axxxoi
+					      a		axxxoik
+					     fa		axxxoik
+					    dfa		axxxoik
+					   sdfa		axxxoik
+					  asdfa		axxxoik
+					 xasdfa		axxxoik
+					asxxdfa		axxxoik
+				       asxa;ofa		axxxoik
+				      asdfaqwer		axxxoik
+					      a		axxxoike
+					     fa		axxxoike
+					    dfa		axxxoike
+					   sdfa		axxxoike
+					  asdfa		axxxoike
+					 xasdfa		axxxoike
+					asxxdfa		axxxoike
+				       asxa;ofa		axxxoike
+				      asdfaqwer		axxxoike
+					      a		axxxoikey
+					     fa		axxxoikey
+					    dfa		axxxoikey
+					   sdfa		axxxoikey
+					  asdfa		axxxoikey
+					 xasdfa		axxxoikey
+					asxxdfa		axxxoikey
+				       asxa;ofa		axxxoikey
+				      asdfaqwer		axxxoikey
+
+xxxxx xx xxxxxx xxxxxxx xxxxxxxxx xxx xxxx xxxxx xxxxx xxx xx
+xxxxxxxxxxxxxxxxxx xxxxx xxxx, xxxx xxxx xxxx xxxx xxx xx xx xx xxxxxxx.
+xxxx xxxx.
+
+> xx xx, xxxx xxxx xxx xxxx xxx xxxxx xxx xxx xxxxxxx xxx xxxxx xxxxxx
+> xxxxxxx: xxxx xxxxxxx, xx xxxxxx xxxx xxxxxxxxxx
+
+aa aa aa aa
+bb bb bb bb
+cc cc cc cc
--- /dev/null
+++ b/testdir/test16.in
@@ -1,0 +1,14 @@
+Tests for resetting "secure" flag after GUI has started.
+For KDE set a font, empty 'guifont' may cause a hang.
+
+STARTTEST
+:set exrc secure
+:if has("gui_kde")
+:  set guifont=Courier\ 10\ Pitch/8/-1/5/50/0/0/0/0/0
+:endif
+:gui -f
+:.,$w! test.out
+:qa!
+ENDTEST
+
+	just some text
--- /dev/null
+++ b/testdir/test16.ok
@@ -1,0 +1,2 @@
+
+	just some text
--- /dev/null
+++ b/testdir/test17.in
@@ -1,0 +1,27 @@
+Tests for "gf" on ${VAR}
+
+STARTTEST
+:so small.vim
+:if has("ebcdic")
+: set isfname=@,240-249,/,.,-,_,+,,,$,:,~,{,}
+:else
+: set isfname=@,48-57,/,.,-,_,+,,,$,:,~,{,}
+:endif
+:if has("unix")
+:let $CDIR = "."
+/CDIR
+:else
+:if has("amiga")
+:let $TDIR = "/testdir"
+:else
+:let $TDIR = "."
+:endif
+/TDIR
+:endif
+gf
+:w! test.out
+:qa!
+ENDTEST
+
+	${CDIR}/test17a.in
+	$TDIR/test17a.in
--- /dev/null
+++ b/testdir/test17.ok
@@ -1,0 +1,3 @@
+This file is just to test "gf" in test 17.
+The contents is not importent.
+Just testing!
--- /dev/null
+++ b/testdir/test17a.in
@@ -1,0 +1,3 @@
+This file is just to test "gf" in test 17.
+The contents is not importent.
+Just testing!
--- /dev/null
+++ b/testdir/test18.in
@@ -1,0 +1,16 @@
+Tests for not doing smart indenting when it isn't set.
+
+STARTTEST
+:so small.vim
+:set nocin nosi ai
+/some
+2cc#test
+:?start?,$w! test.out
+:qa!
+ENDTEST
+
+start text
+		some test text
+		test text
+test text
+		test text
--- /dev/null
+++ b/testdir/test18.ok
@@ -1,0 +1,4 @@
+start text
+		#test
+test text
+		test text
--- /dev/null
+++ b/testdir/test19.in
@@ -1,0 +1,23 @@
+Tests for "r<Tab>" with 'smarttab' and 'expandtab' set/not set.
+
+STARTTEST
+:set smarttab expandtab ts=8 sw=4
+/some
+r	:set noexpandtab
+/other
+r	
+:" Test replacing with Tabs and then backspacing to undo it
+0wR			
+:" Test replacing with Tabs
+0wR			
+:?^start?,$w! test.out
+:qa!
+ENDTEST
+
+start text
+		some test text
+test text
+		other test text
+    a cde
+    f ghi
+test text
--- /dev/null
+++ b/testdir/test19.ok
@@ -1,0 +1,7 @@
+start text
+		    ome test text
+test text
+		    ther test text
+    a cde
+    		hi
+test text
--- /dev/null
+++ b/testdir/test2.in
@@ -1,0 +1,29 @@
+
+This is a test if a URL is recognized by "gf", with the cursor before and
+after the "://".  Also test ":\\".
+
+STARTTEST
+:so small.vim
+/^first
+/tmp
+:call append(0, expand("<cfile>"))
+/^second
+/URL
+:call append(1, expand("<cfile>"))
+:if has("ebcdic")
+: set isf=@,240-249,/,.,-,_,+,,,$,:,~,\
+:else
+: set isf=@,48-57,/,.,-,_,+,,,$,:,~,\
+:endif
+/^third
+/name
+:call append(2, expand("<cfile>"))
+/^fourth
+/URL
+:call append(3, expand("<cfile>"))
+5GdG:wq! test.out
+ENDTEST
+first test for URL://machine.name/tmp/vimtest2a and other text
+second test for URL://machine.name/tmp/vimtest2b. And other text
+third test for URL:\\machine.name\vimtest2c and other text
+fourth test for URL:\\machine.name\tmp\vimtest2d, and other text
--- /dev/null
+++ b/testdir/test2.ok
@@ -1,0 +1,4 @@
+URL://machine.name/tmp/vimtest2a
+URL://machine.name/tmp/vimtest2b
+URL:\\machine.name\vimtest2c
+URL:\\machine.name\tmp\vimtest2d
--- /dev/null
+++ b/testdir/test20.in
@@ -1,0 +1,22 @@
+Tests Blockwise Visual when there are TABs before the text.
+First test for undo working properly when executing commands from a register.
+Also test this in an empty buffer.
+
+STARTTEST
+:so tiny.vim
+G0"ay$k@au
+:new
+@auY:quit!
+GP
+/start here$
+jjlld
+:/here$/,$-1w! test.out
+:qa!
+ENDTEST
+
+test text test tex start here
+		some text
+		test text
+test text
+
+OxjAykdd
--- /dev/null
+++ b/testdir/test20.ok
@@ -1,0 +1,6 @@
+test text test tex rt here
+		somext
+		tesext
+test text
+
+
--- /dev/null
+++ b/testdir/test21.in
@@ -1,0 +1,19 @@
+Tests for [ CTRL-I with a count and CTRL-W CTRL-I with a count
+
+STARTTEST
+:so small.vim
+/start
+6[	:.w! test.out
+?start here
+6	:.w >>test.out
+:qa!
+ENDTEST
+
+#include test21.in
+
+/* test text test tex start here
+		some text
+		test text
+		start OK if found this line
+	start found wrong line
+test text
--- /dev/null
+++ b/testdir/test21.ok
@@ -1,0 +1,2 @@
+		start OK if found this line
+		start OK if found this line
--- /dev/null
+++ b/testdir/test22.in
@@ -1,0 +1,13 @@
+Tests for file with some lines ending in CTRL-M, some not
+
+STARTTEST
+:set ta tx
+:e!
+:$-3,$w! test.out
+:qa!
+ENDTEST
+
+this lines ends in a
+this one doesn't
+this one does
+and the last one doesn't
--- /dev/null
+++ b/testdir/test22.ok
@@ -1,0 +1,4 @@
+this lines ends in a
+this one doesn't
+this one does
+and the last one doesn't
--- /dev/null
+++ b/testdir/test23.in
@@ -1,0 +1,15 @@
+Tests for complicated + argument to :edit command
+
+STARTTEST
+:$-1w! Xfile1
+:$w! Xfile2
+:edit +1|s/|/PIPE/|w Xfile1| e Xfile2|1 | s/\//SLASH/|w
+:w! test.out
+:e Xfile1
+:w >> test.out
+:qa!
+ENDTEST
+
+The result should be in Xfile1: "fooPIPEbar", in Xfile2: "fooSLASHbar"
+foo|bar
+foo/bar
--- /dev/null
+++ b/testdir/test23.ok
@@ -1,0 +1,2 @@
+fooSLASHbar
+fooPIPEbar
binary files /dev/null b/testdir/test24.in differ
--- /dev/null
+++ b/testdir/test24.ok
@@ -1,0 +1,29 @@
+start
+test text test text
+test text test text
+test text test text
+test text test text
+test text test text
+test text test text
+test text test text  x61
+test text test text  x60-x64
+test text test text  x78 5
+test text test text  o143
+test text test text  o140-o144
+test text test text  o41 7
+test text test text  \%x42
+test text test text  \%o103
+test text test text  [\x00]
+test text test text  [\x00-\x10]
+test text test text  [\x-z]
+test text test text  [\u-z]
+xx  xx a
+xx aaaaa xx a
+xx aaaaa xx a
+xx Aaa xx
+xx Aaaa xx
+xx Aaa xx
+xx foobar xA xx
+xx an A xx
+XX 9;
+YY 77;
--- /dev/null
+++ b/testdir/test25.in
@@ -1,0 +1,31 @@
+Test for jumping to a tag with 'hidden' set, with symbolic link in path of tag.
+This only works for Unix, because of the symbolic link.
+
+STARTTEST
+:so small.vim
+:set hidden
+:" Create a link from test25.dir to the current directory.
+:!rm -f test25.dir
+:!ln -s . test25.dir
+:" Create tags.text, with the current directory name inserted.
+/tags line
+:r !pwd
+d$/test
+hP:.w! tags.test
+:" Try jumping to a tag in the current file, but with a path that contains a
+:" symbolic link.  When wrong, this will give the ATTENTION message.  The next
+:" space will then be eaten by hit-return, instead of moving the cursor to 'd'.
+:set tags=tags.test
+G x:.w! test.out
+:!rm -f test25.dir tags.test
+:qa!
+ENDTEST
+
+tags line:
+SECTION_OFF	/test25.dir/test25.in	/^#define  SECTION_OFF  3$/
+
+/*tx.c*/
+#define  SECTION_OFF  3
+#define  NUM_SECTIONS 3
+
+SECTION_OFF
--- /dev/null
+++ b/testdir/test25.ok
@@ -1,0 +1,1 @@
+#efine  SECTION_OFF  3
--- /dev/null
+++ b/testdir/test26.in
@@ -1,0 +1,43 @@
+Test for :execute, :while and :if
+
+STARTTEST
+:so small.vim
+mt:let i = 0
+:while i < 12
+:  let i = i + 1
+:  if has("ebcdic")
+:    execute "normal o" . i . "\047"
+:  else
+:    execute "normal o" . i . "\033"
+:  endif
+:  if i % 2
+:    normal Ax
+:    if i == 9
+:      break
+:    endif
+:    if i == 5
+:      continue
+:    else
+:      let j = 9
+:      while j > 0
+:        if has("ebcdic")
+:          execute "normal" j . "a" . j . "\x27"
+:        else
+:          execute "normal" j . "a" . j . "\x1b"
+:        endif
+:        let j = j - 1
+:      endwhile
+:    endif
+:  endif
+:  if i == 9
+:    if has("ebcdic")
+:      execute "normal Az\047"
+:    else
+:      execute "normal Az\033"
+:    endif
+:  endif
+:endwhile
+:'t,$w! test.out
+:qa!
+ENDTEST
+
--- /dev/null
+++ b/testdir/test26.ok
@@ -1,0 +1,10 @@
+
+1x999999999888888887777777666666555554444333221
+2
+3x999999999888888887777777666666555554444333221
+4
+5x
+6
+7x999999999888888887777777666666555554444333221
+8
+9x
--- /dev/null
+++ b/testdir/test27.in
@@ -1,0 +1,20 @@
+Test for expanding file names
+
+STARTTEST
+:!mkdir Xdir1
+:!mkdir Xdir2
+:!mkdir Xdir3
+:cd Xdir3
+:!mkdir Xdir4
+:cd ..
+:w Xdir1/file
+:w Xdir3/Xdir4/file
+:n Xdir?/*/file
+Go%:.w! test.out
+:n! Xdir?/*/nofile
+Go%:.w >>test.out
+:e! xx
+:!rm -rf Xdir1 Xdir2 Xdir3
+:qa!
+ENDTEST
+
--- /dev/null
+++ b/testdir/test27.ok
@@ -1,0 +1,2 @@
+Xdir3/Xdir4/file
+Xdir?/*/nofile
binary files /dev/null b/testdir/test28.in differ
--- /dev/null
+++ b/testdir/test28.ok
@@ -1,0 +1,2 @@
+sd
+map __2 asdsecondsdsd0map __5 asd0fifth
--- /dev/null
+++ b/testdir/test29.in
@@ -1,0 +1,67 @@
+Test for joining lines with 'joinspaces' set or not
+
+STARTTEST
+:set nojoinspaces
+/firstline/
+jJjJjJjJjJjJjJjJjJjJjJjJjJjJ:set joinspaces
+jJjJjJjJjJjJjJjJjJjJjJjJjJjJ:?firstline?+1,$w! test.out
+:qa!
+ENDTEST
+
+firstline
+asdfasdf.
+asdf
+asdfasdf. 
+asdf
+asdfasdf.  
+asdf
+asdfasdf.	
+asdf
+asdfasdf. 	
+asdf
+asdfasdf.	 
+asdf
+asdfasdf.		
+asdf
+asdfasdf
+asdf
+asdfasdf 
+asdf
+asdfasdf  
+asdf
+asdfasdf	
+asdf
+asdfasdf	 
+asdf
+asdfasdf 	
+asdf
+asdfasdf		
+asdf
+asdfasdf.
+asdf
+asdfasdf. 
+asdf
+asdfasdf.  
+asdf
+asdfasdf.	
+asdf
+asdfasdf. 	
+asdf
+asdfasdf.	 
+asdf
+asdfasdf.		
+asdf
+asdfasdf
+asdf
+asdfasdf 
+asdf
+asdfasdf  
+asdf
+asdfasdf	
+asdf
+asdfasdf	 
+asdf
+asdfasdf 	
+asdf
+asdfasdf		
+asdf
--- /dev/null
+++ b/testdir/test29.ok
@@ -1,0 +1,28 @@
+asdfasdf. asdf
+asdfasdf. asdf
+asdfasdf.  asdf
+asdfasdf.	asdf
+asdfasdf. 	asdf
+asdfasdf.	 asdf
+asdfasdf.		asdf
+asdfasdf asdf
+asdfasdf asdf
+asdfasdf  asdf
+asdfasdf	asdf
+asdfasdf	 asdf
+asdfasdf 	asdf
+asdfasdf		asdf
+asdfasdf.  asdf
+asdfasdf.  asdf
+asdfasdf.  asdf
+asdfasdf.	asdf
+asdfasdf. 	asdf
+asdfasdf.	 asdf
+asdfasdf.		asdf
+asdfasdf asdf
+asdfasdf asdf
+asdfasdf  asdf
+asdfasdf	asdf
+asdfasdf	 asdf
+asdfasdf 	asdf
+asdfasdf		asdf
--- /dev/null
+++ b/testdir/test3.in
@@ -1,0 +1,1320 @@
+/* vim: set cin ts=4 sw=4 : */
+
+Test for 'cindent'
+
+STARTTEST
+:so small.vim
+:set nocompatible viminfo+=nviminfo
+:edit                " read modeline
+/start of AUTO
+=/end of AUTO
+ENDTEST
+
+/* start of AUTO matically checked vim: set ts=4 : */
+{
+	if (test)
+		cmd1;
+	cmd2;
+}
+
+{
+	if (test)
+		cmd1;
+	else
+		cmd2;
+}
+
+{
+	if (test)
+	{
+		cmd1;
+		cmd2;
+	}
+}
+
+{
+	if (test)
+	{
+		cmd1;
+		else
+	}
+}
+
+{
+	while (this)
+		if (test)
+			cmd1;
+	cmd2;
+}
+
+{
+	while (this)
+		if (test)
+			cmd1;
+		else
+			cmd2;
+}
+
+{
+	if (test)
+	{
+		cmd;
+	}
+
+	if (test)
+		cmd;
+}
+
+{
+	if (test) {
+		cmd;
+	}
+
+	if (test) cmd;
+}
+
+{
+	cmd1;
+	for (blah)
+		while (this)
+			if (test)
+				cmd2;
+	cmd3;
+}
+
+{
+	cmd1;
+	for (blah)
+		while (this)
+			if (test)
+				cmd2;
+	cmd3;
+
+	if (test)
+	{
+		cmd1;
+		cmd2;
+		cmd3;
+	}
+}
+
+
+/* Test for 'cindent' do/while mixed with if/else: */
+
+{
+	do
+		if (asdf)
+			asdfasd;
+	while (cond);
+
+	do
+		if (asdf)
+			while (asdf)
+				asdf;
+	while (asdf);
+}
+
+/* Test for 'cindent' with two ) on a continuation line */
+{
+	if (asdfasdf;asldkfj asdlkfj as;ldkfj sal;d
+			aal;sdkjf  ( ;asldfkja;sldfk
+					al;sdjfka ;slkdf ) sa;ldkjfsa dlk;)
+		line up here;
+}
+
+
+/* C++ tests: */
+
+// foo()		these three lines should remain in column 0
+// {
+// }
+
+/* Test for continuation and unterminated lines: */
+{
+	i = 99 + 14325 +
+		21345 +
+		21345 +
+		21345 + ( 21345 +
+				21345) +
+		2345 +
+		1234;
+	c = 1;
+}
+
+/*
+   testje for indent with empty line
+
+   here */
+
+{
+	if (testing &&
+			not a joke ||
+			line up here)
+		hay;
+	if (testing &&
+			(not a joke || testing
+			)line up here)
+		hay;
+	if (testing &&
+			(not a joke || testing
+			 line up here))
+		hay;
+}
+
+
+{
+	switch (c)
+	{
+		case xx:
+			do
+				if (asdf)
+					do
+						asdfasdf;
+					while (asdf);
+				else
+					asdfasdf;
+			while (cond);
+		case yy:
+		case xx:
+		case zz:
+			testing;
+	}
+}
+
+{
+	if (cond) {
+		foo;
+	}
+	else
+	{
+		bar;
+	}
+}
+
+{
+	if (alskdfj ;alsdkfjal;skdjf (;sadlkfsa ;dlkf j;alksdfj ;alskdjf
+			alsdkfj (asldk;fj
+					awith cino=(0 ;lf this one goes to below the paren with ==
+							;laksjfd ;lsakdjf ;alskdf asd)
+					asdfasdf;)))
+		asdfasdf;
+}
+
+	int
+func(a, b)
+	int a;
+	int c;
+{
+	if (c1 && (c2 ||
+			c3))
+		foo;
+	if (c1 &&
+			(c2 || c3)
+	   )
+}
+
+{
+	while (asd)
+	{
+		if (asdf)
+			if (test)
+				if (that)
+				{
+					if (asdf)
+						do
+							cdasd;
+						while (as
+								df);
+				}
+				else
+					if (asdf)
+						asdf;
+					else
+						asdf;
+		asdf;
+	}
+}
+
+{
+	s = "/*"; b = ';'
+		s = "/*"; b = ';';
+	a = b;
+}
+
+{
+	switch (a)
+	{
+		case a:
+			switch (t)
+			{
+				case 1:
+					cmd;
+					break;
+				case 2:
+					cmd;
+					break;
+			}
+			cmd;
+			break;
+		case b:
+			{
+				int i;
+				cmd;
+			}
+			break;
+		case c: {
+					int i;
+					cmd;
+				}
+		case d: if (cond &&
+						test) {		/* this line doesn't work right */
+					int i;
+					cmd;
+				}
+				break;
+	}
+}
+
+{
+	if (!(vim_strchr(p_cpo, CPO_BUFOPTGLOB) != NULL && entering) &&
+			(bp_to->b_p_initialized ||
+			 (!entering && vim_strchr(p_cpo, CPO_BUFOPT) != NULL)))
+		return;
+label :
+	asdf = asdf ?
+		asdf : asdf;
+	asdf = asdf ?
+		asdf: asdf;
+}
+
+/* Special Comments	: This function has the added complexity (compared  */
+/*					: to addtolist) of having to check for a detail     */
+/*					: texture and add that to the list first.	 	    */
+
+char *(array[100]) = {
+	"testje",
+	"foo",
+	"bar",
+}
+
+enum soppie
+{
+	yes = 0,
+	no,
+	maybe
+};
+
+typedef enum soppie
+{
+	yes = 0,
+	no,
+	maybe
+};
+
+{
+	int a,
+		b;
+}
+
+{
+	struct Type
+	{
+		int i;
+		char *str;
+	} var[] =
+	{
+		0, "zero",
+		1, "one",
+		2, "two",
+		3, "three"
+	};
+
+	float matrix[3][3] =
+	{
+		{
+			0,
+			1,
+			2
+		},
+		{
+			3,
+			4,
+			5
+		},
+		{
+			6,
+			7,
+			8
+		}
+	};
+}
+
+{
+	/* blah ( blah */
+	/* where does this go? */
+
+	/* blah ( blah */
+	cmd;
+
+	func(arg1,
+			/* comment */
+			arg2);
+	a;
+	{
+		b;
+		{
+			c; /* Hey, NOW it indents?! */
+		}
+	}
+
+	{
+		func(arg1,
+				arg2,
+				arg3);
+		/* Hey, what am I doing here?  Is this coz of the ","? */
+	}
+}
+
+main ()
+{
+	if (cond)
+	{
+		a = b;
+	}
+	if (cond) {
+		a = c;
+	}
+	if (cond)
+		a = d;
+	return;
+}
+
+{
+	case 2: if (asdf &&
+					asdfasdf)
+				aasdf;
+			a = 9;
+	case 3: if (asdf)
+				aasdf;
+			a = 9;
+	case 4:    x = 1;
+			   y = 2;
+
+label:	if (asdf)
+			here;
+
+label:  if (asdf &&
+				asdfasdf)
+		{
+		}
+
+label:  if (asdf &&
+				asdfasdf) {
+			there;
+		}
+
+label:  if (asdf &&
+				asdfasdf)
+			there;
+}
+
+{
+	/*
+	   hello with ":set comments= cino=c5"
+	 */
+
+	/*
+	   hello with ":set comments= cino="
+	 */
+}
+
+
+{
+	if (a < b) {
+		a = a + 1;
+	} else
+		a = a + 2;
+
+	if (a)
+		do {
+			testing;
+		} while (asdfasdf);
+	a = b + 1;
+	asdfasdf
+}
+
+class bob
+{
+	int foo() {return 1;}
+		int bar;
+}
+
+main()
+{
+while(1)
+if (foo)
+{
+bar;
+}
+else {
+asdf;
+}
+misplacedline;
+}
+
+{
+	if (clipboard.state == SELECT_DONE
+	&& ((row == clipboard.start.lnum
+	&& col >= clipboard.start.col)
+	|| row > clipboard.start.lnum))
+}
+
+{
+if (1) {i += 4;}
+where_am_i;
+return 0;
+}
+
+{
+{
+} // sdf(asdf
+if (asdf)
+asd;
+}
+
+{
+label1:
+label2:
+}
+
+{
+int fooRet = foo(pBar1, false /*fKB*/,
+	true /*fPTB*/, 3 /*nT*/, false /*fDF*/);
+f() {
+for ( i = 0;
+	i < m;
+	/* c */ i++ ) {
+a = b;
+}
+}
+}
+
+{
+	f1(/*comment*/);
+	f2();
+}
+
+{
+do {
+if (foo) {
+} else
+;
+} while (foo);
+foo();	// was wrong
+}
+
+int x;	    // no extra indent because of the ;
+void func()
+{
+}
+
+char *tab[] = {"aaa",
+	"};", /* }; */ NULL}
+	int indented;
+{}
+
+char *a[] = {"aaa", "bbb",
+	"ccc", NULL};
+// here
+
+char *tab[] = {"aaa",
+	"xx", /* xx */};    /* asdf */
+int not_indented;
+
+{
+	do {
+		switch (bla)
+		{
+			case 1: if (foo)
+						bar;
+		}
+	} while (boo);
+					wrong;
+}
+
+int	foo,
+	bar;
+int foo;
+
+#if defined(foo) \
+	&& defined(bar)
+char * xx = "asdf\
+	foo\
+	bor";
+int x;
+
+char    *foo = "asdf\
+	asdf\
+	asdf",
+	*bar;
+
+void f()
+{
+#if defined(foo) \
+	&& defined(bar)
+char    *foo = "asdf\
+	asdf\
+	asdf",
+	*bar;
+	{
+	int i;
+char    *foo = "asdf\
+	asdf\
+	asdf",
+	*bar;
+	}
+#endif
+}
+#endif
+
+int y;		// comment
+		// comment
+
+	// comment
+
+{
+	Constructor(int a,
+			int b )  : BaseClass(a)
+	{
+	}
+}
+
+void foo()
+{
+	char one,
+	two;
+	struct bla piet,
+	jan;
+	enum foo kees,
+	jannie;
+	static unsigned sdf,
+	krap;
+	unsigned int piet,
+	jan;
+	int
+	kees,
+	jan;
+}
+
+{
+	t(int f,
+			int d);		// )
+	d();
+}
+
+Constructor::Constructor(int a,
+                         int b 
+                        )  : 
+   BaseClass(a,
+             b,
+             c),
+   mMember(b),
+{
+}
+
+Constructor::Constructor(int a,
+                         int b )  : 
+   BaseClass(a)
+{
+}
+
+Constructor::Constructor(int a,
+                         int b ) /*x*/ : /*x*/ BaseClass(a),
+                                               member(b)
+{
+}
+
+class CAbc :
+   public BaseClass1,
+   protected BaseClass2
+{
+   int Test() { return FALSE; }
+   int Test1() { return TRUE; }
+
+   CAbc(int a, int b )  : 
+      BaseClass(a)
+   { 
+      switch(xxx)
+      {
+         case abc:
+            asdf();
+            break;
+
+         case 999:
+            baer();
+            break;
+      }
+   }
+
+public: // <-- this was incoreectly indented before!!
+   void testfall();
+protected:
+   void testfall();
+};
+
+class CAbc : public BaseClass1,
+             protected BaseClass2
+{
+};
+
+static struct
+{
+    int a;
+    int b;
+} variable[COUNT] =
+{
+    {
+        123,
+        456
+    },
+	{
+        123,
+        456
+    }
+};
+
+static struct
+{
+    int a;
+    int b;
+} variable[COUNT] =
+{
+    { 123, 456 },
+	{ 123, 456 }
+};
+
+void asdf()		/* ind_maxparen may cause trouble here */
+{
+	if ((0
+				&& 1
+				&& 1
+				&& 1
+				&& 1
+				&& 1
+				&& 1
+				&& 1
+				&& 1
+				&& 1
+				&& 1
+				&& 1
+				&& 1
+				&& 1
+				&& 1
+				&& 1
+				&& 1
+				&& 1
+				&& 1
+				&& 1
+				&& 1
+				&& 1
+				&& 1
+				&& 1
+				&& 1
+				&& 1)) break;
+}
+
+foo()
+{
+	a = cond ? foo() : asdf
+					   + asdf;
+
+	a = cond ?
+		foo() : asdf
+				+ asdf;
+}
+
+int  main(void)
+{
+	if (a)
+		if (b)
+			2;
+		else 3;
+	next_line_of_code();
+}
+
+barry()
+{
+	Foo::Foo (int one,
+			int two)
+		: something(4)
+	{}
+}
+
+barry()
+{
+	Foo::Foo (int one, int two)
+		: something(4)
+	{}
+}
+
+Constructor::Constructor(int a,
+		int b 
+		)  : 
+	BaseClass(a,
+			b,
+			c),
+	mMember(b)
+{
+}
+       int main ()
+       {
+	 if (lala)
+	   do
+	     ++(*lolo);
+	   while (lili
+		  && lele);
+	   lulu;
+       }
+
+int main ()
+{
+switch (c)
+{
+case 'c': if (cond)
+{
+}
+}
+}
+
+main()
+{
+	(void) MyFancyFuasdfadsfnction(
+			argument);
+}
+
+main()
+{
+	char	foo[] = "/*";
+	/* as
+	df */
+		hello
+}
+/* end of AUTO */
+
+STARTTEST
+:set tw=0 wm=60 columns=80 noai fo=croq
+/serious/e
+a about life, the universe, and the rest
+ENDTEST
+
+{
+
+/* this is
+ * a real serious important big
+ * comment
+ */
+	/* insert " about life, the universe, and the rest" after "serious" */
+}
+
+STARTTEST
+:set nocin
+/comments
+joabout life/happens
+jothere/below
+oline/this
+Ohello
+ENDTEST
+
+{
+	/*
+	 * Testing for comments, without 'cin' set
+	 */
+
+/*
+* what happens here?
+*/
+
+	/*
+	   the end of the comment, try inserting a line below */
+
+		/* how about
+		                this one */
+}
+
+STARTTEST
+:set cin
+/vec2
+==
+ENDTEST
+
+{
+    var = this + that + vec[0] * vec[0]
+				      + vec[1] * vec[1]
+					  + vec2[2] * vec[2];
+}
+
+STARTTEST
+:set cin
+:set cino=}4
+/testing1
+k2==/testing2
+k2==
+ENDTEST
+
+{
+		asdf asdflkajds f;
+	if (tes & ting) {
+		asdf asdf asdf ;
+		asdfa sdf asdf;
+		}
+	testing1;
+	if (tes & ting)
+	{
+		asdf asdf asdf ;
+		asdfa sdf asdf;
+		}
+	testing2;
+}
+
+STARTTEST
+:set cin
+:set cino=(0,)20
+/main
+=][
+ENDTEST
+
+main ( int first_par, /*
+                       * Comment for
+                       * first par
+                       */
+          int second_par /*
+                       * Comment for
+                       * second par
+                       */
+     )
+{
+	func( first_par, /*
+                      * Comment for
+                      * first par
+                      */
+    second_par /*
+                      * Comment for
+                      * second par
+                      */
+        );
+
+}
+
+STARTTEST
+:set cin
+:set cino=
+]]=][
+ENDTEST
+
+{
+	do
+	{
+		if ()
+		{
+			if ()
+				asdf;
+			else
+				asdf;
+		}
+	} while ();
+			cmd;		/* this should go under the } */
+}
+
+STARTTEST
+]]=][
+ENDTEST
+
+void f()
+{
+    if ( k() ) {
+        l();
+
+    } else { /* Start (two words) end */
+        m();
+    }
+
+    n();
+}
+
+STARTTEST
+:set cino={s,e-s
+]]=][
+ENDTEST
+
+void f()
+{
+    if ( k() )
+	{
+        l();
+    } else { /* Start (two words) end */
+        m();
+    }
+		n();	/* should be under the if () */
+}
+
+STARTTEST
+:set cino={s,fs
+]]=/ foo
+ENDTEST
+
+void bar(void)
+{
+	static array[2][2] =
+	{
+		{ 1, 2 },
+		{ 3, 4 },
+	}
+
+	while (a)
+	{
+		foo(&a);
+	}
+
+	{
+		int a;
+		{
+			a = a + 1;
+		}
+	}
+	b = a;
+	}
+
+void func(void)
+	{
+	a = 1;
+	{
+		b = 2;
+	}
+	c = 3;
+	d = 4;
+	}
+/* foo */
+
+STARTTEST
+:set cino=
+/while
+ohere
+ENDTEST
+
+a()
+{
+  do {
+    a = a +
+      a;
+  } while ( a );		/* add text under this line */
+    if ( a )
+      a;
+}
+
+STARTTEST
+:set cino= com=
+/comment
+olabel2: b();
label3 /* post */:
/* pre */ label4:
f(/*com*/);
if (/*com*/)
cmd();
+ENDTEST
+
+a()
+{
+label1:
+            /* hmm */
+            // comment
+}
+
+STARTTEST
+:set comments& comments^=s:/*,m:**,ex:*/
+/simple
+=5j
+ENDTEST
+
+/*
+  * A simple comment
+   */
+
+/*
+  ** A different comment
+   */
+
+STARTTEST
+:set cino=c0
+:set comments& comments-=s1:/* comments^=s0:/*
+2kdd]]=][
+ENDTEST
+
+void f()
+{
+
+	/*********
+  A comment.
+*********/
+}
+
+STARTTEST
+:set cino=c0,C1
+:set comments& comments-=s1:/* comments^=s0:/*
+2kdd]]=][
+ENDTEST
+
+void f()
+{
+
+	/*********
+  A comment.
+*********/
+}
+
+STARTTEST
+:set cino=
+]]=][
+ENDTEST
+
+void f()
+{
+	c = c1 &&
+	(
+	c2 ||
+	c3
+	) && c4;
+}
+
+STARTTEST
+:set cino=(s
+2kdd]]=][
+ENDTEST
+
+void f()
+{
+	c = c1 &&
+	(
+	c2 ||
+	c3
+	) && c4;
+}
+
+STARTTEST
+:set cino=(s,U1  
+2kdd]]=][
+ENDTEST
+
+void f()
+{
+	c = c1 &&
+	(
+	c2 ||
+	c3
+	) && c4;
+}
+
+STARTTEST
+:set cino=(0
+2kdd]]=][
+ENDTEST
+
+void f()
+{
+	if (   c1
+	&& (   c2
+	|| c3))
+	foo;
+}
+
+STARTTEST
+:set cino=(0,w1  
+2kdd]]=][
+ENDTEST
+
+void f()
+{
+	if (   c1
+	&& (   c2
+	|| c3))
+	foo;
+}
+
+STARTTEST
+:set cino=(s
+2kdd]]=][
+ENDTEST
+
+void f()
+{
+	c = c1 && (
+	c2 ||
+	c3
+	) && c4;
+	if (
+	c1 && c2
+	)
+	foo;
+}
+
+STARTTEST
+:set cino=(s,m1  
+2kdd]]=][
+ENDTEST
+
+void f()
+{
+	c = c1 && (
+	c2 ||
+	c3
+	) && c4;
+	if (
+	c1 && c2
+	)
+	foo;
+}
+
+STARTTEST
+:set cino=b1
+2kdd]]=][
+ENDTEST
+
+void f()
+{
+	switch (x)
+	{
+		case 1:
+			a = b;
+			break;
+		default:
+			a = 0;
+			break;
+	}
+}
+
+STARTTEST
+:set cino=(0,W5
+2kdd]]=][
+ENDTEST
+
+void f()
+{
+	invokeme(
+	argu,
+	ment);
+	invokeme(
+	argu,
+	ment
+	);
+	invokeme(argu,
+	ment
+	);
+}
+
+STARTTEST
+:set cino=/6
+2kdd]]=][
+ENDTEST
+
+void f()
+{
+	statement;
+		// comment 1
+	// comment 2
+}
+
+STARTTEST
+:set cino=
+2kdd]]/comment 1/+1
+==
+ENDTEST
+
+void f()
+{
+	statement;
+	   // comment 1
+	// comment 2
+}
+
+STARTTEST
+:set cino=g0
+2kdd]]=][
+ENDTEST
+
+class CAbc
+{
+   int Test() { return FALSE; }
+
+public: // comment
+   void testfall();
+protected:
+   void testfall();
+};
+
+STARTTEST
+:set cino=+20
+2kdd]]=][
+ENDTEST
+
+	void
+foo()
+{
+	if (a)
+	{
+	} else
+		asdf;
+}
+
+STARTTEST
+:set cino=(0,W2s
+2kdd]]=][
+ENDTEST
+
+{
+   averylongfunctionnamelongfunctionnameaverylongfunctionname()->asd(
+         asdasdf,
+         func(asdf,
+              asdfadsf),
+         asdfasdf
+         );
+
+   /* those are ugly, but consequent */
+
+   func()->asd(asdasdf,
+               averylongfunctionname(
+                     abc,
+                     dec)->averylongfunctionname(
+                           asdfadsf,
+                           asdfasdf,
+                           asdfasdf,
+                           ),
+               func(asdfadf,
+                    asdfasdf
+                   ),
+               asdasdf
+              );
+
+   averylongfunctionnameaverylongfunctionnameavery()->asd(fasdf(
+               abc,
+               dec)->asdfasdfasdf(
+                     asdfadsf,
+                     asdfasdf,
+                     asdfasdf,
+                     ),
+         func(asdfadf,
+              asdfasdf),
+         asdasdf
+         );
+}
+
+STARTTEST
+:set cino=M1
+2kdd]]=][
+ENDTEST
+
+int main ()
+{
+	if (cond1 &&
+			cond2
+			)
+		foo;
+}
+
+STARTTEST
+:g/^STARTTEST/.,/^ENDTEST/d
+:1;/start of AUTO/,$wq! test.out
+ENDTEST
--- /dev/null
+++ b/testdir/test3.ok
@@ -1,0 +1,1185 @@
+/* start of AUTO matically checked vim: set ts=4 : */
+{
+	if (test)
+		cmd1;
+	cmd2;
+}
+
+{
+	if (test)
+		cmd1;
+	else
+		cmd2;
+}
+
+{
+	if (test)
+	{
+		cmd1;
+		cmd2;
+	}
+}
+
+{
+	if (test)
+	{
+		cmd1;
+		else
+	}
+}
+
+{
+	while (this)
+		if (test)
+			cmd1;
+	cmd2;
+}
+
+{
+	while (this)
+		if (test)
+			cmd1;
+		else
+			cmd2;
+}
+
+{
+	if (test)
+	{
+		cmd;
+	}
+
+	if (test)
+		cmd;
+}
+
+{
+	if (test) {
+		cmd;
+	}
+
+	if (test) cmd;
+}
+
+{
+	cmd1;
+	for (blah)
+		while (this)
+			if (test)
+				cmd2;
+	cmd3;
+}
+
+{
+	cmd1;
+	for (blah)
+		while (this)
+			if (test)
+				cmd2;
+	cmd3;
+
+	if (test)
+	{
+		cmd1;
+		cmd2;
+		cmd3;
+	}
+}
+
+
+/* Test for 'cindent' do/while mixed with if/else: */
+
+{
+	do
+		if (asdf)
+			asdfasd;
+	while (cond);
+
+	do
+		if (asdf)
+			while (asdf)
+				asdf;
+	while (asdf);
+}
+
+/* Test for 'cindent' with two ) on a continuation line */
+{
+	if (asdfasdf;asldkfj asdlkfj as;ldkfj sal;d
+			aal;sdkjf  ( ;asldfkja;sldfk
+				al;sdjfka ;slkdf ) sa;ldkjfsa dlk;)
+		line up here;
+}
+
+
+/* C++ tests: */
+
+// foo()		these three lines should remain in column 0
+// {
+// }
+
+/* Test for continuation and unterminated lines: */
+{
+	i = 99 + 14325 +
+		21345 +
+		21345 +
+		21345 + ( 21345 +
+				21345) +
+		2345 +
+		1234;
+	c = 1;
+}
+
+/*
+   testje for indent with empty line
+
+   here */
+
+{
+	if (testing &&
+			not a joke ||
+			line up here)
+		hay;
+	if (testing &&
+			(not a joke || testing
+			)line up here)
+		hay;
+	if (testing &&
+			(not a joke || testing
+			 line up here))
+		hay;
+}
+
+
+{
+	switch (c)
+	{
+		case xx:
+			do
+				if (asdf)
+					do
+						asdfasdf;
+					while (asdf);
+				else
+					asdfasdf;
+			while (cond);
+		case yy:
+		case xx:
+		case zz:
+			testing;
+	}
+}
+
+{
+	if (cond) {
+		foo;
+	}
+	else
+	{
+		bar;
+	}
+}
+
+{
+	if (alskdfj ;alsdkfjal;skdjf (;sadlkfsa ;dlkf j;alksdfj ;alskdjf
+				alsdkfj (asldk;fj
+					awith cino=(0 ;lf this one goes to below the paren with ==
+						;laksjfd ;lsakdjf ;alskdf asd)
+					asdfasdf;)))
+		asdfasdf;
+}
+
+	int
+func(a, b)
+	int a;
+	int c;
+{
+	if (c1 && (c2 ||
+				c3))
+		foo;
+	if (c1 &&
+			(c2 || c3)
+	   )
+}
+
+{
+	while (asd)
+	{
+		if (asdf)
+			if (test)
+				if (that)
+				{
+					if (asdf)
+						do
+							cdasd;
+						while (as
+								df);
+				}
+				else
+					if (asdf)
+						asdf;
+					else
+						asdf;
+		asdf;
+	}
+}
+
+{
+	s = "/*"; b = ';'
+		s = "/*"; b = ';';
+	a = b;
+}
+
+{
+	switch (a)
+	{
+		case a:
+			switch (t)
+			{
+				case 1:
+					cmd;
+					break;
+				case 2:
+					cmd;
+					break;
+			}
+			cmd;
+			break;
+		case b:
+			{
+				int i;
+				cmd;
+			}
+			break;
+		case c: {
+					int i;
+					cmd;
+				}
+		case d: if (cond &&
+						test) {		/* this line doesn't work right */
+					int i;
+					cmd;
+				}
+				break;
+	}
+}
+
+{
+	if (!(vim_strchr(p_cpo, CPO_BUFOPTGLOB) != NULL && entering) &&
+			(bp_to->b_p_initialized ||
+			 (!entering && vim_strchr(p_cpo, CPO_BUFOPT) != NULL)))
+		return;
+label :
+	asdf = asdf ?
+		asdf : asdf;
+	asdf = asdf ?
+		asdf: asdf;
+}
+
+/* Special Comments	: This function has the added complexity (compared  */
+/*					: to addtolist) of having to check for a detail     */
+/*					: texture and add that to the list first.	 	    */
+
+char *(array[100]) = {
+	"testje",
+	"foo",
+	"bar",
+}
+
+enum soppie
+{
+	yes = 0,
+	no,
+	maybe
+};
+
+typedef enum soppie
+{
+	yes = 0,
+	no,
+	maybe
+};
+
+{
+	int a,
+		b;
+}
+
+{
+	struct Type
+	{
+		int i;
+		char *str;
+	} var[] =
+	{
+		0, "zero",
+		1, "one",
+		2, "two",
+		3, "three"
+	};
+
+	float matrix[3][3] =
+	{
+		{
+			0,
+			1,
+			2
+		},
+		{
+			3,
+			4,
+			5
+		},
+		{
+			6,
+			7,
+			8
+		}
+	};
+}
+
+{
+	/* blah ( blah */
+	/* where does this go? */
+
+	/* blah ( blah */
+	cmd;
+
+	func(arg1,
+			/* comment */
+			arg2);
+	a;
+	{
+		b;
+		{
+			c; /* Hey, NOW it indents?! */
+		}
+	}
+
+	{
+		func(arg1,
+				arg2,
+				arg3);
+		/* Hey, what am I doing here?  Is this coz of the ","? */
+	}
+}
+
+main ()
+{
+	if (cond)
+	{
+		a = b;
+	}
+	if (cond) {
+		a = c;
+	}
+	if (cond)
+		a = d;
+	return;
+}
+
+{
+	case 2: if (asdf &&
+					asdfasdf)
+				aasdf;
+			a = 9;
+	case 3: if (asdf)
+				aasdf;
+			a = 9;
+	case 4:    x = 1;
+			   y = 2;
+
+label:	if (asdf)
+			here;
+
+label:  if (asdf &&
+				asdfasdf)
+		{
+		}
+
+label:  if (asdf &&
+				asdfasdf) {
+			there;
+		}
+
+label:  if (asdf &&
+				asdfasdf)
+			there;
+}
+
+{
+	/*
+	   hello with ":set comments= cino=c5"
+	 */
+
+	/*
+	   hello with ":set comments= cino="
+	 */
+}
+
+
+{
+	if (a < b) {
+		a = a + 1;
+	} else
+		a = a + 2;
+
+	if (a)
+		do {
+			testing;
+		} while (asdfasdf);
+	a = b + 1;
+	asdfasdf
+}
+
+class bob
+{
+	int foo() {return 1;}
+	int bar;
+}
+
+main()
+{
+	while(1)
+		if (foo)
+		{
+			bar;
+		}
+		else {
+			asdf;
+		}
+	misplacedline;
+}
+
+{
+	if (clipboard.state == SELECT_DONE
+			&& ((row == clipboard.start.lnum
+					&& col >= clipboard.start.col)
+				|| row > clipboard.start.lnum))
+}
+
+{
+	if (1) {i += 4;}
+	where_am_i;
+	return 0;
+}
+
+{
+	{
+	} // sdf(asdf
+	if (asdf)
+		asd;
+}
+
+{
+label1:
+label2:
+}
+
+{
+	int fooRet = foo(pBar1, false /*fKB*/,
+			true /*fPTB*/, 3 /*nT*/, false /*fDF*/);
+	f() {
+		for ( i = 0;
+				i < m;
+				/* c */ i++ ) {
+			a = b;
+		}
+	}
+}
+
+{
+	f1(/*comment*/);
+	f2();
+}
+
+{
+	do {
+		if (foo) {
+		} else
+			;
+	} while (foo);
+	foo();	// was wrong
+}
+
+int x;	    // no extra indent because of the ;
+void func()
+{
+}
+
+char *tab[] = {"aaa",
+	"};", /* }; */ NULL}
+	int indented;
+{}
+
+char *a[] = {"aaa", "bbb",
+	"ccc", NULL};
+// here
+
+char *tab[] = {"aaa",
+	"xx", /* xx */};    /* asdf */
+int not_indented;
+
+{
+	do {
+		switch (bla)
+		{
+			case 1: if (foo)
+						bar;
+		}
+	} while (boo);
+	wrong;
+}
+
+int	foo,
+	bar;
+int foo;
+
+#if defined(foo) \
+	&& defined(bar)
+char * xx = "asdf\
+			 foo\
+			 bor";
+int x;
+
+char    *foo = "asdf\
+				asdf\
+				asdf",
+		*bar;
+
+void f()
+{
+#if defined(foo) \
+	&& defined(bar)
+	char    *foo = "asdf\
+					asdf\
+					asdf",
+			*bar;
+	{
+		int i;
+		char    *foo = "asdf\
+						asdf\
+						asdf",
+				*bar;
+	}
+#endif
+}
+#endif
+
+int y;		// comment
+// comment
+
+// comment
+
+{
+	Constructor(int a,
+			int b )  : BaseClass(a)
+	{
+	}
+}
+
+void foo()
+{
+	char one,
+		 two;
+	struct bla piet,
+			   jan;
+	enum foo kees,
+			 jannie;
+	static unsigned sdf,
+					krap;
+	unsigned int piet,
+				 jan;
+	int
+		kees,
+		jan;
+}
+
+{
+	t(int f,
+			int d);		// )
+	d();
+}
+
+Constructor::Constructor(int a,
+		int b 
+		)  : 
+	BaseClass(a,
+			b,
+			c),
+	mMember(b),
+{
+}
+
+Constructor::Constructor(int a,
+		int b )  : 
+	BaseClass(a)
+{
+}
+
+Constructor::Constructor(int a,
+		int b ) /*x*/ : /*x*/ BaseClass(a),
+	member(b)
+{
+}
+
+class CAbc :
+	public BaseClass1,
+	protected BaseClass2
+{
+	int Test() { return FALSE; }
+	int Test1() { return TRUE; }
+
+	CAbc(int a, int b )  : 
+		BaseClass(a)
+	{ 
+		switch(xxx)
+		{
+			case abc:
+				asdf();
+				break;
+
+			case 999:
+				baer();
+				break;
+		}
+	}
+
+	public: // <-- this was incoreectly indented before!!
+	void testfall();
+	protected:
+	void testfall();
+};
+
+class CAbc : public BaseClass1,
+	protected BaseClass2
+{
+};
+
+static struct
+{
+	int a;
+	int b;
+} variable[COUNT] =
+{
+	{
+		123,
+		456
+	},
+	{
+		123,
+		456
+	}
+};
+
+static struct
+{
+	int a;
+	int b;
+} variable[COUNT] =
+{
+	{ 123, 456 },
+	{ 123, 456 }
+};
+
+void asdf()		/* ind_maxparen may cause trouble here */
+{
+	if ((0
+				&& 1
+				&& 1
+				&& 1
+				&& 1
+				&& 1
+				&& 1
+				&& 1
+				&& 1
+				&& 1
+				&& 1
+				&& 1
+				&& 1
+				&& 1
+				&& 1
+				&& 1
+				&& 1
+				&& 1
+				&& 1
+				&& 1
+				&& 1
+				&& 1
+				&& 1
+				&& 1
+				&& 1
+				&& 1)) break;
+}
+
+foo()
+{
+	a = cond ? foo() : asdf
+		+ asdf;
+
+	a = cond ?
+		foo() : asdf
+		+ asdf;
+}
+
+int  main(void)
+{
+	if (a)
+		if (b)
+			2;
+		else 3;
+	next_line_of_code();
+}
+
+barry()
+{
+	Foo::Foo (int one,
+			int two)
+		: something(4)
+	{}
+}
+
+barry()
+{
+	Foo::Foo (int one, int two)
+		: something(4)
+	{}
+}
+
+Constructor::Constructor(int a,
+		int b 
+		)  : 
+	BaseClass(a,
+			b,
+			c),
+	mMember(b)
+{
+}
+int main ()
+{
+	if (lala)
+		do
+			++(*lolo);
+		while (lili
+				&& lele);
+	lulu;
+}
+
+int main ()
+{
+	switch (c)
+	{
+		case 'c': if (cond)
+				  {
+				  }
+	}
+}
+
+main()
+{
+	(void) MyFancyFuasdfadsfnction(
+			argument);
+}
+
+main()
+{
+	char	foo[] = "/*";
+	/* as
+	   df */
+	hello
+}
+/* end of AUTO */
+
+
+{
+
+/* this is
+ * a real serious
+ * about life, the
+ * universe, and the
+ * rest important big
+ * comment
+ */
+	/* insert " about life, the universe, and the rest" after "serious" */
+}
+
+
+{
+	/*
+	 * Testing for comments, without 'cin' set
+	 */
+about life
+
+/*
+* what happens here?
+*/
+there
+
+	/*
+	   the end of the comment, try inserting a line below */
+line
+
+		/* how about
+hello
+		                this one */
+}
+
+
+{
+    var = this + that + vec[0] * vec[0]
+				      + vec[1] * vec[1]
+					  + vec2[2] * vec[2];
+}
+
+
+{
+		asdf asdflkajds f;
+	if (tes & ting) {
+		asdf asdf asdf ;
+		asdfa sdf asdf;
+		}
+	testing1;
+	if (tes & ting)
+	{
+		asdf asdf asdf ;
+		asdfa sdf asdf;
+		}
+	testing2;
+}
+
+
+main ( int first_par, /*
+					   * Comment for
+					   * first par
+					   */
+	   int second_par /*
+					   * Comment for
+					   * second par
+					   */
+	 )
+{
+	func( first_par, /*
+					  * Comment for
+					  * first par
+					  */
+		  second_par /*
+					  * Comment for
+					  * second par
+					  */
+		);
+
+}
+
+
+{
+	do
+	{
+		if ()
+		{
+			if ()
+				asdf;
+			else
+				asdf;
+		}
+	} while ();
+	cmd;		/* this should go under the } */
+}
+
+
+void f()
+{
+	if ( k() ) {
+		l();
+
+	} else { /* Start (two words) end */
+		m();
+	}
+
+	n();
+}
+
+
+void f()
+	{
+	if ( k() )
+		{
+		l();
+		} else { /* Start (two words) end */
+		m();
+		}
+	n();	/* should be under the if () */
+}
+
+
+void bar(void)
+	{
+	static array[2][2] =
+		{
+			{ 1, 2 },
+			{ 3, 4 },
+		}
+
+	while (a)
+		{
+		foo(&a);
+		}
+
+		{
+		int a;
+			{
+			a = a + 1;
+			}
+		}
+	b = a;
+	}
+
+void func(void)
+	{
+	a = 1;
+		{
+		b = 2;
+		}
+	c = 3;
+	d = 4;
+	}
+/* foo */
+
+
+a()
+{
+  do {
+    a = a +
+      a;
+  } while ( a );		/* add text under this line */
+  here
+    if ( a )
+      a;
+}
+
+
+a()
+{
+label1:
+            /* hmm */
+            // comment
+label2: b();
+label3 /* post */:
+/* pre */ label4:
+		f(/*com*/);
+		if (/*com*/)
+			cmd();
+}
+
+
+/*
+ * A simple comment
+ */
+
+/*
+** A different comment
+*/
+
+
+void f()
+{
+
+	/*********
+	  A comment.
+	*********/
+}
+
+
+void f()
+{
+
+	/*********
+	A comment.
+	*********/
+}
+
+
+void f()
+{
+	c = c1 &&
+		(
+		 c2 ||
+		 c3
+		) && c4;
+}
+
+
+void f()
+{
+	c = c1 &&
+		(
+		 c2 ||
+		 c3
+		) && c4;
+}
+
+
+void f()
+{
+	c = c1 &&
+		(
+			c2 ||
+			c3
+		) && c4;
+}
+
+
+void f()
+{
+	if (   c1
+		   && (   c2
+				  || c3))
+		foo;
+}
+
+
+void f()
+{
+	if (   c1
+		&& (   c2
+			|| c3))
+		foo;
+}
+
+
+void f()
+{
+	c = c1 && (
+		c2 ||
+		c3
+		) && c4;
+	if (
+		c1 && c2
+	   )
+		foo;
+}
+
+
+void f()
+{
+	c = c1 && (
+		c2 ||
+		c3
+	) && c4;
+	if (
+		c1 && c2
+	)
+		foo;
+}
+
+
+void f()
+{
+	switch (x)
+	{
+		case 1:
+			a = b;
+		break;
+		default:
+			a = 0;
+		break;
+	}
+}
+
+
+void f()
+{
+	invokeme(
+		 argu,
+		 ment);
+	invokeme(
+		 argu,
+		 ment
+		 );
+	invokeme(argu,
+			 ment
+			);
+}
+
+
+void f()
+{
+	statement;
+		  // comment 1
+		  // comment 2
+}
+
+
+void f()
+{
+	statement;
+	   // comment 1
+	   // comment 2
+}
+
+
+class CAbc
+{
+	int Test() { return FALSE; }
+
+public: // comment
+	void testfall();
+protected:
+	void testfall();
+};
+
+
+	void
+foo()
+{
+	if (a)
+	{
+	} else
+		asdf;
+}
+
+
+{
+	averylongfunctionnamelongfunctionnameaverylongfunctionname()->asd(
+			asdasdf,
+			func(asdf,
+				 asdfadsf),
+			asdfasdf
+			);
+
+	/* those are ugly, but consequent */
+
+	func()->asd(asdasdf,
+				averylongfunctionname(
+						abc,
+						dec)->averylongfunctionname(
+								asdfadsf,
+								asdfasdf,
+								asdfasdf,
+								),
+				func(asdfadf,
+					 asdfasdf
+					),
+				asdasdf
+			   );
+
+	averylongfunctionnameaverylongfunctionnameavery()->asd(fasdf(
+					abc,
+					dec)->asdfasdfasdf(
+							asdfadsf,
+							asdfasdf,
+							asdfasdf,
+							),
+			func(asdfadf,
+				 asdfasdf),
+			asdasdf
+			);
+}
+
+
+int main ()
+{
+	if (cond1 &&
+			cond2
+			)
+		foo;
+}
+
--- /dev/null
+++ b/testdir/test30.in
@@ -1,0 +1,208 @@
+Test for a lot of variations of the 'fileformats' option
+
+STARTTEST
+:so small.vim
+:" first write three test files, one in each format
+:set fileformat=unix
+:set fileformats=
+:/^1/w! XX1
+:/^2/w! XX2
+:/^3/w! XX3
+:/^4/w! XX4
+:/^5/w! XX5
+:/^6/w! XX6
+:/^7/w! XX7
+:/^8/w! XX8
+:/^9/w! XX9
+:/^10/w! XX10
+:/^unix/;/eof/-1w! XXUnix
+:/^dos/;/eof/-1w! XXDos
+:set bin noeol
+:$w! XXMac
+:set nobin eol
+:bwipe XXUnix XXDos XXMac
+:" create mixed format files
+:!cat XXUnix XXDos >XXUxDs
+:!cat XXUnix XXMac >XXUxMac
+:!cat XXDos XXMac >XXDosMac
+:!cat XXUnix XXDos XXMac >XXUxDsMc
+:"
+:" try reading and writing with 'fileformats' empty
+:set fileformat=unix
+:e! XXUnix
+:w! test.out
+:e! XXDos
+:w! XXtt01
+:e! XXMac
+:w! XXtt02
+:bwipe XXUnix XXDos XXMac
+:set fileformat=dos
+:e! XXUnix
+:w! XXtt11
+:e! XXDos
+:w! XXtt12
+:e! XXMac
+:w! XXtt13
+:bwipe XXUnix XXDos XXMac
+:set fileformat=mac
+:e! XXUnix
+:w! XXtt21
+:e! XXDos
+:w! XXtt22
+:e! XXMac
+:w! XXtt23
+:bwipe XXUnix XXDos XXMac
+:"
+:" try reading and writing with 'fileformats' set to one format
+:set fileformats=unix
+:e! XXUxDsMc
+:w! XXtt31
+:bwipe XXUxDsMc
+:set fileformats=dos
+:e! XXUxDsMc
+:w! XXtt32
+:bwipe XXUxDsMc
+:set fileformats=mac
+:e! XXUxDsMc
+:w! XXtt33
+:bwipe XXUxDsMc
+:"
+:" try reading and writing with 'fileformats' set to two formats
+:set fileformats=unix,dos
+:e! XXUxDsMc
+:w! XXtt41
+:bwipe XXUxDsMc
+:e! XXUxMac
+:w! XXtt42
+:bwipe XXUxMac
+:e! XXDosMac
+:w! XXtt43
+:bwipe XXDosMac
+:set fileformats=unix,mac
+:e! XXUxDs
+:w! XXtt51
+:bwipe XXUxDs
+:e! XXUxDsMc
+:w! XXtt52
+:bwipe XXUxDsMc
+:e! XXDosMac
+:w! XXtt53
+:bwipe XXDosMac
+:set fileformats=dos,mac
+:e! XXUxDs
+:w! XXtt61
+:bwipe XXUxDs
+:e! XXUxMac
+:w! XXtt62
+:bwipe XXUxMac
+:e! XXUxDsMc
+:w! XXtt63
+:bwipe XXUxDsMc
+:"
+:" try reading and writing with 'fileformats' set to three formats
+:set fileformats=unix,dos,mac
+:e! XXUxDsMc
+:w! XXtt71
+:bwipe XXUxDsMc
+:set fileformats=mac,dos,unix
+:e! XXUxDsMc
+:w! XXtt81
+:bwipe XXUxDsMc
+:" try with 'binary' set
+:set fileformats=mac,unix,dos
+:set binary
+:e! XXUxDsMc
+:w! XXtt91
+:bwipe XXUxDsMc
+:set fileformats=mac
+:e! XXUxDsMc
+:w! XXtt92
+:bwipe XXUxDsMc
+:set fileformats=dos
+:e! XXUxDsMc
+:w! XXtt93
+:"
+:" Append "END" to each file so that we can see what the last written char was.
+:set fileformat=unix nobin
+ggdGaEND:w >>XXtt01
+:w >>XXtt02
+:w >>XXtt11
+:w >>XXtt12
+:w >>XXtt13
+:w >>XXtt21
+:w >>XXtt22
+:w >>XXtt23
+:w >>XXtt31
+:w >>XXtt32
+:w >>XXtt33
+:w >>XXtt41
+:w >>XXtt42
+:w >>XXtt43
+:w >>XXtt51
+:w >>XXtt52
+:w >>XXtt53
+:w >>XXtt61
+:w >>XXtt62
+:w >>XXtt63
+:w >>XXtt71
+:w >>XXtt81
+:w >>XXtt91
+:w >>XXtt92
+:w >>XXtt93
+:"
+:" Concatenate the results.
+:" Make fileformat of test.out the native fileformat.
+:" Add a newline at the end.
+:set binary
+:e! test.out
+:$r XXtt01
+:$r XXtt02
+Go1:$r XXtt11
+:$r XXtt12
+:$r XXtt13
+Go2:$r XXtt21
+:$r XXtt22
+:$r XXtt23
+Go3:$r XXtt31
+:$r XXtt32
+:$r XXtt33
+Go4:$r XXtt41
+:$r XXtt42
+:$r XXtt43
+Go5:$r XXtt51
+:$r XXtt52
+:$r XXtt53
+Go6:$r XXtt61
+:$r XXtt62
+:$r XXtt63
+Go7:$r XXtt71
+Go8:$r XXtt81
+Go9:$r XXtt91
+:$r XXtt92
+:$r XXtt93
+Go10:$r XXUnix
+:set nobinary ff&
+:w
+:qa!
+ENDTEST
+
+1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+
+unix
+unix
+eof
+
+dos
+dos
+eof
+
+mac
mac
--- /dev/null
+++ b/testdir/test30.ok
@@ -1,0 +1,121 @@
+unix
+unix
+dos
+dos
+END
+mac
mac
+END
+1
+unix
+unix
+END
+dos
+dos
+END
+mac
mac

+END
+2
+unix
+unix
+
END
+dos
+dos
+
END
+mac
mac
END
+3
+unix
+unix
+dos
+dos
+mac
mac
+END
+unix
+unix
+dos
+dos
+mac
mac

+END
+unix
+unix
+dos
+dos
+mac
mac
END
+4
+unix
+unix
+dos
+dos
+mac
mac
+END
+unix
+unix
+mac
mac
+END
+dos
+dos
+mac
mac

+END
+5
+unix
+unix
+dos
+dos
+END
+unix
+unix
+dos
+dos
+mac
mac
+END
+dos
+dos
+mac
mac
END
+6
+unix
+unix
+dos
+dos
+END
+unix
+unix
+mac
mac

+END
+unix
+unix
+dos
+dos
+mac
mac

+END
+7
+unix
+unix
+dos
+dos
+mac
mac
+END
+8
+unix
+unix
+dos
+dos
+mac
mac
+END
+9
+unix
+unix
+dos
+dos
+mac
mac
END
+unix
+unix
+dos
+dos
+mac
mac
END
+unix
+unix
+dos
+dos
+mac
mac
END
+10
+unix
+unix
--- /dev/null
+++ b/testdir/test31.in
@@ -1,0 +1,69 @@
+Test for commands that close windows and/or buffers:
+:quit
+:close
+:hide
+:only
+:sall
+:all
+:ball
+:buf
+:edit
+
+STARTTEST
+:so tiny.vim
+GA 1:$w! Xtest1
+$r2:$w! Xtest2
+$r3:$w! Xtest3
+:n! Xtest1 Xtest2
+A 1:set hidden
+:" test for working :n when hidden set; write "testtext 2"
+:n
+:w! test.out
+:" test for failing :rew when hidden not set; write "testtext 2 2"
+:set nohidden
+A 2:rew
+:w >>test.out
+:" test for working :rew when hidden set; write "testtext 1 1"
+:set hidden
+:rew
+:w >>test.out
+:" test for :all keeping a buffer when it's modified; write "testtext 1 1 1"
+:set nohidden
+A 1:sp
+:n Xtest2 Xtest3
+:all
+:1wincmd w
+:w >>test.out
+:" test abandoning changed buffer, should be unloaded even when 'hidden' set
+:" write "testtext 2 2" twice
+:set hidden
+A 1:q!
+:w >>test.out
+:unhide
+:w >>test.out
+:" test ":hide" hides anyway when 'hidden' not set; write "testtext 3"
+:set nohidden
+A 2:hide
+:w >>test.out
+:" test ":edit" failing in modified buffer when 'hidden' not set
+:" write "testtext 3 3"
+A 3:e Xtest1
+:w >>test.out
+:" test ":edit" working in modified buffer when 'hidden' set; write "testtext 1"
+:set hidden
+:e Xtest1
+:w >>test.out
+:" test ":close" not hiding when 'hidden' not set in modified buffer;
+:" write "testtext 3 3 3"
+:sp Xtest3
+:set nohidden
+A 3:close
+:w >>test.out
+:" test ":close!" does hide when 'hidden' not set in modified buffer;
+:" write "testtext 1"
+A 3:close!
+:w >>test.out
+:qa!
+ENDTEST
+
+testtext
--- /dev/null
+++ b/testdir/test31.ok
@@ -1,0 +1,11 @@
+testtext 2
+testtext 2 2
+testtext 1 1
+testtext 1 1 1
+testtext 2 2
+testtext 2 2
+testtext 3
+testtext 3 3
+testtext 1
+testtext 3 3 3
+testtext 1
--- /dev/null
+++ b/testdir/test32.in
@@ -1,0 +1,57 @@
+Test for insert expansion
+
+:se cpt=.,w
+* add-expands (word from next line) from other window
+* add-expands (current buffer first)
+* Local expansion, ends in an empty line (unless it becomes a global expansion)
+* starts Local and switches to global add-expansion
+:se cpt=.,w,i
+* i-add-expands and switches to local
+* add-expands lines (it would end in an empty line if it didn't ignored it self)
+:se cpt=kXtestfile
+* checks k-expansion, and file expansion (use Xtest11 instead of test11,
+* because TEST11.OUT may match first on DOS)
+:se cpt=w
+* checks make_cyclic in other window
+:se cpt=u nohid
+* checks unloaded buffer expansion
+* checks adding mode abortion
+:se cpt=t,d
+* tag expansion, define add-expansion interrupted
+* t-expansion
+
+STARTTEST
+:so small.vim
+:se nocp viminfo+=nviminfo cpt=.,w ff=unix | $-2,$w!Xtestfile | set ff&
+:se cot=
+nO#include "Xtestfile"
+ru
+O
+
+
+:se cpt=.,w,i
+kOM
+
+:se cpt=kXtestfile
+:w Xtest11.one
+:w Xtest11.two
+OIXA
+:se cpt=w
+OST
+:se cpt=u nohid
+oOEN
+unl
+:se cpt=t,d def=^\\k* tags=Xtestfile notagbsearch
+O
+a
+:wq! test.out
+ENDTEST
+
+start of testfile
+run1
+run2
+end of testfile
+
+test11	36Gepeto	/Tag/
+asd	test11file	36G
+Makefile	to	run
--- /dev/null
+++ b/testdir/test32.ok
@@ -1,0 +1,15 @@
+#include "Xtestfile"
+run1 run3
+run3 run3
+
+Makefile	to	run3
+Makefile	to	run3
+Makefile	to	run3
+Xtest11.two
+STARTTEST
+ENDTEST
+unless
+test11file	36Gepeto	/Tag/ asd
+asd
+run1 run2
+
--- /dev/null
+++ b/testdir/test33.in
@@ -1,0 +1,34 @@
+Test for 'lisp'
+If the lisp feature is not enabled, this will fail!
+
+STARTTEST
+:so small.vim
+:set lisp
+/^(defun
+=G:/^(defun/,$w! test.out
+:q!
+ENDTEST
+
+(defun html-file (base)
+(format nil "~(~A~).html" base))
+
+(defmacro page (name title &rest body)
+(let ((ti (gensym)))
+`(with-open-file (*standard-output*
+(html-file ,name)
+:direction :output
+:if-exists :supersede)
+(let ((,ti ,title))
+(as title ,ti)
+(with center 
+(as h2 (string-upcase ,ti)))
+(brs 3)
+,@body))))
+
+;;; Utilities for generating links
+
+(defmacro with-link (dest &rest body)
+`(progn
+(format t "<a href=\"~A\">" (html-file ,dest))
+,@body
+(princ "</a>")))
--- /dev/null
+++ b/testdir/test33.ok
@@ -1,0 +1,23 @@
+(defun html-file (base)
+  (format nil "~(~A~).html" base))
+
+(defmacro page (name title &rest body)
+  (let ((ti (gensym)))
+       `(with-open-file (*standard-output*
+			 (html-file ,name)
+			 :direction :output
+			 :if-exists :supersede)
+			(let ((,ti ,title))
+			     (as title ,ti)
+			     (with center 
+				   (as h2 (string-upcase ,ti)))
+			     (brs 3)
+			     ,@body))))
+
+;;; Utilities for generating links
+
+(defmacro with-link (dest &rest body)
+  `(progn
+    (format t "<a href=\"~A\">" (html-file ,dest))
+    ,@body
+    (princ "</a>")))
--- /dev/null
+++ b/testdir/test34.in
@@ -1,0 +1,58 @@
+Test for user functions.
+Also test an <expr> mapping calling a function.
+
+STARTTEST
+:so small.vim
+:function Table(title, ...)
+:  let ret = a:title
+:  let idx = 1
+:  while idx <= a:0
+:    exe "let ret = ret . a:" . idx
+:    let idx = idx + 1
+:  endwhile
+:  return ret
+:endfunction
+:function Compute(n1, n2, divname)
+:  if a:n2 == 0
+:    return "fail"
+:  endif
+:  exe "let g:" . a:divname . " = ". a:n1 / a:n2
+:  return "ok"
+:endfunction
+:func Expr1()
+:  normal! v
+:  return "111"
+:endfunc
+:func Expr2()
+:  call search('XX', 'b')
+:  return "222"
+:endfunc
+:func ListItem()
+:  let g:counter += 1
+:  return g:counter . '. '
+:endfunc
+:func ListReset()
+:  let g:counter = 0
+:  return ''
+:endfunc
+:let counter = 0
+:inoremap <expr> ( ListItem()
+:inoremap <expr> [ ListReset()
+:imap <expr> + Expr1()
+:imap <expr> * Expr2()
+:let retval = "nop"
+/^here
+C=Table("xxx", 4, "asdf")
+ =Compute(45, 0, "retval")
+ =retval
+ =Compute(45, 5, "retval")
+ =retval
+
+XX+-XX
+---*---
+(one
+(two
+[(one again:$-5,$wq! test.out
+ENDTEST
+
+here
--- /dev/null
+++ b/testdir/test34.ok
@@ -1,0 +1,6 @@
+xxx4asdf fail nop ok 9
+XX111XX
+---222---
+1. one
+2. two
+1. one again
--- /dev/null
+++ b/testdir/test35.in
@@ -1,0 +1,21 @@
+Test Ctrl-A and Ctrl-X, which increment and decrement decimal, hexadecimal,
+and octal numbers.
+
+STARTTEST
+/^start-here
+:set nrformats=octal,hex
+j102ll64128$
+:set nrformats=octal
+0102l2w65129blx6lD
+:set nrformats=hex
+0101l257Txldt   
+:set nrformats=
+0200l100w78k
+:$-3,$wq! test.out
+ENDTEST
+
+start-here
+100     0x100     077     0
+100     0x100     077     
+100     0x100     077     0xfF     0xFf
+100     0x100     077     
--- /dev/null
+++ b/testdir/test35.ok
@@ -1,0 +1,4 @@
+0     0x0ff     0000     -1
+0     1x100     0777777
+-1     0x0     078     0xFE     0xfe
+-100     -100x100     000     
--- /dev/null
+++ b/testdir/test36.in
@@ -1,0 +1,40 @@
+Test character classes in regexp
+
+STARTTEST
+/^start-here
+j:s/\d//g
+j:s/\D//g
+j:s/\o//g
+j:s/\O//g
+j:s/\x//g
+j:s/\X//g
+j:s/\w//g
+j:s/\W//g
+j:s/\h//g
+j:s/\H//g
+j:s/\a//g
+j:s/\A//g
+j:s/\l//g
+j:s/\L//g
+j:s/\u//g
+j:s/\U//g
+:/^start-here/+1,$wq! test.out
+ENDTEST
+
+start-here
+	
 !"#$%&'()#+'-./0123456789:;<=>?@ABCDEFGHIXYZ[\]^_`abcdefghiwxyz{|}~���������+	
 !"#$%&'()#+'-./0123456789:;<=>?@ABCDEFGHIXYZ[\]^_`abcdefghiwxyz{|}~���������+	
 !"#$%&'()#+'-./0123456789:;<=>?@ABCDEFGHIXYZ[\]^_`abcdefghiwxyz{|}~���������+	
 !"#$%&'()#+'-./0123456789:;<=>?@ABCDEFGHIXYZ[\]^_`abcdefghiwxyz{|}~���������+	
 !"#$%&'()#+'-./0123456789:;<=>?@ABCDEFGHIXYZ[\]^_`abcdefghiwxyz{|}~���������+	
 !"#$%&'()#+'-./0123456789:;<=>?@ABCDEFGHIXYZ[\]^_`abcdefghiwxyz{|}~���������+	
 !"#$%&'()#+'-./0123456789:;<=>?@ABCDEFGHIXYZ[\]^_`abcdefghiwxyz{|}~���������+	
 !"#$%&'()#+'-./0123456789:;<=>?@ABCDEFGHIXYZ[\]^_`abcdefghiwxyz{|}~���������+	
 !"#$%&'()#+'-./0123456789:;<=>?@ABCDEFGHIXYZ[\]^_`abcdefghiwxyz{|}~���������+	
 !"#$%&'()#+'-./0123456789:;<=>?@ABCDEFGHIXYZ[\]^_`abcdefghiwxyz{|}~���������+	
 !"#$%&'()#+'-./0123456789:;<=>?@ABCDEFGHIXYZ[\]^_`abcdefghiwxyz{|}~���������+	
 !"#$%&'()#+'-./0123456789:;<=>?@ABCDEFGHIXYZ[\]^_`abcdefghiwxyz{|}~���������+	
 !"#$%&'()#+'-./0123456789:;<=>?@ABCDEFGHIXYZ[\]^_`abcdefghiwxyz{|}~���������+	
 !"#$%&'()#+'-./0123456789:;<=>?@ABCDEFGHIXYZ[\]^_`abcdefghiwxyz{|}~���������+	
 !"#$%&'()#+'-./0123456789:;<=>?@ABCDEFGHIXYZ[\]^_`abcdefghiwxyz{|}~���������+	
 !"#$%&'()#+'-./0123456789:;<=>?@ABCDEFGHIXYZ[\]^_`abcdefghiwxyz{|}~���������--- /dev/null
+++ b/testdir/test36.ok
@@ -1,0 +1,16 @@
+	
 !"#$%&'()#+'-./:;<=>?@ABCDEFGHIXYZ[\]^_`abcdefghiwxyz{|}~���������+0123456789
+	
 !"#$%&'()#+'-./89:;<=>?@ABCDEFGHIXYZ[\]^_`abcdefghiwxyz{|}~���������+01234567
+	
 !"#$%&'()#+'-./:;<=>?@GHIXYZ[\]^_`ghiwxyz{|}~���������+0123456789ABCDEFabcdef
+	
 !"#$%&'()#+'-./:;<=>?@[\]^`{|}~���������+0123456789ABCDEFGHIXYZ_abcdefghiwxyz
+	
 !"#$%&'()#+'-./0123456789:;<=>?@[\]^`{|}~���������+ABCDEFGHIXYZ_abcdefghiwxyz
+	
 !"#$%&'()#+'-./0123456789:;<=>?@[\]^_`{|}~���������+ABCDEFGHIXYZabcdefghiwxyz
+	
 !"#$%&'()#+'-./0123456789:;<=>?@ABCDEFGHIXYZ[\]^_`{|}~���������+abcdefghiwxyz
+	
 !"#$%&'()#+'-./0123456789:;<=>?@[\]^_`abcdefghiwxyz{|}~���������+ABCDEFGHIXYZ
--- /dev/null
+++ b/testdir/test37.in
@@ -1,0 +1,116 @@
+Test for 'scrollbind'. <eralston@computer.org>   Do not add a line below!
+STARTTEST
+:so small.vim
+:set noscrollbind
+:set scrollopt=ver,jump
+:set scrolloff=2
+:set nowrap
+:set noequalalways
+:set splitbelow
+:" TEST using two windows open to one buffer, one extra empty window
+:split
+:new
+t:
+:resize 8
+/^start of window 1$/
+zt:
+:set scrollbind
+j:
+:resize 7
+/^start of window 2$/
+zt:
+:set scrollbind
+:" -- start of tests --
+:" TEST scrolling down
+L5jHyybpr0tHyybpr1tL6jHyybpr2kHyybpr3:
+:" TEST scrolling up
+tH4kjHtHyybpr4kHyybpr5k3ktHjHyybpr6tHyybpr7:
+:" TEST horizontal scrolling
+:set scrollopt+=hor
+gg"zyyG"zpGt015zly$bp"zpGky$bp"zpG:
+k10jH7zhg0y$bp"zpGtHg0y$bp"zpG:
+:set scrollopt-=hor
+:" ****** tests using two different buffers *****
+tj:
+:close
+t:
+:set noscrollbind
+:/^start of window 2$/,/^end of window 2$/y
+:new
+tj4"zpGp:
+t/^start of window 1$/
+zt:
+:set scrollbind
+j:
+/^start of window 2$/
+zt:
+:set scrollbind
+:" -- start of tests --
+:" TEST scrolling down
+L5jHyybpr0tHyybpr1tL6jHyybpr2kHyybpr3:
+:" TEST scrolling up
+tH4kjHtHyybpr4kHyybpr5k3ktHjHyybpr6tHyybpr7:
+:" TEST horizontal scrolling
+:set scrollopt+=hor
+gg"zyyG"zpGt015zly$bp"zpGky$bp"zpG:
+k10jH7zhg0y$bp"zpGtHg0y$bp"zpG:
+:set scrollopt-=hor
+:" TEST syncbind
+t:set noscb
+ggLj:set noscb
+ggL:set scb
+t:set scb
+GjG:syncbind
+HktHjHyybptyybp:
+t:set noscb
+ggLj:set noscb
+ggL:set scb
+t:set scb
+tGjGt:syncbind
+HkjHtHyybptjyybp:
+tH3kjHtHyybptjyybp:
+:" ***** done with tests *****
+:w! test.out             " Write contents of this file
+:qa!
+ENDTEST
+
+
+start of window 1
+. line 01 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ 01
+. line 02 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ 02
+. line 03 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ 03
+. line 04 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ 04
+. line 05 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ 05
+. line 06 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ 06
+. line 07 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ 07
+. line 08 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ 08
+. line 09 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ 09
+. line 10 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ 10
+. line 11 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ 11
+. line 12 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ 12
+. line 13 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ 13
+. line 14 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ 14
+. line 15 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ 15
+end of window 1
+
+
+start of window 2
+. line 01 ZYXWVUTSRQPONMLKJIHGREDCBA9876543210 01
+. line 02 ZYXWVUTSRQPONMLKJIHGREDCBA9876543210 02
+. line 03 ZYXWVUTSRQPONMLKJIHGREDCBA9876543210 03
+. line 04 ZYXWVUTSRQPONMLKJIHGREDCBA9876543210 04
+. line 05 ZYXWVUTSRQPONMLKJIHGREDCBA9876543210 05
+. line 06 ZYXWVUTSRQPONMLKJIHGREDCBA9876543210 06
+. line 07 ZYXWVUTSRQPONMLKJIHGREDCBA9876543210 07
+. line 08 ZYXWVUTSRQPONMLKJIHGREDCBA9876543210 08
+. line 09 ZYXWVUTSRQPONMLKJIHGREDCBA9876543210 09
+. line 10 ZYXWVUTSRQPONMLKJIHGREDCBA9876543210 10
+. line 11 ZYXWVUTSRQPONMLKJIHGREDCBA9876543210 11
+. line 12 ZYXWVUTSRQPONMLKJIHGREDCBA9876543210 12
+. line 13 ZYXWVUTSRQPONMLKJIHGREDCBA9876543210 13
+. line 14 ZYXWVUTSRQPONMLKJIHGREDCBA9876543210 14
+. line 15 ZYXWVUTSRQPONMLKJIHGREDCBA9876543210 15
+. line 16 ZYXWVUTSRQPONMLKJIHGREDCBA9876543210 16
+end of window 2
+
+end of test37.in (please don't delete this line)
--- /dev/null
+++ b/testdir/test37.ok
@@ -1,0 +1,33 @@
+
+0 line 05 ZYXWVUTSRQPONMLKJIHGREDCBA9876543210 05
+1 line 05 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ 05
+2 line 11 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ 11
+3 line 11 ZYXWVUTSRQPONMLKJIHGREDCBA9876543210 11
+4 line 06 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ 06
+5 line 06 ZYXWVUTSRQPONMLKJIHGREDCBA9876543210 06
+6 line 02 ZYXWVUTSRQPONMLKJIHGREDCBA9876543210 02
+7 line 02 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ 02
+56789ABCDEFGHIJKLMNOPQRSTUVWXYZ 02
+UTSRQPONMLKJIHGREDCBA9876543210 02
+. line 11 ZYXWVUTSRQPONMLKJIHGREDCBA9876543210 11
+. line 11 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ 11
+
+0 line 05 ZYXWVUTSRQPONMLKJIHGREDCBA9876543210 05
+1 line 05 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ 05
+2 line 11 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ 11
+3 line 11 ZYXWVUTSRQPONMLKJIHGREDCBA9876543210 11
+4 line 06 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ 06
+5 line 06 ZYXWVUTSRQPONMLKJIHGREDCBA9876543210 06
+6 line 02 ZYXWVUTSRQPONMLKJIHGREDCBA9876543210 02
+7 line 02 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ 02
+56789ABCDEFGHIJKLMNOPQRSTUVWXYZ 02
+UTSRQPONMLKJIHGREDCBA9876543210 02
+. line 11 ZYXWVUTSRQPONMLKJIHGREDCBA9876543210 11
+. line 11 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ 11
+
+. line 16 ZYXWVUTSRQPONMLKJIHGREDCBA9876543210 16
+:set scrollbind
+zt:
+. line 15 ZYXWVUTSRQPONMLKJIHGREDCBA9876543210 15
+:set scrollbind
+. line 11 ZYXWVUTSRQPONMLKJIHGREDCBA9876543210 11
--- /dev/null
+++ b/testdir/test38.in
@@ -1,0 +1,33 @@
+
+Test Virtual replace mode.
+
+STARTTEST
+:so small.vim
+ggdGa
+abcdefghi
+jk	lmn
+    opq	rst
+uvwxyz
+gg:set ai
+:set bs=2
+gR0 1
+A
+BCDEFGHIJ
+	KL
+MNO
+PQRG:ka
+o0
+abcdefghi
+jk	lmn
+    opq	rst
+uvwxyz
+'ajgR0 1
+A
+BCDEFGHIJ
+	KL
+MNO
+PQR:$
+iab	cdefghi	jkl0gRAB......CDEFGHI.Jo:
+iabcdefghijklmnopqrst0gRAB	IJKLMNO	QR:wq! test.out
+ENDTEST
+
--- /dev/null
+++ b/testdir/test38.ok
@@ -1,0 +1,13 @@
+ 1
+ A
+ BCDEFGHIJ
+ 	KL
+	MNO
+	PQR
+ 1
+abcdefghi
+jk	lmn
+    opq	rst
+uvwxyz
+AB......CDEFGHI.Jkl
+AB	IJKLMNO	QRst
--- /dev/null
+++ b/testdir/test39.in
@@ -1,0 +1,24 @@
+
+Test Visual block mode commands
+
+STARTTEST
+:so small.vim
+/^abcde
+:" Test shift-right of a block
+jlllljj>wlljlll>
+:" Test shift-left of a block
+G$hhhhkk<
+:" Test block-insert
+GklkkkIxyz
+:" Test block-replace
+Gllllkkklllrq
+:" Test block-change
+G$khhhhhkkcmno
+:$-4,$wq! test.out
+ENDTEST
+
+abcdefghijklm
+abcdefghijklm
+abcdefghijklm
+abcdefghijklm
+abcdefghijklm
--- /dev/null
+++ b/testdir/test39.ok
@@ -1,0 +1,5 @@
+axyzbcdefghijklm
+axyzqqqq   mno	      ghijklm
+axyzqqqqef mno        ghijklm
+axyzqqqqefgmnoklm
+abcdqqqqijklm
--- /dev/null
+++ b/testdir/test4.in
@@ -1,0 +1,31 @@
+Test for autocommand that changes current buffer on BufEnter event.
+Check if modelines are interpreted for the correct buffer.
+
+STARTTEST
+:so small.vim
+:set nocompatible viminfo+=nviminfo
+:au BufEnter Xxx brew
+/start of
+:.,/end of/w! Xxx   " write test file Xxx
+:set ai modeline modelines=3
+:sp Xxx             " split to Xxx, autocmd will do :brew
+G?this is a
+othis should be auto-indented
+:                   " Append text with autoindent to this file
+:au! BufEnter Xxx
+:buf Xxx            " go to Xxx, no autocmd anymore
+G?this is a
+othis should be in column 1:wq " append text without autoindent to Xxx
+G:r Xxx             " include Xxx in the current file
+:?startstart?,$w! test.out
+:qa!
+ENDTEST
+
+startstart
+start of test file Xxx
+vim: set noai :
+	this is a test
+	this is a test
+	this is a test
+	this is a test
+end of test file Xxx
--- /dev/null
+++ b/testdir/test4.ok
@@ -1,0 +1,17 @@
+startstart
+start of test file Xxx
+vim: set noai :
+	this is a test
+	this is a test
+	this is a test
+	this is a test
+	this should be auto-indented
+end of test file Xxx
+start of test file Xxx
+vim: set noai :
+	this is a test
+	this is a test
+	this is a test
+	this is a test
+this should be in column 1
+end of test file Xxx
--- /dev/null
+++ b/testdir/test40.in
@@ -1,0 +1,63 @@
+Test for "*Cmd" autocommands
+
+STARTTEST
+:so small.vim
+:/^start/,$w! Xxx		" write lines below to Xxx
+:au BufReadCmd testA 0r Xxx|$del
+:e testA			" will read text of Xxd instead
+:au BufWriteCmd testA call append(line("$"), "write")
+:w				" will append a line to the file
+:r testA			" should not read anything
+:				" now we have:
+:				" 1	start of Xxx
+:				" 2		test40
+:				" 3	end of Xxx
+:				" 4	write
+:au FileReadCmd testB '[r Xxx
+:2r testB			" will read Xxx below line 2 instead
+:				" 1	start of Xxx
+:				" 2		test40
+:				" 3	start of Xxx
+:				" 4		test40
+:				" 5	end of Xxx
+:				" 6	end of Xxx
+:				" 7	write
+:au FileWriteCmd testC '[,']copy $
+4GA1
+:4,5w testC			" will copy lines 4 and 5 to the end
+:r testC			" should not read anything
+:				" 1	start of Xxx
+:				" 2		test40
+:				" 3	start of Xxx
+:				" 4		test401
+:				" 5	end of Xxx
+:				" 6	end of Xxx
+:				" 7	write
+:				" 8		test401
+:				" 9	end of Xxx
+:au FILEAppendCmd testD '[,']w! test.out
+:w >>testD			" will write all lines to test.out
+:$r testD			" should not read anything
+:$w >>test.out			" append "end of Xxx" to test.out
+:au BufReadCmd testE 0r test.out|$del
+:sp testE			" split window with test.out
+5Goasdf:"
+:au BufWriteCmd testE w! test.out
+:wall				" will write other window to test.out
+:				" 1	start of Xxx
+:				" 2		test40
+:				" 3	start of Xxx
+:				" 4		test401
+:				" 5	end of Xxx
+:				" 6	asdf
+:				" 7	end of Xxx
+:				" 8	write
+:				" 9		test401
+:				" 10	end of Xxx
+:				" 11	end of Xxx
+:qa!
+ENDTEST
+
+start of Xxx
+	test40
+end of Xxx
--- /dev/null
+++ b/testdir/test40.ok
@@ -1,0 +1,11 @@
+start of Xxx
+	test40
+start of Xxx
+	test401
+end of Xxx
+asdf
+end of Xxx
+write
+	test401
+end of Xxx
+end of Xxx
--- /dev/null
+++ b/testdir/test41.in
@@ -1,0 +1,24 @@
+Test for writing and reading a file of over 100 Kbyte
+
+1 line: "This is the start"
+3001 lines: "This is the leader"
+1 line: "This is the middle"
+3001 lines: "This is the trailer"
+1 line: "This is the end"
+
+STARTTEST
+:%d
+aThis is the start
+This is the leader
+This is the middle
+This is the trailer
+This is the endkY3000p2GY3000p
+:w! Xtest
+:%d
+:e! Xtest
+:.w! test.out
+3003G:.w >>test.out
+6005G:.w >>test.out
+:qa!
+ENDTEST
+
--- /dev/null
+++ b/testdir/test41.ok
@@ -1,0 +1,3 @@
+This is the start
+This is the middle
+This is the end
binary files /dev/null b/testdir/test42.in differ
binary files /dev/null b/testdir/test42.ok differ
--- /dev/null
+++ b/testdir/test43.in
@@ -1,0 +1,27 @@
+Tests for regexp with various magic settings.
+
+STARTTEST
+:set nocompatible viminfo+=nviminfo
+/^1
+/a*b\{2}c\+/e
+x/\Md\*e\{2}f\+/e
+x:set nomagic
+/g\*h\{2}i\+/e
+x/\mj*k\{2}l\+/e
+x/\vm*n{2}o+/e
+x/\V^aa$
+x:set magic
+/\v(a)(b)\2\1\1/e
+x/\V[ab]\(\[xy]\)\1
+x:?^1?,$w! test.out
+:qa!
+ENDTEST
+
+1 a aa abb abbccc
+2 d dd dee deefff
+3 g gg ghh ghhiii
+4 j jj jkk jkklll
+5 m mm mnn mnnooo
+6 x ^aa$ x
+7 (a)(b) abbaa
+8 axx [ab]xx
--- /dev/null
+++ b/testdir/test43.ok
@@ -1,0 +1,8 @@
+1 a aa abb abbcc
+2 d dd dee deeff
+3 g gg ghh ghhii
+4 j jj jkk jkkll
+5 m mm mnn mnnoo
+6 x aa$ x
+7 (a)(b) abba
+8 axx ab]xx
--- /dev/null
+++ b/testdir/test44.in
@@ -1,0 +1,55 @@
+Tests for regexp with multi-byte encoding and various magic settings.
+Test matchstr() with a count and multi-byte chars.
+
+STARTTEST
+:so mbyte.vim
+:set nocompatible encoding=utf-8 termencoding=latin1 viminfo+=nviminfo
+/^1
+/a*b\{2}c\+/e
+x/\Md\*e\{2}f\+/e
+x:set nomagic
+/g\*h\{2}i\+/e
+x/\mj*k\{2}l\+/e
+x/\vm*n{2}o+/e
+x/\V^aa$
+x:set magic
+/\v(a)(b)\2\1\1/e
+x/\V[ab]\(\[xy]\)\1
+x:" Now search for multi-byte without composing char
+/ม
+x:" Now search for multi-byte with composing char
+/ม่
+x:" find word by change of word class
+/ち\<カヨ\>は
+x:" Test \%u, [\u] and friends
+/\%u20ac
+x/[\u4f7f\u5929]\+
+x/\%U12345678
+x/[\U1234abcd\u1234\uabcd]
+x/\%d21879b
+x:?^1?,$w! test.out
+:e! test.out
+G:put =matchstr(\"אבגד\", \".\", 0, 2) " ב
+:put =matchstr(\"אבגד\", \"..\", 0, 2) " בג
+:put =matchstr(\"אבגד\", \".\", 0, 0) " א
+:put =matchstr(\"אבגד\", \".\", 4, -1) " ג
+:w!
+:qa!
+ENDTEST
+
+1 a aa abb abbccc
+2 d dd dee deefff
+3 g gg ghh ghhiii
+4 j jj jkk jkklll
+5 m mm mnn mnnooo
+6 x ^aa$ x
+7 (a)(b) abbaa
+8 axx [ab]xx
+9 หม่x อมx
+a อมx หม่x
+b ちカヨは
+c x ¬€x
+d 天使x
+e ������y
+f ������z
+g a啷bb
--- /dev/null
+++ b/testdir/test44.ok
@@ -1,0 +1,20 @@
+1 a aa abb abbcc
+2 d dd dee deeff
+3 g gg ghh ghhii
+4 j jj jkk jkkll
+5 m mm mnn mnnoo
+6 x aa$ x
+7 (a)(b) abba
+8 axx ab]xx
+9 หม่x อx
+a อมx หx
+b カヨは
+c x ¬x
+d 使x
+e y
+f z
+g abb
+בג
--- /dev/null
+++ b/testdir/test45.in
@@ -1,0 +1,72 @@
+Tests for folding. vim: set ft=vim :
+
+STARTTEST
+:so small.vim
+:" We also need the +syntax feature here.
+:if !has("syntax")
+   e! test.ok
+   w! test.out
+   qa!
+:endif
+:" basic test if a fold can be created, opened, moving to the end and closed
+/^1
+zf2j:call append("$", "manual " . getline(foldclosed(".")))
+zo:call append("$", foldclosed("."))
+]z:call append("$", getline("."))
+zc:call append("$", getline(foldclosed(".")))
+:" test folding with markers.
+:set fdm=marker fdl=1 fdc=3
+/^5
+:call append("$", "marker " . foldlevel("."))
+[z:call append("$", foldlevel("."))
+jo{{ r{jj:call append("$", foldlevel("."))
+kYpj:call append("$", foldlevel("."))
+:" test folding with indent
+:set fdm=indent sw=2
+/^2 b
+i  jI    :call append("$", "indent " . foldlevel("."))
+k:call append("$", foldlevel("."))
+:" test syntax folding
+:set fdm=syntax fdl=0
+:syn region Hup start="dd" end="hh" fold
+Gzk:call append("$", "folding " . getline("."))
+k:call append("$", getline("."))
+:" test expression folding
+:fun Flvl()
+  let l = getline(v:lnum)
+  if l =~ "bb$"
+    return 2
+  elseif l =~ "gg$"
+    return "s1"
+  elseif l =~ "ii$"
+    return ">2"
+  elseif l =~ "kk$"
+    return "0"
+  endif
+  return "="
+endfun
+:set fdm=expr fde=Flvl()
+/bb$
+:call append("$", "expr " . foldlevel("."))
+/hh$
+:call append("$", foldlevel("."))
+/ii$
+:call append("$", foldlevel("."))
+/kk$
+:call append("$", foldlevel("."))
+:/^last/+1,$w! test.out
+:qa!
+ENDTEST
+
+1 aa
+2 bb
+3 cc
+4 dd {{{
+5 ee {{{ }}}
+6 ff }}}
+7 gg
+8 hh
+9 ii
+a jj
+b kk
+last
--- /dev/null
+++ b/testdir/test45.ok
@@ -1,0 +1,16 @@
+manual 1 aa
+-1
+3 cc
+1 aa
+marker 2
+1
+1
+0
+indent 2
+1
+folding 8 hh
+    3 cc
+expr 2
+1
+2
+0
--- /dev/null
+++ b/testdir/test46.in
@@ -1,0 +1,27 @@
+Tests for multi-line regexps with ":s". vim: set ft=vim :
+
+STARTTEST
+:" test if replacing a line break works with a back reference
+:/^1/,/^2/s/\n\(.\)/ \1/
+:" test if inserting a line break works with a back reference
+:/^3/,/^4/s/\(.\)$/\r\1/
+:" test if replacing a line break with another line break works
+:/^5/,/^6/s/\(\_d\{3}\)/x\1x/
+:/^1/,$w! test.out
+:qa!
+ENDTEST
+
+1 aa
+bb
+cc
+2 dd
+ee
+3 ef
+gh
+4 ij
+5 a8
+8b c9
+9d
+6 e7
+77f
+xxxxx
--- /dev/null
+++ b/testdir/test46.ok
@@ -1,0 +1,13 @@
+1 aa bb cc 2 dd ee
+3 e
+f
+g
+h
+4 i
+j
+5 ax8
+8xb cx9
+9xd
+6 ex7
+7x7f
+xxxxx
--- /dev/null
+++ b/testdir/test47.in
@@ -1,0 +1,44 @@
+Tests for vertical splits and filler lines in diff mode
+
+STARTTEST
+:so small.vim
+/^1
+yG:new
+pkdd:w! Xtest
+ddGpkkrXoxxx:w! Xtest2
+:file Nop
+ggoyyyjjjozzzz
+:vert diffsplit Xtest
+:vert diffsplit Xtest2
+:" jump to second window for a moment to have filler line appear at start of
+:" first window
+ggpgg:let one = winline()
+j:let one = one . "-" . winline()
+j:let one = one . "-" . winline()
+j:let one = one . "-" . winline()
+j:let one = one . "-" . winline()
+j:let one = one . "-" . winline()
+gg:let two = winline()
+j:let two = two . "-" . winline()
+j:let two = two . "-" . winline()
+j:let two = two . "-" . winline()
+j:let two = two . "-" . winline()
+gg:let three = winline()
+j:let three = three . "-" . winline()
+j:let three = three . "-" . winline()
+j:let three = three . "-" . winline()
+j:let three = three . "-" . winline()
+j:let three = three . "-" . winline()
+j:let three = three . "-" . winline()
+:call append("$", one)
+:call append("$", two)
+:call append("$", three)
+:$-2,$w! test.out
+:qa!
+ENDTEST
+
+1 aa
+2 bb
+3 cc
+4 dd
+5 ee
--- /dev/null
+++ b/testdir/test47.ok
@@ -1,0 +1,3 @@
+2-4-5-6-8-9
+1-2-4-5-8
+2-3-4-5-6-7-8
--- /dev/null
+++ b/testdir/test48.in
@@ -1,0 +1,74 @@
+This is a test of 'virtualedit'.
+
+STARTTEST
+:so small.vim
+:set noswf
+:set ve=all
+-dgg
+:"
+:"   Insert "keyword keyw", ESC, C CTRL-N, shows "keyword ykeyword".
+:"    Repeating CTRL-N fixes it. (Mary Ellen Foster)
+2/w
+C
+:"
+:"   Using "C" then then <CR> moves the last remaining character to the next
+:"    line.  (Mary Ellen Foster)
+j^/are
+C
are belong to vim
+:"
+:"   When past the end of a line that ends in a single character "b" skips
+:"    that word.
+^$15lbC7
+:"
+:"   Make sure 'i' works
+$4li<-- should be 3 ' '
+:"
+:"   Make sure 'C' works
+$4lC<-- should be 3 ' '
+:"
+:"   Make sure 'a' works
+$4la<-- should be 4 ' '
+:"
+:"   Make sure 'A' works
+$4lA<-- should be 0 ' '
+:"
+:"   Make sure 'D' works
+$4lDi<-- 'D' should be intact
+:"
+:"   Test for yank bug reported by Mark Waggoner.
+:set ve=block
+^2w3jyGp
+:"
+:" Test "r" beyond the end of the line
+:set ve=all
+/^"r"
+$5lrxa<-- should be 'x'
+:"
+:"   Test to make sure 'x' can delete control characters
+:set display=uhex
+^xxxxxxi[This line should contain only the text between the brackets.]
+:set display=
+:"
+:"   Test for ^Y/^E due to bad w_virtcol value, reported by
+:"   Roy <royl@netropolis.net>.
+^O3li4li4li   <-- should show the name of a noted text editor
+^o4li4li4li   <-- and its version number-dd
+:"
+:wq! test.out
+ENDTEST
+keyword keyw
+all your base are belong to us
+1 2 3 4 5 6
+'i'
+'C'
+'a'
+'A'
+'D'
+this is a test
+this is a test
+this is a test
+"r"
+ab
sd
+abcv6efi.him0kl
+
+
--- /dev/null
+++ b/testdir/test48.ok
@@ -1,0 +1,21 @@
+keyword keyword
+all your base 
+are belong to vim
+1 2 3 4 5 7
+'i'   <-- should be 3 ' '
+'C'   <-- should be 3 ' '
+'a'    <-- should be 4 ' '
+'A'<-- should be 0 ' '
+'D'   <-- 'D' should be intact
+this is a test
+this is a test
+this is a test
+"r"    x<-- should be 'x'
+[This line should contain only the text between the brackets.]
+   v   i   m   <-- should show the name of a noted text editor
+    6   .   0   <-- and its version number
+
+a
+a
+a
+ 
--- /dev/null
+++ b/testdir/test49.in
@@ -1,0 +1,13 @@
+This is a test of the script language.
+
+If after adding a new test, the test output doesn't appear properly in
+test49.failed, try to add one ore more "G"s at the line before ENDTEST.
+
+STARTTEST
+:so small.vim
+:se nocp nomore viminfo+=nviminfo
+:so test49.vim
+GGGGGGGGGG"rp:.-,$wq! test.out
+ENDTEST
+
+Results of test49.vim:
--- /dev/null
+++ b/testdir/test49.ok
@@ -1,0 +1,92 @@
+Results of test49.vim:
+*** Test   1: OK (34695)
+*** Test   2: OK (34695)
+*** Test   3: OK (1384648195)
+*** Test   4: OK (32883)
+*** Test   5: OK (32883)
+*** Test   6: OK (603978947)
+*** Test   7: OK (90563)
+*** Test   8: OK (562493431)
+*** Test   9: OK (363)
+*** Test  10: OK (559615)
+*** Test  11: OK (2049)
+*** Test  12: OK (352256)
+*** Test  13: OK (145)
+*** Test  14: OK (42413)
+*** Test  15: OK (42413)
+*** Test  16: OK (8722)
+*** Test  17: OK (285127993)
+*** Test  18: OK (67224583)
+*** Test  19: OK (69275973)
+*** Test  20: OK (1874575085)
+*** Test  21: OK (147932225)
+*** Test  22: OK (4161)
+*** Test  23: OK (49)
+*** Test  24: OK (41)
+*** Test  25: OK (260177811)
+*** Test  26: OK (1681500476)
+*** Test  27: OK (1996459)
+*** Test  28: OK (1996459)
+*** Test  29: OK (170428555)
+*** Test  30: OK (190905173)
+*** Test  31: OK (190905173)
+*** Test  32: OK (354833067)
+--- Test  33: sum = 178275600 (ok)
+*** Test  33: OK (1216907538)
+*** Test  34: OK (2146584868)
+*** Test  35: OK (2146584868)
+*** Test  36: OK (1071644672)
+*** Test  37: OK (1071644672)
+*** Test  38: OK (357908480)
+*** Test  39: OK (357908480)
+*** Test  40: OK (357908480)
+*** Test  41: OK (3076095)
+*** Test  42: OK (1505155949)
+*** Test  43: OK (1157763329)
+*** Test  44: OK (1031761407)
+*** Test  45: OK (1157763329)
+*** Test  46: OK (739407)
+*** Test  47: OK (371213935)
+*** Test  48: OK (756255461)
+*** Test  49: OK (179000669)
+*** Test  50: OK (363550045)
+*** Test  51: OK (40744667)
+*** Test  52: OK (1247112011)
+*** Test  53: OK (131071)
+*** Test  54: OK (2047)
+*** Test  55: OK (1023)
+*** Test  56: OK (511)
+*** Test  57: OK (2147450880)
+*** Test  58: OK (624945)
+*** Test  59: OK (2038431743)
+*** Test  60: OK (311511339)
+*** Test  61: OK (374889517)
+*** Test  62: OK (286331153)
+*** Test  63: OK (236978127)
+*** Test  64: OK (1499645335)
+*** Test  65: OK (70187)
+*** Test  66: OK (5464)
+*** Test  67: OK (212514423)
+*** Test  68: OK (212514423)
+*** Test  69: OK (8995471)
+*** Test  70: OK (69544277)
+*** Test  71: OK (34886997)
+*** Test  72: OK (1789569365)
+*** Test  73: OK (9032615)
+*** Test  74: OK (224907669)
+*** Test  75: OK (2000403408)
+*** Test  76: OK (1610087935)
+*** Test  77: OK (1388671)
+*** Test  78: OK (134217728)
+*** Test  79: OK (70288929)
+*** Test  80: OK (17895765)
+*** Test  81: OK (387)
+*** Test  82: OK (8454401)
+*** Test  83: OK (2835)
+*** Test  84: OK (934782101)
+*** Test  85: OK (198689)
+--- Test  86: All tests were run with throwing exceptions on error.
+	      The $VIMNOERRTHROW control is not configured.
+--- Test  86: All tests were run with throwing exceptions on interrupt.
+	      The $VIMNOINTTHROW control is not configured.
+*** Test  86: OK (50443995)
--- /dev/null
+++ b/testdir/test49.vim
@@ -1,0 +1,9802 @@
+" Vim script language tests
+" Author:	Servatius Brandt <Servatius.Brandt@fujitsu-siemens.com>
+" Last Change:	2006 Apr 28
+
+"-------------------------------------------------------------------------------
+" Test environment							    {{{1
+"-------------------------------------------------------------------------------
+
+
+" Adding new tests easily.						    {{{2
+"
+" Writing new tests is eased considerably with the following functions and
+" abbreviations (see "Commands for recording the execution path", "Automatic
+" argument generation").
+"
+" To get the abbreviations, execute the command
+"
+"    :let test49_set_env = 1 | source test49.vim
+"
+" To get them always (from src/testdir), put a line
+"
+"    au! BufRead test49.vim let test49_set_env = 1 | source test49.vim
+"
+" into the local .vimrc file in the src/testdir directory.
+"
+if exists("test49_set_env") && test49_set_env
+
+    " Automatic argument generation for the test environment commands.
+
+    function! Xsum()
+	let addend = substitute(getline("."), '^.*"\s*X:\s*\|^.*', '', "")
+	" Evaluate arithmetic expression.
+	if addend != ""
+	    exec "let g:Xsum = g:Xsum + " . addend
+	endif
+    endfunction
+
+    function! Xcheck()
+	let g:Xsum=0
+	?XpathINIT?,.call Xsum()
+	exec "norm A "
+	return g:Xsum
+    endfunction
+
+    iab Xcheck Xcheck<Space><C-R>=Xcheck()<CR><C-O>x
+
+    function! Xcomment(num)
+	let str = ""
+	let tabwidth = &sts ? &sts : &ts
+	let tabs = (48+tabwidth - a:num - virtcol(".")) / tabwidth
+	while tabs > 0
+	    let str = str . "\t"
+	    let tabs = tabs - 1
+	endwhile
+	let str = str . '" X:'
+	return str
+    endfunction
+
+    function! Xloop()
+	let back = line(".") . "|norm" . virtcol(".") . "|"
+	norm 0
+	let last = search('X\(loop\|path\)INIT\|Xloop\>', "bW")
+	exec back
+	let theline = getline(last)
+	if theline =~ 'X\(loop\|path\)INIT'
+	    let num = 1
+	else
+	    let num = 2 * substitute(theline, '.*Xloop\s*\(\d\+\).*', '\1', "")
+	endif
+	?X\(loop\|path\)INIT?
+	    \s/\(XloopINIT!\=\s*\d\+\s\+\)\@<=\(\d\+\)/\=2*submatch(2)/
+	exec back
+	exec "norm a "
+	return num . Xcomment(strlen(num))
+    endfunction
+
+    iab Xloop Xloop<Space><C-R>=Xloop()<CR><C-O>x
+
+    function! Xpath(loopinit)
+	let back = line(".") . "|norm" . virtcol(".") . "|"
+	norm 0
+	let last = search('XpathINIT\|Xpath\>\|XloopINIT', "bW")
+	exec back
+	let theline = getline(last)
+	if theline =~ 'XpathINIT'
+	    let num = 1
+	elseif theline =~ 'Xpath\>'
+	    let num = 2 * substitute(theline, '.*Xpath\s*\(\d\+\).*', '\1', "")
+	else
+	    let pattern = '.*XloopINIT!\=\s*\(\d\+\)\s*\(\d\+\).*'
+	    let num = substitute(theline, pattern, '\1', "")
+	    let factor = substitute(theline, pattern, '\2', "")
+	    " The "<C-O>x" from the "Xpath" iab and the character triggering its
+	    " expansion are in the input buffer.  Save and clear typeahead so
+	    " that it is not read away by the call to "input()" below.  Restore
+	    " afterwards.
+	    call inputsave()
+	    let loops = input("Number of iterations in previous loop? ")
+	    call inputrestore()
+	    while (loops > 0)
+		let num = num * factor
+		let loops = loops - 1
+	    endwhile
+	endif
+	exec "norm a "
+	if a:loopinit
+	    return num . " 1"
+	endif
+	return num . Xcomment(strlen(num))
+    endfunction
+
+    iab Xpath Xpath<Space><C-R>=Xpath(0)<CR><C-O>x
+    iab XloopINIT XloopINIT<Space><C-R>=Xpath(1)<CR><C-O>x
+
+    " Also useful (see ExtraVim below):
+    aug ExtraVim
+	au!
+	au  BufEnter <sfile> syn region ExtraVim
+		    \ start=+^if\s\+ExtraVim(.*)+ end=+^endif+
+		    \ transparent keepend
+	au  BufEnter <sfile> syn match ExtraComment /^"/
+		    \ contained containedin=ExtraVim
+	au  BufEnter <sfile> hi link ExtraComment vimComment
+    aug END
+
+    aug Xpath
+	au  BufEnter <sfile> syn keyword Xpath
+		    \ XpathINIT Xpath XloopINIT Xloop XloopNEXT Xcheck Xout
+	au  BufEnter <sfile> hi link Xpath Special
+    aug END
+
+    do BufEnter <sfile>
+
+    " Do not execute the tests when sourcing this file for getting the functions
+    " and abbreviations above, which are intended for easily adding new test
+    " cases; they are not needed for test execution.  Unlet the variable
+    " controlling this so that an explicit ":source" command for this file will
+    " execute the tests.
+    unlet test49_set_env
+    finish
+
+endif
+
+
+" Commands for recording the execution path.				    {{{2
+"
+" The Xpath/Xloop commands can be used for computing the eXecution path by
+" adding (different) powers of 2 from those script lines, for which the
+" execution should be checked.  Xloop provides different addends for each
+" execution of a loop.  Permitted values are 2^0 to 2^30, so that 31 execution
+" points (multiply counted inside loops) can be tested.
+"
+" Note that the arguments of the following commands can be generated
+" automatically, see below.
+"
+" Usage:								    {{{3
+"
+"   - Use XpathINIT at the beginning of the test.
+"
+"   - Use Xpath to check if a line is executed.
+"     Argument: power of 2 (decimal).
+"
+"   - To check multiple execution of loops use Xloop for automatically
+"     computing Xpath values:
+"
+"	- Use XloopINIT before the loop.
+"	  Two arguments:
+"		- the first Xpath value (power of 2) to be used (Xnext),
+"		- factor for computing a new Xnext value when reexecuting a loop
+"		  (by a ":continue" or ":endwhile"); this should be 2^n where
+"		  n is the number of Xloop commands inside the loop.
+"	  If XloopINIT! is used, the first execution of XloopNEXT is
+"	  a no-operation.
+"
+"       - Use Xloop inside the loop:
+"	  One argument:
+"		The argument and the Xnext value are multiplied to build the
+"		next Xpath value.  No new Xnext value is prepared.  The argument
+"		should be 2^(n-1) for the nth Xloop command inside the loop.
+"		If the loop has only one Xloop command, the argument can be
+"		ommitted (default: 1).
+"
+"	- Use XloopNEXT before ":continue" and ":endwhile".  This computes a new
+"	  Xnext value for the next execution of the loop by multiplying the old
+"	  one with the factor specified in the XloopINIT command.  No Argument.
+"	  Alternatively, when XloopINIT! is used, a single XloopNEXT at the
+"	  beginning of the loop can be used.
+"
+"     Nested loops are not supported.
+"
+"   - Use Xcheck at end of each test.  It prints the test number, the expected
+"     execution path value, the test result ("OK" or "FAIL"), and, if the tests
+"     fails, the actual execution path.
+"     One argument:
+"	    Expected Xpath/Xloop sum for the correct execution path.
+"	    In order that this value can be computed automatically, do the
+"	    following: For each line in the test with an Xpath and Xloop
+"	    command, add a comment starting with "X:" and specifying an
+"	    expression that evaluates to the value contributed by this line to
+"	    the correct execution path.  (For copying an Xpath argument of at
+"	    least two digits into the comment, press <C-P>.)  At the end of the
+"	    test, just type "Xcheck" and press <Esc>.
+"
+"   - In order to add additional information to the test output file, use the
+"     Xout command.  Argument(s) like ":echo".
+"
+" Automatic argument generation:					    {{{3
+"
+"   The arguments of the Xpath, XloopINIT, Xloop, and Xcheck commands can be
+"   generated automatically, so that new tests can easily be written without
+"   mental arithmetic.  The Xcheck argument is computed from the "X:" comments
+"   of the preceding Xpath and Xloop commands.  See the commands and
+"   abbreviations at the beginning of this file.
+"
+" Implementation:							    {{{3
+"     XpathINIT, Xpath, XloopINIT, Xloop, XloopNEXT, Xcheck, Xout.
+"
+" The variants for existing g:ExtraVimResult are needed when executing a script
+" in an extra Vim process, see ExtraVim below.
+
+" EXTRA_VIM_START - do not change or remove this line.
+
+com!		    XpathINIT	let g:Xpath = 0
+
+if exists("g:ExtraVimResult")
+    com! -count -bar    Xpath	exec "!echo <count> >>" . g:ExtraVimResult
+else
+    com! -count -bar    Xpath	let g:Xpath = g:Xpath + <count>
+endif
+
+com! -count -nargs=1 -bang
+		  \ XloopINIT	let g:Xnext = <count> |
+				    \ let g:Xfactor = <args> |
+				    \ let g:Xskip = strlen("<bang>")
+
+if exists("g:ExtraVimResult")
+    com! -count=1 -bar  Xloop	exec "!echo " . (g:Xnext * <count>) . " >>" .
+				    \ g:ExtraVimResult
+else
+    com! -count=1 -bar  Xloop	let g:Xpath = g:Xpath + g:Xnext * <count>
+endif
+
+com!		    XloopNEXT	let g:Xnext = g:Xnext *
+				    \ (g:Xskip ? 1 : g:Xfactor) |
+				    \ let g:Xskip = 0
+
+let @r = ""
+let Xtest = 1
+com! -count	    Xcheck	let Xresult = "*** Test " .
+				    \ (Xtest<10?"  ":Xtest<100?" ":"") .
+				    \ Xtest . ": " . (
+				    \ (Xpath==<count>) ? "OK (".Xpath.")" :
+					\ "FAIL (".Xpath." instead of <count>)"
+				    \ ) |
+				    \ let @R = Xresult . "\n" |
+				    \ echo Xresult |
+				    \ let Xtest = Xtest + 1
+
+if exists("g:ExtraVimResult")
+    com! -nargs=+    Xoutq	exec "!echo @R:'" .
+				    \ substitute(substitute(<q-args>,
+				    \ "'", '&\\&&', "g"), "\n", "@NL@", "g")
+				    \ . "' >>" . g:ExtraVimResult
+else
+    com! -nargs=+    Xoutq	let @R = "--- Test " .
+				    \ (g:Xtest<10?"  ":g:Xtest<100?" ":"") .
+				    \ g:Xtest . ": " . substitute(<q-args>,
+				    \ "\n", "&\t      ", "g") . "\n"
+endif
+com! -nargs=+	    Xout	exec 'Xoutq' <args>
+
+" Switch off storing of lines for undoing changes.  Speeds things up a little.
+set undolevels=-1
+
+" EXTRA_VIM_STOP - do not change or remove this line.
+
+
+" ExtraVim() - Run a script file in an extra Vim process.		    {{{2
+"
+" This is useful for testing immediate abortion of the script processing due to
+" an error in a command dynamically enclosed by a :try/:tryend region or when an
+" exception is thrown but not caught or when an interrupt occurs.  It can also
+" be used for testing :finish.
+"
+" An interrupt location can be specified by an "INTERRUPT" comment.  A number
+" telling how often this location is reached (in a loop or in several function
+" calls) should be specified as argument.  When missing, once per script
+" invocation or function call is assumed.  INTERRUPT locations are tested by
+" setting a breakpoint in that line and using the ">quit" debug command when
+" the breakpoint is reached.  A function for which an INTERRUPT location is
+" specified must be defined before calling it (or executing it as a script by
+" using ExecAsScript below).
+"
+" This function is only called in normal modus ("g:ExtraVimResult" undefined).
+"
+" Tests to be executed as an extra script should be written as follows:
+"
+"	column 1			column 1
+"	|				|
+"	v				v
+"
+"	XpathINIT			XpathINIT
+"	if ExtraVim()			if ExtraVim()
+"	    ...				"   ...
+"	    ...				"   ...
+"	endif				endif
+"	Xcheck <number>			Xcheck <number>
+"
+" Double quotes in column 1 are removed before the script is executed.
+" They should be used if the test has unbalanced conditionals (:if/:endif,
+" :while:/endwhile, :try/:endtry) or for a line with a syntax error.  The
+" extra script may use Xpath, XloopINIT, Xloop, XloopNEXT, and Xout as usual.
+"
+" A file name may be specified as argument.  All messages of the extra Vim
+" process are then redirected to the file.  An existing file is overwritten.
+"
+let ExtraVimCount = 0
+let ExtraVimBase = expand("<sfile>")
+let ExtraVimTestEnv = ""
+"
+function! ExtraVim(...)
+    " Count how often this function is called.
+    let g:ExtraVimCount = g:ExtraVimCount + 1
+
+    " Disable folds to prevent that the ranges in the ":write" commands below
+    " are extended up to the end of a closed fold.  This also speeds things up
+    " considerably.
+    set nofoldenable
+
+    " Open a buffer for this test script and copy the test environment to
+    " a temporary file.  Take account of parts relevant for the extra script
+    " execution only.
+    let current_buffnr = bufnr("%")
+    execute "view +1" g:ExtraVimBase
+    if g:ExtraVimCount == 1
+	let g:ExtraVimTestEnv = tempname()
+	execute "/E" . "XTRA_VIM_START/+,/E" . "XTRA_VIM_STOP/-w"
+		    \ g:ExtraVimTestEnv "|']+"
+	execute "/E" . "XTRA_VIM_START/+,/E" . "XTRA_VIM_STOP/-w >>"
+		    \ g:ExtraVimTestEnv "|']+"
+	execute "/E" . "XTRA_VIM_START/+,/E" . "XTRA_VIM_STOP/-w >>"
+		    \ g:ExtraVimTestEnv "|']+"
+	execute "/E" . "XTRA_VIM_START/+,/E" . "XTRA_VIM_STOP/-w >>"
+		    \ g:ExtraVimTestEnv "|']+"
+    endif
+
+    " Start the extra Vim script with a ":source" command for the test
+    " environment.  The source line number where the extra script will be
+    " appended, needs to be passed as variable "ExtraVimBegin" to the script.
+    let extra_script = tempname()
+    exec "!echo 'source " . g:ExtraVimTestEnv . "' >" . extra_script
+    let extra_begin = 1
+
+    " Starting behind the test environment, skip over the first g:ExtraVimCount
+    " occurrences of "if ExtraVim()" and copy the following lines up to the
+    " matching "endif" to the extra Vim script.
+    execute "/E" . "ND_OF_TEST_ENVIRONMENT/"
+    exec 'norm ' . g:ExtraVimCount . '/^\s*if\s\+ExtraVim(.*)/+' . "\n"
+    execute ".,/^endif/-write >>" . extra_script
+
+    " Open a buffer for the extra Vim script, delete all ^", and write the
+    " script if was actually modified.
+    execute "edit +" . (extra_begin + 1) extra_script
+    ,$s/^"//e
+    update
+
+    " Count the INTERRUPTs and build the breakpoint and quit commands.
+    let breakpoints = ""
+    let debug_quits = ""
+    let in_func = 0
+    exec extra_begin
+    while search(
+	    \ '"\s*INTERRUPT\h\@!\|^\s*fu\%[nction]\>!\=\s*\%(\u\|s:\)\w*\s*(\|'
+	    \ . '^\s*\\\|^\s*endf\%[unction]\>\|'
+	    \ . '\%(^\s*fu\%[nction]!\=\s*\)\@<!\%(\u\|s:\)\w*\s*(\|'
+	    \ . 'ExecAsScript\s\+\%(\u\|s:\)\w*',
+	    \ "W") > 0
+	let theline = getline(".")
+	if theline =~ '^\s*fu'
+	    " Function definition.
+	    let in_func = 1
+	    let func_start = line(".")
+	    let func_name = substitute(theline,
+		\ '^\s*fu\%[nction]!\=\s*\(\%(\u\|s:\)\w*\).*', '\1', "")
+	elseif theline =~ '^\s*endf'
+	    " End of function definition.
+	    let in_func = 0
+	else
+	    let finding = substitute(theline, '.*\(\%' . col(".") . 'c.*\)',
+		\ '\1', "")
+	    if finding =~ '^"\s*INTERRUPT\h\@!'
+		" Interrupt comment.  Compose as many quit commands as
+		" specified.
+		let cnt = substitute(finding,
+		    \ '^"\s*INTERRUPT\s*\(\d*\).*$', '\1', "")
+		let quits = ""
+		while cnt > 0
+		    " Use "\r" rather than "\n" to separate the quit commands.
+		    " "\r" is not interpreted as command separator by the ":!"
+		    " command below but works to separate commands in the
+		    " external vim.
+		    let quits = quits . "q\r"
+		    let cnt = cnt - 1
+		endwhile
+		if in_func
+		    " Add the function breakpoint and note the number of quits
+		    " to be used, if specified, or one for every call else.
+		    let breakpoints = breakpoints . " -c 'breakadd func " .
+			\ (line(".") - func_start) . " " .
+			\ func_name . "'"
+		    if quits != ""
+			let debug_quits = debug_quits . quits
+		    elseif !exists("quits{func_name}")
+			let quits{func_name} = "q\r"
+		    else
+			let quits{func_name} = quits{func_name} . "q\r"
+		    endif
+		else
+		    " Add the file breakpoint and the quits to be used for it.
+		    let breakpoints = breakpoints . " -c 'breakadd file " .
+			\ line(".") . " " . extra_script . "'"
+		    if quits == ""
+			let quits = "q\r"
+		    endif
+		    let debug_quits = debug_quits . quits
+		endif
+	    else
+		" Add the quits to be used for calling the function or executing
+		" it as script file.
+		if finding =~ '^ExecAsScript'
+		    " Sourcing function as script.
+		    let finding = substitute(finding,
+			\ '^ExecAsScript\s\+\(\%(\u\|s:\)\w*\).*', '\1', "")
+		else
+		    " Function call.
+		    let finding = substitute(finding,
+			\ '^\(\%(\u\|s:\)\w*\).*', '\1', "")
+		endif
+		if exists("quits{finding}")
+		    let debug_quits = debug_quits . quits{finding}
+		endif
+	    endif
+	endif
+    endwhile
+
+    " Close the buffer for the script and create an (empty) resultfile.
+    bwipeout
+    let resultfile = tempname()
+    exec "!>" . resultfile
+
+    " Run the script in an extra vim.  Switch to extra modus by passing the
+    " resultfile in ExtraVimResult.  Redirect messages to the file specified as
+    " argument if any.  Use ":debuggreedy" so that the commands provided on the
+    " pipe are consumed at the debug prompt.  Use "-N" to enable command-line
+    " continuation ("C" in 'cpo').  Add "nviminfo" to 'viminfo' to avoid
+    " messing up the user's viminfo file.
+    let redirect = a:0 ?
+	\ " -c 'au VimLeave * redir END' -c 'redir\\! >" . a:1 . "'" : ""
+    exec "!echo '" . debug_quits . "q' | ../vim -u NONE -N -Xes" . redirect .
+	\ " -c 'debuggreedy|set viminfo+=nviminfo'" .
+	\ " -c 'let ExtraVimBegin = " . extra_begin . "'" .
+	\ " -c 'let ExtraVimResult = \"" . resultfile . "\"'" . breakpoints .
+	\ " -S " . extra_script
+
+    " Build the resulting sum for resultfile and add it to g:Xpath.  Add Xout
+    " information provided by the extra Vim process to the test output.
+    let sum = 0
+    exec "edit" resultfile
+    let line = 1
+    while line <= line("$")
+	let theline = getline(line)
+	if theline =~ '^@R:'
+	    exec 'Xout "' . substitute(substitute(
+		\ escape(escape(theline, '"'), '\"'),
+		\ '^@R:', '', ""), '@NL@', "\n", "g") . '"'
+	else
+	    let sum = sum + getline(line)
+	endif
+	let line = line + 1
+    endwhile
+    bwipeout
+    let g:Xpath = g:Xpath + sum
+
+    " Delete the extra script and the resultfile.
+    call delete(extra_script)
+    call delete(resultfile)
+
+    " Switch back to the buffer that was active when this function was entered.
+    exec "buffer" current_buffnr
+
+    " Return 0.  This protects extra scripts from being run in the main Vim
+    " process.
+    return 0
+endfunction
+
+
+" ExtraVimThrowpoint() - Relative throwpoint in ExtraVim script		    {{{2
+"
+" Evaluates v:throwpoint and returns the throwpoint relative to the beginning of
+" an ExtraVim script as passed by ExtraVim() in ExtraVimBegin.
+"
+" EXTRA_VIM_START - do not change or remove this line.
+function! ExtraVimThrowpoint()
+    if !exists("g:ExtraVimBegin")
+	Xout "ExtraVimThrowpoint() used outside ExtraVim() script."
+	return v:throwpoint
+    endif
+
+    if v:throwpoint =~ '^function\>'
+	return v:throwpoint
+    endif
+
+    return "line " .
+	\ (substitute(v:throwpoint, '.*, line ', '', "") - g:ExtraVimBegin) .
+	\ " of ExtraVim() script"
+endfunction
+" EXTRA_VIM_STOP - do not change or remove this line.
+
+
+" MakeScript() - Make a script file from a function.			    {{{2
+"
+" Create a script that consists of the body of the function a:funcname.
+" Replace any ":return" by a ":finish", any argument variable by a global
+" variable, and and every ":call" by a ":source" for the next following argument
+" in the variable argument list.  This function is useful if similar tests are
+" to be made for a ":return" from a function call or a ":finish" in a script
+" file.
+"
+" In order to execute a function specifying an INTERRUPT location (see ExtraVim)
+" as a script file, use ExecAsScript below.
+"
+" EXTRA_VIM_START - do not change or remove this line.
+function! MakeScript(funcname, ...)
+    let script = tempname()
+    execute "redir! >" . script
+    execute "function" a:funcname
+    redir END
+    execute "edit" script
+    " Delete the "function" and the "endfunction" lines.  Do not include the
+    " word "function" in the pattern since it might be translated if LANG is
+    " set.  When MakeScript() is being debugged, this deletes also the debugging
+    " output of its line 3 and 4.
+    exec '1,/.*' . a:funcname . '(.*)/d'
+    /^\d*\s*endfunction\>/,$d
+    %s/^\d*//e
+    %s/return/finish/e
+    %s/\<a:\(\h\w*\)/g:\1/ge
+    normal gg0
+    let cnt = 0
+    while search('\<call\s*\%(\u\|s:\)\w*\s*(.*)', 'W') > 0
+	let cnt = cnt + 1
+	s/\<call\s*\%(\u\|s:\)\w*\s*(.*)/\='source ' . a:{cnt}/
+    endwhile
+    g/^\s*$/d
+    write
+    bwipeout
+    return script
+endfunction
+" EXTRA_VIM_STOP - do not change or remove this line.
+
+
+" ExecAsScript - Source a temporary script made from a function.	    {{{2
+"
+" Make a temporary script file from the function a:funcname, ":source" it, and
+" delete it afterwards.
+"
+" When inside ":if ExtraVim()", add a file breakpoint for each INTERRUPT
+" location specified in the function.
+"
+" EXTRA_VIM_START - do not change or remove this line.
+function! ExecAsScript(funcname)
+    " Make a script from the function passed as argument.
+    let script = MakeScript(a:funcname)
+
+    " When running in an extra Vim process, add a file breakpoint for each
+    " function breakpoint set when the extra Vim process was invoked by
+    " ExtraVim().
+    if exists("g:ExtraVimResult")
+	let bplist = tempname()
+	execute "redir! >" . bplist
+	breaklist
+	redir END
+	execute "edit" bplist
+	" Get the line number from the function breakpoint.  Works also when
+	" LANG is set.
+	execute 'v/^\s*\d\+\s\+func\s\+' . a:funcname . '\s.*/d'
+	%s/^\s*\d\+\s\+func\s\+\%(\u\|s:\)\w*\s\D*\(\d*\).*/\1/e
+	let cnt = 0
+	while cnt < line("$")
+	    let cnt = cnt + 1
+	    if getline(cnt) != ""
+		execute "breakadd file" getline(cnt) script
+	    endif
+	endwhile
+	bwipeout!
+	call delete(bplist)
+    endif
+
+    " Source and delete the script.
+    exec "source" script
+    call delete(script)
+endfunction
+
+com! -nargs=1 -bar ExecAsScript call ExecAsScript(<f-args>)
+" EXTRA_VIM_STOP - do not change or remove this line.
+
+
+" END_OF_TEST_ENVIRONMENT - do not change or remove this line.
+
+
+"-------------------------------------------------------------------------------
+" Test 1:   :endwhile in function					    {{{1
+"
+"	    Detect if a broken loop is (incorrectly) reactivated by the
+"	    :endwhile.  Use a :return to prevent an endless loop, and make
+"	    this test first to get a meaningful result on an error before other
+"	    tests will hang.
+"-------------------------------------------------------------------------------
+
+XpathINIT
+
+function! F()
+    Xpath 1					" X: 1
+    let first = 1
+    XloopINIT 2 8
+    while 1
+	Xloop 1					" X: 2	    + 0 * 16
+	if first
+	    Xloop 2				" X: 4	    + 0 * 32
+	    let first = 0
+	    XloopNEXT
+	    break
+	else
+	    Xloop 4				" X: 0	    + 0 * 64
+	    return
+	endif
+    endwhile
+endfunction
+
+call F()
+Xpath 128					" X: 128
+
+function! G()
+    Xpath 256					" X: 256    + 0 * 2048
+    let first = 1
+    XloopINIT 512 8
+    while 1
+	Xloop 1					" X: 512    + 0 * 4096
+	if first
+	    Xloop 2				" X: 1024   + 0 * 8192
+	    let first = 0
+	    XloopNEXT
+	    break
+	else
+	    Xloop 4				" X: 0	    + 0 * 16384
+	    return
+	endif
+	if 1	" unmatched :if
+    endwhile
+endfunction
+
+call G()
+Xpath 32768					" X: 32768
+
+Xcheck 34695
+
+" Leave F and G for execution as scripts in the next test.
+
+
+"-------------------------------------------------------------------------------
+" Test 2:   :endwhile in script						    {{{1
+"
+"	    Detect if a broken loop is (incorrectly) reactivated by the
+"	    :endwhile.  Use a :finish to prevent an endless loop, and place
+"	    this test before others that might hang to get a meaningful result
+"	    on an error.
+"
+"	    This test executes the bodies of the functions F and G from the
+"	    previous test as script files (:return replaced by :finish).
+"-------------------------------------------------------------------------------
+
+XpathINIT
+
+ExecAsScript F					" X: 1 + 2 + 4
+Xpath 128					" X: 128
+
+ExecAsScript G					" X: 256 + 512 + 1024
+Xpath 32768					" X: 32768
+
+unlet first
+delfunction F
+delfunction G
+
+Xcheck 34695
+
+
+"-------------------------------------------------------------------------------
+" Test 3:   :if, :elseif, :while, :continue, :break			    {{{1
+"-------------------------------------------------------------------------------
+
+XpathINIT
+if 1
+    Xpath 1					" X: 1
+    let loops = 3
+    XloopINIT 2 512
+    while loops > -1	    " main loop: loops == 3, 2, 1 (which breaks)
+	if loops <= 0
+	    let break_err = 1
+	    let loops = -1
+	else					"    3:  2:      1:
+	    Xloop 1				" X: 2 + 2*512 + 2*512*512
+	endif
+	if (loops == 2)
+	    while loops == 2 " dummy loop
+		Xloop 2				" X:     4*512
+		let loops = loops - 1
+		continue    " stop dummy loop
+		Xloop 4				" X:     0
+	    endwhile
+	    XloopNEXT
+	    continue	    " continue main loop
+	    Xloop 8				" X:     0
+	elseif (loops == 1)
+	    let p = 1
+	    while p	    " dummy loop
+		Xloop 16			" X:		 32*512*512
+		let p = 0
+		break	    " break dummy loop
+		Xloop 32			" X:		 0
+	    endwhile
+	    Xloop 64				" X:		 128*512*512
+	    unlet p
+	    break	    " break main loop
+	    Xloop 128				" X:		 0
+	endif
+	if (loops > 0)
+	    Xloop 256				" X: 512
+	endif
+	while loops == 3    " dummy loop
+	    let loops = loops - 1
+	endwhile	    " end dummy loop
+	XloopNEXT
+    endwhile		    " end main loop
+    Xpath 268435456				" X: 1024*512*512
+else
+    Xpath 536870912				" X: 0
+endif
+Xpath 1073741824				" X: 4096*512*512
+if exists("break_err")
+    " The Xpath command does not accept 2^31 (negative); add explicitly:
+    let Xpath = Xpath + 2147483648		" X: 0
+    unlet break_err
+endif
+
+unlet loops
+
+Xcheck 1384648195
+
+
+"-------------------------------------------------------------------------------
+" Test 4:   :return							    {{{1
+"-------------------------------------------------------------------------------
+
+XpathINIT
+
+function! F()
+    if 1
+	Xpath 1					" X: 1
+	let loops = 3
+	XloopINIT 2 16
+	while loops > 0				"    3:  2:     1:
+	    Xloop 1				" X: 2 + 2*16 + 0*16*16
+	    if (loops == 2)
+		Xloop 2				" X:     4*16
+		return
+		Xloop 4				" X:     0
+	    endif
+	    Xloop 8				" X: 16
+	    let loops = loops - 1
+	    XloopNEXT
+	endwhile
+	Xpath 8192				" X: 0
+    else
+	Xpath 16384				" X: 0
+    endif
+endfunction
+
+call F()
+Xpath 32768					" X: 8*16*16*16
+
+Xcheck 32883
+
+" Leave F for execution as a script in the next test.
+
+
+"-------------------------------------------------------------------------------
+" Test 5:   :finish							    {{{1
+"
+"	    This test executes the body of the function F from the previous test
+"	    as a script file (:return replaced by :finish).
+"-------------------------------------------------------------------------------
+
+XpathINIT
+
+ExecAsScript F					" X: 1 + 2 + 2*16 + 4*16 + 16
+Xpath 32768					" X: 32768
+
+unlet loops
+delfunction F
+
+Xcheck 32883
+
+
+"-------------------------------------------------------------------------------
+" Test 6:   Defining functions in :while loops				    {{{1
+"
+"	     Functions can be defined inside other functions.  An inner function
+"	     gets defined when the outer function is executed.  Functions may
+"	     also be defined inside while loops.  Expressions in braces for
+"	     defining the function name are allowed.
+"-------------------------------------------------------------------------------
+
+XpathINIT
+
+if ExtraVim()
+
+    " The command CALL collects the argument of all its invocations in "calls"
+    " when used from a function (that is, when the global variable "calls" needs
+    " the "g:" prefix).  This is to check that the function code is skipped when
+    " the function is defined.  For inner functions, do so only if the outer
+    " function is not being executed.
+    "
+    let calls = ""
+    com! -nargs=1 CALL
+		\ if !exists("calls") && !exists("outer") |
+		\ let g:calls = g:calls . <args> |
+		\ endif
+
+
+    XloopINIT! 1 16
+
+    let i = 0
+    while i < 3
+
+	XloopNEXT
+	let i = i + 1
+
+	if i == 1
+	    Xloop 1				" X: 1
+	    function! F1(arg)
+		CALL a:arg
+		let outer = 1
+
+		XloopINIT! 4096 4
+		let j = 0
+		while j < 1
+		    XloopNEXT
+		    Xloop 1			" X: 4096
+		    let j = j + 1
+		    function! G1(arg)
+			CALL a:arg
+		    endfunction
+		    Xloop 2			" X: 8192
+		endwhile
+	    endfunction
+	    Xloop 2				" X: 2
+
+	    continue
+	endif
+
+	Xloop 4					" X: 4 * (16 + 256)
+	function! F{i}(i, arg)
+	    CALL a:arg
+	    let outer = 1
+
+	    XloopINIT! 16384 4
+	    if a:i == 3
+		XloopNEXT
+		XloopNEXT
+		XloopNEXT
+	    endif
+	    let k = 0
+	    while k < 3
+		XloopNEXT
+		Xloop 1				" X: 16384*(1+4+16+64+256+1024)
+		let k = k + 1
+		function! G{a:i}{k}(arg)
+		    CALL a:arg
+		endfunction
+		Xloop 2				" X: 32768*(1+4+16+64+256+1024)
+	    endwhile
+	endfunction
+	Xloop 8					" X: 8 * (16 + 256)
+
+    endwhile
+
+    if exists("*G1")
+	Xpath 67108864				" X: 0
+    endif
+    if exists("*F1")
+	call F1("F1")
+	if exists("*G1")
+	    call G1("G1")
+	endif
+    endif
+
+    if exists("G21") || exists("G21") || exists("G21")
+	Xpath 134217728				" X: 0
+    endif
+    if exists("*F2")
+	call F2(2, "F2")
+	if exists("*G21")
+	    call G21("G21")
+	endif
+	if exists("*G22")
+	    call G22("G22")
+	endif
+	if exists("*G23")
+	    call G23("G23")
+	endif
+    endif
+
+    if exists("G31") || exists("G31") || exists("G31")
+	Xpath 268435456				" X: 0
+    endif
+    if exists("*F3")
+	call F3(3, "F3")
+	if exists("*G31")
+	    call G31("G31")
+	endif
+	if exists("*G32")
+	    call G32("G32")
+	endif
+	if exists("*G33")
+	    call G33("G33")
+	endif
+    endif
+
+    Xpath 536870912				" X: 536870912
+
+    if calls != "F1G1F2G21G22G23F3G31G32G33"
+	Xpath 1073741824			" X: 0
+	Xout "calls is" calls
+    endif
+
+    delfunction F1
+    delfunction G1
+    delfunction F2
+    delfunction G21
+    delfunction G22
+    delfunction G23
+    delfunction G31
+    delfunction G32
+    delfunction G33
+
+endif
+
+Xcheck 603978947
+
+
+"-------------------------------------------------------------------------------
+" Test 7:   Continuing on errors outside functions			    {{{1
+"
+"	    On an error outside a function, the script processing continues
+"	    at the line following the outermost :endif or :endwhile.  When not
+"	    inside an :if or :while, the script processing continues at the next
+"	    line.
+"-------------------------------------------------------------------------------
+
+XpathINIT
+
+if 1
+    Xpath 1					" X: 1
+    while 1
+	Xpath 2					" X: 2
+	asdf
+	Xpath 4					" X: 0
+	break
+    endwhile | Xpath 8				" X: 0
+    Xpath 16					" X: 0
+endif | Xpath 32				" X: 0
+Xpath 64					" X: 64
+
+while 1
+    Xpath 128					" X: 128
+    if 1
+	Xpath 256				" X: 256
+	asdf
+	Xpath 512				" X: 0
+    endif | Xpath 1024				" X: 0
+    Xpath 2048					" X: 0
+    break
+endwhile | Xpath 4096				" X: 0
+Xpath 8192					" X: 8192
+
+asdf
+Xpath 16384					" X: 16384
+
+asdf | Xpath 32768				" X: 0
+Xpath 65536					" X: 65536
+
+Xcheck 90563
+
+
+"-------------------------------------------------------------------------------
+" Test 8:   Aborting and continuing on errors inside functions		    {{{1
+"
+"	    On an error inside a function without the "abort" attribute, the
+"	    script processing continues at the next line (unless the error was
+"	    in a :return command).  On an error inside a function with the
+"	    "abort" attribute, the function is aborted and the script processing
+"	    continues after the function call; the value -1 is returned then.
+"-------------------------------------------------------------------------------
+
+XpathINIT
+
+function! F()
+    if 1
+	Xpath 1					" X: 1
+	while 1
+	    Xpath 2				" X: 2
+	    asdf
+	    Xpath 4				" X: 4
+	    asdf | Xpath 8			" X: 0
+	    Xpath 16				" X: 16
+	    break
+	endwhile
+	Xpath 32				" X: 32
+    endif | Xpath 64				" X: 64
+    Xpath 128					" X: 128
+
+    while 1
+	Xpath 256				" X: 256
+	if 1
+	    Xpath 512				" X: 512
+	    asdf
+	    Xpath 1024				" X: 1024
+	    asdf | Xpath 2048			" X: 0
+	    Xpath 4096				" X: 4096
+	endif
+	Xpath 8192				" X: 8192
+	break
+    endwhile | Xpath 16384			" X: 16384
+    Xpath 32768					" X: 32768
+
+    return novar		" returns (default return value 0)
+    Xpath 65536					" X: 0
+    return 1			" not reached
+endfunction
+
+function! G() abort
+    if 1
+	Xpath 131072				" X: 131072
+	while 1
+	    Xpath 262144			" X: 262144
+	    asdf		" returns -1
+	    Xpath 524288			" X: 0
+	    break
+	endwhile
+	Xpath 1048576				" X: 0
+    endif | Xpath 2097152			" X: 0
+    Xpath Xpath 4194304				" X: 0
+
+    return -4			" not reached
+endfunction
+
+function! H() abort
+    while 1
+	Xpath 8388608				" X: 8388608
+	if 1
+	    Xpath 16777216			" X: 16777216
+	    asdf		" returns -1
+	    Xpath 33554432			" X: 0
+	endif
+	Xpath 67108864				" X: 0
+	break
+    endwhile | Xpath 134217728			" X: 0
+    Xpath 268435456				" X: 0
+
+    return -4			" not reached
+endfunction
+
+" Aborted functions (G and H) return -1.
+let sum = (F() + 1) - 4*G() - 8*H()
+Xpath 536870912					" X: 536870912
+if sum != 13
+    Xpath 1073741824				" X: 0
+    Xout "sum is" sum
+endif
+
+unlet sum
+delfunction F
+delfunction G
+delfunction H
+
+Xcheck 562493431
+
+
+"-------------------------------------------------------------------------------
+" Test 9:   Continuing after aborted functions				    {{{1
+"
+"	    When a function with the "abort" attribute is aborted due to an
+"	    error, the next function back in the call hierarchy without an
+"	    "abort" attribute continues; the value -1 is returned then.
+"-------------------------------------------------------------------------------
+
+XpathINIT
+
+function! F() abort
+    Xpath 1					" X: 1
+    let result = G()	" not aborted
+    Xpath 2					" X: 2
+    if result != 2
+	Xpath 4					" X: 0
+    endif
+    return 1
+endfunction
+
+function! G()		" no abort attribute
+    Xpath 8					" X: 8
+    if H() != -1	" aborted
+	Xpath 16				" X: 0
+    endif
+    Xpath 32					" X: 32
+    return 2
+endfunction
+
+function! H() abort
+    Xpath 64					" X: 64
+    call I()		" aborted
+    Xpath 128					" X: 0
+    return 4
+endfunction
+
+function! I() abort
+    Xpath 256					" X: 256
+    asdf		" error
+    Xpath 512					" X: 0
+    return 8
+endfunction
+
+if F() != 1
+    Xpath 1024					" X: 0
+endif
+
+delfunction F
+delfunction G
+delfunction H
+delfunction I
+
+Xcheck 363
+
+
+"-------------------------------------------------------------------------------
+" Test 10:  :if, :elseif, :while argument parsing			    {{{1
+"
+"	    A '"' or '|' in an argument expression must not be mixed up with
+"	    a comment or a next command after a bar.  Parsing errors should
+"	    be recognized.
+"-------------------------------------------------------------------------------
+
+XpathINIT
+
+function! MSG(enr, emsg)
+    let english = v:lang == "C" || v:lang =~ '^[Ee]n'
+    if a:enr == ""
+	Xout "TODO: Add message number for:" a:emsg
+	let v:errmsg = ":" . v:errmsg
+    endif
+    let match = 1
+    if v:errmsg !~ '^'.a:enr.':' || (english && v:errmsg !~ a:emsg)
+	let match = 0
+	if v:errmsg == ""
+	    Xout "Message missing."
+	else
+	    let v:errmsg = escape(v:errmsg, '"')
+	    Xout "Unexpected message:" v:errmsg
+	endif
+    endif
+    return match
+endfunction
+
+if 1 || strlen("\"") | Xpath 1			" X: 1
+    Xpath 2					" X: 2
+endif
+Xpath 4						" X: 4
+
+if 0
+elseif 1 || strlen("\"") | Xpath 8		" X: 8
+    Xpath 16					" X: 16
+endif
+Xpath 32					" X: 32
+
+while 1 || strlen("\"") | Xpath 64		" X: 64
+    Xpath 128					" X: 128
+    break
+endwhile
+Xpath 256					" X: 256
+
+let v:errmsg = ""
+if 1 ||| strlen("\"") | Xpath 512		" X: 0
+    Xpath 1024					" X: 0
+endif
+Xpath 2048					" X: 2048
+if !MSG('E15', "Invalid expression")
+    Xpath 4096					" X: 0
+endif
+
+let v:errmsg = ""
+if 0
+elseif 1 ||| strlen("\"") | Xpath 8192		" X: 0
+    Xpath 16384					" X: 0
+endif
+Xpath 32768					" X: 32768
+if !MSG('E15', "Invalid expression")
+    Xpath 65536					" X: 0
+endif
+
+let v:errmsg = ""
+while 1 ||| strlen("\"") | Xpath 131072		" X: 0
+    Xpath 262144				" X: 0
+    break
+endwhile
+Xpath 524288					" X: 524288
+if !MSG('E15', "Invalid expression")
+    Xpath 1048576				" X: 0
+endif
+
+delfunction MSG
+
+Xcheck 559615
+
+
+"-------------------------------------------------------------------------------
+" Test 11:  :if, :elseif, :while argument evaluation after abort	    {{{1
+"
+"	    When code is skipped over due to an error, the boolean argument to
+"	    an :if, :elseif, or :while must not be evaluated.
+"-------------------------------------------------------------------------------
+
+XpathINIT
+
+let calls = 0
+
+function! P(num)
+    let g:calls = g:calls + a:num   " side effect on call
+    return 0
+endfunction
+
+if 1
+    Xpath 1					" X: 1
+    asdf		" error
+    Xpath 2					" X: 0
+    if P(1)		" should not be called
+	Xpath 4					" X: 0
+    elseif !P(2)	" should not be called
+	Xpath 8					" X: 0
+    else
+	Xpath 16				" X: 0
+    endif
+    Xpath 32					" X: 0
+    while P(4)		" should not be called
+	Xpath 64				" X: 0
+    endwhile
+    Xpath 128					" X: 0
+endif
+
+if calls % 2
+    Xpath 256					" X: 0
+endif
+if (calls/2) % 2
+    Xpath 512					" X: 0
+endif
+if (calls/4) % 2
+    Xpath 1024					" X: 0
+endif
+Xpath 2048					" X: 2048
+
+unlet calls
+delfunction P
+
+Xcheck 2049
+
+
+"-------------------------------------------------------------------------------
+" Test 12:  Expressions in braces in skipped code			    {{{1
+"
+"	    In code skipped over due to an error or inactive conditional,
+"	    an expression in braces as part of a variable or function name
+"	    should not be evaluated.
+"-------------------------------------------------------------------------------
+
+XpathINIT
+
+XloopINIT 1 8
+
+function! NULL()
+    Xloop 1					" X: 0
+    return 0
+endfunction
+
+function! ZERO()
+    Xloop 2					" X: 0
+    return 0
+endfunction
+
+function! F0()
+    Xloop 4					" X: 0
+endfunction
+
+function! F1(arg)
+    Xpath 4096					" X: 0
+endfunction
+
+let V0 = 1
+
+Xpath 8192					" X: 8192
+echo 0 ? F{NULL() + V{ZERO()}}() : 1
+XloopNEXT
+
+Xpath 16384					" X: 16384
+if 0
+    Xpath 32768					" X: 0
+    call F{NULL() + V{ZERO()}}()
+endif
+XloopNEXT
+
+Xpath 65536					" X: 65536
+if 1
+    asdf		" error
+    Xpath 131072				" X: 0
+    call F1(F{NULL() + V{ZERO()}}())
+endif
+XloopNEXT
+
+Xpath 262144					" X: 262144
+if 1
+    asdf		" error
+    Xpath 524288				" X: 0
+    call F{NULL() + V{ZERO()}}()
+endif
+
+Xcheck 352256
+
+
+"-------------------------------------------------------------------------------
+" Test 13:  Failure in argument evaluation for :while			    {{{1
+"
+"	    A failure in the expression evaluation for the condition of a :while
+"	    causes the whole :while loop until the matching :endwhile being
+"	    ignored.  Continuation is at the next following line.
+"-------------------------------------------------------------------------------
+
+XpathINIT
+
+Xpath 1						" X: 1
+while asdf
+    Xpath 2					" X: 0
+    while 1
+	Xpath 4					" X: 0
+	break
+    endwhile
+    Xpath 8					" X: 0
+    break
+endwhile
+Xpath 16					" X: 16
+
+while asdf | Xpath 32 | endwhile | Xpath 64	" X: 0
+Xpath 128					" X: 128
+
+Xcheck 145
+
+
+"-------------------------------------------------------------------------------
+" Test 14:  Failure in argument evaluation for :if			    {{{1
+"
+"	    A failure in the expression evaluation for the condition of an :if
+"	    does not cause the corresponding :else or :endif being matched to
+"	    a previous :if/:elseif.  Neither of both branches of the failed :if
+"	    are executed.
+"-------------------------------------------------------------------------------
+
+XpathINIT
+XloopINIT 1 256
+
+function! F()
+    Xloop 1					" X: 1	    + 256 * 1
+    let x = 0
+    if x		" false
+	Xloop 2					" X: 0	    + 256 * 0
+    elseif !x		" always true
+	Xloop 4					" X: 4	    + 256 * 4
+	let x = 1
+	if g:boolvar	" possibly undefined
+	    Xloop 8				" X: 8	    + 256 * 0
+	else
+	    Xloop 16				" X: 0	    + 256 * 0
+	endif
+	Xloop 32				" X: 32	    + 256 * 32
+    elseif x		" never executed
+	Xloop 64				" X: 0	    + 256 * 0
+    endif
+    Xloop 128					" X: 128    + 256 * 128
+endfunction
+
+let boolvar = 1
+call F()
+
+XloopNEXT
+unlet boolvar
+call F()
+
+delfunction F
+
+Xcheck 42413
+
+
+"-------------------------------------------------------------------------------
+" Test 15:  Failure in argument evaluation for :if (bar)		    {{{1
+"
+"	    Like previous test, except that the failing :if ... | ... | :endif
+"	    is in a single line.
+"-------------------------------------------------------------------------------
+
+XpathINIT
+XloopINIT 1 256
+
+function! F()
+    Xloop 1					" X: 1	    + 256 * 1
+    let x = 0
+    if x		" false
+	Xloop 2					" X: 0	    + 256 * 0
+    elseif !x		" always true
+	Xloop 4					" X: 4	    + 256 * 4
+	let x = 1
+	if g:boolvar | Xloop 8 | else | Xloop 16 | endif    " X: 8
+	Xloop 32				" X: 32	    + 256 * 32
+    elseif x		" never executed
+	Xloop 64				" X: 0	    + 256 * 0
+    endif
+    Xloop 128					" X: 128    + 256 * 128
+endfunction
+
+let boolvar = 1
+call F()
+
+XloopNEXT
+unlet boolvar
+call F()
+
+delfunction F
+
+Xcheck 42413
+
+
+"-------------------------------------------------------------------------------
+" Test 16:  Double :else or :elseif after :else				    {{{1
+"
+"	    Multiple :elses or an :elseif after an :else are forbidden.
+"-------------------------------------------------------------------------------
+
+XpathINIT
+
+function! F() abort
+    if 0
+	Xpath 1					" X: 0
+    else
+	Xpath 2					" X: 2
+    else		" aborts function
+	Xpath 4					" X: 0
+    endif
+endfunction
+
+function! G() abort
+    if 0
+	Xpath 8					" X: 0
+    else
+	Xpath 16				" X: 16
+    elseif 1		" aborts function
+	Xpath 32				" X: 0
+    else
+	Xpath 64				" X: 0
+    endif
+endfunction
+
+function! H() abort
+    if 0
+	Xpath 128				" X: 0
+    elseif 0
+	Xpath 256				" X: 0
+    else
+	Xpath 512				" X: 512
+    else		" aborts function
+	Xpath 1024				" X: 0
+    endif
+endfunction
+
+function! I() abort
+    if 0
+	Xpath 2048				" X: 0
+    elseif 0
+	Xpath 4096				" X: 0
+    else
+	Xpath 8192				" X: 8192
+    elseif 1		" aborts function
+	Xpath 16384				" X: 0
+    else
+	Xpath 32768				" X: 0
+    endif
+endfunction
+
+call F()
+call G()
+call H()
+call I()
+
+delfunction F
+delfunction G
+delfunction H
+delfunction I
+
+Xcheck 8722
+
+
+"-------------------------------------------------------------------------------
+" Test 17:  Nesting of unmatched :if or :endif inside a :while		    {{{1
+"
+"	    The :while/:endwhile takes precedence in nesting over an unclosed
+"	    :if or an unopened :endif.
+"-------------------------------------------------------------------------------
+
+XpathINIT
+
+function! MSG(enr, emsg)
+    let english = v:lang == "C" || v:lang =~ '^[Ee]n'
+    if a:enr == ""
+	Xout "TODO: Add message number for:" a:emsg
+	let v:errmsg = ":" . v:errmsg
+    endif
+    let match = 1
+    if v:errmsg !~ '^'.a:enr.':' || (english && v:errmsg !~ a:emsg)
+	let match = 0
+	if v:errmsg == ""
+	    Xout "Message missing."
+	else
+	    let v:errmsg = escape(v:errmsg, '"')
+	    Xout "Unexpected message:" v:errmsg
+	endif
+    endif
+    return match
+endfunction
+
+let messages = ""
+
+" While loops inside a function are continued on error.
+function! F()
+    let v:errmsg = ""
+    XloopINIT 1 16
+    let loops = 3
+    while loops > 0
+	let loops = loops - 1			"    2:  1:     0:
+	Xloop 1					" X: 1 + 1*16 + 1*16*16
+	if (loops == 1)
+	    Xloop 2				" X:     2*16
+	    XloopNEXT
+	    continue
+	elseif (loops == 0)
+	    Xloop 4				" X:		4*16*16
+	    break
+	elseif 1
+	    Xloop 8				" X: 8
+	    XloopNEXT
+	" endif missing!
+    endwhile	" :endwhile after :if 1
+    Xpath 4096					" X: 16*16*16
+    if MSG('E171', "Missing :endif")
+	let g:messages = g:messages . "A"
+    endif
+
+    let v:errmsg = ""
+    XloopINIT! 8192 4
+    let loops = 2
+    while loops > 0				"    2:     1:
+	XloopNEXT
+	let loops = loops - 1
+	Xloop 1					" X: 8192 + 8192*4
+	if 0
+	    Xloop 2				" X: 0
+	" endif missing
+    endwhile	" :endwhile after :if 0
+    Xpath 131072				" X: 8192*4*4
+    if MSG('E171', "Missing :endif")
+	let g:messages = g:messages . "B"
+    endif
+
+    let v:errmsg = ""
+    XloopINIT 262144 4
+    let loops = 2
+    while loops > 0				"    2:     1:
+	let loops = loops - 1
+	Xloop 1					" X: 262144 + 262144 * 4
+	" if missing!
+	endif	" :endif without :if in while
+	Xloop 2					" X: 524288 + 524288 * 4
+	XloopNEXT
+    endwhile
+    Xpath 4194304				" X: 262144*4*4
+    if MSG('E580', ":endif without :if")
+	let g:messages = g:messages . "C"
+    endif
+endfunction
+
+call F()
+
+" Error continuation outside a function is at the outermost :endwhile or :endif.
+let v:errmsg = ""
+XloopINIT! 8388608 4
+let loops = 2
+while loops > 0					"    2:		1:
+    XloopNEXT
+    let loops = loops - 1
+    Xloop 1					" X: 8388608 + 0 * 4
+    if 0
+	Xloop 2					" X: 0
+    " endif missing! Following :endwhile fails.
+endwhile | Xpath 134217728			" X: 0
+Xpath 268435456					" X: 2*8388608*4*4
+if MSG('E171', "Missing :endif")
+    let messages = g:messages . "D"
+endif
+
+if messages != "ABCD"
+    Xpath 536870912				" X: 0
+    Xout "messages is" messages "instead of ABCD"
+endif
+
+unlet loops messages
+delfunction F
+delfunction MSG
+
+Xcheck 285127993
+
+
+"-------------------------------------------------------------------------------
+" Test 18:  Interrupt (Ctrl-C pressed)					    {{{1
+"
+"	    On an interrupt, the script processing is terminated immediately.
+"-------------------------------------------------------------------------------
+
+XpathINIT
+
+if ExtraVim()
+    if 1
+	Xpath 1					" X: 1
+	while 1
+	    Xpath 2				" X: 2
+	    if 1
+		Xpath 4				" X: 4
+		"INTERRUPT
+		Xpath 8				" X: 0
+		break
+		finish
+	    endif | Xpath 16			" X: 0
+	    Xpath 32				" X: 0
+	endwhile | Xpath 64			" X: 0
+	Xpath 128				" X: 0
+    endif | Xpath 256				" X: 0
+    Xpath 512					" X: 0
+endif
+
+if ExtraVim()
+    try
+	Xpath 1024				" X: 1024
+	"INTERRUPT
+	Xpath 2048				" X: 0
+    endtry | Xpath 4096				" X: 0
+    Xpath 8192					" X: 0
+endif
+
+if ExtraVim()
+    function! F()
+	if 1
+	    Xpath 16384				" X: 16384
+	    while 1
+		Xpath 32768			" X: 32768
+		if 1
+		    Xpath 65536			" X: 65536
+		    "INTERRUPT
+		    Xpath 131072		" X: 0
+		    break
+		    return
+		endif | Xpath 262144		" X: 0
+		Xpath Xpath 524288		" X: 0
+	    endwhile | Xpath 1048576		" X: 0
+	    Xpath Xpath 2097152			" X: 0
+	endif | Xpath Xpath 4194304		" X: 0
+	Xpath Xpath 8388608			" X: 0
+    endfunction
+
+    call F() | Xpath 16777216			" X: 0
+    Xpath 33554432				" X: 0
+endif
+
+if ExtraVim()
+    function! G()
+	try
+	    Xpath 67108864			" X: 67108864
+	    "INTERRUPT
+	    Xpath 134217728			" X: 0
+	endtry | Xpath 268435456		" X: 0
+	Xpath 536870912				" X: 0
+    endfunction
+
+    call G() | Xpath 1073741824			" X: 0
+    " The Xpath command does not accept 2^31 (negative); display explicitly:
+    exec "!echo 2147483648 >>" . g:ExtraVimResult
+						" X: 0
+endif
+
+Xcheck 67224583
+
+
+"-------------------------------------------------------------------------------
+" Test 19:  Aborting on errors inside :try/:endtry			    {{{1
+"
+"	    An error in a command dynamically enclosed in a :try/:endtry region
+"	    aborts script processing immediately.  It does not matter whether
+"	    the failing command is outside or inside a function and whether a
+"	    function has an "abort" attribute.
+"-------------------------------------------------------------------------------
+
+XpathINIT
+
+if ExtraVim()
+    function! F() abort
+	Xpath 1					" X: 1
+	asdf
+	Xpath 2					" X: 0
+    endfunction
+
+    try
+	Xpath 4					" X: 4
+	call F()
+	Xpath 8					" X: 0
+    endtry | Xpath 16				" X: 0
+    Xpath 32					" X: 0
+endif
+
+if ExtraVim()
+    function! G()
+	Xpath 64				" X: 64
+	asdf
+	Xpath 128				" X: 0
+    endfunction
+
+    try
+	Xpath 256				" X: 256
+	call G()
+	Xpath 512				" X: 0
+    endtry | Xpath 1024				" X: 0
+    Xpath 2048					" X: 0
+endif
+
+if ExtraVim()
+    try
+	Xpath 4096				" X: 4096
+	asdf
+	Xpath 8192				" X: 0
+    endtry | Xpath 16384			" X: 0
+    Xpath 32768					" X: 0
+endif
+
+if ExtraVim()
+    if 1
+	try
+	    Xpath 65536				" X: 65536
+	    asdf
+	    Xpath 131072			" X: 0
+	endtry | Xpath 262144			" X: 0
+    endif | Xpath 524288			" X: 0
+    Xpath 1048576				" X: 0
+endif
+
+if ExtraVim()
+    let p = 1
+    while p
+	let p = 0
+	try
+	    Xpath 2097152			" X: 2097152
+	    asdf
+	    Xpath 4194304			" X: 0
+	endtry | Xpath 8388608			" X: 0
+    endwhile | Xpath 16777216			" X: 0
+    Xpath 33554432				" X: 0
+endif
+
+if ExtraVim()
+    let p = 1
+    while p
+	let p = 0
+"	try
+	    Xpath 67108864			" X: 67108864
+    endwhile | Xpath 134217728			" X: 0
+    Xpath 268435456				" X: 0
+endif
+
+Xcheck 69275973
+"-------------------------------------------------------------------------------
+" Test 20:  Aborting on errors after :try/:endtry			    {{{1
+"
+"	    When an error occurs after the last active :try/:endtry region has
+"	    been left, termination behavior is as if no :try/:endtry has been
+"	    seen.
+"-------------------------------------------------------------------------------
+
+XpathINIT
+
+if ExtraVim()
+    let p = 1
+    while p
+	let p = 0
+	try
+	    Xpath 1				" X: 1
+	endtry
+	asdf
+    endwhile | Xpath 2				" X: 0
+    Xpath 4					" X: 4
+endif
+
+if ExtraVim()
+    while 1
+	try
+	    Xpath 8				" X: 8
+	    break
+	    Xpath 16				" X: 0
+	endtry
+    endwhile
+    Xpath 32					" X: 32
+    asdf
+    Xpath 64					" X: 64
+endif
+
+if ExtraVim()
+    while 1
+	try
+	    Xpath 128				" X: 128
+	    break
+	    Xpath 256				" X: 0
+	finally
+	    Xpath 512				" X: 512
+	endtry
+    endwhile
+    Xpath 1024					" X: 1024
+    asdf
+    Xpath 2048					" X: 2048
+endif
+
+if ExtraVim()
+    while 1
+	try
+	    Xpath 4096				" X: 4096
+	finally
+	    Xpath 8192				" X: 8192
+	    break
+	    Xpath 16384				" X: 0
+	endtry
+    endwhile
+    Xpath 32768					" X: 32768
+    asdf
+    Xpath 65536					" X: 65536
+endif
+
+if ExtraVim()
+    let p = 1
+    while p
+	let p = 0
+	try
+	    Xpath 131072			" X: 131072
+	    continue
+	    Xpath 262144			" X: 0
+	endtry
+    endwhile
+    Xpath 524288				" X: 524288
+    asdf
+    Xpath 1048576				" X: 1048576
+endif
+
+if ExtraVim()
+    let p = 1
+    while p
+	let p = 0
+	try
+	    Xpath 2097152			" X: 2097152
+	    continue
+	    Xpath 4194304			" X: 0
+	finally
+	    Xpath 8388608			" X: 8388608
+	endtry
+    endwhile
+    Xpath 16777216				" X: 16777216
+    asdf
+    Xpath 33554432				" X: 33554432
+endif
+
+if ExtraVim()
+    let p = 1
+    while p
+	let p = 0
+	try
+	    Xpath 67108864			" X: 67108864
+	finally
+	    Xpath 134217728			" X: 134217728
+	    continue
+	    Xpath 268435456			" X: 0
+	endtry
+    endwhile
+    Xpath 536870912				" X: 536870912
+    asdf
+    Xpath 1073741824				" X: 1073741824
+endif
+
+Xcheck 1874575085
+
+
+"-------------------------------------------------------------------------------
+" Test 21:  :finally for :try after :continue/:break/:return/:finish	    {{{1
+"
+"	    If a :try conditional stays inactive due to a preceding :continue,
+"	    :break, :return, or :finish, its :finally clause should not be
+"	    executed.
+"-------------------------------------------------------------------------------
+
+XpathINIT
+
+if ExtraVim()
+    function F()
+	let loops = 2
+	XloopINIT! 1 256
+	while loops > 0
+	    XloopNEXT
+	    let loops = loops - 1
+	    try
+		if loops == 1
+		    Xloop 1			" X: 1
+		    continue
+		    Xloop 2			" X: 0
+		elseif loops == 0
+		    Xloop 4			" X: 4*256
+		    break
+		    Xloop 8			" X: 0
+		endif
+
+		try		" inactive
+		    Xloop 16			" X: 0
+		finally
+		    Xloop 32			" X: 0
+		endtry
+	    finally
+		Xloop 64			" X: 64 + 64*256
+	    endtry
+	    Xloop 128				" X: 0
+	endwhile
+
+	try
+	    Xpath 65536				" X: 65536
+	    return
+	    Xpath 131072			" X: 0
+	    try		    " inactive
+		Xpath 262144			" X: 0
+	    finally
+		Xpath 524288			" X: 0
+	    endtry
+	finally
+	    Xpath 1048576			" X: 1048576
+	endtry
+	Xpath 2097152				" X: 0
+    endfunction
+
+    try
+	Xpath 4194304				" X: 4194304
+	call F()
+	Xpath 8388608				" X: 8388608
+	finish
+	Xpath 16777216				" X: 0
+	try		" inactive
+	    Xpath 33554432			" X: 0
+	finally
+	    Xpath 67108864			" X: 0
+	endtry
+    finally
+	Xpath 134217728				" X: 134217728
+    endtry
+    Xpath 268435456				" X: 0
+endif
+
+Xcheck 147932225
+
+
+"-------------------------------------------------------------------------------
+" Test 22:  :finally for a :try after an error/interrupt/:throw		    {{{1
+"
+"	    If a :try conditional stays inactive due to a preceding error or
+"	    interrupt or :throw, its :finally clause should not be executed.
+"-------------------------------------------------------------------------------
+
+XpathINIT
+
+if ExtraVim()
+    function! Error()
+	try
+	    asdf    " aborting error, triggering error exception
+	endtry
+    endfunction
+
+    Xpath 1					" X: 1
+    call Error()
+    Xpath 2					" X: 0
+
+    if 1	" not active due to error
+	try	" not active since :if inactive
+	    Xpath 4				" X: 0
+	finally
+	    Xpath 8				" X: 0
+	endtry
+    endif
+
+    try		" not active due to error
+	Xpath 16				" X: 0
+    finally
+	Xpath 32				" X: 0
+    endtry
+endif
+
+if ExtraVim()
+    function! Interrupt()
+	try
+	    "INTERRUPT	" triggering interrupt exception
+	endtry
+    endfunction
+
+    Xpath 64					" X: 64
+    call Interrupt()
+    Xpath 128					" X: 0
+
+    if 1	" not active due to interrupt
+	try	" not active since :if inactive
+	    Xpath 256				" X: 0
+	finally
+	    Xpath 512				" X: 0
+	endtry
+    endif
+
+    try		" not active due to interrupt
+	Xpath 1024				" X: 0
+    finally
+	Xpath 2048				" X: 0
+    endtry
+endif
+
+if ExtraVim()
+    function! Throw()
+	throw "xyz"
+    endfunction
+
+    Xpath 4096					" X: 4096
+    call Throw()
+    Xpath 8192					" X: 0
+
+    if 1	" not active due to :throw
+	try	" not active since :if inactive
+	    Xpath 16384				" X: 0
+	finally
+	    Xpath 32768				" X: 0
+	endtry
+    endif
+
+    try		" not active due to :throw
+	Xpath 65536				" X: 0
+    finally
+	Xpath 131072				" X: 0
+    endtry
+endif
+
+Xcheck 4161
+
+
+"-------------------------------------------------------------------------------
+" Test 23:  :catch clauses for a :try after a :throw			    {{{1
+"
+"	    If a :try conditional stays inactive due to a preceding :throw,
+"	    none of its :catch clauses should be executed.
+"-------------------------------------------------------------------------------
+
+XpathINIT
+
+if ExtraVim()
+    try
+	Xpath 1					" X: 1
+	throw "xyz"
+	Xpath 2					" X: 0
+
+	if 1	" not active due to :throw
+	    try	" not active since :if inactive
+		Xpath 4				" X: 0
+	    catch /xyz/
+		Xpath 8				" X: 0
+	    endtry
+	endif
+    catch /xyz/
+	Xpath 16				" X: 16
+    endtry
+
+    Xpath 32					" X: 32
+    throw "abc"
+    Xpath 64					" X: 0
+
+    try		" not active due to :throw
+	Xpath 128				" X: 0
+    catch /abc/
+	Xpath 256				" X: 0
+    endtry
+endif
+
+Xcheck 49
+
+
+"-------------------------------------------------------------------------------
+" Test 24:  :endtry for a :try after a :throw				    {{{1
+"
+"	    If a :try conditional stays inactive due to a preceding :throw,
+"	    its :endtry should not rethrow the exception to the next surrounding
+"	    active :try conditional.
+"-------------------------------------------------------------------------------
+
+XpathINIT
+
+if ExtraVim()
+    try			" try 1
+	try		" try 2
+	    Xpath 1				" X: 1
+	    throw "xyz"	" makes try 2 inactive
+	    Xpath 2				" X: 0
+
+	    try		" try 3
+		Xpath 4				" X: 0
+	    endtry	" no rethrow to try 1
+	catch /xyz/	" should catch although try 2 inactive
+	    Xpath 8				" X: 8
+	endtry
+    catch /xyz/		" try 1 active, but exception already caught
+	Xpath 16				" X: 0
+    endtry
+    Xpath 32					" X: 32
+endif
+
+Xcheck 41
+
+
+"-------------------------------------------------------------------------------
+" Test 25:  Executing :finally clauses on normal control flow		    {{{1
+"
+"	    Control flow in a :try conditional should always fall through to its
+"	    :finally clause.  A :finally clause of a :try conditional inside an
+"	    inactive conditional should never be executed.
+"-------------------------------------------------------------------------------
+
+XpathINIT
+
+function! F()
+    let loops = 3
+    XloopINIT 1 256
+    while loops > 0				"     3:   2:       1:
+	Xloop 1					" X:  1 +  1*256 + 1*256*256
+	if loops >= 2
+	    try
+		Xloop 2				" X:  2 +  2*256
+		if loops == 2
+		    try
+			Xloop 4			" X:       4*256
+		    finally
+			Xloop 8			" X:       8*256
+		    endtry
+		endif
+	    finally
+		Xloop 16			" X: 16 + 16*256
+		if loops == 2
+		    try
+			Xloop 32		" X:      32*256
+		    finally
+			Xloop 64		" X:      64*256
+		    endtry
+		endif
+	    endtry
+	endif
+	Xloop 128				" X: 128 + 128*256 + 128*256*256
+	let loops = loops - 1
+	XloopNEXT
+    endwhile
+    Xpath 16777216				" X: 16777216
+endfunction
+
+if 1
+    try
+	Xpath 33554432				" X: 33554432
+	call F()
+	Xpath 67108864				" X: 67108864
+    finally
+	Xpath 134217728				" X: 134217728
+    endtry
+else
+    try
+	Xpath 268435456				" X: 0
+    finally
+	Xpath 536870912				" X: 0
+    endtry
+endif
+
+delfunction F
+
+Xcheck 260177811
+
+
+"-------------------------------------------------------------------------------
+" Test 26:  Executing :finally clauses after :continue or :break	    {{{1
+"
+"	    For a :continue or :break dynamically enclosed in a :try/:endtry
+"	    region inside the next surrounding :while/:endwhile, if the
+"	    :continue/:break is before the :finally, the :finally clause is
+"	    executed first.  If the :continue/:break is after the :finally, the
+"	    :finally clause is broken (like an :if/:endif region).
+"-------------------------------------------------------------------------------
+
+XpathINIT
+
+try
+    let loops = 3
+    XloopINIT! 1 32
+    while loops > 0
+	XloopNEXT
+	try
+	    try
+		if loops == 2			"    3:   2:     1:
+		    Xloop 1			" X:      1*32
+		    let loops = loops - 1
+		    continue
+		elseif loops == 1
+		    Xloop 2			" X:		 2*32*32
+		    break
+		    finish
+		endif
+		Xloop 4				" X: 4
+	    endtry
+	finally
+	    Xloop 8				" X: 8  + 8*32 + 8*32*32
+	endtry
+	Xloop 16				" X: 16
+	let loops = loops - 1
+    endwhile
+    Xpath 32768					" X: 32768
+finally
+    Xpath 65536					" X: 65536
+    let loops = 3
+    XloopINIT 131072 16
+    while loops > 0
+	try
+	finally
+	    try
+		if loops == 2
+		    Xloop 1			" X: 131072*16
+		    let loops = loops - 1
+		    XloopNEXT
+		    continue
+		elseif loops == 1
+		    Xloop 2			" X: 131072*2*16*16
+		    break
+		    finish
+		endif
+	    endtry
+	    Xloop 4				" X: 131072*4
+	endtry
+	Xloop 8					" X: 131072*8
+	let loops = loops - 1
+	XloopNEXT
+    endwhile
+    Xpath 536870912				" X: 536870912
+endtry
+Xpath 1073741824				" X: 1073741824
+
+unlet loops
+
+Xcheck 1681500476
+
+
+"-------------------------------------------------------------------------------
+" Test 27:  Executing :finally clauses after :return			    {{{1
+"
+"	    For a :return command dynamically enclosed in a :try/:endtry region,
+"	    :finally clauses are executed and the called function is ended.
+"-------------------------------------------------------------------------------
+
+XpathINIT
+
+function! F()
+    try
+	Xpath 1					" X: 1
+	try
+	    Xpath 2				" X: 2
+	    return
+	    Xpath 4				" X: 0
+	finally
+	    Xpath 8				" X: 8
+	endtry
+	Xpath 16				" X: 0
+    finally
+	Xpath 32				" X: 32
+    endtry
+    Xpath 64					" X: 0
+endfunction
+
+function! G()
+    try
+	Xpath 128				" X: 128
+	return
+	Xpath 256				" X: 0
+    finally
+	Xpath 512				" X: 512
+	call F()
+	Xpath 1024				" X: 1024
+    endtry
+    Xpath 2048					" X: 0
+endfunction
+
+function! H()
+    try
+	Xpath 4096				" X: 4096
+	call G()
+	Xpath 8192				" X: 8192
+    finally
+	Xpath 16384				" X: 16384
+	return
+	Xpath 32768				" X: 0
+    endtry
+    Xpath 65536					" X: 0
+endfunction
+
+try
+    Xpath 131072				" X: 131072
+    call H()
+    Xpath 262144				" X: 262144
+finally
+    Xpath 524288				" X: 524288
+endtry
+Xpath 1048576					" X: 1048576
+
+Xcheck 1996459
+
+" Leave F, G, and H for execution as scripts in the next test.
+
+
+"-------------------------------------------------------------------------------
+" Test 28:  Executing :finally clauses after :finish			    {{{1
+"
+"	    For a :finish command dynamically enclosed in a :try/:endtry region,
+"	    :finally clauses are executed and the sourced file is finished.
+"
+"	    This test executes the bodies of the functions F, G, and H from the
+"	    previous test as script files (:return replaced by :finish).
+"-------------------------------------------------------------------------------
+
+XpathINIT
+
+let scriptF = MakeScript("F")			" X: 1 + 2 + 8 + 32
+let scriptG = MakeScript("G", scriptF)		" X: 128 + 512 + 1024
+let scriptH = MakeScript("H", scriptG)		" X: 4096 + 8192 + 16384
+
+try
+    Xpath 131072				" X: 131072
+    exec "source" scriptH
+    Xpath 262144				" X: 262144
+finally
+    Xpath 524288				" X: 524288
+endtry
+Xpath 1048576					" X: 1048576
+
+call delete(scriptF)
+call delete(scriptG)
+call delete(scriptH)
+unlet scriptF scriptG scriptH
+delfunction F
+delfunction G
+delfunction H
+
+Xcheck 1996459
+
+
+"-------------------------------------------------------------------------------
+" Test 29:  Executing :finally clauses on errors			    {{{1
+"
+"	    After an error in a command dynamically enclosed in a :try/:endtry
+"	    region, :finally clauses are executed and the script processing is
+"	    terminated.
+"-------------------------------------------------------------------------------
+
+XpathINIT
+
+if ExtraVim()
+    function! F()
+	while 1
+	    try
+		Xpath 1				" X: 1
+		while 1
+		    try
+			Xpath 2			" X: 2
+			asdf	    " error
+			Xpath 4			" X: 0
+		    finally
+			Xpath 8			" X: 8
+		    endtry | Xpath 16		" X: 0
+		    Xpath 32			" X: 0
+		    break
+		endwhile
+		Xpath 64			" X: 0
+	    finally
+		Xpath 128			" X: 128
+	    endtry | Xpath 256			" X: 0
+	    Xpath 512				" X: 0
+	    break
+	endwhile
+	Xpath 1024				" X: 0
+    endfunction
+
+    while 1
+	try
+	    Xpath 2048				" X: 2048
+	    while 1
+		call F()
+		Xpath 4096			" X: 0
+		break
+	    endwhile  | Xpath 8192		" X: 0
+	    Xpath 16384				" X: 0
+	finally
+	    Xpath 32768				" X: 32768
+	endtry | Xpath 65536			" X: 0
+    endwhile | Xpath 131072			" X: 0
+    Xpath 262144				" X: 0
+endif
+
+if ExtraVim()
+    function! G() abort
+	if 1
+	    try
+		Xpath 524288			" X: 524288
+		asdf	    " error
+		Xpath 1048576			" X: 0
+	    finally
+		Xpath 2097152			" X: 2097152
+	    endtry | Xpath 4194304		" X: 0
+	endif | Xpath 8388608			" X: 0
+	Xpath 16777216				" X: 0
+    endfunction
+
+    if 1
+	try
+	    Xpath 33554432			" X: 33554432
+	    call G()
+	    Xpath 67108864			" X: 0
+	finally
+	    Xpath 134217728			" X: 134217728
+	endtry | Xpath 268435456		" X: 0
+    endif | Xpath 536870912			" X: 0
+    Xpath 1073741824				" X: 0
+endif
+
+Xcheck 170428555
+
+
+"-------------------------------------------------------------------------------
+" Test 30:  Executing :finally clauses on interrupt			    {{{1
+"
+"	    After an interrupt in a command dynamically enclosed in
+"	    a :try/:endtry region, :finally clauses are executed and the
+"	    script processing is terminated.
+"-------------------------------------------------------------------------------
+
+XpathINIT
+
+if ExtraVim()
+    XloopINIT 1 16
+
+    function! F()
+	try
+	    Xloop 1				" X: 1 + 1*16
+	    "INTERRUPT
+	    Xloop 2				" X: 0
+	finally
+	    Xloop 4				" X: 4 + 4*16
+	endtry
+	Xloop 8					" X: 0
+    endfunction
+
+    try
+	Xpath 256				" X: 256
+	try
+	    Xpath 512				" X: 512
+	    "INTERRUPT
+	    Xpath 1024				" X: 0
+	finally
+	    Xpath 2048				" X: 2048
+	    try
+		Xpath 4096			" X: 4096
+		try
+		    Xpath 8192			" X: 8192
+		finally
+		    Xpath 16384			" X: 16384
+		    try
+			Xpath 32768		" X: 32768
+			"INTERRUPT
+			Xpath 65536		" X: 0
+		    endtry
+		    Xpath 131072		" X: 0
+		endtry
+		Xpath 262144			" X: 0
+	    endtry
+	    Xpath 524288			" X: 0
+	endtry
+	Xpath 1048576				" X: 0
+    finally
+	Xpath 2097152				" X: 2097152
+	try
+	    Xpath 4194304			" X: 4194304
+	    call F()
+	    Xpath 8388608			" X: 0
+	finally
+	    Xpath 16777216			" X: 16777216
+	    try
+		Xpath 33554432			" X: 33554432
+		XloopNEXT
+		ExecAsScript F
+		Xpath 67108864			" X: 0
+	    finally
+		Xpath 134217728			" X: 134217728
+	    endtry
+	    Xpath 268435456			" X: 0
+	endtry
+	Xpath 536870912				" X: 0
+    endtry
+    Xpath 1073741824				" X: 0
+endif
+
+Xcheck 190905173
+
+
+"-------------------------------------------------------------------------------
+" Test 31:  Executing :finally clauses after :throw			    {{{1
+"
+"	    After a :throw dynamically enclosed in a :try/:endtry region,
+"	    :finally clauses are executed and the script processing is
+"	    terminated.
+"-------------------------------------------------------------------------------
+
+XpathINIT
+
+if ExtraVim()
+    XloopINIT 1 16
+
+    function! F()
+	try
+	    Xloop 1				" X: 1 + 1*16
+	    throw "exception"
+	    Xloop 2				" X: 0
+	finally
+	    Xloop 4				" X: 4 + 4*16
+	endtry
+	Xloop 8					" X: 0
+    endfunction
+
+    try
+	Xpath 256				" X: 256
+	try
+	    Xpath 512				" X: 512
+	    throw "exception"
+	    Xpath 1024				" X: 0
+	finally
+	    Xpath 2048				" X: 2048
+	    try
+		Xpath 4096			" X: 4096
+		try
+		    Xpath 8192			" X: 8192
+		finally
+		    Xpath 16384			" X: 16384
+		    try
+			Xpath 32768		" X: 32768
+			throw "exception"
+			Xpath 65536		" X: 0
+		    endtry
+		    Xpath 131072		" X: 0
+		endtry
+		Xpath 262144			" X: 0
+	    endtry
+	    Xpath 524288			" X: 0
+	endtry
+	Xpath 1048576				" X: 0
+    finally
+	Xpath 2097152				" X: 2097152
+	try
+	    Xpath 4194304			" X: 4194304
+	    call F()
+	    Xpath 8388608			" X: 0
+	finally
+	    Xpath 16777216			" X: 16777216
+	    try
+		Xpath 33554432			" X: 33554432
+		XloopNEXT
+		ExecAsScript F
+		Xpath 67108864			" X: 0
+	    finally
+		Xpath 134217728			" X: 134217728
+	    endtry
+	    Xpath 268435456			" X: 0
+	endtry
+	Xpath 536870912				" X: 0
+    endtry
+    Xpath 1073741824				" X: 0
+endif
+
+Xcheck 190905173
+
+
+"-------------------------------------------------------------------------------
+" Test 32:  Remembering the :return value on :finally			    {{{1
+"
+"	    If a :finally clause is executed due to a :return specifying
+"	    a value, this is the value visible to the caller if not overwritten
+"	    by a new :return in the :finally clause.  A :return without a value
+"	    in the :finally clause overwrites with value 0.
+"-------------------------------------------------------------------------------
+
+XpathINIT
+
+function! F()
+    try
+	Xpath 1					" X: 1
+	try
+	    Xpath 2				" X: 2
+	    return "ABCD"
+	    Xpath 4				" X: 0
+	finally
+	    Xpath 8				" X: 8
+	endtry
+	Xpath 16				" X: 0
+    finally
+	Xpath 32				" X: 32
+    endtry
+    Xpath 64					" X: 0
+endfunction
+
+function! G()
+    try
+	Xpath 128				" X: 128
+	return 8
+	Xpath 256				" X: 0
+    finally
+	Xpath 512				" X: 512
+	return 16 + strlen(F())
+	Xpath 1024				" X: 0
+    endtry
+    Xpath 2048					" X: 0
+endfunction
+
+function! H()
+    try
+	Xpath 4096				" X: 4096
+	return 32
+	Xpath 8192				" X: 0
+    finally
+	Xpath 16384				" X: 16384
+	return
+	Xpath 32768				" X: 0
+    endtry
+    Xpath 65536					" X: 0
+endfunction
+
+function! I()
+    try
+	Xpath 131072				" X: 131072
+    finally
+	Xpath 262144				" X: 262144
+	return G() + H() + 64
+	Xpath 524288				" X: 0
+    endtry
+    Xpath 1048576				" X: 0
+endfunction
+
+let retcode = I()
+Xpath 2097152					" X: 2097152
+
+if retcode < 0
+    Xpath 4194304				" X: 0
+endif
+if retcode % 4
+    Xpath 8388608				" X: 0
+endif
+if (retcode/4) % 2
+    Xpath 16777216				" X: 16777216
+endif
+if (retcode/8) % 2
+    Xpath 33554432				" X: 0
+endif
+if (retcode/16) % 2
+    Xpath 67108864				" X: 67108864
+endif
+if (retcode/32) % 2
+    Xpath 134217728				" X: 0
+endif
+if (retcode/64) % 2
+    Xpath 268435456				" X: 268435456
+endif
+if retcode/128
+    Xpath 536870912				" X: 0
+endif
+
+unlet retcode
+delfunction F
+delfunction G
+delfunction H
+delfunction I
+
+Xcheck 354833067
+
+
+"-------------------------------------------------------------------------------
+" Test 33:  :return under :execute or user command and :finally		    {{{1
+"
+"	    A :return command may be executed under an ":execute" or from
+"	    a user command.  Executing of :finally clauses and passing through
+"	    the return code works also then.
+"-------------------------------------------------------------------------------
+XpathINIT
+
+command! -nargs=? RETURN
+    \ try | return <args> | finally | return <args> * 2 | endtry
+
+function! F()
+    try
+	RETURN 8
+	Xpath 1					" X: 0
+    finally
+	Xpath 2					" X: 2
+    endtry
+    Xpath 4					" X: 0
+endfunction
+
+function! G()
+    try
+	RETURN 32
+	Xpath 8					" X: 0
+    finally
+	Xpath 16				" X: 16
+	RETURN 128
+	Xpath 32				" X: 0
+    endtry
+    Xpath 64					" X: 0
+endfunction
+
+function! H()
+    try
+	execute "try | return 512 | finally | return 1024 | endtry"
+	Xpath 128				" X: 0
+    finally
+	Xpath 256				" X: 256
+    endtry
+    Xpath 512					" X: 0
+endfunction
+
+function! I()
+    try
+	execute "try | return 2048 | finally | return 4096 | endtry"
+	Xpath 1024				" X: 0
+    finally
+	Xpath 2048				" X: 2048
+	execute "try | return 8192 | finally | return 16384 | endtry"
+	Xpath 4096				" X: 0
+    endtry
+    Xpath 8192					" X: 0
+endfunction
+
+function! J()
+    try
+	RETURN 32768
+	Xpath 16384				" X: 0
+    finally
+	Xpath 32768				" X: 32768
+	return
+	Xpath 65536				" X: 0
+    endtry
+    Xpath 131072				" X: 0
+endfunction
+
+function! K()
+    try
+	execute "try | return 131072 | finally | return 262144 | endtry"
+	Xpath 262144				" X: 0
+    finally
+	Xpath 524288				" X: 524288
+	execute "try | return 524288 | finally | return | endtry"
+	Xpath 1048576				" X: 0
+    endtry
+    Xpath 2097152				" X: 0
+endfunction
+
+function! L()
+    try
+	return
+	Xpath 4194304				" X: 0
+    finally
+	Xpath 8388608				" X: 8388608
+	RETURN 1048576
+	Xpath 16777216				" X: 0
+    endtry
+    Xpath 33554432				" X: 0
+endfunction
+
+function! M()
+    try
+	return
+	Xpath 67108864				" X: 0
+    finally
+	Xpath 134217728				" X: 134217728
+	execute "try | return 4194304 | finally | return 8388608 | endtry"
+	Xpath 268435456				" X: 0
+    endtry
+    Xpath 536870912				" X: 0
+endfunction
+
+function! N()
+    RETURN 16777216
+endfunction
+
+function! O()
+    execute "try | return 67108864 | finally | return 134217728 | endtry"
+endfunction
+
+let sum	     = F() + G() + H()  + I()   + J() + K() + L()     + M()
+let expected = 16  + 256 + 1024 + 16384 + 0   + 0   + 2097152 + 8388608
+let sum	     = sum      + N()      + O()
+let expected = expected + 33554432 + 134217728
+
+if sum == expected
+    Xout "sum = " . sum . " (ok)"
+else
+    Xout "sum = " . sum . ", expected: " . expected
+endif
+
+Xpath 1073741824				" X: 1073741824
+
+if sum != expected
+    " The Xpath command does not accept 2^31 (negative); add explicitly:
+    let Xpath = Xpath + 2147483648		" X: 0
+endif
+
+unlet sum expected
+delfunction F
+delfunction G
+delfunction H
+delfunction I
+delfunction J
+delfunction K
+delfunction L
+delfunction M
+delfunction N
+delfunction O
+
+Xcheck 1216907538
+
+
+"-------------------------------------------------------------------------------
+" Test 34:  :finally reason discarded by :continue			    {{{1
+"
+"	    When a :finally clause is executed due to a :continue, :break,
+"	    :return, :finish, error, interrupt or :throw, the jump reason is
+"	    discarded by a :continue in the finally clause.
+"-------------------------------------------------------------------------------
+
+XpathINIT
+
+if ExtraVim()
+
+    XloopINIT! 1 8
+
+    function! C(jump)
+	XloopNEXT
+	let loop = 0
+	while loop < 2
+	    let loop = loop + 1
+	    if loop == 1
+		try
+		    if a:jump == "continue"
+			continue
+		    elseif a:jump == "break"
+			break
+		    elseif a:jump == "return" || a:jump == "finish"
+			return
+		    elseif a:jump == "error"
+			asdf
+		    elseif a:jump == "interrupt"
+			"INTERRUPT
+			let dummy = 0
+		    elseif a:jump == "throw"
+			throw "abc"
+		    endif
+		finally
+		    continue	" discards jump that caused the :finally
+		    Xloop 1		" X: 0
+		endtry
+		Xloop 2			" X: 0
+	    elseif loop == 2
+		Xloop 4			" X: 4*(1+8+64+512+4096+32768+262144)
+	    endif
+	endwhile
+    endfunction
+
+    call C("continue")
+    Xpath 2097152				" X: 2097152
+    call C("break")
+    Xpath 4194304				" X: 4194304
+    call C("return")
+    Xpath 8388608				" X: 8388608
+    let g:jump = "finish"
+    ExecAsScript C
+    unlet g:jump
+    Xpath 16777216				" X: 16777216
+    try
+	call C("error")
+	Xpath 33554432				" X: 33554432
+    finally
+	Xpath 67108864				" X: 67108864
+	try
+	    call C("interrupt")
+	    Xpath 134217728			" X: 134217728
+	finally
+	    Xpath 268435456			" X: 268435456
+	    call C("throw")
+	    Xpath 536870912			" X: 536870912
+	endtry
+    endtry
+    Xpath 1073741824				" X: 1073741824
+
+    delfunction C
+
+endif
+
+Xcheck 2146584868
+
+
+"-------------------------------------------------------------------------------
+" Test 35:  :finally reason discarded by :break				    {{{1
+"
+"	    When a :finally clause is executed due to a :continue, :break,
+"	    :return, :finish, error, interrupt or :throw, the jump reason is
+"	    discarded by a :break in the finally clause.
+"-------------------------------------------------------------------------------
+
+XpathINIT
+
+if ExtraVim()
+
+    XloopINIT! 1 8
+
+    function! B(jump)
+	XloopNEXT
+	let loop = 0
+	while loop < 2
+	    let loop = loop + 1
+	    if loop == 1
+		try
+		    if a:jump == "continue"
+			continue
+		    elseif a:jump == "break"
+			break
+		    elseif a:jump == "return" || a:jump == "finish"
+			return
+		    elseif a:jump == "error"
+			asdf
+		    elseif a:jump == "interrupt"
+			"INTERRUPT
+			let dummy = 0
+		    elseif a:jump == "throw"
+			throw "abc"
+		    endif
+		finally
+		    break	" discards jump that caused the :finally
+		    Xloop 1		" X: 0
+		endtry
+	    elseif loop == 2
+		Xloop 2			" X: 0
+	    endif
+	endwhile
+	Xloop 4				" X: 4*(1+8+64+512+4096+32768+262144)
+    endfunction
+
+    call B("continue")
+    Xpath 2097152				" X: 2097152
+    call B("break")
+    Xpath 4194304				" X: 4194304
+    call B("return")
+    Xpath 8388608				" X: 8388608
+    let g:jump = "finish"
+    ExecAsScript B
+    unlet g:jump
+    Xpath 16777216				" X: 16777216
+    try
+	call B("error")
+	Xpath 33554432				" X: 33554432
+    finally
+	Xpath 67108864				" X: 67108864
+	try
+	    call B("interrupt")
+	    Xpath 134217728			" X: 134217728
+	finally
+	    Xpath 268435456			" X: 268435456
+	    call B("throw")
+	    Xpath 536870912			" X: 536870912
+	endtry
+    endtry
+    Xpath 1073741824				" X: 1073741824
+
+    delfunction B
+
+endif
+
+Xcheck 2146584868
+
+
+"-------------------------------------------------------------------------------
+" Test 36:  :finally reason discarded by :return			    {{{1
+"
+"	    When a :finally clause is executed due to a :continue, :break,
+"	    :return, :finish, error, interrupt or :throw, the jump reason is
+"	    discarded by a :return in the finally clause.
+"-------------------------------------------------------------------------------
+
+XpathINIT
+
+if ExtraVim()
+
+    XloopINIT! 1 8
+
+    function! R(jump, retval) abort
+	XloopNEXT
+	let loop = 0
+	while loop < 2
+	    let loop = loop + 1
+	    if loop == 1
+		try
+		    if a:jump == "continue"
+			continue
+		    elseif a:jump == "break"
+			break
+		    elseif a:jump == "return"
+			return
+		    elseif a:jump == "error"
+			asdf
+		    elseif a:jump == "interrupt"
+			"INTERRUPT
+			let dummy = 0
+		    elseif a:jump == "throw"
+			throw "abc"
+		    endif
+		finally
+		    return a:retval	" discards jump that caused the :finally
+		    Xloop 1			" X: 0
+		endtry
+	    elseif loop == 2
+		Xloop 2				" X: 0
+	    endif
+	endwhile
+	Xloop 4					" X: 0
+    endfunction
+
+    let sum =  -R("continue", -8)
+    Xpath 2097152				" X: 2097152
+    let sum = sum - R("break", -16)
+    Xpath 4194304				" X: 4194304
+    let sum = sum - R("return", -32)
+    Xpath 8388608				" X: 8388608
+    try
+	let sum = sum - R("error", -64)
+	Xpath 16777216				" X: 16777216
+    finally
+	Xpath 33554432				" X: 33554432
+	try
+	    let sum = sum - R("interrupt", -128)
+	    Xpath 67108864			" X: 67108864
+	finally
+	    Xpath 134217728			" X: 134217728
+	    let sum = sum - R("throw", -256)
+	    Xpath 268435456			" X: 268435456
+	endtry
+    endtry
+    Xpath 536870912				" X: 536870912
+
+    let expected = 8 + 16 + 32 + 64 + 128 + 256
+    if sum != expected
+	Xpath 1073741824			" X: 0
+	Xout "sum =" . sum . ", expected: " . expected
+    endif
+
+    unlet sum expected
+    delfunction R
+
+endif
+
+Xcheck 1071644672
+
+
+"-------------------------------------------------------------------------------
+" Test 37:  :finally reason discarded by :finish			    {{{1
+"
+"	    When a :finally clause is executed due to a :continue, :break,
+"	    :return, :finish, error, interrupt or :throw, the jump reason is
+"	    discarded by a :finish in the finally clause.
+"-------------------------------------------------------------------------------
+
+XpathINIT
+
+if ExtraVim()
+
+    XloopINIT! 1 8
+
+    function! F(jump)	" not executed as function, transformed to a script
+	XloopNEXT
+	let loop = 0
+	while loop < 2
+	    let loop = loop + 1
+	    if loop == 1
+		try
+		    if a:jump == "continue"
+			continue
+		    elseif a:jump == "break"
+			break
+		    elseif a:jump == "finish"
+			finish
+		    elseif a:jump == "error"
+			asdf
+		    elseif a:jump == "interrupt"
+			"INTERRUPT
+			let dummy = 0
+		    elseif a:jump == "throw"
+			throw "abc"
+		    endif
+		finally
+		    finish	" discards jump that caused the :finally
+		    Xloop 1			" X: 0
+		endtry
+	    elseif loop == 2
+		Xloop 2				" X: 0
+	    endif
+	endwhile
+	Xloop 4					" X: 0
+    endfunction
+
+    let scriptF = MakeScript("F")
+    delfunction F
+
+    let g:jump = "continue"
+    exec "source" scriptF
+    Xpath 2097152				" X: 2097152
+    let g:jump = "break"
+    exec "source" scriptF
+    Xpath 4194304				" X: 4194304
+    let g:jump = "finish"
+    exec "source" scriptF
+    Xpath 8388608				" X: 8388608
+    try
+	let g:jump = "error"
+	exec "source" scriptF
+	Xpath 16777216				" X: 16777216
+    finally
+	Xpath 33554432				" X: 33554432
+	try
+	    let g:jump = "interrupt"
+	    exec "source" scriptF
+	    Xpath 67108864			" X: 67108864
+	finally
+	    Xpath 134217728			" X: 134217728
+	    try
+		let g:jump = "throw"
+		exec "source" scriptF
+		Xpath 268435456			" X: 268435456
+	    finally
+		Xpath 536870912			" X: 536870912
+	    endtry
+	endtry
+    endtry
+    unlet g:jump
+
+    call delete(scriptF)
+    unlet scriptF
+
+endif
+
+Xcheck 1071644672
+
+
+"-------------------------------------------------------------------------------
+" Test 38:  :finally reason discarded by an error			    {{{1
+"
+"	    When a :finally clause is executed due to a :continue, :break,
+"	    :return, :finish, error, interrupt or :throw, the jump reason is
+"	    discarded by an error in the finally clause.
+"-------------------------------------------------------------------------------
+
+XpathINIT
+
+if ExtraVim()
+
+    XloopINIT! 1 4
+
+    function! E(jump)
+	XloopNEXT
+	let loop = 0
+	while loop < 2
+	    let loop = loop + 1
+	    if loop == 1
+		try
+		    if a:jump == "continue"
+			continue
+		    elseif a:jump == "break"
+			break
+		    elseif a:jump == "return" || a:jump == "finish"
+			return
+		    elseif a:jump == "error"
+			asdf
+		    elseif a:jump == "interrupt"
+			"INTERRUPT
+			let dummy = 0
+		    elseif a:jump == "throw"
+			throw "abc"
+		    endif
+		finally
+		    asdf	" error; discards jump that caused the :finally
+		endtry
+	    elseif loop == 2
+		Xloop 1				" X: 0
+	    endif
+	endwhile
+	Xloop 2					" X: 0
+    endfunction
+
+    try
+	Xpath 16384				" X: 16384
+	call E("continue")
+	Xpath 32768				" X: 0
+    finally
+	try
+	    Xpath 65536				" X: 65536
+	    call E("break")
+	    Xpath 131072			" X: 0
+	finally
+	    try
+		Xpath 262144			" X: 262144
+		call E("return")
+		Xpath 524288			" X: 0
+	    finally
+		try
+		    Xpath 1048576		" X: 1048576
+		    let g:jump = "finish"
+		    ExecAsScript E
+		    Xpath 2097152		" X: 0
+		finally
+		    unlet g:jump
+		    try
+			Xpath 4194304		" X: 4194304
+			call E("error")
+			Xpath 8388608		" X: 0
+		    finally
+			try
+			    Xpath 16777216	" X: 16777216
+			    call E("interrupt")
+			    Xpath 33554432	" X: 0
+			finally
+			    try
+				Xpath 67108864	" X: 67108864
+				call E("throw")
+				Xpath 134217728	" X: 0
+			    finally
+				Xpath 268435456	" X: 268435456
+				delfunction E
+			    endtry
+			endtry
+		    endtry
+		endtry
+	    endtry
+	endtry
+    endtry
+    Xpath 536870912				" X: 0
+
+endif
+
+Xcheck 357908480
+
+
+"-------------------------------------------------------------------------------
+" Test 39:  :finally reason discarded by an interrupt			    {{{1
+"
+"	    When a :finally clause is executed due to a :continue, :break,
+"	    :return, :finish, error, interrupt or :throw, the jump reason is
+"	    discarded by an interrupt in the finally clause.
+"-------------------------------------------------------------------------------
+
+XpathINIT
+
+if ExtraVim()
+
+    XloopINIT! 1 4
+
+    function! I(jump)
+	XloopNEXT
+	let loop = 0
+	while loop < 2
+	    let loop = loop + 1
+	    if loop == 1
+		try
+		    if a:jump == "continue"
+			continue
+		    elseif a:jump == "break"
+			break
+		    elseif a:jump == "return" || a:jump == "finish"
+			return
+		    elseif a:jump == "error"
+			asdf
+		    elseif a:jump == "interrupt"
+			"INTERRUPT
+			let dummy = 0
+		    elseif a:jump == "throw"
+			throw "abc"
+		    endif
+		finally
+		    "INTERRUPT - discards jump that caused the :finally
+		    let dummy = 0
+		endtry
+	    elseif loop == 2
+		Xloop 1				" X: 0
+	    endif
+	endwhile
+	Xloop 2					" X: 0
+    endfunction
+
+    try
+	Xpath 16384				" X: 16384
+	call I("continue")
+	Xpath 32768				" X: 0
+    finally
+	try
+	    Xpath 65536				" X: 65536
+	    call I("break")
+	    Xpath 131072			" X: 0
+	finally
+	    try
+		Xpath 262144			" X: 262144
+		call I("return")
+		Xpath 524288			" X: 0
+	    finally
+		try
+		    Xpath 1048576		" X: 1048576
+		    let g:jump = "finish"
+		    ExecAsScript I
+		    Xpath 2097152		" X: 0
+		finally
+		    unlet g:jump
+		    try
+			Xpath 4194304		" X: 4194304
+			call I("error")
+			Xpath 8388608		" X: 0
+		    finally
+			try
+			    Xpath 16777216	" X: 16777216
+			    call I("interrupt")
+			    Xpath 33554432	" X: 0
+			finally
+			    try
+				Xpath 67108864	" X: 67108864
+				call I("throw")
+				Xpath 134217728	" X: 0
+			    finally
+				Xpath 268435456	" X: 268435456
+				delfunction I
+			    endtry
+			endtry
+		    endtry
+		endtry
+	    endtry
+	endtry
+    endtry
+    Xpath 536870912				" X: 0
+
+endif
+
+Xcheck 357908480
+
+
+"-------------------------------------------------------------------------------
+" Test 40:  :finally reason discarded by :throw				    {{{1
+"
+"	    When a :finally clause is executed due to a :continue, :break,
+"	    :return, :finish, error, interrupt or :throw, the jump reason is
+"	    discarded by a :throw in the finally clause.
+"-------------------------------------------------------------------------------
+
+XpathINIT
+
+if ExtraVim()
+
+    XloopINIT! 1 4
+
+    function! T(jump)
+	XloopNEXT
+	let loop = 0
+	while loop < 2
+	    let loop = loop + 1
+	    if loop == 1
+		try
+		    if a:jump == "continue"
+			continue
+		    elseif a:jump == "break"
+			break
+		    elseif a:jump == "return" || a:jump == "finish"
+			return
+		    elseif a:jump == "error"
+			asdf
+		    elseif a:jump == "interrupt"
+			"INTERRUPT
+			let dummy = 0
+		    elseif a:jump == "throw"
+			throw "abc"
+		    endif
+		finally
+		    throw "xyz"	" discards jump that caused the :finally
+		endtry
+	    elseif loop == 2
+		Xloop 1				" X: 0
+	    endif
+	endwhile
+	Xloop 2					" X: 0
+    endfunction
+
+    try
+	Xpath 16384				" X: 16384
+	call T("continue")
+	Xpath 32768				" X: 0
+    finally
+	try
+	    Xpath 65536				" X: 65536
+	    call T("break")
+	    Xpath 131072			" X: 0
+	finally
+	    try
+		Xpath 262144			" X: 262144
+		call T("return")
+		Xpath 524288			" X: 0
+	    finally
+		try
+		    Xpath 1048576		" X: 1048576
+		    let g:jump = "finish"
+		    ExecAsScript T
+		    Xpath 2097152		" X: 0
+		finally
+		    unlet g:jump
+		    try
+			Xpath 4194304		" X: 4194304
+			call T("error")
+			Xpath 8388608		" X: 0
+		    finally
+			try
+			    Xpath 16777216	" X: 16777216
+			    call T("interrupt")
+			    Xpath 33554432	" X: 0
+			finally
+			    try
+				Xpath 67108864	" X: 67108864
+				call T("throw")
+				Xpath 134217728	" X: 0
+			    finally
+				Xpath 268435456	" X: 268435456
+				delfunction T
+			    endtry
+			endtry
+		    endtry
+		endtry
+	    endtry
+	endtry
+    endtry
+    Xpath 536870912				" X: 0
+
+endif
+
+Xcheck 357908480
+
+
+"-------------------------------------------------------------------------------
+" Test 41:  Skipped :throw finding next command				    {{{1
+"
+"	    A :throw in an inactive conditional must not hide a following
+"	    command.
+"-------------------------------------------------------------------------------
+
+XpathINIT
+
+function! F()
+    Xpath 1					" X: 1
+    if 0 | throw "never" | endif | Xpath 2	" X: 2
+    Xpath 4					" X: 4
+endfunction
+
+function! G()
+    Xpath 8					    " X: 8
+    while 0 | throw "never" | endwhile | Xpath 16   " X: 16
+    Xpath 32					    " X: 32
+endfunction
+
+function H()
+    Xpath 64						    " X: 64
+    if 0 | try | throw "never" | endtry | endif | Xpath 128 " X: 128
+    Xpath 256						    " X: 256
+endfunction
+
+Xpath 512					" X: 512
+
+try
+    Xpath 1024					" X: 1024
+    call F()
+    Xpath 2048					" X: 2048
+catch /.*/
+    Xpath 4096					" X: 0
+    Xout v:exception "in" v:throwpoint
+endtry
+
+Xpath 8192					" X: 8192
+
+try
+    Xpath 16384					" X: 16384
+    call G()
+    Xpath 32768					" X: 32768
+catch /.*/
+    Xpath 65536					" X: 0
+    Xout v:exception "in" v:throwpoint
+endtry
+
+Xpath 131072					" X: 131072
+
+try
+    Xpath 262144				" X: 262144
+    call H()
+    Xpath 524288				" X: 524288
+catch /.*/
+    Xpath 1048576				" X: 0
+    Xout v:exception "in" v:throwpoint
+endtry
+
+Xpath 2097152					" X: 2097152
+
+delfunction F
+delfunction G
+delfunction H
+
+Xcheck 3076095
+
+
+"-------------------------------------------------------------------------------
+" Test 42:  Catching number and string exceptions			    {{{1
+"
+"	    When a number is thrown, it is converted to a string exception.
+"	    Numbers and strings may be caught by specifying a regular exception
+"	    as argument to the :catch command.
+"-------------------------------------------------------------------------------
+
+XpathINIT
+
+try
+
+    try
+	Xpath 1					" X: 1
+	throw 4711
+	Xpath 2					" X: 0
+    catch /4711/
+	Xpath 4					" X: 4
+    endtry
+
+    try
+	Xpath 8					" X: 8
+	throw 4711
+	Xpath 16				" X: 0
+    catch /^4711$/
+	Xpath 32				" X: 32
+    endtry
+
+    try
+	Xpath 64				" X: 64
+	throw 4711
+	Xpath 128				" X: 0
+    catch /\d/
+	Xpath 256				" X: 256
+    endtry
+
+    try
+	Xpath 512				" X: 512
+	throw 4711
+	Xpath 1024				" X: 0
+    catch /^\d\+$/
+	Xpath 2048				" X: 2048
+    endtry
+
+    try
+	Xpath 4096				" X: 4096
+	throw "arrgh"
+	Xpath 8192				" X: 0
+    catch /arrgh/
+	Xpath 16384				" X: 16384
+    endtry
+
+    try
+	Xpath 32768				" X: 32768
+	throw "arrgh"
+	Xpath 65536				" X: 0
+    catch /^arrgh$/
+	Xpath 131072				" X: 131072
+    endtry
+
+    try
+	Xpath 262144				" X: 262144
+	throw "arrgh"
+	Xpath 524288				" X: 0
+    catch /\l/
+	Xpath 1048576				" X: 1048576
+    endtry
+
+    try
+	Xpath 2097152				" X: 2097152
+	throw "arrgh"
+	Xpath 4194304				" X: 0
+    catch /^\l\+$/
+	Xpath 8388608				" X: 8388608
+    endtry
+
+    try
+	try
+	    Xpath 16777216			" X: 16777216
+	    throw "ARRGH"
+	    Xpath 33554432			" X: 0
+	catch /^arrgh$/
+	    Xpath 67108864			" X: 0
+	endtry
+    catch /^\carrgh$/
+	Xpath 134217728				" X: 134217728
+    endtry
+
+    try
+	Xpath 268435456				" X: 268435456
+	throw ""
+	Xpath 536870912				" X: 0
+    catch /^$/
+	Xpath 1073741824			" X: 1073741824
+    endtry
+
+catch /.*/
+    " The Xpath command does not accept 2^31 (negative); add explicitly:
+    let Xpath = Xpath + 2147483648		" X: 0
+    Xout v:exception "in" v:throwpoint
+endtry
+
+Xcheck 1505155949
+
+
+"-------------------------------------------------------------------------------
+" Test 43:  Selecting the correct :catch clause				    {{{1
+"
+"	    When an exception is thrown and there are multiple :catch clauses,
+"	    the first matching one is taken.
+"-------------------------------------------------------------------------------
+
+XpathINIT
+
+XloopINIT 1 1024
+let loops = 3
+while loops > 0
+    try
+	if loops == 3
+	    Xloop 1				" X: 1
+	    throw "a"
+	    Xloop 2				" X: 0
+	elseif loops == 2
+	    Xloop 4				" X: 4*1024
+	    throw "ab"
+	    Xloop 8				" X: 0
+	elseif loops == 1
+	    Xloop 16				" X: 16*1024*1024
+	    throw "abc"
+	    Xloop 32				" X: 0
+	endif
+    catch /abc/
+	Xloop 64				" X: 64*1024*1024
+    catch /ab/
+	Xloop 128				" X: 128*1024
+    catch /.*/
+	Xloop 256				" X: 256
+    catch /a/
+	Xloop 512				" X: 0
+    endtry
+
+    let loops = loops - 1
+    XloopNEXT
+endwhile
+Xpath 1073741824				" X: 1073741824
+
+unlet loops
+
+Xcheck 1157763329
+
+
+"-------------------------------------------------------------------------------
+" Test 44:  Missing or empty :catch patterns				    {{{1
+"
+"	    A missing or empty :catch pattern means the same as /.*/, that is,
+"	    catches everything.  To catch only empty exceptions, /^$/ must be
+"	    used.  A :catch with missing, empty, or /.*/ argument also works
+"	    when followed by another command separated by a bar on the same
+"	    line.  :catch patterns cannot be specified between ||.  But other
+"	    pattern separators can be used instead of //.
+"-------------------------------------------------------------------------------
+
+XpathINIT
+
+try
+    try
+	Xpath 1					" X: 1
+	throw ""
+    catch /^$/
+	Xpath 2					" X: 2
+    endtry
+
+    try
+	Xpath 4					" X: 4
+	throw ""
+    catch /.*/
+	Xpath 8					" X: 8
+    endtry
+
+    try
+	Xpath 16				" X: 16
+	throw ""
+    catch //
+	Xpath 32				" X: 32
+    endtry
+
+    try
+	Xpath 64				" X: 64
+	throw ""
+    catch
+	Xpath 128				" X: 128
+    endtry
+
+    try
+	Xpath 256				" X: 256
+	throw "oops"
+    catch /^$/
+	Xpath 512				" X: 0
+    catch /.*/
+	Xpath 1024				" X: 1024
+    endtry
+
+    try
+	Xpath 2048				" X: 2048
+	throw "arrgh"
+    catch /^$/
+	Xpath 4096				" X: 0
+    catch //
+	Xpath 8192				" X: 8192
+    endtry
+
+    try
+	Xpath 16384				" X: 16384
+	throw "brrr"
+    catch /^$/
+	Xpath 32768				" X: 0
+    catch
+	Xpath 65536				" X: 65536
+    endtry
+
+    try | Xpath 131072 | throw "x" | catch /.*/ | Xpath 262144 | endtry
+						" X: 131072 + 262144
+
+    try | Xpath 524288 | throw "y" | catch // | Xpath 1048576 | endtry
+						" X: 524288 + 1048576
+
+    while 1
+	try
+	    let caught = 0
+	    let v:errmsg = ""
+	    " Extra try level:  if ":catch" without arguments below raises
+	    " a syntax error because it misinterprets the "Xpath" as a pattern,
+	    " let it be caught by the ":catch /.*/" below.
+	    try
+		try | Xpath 2097152 | throw "z" | catch | Xpath 4194304 | :
+		endtry				" X: 2097152 + 4194304
+	    endtry
+	catch /.*/
+	    let caught = 1
+	    Xout v:exception "in" v:throwpoint
+	finally
+	    if $VIMNOERRTHROW && v:errmsg != ""
+		Xout v:errmsg
+	    endif
+	    if caught || $VIMNOERRTHROW && v:errmsg != ""
+		Xpath 8388608				" X: 0
+	    endif
+	    break		" discard error for $VIMNOERRTHROW
+	endtry
+    endwhile
+
+    let cologne = 4711
+    try
+	try
+	    Xpath 16777216			" X: 16777216
+	    throw "throw cologne"
+	" Next lines catches all and throws 4711:
+	catch |throw cologne|
+	    Xpath 33554432			" X: 0
+	endtry
+    catch /4711/
+	Xpath 67108864				" X: 67108864
+    endtry
+
+    try
+	Xpath 134217728				" X: 134217728
+	throw "plus"
+    catch +plus+
+	Xpath 268435456				" X: 268435456
+    endtry
+
+    Xpath 536870912				" X: 536870912
+catch /.*/
+    Xpath 1073741824				" X: 0
+    Xout v:exception "in" v:throwpoint
+endtry
+
+unlet! caught cologne
+
+Xcheck 1031761407
+
+
+"-------------------------------------------------------------------------------
+" Test 45:  Catching exceptions from nested :try blocks			    {{{1
+"
+"	    When :try blocks are nested, an exception is caught by the innermost
+"	    try conditional that has a matching :catch clause.
+"-------------------------------------------------------------------------------
+
+XpathINIT
+
+XloopINIT 1 1024
+let loops = 3
+while loops > 0
+    try
+	try
+	    try
+		try
+		    if loops == 3
+			Xloop 1			" X: 1
+			throw "a"
+			Xloop 2			" X: 0
+		    elseif loops == 2
+			Xloop 4			" X: 4*1024
+			throw "ab"
+			Xloop 8			" X: 0
+		    elseif loops == 1
+			Xloop 16		" X: 16*1024*1024
+			throw "abc"
+			Xloop 32		" X: 0
+		    endif
+		catch /abc/
+		    Xloop 64			" X: 64*1024*1024
+		endtry
+	    catch /ab/
+		Xloop 128			" X: 128*1024
+	    endtry
+	catch /.*/
+	    Xloop 256				" X: 256
+	endtry
+    catch /a/
+	Xloop 512				" X: 0
+    endtry
+
+    let loops = loops - 1
+    XloopNEXT
+endwhile
+Xpath 1073741824				" X: 1073741824
+
+unlet loops
+
+Xcheck 1157763329
+
+
+"-------------------------------------------------------------------------------
+" Test 46:  Executing :finally after a :throw in nested :try		    {{{1
+"
+"	    When an exception is thrown from within nested :try blocks, the
+"	    :finally clauses of the non-catching try conditionals should be
+"	    executed before the matching :catch of the next surrounding :try
+"	    gets the control.  If this also has a :finally clause, it is
+"	    executed afterwards.
+"-------------------------------------------------------------------------------
+
+XpathINIT
+
+let sum = 0
+
+try
+    Xpath 1					" X: 1
+    try
+	Xpath 2					" X: 2
+	try
+	    Xpath 4				" X: 4
+	    try
+		Xpath 8				" X: 8
+		throw "ABC"
+		Xpath 16			" X: 0
+	    catch /xyz/
+		Xpath 32			" X: 0
+	    finally
+		Xpath 64			" X: 64
+		if sum != 0
+		    Xpath 128			" X: 0
+		endif
+		let sum = sum + 1
+	    endtry
+	    Xpath 256				" X: 0
+	catch /123/
+	    Xpath 512				" X: 0
+	catch /321/
+	    Xpath 1024				" X: 0
+	finally
+	    Xpath 2048				" X: 2048
+	    if sum != 1
+		Xpath 4096			" X: 0
+	    endif
+	    let sum = sum + 2
+	endtry
+	Xpath 8192				" X: 0
+    finally
+	Xpath 16384				" X: 16384
+	if sum != 3
+	    Xpath 32768				" X: 0
+	endif
+	let sum = sum + 4
+    endtry
+    Xpath 65536					" X: 0
+catch /ABC/
+    Xpath 131072				" X: 131072
+    if sum != 7
+	Xpath 262144				" X: 0
+    endif
+    let sum = sum + 8
+finally
+    Xpath 524288				" X: 524288
+    if sum != 15
+	Xpath 1048576				" X: 0
+    endif
+    let sum = sum + 16
+endtry
+Xpath 65536					" X: 65536
+if sum != 31
+    Xpath 131072				" X: 0
+endif
+
+unlet sum
+
+Xcheck 739407
+
+
+"-------------------------------------------------------------------------------
+" Test 47:  Throwing exceptions from a :catch clause			    {{{1
+"
+"	    When an exception is thrown from a :catch clause, it should not be
+"	    caught by a :catch of the same :try conditional.  After executing
+"	    the :finally clause (if present), surrounding try conditionals
+"	    should be checked for a matching :catch.
+"-------------------------------------------------------------------------------
+
+XpathINIT
+
+Xpath 1						" X: 1
+try
+    Xpath 2					" X: 2
+    try
+	Xpath 4					" X: 4
+	try
+	    Xpath 8				" X: 8
+	    throw "x1"
+	    Xpath 16				" X: 0
+	catch /x1/
+	    Xpath 32				" X: 32
+	    try
+		Xpath 64			" X: 64
+		throw "x2"
+		Xpath 128			" X: 0
+	    catch /x1/
+		Xpath 256			" X: 0
+	    catch /x2/
+		Xpath 512			" X: 512
+		try
+		    Xpath 1024			" X: 1024
+		    throw "x3"
+		    Xpath 2048			" X: 0
+		catch /x1/
+		    Xpath 4096			" X: 0
+		catch /x2/
+		    Xpath 8192			" X: 0
+		finally
+		    Xpath 16384			" X: 16384
+		endtry
+		Xpath 32768			" X: 0
+	    catch /x3/
+		Xpath 65536			" X: 0
+	    endtry
+	    Xpath 131072			" X: 0
+	catch /x1/
+	    Xpath 262144			" X: 0
+	catch /x2/
+	    Xpath 524288			" X: 0
+	catch /x3/
+	    Xpath 1048576			" X: 0
+	finally
+	    Xpath 2097152			" X: 2097152
+	endtry
+	Xpath 4194304				" X: 0
+    catch /x1/
+	Xpath 8388608				" X: 0
+    catch /x2/
+	Xpath 16777216				" X: 0
+    catch /x3/
+	Xpath 33554432				" X: 33554432
+    endtry
+    Xpath 67108864				" X: 67108864
+catch /.*/
+    Xpath 134217728				" X: 0
+    Xout v:exception "in" v:throwpoint
+endtry
+Xpath 268435456					" X: 268435456
+
+Xcheck 371213935
+
+
+"-------------------------------------------------------------------------------
+" Test 48:  Throwing exceptions from a :finally clause			    {{{1
+"
+"	    When an exception is thrown from a :finally clause, it should not be
+"	    caught by a :catch of the same :try conditional.  Surrounding try
+"	    conditionals should be checked for a matching :catch.  A previously
+"	    thrown exception is discarded.
+"-------------------------------------------------------------------------------
+
+XpathINIT
+
+try
+
+    try
+	try
+	    Xpath 1				" X: 1
+	catch /x1/
+	    Xpath 2				" X: 0
+	finally
+	    Xpath 4				" X: 4
+	    throw "x1"
+	    Xpath 8				" X: 0
+	endtry
+	Xpath 16				" X: 0
+    catch /x1/
+	Xpath 32				" X: 32
+    endtry
+    Xpath 64					" X: 64
+
+    try
+	try
+	    Xpath 128				" X: 128
+	    throw "x2"
+	    Xpath 256				" X: 0
+	catch /x2/
+	    Xpath 512				" X: 512
+	catch /x3/
+	    Xpath 1024				" X: 0
+	finally
+	    Xpath 2048				" X: 2048
+	    throw "x3"
+	    Xpath 4096				" X: 0
+	endtry
+	Xpath 8192				" X: 0
+    catch /x2/
+	Xpath 16384				" X: 0
+    catch /x3/
+	Xpath 32768				" X: 32768
+    endtry
+    Xpath 65536					" X: 65536
+
+    try
+	try
+	    try
+		Xpath 131072			" X: 131072
+		throw "x4"
+		Xpath 262144			" X: 0
+	    catch /x5/
+		Xpath 524288			" X: 0
+	    finally
+		Xpath 1048576			" X: 1048576
+		throw "x5"	" discards "x4"
+		Xpath 2097152			" X: 0
+	    endtry
+	    Xpath 4194304			" X: 0
+	catch /x4/
+	    Xpath 8388608			" X: 0
+	finally
+	    Xpath 16777216			" X: 16777216
+	endtry
+	Xpath 33554432				" X: 0
+    catch /x5/
+	Xpath 67108864				" X: 67108864
+    endtry
+    Xpath 134217728				" X: 134217728
+
+catch /.*/
+    Xpath 268435456				" X: 0
+    Xout v:exception "in" v:throwpoint
+endtry
+Xpath 536870912					" X: 536870912
+
+Xcheck 756255461
+
+
+"-------------------------------------------------------------------------------
+" Test 49:  Throwing exceptions across functions			    {{{1
+"
+"	    When an exception is thrown but not caught inside a function, the
+"	    caller is checked for a matching :catch clause.
+"-------------------------------------------------------------------------------
+
+XpathINIT
+
+function! C()
+    try
+	Xpath 1					" X: 1
+	throw "arrgh"
+	Xpath 2					" X: 0
+    catch /arrgh/
+	Xpath 4					" X: 4
+    endtry
+    Xpath 8					" X: 8
+endfunction
+
+XloopINIT! 16 16
+
+function! T1()
+    XloopNEXT
+    try
+	Xloop 1					" X: 16 + 16*16
+	throw "arrgh"
+	Xloop 2					" X: 0
+    finally
+	Xloop 4					" X: 64 + 64*16
+    endtry
+    Xloop 8					" X: 0
+endfunction
+
+function! T2()
+    try
+	Xpath 4096				" X: 4096
+	call T1()
+	Xpath 8192				" X: 0
+    finally
+	Xpath 16384				" X: 16384
+    endtry
+    Xpath 32768					" X: 0
+endfunction
+
+try
+    Xpath 65536					" X: 65536
+    call C()	" throw and catch
+    Xpath 131072				" X: 131072
+catch /.*/
+    Xpath 262144				" X: 0
+    Xout v:exception "in" v:throwpoint
+endtry
+
+try
+    Xpath 524288				" X: 524288
+    call T1()  " throw, one level
+    Xpath 1048576				" X: 0
+catch /arrgh/
+    Xpath 2097152				" X: 2097152
+catch /.*/
+    Xpath 4194304				" X: 0
+    Xout v:exception "in" v:throwpoint
+endtry
+
+try
+    Xpath 8388608				" X: 8388608
+    call T2()	" throw, two levels
+    Xpath 16777216				" X: 0
+catch /arrgh/
+    Xpath 33554432				" X: 33554432
+catch /.*/
+    Xpath 67108864				" X: 0
+    Xout v:exception "in" v:throwpoint
+endtry
+Xpath 134217728					" X: 134217728
+
+Xcheck 179000669
+
+" Leave C, T1, and T2 for execution as scripts in the next test.
+
+
+"-------------------------------------------------------------------------------
+" Test 50:  Throwing exceptions across script files			    {{{1
+"
+"	    When an exception is thrown but not caught inside a script file,
+"	    the sourcing script or function is checked for a matching :catch
+"	    clause.
+"
+"	    This test executes the bodies of the functions C, T1, and T2 from
+"	    the previous test as script files (:return replaced by :finish).
+"-------------------------------------------------------------------------------
+
+XpathINIT
+
+let scriptC = MakeScript("C")			" X: 1 + 4 + 8
+delfunction C
+
+XloopINIT! 16 16
+
+let scriptT1 = MakeScript("T1")			" X: 16 + 64 + 16*16 + 64*16
+delfunction T1
+
+let scriptT2 = MakeScript("T2", scriptT1)	" X: 4096 + 16384
+delfunction T2
+
+function! F()
+    try
+	Xpath 65536				" X: 65536
+	exec "source" g:scriptC
+	Xpath 131072				" X: 131072
+    catch /.*/
+	Xpath 262144				" X: 0
+	Xout v:exception "in" v:throwpoint
+    endtry
+
+    try
+	Xpath 524288				" X: 524288
+	exec "source" g:scriptT1
+	Xpath 1048576				" X: 0
+    catch /arrgh/
+	Xpath 2097152				" X: 2097152
+    catch /.*/
+	Xpath 4194304				" X: 0
+	Xout v:exception "in" v:throwpoint
+    endtry
+endfunction
+
+try
+    Xpath 8388608				" X: 8388608
+    call F()
+    Xpath 16777216				" X: 16777216
+    exec "source" scriptT2
+    Xpath 33554432				" X: 0
+catch /arrgh/
+    Xpath 67108864				" X: 67108864
+catch /.*/
+    Xpath 134217728				" X: 0
+    Xout v:exception "in" v:throwpoint
+endtry
+Xpath 268435456					" X: 268435456
+
+call delete(scriptC)
+call delete(scriptT1)
+call delete(scriptT2)
+unlet scriptC scriptT1 scriptT2
+delfunction F
+
+Xcheck 363550045
+
+
+"-------------------------------------------------------------------------------
+" Test 51:  Throwing exceptions across :execute and user commands	    {{{1
+"
+"	    A :throw command may be executed under an ":execute" or from
+"	    a user command.
+"-------------------------------------------------------------------------------
+
+XpathINIT
+
+command! -nargs=? THROW1    throw <args> | throw 1
+command! -nargs=? THROW2    try | throw <args> | endtry | throw 2
+command! -nargs=? THROW3    try | throw 3 | catch /3/ | throw <args> | endtry
+command! -nargs=? THROW4    try | throw 4 | finally   | throw <args> | endtry
+
+try
+
+    try
+	try
+	    Xpath 1				" X: 1
+	    THROW1 "A"
+	catch /A/
+	    Xpath 2				" X: 2
+	endtry
+    catch /1/
+	Xpath 4					" X: 0
+    endtry
+
+    try
+	try
+	    Xpath 8				" X: 8
+	    THROW2 "B"
+	catch /B/
+	    Xpath 16				" X: 16
+	endtry
+    catch /2/
+	Xpath 32				" X: 0
+    endtry
+
+    try
+	try
+	    Xpath 64				" X: 64
+	    THROW3 "C"
+	catch /C/
+	    Xpath 128				" X: 128
+	endtry
+    catch /3/
+	Xpath 256				" X: 0
+    endtry
+
+    try
+	try
+	    Xpath 512				" X: 512
+	    THROW4 "D"
+	catch /D/
+	    Xpath 1024				" X: 1024
+	endtry
+    catch /4/
+	Xpath 2048				" X: 0
+    endtry
+
+    try
+	try
+	    Xpath 4096				" X: 4096
+	    execute 'throw "E" | throw 5'
+	catch /E/
+	    Xpath 8192				" X: 8192
+	endtry
+    catch /5/
+	Xpath 16384				" X: 0
+    endtry
+
+    try
+	try
+	    Xpath 32768				" X: 32768
+	    execute 'try | throw "F" | endtry | throw 6'
+	catch /F/
+	    Xpath 65536				" X: 65536
+	endtry
+    catch /6/
+	Xpath 131072				" X: 0
+    endtry
+
+    try
+	try
+	    Xpath 262144			" X: 262144
+	    execute'try | throw 7 | catch /7/ | throw "G" | endtry'
+	catch /G/
+	    Xpath 524288			" X: 524288
+	endtry
+    catch /7/
+	Xpath 1048576				" X: 0
+    endtry
+
+    try
+	try
+	    Xpath 2097152			" X: 2097152
+	    execute 'try | throw 8 | finally   | throw "H" | endtry'
+	catch /H/
+	    Xpath 4194304			" X: 4194304
+	endtry
+    catch /8/
+	Xpath 8388608				" X: 0
+    endtry
+
+catch /.*/
+    Xpath 16777216				" X: 0
+    Xout v:exception "in" v:throwpoint
+endtry
+
+Xpath 33554432					" X: 33554432
+
+delcommand THROW1
+delcommand THROW2
+delcommand THROW3
+delcommand THROW4
+
+Xcheck 40744667
+
+
+"-------------------------------------------------------------------------------
+" Test 52:  Uncaught exceptions						    {{{1
+"
+"	    When an exception is thrown but not caught, an error message is
+"	    displayed when the script is terminated.  In case of an interrupt
+"	    or error exception, the normal interrupt or error message(s) are
+"	    displayed.
+"-------------------------------------------------------------------------------
+
+XpathINIT
+
+let msgfile = tempname()
+
+function! MESSAGES(...)
+    try
+	exec "edit" g:msgfile
+    catch /^Vim(edit):/
+	return 0
+    endtry
+
+    let english = v:lang == "C" || v:lang =~ '^[Ee]n'
+    let match = 1
+    norm gg
+
+    let num = a:0 / 2
+    let cnt = 1
+    while cnt <= num
+	let enr = a:{2*cnt - 1}
+	let emsg= a:{2*cnt}
+	let cnt = cnt + 1
+
+	if enr == ""
+	    Xout "TODO: Add message number for:" emsg
+	elseif enr == "INT"
+	    let enr = ""
+	endif
+	if enr == "" && !english
+	    continue
+	endif
+	let pattern = (enr != "") ? enr . ':.*' : ''
+	if english
+	    let pattern = pattern . emsg
+	endif
+	if !search(pattern, "W")
+	    let match = 0
+	    Xout "No match for:" pattern
+	endif
+	norm $
+    endwhile
+
+    bwipeout!
+    return match
+endfunction
+
+if ExtraVim(msgfile)
+    Xpath 1					" X: 1
+    throw "arrgh"
+endif
+
+Xpath 2						" X: 2
+if !MESSAGES('E605', "Exception not caught")
+    Xpath 4					" X: 0
+endif
+
+if ExtraVim(msgfile)
+    try
+	Xpath 8					" X: 8
+	throw "oops"
+    catch /arrgh/
+	Xpath 16				" X: 0
+    endtry
+    Xpath 32					" X: 0
+endif
+
+Xpath 64					" X: 64
+if !MESSAGES('E605', "Exception not caught")
+    Xpath 128					" X: 0
+endif
+
+if ExtraVim(msgfile)
+    function! T()
+	throw "brrr"
+    endfunction
+
+    try
+	Xpath 256				" X: 256
+	throw "arrgh"
+    catch /.*/
+	Xpath 512				" X: 512
+	call T()
+    endtry
+    Xpath 1024					" X: 0
+endif
+
+Xpath 2048					" X: 2048
+if !MESSAGES('E605', "Exception not caught")
+    Xpath 4096					" X: 0
+endif
+
+if ExtraVim(msgfile)
+    try
+	Xpath 8192				" X: 8192
+	throw "arrgh"
+    finally
+	Xpath 16384				" X: 16384
+	throw "brrr"
+    endtry
+    Xpath 32768					" X: 0
+endif
+
+Xpath 65536					" X: 65536
+if !MESSAGES('E605', "Exception not caught")
+    Xpath 131072				" X: 0
+endif
+
+if ExtraVim(msgfile)
+    try
+	Xpath 262144				" X: 262144
+	"INTERRUPT
+    endtry
+    Xpath 524288				" X: 0
+endif
+
+Xpath 1048576					" X: 1048576
+if !MESSAGES('INT', "Interrupted")
+    Xpath 2097152				" X: 0
+endif
+
+if ExtraVim(msgfile)
+    try
+	Xpath 4194304				" X: 4194304
+	let x = novar	" error E121/E15; exception: E121
+    catch /E15:/	" should not catch
+	Xpath 8388608				" X: 0
+    endtry
+    Xpath 16777216				" X: 0
+endif
+
+Xpath 33554432					" X: 33554432
+if !MESSAGES('E121', "Undefined variable", 'E15', "Invalid expression")
+    Xpath 67108864				" X: 0
+endif
+
+if ExtraVim(msgfile)
+    try
+	Xpath 134217728				" X: 134217728
+"	unlet novar #	" error E108/E488; exception: E488
+    catch /E108:/	" should not catch
+	Xpath 268435456				" X: 0
+    endtry
+    Xpath 536870912				" X: 0
+endif
+
+Xpath 1073741824				" X: 1073741824
+if !MESSAGES('E108', "No such variable", 'E488', "Trailing characters")
+    " The Xpath command does not accept 2^31 (negative); add explicitly:
+    let Xpath = Xpath + 2147483648		" X: 0
+endif
+
+call delete(msgfile)
+unlet msgfile
+
+Xcheck 1247112011
+
+" Leave MESSAGES() for the next tests.
+
+
+"-------------------------------------------------------------------------------
+" Test 53:  Nesting errors: :endif/:else/:elseif			    {{{1
+"
+"	    For nesting errors of :if conditionals the correct error messages
+"	    should be given.
+"
+"	    This test reuses the function MESSAGES() from the previous test.
+"	    This functions checks the messages in g:msgfile.
+"-------------------------------------------------------------------------------
+
+XpathINIT
+
+let msgfile = tempname()
+
+if ExtraVim(msgfile)
+"   endif
+endif
+if MESSAGES('E580', ":endif without :if")
+    Xpath 1					" X: 1
+endif
+
+if ExtraVim(msgfile)
+"   while 1
+"       endif
+"   endwhile
+endif
+if MESSAGES('E580', ":endif without :if")
+    Xpath 2					" X: 2
+endif
+
+if ExtraVim(msgfile)
+"   try
+"   finally
+"       endif
+"   endtry
+endif
+if MESSAGES('E580', ":endif without :if")
+    Xpath 4					" X: 4
+endif
+
+if ExtraVim(msgfile)
+"   try
+"       endif
+"   endtry
+endif
+if MESSAGES('E580', ":endif without :if")
+    Xpath 8					" X: 8
+endif
+
+if ExtraVim(msgfile)
+"   try
+"       throw "a"
+"   catch /a/
+"       endif
+"   endtry
+endif
+if MESSAGES('E580', ":endif without :if")
+    Xpath 16					" X: 16
+endif
+
+if ExtraVim(msgfile)
+"   else
+endif
+if MESSAGES('E581', ":else without :if")
+    Xpath 32					" X: 32
+endif
+
+if ExtraVim(msgfile)
+"   while 1
+"       else
+"   endwhile
+endif
+if MESSAGES('E581', ":else without :if")
+    Xpath 64					" X: 64
+endif
+
+if ExtraVim(msgfile)
+"   try
+"   finally
+"       else
+"   endtry
+endif
+if MESSAGES('E581', ":else without :if")
+    Xpath 128					" X: 128
+endif
+
+if ExtraVim(msgfile)
+"   try
+"       else
+"   endtry
+endif
+if MESSAGES('E581', ":else without :if")
+    Xpath 256					" X: 256
+endif
+
+if ExtraVim(msgfile)
+"   try
+"       throw "a"
+"   catch /a/
+"       else
+"   endtry
+endif
+if MESSAGES('E581', ":else without :if")
+    Xpath 512					" X: 512
+endif
+
+if ExtraVim(msgfile)
+"   elseif
+endif
+if MESSAGES('E582', ":elseif without :if")
+    Xpath 1024					" X: 1024
+endif
+
+if ExtraVim(msgfile)
+"   while 1
+"       elseif
+"   endwhile
+endif
+if MESSAGES('E582', ":elseif without :if")
+    Xpath 2048					" X: 2048
+endif
+
+if ExtraVim(msgfile)
+"   try
+"   finally
+"       elseif
+"   endtry
+endif
+if MESSAGES('E582', ":elseif without :if")
+    Xpath 4096					" X: 4096
+endif
+
+if ExtraVim(msgfile)
+"   try
+"       elseif
+"   endtry
+endif
+if MESSAGES('E582', ":elseif without :if")
+    Xpath 8192					" X: 8192
+endif
+
+if ExtraVim(msgfile)
+"   try
+"       throw "a"
+"   catch /a/
+"       elseif
+"   endtry
+endif
+if MESSAGES('E582', ":elseif without :if")
+    Xpath 16384					" X: 16384
+endif
+
+if ExtraVim(msgfile)
+"   if 1
+"   else
+"   else
+"   endif
+endif
+if MESSAGES('E583', "multiple :else")
+    Xpath 32768					" X: 32768
+endif
+
+if ExtraVim(msgfile)
+"   if 1
+"   else
+"   elseif 1
+"   endif
+endif
+if MESSAGES('E584', ":elseif after :else")
+    Xpath 65536					" X: 65536
+endif
+
+call delete(msgfile)
+unlet msgfile
+
+Xcheck 131071
+
+" Leave MESSAGES() for the next test.
+
+
+"-------------------------------------------------------------------------------
+" Test 54:  Nesting errors: :while/:endwhile				    {{{1
+"
+"	    For nesting errors of :while conditionals the correct error messages
+"	    should be given.
+"
+"	    This test reuses the function MESSAGES() from the previous test.
+"	    This functions checks the messages in g:msgfile.
+"-------------------------------------------------------------------------------
+
+XpathINIT
+
+let msgfile = tempname()
+
+if ExtraVim(msgfile)
+"   endwhile
+endif
+if MESSAGES('E588', ":endwhile without :while")
+    Xpath 1					" X: 1
+endif
+
+if ExtraVim(msgfile)
+"   if 1
+"       endwhile
+"   endif
+endif
+if MESSAGES('E588', ":endwhile without :while")
+    Xpath 2					" X: 2
+endif
+
+if ExtraVim(msgfile)
+"   while 1
+"       if 1
+"   endwhile
+endif
+if MESSAGES('E171', "Missing :endif")
+    Xpath 4					" X: 4
+endif
+
+if ExtraVim(msgfile)
+"   try
+"   finally
+"       endwhile
+"   endtry
+endif
+if MESSAGES('E588', ":endwhile without :while")
+    Xpath 8					" X: 8
+endif
+
+if ExtraVim(msgfile)
+"   while 1
+"       try
+"       finally
+"   endwhile
+endif
+if MESSAGES('E600', "Missing :endtry")
+    Xpath 16					" X: 16
+endif
+
+if ExtraVim(msgfile)
+"   while 1
+"       if 1
+"	    try
+"	    finally
+"   endwhile
+endif
+if MESSAGES('E600', "Missing :endtry")
+    Xpath 32					" X: 32
+endif
+
+if ExtraVim(msgfile)
+"   while 1
+"       try
+"       finally
+"	    if 1
+"   endwhile
+endif
+if MESSAGES('E171', "Missing :endif")
+    Xpath 64					" X: 64
+endif
+
+if ExtraVim(msgfile)
+"   try
+"       endwhile
+"   endtry
+endif
+if MESSAGES('E588', ":endwhile without :while")
+    Xpath 128					" X: 128
+endif
+
+if ExtraVim(msgfile)
+"   while 1
+"       try
+"	    endwhile
+"       endtry
+"   endwhile
+endif
+if MESSAGES('E588', ":endwhile without :while")
+    Xpath 256					" X: 256
+endif
+
+if ExtraVim(msgfile)
+"   try
+"       throw "a"
+"   catch /a/
+"       endwhile
+"   endtry
+endif
+if MESSAGES('E588', ":endwhile without :while")
+    Xpath 512					" X: 512
+endif
+
+if ExtraVim(msgfile)
+"   while 1
+"       try
+"	    throw "a"
+"	catch /a/
+"	    endwhile
+"       endtry
+"   endwhile
+endif
+if MESSAGES('E588', ":endwhile without :while")
+    Xpath 1024					" X: 1024
+endif
+
+
+call delete(msgfile)
+unlet msgfile
+
+Xcheck 2047
+
+" Leave MESSAGES() for the next test.
+
+
+"-------------------------------------------------------------------------------
+" Test 55:  Nesting errors: :continue/:break				    {{{1
+"
+"	    For nesting errors of :continue and :break commands the correct
+"	    error messages should be given.
+"
+"	    This test reuses the function MESSAGES() from the previous test.
+"	    This functions checks the messages in g:msgfile.
+"-------------------------------------------------------------------------------
+
+XpathINIT
+
+let msgfile = tempname()
+
+if ExtraVim(msgfile)
+"   continue
+endif
+if MESSAGES('E586', ":continue without :while")
+    Xpath 1					" X: 1
+endif
+
+if ExtraVim(msgfile)
+"   if 1
+"       continue
+"   endif
+endif
+if MESSAGES('E586', ":continue without :while")
+    Xpath 2					" X: 2
+endif
+
+if ExtraVim(msgfile)
+"   try
+"   finally
+"       continue
+"   endtry
+endif
+if MESSAGES('E586', ":continue without :while")
+    Xpath 4					" X: 4
+endif
+
+if ExtraVim(msgfile)
+"   try
+"       continue
+"   endtry
+endif
+if MESSAGES('E586', ":continue without :while")
+    Xpath 8					" X: 8
+endif
+
+if ExtraVim(msgfile)
+"   try
+"       throw "a"
+"   catch /a/
+"       continue
+"   endtry
+endif
+if MESSAGES('E586', ":continue without :while")
+    Xpath 16					" X: 16
+endif
+
+if ExtraVim(msgfile)
+"   break
+endif
+if MESSAGES('E587', ":break without :while")
+    Xpath 32					" X: 32
+endif
+
+if ExtraVim(msgfile)
+"   if 1
+"       break
+"   endif
+endif
+if MESSAGES('E587', ":break without :while")
+    Xpath 64					" X: 64
+endif
+
+if ExtraVim(msgfile)
+"   try
+"   finally
+"       break
+"   endtry
+endif
+if MESSAGES('E587', ":break without :while")
+    Xpath 128					" X: 128
+endif
+
+if ExtraVim(msgfile)
+"   try
+"       break
+"   endtry
+endif
+if MESSAGES('E587', ":break without :while")
+    Xpath 256					" X: 256
+endif
+
+if ExtraVim(msgfile)
+"   try
+"       throw "a"
+"   catch /a/
+"       break
+"   endtry
+endif
+if MESSAGES('E587', ":break without :while")
+    Xpath 512					" X: 512
+endif
+
+call delete(msgfile)
+unlet msgfile
+
+Xcheck 1023
+
+" Leave MESSAGES() for the next test.
+
+
+"-------------------------------------------------------------------------------
+" Test 56:  Nesting errors: :endtry					    {{{1
+"
+"	    For nesting errors of :try conditionals the correct error messages
+"	    should be given.
+"
+"	    This test reuses the function MESSAGES() from the previous test.
+"	    This functions checks the messages in g:msgfile.
+"-------------------------------------------------------------------------------
+
+XpathINIT
+
+let msgfile = tempname()
+
+if ExtraVim(msgfile)
+"   endtry
+endif
+if MESSAGES('E602', ":endtry without :try")
+    Xpath 1					" X: 1
+endif
+
+if ExtraVim(msgfile)
+"   if 1
+"       endtry
+"   endif
+endif
+if MESSAGES('E602', ":endtry without :try")
+    Xpath 2					" X: 2
+endif
+
+if ExtraVim(msgfile)
+"   while 1
+"       endtry
+"   endwhile
+endif
+if MESSAGES('E602', ":endtry without :try")
+    Xpath 4					" X: 4
+endif
+
+if ExtraVim(msgfile)
+"   try
+"       if 1
+"   endtry
+endif
+if MESSAGES('E171', "Missing :endif")
+    Xpath 8					" X: 8
+endif
+
+if ExtraVim(msgfile)
+"   try
+"       while 1
+"   endtry
+endif
+if MESSAGES('E170', "Missing :endwhile")
+    Xpath 16					" X: 16
+endif
+
+if ExtraVim(msgfile)
+"   try
+"   finally
+"       if 1
+"   endtry
+endif
+if MESSAGES('E171', "Missing :endif")
+    Xpath 32					" X: 32
+endif
+
+if ExtraVim(msgfile)
+"   try
+"   finally
+"       while 1
+"   endtry
+endif
+if MESSAGES('E170', "Missing :endwhile")
+    Xpath 64					" X: 64
+endif
+
+if ExtraVim(msgfile)
+"   try
+"       throw "a"
+"   catch /a/
+"       if 1
+"   endtry
+endif
+if MESSAGES('E171', "Missing :endif")
+    Xpath 128					" X: 128
+endif
+
+if ExtraVim(msgfile)
+"   try
+"       throw "a"
+"   catch /a/
+"       while 1
+"   endtry
+endif
+if MESSAGES('E170', "Missing :endwhile")
+    Xpath 256					" X: 256
+endif
+
+call delete(msgfile)
+unlet msgfile
+
+delfunction MESSAGES
+
+Xcheck 511
+
+
+"-------------------------------------------------------------------------------
+" Test 57:  v:exception and v:throwpoint for user exceptions		    {{{1
+"
+"	    v:exception evaluates to the value of the exception that was caught
+"	    most recently and is not finished.  (A caught exception is finished
+"	    when the next ":catch", ":finally", or ":endtry" is reached.)
+"	    v:throwpoint evaluates to the script/function name and line number
+"	    where that exception has been thrown.
+"-------------------------------------------------------------------------------
+
+XpathINIT
+
+function! FuncException()
+    let g:exception = v:exception
+endfunction
+
+function! FuncThrowpoint()
+    let g:throwpoint = v:throwpoint
+endfunction
+
+let scriptException  = MakeScript("FuncException")
+let scriptThrowPoint = MakeScript("FuncThrowpoint")
+
+command! CmdException  let g:exception  = v:exception
+command! CmdThrowpoint let g:throwpoint = v:throwpoint
+
+XloopINIT! 1 2
+
+function! CHECK(n, exception, throwname, throwline)
+    XloopNEXT
+    let error = 0
+    if v:exception != a:exception
+	Xout a:n.": v:exception is" v:exception "instead of" a:exception
+	let error = 1
+    endif
+    if v:throwpoint !~ a:throwname
+	let name = escape(a:throwname, '\')
+	Xout a:n.": v:throwpoint (".v:throwpoint.") does not match" name
+	let error = 1
+    endif
+    if v:throwpoint !~ a:throwline
+	let line = escape(a:throwline, '\')
+	Xout a:n.": v:throwpoint (".v:throwpoint.") does not match" line
+	let error = 1
+    endif
+    if error
+	Xloop 1					" X: 0
+    endif
+endfunction
+
+function! T(arg, line)
+    if a:line == 2
+	throw a:arg		" in line 2
+    elseif a:line == 4
+	throw a:arg		" in line 4
+    elseif a:line == 6
+	throw a:arg		" in line 6
+    elseif a:line == 8
+	throw a:arg		" in line 8
+    endif
+endfunction
+
+function! G(arg, line)
+    call T(a:arg, a:line)
+endfunction
+
+function! F(arg, line)
+    call G(a:arg, a:line)
+endfunction
+
+let scriptT = MakeScript("T")
+let scriptG = MakeScript("G", scriptT)
+let scriptF = MakeScript("F", scriptG)
+
+try
+    Xpath 32768					" X: 32768
+    call F("oops", 2)
+catch /.*/
+    Xpath 65536					" X: 65536
+    let exception  = v:exception
+    let throwpoint = v:throwpoint
+    call CHECK(1, "oops", '\<F\.\.G\.\.T\>', '\<2\>')
+    exec "let exception  = v:exception"
+    exec "let throwpoint = v:throwpoint"
+    call CHECK(2, "oops", '\<F\.\.G\.\.T\>', '\<2\>')
+    CmdException
+    CmdThrowpoint
+    call CHECK(3, "oops", '\<F\.\.G\.\.T\>', '\<2\>')
+    call FuncException()
+    call FuncThrowpoint()
+    call CHECK(4, "oops", '\<F\.\.G\.\.T\>', '\<2\>')
+    exec "source" scriptException
+    exec "source" scriptThrowPoint
+    call CHECK(5, "oops", '\<F\.\.G\.\.T\>', '\<2\>')
+    try
+	Xpath 131072				" X: 131072
+	call G("arrgh", 4)
+    catch /.*/
+	Xpath 262144				" X: 262144
+	let exception  = v:exception
+	let throwpoint = v:throwpoint
+	call CHECK(6, "arrgh", '\<G\.\.T\>', '\<4\>')
+	try
+	    Xpath 524288			" X: 524288
+	    let g:arg = "autsch"
+	    let g:line = 6
+	    exec "source" scriptF
+	catch /.*/
+	    Xpath 1048576			" X: 1048576
+	    let exception  = v:exception
+	    let throwpoint = v:throwpoint
+	    " Symbolic links in tempname()s are not resolved, whereas resolving
+	    " is done for v:throwpoint.  Resolve the temporary file name for
+	    " scriptT, so that it can be matched against v:throwpoint.
+	    call CHECK(7, "autsch", resolve(scriptT), '\<6\>')
+	finally
+	    Xpath 2097152			" X: 2097152
+	    let exception  = v:exception
+	    let throwpoint = v:throwpoint
+	    call CHECK(8, "arrgh", '\<G\.\.T\>', '\<4\>')
+	    try
+		Xpath 4194304			" X: 4194304
+		let g:arg = "brrrr"
+		let g:line = 8
+		exec "source" scriptG
+	    catch /.*/
+		Xpath 8388608			" X: 8388608
+		let exception  = v:exception
+		let throwpoint = v:throwpoint
+		" Resolve scriptT for matching it against v:throwpoint.
+		call CHECK(9, "brrrr", resolve(scriptT), '\<8\>')
+	    finally
+		Xpath 16777216			" X: 16777216
+		let exception  = v:exception
+		let throwpoint = v:throwpoint
+		call CHECK(10, "arrgh", '\<G\.\.T\>', '\<4\>')
+	    endtry
+	    Xpath 33554432			" X: 33554432
+	    let exception  = v:exception
+	    let throwpoint = v:throwpoint
+	    call CHECK(11, "arrgh", '\<G\.\.T\>', '\<4\>')
+	endtry
+	Xpath 67108864				" X: 67108864
+	let exception  = v:exception
+	let throwpoint = v:throwpoint
+	call CHECK(12, "arrgh", '\<G\.\.T\>', '\<4\>')
+    finally
+	Xpath 134217728				" X: 134217728
+	let exception  = v:exception
+	let throwpoint = v:throwpoint
+	call CHECK(13, "oops", '\<F\.\.G\.\.T\>', '\<2\>')
+    endtry
+    Xpath 268435456				" X: 268435456
+    let exception  = v:exception
+    let throwpoint = v:throwpoint
+    call CHECK(14, "oops", '\<F\.\.G\.\.T\>', '\<2\>')
+finally
+    Xpath 536870912				" X: 536870912
+    let exception  = v:exception
+    let throwpoint = v:throwpoint
+    call CHECK(15, "", '^$', '^$')
+endtry
+
+Xpath 1073741824				" X: 1073741824
+
+unlet exception throwpoint
+delfunction FuncException
+delfunction FuncThrowpoint
+call delete(scriptException)
+call delete(scriptThrowPoint)
+unlet scriptException scriptThrowPoint
+delcommand CmdException
+delcommand CmdThrowpoint
+delfunction T
+delfunction G
+delfunction F
+call delete(scriptT)
+call delete(scriptG)
+call delete(scriptF)
+unlet scriptT scriptG scriptF
+
+Xcheck 2147450880
+
+
+"-------------------------------------------------------------------------------
+"
+" Test 58:  v:exception and v:throwpoint for error/interrupt exceptions	    {{{1
+"
+"	    v:exception and v:throwpoint work also for error and interrupt
+"	    exceptions.
+"-------------------------------------------------------------------------------
+
+XpathINIT
+
+if ExtraVim()
+
+    function! T(line)
+	if a:line == 2
+	    delfunction T		" error (function in use) in line 2
+	elseif a:line == 4
+	    let dummy = 0		" INTERRUPT1 - interrupt in line 4
+	endif
+    endfunction
+
+    while 1
+	try
+	    Xpath 1				" X: 1
+	    let caught = 0
+	    call T(2)
+	catch /.*/
+	    let caught = 1
+	    if v:exception !~ 'Vim(delfunction):'
+		Xpath 2				" X: 0
+	    endif
+	    if v:throwpoint !~ '\<T\>'
+		Xpath 4				" X: 0
+	    endif
+	    if v:throwpoint !~ '\<2\>'
+		Xpath 8				" X: 0
+	    endif
+	finally
+	    Xpath 16				" X: 16
+	    if caught || $VIMNOERRTHROW
+		Xpath 32			" X: 32
+	    endif
+	    if v:exception != ""
+		Xpath 64			" X: 0
+	    endif
+	    if v:throwpoint != ""
+		Xpath 128			" X: 0
+	    endif
+	    break		" discard error for $VIMNOERRTHROW
+	endtry
+    endwhile
+
+    Xpath 256					" X: 256
+    if v:exception != ""
+	Xpath 512				" X: 0
+    endif
+    if v:throwpoint != ""
+	Xpath 1024				" X: 0
+    endif
+
+    while 1
+	try
+	    Xpath 2048				" X: 2048
+	    let caught = 0
+	    call T(4)
+	catch /.*/
+	    let caught = 1
+	    if v:exception != 'Vim:Interrupt'
+		Xpath 4096			" X: 0
+	    endif
+	    if v:throwpoint !~ '\<T\>'
+		Xpath 8192			" X: 0
+	    endif
+	    if v:throwpoint !~ '\<4\>'
+		Xpath 16384			" X: 0
+	    endif
+	finally
+	    Xpath 32768				" X: 32768
+	    if caught || $VIMNOINTTHROW
+		Xpath 65536			" X: 65536
+	    endif
+	    if v:exception != ""
+		Xpath 131072			" X: 0
+	    endif
+	    if v:throwpoint != ""
+		Xpath 262144			" X: 0
+	    endif
+	    break		" discard error for $VIMNOERRTHROW
+	endtry
+    endwhile
+
+    Xpath 524288				" X: 524288
+    if v:exception != ""
+	Xpath 1048576				" X: 0
+    endif
+    if v:throwpoint != ""
+	Xpath 2097152				" X: 0
+    endif
+
+endif
+
+Xcheck 624945
+
+
+"-------------------------------------------------------------------------------
+"
+" Test 59:  v:exception and v:throwpoint when discarding exceptions	    {{{1
+"
+"	    When a :catch clause is left by a ":break" etc or an error or
+"	    interrupt exception, v:exception and v:throwpoint are reset.  They
+"	    are not affected by an exception that is discarded before being
+"	    caught.
+"-------------------------------------------------------------------------------
+
+XpathINIT
+
+if ExtraVim()
+
+    XloopINIT! 1 2
+
+    let sfile = expand("<sfile>")
+
+    function! LineNumber()
+	return substitute(substitute(v:throwpoint, g:sfile, '', ""),
+	    \ '\D*\(\d*\).*', '\1', "")
+    endfunction
+
+    command! -nargs=1 SetLineNumber
+	\ try | throw "line" | catch /.*/ | let <args> =  LineNumber() | endtry
+
+    " Check v:exception/v:throwpoint against second/fourth parameter if
+    " specified, check for being empty else.
+    function! CHECK(n, ...)
+	XloopNEXT
+	let exception = a:0 != 0 ? a:1 : ""	" second parameter (optional)
+	let emsg      = a:0 != 0 ? a:2 : ""	" third parameter (optional)
+	let line      = a:0 != 0 ? a:3 : 0	" fourth parameter (optional)
+	let error = 0
+	if emsg != ""
+	    " exception is the error number, emsg the English error message text
+	    if exception !~ '^E\d\+$'
+		Xout "TODO: Add message number for:" emsg
+	    elseif v:lang == "C" || v:lang =~ '^[Ee]n'
+		if exception == "E492" && emsg == "Not an editor command"
+		    let exception = '^Vim:' . exception . ': ' . emsg
+		else
+		    let exception = '^Vim(\a\+):' . exception . ': ' . emsg
+		endif
+	    else
+		if exception == "E492"
+		    let exception = '^Vim:' . exception
+		else
+		    let exception = '^Vim(\a\+):' . exception
+		endif
+	    endif
+	endif
+	if exception == "" && v:exception != ""
+	    Xout a:n.": v:exception is set:" v:exception
+	    let error = 1
+	elseif exception != "" && v:exception !~ exception
+	    Xout a:n.": v:exception (".v:exception.") does not match" exception
+	    let error = 1
+	endif
+	if line == 0 && v:throwpoint != ""
+	    Xout a:n.": v:throwpoint is set:" v:throwpoint
+	    let error = 1
+	elseif line != 0 && v:throwpoint !~ '\<' . line . '\>'
+	    Xout a:n.": v:throwpoint (".v:throwpoint.") does not match" line
+	    let error = 1
+	endif
+	if !error
+	    Xloop 1				" X: 2097151
+	endif
+    endfunction
+
+    while 1
+	try
+	    throw "x1"
+	catch /.*/
+	    break
+	endtry
+    endwhile
+    call CHECK(1)
+
+    while 1
+	try
+	    throw "x2"
+	catch /.*/
+	    break
+	finally
+	    call CHECK(2)
+	endtry
+	break
+    endwhile
+    call CHECK(3)
+
+    while 1
+	try
+	    let errcaught = 0
+	    try
+		try
+		    throw "x3"
+		catch /.*/
+		    SetLineNumber line_before_error
+		    asdf
+		endtry
+	    catch /.*/
+		let errcaught = 1
+		call CHECK(4, 'E492', "Not an editor command",
+		    \ line_before_error + 1)
+	    endtry
+	finally
+	    if !errcaught && $VIMNOERRTHROW
+		call CHECK(4)
+	    endif
+	    break		" discard error for $VIMNOERRTHROW
+	endtry
+    endwhile
+    call CHECK(5)
+
+    Xpath 2097152				" X: 2097152
+
+    while 1
+	try
+	    let intcaught = 0
+	    try
+		try
+		    throw "x4"
+		catch /.*/
+		    SetLineNumber two_lines_before_interrupt
+		    "INTERRUPT
+		    let dummy = 0
+		endtry
+	    catch /.*/
+		let intcaught = 1
+		call CHECK(6, "Vim:Interrupt", '',
+		    \ two_lines_before_interrupt + 2)
+	    endtry
+	finally
+	    if !intcaught && $VIMNOINTTHROW
+		call CHECK(6)
+	    endif
+	    break		" discard interrupt for $VIMNOINTTHROW
+	endtry
+    endwhile
+    call CHECK(7)
+
+    Xpath 4194304				" X: 4194304
+
+    while 1
+	try
+	    let errcaught = 0
+	    try
+		try
+"		    if 1
+			SetLineNumber line_before_throw
+			throw "x5"
+		    " missing endif
+		catch /.*/
+		    Xpath 8388608			" X: 0
+		endtry
+	    catch /.*/
+		let errcaught = 1
+		call CHECK(8, 'E171', "Missing :endif", line_before_throw + 3)
+	    endtry
+	finally
+	    if !errcaught && $VIMNOERRTHROW
+		call CHECK(8)
+	    endif
+	    break		" discard error for $VIMNOERRTHROW
+	endtry
+    endwhile
+    call CHECK(9)
+
+    Xpath 16777216				" X: 16777216
+
+    try
+	while 1
+	    try
+		throw "x6"
+	    finally
+		break
+	    endtry
+	    break
+	endwhile
+    catch /.*/
+	Xpath 33554432				" X: 0
+    endtry
+    call CHECK(10)
+
+    try
+	while 1
+	    try
+		throw "x7"
+	    finally
+		break
+	    endtry
+	    break
+	endwhile
+    catch /.*/
+	Xpath 67108864				" X: 0
+    finally
+	call CHECK(11)
+    endtry
+    call CHECK(12)
+
+    while 1
+	try
+	    let errcaught = 0
+	    try
+		try
+		    throw "x8"
+		finally
+		    SetLineNumber line_before_error
+		    asdf
+		endtry
+	    catch /.*/
+		let errcaught = 1
+		call CHECK(13, 'E492', "Not an editor command",
+		    \ line_before_error + 1)
+	    endtry
+	finally
+	    if !errcaught && $VIMNOERRTHROW
+		call CHECK(13)
+	    endif
+	    break		" discard error for $VIMNOERRTHROW
+	endtry
+    endwhile
+    call CHECK(14)
+
+    Xpath 134217728				" X: 134217728
+
+    while 1
+	try
+	    let intcaught = 0
+	    try
+		try
+		    throw "x9"
+		finally
+		    SetLineNumber two_lines_before_interrupt
+		    "INTERRUPT
+		endtry
+	    catch /.*/
+		let intcaught = 1
+		call CHECK(15, "Vim:Interrupt", '',
+		    \ two_lines_before_interrupt + 2)
+	    endtry
+	finally
+	    if !intcaught && $VIMNOINTTHROW
+		call CHECK(15)
+	    endif
+	    break		" discard interrupt for $VIMNOINTTHROW
+	endtry
+    endwhile
+    call CHECK(16)
+
+    Xpath 268435456				" X: 268435456
+
+    while 1
+	try
+	    let errcaught = 0
+	    try
+		try
+"		    if 1
+			SetLineNumber line_before_throw
+			throw "x10"
+		    " missing endif
+		finally
+		    call CHECK(17)
+		endtry
+	    catch /.*/
+		let errcaught = 1
+		call CHECK(18, 'E171', "Missing :endif", line_before_throw + 3)
+	    endtry
+	finally
+	    if !errcaught && $VIMNOERRTHROW
+		call CHECK(18)
+	    endif
+	    break		" discard error for $VIMNOERRTHROW
+	endtry
+    endwhile
+    call CHECK(19)
+
+    Xpath 536870912				" X: 536870912
+
+    while 1
+	try
+	    let errcaught = 0
+	    try
+		try
+"		    if 1
+			SetLineNumber line_before_throw
+			throw "x11"
+		    " missing endif
+		endtry
+	    catch /.*/
+		let errcaught = 1
+		call CHECK(20, 'E171', "Missing :endif", line_before_throw + 3)
+	    endtry
+	finally
+	    if !errcaught && $VIMNOERRTHROW
+		call CHECK(20)
+	    endif
+	    break		" discard error for $VIMNOERRTHROW
+	endtry
+    endwhile
+    call CHECK(21)
+
+    Xpath 1073741824				" X: 1073741824
+
+endif
+
+Xcheck 2038431743
+
+
+"-------------------------------------------------------------------------------
+"
+" Test 60:  (Re)throwing v:exception; :echoerr.				    {{{1
+"
+"	    A user exception can be rethrown after catching by throwing
+"	    v:exception.  An error or interrupt exception cannot be rethrown
+"	    because Vim exceptions cannot be faked.  A Vim exception using the
+"	    value of v:exception can, however, be triggered by the :echoerr
+"	    command.
+"-------------------------------------------------------------------------------
+
+XpathINIT
+
+try
+    try
+	Xpath 1					" X: 1
+	throw "oops"
+    catch /oops/
+	Xpath 2					" X: 2
+	throw v:exception	" rethrow user exception
+    catch /.*/
+	Xpath 4					" X: 0
+    endtry
+catch /^oops$/			" catches rethrown user exception
+    Xpath 8					" X: 8
+catch /.*/
+    Xpath 16					" X: 0
+endtry
+
+function! F()
+    try
+	let caught = 0
+	try
+	    Xpath 32				" X: 32
+	    write /n/o/n/w/r/i/t/a/b/l/e/_/f/i/l/e
+	    Xpath 64				" X: 0
+	    Xout "did_emsg was reset before executing " .
+		\ "BufWritePost autocommands."
+	catch /^Vim(write):/
+	    let caught = 1
+	    throw v:exception	" throw error: cannot fake Vim exception
+	catch /.*/
+	    Xpath 128				" X: 0
+	finally
+	    Xpath 256				" X: 256
+	    if !caught && !$VIMNOERRTHROW
+		Xpath 512			" X: 0
+	    endif
+	endtry
+    catch /^Vim(throw):/	" catches throw error
+	let caught = caught + 1
+    catch /.*/
+	Xpath 1024				" X: 0
+    finally
+	Xpath 2048				" X: 2048
+	if caught != 2
+	    if !caught && !$VIMNOERRTHROW
+		Xpath 4096			" X: 0
+	    elseif caught
+		Xpath 8192			" X: 0
+	    endif
+	    return		| " discard error for $VIMNOERRTHROW
+	endif
+    endtry
+endfunction
+
+call F()
+delfunction F
+
+function! G()
+    try
+	let caught = 0
+	try
+	    Xpath 16384				" X: 16384
+	    asdf
+	catch /^Vim/		" catch error exception
+	    let caught = 1
+	    " Trigger Vim error exception with value specified after :echoerr
+	    let value = substitute(v:exception, '^Vim\((.*)\)\=:', '', "")
+	    echoerr value
+	catch /.*/
+	    Xpath 32768				" X: 0
+	finally
+	    Xpath 65536				" X: 65536
+	    if !caught
+		if !$VIMNOERRTHROW
+		    Xpath 131072		" X: 0
+		else
+		    let value = "Error"
+		    echoerr value
+		endif
+	    endif
+	endtry
+    catch /^Vim(echoerr):/
+	let caught = caught + 1
+	if v:exception !~ value
+	    Xpath 262144			" X: 0
+	endif
+    catch /.*/
+	Xpath 524288				" X: 0
+    finally
+	Xpath 1048576				" X: 1048576
+	if caught != 2
+	    if !caught && !$VIMNOERRTHROW
+		Xpath 2097152			" X: 0
+	    elseif caught
+		Xpath 4194304			" X: 0
+	    endif
+	    return		| " discard error for $VIMNOERRTHROW
+	endif
+    endtry
+endfunction
+
+call G()
+delfunction G
+
+unlet! value caught
+
+if ExtraVim()
+    try
+	let errcaught = 0
+	try
+	    Xpath 8388608			" X: 8388608
+	    let intcaught = 0
+	    "INTERRUPT
+	catch /^Vim:/		" catch interrupt exception
+	    let intcaught = 1
+	    " Trigger Vim error exception with value specified after :echoerr
+	    echoerr substitute(v:exception, '^Vim\((.*)\)\=:', '', "")
+	catch /.*/
+	    Xpath 16777216			" X: 0
+	finally
+	    Xpath 33554432			" X: 33554432
+	    if !intcaught
+		if !$VIMNOINTTHROW
+		    Xpath 67108864		" X: 0
+		else
+		    echoerr "Interrupt"
+		endif
+	    endif
+	endtry
+    catch /^Vim(echoerr):/
+	let errcaught = 1
+	if v:exception !~ "Interrupt"
+	    Xpath 134217728			" X: 0
+	endif
+    finally
+	Xpath 268435456				" X: 268435456
+	if !errcaught && !$VIMNOERRTHROW
+	    Xpath 536870912			" X: 0
+	endif
+    endtry
+endif
+
+Xcheck 311511339
+
+
+"-------------------------------------------------------------------------------
+" Test 61:  Catching interrupt exceptions				    {{{1
+"
+"	    When an interrupt occurs inside a :try/:endtry region, an
+"	    interrupt exception is thrown and can be caught.  Its value is
+"	    "Vim:Interrupt".  If the interrupt occurs after an error or a :throw
+"	    but before a matching :catch is reached, all following :catches of
+"	    that try block are ignored, but the interrupt exception can be
+"	    caught by the next surrounding try conditional.  An interrupt is
+"	    ignored when there is a previous interrupt that has not been caught
+"	    or causes a :finally clause to be executed.
+"-------------------------------------------------------------------------------
+
+XpathINIT
+
+if ExtraVim()
+
+    while 1
+	try
+	    try
+		Xpath 1				" X: 1
+		let caught = 0
+		"INTERRUPT
+		Xpath 2				" X: 0
+	    catch /^Vim:Interrupt$/
+		let caught = 1
+	    finally
+		Xpath 4				" X: 4
+		if caught || $VIMNOINTTHROW
+		    Xpath 8			" X: 8
+		endif
+	    endtry
+	catch /.*/
+	    Xpath 16				" X: 0
+	    Xout v:exception "in" v:throwpoint
+	finally
+	    break		" discard interrupt for $VIMNOINTTHROW
+	endtry
+    endwhile
+
+    while 1
+	try
+	    try
+		let caught = 0
+		try
+		    Xpath 32			" X: 32
+		    asdf
+		    Xpath 64			" X: 0
+		catch /do_not_catch/
+		    Xpath 128			" X: 0
+		catch /.*/	"INTERRUPT - throw interrupt if !$VIMNOERRTHROW
+		    Xpath 256			" X: 0
+		catch /.*/
+		    Xpath 512			" X: 0
+		finally		"INTERRUPT - throw interrupt if $VIMNOERRTHROW
+		    Xpath 1024			" X: 1024
+		endtry
+	    catch /^Vim:Interrupt$/
+		let caught = 1
+	    finally
+		Xpath 2048			" X: 2048
+		if caught || $VIMNOINTTHROW
+		    Xpath 4096			" X: 4096
+		endif
+	    endtry
+	catch /.*/
+	    Xpath 8192				" X: 0
+	    Xout v:exception "in" v:throwpoint
+	finally
+	    break		" discard interrupt for $VIMNOINTTHROW
+	endtry
+    endwhile
+
+    while 1
+	try
+	    try
+		let caught = 0
+		try
+		    Xpath 16384			" X: 16384
+		    throw "x"
+		    Xpath 32768			" X: 0
+		catch /do_not_catch/
+		    Xpath 65536			" X: 0
+		catch /x/	"INTERRUPT
+		    Xpath 131072		" X: 0
+		catch /.*/
+		    Xpath 262144		" X: 0
+		endtry
+	    catch /^Vim:Interrupt$/
+		let caught = 1
+	    finally
+		Xpath 524288			" X: 524288
+		if caught || $VIMNOINTTHROW
+		    Xpath 1048576		" X: 1048576
+		endif
+	    endtry
+	catch /.*/
+	    Xpath 2097152			" X: 0
+	    Xout v:exception "in" v:throwpoint
+	finally
+	    break		" discard interrupt for $VIMNOINTTHROW
+	endtry
+    endwhile
+
+    while 1
+	try
+	    let caught = 0
+	    try
+		Xpath 4194304			" X: 4194304
+		"INTERRUPT
+		Xpath 8388608			" X: 0
+	    catch /do_not_catch/ "INTERRUPT
+		Xpath 16777216			" X: 0
+	    catch /^Vim:Interrupt$/
+		let caught = 1
+	    finally
+		Xpath 33554432			" X: 33554432
+		if caught || $VIMNOINTTHROW
+		    Xpath 67108864		" X: 67108864
+		endif
+	    endtry
+	catch /.*/
+	    Xpath 134217728			" X: 0
+	    Xout v:exception "in" v:throwpoint
+	finally
+	    break		" discard interrupt for $VIMNOINTTHROW
+	endtry
+    endwhile
+
+    Xpath 268435456				" X: 268435456
+
+endif
+
+Xcheck 374889517
+
+
+"-------------------------------------------------------------------------------
+" Test 62:  Catching error exceptions					    {{{1
+"
+"	    An error inside a :try/:endtry region is converted to an exception
+"	    and can be caught.  The error exception has a "Vim(cmdname):" prefix
+"	    where cmdname is the name of the failing command, or a "Vim:" prefix
+"	    if no command name is known.  The "Vim" prefixes cannot be faked.
+"-------------------------------------------------------------------------------
+
+XpathINIT
+
+function! MSG(enr, emsg)
+    let english = v:lang == "C" || v:lang =~ '^[Ee]n'
+    if a:enr == ""
+	Xout "TODO: Add message number for:" a:emsg
+	let v:errmsg = ":" . v:errmsg
+    endif
+    let match = 1
+    if v:errmsg !~ '^'.a:enr.':' || (english && v:errmsg !~ a:emsg)
+	let match = 0
+	if v:errmsg == ""
+	    Xout "Message missing."
+	else
+	    let v:errmsg = escape(v:errmsg, '"')
+	    Xout "Unexpected message:" v:errmsg
+	endif
+    endif
+    return match
+endfunction
+
+while 1
+    try
+	try
+	    let caught = 0
+	    unlet novar
+	catch /^Vim(unlet):/
+	    let caught = 1
+	    let v:errmsg = substitute(v:exception, '^Vim(unlet):', '', "")
+	finally
+	    Xpath 1				" X: 1
+	    if !caught && !$VIMNOERRTHROW
+		Xpath 2				" X: 0
+	    endif
+	    if !MSG('E108', "No such variable")
+		Xpath 4				" X: 0
+	    endif
+	endtry
+    catch /.*/
+	Xpath 8					" X: 0
+	Xout v:exception "in" v:throwpoint
+    finally
+	break		" discard error for $VIMNOERRTHROW
+    endtry
+endwhile
+
+while 1
+    try
+	try
+	    let caught = 0
+	    throw novar			" error in :throw
+	catch /^Vim(throw):/
+	    let caught = 1
+	    let v:errmsg = substitute(v:exception, '^Vim(throw):', '', "")
+	finally
+	    Xpath 16				" X: 16
+	    if !caught && !$VIMNOERRTHROW
+		Xpath 32			" X: 0
+	    endif
+	    if caught ? !MSG('E121', "Undefined variable")
+			\ : !MSG('E15', "Invalid expression")
+		Xpath 64			" X: 0
+	    endif
+	endtry
+    catch /.*/
+	Xpath 128				" X: 0
+	Xout v:exception "in" v:throwpoint
+    finally
+	break		" discard error for $VIMNOERRTHROW
+    endtry
+endwhile
+
+while 1
+    try
+	try
+	    let caught = 0
+	    throw "Vim:faked"		" error: cannot fake Vim exception
+	catch /^Vim(throw):/
+	    let caught = 1
+	    let v:errmsg = substitute(v:exception, '^Vim(throw):', '', "")
+	finally
+	    Xpath 256				" X: 256
+	    if !caught && !$VIMNOERRTHROW
+		Xpath 512			" X: 0
+	    endif
+	    if !MSG('E608', "Cannot :throw exceptions with 'Vim' prefix")
+		Xpath 1024			" X: 0
+	    endif
+	endtry
+    catch /.*/
+	Xpath 2048				" X: 0
+	Xout v:exception "in" v:throwpoint
+    finally
+	break		" discard error for $VIMNOERRTHROW
+    endtry
+endwhile
+
+function! F()
+    while 1
+    " Missing :endwhile
+endfunction
+
+while 1
+    try
+	try
+	    let caught = 0
+	    call F()
+	catch /^Vim(endfunction):/
+	    let caught = 1
+	    let v:errmsg = substitute(v:exception, '^Vim(endfunction):', '', "")
+	finally
+	    Xpath 4096				" X: 4096
+	    if !caught && !$VIMNOERRTHROW
+		Xpath 8192			" X: 0
+	    endif
+	    if !MSG('E170', "Missing :endwhile")
+		Xpath 16384			" X: 0
+	    endif
+	endtry
+    catch /.*/
+	Xpath 32768				" X: 0
+	Xout v:exception "in" v:throwpoint
+    finally
+	break		" discard error for $VIMNOERRTHROW
+    endtry
+endwhile
+
+while 1
+    try
+	try
+	    let caught = 0
+	    ExecAsScript F
+	catch /^Vim:/
+	    let caught = 1
+	    let v:errmsg = substitute(v:exception, '^Vim:', '', "")
+	finally
+	    Xpath 65536				" X: 65536
+	    if !caught && !$VIMNOERRTHROW
+		Xpath 131072			" X: 0
+	    endif
+	    if !MSG('E170', "Missing :endwhile")
+		Xpath 262144			" X: 0
+	    endif
+	endtry
+    catch /.*/
+	Xpath 524288				" X: 0
+	Xout v:exception "in" v:throwpoint
+    finally
+	break		" discard error for $VIMNOERRTHROW
+    endtry
+endwhile
+
+function! G()
+    call G()
+endfunction
+
+while 1
+    try
+	let mfd_save = &mfd
+	set mfd=3
+	try
+	    let caught = 0
+	    call G()
+	catch /^Vim(call):/
+	    let caught = 1
+	    let v:errmsg = substitute(v:exception, '^Vim(call):', '', "")
+	finally
+	    Xpath 1048576			" X: 1048576
+	    if !caught && !$VIMNOERRTHROW
+		Xpath 2097152			" X: 0
+	    endif
+	    if !MSG('E132', "Function call depth is higher than 'maxfuncdepth'")
+		Xpath 4194304			" X: 0
+	    endif
+	endtry
+    catch /.*/
+	Xpath 8388608				" X: 0
+	Xout v:exception "in" v:throwpoint
+    finally
+	let &mfd = mfd_save
+	break		" discard error for $VIMNOERRTHROW
+    endtry
+endwhile
+
+function! H()
+    return H()
+endfunction
+
+while 1
+    try
+	let mfd_save = &mfd
+	set mfd=3
+	try
+	    let caught = 0
+	    call H()
+	catch /^Vim(return):/
+	    let caught = 1
+	    let v:errmsg = substitute(v:exception, '^Vim(return):', '', "")
+	finally
+	    Xpath 16777216			" X: 16777216
+	    if !caught && !$VIMNOERRTHROW
+		Xpath 33554432			" X: 0
+	    endif
+	    if !MSG('E132', "Function call depth is higher than 'maxfuncdepth'")
+		Xpath 67108864			" X: 0
+	    endif
+	endtry
+    catch /.*/
+	Xpath 134217728				" X: 0
+	Xout v:exception "in" v:throwpoint
+    finally
+	let &mfd = mfd_save
+	break		" discard error for $VIMNOERRTHROW
+    endtry
+endwhile
+
+unlet! caught mfd_save
+delfunction F
+delfunction G
+delfunction H
+Xpath 268435456					" X: 268435456
+
+Xcheck 286331153
+
+" Leave MSG() for the next test.
+
+
+"-------------------------------------------------------------------------------
+" Test 63:  Suppressing error exceptions by :silent!.			    {{{1
+"
+"	    A :silent! command inside a :try/:endtry region suppresses the
+"	    conversion of errors to an exception and the immediate abortion on
+"	    error.  When the commands executed by the :silent! themselves open
+"	    a new :try/:endtry region, conversion of errors to exception and
+"	    immediate abortion is switched on again - until the next :silent!
+"	    etc.  The :silent! has the effect of setting v:errmsg to the error
+"	    message text (without displaying it) and continuing with the next
+"	    script line.
+"
+"	    When a command triggering autocommands is executed by :silent!
+"	    inside a :try/:endtry, the autocommand execution is not suppressed
+"	    on error.
+"
+"	    This test reuses the function MSG() from the previous test.
+"-------------------------------------------------------------------------------
+
+XpathINIT
+
+XloopINIT! 1 4
+
+let taken = ""
+
+function! S(n) abort
+    XloopNEXT
+    let g:taken = g:taken . "E" . a:n
+    let v:errmsg = ""
+    exec "asdf" . a:n
+
+    " Check that ":silent!" continues:
+    Xloop 1
+
+    " Check that ":silent!" sets "v:errmsg":
+    if MSG('E492', "Not an editor command")
+	Xloop 2
+    endif
+endfunction
+
+function! Foo()
+    while 1
+	try
+	    try
+		let caught = 0
+		" This is not silent:
+		call S(3)				" X: 0 * 16
+	    catch /^Vim:/
+		let caught = 1
+		let errmsg3 = substitute(v:exception, '^Vim:', '', "")
+		silent! call S(4)			" X: 3 * 64
+	    finally
+		if !caught
+		    let errmsg3 = v:errmsg
+		    " Do call S(4) here if not executed in :catch.
+		    silent! call S(4)
+		endif
+		Xpath 1048576			" X: 1048576
+		if !caught && !$VIMNOERRTHROW
+		    Xpath 2097152		" X: 0
+		endif
+		let v:errmsg = errmsg3
+		if !MSG('E492', "Not an editor command")
+		    Xpath 4194304		" X: 0
+		endif
+		silent! call S(5)			" X: 3 * 256
+		" Break out of try conditionals that cover ":silent!".  This also
+		" discards the aborting error when $VIMNOERRTHROW is non-zero.
+		break
+	    endtry
+	catch /.*/
+	    Xpath 8388608			" X: 0
+	    Xout v:exception "in" v:throwpoint
+	endtry
+    endwhile
+    " This is a double ":silent!" (see caller).
+    silent! call S(6)					" X: 3 * 1024
+endfunction
+
+function! Bar()
+    try
+	silent! call S(2)				" X: 3 * 4
+							" X: 3 * 4096
+	silent! execute "call Foo() | call S(7)"
+	silent! call S(8)				" X: 3 * 16384
+    endtry	" normal end of try cond that covers ":silent!"
+    " This has a ":silent!" from the caller:
+    call S(9)						" X: 3 * 65536
+endfunction
+
+silent! call S(1)					" X: 3 * 1
+silent! call Bar()
+silent! call S(10)					" X: 3 * 262144
+
+let expected = "E1E2E3E4E5E6E7E8E9E10"
+if taken != expected
+    Xpath 16777216				" X: 0
+    Xout "'taken' is" taken "instead of" expected
+endif
+
+augroup TMP
+    autocmd BufWritePost * Xpath 33554432	" X: 33554432
+augroup END
+
+Xpath 67108864					" X: 67108864
+write /i/m/p/o/s/s/i/b/l/e
+Xpath 134217728					" X: 134217728
+
+autocmd! TMP
+unlet! caught errmsg3 taken expected
+delfunction S
+delfunction Foo
+delfunction Bar
+delfunction MSG
+
+Xcheck 236978127
+
+
+"-------------------------------------------------------------------------------
+" Test 64:  Error exceptions after error, interrupt or :throw		    {{{1
+"
+"	    When an error occurs after an interrupt or a :throw but before
+"	    a matching :catch is reached, all following :catches of that try
+"	    block are ignored, but the error exception can be caught by the next
+"	    surrounding try conditional.  Any previous error exception is
+"	    discarded.  An error is ignored when there is a previous error that
+"	    has not been caught.
+"-------------------------------------------------------------------------------
+
+XpathINIT
+
+if ExtraVim()
+
+    while 1
+	try
+	    try
+		Xpath 1				" X: 1
+		let caught = 0
+		while 1
+"		    if 1
+		    " Missing :endif
+		endwhile	" throw error exception
+	    catch /^Vim(/
+		let caught = 1
+	    finally
+		Xpath 2				" X: 2
+		if caught || $VIMNOERRTHROW
+		    Xpath 4			" X: 4
+		endif
+	    endtry
+	catch /.*/
+	    Xpath 8				" X: 0
+	    Xout v:exception "in" v:throwpoint
+	finally
+	    break		" discard error for $VIMNOERRTHROW
+	endtry
+    endwhile
+
+    while 1
+	try
+	    try
+		Xpath 16			" X: 16
+		let caught = 0
+		try
+"		    if 1
+		    " Missing :endif
+		catch /.*/	" throw error exception
+		    Xpath 32			" X: 0
+		catch /.*/
+		    Xpath 64			" X: 0
+		endtry
+	    catch /^Vim(/
+		let caught = 1
+	    finally
+		Xpath 128			" X: 128
+		if caught || $VIMNOERRTHROW
+		    Xpath 256			" X: 256
+		endif
+	    endtry
+	catch /.*/
+	    Xpath 512				" X: 0
+	    Xout v:exception "in" v:throwpoint
+	finally
+	    break		" discard error for $VIMNOERRTHROW
+	endtry
+    endwhile
+
+    while 1
+	try
+	    try
+		let caught = 0
+		try
+		    Xpath 1024			" X: 1024
+		    "INTERRUPT
+		catch /do_not_catch/
+		    Xpath 2048			" X: 0
+"		    if 1
+		    " Missing :endif
+		catch /.*/	" throw error exception
+		    Xpath 4096			" X: 0
+		catch /.*/
+		    Xpath 8192			" X: 0
+		endtry
+	    catch /^Vim(/
+		let caught = 1
+	    finally
+		Xpath 16384			" X: 16384
+		if caught || $VIMNOERRTHROW
+		    Xpath 32768			" X: 32768
+		endif
+	    endtry
+	catch /.*/
+	    Xpath 65536				" X: 0
+	    Xout v:exception "in" v:throwpoint
+	finally
+	    break		" discard error for $VIMNOERRTHROW
+	endtry
+    endwhile
+
+    while 1
+	try
+	    try
+		let caught = 0
+		try
+		    Xpath 131072		" X: 131072
+		    throw "x"
+		catch /do_not_catch/
+		    Xpath 262144		" X: 0
+"		    if 1
+		    " Missing :endif
+		catch /x/	" throw error exception
+		    Xpath 524288		" X: 0
+		catch /.*/
+		   Xpath 1048576		" X: 0
+		endtry
+	    catch /^Vim(/
+		let caught = 1
+	    finally
+		Xpath 2097152			" X: 2097152
+		if caught || $VIMNOERRTHROW
+		    Xpath 4194304		" X: 4194304
+		endif
+	    endtry
+	catch /.*/
+	    Xpath 8388608			" X: 0
+	    Xout v:exception "in" v:throwpoint
+	finally
+	    break		" discard error for $VIMNOERRTHROW
+	endtry
+    endwhile
+
+    while 1
+	try
+	    try
+		let caught = 0
+		Xpath 16777216			" X: 16777216
+"		endif		" :endif without :if; throw error exception
+"		if 1
+		" Missing :endif
+	    catch /do_not_catch/ " ignore new error
+		Xpath 33554432			" X: 0
+	    catch /^Vim(endif):/
+		let caught = 1
+	    catch /^Vim(/
+		Xpath 67108864			" X: 0
+	    finally
+		Xpath 134217728			" X: 134217728
+		if caught || $VIMNOERRTHROW
+		    Xpath 268435456		" X: 268435456
+		endif
+	    endtry
+	catch /.*/
+	    Xpath 536870912			" X: 0
+	    Xout v:exception "in" v:throwpoint
+	finally
+	    break		" discard error for $VIMNOERRTHROW
+	endtry
+    endwhile
+
+    Xpath 1073741824				" X: 1073741824
+
+endif
+
+Xcheck 1499645335
+
+
+"-------------------------------------------------------------------------------
+" Test 65:  Errors in the /pattern/ argument of a :catch		    {{{1
+"
+"	    On an error in the /pattern/ argument of a :catch, the :catch does
+"	    not match.  Any following :catches of the same :try/:endtry don't
+"	    match either.  Finally clauses are executed.
+"-------------------------------------------------------------------------------
+
+XpathINIT
+
+function! MSG(enr, emsg)
+    let english = v:lang == "C" || v:lang =~ '^[Ee]n'
+    if a:enr == ""
+	Xout "TODO: Add message number for:" a:emsg
+	let v:errmsg = ":" . v:errmsg
+    endif
+    let match = 1
+    if v:errmsg !~ '^'.a:enr.':' || (english && v:errmsg !~ a:emsg)
+	let match = 0
+	if v:errmsg == ""
+	    Xout "Message missing."
+	else
+	    let v:errmsg = escape(v:errmsg, '"')
+	    Xout "Unexpected message:" v:errmsg
+	endif
+    endif
+    return match
+endfunction
+
+try
+    try
+	Xpath 1					" X: 1
+	throw "oops"
+    catch /^oops$/
+	Xpath 2					" X: 2
+    catch /\)/		" not checked; exception has already been caught
+	Xpath 4					" X: 0
+    endtry
+    Xpath 8					" X: 8
+catch /.*/
+    Xpath 16					" X: 0
+    Xout v:exception "in" v:throwpoint
+endtry
+
+function! F()
+    try
+	let caught = 0
+	try
+	    try
+		Xpath 32			" X: 32
+		throw "ab"
+	    catch /abc/	" does not catch
+		Xpath 64			" X: 0
+	    catch /\)/	" error; discards exception
+		Xpath 128			" X: 0
+	    catch /.*/	" not checked
+		Xpath 256			" X: 0
+	    finally
+		Xpath 512			" X: 512
+	    endtry
+	    Xpath 1024				" X: 0
+	catch /^ab$/	" checked, but original exception is discarded
+	    Xpath 2048				" X: 0
+	catch /^Vim(catch):/
+	    let caught = 1
+	    let v:errmsg = substitute(v:exception, '^Vim(catch):', '', "")
+	finally
+	    Xpath 4096				" X: 4096
+	    if !caught && !$VIMNOERRTHROW
+		Xpath 8192			" X: 0
+	    endif
+	    if caught ? !MSG('E55', 'Unmatched \\)')
+			\ : !MSG('E475', "Invalid argument")
+		Xpath 16384			" X: 0
+	    endif
+	    if !caught
+		return	| " discard error
+	    endif
+	endtry
+    catch /.*/
+	Xpath 32768				" X: 0
+	Xout v:exception "in" v:throwpoint
+    endtry
+endfunction
+
+call F()
+Xpath 65536					" X: 65536
+
+delfunction MSG
+delfunction F
+unlet! caught
+
+Xcheck 70187
+
+
+"-------------------------------------------------------------------------------
+" Test 66:  Stop range :call on error, interrupt, or :throw		    {{{1
+"
+"	    When a function which is multiply called for a range since it
+"	    doesn't handle the range itself has an error in a command
+"	    dynamically enclosed by :try/:endtry or gets an interrupt or
+"	    executes a :throw, no more calls for the remaining lines in the
+"	    range are made.  On an error in a command not dynamically enclosed
+"	    by :try/:endtry, the function is executed again for the remaining
+"	    lines in the range.
+"-------------------------------------------------------------------------------
+
+XpathINIT
+
+if ExtraVim()
+
+    let file = tempname()
+    exec "edit" file
+
+    insert
+line 1
+line 2
+line 3
+.
+
+    XloopINIT! 1 2
+
+    let taken = ""
+    let expected = "G1EF1E(1)F1E(2)F1E(3)G2EF2E(1)G3IF3I(1)G4TF4T(1)G5AF5A(1)"
+
+    function! F(reason, n) abort
+	let g:taken = g:taken . "F" . a:n .
+	    \ substitute(a:reason, '\(\l\).*', '\u\1', "") .
+	    \ "(" . line(".") . ")"
+
+	if a:reason == "error"
+	    asdf
+	elseif a:reason == "interrupt"
+	    "INTERRUPT
+	    let dummy = 0
+	elseif a:reason == "throw"
+	    throw "xyz"
+	elseif a:reason == "aborting error"
+	    XloopNEXT
+	    if g:taken != g:expected
+		Xloop 1				" X: 0
+		Xout "'taken' is" g:taken "instead of" g:expected
+	    endif
+	    try
+		bwipeout!
+		call delete(file)
+		asdf
+	    endtry
+	endif
+    endfunction
+
+    function! G(reason, n)
+	let g:taken = g:taken . "G" . a:n .
+	    \ substitute(a:reason, '\(\l\).*', '\u\1', "")
+	1,3call F(a:reason, a:n)
+    endfunction
+
+    Xpath 8					" X: 8
+    call G("error", 1)
+    try
+	Xpath 16				" X: 16
+	try
+	    call G("error", 2)
+	    Xpath 32				" X: 0
+	finally
+	    Xpath 64				" X: 64
+	    try
+		call G("interrupt", 3)
+		Xpath 128			" X: 0
+	    finally
+		Xpath 256			" X: 256
+		try
+		    call G("throw", 4)
+		    Xpath 512			" X: 0
+		endtry
+	    endtry
+	endtry
+    catch /xyz/
+	Xpath 1024				" X: 1024
+    catch /.*/
+	Xpath 2048				" X: 0
+	Xout v:exception "in" ExtraVimThrowpoint()
+    endtry
+    Xpath 4096					" X: 4096
+    call G("aborting error", 5)
+    Xpath 8192					" X: 0
+    Xout "'taken' is" taken "instead of" expected
+
+endif
+
+Xcheck 5464
+
+
+"-------------------------------------------------------------------------------
+" Test 67:  :throw across :call command					    {{{1
+"
+"	    On a call command, an exception might be thrown when evaluating the
+"	    function name, during evaluation of the arguments, or when the
+"	    function is being executed.  The exception can be caught by the
+"	    caller.
+"-------------------------------------------------------------------------------
+
+XpathINIT
+
+function! THROW(x, n)
+    if a:n == 1
+	Xpath 1						" X: 1
+    elseif a:n == 2
+	Xpath 2						" X: 2
+    elseif a:n == 3
+	Xpath 4						" X: 4
+    endif
+    throw a:x
+endfunction
+
+function! NAME(x, n)
+    if a:n == 1
+	Xpath 8						" X: 0
+    elseif a:n == 2
+	Xpath 16					" X: 16
+    elseif a:n == 3
+	Xpath 32					" X: 32
+    elseif a:n == 4
+	Xpath 64					" X: 64
+    endif
+    return a:x
+endfunction
+
+function! ARG(x, n)
+    if a:n == 1
+	Xpath 128					" X: 0
+    elseif a:n == 2
+	Xpath 256					" X: 0
+    elseif a:n == 3
+	Xpath 512					" X: 512
+    elseif a:n == 4
+	Xpath 1024					" X: 1024
+    endif
+    return a:x
+endfunction
+
+function! F(x, n)
+    if a:n == 2
+	Xpath 2048					" X: 0
+    elseif a:n == 4
+	Xpath 4096					" X: 4096
+    endif
+endfunction
+
+while 1
+    try
+	let error = 0
+	let v:errmsg = ""
+
+	while 1
+	    try
+		Xpath 8192				" X: 8192
+		call {NAME(THROW("name", 1), 1)}(ARG(4711, 1), 1)
+		Xpath 16384				" X: 0
+	    catch /^name$/
+		Xpath 32768				" X: 32768
+	    catch /.*/
+		let error = 1
+		Xout "1:" v:exception "in" v:throwpoint
+	    finally
+		if !error && $VIMNOERRTHROW && v:errmsg != ""
+		    let error = 1
+		    Xout "1:" v:errmsg
+		endif
+		if error
+		    Xpath 65536				" X: 0
+		endif
+		let error = 0
+		let v:errmsg = ""
+		break		" discard error for $VIMNOERRTHROW
+	    endtry
+	endwhile
+
+	while 1
+	    try
+		Xpath 131072				" X: 131072
+		call {NAME("F", 2)}(ARG(THROW("arg", 2), 2), 2)
+		Xpath 262144				" X: 0
+	    catch /^arg$/
+		Xpath 524288				" X: 524288
+	    catch /.*/
+		let error = 1
+		Xout "2:" v:exception "in" v:throwpoint
+	    finally
+		if !error && $VIMNOERRTHROW && v:errmsg != ""
+		    let error = 1
+		    Xout "2:" v:errmsg
+		endif
+		if error
+		    Xpath 1048576			" X: 0
+		endif
+		let error = 0
+		let v:errmsg = ""
+		break		" discard error for $VIMNOERRTHROW
+	    endtry
+	endwhile
+
+	while 1
+	    try
+		Xpath 2097152				" X: 2097152
+		call {NAME("THROW", 3)}(ARG("call", 3), 3)
+		Xpath 4194304				" X: 0
+	    catch /^call$/
+		Xpath 8388608				" X: 8388608
+	    catch /^0$/	    " default return value
+		Xpath 16777216				" X: 0
+		Xout "3:" v:throwpoint
+	    catch /.*/
+		let error = 1
+		Xout "3:" v:exception "in" v:throwpoint
+	    finally
+		if !error && $VIMNOERRTHROW && v:errmsg != ""
+		    let error = 1
+		    Xout "3:" v:errmsg
+		endif
+		if error
+		    Xpath 33554432			" X: 0
+		endif
+		let error = 0
+		let v:errmsg = ""
+		break		" discard error for $VIMNOERRTHROW
+	    endtry
+	endwhile
+
+	while 1
+	    try
+		Xpath 67108864				" X: 67108864
+		call {NAME("F", 4)}(ARG(4711, 4), 4)
+		Xpath 134217728				" X: 134217728
+	    catch /.*/
+		let error = 1
+		Xout "4:" v:exception "in" v:throwpoint
+	    finally
+		if !error && $VIMNOERRTHROW && v:errmsg != ""
+		    let error = 1
+		    Xout "4:" v:errmsg
+		endif
+		if error
+		    Xpath 268435456			" X: 0
+		endif
+		let error = 0
+		let v:errmsg = ""
+		break		" discard error for $VIMNOERRTHROW
+	    endtry
+	endwhile
+
+    catch /^0$/	    " default return value
+	Xpath 536870912					" X: 0
+	Xout v:throwpoint
+    catch /.*/
+	let error = 1
+	Xout v:exception "in" v:throwpoint
+    finally
+	if !error && $VIMNOERRTHROW && v:errmsg != ""
+	    let error = 1
+	    Xout v:errmsg
+	endif
+	if error
+	    Xpath 1073741824				" X: 0
+	endif
+	break		" discard error for $VIMNOERRTHROW
+    endtry
+endwhile
+
+unlet error
+delfunction F
+
+Xcheck 212514423
+
+" Leave THROW(), NAME(), and ARG() for the next test.
+
+
+"-------------------------------------------------------------------------------
+" Test 68:  :throw across function calls in expressions			    {{{1
+"
+"	    On a function call within an expression, an exception might be
+"	    thrown when evaluating the function name, during evaluation of the
+"	    arguments, or when the function is being executed.  The exception
+"	    can be caught by the caller.
+"
+"	    This test reuses the functions THROW(), NAME(), and ARG() from the
+"	    previous test.
+"-------------------------------------------------------------------------------
+
+XpathINIT
+
+function! F(x, n)
+    if a:n == 2
+	Xpath 2048					" X: 0
+    elseif a:n == 4
+	Xpath 4096					" X: 4096
+    endif
+    return a:x
+endfunction
+
+unlet! var1 var2 var3 var4
+
+while 1
+    try
+	let error = 0
+	let v:errmsg = ""
+
+	while 1
+	    try
+		Xpath 8192				" X: 8192
+		let var1 = {NAME(THROW("name", 1), 1)}(ARG(4711, 1), 1)
+		Xpath 16384				" X: 0
+	    catch /^name$/
+		Xpath 32768				" X: 32768
+	    catch /.*/
+		let error = 1
+		Xout "1:" v:exception "in" v:throwpoint
+	    finally
+		if !error && $VIMNOERRTHROW && v:errmsg != ""
+		    let error = 1
+		    Xout "1:" v:errmsg
+		endif
+		if error
+		    Xpath 65536				" X: 0
+		endif
+		let error = 0
+		let v:errmsg = ""
+		break		" discard error for $VIMNOERRTHROW
+	    endtry
+	endwhile
+
+	while 1
+	    try
+		Xpath 131072				" X: 131072
+		let var2 = {NAME("F", 2)}(ARG(THROW("arg", 2), 2), 2)
+		Xpath 262144				" X: 0
+	    catch /^arg$/
+		Xpath 524288				" X: 524288
+	    catch /.*/
+		let error = 1
+		Xout "2:" v:exception "in" v:throwpoint
+	    finally
+		if !error && $VIMNOERRTHROW && v:errmsg != ""
+		    let error = 1
+		    Xout "2:" v:errmsg
+		endif
+		if error
+		    Xpath 1048576			" X: 0
+		endif
+		let error = 0
+		let v:errmsg = ""
+		break		" discard error for $VIMNOERRTHROW
+	    endtry
+	endwhile
+
+	while 1
+	    try
+		Xpath 2097152				" X: 2097152
+		let var3 = {NAME("THROW", 3)}(ARG("call", 3), 3)
+		Xpath 4194304				" X: 0
+	    catch /^call$/
+		Xpath 8388608				" X: 8388608
+	    catch /^0$/	    " default return value
+		Xpath 16777216				" X: 0
+		Xout "3:" v:throwpoint
+	    catch /.*/
+		let error = 1
+		Xout "3:" v:exception "in" v:throwpoint
+	    finally
+		if !error && $VIMNOERRTHROW && v:errmsg != ""
+		    let error = 1
+		    Xout "3:" v:errmsg
+		endif
+		if error
+		    Xpath 33554432			" X: 0
+		endif
+		let error = 0
+		let v:errmsg = ""
+		break		" discard error for $VIMNOERRTHROW
+	    endtry
+	endwhile
+
+	while 1
+	    try
+		Xpath 67108864				" X: 67108864
+		let var4 = {NAME("F", 4)}(ARG(4711, 4), 4)
+		Xpath 134217728				" X: 134217728
+	    catch /.*/
+		let error = 1
+		Xout "4:" v:exception "in" v:throwpoint
+	    finally
+		if !error && $VIMNOERRTHROW && v:errmsg != ""
+		    let error = 1
+		    Xout "4:" v:errmsg
+		endif
+		if error
+		    Xpath 268435456			" X: 0
+		endif
+		let error = 0
+		let v:errmsg = ""
+		break		" discard error for $VIMNOERRTHROW
+	    endtry
+	endwhile
+
+    catch /^0$/	    " default return value
+	Xpath 536870912					" X: 0
+	Xout v:throwpoint
+    catch /.*/
+	let error = 1
+	Xout v:exception "in" v:throwpoint
+    finally
+	if !error && $VIMNOERRTHROW && v:errmsg != ""
+	    let error = 1
+	    Xout v:errmsg
+	endif
+	if error
+	    Xpath 1073741824				" X: 0
+	endif
+	break		" discard error for $VIMNOERRTHROW
+    endtry
+endwhile
+
+if exists("var1") || exists("var2") || exists("var3") ||
+	    \ !exists("var4") || var4 != 4711
+    " The Xpath command does not accept 2^31 (negative); add explicitly:
+    let Xpath = Xpath + 2147483648			" X: 0
+    if exists("var1")
+	Xout "var1 =" var1
+    endif
+    if exists("var2")
+	Xout "var2 =" var2
+    endif
+    if exists("var3")
+	Xout "var3 =" var3
+    endif
+    if !exists("var4")
+	Xout "var4 unset"
+    elseif var4 != 4711
+	Xout "var4 =" var4
+    endif
+endif
+
+unlet! error var1 var2 var3 var4
+delfunction THROW
+delfunction NAME
+delfunction ARG
+delfunction F
+
+Xcheck 212514423
+
+
+"-------------------------------------------------------------------------------
+" Test 69:  :throw across :if, :elseif, :while				    {{{1
+"
+"	    On an :if, :elseif, or :while command, an exception might be thrown
+"	    during evaluation of the expression to test.  The exception can be
+"	    caught by the script.
+"-------------------------------------------------------------------------------
+
+XpathINIT
+
+XloopINIT! 1 2
+
+function! THROW(x)
+    XloopNEXT
+    Xloop 1					" X: 1 + 2 + 4
+    throw a:x
+endfunction
+
+try
+
+    try
+	Xpath 8					" X: 8
+	if 4711 == THROW("if") + 111
+	    Xpath 16				" X: 0
+	else
+	    Xpath 32				" X: 0
+	endif
+	Xpath 64				" X: 0
+    catch /^if$/
+	Xpath 128				" X: 128
+    catch /.*/
+	Xpath 256				" X: 0
+	Xout "if:" v:exception "in" v:throwpoint
+    endtry
+
+    try
+	Xpath 512				" X: 512
+	if 4711 == 4 + 7 + 1 + 1
+	    Xpath 1024				" X: 0
+	elseif 4711 == THROW("elseif") + 222
+	    Xpath 2048				" X: 0
+	else
+	    Xpath 4096				" X: 0
+	endif
+	Xpath 8192				" X: 0
+    catch /^elseif$/
+	Xpath 16384				" X: 16384
+    catch /.*/
+	Xpath 32768				" X: 0
+	Xout "elseif:" v:exception "in" v:throwpoint
+    endtry
+
+    try
+	Xpath 65536				" X: 65536
+	while 4711 == THROW("while") + 4711
+	    Xpath 131072			" X: 0
+	    break
+	endwhile
+	Xpath 262144				" X: 0
+    catch /^while$/
+	Xpath 524288				" X: 524288
+    catch /.*/
+	Xpath 1048576				" X: 0
+	Xout "while:" v:exception "in" v:throwpoint
+    endtry
+
+catch /^0$/	    " default return value
+    Xpath 2097152				" X: 0
+    Xout v:throwpoint
+catch /.*/
+    Xout v:exception "in" v:throwpoint
+    Xpath 4194304				" X: 0
+endtry
+
+Xpath 8388608					" X: 8388608
+
+delfunction THROW
+
+Xcheck 8995471
+
+
+"-------------------------------------------------------------------------------
+" Test 70:  :throw across :return or :throw				    {{{1
+"
+"	    On a :return or :throw command, an exception might be thrown during
+"	    evaluation of the expression to return or throw, respectively.  The
+"	    exception can be caught by the script.
+"-------------------------------------------------------------------------------
+
+XpathINIT
+
+let taken = ""
+
+function! THROW(x, n)
+    let g:taken = g:taken . "T" . a:n
+    throw a:x
+endfunction
+
+function! F(x, y, n)
+    let g:taken = g:taken . "F" . a:n
+    return a:x + THROW(a:y, a:n)
+endfunction
+
+function! G(x, y, n)
+    let g:taken = g:taken . "G" . a:n
+    throw a:x . THROW(a:y, a:n)
+    return a:x
+endfunction
+
+try
+    try
+	Xpath 1					" X: 1
+	call F(4711, "return", 1)
+	Xpath 2					" X: 0
+    catch /^return$/
+	Xpath 4					" X: 4
+    catch /.*/
+	Xpath 8					" X: 0
+	Xout "return:" v:exception "in" v:throwpoint
+    endtry
+
+    try
+	Xpath 16				" X: 16
+	let var = F(4712, "return-var", 2)
+	Xpath 32				" X: 0
+    catch /^return-var$/
+	Xpath 64				" X: 64
+    catch /.*/
+	Xpath 128				" X: 0
+	Xout "return-var:" v:exception "in" v:throwpoint
+    finally
+	unlet! var
+    endtry
+
+    try
+	Xpath 256				" X: 256
+	throw "except1" . THROW("throw1", 3)
+	Xpath 512				" X: 0
+    catch /^except1/
+	Xpath 1024				" X: 0
+    catch /^throw1$/
+	Xpath 2048				" X: 2048
+    catch /.*/
+	Xpath 4096				" X: 0
+	Xout "throw1:" v:exception "in" v:throwpoint
+    endtry
+
+    try
+	Xpath 8192				" X: 8192
+	call G("except2", "throw2", 4)
+	Xpath 16384				" X: 0
+    catch /^except2/
+	Xpath 32768				" X: 0
+    catch /^throw2$/
+	Xpath 65536				" X: 65536
+    catch /.*/
+	Xpath 131072				" X: 0
+	Xout "throw2:" v:exception "in" v:throwpoint
+    endtry
+
+    try
+	Xpath 262144				" X: 262144
+	let var = G("except3", "throw3", 5)
+	Xpath 524288				" X: 0
+    catch /^except3/
+	Xpath 1048576				" X: 0
+    catch /^throw3$/
+	Xpath 2097152				" X: 2097152
+    catch /.*/
+	Xpath 4194304				" X: 0
+	Xout "throw3:" v:exception "in" v:throwpoint
+    finally
+	unlet! var
+    endtry
+
+    let expected = "F1T1F2T2T3G4T4G5T5"
+    if taken != expected
+	Xpath 8388608				" X: 0
+	Xout "'taken' is" taken "instead of" expected
+    endif
+
+catch /^0$/	    " default return value
+    Xpath 16777216				" X: 0
+    Xout v:throwpoint
+catch /.*/
+    Xpath 33554432				" X: 0
+    Xout v:exception "in" v:throwpoint
+endtry
+
+Xpath 67108864					" X: 67108864
+
+unlet taken expected
+delfunction THROW
+delfunction F
+delfunction G
+
+Xcheck 69544277
+
+
+"-------------------------------------------------------------------------------
+" Test 71:  :throw across :echo variants and :execute			    {{{1
+"
+"	    On an :echo, :echon, :echomsg, :echoerr, or :execute command, an
+"	    exception might be thrown during evaluation of the arguments to
+"	    be displayed or executed as a command, respectively.  Any following
+"	    arguments are not evaluated, then.  The exception can be caught by
+"	    the script.
+"-------------------------------------------------------------------------------
+
+XpathINIT
+
+let taken = ""
+
+function! THROW(x, n)
+    let g:taken = g:taken . "T" . a:n
+    throw a:x
+endfunction
+
+function! F(n)
+    let g:taken = g:taken . "F" . a:n
+    return "F" . a:n
+endfunction
+
+try
+    try
+	Xpath 1					" X: 1
+	echo "echo" . THROW("echo-except", 1) F(1)
+	Xpath 2					" X: 0
+    catch /^echo-except$/
+	Xpath 4					" X: 4
+    catch /.*/
+	Xpath 8					" X: 0
+	Xout "echo:" v:exception "in" v:throwpoint
+    endtry
+
+    try
+	Xpath 16				" X: 16
+	echon "echon" . THROW("echon-except", 2) F(2)
+	Xpath 32				" X: 0
+    catch /^echon-except$/
+	Xpath 64				" X: 64
+    catch /.*/
+	Xpath 128				" X: 0
+	Xout "echon:" v:exception "in" v:throwpoint
+    endtry
+
+    try
+	Xpath 256				" X: 256
+	echomsg "echomsg" . THROW("echomsg-except", 3) F(3)
+	Xpath 512				" X: 0
+    catch /^echomsg-except$/
+	Xpath 1024				" X: 1024
+    catch /.*/
+	Xpath 2048				" X: 0
+	Xout "echomsg:" v:exception "in" v:throwpoint
+    endtry
+
+    try
+	Xpath 4096				" X: 4096
+	echoerr "echoerr" . THROW("echoerr-except", 4) F(4)
+	Xpath 8192				" X: 0
+    catch /^echoerr-except$/
+	Xpath 16384				" X: 16384
+    catch /Vim/
+	Xpath 32768				" X: 0
+    catch /echoerr/
+	Xpath 65536				" X: 0
+    catch /.*/
+	Xpath 131072				" X: 0
+	Xout "echoerr:" v:exception "in" v:throwpoint
+    endtry
+
+    try
+	Xpath 262144				" X: 262144
+	execute "echo 'execute" . THROW("execute-except", 5) F(5) "'"
+	Xpath 524288				" X: 0
+    catch /^execute-except$/
+	Xpath 1048576				" X: 1048576
+    catch /.*/
+	Xpath 2097152				" X: 0
+	Xout "execute:" v:exception "in" v:throwpoint
+    endtry
+
+    let expected = "T1T2T3T4T5"
+    if taken != expected
+	Xpath 4194304				" X: 0
+	Xout "'taken' is" taken "instead of" expected
+    endif
+
+catch /^0$/	    " default return value
+    Xpath 8388608				" X: 0
+    Xout v:throwpoint
+catch /.*/
+    Xpath 16777216				" X: 0
+    Xout v:exception "in" v:throwpoint
+endtry
+
+Xpath 33554432					" X: 33554432
+
+unlet taken expected
+delfunction THROW
+delfunction F
+
+Xcheck 34886997
+
+
+"-------------------------------------------------------------------------------
+" Test 72:  :throw across :let or :unlet				    {{{1
+"
+"	    On a :let command, an exception might be thrown during evaluation
+"	    of the expression to assign.  On an :let or :unlet command, the
+"	    evaluation of the name of the variable to be assigned or list or
+"	    deleted, respectively, may throw an exception.  Any following
+"	    arguments are not evaluated, then.  The exception can be caught by
+"	    the script.
+"-------------------------------------------------------------------------------
+
+XpathINIT
+
+let throwcount = 0
+
+function! THROW(x)
+    let g:throwcount = g:throwcount + 1
+    throw a:x
+endfunction
+
+try
+    try
+	let $VAR = "old_value"
+	Xpath 1					" X: 1
+	let $VAR = "let(" . THROW("var") . ")"
+	Xpath 2					" X: 0
+    catch /^var$/
+	Xpath 4					" X: 4
+    finally
+	if $VAR != "old_value"
+	    Xpath 8				" X: 0
+	endif
+    endtry
+
+    try
+	let @a = "old_value"
+	Xpath 16				" X: 16
+	let @a = "let(" . THROW("reg") . ")"
+	Xpath 32				" X: 0
+    catch /^reg$/
+	try
+	    Xpath 64				" X: 64
+	    let @A = "let(" . THROW("REG") . ")"
+	    Xpath 128				" X: 0
+	catch /^REG$/
+	    Xpath 256				" X: 256
+	endtry
+    finally
+	if @a != "old_value"
+	    Xpath 512				" X: 0
+	endif
+	if @A != "old_value"
+	    Xpath 1024				" X: 0
+	endif
+    endtry
+
+    try
+	let saved_gpath = &g:path
+	let saved_lpath = &l:path
+	Xpath 2048				" X: 2048
+	let &path = "let(" . THROW("opt") . ")"
+	Xpath 4096				" X: 0
+    catch /^opt$/
+	try
+	    Xpath 8192				" X: 8192
+	    let &g:path = "let(" . THROW("gopt") . ")"
+	    Xpath 16384				" X: 0
+	catch /^gopt$/
+	    try
+		Xpath 32768			" X: 32768
+		let &l:path = "let(" . THROW("lopt") . ")"
+		Xpath 65536			" X: 0
+	    catch /^lopt$/
+		Xpath 131072			" X: 131072
+	    endtry
+	endtry
+    finally
+	if &g:path != saved_gpath || &l:path != saved_lpath
+	    Xpath 262144			" X: 0
+	endif
+	let &g:path = saved_gpath
+	let &l:path = saved_lpath
+    endtry
+
+    unlet! var1 var2 var3
+
+    try
+	Xpath 524288				" X: 524288
+	let var1 = "let(" . THROW("var1") . ")"
+	Xpath 1048576				" X: 0
+    catch /^var1$/
+	Xpath 2097152				" X: 2097152
+    finally
+	if exists("var1")
+	    Xpath 4194304			" X: 0
+	endif
+    endtry
+
+    try
+	let var2 = "old_value"
+	Xpath 8388608				" X: 8388608
+	let var2 = "let(" . THROW("var2"). ")"
+	Xpath 16777216				" X: 0
+    catch /^var2$/
+	Xpath 33554432				" X: 33554432
+    finally
+	if var2 != "old_value"
+	    Xpath 67108864			" X: 0
+	endif
+    endtry
+
+    try
+	Xpath 134217728				" X: 134217728
+	let var{THROW("var3")} = 4711
+	Xpath 268435456				" X: 0
+    catch /^var3$/
+	Xpath 536870912				" X: 536870912
+    endtry
+
+    let addpath = ""
+
+    function ADDPATH(p)
+	let g:addpath = g:addpath . a:p
+    endfunction
+
+    try
+	call ADDPATH("T1")
+	let var{THROW("var4")} var{ADDPATH("T2")} | call ADDPATH("T3")
+	call ADDPATH("T4")
+    catch /^var4$/
+	call ADDPATH("T5")
+    endtry
+
+    try
+	call ADDPATH("T6")
+	unlet var{THROW("var5")} var{ADDPATH("T7")} | call ADDPATH("T8")
+	call ADDPATH("T9")
+    catch /^var5$/
+	call ADDPATH("T10")
+    endtry
+
+    if addpath != "T1T5T6T10" || throwcount != 11
+	throw "addpath: " . addpath . ", throwcount: " . throwcount
+    endif
+
+    Xpath 1073741824				" X: 1073741824
+
+catch /.*/
+    " The Xpath command does not accept 2^31 (negative); add explicitly:
+    let Xpath = Xpath + 2147483648		" X: 0
+    Xout v:exception "in" v:throwpoint
+endtry
+
+unlet! var1 var2 var3 addpath throwcount
+delfunction THROW
+
+Xcheck 1789569365
+
+
+"-------------------------------------------------------------------------------
+" Test 73:  :throw across :function, :delfunction			    {{{1
+"
+"	    The :function and :delfunction commands may cause an expression
+"	    specified in braces to be evaluated.  During evaluation, an
+"	    exception might be thrown.  The exception can be caught by the
+"	    script.
+"-------------------------------------------------------------------------------
+
+XpathINIT
+
+let taken = ""
+
+function! THROW(x, n)
+    let g:taken = g:taken . "T" . a:n
+    throw a:x
+endfunction
+
+function! EXPR(x, n)
+    let g:taken = g:taken . "E" . a:n
+    if a:n % 2 == 0
+	call THROW(a:x, a:n)
+    endif
+    return 2 - a:n % 2
+endfunction
+
+try
+    try
+	" Define function.
+	Xpath 1					" X: 1
+	function! F0()
+	endfunction
+	Xpath 2					" X: 2
+	function! F{EXPR("function-def-ok", 1)}()
+	endfunction
+	Xpath 4					" X: 4
+	function! F{EXPR("function-def", 2)}()
+	endfunction
+	Xpath 8					" X: 0
+    catch /^function-def-ok$/
+	Xpath 16				" X: 0
+    catch /^function-def$/
+	Xpath 32				" X: 32
+    catch /.*/
+	Xpath 64				" X: 0
+	Xout "def:" v:exception "in" v:throwpoint
+    endtry
+
+    try
+	" List function.
+	Xpath 128				" X: 128
+	function F0
+	Xpath 256				" X: 256
+	function F{EXPR("function-lst-ok", 3)}
+	Xpath 512				" X: 512
+	function F{EXPR("function-lst", 4)}
+	Xpath 1024				" X: 0
+    catch /^function-lst-ok$/
+	Xpath 2048				" X: 0
+    catch /^function-lst$/
+	Xpath 4096				" X: 4096
+    catch /.*/
+	Xpath 8192				" X: 0
+	Xout "lst:" v:exception "in" v:throwpoint
+    endtry
+
+    try
+	" Delete function
+	Xpath 16384				" X: 16384
+	delfunction F0
+	Xpath 32768				" X: 32768
+	delfunction F{EXPR("function-del-ok", 5)}
+	Xpath 65536				" X: 65536
+	delfunction F{EXPR("function-del", 6)}
+	Xpath 131072				" X: 0
+    catch /^function-del-ok$/
+	Xpath 262144				" X: 0
+    catch /^function-del$/
+	Xpath 524288				" X: 524288
+    catch /.*/
+	Xpath 1048576				" X: 0
+	Xout "del:" v:exception "in" v:throwpoint
+    endtry
+
+    let expected = "E1E2T2E3E4T4E5E6T6"
+    if taken != expected
+	Xpath 2097152				" X: 0
+	Xout "'taken' is" taken "instead of" expected
+    endif
+
+catch /.*/
+    Xpath 4194304				" X: 0
+    Xout v:exception "in" v:throwpoint
+endtry
+
+Xpath 8388608					" X: 8388608
+
+unlet taken expected
+delfunction THROW
+delfunction EXPR
+
+Xcheck 9032615
+
+
+"-------------------------------------------------------------------------------
+" Test 74:  :throw across builtin functions and commands		    {{{1
+"
+"	    Some functions like exists(), searchpair() take expression
+"	    arguments, other functions or commands like substitute() or
+"	    :substitute cause an expression (specified in the regular
+"	    expression) to be evaluated.  During evaluation an exception
+"	    might be thrown.  The exception can be caught by the script.
+"-------------------------------------------------------------------------------
+
+XpathINIT
+
+let taken = ""
+
+function! THROW(x, n)
+    let g:taken = g:taken . "T" . a:n
+    throw a:x
+endfunction
+
+function! EXPR(x, n)
+    let g:taken = g:taken . "E" . a:n
+    call THROW(a:x . a:n, a:n)
+    return "EXPR"
+endfunction
+
+function! SKIP(x, n)
+    let g:taken = g:taken . "S" . a:n . "(" . line(".")
+    let theline = getline(".")
+    if theline =~ "skip"
+	let g:taken = g:taken . "s)"
+	return 1
+    elseif theline =~ "throw"
+	let g:taken = g:taken . "t)"
+	call THROW(a:x . a:n, a:n)
+    else
+	let g:taken = g:taken . ")"
+	return 0
+    endif
+endfunction
+
+function! SUBST(x, n)
+    let g:taken = g:taken . "U" . a:n . "(" . line(".")
+    let theline = getline(".")
+    if theline =~ "not"	    " SUBST() should not be called for this line
+	let g:taken = g:taken . "n)"
+	call THROW(a:x . a:n, a:n)
+    elseif theline =~ "throw"
+	let g:taken = g:taken . "t)"
+	call THROW(a:x . a:n, a:n)
+    else
+	let g:taken = g:taken . ")"
+	return "replaced"
+    endif
+endfunction
+
+try
+    try
+	Xpath 1					" X: 1
+	let result = exists('*{EXPR("exists", 1)}')
+	Xpath 2					" X: 0
+    catch /^exists1$/
+	Xpath 4					" X: 4
+	try
+	    let result = exists('{EXPR("exists", 2)}')
+	    Xpath 8				" X: 0
+	catch /^exists2$/
+	    Xpath 16				" X: 16
+	catch /.*/
+	    Xpath 32				" X: 0
+	    Xout "exists2:" v:exception "in" v:throwpoint
+	endtry
+    catch /.*/
+	Xpath 64				" X: 0
+	Xout "exists1:" v:exception "in" v:throwpoint
+    endtry
+
+    try
+	let file = tempname()
+	exec "edit" file
+	insert
+begin
+    xx
+middle 3
+    xx
+middle 5 skip
+    xx
+middle 7 throw
+    xx
+end
+.
+	normal! gg
+	Xpath 128				" X: 128
+	let result =
+	    \ searchpair("begin", "middle", "end", '', 'SKIP("searchpair", 3)')
+	Xpath 256				" X: 256
+	let result =
+	    \ searchpair("begin", "middle", "end", '', 'SKIP("searchpair", 4)')
+	Xpath 512				" X: 0
+	let result =
+	    \ searchpair("begin", "middle", "end", '', 'SKIP("searchpair", 5)')
+	Xpath 1024				" X: 0
+    catch /^searchpair[35]$/
+	Xpath 2048				" X: 0
+    catch /^searchpair4$/
+	Xpath 4096				" X: 4096
+    catch /.*/
+	Xpath 8192				" X: 0
+	Xout "searchpair:" v:exception "in" v:throwpoint
+    finally
+	bwipeout!
+	call delete(file)
+    endtry
+
+    try
+	let file = tempname()
+	exec "edit" file
+	insert
+subst 1
+subst 2
+not
+subst 4
+subst throw
+subst 6
+.
+	normal! gg
+	Xpath 16384				" X: 16384
+	1,2substitute/subst/\=SUBST("substitute", 6)/
+	try
+	    Xpath 32768				" X: 32768
+	    try
+		let v:errmsg = ""
+		3substitute/subst/\=SUBST("substitute", 7)/
+	    finally
+		if v:errmsg != ""
+		    " If exceptions are not thrown on errors, fake the error
+		    " exception in order to get the same execution path.
+		    throw "faked Vim(substitute)"
+		endif
+	    endtry
+	catch /Vim(substitute)/	    " Pattern not found ('e' flag missing)
+	    Xpath 65536				" X: 65536
+	    3substitute/subst/\=SUBST("substitute", 8)/e
+	    Xpath 131072			" X: 131072
+	endtry
+	Xpath 262144				" X: 262144
+	4,6substitute/subst/\=SUBST("substitute", 9)/
+	Xpath 524288				" X: 0
+    catch /^substitute[678]/
+	Xpath 1048576				" X: 0
+    catch /^substitute9/
+	Xpath 2097152				" X: 2097152
+    finally
+	bwipeout!
+	call delete(file)
+    endtry
+
+    try
+	Xpath 4194304				" X: 4194304
+	let var = substitute("sub", "sub", '\=THROW("substitute()y", 10)', '')
+	Xpath 8388608				" X: 0
+    catch /substitute()y/
+	Xpath 16777216				" X: 16777216
+    catch /.*/
+	Xpath 33554432				" X: 0
+	Xout "substitute()y:" v:exception "in" v:throwpoint
+    endtry
+
+    try
+	Xpath 67108864				" X: 67108864
+	let var = substitute("not", "sub", '\=THROW("substitute()n", 11)', '')
+	Xpath 134217728				" X: 134217728
+    catch /substitute()n/
+	Xpath 268435456				" X: 0
+    catch /.*/
+	Xpath 536870912				" X: 0
+	Xout "substitute()n:" v:exception "in" v:throwpoint
+    endtry
+
+    let expected = "E1T1E2T2S3(3)S4(5s)S4(7t)T4U6(1)U6(2)U9(4)U9(5t)T9T10"
+    if taken != expected
+	Xpath 1073741824			" X: 0
+	Xout "'taken' is" taken "instead of" expected
+    endif
+
+catch /.*/
+    " The Xpath command does not accept 2^31 (negative); add explicitly:
+    let Xpath = Xpath + 2147483648		" X: 0
+    Xout v:exception "in" v:throwpoint
+endtry
+
+unlet result var taken expected
+delfunction THROW
+delfunction EXPR
+delfunction SKIP
+delfunction SUBST
+
+Xcheck 224907669
+
+
+"-------------------------------------------------------------------------------
+" Test 75:  Errors in builtin functions.				    {{{1
+"
+"	    On an error in a builtin function called inside a :try/:endtry
+"	    region, the evaluation of the expression calling that function and
+"	    the command containing that expression are abandoned.  The error can
+"	    be caught as an exception.
+"
+"	    A simple :call of the builtin function is a trivial case.  If the
+"	    builtin function is called in the argument list of another function,
+"	    no further arguments are evaluated, and the other function is not
+"	    executed.  If the builtin function is called from the argument of
+"	    a :return command, the :return command is not executed.  If the
+"	    builtin function is called from the argument of a :throw command,
+"	    the :throw command is not executed.  The evaluation of the
+"	    expression calling the builtin function is abandoned.
+"-------------------------------------------------------------------------------
+
+XpathINIT
+
+function! F1(arg1)
+    Xpath 1					" X: 0
+endfunction
+
+function! F2(arg1, arg2)
+    Xpath 2					" X: 0
+endfunction
+
+function! G()
+    Xpath 4					" X: 0
+endfunction
+
+function! H()
+    Xpath 8					" X: 0
+endfunction
+
+function! R()
+    while 1
+	try
+	    let caught = 0
+	    let v:errmsg = ""
+	    Xpath 16				" X: 16
+	    return append(1, "s")
+	catch /E21/
+	    let caught = 1
+	catch /.*/
+	    Xpath 32				" X: 0
+	finally
+	    Xpath 64				" X: 64
+	    if caught || $VIMNOERRTHROW && v:errmsg =~ 'E21'
+		Xpath 128			" X: 128
+	    endif
+	    break		" discard error for $VIMNOERRTHROW
+	endtry
+    endwhile
+    Xpath 256					" X: 256
+endfunction
+
+try
+    set noma	" let append() fail with "E21"
+
+    while 1
+	try
+	    let caught = 0
+	    let v:errmsg = ""
+	    Xpath 512				" X: 512
+	    call append(1, "s")
+	catch /E21/
+	    let caught = 1
+	catch /.*/
+	    Xpath 1024				" X: 0
+	finally
+	    Xpath 2048				" X: 2048
+	    if caught || $VIMNOERRTHROW && v:errmsg =~ 'E21'
+		Xpath 4096			" X: 4096
+	    endif
+	    break		" discard error for $VIMNOERRTHROW
+	endtry
+    endwhile
+
+    while 1
+	try
+	    let caught = 0
+	    let v:errmsg = ""
+	    Xpath 8192				" X: 8192
+	    call F1('x' . append(1, "s"))
+	catch /E21/
+	    let caught = 1
+	catch /.*/
+	    Xpath 16384				" X: 0
+	finally
+	    Xpath 32768				" X: 32768
+	    if caught || $VIMNOERRTHROW && v:errmsg =~ 'E21'
+		Xpath 65536			" X: 65536
+	    endif
+	    break		" discard error for $VIMNOERRTHROW
+	endtry
+    endwhile
+
+    while 1
+	try
+	    let caught = 0
+	    let v:errmsg = ""
+	    Xpath 131072			" X: 131072
+	    call F2('x' . append(1, "s"), G())
+	catch /E21/
+	    let caught = 1
+	catch /.*/
+	    Xpath 262144			" X: 0
+	finally
+	    Xpath 524288			" X: 524288
+	    if caught || $VIMNOERRTHROW && v:errmsg =~ 'E21'
+		Xpath 1048576			" X: 1048576
+	    endif
+	    break		" discard error for $VIMNOERRTHROW
+	endtry
+    endwhile
+
+    call R()
+
+    while 1
+	try
+	    let caught = 0
+	    let v:errmsg = ""
+	    Xpath 2097152			" X: 2097152
+	    throw "T" . append(1, "s")
+	catch /E21/
+	    let caught = 1
+	catch /^T.*/
+	    Xpath 4194304			" X: 0
+	catch /.*/
+	    Xpath 8388608			" X: 0
+	finally
+	    Xpath 16777216			" X: 16777216
+	    if caught || $VIMNOERRTHROW && v:errmsg =~ 'E21'
+		Xpath 33554432			" X: 33554432
+	    endif
+	    break		" discard error for $VIMNOERRTHROW
+	endtry
+    endwhile
+
+    while 1
+	try
+	    let caught = 0
+	    let v:errmsg = ""
+	    Xpath 67108864			" X: 67108864
+	    let x = "a"
+	    let x = x . "b" . append(1, "s") . H()
+	catch /E21/
+	    let caught = 1
+	catch /.*/
+	    Xpath 134217728			" X: 0
+	finally
+	    Xpath 268435456			" X: 268435456
+	    if caught || $VIMNOERRTHROW && v:errmsg =~ 'E21'
+		Xpath 536870912			" X: 536870912
+	    endif
+	    if x == "a"
+		Xpath 1073741824		" X: 1073741824
+	    endif
+	    break		" discard error for $VIMNOERRTHROW
+	endtry
+    endwhile
+catch /.*/
+    " The Xpath command does not accept 2^31 (negative); add explicitly:
+    let Xpath = Xpath + 2147483648		" X: 0
+    Xout v:exception "in" v:throwpoint
+finally
+    set ma&
+endtry
+
+unlet! caught x
+delfunction F1
+delfunction F2
+delfunction G
+delfunction H
+delfunction R
+
+Xcheck 2000403408
+
+
+"-------------------------------------------------------------------------------
+" Test 76:  Errors, interrupts, :throw during expression evaluation	    {{{1
+"
+"	    When a function call made during expression evaluation is aborted
+"	    due to an error inside a :try/:endtry region or due to an interrupt
+"	    or a :throw, the expression evaluation is aborted as well.	No
+"	    message is displayed for the cancelled expression evaluation.  On an
+"	    error not inside :try/:endtry, the expression evaluation continues.
+"-------------------------------------------------------------------------------
+
+XpathINIT
+
+if ExtraVim()
+
+    let taken = ""
+
+    function! ERR(n)
+	let g:taken = g:taken . "E" . a:n
+	asdf
+    endfunction
+
+    function! ERRabort(n) abort
+	let g:taken = g:taken . "A" . a:n
+	asdf
+    endfunction	" returns -1; may cause follow-up msg for illegal var/func name
+
+    function! WRAP(n, arg)
+	let g:taken = g:taken . "W" . a:n
+	let g:saved_errmsg = v:errmsg
+	return arg
+    endfunction
+
+    function! INT(n)
+	let g:taken = g:taken . "I" . a:n
+	"INTERRUPT9
+	let dummy = 0
+    endfunction
+
+    function! THR(n)
+	let g:taken = g:taken . "T" . a:n
+	throw "should not be caught"
+    endfunction
+
+    function! CONT(n)
+	let g:taken = g:taken . "C" . a:n
+    endfunction
+
+    function! MSG(n)
+	let g:taken = g:taken . "M" . a:n
+	let errmsg = (a:n >= 37 && a:n <= 44) ? g:saved_errmsg : v:errmsg
+	let msgptn = (a:n >= 10 && a:n <= 27) ? "^$" : "asdf"
+	if errmsg !~ msgptn
+	    let g:taken = g:taken . "x"
+	    Xout "Expr" a:n.": Unexpected message:" v:errmsg
+	endif
+	let v:errmsg = ""
+	let g:saved_errmsg = ""
+    endfunction
+
+    let v:errmsg = ""
+
+    try
+	let t = 1
+	XloopINIT 1 2
+	while t <= 9
+	    Xloop 1				" X: 511
+	    try
+		if t == 1
+		    let v{ERR(t) + CONT(t)} = 0
+		elseif t == 2
+		    let v{ERR(t) + CONT(t)}
+		elseif t == 3
+		    let var = exists('v{ERR(t) + CONT(t)}')
+		elseif t == 4
+		    unlet v{ERR(t) + CONT(t)}
+		elseif t == 5
+		    function F{ERR(t) + CONT(t)}()
+		    endfunction
+		elseif t == 6
+		    function F{ERR(t) + CONT(t)}
+		elseif t == 7
+		    let var = exists('*F{ERR(t) + CONT(t)}')
+		elseif t == 8
+		    delfunction F{ERR(t) + CONT(t)}
+		elseif t == 9
+		    let var = ERR(t) + CONT(t)
+		endif
+	    catch /asdf/
+		" v:errmsg is not set when the error message is converted to an
+		" exception.  Set it to the original error message.
+		let v:errmsg = substitute(v:exception, '^Vim:', '', "")
+	    catch /^Vim\((\a\+)\)\=:/
+		" An error exception has been thrown after the original error.
+		let v:errmsg = ""
+	    finally
+		call MSG(t)
+		let t = t + 1
+		XloopNEXT
+		continue	" discard an aborting error
+	    endtry
+	endwhile
+    catch /.*/
+	Xpath 512				" X: 0
+	Xout v:exception "in" ExtraVimThrowpoint()
+    endtry
+
+    try
+	let t = 10
+	XloopINIT 1024 2
+	while t <= 18
+	    Xloop 1				" X: 1024 * 511
+	    try
+		if t == 10
+		    let v{INT(t) + CONT(t)} = 0
+		elseif t == 11
+		    let v{INT(t) + CONT(t)}
+		elseif t == 12
+		    let var = exists('v{INT(t) + CONT(t)}')
+		elseif t == 13
+		    unlet v{INT(t) + CONT(t)}
+		elseif t == 14
+		    function F{INT(t) + CONT(t)}()
+		    endfunction
+		elseif t == 15
+		    function F{INT(t) + CONT(t)}
+		elseif t == 16
+		    let var = exists('*F{INT(t) + CONT(t)}')
+		elseif t == 17
+		    delfunction F{INT(t) + CONT(t)}
+		elseif t == 18
+		    let var = INT(t) + CONT(t)
+		endif
+	    catch /^Vim\((\a\+)\)\=:\(Interrupt\)\@!/
+		" An error exception has been triggered after the interrupt.
+		let v:errmsg = substitute(v:exception,
+		    \ '^Vim\((\a\+)\)\=:', '', "")
+	    finally
+		call MSG(t)
+		let t = t + 1
+		XloopNEXT
+		continue	" discard interrupt
+	    endtry
+	endwhile
+    catch /.*/
+	Xpath 524288				" X: 0
+	Xout v:exception "in" ExtraVimThrowpoint()
+    endtry
+
+    try
+	let t = 19
+	XloopINIT 1048576 2
+	while t <= 27
+	    Xloop 1				" X: 1048576 * 511
+	    try
+		if t == 19
+		    let v{THR(t) + CONT(t)} = 0
+		elseif t == 20
+		    let v{THR(t) + CONT(t)}
+		elseif t == 21
+		    let var = exists('v{THR(t) + CONT(t)}')
+		elseif t == 22
+		    unlet v{THR(t) + CONT(t)}
+		elseif t == 23
+		    function F{THR(t) + CONT(t)}()
+		    endfunction
+		elseif t == 24
+		    function F{THR(t) + CONT(t)}
+		elseif t == 25
+		    let var = exists('*F{THR(t) + CONT(t)}')
+		elseif t == 26
+		    delfunction F{THR(t) + CONT(t)}
+		elseif t == 27
+		    let var = THR(t) + CONT(t)
+		endif
+	    catch /^Vim\((\a\+)\)\=:/
+		" An error exception has been triggered after the :throw.
+		let v:errmsg = substitute(v:exception,
+		    \ '^Vim\((\a\+)\)\=:', '', "")
+	    finally
+		call MSG(t)
+		let t = t + 1
+		XloopNEXT
+		continue	" discard exception
+	    endtry
+	endwhile
+    catch /.*/
+	Xpath 536870912				" X: 0
+	Xout v:exception "in" ExtraVimThrowpoint()
+    endtry
+
+    let v{ERR(28) + CONT(28)} = 0
+    call MSG(28)
+    let v{ERR(29) + CONT(29)}
+    call MSG(29)
+    let var = exists('v{ERR(30) + CONT(30)}')
+    call MSG(30)
+    unlet v{ERR(31) + CONT(31)}
+    call MSG(31)
+    function F{ERR(32) + CONT(32)}()
+    endfunction
+    call MSG(32)
+    function F{ERR(33) + CONT(33)}
+    call MSG(33)
+    let var = exists('*F{ERR(34) + CONT(34)}')
+    call MSG(34)
+    delfunction F{ERR(35) + CONT(35)}
+    call MSG(35)
+    let var = ERR(36) + CONT(36)
+    call MSG(36)
+
+    let saved_errmsg = ""
+
+    let v{WRAP(37, ERRabort(37)) + CONT(37)} = 0
+    call MSG(37)
+    let v{WRAP(38, ERRabort(38)) + CONT(38)}
+    call MSG(38)
+    let var = exists('v{WRAP(39, ERRabort(39)) + CONT(39)}')
+    call MSG(39)
+    unlet v{WRAP(40, ERRabort(40)) + CONT(40)}
+    call MSG(40)
+    function F{WRAP(41, ERRabort(41)) + CONT(41)}()
+    endfunction
+    call MSG(41)
+    function F{WRAP(42, ERRabort(42)) + CONT(42)}
+    call MSG(42)
+    let var = exists('*F{WRAP(43, ERRabort(43)) + CONT(43)}')
+    call MSG(43)
+    delfunction F{WRAP(44, ERRabort(44)) + CONT(44)}
+    call MSG(44)
+    let var = ERRabort(45) + CONT(45)
+    call MSG(45)
+
+    Xpath 1073741824				" X: 1073741824
+
+    let expected = ""
+	\ . "E1M1E2M2E3M3E4M4E5M5E6M6E7M7E8M8E9M9"
+	\ . "I10M10I11M11I12M12I13M13I14M14I15M15I16M16I17M17I18M18"
+	\ . "T19M19T20M20T21M21T22M22T23M23T24M24T25M25T26M26T27M27"
+	\ . "E28C28M28E29C29M29E30C30M30E31C31M31E32C32M32E33C33M33"
+	\ . "E34C34M34E35C35M35E36C36M36"
+	\ . "A37W37C37M37A38W38C38M38A39W39C39M39A40W40C40M40A41W41C41M41"
+	\ . "A42W42C42M42A43W43C43M43A44W44C44M44A45C45M45"
+
+    if taken != expected
+	" The Xpath command does not accept 2^31 (negative); display explicitly:
+	exec "!echo 2147483648 >>" . g:ExtraVimResult
+						" X: 0
+	Xout "'taken' is" taken "instead of" expected
+	if substitute(taken,
+	\ '\(.*\)E3C3M3x\(.*\)E30C30M30x\(.*\)A39C39M39x\(.*\)',
+	\ '\1E3M3\2E30C30M30\3A39C39M39\4',
+	\ "") == expected
+	    Xout "Is ++emsg_skip for var with expr_start non-NULL"
+		\ "in f_exists ok?"
+	endif
+    endif
+
+    unlet! v var saved_errmsg taken expected
+    call delete(WA_t5)
+    call delete(WA_t14)
+    call delete(WA_t23)
+    unlet! WA_t5 WA_t14 WA_t23
+    delfunction WA_t5
+    delfunction WA_t14
+    delfunction WA_t23
+
+endif
+
+Xcheck 1610087935
+
+
+"-------------------------------------------------------------------------------
+" Test 77:  Errors, interrupts, :throw in name{brace-expression}	    {{{1
+"
+"	    When a function call made during evaluation of an expression in
+"	    braces as part of a function name after ":function" is aborted due
+"	    to an error inside a :try/:endtry region or due to an interrupt or
+"	    a :throw, the expression evaluation is aborted as well, and the
+"	    function definition is ignored, skipping all commands to the
+"	    ":endfunction".  On an error not inside :try/:endtry, the expression
+"	    evaluation continues and the function gets defined, and can be
+"	    called and deleted.
+"-------------------------------------------------------------------------------
+
+XpathINIT
+
+XloopINIT 1 4
+
+function! ERR() abort
+    Xloop 1					" X: 1 + 4 + 16 + 64
+    asdf
+endfunction		" returns -1
+
+function! OK()
+    Xloop 2					" X: 2 * (1 + 4 + 16)
+    let v:errmsg = ""
+    return 0
+endfunction
+
+let v:errmsg = ""
+
+Xpath 4096					" X: 4096
+function! F{1 + ERR() + OK()}(arg)
+    " F0 should be defined.
+    if exists("a:arg") && a:arg == "calling"
+	Xpath 8192				" X: 8192
+    else
+	Xpath 16384				" X: 0
+    endif
+endfunction
+if v:errmsg != ""
+    Xpath 32768					" X: 0
+endif
+XloopNEXT
+
+Xpath 65536					" X: 65536
+call F{1 + ERR() + OK()}("calling")
+if v:errmsg != ""
+    Xpath 131072				" X: 0
+endif
+XloopNEXT
+
+Xpath 262144					" X: 262144
+delfunction F{1 + ERR() + OK()}
+if v:errmsg != ""
+    Xpath 524288				" X: 0
+endif
+XloopNEXT
+
+try
+    while 1
+	let caught = 0
+	try
+	    Xpath 1048576			" X: 1048576
+	    function! G{1 + ERR() + OK()}(arg)
+		" G0 should not be defined, and the function body should be
+		" skipped.
+		if exists("a:arg") && a:arg == "calling"
+		    Xpath 2097152		" X: 0
+		else
+		    Xpath 4194304		" X: 0
+		endif
+		" Use an unmatched ":finally" to check whether the body is
+		" skipped when an error occurs in ERR().  This works whether or
+		" not the exception is converted to an exception.
+		finally
+		    Xpath 8388608		" X: 0
+		    Xout "Body of G{1 + ERR() + OK()}() not skipped"
+		    " Discard the aborting error or exception, and break the
+		    " while loop.
+		    break
+		" End the try conditional and start a new one to avoid
+		" ":catch after :finally" errors.
+		endtry
+		try
+		Xpath 16777216			" X: 0
+	    endfunction
+
+	    " When the function was not defined, this won't be reached - whether
+	    " the body was skipped or not.  When the function was defined, it
+	    " can be called and deleted here.
+	    Xpath 33554432			" X: 0
+	    Xout "G0() has been defined"
+	    XloopNEXT
+	    try
+		call G{1 + ERR() + OK()}("calling")
+	    catch /.*/
+		Xpath 67108864			" X: 0
+	    endtry
+	    Xpath 134217728			" X: 0
+	    XloopNEXT
+	    try
+		delfunction G{1 + ERR() + OK()}
+	    catch /.*/
+		Xpath 268435456			" X: 0
+	    endtry
+	catch /asdf/
+	    " Jumped to when the function is not defined and the body is
+	    " skipped.
+	    let caught = 1
+	catch /.*/
+	    Xpath 536870912			" X: 0
+	finally
+	    if !caught && !$VIMNOERRTHROW
+		Xpath 1073741824		" X: 0
+	    endif
+	    break		" discard error for $VIMNOERRTHROW
+	endtry			" jumped to when the body is not skipped
+    endwhile
+catch /.*/
+    " The Xpath command does not accept 2^31 (negative); add explicitly:
+    let Xpath = Xpath + 2147483648		" X: 0
+    Xout "Body of G{1 + ERR() + OK()}() not skipped, exception caught"
+    Xout v:exception "in" v:throwpoint
+endtry
+
+Xcheck 1388671
+
+
+"-------------------------------------------------------------------------------
+" Test 78:  Messages on parsing errors in expression evaluation		    {{{1
+"
+"	    When an expression evaluation detects a parsing error, an error
+"	    message is given and converted to an exception, and the expression
+"	    evaluation is aborted.
+"-------------------------------------------------------------------------------
+
+XpathINIT
+
+if ExtraVim()
+
+    let taken = ""
+
+    function! F(n)
+	let g:taken = g:taken . "F" . a:n
+    endfunction
+
+    function! MSG(n, enr, emsg)
+	let g:taken = g:taken . "M" . a:n
+	let english = v:lang == "C" || v:lang =~ '^[Ee]n'
+	if a:enr == ""
+	    Xout "TODO: Add message number for:" a:emsg
+	    let v:errmsg = ":" . v:errmsg
+	endif
+	if v:errmsg !~ '^'.a:enr.':' || (english && v:errmsg !~ a:emsg)
+	    if v:errmsg == ""
+		Xout "Expr" a:n.": Message missing."
+		let g:taken = g:taken . "x"
+	    else
+		let v:errmsg = escape(v:errmsg, '"')
+		Xout "Expr" a:n.": Unexpected message:" v:errmsg
+		Xout "Expected: " . a:enr . ': ' . a:emsg
+		let g:taken = g:taken . "X"
+	    endif
+	endif
+    endfunction
+
+    function! CONT(n)
+	let g:taken = g:taken . "C" . a:n
+    endfunction
+
+    let v:errmsg = ""
+    XloopINIT 1 2
+
+    try
+	let t = 1
+	while t <= 14
+	    let g:taken = g:taken . "T" . t
+	    let v:errmsg = ""
+	    try
+		let caught = 0
+		if t == 1
+		    let v{novar + CONT(t)} = 0
+		elseif t == 2
+		    let v{novar + CONT(t)}
+		elseif t == 3
+		    let var = exists('v{novar + CONT(t)}')
+		elseif t == 4
+		    unlet v{novar + CONT(t)}
+		elseif t == 5
+		    function F{novar + CONT(t)}()
+		    endfunction
+		elseif t == 6
+		    function F{novar + CONT(t)}
+		elseif t == 7
+		    let var = exists('*F{novar + CONT(t)}')
+		elseif t == 8
+		    delfunction F{novar + CONT(t)}
+		elseif t == 9
+		    echo novar + CONT(t)
+		elseif t == 10
+		    echo v{novar + CONT(t)}
+		elseif t == 11
+		    echo F{novar + CONT(t)}
+		elseif t == 12
+		    let var = novar + CONT(t)
+		elseif t == 13
+		    let var = v{novar + CONT(t)}
+		elseif t == 14
+		    let var = F{novar + CONT(t)}()
+		endif
+	    catch /^Vim\((\a\+)\)\=:/
+		" v:errmsg is not set when the error message is converted to an
+		" exception.  Set it to the original error message.
+		let v:errmsg = substitute(v:exception,
+		    \ '^Vim\((\a\+)\)\=:', '', "")
+		let caught = 1
+	    finally
+		if t <= 8 && t != 3 && t != 7
+		    call MSG(t, 'E475', 'Invalid argument\>')
+		else
+		    if !caught	" no error exceptions ($VIMNOERRTHROW set)
+			call MSG(t, 'E15', "Invalid expression")
+		    else
+			call MSG(t, 'E121', "Undefined variable")
+		    endif
+		endif
+		let t = t + 1
+		XloopNEXT
+		continue	" discard an aborting error
+	    endtry
+	endwhile
+    catch /.*/
+	Xloop 1					" X: 0
+	Xout t.":" v:exception "in" ExtraVimThrowpoint()
+    endtry
+
+    function! T(n, expr, enr, emsg)
+	try
+	    let g:taken = g:taken . "T" . a:n
+	    let v:errmsg = ""
+	    try
+		let caught = 0
+		execute "let var = " . a:expr
+	    catch /^Vim\((\a\+)\)\=:/
+		" v:errmsg is not set when the error message is converted to an
+		" exception.  Set it to the original error message.
+		let v:errmsg = substitute(v:exception,
+		    \ '^Vim\((\a\+)\)\=:', '', "")
+		let caught = 1
+	    finally
+		if !caught	" no error exceptions ($VIMNOERRTHROW set)
+		    call MSG(a:n, 'E15', "Invalid expression")
+		else
+		    call MSG(a:n, a:enr, a:emsg)
+		endif
+		XloopNEXT
+		" Discard an aborting error:
+		return
+	    endtry
+	catch /.*/
+	    Xloop 1				" X: 0
+	    Xout a:n.":" v:exception "in" ExtraVimThrowpoint()
+	endtry
+    endfunction
+
+    call T(15, 'Nofunc() + CONT(15)',	'E117',	"Unknown function")
+    call T(16, 'F(1 2 + CONT(16))',	'E116',	"Invalid arguments")
+    call T(17, 'F(1, 2) + CONT(17)',	'E118',	"Too many arguments")
+    call T(18, 'F() + CONT(18)',	'E119',	"Not enough arguments")
+    call T(19, '{(1} + CONT(19)',	'E110',	"Missing ')'")
+    call T(20, '("abc"[1) + CONT(20)',	'E111',	"Missing ']'")
+    call T(21, '(1 +) + CONT(21)',	'E15',	"Invalid expression")
+    call T(22, '1 2 + CONT(22)',	'E15',	"Invalid expression")
+    call T(23, '(1 ? 2) + CONT(23)',	'E109',	"Missing ':' after '?'")
+    call T(24, '("abc) + CONT(24)',	'E114',	"Missing quote")
+    call T(25, "('abc) + CONT(25)",	'E115',	"Missing quote")
+    call T(26, '& + CONT(26)',		'E112', "Option name missing")
+    call T(27, '&asdf + CONT(27)',	'E113', "Unknown option")
+
+    Xpath 134217728				" X: 134217728
+
+    let expected = ""
+	\ . "T1M1T2M2T3M3T4M4T5M5T6M6T7M7T8M8T9M9T10M10T11M11T12M12T13M13T14M14"
+	\ . "T15M15T16M16T17M17T18M18T19M19T20M20T21M21T22M22T23M23T24M24T25M25"
+	\ . "T26M26T27M27"
+
+    if taken != expected
+	Xpath 268435456				" X: 0
+	Xout "'taken' is" taken "instead of" expected
+	if substitute(taken, '\(.*\)T3M3x\(.*\)', '\1T3M3\2', "") == expected
+	    Xout "Is ++emsg_skip for var with expr_start non-NULL"
+		\ "in f_exists ok?"
+	endif
+    endif
+
+    unlet! var caught taken expected
+    call delete(WA_t5)
+    unlet! WA_t5
+    delfunction WA_t5
+
+endif
+
+Xcheck 134217728
+
+
+"-------------------------------------------------------------------------------
+" Test 79:  Throwing one of several errors for the same command		    {{{1
+"
+"	    When several errors appear in a row (for instance during expression
+"	    evaluation), the first as the most specific one is used when
+"	    throwing an error exception.  If, however, a syntax error is
+"	    detected afterwards, this one is used for the error exception.
+"	    On a syntax error, the next command is not executed, on a normal
+"	    error, however, it is (relevant only in a function without the
+"	    "abort" flag).  v:errmsg is not set.
+"
+"	    If throwing error exceptions is configured off, v:errmsg is always
+"	    set to the latest error message, that is, to the more general
+"	    message or the syntax error, respectively.
+"-------------------------------------------------------------------------------
+
+XpathINIT
+
+XloopINIT 1 2
+
+function! NEXT(cmd)
+    exec a:cmd . " | Xloop 1"
+endfunction
+
+call NEXT('echo novar')				" X: 1 *  1  (checks nextcmd)
+XloopNEXT
+call NEXT('let novar #')			" X: 0 *  2  (skips nextcmd)
+XloopNEXT
+call NEXT('unlet novar #')			" X: 0 *  4  (skips nextcmd)
+XloopNEXT
+call NEXT('let {novar}')			" X: 0 *  8  (skips nextcmd)
+XloopNEXT
+call NEXT('unlet{ novar}')			" X: 0 * 16  (skips nextcmd)
+
+function! EXEC(cmd)
+    exec a:cmd
+endfunction
+
+function! MATCH(expected, msg, enr, emsg)
+    let msg = a:msg
+    if a:enr == ""
+	Xout "TODO: Add message number for:" a:emsg
+	let msg = ":" . msg
+    endif
+    let english = v:lang == "C" || v:lang =~ '^[Ee]n'
+    if msg !~ '^'.a:enr.':' || (english && msg !~ a:emsg)
+	let match =  0
+	if a:expected		" no match although expected
+	    if a:msg == ""
+		Xout "Message missing."
+	    else
+		let msg = escape(msg, '"')
+		Xout "Unexpected message:" msg
+		Xout "Expected:" a:enr . ": " . a:emsg
+	    endif
+	endif
+    else
+	let match =  1
+	if !a:expected		" match although not expected
+	    let msg = escape(msg, '"')
+	    Xout "Unexpected message:" msg
+	    Xout "Expected none."
+	endif
+    endif
+    return match
+endfunction
+
+try
+
+    while 1				" dummy loop
+	try
+	    let v:errmsg = ""
+	    let caught = 0
+	    let thrmsg = ""
+	    call EXEC('echo novar')	" normal error
+	catch /^Vim\((\a\+)\)\=:/
+	    let caught = 1
+	    let thrmsg = substitute(v:exception, '^Vim\((\a\+)\)\=:', '', "")
+	finally
+	    Xpath 32				" X: 32
+	    if !caught
+		if !$VIMNOERRTHROW
+		    Xpath 64			" X: 0
+		endif
+	    elseif !MATCH(1, thrmsg, 'E121', "Undefined variable")
+	    \ || v:errmsg != ""
+		Xpath 128			" X: 0
+	    endif
+	    if !caught && !MATCH(1, v:errmsg, 'E15', "Invalid expression")
+		Xpath 256			" X: 0
+	    endif
+	    break			" discard error if $VIMNOERRTHROW == 1
+	endtry
+    endwhile
+
+    Xpath 512					" X: 512
+    let cmd = "let"
+    XloopINIT 1024 32
+    while cmd != ""
+	try
+	    let v:errmsg = ""
+	    let caught = 0
+	    let thrmsg = ""
+	    call EXEC(cmd . ' novar #')		" normal plus syntax error
+	catch /^Vim\((\a\+)\)\=:/
+	    let caught = 1
+	    let thrmsg = substitute(v:exception, '^Vim\((\a\+)\)\=:', '', "")
+	finally
+	    Xloop 1				" X: 1024 * (1 + 32)
+	    if !caught
+		if !$VIMNOERRTHROW
+		    Xloop 2			" X: 0
+		endif
+	    else
+		if cmd == "let"
+		    let match = MATCH(0, thrmsg, 'E106', "Unknown variable")
+		elseif cmd == "unlet"
+		    let match = MATCH(0, thrmsg, 'E108', "No such variable")
+		endif
+		if match					" normal error
+		    Xloop 4			" X: 0
+		endif
+		if !MATCH(1, thrmsg, 'E488', "Trailing characters")
+		\|| v:errmsg != ""
+								" syntax error
+		    Xloop 8			" X: 0
+		endif
+	    endif
+	    if !caught && !MATCH(1, v:errmsg, 'E488', "Trailing characters")
+								" last error
+		Xloop 16			" X: 0
+	    endif
+	    if cmd == "let"
+		let cmd = "unlet"
+	    else
+		let cmd = ""
+	    endif
+	    XloopNEXT
+	    continue			" discard error if $VIMNOERRTHROW == 1
+	endtry
+    endwhile
+
+    Xpath 1048576				" X: 1048576
+    let cmd = "let"
+    XloopINIT 2097152 32
+    while cmd != ""
+	try
+	    let v:errmsg = ""
+	    let caught = 0
+	    let thrmsg = ""
+	    call EXEC(cmd . ' {novar}')		" normal plus syntax error
+	catch /^Vim\((\a\+)\)\=:/
+	    let caught = 1
+	    let thrmsg = substitute(v:exception, '^Vim\((\a\+)\)\=:', '', "")
+	finally
+	    Xloop 1				" X: 2097152 * (1 + 32)
+	    if !caught
+		if !$VIMNOERRTHROW
+		    Xloop 2			" X: 0
+		endif
+	    else
+		if MATCH(0, thrmsg, 'E121', "Undefined variable") " normal error
+		    Xloop 4			" X: 0
+		endif
+		if !MATCH(1, thrmsg, 'E475', 'Invalid argument\>')
+		\ || v:errmsg != ""				  " syntax error
+		    Xloop 8			" X: 0
+		endif
+	    endif
+	    if !caught && !MATCH(1, v:errmsg, 'E475', 'Invalid argument\>')
+								" last error
+		Xloop 16			" X: 0
+	    endif
+	    if cmd == "let"
+		let cmd = "unlet"
+	    else
+		let cmd = ""
+	    endif
+	    XloopNEXT
+	    continue			" discard error if $VIMNOERRTHROW == 1
+	endtry
+    endwhile
+
+catch /.*/
+    " The Xpath command does not accept 2^31 (negative); add explicitly:
+    let Xpath = Xpath + 2147483648		" X: 0
+    Xout v:exception "in" v:throwpoint
+endtry
+
+unlet! next_command thrmsg match
+delfunction NEXT
+delfunction EXEC
+delfunction MATCH
+
+Xcheck 70288929
+
+
+"-------------------------------------------------------------------------------
+" Test 80:  Syntax error in expression for illegal :elseif		    {{{1
+"
+"	    If there is a syntax error in the expression after an illegal
+"	    :elseif, an error message is given (or an error exception thrown)
+"	    for the illegal :elseif rather than the expression error.
+"-------------------------------------------------------------------------------
+
+XpathINIT
+
+function! MSG(enr, emsg)
+    let english = v:lang == "C" || v:lang =~ '^[Ee]n'
+    if a:enr == ""
+	Xout "TODO: Add message number for:" a:emsg
+	let v:errmsg = ":" . v:errmsg
+    endif
+    let match = 1
+    if v:errmsg !~ '^'.a:enr.':' || (english && v:errmsg !~ a:emsg)
+	let match = 0
+	if v:errmsg == ""
+	    Xout "Message missing."
+	else
+	    let v:errmsg = escape(v:errmsg, '"')
+	    Xout "Unexpected message:" v:errmsg
+	endif
+    endif
+    return match
+endfunction
+
+let v:errmsg = ""
+if 0
+else
+elseif 1 ||| 2
+endif
+Xpath 1						" X: 1
+if !MSG('E584', ":elseif after :else")
+    Xpath 2					" X: 0
+endif
+
+let v:errmsg = ""
+if 1
+else
+elseif 1 ||| 2
+endif
+Xpath 4						" X: 4
+if !MSG('E584', ":elseif after :else")
+    Xpath 8					" X: 0
+endif
+
+let v:errmsg = ""
+elseif 1 ||| 2
+Xpath 16					" X: 16
+if !MSG('E582', ":elseif without :if")
+    Xpath 32					" X: 0
+endif
+
+let v:errmsg = ""
+while 1
+    elseif 1 ||| 2
+endwhile
+Xpath 64					" X: 64
+if !MSG('E582', ":elseif without :if")
+    Xpath 128					" X: 0
+endif
+
+while 1
+    try
+	try
+	    let v:errmsg = ""
+	    let caught = 0
+	    if 0
+	    else
+	    elseif 1 ||| 2
+	    endif
+	catch /^Vim\((\a\+)\)\=:/
+	    let caught = 1
+	    let v:errmsg = substitute(v:exception, '^Vim\((\a\+)\)\=:', '', "")
+	finally
+	    Xpath 256				" X: 256
+	    if !caught && !$VIMNOERRTHROW
+		Xpath 512			" X: 0
+	    endif
+	    if !MSG('E584', ":elseif after :else")
+		Xpath 1024			" X: 0
+	    endif
+	endtry
+    catch /.*/
+	Xpath 2048				" X: 0
+	Xout v:exception "in" v:throwpoint
+    finally
+	break		" discard error for $VIMNOERRTHROW
+    endtry
+endwhile
+
+while 1
+    try
+	try
+	    let v:errmsg = ""
+	    let caught = 0
+	    if 1
+	    else
+	    elseif 1 ||| 2
+	    endif
+	catch /^Vim\((\a\+)\)\=:/
+	    let caught = 1
+	    let v:errmsg = substitute(v:exception, '^Vim\((\a\+)\)\=:', '', "")
+	finally
+	    Xpath 4096				" X: 4096
+	    if !caught && !$VIMNOERRTHROW
+		Xpath 8192			" X: 0
+	    endif
+	    if !MSG('E584', ":elseif after :else")
+		Xpath 16384			" X: 0
+	    endif
+	endtry
+    catch /.*/
+	Xpath 32768				" X: 0
+	Xout v:exception "in" v:throwpoint
+    finally
+	break		" discard error for $VIMNOERRTHROW
+    endtry
+endwhile
+
+while 1
+    try
+	try
+	    let v:errmsg = ""
+	    let caught = 0
+	    elseif 1 ||| 2
+	catch /^Vim\((\a\+)\)\=:/
+	    let caught = 1
+	    let v:errmsg = substitute(v:exception, '^Vim\((\a\+)\)\=:', '', "")
+	finally
+	    Xpath 65536				" X: 65536
+	    if !caught && !$VIMNOERRTHROW
+		Xpath 131072			" X: 0
+	    endif
+	    if !MSG('E582', ":elseif without :if")
+		Xpath 262144			" X: 0
+	    endif
+	endtry
+    catch /.*/
+	Xpath 524288				" X: 0
+	Xout v:exception "in" v:throwpoint
+    finally
+	break		" discard error for $VIMNOERRTHROW
+    endtry
+endwhile
+
+while 1
+    try
+	try
+	    let v:errmsg = ""
+	    let caught = 0
+	    while 1
+		elseif 1 ||| 2
+	    endwhile
+	catch /^Vim\((\a\+)\)\=:/
+	    let caught = 1
+	    let v:errmsg = substitute(v:exception, '^Vim\((\a\+)\)\=:', '', "")
+	finally
+	    Xpath 1048576			" X: 1048576
+	    if !caught && !$VIMNOERRTHROW
+		Xpath 2097152			" X: 0
+	    endif
+	    if !MSG('E582', ":elseif without :if")
+		Xpath 4194304			" X: 0
+	    endif
+	endtry
+    catch /.*/
+	Xpath 8388608				" X: 0
+	Xout v:exception "in" v:throwpoint
+    finally
+	break		" discard error for $VIMNOERRTHROW
+    endtry
+endwhile
+
+Xpath 16777216					" X: 16777216
+
+unlet! caught
+delfunction MSG
+
+Xcheck 17895765
+
+
+"-------------------------------------------------------------------------------
+" Test 81:  Discarding exceptions after an error or interrupt		    {{{1
+"
+"	    When an exception is thrown from inside a :try conditional without
+"	    :catch and :finally clauses and an error or interrupt occurs before
+"	    the :endtry is reached, the exception is discarded.
+"-------------------------------------------------------------------------------
+
+XpathINIT
+
+if ExtraVim()
+    try
+	Xpath 1					" X: 1
+	try
+	    Xpath 2				" X: 2
+	    throw "arrgh"
+	    Xpath 4				" X: 0
+"	    if 1
+		Xpath 8				" X: 0
+	    " error after :throw: missing :endif
+	endtry
+	Xpath 16				" X: 0
+    catch /arrgh/
+	Xpath 32				" X: 0
+    endtry
+    Xpath 64					" X: 0
+endif
+
+if ExtraVim()
+    try
+	Xpath 128				" X: 128
+	try
+	    Xpath 256				" X: 256
+	    throw "arrgh"
+	    Xpath 512				" X: 0
+	endtry		" INTERRUPT
+	Xpath 1024				" X: 0
+    catch /arrgh/
+	Xpath 2048				" X: 0
+    endtry
+    Xpath 4096					" X: 0
+endif
+
+Xcheck 387
+
+
+"-------------------------------------------------------------------------------
+" Test 82:  Ignoring :catch clauses after an error or interrupt		    {{{1
+"
+"	    When an exception is thrown and an error or interrupt occurs before
+"	    the matching :catch clause is reached, the exception is discarded
+"	    and the :catch clause is ignored (also for the error or interrupt
+"	    exception being thrown then).
+"-------------------------------------------------------------------------------
+
+XpathINIT
+
+if ExtraVim()
+    try
+	try
+	    Xpath 1				" X: 1
+	    throw "arrgh"
+	    Xpath 2				" X: 0
+"	    if 1
+		Xpath 4				" X: 0
+		" error after :throw: missing :endif
+	catch /.*/
+	    Xpath 8				" X: 0
+	    Xout v:exception "in" ExtraVimThrowpoint()
+	catch /.*/
+	    Xpath 16				" X: 0
+	    Xout v:exception "in" ExtraVimThrowpoint()
+	endtry
+	Xpath 32				" X: 0
+    catch /arrgh/
+	Xpath 64				" X: 0
+    endtry
+    Xpath 128					" X: 0
+endif
+
+if ExtraVim()
+    function! E()
+	try
+	    try
+		Xpath 256			" X: 256
+		throw "arrgh"
+		Xpath 512			" X: 0
+"		if 1
+		    Xpath 1024			" X: 0
+		    " error after :throw: missing :endif
+	    catch /.*/
+		Xpath 2048			" X: 0
+		Xout v:exception "in" ExtraVimThrowpoint()
+	    catch /.*/
+		Xpath 4096			" X: 0
+		Xout v:exception "in" ExtraVimThrowpoint()
+	    endtry
+	    Xpath 8192				" X: 0
+	catch /arrgh/
+	    Xpath 16384				" X: 0
+	endtry
+    endfunction
+
+    call E()
+    Xpath 32768					" X: 0
+endif
+
+if ExtraVim()
+    try
+	try
+	    Xpath 65536				" X: 65536
+	    throw "arrgh"
+	    Xpath 131072			" X: 0
+	catch /.*/	"INTERRUPT
+	    Xpath 262144			" X: 0
+	    Xout v:exception "in" ExtraVimThrowpoint()
+	catch /.*/
+	    Xpath 524288			" X: 0
+	    Xout v:exception "in" ExtraVimThrowpoint()
+	endtry
+	Xpath 1048576				" X: 0
+    catch /arrgh/
+	Xpath 2097152				" X: 0
+    endtry
+    Xpath 4194304				" X: 0
+endif
+
+if ExtraVim()
+    function I()
+	try
+	    try
+		Xpath 8388608			" X: 8388608
+		throw "arrgh"
+		Xpath 16777216			" X: 0
+	    catch /.*/	"INTERRUPT
+		Xpath 33554432			" X: 0
+		Xout v:exception "in" ExtraVimThrowpoint()
+	    catch /.*/
+		Xpath 67108864			" X: 0
+		Xout v:exception "in" ExtraVimThrowpoint()
+	    endtry
+	    Xpath 134217728			" X: 0
+	catch /arrgh/
+	    Xpath 268435456			" X: 0
+	endtry
+    endfunction
+
+    call I()
+    Xpath 536870912				" X: 0
+endif
+
+Xcheck 8454401
+
+
+"-------------------------------------------------------------------------------
+" Test 83:  Executing :finally clauses after an error or interrupt	    {{{1
+"
+"	    When an exception is thrown and an error or interrupt occurs before
+"	    the :finally of the innermost :try is reached, the exception is
+"	    discarded and the :finally clause is executed.
+"-------------------------------------------------------------------------------
+
+XpathINIT
+
+if ExtraVim()
+    try
+	Xpath 1					" X: 1
+	try
+	    Xpath 2				" X: 2
+	    throw "arrgh"
+	    Xpath 4				" X: 0
+"	    if 1
+		Xpath 8				" X: 0
+	    " error after :throw: missing :endif
+	finally
+	    Xpath 16				" X: 16
+	endtry
+	Xpath 32				" X: 0
+    catch /arrgh/
+	Xpath 64				" X: 0
+    endtry
+    Xpath 128					" X: 0
+endif
+
+if ExtraVim()
+    try
+	Xpath 256				" X: 256
+	try
+	    Xpath 512				" X: 512
+	    throw "arrgh"
+	    Xpath 1024				" X: 0
+	finally		"INTERRUPT
+	    Xpath 2048				" X: 2048
+	endtry
+	Xpath 4096				" X: 0
+    catch /arrgh/
+	Xpath 8192				" X: 0
+    endtry
+    Xpath 16384					" X: 0
+endif
+
+Xcheck 2835
+
+
+"-------------------------------------------------------------------------------
+" Test 84:  Exceptions in autocommand sequences.			    {{{1
+"
+"	    When an exception occurs in a sequence of autocommands for
+"	    a specific event, the rest of the sequence is not executed.  The
+"	    command that triggered the autocommand execution aborts, and the
+"	    exception is propagated to the caller.
+"
+"	    For the FuncUndefined event under a function call expression or
+"	    :call command, the function is not executed, even when it has
+"	    been defined by the autocommands before the exception occurred.
+"-------------------------------------------------------------------------------
+
+XpathINIT
+
+if ExtraVim()
+
+    function! INT()
+	"INTERRUPT
+	let dummy = 0
+    endfunction
+
+    aug TMP
+	autocmd!
+
+	autocmd User x1 Xpath 1			" X: 1
+	autocmd User x1 throw "x1"
+	autocmd User x1 Xpath 2			" X: 0
+
+	autocmd User x2 Xpath 4			" X: 4
+	autocmd User x2 asdf
+	autocmd User x2 Xpath 8			" X: 0
+
+	autocmd User x3 Xpath 16		" X: 16
+	autocmd User x3 call INT()
+	autocmd User x3 Xpath 32		" X: 0
+
+	autocmd FuncUndefined U1 function! U1()
+	autocmd FuncUndefined U1     Xpath 64	" X: 0
+	autocmd FuncUndefined U1 endfunction
+	autocmd FuncUndefined U1 Xpath 128	" X: 128
+	autocmd FuncUndefined U1 throw "U1"
+	autocmd FuncUndefined U1 Xpath 256	" X: 0
+
+	autocmd FuncUndefined U2 function! U2()
+	autocmd FuncUndefined U2     Xpath 512	" X: 0
+	autocmd FuncUndefined U2 endfunction
+	autocmd FuncUndefined U2 Xpath 1024	" X: 1024
+	autocmd FuncUndefined U2 ASDF
+	autocmd FuncUndefined U2 Xpath 2048	" X: 0
+
+	autocmd FuncUndefined U3 function! U3()
+	autocmd FuncUndefined U3     Xpath 4096	" X: 0
+	autocmd FuncUndefined U3 endfunction
+	autocmd FuncUndefined U3 Xpath 8192	" X: 8192
+	autocmd FuncUndefined U3 call INT()
+	autocmd FuncUndefined U3 Xpath 16384	" X: 0
+    aug END
+
+    try
+	try
+	    Xpath 32768				" X: 32768
+	    doautocmd User x1
+	catch /x1/
+	    Xpath 65536				" X: 65536
+	endtry
+
+	while 1
+	    try
+		Xpath 131072			" X: 131072
+		let caught = 0
+		doautocmd User x2
+	    catch /asdf/
+		let caught = 1
+	    finally
+		Xpath 262144			" X: 262144
+		if !caught && !$VIMNOERRTHROW
+		    Xpath 524288		" X: 0
+		    " Propagate uncaught error exception,
+		else
+		    " ... but break loop for caught error exception,
+		    " or discard error and break loop if $VIMNOERRTHROW
+		    break
+		endif
+	    endtry
+	endwhile
+
+	while 1
+	    try
+		Xpath 1048576			" X: 1048576
+		let caught = 0
+		doautocmd User x3
+	    catch /Vim:Interrupt/
+		let caught = 1
+	    finally
+		Xpath 2097152			" X: 2097152
+		if !caught && !$VIMNOINTTHROW
+		    Xpath 4194304		" X: 0
+		    " Propagate uncaught interrupt exception,
+		else
+		    " ... but break loop for caught interrupt exception,
+		    " or discard interrupt and break loop if $VIMNOINTTHROW
+		    break
+		endif
+	    endtry
+	endwhile
+
+	if exists("*U1") | delfunction U1 | endif
+	if exists("*U2") | delfunction U2 | endif
+	if exists("*U3") | delfunction U3 | endif
+
+	try
+	    Xpath 8388608			" X: 8388608
+	    call U1()
+	catch /U1/
+	    Xpath 16777216			" X: 16777216
+	endtry
+
+	while 1
+	    try
+		Xpath 33554432			" X: 33554432
+		let caught = 0
+		call U2()
+	    catch /ASDF/
+		let caught = 1
+	    finally
+		Xpath 67108864			" X: 67108864
+		if !caught && !$VIMNOERRTHROW
+		    Xpath 134217728		" X: 0
+		    " Propagate uncaught error exception,
+		else
+		    " ... but break loop for caught error exception,
+		    " or discard error and break loop if $VIMNOERRTHROW
+		    break
+		endif
+	    endtry
+	endwhile
+
+	while 1
+	    try
+		Xpath 268435456			" X: 268435456
+		let caught = 0
+		call U3()
+	    catch /Vim:Interrupt/
+		let caught = 1
+	    finally
+		Xpath 536870912			" X: 536870912
+		if !caught && !$VIMNOINTTHROW
+		    Xpath 1073741824		" X: 0
+		    " Propagate uncaught interrupt exception,
+		else
+		    " ... but break loop for caught interrupt exception,
+		    " or discard interrupt and break loop if $VIMNOINTTHROW
+		    break
+		endif
+	    endtry
+	endwhile
+    catch /.*/
+	" The Xpath command does not accept 2^31 (negative); display explicitly:
+	exec "!echo 2147483648 >>" . g:ExtraVimResult
+	Xout "Caught" v:exception "in" v:throwpoint
+    endtry
+
+    unlet caught
+    delfunction INT
+    delfunction U1
+    delfunction U2
+    delfunction U3
+    au! TMP
+    aug! TMP
+endif
+
+Xcheck 934782101
+
+
+"-------------------------------------------------------------------------------
+" Test 85:  Error exceptions in autocommands for I/O command events	    {{{1
+"
+"	    When an I/O command is inside :try/:endtry, autocommands to be
+"	    executed after it should be skipped on an error (exception) in the
+"	    command itself or in autocommands to be executed before the command.
+"	    In the latter case, the I/O command should not be executed either.
+"	    Example 1: BufWritePre, :write, BufWritePost
+"	    Example 2: FileReadPre, :read, FileReadPost.
+"-------------------------------------------------------------------------------
+
+XpathINIT
+
+function! MSG(enr, emsg)
+    let english = v:lang == "C" || v:lang =~ '^[Ee]n'
+    if a:enr == ""
+	Xout "TODO: Add message number for:" a:emsg
+	let v:errmsg = ":" . v:errmsg
+    endif
+    let match = 1
+    if v:errmsg !~ '^'.a:enr.':' || (english && v:errmsg !~ a:emsg)
+	let match = 0
+	if v:errmsg == ""
+	    Xout "Message missing."
+	else
+	    let v:errmsg = escape(v:errmsg, '"')
+	    Xout "Unexpected message:" v:errmsg
+	endif
+    endif
+    return match
+endfunction
+
+" Remove the autocommands for the events specified as arguments in all used
+" autogroups.
+function! Delete_autocommands(...)
+    let augfile = tempname()
+    while 1
+	try
+	    exec "redir >" . augfile
+	    aug
+	    redir END
+	    exec "edit" augfile
+	    g/^$/d
+	    norm G$
+	    let wrap = "w"
+	    while search('\%(  \|^\)\@<=.\{-}\%(  \)\@=', wrap) > 0
+		let wrap = "W"
+		exec "norm y/  \n"
+		let argno = 1
+		while argno <= a:0
+		    exec "au!" escape(@", " ") a:{argno}
+		    let argno = argno + 1
+		endwhile
+	    endwhile
+	catch /.*/
+	finally
+	    bwipeout!
+	    call delete(augfile)
+	    break		" discard errors for $VIMNOERRTHROW
+	endtry
+    endwhile
+endfunction
+
+call Delete_autocommands("BufWritePre", "BufWritePost")
+
+while 1
+    try
+	try
+	    let post = 0
+	    aug TMP
+		au! BufWritePost * let post = 1
+	    aug END
+	    let caught = 0
+	    write /n/o/n/e/x/i/s/t/e/n/t
+	catch /^Vim(write):/
+	    let caught = 1
+	    let v:errmsg = substitute(v:exception, '^Vim(write):', '', "")
+	finally
+	    Xpath 1				" X: 1
+	    if !caught && !$VIMNOERRTHROW
+		Xpath 2				" X: 0
+	    endif
+	    let v:errmsg = substitute(v:errmsg, '^"/n/o/n/e/x/i/s/t/e/n/t" ',
+		\ '', "")
+	    if !MSG('E212', "Can't open file for writing")
+		Xpath 4				" X: 0
+	    endif
+	    if post
+		Xpath 8				" X: 0
+		Xout "BufWritePost commands executed after write error"
+	    endif
+	    au! TMP
+	    aug! TMP
+	endtry
+    catch /.*/
+	Xpath 16				" X: 0
+	Xout v:exception "in" v:throwpoint
+    finally
+	break		" discard error for $VIMNOERRTHROW
+    endtry
+endwhile
+
+while 1
+    try
+	try
+	    let post = 0
+	    aug TMP
+		au! BufWritePre  * asdf
+		au! BufWritePost * let post = 1
+	    aug END
+	    let tmpfile = tempname()
+	    let caught = 0
+	    exec "write" tmpfile
+	catch /^Vim\((write)\)\=:/
+	    let caught = 1
+	    let v:errmsg = substitute(v:exception, '^Vim\((write)\)\=:', '', "")
+	finally
+	    Xpath 32				" X: 32
+	    if !caught && !$VIMNOERRTHROW
+		Xpath 64			" X: 0
+	    endif
+	    let v:errmsg = substitute(v:errmsg, '^"'.tmpfile.'" ', '', "")
+	    if !MSG('E492', "Not an editor command")
+		Xpath 128			" X: 0
+	    endif
+	    if filereadable(tmpfile)
+		Xpath 256			" X: 0
+		Xout ":write command not suppressed after BufWritePre error"
+	    endif
+	    if post
+		Xpath 512			" X: 0
+		Xout "BufWritePost commands executed after BufWritePre error"
+	    endif
+	    au! TMP
+	    aug! TMP
+	endtry
+    catch /.*/
+	Xpath 1024				" X: 0
+	Xout v:exception "in" v:throwpoint
+    finally
+	break		" discard error for $VIMNOERRTHROW
+    endtry
+endwhile
+
+call delete(tmpfile)
+
+call Delete_autocommands("BufWritePre", "BufWritePost",
+    \ "BufReadPre", "BufReadPost", "FileReadPre", "FileReadPost")
+
+while 1
+    try
+	try
+	    let post = 0
+	    aug TMP
+		au! FileReadPost * let post = 1
+	    aug END
+	    let caught = 0
+	    read /n/o/n/e/x/i/s/t/e/n/t
+	catch /^Vim(read):/
+	    let caught = 1
+	    let v:errmsg = substitute(v:exception, '^Vim(read):', '', "")
+	finally
+	    Xpath 2048				" X: 2048
+	    if !caught && !$VIMNOERRTHROW
+		Xpath 4096			" X: 0
+	    endif
+	    let v:errmsg = substitute(v:errmsg, ' /n/o/n/e/x/i/s/t/e/n/t$',
+		\ '', "")
+	    if !MSG('E484', "Can't open file")
+		Xpath 8192			" X: 0
+	    endif
+	    if post
+		Xpath 16384			" X: 0
+		Xout "FileReadPost commands executed after write error"
+	    endif
+	    au! TMP
+	    aug! TMP
+	endtry
+    catch /.*/
+	Xpath 32768				" X: 0
+	Xout v:exception "in" v:throwpoint
+    finally
+	break		" discard error for $VIMNOERRTHROW
+    endtry
+endwhile
+
+while 1
+    try
+	let infile = tempname()
+	let tmpfile = tempname()
+	exec "!echo XYZ >" . infile
+	exec "edit" tmpfile
+	try
+	    Xpath 65536				" X: 65536
+	    try
+		let post = 0
+		aug TMP
+		    au! FileReadPre  * asdf
+		    au! FileReadPost * let post = 1
+		aug END
+		let caught = 0
+		exec "0read" infile
+	    catch /^Vim\((read)\)\=:/
+		let caught = 1
+		let v:errmsg = substitute(v:exception, '^Vim\((read)\)\=:', '',
+		    \ "")
+	    finally
+		Xpath 131072			" X: 131072
+		if !caught && !$VIMNOERRTHROW
+		    Xpath 262144		" X: 0
+		endif
+		let v:errmsg = substitute(v:errmsg, ' '.infile.'$', '', "")
+		if !MSG('E492', "Not an editor command")
+		    Xpath 524288		" X: 0
+		endif
+		if getline("1") == "XYZ"
+		    Xpath 1048576		" X: 0
+		    Xout ":read command not suppressed after FileReadPre error"
+		endif
+		if post
+		    Xpath 2097152		" X: 0
+		    Xout "FileReadPost commands executed after " .
+			\ "FileReadPre error"
+		endif
+		au! TMP
+		aug! TMP
+	    endtry
+	finally
+	    bwipeout!
+	endtry
+    catch /.*/
+	Xpath 4194304				" X: 0
+	Xout v:exception "in" v:throwpoint
+    finally
+	break		" discard error for $VIMNOERRTHROW
+    endtry
+endwhile
+
+call delete(infile)
+call delete(tmpfile)
+unlet! caught post infile tmpfile
+delfunction MSG
+delfunction Delete_autocommands
+
+Xcheck 198689
+
+
+"-------------------------------------------------------------------------------
+" Test 86:  $VIMNOERRTHROW and $VIMNOINTTHROW support			    {{{1
+"
+"	    It is possible to configure Vim for throwing exceptions on error
+"	    or interrupt, controlled by variables $VIMNOERRTHROW and
+"	    $VIMNOINTTHROW.  This is just for increasing the number of tests.
+"	    All tests here should run for all four combinations of setting
+"	    these variables to 0 or 1.  The variables are intended for the
+"	    development phase only.  In the final release, Vim should be
+"	    configured to always use error and interrupt exceptions.
+"
+"	    The test result is "OK",
+"
+"		- if the $VIMNOERRTHROW and the $VIMNOINTTHROW control are not
+"		  configured and exceptions are thrown on error and on
+"		  interrupt.
+"
+"		- if the $VIMNOERRTHROW or the $VIMNOINTTHROW control is
+"		  configured and works as intended.
+"
+"	    What actually happens, is shown in the test output.
+"
+"	    Otherwise, the test result is "FAIL", and the test output describes
+"	    the problem.
+"
+" IMPORTANT:  This must be the last test because it sets $VIMNOERRTHROW and
+"	      $VIMNOINTTHROW.
+"-------------------------------------------------------------------------------
+
+XpathINIT
+
+if ExtraVim()
+
+    function! ThrowOnError()
+	XloopNEXT
+	let caught = 0
+	try
+	    Xloop 1				" X: 1 + 8 + 64
+	    asdf
+	catch /.*/
+	    let caught = 1	" error exception caught
+	finally
+	    Xloop 2				" X: 2 + 16 + 128
+	    return caught	" discard aborting error
+	endtry
+	Xloop 4					" X: 0
+    endfunction
+
+    let quits_skipped = 0
+
+    function! ThrowOnInterrupt()
+	XloopNEXT
+	let caught = 0
+	try
+	    Xloop 1				" X: (1 + 8 + 64) * 512
+	    "INTERRUPT3
+	    let dummy = 0
+	    let g:quits_skipped = g:quits_skipped + 1
+	catch /.*/
+	    let caught = 1	" interrupt exception caught
+	finally
+	    Xloop 2				" X: (2 + 16 + 128) * 512
+	    return caught	" discard interrupt
+	endtry
+	Xloop 4					" X: 0
+    endfunction
+
+    function! CheckThrow(Type)
+	execute 'return ThrowOn' . a:Type . '()'
+    endfunction
+
+    function! CheckConfiguration(type)	    " type is "error" or "interrupt"
+
+	let type = a:type
+	let Type = substitute(type, '.*', '\u&', "")
+	let VAR = '$VIMNO' . substitute(type, '\(...\).*', '\U\1', "") . 'THROW'
+
+	if type == "error"
+	    XloopINIT! 1 8
+	elseif type == "interrupt"
+	    XloopINIT! 512 8
+	endif
+
+	exec 'let requested_for_tests = exists(VAR) && ' . VAR . ' == 0'
+	exec 'let suppressed_for_tests = ' . VAR . ' != 0'
+	let used_in_tests = CheckThrow(Type)
+
+	exec 'let ' . VAR . ' = 0'
+	let request_works = CheckThrow(Type)
+
+	exec 'let ' . VAR . ' = 1'
+	let suppress_works = !CheckThrow(Type)
+
+	if type == "error"
+	    XloopINIT! 262144 8
+	elseif type == "interrupt"
+	    XloopINIT! 2097152 8
+
+	    if g:quits_skipped != 0
+		Xloop 1				" X: 0*2097152
+		Xout "Test environment error.  Interrupt breakpoints skipped: "
+		    \ . g:quits_skipped . ".\n"
+		    \ . "Cannot check whether interrupt exceptions are thrown."
+		return
+	    endif
+	endif
+
+	let failure =
+	    \ !suppressed_for_tests && !used_in_tests
+	    \ || !request_works
+
+	let contradiction =
+	    \ used_in_tests
+		\ ? suppressed_for_tests && !request_works
+		\ : !suppressed_for_tests
+
+	if failure
+	    " Failure in configuration.
+	    Xloop 2				" X: 0 * 2*  (262144 + 2097152)
+	elseif contradiction
+	    " Failure in test logic.  Should not happen.
+	    Xloop 4				" X: 0 * 4 * (262144 + 2097152)
+	endif
+
+	let var_control_configured =
+	    \ request_works != used_in_tests
+	    \ || suppress_works == used_in_tests
+
+	let var_control_not_configured =
+	    \ requested_for_tests || suppressed_for_tests
+		\ ? request_works && !suppress_works
+		\ : request_works == used_in_tests
+		    \ && suppress_works != used_in_tests
+
+	let with = used_in_tests ? "with" : "without"
+
+	let set = suppressed_for_tests ? "non-zero" :
+	    \ requested_for_tests ? "0" : "unset"
+
+	let although = contradiction && !var_control_not_configured
+	    \ ? ",\nalthough "
+	    \ : ".\n"
+
+	let output = "All tests were run " . with . " throwing exceptions on "
+	    \ . type . although
+
+	if !var_control_not_configured
+	    let output = output . VAR . " was " . set . "."
+
+	    if !request_works && !requested_for_tests
+		let output = output .
+		    \ "\n" . Type . " exceptions are not thrown when " . VAR .
+		    \ " is\nset to 0."
+	    endif
+
+	    if !suppress_works && (!used_in_tests ||
+	    \ !request_works &&
+	    \ !requested_for_tests && !suppressed_for_tests)
+		let output = output .
+		    \ "\n" . Type . " exceptions are thrown when " . VAR .
+		    \ " is set to 1."
+	    endif
+
+	    if !failure && var_control_configured
+		let output = output .
+		    \ "\nRun tests also with " . substitute(VAR, '^\$', '', "")
+		    \ . "=" . used_in_tests . "."
+		    \ . "\nThis is for testing in the development phase only."
+		    \ . "  Remove the \n"
+		    \ . VAR . " control in the final release."
+	    endif
+	else
+	    let output = output .
+		\ "The " . VAR . " control is not configured."
+	endif
+
+	Xout output
+    endfunction
+
+    call CheckConfiguration("error")
+    Xpath 16777216				" X: 16777216
+    call CheckConfiguration("interrupt")
+    Xpath 33554432				" X: 33554432
+endif
+
+Xcheck 50443995
+
+" IMPORTANT: No test should be added after this test because it changes
+"	     $VIMNOERRTHROW and $VIMNOINTTHROW.
+
+
+"-------------------------------------------------------------------------------
+" Modelines								    {{{1
+" vim: ts=8 sw=4 tw=80 fdm=marker
+" vim: fdt=substitute(substitute(foldtext(),\ '\\%(^+--\\)\\@<=\\(\\s*\\)\\(.\\{-}\\)\:\ \\%(\"\ \\)\\=\\(Test\ \\d*\\)\:\\s*',\ '\\3\ (\\2)\:\ \\1',\ \"\"),\ '\\(Test\\s*\\)\\(\\d\\)\\D\\@=',\ '\\1\ \\2',\ "")
+"-------------------------------------------------------------------------------
--- /dev/null
+++ b/testdir/test5.in
@@ -1,0 +1,29 @@
+Test for autocommand that deletes the current buffer on BufLeave event.
+Also test deleting the last buffer, should give a new, empty buffer.
+
+STARTTEST
+:so small.vim
+:au BufLeave Xxx bwipe
+/start of
+:.,/end of/w! Xxx               " write test file Xxx
+:sp Xxx                         " split to Xxx
+:bwipe                          " delete buffer Xxx, now we're back here
+G?this is a
+othis is some more text
+:                               " Append some text to this file
+:?start?,$w! test.out           " Write current file contents
+:bwipe test.out                 " delete alternate buffer
+:au bufleave test5.in bwipe
+:bwipe!                         " delete current buffer, get an empty one
+ithis is another test line:w >>test.out
+:                               " append an extra line to the output file
+:qa!
+ENDTEST
+
+start of test file Xxx
+vim: set noai :
+	this is a test
+	this is a test
+	this is a test
+	this is a test
+end of test file Xxx
--- /dev/null
+++ b/testdir/test5.ok
@@ -1,0 +1,9 @@
+start of test file Xxx
+vim: set noai :
+	this is a test
+	this is a test
+	this is a test
+	this is a test
+this is some more text
+end of test file Xxx
+this is another test line
--- /dev/null
+++ b/testdir/test50.in
@@ -1,0 +1,85 @@
+Test for shortpathname ':8' extension.
+Only for use on Win32 systems!
+
+STARTTEST
+:so small.vim
+:fun! TestIt(file, bits, expected)
+	let res=fnamemodify(a:file,a:bits)
+	if a:expected == ''
+		echo "'".a:file."'->(".a:bits.")->'".res."'"
+	else
+		if substitute(res,'/','\\', 'g') != substitute( a:expected, '/','\\', 'g') 
+			echo "FAILED: '".a:file."'->(".a:bits.")->'".res."'"
+			echo "Expected: '".a:expected."'"
+		else
+			echo "OK"
+		endif
+	endif
+endfun
+:fun! MakeDir( dirname )
+	"exe '!mkdir '.substitute(a:dirname,'/','\\','g')
+	call system('mkdir '.substitute(a:dirname,'/','\\','g'))
+endfun
+:fun! RMDir( dirname)
+	"exe '!rmdir '.substitute(a:dirname,'/','\\','g')
+	call system('rmdir '.substitute(a:dirname,'/','\\','g'))
+endfun
+:fun! MakeFile( filename)
+	"exe '!copy nul '.substitute(a:filename,'/','\\','g')
+	call system('copy nul '.substitute(a:filename,'/','\\','g'))
+endfun
+:fun! TestColonEight()
+   redir! >test.out
+	" This could change for CygWin to //cygdrive/c
+	let dir1='c:/x.x.y'
+	if filereadable(dir1) || isdirectory(dir1)
+		call confirm( "'".dir1."' exists, cannot run test" )
+		return
+	endif
+	let file1=dir1.'/zz.y.txt'
+	let nofile1=dir1.'/z.y.txt'
+	let dir2=dir1.'/VimIsTheGreatestSinceSlicedBread'
+	let file2=dir2.'/z.txt'
+	let nofile2=dir2.'/zz.txt'
+	let resdir1='c:/XX2235~1.Y'
+	let resfile1=resdir1.'/ZZY~1.TXT'
+	let resnofile1=resdir1.'/z.y.txt'
+	let resdir2=resdir1.'/VIMIST~1'
+	let resfile2=resdir2.'/z.txt'
+	let resnofile2=resdir2.'/zz.txt'
+	call MakeDir( dir1 )
+	call MakeDir( dir2 )
+	call MakeFile( file1 )
+	call MakeFile( file2 )
+	call TestIt(file1, ':p:8', resfile1)
+	call TestIt(nofile1, ':p:8', resnofile1)
+	call TestIt(file2, ':p:8', resfile2)
+	call TestIt(nofile2, ':p:8', resnofile2)
+	call TestIt(nofile2, ':p:8:h', fnamemodify(resnofile2,':h'))
+	exe 'cd '.dir1
+	call TestIt(file1, ':.:8', strpart(resfile1,strlen(resdir1)+1))
+	call TestIt(nofile1, ':.:8', strpart(resnofile1,strlen(resdir1)+1))
+	call TestIt(file2, ':.:8', strpart(resfile2,strlen(resdir1)+1))
+	call TestIt(nofile2, ':.:8', strpart(resnofile2,strlen(resdir1)+1))
+	let $HOME=dir1
+	call TestIt(file1, ':~:8', '~'.strpart(resfile1,strlen(resdir1)))
+	call TestIt(nofile1, ':~:8', '~'.strpart(resnofile1,strlen(resdir1)))
+	call TestIt(file2, ':~:8', '~'.strpart(resfile2,strlen(resdir1)))
+	call TestIt(nofile2, ':~:8', '~'.strpart(resnofile2,strlen(resdir1)))
+	cd c:/
+	call delete( file2 )
+	call delete( file1 )
+	call RMDir( dir2 )
+	call RMDir( dir1 )
+       echo
+   redir END
+endfun
+:let dir = getcwd()
+:call TestColonEight()
+:exe "cd " . dir
+:edit! test.out
+:set ff=dos
+:w
+:qa!
+ENDTEST
+
--- /dev/null
+++ b/testdir/test50.ok
@@ -1,0 +1,14 @@
+
+OK
+OK
+OK
+OK
+OK
+OK
+OK
+OK
+OK
+OK
+OK
+OK
+OK
--- /dev/null
+++ b/testdir/test51.in
@@ -1,0 +1,36 @@
+Tests for ":highlight". vim: set ft=vim :
+
+STARTTEST
+:so small.vim
+:" basic test if ":highlight" doesn't crash
+:highlight
+:hi Search
+:" test setting colors.
+:" test clearing one color and all doesn't generate error or warning
+:hi NewGroup term=bold cterm=italic ctermfg=DarkBlue ctermbg=Grey gui= guifg=#00ff00 guibg=Cyan
+:hi Group2 term= cterm=
+:hi Group3 term=underline cterm=bold
+:redir! >test.out
+:hi NewGroup
+:hi Group2
+:hi Group3
+:hi clear NewGroup
+:hi NewGroup
+:hi Group2
+:hi Group2 NONE
+:hi Group2
+:hi clear
+:hi Group3
+:hi Crash term='asdf
+:redir END
+:" filter ctermfg and ctermbg, the numbers depend on the terminal
+:e test.out
+:%s/ctermfg=\d*/ctermfg=2/
+:%s/ctermbg=\d*/ctermbg=3/
+:" filter out possibly translated error message
+:%s/E475: [^:]*:/E475:/
+:" fix the fileformat
+:set ff&
+:wq!
+ENDTEST
+
--- /dev/null
+++ b/testdir/test51.ok
@@ -1,0 +1,20 @@
+
+
+NewGroup       xxx term=bold cterm=italic ctermfg=2 ctermbg=3
+
+Group2         xxx cleared
+
+Group3         xxx term=underline cterm=bold
+
+
+NewGroup       xxx cleared
+
+Group2         xxx cleared
+
+
+Group2         xxx cleared
+
+
+Group3         xxx cleared
+
+E475: term='asdf
--- /dev/null
+++ b/testdir/test52.in
@@ -1,0 +1,65 @@
+Tests for reading and writing files with conversion for Win32.
+
+STARTTEST
+:so mbyte.vim
+:" make this a dummy test for non-Win32 systems
+:if !has("win32") | e! test.ok | wq! test.out | endif
+:"
+:" write tests:
+:" combine three values for 'encoding' with three values for 'fileencoding'
+:" also write files for read tests
+/^1
+:set encoding=utf-8
+:.w! ++enc=utf-8 test.out
+:.w ++enc=cp1251 >>test.out
+:.w ++enc=cp866 >>test.out
+:.w! ++enc=utf-8 Xutf8
+/^2
+:set encoding=cp1251
+:.w ++enc=utf-8 >>test.out
+:.w ++enc=cp1251 >>test.out
+:.w ++enc=cp866 >>test.out
+:.w! ++enc=cp1251 Xcp1251
+/^3
+:set encoding=cp866
+:.w ++enc=utf-8 >>test.out
+:.w ++enc=cp1251 >>test.out
+:.w ++enc=cp866 >>test.out
+:.w! ++enc=cp866 Xcp866
+:"
+:" read three 'fileencoding's with utf-8 'encoding'
+:set encoding=utf-8 fencs=utf-8,cp1251
+:e Xutf8
+:.w ++enc=utf-8 >>test.out
+:e Xcp1251
+:.w ++enc=utf-8 >>test.out
+:set fencs=utf-8,cp866
+:e Xcp866
+:.w ++enc=utf-8 >>test.out
+:"
+:" read three 'fileencoding's with cp1251 'encoding'
+:set encoding=utf-8 fencs=utf-8,cp1251
+:e Xutf8
+:.w ++enc=cp1251 >>test.out
+:e Xcp1251
+:.w ++enc=cp1251 >>test.out
+:set fencs=utf-8,cp866
+:e Xcp866
+:.w ++enc=cp1251 >>test.out
+:"
+:" read three 'fileencoding's with cp866 'encoding'
+:set encoding=cp866 fencs=utf-8,cp1251
+:e Xutf8
+:.w ++enc=cp866 >>test.out
+:e Xcp1251
+:.w ++enc=cp866 >>test.out
+:set fencs=utf-8,cp866
+:e Xcp866
+:.w ++enc=cp866 >>test.out
+:"
+:qa!
+ENDTEST
+
+1 utf-8 text: Для Vim version 6.2.  Последнее изменение: 1970 Jan 01
+2 cp1251 text: ��� Vim version 6.2.  ��������� ���������: 1970 Jan 01
+3 cp866 text: ��� Vim version 6.2.  ��᫥���� ���������: 1970 Jan 01
--- /dev/null
+++ b/testdir/test52.ok
@@ -1,0 +1,18 @@
+1 utf-8 text: Для Vim version 6.2.  Последнее изменение: 1970 Jan 01
+1 utf-8 text: ��� Vim version 6.2.  ��������� ���������: 1970 Jan 01
+1 utf-8 text: ��� Vim version 6.2.  ��᫥���� ���������: 1970 Jan 01
+2 cp1251 text: Для Vim version 6.2.  Последнее изменение: 1970 Jan 01
+2 cp1251 text: ��� Vim version 6.2.  ��������� ���������: 1970 Jan 01
+2 cp1251 text: ��� Vim version 6.2.  ��᫥���� ���������: 1970 Jan 01
+3 cp866 text: Для Vim version 6.2.  Последнее изменение: 1970 Jan 01
+3 cp866 text: ��� Vim version 6.2.  ��������� ���������: 1970 Jan 01
+3 cp866 text: ��� Vim version 6.2.  ��᫥���� ���������: 1970 Jan 01
+1 utf-8 text: Для Vim version 6.2.  Последнее изменение: 1970 Jan 01
+2 cp1251 text: Для Vim version 6.2.  Последнее изменение: 1970 Jan 01
+3 cp866 text: Для Vim version 6.2.  Последнее изменение: 1970 Jan 01
+1 utf-8 text: ��� Vim version 6.2.  ��������� ���������: 1970 Jan 01
+2 cp1251 text: ��� Vim version 6.2.  ��������� ���������: 1970 Jan 01
+3 cp866 text: ��� Vim version 6.2.  ��������� ���������: 1970 Jan 01
+1 utf-8 text: ��� Vim version 6.2.  ��᫥���� ���������: 1970 Jan 01
+2 cp1251 text: ��� Vim version 6.2.  ��᫥���� ���������: 1970 Jan 01
+3 cp866 text: ��� Vim version 6.2.  ��᫥���� ���������: 1970 Jan 01
--- /dev/null
+++ b/testdir/test53.in
@@ -1,0 +1,48 @@
+Tests for string and html text objects. vim: set ft=vim :
+
+Note that the end-of-line moves the cursor to the next test line.
+
+Also test match() and matchstr()
+
+STARTTEST
+:so small.vim
+/^start:/
+da"
+0va'a'rx
+02f`da`
+0fXdi"
+03f'vi'ry
+:set quoteescape=+*-
+di`
+$F"va"oha"i"rz
+:"
+/^<begin
+jfXdit
+0fXdit
+fXdat
+0fXdat
+:"
+:put =matchstr(\"abcd\", \".\", 0, 2) " b
+:put =matchstr(\"abcd\", \"..\", 0, 2) " bc
+:put =matchstr(\"abcd\", \".\", 2, 0) " c (zero and negative -> first match)
+:put =matchstr(\"abcd\", \".\", 0, -1) " a
+:put =match(\"abcd\", \".\", 0, 5) " -1
+:put =match(\"abcd\", \".\", 0, -1) " 0
+:/^start:/,/^end:/wq! test.out
+ENDTEST
+
+start: "wo\"rd\\" foo
+'foo' 'bar' 'piep'
+bla bla `quote` blah
+out " in "noXno"
+"'" 'blah' rep 'buh'
+bla `s*`d-`+++`l**` b`la
+voo "nah" sdf " asdf" sdf " sdf" sd
+
+<begin>
+-<b>asdf<i>Xasdf</i>asdf</b>-
+-<b>asdX<i>a<i />sdf</i>asdf</b>-
+-<b>asdf<i>Xasdf</i>asdf</b>-
+-<b>asdX<i>as<b />df</i>asdf</b>-
+</begin>
+end:
--- /dev/null
+++ b/testdir/test53.ok
@@ -1,0 +1,21 @@
+start: foo
+xxxxxxxxxxxx'piep'
+bla bla blah
+out " in ""
+"'" 'blah'yyyyy'buh'
+bla `` b`la
+voo "zzzzzzzzzzzzzzzzzzzzzzzzzzzzsd
+
+<begin>
+-<b>asdf<i></i>asdf</b>-
+-<b></b>-
+-<b>asdfasdf</b>-
+--
+</begin>
+b
+bc
+c
+a
+-1
+0
+end:
--- /dev/null
+++ b/testdir/test54.in
@@ -1,0 +1,17 @@
+Some tests for buffer-local autocommands
+
+STARTTEST
+:so small.vim
+:e xx
+:!rm -f test.out
+:au BufLeave <buffer> :!echo buffer-local autommand in %>> test.out
+:e somefile           " here, autocommand for xx shall write test.out 
+:                     " but autocommand shall not apply to buffer named <buffer>
+:bwipe xx             " here, autocommand shall be auto-deleted
+:e xx                 " nothing shall be written
+:e somefile           " nothing shall be written
+:qa!
+ENDTEST
+
+start of test file xx
+end of test file xx
--- /dev/null
+++ b/testdir/test54.ok
@@ -1,0 +1,1 @@
+buffer-local autommand in xx
--- /dev/null
+++ b/testdir/test55.in
@@ -1,0 +1,351 @@
+Tests for List and Dictionary types.     vim: set ft=vim :
+
+STARTTEST
+:so small.vim
+:fun Test(...)
+:" Creating List directly with different types
+:let l = [1, 'as''d', [1, 2, function("strlen")], {'a': 1},]
+:$put =string(l)
+:$put =string(l[-1])
+:$put =string(l[-4])
+:try
+:  $put =string(l[-5])
+:catch
+:  $put =v:exception[:14]
+:endtry
+:" List slices
+:$put =string(l[:])
+:$put =string(l[1:])
+:$put =string(l[:-2])
+:$put =string(l[0:8])
+:$put =string(l[8:-1])
+:"
+:" List identity
+:let ll = l
+:let lx = copy(l)
+:try
+:  $put =(l == ll) . (l isnot ll) . (l is ll) . (l == lx) . (l is lx) . (l isnot lx)
+:catch
+:  $put =v:exception
+:endtry
+:"
+:" Creating Dictionary directly with different types
+:let d = {001: 'asd', 'b': [1, 2, function('strlen')], -1: {'a': 1},}
+:$put =string(d) . d.1
+:$put =string(sort(keys(d)))
+:$put =string (values(d))
+:for [key, val] in items(d)
+:  $put =key . ':' . string(val)
+:  unlet key val
+:endfor
+:call extend  (d, {3:33, 1:99})
+:call extend(d, {'b':'bbb', 'c':'ccc'}, "keep")
+:try
+:  call extend(d, {3:333,4:444}, "error")
+:catch
+:  $put =v:exception[:15] . v:exception[-1:-1]
+:endtry
+:$put =string(d)
+:call filter(d, 'v:key =~ ''[ac391]''')
+:$put =string(d)
+:"
+:" Dictionary identity
+:let dd = d
+:let dx = copy(d)
+:try
+:  $put =(d == dd) . (d isnot dd) . (d is dd) . (d == dx) . (d is dx) . (d isnot dx)
+:catch
+:  $put =v:exception
+:endtry
+:"
+:" Changing var type should fail
+:try
+:  let d = []
+:catch
+:  $put =v:exception[:14] . v:exception[-1:-1]
+:endtry
+:try
+:  let l = {}
+:catch
+:  $put =v:exception[:14] . v:exception[-1:-1]
+:endtry
+:"
+:" removing items with :unlet
+:unlet l[2]
+:$put =string(l)
+:let l = range(8)
+:try
+:unlet l[:3]
+:unlet l[1:]
+:catch
+:$put =v:exception
+:endtry
+:$put =string(l)
+:"
+:unlet d.c
+:unlet d[-1]
+:$put =string(d)
+:"
+:" removing items out of range: silently skip items that don't exist
+let l = [0, 1, 2, 3]
+:unlet l[2:1]
+:$put =string(l)
+let l = [0, 1, 2, 3]
+:unlet l[2:2]
+:$put =string(l)
+let l = [0, 1, 2, 3]
+:unlet l[2:3]
+:$put =string(l)
+let l = [0, 1, 2, 3]
+:unlet l[2:4]
+:$put =string(l)
+let l = [0, 1, 2, 3]
+:unlet l[2:5]
+:$put =string(l)
+let l = [0, 1, 2, 3]
+:unlet l[-1:2]
+:$put =string(l)
+let l = [0, 1, 2, 3]
+:unlet l[-2:2]
+:$put =string(l)
+let l = [0, 1, 2, 3]
+:unlet l[-3:2]
+:$put =string(l)
+let l = [0, 1, 2, 3]
+:unlet l[-4:2]
+:$put =string(l)
+let l = [0, 1, 2, 3]
+:unlet l[-5:2]
+:$put =string(l)
+let l = [0, 1, 2, 3]
+:unlet l[-6:2]
+:$put =string(l)
+:"
+:" assignment to a list
+:let l = [0, 1, 2, 3]
+:let [va, vb] = l[2:3]
+:$put =va
+:$put =vb
+:try
+:  let [va, vb] = l
+:catch
+:  $put =v:exception[:14]
+:endtry
+:try
+:  let [va, vb] = l[1:1]
+:catch
+:  $put =v:exception[:14]
+:endtry
+:"
+:" manipulating a big Dictionary (hashtable.c has a border of 1000 entries)
+:let d = {}
+:for i in range(1500)
+: let d[i] = 3000 - i
+:endfor
+:$put =d[0] . ' ' . d[100] . ' ' . d[999] . ' ' . d[1400] . ' ' . d[1499]
+:try
+:  let n = d[1500]
+:catch
+:  $put =v:exception[:14] . v:exception[-4:-1]
+:endtry
+:" lookup each items
+:for i in range(1500)
+: if d[i] != 3000 - i
+:  $put =d[i]
+: endif
+:endfor
+: let i += 1
+:" delete even items
+:while i >= 2
+: let i -= 2
+: unlet d[i]
+:endwhile
+:$put =get(d, 1500 - 100, 'NONE') . ' ' . d[1]
+:" delete odd items, checking value, one intentionally wrong
+:let d[33] = 999
+:let i = 1
+:while i < 1500
+: if d[i] != 3000 - i
+:  $put =i . '=' . d[i]
+: else
+:  unlet d[i]
+: endif
+: let i += 2
+:endwhile
+:$put =string(d)  " must be almost empty now
+:unlet d
+:"
+:" Dictionary function
+:let dict = {}
+:func dict.func(a) dict
+:  $put =a:a . len(self.data)
+:endfunc
+:let dict.data = [1,2,3]
+:call dict.func("len: ")
+:let x = dict.func("again: ")
+:try
+:  let Fn = dict.func
+:  call Fn('xxx')
+:catch
+:  $put =v:exception[:15]
+:endtry
+:" 
+:" Function in script-local List or Dict
+:let g:dict = {}
+:function g:dict.func() dict
+:  $put ='g:dict.func'.self.foo[1].self.foo[0]('asdf')
+:endfunc
+:let g:dict.foo = ['-', 2, 3]
+:call insert(g:dict.foo, function('strlen'))
+:call g:dict.func()
+:" 
+:" Nasty: remove func from Dict that's being called (works)
+:let d = {1:1}
+:func d.func(a)
+:  return "a:". a:a
+:endfunc
+:$put =d.func(string(remove(d, 'func')))
+:"
+:" Nasty: deepcopy() dict that refers to itself (fails when noref used)
+:let d = {1:1, 2:2}
+:let l = [4, d, 6]
+:let d[3] = l
+:let dc = deepcopy(d)
+:try
+:  let dc = deepcopy(d, 1)
+:catch
+:  $put =v:exception[:14]
+:endtry
+:let l2 = [0, l, l, 3]
+:let l[1] = l2
+:let l3 = deepcopy(l2)
+:$put ='same list: ' . (l3[1] is l3[2])
+:"
+:" Locked variables
+:for depth in range(5)
+:  $put ='depth is ' . depth
+:  for u in range(3)
+:    unlet l
+:    let l = [0, [1, [2, 3]], {4: 5, 6: {7: 8}}]
+:    exe "lockvar " . depth . " l"
+:    if u == 1
+:      exe "unlockvar l"
+:    elseif u == 2
+:      exe "unlockvar " . depth . " l"
+:    endif
+:    let ps = islocked("l").islocked("l[1]").islocked("l[1][1]").islocked("l[1][1][0]").'-'.islocked("l[2]").islocked("l[2]['6']").islocked("l[2]['6'][7]")
+:    $put =ps
+:    let ps = ''
+:    try
+:      let l[1][1][0] = 99
+:      let ps .= 'p'
+:    catch
+:      let ps .= 'F'
+:    endtry
+:    try
+:      let l[1][1] = [99]
+:      let ps .= 'p'
+:    catch
+:      let ps .= 'F'
+:    endtry
+:    try
+:      let l[1] = [99]
+:      let ps .= 'p'
+:    catch
+:      let ps .= 'F'
+:    endtry
+:    try
+:      let l[2]['6'][7] = 99
+:      let ps .= 'p'
+:    catch
+:      let ps .= 'F'
+:    endtry
+:    try
+:      let l[2][6] = {99: 99}
+:      let ps .= 'p'
+:    catch
+:      let ps .= 'F'
+:    endtry
+:    try
+:      let l[2] = {99: 99}
+:      let ps .= 'p'
+:    catch
+:      let ps .= 'F'
+:    endtry
+:    try
+:      let l = [99]
+:      let ps .= 'p'
+:    catch
+:      let ps .= 'F'
+:    endtry
+:    $put =ps
+:  endfor
+:endfor
+:"
+:" a:000 function argument
+:" first the tests that should fail
+:try
+:  let a:000 = [1, 2]
+:catch
+:  $put ='caught a:000'
+:endtry
+:try
+:  let a:000[0] = 9
+:catch
+:  $put ='caught a:000[0]'
+:endtry
+:try
+:  let a:000[2] = [9, 10]
+:catch
+:  $put ='caught a:000[2]'
+:endtry
+:try
+:  let a:000[3] = {9: 10}
+:catch
+:  $put ='caught a:000[3]'
+:endtry
+:" now the tests that should pass
+:try
+:  let a:000[2][1] = 9
+:  call extend(a:000[2], [5, 6])
+:  let a:000[3][5] = 8
+:  let a:000[3]['a'] = 12
+:  $put =string(a:000)
+:catch
+:  $put ='caught ' . v:exception
+:endtry
+:"
+:" reverse() and sort()
+:let l = ['-0', 'A11', 2, 'xaaa', 4, 'foo', 'foo6', [0, 1, 2], 'x8']
+:$put =string(reverse(l))
+:$put =string(reverse(reverse(l)))
+:$put =string(sort(l))
+:$put =string(reverse(sort(l)))
+:$put =string(sort(reverse(sort(l))))
+:"
+:" splitting a string to a List
+:$put =string(split('  aa  bb '))
+:$put =string(split('  aa  bb  ', '\W\+', 0))
+:$put =string(split('  aa  bb  ', '\W\+', 1))
+:$put =string(split('  aa  bb  ', '\W', 1))
+:$put =string(split(':aa::bb:', ':', 0))
+:$put =string(split(':aa::bb:', ':', 1))
+:$put =string(split('aa,,bb, cc,', ',\s*', 1))
+:$put =string(split('abc', '\zs'))
+:$put =string(split('abc', '\zs', 1))
+:"
+:" compare recursively linked list and dict
+:let l = [1, 2, 3, 4]
+:let d = {'1': 1, '2': l, '3': 3}
+:let l[1] = d
+:$put =(l == l)
+:$put =(d == d)
+:$put =(l != deepcopy(l))
+:$put =(d != deepcopy(d))
+:endfun
+:call Test(1, 2, [3, 4], {5: 6})  " This may take a while
+:"
+:/^start:/,$wq! test.out
+ENDTEST
+
+start:
--- /dev/null
+++ b/testdir/test55.ok
@@ -1,0 +1,111 @@
+start:
+[1, 'as''d', [1, 2, function('strlen')], {'a': 1}]
+{'a': 1}
+1
+Vim(put):E684: 
+[1, 'as''d', [1, 2, function('strlen')], {'a': 1}]
+['as''d', [1, 2, function('strlen')], {'a': 1}]
+[1, 'as''d', [1, 2, function('strlen')]]
+[1, 'as''d', [1, 2, function('strlen')], {'a': 1}]
+[]
+101101
+{'1': 'asd', 'b': [1, 2, function('strlen')], '-1': {'a': 1}}asd
+['-1', '1', 'b']
+['asd', [1, 2, function('strlen')], {'a': 1}]
+1:'asd'
+b:[1, 2, function('strlen')]
+-1:{'a': 1}
+Vim(call):E737: 3
+{'c': 'ccc', '1': 99, 'b': [1, 2, function('strlen')], '3': 33, '-1': {'a': 1}}
+{'c': 'ccc', '1': 99, '3': 33, '-1': {'a': 1}}
+101101
+Vim(let):E706: d
+Vim(let):E706: l
+[1, 'as''d', {'a': 1}]
+[4]
+{'1': 99, '3': 33}
+[0, 1, 2, 3]
+[0, 1, 3]
+[0, 1]
+[0, 1]
+[0, 1]
+[0, 1, 2, 3]
+[0, 1, 3]
+[0, 3]
+[3]
+[3]
+[3]
+2
+3
+Vim(let):E687: 
+Vim(let):E688: 
+3000 2900 2001 1600 1501
+Vim(let):E716: 1500
+NONE 2999
+33=999
+{'33': 999}
+len: 3
+again: 3
+Vim(call):E725: 
+g:dict.func-4
+a:function('3')
+Vim(let):E698: 
+same list: 1
+depth is 0
+0000-000
+ppppppp
+0000-000
+ppppppp
+0000-000
+ppppppp
+depth is 1
+1000-000
+ppppppF
+0000-000
+ppppppp
+0000-000
+ppppppp
+depth is 2
+1100-100
+ppFppFF
+0000-000
+ppppppp
+0000-000
+ppppppp
+depth is 3
+1110-110
+pFFpFFF
+0010-010
+pFppFpp
+0000-000
+ppppppp
+depth is 4
+1111-111
+FFFFFFF
+0011-011
+FFpFFpp
+0000-000
+ppppppp
+caught a:000
+caught a:000[0]
+caught a:000[2]
+caught a:000[3]
+[1, 2, [3, 9, 5, 6], {'a': 12, '5': 8}]
+['x8', [0, 1, 2], 'foo6', 'foo', 4, 'xaaa', 2, 'A11', '-0']
+['x8', [0, 1, 2], 'foo6', 'foo', 4, 'xaaa', 2, 'A11', '-0']
+['-0', 'A11', 'foo', 'foo6', 'x8', 'xaaa', 2, 4, [0, 1, 2]]
+[[0, 1, 2], 4, 2, 'xaaa', 'x8', 'foo6', 'foo', 'A11', '-0']
+['-0', 'A11', 'foo', 'foo6', 'x8', 'xaaa', 2, 4, [0, 1, 2]]
+['aa', 'bb']
+['aa', 'bb']
+['', 'aa', 'bb', '']
+['', '', 'aa', '', 'bb', '', '']
+['aa', '', 'bb']
+['', 'aa', '', 'bb', '']
+['aa', '', 'bb', 'cc', '']
+['a', 'b', 'c']
+['', 'a', '', 'b', '', 'c', '']
+1
+1
+0
+0
--- /dev/null
+++ b/testdir/test56.in
@@ -1,0 +1,21 @@
+Test for script-local function.     vim: set ft=vim :
+
+STARTTEST
+:so small.vim
+:"
+:set nocp viminfo+=nviminfo
+:/^start:/+1,/^end:/-1w! Xtest.vim
+:source Xtest.vim
+_x
+:$-1,$wq! test.out
+ENDTEST
+
+start:
+fun <SID>DoLast()
+  call append(line('$'), "last line")
+endfun
+fun s:DoNothing()
+  call append(line('$'), "nothing line")
+endfun
+nnoremap <buffer> _x	:call <SID>DoNothing()<bar>call <SID>DoLast()<cr>
+end:
--- /dev/null
+++ b/testdir/test56.ok
@@ -1,0 +1,2 @@
+nothing line
+last line
--- /dev/null
+++ b/testdir/test57.in
@@ -1,0 +1,496 @@
+Tests for :sort command.     vim: set ft=vim :
+
+STARTTEST
+:so small.vim
+:"
+:/^t01:/+1,/^t02/-1sort
+:/^t02:/+1,/^t03/-1sort n
+:/^t03:/+1,/^t04/-1sort x
+:/^t04:/+1,/^t05/-1sort u
+:/^t05:/+1,/^t06/-1sort!
+:/^t06:/+1,/^t07/-1sort! n        
+:/^t07:/+1,/^t08/-1sort! u
+:/^t08:/+1,/^t09/-1sort o         
+:/^t09:/+1,/^t10/-1sort! x        
+:/^t10:/+1,/^t11/-1sort/./        
+:/^t11:/+1,/^t12/-1sort/../       
+:/^t12:/+1,/^t13/-1sort/../u
+:/^t13:/+1,/^t14/-1sort/./n
+:/^t14:/+1,/^t15/-1sort/./r
+:/^t15:/+1,/^t16/-1sort/../r
+:/^t16:/+1,/^t17/-1sort/./rn
+:/^t17:/+1,/^t18/-1sort/\d/
+:/^t18:/+1,/^t19/-1sort/\d/r
+:/^t19:/+1,/^t20/-1sort/\d/n
+:/^t20:/+1,/^t21/-1sort/\d/rn
+:/^t21:/+1,/^t22/-1sort/\d\d/
+:/^t22:/+1,/^t23/-1sort/\d\d/n
+:/^t23:/+1,/^t24/-1sort/\d\d/x
+:/^t24:/+1,/^t25/-1sort/\d\d/r
+:/^t25:/+1,/^t26/-1sort/\d\d/rn
+:/^t26:/+1,/^t27/-1sort/\d\d/rx
+:/^t27:/+1,/^t28/-1sort no
+:/^t01:/,$wq! test.out
+ENDTEST
+
+t01: alphebetical
+abc
+ab
+a
+a321
+a123
+a122
+b321
+b123
+c123d
+ 123b
+c321d
+b322b
+b321
+b321b
+
+
+t02: numeric
+abc
+ab
+a
+a321
+a123
+a122
+b321
+b123
+c123d
+ 123b
+c321d
+b322b
+b321
+b321b
+
+
+t03: hexadecimal
+abc
+ab
+a
+a321
+a123
+a122
+b321
+b123
+c123d
+ 123b
+c321d
+b322b
+b321
+b321b
+
+
+t04: alpha, unique
+abc
+ab
+a
+a321
+a123
+a122
+b321
+b123
+c123d
+ 123b
+c321d
+b322b
+b321
+b321b
+
+
+t05: alpha, reverse
+abc
+ab
+a
+a321
+a123
+a122
+b321
+b123
+c123d
+ 123b
+c321d
+b322b
+b321
+b321b
+
+
+t06: numeric, reverse
+abc
+ab
+a
+a321
+a123
+a122
+b321
+b123
+c123d
+ 123b
+c321d
+b322b
+b321
+b321b
+
+
+t07: unique, reverse
+abc
+ab
+a
+a321
+a123
+a122
+b321
+b123
+c123d
+ 123b
+c321d
+b322b
+b321
+b321b
+
+
+t08: octal
+abc
+ab
+a
+a321
+a123
+a122
+b321
+b123
+c123d
+ 123b
+c321d
+b322b
+b321
+b321b
+
+
+t09: reverse, hexadecimal
+abc
+ab
+a
+a321
+a123
+a122
+b321
+b123
+c123d
+ 123b
+c321d
+b322b
+b321
+b321b
+
+
+t10: alpha, skip first character
+abc
+ab
+a
+a321
+a123
+a122
+b321
+b123
+c123d
+ 123b
+c321d
+b322b
+b321
+b321b
+
+
+t11: alpha, skip first 2 characters
+abc
+ab
+a
+a321
+a123
+a122
+b321
+b123
+c123d
+ 123b
+c321d
+b322b
+b321
+b321b
+
+
+t12: alpha, unique, skip first 2 characters
+abc
+ab
+a
+a321
+a123
+a122
+b321
+b123
+c123d
+ 123b
+c321d
+b322b
+b321
+b321b
+
+
+t13: numeric, skip first character
+abc
+ab
+a
+a321
+a123
+a122
+b321
+b123
+c123d
+ 123b
+c321d
+b322b
+b321
+b321b
+
+
+t14: alpha, sort on first character
+abc
+ab
+a
+a321
+a123
+a122
+b321
+b123
+c123d
+ 123b
+c321d
+b322b
+b321
+b321b
+
+
+t15: alpha, sort on first 2 characters
+abc
+ab
+a
+a321
+a123
+a122
+b321
+b123
+c123d
+ 123b
+c321d
+b322b
+b321
+b321b
+
+
+t16: numeric, sort on first character
+abc
+ab
+a
+a321
+a123
+a122
+b321
+b123
+c123d
+ 123b
+c321d
+b322b
+b321
+b321b
+
+
+t17: alpha, skip past first digit
+abc
+ab
+a
+a321
+a123
+a122
+b321
+b123
+c123d
+ 123b
+c321d
+b322b
+b321
+b321b
+
+
+t18: alpha, sort on first digit
+abc
+ab
+a
+a321
+a123
+a122
+b321
+b123
+c123d
+ 123b
+c321d
+b322b
+b321
+b321b
+
+
+t19: numeric, skip past first digit
+abc
+ab
+a
+a321
+a123
+a122
+b321
+b123
+c123d
+ 123b
+c321d
+b322b
+b321
+b321b
+
+
+t20: numeric, sort on first digit
+abc
+ab
+a
+a321
+a123
+a122
+b321
+b123
+c123d
+ 123b
+c321d
+b322b
+b321
+b321b
+
+
+t21: alpha, skip past first 2 digits
+abc
+ab
+a
+a321
+a123
+a122
+b321
+b123
+c123d
+ 123b
+c321d
+b322b
+b321
+b321b
+
+
+t22: numeric, skip past first 2 digits
+abc
+ab
+a
+a321
+a123
+a122
+b321
+b123
+c123d
+ 123b
+c321d
+b322b
+b321
+b321b
+
+
+t23: hexadecimal, skip past first 2 digits
+abc
+ab
+a
+a321
+a123
+a122
+b321
+b123
+c123d
+ 123b
+c321d
+b322b
+b321
+b321b
+
+
+t24: alpha, sort on first 2 digits
+abc
+ab
+a
+a321
+a123
+a122
+b321
+b123
+c123d
+ 123b
+c321d
+b322b
+b321
+b321b
+
+
+t25: numeric, sort on first 2 digits
+abc
+ab
+a
+a321
+a123
+a122
+b321
+b123
+c123d
+ 123b
+c321d
+b322b
+b321
+b321b
+
+
+t26: hexadecimal, sort on first 2 digits
+abc
+ab
+a
+a321
+a123
+a122
+b321
+b123
+c123d
+ 123b
+c321d
+b322b
+b321
+b321b
+
+
+t27: wrong arguments
+abc
+ab
+a
+a321
+a123
+a122
+b321
+b123
+c123d
+ 123b
+c321d
+b322b
+b321
+b321b
+
+
+t28: done
+
--- /dev/null
+++ b/testdir/test57.ok
@@ -1,0 +1,455 @@
+t01: alphebetical
+
+
+ 123b
+a
+a122
+a123
+a321
+ab
+abc
+b123
+b321
+b321
+b321b
+b322b
+c123d
+c321d
+t02: numeric
+abc
+ab
+a
+
+
+a122
+a123
+b123
+c123d
+ 123b
+a321
+b321
+c321d
+b321
+b321b
+b322b
+t03: hexadecimal
+
+
+a
+ab
+abc
+ 123b
+a122
+a123
+a321
+b123
+b321
+b321
+b321b
+b322b
+c123d
+c321d
+t04: alpha, unique
+
+ 123b
+a
+a122
+a123
+a321
+ab
+abc
+b123
+b321
+b321b
+b322b
+c123d
+c321d
+t05: alpha, reverse
+c321d
+c123d
+b322b
+b321b
+b321
+b321
+b123
+abc
+ab
+a321
+a123
+a122
+a
+ 123b
+
+
+t06: numeric, reverse
+b322b
+b321b
+b321
+c321d
+b321
+a321
+ 123b
+c123d
+b123
+a123
+a122
+
+
+a
+ab
+abc
+t07: unique, reverse
+c321d
+c123d
+b322b
+b321b
+b321
+b123
+abc
+ab
+a321
+a123
+a122
+a
+ 123b
+
+t08: octal
+abc
+ab
+a
+
+
+a122
+a123
+b123
+c123d
+ 123b
+a321
+b321
+c321d
+b321
+b321b
+b322b
+t09: reverse, hexadecimal
+c321d
+c123d
+b322b
+b321b
+b321
+b321
+b123
+a321
+a123
+a122
+ 123b
+abc
+ab
+a
+
+
+t10: alpha, skip first character
+a
+
+
+a122
+a123
+b123
+ 123b
+c123d
+a321
+b321
+b321
+b321b
+c321d
+b322b
+ab
+abc
+t11: alpha, skip first 2 characters
+ab
+a
+
+
+a321
+b321
+b321
+b321b
+c321d
+a122
+b322b
+a123
+b123
+ 123b
+c123d
+abc
+t12: alpha, unique, skip first 2 characters
+ab
+a
+
+a321
+b321
+b321b
+c321d
+a122
+b322b
+a123
+b123
+ 123b
+c123d
+abc
+t13: numeric, skip first character
+abc
+ab
+a
+
+
+a122
+a123
+b123
+c123d
+ 123b
+a321
+b321
+c321d
+b321
+b321b
+b322b
+t14: alpha, sort on first character
+
+
+ 123b
+abc
+ab
+a
+a321
+a123
+a122
+b321
+b123
+b322b
+b321
+b321b
+c123d
+c321d
+t15: alpha, sort on first 2 characters
+a
+
+
+ 123b
+a123
+a122
+a321
+abc
+ab
+b123
+b321
+b322b
+b321
+b321b
+c123d
+c321d
+t16: numeric, sort on first character
+abc
+ab
+a
+a321
+a123
+a122
+b321
+b123
+c123d
+ 123b
+c321d
+b322b
+b321
+b321b
+
+
+t17: alpha, skip past first digit
+abc
+ab
+a
+
+
+a321
+b321
+b321
+b321b
+c321d
+a122
+b322b
+a123
+b123
+ 123b
+c123d
+t18: alpha, sort on first digit
+abc
+ab
+a
+
+
+a123
+a122
+b123
+c123d
+ 123b
+a321
+b321
+c321d
+b322b
+b321
+b321b
+t19: numeric, skip past first digit
+abc
+ab
+a
+
+
+a321
+b321
+c321d
+b321
+b321b
+a122
+b322b
+a123
+b123
+c123d
+ 123b
+t20: numeric, sort on first digit
+abc
+ab
+a
+
+
+a123
+a122
+b123
+c123d
+ 123b
+a321
+b321
+c321d
+b322b
+b321
+b321b
+t21: alpha, skip past first 2 digits
+abc
+ab
+a
+
+
+a321
+b321
+b321
+b321b
+c321d
+a122
+b322b
+a123
+b123
+ 123b
+c123d
+t22: numeric, skip past first 2 digits
+abc
+ab
+a
+
+
+a321
+b321
+c321d
+b321
+b321b
+a122
+b322b
+a123
+b123
+c123d
+ 123b
+t23: hexadecimal, skip past first 2 digits
+abc
+ab
+a
+
+
+a321
+b321
+b321
+a122
+a123
+b123
+b321b
+c321d
+b322b
+ 123b
+c123d
+t24: alpha, sort on first 2 digits
+abc
+ab
+a
+
+
+a123
+a122
+b123
+c123d
+ 123b
+a321
+b321
+c321d
+b322b
+b321
+b321b
+t25: numeric, sort on first 2 digits
+abc
+ab
+a
+
+
+a123
+a122
+b123
+c123d
+ 123b
+a321
+b321
+c321d
+b322b
+b321
+b321b
+t26: hexadecimal, sort on first 2 digits
+abc
+ab
+a
+
+
+a123
+a122
+b123
+c123d
+ 123b
+a321
+b321
+c321d
+b322b
+b321
+b321b
+t27: wrong arguments
+abc
+ab
+a
+a321
+a123
+a122
+b321
+b123
+c123d
+ 123b
+c321d
+b322b
+b321
+b321b
+
+
+t28: done
+
--- /dev/null
+++ b/testdir/test58.in
@@ -1,0 +1,630 @@
+Tests for spell checking.     vim: set ft=vim :
+
+STARTTEST
+:so small.vim
+:"
+:" Don't want to depend on the locale from the environment
+:set enc=latin1
+:e!
+:"
+:" Function to test .aff/.dic with list of good and bad words.
+:func TestOne(aff, dic)
+  set spellfile=
+  $put =''
+  $put ='test '. a:aff . '-' . a:dic
+  " Generate a .spl file from a .dic and .aff file.
+  exe '1;/^' . a:aff . 'affstart/+1,/^' . a:aff . 'affend/-1w! Xtest.aff'
+  exe '1;/^' . a:dic . 'dicstart/+1,/^' . a:dic . 'dicend/-1w! Xtest.dic'
+  mkspell! Xtest Xtest
+  " use that spell file
+  set spl=Xtest.latin1.spl spell
+  " list all valid words
+  spelldump
+  %yank
+  quit
+  $put
+  $put ='-------'
+  " find all bad words and suggestions for them
+  exe '1;/^' . a:aff . 'good:'
+  normal 0f:]s
+  let prevbad = ''
+  while 1
+    let [bad, a] = spellbadword()
+    if bad == '' || bad == prevbad || bad == 'badend'
+      break
+    endif
+    let prevbad = bad
+    let lst = spellsuggest(bad, 3)
+    normal mm
+    $put =bad
+    $put =string(lst)
+    normal `m]s
+  endwhile
+endfunc
+:"
+:call TestOne('1', '1')
+:$put =soundfold('goobledygoook')
+:$put =soundfold('k�op�r�n�ven')
+:$put =soundfold('oeverloos gezwets edale')
+:"
+:"
+:" and now with SAL instead of SOFO items; test automatic reloading
+gg:/^affstart_sal/+1,/^affend_sal/-1w! Xtest.aff
+:mkspell! Xtest Xtest
+:$put =soundfold('goobledygoook')
+:$put =soundfold('k�op�r�n�ven')
+:$put =soundfold('oeverloos gezwets edale')
+:"
+:" also use an addition file
+gg:/^addstart/+1,/^addend/-1w! Xtest.latin1.add
+:mkspell! Xtest.latin1.add.spl Xtest.latin1.add
+:set spellfile=Xtest.latin1.add
+/^test2:
+]s:let [str, a] = spellbadword()
+:$put =str
+:set spl=Xtest_us.latin1.spl
+/^test2:
+]smm:let [str, a] = spellbadword()
+:$put =str
+`m]s:let [str, a] = spellbadword()
+:$put =str
+:set spl=Xtest_gb.latin1.spl
+/^test2:
+]smm:let [str, a] = spellbadword()
+:$put =str
+`m]s:let [str, a] = spellbadword()
+:$put =str
+:set spl=Xtest_nz.latin1.spl
+/^test2:
+]smm:let [str, a] = spellbadword()
+:$put =str
+`m]s:let [str, a] = spellbadword()
+:$put =str
+:set spl=Xtest_ca.latin1.spl
+/^test2:
+]smm:let [str, a] = spellbadword()
+:$put =str
+`m]s:let [str, a] = spellbadword()
+:$put =str
+:"
+:" Postponed prefixes
+:call TestOne('2', '1')
+:"
+:" Compound words
+:call TestOne('3', '3')
+:call TestOne('4', '4')
+:call TestOne('5', '5')
+:call TestOne('6', '6')
+:call TestOne('7', '7')
+:"
+:" NOSLITSUGS
+:call TestOne('8', '8')
+:"
+gg:/^test output:/,$wq! test.out
+ENDTEST
+
+1affstart
+SET ISO8859-1
+TRY esianrtolcdugmphbyfvkwjkqxz-������������'ESIANRTOLCDUGMPHBYFVKWJKQXZ
+
+FOL  �������������������������������+LOW  �������������������������������+UPP  �������������������������������+
+SOFOFROM abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ�������������������������������������������������������������޿
+SOFOTO   ebctefghejklnnepkrstevvkesebctefghejklnnepkrstevvkeseeeeeeeceeeeeeeedneeeeeeeeeeepseeeeeeeeceeeeeeeedneeeeeeeeeeep?
+
+MIDWORD	'-
+
+KEP =
+RAR ?
+BAD !
+
+PFX I N 1
+PFX I 0 in .
+
+PFX O Y 1
+PFX O 0 out .
+
+SFX S Y 2
+SFX S 0 s [^s]
+SFX S 0 es s
+
+SFX N N 3
+SFX N 0 en [^n]
+SFX N 0 nen n
+SFX N 0 n .
+
+REP 3
+REP g ch
+REP ch g
+REP svp s.v.p.
+
+MAP 9
+MAP a�����+MAP e���+MAP i���+MAP o���+MAP u��+MAP n+MAP c+MAP y+MAP s�
+1affend
+
+1good: wrong OK puts. Test the end
+bad:  inputs comment ok Ok. test d��l end the
+badend
+
+1dicstart
+123456
+test/NO
+# comment
+wrong
+Comment
+OK
+uk
+put/ISO
+the end
+deol
+d�+1dicend
+
+affstart_sal
+SET ISO8859-1
+TRY esianrtolcdugmphbyfvkwjkqxz-������������'ESIANRTOLCDUGMPHBYFVKWJKQXZ
+
+FOL  �������������������������������+LOW  �������������������������������+UPP  �������������������������������+
+MIDWORD	'-
+
+KEP =
+RAR ?
+BAD !
+
+PFX I N 1
+PFX I 0 in .
+
+PFX O Y 1
+PFX O 0 out .
+
+SFX S Y 2
+SFX S 0 s [^s]
+SFX S 0 es s
+
+SFX N N 3
+SFX N 0 en [^n]
+SFX N 0 nen n
+SFX N 0 n .
+
+REP 3
+REP g ch
+REP ch g
+REP svp s.v.p.
+
+MAP 9
+MAP a�����+MAP e���+MAP i���+MAP o���+MAP u��+MAP n+MAP c+MAP y+MAP s�
+
+SAL AH(AEIOUY)-^         *H
+SAL AR(AEIOUY)-^         *R
+SAL A(HR)^               *
+SAL A^                   *
+SAL AH(AEIOUY)-          H
+SAL AR(AEIOUY)-          R
+SAL A(HR)                _
+SAL �^                   *
+SAL �^                   *
+SAL BB-                  _
+SAL B                    B
+SAL CQ-                  _
+SAL CIA                  X
+SAL CH                   X
+SAL C(EIY)-              S
+SAL CK                   K
+SAL COUGH^               KF
+SAL CC<                  C
+SAL C                    K
+SAL DG(EIY)              K
+SAL DD-                  _
+SAL D                    T
+SAL �<                   E
+SAL EH(AEIOUY)-^         *H
+SAL ER(AEIOUY)-^         *R
+SAL E(HR)^               *
+SAL ENOUGH^$             *NF
+SAL E^                   *
+SAL EH(AEIOUY)-          H
+SAL ER(AEIOUY)-          R
+SAL E(HR)                _
+SAL FF-                  _
+SAL F                    F
+SAL GN^                  N
+SAL GN$                  N
+SAL GNS$                 NS
+SAL GNED$                N
+SAL GH(AEIOUY)-          K
+SAL GH                   _
+SAL GG9                  K
+SAL G                    K
+SAL H                    H
+SAL IH(AEIOUY)-^         *H
+SAL IR(AEIOUY)-^         *R
+SAL I(HR)^               *
+SAL I^                   *
+SAL ING6                 N
+SAL IH(AEIOUY)-          H
+SAL IR(AEIOUY)-          R
+SAL I(HR)                _
+SAL J                    K
+SAL KN^                  N
+SAL KK-                  _
+SAL K                    K
+SAL LAUGH^               LF
+SAL LL-                  _
+SAL L                    L
+SAL MB$                  M
+SAL MM                   M
+SAL M                    M
+SAL NN-                  _
+SAL N                    N
+SAL OH(AEIOUY)-^         *H
+SAL OR(AEIOUY)-^         *R
+SAL O(HR)^               *
+SAL O^                   *
+SAL OH(AEIOUY)-          H
+SAL OR(AEIOUY)-          R
+SAL O(HR)                _
+SAL PH                   F
+SAL PN^                  N
+SAL PP-                  _
+SAL P                    P
+SAL Q                    K
+SAL RH^                  R
+SAL ROUGH^               RF
+SAL RR-                  _
+SAL R                    R
+SAL SCH(EOU)-            SK
+SAL SC(IEY)-             S
+SAL SH                   X
+SAL SI(AO)-              X
+SAL SS-                  _
+SAL S                    S
+SAL TI(AO)-              X
+SAL TH                   @
+SAL TCH--                _
+SAL TOUGH^               TF
+SAL TT-                  _
+SAL T                    T
+SAL UH(AEIOUY)-^         *H
+SAL UR(AEIOUY)-^         *R
+SAL U(HR)^               *
+SAL U^                   *
+SAL UH(AEIOUY)-          H
+SAL UR(AEIOUY)-          R
+SAL U(HR)                _
+SAL V^                   W
+SAL V                    F
+SAL WR^                  R
+SAL WH^                  W
+SAL W(AEIOU)-            W
+SAL X^                   S
+SAL X                    KS
+SAL Y(AEIOU)-            Y
+SAL ZZ-                  _
+SAL Z                    S
+affend_sal
+
+2affstart
+SET ISO8859-1
+
+FOL  �������������������������������+LOW  �������������������������������+UPP  �������������������������������+
+PFXPOSTPONE
+
+MIDWORD	'-
+
+KEP =
+RAR ?
+BAD !
+
+PFX I N 1
+PFX I 0 in .
+
+PFX O Y 1
+PFX O 0 out [a-z]
+
+SFX S Y 2
+SFX S 0 s [^s]
+SFX S 0 es s
+
+SFX N N 3
+SFX N 0 en [^n]
+SFX N 0 nen n
+SFX N 0 n .
+
+REP 3
+REP g ch
+REP ch g
+REP svp s.v.p.
+
+MAP 9
+MAP a�����+MAP e���+MAP i���+MAP o���+MAP u��+MAP n+MAP c+MAP y+MAP s�
+2affend
+
+2good: puts
+bad: inputs comment ok Ok end the. test d�+badend
+
+addstart
+/regions=usgbnz
+elequint/2
+elekwint/3
+addend
+
+test2:
+elequint test elekwint test elekwent asdf
+
+Test rules for compounding.
+
+3affstart
+SET ISO8859-1
+
+COMPOUNDMIN 3
+COMPOUNDRULE m*
+NEEDCOMPOUND x
+3affend
+
+3dicstart
+1234
+foo/m
+bar/mx
+m�/m
+la/mx
+3dicend
+
+3good: foo m� foobar foofoobar barfoo barbarfoo
+bad: bar la foom� barm� m�foo m�bar m�m� lala m�la lam� foola labar
+badend
+
+
+Tests for compounding.
+
+4affstart
+SET ISO8859-1
+
+FOL  �������������������������������+LOW  �������������������������������+UPP  �������������������������������+
+COMPOUNDRULE m+
+COMPOUNDRULE sm*e
+COMPOUNDRULE sm+
+COMPOUNDMIN 3
+COMPOUNDWORDMAX 3
+COMPOUNDFORBIDFLAG t
+
+COMPOUNDSYLMAX 5
+SYLLABLE a�e�i�o���u���y/aa/au/ea/ee/ei/ie/oa/oe/oo/ou/uu/ui
+
+MAP 9
+MAP a�����+MAP e���+MAP i���+MAP o���+MAP u��+MAP n+MAP c+MAP y+MAP s�
+
+NEEDAFFIX x
+
+PFXPOSTPONE
+
+MIDWORD '-
+
+SFX q N 1
+SFX q   0    -ok .
+
+SFX a Y 2
+SFX a 0 s .
+SFX a 0 ize/t .
+
+PFX p N 1
+PFX p 0 pre .
+
+PFX P N 1
+PFX P 0 nou .
+4affend
+
+4dicstart
+1234
+word/mP
+util/am
+pro/xq
+tomato/m
+bork/mp
+start/s
+end/e
+4dicend
+
+4good: word util bork prebork start end wordutil wordutils pro-ok
+	bork borkbork borkborkbork borkborkborkbork borkborkborkborkbork
+	tomato tomatotomato startend startword startwordword startwordend
+	startwordwordend startwordwordwordend prebork preborkbork
+	preborkborkbork
+	nouword
+bad: wordutilize pro borkborkborkborkborkbork tomatotomatotomato
+	endstart endend startstart wordend wordstart
+	preborkprebork  preborkpreborkbork
+ 	startwordwordwordwordend borkpreborkpreborkbork
+	utilsbork  startnouword
+badend
+
+Test affix flags with two characters
+
+5affstart
+SET ISO8859-1
+
+FLAG long
+
+NEEDAFFIX !!
+
+COMPOUNDRULE ssmm*ee
+
+NEEDCOMPOUND xx
+COMPOUNDPERMITFLAG pp
+
+SFX 13 Y 1
+SFX 13 0 bork .
+
+SFX a1 Y 1
+SFX a1 0 a1 .
+
+SFX a� Y 1
+SFX a� 0 a� .
+
+PFX zz Y 1
+PFX zz 0 pre/pp .
+
+PFX yy Y 1
+PFX yy 0 nou .
+5affend
+
+5dicstart
+1234
+foo/a1a�!!
+bar/zz13ee
+start/ss
+end/eeyy
+middle/mmxx
+5dicend
+
+5good: fooa1 fooa� bar prebar barbork prebarbork  startprebar
+      start end startend  startmiddleend nouend
+bad: foo fooa2 prabar probarbirk middle startmiddle middleend endstart
+	startprobar startnouend
+badend
+
+6affstart
+SET ISO8859-1
+
+FLAG caplong
+
+NEEDAFFIX A!
+
+COMPOUNDRULE sMm*Ee
+
+NEEDCOMPOUND Xx
+
+COMPOUNDPERMITFLAG p
+
+SFX N3 Y 1
+SFX N3 0 bork .
+
+SFX A1 Y 1
+SFX A1 0 a1 .
+
+SFX A� Y 1
+SFX A� 0 a� .
+
+PFX Zz Y 1
+PFX Zz 0 pre/p .
+6affend
+
+6dicstart
+1234
+mee/A1A�A!
+bar/ZzN3Ee
+lead/s
+end/Ee
+middle/MmXx
+6dicend
+
+6good: meea1 meea� bar prebar barbork prebarbork  leadprebar
+      lead end leadend  leadmiddleend
+bad: mee meea2 prabar probarbirk middle leadmiddle middleend endlead
+	leadprobar
+badend
+
+7affstart
+SET ISO8859-1
+
+FLAG num
+
+NEEDAFFIX 9999
+
+COMPOUNDRULE 2,77*123
+
+NEEDCOMPOUND 1
+COMPOUNDPERMITFLAG 432
+
+SFX 61003 Y 1
+SFX 61003 0 meat .
+
+SFX 391 Y 1
+SFX 391 0 a1 .
+
+SFX 111 Y 1
+SFX 111 0 a� .
+
+PFX 17 Y 1
+PFX 17 0 pre/432 .
+7affend
+
+7dicstart
+1234
+mee/391,111,9999
+bar/17,61003,123
+lead/2
+tail/123
+middle/77,1
+7dicend
+
+7good: meea1 meea� bar prebar barmeat prebarmeat  leadprebar
+      lead tail leadtail  leadmiddletail
+bad: mee meea2 prabar probarmaat middle leadmiddle middletail taillead
+	leadprobar
+badend
+
+Test NOSLITSUGS
+
+8affstart
+SET ISO8859-1
+
+NOSPLITSUGS
+8affend
+
+8dicstart
+1234
+foo
+bar
+faabar
+8dicend
+
+8good: foo bar faabar
+bad: foobar barfoo
+badend
+
+
+test output:
--- /dev/null
+++ b/testdir/test58.ok
@@ -1,0 +1,283 @@
+test output:
+
+test 1-1
+# file: Xtest.latin1.spl
+Comment
+deol
+d�+input
+OK
+output
+outputs
+outtest
+put
+puts
+test
+testen
+testn
+the end
+uk
+wrong
+-------
+bad
+['put', 'uk', 'OK']
+inputs
+['input', 'puts', 'outputs']
+comment
+['Comment', 'outtest', 'the end']
+ok
+['OK', 'uk', 'put']
+Ok
+['OK', 'Uk', 'Put']
+test
+['Test', 'testn', 'testen']
+d�+['deol', 'd��r', 'test']
+end
+['put', 'uk', 'test']
+the
+['put', 'uk', 'test']
+gebletegek
+kepereneven
+everles gesvets etele
+kbltykk
+kprnfn
+*fls kswts tl
+elekwent
+elequint
+elekwint
+elekwint
+elekwent
+elequint
+elekwent
+elequint
+elekwint
+
+test 2-1
+# file: Xtest.latin1.spl
+Comment
+deol
+d�+OK
+put
+input
+output
+puts
+outputs
+test
+outtest
+testen
+testn
+the end
+uk
+wrong
+-------
+bad
+['put', 'uk', 'OK']
+inputs
+['input', 'puts', 'outputs']
+comment
+['Comment']
+ok
+['OK', 'uk', 'put']
+Ok
+['OK', 'Uk', 'Put']
+end
+['put', 'uk', 'deol']
+the
+['put', 'uk', 'test']
+test
+['Test', 'testn', 'testen']
+d�+['deol', 'd��r', 'test']
+
+test 3-3
+# file: Xtest.latin1.spl
+foo
+m+-------
+bad
+['foo', 'm�']
+bar
+['barfoo', 'foobar', 'foo']
+la
+['m�', 'foo']
+foom+['foo m�', 'foo', 'foofoo']
+barm+['barfoo', 'm�', 'barbar']
+m�foo
+['m� foo', 'foo', 'foofoo']
+m�bar
+['foobar', 'barbar', 'm�']
+m�m+['m� m�', 'm�']
+lala
+[]
+m�la
+['m�', 'm� m�']
+lam+['m�', 'm� m�']
+foola
+['foo', 'foobar', 'foofoo']
+labar
+['barbar', 'foobar']
+
+test 4-4
+# file: Xtest.latin1.spl
+bork
+prebork
+end
+pro-ok
+start
+tomato
+util
+utilize
+utils
+word
+nouword
+-------
+bad
+['end', 'bork', 'word']
+wordutilize
+['word utilize', 'wordutils', 'wordutil']
+pro
+['bork', 'word', 'end']
+borkborkborkborkborkbork
+['bork borkborkborkborkbork', 'borkbork borkborkborkbork', 'borkborkbork borkborkbork']
+tomatotomatotomato
+['tomato tomatotomato', 'tomatotomato tomato', 'tomato tomato tomato']
+endstart
+['end start', 'start']
+endend
+['end end', 'end']
+startstart
+['start start']
+wordend
+['word end', 'word', 'wordword']
+wordstart
+['word start', 'bork start']
+preborkprebork
+['prebork prebork', 'preborkbork', 'preborkborkbork']
+preborkpreborkbork
+['prebork preborkbork', 'preborkborkbork', 'preborkborkborkbork']
+startwordwordwordwordend
+['startwordwordwordword end', 'startwordwordwordword', 'start wordwordwordword end']
+borkpreborkpreborkbork
+['bork preborkpreborkbork', 'bork prebork preborkbork', 'bork preborkprebork bork']
+utilsbork
+['utilbork', 'utils bork', 'util bork']
+startnouword
+['start nouword', 'startword', 'startborkword']
+
+test 5-5
+# file: Xtest.latin1.spl
+bar
+barbork
+end
+fooa1
+fooa+nouend
+prebar
+prebarbork
+start
+-------
+bad
+['bar', 'end', 'fooa1']
+foo
+['fooa1', 'fooa�', 'bar']
+fooa2
+['fooa1', 'fooa�', 'bar']
+prabar
+['prebar', 'bar', 'bar bar']
+probarbirk
+['prebarbork']
+middle
+[]
+startmiddle
+['startmiddleend', 'startmiddlebar']
+middleend
+[]
+endstart
+['end start', 'start']
+startprobar
+['startprebar', 'start prebar', 'startbar']
+startnouend
+['start nouend', 'startend']
+
+test 6-6
+# file: Xtest.latin1.spl
+bar
+barbork
+end
+lead
+meea1
+meea+prebar
+prebarbork
+-------
+bad
+['bar', 'end', 'lead']
+mee
+['meea1', 'meea�', 'bar']
+meea2
+['meea1', 'meea�', 'lead']
+prabar
+['prebar', 'bar', 'leadbar']
+probarbirk
+['prebarbork']
+middle
+[]
+leadmiddle
+['leadmiddleend', 'leadmiddlebar']
+middleend
+[]
+endlead
+['end lead', 'lead', 'end end']
+leadprobar
+['leadprebar', 'lead prebar', 'leadbar']
+
+test 7-7
+# file: Xtest.latin1.spl
+bar
+barmeat
+lead
+meea1
+meea+prebar
+prebarmeat
+tail
+-------
+bad
+['bar', 'lead', 'tail']
+mee
+['meea1', 'meea�', 'bar']
+meea2
+['meea1', 'meea�', 'lead']
+prabar
+['prebar', 'bar', 'leadbar']
+probarmaat
+['prebarmeat']
+middle
+[]
+leadmiddle
+['leadmiddlebar']
+middletail
+[]
+taillead
+['tail lead', 'tail']
+leadprobar
+['leadprebar', 'lead prebar', 'leadbar']
+
+test 8-8
+# file: Xtest.latin1.spl
+bar
+faabar
+foo
+-------
+bad
+['bar', 'foo']
+foobar
+['faabar', 'foo bar', 'bar']
+barfoo
+['bar foo', 'bar', 'foo']
--- /dev/null
+++ b/testdir/test59.in
@@ -1,0 +1,621 @@
+Tests for spell checking with 'encoding' set to "utf-8".  vim: set ft=vim :
+
+STARTTEST
+:so small.vim
+:so mbyte.vim
+:"
+:" Don't want to depend on the locale from the environment.  The .aff and .dic
+:" text is in latin1, the test text is utf-8.
+:set enc=latin1
+:e!
+:set enc=utf-8
+:set fenc=
+:"
+:" Function to test .aff/.dic with list of good and bad words.
+:func TestOne(aff, dic)
+  set spellfile=
+  $put =''
+  $put ='test '. a:aff . '-' . a:dic
+  " Generate a .spl file from a .dic and .aff file.
+  exe '1;/^' . a:aff . 'affstart/+1,/^' . a:aff . 'affend/-1w! Xtest.aff'
+  exe '1;/^' . a:dic . 'dicstart/+1,/^' . a:dic . 'dicend/-1w! Xtest.dic'
+  mkspell! Xtest Xtest
+  " use that spell file
+  set spl=Xtest.utf-8.spl spell
+  " list all valid words
+  spelldump
+  %yank
+  quit
+  $put
+  $put ='-------'
+  " find all bad words and suggestions for them
+  exe '1;/^' . a:aff . 'good:'
+  normal 0f:]s
+  let prevbad = ''
+  while 1
+    let [bad, a] = spellbadword()
+    if bad == '' || bad == prevbad || bad == 'badend'
+      break
+    endif
+    let prevbad = bad
+    let lst = spellsuggest(bad, 3)
+    normal mm
+    $put =bad
+    $put =string(lst)
+    normal `m]s
+  endwhile
+endfunc
+:"
+:call TestOne('1', '1')
+:$put =soundfold('goobledygoook')
+:$put =soundfold('kóopërÿnôven')
+:$put =soundfold('oeverloos gezwets edale')
+:"
+:"
+:" and now with SAL instead of SOFO items; test automatic reloading
+gg:/^affstart_sal/+1,/^affend_sal/-1w! Xtest.aff
+:mkspell! Xtest Xtest
+:$put =soundfold('goobledygoook')
+:$put =soundfold('kóopërÿnôven')
+:$put =soundfold('oeverloos gezwets edale')
+:"
+:" also use an addition file
+gg:/^addstart/+1,/^addend/-1w! Xtest.utf-8.add
+:mkspell! Xtest.utf-8.add.spl Xtest.utf-8.add
+:set spellfile=Xtest.utf-8.add
+/^test2:
+]s:let [str, a] = spellbadword()
+:$put =str
+:set spl=Xtest_us.utf-8.spl
+/^test2:
+]smm:let [str, a] = spellbadword()
+:$put =str
+`m]s:let [str, a] = spellbadword()
+:$put =str
+:set spl=Xtest_gb.utf-8.spl
+/^test2:
+]smm:let [str, a] = spellbadword()
+:$put =str
+`m]s:let [str, a] = spellbadword()
+:$put =str
+:set spl=Xtest_nz.utf-8.spl
+/^test2:
+]smm:let [str, a] = spellbadword()
+:$put =str
+`m]s:let [str, a] = spellbadword()
+:$put =str
+:set spl=Xtest_ca.utf-8.spl
+/^test2:
+]smm:let [str, a] = spellbadword()
+:$put =str
+`m]s:let [str, a] = spellbadword()
+:$put =str
+:"
+:" Postponed prefixes
+:call TestOne('2', '1')
+:"
+:" Compound words
+:call TestOne('3', '3')
+:call TestOne('4', '4')
+:call TestOne('5', '5')
+:call TestOne('6', '6')
+:call TestOne('7', '7')
+:"
+gg:/^test output:/,$wq! test.out
+ENDTEST
+
+1affstart
+SET ISO8859-1
+TRY esianrtolcdugmphbyfvkwjkqxz-������������'ESIANRTOLCDUGMPHBYFVKWJKQXZ
+
+FOL  �������������������������������+LOW  �������������������������������+UPP  �������������������������������+
+SOFOFROM abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ�������������������������������������������������������������޿
+SOFOTO   ebctefghejklnnepkrstevvkesebctefghejklnnepkrstevvkeseeeeeeeceeeeeeeedneeeeeeeeeeepseeeeeeeeceeeeeeeedneeeeeeeeeeep?
+
+MIDWORD	'-
+
+KEP =
+RAR ?
+BAD !
+
+#NOSPLITSUGS
+
+PFX I N 1
+PFX I 0 in .
+
+PFX O Y 1
+PFX O 0 out .
+
+SFX S Y 2
+SFX S 0 s [^s]
+SFX S 0 es s
+
+SFX N N 3
+SFX N 0 en [^n]
+SFX N 0 nen n
+SFX N 0 n .
+
+REP 3
+REP g ch
+REP ch g
+REP svp s.v.p.
+
+MAP 9
+MAP a�����+MAP e���+MAP i���+MAP o���+MAP u��+MAP n+MAP c+MAP y+MAP s�
+1affend
+
+affstart_sal
+SET ISO8859-1
+TRY esianrtolcdugmphbyfvkwjkqxz-������������'ESIANRTOLCDUGMPHBYFVKWJKQXZ
+
+FOL  �������������������������������+LOW  �������������������������������+UPP  �������������������������������+
+MIDWORD	'-
+
+KEP =
+RAR ?
+BAD !
+
+#NOSPLITSUGS
+
+PFX I N 1
+PFX I 0 in .
+
+PFX O Y 1
+PFX O 0 out .
+
+SFX S Y 2
+SFX S 0 s [^s]
+SFX S 0 es s
+
+SFX N N 3
+SFX N 0 en [^n]
+SFX N 0 nen n
+SFX N 0 n .
+
+REP 3
+REP g ch
+REP ch g
+REP svp s.v.p.
+
+MAP 9
+MAP a�����+MAP e���+MAP i���+MAP o���+MAP u��+MAP n+MAP c+MAP y+MAP s�
+
+SAL AH(AEIOUY)-^         *H
+SAL AR(AEIOUY)-^         *R
+SAL A(HR)^               *
+SAL A^                   *
+SAL AH(AEIOUY)-          H
+SAL AR(AEIOUY)-          R
+SAL A(HR)                _
+SAL �^                   *
+SAL �^                   *
+SAL BB-                  _
+SAL B                    B
+SAL CQ-                  _
+SAL CIA                  X
+SAL CH                   X
+SAL C(EIY)-              S
+SAL CK                   K
+SAL COUGH^               KF
+SAL CC<                  C
+SAL C                    K
+SAL DG(EIY)              K
+SAL DD-                  _
+SAL D                    T
+SAL �<                   E
+SAL EH(AEIOUY)-^         *H
+SAL ER(AEIOUY)-^         *R
+SAL E(HR)^               *
+SAL ENOUGH^$             *NF
+SAL E^                   *
+SAL EH(AEIOUY)-          H
+SAL ER(AEIOUY)-          R
+SAL E(HR)                _
+SAL FF-                  _
+SAL F                    F
+SAL GN^                  N
+SAL GN$                  N
+SAL GNS$                 NS
+SAL GNED$                N
+SAL GH(AEIOUY)-          K
+SAL GH                   _
+SAL GG9                  K
+SAL G                    K
+SAL H                    H
+SAL IH(AEIOUY)-^         *H
+SAL IR(AEIOUY)-^         *R
+SAL I(HR)^               *
+SAL I^                   *
+SAL ING6                 N
+SAL IH(AEIOUY)-          H
+SAL IR(AEIOUY)-          R
+SAL I(HR)                _
+SAL J                    K
+SAL KN^                  N
+SAL KK-                  _
+SAL K                    K
+SAL LAUGH^               LF
+SAL LL-                  _
+SAL L                    L
+SAL MB$                  M
+SAL MM                   M
+SAL M                    M
+SAL NN-                  _
+SAL N                    N
+SAL OH(AEIOUY)-^         *H
+SAL OR(AEIOUY)-^         *R
+SAL O(HR)^               *
+SAL O^                   *
+SAL OH(AEIOUY)-          H
+SAL OR(AEIOUY)-          R
+SAL O(HR)                _
+SAL PH                   F
+SAL PN^                  N
+SAL PP-                  _
+SAL P                    P
+SAL Q                    K
+SAL RH^                  R
+SAL ROUGH^               RF
+SAL RR-                  _
+SAL R                    R
+SAL SCH(EOU)-            SK
+SAL SC(IEY)-             S
+SAL SH                   X
+SAL SI(AO)-              X
+SAL SS-                  _
+SAL S                    S
+SAL TI(AO)-              X
+SAL TH                   @
+SAL TCH--                _
+SAL TOUGH^               TF
+SAL TT-                  _
+SAL T                    T
+SAL UH(AEIOUY)-^         *H
+SAL UR(AEIOUY)-^         *R
+SAL U(HR)^               *
+SAL U^                   *
+SAL UH(AEIOUY)-          H
+SAL UR(AEIOUY)-          R
+SAL U(HR)                _
+SAL V^                   W
+SAL V                    F
+SAL WR^                  R
+SAL WH^                  W
+SAL W(AEIOU)-            W
+SAL X^                   S
+SAL X                    KS
+SAL Y(AEIOU)-            Y
+SAL ZZ-                  _
+SAL Z                    S
+affend_sal
+
+2affstart
+SET ISO8859-1
+
+FOL  �������������������������������+LOW  �������������������������������+UPP  �������������������������������+
+PFXPOSTPONE
+
+MIDWORD	'-
+
+KEP =
+RAR ?
+BAD !
+
+#NOSPLITSUGS
+
+PFX I N 1
+PFX I 0 in .
+
+PFX O Y 1
+PFX O 0 out [a-z]
+
+SFX S Y 2
+SFX S 0 s [^s]
+SFX S 0 es s
+
+SFX N N 3
+SFX N 0 en [^n]
+SFX N 0 nen n
+SFX N 0 n .
+
+REP 3
+REP g ch
+REP ch g
+REP svp s.v.p.
+
+MAP 9
+MAP a�����+MAP e���+MAP i���+MAP o���+MAP u��+MAP n+MAP c+MAP y+MAP s�
+2affend
+
+1dicstart
+123456
+test/NO
+# comment
+wrong
+Comment
+OK
+uk
+put/ISO
+the end
+deol
+d�+1dicend
+
+addstart
+/regions=usgbnz
+elequint/2
+elekwint/3
+addend
+
+1good: wrong OK puts. Test the end
+bad:  inputs comment ok Ok. test déôl end the
+badend
+
+2good: puts
+bad: inputs comment ok Ok end the. test déôl
+badend
+
+Test rules for compounding.
+
+3affstart
+SET ISO8859-1
+
+COMPOUNDMIN 3
+COMPOUNDRULE m*
+NEEDCOMPOUND x
+3affend
+
+3dicstart
+1234
+foo/m
+bar/mx
+m�/m
+la/mx
+3dicend
+
+3good: foo mï foobar foofoobar barfoo barbarfoo
+bad: bar la foomï barmï mïfoo mïbar mïmï lala mïla lamï foola labar
+badend
+
+
+Tests for compounding.
+
+4affstart
+SET ISO8859-1
+
+FOL  �������������������������������+LOW  �������������������������������+UPP  �������������������������������+
+COMPOUNDRULE m+
+COMPOUNDRULE sm*e
+COMPOUNDRULE sm+
+COMPOUNDMIN 3
+COMPOUNDWORDMAX 3
+COMPOUNDFORBIDFLAG t
+
+COMPOUNDSYLMAX 5
+SYLLABLE a�e�i�o���u���y/aa/au/ea/ee/ei/ie/oa/oe/oo/ou/uu/ui
+
+MAP 9
+MAP a�����+MAP e���+MAP i���+MAP o���+MAP u��+MAP n+MAP c+MAP y+MAP s�
+
+NEEDAFFIX x
+
+PFXPOSTPONE
+
+MIDWORD '-
+
+SFX q N 1
+SFX q   0    -ok .
+
+SFX a Y 2
+SFX a 0 s .
+SFX a 0 ize/t .
+
+PFX p N 1
+PFX p 0 pre .
+
+PFX P N 1
+PFX P 0 nou .
+4affend
+
+4dicstart
+1234
+word/mP
+util/am
+pro/xq
+tomato/m
+bork/mp
+start/s
+end/e
+4dicend
+
+4good: word util bork prebork start end wordutil wordutils pro-ok
+	bork borkbork borkborkbork borkborkborkbork borkborkborkborkbork
+	tomato tomatotomato startend startword startwordword startwordend
+	startwordwordend startwordwordwordend prebork preborkbork
+	preborkborkbork
+	nouword
+bad: wordutilize pro borkborkborkborkborkbork tomatotomatotomato
+	endstart endend startstart wordend wordstart
+	preborkprebork  preborkpreborkbork
+ 	startwordwordwordwordend borkpreborkpreborkbork
+	utilsbork  startnouword
+badend
+
+test2:
+elequint test elekwint test elekwent asdf
+
+Test affix flags with two characters
+
+5affstart
+SET ISO8859-1
+
+FLAG long
+
+NEEDAFFIX !!
+
+COMPOUNDRULE ssmm*ee
+
+NEEDCOMPOUND xx
+COMPOUNDPERMITFLAG pp
+
+SFX 13 Y 1
+SFX 13 0 bork .
+
+SFX a1 Y 1
+SFX a1 0 a1 .
+
+SFX a� Y 1
+SFX a� 0 a� .
+
+PFX zz Y 1
+PFX zz 0 pre/pp .
+
+PFX yy Y 1
+PFX yy 0 nou .
+5affend
+
+5dicstart
+1234
+foo/a1a�!!
+bar/zz13ee
+start/ss
+end/eeyy
+middle/mmxx
+5dicend
+
+5good: fooa1 fooaé bar prebar barbork prebarbork  startprebar
+      start end startend  startmiddleend nouend
+bad: foo fooa2 prabar probarbirk middle startmiddle middleend endstart
+	startprobar startnouend
+badend
+
+6affstart
+SET ISO8859-1
+
+FLAG caplong
+
+NEEDAFFIX A!
+
+COMPOUNDRULE sMm*Ee
+
+NEEDCOMPOUND Xx
+
+COMPOUNDPERMITFLAG p
+
+SFX N3 Y 1
+SFX N3 0 bork .
+
+SFX A1 Y 1
+SFX A1 0 a1 .
+
+SFX A� Y 1
+SFX A� 0 a� .
+
+PFX Zz Y 1
+PFX Zz 0 pre/p .
+6affend
+
+6dicstart
+1234
+mee/A1A�A!
+bar/ZzN3Ee
+lead/s
+end/Ee
+middle/MmXx
+6dicend
+
+6good: meea1 meeaé bar prebar barbork prebarbork  leadprebar
+      lead end leadend  leadmiddleend
+bad: mee meea2 prabar probarbirk middle leadmiddle middleend endlead
+	leadprobar
+badend
+
+7affstart
+SET ISO8859-1
+
+FOL  �������������������������������+LOW  �������������������������������+UPP  �������������������������������+
+FLAG num
+
+NEEDAFFIX 9999
+
+COMPOUNDRULE 2,77*123
+
+NEEDCOMPOUND 1
+COMPOUNDPERMITFLAG 432
+
+SFX 61003 Y 1
+SFX 61003 0 meat .
+
+SFX 391 Y 1
+SFX 391 0 a1 .
+
+SFX 111 Y 1
+SFX 111 0 a� .
+
+PFX 17 Y 1
+PFX 17 0 pre/432 .
+7affend
+
+7dicstart
+1234
+mee/391,111,9999
+bar/17,61003,123
+lead/2
+tail/123
+middle/77,1
+7dicend
+
+7good: meea1 meeaé bar prebar barmeat prebarmeat  leadprebar
+      lead tail leadtail  leadmiddletail
+bad: mee meea2 prabar probarmaat middle leadmiddle middletail taillead
+	leadprobar
+badend
+
+test output:
--- /dev/null
+++ b/testdir/test59.ok
@@ -1,0 +1,270 @@
+test output:
+
+test 1-1
+# file: Xtest.utf-8.spl
+Comment
+deol
+déôr
+input
+OK
+output
+outputs
+outtest
+put
+puts
+test
+testen
+testn
+the end
+uk
+wrong
+-------
+bad
+['put', 'uk', 'OK']
+inputs
+['input', 'puts', 'outputs']
+comment
+['Comment', 'outtest', 'the end']
+ok
+['OK', 'uk', 'put']
+Ok
+['OK', 'Uk', 'Put']
+test
+['Test', 'testn', 'testen']
+déôl
+['deol', 'déôr', 'test']
+end
+['put', 'uk', 'test']
+the
+['put', 'uk', 'test']
+gebletegek
+kepereneven
+everles gesvets etele
+kbltykk
+kprnfn
+*fls kswts tl
+elekwent
+elequint
+elekwint
+elekwint
+elekwent
+elequint
+elekwent
+elequint
+elekwint
+
+test 2-1
+# file: Xtest.utf-8.spl
+Comment
+deol
+déôr
+OK
+put
+input
+output
+puts
+outputs
+test
+outtest
+testen
+testn
+the end
+uk
+wrong
+-------
+bad
+['put', 'uk', 'OK']
+inputs
+['input', 'puts', 'outputs']
+comment
+['Comment']
+ok
+['OK', 'uk', 'put']
+Ok
+['OK', 'Uk', 'Put']
+end
+['put', 'uk', 'deol']
+the
+['put', 'uk', 'test']
+test
+['Test', 'testn', 'testen']
+déôl
+['deol', 'déôr', 'test']
+
+test 3-3
+# file: Xtest.utf-8.spl
+foo
+mï
+-------
+bad
+['foo', 'mï']
+bar
+['barfoo', 'foobar', 'foo']
+la
+['mï', 'foo']
+foomï
+['foo mï', 'foo', 'foofoo']
+barmï
+['barfoo', 'mï', 'barbar']
+mïfoo
+['mï foo', 'foo', 'foofoo']
+mïbar
+['foobar', 'barbar', 'mï']
+mïmï
+['mï mï', 'mï']
+lala
+[]
+mïla
+['mï', 'mï mï']
+lamï
+['mï', 'mï mï']
+foola
+['foo', 'foobar', 'foofoo']
+labar
+['barbar', 'foobar']
+
+test 4-4
+# file: Xtest.utf-8.spl
+bork
+prebork
+end
+pro-ok
+start
+tomato
+util
+utilize
+utils
+word
+nouword
+-------
+bad
+['end', 'bork', 'word']
+wordutilize
+['word utilize', 'wordutils', 'wordutil']
+pro
+['bork', 'word', 'end']
+borkborkborkborkborkbork
+['bork borkborkborkborkbork', 'borkbork borkborkborkbork', 'borkborkbork borkborkbork']
+tomatotomatotomato
+['tomato tomatotomato', 'tomatotomato tomato', 'tomato tomato tomato']
+endstart
+['end start', 'start']
+endend
+['end end', 'end']
+startstart
+['start start']
+wordend
+['word end', 'word', 'wordword']
+wordstart
+['word start', 'bork start']
+preborkprebork
+['prebork prebork', 'preborkbork', 'preborkborkbork']
+preborkpreborkbork
+['prebork preborkbork', 'preborkborkbork', 'preborkborkborkbork']
+startwordwordwordwordend
+['startwordwordwordword end', 'startwordwordwordword', 'start wordwordwordword end']
+borkpreborkpreborkbork
+['bork preborkpreborkbork', 'bork prebork preborkbork', 'bork preborkprebork bork']
+utilsbork
+['utilbork', 'utils bork', 'util bork']
+startnouword
+['start nouword', 'startword', 'startborkword']
+
+test 5-5
+# file: Xtest.utf-8.spl
+bar
+barbork
+end
+fooa1
+fooaé
+nouend
+prebar
+prebarbork
+start
+-------
+bad
+['bar', 'end', 'fooa1']
+foo
+['fooa1', 'fooaé', 'bar']
+fooa2
+['fooa1', 'fooaé', 'bar']
+prabar
+['prebar', 'bar', 'bar bar']
+probarbirk
+['prebarbork']
+middle
+[]
+startmiddle
+['startmiddleend', 'startmiddlebar']
+middleend
+[]
+endstart
+['end start', 'start']
+startprobar
+['startprebar', 'start prebar', 'startbar']
+startnouend
+['start nouend', 'startend']
+
+test 6-6
+# file: Xtest.utf-8.spl
+bar
+barbork
+end
+lead
+meea1
+meeaé
+prebar
+prebarbork
+-------
+bad
+['bar', 'end', 'lead']
+mee
+['meea1', 'meeaé', 'bar']
+meea2
+['meea1', 'meeaé', 'lead']
+prabar
+['prebar', 'bar', 'leadbar']
+probarbirk
+['prebarbork']
+middle
+[]
+leadmiddle
+['leadmiddleend', 'leadmiddlebar']
+middleend
+[]
+endlead
+['end lead', 'lead', 'end end']
+leadprobar
+['leadprebar', 'lead prebar', 'leadbar']
+
+test 7-7
+# file: Xtest.utf-8.spl
+bar
+barmeat
+lead
+meea1
+meeaé
+prebar
+prebarmeat
+tail
+-------
+bad
+['bar', 'lead', 'tail']
+mee
+['meea1', 'meeaé', 'bar']
+meea2
+['meea1', 'meeaé', 'lead']
+prabar
+['prebar', 'bar', 'leadbar']
+probarmaat
+['prebarmeat']
+middle
+[]
+leadmiddle
+['leadmiddlebar']
+middletail
+[]
+taillead
+['tail lead', 'tail']
+leadprobar
+['leadprebar', 'lead prebar', 'leadbar']
--- /dev/null
+++ b/testdir/test6.in
@@ -1,0 +1,24 @@
+Test for autocommand that redefines the argument list, when doing ":all".
+
+STARTTEST
+:so small.vim
+:au BufReadPost Xxx2 next Xxx2 Xxx1
+/^start of
+A1:.,/end of/w! Xxx1    " write test file Xxx1
+$r2:.,/end of/w! Xxx2     " write test file Xxx2
+$r3:.,/end of/w! Xxx3     " write test file Xxx3
+:next! Xxx1 Xxx2 Xxx3     " redefine arglist; go to Xxx1
+:all                      " open window for all args
+:w! test.out              " Write contents of Xxx1
+:w >>test.out     " Append contents of last window (Xxx1)
+:rew                      " should now be in Xxx2
+:w >>test.out             " Append contents of Xxx2
+:qa!
+ENDTEST
+
+start of test file Xxx
+	this is a test
+	this is a test
+	this is a test
+	this is a test
+end of test file Xxx
--- /dev/null
+++ b/testdir/test6.ok
@@ -1,0 +1,18 @@
+start of test file Xxx1
+	this is a test
+	this is a test
+	this is a test
+	this is a test
+end of test file Xxx
+start of test file Xxx1
+	this is a test
+	this is a test
+	this is a test
+	this is a test
+end of test file Xxx
+start of test file Xxx2
+	this is a test
+	this is a test
+	this is a test
+	this is a test
+end of test file Xxx
--- /dev/null
+++ b/testdir/test60.in
@@ -1,0 +1,577 @@
+Tests for the exists() function.  vim: set ft=vim :
+
+STARTTEST
+:so small.vim
+:function! RunTest(str, result)
+    if exists(a:str) == a:result
+	echo "OK"
+    else
+	echo "FAILED: Checking for " . a:str
+    endif
+endfunction
+:function! TestExists()
+    augroup myagroup
+	autocmd! BufEnter *.my echo 'myfile edited'
+    augroup END
+
+    let test_cases = []
+
+    " valid autocmd group
+    let test_cases += [['#myagroup', 1]]
+    " valid autocmd group with garbage
+    let test_cases += [['#myagroup+b', 0]]
+    " Valid autocmd group and event
+    let test_cases += [['#myagroup#BufEnter', 1]]
+    " Valid autocmd group, event and pattern
+    let test_cases += [['#myagroup#BufEnter#*.my', 1]]
+    " Valid autocmd event
+    let test_cases += [['#BufEnter', 1]]
+    " Valid autocmd event and pattern
+    let test_cases += [['#BufEnter#*.my', 1]]
+    " Non-existing autocmd group or event
+    let test_cases += [['#xyzagroup', 0]]
+    " Non-existing autocmd group and valid autocmd event
+    let test_cases += [['#xyzagroup#BufEnter', 0]]
+    " Valid autocmd group and event with no matching pattern
+    let test_cases += [['#myagroup#CmdwinEnter', 0]]
+    " Valid autocmd group and non-existing autocmd event
+    let test_cases += [['#myagroup#xyzacmd', 0]]
+    " Valid autocmd group and event and non-matching pattern
+    let test_cases += [['#myagroup#BufEnter#xyzpat', 0]]
+    " Valid autocmd event and non-matching pattern
+    let test_cases += [['#BufEnter#xyzpat', 0]]
+    " Empty autocmd group, event and pattern
+    let test_cases += [['###', 0]]
+    " Empty autocmd group and event or empty event and pattern
+    let test_cases += [['##', 0]]
+    " Valid autocmd event
+    let test_cases += [['##FileReadCmd', 1]]
+    " Non-existing autocmd event
+    let test_cases += [['##MySpecialCmd', 0]]
+
+    " Existing and working option (long form)
+    let test_cases += [['&textwidth', 1]]
+    " Existing and working option (short form)
+    let test_cases += [['&tw', 1]]
+    " Existing and working option with garbage
+    let test_cases += [['&tw-', 0]]
+    " Global option
+    let test_cases += [['&g:errorformat', 1]]
+    " Local option
+    let test_cases += [['&l:errorformat', 1]]
+    " Negative form of existing and working option (long form)
+    let test_cases += [['&nojoinspaces', 0]]
+    " Negative form of existing and working option (short form)
+    let test_cases += [['&nojs', 0]]
+    " Non-existing option
+    let test_cases += [['&myxyzoption', 0]]
+
+    " Existing and working option (long form)
+    let test_cases += [['+incsearch', 1]]
+    " Existing and working option with garbage
+    let test_cases += [['+incsearch!1', 0]]
+    " Existing and working option (short form)
+    let test_cases += [['+is', 1]]
+    " Existing option that is hidden.
+    let test_cases += [['+autoprint', 0]]
+
+    " Existing environment variable
+    let $EDITOR_NAME = 'Vim Editor'
+    let test_cases += [['$EDITOR_NAME', 1]]
+    " Non-existing environment variable
+    let test_cases += [['$NON_ENV_VAR', 0]]
+
+    " Valid internal function
+    let test_cases += [['*bufnr', 1]]
+    " Valid internal function with ()
+    let test_cases += [['*bufnr()', 1]]
+    " Non-existing internal function
+    let test_cases += [['*myxyzfunc', 0]]
+    " Valid internal function with garbage
+    let test_cases += [['*bufnr&6', 0]]
+
+    " Valid user defined function
+    let test_cases += [['*TestExists', 1]]
+    " Non-existing user defined function
+    let test_cases += [['*MyxyzFunc', 0]]
+
+    redir! > test.out
+
+    for [test_case, result] in test_cases
+      	echo test_case . ": " . result
+        call RunTest(test_case, result)
+    endfor
+
+    " Valid internal command (full match)
+    echo ':edit: 2'
+    if exists(':edit') == 2
+	echo "OK"
+    else
+	echo "FAILED"
+    endif
+
+    " Valid internal command (full match) with garbage
+    echo ':edit/a: 0'
+    if exists(':edit/a') == 0
+	echo "OK"
+    else
+	echo "FAILED"
+    endif
+
+    " Valid internal command (partial match)
+    echo ':q: 1'
+    if exists(':q') == 1
+	echo "OK"
+    else
+	echo "FAILED"
+    endif
+
+    " Non-existing internal command
+    echo ':invalidcmd: 0'
+    if !exists(':invalidcmd')
+	echo "OK"
+    else
+	echo "FAILED"
+    endif
+
+    " User defined command (full match)
+    command! MyCmd :echo 'My command'
+    echo ':MyCmd: 2'
+    if exists(':MyCmd') == 2
+	echo "OK"
+    else
+	echo "FAILED"
+    endif
+
+    " User defined command (partial match)
+    command! MyOtherCmd :echo 'Another command'
+    echo ':My: 3'
+    if exists(':My') == 3
+	echo "OK"
+    else
+	echo "FAILED"
+    endif
+
+    " Command modifier
+    echo ':rightbelow: 2'
+    if exists(':rightbelow') == 2
+	echo "OK"
+    else
+	echo "FAILED"
+    endif
+
+    " Non-existing user defined command (full match)
+    delcommand MyCmd
+
+    echo ':MyCmd: 0'
+    if !exists(':MyCmd')
+	echo "OK"
+    else
+	echo "FAILED"
+    endif
+
+    " Non-existing user defined command (partial match)
+    delcommand MyOtherCmd
+
+    echo ':My: 0'
+    if !exists(':My')
+	echo "OK"
+    else
+	echo "FAILED"
+    endif
+
+    " Valid local variable
+    let local_var = 1
+    echo 'local_var: 1'
+    if exists('local_var')
+	echo "OK"
+    else
+	echo "FAILED"
+    endif
+
+    " Valid local variable with garbage
+    let local_var = 1
+    echo 'local_var%n: 0'
+    if !exists('local_var%n')
+	echo "OK"
+    else
+	echo "FAILED"
+    endif
+
+    " Non-existing local variable
+    unlet local_var
+    echo 'local_var: 0'
+    if !exists('local_var')
+	echo "OK"
+    else
+	echo "FAILED"
+    endif
+
+    " Valid local list
+    let local_list = ["blue", "orange"]
+    echo 'local_list: 1'
+    if exists('local_list')
+	echo "OK"
+    else
+	echo "FAILED"
+    endif
+
+    " Valid local list item
+    echo 'local_list[1]: 1'
+    if exists('local_list[1]')
+	echo "OK"
+    else
+	echo "FAILED"
+    endif
+
+    " Valid local list item with garbage
+    echo 'local_list[1]+5: 0'
+    if !exists('local_list[1]+5')
+	echo "OK"
+    else
+	echo "FAILED"
+    endif
+
+    " Invalid local list item
+    echo 'local_list[2]: 0'
+    if !exists('local_list[2]')
+	echo "OK"
+    else
+	echo "FAILED"
+    endif
+
+    " Non-existing local list
+    unlet local_list
+    echo 'local_list: 0'
+    if !exists('local_list')
+	echo "OK"
+    else
+	echo "FAILED"
+    endif
+
+    " Valid local dictionary
+    let local_dict = {"xcord":100, "ycord":2}
+    echo 'local_dict: 1'
+    if exists('local_dict')
+	echo "OK"
+    else
+	echo "FAILED"
+    endif
+
+    " Non-existing local dictionary
+    unlet local_dict
+    echo 'local_dict: 0'
+    if !exists('local_dict')
+	echo "OK"
+    else
+	echo "FAILED"
+    endif
+
+    " Existing local curly-brace variable
+    let str = "local"
+    let curly_{str}_var = 1
+    echo 'curly_' . str . '_var: 1'
+    if exists('curly_{str}_var')
+	echo "OK"
+    else
+	echo "FAILED"
+    endif
+
+    " Non-existing local curly-brace variable
+    unlet curly_{str}_var
+    echo 'curly_' . str . '_var: 0'
+    if !exists('curly_{str}_var')
+	echo "OK"
+    else
+	echo "FAILED"
+    endif
+
+
+    " Existing global variable
+    let g:global_var = 1
+    echo 'g:global_var: 1'
+    if exists('g:global_var')
+	echo "OK"
+    else
+	echo "FAILED"
+    endif
+
+    " Existing global variable with garbage
+    echo 'g:global_var-n: 1'
+    if !exists('g:global_var-n')
+	echo "OK"
+    else
+	echo "FAILED"
+    endif
+
+    " Non-existing global variable
+    unlet g:global_var
+    echo 'g:global_var: 0'
+    if !exists('g:global_var')
+	echo "OK"
+    else
+	echo "FAILED"
+    endif
+
+    " Existing global list
+    let g:global_list = ["blue", "orange"]
+    echo 'g:global_list: 1'
+    if exists('g:global_list')
+	echo "OK"
+    else
+	echo "FAILED"
+    endif
+
+    " Non-existing global list
+    unlet g:global_list
+    echo 'g:global_list: 0'
+    if !exists('g:global_list')
+	echo "OK"
+    else
+	echo "FAILED"
+    endif
+
+    " Existing global dictionary
+    let g:global_dict = {"xcord":100, "ycord":2}
+    echo 'g:global_dict: 1'
+    if exists('g:global_dict')
+	echo "OK"
+    else
+	echo "FAILED"
+    endif
+
+    " Non-existing global dictionary
+    unlet g:global_dict
+    echo 'g:global_dict: 0'
+    if !exists('g:global_dict')
+	echo "OK"
+    else
+	echo "FAILED"
+    endif
+
+    " Existing global curly-brace variable
+    let str = "global"
+    let g:curly_{str}_var = 1
+    echo 'g:curly_' . str . '_var: 1'
+    if exists('g:curly_{str}_var')
+	echo "OK"
+    else
+	echo "FAILED"
+    endif
+
+    " Non-existing global curly-brace variable
+    unlet g:curly_{str}_var
+    echo 'g:curly_' . str . '_var: 0'
+    if !exists('g:curly_{str}_var')
+	echo "OK"
+    else
+	echo "FAILED"
+    endif
+
+    " Existing window variable
+    echo 'w:window_var: 1'
+    let w:window_var = 1
+    if exists('w:window_var')
+	echo "OK"
+    else
+	echo "FAILED"
+    endif
+
+    " Non-existing window variable
+    unlet w:window_var
+    echo 'w:window_var: 0'
+    if !exists('w:window_var')
+	echo "OK"
+    else
+	echo "FAILED"
+    endif
+
+    " Existing window list
+    let w:window_list = ["blue", "orange"]
+    echo 'w:window_list: 1'
+    if exists('w:window_list')
+	echo "OK"
+    else
+	echo "FAILED"
+    endif
+
+    " Non-existing window list
+    unlet w:window_list
+    echo 'w:window_list: 0'
+    if !exists('w:window_list')
+	echo "OK"
+    else
+	echo "FAILED"
+    endif
+
+    " Existing window dictionary
+    let w:window_dict = {"xcord":100, "ycord":2}
+    echo 'w:window_dict: 1'
+    if exists('w:window_dict')
+	echo "OK"
+    else
+	echo "FAILED"
+    endif
+
+    " Non-existing window dictionary
+    unlet w:window_dict
+    echo 'w:window_dict: 0'
+    if !exists('w:window_dict')
+	echo "OK"
+    else
+	echo "FAILED"
+    endif
+
+    " Existing window curly-brace variable
+    let str = "window"
+    let w:curly_{str}_var = 1
+    echo 'w:curly_' . str . '_var: 1'
+    if exists('w:curly_{str}_var')
+	echo "OK"
+    else
+	echo "FAILED"
+    endif
+
+    " Non-existing window curly-brace variable
+    unlet w:curly_{str}_var
+    echo 'w:curly_' . str . '_var: 0'
+    if !exists('w:curly_{str}_var')
+	echo "OK"
+    else
+	echo "FAILED"
+    endif
+
+    " Existing buffer variable
+    echo 'b:buffer_var: 1'
+    let b:buffer_var = 1
+    if exists('b:buffer_var')
+	echo "OK"
+    else
+	echo "FAILED"
+    endif
+
+    " Non-existing buffer variable
+    unlet b:buffer_var
+    echo 'b:buffer_var: 0'
+    if !exists('b:buffer_var')
+	echo "OK"
+    else
+	echo "FAILED"
+    endif
+
+    " Existing buffer list
+    let b:buffer_list = ["blue", "orange"]
+    echo 'b:buffer_list: 1'
+    if exists('b:buffer_list')
+	echo "OK"
+    else
+	echo "FAILED"
+    endif
+
+    " Non-existing buffer list
+    unlet b:buffer_list
+    echo 'b:buffer_list: 0'
+    if !exists('b:buffer_list')
+	echo "OK"
+    else
+	echo "FAILED"
+    endif
+
+    " Existing buffer dictionary
+    let b:buffer_dict = {"xcord":100, "ycord":2}
+    echo 'b:buffer_dict: 1'
+    if exists('b:buffer_dict')
+	echo "OK"
+    else
+	echo "FAILED"
+    endif
+
+    " Non-existing buffer dictionary
+    unlet b:buffer_dict
+    echo 'b:buffer_dict: 0'
+    if !exists('b:buffer_dict')
+	echo "OK"
+    else
+	echo "FAILED"
+    endif
+
+    " Existing buffer curly-brace variable
+    let str = "buffer"
+    let b:curly_{str}_var = 1
+    echo 'b:curly_' . str . '_var: 1'
+    if exists('b:curly_{str}_var')
+	echo "OK"
+    else
+	echo "FAILED"
+    endif
+
+    " Non-existing buffer curly-brace variable
+    unlet b:curly_{str}_var
+    echo 'b:curly_' . str . '_var: 0'
+    if !exists('b:curly_{str}_var')
+	echo "OK"
+    else
+	echo "FAILED"
+    endif
+
+    " Script-local tests
+    source test60.vim
+
+    " Existing Vim internal variable
+    echo 'v:version: 1'
+    if exists('v:version')
+	echo "OK"
+    else
+	echo "FAILED"
+    endif
+
+    " Non-existing Vim internal variable
+    echo 'v:non_exists_var: 0'
+    if !exists('v:non_exists_var')
+	echo "OK"
+    else
+	echo "FAILED"
+    endif
+
+    " Function arguments
+    function TestFuncArg(func_arg, ...)
+        echo 'a:func_arg: 1'
+        if exists('a:func_arg')
+            echo "OK"
+        else
+            echo "FAILED"
+        endif
+
+        echo 'a:non_exists_arg: 0'
+        if !exists('a:non_exists_arg')
+            echo "OK"
+        else
+            echo "FAILED"
+        endif
+
+        echo 'a:1: 1'
+        if exists('a:1')
+            echo "OK"
+        else
+            echo "FAILED"
+        endif
+
+        echo 'a:2: 0'
+        if !exists('a:2')
+            echo "OK"
+        else
+            echo "FAILED"
+        endif
+    endfunction
+
+    call TestFuncArg("arg1", "arg2")
+
+    redir END
+endfunction
+:call TestExists()
+:edit! test.out
+:set ff=unix
+:w
+:qa!
+ENDTEST
+
--- /dev/null
+++ b/testdir/test60.ok
@@ -1,0 +1,197 @@
+
+#myagroup: 1
+OK
+#myagroup+b: 0
+OK
+#myagroup#BufEnter: 1
+OK
+#myagroup#BufEnter#*.my: 1
+OK
+#BufEnter: 1
+OK
+#BufEnter#*.my: 1
+OK
+#xyzagroup: 0
+OK
+#xyzagroup#BufEnter: 0
+OK
+#myagroup#CmdwinEnter: 0
+OK
+#myagroup#xyzacmd: 0
+OK
+#myagroup#BufEnter#xyzpat: 0
+OK
+#BufEnter#xyzpat: 0
+OK
+###: 0
+OK
+##: 0
+OK
+##FileReadCmd: 1
+OK
+##MySpecialCmd: 0
+OK
+&textwidth: 1
+OK
+&tw: 1
+OK
+&tw-: 0
+OK
+&g:errorformat: 1
+OK
+&l:errorformat: 1
+OK
+&nojoinspaces: 0
+OK
+&nojs: 0
+OK
+&myxyzoption: 0
+OK
++incsearch: 1
+OK
++incsearch!1: 0
+OK
++is: 1
+OK
++autoprint: 0
+OK
+$EDITOR_NAME: 1
+OK
+$NON_ENV_VAR: 0
+OK
+*bufnr: 1
+OK
+*bufnr(): 1
+OK
+*myxyzfunc: 0
+OK
+*bufnr&6: 0
+OK
+*TestExists: 1
+OK
+*MyxyzFunc: 0
+OK
+:edit: 2
+OK
+:edit/a: 0
+OK
+:q: 1
+OK
+:invalidcmd: 0
+OK
+:MyCmd: 2
+OK
+:My: 3
+OK
+:rightbelow: 2
+OK
+:MyCmd: 0
+OK
+:My: 0
+OK
+local_var: 1
+OK
+local_var%n: 0
+OK
+local_var: 0
+OK
+local_list: 1
+OK
+local_list[1]: 1
+OK
+local_list[1]+5: 0
+OK
+local_list[2]: 0
+OK
+local_list: 0
+OK
+local_dict: 1
+OK
+local_dict: 0
+OK
+curly_local_var: 1
+OK
+curly_local_var: 0
+OK
+g:global_var: 1
+OK
+g:global_var-n: 1
+OK
+g:global_var: 0
+OK
+g:global_list: 1
+OK
+g:global_list: 0
+OK
+g:global_dict: 1
+OK
+g:global_dict: 0
+OK
+g:curly_global_var: 1
+OK
+g:curly_global_var: 0
+OK
+w:window_var: 1
+OK
+w:window_var: 0
+OK
+w:window_list: 1
+OK
+w:window_list: 0
+OK
+w:window_dict: 1
+OK
+w:window_dict: 0
+OK
+w:curly_window_var: 1
+OK
+w:curly_window_var: 0
+OK
+b:buffer_var: 1
+OK
+b:buffer_var: 0
+OK
+b:buffer_list: 1
+OK
+b:buffer_list: 0
+OK
+b:buffer_dict: 1
+OK
+b:buffer_dict: 0
+OK
+b:curly_buffer_var: 1
+OK
+b:curly_buffer_var: 0
+OK
+s:script_var: 1
+OK
+s:script_var: 0
+OK
+s:script_list: 1
+OK
+s:script_list: 0
+OK
+s:script_dict: 1
+OK
+s:script_dict: 0
+OK
+s:curly_script_var: 1
+OK
+s:curly_script_var: 0
+OK
+*s:my_script_func: 1
+OK
+*s:my_script_func: 0
+OK
+v:version: 1
+OK
+v:non_exists_var: 0
+OK
+a:func_arg: 1
+OK
+a:non_exists_arg: 0
+OK
+a:1: 1
+OK
+a:2: 0
+OK
--- /dev/null
+++ b/testdir/test60.vim
@@ -1,0 +1,97 @@
+" Vim script for exists() function test
+" Script-local variables are checked here
+
+" Existing script-local variable
+let s:script_var = 1
+echo 's:script_var: 1'
+if exists('s:script_var')
+    echo "OK"
+else
+    echo "FAILED"
+endif
+
+" Non-existing script-local variable
+unlet s:script_var
+echo 's:script_var: 0'
+if !exists('s:script_var')
+    echo "OK"
+else
+    echo "FAILED"
+endif
+
+" Existing script-local list
+let s:script_list = ["blue", "orange"]
+echo 's:script_list: 1'
+if exists('s:script_list')
+    echo "OK"
+else
+    echo "FAILED"
+endif
+
+" Non-existing script-local list
+unlet s:script_list
+echo 's:script_list: 0'
+if !exists('s:script_list')
+    echo "OK"
+else
+    echo "FAILED"
+endif
+
+" Existing script-local dictionary
+let s:script_dict = {"xcord":100, "ycord":2}
+echo 's:script_dict: 1'
+if exists('s:script_dict')
+    echo "OK"
+else
+    echo "FAILED"
+endif
+
+" Non-existing script-local dictionary
+unlet s:script_dict
+echo 's:script_dict: 0'
+if !exists('s:script_dict')
+    echo "OK"
+else
+    echo "FAILED"
+endif
+
+" Existing script curly-brace variable
+let str = "script"
+let s:curly_{str}_var = 1
+echo 's:curly_' . str . '_var: 1'
+if exists('s:curly_{str}_var')
+    echo "OK"
+else
+    echo "FAILED"
+endif
+
+" Non-existing script-local curly-brace variable
+unlet s:curly_{str}_var
+echo 's:curly_' . str . '_var: 0'
+if !exists('s:curly_{str}_var')
+    echo "OK"
+else
+    echo "FAILED"
+endif
+
+" Existing script-local function
+function! s:my_script_func()
+endfunction
+
+echo '*s:my_script_func: 1'
+if exists('*s:my_script_func')
+    echo "OK"
+else
+    echo "FAILED"
+endif
+
+" Non-existing script-local function
+delfunction s:my_script_func
+
+echo '*s:my_script_func: 0'
+if !exists('*s:my_script_func')
+    echo "OK"
+else
+    echo "FAILED"
+endif
+
--- /dev/null
+++ b/testdir/test61.in
@@ -1,0 +1,59 @@
+Tests for undo tree.
+Since this script is sourced we need to explicitly break changes up in
+undo-able pieces.  Do that by setting 'undolevels'.
+
+STARTTEST
+:" Delete three characters and undo
+Gx:set ul=100
+x:set ul=100
+x:.w! test.out
+g-:.w >>test.out
+g-:.w >>test.out
+g-:.w >>test.out
+g-:.w >>test.out
+:"
+:/^111/w >>test.out
+:" Delete three other characters and go back in time step by step
+$x:set ul=100
+x:set ul=100
+x:.w >>test.out
+:sleep 1
+g-:.w >>test.out
+g-:.w >>test.out
+g-:.w >>test.out
+g-:.w >>test.out
+g-:.w >>test.out
+g-:.w >>test.out
+g-:.w >>test.out
+g-:.w >>test.out
+10g+:.w >>test.out
+:"
+:/^222/w >>test.out
+:" Delay for three seconds and go some seconds forward and backward
+:sleep 2
+Aa:set ul=100
+Ab:set ul=100
+Ac:set ul=100
+:.w >>test.out
+:ear 1s
+:.w >>test.out
+:ear 3s
+:.w >>test.out
+:later 1s
+:.w >>test.out
+:later 1h
+:.w >>test.out
+:"
+:" test undojoin
+Goaaaa:set ul=100
+obbbbu:.w >>test.out
+obbbb:set ul=100
+:undojoin
+occccu:.w >>test.out
+:qa!
+ENDTEST
+
+1111 -----
+2222 -----
+
+123456789
--- /dev/null
+++ b/testdir/test61.ok
@@ -1,0 +1,24 @@
+456789
+3456789
+23456789
+123456789
+123456789
+1111 -----
+123456
+1234567
+12345678
+456789
+3456789
+23456789
+123456789
+123456789
+123456789
+123456
+2222 -----
+123456abc
+123456
+123456789
+123456
+123456abc
+aaaa
+aaaa
--- /dev/null
+++ b/testdir/test62.in
@@ -1,0 +1,32 @@
+Tests for tab pages
+
+STARTTEST
+:so small.vim
+:" Simple test for opening and closing a tab page
+:tabnew
+:let nr = tabpagenr()
+:q
+:call append(line('$'), 'tab page ' . nr)
+:"
+:" Open three tab pages and use ":tabdo"
+:0tabnew
+:1tabnew
+:888tabnew
+:tabdo call append(line('$'), 'this is tab page ' . tabpagenr())
+:tabclose! 2
+:tabrewind
+:let line1 = getline('$')
+:undo
+:q
+:tablast
+:let line2 = getline('$')
+:q!
+:call append(line('$'), line1)
+:call append(line('$'), line2)
+:"
+:"
+:/^Results/,$w! test.out
+:qa!
+ENDTEST
+
+Results:
--- /dev/null
+++ b/testdir/test62.ok
@@ -1,0 +1,5 @@
+Results:
+tab page 2
+this is tab page 3
+this is tab page 1
+this is tab page 4
--- /dev/null
+++ b/testdir/test7.in
@@ -1,0 +1,26 @@
+Test for autocommand that changes the buffer list, when doing ":ball".
+
+STARTTEST
+:so small.vim
+/^start of
+A1:.,/end of/w! Xxx1   " write test file Xxx1
+:sp Xxx1
+:close
+$r2:.,/end of/w! Xxx2    " write test file Xxx2
+:sp Xxx2
+:close
+$r3:.,/end of/w! Xxx3    " write test file Xxx3
+:sp Xxx3
+:close
+:au BufReadPost Xxx2 bwipe
+$r4:ball                 " open window for all args, close Xxx2
+:.,$w! test.out          " Write contents of this file
+:w >>test.out        " Append contents of second window (Xxx1)
+:/^start of/,$w >>test.out   " Append contents of last window (this file)
+:qa!
+ENDTEST
+
+start of test file Xxx
+	this is a test
+	this is a test
+end of test file Xxx
--- /dev/null
+++ b/testdir/test7.ok
@@ -1,0 +1,12 @@
+start of test file Xxx4
+	this is a test
+	this is a test
+end of test file Xxx
+start of test file Xxx1
+	this is a test
+	this is a test
+end of test file Xxx
+start of test file Xxx4
+	this is a test
+	this is a test
+end of test file Xxx
--- /dev/null
+++ b/testdir/test8.in
@@ -1,0 +1,24 @@
+Test for BufWritePre autocommand that deletes or unloads the buffer.
+
+STARTTEST
+:so small.vim
+:au BufWritePre Xxx1 bunload
+:au BufWritePre Xxx2 bwipe
+/^start of
+A1:.,/end of/w! Xxx1  " write test file Xxx1
+$r2:.,/end of/w! Xxx2   " write test file Xxx2
+:e! Xxx2                " edit Xxx2
+:bdel test8.in		" delete this file from the buffer list
+:e Xxx1                 " edit Xxx1
+:w                      " write it, will unload it and give an error msg
+:w! test.out            " Write contents of this file
+:e! Xxx2                " start editing Xxx2
+:bwipe test.out         " remove test.out from the buffer list
+:w                      " write it, will delete the buffer and give an error msg
+:w >>test.out           " Append contents of this file
+:qa!
+ENDTEST
+
+start of Xxx
+	test
+end of Xxx
--- /dev/null
+++ b/testdir/test8.ok
@@ -1,0 +1,6 @@
+start of Xxx2
+	test
+end of Xxx
+start of Xxx1
+	test
+end of Xxx
--- /dev/null
+++ b/testdir/test9.in
@@ -1,0 +1,12 @@
+Test for Bufleave autocommand that deletes the buffer we are about to edit.
+
+STARTTEST
+:so small.vim
+:au BufLeave test9.in bwipe yy
+:e yy
+:/^start of/,$w! test.out      " Write contents of this file
+:qa!
+ENDTEST
+
+start of test file xx
+end of test file xx
--- /dev/null
+++ b/testdir/test9.ok
@@ -1,0 +1,2 @@
+start of test file xx
+end of test file xx
--- /dev/null
+++ b/ui.c
@@ -1,0 +1,3118 @@
+/* vi:set ts=8 sts=4 sw=4:
+ *
+ * VIM - Vi IMproved	by Bram Moolenaar
+ *
+ * Do ":help uganda"  in Vim to read copying and usage conditions.
+ * Do ":help credits" in Vim to see a list of people who contributed.
+ * See README.txt for an overview of the Vim source code.
+ */
+
+/*
+ * ui.c: functions that handle the user interface.
+ * 1. Keyboard input stuff, and a bit of windowing stuff.  These are called
+ *    before the machine specific stuff (mch_*) so that we can call the GUI
+ *    stuff instead if the GUI is running.
+ * 2. Clipboard stuff.
+ * 3. Input buffer stuff.
+ */
+
+#include "vim.h"
+
+    void
+ui_write(s, len)
+    char_u  *s;
+    int	    len;
+{
+#ifdef FEAT_GUI
+    if (gui.in_use && !gui.dying && !gui.starting)
+    {
+	gui_write(s, len);
+	if (p_wd)
+	    gui_wait_for_chars(p_wd);
+	return;
+    }
+#endif
+#ifndef NO_CONSOLE
+    /* Don't output anything in silent mode ("ex -s") unless 'verbose' set */
+    if (!(silent_mode && p_verbose == 0))
+    {
+#ifdef FEAT_MBYTE
+	char_u	*tofree = NULL;
+
+	if (output_conv.vc_type != CONV_NONE)
+	{
+	    /* Convert characters from 'encoding' to 'termencoding'. */
+	    tofree = string_convert(&output_conv, s, &len);
+	    if (tofree != NULL)
+		s = tofree;
+	}
+#endif
+
+	mch_write(s, len);
+
+#ifdef FEAT_MBYTE
+	if (output_conv.vc_type != CONV_NONE)
+	    vim_free(tofree);
+#endif
+    }
+#endif
+}
+
+#if defined(UNIX) || defined(VMS) || defined(PROTO)
+/*
+ * When executing an external program, there may be some typed characters that
+ * are not consumed by it.  Give them back to ui_inchar() and they are stored
+ * here for the next call.
+ */
+static char_u *ta_str = NULL;
+static int ta_off;	/* offset for next char to use when ta_str != NULL */
+static int ta_len;	/* length of ta_str when it's not NULL*/
+
+    void
+ui_inchar_undo(s, len)
+    char_u	*s;
+    int		len;
+{
+    char_u  *new;
+    int	    newlen;
+
+    newlen = len;
+    if (ta_str != NULL)
+	newlen += ta_len - ta_off;
+    new = alloc(newlen);
+    if (new != NULL)
+    {
+	if (ta_str != NULL)
+	{
+	    mch_memmove(new, ta_str + ta_off, (size_t)(ta_len - ta_off));
+	    mch_memmove(new + ta_len - ta_off, s, (size_t)len);
+	    vim_free(ta_str);
+	}
+	else
+	    mch_memmove(new, s, (size_t)len);
+	ta_str = new;
+	ta_len = newlen;
+	ta_off = 0;
+    }
+}
+#endif
+
+/*
+ * ui_inchar(): low level input funcion.
+ * Get characters from the keyboard.
+ * Return the number of characters that are available.
+ * If "wtime" == 0 do not wait for characters.
+ * If "wtime" == -1 wait forever for characters.
+ * If "wtime" > 0 wait "wtime" milliseconds for a character.
+ *
+ * "tb_change_cnt" is the value of typebuf.tb_change_cnt if "buf" points into
+ * it.  When typebuf.tb_change_cnt changes (e.g., when a message is received
+ * from a remote client) "buf" can no longer be used.  "tb_change_cnt" is NULL
+ * otherwise.
+ */
+    int
+ui_inchar(buf, maxlen, wtime, tb_change_cnt)
+    char_u	*buf;
+    int		maxlen;
+    long	wtime;	    /* don't use "time", MIPS cannot handle it */
+    int		tb_change_cnt;
+{
+    int		retval = 0;
+
+#if defined(FEAT_GUI) && (defined(UNIX) || defined(VMS))
+    /*
+     * Use the typeahead if there is any.
+     */
+    if (ta_str != NULL)
+    {
+	if (maxlen >= ta_len - ta_off)
+	{
+	    mch_memmove(buf, ta_str + ta_off, (size_t)ta_len);
+	    vim_free(ta_str);
+	    ta_str = NULL;
+	    return ta_len;
+	}
+	mch_memmove(buf, ta_str + ta_off, (size_t)maxlen);
+	ta_off += maxlen;
+	return maxlen;
+    }
+#endif
+
+#ifdef FEAT_PROFILE
+    if (do_profiling == PROF_YES && wtime != 0)
+	prof_inchar_enter();
+#endif
+
+#ifdef NO_CONSOLE_INPUT
+    /* Don't wait for character input when the window hasn't been opened yet.
+     * Do try reading, this works when redirecting stdin from a file.
+     * Must return something, otherwise we'll loop forever.  If we run into
+     * this very often we probably got stuck, exit Vim. */
+    if (no_console_input())
+    {
+	static int count = 0;
+
+# ifndef NO_CONSOLE
+	retval = mch_inchar(buf, maxlen, (wtime >= 0 && wtime < 10)
+						? 10L : wtime, tb_change_cnt);
+	if (retval > 0 || typebuf_changed(tb_change_cnt) || wtime >= 0)
+	    goto theend;
+# endif
+	if (wtime == -1 && ++count == 1000)
+	    read_error_exit();
+	buf[0] = CAR;
+	retval = 1;
+	goto theend;
+    }
+#endif
+
+    /* If we are going to wait for some time or block... */
+    if (wtime == -1 || wtime > 100L)
+    {
+	/* ... allow signals to kill us. */
+	(void)vim_handle_signal(SIGNAL_UNBLOCK);
+
+	/* ... there is no need for CTRL-C to interrupt something, don't let
+	 * it set got_int when it was mapped. */
+	if (mapped_ctrl_c)
+	    ctrl_c_interrupts = FALSE;
+    }
+
+#ifdef FEAT_GUI
+    if (gui.in_use)
+    {
+	if (gui_wait_for_chars(wtime) && !typebuf_changed(tb_change_cnt))
+	    retval = read_from_input_buf(buf, (long)maxlen);
+    }
+#endif
+#ifndef NO_CONSOLE
+# ifdef FEAT_GUI
+    else
+# endif
+    {
+	retval = mch_inchar(buf, maxlen, wtime, tb_change_cnt);
+    }
+#endif
+
+    if (wtime == -1 || wtime > 100L)
+	/* block SIGHUP et al. */
+	(void)vim_handle_signal(SIGNAL_BLOCK);
+
+    ctrl_c_interrupts = TRUE;
+
+#ifdef NO_CONSOLE_INPUT
+theend:
+#endif
+#ifdef FEAT_PROFILE
+    if (do_profiling == PROF_YES && wtime != 0)
+	prof_inchar_exit();
+#endif
+    return retval;
+}
+
+/*
+ * return non-zero if a character is available
+ */
+    int
+ui_char_avail()
+{
+#ifdef FEAT_GUI
+    if (gui.in_use)
+    {
+	gui_mch_update();
+	return input_available();
+    }
+#endif
+#ifndef NO_CONSOLE
+# ifdef NO_CONSOLE_INPUT
+    if (no_console_input())
+	return 0;
+# endif
+    return mch_char_avail();
+#else
+    return 0;
+#endif
+}
+
+/*
+ * Delay for the given number of milliseconds.	If ignoreinput is FALSE then we
+ * cancel the delay if a key is hit.
+ */
+    void
+ui_delay(msec, ignoreinput)
+    long	msec;
+    int		ignoreinput;
+{
+#ifdef FEAT_GUI
+    if (gui.in_use && !ignoreinput)
+	gui_wait_for_chars(msec);
+    else
+#endif
+	mch_delay(msec, ignoreinput);
+}
+
+/*
+ * If the machine has job control, use it to suspend the program,
+ * otherwise fake it by starting a new shell.
+ * When running the GUI iconify the window.
+ */
+    void
+ui_suspend()
+{
+#ifdef FEAT_GUI
+    if (gui.in_use)
+    {
+	gui_mch_iconify();
+	return;
+    }
+#endif
+    mch_suspend();
+}
+
+#if !defined(UNIX) || !defined(SIGTSTP) || defined(PROTO) || defined(__BEOS__)
+/*
+ * When the OS can't really suspend, call this function to start a shell.
+ * This is never called in the GUI.
+ */
+    void
+suspend_shell()
+{
+    if (*p_sh == NUL)
+	EMSG(_(e_shellempty));
+    else
+    {
+	MSG_PUTS(_("new shell started\n"));
+	do_shell(NULL, 0);
+    }
+}
+#endif
+
+/*
+ * Try to get the current Vim shell size.  Put the result in Rows and Columns.
+ * Use the new sizes as defaults for 'columns' and 'lines'.
+ * Return OK when size could be determined, FAIL otherwise.
+ */
+    int
+ui_get_shellsize()
+{
+    int	    retval;
+
+#ifdef FEAT_GUI
+    if (gui.in_use)
+	retval = gui_get_shellsize();
+    else
+#endif
+	retval = mch_get_shellsize();
+
+    check_shellsize();
+
+    /* adjust the default for 'lines' and 'columns' */
+    if (retval == OK)
+    {
+	set_number_default("lines", Rows);
+	set_number_default("columns", Columns);
+    }
+    return retval;
+}
+
+/*
+ * Set the size of the Vim shell according to Rows and Columns, if possible.
+ * The gui_set_shellsize() or mch_set_shellsize() function will try to set the
+ * new size.  If this is not possible, it will adjust Rows and Columns.
+ */
+/*ARGSUSED*/
+    void
+ui_set_shellsize(mustset)
+    int		mustset;	/* set by the user */
+{
+#ifdef FEAT_GUI
+    if (gui.in_use)
+	gui_set_shellsize(mustset,
+# ifdef WIN3264
+		TRUE
+# else
+		FALSE
+# endif
+		, RESIZE_BOTH);
+    else
+#endif
+	mch_set_shellsize();
+}
+
+/*
+ * Called when Rows and/or Columns changed.  Adjust scroll region and mouse
+ * region.
+ */
+    void
+ui_new_shellsize()
+{
+    if (full_screen && !exiting)
+    {
+#ifdef FEAT_GUI
+	if (gui.in_use)
+	    gui_new_shellsize();
+	else
+#endif
+	    mch_new_shellsize();
+    }
+}
+
+    void
+ui_breakcheck()
+{
+#ifdef FEAT_GUI
+    if (gui.in_use)
+	gui_mch_update();
+    else
+#endif
+	mch_breakcheck();
+}
+
+/*****************************************************************************
+ * Functions for copying and pasting text between applications.
+ * This is always included in a GUI version, but may also be included when the
+ * clipboard and mouse is available to a terminal version such as xterm.
+ * Note: there are some more functions in ops.c that handle selection stuff.
+ *
+ * Also note that the majority of functions here deal with the X 'primary'
+ * (visible - for Visual mode use) selection, and only that. There are no
+ * versions of these for the 'clipboard' selection, as Visual mode has no use
+ * for them.
+ */
+
+#if defined(FEAT_CLIPBOARD) || defined(PROTO)
+
+/*
+ * Selection stuff using Visual mode, for cutting and pasting text to other
+ * windows.
+ */
+
+/*
+ * Call this to initialise the clipboard.  Pass it FALSE if the clipboard code
+ * is included, but the clipboard can not be used, or TRUE if the clipboard can
+ * be used.  Eg unix may call this with FALSE, then call it again with TRUE if
+ * the GUI starts.
+ */
+    void
+clip_init(can_use)
+    int	    can_use;
+{
+    VimClipboard *cb;
+
+    cb = &clip_star;
+    for (;;)
+    {
+	cb->available  = can_use;
+	cb->owned      = FALSE;
+	cb->start.lnum = 0;
+	cb->start.col  = 0;
+	cb->end.lnum   = 0;
+	cb->end.col    = 0;
+	cb->state      = SELECT_CLEARED;
+
+	if (cb == &clip_plus)
+	    break;
+	cb = &clip_plus;
+    }
+}
+
+/*
+ * Check whether the VIsual area has changed, and if so try to become the owner
+ * of the selection, and free any old converted selection we may still have
+ * lying around.  If the VIsual mode has ended, make a copy of what was
+ * selected so we can still give it to others.	Will probably have to make sure
+ * this is called whenever VIsual mode is ended.
+ */
+    void
+clip_update_selection()
+{
+    pos_T    start, end;
+
+    /* If visual mode is only due to a redo command ("."), then ignore it */
+    if (!redo_VIsual_busy && VIsual_active && (State & NORMAL))
+    {
+	if (lt(VIsual, curwin->w_cursor))
+	{
+	    start = VIsual;
+	    end = curwin->w_cursor;
+#ifdef FEAT_MBYTE
+	    if (has_mbyte)
+		end.col += (*mb_ptr2len)(ml_get_cursor()) - 1;
+#endif
+	}
+	else
+	{
+	    start = curwin->w_cursor;
+	    end = VIsual;
+	}
+	if (!equalpos(clip_star.start, start)
+		|| !equalpos(clip_star.end, end)
+		|| clip_star.vmode != VIsual_mode)
+	{
+	    clip_clear_selection();
+	    clip_star.start = start;
+	    clip_star.end = end;
+	    clip_star.vmode = VIsual_mode;
+	    clip_free_selection(&clip_star);
+	    clip_own_selection(&clip_star);
+	    clip_gen_set_selection(&clip_star);
+	}
+    }
+}
+
+    void
+clip_own_selection(cbd)
+    VimClipboard	*cbd;
+{
+    /*
+     * Also want to check somehow that we are reading from the keyboard rather
+     * than a mapping etc.
+     */
+    if (!cbd->owned && cbd->available)
+    {
+	cbd->owned = (clip_gen_own_selection(cbd) == OK);
+#ifdef FEAT_X11
+	if (cbd == &clip_star)
+	{
+	    /* May have to show a different kind of highlighting for the
+	     * selected area.  There is no specific redraw command for this,
+	     * just redraw all windows on the current buffer. */
+	    if (cbd->owned
+		    && (get_real_state() == VISUAL
+					    || get_real_state() == SELECTMODE)
+		    && clip_isautosel()
+		    && hl_attr(HLF_V) != hl_attr(HLF_VNC))
+		redraw_curbuf_later(INVERTED_ALL);
+	}
+#endif
+    }
+}
+
+    void
+clip_lose_selection(cbd)
+    VimClipboard	*cbd;
+{
+#ifdef FEAT_X11
+    int	    was_owned = cbd->owned;
+#endif
+    int     visual_selection = (cbd == &clip_star);
+
+    clip_free_selection(cbd);
+    cbd->owned = FALSE;
+    if (visual_selection)
+	clip_clear_selection();
+    clip_gen_lose_selection(cbd);
+#ifdef FEAT_X11
+    if (visual_selection)
+    {
+	/* May have to show a different kind of highlighting for the selected
+	 * area.  There is no specific redraw command for this, just redraw all
+	 * windows on the current buffer. */
+	if (was_owned
+		&& (get_real_state() == VISUAL
+					    || get_real_state() == SELECTMODE)
+		&& clip_isautosel()
+		&& hl_attr(HLF_V) != hl_attr(HLF_VNC))
+	{
+	    update_curbuf(INVERTED_ALL);
+	    setcursor();
+	    cursor_on();
+	    out_flush();
+# ifdef FEAT_GUI
+	    if (gui.in_use)
+		gui_update_cursor(TRUE, FALSE);
+# endif
+	}
+    }
+#endif
+}
+
+    void
+clip_copy_selection()
+{
+    if (VIsual_active && (State & NORMAL) && clip_star.available)
+    {
+	if (clip_isautosel())
+	    clip_update_selection();
+	clip_free_selection(&clip_star);
+	clip_own_selection(&clip_star);
+	if (clip_star.owned)
+	    clip_get_selection(&clip_star);
+	clip_gen_set_selection(&clip_star);
+    }
+}
+
+/*
+ * Called when Visual mode is ended: update the selection.
+ */
+    void
+clip_auto_select()
+{
+    if (clip_isautosel())
+	clip_copy_selection();
+}
+
+/*
+ * Return TRUE if automatic selection of Visual area is desired.
+ */
+    int
+clip_isautosel()
+{
+    return (
+#ifdef FEAT_GUI
+	    gui.in_use ? (vim_strchr(p_go, GO_ASEL) != NULL) :
+#endif
+	    clip_autoselect);
+}
+
+
+/*
+ * Stuff for general mouse selection, without using Visual mode.
+ */
+
+static int clip_compare_pos __ARGS((int row1, int col1, int row2, int col2));
+static void clip_invert_area __ARGS((int, int, int, int, int how));
+static void clip_invert_rectangle __ARGS((int row, int col, int height, int width, int invert));
+static void clip_get_word_boundaries __ARGS((VimClipboard *, int, int));
+static int  clip_get_line_end __ARGS((int));
+static void clip_update_modeless_selection __ARGS((VimClipboard *, int, int,
+						    int, int));
+
+/* flags for clip_invert_area() */
+#define CLIP_CLEAR	1
+#define CLIP_SET	2
+#define CLIP_TOGGLE	3
+
+/*
+ * Start, continue or end a modeless selection.  Used when editing the
+ * command-line and in the cmdline window.
+ */
+    void
+clip_modeless(button, is_click, is_drag)
+    int		button;
+    int		is_click;
+    int		is_drag;
+{
+    int		repeat;
+
+    repeat = ((clip_star.mode == SELECT_MODE_CHAR
+		|| clip_star.mode == SELECT_MODE_LINE)
+					      && (mod_mask & MOD_MASK_2CLICK))
+	    || (clip_star.mode == SELECT_MODE_WORD
+					     && (mod_mask & MOD_MASK_3CLICK));
+    if (is_click && button == MOUSE_RIGHT)
+    {
+	/* Right mouse button: If there was no selection, start one.
+	 * Otherwise extend the existing selection. */
+	if (clip_star.state == SELECT_CLEARED)
+	    clip_start_selection(mouse_col, mouse_row, FALSE);
+	clip_process_selection(button, mouse_col, mouse_row, repeat);
+    }
+    else if (is_click)
+	clip_start_selection(mouse_col, mouse_row, repeat);
+    else if (is_drag)
+    {
+	/* Don't try extending a selection if there isn't one.  Happens when
+	 * button-down is in the cmdline and them moving mouse upwards. */
+	if (clip_star.state != SELECT_CLEARED)
+	    clip_process_selection(button, mouse_col, mouse_row, repeat);
+    }
+    else /* release */
+	clip_process_selection(MOUSE_RELEASE, mouse_col, mouse_row, FALSE);
+}
+
+/*
+ * Compare two screen positions ala strcmp()
+ */
+    static int
+clip_compare_pos(row1, col1, row2, col2)
+    int		row1;
+    int		col1;
+    int		row2;
+    int		col2;
+{
+    if (row1 > row2) return(1);
+    if (row1 < row2) return(-1);
+    if (col1 > col2) return(1);
+    if (col1 < col2) return(-1);
+		     return(0);
+}
+
+/*
+ * Start the selection
+ */
+    void
+clip_start_selection(col, row, repeated_click)
+    int		col;
+    int		row;
+    int		repeated_click;
+{
+    VimClipboard	*cb = &clip_star;
+
+    if (cb->state == SELECT_DONE)
+	clip_clear_selection();
+
+    row = check_row(row);
+    col = check_col(col);
+#ifdef FEAT_MBYTE
+    col = mb_fix_col(col, row);
+#endif
+
+    cb->start.lnum  = row;
+    cb->start.col   = col;
+    cb->end	    = cb->start;
+    cb->origin_row  = (short_u)cb->start.lnum;
+    cb->state	    = SELECT_IN_PROGRESS;
+
+    if (repeated_click)
+    {
+	if (++cb->mode > SELECT_MODE_LINE)
+	    cb->mode = SELECT_MODE_CHAR;
+    }
+    else
+	cb->mode = SELECT_MODE_CHAR;
+
+#ifdef FEAT_GUI
+    /* clear the cursor until the selection is made */
+    if (gui.in_use)
+	gui_undraw_cursor();
+#endif
+
+    switch (cb->mode)
+    {
+	case SELECT_MODE_CHAR:
+	    cb->origin_start_col = cb->start.col;
+	    cb->word_end_col = clip_get_line_end((int)cb->start.lnum);
+	    break;
+
+	case SELECT_MODE_WORD:
+	    clip_get_word_boundaries(cb, (int)cb->start.lnum, cb->start.col);
+	    cb->origin_start_col = cb->word_start_col;
+	    cb->origin_end_col	 = cb->word_end_col;
+
+	    clip_invert_area((int)cb->start.lnum, cb->word_start_col,
+			    (int)cb->end.lnum, cb->word_end_col, CLIP_SET);
+	    cb->start.col = cb->word_start_col;
+	    cb->end.col   = cb->word_end_col;
+	    break;
+
+	case SELECT_MODE_LINE:
+	    clip_invert_area((int)cb->start.lnum, 0, (int)cb->start.lnum,
+			    (int)Columns, CLIP_SET);
+	    cb->start.col = 0;
+	    cb->end.col   = Columns;
+	    break;
+    }
+
+    cb->prev = cb->start;
+
+#ifdef DEBUG_SELECTION
+    printf("Selection started at (%u,%u)\n", cb->start.lnum, cb->start.col);
+#endif
+}
+
+/*
+ * Continue processing the selection
+ */
+    void
+clip_process_selection(button, col, row, repeated_click)
+    int		button;
+    int		col;
+    int		row;
+    int_u	repeated_click;
+{
+    VimClipboard	*cb = &clip_star;
+    int			diff;
+    int			slen = 1;	/* cursor shape width */
+
+    if (button == MOUSE_RELEASE)
+    {
+	/* Check to make sure we have something selected */
+	if (cb->start.lnum == cb->end.lnum && cb->start.col == cb->end.col)
+	{
+#ifdef FEAT_GUI
+	    if (gui.in_use)
+		gui_update_cursor(FALSE, FALSE);
+#endif
+	    cb->state = SELECT_CLEARED;
+	    return;
+	}
+
+#ifdef DEBUG_SELECTION
+	printf("Selection ended: (%u,%u) to (%u,%u)\n", cb->start.lnum,
+		cb->start.col, cb->end.lnum, cb->end.col);
+#endif
+	if (clip_isautosel()
+		|| (
+#ifdef FEAT_GUI
+		    gui.in_use ? (vim_strchr(p_go, GO_ASELML) != NULL) :
+#endif
+		    clip_autoselectml))
+	    clip_copy_modeless_selection(FALSE);
+#ifdef FEAT_GUI
+	if (gui.in_use)
+	    gui_update_cursor(FALSE, FALSE);
+#endif
+
+	cb->state = SELECT_DONE;
+	return;
+    }
+
+    row = check_row(row);
+    col = check_col(col);
+#ifdef FEAT_MBYTE
+    col = mb_fix_col(col, row);
+#endif
+
+    if (col == (int)cb->prev.col && row == cb->prev.lnum && !repeated_click)
+	return;
+
+    /*
+     * When extending the selection with the right mouse button, swap the
+     * start and end if the position is before half the selection
+     */
+    if (cb->state == SELECT_DONE && button == MOUSE_RIGHT)
+    {
+	/*
+	 * If the click is before the start, or the click is inside the
+	 * selection and the start is the closest side, set the origin to the
+	 * end of the selection.
+	 */
+	if (clip_compare_pos(row, col, (int)cb->start.lnum, cb->start.col) < 0
+		|| (clip_compare_pos(row, col,
+					   (int)cb->end.lnum, cb->end.col) < 0
+		    && (((cb->start.lnum == cb->end.lnum
+			    && cb->end.col - col > col - cb->start.col))
+			|| ((diff = (cb->end.lnum - row) -
+						   (row - cb->start.lnum)) > 0
+			    || (diff == 0 && col < (int)(cb->start.col +
+							 cb->end.col) / 2)))))
+	{
+	    cb->origin_row = (short_u)cb->end.lnum;
+	    cb->origin_start_col = cb->end.col - 1;
+	    cb->origin_end_col = cb->end.col;
+	}
+	else
+	{
+	    cb->origin_row = (short_u)cb->start.lnum;
+	    cb->origin_start_col = cb->start.col;
+	    cb->origin_end_col = cb->start.col;
+	}
+	if (cb->mode == SELECT_MODE_WORD && !repeated_click)
+	    cb->mode = SELECT_MODE_CHAR;
+    }
+
+    /* set state, for when using the right mouse button */
+    cb->state = SELECT_IN_PROGRESS;
+
+#ifdef DEBUG_SELECTION
+    printf("Selection extending to (%d,%d)\n", row, col);
+#endif
+
+    if (repeated_click && ++cb->mode > SELECT_MODE_LINE)
+	cb->mode = SELECT_MODE_CHAR;
+
+    switch (cb->mode)
+    {
+	case SELECT_MODE_CHAR:
+	    /* If we're on a different line, find where the line ends */
+	    if (row != cb->prev.lnum)
+		cb->word_end_col = clip_get_line_end(row);
+
+	    /* See if we are before or after the origin of the selection */
+	    if (clip_compare_pos(row, col, cb->origin_row,
+						   cb->origin_start_col) >= 0)
+	    {
+		if (col >= (int)cb->word_end_col)
+		    clip_update_modeless_selection(cb, cb->origin_row,
+			    cb->origin_start_col, row, (int)Columns);
+		else
+		{
+#ifdef FEAT_MBYTE
+		    if (has_mbyte && mb_lefthalve(row, col))
+			slen = 2;
+#endif
+		    clip_update_modeless_selection(cb, cb->origin_row,
+			    cb->origin_start_col, row, col + slen);
+		}
+	    }
+	    else
+	    {
+#ifdef FEAT_MBYTE
+		if (has_mbyte
+			&& mb_lefthalve(cb->origin_row, cb->origin_start_col))
+		    slen = 2;
+#endif
+		if (col >= (int)cb->word_end_col)
+		    clip_update_modeless_selection(cb, row, cb->word_end_col,
+			    cb->origin_row, cb->origin_start_col + slen);
+		else
+		    clip_update_modeless_selection(cb, row, col,
+			    cb->origin_row, cb->origin_start_col + slen);
+	    }
+	    break;
+
+	case SELECT_MODE_WORD:
+	    /* If we are still within the same word, do nothing */
+	    if (row == cb->prev.lnum && col >= (int)cb->word_start_col
+		    && col < (int)cb->word_end_col && !repeated_click)
+		return;
+
+	    /* Get new word boundaries */
+	    clip_get_word_boundaries(cb, row, col);
+
+	    /* Handle being after the origin point of selection */
+	    if (clip_compare_pos(row, col, cb->origin_row,
+		    cb->origin_start_col) >= 0)
+		clip_update_modeless_selection(cb, cb->origin_row,
+			cb->origin_start_col, row, cb->word_end_col);
+	    else
+		clip_update_modeless_selection(cb, row, cb->word_start_col,
+			cb->origin_row, cb->origin_end_col);
+	    break;
+
+	case SELECT_MODE_LINE:
+	    if (row == cb->prev.lnum && !repeated_click)
+		return;
+
+	    if (clip_compare_pos(row, col, cb->origin_row,
+		    cb->origin_start_col) >= 0)
+		clip_update_modeless_selection(cb, cb->origin_row, 0, row,
+			(int)Columns);
+	    else
+		clip_update_modeless_selection(cb, row, 0, cb->origin_row,
+			(int)Columns);
+	    break;
+    }
+
+    cb->prev.lnum = row;
+    cb->prev.col  = col;
+
+#ifdef DEBUG_SELECTION
+	printf("Selection is: (%u,%u) to (%u,%u)\n", cb->start.lnum,
+		cb->start.col, cb->end.lnum, cb->end.col);
+#endif
+}
+
+#if 0 /* not used */
+/*
+ * Called after an Expose event to redraw the selection
+ */
+    void
+clip_redraw_selection(x, y, w, h)
+    int	    x;
+    int	    y;
+    int	    w;
+    int	    h;
+{
+    VimClipboard    *cb = &clip_star;
+    int		    row1, col1, row2, col2;
+    int		    row;
+    int		    start;
+    int		    end;
+
+    if (cb->state == SELECT_CLEARED)
+	return;
+
+    row1 = check_row(Y_2_ROW(y));
+    col1 = check_col(X_2_COL(x));
+    row2 = check_row(Y_2_ROW(y + h - 1));
+    col2 = check_col(X_2_COL(x + w - 1));
+
+    /* Limit the rows that need to be re-drawn */
+    if (cb->start.lnum > row1)
+	row1 = cb->start.lnum;
+    if (cb->end.lnum < row2)
+	row2 = cb->end.lnum;
+
+    /* Look at each row that might need to be re-drawn */
+    for (row = row1; row <= row2; row++)
+    {
+	/* For the first selection row, use the starting selection column */
+	if (row == cb->start.lnum)
+	    start = cb->start.col;
+	else
+	    start = 0;
+
+	/* For the last selection row, use the ending selection column */
+	if (row == cb->end.lnum)
+	    end = cb->end.col;
+	else
+	    end = Columns;
+
+	if (col1 > start)
+	    start = col1;
+
+	if (col2 < end)
+	    end = col2 + 1;
+
+	if (end > start)
+	    gui_mch_invert_rectangle(row, start, 1, end - start);
+    }
+}
+#endif
+
+# if defined(FEAT_GUI) || defined(PROTO)
+/*
+ * Redraw part of the selection if character at "row,col" is inside of it.
+ * Only used for the GUI.
+ */
+    void
+clip_may_redraw_selection(row, col, len)
+    int		row, col;
+    int		len;
+{
+    int		start = col;
+    int		end = col + len;
+
+    if (clip_star.state != SELECT_CLEARED
+	    && row >= clip_star.start.lnum
+	    && row <= clip_star.end.lnum)
+    {
+	if (row == clip_star.start.lnum && start < (int)clip_star.start.col)
+	    start = clip_star.start.col;
+	if (row == clip_star.end.lnum && end > (int)clip_star.end.col)
+	    end = clip_star.end.col;
+	if (end > start)
+	    clip_invert_area(row, start, row, end, 0);
+    }
+}
+# endif
+
+/*
+ * Called from outside to clear selected region from the display
+ */
+    void
+clip_clear_selection()
+{
+    VimClipboard    *cb = &clip_star;
+
+    if (cb->state == SELECT_CLEARED)
+	return;
+
+    clip_invert_area((int)cb->start.lnum, cb->start.col, (int)cb->end.lnum,
+						     cb->end.col, CLIP_CLEAR);
+    cb->state = SELECT_CLEARED;
+}
+
+/*
+ * Clear the selection if any lines from "row1" to "row2" are inside of it.
+ */
+    void
+clip_may_clear_selection(row1, row2)
+    int	row1, row2;
+{
+    if (clip_star.state == SELECT_DONE
+	    && row2 >= clip_star.start.lnum
+	    && row1 <= clip_star.end.lnum)
+	clip_clear_selection();
+}
+
+/*
+ * Called before the screen is scrolled up or down.  Adjusts the line numbers
+ * of the selection.  Call with big number when clearing the screen.
+ */
+    void
+clip_scroll_selection(rows)
+    int	    rows;		/* negative for scroll down */
+{
+    int	    lnum;
+
+    if (clip_star.state == SELECT_CLEARED)
+	return;
+
+    lnum = clip_star.start.lnum - rows;
+    if (lnum <= 0)
+	clip_star.start.lnum = 0;
+    else if (lnum >= screen_Rows)	/* scrolled off of the screen */
+	clip_star.state = SELECT_CLEARED;
+    else
+	clip_star.start.lnum = lnum;
+
+    lnum = clip_star.end.lnum - rows;
+    if (lnum < 0)			/* scrolled off of the screen */
+	clip_star.state = SELECT_CLEARED;
+    else if (lnum >= screen_Rows)
+	clip_star.end.lnum = screen_Rows - 1;
+    else
+	clip_star.end.lnum = lnum;
+}
+
+/*
+ * Invert a region of the display between a starting and ending row and column
+ * Values for "how":
+ * CLIP_CLEAR:  undo inversion
+ * CLIP_SET:    set inversion
+ * CLIP_TOGGLE: set inversion if pos1 < pos2, undo inversion otherwise.
+ * 0: invert (GUI only).
+ */
+    static void
+clip_invert_area(row1, col1, row2, col2, how)
+    int		row1;
+    int		col1;
+    int		row2;
+    int		col2;
+    int		how;
+{
+    int		invert = FALSE;
+
+    if (how == CLIP_SET)
+	invert = TRUE;
+
+    /* Swap the from and to positions so the from is always before */
+    if (clip_compare_pos(row1, col1, row2, col2) > 0)
+    {
+	int tmp_row, tmp_col;
+
+	tmp_row = row1;
+	tmp_col = col1;
+	row1	= row2;
+	col1	= col2;
+	row2	= tmp_row;
+	col2	= tmp_col;
+    }
+    else if (how == CLIP_TOGGLE)
+	invert = TRUE;
+
+    /* If all on the same line, do it the easy way */
+    if (row1 == row2)
+    {
+	clip_invert_rectangle(row1, col1, 1, col2 - col1, invert);
+    }
+    else
+    {
+	/* Handle a piece of the first line */
+	if (col1 > 0)
+	{
+	    clip_invert_rectangle(row1, col1, 1, (int)Columns - col1, invert);
+	    row1++;
+	}
+
+	/* Handle a piece of the last line */
+	if (col2 < Columns - 1)
+	{
+	    clip_invert_rectangle(row2, 0, 1, col2, invert);
+	    row2--;
+	}
+
+	/* Handle the rectangle thats left */
+	if (row2 >= row1)
+	    clip_invert_rectangle(row1, 0, row2 - row1 + 1, (int)Columns,
+								      invert);
+    }
+}
+
+/*
+ * Invert or un-invert a rectangle of the screen.
+ * "invert" is true if the result is inverted.
+ */
+    static void
+clip_invert_rectangle(row, col, height, width, invert)
+    int		row;
+    int		col;
+    int		height;
+    int		width;
+    int		invert;
+{
+#ifdef FEAT_GUI
+    if (gui.in_use)
+	gui_mch_invert_rectangle(row, col, height, width);
+    else
+#endif
+	screen_draw_rectangle(row, col, height, width, invert);
+}
+
+/*
+ * Copy the currently selected area into the '*' register so it will be
+ * available for pasting.
+ * When "both" is TRUE also copy to the '+' register.
+ */
+/*ARGSUSED*/
+    void
+clip_copy_modeless_selection(both)
+    int		both;
+{
+    char_u	*buffer;
+    char_u	*bufp;
+    int		row;
+    int		start_col;
+    int		end_col;
+    int		line_end_col;
+    int		add_newline_flag = FALSE;
+    int		len;
+#ifdef FEAT_MBYTE
+    char_u	*p;
+#endif
+    int		row1 = clip_star.start.lnum;
+    int		col1 = clip_star.start.col;
+    int		row2 = clip_star.end.lnum;
+    int		col2 = clip_star.end.col;
+
+    /* Can't use ScreenLines unless initialized */
+    if (ScreenLines == NULL)
+	return;
+
+    /*
+     * Make sure row1 <= row2, and if row1 == row2 that col1 <= col2.
+     */
+    if (row1 > row2)
+    {
+	row = row1; row1 = row2; row2 = row;
+	row = col1; col1 = col2; col2 = row;
+    }
+    else if (row1 == row2 && col1 > col2)
+    {
+	row = col1; col1 = col2; col2 = row;
+    }
+#ifdef FEAT_MBYTE
+    /* correct starting point for being on right halve of double-wide char */
+    p = ScreenLines + LineOffset[row1];
+    if (enc_dbcs != 0)
+	col1 -= (*mb_head_off)(p, p + col1);
+    else if (enc_utf8 && p[col1] == 0)
+	--col1;
+#endif
+
+    /* Create a temporary buffer for storing the text */
+    len = (row2 - row1 + 1) * Columns + 1;
+#ifdef FEAT_MBYTE
+    if (enc_dbcs != 0)
+	len *= 2;	/* max. 2 bytes per display cell */
+    else if (enc_utf8)
+	len *= MB_MAXBYTES;
+#endif
+    buffer = lalloc((long_u)len, TRUE);
+    if (buffer == NULL)	    /* out of memory */
+	return;
+
+    /* Process each row in the selection */
+    for (bufp = buffer, row = row1; row <= row2; row++)
+    {
+	if (row == row1)
+	    start_col = col1;
+	else
+	    start_col = 0;
+
+	if (row == row2)
+	    end_col = col2;
+	else
+	    end_col = Columns;
+
+	line_end_col = clip_get_line_end(row);
+
+	/* See if we need to nuke some trailing whitespace */
+	if (end_col >= Columns && (row < row2 || end_col > line_end_col))
+	{
+	    /* Get rid of trailing whitespace */
+	    end_col = line_end_col;
+	    if (end_col < start_col)
+		end_col = start_col;
+
+	    /* If the last line extended to the end, add an extra newline */
+	    if (row == row2)
+		add_newline_flag = TRUE;
+	}
+
+	/* If after the first row, we need to always add a newline */
+	if (row > row1 && !LineWraps[row - 1])
+	    *bufp++ = NL;
+
+	if (row < screen_Rows && end_col <= screen_Columns)
+	{
+#ifdef FEAT_MBYTE
+	    if (enc_dbcs != 0)
+	    {
+		int	i;
+
+		p = ScreenLines + LineOffset[row];
+		for (i = start_col; i < end_col; ++i)
+		    if (enc_dbcs == DBCS_JPNU && p[i] == 0x8e)
+		    {
+			/* single-width double-byte char */
+			*bufp++ = 0x8e;
+			*bufp++ = ScreenLines2[LineOffset[row] + i];
+		    }
+		    else
+		    {
+			*bufp++ = p[i];
+			if (MB_BYTE2LEN(p[i]) == 2)
+			    *bufp++ = p[++i];
+		    }
+	    }
+	    else if (enc_utf8)
+	    {
+		int	off;
+		int	i;
+		int	ci;
+
+		off = LineOffset[row];
+		for (i = start_col; i < end_col; ++i)
+		{
+		    /* The base character is either in ScreenLinesUC[] or
+		     * ScreenLines[]. */
+		    if (ScreenLinesUC[off + i] == 0)
+			*bufp++ = ScreenLines[off + i];
+		    else
+		    {
+			bufp += utf_char2bytes(ScreenLinesUC[off + i], bufp);
+			for (ci = 0; ci < Screen_mco; ++ci)
+			{
+			    /* Add a composing character. */
+			    if (ScreenLinesC[ci][off + i] == 0)
+				break;
+			    bufp += utf_char2bytes(ScreenLinesC[ci][off + i],
+									bufp);
+			}
+		    }
+		    /* Skip right halve of double-wide character. */
+		    if (ScreenLines[off + i + 1] == 0)
+			++i;
+		}
+	    }
+	    else
+#endif
+	    {
+		STRNCPY(bufp, ScreenLines + LineOffset[row] + start_col,
+							 end_col - start_col);
+		bufp += end_col - start_col;
+	    }
+	}
+    }
+
+    /* Add a newline at the end if the selection ended there */
+    if (add_newline_flag)
+	*bufp++ = NL;
+
+    /* First cleanup any old selection and become the owner. */
+    clip_free_selection(&clip_star);
+    clip_own_selection(&clip_star);
+
+    /* Yank the text into the '*' register. */
+    clip_yank_selection(MCHAR, buffer, (long)(bufp - buffer), &clip_star);
+
+    /* Make the register contents available to the outside world. */
+    clip_gen_set_selection(&clip_star);
+
+#ifdef FEAT_X11
+    if (both)
+    {
+	/* Do the same for the '+' register. */
+	clip_free_selection(&clip_plus);
+	clip_own_selection(&clip_plus);
+	clip_yank_selection(MCHAR, buffer, (long)(bufp - buffer), &clip_plus);
+	clip_gen_set_selection(&clip_plus);
+    }
+#endif
+    vim_free(buffer);
+}
+
+/*
+ * Find the starting and ending positions of the word at the given row and
+ * column.  Only white-separated words are recognized here.
+ */
+#define CHAR_CLASS(c)	(c <= ' ' ? ' ' : vim_iswordc(c))
+
+    static void
+clip_get_word_boundaries(cb, row, col)
+    VimClipboard	*cb;
+    int			row;
+    int			col;
+{
+    int		start_class;
+    int		temp_col;
+    char_u	*p;
+#ifdef FEAT_MBYTE
+    int		mboff;
+#endif
+
+    if (row >= screen_Rows || col >= screen_Columns || ScreenLines == NULL)
+	return;
+
+    p = ScreenLines + LineOffset[row];
+#ifdef FEAT_MBYTE
+    /* Correct for starting in the right halve of a double-wide char */
+    if (enc_dbcs != 0)
+	col -= dbcs_screen_head_off(p, p + col);
+    else if (enc_utf8 && p[col] == 0)
+	--col;
+#endif
+    start_class = CHAR_CLASS(p[col]);
+
+    temp_col = col;
+    for ( ; temp_col > 0; temp_col--)
+#ifdef FEAT_MBYTE
+	if (enc_dbcs != 0
+		   && (mboff = dbcs_screen_head_off(p, p + temp_col - 1)) > 0)
+	    temp_col -= mboff;
+	else
+#endif
+	if (CHAR_CLASS(p[temp_col - 1]) != start_class
+#ifdef FEAT_MBYTE
+		&& !(enc_utf8 && p[temp_col - 1] == 0)
+#endif
+		)
+	    break;
+    cb->word_start_col = temp_col;
+
+    temp_col = col;
+    for ( ; temp_col < screen_Columns; temp_col++)
+#ifdef FEAT_MBYTE
+	if (enc_dbcs != 0 && dbcs_ptr2cells(p + temp_col) == 2)
+	    ++temp_col;
+	else
+#endif
+	if (CHAR_CLASS(p[temp_col]) != start_class
+#ifdef FEAT_MBYTE
+		&& !(enc_utf8 && p[temp_col] == 0)
+#endif
+		)
+	    break;
+    cb->word_end_col = temp_col;
+}
+
+/*
+ * Find the column position for the last non-whitespace character on the given
+ * line.
+ */
+    static int
+clip_get_line_end(row)
+    int		row;
+{
+    int	    i;
+
+    if (row >= screen_Rows || ScreenLines == NULL)
+	return 0;
+    for (i = screen_Columns; i > 0; i--)
+	if (ScreenLines[LineOffset[row] + i - 1] != ' ')
+	    break;
+    return i;
+}
+
+/*
+ * Update the currently selected region by adding and/or subtracting from the
+ * beginning or end and inverting the changed area(s).
+ */
+    static void
+clip_update_modeless_selection(cb, row1, col1, row2, col2)
+    VimClipboard    *cb;
+    int		    row1;
+    int		    col1;
+    int		    row2;
+    int		    col2;
+{
+    /* See if we changed at the beginning of the selection */
+    if (row1 != cb->start.lnum || col1 != (int)cb->start.col)
+    {
+	clip_invert_area(row1, col1, (int)cb->start.lnum, cb->start.col,
+								 CLIP_TOGGLE);
+	cb->start.lnum = row1;
+	cb->start.col  = col1;
+    }
+
+    /* See if we changed at the end of the selection */
+    if (row2 != cb->end.lnum || col2 != (int)cb->end.col)
+    {
+	clip_invert_area((int)cb->end.lnum, cb->end.col, row2, col2,
+								 CLIP_TOGGLE);
+	cb->end.lnum = row2;
+	cb->end.col  = col2;
+    }
+}
+
+    int
+clip_gen_own_selection(cbd)
+    VimClipboard	*cbd;
+{
+#ifdef FEAT_XCLIPBOARD
+# ifdef FEAT_GUI
+    if (gui.in_use)
+	return clip_mch_own_selection(cbd);
+    else
+# endif
+	return clip_xterm_own_selection(cbd);
+#else
+    return clip_mch_own_selection(cbd);
+#endif
+}
+
+    void
+clip_gen_lose_selection(cbd)
+    VimClipboard	*cbd;
+{
+#ifdef FEAT_XCLIPBOARD
+# ifdef FEAT_GUI
+    if (gui.in_use)
+	clip_mch_lose_selection(cbd);
+    else
+# endif
+	clip_xterm_lose_selection(cbd);
+#else
+    clip_mch_lose_selection(cbd);
+#endif
+}
+
+    void
+clip_gen_set_selection(cbd)
+    VimClipboard	*cbd;
+{
+#ifdef FEAT_XCLIPBOARD
+# ifdef FEAT_GUI
+    if (gui.in_use)
+	clip_mch_set_selection(cbd);
+    else
+# endif
+	clip_xterm_set_selection(cbd);
+#else
+    clip_mch_set_selection(cbd);
+#endif
+}
+
+    void
+clip_gen_request_selection(cbd)
+    VimClipboard	*cbd;
+{
+#ifdef FEAT_XCLIPBOARD
+# ifdef FEAT_GUI
+    if (gui.in_use)
+	clip_mch_request_selection(cbd);
+    else
+# endif
+	clip_xterm_request_selection(cbd);
+#else
+    clip_mch_request_selection(cbd);
+#endif
+}
+
+#endif /* FEAT_CLIPBOARD */
+
+/*****************************************************************************
+ * Functions that handle the input buffer.
+ * This is used for any GUI version, and the unix terminal version.
+ *
+ * For Unix, the input characters are buffered to be able to check for a
+ * CTRL-C.  This should be done with signals, but I don't know how to do that
+ * in a portable way for a tty in RAW mode.
+ *
+ * For the client-server code in the console the received keys are put in the
+ * input buffer.
+ */
+
+#if defined(USE_INPUT_BUF) || defined(PROTO)
+
+/*
+ * Internal typeahead buffer.  Includes extra space for long key code
+ * descriptions which would otherwise overflow.  The buffer is considered full
+ * when only this extra space (or part of it) remains.
+ */
+#if defined(FEAT_SUN_WORKSHOP) || defined(FEAT_NETBEANS_INTG) \
+	|| defined(FEAT_CLIENTSERVER)
+   /*
+    * Sun WorkShop and NetBeans stuff debugger commands into the input buffer.
+    * This requires a larger buffer...
+    * (Madsen) Go with this for remote input as well ...
+    */
+# define INBUFLEN 4096
+#else
+# define INBUFLEN 250
+#endif
+
+static char_u	inbuf[INBUFLEN + MAX_KEY_CODE_LEN];
+static int	inbufcount = 0;	    /* number of chars in inbuf[] */
+
+/*
+ * vim_is_input_buf_full(), vim_is_input_buf_empty(), add_to_input_buf(), and
+ * trash_input_buf() are functions for manipulating the input buffer.  These
+ * are used by the gui_* calls when a GUI is used to handle keyboard input.
+ */
+
+    int
+vim_is_input_buf_full()
+{
+    return (inbufcount >= INBUFLEN);
+}
+
+    int
+vim_is_input_buf_empty()
+{
+    return (inbufcount == 0);
+}
+
+#if defined(FEAT_OLE) || defined(PROTO)
+    int
+vim_free_in_input_buf()
+{
+    return (INBUFLEN - inbufcount);
+}
+#endif
+
+#if defined(FEAT_GUI_GTK) || defined(PROTO)
+    int
+vim_used_in_input_buf()
+{
+    return inbufcount;
+}
+#endif
+
+#if defined(FEAT_EVAL) || defined(FEAT_EX_EXTRA) || defined(PROTO)
+/*
+ * Return the current contents of the input buffer and make it empty.
+ * The returned pointer must be passed to set_input_buf() later.
+ */
+    char_u *
+get_input_buf()
+{
+    garray_T	*gap;
+
+    /* We use a growarray to store the data pointer and the length. */
+    gap = (garray_T *)alloc((unsigned)sizeof(garray_T));
+    if (gap != NULL)
+    {
+	/* Add one to avoid a zero size. */
+	gap->ga_data = alloc((unsigned)inbufcount + 1);
+	if (gap->ga_data != NULL)
+	    mch_memmove(gap->ga_data, inbuf, (size_t)inbufcount);
+	gap->ga_len = inbufcount;
+    }
+    trash_input_buf();
+    return (char_u *)gap;
+}
+
+/*
+ * Restore the input buffer with a pointer returned from get_input_buf().
+ * The allocated memory is freed, this only works once!
+ */
+    void
+set_input_buf(p)
+    char_u	*p;
+{
+    garray_T	*gap = (garray_T *)p;
+
+    if (gap != NULL)
+    {
+	if (gap->ga_data != NULL)
+	{
+	    mch_memmove(inbuf, gap->ga_data, gap->ga_len);
+	    inbufcount = gap->ga_len;
+	    vim_free(gap->ga_data);
+	}
+	vim_free(gap);
+    }
+}
+#endif
+
+#if defined(FEAT_GUI) || defined(FEAT_MOUSE_GPM) \
+	|| defined(FEAT_XCLIPBOARD) || defined(VMS) \
+	|| defined(FEAT_SNIFF) || defined(FEAT_CLIENTSERVER) \
+	|| (defined(FEAT_GUI) && (!defined(USE_ON_FLY_SCROLL) \
+		|| defined(FEAT_MENU))) \
+	|| defined(PLAN9) || defined(PROTO)
+/*
+ * Add the given bytes to the input buffer
+ * Special keys start with CSI.  A real CSI must have been translated to
+ * CSI KS_EXTRA KE_CSI.  K_SPECIAL doesn't require translation.
+ */
+    void
+add_to_input_buf(s, len)
+    char_u  *s;
+    int	    len;
+{
+    if (inbufcount + len > INBUFLEN + MAX_KEY_CODE_LEN)
+	return;	    /* Shouldn't ever happen! */
+
+#ifdef FEAT_HANGULIN
+    if ((State & (INSERT|CMDLINE)) && hangul_input_state_get())
+	if ((len = hangul_input_process(s, len)) == 0)
+	    return;
+#endif
+
+    while (len--)
+	inbuf[inbufcount++] = *s++;
+}
+#endif
+
+#if (defined(FEAT_XIM) && defined(FEAT_GUI_GTK)) \
+	|| (defined(FEAT_MBYTE) && defined(FEAT_MBYTE_IME)) \
+	|| (defined(FEAT_GUI) && (!defined(USE_ON_FLY_SCROLL) \
+		|| defined(FEAT_MENU))) \
+	|| defined(PLAN9) \
+	|| defined(PROTO)
+/*
+ * Add "str[len]" to the input buffer while escaping CSI bytes.
+ */
+    void
+add_to_input_buf_csi(char_u *str, int len)
+{
+    int		i;
+    char_u	buf[2];
+
+    for (i = 0; i < len; ++i)
+    {
+	add_to_input_buf(str + i, 1);
+	if (str[i] == CSI)
+	{
+	    /* Turn CSI into K_CSI. */
+	    buf[0] = KS_EXTRA;
+	    buf[1] = (int)KE_CSI;
+	    add_to_input_buf(buf, 2);
+	}
+    }
+}
+#endif
+
+#if defined(FEAT_HANGULIN) || defined(PROTO)
+    void
+push_raw_key (s, len)
+    char_u  *s;
+    int	    len;
+{
+    while (len--)
+	inbuf[inbufcount++] = *s++;
+}
+#endif
+
+#if defined(FEAT_GUI) || defined(FEAT_EVAL) || defined(FEAT_EX_EXTRA) \
+	|| defined(PROTO)
+/* Remove everything from the input buffer.  Called when ^C is found */
+    void
+trash_input_buf()
+{
+    inbufcount = 0;
+}
+#endif
+
+/*
+ * Read as much data from the input buffer as possible up to maxlen, and store
+ * it in buf.
+ * Note: this function used to be Read() in unix.c
+ */
+    int
+read_from_input_buf(buf, maxlen)
+    char_u  *buf;
+    long    maxlen;
+{
+    if (inbufcount == 0)	/* if the buffer is empty, fill it */
+	fill_input_buf(TRUE);
+    if (maxlen > inbufcount)
+	maxlen = inbufcount;
+    mch_memmove(buf, inbuf, (size_t)maxlen);
+    inbufcount -= maxlen;
+    if (inbufcount)
+	mch_memmove(inbuf, inbuf + maxlen, (size_t)inbufcount);
+    return (int)maxlen;
+}
+
+/*ARGSUSED*/
+    void
+fill_input_buf(exit_on_error)
+    int	exit_on_error;
+{
+#if defined(UNIX) || defined(OS2) || defined(VMS) || \
+	defined(MACOS_X_UNIX) || defined(PLAN9)
+    int		len;
+    int		try;
+    static int	did_read_something = FALSE;
+# ifdef FEAT_MBYTE
+    static char_u *rest = NULL;	    /* unconverted rest of previous read */
+    static int	restlen = 0;
+    int		unconverted;
+# endif
+#endif
+
+#ifdef FEAT_GUI
+    if (gui.in_use
+# ifdef NO_CONSOLE_INPUT
+    /* Don't use the GUI input when the window hasn't been opened yet.
+     * We get here from ui_inchar() when we should try reading from stdin. */
+	    && !no_console_input()
+# endif
+       )
+    {
+	gui_mch_update();
+	return;
+    }
+#endif
+#if defined(UNIX) || defined(OS2) || defined(VMS) || \
+    defined(MACOS_X_UNIX) || defined(PLAN9)
+    if (vim_is_input_buf_full())
+	return;
+    /*
+     * Fill_input_buf() is only called when we really need a character.
+     * If we can't get any, but there is some in the buffer, just return.
+     * If we can't get any, and there isn't any in the buffer, we give up and
+     * exit Vim.
+     */
+# if defined(__BEOS__) || defined(PLAN9)
+    /*
+     * On the BeBox version (for now) and on Plan 9, all input is secretly
+     * performed in RealWaitForChar().  On BeOS, this happens in beos_select().
+     */
+    while (!vim_is_input_buf_full() && RealWaitForChar(read_cmd_fd, 0, NULL))
+	    ;
+    len = inbufcount;
+    inbufcount = 0;
+# else
+
+#  ifdef FEAT_SNIFF
+    if (sniff_request_waiting)
+    {
+	add_to_input_buf((char_u *)"\233sniff",6); /* results in K_SNIFF */
+	sniff_request_waiting = 0;
+	want_sniff_request = 0;
+	return;
+    }
+#  endif
+
+# ifdef FEAT_MBYTE
+    if (rest != NULL)
+    {
+	/* Use remainder of previous call, starts with an invalid character
+	 * that may become valid when reading more. */
+	if (restlen > INBUFLEN - inbufcount)
+	    unconverted = INBUFLEN - inbufcount;
+	else
+	    unconverted = restlen;
+	mch_memmove(inbuf + inbufcount, rest, unconverted);
+	if (unconverted == restlen)
+	{
+	    vim_free(rest);
+	    rest = NULL;
+	}
+	else
+	{
+	    restlen -= unconverted;
+	    mch_memmove(rest, rest + unconverted, restlen);
+	}
+	inbufcount += unconverted;
+    }
+    else
+	unconverted = 0;
+#endif
+
+    len = 0;	/* to avoid gcc warning */
+    for (try = 0; try < 100; ++try)
+    {
+#  ifdef VMS
+	len = vms_read(
+#  else
+	len = read(read_cmd_fd,
+#  endif
+	    (char *)inbuf + inbufcount, (size_t)((INBUFLEN - inbufcount)
+#  ifdef FEAT_MBYTE
+		/ input_conv.vc_factor
+#  endif
+		));
+#  if 0
+		)	/* avoid syntax highlight error */
+#  endif
+
+	if (len > 0 || got_int)
+	    break;
+	/*
+	 * If reading stdin results in an error, continue reading stderr.
+	 * This helps when using "foo | xargs vim".
+	 */
+	if (!did_read_something && !isatty(read_cmd_fd) && read_cmd_fd == 0)
+	{
+	    int m = cur_tmode;
+
+	    /* We probably set the wrong file descriptor to raw mode.  Switch
+	     * back to cooked mode, use another descriptor and set the mode to
+	     * what it was. */
+	    settmode(TMODE_COOK);
+#ifdef HAVE_DUP
+	    /* Use stderr for stdin, also works for shell commands. */
+	    close(0);
+	    dup(2);
+#else
+	    read_cmd_fd = 2;	/* read from stderr instead of stdin */
+#endif
+	    settmode(m);
+	}
+	if (!exit_on_error)
+	    return;
+    }
+# endif
+    if (len <= 0 && !got_int)
+	read_error_exit();
+    if (len > 0)
+	did_read_something = TRUE;
+    if (got_int)
+    {
+	/* Interrupted, pretend a CTRL-C was typed. */
+	inbuf[0] = 3;
+	inbufcount = 1;
+    }
+    else
+    {
+# ifdef FEAT_MBYTE
+	/*
+	 * May perform conversion on the input characters.
+	 * Include the unconverted rest of the previous call.
+	 * If there is an incomplete char at the end it is kept for the next
+	 * time, reading more bytes should make conversion possible.
+	 * Don't do this in the unlikely event that the input buffer is too
+	 * small ("rest" still contains more bytes).
+	 */
+	if (input_conv.vc_type != CONV_NONE)
+	{
+	    inbufcount -= unconverted;
+	    len = convert_input_safe(inbuf + inbufcount,
+				     len + unconverted, INBUFLEN - inbufcount,
+				       rest == NULL ? &rest : NULL, &restlen);
+	}
+# endif
+	while (len-- > 0)
+	{
+	    /*
+	     * if a CTRL-C was typed, remove it from the buffer and set got_int
+	     */
+	    if (inbuf[inbufcount] == 3 && ctrl_c_interrupts)
+	    {
+		/* remove everything typed before the CTRL-C */
+		mch_memmove(inbuf, inbuf + inbufcount, (size_t)(len + 1));
+		inbufcount = 0;
+		got_int = TRUE;
+	    }
+	    ++inbufcount;
+	}
+    }
+#endif /* UNIX or OS2 or VMS*/
+}
+#endif /* defined(UNIX) || defined(FEAT_GUI) || defined(OS2)  || defined(VMS) */
+
+/*
+ * Exit because of an input read error.
+ */
+    void
+read_error_exit()
+{
+    if (silent_mode)	/* Normal way to exit for "ex -s" */
+	getout(0);
+    STRCPY(IObuff, _("Vim: Error reading input, exiting...\n"));
+    preserve_exit();
+}
+
+#if defined(CURSOR_SHAPE) || defined(PROTO)
+/*
+ * May update the shape of the cursor.
+ */
+    void
+ui_cursor_shape()
+{
+# ifdef FEAT_GUI
+    if (gui.in_use)
+	gui_update_cursor_later();
+    else
+# endif
+	term_cursor_shape();
+
+# ifdef MCH_CURSOR_SHAPE
+    mch_update_cursor();
+# endif
+}
+#endif
+
+#if defined(FEAT_CLIPBOARD) || defined(FEAT_GUI) || defined(FEAT_RIGHTLEFT) \
+	|| defined(PROTO)
+/*
+ * Check bounds for column number
+ */
+    int
+check_col(col)
+    int	    col;
+{
+    if (col < 0)
+	return 0;
+    if (col >= (int)screen_Columns)
+	return (int)screen_Columns - 1;
+    return col;
+}
+
+/*
+ * Check bounds for row number
+ */
+    int
+check_row(row)
+    int	    row;
+{
+    if (row < 0)
+	return 0;
+    if (row >= (int)screen_Rows)
+	return (int)screen_Rows - 1;
+    return row;
+}
+#endif
+
+/*
+ * Stuff for the X clipboard.  Shared between VMS and Unix.
+ */
+
+#if defined(FEAT_XCLIPBOARD) || defined(FEAT_GUI_X11) || defined(PROTO)
+# include <X11/Xatom.h>
+# include <X11/Intrinsic.h>
+
+/*
+ * Open the application context (if it hasn't been opened yet).
+ * Used for Motif and Athena GUI and the xterm clipboard.
+ */
+    void
+open_app_context()
+{
+    if (app_context == NULL)
+    {
+	XtToolkitInitialize();
+	app_context = XtCreateApplicationContext();
+    }
+}
+
+static Atom	vim_atom;	/* Vim's own special selection format */
+#ifdef FEAT_MBYTE
+static Atom	vimenc_atom;	/* Vim's extended selection format */
+#endif
+static Atom	compound_text_atom;
+static Atom	text_atom;
+static Atom	targets_atom;
+
+    void
+x11_setup_atoms(dpy)
+    Display	*dpy;
+{
+    vim_atom	       = XInternAtom(dpy, VIM_ATOM_NAME,   False);
+#ifdef FEAT_MBYTE
+    vimenc_atom	       = XInternAtom(dpy, VIMENC_ATOM_NAME,False);
+#endif
+    compound_text_atom = XInternAtom(dpy, "COMPOUND_TEXT", False);
+    text_atom	       = XInternAtom(dpy, "TEXT",	   False);
+    targets_atom       = XInternAtom(dpy, "TARGETS",       False);
+    clip_star.sel_atom = XA_PRIMARY;
+    clip_plus.sel_atom = XInternAtom(dpy, "CLIPBOARD",     False);
+}
+
+/*
+ * X Selection stuff, for cutting and pasting text to other windows.
+ */
+
+static void  clip_x11_request_selection_cb __ARGS((Widget, XtPointer, Atom *, Atom *, XtPointer, long_u *, int *));
+
+/* ARGSUSED */
+    static void
+clip_x11_request_selection_cb(w, success, sel_atom, type, value, length,
+			      format)
+    Widget	w;
+    XtPointer	success;
+    Atom	*sel_atom;
+    Atom	*type;
+    XtPointer	value;
+    long_u	*length;
+    int		*format;
+{
+    int		motion_type;
+    long_u	len;
+    char_u	*p;
+    char	**text_list = NULL;
+    VimClipboard	*cbd;
+#ifdef FEAT_MBYTE
+    char_u	*tmpbuf = NULL;
+#endif
+
+    if (*sel_atom == clip_plus.sel_atom)
+	cbd = &clip_plus;
+    else
+	cbd = &clip_star;
+
+    if (value == NULL || *length == 0)
+    {
+	clip_free_selection(cbd);	/* ???  [what's the query?] */
+	*(int *)success = FALSE;
+	return;
+    }
+    motion_type = MCHAR;
+    p = (char_u *)value;
+    len = *length;
+    if (*type == vim_atom)
+    {
+	motion_type = *p++;
+	len--;
+    }
+
+#ifdef FEAT_MBYTE
+    else if (*type == vimenc_atom)
+    {
+	char_u		*enc;
+	vimconv_T	conv;
+	int		convlen;
+
+	motion_type = *p++;
+	--len;
+
+	enc = p;
+	p += STRLEN(p) + 1;
+	len -= p - enc;
+
+	/* If the encoding of the text is different from 'encoding', attempt
+	 * converting it. */
+	conv.vc_type = CONV_NONE;
+	convert_setup(&conv, enc, p_enc);
+	if (conv.vc_type != CONV_NONE)
+	{
+	    convlen = len;	/* Need to use an int here. */
+	    tmpbuf = string_convert(&conv, p, &convlen);
+	    len = convlen;
+	    if (tmpbuf != NULL)
+		p = tmpbuf;
+	    convert_setup(&conv, NULL, NULL);
+	}
+    }
+#endif
+
+    else if (*type == compound_text_atom || (
+#ifdef FEAT_MBYTE
+		enc_dbcs != 0 &&
+#endif
+		*type == text_atom))
+    {
+	XTextProperty	text_prop;
+	int		n_text = 0;
+	int		status;
+
+	text_prop.value = (unsigned char *)value;
+	text_prop.encoding = *type;
+	text_prop.format = *format;
+	text_prop.nitems = STRLEN(value);
+	status = XmbTextPropertyToTextList(X_DISPLAY, &text_prop,
+							 &text_list, &n_text);
+	if (status != Success || n_text < 1)
+	{
+	    *(int *)success = FALSE;
+	    return;
+	}
+	p = (char_u *)text_list[0];
+	len = STRLEN(p);
+    }
+    clip_yank_selection(motion_type, p, (long)len, cbd);
+
+    if (text_list != NULL)
+	XFreeStringList(text_list);
+#ifdef FEAT_MBYTE
+    vim_free(tmpbuf);
+#endif
+    XtFree((char *)value);
+    *(int *)success = TRUE;
+}
+
+    void
+clip_x11_request_selection(myShell, dpy, cbd)
+    Widget	myShell;
+    Display	*dpy;
+    VimClipboard	*cbd;
+{
+    XEvent	event;
+    Atom	type;
+    static int	success;
+    int		i;
+    int		nbytes = 0;
+    char_u	*buffer;
+
+    for (i =
+#ifdef FEAT_MBYTE
+	    0
+#else
+	    1
+#endif
+	    ; i < 5; i++)
+    {
+	switch (i)
+	{
+#ifdef FEAT_MBYTE
+	    case 0:  type = vimenc_atom;	break;
+#endif
+	    case 1:  type = vim_atom;		break;
+	    case 2:  type = compound_text_atom; break;
+	    case 3:  type = text_atom;		break;
+	    default: type = XA_STRING;
+	}
+	XtGetSelectionValue(myShell, cbd->sel_atom, type,
+	    clip_x11_request_selection_cb, (XtPointer)&success, CurrentTime);
+
+	/* Make sure the request for the selection goes out before waiting for
+	 * a response. */
+	XFlush(dpy);
+
+	/*
+	 * Wait for result of selection request, otherwise if we type more
+	 * characters, then they will appear before the one that requested the
+	 * paste!  Don't worry, we will catch up with any other events later.
+	 */
+	for (;;)
+	{
+	    if (XCheckTypedEvent(dpy, SelectionNotify, &event))
+		break;
+	    if (XCheckTypedEvent(dpy, SelectionRequest, &event))
+		/* We may get a SelectionRequest here and if we don't handle
+		 * it we hang.  KDE klipper does this, for example. */
+		XtDispatchEvent(&event);
+
+	    /* Do we need this?  Probably not. */
+	    XSync(dpy, False);
+
+	    /* Bernhard Walle solved a slow paste response in an X terminal by
+	     * adding: usleep(10000); here. */
+	}
+
+	/* this is where clip_x11_request_selection_cb() is actually called */
+	XtDispatchEvent(&event);
+
+	if (success)
+	    return;
+    }
+
+    /* Final fallback position - use the X CUT_BUFFER0 store */
+    buffer = (char_u *)XFetchBuffer(dpy, &nbytes, 0);
+    if (nbytes > 0)
+    {
+	/* Got something */
+	clip_yank_selection(MCHAR, buffer, (long)nbytes, cbd);
+	XFree((void *)buffer);
+	if (p_verbose > 0)
+	    verb_msg((char_u *)_("Used CUT_BUFFER0 instead of empty selection"));
+    }
+}
+
+static Boolean	clip_x11_convert_selection_cb __ARGS((Widget, Atom *, Atom *, Atom *, XtPointer *, long_u *, int *));
+
+/* ARGSUSED */
+    static Boolean
+clip_x11_convert_selection_cb(w, sel_atom, target, type, value, length, format)
+    Widget	w;
+    Atom	*sel_atom;
+    Atom	*target;
+    Atom	*type;
+    XtPointer	*value;
+    long_u	*length;
+    int		*format;
+{
+    char_u	*string;
+    char_u	*result;
+    int		motion_type;
+    VimClipboard	*cbd;
+    int		i;
+
+    if (*sel_atom == clip_plus.sel_atom)
+	cbd = &clip_plus;
+    else
+	cbd = &clip_star;
+
+    if (!cbd->owned)
+	return False;	    /* Shouldn't ever happen */
+
+    /* requestor wants to know what target types we support */
+    if (*target == targets_atom)
+    {
+	Atom *array;
+
+	if ((array = (Atom *)XtMalloc((unsigned)(sizeof(Atom) * 6))) == NULL)
+	    return False;
+	*value = (XtPointer)array;
+	i = 0;
+	array[i++] = XA_STRING;
+	array[i++] = targets_atom;
+#ifdef FEAT_MBYTE
+	array[i++] = vimenc_atom;
+#endif
+	array[i++] = vim_atom;
+	array[i++] = text_atom;
+	array[i++] = compound_text_atom;
+	*type = XA_ATOM;
+	/* This used to be: *format = sizeof(Atom) * 8; but that caused
+	 * crashes on 64 bit machines. (Peter Derr) */
+	*format = 32;
+	*length = i;
+	return True;
+    }
+
+    if (       *target != XA_STRING
+#ifdef FEAT_MBYTE
+	    && *target != vimenc_atom
+#endif
+	    && *target != vim_atom
+	    && *target != text_atom
+	    && *target != compound_text_atom)
+	return False;
+
+    clip_get_selection(cbd);
+    motion_type = clip_convert_selection(&string, length, cbd);
+    if (motion_type < 0)
+	return False;
+
+    /* For our own format, the first byte contains the motion type */
+    if (*target == vim_atom)
+	(*length)++;
+
+#ifdef FEAT_MBYTE
+    /* Our own format with encoding: motion 'encoding' NUL text */
+    if (*target == vimenc_atom)
+	*length += STRLEN(p_enc) + 2;
+#endif
+
+    *value = XtMalloc((Cardinal)*length);
+    result = (char_u *)*value;
+    if (result == NULL)
+    {
+	vim_free(string);
+	return False;
+    }
+
+    if (*target == XA_STRING)
+    {
+	mch_memmove(result, string, (size_t)(*length));
+	*type = XA_STRING;
+    }
+    else if (*target == compound_text_atom
+	    || *target == text_atom)
+    {
+	XTextProperty	text_prop;
+	char		*string_nt = (char *)alloc((unsigned)*length + 1);
+
+	/* create NUL terminated string which XmbTextListToTextProperty wants */
+	mch_memmove(string_nt, string, (size_t)*length);
+	string_nt[*length] = NUL;
+	XmbTextListToTextProperty(X_DISPLAY, (char **)&string_nt, 1,
+					      XCompoundTextStyle, &text_prop);
+	vim_free(string_nt);
+	XtFree(*value);			/* replace with COMPOUND text */
+	*value = (XtPointer)(text_prop.value);	/*    from plain text */
+	*length = text_prop.nitems;
+	*type = compound_text_atom;
+    }
+
+#ifdef FEAT_MBYTE
+    else if (*target == vimenc_atom)
+    {
+	int l = STRLEN(p_enc);
+
+	result[0] = motion_type;
+	STRCPY(result + 1, p_enc);
+	mch_memmove(result + l + 2, string, (size_t)(*length - l - 2));
+	*type = vimenc_atom;
+    }
+#endif
+
+    else
+    {
+	result[0] = motion_type;
+	mch_memmove(result + 1, string, (size_t)(*length - 1));
+	*type = vim_atom;
+    }
+    *format = 8;	    /* 8 bits per char */
+    vim_free(string);
+    return True;
+}
+
+static void  clip_x11_lose_ownership_cb __ARGS((Widget, Atom *));
+
+/* ARGSUSED */
+    static void
+clip_x11_lose_ownership_cb(w, sel_atom)
+    Widget  w;
+    Atom    *sel_atom;
+{
+    if (*sel_atom == clip_plus.sel_atom)
+	clip_lose_selection(&clip_plus);
+    else
+	clip_lose_selection(&clip_star);
+}
+
+    void
+clip_x11_lose_selection(myShell, cbd)
+    Widget	myShell;
+    VimClipboard	*cbd;
+{
+    XtDisownSelection(myShell, cbd->sel_atom, CurrentTime);
+}
+
+    int
+clip_x11_own_selection(myShell, cbd)
+    Widget	myShell;
+    VimClipboard	*cbd;
+{
+    if (XtOwnSelection(myShell, cbd->sel_atom, CurrentTime,
+	    clip_x11_convert_selection_cb, clip_x11_lose_ownership_cb,
+							       NULL) == False)
+	return FAIL;
+    return OK;
+}
+
+/*
+ * Send the current selection to the clipboard.  Do nothing for X because we
+ * will fill in the selection only when requested by another app.
+ */
+/*ARGSUSED*/
+    void
+clip_x11_set_selection(cbd)
+    VimClipboard *cbd;
+{
+}
+#endif
+
+#if defined(FEAT_MOUSE) || defined(PROTO)
+
+/*
+ * Move the cursor to the specified row and column on the screen.
+ * Change current window if necessary.	Returns an integer with the
+ * CURSOR_MOVED bit set if the cursor has moved or unset otherwise.
+ *
+ * The MOUSE_FOLD_CLOSE bit is set when clicked on the '-' in a fold column.
+ * The MOUSE_FOLD_OPEN bit is set when clicked on the '+' in a fold column.
+ *
+ * If flags has MOUSE_FOCUS, then the current window will not be changed, and
+ * if the mouse is outside the window then the text will scroll, or if the
+ * mouse was previously on a status line, then the status line may be dragged.
+ *
+ * If flags has MOUSE_MAY_VIS, then VIsual mode will be started before the
+ * cursor is moved unless the cursor was on a status line.
+ * This function returns one of IN_UNKNOWN, IN_BUFFER, IN_STATUS_LINE or
+ * IN_SEP_LINE depending on where the cursor was clicked.
+ *
+ * If flags has MOUSE_MAY_STOP_VIS, then Visual mode will be stopped, unless
+ * the mouse is on the status line of the same window.
+ *
+ * If flags has MOUSE_DID_MOVE, nothing is done if the mouse didn't move since
+ * the last call.
+ *
+ * If flags has MOUSE_SETPOS, nothing is done, only the current position is
+ * remembered.
+ */
+    int
+jump_to_mouse(flags, inclusive, which_button)
+    int		flags;
+    int		*inclusive;	/* used for inclusive operator, can be NULL */
+    int		which_button;	/* MOUSE_LEFT, MOUSE_RIGHT, MOUSE_MIDDLE */
+{
+    static int	on_status_line = 0;	/* #lines below bottom of window */
+#ifdef FEAT_VERTSPLIT
+    static int	on_sep_line = 0;	/* on separator right of window */
+#endif
+    static int	prev_row = -1;
+    static int	prev_col = -1;
+    static win_T *dragwin = NULL;	/* window being dragged */
+    static int	did_drag = FALSE;	/* drag was noticed */
+
+    win_T	*wp, *old_curwin;
+    pos_T	old_cursor;
+    int		count;
+    int		first;
+    int		row = mouse_row;
+    int		col = mouse_col;
+#ifdef FEAT_FOLDING
+    int		mouse_char;
+#endif
+
+    mouse_past_bottom = FALSE;
+    mouse_past_eol = FALSE;
+
+    if (flags & MOUSE_RELEASED)
+    {
+	/* On button release we may change window focus if positioned on a
+	 * status line and no dragging happened. */
+	if (dragwin != NULL && !did_drag)
+	    flags &= ~(MOUSE_FOCUS | MOUSE_DID_MOVE);
+	dragwin = NULL;
+	did_drag = FALSE;
+    }
+
+    if ((flags & MOUSE_DID_MOVE)
+	    && prev_row == mouse_row
+	    && prev_col == mouse_col)
+    {
+retnomove:
+	/* before moving the cursor for a left click which is NOT in a status
+	 * line, stop Visual mode */
+	if (on_status_line)
+	    return IN_STATUS_LINE;
+#ifdef FEAT_VERTSPLIT
+	if (on_sep_line)
+	    return IN_SEP_LINE;
+#endif
+#ifdef FEAT_VISUAL
+	if (flags & MOUSE_MAY_STOP_VIS)
+	{
+	    end_visual_mode();
+	    redraw_curbuf_later(INVERTED);	/* delete the inversion */
+	}
+#endif
+#if defined(FEAT_CMDWIN) && defined(FEAT_CLIPBOARD)
+	/* Continue a modeless selection in another window. */
+	if (cmdwin_type != 0 && row < W_WINROW(curwin))
+	    return IN_OTHER_WIN;
+#endif
+	return IN_BUFFER;
+    }
+
+    prev_row = mouse_row;
+    prev_col = mouse_col;
+
+    if (flags & MOUSE_SETPOS)
+	goto retnomove;				/* ugly goto... */
+
+#ifdef FEAT_FOLDING
+    /* Remember the character under the mouse, it might be a '-' or '+' in the
+     * fold column. */
+    if (row >= 0 && row < Rows && col >= 0 && col <= Columns
+						       && ScreenLines != NULL)
+	mouse_char = ScreenLines[LineOffset[row] + col];
+    else
+	mouse_char = ' ';
+#endif
+
+    old_curwin = curwin;
+    old_cursor = curwin->w_cursor;
+
+    if (!(flags & MOUSE_FOCUS))
+    {
+	if (row < 0 || col < 0)			/* check if it makes sense */
+	    return IN_UNKNOWN;
+
+#ifdef FEAT_WINDOWS
+	/* find the window where the row is in */
+	wp = mouse_find_win(&row, &col);
+#else
+	wp = firstwin;
+#endif
+	dragwin = NULL;
+	/*
+	 * winpos and height may change in win_enter()!
+	 */
+	if (row >= wp->w_height)		/* In (or below) status line */
+	{
+	    on_status_line = row - wp->w_height + 1;
+	    dragwin = wp;
+	}
+	else
+	    on_status_line = 0;
+#ifdef FEAT_VERTSPLIT
+	if (col >= wp->w_width)		/* In separator line */
+	{
+	    on_sep_line = col - wp->w_width + 1;
+	    dragwin = wp;
+	}
+	else
+	    on_sep_line = 0;
+
+	/* The rightmost character of the status line might be a vertical
+	 * separator character if there is no connecting window to the right. */
+	if (on_status_line && on_sep_line)
+	{
+	    if (stl_connected(wp))
+		on_sep_line = 0;
+	    else
+		on_status_line = 0;
+	}
+#endif
+
+#ifdef FEAT_VISUAL
+	/* Before jumping to another buffer, or moving the cursor for a left
+	 * click, stop Visual mode. */
+	if (VIsual_active
+		&& (wp->w_buffer != curwin->w_buffer
+		    || (!on_status_line
+# ifdef FEAT_VERTSPLIT
+			&& !on_sep_line
+# endif
+# ifdef FEAT_FOLDING
+			&& (
+#  ifdef FEAT_RIGHTLEFT
+			    wp->w_p_rl ? col < W_WIDTH(wp) - wp->w_p_fdc :
+#  endif
+			    col >= wp->w_p_fdc
+#  ifdef FEAT_CMDWIN
+				  + (cmdwin_type == 0 && wp == curwin ? 0 : 1)
+#  endif
+			    )
+# endif
+			&& (flags & MOUSE_MAY_STOP_VIS))))
+	{
+	    end_visual_mode();
+	    redraw_curbuf_later(INVERTED);	/* delete the inversion */
+	}
+#endif
+#ifdef FEAT_CMDWIN
+	if (cmdwin_type != 0 && wp != curwin)
+	{
+	    /* A click outside the command-line window: Use modeless
+	     * selection if possible.  Allow dragging the status line of
+	     * windows just above the command-line window. */
+	    if (wp->w_winrow + wp->w_height
+		       != curwin->w_prev->w_winrow + curwin->w_prev->w_height)
+	    {
+		on_status_line = 0;
+		dragwin = NULL;
+	    }
+# ifdef FEAT_VERTSPLIT
+	    on_sep_line = 0;
+# endif
+# ifdef FEAT_CLIPBOARD
+	    if (on_status_line)
+		return IN_STATUS_LINE;
+	    return IN_OTHER_WIN;
+# else
+	    row = 0;
+	    col += wp->w_wincol;
+	    wp = curwin;
+# endif
+	}
+#endif
+#ifdef FEAT_WINDOWS
+	/* Only change window focus when not clicking on or dragging the
+	 * status line.  Do change focus when releasing the mouse button
+	 * (MOUSE_FOCUS was set above if we dragged first). */
+	if (dragwin == NULL || (flags & MOUSE_RELEASED))
+	    win_enter(wp, TRUE);		/* can make wp invalid! */
+# ifdef CHECK_DOUBLE_CLICK
+	/* set topline, to be able to check for double click ourselves */
+	if (curwin != old_curwin)
+	    set_mouse_topline(curwin);
+# endif
+#endif
+	if (on_status_line)			/* In (or below) status line */
+	{
+	    /* Don't use start_arrow() if we're in the same window */
+	    if (curwin == old_curwin)
+		return IN_STATUS_LINE;
+	    else
+		return IN_STATUS_LINE | CURSOR_MOVED;
+	}
+#ifdef FEAT_VERTSPLIT
+	if (on_sep_line)			/* In (or below) status line */
+	{
+	    /* Don't use start_arrow() if we're in the same window */
+	    if (curwin == old_curwin)
+		return IN_SEP_LINE;
+	    else
+		return IN_SEP_LINE | CURSOR_MOVED;
+	}
+#endif
+
+	curwin->w_cursor.lnum = curwin->w_topline;
+#ifdef FEAT_GUI
+	/* remember topline, needed for double click */
+	gui_prev_topline = curwin->w_topline;
+# ifdef FEAT_DIFF
+	gui_prev_topfill = curwin->w_topfill;
+# endif
+#endif
+    }
+    else if (on_status_line && which_button == MOUSE_LEFT)
+    {
+#ifdef FEAT_WINDOWS
+	if (dragwin != NULL)
+	{
+	    /* Drag the status line */
+	    count = row - dragwin->w_winrow - dragwin->w_height + 1
+							     - on_status_line;
+	    win_drag_status_line(dragwin, count);
+	    did_drag |= count;
+	}
+#endif
+	return IN_STATUS_LINE;			/* Cursor didn't move */
+    }
+#ifdef FEAT_VERTSPLIT
+    else if (on_sep_line && which_button == MOUSE_LEFT)
+    {
+	if (dragwin != NULL)
+	{
+	    /* Drag the separator column */
+	    count = col - dragwin->w_wincol - dragwin->w_width + 1
+								- on_sep_line;
+	    win_drag_vsep_line(dragwin, count);
+	    did_drag |= count;
+	}
+	return IN_SEP_LINE;			/* Cursor didn't move */
+    }
+#endif
+    else /* keep_window_focus must be TRUE */
+    {
+#ifdef FEAT_VISUAL
+	/* before moving the cursor for a left click, stop Visual mode */
+	if (flags & MOUSE_MAY_STOP_VIS)
+	{
+	    end_visual_mode();
+	    redraw_curbuf_later(INVERTED);	/* delete the inversion */
+	}
+#endif
+
+#if defined(FEAT_CMDWIN) && defined(FEAT_CLIPBOARD)
+	/* Continue a modeless selection in another window. */
+	if (cmdwin_type != 0 && row < W_WINROW(curwin))
+	    return IN_OTHER_WIN;
+#endif
+
+	row -= W_WINROW(curwin);
+#ifdef FEAT_VERTSPLIT
+	col -= W_WINCOL(curwin);
+#endif
+
+	/*
+	 * When clicking beyond the end of the window, scroll the screen.
+	 * Scroll by however many rows outside the window we are.
+	 */
+	if (row < 0)
+	{
+	    count = 0;
+	    for (first = TRUE; curwin->w_topline > 1; )
+	    {
+#ifdef FEAT_DIFF
+		if (curwin->w_topfill < diff_check(curwin, curwin->w_topline))
+		    ++count;
+		else
+#endif
+		    count += plines(curwin->w_topline - 1);
+		if (!first && count > -row)
+		    break;
+		first = FALSE;
+#ifdef FEAT_FOLDING
+		hasFolding(curwin->w_topline, &curwin->w_topline, NULL);
+#endif
+#ifdef FEAT_DIFF
+		if (curwin->w_topfill < diff_check(curwin, curwin->w_topline))
+		    ++curwin->w_topfill;
+		else
+#endif
+		{
+		    --curwin->w_topline;
+#ifdef FEAT_DIFF
+		    curwin->w_topfill = 0;
+#endif
+		}
+	    }
+#ifdef FEAT_DIFF
+	    check_topfill(curwin, FALSE);
+#endif
+	    curwin->w_valid &=
+		      ~(VALID_WROW|VALID_CROW|VALID_BOTLINE|VALID_BOTLINE_AP);
+	    redraw_later(VALID);
+	    row = 0;
+	}
+	else if (row >= curwin->w_height)
+	{
+	    count = 0;
+	    for (first = TRUE; curwin->w_topline < curbuf->b_ml.ml_line_count; )
+	    {
+#ifdef FEAT_DIFF
+		if (curwin->w_topfill > 0)
+		    ++count;
+		else
+#endif
+		    count += plines(curwin->w_topline);
+		if (!first && count > row - curwin->w_height + 1)
+		    break;
+		first = FALSE;
+#ifdef FEAT_FOLDING
+		if (hasFolding(curwin->w_topline, NULL, &curwin->w_topline)
+			&& curwin->w_topline == curbuf->b_ml.ml_line_count)
+		    break;
+#endif
+#ifdef FEAT_DIFF
+		if (curwin->w_topfill > 0)
+		    --curwin->w_topfill;
+		else
+#endif
+		{
+		    ++curwin->w_topline;
+#ifdef FEAT_DIFF
+		    curwin->w_topfill =
+				   diff_check_fill(curwin, curwin->w_topline);
+#endif
+		}
+	    }
+#ifdef FEAT_DIFF
+	    check_topfill(curwin, FALSE);
+#endif
+	    redraw_later(VALID);
+	    curwin->w_valid &=
+		      ~(VALID_WROW|VALID_CROW|VALID_BOTLINE|VALID_BOTLINE_AP);
+	    row = curwin->w_height - 1;
+	}
+	else if (row == 0)
+	{
+	    /* When dragging the mouse, while the text has been scrolled up as
+	     * far as it goes, moving the mouse in the top line should scroll
+	     * the text down (done later when recomputing w_topline). */
+	    if (mouse_dragging > 0
+		    && curwin->w_cursor.lnum
+				       == curwin->w_buffer->b_ml.ml_line_count
+		    && curwin->w_cursor.lnum == curwin->w_topline)
+		curwin->w_valid &= ~(VALID_TOPLINE);
+	}
+    }
+
+#ifdef FEAT_FOLDING
+    /* Check for position outside of the fold column. */
+    if (
+# ifdef FEAT_RIGHTLEFT
+	    curwin->w_p_rl ? col < W_WIDTH(curwin) - curwin->w_p_fdc :
+# endif
+	    col >= curwin->w_p_fdc
+#  ifdef FEAT_CMDWIN
+				+ (cmdwin_type == 0 ? 0 : 1)
+#  endif
+       )
+	mouse_char = ' ';
+#endif
+
+    /* compute the position in the buffer line from the posn on the screen */
+    if (mouse_comp_pos(curwin, &row, &col, &curwin->w_cursor.lnum))
+	mouse_past_bottom = TRUE;
+
+#ifdef FEAT_VISUAL
+    /* Start Visual mode before coladvance(), for when 'sel' != "old" */
+    if ((flags & MOUSE_MAY_VIS) && !VIsual_active)
+    {
+	check_visual_highlight();
+	VIsual = old_cursor;
+	VIsual_active = TRUE;
+	VIsual_reselect = TRUE;
+	/* if 'selectmode' contains "mouse", start Select mode */
+	may_start_select('o');
+	setmouse();
+	if (p_smd && msg_silent == 0)
+	    redraw_cmdline = TRUE;	/* show visual mode later */
+    }
+#endif
+
+    curwin->w_curswant = col;
+    curwin->w_set_curswant = FALSE;	/* May still have been TRUE */
+    if (coladvance(col) == FAIL)	/* Mouse click beyond end of line */
+    {
+	if (inclusive != NULL)
+	    *inclusive = TRUE;
+	mouse_past_eol = TRUE;
+    }
+    else if (inclusive != NULL)
+	*inclusive = FALSE;
+
+    count = IN_BUFFER;
+    if (curwin != old_curwin || curwin->w_cursor.lnum != old_cursor.lnum
+	    || curwin->w_cursor.col != old_cursor.col)
+	count |= CURSOR_MOVED;		/* Cursor has moved */
+
+#ifdef FEAT_FOLDING
+    if (mouse_char == '+')
+	count |= MOUSE_FOLD_OPEN;
+    else if (mouse_char != ' ')
+	count |= MOUSE_FOLD_CLOSE;
+#endif
+
+    return count;
+}
+
+/*
+ * Compute the position in the buffer line from the posn on the screen in
+ * window "win".
+ * Returns TRUE if the position is below the last line.
+ */
+    int
+mouse_comp_pos(win, rowp, colp, lnump)
+    win_T	*win;
+    int		*rowp;
+    int		*colp;
+    linenr_T	*lnump;
+{
+    int		col = *colp;
+    int		row = *rowp;
+    linenr_T	lnum;
+    int		retval = FALSE;
+    int		off;
+    int		count;
+
+#ifdef FEAT_RIGHTLEFT
+    if (win->w_p_rl)
+	col = W_WIDTH(win) - 1 - col;
+#endif
+
+    lnum = win->w_topline;
+
+    while (row > 0)
+    {
+#ifdef FEAT_DIFF
+	/* Don't include filler lines in "count" */
+	if (win->w_p_diff
+# ifdef FEAT_FOLDING
+		&& !hasFoldingWin(win, lnum, NULL, NULL, TRUE, NULL)
+# endif
+		)
+	{
+	    if (lnum == win->w_topline)
+		row -= win->w_topfill;
+	    else
+		row -= diff_check_fill(win, lnum);
+	    count = plines_win_nofill(win, lnum, TRUE);
+	}
+	else
+#endif
+	    count = plines_win(win, lnum, TRUE);
+	if (count > row)
+	    break;	/* Position is in this buffer line. */
+#ifdef FEAT_FOLDING
+	(void)hasFoldingWin(win, lnum, NULL, &lnum, TRUE, NULL);
+#endif
+	if (lnum == win->w_buffer->b_ml.ml_line_count)
+	{
+	    retval = TRUE;
+	    break;		/* past end of file */
+	}
+	row -= count;
+	++lnum;
+    }
+
+    if (!retval)
+    {
+	/* Compute the column without wrapping. */
+	off = win_col_off(win) - win_col_off2(win);
+	if (col < off)
+	    col = off;
+	col += row * (W_WIDTH(win) - off);
+	/* add skip column (for long wrapping line) */
+	col += win->w_skipcol;
+    }
+
+    if (!win->w_p_wrap)
+	col += win->w_leftcol;
+
+    /* skip line number and fold column in front of the line */
+    col -= win_col_off(win);
+    if (col < 0)
+    {
+#ifdef FEAT_NETBEANS_INTG
+	if (usingNetbeans)
+	    netbeans_gutter_click(lnum);
+#endif
+	col = 0;
+    }
+
+    *colp = col;
+    *rowp = row;
+    *lnump = lnum;
+    return retval;
+}
+
+#if defined(FEAT_WINDOWS) || defined(PROTO)
+/*
+ * Find the window at screen position "*rowp" and "*colp".  The positions are
+ * updated to become relative to the top-left of the window.
+ */
+/*ARGSUSED*/
+    win_T *
+mouse_find_win(rowp, colp)
+    int		*rowp;
+    int		*colp;
+{
+    frame_T	*fp;
+
+    fp = topframe;
+    *rowp -= firstwin->w_winrow;
+    for (;;)
+    {
+	if (fp->fr_layout == FR_LEAF)
+	    break;
+#ifdef FEAT_VERTSPLIT
+	if (fp->fr_layout == FR_ROW)
+	{
+	    for (fp = fp->fr_child; fp->fr_next != NULL; fp = fp->fr_next)
+	    {
+		if (*colp < fp->fr_width)
+		    break;
+		*colp -= fp->fr_width;
+	    }
+	}
+#endif
+	else    /* fr_layout == FR_COL */
+	{
+	    for (fp = fp->fr_child; fp->fr_next != NULL; fp = fp->fr_next)
+	    {
+		if (*rowp < fp->fr_height)
+		    break;
+		*rowp -= fp->fr_height;
+	    }
+	}
+    }
+    return fp->fr_win;
+}
+#endif
+
+#if defined(FEAT_GUI_MOTIF) || defined(FEAT_GUI_GTK) || defined (FEAT_GUI_MAC) \
+	|| defined(FEAT_GUI_ATHENA) || defined(FEAT_GUI_MSWIN) \
+	|| defined(FEAT_GUI_PHOTON) || defined(PROTO)
+/*
+ * Translate window coordinates to buffer position without any side effects
+ */
+    int
+get_fpos_of_mouse(mpos)
+    pos_T	*mpos;
+{
+    win_T	*wp;
+    int		row = mouse_row;
+    int		col = mouse_col;
+
+    if (row < 0 || col < 0)		/* check if it makes sense */
+	return IN_UNKNOWN;
+
+#ifdef FEAT_WINDOWS
+    /* find the window where the row is in */
+    wp = mouse_find_win(&row, &col);
+#else
+    wp = firstwin;
+#endif
+    /*
+     * winpos and height may change in win_enter()!
+     */
+    if (row >= wp->w_height)	/* In (or below) status line */
+	return IN_STATUS_LINE;
+#ifdef FEAT_VERTSPLIT
+    if (col >= wp->w_width)	/* In vertical separator line */
+	return IN_SEP_LINE;
+#endif
+
+    if (wp != curwin)
+	return IN_UNKNOWN;
+
+    /* compute the position in the buffer line from the posn on the screen */
+    if (mouse_comp_pos(curwin, &row, &col, &mpos->lnum))
+	return IN_STATUS_LINE; /* past bottom */
+
+    mpos->col = vcol2col(wp, mpos->lnum, col);
+
+    if (mpos->col > 0)
+	--mpos->col;
+    return IN_BUFFER;
+}
+
+/*
+ * Convert a virtual (screen) column to a character column.
+ * The first column is one.
+ */
+    int
+vcol2col(wp, lnum, vcol)
+    win_T	*wp;
+    linenr_T	lnum;
+    int		vcol;
+{
+    /* try to advance to the specified column */
+    int		col = 0;
+    int		count = 0;
+    char_u	*ptr;
+
+    ptr = ml_get_buf(wp->w_buffer, lnum, FALSE);
+    while (count <= vcol && *ptr != NUL)
+    {
+	++col;
+	count += win_lbr_chartabsize(wp, ptr, count, NULL);
+	mb_ptr_adv(ptr);
+    }
+    return col;
+}
+#endif
+
+#endif /* FEAT_MOUSE */
+
+#if defined(FEAT_GUI) || defined(WIN3264) || defined(PROTO)
+/*
+ * Called when focus changed.  Used for the GUI or for systems where this can
+ * be done in the console (Win32).
+ */
+    void
+ui_focus_change(in_focus)
+    int		in_focus;	/* TRUE if focus gained. */
+{
+    static time_t	last_time = (time_t)0;
+    int			need_redraw = FALSE;
+
+    /* When activated: Check if any file was modified outside of Vim.
+     * Only do this when not done within the last two seconds (could get
+     * several events in a row). */
+    if (in_focus && last_time + 2 < time(NULL))
+    {
+	need_redraw = check_timestamps(
+# ifdef FEAT_GUI
+		gui.in_use
+# else
+		FALSE
+# endif
+		);
+	last_time = time(NULL);
+    }
+
+#ifdef FEAT_AUTOCMD
+    /*
+     * Fire the focus gained/lost autocommand.
+     */
+    need_redraw |= apply_autocmds(in_focus ? EVENT_FOCUSGAINED
+				: EVENT_FOCUSLOST, NULL, NULL, FALSE, curbuf);
+#endif
+
+    if (need_redraw)
+    {
+	/* Something was executed, make sure the cursor is put back where it
+	 * belongs. */
+	need_wait_return = FALSE;
+
+	if (State & CMDLINE)
+	    redrawcmdline();
+	else if (State == HITRETURN || State == SETWSIZE || State == ASKMORE
+		|| State == EXTERNCMD || State == CONFIRM || exmode_active)
+	    repeat_message();
+	else if ((State & NORMAL) || (State & INSERT))
+	{
+	    if (must_redraw != 0)
+		update_screen(0);
+	    setcursor();
+	}
+	cursor_on();	    /* redrawing may have switched it off */
+	out_flush();
+# ifdef FEAT_GUI
+	if (gui.in_use)
+	{
+	    gui_update_cursor(FALSE, TRUE);
+	    gui_update_scrollbars(FALSE);
+	}
+# endif
+    }
+#ifdef FEAT_TITLE
+    /* File may have been changed from 'readonly' to 'noreadonly' */
+    if (need_maketitle)
+	maketitle();
+#endif
+}
+#endif
+
+#if defined(USE_IM_CONTROL) || defined(PROTO)
+/*
+ * Save current Input Method status to specified place.
+ */
+    void
+im_save_status(psave)
+    long *psave;
+{
+    /* Don't save when 'imdisable' is set or "xic" is NULL, IM is always
+     * disabled then (but might start later).
+     * Also don't save when inside a mapping, vgetc_im_active has not been set
+     * then.
+     * And don't save when the keys were stuffed (e.g., for a "." command).
+     * And don't save when the GUI is running but our window doesn't have
+     * input focus (e.g., when a find dialog is open). */
+    if (!p_imdisable && KeyTyped && !KeyStuffed
+# ifdef FEAT_XIM
+	    && xic != NULL
+# endif
+# ifdef FEAT_GUI
+	    && (!gui.in_use || gui.in_focus)
+# endif
+	)
+    {
+	/* Do save when IM is on, or IM is off and saved status is on. */
+	if (vgetc_im_active)
+	    *psave = B_IMODE_IM;
+	else if (*psave == B_IMODE_IM)
+	    *psave = B_IMODE_NONE;
+    }
+}
+#endif
--- /dev/null
+++ b/undo.c
@@ -1,0 +1,2150 @@
+/* vi:set ts=8 sts=4 sw=4:
+ *
+ * VIM - Vi IMproved	by Bram Moolenaar
+ *
+ * Do ":help uganda"  in Vim to read copying and usage conditions.
+ * Do ":help credits" in Vim to see a list of people who contributed.
+ * See README.txt for an overview of the Vim source code.
+ */
+
+/*
+ * undo.c: multi level undo facility
+ *
+ * The saved lines are stored in a list of lists (one for each buffer):
+ *
+ * b_u_oldhead------------------------------------------------+
+ *							      |
+ *							      V
+ *		  +--------------+    +--------------+	  +--------------+
+ * b_u_newhead--->| u_header	 |    | u_header     |	  | u_header	 |
+ *		  |	uh_next------>|     uh_next------>|	uh_next---->NULL
+ *	   NULL<--------uh_prev  |<---------uh_prev  |<---------uh_prev  |
+ *		  |	uh_entry |    |     uh_entry |	  |	uh_entry |
+ *		  +--------|-----+    +--------|-----+	  +--------|-----+
+ *			   |		       |		   |
+ *			   V		       V		   V
+ *		  +--------------+    +--------------+	  +--------------+
+ *		  | u_entry	 |    | u_entry      |	  | u_entry	 |
+ *		  |	ue_next  |    |     ue_next  |	  |	ue_next  |
+ *		  +--------|-----+    +--------|-----+	  +--------|-----+
+ *			   |		       |		   |
+ *			   V		       V		   V
+ *		  +--------------+	      NULL		  NULL
+ *		  | u_entry	 |
+ *		  |	ue_next  |
+ *		  +--------|-----+
+ *			   |
+ *			   V
+ *			  etc.
+ *
+ * Each u_entry list contains the information for one undo or redo.
+ * curbuf->b_u_curhead points to the header of the last undo (the next redo),
+ * or is NULL if nothing has been undone (end of the branch).
+ *
+ * For keeping alternate undo/redo branches the uh_alt field is used.  Thus at
+ * each point in the list a branch may appear for an alternate to redo.  The
+ * uh_seq field is numbered sequentially to be able to find a newer or older
+ * branch.
+ *
+ *		   +---------------+	+---------------+
+ * b_u_oldhead --->| u_header	   |	| u_header	|
+ *		   |   uh_alt_next ---->|   uh_alt_next ----> NULL
+ *	   NULL <----- uh_alt_prev |<------ uh_alt_prev |
+ *		   |   uh_prev	   |	|   uh_prev	|
+ *		   +-----|---------+	+-----|---------+
+ *			 |		      |
+ *			 V		      V
+ *		   +---------------+	+---------------+
+ *		   | u_header	   |	| u_header	|
+ *		   |   uh_alt_next |	|   uh_alt_next |
+ * b_u_newhead --->|   uh_alt_prev |	|   uh_alt_prev |
+ *		   |   uh_prev	   |	|   uh_prev	|
+ *		   +-----|---------+	+-----|---------+
+ *			 |		      |
+ *			 V		      V
+ *		       NULL		+---------------+    +---------------+
+ *					| u_header	|    | u_header      |
+ *					|   uh_alt_next ---->|	 uh_alt_next |
+ *					|   uh_alt_prev |<------ uh_alt_prev |
+ *					|   uh_prev	|    |	 uh_prev     |
+ *					+-----|---------+    +-----|---------+
+ *					      |			   |
+ *					     etc.		  etc.
+ *
+ *
+ * All data is allocated with U_ALLOC_LINE(), it will be freed as soon as the
+ * buffer is unloaded.
+ */
+
+#include "vim.h"
+
+/* See below: use malloc()/free() for memory management. */
+#define U_USE_MALLOC 1
+
+static void u_unch_branch __ARGS((u_header_T *uhp));
+static u_entry_T *u_get_headentry __ARGS((void));
+static void u_getbot __ARGS((void));
+static int u_savecommon __ARGS((linenr_T, linenr_T, linenr_T));
+static void u_doit __ARGS((int count));
+static void u_undoredo __ARGS((int undo));
+static void u_undo_end __ARGS((int did_undo, int absolute));
+static void u_add_time __ARGS((char_u *buf, size_t buflen, time_t tt));
+static void u_freeheader __ARGS((buf_T *buf, u_header_T *uhp, u_header_T **uhpp));
+static void u_freebranch __ARGS((buf_T *buf, u_header_T *uhp, u_header_T **uhpp));
+static void u_freeentries __ARGS((buf_T *buf, u_header_T *uhp, u_header_T **uhpp));
+static void u_freeentry __ARGS((u_entry_T *, long));
+
+#ifdef U_USE_MALLOC
+# define U_FREE_LINE(ptr) vim_free(ptr)
+# define U_ALLOC_LINE(size) lalloc((long_u)((size) + 1), FALSE)
+#else
+static void u_free_line __ARGS((char_u *ptr, int keep));
+static char_u *u_alloc_line __ARGS((unsigned size));
+# define U_FREE_LINE(ptr) u_free_line((ptr), FALSE)
+# define U_ALLOC_LINE(size) u_alloc_line(size)
+#endif
+static char_u *u_save_line __ARGS((linenr_T));
+
+static long	u_newcount, u_oldcount;
+
+/*
+ * When 'u' flag included in 'cpoptions', we behave like vi.  Need to remember
+ * the action that "u" should do.
+ */
+static int	undo_undoes = FALSE;
+
+/*
+ * Save the current line for both the "u" and "U" command.
+ * Returns OK or FAIL.
+ */
+    int
+u_save_cursor()
+{
+    return (u_save((linenr_T)(curwin->w_cursor.lnum - 1),
+				      (linenr_T)(curwin->w_cursor.lnum + 1)));
+}
+
+/*
+ * Save the lines between "top" and "bot" for both the "u" and "U" command.
+ * "top" may be 0 and bot may be curbuf->b_ml.ml_line_count + 1.
+ * Returns FAIL when lines could not be saved, OK otherwise.
+ */
+    int
+u_save(top, bot)
+    linenr_T top, bot;
+{
+    if (undo_off)
+	return OK;
+
+    if (top > curbuf->b_ml.ml_line_count ||
+			    top >= bot || bot > curbuf->b_ml.ml_line_count + 1)
+	return FALSE;	/* rely on caller to do error messages */
+
+    if (top + 2 == bot)
+	u_saveline((linenr_T)(top + 1));
+
+    return (u_savecommon(top, bot, (linenr_T)0));
+}
+
+/*
+ * save the line "lnum" (used by ":s" and "~" command)
+ * The line is replaced, so the new bottom line is lnum + 1.
+ */
+    int
+u_savesub(lnum)
+    linenr_T	lnum;
+{
+    if (undo_off)
+	return OK;
+
+    return (u_savecommon(lnum - 1, lnum + 1, lnum + 1));
+}
+
+/*
+ * a new line is inserted before line "lnum" (used by :s command)
+ * The line is inserted, so the new bottom line is lnum + 1.
+ */
+    int
+u_inssub(lnum)
+    linenr_T	lnum;
+{
+    if (undo_off)
+	return OK;
+
+    return (u_savecommon(lnum - 1, lnum, lnum + 1));
+}
+
+/*
+ * save the lines "lnum" - "lnum" + nlines (used by delete command)
+ * The lines are deleted, so the new bottom line is lnum, unless the buffer
+ * becomes empty.
+ */
+    int
+u_savedel(lnum, nlines)
+    linenr_T	lnum;
+    long	nlines;
+{
+    if (undo_off)
+	return OK;
+
+    return (u_savecommon(lnum - 1, lnum + nlines,
+			nlines == curbuf->b_ml.ml_line_count ? 2 : lnum));
+}
+
+/*
+ * Return TRUE when undo is allowed.  Otherwise give an error message and
+ * return FALSE.
+ */
+    int
+undo_allowed()
+{
+    /* Don't allow changes when 'modifiable' is off.  */
+    if (!curbuf->b_p_ma)
+    {
+	EMSG(_(e_modifiable));
+	return FALSE;
+    }
+
+#ifdef HAVE_SANDBOX
+    /* In the sandbox it's not allowed to change the text. */
+    if (sandbox != 0)
+    {
+	EMSG(_(e_sandbox));
+	return FALSE;
+    }
+#endif
+
+    /* Don't allow changes in the buffer while editing the cmdline.  The
+     * caller of getcmdline() may get confused. */
+    if (textlock != 0)
+    {
+	EMSG(_(e_secure));
+	return FALSE;
+    }
+
+    return TRUE;
+}
+
+    static int
+u_savecommon(top, bot, newbot)
+    linenr_T	top, bot;
+    linenr_T	newbot;
+{
+    linenr_T	lnum;
+    long	i;
+    u_header_T	*uhp;
+    u_header_T	*old_curhead;
+    u_entry_T	*uep;
+    u_entry_T	*prev_uep;
+    long	size;
+
+    /* When making changes is not allowed return FAIL.  It's a crude way to
+     * make all change commands fail. */
+    if (!undo_allowed())
+	return FAIL;
+
+#ifdef FEAT_NETBEANS_INTG
+    /*
+     * Netbeans defines areas that cannot be modified.  Bail out here when
+     * trying to change text in a guarded area.
+     */
+    if (usingNetbeans)
+    {
+	if (netbeans_is_guarded(top, bot))
+	{
+	    EMSG(_(e_guarded));
+	    return FAIL;
+	}
+	if (curbuf->b_p_ro)
+	{
+	    EMSG(_(e_nbreadonly));
+	    return FAIL;
+	}
+    }
+#endif
+
+#ifdef FEAT_AUTOCMD
+    /*
+     * Saving text for undo means we are going to make a change.  Give a
+     * warning for a read-only file before making the change, so that the
+     * FileChangedRO event can replace the buffer with a read-write version
+     * (e.g., obtained from a source control system).
+     */
+    change_warning(0);
+#endif
+
+    size = bot - top - 1;
+
+    /*
+     * if curbuf->b_u_synced == TRUE make a new header
+     */
+    if (curbuf->b_u_synced)
+    {
+#ifdef FEAT_JUMPLIST
+	/* Need to create new entry in b_changelist. */
+	curbuf->b_new_change = TRUE;
+#endif
+
+	if (p_ul >= 0)
+	{
+	    /*
+	     * Make a new header entry.  Do this first so that we don't mess
+	     * up the undo info when out of memory.
+	     */
+	    uhp = (u_header_T *)U_ALLOC_LINE((unsigned)sizeof(u_header_T));
+	    if (uhp == NULL)
+		goto nomem;
+	}
+	else
+	    uhp = NULL;
+
+	/*
+	 * If we undid more than we redid, move the entry lists before and
+	 * including curbuf->b_u_curhead to an alternate branch.
+	 */
+	old_curhead = curbuf->b_u_curhead;
+	if (old_curhead != NULL)
+	{
+	    curbuf->b_u_newhead = old_curhead->uh_next;
+	    curbuf->b_u_curhead = NULL;
+	}
+
+	/*
+	 * free headers to keep the size right
+	 */
+	while (curbuf->b_u_numhead > p_ul && curbuf->b_u_oldhead != NULL)
+	{
+	    u_header_T	    *uhfree = curbuf->b_u_oldhead;
+
+	    /* If there is no branch only free one header. */
+	    if (uhfree->uh_alt_next == NULL)
+		u_freeheader(curbuf, uhfree, &old_curhead);
+	    else
+	    {
+		/* Free the oldest alternate branch as a whole. */
+		while (uhfree->uh_alt_next != NULL)
+		    uhfree = uhfree->uh_alt_next;
+		u_freebranch(curbuf, uhfree, &old_curhead);
+	    }
+	}
+
+	if (uhp == NULL)		/* no undo at all */
+	{
+	    if (old_curhead != NULL)
+		u_freebranch(curbuf, old_curhead, NULL);
+	    curbuf->b_u_synced = FALSE;
+	    return OK;
+	}
+
+	uhp->uh_prev = NULL;
+	uhp->uh_next = curbuf->b_u_newhead;
+	uhp->uh_alt_next = old_curhead;
+	if (old_curhead != NULL)
+	{
+	    uhp->uh_alt_prev = old_curhead->uh_alt_prev;
+	    if (uhp->uh_alt_prev != NULL)
+		uhp->uh_alt_prev->uh_alt_next = uhp;
+	    old_curhead->uh_alt_prev = uhp;
+	    if (curbuf->b_u_oldhead == old_curhead)
+		curbuf->b_u_oldhead = uhp;
+	}
+	else
+	    uhp->uh_alt_prev = NULL;
+	if (curbuf->b_u_newhead != NULL)
+	    curbuf->b_u_newhead->uh_prev = uhp;
+
+	uhp->uh_seq = ++curbuf->b_u_seq_last;
+	curbuf->b_u_seq_cur = uhp->uh_seq;
+	uhp->uh_time = time(NULL);
+	curbuf->b_u_seq_time = uhp->uh_time + 1;
+
+	uhp->uh_walk = 0;
+	uhp->uh_entry = NULL;
+	uhp->uh_getbot_entry = NULL;
+	uhp->uh_cursor = curwin->w_cursor;	/* save cursor pos. for undo */
+#ifdef FEAT_VIRTUALEDIT
+	if (virtual_active() && curwin->w_cursor.coladd > 0)
+	    uhp->uh_cursor_vcol = getviscol();
+	else
+	    uhp->uh_cursor_vcol = -1;
+#endif
+
+	/* save changed and buffer empty flag for undo */
+	uhp->uh_flags = (curbuf->b_changed ? UH_CHANGED : 0) +
+		       ((curbuf->b_ml.ml_flags & ML_EMPTY) ? UH_EMPTYBUF : 0);
+
+	/* save named marks and Visual marks for undo */
+	mch_memmove(uhp->uh_namedm, curbuf->b_namedm, sizeof(pos_T) * NMARKS);
+#ifdef FEAT_VISUAL
+	uhp->uh_visual = curbuf->b_visual;
+#endif
+
+	curbuf->b_u_newhead = uhp;
+	if (curbuf->b_u_oldhead == NULL)
+	    curbuf->b_u_oldhead = uhp;
+	++curbuf->b_u_numhead;
+    }
+    else
+    {
+	if (p_ul < 0)		/* no undo at all */
+	    return OK;
+
+	/*
+	 * When saving a single line, and it has been saved just before, it
+	 * doesn't make sense saving it again.  Saves a lot of memory when
+	 * making lots of changes inside the same line.
+	 * This is only possible if the previous change didn't increase or
+	 * decrease the number of lines.
+	 * Check the ten last changes.  More doesn't make sense and takes too
+	 * long.
+	 */
+	if (size == 1)
+	{
+	    uep = u_get_headentry();
+	    prev_uep = NULL;
+	    for (i = 0; i < 10; ++i)
+	    {
+		if (uep == NULL)
+		    break;
+
+		/* If lines have been inserted/deleted we give up.
+		 * Also when the line was included in a multi-line save. */
+		if ((curbuf->b_u_newhead->uh_getbot_entry != uep
+			    ? (uep->ue_top + uep->ue_size + 1
+				!= (uep->ue_bot == 0
+				    ? curbuf->b_ml.ml_line_count + 1
+				    : uep->ue_bot))
+			    : uep->ue_lcount != curbuf->b_ml.ml_line_count)
+			|| (uep->ue_size > 1
+			    && top >= uep->ue_top
+			    && top + 2 <= uep->ue_top + uep->ue_size + 1))
+		    break;
+
+		/* If it's the same line we can skip saving it again. */
+		if (uep->ue_size == 1 && uep->ue_top == top)
+		{
+		    if (i > 0)
+		    {
+			/* It's not the last entry: get ue_bot for the last
+			 * entry now.  Following deleted/inserted lines go to
+			 * the re-used entry. */
+			u_getbot();
+			curbuf->b_u_synced = FALSE;
+
+			/* Move the found entry to become the last entry.  The
+			 * order of undo/redo doesn't matter for the entries
+			 * we move it over, since they don't change the line
+			 * count and don't include this line.  It does matter
+			 * for the found entry if the line count is changed by
+			 * the executed command. */
+			prev_uep->ue_next = uep->ue_next;
+			uep->ue_next = curbuf->b_u_newhead->uh_entry;
+			curbuf->b_u_newhead->uh_entry = uep;
+		    }
+
+		    /* The executed command may change the line count. */
+		    if (newbot != 0)
+			uep->ue_bot = newbot;
+		    else if (bot > curbuf->b_ml.ml_line_count)
+			uep->ue_bot = 0;
+		    else
+		    {
+			uep->ue_lcount = curbuf->b_ml.ml_line_count;
+			curbuf->b_u_newhead->uh_getbot_entry = uep;
+		    }
+		    return OK;
+		}
+		prev_uep = uep;
+		uep = uep->ue_next;
+	    }
+	}
+
+	/* find line number for ue_bot for previous u_save() */
+	u_getbot();
+    }
+
+#if !defined(UNIX) && !defined(DJGPP) && !defined(WIN32) && !defined(__EMX__)
+	/*
+	 * With Amiga and MSDOS 16 bit we can't handle big undo's, because
+	 * then u_alloc_line would have to allocate a block larger than 32K
+	 */
+    if (size >= 8000)
+	goto nomem;
+#endif
+
+    /*
+     * add lines in front of entry list
+     */
+    uep = (u_entry_T *)U_ALLOC_LINE((unsigned)sizeof(u_entry_T));
+    if (uep == NULL)
+	goto nomem;
+
+    uep->ue_size = size;
+    uep->ue_top = top;
+    if (newbot != 0)
+	uep->ue_bot = newbot;
+    /*
+     * Use 0 for ue_bot if bot is below last line.
+     * Otherwise we have to compute ue_bot later.
+     */
+    else if (bot > curbuf->b_ml.ml_line_count)
+	uep->ue_bot = 0;
+    else
+    {
+	uep->ue_lcount = curbuf->b_ml.ml_line_count;
+	curbuf->b_u_newhead->uh_getbot_entry = uep;
+    }
+
+    if (size > 0)
+    {
+	if ((uep->ue_array = (char_u **)U_ALLOC_LINE(
+				(unsigned)(sizeof(char_u *) * size))) == NULL)
+	{
+	    u_freeentry(uep, 0L);
+	    goto nomem;
+	}
+	for (i = 0, lnum = top + 1; i < size; ++i)
+	{
+	    fast_breakcheck();
+	    if (got_int)
+	    {
+		u_freeentry(uep, i);
+		return FAIL;
+	    }
+	    if ((uep->ue_array[i] = u_save_line(lnum++)) == NULL)
+	    {
+		u_freeentry(uep, i);
+		goto nomem;
+	    }
+	}
+    }
+    else
+	uep->ue_array = NULL;
+    uep->ue_next = curbuf->b_u_newhead->uh_entry;
+    curbuf->b_u_newhead->uh_entry = uep;
+    curbuf->b_u_synced = FALSE;
+    undo_undoes = FALSE;
+
+    return OK;
+
+nomem:
+    msg_silent = 0;	/* must display the prompt */
+    if (ask_yesno((char_u *)_("No undo possible; continue anyway"), TRUE)
+								       == 'y')
+    {
+	undo_off = TRUE;	    /* will be reset when character typed */
+	return OK;
+    }
+    do_outofmem_msg((long_u)0);
+    return FAIL;
+}
+
+/*
+ * If 'cpoptions' contains 'u': Undo the previous undo or redo (vi compatible).
+ * If 'cpoptions' does not contain 'u': Always undo.
+ */
+    void
+u_undo(count)
+    int count;
+{
+    /*
+     * If we get an undo command while executing a macro, we behave like the
+     * original vi. If this happens twice in one macro the result will not
+     * be compatible.
+     */
+    if (curbuf->b_u_synced == FALSE)
+    {
+	u_sync(TRUE);
+	count = 1;
+    }
+
+    if (vim_strchr(p_cpo, CPO_UNDO) == NULL)
+	undo_undoes = TRUE;
+    else
+	undo_undoes = !undo_undoes;
+    u_doit(count);
+}
+
+/*
+ * If 'cpoptions' contains 'u': Repeat the previous undo or redo.
+ * If 'cpoptions' does not contain 'u': Always redo.
+ */
+    void
+u_redo(count)
+    int count;
+{
+    if (vim_strchr(p_cpo, CPO_UNDO) == NULL)
+	undo_undoes = FALSE;
+    u_doit(count);
+}
+
+/*
+ * Undo or redo, depending on 'undo_undoes', 'count' times.
+ */
+    static void
+u_doit(startcount)
+    int startcount;
+{
+    int count = startcount;
+
+    if (!undo_allowed())
+	return;
+
+    u_newcount = 0;
+    u_oldcount = 0;
+    if (curbuf->b_ml.ml_flags & ML_EMPTY)
+	u_oldcount = -1;
+    while (count--)
+    {
+	if (undo_undoes)
+	{
+	    if (curbuf->b_u_curhead == NULL)		/* first undo */
+		curbuf->b_u_curhead = curbuf->b_u_newhead;
+	    else if (p_ul > 0)				/* multi level undo */
+		/* get next undo */
+		curbuf->b_u_curhead = curbuf->b_u_curhead->uh_next;
+	    /* nothing to undo */
+	    if (curbuf->b_u_numhead == 0 || curbuf->b_u_curhead == NULL)
+	    {
+		/* stick curbuf->b_u_curhead at end */
+		curbuf->b_u_curhead = curbuf->b_u_oldhead;
+		beep_flush();
+		if (count == startcount - 1)
+		{
+		    MSG(_("Already at oldest change"));
+		    return;
+		}
+		break;
+	    }
+
+	    u_undoredo(TRUE);
+	}
+	else
+	{
+	    if (curbuf->b_u_curhead == NULL || p_ul <= 0)
+	    {
+		beep_flush();	/* nothing to redo */
+		if (count == startcount - 1)
+		{
+		    MSG(_("Already at newest change"));
+		    return;
+		}
+		break;
+	    }
+
+	    u_undoredo(FALSE);
+
+	    /* Advance for next redo.  Set "newhead" when at the end of the
+	     * redoable changes. */
+	    if (curbuf->b_u_curhead->uh_prev == NULL)
+		curbuf->b_u_newhead = curbuf->b_u_curhead;
+	    curbuf->b_u_curhead = curbuf->b_u_curhead->uh_prev;
+	}
+    }
+    u_undo_end(undo_undoes, FALSE);
+}
+
+static int lastmark = 0;
+
+/*
+ * Undo or redo over the timeline.
+ * When "step" is negative go back in time, otherwise goes forward in time.
+ * When "sec" is FALSE make "step" steps, when "sec" is TRUE use "step" as
+ * seconds.
+ * When "absolute" is TRUE use "step" as the sequence number to jump to.
+ * "sec" must be FALSE then.
+ */
+    void
+undo_time(step, sec, absolute)
+    long	step;
+    int		sec;
+    int		absolute;
+{
+    long	    target;
+    long	    closest;
+    long	    closest_start;
+    long	    closest_seq = 0;
+    long	    val;
+    u_header_T	    *uhp;
+    u_header_T	    *last;
+    int		    mark;
+    int		    nomark;
+    int		    round;
+    int		    dosec = sec;
+    int		    above = FALSE;
+    int		    did_undo = TRUE;
+
+    /* First make sure the current undoable change is synced. */
+    if (curbuf->b_u_synced == FALSE)
+	u_sync(TRUE);
+
+    u_newcount = 0;
+    u_oldcount = 0;
+    if (curbuf->b_ml.ml_flags & ML_EMPTY)
+	u_oldcount = -1;
+
+    /* "target" is the node below which we want to be.
+     * Init "closest" to a value we can't reach. */
+    if (absolute)
+    {
+	target = step;
+	closest = -1;
+    }
+    else
+    {
+	/* When doing computations with time_t subtract starttime, because
+	 * time_t converted to a long may result in a wrong number. */
+	if (sec)
+	    target = (long)(curbuf->b_u_seq_time - starttime) + step;
+	else
+	    target = curbuf->b_u_seq_cur + step;
+	if (step < 0)
+	{
+	    if (target < 0)
+		target = 0;
+	    closest = -1;
+	}
+	else
+	{
+	    if (sec)
+		closest = (long)(time(NULL) - starttime + 1);
+	    else
+		closest = curbuf->b_u_seq_last + 2;
+	    if (target >= closest)
+		target = closest - 1;
+	}
+    }
+    closest_start = closest;
+    closest_seq = curbuf->b_u_seq_cur;
+
+    /*
+     * May do this twice:
+     * 1. Search for "target", update "closest" to the best match found.
+     * 2. If "target" not found search for "closest".
+     *
+     * When using the closest time we use the sequence number in the second
+     * round, because there may be several entries with the same time.
+     */
+    for (round = 1; round <= 2; ++round)
+    {
+	/* Find the path from the current state to where we want to go.  The
+	 * desired state can be anywhere in the undo tree, need to go all over
+	 * it.  We put "nomark" in uh_walk where we have been without success,
+	 * "mark" where it could possibly be. */
+	mark = ++lastmark;
+	nomark = ++lastmark;
+
+	if (curbuf->b_u_curhead == NULL)	/* at leaf of the tree */
+	    uhp = curbuf->b_u_newhead;
+	else
+	    uhp = curbuf->b_u_curhead;
+
+	while (uhp != NULL)
+	{
+	    uhp->uh_walk = mark;
+	    val = (long)(dosec ? (uhp->uh_time - starttime) : uhp->uh_seq);
+
+	    if (round == 1)
+	    {
+		/* Remember the header that is closest to the target.
+		 * It must be at least in the right direction (checked with
+		 * "b_u_seq_cur").  When the timestamp is equal find the
+		 * highest/lowest sequence number. */
+		if ((step < 0 ? uhp->uh_seq <= curbuf->b_u_seq_cur
+			      : uhp->uh_seq > curbuf->b_u_seq_cur)
+			&& ((dosec && val == closest)
+			    ? (step < 0
+				? uhp->uh_seq < closest_seq
+				: uhp->uh_seq > closest_seq)
+			    : closest == closest_start
+				|| (val > target
+				    ? (closest > target
+					? val - target <= closest - target
+					: val - target <= target - closest)
+				    : (closest > target
+					? target - val <= closest - target
+					: target - val <= target - closest))))
+		{
+		    closest = val;
+		    closest_seq = uhp->uh_seq;
+		}
+	    }
+
+	    /* Quit searching when we found a match.  But when searching for a
+	     * time we need to continue looking for the best uh_seq. */
+	    if (target == val && !dosec)
+		break;
+
+	    /* go down in the tree if we haven't been there */
+	    if (uhp->uh_prev != NULL && uhp->uh_prev->uh_walk != nomark
+					     && uhp->uh_prev->uh_walk != mark)
+		uhp = uhp->uh_prev;
+
+	    /* go to alternate branch if we haven't been there */
+	    else if (uhp->uh_alt_next != NULL
+		    && uhp->uh_alt_next->uh_walk != nomark
+		    && uhp->uh_alt_next->uh_walk != mark)
+		uhp = uhp->uh_alt_next;
+
+	    /* go up in the tree if we haven't been there and we are at the
+	     * start of alternate branches */
+	    else if (uhp->uh_next != NULL && uhp->uh_alt_prev == NULL
+		    && uhp->uh_next->uh_walk != nomark
+		    && uhp->uh_next->uh_walk != mark)
+	    {
+		/* If still at the start we don't go through this change. */
+		if (uhp == curbuf->b_u_curhead)
+		    uhp->uh_walk = nomark;
+		uhp = uhp->uh_next;
+	    }
+
+	    else
+	    {
+		/* need to backtrack; mark this node as useless */
+		uhp->uh_walk = nomark;
+		if (uhp->uh_alt_prev != NULL)
+		    uhp = uhp->uh_alt_prev;
+		else
+		    uhp = uhp->uh_next;
+	    }
+	}
+
+	if (uhp != NULL)    /* found it */
+	    break;
+
+	if (absolute)
+	{
+	    EMSGN(_("Undo number %ld not found"), step);
+	    return;
+	}
+
+	if (closest == closest_start)
+	{
+	    if (step < 0)
+		MSG(_("Already at oldest change"));
+	    else
+		MSG(_("Already at newest change"));
+	    return;
+	}
+
+	target = closest_seq;
+	dosec = FALSE;
+	if (step < 0)
+	    above = TRUE;	/* stop above the header */
+    }
+
+    /* If we found it: Follow the path to go to where we want to be. */
+    if (uhp != NULL)
+    {
+	/*
+	 * First go up the tree as much as needed.
+	 */
+	for (;;)
+	{
+	    uhp = curbuf->b_u_curhead;
+	    if (uhp == NULL)
+		uhp = curbuf->b_u_newhead;
+	    else
+		uhp = uhp->uh_next;
+	    if (uhp == NULL || uhp->uh_walk != mark
+					 || (uhp->uh_seq == target && !above))
+		break;
+	    curbuf->b_u_curhead = uhp;
+	    u_undoredo(TRUE);
+	    uhp->uh_walk = nomark;	/* don't go back down here */
+	}
+
+	/*
+	 * And now go down the tree (redo), branching off where needed.
+	 */
+	uhp = curbuf->b_u_curhead;
+	while (uhp != NULL)
+	{
+	    /* Go back to the first branch with a mark. */
+	    while (uhp->uh_alt_prev != NULL
+					&& uhp->uh_alt_prev->uh_walk == mark)
+		uhp = uhp->uh_alt_prev;
+
+	    /* Find the last branch with a mark, that's the one. */
+	    last = uhp;
+	    while (last->uh_alt_next != NULL
+					&& last->uh_alt_next->uh_walk == mark)
+		last = last->uh_alt_next;
+	    if (last != uhp)
+	    {
+		/* Make the used branch the first entry in the list of
+		 * alternatives to make "u" and CTRL-R take this branch. */
+		while (uhp->uh_alt_prev != NULL)
+		    uhp = uhp->uh_alt_prev;
+		if (last->uh_alt_next != NULL)
+		    last->uh_alt_next->uh_alt_prev = last->uh_alt_prev;
+		last->uh_alt_prev->uh_alt_next = last->uh_alt_next;
+		last->uh_alt_prev = NULL;
+		last->uh_alt_next = uhp;
+		uhp->uh_alt_prev = last;
+
+		uhp = last;
+		if (uhp->uh_next != NULL)
+		    uhp->uh_next->uh_prev = uhp;
+	    }
+	    curbuf->b_u_curhead = uhp;
+
+	    if (uhp->uh_walk != mark)
+		break;	    /* must have reached the target */
+
+	    /* Stop when going backwards in time and didn't find the exact
+	     * header we were looking for. */
+	    if (uhp->uh_seq == target && above)
+	    {
+		curbuf->b_u_seq_cur = target - 1;
+		break;
+	    }
+
+	    u_undoredo(FALSE);
+
+	    /* Advance "curhead" to below the header we last used.  If it
+	     * becomes NULL then we need to set "newhead" to this leaf. */
+	    if (uhp->uh_prev == NULL)
+		curbuf->b_u_newhead = uhp;
+	    curbuf->b_u_curhead = uhp->uh_prev;
+	    did_undo = FALSE;
+
+	    if (uhp->uh_seq == target)	/* found it! */
+		break;
+
+	    uhp = uhp->uh_prev;
+	    if (uhp == NULL || uhp->uh_walk != mark)
+	    {
+		/* Need to redo more but can't find it... */
+		EMSG2(_(e_intern2), "undo_time()");
+		break;
+	    }
+	}
+    }
+    u_undo_end(did_undo, absolute);
+}
+
+/*
+ * u_undoredo: common code for undo and redo
+ *
+ * The lines in the file are replaced by the lines in the entry list at
+ * curbuf->b_u_curhead. The replaced lines in the file are saved in the entry
+ * list for the next undo/redo.
+ *
+ * When "undo" is TRUE we go up in the tree, when FALSE we go down.
+ */
+    static void
+u_undoredo(undo)
+    int		undo;
+{
+    char_u	**newarray = NULL;
+    linenr_T	oldsize;
+    linenr_T	newsize;
+    linenr_T	top, bot;
+    linenr_T	lnum;
+    linenr_T	newlnum = MAXLNUM;
+    long	i;
+    u_entry_T	*uep, *nuep;
+    u_entry_T	*newlist = NULL;
+    int		old_flags;
+    int		new_flags;
+    pos_T	namedm[NMARKS];
+#ifdef FEAT_VISUAL
+    visualinfo_T visualinfo;
+#endif
+    int		empty_buffer;		    /* buffer became empty */
+    u_header_T	*curhead = curbuf->b_u_curhead;
+
+    old_flags = curhead->uh_flags;
+    new_flags = (curbuf->b_changed ? UH_CHANGED : 0) +
+	       ((curbuf->b_ml.ml_flags & ML_EMPTY) ? UH_EMPTYBUF : 0);
+    setpcmark();
+
+    /*
+     * save marks before undo/redo
+     */
+    mch_memmove(namedm, curbuf->b_namedm, sizeof(pos_T) * NMARKS);
+#ifdef FEAT_VISUAL
+    visualinfo = curbuf->b_visual;
+#endif
+    curbuf->b_op_start.lnum = curbuf->b_ml.ml_line_count;
+    curbuf->b_op_start.col = 0;
+    curbuf->b_op_end.lnum = 0;
+    curbuf->b_op_end.col = 0;
+
+    for (uep = curhead->uh_entry; uep != NULL; uep = nuep)
+    {
+	top = uep->ue_top;
+	bot = uep->ue_bot;
+	if (bot == 0)
+	    bot = curbuf->b_ml.ml_line_count + 1;
+	if (top > curbuf->b_ml.ml_line_count || top >= bot
+				      || bot > curbuf->b_ml.ml_line_count + 1)
+	{
+	    EMSG(_("E438: u_undo: line numbers wrong"));
+	    changed();		/* don't want UNCHANGED now */
+	    return;
+	}
+
+	oldsize = bot - top - 1;    /* number of lines before undo */
+	newsize = uep->ue_size;	    /* number of lines after undo */
+
+	if (top < newlnum)
+	{
+	    /* If the saved cursor is somewhere in this undo block, move it to
+	     * the remembered position.  Makes "gwap" put the cursor back
+	     * where it was. */
+	    lnum = curhead->uh_cursor.lnum;
+	    if (lnum >= top && lnum <= top + newsize + 1)
+	    {
+		curwin->w_cursor = curhead->uh_cursor;
+		newlnum = curwin->w_cursor.lnum - 1;
+	    }
+	    else
+	    {
+		/* Use the first line that actually changed.  Avoids that
+		 * undoing auto-formatting puts the cursor in the previous
+		 * line. */
+		for (i = 0; i < newsize && i < oldsize; ++i)
+		    if (STRCMP(uep->ue_array[i], ml_get(top + 1 + i)) != 0)
+			break;
+		if (i == newsize && newlnum == MAXLNUM && uep->ue_next == NULL)
+		{
+		    newlnum = top;
+		    curwin->w_cursor.lnum = newlnum + 1;
+		}
+		else if (i < newsize)
+		{
+		    newlnum = top + i;
+		    curwin->w_cursor.lnum = newlnum + 1;
+		}
+	    }
+	}
+
+	empty_buffer = FALSE;
+
+	/* delete the lines between top and bot and save them in newarray */
+	if (oldsize > 0)
+	{
+	    if ((newarray = (char_u **)U_ALLOC_LINE(
+			    (unsigned)(sizeof(char_u *) * oldsize))) == NULL)
+	    {
+		do_outofmem_msg((long_u)(sizeof(char_u *) * oldsize));
+		/*
+		 * We have messed up the entry list, repair is impossible.
+		 * we have to free the rest of the list.
+		 */
+		while (uep != NULL)
+		{
+		    nuep = uep->ue_next;
+		    u_freeentry(uep, uep->ue_size);
+		    uep = nuep;
+		}
+		break;
+	    }
+	    /* delete backwards, it goes faster in most cases */
+	    for (lnum = bot - 1, i = oldsize; --i >= 0; --lnum)
+	    {
+		/* what can we do when we run out of memory? */
+		if ((newarray[i] = u_save_line(lnum)) == NULL)
+		    do_outofmem_msg((long_u)0);
+		/* remember we deleted the last line in the buffer, and a
+		 * dummy empty line will be inserted */
+		if (curbuf->b_ml.ml_line_count == 1)
+		    empty_buffer = TRUE;
+		ml_delete(lnum, FALSE);
+	    }
+	}
+	else
+	    newarray = NULL;
+
+	/* insert the lines in u_array between top and bot */
+	if (newsize)
+	{
+	    for (lnum = top, i = 0; i < newsize; ++i, ++lnum)
+	    {
+		/*
+		 * If the file is empty, there is an empty line 1 that we
+		 * should get rid of, by replacing it with the new line
+		 */
+		if (empty_buffer && lnum == 0)
+		    ml_replace((linenr_T)1, uep->ue_array[i], TRUE);
+		else
+		    ml_append(lnum, uep->ue_array[i], (colnr_T)0, FALSE);
+		U_FREE_LINE(uep->ue_array[i]);
+	    }
+	    U_FREE_LINE((char_u *)uep->ue_array);
+	}
+
+	/* adjust marks */
+	if (oldsize != newsize)
+	{
+	    mark_adjust(top + 1, top + oldsize, (long)MAXLNUM,
+					       (long)newsize - (long)oldsize);
+	    if (curbuf->b_op_start.lnum > top + oldsize)
+		curbuf->b_op_start.lnum += newsize - oldsize;
+	    if (curbuf->b_op_end.lnum > top + oldsize)
+		curbuf->b_op_end.lnum += newsize - oldsize;
+	}
+
+	changed_lines(top + 1, 0, bot, newsize - oldsize);
+
+	/* set '[ and '] mark */
+	if (top + 1 < curbuf->b_op_start.lnum)
+	    curbuf->b_op_start.lnum = top + 1;
+	if (newsize == 0 && top + 1 > curbuf->b_op_end.lnum)
+	    curbuf->b_op_end.lnum = top + 1;
+	else if (top + newsize > curbuf->b_op_end.lnum)
+	    curbuf->b_op_end.lnum = top + newsize;
+
+	u_newcount += newsize;
+	u_oldcount += oldsize;
+	uep->ue_size = oldsize;
+	uep->ue_array = newarray;
+	uep->ue_bot = top + newsize + 1;
+
+	/*
+	 * insert this entry in front of the new entry list
+	 */
+	nuep = uep->ue_next;
+	uep->ue_next = newlist;
+	newlist = uep;
+    }
+
+    curhead->uh_entry = newlist;
+    curhead->uh_flags = new_flags;
+    if ((old_flags & UH_EMPTYBUF) && bufempty())
+	curbuf->b_ml.ml_flags |= ML_EMPTY;
+    if (old_flags & UH_CHANGED)
+	changed();
+    else
+#ifdef FEAT_NETBEANS_INTG
+	/* per netbeans undo rules, keep it as modified */
+	if (!isNetbeansModified(curbuf))
+#endif
+	unchanged(curbuf, FALSE);
+
+    /*
+     * restore marks from before undo/redo
+     */
+    for (i = 0; i < NMARKS; ++i)
+	if (curhead->uh_namedm[i].lnum != 0)
+	{
+	    curbuf->b_namedm[i] = curhead->uh_namedm[i];
+	    curhead->uh_namedm[i] = namedm[i];
+	}
+#ifdef FEAT_VISUAL
+    if (curhead->uh_visual.vi_start.lnum != 0)
+    {
+	curbuf->b_visual = curhead->uh_visual;
+	curhead->uh_visual = visualinfo;
+    }
+#endif
+
+    /*
+     * If the cursor is only off by one line, put it at the same position as
+     * before starting the change (for the "o" command).
+     * Otherwise the cursor should go to the first undone line.
+     */
+    if (curhead->uh_cursor.lnum + 1 == curwin->w_cursor.lnum
+						 && curwin->w_cursor.lnum > 1)
+	--curwin->w_cursor.lnum;
+    if (curhead->uh_cursor.lnum == curwin->w_cursor.lnum)
+    {
+	curwin->w_cursor.col = curhead->uh_cursor.col;
+#ifdef FEAT_VIRTUALEDIT
+	if (virtual_active() && curhead->uh_cursor_vcol >= 0)
+	    coladvance((colnr_T)curhead->uh_cursor_vcol);
+	else
+	    curwin->w_cursor.coladd = 0;
+#endif
+    }
+    else if (curwin->w_cursor.lnum <= curbuf->b_ml.ml_line_count)
+	beginline(BL_SOL | BL_FIX);
+    else
+    {
+	/* We get here with the current cursor line being past the end (eg
+	 * after adding lines at the end of the file, and then undoing it).
+	 * check_cursor() will move the cursor to the last line.  Move it to
+	 * the first column here. */
+	curwin->w_cursor.col = 0;
+#ifdef FEAT_VIRTUALEDIT
+	curwin->w_cursor.coladd = 0;
+#endif
+    }
+
+    /* Make sure the cursor is on an existing line and column. */
+    check_cursor();
+
+    /* Remember where we are for "g-" and ":earlier 10s". */
+    curbuf->b_u_seq_cur = curhead->uh_seq;
+    if (undo)
+	/* We are below the previous undo.  However, to make ":earlier 1s"
+	 * work we compute this as being just above the just undone change. */
+	--curbuf->b_u_seq_cur;
+
+    /* The timestamp can be the same for multiple changes, just use the one of
+     * the undone/redone change. */
+    curbuf->b_u_seq_time = curhead->uh_time;
+}
+
+/*
+ * If we deleted or added lines, report the number of less/more lines.
+ * Otherwise, report the number of changes (this may be incorrect
+ * in some cases, but it's better than nothing).
+ */
+    static void
+u_undo_end(did_undo, absolute)
+    int		did_undo;	/* just did an undo */
+    int		absolute;	/* used ":undo N" */
+{
+    char	*msgstr;
+    u_header_T	*uhp;
+    char_u	msgbuf[80];
+
+#ifdef FEAT_FOLDING
+    if ((fdo_flags & FDO_UNDO) && KeyTyped)
+	foldOpenCursor();
+#endif
+
+    if (global_busy	    /* no messages now, wait until global is finished */
+	    || !messaging())  /* 'lazyredraw' set, don't do messages now */
+	return;
+
+    if (curbuf->b_ml.ml_flags & ML_EMPTY)
+	--u_newcount;
+
+    u_oldcount -= u_newcount;
+    if (u_oldcount == -1)
+	msgstr = N_("more line");
+    else if (u_oldcount < 0)
+	msgstr = N_("more lines");
+    else if (u_oldcount == 1)
+	msgstr = N_("line less");
+    else if (u_oldcount > 1)
+	msgstr = N_("fewer lines");
+    else
+    {
+	u_oldcount = u_newcount;
+	if (u_newcount == 1)
+	    msgstr = N_("change");
+	else
+	    msgstr = N_("changes");
+    }
+
+    if (curbuf->b_u_curhead != NULL)
+    {
+	/* For ":undo N" we prefer a "after #N" message. */
+	if (absolute && curbuf->b_u_curhead->uh_next != NULL)
+	{
+	    uhp = curbuf->b_u_curhead->uh_next;
+	    did_undo = FALSE;
+	}
+	else if (did_undo)
+	    uhp = curbuf->b_u_curhead;
+	else
+	    uhp = curbuf->b_u_curhead->uh_next;
+    }
+    else
+	uhp = curbuf->b_u_newhead;
+
+    if (uhp == NULL)
+	*msgbuf = NUL;
+    else
+	u_add_time(msgbuf, sizeof(msgbuf), uhp->uh_time);
+
+    smsg((char_u *)_("%ld %s; %s #%ld  %s"),
+	    u_oldcount < 0 ? -u_oldcount : u_oldcount,
+	    _(msgstr),
+	    did_undo ? _("before") : _("after"),
+	    uhp == NULL ? 0L : uhp->uh_seq,
+	    msgbuf);
+}
+
+/*
+ * u_sync: stop adding to the current entry list
+ */
+    void
+u_sync(force)
+    int	    force;	/* Also sync when no_u_sync is set. */
+{
+    /* Skip it when already synced or syncing is disabled. */
+    if (curbuf->b_u_synced || (!force && no_u_sync > 0))
+	return;
+#if defined(FEAT_XIM) && defined(FEAT_GUI_GTK)
+    if (im_is_preediting())
+	return;		    /* XIM is busy, don't break an undo sequence */
+#endif
+    if (p_ul < 0)
+	curbuf->b_u_synced = TRUE;  /* no entries, nothing to do */
+    else
+    {
+	u_getbot();		    /* compute ue_bot of previous u_save */
+	curbuf->b_u_curhead = NULL;
+    }
+}
+
+/*
+ * ":undolist": List the leafs of the undo tree
+ */
+/*ARGSUSED*/
+    void
+ex_undolist(eap)
+    exarg_T *eap;
+{
+    garray_T	ga;
+    u_header_T	*uhp;
+    int		mark;
+    int		nomark;
+    int		changes = 1;
+    int		i;
+
+    /*
+     * 1: walk the tree to find all leafs, put the info in "ga".
+     * 2: sort the lines
+     * 3: display the list
+     */
+    mark = ++lastmark;
+    nomark = ++lastmark;
+    ga_init2(&ga, (int)sizeof(char *), 20);
+
+    uhp = curbuf->b_u_oldhead;
+    while (uhp != NULL)
+    {
+	if (uhp->uh_prev == NULL && uhp->uh_walk != nomark
+						      && uhp->uh_walk != mark)
+	{
+	    if (ga_grow(&ga, 1) == FAIL)
+		break;
+	    vim_snprintf((char *)IObuff, IOSIZE, "%6ld %7ld  ",
+							uhp->uh_seq, changes);
+	    u_add_time(IObuff + STRLEN(IObuff), IOSIZE - STRLEN(IObuff),
+								uhp->uh_time);
+	    ((char_u **)(ga.ga_data))[ga.ga_len++] = vim_strsave(IObuff);
+	}
+
+	uhp->uh_walk = mark;
+
+	/* go down in the tree if we haven't been there */
+	if (uhp->uh_prev != NULL && uhp->uh_prev->uh_walk != nomark
+					 && uhp->uh_prev->uh_walk != mark)
+	{
+	    uhp = uhp->uh_prev;
+	    ++changes;
+	}
+
+	/* go to alternate branch if we haven't been there */
+	else if (uhp->uh_alt_next != NULL
+		&& uhp->uh_alt_next->uh_walk != nomark
+		&& uhp->uh_alt_next->uh_walk != mark)
+	    uhp = uhp->uh_alt_next;
+
+	/* go up in the tree if we haven't been there and we are at the
+	 * start of alternate branches */
+	else if (uhp->uh_next != NULL && uhp->uh_alt_prev == NULL
+		&& uhp->uh_next->uh_walk != nomark
+		&& uhp->uh_next->uh_walk != mark)
+	{
+	    uhp = uhp->uh_next;
+	    --changes;
+	}
+
+	else
+	{
+	    /* need to backtrack; mark this node as done */
+	    uhp->uh_walk = nomark;
+	    if (uhp->uh_alt_prev != NULL)
+		uhp = uhp->uh_alt_prev;
+	    else
+	    {
+		uhp = uhp->uh_next;
+		--changes;
+	    }
+	}
+    }
+
+    if (ga.ga_len == 0)
+	MSG(_("Nothing to undo"));
+    else
+    {
+	sort_strings((char_u **)ga.ga_data, ga.ga_len);
+
+	msg_start();
+	msg_puts_attr((char_u *)_("number changes  time"), hl_attr(HLF_T));
+	for (i = 0; i < ga.ga_len && !got_int; ++i)
+	{
+	    msg_putchar('\n');
+	    if (got_int)
+		break;
+	    msg_puts(((char_u **)ga.ga_data)[i]);
+	}
+	msg_end();
+
+	ga_clear_strings(&ga);
+    }
+}
+
+/*
+ * Put the timestamp of an undo header in "buf[buflen]" in a nice format.
+ */
+    static void
+u_add_time(buf, buflen, tt)
+    char_u	*buf;
+    size_t	buflen;
+    time_t	tt;
+{
+#ifdef HAVE_STRFTIME
+    struct tm	*curtime;
+
+    if (time(NULL) - tt >= 100)
+    {
+	curtime = localtime(&tt);
+	(void)strftime((char *)buf, buflen, "%H:%M:%S", curtime);
+    }
+    else
+#endif
+	vim_snprintf((char *)buf, buflen, _("%ld seconds ago"),
+						     (long)(time(NULL) - tt));
+}
+
+/*
+ * ":undojoin": continue adding to the last entry list
+ */
+/*ARGSUSED*/
+    void
+ex_undojoin(eap)
+    exarg_T *eap;
+{
+    if (curbuf->b_u_newhead == NULL)
+	return;		    /* nothing changed before */
+    if (curbuf->b_u_curhead != NULL)
+    {
+	EMSG(_("E790: undojoin is not allowed after undo"));
+	return;
+    }
+    if (!curbuf->b_u_synced)
+	return;		    /* already unsynced */
+    if (p_ul < 0)
+	return;		    /* no entries, nothing to do */
+    else
+    {
+	/* Go back to the last entry */
+	curbuf->b_u_curhead = curbuf->b_u_newhead;
+	curbuf->b_u_synced = FALSE;  /* no entries, nothing to do */
+    }
+}
+
+/*
+ * Called after writing the file and setting b_changed to FALSE.
+ * Now an undo means that the buffer is modified.
+ */
+    void
+u_unchanged(buf)
+    buf_T	*buf;
+{
+    u_unch_branch(buf->b_u_oldhead);
+    buf->b_did_warn = FALSE;
+}
+
+    static void
+u_unch_branch(uhp)
+    u_header_T	*uhp;
+{
+    u_header_T	*uh;
+
+    for (uh = uhp; uh != NULL; uh = uh->uh_prev)
+    {
+	uh->uh_flags |= UH_CHANGED;
+	if (uh->uh_alt_next != NULL)
+	    u_unch_branch(uh->uh_alt_next);	    /* recursive */
+    }
+}
+
+/*
+ * Get pointer to last added entry.
+ * If it's not valid, give an error message and return NULL.
+ */
+    static u_entry_T *
+u_get_headentry()
+{
+    if (curbuf->b_u_newhead == NULL || curbuf->b_u_newhead->uh_entry == NULL)
+    {
+	EMSG(_("E439: undo list corrupt"));
+	return NULL;
+    }
+    return curbuf->b_u_newhead->uh_entry;
+}
+
+/*
+ * u_getbot(): compute the line number of the previous u_save
+ *		It is called only when b_u_synced is FALSE.
+ */
+    static void
+u_getbot()
+{
+    u_entry_T	*uep;
+    linenr_T	extra;
+
+    uep = u_get_headentry();	/* check for corrupt undo list */
+    if (uep == NULL)
+	return;
+
+    uep = curbuf->b_u_newhead->uh_getbot_entry;
+    if (uep != NULL)
+    {
+	/*
+	 * the new ue_bot is computed from the number of lines that has been
+	 * inserted (0 - deleted) since calling u_save. This is equal to the
+	 * old line count subtracted from the current line count.
+	 */
+	extra = curbuf->b_ml.ml_line_count - uep->ue_lcount;
+	uep->ue_bot = uep->ue_top + uep->ue_size + 1 + extra;
+	if (uep->ue_bot < 1 || uep->ue_bot > curbuf->b_ml.ml_line_count)
+	{
+	    EMSG(_("E440: undo line missing"));
+	    uep->ue_bot = uep->ue_top + 1;  /* assume all lines deleted, will
+					     * get all the old lines back
+					     * without deleting the current
+					     * ones */
+	}
+
+	curbuf->b_u_newhead->uh_getbot_entry = NULL;
+    }
+
+    curbuf->b_u_synced = TRUE;
+}
+
+/*
+ * Free one header and its entry list and adjust the pointers.
+ */
+    static void
+u_freeheader(buf, uhp, uhpp)
+    buf_T	    *buf;
+    u_header_T	    *uhp;
+    u_header_T	    **uhpp;	/* if not NULL reset when freeing this header */
+{
+    /* When there is an alternate redo list free that branch completely,
+     * because we can never go there. */
+    if (uhp->uh_alt_next != NULL)
+	u_freebranch(buf, uhp->uh_alt_next, uhpp);
+
+    if (uhp->uh_alt_prev != NULL)
+	uhp->uh_alt_prev->uh_alt_next = NULL;
+
+    /* Update the links in the list to remove the header. */
+    if (uhp->uh_next == NULL)
+	buf->b_u_oldhead = uhp->uh_prev;
+    else
+	uhp->uh_next->uh_prev = uhp->uh_prev;
+
+    if (uhp->uh_prev == NULL)
+	buf->b_u_newhead = uhp->uh_next;
+    else
+	uhp->uh_prev->uh_next = uhp->uh_next;
+
+    u_freeentries(buf, uhp, uhpp);
+}
+
+/*
+ * Free an alternate branch and any following alternate branches.
+ */
+    static void
+u_freebranch(buf, uhp, uhpp)
+    buf_T	    *buf;
+    u_header_T	    *uhp;
+    u_header_T	    **uhpp;	/* if not NULL reset when freeing this header */
+{
+    u_header_T	    *tofree, *next;
+
+    if (uhp->uh_alt_prev != NULL)
+	uhp->uh_alt_prev->uh_alt_next = NULL;
+
+    next = uhp;
+    while (next != NULL)
+    {
+	tofree = next;
+	if (tofree->uh_alt_next != NULL)
+	    u_freebranch(buf, tofree->uh_alt_next, uhpp);   /* recursive */
+	next = tofree->uh_prev;
+	u_freeentries(buf, tofree, uhpp);
+    }
+}
+
+/*
+ * Free all the undo entries for one header and the header itself.
+ * This means that "uhp" is invalid when returning.
+ */
+    static void
+u_freeentries(buf, uhp, uhpp)
+    buf_T	    *buf;
+    u_header_T	    *uhp;
+    u_header_T	    **uhpp;	/* if not NULL reset when freeing this header */
+{
+    u_entry_T	    *uep, *nuep;
+
+    /* Check for pointers to the header that become invalid now. */
+    if (buf->b_u_curhead == uhp)
+	buf->b_u_curhead = NULL;
+    if (uhpp != NULL && uhp == *uhpp)
+	*uhpp = NULL;
+
+    for (uep = uhp->uh_entry; uep != NULL; uep = nuep)
+    {
+	nuep = uep->ue_next;
+	u_freeentry(uep, uep->ue_size);
+    }
+
+    U_FREE_LINE((char_u *)uhp);
+    --buf->b_u_numhead;
+}
+
+/*
+ * free entry 'uep' and 'n' lines in uep->ue_array[]
+ */
+    static void
+u_freeentry(uep, n)
+    u_entry_T	*uep;
+    long	    n;
+{
+    while (n > 0)
+	U_FREE_LINE(uep->ue_array[--n]);
+    U_FREE_LINE((char_u *)uep->ue_array);
+    U_FREE_LINE((char_u *)uep);
+}
+
+/*
+ * invalidate the undo buffer; called when storage has already been released
+ */
+    void
+u_clearall(buf)
+    buf_T	*buf;
+{
+    buf->b_u_newhead = buf->b_u_oldhead = buf->b_u_curhead = NULL;
+    buf->b_u_synced = TRUE;
+    buf->b_u_numhead = 0;
+    buf->b_u_line_ptr = NULL;
+    buf->b_u_line_lnum = 0;
+}
+
+/*
+ * save the line "lnum" for the "U" command
+ */
+    void
+u_saveline(lnum)
+    linenr_T lnum;
+{
+    if (lnum == curbuf->b_u_line_lnum)	    /* line is already saved */
+	return;
+    if (lnum < 1 || lnum > curbuf->b_ml.ml_line_count) /* should never happen */
+	return;
+    u_clearline();
+    curbuf->b_u_line_lnum = lnum;
+    if (curwin->w_cursor.lnum == lnum)
+	curbuf->b_u_line_colnr = curwin->w_cursor.col;
+    else
+	curbuf->b_u_line_colnr = 0;
+    if ((curbuf->b_u_line_ptr = u_save_line(lnum)) == NULL)
+	do_outofmem_msg((long_u)0);
+}
+
+/*
+ * clear the line saved for the "U" command
+ * (this is used externally for crossing a line while in insert mode)
+ */
+    void
+u_clearline()
+{
+    if (curbuf->b_u_line_ptr != NULL)
+    {
+	U_FREE_LINE(curbuf->b_u_line_ptr);
+	curbuf->b_u_line_ptr = NULL;
+	curbuf->b_u_line_lnum = 0;
+    }
+}
+
+/*
+ * Implementation of the "U" command.
+ * Differentiation from vi: "U" can be undone with the next "U".
+ * We also allow the cursor to be in another line.
+ */
+    void
+u_undoline()
+{
+    colnr_T t;
+    char_u  *oldp;
+
+    if (undo_off)
+	return;
+
+    if (curbuf->b_u_line_ptr == NULL ||
+			curbuf->b_u_line_lnum > curbuf->b_ml.ml_line_count)
+    {
+	beep_flush();
+	return;
+    }
+	/* first save the line for the 'u' command */
+    if (u_savecommon(curbuf->b_u_line_lnum - 1,
+				curbuf->b_u_line_lnum + 1, (linenr_T)0) == FAIL)
+	return;
+    oldp = u_save_line(curbuf->b_u_line_lnum);
+    if (oldp == NULL)
+    {
+	do_outofmem_msg((long_u)0);
+	return;
+    }
+    ml_replace(curbuf->b_u_line_lnum, curbuf->b_u_line_ptr, TRUE);
+    changed_bytes(curbuf->b_u_line_lnum, 0);
+    U_FREE_LINE(curbuf->b_u_line_ptr);
+    curbuf->b_u_line_ptr = oldp;
+
+    t = curbuf->b_u_line_colnr;
+    if (curwin->w_cursor.lnum == curbuf->b_u_line_lnum)
+	curbuf->b_u_line_colnr = curwin->w_cursor.col;
+    curwin->w_cursor.col = t;
+    curwin->w_cursor.lnum = curbuf->b_u_line_lnum;
+}
+
+/*
+ * There are two implementations of the memory management for undo:
+ * 1. Use the standard malloc()/free() functions.
+ *    This should be fast for allocating memory, but when a buffer is
+ *    abandoned every single allocated chunk must be freed, which may be slow.
+ * 2. Allocate larger blocks of memory and keep track of chunks ourselves.
+ *    This is fast for abandoning, but the use of linked lists is slow for
+ *    finding a free chunk.  Esp. when a lot of lines are changed or deleted.
+ * A bit of profiling showed that the first method is faster, especially when
+ * making a large number of changes, under the condition that malloc()/free()
+ * is implemented efficiently.
+ */
+#ifdef U_USE_MALLOC
+/*
+ * Version of undo memory allocation using malloc()/free()
+ *
+ * U_FREE_LINE() and U_ALLOC_LINE() are macros that invoke vim_free() and
+ * lalloc() directly.
+ */
+
+/*
+ * Free all allocated memory blocks for the buffer 'buf'.
+ */
+    void
+u_blockfree(buf)
+    buf_T	*buf;
+{
+    while (buf->b_u_oldhead != NULL)
+	u_freeheader(buf, buf->b_u_oldhead, NULL);
+    U_FREE_LINE(buf->b_u_line_ptr);
+}
+
+#else
+/*
+ * Storage allocation for the undo lines and blocks of the current file.
+ * Version where Vim keeps track of the available memory.
+ */
+
+/*
+ * Memory is allocated in relatively large blocks. These blocks are linked
+ * in the allocated block list, headed by curbuf->b_block_head. They are all
+ * freed when abandoning a file, so we don't have to free every single line.
+ * The list is kept sorted on memory address.
+ * block_alloc() allocates a block.
+ * m_blockfree() frees all blocks.
+ *
+ * The available chunks of memory are kept in free chunk lists. There is
+ * one free list for each block of allocated memory. The list is kept sorted
+ * on memory address.
+ * u_alloc_line() gets a chunk from the free lists.
+ * u_free_line() returns a chunk to the free lists.
+ * curbuf->b_m_search points to the chunk before the chunk that was
+ * freed/allocated the last time.
+ * curbuf->b_mb_current points to the b_head where curbuf->b_m_search
+ * points into the free list.
+ *
+ *
+ *  b_block_head     /---> block #1	/---> block #2
+ *	 mb_next ---/	    mb_next ---/       mb_next ---> NULL
+ *	 mb_info	    mb_info	       mb_info
+ *	    |		       |		  |
+ *	    V		       V		  V
+ *	  NULL		free chunk #1.1      free chunk #2.1
+ *			       |		  |
+ *			       V		  V
+ *			free chunk #1.2		 NULL
+ *			       |
+ *			       V
+ *			      NULL
+ *
+ * When a single free chunk list would have been used, it could take a lot
+ * of time in u_free_line() to find the correct place to insert a chunk in the
+ * free list. The single free list would become very long when many lines are
+ * changed (e.g. with :%s/^M$//).
+ */
+
+ /*
+  * this blocksize is used when allocating new lines
+  */
+#define MEMBLOCKSIZE 2044
+
+/*
+ * The size field contains the size of the chunk, including the size field
+ * itself.
+ *
+ * When the chunk is not in-use it is preceded with the m_info structure.
+ * The m_next field links it in one of the free chunk lists.
+ *
+ * On most unix systems structures have to be longword (32 or 64 bit) aligned.
+ * On most other systems they are short (16 bit) aligned.
+ */
+
+/* the structure definitions are now in structs.h */
+
+#ifdef ALIGN_LONG
+    /* size of m_size */
+# define M_OFFSET (sizeof(long_u))
+#else
+    /* size of m_size */
+# define M_OFFSET (sizeof(short_u))
+#endif
+
+static char_u *u_blockalloc __ARGS((long_u));
+
+/*
+ * Allocate a block of memory and link it in the allocated block list.
+ */
+    static char_u *
+u_blockalloc(size)
+    long_u	size;
+{
+    mblock_T	*p;
+    mblock_T	*mp, *next;
+
+    p = (mblock_T *)lalloc(size + sizeof(mblock_T), FALSE);
+    if (p != NULL)
+    {
+	 /* Insert the block into the allocated block list, keeping it
+		    sorted on address. */
+	for (mp = &curbuf->b_block_head;
+		(next = mp->mb_next) != NULL && next < p;
+			mp = next)
+	    ;
+	p->mb_next = next;		/* link in block list */
+	p->mb_size = size;
+	p->mb_maxsize = 0;		/* nothing free yet */
+	mp->mb_next = p;
+	p->mb_info.m_next = NULL;	/* clear free list */
+	p->mb_info.m_size = 0;
+	curbuf->b_mb_current = p;	/* remember current block */
+	curbuf->b_m_search = NULL;
+	p++;				/* return usable memory */
+    }
+    return (char_u *)p;
+}
+
+/*
+ * free all allocated memory blocks for the buffer 'buf'
+ */
+    void
+u_blockfree(buf)
+    buf_T	*buf;
+{
+    mblock_T	*p, *np;
+
+    for (p = buf->b_block_head.mb_next; p != NULL; p = np)
+    {
+	np = p->mb_next;
+	vim_free(p);
+    }
+    buf->b_block_head.mb_next = NULL;
+    buf->b_m_search = NULL;
+    buf->b_mb_current = NULL;
+}
+
+/*
+ * Free a chunk of memory for the current buffer.
+ * Insert the chunk into the correct free list, keeping it sorted on address.
+ */
+    static void
+u_free_line(ptr, keep)
+    char_u	*ptr;
+    int		keep;	/* don't free the block when it's empty */
+{
+    minfo_T	*next;
+    minfo_T	*prev, *curr;
+    minfo_T	*mp;
+    mblock_T	*nextb;
+    mblock_T	*prevb;
+    long_u	maxsize;
+
+    if (ptr == NULL || ptr == IObuff)
+	return;	/* illegal address can happen in out-of-memory situations */
+
+    mp = (minfo_T *)(ptr - M_OFFSET);
+
+    /* find block where chunk could be a part off */
+    /* if we change curbuf->b_mb_current, curbuf->b_m_search is set to NULL */
+    if (curbuf->b_mb_current == NULL || mp < (minfo_T *)curbuf->b_mb_current)
+    {
+	curbuf->b_mb_current = curbuf->b_block_head.mb_next;
+	curbuf->b_m_search = NULL;
+    }
+    if ((nextb = curbuf->b_mb_current->mb_next) != NULL
+						     && (minfo_T *)nextb < mp)
+    {
+	curbuf->b_mb_current = nextb;
+	curbuf->b_m_search = NULL;
+    }
+    while ((nextb = curbuf->b_mb_current->mb_next) != NULL
+						     && (minfo_T *)nextb < mp)
+	curbuf->b_mb_current = nextb;
+
+    curr = NULL;
+    /*
+     * If mp is smaller than curbuf->b_m_search->m_next go to the start of
+     * the free list
+     */
+    if (curbuf->b_m_search == NULL || mp < (curbuf->b_m_search->m_next))
+	next = &(curbuf->b_mb_current->mb_info);
+    else
+	next = curbuf->b_m_search;
+    /*
+     * The following loop is executed very often.
+     * Therefore it has been optimized at the cost of readability.
+     * Keep it fast!
+     */
+#ifdef SLOW_BUT_EASY_TO_READ
+    do
+    {
+	prev = curr;
+	curr = next;
+	next = next->m_next;
+    }
+    while (mp > next && next != NULL);
+#else
+    do					    /* first, middle, last */
+    {
+	prev = next->m_next;		    /* curr, next, prev */
+	if (prev == NULL || mp <= prev)
+	{
+	    prev = curr;
+	    curr = next;
+	    next = next->m_next;
+	    break;
+	}
+	curr = prev->m_next;		    /* next, prev, curr */
+	if (curr == NULL || mp <= curr)
+	{
+	    prev = next;
+	    curr = prev->m_next;
+	    next = curr->m_next;
+	    break;
+	}
+	next = curr->m_next;		    /* prev, curr, next */
+    }
+    while (mp > next && next != NULL);
+#endif
+
+    /* if *mp and *next are concatenated, join them into one chunk */
+    if ((char_u *)mp + mp->m_size == (char_u *)next)
+    {
+	mp->m_size += next->m_size;
+	mp->m_next = next->m_next;
+    }
+    else
+	mp->m_next = next;
+    maxsize = mp->m_size;
+
+    /* if *curr and *mp are concatenated, join them */
+    if (prev != NULL && (char_u *)curr + curr->m_size == (char_u *)mp)
+    {
+	curr->m_size += mp->m_size;
+	maxsize = curr->m_size;
+	curr->m_next = mp->m_next;
+	curbuf->b_m_search = prev;
+    }
+    else
+    {
+	curr->m_next = mp;
+	curbuf->b_m_search = curr;  /* put curbuf->b_m_search before freed
+				       chunk */
+    }
+
+    /*
+     * If the block only contains free memory now, release it.
+     */
+    if (!keep && curbuf->b_mb_current->mb_size
+			      == curbuf->b_mb_current->mb_info.m_next->m_size)
+    {
+	/* Find the block before the current one to be able to unlink it from
+	 * the list of blocks. */
+	prevb = &curbuf->b_block_head;
+	for (nextb = prevb->mb_next; nextb != curbuf->b_mb_current;
+						       nextb = nextb->mb_next)
+	    prevb = nextb;
+	prevb->mb_next = nextb->mb_next;
+	vim_free(nextb);
+	curbuf->b_mb_current = NULL;
+	curbuf->b_m_search = NULL;
+    }
+    else if (curbuf->b_mb_current->mb_maxsize < maxsize)
+	curbuf->b_mb_current->mb_maxsize = maxsize;
+}
+
+/*
+ * Allocate and initialize a new line structure with room for at least
+ * 'size' characters plus a terminating NUL.
+ */
+    static char_u *
+u_alloc_line(size)
+    unsigned	size;
+{
+    minfo_T	*mp, *mprev, *mp2;
+    mblock_T	*mbp;
+    int		size_align;
+
+    /*
+     * Add room for size field and trailing NUL byte.
+     * Adjust for minimal size (must be able to store minfo_T
+     * plus a trailing NUL, so the chunk can be released again)
+     */
+    size += M_OFFSET + 1;
+    if (size < sizeof(minfo_T) + 1)
+	size = sizeof(minfo_T) + 1;
+
+    /*
+     * round size up for alignment
+     */
+    size_align = (size + ALIGN_MASK) & ~ALIGN_MASK;
+
+    /*
+     * If curbuf->b_m_search is NULL (uninitialized free list) start at
+     * curbuf->b_block_head
+     */
+    if (curbuf->b_mb_current == NULL || curbuf->b_m_search == NULL)
+    {
+	curbuf->b_mb_current = &curbuf->b_block_head;
+	curbuf->b_m_search = &(curbuf->b_block_head.mb_info);
+    }
+
+    /* Search for a block with enough space. */
+    mbp = curbuf->b_mb_current;
+    while (mbp->mb_maxsize < size_align)
+    {
+	if (mbp->mb_next != NULL)
+	    mbp = mbp->mb_next;
+	else
+	    mbp = &curbuf->b_block_head;
+	if (mbp == curbuf->b_mb_current)
+	{
+	    int	n = (size_align > (MEMBLOCKSIZE / 4)
+					     ? size_align : MEMBLOCKSIZE);
+
+	    /* Back where we started in block list: need to add a new block
+	     * with enough space. */
+	    mp = (minfo_T *)u_blockalloc((long_u)n);
+	    if (mp == NULL)
+		return (NULL);
+	    mp->m_size = n;
+	    u_free_line((char_u *)mp + M_OFFSET, TRUE);
+	    mbp = curbuf->b_mb_current;
+	    break;
+	}
+    }
+    if (mbp != curbuf->b_mb_current)
+	curbuf->b_m_search = &(mbp->mb_info);
+
+    /* In this block find a chunk with enough space. */
+    mprev = curbuf->b_m_search;
+    mp = curbuf->b_m_search->m_next;
+    for (;;)
+    {
+	if (mp == NULL)			    /* at end of the list */
+	    mp = &(mbp->mb_info);	    /* wrap around to begin */
+	if (mp->m_size >= size)
+	    break;
+	if (mp == curbuf->b_m_search)
+	{
+	    /* back where we started in free chunk list: "cannot happen" */
+	    EMSG2(_(e_intern2), "u_alloc_line()");
+	    return NULL;
+	}
+	mprev = mp;
+	mp = mp->m_next;
+    }
+
+    /* when using the largest chunk adjust mb_maxsize */
+    if (mp->m_size >= mbp->mb_maxsize)
+	mbp->mb_maxsize = 0;
+
+    /* if the chunk we found is large enough, split it up in two */
+    if ((long)mp->m_size - size_align >= (long)(sizeof(minfo_T) + 1))
+    {
+	mp2 = (minfo_T *)((char_u *)mp + size_align);
+	mp2->m_size = mp->m_size - size_align;
+	mp2->m_next = mp->m_next;
+	mprev->m_next = mp2;
+	mp->m_size = size_align;
+    }
+    else		    /* remove *mp from the free list */
+    {
+	mprev->m_next = mp->m_next;
+    }
+    curbuf->b_m_search = mprev;
+    curbuf->b_mb_current = mbp;
+
+    /* If using the largest chunk need to find the new largest chunk */
+    if (mbp->mb_maxsize == 0)
+	for (mp2 = &(mbp->mb_info); mp2 != NULL; mp2 = mp2->m_next)
+	    if (mbp->mb_maxsize < mp2->m_size)
+		mbp->mb_maxsize = mp2->m_size;
+
+    mp = (minfo_T *)((char_u *)mp + M_OFFSET);
+    *(char_u *)mp = NUL;		    /* set the first byte to NUL */
+
+    return ((char_u *)mp);
+}
+#endif
+
+/*
+ * u_save_line(): allocate memory with u_alloc_line() and copy line 'lnum'
+ * into it.
+ */
+    static char_u *
+u_save_line(lnum)
+    linenr_T	lnum;
+{
+    char_u	*src;
+    char_u	*dst;
+    unsigned	len;
+
+    src = ml_get(lnum);
+    len = (unsigned)STRLEN(src);
+    if ((dst = U_ALLOC_LINE(len)) != NULL)
+	mch_memmove(dst, src, (size_t)(len + 1));
+    return (dst);
+}
+
+/*
+ * Check if the 'modified' flag is set, or 'ff' has changed (only need to
+ * check the first character, because it can only be "dos", "unix" or "mac").
+ * "nofile" and "scratch" type buffers are considered to always be unchanged.
+ */
+    int
+bufIsChanged(buf)
+    buf_T	*buf;
+{
+    return
+#ifdef FEAT_QUICKFIX
+	    !bt_dontwrite(buf) &&
+#endif
+	    (buf->b_changed || file_ff_differs(buf));
+}
+
+    int
+curbufIsChanged()
+{
+    return
+#ifdef FEAT_QUICKFIX
+	!bt_dontwrite(curbuf) &&
+#endif
+	(curbuf->b_changed || file_ff_differs(curbuf));
+}
--- /dev/null
+++ b/version.c
@@ -1,0 +1,1250 @@
+/* vi:set ts=8 sts=4 sw=4:
+ *
+ * VIM - Vi IMproved		by Bram Moolenaar
+ *
+ * Do ":help uganda"  in Vim to read copying and usage conditions.
+ * Do ":help credits" in Vim to see a list of people who contributed.
+ * See README.txt for an overview of the Vim source code.
+ */
+
+#include "vim.h"
+
+#ifdef AMIGA
+# include <time.h>	/* for time() */
+#endif
+
+/*
+ * Vim originated from Stevie version 3.6 (Fish disk 217) by GRWalter (Fred)
+ * It has been changed beyond recognition since then.
+ *
+ * Differences between version 6.x and 7.x can be found with ":help version7".
+ * Differences between version 5.x and 6.x can be found with ":help version6".
+ * Differences between version 4.x and 5.x can be found with ":help version5".
+ * Differences between version 3.0 and 4.x can be found with ":help version4".
+ * All the remarks about older versions have been removed, they are not very
+ * interesting.
+ */
+
+#include "version.h"
+
+char		*Version = VIM_VERSION_SHORT;
+static char	*mediumVersion = VIM_VERSION_MEDIUM;
+
+#if defined(HAVE_DATE_TIME) || defined(PROTO)
+# if (defined(VMS) && defined(VAXC)) || defined(PROTO)
+char	longVersion[sizeof(VIM_VERSION_LONG_DATE) + sizeof(__DATE__)
+						      + sizeof(__TIME__) + 3];
+    void
+make_version()
+{
+    /*
+     * Construct the long version string.  Necessary because
+     * VAX C can't catenate strings in the preprocessor.
+     */
+    strcpy(longVersion, VIM_VERSION_LONG_DATE);
+    strcat(longVersion, __DATE__);
+    strcat(longVersion, " ");
+    strcat(longVersion, __TIME__);
+    strcat(longVersion, ")");
+}
+# else
+char	*longVersion = VIM_VERSION_LONG_DATE __DATE__ " " __TIME__ ")";
+# endif
+#else
+char	*longVersion = VIM_VERSION_LONG;
+#endif
+
+static void version_msg __ARGS((char *s));
+
+static char *(features[]) =
+{
+#ifdef AMIGA		/* only for Amiga systems */
+# ifdef FEAT_ARP
+	"+ARP",
+# else
+	"-ARP",
+# endif
+#endif
+#ifdef FEAT_ARABIC
+	"+arabic",
+#else
+	"-arabic",
+#endif
+#ifdef FEAT_AUTOCMD
+	"+autocmd",
+#else
+	"-autocmd",
+#endif
+#ifdef FEAT_BEVAL
+	"+balloon_eval",
+#else
+	"-balloon_eval",
+#endif
+#ifdef FEAT_BROWSE
+	"+browse",
+#else
+	"-browse",
+#endif
+#ifdef NO_BUILTIN_TCAPS
+	"-builtin_terms",
+#endif
+#ifdef SOME_BUILTIN_TCAPS
+	"+builtin_terms",
+#endif
+#ifdef ALL_BUILTIN_TCAPS
+	"++builtin_terms",
+#endif
+#ifdef FEAT_BYTEOFF
+	"+byte_offset",
+#else
+	"-byte_offset",
+#endif
+#ifdef FEAT_CINDENT
+	"+cindent",
+#else
+	"-cindent",
+#endif
+#ifdef FEAT_CLIENTSERVER
+	"+clientserver",
+#else
+	"-clientserver",
+#endif
+#ifdef FEAT_CLIPBOARD
+	"+clipboard",
+#else
+	"-clipboard",
+#endif
+#ifdef FEAT_CMDL_COMPL
+	"+cmdline_compl",
+#else
+	"-cmdline_compl",
+#endif
+#ifdef FEAT_CMDHIST
+	"+cmdline_hist",
+#else
+	"-cmdline_hist",
+#endif
+#ifdef FEAT_CMDL_INFO
+	"+cmdline_info",
+#else
+	"-cmdline_info",
+#endif
+#ifdef FEAT_COMMENTS
+	"+comments",
+#else
+	"-comments",
+#endif
+#ifdef FEAT_CRYPT
+	"+cryptv",
+#else
+	"-cryptv",
+#endif
+#ifdef FEAT_CSCOPE
+	"+cscope",
+#else
+	"-cscope",
+#endif
+#ifdef CURSOR_SHAPE
+	"+cursorshape",
+#else
+	"-cursorshape",
+#endif
+#if defined(FEAT_CON_DIALOG) && defined(FEAT_GUI_DIALOG)
+	"+dialog_con_gui",
+#else
+# if defined(FEAT_CON_DIALOG)
+	"+dialog_con",
+# else
+#  if defined(FEAT_GUI_DIALOG)
+	"+dialog_gui",
+#  else
+	"-dialog",
+#  endif
+# endif
+#endif
+#ifdef FEAT_DIFF
+	"+diff",
+#else
+	"-diff",
+#endif
+#ifdef FEAT_DIGRAPHS
+	"+digraphs",
+#else
+	"-digraphs",
+#endif
+#ifdef FEAT_DND
+	"+dnd",
+#else
+	"-dnd",
+#endif
+#ifdef EBCDIC
+	"+ebcdic",
+#else
+	"-ebcdic",
+#endif
+#ifdef FEAT_EMACS_TAGS
+	"+emacs_tags",
+#else
+	"-emacs_tags",
+#endif
+#ifdef FEAT_EVAL
+	"+eval",
+#else
+	"-eval",
+#endif
+#ifdef FEAT_EX_EXTRA
+	"+ex_extra",
+#else
+	"-ex_extra",
+#endif
+#ifdef FEAT_SEARCH_EXTRA
+	"+extra_search",
+#else
+	"-extra_search",
+#endif
+#ifdef FEAT_FKMAP
+	"+farsi",
+#else
+	"-farsi",
+#endif
+#ifdef FEAT_SEARCHPATH
+	"+file_in_path",
+#else
+	"-file_in_path",
+#endif
+#ifdef FEAT_FIND_ID
+	"+find_in_path",
+#else
+	"-find_in_path",
+#endif
+#ifdef FEAT_FOLDING
+	"+folding",
+#else
+	"-folding",
+#endif
+#ifdef FEAT_FOOTER
+	"+footer",
+#else
+	"-footer",
+#endif
+	    /* only interesting on Unix systems */
+#if !defined(USE_SYSTEM) && defined(UNIX)
+	"+fork()",
+#endif
+#ifdef FEAT_GETTEXT
+# ifdef DYNAMIC_GETTEXT
+	"+gettext/dyn",
+# else
+	"+gettext",
+# endif
+#else
+	"-gettext",
+#endif
+#ifdef FEAT_HANGULIN
+	"+hangul_input",
+#else
+	"-hangul_input",
+#endif
+#if (defined(HAVE_ICONV_H) && defined(USE_ICONV)) || defined(DYNAMIC_ICONV)
+# ifdef DYNAMIC_ICONV
+	"+iconv/dyn",
+# else
+	"+iconv",
+# endif
+#else
+	"-iconv",
+#endif
+#ifdef FEAT_INS_EXPAND
+	"+insert_expand",
+#else
+	"-insert_expand",
+#endif
+#ifdef FEAT_JUMPLIST
+	"+jumplist",
+#else
+	"-jumplist",
+#endif
+#ifdef FEAT_KEYMAP
+	"+keymap",
+#else
+	"-keymap",
+#endif
+#ifdef FEAT_LANGMAP
+	"+langmap",
+#else
+	"-langmap",
+#endif
+#ifdef FEAT_LIBCALL
+	"+libcall",
+#else
+	"-libcall",
+#endif
+#ifdef FEAT_LINEBREAK
+	"+linebreak",
+#else
+	"-linebreak",
+#endif
+#ifdef FEAT_LISP
+	"+lispindent",
+#else
+	"-lispindent",
+#endif
+#ifdef FEAT_LISTCMDS
+	"+listcmds",
+#else
+	"-listcmds",
+#endif
+#ifdef FEAT_LOCALMAP
+	"+localmap",
+#else
+	"-localmap",
+#endif
+#ifdef FEAT_MENU
+	"+menu",
+#else
+	"-menu",
+#endif
+#ifdef FEAT_SESSION
+	"+mksession",
+#else
+	"-mksession",
+#endif
+#ifdef FEAT_MODIFY_FNAME
+	"+modify_fname",
+#else
+	"-modify_fname",
+#endif
+#ifdef FEAT_MOUSE
+	"+mouse",
+#  ifdef FEAT_MOUSESHAPE
+	"+mouseshape",
+#  else
+	"-mouseshape",
+#  endif
+# else
+	"-mouse",
+#endif
+#if defined(UNIX) || defined(VMS)
+# ifdef FEAT_MOUSE_DEC
+	"+mouse_dec",
+# else
+	"-mouse_dec",
+# endif
+# ifdef FEAT_MOUSE_GPM
+	"+mouse_gpm",
+# else
+	"-mouse_gpm",
+# endif
+# ifdef FEAT_MOUSE_JSB
+	"+mouse_jsbterm",
+# else
+	"-mouse_jsbterm",
+# endif
+# ifdef FEAT_MOUSE_NET
+	"+mouse_netterm",
+# else
+	"-mouse_netterm",
+# endif
+# ifdef FEAT_MOUSE_XTERM
+	"+mouse_xterm",
+# else
+	"-mouse_xterm",
+# endif
+#endif
+#ifdef __QNX__
+# ifdef FEAT_MOUSE_PTERM
+	"+mouse_pterm",
+# else
+	"-mouse_pterm",
+# endif
+#endif
+#ifdef FEAT_MBYTE_IME
+# ifdef DYNAMIC_IME
+	"+multi_byte_ime/dyn",
+# else
+	"+multi_byte_ime",
+# endif
+#else
+# ifdef FEAT_MBYTE
+	"+multi_byte",
+# else
+	"-multi_byte",
+# endif
+#endif
+#ifdef FEAT_MULTI_LANG
+	"+multi_lang",
+#else
+	"-multi_lang",
+#endif
+#ifdef FEAT_MZSCHEME
+# ifdef DYNAMIC_MZSCHEME
+	"+mzscheme/dyn",
+# else
+	"+mzscheme",
+# endif
+#else
+	"-mzscheme",
+#endif
+#ifdef FEAT_NETBEANS_INTG
+	"+netbeans_intg",
+#else
+	"-netbeans_intg",
+#endif
+#ifdef FEAT_GUI_W32
+# ifdef FEAT_OLE
+	"+ole",
+# else
+	"-ole",
+# endif
+#endif
+#ifdef FEAT_OSFILETYPE
+	"+osfiletype",
+#else
+	"-osfiletype",
+#endif
+#ifdef FEAT_PATH_EXTRA
+	"+path_extra",
+#else
+	"-path_extra",
+#endif
+#ifdef FEAT_PERL
+# ifdef DYNAMIC_PERL
+	"+perl/dyn",
+# else
+	"+perl",
+# endif
+#else
+	"-perl",
+#endif
+#ifdef FEAT_PRINTER
+# ifdef FEAT_POSTSCRIPT
+	"+postscript",
+# else
+	"-postscript",
+# endif
+	"+printer",
+#else
+	"-printer",
+#endif
+#ifdef FEAT_PROFILE
+	"+profile",
+#else
+	"-profile",
+#endif
+#ifdef FEAT_PYTHON
+# ifdef DYNAMIC_PYTHON
+	"+python/dyn",
+# else
+	"+python",
+# endif
+#else
+	"-python",
+#endif
+#ifdef FEAT_QUICKFIX
+	"+quickfix",
+#else
+	"-quickfix",
+#endif
+#ifdef FEAT_RELTIME
+	"+reltime",
+#else
+	"-reltime",
+#endif
+#ifdef FEAT_RIGHTLEFT
+	"+rightleft",
+#else
+	"-rightleft",
+#endif
+#ifdef FEAT_RUBY
+# ifdef DYNAMIC_RUBY
+	"+ruby/dyn",
+# else
+	"+ruby",
+# endif
+#else
+	"-ruby",
+#endif
+#ifdef FEAT_SCROLLBIND
+	"+scrollbind",
+#else
+	"-scrollbind",
+#endif
+#ifdef FEAT_SIGNS
+	"+signs",
+#else
+	"-signs",
+#endif
+#ifdef FEAT_SMARTINDENT
+	"+smartindent",
+#else
+	"-smartindent",
+#endif
+#ifdef FEAT_SNIFF
+	"+sniff",
+#else
+	"-sniff",
+#endif
+#ifdef FEAT_STL_OPT
+	"+statusline",
+#else
+	"-statusline",
+#endif
+#ifdef FEAT_SUN_WORKSHOP
+	"+sun_workshop",
+#else
+	"-sun_workshop",
+#endif
+#ifdef FEAT_SYN_HL
+	"+syntax",
+#else
+	"-syntax",
+#endif
+	    /* only interesting on Unix systems */
+#if defined(USE_SYSTEM) && (defined(UNIX) || defined(__EMX__))
+	"+system()",
+#endif
+#ifdef FEAT_TAG_BINS
+	"+tag_binary",
+#else
+	"-tag_binary",
+#endif
+#ifdef FEAT_TAG_OLDSTATIC
+	"+tag_old_static",
+#else
+	"-tag_old_static",
+#endif
+#ifdef FEAT_TAG_ANYWHITE
+	"+tag_any_white",
+#else
+	"-tag_any_white",
+#endif
+#ifdef FEAT_TCL
+# ifdef DYNAMIC_TCL
+	"+tcl/dyn",
+# else
+	"+tcl",
+# endif
+#else
+	"-tcl",
+#endif
+#if defined(UNIX) || defined(__EMX__)
+/* only Unix (or OS/2 with EMX!) can have terminfo instead of termcap */
+# ifdef TERMINFO
+	"+terminfo",
+# else
+	"-terminfo",
+# endif
+#else		    /* unix always includes termcap support */
+# ifdef HAVE_TGETENT
+	"+tgetent",
+# else
+	"-tgetent",
+# endif
+#endif
+#ifdef FEAT_TERMRESPONSE
+	"+termresponse",
+#else
+	"-termresponse",
+#endif
+#ifdef FEAT_TEXTOBJ
+	"+textobjects",
+#else
+	"-textobjects",
+#endif
+#ifdef FEAT_TITLE
+	"+title",
+#else
+	"-title",
+#endif
+#ifdef FEAT_TOOLBAR
+	"+toolbar",
+#else
+	"-toolbar",
+#endif
+#ifdef FEAT_USR_CMDS
+	"+user_commands",
+#else
+	"-user_commands",
+#endif
+#ifdef FEAT_VERTSPLIT
+	"+vertsplit",
+#else
+	"-vertsplit",
+#endif
+#ifdef FEAT_VIRTUALEDIT
+	"+virtualedit",
+#else
+	"-virtualedit",
+#endif
+#ifdef FEAT_VISUAL
+	"+visual",
+# ifdef FEAT_VISUALEXTRA
+	"+visualextra",
+# else
+	"-visualextra",
+# endif
+#else
+	"-visual",
+#endif
+#ifdef FEAT_VIMINFO
+	"+viminfo",
+#else
+	"-viminfo",
+#endif
+#ifdef FEAT_VREPLACE
+	"+vreplace",
+#else
+	"-vreplace",
+#endif
+#ifdef FEAT_WILDIGN
+	"+wildignore",
+#else
+	"-wildignore",
+#endif
+#ifdef FEAT_WILDMENU
+	"+wildmenu",
+#else
+	"-wildmenu",
+#endif
+#ifdef FEAT_WINDOWS
+	"+windows",
+#else
+	"-windows",
+#endif
+#ifdef FEAT_WRITEBACKUP
+	"+writebackup",
+#else
+	"-writebackup",
+#endif
+#if defined(UNIX) || defined(VMS)
+# ifdef FEAT_X11
+	"+X11",
+# else
+	"-X11",
+# endif
+#endif
+#ifdef FEAT_XFONTSET
+	"+xfontset",
+#else
+	"-xfontset",
+#endif
+#ifdef FEAT_XIM
+	"+xim",
+#else
+	"-xim",
+#endif
+#if defined(UNIX) || defined(VMS)
+# ifdef USE_XSMP_INTERACT
+	"+xsmp_interact",
+# else
+#  ifdef USE_XSMP
+	"+xsmp",
+#  else
+	"-xsmp",
+#  endif
+# endif
+# ifdef FEAT_XCLIPBOARD
+	"+xterm_clipboard",
+# else
+	"-xterm_clipboard",
+# endif
+#endif
+#ifdef FEAT_XTERM_SAVE
+	"+xterm_save",
+#else
+	"-xterm_save",
+#endif
+#ifdef WIN3264
+# ifdef FEAT_XPM_W32
+	"+xpm_w32",
+# else
+	"-xpm_w32",
+# endif
+#endif
+	NULL
+};
+
+static int included_patches[] =
+{   /* Add new patch number below this line */
+/**/
+    0
+};
+
+    int
+highest_patch()
+{
+    int		i;
+    int		h = 0;
+
+    for (i = 0; included_patches[i] != 0; ++i)
+	if (included_patches[i] > h)
+	    h = included_patches[i];
+    return h;
+}
+
+#if defined(FEAT_EVAL) || defined(PROTO)
+/*
+ * Return TRUE if patch "n" has been included.
+ */
+    int
+has_patch(n)
+    int		n;
+{
+    int		i;
+
+    for (i = 0; included_patches[i] != 0; ++i)
+	if (included_patches[i] == n)
+	    return TRUE;
+    return FALSE;
+}
+#endif
+
+    void
+ex_version(eap)
+    exarg_T	*eap;
+{
+    /*
+     * Ignore a ":version 9.99" command.
+     */
+    if (*eap->arg == NUL)
+    {
+	msg_putchar('\n');
+	list_version();
+    }
+}
+
+    void
+list_version()
+{
+    int		i;
+    int		first;
+    char	*s = "";
+
+    /*
+     * When adding features here, don't forget to update the list of
+     * internal variables in eval.c!
+     */
+    MSG(longVersion);
+#ifdef WIN3264
+# ifdef FEAT_GUI_W32
+#  if defined(_MSC_VER) && (_MSC_VER <= 1010)
+    /* Only MS VC 4.1 and earlier can do Win32s */
+    MSG_PUTS(_("\nMS-Windows 16/32 bit GUI version"));
+#  else
+#   ifdef _WIN64
+    MSG_PUTS(_("\nMS-Windows 64 bit GUI version"));
+#   else
+    MSG_PUTS(_("\nMS-Windows 32 bit GUI version"));
+#   endif
+#  endif
+    if (gui_is_win32s())
+	MSG_PUTS(_(" in Win32s mode"));
+# ifdef FEAT_OLE
+    MSG_PUTS(_(" with OLE support"));
+# endif
+# else
+    MSG_PUTS(_("\nMS-Windows 32 bit console version"));
+# endif
+#endif
+#ifdef WIN16
+    MSG_PUTS(_("\nMS-Windows 16 bit version"));
+#endif
+#ifdef MSDOS
+# ifdef DJGPP
+    MSG_PUTS(_("\n32 bit MS-DOS version"));
+# else
+    MSG_PUTS(_("\n16 bit MS-DOS version"));
+# endif
+#endif
+#ifdef MACOS
+# ifdef MACOS_X
+#  ifdef MACOS_X_UNIX
+    MSG_PUTS(_("\nMacOS X (unix) version"));
+#  else
+    MSG_PUTS(_("\nMacOS X version"));
+#  endif
+#else
+    MSG_PUTS(_("\nMacOS version"));
+# endif
+#endif
+
+#ifdef RISCOS
+    MSG_PUTS(_("\nRISC OS version"));
+#endif
+#ifdef VMS
+    MSG_PUTS("\nOpenVMS version");
+# ifdef HAVE_PATHDEF
+    if (*compiled_arch != NUL)
+    {
+	MSG_PUTS(" - ");
+	MSG_PUTS(compiled_arch);
+    }
+# endif
+
+#endif
+
+    /* Print the list of patch numbers if there is at least one. */
+    /* Print a range when patches are consecutive: "1-10, 12, 15-40, 42-45" */
+    if (included_patches[0] != 0)
+    {
+	MSG_PUTS(_("\nIncluded patches: "));
+	first = -1;
+	/* find last one */
+	for (i = 0; included_patches[i] != 0; ++i)
+	    ;
+	while (--i >= 0)
+	{
+	    if (first < 0)
+		first = included_patches[i];
+	    if (i == 0 || included_patches[i - 1] != included_patches[i] + 1)
+	    {
+		MSG_PUTS(s);
+		s = ", ";
+		msg_outnum((long)first);
+		if (first != included_patches[i])
+		{
+		    MSG_PUTS("-");
+		    msg_outnum((long)included_patches[i]);
+		}
+		first = -1;
+	    }
+	}
+    }
+
+#ifdef MODIFIED_BY
+    MSG_PUTS("\n");
+    MSG_PUTS(_("Modified by "));
+    MSG_PUTS(MODIFIED_BY);
+#endif
+
+#ifdef HAVE_PATHDEF
+    if (*compiled_user != NUL || *compiled_sys != NUL)
+    {
+	MSG_PUTS(_("\nCompiled "));
+	if (*compiled_user != NUL)
+	{
+	    MSG_PUTS(_("by "));
+	    MSG_PUTS(compiled_user);
+	}
+	if (*compiled_sys != NUL)
+	{
+	    MSG_PUTS("@");
+	    MSG_PUTS(compiled_sys);
+	}
+    }
+#endif
+
+#ifdef FEAT_HUGE
+    MSG_PUTS(_("\nHuge version "));
+#else
+# ifdef FEAT_BIG
+    MSG_PUTS(_("\nBig version "));
+# else
+#  ifdef FEAT_NORMAL
+    MSG_PUTS(_("\nNormal version "));
+#  else
+#   ifdef FEAT_SMALL
+    MSG_PUTS(_("\nSmall version "));
+#   else
+    MSG_PUTS(_("\nTiny version "));
+#   endif
+#  endif
+# endif
+#endif
+#ifndef FEAT_GUI
+    MSG_PUTS(_("without GUI."));
+#else
+# ifdef FEAT_GUI_GTK
+#  ifdef FEAT_GUI_GNOME
+#   ifdef HAVE_GTK2
+    MSG_PUTS(_("with GTK2-GNOME GUI."));
+#   else
+    MSG_PUTS(_("with GTK-GNOME GUI."));
+#   endif
+#  else
+#   ifdef HAVE_GTK2
+    MSG_PUTS(_("with GTK2 GUI."));
+#   else
+    MSG_PUTS(_("with GTK GUI."));
+#   endif
+#  endif
+# else
+#  ifdef FEAT_GUI_MOTIF
+    MSG_PUTS(_("with X11-Motif GUI."));
+#  else
+#   ifdef FEAT_GUI_ATHENA
+#    ifdef FEAT_GUI_NEXTAW
+    MSG_PUTS(_("with X11-neXtaw GUI."));
+#    else
+    MSG_PUTS(_("with X11-Athena GUI."));
+#    endif
+#   else
+#     ifdef FEAT_GUI_PHOTON
+    MSG_PUTS(_("with Photon GUI."));
+#     else
+#      if defined(MSWIN)
+    MSG_PUTS(_("with GUI."));
+#      else
+#	if defined (TARGET_API_MAC_CARBON) && TARGET_API_MAC_CARBON
+    MSG_PUTS(_("with Carbon GUI."));
+#	else
+#	 if defined (TARGET_API_MAC_OSX) && TARGET_API_MAC_OSX
+    MSG_PUTS(_("with Cocoa GUI."));
+#	 else
+#	  if defined (MACOS)
+    MSG_PUTS(_("with (classic) GUI."));
+#	  endif
+#	 endif
+#	endif
+#      endif
+#    endif
+#   endif
+#  endif
+# endif
+#endif
+    version_msg(_("  Features included (+) or not (-):\n"));
+
+    /* print all the features */
+    for (i = 0; features[i] != NULL; ++i)
+    {
+	version_msg(features[i]);
+	if (msg_col > 0)
+	    version_msg(" ");
+    }
+
+    version_msg("\n");
+#ifdef SYS_VIMRC_FILE
+    version_msg(_("   system vimrc file: \""));
+    version_msg(SYS_VIMRC_FILE);
+    version_msg("\"\n");
+#endif
+#ifdef USR_VIMRC_FILE
+    version_msg(_("     user vimrc file: \""));
+    version_msg(USR_VIMRC_FILE);
+    version_msg("\"\n");
+#endif
+#ifdef USR_VIMRC_FILE2
+    version_msg(_(" 2nd user vimrc file: \""));
+    version_msg(USR_VIMRC_FILE2);
+    version_msg("\"\n");
+#endif
+#ifdef USR_VIMRC_FILE3
+    version_msg(_(" 3rd user vimrc file: \""));
+    version_msg(USR_VIMRC_FILE3);
+    version_msg("\"\n");
+#endif
+#ifdef USR_EXRC_FILE
+    version_msg(_("      user exrc file: \""));
+    version_msg(USR_EXRC_FILE);
+    version_msg("\"\n");
+#endif
+#ifdef USR_EXRC_FILE2
+    version_msg(_("  2nd user exrc file: \""));
+    version_msg(USR_EXRC_FILE2);
+    version_msg("\"\n");
+#endif
+#ifdef FEAT_GUI
+# ifdef SYS_GVIMRC_FILE
+    version_msg(_("  system gvimrc file: \""));
+    version_msg(SYS_GVIMRC_FILE);
+    version_msg("\"\n");
+# endif
+    version_msg(_("    user gvimrc file: \""));
+    version_msg(USR_GVIMRC_FILE);
+    version_msg("\"\n");
+# ifdef USR_GVIMRC_FILE2
+    version_msg(_("2nd user gvimrc file: \""));
+    version_msg(USR_GVIMRC_FILE2);
+    version_msg("\"\n");
+# endif
+# ifdef USR_GVIMRC_FILE3
+    version_msg(_("3rd user gvimrc file: \""));
+    version_msg(USR_GVIMRC_FILE3);
+    version_msg("\"\n");
+# endif
+#endif
+#ifdef FEAT_GUI
+# ifdef SYS_MENU_FILE
+    version_msg(_("    system menu file: \""));
+    version_msg(SYS_MENU_FILE);
+    version_msg("\"\n");
+# endif
+#endif
+#ifdef HAVE_PATHDEF
+    if (*default_vim_dir != NUL)
+    {
+	version_msg(_("  fall-back for $VIM: \""));
+	version_msg((char *)default_vim_dir);
+	version_msg("\"\n");
+    }
+    if (*default_vimruntime_dir != NUL)
+    {
+	version_msg(_(" f-b for $VIMRUNTIME: \""));
+	version_msg((char *)default_vimruntime_dir);
+	version_msg("\"\n");
+    }
+    version_msg(_("Compilation: "));
+    version_msg((char *)all_cflags);
+    version_msg("\n");
+#ifdef VMS
+    if (*compiler_version != NUL)
+    {
+	version_msg(_("Compiler: "));
+	version_msg((char *)compiler_version);
+	version_msg("\n");
+    }
+#endif
+    version_msg(_("Linking: "));
+    version_msg((char *)all_lflags);
+#endif
+#ifdef DEBUG
+    version_msg("\n");
+    version_msg(_("  DEBUG BUILD"));
+#endif
+}
+
+/*
+ * Output a string for the version message.  If it's going to wrap, output a
+ * newline, unless the message is too long to fit on the screen anyway.
+ */
+    static void
+version_msg(s)
+    char	*s;
+{
+    int		len = (int)STRLEN(s);
+
+    if (!got_int && len < (int)Columns && msg_col + len >= (int)Columns
+								&& *s != '\n')
+	msg_putchar('\n');
+    if (!got_int)
+	MSG_PUTS(s);
+}
+
+static void do_intro_line __ARGS((int row, char_u *mesg, int add_version, int attr));
+
+/*
+ * Give an introductory message about Vim.
+ * Only used when starting Vim on an empty file, without a file name.
+ * Or with the ":intro" command (for Sven :-).
+ */
+    void
+intro_message(colon)
+    int		colon;		/* TRUE for ":intro" */
+{
+    int		i;
+    int		row;
+    int		blanklines;
+    int		sponsor;
+    char	*p;
+    static char	*(lines[]) =
+    {
+	N_("VIM - Vi IMproved"),
+	"",
+	N_("version "),
+	N_("by Bram Moolenaar et al."),
+#ifdef MODIFIED_BY
+	" ",
+#endif
+	N_("Vim is open source and freely distributable"),
+	"",
+	N_("Help poor children in Uganda!"),
+	N_("type  :help iccf<Enter>       for information "),
+	"",
+	N_("type  :q<Enter>               to exit         "),
+	N_("type  :help<Enter>  or  <F1>  for on-line help"),
+	N_("type  :help version7<Enter>   for version info"),
+	NULL,
+	"",
+	N_("Running in Vi compatible mode"),
+	N_("type  :set nocp<Enter>        for Vim defaults"),
+	N_("type  :help cp-default<Enter> for info on this"),
+    };
+#ifdef FEAT_GUI
+    static char	*(gui_lines[]) =
+    {
+	NULL,
+	NULL,
+	NULL,
+	NULL,
+#ifdef MODIFIED_BY
+	NULL,
+#endif
+	NULL,
+	NULL,
+	NULL,
+	N_("menu  Help->Orphans           for information    "),
+	NULL,
+	N_("Running modeless, typed text is inserted"),
+	N_("menu  Edit->Global Settings->Toggle Insert Mode  "),
+	N_("                              for two modes      "),
+	NULL,
+	NULL,
+	NULL,
+	N_("menu  Edit->Global Settings->Toggle Vi Compatible"),
+	N_("                              for Vim defaults   "),
+    };
+#endif
+
+    /* blanklines = screen height - # message lines */
+    blanklines = (int)Rows - ((sizeof(lines) / sizeof(char *)) - 1);
+    if (!p_cp)
+	blanklines += 4;  /* add 4 for not showing "Vi compatible" message */
+#if defined(WIN3264) && !defined(FEAT_GUI_W32)
+    if (mch_windows95())
+	blanklines -= 3;  /* subtract 3 for showing "Windows 95" message */
+#endif
+
+#ifdef FEAT_WINDOWS
+    /* Don't overwrite a statusline.  Depends on 'cmdheight'. */
+    if (p_ls > 1)
+	blanklines -= Rows - topframe->fr_height;
+#endif
+    if (blanklines < 0)
+	blanklines = 0;
+
+    /* Show the sponsor and register message one out of four times, the Uganda
+     * message two out of four times. */
+    sponsor = (int)time(NULL);
+    sponsor = ((sponsor & 2) == 0) - ((sponsor & 4) == 0);
+
+    /* start displaying the message lines after half of the blank lines */
+    row = blanklines / 2;
+    if ((row >= 2 && Columns >= 50) || colon)
+    {
+	for (i = 0; i < (int)(sizeof(lines) / sizeof(char *)); ++i)
+	{
+	    p = lines[i];
+#ifdef FEAT_GUI
+	    if (p_im && gui.in_use && gui_lines[i] != NULL)
+		p = gui_lines[i];
+#endif
+	    if (p == NULL)
+	    {
+		if (!p_cp)
+		    break;
+		continue;
+	    }
+	    if (sponsor != 0)
+	    {
+		if (strstr(p, "children") != NULL)
+		    p = sponsor < 0
+			? N_("Sponsor Vim development!")
+			: N_("Become a registered Vim user!");
+		else if (strstr(p, "iccf") != NULL)
+		    p = sponsor < 0
+			? N_("type  :help sponsor<Enter>    for information ")
+			: N_("type  :help register<Enter>   for information ");
+		else if (strstr(p, "Orphans") != NULL)
+		    p = N_("menu  Help->Sponsor/Register  for information    ");
+	    }
+	    if (*p != NUL)
+		do_intro_line(row, (char_u *)_(p), i == 2, 0);
+	    ++row;
+	}
+#if defined(WIN3264) && !defined(FEAT_GUI_W32)
+	if (mch_windows95())
+	{
+	    do_intro_line(++row,
+		    (char_u *)_("WARNING: Windows 95/98/ME detected"),
+							FALSE, hl_attr(HLF_E));
+	    do_intro_line(++row,
+		(char_u *)_("type  :help windows95<Enter>  for info on this"),
+								    FALSE, 0);
+	}
+#endif
+    }
+
+    /* Make the wait-return message appear just below the text. */
+    if (colon)
+	msg_row = row;
+}
+
+    static void
+do_intro_line(row, mesg, add_version, attr)
+    int		row;
+    char_u	*mesg;
+    int		add_version;
+    int		attr;
+{
+    char_u	vers[20];
+    int		col;
+    char_u	*p;
+    int		l;
+    int		clen;
+#ifdef MODIFIED_BY
+# define MODBY_LEN 150
+    char_u	modby[MODBY_LEN];
+
+    if (*mesg == ' ')
+    {
+	vim_strncpy(modby, _("Modified by "), MODBY_LEN - 1);
+	l = STRLEN(modby);
+	vim_strncpy(modby + l, MODIFIED_BY, MODBY_LEN - l - 1);
+	mesg = modby;
+    }
+#endif
+
+    /* Center the message horizontally. */
+    col = vim_strsize(mesg);
+    if (add_version)
+    {
+	STRCPY(vers, mediumVersion);
+	if (highest_patch())
+	{
+	    /* Check for 9.9x or 9.9xx, alpha/beta version */
+	    if (isalpha((int)mediumVersion[3]))
+	    {
+		if (isalpha((int)mediumVersion[4]))
+		    sprintf((char *)vers + 5, ".%d%s", highest_patch(),
+							   mediumVersion + 5);
+		else
+		    sprintf((char *)vers + 4, ".%d%s", highest_patch(),
+							   mediumVersion + 4);
+	    }
+	    else
+		sprintf((char *)vers + 3, ".%d", highest_patch());
+	}
+	col += (int)STRLEN(vers);
+    }
+    col = (Columns - col) / 2;
+    if (col < 0)
+	col = 0;
+
+    /* Split up in parts to highlight <> items differently. */
+    for (p = mesg; *p != NUL; p += l)
+    {
+	clen = 0;
+	for (l = 0; p[l] != NUL
+			 && (l == 0 || (p[l] != '<' && p[l - 1] != '>')); ++l)
+	{
+#ifdef FEAT_MBYTE
+	    if (has_mbyte)
+	    {
+		clen += ptr2cells(p + l);
+		l += (*mb_ptr2len)(p + l) - 1;
+	    }
+	    else
+#endif
+		clen += byte2cells(p[l]);
+	}
+	screen_puts_len(p, l, row, col, *p == '<' ? hl_attr(HLF_8) : attr);
+	col += clen;
+    }
+
+    /* Add the version number to the version line. */
+    if (add_version)
+	screen_puts(vers, row, col, 0);
+}
+
+/*
+ * ":intro": clear screen, display intro screen and wait for return.
+ */
+/*ARGSUSED*/
+    void
+ex_intro(eap)
+    exarg_T	*eap;
+{
+    screenclear();
+    intro_message(TRUE);
+    wait_return(TRUE);
+}
--- /dev/null
+++ b/version.h
@@ -1,0 +1,40 @@
+/* vi:set ts=8 sts=4 sw=4:
+ *
+ * VIM - Vi IMproved		by Bram Moolenaar
+ *
+ * Do ":help uganda"  in Vim to read copying and usage conditions.
+ * Do ":help credits" in Vim to see a list of people who contributed.
+ */
+
+/*
+ * Define the version number, name, etc.
+ * The patchlevel is in included_patches[], in version.c.
+ *
+ * This doesn't use string concatenation, some compilers don't support it.
+ */
+
+#define VIM_VERSION_MAJOR		 7
+#define VIM_VERSION_MAJOR_STR		"7"
+#define VIM_VERSION_MINOR		 1
+#define VIM_VERSION_MINOR_STR		"1"
+#define VIM_VERSION_100	    (VIM_VERSION_MAJOR * 100 + VIM_VERSION_MINOR)
+
+#define VIM_VERSION_BUILD		 265
+#define VIM_VERSION_BUILD_BCD		0x109
+#define VIM_VERSION_BUILD_STR		"265"
+#define VIM_VERSION_PATCHLEVEL		 0
+#define VIM_VERSION_PATCHLEVEL_STR	"0"
+/* Used by MacOS port should be one of: development, alpha, beta, final */
+#define VIM_VERSION_RELEASE		final
+
+/*
+ * VIM_VERSION_NODOT is used for the runtime directory name.
+ * VIM_VERSION_SHORT is copied into the swap file (max. length is 6 chars).
+ * VIM_VERSION_MEDIUM is used for the startup-screen.
+ * VIM_VERSION_LONG is used for the ":version" command and "Vim -h".
+ */
+#define VIM_VERSION_NODOT	"vim71"
+#define VIM_VERSION_SHORT	"7.1"
+#define VIM_VERSION_MEDIUM	"7.1"
+#define VIM_VERSION_LONG	"VIM - Vi IMproved 7.1 (2007 May 12)"
+#define VIM_VERSION_LONG_DATE	"VIM - Vi IMproved 7.1 (2007 May 12, compiled "
--- /dev/null
+++ b/vim.h
@@ -1,0 +1,2027 @@
+/* vi:set ts=8 sts=4 sw=4:
+ *
+ * VIM - Vi IMproved	by Bram Moolenaar
+ *
+ * Do ":help uganda"  in Vim to read copying and usage conditions.
+ * Do ":help credits" in Vim to see a list of people who contributed.
+ */
+
+#ifndef VIM__H
+# define VIM__H
+
+/* use fastcall for Borland, when compiling for Win32 (not for DOS16) */
+#if defined(__BORLANDC__) && defined(WIN32) && !defined(DEBUG)
+#if defined(FEAT_PERL) || \
+    defined(FEAT_PYTHON) || \
+    defined(FEAT_RUBY) || \
+    defined(FEAT_TCL) || \
+    defined(FEAT_MZSCHEME) || \
+    defined(DYNAMIC_GETTEXT) || \
+    defined(DYNAMIC_ICONV) || \
+    defined(DYNAMIC_IME) || \
+    defined(XPM)
+  #pragma option -pc
+# else
+  #pragma option -pr
+# endif
+#endif
+
+/* ============ the header file puzzle (ca. 50-100 pieces) ========= */
+
+#ifdef HAVE_CONFIG_H	/* GNU autoconf (or something else) was here */
+# include "auto/config.h"
+# define HAVE_PATHDEF
+
+/*
+ * Check if configure correctly managed to find sizeof(int).  If this failed,
+ * it becomes zero.  This is likely a problem of not being able to run the
+ * test program.  Other items from configure may also be wrong then!
+ */
+# if (SIZEOF_INT == 0)
+    Error: configure did not run properly.  Check auto/config.log.
+# endif
+
+/*
+ * Cygwin may have fchdir() in a newer release, but in most versions it
+ * doesn't work well and avoiding it keeps the binary backward compatible.
+ */
+# if defined(__CYGWIN32__) && defined(HAVE_FCHDIR)
+#  undef HAVE_FCHDIR
+# endif
+#endif
+
+/* user ID of root is usually zero, but not for everybody */
+#ifdef __TANDEM
+# define _TANDEM_SOURCE
+# include <floss.h>
+# define ROOT_UID 65535
+#else
+# define ROOT_UID 0
+#endif
+
+#ifdef __EMX__		/* hand-edited config.h for OS/2 with EMX */
+# include "os_os2_cfg.h"
+#endif
+
+/*
+ * MACOS_CLASSIC compiling for MacOS prior to MacOS X
+ * MACOS_X_UNIX  compiling for MacOS X (using os_unix.c)
+ * MACOS_X       compiling for MacOS X (using os_unix.c)
+ * MACOS	 compiling for either one
+ */
+#if defined(macintosh) && !defined(MACOS_CLASSIC)
+# define MACOS_CLASSIC
+#endif
+#if defined(MACOS_X_UNIX)
+# define MACOS_X
+# ifndef HAVE_CONFIG_H
+#  define UNIX
+# endif
+#endif
+#if defined(MACOS_X) || defined(MACOS_CLASSIC)
+#  define MACOS
+#endif
+#if defined(MACOS_X) && defined(MACOS_CLASSIC)
+    Error: To compile for both MACOS X and Classic use a Classic Carbon
+#endif
+/* Unless made through the Makefile enforce GUI on Mac */
+#if defined(MACOS) && !defined(HAVE_CONFIG_H)
+# define FEAT_GUI_MAC
+#endif
+
+#if defined(FEAT_GUI_MOTIF) \
+    || defined(FEAT_GUI_GTK) \
+    || defined(FEAT_GUI_ATHENA) \
+    || defined(FEAT_GUI_MAC) \
+    || defined(FEAT_GUI_W32) \
+    || defined(FEAT_GUI_W16) \
+    || defined(FEAT_GUI_PHOTON)
+# if !defined(FEAT_GUI) && !defined(NO_X11_INCLUDES)
+#  define FEAT_GUI
+# endif
+#endif
+
+/* Visual Studio 2005 has 'deprecated' many of the standard CRT functions */
+#if _MSC_VER >= 1400
+# define _CRT_SECURE_NO_DEPRECATE
+# define _CRT_NONSTDC_NO_DEPRECATE
+#endif
+
+#if defined(FEAT_GUI_W32) || defined(FEAT_GUI_W16)
+# define FEAT_GUI_MSWIN
+#endif
+#if defined(WIN16) || defined(WIN32) || defined(_WIN64)
+# define MSWIN
+#endif
+/* Practically everything is common to both Win32 and Win64 */
+#if defined(WIN32) || defined(_WIN64)
+# define WIN3264
+#endif
+
+/*
+ * SIZEOF_INT is used in feature.h, and the system-specific included files
+ * need items from feature.h.  Therefore define SIZEOF_INT here.
+ */
+#ifdef WIN3264
+# define SIZEOF_INT 4
+#endif
+#ifdef MSDOS
+# ifdef DJGPP
+#  ifndef FEAT_GUI_GTK		/* avoid problems when generating prototypes */
+#   define SIZEOF_INT 4		/* 32 bit ints */
+#  endif
+#  define DOS32
+#  define FEAT_CLIPBOARD
+# else
+#  ifndef FEAT_GUI_GTK		/* avoid problems when generating prototypes */
+#   define SIZEOF_INT 2		/* 16 bit ints */
+#  endif
+#  define SMALL_MALLOC		/* 16 bit storage allocation */
+#  define DOS16
+# endif
+#endif
+
+#ifdef AMIGA
+  /* Be conservative about sizeof(int). It could be 4 too. */
+# ifndef FEAT_GUI_GTK	/* avoid problems when generating prototypes */
+#  ifdef __GNUC__
+#   define SIZEOF_INT	4
+#  else
+#   define SIZEOF_INT	2
+#  endif
+# endif
+#endif
+#ifdef MACOS
+# if defined(__POWERPC__) || defined(MACOS_X) || defined(__fourbyteints__) \
+  || defined(__MRC__) || defined(__SC__) || defined(__APPLE_CC__)/* MPW Compilers */
+#  define SIZEOF_INT 4
+# else
+#  define SIZEOF_INT 2
+# endif
+#endif
+#ifdef RISCOS
+# define SIZEOF_INT 4
+#endif
+#ifdef PLAN9
+# define SIZEOF_INT 4
+#endif
+
+
+#include "feature.h"	/* #defines for optionals and features */
+
+/* +x11 is only enabled when it's both available and wanted. */
+#if defined(HAVE_X11) && defined(WANT_X11)
+# define FEAT_X11
+#endif
+
+#ifdef NO_X11_INCLUDES
+    /* In os_mac_conv.c NO_X11_INCLUDES is defined to avoid X11 headers.
+     * Disable all X11 related things to avoid conflicts. */
+# ifdef FEAT_X11
+#  undef FEAT_X11
+# endif
+# ifdef FEAT_XCLIPBOARD
+#  undef FEAT_XCLIPBOARD
+# endif
+# ifdef FEAT_GUI_MOTIF
+#  undef FEAT_GUI_MOTIF
+# endif
+# ifdef FEAT_GUI_ATHENA
+#  undef FEAT_GUI_ATHENA
+# endif
+# ifdef FEAT_GUI_GTK
+#  undef FEAT_GUI_GTK
+# endif
+# ifdef FEAT_BEVAL_TIP
+#  undef FEAT_BEVAL_TIP
+# endif
+# ifdef FEAT_XIM
+#  undef FEAT_XIM
+# endif
+# ifdef FEAT_CLIENTSERVER
+#  undef FEAT_CLIENTSERVER
+# endif
+#endif
+
+/* The Mac conversion stuff doesn't work under X11. */
+#if defined(FEAT_MBYTE) && defined(MACOS_X)
+# define MACOS_CONVERT
+#endif
+
+/* Can't use "PACKAGE" here, conflicts with a Perl include file. */
+#ifndef VIMPACKAGE
+# define VIMPACKAGE	"vim"
+#endif
+
+/*
+ * Find out if function definitions should include argument types
+ */
+#ifdef AZTEC_C
+# include <functions.h>
+# define __ARGS(x)  x
+#endif
+
+#ifdef SASC
+# include <clib/exec_protos.h>
+# define __ARGS(x)  x
+#endif
+
+#ifdef _DCC
+# include <clib/exec_protos.h>
+# define __ARGS(x)  x
+#endif
+
+#ifdef __TURBOC__
+# define __ARGS(x) x
+#endif
+
+#ifdef __BEOS__
+# include "os_beos.h"
+# define __ARGS(x)  x
+#endif
+
+#if (defined(UNIX) || defined(__EMX__) || defined(VMS)) \
+	&& (!defined(MACOS_X) || defined(HAVE_CONFIG_H))
+# include "os_unix.h"	    /* bring lots of system header files */
+#endif
+
+#if defined(MACOS) && (defined(__MRC__) || defined(__SC__))
+   /* Apple's Compilers support prototypes */
+# define __ARGS(x) x
+#endif
+#ifndef __ARGS
+# if defined(__STDC__) || defined(__GNUC__) || defined(WIN3264)
+#  define __ARGS(x) x
+# else
+#  define __ARGS(x) ()
+# endif
+#endif
+
+/* __ARGS and __PARMS are the same thing. */
+#ifndef __PARMS
+# define __PARMS(x) __ARGS(x)
+#endif
+
+/* if we're compiling in C++ (currently only KVim), the system
+ * headers must have the correct prototypes or nothing will build.
+ * conversely, our prototypes might clash due to throw() specifiers and
+ * cause compilation failures even though the headers are correct.  For
+ * a concrete example, gcc-3.2 enforces exception specifications, and
+ * glibc-2.2.5 has them in their system headers.
+ */
+#if !defined(__cplusplus) && defined(UNIX) \
+  && !defined(MACOS_X) /* MACOS_X doesn't yet support osdef.h */
+# include "auto/osdef.h"	/* bring missing declarations in */
+#endif
+
+#ifdef __EMX__
+# define    getcwd  _getcwd2
+# define    chdir   _chdir2
+# undef	    CHECK_INODE
+#endif
+
+#ifdef AMIGA
+# include "os_amiga.h"
+#endif
+
+#ifdef MSDOS
+# include "os_msdos.h"
+#endif
+
+#ifdef WIN16
+# include "os_win16.h"
+#endif
+
+#ifdef WIN3264
+# include "os_win32.h"
+#endif
+
+#ifdef __MINT__
+# include "os_mint.h"
+#endif
+
+#if defined(MACOS)
+# if defined(__MRC__) || defined(__SC__) /* MPW Compilers */
+#  define HAVE_SETENV
+# endif
+# include "os_mac.h"
+#endif
+
+#if defined(PLAN9)
+# include "os_plan9.h"
+#endif
+
+#ifdef RISCOS
+# include "os_riscos.h"
+#endif
+
+#ifdef __QNX__
+# include "os_qnx.h"
+#endif
+
+#ifdef FEAT_SUN_WORKSHOP
+# include "workshop.h"
+#endif
+
+#ifdef X_LOCALE
+# include <X11/Xlocale.h>
+#else
+# ifdef HAVE_LOCALE_H
+#  include <locale.h>
+# endif
+#endif
+
+/*
+ * Maximum length of a path (for non-unix systems) Make it a bit long, to stay
+ * on the safe side.  But not too long to put on the stack.
+ */
+#ifndef MAXPATHL
+# ifdef MAXPATHLEN
+#  define MAXPATHL  MAXPATHLEN
+# else
+#  define MAXPATHL  256
+# endif
+#endif
+#ifdef BACKSLASH_IN_FILENAME
+# define PATH_ESC_CHARS ((char_u *)" \t*?[{`%#")
+#else
+# define PATH_ESC_CHARS ((char_u *)" \t*?[{`$\\%#'\"|")
+# define SHELL_ESC_CHARS ((char_u *)" \t*?[{`$\\%#'\"|<>();&!")
+#endif
+
+#define NUMBUFLEN 30	    /* length of a buffer to store a number in ASCII */
+
+/*
+ * Shorthand for unsigned variables. Many systems, but not all, have u_char
+ * already defined, so we use char_u to avoid trouble.
+ */
+typedef unsigned char	char_u;
+typedef unsigned short	short_u;
+typedef unsigned int	int_u;
+/* Make sure long_u is big enough to hold a pointer.
+ * On Win64 longs are 32 bit and pointers 64 bit.
+ * For printf() and scanf() we need to take care of long_u specifically. */
+#ifdef _WIN64
+typedef unsigned __int64 long_u;
+typedef		 __int64 long_i;
+# define SCANF_HEX_LONG_U  "%Ix"
+# define PRINTF_HEX_LONG_U "0x%Ix"
+#else
+typedef unsigned long	long_u;
+typedef		 long	long_i;
+# define SCANF_HEX_LONG_U  "%lx"
+# define PRINTF_HEX_LONG_U "0x%lx"
+#endif
+
+/*
+ * The characters and attributes cached for the screen.
+ */
+typedef char_u schar_T;
+#ifdef FEAT_SYN_HL
+typedef unsigned short sattr_T;
+# define MAX_TYPENR 65535
+#else
+typedef unsigned char sattr_T;
+# define MAX_TYPENR 255
+#endif
+
+/*
+ * The u8char_T can hold one decoded UTF-8 character.
+ * We normally use 32 bits now, since some Asian characters don't fit in 16
+ * bits.  u8char_T is only used for displaying, it could be 16 bits to save
+ * memory.
+ */
+#ifdef FEAT_MBYTE
+# ifdef UNICODE16
+typedef unsigned short u8char_T;    /* short should be 16 bits */
+# else
+#  if SIZEOF_INT >= 4
+typedef unsigned int u8char_T;	    /* int is 32 bits */
+#  else
+typedef unsigned long u8char_T;	    /* long should be 32 bits or more */
+#  endif
+# endif
+#endif
+
+#ifndef UNIX		    /* For Unix this is included in os_unix.h */
+# include <stdio.h>
+# include <ctype.h>
+#endif
+
+#include "ascii.h"
+#include "keymap.h"
+#include "term.h"
+#include "macros.h"
+
+#ifdef LATTICE
+# include <sys/types.h>
+# include <sys/stat.h>
+#endif
+#ifdef _DCC
+# include <sys/stat.h>
+#endif
+#if defined(MSDOS) || defined(MSWIN)
+# include <sys/stat.h>
+#endif
+
+/*
+ * Allow other (non-unix) systems to configure themselves now
+ * These are also in os_unix.h, because osdef.sh needs them there.
+ */
+#ifndef UNIX
+/* Note: Some systems need both string.h and strings.h (Savage).  If the
+ * system can't handle this, define NO_STRINGS_WITH_STRING_H. */
+# ifdef HAVE_STRING_H
+#  include <string.h>
+# endif
+# if defined(HAVE_STRINGS_H) && !defined(NO_STRINGS_WITH_STRING_H)
+#   include <strings.h>
+# endif
+# ifdef HAVE_STAT_H
+#  include <stat.h>
+# endif
+# ifdef HAVE_STDLIB_H
+#  include <stdlib.h>
+# endif
+#endif /* NON-UNIX */
+
+#include <assert.h>
+
+#ifdef HAVE_WCTYPE_H
+# include <wctype.h>
+#endif
+#if defined(HAVE_STDARG_H) && !defined(PLAN9)
+# include <stdarg.h>
+#endif
+
+/* ================ end of the header file puzzle =============== */
+
+/*
+ * For dynamically loaded imm library. Currently, only for Win32.
+ */
+#ifdef DYNAMIC_IME
+# ifndef FEAT_MBYTE_IME
+#  define FEAT_MBYTE_IME
+# endif
+#endif
+
+/*
+ * Check input method control.
+ */
+#if defined(FEAT_XIM) || \
+    (defined(FEAT_GUI) && (defined(FEAT_MBYTE_IME) || defined(GLOBAL_IME)))
+# define USE_IM_CONTROL
+#endif
+
+/*
+ * For dynamically loaded gettext library.  Currently, only for Win32.
+ */
+#ifdef DYNAMIC_GETTEXT
+# ifndef FEAT_GETTEXT
+#  define FEAT_GETTEXT
+# endif
+/* These are in os_win32.c */
+extern char *(*dyn_libintl_gettext)(const char *msgid);
+extern char *(*dyn_libintl_bindtextdomain)(const char *domainname, const char *dirname);
+extern char *(*dyn_libintl_bind_textdomain_codeset)(const char *domainname, const char *codeset);
+extern char *(*dyn_libintl_textdomain)(const char *domainname);
+#endif
+
+
+/*
+ * The _() stuff is for using gettext().  It is a no-op when libintl.h is not
+ * found or the +multilang feature is disabled.
+ */
+#ifdef FEAT_GETTEXT
+# ifdef DYNAMIC_GETTEXT
+#  define _(x) (*dyn_libintl_gettext)((char *)(x))
+#  define N_(x) x
+#  define bindtextdomain(domain, dir) (*dyn_libintl_bindtextdomain)((domain), (dir))
+#  define bind_textdomain_codeset(domain, codeset) (*dyn_libintl_bind_textdomain_codeset)((domain), (codeset))
+#  if !defined(HAVE_BIND_TEXTDOMAIN_CODESET)
+#   define HAVE_BIND_TEXTDOMAIN_CODESET 1
+#  endif
+#  define textdomain(domain) (*dyn_libintl_textdomain)(domain)
+# else
+#  include <libintl.h>
+#  define _(x) gettext((char *)(x))
+#  ifdef gettext_noop
+#   define N_(x) gettext_noop(x)
+#  else
+#   define N_(x) x
+#  endif
+# endif
+#else
+# define _(x) ((char *)(x))
+# define N_(x) x
+# ifdef bindtextdomain
+#  undef bindtextdomain
+# endif
+# define bindtextdomain(x, y) /* empty */
+# ifdef bind_textdomain_codeset
+#  undef bind_textdomain_codeset
+# endif
+# define bind_textdomain_codeset(x, y) /* empty */
+# ifdef textdomain
+#  undef textdomain
+# endif
+# define textdomain(x) /* empty */
+#endif
+
+/*
+ * flags for update_screen()
+ * The higher the value, the higher the priority
+ */
+#define VALID			10  /* buffer not changed, or changes marked
+				       with b_mod_* */
+#define INVERTED		20  /* redisplay inverted part that changed */
+#define INVERTED_ALL		25  /* redisplay whole inverted part */
+#define REDRAW_TOP		30  /* display first w_upd_rows screen lines */
+#define SOME_VALID		35  /* like NOT_VALID but may scroll */
+#define NOT_VALID		40  /* buffer needs complete redraw */
+#define CLEAR			50  /* screen messed up, clear it */
+
+/*
+ * Flags for w_valid.
+ * These are set when something in a window structure becomes invalid, except
+ * when the cursor is moved.  Call check_cursor_moved() before testing one of
+ * the flags.
+ * These are reset when that thing has been updated and is valid again.
+ *
+ * Every function that invalidates one of these must call one of the
+ * invalidate_* functions.
+ *
+ * w_valid is supposed to be used only in screen.c.  From other files, use the
+ * functions that set or reset the flags.
+ *
+ * VALID_BOTLINE    VALID_BOTLINE_AP
+ *     on		on		w_botline valid
+ *     off		on		w_botline approximated
+ *     off		off		w_botline not valid
+ *     on		off		not possible
+ */
+#define VALID_WROW	0x01	/* w_wrow (window row) is valid */
+#define VALID_WCOL	0x02	/* w_wcol (window col) is valid */
+#define VALID_VIRTCOL	0x04	/* w_virtcol (file col) is valid */
+#define VALID_CHEIGHT	0x08	/* w_cline_height and w_cline_folded valid */
+#define VALID_CROW	0x10	/* w_cline_row is valid */
+#define VALID_BOTLINE	0x20	/* w_botine and w_empty_rows are valid */
+#define VALID_BOTLINE_AP 0x40	/* w_botine is approximated */
+#define VALID_TOPLINE	0x80	/* w_topline is valid (for cursor position) */
+
+/*
+ * Terminal highlighting attribute bits.
+ * Attibutes above HL_ALL are used for syntax highlighting.
+ */
+#define HL_NORMAL		0x00
+#define HL_INVERSE		0x01
+#define HL_BOLD			0x02
+#define HL_ITALIC		0x04
+#define HL_UNDERLINE		0x08
+#define HL_UNDERCURL		0x10
+#define HL_STANDOUT		0x20
+#define HL_ALL			0x3f
+
+/* special attribute addition: Put message in history */
+#define MSG_HIST		0x1000
+
+/*
+ * values for State
+ *
+ * The lower bits up to 0x20 are used to distinguish normal/visual/op_pending
+ * and cmdline/insert+replace mode.  This is used for mapping.  If none of
+ * these bits are set, no mapping is done.
+ * The upper bits are used to distinguish between other states.
+ */
+#define NORMAL		0x01	/* Normal mode, command expected */
+#define VISUAL		0x02	/* Visual mode - use get_real_state() */
+#define OP_PENDING	0x04	/* Normal mode, operator is pending - use
+				   get_real_state() */
+#define CMDLINE		0x08	/* Editing command line */
+#define INSERT		0x10	/* Insert mode */
+#define LANGMAP		0x20	/* Language mapping, can be combined with
+				   INSERT and CMDLINE */
+
+#define REPLACE_FLAG	0x40	/* Replace mode flag */
+#define REPLACE		(REPLACE_FLAG + INSERT)
+#ifdef FEAT_VREPLACE
+# define VREPLACE_FLAG	0x80	/* Virtual-replace mode flag */
+# define VREPLACE	(REPLACE_FLAG + VREPLACE_FLAG + INSERT)
+#endif
+#define LREPLACE	(REPLACE_FLAG + LANGMAP)
+
+#define NORMAL_BUSY	(0x100 + NORMAL) /* Normal mode, busy with a command */
+#define HITRETURN	(0x200 + NORMAL) /* waiting for return or command */
+#define ASKMORE		0x300	/* Asking if you want --more-- */
+#define SETWSIZE	0x400	/* window size has changed */
+#define ABBREV		0x500	/* abbreviation instead of mapping */
+#define EXTERNCMD	0x600	/* executing an external command */
+#define SHOWMATCH	(0x700 + INSERT) /* show matching paren */
+#define CONFIRM		0x800	/* ":confirm" prompt */
+#define SELECTMODE	0x1000	/* Select mode, only for mappings */
+
+#define MAP_ALL_MODES	(0x3f | SELECTMODE)	/* all mode bits used for
+						 * mapping */
+
+/* directions */
+#define FORWARD			1
+#define BACKWARD		(-1)
+#define FORWARD_FILE		3
+#define BACKWARD_FILE		(-3)
+
+/* return values for functions */
+#if !(defined(OK) && (OK == 1))
+/* OK already defined to 1 in MacOS X curses, skip this */
+# define OK			1
+#endif
+#define FAIL			0
+#define NOTDONE			2   /* not OK or FAIL but skipped */
+
+/* flags for b_flags */
+#define BF_RECOVERED	0x01	/* buffer has been recovered */
+#define BF_CHECK_RO	0x02	/* need to check readonly when loading file
+				   into buffer (set by ":e", may be reset by
+				   ":buf" */
+#define BF_NEVERLOADED	0x04	/* file has never been loaded into buffer,
+				   many variables still need to be set */
+#define BF_NOTEDITED	0x08	/* Set when file name is changed after
+				   starting to edit, reset when file is
+				   written out. */
+#define BF_NEW		0x10	/* file didn't exist when editing started */
+#define BF_NEW_W	0x20	/* Warned for BF_NEW and file created */
+#define BF_READERR	0x40	/* got errors while reading the file */
+#define BF_DUMMY	0x80	/* dummy buffer, only used internally */
+#define BF_PRESERVED	0x100	/* ":preserve" was used */
+
+/* Mask to check for flags that prevent normal writing */
+#define BF_WRITE_MASK	(BF_NOTEDITED + BF_NEW + BF_READERR)
+
+/*
+ * values for xp_context when doing command line completion
+ */
+#define EXPAND_UNSUCCESSFUL	(-2)
+#define EXPAND_OK		(-1)
+#define EXPAND_NOTHING		0
+#define EXPAND_COMMANDS		1
+#define EXPAND_FILES		2
+#define EXPAND_DIRECTORIES	3
+#define EXPAND_SETTINGS		4
+#define EXPAND_BOOL_SETTINGS	5
+#define EXPAND_TAGS		6
+#define EXPAND_OLD_SETTING	7
+#define EXPAND_HELP		8
+#define EXPAND_BUFFERS		9
+#define EXPAND_EVENTS		10
+#define EXPAND_MENUS		11
+#define EXPAND_SYNTAX		12
+#define EXPAND_HIGHLIGHT	13
+#define EXPAND_AUGROUP		14
+#define EXPAND_USER_VARS	15
+#define EXPAND_MAPPINGS		16
+#define EXPAND_TAGS_LISTFILES	17
+#define EXPAND_FUNCTIONS	18
+#define EXPAND_USER_FUNC	19
+#define EXPAND_EXPRESSION	20
+#define EXPAND_MENUNAMES	21
+#define EXPAND_USER_COMMANDS	22
+#define EXPAND_USER_CMD_FLAGS	23
+#define EXPAND_USER_NARGS	24
+#define EXPAND_USER_COMPLETE	25
+#define EXPAND_ENV_VARS		26
+#define EXPAND_LANGUAGE		27
+#define EXPAND_COLORS		28
+#define EXPAND_COMPILER		29
+#define EXPAND_USER_DEFINED	30
+#define EXPAND_USER_LIST	31
+#define EXPAND_SHELLCMD		32
+
+/* Values for exmode_active (0 is no exmode) */
+#define EXMODE_NORMAL		1
+#define EXMODE_VIM		2
+
+/* Values for nextwild() and ExpandOne().  See ExpandOne() for meaning. */
+#define WILD_FREE		1
+#define WILD_EXPAND_FREE	2
+#define WILD_EXPAND_KEEP	3
+#define WILD_NEXT		4
+#define WILD_PREV		5
+#define WILD_ALL		6
+#define WILD_LONGEST		7
+
+#define WILD_LIST_NOTFOUND	1
+#define WILD_HOME_REPLACE	2
+#define WILD_USE_NL		4
+#define WILD_NO_BEEP		8
+#define WILD_ADD_SLASH		16
+#define WILD_KEEP_ALL		32
+#define WILD_SILENT		64
+#define WILD_ESCAPE		128
+
+/* Flags for expand_wildcards() */
+#define EW_DIR		0x01	/* include directory names */
+#define EW_FILE		0x02	/* include file names */
+#define EW_NOTFOUND	0x04	/* include not found names */
+#define EW_ADDSLASH	0x08	/* append slash to directory name */
+#define EW_KEEPALL	0x10	/* keep all matches */
+#define EW_SILENT	0x20	/* don't print "1 returned" from shell */
+#define EW_EXEC		0x40	/* executable files */
+/* Note: mostly EW_NOTFOUND and EW_SILENT are mutually exclusive: EW_NOTFOUND
+ * is used when executing commands and EW_SILENT for interactive expanding. */
+
+#ifdef FEAT_VERTSPLIT
+# define W_WINCOL(wp)	(wp->w_wincol)
+# define W_WIDTH(wp)	(wp->w_width)
+# define W_ENDCOL(wp)	(wp->w_wincol + wp->w_width)
+# define W_VSEP_WIDTH(wp) (wp->w_vsep_width)
+#else
+# define W_WINCOL(wp)	0
+# define W_WIDTH(wp)	Columns
+# define W_ENDCOL(wp)	Columns
+# define W_VSEP_WIDTH(wp) 0
+#endif
+#ifdef FEAT_WINDOWS
+# define W_STATUS_HEIGHT(wp) (wp->w_status_height)
+# define W_WINROW(wp)	(wp->w_winrow)
+#else
+# define W_STATUS_HEIGHT(wp) 0
+# define W_WINROW(wp)	0
+#endif
+
+#ifdef NO_EXPANDPATH
+# define gen_expand_wildcards mch_expand_wildcards
+#endif
+
+/* Values for the find_pattern_in_path() function args 'type' and 'action': */
+#define FIND_ANY	1
+#define FIND_DEFINE	2
+#define CHECK_PATH	3
+
+#define ACTION_SHOW	1
+#define ACTION_GOTO	2
+#define ACTION_SPLIT	3
+#define ACTION_SHOW_ALL	4
+#ifdef FEAT_INS_EXPAND
+# define ACTION_EXPAND	5
+#endif
+
+#ifdef FEAT_SYN_HL
+# define SST_MIN_ENTRIES 150	/* minimal size for state stack array */
+# ifdef FEAT_GUI_W16
+#  define SST_MAX_ENTRIES 500	/* (only up to 64K blocks) */
+# else
+#  define SST_MAX_ENTRIES 1000	/* maximal size for state stack array */
+# endif
+# define SST_FIX_STATES	 7	/* size of sst_stack[]. */
+# define SST_DIST	 16	/* normal distance between entries */
+#endif
+
+/* Values for 'options' argument in do_search() and searchit() */
+#define SEARCH_REV    0x01  /* go in reverse of previous dir. */
+#define SEARCH_ECHO   0x02  /* echo the search command and handle options */
+#define SEARCH_MSG    0x0c  /* give messages (yes, it's not 0x04) */
+#define SEARCH_NFMSG  0x08  /* give all messages except not found */
+#define SEARCH_OPT    0x10  /* interpret optional flags */
+#define SEARCH_HIS    0x20  /* put search pattern in history */
+#define SEARCH_END    0x40  /* put cursor at end of match */
+#define SEARCH_NOOF   0x80  /* don't add offset to position */
+#define SEARCH_START 0x100  /* start search without col offset */
+#define SEARCH_MARK  0x200  /* set previous context mark */
+#define SEARCH_KEEP  0x400  /* keep previous search pattern */
+#define SEARCH_PEEK  0x800  /* peek for typed char, cancel search */
+
+/* Values for find_ident_under_cursor() */
+#define FIND_IDENT	1	/* find identifier (word) */
+#define FIND_STRING	2	/* find any string (WORD) */
+#define FIND_EVAL	4	/* include "->", "[]" and "." */
+
+/* Values for file_name_in_line() */
+#define FNAME_MESS	1	/* give error message */
+#define FNAME_EXP	2	/* expand to path */
+#define FNAME_HYP	4	/* check for hypertext link */
+#define FNAME_INCL	8	/* apply 'includeexpr' */
+#define FNAME_REL	16	/* ".." and "./" are relative to the (current)
+				   file instead of the current directory */
+
+/* Values for buflist_getfile() */
+#define GETF_SETMARK	0x01	/* set pcmark before jumping */
+#define GETF_ALT	0x02	/* jumping to alternate file (not buf num) */
+#define GETF_SWITCH	0x04	/* respect 'switchbuf' settings when jumping */
+
+/* Values for buflist_new() flags */
+#define BLN_CURBUF	1	/* May re-use curbuf for new buffer */
+#define BLN_LISTED	2	/* Put new buffer in buffer list */
+#define BLN_DUMMY	4	/* Allocating dummy buffer */
+
+/* Values for in_cinkeys() */
+#define KEY_OPEN_FORW	0x101
+#define KEY_OPEN_BACK	0x102
+#define KEY_COMPLETE	0x103	/* end of completion */
+
+/* Values for "noremap" argument of ins_typebuf().  Also used for
+ * map->m_noremap and menu->noremap[]. */
+#define REMAP_YES	0	/* allow remapping */
+#define REMAP_NONE	-1	/* no remapping */
+#define REMAP_SCRIPT	-2	/* remap script-local mappings only */
+#define REMAP_SKIP	-3	/* no remapping for first char */
+
+/* Values for mch_call_shell() second argument */
+#define SHELL_FILTER	1	/* filtering text */
+#define SHELL_EXPAND	2	/* expanding wildcards */
+#define SHELL_COOKED	4	/* set term to cooked mode */
+#define SHELL_DOOUT	8	/* redirecting output */
+#define SHELL_SILENT	16	/* don't print error returned by command */
+#define SHELL_READ	32	/* read lines and insert into buffer */
+#define SHELL_WRITE	64	/* write lines from buffer */
+
+/* Values returned by mch_nodetype() */
+#define NODE_NORMAL	0	/* file or directory, check with mch_isdir()*/
+#define NODE_WRITABLE	1	/* something we can write to (character
+				   device, fifo, socket, ..) */
+#define NODE_OTHER	2	/* non-writable thing (e.g., block device) */
+
+/* Values for readfile() flags */
+#define READ_NEW	0x01	/* read a file into a new buffer */
+#define READ_FILTER	0x02	/* read filter output */
+#define READ_STDIN	0x04	/* read from stdin */
+#define READ_BUFFER	0x08	/* read from curbuf (converting stdin) */
+#define READ_DUMMY	0x10	/* reading into a dummy buffer */
+
+/* Values for change_indent() */
+#define INDENT_SET	1	/* set indent */
+#define INDENT_INC	2	/* increase indent */
+#define INDENT_DEC	3	/* decrease indent */
+
+/* Values for flags argument for findmatchlimit() */
+#define FM_BACKWARD	0x01	/* search backwards */
+#define FM_FORWARD	0x02	/* search forwards */
+#define FM_BLOCKSTOP	0x04	/* stop at start/end of block */
+#define FM_SKIPCOMM	0x08	/* skip comments */
+
+/* Values for action argument for do_buffer() */
+#define DOBUF_GOTO	0	/* go to specified buffer */
+#define DOBUF_SPLIT	1	/* split window and go to specified buffer */
+#define DOBUF_UNLOAD	2	/* unload specified buffer(s) */
+#define DOBUF_DEL	3	/* delete specified buffer(s) from buflist */
+#define DOBUF_WIPE	4	/* delete specified buffer(s) really */
+
+/* Values for start argument for do_buffer() */
+#define DOBUF_CURRENT	0	/* "count" buffer from current buffer */
+#define DOBUF_FIRST	1	/* "count" buffer from first buffer */
+#define DOBUF_LAST	2	/* "count" buffer from last buffer */
+#define DOBUF_MOD	3	/* "count" mod. buffer from current buffer */
+
+/* Values for sub_cmd and which_pat argument for search_regcomp() */
+/* Also used for which_pat argument for searchit() */
+#define RE_SEARCH	0	/* save/use pat in/from search_pattern */
+#define RE_SUBST	1	/* save/use pat in/from subst_pattern */
+#define RE_BOTH		2	/* save pat in both patterns */
+#define RE_LAST		2	/* use last used pattern if "pat" is NULL */
+
+/* Second argument for vim_regcomp(). */
+#define RE_MAGIC	1	/* 'magic' option */
+#define RE_STRING	2	/* match in string instead of buffer text */
+#define RE_STRICT	4	/* don't allow [abc] without ] */
+
+#ifdef FEAT_SYN_HL
+/* values for reg_do_extmatch */
+# define REX_SET	1	/* to allow \z\(...\), */
+# define REX_USE	2	/* to allow \z\1 et al. */
+#endif
+
+/* Return values for fullpathcmp() */
+/* Note: can use (fullpathcmp() & FPC_SAME) to check for equal files */
+#define FPC_SAME	1	/* both exist and are the same file. */
+#define FPC_DIFF	2	/* both exist and are different files. */
+#define FPC_NOTX	4	/* both don't exist. */
+#define FPC_DIFFX	6	/* one of them doesn't exist. */
+#define FPC_SAMEX	7	/* both don't exist and file names are same. */
+
+/* flags for do_ecmd() */
+#define ECMD_HIDE	0x01	/* don't free the current buffer */
+#define ECMD_SET_HELP	0x02	/* set b_help flag of (new) buffer before
+				   opening file */
+#define ECMD_OLDBUF	0x04	/* use existing buffer if it exists */
+#define ECMD_FORCEIT	0x08	/* ! used in Ex command */
+#define ECMD_ADDBUF	0x10	/* don't edit, just add to buffer list */
+
+/* for lnum argument in do_ecmd() */
+#define ECMD_LASTL	(linenr_T)0	/* use last position in loaded file */
+#define ECMD_LAST	(linenr_T)-1	/* use last position in all files */
+#define ECMD_ONE	(linenr_T)1	/* use first line */
+
+/* flags for do_cmdline() */
+#define DOCMD_VERBOSE	0x01	/* included command in error message */
+#define DOCMD_NOWAIT	0x02	/* don't call wait_return() and friends */
+#define DOCMD_REPEAT	0x04	/* repeat exec. until getline() returns NULL */
+#define DOCMD_KEYTYPED	0x08	/* don't reset KeyTyped */
+#define DOCMD_EXCRESET	0x10	/* reset exception environment (for debugging)*/
+#define DOCMD_KEEPLINE  0x20	/* keep typed line for repeating with "." */
+
+/* flags for beginline() */
+#define BL_WHITE	1	/* cursor on first non-white in the line */
+#define BL_SOL		2	/* use 'sol' option */
+#define BL_FIX		4	/* don't leave cursor on a NUL */
+
+/* flags for mf_sync() */
+#define MFS_ALL		1	/* also sync blocks with negative numbers */
+#define MFS_STOP	2	/* stop syncing when a character is available */
+#define MFS_FLUSH	4	/* flushed file to disk */
+#define MFS_ZERO	8	/* only write block 0 */
+
+/* flags for buf_copy_options() */
+#define BCO_ENTER	1	/* going to enter the buffer */
+#define BCO_ALWAYS	2	/* always copy the options */
+#define BCO_NOHELP	4	/* don't touch the help related options */
+
+/* flags for do_put() */
+#define PUT_FIXINDENT	1	/* make indent look nice */
+#define PUT_CURSEND	2	/* leave cursor after end of new text */
+#define PUT_CURSLINE	4	/* leave cursor on last line of new text */
+#define PUT_LINE	8	/* put register as lines */
+#define PUT_LINE_SPLIT	16	/* split line for linewise register */
+#define PUT_LINE_FORWARD 32	/* put linewise register below Visual sel. */
+
+/* flags for set_indent() */
+#define SIN_CHANGED	1	/* call changed_bytes() when line changed */
+#define SIN_INSERT	2	/* insert indent before existing text */
+#define SIN_UNDO	4	/* save line for undo before changing it */
+
+/* flags for insertchar() */
+#define INSCHAR_FORMAT	1	/* force formatting */
+#define INSCHAR_DO_COM	2	/* format comments */
+#define INSCHAR_CTRLV	4	/* char typed just after CTRL-V */
+
+/* flags for open_line() */
+#define OPENLINE_DELSPACES  1	/* delete spaces after cursor */
+#define OPENLINE_DO_COM	    2	/* format comments */
+#define OPENLINE_KEEPTRAIL  4	/* keep trailing spaces */
+#define OPENLINE_MARKFIX    8	/* fix mark positions */
+
+/*
+ * There are four history tables:
+ */
+#define HIST_CMD	0	/* colon commands */
+#define HIST_SEARCH	1	/* search commands */
+#define HIST_EXPR	2	/* expressions (from entering = register) */
+#define HIST_INPUT	3	/* input() lines */
+#define HIST_DEBUG	4	/* debug commands */
+#define HIST_COUNT	5	/* number of history tables */
+
+/*
+ * Flags for chartab[].
+ */
+#define CT_CELL_MASK	0x07	/* mask: nr of display cells (1, 2 or 4) */
+#define CT_PRINT_CHAR	0x10	/* flag: set for printable chars */
+#define CT_ID_CHAR	0x20	/* flag: set for ID chars */
+#define CT_FNAME_CHAR	0x40	/* flag: set for file name chars */
+
+/*
+ * Values for do_tag().
+ */
+#define DT_TAG		1	/* jump to newer position or same tag again */
+#define DT_POP		2	/* jump to older position */
+#define DT_NEXT		3	/* jump to next match of same tag */
+#define DT_PREV		4	/* jump to previous match of same tag */
+#define DT_FIRST	5	/* jump to first match of same tag */
+#define DT_LAST		6	/* jump to first match of same tag */
+#define DT_SELECT	7	/* jump to selection from list */
+#define DT_HELP		8	/* like DT_TAG, but no wildcards */
+#define DT_JUMP		9	/* jump to new tag or selection from list */
+#define DT_CSCOPE	10	/* cscope find command (like tjump) */
+#define DT_LTAG		11	/* tag using location list */
+#define DT_FREE		99	/* free cached matches */
+
+/*
+ * flags for find_tags().
+ */
+#define TAG_HELP	1	/* only search for help tags */
+#define TAG_NAMES	2	/* only return name of tag */
+#define	TAG_REGEXP	4	/* use tag pattern as regexp */
+#define	TAG_NOIC	8	/* don't always ignore case */
+#ifdef FEAT_CSCOPE
+# define TAG_CSCOPE	16	/* cscope tag */
+#endif
+#define TAG_VERBOSE	32	/* message verbosity */
+#define TAG_INS_COMP	64	/* Currently doing insert completion */
+#define TAG_KEEP_LANG	128	/* keep current language */
+
+#define TAG_MANY	200	/* When finding many tags (for completion),
+				   find up to this many tags */
+
+/*
+ * Types of dialogs passed to do_vim_dialog().
+ */
+#define VIM_GENERIC	0
+#define VIM_ERROR	1
+#define VIM_WARNING	2
+#define VIM_INFO	3
+#define VIM_QUESTION	4
+#define VIM_LAST_TYPE	4	/* sentinel value */
+
+/*
+ * Return values for functions like gui_yesnocancel()
+ */
+#define VIM_YES		2
+#define VIM_NO		3
+#define VIM_CANCEL	4
+#define VIM_ALL		5
+#define VIM_DISCARDALL  6
+
+/*
+ * arguments for win_split()
+ */
+#define WSP_ROOM	1	/* require enough room */
+#define WSP_VERT	2	/* split vertically */
+#define WSP_TOP		4	/* window at top-left of shell */
+#define WSP_BOT		8	/* window at bottom-right of shell */
+#define WSP_HELP	16	/* creating the help window */
+#define WSP_BELOW	32	/* put new window below/right */
+#define WSP_ABOVE	64	/* put new window above/left */
+
+/*
+ * arguments for gui_set_shellsize()
+ */
+#define RESIZE_VERT	1	/* resize vertically */
+#define RESIZE_HOR	2	/* resize horizontally */
+#define RESIZE_BOTH	15	/* resize in both directions */
+
+/*
+ * "flags" values for option-setting functions.
+ * When OPT_GLOBAL and OPT_LOCAL are both missing, set both local and global
+ * values, get local value.
+ */
+#define OPT_FREE	1	/* free old value if it was allocated */
+#define OPT_GLOBAL	2	/* use global value */
+#define OPT_LOCAL	4	/* use local value */
+#define OPT_MODELINE	8	/* option in modeline */
+#define OPT_WINONLY	16	/* only set window-local options */
+#define OPT_NOWIN	32	/* don't set window-local options */
+
+/* Magic chars used in confirm dialog strings */
+#define DLG_BUTTON_SEP	'\n'
+#define DLG_HOTKEY_CHAR	'&'
+
+/* Values for "starting" */
+#define NO_SCREEN	2	/* no screen updating yet */
+#define NO_BUFFERS	1	/* not all buffers loaded yet */
+/*			0	   not starting anymore */
+
+/* Values for swap_exists_action: what to do when swap file already exists */
+#define SEA_NONE	0	/* don't use dialog */
+#define SEA_DIALOG	1	/* use dialog when possible */
+#define SEA_QUIT	2	/* quit editing the file */
+#define SEA_RECOVER	3	/* recover the file */
+
+/*
+ * Minimal size for block 0 of a swap file.
+ * NOTE: This depends on size of struct block0! It's not done with a sizeof(),
+ * because struct block0 is defined in memline.c (Sorry).
+ * The maximal block size is arbitrary.
+ */
+#define MIN_SWAP_PAGE_SIZE 1048
+#define MAX_SWAP_PAGE_SIZE 50000
+
+/* Special values for current_SID. */
+#define SID_MODELINE	-1	/* when using a modeline */
+#define SID_CMDARG	-2	/* for "--cmd" argument */
+#define SID_CARG	-3	/* for "-c" argument */
+#define SID_ENV		-4	/* for sourcing environment variable */
+#define SID_ERROR	-5	/* option was reset because of an error */
+#define SID_NONE	-6	/* don't set scriptID */
+
+/*
+ * Events for autocommands.
+ */
+enum auto_event
+{
+    EVENT_BUFADD = 0,		/* after adding a buffer to the buffer list */
+    EVENT_BUFNEW,		/* after creating any buffer */
+    EVENT_BUFDELETE,		/* deleting a buffer from the buffer list */
+    EVENT_BUFWIPEOUT,		/* just before really deleting a buffer */
+    EVENT_BUFENTER,		/* after entering a buffer */
+    EVENT_BUFFILEPOST,		/* after renaming a buffer */
+    EVENT_BUFFILEPRE,		/* before renaming a buffer */
+    EVENT_BUFLEAVE,		/* before leaving a buffer */
+    EVENT_BUFNEWFILE,		/* when creating a buffer for a new file */
+    EVENT_BUFREADPOST,		/* after reading a buffer */
+    EVENT_BUFREADPRE,		/* before reading a buffer */
+    EVENT_BUFREADCMD,		/* read buffer using command */
+    EVENT_BUFUNLOAD,		/* just before unloading a buffer */
+    EVENT_BUFHIDDEN,		/* just after buffer becomes hidden */
+    EVENT_BUFWINENTER,		/* after showing a buffer in a window */
+    EVENT_BUFWINLEAVE,		/* just after buffer removed from window */
+    EVENT_BUFWRITEPOST,		/* after writing a buffer */
+    EVENT_BUFWRITEPRE,		/* before writing a buffer */
+    EVENT_BUFWRITECMD,		/* write buffer using command */
+    EVENT_CMDWINENTER,		/* after entering the cmdline window */
+    EVENT_CMDWINLEAVE,		/* before leaving the cmdline window */
+    EVENT_COLORSCHEME,		/* after loading a colorscheme */
+    EVENT_FILEAPPENDPOST,	/* after appending to a file */
+    EVENT_FILEAPPENDPRE,	/* before appending to a file */
+    EVENT_FILEAPPENDCMD,	/* append to a file using command */
+    EVENT_FILECHANGEDSHELL,	/* after shell command that changed file */
+    EVENT_FILECHANGEDSHELLPOST,	/* after (not) reloading changed file */
+    EVENT_FILECHANGEDRO,	/* before first change to read-only file */
+    EVENT_FILEREADPOST,		/* after reading a file */
+    EVENT_FILEREADPRE,		/* before reading a file */
+    EVENT_FILEREADCMD,		/* read from a file using command */
+    EVENT_FILETYPE,		/* new file type detected (user defined) */
+    EVENT_FILEWRITEPOST,	/* after writing a file */
+    EVENT_FILEWRITEPRE,		/* before writing a file */
+    EVENT_FILEWRITECMD,		/* write to a file using command */
+    EVENT_FILTERREADPOST,	/* after reading from a filter */
+    EVENT_FILTERREADPRE,	/* before reading from a filter */
+    EVENT_FILTERWRITEPOST,	/* after writing to a filter */
+    EVENT_FILTERWRITEPRE,	/* before writing to a filter */
+    EVENT_FOCUSGAINED,		/* got the focus */
+    EVENT_FOCUSLOST,		/* lost the focus to another app */
+    EVENT_GUIENTER,		/* after starting the GUI */
+    EVENT_GUIFAILED,		/* after starting the GUI failed */
+    EVENT_INSERTCHANGE,		/* when changing Insert/Replace mode */
+    EVENT_INSERTENTER,		/* when entering Insert mode */
+    EVENT_INSERTLEAVE,		/* when leaving Insert mode */
+    EVENT_MENUPOPUP,		/* just before popup menu is displayed */
+    EVENT_QUICKFIXCMDPOST,	/* after :make, :grep etc */
+    EVENT_QUICKFIXCMDPRE,	/* before :make, :grep etc */
+    EVENT_SESSIONLOADPOST,	/* after loading a session file */
+    EVENT_STDINREADPOST,	/* after reading from stdin */
+    EVENT_STDINREADPRE,		/* before reading from stdin */
+    EVENT_SYNTAX,		/* syntax selected */
+    EVENT_TERMCHANGED,		/* after changing 'term' */
+    EVENT_TERMRESPONSE,		/* after setting "v:termresponse" */
+    EVENT_USER,			/* user defined autocommand */
+    EVENT_VIMENTER,		/* after starting Vim */
+    EVENT_VIMLEAVE,		/* before exiting Vim */
+    EVENT_VIMLEAVEPRE,		/* before exiting Vim and writing .viminfo */
+    EVENT_VIMRESIZED,		/* after Vim window was resized */
+    EVENT_WINENTER,		/* after entering a window */
+    EVENT_WINLEAVE,		/* before leaving a window */
+    EVENT_ENCODINGCHANGED,	/* after changing the 'encoding' option */
+    EVENT_CURSORHOLD,		/* cursor in same position for a while */
+    EVENT_CURSORHOLDI,		/* idem, in Insert mode */
+    EVENT_FUNCUNDEFINED,	/* if calling a function which doesn't exist */
+    EVENT_REMOTEREPLY,		/* upon string reception from a remote vim */
+    EVENT_SWAPEXISTS,		/* found existing swap file */
+    EVENT_SOURCEPRE,		/* before sourcing a Vim script */
+    EVENT_SOURCECMD,		/* sourcing a Vim script using command */
+    EVENT_SPELLFILEMISSING,	/* spell file missing */
+    EVENT_CURSORMOVED,		/* cursor was moved */
+    EVENT_CURSORMOVEDI,		/* cursor was moved in Insert mode */
+    EVENT_TABLEAVE,		/* before leaving a tab page */
+    EVENT_TABENTER,		/* after entering a tab page */
+    EVENT_SHELLCMDPOST,		/* after ":!cmd" */
+    EVENT_SHELLFILTERPOST,	/* after ":1,2!cmd", ":w !cmd", ":r !cmd". */
+    NUM_EVENTS			/* MUST be the last one */
+};
+
+typedef enum auto_event event_T;
+
+/*
+ * Values for index in highlight_attr[].
+ * When making changes, also update HL_FLAGS below!  And update the default
+ * value of 'highlight' in option.c.
+ */
+typedef enum
+{
+    HLF_8 = 0	    /* Meta & special keys listed with ":map", text that is
+		       displayed different from what it is */
+    , HLF_AT	    /* @ and ~ characters at end of screen, characters that
+		       don't really exist in the text */
+    , HLF_D	    /* directories in CTRL-D listing */
+    , HLF_E	    /* error messages */
+    , HLF_H	    /* obsolete, ignored */
+    , HLF_I	    /* incremental search */
+    , HLF_L	    /* last search string */
+    , HLF_M	    /* "--More--" message */
+    , HLF_CM	    /* Mode (e.g., "-- INSERT --") */
+    , HLF_N	    /* line number for ":number" and ":#" commands */
+    , HLF_R	    /* return to continue message and yes/no questions */
+    , HLF_S	    /* status lines */
+    , HLF_SNC	    /* status lines of not-current windows */
+    , HLF_C	    /* column to separate vertically split windows */
+    , HLF_T	    /* Titles for output from ":set all", ":autocmd" etc. */
+    , HLF_V	    /* Visual mode */
+    , HLF_VNC	    /* Visual mode, autoselecting and not clipboard owner */
+    , HLF_W	    /* warning messages */
+    , HLF_WM	    /* Wildmenu highlight */
+    , HLF_FL	    /* Folded line */
+    , HLF_FC	    /* Fold column */
+    , HLF_ADD	    /* Added diff line */
+    , HLF_CHD	    /* Changed diff line */
+    , HLF_DED	    /* Deleted diff line */
+    , HLF_TXD	    /* Text Changed in diff line */
+    , HLF_SC	    /* Sign column */
+    , HLF_SPB	    /* SpellBad */
+    , HLF_SPC	    /* SpellCap */
+    , HLF_SPR	    /* SpellRare */
+    , HLF_SPL	    /* SpellLocal */
+    , HLF_PNI	    /* popup menu normal item */
+    , HLF_PSI	    /* popup menu selected item */
+    , HLF_PSB	    /* popup menu scrollbar */
+    , HLF_PST	    /* popup menu scrollbar thumb */
+    , HLF_TP	    /* tabpage line */
+    , HLF_TPS	    /* tabpage line selected */
+    , HLF_TPF	    /* tabpage line filler */
+    , HLF_CUC	    /* 'cursurcolumn' */
+    , HLF_CUL	    /* 'cursurline' */
+    , HLF_COUNT	    /* MUST be the last one */
+} hlf_T;
+
+/* The HL_FLAGS must be in the same order as the HLF_ enums!
+ * When chainging this also adjust the default for 'highlight'. */
+#define HL_FLAGS {'8', '@', 'd', 'e', 'h', 'i', 'l', 'm', 'M', \
+		  'n', 'r', 's', 'S', 'c', 't', 'v', 'V', 'w', 'W', \
+		  'f', 'F', 'A', 'C', 'D', 'T', '>', \
+		  'B', 'P', 'R', 'L', \
+		  '+', '=', 'x', 'X', '*', '#', '_', '!', '.'}
+
+/*
+ * Boolean constants
+ */
+#ifndef TRUE
+# define FALSE	0	    /* note: this is an int, not a long! */
+# define TRUE	1
+#endif
+
+#define MAYBE	2	    /* sometimes used for a variant on TRUE */
+
+/*
+ * Operator IDs; The order must correspond to opchars[] in ops.c!
+ */
+#define OP_NOP		0	/* no pending operation */
+#define OP_DELETE	1	/* "d"  delete operator */
+#define OP_YANK		2	/* "y"  yank operator */
+#define OP_CHANGE	3	/* "c"  change operator */
+#define OP_LSHIFT	4	/* "<"  left shift operator */
+#define OP_RSHIFT	5	/* ">"  right shift operator */
+#define OP_FILTER	6	/* "!"  filter operator */
+#define OP_TILDE	7	/* "g~" switch case operator */
+#define OP_INDENT	8	/* "="  indent operator */
+#define OP_FORMAT	9	/* "gq" format operator */
+#define OP_COLON	10	/* ":"  colon operator */
+#define OP_UPPER	11	/* "gU" make upper case operator */
+#define OP_LOWER	12	/* "gu" make lower case operator */
+#define OP_JOIN		13	/* "J"  join operator, only for Visual mode */
+#define OP_JOIN_NS	14	/* "gJ"  join operator, only for Visual mode */
+#define OP_ROT13	15	/* "g?" rot-13 encoding */
+#define OP_REPLACE	16	/* "r"  replace chars, only for Visual mode */
+#define OP_INSERT	17	/* "I"  Insert column, only for Visual mode */
+#define OP_APPEND	18	/* "A"  Append column, only for Visual mode */
+#define OP_FOLD		19	/* "zf" define a fold */
+#define OP_FOLDOPEN	20	/* "zo" open folds */
+#define OP_FOLDOPENREC	21	/* "zO" open folds recursively */
+#define OP_FOLDCLOSE	22	/* "zc" close folds */
+#define OP_FOLDCLOSEREC	23	/* "zC" close folds recursively */
+#define OP_FOLDDEL	24	/* "zd" delete folds */
+#define OP_FOLDDELREC	25	/* "zD" delete folds recursively */
+#define OP_FORMAT2	26	/* "gw" format operator, keeps cursor pos */
+#define OP_FUNCTION	27	/* "g@" call 'operatorfunc' */
+
+/*
+ * Motion types, used for operators and for yank/delete registers.
+ */
+#define MCHAR	0		/* character-wise movement/register */
+#define MLINE	1		/* line-wise movement/register */
+#define MBLOCK	2		/* block-wise register */
+
+#define MAUTO	0xff		/* Decide between MLINE/MCHAR */
+
+/*
+ * Minimum screen size
+ */
+#define MIN_COLUMNS	12	/* minimal columns for screen */
+#define MIN_LINES	2	/* minimal lines for screen */
+#define STATUS_HEIGHT	1	/* height of a status line under a window */
+#define QF_WINHEIGHT	10	/* default height for quickfix window */
+
+/*
+ * Buffer sizes
+ */
+#ifndef CMDBUFFSIZE
+# define CMDBUFFSIZE	256	/* size of the command processing buffer */
+#endif
+
+#define LSIZE	    512		/* max. size of a line in the tags file */
+
+#define IOSIZE	   (1024+1)	/* file i/o and sprintf buffer size */
+
+#ifdef FEAT_MBYTE
+# define MSG_BUF_LEN 480	/* length of buffer for small messages */
+# define MSG_BUF_CLEN  (MSG_BUF_LEN / 6)    /* cell length (worst case: utf-8
+					       takes 6 bytes for one cell) */
+#else
+# define MSG_BUF_LEN 80		/* length of buffer for small messages */
+# define MSG_BUF_CLEN  MSG_BUF_LEN	    /* cell length */
+#endif
+
+#if defined(AMIGA) || defined(__linux__) || defined(__QNX__) || defined(__CYGWIN32__) || defined(_AIX)
+# define TBUFSZ 2048		/* buffer size for termcap entry */
+#else
+# define TBUFSZ 1024		/* buffer size for termcap entry */
+#endif
+
+/*
+ * Maximum length of key sequence to be mapped.
+ * Must be able to hold an Amiga resize report.
+ */
+#define MAXMAPLEN   50
+
+#ifdef BINARY_FILE_IO
+# define WRITEBIN   "wb"	/* no CR-LF translation */
+# define READBIN    "rb"
+# define APPENDBIN  "ab"
+#else
+# define WRITEBIN   "w"
+# define READBIN    "r"
+# define APPENDBIN  "a"
+#endif
+
+/*
+ * EMX doesn't have a global way of making open() use binary I/O.
+ * Use O_BINARY for all open() calls.
+ */
+#if defined(__EMX__) || defined(__CYGWIN32__)
+# define O_EXTRA    O_BINARY
+#else
+# define O_EXTRA    0
+#endif
+
+#ifndef O_NOFOLLOW
+# define O_NOFOLLOW 0
+#endif
+
+#ifndef W_OK
+# define W_OK 2		/* for systems that don't have W_OK in unistd.h */
+#endif
+#ifndef R_OK
+# define R_OK 4		/* for systems that don't have R_OK in unistd.h */
+#endif
+
+/*
+ * defines to avoid typecasts from (char_u *) to (char *) and back
+ * (vim_strchr() and vim_strrchr() are now in alloc.c)
+ */
+#define STRLEN(s)	    strlen((char *)(s))
+#define STRCPY(d, s)	    strcpy((char *)(d), (char *)(s))
+#define STRNCPY(d, s, n)    strncpy((char *)(d), (char *)(s), (size_t)(n))
+#define STRCMP(d, s)	    strcmp((char *)(d), (char *)(s))
+#define STRNCMP(d, s, n)    strncmp((char *)(d), (char *)(s), (size_t)(n))
+#ifdef HAVE_STRCASECMP
+# define STRICMP(d, s)	    strcasecmp((char *)(d), (char *)(s))
+#else
+# ifdef HAVE_STRICMP
+#  define STRICMP(d, s)	    stricmp((char *)(d), (char *)(s))
+# else
+#  define STRICMP(d, s)	    vim_stricmp((char *)(d), (char *)(s))
+# endif
+#endif
+
+#ifdef HAVE_STRNCASECMP
+# define STRNICMP(d, s, n)  strncasecmp((char *)(d), (char *)(s), (size_t)(n))
+#else
+# ifdef HAVE_STRNICMP
+#  define STRNICMP(d, s, n) strnicmp((char *)(d), (char *)(s), (size_t)(n))
+# else
+#  define STRNICMP(d, s, n) vim_strnicmp((char *)(d), (char *)(s), (size_t)(n))
+# endif
+#endif
+
+#ifdef FEAT_MBYTE
+# define MB_STRICMP(d, s)	(has_mbyte ? mb_strnicmp((char_u *)(d), (char_u *)(s), (int)MAXCOL) : STRICMP((d), (s)))
+# define MB_STRNICMP(d, s, n)	(has_mbyte ? mb_strnicmp((char_u *)(d), (char_u *)(s), (int)(n)) : STRNICMP((d), (s), (n)))
+#else
+# define MB_STRICMP(d, s)	STRICMP((d), (s))
+# define MB_STRNICMP(d, s, n)	STRNICMP((d), (s), (n))
+#endif
+
+#define STRCAT(d, s)	    strcat((char *)(d), (char *)(s))
+#define STRNCAT(d, s, n)    strncat((char *)(d), (char *)(s), (size_t)(n))
+
+#ifdef HAVE_STRPBRK
+# define vim_strpbrk(s, cs) (char_u *)strpbrk((char *)(s), (char *)(cs))
+#endif
+
+#define MSG(s)			    msg((char_u *)(s))
+#define MSG_ATTR(s, attr)	    msg_attr((char_u *)(s), (attr))
+#define EMSG(s)			    emsg((char_u *)(s))
+#define EMSG2(s, p)		    emsg2((char_u *)(s), (char_u *)(p))
+#define EMSG3(s, p, q)		    emsg3((char_u *)(s), (char_u *)(p), (char_u *)(q))
+#define EMSGN(s, n)		    emsgn((char_u *)(s), (long)(n))
+#define EMSGU(s, n)		    emsgu((char_u *)(s), (long_u)(n))
+#define OUT_STR(s)		    out_str((char_u *)(s))
+#define OUT_STR_NF(s)		    out_str_nf((char_u *)(s))
+#define MSG_PUTS(s)		    msg_puts((char_u *)(s))
+#define MSG_PUTS_ATTR(s, a)	    msg_puts_attr((char_u *)(s), (a))
+#define MSG_PUTS_TITLE(s)	    msg_puts_title((char_u *)(s))
+#define MSG_PUTS_LONG(s)	    msg_puts_long_attr((char_u *)(s), 0)
+#define MSG_PUTS_LONG_ATTR(s, a)    msg_puts_long_attr((char_u *)(s), (a))
+
+/* Prefer using emsg3(), because perror() may send the output to the wrong
+ * destination and mess up the screen. */
+#ifdef HAVE_STRERROR
+# define PERROR(msg)		    (void)emsg3((char_u *)"%s: %s", (char_u *)msg, (char_u *)strerror(errno))
+#else
+# define PERROR(msg)		    perror(msg)
+#endif
+
+typedef long	    linenr_T;		/* line number type */
+typedef unsigned    colnr_T;		/* column number type */
+typedef unsigned short disptick_T;	/* display tick type */
+
+#define MAXLNUM (0x7fffffffL)		/* maximum (invalid) line number */
+
+/*
+ * Well, you won't believe it, but some S/390 machines ("host", now also known
+ * as zServer) us 31 bit pointers. There are also some newer machines, that
+ * use 64 bit pointers. I don't know how to distinguish between 31 and 64 bit
+ * machines, so the best way is to assume 31 bits whenever we detect OS/390
+ * Unix.
+ * With this we restrict the maximum line length to 1073741823. I guess this is
+ * not a real problem. BTW:  Longer lines are split.
+ */
+#if SIZEOF_INT >= 4
+# ifdef __MVS__
+#  define MAXCOL (0x3fffffffL)		/* maximum column number, 30 bits */
+# else
+#  define MAXCOL (0x7fffffffL)		/* maximum column number, 31 bits */
+# endif
+#else
+# define MAXCOL	(0x7fff)		/* maximum column number, 15 bits */
+#endif
+
+#define SHOWCMD_COLS 10			/* columns needed by shown command */
+#define STL_MAX_ITEM 80			/* max nr of %<flag> in statusline */
+
+typedef void	    *vim_acl_T;		/* dummy to pass an ACL to a function */
+
+/*
+ * Include a prototype for mch_memmove(), it may not be in alloc.pro.
+ */
+#ifdef VIM_MEMMOVE
+void mch_memmove __ARGS((void *, void *, size_t));
+#else
+# ifndef mch_memmove
+#  define mch_memmove(to, from, len) memmove(to, from, len)
+# endif
+#endif
+
+/*
+ * fnamecmp() is used to compare file names.
+ * On some systems case in a file name does not matter, on others it does.
+ * (this does not account for maximum name lengths and things like "../dir",
+ * thus it is not 100% accurate!)
+ */
+#ifdef CASE_INSENSITIVE_FILENAME
+# ifdef BACKSLASH_IN_FILENAME
+#  define fnamecmp(x, y) vim_fnamecmp((x), (y))
+#  define fnamencmp(x, y, n) vim_fnamencmp((x), (y), (size_t)(n))
+# else
+#  define fnamecmp(x, y) MB_STRICMP((x), (y))
+#  define fnamencmp(x, y, n) MB_STRNICMP((x), (y), (n))
+# endif
+#else
+# define fnamecmp(x, y) strcmp((char *)(x), (char *)(y))
+# define fnamencmp(x, y, n) strncmp((char *)(x), (char *)(y), (size_t)(n))
+#endif
+
+#ifdef HAVE_MEMSET
+# define vim_memset(ptr, c, size)   memset((ptr), (c), (size))
+#else
+void *vim_memset __ARGS((void *, int, size_t));
+#endif
+
+#ifdef HAVE_MEMCMP
+# define vim_memcmp(p1, p2, len)   memcmp((p1), (p2), (len))
+#else
+# ifdef HAVE_BCMP
+#  define vim_memcmp(p1, p2, len)   bcmp((p1), (p2), (len))
+# else
+int vim_memcmp __ARGS((void *, void *, size_t));
+#  define VIM_MEMCMP
+# endif
+#endif
+
+#if defined(UNIX) || defined(FEAT_GUI) || defined(OS2) || defined(VMS) \
+	|| defined(FEAT_CLIENTSERVER) || defined(PLAN9)
+# define USE_INPUT_BUF
+#endif
+
+#ifdef MSWIN
+/* On MS-Windows the third argument isn't size_t.  This matters for Win64,
+ * where sizeof(size_t)==8, not 4 */
+# define vim_read(fd, buf, count)   read((fd), (char *)(buf), (unsigned int)(count))
+# define vim_write(fd, buf, count)  write((fd), (char *)(buf), (unsigned int)(count))
+#else
+# define vim_read(fd, buf, count)   read((fd), (char *)(buf), (size_t) (count))
+# define vim_write(fd, buf, count)  write((fd), (char *)(buf), (size_t) (count))
+#endif
+
+/*
+ * Enums need a typecast to be used as array index (for Ultrix).
+ */
+#define hl_attr(n)	highlight_attr[(int)(n)]
+#define term_str(n)	term_strings[(int)(n)]
+
+/*
+ * vim_iswhite() is used for "^" and the like. It differs from isspace()
+ * because it doesn't include <CR> and <LF> and the like.
+ */
+#define vim_iswhite(x)	((x) == ' ' || (x) == '\t')
+
+/*
+ * EXTERN is only defined in main.c.  That's where global variables are
+ * actually defined and initialized.
+ */
+#ifndef EXTERN
+# define EXTERN extern
+# define INIT(x)
+#else
+# ifndef INIT
+#  define INIT(x) x
+#  define DO_INIT
+# endif
+#endif
+
+#ifdef FEAT_MBYTE
+# define MAX_MCO	6	/* maximum value for 'maxcombine' */
+
+/* Maximum number of bytes in a multi-byte character.  It can be one 32-bit
+ * character of up to 6 bytes, or one 16-bit character of up to three bytes
+ * plus six following composing characters of three bytes each. */
+# define MB_MAXBYTES	21
+#endif
+
+/* Include option.h before structs.h, because the number of window-local and
+ * buffer-local options is used there. */
+#include "option.h"	    /* options and default values */
+
+/* Note that gui.h is included by structs.h */
+
+#include "structs.h"	    /* file that defines many structures */
+
+/* Values for "do_profiling". */
+#define PROF_NONE	0	/* profiling not started */
+#define PROF_YES	1	/* profiling busy */
+#define PROF_PAUSED	2	/* profiling paused */
+
+#ifdef FEAT_MOUSE
+
+/* Codes for mouse button events in lower three bits: */
+# define MOUSE_LEFT	0x00
+# define MOUSE_MIDDLE	0x01
+# define MOUSE_RIGHT	0x02
+# define MOUSE_RELEASE	0x03
+
+/* bit masks for modifiers: */
+# define MOUSE_SHIFT	0x04
+# define MOUSE_ALT	0x08
+# define MOUSE_CTRL	0x10
+
+/* mouse buttons that are handled like a key press (GUI only) */
+# define MOUSE_4	0x100	/* scroll wheel down */
+# define MOUSE_5	0x200	/* scroll wheel up */
+
+# define MOUSE_X1	0x300 /* Mouse-button X1 (6th) */
+# define MOUSE_X2	0x400 /* Mouse-button X2 */
+
+/* 0x20 is reserved by xterm */
+# define MOUSE_DRAG_XTERM   0x40
+
+# define MOUSE_DRAG	(0x40 | MOUSE_RELEASE)
+
+/* Lowest button code for using the mouse wheel (xterm only) */
+# define MOUSEWHEEL_LOW		0x60
+
+# define MOUSE_CLICK_MASK	0x03
+
+# define NUM_MOUSE_CLICKS(code) \
+    (((unsigned)((code) & 0xC0) >> 6) + 1)
+
+# define SET_NUM_MOUSE_CLICKS(code, num) \
+    (code) = ((code) & 0x3f) | ((((num) - 1) & 3) << 6)
+
+/* Added to mouse column for GUI when 'mousefocus' wants to give focus to a
+ * window by simulating a click on its status line.  We could use up to 128 *
+ * 128 = 16384 columns, now it's reduced to 10000. */
+# define MOUSE_COLOFF 10000
+
+/*
+ * jump_to_mouse() returns one of first four these values, possibly with
+ * some of the other three added.
+ */
+# define IN_UNKNOWN		0
+# define IN_BUFFER		1
+# define IN_STATUS_LINE		2	/* on status or command line */
+# define IN_SEP_LINE		4	/* on vertical separator line */
+# define IN_OTHER_WIN		8	/* in other window but can't go there */
+# define CURSOR_MOVED		0x100
+# define MOUSE_FOLD_CLOSE	0x200	/* clicked on '-' in fold column */
+# define MOUSE_FOLD_OPEN	0x400	/* clicked on '+' in fold column */
+
+/* flags for jump_to_mouse() */
+# define MOUSE_FOCUS		0x01	/* need to stay in this window */
+# define MOUSE_MAY_VIS		0x02	/* may start Visual mode */
+# define MOUSE_DID_MOVE		0x04	/* only act when mouse has moved */
+# define MOUSE_SETPOS		0x08	/* only set current mouse position */
+# define MOUSE_MAY_STOP_VIS	0x10	/* may stop Visual mode */
+# define MOUSE_RELEASED		0x20	/* button was released */
+
+# if defined(UNIX) && defined(HAVE_GETTIMEOFDAY) && defined(HAVE_SYS_TIME_H)
+#  define CHECK_DOUBLE_CLICK 1	/* Checking for double clicks ourselves. */
+# endif
+
+#endif /* FEAT_MOUSE */
+
+/* defines for eval_vars() */
+#define VALID_PATH		1
+#define VALID_HEAD		2
+
+/* Defines for Vim variables.  These must match vimvars[] in eval.c! */
+#define VV_COUNT	0
+#define VV_COUNT1	1
+#define VV_PREVCOUNT	2
+#define VV_ERRMSG	3
+#define VV_WARNINGMSG	4
+#define VV_STATUSMSG	5
+#define VV_SHELL_ERROR	6
+#define VV_THIS_SESSION	7
+#define VV_VERSION	8
+#define VV_LNUM		9
+#define VV_TERMRESPONSE	10
+#define VV_FNAME	11
+#define VV_LANG		12
+#define VV_LC_TIME	13
+#define VV_CTYPE	14
+#define VV_CC_FROM	15
+#define VV_CC_TO	16
+#define VV_FNAME_IN	17
+#define VV_FNAME_OUT	18
+#define VV_FNAME_NEW	19
+#define VV_FNAME_DIFF	20
+#define VV_CMDARG	21
+#define VV_FOLDSTART	22
+#define VV_FOLDEND	23
+#define VV_FOLDDASHES	24
+#define VV_FOLDLEVEL	25
+#define VV_PROGNAME	26
+#define VV_SEND_SERVER	27
+#define VV_DYING	28
+#define VV_EXCEPTION	29
+#define VV_THROWPOINT	30
+#define VV_REG		31
+#define VV_CMDBANG	32
+#define VV_INSERTMODE	33
+#define VV_VAL		34
+#define VV_KEY		35
+#define VV_PROFILING	36
+#define VV_FCS_REASON	37
+#define VV_FCS_CHOICE	38
+#define VV_BEVAL_BUFNR	39
+#define VV_BEVAL_WINNR	40
+#define VV_BEVAL_LNUM	41
+#define VV_BEVAL_COL	42
+#define VV_BEVAL_TEXT	43
+#define VV_SCROLLSTART	44
+#define VV_SWAPNAME	45
+#define VV_SWAPCHOICE	46
+#define VV_SWAPCOMMAND	47
+#define VV_CHAR		48
+#define VV_MOUSE_WIN	49
+#define VV_MOUSE_LNUM   50
+#define VV_MOUSE_COL	51
+#define VV_LEN		52	/* number of v: vars */
+
+#ifdef FEAT_CLIPBOARD
+
+/* VIM_ATOM_NAME is the older Vim-specific selection type for X11.  Still
+ * supported for when a mix of Vim versions is used. VIMENC_ATOM_NAME includes
+ * the encoding to support Vims using different 'encoding' values. */
+#define VIM_ATOM_NAME "_VIM_TEXT"
+#define VIMENC_ATOM_NAME "_VIMENC_TEXT"
+
+/* Selection states for modeless selection */
+# define SELECT_CLEARED		0
+# define SELECT_IN_PROGRESS	1
+# define SELECT_DONE		2
+
+# define SELECT_MODE_CHAR	0
+# define SELECT_MODE_WORD	1
+# define SELECT_MODE_LINE	2
+
+# ifdef FEAT_GUI_W32
+#  ifdef FEAT_OLE
+#   define WM_OLE (WM_APP+0)
+#  endif
+#  ifdef FEAT_NETBEANS_INTG
+    /* message for Netbeans socket event */
+#   define WM_NETBEANS (WM_APP+1)
+#  endif
+# endif
+
+/* Info about selected text */
+typedef struct VimClipboard
+{
+    int		available;	/* Is clipboard available? */
+    int		owned;		/* Flag: do we own the selection? */
+    pos_T	start;		/* Start of selected area */
+    pos_T	end;		/* End of selected area */
+    int		vmode;		/* Visual mode character */
+
+    /* Fields for selection that doesn't use Visual mode */
+    short_u	origin_row;
+    short_u	origin_start_col;
+    short_u	origin_end_col;
+    short_u	word_start_col;
+    short_u	word_end_col;
+
+    pos_T	prev;		/* Previous position */
+    short_u	state;		/* Current selection state */
+    short_u	mode;		/* Select by char, word, or line. */
+
+# if defined(FEAT_GUI_X11) || defined(FEAT_XCLIPBOARD)
+    Atom	sel_atom;	/* PRIMARY/CLIPBOARD selection ID */
+# endif
+
+# ifdef FEAT_GUI_GTK
+    GdkAtom     gtk_sel_atom;	/* PRIMARY/CLIPBOARD selection ID */
+# endif
+
+# ifdef MSWIN
+    int_u	format;		/* Vim's own special clipboard format */
+    int_u	format_raw;	/* Vim's raw text clipboard format */
+# endif
+} VimClipboard;
+#else
+typedef int VimClipboard;	/* This is required for the prototypes. */
+#endif
+
+#ifdef __BORLANDC__
+/* work around a bug in the Borland 'stat' function: */
+# include <io.h>	    /* for access() */
+
+# define stat(a,b) (access(a,0) ? -1 : stat(a,b))
+#endif
+
+#if (defined(FEAT_PROFILE) || defined(FEAT_RELTIME)) && !defined(PROTO)
+# ifdef WIN3264
+typedef LARGE_INTEGER proftime_T;
+# else
+typedef struct timeval proftime_T;
+# endif
+#else
+typedef int proftime_T;	    /* dummy for function prototypes */
+#endif
+
+#include "ex_cmds.h"	    /* Ex command defines */
+#include "proto.h"	    /* function prototypes */
+
+/* This has to go after the include of proto.h, as proto/gui.pro declares
+ * functions of these names. The declarations would break if the defines had
+ * been seen at that stage.  But it must be before globals.h, where error_ga
+ * is declared. */
+#if !defined(FEAT_GUI_W32) && !defined(FEAT_GUI_X11) \
+	&& !defined(FEAT_GUI_GTK) && !defined(FEAT_GUI_MAC)
+# define mch_errmsg(str)	fprintf(stderr, "%s", (str))
+# define display_errors()	fflush(stderr)
+# define mch_msg(str)		printf("%s", (str))
+#else
+# define USE_MCH_ERRMSG
+#endif
+
+#ifndef FEAT_MBYTE
+# define after_pathsep(b, p)	vim_ispathsep(*((p) - 1))
+# define transchar_byte(c)	transchar(c)
+#endif
+
+#ifndef FEAT_LINEBREAK
+/* Without the 'numberwidth' option line numbers are always 7 chars. */
+# define number_width(x) 7
+#endif
+
+
+#include "globals.h"	    /* global variables and messages */
+
+#ifdef FEAT_SNIFF
+# include "if_sniff.h"
+#endif
+
+#ifndef FEAT_VIRTUALEDIT
+# define getvvcol(w, p, s, c, e) getvcol(w, p, s, c, e)
+# define virtual_active() 0
+# define virtual_op FALSE
+#endif
+
+/*
+ * If console dialog not supported, but GUI dialog is, use the GUI one.
+ */
+#if defined(FEAT_GUI_DIALOG) && !defined(FEAT_CON_DIALOG)
+# define do_dialog gui_mch_dialog
+#endif
+
+/*
+ * Default filters for gui_mch_browse().
+ * The filters are almost system independent.  Except for the difference
+ * between "*" and "*.*" for MSDOS-like systems.
+ * NOTE: Motif only uses the very first pattern.  Therefore
+ * BROWSE_FILTER_DEFAULT should start with a "*" pattern.
+ */
+#ifdef FEAT_BROWSE
+# ifdef BACKSLASH_IN_FILENAME
+#  define BROWSE_FILTER_MACROS \
+	(char_u *)"Vim macro files (*.vim)\t*.vim\nAll Files (*.*)\t*.*\n"
+#  define BROWSE_FILTER_ALL_FILES (char_u *)"All Files (*.*)\t*.*\n"
+#  define BROWSE_FILTER_DEFAULT \
+	(char_u *)"All Files (*.*)\t*.*\nC source (*.c, *.h)\t*.c;*.h\nC++ source (*.cpp, *.hpp)\t*.cpp;*.hpp\nVB code (*.bas, *.frm)\t*.bas;*.frm\nVim files (*.vim, _vimrc, _gvimrc)\t*.vim;_vimrc;_gvimrc\n"
+# else
+#  define BROWSE_FILTER_MACROS \
+	(char_u *)"Vim macro files (*.vim)\t*.vim\nAll Files (*)\t*\n"
+#  define BROWSE_FILTER_ALL_FILES (char_u *)"All Files (*)\t*\n"
+#  define BROWSE_FILTER_DEFAULT \
+	(char_u *)"All Files (*)\t*\nC source (*.c, *.h)\t*.c;*.h\nC++ source (*.cpp, *.hpp)\t*.cpp;*.hpp\nVim files (*.vim, _vimrc, _gvimrc)\t*.vim;_vimrc;_gvimrc\n"
+# endif
+# define BROWSE_SAVE 1	    /* flag for do_browse() */
+# define BROWSE_DIR 2	    /* flag for do_browse() */
+#endif
+
+/* stop using fastcall for Borland */
+#if defined(__BORLANDC__) && defined(WIN32) && !defined(DEBUG)
+ #pragma option -p.
+#endif
+
+#if defined(MEM_PROFILE)
+# define vim_realloc(ptr, size)  mem_realloc((ptr), (size))
+#else
+# define vim_realloc(ptr, size)  realloc((ptr), (size))
+#endif
+
+/*
+ * The following macros stop display/event loop nesting at the wrong time.
+ */
+#ifdef ALT_X_INPUT
+# define ALT_INPUT_LOCK_OFF	suppress_alternate_input = FALSE
+# define ALT_INPUT_LOCK_ON	suppress_alternate_input = TRUE
+#endif
+
+#ifdef FEAT_MBYTE
+/*
+ * Return byte length of character that starts with byte "b".
+ * Returns 1 for a single-byte character.
+ * MB_BYTE2LEN_CHECK() can be used to count a special key as one byte.
+ * Don't call MB_BYTE2LEN(b) with b < 0 or b > 255!
+ */
+# define MB_BYTE2LEN(b)		mb_bytelen_tab[b]
+# define MB_BYTE2LEN_CHECK(b)	(((b) < 0 || (b) > 255) ? 1 : mb_bytelen_tab[b])
+#endif
+
+#if defined(FEAT_MBYTE) || defined(FEAT_POSTSCRIPT)
+/* properties used in enc_canon_table[] (first three mutually exclusive) */
+# define ENC_8BIT	0x01
+# define ENC_DBCS	0x02
+# define ENC_UNICODE	0x04
+
+# define ENC_ENDIAN_B	0x10	    /* Unicode: Big endian */
+# define ENC_ENDIAN_L	0x20	    /* Unicode: Little endian */
+
+# define ENC_2BYTE	0x40	    /* Unicode: UCS-2 */
+# define ENC_4BYTE	0x80	    /* Unicode: UCS-4 */
+# define ENC_2WORD	0x100	    /* Unicode: UTF-16 */
+
+# define ENC_LATIN1	0x200	    /* Latin1 */
+# define ENC_LATIN9	0x400	    /* Latin9 */
+# define ENC_MACROMAN	0x800	    /* Mac Roman (not Macro Man! :-) */
+#endif
+
+#ifdef FEAT_MBYTE
+# ifdef USE_ICONV
+#  ifndef EILSEQ
+#   define EILSEQ 123
+#  endif
+#  ifdef DYNAMIC_ICONV
+/* On Win32 iconv.dll is dynamically loaded. */
+#   define ICONV_ERRNO (*iconv_errno())
+#   define ICONV_E2BIG  7
+#   define ICONV_EINVAL 22
+#   define ICONV_EILSEQ 42
+#  else
+#   define ICONV_ERRNO errno
+#   define ICONV_E2BIG  E2BIG
+#   define ICONV_EINVAL EINVAL
+#   define ICONV_EILSEQ EILSEQ
+#  endif
+# endif
+
+#endif
+
+/* ISSYMLINK(mode) tests if a file is a symbolic link. */
+#if (defined(S_IFMT) && defined(S_IFLNK)) || defined(S_ISLNK)
+# define HAVE_ISSYMLINK
+# if defined(S_IFMT) && defined(S_IFLNK)
+#  define ISSYMLINK(mode) (((mode) & S_IFMT) == S_IFLNK)
+# else
+#  define ISSYMLINK(mode) S_ISLNK(mode)
+# endif
+#endif
+
+#define SIGN_BYTE 1	    /* byte value used where sign is displayed;
+			       attribute value is sign type */
+
+#ifdef FEAT_NETBEANS_INTG
+# define MULTISIGN_BYTE 2   /* byte value used where sign is displayed if
+			       multiple signs exist on the line */
+#endif
+
+#if defined(FEAT_GUI) && defined(FEAT_XCLIPBOARD)
+# ifdef FEAT_GUI_GTK
+   /* Avoid using a global variable for the X display.  It's ugly
+    * and is likely to cause trouble in multihead environments. */
+#  define X_DISPLAY	((gui.in_use) ? gui_mch_get_display() : xterm_dpy)
+# else
+#  define X_DISPLAY	(gui.in_use ? gui.dpy : xterm_dpy)
+# endif
+#else
+# ifdef FEAT_GUI
+#  ifdef FEAT_GUI_GTK
+#   define X_DISPLAY	((gui.in_use) ? gui_mch_get_display() : (Display *)NULL)
+#  else
+#   define X_DISPLAY	gui.dpy
+#  endif
+# else
+#  define X_DISPLAY	xterm_dpy
+# endif
+#endif
+
+#ifdef NBDEBUG /* Netbeans debugging. */
+# include "nbdebug.h"
+#else
+# define nbdebug(a)
+#endif
+
+#ifdef IN_PERL_FILE
+  /*
+   * Avoid clashes between Perl and Vim namespace.
+   */
+# undef NORMAL
+# undef STRLEN
+# undef FF
+# undef OP_DELETE
+# undef OP_JOIN
+# ifdef __BORLANDC__
+#  define NOPROTO 1
+# endif
+  /* remove MAX and MIN, included by glib.h, redefined by sys/param.h */
+# ifdef MAX
+#  undef MAX
+# endif
+# ifdef MIN
+#  undef MIN
+# endif
+  /* We use _() for gettext(), Perl uses it for function prototypes... */
+# ifdef _
+#  undef _
+# endif
+# ifdef DEBUG
+#  undef DEBUG
+# endif
+# ifdef _DEBUG
+#  undef _DEBUG
+# endif
+# ifdef instr
+#  undef instr
+# endif
+  /* bool causes trouble on MACOS but is required on a few other systems */
+# if defined(bool) && defined(MACOS)
+#  undef bool
+# endif
+
+# ifdef __BORLANDC__
+  /* Borland has the structure stati64 but not _stati64 */
+#  define _stati64 stati64
+# endif
+
+# include <EXTERN.h>
+# include <perl.h>
+# include <XSUB.h>
+#endif
+
+/* values for vim_handle_signal() that are not a signal */
+#define SIGNAL_BLOCK	-1
+#define SIGNAL_UNBLOCK  -2
+#if !defined(UNIX) && !defined(VMS) && !defined(OS2)
+# define vim_handle_signal(x) 0
+#endif
+
+/* flags for skip_vimgrep_pat() */
+#define VGR_GLOBAL	1
+#define VGR_NOJUMP	2
+
+/* behavior for bad character, "++bad=" argument */
+#define BAD_REPLACE	'?'	/* replace it with '?' (default) */
+#define BAD_KEEP	-1	/* leave it */
+#define BAD_DROP	-2	/* erase it */
+
+/* last argument for do_source() */
+#define DOSO_NONE	0
+#define DOSO_VIMRC	1	/* loading vimrc file */
+#define DOSO_GVIMRC	2	/* loading gvimrc file */
+
+#endif /* VIM__H */
--- /dev/null
+++ b/vim.proto
@@ -1,0 +1,13 @@
+# Vim: enhanced vi editor
+386	- sys sys
+	bin	- sys sys
+		vim	- sys sys
+		xxd	- sys sys
+sys	- sys sys
+	lib	- sys sys 
+		vim	- sys sys 
+			+	- sys sys 
+	src	- sys sys
+		cmd	- sys sys
+			vim	- sys sys
+				+	- sys sys
--- /dev/null
+++ b/window.c
@@ -1,0 +1,6176 @@
+/* vi:set ts=8 sts=4 sw=4:
+ *
+ * VIM - Vi IMproved	by Bram Moolenaar
+ *
+ * Do ":help uganda"  in Vim to read a list of people who contributed.
+ * Do ":help credits" in Vim to see a list of people who contributed.
+ * See README.txt for an overview of the Vim source code.
+ */
+
+#include "vim.h"
+
+#ifdef HAVE_FCNTL_H
+# include <fcntl.h>	    /* for chdir() */
+#endif
+
+static int path_is_url __ARGS((char_u *p));
+#if defined(FEAT_WINDOWS) || defined(PROTO)
+static int win_split_ins __ARGS((int size, int flags, win_T *newwin, int dir));
+static void win_init __ARGS((win_T *newp, win_T *oldp));
+static void frame_comp_pos __ARGS((frame_T *topfrp, int *row, int *col));
+static void frame_setheight __ARGS((frame_T *curfrp, int height));
+#ifdef FEAT_VERTSPLIT
+static void frame_setwidth __ARGS((frame_T *curfrp, int width));
+#endif
+static void win_exchange __ARGS((long));
+static void win_rotate __ARGS((int, int));
+static void win_totop __ARGS((int size, int flags));
+static void win_equal_rec __ARGS((win_T *next_curwin, int current, frame_T *topfr, int dir, int col, int row, int width, int height));
+static int last_window __ARGS((void));
+static win_T *win_free_mem __ARGS((win_T *win, int *dirp, tabpage_T *tp));
+static win_T *winframe_remove __ARGS((win_T *win, int *dirp, tabpage_T *tp));
+static frame_T *win_altframe __ARGS((win_T *win, tabpage_T *tp));
+static tabpage_T *alt_tabpage __ARGS((void));
+static win_T *frame2win __ARGS((frame_T *frp));
+static int frame_has_win __ARGS((frame_T *frp, win_T *wp));
+static void frame_new_height __ARGS((frame_T *topfrp, int height, int topfirst, int wfh));
+static int frame_fixed_height __ARGS((frame_T *frp));
+#ifdef FEAT_VERTSPLIT
+static int frame_fixed_width __ARGS((frame_T *frp));
+static void frame_add_statusline __ARGS((frame_T *frp));
+static void frame_new_width __ARGS((frame_T *topfrp, int width, int leftfirst, int wfw));
+static void frame_add_vsep __ARGS((frame_T *frp));
+static int frame_minwidth __ARGS((frame_T *topfrp, win_T *next_curwin));
+static void frame_fix_width __ARGS((win_T *wp));
+#endif
+#endif
+static int win_alloc_firstwin __ARGS((win_T *oldwin));
+#if defined(FEAT_WINDOWS) || defined(PROTO)
+static tabpage_T *alloc_tabpage __ARGS((void));
+static int leave_tabpage __ARGS((buf_T *new_curbuf));
+static void enter_tabpage __ARGS((tabpage_T *tp, buf_T *old_curbuf));
+static void frame_fix_height __ARGS((win_T *wp));
+static int frame_minheight __ARGS((frame_T *topfrp, win_T *next_curwin));
+static void win_enter_ext __ARGS((win_T *wp, int undo_sync, int no_curwin));
+static void win_free __ARGS((win_T *wp, tabpage_T *tp));
+static void win_append __ARGS((win_T *, win_T *));
+static void win_remove __ARGS((win_T *, tabpage_T *tp));
+static void frame_append __ARGS((frame_T *after, frame_T *frp));
+static void frame_insert __ARGS((frame_T *before, frame_T *frp));
+static void frame_remove __ARGS((frame_T *frp));
+#ifdef FEAT_VERTSPLIT
+static void win_new_width __ARGS((win_T *wp, int width));
+static void win_goto_ver __ARGS((int up, long count));
+static void win_goto_hor __ARGS((int left, long count));
+#endif
+static void frame_add_height __ARGS((frame_T *frp, int n));
+static void last_status_rec __ARGS((frame_T *fr, int statusline));
+
+static void make_snapshot __ARGS((void));
+static void make_snapshot_rec __ARGS((frame_T *fr, frame_T **frp));
+static void clear_snapshot __ARGS((tabpage_T *tp));
+static void clear_snapshot_rec __ARGS((frame_T *fr));
+static void restore_snapshot __ARGS((int close_curwin));
+static int check_snapshot_rec __ARGS((frame_T *sn, frame_T *fr));
+static win_T *restore_snapshot_rec __ARGS((frame_T *sn, frame_T *fr));
+
+#endif /* FEAT_WINDOWS */
+static win_T *win_alloc __ARGS((win_T *after));
+static void win_new_height __ARGS((win_T *, int));
+
+#define URL_SLASH	1		/* path_is_url() has found "://" */
+#define URL_BACKSLASH	2		/* path_is_url() has found ":\\" */
+
+#define NOWIN		(win_T *)-1	/* non-existing window */
+
+#ifdef FEAT_WINDOWS
+# define ROWS_AVAIL (Rows - p_ch - tabline_height())
+#else
+# define ROWS_AVAIL (Rows - p_ch)
+#endif
+
+#if defined(FEAT_WINDOWS) || defined(PROTO)
+
+static char *m_onlyone = N_("Already only one window");
+
+/*
+ * all CTRL-W window commands are handled here, called from normal_cmd().
+ */
+    void
+do_window(nchar, Prenum, xchar)
+    int		nchar;
+    long	Prenum;
+    int		xchar;	    /* extra char from ":wincmd gx" or NUL */
+{
+    long	Prenum1;
+    win_T	*wp;
+#if defined(FEAT_SEARCHPATH) || defined(FEAT_FIND_ID)
+    char_u	*ptr;
+    linenr_T    lnum = -1;
+#endif
+#ifdef FEAT_FIND_ID
+    int		type = FIND_DEFINE;
+    int		len;
+#endif
+    char_u	cbuf[40];
+
+    if (Prenum == 0)
+	Prenum1 = 1;
+    else
+	Prenum1 = Prenum;
+
+#ifdef FEAT_CMDWIN
+# define CHECK_CMDWIN if (cmdwin_type != 0) { EMSG(_(e_cmdwin)); break; }
+#else
+# define CHECK_CMDWIN
+#endif
+
+    switch (nchar)
+    {
+/* split current window in two parts, horizontally */
+    case 'S':
+    case Ctrl_S:
+    case 's':
+		CHECK_CMDWIN
+#ifdef FEAT_VISUAL
+		reset_VIsual_and_resel();	/* stop Visual mode */
+#endif
+#ifdef FEAT_QUICKFIX
+		/* When splitting the quickfix window open a new buffer in it,
+		 * don't replicate the quickfix buffer. */
+		if (bt_quickfix(curbuf))
+		    goto newwindow;
+#endif
+#ifdef FEAT_GUI
+		need_mouse_correct = TRUE;
+#endif
+		win_split((int)Prenum, 0);
+		break;
+
+#ifdef FEAT_VERTSPLIT
+/* split current window in two parts, vertically */
+    case Ctrl_V:
+    case 'v':
+		CHECK_CMDWIN
+#ifdef FEAT_VISUAL
+		reset_VIsual_and_resel();	/* stop Visual mode */
+#endif
+#ifdef FEAT_GUI
+		need_mouse_correct = TRUE;
+#endif
+		win_split((int)Prenum, WSP_VERT);
+		break;
+#endif
+
+/* split current window and edit alternate file */
+    case Ctrl_HAT:
+    case '^':
+		CHECK_CMDWIN
+#ifdef FEAT_VISUAL
+		reset_VIsual_and_resel();	/* stop Visual mode */
+#endif
+		STRCPY(cbuf, "split #");
+		if (Prenum)
+		    sprintf((char *)cbuf + 7, "%ld", Prenum);
+		do_cmdline_cmd(cbuf);
+		break;
+
+/* open new window */
+    case Ctrl_N:
+    case 'n':
+		CHECK_CMDWIN
+#ifdef FEAT_VISUAL
+		reset_VIsual_and_resel();	/* stop Visual mode */
+#endif
+#ifdef FEAT_QUICKFIX
+newwindow:
+#endif
+		if (Prenum)
+		    sprintf((char *)cbuf, "%ld", Prenum); /* window height */
+		else
+		    cbuf[0] = NUL;
+		STRCAT(cbuf, "new");
+		do_cmdline_cmd(cbuf);
+		break;
+
+/* quit current window */
+    case Ctrl_Q:
+    case 'q':
+#ifdef FEAT_VISUAL
+		reset_VIsual_and_resel();	/* stop Visual mode */
+#endif
+		do_cmdline_cmd((char_u *)"quit");
+		break;
+
+/* close current window */
+    case Ctrl_C:
+    case 'c':
+#ifdef FEAT_VISUAL
+		reset_VIsual_and_resel();	/* stop Visual mode */
+#endif
+		do_cmdline_cmd((char_u *)"close");
+		break;
+
+#if defined(FEAT_WINDOWS) && defined(FEAT_QUICKFIX)
+/* close preview window */
+    case Ctrl_Z:
+    case 'z':
+		CHECK_CMDWIN
+#ifdef FEAT_VISUAL
+		reset_VIsual_and_resel();	/* stop Visual mode */
+#endif
+		do_cmdline_cmd((char_u *)"pclose");
+		break;
+
+/* cursor to preview window */
+    case 'P':
+		for (wp = firstwin; wp != NULL; wp = wp->w_next)
+		    if (wp->w_p_pvw)
+			break;
+		if (wp == NULL)
+		    EMSG(_("E441: There is no preview window"));
+		else
+		    win_goto(wp);
+		break;
+#endif
+
+/* close all but current window */
+    case Ctrl_O:
+    case 'o':
+		CHECK_CMDWIN
+#ifdef FEAT_VISUAL
+		reset_VIsual_and_resel();	/* stop Visual mode */
+#endif
+		do_cmdline_cmd((char_u *)"only");
+		break;
+
+/* cursor to next window with wrap around */
+    case Ctrl_W:
+    case 'w':
+/* cursor to previous window with wrap around */
+    case 'W':
+		CHECK_CMDWIN
+		if (lastwin == firstwin && Prenum != 1)	/* just one window */
+		    beep_flush();
+		else
+		{
+		    if (Prenum)			/* go to specified window */
+		    {
+			for (wp = firstwin; --Prenum > 0; )
+			{
+			    if (wp->w_next == NULL)
+				break;
+			    else
+				wp = wp->w_next;
+			}
+		    }
+		    else
+		    {
+			if (nchar == 'W')	    /* go to previous window */
+			{
+			    wp = curwin->w_prev;
+			    if (wp == NULL)
+				wp = lastwin;	    /* wrap around */
+			}
+			else			    /* go to next window */
+			{
+			    wp = curwin->w_next;
+			    if (wp == NULL)
+				wp = firstwin;	    /* wrap around */
+			}
+		    }
+		    win_goto(wp);
+		}
+		break;
+
+/* cursor to window below */
+    case 'j':
+    case K_DOWN:
+    case Ctrl_J:
+		CHECK_CMDWIN
+#ifdef FEAT_VERTSPLIT
+		win_goto_ver(FALSE, Prenum1);
+#else
+		for (wp = curwin; wp->w_next != NULL && Prenum1-- > 0;
+							    wp = wp->w_next)
+		    ;
+		win_goto(wp);
+#endif
+		break;
+
+/* cursor to window above */
+    case 'k':
+    case K_UP:
+    case Ctrl_K:
+		CHECK_CMDWIN
+#ifdef FEAT_VERTSPLIT
+		win_goto_ver(TRUE, Prenum1);
+#else
+		for (wp = curwin; wp->w_prev != NULL && Prenum1-- > 0;
+							    wp = wp->w_prev)
+		    ;
+		win_goto(wp);
+#endif
+		break;
+
+#ifdef FEAT_VERTSPLIT
+/* cursor to left window */
+    case 'h':
+    case K_LEFT:
+    case Ctrl_H:
+    case K_BS:
+		CHECK_CMDWIN
+		win_goto_hor(TRUE, Prenum1);
+		break;
+
+/* cursor to right window */
+    case 'l':
+    case K_RIGHT:
+    case Ctrl_L:
+		CHECK_CMDWIN
+		win_goto_hor(FALSE, Prenum1);
+		break;
+#endif
+
+/* move window to new tab page */
+    case 'T':
+		if (firstwin == lastwin)
+		    MSG(_(m_onlyone));
+		else
+		{
+		    tabpage_T	*oldtab = curtab;
+		    tabpage_T	*newtab;
+
+		    /* First create a new tab with the window, then go back to
+		     * the old tab and close the window there. */
+		    wp = curwin;
+		    if (win_new_tabpage((int)Prenum) == OK
+						     && valid_tabpage(oldtab))
+		    {
+			newtab = curtab;
+			goto_tabpage_tp(oldtab);
+			if (curwin == wp)
+			    win_close(curwin, FALSE);
+			if (valid_tabpage(newtab))
+			    goto_tabpage_tp(newtab);
+		    }
+		}
+		break;
+
+/* cursor to top-left window */
+    case 't':
+    case Ctrl_T:
+		win_goto(firstwin);
+		break;
+
+/* cursor to bottom-right window */
+    case 'b':
+    case Ctrl_B:
+		win_goto(lastwin);
+		break;
+
+/* cursor to last accessed (previous) window */
+    case 'p':
+    case Ctrl_P:
+		if (prevwin == NULL)
+		    beep_flush();
+		else
+		    win_goto(prevwin);
+		break;
+
+/* exchange current and next window */
+    case 'x':
+    case Ctrl_X:
+		CHECK_CMDWIN
+		win_exchange(Prenum);
+		break;
+
+/* rotate windows downwards */
+    case Ctrl_R:
+    case 'r':
+		CHECK_CMDWIN
+#ifdef FEAT_VISUAL
+		reset_VIsual_and_resel();	/* stop Visual mode */
+#endif
+		win_rotate(FALSE, (int)Prenum1);    /* downwards */
+		break;
+
+/* rotate windows upwards */
+    case 'R':
+		CHECK_CMDWIN
+#ifdef FEAT_VISUAL
+		reset_VIsual_and_resel();	/* stop Visual mode */
+#endif
+		win_rotate(TRUE, (int)Prenum1);	    /* upwards */
+		break;
+
+/* move window to the very top/bottom/left/right */
+    case 'K':
+    case 'J':
+#ifdef FEAT_VERTSPLIT
+    case 'H':
+    case 'L':
+#endif
+		CHECK_CMDWIN
+		win_totop((int)Prenum,
+			((nchar == 'H' || nchar == 'L') ? WSP_VERT : 0)
+			| ((nchar == 'H' || nchar == 'K') ? WSP_TOP : WSP_BOT));
+		break;
+
+/* make all windows the same height */
+    case '=':
+#ifdef FEAT_GUI
+		need_mouse_correct = TRUE;
+#endif
+		win_equal(NULL, FALSE, 'b');
+		break;
+
+/* increase current window height */
+    case '+':
+#ifdef FEAT_GUI
+		need_mouse_correct = TRUE;
+#endif
+		win_setheight(curwin->w_height + (int)Prenum1);
+		break;
+
+/* decrease current window height */
+    case '-':
+#ifdef FEAT_GUI
+		need_mouse_correct = TRUE;
+#endif
+		win_setheight(curwin->w_height - (int)Prenum1);
+		break;
+
+/* set current window height */
+    case Ctrl__:
+    case '_':
+#ifdef FEAT_GUI
+		need_mouse_correct = TRUE;
+#endif
+		win_setheight(Prenum ? (int)Prenum : 9999);
+		break;
+
+#ifdef FEAT_VERTSPLIT
+/* increase current window width */
+    case '>':
+#ifdef FEAT_GUI
+		need_mouse_correct = TRUE;
+#endif
+		win_setwidth(curwin->w_width + (int)Prenum1);
+		break;
+
+/* decrease current window width */
+    case '<':
+#ifdef FEAT_GUI
+		need_mouse_correct = TRUE;
+#endif
+		win_setwidth(curwin->w_width - (int)Prenum1);
+		break;
+
+/* set current window width */
+    case '|':
+#ifdef FEAT_GUI
+		need_mouse_correct = TRUE;
+#endif
+		win_setwidth(Prenum != 0 ? (int)Prenum : 9999);
+		break;
+#endif
+
+/* jump to tag and split window if tag exists (in preview window) */
+#if defined(FEAT_QUICKFIX)
+    case '}':
+		CHECK_CMDWIN
+		if (Prenum)
+		    g_do_tagpreview = Prenum;
+		else
+		    g_do_tagpreview = p_pvh;
+		/*FALLTHROUGH*/
+#endif
+    case ']':
+    case Ctrl_RSB:
+		CHECK_CMDWIN
+#ifdef FEAT_VISUAL
+		reset_VIsual_and_resel();	/* stop Visual mode */
+#endif
+		if (Prenum)
+		    postponed_split = Prenum;
+		else
+		    postponed_split = -1;
+
+		/* Execute the command right here, required when
+		 * "wincmd ]" was used in a function. */
+		do_nv_ident(Ctrl_RSB, NUL);
+		break;
+
+#ifdef FEAT_SEARCHPATH
+/* edit file name under cursor in a new window */
+    case 'f':
+    case 'F':
+    case Ctrl_F:
+wingotofile:
+		CHECK_CMDWIN
+
+		ptr = grab_file_name(Prenum1, &lnum);
+		if (ptr != NULL)
+		{
+# ifdef FEAT_GUI
+		    need_mouse_correct = TRUE;
+# endif
+		    setpcmark();
+		    if (win_split(0, 0) == OK)
+		    {
+# ifdef FEAT_SCROLLBIND
+			curwin->w_p_scb = FALSE;
+# endif
+			(void)do_ecmd(0, ptr, NULL, NULL, ECMD_LASTL, ECMD_HIDE);
+			if (nchar == 'F' && lnum >= 0)
+			{
+			    curwin->w_cursor.lnum = lnum;
+			    check_cursor_lnum();
+			    beginline(BL_SOL | BL_FIX);
+			}
+		    }
+		    vim_free(ptr);
+		}
+		break;
+#endif
+
+#ifdef FEAT_FIND_ID
+/* Go to the first occurrence of the identifier under cursor along path in a
+ * new window -- webb
+ */
+    case 'i':			    /* Go to any match */
+    case Ctrl_I:
+		type = FIND_ANY;
+		/* FALLTHROUGH */
+    case 'd':			    /* Go to definition, using 'define' */
+    case Ctrl_D:
+		CHECK_CMDWIN
+		if ((len = find_ident_under_cursor(&ptr, FIND_IDENT)) == 0)
+		    break;
+		find_pattern_in_path(ptr, 0, len, TRUE,
+			Prenum == 0 ? TRUE : FALSE, type,
+			Prenum1, ACTION_SPLIT, (linenr_T)1, (linenr_T)MAXLNUM);
+		curwin->w_set_curswant = TRUE;
+		break;
+#endif
+
+    case K_KENTER:
+    case CAR:
+#if defined(FEAT_QUICKFIX)
+		/*
+		 * In a quickfix window a <CR> jumps to the error under the
+		 * cursor in a new window.
+		 */
+		if (bt_quickfix(curbuf))
+		{
+		    sprintf((char *)cbuf, "split +%ld%s",
+				(long)curwin->w_cursor.lnum,
+				(curwin->w_llist_ref == NULL) ? "cc" : "ll");
+		    do_cmdline_cmd(cbuf);
+		}
+#endif
+		break;
+
+
+/* CTRL-W g  extended commands */
+    case 'g':
+    case Ctrl_G:
+		CHECK_CMDWIN
+#ifdef USE_ON_FLY_SCROLL
+		dont_scroll = TRUE;		/* disallow scrolling here */
+#endif
+		++no_mapping;
+		++allow_keys;   /* no mapping for xchar, but allow key codes */
+		if (xchar == NUL)
+		    xchar = safe_vgetc();
+#ifdef FEAT_LANGMAP
+		LANGMAP_ADJUST(xchar, TRUE);
+#endif
+		--no_mapping;
+		--allow_keys;
+#ifdef FEAT_CMDL_INFO
+		(void)add_to_showcmd(xchar);
+#endif
+		switch (xchar)
+		{
+#if defined(FEAT_QUICKFIX)
+		    case '}':
+			xchar = Ctrl_RSB;
+			if (Prenum)
+			    g_do_tagpreview = Prenum;
+			else
+			    g_do_tagpreview = p_pvh;
+			/*FALLTHROUGH*/
+#endif
+		    case ']':
+		    case Ctrl_RSB:
+#ifdef FEAT_VISUAL
+			reset_VIsual_and_resel();	/* stop Visual mode */
+#endif
+			if (Prenum)
+			    postponed_split = Prenum;
+			else
+			    postponed_split = -1;
+
+			/* Execute the command right here, required when
+			 * "wincmd g}" was used in a function. */
+			do_nv_ident('g', xchar);
+			break;
+
+#ifdef FEAT_SEARCHPATH
+		    case 'f':	    /* CTRL-W gf: "gf" in a new tab page */
+		    case 'F':	    /* CTRL-W gF: "gF" in a new tab page */
+			cmdmod.tab = TRUE;
+			nchar = xchar;
+			goto wingotofile;
+#endif
+		    default:
+			beep_flush();
+			break;
+		}
+		break;
+
+    default:	beep_flush();
+		break;
+    }
+}
+
+/*
+ * split the current window, implements CTRL-W s and :split
+ *
+ * "size" is the height or width for the new window, 0 to use half of current
+ * height or width.
+ *
+ * "flags":
+ * WSP_ROOM: require enough room for new window
+ * WSP_VERT: vertical split.
+ * WSP_TOP:  open window at the top-left of the shell (help window).
+ * WSP_BOT:  open window at the bottom-right of the shell (quickfix window).
+ * WSP_HELP: creating the help window, keep layout snapshot
+ *
+ * return FAIL for failure, OK otherwise
+ */
+    int
+win_split(size, flags)
+    int		size;
+    int		flags;
+{
+    /* When the ":tab" modifier was used open a new tab page instead. */
+    if (may_open_tabpage() == OK)
+	return OK;
+
+    /* Add flags from ":vertical", ":topleft" and ":botright". */
+    flags |= cmdmod.split;
+    if ((flags & WSP_TOP) && (flags & WSP_BOT))
+    {
+	EMSG(_("E442: Can't split topleft and botright at the same time"));
+	return FAIL;
+    }
+
+    /* When creating the help window make a snapshot of the window layout.
+     * Otherwise clear the snapshot, it's now invalid. */
+    if (flags & WSP_HELP)
+	make_snapshot();
+    else
+	clear_snapshot(curtab);
+
+    return win_split_ins(size, flags, NULL, 0);
+}
+
+/*
+ * When "newwin" is NULL: split the current window in two.
+ * When "newwin" is not NULL: insert this window at the far
+ * top/left/right/bottom.
+ * return FAIL for failure, OK otherwise
+ */
+    static int
+win_split_ins(size, flags, newwin, dir)
+    int		size;
+    int		flags;
+    win_T	*newwin;
+    int		dir;
+{
+    win_T	*wp = newwin;
+    win_T	*oldwin;
+    int		new_size = size;
+    int		i;
+    int		need_status = 0;
+    int		do_equal = FALSE;
+    int		needed;
+    int		available;
+    int		oldwin_height = 0;
+    int		layout;
+    frame_T	*frp, *curfrp;
+    int		before;
+
+    if (flags & WSP_TOP)
+	oldwin = firstwin;
+    else if (flags & WSP_BOT)
+	oldwin = lastwin;
+    else
+	oldwin = curwin;
+
+    /* add a status line when p_ls == 1 and splitting the first window */
+    if (lastwin == firstwin && p_ls == 1 && oldwin->w_status_height == 0)
+    {
+	if (oldwin->w_height <= p_wmh && newwin == NULL)
+	{
+	    EMSG(_(e_noroom));
+	    return FAIL;
+	}
+	need_status = STATUS_HEIGHT;
+    }
+
+#ifdef FEAT_GUI
+    /* May be needed for the scrollbars that are going to change. */
+    if (gui.in_use)
+	out_flush();
+#endif
+
+#ifdef FEAT_VERTSPLIT
+    if (flags & WSP_VERT)
+    {
+	layout = FR_ROW;
+	do_equal = (p_ea && new_size == 0 && *p_ead != 'v');
+
+	/*
+	 * Check if we are able to split the current window and compute its
+	 * width.
+	 */
+	needed = p_wmw + 1;
+	if (flags & WSP_ROOM)
+	    needed += p_wiw - p_wmw;
+	if (p_ea || (flags & (WSP_BOT | WSP_TOP)))
+	{
+	    available = topframe->fr_width;
+	    needed += frame_minwidth(topframe, NULL);
+	}
+	else
+	    available = oldwin->w_width;
+	if (available < needed && newwin == NULL)
+	{
+	    EMSG(_(e_noroom));
+	    return FAIL;
+	}
+	if (new_size == 0)
+	    new_size = oldwin->w_width / 2;
+	if (new_size > oldwin->w_width - p_wmw - 1)
+	    new_size = oldwin->w_width - p_wmw - 1;
+	if (new_size < p_wmw)
+	    new_size = p_wmw;
+
+	/* if it doesn't fit in the current window, need win_equal() */
+	if (oldwin->w_width - new_size - 1 < p_wmw)
+	    do_equal = TRUE;
+
+	/* We don't like to take lines for the new window from a
+	 * 'winfixwidth' window.  Take them from a window to the left or right
+	 * instead, if possible. */
+	if (oldwin->w_p_wfw)
+	    win_setwidth_win(oldwin->w_width + new_size, oldwin);
+    }
+    else
+#endif
+    {
+	layout = FR_COL;
+	do_equal = (p_ea && new_size == 0
+#ifdef FEAT_VERTSPLIT
+		&& *p_ead != 'h'
+#endif
+		);
+
+	/*
+	 * Check if we are able to split the current window and compute its
+	 * height.
+	 */
+	needed = p_wmh + STATUS_HEIGHT + need_status;
+	if (flags & WSP_ROOM)
+	    needed += p_wh - p_wmh;
+	if (p_ea || (flags & (WSP_BOT | WSP_TOP)))
+	{
+	    available = topframe->fr_height;
+	    needed += frame_minheight(topframe, NULL);
+	}
+	else
+	{
+	    available = oldwin->w_height;
+	    needed += p_wmh;
+	}
+	if (available < needed && newwin == NULL)
+	{
+	    EMSG(_(e_noroom));
+	    return FAIL;
+	}
+	oldwin_height = oldwin->w_height;
+	if (need_status)
+	{
+	    oldwin->w_status_height = STATUS_HEIGHT;
+	    oldwin_height -= STATUS_HEIGHT;
+	}
+	if (new_size == 0)
+	    new_size = oldwin_height / 2;
+
+	if (new_size > oldwin_height - p_wmh - STATUS_HEIGHT)
+	    new_size = oldwin_height - p_wmh - STATUS_HEIGHT;
+	if (new_size < p_wmh)
+	    new_size = p_wmh;
+
+	/* if it doesn't fit in the current window, need win_equal() */
+	if (oldwin_height - new_size - STATUS_HEIGHT < p_wmh)
+	    do_equal = TRUE;
+
+	/* We don't like to take lines for the new window from a
+	 * 'winfixheight' window.  Take them from a window above or below
+	 * instead, if possible. */
+	if (oldwin->w_p_wfh)
+	{
+	    win_setheight_win(oldwin->w_height + new_size + STATUS_HEIGHT,
+								      oldwin);
+	    oldwin_height = oldwin->w_height;
+	    if (need_status)
+		oldwin_height -= STATUS_HEIGHT;
+	}
+    }
+
+    /*
+     * allocate new window structure and link it in the window list
+     */
+    if ((flags & WSP_TOP) == 0
+	    && ((flags & WSP_BOT)
+		|| (flags & WSP_BELOW)
+		|| (!(flags & WSP_ABOVE)
+		    && (
+#ifdef FEAT_VERTSPLIT
+			(flags & WSP_VERT) ? p_spr :
+#endif
+			p_sb))))
+    {
+	/* new window below/right of current one */
+	if (newwin == NULL)
+	    wp = win_alloc(oldwin);
+	else
+	    win_append(oldwin, wp);
+    }
+    else
+    {
+	if (newwin == NULL)
+	    wp = win_alloc(oldwin->w_prev);
+	else
+	    win_append(oldwin->w_prev, wp);
+    }
+
+    if (newwin == NULL)
+    {
+	if (wp == NULL)
+	    return FAIL;
+
+	/* make the contents of the new window the same as the current one */
+	win_init(wp, curwin);
+    }
+
+    /*
+     * Reorganise the tree of frames to insert the new window.
+     */
+    if (flags & (WSP_TOP | WSP_BOT))
+    {
+#ifdef FEAT_VERTSPLIT
+	if ((topframe->fr_layout == FR_COL && (flags & WSP_VERT) == 0)
+	    || (topframe->fr_layout == FR_ROW && (flags & WSP_VERT) != 0))
+#else
+	if (topframe->fr_layout == FR_COL)
+#endif
+	{
+	    curfrp = topframe->fr_child;
+	    if (flags & WSP_BOT)
+		while (curfrp->fr_next != NULL)
+		    curfrp = curfrp->fr_next;
+	}
+	else
+	    curfrp = topframe;
+	before = (flags & WSP_TOP);
+    }
+    else
+    {
+	curfrp = oldwin->w_frame;
+	if (flags & WSP_BELOW)
+	    before = FALSE;
+	else if (flags & WSP_ABOVE)
+	    before = TRUE;
+	else
+#ifdef FEAT_VERTSPLIT
+	if (flags & WSP_VERT)
+	    before = !p_spr;
+	else
+#endif
+	    before = !p_sb;
+    }
+    if (curfrp->fr_parent == NULL || curfrp->fr_parent->fr_layout != layout)
+    {
+	/* Need to create a new frame in the tree to make a branch. */
+	frp = (frame_T *)alloc_clear((unsigned)sizeof(frame_T));
+	*frp = *curfrp;
+	curfrp->fr_layout = layout;
+	frp->fr_parent = curfrp;
+	frp->fr_next = NULL;
+	frp->fr_prev = NULL;
+	curfrp->fr_child = frp;
+	curfrp->fr_win = NULL;
+	curfrp = frp;
+	if (frp->fr_win != NULL)
+	    oldwin->w_frame = frp;
+	else
+	    for (frp = frp->fr_child; frp != NULL; frp = frp->fr_next)
+		frp->fr_parent = curfrp;
+    }
+
+    if (newwin == NULL)
+    {
+	/* Create a frame for the new window. */
+	frp = (frame_T *)alloc_clear((unsigned)sizeof(frame_T));
+	frp->fr_layout = FR_LEAF;
+	frp->fr_win = wp;
+	wp->w_frame = frp;
+    }
+    else
+	frp = newwin->w_frame;
+    frp->fr_parent = curfrp->fr_parent;
+
+    /* Insert the new frame at the right place in the frame list. */
+    if (before)
+	frame_insert(curfrp, frp);
+    else
+	frame_append(curfrp, frp);
+
+#ifdef FEAT_VERTSPLIT
+    if (flags & WSP_VERT)
+    {
+	wp->w_p_scr = curwin->w_p_scr;
+	if (need_status)
+	{
+	    --oldwin->w_height;
+	    oldwin->w_status_height = need_status;
+	}
+	if (flags & (WSP_TOP | WSP_BOT))
+	{
+	    /* set height and row of new window to full height */
+	    wp->w_winrow = tabline_height();
+	    wp->w_height = curfrp->fr_height - (p_ls > 0);
+	    wp->w_status_height = (p_ls > 0);
+	}
+	else
+	{
+	    /* height and row of new window is same as current window */
+	    wp->w_winrow = oldwin->w_winrow;
+	    wp->w_height = oldwin->w_height;
+	    wp->w_status_height = oldwin->w_status_height;
+	}
+	frp->fr_height = curfrp->fr_height;
+
+	/* "new_size" of the current window goes to the new window, use
+	 * one column for the vertical separator */
+	wp->w_width = new_size;
+	if (before)
+	    wp->w_vsep_width = 1;
+	else
+	{
+	    wp->w_vsep_width = oldwin->w_vsep_width;
+	    oldwin->w_vsep_width = 1;
+	}
+	if (flags & (WSP_TOP | WSP_BOT))
+	{
+	    if (flags & WSP_BOT)
+		frame_add_vsep(curfrp);
+	    /* Set width of neighbor frame */
+	    frame_new_width(curfrp, curfrp->fr_width
+		     - (new_size + ((flags & WSP_TOP) != 0)), flags & WSP_TOP,
+								       FALSE);
+	}
+	else
+	    win_new_width(oldwin, oldwin->w_width - (new_size + 1));
+	if (before)	/* new window left of current one */
+	{
+	    wp->w_wincol = oldwin->w_wincol;
+	    oldwin->w_wincol += new_size + 1;
+	}
+	else		/* new window right of current one */
+	    wp->w_wincol = oldwin->w_wincol + oldwin->w_width + 1;
+	frame_fix_width(oldwin);
+	frame_fix_width(wp);
+    }
+    else
+#endif
+    {
+	/* width and column of new window is same as current window */
+#ifdef FEAT_VERTSPLIT
+	if (flags & (WSP_TOP | WSP_BOT))
+	{
+	    wp->w_wincol = 0;
+	    wp->w_width = Columns;
+	    wp->w_vsep_width = 0;
+	}
+	else
+	{
+	    wp->w_wincol = oldwin->w_wincol;
+	    wp->w_width = oldwin->w_width;
+	    wp->w_vsep_width = oldwin->w_vsep_width;
+	}
+	frp->fr_width = curfrp->fr_width;
+#endif
+
+	/* "new_size" of the current window goes to the new window, use
+	 * one row for the status line */
+	win_new_height(wp, new_size);
+	if (flags & (WSP_TOP | WSP_BOT))
+	    frame_new_height(curfrp, curfrp->fr_height
+			- (new_size + STATUS_HEIGHT), flags & WSP_TOP, FALSE);
+	else
+	    win_new_height(oldwin, oldwin_height - (new_size + STATUS_HEIGHT));
+	if (before)	/* new window above current one */
+	{
+	    wp->w_winrow = oldwin->w_winrow;
+	    wp->w_status_height = STATUS_HEIGHT;
+	    oldwin->w_winrow += wp->w_height + STATUS_HEIGHT;
+	}
+	else		/* new window below current one */
+	{
+	    wp->w_winrow = oldwin->w_winrow + oldwin->w_height + STATUS_HEIGHT;
+	    wp->w_status_height = oldwin->w_status_height;
+	    oldwin->w_status_height = STATUS_HEIGHT;
+	}
+#ifdef FEAT_VERTSPLIT
+	if (flags & WSP_BOT)
+	    frame_add_statusline(curfrp);
+#endif
+	frame_fix_height(wp);
+	frame_fix_height(oldwin);
+    }
+
+    if (flags & (WSP_TOP | WSP_BOT))
+	(void)win_comp_pos();
+
+    /*
+     * Both windows need redrawing
+     */
+    redraw_win_later(wp, NOT_VALID);
+    wp->w_redr_status = TRUE;
+    redraw_win_later(oldwin, NOT_VALID);
+    oldwin->w_redr_status = TRUE;
+
+    if (need_status)
+    {
+	msg_row = Rows - 1;
+	msg_col = sc_col;
+	msg_clr_eos_force();	/* Old command/ruler may still be there */
+	comp_col();
+	msg_row = Rows - 1;
+	msg_col = 0;	/* put position back at start of line */
+    }
+
+    /*
+     * make the new window the current window and redraw
+     */
+    if (do_equal || dir != 0)
+	win_equal(wp, TRUE,
+#ifdef FEAT_VERTSPLIT
+		(flags & WSP_VERT) ? (dir == 'v' ? 'b' : 'h')
+		: dir == 'h' ? 'b' :
+#endif
+		'v');
+
+    /* Don't change the window height/width to 'winheight' / 'winwidth' if a
+     * size was given. */
+#ifdef FEAT_VERTSPLIT
+    if (flags & WSP_VERT)
+    {
+	i = p_wiw;
+	if (size != 0)
+	    p_wiw = size;
+
+# ifdef FEAT_GUI
+	/* When 'guioptions' includes 'L' or 'R' may have to add scrollbars. */
+	if (gui.in_use)
+	    gui_init_which_components(NULL);
+# endif
+    }
+    else
+#endif
+    {
+	i = p_wh;
+	if (size != 0)
+	    p_wh = size;
+    }
+    win_enter(wp, FALSE);
+#ifdef FEAT_VERTSPLIT
+    if (flags & WSP_VERT)
+	p_wiw = i;
+    else
+#endif
+	p_wh = i;
+
+    return OK;
+}
+
+/*
+ * Initialize window "newp" from window "oldp".
+ * Used when splitting a window and when creating a new tab page.
+ * The windows will both edit the same buffer.
+ */
+    static void
+win_init(newp, oldp)
+    win_T	*newp;
+    win_T	*oldp;
+{
+    int		i;
+
+    newp->w_buffer = oldp->w_buffer;
+    oldp->w_buffer->b_nwindows++;
+    newp->w_cursor = oldp->w_cursor;
+    newp->w_valid = 0;
+    newp->w_curswant = oldp->w_curswant;
+    newp->w_set_curswant = oldp->w_set_curswant;
+    newp->w_topline = oldp->w_topline;
+#ifdef FEAT_DIFF
+    newp->w_topfill = oldp->w_topfill;
+#endif
+    newp->w_leftcol = oldp->w_leftcol;
+    newp->w_pcmark = oldp->w_pcmark;
+    newp->w_prev_pcmark = oldp->w_prev_pcmark;
+    newp->w_alt_fnum = oldp->w_alt_fnum;
+    newp->w_wrow = oldp->w_wrow;
+    newp->w_fraction = oldp->w_fraction;
+    newp->w_prev_fraction_row = oldp->w_prev_fraction_row;
+#ifdef FEAT_JUMPLIST
+    copy_jumplist(oldp, newp);
+#endif
+#ifdef FEAT_QUICKFIX
+    copy_loclist(oldp, newp);
+#endif
+    if (oldp->w_localdir != NULL)
+	newp->w_localdir = vim_strsave(oldp->w_localdir);
+
+    /* Use the same argument list. */
+    newp->w_alist = oldp->w_alist;
+    ++newp->w_alist->al_refcount;
+    newp->w_arg_idx = oldp->w_arg_idx;
+
+    /*
+     * copy tagstack and options from existing window
+     */
+    for (i = 0; i < oldp->w_tagstacklen; i++)
+    {
+	newp->w_tagstack[i] = oldp->w_tagstack[i];
+	if (newp->w_tagstack[i].tagname != NULL)
+	    newp->w_tagstack[i].tagname =
+				   vim_strsave(newp->w_tagstack[i].tagname);
+    }
+    newp->w_tagstackidx = oldp->w_tagstackidx;
+    newp->w_tagstacklen = oldp->w_tagstacklen;
+    win_copy_options(oldp, newp);
+# ifdef FEAT_FOLDING
+    copyFoldingState(oldp, newp);
+# endif
+}
+
+#endif /* FEAT_WINDOWS */
+
+#if defined(FEAT_WINDOWS) || defined(PROTO)
+/*
+ * Check if "win" is a pointer to an existing window.
+ */
+    int
+win_valid(win)
+    win_T	*win;
+{
+    win_T	*wp;
+
+    if (win == NULL)
+	return FALSE;
+    for (wp = firstwin; wp != NULL; wp = wp->w_next)
+	if (wp == win)
+	    return TRUE;
+    return FALSE;
+}
+
+/*
+ * Return the number of windows.
+ */
+    int
+win_count()
+{
+    win_T	*wp;
+    int		count = 0;
+
+    for (wp = firstwin; wp != NULL; wp = wp->w_next)
+	++count;
+    return count;
+}
+
+/*
+ * Make "count" windows on the screen.
+ * Return actual number of windows on the screen.
+ * Must be called when there is just one window, filling the whole screen
+ * (excluding the command line).
+ */
+/*ARGSUSED*/
+    int
+make_windows(count, vertical)
+    int		count;
+    int		vertical;	/* split windows vertically if TRUE */
+{
+    int		maxcount;
+    int		todo;
+
+#ifdef FEAT_VERTSPLIT
+    if (vertical)
+    {
+	/* Each windows needs at least 'winminwidth' lines and a separator
+	 * column. */
+	maxcount = (curwin->w_width + curwin->w_vsep_width
+					     - (p_wiw - p_wmw)) / (p_wmw + 1);
+    }
+    else
+#endif
+    {
+	/* Each window needs at least 'winminheight' lines and a status line. */
+	maxcount = (curwin->w_height + curwin->w_status_height
+				  - (p_wh - p_wmh)) / (p_wmh + STATUS_HEIGHT);
+    }
+
+    if (maxcount < 2)
+	maxcount = 2;
+    if (count > maxcount)
+	count = maxcount;
+
+    /*
+     * add status line now, otherwise first window will be too big
+     */
+    if (count > 1)
+	last_status(TRUE);
+
+#ifdef FEAT_AUTOCMD
+    /*
+     * Don't execute autocommands while creating the windows.  Must do that
+     * when putting the buffers in the windows.
+     */
+    ++autocmd_block;
+#endif
+
+    /* todo is number of windows left to create */
+    for (todo = count - 1; todo > 0; --todo)
+#ifdef FEAT_VERTSPLIT
+	if (vertical)
+	{
+	    if (win_split(curwin->w_width - (curwin->w_width - todo)
+			/ (todo + 1) - 1, WSP_VERT | WSP_ABOVE) == FAIL)
+		break;
+	}
+	else
+#endif
+	{
+	    if (win_split(curwin->w_height - (curwin->w_height - todo
+			    * STATUS_HEIGHT) / (todo + 1)
+			- STATUS_HEIGHT, WSP_ABOVE) == FAIL)
+		break;
+	}
+
+#ifdef FEAT_AUTOCMD
+    --autocmd_block;
+#endif
+
+    /* return actual number of windows */
+    return (count - todo);
+}
+
+/*
+ * Exchange current and next window
+ */
+    static void
+win_exchange(Prenum)
+    long	Prenum;
+{
+    frame_T	*frp;
+    frame_T	*frp2;
+    win_T	*wp;
+    win_T	*wp2;
+    int		temp;
+
+    if (lastwin == firstwin)	    /* just one window */
+    {
+	beep_flush();
+	return;
+    }
+
+#ifdef FEAT_GUI
+    need_mouse_correct = TRUE;
+#endif
+
+    /*
+     * find window to exchange with
+     */
+    if (Prenum)
+    {
+	frp = curwin->w_frame->fr_parent->fr_child;
+	while (frp != NULL && --Prenum > 0)
+	    frp = frp->fr_next;
+    }
+    else if (curwin->w_frame->fr_next != NULL)	/* Swap with next */
+	frp = curwin->w_frame->fr_next;
+    else    /* Swap last window in row/col with previous */
+	frp = curwin->w_frame->fr_prev;
+
+    /* We can only exchange a window with another window, not with a frame
+     * containing windows. */
+    if (frp == NULL || frp->fr_win == NULL || frp->fr_win == curwin)
+	return;
+    wp = frp->fr_win;
+
+/*
+ * 1. remove curwin from the list. Remember after which window it was in wp2
+ * 2. insert curwin before wp in the list
+ * if wp != wp2
+ *    3. remove wp from the list
+ *    4. insert wp after wp2
+ * 5. exchange the status line height and vsep width.
+ */
+    wp2 = curwin->w_prev;
+    frp2 = curwin->w_frame->fr_prev;
+    if (wp->w_prev != curwin)
+    {
+	win_remove(curwin, NULL);
+	frame_remove(curwin->w_frame);
+	win_append(wp->w_prev, curwin);
+	frame_insert(frp, curwin->w_frame);
+    }
+    if (wp != wp2)
+    {
+	win_remove(wp, NULL);
+	frame_remove(wp->w_frame);
+	win_append(wp2, wp);
+	if (frp2 == NULL)
+	    frame_insert(wp->w_frame->fr_parent->fr_child, wp->w_frame);
+	else
+	    frame_append(frp2, wp->w_frame);
+    }
+    temp = curwin->w_status_height;
+    curwin->w_status_height = wp->w_status_height;
+    wp->w_status_height = temp;
+#ifdef FEAT_VERTSPLIT
+    temp = curwin->w_vsep_width;
+    curwin->w_vsep_width = wp->w_vsep_width;
+    wp->w_vsep_width = temp;
+
+    /* If the windows are not in the same frame, exchange the sizes to avoid
+     * messing up the window layout.  Otherwise fix the frame sizes. */
+    if (curwin->w_frame->fr_parent != wp->w_frame->fr_parent)
+    {
+	temp = curwin->w_height;
+	curwin->w_height = wp->w_height;
+	wp->w_height = temp;
+	temp = curwin->w_width;
+	curwin->w_width = wp->w_width;
+	wp->w_width = temp;
+    }
+    else
+    {
+	frame_fix_height(curwin);
+	frame_fix_height(wp);
+	frame_fix_width(curwin);
+	frame_fix_width(wp);
+    }
+#endif
+
+    (void)win_comp_pos();		/* recompute window positions */
+
+    win_enter(wp, TRUE);
+    redraw_later(CLEAR);
+}
+
+/*
+ * rotate windows: if upwards TRUE the second window becomes the first one
+ *		   if upwards FALSE the first window becomes the second one
+ */
+    static void
+win_rotate(upwards, count)
+    int		upwards;
+    int		count;
+{
+    win_T	*wp1;
+    win_T	*wp2;
+    frame_T	*frp;
+    int		n;
+
+    if (firstwin == lastwin)		/* nothing to do */
+    {
+	beep_flush();
+	return;
+    }
+
+#ifdef FEAT_GUI
+    need_mouse_correct = TRUE;
+#endif
+
+#ifdef FEAT_VERTSPLIT
+    /* Check if all frames in this row/col have one window. */
+    for (frp = curwin->w_frame->fr_parent->fr_child; frp != NULL;
+							   frp = frp->fr_next)
+	if (frp->fr_win == NULL)
+	{
+	    EMSG(_("E443: Cannot rotate when another window is split"));
+	    return;
+	}
+#endif
+
+    while (count--)
+    {
+	if (upwards)		/* first window becomes last window */
+	{
+	    /* remove first window/frame from the list */
+	    frp = curwin->w_frame->fr_parent->fr_child;
+	    wp1 = frp->fr_win;
+	    win_remove(wp1, NULL);
+	    frame_remove(frp);
+
+	    /* find last frame and append removed window/frame after it */
+	    for ( ; frp->fr_next != NULL; frp = frp->fr_next)
+		;
+	    win_append(frp->fr_win, wp1);
+	    frame_append(frp, wp1->w_frame);
+
+	    wp2 = frp->fr_win;		/* previously last window */
+	}
+	else			/* last window becomes first window */
+	{
+	    /* find last window/frame in the list and remove it */
+	    for (frp = curwin->w_frame; frp->fr_next != NULL;
+							   frp = frp->fr_next)
+		;
+	    wp1 = frp->fr_win;
+	    wp2 = wp1->w_prev;		    /* will become last window */
+	    win_remove(wp1, NULL);
+	    frame_remove(frp);
+
+	    /* append the removed window/frame before the first in the list */
+	    win_append(frp->fr_parent->fr_child->fr_win->w_prev, wp1);
+	    frame_insert(frp->fr_parent->fr_child, frp);
+	}
+
+	/* exchange status height and vsep width of old and new last window */
+	n = wp2->w_status_height;
+	wp2->w_status_height = wp1->w_status_height;
+	wp1->w_status_height = n;
+	frame_fix_height(wp1);
+	frame_fix_height(wp2);
+#ifdef FEAT_VERTSPLIT
+	n = wp2->w_vsep_width;
+	wp2->w_vsep_width = wp1->w_vsep_width;
+	wp1->w_vsep_width = n;
+	frame_fix_width(wp1);
+	frame_fix_width(wp2);
+#endif
+
+	    /* recompute w_winrow and w_wincol for all windows */
+	(void)win_comp_pos();
+    }
+
+    redraw_later(CLEAR);
+}
+
+/*
+ * Move the current window to the very top/bottom/left/right of the screen.
+ */
+    static void
+win_totop(size, flags)
+    int		size;
+    int		flags;
+{
+    int		dir;
+    int		height = curwin->w_height;
+
+    if (lastwin == firstwin)
+    {
+	beep_flush();
+	return;
+    }
+
+    /* Remove the window and frame from the tree of frames. */
+    (void)winframe_remove(curwin, &dir, NULL);
+    win_remove(curwin, NULL);
+    last_status(FALSE);	    /* may need to remove last status line */
+    (void)win_comp_pos();   /* recompute window positions */
+
+    /* Split a window on the desired side and put the window there. */
+    (void)win_split_ins(size, flags, curwin, dir);
+    if (!(flags & WSP_VERT))
+    {
+	win_setheight(height);
+	if (p_ea)
+	    win_equal(curwin, TRUE, 'v');
+    }
+
+#if defined(FEAT_GUI) && defined(FEAT_VERTSPLIT)
+    /* When 'guioptions' includes 'L' or 'R' may have to remove or add
+     * scrollbars.  Have to update them anyway. */
+    if (gui.in_use)
+    {
+	out_flush();
+	gui_init_which_components(NULL);
+	gui_update_scrollbars(TRUE);
+    }
+    need_mouse_correct = TRUE;
+#endif
+
+}
+
+/*
+ * Move window "win1" to below/right of "win2" and make "win1" the current
+ * window.  Only works within the same frame!
+ */
+    void
+win_move_after(win1, win2)
+    win_T	*win1, *win2;
+{
+    int		height;
+
+    /* check if the arguments are reasonable */
+    if (win1 == win2)
+	return;
+
+    /* check if there is something to do */
+    if (win2->w_next != win1)
+    {
+	/* may need move the status line/vertical separator of the last window
+	 * */
+	if (win1 == lastwin)
+	{
+	    height = win1->w_prev->w_status_height;
+	    win1->w_prev->w_status_height = win1->w_status_height;
+	    win1->w_status_height = height;
+#ifdef FEAT_VERTSPLIT
+	    if (win1->w_prev->w_vsep_width == 1)
+	    {
+		/* Remove the vertical separator from the last-but-one window,
+		 * add it to the last window.  Adjust the frame widths. */
+		win1->w_prev->w_vsep_width = 0;
+		win1->w_prev->w_frame->fr_width -= 1;
+		win1->w_vsep_width = 1;
+		win1->w_frame->fr_width += 1;
+	    }
+#endif
+	}
+	else if (win2 == lastwin)
+	{
+	    height = win1->w_status_height;
+	    win1->w_status_height = win2->w_status_height;
+	    win2->w_status_height = height;
+#ifdef FEAT_VERTSPLIT
+	    if (win1->w_vsep_width == 1)
+	    {
+		/* Remove the vertical separator from win1, add it to the last
+		 * window, win2.  Adjust the frame widths. */
+		win2->w_vsep_width = 1;
+		win2->w_frame->fr_width += 1;
+		win1->w_vsep_width = 0;
+		win1->w_frame->fr_width -= 1;
+	    }
+#endif
+	}
+	win_remove(win1, NULL);
+	frame_remove(win1->w_frame);
+	win_append(win2, win1);
+	frame_append(win2->w_frame, win1->w_frame);
+
+	(void)win_comp_pos();	/* recompute w_winrow for all windows */
+	redraw_later(NOT_VALID);
+    }
+    win_enter(win1, FALSE);
+}
+
+/*
+ * Make all windows the same height.
+ * 'next_curwin' will soon be the current window, make sure it has enough
+ * rows.
+ */
+    void
+win_equal(next_curwin, current, dir)
+    win_T	*next_curwin;	/* pointer to current window to be or NULL */
+    int		current;	/* do only frame with current window */
+    int		dir;		/* 'v' for vertically, 'h' for horizontally,
+				   'b' for both, 0 for using p_ead */
+{
+    if (dir == 0)
+#ifdef FEAT_VERTSPLIT
+	dir = *p_ead;
+#else
+	dir = 'b';
+#endif
+    win_equal_rec(next_curwin == NULL ? curwin : next_curwin, current,
+		      topframe, dir, 0, tabline_height(),
+					   (int)Columns, topframe->fr_height);
+}
+
+/*
+ * Set a frame to a new position and height, spreading the available room
+ * equally over contained frames.
+ * The window "next_curwin" (if not NULL) should at least get the size from
+ * 'winheight' and 'winwidth' if possible.
+ */
+    static void
+win_equal_rec(next_curwin, current, topfr, dir, col, row, width, height)
+    win_T	*next_curwin;	/* pointer to current window to be or NULL */
+    int		current;	/* do only frame with current window */
+    frame_T	*topfr;		/* frame to set size off */
+    int		dir;		/* 'v', 'h' or 'b', see win_equal() */
+    int		col;		/* horizontal position for frame */
+    int		row;		/* vertical position for frame */
+    int		width;		/* new width of frame */
+    int		height;		/* new height of frame */
+{
+    int		n, m;
+    int		extra_sep = 0;
+    int		wincount, totwincount = 0;
+    frame_T	*fr;
+    int		next_curwin_size = 0;
+    int		room = 0;
+    int		new_size;
+    int		has_next_curwin = 0;
+    int		hnc;
+
+    if (topfr->fr_layout == FR_LEAF)
+    {
+	/* Set the width/height of this frame.
+	 * Redraw when size or position changes */
+	if (topfr->fr_height != height || topfr->fr_win->w_winrow != row
+#ifdef FEAT_VERTSPLIT
+		|| topfr->fr_width != width || topfr->fr_win->w_wincol != col
+#endif
+	   )
+	{
+	    topfr->fr_win->w_winrow = row;
+	    frame_new_height(topfr, height, FALSE, FALSE);
+#ifdef FEAT_VERTSPLIT
+	    topfr->fr_win->w_wincol = col;
+	    frame_new_width(topfr, width, FALSE, FALSE);
+#endif
+	    redraw_all_later(CLEAR);
+	}
+    }
+#ifdef FEAT_VERTSPLIT
+    else if (topfr->fr_layout == FR_ROW)
+    {
+	topfr->fr_width = width;
+	topfr->fr_height = height;
+
+	if (dir != 'v')			/* equalize frame widths */
+	{
+	    /* Compute the maximum number of windows horizontally in this
+	     * frame. */
+	    n = frame_minwidth(topfr, NOWIN);
+	    /* add one for the rightmost window, it doesn't have a separator */
+	    if (col + width == Columns)
+		extra_sep = 1;
+	    else
+		extra_sep = 0;
+	    totwincount = (n + extra_sep) / (p_wmw + 1);
+	    has_next_curwin = frame_has_win(topfr, next_curwin);
+
+	    /*
+	     * Compute width for "next_curwin" window and room available for
+	     * other windows.
+	     * "m" is the minimal width when counting p_wiw for "next_curwin".
+	     */
+	    m = frame_minwidth(topfr, next_curwin);
+	    room = width - m;
+	    if (room < 0)
+	    {
+		next_curwin_size = p_wiw + room;
+		room = 0;
+	    }
+	    else
+	    {
+		next_curwin_size = -1;
+		for (fr = topfr->fr_child; fr != NULL; fr = fr->fr_next)
+		{
+		    /* If 'winfixwidth' set keep the window width if
+		     * possible.
+		     * Watch out for this window being the next_curwin. */
+		    if (frame_fixed_width(fr))
+		    {
+			n = frame_minwidth(fr, NOWIN);
+			new_size = fr->fr_width;
+			if (frame_has_win(fr, next_curwin))
+			{
+			    room += p_wiw - p_wmw;
+			    next_curwin_size = 0;
+			    if (new_size < p_wiw)
+				new_size = p_wiw;
+			}
+			else
+			    /* These windows don't use up room. */
+			    totwincount -= (n + (fr->fr_next == NULL
+					      ? extra_sep : 0)) / (p_wmw + 1);
+			room -= new_size - n;
+			if (room < 0)
+			{
+			    new_size += room;
+			    room = 0;
+			}
+			fr->fr_newwidth = new_size;
+		    }
+		}
+		if (next_curwin_size == -1)
+		{
+		    if (!has_next_curwin)
+			next_curwin_size = 0;
+		    else if (totwincount > 1
+			    && (room + (totwincount - 2))
+						  / (totwincount - 1) > p_wiw)
+		    {
+			/* Can make all windows wider than 'winwidth', spread
+			 * the room equally. */
+			next_curwin_size = (room + p_wiw
+					    + (totwincount - 1) * p_wmw
+					    + (totwincount - 1)) / totwincount;
+			room -= next_curwin_size - p_wiw;
+		    }
+		    else
+			next_curwin_size = p_wiw;
+		}
+	    }
+
+	    if (has_next_curwin)
+		--totwincount;		/* don't count curwin */
+	}
+
+	for (fr = topfr->fr_child; fr != NULL; fr = fr->fr_next)
+	{
+	    n = m = 0;
+	    wincount = 1;
+	    if (fr->fr_next == NULL)
+		/* last frame gets all that remains (avoid roundoff error) */
+		new_size = width;
+	    else if (dir == 'v')
+		new_size = fr->fr_width;
+	    else if (frame_fixed_width(fr))
+	    {
+		new_size = fr->fr_newwidth;
+		wincount = 0;	    /* doesn't count as a sizeable window */
+	    }
+	    else
+	    {
+		/* Compute the maximum number of windows horiz. in "fr". */
+		n = frame_minwidth(fr, NOWIN);
+		wincount = (n + (fr->fr_next == NULL ? extra_sep : 0))
+								/ (p_wmw + 1);
+		m = frame_minwidth(fr, next_curwin);
+		if (has_next_curwin)
+		    hnc = frame_has_win(fr, next_curwin);
+		else
+		    hnc = FALSE;
+		if (hnc)	    /* don't count next_curwin */
+		    --wincount;
+		if (totwincount == 0)
+		    new_size = room;
+		else
+		    new_size = (wincount * room + ((unsigned)totwincount >> 1))
+								/ totwincount;
+		if (hnc)	    /* add next_curwin size */
+		{
+		    next_curwin_size -= p_wiw - (m - n);
+		    new_size += next_curwin_size;
+		    room -= new_size - next_curwin_size;
+		}
+		else
+		    room -= new_size;
+		new_size += n;
+	    }
+
+	    /* Skip frame that is full width when splitting or closing a
+	     * window, unless equalizing all frames. */
+	    if (!current || dir != 'v' || topfr->fr_parent != NULL
+		    || (new_size != fr->fr_width)
+		    || frame_has_win(fr, next_curwin))
+		win_equal_rec(next_curwin, current, fr, dir, col, row,
+							    new_size, height);
+	    col += new_size;
+	    width -= new_size;
+	    totwincount -= wincount;
+	}
+    }
+#endif
+    else /* topfr->fr_layout == FR_COL */
+    {
+#ifdef FEAT_VERTSPLIT
+	topfr->fr_width = width;
+#endif
+	topfr->fr_height = height;
+
+	if (dir != 'h')			/* equalize frame heights */
+	{
+	    /* Compute maximum number of windows vertically in this frame. */
+	    n = frame_minheight(topfr, NOWIN);
+	    /* add one for the bottom window if it doesn't have a statusline */
+	    if (row + height == cmdline_row && p_ls == 0)
+		extra_sep = 1;
+	    else
+		extra_sep = 0;
+	    totwincount = (n + extra_sep) / (p_wmh + 1);
+	    has_next_curwin = frame_has_win(topfr, next_curwin);
+
+	    /*
+	     * Compute height for "next_curwin" window and room available for
+	     * other windows.
+	     * "m" is the minimal height when counting p_wh for "next_curwin".
+	     */
+	    m = frame_minheight(topfr, next_curwin);
+	    room = height - m;
+	    if (room < 0)
+	    {
+		/* The room is less then 'winheight', use all space for the
+		 * current window. */
+		next_curwin_size = p_wh + room;
+		room = 0;
+	    }
+	    else
+	    {
+		next_curwin_size = -1;
+		for (fr = topfr->fr_child; fr != NULL; fr = fr->fr_next)
+		{
+		    /* If 'winfixheight' set keep the window height if
+		     * possible.
+		     * Watch out for this window being the next_curwin. */
+		    if (frame_fixed_height(fr))
+		    {
+			n = frame_minheight(fr, NOWIN);
+			new_size = fr->fr_height;
+			if (frame_has_win(fr, next_curwin))
+			{
+			    room += p_wh - p_wmh;
+			    next_curwin_size = 0;
+			    if (new_size < p_wh)
+				new_size = p_wh;
+			}
+			else
+			    /* These windows don't use up room. */
+			    totwincount -= (n + (fr->fr_next == NULL
+					      ? extra_sep : 0)) / (p_wmh + 1);
+			room -= new_size - n;
+			if (room < 0)
+			{
+			    new_size += room;
+			    room = 0;
+			}
+			fr->fr_newheight = new_size;
+		    }
+		}
+		if (next_curwin_size == -1)
+		{
+		    if (!has_next_curwin)
+			next_curwin_size = 0;
+		    else if (totwincount > 1
+			    && (room + (totwincount - 2))
+						   / (totwincount - 1) > p_wh)
+		    {
+			/* can make all windows higher than 'winheight',
+			 * spread the room equally. */
+			next_curwin_size = (room + p_wh
+					   + (totwincount - 1) * p_wmh
+					   + (totwincount - 1)) / totwincount;
+			room -= next_curwin_size - p_wh;
+		    }
+		    else
+			next_curwin_size = p_wh;
+		}
+	    }
+
+	    if (has_next_curwin)
+		--totwincount;		/* don't count curwin */
+	}
+
+	for (fr = topfr->fr_child; fr != NULL; fr = fr->fr_next)
+	{
+	    n = m = 0;
+	    wincount = 1;
+	    if (fr->fr_next == NULL)
+		/* last frame gets all that remains (avoid roundoff error) */
+		new_size = height;
+	    else if (dir == 'h')
+		new_size = fr->fr_height;
+	    else if (frame_fixed_height(fr))
+	    {
+		new_size = fr->fr_newheight;
+		wincount = 0;	    /* doesn't count as a sizeable window */
+	    }
+	    else
+	    {
+		/* Compute the maximum number of windows vert. in "fr". */
+		n = frame_minheight(fr, NOWIN);
+		wincount = (n + (fr->fr_next == NULL ? extra_sep : 0))
+								/ (p_wmh + 1);
+		m = frame_minheight(fr, next_curwin);
+		if (has_next_curwin)
+		    hnc = frame_has_win(fr, next_curwin);
+		else
+		    hnc = FALSE;
+		if (hnc)	    /* don't count next_curwin */
+		    --wincount;
+		if (totwincount == 0)
+		    new_size = room;
+		else
+		    new_size = (wincount * room + ((unsigned)totwincount >> 1))
+								/ totwincount;
+		if (hnc)	    /* add next_curwin size */
+		{
+		    next_curwin_size -= p_wh - (m - n);
+		    new_size += next_curwin_size;
+		    room -= new_size - next_curwin_size;
+		}
+		else
+		    room -= new_size;
+		new_size += n;
+	    }
+	    /* Skip frame that is full width when splitting or closing a
+	     * window, unless equalizing all frames. */
+	    if (!current || dir != 'h' || topfr->fr_parent != NULL
+		    || (new_size != fr->fr_height)
+		    || frame_has_win(fr, next_curwin))
+		win_equal_rec(next_curwin, current, fr, dir, col, row,
+							     width, new_size);
+	    row += new_size;
+	    height -= new_size;
+	    totwincount -= wincount;
+	}
+    }
+}
+
+/*
+ * close all windows for buffer 'buf'
+ */
+    void
+close_windows(buf, keep_curwin)
+    buf_T	*buf;
+    int		keep_curwin;	    /* don't close "curwin" */
+{
+    win_T	*wp;
+    tabpage_T   *tp, *nexttp;
+    int		h = tabline_height();
+
+    ++RedrawingDisabled;
+
+    for (wp = firstwin; wp != NULL && lastwin != firstwin; )
+    {
+	if (wp->w_buffer == buf && (!keep_curwin || wp != curwin))
+	{
+	    win_close(wp, FALSE);
+
+	    /* Start all over, autocommands may change the window layout. */
+	    wp = firstwin;
+	}
+	else
+	    wp = wp->w_next;
+    }
+
+    /* Also check windows in other tab pages. */
+    for (tp = first_tabpage; tp != NULL; tp = nexttp)
+    {
+	nexttp = tp->tp_next;
+	if (tp != curtab)
+	    for (wp = tp->tp_firstwin; wp != NULL; wp = wp->w_next)
+		if (wp->w_buffer == buf)
+		{
+		    win_close_othertab(wp, FALSE, tp);
+
+		    /* Start all over, the tab page may be closed and
+		     * autocommands may change the window layout. */
+		    nexttp = first_tabpage;
+		    break;
+		}
+    }
+
+    --RedrawingDisabled;
+
+    if (h != tabline_height())
+	shell_new_rows();
+}
+
+/*
+ * Return TRUE if the current window is the only window that exists.
+ * Returns FALSE if there is a window, possibly in another tab page.
+ */
+    static int
+last_window()
+{
+    return (lastwin == firstwin && first_tabpage->tp_next == NULL);
+}
+
+/*
+ * Close window "win".  Only works for the current tab page.
+ * If "free_buf" is TRUE related buffer may be unloaded.
+ *
+ * called by :quit, :close, :xit, :wq and findtag()
+ */
+    void
+win_close(win, free_buf)
+    win_T	*win;
+    int		free_buf;
+{
+    win_T	*wp;
+#ifdef FEAT_AUTOCMD
+    int		other_buffer = FALSE;
+#endif
+    int		close_curwin = FALSE;
+    int		dir;
+    int		help_window = FALSE;
+    tabpage_T   *prev_curtab = curtab;
+
+    if (last_window())
+    {
+	EMSG(_("E444: Cannot close last window"));
+	return;
+    }
+
+    /*
+     * When closing the last window in a tab page first go to another tab
+     * page and then close the window and the tab page.  This avoids that
+     * curwin and curtab are not invalid while we are freeing memory, they may
+     * be used in GUI events.
+     */
+    if (firstwin == lastwin)
+    {
+	goto_tabpage_tp(alt_tabpage());
+	redraw_tabline = TRUE;
+
+	/* Safety check: Autocommands may have closed the window when jumping
+	 * to the other tab page. */
+	if (valid_tabpage(prev_curtab) && prev_curtab->tp_firstwin == win)
+	{
+	    int	    h = tabline_height();
+
+	    win_close_othertab(win, free_buf, prev_curtab);
+	    if (h != tabline_height())
+		shell_new_rows();
+	}
+	return;
+    }
+
+    /* When closing the help window, try restoring a snapshot after closing
+     * the window.  Otherwise clear the snapshot, it's now invalid. */
+    if (win->w_buffer->b_help)
+	help_window = TRUE;
+    else
+	clear_snapshot(curtab);
+
+#ifdef FEAT_AUTOCMD
+    if (win == curwin)
+    {
+	/*
+	 * Guess which window is going to be the new current window.
+	 * This may change because of the autocommands (sigh).
+	 */
+	wp = frame2win(win_altframe(win, NULL));
+
+	/*
+	 * Be careful: If autocommands delete the window, return now.
+	 */
+	if (wp->w_buffer != curbuf)
+	{
+	    other_buffer = TRUE;
+	    apply_autocmds(EVENT_BUFLEAVE, NULL, NULL, FALSE, curbuf);
+	    if (!win_valid(win) || last_window())
+		return;
+	}
+	apply_autocmds(EVENT_WINLEAVE, NULL, NULL, FALSE, curbuf);
+	if (!win_valid(win) || last_window())
+	    return;
+# ifdef FEAT_EVAL
+	/* autocmds may abort script processing */
+	if (aborting())
+	    return;
+# endif
+    }
+#endif
+
+#ifdef FEAT_GUI
+    /* Avoid trouble with scrollbars that are going to be deleted in
+     * win_free(). */
+    if (gui.in_use)
+	out_flush();
+#endif
+
+    /*
+     * Close the link to the buffer.
+     */
+    close_buffer(win, win->w_buffer, free_buf ? DOBUF_UNLOAD : 0);
+
+    /* Autocommands may have closed the window already, or closed the only
+     * other window or moved to another tab page. */
+    if (!win_valid(win) || last_window() || curtab != prev_curtab)
+	return;
+
+    /* Free the memory used for the window. */
+    wp = win_free_mem(win, &dir, NULL);
+
+    /* Make sure curwin isn't invalid.  It can cause severe trouble when
+     * printing an error message.  For win_equal() curbuf needs to be valid
+     * too. */
+    if (win == curwin)
+    {
+	curwin = wp;
+#ifdef FEAT_QUICKFIX
+	if (wp->w_p_pvw || bt_quickfix(wp->w_buffer))
+	{
+	    /*
+	     * The cursor goes to the preview or the quickfix window, try
+	     * finding another window to go to.
+	     */
+	    for (;;)
+	    {
+		if (wp->w_next == NULL)
+		    wp = firstwin;
+		else
+		    wp = wp->w_next;
+		if (wp == curwin)
+		    break;
+		if (!wp->w_p_pvw && !bt_quickfix(wp->w_buffer))
+		{
+		    curwin = wp;
+		    break;
+		}
+	    }
+	}
+#endif
+	curbuf = curwin->w_buffer;
+	close_curwin = TRUE;
+    }
+    if (p_ea
+#ifdef FEAT_VERTSPLIT
+	    && (*p_ead == 'b' || *p_ead == dir)
+#endif
+	    )
+	win_equal(curwin, TRUE,
+#ifdef FEAT_VERTSPLIT
+		dir
+#else
+		0
+#endif
+		);
+    else
+	win_comp_pos();
+    if (close_curwin)
+    {
+	win_enter_ext(wp, FALSE, TRUE);
+#ifdef FEAT_AUTOCMD
+	if (other_buffer)
+	    /* careful: after this wp and win may be invalid! */
+	    apply_autocmds(EVENT_BUFENTER, NULL, NULL, FALSE, curbuf);
+#endif
+    }
+
+    /*
+     * If last window has a status line now and we don't want one,
+     * remove the status line.
+     */
+    last_status(FALSE);
+
+    /* After closing the help window, try restoring the window layout from
+     * before it was opened. */
+    if (help_window)
+	restore_snapshot(close_curwin);
+
+#if defined(FEAT_GUI) && defined(FEAT_VERTSPLIT)
+    /* When 'guioptions' includes 'L' or 'R' may have to remove scrollbars. */
+    if (gui.in_use && !win_hasvertsplit())
+	gui_init_which_components(NULL);
+#endif
+
+    redraw_all_later(NOT_VALID);
+}
+
+/*
+ * Close window "win" in tab page "tp", which is not the current tab page.
+ * This may be the last window ih that tab page and result in closing the tab,
+ * thus "tp" may become invalid!
+ * Caller must check if buffer is hidden and whether the tabline needs to be
+ * updated.
+ */
+    void
+win_close_othertab(win, free_buf, tp)
+    win_T	*win;
+    int		free_buf;
+    tabpage_T	*tp;
+{
+    win_T	*wp;
+    int		dir;
+    tabpage_T   *ptp = NULL;
+
+    /* Close the link to the buffer. */
+    close_buffer(win, win->w_buffer, free_buf ? DOBUF_UNLOAD : 0);
+
+    /* Careful: Autocommands may have closed the tab page or made it the
+     * current tab page.  */
+    for (ptp = first_tabpage; ptp != NULL && ptp != tp; ptp = ptp->tp_next)
+	;
+    if (ptp == NULL || tp == curtab)
+	return;
+
+    /* Autocommands may have closed the window already. */
+    for (wp = tp->tp_firstwin; wp != NULL && wp != win; wp = wp->w_next)
+	;
+    if (wp == NULL)
+	return;
+
+    /* Free the memory used for the window. */
+    wp = win_free_mem(win, &dir, tp);
+
+    /* When closing the last window in a tab page remove the tab page. */
+    if (wp == NULL)
+    {
+	if (tp == first_tabpage)
+	    first_tabpage = tp->tp_next;
+	else
+	{
+	    for (ptp = first_tabpage; ptp != NULL && ptp->tp_next != tp;
+							   ptp = ptp->tp_next)
+		;
+	    if (ptp == NULL)
+	    {
+		EMSG2(_(e_intern2), "win_close_othertab()");
+		return;
+	    }
+	    ptp->tp_next = tp->tp_next;
+	}
+	free_tabpage(tp);
+    }
+}
+
+/*
+ * Free the memory used for a window.
+ * Returns a pointer to the window that got the freed up space.
+ */
+    static win_T *
+win_free_mem(win, dirp, tp)
+    win_T	*win;
+    int		*dirp;		/* set to 'v' or 'h' for direction if 'ea' */
+    tabpage_T	*tp;		/* tab page "win" is in, NULL for current */
+{
+    frame_T	*frp;
+    win_T	*wp;
+
+#ifdef FEAT_FOLDING
+    clearFolding(win);
+#endif
+
+    /* reduce the reference count to the argument list. */
+    alist_unlink(win->w_alist);
+
+    /* Remove the window and its frame from the tree of frames. */
+    frp = win->w_frame;
+    wp = winframe_remove(win, dirp, tp);
+    vim_free(frp);
+    win_free(win, tp);
+
+    /* When deleting the current window of another tab page select a new
+     * current window. */
+    if (tp != NULL && win == tp->tp_curwin)
+	tp->tp_curwin = wp;
+
+    return wp;
+}
+
+#if defined(EXITFREE) || defined(PROTO)
+    void
+win_free_all()
+{
+    int		dummy;
+
+# ifdef FEAT_WINDOWS
+    while (first_tabpage->tp_next != NULL)
+	tabpage_close(TRUE);
+# endif
+
+    while (firstwin != NULL)
+	(void)win_free_mem(firstwin, &dummy, NULL);
+}
+#endif
+
+/*
+ * Remove a window and its frame from the tree of frames.
+ * Returns a pointer to the window that got the freed up space.
+ */
+/*ARGSUSED*/
+    static win_T *
+winframe_remove(win, dirp, tp)
+    win_T	*win;
+    int		*dirp;		/* set to 'v' or 'h' for direction if 'ea' */
+    tabpage_T	*tp;		/* tab page "win" is in, NULL for current */
+{
+    frame_T	*frp, *frp2, *frp3;
+    frame_T	*frp_close = win->w_frame;
+    win_T	*wp;
+    int		old_size = 0;
+
+    /*
+     * If there is only one window there is nothing to remove.
+     */
+    if (tp == NULL ? firstwin == lastwin : tp->tp_firstwin == tp->tp_lastwin)
+	return NULL;
+
+    /*
+     * Remove the window from its frame.
+     */
+    frp2 = win_altframe(win, tp);
+    wp = frame2win(frp2);
+
+    /* Remove this frame from the list of frames. */
+    frame_remove(frp_close);
+
+#ifdef FEAT_VERTSPLIT
+    if (frp_close->fr_parent->fr_layout == FR_COL)
+    {
+#endif
+	/* When 'winfixheight' is set, remember its old size and restore
+	 * it later (it's a simplistic solution...).  Don't do this if the
+	 * window will occupy the full height of the screen. */
+	if (frp2->fr_win != NULL
+		&& (frp2->fr_next != NULL || frp2->fr_prev != NULL)
+		&& frp2->fr_win->w_p_wfh)
+	    old_size = frp2->fr_win->w_height;
+	frame_new_height(frp2, frp2->fr_height + frp_close->fr_height,
+			    frp2 == frp_close->fr_next ? TRUE : FALSE, FALSE);
+	if (old_size != 0)
+	    win_setheight_win(old_size, frp2->fr_win);
+#ifdef FEAT_VERTSPLIT
+	*dirp = 'v';
+    }
+    else
+    {
+	/* When 'winfixwidth' is set, remember its old size and restore
+	 * it later (it's a simplistic solution...).  Don't do this if the
+	 * window will occupy the full width of the screen. */
+	if (frp2->fr_win != NULL
+		&& (frp2->fr_next != NULL || frp2->fr_prev != NULL)
+		&& frp2->fr_win->w_p_wfw)
+	    old_size = frp2->fr_win->w_width;
+	frame_new_width(frp2, frp2->fr_width + frp_close->fr_width,
+			    frp2 == frp_close->fr_next ? TRUE : FALSE, FALSE);
+	if (old_size != 0)
+	    win_setwidth_win(old_size, frp2->fr_win);
+	*dirp = 'h';
+    }
+#endif
+
+    /* If rows/columns go to a window below/right its positions need to be
+     * updated.  Can only be done after the sizes have been updated. */
+    if (frp2 == frp_close->fr_next)
+    {
+	int row = win->w_winrow;
+	int col = W_WINCOL(win);
+
+	frame_comp_pos(frp2, &row, &col);
+    }
+
+    if (frp2->fr_next == NULL && frp2->fr_prev == NULL)
+    {
+	/* There is no other frame in this list, move its info to the parent
+	 * and remove it. */
+	frp2->fr_parent->fr_layout = frp2->fr_layout;
+	frp2->fr_parent->fr_child = frp2->fr_child;
+	for (frp = frp2->fr_child; frp != NULL; frp = frp->fr_next)
+	    frp->fr_parent = frp2->fr_parent;
+	frp2->fr_parent->fr_win = frp2->fr_win;
+	if (frp2->fr_win != NULL)
+	    frp2->fr_win->w_frame = frp2->fr_parent;
+	frp = frp2->fr_parent;
+	vim_free(frp2);
+
+	frp2 = frp->fr_parent;
+	if (frp2 != NULL && frp2->fr_layout == frp->fr_layout)
+	{
+	    /* The frame above the parent has the same layout, have to merge
+	     * the frames into this list. */
+	    if (frp2->fr_child == frp)
+		frp2->fr_child = frp->fr_child;
+	    frp->fr_child->fr_prev = frp->fr_prev;
+	    if (frp->fr_prev != NULL)
+		frp->fr_prev->fr_next = frp->fr_child;
+	    for (frp3 = frp->fr_child; ; frp3 = frp3->fr_next)
+	    {
+		frp3->fr_parent = frp2;
+		if (frp3->fr_next == NULL)
+		{
+		    frp3->fr_next = frp->fr_next;
+		    if (frp->fr_next != NULL)
+			frp->fr_next->fr_prev = frp3;
+		    break;
+		}
+	    }
+	    vim_free(frp);
+	}
+    }
+
+    return wp;
+}
+
+/*
+ * Find out which frame is going to get the freed up space when "win" is
+ * closed.
+ * if 'splitbelow'/'splitleft' the space goes to the window above/left.
+ * if 'nosplitbelow'/'nosplitleft' the space goes to the window below/right.
+ * This makes opening a window and closing it immediately keep the same window
+ * layout.
+ */
+    static frame_T *
+win_altframe(win, tp)
+    win_T	*win;
+    tabpage_T	*tp;		/* tab page "win" is in, NULL for current */
+{
+    frame_T	*frp;
+    int		b;
+
+    if (tp == NULL ? firstwin == lastwin : tp->tp_firstwin == tp->tp_lastwin)
+	/* Last window in this tab page, will go to next tab page. */
+	return alt_tabpage()->tp_curwin->w_frame;
+
+    frp = win->w_frame;
+#ifdef FEAT_VERTSPLIT
+    if (frp->fr_parent != NULL && frp->fr_parent->fr_layout == FR_ROW)
+	b = p_spr;
+    else
+#endif
+	b = p_sb;
+    if ((!b && frp->fr_next != NULL) || frp->fr_prev == NULL)
+	return frp->fr_next;
+    return frp->fr_prev;
+}
+
+/*
+ * Return the tabpage that will be used if the current one is closed.
+ */
+    static tabpage_T *
+alt_tabpage()
+{
+    tabpage_T	*tp;
+
+    /* Use the next tab page if possible. */
+    if (curtab->tp_next != NULL)
+	return curtab->tp_next;
+
+    /* Find the last but one tab page. */
+    for (tp = first_tabpage; tp->tp_next != curtab; tp = tp->tp_next)
+	;
+    return tp;
+}
+
+/*
+ * Find the left-upper window in frame "frp".
+ */
+    static win_T *
+frame2win(frp)
+    frame_T	*frp;
+{
+    while (frp->fr_win == NULL)
+	frp = frp->fr_child;
+    return frp->fr_win;
+}
+
+/*
+ * Return TRUE if frame "frp" contains window "wp".
+ */
+    static int
+frame_has_win(frp, wp)
+    frame_T	*frp;
+    win_T	*wp;
+{
+    frame_T	*p;
+
+    if (frp->fr_layout == FR_LEAF)
+	return frp->fr_win == wp;
+
+    for (p = frp->fr_child; p != NULL; p = p->fr_next)
+	if (frame_has_win(p, wp))
+	    return TRUE;
+    return FALSE;
+}
+
+/*
+ * Set a new height for a frame.  Recursively sets the height for contained
+ * frames and windows.  Caller must take care of positions.
+ */
+    static void
+frame_new_height(topfrp, height, topfirst, wfh)
+    frame_T	*topfrp;
+    int		height;
+    int		topfirst;	/* resize topmost contained frame first */
+    int		wfh;		/* obey 'winfixheight' when there is a choice;
+				   may cause the height not to be set */
+{
+    frame_T	*frp;
+    int		extra_lines;
+    int		h;
+
+    if (topfrp->fr_win != NULL)
+    {
+	/* Simple case: just one window. */
+	win_new_height(topfrp->fr_win,
+				    height - topfrp->fr_win->w_status_height);
+    }
+#ifdef FEAT_VERTSPLIT
+    else if (topfrp->fr_layout == FR_ROW)
+    {
+	do
+	{
+	    /* All frames in this row get the same new height. */
+	    for (frp = topfrp->fr_child; frp != NULL; frp = frp->fr_next)
+	    {
+		frame_new_height(frp, height, topfirst, wfh);
+		if (frp->fr_height > height)
+		{
+		    /* Could not fit the windows, make the whole row higher. */
+		    height = frp->fr_height;
+		    break;
+		}
+	    }
+	}
+	while (frp != NULL);
+    }
+#endif
+    else    /* fr_layout == FR_COL */
+    {
+	/* Complicated case: Resize a column of frames.  Resize the bottom
+	 * frame first, frames above that when needed. */
+
+	frp = topfrp->fr_child;
+	if (wfh)
+	    /* Advance past frames with one window with 'wfh' set. */
+	    while (frame_fixed_height(frp))
+	    {
+		frp = frp->fr_next;
+		if (frp == NULL)
+		    return;	    /* no frame without 'wfh', give up */
+	    }
+	if (!topfirst)
+	{
+	    /* Find the bottom frame of this column */
+	    while (frp->fr_next != NULL)
+		frp = frp->fr_next;
+	    if (wfh)
+		/* Advance back for frames with one window with 'wfh' set. */
+		while (frame_fixed_height(frp))
+		    frp = frp->fr_prev;
+	}
+
+	extra_lines = height - topfrp->fr_height;
+	if (extra_lines < 0)
+	{
+	    /* reduce height of contained frames, bottom or top frame first */
+	    while (frp != NULL)
+	    {
+		h = frame_minheight(frp, NULL);
+		if (frp->fr_height + extra_lines < h)
+		{
+		    extra_lines += frp->fr_height - h;
+		    frame_new_height(frp, h, topfirst, wfh);
+		}
+		else
+		{
+		    frame_new_height(frp, frp->fr_height + extra_lines,
+							       topfirst, wfh);
+		    break;
+		}
+		if (topfirst)
+		{
+		    do
+			frp = frp->fr_next;
+		    while (wfh && frp != NULL && frame_fixed_height(frp));
+		}
+		else
+		{
+		    do
+			frp = frp->fr_prev;
+		    while (wfh && frp != NULL && frame_fixed_height(frp));
+		}
+		/* Increase "height" if we could not reduce enough frames. */
+		if (frp == NULL)
+		    height -= extra_lines;
+	    }
+	}
+	else if (extra_lines > 0)
+	{
+	    /* increase height of bottom or top frame */
+	    frame_new_height(frp, frp->fr_height + extra_lines, topfirst, wfh);
+	}
+    }
+    topfrp->fr_height = height;
+}
+
+/*
+ * Return TRUE if height of frame "frp" should not be changed because of
+ * the 'winfixheight' option.
+ */
+    static int
+frame_fixed_height(frp)
+    frame_T	*frp;
+{
+    /* frame with one window: fixed height if 'winfixheight' set. */
+    if (frp->fr_win != NULL)
+	return frp->fr_win->w_p_wfh;
+
+    if (frp->fr_layout == FR_ROW)
+    {
+	/* The frame is fixed height if one of the frames in the row is fixed
+	 * height. */
+	for (frp = frp->fr_child; frp != NULL; frp = frp->fr_next)
+	    if (frame_fixed_height(frp))
+		return TRUE;
+	return FALSE;
+    }
+
+    /* frp->fr_layout == FR_COL: The frame is fixed height if all of the
+     * frames in the row are fixed height. */
+    for (frp = frp->fr_child; frp != NULL; frp = frp->fr_next)
+	if (!frame_fixed_height(frp))
+	    return FALSE;
+    return TRUE;
+}
+
+#ifdef FEAT_VERTSPLIT
+/*
+ * Return TRUE if width of frame "frp" should not be changed because of
+ * the 'winfixwidth' option.
+ */
+    static int
+frame_fixed_width(frp)
+    frame_T	*frp;
+{
+    /* frame with one window: fixed width if 'winfixwidth' set. */
+    if (frp->fr_win != NULL)
+	return frp->fr_win->w_p_wfw;
+
+    if (frp->fr_layout == FR_COL)
+    {
+	/* The frame is fixed width if one of the frames in the row is fixed
+	 * width. */
+	for (frp = frp->fr_child; frp != NULL; frp = frp->fr_next)
+	    if (frame_fixed_width(frp))
+		return TRUE;
+	return FALSE;
+    }
+
+    /* frp->fr_layout == FR_ROW: The frame is fixed width if all of the
+     * frames in the row are fixed width. */
+    for (frp = frp->fr_child; frp != NULL; frp = frp->fr_next)
+	if (!frame_fixed_width(frp))
+	    return FALSE;
+    return TRUE;
+}
+
+/*
+ * Add a status line to windows at the bottom of "frp".
+ * Note: Does not check if there is room!
+ */
+    static void
+frame_add_statusline(frp)
+    frame_T	*frp;
+{
+    win_T	*wp;
+
+    if (frp->fr_layout == FR_LEAF)
+    {
+	wp = frp->fr_win;
+	if (wp->w_status_height == 0)
+	{
+	    if (wp->w_height > 0)	/* don't make it negative */
+		--wp->w_height;
+	    wp->w_status_height = STATUS_HEIGHT;
+	}
+    }
+    else if (frp->fr_layout == FR_ROW)
+    {
+	/* Handle all the frames in the row. */
+	for (frp = frp->fr_child; frp != NULL; frp = frp->fr_next)
+	    frame_add_statusline(frp);
+    }
+    else /* frp->fr_layout == FR_COL */
+    {
+	/* Only need to handle the last frame in the column. */
+	for (frp = frp->fr_child; frp->fr_next != NULL; frp = frp->fr_next)
+	    ;
+	frame_add_statusline(frp);
+    }
+}
+
+/*
+ * Set width of a frame.  Handles recursively going through contained frames.
+ * May remove separator line for windows at the right side (for win_close()).
+ */
+    static void
+frame_new_width(topfrp, width, leftfirst, wfw)
+    frame_T	*topfrp;
+    int		width;
+    int		leftfirst;	/* resize leftmost contained frame first */
+    int		wfw;		/* obey 'winfixwidth' when there is a choice;
+				   may cause the width not to be set */
+{
+    frame_T	*frp;
+    int		extra_cols;
+    int		w;
+    win_T	*wp;
+
+    if (topfrp->fr_layout == FR_LEAF)
+    {
+	/* Simple case: just one window. */
+	wp = topfrp->fr_win;
+	/* Find out if there are any windows right of this one. */
+	for (frp = topfrp; frp->fr_parent != NULL; frp = frp->fr_parent)
+	    if (frp->fr_parent->fr_layout == FR_ROW && frp->fr_next != NULL)
+		break;
+	if (frp->fr_parent == NULL)
+	    wp->w_vsep_width = 0;
+	win_new_width(wp, width - wp->w_vsep_width);
+    }
+    else if (topfrp->fr_layout == FR_COL)
+    {
+	do
+	{
+	    /* All frames in this column get the same new width. */
+	    for (frp = topfrp->fr_child; frp != NULL; frp = frp->fr_next)
+	    {
+		frame_new_width(frp, width, leftfirst, wfw);
+		if (frp->fr_width > width)
+		{
+		    /* Could not fit the windows, make whole column wider. */
+		    width = frp->fr_width;
+		    break;
+		}
+	    }
+	} while (frp != NULL);
+    }
+    else    /* fr_layout == FR_ROW */
+    {
+	/* Complicated case: Resize a row of frames.  Resize the rightmost
+	 * frame first, frames left of it when needed. */
+
+	frp = topfrp->fr_child;
+	if (wfw)
+	    /* Advance past frames with one window with 'wfw' set. */
+	    while (frame_fixed_width(frp))
+	    {
+		frp = frp->fr_next;
+		if (frp == NULL)
+		    return;	    /* no frame without 'wfw', give up */
+	    }
+	if (!leftfirst)
+	{
+	    /* Find the rightmost frame of this row */
+	    while (frp->fr_next != NULL)
+		frp = frp->fr_next;
+	    if (wfw)
+		/* Advance back for frames with one window with 'wfw' set. */
+		while (frame_fixed_width(frp))
+		    frp = frp->fr_prev;
+	}
+
+	extra_cols = width - topfrp->fr_width;
+	if (extra_cols < 0)
+	{
+	    /* reduce frame width, rightmost frame first */
+	    while (frp != NULL)
+	    {
+		w = frame_minwidth(frp, NULL);
+		if (frp->fr_width + extra_cols < w)
+		{
+		    extra_cols += frp->fr_width - w;
+		    frame_new_width(frp, w, leftfirst, wfw);
+		}
+		else
+		{
+		    frame_new_width(frp, frp->fr_width + extra_cols,
+							      leftfirst, wfw);
+		    break;
+		}
+		if (leftfirst)
+		{
+		    do
+			frp = frp->fr_next;
+		    while (wfw && frp != NULL && frame_fixed_width(frp));
+		}
+		else
+		{
+		    do
+			frp = frp->fr_prev;
+		    while (wfw && frp != NULL && frame_fixed_width(frp));
+		}
+		/* Increase "width" if we could not reduce enough frames. */
+		if (frp == NULL)
+		    width -= extra_cols;
+	    }
+	}
+	else if (extra_cols > 0)
+	{
+	    /* increase width of rightmost frame */
+	    frame_new_width(frp, frp->fr_width + extra_cols, leftfirst, wfw);
+	}
+    }
+    topfrp->fr_width = width;
+}
+
+/*
+ * Add the vertical separator to windows at the right side of "frp".
+ * Note: Does not check if there is room!
+ */
+    static void
+frame_add_vsep(frp)
+    frame_T	*frp;
+{
+    win_T	*wp;
+
+    if (frp->fr_layout == FR_LEAF)
+    {
+	wp = frp->fr_win;
+	if (wp->w_vsep_width == 0)
+	{
+	    if (wp->w_width > 0)	/* don't make it negative */
+		--wp->w_width;
+	    wp->w_vsep_width = 1;
+	}
+    }
+    else if (frp->fr_layout == FR_COL)
+    {
+	/* Handle all the frames in the column. */
+	for (frp = frp->fr_child; frp != NULL; frp = frp->fr_next)
+	    frame_add_vsep(frp);
+    }
+    else /* frp->fr_layout == FR_ROW */
+    {
+	/* Only need to handle the last frame in the row. */
+	frp = frp->fr_child;
+	while (frp->fr_next != NULL)
+	    frp = frp->fr_next;
+	frame_add_vsep(frp);
+    }
+}
+
+/*
+ * Set frame width from the window it contains.
+ */
+    static void
+frame_fix_width(wp)
+    win_T	*wp;
+{
+    wp->w_frame->fr_width = wp->w_width + wp->w_vsep_width;
+}
+#endif
+
+/*
+ * Set frame height from the window it contains.
+ */
+    static void
+frame_fix_height(wp)
+    win_T	*wp;
+{
+    wp->w_frame->fr_height = wp->w_height + wp->w_status_height;
+}
+
+/*
+ * Compute the minimal height for frame "topfrp".
+ * Uses the 'winminheight' option.
+ * When "next_curwin" isn't NULL, use p_wh for this window.
+ * When "next_curwin" is NOWIN, don't use at least one line for the current
+ * window.
+ */
+    static int
+frame_minheight(topfrp, next_curwin)
+    frame_T	*topfrp;
+    win_T	*next_curwin;
+{
+    frame_T	*frp;
+    int		m;
+#ifdef FEAT_VERTSPLIT
+    int		n;
+#endif
+
+    if (topfrp->fr_win != NULL)
+    {
+	if (topfrp->fr_win == next_curwin)
+	    m = p_wh + topfrp->fr_win->w_status_height;
+	else
+	{
+	    /* window: minimal height of the window plus status line */
+	    m = p_wmh + topfrp->fr_win->w_status_height;
+	    /* Current window is minimal one line high */
+	    if (p_wmh == 0 && topfrp->fr_win == curwin && next_curwin == NULL)
+		++m;
+	}
+    }
+#ifdef FEAT_VERTSPLIT
+    else if (topfrp->fr_layout == FR_ROW)
+    {
+	/* get the minimal height from each frame in this row */
+	m = 0;
+	for (frp = topfrp->fr_child; frp != NULL; frp = frp->fr_next)
+	{
+	    n = frame_minheight(frp, next_curwin);
+	    if (n > m)
+		m = n;
+	}
+    }
+#endif
+    else
+    {
+	/* Add up the minimal heights for all frames in this column. */
+	m = 0;
+	for (frp = topfrp->fr_child; frp != NULL; frp = frp->fr_next)
+	    m += frame_minheight(frp, next_curwin);
+    }
+
+    return m;
+}
+
+#ifdef FEAT_VERTSPLIT
+/*
+ * Compute the minimal width for frame "topfrp".
+ * When "next_curwin" isn't NULL, use p_wiw for this window.
+ * When "next_curwin" is NOWIN, don't use at least one column for the current
+ * window.
+ */
+    static int
+frame_minwidth(topfrp, next_curwin)
+    frame_T	*topfrp;
+    win_T	*next_curwin;	/* use p_wh and p_wiw for next_curwin */
+{
+    frame_T	*frp;
+    int		m, n;
+
+    if (topfrp->fr_win != NULL)
+    {
+	if (topfrp->fr_win == next_curwin)
+	    m = p_wiw + topfrp->fr_win->w_vsep_width;
+	else
+	{
+	    /* window: minimal width of the window plus separator column */
+	    m = p_wmw + topfrp->fr_win->w_vsep_width;
+	    /* Current window is minimal one column wide */
+	    if (p_wmw == 0 && topfrp->fr_win == curwin && next_curwin == NULL)
+		++m;
+	}
+    }
+    else if (topfrp->fr_layout == FR_COL)
+    {
+	/* get the minimal width from each frame in this column */
+	m = 0;
+	for (frp = topfrp->fr_child; frp != NULL; frp = frp->fr_next)
+	{
+	    n = frame_minwidth(frp, next_curwin);
+	    if (n > m)
+		m = n;
+	}
+    }
+    else
+    {
+	/* Add up the minimal widths for all frames in this row. */
+	m = 0;
+	for (frp = topfrp->fr_child; frp != NULL; frp = frp->fr_next)
+	    m += frame_minwidth(frp, next_curwin);
+    }
+
+    return m;
+}
+#endif
+
+
+/*
+ * Try to close all windows except current one.
+ * Buffers in the other windows become hidden if 'hidden' is set, or '!' is
+ * used and the buffer was modified.
+ *
+ * Used by ":bdel" and ":only".
+ */
+    void
+close_others(message, forceit)
+    int		message;
+    int		forceit;	    /* always hide all other windows */
+{
+    win_T	*wp;
+    win_T	*nextwp;
+    int		r;
+
+    if (lastwin == firstwin)
+    {
+	if (message
+#ifdef FEAT_AUTOCMD
+		    && !autocmd_busy
+#endif
+				    )
+	    MSG(_(m_onlyone));
+	return;
+    }
+
+    /* Be very careful here: autocommands may change the window layout. */
+    for (wp = firstwin; win_valid(wp); wp = nextwp)
+    {
+	nextwp = wp->w_next;
+	if (wp != curwin)		/* don't close current window */
+	{
+
+	    /* Check if it's allowed to abandon this window */
+	    r = can_abandon(wp->w_buffer, forceit);
+#ifdef FEAT_AUTOCMD
+	    if (!win_valid(wp))		/* autocommands messed wp up */
+	    {
+		nextwp = firstwin;
+		continue;
+	    }
+#endif
+	    if (!r)
+	    {
+#if defined(FEAT_GUI_DIALOG) || defined(FEAT_CON_DIALOG)
+		if (message && (p_confirm || cmdmod.confirm) && p_write)
+		{
+		    dialog_changed(wp->w_buffer, FALSE);
+# ifdef FEAT_AUTOCMD
+		    if (!win_valid(wp))		/* autocommands messed wp up */
+		    {
+			nextwp = firstwin;
+			continue;
+		    }
+# endif
+		}
+		if (bufIsChanged(wp->w_buffer))
+#endif
+		    continue;
+	    }
+	    win_close(wp, !P_HID(wp->w_buffer) && !bufIsChanged(wp->w_buffer));
+	}
+    }
+
+    if (message && lastwin != firstwin)
+	EMSG(_("E445: Other window contains changes"));
+}
+
+#endif /* FEAT_WINDOWS */
+
+/*
+ * Init the current window "curwin".
+ * Called when a new file is being edited.
+ */
+    void
+curwin_init()
+{
+    redraw_win_later(curwin, NOT_VALID);
+    curwin->w_lines_valid = 0;
+    curwin->w_cursor.lnum = 1;
+    curwin->w_curswant = curwin->w_cursor.col = 0;
+#ifdef FEAT_VIRTUALEDIT
+    curwin->w_cursor.coladd = 0;
+#endif
+    curwin->w_pcmark.lnum = 1;	/* pcmark not cleared but set to line 1 */
+    curwin->w_pcmark.col = 0;
+    curwin->w_prev_pcmark.lnum = 0;
+    curwin->w_prev_pcmark.col = 0;
+    curwin->w_topline = 1;
+#ifdef FEAT_DIFF
+    curwin->w_topfill = 0;
+#endif
+    curwin->w_botline = 2;
+#ifdef FEAT_FKMAP
+    if (curwin->w_p_rl)
+	curwin->w_farsi = W_CONV + W_R_L;
+    else
+	curwin->w_farsi = W_CONV;
+#endif
+}
+
+/*
+ * Allocate the first window and put an empty buffer in it.
+ * Called from main().
+ * Return FAIL when something goes wrong (out of memory).
+ */
+    int
+win_alloc_first()
+{
+    if (win_alloc_firstwin(NULL) == FAIL)
+	return FAIL;
+
+#ifdef FEAT_WINDOWS
+    first_tabpage = alloc_tabpage();
+    if (first_tabpage == NULL)
+	return FAIL;
+    first_tabpage->tp_topframe = topframe;
+    curtab = first_tabpage;
+#endif
+    return OK;
+}
+
+/*
+ * Allocate the first window or the first window in a new tab page.
+ * When "oldwin" is NULL create an empty buffer for it.
+ * When "oldwin" is not NULL copy info from it to the new window (only with
+ * FEAT_WINDOWS).
+ * Return FAIL when something goes wrong (out of memory).
+ */
+    static int
+win_alloc_firstwin(oldwin)
+    win_T	*oldwin;
+{
+    curwin = win_alloc(NULL);
+    if (oldwin == NULL)
+    {
+	/* Very first window, need to create an empty buffer for it and
+	 * initialize from scratch. */
+	curbuf = buflist_new(NULL, NULL, 1L, BLN_LISTED);
+	if (curwin == NULL || curbuf == NULL)
+	    return FAIL;
+	curwin->w_buffer = curbuf;
+	curbuf->b_nwindows = 1;	/* there is one window */
+#ifdef FEAT_WINDOWS
+	curwin->w_alist = &global_alist;
+#endif
+	curwin_init();		/* init current window */
+    }
+#ifdef FEAT_WINDOWS
+    else
+    {
+	/* First window in new tab page, initialize it from "oldwin". */
+	win_init(curwin, oldwin);
+
+# ifdef FEAT_SCROLLBIND
+	/* We don't want scroll-binding in the first window. */
+	curwin->w_p_scb = FALSE;
+# endif
+    }
+#endif
+
+    topframe = (frame_T *)alloc_clear((unsigned)sizeof(frame_T));
+    if (topframe == NULL)
+	return FAIL;
+    topframe->fr_layout = FR_LEAF;
+#ifdef FEAT_VERTSPLIT
+    topframe->fr_width = Columns;
+#endif
+    topframe->fr_height = Rows - p_ch;
+    topframe->fr_win = curwin;
+    curwin->w_frame = topframe;
+
+    return OK;
+}
+
+/*
+ * Initialize the window and frame size to the maximum.
+ */
+    void
+win_init_size()
+{
+    firstwin->w_height = ROWS_AVAIL;
+    topframe->fr_height = ROWS_AVAIL;
+#ifdef FEAT_VERTSPLIT
+    firstwin->w_width = Columns;
+    topframe->fr_width = Columns;
+#endif
+}
+
+#if defined(FEAT_WINDOWS) || defined(PROTO)
+
+/*
+ * Allocate a new tabpage_T and init the values.
+ * Returns NULL when out of memory.
+ */
+    static tabpage_T *
+alloc_tabpage()
+{
+    tabpage_T	*tp;
+
+    tp = (tabpage_T *)alloc_clear((unsigned)sizeof(tabpage_T));
+    if (tp != NULL)
+    {
+# ifdef FEAT_GUI
+	int	i;
+
+	for (i = 0; i < 3; i++)
+	    tp->tp_prev_which_scrollbars[i] = -1;
+# endif
+# ifdef FEAT_DIFF
+	tp->tp_diff_invalid = TRUE;
+# endif
+#ifdef FEAT_EVAL
+	/* init t: variables */
+	init_var_dict(&tp->tp_vars, &tp->tp_winvar);
+#endif
+	tp->tp_ch_used = p_ch;
+    }
+    return tp;
+}
+
+    void
+free_tabpage(tp)
+    tabpage_T	*tp;
+{
+# ifdef FEAT_DIFF
+    diff_clear(tp);
+# endif
+    clear_snapshot(tp);
+#ifdef FEAT_EVAL
+    vars_clear(&tp->tp_vars.dv_hashtab);	/* free all t: variables */
+#endif
+    vim_free(tp);
+}
+
+/*
+ * Create a new Tab page with one window.
+ * It will edit the current buffer, like after ":split".
+ * When "after" is 0 put it just after the current Tab page.
+ * Otherwise put it just before tab page "after".
+ * Return FAIL or OK.
+ */
+    int
+win_new_tabpage(after)
+    int		after;
+{
+    tabpage_T	*tp = curtab;
+    tabpage_T	*newtp;
+    int		n;
+
+    newtp = alloc_tabpage();
+    if (newtp == NULL)
+	return FAIL;
+
+    /* Remember the current windows in this Tab page. */
+    if (leave_tabpage(curbuf) == FAIL)
+    {
+	vim_free(newtp);
+	return FAIL;
+    }
+    curtab = newtp;
+
+    /* Create a new empty window. */
+    if (win_alloc_firstwin(tp->tp_curwin) == OK)
+    {
+	/* Make the new Tab page the new topframe. */
+	if (after == 1)
+	{
+	    /* New tab page becomes the first one. */
+	    newtp->tp_next = first_tabpage;
+	    first_tabpage = newtp;
+	}
+	else
+	{
+	    if (after > 0)
+	    {
+		/* Put new tab page before tab page "after". */
+		n = 2;
+		for (tp = first_tabpage; tp->tp_next != NULL
+					       && n < after; tp = tp->tp_next)
+		    ++n;
+	    }
+	    newtp->tp_next = tp->tp_next;
+	    tp->tp_next = newtp;
+	}
+	win_init_size();
+	firstwin->w_winrow = tabline_height();
+	win_comp_scroll(curwin);
+
+	newtp->tp_topframe = topframe;
+	last_status(FALSE);
+
+#if defined(FEAT_GUI)
+	/* When 'guioptions' includes 'L' or 'R' may have to remove or add
+	 * scrollbars.  Have to update them anyway. */
+	if (gui.in_use && starting == 0)
+	{
+	    gui_init_which_components(NULL);
+	    gui_update_scrollbars(TRUE);
+	}
+	need_mouse_correct = TRUE;
+#endif
+
+	redraw_all_later(CLEAR);
+#ifdef FEAT_AUTOCMD
+	apply_autocmds(EVENT_TABENTER, NULL, NULL, FALSE, curbuf);
+	apply_autocmds(EVENT_WINENTER, NULL, NULL, FALSE, curbuf);
+#endif
+	return OK;
+    }
+
+    /* Failed, get back the previous Tab page */
+    enter_tabpage(curtab, curbuf);
+    return FAIL;
+}
+
+/*
+ * Open a new tab page if ":tab cmd" was used.  It will edit the same buffer,
+ * like with ":split".
+ * Returns OK if a new tab page was created, FAIL otherwise.
+ */
+    int
+may_open_tabpage()
+{
+    int		n = (cmdmod.tab == 0) ? postponed_split_tab : cmdmod.tab;
+
+    if (n != 0)
+    {
+	cmdmod.tab = 0;	    /* reset it to avoid doing it twice */
+	postponed_split_tab = 0;
+	return win_new_tabpage(n);
+    }
+    return FAIL;
+}
+
+/*
+ * Create up to "maxcount" tabpages with empty windows.
+ * Returns the number of resulting tab pages.
+ */
+    int
+make_tabpages(maxcount)
+    int		maxcount;
+{
+    int		count = maxcount;
+    int		todo;
+
+    /* Limit to 'tabpagemax' tabs. */
+    if (count > p_tpm)
+	count = p_tpm;
+
+#ifdef FEAT_AUTOCMD
+    /*
+     * Don't execute autocommands while creating the tab pages.  Must do that
+     * when putting the buffers in the windows.
+     */
+    ++autocmd_block;
+#endif
+
+    for (todo = count - 1; todo > 0; --todo)
+	if (win_new_tabpage(0) == FAIL)
+	    break;
+
+#ifdef FEAT_AUTOCMD
+    --autocmd_block;
+#endif
+
+    /* return actual number of tab pages */
+    return (count - todo);
+}
+
+/*
+ * Return TRUE when "tpc" points to a valid tab page.
+ */
+    int
+valid_tabpage(tpc)
+    tabpage_T	*tpc;
+{
+    tabpage_T	*tp;
+
+    for (tp = first_tabpage; tp != NULL; tp = tp->tp_next)
+	if (tp == tpc)
+	    return TRUE;
+    return FALSE;
+}
+
+/*
+ * Find tab page "n" (first one is 1).  Returns NULL when not found.
+ */
+    tabpage_T *
+find_tabpage(n)
+    int		n;
+{
+    tabpage_T	*tp;
+    int		i = 1;
+
+    for (tp = first_tabpage; tp != NULL && i != n; tp = tp->tp_next)
+	++i;
+    return tp;
+}
+
+/*
+ * Get index of tab page "tp".  First one has index 1.
+ * When not found returns number of tab pages plus one.
+ */
+    int
+tabpage_index(ftp)
+    tabpage_T	*ftp;
+{
+    int		i = 1;
+    tabpage_T	*tp;
+
+    for (tp = first_tabpage; tp != NULL && tp != ftp; tp = tp->tp_next)
+	++i;
+    return i;
+}
+
+/*
+ * Prepare for leaving the current tab page.
+ * When autocomands change "curtab" we don't leave the tab page and return
+ * FAIL.
+ * Careful: When OK is returned need to get a new tab page very very soon!
+ */
+/*ARGSUSED*/
+    static int
+leave_tabpage(new_curbuf)
+    buf_T	*new_curbuf;	    /* what is going to be the new curbuf,
+				       NULL if unknown */
+{
+    tabpage_T	*tp = curtab;
+
+#ifdef FEAT_VISUAL
+    reset_VIsual_and_resel();	/* stop Visual mode */
+#endif
+#ifdef FEAT_AUTOCMD
+    if (new_curbuf != curbuf)
+    {
+	apply_autocmds(EVENT_BUFLEAVE, NULL, NULL, FALSE, curbuf);
+	if (curtab != tp)
+	    return FAIL;
+    }
+    apply_autocmds(EVENT_WINLEAVE, NULL, NULL, FALSE, curbuf);
+    if (curtab != tp)
+	return FAIL;
+    apply_autocmds(EVENT_TABLEAVE, NULL, NULL, FALSE, curbuf);
+    if (curtab != tp)
+	return FAIL;
+#endif
+#if defined(FEAT_GUI)
+    /* Remove the scrollbars.  They may be added back later. */
+    if (gui.in_use)
+	gui_remove_scrollbars();
+#endif
+    tp->tp_curwin = curwin;
+    tp->tp_prevwin = prevwin;
+    tp->tp_firstwin = firstwin;
+    tp->tp_lastwin = lastwin;
+    tp->tp_old_Rows = Rows;
+    tp->tp_old_Columns = Columns;
+    firstwin = NULL;
+    lastwin = NULL;
+    return OK;
+}
+
+/*
+ * Start using tab page "tp".
+ * Only to be used after leave_tabpage() or freeing the current tab page.
+ */
+/*ARGSUSED*/
+    static void
+enter_tabpage(tp, old_curbuf)
+    tabpage_T	*tp;
+    buf_T	*old_curbuf;
+{
+    int		old_off = tp->tp_firstwin->w_winrow;
+    win_T	*next_prevwin = tp->tp_prevwin;
+
+    curtab = tp;
+    firstwin = tp->tp_firstwin;
+    lastwin = tp->tp_lastwin;
+    topframe = tp->tp_topframe;
+
+    /* We would like doing the TabEnter event first, but we don't have a
+     * valid current window yet, which may break some commands.
+     * This triggers autocommands, thus may make "tp" invalid. */
+    win_enter_ext(tp->tp_curwin, FALSE, TRUE);
+    prevwin = next_prevwin;
+
+#ifdef FEAT_AUTOCMD
+    apply_autocmds(EVENT_TABENTER, NULL, NULL, FALSE, curbuf);
+
+    if (old_curbuf != curbuf)
+	apply_autocmds(EVENT_BUFENTER, NULL, NULL, FALSE, curbuf);
+#endif
+
+    last_status(FALSE);		/* status line may appear or disappear */
+    (void)win_comp_pos();	/* recompute w_winrow for all windows */
+    must_redraw = CLEAR;	/* need to redraw everything */
+#ifdef FEAT_DIFF
+    diff_need_scrollbind = TRUE;
+#endif
+
+    /* The tabpage line may have appeared or disappeared, may need to resize
+     * the frames for that.  When the Vim window was resized need to update
+     * frame sizes too.  Use the stored value of p_ch, so that it can be
+     * different for each tab page. */
+    p_ch = curtab->tp_ch_used;
+    if (curtab->tp_old_Rows != Rows || (old_off != firstwin->w_winrow
+#ifdef FEAT_GUI_TABLINE
+			    && !gui_use_tabline()
+#endif
+		))
+	shell_new_rows();
+#ifdef FEAT_VERTSPLIT
+    if (curtab->tp_old_Columns != Columns && starting == 0)
+	shell_new_columns();	/* update window widths */
+#endif
+
+#if defined(FEAT_GUI)
+    /* When 'guioptions' includes 'L' or 'R' may have to remove or add
+     * scrollbars.  Have to update them anyway. */
+    if (gui.in_use && starting == 0)
+    {
+	gui_init_which_components(NULL);
+	gui_update_scrollbars(TRUE);
+    }
+    need_mouse_correct = TRUE;
+#endif
+
+    redraw_all_later(CLEAR);
+}
+
+/*
+ * Go to tab page "n".  For ":tab N" and "Ngt".
+ * When "n" is 9999 go to the last tab page.
+ */
+    void
+goto_tabpage(n)
+    int	    n;
+{
+    tabpage_T	*tp;
+    tabpage_T	*ttp;
+    int		i;
+
+    if (text_locked())
+    {
+	/* Not allowed when editing the command line. */
+#ifdef FEAT_CMDWIN
+	if (cmdwin_type != 0)
+	    EMSG(_(e_cmdwin));
+	else
+#endif
+	    EMSG(_(e_secure));
+	return;
+    }
+
+    /* If there is only one it can't work. */
+    if (first_tabpage->tp_next == NULL)
+    {
+	if (n > 1)
+	    beep_flush();
+	return;
+    }
+
+    if (n == 0)
+    {
+	/* No count, go to next tab page, wrap around end. */
+	if (curtab->tp_next == NULL)
+	    tp = first_tabpage;
+	else
+	    tp = curtab->tp_next;
+    }
+    else if (n < 0)
+    {
+	/* "gT": go to previous tab page, wrap around end.  "N gT" repeats
+	 * this N times. */
+	ttp = curtab;
+	for (i = n; i < 0; ++i)
+	{
+	    for (tp = first_tabpage; tp->tp_next != ttp && tp->tp_next != NULL;
+		    tp = tp->tp_next)
+		;
+	    ttp = tp;
+	}
+    }
+    else if (n == 9999)
+    {
+	/* Go to last tab page. */
+	for (tp = first_tabpage; tp->tp_next != NULL; tp = tp->tp_next)
+	    ;
+    }
+    else
+    {
+	/* Go to tab page "n". */
+	tp = find_tabpage(n);
+	if (tp == NULL)
+	{
+	    beep_flush();
+	    return;
+	}
+    }
+
+    goto_tabpage_tp(tp);
+
+#ifdef FEAT_GUI_TABLINE
+    if (gui_use_tabline())
+	gui_mch_set_curtab(tabpage_index(curtab));
+#endif
+}
+
+/*
+ * Go to tabpage "tp".
+ * Note: doesn't update the GUI tab.
+ */
+    void
+goto_tabpage_tp(tp)
+    tabpage_T	*tp;
+{
+    if (tp != curtab && leave_tabpage(tp->tp_curwin->w_buffer) == OK)
+    {
+	if (valid_tabpage(tp))
+	    enter_tabpage(tp, curbuf);
+	else
+	    enter_tabpage(curtab, curbuf);
+    }
+}
+
+/*
+ * Enter window "wp" in tab page "tp".
+ * Also updates the GUI tab.
+ */
+    void
+goto_tabpage_win(tp, wp)
+    tabpage_T	*tp;
+    win_T	*wp;
+{
+    goto_tabpage_tp(tp);
+    if (curtab == tp && win_valid(wp))
+    {
+	win_enter(wp, TRUE);
+# ifdef FEAT_GUI_TABLINE
+	if (gui_use_tabline())
+	    gui_mch_set_curtab(tabpage_index(curtab));
+# endif
+    }
+}
+
+/*
+ * Move the current tab page to before tab page "nr".
+ */
+    void
+tabpage_move(nr)
+    int		nr;
+{
+    int		n = nr;
+    tabpage_T	*tp;
+
+    if (first_tabpage->tp_next == NULL)
+	return;
+
+    /* Remove the current tab page from the list of tab pages. */
+    if (curtab == first_tabpage)
+	first_tabpage = curtab->tp_next;
+    else
+    {
+	for (tp = first_tabpage; tp != NULL; tp = tp->tp_next)
+	    if (tp->tp_next == curtab)
+		break;
+	if (tp == NULL)	/* "cannot happen" */
+	    return;
+	tp->tp_next = curtab->tp_next;
+    }
+
+    /* Re-insert it at the specified position. */
+    if (n == 0)
+    {
+	curtab->tp_next = first_tabpage;
+	first_tabpage = curtab;
+    }
+    else
+    {
+	for (tp = first_tabpage; tp->tp_next != NULL && n > 1; tp = tp->tp_next)
+	    --n;
+	curtab->tp_next = tp->tp_next;
+	tp->tp_next = curtab;
+    }
+
+    /* Need to redraw the tabline.  Tab page contents doesn't change. */
+    redraw_tabline = TRUE;
+}
+
+
+/*
+ * Go to another window.
+ * When jumping to another buffer, stop Visual mode.  Do this before
+ * changing windows so we can yank the selection into the '*' register.
+ * When jumping to another window on the same buffer, adjust its cursor
+ * position to keep the same Visual area.
+ */
+    void
+win_goto(wp)
+    win_T	*wp;
+{
+    if (text_locked())
+    {
+	beep_flush();
+	text_locked_msg();
+	return;
+    }
+#ifdef FEAT_AUTOCMD
+    if (curbuf_locked())
+	return;
+#endif
+
+#ifdef FEAT_VISUAL
+    if (wp->w_buffer != curbuf)
+	reset_VIsual_and_resel();
+    else if (VIsual_active)
+	wp->w_cursor = curwin->w_cursor;
+#endif
+
+#ifdef FEAT_GUI
+    need_mouse_correct = TRUE;
+#endif
+    win_enter(wp, TRUE);
+}
+
+#if defined(FEAT_PERL) || defined(PROTO)
+/*
+ * Find window number "winnr" (counting top to bottom).
+ */
+    win_T *
+win_find_nr(winnr)
+    int		winnr;
+{
+    win_T	*wp;
+
+# ifdef FEAT_WINDOWS
+    for (wp = firstwin; wp != NULL; wp = wp->w_next)
+	if (--winnr == 0)
+	    break;
+    return wp;
+# else
+    return curwin;
+# endif
+}
+#endif
+
+#ifdef FEAT_VERTSPLIT
+/*
+ * Move to window above or below "count" times.
+ */
+    static void
+win_goto_ver(up, count)
+    int		up;		/* TRUE to go to win above */
+    long	count;
+{
+    frame_T	*fr;
+    frame_T	*nfr;
+    frame_T	*foundfr;
+
+    foundfr = curwin->w_frame;
+    while (count--)
+    {
+	/*
+	 * First go upwards in the tree of frames until we find a upwards or
+	 * downwards neighbor.
+	 */
+	fr = foundfr;
+	for (;;)
+	{
+	    if (fr == topframe)
+		goto end;
+	    if (up)
+		nfr = fr->fr_prev;
+	    else
+		nfr = fr->fr_next;
+	    if (fr->fr_parent->fr_layout == FR_COL && nfr != NULL)
+		break;
+	    fr = fr->fr_parent;
+	}
+
+	/*
+	 * Now go downwards to find the bottom or top frame in it.
+	 */
+	for (;;)
+	{
+	    if (nfr->fr_layout == FR_LEAF)
+	    {
+		foundfr = nfr;
+		break;
+	    }
+	    fr = nfr->fr_child;
+	    if (nfr->fr_layout == FR_ROW)
+	    {
+		/* Find the frame at the cursor row. */
+		while (fr->fr_next != NULL
+			&& frame2win(fr)->w_wincol + fr->fr_width
+					 <= curwin->w_wincol + curwin->w_wcol)
+		    fr = fr->fr_next;
+	    }
+	    if (nfr->fr_layout == FR_COL && up)
+		while (fr->fr_next != NULL)
+		    fr = fr->fr_next;
+	    nfr = fr;
+	}
+    }
+end:
+    if (foundfr != NULL)
+	win_goto(foundfr->fr_win);
+}
+
+/*
+ * Move to left or right window.
+ */
+    static void
+win_goto_hor(left, count)
+    int		left;		/* TRUE to go to left win */
+    long	count;
+{
+    frame_T	*fr;
+    frame_T	*nfr;
+    frame_T	*foundfr;
+
+    foundfr = curwin->w_frame;
+    while (count--)
+    {
+	/*
+	 * First go upwards in the tree of frames until we find a left or
+	 * right neighbor.
+	 */
+	fr = foundfr;
+	for (;;)
+	{
+	    if (fr == topframe)
+		goto end;
+	    if (left)
+		nfr = fr->fr_prev;
+	    else
+		nfr = fr->fr_next;
+	    if (fr->fr_parent->fr_layout == FR_ROW && nfr != NULL)
+		break;
+	    fr = fr->fr_parent;
+	}
+
+	/*
+	 * Now go downwards to find the leftmost or rightmost frame in it.
+	 */
+	for (;;)
+	{
+	    if (nfr->fr_layout == FR_LEAF)
+	    {
+		foundfr = nfr;
+		break;
+	    }
+	    fr = nfr->fr_child;
+	    if (nfr->fr_layout == FR_COL)
+	    {
+		/* Find the frame at the cursor row. */
+		while (fr->fr_next != NULL
+			&& frame2win(fr)->w_winrow + fr->fr_height
+					 <= curwin->w_winrow + curwin->w_wrow)
+		    fr = fr->fr_next;
+	    }
+	    if (nfr->fr_layout == FR_ROW && left)
+		while (fr->fr_next != NULL)
+		    fr = fr->fr_next;
+	    nfr = fr;
+	}
+    }
+end:
+    if (foundfr != NULL)
+	win_goto(foundfr->fr_win);
+}
+#endif
+
+/*
+ * Make window "wp" the current window.
+ */
+    void
+win_enter(wp, undo_sync)
+    win_T	*wp;
+    int		undo_sync;
+{
+    win_enter_ext(wp, undo_sync, FALSE);
+}
+
+/*
+ * Make window wp the current window.
+ * Can be called with "curwin_invalid" TRUE, which means that curwin has just
+ * been closed and isn't valid.
+ */
+    static void
+win_enter_ext(wp, undo_sync, curwin_invalid)
+    win_T	*wp;
+    int		undo_sync;
+    int		curwin_invalid;
+{
+#ifdef FEAT_AUTOCMD
+    int		other_buffer = FALSE;
+#endif
+
+    if (wp == curwin && !curwin_invalid)	/* nothing to do */
+	return;
+
+#ifdef FEAT_AUTOCMD
+    if (!curwin_invalid)
+    {
+	/*
+	 * Be careful: If autocommands delete the window, return now.
+	 */
+	if (wp->w_buffer != curbuf)
+	{
+	    apply_autocmds(EVENT_BUFLEAVE, NULL, NULL, FALSE, curbuf);
+	    other_buffer = TRUE;
+	    if (!win_valid(wp))
+		return;
+	}
+	apply_autocmds(EVENT_WINLEAVE, NULL, NULL, FALSE, curbuf);
+	if (!win_valid(wp))
+	    return;
+# ifdef FEAT_EVAL
+	/* autocmds may abort script processing */
+	if (aborting())
+	    return;
+# endif
+    }
+#endif
+
+    /* sync undo before leaving the current buffer */
+    if (undo_sync && curbuf != wp->w_buffer)
+	u_sync(FALSE);
+    /* may have to copy the buffer options when 'cpo' contains 'S' */
+    if (wp->w_buffer != curbuf)
+	buf_copy_options(wp->w_buffer, BCO_ENTER | BCO_NOHELP);
+    if (!curwin_invalid)
+    {
+	prevwin = curwin;	/* remember for CTRL-W p */
+	curwin->w_redr_status = TRUE;
+    }
+    curwin = wp;
+    curbuf = wp->w_buffer;
+    check_cursor();
+#ifdef FEAT_VIRTUALEDIT
+    if (!virtual_active())
+	curwin->w_cursor.coladd = 0;
+#endif
+    changed_line_abv_curs();	/* assume cursor position needs updating */
+
+    if (curwin->w_localdir != NULL)
+    {
+	/* Window has a local directory: Save current directory as global
+	 * directory (unless that was done already) and change to the local
+	 * directory. */
+	if (globaldir == NULL)
+	{
+	    char_u	cwd[MAXPATHL];
+
+	    if (mch_dirname(cwd, MAXPATHL) == OK)
+		globaldir = vim_strsave(cwd);
+	}
+	mch_chdir((char *)curwin->w_localdir);
+	shorten_fnames(TRUE);
+    }
+    else if (globaldir != NULL)
+    {
+	/* Window doesn't have a local directory and we are not in the global
+	 * directory: Change to the global directory. */
+	mch_chdir((char *)globaldir);
+	vim_free(globaldir);
+	globaldir = NULL;
+	shorten_fnames(TRUE);
+    }
+
+#ifdef FEAT_AUTOCMD
+    apply_autocmds(EVENT_WINENTER, NULL, NULL, FALSE, curbuf);
+    if (other_buffer)
+	apply_autocmds(EVENT_BUFENTER, NULL, NULL, FALSE, curbuf);
+#endif
+
+#ifdef FEAT_TITLE
+    maketitle();
+#endif
+    curwin->w_redr_status = TRUE;
+    redraw_tabline = TRUE;
+    if (restart_edit)
+	redraw_later(VALID);	/* causes status line redraw */
+
+    /* set window height to desired minimal value */
+    if (curwin->w_height < p_wh && !curwin->w_p_wfh)
+	win_setheight((int)p_wh);
+    else if (curwin->w_height == 0)
+	win_setheight(1);
+
+#ifdef FEAT_VERTSPLIT
+    /* set window width to desired minimal value */
+    if (curwin->w_width < p_wiw && !curwin->w_p_wfw)
+	win_setwidth((int)p_wiw);
+#endif
+
+#ifdef FEAT_MOUSE
+    setmouse();			/* in case jumped to/from help buffer */
+#endif
+
+    /* Change directories when the 'acd' option is set. */
+    DO_AUTOCHDIR
+}
+
+#endif /* FEAT_WINDOWS */
+
+#if defined(FEAT_WINDOWS) || defined(FEAT_SIGNS) || defined(PROTO)
+/*
+ * Jump to the first open window that contains buffer "buf", if one exists.
+ * Returns a pointer to the window found, otherwise NULL.
+ */
+    win_T *
+buf_jump_open_win(buf)
+    buf_T	*buf;
+{
+# ifdef FEAT_WINDOWS
+    win_T	*wp;
+
+    for (wp = firstwin; wp != NULL; wp = wp->w_next)
+	if (wp->w_buffer == buf)
+	    break;
+    if (wp != NULL)
+	win_enter(wp, FALSE);
+    return wp;
+# else
+    if (curwin->w_buffer == buf)
+	return curwin;
+    return NULL;
+# endif
+}
+
+/*
+ * Jump to the first open window in any tab page that contains buffer "buf",
+ * if one exists.
+ * Returns a pointer to the window found, otherwise NULL.
+ */
+    win_T *
+buf_jump_open_tab(buf)
+    buf_T	*buf;
+{
+# ifdef FEAT_WINDOWS
+    win_T	*wp;
+    tabpage_T	*tp;
+
+    /* First try the current tab page. */
+    wp = buf_jump_open_win(buf);
+    if (wp != NULL)
+	return wp;
+
+    for (tp = first_tabpage; tp != NULL; tp = tp->tp_next)
+	if (tp != curtab)
+	{
+	    for (wp = tp->tp_firstwin; wp != NULL; wp = wp->w_next)
+		if (wp->w_buffer == buf)
+		    break;
+	    if (wp != NULL)
+	    {
+		goto_tabpage_win(tp, wp);
+		if (curwin != wp)
+		    wp = NULL;	/* something went wrong */
+		break;
+	    }
+	}
+
+    return wp;
+# else
+    if (curwin->w_buffer == buf)
+	return curwin;
+    return NULL;
+# endif
+}
+#endif
+
+/*
+ * allocate a window structure and link it in the window list
+ */
+/*ARGSUSED*/
+    static win_T *
+win_alloc(after)
+    win_T	*after;
+{
+    win_T	*newwin;
+
+    /*
+     * allocate window structure and linesizes arrays
+     */
+    newwin = (win_T *)alloc_clear((unsigned)sizeof(win_T));
+    if (newwin != NULL && win_alloc_lines(newwin) == FAIL)
+    {
+	vim_free(newwin);
+	newwin = NULL;
+    }
+
+    if (newwin != NULL)
+    {
+#ifdef FEAT_AUTOCMD
+	/* Don't execute autocommands while the window is not properly
+	 * initialized yet.  gui_create_scrollbar() may trigger a FocusGained
+	 * event. */
+	++autocmd_block;
+#endif
+	/*
+	 * link the window in the window list
+	 */
+#ifdef FEAT_WINDOWS
+	win_append(after, newwin);
+#endif
+#ifdef FEAT_VERTSPLIT
+	newwin->w_wincol = 0;
+	newwin->w_width = Columns;
+#endif
+
+	/* position the display and the cursor at the top of the file. */
+	newwin->w_topline = 1;
+#ifdef FEAT_DIFF
+	newwin->w_topfill = 0;
+#endif
+	newwin->w_botline = 2;
+	newwin->w_cursor.lnum = 1;
+#ifdef FEAT_SCROLLBIND
+	newwin->w_scbind_pos = 1;
+#endif
+
+	/* We won't calculate w_fraction until resizing the window */
+	newwin->w_fraction = 0;
+	newwin->w_prev_fraction_row = -1;
+
+#ifdef FEAT_GUI
+	if (gui.in_use)
+	{
+	    gui_create_scrollbar(&newwin->w_scrollbars[SBAR_LEFT],
+		    SBAR_LEFT, newwin);
+	    gui_create_scrollbar(&newwin->w_scrollbars[SBAR_RIGHT],
+		    SBAR_RIGHT, newwin);
+	}
+#endif
+#ifdef FEAT_EVAL
+	/* init w: variables */
+	init_var_dict(&newwin->w_vars, &newwin->w_winvar);
+#endif
+#ifdef FEAT_FOLDING
+	foldInitWin(newwin);
+#endif
+#ifdef FEAT_AUTOCMD
+	--autocmd_block;
+#endif
+    }
+    return newwin;
+}
+
+#if defined(FEAT_WINDOWS) || defined(PROTO)
+
+/*
+ * remove window 'wp' from the window list and free the structure
+ */
+    static void
+win_free(wp, tp)
+    win_T	*wp;
+    tabpage_T	*tp;		/* tab page "win" is in, NULL for current */
+{
+    int		i;
+
+#ifdef FEAT_AUTOCMD
+    /* Don't execute autocommands while the window is halfway being deleted.
+     * gui_mch_destroy_scrollbar() may trigger a FocusGained event. */
+    ++autocmd_block;
+#endif
+
+#ifdef FEAT_MZSCHEME
+    mzscheme_window_free(wp);
+#endif
+
+#ifdef FEAT_PERL
+    perl_win_free(wp);
+#endif
+
+#ifdef FEAT_PYTHON
+    python_window_free(wp);
+#endif
+
+#ifdef FEAT_TCL
+    tcl_window_free(wp);
+#endif
+
+#ifdef FEAT_RUBY
+    ruby_window_free(wp);
+#endif
+
+    clear_winopt(&wp->w_onebuf_opt);
+    clear_winopt(&wp->w_allbuf_opt);
+
+#ifdef FEAT_EVAL
+    vars_clear(&wp->w_vars.dv_hashtab);	    /* free all w: variables */
+#endif
+
+    if (prevwin == wp)
+	prevwin = NULL;
+    win_free_lsize(wp);
+
+    for (i = 0; i < wp->w_tagstacklen; ++i)
+	vim_free(wp->w_tagstack[i].tagname);
+
+    vim_free(wp->w_localdir);
+#ifdef FEAT_SEARCH_EXTRA
+    vim_free(wp->w_match[0].regprog);
+    vim_free(wp->w_match[1].regprog);
+    vim_free(wp->w_match[2].regprog);
+#endif
+#ifdef FEAT_JUMPLIST
+    free_jumplist(wp);
+#endif
+
+#ifdef FEAT_QUICKFIX
+    qf_free_all(wp);
+#endif
+
+#ifdef FEAT_GUI
+    if (gui.in_use)
+    {
+	gui_mch_destroy_scrollbar(&wp->w_scrollbars[SBAR_LEFT]);
+	gui_mch_destroy_scrollbar(&wp->w_scrollbars[SBAR_RIGHT]);
+    }
+#endif /* FEAT_GUI */
+
+    win_remove(wp, tp);
+    vim_free(wp);
+
+#ifdef FEAT_AUTOCMD
+    --autocmd_block;
+#endif
+}
+
+/*
+ * Append window "wp" in the window list after window "after".
+ */
+    static void
+win_append(after, wp)
+    win_T	*after, *wp;
+{
+    win_T	*before;
+
+    if (after == NULL)	    /* after NULL is in front of the first */
+	before = firstwin;
+    else
+	before = after->w_next;
+
+    wp->w_next = before;
+    wp->w_prev = after;
+    if (after == NULL)
+	firstwin = wp;
+    else
+	after->w_next = wp;
+    if (before == NULL)
+	lastwin = wp;
+    else
+	before->w_prev = wp;
+}
+
+/*
+ * Remove a window from the window list.
+ */
+    static void
+win_remove(wp, tp)
+    win_T	*wp;
+    tabpage_T	*tp;		/* tab page "win" is in, NULL for current */
+{
+    if (wp->w_prev != NULL)
+	wp->w_prev->w_next = wp->w_next;
+    else if (tp == NULL)
+	firstwin = wp->w_next;
+    else
+	tp->tp_firstwin = wp->w_next;
+    if (wp->w_next != NULL)
+	wp->w_next->w_prev = wp->w_prev;
+    else if (tp == NULL)
+	lastwin = wp->w_prev;
+    else
+	tp->tp_lastwin = wp->w_prev;
+}
+
+/*
+ * Append frame "frp" in a frame list after frame "after".
+ */
+    static void
+frame_append(after, frp)
+    frame_T	*after, *frp;
+{
+    frp->fr_next = after->fr_next;
+    after->fr_next = frp;
+    if (frp->fr_next != NULL)
+	frp->fr_next->fr_prev = frp;
+    frp->fr_prev = after;
+}
+
+/*
+ * Insert frame "frp" in a frame list before frame "before".
+ */
+    static void
+frame_insert(before, frp)
+    frame_T	*before, *frp;
+{
+    frp->fr_next = before;
+    frp->fr_prev = before->fr_prev;
+    before->fr_prev = frp;
+    if (frp->fr_prev != NULL)
+	frp->fr_prev->fr_next = frp;
+    else
+	frp->fr_parent->fr_child = frp;
+}
+
+/*
+ * Remove a frame from a frame list.
+ */
+    static void
+frame_remove(frp)
+    frame_T	*frp;
+{
+    if (frp->fr_prev != NULL)
+	frp->fr_prev->fr_next = frp->fr_next;
+    else
+	frp->fr_parent->fr_child = frp->fr_next;
+    if (frp->fr_next != NULL)
+	frp->fr_next->fr_prev = frp->fr_prev;
+}
+
+#endif /* FEAT_WINDOWS */
+
+/*
+ * Allocate w_lines[] for window "wp".
+ * Return FAIL for failure, OK for success.
+ */
+    int
+win_alloc_lines(wp)
+    win_T	*wp;
+{
+    wp->w_lines_valid = 0;
+    wp->w_lines = (wline_T *)alloc_clear((unsigned)(Rows * sizeof(wline_T)));
+    if (wp->w_lines == NULL)
+	return FAIL;
+    return OK;
+}
+
+/*
+ * free lsize arrays for a window
+ */
+    void
+win_free_lsize(wp)
+    win_T	*wp;
+{
+    vim_free(wp->w_lines);
+    wp->w_lines = NULL;
+}
+
+/*
+ * Called from win_new_shellsize() after Rows changed.
+ * This only does the current tab page, others must be done when made active.
+ */
+    void
+shell_new_rows()
+{
+    int		h = (int)ROWS_AVAIL;
+
+    if (firstwin == NULL)	/* not initialized yet */
+	return;
+#ifdef FEAT_WINDOWS
+    if (h < frame_minheight(topframe, NULL))
+	h = frame_minheight(topframe, NULL);
+
+    /* First try setting the heights of windows with 'winfixheight'.  If
+     * that doesn't result in the right height, forget about that option. */
+    frame_new_height(topframe, h, FALSE, TRUE);
+    if (topframe->fr_height != h)
+	frame_new_height(topframe, h, FALSE, FALSE);
+
+    (void)win_comp_pos();		/* recompute w_winrow and w_wincol */
+#else
+    if (h < 1)
+	h = 1;
+    win_new_height(firstwin, h);
+#endif
+    compute_cmdrow();
+#ifdef FEAT_WINDOWS
+    curtab->tp_ch_used = p_ch;
+#endif
+
+#if 0
+    /* Disabled: don't want making the screen smaller make a window larger. */
+    if (p_ea)
+	win_equal(curwin, FALSE, 'v');
+#endif
+}
+
+#if defined(FEAT_VERTSPLIT) || defined(PROTO)
+/*
+ * Called from win_new_shellsize() after Columns changed.
+ */
+    void
+shell_new_columns()
+{
+    if (firstwin == NULL)	/* not initialized yet */
+	return;
+
+    /* First try setting the widths of windows with 'winfixwidth'.  If that
+     * doesn't result in the right width, forget about that option. */
+    frame_new_width(topframe, (int)Columns, FALSE, TRUE);
+    if (topframe->fr_width != Columns)
+	frame_new_width(topframe, (int)Columns, FALSE, FALSE);
+
+    (void)win_comp_pos();		/* recompute w_winrow and w_wincol */
+#if 0
+    /* Disabled: don't want making the screen smaller make a window larger. */
+    if (p_ea)
+	win_equal(curwin, FALSE, 'h');
+#endif
+}
+#endif
+
+#if defined(FEAT_CMDWIN) || defined(PROTO)
+/*
+ * Save the size of all windows in "gap".
+ */
+    void
+win_size_save(gap)
+    garray_T	*gap;
+
+{
+    win_T	*wp;
+
+    ga_init2(gap, (int)sizeof(int), 1);
+    if (ga_grow(gap, win_count() * 2) == OK)
+	for (wp = firstwin; wp != NULL; wp = wp->w_next)
+	{
+	    ((int *)gap->ga_data)[gap->ga_len++] =
+					       wp->w_width + wp->w_vsep_width;
+	    ((int *)gap->ga_data)[gap->ga_len++] = wp->w_height;
+	}
+}
+
+/*
+ * Restore window sizes, but only if the number of windows is still the same.
+ * Does not free the growarray.
+ */
+    void
+win_size_restore(gap)
+    garray_T	*gap;
+{
+    win_T	*wp;
+    int		i;
+
+    if (win_count() * 2 == gap->ga_len)
+    {
+	i = 0;
+	for (wp = firstwin; wp != NULL; wp = wp->w_next)
+	{
+	    frame_setwidth(wp->w_frame, ((int *)gap->ga_data)[i++]);
+	    win_setheight_win(((int *)gap->ga_data)[i++], wp);
+	}
+	/* recompute the window positions */
+	(void)win_comp_pos();
+    }
+}
+#endif /* FEAT_CMDWIN */
+
+#if defined(FEAT_WINDOWS) || defined(PROTO)
+/*
+ * Update the position for all windows, using the width and height of the
+ * frames.
+ * Returns the row just after the last window.
+ */
+    int
+win_comp_pos()
+{
+    int		row = tabline_height();
+    int		col = 0;
+
+    frame_comp_pos(topframe, &row, &col);
+    return row;
+}
+
+/*
+ * Update the position of the windows in frame "topfrp", using the width and
+ * height of the frames.
+ * "*row" and "*col" are the top-left position of the frame.  They are updated
+ * to the bottom-right position plus one.
+ */
+    static void
+frame_comp_pos(topfrp, row, col)
+    frame_T	*topfrp;
+    int		*row;
+    int		*col;
+{
+    win_T	*wp;
+    frame_T	*frp;
+#ifdef FEAT_VERTSPLIT
+    int		startcol;
+    int		startrow;
+#endif
+
+    wp = topfrp->fr_win;
+    if (wp != NULL)
+    {
+	if (wp->w_winrow != *row
+#ifdef FEAT_VERTSPLIT
+		|| wp->w_wincol != *col
+#endif
+		)
+	{
+	    /* position changed, redraw */
+	    wp->w_winrow = *row;
+#ifdef FEAT_VERTSPLIT
+	    wp->w_wincol = *col;
+#endif
+	    redraw_win_later(wp, NOT_VALID);
+	    wp->w_redr_status = TRUE;
+	}
+	*row += wp->w_height + wp->w_status_height;
+#ifdef FEAT_VERTSPLIT
+	*col += wp->w_width + wp->w_vsep_width;
+#endif
+    }
+    else
+    {
+#ifdef FEAT_VERTSPLIT
+	startrow = *row;
+	startcol = *col;
+#endif
+	for (frp = topfrp->fr_child; frp != NULL; frp = frp->fr_next)
+	{
+#ifdef FEAT_VERTSPLIT
+	    if (topfrp->fr_layout == FR_ROW)
+		*row = startrow;	/* all frames are at the same row */
+	    else
+		*col = startcol;	/* all frames are at the same col */
+#endif
+	    frame_comp_pos(frp, row, col);
+	}
+    }
+}
+
+#endif /* FEAT_WINDOWS */
+
+/*
+ * Set current window height and take care of repositioning other windows to
+ * fit around it.
+ */
+    void
+win_setheight(height)
+    int		height;
+{
+    win_setheight_win(height, curwin);
+}
+
+/*
+ * Set the window height of window "win" and take care of repositioning other
+ * windows to fit around it.
+ */
+    void
+win_setheight_win(height, win)
+    int		height;
+    win_T	*win;
+{
+    int		row;
+
+    if (win == curwin)
+    {
+	/* Always keep current window at least one line high, even when
+	 * 'winminheight' is zero. */
+#ifdef FEAT_WINDOWS
+	if (height < p_wmh)
+	    height = p_wmh;
+#endif
+	if (height == 0)
+	    height = 1;
+    }
+
+#ifdef FEAT_WINDOWS
+    frame_setheight(win->w_frame, height + win->w_status_height);
+
+    /* recompute the window positions */
+    row = win_comp_pos();
+#else
+    if (height > topframe->fr_height)
+	height = topframe->fr_height;
+    win->w_height = height;
+    row = height;
+#endif
+
+    /*
+     * If there is extra space created between the last window and the command
+     * line, clear it.
+     */
+    if (full_screen && msg_scrolled == 0 && row < cmdline_row)
+	screen_fill(row, cmdline_row, 0, (int)Columns, ' ', ' ', 0);
+    cmdline_row = row;
+    msg_row = row;
+    msg_col = 0;
+
+    redraw_all_later(NOT_VALID);
+}
+
+#if defined(FEAT_WINDOWS) || defined(PROTO)
+
+/*
+ * Set the height of a frame to "height" and take care that all frames and
+ * windows inside it are resized.  Also resize frames on the left and right if
+ * the are in the same FR_ROW frame.
+ *
+ * Strategy:
+ * If the frame is part of a FR_COL frame, try fitting the frame in that
+ * frame.  If that doesn't work (the FR_COL frame is too small), recursively
+ * go to containing frames to resize them and make room.
+ * If the frame is part of a FR_ROW frame, all frames must be resized as well.
+ * Check for the minimal height of the FR_ROW frame.
+ * At the top level we can also use change the command line height.
+ */
+    static void
+frame_setheight(curfrp, height)
+    frame_T	*curfrp;
+    int		height;
+{
+    int		room;		/* total number of lines available */
+    int		take;		/* number of lines taken from other windows */
+    int		room_cmdline;	/* lines available from cmdline */
+    int		run;
+    frame_T	*frp;
+    int		h;
+    int		room_reserved;
+
+    /* If the height already is the desired value, nothing to do. */
+    if (curfrp->fr_height == height)
+	return;
+
+    if (curfrp->fr_parent == NULL)
+    {
+	/* topframe: can only change the command line */
+	if (height > ROWS_AVAIL)
+	    height = ROWS_AVAIL;
+	if (height > 0)
+	    frame_new_height(curfrp, height, FALSE, FALSE);
+    }
+    else if (curfrp->fr_parent->fr_layout == FR_ROW)
+    {
+	/* Row of frames: Also need to resize frames left and right of this
+	 * one.  First check for the minimal height of these. */
+	h = frame_minheight(curfrp->fr_parent, NULL);
+	if (height < h)
+	    height = h;
+	frame_setheight(curfrp->fr_parent, height);
+    }
+    else
+    {
+	/*
+	 * Column of frames: try to change only frames in this column.
+	 */
+#ifdef FEAT_VERTSPLIT
+	/*
+	 * Do this twice:
+	 * 1: compute room available, if it's not enough try resizing the
+	 *    containing frame.
+	 * 2: compute the room available and adjust the height to it.
+	 * Try not to reduce the height of a window with 'winfixheight' set.
+	 */
+	for (run = 1; run <= 2; ++run)
+#else
+	for (;;)
+#endif
+	{
+	    room = 0;
+	    room_reserved = 0;
+	    for (frp = curfrp->fr_parent->fr_child; frp != NULL;
+							   frp = frp->fr_next)
+	    {
+		if (frp != curfrp
+			&& frp->fr_win != NULL
+			&& frp->fr_win->w_p_wfh)
+		    room_reserved += frp->fr_height;
+		room += frp->fr_height;
+		if (frp != curfrp)
+		    room -= frame_minheight(frp, NULL);
+	    }
+#ifdef FEAT_VERTSPLIT
+	    if (curfrp->fr_width != Columns)
+		room_cmdline = 0;
+	    else
+#endif
+	    {
+		room_cmdline = Rows - p_ch - (lastwin->w_winrow
+			       + lastwin->w_height + lastwin->w_status_height);
+		if (room_cmdline < 0)
+		    room_cmdline = 0;
+	    }
+
+	    if (height <= room + room_cmdline)
+		break;
+#ifdef FEAT_VERTSPLIT
+	    if (run == 2 || curfrp->fr_width == Columns)
+#endif
+	    {
+		if (height > room + room_cmdline)
+		    height = room + room_cmdline;
+		break;
+	    }
+#ifdef FEAT_VERTSPLIT
+	    frame_setheight(curfrp->fr_parent, height
+		+ frame_minheight(curfrp->fr_parent, NOWIN) - (int)p_wmh - 1);
+#endif
+	    /*NOTREACHED*/
+	}
+
+	/*
+	 * Compute the number of lines we will take from others frames (can be
+	 * negative!).
+	 */
+	take = height - curfrp->fr_height;
+
+	/* If there is not enough room, also reduce the height of a window
+	 * with 'winfixheight' set. */
+	if (height > room + room_cmdline - room_reserved)
+	    room_reserved = room + room_cmdline - height;
+	/* If there is only a 'winfixheight' window and making the
+	 * window smaller, need to make the other window taller. */
+	if (take < 0 && room - curfrp->fr_height < room_reserved)
+	    room_reserved = 0;
+
+	if (take > 0 && room_cmdline > 0)
+	{
+	    /* use lines from cmdline first */
+	    if (take < room_cmdline)
+		room_cmdline = take;
+	    take -= room_cmdline;
+	    topframe->fr_height += room_cmdline;
+	}
+
+	/*
+	 * set the current frame to the new height
+	 */
+	frame_new_height(curfrp, height, FALSE, FALSE);
+
+	/*
+	 * First take lines from the frames after the current frame.  If
+	 * that is not enough, takes lines from frames above the current
+	 * frame.
+	 */
+	for (run = 0; run < 2; ++run)
+	{
+	    if (run == 0)
+		frp = curfrp->fr_next;	/* 1st run: start with next window */
+	    else
+		frp = curfrp->fr_prev;	/* 2nd run: start with prev window */
+	    while (frp != NULL && take != 0)
+	    {
+		h = frame_minheight(frp, NULL);
+		if (room_reserved > 0
+			&& frp->fr_win != NULL
+			&& frp->fr_win->w_p_wfh)
+		{
+		    if (room_reserved >= frp->fr_height)
+			room_reserved -= frp->fr_height;
+		    else
+		    {
+			if (frp->fr_height - room_reserved > take)
+			    room_reserved = frp->fr_height - take;
+			take -= frp->fr_height - room_reserved;
+			frame_new_height(frp, room_reserved, FALSE, FALSE);
+			room_reserved = 0;
+		    }
+		}
+		else
+		{
+		    if (frp->fr_height - take < h)
+		    {
+			take -= frp->fr_height - h;
+			frame_new_height(frp, h, FALSE, FALSE);
+		    }
+		    else
+		    {
+			frame_new_height(frp, frp->fr_height - take,
+								FALSE, FALSE);
+			take = 0;
+		    }
+		}
+		if (run == 0)
+		    frp = frp->fr_next;
+		else
+		    frp = frp->fr_prev;
+	    }
+	}
+    }
+}
+
+#if defined(FEAT_VERTSPLIT) || defined(PROTO)
+/*
+ * Set current window width and take care of repositioning other windows to
+ * fit around it.
+ */
+    void
+win_setwidth(width)
+    int		width;
+{
+    win_setwidth_win(width, curwin);
+}
+
+    void
+win_setwidth_win(width, wp)
+    int		width;
+    win_T	*wp;
+{
+    /* Always keep current window at least one column wide, even when
+     * 'winminwidth' is zero. */
+    if (wp == curwin)
+    {
+	if (width < p_wmw)
+	    width = p_wmw;
+	if (width == 0)
+	    width = 1;
+    }
+
+    frame_setwidth(wp->w_frame, width + wp->w_vsep_width);
+
+    /* recompute the window positions */
+    (void)win_comp_pos();
+
+    redraw_all_later(NOT_VALID);
+}
+
+/*
+ * Set the width of a frame to "width" and take care that all frames and
+ * windows inside it are resized.  Also resize frames above and below if the
+ * are in the same FR_ROW frame.
+ *
+ * Strategy is similar to frame_setheight().
+ */
+    static void
+frame_setwidth(curfrp, width)
+    frame_T	*curfrp;
+    int		width;
+{
+    int		room;		/* total number of lines available */
+    int		take;		/* number of lines taken from other windows */
+    int		run;
+    frame_T	*frp;
+    int		w;
+    int		room_reserved;
+
+    /* If the width already is the desired value, nothing to do. */
+    if (curfrp->fr_width == width)
+	return;
+
+    if (curfrp->fr_parent == NULL)
+	/* topframe: can't change width */
+	return;
+
+    if (curfrp->fr_parent->fr_layout == FR_COL)
+    {
+	/* Column of frames: Also need to resize frames above and below of
+	 * this one.  First check for the minimal width of these. */
+	w = frame_minwidth(curfrp->fr_parent, NULL);
+	if (width < w)
+	    width = w;
+	frame_setwidth(curfrp->fr_parent, width);
+    }
+    else
+    {
+	/*
+	 * Row of frames: try to change only frames in this row.
+	 *
+	 * Do this twice:
+	 * 1: compute room available, if it's not enough try resizing the
+	 *    containing frame.
+	 * 2: compute the room available and adjust the width to it.
+	 */
+	for (run = 1; run <= 2; ++run)
+	{
+	    room = 0;
+	    room_reserved = 0;
+	    for (frp = curfrp->fr_parent->fr_child; frp != NULL;
+							   frp = frp->fr_next)
+	    {
+		if (frp != curfrp
+			&& frp->fr_win != NULL
+			&& frp->fr_win->w_p_wfw)
+		    room_reserved += frp->fr_width;
+		room += frp->fr_width;
+		if (frp != curfrp)
+		    room -= frame_minwidth(frp, NULL);
+	    }
+
+	    if (width <= room)
+		break;
+	    if (run == 2 || curfrp->fr_height >= ROWS_AVAIL)
+	    {
+		if (width > room)
+		    width = room;
+		break;
+	    }
+	    frame_setwidth(curfrp->fr_parent, width
+		 + frame_minwidth(curfrp->fr_parent, NOWIN) - (int)p_wmw - 1);
+	}
+
+	/*
+	 * Compute the number of lines we will take from others frames (can be
+	 * negative!).
+	 */
+	take = width - curfrp->fr_width;
+
+	/* If there is not enough room, also reduce the width of a window
+	 * with 'winfixwidth' set. */
+	if (width > room - room_reserved)
+	    room_reserved = room - width;
+	/* If there is only a 'winfixwidth' window and making the
+	 * window smaller, need to make the other window narrower. */
+	if (take < 0 && room - curfrp->fr_width < room_reserved)
+	    room_reserved = 0;
+
+	/*
+	 * set the current frame to the new width
+	 */
+	frame_new_width(curfrp, width, FALSE, FALSE);
+
+	/*
+	 * First take lines from the frames right of the current frame.  If
+	 * that is not enough, takes lines from frames left of the current
+	 * frame.
+	 */
+	for (run = 0; run < 2; ++run)
+	{
+	    if (run == 0)
+		frp = curfrp->fr_next;	/* 1st run: start with next window */
+	    else
+		frp = curfrp->fr_prev;	/* 2nd run: start with prev window */
+	    while (frp != NULL && take != 0)
+	    {
+		w = frame_minwidth(frp, NULL);
+		if (room_reserved > 0
+			&& frp->fr_win != NULL
+			&& frp->fr_win->w_p_wfw)
+		{
+		    if (room_reserved >= frp->fr_width)
+			room_reserved -= frp->fr_width;
+		    else
+		    {
+			if (frp->fr_width - room_reserved > take)
+			    room_reserved = frp->fr_width - take;
+			take -= frp->fr_width - room_reserved;
+			frame_new_width(frp, room_reserved, FALSE, FALSE);
+			room_reserved = 0;
+		    }
+		}
+		else
+		{
+		    if (frp->fr_width - take < w)
+		    {
+			take -= frp->fr_width - w;
+			frame_new_width(frp, w, FALSE, FALSE);
+		    }
+		    else
+		    {
+			frame_new_width(frp, frp->fr_width - take,
+								FALSE, FALSE);
+			take = 0;
+		    }
+		}
+		if (run == 0)
+		    frp = frp->fr_next;
+		else
+		    frp = frp->fr_prev;
+	    }
+	}
+    }
+}
+#endif /* FEAT_VERTSPLIT */
+
+/*
+ * Check 'winminheight' for a valid value.
+ */
+    void
+win_setminheight()
+{
+    int		room;
+    int		first = TRUE;
+    win_T	*wp;
+
+    /* loop until there is a 'winminheight' that is possible */
+    while (p_wmh > 0)
+    {
+	/* TODO: handle vertical splits */
+	room = -p_wh;
+	for (wp = firstwin; wp != NULL; wp = wp->w_next)
+	    room += wp->w_height - p_wmh;
+	if (room >= 0)
+	    break;
+	--p_wmh;
+	if (first)
+	{
+	    EMSG(_(e_noroom));
+	    first = FALSE;
+	}
+    }
+}
+
+#ifdef FEAT_MOUSE
+
+/*
+ * Status line of dragwin is dragged "offset" lines down (negative is up).
+ */
+    void
+win_drag_status_line(dragwin, offset)
+    win_T	*dragwin;
+    int		offset;
+{
+    frame_T	*curfr;
+    frame_T	*fr;
+    int		room;
+    int		row;
+    int		up;	/* if TRUE, drag status line up, otherwise down */
+    int		n;
+
+    fr = dragwin->w_frame;
+    curfr = fr;
+    if (fr != topframe)		/* more than one window */
+    {
+	fr = fr->fr_parent;
+	/* When the parent frame is not a column of frames, its parent should
+	 * be. */
+	if (fr->fr_layout != FR_COL)
+	{
+	    curfr = fr;
+	    if (fr != topframe)	/* only a row of windows, may drag statusline */
+		fr = fr->fr_parent;
+	}
+    }
+
+    /* If this is the last frame in a column, may want to resize the parent
+     * frame instead (go two up to skip a row of frames). */
+    while (curfr != topframe && curfr->fr_next == NULL)
+    {
+	if (fr != topframe)
+	    fr = fr->fr_parent;
+	curfr = fr;
+	if (fr != topframe)
+	    fr = fr->fr_parent;
+    }
+
+    if (offset < 0) /* drag up */
+    {
+	up = TRUE;
+	offset = -offset;
+	/* sum up the room of the current frame and above it */
+	if (fr == curfr)
+	{
+	    /* only one window */
+	    room = fr->fr_height - frame_minheight(fr, NULL);
+	}
+	else
+	{
+	    room = 0;
+	    for (fr = fr->fr_child; ; fr = fr->fr_next)
+	    {
+		room += fr->fr_height - frame_minheight(fr, NULL);
+		if (fr == curfr)
+		    break;
+	    }
+	}
+	fr = curfr->fr_next;		/* put fr at frame that grows */
+    }
+    else    /* drag down */
+    {
+	up = FALSE;
+	/*
+	 * Only dragging the last status line can reduce p_ch.
+	 */
+	room = Rows - cmdline_row;
+	if (curfr->fr_next == NULL)
+	    room -= 1;
+	else
+	    room -= p_ch;
+	if (room < 0)
+	    room = 0;
+	/* sum up the room of frames below of the current one */
+	for (fr = curfr->fr_next; fr != NULL; fr = fr->fr_next)
+	    room += fr->fr_height - frame_minheight(fr, NULL);
+	fr = curfr;			/* put fr at window that grows */
+    }
+
+    if (room < offset)		/* Not enough room */
+	offset = room;		/* Move as far as we can */
+    if (offset <= 0)
+	return;
+
+    /*
+     * Grow frame fr by "offset" lines.
+     * Doesn't happen when dragging the last status line up.
+     */
+    if (fr != NULL)
+	frame_new_height(fr, fr->fr_height + offset, up, FALSE);
+
+    if (up)
+	fr = curfr;		/* current frame gets smaller */
+    else
+	fr = curfr->fr_next;	/* next frame gets smaller */
+
+    /*
+     * Now make the other frames smaller.
+     */
+    while (fr != NULL && offset > 0)
+    {
+	n = frame_minheight(fr, NULL);
+	if (fr->fr_height - offset <= n)
+	{
+	    offset -= fr->fr_height - n;
+	    frame_new_height(fr, n, !up, FALSE);
+	}
+	else
+	{
+	    frame_new_height(fr, fr->fr_height - offset, !up, FALSE);
+	    break;
+	}
+	if (up)
+	    fr = fr->fr_prev;
+	else
+	    fr = fr->fr_next;
+    }
+    row = win_comp_pos();
+    screen_fill(row, cmdline_row, 0, (int)Columns, ' ', ' ', 0);
+    cmdline_row = row;
+    p_ch = Rows - cmdline_row;
+    if (p_ch < 1)
+	p_ch = 1;
+    curtab->tp_ch_used = p_ch;
+    redraw_all_later(SOME_VALID);
+    showmode();
+}
+
+#ifdef FEAT_VERTSPLIT
+/*
+ * Separator line of dragwin is dragged "offset" lines right (negative is left).
+ */
+    void
+win_drag_vsep_line(dragwin, offset)
+    win_T	*dragwin;
+    int		offset;
+{
+    frame_T	*curfr;
+    frame_T	*fr;
+    int		room;
+    int		left;	/* if TRUE, drag separator line left, otherwise right */
+    int		n;
+
+    fr = dragwin->w_frame;
+    if (fr == topframe)		/* only one window (cannot happen?) */
+	return;
+    curfr = fr;
+    fr = fr->fr_parent;
+    /* When the parent frame is not a row of frames, its parent should be. */
+    if (fr->fr_layout != FR_ROW)
+    {
+	if (fr == topframe)	/* only a column of windows (cannot happen?) */
+	    return;
+	curfr = fr;
+	fr = fr->fr_parent;
+    }
+
+    /* If this is the last frame in a row, may want to resize a parent
+     * frame instead. */
+    while (curfr->fr_next == NULL)
+    {
+	if (fr == topframe)
+	    break;
+	curfr = fr;
+	fr = fr->fr_parent;
+	if (fr != topframe)
+	{
+	    curfr = fr;
+	    fr = fr->fr_parent;
+	}
+    }
+
+    if (offset < 0) /* drag left */
+    {
+	left = TRUE;
+	offset = -offset;
+	/* sum up the room of the current frame and left of it */
+	room = 0;
+	for (fr = fr->fr_child; ; fr = fr->fr_next)
+	{
+	    room += fr->fr_width - frame_minwidth(fr, NULL);
+	    if (fr == curfr)
+		break;
+	}
+	fr = curfr->fr_next;		/* put fr at frame that grows */
+    }
+    else    /* drag right */
+    {
+	left = FALSE;
+	/* sum up the room of frames right of the current one */
+	room = 0;
+	for (fr = curfr->fr_next; fr != NULL; fr = fr->fr_next)
+	    room += fr->fr_width - frame_minwidth(fr, NULL);
+	fr = curfr;			/* put fr at window that grows */
+    }
+
+    if (room < offset)		/* Not enough room */
+	offset = room;		/* Move as far as we can */
+    if (offset <= 0)		/* No room at all, quit. */
+	return;
+
+    /* grow frame fr by offset lines */
+    frame_new_width(fr, fr->fr_width + offset, left, FALSE);
+
+    /* shrink other frames: current and at the left or at the right */
+    if (left)
+	fr = curfr;		/* current frame gets smaller */
+    else
+	fr = curfr->fr_next;	/* next frame gets smaller */
+
+    while (fr != NULL && offset > 0)
+    {
+	n = frame_minwidth(fr, NULL);
+	if (fr->fr_width - offset <= n)
+	{
+	    offset -= fr->fr_width - n;
+	    frame_new_width(fr, n, !left, FALSE);
+	}
+	else
+	{
+	    frame_new_width(fr, fr->fr_width - offset, !left, FALSE);
+	    break;
+	}
+	if (left)
+	    fr = fr->fr_prev;
+	else
+	    fr = fr->fr_next;
+    }
+    (void)win_comp_pos();
+    redraw_all_later(NOT_VALID);
+}
+#endif /* FEAT_VERTSPLIT */
+#endif /* FEAT_MOUSE */
+
+#endif /* FEAT_WINDOWS */
+
+/*
+ * Set the height of a window.
+ * This takes care of the things inside the window, not what happens to the
+ * window position, the frame or to other windows.
+ */
+    static void
+win_new_height(wp, height)
+    win_T	*wp;
+    int		height;
+{
+    linenr_T	lnum;
+    int		sline, line_size;
+#define FRACTION_MULT	16384L
+
+    /* Don't want a negative height.  Happens when splitting a tiny window.
+     * Will equalize heights soon to fix it. */
+    if (height < 0)
+	height = 0;
+    if (wp->w_height == height)
+	return;	    /* nothing to do */
+
+    if (wp->w_wrow != wp->w_prev_fraction_row && wp->w_height > 0)
+	wp->w_fraction = ((long)wp->w_wrow * FRACTION_MULT
+				    + FRACTION_MULT / 2) / (long)wp->w_height;
+
+    wp->w_height = height;
+    wp->w_skipcol = 0;
+
+    /* Don't change w_topline when height is zero.  Don't set w_topline when
+     * 'scrollbind' is set and this isn't the current window. */
+    if (height > 0
+#ifdef FEAT_SCROLLBIND
+	    && (!wp->w_p_scb || wp == curwin)
+#endif
+       )
+    {
+	/*
+	 * Find a value for w_topline that shows the cursor at the same
+	 * relative position in the window as before (more or less).
+	 */
+	lnum = wp->w_cursor.lnum;
+	if (lnum < 1)		/* can happen when starting up */
+	    lnum = 1;
+	wp->w_wrow = ((long)wp->w_fraction * (long)height - 1L) / FRACTION_MULT;
+	line_size = plines_win_col(wp, lnum, (long)(wp->w_cursor.col)) - 1;
+	sline = wp->w_wrow - line_size;
+
+	if (sline >= 0)
+	{
+	    /* Make sure the whole cursor line is visible, if possible. */
+	    int rows = plines_win(wp, lnum, FALSE);
+
+	    if (sline > wp->w_height - rows)
+	    {
+		sline = wp->w_height - rows;
+		wp->w_wrow -= rows - line_size;
+	    }
+	}
+
+	if (sline < 0)
+	{
+	    /*
+	     * Cursor line would go off top of screen if w_wrow was this high.
+	     * Make cursor line the first line in the window.  If not enough
+	     * room use w_skipcol;
+	     */
+	    wp->w_wrow = line_size;
+	    if (wp->w_wrow >= wp->w_height
+				       && (W_WIDTH(wp) - win_col_off(wp)) > 0)
+	    {
+		wp->w_skipcol += W_WIDTH(wp) - win_col_off(wp);
+		--wp->w_wrow;
+		while (wp->w_wrow >= wp->w_height)
+		{
+		    wp->w_skipcol += W_WIDTH(wp) - win_col_off(wp)
+							   + win_col_off2(wp);
+		    --wp->w_wrow;
+		}
+	    }
+	}
+	else
+	{
+	    while (sline > 0 && lnum > 1)
+	    {
+#ifdef FEAT_FOLDING
+		hasFoldingWin(wp, lnum, &lnum, NULL, TRUE, NULL);
+		if (lnum == 1)
+		{
+		    /* first line in buffer is folded */
+		    line_size = 1;
+		    --sline;
+		    break;
+		}
+#endif
+		--lnum;
+#ifdef FEAT_DIFF
+		if (lnum == wp->w_topline)
+		    line_size = plines_win_nofill(wp, lnum, TRUE)
+							      + wp->w_topfill;
+		else
+#endif
+		    line_size = plines_win(wp, lnum, TRUE);
+		sline -= line_size;
+	    }
+
+	    if (sline < 0)
+	    {
+		/*
+		 * Line we want at top would go off top of screen.  Use next
+		 * line instead.
+		 */
+#ifdef FEAT_FOLDING
+		hasFoldingWin(wp, lnum, NULL, &lnum, TRUE, NULL);
+#endif
+		lnum++;
+		wp->w_wrow -= line_size + sline;
+	    }
+	    else if (sline > 0)
+	    {
+		/* First line of file reached, use that as topline. */
+		lnum = 1;
+		wp->w_wrow -= sline;
+	    }
+	}
+	set_topline(wp, lnum);
+    }
+
+    if (wp == curwin)
+    {
+	if (p_so)
+	    update_topline();
+	curs_columns(FALSE);	/* validate w_wrow */
+    }
+    wp->w_prev_fraction_row = wp->w_wrow;
+
+    win_comp_scroll(wp);
+    redraw_win_later(wp, SOME_VALID);
+#ifdef FEAT_WINDOWS
+    wp->w_redr_status = TRUE;
+#endif
+    invalidate_botline_win(wp);
+}
+
+#ifdef FEAT_VERTSPLIT
+/*
+ * Set the width of a window.
+ */
+    static void
+win_new_width(wp, width)
+    win_T	*wp;
+    int		width;
+{
+    wp->w_width = width;
+    wp->w_lines_valid = 0;
+    changed_line_abv_curs_win(wp);
+    invalidate_botline_win(wp);
+    if (wp == curwin)
+    {
+	update_topline();
+	curs_columns(TRUE);	/* validate w_wrow */
+    }
+    redraw_win_later(wp, NOT_VALID);
+    wp->w_redr_status = TRUE;
+}
+#endif
+
+    void
+win_comp_scroll(wp)
+    win_T	*wp;
+{
+    wp->w_p_scr = ((unsigned)wp->w_height >> 1);
+    if (wp->w_p_scr == 0)
+	wp->w_p_scr = 1;
+}
+
+/*
+ * command_height: called whenever p_ch has been changed
+ */
+    void
+command_height()
+{
+#ifdef FEAT_WINDOWS
+    int		h;
+    frame_T	*frp;
+    int		old_p_ch = curtab->tp_ch_used;
+
+    /* Use the value of p_ch that we remembered.  This is needed for when the
+     * GUI starts up, we can't be sure in what order things happen.  And when
+     * p_ch was changed in another tab page. */
+    curtab->tp_ch_used = p_ch;
+
+    /* Find bottom frame with width of screen. */
+    frp = lastwin->w_frame;
+# ifdef FEAT_VERTSPLIT
+    while (frp->fr_width != Columns && frp->fr_parent != NULL)
+	frp = frp->fr_parent;
+# endif
+
+    /* Avoid changing the height of a window with 'winfixheight' set. */
+    while (frp->fr_prev != NULL && frp->fr_layout == FR_LEAF
+						      && frp->fr_win->w_p_wfh)
+	frp = frp->fr_prev;
+
+    if (starting != NO_SCREEN)
+    {
+	cmdline_row = Rows - p_ch;
+
+	if (p_ch > old_p_ch)		    /* p_ch got bigger */
+	{
+	    while (p_ch > old_p_ch)
+	    {
+		if (frp == NULL)
+		{
+		    EMSG(_(e_noroom));
+		    p_ch = old_p_ch;
+		    cmdline_row = Rows - p_ch;
+		    break;
+		}
+		h = frp->fr_height - frame_minheight(frp, NULL);
+		if (h > p_ch - old_p_ch)
+		    h = p_ch - old_p_ch;
+		old_p_ch += h;
+		frame_add_height(frp, -h);
+		frp = frp->fr_prev;
+	    }
+
+	    /* Recompute window positions. */
+	    (void)win_comp_pos();
+
+	    /* clear the lines added to cmdline */
+	    if (full_screen)
+		screen_fill((int)(cmdline_row), (int)Rows, 0,
+						   (int)Columns, ' ', ' ', 0);
+	    msg_row = cmdline_row;
+	    redraw_cmdline = TRUE;
+	    return;
+	}
+
+	if (msg_row < cmdline_row)
+	    msg_row = cmdline_row;
+	redraw_cmdline = TRUE;
+    }
+    frame_add_height(frp, (int)(old_p_ch - p_ch));
+
+    /* Recompute window positions. */
+    if (frp != lastwin->w_frame)
+	(void)win_comp_pos();
+#else
+    cmdline_row = Rows - p_ch;
+    win_setheight(cmdline_row);
+#endif
+}
+
+#if defined(FEAT_WINDOWS) || defined(PROTO)
+/*
+ * Resize frame "frp" to be "n" lines higher (negative for less high).
+ * Also resize the frames it is contained in.
+ */
+    static void
+frame_add_height(frp, n)
+    frame_T	*frp;
+    int		n;
+{
+    frame_new_height(frp, frp->fr_height + n, FALSE, FALSE);
+    for (;;)
+    {
+	frp = frp->fr_parent;
+	if (frp == NULL)
+	    break;
+	frp->fr_height += n;
+    }
+}
+
+/*
+ * Add or remove a status line for the bottom window(s), according to the
+ * value of 'laststatus'.
+ */
+    void
+last_status(morewin)
+    int		morewin;	/* pretend there are two or more windows */
+{
+    /* Don't make a difference between horizontal or vertical split. */
+    last_status_rec(topframe, (p_ls == 2
+			  || (p_ls == 1 && (morewin || lastwin != firstwin))));
+}
+
+    static void
+last_status_rec(fr, statusline)
+    frame_T	*fr;
+    int		statusline;
+{
+    frame_T	*fp;
+    win_T	*wp;
+
+    if (fr->fr_layout == FR_LEAF)
+    {
+	wp = fr->fr_win;
+	if (wp->w_status_height != 0 && !statusline)
+	{
+	    /* remove status line */
+	    win_new_height(wp, wp->w_height + 1);
+	    wp->w_status_height = 0;
+	    comp_col();
+	}
+	else if (wp->w_status_height == 0 && statusline)
+	{
+	    /* Find a frame to take a line from. */
+	    fp = fr;
+	    while (fp->fr_height <= frame_minheight(fp, NULL))
+	    {
+		if (fp == topframe)
+		{
+		    EMSG(_(e_noroom));
+		    return;
+		}
+		/* In a column of frames: go to frame above.  If already at
+		 * the top or in a row of frames: go to parent. */
+		if (fp->fr_parent->fr_layout == FR_COL && fp->fr_prev != NULL)
+		    fp = fp->fr_prev;
+		else
+		    fp = fp->fr_parent;
+	    }
+	    wp->w_status_height = 1;
+	    if (fp != fr)
+	    {
+		frame_new_height(fp, fp->fr_height - 1, FALSE, FALSE);
+		frame_fix_height(wp);
+		(void)win_comp_pos();
+	    }
+	    else
+		win_new_height(wp, wp->w_height - 1);
+	    comp_col();
+	    redraw_all_later(SOME_VALID);
+	}
+    }
+#ifdef FEAT_VERTSPLIT
+    else if (fr->fr_layout == FR_ROW)
+    {
+	/* vertically split windows, set status line for each one */
+	for (fp = fr->fr_child; fp != NULL; fp = fp->fr_next)
+	    last_status_rec(fp, statusline);
+    }
+#endif
+    else
+    {
+	/* horizontally split window, set status line for last one */
+	for (fp = fr->fr_child; fp->fr_next != NULL; fp = fp->fr_next)
+	    ;
+	last_status_rec(fp, statusline);
+    }
+}
+
+/*
+ * Return the number of lines used by the tab page line.
+ */
+    int
+tabline_height()
+{
+#ifdef FEAT_GUI_TABLINE
+    /* When the GUI has the tabline then this always returns zero. */
+    if (gui_use_tabline())
+	return 0;
+#endif
+    switch (p_stal)
+    {
+	case 0: return 0;
+	case 1: return (first_tabpage->tp_next == NULL) ? 0 : 1;
+    }
+    return 1;
+}
+
+#endif /* FEAT_WINDOWS */
+
+#if defined(FEAT_SEARCHPATH) || defined(PROTO)
+/*
+ * Get the file name at the cursor.
+ * If Visual mode is active, use the selected text if it's in one line.
+ * Returns the name in allocated memory, NULL for failure.
+ */
+    char_u *
+grab_file_name(count, file_lnum)
+    long	count;
+    linenr_T	*file_lnum;
+{
+# ifdef FEAT_VISUAL
+    if (VIsual_active)
+    {
+	int	len;
+	char_u	*ptr;
+
+	if (get_visual_text(NULL, &ptr, &len) == FAIL)
+	    return NULL;
+	return find_file_name_in_path(ptr, len,
+		     FNAME_MESS|FNAME_EXP|FNAME_REL, count, curbuf->b_ffname);
+    }
+# endif
+    return file_name_at_cursor(FNAME_MESS|FNAME_HYP|FNAME_EXP|FNAME_REL, count,
+			       file_lnum);
+
+}
+
+/*
+ * Return the file name under or after the cursor.
+ *
+ * The 'path' option is searched if the file name is not absolute.
+ * The string returned has been alloc'ed and should be freed by the caller.
+ * NULL is returned if the file name or file is not found.
+ *
+ * options:
+ * FNAME_MESS	    give error messages
+ * FNAME_EXP	    expand to path
+ * FNAME_HYP	    check for hypertext link
+ * FNAME_INCL	    apply "includeexpr"
+ */
+    char_u *
+file_name_at_cursor(options, count, file_lnum)
+    int		options;
+    long	count;
+    linenr_T	*file_lnum;
+{
+    return file_name_in_line(ml_get_curline(),
+		      curwin->w_cursor.col, options, count, curbuf->b_ffname,
+		      file_lnum);
+}
+
+/*
+ * Return the name of the file under or after ptr[col].
+ * Otherwise like file_name_at_cursor().
+ */
+    char_u *
+file_name_in_line(line, col, options, count, rel_fname, file_lnum)
+    char_u	*line;
+    int		col;
+    int		options;
+    long	count;
+    char_u	*rel_fname;	/* file we are searching relative to */
+    linenr_T	*file_lnum;	/* line number after the file name */
+{
+    char_u	*ptr;
+    int		len;
+
+    /*
+     * search forward for what could be the start of a file name
+     */
+    ptr = line + col;
+    while (*ptr != NUL && !vim_isfilec(*ptr))
+	mb_ptr_adv(ptr);
+    if (*ptr == NUL)		/* nothing found */
+    {
+	if (options & FNAME_MESS)
+	    EMSG(_("E446: No file name under cursor"));
+	return NULL;
+    }
+
+    /*
+     * Search backward for first char of the file name.
+     * Go one char back to ":" before "//" even when ':' is not in 'isfname'.
+     */
+    while (ptr > line)
+    {
+#ifdef FEAT_MBYTE
+	if (has_mbyte && (len = (*mb_head_off)(line, ptr - 1)) > 0)
+	    ptr -= len + 1;
+	else
+#endif
+	if (vim_isfilec(ptr[-1])
+		|| ((options & FNAME_HYP) && path_is_url(ptr - 1)))
+	    --ptr;
+	else
+	    break;
+    }
+
+    /*
+     * Search forward for the last char of the file name.
+     * Also allow "://" when ':' is not in 'isfname'.
+     */
+    len = 0;
+    while (vim_isfilec(ptr[len])
+			 || ((options & FNAME_HYP) && path_is_url(ptr + len)))
+#ifdef FEAT_MBYTE
+	if (has_mbyte)
+	    len += (*mb_ptr2len)(ptr + len);
+	else
+#endif
+	    ++len;
+
+    /*
+     * If there is trailing punctuation, remove it.
+     * But don't remove "..", could be a directory name.
+     */
+    if (len > 2 && vim_strchr((char_u *)".,:;!", ptr[len - 1]) != NULL
+						       && ptr[len - 2] != '.')
+	--len;
+
+    if (file_lnum != NULL)
+    {
+	char_u *p;
+
+	/* Get the number after the file name and a separator character */
+	p = ptr + len;
+	p = skipwhite(p);
+	if (*p != NUL)
+	{
+	    if (!isdigit(*p))
+		++p;		    /* skip the separator */
+	    p = skipwhite(p);
+	    if (isdigit(*p))
+		*file_lnum = (int)getdigits(&p);
+	}
+    }
+
+    return find_file_name_in_path(ptr, len, options, count, rel_fname);
+}
+
+# if defined(FEAT_FIND_ID) && defined(FEAT_EVAL)
+static char_u *eval_includeexpr __ARGS((char_u *ptr, int len));
+
+    static char_u *
+eval_includeexpr(ptr, len)
+    char_u	*ptr;
+    int		len;
+{
+    char_u	*res;
+
+    set_vim_var_string(VV_FNAME, ptr, len);
+    res = eval_to_string_safe(curbuf->b_p_inex, NULL,
+		      was_set_insecurely((char_u *)"includeexpr", OPT_LOCAL));
+    set_vim_var_string(VV_FNAME, NULL, 0);
+    return res;
+}
+#endif
+
+/*
+ * Return the name of the file ptr[len] in 'path'.
+ * Otherwise like file_name_at_cursor().
+ */
+    char_u *
+find_file_name_in_path(ptr, len, options, count, rel_fname)
+    char_u	*ptr;
+    int		len;
+    int		options;
+    long	count;
+    char_u	*rel_fname;	/* file we are searching relative to */
+{
+    char_u	*file_name;
+    int		c;
+# if defined(FEAT_FIND_ID) && defined(FEAT_EVAL)
+    char_u	*tofree = NULL;
+
+    if ((options & FNAME_INCL) && *curbuf->b_p_inex != NUL)
+    {
+	tofree = eval_includeexpr(ptr, len);
+	if (tofree != NULL)
+	{
+	    ptr = tofree;
+	    len = (int)STRLEN(ptr);
+	}
+    }
+# endif
+
+    if (options & FNAME_EXP)
+    {
+	file_name = find_file_in_path(ptr, len, options & ~FNAME_MESS,
+							     TRUE, rel_fname);
+
+# if defined(FEAT_FIND_ID) && defined(FEAT_EVAL)
+	/*
+	 * If the file could not be found in a normal way, try applying
+	 * 'includeexpr' (unless done already).
+	 */
+	if (file_name == NULL
+		&& !(options & FNAME_INCL) && *curbuf->b_p_inex != NUL)
+	{
+	    tofree = eval_includeexpr(ptr, len);
+	    if (tofree != NULL)
+	    {
+		ptr = tofree;
+		len = (int)STRLEN(ptr);
+		file_name = find_file_in_path(ptr, len, options & ~FNAME_MESS,
+							     TRUE, rel_fname);
+	    }
+	}
+# endif
+	if (file_name == NULL && (options & FNAME_MESS))
+	{
+	    c = ptr[len];
+	    ptr[len] = NUL;
+	    EMSG2(_("E447: Can't find file \"%s\" in path"), ptr);
+	    ptr[len] = c;
+	}
+
+	/* Repeat finding the file "count" times.  This matters when it
+	 * appears several times in the path. */
+	while (file_name != NULL && --count > 0)
+	{
+	    vim_free(file_name);
+	    file_name = find_file_in_path(ptr, len, options, FALSE, rel_fname);
+	}
+    }
+    else
+	file_name = vim_strnsave(ptr, len);
+
+# if defined(FEAT_FIND_ID) && defined(FEAT_EVAL)
+    vim_free(tofree);
+# endif
+
+    return file_name;
+}
+#endif /* FEAT_SEARCHPATH */
+
+/*
+ * Check if the "://" of a URL is at the pointer, return URL_SLASH.
+ * Also check for ":\\", which MS Internet Explorer accepts, return
+ * URL_BACKSLASH.
+ */
+    static int
+path_is_url(p)
+    char_u  *p;
+{
+    if (STRNCMP(p, "://", (size_t)3) == 0)
+	return URL_SLASH;
+    else if (STRNCMP(p, ":\\\\", (size_t)3) == 0)
+	return URL_BACKSLASH;
+    return 0;
+}
+
+/*
+ * Check if "fname" starts with "name://".  Return URL_SLASH if it does.
+ * Return URL_BACKSLASH for "name:\\".
+ * Return zero otherwise.
+ */
+    int
+path_with_url(fname)
+    char_u *fname;
+{
+    char_u *p;
+
+    for (p = fname; isalpha(*p); ++p)
+	;
+    return path_is_url(p);
+}
+
+/*
+ * Return TRUE if "name" is a full (absolute) path name or URL.
+ */
+    int
+vim_isAbsName(name)
+    char_u	*name;
+{
+    return (path_with_url(name) != 0 || mch_isFullName(name));
+}
+
+/*
+ * Get absolute file name into buffer "buf[len]".
+ *
+ * return FAIL for failure, OK otherwise
+ */
+    int
+vim_FullName(fname, buf, len, force)
+    char_u	*fname, *buf;
+    int		len;
+    int		force;	    /* force expansion even when already absolute */
+{
+    int		retval = OK;
+    int		url;
+
+    *buf = NUL;
+    if (fname == NULL)
+	return FAIL;
+
+    url = path_with_url(fname);
+    if (!url)
+	retval = mch_FullName(fname, buf, len, force);
+    if (url || retval == FAIL)
+    {
+	/* something failed; use the file name (truncate when too long) */
+	vim_strncpy(buf, fname, len - 1);
+    }
+#if defined(MACOS_CLASSIC) || defined(OS2) || defined(MSDOS) || defined(MSWIN)
+    slash_adjust(buf);
+#endif
+    return retval;
+}
+
+/*
+ * Return the minimal number of rows that is needed on the screen to display
+ * the current number of windows.
+ */
+    int
+min_rows()
+{
+    int		total;
+#ifdef FEAT_WINDOWS
+    tabpage_T	*tp;
+    int		n;
+#endif
+
+    if (firstwin == NULL)	/* not initialized yet */
+	return MIN_LINES;
+
+#ifdef FEAT_WINDOWS
+    total = 0;
+    for (tp = first_tabpage; tp != NULL; tp = tp->tp_next)
+    {
+	n = frame_minheight(tp->tp_topframe, NULL);
+	if (total < n)
+	    total = n;
+    }
+    total += tabline_height();
+#else
+    total = 1;		/* at least one window should have a line! */
+#endif
+    total += 1;		/* count the room for the command line */
+    return total;
+}
+
+/*
+ * Return TRUE if there is only one window (in the current tab page), not
+ * counting a help or preview window, unless it is the current window.
+ */
+    int
+only_one_window()
+{
+#ifdef FEAT_WINDOWS
+    int		count = 0;
+    win_T	*wp;
+
+    /* If there is another tab page there always is another window. */
+    if (first_tabpage->tp_next != NULL)
+	return FALSE;
+
+    for (wp = firstwin; wp != NULL; wp = wp->w_next)
+	if (!((wp->w_buffer->b_help && !curbuf->b_help)
+# ifdef FEAT_QUICKFIX
+		    || wp->w_p_pvw
+# endif
+	     ) || wp == curwin)
+	    ++count;
+    return (count <= 1);
+#else
+    return TRUE;
+#endif
+}
+
+#if defined(FEAT_WINDOWS) || defined(FEAT_AUTOCMD) || defined(PROTO)
+/*
+ * Correct the cursor line number in other windows.  Used after changing the
+ * current buffer, and before applying autocommands.
+ * When "do_curwin" is TRUE, also check current window.
+ */
+    void
+check_lnums(do_curwin)
+    int		do_curwin;
+{
+    win_T	*wp;
+
+#ifdef FEAT_WINDOWS
+    tabpage_T	*tp;
+
+    FOR_ALL_TAB_WINDOWS(tp, wp)
+	if ((do_curwin || wp != curwin) && wp->w_buffer == curbuf)
+#else
+    wp = curwin;
+    if (do_curwin)
+#endif
+	{
+	    if (wp->w_cursor.lnum > curbuf->b_ml.ml_line_count)
+		wp->w_cursor.lnum = curbuf->b_ml.ml_line_count;
+	    if (wp->w_topline > curbuf->b_ml.ml_line_count)
+		wp->w_topline = curbuf->b_ml.ml_line_count;
+	}
+}
+#endif
+
+#if defined(FEAT_WINDOWS) || defined(PROTO)
+
+/*
+ * A snapshot of the window sizes, to restore them after closing the help
+ * window.
+ * Only these fields are used:
+ * fr_layout
+ * fr_width
+ * fr_height
+ * fr_next
+ * fr_child
+ * fr_win (only valid for the old curwin, NULL otherwise)
+ */
+
+/*
+ * Create a snapshot of the current frame sizes.
+ */
+    static void
+make_snapshot()
+{
+    clear_snapshot(curtab);
+    make_snapshot_rec(topframe, &curtab->tp_snapshot);
+}
+
+    static void
+make_snapshot_rec(fr, frp)
+    frame_T	*fr;
+    frame_T	**frp;
+{
+    *frp = (frame_T *)alloc_clear((unsigned)sizeof(frame_T));
+    if (*frp == NULL)
+	return;
+    (*frp)->fr_layout = fr->fr_layout;
+# ifdef FEAT_VERTSPLIT
+    (*frp)->fr_width = fr->fr_width;
+# endif
+    (*frp)->fr_height = fr->fr_height;
+    if (fr->fr_next != NULL)
+	make_snapshot_rec(fr->fr_next, &((*frp)->fr_next));
+    if (fr->fr_child != NULL)
+	make_snapshot_rec(fr->fr_child, &((*frp)->fr_child));
+    if (fr->fr_layout == FR_LEAF && fr->fr_win == curwin)
+	(*frp)->fr_win = curwin;
+}
+
+/*
+ * Remove any existing snapshot.
+ */
+    static void
+clear_snapshot(tp)
+    tabpage_T	*tp;
+{
+    clear_snapshot_rec(tp->tp_snapshot);
+    tp->tp_snapshot = NULL;
+}
+
+    static void
+clear_snapshot_rec(fr)
+    frame_T	*fr;
+{
+    if (fr != NULL)
+    {
+	clear_snapshot_rec(fr->fr_next);
+	clear_snapshot_rec(fr->fr_child);
+	vim_free(fr);
+    }
+}
+
+/*
+ * Restore a previously created snapshot, if there is any.
+ * This is only done if the screen size didn't change and the window layout is
+ * still the same.
+ */
+    static void
+restore_snapshot(close_curwin)
+    int		close_curwin;	    /* closing current window */
+{
+    win_T	*wp;
+
+    if (curtab->tp_snapshot != NULL
+# ifdef FEAT_VERTSPLIT
+	    && curtab->tp_snapshot->fr_width == topframe->fr_width
+# endif
+	    && curtab->tp_snapshot->fr_height == topframe->fr_height
+	    && check_snapshot_rec(curtab->tp_snapshot, topframe) == OK)
+    {
+	wp = restore_snapshot_rec(curtab->tp_snapshot, topframe);
+	win_comp_pos();
+	if (wp != NULL && close_curwin)
+	    win_goto(wp);
+	redraw_all_later(CLEAR);
+    }
+    clear_snapshot(curtab);
+}
+
+/*
+ * Check if frames "sn" and "fr" have the same layout, same following frames
+ * and same children.
+ */
+    static int
+check_snapshot_rec(sn, fr)
+    frame_T	*sn;
+    frame_T	*fr;
+{
+    if (sn->fr_layout != fr->fr_layout
+	    || (sn->fr_next == NULL) != (fr->fr_next == NULL)
+	    || (sn->fr_child == NULL) != (fr->fr_child == NULL)
+	    || (sn->fr_next != NULL
+		&& check_snapshot_rec(sn->fr_next, fr->fr_next) == FAIL)
+	    || (sn->fr_child != NULL
+		&& check_snapshot_rec(sn->fr_child, fr->fr_child) == FAIL))
+	return FAIL;
+    return OK;
+}
+
+/*
+ * Copy the size of snapshot frame "sn" to frame "fr".  Do the same for all
+ * following frames and children.
+ * Returns a pointer to the old current window, or NULL.
+ */
+    static win_T *
+restore_snapshot_rec(sn, fr)
+    frame_T	*sn;
+    frame_T	*fr;
+{
+    win_T	*wp = NULL;
+    win_T	*wp2;
+
+    fr->fr_height = sn->fr_height;
+# ifdef FEAT_VERTSPLIT
+    fr->fr_width = sn->fr_width;
+# endif
+    if (fr->fr_layout == FR_LEAF)
+    {
+	frame_new_height(fr, fr->fr_height, FALSE, FALSE);
+# ifdef FEAT_VERTSPLIT
+	frame_new_width(fr, fr->fr_width, FALSE, FALSE);
+# endif
+	wp = sn->fr_win;
+    }
+    if (sn->fr_next != NULL)
+    {
+	wp2 = restore_snapshot_rec(sn->fr_next, fr->fr_next);
+	if (wp2 != NULL)
+	    wp = wp2;
+    }
+    if (sn->fr_child != NULL)
+    {
+	wp2 = restore_snapshot_rec(sn->fr_child, fr->fr_child);
+	if (wp2 != NULL)
+	    wp = wp2;
+    }
+    return wp;
+}
+
+#endif
+
+#if (defined(FEAT_GUI) && defined(FEAT_VERTSPLIT)) || defined(PROTO)
+/*
+ * Return TRUE if there is any vertically split window.
+ */
+    int
+win_hasvertsplit()
+{
+    frame_T	*fr;
+
+    if (topframe->fr_layout == FR_ROW)
+	return TRUE;
+
+    if (topframe->fr_layout == FR_COL)
+	for (fr = topframe->fr_child; fr != NULL; fr = fr->fr_next)
+	    if (fr->fr_layout == FR_ROW)
+		return TRUE;
+
+    return FALSE;
+}
+#endif
--- /dev/null
+++ b/xxd/xxd.c
@@ -1,0 +1,782 @@
+/* xxd: my hexdump facility. jw
+ *
+ *  2.10.90 changed to word output
+ *  3.03.93 new indent style, dumb bug inserted and fixed.
+ *	    -c option, mls
+ * 26.04.94 better option parser, -ps, -l, -s added.
+ *  1.07.94 -r badly needs - as input file.  Per default autoskip over
+ *	       consecutive lines of zeroes, as unix od does.
+ *	    -a shows them too.
+ *	    -i dump as c-style #include "file.h"
+ *  1.11.95 if "xxd -i" knows the filename, an 'unsigned char filename_bits[]'
+ *	    array is written in correct c-syntax.
+ *	    -s improved, now defaults to absolute seek, relative requires a '+'.
+ *	    -r improved, now -r -s -0x... is supported.
+ *	       change/suppress leading '\0' bytes.
+ *	    -l n improved: stops exactly after n bytes.
+ *	    -r improved, better handling of partial lines with trailing garbage.
+ *	    -r improved, now -r -p works again!
+ *	    -r improved, less flushing, much faster now! (that was silly)
+ *  3.04.96 Per repeated request of a single person: autoskip defaults to off.
+ * 15.05.96 -v added. They want to know the version.
+ *	    -a fixed, to show last line inf file ends in all zeros.
+ *	    -u added: Print upper case hex-letters, as preferred by unix bc.
+ *	    -h added to usage message. Usage message extended.
+ *	    Now using outfile if specified even in normal mode, aehem.
+ *	    No longer mixing of ints and longs. May help doze people.
+ *	    Added binify ioctl for same reason. (Enough Doze stress for 1996!)
+ * 16.05.96 -p improved, removed occasional superfluous linefeed.
+ * 20.05.96 -l 0 fixed. tried to read anyway.
+ * 21.05.96 -i fixed. now honours -u, and prepends __ to numeric filenames.
+ *	    compile -DWIN32 for NT or W95. George V. Reilly, * -v improved :-)
+ *	    support --gnuish-longhorn-options
+ * 25.05.96 MAC support added: CodeWarrior already uses ``outline'' in Types.h
+ *	    which is included by MacHeaders (Axel Kielhorn). Renamed to
+ *	    xxdline().
+ *  7.06.96 -i printed 'int' instead of 'char'. *blush*
+ *	    added Bram's OS2 ifdefs...
+ * 18.07.96 gcc -Wall @ SunOS4 is now slient.
+ *	    Added osver for MSDOS/DJGPP/WIN32.
+ * 29.08.96 Added size_t to strncmp() for Amiga.
+ * 24.03.97 Windows NT support (Phil Hanna). Clean exit for Amiga WB (Bram)
+ * 02.04.97 Added -E option, to have EBCDIC translation instead of ASCII
+ *	    (azc10@yahoo.com)
+ * 22.05.97 added -g (group octets) option (jcook@namerica.kla.com).
+ * 23.09.98 nasty -p -r misfeature fixed: slightly wrong output, when -c was
+ *	    missing or wrong.
+ * 26.09.98 Fixed: 'xxd -i infile outfile' did not truncate outfile.
+ * 27.10.98 Fixed: -g option parser required blank.
+ *	    option -b added: 01000101 binary output in normal format.
+ * 16.05.00 Added VAXC changes by Stephen P. Wall
+ * 16.05.00 Improved MMS file and merge for VMS by Zoltan Arpadffy
+ *
+ * (c) 1990-1998 by Juergen Weigert (jnweiger@informatik.uni-erlangen.de)
+ *
+ * Small changes made afterwards by Bram Moolenaar et al.
+ *
+ * Distribute freely and credit me,
+ * make money and share with me,
+ * lose money and don't ask me.
+ */
+
+/* Visual Studio 2005 has 'deprecated' many of the standard CRT functions */
+#if _MSC_VER >= 1400
+# define _CRT_SECURE_NO_DEPRECATE
+# define _CRT_NONSTDC_NO_DEPRECATE
+#endif
+
+#include <stdio.h>
+#ifdef VAXC
+# include <file.h>
+#else
+# include <fcntl.h>
+#endif
+#ifdef __TSC__
+# define MSDOS
+#endif
+#if !defined(OS2) && defined(__EMX__)
+# define OS2
+#endif
+#if defined(MSDOS) || defined(WIN32) || defined(OS2) || defined(__BORLANDC__)
+# include <io.h>	/* for setmode() */
+#else
+# ifdef UNIX
+#  include <unistd.h>
+# endif
+#endif
+#include <stdlib.h>
+#include <string.h>	/* for strncmp() */
+#include <ctype.h>	/* for isalnum() */
+#if __MWERKS__ && !defined(BEBOX)
+# include <unix.h>	/* for fdopen() on MAC */
+#endif
+
+#if defined(__BORLANDC__) && __BORLANDC__ <= 0x0410 && !defined(fileno)
+/* Missing define and prototype grabbed from the BC 4.0 <stdio.h> */
+# define fileno(f)       ((f)->fd)
+FILE   _FAR *_Cdecl _FARFUNC fdopen(int __handle, char _FAR *__type);
+#endif
+
+
+/*  This corrects the problem of missing prototypes for certain functions
+ *  in some GNU installations (e.g. SunOS 4.1.x).
+ *  Darren Hiebert <darren@hmi.com> (sparc-sun-sunos4.1.3_U1/2.7.2.2)
+ */
+#if defined(__GNUC__) && defined(__STDC__)
+# ifndef __USE_FIXED_PROTOTYPES__
+#  define __USE_FIXED_PROTOTYPES__
+# endif
+#endif
+
+#ifndef __USE_FIXED_PROTOTYPES__
+/*
+ * This is historic and works only if the compiler really has no prototypes:
+ *
+ * Include prototypes for Sun OS 4.x, when using an ANSI compiler.
+ * FILE is defined on OS 4.x, not on 5.x (Solaris).
+ * if __SVR4 is defined (some Solaris versions), don't include this.
+ */
+#if defined(sun) && defined(FILE) && !defined(__SVR4) && defined(__STDC__)
+#  define __P(a) a
+/* excerpt from my sun_stdlib.h */
+extern int fprintf __P((FILE *, char *, ...));
+extern int fputs   __P((char *, FILE *));
+extern int _flsbuf __P((unsigned char, FILE *));
+extern int _filbuf __P((FILE *));
+extern int fflush  __P((FILE *));
+extern int fclose  __P((FILE *));
+extern int fseek   __P((FILE *, long, int));
+extern int rewind  __P((FILE *));
+
+extern void perror __P((char *));
+# endif
+#endif
+
+extern long int strtol();
+extern long int ftell();
+
+char version[] = "xxd V1.10 27oct98 by Juergen Weigert";
+#ifdef WIN32
+char osver[] = " (Win32)";
+#else
+# ifdef DJGPP
+char osver[] = " (dos 32 bit)";
+# else
+#  ifdef MSDOS
+char osver[] = " (dos 16 bit)";
+#  else
+char osver[] = "";
+#  endif
+# endif
+#endif
+
+#if !defined(CYGWIN) && (defined(CYGWIN32) || defined(__CYGWIN__) || defined(__CYGWIN32__))
+# define CYGWIN
+#endif
+#if defined(MSDOS) || defined(WIN32) || defined(OS2)
+# define BIN_READ(yes)  ((yes) ? "rb" : "rt")
+# define BIN_WRITE(yes) ((yes) ? "wb" : "wt")
+# define BIN_CREAT(yes) ((yes) ? (O_CREAT|O_BINARY) : O_CREAT)
+# define BIN_ASSIGN(fp, yes) setmode(fileno(fp), (yes) ? O_BINARY : O_TEXT)
+# define PATH_SEP '\\'
+#elif defined(CYGWIN)
+# define BIN_READ(yes)  ((yes) ? "rb" : "rt")
+# define BIN_WRITE(yes) ((yes) ? "wb" : "w")
+# define BIN_CREAT(yes) ((yes) ? (O_CREAT|O_BINARY) : O_CREAT)
+# define BIN_ASSIGN(fp, yes) ((yes) ? (void) setmode(fileno(fp), O_BINARY) : (void) (fp))
+# define PATH_SEP '/'
+#else
+# ifdef VMS
+#  define BIN_READ(dummy)  "r"
+#  define BIN_WRITE(dummy) "w"
+#  define BIN_CREAT(dummy) O_CREAT
+#  define BIN_ASSIGN(fp, dummy) fp
+#  define PATH_SEP ']'
+#  define FILE_SEP '.'
+# else
+#  define BIN_READ(dummy)  "r"
+#  define BIN_WRITE(dummy) "w"
+#  define BIN_CREAT(dummy) O_CREAT
+#  define BIN_ASSIGN(fp, dummy) fp
+#  define PATH_SEP '/'
+# endif
+#endif
+
+/* open has only to arguments on the Mac */
+#if __MWERKS__
+# define OPEN(name, mode, umask) open(name, mode)
+#else
+# define OPEN(name, mode, umask) open(name, mode, umask)
+#endif
+
+#ifdef AMIGA
+# define STRNCMP(s1, s2, l) strncmp(s1, s2, (size_t)l)
+#else
+# define STRNCMP(s1, s2, l) strncmp(s1, s2, l)
+#endif
+
+#ifndef __P
+# if defined(__STDC__) || defined(MSDOS) || defined(WIN32) || defined(OS2) \
+		|| defined(__BORLANDC__)
+#  define __P(a) a
+# else
+#  define __P(a) ()
+# endif
+#endif
+
+/* Let's collect some prototypes */
+/* CodeWarrior is really picky about missing prototypes */
+static void exit_with_usage __P((char *));
+static int huntype __P((FILE *, FILE *, FILE *, char *, int, int, long));
+static void xxdline __P((FILE *, char *, int));
+
+#define TRY_SEEK	/* attempt to use lseek, or skip forward by reading */
+#define COLS 256	/* change here, if you ever need more columns */
+#define LLEN (9 + (5*COLS-1)/2 + 2 + COLS)
+
+char hexxa[] = "0123456789abcdef0123456789ABCDEF", *hexx = hexxa;
+
+/* the different hextypes known by this program: */
+#define HEX_NORMAL 0
+#define HEX_POSTSCRIPT 1
+#define HEX_CINCLUDE 2
+#define HEX_BITS 3		/* not hex a dump, but bits: 01111001 */
+
+static void
+exit_with_usage(pname)
+char *pname;
+{
+  fprintf(stderr, "Usage:\n       %s [options] [infile [outfile]]\n", pname);
+  fprintf(stderr, "    or\n       %s -r [-s [-]offset] [-c cols] [-ps] [infile [outfile]]\n", pname);
+  fprintf(stderr, "Options:\n");
+  fprintf(stderr, "    -a          toggle autoskip: A single '*' replaces nul-lines. Default off.\n");
+  fprintf(stderr, "    -b          binary digit dump (incompatible with -p,-i,-r). Default hex.\n");
+  fprintf(stderr, "    -c cols     format <cols> octets per line. Default 16 (-i: 12, -ps: 30).\n");
+  fprintf(stderr, "    -E          show characters in EBCDIC. Default ASCII.\n");
+  fprintf(stderr, "    -g          number of octets per group in normal output. Default 2.\n");
+  fprintf(stderr, "    -h          print this summary.\n");
+  fprintf(stderr, "    -i          output in C include file style.\n");
+  fprintf(stderr, "    -l len      stop after <len> octets.\n");
+  fprintf(stderr, "    -ps         output in postscript plain hexdump style.\n");
+  fprintf(stderr, "    -r          reverse operation: convert (or patch) hexdump into binary.\n");
+  fprintf(stderr, "    -r -s off   revert with <off> added to file positions found in hexdump.\n");
+  fprintf(stderr, "    -s %sseek  start at <seek> bytes abs. %sinfile offset.\n",
+#ifdef TRY_SEEK
+	  "[+][-]", "(or +: rel.) ");
+#else
+	  "", "");
+#endif
+  fprintf(stderr, "    -u          use upper case hex letters.\n");
+  fprintf(stderr, "    -v          show version: \"%s%s\".\n", version, osver);
+  exit(1);
+}
+
+/*
+ * Max. cols binary characters are decoded from the input stream per line.
+ * Two adjacent garbage characters after evaluated data delimit valid data.
+ * Everything up to the next newline is discarded.
+ *
+ * The name is historic and came from 'undo type opt h'.
+ */
+static int
+huntype(fpi, fpo, fperr, pname, cols, hextype, base_off)
+FILE *fpi, *fpo, *fperr;
+char *pname;
+int cols, hextype;
+long base_off;
+{
+  int c, ign_garb = 1, n1 = -1, n2 = 0, n3, p = cols;
+  long have_off = 0, want_off = 0;
+
+  rewind(fpi);
+
+  while ((c = getc(fpi)) != EOF)
+    {
+      if (c == '\r')	/* Doze style input file? */
+	continue;
+
+#if 0	/* this doesn't work when there is normal text after the hex codes in
+	   the last line that looks like hex */
+      if (c == ' ' || c == '\n' || c == '\t')  /* allow multiple spaces */
+	continue;
+#endif
+
+      n3 = n2;
+      n2 = n1;
+
+      if (c >= '0' && c <= '9')
+	n1 = c - '0';
+      else if (c >= 'a' && c <= 'f')
+	n1 = c - 'a' + 10;
+      else if (c >= 'A' && c <= 'F')
+	n1 = c - 'A' + 10;
+      else
+	{
+	  n1 = -1;
+	  if (ign_garb)
+	    continue;
+	}
+
+      ign_garb = 0;
+
+      if (p >= cols)
+	{
+	  if (!hextype)
+	    {
+	      if (n1 < 0)
+		{
+		  p = 0;
+		  continue;
+		}
+	      want_off = (want_off << 4) | n1;
+	      continue;
+	    }
+	  else
+	    p = 0;
+	}
+
+      if (base_off + want_off != have_off)
+	{
+	  fflush(fpo);
+#ifdef TRY_SEEK
+	  c = fseek(fpo, base_off + want_off - have_off, 1);
+	  if (c >= 0)
+	    have_off = base_off + want_off;
+#endif
+	  if (base_off + want_off < have_off)
+	    {
+	      fprintf(fperr, "%s: sorry, cannot seek backwards.\n", pname);
+	      return 5;
+	    }
+	  for (; have_off < base_off + want_off; have_off++)
+	    putc(0, fpo);
+	}
+
+      if (n2 >= 0 && n1 >= 0)
+	{
+	  putc((n2 << 4) | n1, fpo);
+	  have_off++;
+	  want_off++;
+	  n1 = -1;
+	  if ((++p >= cols) && !hextype)
+	    {
+	      /* skip rest of line as garbage */
+	      want_off = 0;
+	      while ((c = getc(fpi)) != '\n' && c != EOF)
+		;
+	      ign_garb = 1;
+	    }
+	}
+      else if (n1 < 0 && n2 < 0 && n3 < 0)
+	{
+	  /* already stumbled into garbage, skip line, wait and see */
+	  if (!hextype)
+	    want_off = 0;
+	  while ((c = getc(fpi)) != '\n' && c != EOF)
+	    ;
+	  ign_garb = 1;
+	}
+    }
+  fflush(fpo);
+#ifdef TRY_SEEK
+  fseek(fpo, 0L, 2);
+#endif
+  fclose(fpo);
+  fclose(fpi);
+  return 0;
+}
+
+/*
+ * Print line l. If nz is false, xxdline regards the line a line of
+ * zeroes. If there are three or more consecutive lines of zeroes,
+ * they are replaced by a single '*' character.
+ *
+ * If the output ends with more than two lines of zeroes, you
+ * should call xxdline again with l being the last line and nz
+ * negative. This ensures that the last line is shown even when
+ * it is all zeroes.
+ *
+ * If nz is always positive, lines are never suppressed.
+ */
+static void
+xxdline(fp, l, nz)
+FILE *fp;
+char *l;
+int nz;
+{
+  static char z[LLEN+1];
+  static int zero_seen = 0;
+
+  if (!nz && zero_seen == 1)
+    strcpy(z, l);
+
+  if (nz || !zero_seen++)
+    {
+      if (nz)
+	{
+	  if (nz < 0)
+	    zero_seen--;
+	  if (zero_seen == 2)
+	    fputs(z, fp);
+	  if (zero_seen > 2)
+	    fputs("*\n", fp);
+	}
+      if (nz >= 0 || zero_seen > 0)
+	fputs(l, fp);
+      if (nz)
+	zero_seen = 0;
+    }
+}
+
+/* This is an EBCDIC to ASCII conversion table */
+/* from a proposed BTL standard April 16, 1979 */
+static unsigned char etoa64[] =
+{
+    0040,0240,0241,0242,0243,0244,0245,0246,
+    0247,0250,0325,0056,0074,0050,0053,0174,
+    0046,0251,0252,0253,0254,0255,0256,0257,
+    0260,0261,0041,0044,0052,0051,0073,0176,
+    0055,0057,0262,0263,0264,0265,0266,0267,
+    0270,0271,0313,0054,0045,0137,0076,0077,
+    0272,0273,0274,0275,0276,0277,0300,0301,
+    0302,0140,0072,0043,0100,0047,0075,0042,
+    0303,0141,0142,0143,0144,0145,0146,0147,
+    0150,0151,0304,0305,0306,0307,0310,0311,
+    0312,0152,0153,0154,0155,0156,0157,0160,
+    0161,0162,0136,0314,0315,0316,0317,0320,
+    0321,0345,0163,0164,0165,0166,0167,0170,
+    0171,0172,0322,0323,0324,0133,0326,0327,
+    0330,0331,0332,0333,0334,0335,0336,0337,
+    0340,0341,0342,0343,0344,0135,0346,0347,
+    0173,0101,0102,0103,0104,0105,0106,0107,
+    0110,0111,0350,0351,0352,0353,0354,0355,
+    0175,0112,0113,0114,0115,0116,0117,0120,
+    0121,0122,0356,0357,0360,0361,0362,0363,
+    0134,0237,0123,0124,0125,0126,0127,0130,
+    0131,0132,0364,0365,0366,0367,0370,0371,
+    0060,0061,0062,0063,0064,0065,0066,0067,
+    0070,0071,0372,0373,0374,0375,0376,0377
+};
+
+int
+main(argc, argv)
+int argc;
+char *argv[];
+{
+  FILE *fp, *fpo;
+  int c, e, p = 0, relseek = 1, negseek = 0, revert = 0;
+  int cols = 0, nonzero = 0, autoskip = 0, hextype = HEX_NORMAL;
+  int ebcdic = 0;
+  int octspergrp = -1;	/* number of octets grouped in output */
+  int grplen;		/* total chars per octet group */
+  long length = -1, n = 0, seekoff = 0;
+  char l[LLEN+1];
+  char *pname, *pp;
+
+#ifdef AMIGA
+  /* This program doesn't work when started from the Workbench */
+  if (argc == 0)
+    exit(1);
+#endif
+
+  pname = argv[0];
+  for (pp = pname; *pp; )
+    if (*pp++ == PATH_SEP)
+      pname = pp;
+#ifdef FILE_SEP
+  for (pp = pname; *pp; pp++)
+    if (*pp == FILE_SEP)
+      {
+	*pp = '\0';
+	break;
+      }
+#endif
+
+  while (argc >= 2)
+    {
+      pp = argv[1] + (!STRNCMP(argv[1], "--", 2) && argv[1][2]);
+	   if (!STRNCMP(pp, "-a", 2)) autoskip = 1 - autoskip;
+      else if (!STRNCMP(pp, "-b", 2)) hextype = HEX_BITS;
+      else if (!STRNCMP(pp, "-u", 2)) hexx = hexxa + 16;
+      else if (!STRNCMP(pp, "-p", 2)) hextype = HEX_POSTSCRIPT;
+      else if (!STRNCMP(pp, "-i", 2)) hextype = HEX_CINCLUDE;
+      else if (!STRNCMP(pp, "-r", 2)) revert++;
+      else if (!STRNCMP(pp, "-E", 2)) ebcdic++;
+      else if (!STRNCMP(pp, "-v", 2))
+	{
+	  fprintf(stderr, "%s%s\n", version, osver);
+	  exit(0);
+	}
+      else if (!STRNCMP(pp, "-c", 2))
+	{
+	  if (pp[2] && STRNCMP("ols", pp + 2, 3))
+	    cols = (int)strtol(pp + 2, NULL, 0);
+	  else
+	    {
+	      if (!argv[2])
+		exit_with_usage(pname);
+	      cols = (int)strtol(argv[2], NULL, 0);
+	      argv++;
+	      argc--;
+	    }
+	}
+      else if (!STRNCMP(pp, "-g", 2))
+	{
+	  if (pp[2] && STRNCMP("group", pp + 2, 5))
+	    octspergrp = (int)strtol(pp + 2, NULL, 0);
+	  else
+	    {
+	      if (!argv[2])
+		exit_with_usage(pname);
+	      octspergrp = (int)strtol(argv[2], NULL, 0);
+	      argv++;
+	      argc--;
+	    }
+	}
+      else if (!STRNCMP(pp, "-s", 2))
+	{
+	  relseek = 0;
+	  negseek = 0;
+	  if (pp[2] && STRNCMP("kip", pp+2, 3) && STRNCMP("eek", pp+2, 3))
+	    {
+#ifdef TRY_SEEK
+	      if (pp[2] == '+')
+		relseek++;
+	      if (pp[2+relseek] == '-')
+		negseek++;
+#endif
+	      seekoff = strtol(pp + 2+relseek+negseek, (char **)NULL, 0);
+	    }
+	  else
+	    {
+	      if (!argv[2])
+		exit_with_usage(pname);
+#ifdef TRY_SEEK
+	      if (argv[2][0] == '+')
+		relseek++;
+	      if (argv[2][relseek] == '-')
+		negseek++;
+#endif
+	      seekoff = strtol(argv[2] + relseek+negseek, (char **)NULL, 0);
+	      argv++;
+	      argc--;
+	    }
+	}
+      else if (!STRNCMP(pp, "-l", 2))
+	{
+	  if (pp[2] && STRNCMP("en", pp + 2, 2))
+	    length = strtol(pp + 2, (char **)NULL, 0);
+	  else
+	    {
+	      if (!argv[2])
+		exit_with_usage(pname);
+	      length = strtol(argv[2], (char **)NULL, 0);
+	      argv++;
+	      argc--;
+	    }
+	}
+      else if (!strcmp(pp, "--"))	/* end of options */
+	{
+	  argv++;
+	  argc--;
+	  break;
+	}
+      else if (pp[0] == '-' && pp[1])	/* unknown option */
+	exit_with_usage(pname);
+      else
+	break;				/* not an option */
+
+      argv++;				/* advance to next argument */
+      argc--;
+    }
+
+  if (!cols)
+    switch (hextype)
+      {
+      case HEX_POSTSCRIPT:	cols = 30; break;
+      case HEX_CINCLUDE:	cols = 12; break;
+      case HEX_BITS:		cols = 6; break;
+      case HEX_NORMAL:
+      default:			cols = 16; break;
+      }
+
+  if (octspergrp < 0)
+    switch (hextype)
+      {
+      case HEX_BITS:		octspergrp = 1; break;
+      case HEX_NORMAL:		octspergrp = 2; break;
+      case HEX_POSTSCRIPT:
+      case HEX_CINCLUDE:
+      default:			octspergrp = 0; break;
+      }
+
+  if (cols < 1 || (!hextype && (cols > COLS)))
+    {
+      fprintf(stderr, "%s: invalid number of columns (max. %d).\n", pname, COLS);
+      exit(1);
+    }
+
+  if (octspergrp < 1)
+    octspergrp = cols;
+
+  if (argc > 3)
+    exit_with_usage(pname);
+
+  if (argc == 1 || (argv[1][0] == '-' && !argv[1][1]))
+    BIN_ASSIGN(fp = stdin, !revert);
+  else
+    {
+      if ((fp = fopen(argv[1], BIN_READ(!revert))) == NULL)
+	{
+	  fprintf(stderr,"%s: ", pname);
+	  perror(argv[1]);
+	  return 2;
+	}
+    }
+
+  if (argc < 3 || (argv[2][0] == '-' && !argv[2][1]))
+    BIN_ASSIGN(fpo = stdout, revert);
+  else
+    {
+      int fd;
+      int mode = revert ? O_WRONLY : (O_TRUNC|O_WRONLY);
+
+      if (((fd = OPEN(argv[2], mode | BIN_CREAT(revert), 0666)) < 0) ||
+	  (fpo = fdopen(fd, BIN_WRITE(revert))) == NULL)
+	{
+	  fprintf(stderr, "%s: ", pname);
+	  perror(argv[2]);
+	  return 3;
+	}
+      rewind(fpo);
+    }
+
+  if (revert)
+    {
+      if (hextype && (hextype != HEX_POSTSCRIPT))
+	{
+	  fprintf(stderr, "%s: sorry, cannot revert this type of hexdump\n", pname);
+	  return -1;
+	}
+      return huntype(fp, fpo, stderr, pname, cols, hextype,
+		negseek ? -seekoff : seekoff);
+    }
+
+  if (seekoff || negseek || !relseek)
+    {
+#ifdef TRY_SEEK
+      if (relseek)
+	e = fseek(fp, negseek ? -seekoff : seekoff, 1);
+      else
+	e = fseek(fp, negseek ? -seekoff : seekoff, negseek ? 2 : 0);
+      if (e < 0 && negseek)
+	{
+	  fprintf(stderr, "%s: sorry cannot seek.\n", pname);
+	  return 4;
+	}
+      if (e >= 0)
+	seekoff = ftell(fp);
+      else
+#endif
+	{
+	  long s = seekoff;
+
+	  while (s--)
+	    (void)getc(fp);
+	}
+    }
+
+  if (hextype == HEX_CINCLUDE)
+    {
+      if (fp != stdin)
+	{
+	  fprintf(fpo, "unsigned char %s", isdigit((int)argv[1][0]) ? "__" : "");
+	  for (e = 0; (c = argv[1][e]) != 0; e++)
+	    putc(isalnum(c) ? c : '_', fpo);
+	  fputs("[] = {\n", fpo);
+	}
+
+      p = 0;
+      while ((length < 0 || p < length) && (c = getc(fp)) != EOF)
+	{
+	  fprintf(fpo, (hexx == hexxa) ? "%s0x%02x" : "%s0X%02X",
+	    (p % cols) ? ", " : ",\n  "+2*!p,  c);
+	  p++;
+	}
+
+      if (p)
+	fputs("\n};\n"+3*(fp == stdin), fpo);
+
+      if (fp != stdin)
+	{
+	  fprintf(fpo, "unsigned int %s", isdigit((int)argv[1][0]) ? "__" : "");
+	  for (e = 0; (c = argv[1][e]) != 0; e++)
+	    putc(isalnum(c) ? c : '_', fpo);
+	  fprintf(fpo, "_len = %d;\n", p);
+	}
+
+      fclose(fp);
+      fclose(fpo);
+      return 0;
+    }
+
+  if (hextype == HEX_POSTSCRIPT)
+    {
+      p = cols;
+      while ((length < 0 || n < length) && (e = getc(fp)) != EOF)
+	{
+	  putchar(hexx[(e >> 4) & 0xf]);
+	  putchar(hexx[(e     ) & 0xf]);
+	  n++;
+	  if (!--p)
+	    {
+	      putchar('\n');
+	      p = cols;
+	    }
+	}
+      if (p < cols)
+	putchar('\n');
+      fclose(fp);
+      fclose(fpo);
+      return 0;
+    }
+
+  /* hextype: HEX_NORMAL or HEX_BITS */
+
+  if (hextype == HEX_NORMAL)
+    grplen = octspergrp + octspergrp + 1;	/* chars per octet group */
+  else	/* hextype == HEX_BITS */
+    grplen = 8 * octspergrp + 1;
+
+  while ((length < 0 || n < length) && (e = getc(fp)) != EOF)
+    {
+      if (p == 0)
+	{
+	  sprintf(l, "%07lx: ", n + seekoff);
+	  for (c = 9; c < LLEN; l[c++] = ' ');
+	}
+      if (hextype == HEX_NORMAL)
+	{
+	  l[c = (9 + (grplen * p) / octspergrp)] = hexx[(e >> 4) & 0xf];
+	  l[++c]			       = hexx[ e       & 0xf];
+	}
+      else /* hextype == HEX_BITS */
+	{
+	  int i;
+
+	  c = (9 + (grplen * p) / octspergrp) - 1;
+	  for (i = 7; i >= 0; i--)
+	    l[++c] = (e & (1 << i)) ? '1' : '0';
+	}
+      if (ebcdic)
+	e = (e < 64) ? '.' : etoa64[e-64];
+      l[11 + (grplen * cols - 1)/octspergrp + p] =
+#ifdef __MVS__
+	  (e >= 64)
+#else
+	  (e > 31 && e < 127)
+#endif
+	  ? e : '.';
+      if (e)
+	nonzero++;
+      n++;
+      if (++p == cols)
+	{
+	  l[c = (11 + (grplen * cols - 1)/octspergrp + p)] = '\n'; l[++c] = '\0';
+	  xxdline(fpo, l, autoskip ? nonzero : 1);
+	  nonzero = 0;
+	  p = 0;
+	}
+    }
+  if (p)
+    {
+      l[c = (11 + (grplen * cols - 1)/octspergrp + p)] = '\n'; l[++c] = '\0';
+      xxdline(fpo, l, 1);
+    }
+  else if (autoskip)
+    xxdline(fpo, l, -1);	/* last chance to flush out suppressed lines */
+
+  fclose(fp);
+  fclose(fpo);
+  return 0;
+}
--